diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 000000000..c6e7765a6 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,643 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + + +ADDITIONAL TERMS APPLICABLE TO THE DOOM 3 GPL SOURCE CODE. + + The following additional terms (“Additional Terms”) supplement and modify the GNU General Public License, Version 3 (“GPL”) applicable to the Doom 3 GPL Source Code (“Doom 3 Source Code”). In addition to the terms and conditions of the GPL, the Doom 3 Source Code is subject to the further restrictions below. + +1. Replacement of Section 15. Section 15 of the GPL shall be deleted in its entirety and replaced with the following: + +“15. Disclaimer of Warranty. + +THE PROGRAM IS PROVIDED WITHOUT ANY WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE AND MERCHANTABILITY. THE PROGRAM IS BEING DELIVERED OR MADE AVAILABLE “AS IS”, “WITH ALL FAULTS” AND WITHOUT WARRANTY OR REPRESENTATION. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.” + +2. Replacement of Section 16. Section 16 of the GPL shall be deleted in its entirety and replaced with the following: + +“16. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES SHALL ANY COPYRIGHT HOLDER OR ITS AFFILIATES, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, FOR ANY DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, DIRECT, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES ARISING FROM, OUT OF OR IN CONNECTION WITH THE USE OR INABILITY TO USE THE PROGRAM OR OTHER DEALINGS WITH THE PROGRAM(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), WHETHER OR NOT ANY COPYRIGHT HOLDER OR SUCH OTHER PARTY RECEIVES NOTICE OF ANY SUCH DAMAGES AND WHETHER OR NOT SUCH DAMAGES COULD HAVE BEEN FORESEEN.” + +3. LEGAL NOTICES; NO TRADEMARK LICENSE; ORIGIN. You must reproduce faithfully all trademark, copyright and other proprietary and legal notices on any copies of the Program or any other required author attributions. This license does not grant you rights to use any copyright holder or any other party’s name, logo, or trademarks. Neither the name of the copyright holder or its affiliates, or any other party who modifies and/or conveys the Program may be used to endorse or promote products derived from this software without specific prior written permission. The origin of the Program must not be misrepresented; you must not claim that you wrote the original Program. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original Program. + +4. INDEMNIFICATION. IF YOU CONVEY A COVERED WORK AND AGREE WITH ANY RECIPIENT OF THAT COVERED WORK THAT YOU WILL ASSUME ANY LIABILITY FOR THAT COVERED WORK, YOU HEREBY AGREE TO INDEMNIFY, DEFEND AND HOLD HARMLESS THE OTHER LICENSORS AND AUTHORS OF THAT COVERED WORK FOR ANY DAMAEGS, DEMANDS, CLAIMS, LOSSES, CAUSES OF ACTION, LAWSUITS, JUDGMENTS EXPENSES (INCLUDING WITHOUT LIMITATION REASONABLE ATTORNEYS' FEES AND EXPENSES) OR ANY OTHER LIABLITY ARISING FROM, RELATED TO OR IN CONNECTION WITH YOUR ASSUMPTIONS OF LIABILITY. diff --git a/DarkMod/AI/AreaManager.h b/DarkMod/AI/AreaManager.h deleted file mode 100644 index c64411bfe..000000000 --- a/DarkMod/AI/AreaManager.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AREA_MANAGER_H__ -#define __AREA_MANAGER_H__ - -#include -#include - -class idAI; - -namespace ai -{ - -class AreaManager -{ -private: - // angua: Forbidden areas (e.g. areas with locked doors) are excluded from path finding - // for specific AI - // ForbiddenAreasMap: multimap of area number and the AI for which this area should be excluded - typedef std::multimap ForbiddenAreasMap; - ForbiddenAreasMap _forbiddenAreas; - - // angua: AiAreasMap: gives a set of areas for each AI (for faster lookup) - typedef std::set AreaSet; - typedef std::map AiAreasMap; - AiAreasMap _aiAreas; - -public: - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - - void AddForbiddenArea(int areanum, const idAI* ai); - bool AreaIsForbidden(int areanum, const idAI* ai) const; - void RemoveForbiddenArea(int areanum, const idAI* ai); - - void DisableForbiddenAreas(const idAI* ai); - void EnableForbiddenAreas(const idAI* ai); - - void Clear(); -}; - -} // namespace ai - -#endif /* __AREA_MANAGER_H__ */ diff --git a/DarkMod/AI/CommunicationSubsystem.h b/DarkMod/AI/CommunicationSubsystem.h deleted file mode 100644 index aefaaf429..000000000 --- a/DarkMod/AI/CommunicationSubsystem.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_COMMUNICATION_SUBSYSTEM_H__ -#define __AI_COMMUNICATION_SUBSYSTEM_H__ - -#include -#include - -#include "Tasks/CommunicationTask.h" -#include "Subsystem.h" -#include "Queue.h" - -namespace ai -{ - -class CommunicationSubsystem : - public Subsystem -{ -protected: - - enum EActionTypeOnConflict - { - EDefault, // default behaviour - EOverride, // override the existing sound - EQueue, // queue after the current sound - EDiscard, // discard the new sound - EPush, // push on top of existing sound - }; - -public: - CommunicationSubsystem(SubsystemId subsystemId, idAI* owner); - - /** - * greebo: Handle a new incoming communication task and decide whether - * to push or queue it or do whatever action is defined according to the - * settings in the entityDef. - * - * Note: Does not accept NULL pointers. - * - * @returns: TRUE if the new bark has been accepted, FALSE if it has been ignored. - */ - bool AddCommTask(const CommunicationTaskPtr& communicationTask); - - // returns the priority of the currently active communication task - int GetCurrentPriority(); - - /** - * greebo: Queues a silence task at the end of the queue. The task - * gets the same priority assigned as the last one of the queue. - */ - void AddSilence(int duration); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Returns some debug text for console or renderworld display - virtual idStr GetDebugInfo(); - -protected: - // Priority difference is "new snd prio - current snd prio" - EActionTypeOnConflict GetActionTypeForSound(const CommunicationTaskPtr& communicationTask); - - // Returns the currently active commtask or NULL if no commtask is active - CommunicationTaskPtr GetCurrentCommTask(); -}; -typedef boost::shared_ptr CommunicationSubsystemPtr; - -} // namespace ai - -#endif /* __AI_COMMUNICATION_SUBSYSTEM_H__ */ diff --git a/DarkMod/AI/Conversation/ConversationSystem.h b/DarkMod/AI/Conversation/ConversationSystem.h deleted file mode 100644 index e71e5dd45..000000000 --- a/DarkMod/AI/Conversation/ConversationSystem.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_CONVERSATION_SYSTEM_H__ -#define __AI_CONVERSATION_SYSTEM_H__ - -#include "../../../idlib/precompiled.h" - -#include "Conversation.h" - -namespace ai { - -class ConversationSystem -{ - // The indexed list of conversations - idList _conversations; - - // The indices of all active conversations - idList _activeConversations; - - // The indices of all finished conversations, ready for removal - idList _dyingConversations; - -public: - // Clears and removes all allocated data - void Clear(); - - /** - * greebo: Initialises this class. This means loading the conversation entities - * containing all conversations for this map. - */ - void Init(idMapFile* mapFile); - - /** - * greebo: Returns the conversation for the given name/index or NULL if not found. - */ - ConversationPtr GetConversation(const idStr& name); - ConversationPtr GetConversation(int index); - - /** - * Returns the numeric index for the given conversation name or -1 if not found. - */ - int GetConversationIndex(const idStr& name); - - /** - * greebo: Returns the number of available conversations in this system. - */ - int GetNumConversations(); - - /** - * greebo: This starts the conversation, after checking whether all conditions are met. - * - * @index: The conversation index. Use GetConversationIndex() to convert a conversation name to an index. - */ - void StartConversation(int index); - - /** - * greebo: Stops the given conversation. This can be called during ProcessConversations() too, - * as the index is only marked for removal next frame. - */ - void EndConversation(int index); - - /** - * greebo: This is the "thinking" routine for conversations which - * remotely controls the participating actors. - */ - void ProcessConversations(); - - // Save/Restore routines - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - -private: - // Helper to load a conversation from an entity's spawnargs - void LoadConversationEntity(idMapEntity* entity); -}; -typedef boost::shared_ptr ConversationSystemPtr; - -} // namespace ai - -#endif /* __AI_CONVERSATION_SYSTEM_H__ */ diff --git a/DarkMod/AI/DoorInfo.cpp b/DarkMod/AI/DoorInfo.cpp deleted file mode 100644 index 693ff8560..000000000 --- a/DarkMod/AI/DoorInfo.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "DoorInfo.h" - -namespace ai -{ - -DoorInfo::DoorInfo() : - areaNum(-1), - lastTimeSeen(-1), - lastTimeUsed(-1), // grayman #2345 - lastTimeTriedToOpen(-1), - wasOpen(false), - wasLocked(false), - wasBlocked(false) -{} - -void DoorInfo::Save(idSaveGame* savefile) const -{ - savefile->WriteInt(areaNum); - savefile->WriteInt(lastTimeSeen); - savefile->WriteInt(lastTimeTriedToOpen); - savefile->WriteBool(wasOpen); - savefile->WriteBool(wasLocked); - savefile->WriteBool(wasBlocked); - savefile->WriteInt(lastTimeUsed); // grayman #2345 -} - -void DoorInfo::Restore(idRestoreGame* savefile) -{ - savefile->ReadInt(areaNum); - savefile->ReadInt(lastTimeSeen); - savefile->ReadInt(lastTimeTriedToOpen); - savefile->ReadBool(wasOpen); - savefile->ReadBool(wasLocked); - savefile->ReadBool(wasBlocked); - savefile->ReadInt(lastTimeUsed); // grayman #2345 -} - -} // namespace ai diff --git a/DarkMod/AI/DoorInfo.h b/DarkMod/AI/DoorInfo.h deleted file mode 100644 index d959f4f0a..000000000 --- a/DarkMod/AI/DoorInfo.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __DOOR_INFO_H__ -#define __DOOR_INFO_H__ - -#include - -namespace ai -{ - -struct DoorInfo -{ - // The AAS area number - int areaNum; - - // When this door was seen the last time (-1 == never) - int lastTimeSeen; - - // When this door was used the last time (-1 == never) - int lastTimeUsed; // grayman #2345 - - // The last time this door was attempted to be opened (-1 == never) - int lastTimeTriedToOpen; - - // Whether this door was open the last time it was seen - bool wasOpen; - - // Whether this door was locked at the last open attempt - bool wasLocked; - - // Whether this door was blocked at the last open attempt - bool wasBlocked; - - DoorInfo(); - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); -}; -typedef boost::shared_ptr DoorInfoPtr; - -} // namespace ai - -#endif /* __DOOR_INFO_H__ */ diff --git a/DarkMod/AI/EAS/ElevatorStationInfo.h b/DarkMod/AI/EAS/ElevatorStationInfo.h deleted file mode 100644 index f71add131..000000000 --- a/DarkMod/AI/EAS/ElevatorStationInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_EAS_ELEVATOR_STATION_INFO_H__ -#define __AI_EAS_ELEVATOR_STATION_INFO_H__ - -#include -#include -#include "RouteNode.h" -#include "../../../game/game_local.h" - -namespace eas { - -struct ElevatorStationInfo -{ - idEntityPtr elevator; // The elevator this station is belonging to - idEntityPtr elevatorPosition; // The elevator position entity - int areaNum; // The area number of this elevator station - int clusterNum; // The cluster number of this elevator station - int elevatorNum; // The elevator number this position is belonging to - - ElevatorStationInfo() : - areaNum(-1), - clusterNum(-1), - elevatorNum(-1) - { - elevator = NULL; - elevatorPosition = NULL; - } - - void Save(idSaveGame* savefile) const - { - elevator.Save(savefile); - elevatorPosition.Save(savefile); - - savefile->WriteInt(areaNum); - savefile->WriteInt(clusterNum); - savefile->WriteInt(elevatorNum); - } - - void Restore(idRestoreGame* savefile) - { - elevator.Restore(savefile); - elevatorPosition.Restore(savefile); - - savefile->ReadInt(areaNum); - savefile->ReadInt(clusterNum); - savefile->ReadInt(elevatorNum); - } -}; -typedef boost::shared_ptr ElevatorStationInfoPtr; -typedef std::list ElevatorStationInfoList; - -} // namespace eas - -#endif /* __AI_EAS_ELEVATOR_STATION_INFO_H__ */ diff --git a/DarkMod/AI/EAS/RouteInfo.cpp b/DarkMod/AI/EAS/RouteInfo.cpp deleted file mode 100644 index 6e89f28ff..000000000 --- a/DarkMod/AI/EAS/RouteInfo.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "RouteInfo.h" - -namespace eas { - -RouteInfo::RouteInfo() : - routeType(ROUTE_TO_CLUSTER), - target(-1) -{} - -RouteInfo::RouteInfo(RouteType type, int targetNum) : - routeType(type), - target(targetNum) -{} - -// Copy constructor -RouteInfo::RouteInfo(const RouteInfo& other) : - routeType(other.routeType), - target(other.target) -{ - // Copy the RouteNodes of the other list, one by one - for (RouteNodeList::const_iterator otherNode = other.routeNodes.begin(); - otherNode != other.routeNodes.end(); ++otherNode) - { - RouteNodePtr newNode(new RouteNode(**otherNode)); - routeNodes.push_back(newNode); - } -} - -bool RouteInfo::operator==(const RouteInfo& other) const -{ - if (routeType == other.routeType && target == other.target && routeNodes.size() == other.routeNodes.size()) - { - for (RouteNodeList::const_iterator i = routeNodes.begin(), j = other.routeNodes.begin(); i != routeNodes.end(); ++i, ++j) - { - if (*i != *j) - { - return false; // RouteNode mismatch - } - } - - return true; // everything matched - } - - return false; // routeType, routeNodes.size() or target mismatched -} - -bool RouteInfo::operator!=(const RouteInfo& other) const -{ - return !operator==(other); -} - -void RouteInfo::Save(idSaveGame* savefile) const -{ - savefile->WriteInt(static_cast(routeType)); - savefile->WriteInt(target); - - savefile->WriteInt(static_cast(routeNodes.size())); - for (RouteNodeList::const_iterator i = routeNodes.begin(); i != routeNodes.end(); ++i) - { - (*i)->Save(savefile); - } -} - -void RouteInfo::Restore(idRestoreGame* savefile) -{ - int temp; - savefile->ReadInt(temp); - routeType = static_cast(temp); - savefile->ReadInt(target); - - int num; - savefile->ReadInt(num); - routeNodes.clear(); - for (int i = 0; i < num; i++) - { - RouteNodePtr node(new RouteNode); - node->Restore(savefile); - routeNodes.push_back(node); - } -} - -} // namespace eas diff --git a/DarkMod/AI/EAS/RouteInfo.h b/DarkMod/AI/EAS/RouteInfo.h deleted file mode 100644 index 2b880ffca..000000000 --- a/DarkMod/AI/EAS/RouteInfo.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_EAS_ROUTEINFO_H__ -#define __AI_EAS_ROUTEINFO_H__ - -#include -#include -#include -#include "RouteNode.h" - -namespace eas { - -enum RouteType { - ROUTE_DUMMY = 0, // placeholder - ROUTE_TO_AREA, // a route to an AAS area - ROUTE_TO_CLUSTER, // a route to an AAS cluster - NUM_ROUTE_TYPES, -}; - -// A route info contains information of how to get to a specific target -struct RouteInfo -{ - RouteType routeType; // ROUTE_TO_AREA or ROUTE_TO_CLUSTER, ... - int target; // either the target AREA or the target CLUSTER number, depending on routeType - RouteNodeList routeNodes; // contains the actual route node chain (WALK, USE_ELEVATOR, WALK, etc.) - - // Default constructor - RouteInfo(); - - // Specialised constructor - RouteInfo(RouteType type, int targetNum); - - // Copy constructor - RouteInfo(const RouteInfo& other); - - bool operator==(const RouteInfo& other) const; - bool operator!=(const RouteInfo& other) const; - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); -}; -typedef boost::shared_ptr RouteInfoPtr; -typedef std::list RouteInfoList; -typedef std::vector RouteInfoListVector; - -} // namespace eas - -#endif /* __AI_EAS_ROUTEINFO_H__ */ diff --git a/DarkMod/AI/EAS/RouteNode.cpp b/DarkMod/AI/EAS/RouteNode.cpp deleted file mode 100644 index 63f7ac4e9..000000000 --- a/DarkMod/AI/EAS/RouteNode.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "RouteNode.h" - -namespace eas { - -RouteNode::RouteNode() : - type(ACTION_WALK), - toArea(0), - toCluster(0), - elevator(-1), - elevatorStation(-1) -{} - -RouteNode::RouteNode(ActionType t, int goalArea, int goalCluster, int elevatorNum, int elevatorStationNum) : - type(t), - toArea(goalArea), - toCluster(goalCluster), - elevator(elevatorNum), - elevatorStation(elevatorStationNum) -{} - -// Copy constructor -RouteNode::RouteNode(const RouteNode& other) : - type(other.type), - toArea(other.toArea), - toCluster(other.toCluster), - elevator(other.elevator), - elevatorStation(other.elevatorStation) -{} - -bool RouteNode::operator==(const RouteNode& other) const -{ - return (type == other.type && toArea == other.toArea && toCluster == other.toCluster && - elevator == other.elevator && elevatorStation == other.elevatorStation); -} - -bool RouteNode::operator!=(const RouteNode& other) const -{ - return !operator==(other); -} - -void RouteNode::Save(idSaveGame* savefile) const -{ - savefile->WriteInt(static_cast(type)); - savefile->WriteInt(toArea); - savefile->WriteInt(toCluster); - savefile->WriteInt(elevator); - savefile->WriteInt(elevatorStation); -} - -void RouteNode::Restore(idRestoreGame* savefile) -{ - int temp; - savefile->ReadInt(temp); - type = static_cast(temp); - savefile->ReadInt(toArea); - savefile->ReadInt(toCluster); - savefile->ReadInt(elevator); - savefile->ReadInt(elevatorStation); -} - -} // namespace eas diff --git a/DarkMod/AI/EAS/RouteNode.h b/DarkMod/AI/EAS/RouteNode.h deleted file mode 100644 index 865d19f43..000000000 --- a/DarkMod/AI/EAS/RouteNode.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_EAS_ROUTENODE_H__ -#define __AI_EAS_ROUTENODE_H__ - -#include -#include - -namespace eas { - -enum ActionType { - ACTION_WALK = 0, // AI just needs to walk to the target - ACTION_USE_ELEVATOR, // AI needs to use an elevator - NUM_ACTIONS, -}; - -struct RouteNode -{ - ActionType type; // what needs to be done in this route section (walk?, use elevator?) - int toArea; // the target AAS area number - int toCluster; // the target AAS cluster number - int elevator; // the elevator number (is -1 if no elevator to be used in this node) - int elevatorStation; // The elevator station number of this position (-1 if unused) - - // Default constructor - RouteNode(); - - // Specialised constructor - RouteNode(ActionType t, int goalArea, int goalCluster, int elevatorNum = -1, int elevatorStationNum = -1); - - // Copy constructor - RouteNode(const RouteNode& other); - - bool operator==(const RouteNode& other) const; - bool operator!=(const RouteNode& other) const; - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); -}; -typedef boost::shared_ptr RouteNodePtr; -typedef std::list RouteNodeList; - -} // namespace eas - -#endif /* __AI_EAS_ROUTENODE_H__ */ diff --git a/DarkMod/AI/Queue.h b/DarkMod/AI/Queue.h deleted file mode 100644 index e0d333a0a..000000000 --- a/DarkMod/AI/Queue.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __STATEQUEUE_H__ -#define __STATEQUEUE_H__ - -#include -#include - -#include "../DarkModGlobals.h" -#include "Library.h" - -namespace ai -{ - -/** - * greebo: Templated queue containing shared ptrs of a certain type (Tasks and States). - * - * This is not a priority queue, no sorting happens. It derives from the std::list - * class, as this implements most of the methods we need for this queue. - * - * The interface is extended by a few convenience methods. - * - * The Save/Restore methods work together with the templated Library<> class. - */ -template -class Queue : - public std::list< boost::shared_ptr > -{ - // Parent list type - typedef std::list > ListType; - - // greebo: Don't define data members in a class deriving from an STL container - // (std::list destructor is non-virtual) - - // Shortcut typedef - typedef boost::shared_ptr ElementPtr; - -public: - /** - * Returns the entire contents of this queue as a string, for debugging purposes. - * Relies on the Elements having a member method GetName() - */ - const std::string DebuggingInfo() const - { - std::stringstream debugInfo; - for (typename ListType::const_iterator i = ListType::begin(); - i != ListType::end(); - ++i) - { - debugInfo << (*i)->GetName(); - debugInfo << "\n"; - } - return debugInfo.str(); - } - - /** - * Save this data structure to a savefile - */ - void Save(idSaveGame *savefile) const - { - savefile->WriteInt(ListType::size()); - for (typename ListType::const_iterator i = ListType::begin(); - i != ListType::end(); - ++i) - { - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Saving element %s.\r", (*i)->GetName().c_str()); - savefile->WriteString((*i)->GetName().c_str()); - - // Write the Element data into the savefile - (*i)->Save(savefile); - } - } - - /** - * Restore this data structure from a savefile - */ - void Restore(idRestoreGame *savefile) - { - // Clear the queue before restoring - ListType::clear(); - - int elements; - savefile->ReadInt(elements); - for (int i = 0; i < elements; i++) - { - idStr str; - savefile->ReadString(str); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Restoring task %s.\r", str.c_str()); - - ElementPtr element = Library::Instance().CreateInstance(str.c_str()); - assert(element != NULL); // the element must be found - - // Restore the element's state - element->Restore(savefile); - - // Add the element to the queue - push_back(element); - } - } -}; - -// Convenience typedefs -class State; -typedef Queue StateQueue; - -class Task; -typedef Queue TaskQueue; - -} // namespace ai - -#endif /* !__STATEQUEUE_H__ */ diff --git a/DarkMod/AI/States/AgitatedSearchingState.h b/DarkMod/AI/States/AgitatedSearchingState.h deleted file mode 100644 index 6b2a554fa..000000000 --- a/DarkMod/AI/States/AgitatedSearchingState.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_AGITATED_SEARCHING_STATE_H__ -#define __AI_AGITATED_SEARCHING_STATE_H__ - -#include "State.h" -#include "SearchingState.h" - -/** -* greebo: AgitatedSearchingState is one alert index above SearchingState. -* -* Apart from a few minor things this is similar to the base class SearchingState. -* -* See the base class for documentation. -*/ - -namespace ai -{ - -#define STATE_AGITATED_SEARCHING "AgitatedSearching" - -class AgitatedSearchingState : - public SearchingState -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); - -protected: - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); - - virtual void CalculateAlertDecreaseRate(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_AGITATED_SEARCHING_STATE_H__ */ diff --git a/DarkMod/AI/States/AgitatedSearchingStateLanternBot.h b/DarkMod/AI/States/AgitatedSearchingStateLanternBot.h deleted file mode 100644 index 2096ee293..000000000 --- a/DarkMod/AI/States/AgitatedSearchingStateLanternBot.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _AGITATED_SEARCHING_STATE_LANTERN_BOT_H_ -#define _AGITATED_SEARCHING_STATE_LANTERN_BOT_H_ - -#include "../../../game/ai/ai.h" -#include "AgitatedSearchingState.h" - -namespace ai -{ - -#define STATE_AGITATED_SEARCHING_LANTERN_BOT "AgitatedSearchingLanternBot" - -class AgitatedSearchingStateLanternBot : - public AgitatedSearchingState -{ -protected: - idVec3 _curAlertPos; - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); - - // Override base class signal - virtual void OnMovementBlocked(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - -protected: - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); - - void MoveTowardAlertPos(idAI* owner); -}; - -} // namespace - -#endif diff --git a/DarkMod/AI/States/AlertIdleState.h b/DarkMod/AI/States/AlertIdleState.h deleted file mode 100644 index 369c2b4cf..000000000 --- a/DarkMod/AI/States/AlertIdleState.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_ALERT_IDLE_STATE_H__ -#define __AI_ALERT_IDLE_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_ALERT_IDLE "AlertIdle" - -/** - * angua: This is a specialisation of the IdleState. If the AI - * has been highly alerted during its lifetime, it doesn't return - * into the regular IdleState, but this one. - */ -class AlertIdleState : - public IdleState -{ - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - // Note: we do not call IdleState::Init - virtual void Init(idAI* owner); - - // Think is inherited from IdleState::Think - - static StatePtr CreateInstance(); - -protected: - // Returns the initial idle bark sound, depending on the alert level - // and the current state of mind - virtual idStr GetInitialIdleBark(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_ALERT_IDLE_STATE_H__ */ diff --git a/DarkMod/AI/States/BlindedState.h b/DarkMod/AI/States/BlindedState.h deleted file mode 100644 index 57550552f..000000000 --- a/DarkMod/AI/States/BlindedState.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_BLINDED_STATE_H__ -#define __AI_BLINDED_STATE_H__ - -#include "../../../game/ai/ai.h" -#include "State.h" - -namespace ai -{ - -#define STATE_BLINDED "Blinded" - -class BlindedState : - public State -{ -private: - int _endTime; - float _oldAcuity; // to restore visual acuity - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_BLINDED_STATE_H__ */ diff --git a/DarkMod/AI/States/CombatState.h b/DarkMod/AI/States/CombatState.h deleted file mode 100644 index bbaef7200..000000000 --- a/DarkMod/AI/States/CombatState.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_COMBAT_STATE_H__ -#define __AI_COMBAT_STATE_H__ - -#include "../../../game/ai/ai.h" -#include "State.h" - -namespace ai -{ - -#define STATE_COMBAT "Combat" - -class CombatState : - public State -{ -protected: - // The AI's enemy - idEntityPtr _enemy; - int _criticalHealth; - bool _meleePossible; - bool _rangedPossible; - - ECombatType _combatType; - - // When end time is set, the state is just waiting to be finished - // and is not performing any routines anymore - int _endTime; - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Override the alert functions - virtual void OnTactileAlert(idEntity* tactEnt); - virtual void OnVisualAlert(idActor* enemy); - virtual void OnAudioAlert(); - - virtual void OnPersonEncounter(idEntity* stimSource, idAI* owner); - virtual void OnFailedKnockoutBlow(idEntity* attacker, const idVec3& direction, bool hitHead); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); - -protected: - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); - - // Checks enemy status (dead, visible, not an enemy anymore). - // Returns false if the enemy is not applicable anymore and the state has ended - bool CheckEnemyStatus(idActor* enemy, idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_COMBAT_STATE_H__ */ diff --git a/DarkMod/AI/States/DeadState.h b/DarkMod/AI/States/DeadState.h deleted file mode 100644 index ecea2cd61..000000000 --- a/DarkMod/AI/States/DeadState.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_DEAD_STATE_H__ -#define __AI_DEAD_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_DEAD "Dead" - -class DeadState : - public State -{ -private: - bool _waitingForDeath; - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_DEAD_STATE_H__ */ diff --git a/DarkMod/AI/States/EmergeFromCoverState.cpp b/DarkMod/AI/States/EmergeFromCoverState.cpp deleted file mode 100644 index 5d5341a3d..000000000 --- a/DarkMod/AI/States/EmergeFromCoverState.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "EmergeFromCoverState.h" -#include "../Memory.h" -#include "../Tasks/MoveToCoverTask.h" -#include "../Tasks/WaitTask.h" -#include "../Tasks/MoveToPositionTask.h" -#include "../Tasks/RandomHeadturnTask.h" -#include "LostTrackOfEnemyState.h" -#include "../Library.h" - -namespace ai -{ - -// Get the name of this state -const idStr& EmergeFromCoverState::GetName() const -{ - static idStr _name(STATE_EMERGE_FROM_COVER); - return _name; -} - -void EmergeFromCoverState::Init(idAI* owner) -{ - // Init base class first - State::Init(owner); - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("EmergeFromCoverState initialised.\r"); - assert(owner); - - // Shortcut reference - Memory& memory = owner->GetMemory(); - - // Fill the subsystems with their tasks - owner->GetSubsystem(SubsysCommunication)->ClearTasks(); - owner->actionSubsystem->ClearTasks(); - - owner->movementSubsystem->ClearTasks(); - owner->movementSubsystem->QueueTask( - TaskPtr(new MoveToPositionTask(memory.positionBeforeTakingCover)) - ); -} - -// Gets called each time the mind is thinking -void EmergeFromCoverState::Think(idAI* owner) -{ - Memory& memory = owner->GetMemory(); - - // Let the AI check its senses - owner->PerformVisualScan(); - - if (owner->AI_MOVE_DONE - && !owner->AI_DEST_UNREACHABLE - && (owner->GetPhysics()->GetOrigin() - memory.positionBeforeTakingCover).LengthFast() < 50) - { - // Reached position before taking cover, look for enemy - // Turn to last visible enemy position - owner->TurnToward(owner->lastVisibleEnemyPos); - owner->Event_LookAtPosition(owner->lastVisibleEnemyPos,1); - - owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY); - } - else if (owner->AI_DEST_UNREACHABLE) - { - // Can't move back to position before taking cover - owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY); - } -} - -StatePtr EmergeFromCoverState::CreateInstance() -{ - return StatePtr(new EmergeFromCoverState); -} - -// Register this state with the StateLibrary -StateLibrary::Registrar emergeFromCoverStateRegistrar( - STATE_EMERGE_FROM_COVER, // Task Name - StateLibrary::CreateInstanceFunc(&EmergeFromCoverState::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/States/EmergeFromCoverState.h b/DarkMod/AI/States/EmergeFromCoverState.h deleted file mode 100644 index cf01932df..000000000 --- a/DarkMod/AI/States/EmergeFromCoverState.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_EMERGE_FROM_COVER_STATE_H__ -#define __AI_EMERGE_FROM_COVER_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_EMERGE_FROM_COVER "EmergeFromCover" - -class EmergeFromCoverState : - public State -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_EMERGE_FROM_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/ExamineRopeState.h b/DarkMod/AI/States/ExamineRopeState.h deleted file mode 100644 index ab847b8dd..000000000 --- a/DarkMod/AI/States/ExamineRopeState.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_EXAMINE_ROPE_H__ -#define __AI_EXAMINE_ROPE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_EXAMINE_ROPE "ExamineRope" - -class ExamineRopeState : - public State -{ -private: - // Default constructor - ExamineRopeState(); - - idEntityPtr _rope; - idVec3 _point; // the interesting point on the rope - - // time to wait before proceeding with a state - int _waitEndTime; - - idVec3 _examineSpot; // where to stand to examine the rope - - enum EExamineRopeState - { - EStateSitting, - EStateStarting, - EStateApproaching, - EStateTurningToward, - EStateExamineTop, - EStateExamineBottom, - EStateFinal - } _examineRopeState; - -public: - // Constructor using rope and examination point as input - ExamineRopeState(idAFEntity_Generic* rope, idVec3 point); - - // Get the name of this state - virtual const idStr& GetName() const; - - virtual void Wrapup(idAI* owner); - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Look at top of rope - void StartExaminingTop(idAI* owner); - - // Look at bottom of rope - void StartExaminingBottom(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_EXAMINE_ROPE_H__ */ diff --git a/DarkMod/AI/States/FailedKnockoutState.h b/DarkMod/AI/States/FailedKnockoutState.h deleted file mode 100644 index 04e4e9e2b..000000000 --- a/DarkMod/AI/States/FailedKnockoutState.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_FAILED_KNOCK_OUT_STATE_H__ -#define __AI_FAILED_KNOCK_OUT_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_FAILED_KNOCKED_OUT "FailedKnockout" - -class FailedKnockoutState : - public State -{ - int _stateEndTime; - int _allowEndTime; - idEntity* _attacker; - idVec3 _attackDirection; - bool _hitHead; - - FailedKnockoutState(); - -public: - FailedKnockoutState(idEntity* attacker, const idVec3& attackDirection, bool hitHead); - - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_FAILED_KNOCK_OUT_STATE_H__ */ diff --git a/DarkMod/AI/States/FleeDoneState.h b/DarkMod/AI/States/FleeDoneState.h deleted file mode 100644 index 82badd1c2..000000000 --- a/DarkMod/AI/States/FleeDoneState.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_FLEE_DONE_H__ -#define __AI_FLEE_DONE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_FLEE_DONE "FleeDone" - -class FleeDoneState : - public State -{ -private: - float _oldTurnRate; - int _turnEndTime; - bool _searchForFriendDone; - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - void OnPersonEncounter(idEntity* stimSource, idAI* owner); - - virtual bool CheckAlertLevel(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_FLEE_DONE_H__ */ diff --git a/DarkMod/AI/States/FleeState.h b/DarkMod/AI/States/FleeState.h deleted file mode 100644 index 6f0ed46a6..000000000 --- a/DarkMod/AI/States/FleeState.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_FLEE_H__ -#define __AI_FLEE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_FLEE "Flee" - -class FleeState : - public State -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - virtual void OnFailedKnockoutBlow(idEntity* attacker, const idVec3& direction, bool hitHead); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_FLEE_H__ */ diff --git a/DarkMod/AI/States/IdleSleepState.h b/DarkMod/AI/States/IdleSleepState.h deleted file mode 100644 index b73cd1d19..000000000 --- a/DarkMod/AI/States/IdleSleepState.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_IDLE_SLEEP_STATE_H__ -#define __AI_IDLE_SLEEP_STATE_H__ - -#include "State.h" -#include "IdleState.h" - -namespace ai -{ - -#define STATE_IDLE_SLEEP "IdleSleep" - -class IdleSleepState : - public IdleState -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); - - /** - * ishtvan: Called when targets are changed - * Re-initializes to catch new path corners - **/ - virtual void OnChangeTarget(idAI *owner); - -protected: - - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); - -}; - -} // namespace ai - -#endif /* __AI_IDLE_SLEEP_STATE_H__ */ diff --git a/DarkMod/AI/States/IdleState.h b/DarkMod/AI/States/IdleState.h deleted file mode 100644 index b64464490..000000000 --- a/DarkMod/AI/States/IdleState.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_IDLE_STATE_H__ -#define __AI_IDLE_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_IDLE "Idle" - -class IdleState : - public State -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); - - /** - * ishtvan: Called when targets are changed - * Re-initializes to catch new path corners - **/ - virtual void OnChangeTarget(idAI *owner); - -protected: - - bool _startSitting; - bool _startSleeping; - - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); - - // Returns the initial idle bark sound, depending on the alert level - // and the current state of mind - virtual idStr GetInitialIdleBark(idAI* owner); - - virtual void InitialiseMovement(idAI* owner); - virtual void InitialiseCommunication(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_IDLE_STATE_H__ */ diff --git a/DarkMod/AI/States/KnockedOutState.h b/DarkMod/AI/States/KnockedOutState.h deleted file mode 100644 index bf0cb33f0..000000000 --- a/DarkMod/AI/States/KnockedOutState.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_KNOCKED_OUT_STATE_H__ -#define __AI_KNOCKED_OUT_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_KNOCKED_OUT "KnockedOut" - -class KnockedOutState : - public State -{ - bool _waitingForKnockout; -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_KNOCKED_OUT_STATE_H__ */ diff --git a/DarkMod/AI/States/LostTrackOfEnemyState.cpp b/DarkMod/AI/States/LostTrackOfEnemyState.cpp deleted file mode 100644 index ab374c535..000000000 --- a/DarkMod/AI/States/LostTrackOfEnemyState.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "LostTrackOfEnemyState.h" -#include "../Memory.h" -#include "../Tasks/SingleBarkTask.h" -#include "../Library.h" - -namespace ai -{ - -// Get the name of this state -const idStr& LostTrackOfEnemyState::GetName() const -{ - static idStr _name(STATE_LOST_TRACK_OF_ENEMY); - return _name; -} - -void LostTrackOfEnemyState::Init(idAI* owner) -{ - // Init base class first - State::Init(owner); - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("LostTrackOfEnemyState initialised.\r"); - assert(owner); - - // Shortcut reference - Memory& memory = owner->GetMemory(); - - owner->SetAlertLevel((owner->thresh_5 + owner->thresh_4) * 0.5); - - // Draw weapon, if we haven't already - owner->DrawWeapon(); - - // Setup the search parameters - memory.alertPos = owner->lastVisibleReachableEnemyPos; - memory.alertRadius = LOST_ENEMY_ALERT_RADIUS; - memory.alertSearchVolume = LOST_ENEMY_SEARCH_VOLUME; - memory.alertSearchExclusionVolume.Zero(); - - memory.alertedDueToCommunication = false; - memory.stimulusLocationItselfShouldBeSearched = true; - - // Forget about the enemy, prevent UpdateEnemyPosition from "cheating". - owner->ClearEnemy(); - - // Enqueue a lost track of enemy bark - owner->commSubsystem->AddCommTask( - CommunicationTaskPtr(new SingleBarkTask("snd_lostTrackOfEnemy")) - ); - - // For now, clear the action tasks and movement tasks - owner->actionSubsystem->ClearTasks(); - owner->movementSubsystem->ClearTasks(); - - owner->GetMind()->EndState(); -} - -// Gets called each time the mind is thinking -void LostTrackOfEnemyState::Think(idAI* owner) -{ - -} - -StatePtr LostTrackOfEnemyState::CreateInstance() -{ - return StatePtr(new LostTrackOfEnemyState); -} - -// Register this state with the StateLibrary -StateLibrary::Registrar lostTrackOfEnemyStateRegistrar( - STATE_LOST_TRACK_OF_ENEMY, // Task Name - StateLibrary::CreateInstanceFunc(&LostTrackOfEnemyState::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/States/LostTrackOfEnemyState.h b/DarkMod/AI/States/LostTrackOfEnemyState.h deleted file mode 100644 index d7095f0e8..000000000 --- a/DarkMod/AI/States/LostTrackOfEnemyState.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_LOST_TRACK_OF_ENEMY_STATE_H__ -#define __AI_LOST_TRACK_OF_ENEMY_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_LOST_TRACK_OF_ENEMY "LostTrackOfEnemy" - -class LostTrackOfEnemyState : - public State -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_LOST_TRACK_OF_ENEMY_STATE_H__ */ diff --git a/DarkMod/AI/States/ObservantState.h b/DarkMod/AI/States/ObservantState.h deleted file mode 100644 index 44bb2337f..000000000 --- a/DarkMod/AI/States/ObservantState.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_OBSERVANT_STATE_H__ -#define __AI_OBSERVANT_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_OBSERVANT "Observant" - -class ObservantState : - public State -{ - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); - -protected: - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_OBSERVANT_STATE_H__ */ diff --git a/DarkMod/AI/States/PainState.cpp b/DarkMod/AI/States/PainState.cpp deleted file mode 100644 index ac294743a..000000000 --- a/DarkMod/AI/States/PainState.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "PainState.h" -#include "../Tasks/SingleBarkTask.h" -#include "../Memory.h" -#include "../Library.h" - -namespace ai -{ - -// Get the name of this state -const idStr& PainState::GetName() const -{ - static idStr _name(STATE_PAIN); - return _name; -} - -void PainState::Init(idAI* owner) -{ - // Init base class first - State::Init(owner); - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("PainState initialised.\r"); - assert(owner); - - Memory& memory = owner->GetMemory(); - - // Play the animation - owner->SetAnimState(ANIMCHANNEL_TORSO, "Torso_Pain", 4); - owner->SetAnimState(ANIMCHANNEL_LEGS, "Legs_Pain", 4); - - owner->SetWaitState(ANIMCHANNEL_TORSO, "pain"); - owner->SetWaitState(ANIMCHANNEL_LEGS, "pain"); - - // Set end time - _stateEndTime = gameLocal.time + 5000; - - // Set the alert position 50 units in the attacking direction - memory.alertPos = owner->GetPhysics()->GetOrigin(); - - // Do a single bark and assemble an AI message - CommMessagePtr message = CommMessagePtr(new CommMessage( - CommMessage::DetectedEnemy_CommType, - owner, NULL, // from this AI to anyone - NULL, - memory.alertPos - )); - - owner->commSubsystem->AddCommTask( - CommunicationTaskPtr(new SingleBarkTask("snd_pain_large", message)) - ); -} - -// Gets called each time the mind is thinking -void PainState::Think(idAI* owner) -{ - if (gameLocal.time >= _stateEndTime || - idStr(owner->WaitState(ANIMCHANNEL_TORSO)) != "pain") - { - // End this state - owner->GetMind()->EndState(); - } -} - -// Save/Restore methods -void PainState::Save(idSaveGame* savefile) const -{ - State::Save(savefile); - - savefile->WriteInt(_stateEndTime); -} - -void PainState::Restore(idRestoreGame* savefile) -{ - State::Restore(savefile); - savefile->ReadInt(_stateEndTime); -} - -StatePtr PainState::CreateInstance() -{ - return StatePtr(new PainState); -} - -// Register this state with the StateLibrary -StateLibrary::Registrar painStateRegistrar( - STATE_PAIN, // Task Name - StateLibrary::CreateInstanceFunc(&PainState::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/States/PainState.h b/DarkMod/AI/States/PainState.h deleted file mode 100644 index e3cca9450..000000000 --- a/DarkMod/AI/States/PainState.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PAIN_STATE_H__ -#define __AI_PAIN_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_PAIN "Pain" - -// An intermediate state, playing the pain anim and alerting the AI afterwards -class PainState : - public State -{ - int _stateEndTime; - -public: - - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PAIN_STATE_H__ */ diff --git a/DarkMod/AI/States/StayInCoverState.h b/DarkMod/AI/States/StayInCoverState.h deleted file mode 100644 index f1719596a..000000000 --- a/DarkMod/AI/States/StayInCoverState.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_STAY_IN_COVER_STATE_H__ -#define __AI_STAY_IN_COVER_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_STAY_IN_COVER "StayInCover" - -class StayInCoverState : - public State -{ -private: - int _emergeDelay; -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); - -protected: - // Override the base class method to catch projectile hit events - virtual void OnProjectileHit(idProjectile* projectile); -}; - -} // namespace ai - -#endif /* __AI_STAY_IN_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/SuspiciousState.h b/DarkMod/AI/States/SuspiciousState.h deleted file mode 100644 index 7fe790ac4..000000000 --- a/DarkMod/AI/States/SuspiciousState.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_SUSPICIOUS_STATE_H__ -#define __AI_SUSPICIOUS_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_SUSPICIOUS "Suspicious" - -class SuspiciousState : - public State -{ - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); - -protected: - // Override base class method - virtual bool CheckAlertLevel(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_SUSPICIOUS_STATE_H__ */ diff --git a/DarkMod/AI/States/SwitchOnLightState.h b/DarkMod/AI/States/SwitchOnLightState.h deleted file mode 100644 index 6a024a2a0..000000000 --- a/DarkMod/AI/States/SwitchOnLightState.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_SWITCH_ON_LIGHT_H__ -#define __AI_SWITCH_ON_LIGHT_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_SWITCH_ON_LIGHT "SwitchOnLight" - -class SwitchOnLightState : - public State -{ -private: - // Default constructor - SwitchOnLightState(); - - idEntityPtr _light; - - // time to wait after starting anim before the light is switched on - int _waitEndTime; - - idEntity* _goalEnt; // grayman #2603 - entity to walk toward when relighting a light - float _standOff; // grayman #2603 - get this close to relight - idVec3 _relightSpot; // grayman #2603 - where to stand to relight - - enum ERelightState // grayman #2603 - { - EStateSitting, - EStateStarting, - EStateApproaching, - EStateTurningToward, - EStateRelight, - EStatePause, - EStateFinal - } _relightState; - - bool CheckRelightPosition(idLight* light, idAI* owner, idVec3& pos); // grayman #2603 - -public: - // Constructor using light source as input parameter - SwitchOnLightState(idLight* light); - - // Get the name of this state - virtual const idStr& GetName() const; - - virtual void Wrapup(idAI* owner, idLight* light, bool ignore); // grayman #2603 - - virtual float GetMaxReach(idAI* owner, idEntity* torch, idStr lightType); // grayman #2603 - virtual bool GetSwitchGoal(idAI* owner, CBinaryFrobMover* mySwitch, idVec3 &target); // grayman #2603 - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Start switching on (stop move, start anim) - void StartSwitchOn(idAI* owner, idLight* light); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_SWITCH_ON_LIGHT_H__ */ diff --git a/DarkMod/AI/States/TakeCoverState.h b/DarkMod/AI/States/TakeCoverState.h deleted file mode 100644 index d29412a17..000000000 --- a/DarkMod/AI/States/TakeCoverState.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_TAKE_COVER_STATE_H__ -#define __AI_TAKE_COVER_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_TAKE_COVER "TakeCover" - -class TakeCoverState : - public State -{ -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_TAKE_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/UnreachableTargetState.h b/DarkMod/AI/States/UnreachableTargetState.h deleted file mode 100644 index c1ad1d0f6..000000000 --- a/DarkMod/AI/States/UnreachableTargetState.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_UNREACHABLE_TARGET_STATE_H__ -#define __AI_UNREACHABLE_TARGET_STATE_H__ - -#include "State.h" - -namespace ai -{ - -#define STATE_UNREACHABLE_TARGET "UnreachableTarget" - -class UnreachableTargetState : - public State -{ - // The AI's enemy - idEntityPtr _enemy; - bool _takingCoverPossible; - int _takeCoverTime; - bool _moveRequired; - int _reachEnemyCheck; - -public: - // Get the name of this state - virtual const idStr& GetName() const; - - // This is called when the state is first attached to the AI's Mind. - virtual void Init(idAI* owner); - - // Gets called each time the mind is thinking - virtual void Think(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - static StatePtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_UNREACHABLE_TARGET_STATE_H__ */ diff --git a/DarkMod/AI/Tasks/AnimalPatrolTask.h b/DarkMod/AI/Tasks/AnimalPatrolTask.h deleted file mode 100644 index 8f6865cd3..000000000 --- a/DarkMod/AI/Tasks/AnimalPatrolTask.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_ANIMAL_PATROL_TASK_H__ -#define __AI_ANIMAL_PATROL_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_ANIMAL_PATROL "AnimalPatrol" - -class AnimalPatrolTask; -typedef boost::shared_ptr AnimalPatrolTaskPtr; - -class AnimalPatrolTask : - public Task -{ - // greebo: These are the various states the animal is in - // It's a basic set of actions, chosen randomly, repeating - enum EState - { - stateNone, - stateMovingToNextSpot, - stateMovingToNextPathCorner, - stateDoingSomething, - stateWaiting, - statePreMovingToNextSpot, // grayman #2356 - no path corners, go elsewhere - stateCount, - } _state; - - // For waiting state - int _waitEndTime; - - // grayman #2356 - for 'move to position' state - int _moveEndTime; - - // Private constructor - AnimalPatrolTask(); - -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static AnimalPatrolTaskPtr CreateInstance(); - -private: - // Helper methods, corresponding to the EState enum - void chooseNewState(idAI* owner); - - void movingToNextSpot(idAI* owner); - void movingToNextPathCorner(idAI* owner); - void waiting(idAI* owner); - - void switchToState(EState newState, idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_ANIMAL_PATROL_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ChaseEnemyRangedTask.h b/DarkMod/AI/Tasks/ChaseEnemyRangedTask.h deleted file mode 100644 index 39ffaf0c3..000000000 --- a/DarkMod/AI/Tasks/ChaseEnemyRangedTask.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_CHASE_ENEMY_RANGED_TASK_H__ -#define __AI_CHASE_ENEMY_RANGED_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_CHASE_ENEMY_RANGED "ChaseEnemyRanged" - -class ChaseEnemyRangedTask; -typedef boost::shared_ptr ChaseEnemyRangedTaskPtr; - -class ChaseEnemyRangedTask : - public Task -{ - bool _hasGoal; - - idEntityPtr _enemy; - -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static ChaseEnemyRangedTaskPtr CreateInstance(); - - // Class-specific methods - virtual void SetEnemy(idActor* enemy); -}; - -} // namespace ai - -#endif /* __AI_CHASE_ENEMY_RANGED_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ChaseEnemyTask.h b/DarkMod/AI/Tasks/ChaseEnemyTask.h deleted file mode 100644 index b16f849d4..000000000 --- a/DarkMod/AI/Tasks/ChaseEnemyTask.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_CHASE_ENEMY_TASK_H__ -#define __AI_CHASE_ENEMY_TASK_H__ - -#include "Task.h" -#include "../../MultiStateMover.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_CHASE_ENEMY "ChaseEnemy" - -class ChaseEnemyTask; -typedef boost::shared_ptr ChaseEnemyTaskPtr; - -class ChaseEnemyTask : - public Task -{ - idEntityPtr _enemy; - int _reachEnemyCheck; - - // Private default constructor - ChaseEnemyTask(); -public: - ChaseEnemyTask(idActor* enemy); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static ChaseEnemyTaskPtr CreateInstance(); - - // Class-specific methods - virtual void SetEnemy(idActor* enemy); - -private: - CMultiStateMoverPosition* CanFetchElevator(CMultiStateMover* mover, idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_CHASE_ENEMY_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/CombatTask.cpp b/DarkMod/AI/Tasks/CombatTask.cpp deleted file mode 100644 index 8de180e3e..000000000 --- a/DarkMod/AI/Tasks/CombatTask.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "CombatTask.h" -#include "SingleBarkTask.h" -#include "../Memory.h" -#include "../Library.h" - -namespace ai -{ - -CombatTask::CombatTask() : - _lastCombatBarkTime(-1) -{} - -void CombatTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Init the base class - Task::Init(owner, subsystem); - - _enemy = owner->GetEnemy(); -} - -void CombatTask::EmitCombatBark(idAI* owner, const idStr& sndName) -{ - // This will hold the message to be delivered with the bark, if appropriate - CommMessagePtr message; - - // Only alert the bystanders if we didn't receive the alert by message ourselves - message = CommMessagePtr(new CommMessage( - CommMessage::DetectedEnemy_CommType, - owner, NULL, // from this AI to anyone - owner->GetEnemy(), - owner->GetPhysics()->GetOrigin() - )); - - _lastCombatBarkTime = gameLocal.time; - - // The communication system - owner->commSubsystem->AddCommTask( - CommunicationTaskPtr(new SingleBarkTask(sndName, message)) - ); -} - -void CombatTask::Save(idSaveGame* savefile) const -{ - Task::Save(savefile); - - _enemy.Save(savefile); - savefile->WriteInt(_lastCombatBarkTime); -} - -void CombatTask::Restore(idRestoreGame* savefile) -{ - Task::Restore(savefile); - - _enemy.Restore(savefile); - savefile->ReadInt(_lastCombatBarkTime); -} - -} // namespace ai diff --git a/DarkMod/AI/Tasks/CombatTask.h b/DarkMod/AI/Tasks/CombatTask.h deleted file mode 100644 index e75b237a8..000000000 --- a/DarkMod/AI/Tasks/CombatTask.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_COMBAT_TASK_H__ -#define __AI_COMBAT_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -class CombatTask : - public Task -{ -protected: - idEntityPtr _enemy; - - int _lastCombatBarkTime; - - CombatTask(); - -public: - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - // This task lacks a Perform() method, this is to be implemented by subclasses - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - -protected: - - // Emits a combat bark plus an AI message to be delivered by soundprop - // about the enemy's position - void EmitCombatBark(idAI* owner, const idStr& sndName); -}; -typedef boost::shared_ptr CombatTaskPtr; - -} // namespace ai - -#endif /* __AI_RANGED_COMBAT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/CommWaitTask.cpp b/DarkMod/AI/Tasks/CommWaitTask.cpp deleted file mode 100644 index f50cdc905..000000000 --- a/DarkMod/AI/Tasks/CommWaitTask.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "CommWaitTask.h" -#include "../Memory.h" -#include "../Library.h" - -namespace ai -{ - -CommWaitTask::CommWaitTask() : - CommunicationTask(""), - _duration(0), - _endTime(-1) -{} - -CommWaitTask::CommWaitTask(int duration, int priority) : - CommunicationTask(""), - _duration(duration), - _endTime(-1) -{ - _priority = priority; -} - -// Get the name of this task -const idStr& CommWaitTask::GetName() const -{ - static idStr _name(TASK_COMM_WAIT); - return _name; -} - -void CommWaitTask::Init(idAI* owner, Subsystem& subsystem) -{ - CommunicationTask::Init(owner, subsystem); - - _endTime = gameLocal.time + _duration; -} - -bool CommWaitTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("CommWaitTask performing.\r"); - - return (gameLocal.time >= _endTime); -} - -// Save/Restore methods -void CommWaitTask::Save(idSaveGame* savefile) const -{ - CommunicationTask::Save(savefile); - - savefile->WriteInt(_duration); - savefile->WriteInt(_endTime); -} - -void CommWaitTask::Restore(idRestoreGame* savefile) -{ - CommunicationTask::Restore(savefile); - - savefile->ReadInt(_duration); - savefile->ReadInt(_endTime); -} - -CommWaitTaskPtr CommWaitTask::CreateInstance() -{ - return CommWaitTaskPtr(new CommWaitTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar commWaitTaskRegistrar( - TASK_COMM_WAIT, // Task Name - TaskLibrary::CreateInstanceFunc(&CommWaitTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/CommWaitTask.h b/DarkMod/AI/Tasks/CommWaitTask.h deleted file mode 100644 index ec7504a46..000000000 --- a/DarkMod/AI/Tasks/CommWaitTask.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_COMM_WAIT_TASK_H__ -#define __AI_COMM_WAIT_TASK_H__ - -#include "CommunicationTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_COMM_WAIT "CommWaitTask" - -class CommWaitTask; -typedef boost::shared_ptr CommWaitTaskPtr; - -// A simple silent task, causes the AI to shut up for a while -class CommWaitTask : - public CommunicationTask -{ - int _duration; - int _endTime; - - // Default constructor - CommWaitTask(); - -public: - // Constructor: pass the duration of the silence - CommWaitTask(int duration, int priority = 0); - - // Get the name of this task - virtual const idStr& GetName() const; - - virtual void Init(idAI* owner, Subsystem& subsystem); - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static CommWaitTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_COMM_WAIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/CommunicationTask.cpp b/DarkMod/AI/Tasks/CommunicationTask.cpp deleted file mode 100644 index a94067605..000000000 --- a/DarkMod/AI/Tasks/CommunicationTask.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "CommunicationTask.h" -#include "../Library.h" - -namespace ai -{ - -CommunicationTask::CommunicationTask() -{} - -CommunicationTask::CommunicationTask(const idStr& soundName) : - _soundName(soundName) -{ - // Look up priority - const idDict* dict = gameLocal.FindEntityDefDict(BARK_PRIORITY_DEF); - - if (dict != NULL) - { - // Change "snd_blah" to "prio_blah" - idStr prioName(soundName); - prioName.StripLeadingOnce("snd_"); - prioName = "prio_" + prioName; - - // Emit a warning if priority not found, but only if sound name is empty - if (!dict->GetInt(prioName, "-1", _priority) && !soundName.IsEmpty()) - { - gameLocal.Warning("Could not find bark priority for %s", soundName.c_str()); - } - } - else - { - gameLocal.Warning("Cannot find bark priority entitydef %s", BARK_PRIORITY_DEF); - _priority = -1; - } -} - -void CommunicationTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Just init the base class - Task::Init(owner, subsystem); - - _barkStartTime = gameLocal.time; - _barkLength = 0; -} - -int CommunicationTask::GetPriority() -{ - return _priority; -} - -void CommunicationTask::SetPriority(int priority) -{ - _priority = priority; -} - -bool CommunicationTask::IsBarking() -{ - return (gameLocal.time < _barkStartTime + _barkLength); -} - -const idStr& CommunicationTask::GetSoundName() -{ - return _soundName; -} - -// Save/Restore methods -void CommunicationTask::Save(idSaveGame* savefile) const -{ - Task::Save(savefile); - - savefile->WriteString(_soundName); - savefile->WriteInt(_priority); - savefile->WriteInt(_barkStartTime); - savefile->WriteInt(_barkLength); -} - -void CommunicationTask::Restore(idRestoreGame* savefile) -{ - Task::Restore(savefile); - - savefile->ReadString(_soundName); - savefile->ReadInt(_priority); - savefile->ReadInt(_barkStartTime); - savefile->ReadInt(_barkLength); -} - -} // namespace ai diff --git a/DarkMod/AI/Tasks/CommunicationTask.h b/DarkMod/AI/Tasks/CommunicationTask.h deleted file mode 100644 index 6c8e82bb3..000000000 --- a/DarkMod/AI/Tasks/CommunicationTask.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_COMMUNICATION_TASK_H__ -#define __AI_COMMUNICATION_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -#define BARK_PRIORITY_DEF "atdm:ai_bark_priority" -#define VERY_HIGH_BARK_PRIORITY 9000000 - -class CommunicationTask; -typedef boost::shared_ptr CommunicationTaskPtr; - -/** - * A CommunicationTask is a more specialised task, extending - * the interface by a few methods, which facilitate the handling - * of concurrent AI barks. A bark sound always has an associated - * priority, which the CommunicationSubsystem is using to decide - * whether a new incoming bark is allowed to override an existing - * one or not. - */ -class CommunicationTask : - public Task -{ -protected: - // The sound to play - idStr _soundName; - - // The priority of this sound - int _priority; - - int _barkStartTime; - int _barkLength; - - // Private constructors - CommunicationTask(); - - CommunicationTask(const idStr& soundName); - -public: - // Returns the priority of this bark - int GetPriority(); - void SetPriority(int priority); - - // Returns TRUE if the task is still playing a bark - // (this is excluding any possible delay after the actual sound) - bool IsBarking(); - - const idStr& GetSoundName(); - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); -}; - -} // namespace ai - -#endif /* __AI_COMMUNICATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/FleeTask.h b/DarkMod/AI/Tasks/FleeTask.h deleted file mode 100644 index caace9cc1..000000000 --- a/DarkMod/AI/Tasks/FleeTask.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_FLEE_TASK_H__ -#define __AI_FLEE_TASK_H__ - -#include "Task.h" -#include "../../EscapePointManager.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_FLEE "FleeTask" - -class FleeTask; -typedef boost::shared_ptr FleeTaskPtr; - -class FleeTask : - public Task -{ - idEntityPtr _enemy; - int _escapeSearchLevel; - int _failureCount; - int _fleeStartTime; - EscapeDistanceOption _distOpt; - - FleeTask(); -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static FleeTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_FLEE_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/FollowActorTask.h b/DarkMod/AI/Tasks/FollowActorTask.h deleted file mode 100644 index 1e58ba775..000000000 --- a/DarkMod/AI/Tasks/FollowActorTask.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_FOLLOW_ACTOR_TASK_H__ -#define __AI_FOLLOW_ACTOR_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_FOLLOW_ACTOR "FollowActor" - -class FollowActorTask; -typedef boost::shared_ptr FollowActorTaskPtr; - -class FollowActorTask : - public Task -{ -private: - // The actor we're following - idEntityPtr _actor; - - FollowActorTask(); - -public: - // Construct this task by passing an actor to follow - it's safe to pass a NULL actor, - // the task will terminate after one thinking round in that case. - FollowActorTask(idActor* actorToFollow); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static FollowActorTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_FOLLOW_ACTOR_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/GreetingBarkTask.h b/DarkMod/AI/Tasks/GreetingBarkTask.h deleted file mode 100644 index d75de1bf4..000000000 --- a/DarkMod/AI/Tasks/GreetingBarkTask.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_GREETING_BARK_TASK_H__ -#define __AI_GREETING_BARK_TASK_H__ - -#include "SingleBarkTask.h" -#include "../../AIComm_Message.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_GREETING_BARK "GreetingBark" - -class GreetingBarkTask; -typedef boost::shared_ptr GreetingBarkTaskPtr; - -class GreetingBarkTask : - public SingleBarkTask -{ -protected: - - idActor* _greetingTarget; - - // Default constructor - GreetingBarkTask(); - -public: - // Constructor taking a sound name and the target actor as argument - GreetingBarkTask(const idStr& soundName, idActor* greetingTarget); - - // Get the name of this task - virtual const idStr& GetName() const; - - virtual void Init(idAI* owner, Subsystem& subsystem); - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static GreetingBarkTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_GREETING_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/HandleElevatorTask.h b/DarkMod/AI/Tasks/HandleElevatorTask.h deleted file mode 100644 index d843d8ea8..000000000 --- a/DarkMod/AI/Tasks/HandleElevatorTask.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_HANDLE_ELEVATOR_TASK_H__ -#define __AI_HANDLE_ELEVATOR_TASK_H__ - -#include "Task.h" -#include "../EAS/RouteInfo.h" -#include "../../BinaryFrobMover.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_HANDLE_ELEVATOR "HandleElevator" - -class HandleElevatorTask; -typedef boost::shared_ptr HandleElevatorTaskPtr; - -class HandleElevatorTask : - public Task -{ -private: - enum State - { - EMovingTowardsStation, - EInitiateMoveToFetchButton, - EMovingToFetchButton, - EPressFetchButton, - EWaitForElevator, - EMoveOntoElevator, - EInitiateMoveToRideButton, - EMovingToRideButton, - EPressRideButton, - ERideOnElevator, - EGetOffElevator, - ENumStates, - } _state; - - int _waitEndTime; - - // The actual route info structure - eas::RouteInfo _routeInfo; - - // Is TRUE if this task has finished successfully - bool _success; - - // Private constructor - HandleElevatorTask(); -public: - - HandleElevatorTask(const eas::RouteInfoPtr& routeInfo); - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static HandleElevatorTaskPtr CreateInstance(); - -private: - // Checks if the elevator station is reachable, returns TRUE if this is the case - bool IsElevatorStationReachable(CMultiStateMoverPosition* pos); - - void DebugDraw(idAI* owner); - - // Lets the AI move towards the position entity (is slightly more complicated than just idAI::MoveToPos) - bool MoveToPositionEntity(idAI* owner, CMultiStateMoverPosition* pos); - - // Lets the Ai move to the button - bool MoveToButton(idAI* owner, CMultiStateMoverButton* button); - -}; - -} // namespace ai - -#endif /* __AI_HANDLE_ELEVATOR_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/IdleAnimationTask.h b/DarkMod/AI/Tasks/IdleAnimationTask.h deleted file mode 100644 index 17db14809..000000000 --- a/DarkMod/AI/Tasks/IdleAnimationTask.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_IDLE_ANIMATION_TASK_H__ -#define __AI_IDLE_ANIMATION_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_IDLE_ANIMATION "IdleAnimation" - -class IdleAnimationTask; -typedef boost::shared_ptr IdleAnimationTaskPtr; - -class IdleAnimationTask : - public Task -{ - int _nextAnimationTime; - - idStringList _idleAnimations; - idStringList _idleAnimationsTorso; - idStringList _idleAnimationsSitting; - - int _idleAnimationInterval; - - // The index of the last anim played (to avoid duplicates) - int _lastIdleAnim; - - // Default constructor is private - IdleAnimationTask(); -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static IdleAnimationTaskPtr CreateInstance(); - -protected: - // De-serialises the comma-separated string list of animations - void ParseAnimsToList(const std::string& animStringList, idStringList& targetList); - - // Attempt to play an animation from the given list. Set torsoOnly to true if legs channel is forbidden - void AttemptToPlayAnim(idAI* owner, const idStringList& anims, bool torsoOnly); - - // Returns TRUE if the given anim has no_random_head_turning set - bool AnimHasNoHeadTurnFlag(idAI* owner, int animNum); - - // Returns a new idle anim index - virtual int GetNewIdleAnimIndex(const idStringList& anims, idAI* owner); - - // Returns true if the named anim is ok at this point - virtual bool AnimIsApplicable(idAI* owner, const idStr& animName); -}; - -} // namespace ai - -#endif /* __AI_IDLE_ANIMATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/InteractionTask.h b/DarkMod/AI/Tasks/InteractionTask.h deleted file mode 100644 index e11b9943f..000000000 --- a/DarkMod/AI/Tasks/InteractionTask.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_INTERACTION_TASK_H__ -#define __AI_INTERACTION_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_INTERACTION "Interaction" - -class InteractionTask; -typedef boost::shared_ptr InteractionTaskPtr; - -class InteractionTask : - public Task -{ - idEntity* _interactEnt; - - int _waitEndTime; - - InteractionTask(); - -public: - InteractionTask(idEntity* interactEnt); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static InteractionTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_INTERACTION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/InvestigateSpotTask.h b/DarkMod/AI/Tasks/InvestigateSpotTask.h deleted file mode 100644 index 4d87e1684..000000000 --- a/DarkMod/AI/Tasks/InvestigateSpotTask.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_INVESTIGATE_SPOT_TASK_H__ -#define __AI_INVESTIGATE_SPOT_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -/** -* greebo: This task requires memory.currentSearchSpot to be valid. -* -* This task is intended to be pushed into the action Subsystem and -* performs single-handedly how the given hiding spot should be handled. -* -* Note: This Task employs the Movement Subsystem when the algorithm -* judges to walk/run over to the given search spot. -**/ - -// Define the name of this task -#define TASK_INVESTIGATE_SPOT "InvestigateSpot" - -class InvestigateSpotTask; -typedef boost::shared_ptr InvestigateSpotTaskPtr; - -class InvestigateSpotTask : - public Task -{ - // The search spot to investigate - idVec3 _searchSpot; - - // The time this task may exit - int _exitTime; - - // Set to TRUE, if the AI should investigate the spot very closely - // usually by playing the kneel_down animation. - bool _investigateClosely; - - // Whether this task has told the AI to actually move to the searchspot - bool _moveInitiated; - - // Private default constructor - InvestigateSpotTask(); -public: - // @param: see member _investigateClosely - InvestigateSpotTask(bool investigateClosely); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - /** - * greebo: Sets a new goal position for this task. - * - * @newPos: The new position - */ - virtual void SetNewGoal(const idVec3& newPos); - - /** - * greebo: Sets the "should investigate closely" flag. - */ - virtual void SetInvestigateClosely(bool closely); - - virtual void OnFinish(idAI* owner); // grayman #2560 - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static InvestigateSpotTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_INVESTIGATE_SPOT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/MoveToCoverTask.cpp b/DarkMod/AI/Tasks/MoveToCoverTask.cpp deleted file mode 100644 index 2d0a24504..000000000 --- a/DarkMod/AI/Tasks/MoveToCoverTask.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "MoveToCoverTask.h" -#include "../Library.h" - -namespace ai -{ - -// Get the name of this task -const idStr& MoveToCoverTask::GetName() const -{ - static idStr _name(TASK_MOVE_TO_COVER); - return _name; -} - -void MoveToCoverTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Init the base class - Task::Init(owner, subsystem); - idActor* enemy = owner->GetEnemy(); - - //Move to cover position - owner->AI_RUN = true; - owner->AI_FORWARD = true; - owner->m_pathRank = owner->rank; // grayman #2345 - - owner->MoveToCover(enemy, owner->lastVisibleEnemyPos); -} - -bool MoveToCoverTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Move to Cover Task performing.\r"); - - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointer - assert(owner != NULL); - - if (owner->AI_DEST_UNREACHABLE) - { - //TODO - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Destination unreachable.\r"); - return true; - } - - if (owner->AI_MOVE_DONE) - { - // Move is done, - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Move is done.\r"); - owner->TurnToward(owner->lastVisibleEnemyPos); - - // finish this task - - return true; - } - - return false; // not finished yet -} - -MoveToCoverTaskPtr MoveToCoverTask::CreateInstance() -{ - return MoveToCoverTaskPtr(new MoveToCoverTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar moveToCoverTaskRegistrar( - TASK_MOVE_TO_COVER, // Task Name - TaskLibrary::CreateInstanceFunc(&MoveToCoverTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/MoveToCoverTask.h b/DarkMod/AI/Tasks/MoveToCoverTask.h deleted file mode 100644 index 5797ac0a9..000000000 --- a/DarkMod/AI/Tasks/MoveToCoverTask.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_MOVE_TO_COVER_TASK_H__ -#define __AI_MOVE_TO_COVER_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_MOVE_TO_COVER "MoveToCover" - -class MoveToCoverTask; -typedef boost::shared_ptr MoveToCoverTaskPtr; - -class MoveToCoverTask : - public Task -{ -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static MoveToCoverTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_MOVE_TO_COVER_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/MoveToPositionTask.h b/DarkMod/AI/Tasks/MoveToPositionTask.h deleted file mode 100644 index dd3542857..000000000 --- a/DarkMod/AI/Tasks/MoveToPositionTask.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_MOVE_TO_POSITION_H__ -#define __AI_MOVE_TO_POSITION_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_MOVE_TO_POSITION "MoveToPosition" - -#define DEFAULT_ENTITY_REACH_DISTANCE 50.0f - -class MoveToPositionTask; -typedef boost::shared_ptr MoveToPositionTaskPtr; - -class MoveToPositionTask : - public Task -{ -private: - - // The target position - idVec3 _targetPosition; - - // The previous target position - idVec3 _prevTargetPosition; - - // Target yaw (is not INFINITY if set) - float _targetYaw; - - idEntity* _targetEntity; - - // the distance below which entities are considered "reached" - float _entityReachDistance; - - // angua: if > 0, this changes the size of the bounding box used for checking whether the AI has reached their destination - float _accuracy; - - // Default constructor - MoveToPositionTask(); - -public: - // Constructor taking the target position (and optional target yaw) as input argument - MoveToPositionTask(const idVec3& targetPosition, float targetYaw = idMath::INFINITY, float accuracy = -1); - - // Constructor taking a target entity - MoveToPositionTask(idEntity* targetEntity, float entityReachDistance = DEFAULT_ENTITY_REACH_DISTANCE, float accuracy = -1); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - void SetPosition(idVec3 targetPosition); - - // Sets the distance below which entities are considered "reached" - void SetEntityReachDistance(float distance); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static MoveToPositionTaskPtr CreateInstance(); - -private: - // Refines the goal position, if appropriate - void UpdateTargetPosition(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_MOVE_TO_POSITION_H__ */ diff --git a/DarkMod/AI/Tasks/PathAnimTask.h b/DarkMod/AI/Tasks/PathAnimTask.h deleted file mode 100644 index 93dde5886..000000000 --- a/DarkMod/AI/Tasks/PathAnimTask.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_ANIM_TASK_H__ -#define __AI_PATH_ANIM_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_ANIM "PathAnim" - -class PathAnimTask; -typedef boost::shared_ptr PathAnimTaskPtr; - -class PathAnimTask : - public PathTask -{ -private: - // Private constructor - PathAnimTask(); - -public: - PathAnimTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Creates a new Instance of this task - static PathAnimTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_PATH_ANIM_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathCornerTask.h b/DarkMod/AI/Tasks/PathCornerTask.h deleted file mode 100644 index ecdc22572..000000000 --- a/DarkMod/AI/Tasks/PathCornerTask.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_CORNER_TASK_H__ -#define __AI_PATH_CORNER_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_CORNER "PathCorner" - -// grayman #2414 - For path prediction -const int PATH_PREDICTION_MOVES = 2; // Number of moves to look ahead -const float PATH_PREDICTION_CONSTANT = 26.0; // Empirically determined for smooth - // turns at any m_maxInterleaveThinkFrames - -class PathCornerTask; -typedef boost::shared_ptr PathCornerTaskPtr; - -class PathCornerTask : - public PathTask -{ -private: - bool _moveInitiated; - - // Position last time this task was executed, used for path prediction - idVec3 _lastPosition; - - // Frame this task was last executed - int _lastFrameNum; - - // Whether to anticipate the AI reaching path corners - bool _usePathPrediction; - - PathCornerTask(); - -public: - PathCornerTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathCornerTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_PATH_CORNER_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathCycleAnimTask.h b/DarkMod/AI/Tasks/PathCycleAnimTask.h deleted file mode 100644 index 62877ae65..000000000 --- a/DarkMod/AI/Tasks/PathCycleAnimTask.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_CYCLE_ANIM_TASK_H__ -#define __AI_PATH_CYCLE_ANIM_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_CYCLE_ANIM "PathCycleAnim" - -class PathCycleAnimTask; -typedef boost::shared_ptr PathCycleAnimTaskPtr; - -class PathCycleAnimTask : - public PathTask -{ - int _waitEndTime; - - // Private constructor - PathCycleAnimTask(); - -public: - PathCycleAnimTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathCycleAnimTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_PATH_CYCLE_ANIM_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathHideTask.cpp b/DarkMod/AI/Tasks/PathHideTask.cpp deleted file mode 100644 index a34afeff0..000000000 --- a/DarkMod/AI/Tasks/PathHideTask.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathHideTask.h" -#include "../Library.h" - -namespace ai -{ - -PathHideTask::PathHideTask() : - PathTask() -{} - -PathHideTask::PathHideTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathHideTask::GetName() const -{ - static idStr _name(TASK_PATH_HIDE); - return _name; -} - -void PathHideTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Init the base class - PathTask::Init(owner, subsystem); - - // Make invisible and nonsolid - owner->Hide(); -} - -bool PathHideTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Hide task performing.\r"); - - idPathCorner* path = _path.GetEntity(); - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(path != NULL && owner != NULL); - - // Move on to next target - if (owner->IsHidden()) - { - // Trigger path targets, now that we've reached the corner - owner->ActivateTargets(owner); - - // NextPath(); - - // Move is done, fall back to PatrolTask - DM_LOG(LC_AI, LT_INFO)LOGSTRING("entity is hidden.\r"); - - return true; // finish this task - } - return false; -} - -PathHideTaskPtr PathHideTask::CreateInstance() -{ - return PathHideTaskPtr(new PathHideTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar pathHideTaskRegistrar( - TASK_PATH_HIDE, // Task Name - TaskLibrary::CreateInstanceFunc(&PathHideTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathHideTask.h b/DarkMod/AI/Tasks/PathHideTask.h deleted file mode 100644 index 7d0f34d1e..000000000 --- a/DarkMod/AI/Tasks/PathHideTask.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_HIDE_TASK_H__ -#define __AI_PATH_HIDE_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_HIDE "PathHide" - -class PathHideTask; -typedef boost::shared_ptr PathHideTaskPtr; - -class PathHideTask : - public PathTask -{ -private: - PathHideTask(); - -public: - PathHideTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static PathHideTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_PATH_HIDE_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathInteractTask.h b/DarkMod/AI/Tasks/PathInteractTask.h deleted file mode 100644 index cebdce276..000000000 --- a/DarkMod/AI/Tasks/PathInteractTask.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_INTERACT_TASK_H__ -#define __AI_PATH_INTERACT_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_INTERACT "PathInteract" - -class PathInteractTask; -typedef boost::shared_ptr PathInteractTaskPtr; - -class PathInteractTask : - public PathTask -{ - idEntity* _target; - - int _waitEndTime; - - PathInteractTask(); - -public: - PathInteractTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathInteractTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_INTERACT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathLookatTask.h b/DarkMod/AI/Tasks/PathLookatTask.h deleted file mode 100644 index c45910c08..000000000 --- a/DarkMod/AI/Tasks/PathLookatTask.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_LOOKAT_TASK_H__ -#define __AI_PATH_LOOKAT_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_LOOKAT "PathLookat" - -class PathLookatTask; -typedef boost::shared_ptr PathLookatTaskPtr; - -class PathLookatTask : - public PathTask -{ -private: - PathLookatTask(); - - idEntity* _focusEnt; - float _duration; - -public: - PathLookatTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathLookatTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_LOOKAT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathShowTask.cpp b/DarkMod/AI/Tasks/PathShowTask.cpp deleted file mode 100644 index 771d10598..000000000 --- a/DarkMod/AI/Tasks/PathShowTask.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathShowTask.h" -#include "../Library.h" - -namespace ai -{ - -PathShowTask::PathShowTask() : - PathTask() -{} - -PathShowTask::PathShowTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathShowTask::GetName() const -{ - static idStr _name(TASK_PATH_SHOW); - return _name; -} - -void PathShowTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Just init the base class - PathTask::Init(owner, subsystem); -} - -bool PathShowTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Show task performing.\r"); - - idPathCorner* path = _path.GetEntity(); - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(path != NULL && owner != NULL); - - if (owner->CanBecomeSolid()) - { - owner->Show(); - } - - if (!owner->IsHidden()) - { - // Trigger path targets, now that we've reached the corner - owner->ActivateTargets(owner); - - // NextPath(); - - // Move is done, fall back to PatrolTask - DM_LOG(LC_AI, LT_INFO)LOGSTRING("entity is visible.\r"); - - return true; // finish this task - } - return false; -} - - -PathShowTaskPtr PathShowTask::CreateInstance() -{ - return PathShowTaskPtr(new PathShowTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar pathShowTaskRegistrar( - TASK_PATH_SHOW, // Task Name - TaskLibrary::CreateInstanceFunc(&PathShowTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathShowTask.h b/DarkMod/AI/Tasks/PathShowTask.h deleted file mode 100644 index 8f190f558..000000000 --- a/DarkMod/AI/Tasks/PathShowTask.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_SHOW_TASK_H__ -#define __AI_PATH_SHOW_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_SHOW "PathShow" - -class PathShowTask; -typedef boost::shared_ptr PathShowTaskPtr; - -class PathShowTask : - public PathTask -{ -private: - PathShowTask(); -public: - PathShowTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static PathShowTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_SHOW_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathSitTask.h b/DarkMod/AI/Tasks/PathSitTask.h deleted file mode 100644 index 0b641ef8b..000000000 --- a/DarkMod/AI/Tasks/PathSitTask.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_SIT_TASK_H__ -#define __AI_PATH_SIT_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_SIT "PathSit" - -class PathSitTask; -typedef boost::shared_ptr PathSitTaskPtr; - -class PathSitTask : - public PathTask -{ -private: - int _waitEndTime; - - // Private constructor - PathSitTask(); - -public: - PathSitTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathSitTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_SIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathSleepTask.cpp b/DarkMod/AI/Tasks/PathSleepTask.cpp deleted file mode 100644 index 411d84e61..000000000 --- a/DarkMod/AI/Tasks/PathSleepTask.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathSleepTask.h" -#include "PathTurnTask.h" -#include "WaitTask.h" -#include "RepeatedBarkTask.h" -#include "../States/IdleSleepState.h" -#include "../Library.h" - -namespace ai -{ - -PathSleepTask::PathSleepTask() : - PathTask() -{} - -PathSleepTask::PathSleepTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathSleepTask::GetName() const -{ - static idStr _name(TASK_PATH_SLEEP); - return _name; -} - -void PathSleepTask::Init(idAI* owner, Subsystem& subsystem) -{ - PathTask::Init(owner, subsystem); - - if(_path.GetEntity()->spawnArgs.GetBool("lay_down_left", "1")) - { - owner->AI_LAY_DOWN_LEFT = true; - } - else - { - owner->AI_LAY_DOWN_LEFT = false; - } - - if (owner->GetMoveType() == MOVETYPE_ANIM) - { - owner->LayDown(); - } -} - -bool PathSleepTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("PathSleepTask performing.\r"); - - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with an empty owner pointer - assert(owner != NULL); - - if (owner->GetMoveType() == MOVETYPE_SLEEP) - { - return true; - } - return false; -} - -PathSleepTaskPtr PathSleepTask::CreateInstance() -{ - return PathSleepTaskPtr(new PathSleepTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar pathSleepTaskRegistrar( - TASK_PATH_SLEEP, // Task Name - TaskLibrary::CreateInstanceFunc(&PathSleepTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathSleepTask.h b/DarkMod/AI/Tasks/PathSleepTask.h deleted file mode 100644 index 7c3251c7e..000000000 --- a/DarkMod/AI/Tasks/PathSleepTask.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_SLEEP_TASK_H__ -#define __AI_PATH_SLEEP_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_SLEEP "PathSleep" - -class PathSleepTask; -typedef boost::shared_ptr PathSleepTaskPtr; - -class PathSleepTask : - public PathTask -{ -private: - // Private constructor - PathSleepTask(); - -public: - PathSleepTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static PathSleepTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_PATH_SLEEP_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathTask.cpp b/DarkMod/AI/Tasks/PathTask.cpp deleted file mode 100644 index e9cf3e351..000000000 --- a/DarkMod/AI/Tasks/PathTask.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathTask.h" -#include "../Library.h" - -namespace ai -{ - -PathTask::PathTask() -{} - -PathTask::PathTask(idPathCorner* path) -{ - _path = path; -} - -void PathTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Just init the base class - Task::Init(owner, subsystem); - - if (_path.GetEntity() == NULL) - { - gameLocal.Error("Path Entity not set before Init()"); - } - - idPathCorner* path = _path.GetEntity(); - - _accuracy = path->spawnArgs.GetFloat("move_to_position_tolerance", "-1"); -} - - -void PathTask::SetTargetEntity(idPathCorner* path) -{ - assert(path); - _path = path; -} - -// Save/Restore methods -void PathTask::Save(idSaveGame* savefile) const -{ - Task::Save(savefile); - - _path.Save(savefile); - savefile->WriteFloat(_accuracy); -} - -void PathTask::Restore(idRestoreGame* savefile) -{ - Task::Restore(savefile); - - _path.Restore(savefile); - savefile->ReadFloat(_accuracy); -} - - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathTask.h b/DarkMod/AI/Tasks/PathTask.h deleted file mode 100644 index 37fb63292..000000000 --- a/DarkMod/AI/Tasks/PathTask.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_TASK_H__ -#define __AI_PATH_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH "Path" - -class PathTask; -typedef boost::shared_ptr PathTaskPtr; - -class PathTask : - public Task -{ -protected: - idEntityPtr _path; - float _accuracy; - - PathTask(); - -public: - PathTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const = 0; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem) = 0; - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - - // Class-specific methods - virtual void SetTargetEntity(idPathCorner* path); -}; - -} // namespace ai - -#endif /* __AI_PATH_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathTurnTask.cpp b/DarkMod/AI/Tasks/PathTurnTask.cpp deleted file mode 100644 index 05e901509..000000000 --- a/DarkMod/AI/Tasks/PathTurnTask.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathTurnTask.h" -#include "../Library.h" - -namespace ai -{ - -PathTurnTask::PathTurnTask() : - PathTask() -{} - -PathTurnTask::PathTurnTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathTurnTask::GetName() const -{ - static idStr _name(TASK_PATH_TURN); - return _name; -} - -void PathTurnTask::Init(idAI* owner, Subsystem& subsystem) -{ - PathTask::Init(owner, subsystem); - - idPathCorner* path = _path.GetEntity(); - - //Start turning - float angle = path->spawnArgs.GetFloat("angle","0"); - owner->TurnToward(angle); -} - -bool PathTurnTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Turn Task performing.\r"); - - idPathCorner* path = _path.GetEntity(); - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(path != NULL && owner != NULL); - - // Move on to next target when turning is done - if (owner->FacingIdeal()) - { - // Trigger path targets, now that we've reached the corner - owner->ActivateTargets(owner); - - // NextPath(); - - // Move is done, fall back to PatrolTask - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Turn is done.\r"); - - return true; // finish this task - } - return false; -} - -PathTurnTaskPtr PathTurnTask::CreateInstance() -{ - return PathTurnTaskPtr(new PathTurnTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar pathTurnTaskRegistrar( - TASK_PATH_TURN, // Task Name - TaskLibrary::CreateInstanceFunc(&PathTurnTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathTurnTask.h b/DarkMod/AI/Tasks/PathTurnTask.h deleted file mode 100644 index 2b4914385..000000000 --- a/DarkMod/AI/Tasks/PathTurnTask.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_TURN_TASK_H__ -#define __AI_PATH_TURN_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_TURN "PathTurn" - -class PathTurnTask; -typedef boost::shared_ptr PathTurnTaskPtr; - -class PathTurnTask : - public PathTask -{ -private: - PathTurnTask(); - -public: - PathTurnTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static PathTurnTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_TURN_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathWaitForTriggerTask.cpp b/DarkMod/AI/Tasks/PathWaitForTriggerTask.cpp deleted file mode 100644 index 86e51e181..000000000 --- a/DarkMod/AI/Tasks/PathWaitForTriggerTask.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathWaitForTriggerTask.h" -#include "../Library.h" - -namespace ai -{ - -PathWaitForTriggerTask::PathWaitForTriggerTask() : - PathTask() -{} - -PathWaitForTriggerTask::PathWaitForTriggerTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathWaitForTriggerTask::GetName() const -{ - static idStr _name(TASK_PATH_WAIT_FOR_TRIGGER); - return _name; -} - -void PathWaitForTriggerTask::Init(idAI* owner, Subsystem& subsystem) -{ - PathTask::Init(owner, subsystem); - - owner->AI_ACTIVATED = false; -} - -bool PathWaitForTriggerTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path WaitForTrigger Task performing.\r"); - - idPathCorner* path = _path.GetEntity(); - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(path != NULL && owner != NULL); - - if (owner->AI_ACTIVATED) - { - owner->AI_ACTIVATED = false; - - // Trigger path targets, now that we've reached the corner - owner->ActivateTargets(owner); - - // NextPath(); - - // Move is done, fall back to PatrolTask - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Waiting for trigger is done.\r"); - - return true; // finish this task - } - return false; -} - -PathWaitForTriggerTaskPtr PathWaitForTriggerTask::CreateInstance() -{ - return PathWaitForTriggerTaskPtr(new PathWaitForTriggerTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar pathWaitForTriggerTaskRegistrar( - TASK_PATH_WAIT_FOR_TRIGGER, // Task Name - TaskLibrary::CreateInstanceFunc(&PathWaitForTriggerTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathWaitForTriggerTask.h b/DarkMod/AI/Tasks/PathWaitForTriggerTask.h deleted file mode 100644 index ed339dbf1..000000000 --- a/DarkMod/AI/Tasks/PathWaitForTriggerTask.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ -#define __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_WAIT_FOR_TRIGGER "PathWaitForTrigger" - -class PathWaitForTriggerTask; -typedef boost::shared_ptr PathWaitForTriggerTaskPtr; - -class PathWaitForTriggerTask : - public PathTask -{ -private: - PathWaitForTriggerTask(); -public: - PathWaitForTriggerTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static PathWaitForTriggerTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathWaitTask.cpp b/DarkMod/AI/Tasks/PathWaitTask.cpp deleted file mode 100644 index f927cd17a..000000000 --- a/DarkMod/AI/Tasks/PathWaitTask.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "PathWaitTask.h" -#include "../Library.h" - -namespace ai -{ - -PathWaitTask::PathWaitTask() : - PathTask() -{} - -PathWaitTask::PathWaitTask(idPathCorner* path) : - PathTask(path) -{ - _path = path; -} - -// Get the name of this task -const idStr& PathWaitTask::GetName() const -{ - static idStr _name(TASK_PATH_WAIT); - return _name; -} - -void PathWaitTask::Init(idAI* owner, Subsystem& subsystem) -{ - PathTask::Init(owner, subsystem); - - idPathCorner* path = _path.GetEntity(); - - float waittime = path->spawnArgs.GetFloat("wait","0"); - float waitmax = path->spawnArgs.GetFloat("wait_max", "0"); - - if (waitmax > 0) - { - waittime += (waitmax - waittime) * gameLocal.random.RandomFloat(); - } - - waittime = SEC2MS(waittime); - - _endtime = waittime + gameLocal.time; -} - -bool PathWaitTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("PathWaitTask performing.\r"); - - idPathCorner* path = _path.GetEntity(); - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(path != NULL && owner != NULL); - - if (gameLocal.time >= _endtime) - { - // Trigger path targets, now that we've reached the corner - owner->ActivateTargets(owner); - - // NextPath(); - - // Wait is done, fall back to PatrolTask - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Wait is done.\r"); - - return true; // finish this task - } - return false; -} - - -// Save/Restore methods -void PathWaitTask::Save(idSaveGame* savefile) const -{ - PathTask::Save(savefile); - - savefile->WriteFloat(_endtime); -} - -void PathWaitTask::Restore(idRestoreGame* savefile) -{ - PathTask::Restore(savefile); - - savefile->ReadFloat(_endtime); -} - -PathWaitTaskPtr PathWaitTask::CreateInstance() -{ - return PathWaitTaskPtr(new PathWaitTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar PathWaitTaskRegistrar( - TASK_PATH_WAIT, // Task Name - TaskLibrary::CreateInstanceFunc(&PathWaitTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/PathWaitTask.h b/DarkMod/AI/Tasks/PathWaitTask.h deleted file mode 100644 index 39d88e6bc..000000000 --- a/DarkMod/AI/Tasks/PathWaitTask.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PATH_WAIT_TASK_H__ -#define __AI_PATH_WAIT_TASK_H__ - -#include "PathTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PATH_WAIT "PathWait" - -class PathWaitTask; -typedef boost::shared_ptr PathWaitTaskPtr; - -class PathWaitTask : - public PathTask -{ -private: - // The game time at which waiting ends in ms. - float _endtime; - - PathWaitTask(); -public: - PathWaitTask(idPathCorner* path); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PathWaitTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_PATH_WAIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PlayAnimationTask.h b/DarkMod/AI/Tasks/PlayAnimationTask.h deleted file mode 100644 index 3e9d5bc37..000000000 --- a/DarkMod/AI/Tasks/PlayAnimationTask.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_PLAY_ANIMATION_TASK_H__ -#define __AI_PLAY_ANIMATION_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_PLAY_ANIMATION "PlayAnimation" - -class PlayAnimationTask; -typedef boost::shared_ptr PlayAnimationTaskPtr; - -class PlayAnimationTask : - public Task -{ - idStr _animName; - - int _blendFrames; - - bool _playCycle; - - // Private constructor - PlayAnimationTask(); - -public: - // Pass the animation name directly here (like "idle_armwipe") - // Set playCycle to TRUE if this animation task should play continuously - PlayAnimationTask(const idStr& animName, int blendFrames, bool playCycle = false); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static PlayAnimationTaskPtr CreateInstance(); - -private: - // Private helper - void StartAnim(idAI* owner); -}; - -} // namespace ai - -#endif /* __AI_PLAY_ANIMATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RandomHeadturnTask.h b/DarkMod/AI/Tasks/RandomHeadturnTask.h deleted file mode 100644 index e950774f3..000000000 --- a/DarkMod/AI/Tasks/RandomHeadturnTask.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_RANDOM_HEADTURN_TASK_H__ -#define __AI_RANDOM_HEADTURN_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_RANDOM_HEADTURN "RandomHeadturn" - -class RandomHeadturnTask; -typedef boost::shared_ptr RandomHeadturnTaskPtr; - -class RandomHeadturnTask : - public Task -{ -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static RandomHeadturnTaskPtr CreateInstance(); - -private: - /** - * SophisticatedZombie: This method handles a random chance of turning the AIs head - * (visual gaze movement) - */ - void PerformHeadTurnCheck(); - void SetNextHeadTurnCheckTime(); -}; - -} // namespace ai - -#endif /* __AI_RANDOM_HEADTURN_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RandomTurningTask.cpp b/DarkMod/AI/Tasks/RandomTurningTask.cpp deleted file mode 100644 index ffcd7b7a7..000000000 --- a/DarkMod/AI/Tasks/RandomTurningTask.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "RandomTurningTask.h" -#include "../Library.h" - -namespace ai -{ - -// Get the name of this task -const idStr& RandomTurningTask::GetName() const -{ - static idStr _name(TASK_RANDOM_TURNING); - return _name; -} - -void RandomTurningTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Just init the base class - Task::Init(owner, subsystem); - - _nextYaw = owner->GetCurrentYaw() + (gameLocal.random.RandomFloat() - 0.5) * 360; - owner->TurnToward(_nextYaw); - _turning = true; - _nextTurningTime = gameLocal.time; -} - -bool RandomTurningTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Random Turning Task performing.\r"); - - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointers - assert(owner != NULL); - - if (_turning && owner->FacingIdeal()) - { - // TODO: un-hardcode - int turnDelay = static_cast(1000 + gameLocal.random.RandomFloat() * 400); - - // Wait a bit before turning again - _nextTurningTime = gameLocal.time + turnDelay; - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Turn is done.\r"); - _turning = false; - _nextYaw = owner->GetCurrentYaw() + (gameLocal.random.RandomFloat() - 0.5) * 180; - - } - - if (!_turning && gameLocal.time >= _nextTurningTime) - { - owner->TurnToward(_nextYaw); - _turning = true; - } - - return false; -} - -// Save/Restore methods -void RandomTurningTask::Save(idSaveGame* savefile) const -{ - Task::Save(savefile); - - savefile->WriteFloat(_nextYaw); - savefile->WriteBool(_turning); - savefile->WriteInt(_nextTurningTime); -} - -void RandomTurningTask::Restore(idRestoreGame* savefile) -{ - Task::Restore(savefile); - - savefile->ReadFloat(_nextYaw); - savefile->ReadBool(_turning); - savefile->ReadInt(_nextTurningTime); -} - -RandomTurningTaskPtr RandomTurningTask::CreateInstance() -{ - return RandomTurningTaskPtr(new RandomTurningTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar randomTurningTaskRegistrar( - TASK_RANDOM_TURNING, // Task Name - TaskLibrary::CreateInstanceFunc(&RandomTurningTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/RandomTurningTask.h b/DarkMod/AI/Tasks/RandomTurningTask.h deleted file mode 100644 index 657a6cbc1..000000000 --- a/DarkMod/AI/Tasks/RandomTurningTask.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_RANDOM_TURNING_TASK_H__ -#define __AI_RANDOM_TURNING_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_RANDOM_TURNING "RandomTurning" - -class RandomTurningTask; -typedef boost::shared_ptr RandomTurningTaskPtr; - -class RandomTurningTask : - public Task -{ -private: - - float _nextYaw; - bool _turning; - int _nextTurningTime; - -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static RandomTurningTaskPtr CreateInstance(); - - // Class-specific methods -}; - -} // namespace ai - -#endif /* __AI_RANDOM_TURNING_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RangedCombatTask.h b/DarkMod/AI/Tasks/RangedCombatTask.h deleted file mode 100644 index 52c08dc0a..000000000 --- a/DarkMod/AI/Tasks/RangedCombatTask.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_RANGED_COMBAT_TASK_H__ -#define __AI_RANGED_COMBAT_TASK_H__ - -#include "CombatTask.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_RANGED_COMBAT "RangedCombat" - -class RangedCombatTask; -typedef boost::shared_ptr RangedCombatTaskPtr; - -class RangedCombatTask : - public CombatTask -{ - int _lastCombatBarkTime; -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Creates a new Instance of this task - static RangedCombatTaskPtr CreateInstance(); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); -}; - -} // namespace ai - -#endif /* __AI_RANGED_COMBAT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RepeatedBarkTask.h b/DarkMod/AI/Tasks/RepeatedBarkTask.h deleted file mode 100644 index 4e95fe376..000000000 --- a/DarkMod/AI/Tasks/RepeatedBarkTask.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_REPEATED_BARK_TASK_H__ -#define __AI_REPEATED_BARK_TASK_H__ - -#include "CommunicationTask.h" -#include "../../AIComm_Message.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_REPEATED_BARK "RepeatedBark" - -class RepeatedBarkTask; -typedef boost::shared_ptr RepeatedBarkTaskPtr; - -class RepeatedBarkTask : - public CommunicationTask -{ -private: - // times in milliseconds: - int _barkRepeatIntervalMin; - int _barkRepeatIntervalMax; - int _nextBarkTime; - - // The message which should be delivered when barking - CommMessagePtr _message; - - // Default Constructor - RepeatedBarkTask(); - -public: - /** - * greebo: Pass the sound shader name plus the interval range in milliseconds. - * The message argument is optional and can be used to let this Task emit messages - * when playing the sound. - */ - RepeatedBarkTask(const idStr& soundName, - int barkRepeatIntervalMin, int barkRepeatIntervalMax, - const CommMessagePtr& message = CommMessagePtr()); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static RepeatedBarkTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_REPEATED_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ResolveMovementBlockTask.h b/DarkMod/AI/Tasks/ResolveMovementBlockTask.h deleted file mode 100644 index e70eff11e..000000000 --- a/DarkMod/AI/Tasks/ResolveMovementBlockTask.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ -#define __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_RESOLVE_MOVEMENT_BLOCK "ResolveMovementBlock" -#define RESOLVE_MOVE_DIST 16 // grayman #2345 - -class ResolveMovementBlockTask; -typedef boost::shared_ptr ResolveMovementBlockTaskPtr; - -class ResolveMovementBlockTask : - public Task -{ -private: - // The entity in the way - idEntity* _blockingEnt; - - // The angles we had when starting this task - idAngles _initialAngles; - - int _preTaskContents; - - int _endTime; - - // Default constructor - ResolveMovementBlockTask(); - -public: - ResolveMovementBlockTask(idEntity* blockingEnt); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static ResolveMovementBlockTaskPtr CreateInstance(); - -private: - void InitBlockingAI(idAI* owner, Subsystem& subsystem); - void InitBlockingStatic(idAI* owner, Subsystem& subsystem); - - bool PerformBlockingAI(idAI* owner); - bool PerformBlockingStatic(idAI* owner); - bool Room2Pass(idAI* owner); // grayman #2345 - bool IsSolid(); // grayman #2345 - void BecomeNonSolid(idAI* owner); // grayman #2345 -}; - -} // namespace ai - -#endif /* __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ScriptTask.h b/DarkMod/AI/Tasks/ScriptTask.h deleted file mode 100644 index 86167fd73..000000000 --- a/DarkMod/AI/Tasks/ScriptTask.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_SCRIPT_TASK_H__ -#define __AI_SCRIPT_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_SCRIPT "ScriptTask" - -class ScriptTask; -typedef boost::shared_ptr ScriptTaskPtr; - -/** - * greebo: A ScriptTask can be plugged into any AI subsystem and - * has the only purpose to execute a script thread. The actual - * script function must be specified in the constructor and - * can bei either global or local (=defined on the AI's scriptobject). - * - * For local scripts, the function does not to take any arguments. - * For global scripts, the function needs to take an entity argument (=this owner). - * - * The Task is finishing itself when the script thread is done executing. - * - * Terminating this task will of course kill the thread. - */ -class ScriptTask : - public Task -{ - // The name of the script function to execute - idStr _functionName; - - // The script thread - idThread* _thread; - - // Private constructor - ScriptTask(); - -public: - // Optional constructor taking the function name - ScriptTask(const idStr& functionName); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Gets called when this task is finished (or gets terminated) - virtual void OnFinish(idAI* owner); - - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static ScriptTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_SCRIPT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/SingleBarkTask.h b/DarkMod/AI/Tasks/SingleBarkTask.h deleted file mode 100644 index 816c54f1d..000000000 --- a/DarkMod/AI/Tasks/SingleBarkTask.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_SINGLE_BARK_TASK_H__ -#define __AI_SINGLE_BARK_TASK_H__ - -#include "CommunicationTask.h" -#include "../../AIComm_Message.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_SINGLE_BARK "SingleBark" - -class SingleBarkTask; -typedef boost::shared_ptr SingleBarkTaskPtr; - -class SingleBarkTask : - public CommunicationTask -{ -protected: - int _startDelay; - - int _endTime; - - // The message which should be delivered when barking - CommMessagePtr _message; - - // Default constructor - SingleBarkTask(); - -public: - // Constructor taking a sound name as argument - // Optional arguments are the message to deliver - // and the time to pass in ms before the bark should be played - SingleBarkTask(const idStr& soundName, - const CommMessagePtr& message = CommMessagePtr(), - int startDelayMS = 0); - - // Get the name of this task - virtual const idStr& GetName() const; - - virtual void Init(idAI* owner, Subsystem& subsystem); - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static SingleBarkTaskPtr CreateInstance(); - - // Class-specific methods - virtual void SetSound(const idStr& soundName); - virtual void SetMessage(const CommMessagePtr& message); -}; - -} // namespace ai - -#endif /* __AI_SINGLE_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ThrowObjectTask.h b/DarkMod/AI/Tasks/ThrowObjectTask.h deleted file mode 100644 index 64e94b607..000000000 --- a/DarkMod/AI/Tasks/ThrowObjectTask.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_THROW_OBJECT_TASK_H__ -#define __AI_THROW_OBJECT_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_THROW_OBJECT "ThrowObject" - -class ThrowObjectTask; -typedef boost::shared_ptr ThrowObjectTaskPtr; - -class ThrowObjectTask : - public Task -{ - int _projectileDelayMin; - int _projectileDelayMax; - int _nextThrowObjectTime; - -public: - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - virtual void OnFinish(idAI* owner); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static ThrowObjectTaskPtr CreateInstance(); - -}; - -} // namespace ai - -#endif /* __AI_THROW_OBJECT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/WaitTask.cpp b/DarkMod/AI/Tasks/WaitTask.cpp deleted file mode 100644 index 0de3bd8d1..000000000 --- a/DarkMod/AI/Tasks/WaitTask.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../Memory.h" -#include "WaitTask.h" -#include "../Library.h" - -namespace ai -{ - -WaitTask::WaitTask() : - _waitTime(0) -{} - -WaitTask::WaitTask(const int waitTime) : - _waitTime(waitTime) -{} - -// Get the name of this task -const idStr& WaitTask::GetName() const -{ - static idStr _name(TASK_WAIT); - return _name; -} - -void WaitTask::Init(idAI* owner, Subsystem& subsystem) -{ - // Just init the base class - Task::Init(owner, subsystem); - - _waitEndTime = gameLocal.time + _waitTime; -} - -bool WaitTask::Perform(Subsystem& subsystem) -{ - DM_LOG(LC_AI, LT_INFO)LOGSTRING("WaitTask performing.\r"); - - idAI* owner = _owner.GetEntity(); - - // This task may not be performed with empty entity pointer - assert(owner != NULL); - - // This task does nothing but wait until the time is over. - if (_waitEndTime <= gameLocal.time) - { - return true; - } - - return false; // not finished yet -} - -void WaitTask::SetTime(int waitTime) -{ - _waitTime = waitTime; -} - -// Save/Restore methods -void WaitTask::Save(idSaveGame* savefile) const -{ - Task::Save(savefile); - - savefile->WriteInt(_waitTime); - savefile->WriteInt(_waitEndTime); -} - -void WaitTask::Restore(idRestoreGame* savefile) -{ - Task::Restore(savefile); - - savefile->ReadInt(_waitTime); - savefile->ReadInt(_waitEndTime); -} - -WaitTaskPtr WaitTask::CreateInstance() -{ - return WaitTaskPtr(new WaitTask); -} - -// Register this task with the TaskLibrary -TaskLibrary::Registrar waitTaskRegistrar( - TASK_WAIT, // Task Name - TaskLibrary::CreateInstanceFunc(&WaitTask::CreateInstance) // Instance creation callback -); - -} // namespace ai diff --git a/DarkMod/AI/Tasks/WaitTask.h b/DarkMod/AI/Tasks/WaitTask.h deleted file mode 100644 index 16a5e15ee..000000000 --- a/DarkMod/AI/Tasks/WaitTask.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_WAIT_TASK_H__ -#define __AI_WAIT_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_WAIT "Wait" - -class WaitTask; -typedef boost::shared_ptr WaitTaskPtr; - -class WaitTask : - public Task -{ -private: - - int _waitTime; - int _waitEndTime; - - // Default constructor - WaitTask(); - -public: - - // Constructor with waittime (in ms) as input argument - WaitTask(const int waitTime); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - void SetTime(int waitTime); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static WaitTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_WAIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/WanderInLocationTask.h b/DarkMod/AI/Tasks/WanderInLocationTask.h deleted file mode 100644 index 53205607d..000000000 --- a/DarkMod/AI/Tasks/WanderInLocationTask.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __AI_WANDER_IN_LOCATION_TASK_H__ -#define __AI_WANDER_IN_LOCATION_TASK_H__ - -#include "Task.h" - -namespace ai -{ - -// Define the name of this task -#define TASK_WANDER_IN_LOCATION "WanderInLocation" - -class WanderInLocationTask; -typedef boost::shared_ptr WanderInLocationTaskPtr; - -class WanderInLocationTask : - public Task -{ - idVec3 _location; - - // Private default constructor - WanderInLocationTask(); -public: - // Constructor taking the target location as argument - WanderInLocationTask(const idVec3& location); - - // Get the name of this task - virtual const idStr& GetName() const; - - // Override the base Init method - virtual void Init(idAI* owner, Subsystem& subsystem); - - virtual bool Perform(Subsystem& subsystem); - - // Save/Restore methods - virtual void Save(idSaveGame* savefile) const; - virtual void Restore(idRestoreGame* savefile); - - // Creates a new Instance of this task - static WanderInLocationTaskPtr CreateInstance(); -}; - -} // namespace ai - -#endif /* __AI_WANDER_IN_LOCATION_TASK_H__ */ diff --git a/DarkMod/AbsenceMarker.h b/DarkMod/AbsenceMarker.h deleted file mode 100644 index dca47b4c3..000000000 --- a/DarkMod/AbsenceMarker.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef ABSENCEMARKER_H -#define ABSENCEMARKER_H - -#pragma hdrstop - -// Includes -#include "../game/entity.h" - - -/** -* The purpose of this entity subclass is to act as a marker for other entities that have -* been moved or destroyed. An instance of this class can be spawned when the other entity -* is removed, destroyed, moved or re-oriented in a noticeable fashion. If an instance -* of this class has a stim, it can signal entities to notice it, and then provide them -* with a copy of the missing entities spawn args so that a script will konw how to -* react to the absence. -* -* @author SophisticatedZombie -* @project The Dark Mode -* @copyright 2006 The Dark Mod team -* -*/ -class CAbsenceMarker : public idEntity -{ -public: - CLASS_PROTOTYPE( CAbsenceMarker ); - - int ownerTeam; - -protected: - - // Defines the spawnargs etc.. for this entity's script type - idStr referenced_entityDefName; - int referenced_entityDefNumber; - - // The name of the entity being referenced - idStr referenced_entityName; - - // The spawn args of the entity being referenced - idDict referenced_spawnArgs; - - -public: - - CAbsenceMarker(void); - - const idDict& GetRefSpawnargs() const; - - // Save and restore - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * Call this method to set the information about the entity - * which this references as "missing" from its normal location. - * - * @param absetEntity idEntityPtr indicating the entity who's - * absence we are marking. - */ - bool initAbsenceReference(idEntity* owner, idBounds& startBounds); -}; - - -// End of header wrapper -#endif diff --git a/DarkMod/BloodMarker.h b/DarkMod/BloodMarker.h deleted file mode 100644 index c14c2a0d7..000000000 --- a/DarkMod/BloodMarker.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef BLOODMARKER_H -#define BLOODMARKER_H - -#pragma hdrstop - -// Includes -#include "../game/entity.h" - -class CBloodMarker : public idEntity -{ -public: - CLASS_PROTOTYPE( CBloodMarker ); - -protected: - idStr _bloodSplat; - idStr _bloodSplatFading; - float _angle; - float _size; - - // True if this bloodsplat is in the process of disappearing - bool _isFading; - -public: - void Init(const idStr& splat, const idStr& splatFading, float size); - void Event_GenerateBloodSplat(); - - /** - * greebo: Overrides the OnStim method of the base class to check - * for water stims. - */ - void OnStim(const CStimPtr& stim, idEntity* stimSource); - - // Save and restore - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); -}; - -// End of header wrapper -#endif diff --git a/DarkMod/ButtonStateTracker.cpp b/DarkMod/ButtonStateTracker.cpp deleted file mode 100644 index 117278316..000000000 --- a/DarkMod/ButtonStateTracker.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "ButtonStateTracker.h" - -ButtonStateTracker::ButtonStateTracker(idPlayer* owner) : - _owner(owner), - _lastCheckTime(0) -{} - -void ButtonStateTracker::Update() -{ - int timeSinceLastCheck = gameLocal.time - _lastCheckTime; - - if (timeSinceLastCheck == 0) return; // no double-checking in the same frame - - //DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Updating button states\r"); - for (ButtonHoldTimeMap::iterator i = _buttons.begin(); i != _buttons.end(); /* in-loop increment */) - { - int impulse = i->first; - - if (common->ButtonState(KEY_FROM_IMPULSE(impulse))) - { - // Key is still held down, increase the hold time - i->second += timeSinceLastCheck; - - _owner->PerformKeyRepeat(impulse, i->second); - - // Increase the iterator - ++i; - } - else - { - int holdTime = i->second + timeSinceLastCheck; - - // Delete the impulse from the map, and increase the iterator immediately afterwards - _buttons.erase(i++); - - // Notify the player class about the keyrelease event - _owner->PerformKeyRelease(impulse, holdTime); - } - } - - // Remember the last time the buttons have been checked - _lastCheckTime = gameLocal.time; -} - -void ButtonStateTracker::StartTracking(int impulse) -{ - DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Impulse registered for tracking: %d\r", impulse); - // Initialise the given impulse with a hold time of zero - _buttons[impulse] = 0; - - if (_lastCheckTime == 0) - { - // Initialise the last check time, as it is 0 up to now - _lastCheckTime = gameLocal.time; - } -} - -bool ButtonStateTracker::ButtonIsHeld(int impulse) -{ - return (common->ButtonState(KEY_FROM_IMPULSE(impulse)) != 0); -} - -void ButtonStateTracker::StopTracking(int impulse) -{ - ButtonHoldTimeMap::iterator i = _buttons.find(impulse); - - if (i != _buttons.end()) - { - _buttons.erase(i); - } -} diff --git a/DarkMod/ButtonStateTracker.h b/DarkMod/ButtonStateTracker.h deleted file mode 100644 index 62ae36d51..000000000 --- a/DarkMod/ButtonStateTracker.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __GAME_BUTTON_STATE_TRACKER_H__ -#define __GAME_BUTTON_STATE_TRACKER_H__ - -#include - -/** -* greebo: The ButtonStateTracker is a helper class keeping track -* of certain buttons. As soon as a tracked button is released, -* this calls the method PerformButtonRelease() on the idPlayer class. -* -* Use the StartTracking() method to register an impulse for tracking. -*/ - -// Forward declaration -class idPlayer; - -class ButtonStateTracker -{ - // The class that is going to be notified on button release - idPlayer* _owner; - - // ButtonTimeTable: maps buttons => hold time - typedef std::map ButtonHoldTimeMap; - - ButtonHoldTimeMap _buttons; - - int _lastCheckTime; - -public: - // Constructor, pass the owning, to-be-notified entity here - ButtonStateTracker(idPlayer* owner); - - /** - * greebo: Call this from the Think() method so that - * this class can update the state of the tracked buttons. - */ - void Update(); - - /** - * greebo: Register an impulse for tracking to consider it - * during the update() routine. Released buttons get - * automatically de-registered, so no stopTracking() call is needed. - */ - void StartTracking(int impulse); - - /** - * greebo: Returns TRUE if the given impulse button is currently - * held down by the user, FALSE otherwise. - */ - bool ButtonIsHeld(int impulse); - - /** - * greebo: De-register an impulse for tracking. Calling this method - * does not trigger a PerformKeyReleased() event on the player, - * so this is more or less a "cancellation". - */ - void StopTracking(int impulse); - -}; // class ButtonStateTracker - -#endif /* __GAME_BUTTON_STATE_TRACKER_H__ */ diff --git a/DarkMod/DownloadMenu.h b/DarkMod/DownloadMenu.h deleted file mode 100644 index 61ce26576..000000000 --- a/DarkMod/DownloadMenu.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _DOWNLOAD_MENU_H_ -#define _DOWNLOAD_MENU_H_ - -#include -#include - -// Handles mainmenu that displays list of downloadable mods/PK4 files -class CDownloadMenu -{ -private: - // The index of the first displayed mod - int _availListTop; - int _selectedListTop; - - idList _selectedMods; - - /** - * greebo: Since mission l10n packs are stored separately, a mission - * transfer can consist of several downloads. - */ - struct MissionDownload - { - int missionDownloadId; // Download ID of the actual mission pack - int l10nPackDownloadId; // Download ID of the L10n Pack, is -1 by default - - MissionDownload() : - missionDownloadId(-1), - l10nPackDownloadId(-1) - {} - - MissionDownload(int missionDownloadId_, int l10nPackDownloadId_ = -1) : - missionDownloadId(missionDownloadId_), - l10nPackDownloadId(l10nPackDownloadId_) - {} - }; - - // A mapping "selected mod id" => download info - typedef std::map ActiveDownloads; - ActiveDownloads _downloads; - -public: - CDownloadMenu(); - - // handles main menu commands - void HandleCommands(const idStr& cmd, idUserInterface* gui); - - // updates the GUI variables - void UpdateGUI(idUserInterface* gui); - -private: - void StartDownload(idUserInterface* gui); - - void UpdateDownloadProgress(idUserInterface* gui); - - void ShowDownloadResult(idUserInterface* gui); - - void UpdateModDetails(idUserInterface* gui); - - void PerformScreenshotStep(idUserInterface* gui, int step); - - void UpdateNextScreenshotData(idUserInterface* gui, int nextScreenshotNum); - void UpdateScreenshotItemVisibility(idUserInterface* gui); - - idStr GetMissionDownloadProgressString(int modIndex); -}; -typedef boost::shared_ptr CDownloadMenuPtr; - -#endif /* _DOWNLOAD_MENU_H_ */ diff --git a/DarkMod/FrobButton.cpp b/DarkMod/FrobButton.cpp deleted file mode 100644 index 8e2a69747..000000000 --- a/DarkMod/FrobButton.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" -#include "DarkModGlobals.h" -#include "FrobButton.h" -#include "sndProp.h" - -//=============================================================================== -// CFrobButton -//=============================================================================== - -const idEventDef EV_TDM_Button_Operate("Operate", NULL); - -CLASS_DECLARATION( CBinaryFrobMover, CFrobButton ) - EVENT( EV_TDM_Button_Operate, CFrobButton::Operate) -END_CLASS - -void CFrobButton::Save(idSaveGame *savefile) const -{ - // nothing to save (yet) -} - -void CFrobButton::Restore( idRestoreGame *savefile ) -{ - // nothing to restore (yet) -} - -void CFrobButton::Spawn() -{ -} - -void CFrobButton::Operate() -{ - ToggleOpen(); -} - -void CFrobButton::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) -{ - // grayman #2603 - check "noimpact" flag - if (spawnArgs.GetBool("noimpact")) - { - return; // button can't be hit, so do nothing - } - - // grayman #2603 - ignore impulse from AI - - if (ent->IsType(idAI::Type)) - { - return; - } - - // Check if the impulse is applied in the right direction - if (impulse * m_Translation >= 0) - { - Operate(); - } -} diff --git a/DarkMod/FrobButton.h b/DarkMod/FrobButton.h deleted file mode 100644 index 6f9d28b07..000000000 --- a/DarkMod/FrobButton.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef FROBBUTTON_H -#define FROBBUTTON_H - -/** - * angua: This class is designed specifically for buttons. - * It doesn't do much more than using the BinaryFrobMover functions for now - * but I guess we will want some additional functionality in the future. - */ -class CFrobButton : - public CBinaryFrobMover -{ -public: - - CLASS_PROTOTYPE( CFrobButton ); - - void Spawn(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // this does only call open for now, might be that we want - // a more complex operation algorithm when the button is pressed in the future - virtual void Operate(); - - // Override the base class's ApplyImpulse method - virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse); -}; - -#endif /* FROBBUTTON_H */ diff --git a/DarkMod/FrobDoorHandle.cpp b/DarkMod/FrobDoorHandle.cpp deleted file mode 100644 index e4b15a906..000000000 --- a/DarkMod/FrobDoorHandle.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Gerhard W. Gruber -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" -#include "DarkModGlobals.h" -#include "FrobDoor.h" -#include "FrobDoorHandle.h" - -//=============================================================================== -// CFrobDoorHandle -//=============================================================================== -const idEventDef EV_TDM_Handle_GetDoor( "GetDoor", NULL, 'e' ); - -CLASS_DECLARATION( CFrobHandle, CFrobDoorHandle ) - EVENT( EV_TDM_Handle_GetDoor, CFrobDoorHandle::Event_GetDoor ) -END_CLASS - -CFrobDoorHandle::CFrobDoorHandle() : - m_Door(NULL) -{} - -void CFrobDoorHandle::Save(idSaveGame *savefile) const -{ - savefile->WriteObject(m_Door); -} - -void CFrobDoorHandle::Restore( idRestoreGame *savefile ) -{ - savefile->ReadObject(reinterpret_cast(m_Door)); -} - -void CFrobDoorHandle::Spawn() -{} - -CFrobDoor* CFrobDoorHandle::GetDoor() -{ - return m_Door; -} - -void CFrobDoorHandle::SetDoor(CFrobDoor* door) -{ - m_Door = door; - - // Set the frob master accordingly - SetFrobMaster(m_Door); -} - -void CFrobDoorHandle::Event_GetDoor() -{ - return idThread::ReturnEntity(m_Door); -} - -void CFrobDoorHandle::OnOpenPositionReached() -{ - // The handle is "opened", trigger the door, but only if this is the master handle - if (IsMasterHandle() && m_Door != NULL && !m_Door->IsOpen()) - { - m_Door->OpenDoor(false); - } - - // Let the handle return to its initial position - Close(true); -} - -void CFrobDoorHandle::Tap() -{ - // Invoke the base class first - CFrobHandle::Tap(); - - // Only the master handle is allowed to trigger sounds - if (IsMasterHandle() && m_Door != NULL) - { - // Start the appropriate sound - FrobMoverStartSound(m_Door->IsLocked() ? "snd_tap_locked" : "snd_tap_default"); - } -} - -bool CFrobDoorHandle::DoorIsLocked() -{ - return m_Door ? m_Door->IsLocked() : IsLocked(); -} diff --git a/DarkMod/FrobDoorHandle.h b/DarkMod/FrobDoorHandle.h deleted file mode 100644 index 11cfcc444..000000000 --- a/DarkMod/FrobDoorHandle.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Gerhard W. Gruber -// - -#ifndef FROBDOORHANDLE_H -#define FROBDOORHANDLE_H - -#include "FrobHandle.h" - -class CFrobDoor; - -/** - * CFrobDoorHandle is the complement for CFrobDoors, it specialises - * the generic base class CFrobHandle. - * - * Basically, if a handle is frobbed instead of the actual door, - * all calls are forwarded to its door, so that the player doesn't - * notice the difference. From the player's perspective frobbing - * the handle feels the same as frobbing the door. - * - * When frobbing a door with a handle attached, the event chain is like this: - * Frob > Door::Open > Handle::Tap > Handle moves to open pos > Door::OpenDoor - */ -class CFrobDoorHandle : - public CFrobHandle -{ -public: - CLASS_PROTOTYPE( CFrobDoorHandle ); - - CFrobDoorHandle(); - - void Spawn(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * greebo: This method is invoked directly or it gets called by the attached master. - * For instance, a call to CFrobDoor::Open() gets re-routed here first to let - * the handle animation play before actually trying to open the door. - * - * The Tap() algorithm attempts to rotate the door handle down until and - * calls OpenDoor() when the handle reaches its end rotation/position. - * - * Overrides CFrobHandle::Tap() - */ - virtual void Tap(); - - /** - * Get/set the door associated with this handle. - */ - CFrobDoor* GetDoor(); - void SetDoor(CFrobDoor* door); - - // greebo: Returns TRUE if the associated door is locked (not to confuse with CBinaryFrobMover::IsLocked()) - bool DoorIsLocked(); - -protected: - // Specialise the OpenPositionReached method of BinaryFrobMover to trigger the door's Open() routine - virtual void OnOpenPositionReached(); - - // Script event interface - void Event_GetDoor(); - -protected: - /** - * Pointer to the door that is associated with this handle - **/ - CFrobDoor* m_Door; -}; - -#endif /* FROBDOORHANDLE_H */ diff --git a/DarkMod/FrobLever.cpp b/DarkMod/FrobLever.cpp deleted file mode 100644 index 3a97e5e1f..000000000 --- a/DarkMod/FrobLever.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" -#include "DarkModGlobals.h" -#include "FrobLever.h" - -const idEventDef EV_TDM_Lever_Operate( "Operate", NULL ); -const idEventDef EV_TDM_Lever_Switch( "Switch", "d" ); - -CLASS_DECLARATION( CBinaryFrobMover, CFrobLever ) - EVENT( EV_TDM_Lever_Operate, CFrobLever::Event_Operate) - EVENT( EV_TDM_Lever_Switch, CFrobLever::Event_Switch) -END_CLASS - -void CFrobLever::Save(idSaveGame *savefile) const -{ - savefile->WriteBool(m_Latch); -} - -void CFrobLever::Restore( idRestoreGame *savefile ) -{ - savefile->ReadBool(m_Latch); -} - -void CFrobLever::Spawn() -{} - -void CFrobLever::PostSpawn() -{ - // Call the base class first - CBinaryFrobMover::PostSpawn(); - - // Set the latch to TRUE if the mover starts out closed - m_Latch = IsAtClosedPosition(); -} - -void CFrobLever::SwitchState(bool newState) -{ - if (newState) - { - Open(); - } - else - { - Close(); - } -} - -void CFrobLever::Operate() -{ - // Just call the BinaryFrobMover method - ToggleOpen(); -} - -void CFrobLever::OnOpenPositionReached() -{ - // Only allow event firing when the latch is TRUE - if (m_Latch) - { - // Set the latch to false, we've reached the position - m_Latch = false; - - CBinaryFrobMover::OnOpenPositionReached(); - } -} - -void CFrobLever::OnClosedPositionReached() -{ - // Only allow event firing when the latch is FALSE - if (!m_Latch) - { - // Set the latch to false, we've reached the position - m_Latch = true; - - CBinaryFrobMover::OnClosedPositionReached(); - } -} - -void CFrobLever::Event_Operate() -{ - Operate(); -} - -void CFrobLever::Event_Switch(int newState) -{ - SwitchState(newState == 0 ? false : true); -} diff --git a/DarkMod/FrobLever.h b/DarkMod/FrobLever.h deleted file mode 100644 index abafe08ce..000000000 --- a/DarkMod/FrobLever.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _FROB_LEVER_H_ -#define _FROB_LEVER_H_ - -/** - * greebo: This class is designed specifically for levers. - * - * It builds on top of the BinaryFrobMover class and overrides - * the relevant virtual event functions to implement proper - * two-state lever behaviour. - */ -class CFrobLever : - public CBinaryFrobMover -{ -public: - - CLASS_PROTOTYPE( CFrobLever ); - - void Spawn(); - - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); - - // Switches the lever state to the given state (true = "open") - void SwitchState(bool newState); - - // Calling Operate() toggles the current state - void Operate(); - -protected: - // Specialise the postspawn event - virtual void PostSpawn(); - - // Specialise the BinaryFrobMover events - virtual void OnOpenPositionReached(); - virtual void OnClosedPositionReached(); - -protected: - // The latch is to keep track of our visited positions. - // For instance, the lever should not trigger the targets at - // its closed position when it wasn't fully opened before. - bool m_Latch; - -private: - // Script interface - void Event_Operate(); - void Event_Switch(int newState); -}; - -#endif /* _FROB_LEVER_H_ */ diff --git a/DarkMod/FrobLockHandle.cpp b/DarkMod/FrobLockHandle.cpp deleted file mode 100644 index f74ead2eb..000000000 --- a/DarkMod/FrobLockHandle.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Gerhard W. Gruber -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" -#include "DarkModGlobals.h" -#include "FrobLock.h" -#include "FrobLockHandle.h" - -//=============================================================================== -// CFrobLockHandle -//=============================================================================== -const idEventDef EV_TDM_Handle_GetLock( "GetLock", NULL, 'e' ); - -CLASS_DECLARATION( CFrobHandle, CFrobLockHandle ) - EVENT( EV_TDM_Handle_GetLock, CFrobLockHandle::Event_GetLock ) -END_CLASS - -CFrobLockHandle::CFrobLockHandle() : - m_FrobLock(NULL) -{} - -void CFrobLockHandle::Save(idSaveGame *savefile) const -{ - savefile->WriteObject(m_FrobLock); -} - -void CFrobLockHandle::Restore( idRestoreGame *savefile ) -{ - savefile->ReadObject(reinterpret_cast(m_FrobLock)); -} - -void CFrobLockHandle::Spawn() -{} - -CFrobLock* CFrobLockHandle::GetFrobLock() -{ - return m_FrobLock; -} - -void CFrobLockHandle::SetFrobLock(CFrobLock* lock) -{ - m_FrobLock = lock; - - // Set the frob master accordingly - SetFrobMaster(m_FrobLock); -} - -void CFrobLockHandle::Event_GetLock() -{ - return idThread::ReturnEntity(m_FrobLock); -} - -void CFrobLockHandle::OnOpenPositionReached() -{ - // The handle is "opened", trigger the lock, but only if this is the master handle - if (IsMasterHandle() && m_FrobLock != NULL) - { - m_FrobLock->OpenTargets(); - } - - // Let the handle return to its initial position - Close(true); -} - -void CFrobLockHandle::Tap() -{ - // Invoke the base class first - CFrobHandle::Tap(); - - // Only the master handle is allowed to trigger sounds - if (IsMasterHandle() && m_FrobLock != NULL) - { - // Start the appropriate sound - FrobMoverStartSound(m_FrobLock->IsLocked() ? "snd_tap_locked" : "snd_tap_default"); - } -} - -bool CFrobLockHandle::LockIsLocked() -{ - return m_FrobLock ? m_FrobLock->IsLocked() : IsLocked(); -} diff --git a/DarkMod/FrobLockHandle.h b/DarkMod/FrobLockHandle.h deleted file mode 100644 index 4fb32f2dd..000000000 --- a/DarkMod/FrobLockHandle.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _FROB_LOCK_HANDLE_H -#define _FROB_LOCK_HANDLE_H - -#include "FrobHandle.h" - -class CFrobLock; - -/** - * CFrobLockHandle is meant to be used as moveable part of a CFrobLock. - * It behaves similarly to the CFrobDoorHandle class, but is specialised for - * use with the static froblock. - */ -class CFrobLockHandle : - public CFrobHandle -{ -public: - CLASS_PROTOTYPE( CFrobLockHandle ); - - CFrobLockHandle(); - - void Spawn(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * greebo: This method is invoked directly or it gets called by the attached master. - * - * Overrides CFrobHandle::Tap() - */ - virtual void Tap(); - - /** - * Get/set the lock associated with this handle. - */ - CFrobLock* GetFrobLock(); - void SetFrobLock(CFrobLock* lock); - - // greebo: Returns TRUE if the associated lock is locked (not to confuse with CBinaryFrobMover::IsLocked()) - bool LockIsLocked(); - -protected: - // Specialise the OpenPositionReached method of BinaryFrobMover to trigger the lock's open event - virtual void OnOpenPositionReached(); - - // Script event interface - void Event_GetLock(); - -protected: - /** - * Pointer to the lock that is associated with this handle - **/ - CFrobLock* m_FrobLock; -}; - -#endif /* _FROB_LOCK_HANDLE_H */ diff --git a/DarkMod/GamePlayTimer.h b/DarkMod/GamePlayTimer.h deleted file mode 100644 index dbc589d13..000000000 --- a/DarkMod/GamePlayTimer.h +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __GAMEPLAY_TIMER_H__ -#define __GAMEPLAY_TIMER_H__ - -#include "../idlib/precompiled.h" -#include - -/** - * greebo: This class keeps track of the total gameplay time. Just call Update() - * in regular intervals and the class checks the time difference since the last update call. - * - * For saving and loading, this class provides separate routines. - */ -class GamePlayTimer -{ - std::time_t _lastTime; - std::time_t _curTime; - - // The passed time in seconds - unsigned int _timePassed; - - // TRUE if the timer updates the passed time - bool _enabled; -public: - GamePlayTimer() : - _timePassed(0) - {} - - // Defines the starting point - void Start() - { - // Remember this time as starting point - std::time(&_lastTime); - SetEnabled(true); - } - - void Stop() - { - SetEnabled(false); - } - - bool IsEnabled() const - { - return _enabled; - } - - void SetEnabled(bool enabled) - { - _enabled = enabled; - } - - void Clear() - { - _timePassed = 0; - std::time(&_lastTime); - } - - void Update() - { - if (!_enabled) - { - return; - } - - // Get the current time and calculate the difference - std::time(&_curTime); - - // Increase the time that has passed - _timePassed += _curTime - _lastTime; - - // Remember this last check time - _lastTime = _curTime; - } - - idStr GetTime() const { - return TimeToStr(_timePassed); - } - - // Returns the gameplay time in seconds - unsigned int GetTimeInSeconds() const - { - return _timePassed; - } - - void Save(idSaveGame *savefile) const - { - savefile->WriteUnsignedInt(_timePassed); - savefile->WriteBool(_enabled); - } - - void Restore(idRestoreGame *savefile) - { - savefile->ReadUnsignedInt(_timePassed); - savefile->ReadBool(_enabled); - } - - // Formats the given gameplay time - static idStr TimeToStr(unsigned int time) { - unsigned int hours = static_cast(idMath::Floor(time / 3600.0f)); - unsigned int minutes = time % 3600; - minutes = static_cast(idMath::Floor(minutes / 60.0f)); - unsigned int seconds = time % 60; - - return va("%02d:%02d:%02d", hours, minutes, seconds); - } -}; - -#endif /* __GAMEPLAY_TIMER_H__ */ diff --git a/DarkMod/Http/HttpConnection.cpp b/DarkMod/Http/HttpConnection.cpp deleted file mode 100644 index 4805e1d0a..000000000 --- a/DarkMod/Http/HttpConnection.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "HttpConnection.h" -#include "HttpRequest.h" - -#ifdef WIN32 -#pragma warning(disable: 4800) // stgatilov: suppress "forcing value to bool" warning in WinSDK -#include // greebo: need to include winsock2 before curl/curl.h -#include -#include -#endif - -#include - -CHttpConnection::CHttpConnection() -{ - curl_global_init(CURL_GLOBAL_ALL); -} - -CHttpConnection::~CHttpConnection() -{ - // Clean up cURL - curl_global_cleanup(); -} - -bool CHttpConnection::HasProxy() -{ - return idStr::Length(cv_tdm_proxy.GetString()) > 0; -} - -idStr CHttpConnection::GetProxyHost() -{ - return cv_tdm_proxy.GetString(); -} - -idStr CHttpConnection::GetProxyUsername() -{ - return cv_tdm_proxy_user.GetString(); -} - -idStr CHttpConnection::GetProxyPassword() -{ - return cv_tdm_proxy_pass.GetString(); -} - -CHttpRequestPtr CHttpConnection::CreateRequest(const std::string& url) -{ - return CHttpRequestPtr(new CHttpRequest(*this, url)); -} - -CHttpRequestPtr CHttpConnection::CreateRequest(const std::string& url, const std::string& destFilename) -{ - return CHttpRequestPtr(new CHttpRequest(*this, url, destFilename)); -} diff --git a/DarkMod/Http/HttpConnection.h b/DarkMod/Http/HttpConnection.h deleted file mode 100644 index 10fc20dd5..000000000 --- a/DarkMod/Http/HttpConnection.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _HTTP_CONNECTION_H_ -#define _HTTP_CONNECTION_H_ - -#include - -class CHttpRequest; -typedef boost::shared_ptr CHttpRequestPtr; - -/** - * greebo: An object representing a single HttpConnection, holding - * proxy settings and providing error handling. - * - * Use the CreateRequest() method to generate a new request object. - * - * TDM provides a single http connection object via the gameLocal class: - * - * gameLocal.m_HttpConnection->CreateRequest("http://www.thedarkmod.com"); - * - * Note: the m_HttpConnection object can be NULL if HTTP requests have been - * disabled by the user. - */ -class CHttpConnection -{ - friend class idGameLocal; - -private: - CHttpConnection(); - -public: - ~CHttpConnection(); - - bool HasProxy(); - - idStr GetProxyHost(); - idStr GetProxyUsername(); - idStr GetProxyPassword(); - - /** - * Constructs a new HTTP request using the given URL (optional: filename) - */ - CHttpRequestPtr CreateRequest(const std::string& url); - CHttpRequestPtr CreateRequest(const std::string& url, const std::string& destFilename); -}; -typedef boost::shared_ptr CHttpConnectionPtr; - -#endif /* _HTTP_CONNECTION_H_ */ diff --git a/DarkMod/Http/HttpRequest.h b/DarkMod/Http/HttpRequest.h deleted file mode 100644 index c0b4696ee..000000000 --- a/DarkMod/Http/HttpRequest.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _HTTP_REQUEST_H_ -#define _HTTP_REQUEST_H_ - -#include -#include - -class CHttpConnection; - -#include "../pugixml/pugixml.hpp" -typedef void CURL; - -// Shared_ptr typedef -typedef boost::shared_ptr XmlDocumentPtr; - -/** - * greebo: An object representing a single HttpRequest, holding - * the result (string) and status information. - * - * Use the Perform() method to execute the request. - */ -class CHttpRequest -{ -public: - - enum RequestStatus - { - NOT_PERFORMED_YET, - OK, // successful - IN_PROGRESS, - FAILED, - ABORTED, - }; - -private: - // The connection we're working with - CHttpConnection& _conn; - - // The URL we're supposed to query - std::string _url; - - std::vector _buffer; - - // The curl handle - CURL* _handle; - - // The current state - RequestStatus _status; - - std::string _destFilename; - - std::ofstream _destStream; - - // True if we should cancel the download - bool _cancelFlag; - - double _progress; - -public: - CHttpRequest(CHttpConnection& conn, const std::string& url); - - CHttpRequest(CHttpConnection& conn, const std::string& url, const std::string& destFilename); - - // Callbacks for CURL - static size_t WriteMemoryCallback(void* ptr, size_t size, size_t nmemb, CHttpRequest* self); - static size_t WriteFileCallback(void* ptr, size_t size, size_t nmemb, CHttpRequest* self); - - RequestStatus GetStatus(); - - // Perform the request - void Perform(); - - void Cancel(); - - // Between 0.0 and 1.0 - double GetProgressFraction(); - - // Returns the result string - std::string GetResultString(); - - // Returns the result as XML document - XmlDocumentPtr GetResultXml(); - -private: - void InitRequest(); - - void UpdateProgress(); -}; -typedef boost::shared_ptr CHttpRequestPtr; - -#endif /* _HTTP_REQUEST_H_ */ diff --git a/DarkMod/Inventory/Item.cpp b/DarkMod/Inventory/Item.cpp deleted file mode 100644 index f4caa62fe..000000000 --- a/DarkMod/Inventory/Item.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#pragma warning(disable : 4533 4800) - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "Item.h" -#include "Inventory.h" -#include - -CInventoryItem::CInventoryItem(idEntity *owner) -{ - m_Owner = owner; - m_Item = NULL; - m_Category = NULL; - m_Type = IT_ITEM; - m_LootType = LOOT_NONE; - m_Value = 0; - m_Stackable = false; - m_Count = 1; - m_Droppable = false; - m_Overlay = OVERLAYS_INVALID_HANDLE; - m_Hud = false; - m_Orientated = false; - m_Persistent = false; - m_LightgemModifier = 0; - m_MovementModifier = 1.0f; - m_FrobDistanceCap = -1; - m_UseOnFrob = false; - m_DropOrientation = mat3_identity; -} - -CInventoryItem::CInventoryItem(idEntity* itemEntity, idEntity* owner) { - // Don't allow NULL pointers - assert(owner && itemEntity); - - // Parse a few common spawnargs - ParseSpawnargs(itemEntity->spawnArgs); - - m_Category = NULL; - m_Overlay = OVERLAYS_INVALID_HANDLE; - m_Hud = false; - - m_Owner = owner; - m_Item = itemEntity; - - // Determine and set the loot type - m_LootType = GetLootTypeFromSpawnargs(itemEntity->spawnArgs); - - // Read the spawnargs into the member variables - m_Name = itemEntity->spawnArgs.GetString("inv_name", ""); - // Tels: Replace "\n" with \x0a, otherwise multiline names set inside DR do not work - m_Name.Replace( "\\n", "\n" ); - m_Value = itemEntity->spawnArgs.GetInt("inv_loot_value", "-1"); - m_Stackable = itemEntity->spawnArgs.GetBool("inv_stackable", "0"); - m_UseOnFrob = itemEntity->spawnArgs.GetBool("inv_use_on_frob", "0"); - - m_Count = (m_Stackable) ? itemEntity->spawnArgs.GetInt("inv_count", "1") : 1; - - m_Droppable = itemEntity->spawnArgs.GetBool("inv_droppable", "0"); - m_ItemId = itemEntity->spawnArgs.GetString("inv_item_id", ""); - - if (m_Icon.IsEmpty() && m_LootType == LOOT_NONE) - { - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Information: non-loot item %s has no icon.\r", itemEntity->name.c_str()); - } - - if (m_LootType != LOOT_NONE && m_Value <= 0) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Warning: Value for loot item missing on entity %s\r", itemEntity->name.c_str()); - } - - // Set the item type according to the loot property - m_Type = (m_LootType != LOOT_NONE) ? IT_LOOT : IT_ITEM; - - m_BindMaster = itemEntity->GetBindMaster(); - m_Orientated = itemEntity->fl.bindOrientated; - - idStr hudName; - // Item could be added to the inventory, check for custom HUD - if (itemEntity->spawnArgs.GetString("inv_hud", "", hudName) != false) - { - int hudLayer; - itemEntity->spawnArgs.GetInt("inv_hud_layer", "0", hudLayer); - SetHUD(hudName, hudLayer); - } - - // Check for a preferred drop orientation, if not, use current orientation - if( itemEntity->spawnArgs.FindKey("drop_angles") ) - { - idAngles DropAngles; - DropAngles = itemEntity->spawnArgs.GetAngles("drop_angles"); - m_DropOrientation = DropAngles.ToMat3(); - } - else - { - idVec3 dummy; - idMat3 playerView; - gameLocal.GetLocalPlayer()->GetViewPos(dummy, playerView); - // drop orientation is relative to the player view yaw only - idAngles viewYaw = playerView.ToAngles(); - // ignore pitch and roll - viewYaw[0] = 0; - viewYaw[2] = 0; - idMat3 playerViewYaw = viewYaw.ToMat3(); - - m_DropOrientation = itemEntity->GetPhysics()->GetAxis() * playerViewYaw.Transpose(); - } -} - -void CInventoryItem::Save( idSaveGame *savefile ) const -{ - m_Owner.Save(savefile); - m_Item.Save(savefile); - - savefile->WriteBool(m_ItemDict != NULL); - - if (m_ItemDict != NULL) - { - savefile->WriteDict(m_ItemDict.get()); - } - - m_BindMaster.Save(savefile); - - savefile->WriteString(m_Name); - savefile->WriteString(m_HudName); - savefile->WriteString(m_ItemId); - - savefile->WriteInt(static_cast(m_Type)); - savefile->WriteInt(static_cast(m_LootType)); - - savefile->WriteInt(m_Value); - savefile->WriteInt(m_Overlay); - savefile->WriteInt(m_Count); - - savefile->WriteBool(m_Stackable); - savefile->WriteBool(m_Droppable); - savefile->WriteBool(m_Hud); - - savefile->WriteString(m_Icon); - - savefile->WriteBool(m_Orientated); - savefile->WriteBool(m_Persistent); - - savefile->WriteInt(m_LightgemModifier); - savefile->WriteFloat(m_MovementModifier); - savefile->WriteBool(m_UseOnFrob); - savefile->WriteFloat(m_FrobDistanceCap); - savefile->WriteMat3(m_DropOrientation); -} - -void CInventoryItem::Restore( idRestoreGame *savefile ) -{ - m_Owner.Restore(savefile); - m_Item.Restore(savefile); - - bool hasDict; - savefile->ReadBool(hasDict); - - if (hasDict) - { - m_ItemDict.reset(new idDict); - savefile->ReadDict(m_ItemDict.get()); - } - else - { - m_ItemDict.reset(); - } - - m_BindMaster.Restore(savefile); - - savefile->ReadString(m_Name); - savefile->ReadString(m_HudName); - savefile->ReadString(m_ItemId); - - int tempInt; - savefile->ReadInt(tempInt); - m_Type = static_cast(tempInt); - - savefile->ReadInt(tempInt); - m_LootType = static_cast(tempInt); - - savefile->ReadInt(m_Value); - savefile->ReadInt(m_Overlay); - savefile->ReadInt(m_Count); - - savefile->ReadBool(m_Stackable); - savefile->ReadBool(m_Droppable); - savefile->ReadBool(m_Hud); - - savefile->ReadString(m_Icon); - - savefile->ReadBool(m_Orientated); - savefile->ReadBool(m_Persistent); - - savefile->ReadInt(m_LightgemModifier); - savefile->ReadFloat(m_MovementModifier); - savefile->ReadBool(m_UseOnFrob); - savefile->ReadFloat(m_FrobDistanceCap); - savefile->ReadMat3(m_DropOrientation); -} - -void CInventoryItem::ParseSpawnargs(const idDict& spawnArgs) -{ - m_Persistent = spawnArgs.GetBool("inv_persistent", "0"); - m_LightgemModifier = spawnArgs.GetInt("inv_lgmodifier", "0"); - m_MovementModifier = spawnArgs.GetFloat("inv_movement_modifier", "1"); - m_FrobDistanceCap = spawnArgs.GetFloat("inv_frob_distance_cap", "-1"); - m_Icon = spawnArgs.GetString("inv_icon", ""); -} - -void CInventoryItem::SetLootType(LootType t) -{ - // Only positive values are allowed - if (t >= LOOT_NONE && t <= LOOT_COUNT) - { - m_LootType = t; - } - else - { - m_LootType = LOOT_NONE; - } - - NotifyItemChanged(); -} - -void CInventoryItem::SetValue(int n) -{ - // Only positive values are allowed - if (n >= 0) - { - m_Value = n; - - NotifyItemChanged(); - } -} - -void CInventoryItem::SaveItemEntityDict() -{ - idEntity* ent = GetItemEntity(); - - if (ent == NULL) - { - return; - } - - // We have a non-NULL item entity, save its spawnargs - m_ItemDict.reset(new idDict); - - // Copy spawnargs over - *m_ItemDict = ent->spawnArgs; -} - -void CInventoryItem::RestoreItemEntityFromDict(const idVec3& entPosition) -{ - if (!m_ItemDict) - { - return; // no saved spawnargs, do nothing - } - - // We have an item dictionary, let's respawn our entity - idEntity* ent; - - if (!gameLocal.SpawnEntityDef(*m_ItemDict, &ent)) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Can't respawn inventory item entity '%s'!\r", m_ItemDict->GetString("name")); - gameLocal.Error("Can't respawn inventory item entity '%s'!", m_ItemDict->GetString("name")); - } - - // Place the entity at the given position - ent->SetOrigin(entPosition); - - // Hide the entity (don't delete it) - CInventory::RemoveEntityFromMap(ent, false); - - // Set this as new item entity - SetItemEntity(ent); - - // Finally, remove our saved spawnargs - m_ItemDict.reset(); -} - -const idDict* CInventoryItem::GetSavedItemEntityDict() const -{ - return m_ItemDict ? m_ItemDict.get() : NULL; -} - -void CInventoryItem::SetCount(int n) -{ - // Only positive values are allowed - m_Count = (n >= 0) ? n : 0; - - NotifyItemChanged(); -} - -void CInventoryItem::SetStackable(bool stack) -{ - m_Stackable = stack; -} - -void CInventoryItem::SetHUD(const idStr &HudName, int layer) -{ - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Setting hud %s on layer %d\r", HudName.c_str(), layer); - if (m_Overlay == OVERLAYS_INVALID_HANDLE || m_HudName != HudName) - { - idEntity *owner = GetOwner(); - - m_Hud = true; - m_HudName = HudName; - m_Overlay = owner->CreateOverlay(HudName, layer); - idEntity* it = m_Item.GetEntity(); - if (it != NULL) - { - it->CallScriptFunctionArgs("inventory_item_init", true, 0, "eefs", it, owner, (float)m_Overlay, HudName.c_str()); - } - } - - NotifyItemChanged(); -} - -void CInventoryItem::SetOverlay(const idStr &HudName, int overlay) -{ - if (overlay != OVERLAYS_INVALID_HANDLE) - { - idEntity *owner = GetOwner(); - - m_Hud = true; - m_HudName = HudName; - m_Overlay = overlay; - idEntity* it = m_Item.GetEntity(); - if (it != NULL) - { - it->CallScriptFunctionArgs("inventory_item_init", true, 0, "eefs", it, owner, (float)m_Overlay, HudName.c_str()); - } - } - else - { - m_Hud = false; - } -} - -LootType CInventoryItem::GetLootTypeFromSpawnargs(const idDict& spawnargs) -{ - // Determine the loot type - int lootTypeInt; - LootType returnValue = LOOT_NONE; - - if (spawnargs.GetInt("inv_loot_type", "", lootTypeInt) != false) - { - if (lootTypeInt >= LOOT_NONE && lootTypeInt < LOOT_COUNT) - { - returnValue = static_cast(lootTypeInt); - } - else - { - DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("Invalid loot type: %d\r", lootTypeInt); - } - } - - return returnValue; -} - -int CInventoryItem::GetPersistentCount() -{ - if (m_Persistent) - { - return m_Count; - } - else - { - return 0; - } -} - -void CInventoryItem::SetPersistent(bool newValue) -{ - m_Persistent = newValue; -} - -void CInventoryItem::SetLightgemModifier(int newValue) -{ - // greebo: Clamp the value to [0..1] - m_LightgemModifier = idMath::ClampInt(0, DARKMOD_LG_MAX, newValue); -} - -void CInventoryItem::SetMovementModifier(float newValue) -{ - if (newValue > 0) - { - m_MovementModifier = newValue; - } -} - -void CInventoryItem::SetDropOrientation(const idMat3& newAxis) -{ - m_DropOrientation = newAxis; -} - -void CInventoryItem::SetIcon(const idStr& newIcon) -{ - m_Icon = newIcon; - - NotifyItemChanged(); -} - -void CInventoryItem::NotifyItemChanged() -{ - if (m_Owner.GetEntity() == NULL) return; - - m_Owner.GetEntity()->OnInventoryItemChanged(); -} diff --git a/DarkMod/Inventory/Item.h b/DarkMod/Inventory/Item.h deleted file mode 100644 index 5ac41a31e..000000000 --- a/DarkMod/Inventory/Item.h +++ /dev/null @@ -1,210 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef __DARKMOD_INVENTORYITEM_H__ -#define __DARKMOD_INVENTORYITEM_H__ - -#include "LootType.h" - -/* FORWARD DECLS */ -class CInventoryCategory; - -/** - * InventoryItem is an item that belongs to a group. - */ -class CInventoryItem -{ -public: - enum ItemType - { - IT_ITEM, // Normal item, which is associated to an entity - IT_LOOT, // this is a loot item - IT_LOOT_INFO, // loot info item - IT_WEAPON, // a weapon item - IT_DUMMY, // This also doesn't have an entity, but provides a dummy so - // we can have an empty space in the inventory. - IT_COUNT - }; - -public: - CInventoryItem(idEntity *m_Owner); - - // Create an inventoryitem out of the given entity and the given owner - CInventoryItem(idEntity* itemEntity, idEntity* owner); - - virtual void Save( idSaveGame *savefile ) const; - virtual void Restore( idRestoreGame *savefile ); - - CInventoryCategory* Category() const { return m_Category; } - void SetCategory(CInventoryCategory* newCategory) { m_Category = newCategory; }; - - idEntity* GetOwner() { return m_Owner.GetEntity(); }; - void SetOwner(idEntity* newOwner) { m_Owner = newOwner; }; - - void SetItemEntity(idEntity *ent) { m_Item = ent; }; - idEntity* GetItemEntity() { return m_Item.GetEntity(); } - - // Stores the item entity's spawnargs locally - used before ending a mission to prepare an item/entity transfer - // Does nothing if the item entity is NULL - virtual void SaveItemEntityDict(); - - // Restores the item entity from the saved dictionary. Does nothing if the saved dictionary is empty. - // The position is needed to place the respawned entity somewhere valid - virtual void RestoreItemEntityFromDict(const idVec3& entPosition); - - // Get a reference to the saved item entity dictionary. Returns NULL if the spawnargs didn't get saved - // This usually returns non-NULL for items stored in the game's persistent inventory, for inter-mission item transfer - const idDict* GetSavedItemEntityDict() const; - - void SetType(CInventoryItem::ItemType type) { m_Type = type; }; - ItemType GetType() { return m_Type; }; - - int GetCount() { return m_Count; }; - void SetCount(int Amount); - - bool IsStackable() { return m_Stackable; }; - void SetStackable(bool); - - void SetDroppable(bool bDroppable) { m_Droppable = bDroppable; }; - bool IsDroppable() { return m_Droppable; }; - - void SetLootType(LootType t); - LootType GetLootType() { return m_LootType; }; - - void SetValue(int n); - int GetValue() { return m_Value; }; - - void SetName(const idStr &n) { m_Name = n; }; - const idStr& GetName() { return m_Name; }; - - void SetItem(idEntity *item) { m_Item = item; }; - idEntity* GetItem() { return m_Item.GetEntity(); }; - - int GetOverlay() { return m_Overlay; }; - void SetOverlay(const idStr &HudName, int Overlay); - bool HasHUD() { return m_Hud; }; - void SetHUD(const idStr &HudName, int layer); - const idStr& GetHUD() { return m_HudName; }; - - const idStr& GetIcon() { return m_Icon; }; - void SetIcon(const idStr& newIcon); - - void SetItemId(const idStr &id) { m_ItemId = id; }; - const idStr& GetItemId() { return m_ItemId; }; - - static LootType GetLootTypeFromSpawnargs(const idDict& spawnargs); - - /** - * greebo: This returns the number of persistent items contained in this InventoryItem. - * For ordinary persistent items, this is always 1, for non-persistent items this is 0. - * Stackable persistent items will return the current stack count. - */ - int GetPersistentCount(); - - bool IsPersistent() const { return m_Persistent; }; - void SetPersistent(bool newValue); - - /** - * greebo: When this item is active, the lightgem can be modified by this value. - * The integer value should be between 0 and DARKMOD_LG_MAX and is added to the - * the result of the lightgem renderpasses. Corresponds to the spawnarg "inv_lgmodifier" - */ - int GetLightgemModifier() { return m_LightgemModifier; } - void SetLightgemModifier(int newValue); - - /** - * greebo: When this item is active, the owner can be encumbered (or even accelerated?) - * by a certain factor. Each item can have its own movement modifier, which is defined - * in the "inv_movement_modifer" spawnarg. - * - * @modifier value range: a floating point variable in [0, INF]. This value is applied to - * the maximum player movement speed by multiplication. - */ - float GetMovementModifier() { return m_MovementModifier; } - void SetMovementModifier(float newValue); - /** - * Get/set the drop orientation - **/ - const idMat3& GetDropOrientation() { return m_DropOrientation; } - void SetDropOrientation(const idMat3& newAxis); - - // Returns true when this item should be used by the 'frob' impulse - bool UseOnFrob() const { return m_UseOnFrob; } - - // Returns the frob distance cap. If this item doesn't enforce such a value, this returns idMath::INFINITY. - float GetFrobDistanceCap() - { - return (m_FrobDistanceCap == -1) ? idMath::INFINITY : m_FrobDistanceCap; - } - -protected: - // Reads the values from the given spawnargs into the member variables - void ParseSpawnargs(const idDict& spawnArgs); - - // Calls the owner's OnInventoryItemChanged() method - void NotifyItemChanged(); - -protected: - idEntityPtr m_Owner; - idEntityPtr m_Item; - - // greebo: Optional item dictionary. This is used to transfer inventory items between missions - // including their item entities. These entities will be saved at mission end and re-spawned at the - // start of the next mission. - boost::shared_ptr m_ItemDict; - - idEntityPtr m_BindMaster; - idStr m_Name; - idStr m_HudName; // filename for the hud file if it has a custom hud - idStr m_ItemId; // Arbitrary Id, that the mapper can use to idenitfy an item. - // It is also needed to identify items which are stackable - // to make them identifiable. This can be used, for example - // to create a fake health potion which shows up in the inventory - // as a regular health potion, but actually deals damage. Needs - // custom scripting to actually do this though. - CInventoryCategory* m_Category; - ItemType m_Type; - LootType m_LootType; - int m_Value; - int m_Overlay; - int m_Count; // How many of that item are currently represented (i.e. Arrows) - bool m_Stackable; // Counter can be used if true, otherwise it's a unique item - bool m_Droppable; // If the item is not dropable it will be inaccessible after it - // is put into the inventory - bool m_Hud; - idStr m_Icon; // The inventory icon string - bool m_Orientated; // Taken from the entity - - bool m_Persistent; // Can be taken to the next map (default is FALSE) - - int m_LightgemModifier; // Is added to the lightgem when this item is active - - // A value in [0,1] defining the fraction of the regular movement speed - // which the owner is allowed to move with when this item is equipped. - float m_MovementModifier; - - /** - * greebo: When this inventory item is selected, the frob distance can not be higher - * than the value defined here. Is -1 if not set. - */ - float m_FrobDistanceCap; - - bool m_UseOnFrob; // Whether this item can be used by the 'frob' button - - /** - * Which way the object should orient itself when dropping - * Relative to the player's view axis (x,y,z = forward,left,up) - * Typically it maintains the same relative orientation to the player - * that it had when the player picked it up. - * Except for pitch, which is the same as its original pitch - **/ - idMat3 m_DropOrientation; -}; -typedef boost::shared_ptr CInventoryItemPtr; - -#endif /* __DARKMOD_INVENTORYITEM_H__ */ diff --git a/DarkMod/Inventory/LootType.h b/DarkMod/Inventory/LootType.h deleted file mode 100644 index a4a6e3931..000000000 --- a/DarkMod/Inventory/LootType.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef __DARKMOD_LOOTTYPES_H__ -#define __DARKMOD_LOOTTYPES_H__ - -enum LootType -{ - LOOT_NONE, // No lootobject - LOOT_JEWELS, - LOOT_GOLD, - LOOT_GOODS, - LOOT_COUNT -}; - -#endif diff --git a/DarkMod/LightController.h b/DarkMod/LightController.h deleted file mode 100644 index db62906ad..000000000 --- a/DarkMod/LightController.h +++ /dev/null @@ -1,97 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2010 Tels (Donated to The Dark Mod) - -#ifndef __DARKMOD_LIGHTCONTROLLER_H__ -#define __DARKMOD_LIGHTCONTROLLER_H__ - -/* -=============================================================================== - - Light Controller - control local ambient lights depending on which lights - are in the same area/close to them. - - This class is a singleton and initiated/destroyed from gameLocal. - -=============================================================================== -*/ - -// Defines data for each ambient light the light controller controls: -typedef struct { - idVec3 origin; - idVec3 color; // current color of the light - idVec3 target_color; // the target coloer -} light_controller_ambient_t; - -// Defines data for each light the light controller uses to control the ambients: -typedef struct { - idVec3 origin; - idVec3 color; // current color of the light - float radius; // average of the radius -} light_controller_light_t; - - -class CLightController { -public: - //CLASS_PROTOTYPE( CModelGenerator ); - - CLightController( void ); - - ~CLightController(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * Called by gameLocal. - */ - void Init ( void ); - void Clear ( void ); - - /** - * Register a light with the controller. - */ - void RegisterLight ( void ); - - /** - * De-register a light with the controller. - */ - void UnregisterLight ( void ); - - /** - * Register a local ambient light with the controller. - */ - void RegisterAmbient ( void ); - - /** - * Unregister a local ambient light with the controller. - */ - void UnregisterAmbient ( void ); - - /** - * Update the local ambient lights because the light has changed. - */ - void LightChanged( const int entityNum ); - -private: - // Called by the dtor - void Shutdown(); - -private: - - idList< light_controller_ambient_t > m_Ambients; - idList< light_controller_light_t > m_Lights; - - bool m_bActive; -}; - -#endif /* !__DARKMOD_LIGHTCONTROLLER_H__ */ - diff --git a/DarkMod/Missions/DownloadManager.cpp b/DarkMod/Missions/DownloadManager.cpp deleted file mode 100644 index 342871864..000000000 --- a/DarkMod/Missions/DownloadManager.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "DownloadManager.h" - -CDownloadManager::CDownloadManager() : - _nextAvailableId(1), - _allDownloadsDone(true) -{} - -int CDownloadManager::AddDownload(const CDownloadPtr& download) -{ - int id = _nextAvailableId++; - - _downloads[id] = download; - - _allDownloadsDone = false; - - return id; -} - -CDownloadPtr CDownloadManager::GetDownload(int id) -{ - Downloads::iterator found = _downloads.find(id); - - return (found != _downloads.end()) ? found->second : CDownloadPtr(); -} - -void CDownloadManager::ClearDownloads() -{ - _downloads.clear(); -} - -bool CDownloadManager::DownloadInProgress() -{ - for (Downloads::const_iterator i = _downloads.begin(); i != _downloads.end(); ++i) - { - if (i->second->GetStatus() == CDownload::IN_PROGRESS) - { - return true; - } - } - - return false; -} - -void CDownloadManager::RemoveDownload(int id) -{ - Downloads::iterator found = _downloads.find(id); - - if (found != _downloads.end()) - { - _downloads.erase(found); - } -} - -void CDownloadManager::ProcessDownloads() -{ - if (_allDownloadsDone || _downloads.empty()) - { - return; // nothing to do - } - - if (DownloadInProgress()) - { - return; // download still in progress - } - - // No download in progress, pick a new from the queue - for (Downloads::const_iterator i = _downloads.begin(); i != _downloads.end(); ++i) - { - if (i->second->GetStatus() == CDownload::NOT_STARTED_YET) - { - DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("Starting download: %i", i->first); - - i->second->Start(); - - // Check if this download has a related one, if yes, launch both at once - int relatedId = i->second->GetRelatedDownloadId(); - - if (relatedId != -1) - { - CDownloadPtr related = GetDownload(relatedId); - - if (related) - { - DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("Starting related download: %i", relatedId); - - related->Start(); - } - } - - return; - } - } - - // No download left to handle - _allDownloadsDone = true; -} diff --git a/DarkMod/Missions/DownloadManager.h b/DarkMod/Missions/DownloadManager.h deleted file mode 100644 index f0c0e0c12..000000000 --- a/DarkMod/Missions/DownloadManager.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _MISSION_DOWNLOAD_MANAGER_H_ -#define _MISSION_DOWNLOAD_MANAGER_H_ - -#include -#include "Download.h" - -/** - * The class handling the actual mission downloads. - */ -class CDownloadManager -{ -private: - // Ongoing downloads - typedef std::map Downloads; - Downloads _downloads; - - int _nextAvailableId; - - bool _allDownloadsDone; - -public: - CDownloadManager(); - - void ProcessDownloads(); - - void ClearDownloads(); - - int AddDownload(const CDownloadPtr& download); - void RemoveDownload(int id); - - CDownloadPtr GetDownload(int id); - - // Returns true if there is a download already in progress - bool DownloadInProgress(); -}; -typedef boost::shared_ptr CDownloadManagerPtr; - -#endif /* _MISSION_DOWNLOAD_MANAGER_H_ */ diff --git a/DarkMod/Missions/MissionDB.h b/DarkMod/Missions/MissionDB.h deleted file mode 100644 index ea780af07..000000000 --- a/DarkMod/Missions/MissionDB.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _MISSION_DB_H_ -#define _MISSION_DB_H_ - -#include -#include -#include "ModInfo.h" - -/** - * greebo: The mission database class holds the list of available TDM missions - * and the corresponding data like play statistics, size info, etc. - */ -class CMissionDB -{ -private: - // Named mission info structures (fs_game => info) - typedef std::map MissionInfoMap; - MissionInfoMap _missionInfo; - -public: - CMissionDB(); - - void Init(); - - // Saves changed data to disk - void Save(); - - // Returns the mission info structure for this fs_game - // Always returns non-NULL, if the name is not existing, - // a new structure will be created - const CModInfoPtr& GetModInfo(const idStr& name); - - // Checks whether there is a record for the given mod name - bool ModInfoExists(const idStr& name); - -private: - void ReloadMissionInfoFile(); -}; -typedef boost::shared_ptr CMissionDBPtr; - -#endif /* _MISSION_DB_H_ */ diff --git a/DarkMod/Missions/ModInfoDecl.cpp b/DarkMod/Missions/ModInfoDecl.cpp deleted file mode 100644 index 4da00e9d5..000000000 --- a/DarkMod/Missions/ModInfoDecl.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "ModInfoDecl.h" - -const char* const CModInfoDecl::TYPE_NAME = "tdm_missioninfo"; - -bool CModInfoDecl::Parse(idLexer& src) -{ - idToken key; - idToken value; - - if (!src.ReadToken(&key)) - { - src.Warning("Unclosed mod info declaration."); - return false; - } - - if (key.type != TT_PUNCTUATION || key.subtype != P_BRACEOPEN) - { - src.Warning("Cannot find opening brace in file %s:%d.", src.GetFileName(), src.GetLineNum()); - return false; - } - - while (true) - { - // If there's an EOF, this is an error. - if (!src.ReadToken(&key)) - { - src.Warning("Unclosed mod info declaration."); - return false; - } - - // Quit upon encountering the closing brace. - if (key.type == TT_PUNCTUATION && key.subtype == P_BRACECLOSE) - { - break; - } - else if (key.type == TT_STRING) - { - // Found a string, this must be a key - if (!src.ReadToken(&value)) - { - src.Warning("Unexpected EOF in key/value pair."); - return false; - } - - if (value.type == TT_STRING) - { - // Save the key:value pair. - data.Set(key.c_str(), value.c_str()); - } - else - { - src.Warning("Invalid value: %s", value.c_str()); - continue; - } - } - else - { - src.Warning("Unrecognized token: %s", key.c_str()); - continue; - } - } - - return true; -} - -void CModInfoDecl::Update(const idStr& name) -{ - _bodyText = TYPE_NAME; - _bodyText += " " + name; - _bodyText += "\n{\n"; - - // Dump the keyvalues - for (int i = 0; i < data.GetNumKeyVals(); ++i) - { - const idKeyValue* kv = data.GetKeyVal(i); - - _bodyText += "\t\"" + kv->GetKey() + "\""; - _bodyText += "\t\"" + kv->GetValue() + "\"\n"; - } - - _bodyText += "}\n\n"; -} - -void CModInfoDecl::SaveToFile(idFile* file) -{ - file->Write(_bodyText.c_str(), _bodyText.Length()); -} diff --git a/DarkMod/Missions/ModInfoDecl.h b/DarkMod/Missions/ModInfoDecl.h deleted file mode 100644 index 0f428c8f3..000000000 --- a/DarkMod/Missions/ModInfoDecl.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _MOD_INFO_DECL_H_ -#define _MOD_INFO_DECL_H_ - -#include "../../idlib/precompiled.h" -#include - -class CModInfoDecl -{ -private: - // The body text used for saving - idStr _bodyText; - -public: - // Construct this declaration from the given token stream - bool Parse(idLexer& src); - - /// Key/value data parsed from the mod info decl. - idDict data; - - // Regenerates the declaration body using the given name as decl name - void Update(const idStr& name); - - // Append the data to the given file - void SaveToFile(idFile* file); - - static const char* const TYPE_NAME; -}; -typedef boost::shared_ptr CModInfoDeclPtr; - -#endif /* _MOD_INFO_DECL_H_ */ diff --git a/DarkMod/ModMenu.h b/DarkMod/ModMenu.h deleted file mode 100644 index 8ec794c5f..000000000 --- a/DarkMod/ModMenu.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef _MOD_MENU_H_ -#define _MOD_MENU_H_ - -#pragma once - -#include - -class CModInfo; -typedef boost::shared_ptr CModInfoPtr; - -// Handles mainmenu that displays list of mods (FMs) and lets user -// chose which one to load. Also handles display of briefing page -class CModMenu -{ -private: - // The index of the first displayed mod - int _modTop; - - int _briefingPage; - -public: - CModMenu(); - - // handles main menu commands - void HandleCommands(const idStr& cmd, idUserInterface* gui); - - // updates the GUI variables - void UpdateGUI(idUserInterface* gui); - - // displays the current briefing page - void DisplayBriefingPage(idUserInterface* gui); - -private: - - // Performs the version check and returns TRUE if positive, - // returns FALSE otherwise (and issues failure calls to the given GUI) - bool PerformVersionCheck(const CModInfoPtr& mission, idUserInterface* gui); - - void UpdateSelectedMod(idUserInterface* gui); - - // Installs the given mod (doesn't accept NULL pointers); - void InstallMod(const CModInfoPtr& mod, idUserInterface* gui); - - // Uninstalls the current FM - void UninstallMod(idUserInterface* gui); - - // Restarts the game after mod installation - void RestartGame(); -}; - -#endif /* _MOD_MENU_H_ */ diff --git a/DarkMod/MultiStateMoverButton.cpp b/DarkMod/MultiStateMoverButton.cpp deleted file mode 100644 index b20636e8d..000000000 --- a/DarkMod/MultiStateMoverButton.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "DarkModGlobals.h" -#include "MultiStateMoverButton.h" -#include "MultiStateMover.h" - -//=============================================================================== -// CMultiStateMoverButton -//=============================================================================== - -const idEventDef EV_RegisterSelfWithElevator("MSMBRegisterSelfWithElevator", NULL); - -CLASS_DECLARATION( CFrobButton, CMultiStateMoverButton ) - EVENT( EV_RegisterSelfWithElevator, CMultiStateMoverButton::Event_RegisterSelfWithElevator) -END_CLASS - -void CMultiStateMoverButton::Spawn() -{ - if (!spawnArgs.GetBool("ride", "0") && !spawnArgs.GetBool("fetch", "0")) - { - gameLocal.Warning("Elevator button %s has neither 'fetch' nor 'ride' spawnargs set. AI will not be able to use this button!", name.c_str()); - } - - PostEventMS(&EV_RegisterSelfWithElevator, 10); -} - -void CMultiStateMoverButton::Event_RegisterSelfWithElevator() -{ - for (int i = 0; i < targets.Num(); i++) - { - idEntity* ent = targets[i].GetEntity(); - - if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) - { - continue; - } - - CMultiStateMover* elevator = static_cast(ent); - - // Send the information about us to the elevator - if (spawnArgs.GetBool("ride", "0")) - { - elevator->RegisterButton(this, BUTTON_TYPE_RIDE); - } - - if (spawnArgs.GetBool("fetch", "0")) - { - elevator->RegisterButton(this, BUTTON_TYPE_FETCH); - } - } -} diff --git a/DarkMod/MultiStateMoverButton.h b/DarkMod/MultiStateMoverButton.h deleted file mode 100644 index 24777688e..000000000 --- a/DarkMod/MultiStateMoverButton.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __MULTISTATEMOVER_BUTTON_H_ -#define __MULTISTATEMOVER_BUTTON_H_ - -#include "FrobButton.h" - -enum EMMButtonType -{ - BUTTON_TYPE_RIDE = 0, - BUTTON_TYPE_FETCH, - NUM_BUTTON_TYPES, -}; - -/** - * greebo: A MultiStateMoverButton is a bit more intelligent - * than an ordinary FrobButton as it is "communicating" with - * the targetted elevator a bit at spawn time. - */ -class CMultiStateMoverButton : - public CFrobButton -{ -public: - - CLASS_PROTOTYPE( CMultiStateMoverButton ); - - void Spawn(); - -private: - void Event_RegisterSelfWithElevator(); -}; - -#endif /* __MULTISTATEMOVER_BUTTON_H_ */ diff --git a/DarkMod/Objectives/BoolParseNode.h b/DarkMod/Objectives/BoolParseNode.h deleted file mode 100644 index 0a5e649f8..000000000 --- a/DarkMod/Objectives/BoolParseNode.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef TDM_OBJECTIVE_BOOLPARSENODE_H -#define TDM_OBJECTIVE_BOOLPARSENODE_H - -#include "../idlib/precompiled.h" - -/** -* Structure for parsing boolean logic -**/ -struct SBoolParseNode -{ - int Ident; - bool bNotted; // set to true if this node is NOTed - - idList< idList< SBoolParseNode > > Cols; // list of columns, each can contain a different number of rows - - // Link back to previous node this one branched off from - SBoolParseNode* PrevNode; - - // matrix coordinates of this node within the matrix of the previous node - int PrevCol; - int PrevRow; - - // Functions: - - SBoolParseNode() - { - Clear(); - } - - ~SBoolParseNode() - { - Clear(); - } - - bool IsEmpty() const - { - return (Cols.Num() == 0 && Ident == -1); - } - - /** - * Clear the parse node - **/ - void Clear( void ) - { - Ident = -1; - PrevCol = -1; - PrevRow = -1; - - bNotted = false; - Cols.Clear(); - PrevNode = NULL; - } -}; - -#endif diff --git a/DarkMod/Objectives/CampaignStatistics.cpp b/DarkMod/Objectives/CampaignStatistics.cpp deleted file mode 100644 index e1518dc90..000000000 --- a/DarkMod/Objectives/CampaignStatistics.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "CampaignStatistics.h" - -void CampaignStats::Save(idSaveGame* savefile) const -{ - savefile->WriteInt(_stats.Num()); - - for (int i = 0; i < _stats.Num(); ++i) - { - _stats[i].Save(savefile); - } -} - -void CampaignStats::Restore(idRestoreGame* savefile) -{ - int num; - savefile->ReadInt(num); - _stats.SetNum(num); - - for (int i = 0; i < num; ++i) - { - _stats[i].Restore(savefile); - } -} - -void CampaignStats::EnsureSize(int size) -{ - if (_stats.Num() < size) - { - _stats.SetNum(size); - } -} diff --git a/DarkMod/Objectives/CampaignStatistics.h b/DarkMod/Objectives/CampaignStatistics.h deleted file mode 100644 index 59f24c394..000000000 --- a/DarkMod/Objectives/CampaignStatistics.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef TDM_CAMPAIGN_STATISTICS_H -#define TDM_CAMPAIGN_STATISTICS_H - -#include "../idlib/precompiled.h" - -#include "MissionStatistics.h" - -/** - * Multiple mission stats structs combined => campaign stats. - * First mission is carrying index 0. - */ -class CampaignStats -{ -private: - // The internal array of statistics - idList _stats; - -public: - // greebo: Use this operator to get access to the stats of the mission with the given index - // The internal list will automatically be resized to fit. - MissionStatistics& operator[] (int index) - { - EnsureSize(index + 1); - return _stats[index]; - } - - const MissionStatistics& operator[] (int index) const - { - return _stats[index]; - } - - int Num() const - { - return _stats.Num(); - } - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - -private: - void EnsureSize(int size); -}; - -#endif diff --git a/DarkMod/Objectives/EMissionResult.h b/DarkMod/Objectives/EMissionResult.h deleted file mode 100644 index 95c67b993..000000000 --- a/DarkMod/Objectives/EMissionResult.h +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef EMISSIONRESULT_H_ -#define EMISSIONRESULT_H_ - -enum EMissionResult { - MISSION_NOTEVENSTARTED = 0, // before any map is loaded (at game startup, for instance) - MISSION_INPROGRESS = 1, // mission not yet accomplished (in-game) - MISSION_FAILED = 2, // mission failed - MISSION_COMPLETE = 3, // mission completed -}; - -#endif /*EMISSIONRESULT_H_*/ diff --git a/DarkMod/Objectives/MissionStatistics.h b/DarkMod/Objectives/MissionStatistics.h deleted file mode 100644 index bf880cea8..000000000 --- a/DarkMod/Objectives/MissionStatistics.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef MISSIONSTATISTICS_H -#define MISSIONSTATISTICS_H - -#include "../idlib/precompiled.h" - -#include "Objective.h" // for objective state enum -#include "../Inventory/Item.h" // for loot type enum - -// Maximum array sizes: -#define MAX_TEAMS 64 -#define MAX_TYPES 16 -#define MAX_AICOMP 16 -#define MAX_ALERTLEVELS 16 - -struct SStat -{ - int Overall; - int ByTeam[ MAX_TEAMS ]; - int ByType[ MAX_TYPES ]; - int ByInnocence[2]; - int WhileAirborne; - - SStat() - { - Clear(); - } - - void Clear(); -}; - -/** -* Mission stats: Keep track of everything except for loot groups, which are tracked by the inventory -**/ -class MissionStatistics -{ -public: - // AI Stats: - SStat AIStats[ MAX_AICOMP ]; - - SStat AIAlerts[ MAX_ALERTLEVELS ]; - - int DamageDealt; - int DamageReceived; - int HealthReceived; - int PocketsPicked; - - // Item stats are handled by the inventory, not here, - // Might need this for copying over to career stats though - int FoundLoot[LOOT_COUNT]; - - // greebo: This is the available amount of loot in the mission - int LootInMission[LOOT_COUNT]; - - // This gets read out right at "mission complete" time, is 0 before - unsigned int TotalGamePlayTime; - - // Use an array to store the objective states after mission complete - // We need the historic state data to handle conditional objectives. - // This list will be empty throughout the mission, and is filled on mission complete - idList ObjectiveStates; - - // grayman #2887 - for tracking how often and for how long the player was seen - int numberTimesPlayerSeen; - int totalTimePlayerSeen; - - MissionStatistics() - { - Clear(); - } - - void Clear(); - - // Returns the state of the objective specified by the (0-based) index - // Will return INVALID if the objective index is out of bounds or no data is available - EObjCompletionState GetObjectiveState(int objNum) const; - - // Store the objective state into the ObjectiveStates array - void SetObjectiveState(int objNum, EObjCompletionState state); - - // Returns the sum of all found loot types (gold+jewels+goods) - int GetFoundLootValue() const; - - // Returns the total of all loot types in the mission (gold+jewels+goods) - int GetTotalLootInMission() const; - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); -}; - -#endif /* MISSIONSTATISTICS_H */ diff --git a/DarkMod/Objectives/ObjectiveCondition.h b/DarkMod/Objectives/ObjectiveCondition.h deleted file mode 100644 index f20239eef..000000000 --- a/DarkMod/Objectives/ObjectiveCondition.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef TDM_OBJECTIVE_CONDITION_H -#define TDM_OBJECTIVE_CONDITION_H - -#include "../idlib/precompiled.h" - -#include "Objective.h" - -class CMissionData; - -class ObjectiveCondition -{ -private: - // Possible effect types - enum Type - { - CHANGE_STATE, // changes state of target objective - CHANGE_VISIBILITY, // changes visibility of target objective - CHANGE_MANDATORY, // changes mandatory flag of target objetive - INVALID_TYPE, // not a valid type - }; - - Type _type; - - int _value; - int _srcMission; - EObjCompletionState _srcState; - int _srcObj; - int _targetObj; - -public: - // Default constructor - ObjectiveCondition(); - - // Construct from a given dictionary - ObjectiveCondition(const idDict& dict, int index); - - // Returns TRUE if the condition has enough valid parameters to be functional - bool IsValid() const; - - // Applies this conditional action to the given objectives - // Returns TRUE if the condition was applicable, FALSE otherwise - bool Apply(CMissionData& missionData); - -private: - void ParseFromSpawnargs(const idDict& dict, int index); -}; - -#endif diff --git a/DarkMod/Objectives/ObjectiveLocation.h b/DarkMod/Objectives/ObjectiveLocation.h deleted file mode 100644 index 76af20c28..000000000 --- a/DarkMod/Objectives/ObjectiveLocation.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef TDM_OBJECTIVE_LOCATION_H -#define TDM_OBJECTIVE_LOCATION_H - -#include "../idlib/precompiled.h" - -// Helper entity for objective locations -class CObjectiveLocation : public idEntity -{ -public: - CLASS_PROTOTYPE( CObjectiveLocation ); - - CObjectiveLocation(); - - ~CObjectiveLocation(); - - void Think( void ); - void Spawn( void ); - - // Called by ~idEntity to catch entity destructions - void OnEntityDestroyed(idEntity* ent); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -protected: - /** - * Clock interval [seconds] - **/ - int m_Interval; - - int m_TimeStamp; - - /** - * List of entity names that intersected bounds in previous clock tick - **/ - idList< idEntityPtr > m_EntsInBounds; - /** - * Objective system: Location's objective group name for objective checks - **/ - idStr m_ObjectiveGroup; - -private: - idClipModel * clipModel; - -}; // CObjectiveLocation - -#endif diff --git a/DarkMod/PositionWithinRangeFinder.h b/DarkMod/PositionWithinRangeFinder.h deleted file mode 100644 index 987ab23e2..000000000 --- a/DarkMod/PositionWithinRangeFinder.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef POSITION_WITHIN_RANGE_FINDER__H -#define POSITION_WITHIN_RANGE_FINDER__H - -#include "../idlib/precompiled.h" - -class PositionWithinRangeFinder : - public idAASCallback -{ -private: - idVec3 _targetPos; - idVec3 _eyeOffset; - const idAI* _self; - idMat3 _gravityAxis; - float _maxDistance; - bool _haveBestGoal; - - - idBounds excludeBounds; - pvsHandle_t targetPVS; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; - int numPVSAreas; - - aasGoal_t bestGoal; - float bestGoalDistance; - - -public: - PositionWithinRangeFinder(const idAI *self, const idMat3 &gravityAxis, - const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistance); - - ~PositionWithinRangeFinder(); - - bool TestArea( const idAAS *aas, int areaNum ); - - bool GetBestGoalResult(float& out_bestGoalDistance, aasGoal_t& out_bestGoal); -}; - -#endif /* POSITION_WITHIN_RANGE_FINDER__H */ diff --git a/DarkMod/ProjectileResult.h b/DarkMod/ProjectileResult.h deleted file mode 100644 index 13023c223..000000000 --- a/DarkMod/ProjectileResult.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2006 Chris Sarantos - -#ifndef PROJECTILE_RESULT_H -#define PROJECTILE_RESULT_H - -/** -* CProjectileResult is a dummy object that may be spawned when a projectile hits -* a surface. This object handles things like determining whether the projectile -* sticks in to the surface and may be retrieved, or if it breaks. This object -* is also used to store any stim/response information on the projectile (e.g., -* water arrow puts out torches when it detonates), and run other scripts if desired. -* -* NOTE: This object MUST be destroyed/removed in the scripts that are run -**/ - - -class CProjectileResult : public idEntity { -public: - CLASS_PROTOTYPE( CProjectileResult ); - - CProjectileResult(void); - ~CProjectileResult(void); - -/** -* Initialize the projectile result, called by the projectile -**/ - void Init - ( - SFinalProjData *pData, const trace_t &collision, - idProjectile *pProj, bool bActivate - ); - -protected: - /** - * Chooses whether to run the "active" or "dud" script, based on the material - * type hit and the activating material types. - **/ - void RunResultScript( void ); - -protected: - /** - * Collision data from the impacted projectile - **/ - trace_t m_Collision; - - /** - * Other data from the impacted projectile - **/ - SFinalProjData m_ProjData; - - /** - * True => projectile activated, false => projectile is a dud - **/ - bool m_bActivated; - - /** - * Getter events for scripting - **/ - void Event_GetFinalVel( void ); - - void Event_GetFinalAngVel( void ); - - void Event_GetAxialDir( void ); - - void Event_GetProjMass( void ); - - void Event_GetSurfType( void ); - - void Event_GetSurfNormal( void ); - - void Event_GetStruckEnt( void ); - - void Event_GetIncidenceAngle( void ); - - void Event_GetActualStruckEnt( void ); // grayman #837 - - void Event_IsVineFriendly( void ); // grayman #2787 -}; - -#endif diff --git a/DarkMod/RawVector.cpp b/DarkMod/RawVector.cpp deleted file mode 100644 index 526f4a4b9..000000000 --- a/DarkMod/RawVector.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "../idlib/precompiled.h" -#pragma hdrstop - -#include "RawVector.h" - -CRawVector::CRawVector() - : m_Pointer(0) - , m_Size(0), m_Capacity(0) -{ - reallocate(INITIAL_CAPACITY); -} - -CRawVector::~CRawVector() -{ - free(m_Pointer); -} - -void CRawVector::reallocate(int newSize) { - int newCapacity = m_Capacity << 1; - if (newCapacity < newSize) newCapacity = newSize; - - char *newbuffer = (char*)realloc(m_Pointer, newCapacity); - if (!newbuffer) - common->FatalError("CRawBuffer::resize: realloc failed (from %d to %d bytes)", m_Capacity, newCapacity); - - m_Pointer = newbuffer; - m_Capacity = newCapacity; -} - -void CRawVector::clear() { - resize(0); -} - -namespace std { - void swap(CRawVector &a, CRawVector &b) { - static const int RVS = sizeof(CRawVector); - char buffer[RVS]; - memcpy(buffer, &a, RVS); - memcpy(&a, &b, RVS); - memcpy(&b, buffer, RVS); - } -} diff --git a/DarkMod/RawVector.h b/DarkMod/RawVector.h deleted file mode 100644 index 6f202c5e0..000000000 --- a/DarkMod/RawVector.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef RAW_VECTOR_H -#define RAW_VECTOR_H - -/** - * std::vector-like raw buffer class. - * Contains raw bytes, uses C allocation routines. - * Grows exponentially, never shrinks. - * No initialization or checks are done. - * If malloc error happens then Error() is called - * Only the most necessary methods are implemented. - */ -class CRawVector { - static const int INITIAL_CAPACITY = 16; -public: - CRawVector(); - ~CRawVector(); - - ID_INLINE int size() const { return m_Size; } - ID_INLINE char &operator[] (int i) { return m_Pointer[i]; } - ID_INLINE const char &operator[] (int i) const { return m_Pointer[i]; } - - inline void resize(int newSize) - { - if (newSize > m_Capacity) reallocate(newSize); - m_Size = newSize; - } - - //note: does not free memory! - void clear(); - -private: - ///Pointer to data (allocated with malloc). - char *m_Pointer; - ///Size of vector (number of bytes). - int m_Size; - ///Size of allocated buffer. - int m_Capacity; - - ///Reallocate the memory buffer - void reallocate(int newSize); - - //Non-copyable - CRawVector(const CRawVector &other); - CRawVector &operator= (const CRawVector &other); -}; - -namespace std { - void swap(CRawVector &a, CRawVector &b); -} - -#endif diff --git a/DarkMod/RevisionTracker.cpp b/DarkMod/RevisionTracker.cpp deleted file mode 100644 index 91dc80cd1..000000000 --- a/DarkMod/RevisionTracker.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#pragma warning(disable : 4533 4800) - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "RevisionTracker.h" - -#include -#include -#include -#include -#include - -RevisionTracker::RevisionTracker() : - _highestRevision(0), - _lowestRevision(INT_MAX), - _numFiles(0) -{} - -int RevisionTracker::GetHighestRevision() const -{ - return _highestRevision; -} - -int RevisionTracker::GetLowestRevision() const -{ - return _lowestRevision; -} - -int RevisionTracker::GetNumFiles() const -{ - return _numFiles; -} - -void RevisionTracker::AddRevision(int revision) -{ - _numFiles++; - - if (_highestRevision < revision) - { - _highestRevision = revision; - } - - if (_lowestRevision > revision) - { - _lowestRevision = revision; - } -} - -void RevisionTracker::ParseSVNIdString(const char* input) -{ - std::string revStr(input); - std::vector parts; - - // Split the incoming string into parts - boost::algorithm::split(parts, revStr, boost::algorithm::is_any_of(" ")); - - if (parts.size() > 1) - { - // The third token is the SVN revision, convert it to integer and pass it along - Instance().AddRevision(atoi(parts[2].c_str())); - } -} - -// Accessor to the singleton -RevisionTracker& RevisionTracker::Instance() -{ - static RevisionTracker _instance; - return _instance; -} diff --git a/DarkMod/RevisionTracker.h b/DarkMod/RevisionTracker.h deleted file mode 100644 index c4c04924c..000000000 --- a/DarkMod/RevisionTracker.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef __TDM_REVISION_TRACKER_H__ -#define __TDM_REVISION_TRACKER_H__ - -/** - * greebo: This class is a simple singleton keeping track of the highest and - * lowest SVN revision numbers. - * - * The global function FileRevisionList() is taking care of registering - * the revision numbers to this class. - */ -class RevisionTracker -{ - // Some stats - int _highestRevision; - int _lowestRevision; - int _numFiles; - -public: - /** - * Constructor is taking care of initialising the members. - */ - RevisionTracker(); - - /** - * greebo: Accessor methods. Retrieves the highest and lowest revision - * and the number of registered files. - */ - int GetHighestRevision() const; - int GetLowestRevision() const; - int GetNumFiles() const; - - /** - * Use this method to register a new revision. - */ - void AddRevision(int revision); - - /** - * Entry point for FileVersionList(). Take this method to - * parse an SVN id string and retrieve the revision. - * This methods passes the call to AddRevision. - */ - static void ParseSVNIdString(const char* input); - - // Accessor to the singleton - static RevisionTracker& Instance(); -}; - -#endif /* __TDM_REVISION_TRACKER_H__ */ diff --git a/DarkMod/Shop/LootRuleSet.h b/DarkMod/Shop/LootRuleSet.h deleted file mode 100644 index 291ad5d27..000000000 --- a/DarkMod/Shop/LootRuleSet.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef TDM_LOOTRULESET_H -#define TDM_LOOTRULESET_H - -#include "../Inventory/LootType.h" - -/** - * greebo: A structure defining loot carry-over rules for the shop. - * The mapper can define how much of the collected loot - * makes it into the shop. - * - * A default-constructed LootRules set won't change the incoming loot values - * everything is losslessly passed through with a 1:1 conversion, - * and the player is allowed to keep his money. - */ -struct LootRuleSet -{ - // The conversion rate for each loot type. Before entering the shop - // every loot type is converted to gold. - float conversionRate[LOOT_COUNT]; - - // Gold loss after conversion (defaults to 0 => no loss) - int goldLoss; - - // Gold loss by percent after conversion (defaults to 0 => no loss) - float goldLossPercent; - - // Minimum amount of gold available in the shop. At least this value is guaranteed to be returned by ApplyToFoundLoot - int goldMin; - - // Maximum amount of gold available in the shop. Enforced after conversion. (default is -1 => no cap) - int goldCap; - - LootRuleSet() - { - Clear(); - } - - void Clear(); - - // Equality operator, returns true if this class is the same as the other. Doesn't check LOOT_NONE conversion. - bool operator==(const LootRuleSet& other) const; - - // Returns TRUE if this lootrule structure is at default values - // This is a comparably slow call, so don't use it excessively - bool IsEmpty() const - { - // Compare this instance against a default-constructed one - return *this == LootRuleSet(); - } - - // Load the ruleset from the spawnargs matching the given prefix - void LoadFromDict(const idDict& dict, const idStr& prefix); - - /** - * Apply this ruleset to the given amount of found loot and shop start budget. - * - * @foundLoot: The loot collected values. - * @shopStartingGold: The amount of starting gold for the shop. This value - * is added after applying the losses, but before the min/max caps are applied. - * - * Returns the amount of resulting gold, which is at least goldMin. - */ - int ApplyToFoundLoot(const int foundLoot[LOOT_COUNT], int shopStartingGold); -}; - -#endif diff --git a/DarkMod/StimResponse/ResponseEffect.cpp b/DarkMod/StimResponse/ResponseEffect.cpp deleted file mode 100644 index 08b6e4805..000000000 --- a/DarkMod/StimResponse/ResponseEffect.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "ResponseEffect.h" - -/********************************************************************/ -/* CResponseEffect */ -/********************************************************************/ - -CResponseEffect::CResponseEffect( - const function_t* scriptFunction, - const idStr& effectPostfix, - const idStr& scriptName , - bool localScript) : - _scriptFunction(scriptFunction), - _scriptName(scriptName), - _effectPostfix(effectPostfix), - _localScript(localScript), - _scriptFunctionValid(true) -{} - -void CResponseEffect::runScript(idEntity* owner, idEntity* stimEntity, float magnitude) { - if (!_scriptFunctionValid) - { - if (owner == NULL) - { - DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("Cannot restore scriptfunction, owner is NULL: %s\r", _scriptName.c_str()); - return; - } - - _scriptFunctionValid = true; - - if (_localScript) { - // Local scriptfunction - _scriptFunction = owner->scriptObject.GetFunction(_scriptName.c_str()); - } - else { - // Global Method - _scriptFunction = gameLocal.program.FindFunction(_scriptName.c_str()); - } - } - - if (_scriptFunction == NULL) return; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Running ResponseEffect Script, effectPostfix = %s...\r", _effectPostfix.c_str()); - - idThread *pThread = new idThread(_scriptFunction); - int n = pThread->GetThreadNum(); - pThread->CallFunctionArgs(_scriptFunction, true, "eesff", owner, stimEntity, _effectPostfix.c_str(), magnitude, n); - pThread->DelayedStart(0); -} - -void CResponseEffect::Save(idSaveGame *savefile) const -{ - savefile->WriteString(_effectPostfix.c_str()); - savefile->WriteString(_scriptName.c_str()); - savefile->WriteBool(_localScript); -} - -void CResponseEffect::Restore(idRestoreGame *savefile) -{ - savefile->ReadString(_effectPostfix); - savefile->ReadString(_scriptName); - savefile->ReadBool(_localScript); - - // The script function pointer has to be restored after loading, set the dirty flag - _scriptFunctionValid = false; -} diff --git a/DarkMod/StimResponse/ResponseEffect.h b/DarkMod/StimResponse/ResponseEffect.h deleted file mode 100644 index 085a34b2e..000000000 --- a/DarkMod/StimResponse/ResponseEffect.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef SR_RESPONSEEFFECT__H -#define SR_RESPONSEEFFECT__H - -class CStim; - -class CResponseEffect -{ -protected: - const function_t* _scriptFunction; - - // The name of the script - idStr _scriptName; - - // The effect postfix, "1_1" for example - // This is passed to the script along with the "owner" entity, - // so that the script can lookup any arguments it might need. - idStr _effectPostfix; - - // Is TRUE of the script function is on the entity scriptobject, FALSE for local functions - bool _localScript; - - // This is set to FALSE after loading, so that the script function - // gets resolved again. - bool _scriptFunctionValid; - -public: - // Pass the scriptowner to this structure or NULL for global functions - CResponseEffect(const function_t* scriptFunction, - const idStr& effectPostfix, - const idStr& scriptName , - bool localScript); - - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); - - /** - * Runs the attached response effect script - * (does nothing if the scriptfunc pointer is NULL) - * - * @owner: The entity this script is affecting - * @stimEntity: The entity that triggered this response - * @magnitude: the magnitude of the stim (min = 0, max = stim->magnitude) - */ - virtual void runScript(idEntity* owner, idEntity* stimEntity, float magnitude); -}; - -#endif /* SR_RESPONSEEFFECT__H */ diff --git a/DarkMod/StimResponse/StimType.h b/DarkMod/StimResponse/StimType.h deleted file mode 100644 index be7af91ab..000000000 --- a/DarkMod/StimResponse/StimType.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef _STIMTYPE_H_ -#define _STIMTYPE_H_ - -// If default stims are to be added here, the static array in the StimResponse.cpp file -// also must be updated. USER and UNDEFINED are not to be added though, as -// they have special meanings. -enum StimType -{ - ST_FROB, // Frobbed - ST_FIRE, // Fire - ST_WATER, // Water - ST_DAMAGE, // damages target - ST_SHIELD, // protects against arrows or physical blows - ST_HEALING, // heals target - ST_HOLY, // holy is applied - ST_MAGIC, // Magic is being used - ST_TOUCH, // triggered if touched - ST_KNOCKOUT, // target is knocked out - ST_KILL, // target is killed - ST_RESTORE, // target is restored - ST_LIGHT, // triggered by light - ST_SOUND, // triggered by sound - ST_VISUAL, // visual contact - ST_INVITE, // can be used to trigger special behaviour (like a stool can invite an AI to sit down) - ST_READ, // Can be read - ST_RANDOM, // Random response is selected - ST_TIMER, // Timer trigger - ST_COMMUNICATION, // A communication stimulus (see CommunicationStim.h) - ST_GAS, // triggered by gas arrows - ST_TRIGGER, // Triggered by triggering :) - ST_TARGET_REACHED, // Emitted, if the AI has reached its target (induced by effect_moveToPosition) - ST_PLAYER, // The Stim emitted by the player - ST_FLASH, // Emitted by flashbombs - ST_BLIND, // A stim that immediately blinds the AI (no visibility is needed) - for use in flashmines - ST_USER = 1000, // User defined types should use this as it's base - ST_DEFAULT = -1 -}; - -#endif /* _STIMTYPE_H_ */ diff --git a/DarkMod/UserManager.h b/DarkMod/UserManager.h deleted file mode 100644 index 044feee88..000000000 --- a/DarkMod/UserManager.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef USER_MANAGER_H -#define USER_MANAGER_H - -class UserManager -{ - -public: - - int GetNumUsers(); - - // Adds user to the list, sorted by alert level - void AddUser(idActor*); - - void AppendUser(idActor* actor); // grayman #1327 - append to the list, don't care about alert level - - void RemoveUser(idActor*); - - idActor* GetMasterUser(); - - idActor* GetUserAtIndex(const int index); // grayman #2345 - void InsertUserAtIndex(idActor* actor,const int index); // grayman #2345 - - int GetIndex(idActor* user); // grayman #2345 - void ResetMaster(CFrobDoor* frobDoor); // grayman #2706 - - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - -private: - - idList< idEntityPtr > m_users; - - - -}; - -#endif /* USER_MANAGER_H */ diff --git a/DarkMod/ZipLoader/ZipLoader.h b/DarkMod/ZipLoader/ZipLoader.h deleted file mode 100644 index 374f6143d..000000000 --- a/DarkMod/ZipLoader/ZipLoader.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef ZIPLOADER_H_ -#define ZIPLOADER_H_ - -#pragma hdrstop - -#include "../../idlib/precompiled.h" -#include -#include "minizip/unzip.h" - -/** - * A class wrapping around a minizip file handle, providing - * some convenience method to easily extract data from PK4s. - */ -class CZipFile -{ - // The handle for the zip archive - unzFile _handle; - -public: - CZipFile(unzFile handle); - - ~CZipFile(); - - /** - * greebo: returns TRUE when this archive contains the given file. - */ - bool ContainsFile(const idStr& fileName); - - /** - * Attempts to load the given text file. The string will be empty - * if the file failed to load. - */ - idStr LoadTextFile(const idStr& fileName); - - /** - * greebo: Extracts the given file to the given destination path. - * @returns: TRUE on success, FALSE otherwise. - */ - bool ExtractFileTo(const idStr& fileName, const idStr& destPath); -}; -typedef boost::shared_ptr CZipFilePtr; - -/** - * greebo: This service class can be used to load and inspect zip files and - * retrieve specific files from the archive. D3 filesystem doesn't expose - * ZIP loading functionality, so this is the do-it-yourself approach. - */ -class CZipLoader -{ - // Private constructor - CZipLoader(); - -public: - /** - * Tries to load the given file (path is absolute, use D3 VFS functions - * to resolve a relative D3 path to a full OS path). - * - * @returns: NULL on failure, the file object on success. - */ - CZipFilePtr OpenFile(const idStr& fullOSPath); - - // Singleton instance - static CZipLoader& Instance(); -}; - -#endif /* ZIPLOADER_H_ */ diff --git a/DarkMod/decltdm_matinfo.h b/DarkMod/decltdm_matinfo.h deleted file mode 100644 index 0fe21214f..000000000 --- a/DarkMod/decltdm_matinfo.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __DARKMOD_DECLTDM_MATINFO_H__ -#define __DARKMOD_DECLTDM_MATINFO_H__ - -/// A TDM-specific material information declaration class. -/** Currently, the only info it contains is surfacetype. - */ -class tdmDeclTDM_MatInfo : public idDecl -{ -public: - tdmDeclTDM_MatInfo(); - ~tdmDeclTDM_MatInfo(); - - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual void FreeData( void ); - virtual bool Parse( const char *text, const int textLength ); - - /// Used to cache the TDM_MatInfos for all the materials applied to surfaces of a map. - static void precacheMap( idMapFile *map ); - static void precacheModel( idRenderModel *model ); - - /// The surface type of the material. - idStr surfaceType; -}; - -#endif /* __DARKMOD_DECLTDM_MATINFO_H__ */ diff --git a/DarkMod/force_grab.cpp b/DarkMod/force_grab.cpp deleted file mode 100755 index 97107dc6e..000000000 --- a/DarkMod/force_grab.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" -#include "force_grab.h" -#include "../DarkMod/Grabber.h" - -class CDarkModPlayer; - -CLASS_DECLARATION( idForce, CForce_Grab ) -END_CLASS - -/* -================ -CForce_Grab::CForce_Grab -================ -*/ -CForce_Grab::CForce_Grab( void ) -{ - m_damping = 0.0f; - m_physics = NULL; - m_id = 0; - m_p = vec3_zero; - m_dragPosition = vec3_zero; - m_dragAxis.Zero(); - m_centerOfMass = vec3_zero; - m_inertiaTensor.Identity(); - - m_bApplyDamping = false; - m_bLimitForce = false; - m_RefEnt = NULL; -} - -/* -================ -CForce_Grab::~CForce_Grab -================ -*/ -CForce_Grab::~CForce_Grab( void ) { -} - -/* -================ -CForce_Grab::Init -================ -*/ -void CForce_Grab::Init( float damping ) { - if ( damping >= 0.0f && damping < 1.0f ) - { - m_damping = damping; - } - else - { - m_damping = 0; - } -} - -void CForce_Grab::Save( idSaveGame *savefile ) const -{ - m_RefEnt.Save( savefile ); - savefile->WriteFloat(m_damping); - savefile->WriteVec3(m_centerOfMass); - savefile->WriteMat3(m_inertiaTensor); - - // Don't save m_physics, gets restored from the parent class after load - - savefile->WriteVec3(m_p); - savefile->WriteInt(m_id); - savefile->WriteVec3(m_dragPosition); - savefile->WriteMat3(m_dragAxis); - savefile->WriteBool(m_bApplyDamping); - savefile->WriteBool(m_bLimitForce); -} - -void CForce_Grab::Restore( idRestoreGame *savefile ) -{ - m_RefEnt.Restore( savefile ); - savefile->ReadFloat(m_damping); - savefile->ReadVec3(m_centerOfMass); - savefile->ReadMat3(m_inertiaTensor); - - m_physics = NULL; // gets restored from the parent class after loading - - savefile->ReadVec3(m_p); - savefile->ReadInt(m_id); - savefile->ReadVec3(m_dragPosition); - savefile->ReadMat3(m_dragAxis); - savefile->ReadBool(m_bApplyDamping); - savefile->ReadBool(m_bLimitForce); -} - -/* -================ -CForce_Grab::SetPhysics -================ -*/ -void CForce_Grab::SetPhysics( idPhysics *phys, int id, const idVec3 &p ) { - float mass, MassOut, density; - idClipModel *clipModel; - - m_physics = phys; - m_id = id; - m_p = p; - - clipModel = m_physics->GetClipModel( m_id ); - if ( clipModel != NULL && clipModel->IsTraceModel() ) - { - mass = m_physics->GetMass( m_id ); - // PROBLEM: No way to query physics object for density! - // Trick: Use a test density of 1.0 here, then divide the actual mass by output mass to get actual density - clipModel->GetMassProperties( 1.0f, MassOut, m_centerOfMass, m_inertiaTensor ); - density = mass / MassOut; - // Now correct the inertia tensor by using actual density - clipModel->GetMassProperties( density, mass, m_centerOfMass, m_inertiaTensor ); - } else - { - m_centerOfMass.Zero(); - m_inertiaTensor = mat3_identity; - } -} - -/* -================ -CForce_Grab::SetDragPosition -================ -*/ -void CForce_Grab::SetDragPosition( const idVec3 &pos ) -{ - m_dragPosition = pos; -} - -/* -================ -CForce_Grab::GetDragPosition -================ -*/ -const idVec3 &CForce_Grab::GetDragPosition( void ) const -{ - return m_dragPosition; -} - -/* -================ -CForce_Grab::SetDragAxis -================ -*/ -void CForce_Grab::SetDragAxis( const idMat3 &Axis ) -{ - m_dragAxis = Axis; -} - -/* -================ -CForce_Grab::GetDragAxis -================ -*/ -idMat3 CForce_Grab::GetDragAxis( void ) -{ - return m_dragAxis; -} - -/* -================ -CForce_Grab::GetDraggedPosition -================ -*/ -const idVec3 CForce_Grab::GetDraggedPosition( void ) const -{ - return ( m_physics->GetOrigin( m_id ) + m_p * m_physics->GetAxis( m_id ) ); -} - -/* -================ -CForce_Grab::Evaluate -================ -*/ -void CForce_Grab::Evaluate( int time ) -{ - float l1, Accel, dT; - idVec3 dragOrigin, dir1, dir2, velocity, COM, prevVel; - idRotation rotation; - - if ( !m_physics ) - { - return; - } - - CGrabber *grabber = gameLocal.m_Grabber; - -// ======================== LINEAR ========================= - - COM = this->GetCenterOfMass(); - dragOrigin = COM; - - dir1 = m_dragPosition - dragOrigin; - l1 = dir1.Normalize(); - dT = MS2SEC( USERCMD_MSEC ); // time elapsed is time between user mouse commands - - if( !m_bApplyDamping ) - m_damping = 0.0f; - - if( grabber->m_bIsColliding ) - { - // Zero out previous velocity when we start out colliding - prevVel = vec3_zero; - - idVec3 newDir = dir1; - - for( int i=0; i < grabber->m_CollNorms.Num(); i++ ) - { - // subtract out component of desired dir going in to surface - if( newDir * grabber->m_CollNorms[i] < 0.0f ) - { - newDir -= (newDir * grabber->m_CollNorms[i]) * grabber->m_CollNorms[i]; - } - - if( cv_drag_debug.GetBool() ) - gameRenderWorld->DebugArrow( colorBlue, COM, (COM + 30 * grabber->m_CollNorms[i]), 4.0f, 1); - } - - // Clear m_CollNorms so it can be filled next time there's a collision - grabber->m_CollNorms.Clear(); - - newDir.Normalize(); - - float newl1 = l1 * (dir1 * newDir); - - // avoid jittering due to floating point error - if( newl1 > 0.1f ) - { - l1 = newl1; // project the magnitude in the new direction - dir1 = newDir; - } - else - { - dir1 = vec3_zero; - l1 = 0.0f; - } - - if( cv_drag_debug.GetBool() ) - gameRenderWorld->DebugArrow( colorRed, COM, (COM + l1 * dir1), 4.0f, 1); - } - else - { - prevVel = m_physics->GetLinearVelocity( m_id ); - if( cv_drag_debug.GetBool() ) - gameRenderWorld->DebugArrow( colorGreen, COM, (COM + l1 * dir1), 4.0f, 1); - } - - // "Realistic" finite acceleration - Accel = ( 1.0f - m_damping ) * l1 / (dT * dT); - - if( m_bLimitForce ) - { - // max force our arms can exert - float MaxArmAccel = grabber->m_MaxForce / m_physics->GetMass(); - // if player moves object down, gravity will help - if( dir1 * m_physics->GetGravityNormal() > 0 ) - { - idVec3 gravNormal = m_physics->GetGravity(); - float gravMag = gravNormal.Normalize(); - float MaxAccelDown = MaxArmAccel + gravMag; - - // break up desired motion into with gravity and the rest - float DownAccel = Accel * (dir1 * gravNormal); - idVec3 vDownAccel = DownAccel * gravNormal; - idVec3 vOthAccel = Accel * dir1 - vDownAccel; - float OthAccel = vOthAccel.NormalizeFast(); - - OthAccel = idMath::ClampFloat(0.0f, MaxArmAccel, OthAccel ); - DownAccel = idMath::ClampFloat(0.0f, MaxAccelDown, DownAccel ); - // recalculate the vectors now that magnitude is clamped - vDownAccel = DownAccel * gravNormal; - vOthAccel = OthAccel * vOthAccel; - velocity = prevVel * m_damping + (vDownAccel + vOthAccel) * dT; - } - else - { - // we're nice and don't make the player's arms fight gravity - Accel = idMath::ClampFloat(0.0f, MaxArmAccel, Accel ); - velocity = prevVel * m_damping + dir1 * Accel * dT; - } - } - else - { - // unlimited force - velocity = prevVel * m_damping + dir1 * Accel * dT; - } - - if( m_RefEnt.GetEntity() ) - { - // reference frame velocity - velocity += m_RefEnt.GetEntity()->GetPhysics()->GetLinearVelocity(); - - // TODO: Add velocity due to spin angular momentum of reference entity - // e.g., player standing on spinning thing - } - m_physics->SetLinearVelocity( velocity, m_id ); - -// ======================== ANGULAR ========================= - idVec3 Alph, DeltAngVec, RotDir, PrevOmega, Omega; // angular acceleration - float AlphMag, MaxAlph, AlphMod, IAxis, DeltAngLen; - idMat3 DesiredRot; - - // TODO: Make the following into cvars / spawnargs: - float ang_damping = 0.0f; - float max_torque = 100000 * 40; - - // Don't rotate AFs at all for now - if( m_physics->GetSelf()->IsType( idAFEntity_Base::Type ) ) - return; - - // Find the rotation matrix needed to get from current rotation to desired rotation: - DesiredRot = m_dragAxis.Transpose() * m_physics->GetAxis( m_id ); - - // DeltAngVec = DeltAng.ToAngularVelocity(); - DeltAngVec = DesiredRot.ToAngularVelocity(); - RotDir = DeltAngVec; - DeltAngLen = RotDir.Normalize(); - DeltAngLen = DEG2RAD( idMath::AngleNormalize360( RAD2DEG(DeltAngLen) ) ); - DeltAngVec = DeltAngLen * RotDir; - - // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Desired angular velocity is %s\r", DeltAngVec.ToString() ); - // test for FP error - if( (DeltAngLen / dT) <= 0.00001 ) - { - m_physics->SetAngularVelocity( vec3_zero, m_id ); - m_dragAxis = m_physics->GetAxis( m_id ); - return; - } - - // Finite angular acceleration: - Alph = DeltAngVec * (1.0f - ang_damping) / (dT * dT); - AlphMag = Alph.Length(); - - // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Desird angular accel this frame is %s\r", Alph.ToString() ); - - if( m_bLimitForce ) - { - // Find the scalar moment of inertia about this axis: - IAxis = (m_inertiaTensor * RotDir) * RotDir; - - // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: I about axis is %f\r", IAxis ); - - // Calculate max alpha about this axis from max torque - MaxAlph = max_torque / IAxis; - AlphMod = idMath::ClampFloat(0.0f, MaxAlph, AlphMag ); - - // Finally, adjust our angular acceleration vector - Alph *= (AlphMod/AlphMag); - // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Modified alpha is %s\r", Alph.ToString() ); - } - - if( grabber->m_bIsColliding ) - PrevOmega = vec3_zero; - else - PrevOmega = m_physics->GetAngularVelocity( m_id ); - - Omega = PrevOmega * ang_damping + Alph * dT; - - // TODO: Toggle visual debugging with cvar - // gameRenderWorld->DebugLine( colorGreen, COM, (COM + 30 * RotDir), 1); - - // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Setting angular velocity to %s\r", Omega.ToString() ); - m_physics->SetAngularVelocity( Omega, m_id ); -} - -/* -================ -CForce_Grab::RemovePhysics -================ -*/ -void CForce_Grab::RemovePhysics( const idPhysics *phys ) { - if ( m_physics == phys ) { - m_physics = NULL; - } -} - -/* -================ -CForce_Grab::GetCenterOfMass -================ -*/ -idVec3 CForce_Grab::GetCenterOfMass( void ) const -{ - return ( m_physics->GetOrigin( m_id ) + m_centerOfMass * m_physics->GetAxis( m_id ) ); -} - - -/* -================ -CForce_Grab::Rotate -================ -*/ -void CForce_Grab::Rotate( const idVec3 &vec, float angle ) -{ - idRotation r; - - r.Set( vec3_origin, vec, angle ); - r.RotatePoint( m_p ); -} - -void CForce_Grab::ApplyDamping( bool bVal ) -{ - m_bApplyDamping = bVal; -} - -void CForce_Grab::LimitForce( bool bVal ) -{ - m_bLimitForce = bVal; -} - -void CForce_Grab::SetRefEnt( idEntity *InputEnt ) -{ - m_RefEnt = InputEnt; -} diff --git a/DarkMod/force_grab.h b/DarkMod/force_grab.h deleted file mode 100755 index 0c20c759c..000000000 --- a/DarkMod/force_grab.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __FORCE_GRAB_H__ -#define __FORCE_GRAB_H__ - -#include "../game/physics/force.h" - -/* -=============================================================================== - - Grab force - -=============================================================================== -*/ - -class CForce_Grab : public idForce -{ - public: - CLASS_PROTOTYPE( CForce_Grab ); - - CForce_Grab( void ); - virtual ~CForce_Grab( void ); - // initialize the drag force - void Init( float damping ); - // set physics object being dragged - void SetPhysics( idPhysics *physics, int id, const idVec3 &p ); - // set position to drag towards - void SetDragPosition( const idVec3 &pos ); - // get the position dragged towards - const idVec3 & GetDragPosition( void ) const; - // get the position on the dragged physics object - /** - * Set/get orientation to rotate toward - **/ - void SetDragAxis( const idMat3 &Axis ); - idMat3 GetDragAxis( void ); - - const idVec3 GetDraggedPosition( void ) const; - // Gets the center of mass of the grabbed object - idVec3 GetCenterOfMass( void ) const; - // rotates p about the center of mass of the grabbed object - void Rotate( const idVec3 &vec, float angle ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * Toggle whether the force_grab should use a max force limit - **/ - void LimitForce( bool bVal ); - - /** - * Toggle whether the force_grab should apply damping or not - **/ - void ApplyDamping( bool bVal ); - - /** - * Set the reference entity - **/ - void SetRefEnt( idEntity *ent ); - - public: // common force interface - virtual void Evaluate( int time ); - virtual void RemovePhysics( const idPhysics *phys ); - - protected: - - /** - * Entity to which this drag force is referenced, if any - **/ - idEntityPtr m_RefEnt; - - /** - * If true, limit force or apply damping - **/ - bool m_bLimitForce; - bool m_bApplyDamping; - - // properties - float m_damping; - - // physics object properties - idVec3 m_centerOfMass; - idMat3 m_inertiaTensor; - - // positioning - idPhysics * m_physics; // physics object - idVec3 m_p; // position on clip model - int m_id; // clip model id of physics object - /** - * drag towards this position - **/ - idVec3 m_dragPosition; - /** - * Rotate toward this orientation - **/ - idMat3 m_dragAxis; - - /** - * Origin of the dragged entity in the previous frame - **/ - idVec3 m_prevOrigin; -}; - -#endif /* !__FORCE_GRAB_H__ */ diff --git a/DarkMod/func_shooter.cpp b/DarkMod/func_shooter.cpp deleted file mode 100644 index 1cfba2686..000000000 --- a/DarkMod/func_shooter.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "func_shooter.h" -#include "StimResponse/StimResponseCollection.h" - -// Script event interface -const idEventDef EV_ShooterSetState( "shooterSetState", "d" ); -const idEventDef EV_ShooterFireProjectile( "shooterFireProjectile", NULL ); -const idEventDef EV_ShooterGetState( "shooterGetState", NULL, 'd' ); -const idEventDef EV_ShooterSetAmmo( "shooterSetAmmo", "d" ); -const idEventDef EV_ShooterGetAmmo( "shooterGetAmmo", NULL, 'd' ); - -// Event definitions -CLASS_DECLARATION( idStaticEntity, tdmFuncShooter ) - EVENT( EV_Activate, tdmFuncShooter::Event_Activate ) - EVENT( EV_ShooterSetState, tdmFuncShooter::Event_ShooterSetState ) - EVENT( EV_ShooterGetState, tdmFuncShooter::Event_ShooterGetState ) - EVENT( EV_ShooterFireProjectile, tdmFuncShooter::Event_ShooterFireProjectile ) - EVENT( EV_ShooterSetAmmo, tdmFuncShooter::Event_ShooterSetAmmo ) - EVENT( EV_ShooterGetAmmo, tdmFuncShooter::Event_ShooterGetAmmo ) -END_CLASS - -/* -=============== -tdmFuncShooter::tdmFuncShooter -=============== -*/ -tdmFuncShooter::tdmFuncShooter() : - _active(false), - _fireInterval(-1), - _fireIntervalFuzzyness(0), - _startDelay(0), - _endTime(-1), - _lastFireTime(0), - _nextFireTime(0), - _requiredStim(ST_DEFAULT), - _lastStimVisit(0), - _requiredStimTimeOut(0), - _triggerRequired(false), - _lastTriggerVisit(0), - _triggerTimeOut(0), - _ammo(-1), - _useAmmo(false) -{} - -/* -=============== -tdmFuncShooter::Spawn -=============== -*/ -void tdmFuncShooter::Spawn() -{ - _active = !spawnArgs.GetBool("start_off"); - _lastFireTime = 0; - _fireInterval = spawnArgs.GetInt("fire_interval", "-1"); - _fireIntervalFuzzyness = spawnArgs.GetInt("fire_interval_fuzzyness", "0"); - _startDelay = spawnArgs.GetInt("start_delay", "0"); - - idStr reqStimStr = spawnArgs.GetString("required_stim"); - - if (!reqStimStr.IsEmpty()) { - _requiredStim = CStimResponse::GetStimType(reqStimStr); - _requiredStimTimeOut = spawnArgs.GetInt("required_stim_timeout", "5000"); - } - - _triggerRequired = spawnArgs.GetBool("required_trigger"); - _triggerTimeOut = spawnArgs.GetInt("required_trigger_timeout", "4000"); - - _ammo = spawnArgs.GetInt("ammo", "-1"); - _useAmmo = (_ammo != -1); - - if (_active && _fireInterval > 0) - { - BecomeActive( TH_THINK ); - setupNextFireTime(); - _nextFireTime += _startDelay; - - // Set the end time if we have a positive lifetime - int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); - - if (maxLifeTime > 0) - { - _endTime = gameLocal.time + SEC2MS(maxLifeTime); - } - } - - // Always react to stims if a required stim is setup. - if (_requiredStim != ST_DEFAULT) - { - //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("tdmFuncShooter is requiring stim %d\r", _requiredStim); - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - } -} - -/* -=============== -tdmFuncShooter::Save -=============== -*/ -void tdmFuncShooter::Save( idSaveGame *savefile ) const -{ - savefile->WriteBool( _active ); - savefile->WriteInt(_endTime); - savefile->WriteInt( _lastFireTime ); - savefile->WriteInt( _nextFireTime ); - savefile->WriteInt( _fireInterval ); - savefile->WriteInt( _fireIntervalFuzzyness ); - savefile->WriteInt( _startDelay ); - savefile->WriteInt( _requiredStim ); - savefile->WriteInt( _requiredStimTimeOut ); - savefile->WriteInt( _lastStimVisit ); - savefile->WriteInt( _lastTriggerVisit ); - savefile->WriteBool( _triggerRequired ); - savefile->WriteInt( _triggerTimeOut ); - savefile->WriteInt( _ammo ); - savefile->WriteBool( _useAmmo ); -} - -/* -=============== -tdmFuncShooter::Restore -=============== -*/ -void tdmFuncShooter::Restore( idRestoreGame *savefile ) -{ - savefile->ReadBool( _active ); - savefile->ReadInt(_endTime); - savefile->ReadInt( _lastFireTime ); - savefile->ReadInt( _nextFireTime ); - savefile->ReadInt( _fireInterval ); - savefile->ReadInt( _fireIntervalFuzzyness ); - savefile->ReadInt( _startDelay ); - - int stimType; - savefile->ReadInt( stimType ); - _requiredStim = static_cast(stimType); - - savefile->ReadInt( _requiredStimTimeOut ); - savefile->ReadInt( _lastStimVisit ); - savefile->ReadInt( _lastTriggerVisit ); - savefile->ReadBool( _triggerRequired ); - savefile->ReadInt( _triggerTimeOut ); - savefile->ReadInt( _ammo ); - savefile->ReadBool( _useAmmo ); -} - -/* -================ -tdmFuncShooter::Event_Activate -================ -*/ -void tdmFuncShooter::Event_Activate( idEntity *activator ) -{ - if (_triggerRequired) - { - // This shooter requires constant triggering, save the time - _lastTriggerVisit = gameLocal.time; - } - else if ( thinkFlags & TH_THINK ) - { - BecomeInactive( TH_THINK ); - _active = false; - } - else - { - BecomeActive( TH_THINK ); - _active = true; - _ammo = spawnArgs.GetInt("ammo", "-1"); - _lastFireTime = gameLocal.time; - setupNextFireTime(); - _nextFireTime += _startDelay; - - // Set the end time if we have a positive lifetime - int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); - - if (maxLifeTime > 0) - { - _endTime = gameLocal.time + SEC2MS(maxLifeTime); - } - } -} - -void tdmFuncShooter::Event_ShooterGetState() -{ - idThread::ReturnInt(_active ? 1 : 0); -} - -void tdmFuncShooter::Event_ShooterSetState( bool state ) -{ - if (state == _active) return; // Nothing to change - - _active = state; - - if (_active) { - // Reset the ammo on script activation (useAmmo can still override this) - _ammo = spawnArgs.GetInt("ammo", "-1"); - setupNextFireTime(); - _nextFireTime += _startDelay; - - // Set the end time if we have a positive lifetime - int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); - - if (maxLifeTime > 0) - { - _endTime = gameLocal.time + SEC2MS(maxLifeTime); - } - } -} - -void tdmFuncShooter::Event_ShooterFireProjectile() -{ - Fire(); -} - -void tdmFuncShooter::Event_ShooterSetAmmo( int newAmmo ) -{ - _ammo = newAmmo; -} - -void tdmFuncShooter::Event_ShooterGetAmmo() -{ - idThread::ReturnInt(_ammo); -} - -void tdmFuncShooter::setupNextFireTime() -{ - // Calculate the next fire time - int randomness = static_cast( - _fireIntervalFuzzyness*(gameLocal.random.RandomFloat() - 0.5f) - ); - - _nextFireTime = gameLocal.time + _fireInterval + randomness; -} - -void tdmFuncShooter::stimulate(StimType stimId) -{ - if (stimId == _requiredStim && _requiredStim != ST_DEFAULT) - { - //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Stim is visiting at %d\r", gameLocal.time); - // Save the time the stim is visiting - _lastStimVisit = gameLocal.time; - } -} - -void tdmFuncShooter::Fire() -{ - _lastFireTime = gameLocal.time; - - // Spawn a projectile - idStr projectileDef = spawnArgs.GetString("def_projectile"); - if (!projectileDef.IsEmpty()) { - const idDict* projectileDict = gameLocal.FindEntityDefDict(projectileDef); - - idEntity* ent = NULL; - gameLocal.SpawnEntityDef(*projectileDict, &ent); - - if (ent == NULL) - { - gameLocal.Warning("Could not spawn projectile type: %s", projectileDef.c_str()); - return; - } - - if (ent->IsType(idProjectile::Type)) - { - idProjectile* projectile = static_cast(ent); - - // Get the default angle from the entity - float angle = spawnArgs.GetFloat("angle"); - float pitch = spawnArgs.GetFloat("pitch", "0"); - - // Check if the angle should be randomly chosen - if (spawnArgs.GetBool("random_angle")) - { - angle = gameLocal.random.RandomFloat() * 360; - } - - // Check for random pitch angle - if (spawnArgs.GetBool("random_pitch")) - { - pitch = gameLocal.random.RandomFloat() * 180 - 90; - } - - // Calculate the direction from "angle" and "pitch" - idVec3 direction( cos(DEG2RAD(angle)), sin(DEG2RAD(angle)), sin(DEG2RAD(pitch)) ); - direction.NormalizeFast(); - - // Check for a specified velocity on the shooter - float velocity = spawnArgs.GetFloat("velocity", "0"); - - if (velocity <= 0) - { - // Try to get a velocity from the projectile itself - velocity = projectileDict->GetVector("velocity", "0 0 0").Length(); - } - - // Set the brand of the projectile, it should know its roots - projectile->spawnArgs.Set("shooter", name.c_str()); - - // Fire! - projectile->Launch(GetPhysics()->GetOrigin(), direction, direction*velocity); - - if (spawnArgs.GetBool("override_projectile_angles", "0")) - { - // Read the angles from the projectile - idAngles tempAngles(projectile->spawnArgs.GetAngles("angles")); - - // Add the angles of the shoot direction - tempAngles.yaw += angle; - tempAngles.pitch += pitch; - tempAngles.roll += 0; - - // Convert the angles to an axis matrix and store it into the projectile - projectile->GetPhysics()->SetAxis(tempAngles.ToMat3()); - } - - // Check the ammonition - if (_useAmmo && --_ammo <= 0) - { - // Clamp the ammo value to zero - _ammo = 0; - // Inactivate the shooter as the max ammo was specified and has run out - Event_ShooterSetState(false); - } - } - } - - setupNextFireTime(); -} - -void tdmFuncShooter::Think() -{ - if (!_active) return; - - // We're active, so let's check if we have a lifetime - if (_endTime > 0 && gameLocal.time > _endTime) - { - // Lifetime has passed, deactivate ourselves - Event_ShooterSetState(false); - return; - } - - if (_fireInterval > 0 && gameLocal.time > _nextFireTime) - { - // greebo: Check before firing whether we have a required stim - if (_requiredStim != ST_DEFAULT && _lastStimVisit > 0 && - _lastStimVisit + _requiredStimTimeOut >= gameLocal.time) - { - // We have a required stim, but it was not too far in the past => fire - Fire(); - } - else if (_triggerRequired && _lastTriggerVisit > 0 && - _lastTriggerVisit + _triggerTimeOut >= gameLocal.time) - { - // Required constant triggering, last trigger was not too long ago => fire - Fire(); - } - else if (_requiredStim == ST_DEFAULT && !_triggerRequired) - { - // No required stim and no required trigger, fire away - Fire(); - } - } -} diff --git a/DarkMod/func_shooter.h b/DarkMod/func_shooter.h deleted file mode 100644 index 734b828b1..000000000 --- a/DarkMod/func_shooter.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __GAME_FUNC_SHOOTER_H__ -#define __GAME_FUNC_SHOOTER_H__ - -#include "StimResponse/StimResponse.h" - -/** -* greebo: This entity fires projectiles in (periodic) intervals. -* All the key paramaters can be specified in the according entityDef. -*/ -class tdmFuncShooter : - public idStaticEntity -{ -public: - CLASS_PROTOTYPE(tdmFuncShooter); - - // Constructor - tdmFuncShooter(); - - // Needed on game save/load - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // Gets called when this entity is actually being spawned - void Spawn(); - - // Event interface - void Event_Activate( idEntity *activator ); - void Event_ShooterSetState( bool state ); - void Event_ShooterGetState(); - void Event_ShooterSetAmmo( int newAmmo ); - void Event_ShooterGetAmmo(); - void Event_ShooterFireProjectile(); - - // Overload the derived idEntity::Think method so that this object gets called each frame - virtual void Think(); - - /** - * Fires a projectile and sets the timer to gameLocal.time. - */ - virtual void Fire(); - - /** - * Tries to stimulate this class with the given stimType. - * This checks whether the incoming stim is the required one and - * activated the shooter if this is the case. - */ - virtual void stimulate(StimType stimId); - -private: - // Calculates the next time this shooter should fire - void setupNextFireTime(); - - // is TRUE if the shooter can fire projectiles - bool _active; - - // The time interval between fires in ms - int _fireInterval; - - // This is the maximum tolerance the fireInterval can have - int _fireIntervalFuzzyness; - - // Start delay in ms - int _startDelay; - - // If positive, this is the game time beyond which we're becoming automatically inactive. - int _endTime; - - // The last time the shooter fired a projectile - int _lastFireTime; - - // The next game time the shooter should fire - int _nextFireTime; - - // This is != (ST_DEFAULT == -1) if a stim is required in order to stay active - StimType _requiredStim; - - // This is set to the last known time the requiredStim has visited this entity - int _lastStimVisit; - - // This specifies the time that can pass before the shooter becomes inactive - // if the requiredStim is not present. - int _requiredStimTimeOut; - - // TRUE if periodic triggering is needed for this shooter to stay active. - bool _triggerRequired; - - // This is set to the last known time the requiredStim has visited this entity - int _lastTriggerVisit; - - // If this time has passed without a trigger event, the shooter ceases to fire. - int _triggerTimeOut; - - // The maximum number of projectiles (ammo) for this shooter. - // A value of -1 means infinite ammonition - int _ammo; - - // This is true if the _ammo value should be considered or not - bool _useAmmo; -}; - -#endif /* !__GAME_FUNC_SHOOTER_H__ */ - diff --git a/DarkMod/lightgem.cpp b/DarkMod/lightgem.cpp deleted file mode 100644 index 91f06f3dc..000000000 --- a/DarkMod/lightgem.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "lightgem.h" - -// Temporary profiling related macros - -//#define ENABLE_PROFILING - -#ifdef ENABLE_PROFILING -#define PROFILE_BLOCK( block_tag ) \ -class __profile_block { \ - idTimer m_timeStamp; \ -public: \ - __profile_block() { \ - m_timeStamp.Start(); \ - } \ - ~__profile_block() { \ - m_timeStamp.Stop(); \ - gameLocal.Printf( #block_tag" : %lf \n\n", m_timeStamp.Milliseconds() ); \ - } \ -} _profile_blockInstance_##block_tag; \ - - -#define PROFILE_BLOCK_START( block_tag ) \ - idTimer timer##block_tag; \ - timer##block_tag.Start() \ - -// PROFILE_BLOCK_END requires PROFILE_BLOCK_START to be placed before it, to work. -#define PROFILE_BLOCK_END( block_tag ) \ - timer##block_tag.Stop(); \ - gameLocal.Printf( #block_tag": %lf \n", timer##block_tag.Milliseconds() ) \ - -#else - -#define PROFILE_BLOCK( block_tag ) -#define PROFILE_BLOCK_START( block_tag ) -#define PROFILE_BLOCK_END( block_tag ) - -#endif -//------------------------ -// Construction/Destruction -//---------------------------------------------------- -LightGem::LightGem() -{ -} - -LightGem::~LightGem() -{ - Deinitialize(); -} - - -//---------------------------------------------------- -// Initialization -//---------------------------------------------------- -void LightGem::Initialize() -{ -} - -void LightGem::Deinitialize() -{ - // free all dynamically allocated memory - m_LightgemRenderBuffer.Clear(); -} - -void LightGem::Clear() -{ - m_LightgemSurface = NULL; - m_LightgemShotSpot = 0; - for(unsigned int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) - m_LightgemShotValue[i] = 0.0; -} - -void LightGem::SpawnLightGemEntity( idMapFile * a_mapFile ) -{ - static const char *LightgemName = DARKMOD_LG_ENTITY_NAME; - idMapEntity *mapEnt = NULL; - - mapEnt = a_mapFile->FindEntity(LightgemName); - if(mapEnt == NULL) - { - mapEnt = new idMapEntity(); - a_mapFile->AddEntity(mapEnt); - mapEnt->epairs.Set("classname", "func_static"); - mapEnt->epairs.Set("name", LightgemName); - if(strlen(cv_lg_model.GetString()) == 0) - mapEnt->epairs.Set("model", DARKMOD_LG_RENDER_MODEL); - else - mapEnt->epairs.Set("model", cv_lg_model.GetString()); - mapEnt->epairs.Set("origin", "0 0 0"); - mapEnt->epairs.Set("noclipmodel", "1"); - } -} - -void LightGem::InitializeLightGemEntity( void ) -{ - m_LightgemSurface = gameLocal.FindEntity(DARKMOD_LG_ENTITY_NAME); - m_LightgemSurface.GetEntity()->GetRenderEntity()->allowSurfaceInViewID = DARKMOD_LG_VIEWID; - m_LightgemSurface.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noDynamicInteractions = false; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noShadow = true; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noSelfShadow = true; - DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("LightgemSurface: [%08lX]\r", m_LightgemSurface.GetEntity()); -} - -//---------------------------------------------------- -// State Persistence -//---------------------------------------------------- - -void LightGem::Save( idSaveGame & a_saveGame ) -{ - m_LightgemSurface.Save( &a_saveGame ); - a_saveGame.WriteInt(m_LightgemShotSpot); - for (int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) - { - a_saveGame.WriteFloat(m_LightgemShotValue[i]); - } -} - -void LightGem::Restore( idRestoreGame & a_savedGame ) -{ - m_LightgemSurface.Restore( &a_savedGame ); - a_savedGame.ReadInt(m_LightgemShotSpot); - for (int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) - { - a_savedGame.ReadFloat(m_LightgemShotValue[i]); - } - - m_LightgemSurface.GetEntity()->GetRenderEntity()->allowSurfaceInViewID = DARKMOD_LG_VIEWID; - m_LightgemSurface.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noDynamicInteractions = false; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noShadow = true; - m_LightgemSurface.GetEntity()->GetRenderEntity()->noSelfShadow = true; - DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("LightgemSurface: [%08lX]\r", m_LightgemSurface.GetEntity()); -} - -//---------------------------------------------------- -// Calculation -//---------------------------------------------------- -float LightGem::Calculate(idPlayer *player) -{ - PROFILE_BLOCK( LightGem_Calculate ); - - PROFILE_BLOCK_START( LightGem_Calculate_Setup); - float dist = cv_lg_distance.GetFloat(); // reasonable distance to get a good look at the player/test model - float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]; - float fRetVal = 0.0; - int playerid; // player viewid - int headid; // head viewid - int pdef; // player modeldef - int hdef; // head modeldef - int psid; // player shadow viewid - int hsid; // head shadow viewid - int i, nRenderPasses, k, dim, l; - idStr dps; - renderView_t rv/*, rv1*/; - idEntity *lg; - renderEntity_t *prent; // Player renderentity - renderEntity_t *hrent; // Head renderentity - renderEntity_t *lgrend; - const char *dp = NULL; - - lg = m_LightgemSurface.GetEntity(); - idVec3 Cam = player->GetEyePosition(); - idVec3 Pos = player->GetPhysics()->GetOrigin(); - idVec3 LGPos = Pos; // Set the lightgem position to that of the player - LGPos.x += ( Cam.x - Pos.x ) * 0.3; // Move the lightgem out a fraction along the leaning x vector - LGPos.y += ( Cam.y - Pos.y ) * 0.3; // Move the lightgem out a fraction along the leaning y vector - LGPos.z = Cam.z; // Set the lightgem's Z-axis position to that of the player's eyes - - if (LGPos.z < Pos.z + 50 && static_cast(player->GetPlayerPhysics())->IsCrouching()) - { - // Prevent lightgem from clipping into the floor while crouching - LGPos.z = Pos.z + 50; - } - - // Adjust the modelposition with userdefined offsets. - // Move the lightgem testmodel to the players feet based on the eye position - LGPos.x += cv_lg_oxoffs.GetInteger(); - LGPos.y += cv_lg_oyoffs.GetInteger(); - LGPos.z += cv_lg_ozoffs.GetInteger(); - lg->SetOrigin(LGPos); - - memset(&rv, 0, sizeof(rv)); - - for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) - fColVal[i] = 0.0; - - for(i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) - rv.shaderParms[i] = gameLocal.globalShaderParms[i]; - - rv.globalMaterial = gameLocal.GetGlobalMaterial(); - // rv.width = SCREEN_WIDTH; - // rv.height = SCREEN_HEIGHT; - rv.width = cv_lg_screen_width.GetInteger(); - rv.height = cv_lg_screen_height.GetInteger(); - rv.fov_x = cv_lg_fov.GetInteger(); - rv.fov_y = cv_lg_fov.GetInteger(); // Bigger values means more compressed view - rv.forceUpdate = false; - rv.x = 0; - rv.y = 0; - rv.time = gameLocal.GetTime(); - - nRenderPasses = cv_lg_renderpasses.GetInteger(); - // limit the renderpasses between 1 and 4 - if(nRenderPasses < 1) nRenderPasses = 1; - if(nRenderPasses > DARKMOD_LG_MAX_RENDERPASSES) nRenderPasses = DARKMOD_LG_MAX_RENDERPASSES; - - k = cv_lg_hud.GetInteger()-1; - lgrend = lg->GetRenderEntity(); - - // Set the viewid to our private screenshot snapshot. If this number is changed - // for some reason, it has to be changed in player.cpp as well. - rv.viewID = DARKMOD_LG_VIEWID; - lgrend->suppressShadowInViewID = 0; - - if(cv_lg_player.GetBool() == false) - lgrend->allowSurfaceInViewID = rv.viewID; - else - lgrend->allowSurfaceInViewID = 0; - - // Tell the renderengine about the change for this entity. - prent = lg->GetRenderEntity(); - if((pdef = lg->GetModelDefHandle()) != -1) - gameRenderWorld->UpdateEntityDef(pdef, prent); - - prent = player->GetRenderEntity(); - hrent = player->GetHeadEntity()->GetRenderEntity(); - - playerid = prent->suppressSurfaceInViewID; - psid = prent->suppressShadowInViewID; - prent->suppressShadowInViewID = rv.viewID; - prent->suppressSurfaceInViewID = rv.viewID; - - headid = hrent->suppressSurfaceInViewID; - hsid = hrent->suppressShadowInViewID; - hrent->suppressShadowInViewID = rv.viewID; - hrent->suppressSurfaceInViewID = rv.viewID; - - if((pdef = player->GetModelDefHandle()) != -1) - gameRenderWorld->UpdateEntityDef(pdef, prent); - - if((hdef = player->GetHeadEntity()->GetModelDefHandle()) != -1) - gameRenderWorld->UpdateEntityDef(hdef, hrent); - - dim = cv_lg_image_width.GetInteger(); - if(dim <= 0 || dim > 1024) - dim = DARKMOD_LG_RENDER_WIDTH; - - fRetVal = 0.0; - -// rv1 = rv; - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("RenderTurn %u", m_LightgemShotSpot); - - PROFILE_BLOCK_END( LightGem_Calculate_Setup); - - for(i = 0; i < nRenderPasses; i++) - { - PROFILE_BLOCK( LightGem_Calculate_ForLoop); - -// rv = rv1; - rv.vieworg = LGPos; - - // If it's not the turn for this lightgem shot, then - // we skip over it. We also skip it if the splitting is disabled. - if(cv_lg_split.GetBool() == true) - { - if(m_LightgemShotSpot != i) - continue; - } - - m_LightgemShotValue[i] = 0.0; - - PROFILE_BLOCK_START( LightGem_Calculate_ForLoop_switchCase ); - switch(i) - { - case 0: // From the top to bottom - { - rv.vieworg.z += cv_lg_zoffs.GetInteger(); - rv.vieworg.z += dist; - rv.viewaxis = idMat3( - 0.0, 0.0, -1.0, - 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0 - ); - } - break; - - case 1: - { - // From bottom to top - rv.vieworg.z -= cv_lg_zoffs.GetInteger(); - rv.vieworg.z -= dist; - rv.viewaxis = idMat3( - 0.0, 0.0, 1.0, - 0.0, 1.0, 0.0, - -1.0, 0.0, 0.0 - ); - } - break; - } - PROFILE_BLOCK_END( LightGem_Calculate_ForLoop_switchCase ); - - // If the hud is enabled we either process all of them in case it is set to 0, - // then we don't care which one is actually displayed (most likely the last or - // the first one), or we only show the one that should be shown. - if(k == -1 || k == i) - { - // We always use a square image, because we render now an overhead shot which - // covers all four side of the player at once, using a diamond or pyramid shape. - // The result is an image that is split in four triangles with an angle of - // 45 degree, thus the square shape. - PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_RenderScene ); - renderSystem->CropRenderSize(dim, dim, true); - gameRenderWorld->SetRenderView(&rv); - gameRenderWorld->RenderScene(&rv); - PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_RenderScene ); - - PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_CaptureRenderToFile ); - renderSystem->CaptureRenderToFile(DARKMOD_LG_FILENAME); - PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_CaptureRenderToFile ); - - dp = cv_lg_path.GetString(); - if(dp != NULL && strlen(dp) != 0) - { - sprintf(dps, "%s_%u.tga", dp, i); - dp = dps.c_str(); - renderSystem->CaptureRenderToFile(dp); - } - else - dp = NULL; - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Rendering to lightgem render buffer\n"); - renderSystem->UnCrop(); - - PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_AnalyzeRenderImage ); - AnalyzeRenderImage(fColVal); - PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_AnalyzeRenderImage ); - - PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_Cleanup ); - - // Check which of the images has the brightest value, and this is what we will use. - for(l = 0; l < DARKMOD_LG_MAX_IMAGESPLIT; l++) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("fColVal[%u] = %f/%f\n", l, fColVal[l], m_LightgemShotValue[i]); - if(fColVal[l] > m_LightgemShotValue[i]) - m_LightgemShotValue[i] = fColVal[l]; - } - PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_Cleanup ); - } - } - - PROFILE_BLOCK_START ( LightGem_Calculate_UnSetup ); - - m_LightgemShotSpot++; - if(m_LightgemShotSpot >= nRenderPasses) - m_LightgemShotSpot = 0; - - for(i = 0; i < nRenderPasses; i++) - { - if(m_LightgemShotValue[i] > fRetVal) - fRetVal = m_LightgemShotValue[i]; - } - - prent->suppressSurfaceInViewID = playerid; - prent->suppressShadowInViewID = psid; - hrent->suppressSurfaceInViewID = headid; - hrent->suppressShadowInViewID = hsid; - - // and switch back our renderdefinition. - if(pdef != -1) - gameRenderWorld->UpdateEntityDef(pdef, prent); - - if(hdef != -1) - gameRenderWorld->UpdateEntityDef(hdef, hrent); - - PROFILE_BLOCK_END ( LightGem_Calculate_UnSetup ); - - return(fRetVal); -} - -void LightGem::AnalyzeRenderImage(float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]) -{ - CImage *im = &g_Global.m_RenderImage ; - unsigned long counter[DARKMOD_LG_MAX_IMAGESPLIT]; - int i, in, k, kn, h, x; - - im->LoadImageFromMemory(&m_LightgemRenderBuffer[0], m_LightgemRenderBuffer.Num(), DARKMOD_LG_FILENAME); - const unsigned char *buffer = im->GetImageData(); - - // This is just an errorhandling to inform the player that something is wrong. - // The lightgem will simply blink if the renderbuffer doesn't work. - if(buffer == NULL) - { - static int indicator = 0; - static int lasttime; - DM_LOG(LC_SYSTEM, LT_ERROR)LOGSTRING("Unable to read image from lightgem render-buffer\r"); - for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) - fColVal[i] = indicator; - - if(gameLocal.time/1000 != lasttime) - { - lasttime = gameLocal.time/1000; - indicator = !indicator; - } - - goto Quit; - } - - for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) - counter[i] = 0; - - // We always assume a BPP 4 here. We also always assume a square image with an even - // number of lines. An odd number might have only a very small influence though and - // most likely get canceled out if a bigger image is used. - kn = im->m_Height; - h = kn/2; - in = im->m_Width; - - // First we do the top half - for(k = 0; k < h; k++) - { - for(i = 0; i < in; i++) - { - if(i < k) - x = 0; - else if(i > kn-k-1) - x = 2; - else - x = 1; - - // The order is RGBA. - fColVal[x] += ((buffer[0] * DARKMOD_LG_RED + buffer[1] * DARKMOD_LG_GREEN + buffer[2] * DARKMOD_LG_BLUE) * DARKMOD_LG_SCALE); - counter[x]++; - buffer += im->m_Bpp; - } - } - - // Then we do the bottom half where the triangles are inverted. - for(k = (h-1); k >= 0; k--) - { - for(i = 0; i < in; i++) - { - if(i < k) - x = 0; - else if(i > kn-k-1) - x = 2; - else - x = 3; - - // The order is RGBA. - fColVal[x] += ((buffer[0] * DARKMOD_LG_RED + buffer[1] * DARKMOD_LG_GREEN + buffer[2] * DARKMOD_LG_BLUE) * DARKMOD_LG_SCALE); - counter[x]++; - buffer += im->m_Bpp; - } - } - - // Calculate the average for each value - for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) - fColVal[i] = fColVal[i]/counter[i]; - -Quit: - return; -} diff --git a/DarkMod/lightgem.h b/DarkMod/lightgem.h deleted file mode 100644 index 49731af9a..000000000 --- a/DarkMod/lightgem.h +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef __LIGHTGEM_H__ -#define __LIGHTGEM_H__ - -//---------------------------------- -// Preprocessor Constants -//---------------------------------- -// Number of passes that we can do at most. This is 6 because it's simply a cube that is rendered -// from all sides. This is not needed though, because a top and a bottom render with a pyramidic -// shape would be sufficient to cover all lighting situations. For silouhette detection we might -// consider more stages though. -#define DARKMOD_LG_MAX_RENDERPASSES 2 -#define DARKMOD_LG_MAX_IMAGESPLIT 4 -#define DARKMOD_LG_RENDER_MODEL "models/darkmod/misc/system/lightgem.lwo" -#define DARKMOD_LG_ENTITY_NAME "lightgem_surface" -// The lightgem viewid defines the viewid that is to be used for the lightgem surfacetestmodel -#define DARKMOD_LG_VIEWID -1 -#define DARKMOD_LG_RENDER_WIDTH 50 - -#define DARKMOD_LG_FILENAME "TDM_lightgem" -// The colour is converted to a grayscale value which determines the state -// of the lightgem. -// LightGem = (0.29900*R+0.58700*G+0.11400*B) * 0.0625 - -#define DARKMOD_LG_MIN 1 -#define DARKMOD_LG_MAX 32 -#define DARKMOD_LG_FRACTION (1.0f/32.0f) -#define DARKMOD_LG_RED 0.29900f -#define DARKMOD_LG_GREEN 0.58700f -#define DARKMOD_LG_BLUE 0.11400f -#define DARKMOD_LG_SCALE (1.0/255.0) // scaling factor for grayscale value - -//---------------------------------- -// Class Declarations. -//---------------------------------- - -class LightGem -{ -private: - int m_LightgemShotSpot; - float m_LightgemShotValue[DARKMOD_LG_MAX_RENDERPASSES]; - idEntityPtr m_LightgemSurface; - - // stgatilov: The buffer for captured lightgem image - idList m_LightgemRenderBuffer; - -public: - ID_INLINE idList &GetLightgemRenderBuffer ( void ) { return m_LightgemRenderBuffer; } - - //--------------------------------- - // Construction/Destruction - //--------------------------------- - LightGem (); - ~LightGem (); - - //--------------------------------- - // Initialization - //--------------------------------- - void Initialize (); - void Deinitialize (); - void Clear (); - - //--------------------------------- - // Persistence - //--------------------------------- - void Save ( idSaveGame & a_saveGame ); - void Restore ( idRestoreGame & a_savedGame ); - //--------------------------------- - - //--------------------------------- - // SpawnlightgemEntity will create exactly one lightgem entity for the map and ensures - // that no multiple copies of it will exist. - //--------------------------------- - void SpawnLightGemEntity( idMapFile * a_mapFile ); - void InitializeLightGemEntity(); - - //--------------------------------- - // Calculation - //--------------------------------- - float Calculate ( idPlayer * a_pPlayer ); - -private: - void AnalyzeRenderImage (float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]); -}; - -#endif // __LIGHTGEM_H__ \ No newline at end of file diff --git a/DarkMod/liquid.cpp b/DarkMod/liquid.cpp deleted file mode 100644 index c1baca59f..000000000 --- a/DarkMod/liquid.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "StimResponse/StimResponseCollection.h" - -#ifdef MOD_WATERPHYSICS - -// We do these splashes if the mass of the colliding object is less than these values. -// Anything large than MEDIUM_SPLASH does a large splash. (get it?) -const int SMALL_SPLASH = 5; -const int MEDIUM_SPLASH = 20; - -/* -=============================================================================== - - idLiquid - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idLiquid ) - EVENT( EV_Touch, idLiquid::Event_Touch ) -END_CLASS - -idLiquid::idLiquid( void ) { -} - -/* -================ -idLiquid::Save -================ -*/ -void idLiquid::Save( idSaveGame *savefile ) const { - - int i; - - savefile->WriteStaticObject( this->physicsObj ); - - savefile->WriteString(smokeName.c_str()); - savefile->WriteString(soundName.c_str()); - - for( i = 0; i < 3; i++ ) - savefile->WriteParticle(this->splash[i]); - savefile->WriteParticle(this->waves); -} - -/* -================ -idLiquid::Restore -================ -*/ -void idLiquid::Restore( idRestoreGame *savefile ) { - - int i; - - savefile->ReadStaticObject( this->physicsObj ); - RestorePhysics( &this->physicsObj ); - - savefile->ReadString(this->smokeName); - savefile->ReadString(this->soundName); - - for( i = 0; i < 3; i++ ) - savefile->ReadParticle(this->splash[i]); - savefile->ReadParticle(this->waves); -} - -idLiquid::~idLiquid() -{ - // Traverse all spawned entities and remove ourselves as water if necessary - for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - if (ent->GetPhysics() != NULL && ent->GetPhysics()->GetWater() == &physicsObj) - { - ent->GetPhysics()->SetWater(NULL, 0.0f); - } - } -} - -/* -================ -idLiquid::Spawn -================ -*/ -void idLiquid::Spawn() { -/* - model = dynamic_cast( renderEntity.hModel ); - if ( !model ) { - gameLocal.Error( "Entity '%s' must have liquid model", name.c_str() ); - } - model->Reset(); -*/ - float liquidDensity; - float liquidViscosity; - float liquidFriction; - idVec3 minSplash; - idVec3 minWave; - idStr temp; - const char *splashName; - - //common->Printf("idLiquid:%s) Spawned\n",this->GetName() ); - - // getters - spawnArgs.GetFloat("density","0.001043f",liquidDensity); - spawnArgs.GetFloat("viscosity","3.0f",liquidViscosity); - spawnArgs.GetFloat("friction","3.0f",liquidFriction); - spawnArgs.GetString("liquid_name","water",temp); - spawnArgs.GetVector("minSplashVelocity","100 100 100",minSplash); - spawnArgs.GetVector("minWaveVelocity","60 60 60",minWave); - - // setters - this->smokeName = "smoke_"; - this->smokeName.Append(temp); - - this->soundName = "snd_"; - this->soundName.Append(temp); - - splashName = spawnArgs.GetString("smoke_small","water_splash_small"); - this->splash[0] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); - - splashName = spawnArgs.GetString("smoke_medium","water_splash"); - this->splash[1] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); - - splashName = spawnArgs.GetString("smoke_large","water_splash_large"); - this->splash[2] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); - - splashName = spawnArgs.GetString("smoke_waves","water_waves"); - this->waves = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); - - // setup physics - this->physicsObj.SetSelf(this); - this->physicsObj.SetClipModel( new idClipModel(this->GetPhysics()->GetClipModel()), liquidDensity ); - this->physicsObj.SetOrigin(this->GetPhysics()->GetOrigin()); - this->physicsObj.SetAxis(this->GetPhysics()->GetAxis()); - this->physicsObj.SetGravity( gameLocal.GetGravity() ); - this->physicsObj.SetContents( CONTENTS_WATER | CONTENTS_TRIGGER ); - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - this->physicsObj.SetDensity(liquidDensity); - this->physicsObj.SetViscosity(liquidViscosity); - this->physicsObj.SetMinSplashVelocity(minSplash); - this->physicsObj.SetMinWaveVelocity(minWave); - - this->SetPhysics( &this->physicsObj ); - - renderEntity.shaderParms[ 3 ] = spawnArgs.GetFloat( "shaderParm3", "1" ); - renderEntity.shaderParms[ 4 ] = spawnArgs.GetFloat( "shaderParm4", "0" ); - renderEntity.shaderParms[ 5 ] = spawnArgs.GetFloat( "shaderParm5", "0.1" ); - renderEntity.shaderParms[ 6 ] = spawnArgs.GetFloat( "shaderParm6", "1.5" ); - renderEntity.shaderParms[ 7 ] = spawnArgs.GetFloat( "shaderParm7", "0" ); - renderEntity.shaderParms[ 8 ] = spawnArgs.GetFloat( "shaderParm8", "0" ); - renderEntity.shaderParms[ 9 ] = spawnArgs.GetFloat( "shaderParm9", "0" ); - renderEntity.shaderParms[ 10 ] = spawnArgs.GetFloat( "shaderParm10", "0" ); - renderEntity.shaderParms[ 11 ] = spawnArgs.GetFloat( "shaderParm11", "0" ); - - BecomeActive( TH_THINK ); -} - -/* -================ -idLiquid::Event_Touch - - This is mainly used for actors who touch the liquid, it spawns a splash - near they're feet if they're moving fast enough. -================ -*/ -void idLiquid::Event_Touch( idEntity *other, trace_t *trace ) { -// FIXME: for QuakeCon -/* - idVec3 pos; - - pos = other->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - model->IntersectBounds( other->GetPhysics()->GetBounds().Translate( pos ), -10.0f ); -*/ - - idPhysics_Liquid *liquid; - idPhysics_Actor *phys; - - if( !other->GetPhysics()->IsType(idPhysics_Actor::Type) ) - return; - - phys = static_cast(other->GetPhysics()); - if( phys->GetWaterLevel() != WATERLEVEL_FEET ) - return; - - impactInfo_t info; - other->GetImpactInfo(this,trace->c.id,trace->c.point,&info); - liquid = &this->physicsObj; - - trace->c.point = info.position + other->GetPhysics()->GetOrigin(); - trace->c.entityNum = other->entityNumber; - - // stop actors from constantly splashing when they're in the water - // (this is such a bad thing to do!!!) - // TODO: Fixme... - // 1) Probably the best way to fix this is put a wait timer inside the actor and have this - // function set/reset that timer for when the actor should spawn particles at it's feet. - // 2) Actors don't spawn particles at their feet, it's usually at the origin, for some - // reason info.position is (null), needs a fix so that splash position is correct - if( gameLocal.random.RandomFloat() > 0.5f ) - return; - - this->Collide(*trace,info.velocity); -} - -/* -================ -idLiquid::Collide - Spawns a splash particle and attaches a sound to the colliding entity. -================ -*/ -bool idLiquid::Collide( const trace_t &collision, const idVec3 &velocity ) { - idEntity *e = gameLocal.entities[collision.c.entityNum]; - idPhysics_Liquid *phys = static_cast( this->GetPhysics() ); - const idDeclParticle *splash; - const char *sName; - float eMass; - idVec3 splashSpot; - float velSquare = velocity.LengthSqr(); - - ProcCollisionStims( e, collision.c.id ); - - eMass = e->GetPhysics()->GetMass(); - splashSpot = collision.c.point; - - if( velSquare > phys->GetMinSplashVelocity().LengthSqr() ) { - // pick which splash particle to spawn - // first we check the entity, if it's not defined we use - // one defined for this liquid. - sName = e->spawnArgs.GetString(this->smokeName.c_str()); - if( *sName != '\0' ) { - // load entity particle - splash = static_cast(declManager->FindType(DECL_PARTICLE,sName)); - } - else { - // load a liquid particle based on the mass of the splashing entity - if( eMass < SMALL_SPLASH ) - splash = this->splash[0]; - else if( eMass < MEDIUM_SPLASH ) - splash = this->splash[1]; - else - splash = this->splash[2]; - } - - // only play the sound for a splash - e->StartSound( this->soundName.c_str(), SND_CHANNEL_ANY, 0, false, NULL); - } - else if( velSquare > phys->GetMinWaveVelocity().LengthSqr() ) { - splash = this->waves; - } - else { - // the object is moving to slow so we abort - return true; - } - - // spawn the particle - gameLocal.smokeParticles->EmitSmoke( splash, gameLocal.time, gameLocal.random.RandomFloat(), splashSpot, collision.endAxis ); - return true; -} - -#endif diff --git a/DarkMod/liquid.h b/DarkMod/liquid.h deleted file mode 100644 index 07172464e..000000000 --- a/DarkMod/liquid.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __LIQUID_H__ -#define __LIQUID_H__ - -/* -=============================================================================== - - idLiquid - - Base class for all liquid object. The entity part of the liquid is - responsible for spawning splashes and sounds to match. - - The physics portion is as usual, responsible for the physics. -=============================================================================== -*/ - -#define MOD_WATERPHYSICS_VER "Water Physics 0.8 ^7by Lloyd" -#ifdef MOD_WATERPHYSICS - -class idRenderModelLiquid; - -class idLiquid : public idEntity { -public: - CLASS_PROTOTYPE( idLiquid ); - - idLiquid( void ); - - virtual ~idLiquid(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - -private: - void Event_Touch( idEntity *other, trace_t *trace ); - - idPhysics_Liquid physicsObj; - - idRenderModelLiquid *model; - - const idDeclParticle *splash[3]; - const idDeclParticle *waves; - - idStr smokeName; - idStr soundName; -}; - -#endif // MOD_WATERPHYISCS -#endif // __LIQUID_H__ diff --git a/DarkMod/overlaySys.h b/DarkMod/overlaySys.h deleted file mode 100644 index 1826ad258..000000000 --- a/DarkMod/overlaySys.h +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __DARKMOD_OVERLAYSYS_H__ -#define __DARKMOD_OVERLAYSYS_H__ - -const int OVERLAYS_MIN_HANDLE = 1; -const int OVERLAYS_INVALID_HANDLE = 0; - -/** -* These is the layer order of the overlay for the player GUI. -*/ -enum -{ - LAYER_UNDERWATER = 0, // Draw the underwater overlay first - LAYER_MAIN_HUD = 1, - LAYER_INVENTORY = 2, - LAYER_OBJECTIVES = 12, - LAYER_WAITUNTILREADY = 13, -}; - -struct SOverlay; - -/// Container class to keep track of multiple GUIs. -/** An overlay system is used to keep track of an arbitrary number of GUIs. - * The overlay system consists of zero or more 'overlays'. An overlay - * contains a GUI and some bookkeeping information. Each overlay has a - * 'layer' which is used to sort the order the overlays are drawn in. - * Overlays in higher layers are drawn on top of overlays in lower layers. - * Multiple overlays may exist in the same layer, but their drawing order - * with respect to eachother is undefined. - * - * An overlay may be opaque. If/when the overlay system is rendered directly - * to screen, this overlay is assumed to have no transparent sections, and - * nothing underneath it will be rendered. This has no effect on GUIs that - * are in the game-world. - * - * An overlay may be interactive. If the overlay system is asked which GUI - * interactivity should be routed to, it will return the GUI in the highest - * interactive overlay. This has no effect on GUIs that are in the - * game-world. - * - * An overlay may be external, meaning that its GUI points to a GUI defined - * externally. Note that although external overlays are saved and restored, - * their GUI pointer isn't, and needs to be set again. - * - * I'm assuming the overlay system will only be used to contain a few - * overlays at a time, so I've opted for simpler data structures and easier - * code, rather than trying to make the most efficient system possible. - * However, certain easy optimizatons have been made; although accessing a - * different overlay from last time is O(N) with respect to the number of - * overlays contained, repeatedly accessing the same overlay is very fast. - * Similarly, results relating to which layers are opaque/interactive are - * cached. - */ -class COverlaySys -{ - public: - - COverlaySys(); - ~COverlaySys(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /// Draws the contained GUIs to the screen, in order. - void drawOverlays(); - /// Returns true if any of the GUIs are opaque. - bool isOpaque(); - /// Returns the interactive GUI. - idUserInterface* findInteractive(); - /// Used for iterating through the overlays in drawing-order. - /** Very efficient if used properly: - * int h = OVERLAYS_INVALID_HANDLE; - * while ( (h = o.getNextOverlay(h) ) != OVERLAYS_INVALID_HANDLE ) - * o.doSomethingWith( h ); - * It loses efficiency if a handle is accessed other than the one returned. - */ - int getNextOverlay( int handle ); - - /// Create a new overlay, returning a handle for that overlay. - int createOverlay( int layer, int handle = OVERLAYS_INVALID_HANDLE ); - /// Destroy an overlay. - void destroyOverlay( int handle ); - /// Returns whether or not an overlay exists. - bool exists( int handle ); - /// Sets the overlay's GUI to an external GUI. - void setGui( int handle, idUserInterface* gui ); - /// Sets the overlay's GUI to an internal, unique one. - bool setGui( int handle, const char* file ); - /// Return an overlay's GUI. - idUserInterface* getGui( int handle ); - /// Change an overlay's layer. - void setLayer( int handle, int layer ); - /// Return an overlay's layer. - int getLayer( int handle ); - /// Return whether or not an overlay is external. - bool isExternal( int handle ); - /// Change whether or not an overlay is considered opaque. - void setOpaque( int handle, bool isOpaque ); - /// Return whether or not an overlay is considered opaque. - bool isOpaque( int handle ); - /// Change whether or not an overlay is considered interactive. - void setInteractive( int handle, bool isInteractive ); - /// Return whether or not an overlay is considered interactive. - bool isInteractive( int handle ); - - /** - * greebo: This cycles through all overlays and calls HandleNamedEvent() - * on each visible GUI. - */ - void broadcastNamedEvent(const char* eventName); - - /** - * greebo: Use these methods to set the state variables of ALL active overlays. - * This is similar to the broadcastNamedEvent, but these routines only set - * a GUI state variable (e.g. "gui::HUD_Opacity"). - */ - void setGlobalStateString(const char* varName, const char *value); - void setGlobalStateBool(const char* varName, const bool value); - void setGlobalStateInt(const char* varName, const int value); - void setGlobalStateFloat(const char* varName, const float value); - - private: - - /// Returns the overlay associated with a handle. - SOverlay* findOverlay( int handle, bool updateCache = true ); - /// Returns the highest opaque overlay. - idLinkList* findOpaque(); - - /// The list of overlays. - idLinkList m_overlays; - - /// The last handle accessed. - int m_lastUsedHandle; - /// The overlay of the last handle accessed. - SOverlay* m_lastUsedOverlay; - - /// Whether or not the highest opaque overlay needs to be recalculated. - bool m_updateOpaque; - /// The cached value of the highest opaque overlay. - idLinkList* m_highestOpaque; - - /// Whether or not the interactive overlay needs to be recalculated. - bool m_updateInteractive; - /// The cached value of the interactive overlay. - idUserInterface* m_highestInteractive; - - /// This is the next handle to try out when creating a new overlay. - int m_nextHandle; -}; - -struct SOverlay -{ - idLinkList m_node; - idUserInterface* m_gui; - int m_handle; - int m_layer; - bool m_external; - bool m_opaque; - bool m_interactive; -}; - -#endif /* __DARKMOD_OVERLAYSYS_H__ */ diff --git a/DarkMod/overlaysys.cpp b/DarkMod/overlaysys.cpp deleted file mode 100644 index d31a37753..000000000 --- a/DarkMod/overlaysys.cpp +++ /dev/null @@ -1,616 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game/game_local.h" - -#include "overlaySys.h" - -// I'm keeping these functions seperate from the overlaysys code, -// in case I end up needing to implement recycling. -static inline idUserInterface* newGui(const char* file) -{ - //return uiManager->FindGui( file, true, false, true ); - return uiManager->FindGui(file, true, true); -} -static inline void delGui(idUserInterface* gui) -{ - uiManager->DeAlloc(gui); -} - -COverlaySys::COverlaySys() -{ - m_lastUsedHandle = 0; - m_lastUsedOverlay = NULL; - m_updateOpaque = false; - m_highestOpaque = NULL; - m_updateInteractive = false; - m_highestInteractive = NULL; - m_nextHandle = OVERLAYS_MIN_HANDLE; -} - -COverlaySys::~COverlaySys() -{ - SOverlay* overlay; - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - overlay = oNode->Owner(); - oNode = oNode->NextNode(); - - if (!overlay->m_external) - delGui(overlay->m_gui); - - delete overlay; - } -} - -void COverlaySys::Save( idSaveGame *savefile ) const -{ - SOverlay* overlay; - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - overlay = oNode->Owner(); - savefile->WriteInt( overlay->m_handle ); - savefile->WriteInt( overlay->m_layer ); - savefile->WriteBool( overlay->m_external ); - savefile->WriteBool( overlay->m_opaque ); - savefile->WriteBool( overlay->m_interactive ); - if ( !overlay->m_external ) - savefile->WriteUserInterface( overlay->m_gui, false ); - - oNode = oNode->NextNode(); - } - savefile->WriteInt( OVERLAYS_INVALID_HANDLE ); -} - -void COverlaySys::Restore( idRestoreGame *savefile ) -{ - int handle; - SOverlay* overlay; - - savefile->ReadInt( handle ); - while(handle >= OVERLAYS_MIN_HANDLE) - { - overlay = new SOverlay; - if(!overlay) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to allocate SOverlay.\r"); - goto Quit; - } - - overlay->m_node.SetOwner( overlay ); - overlay->m_node.AddToEnd( m_overlays ); - overlay->m_handle = handle; - savefile->ReadInt( overlay->m_layer ); - savefile->ReadBool( overlay->m_external ); - savefile->ReadBool( overlay->m_opaque ); - savefile->ReadBool( overlay->m_interactive ); - if (overlay->m_external) - overlay->m_gui = NULL; // I don't think there's a way to save/restore pointers to GUIs saved by other things. - else - savefile->ReadUserInterface(overlay->m_gui); - - savefile->ReadInt(handle); - } - - m_updateOpaque = m_updateInteractive = true; - -Quit: - return; -} - -void COverlaySys::drawOverlays() -{ - idUserInterface* gui; - idLinkList* oNode = findOpaque(); - if(!oNode) - oNode = m_overlays.NextNode(); - - while(oNode) - { - gui = oNode->Owner()->m_gui; - if(gui) - { - gameLocal.UpdateGUIScaling(gui); - - int time = gameLocal.realClientTime; - - // greebo: We have a special GUI that is updated before control is passed to this method - // there is a time offset stored in that GUI, add that to the realClientTime. - time += gui->GetStateInt("GuiTimeOffset"); - - gui->Redraw(time); - } - oNode = oNode->NextNode(); - } -} - -bool COverlaySys::isOpaque() { - return findOpaque() != NULL; -} - -int COverlaySys::getNextOverlay( int handle ) -{ - int retHandle = OVERLAYS_INVALID_HANDLE; - - idLinkList *oNode; - SOverlay *overlay = findOverlay( handle, false ); - if(overlay) - oNode = overlay->m_node.NextNode(); - else if(handle == OVERLAYS_INVALID_HANDLE) - oNode = m_overlays.NextNode(); - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getNextOverlay: Non-existant GUI handle: %d\r", handle); - return retHandle; - } - - if(oNode) - { - m_lastUsedOverlay = oNode->Owner(); - m_lastUsedHandle = m_lastUsedOverlay->m_handle; - retHandle = m_lastUsedHandle; - } - - return retHandle; -} - -int COverlaySys::createOverlay( int layer, int handle ) -{ - assert( handle >= OVERLAYS_MIN_HANDLE || handle == OVERLAYS_INVALID_HANDLE ); - - int retHandle = OVERLAYS_INVALID_HANDLE; - - // Find a valid handle for our overlay. - idLinkList* oNode; - if(handle == OVERLAYS_INVALID_HANDLE) - { - // Any handle will do. - bool foundHandle = false; - - // Iterate through all available handles until we come back to where we started. - handle = m_nextHandle; - do - { - // Check if the overlay has the handle. - oNode = m_overlays.NextNode(); - while(oNode) - { - if(oNode->Owner()->m_handle == handle) - break; - oNode = oNode->NextNode(); - } - - // If we went all the way through the loop, the handle doesn't already exist. - if(!oNode) - { - foundHandle = true; - break; - } - - handle++; - if(handle < OVERLAYS_MIN_HANDLE) - handle = OVERLAYS_MIN_HANDLE; - } while(handle != m_nextHandle); - - if(!foundHandle) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("No more handles available.\r"); - return retHandle; - } - - m_nextHandle = handle + 1; - if ( m_nextHandle < OVERLAYS_MIN_HANDLE ) - m_nextHandle = OVERLAYS_MIN_HANDLE; - - } - else - { - // There's a specific handle that is desired. - oNode = m_overlays.NextNode(); - while(oNode) - { - // If the handle is unavailable, don't create anything. - if(oNode->Owner()->m_handle == handle) - return retHandle; - - oNode = oNode->NextNode(); - } - } - - // At this point, 'handle' is the handle our overlay will have. - - // Find the position after which we will insert our overlay. - idLinkList* position = &m_overlays; // The position after which we will insert the new overlay - oNode = m_overlays.NextNode(); - while(oNode) - { - if(layer >= oNode->Owner()->m_layer) - position = oNode; - - oNode = oNode->NextNode(); - } - - SOverlay* overlay = new SOverlay; - if(!overlay) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to allocate overlay.\r"); - return retHandle; - } - - overlay->m_node.SetOwner( overlay ); - overlay->m_node.InsertAfter( *position ); - overlay->m_gui = NULL; - overlay->m_handle = handle; - overlay->m_layer = layer; - overlay->m_external = true; - overlay->m_opaque = false; - overlay->m_interactive = false; - - return handle; -} - -void COverlaySys::destroyOverlay( int handle ) -{ - SOverlay* overlay = findOverlay( handle, false ); - if ( overlay == NULL ) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - goto Quit; - } - - // If the last-used cache points to the overlay, clear it. - if(m_lastUsedOverlay == overlay) - { - m_lastUsedHandle = OVERLAYS_INVALID_HANDLE; - m_lastUsedOverlay = NULL; // not necessary, but perhaps safer - } - - // If this was an opaque overlay, we need to update opacity. - if(overlay->m_opaque) - m_updateOpaque = true; - - // If this was an interactive overlay, we need to update interactivity. - if (overlay->m_interactive) - m_updateInteractive = true; - - if (!overlay->m_external) - delGui(overlay->m_gui); - - delete overlay; - -Quit: - return; -} - -/// Returns whether or not an overlay exists. -bool COverlaySys::exists(int handle) -{ - return findOverlay(handle) != NULL; -} - -/// Sets the overlay's GUI to an external GUI. -void COverlaySys::setGui(int handle, idUserInterface* gui) -{ - SOverlay* overlay = findOverlay(handle); - if(overlay) - { - if(!overlay->m_external) - { - delGui( overlay->m_gui ); - overlay->m_external = true; - } - - overlay->m_gui = gui; - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); -} - -/// Sets the overlay's GUI to an internal, unique one. -bool COverlaySys::setGui( int handle, const char* file ) -{ - bool retVal = false; - SOverlay* overlay = findOverlay( handle ); - if(overlay) - { - idUserInterface* gui = newGui(file); - if(gui) - { - if(!overlay->m_external) - delGui(overlay->m_gui); - - overlay->m_gui = gui; - overlay->m_external = false; - retVal = true; - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load gui: %s\r", file); - goto Quit; - } - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d [%s]\r", handle, file); - goto Quit; - } - -Quit: - return retVal; -} - -idUserInterface* COverlaySys::getGui(int handle) -{ - SOverlay* overlay = findOverlay(handle); - if ( overlay ) - return overlay->m_gui; - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - return NULL; - } -} - -void COverlaySys::setLayer( int handle, int layer ) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - // Find the new spot for the overlay. - idLinkList* position = &m_overlays; // insert the new overlay AFTER this position - idLinkList* oNode = m_overlays.NextNode(); - while ( oNode ) - { - if ( layer >= oNode->Owner()->m_layer ) - position = oNode; - oNode = oNode->NextNode(); - } - - // Did we actually change positions? - if ( position->Next() != overlay && position != &overlay->m_node ) - { - overlay->m_node.InsertAfter( *position ); - overlay->m_layer = layer; - - // If this is an opaque overlay, we need to update opacity. - if ( overlay->m_opaque ) - m_updateOpaque = true; - - // If this is an interactive overlay, we need to update interactivity. - if ( overlay->m_interactive ) - m_updateInteractive = true; - } - - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - } -} - -int COverlaySys::getLayer( int handle ) -{ - SOverlay* overlay = findOverlay( handle ); - if(overlay) - return overlay->m_layer; - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - return 0; - } -} - -bool COverlaySys::isExternal(int handle) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - return overlay->m_external; - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - return false; - } -} - -void COverlaySys::setOpaque( int handle, bool isOpaque ) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - if ( overlay->m_opaque != isOpaque ) - { - overlay->m_opaque = isOpaque; - m_updateOpaque = true; - } - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - } -} - -bool COverlaySys::isOpaque( int handle ) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - return overlay->m_opaque; - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - return false; - } -} - -void COverlaySys::setInteractive( int handle, bool isInteractive ) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - if ( overlay->m_interactive != isInteractive ) - { - overlay->m_interactive = isInteractive; - m_updateInteractive = true; - } - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - } -} - -bool COverlaySys::isInteractive( int handle ) -{ - SOverlay* overlay = findOverlay( handle ); - if ( overlay ) - { - return overlay->m_interactive; - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); - return false; - } -} - -SOverlay* COverlaySys::findOverlay( int handle, bool updateCache ) -{ - SOverlay* retVal = NULL; - - if ( handle < OVERLAYS_MIN_HANDLE ) - return NULL; - - // Are we looking for the same handle as last time? - if ( handle == m_lastUsedHandle ) - { - return m_lastUsedOverlay; - } - - idLinkList* oNode = m_overlays.NextNode(); - while ( oNode ) - { - // Did we find the handle we're looking for? - if ( handle == oNode->Owner()->m_handle ) - { - retVal = oNode->Owner(); - - if ( updateCache ) - { - m_lastUsedHandle = handle; - m_lastUsedOverlay = retVal; - } - return retVal; - } - - oNode = oNode->NextNode(); - } - - return NULL; -} - -idLinkList* COverlaySys::findOpaque() -{ - if ( m_updateOpaque ) - { - // Find the highest opaque overlay. - idLinkList* oNode = m_overlays.PrevNode(); - while ( oNode ) - { - if ( oNode->Owner()->m_opaque ) - break; - oNode = oNode->PrevNode(); - } - m_highestOpaque = oNode; - m_updateOpaque = false; - } - return m_highestOpaque; -} - -idUserInterface* COverlaySys::findInteractive() -{ - if ( m_updateInteractive ) - { - // Find the highest interactive overlay. - idLinkList* oNode = m_overlays.PrevNode(); - while ( oNode ) - { - if ( oNode->Owner()->m_interactive ) - break; - oNode = oNode->PrevNode(); - } - m_highestInteractive = oNode ? oNode->Owner()->m_gui : NULL; - m_updateInteractive = false; - } - return m_highestInteractive; -} - -void COverlaySys::broadcastNamedEvent(const char* eventName) -{ - // Cycle through the nodes - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - oNode->Owner()->m_gui->HandleNamedEvent(eventName); - oNode = oNode->NextNode(); - } -} - -void COverlaySys::setGlobalStateString(const char* varName, const char *value) -{ - // Cycle through the nodes - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - oNode->Owner()->m_gui->SetStateString(varName, value); - oNode = oNode->NextNode(); - } -} - -void COverlaySys::setGlobalStateBool(const char* varName, const bool value) -{ - // Cycle through the nodes - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - oNode->Owner()->m_gui->SetStateBool(varName, value); - oNode = oNode->NextNode(); - } -} - -void COverlaySys::setGlobalStateInt(const char* varName, const int value) -{ - // Cycle through the nodes - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - oNode->Owner()->m_gui->SetStateInt(varName, value); - oNode = oNode->NextNode(); - } -} - -void COverlaySys::setGlobalStateFloat(const char* varName, const float value) -{ - // Cycle through the nodes - idLinkList* oNode = m_overlays.NextNode(); - while(oNode) - { - oNode->Owner()->m_gui->SetStateFloat(varName, value); - oNode = oNode->NextNode(); - } -} diff --git a/DarkMod/sndProp.cpp b/DarkMod/sndProp.cpp deleted file mode 100644 index eea49f13d..000000000 --- a/DarkMod/sndProp.cpp +++ /dev/null @@ -1,1662 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -/******************************************************************************/ -/* */ -/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ -/* All rights reserved */ -/* */ -/******************************************************************************/ - -/****************************************************************************** -* -* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI -* during gameplay. Friend class to CsndPropLoader. -* -*****************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#include "../game/game_local.h" - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning(disable : 4996) - -#include "sndPropLoader.h" -#include "sndProp.h" -#include "MatrixSq.h" -#include "DarkModGlobals.h" -#include "Relations.h" -#include "../game/ai/ai.h" - -// NOTES: -// ALL LOSSES ARE POSITIVE (ie, loss of +10dB subtracts 10dB from vol) - -// ALL INITIAL VOLUMES ARE SWL [dB] (power level of the source, 10*log(power/1E-12 Watts)) - -// TODO: Add volInit to propParms instead of continually passing it as an argument - -const float s_DOOM_TO_METERS = 0.0254f; // doom to meters -const float s_METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom - -/** -* Max number of areas to flood when doing wavefront expansion -* -* When the expansion goes above this number, it is terminated -* -* TODO: Read this from soundprop def file! -**/ -const int s_MAX_FLOODNODES = 200; - -/** -* Volume ( SPL [dB] ) threshold after which the sound stops propagating -* -* Should correspond to the absolute lowest volume we want AI to be -* able to detect -* -* TODO: Read this from soundprop def file! -**/ -const float s_MIN_AUD_THRESH = 15; - -/** -* Max number of expansion nodes within which to use detailed path minimization -* (That is, trace the path back from AI thru the portals to find the optimum -* points on the portal surface the path travels thru). -* -* TODO: Read this from soundprop def file! -**/ -const float s_MAX_DETAILNODES = 3; - - -/** -* 1/log(10), useful for change of base between log and log10 -**/ -const float s_invLog10 = 0.434294482f; - - -/************************************************** -* BEGIN CsndProp Implementation -***************************************************/ - -CsndProp::CsndProp ( void ) -{ - m_bLoadSuccess = false; - m_bDefaultSpherical = false; - - m_EventAreas = NULL; - m_PopAreas = NULL; - m_sndAreas = NULL; - m_PortData = NULL; - - m_numAreas = 0; - m_numPortals = 0; - - m_TimeStampProp = 0; - m_TimeStampPortLoss = 0; -} - -void CsndProp::Clear( void ) -{ - SPortEvent *pPortEv; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing sound prop gameplay object.\r"); - - m_AreaPropsG.Clear(); - - m_bLoadSuccess = false; - m_bDefaultSpherical = false; - - if( m_EventAreas != NULL ) - { - // delete portal event data array - for( int i=0; i < m_numAreas; i++ ) - { - pPortEv = m_EventAreas[i].PortalDat; - if( pPortEv != NULL ) - delete[] pPortEv; - } - - delete[] m_EventAreas; - m_EventAreas = NULL; - } - - if( m_PopAreas != NULL ) - { - for( int i=0; i < m_numAreas; i++ ) - { - m_PopAreas[i].AIContents.Clear(); - m_PopAreas[i].VisitedPorts.Clear(); - } - - delete[] m_PopAreas; - m_PopAreas = NULL; - } - - // delete m_sndAreas and m_PortData - DestroyAreasData(); -} - -CsndProp::~CsndProp ( void ) -{ - Clear(); -} - -void CsndProp::Save(idSaveGame *savefile) const -{ - // Pass the call to the base class first - CsndPropBase::Save(savefile); - - savefile->WriteInt(m_TimeStampProp); - savefile->WriteInt(m_TimeStampPortLoss); - - savefile->WriteInt(m_PopAreasInd.Num()); - for (int i = 0; i < m_PopAreasInd.Num(); i++) - { - savefile->WriteInt(m_PopAreasInd[i]); - } - - for (int i = 0; i < m_numAreas; i++) - { - savefile->WriteInt(m_PopAreas[i].addedTime); - savefile->WriteBool(m_PopAreas[i].bVisited); - - savefile->WriteInt(m_PopAreas[i].AIContents.Num()); - for (int j = 0; j < m_PopAreas[i].AIContents.Num(); j++) - { - m_PopAreas[i].AIContents[j].Save(savefile); - } - - savefile->WriteInt(m_PopAreas[i].VisitedPorts.Num()); - for (int j = 0; j < m_PopAreas[i].VisitedPorts.Num(); j++) - { - savefile->WriteInt(m_PopAreas[i].VisitedPorts[j]); - } - } - - for (int i = 0; i < m_numAreas; i++) - { - savefile->WriteBool(m_EventAreas[i].bVisited); - - for (int portal = 0; portal < m_sndAreas[i].numPortals; portal++) - { - savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Loss); - savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Dist); - savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Att); - savefile->WriteInt(m_EventAreas[i].PortalDat[portal].Floods); - - // Don't save ThisPort, it's just pointing at m_sndAreas - - // greebo: TODO: How to save PrevPort? - } - } -} - -void CsndProp::Restore(idRestoreGame *savefile) -{ - int num; - - // Pass the call to the base class first - CsndPropBase::Restore(savefile); - - savefile->ReadInt(m_TimeStampProp); - savefile->ReadInt(m_TimeStampPortLoss); - - m_PopAreasInd.Clear(); - savefile->ReadInt(num); - m_PopAreasInd.SetNum(num); - for (int i = 0; i < num; i++) - { - savefile->ReadInt(m_PopAreasInd[i]); - } - - m_PopAreas = new SPopArea[m_numAreas]; - for (int i = 0; i < m_numAreas; i++) - { - savefile->ReadInt(m_PopAreas[i].addedTime); - savefile->ReadBool(m_PopAreas[i].bVisited); - - savefile->ReadInt(num); - m_PopAreas[i].AIContents.Clear(); - for (int j = 0; j < num; j++) - { - idEntityPtr ai; - ai.Restore(savefile); - m_PopAreas[i].AIContents.Append(ai); - } - - savefile->ReadInt(num); - m_PopAreas[i].VisitedPorts.Clear(); - m_PopAreas[i].VisitedPorts.SetNum(num); - for (int j = 0; j < num; j++) - { - savefile->ReadInt(m_PopAreas[i].VisitedPorts[j]); - } - } - - m_EventAreas = new SEventArea[m_numAreas]; - for (int i = 0; i < m_numAreas; i++) - { - savefile->ReadBool(m_EventAreas[i].bVisited); - - m_EventAreas[i].PortalDat = new SPortEvent[m_sndAreas[i].numPortals]; - - for (int portal = 0; portal < m_sndAreas[i].numPortals; portal++) - { - savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Loss); - savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Dist); - savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Att); - savefile->ReadInt(m_EventAreas[i].PortalDat[portal].Floods); - - // Restore the ThisPort pointer, it's just pointing at m_sndAreas - m_EventAreas[i].PortalDat[portal].ThisPort = &m_sndAreas[i].portals[portal]; - - // greebo: TODO: How to restore PrevPort? - } - } -} - -void CsndProp::SetupFromLoader( const CsndPropLoader *in ) -{ - SAreaProp defaultArea; - int tempint(0); - int numPorts; - SEventArea *pEvArea; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting up soundprop gameplay object\r"); - - Clear(); - - m_SndGlobals = in->m_SndGlobals; - - if( !in->m_bLoadSuccess ) - { - // setup the default sound prop object for failed loads - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SndPropLoader failed to load from the .spr file.\r"); - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SndProp is using default (simple, single area) setup\r"); - - //TODO: Uncomment these when soundprop from file is fully implemented - //gameLocal.Warning("[DM SPR] SndPropLoader failed to load from the .spr file."); - //gameLocal.Warning("[DM SPR] "SndProp is the using default (simple, single area) setup."); - - //TODO : Need better default behavior for bad file, this isn't going to work - defaultArea.area = 0; - defaultArea.LossMult = 1.0 * m_SndGlobals.kappa0; - defaultArea.VolMod = 0.0; - defaultArea.DataEntered = false; - - m_AreaPropsG.Append( defaultArea ); - m_AreaPropsG.Condense(); - - goto Quit; - } - - m_bLoadSuccess = true; - - m_numAreas = in->m_numAreas; - m_numPortals = in->m_numPortals; - - // copy the connectivity database from sndPropLoader - if( (m_sndAreas = new SsndArea[m_numAreas]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when copying area connectivity database to gameplay object\r"); - goto Quit; - } - - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Attempting to copy m_PortData with %d portals\r", m_numPortals); - // copy the handle-indexed portal data from sndPropLoader - if( (m_PortData = new SPortData[m_numPortals]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when copying portal data array to gameplay object\r"); - goto Quit; - } - - // copy the areas array, element by element - for( int i=0; i < m_numAreas; i++ ) - { - m_sndAreas[i].LossMult = in->m_sndAreas[i].LossMult; - m_sndAreas[i].VolMod = in->m_sndAreas[i].VolMod; - - tempint = in->m_sndAreas[i].numPortals; - m_sndAreas[i].numPortals = tempint; - - m_sndAreas[i].center = in->m_sndAreas[i].center; - - m_sndAreas[i].portals = new SsndPortal[ tempint ]; - for( int k=0; k < tempint; k++ ) - m_sndAreas[i].portals[k] = in->m_sndAreas[i].portals[k]; - - m_sndAreas[i].portalDists = new CMatRUT; - - // Copy the values - if (in->m_sndAreas[i].portalDists->size() > 0) - { - *m_sndAreas[i].portalDists = *(in->m_sndAreas[i].portalDists); - } - else - { - m_sndAreas[i].portalDists->Clear(); - } - } - - - // copy the portal data array, element by element - for( int k=0; k < m_numPortals; k++ ) - { - m_PortData[k].loss = in->m_PortData[k].loss; - - m_PortData[k].Areas[0] = in->m_PortData[k].Areas[0]; - m_PortData[k].Areas[1] = in->m_PortData[k].Areas[1]; - m_PortData[k].LocalIndex[0] = in->m_PortData[k].LocalIndex[0]; - m_PortData[k].LocalIndex[1] = in->m_PortData[k].LocalIndex[1]; - } - - m_bDefaultSpherical = in->m_bDefaultSpherical; - m_AreaPropsG = in->m_AreaPropsG; - - // initialize Event Areas - if( (m_EventAreas = new SEventArea[m_numAreas]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing m_EventAreas\r"); - goto Quit; - } - - // initialize Populated Areas - if( (m_PopAreas = new SPopArea[m_numAreas]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing m_PopAreas\r"); - goto Quit; - } - - // Initialize the timestamp in Populated Areas - - for ( int k=0; kbVisited = false; - - numPorts = m_sndAreas[j].numPortals; - - if( (pEvArea->PortalDat = new SPortEvent[ numPorts ]) - == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing portal data array for area %d in m_EventAreas\r", j); - goto Quit; - } - - // point the event portals to the m_sndAreas portals - for( int l=0; lPortalDat[l]; - pEvPtr->ThisPort = &m_sndAreas[j].portals[l]; - } - } - -Quit: - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Soundprop gameplay object finished loading\r"); - return; -} - -// NOTE: Propagate does not call CheckSound. CheckSound should be called before -// calling Propagate, in order to make sure the sound exists somewhere. - -void CsndProp::Propagate - ( float volMod, float durMod, const idStr& sndName, - idVec3 origin, idEntity *maker, - USprFlags *addFlags ) - -{ - bool bValidTeam(false), - bExpandFinished(false); - int mteam; - float range; - - UTeamMask tmask, compMask; - - idBounds envBounds(origin); - idAI *testAI; - idList validTypeEnts, validEnts; - SPopArea *pPopArea; - - idTimer timer_Prop; - timer_Prop.Clear(); - timer_Prop.Start(); - - m_TimeStampProp= gameLocal.time; - - if( cv_spr_debug.GetBool() ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PROPAGATING: From entity %s, sound \"%s\", volume modifier %f, duration modifier %f \r", maker->name.c_str(), sndName.c_str(), volMod, durMod ); - gameLocal.Printf("PROPAGATING: From entity %s, sound \"%s\", volume modifier %f, duration modifier %f \n", maker->name.c_str(), sndName.c_str(), volMod, durMod ); - } - - // clear the old populated areas list - m_PopAreasInd.Clear(); - - // grayman #2907 - Initialize the timestamp in Populated Areas. This - // becomes important if more than one sound propagates in the same frame. - - for ( int k = 0 ; k < m_numAreas ; k++ ) - { - m_PopAreas[k].addedTime = 0; - } - - // initialize the comparison team mask - compMask.m_field = 0; - - // find the dict def for the specific sound - const idDict* parms = gameLocal.FindEntityDefDict( va("sprGS_%s", sndName.c_str() ), false ); - - // redundancy, this is already checked in CheckSound() - if (!parms) return; - - float vol0 = parms->GetFloat("vol","0") + volMod; - - // add the area-specific volMod, if we're in an area - int areaNum = gameRenderWorld->PointInArea(origin); - vol0 += (areaNum >= 0) ? m_AreaPropsG[areaNum].VolMod : 0; - - // scale the volume by some amount that is a cvar for now for tweaking - // later we will put a permananet value in the def for globals->Vol - vol0 += cv_ai_sndvol.GetFloat(); - - if (cv_moveable_collision.GetBool() && maker->IsType(idMoveable::Type)) - { - gameRenderWorld->DrawText( va("PropVol: %f", vol0), maker->GetPhysics()->GetOrigin(), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); - } - - SSprParms propParms; - propParms.name = sndName; - propParms.alertFactor = parms->GetFloat("alert_factor","1"); - propParms.alertMax = parms->GetFloat("alert_max","30"); - - // set team alert and propagation flags from the parms - SetupParms( parms, &propParms, addFlags, &tmask ); - - propParms.duration *= durMod; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found modified duration %f\r", propParms.duration); - propParms.maker = maker; - propParms.makerAI = (maker->IsType(idAI::Type)) ? static_cast(maker) : NULL; - propParms.origin = origin; - - // For objects (non-actors) the team will be set to -1 - mteam = (maker->IsType(idActor::Type)) ? static_cast(maker)->team : -1; - - // Calculate the range, assuming peceived loudness of a sound doubles every 7 dB - // (we want to overestimate a bit. With the current settings, cutoff for a footstep - // at 50dB is ~15 meters ( ~45 ft ) - - // keep in mind that due to FOV compression, visual distances in FPS look shorter - // than they actually are. - - range = pow(2.0f, ((vol0 - m_SndGlobals.MaxRangeCalVol) / 7.0f) ) * m_SndGlobals.MaxRange * s_METERS_TO_DOOM; - - if( cv_spr_debug.GetBool() ) - gameLocal.Printf("Propagation volume: %0.02f Range: %0.02f units (%0.02f m)\n", vol0, range, range / s_METERS_TO_DOOM); - - // Debug drawing of the range - if (cv_spr_radius_show.GetBool()) - { - gameRenderWorld->DebugCircle(colorWhite, origin, idVec3(0,0,1), range, 100, 1000); - } - - idBounds bounds(origin); - bounds.ExpandSelf(range); - - // get a list of all ents with type idAI's or Listeners - - for (idAI* ai = gameLocal.spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) - { - // TODO: Put in Listeners later - validTypeEnts.Append(ai); - } - - if( cv_spr_debug.GetBool() ) - { - gameLocal.Printf("Found %d ents with valid type for propagation\n", validTypeEnts.Num() ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found %d ents with valid type for propagation\r", validTypeEnts.Num() ); - } - - timer_Prop.Stop(); - DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished finding all AI entities, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); - timer_Prop.Start(); - // cull the list by testing distance and valid team flag - - for ( int i=0; i( validTypeEnts[i] ); - - // do not propagate to dead or unconscious AI - if( testAI->health <= 0 || testAI->IsKnockedOut() ) - continue; - - if( !bounds.ContainsPoint( testAI->GetEyePosition() ) ) - { - if( cv_spr_debug.GetBool() ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s is not within propagation cutoff range %f\r", testAI->name.c_str(), range ); - gameLocal.Printf("AI %s is not within propagation cutoff range %0.2f\n", testAI->name.c_str(), range ); - } - continue; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s is within propagation cutoff range %f\r", testAI->name.c_str(), range ); - - if( mteam == -1 ) - { - // for now, inanimate objects alert everyone - bValidTeam = true; - if( cv_spr_debug.GetBool() ) - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound was propagated from inanimate object: Alerts all teams\r" ); - } - else - { - compMask.m_bits.same = ( testAI->team == mteam ); - compMask.m_bits.friendly = testAI->IsFriend(maker); - compMask.m_bits.neutral = testAI->IsNeutral(maker); - compMask.m_bits.enemy = testAI->IsEnemy(maker); - - // do the comparison - if ( tmask.m_field & compMask.m_field ) - { - bValidTeam = true; - if( cv_spr_debug.GetBool() ) - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s has a valid team for soundprop\r", testAI->name.c_str() ); - } - } - - // TODO : Add another else if for the case of Listeners - - // don't alert the AI that caused the sound - if( bValidTeam && testAI != maker ) - { - if( cv_spr_debug.GetBool() ) - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found a valid propagation target: %s\r", testAI->name.c_str() ); - validEnts.Append( validTypeEnts[i] ); - continue; - } - if( cv_spr_debug.GetBool() ) - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s does not have a valid team for propagation\r", testAI->name.c_str() ); - - } - - timer_Prop.Stop(); - DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished culling AI list, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); - timer_Prop.Start(); - - /* handle environmental sounds here - - envBounds = bounds; - envBounds.Expand( s_MAX_ENV_SNDRANGE * s_METERS_TO_DOOM); - - envBounds -= bounds; - - numEnt = gameLocal.clip.EntitiesTouchingBounds( envBounds, -1, inrangeEnts2, MAX_ENTS ); - - for( int j =0; j < numEnt; j++) - { - // if the entities are in the env. sound hash - // add them to the list of env. sounds to check for this propagation - } - */ - - // Don't bother propagation if no one is in range - if (validEnts.Num() == 0) return; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Beginning propagation to %d targets\r", validEnts.Num() ); - - - // ======================== BEGIN WAVEFRONT EXPANSION =================== - - // Populate the AI lists in the m_PopAreas array, use timestamp method to check if it's the first visit - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Filling populated areas array with AI\r" ); - for(int j = 0; j < validEnts.Num(); j++) - { - int AIAreaNum = gameRenderWorld->PointInArea( validEnts[j]->GetPhysics()->GetOrigin() ); - - //Sometimes PointInArea returns -1, don't know why - if (AIAreaNum < 0) - continue; - - pPopArea = &m_PopAreas[AIAreaNum]; - - if( pPopArea == NULL ) - continue; - - //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("TimeStamp Debug: Area timestamp %d, new timestamp %d \r", pPopArea->addedTime, m_TimeStampProp); - - // check if this is the first update to the pop. area in this propagation - if( pPopArea->addedTime != m_TimeStampProp ) - { - //update the timestamp - pPopArea->addedTime = m_TimeStampProp; - - pPopArea->bVisited = false; - pPopArea->AIContents.Clear(); - pPopArea->VisitedPorts.Clear(); - - // add the first AI to the contents list - idEntityPtr ai; - ai = static_cast(validEnts[j]); - pPopArea->AIContents.Append(ai); - - // append the index of this area to the popAreasInd list for later processing - m_PopAreasInd.Append( AIAreaNum ); - } - else - { - // This area has already been updated in this propagation, just add the next AI - idEntityPtr ai; - ai = static_cast(validEnts[j]); - pPopArea->AIContents.Append(ai); - } - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processed AI %s in area %d\r", validEnts[j]->name.c_str(), AIAreaNum ); - } - - timer_Prop.Stop(); - DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished filling populated areas, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); - timer_Prop.Start(); - - bExpandFinished = ExpandWave( vol0, origin ); - - //TODO: If bExpandFinished == false, either fake propagation or - // delay further expansion until later frame - if(bExpandFinished == false) - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion was stopped when max node number %d was exceeded, or propagation was aborted\r", s_MAX_FLOODNODES ); - - timer_Prop.Stop(); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion done, processing AI\r" ); - DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: COMPTIME=%lf [ms]\r", timer_Prop.Milliseconds() ); - timer_Prop.Start(); - - ProcessPopulated( vol0, origin, &propParms ); - - timer_Prop.Stop(); - DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Total TIME for propagation: %lf [ms]\r", timer_Prop.Milliseconds() ); -} - -void CsndProp::SetupParms( const idDict *parms, SSprParms *propParms, USprFlags *addFlags, UTeamMask *tmask ) -{ - USprFlags tempflags; - - tempflags.m_field = 0; - tmask->m_field = 0; - - DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Parsing team alert and propagation flags from propagated_sounds.def\r"); - - // note: by default, if the key is not found, GetBool returns false - tempflags.m_bits.same = parms->GetBool("prop_to_same"); - tempflags.m_bits.friendly = parms->GetBool("prop_to_friend"); - tempflags.m_bits.neutral = parms->GetBool("prop_to_neutral"); - tempflags.m_bits.enemy = parms->GetBool("prop_to_enemy", "1"); - - tempflags.m_bits.omni_dir = parms->GetBool("omnidir"); - tempflags.m_bits.unique_loc = parms->GetBool("unique_loc"); - tempflags.m_bits.urgent = parms->GetBool("urgent"); - tempflags.m_bits.global_vol = parms->GetBool("global_vol"); - tempflags.m_bits.check_touched = parms->GetBool("check_touched"); - - if( addFlags ) - { - tempflags.m_field = tempflags.m_field | addFlags->m_field; - if( cv_spr_debug.GetBool() ) - DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Added additional sound propagation flags from local sound \r"); - } - - // set the team mask from the sprflags - tmask->m_bits.same = tempflags.m_bits.same; - tmask->m_bits.friendly = tempflags.m_bits.friendly; - tmask->m_bits.neutral = tempflags.m_bits.neutral; - tmask->m_bits.enemy = tempflags.m_bits.enemy; - - // copy flags to parms - propParms->flags = tempflags; - - // setup other parms - propParms->duration = parms->GetFloat("dur","200"); - propParms->frequency = parms->GetInt("freq","-1"); - propParms->bandwidth = parms->GetFloat("width", "-1"); - - if( cv_spr_debug.GetBool() ) - { - DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Finished transfering sound prop parms\r"); - } -} - -bool CsndProp::CheckSound( const char *sndNameGlobal, bool isEnv ) -{ - const idDict *parms; - bool returnval; - - if (isEnv) - parms = gameLocal.FindEntityDefDict( va("sprGE_%s", sndNameGlobal ), false ); - else - parms = gameLocal.FindEntityDefDict( va("sprGS_%s", sndNameGlobal ), false ); - - if ( !parms ) - { - // Don't log this, because it happens all the time. Most sounds played with idEntity::StartSound are not propagated. - //if( cv_spr_debug.GetBool() ) - //gameLocal.Warning("[Soundprop] Could not find sound def for sound \"%s\" Sound not propagated.", sndNameGlobal ); - //DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Could not find sound def for sound \"%s\" Sound not propagated.\r", sndNameGlobal ); - returnval = false; - goto Quit; - } - - else - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found propagated sound \"%s\" in the def.\r", sndNameGlobal ); - returnval = true; - } - -Quit: - return returnval; -} - -bool CsndProp::ExpandWave(float volInit, idVec3 origin) -{ - bool returnval; - int //popIndex(-1), - floods(1), nodes(0), area, LocalPort; - float tempDist(0), tempAtt(1), tempLoss(0), AddedDist(0); - idList NextAreas; // expansion queue - idList AddedAreas; // temp storage for next expansion queue - SExpQue tempQEntry; - SPortEvent *pPortEv; // pointer to portal event data - SPopArea *pPopArea; // pointer to populated area data - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting wavefront expansion\r" ); - - // clear the visited settings on m_EventAreas from previous propagations - for(int i=0; i < m_numAreas; i++) - m_EventAreas[i].bVisited = false; - - NextAreas.Clear(); - AddedAreas.Clear(); - - - // ======================== Handle the initial area ========================= - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing initial area\r" ); - - int initArea = gameRenderWorld->PointInArea( origin ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound origin is in portal area: %d\r", initArea ); - if( initArea == -1 ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound origin is outside the map, aborting propagation.\r" ); - return false; - } - - m_EventAreas[ initArea ].bVisited = true; - - // Update m_PopAreas to show that the area has been visited - m_PopAreas[ initArea ].bVisited = true; - - // array index pointers to save on calculation - SsndArea *pSndAreas = &m_sndAreas[ initArea ]; - SEventArea *pEventAreas = &m_EventAreas[ initArea ]; - - // calculate initial portal losses from the sound origin point - for( int i2=0; i2 < pSndAreas->numPortals; i2++) - { - idVec3 portalCoord = pSndAreas->portals[i2].center; - tempDist = (origin - portalCoord).LengthFast() * s_DOOM_TO_METERS; - - // calculate and set initial portal losses - tempAtt = m_AreaPropsG[ initArea ].LossMult * tempDist; - - // add the door loss - tempAtt += m_PortData[ pSndAreas->portals[i2].handle - 1 ].loss; - - // get the current loss - tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; - - pPortEv = &pEventAreas->PortalDat[i2]; - - pPortEv->Loss = tempLoss; - pPortEv->Dist = tempDist; - pPortEv->Att = tempAtt; - pPortEv->Floods = 1; - pPortEv->PrevPort = NULL; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Loss at portal %d is %f [dB]\r", i2, tempLoss); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist at portal %d is %f [m]\r", i2, tempDist); - - - // add the portal destination to flooding queue if the sound has - // not dropped below threshold at the portal - if( (volInit - tempLoss) > s_MIN_AUD_THRESH ) - { - tempQEntry.area = pSndAreas->portals[i2].to; - tempQEntry.curDist = tempDist; - tempQEntry.curAtt = tempAtt; - tempQEntry.curLoss = tempLoss; - tempQEntry.portalH = pSndAreas->portals[i2].handle; - tempQEntry.PrevPort = NULL; - - NextAreas.Append( tempQEntry ); - } - else - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Wavefront intensity dropped below threshold at portal %d\r", i2); - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting main loop\r" ); - - -// done with initial area, begin main loop - - while( NextAreas.Num() > 0 && nodes < s_MAX_FLOODNODES ) - { - floods++; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion loop, iteration %d\r", floods); - - AddedAreas.Clear(); - - for(int j=0; j < NextAreas.Num(); j++) - { - nodes++; - - area = NextAreas[j].area; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Flooding area %d thru portal handle %d\r", area, NextAreas[j].portalH); - - // array index pointers to save on calculation - pSndAreas = &m_sndAreas[ area ]; - pEventAreas = &m_EventAreas[ area ]; - pPopArea = &m_PopAreas[area]; - - // find the local portal number in area for the portal handle - int portHandle = NextAreas[j].portalH; - - SPortData *pPortData = &m_PortData[ portHandle - 1 ]; - if( pPortData->Areas[0] == area ) - LocalPort = pPortData->LocalIndex[0]; - else - LocalPort = pPortData->LocalIndex[1]; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Identified local portal index %d\r", LocalPort ); - - pPortEv = &pEventAreas->PortalDat[ LocalPort ]; - - // copy information from the portal's other side - pPortEv->Dist = NextAreas[j].curDist; - pPortEv->Att = NextAreas[j].curAtt; - pPortEv->Loss = NextAreas[j].curLoss; - pPortEv->Floods = floods - 1; - pPortEv->PrevPort = NextAreas[j].PrevPort; - - - // Updated the Populated Areas to show that it's been visited - // Only do this for populated areas that matter (ie, they've been updated - // on this propagation - - if ( pPopArea->addedTime == m_TimeStampProp ) - { - pPopArea->bVisited = true; - // note the portal flooded in on for later processing - pPopArea->VisitedPorts.AddUnique( LocalPort ); - } - - // Flood to portals in this area - for( int i=0; i < pSndAreas->numPortals; i++) - { - // do not flood back thru same portal we came in - if( LocalPort == i) - continue; - - // set up the portal event pointer - pPortEv = &pEventAreas->PortalDat[i]; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d to portal %d in area %d\r", LocalPort, i, area); - - // Obtain loss at this portal and store in temp var - tempDist = NextAreas[j].curDist; - AddedDist = pSndAreas->portalDists->GetRev( LocalPort, i ); - tempDist += AddedDist; - - tempAtt = NextAreas[j].curAtt; - tempAtt += AddedDist * m_AreaPropsG[ area ].LossMult; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Total distance now %f\r", tempDist ); - - // add any specific loss on the portal - tempAtt += m_PortData[ pSndAreas->portals[i].handle - 1 ].loss; - - tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; - - // check if we've visited the area, and do not add destination area - // if loss is greater this time - if( pEventAreas->bVisited - && tempLoss >= pPortEv->Loss ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Cancelling flood thru portal %d in previously visited area %d\r", i, area); - continue; - } - - if( ( volInit - tempLoss ) < s_MIN_AUD_THRESH ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Wavefront intensity dropped below abs min audibility at portal %d in area %d\r", i, area); - continue; - } - - // path has been determined to be minimal loss, above cutoff intensity - // store the loss value - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Further expansion valid thru portal %d in area %d\r", i, area); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Set loss at portal %d to %f [dB]\r", i, tempLoss); - - pPortEv->Loss = tempLoss; - pPortEv->Dist = tempDist; - pPortEv->Att = tempAtt; - pPortEv->Floods = floods; - pPortEv->PrevPort = &pEventAreas->PortalDat[ LocalPort ]; - - // add the portal destination to flooding queue - tempQEntry.area = pSndAreas->portals[i].to; - tempQEntry.curDist = tempDist; - tempQEntry.curAtt = tempAtt; - tempQEntry.curLoss = tempLoss; - tempQEntry.portalH = pSndAreas->portals[i].handle; - tempQEntry.PrevPort = pPortEv->PrevPort; - - AddedAreas.Append( tempQEntry ); - - } // end portal flood loop - - m_EventAreas[area].bVisited = true; - } // end area flood loop - - // create the next expansion queue - NextAreas = AddedAreas; - - } // end main loop - - // return true if the expansion died out naturally rather than being stopped - returnval = ( !NextAreas.Num() ); - - return returnval; -} // end function - -void CsndProp::ProcessPopulated( float volInit, idVec3 origin, SSprParms *propParms ) -{ - float LeastLoss, TestLoss, tempDist, tempAtt, tempLoss; - int LoudPort(0), portNum; - idVec3 testLoc; - SPortEvent *pPortEv; - SPopArea *pPopArea; - idList showPoints; - - int initArea = gameRenderWorld->PointInArea( origin ); - - for( int i=0; i < m_PopAreasInd.Num(); i++ ) - { - int area = m_PopAreasInd[i]; - - pPopArea = &m_PopAreas[area]; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing pop. area %d\r", area); - - // Special case: AI area = initial area - no portal flooded in on in this case - if( area == initArea ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Special case: AI in initial area %d\r", area); - - propParms->bSameArea = true; - propParms->direction = origin; - - for(int j=0; j < pPopArea->AIContents.Num(); j++) - { - idAI* ai = pPopArea->AIContents[j].GetEntity(); - - if (ai == NULL) - continue; - - tempDist = (origin - ai->GetEyePosition()).LengthFast() * s_DOOM_TO_METERS; - tempAtt = tempDist * m_AreaPropsG[ area ].LossMult; - tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; - - propParms->propVol = volInit - tempLoss; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in (source area) area %d\r", ai->name.c_str(), area); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist to AI: %f [m], Propagated volume found to be %f [dB]\r", tempDist, propParms->propVol); - - ProcessAI( ai, origin, propParms ); - - // draw debug lines if show soundprop cvar is set - if( cv_spr_show.GetBool() ) - { - showPoints.Clear(); - showPoints.Append( ai->GetEyePosition() ); - showPoints.Append( propParms->origin ); - DrawLines(showPoints); - } - } - } - // Normal propagation to a surrounding area - else if ( pPopArea->bVisited == true ) - { - propParms->bSameArea = false; - - // figure out the least loss portal - // May be different for each AI (esp. in large rooms) - // TODO OPTIMIZATION: Don't do this extra loop for each AI if - // we only visited one portal in the area - - for( int aiNum = 0; aiNum < pPopArea->AIContents.Num(); aiNum++ ) - { - idAI* ai = pPopArea->AIContents[ aiNum ].GetEntity(); - - if (ai == NULL) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("NULL AI pointer for AI %d in area %d\r", aiNum, area); - continue; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating least loss for AI %s in area %d\r", ai->name.c_str(), area); - - LeastLoss = idMath::INFINITY; - - for(int k=0; k < pPopArea->VisitedPorts.Num(); k++ ) - { - portNum = pPopArea->VisitedPorts[ k ]; - pPortEv = &m_EventAreas[area].PortalDat[ portNum ]; - - //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d, DEBUG k=%d, portsnum = %d\r", portNum, k, m_PopAreas[i].VisitedPorts.Num()); - - testLoc = m_sndAreas[area].portals[portNum].center; - - tempDist = (testLoc - ai->GetEyePosition()).LengthFast() * s_DOOM_TO_METERS; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Distance to AI = %f [m]\r", tempDist); - - tempAtt = tempDist * m_AreaPropsG[ area ].LossMult; - tempDist += pPortEv->Dist; - tempAtt += pPortEv->Att; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Portal %d has total Dist = %f [m]\r", portNum, tempDist); - - // add loss from portal to AI to total loss at portal - TestLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Portal %d has total Loss = %f [dB]\r", portNum, TestLoss); - - if( TestLoss < LeastLoss ) - { - LeastLoss = TestLoss; - LoudPort = portNum; - } - } - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Portal %d has least loss %f [dB]\r", LoudPort, LeastLoss ); - - pPortEv = &m_EventAreas[area].PortalDat[ LoudPort ]; - propParms->floods = pPortEv->Floods; - - // Detailed Path Minimization: - - // check if AI is within the flood range for detailed path minimization - if( pPortEv->Floods <= s_MAX_DETAILNODES ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting detailed path minimization for portal %d\r", LoudPort ); - propParms->bDetailedPath = true; - - // call detailed path minimization, which writes results to propParms - DetailedMin( ai, propParms, pPortEv, area, volInit ); - - // message the AI - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated volume found to be %f\r", propParms->propVol); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in area %d\r", ai->name.c_str(), area); - - ProcessAI( ai, origin, propParms ); - - continue; - } - - propParms->bDetailedPath = false; - propParms->direction = m_sndAreas[area].portals[ LoudPort ].center; - propParms->propVol = volInit - LeastLoss; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated volume found to be %f\r", propParms->propVol); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in area %d\r", ai->name.c_str(), area); - ProcessAI( ai, origin, propParms ); - } - } - // Propagation was stopped before this area was reached - else if ( pPopArea->bVisited == false ) - { - // Do nothing for now - // TODO: Keep track of these areas for delayed calculation? - } - } - - // greebo: We're done propagating, clear the message list of the issuing AI, if appropriate - if (propParms->makerAI != NULL) - { - propParms->makerAI->ClearMessages(); - } -} - -void CsndProp::ProcessAI(idAI* ai, idVec3 origin, SSprParms *propParms) -{ - if( ai == NULL ) return; - - // check AI hearing, get environmental noise, etc - if( cv_spr_debug.GetBool() ) - { - gameLocal.Printf("Propagated sound %s to AI %s, from origin %s : Propagated volume %f, Apparent origin of sound: %s \r", - propParms->name.c_str(), ai->name.c_str(), origin.ToString(), propParms->propVol, propParms->direction.ToString() ); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated sound %s to AI %s, from origin %s : Propagated volume %f, Apparent origin of sound: %s \r", - propParms->name.c_str(), ai->name.c_str(), origin.ToString(), propParms->propVol, propParms->direction.ToString() ); - } - - if( cv_spr_show.GetBool() ) - { - gameRenderWorld->DrawText( va("Volume: %.2f", propParms->propVol), - (ai->GetEyePosition() - ai->GetPhysics()->GetGravityNormal() * 65.0f), 0.25f, - colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec * 30); - } - - // convert the SPL to loudness and store it in parms - ai->SPLtoLoudness( propParms ); - - if (ai->CheckHearing(propParms)) - { - // TODO: Add env. sound masking check here - // GetEnvNoise should check all the env. noises on the list we made, plus global ones - - // noiseVol = GetEnvNoise( &propParms, origin, AI->GetEyePosition() ); - float noise = 0; - - //message the AI - ai->HearSound( propParms, noise, origin ); - } -} - -/** -* CsndProp::OptSurfPoint -* PSUEDOCODE -* -* 1. Define the surface coordinates by taking vectors to two consecutive -* points in the winding. -* -* 2. Obtain intersection point with winding plane. -* 2.A Test if this point is within the rectangle. If so, we're done. (goto Quit) -* -* 3. Obtain a1 and a2, the coordinates when line is resolved onto the axes -* -* 4. Test sign of a1 and a2 to determine which edge they should intersect -* write the lower numbered point of the intersection edge to edgeNum -* -* -* 5. Find the point along the edge closest to point A -* -Find line that goes thru point isect, and is also perpendicular to the edge -* -* 6. Return this point in world coordinates, we're done. -**/ -idVec3 CsndProp::OptSurfPoint( idVec3 p1, idVec3 p2, const idWinding& wind, idVec3 WCenter ) -{ - idVec3 line, u1, u2, v1, v2, edge, isect, lineSect; - idVec3 returnVec, tempVec, pointA; - idPlane WPlane; - float lenV1, lenV2, lineU1, lineU2, Scale(0), frac; - int edgeStart(0), edgeStop(0); - - // If the winding is not a rectangle, just return the center coordinate - if( wind.GetNumPoints() != 4 ) - { - returnVec = WCenter; - goto Quit; - } - - // Want to find a point on the portal rectangle closest to this line: - line = p2 - p1; - - // define the portal coordinates and extent of the two corners - u1 = (wind[0].ToVec3() - WCenter); - u2 = (wind[1].ToVec3() - WCenter); - u1.NormalizeFast(); - u2.NormalizeFast(); - - // define other coordinates going to midpoint between two points (useful to see if point is on portal) - v1 = (wind[1].ToVec3() + wind[0].ToVec3()) / 2 - WCenter; - v2 = (wind[2].ToVec3() + wind[1].ToVec3()) / 2 - WCenter; - lenV1 = v1.LengthFast(); - lenV2 = v2.LengthFast(); - - wind.GetPlane(WPlane); - - tempVec = p2-p1; - tempVec.NormalizeFast(); - - // find ray intersection point, in terms of p1 + (p2-p1)*Scale - WPlane.RayIntersection( p1, tempVec, Scale ); - - isect = p1 + Scale * tempVec; - lineSect = isect - WCenter; - - if( cv_spr_show.GetBool() ) - { - gameRenderWorld->DebugLine( colorRed, WCenter, (wind[1].ToVec3() + wind[0].ToVec3()) / 2, 3000); - gameRenderWorld->DebugLine( colorRed, WCenter, (wind[2].ToVec3() + wind[1].ToVec3()) / 2, 3000); - //gameRenderWorld->DebugLine( colorYellow, WCenter, isect, 3000); - } - - // resolve into surface coordinates - lineU1 = lineSect * u1; - lineU2 = lineSect * u2; - - // If point is within the rectangular surface boundaries, we're done - // Use the v axes (going to edge midpoints) to check if point is within rectangle - if( fabs(lineSect * v1/lenV1) <= lenV1 && fabs( lineSect * v2/lenV2) <= lenV2 ) - { -// DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MinSurf: Line itersects inside portal surface\r" ); -// DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("v1/lenV1 = %f, v2/lenV2 = %f\r", fabs(lineSect * v1/lenV1)/lenV1, fabs( lineSect * v2/lenV2)/lenV2 ); - returnVec = isect; - goto Quit; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MinSurf: Line intersected outside of portal\r"); - // find the edge that the line intersects - if( lineU1 >= 0 && lineU2 >= 0 ) - { - edgeStart = 0; - edgeStop = 1; - } - else if( lineU1 <= 0 && lineU2 >= 0 ) - { - edgeStart = 1; - edgeStop = 2; - } - else if( lineU1 <= 0 && lineU2 <= 0 ) - { - edgeStart = 2; - edgeStop = 3; - } - else if( lineU1 >= 0 && lineU2 <= 0 ) - { - edgeStart = 3; - edgeStop = 0; - } - - pointA = wind[edgeStart].ToVec3(); - edge = wind[edgeStop].ToVec3() - pointA; - - // Find the closest point on the edge to the isect point - // This is the point we're looking for - frac = ((isect - pointA) * edge )/ edge.LengthSqr(); - - // check if the point is outside the actual edge, if not, set it to - // the appropriate endpoint. - if( frac < 0 ) - returnVec = pointA; - else if( frac > 1.0 ) - returnVec = pointA + edge; - else - returnVec = pointA + frac * edge; - -Quit: - return returnVec; -} - -void CsndProp::DetailedMin( idAI* AI, SSprParms *propParms, SPortEvent *pPortEv, int AIArea, float volInit ) -{ - idList pathPoints; // pathpoints[0] = closest path point to the TARGET - idList PortPtrs; // pointers to the portals along the path - idVec3 point, p1, p2, AIpos; - int floods, curArea; - float tempAtt, tempDist, totAtt, totDist, totLoss; - SPortEvent *pPortTest; - SsndPortal *pPort2nd; - - floods = pPortEv->Floods; - pPortTest = pPortEv; - - AIpos = AI->GetEyePosition(); - p1 = AIpos; - - - // first iteration, populate pathPoints going "backwards" from target to source - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Performing first iteration for %d floods\r", floods ); - - for( int i = 0; i < floods; i++ ) - { - if( pPortEv->ThisPort == NULL) - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("ERROR: pPortEv->ThisPort is NULL\r" ); - - // calculate optimum point for this leg of the path - point = OptSurfPoint( p1, propParms->origin, *pPortTest->ThisPort->winding, - pPortTest->ThisPort->center ); - - pathPoints.Append(point); - PortPtrs.Append(pPortTest); - - p1 = point; - pPortTest = pPortTest->PrevPort; - } - - // check if we have enough floods to perform the 2nd iteration - if( (floods - 2) < 0 ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Skipping second iteration, not enough portals\r" ); - goto Quit; - } - - // second iteration, going forwards from source to target - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Performing second iteration\r" ); - - - p1 = propParms->origin; - - for( int k = 0; k < floods; k++ ) - { - // recalculate the N-1th point using the Nth point and N-2th point on either side - pPort2nd = PortPtrs[floods - k - 1]->ThisPort; - if( pPort2nd == NULL) - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("ERROR: pPort2nd is NULL\r" ); - - // the last point tested must be the AI position - if( (floods - k - 2) >= 0 ) - p2 = pathPoints[floods - k - 2]; - else - p2 = AIpos; - - // DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("2nd iter: Finding optimum surface point\r" ); - point = OptSurfPoint( p1, p2, *pPort2nd->winding, pPort2nd->center ); - pathPoints[floods - k -1] = point; - - p1 = point; - } - -Quit: - -// Now go through and calculate the new loss - - // get loss to 1st point on the path - totDist = (AIpos - pathPoints[0]).LengthFast() * s_DOOM_TO_METERS; - curArea = PortPtrs[0]->ThisPort->to; - totAtt = totDist * m_AreaPropsG[ curArea ].LossMult; - - totAtt += PortPtrs[0]->Att; - - // add the rest of the loss from the path points - for( int j = 0; j < (floods - 1); j++ ) - { - tempDist = (pathPoints[j+1] - pathPoints[j]).LengthFast() * s_DOOM_TO_METERS; - curArea = PortPtrs[j]->ThisPort->to; - tempAtt = tempDist * m_AreaPropsG[ curArea ].LossMult; - - totDist += tempDist; - totAtt += tempAtt; - - totAtt += PortPtrs[j + 1]->Att; - } - - // add the loss from the final path point to the source - tempDist = ( pathPoints[floods - 1] - propParms->origin ).LengthFast() * s_DOOM_TO_METERS; - curArea = PortPtrs[ floods - 1 ]->ThisPort->to; - tempAtt = tempDist * m_AreaPropsG[ curArea ].LossMult; - - totDist += tempDist; - totAtt += tempAtt; - - // Finally, convert to acoustic spreading + attenuation loss in dB - totLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(totDist) + totAtt + 8; - - propParms->direction = pathPoints[0]; - propParms->propVol = volInit - totLoss; - - // draw debug lines if show soundprop cvar is set - if( cv_spr_show.GetBool() ) - { - pathPoints.Insert(AIpos, 0); - pathPoints.Append(propParms->origin); - DrawLines(pathPoints); - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Detailed path minimization for AI %s finished\r", AI->name.c_str() ); - - return; -} - -void CsndProp::DrawLines(idList& pointlist) -{ - for (int i = 0; i < (pointlist.Num() - 1); i++) - { - gameRenderWorld->DebugLine( colorGreen, pointlist[i], pointlist[i+1], 3000); - } -} - -void CsndProp::SetPortalLoss( int handle, float value ) -{ - CsndPropBase::SetPortalLoss( handle, value ); - - // update the portal loss info timestamp - m_TimeStampPortLoss = gameLocal.time; -} - -bool CsndProp::ExpandWaveFast( float volInit, idVec3 origin, float MaxDist, int MaxFloods ) -{ - bool bDistLimit(false); - int //popIndex(-1), - floods(1), nodes(0), area, LocalPort, FloodLimit; - float tempDist(0), tempAtt(1), AddedDist(0); - idList NextAreas; // expansion queue - idList AddedAreas; // temp storage for next expansion queue - SExpQue tempQEntry; - SPortEvent *pPortEv; // pointer to portal event data - SPopArea *pPopArea; // pointer to populated area data - - if( MaxDist != -1 ) - bDistLimit = true; - - if( MaxFloods == -1 ) - FloodLimit = s_MAX_FLOODNODES; - else - FloodLimit = MaxFloods; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting wavefront expansion (fast), DistLimit = %f, NodeLimit = %d\r", MaxDist, FloodLimit ); - - // clear the visited settings on m_EventAreas from previous propagations - for(int i=0; i < m_numAreas; i++) - m_EventAreas[i].bVisited = false; - - NextAreas.Clear(); - AddedAreas.Clear(); - - - // ======================== Handle the initial area ========================= - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing initial area\r" ); - - int initArea = gameRenderWorld->PointInArea( origin ); - - m_EventAreas[ initArea ].bVisited = true; - - // Update m_PopAreas to show that the area has been visited - m_PopAreas[ initArea ].bVisited = true; - - // array index pointers to save on calculation - SsndArea *pSndAreas = &m_sndAreas[ initArea ]; - SEventArea *pEventAreas = &m_EventAreas[ initArea ]; - - // calculate initial portal losses from the sound origin point - for( int i2=0; i2 < pSndAreas->numPortals; i2++) - { - idVec3 portalCoord = pSndAreas->portals[i2].center; - - tempDist = (origin - portalCoord).LengthFast() * s_DOOM_TO_METERS; - // calculate and set initial portal losses - tempAtt = m_AreaPropsG[ initArea ].LossMult * tempDist; - - // add the door loss - tempAtt += m_PortData[ pSndAreas->portals[i2].handle - 1 ].loss; - - pPortEv = &pEventAreas->PortalDat[i2]; - - pPortEv->Dist = tempDist; - pPortEv->Att = tempAtt; - pPortEv->Floods = 1; - pPortEv->PrevPort = NULL; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist at portal %d is %f [m]\r", i2, tempDist); - - - // add the portal destination to flooding queue if the sound has - // not dropped below threshold at the portal - if( !bDistLimit || tempDist < MaxDist ) - { - tempQEntry.area = pSndAreas->portals[i2].to; - tempQEntry.curDist = tempDist; - tempQEntry.curAtt = tempAtt; - tempQEntry.portalH = pSndAreas->portals[i2].handle; - tempQEntry.PrevPort = NULL; - tempQEntry.curLoss = 0.0f; // greebo: Initialised to 0.0f to fix gcc warning - - NextAreas.Append( tempQEntry ); - } - else - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Distance rose above max distance at portal %d\r", i2); - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting main loop\r" ); - - -// done with initial area, begin main loop - - while( NextAreas.Num() > 0 && ( (floods < FloodLimit) ) ) - { - floods++; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion loop, iteration %d\r", floods); - - AddedAreas.Clear(); - - for(int j=0; j < NextAreas.Num(); j++) - { - nodes++; - - area = NextAreas[j].area; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Flooding area %d thru portal handle %d\r", area, NextAreas[j].portalH); - - // array index pointers to save on calculation - pSndAreas = &m_sndAreas[ area ]; - pEventAreas = &m_EventAreas[ area ]; - pPopArea = &m_PopAreas[area]; - - // find the local portal number in area for the portal handle - int portHandle = NextAreas[j].portalH; - - SPortData *pPortData = &m_PortData[ portHandle - 1 ]; - if( pPortData->Areas[0] == area ) - LocalPort = pPortData->LocalIndex[0]; - else - LocalPort = pPortData->LocalIndex[1]; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Identified local portal index %d\r", LocalPort ); - - pPortEv = &pEventAreas->PortalDat[ LocalPort ]; - - // copy information from the portal's other side - pPortEv->Dist = NextAreas[j].curDist; - pPortEv->Att = NextAreas[j].curAtt; - pPortEv->Floods = floods - 1; - pPortEv->PrevPort = NextAreas[j].PrevPort; - - - // Updated the Populated Areas to show that it's been visited - // Only do this for populated areas that matter (ie, they've been updated - // on this propagation - - if ( pPopArea->addedTime == m_TimeStampProp ) - { - pPopArea->bVisited = true; - // note the portal flooded in on for later processing - pPopArea->VisitedPorts.Append( LocalPort ); - } - - // Flood to portals in this area - for( int i=0; i < pSndAreas->numPortals; i++) - { - // do not flood back thru same portal we came in - if( LocalPort == i) - continue; - - // set up the portal event pointer - pPortEv = &pEventAreas->PortalDat[i]; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d to portal %d in area %d\r", LocalPort, i, area); - - // Obtain loss at this portal and store in temp var - tempDist = NextAreas[j].curDist; - AddedDist = pSndAreas->portalDists->GetRev( LocalPort, i ); - tempDist += AddedDist; - - tempAtt = NextAreas[j].curAtt; - tempAtt += AddedDist * m_AreaPropsG[ area ].LossMult; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Total distance now %f\r", tempDist ); - - // add any specific loss on the portal - tempAtt += m_PortData[ pSndAreas->portals[i].handle - 1 ].loss; - - // check if we've visited the area. Fast prop only visits an area once - if( pEventAreas->bVisited ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Cancelling flood thru portal %d in previously visited area %d\r", i, area); - continue; - } - - if( bDistLimit && tempDist > MaxDist ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Distance rose above max distance at portal %d in area %d\r", i, area); - continue; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Further expansion valid thru portal %d in area %d\r", i, area); - - pPortEv->Dist = tempDist; - pPortEv->Att = tempAtt; - pPortEv->Floods = floods; - pPortEv->PrevPort = &pEventAreas->PortalDat[ LocalPort ]; - - // add the portal destination to flooding queue - tempQEntry.area = pSndAreas->portals[i].to; - tempQEntry.curDist = tempDist; - tempQEntry.curAtt = tempAtt; - tempQEntry.portalH = pSndAreas->portals[i].handle; - tempQEntry.PrevPort = pPortEv->PrevPort; - tempQEntry.curLoss = 0.0f; // greebo: Initialised to 0.0f to fix gcc warning - - AddedAreas.Append( tempQEntry ); - - } // end portal flood loop - - m_EventAreas[area].bVisited = true; - - } // end area flood loop - - // create the next expansion queue - NextAreas = AddedAreas; - - } // end main loop - - // return true if the expansion died out naturally rather than being stopped - return !NextAreas.Num(); -} diff --git a/DarkMod/sndProp.h b/DarkMod/sndProp.h deleted file mode 100644 index 6bfbdb65c..000000000 --- a/DarkMod/sndProp.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -/******************************************************************************/ -/* */ -/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ -/* All rights reserved */ -/* */ -/******************************************************************************/ - -/****************************************************************************** -* -* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI -* during gameplay. Friend class to CsndPropLoader. -* -*****************************************************************************/ - -#ifndef SNDPROP_H -#define SNDPROP_H - -#include "sndPropLoader.h" - -/****************************************************************************** -* -* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI -* during gameplay. Friend class to CsndPropLoader. -* -*****************************************************************************/ - -template -class CMatRUT; - -/** -* Team bitmask definition, for comparing team alert flags -* with team status of an entity -**/ - -typedef struct STeamBits_s -{ - unsigned int friendly : 1; - unsigned int neutral : 1; - unsigned int enemy : 1; - unsigned int same : 1; -} STeamBits; - -typedef union UTeamMask_s -{ - unsigned int m_field; - STeamBits m_bits; -} UTeamMask; - -/** -* Array entry in populated areas array -**/ -typedef struct SPopArea_s -{ - int addedTime; // timestamp at which this entry was added from the AI list - - bool bVisited; // area was visited at least once in wavefront expansion - - idList< idEntityPtr > AIContents; // list of AI that are present in area - - //TODO: Handle Listeners in another list here - - idList VisitedPorts; // portals that the sound flooded in on (reduces comp. time to store this) - -} SPopArea; - -/** -* Portal data stored in an event area -**/ -typedef struct SPortEvent_s -{ - float Loss; // dynamic array to store the current loss at the portal - - float Dist; // distance at portal (used to add AI loss to existing loss) - - float Att; // attenuation at portal (again used for final AI calculation) - - int Floods; // How many floods did it take to get to that particular portal - - SsndPortal *ThisPort; // pointer to the snd portal object for this portal - - SPortEvent_s *PrevPort; // the portal visited immediately before each portal - -} SPortEvent; - -/** -* Array entry in event areas array (storing visited areas information) -**/ -typedef struct SEventArea_s -{ - bool bVisited; // area was visited at least once in wavefront expansion - - SPortEvent *PortalDat; // Array of event data for each portal in the area - -} SEventArea; - -/** -* Expansion queue entry for the wavefront expansion algorithm -**/ -typedef struct SExpQue_s -{ - int area; // area number - - int portalH; // portal handle of the portal flooded in on - - float curDist; // total distance travelled by wave so far - - float curAtt; // total attenuation due to material losses so far - - float curLoss; // total loss so far - - SPortEvent *PrevPort; // previous portal flooded through along path - -} SExpQue; - - - - -class CsndProp : public CsndPropBase { - -public: - CsndProp( void ); - ~CsndProp( void ); - - void Clear( void ); - - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); - - void Propagate( float volMod, float durMod, const idStr& soundName, - idVec3 origin, idEntity *maker, USprFlags *addFlags = NULL ); - - /** - * Get the appropriate vars from the sndPropLoader after - * it has loaded data for the map. - * - * Also looks up door entity pointers for current map and - * puts them into area/portal tree - * - * Also initializes various members - **/ - void SetupFromLoader( const CsndPropLoader *in ); - - /** - * Check if a sound is defined in the soundprop def file - **/ - bool CheckSound( const char *sndNameGlobal, bool isEnv ); - - /** - * Insert the loss argument into the portal data array entry for - * the given portal handle. - * - * This one calls the base class function, plus updates the portal losses timestamp - **/ - void SetPortalLoss( int handle, float value ); - - /** - * Static var for AI checking the default threshold - **/ - static float s_SPROP_DEFAULT_TRESHOLD; - -protected: - - /** - * Wavefront expansion algorithm, starts with volume volInit at point origin - * - * Returns true if the expansion died out naturally rather than being stopped - * by a computation limit. - **/ - bool ExpandWave(float volInit, idVec3 origin); - - /** - * Faster and less accurate wavefront expansion algorithm. - * Only visits areas once. - * - * The wave expands until it reaches the maxDist argument distance or until - * the number of nodes traversed exceeds the MaxNodes argument. Note the float/int - * difference between the last two default-valued arguments. - * - * If MaxDist is set to -1, no distance limit is applied. - * If MaxFloods is set to -1, the global maximum flood limit is used. - **/ - bool ExpandWaveFast( float volInit, idVec3 origin, - float MaxDist = -1, int MaxFloods = -1 ); - - /** - * Process the populated areas after a sound propagation event. - **/ - void ProcessPopulated( float volInit, idVec3 origin, SSprParms *propParms ); - - /** - * Process individual AI. Messages the individual AI, and will later calculate - * the effects of environmental sounds in the signal/noise response of the AI. - * - * Called by ProcessPopulated - **/ - void ProcessAI( idAI* ai, idVec3 origin, SSprParms *propParms ); - - /** - * Copy parms from loader object, and also initialize several member vars - **/ - void SetupParms( const idDict *parms, SSprParms *propParms, - USprFlags *addFlags, UTeamMask *tmask ); - - /** - * Detailed path minimization. Finds the optimum path taking points along the portal surfaces - * Writes the final loss info and apparent location of the sound to propParms. - **/ - void DetailedMin( idAI* AI, SSprParms *propParms, - SPortEvent *pPortEv, int AIArea, float volInit ); - - /** - * Takes point 1, point 2, a winding, and the center point of the winding - * Returns the point on the winding surface that is closest - * to the line p1-p2. - * - * If the line intersects the portal surface, the optimum point will - * be the intersection point. Otherwise, the point will be somewhere - * along the outer boundary of the surface. - * - * Assumes a rectangular portal with 4 winding points. - **/ - idVec3 OptSurfPoint( idVec3 p1, idVec3 p2, const idWinding& wind, idVec3 WCenter ); - - /** - * Draws debug lines between a list of points. Used for soundprop debugging - **/ - void DrawLines(idList& pointlist); - - -protected: - - /** - * Time stamp for the current propagation event [ms] - **/ - int m_TimeStampProp; - - /** - * Time stamp for the last time portal losses were updated - * Used to see if env. sounds need to be repropagated when doors/windows change state - **/ - int m_TimeStampPortLoss; - - /** - * Populated areas : List of indices of AI populated areas for this expansion - **/ - idList m_PopAreasInd; - - /** - * Populated areas array: Lists the AI present in each area - * and which portals the sound flowed in on, for later AI processing. - * - * Stays in memory between events. Each entry has a timestamp, - * and only entries whose indices are in the m_PopAreasInd list are - * checked when processing AI. - **/ - SPopArea *m_PopAreas; - - /** - * Array of areas. Areas that have been visited will have the - * current loss at each portal. Size is the total number of areas - * Entries for areas not visited in this propagation are NULL - * - * For now, this is cleared and re-written for every new sound event - * later on, we might see if we can re-use it for multiple events that - * come from close to the same spot, for optimization. - **/ - SEventArea *m_EventAreas; - -}; - -#endif - - - - - - - diff --git a/DarkMod/sndPropLoader.cpp b/DarkMod/sndPropLoader.cpp deleted file mode 100644 index 77dac60cc..000000000 --- a/DarkMod/sndPropLoader.cpp +++ /dev/null @@ -1,909 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -/******************************************************************************/ -/* */ -/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ -/* All rights reserved */ -/* */ -/******************************************************************************/ - -/****************************************************************************** -* -* DESCRIPTION: Sound propagation class for compiling sound propagation data -* from a Mapfile and write it to a file. Also used to read the file on map init. -* -*****************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#include "../game/game_local.h" - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning(disable : 4996) - -#include "sndPropLoader.h" -#include "MatrixSq.h" -#include "../game/misc.h" - -class idLocationEntity; - -// TODO: Write the mapfile timestamp to the .spr file and compare them - -const float s_DOOM_TO_METERS = 0.0254f; // doom to meters -const float s_METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom - - -const float s_DBM_TO_M = 1.0/(10*log10( idMath::E )); // convert between dB/m and 1/m - -void SsndPGlobals::Save(idSaveGame *savefile) const -{ - savefile->WriteString(AreaPropName); - savefile->WriteString(fileExt); - savefile->WriteInt(MaxPaths); - savefile->WriteFloat(DoorExpand); - savefile->WriteFloat(Falloff_Outd); - savefile->WriteFloat(Falloff_Ind); - savefile->WriteFloat(kappa0); - savefile->WriteFloat(DefaultDoorLoss); - savefile->WriteFloat(DefaultThreshold); - savefile->WriteFloat(Vol); - savefile->WriteFloat(MaxRange); - savefile->WriteFloat(MaxRangeCalVol); - savefile->WriteFloat(MaxEnvRange); - savefile->WriteBool(bDebug); -} - -void SsndPGlobals::Restore(idRestoreGame *savefile) -{ - savefile->ReadString(AreaPropName); - savefile->ReadString(fileExt); - savefile->ReadInt(MaxPaths); - savefile->ReadFloat(DoorExpand); - savefile->ReadFloat(Falloff_Outd); - savefile->ReadFloat(Falloff_Ind); - savefile->ReadFloat(kappa0); - savefile->ReadFloat(DefaultDoorLoss); - savefile->ReadFloat(DefaultThreshold); - savefile->ReadFloat(Vol); - savefile->ReadFloat(MaxRange); - savefile->ReadFloat(MaxRangeCalVol); - savefile->ReadFloat(MaxEnvRange); - savefile->ReadBool(bDebug); -} - -/********************************************************* -* -* CsndPropBase Implementation -* -**********************************************************/ - -void CsndPropBase::Save(idSaveGame *savefile) const -{ - m_SndGlobals.Save(savefile); - savefile->WriteBool(m_bLoadSuccess); - savefile->WriteBool(m_bDefaultSpherical); - savefile->WriteInt(m_numAreas); - savefile->WriteInt(m_numPortals); - - for (int area = 0; area < m_numAreas; area++) - { - savefile->WriteFloat(m_sndAreas[area].LossMult); - savefile->WriteFloat(m_sndAreas[area].VolMod); - savefile->WriteInt(m_sndAreas[area].numPortals); - savefile->WriteVec3(m_sndAreas[area].center); - - for (int portal = 0; portal < m_sndAreas[area].numPortals; portal++) - { - SsndPortal_s& soundportal = m_sndAreas[area].portals[portal]; - - savefile->WriteInt(soundportal.handle); - savefile->WriteInt(soundportal.portalNum); - savefile->WriteInt(soundportal.from); - savefile->WriteInt(soundportal.to); - savefile->WriteVec3(soundportal.center); - savefile->WriteVec3(soundportal.normal); - // greebo: Don't save winding pointer, gets restored from idRenderWorld. - } - - m_sndAreas[area].portalDists->Save(savefile); - } - - savefile->WriteInt(m_AreaPropsG.Num()); - for (int i = 0; i < m_AreaPropsG.Num(); i++) - { - savefile->WriteInt(m_AreaPropsG[i].area); - savefile->WriteFloat(m_AreaPropsG[i].LossMult); - savefile->WriteFloat(m_AreaPropsG[i].VolMod); - savefile->WriteBool(m_AreaPropsG[i].DataEntered); - } - - for (int i = 0; i < m_numPortals; i++) - { - savefile->WriteInt(m_PortData[i].LocalIndex[0]); - savefile->WriteInt(m_PortData[i].LocalIndex[1]); - savefile->WriteInt(m_PortData[i].Areas[0]); - savefile->WriteInt(m_PortData[i].Areas[1]); - savefile->WriteFloat(m_PortData[i].loss); - } -} - -void CsndPropBase::Restore(idRestoreGame *savefile) -{ - m_SndGlobals.Restore(savefile); - - savefile->ReadBool(m_bLoadSuccess); - savefile->ReadBool(m_bDefaultSpherical); - savefile->ReadInt(m_numAreas); - savefile->ReadInt(m_numPortals); - - m_sndAreas = new SsndArea[m_numAreas]; - - for (int area = 0; area < m_numAreas; area++) - { - savefile->ReadFloat(m_sndAreas[area].LossMult); - savefile->ReadFloat(m_sndAreas[area].VolMod); - savefile->ReadInt(m_sndAreas[area].numPortals); - savefile->ReadVec3(m_sndAreas[area].center); - - m_sndAreas[area].portals = new SsndPortal[m_sndAreas[area].numPortals]; - - for (int portal = 0; portal < m_sndAreas[area].numPortals; portal++) - { - SsndPortal_s& soundportal = m_sndAreas[area].portals[portal]; - - savefile->ReadInt(soundportal.handle); - savefile->ReadInt(soundportal.portalNum); - savefile->ReadInt(soundportal.from); - savefile->ReadInt(soundportal.to); - savefile->ReadVec3(soundportal.center); - savefile->ReadVec3(soundportal.normal); - - // Restore the winding pointer from idRenderWorld - exitPortal_t p = gameRenderWorld->GetPortal(area, portal); - soundportal.winding = p.w; - } - - // Allocate and resize the triangle matrix - m_sndAreas[area].portalDists = new CMatRUT; - m_sndAreas[area].portalDists->Restore(savefile); - } - - int num; - savefile->ReadInt(num); - m_AreaPropsG.Clear(); - m_AreaPropsG.SetNum(num); - for (int i = 0; i < num; i++) - { - savefile->ReadInt(m_AreaPropsG[i].area); - savefile->ReadFloat(m_AreaPropsG[i].LossMult); - savefile->ReadFloat(m_AreaPropsG[i].VolMod); - savefile->ReadBool(m_AreaPropsG[i].DataEntered); - } - - m_PortData = new SPortData[m_numPortals]; - for (int i = 0; i < m_numPortals; i++) - { - savefile->ReadInt(m_PortData[i].LocalIndex[0]); - savefile->ReadInt(m_PortData[i].LocalIndex[1]); - savefile->ReadInt(m_PortData[i].Areas[0]); - savefile->ReadInt(m_PortData[i].Areas[1]); - savefile->ReadFloat(m_PortData[i].loss); - } -} - -void CsndPropBase::GlobalsFromDef( void ) -{ - const idDict *def; - - def = gameLocal.FindEntityDefDict( "atdm:soundprop_globals", false ); - - if(!def) - { - gameLocal.Warning("[DarkMod Sound Prop] : Did not find def for atdm:soundprop_globals. Bad or missing tdm_soundprop.def file. Using default values."); - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Did not find def for atdm:soundprop_globals. Using default values.\r"); - DefaultGlobals(); - goto Quit; - } - - m_SndGlobals.bDebug = def->GetBool("debug", "0"); - m_SndGlobals.AreaPropName = def->GetString("aprop_name", ""); - m_SndGlobals.fileExt = def->GetString("file_ext", "spr"); - - m_SndGlobals.MaxPaths = def->GetInt("maxpaths", "3"); - m_SndGlobals.DoorExpand = def->GetFloat("doorexpand", "1.0"); - m_SndGlobals.Falloff_Outd = def->GetFloat("falloff_outd", "10.0"); - m_SndGlobals.Falloff_Ind = def->GetFloat("falloff_ind", "9.0"); - m_SndGlobals.kappa0 = def->GetFloat("kappa_dbm", "0.015"); - - m_SndGlobals.DefaultDoorLoss = def->GetFloat("default_doorloss", "20"); - m_SndGlobals.MaxRange = def->GetFloat("maxrange", "2.2"); - m_SndGlobals.MaxRangeCalVol = def->GetFloat("maxrange_cal", "30"); - m_SndGlobals.MaxEnvRange = def->GetFloat("max_envrange", "50"); - - m_SndGlobals.Vol = def->GetFloat("vol_ai", "0.0"); - m_SndGlobals.DefaultThreshold = def->GetFloat("default_thresh", "20.0"); - -Quit: - return; -} - -void CsndPropBase::DefaultGlobals( void ) -{ - m_SndGlobals.bDebug = false; - m_SndGlobals.AreaPropName = ""; - m_SndGlobals.fileExt = "spr"; - - m_SndGlobals.MaxPaths = 3; - m_SndGlobals.DoorExpand = 1.0f; - m_SndGlobals.Falloff_Outd = 10.0f; - m_SndGlobals.Falloff_Ind = 9.0f; - m_SndGlobals.kappa0 = 0.015f; - - m_SndGlobals.DefaultDoorLoss = 20.0f; - m_SndGlobals.MaxRange = 2.2f; - m_SndGlobals.MaxRangeCalVol = 30; - m_SndGlobals.MaxEnvRange = 50; - - m_SndGlobals.Vol = 0.0; - m_SndGlobals.DefaultThreshold = 20.0f; -} - -void CsndPropBase::UpdateGlobals( void ) -{ - // link console vars to globals here -} - - -/********************************************************* -* -* CsndPropLoader Implementation -* -**********************************************************/ - - -CsndPropLoader::CsndPropLoader ( void ) -{ - m_PortData = NULL; - m_sndAreas = NULL; - m_numAreas = 0; - m_numPortals = 0; - m_bDefaultSpherical = false; - m_bLoadSuccess = false; -} - -CsndPropLoader::~CsndPropLoader ( void ) -{ - // Call shutdown in case it was not called before destruction - Shutdown(); -} - -void CsndPropLoader::Save(idSaveGame *savefile) const -{ - // Pass the call to the base class first - CsndPropBase::Save(savefile); - - // TODO -} - -void CsndPropLoader::Restore(idRestoreGame *savefile) -{ - // Pass the call to the base class first - CsndPropBase::Restore(savefile); - - // TODO -} - -/** -* MapEntBounds PSUEDOCODE: -* DOORS WITH BRUSHES: -* For each plane: add the direction normal vector * d to the origin. -* This sould be the point we want to add to bounds for each plane, -* to generate a bounding box containing the planes -**/ - -bool CsndPropLoader::MapEntBounds( idBounds &bounds, idMapEntity *mapEnt ) -{ - bool returnval; - idMapPrimitive *testPrim; - idMapBrush *brush(NULL); - idMapBrushSide *face; - idPlane plane; - int numFaces, numPrim; - idVec3 norm, *addpoints, debugCenter; - idMat3 rotation; - float dist, angle; - const char *modelName; - cmHandle_t cmHandle; // collision model handle for getting bounds - - idDict args = mapEnt->epairs; - const idVec3 origin = args.GetVector("origin","0 0 0"); - modelName = args.GetString("model"); - - // if a door doesn't have a model, the modelname will be the same as the doorname - if( strcmp(modelName,args.GetString("name")) ) - { - // NOTE: In the LoadModel call, Precache is set to false currnetly. If it was set to - // TRUE, this would force the door model to have a .cm file, otherwise - // LoadModel would return 0 in this case. (precache = true, no .cm file) - cmHandle = collisionModelManager->LoadModel( modelName, false ); - if ( cmHandle == 0) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Failed to load collision model for entity %s with model %s. Entity will be ignored.\r", args.GetString("name"), modelName); - returnval = false; - goto Quit; - } - - collisionModelManager->GetModelBounds( cmHandle, bounds ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found bounds with volume %f for entity %s with model %s.\r", bounds.GetVolume(), args.GetString("name"), modelName); - // Rotation copied from Entity::ParseSpawnArgsToRenderEntity() - // get the rotation matrix in either full form, or single angle form - if ( !args.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", rotation ) ) - { - angle = args.GetFloat( "angle" ); - if ( angle != 0.0f ) - { - rotation = idAngles( 0.0f, angle, 0.0f ).ToMat3(); - } - else - { - rotation.Identity(); - } - } - bounds.RotateSelf(rotation); - // Translate and rotate the bounds to be in sync with the model - bounds.TranslateSelf(origin); - // NOTE FOR FUTURE REFERENCE: MUST ROTATE THEN TRANSLATE - /** - * Global DoorExpand is applied to correct door bound inaccuracies. - **/ - ExpandBoundsMinAxis(&bounds, m_SndGlobals.DoorExpand); - debugCenter = bounds.GetCenter(); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Model Bounds center: %s , MapEntity origin: %s\r",debugCenter.ToString(),origin.ToString()); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Bounds rotation: %s\r", rotation.ToString()); - returnval = true; - goto Quit; - // Brian says it's okay if LoadModel is run twice, it just won't load it the 2nd time. - // Therefore we won't worry about freeing the model now. (this caused a crash when I tried) - } - - // Continue on if the door does not have a model: - - if( (numPrim = mapEnt->GetNumPrimitives()) == 0 ) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Door %s has no primitive data. Door will be ignored.\r", args.GetString("name")); - returnval = false; - goto Quit; - } - for (int j=0; j < numPrim; j++) - { - testPrim = mapEnt->GetPrimitive(j); - if ( testPrim->GetType() == testPrim->TYPE_BRUSH ) - { - brush = static_cast(testPrim); - break; - } - } - if (brush == NULL) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Door %s does not have a brush primitive. Door will be ignored\r", args.GetString("name")); - returnval = false; - goto Quit; - } - - numFaces = brush->GetNumSides(); - addpoints = new idVec3[numFaces]; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MapEntBounds: Door %s has %d faces\r", mapEnt->epairs.GetString("name"), numFaces ); - - for(int i = 0; i < numFaces; i++) - { - face = brush->GetSide(i); - plane = face->GetPlane(); - norm = plane.Normal(); - dist = plane.Dist(); - norm.Normalize(); - //addpoints[i] = ( norm/norm.Normalize() * dist ) + origin; - //TODO: Make sure this change works correctly: - addpoints[i] = ( norm * dist ) + origin; - //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Added point: %s to bounds for %s\r", addpoints[i].ToString(), mapEnt->epairs.GetString("name")); - } - - bounds.FromPoints(static_cast(addpoints), static_cast(numFaces)); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Entity %s has bounds with volume %f\r", args.GetString("name"), bounds.GetVolume() ); - - delete[] addpoints; - - returnval = true; - -Quit: - return returnval; -} - -void CsndPropLoader::ExpandBoundsMinAxis( idBounds *bounds, float percent ) -{ - idVec3 points[8], diff, mindiff, addpoints[2], oppPoint; - bounds->ToPoints(points); - float diffDist, mindiffDist(100000.0f); // initialize mindiffDist to a really big number - // find the minimum axis and direction vector between minimum points - for( int i = 1; i<8; i++ ) - { - diff = points[0] - points[i]; - diffDist = diff.LengthFast(); - if (diffDist < mindiffDist) - { - mindiffDist = diffDist; - mindiff = diff; - oppPoint = points[i]; - } - } - // expand the axis by adding points along that axis - addpoints[0] = points[0] + mindiff * percent; - addpoints[1] = oppPoint - mindiff * percent; - bounds->AddPoint(addpoints[0]); - bounds->AddPoint(addpoints[1]); -} - - -void CsndPropLoader::ParseMapEntities ( idMapFile *MapFile ) -{ - int i; - //int count(0), missedCount(0); - idDict args; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Soundprop: Parsing Map entities\r"); - for (i = 0; i < ( MapFile->GetNumEntities() ); i++ ) - { - idMapEntity *mapEnt = MapFile->GetEntity( i ); - args = mapEnt->epairs; - const char *classname = args.GetString("classname"); - - if( !strcmp(classname,m_SndGlobals.AreaPropName) ) - { - ParseAreaPropEnt(args); - } - - if( !strcmp(classname,"worldspawn") ) - { - ParseWorldSpawn(args); - } - } - - m_AreaProps.Condense(); - - FillAPGfromAP( gameRenderWorld->NumAreas() ); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Finished parsing map entities\r"); -} - -void CsndPropLoader::ParseWorldSpawn ( idDict args ) -{ - bool SpherDefault; - - SpherDefault = args.GetBool("outdoor_propmodel","0"); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Parsing worldspawn sound prop data...\r" ); - if(SpherDefault) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Using outdoor sound prop model as the default for this map\r"); - } - else - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Using indoor sound prop model as the default for this map\r" ); - } - m_bDefaultSpherical = SpherDefault; -} - -void CsndPropLoader::ParseAreaPropEnt ( idDict args ) -{ - int area; - float lossMult, VolMod; -// bool SpherSpread(false); - SAreaProp propEntry; - idStr lossvalue, VolOffset; - - if ( ( area = gameRenderWorld->PointInArea(args.GetVector("origin")) ) == -1 ) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Sound area properties entity %s is not placed in any area. It will be ignored\r", args.GetString("name") ); - goto Quit; - } - - lossvalue = args.GetString("sound_loss_mult", "1.0"); - - if(!( lossvalue.IsNumeric() )) - { - lossMult = 1.0; - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Non-numeric loss_mult value on area data entity: %s. Default value assumed\r", args.GetString("name") ); - } - else - lossMult = fabs(atof(lossvalue)); - - VolOffset = args.GetString("sound_vol_offset", "0.0"); - - if(!( VolOffset.IsNumeric() )) - { - VolMod = 0.0; - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Non-numeric volume offset value on area data entity: %s. Default value assumed\r", args.GetString("name") ); - } - else - VolMod = atof(VolOffset); - - // multiply Loss Mult by default attenuation constant - propEntry.LossMult = lossMult * m_SndGlobals.kappa0; - propEntry.VolMod = VolMod; - propEntry.area = area; - propEntry.DataEntered = false; // greebo: Initialised to false to fix gcc warning - - //add to the area properties list - m_AreaProps.Append( static_cast(propEntry) ); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Entity %s is a sound area entity. Applied loss multiplier %f, volume modifier %f\r", args.GetString("name"), lossMult, VolMod ); - -Quit: - return; -} - -void CsndPropLoader::FillAPGfromAP ( int numAreas ) -{ - int i, j, area(0); - - m_AreaPropsG.Clear(); - - m_AreaPropsG.SetNum( numAreas ); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Allocated m_AreaPropsG for %d areas\r", numAreas ); - - // set default values on each area - for (i=0; iNumPortalsInArea(area); - for (int i = 0; i < np; i++) - { - portalTmp = gameRenderWorld->GetPortal(area,i); - //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("FindSndPortal: Desired handle %d, handle of portal %d: %d\r", pHandle, i, areaP->portals[i].handle ); //Uncomment for portal handle debugging - if(portalTmp.portalHandle == pHandle) - { - val = i; - goto Quit; - } - } -Quit: - return val; -} - -void CsndPropLoader::CreateAreasData ( void ) -{ - int i, j, k, np, anum, propscount(0), numAreas(0), numPortals(0), PortIndex; - sndAreaPtr area; - exitPortal_t portalTmp; - idVec3 pCenters; - - numAreas = gameRenderWorld->NumAreas(); - numPortals = gameRenderWorld->NumPortals(); - pCenters.Zero(); - - if( (m_sndAreas = new SsndArea[m_numAreas]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Create Areas: Out of memory when allocating array of %d Areas\r", m_numAreas); - goto Quit; - } - - if( (m_PortData = new SPortData[m_numPortals]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when allocating array of %d portals\r", m_numPortals); - goto Quit; - } - - // Initialize portal data array - for ( int k2 = 0; k2 < m_numPortals; k2++ ) - { - m_PortData[k2].loss = 0; - - m_PortData[k2].LocalIndex[0] = -1; - m_PortData[k2].LocalIndex[1] = -1; - m_PortData[k2].Areas[0] = -1; - m_PortData[k2].Areas[1] = -1; - } - - for ( i = 0; i < m_numAreas; i++ ) - { - area = &m_sndAreas[i]; - area->LossMult = 1.0; - np = gameRenderWorld->NumPortalsInArea(i); - area->numPortals = np; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Number of Portals in Area %d = %d\r", i, np); - - if( (area->portals = new SsndPortal[np]) == NULL ) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Create Areas: Out of memory when building portals array for Area %d\r", i); - goto Quit; - } - for ( j = 0; j < np; j++ ) - { - portalTmp = gameRenderWorld->GetPortal(i,j); - - area->portals[j].portalNum = j; - area->portals[j].handle = portalTmp.portalHandle; - area->portals[j].from = portalTmp.areas[0]; // areas[0] is the 'from' area - area->portals[j].to = portalTmp.areas[1]; - area->portals[j].center = portalTmp.w->GetCenter(); - area->portals[j].winding = portalTmp.w; - - pCenters += area->portals[j].center; - - // enter the data into the portal data array - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting up portal handle %d from area %d\r",portalTmp.portalHandle, i); - SPortData *pPortData = &m_PortData[ portalTmp.portalHandle - 1 ]; - - // make sure we don't overwrite the data from the area on the other side - if(pPortData->Areas[0] == -1 ) - PortIndex = 0; - else - PortIndex = 1; - - pPortData->Areas[ PortIndex ] = i; - pPortData->LocalIndex[ PortIndex ] = j; - } - - // average the portal center coordinates to obtain the area center - if ( np ) - { - area->center = pCenters / np; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Area %d has approximate center %s\r", i, area->center.ToString() ); - } - } - - // Apply special area Properties - for(k = 0; k < m_AreaProps.Num(); k++) - { - anum = m_AreaProps[k].area; - m_sndAreas[anum].LossMult = m_AreaProps[k].LossMult; - m_sndAreas[anum].VolMod = m_AreaProps[k].VolMod; - propscount++; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("%d Area specific losses applied\r", propscount); - - // calculate the portal losses and populate the losses array for each area - WritePortLosses(); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Create Areas array finished.\r"); -Quit: - return; -} - - -void CsndPropLoader::WritePortLosses( void ) -{ - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Writing portal losses...\r"); - - int row, col, area(0), numPorts(0); - float lossval(0); - - for( area=0; area < m_numAreas; area++ ) - { - numPorts = m_sndAreas[area].numPortals; - - if ( (m_sndAreas[area].portalDists = new CMatRUT) == NULL) - { - DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing portal losses array for area %d\r", area); - goto Quit; - } - - // no need to write a matrix if the area only has one portal - if (numPorts == 1) - continue; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Initializing area %d with %d portals\r", area, numPorts); - - // initialize the RUT matrix to the right size - m_sndAreas[area].portalDists->Init( numPorts ); - - // fill the RUT matrix - for( row=0; row < numPorts; row++ ) - { - for( col=(row + 1); col < numPorts; col++ ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting loss for portal %d to portal %d in area %d\r", row, col, area ); - lossval = CalcPortDist( area, row, col ); - - m_sndAreas[area].portalDists->Set( row, col, lossval ); - } - } - } -Quit: - return; -} - -float CsndPropLoader::CalcPortDist( int area, int port1, int port2) -{ - float dist; - idVec3 center1, center2, delta; - // TODO: PHASE 3 SOUNDPROP: Implement design for geometrically calculating loss between portals - // for now, just take center to center distance, correct in a lot of cases - center1 = m_sndAreas[area].portals[port1].center; - center2 = m_sndAreas[area].portals[port2].center; - - delta = center1 - center2; - //TODO: If optimization is needed, use delta.LengthFast() - dist = delta.Length(); - dist *= s_DOOM_TO_METERS; - - return dist; -} - -void CsndPropBase::DestroyAreasData( void ) -{ - int i; - SsndPortal *portalPtr; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing m_sndAreas \r"); - if( m_sndAreas ) - { - for( i=0; i < m_numAreas; i++ ) - { - portalPtr = m_sndAreas[i].portals; - delete[] portalPtr; - - m_sndAreas[i].portalDists->Clear(); - } - - delete[] m_sndAreas; - m_sndAreas = NULL; - m_numAreas = 0; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing m_PortData with %d portals \r", m_numPortals); - if( m_PortData ) - { - delete[] m_PortData; - m_PortData = NULL; - m_numPortals = 0; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Destroy Areas data finished.\r"); -} - -void CsndPropBase::SetPortalLoss( int handle, float value ) -{ - // make sure the handle is valid - if( handle < 1 || handle > gameRenderWorld->NumPortals() ) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SetPortalLoss called with invalid portal handle %d.\r", handle ); - gameLocal.Warning( "SetPortalLoss called with invalid portal handle %d.\n", handle ); - - goto Quit; - } - - m_PortData[ handle - 1 ].loss = value; - -Quit: - return; -} - -float CsndPropBase::GetPortalLoss( int handle ) -{ - float returnval; - - // make sure the handle is valid - if( handle < 1 || handle > gameRenderWorld->NumPortals() ) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("GetPortalLoss called with invalid portal handle %d, returning zero loss.\r", handle ); - gameLocal.Warning( "GetPortalLoss called with invalid portal handle %d, returning zero loss.\n", handle ); - - returnval = 0.0; - goto Quit; - } - - returnval = m_PortData[ handle - 1 ].loss; - -Quit: - return returnval; -} - - -// ======================= CsndPropLoader ============================= - -void CsndPropLoader::CompileMap( idMapFile *MapFile ) -{ - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound propagation system initializing...\r"); - - // Just in case this was somehow not done before now - DestroyAreasData(); - - // clear the area properties - m_AreaProps.Clear(); - - m_numAreas = gameRenderWorld->NumAreas(); - - m_numPortals = gameRenderWorld->NumPortals(); - - ParseMapEntities(MapFile); - - CreateAreasData(); - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound propagation system finished loading.\r"); - - m_bLoadSuccess = true; -} - -void CsndPropLoader::FillLocationData( void ) -{ - idLocationEntity *pLocEnt; - SAreaProp *pAreaProp; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Filling location soundprop data.\r"); - - if ( !m_AreaPropsG.Num() ) - goto Quit; - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Checking %d areas\r", gameRenderWorld->NumAreas() ); - for(int i = 0; i < gameRenderWorld->NumAreas(); i++) - { - pAreaProp = &m_AreaPropsG[i]; - if( pAreaProp->DataEntered ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Data already entered for are %d, skipping\r", i ); - continue; - } - - pLocEnt = gameLocal.LocationForArea( i ); - if ( !pLocEnt ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("No location for area %d, skipping\r", i ); - continue; - } - - pAreaProp->LossMult = pLocEnt->m_SndLossMult; - pAreaProp->VolMod = pLocEnt->m_SndVolMod; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found location data for area %d, entering lossmult %f, volmod %f\r", i, pAreaProp->LossMult, pAreaProp->VolMod ); - } - -Quit: - return; -} - -void CsndPropLoader::Shutdown( void ) -{ - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing sound propagation data loader.\r"); - DestroyAreasData(); - - // clear the area properties - m_AreaProps.Clear(); - - m_bDefaultSpherical = false; - m_bLoadSuccess = false; - - m_AreaPropsG.Clear(); -} diff --git a/DarkMod/sndPropLoader.h b/DarkMod/sndPropLoader.h deleted file mode 100644 index 706e60318..000000000 --- a/DarkMod/sndPropLoader.h +++ /dev/null @@ -1,476 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -/******************************************************************************/ -/* */ -/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ -/* All rights reserved */ -/* */ -/******************************************************************************/ - -/****************************************************************************** -* -* DESCRIPTION: Sound propagation class for propagating suspicious sounds -* to AI Used on map initialization. -* -* This class will be only for map loading and generation of the Loss Matrix. -* Actual gameplay functions will be handled by another class, CsndProp, for -* ease of maintenance. -* -*****************************************************************************/ - -#ifndef SNDPROPLOADER_H -#define SNDPROPLOADER_H - -#include "../idlib/precompiled.h" -#include "DarkModGlobals.h" - -template -class CMatRUT; - -/** -* Global soundprop settings -* Populated from entityDef atdm:soundprop_globals -**/ -class SsndPGlobals -{ -public: - // names - idStr AreaPropName; // classname of area properties entity - idStr fileExt; // soundprop file extension - - // Map compiling: - // Maximum number of paths to calculate for a given loss matrix element - int MaxPaths; - - /** - * Amount to expand the bounding box of a door model in its thinnest dimension - * when checking for portals in doors. - **/ - float DoorExpand; - - /************** - * The following settings effect both gameplay and compiling: - * They are not set const so they may be changed dynamically, - * but keep in mind the compiled soundprop file for the map - * will NOT change until recompiled. - ***************/ - - float Falloff_Outd; // outdoor sound falloff, multiplied by log(dist^2) - float Falloff_Ind; // indoor sound falloff, multiplied by log(dist^2) - - /** - * Kappa0 is the decay constant [db/M] for a sound wave in air - * In reality this depends on freqeuncy, humidity, etc. - * But the effet is small compared to geometric spreading, (~1%) - * So we assume it's a constant. - **/ - float kappa0; - - /************* - * The following settings effect only gameplay, and can - * safely be linked to cVars if we want. - **************/ - - /** - * If a func_door is not a func_darkmod_door, this is the default - * loss that will be applied when sound propagates thru the door. - **/ - float DefaultDoorLoss; - - // AI settings: - - /** - * Default threshold of hearing for an AI (SPL) - * This corresponds to the minimum audible loudness before - * an AI starts getting alerted by a sound. - * (Think of leaves rustling or a very soft whisper) - * In reality this is about 20dB SPL for the average human - **/ - float DefaultThreshold; - - /** - * AI Volume: All sounds propagated to AI will be scaled - * by this amount. This is intended for gameplay balance, - * and should be linked to a cVar for realtime testing. - * This is in dB, so the default value is zero. - **/ - float Vol; - - - float MaxRange; // Range in meters above which sound propagation is not calculated - float MaxRangeCalVol; // volume value to normalize by for the max soundrange (in dB) - // NOT YET IMPLEMENTED: - float MaxEnvRange; // Range in which environmental sounds are heard by AI - - bool bDebug; - - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); -}; - -//TODO: Move this stuff to documentation - -/** -* NOTE: MaxRange is the maximum distance (in meters) that a sound with -* volume equal to MaxRangeCalVol will be propagated. -* At the default values, these settings are calibrated so that the cutoff -* for a whisper (30dB SWL) is 2 meters (~6 ft) -* -* Formula for cutoff range: -* For a given volume vol0, -* Max Range is calculate with the following "empirical" formula,loosely based on -* the fact that sounds sound twice as loud when they differ by 10 dB -* -* range = pow(2, ((vol0 - MaxRangeCalVol) / 7) ) * MaxRange -* -* The penalty for overestimated the cutoff range is more AI included in the computation -* The penalty for underestimating is AI not hearing a sound that they should have heard. -* Ideally, you want the maxrange to be just a few meters past where the sound falls -* below the AI's threshold volume. -**/ - -/** -* ADDITIONAL NOTES: -* The formula for calculating how much an AI is alerted from a sound is: -* -* psychLoud [in "alert" units] = 1 + (propParms->loudness - threshold) -* -* An alert unit of 1 is a barely heard sound (whisper) heard for ~100mS -* An alert unit of 10 corresponds to hearing twice as loud a sound. -**/ - -/** -* Portal data stored in portal data array indexed by handles -* Contains local portal numbers and attenuation for that portal -**/ -typedef struct SPortData_s -{ - // indices of the portal in the two areas connected by it - // order is arbitrary - int LocalIndex[2]; - int Areas[2]; // area numbers that match up with the local index numbers - float loss; // acoustical loss [dB] when going through the portal -} SPortData; - -/** -* Structure containing special area properties -* lossMultiplier defaults to 1.0 if not set. -**/ -typedef struct SAreaProp_s -{ - int area; // number of the area, for list lookup - float LossMult; // loss multiplier - float VolMod; // added to volume of all sounds originating in this area - bool DataEntered; // set to true if this area has specific data (used for area<-locatoin overriding) -} SAreaProp; - -/** -* SsndPortal and SSndArea are structures for storing the area/portal -* connectivity database. They will be copied over to the gameplay object. -**/ -typedef struct SsndPortal_s -{ - qhandle_t handle; // portal handle - - int portalNum; // integer ID of the portal in the area - - int from; // area the portal is in - - int to; // area the portal goes to - - idVec3 center; // coordinates of the center of the portal - - idVec3 normal; // normal vector of portal (by convention, this points into the room) - - const idWinding *winding; // point information - -} SsndPortal; - -typedef SsndPortal* sndPortalPtr; - -/** -* Array entry for the area->portals tree -**/ -typedef struct SsndArea_s -{ - float LossMult; // loss multiplier (in dB/meter, less than 1 => less loss) - - float VolMod; // Volume offset of sounds originating in this area, in dB. - - int numPortals; // number of portals in this area - - idVec3 center; // approximate center of the area - - SsndPortal_s *portals; // array containing the portals of this area - - CMatRUT *portalDists; // acoustical distances from each portal in room to each other portal - -} SsndArea; - -typedef SsndArea* sndAreaPtr; - - - -// ==================================================================== -/** -* CLASS DESCRIPTION: CsndPropBase has functions and members -* inherited by both CsndPropLoader and CsndProp (the gameplay class) -**/ - -class CsndPropBase { - -public: - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); - - /** - * Structure containing global sound properties. - **/ - SsndPGlobals m_SndGlobals; - - /** - * Fill the global properties structure from the - * soundpropglobals entityDef (defined in soundprop.def. - * This could probably be put on CsndPropLoader instead of - * the base class, but just in case CsndProp needs it, it's here. - * - * Logs a warning and sets defaults if it cannot find the def - * for atdm:soundprop_globals. - **/ - void GlobalsFromDef( void ); - - /** - * Insert the loss argument into the portal data array entry for - * the given portal handle - **/ - void SetPortalLoss( int handle, float value ); - - /** - * Get the acoustical loss for the given portal handle - * Portal handle must be between 1 and the number of portals in the map - **/ - float GetPortalLoss( int handle ); - - -protected: - - /** - * Updates any global sound properties that are linked - * to console vars or other realtime vars - **/ - void UpdateGlobals( void ); - - /** - * Set the globals to some default values if the atdm:soundprop_globals - * def is missing. - **/ - void DefaultGlobals( void ); - - /** - * Delete the m_sndAreas array - **/ - void DestroyAreasData( void ); - -protected: - - /** - * This gets set to TRUE when a .spr file is successfully loaded - * for the current map. - **/ - bool m_bLoadSuccess; - - /** - * If set to true, the default sound model will be indoor propagation - * This bool is read from the worldspawn entity, and defaults to false - **/ - bool m_bDefaultSpherical; - - /** - * Count of the number of areas in a map - **/ - int m_numAreas; - - /** - * Count of the number of unique portals in a map - **/ - int m_numPortals; - - - /******************************************************************** - * GAMEPLAY MEMBERS - * Members after this point must be passed along to be used in gameplay! - *********************************************************************/ - - /** - * Area and portal connectivity database - * Created by loader, used during gameplay - **/ - SsndArea *m_sndAreas; - - /** - * m_AreaPropsG contains the area properties of ALL areas for use - * during propagation. - * defaults are loss multiplier = 1.0, and VolMod = 0.0. - **/ - idList m_AreaPropsG; - - /** - * Portal data array indexed by portal handle - * Used to optimize lookup of local portal number - * Also stores the current attenuation value of the portal - **/ - SPortData *m_PortData; -}; - - -/** -* CLASS DESCRIPTION: CsndPropLoader class. Handles parsing of mapfile -* into sound prop data, precalculating portal losses. Also handles -* loading of existing sound propagation files (.spr) for a given map, -* and writing of these files after the mapfile compilation is done. -* -**/ - -class CsndPropLoader : public CsndPropBase { -public: - - friend class CsndProp; - - CsndPropLoader ( void ); - ~CsndPropLoader ( void ); - - void Save(idSaveGame *savefile) const; - void Restore(idRestoreGame *savefile); - - /** - * Load sound prop system from a loaded mapfile. - * This does the actual parsing of the map file and will do - * the generating of the Loss Matrix, as opposed to LoadSprFile - * which just loads the file for the map. - * For now, this is run in game_local every map load as a test - * When the actual system is in place, we must check to see if the map - * has an existing .spr file, and load that instead of running this. - * - * This should probably be renamed to CompileMap. This is what we - * call from the editor console to compile the .spr AFTER compiling - * the map with dmap. - * - * Also, this function will have to load the mapfile - * idMapFile pointer for the appropriate map itself instead of relying on - * something else to pass it. - **/ - void CompileMap( idMapFile *MapFile ); - - /** - * Destroy sound prop data when switching to a new map, game ends, etc - **/ - void Shutdown( void ); - - /** - * To be run AFTER entities spawn. Goes through the location areas and fills - * in location data for each area. Note area data objects override location data. - **/ - void FillLocationData( void ); - -private: - - /** - * The following functions go through the mapfile and identify map entities - * that are associated with sound prop. ParseMapEntities calls ParseWorldSpawn, - * ParseAreapropEnt and ParseDoor. - **/ - - void ParseMapEntities ( idMapFile *MapFile ); - - /** - * ParseWorldSpawn gets map-wide sound information from the worldspawn entity - * This information includes whether the default sound prop model should be - * indoor or outdoor (whether the map is predominantly indoor or outdoor) - **/ - void ParseWorldSpawn ( idDict args ); - - /** - * Area property entities are parsed to add their properties to - * the area properties array. - **/ - void ParseAreaPropEnt ( idDict args ); - - /** - * Searches the provided area number for the portal handle pHandle. - * Then returns the integer index of the portal within the portal list - * of that area. (As defined in gameRenderWorld->GetPortal(area num,portal num)) - * Returns -1 if the portal is not found. - **/ - int FindSndPortal( int area, qhandle_t pHandle ); - - /** - * Finds the bounds of a map entity and writes it to bounds argument. - * - * If the map entity has a model, the bounds of the collision model are returned. - * If no collision model is available for the given model, the rendermodel - * is used as the collision model. This is usually not good since rendermodels can - * be high poly. - * - * If the map entity has no model, the first primitive brush found is used to - * generate a bounding box. Primitive patches are ignored. - * - * This function is currently only used for finding the bounds of doors - * to check if a given door contains a portal. - **/ - bool MapEntBounds( idBounds &bounds, idMapEntity *mapEnt ); - - /** - * Helper function : TODO : move to a more general library, perhaps idBounds - * Expand the bounds only in the direction that they are the thinnest. - * Expands by percent * the thinnest width of the box (note 1.0 = 100%) - **/ - void ExpandBoundsMinAxis( idBounds *bounds, float percent ); - - /** - * Create the Areas array that stores which portals connect which areas - * as well as area sound loss multipliers. - * NOTE: Destroy is on base class - **/ - void CreateAreasData ( void ); - - /** - * Precalculated the portal-to-portal losses and write them to m_sndAreas - * To be called by or after CreateAreasData - **/ - void WritePortLosses( void ); - - /** - * Calculate the distance a sound wave would travel between two - * portal centers Often this is a straight line, but sometimes it bounces. - **/ - float CalcPortDist( int area, int port1, int port2 ); - - /** - * Fill the m_AreaPropsG array from the m_AreaProps array. - * Default loss multiplier = 1.0, default sound model = indoor - **/ - void FillAPGfromAP ( int numAreas ); - -protected: - - /************************************************************ - * PRE-GAMEPLAY MEMBERS - * These members are only used by the pre-gameplay object and don't need - * to be copied to the gameplay object. - ***********************************************************/ - - /** - * List of area properties. - * Only contains areas with non-default properties. - **/ - idList m_AreaProps; - -}; - -#endif diff --git a/LICENSE.txt b/LICENSE.txt index b58b1d46b..e9d9bfc93 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -4,300 +4,52 @@ Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported license, as specified at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode and described at http://creativecommons.org/licenses/by-nc-sa/3.0/ -As an exception to the above, derivative works of assets taken from DOOM 3 -or from the DOOM 3 Software Development Kit are licensed under the DOOM 3 -Software Development Kit Limited Use License Agreement, reproduced below. +Portions of the The Dark Mod Source Code are © 2004-20011 Id Software; +Other portions of this software are © 2005-2011 by Broken Glass Studios +(The Dark Mod Team). -Portions of the software components of The Dark Mod are © 2004 Id Software; -those portions may only be used and distributed under the DOOM 3 Software -Development Kit Limited Use License Agreement, reproduced below. Other -portions of this software are © 2005-2009 Broken Glass Studios (the Dark Mod -team), and may be distributed under the revised BSD license, which is also -reproduced below. You must agree to both licenses before distributing this -software. +All software components of The Dark Mod, either original or based +on the Doom 3 GPL Source Code as released in November 2011, are licensed +and can be distributed under the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at your +option) any later version. -These licenses are applied in a good faith belief that the copyright holders, -as listed in AUTHORS.txt, have implicitly agreed to license their -contributions in this manner. If you have contributed content which you do not -agree to distribute under these licenses, please contact Broken Glass Studios -(the Dark Mod team) to have your contributions removed. +See below for a reproduction of the license notes as included in the original +Doom 3 GPL Source Code release. ------------------------------------------------------------------------------- -DOOM 3 SOFTWARE DEVELOPMENT KIT -LIMITED USE LICENSE AGREEMENT +This license is applied in a good faith belief that the copyright holders, +as listed in AUTHORS.txt, have implicitly agreed to license their contributions +in this manner. If you have contributed content which you do not agree to +distribute under this license, please contact Broken Glass Studios +(The Dark Mod Team) to have your contributions removed. -This DOOM 3 Software Development Kit Limited Use License Agreement (this -"Agreement") is a legal agreement among you, the end-user, and Id Software, -Inc. ("Id Software"). BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THIS -SOFTWARE DEVELOPMENT KIT (THE "SOFTWARE") FOR THE GAME PROGRAM ENTITLED DOOM -3, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE -ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU ARE -AGREEING TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU -ACKNOWLEDGE AND UNDERSTAND THAT IN ORDER TO OPERATE THE SOFTWARE, YOU MUST -HAVE THE FULL VERSION OF THE ID SOFTWARE GAME ENTITLED DOOM 3 INSTALLED ON -YOUR COMPUTER. +=========================================================================== -1. Grant of License. Subject to the terms and provisions of this Agreement -and so long as you fully comply at all times with this Agreement, Id Software -grants to you the non-exclusive and limited right to use the Software only in -executable or object code form. The term "Software" includes all elements of -the Software, including, without limitation, data files and screen displays. -You are not receiving any ownership or proprietary right, title, or interest -in or to the Software or the copyrights, trademarks, or other rights related -thereto. For purposes of the first sentence of this Section, "use" means -loading the Software into RAM and/or onto computer hard drive, as well as -installation of the Software on a hard disk or other storage device, and -means the uses permitted in Sections 2 and 5 hereinbelow. You agree that the -Software will not be downloaded, shipped, transferred, exported or re- -exported into any country in violation of the United States Export -Administration Act (or any other law governing such matters) by you or anyone -at your direction, and that you will not utilize and will not authorize -anyone to utilize the Software in any other manner in violation of any -applicable law. The Software shall not be downloaded or otherwise exported -or re-exported into (or to a national or resident of) any country to which -the United States has embargoed goods, or to anyone or into any country -who/that are prohibited, by applicable law, from receiving such property. In -exercising your limited rights hereunder, you shall comply, at all times, -with all applicable laws, regulations, ordinances, and statutes. Id Software -reserves all rights not granted in this Agreement, including, without -limitation, all rights to Id Software's trademarks. +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -2. Permitted New Creations. Subject to the terms and provisions of this -Agreement and so long as you fully comply at all times with this Agreement, -Id Software grants to you the non-exclusive and limited right to use the -Software to create for the software game DOOM 3 your own modifications (the -"New Creations") that shall operate only with DOOM 3 (but not any demo, test, -or other version of DOOM 3). You may include within the New Creations -certain textures and other images (the "Software Images") from the Software. -You shall not create any New Creations that infringe against any third-party -right or that are libelous, defamatory, obscene, false, misleading, or -otherwise illegal or unlawful. You agree that the New Creations will not be -downloaded, shipped, transferred, exported, or re-exported into any country -in violation of the United States Export Administration Act (or any other law -governing such matters) by you or anyone at your direction, and that you will -not utilize and will not authorize anyone to utilize the New Creations in any -other manner in violation of any applicable law. The New Creations shall not -be downloaded or otherwise exported or re-exported into (or to a national or -resident of) any country to which the United States has embargoed goods or to -anyone or into any country who/that are prohibited, by applicable law, from -receiving such property. You shall not rent, sell, lease, lend, offer on a -pay-per-play basis, or otherwise commercially exploit or commercially -distribute the New Creations. You are permitted to distribute, without any -cost or charge, the New Creations only to other end-users so long as such -distribution is not infringing against any third-party right and otherwise is -not illegal or unlawful. As noted below, in the event you commit any breach -of this Agreement, your license and this Agreement automatically shall -terminate, without notice. +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). -3. Prohibitions with Regard to the Software. You, whether directly or -indirectly, shall not do any of the following acts: +Doom 3 Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. -a. rent the Software; +Doom 3 Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. -b. sell the Software; +You should have received a copy of the GNU General Public License +along with Doom 3 Source Code. If not, see . -c. lease or lend the Software; +In addition, the Doom 3 Source Code is also subject to certain additional terms. +You should have received a copy of these additional terms immediately following +the terms and conditions of the GNU General Public License which accompanied the +Doom 3 Source Code. If not, please request a copy in writing from id Software +at the address below. -d. offer the Software on a pay-per-play basis; +If you have questions concerning this license or the applicable additional terms, +you may contact in writing -e. distribute the Software (except as permitted under Section 5 -hereinbelow); - -f. in any other manner and through any medium whatsoever commercially -exploit the Software or use the Software for any commercial purpose; - -g. disassemble, reverse engineer, decompile, modify (except as permitted -under Section 2 hereinabove) or alter the Software; - -h. translate the Software; - -i. reproduce or copy the Software (except as permitted under Section 5 -hereinbelow); - -j. publicly display the Software; - -k. prepare or develop derivative works based upon the Software; - -l. remove or alter any notices or other markings or legends, such as -trademark or copyright notices, affixed on or within the Software; or - -m. remove, alter, modify, disable, or reduce any of the anti-piracy measures -contained in the Software or in DOOM 3, including, without limitation, -measures relating to multiplayer play. - -4. Prohibition against Cheat Programs. Any attempt by you, either directly -or indirectly, to circumvent or bypass any element of the Software to gain -any advantage in multiplayer play of the Software is a material breach of -this Agreement. It is a material breach of this Agreement for you, whether -directly or indirectly, to create, develop, copy, reproduce, distribute, or -otherwise make any use of any software program or any modification to the -Software ("Cheat Program") itself that enables or allows the user thereof to -obtain an advantage or otherwise exploit another Software player or user when -playing the Software against other players or users on a local area network, -any other network, or on the Internet. Hacking into the executable of the -Software, modification of the Software, or any other use of the Software in -connection with the creation, development, or use of any such unauthorized -Cheat Program is a material breach of this Agreement. Cheat Programs -include, but are not limited to, programs that allow Software players or -users to see through walls or other level geometry; programs that allow -Software players or users to change their rate of speed outside the allowable -limits of the Software; programs that crash either and/or other Software -players, users, PC clients, or network servers; programs that automatically -target other Software players or users (commonly referred to as "aimbots") -that automatically simulate Software player or user input for the purpose of -gaining an advantage over other Software players or users; or any other -program or modification that functions in a similar capacity or allows any -prohibited conduct. - -In the event you breach this Section or otherwise breach this Agreement, your -license and this Agreement automatically shall terminate, without notice, and -you shall have no right to play the Software against other players or make -any other use of the Software. - -5. Permitted Distribution and Copying. So long as this Agreement -accompanies each copy you make of the Software, and so long as you comply -fully at all times with this Agreement, Id Software grants to you the non- -exclusive and limited right to copy the Software and to distribute such -copies of the Software free of charge for non-commercial purposes that shall -include the free-of-charge distribution of copies of the Software as mounted -on the covers of magazines; provided, however, you shall not copy or -distribute the Software in any infringing manner or in any manner that -violates any law or third-party right, and you shall not distribute the -Software together with any material that infringes against any third-party -right or that is libelous, defamatory, obscene, false, misleading, or -otherwise illegal or unlawful. Subject to the terms and conditions of this -Agreement, you also may: (i) download one (1) copy of the Software or copy -the Software from the CD ROM on which you received your copy of the Software -onto your computer RAM; (ii) copy the Software from your computer RAM onto -your computer hard drive; and (iii) make one (1) "backup" or archival copy of -the Software on one (1) hard disk. In exercising your limited rights -hereunder, you shall comply at all times with all applicable laws, -regulations, ordinances, and statutes. Id Software reserves all rights not -granted in this Agreement. You shall not distribute the Software -commercially unless you first enter into a separate contract with Id -Software, on terms and conditions determined in Id Software's sole -discretion, and only upon your receipt of a written agreement executed by an -authorized officer of Id Software. - -6. Intellectual Property Rights. The Software and all copyrights, -trademarks, and all other conceivable intellectual property rights related to -the Software are owned by Id Software and are protected by United States -copyright laws, international treaty provisions, and all applicable law, such -as the Lanham Act. You must treat the Software like any other copyrighted -material, as required by 17 U.S.C. § 101 et seq. and other applicable law. -You agree to use your best efforts to see that any user of the Software -licensed hereunder or the New Creations complies with this Agreement. You -agree that you are receiving a copy of the Software by limited license only -and not by sale and that the "first sale" doctrine of 17 U.S.C. § 109 does -not apply to your receipt or use of the Software. This Section shall survive -the cancellation or termination of this Agreement. - -7. NO ID SOFTWARE WARRANTIES. ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER -EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTY OF -NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE SOFTWARE IMAGES, AND -OTHERWISE. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ID -SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE -WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE SOFTWARE WILL MEET YOUR -SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR -WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD NOT BE RELIED -UPON. This Section shall survive the cancellation or termination of this -Agreement. - -8. Governing Law, Venue, Indemnity, and Liability Limitation. This -Agreement shall be construed in accordance with and governed by the -applicable laws of the State of Texas (but excluding conflicts of laws -principles) and applicable United States federal law. Except as set forth -below, exclusive venue for all litigation regarding this Agreement shall be -in Dallas County, Texas, and you agree to submit to the jurisdiction of the -federal and state courts in Dallas County, Texas, for any such litigation. -You hereby agree to indemnify, defend and hold harmless Id Software and Id -Software's officers, employees, directors, agents, licensees (excluding you), -sub-licensees (excluding you), successors, and assigns from and against all -losses, lawsuits, damages, causes of action, and claims relating to and/or -arising from the New Creations or the distribution or other use of the New -Creations or relating to and/or arising from your breach of this Agreement. -You agree that your unauthorized use of the Software Images or the Software, -or any part thereof, immediately and irreparably may damage Id Software such -that Id Software could not be adequately compensated solely by a monetary -award, and in such event, at Id Software's option, that Id Software shall be -entitled to an injunctive order, in addition to all other available remedies, -including a monetary award, to prohibit such unauthorized use without the -necessity of Id Software posting bond or other security. IN ANY CASE, ID -SOFTWARE AND ID SOFTWARE'S OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, -REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB-LICENSEES (EXCLUDING -YOU), SUCCESSORS, AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF -PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR -PUNITIVE DAMAGES, OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR -BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, -OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE OR ITS RESPECTIVE AGENT(S) HAVE -BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES -ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY. Some -jurisdictions do not allow the exclusion or limitation of incidental or -consequential damages, so the above limitation or exclusion may not apply to -you. This Section shall survive the cancellation or termination of this -Agreement. - -9. United States Government Restricted Rights. To the extent applicable, -the United States Government shall have only those rights to use the Software -as expressly stated and expressly limited and restricted in this Agreement, -as provided in 48 C.F.R. §§ 227.7201 through 227.7204, inclusive. - -10. General Provisions. Neither this Agreement nor any part or portion -hereof shall be assigned or sublicensed by you. Id Software may assign its -rights under this Agreement in its sole discretion. Should any provision of -this Agreement be held to be void, invalid, unenforceable, or illegal by a -court of competent jurisdiction, the validity and enforceability of the other -provisions shall not be affected thereby. If any provision is determined to -be unenforceable by a court of competent jurisdiction, you agree to a -modification of such provision to provide for enforcement of the provision's -intent, to the extent permitted by applicable law. Failure of Id Software to -enforce any provision of this Agreement shall not constitute or be construed -as a waiver of such provision or of the right to enforce such provision. -IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH, OR YOUR BREACH OF ANY TERM OR -PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT -AUTOMATICALLY SHALL TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE MAY PURSUE ALL -RELIEF AND REMEDIES AGAINST YOU THAT ARE AVAILABLE UNDER APPLICABLE LAW -AND/OR THIS AGREEMENT. Immediately upon termination of this Agreement, any -and all rights you are granted hereunder shall terminate, you shall have no -right to use the Software or the New Creations, in any manner, you -immediately shall destroy all copies of the Software and the New Creations in -your possession, custody, or control, and all rights granted hereunder shall -revert, without notice, to and be vested in Id Software. - -YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS -AGREEMENT, AND YOU UNDERSTAND THAT, BY CONTINUING THE DOWNLOAD OR -INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY -PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, -OR OTHER STORAGE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS -AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN, SEPARATE AGREEMENTS, -IF ANY, BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE -STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO RELATING TO THE -SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, -PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, BETWEEN -ID AND YOU RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT. - ------------------------------------------------------------------------------- -REVISED BSD LICENSE: - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. diff --git a/MayaImport.vcproj b/MayaImport.vcproj deleted file mode 100644 index e6a1d0b1c..000000000 --- a/MayaImport.vcproj +++ /dev/null @@ -1,2469 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MayaImport.vcxproj b/MayaImport.vcxproj new file mode 100644 index 000000000..467b187c1 --- /dev/null +++ b/MayaImport.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug with inlines and memory log + Win32 + + + Debug with inlines + Win32 + + + Debug + Win32 + + + Dedicated Debug with inlines + Win32 + + + Dedicated Debug + Win32 + + + Dedicated Release + Win32 + + + Release + Win32 + + + + MayaImport + {49BEC5C6-B964-417A-851E-808886B574F1} + MayaImport + + + + + + + Win32Proj + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + + + + + + + + {49bec5c6-b964-417a-851e-808886b57400} + false + + + + + + \ No newline at end of file diff --git a/MayaImport.vcxproj.filters b/MayaImport.vcxproj.filters new file mode 100644 index 000000000..f5ae3a874 --- /dev/null +++ b/MayaImport.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + + + Maya6.0 + + + + + + + + + + + + {f8291648-d816-40dc-b1a6-8d7940ec7696} + + + \ No newline at end of file diff --git a/MayaImport/Maya4.5/maya.h b/MayaImport/Maya4.5/maya.h deleted file mode 100644 index 91ad4ba4b..000000000 --- a/MayaImport/Maya4.5/maya.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifdef _WIN32 - -#define _BOOL - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef _BOOL - -#endif // _WIN32 diff --git a/MayaImport/exporter.h b/MayaImport/exporter.h index 9f03a9879..b91fa8c92 100644 --- a/MayaImport/exporter.h +++ b/MayaImport/exporter.h @@ -1,3 +1,21 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #define MAYA_DEFAULT_CAMERA "camera1" #define ANIM_TX BIT( 0 ) diff --git a/MayaImport/maya5.0/maya.h b/MayaImport/maya5.0/maya.h deleted file mode 100644 index cd007cb75..000000000 --- a/MayaImport/maya5.0/maya.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifdef _WIN32 - -#define _BOOL - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef _BOOL - -#endif // _WIN32 diff --git a/MayaImport/maya_main.cpp b/MayaImport/maya_main.cpp index 7da5503dc..aa27c0344 100644 --- a/MayaImport/maya_main.cpp +++ b/MayaImport/maya_main.cpp @@ -1,3 +1,21 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -3129,4 +3147,4 @@ const exporterShutdown_t ValidateShutdown = &Maya_Shutdown; bool FileVersionList(const char *str, bool state) { return true; -} \ No newline at end of file +} diff --git a/MayaImport/maya_main.h b/MayaImport/maya_main.h index b39783987..0fe47cfe7 100644 --- a/MayaImport/maya_main.h +++ b/MayaImport/maya_main.h @@ -1,17 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/11/28 18:30:46 sparhawk - * SDK V2 merge - * - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __MAYA_MAIN_H__ #define __MAYA_MAIN_H__ diff --git a/README.linux b/README.linux deleted file mode 100644 index e51cca769..000000000 --- a/README.linux +++ /dev/null @@ -1,109 +0,0 @@ - -Compiling DarkMod on 32 bit Linux -================================= - -For compilation under Linux, you need the following including their -prerequisites: - - * SCONS - * Python - * libdevil-dev - * libdevil1c2 - -In addition, when running Doom and using the DarkMod, you will also need: - - * libmng1 - -To actually compile, you can use the script: - - ./linuxBuild.sh - -If you have less than 2 Gbyte memory, you might want to remove the "-j2" -switch from the scons line. This switch makes scons run two compiler in -parallel, and this eats quite a lot of memory and can result in very strange -compiling errors. - -Compiling DarkMod on 64 bit Linux -================================= - -If you run a 64 bit Linux distribution, you still need to build a 32 bit -version of DarkMod, since Doom3 itself only exists as a 32 bit version. - -To get this to work, you will need to install the 32 bit compatibility libraries. - -Under some distributions like SuSE these are installed by default, but on -Ubuntu/Kubuntu, you need to install the following: - - * ia32 or ia32-libs - -In addition to this, you will also need libdevil-dev, libmng1 and libdevil1c2. -However, these libraries do not come in a compatibility version, only in different -versions for each architecture. - -This means if you install them the regular way with your package manager, you -will automatically get the 64 bit libraries (f.i. amd64) on your system and this -will cause errors like the following: - - ... lib/bv/frustum_gcc.os -lIL - /usr/bin/ld: skipping incompatible /usr/bin/../lib/libIL.so when searching for -lIL - /usr/bin/ld: skipping incompatible /usr/bin/../lib/libIL.a when searching for -lIL - /usr/bin/ld: skipping incompatible /usr/lib/libIL.so when searching for -lIL - /usr/bin/ld: skipping incompatible /usr/lib/libIL.a when searching for -lIL - /usr/bin/ld: cannot find -lI - -To avoid this, fetch the i368 .deb package files from http://www.rpmseek.com/ -and unzip them manually: - - libdevil1c2_1.6.7-5_i386.deb - libdevil-dev_1.6.7-5_i386.deb - libmng1_1.0.9-1_i386.deb - libstdc++6_4.3.2-2_i386.deb - -You might get slightly newer versions, but it should work. Note that this -list doesn't include the -dev variants, you should be able to just install the -matching 64 bit developer packages. - -Then, as root, copy all the files that are in these packages under ./usr to your -/lib32 directory. - -Also, make sure that you rename the libstdc++6_4.3_..._.so etc. file to -just the basename like so: - - /lib32/libstdc++.so - -Then run: - - ./linuxBuild.sh - -It will pick up the correct libraries. Likewise, when running, Doom3 will -also use the right 32bit libraries. - -greebo: I had to install a few more packages to get TDM to compile in Ubuntu 8.10: - - libglew1.5-dev - libc6-dev-i386 (to fix errors about gnu/stubs-32.h missing) - -Troubleshooting -=============== - -Linker errors -------------- - -If you still get linker errors from ld, please make sure that the libraries -can be found under the right name under /lib32. Also, running: - - su ldconfig - -might help. - -Scons errors ------------- - -If you get errors from scons like this: - - scons: *** object of type 'int' has no len() - -then delete the sqlite database file(s) might help: - - rm cons.signatures.dblite - diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..f12fbce21 --- /dev/null +++ b/README.txt @@ -0,0 +1,435 @@ +Doom 3 GPL source release +========================= + +This file contains the following sections: + +GENERAL NOTES +LICENSE + +GENERAL NOTES +============= + +Game data and patching: +----------------------- + +This source release does not contain any game data, the game data is still +covered by the original EULA and must be obeyed as usual. + +You must patch the game to the latest version. + +Note that Doom 3 and Doom 3: Resurrection of Evil are available from the Steam store at +http://store.steampowered.com/app/9050/ +http://store.steampowered.com/app/9070/ + +Other platforms, updated source code, security issues: +------------------------------------------------------ + +If you have obtained this source code several weeks after the time of release, +it is likely that you can find modified and improved +versions of the engine in various open source projects across the internet. +Depending what is your interest with the source code, those may be a better +starting point. + +Compiling on win32: +------------------- + +A project file for Microsoft Visual Studio 2010 is provided in neo\doom.sln +We expect the solution file is compatible with the Express releases + +You will need the Microsoft DirectX SDK installed as well. +If it does not reside in "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)" +you will need to update the project files accordingly. + +Compiling on GNU/Linux x86: +--------------------------- + +The build system on GNU/Linux is based on SCons: http://www.scons.org/ +Issue the scons command in the neo/ folder. + +Compiling on MacOS X: +--------------------------- + +XCode 3.2 project is under neo/sys/osx/ + +Back End Rendering of Stencil Shadows: +-------------------------------------- + +The Doom 3 GPL source code release does not include functionality enabling rendering +of stencil shadows via the “depth fail” method, a functionality commonly known as +"Carmack's Reverse". + +MayaImport: +--------------------------- + +The code for our Maya export plugin is included, if you are a Maya licensee +you can obtain the SDK from Autodesk. + + +LICENSE +======= + +See COPYING.txt for the GNU GENERAL PUBLIC LICENSE + +ADDITIONAL TERMS: The Doom 3 GPL Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU GPL which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +EXCLUDED CODE: The code described below and contained in the Doom 3 GPL Source Code release is not part of the Program covered by the GPL and is expressly excluded from its terms. You are solely responsible for obtaining from the copyright holder a license for such code and complying with the applicable license terms. + +Curl library +--------------------------------------------------------------------------- +lines file(s) + neo/curl/*, neo/curl/README + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2004, Daniel Stenberg, . + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 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. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. + +JPEG library +----------------------------------------------------------------------------- +neo/renderer/jpeg-6/* + +Copyright (C) 1991-1995, Thomas G. Lane + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +NOTE: unfortunately the README that came with our copy of the library has +been lost, so the one from release 6b is included instead. There are a few +'glue type' modifications to the library to make it easier to use from +the engine, but otherwise the dependency can be easily cleaned up to a +better release of the library. + +OggVorbis +--------------------------------------------------------------------------- +neo/sound/OggVorbis/* +neo/sound/OggVorbis/ogg/README +neo/sound/OggVorbis/vorbis/README + +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +PropTree +--------------------------------------------------------------------------- +neo/tools/common/PropTree/* + +Copyright (C) 1998-2001 Scott Ramsay +sramsay@gonavi.com +http://www.gonavi.com + +This material is provided "as is", with absolutely no warranty expressed +or implied. Any use is at your own risk. + +Permission to use or copy this software for any purpose is hereby granted +without fee, provided the above notices are retained on all copies. +Permission to modify the code and to distribute modified code is granted, +provided the above notices are retained, and a notice that the code was +modified is included with the above copyright notice. + +If you use this code, drop me an email. I'd like to know if you find the code +useful. + +OpenAL SDK +--------------------------------------------------------------------------- +neo/openal/docs/* +neo/openal/include/* +neo/openal/lib/* +neo/openal/osx/* + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +Base64 implementation +--------------------------------------------------------------------------- +lines file(s) +234 neo/idlib/Base64.cpp + +Copyright (c) 1996 Lars Wirzenius. All rights reserved. + +June 14 2003: TTimo + modified + endian bug fixes + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=197039 + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +IO on .zip files using portions of zlib +--------------------------------------------------------------------------- +lines file(s) +4471 src/framework/Unzip.cpp +Copyright (C) 1998 Gilles Vollant +zlib is Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +MD4 Message-Digest Algorithm +----------------------------------------------------------------------------- +lines file(s) +260 neo/idlib/hashing/MD4.cpp +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD4 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD4 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +MD5 Message-Digest Algorithm +----------------------------------------------------------------------------- +lines file(s) +273 neo/idlib/hashing/MD5.cpp +This code implements the MD5 message-digest algorithm. +The algorithm is due to Ron Rivest. This code was +written by Colin Plumb in 1993, no copyright is claimed. +This code is in the public domain; do with it what you wish. + +CRC32 Checksum +----------------------------------------------------------------------------- +lines file(s) +168 neo/idlib/hashing/CRC32.cpp +Copyright (C) 1995-1998 Mark Adler + +OpenGL headers +--------------------------------------------------------------------------- +lines file(s) +5920 neo/renderer/glext.h +613 neo/renderer/wglext.h + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +NV-CONTROL X Extension +--------------------------------------------------------------------------- +neo/sys/linux/libXNVCtrl/* +Copyright NVIDIA Corporation + +ExtUtil.h +--------------------------------------------------------------------------- +neo/sys/linux/extutil.h +/* + * $Xorg: extutil.h,v 1.4 2001/02/09 02:03:24 xorgcvs Exp $ + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the 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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT The Open Group + * + * Xlib Extension-Writing Utilities + * + * This package contains utilities for writing the client API for various + * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND + * ARE SUBJECT TO CHANGE! + */ + +OSS headers +--------------------------------------------------------------------------- +neo/sys/linux/oss/* +Copyright by 4Front Technologies 1993-2004 + +Brandelf utility +--------------------------------------------------------------------------- +lines file(s) +225 neo/sys/linux/setup/brandelf.c + +/*- + * Copyright (c) 1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/usr.bin/brandelf/brandelf.c,v 1.16 2000/07/02 03:34:08 imp Exp $ + */ + +makeself - Make self-extractable archives on Unix +--------------------------------------------------------------------------- +neo/sys/linux/setup/makeself/*, neo/sys/linux/setup/makeself/README +Copyright (c) Stéphane Peter +Licensing: GPL v2 diff --git a/SConstruct b/SConstruct index 40acd56c2..1f02a92d8 100644 --- a/SConstruct +++ b/SConstruct @@ -3,7 +3,7 @@ # TTimo # http://scons.sourceforge.net -import sys, os, time, commands, re, pickle, StringIO, commands, pdb, zipfile, string +import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string import SCons sys.path.append( 'sys/scons' ) @@ -15,7 +15,7 @@ conf_filename='site.conf' serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'IDNET_HOST', 'GL_HARDLINK', 'DEDICATED', 'DEBUG_MEMORY', 'LIBC_MALLOC', 'ID_NOLANADDRESS', 'ID_MCHECK', 'ALSA', 'TARGET_CORE', 'TARGET_GAME', 'TARGET_MONO', 'TARGET_DEMO', 'NOCURL', - 'BUILD_ROOT', 'BUILD_GAMEPAK', 'BASEFLAGS', 'MACOSX_TARGET_ARCH'] + 'BUILD_ROOT', 'BUILD_GAMEPAK', 'BASEFLAGS', 'SILENT' ] # global build mode ------------------------------ @@ -23,8 +23,6 @@ g_sdk = not os.path.exists( 'sys/scons/SConscript.core' ) # ------------------------------------------------ -EnsureSConsVersion( 0, 98 ) - # help ------------------------------------------- help_string = """ @@ -52,8 +50,6 @@ BUILD (default debug) debug-all: no optimisations, debugging symbols debug: -O -g release: all optimisations, including CPU target etc. - profile: gcc only: compile with "-pg" to build a profiling build for use with gprof - (consider using oprofile instead of gprof, tho) BUILD_ROOT (default 'build') change the build root directory @@ -69,6 +65,9 @@ BASEFLAGS (default '') NOCONF (default 0, not saved) ignore site configuration and use defaults + command line only + +SILENT ( default 0, saved ) + hide the compiler output, unless error """ if ( not g_sdk ): @@ -125,17 +124,18 @@ SDK (default 0, not saved) NOCURL (default 0) set to 1 to disable usage of libcurl and http/ftp downloads feature - -MACOSX_TARGET_ARCH (default 'i386') - The target architecture when building in Mac OS X. - valid values: 'ppc' or 'i386'. - """ Help( help_string ) # end help --------------------------------------- +# sanity ----------------------------------------- + +EnsureSConsVersion( 0, 96 ) + +# end sanity ------------------------------------- + # system detection ------------------------------- # CPU type @@ -149,11 +149,7 @@ else: cpu = 'ppc' else: cpu = 'cpu' - -if sys.platform == 'darwin': - g_os = 'MacOSX' -else: - g_os = 'Linux' +g_os = 'Linux' # end system detection --------------------------- @@ -182,7 +178,7 @@ NOCONF = '0' NOCURL = '0' BUILD_GAMEPAK = '0' BASEFLAGS = '' -MACOSX_TARGET_ARCH = 'i386' +SILENT = '0' # end default settings --------------------------- @@ -246,7 +242,6 @@ if ( g_sdk or SDK != '0' ): g_build = BUILD_ROOT + '/' + BUILD SConsignFile( 'scons.signatures' ) -Decider('MD5-timestamp') if ( GL_HARDLINK != '0' ): g_build += '-hardlink' @@ -264,7 +259,7 @@ LINK = CXX # common flags # BASE + CORE + OPT for engine # BASE + GAME + OPT for game -# _noopt versions of the environments are built without the OPT +# _noopt versions of the environements are built without the OPT BASECPPFLAGS = [ ] CORECPPPATH = [ ] @@ -281,45 +276,23 @@ BASECPPFLAGS.append( BASEFLAGS ) BASECPPFLAGS.append( '-pipe' ) # warn all BASECPPFLAGS.append( '-Wall' ) - -# Don't throw warnings for unknown pragmas (used by VC++) -BASECPPFLAGS.append('-Wno-unknown-pragmas') -BASECPPFLAGS.append('-Wno-non-virtual-dtor') - +BASECPPFLAGS.append( '-Wno-unknown-pragmas' ) # this define is necessary to make sure threading support is enabled in X CORECPPFLAGS.append( '-DXTHREADS' ) - # don't wrap gcc messages BASECPPFLAGS.append( '-fmessage-length=0' ) +# gcc 4.0 +BASECPPFLAGS.append( '-fpermissive' ) -if ( g_os == 'Linux' or g_os == 'MacOSX' ): +if ( g_os == 'Linux' ): # gcc 4.x option only - only export what we mean to from the game SO BASECPPFLAGS.append( '-fvisibility=hidden' ) - # get the 64 bit machines on the distcc array to produce 32 bit binaries :) + # get the 64 bits machine on the distcc array to produce 32 bit binaries :) BASECPPFLAGS.append( '-m32' ) BASELINKFLAGS.append( '-m32' ) -# BASELINKFLAGS.append( '-Wl,-z,defs' ) - if g_os == 'Linux': - # help 64 bit machines to find the compatibility 32bit libraries - BASELINKFLAGS.append( '-L/lib32' ) - BASELINKFLAGS.append( '-L/usr/lib32' ) - BASELINKFLAGS.append( '-L/usr/lib32/gcc/i486-linux-gnu/4.2/' ) - - # Add the __linux__ define - BASECPPFLAGS.append('-D__linux__') - else: - # Mac OS X - BASECPPFLAGS.append('-DMACOS_X') - - if MACOSX_TARGET_ARCH == 'i386': - # Perform an Intel build - BASECPPFLAGS.append(['-arch', 'i386', '-D__i386__']) - BASELINKFLAGS.append(['-arch', 'i386']) - elif MACOSX_TARGET_ARCH == 'ppc': - # Perform a PowerPC build - BASECPPFLAGS.append(['-arch', 'ppc', '-D__ppc__']) - BASELINKFLAGS.append(['-arch', 'ppc']) +if ( g_sdk or SDK != '0' ): + BASECPPFLAGS.append( '-D_D3SDK' ) if ( BUILD == 'debug-all' ): OPTCPPFLAGS = [ '-g', '-D_DEBUG' ] @@ -327,33 +300,16 @@ if ( BUILD == 'debug-all' ): ID_MCHECK = '1' elif ( BUILD == 'debug' ): OPTCPPFLAGS = [ '-g', '-O1', '-D_DEBUG' ] - if ( ID_MCHECK == '0' ): - ID_MCHECK = '1' -elif ( BUILD == 'profile' ): - print 'Building a profile build.' - OPTCPPFLAGS = [ '-pg', '-O3', '-ffast-math', '-fno-unsafe-math-optimizations' ] - - if g_os == 'Linux': - OPTCPPFLAGS.append( ['-march=pentium3'] ) - if ( ID_MCHECK == '0' ): ID_MCHECK = '1' elif ( BUILD == 'release' ): # -fomit-frame-pointer: "-O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging." - # on x86 have to set it explicitly + # on x86 have to set it explicitely # -finline-functions: implicit at -O3 # -fschedule-insns2: implicit at -O2 # no-unsafe-math-optimizations: that should be on by default really. hit some wonko bugs in physics code because of that - - # Flags applicable to both Linux and MacOSX - OPTCPPFLAGS = [ '-O3', '-ffast-math', '-fno-unsafe-math-optimizations', '-fomit-frame-pointer' ] - - # greebo: Add the NDEBUG define to void-ify the assert() expressions - OPTCPPFLAGS.append( ['-DNDEBUG'] ) - - if g_os == 'Linux': - OPTCPPFLAGS.append( ['-march=pentium3'] ) - + # greebo: Took out -Winline, this is spamming real hard + OPTCPPFLAGS = [ '-O3', '-march=pentium3', '-ffast-math', '-fno-unsafe-math-optimizations', '-fomit-frame-pointer' ] if ( ID_MCHECK == '0' ): ID_MCHECK = '2' else: @@ -382,18 +338,12 @@ if ( ID_MCHECK == '1' ): g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH ) scons_utils.SetupUtils( g_base_env ) -g_base_env.Append(CPPPATH = '#/include') -g_base_env.Append(CPPPATH = '#/include/zlib') -g_base_env.Append(CPPPATH = '#/include/minizip') +g_base_env.Append(CPPPATH = '#/include') +g_base_env.Append(CPPPATH = '#/include/zlib') +g_base_env.Append(CPPPATH = '#/include/minizip') g_base_env.Append(CPPPATH = '#/include/devil') g_base_env.Append(CPPPATH = '#/') -# greebo: Help finding the openGL headers in OS X, for Leopard I had these in X11's include folder -if g_os == 'MacOSX': - g_base_env.Append(CPPPATH = '/Developer/SDKs/MacOSX10.6.sdk/usr/X11/include/') - -g_base_env.Append(CPPDEFINES = 'SUPPRESS_CONSOLE_WARNINGS') - g_env = g_base_env.Clone() g_env['CPPFLAGS'] += OPTCPPFLAGS @@ -404,7 +354,6 @@ g_env_noopt = g_base_env.Clone() g_env_noopt['CPPFLAGS'] += CORECPPFLAGS g_game_env = g_base_env.Clone() - g_game_env['CPPFLAGS'] += OPTCPPFLAGS g_game_env['CPPFLAGS'] += GAMECPPFLAGS @@ -415,8 +364,11 @@ g_game_env.Append( CPPFLAGS = '-fno-strict-aliasing' ) if ( int(JOBS) > 1 ): print 'Using buffered process output' - scons_utils.SetupBufferedOutput( g_env ) - scons_utils.SetupBufferedOutput( g_game_env ) + silent = False + if ( SILENT == '1' ): + silent = True + scons_utils.SetupBufferedOutput( g_env, silent ) + scons_utils.SetupBufferedOutput( g_game_env, silent ) # mark the globals @@ -466,9 +418,9 @@ if ( TARGET_CORE == '1' ): local_dedicated = 0 Export( 'GLOBALS ' + GLOBALS ) - BuildDir( g_build + '/core/glimp', '.', duplicate = 1 ) + VariantDir( g_build + '/core/glimp', '.', duplicate = 1 ) SConscript( g_build + '/core/glimp/sys/scons/SConscript.gl' ) - BuildDir( g_build + '/core', '.', duplicate = 0 ) + VariantDir( g_build + '/core', '.', duplicate = 0 ) idlib_objects = SConscript( g_build + '/core/sys/scons/SConscript.idlib' ) Export( 'GLOBALS ' + GLOBALS ) # update idlib_objects doom = SConscript( g_build + '/core/sys/scons/SConscript.core' ) @@ -479,16 +431,16 @@ if ( TARGET_CORE == '1' ): local_dedicated = 1 Export( 'GLOBALS ' + GLOBALS ) - BuildDir( g_build + '/dedicated/glimp', '.', duplicate = 1 ) + VariantDir( g_build + '/dedicated/glimp', '.', duplicate = 1 ) SConscript( g_build + '/dedicated/glimp/sys/scons/SConscript.gl' ) - BuildDir( g_build + '/dedicated', '.', duplicate = 0 ) + VariantDir( g_build + '/dedicated', '.', duplicate = 0 ) idlib_objects = SConscript( g_build + '/dedicated/sys/scons/SConscript.idlib' ) Export( 'GLOBALS ' + GLOBALS ) doomded = SConscript( g_build + '/dedicated/sys/scons/SConscript.core' ) InstallAs( '#doomded.' + cpu, doomded ) -if ( TARGET_GAME == '1'): +if ( TARGET_GAME == '1' ): local_gamedll = 1 local_demo = 0 local_dedicated = 0 @@ -500,42 +452,25 @@ if ( TARGET_GAME == '1'): # clear the build directory to be safe g_env.PreBuildSDK( [ g_build + '/game' ] ) dupe = 1 - - BuildDir( g_build + '/game', '.', duplicate = dupe ) - - if g_os == 'MacOSX': - game_binary_name = '#game%s-base.dylib' % MACOSX_TARGET_ARCH - else: - # Linux - game_binary_name = '#game%s-base.so' % cpu - + VariantDir( g_build + '/game', '.', duplicate = dupe ) idlib_objects = SConscript( g_build + '/game/sys/scons/SConscript.idlib' ) - - Export( 'GLOBALS ' + GLOBALS ) - game = SConscript( g_build + '/game/sys/scons/SConscript.game' ) - - game_base = InstallAs( game_binary_name, game ) - - # Game PAK name - if ( BUILD_GAMEPAK == '1' ): - if g_os == 'MacOSX': - game_pak = '#tdm_game03.pk4' - else: - game_pak = '#tdm_game02.pk4' - - Command( game_pak, [ game_base, game ], Action( g_env.BuildGamePak ) ) - - # End TARGET_GAME + if ( TARGET_GAME == '1' ): + Export( 'GLOBALS ' + GLOBALS ) + game = SConscript( g_build + '/game/sys/scons/SConscript.game' ) + game_base = InstallAs( '#game%s-base.so' % cpu, game ) + if ( BUILD_GAMEPAK == '1' ): + Command( '#game01-base.pk4', [ game_base, game ], Action( g_env.BuildGamePak ) ) if ( TARGET_MONO == '1' ): + # NOTE: no D3XP atm. add a TARGET_MONO_D3XP local_gamedll = 0 local_dedicated = 0 local_demo = 0 local_idlibpic = 0 Export( 'GLOBALS ' + GLOBALS ) - BuildDir( g_build + '/mono/glimp', '.', duplicate = 1 ) + VariantDir( g_build + '/mono/glimp', '.', duplicate = 1 ) SConscript( g_build + '/mono/glimp/sys/scons/SConscript.gl' ) - BuildDir( g_build + '/mono', '.', duplicate = 0 ) + VariantDir( g_build + '/mono', '.', duplicate = 0 ) idlib_objects = SConscript( g_build + '/mono/sys/scons/SConscript.idlib' ) game_objects = SConscript( g_build + '/mono/sys/scons/SConscript.game' ) Export( 'GLOBALS ' + GLOBALS ) @@ -543,6 +478,7 @@ if ( TARGET_MONO == '1' ): InstallAs( '#doom-mon.' + cpu, doom_mono ) if ( TARGET_DEMO == '1' ): + # NOTE: no D3XP atm. add a TARGET_DEMO_D3XP local_demo = 1 local_dedicated = 0 local_gamedll = 1 @@ -550,9 +486,9 @@ if ( TARGET_DEMO == '1' ): local_curl = 0 curl_lib = [] Export( 'GLOBALS ' + GLOBALS ) - BuildDir( g_build + '/demo/glimp', '.', duplicate = 1 ) + VariantDir( g_build + '/demo/glimp', '.', duplicate = 1 ) SConscript( g_build + '/demo/glimp/sys/scons/SConscript.gl' ) - BuildDir( g_build + '/demo', '.', duplicate = 0 ) + VariantDir( g_build + '/demo', '.', duplicate = 0 ) idlib_objects = SConscript( g_build + '/demo/sys/scons/SConscript.idlib' ) Export( 'GLOBALS ' + GLOBALS ) doom_demo = SConscript( g_build + '/demo/sys/scons/SConscript.core' ) @@ -561,7 +497,7 @@ if ( TARGET_DEMO == '1' ): local_idlibpic = 1 Export( 'GLOBALS ' + GLOBALS ) - BuildDir( g_build + '/demo/game', '.', duplicate = 0 ) + VariantDir( g_build + '/demo/game', '.', duplicate = 0 ) idlib_objects = SConscript( g_build + '/demo/game/sys/scons/SConscript.idlib' ) Export( 'GLOBALS ' + GLOBALS ) game_demo = SConscript( g_build + '/demo/game/sys/scons/SConscript.game' ) @@ -570,6 +506,10 @@ if ( TARGET_DEMO == '1' ): if ( SETUP != '0' ): brandelf = Program( 'brandelf', 'sys/linux/setup/brandelf.c' ) + if ( TARGET_CORE == '1' and TARGET_GAME == '1' ): + setup = Command( 'setup', [ brandelf, doom, doomded, game, d3xp ], Action( g_env.BuildSetup ) ) + else: + print 'Skipping main setup: TARGET_CORE == 0 or TARGET_GAME == 0' if ( TARGET_DEMO == '1' ): setup_demo = Command( 'setup-demo', [ brandelf, doom_demo, game_demo ], Action( g_env.BuildSetup ) ) # if building two setups, make sure JOBS doesn't parallelize them @@ -582,6 +522,6 @@ if ( SETUP != '0' ): if ( SDK != '0' ): setup_sdk = Command( 'sdk', [ ], Action( g_env.BuildSDK ) ) - g_env.Depends( setup_sdk, [ game ] ) + g_env.Depends( setup_sdk, [ game, d3xp ] ) # end targets ------------------------------------ diff --git a/TypeInfo/TypeInfoGen.cpp b/TypeInfo/TypeInfoGen.cpp new file mode 100644 index 000000000..756c0cd80 --- /dev/null +++ b/TypeInfo/TypeInfoGen.cpp @@ -0,0 +1,1041 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "TypeInfoGen.h" + +#define TYPE_INFO_GEN_VERSION "1.0" + +/* +================ +idTypeInfoGen::idTypeInfoGen +================ +*/ +idTypeInfoGen::idTypeInfoGen( void ) { +} + +/* +================ +idTypeInfoGen::~idTypeInfoGen +================ +*/ +idTypeInfoGen::~idTypeInfoGen( void ) { + constants.DeleteContents( true ); + enums.DeleteContents( true ); + classes.DeleteContents( true ); +} + +/* +================ +idTypeInfoGen::GetInheritance +================ +*/ +int idTypeInfoGen::GetInheritance( const char *typeName ) const { + int i; + + for ( i = 0; i < classes.Num(); i++ ) { + if ( classes[i]->typeName.Cmp( typeName ) == 0 ) { + if ( classes[i]->superType[0] != '\0' ) { + return 1 + GetInheritance( classes[i]->superType ); + } + break; + } + } + return 0; +} + +/* +================ +idTypeInfoGen::EvaluateIntegerString +================ +*/ +int idTypeInfoGen::EvaluateIntegerString( const idStr &string ) { + idParser src; + idStr evalString; + + if ( string.Find( "::" ) != -1 ) { + return 0; + } + evalString = "$evalint(" + string + ")"; + src.LoadMemory( evalString, evalString.Length(), "eval integer" ); + return src.ParseInt(); +} + +/* +================ +idTypeInfoGen::EvaluateFloatString +================ +*/ +float idTypeInfoGen::EvaluateFloatString( const idStr &string ) { + idParser src; + idStr evalString; + + if ( string.Find( "::" ) != -1 ) { + return 0.0f; + } + evalString = "$evalfloat(" + string + ")"; + src.LoadMemory( evalString, evalString.Length(), "eval float" ); + return src.ParseFloat(); +} + +/* +================ +idTypeInfoGen::FindConstant +================ +*/ +idConstantInfo *idTypeInfoGen::FindConstant( const char *name ) { + int i; + + for ( i = 0; i < constants.Num(); i++ ) { + if ( constants[i]->name.Cmp( name ) == 0 ) { + return constants[i]; + } + } + return NULL; +} + +/* +================ +idTypeInfoGen::GetIntegerConstant +================ +*/ +int idTypeInfoGen::GetIntegerConstant( const char *scope, const char *name, idParser &src ) { + idConstantInfo *constant = FindConstant( idStr( scope ) + name ); + if ( constant == NULL ) { + constant = FindConstant( name ); + } + if ( constant ) { + return EvaluateIntegerString( constant->value ); + } + src.Warning( "unknown value '%s' in constant expression", name ); + return 0; +} + +/* +================ +idTypeInfoGen::GetFloatConstant +================ +*/ +float idTypeInfoGen::GetFloatConstant( const char *scope, const char *name, idParser &src ) { + idConstantInfo *constant = FindConstant( idStr( scope ) + name ); + if ( constant == NULL ) { + constant = FindConstant( name ); + } + if ( constant ) { + return EvaluateFloatString( constant->value ); + } + src.Warning( "unknown value '%s' in constant expression", name ); + return 0; +} + +/* +================ +idTypeInfoGen::ParseArraySize +================ +*/ +int idTypeInfoGen::ParseArraySize( const char *scope, idParser &src ) { + idToken token; + idStr sizeString, constantString; + int size, totalSize; + + if ( !src.CheckTokenString( "[" ) ) { + return 0; + } + + totalSize = 1; + sizeString = ""; + while( src.ReadToken( &token ) ) { + if ( token == "]" ) { + if ( sizeString.Length() ) { + size = EvaluateIntegerString( sizeString ); + if ( size ) { + totalSize *= size; + } + sizeString = ""; + } + if ( !src.CheckTokenString( "[" ) ) { + break; + } + } else if ( token.type == TT_NAME ) { + constantString = token; + while( src.CheckTokenString( "::" ) ) { + src.ExpectTokenType( TT_NAME, 0, &token ); + constantString += "::" + token; + } + sizeString += va( "%d", GetIntegerConstant( scope, constantString, src ) ); + } else { + sizeString += token; + } + } + + return totalSize; +} + +/* +================ +idTypeInfoGen::ParseConstantValue +================ +*/ +void idTypeInfoGen::ParseConstantValue( const char *scope, idParser &src, idStr &value ) { + idToken token; + idStr constantString; + + int indent = 0; + while( src.ReadToken( &token ) ) { + if ( token == "(" ) { + indent++; + } else if ( token == ")" ) { + indent--; + } else if ( indent == 0 && ( token == ";" || token == "," || token == "}" ) ) { + src.UnreadToken( &token ); + break; + } else if ( token.type == TT_NAME ) { + constantString = token; + while( src.CheckTokenString( "::" ) ) { + src.ExpectTokenType( TT_NAME, 0, &token ); + constantString += "::" + token; + } + value += va( "%d", GetIntegerConstant( scope, constantString, src ) ); + continue; + } + value += token; + } +} + +/* +================ +idTypeInfoGen::ParseEnumType +================ +*/ +idEnumTypeInfo *idTypeInfoGen::ParseEnumType( const char *scope, bool isTemplate, bool typeDef, idParser &src ) { + int value; + idToken token; + idEnumTypeInfo *typeInfo; + idEnumValueInfo enumValue; + idStr valueString; + + typeInfo = new idEnumTypeInfo; + typeInfo->scope = scope; + typeInfo->isTemplate = isTemplate; + + if ( src.CheckTokenType( TT_NAME, 0, &token ) ) { + typeInfo->typeName = token; + typeInfo->unnamed = false; + } else { + sprintf( typeInfo->typeName, "enum_%d", enums.Num() ); + typeInfo->unnamed = true; + } + + if ( !src.CheckTokenString( "{" ) ) { + src.UnreadToken( &token ); + delete typeInfo; + return NULL; + } + + value = -1; + while( src.ExpectTokenType( TT_NAME, 0, &token ) ) { + + enumValue.name = token; + + if ( src.CheckTokenString( "=" ) ) { + idStr valueString; + ParseConstantValue( scope, src, valueString ); + if ( valueString.Length() ) { + value = EvaluateIntegerString( valueString ); + } + } else { + value++; + } + + enumValue.value = value; + typeInfo->values.Append( enumValue ); + + // add a constant for the enum value + idConstantInfo *constantInfo = new idConstantInfo; + constantInfo->name = scope + enumValue.name; + constantInfo->type = "int"; + constantInfo->value = va( "%d", value ); + constants.Append( constantInfo ); + + src.CheckTokenString( "," ); + + if ( src.CheckTokenString( "}" ) ) { + break; + } + } + + if ( typeDef ) { + if ( src.CheckTokenType( TT_NAME, 0, &token ) ) { + typeInfo->typeName = token; + typeInfo->unnamed = false; + } + src.ExpectTokenString( ";" ); + } + + //common->Printf( "enum %s%s\n", typeInfo->scope.c_str(), typeInfo->typeName.c_str() ); + + return typeInfo; +} + +/* +================ +idTypeInfoGen::ParseClassType +================ +*/ +idClassTypeInfo *idTypeInfoGen::ParseClassType( const char *scope, const char *templateArgs, bool isTemplate, bool typeDef, idParser &src ) { + idToken token; + idClassTypeInfo *typeInfo; + + typeInfo = new idClassTypeInfo; + typeInfo->scope = scope; + typeInfo->isTemplate = isTemplate; + + if ( src.CheckTokenType( TT_NAME, 0, &token ) ) { + typeInfo->typeName = token + templateArgs; + typeInfo->unnamed = false; + } else { + sprintf( typeInfo->typeName, "class_%d%s", classes.Num(), templateArgs ); + typeInfo->unnamed = true; + } + + if ( src.CheckTokenString( ":" ) ) { + if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { + delete typeInfo; + return NULL; + } + while( token == "public" || + token == "protected" || + token == "private" ) { + + if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { + delete typeInfo; + return NULL; + } + + typeInfo->superType = token; + + // read template arguments + if ( src.CheckTokenString( "<" ) ) { + + int indent = 1; + typeInfo->superType += "< "; + while( src.ReadToken( &token ) ) { + if ( token == "<" ) { + indent++; + } else if ( token == ">" ) { + indent--; + if ( indent == 0 ) { + break; + } + } + typeInfo->superType += token + " "; + } + typeInfo->superType += ">"; + } + + // check for multiple inheritance + if ( !src.CheckTokenString( "," ) ) { + break; + } + + if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { + delete typeInfo; + return NULL; + } + + src.Warning( "multiple inheritance not supported for '%s%s'", typeInfo->scope.c_str(), typeInfo->typeName.c_str() ); + } + } + + if ( !src.CheckTokenString( "{" ) ) { + src.UnreadToken( &token ); + delete typeInfo; + return NULL; + } + + ParseScope( typeInfo->scope + typeInfo->typeName + "::", typeInfo->isTemplate, src, typeInfo ); + + if ( typeDef ) { + if ( src.CheckTokenType( TT_NAME, 0, &token ) ) { + typeInfo->typeName = token + templateArgs; + typeInfo->unnamed = false; + } + src.ExpectTokenString( ";" ); + } + + //common->Printf( "class %s%s : %s\n", typeInfo->scope.c_str(), typeInfo->typeName.c_str(), typeInfo->superType.c_str() ); + + return typeInfo; +} + +/* +================ +idTypeInfoGen::ParseScope +================ +*/ +void idTypeInfoGen::ParseScope( const char *scope, bool isTemplate, idParser &src, idClassTypeInfo *typeInfo ) { + int indent; + idToken token; + idClassTypeInfo *classInfo; + idEnumTypeInfo *enumInfo; + idStr varType; + bool isConst = false; + bool isStatic = false; + + indent = 1; + while( indent ) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "{" ) { + + do { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + } + varType += token + " "; + } while( indent > 1 && src.ReadToken( &token ) ); + + } else if ( token == "}" ) { + + assert( indent == 1 ); + indent--; + + } else if ( token == "<" ) { + + do { + if ( token == "<" ) { + indent++; + } else if ( token == ">" ) { + indent--; + } + varType += token + " "; + } while( indent > 1 && src.ReadToken( &token ) ); + + } else if ( token == ";" ) { + + varType = ""; + isConst = false; + isStatic = false; + + } else if ( token == "public" || token == "protected" || token == "private" ) { + + if ( !src.ExpectTokenString( ":" ) ) { + break; + } + varType = ""; + isConst = false; + isStatic = false; + + } else if ( token == "friend" ) { + + // skip friend classes/methods + while( src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + if ( indent == 1 ) { + break; + } + } else if ( token == ";" && indent == 1 ) { + break; + } + } + + varType = ""; + isConst = false; + isStatic = false; + + } else if ( token == "template" ) { + + varType = ""; + + if ( src.CheckTokenString( "<" ) ) { + + int indent = 1; + varType += "< "; + while( src.ReadToken( &token ) ) { + if ( token == "<" ) { + indent++; + } else if ( token == ">" ) { + indent--; + if ( indent == 0 ) { + break; + } + } + varType += token + " "; + } + varType += ">"; + } + + if ( src.CheckTokenString( "class" ) ) { + + // parse template class + classInfo = ParseClassType( scope, varType, true, false, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else { + + // skip template methods + while( src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + if ( indent == 1 ) { + break; + } + } else if ( token == ";" && indent == 1 ) { + break; + } + } + } + + varType = ""; + isConst = false; + isStatic = false; + + } else if ( token == "namespace" ) { + + // parse namespace + classInfo = ParseClassType( scope, "", isTemplate, false, src ); + delete classInfo; + + } else if ( token == "class" ) { + + // parse class + classInfo = ParseClassType( scope, "", isTemplate, false, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else if ( token == "struct" ) { + + // parse struct + classInfo = ParseClassType( scope, "", isTemplate, false, src ); + if ( classInfo ) { + classes.Append( classInfo ); + varType = classInfo->scope + classInfo->typeName; + } + + } else if ( token == "union" ) { + + // parse union + classInfo = ParseClassType( scope, "", isTemplate, false, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else if ( token == "enum" ) { + + // parse enum + enumInfo = ParseEnumType( scope, isTemplate, false, src ); + if ( enumInfo ) { + enums.Append( enumInfo ); + varType = enumInfo->scope + enumInfo->typeName; + } + + } else if ( token == "typedef" ) { + + if ( token == "class" ) { + + // parse typedef class + classInfo = ParseClassType( scope, "", isTemplate, true, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else if ( src.CheckTokenString( "struct" ) ) { + + // parse typedef struct + classInfo = ParseClassType( scope, "", isTemplate, true, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else if ( src.CheckTokenString( "union" ) ) { + + // parse typedef union + classInfo = ParseClassType( scope, "", isTemplate, true, src ); + if ( classInfo ) { + classes.Append( classInfo ); + } + + } else if ( src.CheckTokenString( "enum" ) ) { + + // parse typedef enum + enumInfo = ParseEnumType( scope, isTemplate, true, src ); + if ( enumInfo ) { + enums.Append( enumInfo ); + } + + } else { + + // skip other typedefs + while( src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + } else if ( token == ";" && indent == 1 ) { + break; + } + } + } + + varType = ""; + isConst = false; + isStatic = false; + + } else if ( token == "const" ) { + + varType += token + " "; + isConst = true; + + } else if ( token == "static" ) { + + varType += token + " "; + isStatic = true; + + } else if ( token.type == TT_NAME ) { + + assert( indent == 1 ); + + // if this is a class operator + if ( token == "operator" ) { + while( src.ReadToken( &token ) ) { + if ( token == "(" ) { + src.UnreadToken( &token ); + break; + } + } + } + + // if this is a class method + if ( src.CheckTokenString( "(" ) ) { + + indent++; + while( indent > 1 && src.ReadToken( &token ) ) { + if ( token == "(" ) { + indent++; + } else if ( token == ")" ) { + indent--; + } + } + + if ( src.CheckTokenString( "(" ) ) { + indent++; + while( indent > 1 && src.ReadToken( &token ) ) { + if ( token == "(" ) { + indent++; + } else if ( token == ")" ) { + indent--; + } + } + } + + if ( src.CheckTokenString( "const" ) ) { + } + + if ( src.CheckTokenString( "=" ) ) { + + src.ExpectTokenString( "0" ); + + } else if ( src.CheckTokenString( "{" ) ) { + indent++; + while( indent > 1 && src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + } + } + } + + varType = ""; + isConst = false; + isStatic = false; + + } else if ( ( isStatic || isConst ) && src.CheckTokenString( "=" ) ) { + + // constant + idConstantInfo *constantInfo = new idConstantInfo; + constantInfo->name = scope + token; + constantInfo->type = varType; + constantInfo->type.StripTrailing( ' ' ); + ParseConstantValue( scope, src, constantInfo->value ); + constants.Append( constantInfo ); + + } else if ( isStatic ) { + + // static class variable + varType += token + " "; + + } else { + + // check for class variables + while( 1 ) { + + int arraySize = ParseArraySize( scope, src ); + + if ( arraySize ) { + idClassVariableInfo var; + + var.name = token; + var.type = varType; + var.type.StripTrailing( ' ' ); + var.type += va( "[%d]", arraySize ); + var.bits = 0; + typeInfo->variables.Append( var ); + if ( !src.CheckTokenString( "," ) ) { + varType = ""; + isConst = false; + isStatic = false; + break; + } + varType.StripTrailing( "* " ); + + } else { + + int bits = 0; + + if ( src.CheckTokenString( ":" ) ) { + idToken bitSize; + src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &bitSize ); + bits = bitSize.GetIntValue(); + } + + if ( src.CheckTokenString( "," ) ) { + idClassVariableInfo var; + + var.name = token; + var.type = varType; + var.type.StripTrailing( ' ' ); + var.bits = bits; + typeInfo->variables.Append( var ); + varType.StripTrailing( "* " ); + + } else if ( src.CheckTokenString( ";" ) ) { + idClassVariableInfo var; + + var.name = token; + var.type = varType; + var.type.StripTrailing( ' ' ); + var.bits = bits; + typeInfo->variables.Append( var ); + varType = ""; + isConst = false; + isStatic = false; + break; + + } else { + + varType += token + " "; + break; + } + } + + while( src.CheckTokenString( "*" ) ) { + varType += "* "; + } + + if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { + break; + } + } + } + } else { + varType += token + " "; + } + } +} + +/* +================ +idTypeInfoGen::AddDefine +================ +*/ +void idTypeInfoGen::AddDefine( const char *define ) { + defines.Append( define ); +} + +/* +================ +idTypeInfoGen::CreateTypeInfo +================ +*/ +void idTypeInfoGen::CreateTypeInfo( const char *path ) { + int i, j, inheritance; + idStr fileName; + idFileList *files; + idParser src; + + common->Printf( "Type Info Generator v"TYPE_INFO_GEN_VERSION" (c) 2004 id Software\n" ); + common->Printf( "%s\n", path ); + + files = fileSystem->ListFilesTree( path, ".cpp" ); + + for ( i = 0; i < files->GetNumFiles(); i++ ) { + + fileName = fileSystem->RelativePathToOSPath( files->GetFile( i ) ); + + common->Printf( "processing '%s' for type info...\n", fileName.c_str() ); + + if ( !src.LoadFile( fileName, true ) ) { + common->Warning( "couldn't load %s", fileName.c_str() ); + continue; + } + + src.SetFlags( LEXFL_NOBASEINCLUDES ); + + for ( j = 0; j < defines.Num(); j++ ) { + src.AddDefine( defines[j] ); + } + + idClassTypeInfo *typeInfo = new idClassTypeInfo; + ParseScope( "", false, src, typeInfo ); + delete typeInfo; + + src.FreeSource(); + + break; + } + + fileSystem->FreeFileList( files ); + + numTemplates = 0; + for ( i = 0; i < classes.Num(); i++ ) { + if ( classes[i]->isTemplate ) { + numTemplates++; + } + } + + maxInheritance = 0; + maxInheritanceClass = ""; + for ( i = 0; i < classes.Num(); i++ ) { + inheritance = GetInheritance( classes[i]->typeName ); + if ( inheritance > maxInheritance ) { + maxInheritance = inheritance; + maxInheritanceClass = classes[i]->typeName; + } + } + + common->Printf( "%d constants\n", constants.Num() ); + common->Printf( "%d enums\n", enums.Num() ); + common->Printf( "%d classes/structs/unions\n", classes.Num() ); + common->Printf( "%d templates\n", numTemplates ); + common->Printf( "%d max inheritance level for '%s'\n", maxInheritance, maxInheritanceClass.c_str() ); +} + +/* +================ +CleanName +================ +*/ +void CleanName( idStr &name ) { + name.Replace( "::", "_" ); + name.Replace( " , ", "_" ); + name.Replace( "< ", "_" ); + name.Replace( " >", "_" ); + name.Replace( " ", "_" ); +} + +/* +================ +idTypeInfoGen::WriteTypeInfo +================ +*/ +void idTypeInfoGen::WriteTypeInfo( const char *fileName ) const { + int i, j; + idStr path, define; + idFile *file; + + path = fileSystem->RelativePathToOSPath( fileName ); + + file = fileSystem->OpenExplicitFileWrite( path ); + if ( !file ) { + common->Warning( "couldn't open %s", path.c_str() ); + return; + } + + common->Printf( "writing %s...\n", path.c_str() ); + + path.ExtractFileName( define ); + define.Replace( ".", "_" ); + define.ToUpper(); + + file->WriteFloatString( + "\n" + "#ifndef __%s__\n" + "#define __%s__\n" + "\n" + "/*\n" + "===================================================================================\n" + "\n" + "\tThis file has been generated with the Type Info Generator v"TYPE_INFO_GEN_VERSION" (c) 2004 id Software\n" + "\n" + "\t%d constants\n" + "\t%d enums\n" + "\t%d classes/structs/unions\n" + "\t%d templates\n" + "\t%d max inheritance level for '%s'\n" + "\n" + "===================================================================================\n" + "*/\n" + "\n", define.c_str(), define.c_str(), constants.Num(), enums.Num(), classes.Num(), + numTemplates, maxInheritance, maxInheritanceClass.c_str() ); + + file->WriteFloatString( + "typedef struct {\n" + "\t" "const char * name;\n" + "\t" "const char * type;\n" + "\t" "const char * value;\n" + "} constantInfo_t;\n" + "\n" + "typedef struct {\n" + "\t" "const char * name;\n" + "\t" "int value;\n" + "} enumValueInfo_t;\n" + "\n" + "typedef struct {\n" + "\t" "const char * typeName;\n" + "\t" "const enumValueInfo_t * values;\n" + "} enumTypeInfo_t;\n" + "\n" + "typedef struct {\n" + "\t" "const char * type;\n" + "\t" "const char * name;\n" + "\t" "int offset;\n" + "\t" "int size;\n" + "} classVariableInfo_t;\n" + "\n" + "typedef struct {\n" + "\t" "const char * typeName;\n" + "\t" "const char * superType;\n" + "\t" "int size;\n" + "\t" "const classVariableInfo_t * variables;\n" + "} classTypeInfo_t;\n" + "\n" ); + + // constants + file->WriteFloatString( "static constantInfo_t constantInfo[] = {\n" ); + + for ( i = 0; i < constants.Num(); i++ ) { + idConstantInfo *info = constants[i]; + file->WriteFloatString( "\t{ \"%s\", \"%s\", \"%s\" },\n", info->type.c_str(), info->name.c_str(), info->value.c_str() ); + } + + file->WriteFloatString( "\t{ NULL, NULL, NULL }\n" ); + file->WriteFloatString( "};\n\n" ); + + // enum values + for ( i = 0; i < enums.Num(); i++ ) { + idEnumTypeInfo *info = enums[i]; + + idStr typeInfoName = info->scope + info->typeName; + CleanName( typeInfoName ); + + file->WriteFloatString( "static enumValueInfo_t %s_typeInfo[] = {\n", typeInfoName.c_str() ); + + for ( j = 0; j < info->values.Num(); j++ ) { + if ( info->isTemplate ) { + file->WriteFloatString( "//" ); + } + file->WriteFloatString( "\t{ \"%s\", %d },\n", info->values[j].name.c_str(), info->values[j].value ); + } + + file->WriteFloatString( "\t{ NULL, 0 }\n" ); + file->WriteFloatString( "};\n\n" ); + } + + // enums + file->WriteFloatString( "static enumTypeInfo_t enumTypeInfo[] = {\n" ); + + for ( i = 0; i < enums.Num(); i++ ) { + idEnumTypeInfo *info = enums[i]; + + idStr typeName = info->scope + info->typeName; + idStr typeInfoName = typeName; + CleanName( typeInfoName ); + + if ( info->isTemplate ) { + file->WriteFloatString( "//" ); + } + file->WriteFloatString( "\t{ \"%s\", %s_typeInfo },\n", typeName.c_str(), typeInfoName.c_str() ); + } + + file->WriteFloatString( "\t{ NULL, NULL }\n" ); + file->WriteFloatString( "};\n\n" ); + + // class variables + for ( i = 0; i < classes.Num(); i++ ) { + idClassTypeInfo *info = classes[i]; + + idStr typeName = info->scope + info->typeName; + idStr typeInfoName = typeName; + CleanName( typeInfoName ); + + file->WriteFloatString( "static classVariableInfo_t %s_typeInfo[] = {\n", typeInfoName.c_str() ); + + for ( j = 0; j < info->variables.Num(); j++ ) { + const char *varName = info->variables[j].name.c_str(); + const char *varType = info->variables[j].type.c_str(); + + if ( info->unnamed || info->isTemplate || info->variables[j].bits != 0 ) { + file->WriteFloatString( "//" ); + } + file->WriteFloatString( "\t{ \"%s\", \"%s\", (int)(&((%s *)0)->%s), sizeof( ((%s *)0)->%s ) },\n", + varType, varName, typeName.c_str(), varName, typeName.c_str(), varName ); + } + + file->WriteFloatString( "\t{ NULL, 0 }\n" ); + file->WriteFloatString( "};\n\n" ); + } + + // classes + file->WriteFloatString( "static classTypeInfo_t classTypeInfo[] = {\n" ); + + for ( i = 0; i < classes.Num(); i++ ) { + idClassTypeInfo *info = classes[i]; + + idStr typeName = info->scope + info->typeName; + idStr typeInfoName = typeName; + CleanName( typeInfoName ); + + if ( info->unnamed || info->isTemplate ) { + file->WriteFloatString( "//" ); + } + file->WriteFloatString( "\t{ \"%s\", \"%s\", sizeof(%s), %s_typeInfo },\n", + typeName.c_str(), info->superType.c_str(), typeName.c_str(), typeInfoName.c_str() ); + } + + file->WriteFloatString( "\t{ NULL, NULL, 0, NULL }\n" ); + file->WriteFloatString( "};\n\n" ); + + file->WriteFloatString( "#endif /* !__%s__ */\n", define.c_str() ); + + fileSystem->CloseFile( file ); +} diff --git a/TypeInfo/TypeInfoGen.h b/TypeInfo/TypeInfoGen.h new file mode 100644 index 000000000..6b26d13e6 --- /dev/null +++ b/TypeInfo/TypeInfoGen.h @@ -0,0 +1,107 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __TYPEINFOGEN_H__ +#define __TYPEINFOGEN_H__ + +/* +=================================================================================== + + Type Info Generator + + - template classes are commented out (different instantiations are not identified) + - bit fields are commented out (cannot get the address of bit fields) + - multiple inheritance is not supported (only tracks a single super type) + +=================================================================================== +*/ + +class idConstantInfo { +public: + idStr name; + idStr type; + idStr value; +}; + +class idEnumValueInfo { +public: + idStr name; + int value; +}; + +class idEnumTypeInfo { +public: + idStr typeName; + idStr scope; + bool unnamed; + bool isTemplate; + idList values; +}; + +class idClassVariableInfo { +public: + idStr name; + idStr type; + int bits; +}; + +class idClassTypeInfo { +public: + idStr typeName; + idStr superType; + idStr scope; + bool unnamed; + bool isTemplate; + idList variables; +}; + +class idTypeInfoGen { +public: + idTypeInfoGen( void ); + ~idTypeInfoGen( void ); + + void AddDefine( const char *define ); + void CreateTypeInfo( const char *path ); + void WriteTypeInfo( const char *fileName ) const; + +private: + idStrList defines; + + idList constants; + idList enums; + idList classes; + + int numTemplates; + int maxInheritance; + idStr maxInheritanceClass; + + int GetInheritance( const char *typeName ) const; + int EvaluateIntegerString( const idStr &string ); + float EvaluateFloatString( const idStr &string ); + idConstantInfo * FindConstant( const char *name ); + int GetIntegerConstant( const char *scope, const char *name, idParser &src ); + float GetFloatConstant( const char *scope, const char *name, idParser &src ); + int ParseArraySize( const char *scope, idParser &src ); + void ParseConstantValue( const char *scope, idParser &src, idStr &value ); + idEnumTypeInfo * ParseEnumType( const char *scope, bool isTemplate, bool typeDef, idParser &src ); + idClassTypeInfo * ParseClassType( const char *scope, const char *templateArgs, bool isTemplate, bool typeDef, idParser &src ); + void ParseScope( const char *scope, bool isTemplate, idParser &src, idClassTypeInfo *typeInfo ); +}; + +#endif /* !__TYPEINFOGEN_H__ */ diff --git a/TypeInfo/main.cpp b/TypeInfo/main.cpp new file mode 100644 index 000000000..808dde18f --- /dev/null +++ b/TypeInfo/main.cpp @@ -0,0 +1,298 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#include "../sys/sys_local.h" +#pragma hdrstop + +#include "TypeInfoGen.h" + +idSession * session = NULL; +idDeclManager * declManager = NULL; +idEventLoop * eventLoop = NULL; + +int idEventLoop::JournalLevel( void ) const { return 0; } + +/* +============================================================== + + idCommon + +============================================================== +*/ + +#define STDIO_PRINT( pre, post ) \ + va_list argptr; \ + va_start( argptr, fmt ); \ + printf( pre ); \ + vprintf( fmt, argptr ); \ + printf( post ); \ + va_end( argptr ) + + +class idCommonLocal : public idCommon { +public: + idCommonLocal( void ) {} + + virtual void Init( int argc, const char **argv, const char *cmdline ) {} + virtual void Shutdown( void ) {} + virtual void Quit( void ) {} + virtual bool IsInitialized( void ) const { return true; } + virtual void Frame( void ) {} + virtual void GUIFrame( bool execCmd, bool network ) {} + virtual void Async( void ) {} + virtual void StartupVariable( const char *match, bool once ) {} + virtual void InitTool( const toolFlag_t tool, const idDict *dict ) {} + virtual void ActivateTool( bool active ) {} + virtual void WriteConfigToFile( const char *filename ) {} + virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) {} + virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ) {} + virtual void EndRedirect( void ) {} + virtual void SetRefreshOnPrint( bool set ) {} + virtual void Printf( const char *fmt, ... ) { STDIO_PRINT( "", "" ); } + virtual void VPrintf( const char *fmt, va_list arg ) { vprintf( fmt, arg ); } + virtual void DPrintf( const char *fmt, ... ) { /*STDIO_PRINT( "", "" );*/ } + virtual void Warning( const char *fmt, ... ) { STDIO_PRINT( "WARNING: ", "\n" ); } + virtual void DWarning( const char *fmt, ...) { /*STDIO_PRINT( "WARNING: ", "\n" );*/ } + virtual void PrintWarnings( void ) {} + virtual void ClearWarnings( const char *reason ) {} + virtual void Error( const char *fmt, ... ) { STDIO_PRINT( "ERROR: ", "\n" ); exit(0); } + virtual void FatalError( const char *fmt, ... ) { STDIO_PRINT( "FATAL ERROR: ", "\n" ); exit(0); } + virtual const idLangDict *GetLanguageDict() { return NULL; } + virtual const char * KeysFromBinding( const char *bind ) { return NULL; } + virtual const char * BindingFromKey( const char *key ) { return NULL; } + virtual int ButtonState( int key ) { return 0; } + virtual int KeyState( int key ) { return 0; } +}; + +idCVar com_developer( "developer", "0", CVAR_BOOL|CVAR_SYSTEM, "developer mode" ); + +idCommonLocal commonLocal; +idCommon * common = &commonLocal; + +/* +============================================================== + + idSys + +============================================================== +*/ + +void Sys_Mkdir( const char *path ) {} +ID_TIME_T Sys_FileTimeStamp( FILE *fp ) { return 0; } + +#ifdef _WIN32 + +#include +#include + +const char *Sys_Cwd( void ) { + static char cwd[1024]; + + _getcwd( cwd, sizeof( cwd ) - 1 ); + cwd[sizeof( cwd ) - 1] = 0; + + int i = idStr::FindText( cwd, CD_BASEDIR, false ); + if ( i >= 0 ) { + cwd[i + strlen( CD_BASEDIR )] = '\0'; + } + + return cwd; +} + +const char *Sys_DefaultCDPath( void ) { + return ""; +} + +const char *Sys_DefaultBasePath( void ) { + return Sys_Cwd(); +} + +const char *Sys_DefaultSavePath( void ) { + return cvarSystem->GetCVarString( "fs_basepath" ); +} + +const char *Sys_EXEPath( void ) { + return ""; +} + +int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { + idStr search; + struct _finddata_t findinfo; + int findhandle; + int flag; + + if ( !extension) { + extension = ""; + } + + // passing a slash as extension will find directories + if ( extension[0] == '/' && extension[1] == 0 ) { + extension = ""; + flag = 0; + } else { + flag = _A_SUBDIR; + } + + sprintf( search, "%s\\*%s", directory, extension ); + + // search + list.Clear(); + + findhandle = _findfirst( search, &findinfo ); + if ( findhandle == -1 ) { + return -1; + } + + do { + if ( flag ^ ( findinfo.attrib & _A_SUBDIR ) ) { + list.Append( findinfo.name ); + } + } while ( _findnext( findhandle, &findinfo ) != -1 ); + + _findclose( findhandle ); + + return list.Num(); +} + +#else + +const char * Sys_DefaultCDPath( void ) { return ""; } +const char * Sys_DefaultBasePath( void ) { return ""; } +const char * Sys_DefaultSavePath( void ) { return ""; } +int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { return 0; } + +#endif + +xthreadInfo * g_threads[MAX_THREADS]; +int g_thread_count; + +void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo &info, const char *name, xthreadInfo *threads[MAX_THREADS], int *thread_count ) {} +void Sys_DestroyThread( xthreadInfo& info ) {} + +void Sys_EnterCriticalSection( int index ) {} +void Sys_LeaveCriticalSection( int index ) {} + +void Sys_WaitForEvent( int index ) {} +void Sys_TriggerEvent( int index ) {} + +/* +============== +idSysLocal stub +============== +*/ +void idSysLocal::DebugPrintf( const char *fmt, ... ) {} +void idSysLocal::DebugVPrintf( const char *fmt, va_list arg ) {} + +double idSysLocal::GetClockTicks( void ) { return 0.0; } +double idSysLocal::ClockTicksPerSecond( void ) { return 1.0; } +cpuid_t idSysLocal::GetProcessorId( void ) { return (cpuid_t)0; } +const char * idSysLocal::GetProcessorString( void ) { return ""; } +const char * idSysLocal::FPU_GetState( void ) { return ""; } +bool idSysLocal::FPU_StackIsEmpty( void ) { return true; } +void idSysLocal::FPU_SetFTZ( bool enable ) {} +void idSysLocal::FPU_SetDAZ( bool enable ) {} + +bool idSysLocal::LockMemory( void *ptr, int bytes ) { return false; } +bool idSysLocal::UnlockMemory( void *ptr, int bytes ) { return false; } + +void idSysLocal::GetCallStack( address_t *callStack, const int callStackSize ) { memset( callStack, 0, callStackSize * sizeof( callStack[0] ) ); } +const char * idSysLocal::GetCallStackStr( const address_t *callStack, const int callStackSize ) { return ""; } +const char * idSysLocal::GetCallStackCurStr( int depth ) { return ""; } +void idSysLocal::ShutdownSymbols( void ) {} + +int idSysLocal::DLL_Load( const char *dllName ) { return 0; } +void * idSysLocal::DLL_GetProcAddress( int dllHandle, const char *procName ) { return NULL; } +void idSysLocal::DLL_Unload( int dllHandle ) { } +void idSysLocal::DLL_GetFileName( const char *baseName, char *dllName, int maxLength ) { } + +sysEvent_t idSysLocal::GenerateMouseButtonEvent( int button, bool down ) { sysEvent_t ev; memset( &ev, 0, sizeof( ev ) ); return ev; } +sysEvent_t idSysLocal::GenerateMouseMoveEvent( int deltax, int deltay ) { sysEvent_t ev; memset( &ev, 0, sizeof( ev ) ); return ev; } + +void idSysLocal::OpenURL( const char *url, bool quit ) { } +void idSysLocal::StartProcess( const char *exeName, bool quit ) { } + +void idSysLocal::FPU_EnableExceptions( int exceptions ) { } + +idSysLocal sysLocal; +idSys * sys = &sysLocal; + + +/* +============================================================== + + main + +============================================================== +*/ + +int main( int argc, char** argv ) { + idStr fileName, sourcePath; + idTypeInfoGen *generator; + + idLib::common = common; + idLib::cvarSystem = cvarSystem; + idLib::fileSystem = fileSystem; + idLib::sys = sys; + + idLib::Init(); + cmdSystem->Init(); + cvarSystem->Init(); + idCVar::RegisterStaticVars(); + fileSystem->Init(); + + generator = new idTypeInfoGen; + + if ( argc > 1 ) { + sourcePath = idStr( "../"SOURCE_CODE_BASE_FOLDER"/" ) + argv[1]; + } else { + sourcePath = "../"SOURCE_CODE_BASE_FOLDER"/game"; + } + + if ( argc > 2 ) { + fileName = idStr( "../"SOURCE_CODE_BASE_FOLDER"/" ) + argv[2]; + } else { + fileName = "../"SOURCE_CODE_BASE_FOLDER"/game/gamesys/GameTypeInfo.h"; + } + + if ( argc > 3 ) { + for ( int i = 3; i < argc; i++ ) { + generator->AddDefine( argv[i] ); + } + } else { + generator->AddDefine( "__cplusplus" ); + generator->AddDefine( "GAME_DLL" ); + generator->AddDefine( "ID_TYPEINFO" ); + } + + generator->CreateTypeInfo( sourcePath ); + generator->WriteTypeInfo( fileName ); + + delete generator; + + fileName.Clear(); + sourcePath.Clear(); + + fileSystem->Shutdown( false ); + cvarSystem->Shutdown(); + cmdSystem->Shutdown(); + idLib::ShutDown(); + + return 0; +} diff --git a/base/animation/mp_greenarmor.md5mesh b/base/animation/mp_greenarmor.md5mesh deleted file mode 100644 index a9ef2f5bd..000000000 --- a/base/animation/mp_greenarmor.md5mesh +++ /dev/null @@ -1,11136 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:29 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_greenarmor.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh npcplayermesh -keepmesh npcplayerarmmesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 12 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} - -mesh { - // meshes: npcplayermesh - shader "models/characters/player/body" - - numverts 1575 - vert 0 ( 0.7719849944 0.1739491224 ) 422 3 - vert 1 ( 0.7761358023 0.2166122794 ) 16 2 - vert 2 ( 0.9342474341 0.2029662132 ) 369 2 - vert 3 ( 0.7812822461 0.0786810517 ) 366 3 - vert 4 ( 0.7750544548 0.1217979789 ) 37 3 - vert 5 ( 0.9121849537 0.0913875103 ) 40 3 - vert 6 ( 0.9486918449 0.1581048369 ) 364 2 - vert 7 ( 0.981231153 0.1557904482 ) 34 1 - vert 8 ( 0.9848356247 0.2042453289 ) 36 1 - vert 9 ( 0.9571538568 0.1173887253 ) 19 2 - vert 10 ( 0.9781797528 0.1185695529 ) 35 1 - vert 11 ( 0.7780196667 0.2432746291 ) 23 2 - vert 12 ( 0.783043921 0.2686276436 ) 21 2 - vert 13 ( 0.9352849722 0.2521877885 ) 371 2 - vert 14 ( 0.7996753454 0.3063983321 ) 27 3 - vert 15 ( 0.8188717365 0.3275544643 ) 349 3 - vert 16 ( 0.9244232178 0.3222169876 ) 25 2 - vert 17 ( 0.9444288015 0.2927160263 ) 30 2 - vert 18 ( 0.9878923893 0.2447026372 ) 32 1 - vert 19 ( 0.9888691902 0.2783545852 ) 33 1 - vert 20 ( 0.9876963496 0.2955794334 ) 43 1 - vert 21 ( 0.0757317171 0.4933236241 ) 32 1 - vert 22 ( 0.0453148633 0.5029659867 ) 33 1 - vert 23 ( 0.0311859138 0.5125299096 ) 43 1 - vert 24 ( 0.1126397699 0.5029966831 ) 36 1 - vert 25 ( 0.7192665935 0.1945339441 ) 340 3 - vert 26 ( 0.7244434953 0.247870028 ) 338 2 - vert 27 ( 0.7290217876 0.133651495 ) 343 3 - vert 28 ( 0.7376428246 0.2891875505 ) 357 3 - vert 29 ( 0.7843251228 0.3194739819 ) 352 2 - vert 30 ( 0.7916092873 0.0629788637 ) 401 3 - vert 31 ( 0.9808083773 0.1006911993 ) 18 1 - vert 32 ( 0.8500593901 0.3358787894 ) 354 3 - vert 33 ( 0.9903801084 0.3156605959 ) 44 1 - vert 34 ( 0.1371088624 0.5659808517 ) 35 1 - vert 35 ( 0.130730316 0.5783911943 ) 18 1 - vert 36 ( 0.0226989854 0.5299246907 ) 44 1 - vert 37 ( 0.7587145567 0.056238234 ) 389 2 - vert 38 ( 0.7485483289 0.0668531656 ) 346 3 - vert 39 ( 0.1988334358 0.1732062101 ) 49 2 - vert 40 ( 0.1606600583 0.1724814773 ) 289 2 - vert 41 ( 0.2065563202 0.203869462 ) 45 2 - vert 42 ( 0.2440526783 0.1961801648 ) 47 2 - vert 43 ( 0.2199383974 0.1669207215 ) 291 2 - vert 44 ( 0.1853164583 0.1452087164 ) 51 2 - vert 45 ( 0.1977131963 0.1293187141 ) 328 2 - vert 46 ( 0.2320413738 0.1638017893 ) 332 2 - vert 47 ( 0.1319933832 0.1507784128 ) 297 2 - vert 48 ( 0.1471800804 0.1801958084 ) 293 2 - vert 49 ( 0.2207314372 0.0940098166 ) 385 2 - vert 50 ( 0.225637868 0.1261227727 ) 334 2 - vert 51 ( 0.1712719351 0.1212942004 ) 53 2 - vert 52 ( 0.1362573057 0.1269802451 ) 55 2 - vert 53 ( 0.1522771865 0.0921294689 ) 141 2 - vert 54 ( 0.0973446891 0.1073492169 ) 454 2 - vert 55 ( 0.1045014411 0.1306480169 ) 456 2 - vert 56 ( 0.2565999031 0.2072867155 ) 320 2 - vert 57 ( 0.2366932034 0.2238991261 ) 57 2 - vert 58 ( 0.2670832574 0.1976121068 ) 336 2 - vert 59 ( 0.3767080009 0.2687792778 ) 63 2 - vert 60 ( 0.3375673592 0.2588784695 ) 324 2 - vert 61 ( 0.3741098046 0.2935296297 ) 61 2 - vert 62 ( 0.3299535513 0.321767211 ) 428 1 - vert 63 ( 0.312587738 0.3056652546 ) 257 1 - vert 64 ( 0.2032987624 0.3388952017 ) 414 1 - vert 65 ( 0.3047183752 0.3472927809 ) 425 3 - vert 66 ( 0.3684132099 0.2529971004 ) 326 2 - vert 67 ( 0.9777600169 0.3594118357 ) 69 1 - vert 68 ( 0.9560683966 0.3625028133 ) 75 1 - vert 69 ( 0.9850125313 0.3732030392 ) 68 1 - vert 70 ( 0.9726966023 0.3440070152 ) 65 1 - vert 71 ( 0.932472229 0.3331798315 ) 373 3 - vert 72 ( 0.9633110166 0.37722826 ) 70 1 - vert 73 ( 0.9687661529 0.3266601563 ) 363 1 - vert 74 ( 0.9701048732 0.3975123167 ) 71 1 - vert 75 ( 0.9915756583 0.3950402141 ) 72 1 - vert 76 ( 0.9697887897 0.0232592821 ) 82 1 - vert 77 ( 0.9608068466 0.0370163918 ) 73 1 - vert 78 ( 0.9867284298 0.036333859 ) 67 1 - vert 79 ( 0.9498755336 0.05041641 ) 86 1 - vert 80 ( 0.970534265 0.0562456846 ) 181 1 - vert 81 ( 0.9459283948 0.3729259968 ) 76 3 - vert 82 ( 0.9394038916 0.3606226444 ) 79 3 - vert 83 ( 0.9512848258 0.3967273235 ) 430 2 - vert 84 ( 0.9524915814 0.0231742859 ) 98 3 - vert 85 ( 0.9383511543 0.0427190661 ) 87 2 - vert 86 ( 0.9532439709 0.0073193908 ) 430 2 - vert 87 ( 0.9227056503 0.0357826352 ) 83 3 - vert 88 ( 0.9273494482 0.0794126987 ) 74 1 - vert 89 ( 0.903367579 0.0761495829 ) 387 2 - vert 90 ( 0.912866354 0.0514416099 ) 101 3 - vert 91 ( 0.378949672 0.2393563986 ) 89 3 - vert 92 ( 0.3427499235 0.2199612856 ) 376 3 - vert 93 ( 0.4038872123 0.2496082783 ) 95 3 - vert 94 ( 0.9303095937 0.376999259 ) 89 3 - vert 95 ( 0.9103215933 0.3499515057 ) 92 3 - vert 96 ( 0.9111652374 0.3607091308 ) 376 3 - vert 97 ( 0.8924641013 0.3404746652 ) 110 3 - vert 98 ( 0.9377003908 0.0090214014 ) 95 3 - vert 99 ( 0.8568929434 0.0630079508 ) 113 3 - vert 100 ( 0.4133526087 0.3320516348 ) 301 2 - vert 101 ( 0.415583998 0.2983020544 ) 104 2 - vert 102 ( 0.4180713892 0.2780668139 ) 106 2 - vert 103 ( 0.4208335578 0.2669227123 ) 108 2 - vert 104 ( 0.4331079125 0.2405208349 ) 83 3 - vert 105 ( 0.8828138113 0.3507838249 ) 379 3 - vert 106 ( 0.8628867865 0.3445779085 ) 382 3 - vert 107 ( 0.4562674761 0.2193844318 ) 138 3 - vert 108 ( 0.4362439215 0.2208782434 ) 101 3 - vert 109 ( 0.4550754428 0.1958655119 ) 113 3 - vert 110 ( 0.1761716157 0.4823075533 ) 260 2 - vert 111 ( 0.0787279755 0.4527158737 ) 126 2 - vert 112 ( 0.0876064748 0.4868043661 ) 299 2 - vert 113 ( 0.1900507212 0.3695975542 ) 120 2 - vert 114 ( 0.3118098378 0.3776582479 ) 287 2 - vert 115 ( 0.3887416422 0.371606946 ) 285 2 - vert 116 ( 0.1031567305 0.3722125888 ) 253 4 - vert 117 ( 0.0901635066 0.3966794014 ) 122 2 - vert 118 ( 0.1740061939 0.3925652504 ) 118 2 - vert 119 ( 0.2375343442 0.3892092705 ) 124 2 - vert 120 ( 0.1733226031 0.4177527428 ) 262 2 - vert 121 ( 0.0834966749 0.4254398346 ) 116 2 - vert 122 ( 0.0346233733 0.4262166023 ) 1008 2 - vert 123 ( 0.5515291095 0.3668923378 ) 134 2 - vert 124 ( 0.5368750691 0.3310366869 ) 305 2 - vert 125 ( 0.4416243732 0.3692581654 ) 281 2 - vert 126 ( 0.4589667022 0.3330621719 ) 303 2 - vert 127 ( 0.4569578469 0.2928750515 ) 128 2 - vert 128 ( 0.4617646635 0.272947073 ) 130 2 - vert 129 ( 0.4484837353 0.2625659704 ) 132 2 - vert 130 ( 0.4843864143 0.2439597845 ) 394 4 - vert 131 ( 0.4894174337 0.2005261779 ) 398 3 - vert 132 ( 0.4839029312 0.2976908684 ) 392 2 - vert 133 ( 0.6545915604 0.3622258306 ) 136 2 - vert 134 ( 0.6345106959 0.3407916427 ) 409 2 - vert 135 ( 0.630621314 0.3980139494 ) 420 2 - vert 136 ( 0.6880182028 0.3551647663 ) 1034 2 - vert 137 ( 0.3633111715 0.3925454617 ) 266 2 - vert 138 ( 0.2762205899 0.4013280272 ) 264 2 - vert 139 ( 0.4149272144 0.3884478807 ) 268 2 - vert 140 ( 0.5014795661 0.3986136913 ) 418 2 - vert 141 ( 0.1811420172 0.090656817 ) 59 2 - vert 142 ( 0.1877191067 0.0739201903 ) 145 2 - vert 143 ( 0.2234210223 0.0783751607 ) 143 2 - vert 144 ( 0.2155510783 0.053099215 ) 470 2 - vert 145 ( 0.1686146408 0.0724397302 ) 446 2 - vert 146 ( 0.260376811 0.057418704 ) 472 2 - vert 147 ( 0.154160589 0.0672708154 ) 440 2 - vert 148 ( 0.1290840805 0.0645196438 ) 147 2 - vert 149 ( 0.0939202756 0.0857795477 ) 458 2 - vert 150 ( 0.158521235 0.0407286286 ) 442 2 - vert 151 ( 0.621288538 0.026286602 ) 444 2 - vert 152 ( 0.6127229929 0.0111091137 ) 466 2 - vert 153 ( 0.5899264216 0.0242571831 ) 482 2 - vert 154 ( 0.6314601898 0.0188786387 ) 157 2 - vert 155 ( 0.6731433272 0.0233812332 ) 1037 1 - vert 156 ( 0.6693091393 0.0133371949 ) 1040 2 - vert 157 ( 0.6555342674 0.0261619091 ) 151 2 - vert 158 ( 0.6343261003 0.0351712108 ) 153 2 - vert 159 ( 0.5947169662 0.0369234681 ) 480 2 - vert 160 ( 0.1306925267 0.0353519917 ) 149 2 - vert 161 ( 0.1583495736 0.0178813934 ) 482 2 - vert 162 ( 0.1112286523 0.0614367127 ) 155 2 - vert 163 ( 0.0687628537 0.0838969946 ) 460 2 - vert 164 ( 0.1041324735 0.0295057297 ) 466 2 - vert 165 ( 0.2601608932 0.1256691813 ) 176 2 - vert 166 ( 0.2717661262 0.1610040665 ) 330 2 - vert 167 ( 0.2864275277 0.129344821 ) 352 2 - vert 168 ( 0.3224107325 0.0293053389 ) 161 2 - vert 169 ( 0.2948327661 0.0294322371 ) 163 2 - vert 170 ( 0.2858069539 0.0444990396 ) 360 1 - vert 171 ( 0.3294394612 0.0500174761 ) 361 2 - vert 172 ( 0.346196115 0.0249729156 ) 476 2 - vert 173 ( 0.5002523661 0.0174547434 ) 163 2 - vert 174 ( 0.4844011664 0.0202205181 ) 161 2 - vert 175 ( 0.5026299953 0.0355491042 ) 159 2 - vert 176 ( 0.5243685842 0.0238627195 ) 468 2 - vert 177 ( 0.4829595983 0.033801198 ) 476 2 - vert 178 ( 0.3150535226 0.1771664619 ) 354 3 - vert 179 ( 0.2750811577 0.1784644723 ) 168 2 - vert 180 ( 0.2883987129 0.1947547197 ) 165 3 - vert 181 ( 0.3052287698 0.1602692008 ) 349 3 - vert 182 ( 0.2867027223 0.0602782369 ) 170 1 - vert 183 ( 0.293391943 0.0816760659 ) 357 3 - vert 184 ( 0.270162642 0.0748990178 ) 429 1 - vert 185 ( 0.261823833 0.0975263119 ) 171 2 - vert 186 ( 0.2675724924 0.0605119467 ) 173 1 - vert 187 ( 0.2419462353 0.0964244604 ) 174 2 - vert 188 ( 0.3122615218 0.0457592607 ) 178 1 - vert 189 ( 0.1220116317 0.35315907 ) 415 1 - vert 190 ( 0.0705850795 0.3469480276 ) 179 1 - vert 191 ( 0.088236168 0.358579874 ) 180 1 - vert 192 ( 0.0416658707 0.3366687298 ) 1013 1 - vert 193 ( 0.0407538973 0.3570179939 ) 1015 1 - vert 194 ( 0.6823749542 0.3089283705 ) 1033 1 - vert 195 ( 0.6410657167 0.3053518534 ) 411 1 - vert 196 ( 0.6834305525 0.3358545303 ) 1030 1 - vert 197 ( 0.576730907 0.2900364399 ) 406 1 - vert 198 ( 0.5438317657 0.304131031 ) 391 1 - vert 199 ( 0.2288514078 0.0190554261 ) 432 2 - vert 200 ( 0.1894607246 0.0405897498 ) 184 2 - vert 201 ( 0.205780372 0.0468271375 ) 182 2 - vert 202 ( 0.2064351588 0.0169457793 ) 434 2 - vert 203 ( 0.1806353629 0.0167136788 ) 436 2 - vert 204 ( 0.2661892176 0.0248714089 ) 468 2 - vert 205 ( 0.5500692129 0.0519242883 ) 186 2 - vert 206 ( 0.5632948875 0.0237393379 ) 434 2 - vert 207 ( 0.5517164469 0.0273959637 ) 432 2 - vert 208 ( 0.5377216935 0.0548202991 ) 192 2 - vert 209 ( 0.5692396164 0.0458415747 ) 188 2 - vert 210 ( 0.5789684057 0.0221659541 ) 436 2 - vert 211 ( 0.5895558 0.0556252599 ) 492 2 - vert 212 ( 0.531262517 0.0610063672 ) 190 2 - vert 213 ( 0.5751540661 0.0623465776 ) 194 2 - vert 214 ( 0.5516625047 0.0799572468 ) 196 2 - vert 215 ( 0.5441607237 0.089502871 ) 486 2 - vert 216 ( 0.557315588 0.0738011599 ) 198 2 - vert 217 ( 0.5860296488 0.0732482672 ) 200 2 - vert 218 ( 0.6411839724 0.0611894727 ) 438 2 - vert 219 ( 0.5894818306 0.0801156759 ) 202 2 - vert 220 ( 0.645894289 0.0675839186 ) 496 2 - vert 221 ( 0.6396798491 0.0558245778 ) 494 2 - vert 222 ( 0.6101171374 0.0874040723 ) 488 2 - vert 223 ( 0.6612665057 0.0499736667 ) 204 2 - vert 224 ( 0.6559203267 0.0579929352 ) 206 2 - vert 225 ( 0.6458992362 0.1148506403 ) 478 2 - vert 226 ( 0.4101769626 0.4065922499 ) 273 2 - vert 227 ( 0.2977717519 0.4171279669 ) 208 2 - vert 228 ( 0.2972899675 0.4444799423 ) 276 2 - vert 229 ( 0.2023364305 0.4459073544 ) 283 2 - vert 230 ( 0.246791169 0.4823950529 ) 213 1 - vert 231 ( 0.3267735541 0.4799511433 ) 210 1 - vert 232 ( 0.233572349 0.420089066 ) 211 2 - vert 233 ( 0.500195086 0.4161766768 ) 279 2 - vert 234 ( 0.4139399529 0.4374961853 ) 275 1 - vert 235 ( 0.6783809662 0.4751578569 ) 1025 1 - vert 236 ( 0.6117873192 0.4231669903 ) 270 2 - vert 237 ( 0.6149737835 0.4726412296 ) 272 1 - vert 238 ( 0.6375279427 0.2309622765 ) 215 2 - vert 239 ( 0.5880635381 0.1491855979 ) 412 2 - vert 240 ( 0.5833166242 0.2323986888 ) 404 2 - vert 241 ( 0.6415254474 0.1431332827 ) 498 2 - vert 242 ( 0.5958094001 0.124979198 ) 484 2 - vert 243 ( 0.5111600161 0.1006494761 ) 407 2 - vert 244 ( 0.5371952057 0.2796193361 ) 222 2 - vert 245 ( 0.4997964501 0.2775235772 ) 224 2 - vert 246 ( 0.5423352718 0.1698867083 ) 217 2 - vert 247 ( 0.5047276616 0.1677002907 ) 219 3 - vert 248 ( 0.4772584438 0.1726484895 ) 401 3 - vert 249 ( 0.0349275917 0.4559711218 ) 1004 2 - vert 250 ( 0.0369338915 0.4886707067 ) 1006 2 - vert 251 ( 0.6854083538 0.4004590511 ) 1028 2 - vert 252 ( 0.6881486773 0.3641757965 ) 1031 2 - vert 253 ( 0.6855412126 0.0622583032 ) 1043 1 - vert 254 ( 0.6825768948 0.0542641282 ) 1038 1 - vert 255 ( 0.680439949 0.0474733114 ) 1039 1 - vert 256 ( 0.686493814 0.1137228012 ) 1042 1 - vert 257 ( 0.6821902394 0.2316077948 ) 1036 1 - vert 258 ( 0.6833172441 0.1411369443 ) 1044 1 - vert 259 ( 0.6776295304 0.4338669181 ) 1026 2 - vert 260 ( 0.2447962761 0.3158401847 ) 2 1 - vert 261 ( 0.1756124347 0.3161141276 ) 0 1 - vert 262 ( 0.196628347 0.3239648342 ) 3 1 - vert 263 ( 0.2032550424 0.3089809418 ) 247 1 - vert 264 ( 0.2383634746 0.3045857549 ) 248 1 - vert 265 ( 0.2159217894 0.2639656067 ) 242 2 - vert 266 ( 0.1867734194 0.2540796399 ) 230 2 - vert 267 ( 0.1935764849 0.271116972 ) 244 1 - vert 268 ( 0.1509000212 0.2810679674 ) 1 1 - vert 269 ( 0.1800705492 0.2839884758 ) 245 1 - vert 270 ( 0.3037730455 0.2656636238 ) 232 2 - vert 271 ( 0.239786759 0.2652668357 ) 500 2 - vert 272 ( 0.256254822 0.2745233774 ) 250 1 - vert 273 ( 0.0849639997 0.297745347 ) 251 1 - vert 274 ( 0.153091684 0.3213464618 ) 252 1 - vert 275 ( 0.0780468881 0.2612736821 ) 4 1 - vert 276 ( 0.0449726842 0.2876057029 ) 1014 1 - vert 277 ( 0.0544010848 0.1455991268 ) 5 2 - vert 278 ( 0.1122105867 0.1676524878 ) 9 2 - vert 279 ( 0.0222788006 0.1788551807 ) 1018 1 - vert 280 ( 0.0301475562 0.1425036788 ) 11 2 - vert 281 ( 0.0493472107 0.133128047 ) 450 2 - vert 282 ( 0.1609368026 0.2095714808 ) 7 2 - vert 283 ( 0.0253295396 0.1273131371 ) 452 2 - vert 284 ( 0.1810530126 0.2063926458 ) 295 2 - vert 285 ( 0.0926404297 0.2340055704 ) 228 2 - vert 286 ( 0.2798832953 0.2400516272 ) 322 2 - vert 287 ( 0.2205203623 0.2318389416 ) 318 2 - vert 288 ( 0.007626283 0.1254262328 ) 1024 1 - vert 289 ( 0.0102145821 0.1421524286 ) 1019 1 - vert 290 ( 0.1824166179 0.2241794467 ) 13 2 - vert 291 ( 0.3066275716 0.2904499173 ) 15 1 - vert 292 ( 0.0428825654 0.2243050337 ) 1016 1 - vert 293 ( 0.048967585 0.2594988942 ) 1017 1 - vert 294 ( 0.2318297029 0.3024432063 ) 416 1 - vert 295 ( 0.2121662796 0.3043839931 ) 238 1 - vert 296 ( 0.1796101779 0.2976648808 ) 246 1 - vert 297 ( 0.2583833337 0.2881996632 ) 249 1 - vert 298 ( 0.2444739342 0.2935115695 ) 237 1 - vert 299 ( 0.1998132467 0.2987421751 ) 239 1 - vert 300 ( 0.2207421511 0.2761649489 ) 234 1 - vert 301 ( 0.2349794805 0.2770217657 ) 235 1 - vert 302 ( 0.2447223961 0.2831145525 ) 236 1 - vert 303 ( 0.1991215944 0.2893447876 ) 240 1 - vert 304 ( 0.2072287053 0.2808719873 ) 241 1 - vert 305 ( 0.3390630186 0.2856384516 ) 258 2 - vert 306 ( 0.0351432562 0.3959318399 ) 1010 2 - vert 307 ( 0.4145067334 0.4730770588 ) 278 1 - vert 308 ( 0.2830866277 0.2339842319 ) 314 2 - vert 309 ( 0.2919953465 0.2246251106 ) 310 2 - vert 310 ( 0.3245466053 0.2377005816 ) 316 2 - vert 311 ( 0.3043735027 0.2466383576 ) 312 2 - vert 312 ( 0.3077458739 0.2142954469 ) 307 3 - vert 313 ( 0.3315804601 0.2017439604 ) 379 3 - vert 314 ( 0.1374716163 0.5366076231 ) 34 1 - vert 315 ( 0.0239795577 0.5414884686 ) 363 1 - vert 316 ( 0.013230687 0.5592079759 ) 65 1 - vert 317 ( 0.0175803714 0.5961876512 ) 68 1 - vert 318 ( 0.0110753831 0.5788846016 ) 69 1 - vert 319 ( 0.1031310037 0.6050055027 ) 181 1 - vert 320 ( 0.1181451455 0.5825795531 ) 66 1 - vert 321 ( 0.0827152058 0.6226586103 ) 67 1 - vert 322 ( 0.325393647 0.1892156005 ) 382 3 - vert 323 ( 0.0411293432 0.6158047915 ) 72 1 - vert 324 ( 0.9579395652 0.0860168338 ) 66 1 - vert 325 ( 0.5340631604 0.152531147 ) 226 2 - vert 326 ( 0.0217457116 0.9124113321 ) 214 1 - vert 327 ( 0.0583504289 0.8942132592 ) 278 1 - vert 328 ( 0.0537294522 0.989767611 ) 1012 1 - vert 329 ( 0.0021743923 0.9476748109 ) 272 1 - vert 330 ( 0.0019864589 0.9870103598 ) 1025 1 - vert 331 ( 0.1303386241 0.9691649079 ) 299 2 - vert 332 ( 0.1297646761 0.9938191175 ) 1006 2 - vert 333 ( 0.1184003651 0.9390746355 ) 260 2 - vert 334 ( 0.115521118 0.925874114 ) 213 1 - vert 335 ( 0.0988566875 0.9065935612 ) 210 1 - vert 336 ( 0.5047248006 0.1468339562 ) 389 2 - vert 337 ( 0.4947037399 0.4485718608 ) 417 1 - vert 338 ( 0.5007638335 0.4729495049 ) 214 1 - vert 339 ( 0.9935348034 0.0056322813 ) 72 1 - vert 340 ( 0.9720637202 0.0081043243 ) 71 1 - vert 341 ( 0.7080481648 0.2527147532 ) 361 2 - vert 342 ( 0.9357414842 0.3984293938 ) 95 3 - vert 343 ( 0.0517277829 0.1217052937 ) 448 2 - vert 344 ( 0.0312847868 0.1230297089 ) 464 2 - vert 345 ( 0.0462320745 0.1064546704 ) 462 2 - vert 346 ( 0.0369653367 0.0194339752 ) 1040 2 - vert 347 ( 0.0066078696 0.0906814933 ) 1020 2 - vert 348 ( 0.0000675758 0.1059738994 ) 1022 2 - vert 349 ( 0.2404449284 0.0468884706 ) 474 2 - vert 350 ( 0.7014831305 0.2022577524 ) 476 2 - vert 351 ( 0.6995779872 0.114027977 ) 490 2 - vert 352 ( 0.5039020777 0.055891335 ) 490 2 - vert 353 ( 0.4725182056 0.131450057 ) 346 3 - vert 354 ( 0.470426172 0.0956435204 ) 490 2 - vert 355 ( 0.7761358023 0.2166122794 ) 518 2 - vert 356 ( 0.7719849944 0.1739491224 ) 924 3 - vert 357 ( 0.9342474341 0.2029662132 ) 871 2 - vert 358 ( 0.7750544548 0.1217979789 ) 539 3 - vert 359 ( 0.7812822461 0.0786810517 ) 868 3 - vert 360 ( 0.9121849537 0.0913875103 ) 542 3 - vert 361 ( 0.9486918449 0.1581048369 ) 866 2 - vert 362 ( 0.981231153 0.1557904482 ) 536 1 - vert 363 ( 0.9848356247 0.2042453289 ) 538 1 - vert 364 ( 0.9571538568 0.1173887253 ) 521 2 - vert 365 ( 0.9781797528 0.1185695529 ) 537 1 - vert 366 ( 0.783043921 0.2686276436 ) 523 2 - vert 367 ( 0.7780196667 0.2432746291 ) 525 2 - vert 368 ( 0.9352849722 0.2521877885 ) 873 2 - vert 369 ( 0.8188717365 0.3275544643 ) 851 3 - vert 370 ( 0.7996753454 0.3063983321 ) 529 3 - vert 371 ( 0.9244232178 0.3222169876 ) 527 2 - vert 372 ( 0.9444288015 0.2927160263 ) 532 2 - vert 373 ( 0.9878923893 0.2447026372 ) 534 1 - vert 374 ( 0.9888691902 0.2783545852 ) 535 1 - vert 375 ( 0.9876963496 0.2955794334 ) 545 1 - vert 376 ( 0.0453148633 0.5029659867 ) 535 1 - vert 377 ( 0.0757317171 0.4933236241 ) 534 1 - vert 378 ( 0.0311859138 0.5125299096 ) 545 1 - vert 379 ( 0.1126397699 0.5029966831 ) 538 1 - vert 380 ( 0.7244434953 0.247870028 ) 840 2 - vert 381 ( 0.7192665935 0.1945339441 ) 842 3 - vert 382 ( 0.7290217876 0.133651495 ) 845 3 - vert 383 ( 0.7376428246 0.2891875505 ) 859 3 - vert 384 ( 0.7843251228 0.3194739819 ) 854 2 - vert 385 ( 0.7916092873 0.0629788637 ) 903 3 - vert 386 ( 0.9808083773 0.1006911993 ) 520 1 - vert 387 ( 0.8500593901 0.3358787894 ) 856 3 - vert 388 ( 0.9903801084 0.3156605959 ) 546 1 - vert 389 ( 0.1371088624 0.5659808517 ) 537 1 - vert 390 ( 0.130730316 0.5783911943 ) 520 1 - vert 391 ( 0.0226989854 0.5299246907 ) 546 1 - vert 392 ( 0.7485483289 0.0668531656 ) 848 3 - vert 393 ( 0.7587145567 0.056238234 ) 891 2 - vert 394 ( 0.1606600583 0.1724814773 ) 791 2 - vert 395 ( 0.1988334358 0.1732062101 ) 551 2 - vert 396 ( 0.2065563202 0.203869462 ) 547 2 - vert 397 ( 0.2440526783 0.1961801648 ) 549 2 - vert 398 ( 0.2199383974 0.1669207215 ) 793 2 - vert 399 ( 0.1853164583 0.1452087164 ) 553 2 - vert 400 ( 0.1977131963 0.1293187141 ) 830 2 - vert 401 ( 0.2320413738 0.1638017893 ) 834 2 - vert 402 ( 0.1319933832 0.1507784128 ) 799 2 - vert 403 ( 0.1471800804 0.1801958084 ) 795 2 - vert 404 ( 0.2207314372 0.0940098166 ) 887 2 - vert 405 ( 0.225637868 0.1261227727 ) 836 2 - vert 406 ( 0.1712719351 0.1212942004 ) 555 2 - vert 407 ( 0.1362573057 0.1269802451 ) 557 2 - vert 408 ( 0.0973446891 0.1073492169 ) 956 2 - vert 409 ( 0.1522771865 0.0921294689 ) 643 2 - vert 410 ( 0.1045014411 0.1306480169 ) 958 2 - vert 411 ( 0.2565999031 0.2072867155 ) 822 2 - vert 412 ( 0.2366932034 0.2238991261 ) 559 2 - vert 413 ( 0.2670832574 0.1976121068 ) 838 2 - vert 414 ( 0.3375673592 0.2588784695 ) 826 2 - vert 415 ( 0.3767080009 0.2687792778 ) 565 2 - vert 416 ( 0.3741098046 0.2935296297 ) 563 2 - vert 417 ( 0.312587738 0.3056652546 ) 759 1 - vert 418 ( 0.3299535513 0.321767211 ) 930 1 - vert 419 ( 0.2032987624 0.3388952017 ) 916 1 - vert 420 ( 0.3047183752 0.3472927809 ) 927 3 - vert 421 ( 0.3684132099 0.2529971004 ) 828 2 - vert 422 ( 0.9560683966 0.3625028133 ) 577 1 - vert 423 ( 0.9777600169 0.3594118357 ) 571 1 - vert 424 ( 0.9850125313 0.3732030392 ) 570 1 - vert 425 ( 0.9726966023 0.3440070152 ) 567 1 - vert 426 ( 0.932472229 0.3331798315 ) 875 3 - vert 427 ( 0.9633110166 0.37722826 ) 572 1 - vert 428 ( 0.9687661529 0.3266601563 ) 865 1 - vert 429 ( 0.9701048732 0.3975123167 ) 573 1 - vert 430 ( 0.9915756583 0.3950402141 ) 574 1 - vert 431 ( 0.9608068466 0.0370163918 ) 575 1 - vert 432 ( 0.9697887897 0.0232592821 ) 584 1 - vert 433 ( 0.9867284298 0.036333859 ) 569 1 - vert 434 ( 0.970534265 0.0562456846 ) 683 1 - vert 435 ( 0.9498755336 0.05041641 ) 588 1 - vert 436 ( 0.9459283948 0.3729259968 ) 578 3 - vert 437 ( 0.9394038916 0.3606226444 ) 581 3 - vert 438 ( 0.9512848258 0.3967273235 ) 932 2 - vert 439 ( 0.9383511543 0.0427190661 ) 589 2 - vert 440 ( 0.9524915814 0.0231742859 ) 600 3 - vert 441 ( 0.9532439709 0.0073193908 ) 932 2 - vert 442 ( 0.9227056503 0.0357826352 ) 585 3 - vert 443 ( 0.9273494482 0.0794126987 ) 576 1 - vert 444 ( 0.903367579 0.0761495829 ) 889 2 - vert 445 ( 0.912866354 0.0514416099 ) 603 3 - vert 446 ( 0.3427499235 0.2199612856 ) 878 3 - vert 447 ( 0.378949672 0.2393563986 ) 591 3 - vert 448 ( 0.4038872123 0.2496082783 ) 597 3 - vert 449 ( 0.9303095937 0.376999259 ) 591 3 - vert 450 ( 0.9103215933 0.3499515057 ) 594 3 - vert 451 ( 0.9111652374 0.3607091308 ) 878 3 - vert 452 ( 0.8924641013 0.3404746652 ) 612 3 - vert 453 ( 0.9377003908 0.0090214014 ) 597 3 - vert 454 ( 0.8568929434 0.0630079508 ) 615 3 - vert 455 ( 0.4133526087 0.3320516348 ) 803 2 - vert 456 ( 0.415583998 0.2983020544 ) 606 2 - vert 457 ( 0.4180713892 0.2780668139 ) 608 2 - vert 458 ( 0.4208335578 0.2669227123 ) 610 2 - vert 459 ( 0.4331079125 0.2405208349 ) 585 3 - vert 460 ( 0.8828138113 0.3507838249 ) 881 3 - vert 461 ( 0.8628867865 0.3445779085 ) 884 3 - vert 462 ( 0.4362439215 0.2208782434 ) 603 3 - vert 463 ( 0.4562674761 0.2193844318 ) 640 3 - vert 464 ( 0.4550754428 0.1958655119 ) 615 3 - vert 465 ( 0.0787279755 0.4527158737 ) 628 2 - vert 466 ( 0.1761716157 0.4823075533 ) 762 2 - vert 467 ( 0.0876064748 0.4868043661 ) 801 2 - vert 468 ( 0.1900507212 0.3695975542 ) 622 2 - vert 469 ( 0.3118098378 0.3776582479 ) 789 2 - vert 470 ( 0.3887416422 0.371606946 ) 787 2 - vert 471 ( 0.1031567305 0.3722125888 ) 755 4 - vert 472 ( 0.0901635066 0.3966794014 ) 624 2 - vert 473 ( 0.1740061939 0.3925652504 ) 620 2 - vert 474 ( 0.2375343442 0.3892092705 ) 626 2 - vert 475 ( 0.1733226031 0.4177527428 ) 764 2 - vert 476 ( 0.0834966749 0.4254398346 ) 618 2 - vert 477 ( 0.5368750691 0.3310366869 ) 807 2 - vert 478 ( 0.5515291095 0.3668923378 ) 636 2 - vert 479 ( 0.4416243732 0.3692581654 ) 783 2 - vert 480 ( 0.4589667022 0.3330621719 ) 805 2 - vert 481 ( 0.4569578469 0.2928750515 ) 630 2 - vert 482 ( 0.4617646635 0.272947073 ) 632 2 - vert 483 ( 0.4484837353 0.2625659704 ) 634 2 - vert 484 ( 0.4843864143 0.2439597845 ) 896 4 - vert 485 ( 0.4894174337 0.2005261779 ) 900 3 - vert 486 ( 0.4839029312 0.2976908684 ) 894 2 - vert 487 ( 0.6545915604 0.3622258306 ) 638 2 - vert 488 ( 0.6345106959 0.3407916427 ) 911 2 - vert 489 ( 0.630621314 0.3980139494 ) 922 2 - vert 490 ( 0.3633111715 0.3925454617 ) 768 2 - vert 491 ( 0.2762205899 0.4013280272 ) 766 2 - vert 492 ( 0.4149272144 0.3884478807 ) 770 2 - vert 493 ( 0.5014795661 0.3986136913 ) 920 2 - vert 494 ( 0.1877191067 0.0739201903 ) 647 2 - vert 495 ( 0.1811420172 0.090656817 ) 561 2 - vert 496 ( 0.2234210223 0.0783751607 ) 645 2 - vert 497 ( 0.2155510783 0.053099215 ) 972 2 - vert 498 ( 0.1686146408 0.0724397302 ) 948 2 - vert 499 ( 0.260376811 0.057418704 ) 974 2 - vert 500 ( 0.1290840805 0.0645196438 ) 649 2 - vert 501 ( 0.154160589 0.0672708154 ) 942 2 - vert 502 ( 0.0939202756 0.0857795477 ) 960 2 - vert 503 ( 0.158521235 0.0407286286 ) 944 2 - vert 504 ( 0.6127229929 0.0111091137 ) 968 2 - vert 505 ( 0.621288538 0.026286602 ) 946 2 - vert 506 ( 0.5899264216 0.0242571831 ) 984 2 - vert 507 ( 0.6314601898 0.0188786387 ) 659 2 - vert 508 ( 0.6555342674 0.0261619091 ) 653 2 - vert 509 ( 0.6343261003 0.0351712108 ) 655 2 - vert 510 ( 0.5947169662 0.0369234681 ) 982 2 - vert 511 ( 0.1306925267 0.0353519917 ) 651 2 - vert 512 ( 0.1583495736 0.0178813934 ) 984 2 - vert 513 ( 0.1112286523 0.0614367127 ) 657 2 - vert 514 ( 0.0687628537 0.0838969946 ) 962 2 - vert 515 ( 0.1041324735 0.0295057297 ) 968 2 - vert 516 ( 0.2601608932 0.1256691813 ) 678 2 - vert 517 ( 0.2717661262 0.1610040665 ) 832 2 - vert 518 ( 0.2864275277 0.129344821 ) 854 2 - vert 519 ( 0.2948327661 0.0294322371 ) 665 2 - vert 520 ( 0.3224107325 0.0293053389 ) 663 2 - vert 521 ( 0.2858069539 0.0444990396 ) 862 1 - vert 522 ( 0.3294394612 0.0500174761 ) 863 2 - vert 523 ( 0.346196115 0.0249729156 ) 978 2 - vert 524 ( 0.4844011664 0.0202205181 ) 663 2 - vert 525 ( 0.5002523661 0.0174547434 ) 665 2 - vert 526 ( 0.5026299953 0.0355491042 ) 661 2 - vert 527 ( 0.5243685842 0.0238627195 ) 970 2 - vert 528 ( 0.4829595983 0.033801198 ) 978 2 - vert 529 ( 0.2750811577 0.1784644723 ) 670 2 - vert 530 ( 0.3150535226 0.1771664619 ) 856 3 - vert 531 ( 0.2883987129 0.1947547197 ) 667 3 - vert 532 ( 0.3052287698 0.1602692008 ) 851 3 - vert 533 ( 0.2867027223 0.0602782369 ) 672 1 - vert 534 ( 0.293391943 0.0816760659 ) 859 3 - vert 535 ( 0.270162642 0.0748990178 ) 931 1 - vert 536 ( 0.261823833 0.0975263119 ) 673 2 - vert 537 ( 0.2675724924 0.0605119467 ) 675 1 - vert 538 ( 0.2419462353 0.0964244604 ) 676 2 - vert 539 ( 0.3122615218 0.0457592607 ) 680 1 - vert 540 ( 0.0705850795 0.3469480276 ) 681 1 - vert 541 ( 0.1220116317 0.35315907 ) 917 1 - vert 542 ( 0.088236168 0.358579874 ) 682 1 - vert 543 ( 0.6410657167 0.3053518534 ) 913 1 - vert 544 ( 0.5438317657 0.304131031 ) 893 1 - vert 545 ( 0.576730907 0.2900364399 ) 908 1 - vert 546 ( 0.1894607246 0.0405897498 ) 686 2 - vert 547 ( 0.2288514078 0.0190554261 ) 934 2 - vert 548 ( 0.205780372 0.0468271375 ) 684 2 - vert 549 ( 0.2064351588 0.0169457793 ) 936 2 - vert 550 ( 0.1806353629 0.0167136788 ) 938 2 - vert 551 ( 0.2661892176 0.0248714089 ) 970 2 - vert 552 ( 0.5632948875 0.0237393379 ) 936 2 - vert 553 ( 0.5500692129 0.0519242883 ) 688 2 - vert 554 ( 0.5517164469 0.0273959637 ) 934 2 - vert 555 ( 0.5377216935 0.0548202991 ) 694 2 - vert 556 ( 0.5692396164 0.0458415747 ) 690 2 - vert 557 ( 0.5789684057 0.0221659541 ) 938 2 - vert 558 ( 0.5895558 0.0556252599 ) 994 2 - vert 559 ( 0.531262517 0.0610063672 ) 692 2 - vert 560 ( 0.5751540661 0.0623465776 ) 696 2 - vert 561 ( 0.5516625047 0.0799572468 ) 698 2 - vert 562 ( 0.5441607237 0.089502871 ) 988 2 - vert 563 ( 0.557315588 0.0738011599 ) 700 2 - vert 564 ( 0.6411839724 0.0611894727 ) 940 2 - vert 565 ( 0.5860296488 0.0732482672 ) 702 2 - vert 566 ( 0.5894818306 0.0801156759 ) 704 2 - vert 567 ( 0.645894289 0.0675839186 ) 998 2 - vert 568 ( 0.6396798491 0.0558245778 ) 996 2 - vert 569 ( 0.6101171374 0.0874040723 ) 990 2 - vert 570 ( 0.6612665057 0.0499736667 ) 706 2 - vert 571 ( 0.6559203267 0.0579929352 ) 708 2 - vert 572 ( 0.6458992362 0.1148506403 ) 980 2 - vert 573 ( 0.4101769626 0.4065922499 ) 775 2 - vert 574 ( 0.2977717519 0.4171279669 ) 710 2 - vert 575 ( 0.2023364305 0.4459073544 ) 785 2 - vert 576 ( 0.2972899675 0.4444799423 ) 778 2 - vert 577 ( 0.246791169 0.4823950529 ) 715 1 - vert 578 ( 0.3267735541 0.4799511433 ) 712 1 - vert 579 ( 0.233572349 0.420089066 ) 713 2 - vert 580 ( 0.500195086 0.4161766768 ) 781 2 - vert 581 ( 0.4139399529 0.4374961853 ) 777 1 - vert 582 ( 0.6117873192 0.4231669903 ) 772 2 - vert 583 ( 0.6149737835 0.4726412296 ) 774 1 - vert 584 ( 0.5880635381 0.1491855979 ) 914 2 - vert 585 ( 0.6375279427 0.2309622765 ) 717 2 - vert 586 ( 0.5833166242 0.2323986888 ) 906 2 - vert 587 ( 0.6415254474 0.1431332827 ) 1000 2 - vert 588 ( 0.5958094001 0.124979198 ) 986 2 - vert 589 ( 0.5111600161 0.1006494761 ) 909 2 - vert 590 ( 0.5371952057 0.2796193361 ) 724 2 - vert 591 ( 0.4997964501 0.2775235772 ) 726 2 - vert 592 ( 0.5423352718 0.1698867083 ) 719 2 - vert 593 ( 0.5047276616 0.1677002907 ) 721 3 - vert 594 ( 0.4772584438 0.1726484895 ) 903 3 - vert 595 ( 0.1756124347 0.3161141276 ) 502 1 - vert 596 ( 0.2447962761 0.3158401847 ) 504 1 - vert 597 ( 0.196628347 0.3239648342 ) 505 1 - vert 598 ( 0.2032550424 0.3089809418 ) 749 1 - vert 599 ( 0.2383634746 0.3045857549 ) 750 1 - vert 600 ( 0.1867734194 0.2540796399 ) 732 2 - vert 601 ( 0.2159217894 0.2639656067 ) 744 2 - vert 602 ( 0.1935764849 0.271116972 ) 746 1 - vert 603 ( 0.1509000212 0.2810679674 ) 503 1 - vert 604 ( 0.1800705492 0.2839884758 ) 747 1 - vert 605 ( 0.239786759 0.2652668357 ) 1002 2 - vert 606 ( 0.3037730455 0.2656636238 ) 734 2 - vert 607 ( 0.256254822 0.2745233774 ) 752 1 - vert 608 ( 0.0849639997 0.297745347 ) 753 1 - vert 609 ( 0.153091684 0.3213464618 ) 754 1 - vert 610 ( 0.0780468881 0.2612736821 ) 506 1 - vert 611 ( 0.0544010848 0.1455991268 ) 507 2 - vert 612 ( 0.1122105867 0.1676524878 ) 511 2 - vert 613 ( 0.0301475562 0.1425036788 ) 513 2 - vert 614 ( 0.0493472107 0.133128047 ) 952 2 - vert 615 ( 0.1609368026 0.2095714808 ) 509 2 - vert 616 ( 0.0253295396 0.1273131371 ) 954 2 - vert 617 ( 0.1810530126 0.2063926458 ) 797 2 - vert 618 ( 0.0926404297 0.2340055704 ) 730 2 - vert 619 ( 0.2205203623 0.2318389416 ) 820 2 - vert 620 ( 0.2798832953 0.2400516272 ) 824 2 - vert 621 ( 0.1824166179 0.2241794467 ) 515 2 - vert 622 ( 0.3066275716 0.2904499173 ) 517 1 - vert 623 ( 0.2121662796 0.3043839931 ) 740 1 - vert 624 ( 0.2318297029 0.3024432063 ) 918 1 - vert 625 ( 0.1796101779 0.2976648808 ) 748 1 - vert 626 ( 0.2583833337 0.2881996632 ) 751 1 - vert 627 ( 0.2444739342 0.2935115695 ) 739 1 - vert 628 ( 0.1998132467 0.2987421751 ) 741 1 - vert 629 ( 0.2207421511 0.2761649489 ) 736 1 - vert 630 ( 0.2349794805 0.2770217657 ) 737 1 - vert 631 ( 0.2447223961 0.2831145525 ) 738 1 - vert 632 ( 0.1991215944 0.2893447876 ) 742 1 - vert 633 ( 0.2072287053 0.2808719873 ) 743 1 - vert 634 ( 0.3390630186 0.2856384516 ) 760 2 - vert 635 ( 0.4145067334 0.4730770588 ) 780 1 - vert 636 ( 0.2830866277 0.2339842319 ) 816 2 - vert 637 ( 0.2919953465 0.2246251106 ) 812 2 - vert 638 ( 0.3245466053 0.2377005816 ) 818 2 - vert 639 ( 0.3043735027 0.2466383576 ) 814 2 - vert 640 ( 0.3077458739 0.2142954469 ) 809 3 - vert 641 ( 0.3315804601 0.2017439604 ) 881 3 - vert 642 ( 0.1374716163 0.5366076231 ) 536 1 - vert 643 ( 0.013230687 0.5592079759 ) 567 1 - vert 644 ( 0.0239795577 0.5414884686 ) 865 1 - vert 645 ( 0.0175803714 0.5961876512 ) 570 1 - vert 646 ( 0.0110753831 0.5788846016 ) 571 1 - vert 647 ( 0.1181451455 0.5825795531 ) 568 1 - vert 648 ( 0.1031310037 0.6050055027 ) 683 1 - vert 649 ( 0.0827152058 0.6226586103 ) 569 1 - vert 650 ( 0.325393647 0.1892156005 ) 884 3 - vert 651 ( 0.0411293432 0.6158047915 ) 574 1 - vert 652 ( 0.9579395652 0.0860168338 ) 568 1 - vert 653 ( 0.5340631604 0.152531147 ) 728 2 - vert 654 ( 0.0583504289 0.8942132592 ) 780 1 - vert 655 ( 0.0217457116 0.9124113321 ) 716 1 - vert 656 ( 0.0021743923 0.9476748109 ) 774 1 - vert 657 ( 0.1303386241 0.9691649079 ) 801 2 - vert 658 ( 0.1184003651 0.9390746355 ) 762 2 - vert 659 ( 0.115521118 0.925874114 ) 715 1 - vert 660 ( 0.0988566875 0.9065935612 ) 712 1 - vert 661 ( 0.5047248006 0.1468339562 ) 891 2 - vert 662 ( 0.4947037399 0.4485718608 ) 919 1 - vert 663 ( 0.5007638335 0.4729495049 ) 716 1 - vert 664 ( 0.9935348034 0.0056322813 ) 574 1 - vert 665 ( 0.9720637202 0.0081043243 ) 573 1 - vert 666 ( 0.7080481648 0.2527147532 ) 863 2 - vert 667 ( 0.9357414842 0.3984293938 ) 597 3 - vert 668 ( 0.0312847868 0.1230297089 ) 966 2 - vert 669 ( 0.0517277829 0.1217052937 ) 950 2 - vert 670 ( 0.0462320745 0.1064546704 ) 964 2 - vert 671 ( 0.2404449284 0.0468884706 ) 976 2 - vert 672 ( 0.7014831305 0.2022577524 ) 978 2 - vert 673 ( 0.6995779872 0.114027977 ) 992 2 - vert 674 ( 0.5039020777 0.055891335 ) 992 2 - vert 675 ( 0.4725182056 0.131450057 ) 848 3 - vert 676 ( 0.470426172 0.0956435204 ) 992 2 - vert 677 ( 0.4844226241 0.5566906333 ) 1266 3 - vert 678 ( 0.4556623101 0.5267986059 ) 1604 3 - vert 679 ( 0.4623924494 0.5609875321 ) 1531 3 - vert 680 ( 0.5414105058 0.5618732572 ) 1275 3 - vert 681 ( 0.5258905292 0.5797734857 ) 1529 2 - vert 682 ( 0.6545919776 0.553827107 ) 1550 3 - vert 683 ( 0.6137748361 0.5438414216 ) 1278 3 - vert 684 ( 0.6068111062 0.5613096356 ) 1269 3 - vert 685 ( 0.6101557612 0.5782575607 ) 1536 2 - vert 686 ( 0.5893966556 0.5682316422 ) 1272 3 - vert 687 ( 0.8703344464 0.5548382401 ) 1566 3 - vert 688 ( 0.8001342416 0.531160295 ) 1572 2 - vert 689 ( 0.8273750544 0.5603625774 ) 1574 3 - vert 690 ( 0.909593761 0.541890204 ) 1281 2 - vert 691 ( 0.8767282963 0.5172954798 ) 1283 2 - vert 692 ( 0.8257008195 0.4912810326 ) 1569 3 - vert 693 ( 0.9619037509 0.5010288358 ) 2262 2 - vert 694 ( 0.9822099805 0.5455772281 ) 2260 2 - vert 695 ( 0.9197035432 0.4801701307 ) 2264 1 - vert 696 ( 0.9330515862 0.4684963822 ) 2264 1 - vert 697 ( 0.8558362722 0.4774233699 ) 2251 1 - vert 698 ( 0.9145989418 0.414915204 ) 1569 3 - vert 699 ( 0.5110726953 0.5216965079 ) 1290 2 - vert 700 ( 0.5121891499 0.5131419301 ) 1287 2 - vert 701 ( 0.47385481 0.5194527507 ) 1292 2 - vert 702 ( 0.4718330503 0.5102522969 ) 1285 2 - vert 703 ( 0.551738143 0.5262607932 ) 1602 2 - vert 704 ( 0.7645169497 0.5291875601 ) 1636 2 - vert 705 ( 0.7098010182 0.5331394672 ) 1294 2 - vert 706 ( 0.7643043399 0.5454066396 ) 1543 3 - vert 707 ( 0.6833952069 0.5247519016 ) 1546 2 - vert 708 ( 0.7608050704 0.5019616485 ) 1296 3 - vert 709 ( 0.6678441763 0.5021983981 ) 2265 1 - vert 710 ( 0.684728682 0.5411025882 ) 1440 2 - vert 711 ( 0.5425313711 0.5390426517 ) 1340 3 - vert 712 ( 0.1334860176 0.8372231722 ) 1499 2 - vert 713 ( 0.1161015332 0.8097634912 ) 1045 4 - vert 714 ( 0.066893965 0.8124876618 ) 1327 2 - vert 715 ( 0.1494105458 0.8061847091 ) 1495 2 - vert 716 ( 0.1067252457 0.7840147614 ) 1049 3 - vert 717 ( 0.1592390537 0.7751773 ) 1493 2 - vert 718 ( 0.0997084081 0.8485485911 ) 1329 2 - vert 719 ( 0.179611817 0.8616772294 ) 1503 3 - vert 720 ( 0.147523433 0.8784731627 ) 1506 2 - vert 721 ( 0.1823047549 0.7692033052 ) 1412 3 - vert 722 ( 0.4325293601 0.2030385733 ) 1065 1 - vert 723 ( 0.3934423327 0.2154853344 ) 1055 1 - vert 724 ( 0.450535506 0.1691389084 ) 1052 1 - vert 725 ( 0.2697971463 0.9388009906 ) 1456 2 - vert 726 ( 0.2203938365 0.9185550809 ) 1462 1 - vert 727 ( 0.2288205326 0.947565794 ) 1325 1 - vert 728 ( 0.2553950846 0.9668163657 ) 1323 1 - vert 729 ( 0.1856032014 0.9168928266 ) 1488 1 - vert 730 ( 0.1068721712 0.7543548346 ) 1099 2 - vert 731 ( 0.1589485258 0.7296697497 ) 1491 2 - vert 732 ( 0.4507423341 0.1269342899 ) 1053 2 - vert 733 ( 0.3470064998 0.1288274527 ) 1093 2 - vert 734 ( 0.4334782064 0.079718709 ) 1060 2 - vert 735 ( 0.3719279468 0.077619791 ) 1097 2 - vert 736 ( 0.4339954257 0.0209317207 ) 1064 1 - vert 737 ( 0.4459034801 0.0450025201 ) 1063 1 - vert 738 ( 0.3698011935 0.0322951674 ) 1056 1 - vert 739 ( 0.2829498053 0.9672400355 ) 1057 2 - vert 740 ( 0.4466976225 0.067032516 ) 1062 1 - vert 741 ( 0.3599961102 0.0640140772 ) 1102 1 - vert 742 ( 0.3147728443 0.9319956899 ) 1458 2 - vert 743 ( 0.1822359264 0.7390780449 ) 1415 3 - vert 744 ( 0.0806034729 0.8807800412 ) 1053 2 - vert 745 ( 0.0402057692 0.8406550884 ) 1052 1 - vert 746 ( 0.1453045607 0.9171644449 ) 1060 2 - vert 747 ( 0.1389578134 0.9456743598 ) 1062 1 - vert 748 ( 0.1576427966 0.9617500901 ) 1063 1 - vert 749 ( 0.1882094294 0.9814448357 ) 1064 1 - vert 750 ( 0.2093540281 0.994232893 ) 1059 1 - vert 751 ( 0.0557409525 0.7763756514 ) 1332 1 - vert 752 ( 0.0099953711 0.7629817128 ) 1055 1 - vert 753 ( 0.0173776969 0.8030573726 ) 1065 1 - vert 754 ( 0.6037270427 0.9436359406 ) 1066 1 - vert 755 ( 0.6084876657 0.9521949887 ) 1443 1 - vert 756 ( 0.6366115808 0.9544036388 ) 1444 1 - vert 757 ( 0.6703992486 0.952707231 ) 1067 1 - vert 758 ( 0.5618828535 0.942337811 ) 1397 1 - vert 759 ( 0.560995698 0.958578229 ) 1638 1 - vert 760 ( 0.6394431591 0.9342220426 ) 1398 1 - vert 761 ( 0.8133570552 0.9284562469 ) 1148 1 - vert 762 ( 0.784432292 0.9194583893 ) 1430 1 - vert 763 ( 0.7737931609 0.9313602448 ) 1068 1 - vert 764 ( 0.8335347772 0.9431957006 ) 1069 1 - vert 765 ( 0.8008987308 0.9501220584 ) 1432 1 - vert 766 ( 0.8591631055 0.9525725842 ) 1433 1 - vert 767 ( 0.755736053 0.9572163224 ) 1484 1 - vert 768 ( 0.7724640965 0.9715276957 ) 1070 1 - vert 769 ( 0.8242142797 0.9688520432 ) 1071 1 - vert 770 ( 0.7165766358 0.9756656289 ) 1072 1 - vert 771 ( 0.7490272522 0.9496366978 ) 1073 1 - vert 772 ( 0.5128636956 0.937730372 ) 1075 1 - vert 773 ( 0.4712091088 0.9368748069 ) 1111 1 - vert 774 ( 0.4679052532 0.9497407675 ) 1076 1 - vert 775 ( 0.5427181721 0.9391943812 ) 1074 1 - vert 776 ( 0.6465135217 0.9772025943 ) 1446 2 - vert 777 ( 0.6146071553 0.9775508642 ) 1451 2 - vert 778 ( 0.6032831669 0.9908323288 ) 1520 2 - vert 779 ( 0.56441468 0.9820660949 ) 1465 2 - vert 780 ( 0.6623260975 0.9858646393 ) 1485 2 - vert 781 ( 0.2639447749 0.9215126038 ) 1460 2 - vert 782 ( 0.3020117283 0.910166204 ) 1077 2 - vert 783 ( 0.2858190536 0.887234211 ) 1485 2 - vert 784 ( 0.5073122978 0.9638182521 ) 1399 1 - vert 785 ( 0.4756111205 0.962855041 ) 1396 1 - vert 786 ( 0.4740614891 0.9721466899 ) 1079 2 - vert 787 ( 0.5163108706 0.9739463329 ) 1081 2 - vert 788 ( 0.2377866209 0.7694252729 ) 1081 2 - vert 789 ( 0.1957567632 0.7691558599 ) 1421 3 - vert 790 ( 0.1955384016 0.8244740963 ) 1424 3 - vert 791 ( 0.1959729046 0.7359410524 ) 1418 3 - vert 792 ( 0.2387230694 0.735021174 ) 1079 2 - vert 793 ( 0.1097390354 0.7239818573 ) 1086 3 - vert 794 ( 0.1437117904 0.6944991946 ) 1497 2 - vert 795 ( 0.1027592719 0.6849401593 ) 1089 3 - vert 796 ( 0.1371669024 0.6676455736 ) 1489 2 - vert 797 ( 0.1918567866 0.660871923 ) 1508 2 - vert 798 ( 0.2045681477 0.6070845127 ) 1095 1 - vert 799 ( 0.2152799219 0.5780848265 ) 1326 1 - vert 800 ( 0.1750419289 0.6171837449 ) 1331 1 - vert 801 ( 0.0579406396 0.736762464 ) 1333 1 - vert 802 ( 0.3429104686 0.1694720387 ) 1101 1 - vert 803 ( 0.3846998215 0.0155730247 ) 1096 1 - vert 804 ( 0.2671828866 0.5739050508 ) 1057 2 - vert 805 ( 0.2437553555 0.5351557136 ) 1323 1 - vert 806 ( 0.2309366167 0.5582557321 ) 1324 1 - vert 807 ( 0.4134339392 0.0104567409 ) 1059 1 - vert 808 ( 0.3059405386 0.5908458829 ) 1479 2 - vert 809 ( 0.3124449253 0.5614993572 ) 1458 2 - vert 810 ( 0.1310676187 0.6106702685 ) 1097 2 - vert 811 ( 0.0868400261 0.646930337 ) 1093 2 - vert 812 ( 0.1290321946 0.5928460956 ) 1102 1 - vert 813 ( 0.1570510566 0.5653685927 ) 1056 1 - vert 814 ( 0.1781636477 0.5506376028 ) 1096 1 - vert 815 ( 0.2040627897 0.5200959444 ) 1059 1 - vert 816 ( 0.0161549896 0.7231362462 ) 1092 1 - vert 817 ( 0.0666880906 0.7012168765 ) 1334 2 - vert 818 ( 0.0445549861 0.679032743 ) 1101 1 - vert 819 ( 0.4098120332 0.9323342443 ) 1510 1 - vert 820 ( 0.3999845088 0.9443292618 ) 1103 1 - vert 821 ( 0.4223217368 0.9598748088 ) 1104 1 - vert 822 ( 0.4328830838 0.9551070333 ) 1483 1 - vert 823 ( 0.3793930113 0.9401033521 ) 1105 1 - vert 824 ( 0.3703452945 0.9301552773 ) 1526 1 - vert 825 ( 0.3317537308 0.9373200536 ) 1525 1 - vert 826 ( 0.8997014165 0.918351531 ) 1431 1 - vert 827 ( 0.8573371172 0.9288377166 ) 1106 1 - vert 828 ( 0.8910016418 0.9291102886 ) 1370 1 - vert 829 ( 0.8752990961 0.9434298277 ) 1371 1 - vert 830 ( 0.9644690752 0.9518621564 ) 1525 1 - vert 831 ( 0.9195224643 0.9697492719 ) 1109 1 - vert 832 ( 0.8722897172 0.9681579471 ) 1108 1 - vert 833 ( 0.9530124068 0.9723916054 ) 1516 2 - vert 834 ( 0.4402068257 0.9326683283 ) 1128 1 - vert 835 ( 0.9910877943 0.9151383042 ) 1439 1 - vert 836 ( 0.3836629391 0.9175986648 ) 1112 1 - vert 837 ( 0.3476499319 0.9151383042 ) 1439 1 - vert 838 ( 0.7507559657 0.8293662071 ) 1164 1 - vert 839 ( 0.6431443095 0.8385176063 ) 1115 1 - vert 840 ( 0.6946217418 0.842525363 ) 1114 1 - vert 841 ( 0.7608527541 0.8383695483 ) 1113 1 - vert 842 ( 0.7724551558 0.8519358039 ) 1345 1 - vert 843 ( 0.6439136267 0.8294796348 ) 1384 1 - vert 844 ( 0.5785608888 0.8244091868 ) 1391 1 - vert 845 ( 0.5721234083 0.8425920606 ) 1390 1 - vert 846 ( 0.6119430661 0.852090776 ) 1639 1 - vert 847 ( 0.5719413757 0.8559376001 ) 1395 1 - vert 848 ( 0.5691630244 0.7976005673 ) 1626 2 - vert 849 ( 0.5199398398 0.8045666814 ) 1628 2 - vert 850 ( 0.5756840706 0.8114767075 ) 1116 1 - vert 851 ( 0.478374958 0.7954993248 ) 1634 2 - vert 852 ( 0.4793157279 0.8038802743 ) 1125 2 - vert 853 ( 0.6574800611 0.9638392329 ) 1450 1 - vert 854 ( 0.6902530789 0.9726029634 ) 1445 1 - vert 855 ( 0.4234455526 0.7949019074 ) 1117 2 - vert 856 ( 0.4197468758 0.8094581962 ) 1127 1 - vert 857 ( 0.5627219677 0.8314959407 ) 1129 1 - vert 858 ( 0.5277945399 0.822684586 ) 1131 1 - vert 859 ( 0.521248281 0.8330779672 ) 1130 1 - vert 860 ( 0.4835053384 0.8322032094 ) 1135 1 - vert 861 ( 0.5234301686 0.8425521255 ) 1132 1 - vert 862 ( 0.4863252938 0.8419755101 ) 1133 1 - vert 863 ( 0.5241553783 0.8553082943 ) 1364 1 - vert 864 ( 0.478515774 0.821737349 ) 1136 1 - vert 865 ( 0.4278247356 0.8229885101 ) 1137 1 - vert 866 ( 0.4378047585 0.8287451863 ) 1134 1 - vert 867 ( 0.4286729693 0.839835465 ) 1435 1 - vert 868 ( 0.4772183597 0.8542438745 ) 1365 1 - vert 869 ( 0.5414910913 0.7344099879 ) 1139 1 - vert 870 ( 0.5035853386 0.7204599977 ) 1408 1 - vert 871 ( 0.5144074559 0.7354066968 ) 1138 1 - vert 872 ( 0.5407606959 0.7438425422 ) 1142 2 - vert 873 ( 0.5167495012 0.743672967 ) 1140 2 - vert 874 ( 0.5180986524 0.7867024541 ) 1622 2 - vert 875 ( 0.5432906747 0.782232821 ) 1630 2 - vert 876 ( 0.5840035677 0.7776081562 ) 1404 2 - vert 877 ( 0.5607374907 0.7413419485 ) 1146 2 - vert 878 ( 0.563646853 0.7779686451 ) 1144 2 - vert 879 ( 0.5807990432 0.7405381799 ) 1402 2 - vert 880 ( 0.5650606155 0.725248754 ) 1400 2 - vert 881 ( 0.5855128169 0.7861213088 ) 1406 2 - vert 882 ( 0.5442879796 0.7908129096 ) 1632 2 - vert 883 ( 0.2513518929 0.8579275608 ) 1520 2 - vert 884 ( 0.2381370366 0.8270900249 ) 1465 2 - vert 885 ( 0.2083846331 0.8941267729 ) 1501 2 - vert 886 ( 0.6198198795 0.9296262264 ) 1338 1 - vert 887 ( 0.5674852729 0.9353048801 ) 1339 1 - vert 888 ( 0.4179138541 0.9278628826 ) 1392 1 - vert 889 ( 0.4167684317 0.9034226537 ) 1393 1 - vert 890 ( 0.7872781157 0.942671895 ) 1372 1 - vert 891 ( 0.4822467864 0.7343027592 ) 1149 1 - vert 892 ( 0.4474436045 0.7269634008 ) 1409 1 - vert 893 ( 0.4751650989 0.7425705791 ) 1154 2 - vert 894 ( 0.4495840371 0.7772583365 ) 1150 2 - vert 895 ( 0.4732451439 0.7853062749 ) 1160 2 - vert 896 ( 0.439622879 0.737051785 ) 1410 2 - vert 897 ( 0.4277955592 0.7710473537 ) 1158 2 - vert 898 ( 0.4514044225 0.7894487381 ) 1152 2 - vert 899 ( 0.4954291284 0.7882047296 ) 1624 2 - vert 900 ( 0.8525081277 0.8153198361 ) 1383 1 - vert 901 ( 0.800086081 0.8255887628 ) 1162 1 - vert 902 ( 0.8529195786 0.8239960074 ) 1163 1 - vert 903 ( 0.7966136932 0.8169261813 ) 1382 1 - vert 904 ( 0.7988685966 0.8324139118 ) 1165 1 - vert 905 ( 0.8551995158 0.8303270936 ) 1167 1 - vert 906 ( 0.8307558894 0.8504498601 ) 1343 1 - vert 907 ( 0.91786623 0.8181647062 ) 1386 1 - vert 908 ( 0.9086131454 0.8271304965 ) 1166 1 - vert 909 ( 0.9875124097 0.8251116276 ) 1387 1 - vert 910 ( 0.9611976743 0.8418433666 ) 1388 1 - vert 911 ( 0.8971911073 0.8505310416 ) 1344 1 - vert 912 ( 0.1833636761 0.8938746452 ) 1487 1 - vert 913 ( 0.4352655709 0.9708566666 ) 1514 2 - vert 914 ( 0.2419928014 0.6990239024 ) 1514 2 - vert 915 ( 0.1930899769 0.6971670389 ) 1427 3 - vert 916 ( 0.1811438352 0.701256156 ) 1169 3 - vert 917 ( 0.2407904118 0.6583088636 ) 1512 2 - vert 918 ( 0.2714389563 0.6168953776 ) 1518 2 - vert 919 ( 0.2578628361 0.5946584344 ) 1481 2 - vert 920 ( 0.2125813663 0.6291373372 ) 1172 2 - vert 921 ( 0.694883883 0.890166223 ) 1178 1 - vert 922 ( 0.6742520332 0.9002227783 ) 1181 1 - vert 923 ( 0.786329329 0.9057593942 ) 1185 1 - vert 924 ( 0.7896624207 0.8882235289 ) 1175 1 - vert 925 ( 0.8396375775 0.8866693377 ) 1174 1 - vert 926 ( 0.6730630398 0.9216036201 ) 1464 1 - vert 927 ( 0.7366696596 0.8681755066 ) 1177 1 - vert 928 ( 0.8197116256 0.8694882989 ) 1176 1 - vert 929 ( 0.6179950833 0.8907406926 ) 1179 1 - vert 930 ( 0.5915611982 0.8850938678 ) 1366 1 - vert 931 ( 0.6015017629 0.8973373175 ) 1180 1 - vert 932 ( 0.574015975 0.9066434503 ) 1367 1 - vert 933 ( 0.6254544258 0.9187117219 ) 1442 1 - vert 934 ( 0.5960944295 0.8636288643 ) 1363 1 - vert 935 ( 0.6200924516 0.8650151491 ) 1182 1 - vert 936 ( 0.9534772635 0.8989229202 ) 1186 1 - vert 937 ( 0.8950863481 0.8862002492 ) 1183 1 - vert 938 ( 0.8784033656 0.9039754868 ) 1184 1 - vert 939 ( 0.9449782372 0.8866115808 ) 1188 1 - vert 940 ( 0.8526121974 0.8691055179 ) 1189 1 - vert 941 ( 0.9165329337 0.8665160537 ) 1187 1 - vert 942 ( 0.4082273245 0.8925260901 ) 1437 1 - vert 943 ( 0.3780546784 0.885679543 ) 1190 1 - vert 944 ( 0.386038661 0.8951603174 ) 1191 1 - vert 945 ( 0.3854143023 0.9094774723 ) 1394 1 - vert 946 ( 0.3620855808 0.8712576032 ) 1389 1 - vert 947 ( 0.2855044305 0.8725754619 ) 1187 1 - vert 948 ( 0.3084830642 0.8866115808 ) 1188 1 - vert 949 ( 0.3185078204 0.8989229202 ) 1186 1 - vert 950 ( 0.5505428314 0.9041790366 ) 1336 1 - vert 951 ( 0.5107603669 0.9297960997 ) 1379 1 - vert 952 ( 0.5435915589 0.9326674938 ) 1378 1 - vert 953 ( 0.5141093731 0.8962922692 ) 1192 1 - vert 954 ( 0.4773729742 0.9290877581 ) 1380 1 - vert 955 ( 0.4786817729 0.8956178427 ) 1193 1 - vert 956 ( 0.5482464433 0.8635425568 ) 1374 1 - vert 957 ( 0.5145289898 0.8645966649 ) 1376 1 - vert 958 ( 0.482365489 0.8637974262 ) 1377 1 - vert 959 ( 0.4400782585 0.9015974998 ) 1337 1 - vert 960 ( 0.4425452352 0.9287195206 ) 1381 1 - vert 961 ( 0.4476633966 0.861060679 ) 1375 1 - vert 962 ( 0.5705474019 0.8626556993 ) 1368 1 - vert 963 ( 0.4310365319 0.8612377048 ) 1373 1 - vert 964 ( 0.4268456399 0.8531342149 ) 1436 1 - vert 965 ( 0.4038036466 0.7231858969 ) 1196 1 - vert 966 ( 0.359282434 0.7307472825 ) 1616 2 - vert 967 ( 0.4004597664 0.7391049266 ) 1197 2 - vert 968 ( 0.8957604766 0.7239615917 ) 1580 2 - vert 969 ( 0.7741333842 0.7348031402 ) 1582 2 - vert 970 ( 0.9213752747 0.7375072837 ) 1522 2 - vert 971 ( 0.806820333 0.7447397113 ) 1207 2 - vert 972 ( 0.710531652 0.7345507145 ) 1584 2 - vert 973 ( 0.6343027353 0.7398629785 ) 1199 2 - vert 974 ( 0.6962388754 0.7495731115 ) 1527 2 - vert 975 ( 0.4256101549 0.6858440638 ) 1612 1 - vert 976 ( 0.3675605655 0.7146486044 ) 1194 1 - vert 977 ( 0.4699153304 0.6971183419 ) 1577 1 - vert 978 ( 0.4695941508 0.7092337012 ) 1195 1 - vert 979 ( 0.6650369763 0.7221435905 ) 1217 2 - vert 980 ( 0.5916910768 0.7120783925 ) 1615 1 - vert 981 ( 0.9797732234 0.7176145315 ) 1194 1 - vert 982 ( 0.9669525027 0.6981096268 ) 1613 2 - vert 983 ( 0.6215757728 0.7501673102 ) 1201 2 - vert 984 ( 0.6178281307 0.7569681406 ) 1211 2 - vert 985 ( 0.8144189715 0.760948658 ) 1205 2 - vert 986 ( 0.6374437213 0.7690489888 ) 1215 2 - vert 987 ( 0.9750631452 0.7317526937 ) 1616 2 - vert 988 ( 0.9553364515 0.7473914027 ) 1213 2 - vert 989 ( 0.9111297727 0.7560218573 ) 1203 2 - vert 990 ( 0.6938430071 0.762709856 ) 1250 2 - vert 991 ( 0.9322875142 0.7649632096 ) 1596 2 - vert 992 ( 0.6424546242 0.7811055183 ) 1592 2 - vert 993 ( 0.8909954429 0.7691081166 ) 1301 2 - vert 994 ( 0.3917136192 0.7533002496 ) 1209 2 - vert 995 ( 0.3084173203 0.7650984526 ) 1596 2 - vert 996 ( 0.3822190762 0.7685795426 ) 1299 2 - vert 997 ( 0.3428479433 0.7473681569 ) 1213 2 - vert 998 ( 0.8579117656 0.7914496064 ) 1586 2 - vert 999 ( 0.727822125 0.7784240246 ) 1590 2 - vert 1000 ( 0.9140110612 0.7000353336 ) 1578 2 - vert 1001 ( 0.8526973128 0.6914362907 ) 1219 2 - vert 1002 ( 0.7698711157 0.7072541118 ) 1248 2 - vert 1003 ( 0.3492717743 0.6981096268 ) 1613 2 - vert 1004 ( 0.6246590018 0.6811992526 ) 1611 1 - vert 1005 ( 0.7301080823 0.7051903009 ) 1246 2 - vert 1006 ( 0.5407672524 0.6966646314 ) 1221 1 - vert 1007 ( 0.51039958 0.7091558576 ) 1369 1 - vert 1008 ( 0.5188540816 0.6799803376 ) 1222 1 - vert 1009 ( 0.7069051862 0.6559785008 ) 1609 2 - vert 1010 ( 0.899766624 0.6474706531 ) 1600 2 - vert 1011 ( 0.7829682231 0.6644138694 ) 1524 1 - vert 1012 ( 0.5533827543 0.6647381186 ) 1243 1 - vert 1013 ( 0.6242524981 0.6262385249 ) 1313 2 - vert 1014 ( 0.948190093 0.6110125184 ) 1227 2 - vert 1015 ( 0.9421514869 0.6479540467 ) 1235 2 - vert 1016 ( 0.3580010533 0.6196772456 ) 1231 2 - vert 1017 ( 0.3065644503 0.6256317496 ) 2237 3 - vert 1018 ( 0.3248864412 0.6501572132 ) 1241 2 - vert 1019 ( 0.399297893 0.6426792741 ) 1239 2 - vert 1020 ( 0.9931611419 0.6145679951 ) 2237 3 - vert 1021 ( 0.9783809781 0.6451755762 ) 1241 2 - vert 1022 ( 0.6862653494 0.6110110879 ) 1252 2 - vert 1023 ( 0.6523242593 0.5940893888 ) 1256 2 - vert 1024 ( 0.4741988778 0.5722598433 ) 1223 2 - vert 1025 ( 0.4291833341 0.6034495831 ) 1229 2 - vert 1026 ( 0.4815787971 0.6437709332 ) 1237 2 - vert 1027 ( 0.7335687876 0.5797832608 ) 1556 2 - vert 1028 ( 0.9081220031 0.5980070233 ) 1258 2 - vert 1029 ( 0.8656434417 0.575014472 ) 1564 2 - vert 1030 ( 0.8918976188 0.6154376864 ) 1225 2 - vert 1031 ( 0.8163060546 0.6120387912 ) 1598 2 - vert 1032 ( 0.3544656634 0.6056483984 ) 1469 2 - vert 1033 ( 0.3111388087 0.6077952385 ) 2240 1 - vert 1034 ( 0.3026942015 0.6163628697 ) 2242 3 - vert 1035 ( 0.9844691157 0.5990278125 ) 2254 3 - vert 1036 ( 0.7950555682 0.6415287852 ) 1233 2 - vert 1037 ( 0.5458924174 0.6339027286 ) 1244 2 - vert 1038 ( 0.4389449954 0.5731776357 ) 1254 2 - vert 1039 ( 0.8238632083 0.5803208947 ) 1558 3 - vert 1040 ( 0.9684378505 0.5824438334 ) 2257 3 - vert 1041 ( 0.3967536092 0.5808766484 ) 1264 2 - vert 1042 ( 0.3255569339 0.5728743672 ) 2245 1 - vert 1043 ( 0.3223926723 0.5894172192 ) 2246 1 - vert 1044 ( 0.3826692104 0.592597127 ) 1260 2 - vert 1045 ( 0.4239892066 0.5822885036 ) 1467 2 - vert 1046 ( 0.3194819689 0.5985639691 ) 2241 1 - vert 1047 ( 0.432539463 0.5300771594 ) 1618 2 - vert 1048 ( 0.3245143294 0.5239104629 ) 2252 2 - vert 1049 ( 0.3994908929 0.5540006757 ) 1262 2 - vert 1050 ( 0.4291992486 0.5542880893 ) 1473 3 - vert 1051 ( 0.4154266715 0.5975065231 ) 1471 2 - vert 1052 ( 0.9345200658 0.7956544161 ) 1588 2 - vert 1053 ( 0.3817654848 0.7862767577 ) 1594 2 - vert 1054 ( 0.7691301703 0.7937842011 ) 1303 2 - vert 1055 ( 0.3624657393 0.8172302246 ) 1434 1 - vert 1056 ( 0.377725482 0.8053206205 ) 1307 2 - vert 1057 ( 0.3175797164 0.8251116276 ) 1387 1 - vert 1058 ( 0.7873748541 0.8050133586 ) 1309 1 - vert 1059 ( 0.8695567846 0.8089385033 ) 1305 1 - vert 1060 ( 0.963134706 0.805110395 ) 1306 1 - vert 1061 ( 0.70623523 0.806235671 ) 1385 1 - vert 1062 ( 0.4203434587 0.7858124375 ) 1310 2 - vert 1063 ( 0.293201983 0.805110395 ) 1306 1 - vert 1064 ( 0.2800888121 0.7917528749 ) 1588 2 - vert 1065 ( 0.7328642607 0.7992414832 ) 1312 1 - vert 1066 ( 0.327460289 0.5475998521 ) 2247 2 - vert 1067 ( 0.3551490903 0.2034666538 ) 1092 1 - vert 1068 ( 0.3898702264 0.8312378526 ) 1320 1 - vert 1069 ( 0.3641453683 0.8268107176 ) 1321 1 - vert 1070 ( 0.4006169438 0.8430785537 ) 1319 1 - vert 1071 ( 0.3360689282 0.8342242241 ) 1322 1 - vert 1072 ( 0.3933908045 0.855396688 ) 1318 1 - vert 1073 ( 0.3337395787 0.8506288528 ) 1640 1 - vert 1074 ( 0.3620383739 0.8603591323 ) 1317 1 - vert 1075 ( 0.6693634391 0.8196830153 ) 1362 1 - vert 1076 ( 0.6798722148 0.8088632226 ) 1353 1 - vert 1077 ( 0.6446796656 0.8240692019 ) 1361 1 - vert 1078 ( 0.6702853441 0.797947824 ) 1354 1 - vert 1079 ( 0.6218754053 0.8194525242 ) 1360 1 - vert 1080 ( 0.6448164582 0.7933310866 ) 1355 2 - vert 1081 ( 0.6131525636 0.8085372448 ) 1359 1 - vert 1082 ( 0.6212505698 0.7977173924 ) 1357 2 - vert 1083 ( 0.3116773665 0.8574773073 ) 1315 1 - vert 1084 ( 0.4109322429 0.8572394848 ) 1438 1 - vert 1085 ( 0.4099704027 0.823318541 ) 1316 1 - vert 1086 ( 0.2912650704 0.8418433666 ) 1388 1 - vert 1087 ( 0.689548254 0.7895273566 ) 1346 2 - vert 1088 ( 0.5901307464 0.8057367206 ) 1350 1 - vert 1089 ( 0.6018051505 0.7921656966 ) 1348 2 - vert 1090 ( 0.6035143137 0.8224451542 ) 1351 1 - vert 1091 ( 0.6850998998 0.82190907 ) 1352 1 - vert 1092 ( 0.7400199175 0.8212472796 ) 1168 1 - vert 1093 ( 0.9816100001 0.8574773073 ) 1315 1 - vert 1094 ( 0.5159634352 0.9509907365 ) 1110 1 - vert 1095 ( 0.5263341069 0.9614715576 ) 1463 1 - vert 1096 ( 0.4574320614 0.9597361088 ) 1107 1 - vert 1097 ( 0.4118084013 0.7727532983 ) 1156 2 - vert 1098 ( 0.1813786179 0.8128939867 ) 1083 3 - vert 1099 ( 0.6000680923 0.9609757662 ) 1453 1 - vert 1100 ( 0.5989988446 0.9708634019 ) 1448 2 - vert 1101 ( 0.5620049238 0.9718698859 ) 1454 2 - vert 1102 ( 0.3586400449 0.9429779649 ) 1478 1 - vert 1103 ( 0.3415579796 0.9506332278 ) 1476 1 - vert 1104 ( 0.3803156912 0.9470651746 ) 1123 1 - vert 1105 ( 0.3920620084 0.9557168484 ) 1124 1 - vert 1106 ( 0.8232848048 0.9789833426 ) 1458 2 - vert 1107 ( 0.8948417902 0.9775547385 ) 1479 2 - vert 1108 ( 0.7517197728 0.9819450378 ) 1077 2 - vert 1109 ( 0.1833622754 0.6334704161 ) 1511 1 - vert 1110 ( 0.3565215766 0.9672869444 ) 1121 2 - vert 1111 ( 0.3300353885 0.9838322997 ) 1518 2 - vert 1112 ( 0.3851564527 0.9906263351 ) 1512 2 - vert 1113 ( 0.3804599941 0.9662017226 ) 1119 2 - vert 1114 ( 0.3307661712 0.9583724737 ) 1477 1 - vert 1115 ( 0.3027388453 0.9723916054 ) 1516 2 - vert 1116 ( 0.9727258682 0.9859603643 ) 1518 2 - vert 1117 ( 0.4545708001 0.4958548546 ) 1534 2 - vert 1118 ( 0.328756094 0.490121007 ) 2249 2 - vert 1119 ( 0.4894213676 0.4945927858 ) 1289 1 - vert 1120 ( 0.7168648243 0.3641926646 ) 1548 2 - vert 1121 ( 0.7681257129 0.3391145468 ) 1542 1 - vert 1122 ( 0.5403671265 0.4973586798 ) 1548 2 - vert 1123 ( 0.6013734937 0.5281243324 ) 1607 2 - vert 1124 ( 0.6079990268 0.5030022264 ) 1542 1 - vert 1125 ( 0.8147406578 0.3371991515 ) 2265 1 - vert 1126 ( 0.6477783918 0.527874589 ) 1540 2 - vert 1127 ( 0.6476663351 0.5388614535 ) 1538 2 - vert 1128 ( 0.6646463871 0.5732014179 ) 1553 3 - vert 1129 ( 0.9247060418 0.5648664832 ) 1561 3 - vert 1130 ( 0.8690063357 0.3619178534 ) 1296 3 - vert 1131 ( 0.6961885095 0.4022818804 ) 1289 1 - vert 1132 ( 0.6967608333 0.4512689114 ) 1534 2 - vert 1133 ( 0.7017322183 0.4941772819 ) 2249 2 - vert 1134 ( 0.5210370421 0.7928661704 ) 1620 2 - vert 1135 ( 0.4556623101 0.5267986059 ) 2200 3 - vert 1136 ( 0.4844226241 0.5566906333 ) 1862 3 - vert 1137 ( 0.4623924494 0.5609875321 ) 2127 3 - vert 1138 ( 0.5414105058 0.5618732572 ) 1871 3 - vert 1139 ( 0.5258905292 0.5797734857 ) 2125 2 - vert 1140 ( 0.6137748361 0.5438414216 ) 1874 3 - vert 1141 ( 0.6545919776 0.553827107 ) 2146 3 - vert 1142 ( 0.6068111062 0.5613096356 ) 1865 3 - vert 1143 ( 0.6101557612 0.5782575607 ) 2132 2 - vert 1144 ( 0.5893966556 0.5682316422 ) 1868 3 - vert 1145 ( 0.8001342416 0.531160295 ) 2168 2 - vert 1146 ( 0.8703344464 0.5548382401 ) 2162 3 - vert 1147 ( 0.8273750544 0.5603625774 ) 2170 3 - vert 1148 ( 0.909593761 0.541890204 ) 1877 2 - vert 1149 ( 0.8767282963 0.5172954798 ) 1879 2 - vert 1150 ( 0.8257008195 0.4912810326 ) 2165 3 - vert 1151 ( 0.9145989418 0.414915204 ) 2165 3 - vert 1152 ( 0.5121891499 0.5131419301 ) 1883 2 - vert 1153 ( 0.5110726953 0.5216965079 ) 1886 2 - vert 1154 ( 0.47385481 0.5194527507 ) 1888 2 - vert 1155 ( 0.4718330503 0.5102522969 ) 1881 2 - vert 1156 ( 0.551738143 0.5262607932 ) 2198 2 - vert 1157 ( 0.7098010182 0.5331394672 ) 1890 2 - vert 1158 ( 0.7645169497 0.5291875601 ) 2232 2 - vert 1159 ( 0.7643043399 0.5454066396 ) 2139 3 - vert 1160 ( 0.6833952069 0.5247519016 ) 2142 2 - vert 1161 ( 0.7608050704 0.5019616485 ) 1892 3 - vert 1162 ( 0.6678441763 0.5021983981 ) 2266 1 - vert 1163 ( 0.684728682 0.5411025882 ) 2036 2 - vert 1164 ( 0.5425313711 0.5390426517 ) 1936 3 - vert 1165 ( 0.1161015332 0.8097634912 ) 1641 4 - vert 1166 ( 0.1334860176 0.8372231722 ) 2095 2 - vert 1167 ( 0.066893965 0.8124876618 ) 1923 2 - vert 1168 ( 0.1067252457 0.7840147614 ) 1645 3 - vert 1169 ( 0.1494105458 0.8061847091 ) 2091 2 - vert 1170 ( 0.1592390537 0.7751773 ) 2089 2 - vert 1171 ( 0.0997084081 0.8485485911 ) 1925 2 - vert 1172 ( 0.179611817 0.8616772294 ) 2099 3 - vert 1173 ( 0.147523433 0.8784731627 ) 2102 2 - vert 1174 ( 0.1823047549 0.7692033052 ) 2008 3 - vert 1175 ( 0.3934423327 0.2154853344 ) 1651 1 - vert 1176 ( 0.4325293601 0.2030385733 ) 1661 1 - vert 1177 ( 0.450535506 0.1691389084 ) 1648 1 - vert 1178 ( 0.2203938365 0.9185550809 ) 2058 1 - vert 1179 ( 0.2697971463 0.9388009906 ) 2052 2 - vert 1180 ( 0.2288205326 0.947565794 ) 1921 1 - vert 1181 ( 0.2553950846 0.9668163657 ) 1919 1 - vert 1182 ( 0.1856032014 0.9168928266 ) 2084 1 - vert 1183 ( 0.1068721712 0.7543548346 ) 1695 2 - vert 1184 ( 0.1589485258 0.7296697497 ) 2087 2 - vert 1185 ( 0.4507423341 0.1269342899 ) 1649 2 - vert 1186 ( 0.3470064998 0.1288274527 ) 1689 2 - vert 1187 ( 0.4334782064 0.079718709 ) 1656 2 - vert 1188 ( 0.3719279468 0.077619791 ) 1693 2 - vert 1189 ( 0.4459034801 0.0450025201 ) 1659 1 - vert 1190 ( 0.4339954257 0.0209317207 ) 1660 1 - vert 1191 ( 0.3698011935 0.0322951674 ) 1652 1 - vert 1192 ( 0.2829498053 0.9672400355 ) 1653 2 - vert 1193 ( 0.4466976225 0.067032516 ) 1658 1 - vert 1194 ( 0.3599961102 0.0640140772 ) 1698 1 - vert 1195 ( 0.3147728443 0.9319956899 ) 2054 2 - vert 1196 ( 0.1822359264 0.7390780449 ) 2011 3 - vert 1197 ( 0.0806034729 0.8807800412 ) 1649 2 - vert 1198 ( 0.0402057692 0.8406550884 ) 1648 1 - vert 1199 ( 0.1453045607 0.9171644449 ) 1656 2 - vert 1200 ( 0.1389578134 0.9456743598 ) 1658 1 - vert 1201 ( 0.1576427966 0.9617500901 ) 1659 1 - vert 1202 ( 0.1882094294 0.9814448357 ) 1660 1 - vert 1203 ( 0.2093540281 0.994232893 ) 1655 1 - vert 1204 ( 0.0099953711 0.7629817128 ) 1651 1 - vert 1205 ( 0.0557409525 0.7763756514 ) 1928 1 - vert 1206 ( 0.0173776969 0.8030573726 ) 1661 1 - vert 1207 ( 0.6084876657 0.9521949887 ) 2039 1 - vert 1208 ( 0.6037270427 0.9436359406 ) 1662 1 - vert 1209 ( 0.6366115808 0.9544036388 ) 2040 1 - vert 1210 ( 0.6703992486 0.952707231 ) 1663 1 - vert 1211 ( 0.5618828535 0.942337811 ) 1993 1 - vert 1212 ( 0.560995698 0.958578229 ) 2234 1 - vert 1213 ( 0.6394431591 0.9342220426 ) 1994 1 - vert 1214 ( 0.784432292 0.9194583893 ) 2026 1 - vert 1215 ( 0.8133570552 0.9284562469 ) 1744 1 - vert 1216 ( 0.7737931609 0.9313602448 ) 1664 1 - vert 1217 ( 0.8008987308 0.9501220584 ) 2028 1 - vert 1218 ( 0.8335347772 0.9431957006 ) 1665 1 - vert 1219 ( 0.8591631055 0.9525725842 ) 2029 1 - vert 1220 ( 0.755736053 0.9572163224 ) 2080 1 - vert 1221 ( 0.7724640965 0.9715276957 ) 1666 1 - vert 1222 ( 0.8242142797 0.9688520432 ) 1667 1 - vert 1223 ( 0.7165766358 0.9756656289 ) 1668 1 - vert 1224 ( 0.7490272522 0.9496366978 ) 1669 1 - vert 1225 ( 0.4712091088 0.9368748069 ) 1707 1 - vert 1226 ( 0.5128636956 0.937730372 ) 1671 1 - vert 1227 ( 0.4679052532 0.9497407675 ) 1672 1 - vert 1228 ( 0.5427181721 0.9391943812 ) 1670 1 - vert 1229 ( 0.6146071553 0.9775508642 ) 2047 2 - vert 1230 ( 0.6465135217 0.9772025943 ) 2042 2 - vert 1231 ( 0.6032831669 0.9908323288 ) 2116 2 - vert 1232 ( 0.56441468 0.9820660949 ) 2061 2 - vert 1233 ( 0.6623260975 0.9858646393 ) 2081 2 - vert 1234 ( 0.2639447749 0.9215126038 ) 2056 2 - vert 1235 ( 0.2858190536 0.887234211 ) 2081 2 - vert 1236 ( 0.3020117283 0.910166204 ) 1673 2 - vert 1237 ( 0.4756111205 0.962855041 ) 1992 1 - vert 1238 ( 0.5073122978 0.9638182521 ) 1995 1 - vert 1239 ( 0.4740614891 0.9721466899 ) 1675 2 - vert 1240 ( 0.5163108706 0.9739463329 ) 1677 2 - vert 1241 ( 0.1957567632 0.7691558599 ) 2017 3 - vert 1242 ( 0.2377866209 0.7694252729 ) 1677 2 - vert 1243 ( 0.1955384016 0.8244740963 ) 2020 3 - vert 1244 ( 0.1959729046 0.7359410524 ) 2014 3 - vert 1245 ( 0.2387230694 0.735021174 ) 1675 2 - vert 1246 ( 0.1437117904 0.6944991946 ) 2093 2 - vert 1247 ( 0.1097390354 0.7239818573 ) 1682 3 - vert 1248 ( 0.1027592719 0.6849401593 ) 1685 3 - vert 1249 ( 0.1371669024 0.6676455736 ) 2085 2 - vert 1250 ( 0.1918567866 0.660871923 ) 2104 2 - vert 1251 ( 0.2152799219 0.5780848265 ) 1922 1 - vert 1252 ( 0.2045681477 0.6070845127 ) 1691 1 - vert 1253 ( 0.1750419289 0.6171837449 ) 1927 1 - vert 1254 ( 0.0579406396 0.736762464 ) 1929 1 - vert 1255 ( 0.3429104686 0.1694720387 ) 1697 1 - vert 1256 ( 0.3846998215 0.0155730247 ) 1692 1 - vert 1257 ( 0.2437553555 0.5351557136 ) 1919 1 - vert 1258 ( 0.2671828866 0.5739050508 ) 1653 2 - vert 1259 ( 0.2309366167 0.5582557321 ) 1920 1 - vert 1260 ( 0.4134339392 0.0104567409 ) 1655 1 - vert 1261 ( 0.3124449253 0.5614993572 ) 2054 2 - vert 1262 ( 0.3059405386 0.5908458829 ) 2075 2 - vert 1263 ( 0.1310676187 0.6106702685 ) 1693 2 - vert 1264 ( 0.0868400261 0.646930337 ) 1689 2 - vert 1265 ( 0.1290321946 0.5928460956 ) 1698 1 - vert 1266 ( 0.1570510566 0.5653685927 ) 1652 1 - vert 1267 ( 0.1781636477 0.5506376028 ) 1692 1 - vert 1268 ( 0.2040627897 0.5200959444 ) 1655 1 - vert 1269 ( 0.0161549896 0.7231362462 ) 1688 1 - vert 1270 ( 0.0666880906 0.7012168765 ) 1930 2 - vert 1271 ( 0.0445549861 0.679032743 ) 1697 1 - vert 1272 ( 0.3999845088 0.9443292618 ) 1699 1 - vert 1273 ( 0.4098120332 0.9323342443 ) 2106 1 - vert 1274 ( 0.4223217368 0.9598748088 ) 1700 1 - vert 1275 ( 0.4328830838 0.9551070333 ) 2079 1 - vert 1276 ( 0.3793930113 0.9401033521 ) 1701 1 - vert 1277 ( 0.3703452945 0.9301552773 ) 2122 1 - vert 1278 ( 0.3317537308 0.9373200536 ) 2121 1 - vert 1279 ( 0.8573371172 0.9288377166 ) 1702 1 - vert 1280 ( 0.8997014165 0.918351531 ) 2027 1 - vert 1281 ( 0.8910016418 0.9291102886 ) 1966 1 - vert 1282 ( 0.8752990961 0.9434298277 ) 1967 1 - vert 1283 ( 0.9644690752 0.9518621564 ) 2121 1 - vert 1284 ( 0.9195224643 0.9697492719 ) 1705 1 - vert 1285 ( 0.8722897172 0.9681579471 ) 1704 1 - vert 1286 ( 0.9530124068 0.9723916054 ) 2112 2 - vert 1287 ( 0.4402068257 0.9326683283 ) 1724 1 - vert 1288 ( 0.9910877943 0.9151383042 ) 2035 1 - vert 1289 ( 0.3476499319 0.9151383042 ) 2035 1 - vert 1290 ( 0.3836629391 0.9175986648 ) 1708 1 - vert 1291 ( 0.6431443095 0.8385176063 ) 1711 1 - vert 1292 ( 0.7507559657 0.8293662071 ) 1760 1 - vert 1293 ( 0.6946217418 0.842525363 ) 1710 1 - vert 1294 ( 0.7608527541 0.8383695483 ) 1709 1 - vert 1295 ( 0.7724551558 0.8519358039 ) 1941 1 - vert 1296 ( 0.5785608888 0.8244091868 ) 1987 1 - vert 1297 ( 0.6439136267 0.8294796348 ) 1980 1 - vert 1298 ( 0.5721234083 0.8425920606 ) 1986 1 - vert 1299 ( 0.6119430661 0.852090776 ) 2235 1 - vert 1300 ( 0.5719413757 0.8559376001 ) 1991 1 - vert 1301 ( 0.5199398398 0.8045666814 ) 2224 2 - vert 1302 ( 0.5691630244 0.7976005673 ) 2222 2 - vert 1303 ( 0.5756840706 0.8114767075 ) 1712 1 - vert 1304 ( 0.478374958 0.7954993248 ) 2230 2 - vert 1305 ( 0.4793157279 0.8038802743 ) 1721 2 - vert 1306 ( 0.6574800611 0.9638392329 ) 2046 1 - vert 1307 ( 0.6902530789 0.9726029634 ) 2041 1 - vert 1308 ( 0.4234455526 0.7949019074 ) 1713 2 - vert 1309 ( 0.4197468758 0.8094581962 ) 1723 1 - vert 1310 ( 0.5627219677 0.8314959407 ) 1725 1 - vert 1311 ( 0.5277945399 0.822684586 ) 1727 1 - vert 1312 ( 0.521248281 0.8330779672 ) 1726 1 - vert 1313 ( 0.4835053384 0.8322032094 ) 1731 1 - vert 1314 ( 0.5234301686 0.8425521255 ) 1728 1 - vert 1315 ( 0.4863252938 0.8419755101 ) 1729 1 - vert 1316 ( 0.5241553783 0.8553082943 ) 1960 1 - vert 1317 ( 0.4278247356 0.8229885101 ) 1733 1 - vert 1318 ( 0.478515774 0.821737349 ) 1732 1 - vert 1319 ( 0.4378047585 0.8287451863 ) 1730 1 - vert 1320 ( 0.4286729693 0.839835465 ) 2031 1 - vert 1321 ( 0.4772183597 0.8542438745 ) 1961 1 - vert 1322 ( 0.5035853386 0.7204599977 ) 2004 1 - vert 1323 ( 0.5414910913 0.7344099879 ) 1735 1 - vert 1324 ( 0.5144074559 0.7354066968 ) 1734 1 - vert 1325 ( 0.5167495012 0.743672967 ) 1736 2 - vert 1326 ( 0.5407606959 0.7438425422 ) 1738 2 - vert 1327 ( 0.5180986524 0.7867024541 ) 2218 2 - vert 1328 ( 0.5432906747 0.782232821 ) 2226 2 - vert 1329 ( 0.5607374907 0.7413419485 ) 1742 2 - vert 1330 ( 0.5840035677 0.7776081562 ) 2000 2 - vert 1331 ( 0.563646853 0.7779686451 ) 1740 2 - vert 1332 ( 0.5807990432 0.7405381799 ) 1998 2 - vert 1333 ( 0.5650606155 0.725248754 ) 1996 2 - vert 1334 ( 0.5855128169 0.7861213088 ) 2002 2 - vert 1335 ( 0.5442879796 0.7908129096 ) 2228 2 - vert 1336 ( 0.2513518929 0.8579275608 ) 2116 2 - vert 1337 ( 0.2381370366 0.8270900249 ) 2061 2 - vert 1338 ( 0.2083846331 0.8941267729 ) 2097 2 - vert 1339 ( 0.5674852729 0.9353048801 ) 1935 1 - vert 1340 ( 0.6198198795 0.9296262264 ) 1934 1 - vert 1341 ( 0.4179138541 0.9278628826 ) 1988 1 - vert 1342 ( 0.4167684317 0.9034226537 ) 1989 1 - vert 1343 ( 0.7872781157 0.942671895 ) 1968 1 - vert 1344 ( 0.4822467864 0.7343027592 ) 1745 1 - vert 1345 ( 0.4474436045 0.7269634008 ) 2005 1 - vert 1346 ( 0.4495840371 0.7772583365 ) 1746 2 - vert 1347 ( 0.4751650989 0.7425705791 ) 1750 2 - vert 1348 ( 0.4732451439 0.7853062749 ) 1756 2 - vert 1349 ( 0.439622879 0.737051785 ) 2006 2 - vert 1350 ( 0.4277955592 0.7710473537 ) 1754 2 - vert 1351 ( 0.4514044225 0.7894487381 ) 1748 2 - vert 1352 ( 0.4954291284 0.7882047296 ) 2220 2 - vert 1353 ( 0.800086081 0.8255887628 ) 1758 1 - vert 1354 ( 0.8525081277 0.8153198361 ) 1979 1 - vert 1355 ( 0.8529195786 0.8239960074 ) 1759 1 - vert 1356 ( 0.7966136932 0.8169261813 ) 1978 1 - vert 1357 ( 0.7988685966 0.8324139118 ) 1761 1 - vert 1358 ( 0.8551995158 0.8303270936 ) 1763 1 - vert 1359 ( 0.8307558894 0.8504498601 ) 1939 1 - vert 1360 ( 0.91786623 0.8181647062 ) 1982 1 - vert 1361 ( 0.9086131454 0.8271304965 ) 1762 1 - vert 1362 ( 0.9875124097 0.8251116276 ) 1983 1 - vert 1363 ( 0.9611976743 0.8418433666 ) 1984 1 - vert 1364 ( 0.8971911073 0.8505310416 ) 1940 1 - vert 1365 ( 0.1833636761 0.8938746452 ) 2083 1 - vert 1366 ( 0.4352655709 0.9708566666 ) 2110 2 - vert 1367 ( 0.2419928014 0.6990239024 ) 2110 2 - vert 1368 ( 0.1930899769 0.6971670389 ) 2023 3 - vert 1369 ( 0.1811438352 0.701256156 ) 1765 3 - vert 1370 ( 0.2407904118 0.6583088636 ) 2108 2 - vert 1371 ( 0.2578628361 0.5946584344 ) 2077 2 - vert 1372 ( 0.2714389563 0.6168953776 ) 2114 2 - vert 1373 ( 0.2125813663 0.6291373372 ) 1768 2 - vert 1374 ( 0.6742520332 0.9002227783 ) 1777 1 - vert 1375 ( 0.694883883 0.890166223 ) 1774 1 - vert 1376 ( 0.786329329 0.9057593942 ) 1781 1 - vert 1377 ( 0.7896624207 0.8882235289 ) 1771 1 - vert 1378 ( 0.8396375775 0.8866693377 ) 1770 1 - vert 1379 ( 0.6730630398 0.9216036201 ) 2060 1 - vert 1380 ( 0.7366696596 0.8681755066 ) 1773 1 - vert 1381 ( 0.8197116256 0.8694882989 ) 1772 1 - vert 1382 ( 0.5915611982 0.8850938678 ) 1962 1 - vert 1383 ( 0.6179950833 0.8907406926 ) 1775 1 - vert 1384 ( 0.6015017629 0.8973373175 ) 1776 1 - vert 1385 ( 0.574015975 0.9066434503 ) 1963 1 - vert 1386 ( 0.6254544258 0.9187117219 ) 2038 1 - vert 1387 ( 0.5960944295 0.8636288643 ) 1959 1 - vert 1388 ( 0.6200924516 0.8650151491 ) 1778 1 - vert 1389 ( 0.8950863481 0.8862002492 ) 1779 1 - vert 1390 ( 0.9534772635 0.8989229202 ) 1782 1 - vert 1391 ( 0.8784033656 0.9039754868 ) 1780 1 - vert 1392 ( 0.9449782372 0.8866115808 ) 1784 1 - vert 1393 ( 0.8526121974 0.8691055179 ) 1785 1 - vert 1394 ( 0.9165329337 0.8665160537 ) 1783 1 - vert 1395 ( 0.3780546784 0.885679543 ) 1786 1 - vert 1396 ( 0.4082273245 0.8925260901 ) 2033 1 - vert 1397 ( 0.386038661 0.8951603174 ) 1787 1 - vert 1398 ( 0.3854143023 0.9094774723 ) 1990 1 - vert 1399 ( 0.2855044305 0.8725754619 ) 1783 1 - vert 1400 ( 0.3620855808 0.8712576032 ) 1985 1 - vert 1401 ( 0.3084830642 0.8866115808 ) 1784 1 - vert 1402 ( 0.3185078204 0.8989229202 ) 1782 1 - vert 1403 ( 0.5107603669 0.9297960997 ) 1975 1 - vert 1404 ( 0.5505428314 0.9041790366 ) 1932 1 - vert 1405 ( 0.5435915589 0.9326674938 ) 1974 1 - vert 1406 ( 0.5141093731 0.8962922692 ) 1788 1 - vert 1407 ( 0.4773729742 0.9290877581 ) 1976 1 - vert 1408 ( 0.4786817729 0.8956178427 ) 1789 1 - vert 1409 ( 0.5482464433 0.8635425568 ) 1970 1 - vert 1410 ( 0.5145289898 0.8645966649 ) 1972 1 - vert 1411 ( 0.482365489 0.8637974262 ) 1973 1 - vert 1412 ( 0.4400782585 0.9015974998 ) 1933 1 - vert 1413 ( 0.4425452352 0.9287195206 ) 1977 1 - vert 1414 ( 0.4476633966 0.861060679 ) 1971 1 - vert 1415 ( 0.5705474019 0.8626556993 ) 1964 1 - vert 1416 ( 0.4268456399 0.8531342149 ) 2032 1 - vert 1417 ( 0.4310365319 0.8612377048 ) 1969 1 - vert 1418 ( 0.359282434 0.7307472825 ) 2212 2 - vert 1419 ( 0.4038036466 0.7231858969 ) 1792 1 - vert 1420 ( 0.4004597664 0.7391049266 ) 1793 2 - vert 1421 ( 0.7741333842 0.7348031402 ) 2178 2 - vert 1422 ( 0.8957604766 0.7239615917 ) 2176 2 - vert 1423 ( 0.9213752747 0.7375072837 ) 2118 2 - vert 1424 ( 0.806820333 0.7447397113 ) 1803 2 - vert 1425 ( 0.6343027353 0.7398629785 ) 1795 2 - vert 1426 ( 0.710531652 0.7345507145 ) 2180 2 - vert 1427 ( 0.6962388754 0.7495731115 ) 2123 2 - vert 1428 ( 0.3675605655 0.7146486044 ) 1790 1 - vert 1429 ( 0.4256101549 0.6858440638 ) 2208 1 - vert 1430 ( 0.4699153304 0.6971183419 ) 2173 1 - vert 1431 ( 0.4695941508 0.7092337012 ) 1791 1 - vert 1432 ( 0.5916910768 0.7120783925 ) 2211 1 - vert 1433 ( 0.6650369763 0.7221435905 ) 1813 2 - vert 1434 ( 0.9669525027 0.6981096268 ) 2209 2 - vert 1435 ( 0.9797732234 0.7176145315 ) 1790 1 - vert 1436 ( 0.6215757728 0.7501673102 ) 1797 2 - vert 1437 ( 0.6178281307 0.7569681406 ) 1807 2 - vert 1438 ( 0.8144189715 0.760948658 ) 1801 2 - vert 1439 ( 0.6374437213 0.7690489888 ) 1811 2 - vert 1440 ( 0.9750631452 0.7317526937 ) 2212 2 - vert 1441 ( 0.9553364515 0.7473914027 ) 1809 2 - vert 1442 ( 0.9111297727 0.7560218573 ) 1799 2 - vert 1443 ( 0.6938430071 0.762709856 ) 1846 2 - vert 1444 ( 0.9322875142 0.7649632096 ) 2192 2 - vert 1445 ( 0.6424546242 0.7811055183 ) 2188 2 - vert 1446 ( 0.8909954429 0.7691081166 ) 1897 2 - vert 1447 ( 0.3084173203 0.7650984526 ) 2192 2 - vert 1448 ( 0.3917136192 0.7533002496 ) 1805 2 - vert 1449 ( 0.3822190762 0.7685795426 ) 1895 2 - vert 1450 ( 0.3428479433 0.7473681569 ) 1809 2 - vert 1451 ( 0.8579117656 0.7914496064 ) 2182 2 - vert 1452 ( 0.727822125 0.7784240246 ) 2186 2 - vert 1453 ( 0.9140110612 0.7000353336 ) 2174 2 - vert 1454 ( 0.8526973128 0.6914362907 ) 1815 2 - vert 1455 ( 0.7698711157 0.7072541118 ) 1844 2 - vert 1456 ( 0.3492717743 0.6981096268 ) 2209 2 - vert 1457 ( 0.6246590018 0.6811992526 ) 2207 1 - vert 1458 ( 0.7301080823 0.7051903009 ) 1842 2 - vert 1459 ( 0.5407672524 0.6966646314 ) 1817 1 - vert 1460 ( 0.51039958 0.7091558576 ) 1965 1 - vert 1461 ( 0.5188540816 0.6799803376 ) 1818 1 - vert 1462 ( 0.7069051862 0.6559785008 ) 2205 2 - vert 1463 ( 0.7829682231 0.6644138694 ) 2120 1 - vert 1464 ( 0.899766624 0.6474706531 ) 2196 2 - vert 1465 ( 0.5533827543 0.6647381186 ) 1839 1 - vert 1466 ( 0.6242524981 0.6262385249 ) 1909 2 - vert 1467 ( 0.948190093 0.6110125184 ) 1823 2 - vert 1468 ( 0.9421514869 0.6479540467 ) 1831 2 - vert 1469 ( 0.3580010533 0.6196772456 ) 1827 2 - vert 1470 ( 0.3248864412 0.6501572132 ) 1837 2 - vert 1471 ( 0.399297893 0.6426792741 ) 1835 2 - vert 1472 ( 0.9783809781 0.6451755762 ) 1837 2 - vert 1473 ( 0.6523242593 0.5940893888 ) 1852 2 - vert 1474 ( 0.6862653494 0.6110110879 ) 1848 2 - vert 1475 ( 0.4291833341 0.6034495831 ) 1825 2 - vert 1476 ( 0.4741988778 0.5722598433 ) 1819 2 - vert 1477 ( 0.4815787971 0.6437709332 ) 1833 2 - vert 1478 ( 0.7335687876 0.5797832608 ) 2152 2 - vert 1479 ( 0.8656434417 0.575014472 ) 2160 2 - vert 1480 ( 0.9081220031 0.5980070233 ) 1854 2 - vert 1481 ( 0.8918976188 0.6154376864 ) 1821 2 - vert 1482 ( 0.8163060546 0.6120387912 ) 2194 2 - vert 1483 ( 0.3544656634 0.6056483984 ) 2065 2 - vert 1484 ( 0.7950555682 0.6415287852 ) 1829 2 - vert 1485 ( 0.5458924174 0.6339027286 ) 1840 2 - vert 1486 ( 0.4389449954 0.5731776357 ) 1850 2 - vert 1487 ( 0.8238632083 0.5803208947 ) 2154 3 - vert 1488 ( 0.3967536092 0.5808766484 ) 1860 2 - vert 1489 ( 0.3826692104 0.592597127 ) 1856 2 - vert 1490 ( 0.4239892066 0.5822885036 ) 2063 2 - vert 1491 ( 0.432539463 0.5300771594 ) 2214 2 - vert 1492 ( 0.3994908929 0.5540006757 ) 1858 2 - vert 1493 ( 0.4291992486 0.5542880893 ) 2069 3 - vert 1494 ( 0.4154266715 0.5975065231 ) 2067 2 - vert 1495 ( 0.9345200658 0.7956544161 ) 2184 2 - vert 1496 ( 0.3817654848 0.7862767577 ) 2190 2 - vert 1497 ( 0.7691301703 0.7937842011 ) 1899 2 - vert 1498 ( 0.377725482 0.8053206205 ) 1903 2 - vert 1499 ( 0.3624657393 0.8172302246 ) 2030 1 - vert 1500 ( 0.3175797164 0.8251116276 ) 1983 1 - vert 1501 ( 0.7873748541 0.8050133586 ) 1905 1 - vert 1502 ( 0.8695567846 0.8089385033 ) 1901 1 - vert 1503 ( 0.963134706 0.805110395 ) 1902 1 - vert 1504 ( 0.70623523 0.806235671 ) 1981 1 - vert 1505 ( 0.4203434587 0.7858124375 ) 1906 2 - vert 1506 ( 0.293201983 0.805110395 ) 1902 1 - vert 1507 ( 0.2800888121 0.7917528749 ) 2184 2 - vert 1508 ( 0.7328642607 0.7992414832 ) 1908 1 - vert 1509 ( 0.3551490903 0.2034666538 ) 1688 1 - vert 1510 ( 0.3641453683 0.8268107176 ) 1917 1 - vert 1511 ( 0.3898702264 0.8312378526 ) 1916 1 - vert 1512 ( 0.4006169438 0.8430785537 ) 1915 1 - vert 1513 ( 0.3360689282 0.8342242241 ) 1918 1 - vert 1514 ( 0.3933908045 0.855396688 ) 1914 1 - vert 1515 ( 0.3337395787 0.8506288528 ) 2236 1 - vert 1516 ( 0.3620383739 0.8603591323 ) 1913 1 - vert 1517 ( 0.6798722148 0.8088632226 ) 1949 1 - vert 1518 ( 0.6693634391 0.8196830153 ) 1958 1 - vert 1519 ( 0.6446796656 0.8240692019 ) 1957 1 - vert 1520 ( 0.6702853441 0.797947824 ) 1950 1 - vert 1521 ( 0.6218754053 0.8194525242 ) 1956 1 - vert 1522 ( 0.6448164582 0.7933310866 ) 1951 2 - vert 1523 ( 0.6131525636 0.8085372448 ) 1955 1 - vert 1524 ( 0.6212505698 0.7977173924 ) 1953 2 - vert 1525 ( 0.3116773665 0.8574773073 ) 1911 1 - vert 1526 ( 0.4109322429 0.8572394848 ) 2034 1 - vert 1527 ( 0.4099704027 0.823318541 ) 1912 1 - vert 1528 ( 0.2912650704 0.8418433666 ) 1984 1 - vert 1529 ( 0.689548254 0.7895273566 ) 1942 2 - vert 1530 ( 0.5901307464 0.8057367206 ) 1946 1 - vert 1531 ( 0.6018051505 0.7921656966 ) 1944 2 - vert 1532 ( 0.6035143137 0.8224451542 ) 1947 1 - vert 1533 ( 0.6850998998 0.82190907 ) 1948 1 - vert 1534 ( 0.7400199175 0.8212472796 ) 1764 1 - vert 1535 ( 0.9816100001 0.8574773073 ) 1911 1 - vert 1536 ( 0.5159634352 0.9509907365 ) 1706 1 - vert 1537 ( 0.5263341069 0.9614715576 ) 2059 1 - vert 1538 ( 0.4574320614 0.9597361088 ) 1703 1 - vert 1539 ( 0.4118084013 0.7727532983 ) 1752 2 - vert 1540 ( 0.1813786179 0.8128939867 ) 1679 3 - vert 1541 ( 0.5989988446 0.9708634019 ) 2044 2 - vert 1542 ( 0.6000680923 0.9609757662 ) 2049 1 - vert 1543 ( 0.5620049238 0.9718698859 ) 2050 2 - vert 1544 ( 0.3586400449 0.9429779649 ) 2074 1 - vert 1545 ( 0.3415579796 0.9506332278 ) 2072 1 - vert 1546 ( 0.3803156912 0.9470651746 ) 1719 1 - vert 1547 ( 0.3920620084 0.9557168484 ) 1720 1 - vert 1548 ( 0.8232848048 0.9789833426 ) 2054 2 - vert 1549 ( 0.8948417902 0.9775547385 ) 2075 2 - vert 1550 ( 0.7517197728 0.9819450378 ) 1673 2 - vert 1551 ( 0.1833622754 0.6334704161 ) 2107 1 - vert 1552 ( 0.3300353885 0.9838322997 ) 2114 2 - vert 1553 ( 0.3565215766 0.9672869444 ) 1717 2 - vert 1554 ( 0.3851564527 0.9906263351 ) 2108 2 - vert 1555 ( 0.3804599941 0.9662017226 ) 1715 2 - vert 1556 ( 0.3307661712 0.9583724737 ) 2073 1 - vert 1557 ( 0.3027388453 0.9723916054 ) 2112 2 - vert 1558 ( 0.9727258682 0.9859603643 ) 2114 2 - vert 1559 ( 0.4545708001 0.4958548546 ) 2130 2 - vert 1560 ( 0.4894213676 0.4945927858 ) 1885 1 - vert 1561 ( 0.7168648243 0.3641926646 ) 2144 2 - vert 1562 ( 0.7681257129 0.3391145468 ) 2138 1 - vert 1563 ( 0.5403671265 0.4973586798 ) 2144 2 - vert 1564 ( 0.6013734937 0.5281243324 ) 2203 2 - vert 1565 ( 0.6079990268 0.5030022264 ) 2138 1 - vert 1566 ( 0.8147406578 0.3371991515 ) 2266 1 - vert 1567 ( 0.6477783918 0.527874589 ) 2136 2 - vert 1568 ( 0.6476663351 0.5388614535 ) 2134 2 - vert 1569 ( 0.6646463871 0.5732014179 ) 2149 3 - vert 1570 ( 0.9247060418 0.5648664832 ) 2157 3 - vert 1571 ( 0.8690063357 0.3619178534 ) 1892 3 - vert 1572 ( 0.6961885095 0.4022818804 ) 1885 1 - vert 1573 ( 0.6967608333 0.4512689114 ) 2130 2 - vert 1574 ( 0.5210370421 0.7928661704 ) 2216 2 - - numtris 2686 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 6 0 4 - tri 3 7 2 6 - tri 4 7 8 2 - tri 5 9 7 6 - tri 6 10 7 9 - tri 7 13 12 11 - tri 8 13 11 1 - tri 9 13 1 2 - tri 10 16 15 14 - tri 11 16 14 17 - tri 12 17 14 12 - tri 13 17 12 13 - tri 14 18 2 8 - tri 15 18 13 2 - tri 16 19 17 13 - tri 17 19 13 18 - tri 18 20 17 19 - tri 19 20 16 17 - tri 20 23 22 21 - tri 21 23 21 24 - tri 22 1 26 25 - tri 23 0 1 25 - tri 24 27 0 25 - tri 25 4 0 27 - tri 26 12 28 26 - tri 27 11 26 1 - tri 28 12 26 11 - tri 29 29 28 14 - tri 30 14 28 12 - tri 31 15 29 14 - tri 32 5 3 30 - tri 33 31 10 9 - tri 34 31 9 5 - tri 35 16 32 15 - tri 36 33 16 20 - tri 37 35 23 34 - tri 38 36 23 35 - tri 39 30 38 37 - tri 40 30 3 38 - tri 41 41 40 39 - tri 42 41 39 42 - tri 43 42 39 43 - tri 44 39 40 44 - tri 45 39 44 43 - tri 46 43 44 45 - tri 47 42 43 46 - tri 48 48 47 40 - tri 49 50 45 49 - tri 50 44 51 45 - tri 51 44 52 51 - tri 52 52 54 53 - tri 53 55 54 52 - tri 54 47 55 52 - tri 55 57 42 56 - tri 56 57 41 42 - tri 57 56 42 58 - tri 58 58 42 46 - tri 59 61 60 59 - tri 60 64 63 62 - tri 61 65 64 62 - tri 62 59 60 66 - tri 63 69 68 67 - tri 64 67 68 70 - tri 65 68 71 70 - tri 66 69 72 68 - tri 67 70 71 73 - tri 68 75 74 72 - tri 69 75 72 69 - tri 70 78 77 76 - tri 71 78 80 79 - tri 72 78 79 77 - tri 73 72 81 68 - tri 74 81 82 68 - tri 75 68 82 71 - tri 76 72 83 81 - tri 77 77 85 84 - tri 78 76 77 84 - tri 79 76 84 86 - tri 80 84 85 87 - tri 81 79 88 85 - tri 82 77 79 85 - tri 83 85 88 89 - tri 84 85 89 90 - tri 85 87 85 90 - tri 86 66 92 91 - tri 87 66 91 93 - tri 88 81 94 82 - tri 89 94 95 82 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 98 86 84 - tri 93 98 84 87 - tri 94 90 89 99 - tri 95 65 62 100 - tri 96 100 62 101 - tri 97 62 61 101 - tri 98 101 61 102 - tri 99 61 59 102 - tri 100 102 59 103 - tri 101 59 66 103 - tri 102 103 66 93 - tri 103 103 93 104 - tri 104 96 105 97 - tri 105 105 106 97 - tri 106 104 108 107 - tri 107 108 109 107 - tri 108 112 111 110 - tri 109 114 113 65 - tri 110 114 65 115 - tri 111 115 65 100 - tri 112 117 116 113 - tri 113 117 113 118 - tri 114 119 113 114 - tri 115 118 113 119 - tri 116 121 117 120 - tri 117 120 117 118 - tri 118 111 122 121 - tri 119 111 121 120 - tri 120 110 111 120 - tri 121 125 124 123 - tri 122 125 126 124 - tri 123 126 100 101 - tri 124 126 101 127 - tri 125 101 102 127 - tri 126 127 102 128 - tri 127 102 103 129 - tri 128 102 129 128 - tri 129 103 104 129 - tri 130 129 104 107 - tri 131 129 107 130 - tri 132 130 107 131 - tri 133 127 128 132 - tri 134 123 124 133 - tri 135 133 124 134 - tri 136 135 123 133 - tri 137 133 134 136 - tri 138 138 114 137 - tri 139 138 119 114 - tri 140 137 114 115 - tri 141 137 115 139 - tri 142 139 115 125 - tri 143 140 139 125 - tri 144 53 142 141 - tri 145 143 141 142 - tri 146 145 144 142 - tri 147 49 143 146 - tri 148 143 142 144 - tri 149 149 148 147 - tri 150 147 148 150 - tri 151 153 152 151 - tri 152 151 152 154 - tri 153 157 156 155 - tri 154 151 154 157 - tri 155 157 154 156 - tri 156 54 149 145 - tri 157 145 149 147 - tri 158 159 151 158 - tri 159 158 151 157 - tri 160 148 160 150 - tri 161 161 150 160 - tri 162 148 162 160 - tri 163 149 163 148 - tri 164 163 162 148 - tri 165 161 160 164 - tri 166 152 156 154 - tri 167 46 50 165 - tri 168 46 165 166 - tri 169 166 165 167 - tri 170 170 169 168 - tri 171 172 171 168 - tri 172 175 174 173 - tri 173 176 175 173 - tri 174 177 174 175 - tri 175 180 179 178 - tri 176 58 46 179 - tri 177 179 46 166 - tri 178 166 167 181 - tri 179 183 182 171 - tri 180 183 184 182 - tri 181 185 184 183 - tri 182 184 186 182 - tri 183 186 170 182 - tri 184 185 187 184 - tri 185 49 146 186 - tri 186 50 49 187 - tri 187 50 187 165 - tri 188 165 187 185 - tri 189 167 165 185 - tri 190 167 185 183 - tri 191 171 182 188 - tri 192 182 170 188 - tri 193 171 188 168 - tri 194 188 170 168 - tri 195 146 169 170 - tri 196 191 190 189 - tri 197 193 192 190 - tri 198 116 193 191 - tri 199 191 193 190 - tri 200 116 191 189 - tri 201 196 195 194 - tri 202 134 198 197 - tri 203 134 197 195 - tri 204 201 200 199 - tri 205 200 202 199 - tri 206 150 202 200 - tri 207 150 203 202 - tri 208 144 201 199 - tri 209 144 199 204 - tri 210 161 203 150 - tri 211 147 200 201 - tri 212 147 150 200 - tri 213 147 201 144 - tri 214 145 147 144 - tri 215 207 206 205 - tri 216 207 205 208 - tri 217 210 209 206 - tri 218 206 209 205 - tri 219 153 209 210 - tri 220 207 208 176 - tri 221 159 211 153 - tri 222 153 211 209 - tri 223 176 208 212 - tri 224 209 213 205 - tri 225 211 213 209 - tri 226 215 212 214 - tri 227 212 208 214 - tri 228 208 205 216 - tri 229 214 208 216 - tri 230 213 218 217 - tri 231 215 214 219 - tri 232 214 216 219 - tri 233 219 216 217 - tri 234 220 217 218 - tri 235 221 218 213 - tri 236 219 217 220 - tri 237 222 219 220 - tri 238 211 221 213 - tri 239 221 223 218 - tri 240 218 223 224 - tri 241 220 218 224 - tri 242 225 222 220 - tri 243 227 138 226 - tri 244 138 137 226 - tri 245 230 229 228 - tri 246 231 230 228 - tri 247 229 120 232 - tri 248 110 229 230 - tri 249 226 139 140 - tri 250 234 226 233 - tri 251 237 236 235 - tri 252 240 239 238 - tri 253 238 239 241 - tri 254 239 215 242 - tri 255 239 243 215 - tri 256 198 244 197 - tri 257 198 245 244 - tri 258 198 132 245 - tri 259 244 246 240 - tri 260 240 246 239 - tri 261 244 245 247 - tri 262 244 247 246 - tri 263 131 248 247 - tri 264 245 132 130 - tri 265 197 244 240 - tri 266 226 137 139 - tri 267 194 195 238 - tri 268 242 215 222 - tri 269 249 122 111 - tri 270 112 249 111 - tri 271 112 250 249 - tri 272 135 133 251 - tri 273 251 133 252 - tri 274 133 136 252 - tri 275 220 224 253 - tri 276 253 224 254 - tri 277 255 224 223 - tri 278 255 254 224 - tri 279 225 220 253 - tri 280 225 253 256 - tri 281 238 241 257 - tri 282 257 241 258 - tri 283 235 236 259 - tri 284 194 238 257 - tri 285 262 261 260 - tri 286 260 261 263 - tri 287 260 263 264 - tri 288 267 266 265 - tri 289 268 266 267 - tri 290 269 268 267 - tri 291 272 271 270 - tri 292 274 273 261 - tri 293 262 274 261 - tri 294 261 273 268 - tri 295 64 262 260 - tri 296 273 275 268 - tri 297 273 276 275 - tri 298 278 277 47 - tri 299 279 277 278 - tri 300 279 280 277 - tri 301 47 277 281 - tri 302 277 280 281 - tri 303 282 278 48 - tri 304 48 278 47 - tri 305 281 280 283 - tri 306 282 48 284 - tri 307 285 278 282 - tri 308 271 287 286 - tri 309 270 271 286 - tri 310 289 288 280 - tri 311 266 290 287 - tri 312 268 285 266 - tri 313 268 275 285 - tri 314 285 282 290 - tri 315 266 285 290 - tri 316 291 272 270 - tri 317 280 288 283 - tri 318 279 289 280 - tri 319 285 292 278 - tri 320 292 279 278 - tri 321 275 292 285 - tri 322 275 293 292 - tri 323 263 295 294 - tri 324 296 268 269 - tri 325 261 296 263 - tri 326 261 268 296 - tri 327 291 297 272 - tri 328 294 298 264 - tri 329 264 298 297 - tri 330 263 294 264 - tri 331 263 296 295 - tri 332 295 296 299 - tri 333 301 300 265 - tri 334 301 265 271 - tri 335 302 301 271 - tri 336 302 271 272 - tri 337 298 302 297 - tri 338 297 302 272 - tri 339 299 296 303 - tri 340 296 269 303 - tri 341 303 269 267 - tri 342 303 267 304 - tri 343 304 267 265 - tri 344 304 265 300 - tri 345 276 293 275 - tri 346 190 192 276 - tri 347 190 276 273 - tri 348 61 305 60 - tri 349 189 273 274 - tri 350 189 190 273 - tri 351 302 300 301 - tri 352 302 304 300 - tri 353 298 304 302 - tri 354 298 303 304 - tri 355 294 303 298 - tri 356 294 299 303 - tri 357 295 299 294 - tri 358 306 193 116 - tri 359 117 306 116 - tri 360 121 306 117 - tri 361 121 122 306 - tri 362 113 64 65 - tri 363 110 120 229 - tri 364 232 138 227 - tri 365 120 138 232 - tri 366 135 140 123 - tri 367 140 125 123 - tri 368 228 227 234 - tri 369 234 227 226 - tri 370 231 234 307 - tri 371 231 228 234 - tri 372 233 226 140 - tri 373 228 232 227 - tri 374 228 229 232 - tri 375 120 118 119 - tri 376 120 119 138 - tri 377 134 124 198 - tri 378 284 40 41 - tri 379 284 48 40 - tri 380 286 287 308 - tri 381 310 308 309 - tri 382 311 308 310 - tri 383 310 309 312 - tri 384 310 312 92 - tri 385 60 311 310 - tri 386 60 310 66 - tri 387 66 310 92 - tri 388 311 286 308 - tri 389 92 312 313 - tri 390 309 57 56 - tri 391 308 57 309 - tri 392 308 287 57 - tri 393 287 284 41 - tri 394 287 41 57 - tri 395 287 290 284 - tri 396 290 282 284 - tri 397 270 286 311 - tri 398 270 311 60 - tri 399 309 56 312 - tri 400 312 56 58 - tri 401 40 47 44 - tri 402 47 52 44 - tri 403 54 145 53 - tri 404 145 142 53 - tri 405 178 166 181 - tri 406 179 166 178 - tri 407 58 179 180 - tri 408 34 24 314 - tri 409 34 23 24 - tri 410 317 316 315 - tri 411 317 318 316 - tri 412 321 320 319 - tri 413 6 2 0 - tri 414 9 4 5 - tri 415 9 6 4 - tri 416 73 71 16 - tri 417 33 73 16 - tri 418 82 95 71 - tri 419 95 97 71 - tri 420 97 106 32 - tri 421 97 32 16 - tri 422 71 97 16 - tri 423 313 180 322 - tri 424 180 178 322 - tri 425 312 180 313 - tri 426 312 58 180 - tri 427 323 317 315 - tri 428 323 320 321 - tri 429 323 315 320 - tri 430 5 30 99 - tri 431 89 5 99 - tri 432 88 5 89 - tri 433 49 141 143 - tri 434 45 51 49 - tri 435 51 141 49 - tri 436 36 35 315 - tri 437 35 320 315 - tri 438 115 126 125 - tri 439 115 100 126 - tri 440 107 109 131 - tri 441 131 109 248 - tri 442 3 27 38 - tri 443 3 4 27 - tri 444 80 88 79 - tri 445 80 324 88 - tri 446 324 5 88 - tri 447 31 5 324 - tri 448 236 135 251 - tri 449 259 236 251 - tri 450 124 132 198 - tri 451 132 128 130 - tri 452 128 129 130 - tri 453 325 243 239 - tri 454 134 195 196 - tri 455 136 134 196 - tri 456 328 327 326 - tri 457 328 326 329 - tri 458 328 329 330 - tri 459 328 332 331 - tri 460 328 331 333 - tri 461 328 333 334 - tri 462 328 334 335 - tri 463 328 335 327 - tri 464 245 131 247 - tri 465 245 130 131 - tri 466 216 205 213 - tri 467 216 213 217 - tri 468 63 291 305 - tri 469 260 297 291 - tri 470 260 264 297 - tri 471 260 291 63 - tri 472 64 260 63 - tri 473 189 274 262 - tri 474 189 262 64 - tri 475 113 116 64 - tri 476 116 189 64 - tri 477 246 325 239 - tri 478 246 247 325 - tri 479 336 243 325 - tri 480 126 127 132 - tri 481 126 132 124 - tri 482 337 234 233 - tri 483 337 233 236 - tri 484 307 337 338 - tri 485 307 234 337 - tri 486 237 337 236 - tri 487 237 338 337 - tri 488 233 140 135 - tri 489 236 233 135 - tri 490 247 336 325 - tri 491 248 336 247 - tri 492 195 197 238 - tri 493 197 240 238 - tri 494 62 63 61 - tri 495 63 305 61 - tri 496 339 78 76 - tri 497 339 76 340 - tri 498 239 242 241 - tri 499 28 341 26 - tri 500 146 170 186 - tri 501 187 186 184 - tri 502 49 186 187 - tri 503 74 83 72 - tri 504 340 76 86 - tri 505 342 81 83 - tri 506 342 94 81 - tri 507 43 45 50 - tri 508 43 50 46 - tri 509 305 270 60 - tri 510 291 270 305 - tri 511 222 215 219 - tri 512 159 153 151 - tri 513 51 53 141 - tri 514 52 53 51 - tri 515 281 344 343 - tri 516 55 281 343 - tri 517 55 343 54 - tri 518 343 345 54 - tri 519 344 345 343 - tri 520 288 344 283 - tri 521 281 283 344 - tri 522 345 163 149 - tri 523 345 149 54 - tri 524 47 281 55 - tri 525 163 346 164 - tri 526 347 346 163 - tri 527 288 348 344 - tri 528 345 347 163 - tri 529 348 347 345 - tri 530 344 348 345 - tri 531 163 164 162 - tri 532 162 164 160 - tri 533 157 155 255 - tri 534 157 255 223 - tri 535 158 157 221 - tri 536 157 223 221 - tri 537 144 204 349 - tri 538 143 349 146 - tri 539 143 144 349 - tri 540 146 349 204 - tri 541 146 204 169 - tri 542 350 26 341 - tri 543 350 25 26 - tri 544 159 221 211 - tri 545 159 158 221 - tri 546 243 212 215 - tri 547 27 25 351 - tri 548 351 25 350 - tri 549 352 177 175 - tri 550 336 353 243 - tri 551 243 352 212 - tri 552 353 354 243 - tri 553 38 27 351 - tri 554 352 175 212 - tri 555 176 212 175 - tri 556 241 225 258 - tri 557 258 225 256 - tri 558 242 222 225 - tri 559 241 242 225 - tri 560 271 265 287 - tri 561 265 266 287 - tri 562 357 356 355 - tri 563 360 359 358 - tri 564 361 358 356 - tri 565 362 361 357 - tri 566 362 357 363 - tri 567 364 361 362 - tri 568 365 364 362 - tri 569 368 367 366 - tri 570 368 355 367 - tri 571 368 357 355 - tri 572 371 370 369 - tri 573 371 372 370 - tri 574 372 366 370 - tri 575 372 368 366 - tri 576 373 363 357 - tri 577 373 357 368 - tri 578 374 368 372 - tri 579 374 373 368 - tri 580 375 374 372 - tri 581 375 372 371 - tri 582 378 377 376 - tri 583 378 379 377 - tri 584 355 381 380 - tri 585 356 381 355 - tri 586 382 381 356 - tri 587 358 382 356 - tri 588 366 380 383 - tri 589 367 355 380 - tri 590 366 367 380 - tri 591 384 370 383 - tri 592 370 366 383 - tri 593 369 370 384 - tri 594 360 385 359 - tri 595 386 364 365 - tri 596 386 360 364 - tri 597 371 369 387 - tri 598 388 375 371 - tri 599 390 389 378 - tri 600 391 390 378 - tri 601 385 393 392 - tri 602 385 392 359 - tri 603 396 395 394 - tri 604 396 397 395 - tri 605 397 398 395 - tri 606 395 399 394 - tri 607 395 398 399 - tri 608 398 400 399 - tri 609 397 401 398 - tri 610 403 394 402 - tri 611 405 404 400 - tri 612 399 400 406 - tri 613 399 406 407 - tri 614 407 409 408 - tri 615 410 407 408 - tri 616 402 407 410 - tri 617 412 411 397 - tri 618 412 397 396 - tri 619 411 413 397 - tri 620 413 401 397 - tri 621 416 415 414 - tri 622 419 418 417 - tri 623 420 418 419 - tri 624 415 421 414 - tri 625 424 423 422 - tri 626 423 425 422 - tri 627 422 425 426 - tri 628 424 422 427 - tri 629 425 428 426 - tri 630 430 427 429 - tri 631 430 424 427 - tri 632 433 432 431 - tri 633 433 435 434 - tri 634 433 431 435 - tri 635 427 422 436 - tri 636 436 422 437 - tri 637 422 426 437 - tri 638 427 436 438 - tri 639 431 440 439 - tri 640 432 440 431 - tri 641 432 441 440 - tri 642 440 442 439 - tri 643 435 439 443 - tri 644 431 439 435 - tri 645 439 444 443 - tri 646 439 445 444 - tri 647 442 445 439 - tri 648 421 447 446 - tri 649 421 448 447 - tri 650 436 437 449 - tri 651 449 437 450 - tri 652 449 450 451 - tri 653 451 450 452 - tri 654 453 440 441 - tri 655 453 442 440 - tri 656 445 454 444 - tri 657 420 455 418 - tri 658 455 456 418 - tri 659 418 456 416 - tri 660 456 457 416 - tri 661 416 457 415 - tri 662 457 458 415 - tri 663 415 458 421 - tri 664 458 448 421 - tri 665 458 459 448 - tri 666 451 452 460 - tri 667 460 452 461 - tri 668 459 463 462 - tri 669 462 463 464 - tri 670 467 466 465 - tri 671 469 420 468 - tri 672 469 470 420 - tri 673 470 455 420 - tri 674 472 468 471 - tri 675 472 473 468 - tri 676 474 469 468 - tri 677 473 474 468 - tri 678 476 475 472 - tri 679 475 473 472 - tri 680 465 476 122 - tri 681 465 475 476 - tri 682 466 475 465 - tri 683 479 478 477 - tri 684 479 477 480 - tri 685 480 456 455 - tri 686 480 481 456 - tri 687 456 481 457 - tri 688 481 482 457 - tri 689 457 483 458 - tri 690 457 482 483 - tri 691 458 483 459 - tri 692 483 463 459 - tri 693 483 484 463 - tri 694 484 485 463 - tri 695 481 486 482 - tri 696 478 487 477 - tri 697 487 488 477 - tri 698 489 487 478 - tri 699 487 136 488 - tri 700 491 490 469 - tri 701 491 469 474 - tri 702 490 470 469 - tri 703 490 492 470 - tri 704 492 479 470 - tri 705 493 479 492 - tri 706 409 495 494 - tri 707 496 494 495 - tri 708 498 494 497 - tri 709 404 499 496 - tri 710 496 497 494 - tri 711 502 501 500 - tri 712 501 503 500 - tri 713 506 505 504 - tri 714 505 507 504 - tri 715 508 155 156 - tri 716 505 508 507 - tri 717 508 156 507 - tri 718 408 498 502 - tri 719 498 501 502 - tri 720 510 509 505 - tri 721 509 508 505 - tri 722 500 503 511 - tri 723 512 511 503 - tri 724 500 511 513 - tri 725 502 500 514 - tri 726 514 500 513 - tri 727 512 515 511 - tri 728 504 507 156 - tri 729 401 516 405 - tri 730 401 517 516 - tri 731 517 518 516 - tri 732 521 520 519 - tri 733 523 520 522 - tri 734 526 525 524 - tri 735 527 525 526 - tri 736 528 526 524 - tri 737 531 530 529 - tri 738 413 529 401 - tri 739 529 517 401 - tri 740 517 532 518 - tri 741 534 522 533 - tri 742 534 533 535 - tri 743 536 534 535 - tri 744 535 533 537 - tri 745 537 533 521 - tri 746 536 535 538 - tri 747 404 537 499 - tri 748 405 538 404 - tri 749 405 516 538 - tri 750 516 536 538 - tri 751 518 536 516 - tri 752 518 534 536 - tri 753 522 539 533 - tri 754 533 539 521 - tri 755 522 520 539 - tri 756 539 520 521 - tri 757 499 521 519 - tri 758 542 541 540 - tri 759 193 540 192 - tri 760 471 542 193 - tri 761 542 540 193 - tri 762 471 541 542 - tri 763 196 194 543 - tri 764 488 545 544 - tri 765 488 543 545 - tri 766 548 547 546 - tri 767 546 547 549 - tri 768 503 546 549 - tri 769 503 549 550 - tri 770 497 547 548 - tri 771 497 551 547 - tri 772 512 503 550 - tri 773 501 548 546 - tri 774 501 546 503 - tri 775 501 497 548 - tri 776 498 497 501 - tri 777 554 553 552 - tri 778 554 555 553 - tri 779 557 552 556 - tri 780 552 553 556 - tri 781 506 557 556 - tri 782 554 527 555 - tri 783 510 506 558 - tri 784 506 556 558 - tri 785 527 559 555 - tri 786 556 553 560 - tri 787 558 556 560 - tri 788 562 561 559 - tri 789 559 561 555 - tri 790 555 563 553 - tri 791 561 563 555 - tri 792 560 565 564 - tri 793 562 566 561 - tri 794 561 566 563 - tri 795 566 565 563 - tri 796 567 564 565 - tri 797 568 560 564 - tri 798 566 567 565 - tri 799 569 567 566 - tri 800 558 560 568 - tri 801 568 564 570 - tri 802 564 571 570 - tri 803 567 571 564 - tri 804 572 567 569 - tri 805 574 573 491 - tri 806 491 573 490 - tri 807 577 576 575 - tri 808 578 576 577 - tri 809 575 579 475 - tri 810 466 577 575 - tri 811 573 493 492 - tri 812 581 580 573 - tri 813 583 235 582 - tri 814 586 585 584 - tri 815 585 587 584 - tri 816 584 588 562 - tri 817 584 562 589 - tri 818 544 545 590 - tri 819 544 590 591 - tri 820 544 591 486 - tri 821 590 586 592 - tri 822 586 584 592 - tri 823 590 593 591 - tri 824 590 592 593 - tri 825 485 593 594 - tri 826 591 484 486 - tri 827 545 586 590 - tri 828 573 492 490 - tri 829 194 585 543 - tri 830 588 569 562 - tri 831 249 465 122 - tri 832 467 465 249 - tri 833 467 249 250 - tri 834 489 251 487 - tri 835 251 252 487 - tri 836 487 252 136 - tri 837 567 253 571 - tri 838 253 254 571 - tri 839 255 570 571 - tri 840 255 571 254 - tri 841 572 253 567 - tri 842 572 256 253 - tri 843 585 257 587 - tri 844 257 258 587 - tri 845 235 259 582 - tri 846 194 257 585 - tri 847 597 596 595 - tri 848 596 598 595 - tri 849 596 599 598 - tri 850 602 601 600 - tri 851 603 602 600 - tri 852 604 602 603 - tri 853 607 606 605 - tri 854 609 595 608 - tri 855 597 595 609 - tri 856 595 603 608 - tri 857 419 596 597 - tri 858 608 603 610 - tri 859 608 610 276 - tri 860 612 402 611 - tri 861 279 612 611 - tri 862 279 611 613 - tri 863 402 614 611 - tri 864 611 614 613 - tri 865 615 403 612 - tri 866 403 402 612 - tri 867 614 616 613 - tri 868 615 617 403 - tri 869 618 615 612 - tri 870 605 620 619 - tri 871 606 620 605 - tri 872 289 613 288 - tri 873 600 619 621 - tri 874 603 600 618 - tri 875 603 618 610 - tri 876 618 621 615 - tri 877 600 621 618 - tri 878 622 606 607 - tri 879 613 616 288 - tri 880 279 613 289 - tri 881 618 612 292 - tri 882 292 612 279 - tri 883 610 618 292 - tri 884 610 292 293 - tri 885 598 624 623 - tri 886 625 604 603 - tri 887 595 598 625 - tri 888 595 625 603 - tri 889 622 607 626 - tri 890 624 599 627 - tri 891 599 626 627 - tri 892 598 599 624 - tri 893 598 623 625 - tri 894 623 628 625 - tri 895 630 601 629 - tri 896 630 605 601 - tri 897 631 605 630 - tri 898 631 607 605 - tri 899 627 626 631 - tri 900 626 607 631 - tri 901 628 632 625 - tri 902 625 632 604 - tri 903 632 602 604 - tri 904 632 633 602 - tri 905 633 601 602 - tri 906 633 629 601 - tri 907 276 610 293 - tri 908 540 276 192 - tri 909 540 608 276 - tri 910 416 414 634 - tri 911 541 609 608 - tri 912 541 608 540 - tri 913 631 630 629 - tri 914 631 629 633 - tri 915 627 631 633 - tri 916 627 633 632 - tri 917 624 627 632 - tri 918 624 632 628 - tri 919 623 624 628 - tri 920 306 471 193 - tri 921 472 471 306 - tri 922 476 472 306 - tri 923 476 306 122 - tri 924 468 420 419 - tri 925 466 575 475 - tri 926 579 574 491 - tri 927 475 579 491 - tri 928 489 478 493 - tri 929 493 478 479 - tri 930 576 581 574 - tri 931 581 573 574 - tri 932 578 635 581 - tri 933 578 581 576 - tri 934 580 493 573 - tri 935 576 574 579 - tri 936 576 579 575 - tri 937 475 474 473 - tri 938 475 491 474 - tri 939 488 544 477 - tri 940 617 396 394 - tri 941 617 394 403 - tri 942 620 636 619 - tri 943 638 637 636 - tri 944 639 638 636 - tri 945 638 640 637 - tri 946 638 446 640 - tri 947 414 638 639 - tri 948 414 421 638 - tri 949 421 446 638 - tri 950 639 636 620 - tri 951 446 641 640 - tri 952 637 411 412 - tri 953 636 637 412 - tri 954 636 412 619 - tri 955 619 396 617 - tri 956 619 412 396 - tri 957 619 617 621 - tri 958 621 617 615 - tri 959 606 639 620 - tri 960 606 414 639 - tri 961 637 640 411 - tri 962 640 413 411 - tri 963 394 399 402 - tri 964 402 399 407 - tri 965 408 409 498 - tri 966 498 409 494 - tri 967 530 532 517 - tri 968 529 530 517 - tri 969 413 531 529 - tri 970 389 642 379 - tri 971 389 379 378 - tri 972 645 644 643 - tri 973 645 643 646 - tri 974 649 648 647 - tri 975 361 356 357 - tri 976 364 360 358 - tri 977 364 358 361 - tri 978 428 371 426 - tri 979 388 371 428 - tri 980 437 426 450 - tri 981 450 426 452 - tri 982 452 387 461 - tri 983 452 371 387 - tri 984 426 371 452 - tri 985 641 650 531 - tri 986 531 650 530 - tri 987 640 641 531 - tri 988 640 531 413 - tri 989 651 644 645 - tri 990 651 649 647 - tri 991 651 647 644 - tri 992 360 454 385 - tri 993 444 454 360 - tri 994 443 444 360 - tri 995 404 496 495 - tri 996 400 404 406 - tri 997 406 404 495 - tri 998 391 644 390 - tri 999 390 644 647 - tri 1000 470 479 480 - tri 1001 470 480 455 - tri 1002 463 485 464 - tri 1003 485 594 464 - tri 1004 359 392 382 - tri 1005 359 382 358 - tri 1006 434 435 443 - tri 1007 434 443 652 - tri 1008 652 443 360 - tri 1009 386 652 360 - tri 1010 582 251 489 - tri 1011 259 251 582 - tri 1012 477 544 486 - tri 1013 486 484 482 - tri 1014 482 484 483 - tri 1015 653 584 589 - tri 1016 488 196 543 - tri 1017 136 196 488 - tri 1018 328 655 654 - tri 1019 328 656 655 - tri 1020 328 330 656 - tri 1021 328 657 332 - tri 1022 328 658 657 - tri 1023 328 659 658 - tri 1024 328 660 659 - tri 1025 328 654 660 - tri 1026 591 593 485 - tri 1027 591 485 484 - tri 1028 563 560 553 - tri 1029 563 565 560 - tri 1030 417 634 622 - tri 1031 596 622 626 - tri 1032 596 626 599 - tri 1033 596 417 622 - tri 1034 419 417 596 - tri 1035 541 597 609 - tri 1036 541 419 597 - tri 1037 468 419 471 - tri 1038 471 419 541 - tri 1039 592 584 653 - tri 1040 592 653 593 - tri 1041 661 653 589 - tri 1042 480 486 481 - tri 1043 480 477 486 - tri 1044 662 580 581 - tri 1045 662 582 580 - tri 1046 635 663 662 - tri 1047 635 662 581 - tri 1048 583 582 662 - tri 1049 583 662 663 - tri 1050 580 489 493 - tri 1051 582 489 580 - tri 1052 593 653 661 - tri 1053 594 593 661 - tri 1054 543 585 545 - tri 1055 545 585 586 - tri 1056 418 416 417 - tri 1057 417 416 634 - tri 1058 664 432 433 - tri 1059 664 665 432 - tri 1060 584 587 588 - tri 1061 383 380 666 - tri 1062 499 537 521 - tri 1063 538 535 537 - tri 1064 404 538 537 - tri 1065 429 427 438 - tri 1066 665 441 432 - tri 1067 667 438 436 - tri 1068 667 436 449 - tri 1069 398 405 400 - tri 1070 398 401 405 - tri 1071 634 414 606 - tri 1072 622 634 606 - tri 1073 569 566 562 - tri 1074 510 505 506 - tri 1075 406 495 409 - tri 1076 407 406 409 - tri 1077 614 669 668 - tri 1078 410 669 614 - tri 1079 410 408 669 - tri 1080 669 408 670 - tri 1081 668 669 670 - tri 1082 288 616 668 - tri 1083 614 668 616 - tri 1084 670 502 514 - tri 1085 670 408 502 - tri 1086 402 410 614 - tri 1087 514 515 346 - tri 1088 347 514 346 - tri 1089 288 668 348 - tri 1090 670 514 347 - tri 1091 348 670 347 - tri 1092 668 670 348 - tri 1093 514 513 515 - tri 1094 513 511 515 - tri 1095 508 255 155 - tri 1096 508 570 255 - tri 1097 509 568 508 - tri 1098 508 568 570 - tri 1099 497 671 551 - tri 1100 496 499 671 - tri 1101 496 671 497 - tri 1102 499 551 671 - tri 1103 499 519 551 - tri 1104 672 666 380 - tri 1105 672 380 381 - tri 1106 510 558 568 - tri 1107 510 568 509 - tri 1108 589 562 559 - tri 1109 382 673 381 - tri 1110 673 672 381 - tri 1111 674 526 528 - tri 1112 661 589 675 - tri 1113 589 559 674 - tri 1114 675 589 676 - tri 1115 392 673 382 - tri 1116 674 559 526 - tri 1117 527 526 559 - tri 1118 587 258 572 - tri 1119 258 256 572 - tri 1120 588 572 569 - tri 1121 587 572 588 - tri 1122 605 619 601 - tri 1123 601 619 600 - tri 1124 679 678 677 - tri 1125 681 677 680 - tri 1126 681 679 677 - tri 1127 684 683 682 - tri 1128 685 684 682 - tri 1129 686 684 685 - tri 1130 681 686 685 - tri 1131 681 680 686 - tri 1132 689 688 687 - tri 1133 687 688 690 - tri 1134 690 688 691 - tri 1135 688 692 691 - tri 1136 694 690 693 - tri 1137 690 691 693 - tri 1138 691 692 693 - tri 1139 693 692 695 - tri 1140 698 697 696 - tri 1141 701 700 699 - tri 1142 701 702 700 - tri 1143 699 700 703 - tri 1144 706 705 704 - tri 1145 705 707 704 - tri 1146 704 707 708 - tri 1147 707 709 708 - tri 1148 706 710 705 - tri 1149 688 704 708 - tri 1150 688 708 692 - tri 1151 680 677 711 - tri 1152 677 678 711 - tri 1153 714 713 712 - tri 1154 713 716 715 - tri 1155 715 716 717 - tri 1156 718 714 712 - tri 1157 712 713 715 - tri 1158 720 712 719 - tri 1159 715 717 721 - tri 1160 724 723 722 - tri 1161 727 726 725 - tri 1162 728 727 725 - tri 1163 729 726 727 - tri 1164 718 712 720 - tri 1165 716 730 717 - tri 1166 730 731 717 - tri 1167 733 724 732 - tri 1168 733 732 734 - tri 1169 733 734 735 - tri 1170 738 737 736 - tri 1171 728 725 739 - tri 1172 741 740 737 - tri 1173 741 737 738 - tri 1174 741 734 740 - tri 1175 739 725 742 - tri 1176 717 743 721 - tri 1177 745 718 744 - tri 1178 744 718 720 - tri 1179 744 720 746 - tri 1180 746 720 729 - tri 1181 747 746 729 - tri 1182 748 747 729 - tri 1183 748 729 727 - tri 1184 748 727 749 - tri 1185 749 727 728 - tri 1186 749 728 750 - tri 1187 753 752 751 - tri 1188 753 751 714 - tri 1189 745 753 714 - tri 1190 745 714 718 - tri 1191 756 755 754 - tri 1192 756 754 757 - tri 1193 759 758 754 - tri 1194 754 758 760 - tri 1195 757 754 760 - tri 1196 763 762 761 - tri 1197 766 765 764 - tri 1198 768 767 765 - tri 1199 768 765 769 - tri 1200 769 765 766 - tri 1201 770 767 768 - tri 1202 767 771 765 - tri 1203 774 773 772 - tri 1204 759 775 758 - tri 1205 778 777 776 - tri 1206 778 779 777 - tri 1207 778 776 780 - tri 1208 726 781 725 - tri 1209 781 783 782 - tri 1210 786 785 784 - tri 1211 786 784 787 - tri 1212 790 789 788 - tri 1213 791 788 789 - tri 1214 791 792 788 - tri 1215 795 794 793 - tri 1216 794 731 793 - tri 1217 796 794 795 - tri 1218 796 797 794 - tri 1219 800 799 798 - tri 1220 801 793 730 - tri 1221 793 731 730 - tri 1222 733 802 724 - tri 1223 738 736 803 - tri 1224 806 805 804 - tri 1225 803 736 807 - tri 1226 741 735 734 - tri 1227 804 809 808 - tri 1228 731 743 717 - tri 1229 811 810 796 - tri 1230 810 800 796 - tri 1231 812 800 810 - tri 1232 812 799 800 - tri 1233 812 813 799 - tri 1234 813 814 799 - tri 1235 814 806 799 - tri 1236 814 815 806 - tri 1237 815 805 806 - tri 1238 752 801 751 - tri 1239 816 801 752 - tri 1240 818 817 816 - tri 1241 816 817 801 - tri 1242 821 820 819 - tri 1243 821 819 822 - tri 1244 820 823 819 - tri 1245 823 824 819 - tri 1246 825 824 823 - tri 1247 828 827 826 - tri 1248 829 827 828 - tri 1249 766 764 829 - tri 1250 831 766 830 - tri 1251 831 832 766 - tri 1252 832 769 766 - tri 1253 833 831 830 - tri 1254 774 834 773 - tri 1255 822 834 774 - tri 1256 822 819 834 - tri 1257 830 766 829 - tri 1258 830 829 828 - tri 1259 830 828 835 - tri 1260 828 826 835 - tri 1261 824 837 836 - tri 1262 840 839 838 - tri 1263 840 838 841 - tri 1264 842 840 841 - tri 1265 845 844 843 - tri 1266 845 843 839 - tri 1267 846 845 839 - tri 1268 846 839 840 - tri 1269 847 845 846 - tri 1270 842 846 840 - tri 1271 850 849 848 - tri 1272 852 851 849 - tri 1273 777 853 776 - tri 1274 776 853 854 - tri 1275 856 855 852 - tri 1276 858 844 857 - tri 1277 859 858 857 - tri 1278 860 858 859 - tri 1279 845 857 844 - tri 1280 861 857 845 - tri 1281 861 859 857 - tri 1282 862 860 859 - tri 1283 862 859 861 - tri 1284 863 862 861 - tri 1285 866 865 864 - tri 1286 860 866 864 - tri 1287 860 864 858 - tri 1288 867 865 866 - tri 1289 862 866 860 - tri 1290 867 866 862 - tri 1291 868 862 863 - tri 1292 871 870 869 - tri 1293 874 873 872 - tri 1294 874 872 875 - tri 1295 873 871 869 - tri 1296 873 869 872 - tri 1297 878 877 876 - tri 1298 875 877 878 - tri 1299 875 872 877 - tri 1300 876 877 879 - tri 1301 870 880 869 - tri 1302 882 876 881 - tri 1303 882 878 876 - tri 1304 882 875 878 - tri 1305 877 880 879 - tri 1306 877 869 880 - tri 1307 872 869 877 - tri 1308 719 790 883 - tri 1309 790 884 883 - tri 1310 885 883 781 - tri 1311 758 887 886 - tri 1312 758 886 760 - tri 1313 888 819 824 - tri 1314 888 836 889 - tri 1315 888 824 836 - tri 1316 764 765 890 - tri 1317 873 891 871 - tri 1318 891 892 870 - tri 1319 895 894 893 - tri 1320 893 892 891 - tri 1321 893 896 892 - tri 1322 894 896 893 - tri 1323 894 897 896 - tri 1324 898 897 894 - tri 1325 891 870 871 - tri 1326 851 895 899 - tri 1327 893 891 873 - tri 1328 902 901 900 - tri 1329 901 903 900 - tri 1330 905 904 901 - tri 1331 905 901 902 - tri 1332 906 842 904 - tri 1333 906 904 905 - tri 1334 841 838 904 - tri 1335 904 838 901 - tri 1336 842 841 904 - tri 1337 908 902 907 - tri 1338 908 907 909 - tri 1339 910 908 909 - tri 1340 902 900 907 - tri 1341 910 905 908 - tri 1342 905 902 908 - tri 1343 911 905 910 - tri 1344 911 906 905 - tri 1345 729 912 885 - tri 1346 885 719 883 - tri 1347 720 719 912 - tri 1348 912 719 885 - tri 1349 781 883 783 - tri 1350 721 791 789 - tri 1351 743 791 721 - tri 1352 913 785 786 - tri 1353 915 914 791 - tri 1354 791 914 792 - tri 1355 797 915 916 - tri 1356 797 917 915 - tri 1357 917 914 915 - tri 1358 920 919 918 - tri 1359 797 918 917 - tri 1360 923 922 921 - tri 1361 923 921 924 - tri 1362 923 924 925 - tri 1363 926 922 923 - tri 1364 762 926 923 - tri 1365 927 846 842 - tri 1366 928 927 842 - tri 1367 928 842 906 - tri 1368 924 927 928 - tri 1369 924 921 927 - tri 1370 925 924 928 - tri 1371 931 930 929 - tri 1372 932 930 931 - tri 1373 933 932 931 - tri 1374 929 930 934 - tri 1375 929 934 935 - tri 1376 922 931 929 - tri 1377 929 935 921 - tri 1378 921 935 927 - tri 1379 922 929 921 - tri 1380 933 931 922 - tri 1381 926 933 922 - tri 1382 927 935 846 - tri 1383 938 937 936 - tri 1384 936 937 939 - tri 1385 938 923 925 - tri 1386 938 925 937 - tri 1387 835 938 936 - tri 1388 826 938 835 - tri 1389 826 762 938 - tri 1390 762 923 938 - tri 1391 940 928 906 - tri 1392 939 937 941 - tri 1393 937 940 941 - tri 1394 937 925 940 - tri 1395 925 928 940 - tri 1396 944 943 942 - tri 1397 945 944 942 - tri 1398 948 947 946 - tri 1399 948 946 943 - tri 1400 949 948 943 - tri 1401 949 943 944 - tri 1402 837 944 945 - tri 1403 837 949 944 - tri 1404 952 951 950 - tri 1405 951 953 950 - tri 1406 954 953 951 - tri 1407 954 955 953 - tri 1408 950 953 956 - tri 1409 953 957 956 - tri 1410 955 958 953 - tri 1411 953 958 957 - tri 1412 954 959 955 - tri 1413 960 959 954 - tri 1414 959 961 955 - tri 1415 955 961 958 - tri 1416 932 962 930 - tri 1417 932 950 962 - tri 1418 950 956 962 - tri 1419 942 964 963 - tri 1420 889 963 959 - tri 1421 959 963 961 - tri 1422 960 889 959 - tri 1423 888 889 960 - tri 1424 967 966 965 - tri 1425 970 969 968 - tri 1426 971 969 970 - tri 1427 974 973 972 - tri 1428 965 976 975 - tri 1429 965 975 977 - tri 1430 892 965 978 - tri 1431 965 977 978 - tri 1432 966 976 965 - tri 1433 973 980 979 - tri 1434 968 982 981 - tri 1435 973 979 972 - tri 1436 974 983 973 - tri 1437 984 983 974 - tri 1438 985 974 971 - tri 1439 876 984 986 - tri 1440 988 970 987 - tri 1441 989 970 988 - tri 1442 990 984 974 - tri 1443 986 984 990 - tri 1444 991 989 988 - tri 1445 992 986 990 - tri 1446 993 989 991 - tri 1447 993 985 989 - tri 1448 996 995 994 - tri 1449 995 997 994 - tri 1450 998 985 993 - tri 1451 998 999 985 - tri 1452 968 1000 982 - tri 1453 969 1001 968 - tri 1454 968 1001 1000 - tri 1455 969 1002 1001 - tri 1456 976 1003 975 - tri 1457 980 1004 979 - tri 1458 979 1004 1005 - tri 1459 973 880 980 - tri 1460 984 879 983 - tri 1461 876 879 984 - tri 1462 992 876 986 - tri 1463 1007 1006 980 - tri 1464 980 1006 1004 - tri 1465 978 977 1007 - tri 1466 1007 977 1008 - tri 1467 1007 1008 1006 - tri 1468 1005 1004 1009 - tri 1469 1001 1011 1010 - tri 1470 1000 1001 1010 - tri 1471 1006 1012 1004 - tri 1472 1004 1012 1013 - tri 1473 1006 1008 1012 - tri 1474 1015 1010 1014 - tri 1475 1018 1017 1016 - tri 1476 1019 1018 1016 - tri 1477 1021 1014 1020 - tri 1478 1015 1014 1021 - tri 1479 1013 1023 1022 - tri 1480 1009 1013 1022 - tri 1481 1026 1025 1024 - tri 1482 1022 1023 1027 - tri 1483 1030 1029 1028 - tri 1484 1030 1031 1029 - tri 1485 1030 1028 1014 - tri 1486 1010 1030 1014 - tri 1487 1019 1016 1025 - tri 1488 1034 1033 1032 - tri 1489 1034 1032 1016 - tri 1490 1034 1016 1017 - tri 1491 1014 1035 1020 - tri 1492 977 975 1026 - tri 1493 1011 1036 1010 - tri 1494 1004 1013 1009 - tri 1495 1000 1010 1015 - tri 1496 975 1025 1026 - tri 1497 1003 1018 1019 - tri 1498 1000 1015 1021 - tri 1499 1000 1021 982 - tri 1500 1012 1037 1013 - tri 1501 1012 1026 1037 - tri 1502 1008 1026 1012 - tri 1503 977 1026 1008 - tri 1504 1009 1031 1036 - tri 1505 1011 1009 1036 - tri 1506 1005 1009 1011 - tri 1507 974 972 969 - tri 1508 969 972 1002 - tri 1509 974 969 971 - tri 1510 999 990 974 - tri 1511 999 974 985 - tri 1512 992 990 999 - tri 1513 972 979 1005 - tri 1514 1002 1005 1011 - tri 1515 972 1005 1002 - tri 1516 1002 1011 1001 - tri 1517 1031 1022 1027 - tri 1518 1009 1022 1031 - tri 1519 1038 679 1024 - tri 1520 1024 679 681 - tri 1521 1031 1027 1039 - tri 1522 1014 1028 1035 - tri 1523 1028 1029 1040 - tri 1524 1035 1028 1040 - tri 1525 1039 1027 706 - tri 1526 1043 1042 1041 - tri 1527 1043 1041 1044 - tri 1528 1044 1041 1045 - tri 1529 1033 1046 1032 - tri 1530 1046 1043 1044 - tri 1531 1032 1046 1044 - tri 1532 1049 1048 1047 - tri 1533 1049 1047 1050 - tri 1534 1041 1042 1049 - tri 1535 1041 1049 1050 - tri 1536 1041 1050 1045 - tri 1537 1032 1044 1051 - tri 1538 1052 993 991 - tri 1539 1052 998 993 - tri 1540 1053 995 996 - tri 1541 998 1054 999 - tri 1542 1057 1056 1055 - tri 1543 900 903 1058 - tri 1544 900 1058 1059 - tri 1545 1059 1058 998 - tri 1546 907 900 1059 - tri 1547 907 1059 1060 - tri 1548 1059 1052 1060 - tri 1549 1059 998 1052 - tri 1550 903 1061 1058 - tri 1551 1056 1053 1062 - tri 1552 909 907 1060 - tri 1553 1057 1063 1056 - tri 1554 1056 1063 1064 - tri 1555 1056 1064 1053 - tri 1556 1058 1054 998 - tri 1557 1064 995 1053 - tri 1558 1058 1061 1065 - tri 1559 1058 1065 1054 - tri 1560 1013 685 1023 - tri 1561 1066 1048 1049 - tri 1562 1042 1066 1049 - tri 1563 1003 1019 975 - tri 1564 975 1019 1025 - tri 1565 898 894 895 - tri 1566 851 898 895 - tri 1567 799 919 798 - tri 1568 804 808 919 - tri 1569 799 806 919 - tri 1570 806 804 919 - tri 1571 714 716 713 - tri 1572 714 751 716 - tri 1573 751 730 716 - tri 1574 801 730 751 - tri 1575 802 1067 723 - tri 1576 802 723 724 - tri 1577 817 793 801 - tri 1578 817 795 793 - tri 1579 1036 1031 1030 - tri 1580 1010 1036 1030 - tri 1581 940 911 941 - tri 1582 940 906 911 - tri 1583 1070 1069 1068 - tri 1584 1070 1071 1069 - tri 1585 1072 1071 1070 - tri 1586 1072 1073 1071 - tri 1587 1074 1073 1072 - tri 1588 1077 1076 1075 - tri 1589 1077 1078 1076 - tri 1590 1077 1079 1078 - tri 1591 1079 1080 1078 - tri 1592 1079 1081 1080 - tri 1593 1081 1082 1080 - tri 1594 1074 1083 1073 - tri 1595 946 1083 1074 - tri 1596 1084 1070 867 - tri 1597 1072 1070 1084 - tri 1598 1068 1069 1055 - tri 1599 1068 1055 1085 - tri 1600 1073 1086 1071 - tri 1601 1086 1057 1071 - tri 1602 1076 1078 1087 - tri 1603 1061 1076 1087 - tri 1604 1087 1078 1080 - tri 1605 1087 1080 992 - tri 1606 1088 1082 1081 - tri 1607 1088 1089 1082 - tri 1608 1090 1088 1079 - tri 1609 1079 1088 1081 - tri 1610 843 1079 1077 - tri 1611 843 1090 1079 - tri 1612 843 1077 1075 - tri 1613 843 1075 1091 - tri 1614 1091 1075 1076 - tri 1615 1091 1076 1061 - tri 1616 930 962 934 - tri 1617 957 863 956 - tri 1618 958 868 957 - tri 1619 868 863 957 - tri 1620 890 926 763 - tri 1621 763 926 762 - tri 1622 890 763 761 - tri 1623 958 961 868 - tri 1624 964 961 963 - tri 1625 964 868 961 - tri 1626 886 926 760 - tri 1627 886 933 926 - tri 1628 847 962 956 - tri 1629 863 847 956 - tri 1630 847 861 845 - tri 1631 863 861 847 - tri 1632 964 862 868 - tri 1633 964 867 862 - tri 1634 1088 848 1089 - tri 1635 848 881 1089 - tri 1636 850 848 1088 - tri 1637 865 852 864 - tri 1638 865 856 852 - tri 1639 1092 1061 903 - tri 1640 1092 1091 1061 - tri 1641 1061 1087 1065 - tri 1642 901 1092 903 - tri 1643 838 1092 901 - tri 1644 1093 911 910 - tri 1645 947 1083 946 - tri 1646 941 911 1093 - tri 1647 839 843 1091 - tri 1648 839 1091 838 - tri 1649 838 1091 1092 - tri 1650 864 849 858 - tri 1651 864 852 849 - tri 1652 889 942 963 - tri 1653 945 942 889 - tri 1654 836 945 889 - tri 1655 836 837 945 - tri 1656 934 962 847 - tri 1657 934 846 935 - tri 1658 934 847 846 - tri 1659 1094 772 775 - tri 1660 774 772 1094 - tri 1661 759 1094 775 - tri 1662 773 951 772 - tri 1663 773 954 951 - tri 1664 775 772 952 - tri 1665 772 951 952 - tri 1666 888 960 834 - tri 1667 834 960 773 - tri 1668 773 960 954 - tri 1669 787 784 1095 - tri 1670 790 788 884 - tri 1671 913 1096 785 - tri 1672 785 774 784 - tri 1673 784 774 1094 - tri 1674 1095 784 1094 - tri 1675 1090 850 1088 - tri 1676 844 850 1090 - tri 1677 844 1090 843 - tri 1678 1087 992 999 - tri 1679 1089 881 992 - tri 1680 881 876 992 - tri 1681 879 880 973 - tri 1682 983 879 973 - tri 1683 1083 1086 1073 - tri 1684 1082 992 1080 - tri 1685 1089 992 1082 - tri 1686 848 882 881 - tri 1687 892 978 870 - tri 1688 870 978 1007 - tri 1689 870 1007 880 - tri 1690 897 1097 896 - tri 1691 1097 996 994 - tri 1692 1097 994 896 - tri 1693 899 895 893 - tri 1694 899 893 873 - tri 1695 899 873 874 - tri 1696 896 965 892 - tri 1697 967 965 896 - tri 1698 997 966 967 - tri 1699 994 967 896 - tri 1700 994 997 967 - tri 1701 887 950 932 - tri 1702 887 952 950 - tri 1703 886 932 933 - tri 1704 886 887 932 - tri 1705 1095 1094 759 - tri 1706 715 721 1098 - tri 1707 758 775 887 - tri 1708 775 952 887 - tri 1709 780 776 854 - tri 1710 777 756 853 - tri 1711 777 1100 1099 - tri 1712 1026 1024 681 - tri 1713 1026 681 1037 - tri 1714 827 761 826 - tri 1715 761 762 826 - tri 1716 898 1097 897 - tri 1717 898 1062 1097 - tri 1718 1053 1097 1062 - tri 1719 1053 996 1097 - tri 1720 852 898 851 - tri 1721 852 855 898 - tri 1722 855 1062 898 - tri 1723 856 1056 855 - tri 1724 1056 1062 855 - tri 1725 865 1085 856 - tri 1726 867 1085 865 - tri 1727 867 1068 1085 - tri 1728 1070 1068 867 - tri 1729 942 1084 964 - tri 1730 942 943 1084 - tri 1731 943 946 1084 - tri 1732 1084 867 964 - tri 1733 1085 1055 1056 - tri 1734 1085 1056 856 - tri 1735 844 849 850 - tri 1736 858 849 844 - tri 1737 854 853 757 - tri 1738 853 756 757 - tri 1739 1099 755 756 - tri 1740 777 1099 756 - tri 1741 759 754 755 - tri 1742 1099 759 755 - tri 1743 779 1100 777 - tri 1744 779 1101 1100 - tri 1745 885 781 726 - tri 1746 729 885 726 - tri 1747 725 782 742 - tri 1748 725 781 782 - tri 1749 712 715 1098 - tri 1750 712 1098 719 - tri 1751 719 1098 790 - tri 1752 1098 789 790 - tri 1753 1098 721 789 - tri 1754 1101 1095 759 - tri 1755 779 787 1101 - tri 1756 787 1095 1101 - tri 1757 1016 1032 1051 - tri 1758 1051 1045 1025 - tri 1759 1016 1051 1025 - tri 1760 1051 1044 1045 - tri 1761 1025 1045 1024 - tri 1762 1045 1038 1024 - tri 1763 1038 1050 679 - tri 1764 1045 1050 1038 - tri 1765 825 823 1102 - tri 1766 1103 825 1102 - tri 1767 1104 823 820 - tri 1768 1104 1102 823 - tri 1769 1105 1104 820 - tri 1770 913 821 822 - tri 1771 1096 774 785 - tri 1772 913 822 1096 - tri 1773 1096 822 774 - tri 1774 794 797 916 - tri 1775 771 926 890 - tri 1776 765 771 890 - tri 1777 771 760 926 - tri 1778 1106 768 769 - tri 1779 1106 769 832 - tri 1780 1107 1106 832 - tri 1781 1107 832 831 - tri 1782 1100 759 1099 - tri 1783 1101 759 1100 - tri 1784 720 912 729 - tri 1785 916 743 731 - tri 1786 794 916 731 - tri 1787 811 796 795 - tri 1788 818 795 817 - tri 1789 811 795 818 - tri 1790 1108 768 1106 - tri 1791 780 854 770 - tri 1792 1108 770 768 - tri 1793 1108 780 770 - tri 1794 916 791 743 - tri 1795 916 915 791 - tri 1796 821 1105 820 - tri 1797 888 834 819 - tri 1798 825 837 824 - tri 1799 798 919 920 - tri 1800 920 918 797 - tri 1801 796 800 1109 - tri 1802 800 798 1109 - tri 1803 1109 798 920 - tri 1804 1109 920 797 - tri 1805 796 1109 797 - tri 1806 919 808 918 - tri 1807 1112 1111 1110 - tri 1808 1112 1110 1113 - tri 1809 1112 1113 913 - tri 1810 1113 1105 821 - tri 1811 913 1113 821 - tri 1812 1115 825 1114 - tri 1813 1114 825 1103 - tri 1814 1116 1107 833 - tri 1815 1107 831 833 - tri 1816 1115 1114 1110 - tri 1817 1111 1115 1110 - tri 1818 1103 1102 1104 - tri 1819 1110 1114 1103 - tri 1820 1110 1103 1104 - tri 1821 1110 1105 1113 - tri 1822 1110 1104 1105 - tri 1823 985 971 989 - tri 1824 989 971 970 - tri 1825 880 1007 980 - tri 1826 1054 1087 999 - tri 1827 1065 1087 1054 - tri 1828 1013 681 685 - tri 1829 1037 681 1013 - tri 1830 678 699 703 - tri 1831 678 701 699 - tri 1832 1048 1118 1117 - tri 1833 1048 1117 1047 - tri 1834 700 1117 1119 - tri 1835 702 1117 700 - tri 1836 1121 1120 697 - tri 1837 1123 703 1122 - tri 1838 1123 1122 1124 - tri 1839 684 711 683 - tri 1840 686 711 684 - tri 1841 680 711 686 - tri 1842 711 678 703 - tri 1843 683 711 1123 - tri 1844 711 703 1123 - tri 1845 1121 697 1125 - tri 1846 1127 1123 1126 - tri 1847 1127 1126 707 - tri 1848 1126 1123 1124 - tri 1849 1126 1124 709 - tri 1850 682 683 1127 - tri 1851 683 1123 1127 - tri 1852 1023 1128 1027 - tri 1853 1128 682 706 - tri 1854 1027 1128 706 - tri 1855 1031 1039 1029 - tri 1856 682 1127 710 - tri 1857 682 710 706 - tri 1858 710 1127 707 - tri 1859 710 707 705 - tri 1860 1126 709 707 - tri 1861 678 702 701 - tri 1862 703 700 1122 - tri 1863 700 1119 1122 - tri 1864 1040 1029 1129 - tri 1865 1040 1129 694 - tri 1866 1039 689 1029 - tri 1867 1039 706 689 - tri 1868 1129 1029 687 - tri 1869 1029 689 687 - tri 1870 689 706 688 - tri 1871 706 704 688 - tri 1872 1129 690 694 - tri 1873 1129 687 690 - tri 1874 1130 697 698 - tri 1875 1125 697 1130 - tri 1876 1120 1131 697 - tri 1877 1132 697 1131 - tri 1878 1133 697 1132 - tri 1879 1128 685 682 - tri 1880 1023 685 1128 - tri 1881 970 968 987 - tri 1882 987 968 981 - tri 1883 849 1134 848 - tri 1884 849 851 1134 - tri 1885 1134 874 875 - tri 1886 1134 875 882 - tri 1887 1134 899 874 - tri 1888 851 899 1134 - tri 1889 848 1134 882 - tri 1890 679 1050 678 - tri 1891 1050 1047 678 - tri 1892 678 1117 702 - tri 1893 1047 1117 678 - tri 1894 764 890 761 - tri 1895 764 761 827 - tri 1896 764 827 829 - tri 1897 771 757 760 - tri 1898 767 757 771 - tri 1899 770 854 767 - tri 1900 854 757 767 - tri 1901 1071 1057 1069 - tri 1902 1057 1055 1069 - tri 1903 946 1072 1084 - tri 1904 946 1074 1072 - tri 1905 1137 1136 1135 - tri 1906 1139 1138 1136 - tri 1907 1139 1136 1137 - tri 1908 1142 1141 1140 - tri 1909 1143 1141 1142 - tri 1910 1144 1143 1142 - tri 1911 1139 1143 1144 - tri 1912 1139 1144 1138 - tri 1913 1147 1146 1145 - tri 1914 1146 1148 1145 - tri 1915 1148 1149 1145 - tri 1916 1145 1149 1150 - tri 1917 694 693 1148 - tri 1918 1148 693 1149 - tri 1919 1149 693 1150 - tri 1920 693 695 1150 - tri 1921 1151 696 697 - tri 1922 1154 1153 1152 - tri 1923 1154 1152 1155 - tri 1924 1153 1156 1152 - tri 1925 1159 1158 1157 - tri 1926 1157 1158 1160 - tri 1927 1158 1161 1160 - tri 1928 1160 1161 1162 - tri 1929 1159 1157 1163 - tri 1930 1145 1161 1158 - tri 1931 1145 1150 1161 - tri 1932 1138 1164 1136 - tri 1933 1136 1164 1135 - tri 1934 1167 1166 1165 - tri 1935 1165 1169 1168 - tri 1936 1169 1170 1168 - tri 1937 1171 1166 1167 - tri 1938 1166 1169 1165 - tri 1939 1173 1172 1166 - tri 1940 1169 1174 1170 - tri 1941 1177 1176 1175 - tri 1942 1180 1179 1178 - tri 1943 1181 1179 1180 - tri 1944 1182 1180 1178 - tri 1945 1171 1173 1166 - tri 1946 1168 1170 1183 - tri 1947 1183 1170 1184 - tri 1948 1186 1185 1177 - tri 1949 1186 1187 1185 - tri 1950 1186 1188 1187 - tri 1951 1191 1190 1189 - tri 1952 1181 1192 1179 - tri 1953 1194 1189 1193 - tri 1954 1194 1191 1189 - tri 1955 1194 1193 1187 - tri 1956 1192 1195 1179 - tri 1957 1170 1174 1196 - tri 1958 1198 1197 1171 - tri 1959 1197 1173 1171 - tri 1960 1197 1199 1173 - tri 1961 1199 1182 1173 - tri 1962 1200 1182 1199 - tri 1963 1201 1182 1200 - tri 1964 1201 1180 1182 - tri 1965 1201 1202 1180 - tri 1966 1202 1181 1180 - tri 1967 1202 1203 1181 - tri 1968 1206 1205 1204 - tri 1969 1206 1167 1205 - tri 1970 1198 1167 1206 - tri 1971 1198 1171 1167 - tri 1972 1209 1208 1207 - tri 1973 1209 1210 1208 - tri 1974 1212 1208 1211 - tri 1975 1208 1213 1211 - tri 1976 1210 1213 1208 - tri 1977 1216 1215 1214 - tri 1978 1219 1218 1217 - tri 1979 1221 1217 1220 - tri 1980 1221 1222 1217 - tri 1981 1222 1219 1217 - tri 1982 1223 1221 1220 - tri 1983 1220 1217 1224 - tri 1984 1227 1226 1225 - tri 1985 1212 1211 1228 - tri 1986 1231 1230 1229 - tri 1987 1231 1229 1232 - tri 1988 1231 1233 1230 - tri 1989 1178 1179 1234 - tri 1990 1234 1236 1235 - tri 1991 1239 1238 1237 - tri 1992 1239 1240 1238 - tri 1993 1243 1242 1241 - tri 1994 1244 1241 1242 - tri 1995 1244 1242 1245 - tri 1996 1248 1247 1246 - tri 1997 1246 1247 1184 - tri 1998 1249 1248 1246 - tri 1999 1249 1246 1250 - tri 2000 1253 1252 1251 - tri 2001 1254 1183 1247 - tri 2002 1247 1183 1184 - tri 2003 1186 1177 1255 - tri 2004 1191 1256 1190 - tri 2005 1259 1258 1257 - tri 2006 1256 1260 1190 - tri 2007 1194 1187 1188 - tri 2008 1258 1262 1261 - tri 2009 1184 1170 1196 - tri 2010 1264 1249 1263 - tri 2011 1263 1249 1253 - tri 2012 1265 1263 1253 - tri 2013 1265 1253 1251 - tri 2014 1265 1251 1266 - tri 2015 1266 1251 1267 - tri 2016 1267 1251 1259 - tri 2017 1267 1259 1268 - tri 2018 1268 1259 1257 - tri 2019 1204 1205 1254 - tri 2020 1269 1204 1254 - tri 2021 1271 1269 1270 - tri 2022 1269 1254 1270 - tri 2023 1274 1273 1272 - tri 2024 1274 1275 1273 - tri 2025 1272 1273 1276 - tri 2026 1276 1273 1277 - tri 2027 1278 1276 1277 - tri 2028 1281 1280 1279 - tri 2029 1282 1281 1279 - tri 2030 1219 1282 1218 - tri 2031 1284 1283 1219 - tri 2032 1284 1219 1285 - tri 2033 1285 1219 1222 - tri 2034 1286 1283 1284 - tri 2035 1227 1225 1287 - tri 2036 1275 1227 1287 - tri 2037 1275 1287 1273 - tri 2038 1283 1282 1219 - tri 2039 1283 1281 1282 - tri 2040 1283 1288 1281 - tri 2041 1281 1288 1280 - tri 2042 1277 1290 1289 - tri 2043 1293 1292 1291 - tri 2044 1293 1294 1292 - tri 2045 1295 1294 1293 - tri 2046 1298 1297 1296 - tri 2047 1298 1291 1297 - tri 2048 1299 1291 1298 - tri 2049 1299 1293 1291 - tri 2050 1300 1299 1298 - tri 2051 1295 1293 1299 - tri 2052 1303 1302 1301 - tri 2053 1305 1301 1304 - tri 2054 1229 1230 1306 - tri 2055 1230 1307 1306 - tri 2056 1309 1305 1308 - tri 2057 1311 1310 1296 - tri 2058 1312 1310 1311 - tri 2059 1313 1312 1311 - tri 2060 1298 1296 1310 - tri 2061 1314 1298 1310 - tri 2062 1314 1310 1312 - tri 2063 1315 1312 1313 - tri 2064 1315 1314 1312 - tri 2065 1316 1314 1315 - tri 2066 1319 1318 1317 - tri 2067 1313 1318 1319 - tri 2068 1313 1311 1318 - tri 2069 1320 1319 1317 - tri 2070 1315 1313 1319 - tri 2071 1320 1315 1319 - tri 2072 1321 1316 1315 - tri 2073 1324 1323 1322 - tri 2074 1327 1326 1325 - tri 2075 1327 1328 1326 - tri 2076 1325 1323 1324 - tri 2077 1325 1326 1323 - tri 2078 1331 1330 1329 - tri 2079 1328 1331 1329 - tri 2080 1328 1329 1326 - tri 2081 1330 1332 1329 - tri 2082 1322 1323 1333 - tri 2083 1335 1334 1330 - tri 2084 1335 1330 1331 - tri 2085 1335 1331 1328 - tri 2086 1329 1332 1333 - tri 2087 1329 1333 1323 - tri 2088 1326 1329 1323 - tri 2089 1172 1336 1243 - tri 2090 1243 1336 1337 - tri 2091 1338 1234 1336 - tri 2092 1211 1340 1339 - tri 2093 1211 1213 1340 - tri 2094 1341 1277 1273 - tri 2095 1341 1342 1290 - tri 2096 1341 1290 1277 - tri 2097 1218 1343 1217 - tri 2098 1325 1324 1344 - tri 2099 1344 1322 1345 - tri 2100 1348 1347 1346 - tri 2101 1347 1344 1345 - tri 2102 1347 1345 1349 - tri 2103 1346 1347 1349 - tri 2104 1346 1349 1350 - tri 2105 1351 1346 1350 - tri 2106 1344 1324 1322 - tri 2107 1304 1352 1348 - tri 2108 1347 1325 1344 - tri 2109 1355 1354 1353 - tri 2110 1353 1354 1356 - tri 2111 1358 1353 1357 - tri 2112 1358 1355 1353 - tri 2113 1359 1357 1295 - tri 2114 1359 1358 1357 - tri 2115 1294 1357 1292 - tri 2116 1357 1353 1292 - tri 2117 1295 1357 1294 - tri 2118 1361 1360 1355 - tri 2119 1361 1362 1360 - tri 2120 1363 1362 1361 - tri 2121 1355 1360 1354 - tri 2122 1363 1361 1358 - tri 2123 1358 1361 1355 - tri 2124 1364 1363 1358 - tri 2125 1364 1358 1359 - tri 2126 1182 1338 1365 - tri 2127 1338 1336 1172 - tri 2128 1173 1365 1172 - tri 2129 1365 1338 1172 - tri 2130 1234 1235 1336 - tri 2131 1174 1241 1244 - tri 2132 1196 1174 1244 - tri 2133 1366 1239 1237 - tri 2134 1368 1244 1367 - tri 2135 1244 1245 1367 - tri 2136 1250 1369 1368 - tri 2137 1250 1368 1370 - tri 2138 1370 1368 1367 - tri 2139 1373 1372 1371 - tri 2140 1250 1370 1372 - tri 2141 1376 1375 1374 - tri 2142 1376 1377 1375 - tri 2143 1376 1378 1377 - tri 2144 1379 1376 1374 - tri 2145 1214 1376 1379 - tri 2146 1380 1295 1299 - tri 2147 1381 1295 1380 - tri 2148 1381 1359 1295 - tri 2149 1377 1381 1380 - tri 2150 1377 1380 1375 - tri 2151 1378 1381 1377 - tri 2152 1384 1383 1382 - tri 2153 1385 1384 1382 - tri 2154 1386 1384 1385 - tri 2155 1383 1387 1382 - tri 2156 1383 1388 1387 - tri 2157 1374 1383 1384 - tri 2158 1383 1375 1388 - tri 2159 1375 1380 1388 - tri 2160 1374 1375 1383 - tri 2161 1386 1374 1384 - tri 2162 1379 1374 1386 - tri 2163 1380 1299 1388 - tri 2164 1391 1390 1389 - tri 2165 1390 1392 1389 - tri 2166 1391 1378 1376 - tri 2167 1391 1389 1378 - tri 2168 1288 1390 1391 - tri 2169 1280 1288 1391 - tri 2170 1280 1391 1214 - tri 2171 1214 1391 1376 - tri 2172 1393 1359 1381 - tri 2173 1392 1394 1389 - tri 2174 1389 1394 1393 - tri 2175 1389 1393 1378 - tri 2176 1378 1393 1381 - tri 2177 1397 1396 1395 - tri 2178 1398 1396 1397 - tri 2179 1401 1400 1399 - tri 2180 1401 1395 1400 - tri 2181 1402 1395 1401 - tri 2182 1402 1397 1395 - tri 2183 1289 1398 1397 - tri 2184 1289 1397 1402 - tri 2185 1405 1404 1403 - tri 2186 1403 1404 1406 - tri 2187 1407 1403 1406 - tri 2188 1407 1406 1408 - tri 2189 1404 1409 1406 - tri 2190 1406 1409 1410 - tri 2191 1408 1406 1411 - tri 2192 1406 1410 1411 - tri 2193 1407 1408 1412 - tri 2194 1413 1407 1412 - tri 2195 1412 1408 1414 - tri 2196 1408 1411 1414 - tri 2197 1385 1382 1415 - tri 2198 1385 1415 1404 - tri 2199 1404 1415 1409 - tri 2200 1396 1417 1416 - tri 2201 1342 1412 1417 - tri 2202 1412 1414 1417 - tri 2203 1413 1412 1342 - tri 2204 1341 1413 1342 - tri 2205 1420 1419 1418 - tri 2206 1423 1422 1421 - tri 2207 1424 1423 1421 - tri 2208 1427 1426 1425 - tri 2209 1419 1429 1428 - tri 2210 1419 1430 1429 - tri 2211 1345 1431 1419 - tri 2212 1419 1431 1430 - tri 2213 1418 1419 1428 - tri 2214 1425 1433 1432 - tri 2215 1422 1435 1434 - tri 2216 1425 1426 1433 - tri 2217 1427 1425 1436 - tri 2218 1437 1427 1436 - tri 2219 1438 1424 1427 - tri 2220 1330 1439 1437 - tri 2221 1441 1440 1423 - tri 2222 1442 1441 1423 - tri 2223 1443 1427 1437 - tri 2224 1439 1443 1437 - tri 2225 1444 1441 1442 - tri 2226 1445 1443 1439 - tri 2227 1446 1444 1442 - tri 2228 1446 1442 1438 - tri 2229 1449 1448 1447 - tri 2230 1447 1448 1450 - tri 2231 1451 1446 1438 - tri 2232 1451 1438 1452 - tri 2233 1422 1434 1453 - tri 2234 1421 1422 1454 - tri 2235 1422 1453 1454 - tri 2236 1421 1454 1455 - tri 2237 1428 1429 1456 - tri 2238 1432 1433 1457 - tri 2239 1433 1458 1457 - tri 2240 1425 1432 1333 - tri 2241 1437 1436 1332 - tri 2242 1330 1437 1332 - tri 2243 1445 1439 1330 - tri 2244 1460 1432 1459 - tri 2245 1432 1457 1459 - tri 2246 1431 1460 1430 - tri 2247 1460 1461 1430 - tri 2248 1460 1459 1461 - tri 2249 1458 1462 1457 - tri 2250 1454 1464 1463 - tri 2251 1453 1464 1454 - tri 2252 1459 1457 1465 - tri 2253 1457 1466 1465 - tri 2254 1459 1465 1461 - tri 2255 1468 1467 1464 - tri 2256 1470 1469 1017 - tri 2257 1471 1469 1470 - tri 2258 1472 1020 1467 - tri 2259 1468 1472 1467 - tri 2260 1466 1474 1473 - tri 2261 1462 1474 1466 - tri 2262 1477 1476 1475 - tri 2263 1474 1478 1473 - tri 2264 1481 1480 1479 - tri 2265 1481 1479 1482 - tri 2266 1481 1467 1480 - tri 2267 1464 1467 1481 - tri 2268 1471 1475 1469 - tri 2269 1034 1483 1033 - tri 2270 1034 1469 1483 - tri 2271 1034 1017 1469 - tri 2272 1467 1020 1035 - tri 2273 1430 1477 1429 - tri 2274 1463 1464 1484 - tri 2275 1457 1462 1466 - tri 2276 1453 1468 1464 - tri 2277 1429 1477 1475 - tri 2278 1456 1471 1470 - tri 2279 1453 1472 1468 - tri 2280 1453 1434 1472 - tri 2281 1465 1466 1485 - tri 2282 1465 1485 1477 - tri 2283 1461 1465 1477 - tri 2284 1430 1461 1477 - tri 2285 1462 1484 1482 - tri 2286 1463 1484 1462 - tri 2287 1458 1463 1462 - tri 2288 1427 1421 1426 - tri 2289 1421 1455 1426 - tri 2290 1427 1424 1421 - tri 2291 1452 1427 1443 - tri 2292 1452 1438 1427 - tri 2293 1445 1452 1443 - tri 2294 1426 1458 1433 - tri 2295 1455 1463 1458 - tri 2296 1426 1455 1458 - tri 2297 1455 1454 1463 - tri 2298 1482 1478 1474 - tri 2299 1462 1482 1474 - tri 2300 1486 1476 1137 - tri 2301 1476 1139 1137 - tri 2302 1482 1487 1478 - tri 2303 1467 1035 1480 - tri 2304 1480 1040 1479 - tri 2305 1035 1040 1480 - tri 2306 1487 1159 1478 - tri 2307 1043 1488 1042 - tri 2308 1043 1489 1488 - tri 2309 1489 1490 1488 - tri 2310 1033 1483 1046 - tri 2311 1046 1489 1043 - tri 2312 1483 1489 1046 - tri 2313 1492 1491 1048 - tri 2314 1492 1493 1491 - tri 2315 1488 1492 1042 - tri 2316 1488 1493 1492 - tri 2317 1488 1490 1493 - tri 2318 1483 1494 1489 - tri 2319 1495 1444 1446 - tri 2320 1495 1446 1451 - tri 2321 1496 1449 1447 - tri 2322 1451 1452 1497 - tri 2323 1500 1499 1498 - tri 2324 1354 1501 1356 - tri 2325 1354 1502 1501 - tri 2326 1502 1451 1501 - tri 2327 1360 1502 1354 - tri 2328 1360 1503 1502 - tri 2329 1502 1503 1495 - tri 2330 1502 1495 1451 - tri 2331 1356 1501 1504 - tri 2332 1498 1505 1496 - tri 2333 1362 1503 1360 - tri 2334 1500 1498 1506 - tri 2335 1498 1507 1506 - tri 2336 1498 1496 1507 - tri 2337 1501 1451 1497 - tri 2338 1507 1496 1447 - tri 2339 1501 1508 1504 - tri 2340 1501 1497 1508 - tri 2341 1466 1473 1143 - tri 2342 1066 1492 1048 - tri 2343 1042 1492 1066 - tri 2344 1456 1429 1471 - tri 2345 1429 1475 1471 - tri 2346 1351 1348 1346 - tri 2347 1304 1348 1351 - tri 2348 1251 1252 1371 - tri 2349 1258 1371 1262 - tri 2350 1251 1371 1259 - tri 2351 1259 1371 1258 - tri 2352 1167 1165 1168 - tri 2353 1167 1168 1205 - tri 2354 1205 1168 1183 - tri 2355 1254 1205 1183 - tri 2356 1255 1175 1509 - tri 2357 1255 1177 1175 - tri 2358 1270 1254 1247 - tri 2359 1270 1247 1248 - tri 2360 1484 1481 1482 - tri 2361 1464 1481 1484 - tri 2362 1393 1394 1364 - tri 2363 1393 1364 1359 - tri 2364 1512 1511 1510 - tri 2365 1512 1510 1513 - tri 2366 1514 1512 1513 - tri 2367 1514 1513 1515 - tri 2368 1516 1514 1515 - tri 2369 1519 1518 1517 - tri 2370 1519 1517 1520 - tri 2371 1519 1520 1521 - tri 2372 1521 1520 1522 - tri 2373 1521 1522 1523 - tri 2374 1523 1522 1524 - tri 2375 1516 1515 1525 - tri 2376 1400 1516 1525 - tri 2377 1526 1320 1512 - tri 2378 1514 1526 1512 - tri 2379 1511 1499 1510 - tri 2380 1511 1527 1499 - tri 2381 1515 1513 1528 - tri 2382 1528 1513 1500 - tri 2383 1517 1529 1520 - tri 2384 1504 1529 1517 - tri 2385 1529 1522 1520 - tri 2386 1529 1445 1522 - tri 2387 1530 1523 1524 - tri 2388 1530 1524 1531 - tri 2389 1532 1521 1530 - tri 2390 1521 1523 1530 - tri 2391 1297 1519 1521 - tri 2392 1297 1521 1532 - tri 2393 1297 1518 1519 - tri 2394 1297 1533 1518 - tri 2395 1533 1517 1518 - tri 2396 1533 1504 1517 - tri 2397 1382 1387 1415 - tri 2398 1410 1409 1316 - tri 2399 1411 1410 1321 - tri 2400 1321 1410 1316 - tri 2401 1343 1216 1379 - tri 2402 1216 1214 1379 - tri 2403 1343 1215 1216 - tri 2404 1411 1321 1414 - tri 2405 1416 1417 1414 - tri 2406 1416 1414 1321 - tri 2407 1340 1213 1379 - tri 2408 1340 1379 1386 - tri 2409 1300 1409 1415 - tri 2410 1316 1409 1300 - tri 2411 1300 1298 1314 - tri 2412 1316 1300 1314 - tri 2413 1416 1321 1315 - tri 2414 1416 1315 1320 - tri 2415 1530 1531 1302 - tri 2416 1302 1531 1334 - tri 2417 1303 1530 1302 - tri 2418 1317 1318 1305 - tri 2419 1317 1305 1309 - tri 2420 1534 1356 1504 - tri 2421 1534 1504 1533 - tri 2422 1504 1508 1529 - tri 2423 1353 1356 1534 - tri 2424 1292 1353 1534 - tri 2425 1535 1363 1364 - tri 2426 1399 1400 1525 - tri 2427 1394 1535 1364 - tri 2428 1291 1533 1297 - tri 2429 1291 1292 1533 - tri 2430 1292 1534 1533 - tri 2431 1318 1311 1301 - tri 2432 1318 1301 1305 - tri 2433 1342 1417 1396 - tri 2434 1398 1342 1396 - tri 2435 1290 1342 1398 - tri 2436 1290 1398 1289 - tri 2437 1387 1300 1415 - tri 2438 1387 1388 1299 - tri 2439 1387 1299 1300 - tri 2440 1536 1228 1226 - tri 2441 1227 1536 1226 - tri 2442 1212 1228 1536 - tri 2443 1225 1226 1403 - tri 2444 1225 1403 1407 - tri 2445 1228 1405 1226 - tri 2446 1226 1405 1403 - tri 2447 1341 1287 1413 - tri 2448 1287 1225 1413 - tri 2449 1225 1407 1413 - tri 2450 1240 1537 1238 - tri 2451 1243 1337 1242 - tri 2452 1366 1237 1538 - tri 2453 1237 1238 1227 - tri 2454 1238 1536 1227 - tri 2455 1537 1536 1238 - tri 2456 1532 1530 1303 - tri 2457 1296 1532 1303 - tri 2458 1296 1297 1532 - tri 2459 1529 1452 1445 - tri 2460 1531 1445 1334 - tri 2461 1334 1445 1330 - tri 2462 1332 1425 1333 - tri 2463 1436 1425 1332 - tri 2464 1525 1515 1528 - tri 2465 1524 1522 1445 - tri 2466 1531 1524 1445 - tri 2467 1302 1334 1335 - tri 2468 1345 1322 1431 - tri 2469 1322 1460 1431 - tri 2470 1322 1333 1460 - tri 2471 1350 1349 1539 - tri 2472 1539 1448 1449 - tri 2473 1539 1349 1448 - tri 2474 1352 1347 1348 - tri 2475 1352 1325 1347 - tri 2476 1352 1327 1325 - tri 2477 1349 1345 1419 - tri 2478 1420 1349 1419 - tri 2479 1450 1420 1418 - tri 2480 1448 1349 1420 - tri 2481 1448 1420 1450 - tri 2482 1339 1385 1404 - tri 2483 1339 1404 1405 - tri 2484 1340 1386 1385 - tri 2485 1340 1385 1339 - tri 2486 1537 1212 1536 - tri 2487 1169 1540 1174 - tri 2488 1211 1339 1228 - tri 2489 1228 1339 1405 - tri 2490 1233 1307 1230 - tri 2491 1229 1306 1209 - tri 2492 1229 1542 1541 - tri 2493 1477 1139 1476 - tri 2494 1477 1485 1139 - tri 2495 1279 1280 1215 - tri 2496 1215 1280 1214 - tri 2497 1351 1350 1539 - tri 2498 1351 1539 1505 - tri 2499 1496 1505 1539 - tri 2500 1496 1539 1449 - tri 2501 1305 1304 1351 - tri 2502 1305 1351 1308 - tri 2503 1308 1351 1505 - tri 2504 1309 1308 1498 - tri 2505 1498 1308 1505 - tri 2506 1317 1309 1527 - tri 2507 1320 1317 1527 - tri 2508 1320 1527 1511 - tri 2509 1512 1320 1511 - tri 2510 1396 1416 1526 - tri 2511 1396 1526 1395 - tri 2512 1395 1526 1400 - tri 2513 1526 1416 1320 - tri 2514 1527 1498 1499 - tri 2515 1527 1309 1498 - tri 2516 1296 1303 1301 - tri 2517 1311 1296 1301 - tri 2518 1307 1210 1306 - tri 2519 1306 1210 1209 - tri 2520 1542 1209 1207 - tri 2521 1229 1209 1542 - tri 2522 1212 1207 1208 - tri 2523 1542 1207 1212 - tri 2524 1232 1229 1541 - tri 2525 1232 1541 1543 - tri 2526 1338 1178 1234 - tri 2527 1182 1178 1338 - tri 2528 1179 1195 1236 - tri 2529 1179 1236 1234 - tri 2530 1166 1540 1169 - tri 2531 1166 1172 1540 - tri 2532 1172 1243 1540 - tri 2533 1540 1243 1241 - tri 2534 1540 1241 1174 - tri 2535 1543 1212 1537 - tri 2536 1232 1543 1240 - tri 2537 1240 1543 1537 - tri 2538 1469 1494 1483 - tri 2539 1494 1475 1490 - tri 2540 1469 1475 1494 - tri 2541 1494 1490 1489 - tri 2542 1475 1476 1490 - tri 2543 1490 1476 1486 - tri 2544 1486 1137 1493 - tri 2545 1490 1486 1493 - tri 2546 1278 1544 1276 - tri 2547 1545 1544 1278 - tri 2548 1546 1272 1276 - tri 2549 1546 1276 1544 - tri 2550 1547 1272 1546 - tri 2551 1366 1275 1274 - tri 2552 1538 1237 1227 - tri 2553 1366 1538 1275 - tri 2554 1538 1227 1275 - tri 2555 1246 1369 1250 - tri 2556 1224 1343 1379 - tri 2557 1217 1343 1224 - tri 2558 1224 1379 1213 - tri 2559 1548 1222 1221 - tri 2560 1548 1285 1222 - tri 2561 1549 1285 1548 - tri 2562 1549 1284 1285 - tri 2563 1541 1542 1212 - tri 2564 1543 1541 1212 - tri 2565 1173 1182 1365 - tri 2566 1369 1184 1196 - tri 2567 1246 1184 1369 - tri 2568 1264 1248 1249 - tri 2569 1271 1270 1248 - tri 2570 1264 1271 1248 - tri 2571 1550 1548 1221 - tri 2572 1233 1223 1307 - tri 2573 1550 1221 1223 - tri 2574 1550 1223 1233 - tri 2575 1369 1196 1244 - tri 2576 1369 1244 1368 - tri 2577 1274 1272 1547 - tri 2578 1341 1273 1287 - tri 2579 1278 1277 1289 - tri 2580 1252 1373 1371 - tri 2581 1373 1250 1372 - tri 2582 1249 1551 1253 - tri 2583 1253 1551 1252 - tri 2584 1551 1373 1252 - tri 2585 1551 1250 1373 - tri 2586 1249 1250 1551 - tri 2587 1371 1372 1262 - tri 2588 1554 1553 1552 - tri 2589 1554 1555 1553 - tri 2590 1554 1366 1555 - tri 2591 1555 1274 1547 - tri 2592 1366 1274 1555 - tri 2593 1557 1556 1278 - tri 2594 1556 1545 1278 - tri 2595 1558 1286 1549 - tri 2596 1549 1286 1284 - tri 2597 1557 1553 1556 - tri 2598 1552 1553 1557 - tri 2599 1545 1546 1544 - tri 2600 1553 1545 1556 - tri 2601 1553 1546 1545 - tri 2602 1553 1555 1547 - tri 2603 1553 1547 1546 - tri 2604 1438 1442 1424 - tri 2605 1442 1423 1424 - tri 2606 1333 1432 1460 - tri 2607 1497 1452 1529 - tri 2608 1508 1497 1529 - tri 2609 1466 1143 1139 - tri 2610 1485 1466 1139 - tri 2611 1135 1156 1153 - tri 2612 1135 1153 1154 - tri 2613 1048 1559 1118 - tri 2614 1048 1491 1559 - tri 2615 1152 1560 1559 - tri 2616 1155 1152 1559 - tri 2617 1562 697 1561 - tri 2618 1564 1563 1156 - tri 2619 1564 1565 1563 - tri 2620 1142 1140 1164 - tri 2621 1144 1142 1164 - tri 2622 1138 1144 1164 - tri 2623 1164 1156 1135 - tri 2624 1140 1564 1164 - tri 2625 1164 1564 1156 - tri 2626 1562 1566 697 - tri 2627 1568 1567 1564 - tri 2628 1568 1160 1567 - tri 2629 1567 1565 1564 - tri 2630 1567 1162 1565 - tri 2631 1141 1568 1140 - tri 2632 1140 1568 1564 - tri 2633 1473 1478 1569 - tri 2634 1569 1159 1141 - tri 2635 1478 1159 1569 - tri 2636 1482 1479 1487 - tri 2637 1141 1163 1568 - tri 2638 1141 1159 1163 - tri 2639 1163 1160 1568 - tri 2640 1163 1157 1160 - tri 2641 1567 1160 1162 - tri 2642 1135 1154 1155 - tri 2643 1156 1563 1152 - tri 2644 1152 1563 1560 - tri 2645 1040 1570 1479 - tri 2646 1040 694 1570 - tri 2647 1487 1479 1147 - tri 2648 1487 1147 1159 - tri 2649 1570 1146 1479 - tri 2650 1479 1146 1147 - tri 2651 1147 1145 1159 - tri 2652 1159 1145 1158 - tri 2653 1570 694 1148 - tri 2654 1570 1148 1146 - tri 2655 1571 1151 697 - tri 2656 1566 1571 697 - tri 2657 1561 697 1572 - tri 2658 1573 1572 697 - tri 2659 1133 1573 697 - tri 2660 1569 1141 1143 - tri 2661 1473 1569 1143 - tri 2662 1423 1440 1422 - tri 2663 1440 1435 1422 - tri 2664 1301 1302 1574 - tri 2665 1301 1574 1304 - tri 2666 1574 1328 1327 - tri 2667 1574 1335 1328 - tri 2668 1574 1327 1352 - tri 2669 1304 1574 1352 - tri 2670 1302 1335 1574 - tri 2671 1137 1135 1493 - tri 2672 1493 1135 1491 - tri 2673 1135 1155 1559 - tri 2674 1491 1135 1559 - tri 2675 1218 1215 1343 - tri 2676 1218 1279 1215 - tri 2677 1218 1282 1279 - tri 2678 1224 1213 1210 - tri 2679 1220 1224 1210 - tri 2680 1223 1220 1307 - tri 2681 1307 1220 1210 - tri 2682 1513 1510 1500 - tri 2683 1500 1510 1499 - tri 2684 1400 1526 1514 - tri 2685 1400 1514 1516 - - numweights 2267 - weight 0 19 1 ( 4.8445672989 3.5474803448 8.2679128647 ) - weight 1 19 1 ( 4.2299785614 5.4739603996 9.2519369125 ) - weight 2 19 1 ( 6.3439702988 3.2810635567 6.6381435394 ) - weight 3 19 1 ( 5.2712097168 3.0016710758 7.2553672791 ) - weight 4 19 1 ( 1.5261673927 6.6848831177 10.2535734177 ) - weight 5 19 0.6624171734 ( 1.2869739532 11.3651981354 7.446914196 ) - weight 6 23 0.3375828564 ( 7.8158621788 -1.0705963373 -0.3087681532 ) - weight 7 19 0.5241057873 ( 4.5647926331 8.9029188156 8.2703351974 ) - weight 8 23 0.4758941829 ( 8.2075233459 2.6028161049 -2.2677423954 ) - weight 9 19 0.6397638321 ( 3.3002691269 10.7812709808 7.7936582565 ) - weight 10 23 0.3602361977 ( 7.9797911644 1.0295708179 -0.5862300992 ) - weight 11 19 0.8934609294 ( 0.90167588 11.8251190186 6.9294381142 ) - weight 12 23 0.1065390483 ( 7.3665881157 -1.5613677502 0.1214177832 ) - weight 13 19 0.678021431 ( 5.1026115417 8.1662931442 8.1946954727 ) - weight 14 23 0.3219785392 ( 8.0331163406 3.2407445908 -2.9003703594 ) - weight 15 19 1 ( 7.6583595276 4.3135032654 5.1793165207 ) - weight 16 23 0.4493831694 ( 0.491373539 6.3412637711 4.3959093094 ) - weight 17 25 0.5506168008 ( 1.3399153948 -0.5861233473 4.4470949173 ) - weight 18 25 1 ( -3.6165471077 5.6419634819 1.6923339367 ) - weight 19 23 0.0885743201 ( -4.2962312698 9.779548645 -0.5904235244 ) - weight 20 25 0.9114256501 ( -3.5745098591 5.0131325722 2.4214498997 ) - weight 21 23 0.4803135693 ( 4.0166683197 5.7046632767 3.3776674271 ) - weight 22 25 0.5196864605 ( 4.5419774055 -0.9494268298 2.5803887844 ) - weight 23 23 0.4583046138 ( 2.3974432945 6.0952367783 4.0829110146 ) - weight 24 25 0.5416953564 ( 3.1209750175 -0.7991139293 3.6894264221 ) - weight 25 23 0.2154574394 ( 4.496442318 8.6312913895 -1.5345004797 ) - weight 26 25 0.7845425606 ( 4.7137260437 3.7988674641 -0.6365868449 ) - weight 27 19 0.0606484413 ( 7.7586784363 12.1194076538 5.3920497894 ) - weight 28 23 0.5090739727 ( 5.4229393005 5.0274662971 1.6307696104 ) - weight 29 25 0.430277586 ( 5.5577921867 -0.8837391734 0.4704953134 ) - weight 30 23 0.1631084234 ( 3.327133894 9.908621788 -0.6240836978 ) - weight 31 25 0.8368915915 ( 3.8939990997 4.6222696304 0.9375066757 ) - weight 32 25 1 ( 1.886956811 6.1845235825 2.7989616394 ) - weight 33 25 1 ( 3.2307040691 6.061630249 1.4529546499 ) - weight 34 25 1 ( -2.7161197662 5.9265975952 3.3653492928 ) - weight 35 25 1 ( -3.5655488968 5.6577939987 2.3454973698 ) - weight 36 25 1 ( -0.3795105517 6.1537222862 3.696824789 ) - weight 37 19 0.0933828354 ( 8.6668891907 12.2293567657 -3.6217293739 ) - weight 38 23 0.3796480298 ( -3.5861420631 5.2071304321 2.5738055706 ) - weight 39 25 0.5269691944 ( -3.085154295 -0.5215893388 3.163721323 ) - weight 40 19 0.0939339846 ( 10.9819784164 8.5530757904 -3.6995155811 ) - weight 41 23 0.1847647876 ( -4.1348781586 8.0506134033 -0.6656733751 ) - weight 42 25 0.7213012576 ( -3.6830563545 3.4869425297 1.5969039202 ) - weight 43 25 1 ( 3.7122447491 5.9261064529 0.6576906443 ) - weight 44 25 1 ( 3.6219484806 5.8819513321 -0.239556402 ) - weight 45 19 0.3753109574 ( 5.8264608383 9.1134996414 8.2740182877 ) - weight 46 23 0.6246890426 ( 8.148475647 3.813097477 -1.8579905033 ) - weight 47 19 0.2997034788 ( 6.5805830956 9.369559288 7.570084095 ) - weight 48 23 0.7002965212 ( 7.4226565361 4.4616756439 -1.4309974909 ) - weight 49 19 0.2185793072 ( 5.4837379456 10.5651903152 8.2010650635 ) - weight 50 23 0.7814207077 ( 8.2253379822 3.2450652122 -0.4789989889 ) - weight 51 19 0.153814733 ( 4.833984375 11.7926425934 7.4382410049 ) - weight 52 23 0.846185267 ( 7.6165089607 2.355963707 0.6827002168 ) - weight 53 19 0.0944913626 ( 4.4890122414 12.7021245956 6.1874475479 ) - weight 54 23 0.9055086374 ( 6.4751067162 1.778511405 1.6177926064 ) - weight 55 19 0.1639066339 ( 3.7668144703 12.2644634247 6.1635694504 ) - weight 56 23 0.8360933661 ( 6.4594502449 1.1331586838 1.0728507042 ) - weight 57 19 0.503538847 ( 6.4761629105 8.0272321701 7.5324897766 ) - weight 58 23 0.4964611828 ( 7.274266243 4.5638222694 -2.7658028603 ) - weight 59 19 0.0660847425 ( 4.3117575645 13.6960668564 4.4811558723 ) - weight 60 23 0.9339152575 ( 4.8775258064 1.317899704 2.6977670193 ) - weight 61 19 0.8687992096 ( 7.8084440231 4.1107563972 2.4757163525 ) - weight 62 23 0.1312008202 ( 1.8182581663 6.0910964012 -6.0191278458 ) - weight 63 19 0.7283416986 ( 8.1711883545 5.3612446785 2.4001698494 ) - weight 64 23 0.2716583312 ( 1.8295024633 6.2488369942 -4.7245225906 ) - weight 65 25 1 ( 3.3734426498 5.148765564 -1.4973394871 ) - weight 66 25 1 ( -3.1138911247 4.8583040237 1.1216371059 ) - weight 67 25 1 ( -2.4671490192 5.3845477104 -1.5190695524 ) - weight 68 25 1 ( 1.9218794107 5.3287730217 -2.6917791367 ) - weight 69 25 1 ( 2.8538711071 5.1842737198 -2.2744576931 ) - weight 70 25 1 ( 1.8252305984 4.6282587051 -2.8486630917 ) - weight 71 25 1 ( -0.078470327 4.8245506287 -2.6389036179 ) - weight 72 25 1 ( 0.002380182 5.4974660873 -2.6232230663 ) - weight 73 25 1 ( -2.4169421196 4.5840411186 -1.4788062572 ) - weight 74 25 1 ( -3.0799603462 3.8839583397 0.9748175144 ) - weight 75 25 1 ( 2.8685896397 4.4948186874 -2.375238657 ) - weight 76 19 0.1077406704 ( 9.7189722061 6.0726656914 3.0613014698 ) - weight 77 23 0.0546411723 ( 2.4495227337 7.7142386436 -3.826177597 ) - weight 78 25 0.8376181722 ( 2.2365813255 4.1254668236 -2.6464960575 ) - weight 79 19 0.0942282602 ( 9.9062108994 6.6120066643 3.8263254166 ) - weight 80 23 0.0630056411 ( 3.2452657223 7.8743395805 -3.3238143921 ) - weight 81 25 0.8427661061 ( 3.1129057407 3.9934933186 -2.29174757 ) - weight 82 25 1 ( -1.4490329027 4.7897987366 -2.1533586979 ) - weight 83 19 0.3565033078 ( 8.9153518677 6.3292460442 -1.9020335674 ) - weight 84 23 0.1718751937 ( -2.4101467133 6.4987816811 -3.3235723972 ) - weight 85 25 0.4716215134 ( -2.6201686859 3.148273468 -1.750166297 ) - weight 86 25 1 ( -3.0170576572 4.3585090637 -0.5905144215 ) - weight 87 19 0.1221254915 ( 9.9867343903 6.4475312233 -2.0741710663 ) - weight 88 25 0.8778744936 ( -2.6488981247 3.9478452206 -1.0076416731 ) - weight 89 19 0.2911888063 ( 8.6426649094 6.5966320038 2.716303587 ) - weight 90 23 0.1886390001 ( 2.2217822075 6.5463280678 -3.4572310448 ) - weight 91 25 0.5201721787 ( 1.8963057995 2.9329230785 -2.7650425434 ) - weight 92 19 0.1986566335 ( 8.8203716278 8.0499620438 4.3790659904 ) - weight 93 23 0.1710185856 ( 3.990717411 6.6249809265 -2.1256115437 ) - weight 94 25 0.6303247809 ( 3.8353579044 2.2967717648 -1.9025367498 ) - weight 95 19 0.3174703121 ( 8.6748132706 5.9642591476 0.7578168511 ) - weight 96 23 0.1770481765 ( 0.2173826098 6.5243172646 -3.9246678352 ) - weight 97 25 0.5054814816 ( -0.1363312453 3.2558376789 -2.7917320728 ) - weight 98 19 0.1330608726 ( 9.8786287308 5.8036046028 -0.5175085068 ) - weight 99 23 0.050177414 ( -1.1419222355 7.6361026764 -3.7917792797 ) - weight 100 25 0.8167617321 ( -1.2817139626 4.2859354019 -1.9382488728 ) - weight 101 19 0.2538379729 ( 9.6596431732 7.2127723694 -2.5370461941 ) - weight 102 23 0.091649361 ( -3.0117850304 7.0458307266 -2.2859797478 ) - weight 103 25 0.6545126438 ( -2.9736950397 3.2229673862 -0.4823849797 ) - weight 104 19 0.8944743276 ( 8.188873291 3.7395002842 0.732164681 ) - weight 105 23 0.1055256426 ( 0.0280118566 6.3883032799 -6.190056324 ) - weight 106 19 0.7718275189 ( 8.0036716461 4.7868037224 0.4135006666 ) - weight 107 23 0.2281724811 ( -0.1849840432 6.0190229416 -5.1648955345 ) - weight 108 19 0.712061286 ( 8.5126562119 5.3174443245 0.171448797 ) - weight 109 23 0.2879386842 ( -0.4118054211 6.4193949699 -4.5424098969 ) - weight 110 19 0.2063084394 ( 8.6430654526 8.799238205 4.9758358002 ) - weight 111 23 0.2971664369 ( 4.6610741615 6.3805031776 -1.462408185 ) - weight 112 25 0.4965251684 ( 4.5532469749 1.7403377295 -1.5503969193 ) - weight 113 19 0.2893922627 ( 8.6493520737 8.6632795334 -3.2549357414 ) - weight 114 23 0.1666120589 ( -3.5331833363 5.7705688477 -0.9661778808 ) - weight 115 25 0.543995738 ( -3.4757926464 1.53619349 0.254308641 ) - weight 116 17 0.5207475424 ( 2.5561676025 4.1699666977 7.7956185341 ) - weight 117 19 0.4792524576 ( 2.0546736717 -1.7559373379 8.9840517044 ) - weight 118 17 0.3675586879 ( 4.9814009666 5.9601583481 6.7253789902 ) - weight 119 19 0.6324413419 ( 4.5602960587 -0.398825258 7.5307588577 ) - weight 120 17 0.1635299921 ( 5.3350086212 7.1664199829 6.5049405098 ) - weight 121 19 0.8364700079 ( 4.9422864914 0.6719723344 6.9509534836 ) - weight 122 17 0.3534659743 ( 2.8127257824 5.5674381256 8.106959343 ) - weight 123 19 0.6465340257 ( 2.3127911091 -0.3318959475 8.8385772705 ) - weight 124 17 0.4341910779 ( 6.0124669075 6.394774437 5.2267303467 ) - weight 125 19 0.5658089519 ( 5.6791701317 -0.4699434638 6.033762455 ) - weight 126 17 0.8026441336 ( 2.3520169258 2.8471312523 7.4860520363 ) - weight 127 19 0.1973558664 ( 1.8498107195 -3.1085584164 9.1099481583 ) - weight 128 19 0.8543192148 ( 7.5472068787 3.7632319927 -1.631722331 ) - weight 129 23 0.1456807554 ( -2.2784793377 5.569653511 -6.0892009735 ) - weight 130 19 0.7742658257 ( 7.0193519592 4.8565526009 -1.5381404161 ) - weight 131 23 0.2257341892 ( -2.0555922985 4.8876819611 -5.1053438187 ) - weight 132 19 0.7471264005 ( 7.834508419 5.3834090233 -1.4033900499 ) - weight 133 23 0.2528736293 ( -1.9278792143 5.6193580627 -4.4661602974 ) - weight 134 17 0.3875789344 ( 4.6872487068 9.2957649231 -1.7631657124 ) - weight 135 19 0.6124210358 ( 4.7857022285 -0.0062151998 -1.5831445456 ) - weight 136 17 0.3116692901 ( 2.3825845718 9.868730545 -2.7496712208 ) - weight 137 19 0.6883307099 ( 2.5477266312 0.203197211 -2.8323721886 ) - weight 138 19 0.4397973418 ( 8.4015016556 7.4504122734 -3.0229344368 ) - weight 139 23 0.2029377371 ( -3.3929941654 5.7322721481 -2.2172505856 ) - weight 140 25 0.3572649062 ( -3.5301060677 2.042522192 -0.897639215 ) - weight 141 19 0.1024227738 ( 3.6739826202 13.4256591797 4.613465786 ) - weight 142 23 0.8975772262 ( 5.026368618 0.7418816686 2.3190422058 ) - weight 143 19 0.0551941991 ( 5.1156005859 13.530828476 3.62109375 ) - weight 144 23 0.9448058009 ( 3.9563531876 2.0686116219 2.7301135063 ) - weight 145 19 0.0648210049 ( 4.1190242767 13.771645546 3.4053151608 ) - weight 146 23 0.9351789951 ( 3.8270995617 1.0330859423 2.8233735561 ) - weight 147 19 0.1818646193 ( 3.029309988 14.1647481918 2.9681212902 ) - weight 148 23 0.8181353807 ( 3.4970943928 -0.1348978132 3.068436861 ) - weight 149 19 0.2278274298 ( 2.8549966812 14.738781929 1.0170263052 ) - weight 150 23 0.7721725702 ( 1.6191431284 -0.5465283394 3.7543888092 ) - weight 151 19 0.828371644 ( 0.7134188414 14.4985723495 -1.6041424274 ) - weight 152 23 0.171628356 ( -0.8697458506 -2.8214719296 3.3740661144 ) - weight 153 19 0.6900701523 ( 1.3182066679 13.9398860931 -1.8880398273 ) - weight 154 23 0.3099298179 ( -1.2398753166 -2.161267519 2.9432182312 ) - weight 155 19 0.2685622573 ( 2.8149504662 14.3941507339 2.5207278728 ) - weight 156 23 0.7314377427 ( 3.0862698555 -0.4161843061 3.2939078808 ) - weight 157 19 0.7010427713 ( 1.5317583084 14.9345188141 -0.8916427493 ) - weight 158 23 0.2989572287 ( -0.1758906692 -2.027854681 3.880150795 ) - weight 159 19 0.0728244781 ( 6.4640574455 14.5801448822 -0.5603785515 ) - weight 160 23 0.9271755219 ( -0.1950310022 2.9104743004 4.298995018 ) - weight 161 19 0.0524587035 ( 6.9352092743 15.0006475449 0.747456491 ) - weight 162 23 0.9475412965 ( 1.1116108894 3.4106276035 4.6885743141 ) - weight 163 19 0.0521270633 ( 6.3127293587 15.0361042023 0.7685776353 ) - weight 164 23 0.9478729367 ( 1.1757684946 2.7936937809 4.6217856407 ) - weight 165 19 0.2938108742 ( 7.1230487823 9.2287311554 6.1649975777 ) - weight 166 23 0.5755110383 ( 5.9786524773 4.9089846611 -1.3749958277 ) - weight 167 25 0.1306780875 ( 5.6374468803 0.2940681577 -2.3515439034 ) - weight 168 19 0.2593457699 ( 6.9671287537 10.1320753098 6.8245491982 ) - weight 169 23 0.7406542301 ( 6.7235560417 4.6665682793 -0.5615452528 ) - weight 170 23 1 ( 3.477868557 3.2198045254 4.4403142929 ) - weight 171 19 0.0650603771 ( 6.0271134377 13.6074008942 5.0311646461 ) - weight 172 23 0.9349396229 ( 5.3061232567 3.0636572838 2.844230175 ) - weight 173 23 1 ( 3.2162761688 2.6080834866 4.0571770668 ) - weight 174 19 0.0552856363 ( 5.5632991791 13.6429634094 4.9607806206 ) - weight 175 23 0.9447143674 ( 5.2691192627 2.5958921909 2.8100442886 ) - weight 176 19 0.0963922739 ( 5.8137106895 12.6753759384 6.065451622 ) - weight 177 23 0.9036077261 ( 6.266254425 3.077899456 1.8137414455 ) - weight 178 23 1 ( 2.397796154 3.5114731789 4.6469173431 ) - weight 179 19 1 ( 1.4808238745 2.1779508591 10.1789779663 ) - weight 180 19 1 ( 2.3127348423 1.4412772655 9.6336326599 ) - weight 181 25 1 ( -3.0754208565 5.0565981865 -0.2069936842 ) - weight 182 19 0.0690433979 ( 4.3752551079 14.1672096252 1.5676848888 ) - weight 183 23 0.9309566021 ( 2.0185832977 1.0819216967 3.3942451477 ) - weight 184 19 0.0836250186 ( 3.9739565849 14.5186100006 1.2882270813 ) - weight 185 23 0.9163749814 ( 1.797426343 0.6106253266 3.6968817711 ) - weight 186 19 0.2235984355 ( 4.8817996979 15.4476041794 -2.8250007629 ) - weight 187 23 0.7764015794 ( -2.2683217525 1.042448163 5.0713181496 ) - weight 188 19 0.2618145943 ( 4.1020479202 15.2770824432 -2.4890949726 ) - weight 189 23 0.7381854057 ( -1.899195075 0.3268889189 4.7525014877 ) - weight 190 19 0.1914669871 ( 5.7272629738 14.3414964676 -2.8975431919 ) - weight 191 23 0.8085330129 ( -2.4918513298 2.0408396721 4.1243252754 ) - weight 192 19 0.1809172034 ( 5.3844356537 15.1597948074 -2.7975587845 ) - weight 193 23 0.8190827966 ( -2.2986278534 1.5841926336 4.8668060303 ) - weight 194 19 0.4753880501 ( 4.0871653557 15.2931070328 -3.9203503132 ) - weight 195 23 0.5246119499 ( -3.3195939064 0.1989488304 4.8752574921 ) - weight 196 19 0.3253329694 ( 5.1115655899 14.5828742981 -4.5197587013 ) - weight 197 23 0.6746670008 ( -4.0436530113 1.271474123 4.3868465424 ) - weight 198 19 0.3729265034 ( 4.8953895569 15.1236467361 -4.5760211945 ) - weight 199 23 0.6270734668 ( -4.0382404327 0.9704526663 4.8885331154 ) - weight 200 19 0.60125494 ( 3.8166801929 15.3820028305 -4.9813656807 ) - weight 201 23 0.39874506 ( -4.3491120338 -0.1633572578 5.0003371239 ) - weight 202 19 0.5448612571 ( 3.7978127003 14.657784462 -5.2947568893 ) - weight 203 23 0.4551387429 ( -4.722951889 -0.0940335914 4.3085999489 ) - weight 204 19 0.8841800094 ( 0.7393733263 15.457531929 -4.0117521286 ) - weight 205 23 0.1158199832 ( -3.1806263924 -3.1308181286 4.5058784485 ) - weight 206 19 0.931039691 ( 1.0313379765 15.623301506 -4.6714787483 ) - weight 207 23 0.0689603239 ( -3.8406834602 -2.9200105667 4.7663521767 ) - weight 208 17 0.7990359664 ( 6.8603596687 5.1960568428 4.8272752762 ) - weight 209 19 0.2009640187 ( 6.5313405991 -1.729113698 6.0946350098 ) - weight 210 17 1 ( 7.3790307045 2.1801087856 3.7680120468 ) - weight 211 17 0.7825206518 ( 5.6728076935 4.8391032219 6.0624523163 ) - weight 212 19 0.2174793631 ( 5.2719922066 -1.6710170507 7.3087291718 ) - weight 213 17 1 ( 5.8182816505 1.7506700754 5.5419921875 ) - weight 214 17 1 ( 6.1118283272 3.9593486786 -3.132007122 ) - weight 215 19 0.9086368084 ( 1.9931775331 6.2422609329 -10.1819114685 ) - weight 216 23 0.0913631767 ( -10.2031297684 -0.9463486075 -3.8891580105 ) - weight 217 19 0.6714816093 ( 6.9141602516 9.6157112122 -7.1801877022 ) - weight 218 23 0.3285184205 ( -7.2399559021 3.6102011204 -0.0079161711 ) - weight 219 19 0.5469177961 ( 7.6492395401 9.8798809052 -5.7171139717 ) - weight 220 23 0.3952530026 ( -5.8096904755 4.4065260887 0.25838992 ) - weight 221 25 0.0578292273 ( -5.7213540077 -0.068194218 1.2166286707 ) - weight 222 19 0.7633374333 ( 6.6618061066 3.9670217037 -5.9489073753 ) - weight 223 23 0.2366625518 ( -6.4952015877 4.3318490982 -5.701069355 ) - weight 224 19 0.7496048212 ( 7.3524150848 4.209177494 -4.6466941833 ) - weight 225 23 0.2503952086 ( -5.2239112854 5.0753321648 -5.4512805939 ) - weight 226 19 0.5158829689 ( 6.3470988274 10.777718544 -5.4962935448 ) - weight 227 23 0.4841170013 ( -5.427646637 3.0020909309 0.915694356 ) - weight 228 19 0.7992503047 ( 2.2913517952 7.9392442703 9.6059703827 ) - weight 229 23 0.2007496953 ( 9.596985817 0.6163668036 -3.6835591793 ) - weight 230 19 0.8831704855 ( 5.3501701355 6.6821045876 8.4692411423 ) - weight 231 23 0.1168295294 ( 8.1599245071 3.73568964 -4.3420443535 ) - weight 232 19 0.8982713223 ( 7.8337192535 5.579726696 5.3616108894 ) - weight 233 23 0.1017286777 ( 4.8142466545 6.1118860245 -4.7900958061 ) - weight 234 19 1 ( 6.5046005249 5.7227888107 8.5231628418 ) - weight 235 19 1 ( 6.9616732597 5.5851173401 8.0614538193 ) - weight 236 19 1 ( 7.2121248245 5.1236858368 7.6837615967 ) - weight 237 19 1 ( 7.0974140167 4.4310698509 7.5746741295 ) - weight 238 19 1 ( 6.0029654503 3.8739600182 8.402130127 ) - weight 239 19 1 ( 5.6446566582 4.3226547241 8.8684082031 ) - weight 240 19 1 ( 5.6811704636 4.9602236748 9.029168129 ) - weight 241 19 1 ( 6.0154910088 5.4840707779 8.8925352097 ) - weight 242 19 0.9401356578 ( 5.9841022491 6.0089740753 7.9647769928 ) - weight 243 23 0.0598643646 ( 7.5586233139 4.4252481461 -4.863969326 ) - weight 244 19 1 ( 5.4314098358 5.7392077446 8.3821697235 ) - weight 245 19 1 ( 5.0536260605 5.1472196579 8.5357885361 ) - weight 246 19 1 ( 4.9950547218 4.4595007896 8.3720092773 ) - weight 247 19 1 ( 5.4840283394 3.805385828 7.7777266502 ) - weight 248 19 1 ( 6.2286338806 3.9039833546 7.1470522881 ) - weight 249 19 1 ( 6.7250328064 4.6438360214 6.8474235535 ) - weight 250 19 1 ( 6.7836046219 5.3319926262 7.0162529945 ) - weight 251 19 1 ( 2.0121905804 4.7541136742 9.6924037933 ) - weight 252 19 1 ( 4.2565402985 3.2908327579 8.0975084305 ) - weight 253 17 0.068359971 ( 3.2311627865 6.7325158119 8.4429655075 ) - weight 254 19 0.8091581464 ( 2.7279317379 0.881221354 8.801150322 ) - weight 255 20 0.0685596243 ( -1.2967512608 -5.2521858215 1.3622517586 ) - weight 256 18 0.053922236 ( 2.8096885681 6.8139839172 0.3526515961 ) - weight 257 19 1 ( 7.0404019356 3.6147813797 4.3325209618 ) - weight 258 19 0.9084361196 ( 7.4340929985 4.5934705734 4.2233901024 ) - weight 259 23 0.0915638879 ( 3.6219871044 5.7829327583 -5.7378592491 ) - weight 260 17 0.920759201 ( 4.7907147408 1.5430752039 5.9116821289 ) - weight 261 18 0.0792407915 ( 4.4359230995 1.1675415039 -0.76222229 ) - weight 262 17 0.5972013474 ( 4.8866963387 4.7575535774 6.3230757713 ) - weight 263 19 0.4027986228 ( 4.4715285301 -1.6673539877 7.5363049507 ) - weight 264 17 0.5359256268 ( 6.3491840363 5.7720284462 4.4632382393 ) - weight 265 19 0.464074403 ( 6.0492563248 -1.3054023981 5.5346078873 ) - weight 266 17 0.3884032667 ( 7.4084448814 6.9302182198 1.6351264715 ) - weight 267 19 0.6115967631 ( 7.2803573608 -1.1244336367 2.5490939617 ) - weight 268 17 0.3772357106 ( 6.8457446098 7.7032051086 -0.0648975447 ) - weight 269 19 0.622764349 ( 6.8239927292 -0.9490959644 0.6609174609 ) - weight 270 17 0.8583768606 ( 3.0720031261 7.0218448639 -4.9315152168 ) - weight 271 19 0.1416231394 ( 3.3181934357 -3.1949262619 -3.9276509285 ) - weight 272 17 1 ( 2.9660339355 4.315284729 -4.7418379784 ) - weight 273 17 0.6433618069 ( 8.1983203888 6.8182373047 1.1847993135 ) - weight 274 19 0.3566381633 ( 8.0924711227 -1.3727740049 2.2055308819 ) - weight 275 17 1 ( 9.1779136658 5.1911296844 0.8187640309 ) - weight 276 17 0.9326625466 ( 7.0927095413 3.6762866974 5.333612442 ) - weight 277 19 0.067337513 ( 6.714076519 -3.0004570484 7.079703331 ) - weight 278 17 1 ( 8.4234676361 3.1220083237 0.0751102418 ) - weight 279 17 0.7854495049 ( 7.34040308 7.5733742714 -4.3935790062 ) - weight 280 19 0.2145504951 ( 7.5572118759 -2.4769201279 -3.3549473286 ) - weight 281 17 0.292829901 ( 6.0339517593 8.86145401 -0.499119252 ) - weight 282 19 0.7071700692 ( 6.0537514687 0.0009032384 -0.1717445552 ) - weight 283 17 0.8891180754 ( 5.374671936 3.4211456776 6.4101858139 ) - weight 284 19 0.1108819246 ( 4.9353618622 -2.9003310204 8.080657959 ) - weight 285 17 0.2254327387 ( 6.9433574677 8.3645305634 1.1053292751 ) - weight 286 19 0.7745672464 ( 6.8653926849 0.0572945476 1.5563365221 ) - weight 287 17 0.3170430362 ( 6.8235902786 7.3393740654 3.3601751328 ) - weight 288 19 0.6829569936 ( 6.6060156822 -0.1795395911 4.0111794472 ) - weight 289 19 0.2461065054 ( 4.4691781998 10.6110486984 8.171462059 ) - weight 290 23 0.7538934946 ( 8.265212059 2.2364356518 -0.5947027802 ) - weight 291 19 0.1607670188 ( 6.0021958351 10.787314415 7.6599025726 ) - weight 292 23 0.8392329812 ( 7.6735105515 3.6793954372 -0.1357224137 ) - weight 293 19 0.3230723143 ( 4.1400732994 10.2026252747 7.7948536873 ) - weight 294 23 0.6769276857 ( 7.8761901855 1.9464036226 -1.0207275152 ) - weight 295 19 0.4277999699 ( 4.8142085075 8.959028244 7.8816661835 ) - weight 296 23 0.5722000003 ( 7.8100342751 2.8096857071 -2.1427326202 ) - weight 297 19 0.329929769 ( 3.6806457043 11.2410421371 6.7770256996 ) - weight 298 23 0.670070231 ( 6.9850440025 1.2542899847 0.0050385771 ) - weight 299 17 0.916015327 ( 2.5002675056 1.1379480362 7.2863836288 ) - weight 300 18 0.0839846432 ( 2.0670580864 1.1055641174 0.5357451439 ) - weight 301 17 0.0513219014 ( 7.5852651596 10.3554172516 1.3169623613 ) - weight 302 19 0.9486780763 ( 7.5219869614 2.0120172501 1.1459642649 ) - weight 303 17 0.0682639182 ( 6.9223814011 10.8550014496 -1.0689799786 ) - weight 304 19 0.931736052 ( 7.0000386238 1.705270052 -1.3066254854 ) - weight 305 17 0.1157888323 ( 5.0958743095 11.2580814362 -2.0409436226 ) - weight 306 19 0.884211123 ( 5.2362713814 1.7611728907 -2.459584713 ) - weight 307 19 0.4405724406 ( 7.5869636536 8.1371355057 5.7207517624 ) - weight 308 23 0.4985500574 ( 5.4114480019 5.5005679131 -2.3406357765 ) - weight 309 25 0.0608774908 ( 5.0267472267 1.287288785 -2.8462269306 ) - weight 310 19 0.5449929833 ( 7.6154241562 7.7501325607 6.0671830177 ) - weight 311 23 0.4550070167 ( 5.7200474739 5.6153564453 -2.7433590889 ) - weight 312 19 0.7743251324 ( 7.5248026848 6.6063671112 5.3296704292 ) - weight 313 23 0.2256748974 ( 4.8924207687 5.646156311 -3.8270666599 ) - weight 314 19 0.6721830368 ( 7.3544774055 7.3331780434 6.2138743401 ) - weight 315 23 0.3278169632 ( 5.8460865021 5.4342851639 -3.2068135738 ) - weight 316 19 0.6456577778 ( 8.0477924347 6.9644694328 4.9809889793 ) - weight 317 23 0.3543422222 ( 4.5435676575 6.0787901878 -3.3639643192 ) - weight 318 19 0.6799911261 ( 6.0329489708 7.6852078438 7.6616215706 ) - weight 319 23 0.3200088739 ( 7.4011497498 4.1902728081 -3.1834816933 ) - weight 320 19 0.4274918437 ( 6.8514614105 8.6860313416 7.1228599548 ) - weight 321 23 0.5725081563 ( 6.9007043839 4.7997055054 -2.0258896351 ) - weight 322 19 0.8172137737 ( 7.2623720169 7.0577697754 6.2991466522 ) - weight 323 23 0.1827861965 ( 5.9126224518 5.3928279877 -3.4991469383 ) - weight 324 19 0.7806497216 ( 7.4643697739 5.9758381844 4.7186379433 ) - weight 325 23 0.2193502635 ( 4.2335977554 5.6369900703 -4.410545826 ) - weight 326 19 0.7039682865 ( 7.985806942 6.2979912758 2.9432559013 ) - weight 327 23 0.2960317135 ( 2.463457346 5.9632148743 -3.8740377426 ) - weight 328 19 0.1038422585 ( 5.082909584 12.4144849777 6.1407847404 ) - weight 329 23 0.8961577415 ( 6.3652787209 2.4043755531 1.4337821007 ) - weight 330 19 0.2030091435 ( 6.7135577202 11.1296548843 6.8086853027 ) - weight 331 23 0.7969908714 ( 6.811601162 4.2610936165 0.3805555105 ) - weight 332 19 0.1855949163 ( 6.0136346817 10.7667255402 6.8046212196 ) - weight 333 23 0.8144050837 ( 6.8207626343 3.6276388168 -0.0887819901 ) - weight 334 19 0.0987952277 ( 5.3036632538 12.2999391556 5.9437665939 ) - weight 335 23 0.9012047648 ( 6.1451787949 2.6242835522 1.3716076612 ) - weight 336 19 0.3208101094 ( 6.8007435799 9.111823082 6.7019839287 ) - weight 337 23 0.6791899204 ( 6.5229353905 4.65122509 -1.5828863382 ) - weight 338 23 0.8099705577 ( 2.4374177456 4.1119771004 4.6547012329 ) - weight 339 25 0.1900293827 ( 2.9522709846 -2.8293120861 3.3552181721 ) - weight 340 19 0.0883323401 ( 7.8683838844 14.7688550949 -0.5040599704 ) - weight 341 23 0.8042147756 ( -0.2128523439 4.2687215805 4.7061347961 ) - weight 342 25 0.1074528545 ( 0.391489774 -2.5303554535 3.9909620285 ) - weight 343 19 0.1353543699 ( 7.6154971123 13.5227231979 -2.4617042542 ) - weight 344 23 0.7209137678 ( -2.2519085407 4.0611052513 3.5888552666 ) - weight 345 25 0.1437318772 ( -1.7989081144 -2.08548522 3.3176007271 ) - weight 346 19 0.2366270423 ( 6.5254569054 11.135887146 -3.410150528 ) - weight 347 23 0.712400794 ( -3.3339440823 3.2837798595 1.1373893023 ) - weight 348 25 0.0509721562 ( -3.3356502056 -1.6294618845 1.0339224339 ) - weight 349 19 0.1157113761 ( 7.1968536377 10.8275089264 6.0477180481 ) - weight 350 23 0.5851498246 ( 5.9975514412 4.7249760628 0.2190786153 ) - weight 351 25 0.2991387844 ( 5.8654408455 -0.5730599165 -1.0206054449 ) - weight 352 19 0.1415073276 ( 6.4242811203 12.2764749527 5.8028407097 ) - weight 353 23 0.8584926724 ( 5.9309277534 3.7206993103 1.5394294262 ) - weight 354 19 0.1760802418 ( 7.547185421 9.7711496353 5.9286913872 ) - weight 355 23 0.5166523457 ( 5.7640347481 5.2244110107 -0.7549998164 ) - weight 356 25 0.3072674274 ( 5.5661840439 0.3185377121 -1.627477169 ) - weight 357 19 0.0554307401 ( 6.7274479866 14.1632137299 4.0685682297 ) - weight 358 23 0.8779892325 ( 4.3529295921 3.5928099155 3.5773100853 ) - weight 359 25 0.0665800944 ( 4.5887656212 -2.9513719082 1.803935647 ) - weight 360 23 1 ( 2.3582787514 2.8925158978 4.5921206474 ) - weight 361 19 0.0658458471 ( 7.2053837776 14.7571573257 1.9999060631 ) - weight 362 23 0.9341540933 ( 2.3178875446 3.8113913536 4.3966889381 ) - weight 363 25 1 ( 3.3603711128 5.1649403572 -0.5088157654 ) - weight 364 23 0.1877750009 ( -3.2251286507 10.3050394058 0.5043415427 ) - weight 365 25 0.8122249842 ( -2.2870504856 4.9290032387 3.3998582363 ) - weight 366 19 0.1630557477 ( 7.4645080566 10.6199893951 -4.1298346519 ) - weight 367 23 0.5551897883 ( -4.1550283432 4.2328352928 0.8356826305 ) - weight 368 25 0.2817544639 ( -4.04327631 -0.5907587409 1.3276462555 ) - weight 369 23 0.1265711486 ( -1.109880805 10.3942337036 1.1698451042 ) - weight 370 25 0.8734288812 ( -0.1066997498 4.5715637207 3.6082620621 ) - weight 371 23 0.1877672225 ( 1.5462152958 10.3094949722 0.6735554934 ) - weight 372 25 0.8122327924 ( 2.4043576717 4.5323319435 2.6075716019 ) - weight 373 19 0.0571100004 ( 10.7686166763 7.8666701317 4.3355326653 ) - weight 374 23 0.0574912056 ( 3.8060107231 8.568816185 -1.9894669056 ) - weight 375 25 0.8853988051 ( 3.9618241787 3.9902200699 -0.9291974902 ) - weight 376 19 0.3791074753 ( 7.988345623 7.8005318642 4.8358793259 ) - weight 377 23 0.3468780518 ( 4.4764766693 5.8795180321 -2.5397188663 ) - weight 378 25 0.274014473 ( 4.1388587952 1.7781203985 -2.6784551144 ) - weight 379 19 0.3133431375 ( 7.4575538635 8.7544851303 5.4896874428 ) - weight 380 23 0.4466394484 ( 5.2442297935 5.2596096992 -1.7362890244 ) - weight 381 25 0.2400174439 ( 4.9174003601 0.8171602488 -2.3790221214 ) - weight 382 19 0.2476018369 ( 7.2163624763 9.4689178467 5.6650891304 ) - weight 383 23 0.4708499312 ( 5.4967737198 4.9249882698 -1.0854408741 ) - weight 384 25 0.2815482318 ( 5.2115960121 0.2140048444 -1.9930100441 ) - weight 385 19 0.0657564402 ( 5.2675285339 13.4878311157 4.7928433418 ) - weight 386 23 0.9342435598 ( 5.1076021194 2.3156149387 2.6226785183 ) - weight 387 19 0.1494024992 ( 10.3300418854 8.3052854538 -3.0666980743 ) - weight 388 25 0.8505975604 ( -3.1889724731 3.1203916073 0.8838816285 ) - weight 389 19 0.4001914561 ( 6.2269906998 10.4077987671 -3.3577852249 ) - weight 390 23 0.5998085141 ( -3.3265471458 3.1066424847 0.3689459264 ) - weight 391 19 1 ( 5.4556202888 3.3671040535 -4.3932404518 ) - weight 392 19 0.8427659273 ( 6.4755516052 4.4741010666 -3.0757756233 ) - weight 393 23 0.1572340876 ( -3.5826590061 4.2922945023 -5.4515967369 ) - weight 394 19 0.6229522824 ( 7.0111885071 6.1521916389 -3.455799818 ) - weight 395 23 0.2573620975 ( -3.8477039337 4.5305175781 -3.6851553917 ) - weight 396 24 0.0536541902 ( 0.6099901199 -3.8950231075 -3.5936584473 ) - weight 397 25 0.0660314336 ( -4.3700304031 1.6430183649 -2.6124694347 ) - weight 398 19 0.4918803871 ( 7.3225984573 8.4050712585 -3.7378945351 ) - weight 399 23 0.2849137783 ( -3.9505574703 4.4664587975 -1.3966321945 ) - weight 400 25 0.2232058495 ( -4.1402859688 0.5862177014 -0.5919716954 ) - weight 401 19 0.3240501881 ( 7.1030936241 9.6156044006 -4.0882873535 ) - weight 402 23 0.4188577235 ( -4.1785697937 4.0356559753 -0.2139380276 ) - weight 403 25 0.2570921183 ( -4.2512311935 -0.304109782 0.3198146224 ) - weight 404 19 0.7974441051 ( 5.0823187828 6.4326629639 -6.8444199562 ) - weight 405 23 0.20255588 ( -7.0675063133 2.3250141144 -3.4602680206 ) - weight 406 19 1 ( 5.1991491318 3.5427584648 -5.9475021362 ) - weight 407 19 0.3418679237 ( 5.9241189957 13.2698040009 -4.686214447 ) - weight 408 23 0.6581320763 ( -4.3765745163 2.2622368336 3.238083601 ) - weight 409 17 0.0513280034 ( 3.150354147 11.1687431335 -4.1655874252 ) - weight 410 19 0.9486719966 ( 3.4110982418 0.9760091305 -4.5475029945 ) - weight 411 19 1 ( 1.6152938604 2.4012238979 -8.9278745651 ) - weight 412 19 0.670599401 ( 5.0842542648 10.6949415207 -7.4311890602 ) - weight 413 23 0.3294006288 ( -7.2770662308 1.6213521957 0.7791022062 ) - weight 414 19 1 ( 5.2872533798 2.1579010487 6.5535182953 ) - weight 415 19 1 ( 3.4945862293 1.609946847 8.9752626419 ) - weight 416 19 1 ( 6.6205143929 3.899638176 7.8368425369 ) - weight 417 17 1 ( 7.4747138023 5.5362343788 -4.6569385529 ) - weight 418 17 0.4902055562 ( 5.9302091599 7.7649593353 -2.0726835728 ) - weight 419 19 0.509794414 ( 6.022685051 -1.548184514 -1.306878686 ) - weight 420 17 0.5569217801 ( 2.8505253792 8.1562767029 -3.8409321308 ) - weight 421 19 0.4430782497 ( 3.0520098209 -1.768654108 -3.2793815136 ) - weight 422 19 0.057944037 ( 9.5413103104 13.5764770508 -2.117672205 ) - weight 423 23 0.4751322865 ( -2.0291147232 5.9761376381 3.9250369072 ) - weight 424 25 0.4669236541 ( -1.2485218048 -0.5336677432 4.3754010201 ) - weight 425 17 0.0714654252 ( 6.7700829506 8.783914566 3.8741366863 ) - weight 426 19 0.8564918041 ( 6.543941021 1.3533338308 4.0239572525 ) - weight 427 20 0.0720428228 ( 2.5192580223 -4.3620147705 -3.3549571037 ) - weight 428 19 1 ( 7.1283516884 2.5655679703 3.6553533077 ) - weight 429 23 1 ( 4.1167583466 2.856675148 3.8166527748 ) - weight 430 19 0.0866496861 ( 9.8136339188 5.7926149368 0.904933095 ) - weight 431 25 0.9133503437 ( 0.0918630958 4.2890014648 -2.3136975765 ) - weight 432 19 0.0949518755 ( 4.5509228706 14.4049577713 -0.414057076 ) - weight 433 23 0.9050481319 ( 0.0581518449 1.0646973848 3.8078832626 ) - weight 434 19 0.1297236681 ( 4.0657763481 14.7400054932 -0.3888465464 ) - weight 435 23 0.8702763319 ( 0.1438159049 0.5369381309 4.0576663017 ) - weight 436 19 0.1711663008 ( 3.4669704437 14.705493927 -0.4351997674 ) - weight 437 23 0.8288336992 ( 0.1332392693 -0.051066298 3.9309892654 ) - weight 438 19 0.7626799941 ( 1.6254361868 15.3576469421 -4.648750782 ) - weight 439 23 0.2373200059 ( -3.8796172142 -2.2919816971 4.5987043381 ) - weight 440 19 0.0975153446 ( 3.3897609711 13.6124639511 2.794873476 ) - weight 441 23 0.9024846554 ( 3.2532408237 0.292234838 2.596154213 ) - weight 442 19 0.1383740902 ( 3.2609643936 14.4725856781 1.2619138956 ) - weight 443 23 0.8616259098 ( 1.8131079674 -0.0865061805 3.5389888287 ) - weight 444 19 0.5951520205 ( 1.9623763561 14.3548383713 -1.1430112123 ) - weight 445 23 0.4048479795 ( -0.504319191 -1.5334194899 3.3981590271 ) - weight 446 19 0.1065164208 ( 3.5741782188 13.2580728531 2.9878425598 ) - weight 447 23 0.8934835792 ( 3.4021146297 0.5436933637 2.2623207569 ) - weight 448 19 0.4923139811 ( 1.7094359398 12.2291755676 5.8952274323 ) - weight 449 23 0.5076860189 ( 6.3219823837 -0.9084520936 0.7279062867 ) - weight 450 19 0.6383779049 ( 1.4439511299 11.7858381271 6.4904961586 ) - weight 451 23 0.3616220653 ( 6.8919143677 -1.0551799536 0.2034795582 ) - weight 452 19 0.8807009459 ( 0.4590358436 11.9974584579 6.4482426643 ) - weight 453 23 0.1192990765 ( 6.9318451881 -2.0612654686 0.2566237152 ) - weight 454 19 0.2427999973 ( 2.9859952927 12.4142818451 4.7526745796 ) - weight 455 23 0.7572000027 ( 5.1203083992 0.2317055464 1.2025809288 ) - weight 456 19 0.3133231997 ( 3.0173053741 11.6713752747 5.7371592522 ) - weight 457 23 0.6866768003 ( 6.0317749977 0.4538179636 0.4013350606 ) - weight 458 19 0.2284029126 ( 2.3240170479 13.5139741898 4.2428860664 ) - weight 459 23 0.7715970874 ( 4.752594471 -0.6300597787 2.2172579765 ) - weight 460 19 0.4539279342 ( 1.8042963743 13.5808095932 4.0792121887 ) - weight 461 23 0.5460720658 ( 4.6291942596 -1.1649526358 2.2119889259 ) - weight 462 19 0.5506329536 ( 1.6334135532 12.3113517761 4.7318472862 ) - weight 463 23 0.4493670762 ( 5.1776051521 -1.0861165524 0.8854572773 ) - weight 464 19 0.7576830983 ( 0.7257264256 12.1895227432 6.3317375183 ) - weight 465 23 0.2423168868 ( 6.815718174 -1.8373693228 0.497395426 ) - weight 466 19 0.4610470533 ( 2.151403904 14.9870710373 -0.0494415238 ) - weight 467 23 0.5389529467 ( 0.6260527372 -1.3605091572 3.9671111107 ) - weight 468 19 0.0757014751 ( 5.5144433975 14.5699796677 0.139491722 ) - weight 469 23 0.9242985249 ( 0.5608949065 2.0309584141 4.0828552246 ) - weight 470 19 0.0646080971 ( 4.6173129082 13.7566709518 1.8133486509 ) - weight 471 23 0.9353919029 ( 2.2112057209 1.4029256105 3.0103993416 ) - weight 472 19 0.051496923 ( 5.7953739166 14.3012447357 2.4747972488 ) - weight 473 23 0.948503077 ( 2.8406951427 2.5300545692 3.6851038933 ) - weight 474 19 0.0556442142 ( 5.2458825111 14.6230382919 1.8481531143 ) - weight 475 23 0.9443557858 ( 2.2813503742 1.8905121088 3.9613156319 ) - weight 476 19 0.0865022242 ( 7.176322937 14.4131307602 -0.1123211607 ) - weight 477 23 0.9134978056 ( 0.1898894906 3.6725349426 4.2149038315 ) - weight 478 19 0.8864985108 ( 0.8135397434 12.7714681625 -7.7247376442 ) - weight 479 23 0.1135015041 ( -7.111948967 -2.9291932583 2.1583805084 ) - weight 480 19 0.5486282706 ( 3.0919597149 13.9394035339 -1.5272010565 ) - weight 481 23 0.4513717294 ( -0.9953477979 -0.386297375 3.2003011703 ) - weight 482 19 0.3262838423 ( 3.1010465622 14.2815828323 -0.5684262514 ) - weight 483 23 0.6737161279 ( -0.0128341401 -0.356121242 3.4652059078 ) - weight 484 19 0.7393954396 ( 3.6222026348 12.2014389038 -6.9090332985 ) - weight 485 23 0.2606045604 ( -6.5317997932 -0.011520098 1.986612916 ) - weight 486 19 0.4849961102 ( 4.6421232224 14.0900278091 -4.7689919472 ) - weight 487 23 0.51500386 ( -4.3044309616 0.8661602736 3.8454537392 ) - weight 488 19 0.7034702301 ( 2.5460412502 13.9163827896 -5.3319077492 ) - weight 489 23 0.2965297699 ( -4.7443699837 -1.2149448395 3.3806512356 ) - weight 490 19 0.1573241353 ( 6.7011814117 13.6079559326 -1.8525781631 ) - weight 491 23 0.8426758647 ( -1.5800918341 3.1945543289 3.4791989326 ) - weight 492 19 0.4455580413 ( 3.8683624268 14.8221120834 -3.4969654083 ) - weight 493 23 0.5544419289 ( -2.9259550571 0.0891750902 4.3442540169 ) - weight 494 19 0.6879624724 ( 1.6253722906 15.0306892395 -4.0591115952 ) - weight 495 23 0.3120375276 ( -3.3221511841 -2.1957585812 4.2318964005 ) - weight 496 19 0.7957887053 ( 1.5359910727 15.1845941544 -5.1603279114 ) - weight 497 23 0.2042112947 ( -4.3975820541 -2.3928768635 4.4531321526 ) - weight 498 19 0.883454442 ( 1.9995269775 10.9818029404 -10.2186746597 ) - weight 499 23 0.1165455505 ( -9.8243703842 -1.6770032644 0.7785322666 ) - weight 500 19 0.9208578467 ( 6.5005960464 5.8534259796 7.4430441856 ) - weight 501 23 0.0791421309 ( 6.9931111336 4.9176421165 -4.8941345215 ) - weight 502 19 1 ( -4.8445672989 3.5474803448 8.2679128647 ) - weight 503 19 1 ( -4.2299785614 5.4739603996 9.2519369125 ) - weight 504 19 1 ( -6.3439702988 3.2810635567 6.6381435394 ) - weight 505 19 1 ( -5.2712097168 3.0016710758 7.2553672791 ) - weight 506 19 1 ( -1.5261673927 6.6848831177 10.2535734177 ) - weight 507 19 0.6624171734 ( -1.2869739532 11.3651981354 7.446914196 ) - weight 508 39 0.3375828564 ( -7.8158597946 -1.0706192255 -0.3087096214 ) - weight 509 19 0.5241057873 ( -4.5647926331 8.9029188156 8.2703351974 ) - weight 510 39 0.4758941829 ( -8.2075242996 2.6027650833 -2.2677357197 ) - weight 511 19 0.6397638321 ( -3.3002691269 10.7812709808 7.7936582565 ) - weight 512 39 0.3602361977 ( -7.9797906876 1.0295439959 -0.5862012506 ) - weight 513 19 0.8934609294 ( -0.90167588 11.8251190186 6.9294381142 ) - weight 514 39 0.1065390483 ( -7.3665852547 -1.5613840818 0.1214832962 ) - weight 515 19 0.678021431 ( -5.1026115417 8.1662931442 8.1946954727 ) - weight 516 39 0.3219785392 ( -8.033118248 3.2406849861 -2.9003727436 ) - weight 517 19 1 ( -7.6583595276 4.3135032654 5.1793165207 ) - weight 518 39 0.4493831694 ( -0.4913783669 6.3413143158 4.3958640099 ) - weight 519 41 0.5506168008 ( -4.6487727165 -0.4633581042 -0.2993050814 ) - weight 520 41 1 ( -0.6806562543 5.6197538376 3.9661483765 ) - weight 521 39 0.0885743201 ( 4.2962241173 9.7795324326 -0.5905166268 ) - weight 522 41 0.9114256501 ( -1.4162145853 5.0083856583 4.0844221115 ) - weight 523 39 0.4803135693 ( -4.0166726112 5.7046957016 3.3776307106 ) - weight 524 41 0.5196864605 ( -3.5681967735 -0.8171390891 -3.8457081318 ) - weight 525 39 0.4583046138 ( -2.3974478245 6.0952811241 4.0828690529 ) - weight 526 41 0.5416953564 ( -4.3212175369 -0.664681673 -2.2081727982 ) - weight 527 39 0.2154574394 ( -4.49644804 8.6312541962 -1.534578681 ) - weight 528 41 0.7845425606 ( -0.3530877233 3.8591120243 -4.694519043 ) - weight 529 19 0.0606484413 ( -7.7586784363 12.1194076538 5.3920497894 ) - weight 530 39 0.5090739727 ( -5.4229426384 5.0274734497 1.6307421923 ) - weight 531 41 0.430277586 ( -1.7432210445 -0.7829293609 -5.3140878677 ) - weight 532 39 0.1631084234 ( -3.3271412849 9.9085979462 -0.6241797209 ) - weight 533 41 0.8368915915 ( -1.6780865192 4.7046604156 -3.5295555592 ) - weight 534 41 1 ( -2.9941067696 6.2761125565 -1.1352915764 ) - weight 535 41 1 ( -1.9921369553 6.1444401741 -2.7512164116 ) - weight 536 41 1 ( -2.5065660477 5.9567751884 3.4729576111 ) - weight 537 41 1 ( -1.3276998997 5.6512184143 4.0652360916 ) - weight 538 41 1 ( -3.3541662693 6.229077816 1.2755435705 ) - weight 539 19 0.0933828279 ( -8.6668891907 12.2293567657 -3.6217293739 ) - weight 540 39 0.379648 ( 3.5861384869 5.2071585655 2.5737769604 ) - weight 541 41 0.5269691944 ( -2.3925790787 -0.4994460642 3.7182490826 ) - weight 542 19 0.0939339846 ( -10.9819784164 8.5530757904 -3.6995155811 ) - weight 543 39 0.1847647876 ( 4.1348724365 8.0505962372 -0.6657420993 ) - weight 544 41 0.7213012576 ( -0.6281665564 3.4623296261 3.9864156246 ) - weight 545 41 1 ( -1.3308038712 5.9987077713 -3.4024410248 ) - weight 546 41 1 ( -0.4379433095 5.9327573776 -3.5190856457 ) - weight 547 19 0.3753109574 ( -5.8264608383 9.1134996414 8.2740182877 ) - weight 548 39 0.6246890426 ( -8.1484775543 3.8130524158 -1.8580009937 ) - weight 549 19 0.2997034788 ( -6.5805830956 9.369559288 7.570084095 ) - weight 550 39 0.7002965212 ( -7.4226589203 4.4616370201 -1.4310170412 ) - weight 551 19 0.2185793072 ( -5.4837379456 10.5651903152 8.2010650635 ) - weight 552 39 0.7814207077 ( -8.2253389359 3.2450397015 -0.4790015519 ) - weight 553 19 0.153814733 ( -4.833984375 11.7926425934 7.4382410049 ) - weight 554 39 0.846185267 ( -7.6165094376 2.3559551239 0.68271029 ) - weight 555 19 0.0944913626 ( -4.4890122414 12.7021245956 6.1874475479 ) - weight 556 39 0.9055086374 ( -6.475107193 1.7785170078 1.6178110838 ) - weight 557 19 0.1639066339 ( -3.7668144703 12.2644634247 6.1635694504 ) - weight 558 39 0.8360933661 ( -6.4594497681 1.1331566572 1.0728782415 ) - weight 559 19 0.503538847 ( -6.4761629105 8.0272321701 7.5324897766 ) - weight 560 39 0.4964611828 ( -7.2742686272 4.563765049 -2.7658240795 ) - weight 561 19 0.0660847425 ( -4.3117575645 13.6960668564 4.4811558723 ) - weight 562 39 0.9339152575 ( -4.8775258064 1.3179219961 2.6977920532 ) - weight 563 19 0.8687992096 ( -7.8084440231 4.1107563972 2.4757163525 ) - weight 564 39 0.1312008202 ( -1.8182612658 6.0909981728 -6.0191698074 ) - weight 565 19 0.7283416986 ( -8.1711883545 5.3612446785 2.4001698494 ) - weight 566 39 0.2716583312 ( -1.8295059204 6.2487568855 -4.7245664597 ) - weight 567 41 1 ( 0.8240913153 5.1673092842 -3.5709760189 ) - weight 568 41 1 ( -0.2594381869 4.8315725327 3.338593483 ) - weight 569 41 1 ( 2.1779937744 5.3081560135 2.1137125492 ) - weight 570 41 1 ( 2.3212575912 5.2967023849 -2.42735219 ) - weight 571 41 1 ( 1.699565053 5.1767811775 -3.2414548397 ) - weight 572 41 1 ( 2.4778931141 4.5913395882 -2.3763372898 ) - weight 573 41 1 ( 2.7111654282 4.7615604401 -0.4728626311 ) - weight 574 41 1 ( 2.6948719025 5.4358768463 -0.5409066677 ) - weight 575 41 1 ( 2.1067686081 4.5096840858 2.0655195713 ) - weight 576 41 1 ( -0.1493162662 3.8548221588 3.2618536949 ) - weight 577 41 1 ( 1.776571393 4.4855451584 -3.2860021591 ) - weight 578 19 0.1077406704 ( -9.7189722061 6.0726656914 3.0613014698 ) - weight 579 39 0.0546411723 ( -2.4495275021 7.7141704559 -3.8262424469 ) - weight 580 41 0.8376181722 ( 2.1746888161 4.0999736786 -2.7362084389 ) - weight 581 19 0.0942282602 ( -9.9062108994 6.6120066643 3.8263254166 ) - weight 582 39 0.0630056411 ( -3.2452709675 7.8742785454 -3.3238816261 ) - weight 583 41 0.8427661061 ( 1.6268795729 3.9902553558 -3.5102078915 ) - weight 584 41 1 ( 2.5489020348 4.715695858 0.9717723131 ) - weight 585 19 0.3565033078 ( -8.9153518677 6.3292460442 -1.9020335674 ) - weight 586 39 0.1718751937 ( 2.4101428986 6.4987254143 -3.3236193657 ) - weight 587 41 0.4716215134 ( 2.3801150322 3.0650348663 2.1864974499 ) - weight 588 41 1 ( 1.3725030422 4.294696331 2.8495473862 ) - weight 589 19 0.1221254915 ( -9.9867343903 6.4475312233 -2.0741710663 ) - weight 590 41 0.8778744936 ( 1.6843781471 3.8806765079 2.3918323517 ) - weight 591 19 0.2911888063 ( -8.6426649094 6.5966320038 2.716303587 ) - weight 592 39 0.1886390001 ( -2.2217862606 6.5462660789 -3.4572794437 ) - weight 593 41 0.5201721787 ( 2.3366646767 2.8997063637 -2.4444494247 ) - weight 594 19 0.1986566335 ( -8.8203716278 8.0499620438 4.3790659904 ) - weight 595 39 0.1710185856 ( -3.9907214642 6.624935627 -2.1256613731 ) - weight 596 41 0.6303247809 ( 1.040158987 2.314691782 -4.1430835724 ) - weight 597 19 0.3174703121 ( -8.6748132706 5.9642591476 0.7578168511 ) - weight 598 39 0.1770481765 ( -0.2173864096 6.5242500305 -3.924715519 ) - weight 599 41 0.5054814816 ( 2.8326745033 3.1890544891 -0.4678738415 ) - weight 600 19 0.1330608726 ( -9.8786287308 5.8036046028 -0.5175085068 ) - weight 601 39 0.050177414 ( 1.1419174671 7.6360387802 -3.7918424606 ) - weight 602 41 0.8167617321 ( 2.2885010242 4.2196106911 0.8524539471 ) - weight 603 19 0.2538379729 ( -9.6596431732 7.2127723694 -2.5370461941 ) - weight 604 39 0.091649361 ( 3.0117805004 7.0457892418 -2.2860343456 ) - weight 605 41 0.6545126438 ( 1.2281317711 3.16274786 2.8199138641 ) - weight 606 19 0.8944743872 ( -8.188873291 3.7395002842 0.732164681 ) - weight 607 39 0.1055256501 ( -0.0280152075 6.3882040977 -6.1901021004 ) - weight 608 19 0.7718275189 ( -8.0036716461 4.7868037224 0.4135006666 ) - weight 609 39 0.2281724811 ( 0.1849808693 6.0189385414 -5.1649360657 ) - weight 610 19 0.712061286 ( -8.5126562119 5.3174443245 0.171448797 ) - weight 611 39 0.2879386842 ( 0.411801815 6.4193196297 -4.5424561501 ) - weight 612 19 0.2063084394 ( -8.6430654526 8.799238205 4.9758358002 ) - weight 613 39 0.2971664369 ( -4.6610784531 6.380466938 -1.4624545574 ) - weight 614 41 0.4965251684 ( 0.5199418664 1.7780587673 -4.7678918839 ) - weight 615 19 0.2893922627 ( -8.6493520737 8.6632795334 -3.2549357414 ) - weight 616 39 0.1666120589 ( 3.53317976 5.7705469131 -0.9662144184 ) - weight 617 41 0.543995738 ( 0.5815390944 1.4852290154 3.4585635662 ) - weight 618 17 0.5207475424 ( -1.5464029312 4.1131296158 8.0245704651 ) - weight 619 19 0.4792524278 ( -2.0546736717 -1.7559373379 8.9840517044 ) - weight 620 17 0.3675586879 ( -4.124150753 5.8340101242 7.2335314751 ) - weight 621 19 0.6324413419 ( -4.5602960587 -0.398825258 7.5307588577 ) - weight 622 17 0.1635299921 ( -4.5332636833 7.0297050476 7.0556578636 ) - weight 623 19 0.8364700079 ( -4.9422864914 0.6719723344 6.9509534836 ) - weight 624 17 0.3534659743 ( -1.8052283525 5.5034608841 8.3646736145 ) - weight 625 19 0.6465340257 ( -2.3127911091 -0.3318959475 8.8385772705 ) - weight 626 17 0.4341910779 ( -5.3271422386 6.23767519 5.8595585823 ) - weight 627 19 0.5658089519 ( -5.6791701317 -0.4699434638 6.033762455 ) - weight 628 17 0.8026441336 ( -1.3415035009 2.7959611416 7.6921758652 ) - weight 629 19 0.1973558664 ( -1.8498107195 -3.1085584164 9.1099481583 ) - weight 630 19 0.8543192744 ( -7.5472068787 3.7632319927 -1.631722331 ) - weight 631 39 0.1456807703 ( 2.2784767151 5.5695576668 -6.0892348289 ) - weight 632 19 0.7742658257 ( -7.0193519592 4.8565526009 -1.5381404161 ) - weight 633 39 0.2257341892 ( 2.0555901527 4.8876004219 -5.1053676605 ) - weight 634 19 0.7471264005 ( -7.834508419 5.3834090233 -1.4033900499 ) - weight 635 39 0.2528736293 ( 1.9278763533 5.6192851067 -4.4661946297 ) - weight 636 17 0.387578994 ( -4.8683719635 9.1633815765 -1.2298964262 ) - weight 637 19 0.6124210358 ( -4.7857022285 -0.0062151998 -1.5831445456 ) - weight 638 17 0.3116692901 ( -2.7044658661 9.7982540131 -2.4657788277 ) - weight 639 19 0.6883307099 ( -2.5477266312 0.203197211 -2.8323721886 ) - weight 640 19 0.4397973716 ( -8.4015016556 7.4504122734 -3.0229344368 ) - weight 641 39 0.202937752 ( 3.3929908276 5.7322320938 -2.2172865868 ) - weight 642 41 0.357264936 ( 1.7283648252 1.9643523693 3.25476408 ) - weight 643 19 0.1024227738 ( -3.6739826202 13.4256591797 4.613465786 ) - weight 644 39 0.8975772262 ( -5.026368618 0.7418985367 2.3190755844 ) - weight 645 19 0.0551941991 ( -5.1156005859 13.530828476 3.62109375 ) - weight 646 39 0.9448058009 ( -3.9563539028 2.0686352253 2.7301280499 ) - weight 647 19 0.0648210049 ( -4.1190242767 13.771645546 3.4053151608 ) - weight 648 39 0.9351789951 ( -3.8270993233 1.0331109762 2.8234028816 ) - weight 649 19 0.1818646193 ( -3.029309988 14.1647481918 2.9681212902 ) - weight 650 39 0.8181353807 ( -3.4970934391 -0.1348689944 3.0684826374 ) - weight 651 19 0.2278274298 ( -2.8549966812 14.738781929 1.0170263052 ) - weight 652 39 0.7721725702 ( -1.6191418171 -0.5464881659 3.7544407845 ) - weight 653 19 0.828371644 ( -0.7134188414 14.4985723495 -1.6041424274 ) - weight 654 39 0.171628356 ( 0.869749248 -2.8214347363 3.374150753 ) - weight 655 19 0.6900701523 ( -1.3182066679 13.9398860931 -1.8880398273 ) - weight 656 39 0.3099298179 ( 1.2398781776 -2.1612362862 2.9432935715 ) - weight 657 19 0.2685622573 ( -2.8149504662 14.3941507339 2.5207278728 ) - weight 658 39 0.7314377427 ( -3.086268425 -0.416151911 3.2939577103 ) - weight 659 19 0.7010427713 ( -1.5317583084 14.9345188141 -0.8916427493 ) - weight 660 39 0.2989572287 ( 0.1758933067 -2.0278112888 3.8802239895 ) - weight 661 19 0.0728244781 ( -6.4640574455 14.5801448822 -0.5603785515 ) - weight 662 39 0.9271755219 ( 0.195029214 2.9105238914 4.298997879 ) - weight 663 19 0.0524587035 ( -6.9352092743 15.0006475449 0.747456491 ) - weight 664 39 0.9475412965 ( -1.1116132736 3.4106814861 4.6885704994 ) - weight 665 19 0.0521270633 ( -6.3127293587 15.0361042023 0.7685776353 ) - weight 666 39 0.9478729367 ( -1.1757702827 2.7937464714 4.6217904091 ) - weight 667 19 0.2938108742 ( -7.1230487823 9.2287311554 6.1649975777 ) - weight 668 39 0.5755110383 ( -5.9786548615 4.9089484215 -1.3750215769 ) - weight 669 41 0.1306780875 ( 1.0163406134 0.3316908777 -6.0211391449 ) - weight 670 19 0.2593457699 ( -6.9671287537 10.1320753098 6.8245491982 ) - weight 671 39 0.7406542301 ( -6.7235584259 4.6665430069 -0.5615676641 ) - weight 672 39 1 ( -3.4778707027 3.2198526859 4.4403128624 ) - weight 673 19 0.0650603771 ( -6.0271134377 13.6074008942 5.0311646461 ) - weight 674 39 0.9349396229 ( -5.306125164 3.0636811256 2.8442306519 ) - weight 675 39 1 ( -3.2162778378 2.6081266403 4.0571842194 ) - weight 676 19 0.0552856363 ( -5.5632991791 13.6429634094 4.9607806206 ) - weight 677 39 0.9447143674 ( -5.2691206932 2.595915556 2.8100514412 ) - weight 678 19 0.0963922739 ( -5.8137106895 12.6753759384 6.065451622 ) - weight 679 39 0.9036077261 ( -6.2662558556 3.0779080391 1.8137414455 ) - weight 680 39 1 ( -2.3977985382 3.5115253925 4.6469116211 ) - weight 681 19 1 ( -1.4808238745 2.1779508591 10.1789779663 ) - weight 682 19 1 ( -2.3127348423 1.4412772655 9.6336326599 ) - weight 683 41 1 ( 1.030380249 5.0002717972 3.0010001659 ) - weight 684 19 0.0690433979 ( -4.3752551079 14.1672096252 1.5676848888 ) - weight 685 39 0.9309566021 ( -2.0185832977 1.0819563866 3.3942739964 ) - weight 686 19 0.0836250186 ( -3.9739565849 14.5186100006 1.2882270813 ) - weight 687 39 0.9163749814 ( -1.7974259853 0.6106645465 3.6969175339 ) - weight 688 19 0.2235984355 ( -4.8817996979 15.4476041794 -2.8250007629 ) - weight 689 39 0.7764015794 ( 2.2683215141 1.0425105095 5.0713481903 ) - weight 690 19 0.2618145943 ( -4.1020479202 15.2770824432 -2.4890949726 ) - weight 691 39 0.7381854057 ( 1.8991955519 0.3269463778 4.7525415421 ) - weight 692 19 0.1914669871 ( -5.7272629738 14.3414964676 -2.8975431919 ) - weight 693 39 0.8085330129 ( 2.4918503761 2.0408887863 4.1243414879 ) - weight 694 19 0.1809172034 ( -5.3844356537 15.1597948074 -2.7975587845 ) - weight 695 39 0.8190827966 ( 2.2986271381 1.5842519999 4.8668284416 ) - weight 696 19 0.4753880501 ( -4.0871653557 15.2931070328 -3.9203503132 ) - weight 697 39 0.5246119499 ( 3.3195943832 0.1990092844 4.8752994537 ) - weight 698 19 0.3253329694 ( -5.1115655899 14.5828742981 -4.5197587013 ) - weight 699 39 0.6746670008 ( 4.0436525345 1.271528244 4.3868737221 ) - weight 700 19 0.3729265034 ( -4.8953895569 15.1236467361 -4.5760211945 ) - weight 701 39 0.6270734668 ( 4.0382404327 0.9705139399 4.8885645866 ) - weight 702 19 0.60125494 ( -3.8166801929 15.3820028305 -4.9813656807 ) - weight 703 39 0.39874506 ( 4.3491129875 -0.1632941067 5.0003843307 ) - weight 704 19 0.5448612571 ( -3.7978127003 14.657784462 -5.2947568893 ) - weight 705 39 0.4551387429 ( 4.7229528427 -0.0939798951 4.3086462021 ) - weight 706 19 0.8841800094 ( -0.7393733263 15.457531929 -4.0117521286 ) - weight 707 39 0.1158199832 ( 3.1806299686 -3.1307630539 4.505967617 ) - weight 708 19 0.931039691 ( -1.0313379765 15.623301506 -4.6714787483 ) - weight 709 39 0.0689603239 ( 3.8406867981 -2.9199512005 4.7664384842 ) - weight 710 17 0.7990359664 ( -6.1807799339 5.0153846741 5.5550603867 ) - weight 711 19 0.2009640187 ( -6.5313405991 -1.729113698 6.0946350098 ) - weight 712 17 1 ( -6.7305803299 1.984634161 4.5554256439 ) - weight 713 17 0.7825206518 ( -4.8537888527 4.6932673454 6.6499085426 ) - weight 714 19 0.2174793631 ( -5.2719922066 -1.6710170507 7.3087291718 ) - weight 715 17 1 ( -4.9709105492 1.6011964083 6.1441030502 ) - weight 716 17 1 ( -6.2884659767 3.7875547409 -2.4399855137 ) - weight 717 19 0.9086368084 ( -1.9931775331 6.2422609329 -10.1819114685 ) - weight 718 39 0.0913631767 ( 10.2031326294 -0.9464059472 -3.8890984058 ) - weight 719 19 0.6714816093 ( -6.9141602516 9.6157112122 -7.1801877022 ) - weight 720 39 0.3285184205 ( 7.2399544716 3.6101958752 -0.007921651 ) - weight 721 19 0.5469177961 ( -7.6492395401 9.8798809052 -5.7171139717 ) - weight 722 39 0.3952530026 ( 5.8096880913 4.4065232277 0.2583729625 ) - weight 723 41 0.0578292273 ( 0.1134397835 -0.1329820305 5.8470649719 ) - weight 724 19 0.7633374333 ( -6.6618061066 3.9670217037 -5.9489073753 ) - weight 725 39 0.2366625518 ( 6.4952001572 4.3317627907 -5.7010850906 ) - weight 726 19 0.7496048212 ( -7.3524150848 4.209177494 -4.6466941833 ) - weight 727 39 0.2503952086 ( 5.2239093781 5.0752482414 -5.4513072968 ) - weight 728 19 0.5158829689 ( -6.3470988274 10.777718544 -5.4962935448 ) - weight 729 39 0.4841170013 ( 5.4276456833 3.0020973682 0.915697217 ) - weight 730 19 0.7992503047 ( -2.2913517952 7.9392442703 9.6059703827 ) - weight 731 39 0.2007496953 ( -9.5969848633 0.616294682 -3.6835246086 ) - weight 732 19 0.8831704259 ( -5.3501701355 6.6821045876 8.4692411423 ) - weight 733 39 0.116829522 ( -8.1599254608 3.735609293 -4.3420538902 ) - weight 734 19 0.8982713223 ( -7.8337192535 5.579726696 5.3616108894 ) - weight 735 39 0.1017286777 ( -4.8142499924 6.111802578 -4.7901382446 ) - weight 736 19 1 ( -6.5046005249 5.7227888107 8.5231628418 ) - weight 737 19 1 ( -6.9616732597 5.5851173401 8.0614538193 ) - weight 738 19 1 ( -7.2121248245 5.1236858368 7.6837615967 ) - weight 739 19 1 ( -7.0974140167 4.4310698509 7.5746741295 ) - weight 740 19 1 ( -6.0029654503 3.8739600182 8.402130127 ) - weight 741 19 1 ( -5.6446566582 4.3226547241 8.8684082031 ) - weight 742 19 1 ( -5.6811704636 4.9602236748 9.029168129 ) - weight 743 19 1 ( -6.0154910088 5.4840707779 8.8925352097 ) - weight 744 19 0.9401356578 ( -5.9841022491 6.0089740753 7.9647769928 ) - weight 745 39 0.0598643646 ( -7.5586252213 4.4251613617 -4.8639883995 ) - weight 746 19 1 ( -5.4314098358 5.7392077446 8.3821697235 ) - weight 747 19 1 ( -5.0536260605 5.1472196579 8.5357885361 ) - weight 748 19 1 ( -4.9950547218 4.4595007896 8.3720092773 ) - weight 749 19 1 ( -5.4840283394 3.805385828 7.7777266502 ) - weight 750 19 1 ( -6.2286338806 3.9039833546 7.1470522881 ) - weight 751 19 1 ( -6.7250328064 4.6438360214 6.8474235535 ) - weight 752 19 1 ( -6.7836046219 5.3319926262 7.0162529945 ) - weight 753 19 1 ( -2.0121905804 4.7541136742 9.6924037933 ) - weight 754 19 1 ( -4.2565402985 3.2908327579 8.0975084305 ) - weight 755 17 0.068359971 ( -2.2157037258 6.6570549011 8.7469377518 ) - weight 756 19 0.8091580868 ( -2.7279317379 0.881221354 8.801150322 ) - weight 757 21 0.0685596243 ( 1.5244281292 -5.3805122375 1.3622517586 ) - weight 758 18 0.0539222322 ( -2.6461749077 6.8139839172 0.3526515961 ) - weight 759 19 1 ( -7.0404019356 3.6147813797 4.3325209618 ) - weight 760 19 0.9084361196 ( -7.4340929985 4.5934705734 4.2233901024 ) - weight 761 39 0.0915638879 ( -3.6219902039 5.7828369141 -5.7378969193 ) - weight 762 17 0.920759201 ( -3.9032566547 1.4226287603 6.3968653679 ) - weight 763 18 0.0792407915 ( -4.2724089622 1.1675415039 -0.76222229 ) - weight 764 17 0.5972013474 ( -4.041613102 4.6338605881 6.8213367462 ) - weight 765 19 0.4027986228 ( -4.4715285301 -1.6673539877 7.5363049507 ) - weight 766 17 0.5359256268 ( -5.7293772697 5.6046919823 5.1373052597 ) - weight 767 19 0.464074403 ( -6.0492563248 -1.3054023981 5.5346078873 ) - weight 768 17 0.3884032667 ( -7.1282582283 6.7288265228 2.4463744164 ) - weight 769 19 0.6115967631 ( -7.2803573608 -1.1244336367 2.5490939617 ) - weight 770 17 0.3772356808 ( -6.7797346115 7.5144371986 0.6954978704 ) - weight 771 19 0.622764349 ( -6.8239927292 -0.9490959644 0.6609174609 ) - weight 772 17 0.8583768606 ( -3.5534398556 6.9300556183 -4.5617699623 ) - weight 773 19 0.1416231394 ( -3.3181934357 -3.1949262619 -3.9276509285 ) - weight 774 17 1 ( -3.3523221016 4.2277503014 -4.3892302513 ) - weight 775 17 0.6433618069 ( -7.9599318504 6.5943808556 2.0865409374 ) - weight 776 19 0.3566381633 ( -8.0924711227 -1.3727740049 2.2055308819 ) - weight 777 17 1 ( -8.9288539886 4.9402780533 1.8292461634 ) - weight 778 17 0.932662487 ( -6.3132991791 3.4905595779 6.0817599297 ) - weight 779 19 0.067337513 ( -6.714076519 -3.0004570484 7.079703331 ) - weight 780 17 1 ( -8.2049665451 2.8916378021 1.0030912161 ) - weight 781 17 0.7854495049 ( -7.7490954399 7.3643240929 -3.5514812469 ) - weight 782 19 0.2145504951 ( -7.5572118759 -2.4769201279 -3.3549473286 ) - weight 783 17 0.292829901 ( -6.0535845757 8.6939926147 0.1754484177 ) - weight 784 19 0.7071700692 ( -6.0537514687 0.0009032384 -0.1717445552 ) - weight 785 17 0.8891180754 ( -4.4797744751 3.2846221924 6.9601316452 ) - weight 786 19 0.1108819246 ( -4.9353618622 -2.9003310204 8.080657959 ) - weight 787 17 0.2254327834 ( -6.7647848129 8.1746177673 1.8703378439 ) - weight 788 19 0.7745672464 ( -6.8653926849 0.0572945476 1.5563365221 ) - weight 789 17 0.3170430362 ( -6.3666534424 7.1566362381 4.0962815285 ) - weight 790 19 0.6829569936 ( -6.6060156822 -0.1795395911 4.0111794472 ) - weight 791 19 0.2461065054 ( -4.4691781998 10.6110486984 8.171462059 ) - weight 792 39 0.7538934946 ( -8.265212059 2.2364084721 -0.5946910977 ) - weight 793 19 0.1607670188 ( -6.0021958351 10.787314415 7.6599025726 ) - weight 794 39 0.8392329812 ( -7.6735124588 3.6793751717 -0.1357310414 ) - weight 795 19 0.3230723143 ( -4.1400732994 10.2026252747 7.7948536873 ) - weight 796 39 0.6769276857 ( -7.8761901855 1.9463706017 -1.0207116604 ) - weight 797 19 0.4277999699 ( -4.8142085075 8.959028244 7.8816661835 ) - weight 798 39 0.5722000003 ( -7.8100352287 2.8096368313 -2.1427288055 ) - weight 799 19 0.329929769 ( -3.6806457043 11.2410421371 6.7770256996 ) - weight 800 39 0.670070231 ( -6.9850440025 1.2542723417 0.0050643375 ) - weight 801 17 0.916015327 ( -1.4637871981 1.0830299854 7.5076050758 ) - weight 802 18 0.0839846432 ( -1.9035443068 1.1055641174 0.5357451439 ) - weight 803 17 0.0513219051 ( -7.4338998795 10.1473417282 2.1551349163 ) - weight 804 19 0.9486781359 ( -7.5219869614 2.0120172501 1.1459642649 ) - weight 805 17 0.0682639182 ( -7.0546088219 10.6613645554 -0.2889678776 ) - weight 806 19 0.931736052 ( -7.0000386238 1.705270052 -1.3066254854 ) - weight 807 17 0.1157888323 ( -5.359398365 11.1132335663 -1.4574674368 ) - weight 808 19 0.884211123 ( -5.2362713814 1.7611728907 -2.459584713 ) - weight 809 19 0.4405724704 ( -7.5869636536 8.1371355057 5.7207517624 ) - weight 810 39 0.4985500872 ( -5.4114508629 5.500518322 -2.3406698704 ) - weight 811 41 0.0608774945 ( 1.6622315645 1.3034391403 -5.5285110474 ) - weight 812 19 0.5449929833 ( -7.6154241562 7.7501325607 6.0671830177 ) - weight 813 39 0.4550070167 ( -5.7200503349 5.6153011322 -2.7433946133 ) - weight 814 19 0.7743251324 ( -7.5248026848 6.6063671112 5.3296704292 ) - weight 815 39 0.2256748974 ( -4.8924236298 5.646086216 -3.8271026611 ) - weight 816 19 0.6721830368 ( -7.3544774055 7.3331780434 6.2138743401 ) - weight 817 39 0.3278169632 ( -5.8460893631 5.434223175 -3.206846714 ) - weight 818 19 0.6456577778 ( -8.0477924347 6.9644694328 4.9809889793 ) - weight 819 39 0.3543422222 ( -4.5435709953 6.0787272453 -3.3640062809 ) - weight 820 19 0.6799911261 ( -6.0329489708 7.6852078438 7.6616215706 ) - weight 821 39 0.3200088739 ( -7.4011516571 4.1902093887 -3.1834976673 ) - weight 822 19 0.4274918437 ( -6.8514614105 8.6860313416 7.1228599548 ) - weight 823 39 0.5725081563 ( -6.900706768 4.7996592522 -2.0259139538 ) - weight 824 19 0.8172137737 ( -7.2623720169 7.0577697754 6.2991466522 ) - weight 825 39 0.1827861965 ( -5.9126253128 5.3927617073 -3.4991793633 ) - weight 826 19 0.7806497216 ( -7.4643697739 5.9758381844 4.7186379433 ) - weight 827 39 0.2193502635 ( -4.2336006165 5.6369123459 -4.4105815887 ) - weight 828 19 0.7039682865 ( -7.985806942 6.2979912758 2.9432559013 ) - weight 829 39 0.2960317135 ( -2.4634606838 5.9631462097 -3.8740777969 ) - weight 830 19 0.1038422585 ( -5.082909584 12.4144849777 6.1407847404 ) - weight 831 39 0.8961577415 ( -6.3652796745 2.4043786526 1.4337917566 ) - weight 832 19 0.2030091435 ( -6.7135577202 11.1296548843 6.8086853027 ) - weight 833 39 0.7969908714 ( -6.8116035461 4.2610816956 0.3805387914 ) - weight 834 19 0.1855949163 ( -6.0136346817 10.7667255402 6.8046212196 ) - weight 835 39 0.8144050837 ( -6.8207645416 3.6276199818 -0.0887897611 ) - weight 836 19 0.0987952277 ( -5.3036632538 12.2999391556 5.9437665939 ) - weight 837 39 0.9012047648 ( -6.1451797485 2.6242861748 1.3716140985 ) - weight 838 19 0.3208101094 ( -6.8007435799 9.111823082 6.7019839287 ) - weight 839 39 0.6791899204 ( -6.5229382515 4.6511855125 -1.5829085112 ) - weight 840 39 0.8099705577 ( -2.437420845 4.1120295525 4.6546869278 ) - weight 841 41 0.1900293827 ( -4.0098433495 -2.7043991089 -2.141392231 ) - weight 842 19 0.0883323401 ( -7.8683838844 14.7688550949 -0.5040599704 ) - weight 843 39 0.8042147756 ( 0.2128493041 4.2687768936 4.7061185837 ) - weight 844 41 0.1074528545 ( -4.0393762589 -2.4325044155 0.4998852611 ) - weight 845 19 0.1353543699 ( -7.6154971123 13.5227231979 -2.4617042542 ) - weight 846 39 0.7209137678 ( 2.2519059181 4.0611467361 3.5888426304 ) - weight 847 41 0.1437318772 ( -2.8748419285 -2.0384662151 2.4842646122 ) - weight 848 19 0.2366270423 ( -6.5254569054 11.135887146 -3.410150528 ) - weight 849 39 0.712400794 ( 3.3339424133 3.2837874889 1.1373878717 ) - weight 850 41 0.0509721562 ( -0.2908211946 -1.6592493057 3.4659729004 ) - weight 851 19 0.1157113761 ( -7.1968536377 10.8275089264 6.0477180481 ) - weight 852 39 0.5851498246 ( -5.9975543022 4.7249622345 0.219055444 ) - weight 853 41 0.2991387844 ( -0.353482455 -0.5012258291 -5.9495563507 ) - weight 854 19 0.1415073276 ( -6.4242811203 12.2764749527 5.8028407097 ) - weight 855 39 0.8584926724 ( -5.9309301376 3.7207043171 1.5394204855 ) - weight 856 19 0.1760802418 ( -7.547185421 9.7711496353 5.9286913872 ) - weight 857 39 0.5166523457 ( -5.7640380859 5.224383831 -0.7550299764 ) - weight 858 41 0.3072674274 ( 0.3282649815 0.371424973 -5.7867832184 ) - weight 859 19 0.0554307401 ( -6.7274479866 14.1632137299 4.0685682297 ) - weight 860 39 0.8779892325 ( -4.3529319763 3.5928452015 3.5773031712 ) - weight 861 41 0.0665800944 ( -2.8745090961 -2.8351655006 -4.0890593529 ) - weight 862 39 1 ( -2.3582806587 2.8925671577 4.5921239853 ) - weight 863 19 0.0658458471 ( -7.2053837776 14.7571573257 1.9999060631 ) - weight 864 39 0.9341540933 ( -2.3178901672 3.811439991 4.3966794014 ) - weight 865 41 1 ( -0.1348701119 5.2056908607 -3.3332121372 ) - weight 866 39 0.1877750009 ( 3.2251210213 10.3050384521 0.5042408109 ) - weight 867 41 0.8122249842 ( -2.6633241177 4.9672818184 3.0524630547 ) - weight 868 19 0.1630557477 ( -7.4645080566 10.6199893951 -4.1298346519 ) - weight 869 39 0.5551897883 ( 4.155025959 4.2328395844 0.8356678486 ) - weight 870 41 0.2817544639 ( -0.3892714083 -0.6257172227 4.2328047752 ) - weight 871 39 0.1265711486 ( 1.109872818 10.3942394257 1.1697428226 ) - weight 872 41 0.8734288812 ( -3.3706786633 4.6499304771 0.9730252028 ) - weight 873 39 0.1877672225 ( -1.5462231636 10.3094911575 0.6734540462 ) - weight 874 41 0.8122327924 ( -2.9678769112 4.628578186 -1.7001049519 ) - weight 875 19 0.0571100004 ( -10.7686166763 7.8666701317 4.3355326653 ) - weight 876 39 0.0574912056 ( -3.8060164452 8.5687732697 -1.989544034 ) - weight 877 41 0.8853988051 ( 0.1074966267 4.0316061974 -4.026910305 ) - weight 878 19 0.3791074753 ( -7.988345623 7.8005318642 4.8358793259 ) - weight 879 39 0.3468780518 ( -4.4764800072 5.8794665337 -2.539757967 ) - weight 880 41 0.274014473 ( 1.7132291794 1.7835429907 -4.6205968857 ) - weight 881 19 0.3133431375 ( -7.4575538635 8.7544851303 5.4896874428 ) - weight 882 39 0.4466394484 ( -5.2442331314 5.2595686913 -1.7363196611 ) - weight 883 41 0.2400174439 ( 1.2201243639 0.8423249125 -5.3207306862 ) - weight 884 19 0.2476018369 ( -7.2163624763 9.4689178467 5.6650891304 ) - weight 885 39 0.4708499312 ( -5.496776104 4.9249563217 -1.0854668617 ) - weight 886 41 0.2815482318 ( 0.7619689107 0.2529125214 -5.5257663727 ) - weight 887 19 0.0657564402 ( -5.2675285339 13.4878311157 4.7928433418 ) - weight 888 39 0.9342435598 ( -5.1076030731 2.3156359196 2.6226894855 ) - weight 889 19 0.1494024992 ( -10.3300418854 8.3052854538 -3.0666980743 ) - weight 890 41 0.8505975604 ( -0.0556985885 3.0877277851 3.3392424583 ) - weight 891 19 0.4001914561 ( -6.2269906998 10.4077987671 -3.3577852249 ) - weight 892 39 0.5998085141 ( 3.3265459538 3.1066391468 0.3689469993 ) - weight 893 19 1 ( -5.4556202888 3.3671040535 -4.3932404518 ) - weight 894 19 0.8427659273 ( -6.4755516052 4.4741010666 -3.0757756233 ) - weight 895 39 0.1572341025 ( 3.5826573372 4.2922086716 -5.4516124725 ) - weight 896 19 0.6229522824 ( -7.0111885071 6.1521916389 -3.455799818 ) - weight 897 39 0.2573620975 ( 3.8477017879 4.5304574966 -3.6851744652 ) - weight 898 40 0.0536541902 ( -0.6099915504 -3.8950202465 -3.5936813354 ) - weight 899 41 0.0660314336 ( 3.5782794952 1.5125347376 3.6783154011 ) - weight 900 19 0.4918803871 ( -7.3225984573 8.4050712585 -3.7378945351 ) - weight 901 39 0.2849137783 ( 3.9505550861 4.4664311409 -1.3966503143 ) - weight 902 41 0.2232058495 ( 1.5318727493 0.5056896806 3.9030456543 ) - weight 903 19 0.3240501881 ( -7.1030936241 9.6156044006 -4.0882873535 ) - weight 904 39 0.4188577235 ( 4.1785678864 4.0356454849 -0.2139499635 ) - weight 905 41 0.2570921183 ( 0.6464938521 -0.3654011786 4.2090702057 ) - weight 906 19 0.7974441051 ( -5.0823187828 6.4326629639 -6.8444199562 ) - weight 907 39 0.20255588 ( 7.0675063133 2.3249599934 -3.4602553844 ) - weight 908 19 1 ( -5.1991491318 3.5427584648 -5.9475021362 ) - weight 909 19 0.3418679237 ( -5.9241189957 13.2698040009 -4.686214447 ) - weight 910 39 0.6581320763 ( 4.3765735626 2.262275219 3.238096714 ) - weight 911 17 0.0513280034 ( -3.6605918407 11.0743837357 -3.7854897976 ) - weight 912 19 0.9486719966 ( -3.4110982418 0.9760091305 -4.5475029945 ) - weight 913 19 1 ( -1.6152938604 2.4012238979 -8.9278745651 ) - weight 914 19 0.670599401 ( -5.0842542648 10.6949415207 -7.4311890602 ) - weight 915 39 0.3294006288 ( 7.2770662308 1.6213582754 0.7791247964 ) - weight 916 19 1 ( -5.2872533798 2.1579010487 6.5535182953 ) - weight 917 19 1 ( -3.4945862293 1.609946847 8.9752626419 ) - weight 918 19 1 ( -6.6205143929 3.899638176 7.8368425369 ) - weight 919 17 1 ( -7.8555593491 5.3238482475 -3.8014037609 ) - weight 920 17 0.490205586 ( -6.0952968597 7.5983576775 -1.4015777111 ) - weight 921 19 0.5097944736 ( -6.022685051 -1.548184514 -1.306878686 ) - weight 922 17 0.5569217801 ( -3.2434282303 8.0718507767 -3.500847578 ) - weight 923 19 0.4430782497 ( -3.0520098209 -1.768654108 -3.2793815136 ) - weight 924 19 0.057944037 ( -9.5413103104 13.5764770508 -2.117672205 ) - weight 925 39 0.4751322865 ( 2.0291101933 5.9761834145 3.9249970913 ) - weight 926 41 0.4669236541 ( -3.9896697998 -0.4543636739 2.2053706646 ) - weight 927 17 0.0714654252 ( -6.296216011 8.6028938293 4.6033258438 ) - weight 928 19 0.8564918041 ( -6.543941021 1.3533338308 4.0239572525 ) - weight 929 21 0.0720428228 ( -2.2915811539 -4.4903411865 -3.3549571037 ) - weight 930 19 1 ( -7.1283516884 2.5655679703 3.6553533077 ) - weight 931 39 1 ( -4.1167602539 2.8567140102 3.8166561127 ) - weight 932 19 0.0866496861 ( -9.8136339188 5.7926149368 0.904933095 ) - weight 933 41 0.9133503437 ( 2.3420827389 4.2363481522 -0.5704072118 ) - weight 934 19 0.0949518755 ( -4.5509228706 14.4049577713 -0.414057076 ) - weight 935 39 0.9050481319 ( -0.0581519343 1.0647397041 3.8079125881 ) - weight 936 19 0.1297236681 ( -4.0657763481 14.7400054932 -0.3888465464 ) - weight 937 39 0.8702763319 ( -0.1438155621 0.5369839072 4.0577030182 ) - weight 938 19 0.1711663008 ( -3.4669704437 14.705493927 -0.4351997674 ) - weight 939 39 0.8288336992 ( -0.1332383901 -0.05102228 3.9310343266 ) - weight 940 19 0.7626799941 ( -1.6254361868 15.3576469421 -4.648750782 ) - weight 941 39 0.2373200059 ( 3.8796200752 -2.291924715 4.5987820625 ) - weight 942 19 0.0975153446 ( -3.3897609711 13.6124639511 2.794873476 ) - weight 943 39 0.9024846554 ( -3.2532398701 0.2922571898 2.5961940289 ) - weight 944 19 0.1383740902 ( -3.2609643936 14.4725856781 1.2619138956 ) - weight 945 39 0.8616259098 ( -1.8131070137 -0.0864692107 3.5390343666 ) - weight 946 19 0.5951520205 ( -1.9623763561 14.3548383713 -1.1430112123 ) - weight 947 39 0.4048479795 ( 0.504321456 -1.5333824158 3.398225069 ) - weight 948 19 0.1065164208 ( -3.5741782188 13.2580728531 2.9878425598 ) - weight 949 39 0.8934835792 ( -3.4021139145 0.5437108278 2.262357235 ) - weight 950 19 0.4923139811 ( -1.7094359398 12.2291755676 5.8952274323 ) - weight 951 39 0.5076860189 ( -6.3219799995 -0.9084589481 0.7279627323 ) - weight 952 19 0.6383779049 ( -1.4439511299 11.7858381271 6.4904961586 ) - weight 953 39 0.3616220653 ( -6.8919119835 -1.0551947355 0.2035379857 ) - weight 954 19 0.8807009459 ( -0.4590358436 11.9974584579 6.4482426643 ) - weight 955 39 0.1192990765 ( -6.9318423271 -2.0612795353 0.2566963434 ) - weight 956 19 0.2427999973 ( -2.9859952927 12.4142818451 4.7526745796 ) - weight 957 39 0.7572000027 ( -5.1203074455 0.231706515 1.2026213408 ) - weight 958 19 0.3133231997 ( -3.0173053741 11.6713752747 5.7371592522 ) - weight 959 39 0.6866768003 ( -6.031774044 0.4538067877 0.4013722837 ) - weight 960 19 0.2284029126 ( -2.3240170479 13.5139741898 4.2428860664 ) - weight 961 39 0.7715970874 ( -4.7525925636 -0.6300441027 2.217310667 ) - weight 962 19 0.4539279342 ( -1.8042963743 13.5808095932 4.0792121887 ) - weight 963 39 0.5460720658 ( -4.6291923523 -1.1649369001 2.2120490074 ) - weight 964 19 0.5506329536 ( -1.6334135532 12.3113517761 4.7318472862 ) - weight 965 39 0.4493670762 ( -5.1776027679 -1.0861201286 0.8855163455 ) - weight 966 19 0.7576830983 ( -0.7257264256 12.1895227432 6.3317375183 ) - weight 967 39 0.2423168868 ( -6.815715313 -1.8373799324 0.4974648952 ) - weight 968 19 0.4610470533 ( -2.151403904 14.9870710373 -0.0494415238 ) - weight 969 39 0.5389529467 ( -0.6260506511 -1.3604650497 3.96717453 ) - weight 970 19 0.0757014751 ( -5.5144433975 14.5699796677 0.139491722 ) - weight 971 39 0.9242985249 ( -0.5608959198 2.0310041904 4.0828704834 ) - weight 972 19 0.0646080971 ( -4.6173129082 13.7566709518 1.8133486509 ) - weight 973 39 0.9353919029 ( -2.2112059593 1.4029548168 3.0104236603 ) - weight 974 19 0.051496923 ( -5.7953739166 14.3012447357 2.4747972488 ) - weight 975 39 0.948503077 ( -2.8406965733 2.5300927162 3.6851119995 ) - weight 976 19 0.0556442142 ( -5.2458825111 14.6230382919 1.8481531143 ) - weight 977 39 0.9443557858 ( -2.2813510895 1.8905545473 3.9613330364 ) - weight 978 19 0.0865022242 ( -7.176322937 14.4131307602 -0.1123211607 ) - weight 979 39 0.9134978056 ( -0.1898919344 3.6725828648 4.2148962021 ) - weight 980 19 0.8864985108 ( -0.8135397434 12.7714681625 -7.7247376442 ) - weight 981 39 0.1135015041 ( 7.1119527817 -2.9291677475 2.1584675312 ) - weight 982 19 0.5486282706 ( -3.0919597149 13.9394035339 -1.5272010565 ) - weight 983 39 0.4513717294 ( 0.9953490496 -0.3862626851 3.2003512383 ) - weight 984 19 0.3262838423 ( -3.1010465622 14.2815828323 -0.5684262514 ) - weight 985 39 0.6737161279 ( 0.0128353592 -0.3560836613 3.4652552605 ) - weight 986 19 0.7393954396 ( -3.6222026348 12.2014389038 -6.9090332985 ) - weight 987 39 0.2606045604 ( 6.5318007469 -0.0114976335 1.9866585732 ) - weight 988 19 0.4849961102 ( -4.6421232224 14.0900278091 -4.7689919472 ) - weight 989 39 0.51500386 ( 4.3044309616 0.8662070632 3.8454866409 ) - weight 990 19 0.7034702301 ( -2.5460412502 13.9163827896 -5.3319077492 ) - weight 991 39 0.2965297699 ( 4.744371891 -1.2149043083 3.3807137012 ) - weight 992 19 0.1573241353 ( -6.7011814117 13.6079559326 -1.8525781631 ) - weight 993 39 0.8426758647 ( 1.5800899267 3.1945934296 3.4791984558 ) - weight 994 19 0.4455580413 ( -3.8683624268 14.8221120834 -3.4969654083 ) - weight 995 39 0.5544419289 ( 2.9259557724 0.0892276838 4.3442974091 ) - weight 996 19 0.6879624724 ( -1.6253722906 15.0306892395 -4.0591115952 ) - weight 997 39 0.3120375276 ( 3.3221538067 -2.1957070827 4.2319726944 ) - weight 998 19 0.7957887053 ( -1.5359910727 15.1845941544 -5.1603279114 ) - weight 999 39 0.2042112947 ( 4.3975849152 -2.3928215504 4.4532113075 ) - weight 1000 19 0.883454442 ( -1.9995269775 10.9818029404 -10.2186746597 ) - weight 1001 39 0.1165455505 ( 9.8243732452 -1.6769949198 0.7786018848 ) - weight 1002 19 0.9208578467 ( -6.5005960464 5.8534259796 7.4430441856 ) - weight 1003 39 0.0791421309 ( -6.9931135178 4.9175553322 -4.8941607475 ) - weight 1004 17 0.906326592 ( 0.5194535851 2.7014155388 7.8136835098 ) - weight 1005 19 0.0936734006 ( 0 -3.1490647793 9.3617887497 ) - weight 1006 17 0.895146966 ( 0.5224833488 1.1002289057 7.4704799652 ) - weight 1007 18 0.1048530191 ( 0.0817569122 1.1133117676 0.6096601486 ) - weight 1008 17 0.6537598968 ( 0.520994246 4.1452364922 8.1997184753 ) - weight 1009 19 0.3462401628 ( 0 -1.6581919193 9.257183075 ) - weight 1010 17 0.3475651443 ( 0.5242241025 5.6105799675 8.6213645935 ) - weight 1011 19 0.6524348855 ( 0 -0.1353783607 9.1792993546 ) - weight 1012 17 1 ( 0.1126546264 2.0764842033 0.3691388965 ) - weight 1013 19 1 ( 0 2.8040280342 10.4248523712 ) - weight 1014 19 1 ( 0 5.5040650368 10.2014312744 ) - weight 1015 19 1 ( 0 1.8801566362 9.5358219147 ) - weight 1016 19 1 ( 0 8.6361865997 9.8544874191 ) - weight 1017 19 1 ( 0 6.9274497032 10.4384326935 ) - weight 1018 19 1 ( 0 10.4618673325 8.5257167816 ) - weight 1019 19 1 ( 0 11.8233375549 6.9349350929 ) - weight 1020 19 0.7936971188 ( 0 13.3199424744 4.4185175896 ) - weight 1021 39 0.2063028514 ( -5.0596938133 -2.8753180504 1.6393979788 ) - weight 1022 19 0.8854335546 ( 0 12.2029123306 4.7602806091 ) - weight 1023 39 0.1145664155 ( -5.3014521599 -2.675870657 0.5140838027 ) - weight 1024 19 1 ( 0 11.9971456528 6.454240799 ) - weight 1025 17 1 ( -0.1819075644 4.2549495697 -4.3683009148 ) - weight 1026 17 0.8664541245 ( -0.2160828561 6.498626709 -4.4236946106 ) - weight 1027 19 0.1335458755 ( 0 -3.5411674976 -3.4662866592 ) - weight 1028 17 0.5759524703 ( -0.1772698611 8.0659599304 -3.3391177654 ) - weight 1029 19 0.4240475297 ( 0 -1.7061650753 -2.9494576454 ) - weight 1030 19 1 ( 0 1.0677033663 -7.9638700485 ) - weight 1031 17 0.3429107964 ( -0.1620621085 9.8607501984 -2.621055603 ) - weight 1032 19 0.6570891738 ( 0 0.2246329933 -2.8538770676 ) - weight 1033 19 1 ( 0 2.3348286152 -9.1001243591 ) - weight 1034 17 0.1384361237 ( -0.2992348671 10.8270206451 -4.8391699791 ) - weight 1035 19 0.861563921 ( 0 0.4164291024 -5.2696046829 ) - weight 1036 19 1 ( 0 6.2523531914 -10.2692222595 ) - weight 1037 19 1 ( 0 14.538351059 -1.6047670841 ) - weight 1038 19 1 ( 0 15.5606851578 -4.662402153 ) - weight 1039 19 1 ( 0 15.4063825607 -4.0176739693 ) - weight 1040 19 0.8323494792 ( 0 15.0685472488 -0.9482078552 ) - weight 1041 39 0.1676505208 ( 0.1218112186 -3.5615718365 3.7702240944 ) - weight 1042 19 1 ( 0 12.7730693817 -7.7097177505 ) - weight 1043 19 1 ( 0 15.2370014191 -5.2234654427 ) - weight 1044 19 1 ( 0 11.0042772293 -10.3073549271 ) - weight 1045 5 0.0772493333 ( 6.9355874062 18.9088439941 -2.6834981441 ) - weight 1046 6 0.3773581684 ( -0.6361972094 6.158015728 4.1528887749 ) - weight 1047 7 0.3850193918 ( -1.9412107468 3.1125352383 2.2996909618 ) - weight 1048 8 0.1603731215 ( -1.8989517689 -1.9920302629 2.3064527512 ) - weight 1049 6 0.2775797844 ( 1.016530633 6.8485250473 5.0132417679 ) - weight 1050 7 0.1956718862 ( -0.6805953383 4.5590076447 2.8164937496 ) - weight 1051 8 0.5267482996 ( -0.6696657538 -0.5170930624 2.8182489872 ) - weight 1052 7 1 ( -3.2310903072 3.3491268158 -0.9709453583 ) - weight 1053 6 0.3528324366 ( -3.1226947308 6.1779670715 0.337423563 ) - weight 1054 7 0.6471675634 ( -3.1424796581 0.2486466318 -1.0313661098 ) - weight 1055 8 1 ( 0.4410169125 1.6802376509 -0.3003240824 ) - weight 1056 6 1 ( 0.4154526591 1.6135696173 -5.8964958191 ) - weight 1057 5 0.2876401842 ( -2.9136476517 19.5257854462 1.2307782173 ) - weight 1058 6 0.712359786 ( -0.3390760422 -1.9037854671 -2.7484643459 ) - weight 1059 6 1 ( -2.5542185307 0.1752854586 -5.4557042122 ) - weight 1060 6 0.9354602098 ( -2.6758725643 3.2221169472 -1.8338268995 ) - weight 1061 7 0.0645397902 ( -1.8537237644 -3.1952280998 -0.6710015535 ) - weight 1062 6 1 ( -3.7953493595 3.5296487808 -2.2768232822 ) - weight 1063 6 1 ( -4.1008143425 2.3043913841 -3.3055956364 ) - weight 1064 6 1 ( -3.692388773 0.8323549628 -4.5415811539 ) - weight 1065 8 1 ( -2.1001014709 0.726890564 -0.3198904991 ) - weight 1066 5 1 ( 2.104269743 13.8080615997 1.8265209198 ) - weight 1067 5 1 ( 0.8626697063 14.8051452637 2.8752985001 ) - weight 1068 5 1 ( -2.0396244526 13.6083145142 3.3739790916 ) - weight 1069 5 1 ( -3.4642608166 15.2237386703 2.7854971886 ) - weight 1070 5 1 ( -1.2950340509 16.8792247772 3.1730237007 ) - weight 1071 5 1 ( -2.6931531429 16.7669448853 2.8042376041 ) - weight 1072 5 1 ( 0.0708806217 17.0057163239 3.0113492012 ) - weight 1073 5 1 ( -0.8209226131 14.9327869415 2.5484933853 ) - weight 1074 5 1 ( 2.8905079365 13.0192222595 -0.0250648018 ) - weight 1075 5 1 ( 3.1424224377 12.7254056931 -1.4790248871 ) - weight 1076 5 1 ( 2.2872316837 13.5897331238 -3.8522896767 ) - weight 1077 5 0.7490617037 ( -0.7553718686 17.421913147 2.215164423 ) - weight 1078 6 0.2509383261 ( -1.1922603846 -2.2158911228 0.2893173993 ) - weight 1079 5 0.7843534946 ( 2.2506866455 15.5439929962 -3.1388113499 ) - weight 1080 6 0.2156464756 ( 2.8520693779 1.5857429504 3.5171649456 ) - weight 1081 5 0.7167745233 ( 3.2518644333 15.6483602524 -1.9323481321 ) - weight 1082 6 0.2832255065 ( 1.4129872322 1.6230846643 4.1468086243 ) - weight 1083 5 0.102107048 ( 4.6578807831 18.1112346649 -1.0448621511 ) - weight 1084 6 0.6951047182 ( -0.8211733699 3.3805441856 3.2807128429 ) - weight 1085 7 0.2027882487 ( -1.6606291533 0.4219939709 3.3912572861 ) - weight 1086 6 0.2530679703 ( 4.1275877953 6.5741434097 3.2251465321 ) - weight 1087 7 0.0652528852 ( 2.8384242058 4.0511622429 2.2598595619 ) - weight 1088 8 0.6816791892 ( 2.8594710827 -0.9513223171 2.2633750439 ) - weight 1089 6 0.2156105489 ( 4.3138685226 6.3436589241 0.9032968879 ) - weight 1090 7 0.4578246772 ( 3.7384915352 2.5404884815 0.7150121331 ) - weight 1091 8 0.3265647888 ( 3.7918236256 -2.447691679 0.7237622738 ) - weight 1092 8 1 ( 3.0128629208 0.8348042965 -0.9489415288 ) - weight 1093 6 0.3368065059 ( 3.2851471901 6.3783578873 -2.4066848755 ) - weight 1094 7 0.6631935239 ( 3.7671144009 0.3467942774 -1.9687049389 ) - weight 1095 6 1 ( 1.7162810564 0.6175383925 -2.6272804737 ) - weight 1096 6 1 ( -0.7164369822 0.5238047838 -6.0565047264 ) - weight 1097 6 0.9460912943 ( 1.0685304403 3.1448001862 -3.5778245926 ) - weight 1098 7 0.0539087057 ( 2.2400145531 -3.3702352047 -1.1989574432 ) - weight 1099 6 0.2486905903 ( 2.8629684448 6.9178786278 4.5600056648 ) - weight 1100 8 0.7513093948 ( 1.2122240067 -0.239029929 2.7910883427 ) - weight 1101 7 1 ( 3.9324524403 3.3335971832 -1.8139876127 ) - weight 1102 6 1 ( 1.5179363489 3.410220623 -4.7447609901 ) - weight 1103 5 1 ( -0.8100654483 13.8977308273 -3.4050934315 ) - weight 1104 5 1 ( -0.0858677179 15.0497436523 -4.1529512405 ) - weight 1105 5 1 ( -1.7545987368 13.7222900391 -2.6185035706 ) - weight 1106 5 1 ( -3.7521052361 13.452255249 2.0706527233 ) - weight 1107 5 1 ( 2.1322393417 14.7920036316 -4.2534852028 ) - weight 1108 5 1 ( -3.6393182278 16.6976222992 1.6754711866 ) - weight 1109 5 1 ( -3.733856678 16.7024841309 0.2749509215 ) - weight 1110 5 1 ( 4.028222084 13.7122898102 -1.7944008112 ) - weight 1111 5 1 ( 1.8625477552 12.643954277 -2.9616553783 ) - weight 1112 5 1 ( -2.048494339 11.8276615143 -1.8249468803 ) - weight 1113 5 1 ( -1.7225512266 5.9147696495 4.4733409882 ) - weight 1114 5 1 ( 0.1495314538 6.0027709007 3.878431797 ) - weight 1115 5 1 ( 2.0566430092 5.4600868225 3.7661833763 ) - weight 1116 5 1 ( 3.6026539803 2.8648166656 1.7929730415 ) - weight 1117 4 0.0944344103 ( -0.2448004782 22.2493839264 -2.7244682312 ) - weight 1118 5 0.9055656195 ( -0.2692781091 1.4510467052 -2.6645076275 ) - weight 1119 5 0.9191969633 ( -2.125562191 15.7558221817 -4.5685830116 ) - weight 1120 6 0.0808030665 ( 5.6641583443 -0.3050833941 0.3934487402 ) - weight 1121 5 0.8827454448 ( -3.0676085949 16.015253067 -3.876073122 ) - weight 1122 6 0.1172545776 ( 5.3489766121 -1.1398389339 -0.4054057598 ) - weight 1123 5 1 ( -1.8895587921 14.1454982758 -3.7821748257 ) - weight 1124 5 1 ( -1.5674954653 14.8267440796 -4.4785909653 ) - weight 1125 4 0.0954859555 ( 0.3720553815 23.4025306702 -0.2800498009 ) - weight 1126 5 0.9045140743 ( 2.4013507366 2.1047537327 -3.0192587376 ) - weight 1127 5 1 ( -0.8693459034 2.6837320328 -2.7158510685 ) - weight 1128 5 1 ( 0.3792999685 12.8329257965 -3.0005793571 ) - weight 1129 5 1 ( 3.3575675488 4.4897665977 1.3386768103 ) - weight 1130 5 1 ( 3.504846096 4.3984761238 -1.0621367693 ) - weight 1131 5 1 ( 2.637922287 4.3233594894 -0.3319391906 ) - weight 1132 5 1 ( 3.2792899609 5.188542366 -0.8997171521 ) - weight 1133 5 1 ( 2.2765028477 5.0924620628 -2.4947447777 ) - weight 1134 5 1 ( -0.2608778477 4.202167511 -2.8914825916 ) - weight 1135 5 1 ( 2.2525610924 4.3056621552 -2.6451253891 ) - weight 1136 5 1 ( 1.3189036846 4.2235078812 -1.9318430424 ) - weight 1137 5 1 ( -0.4462316334 4.225007534 -2.16284585 ) - weight 1138 4 1 ( 0.7746860981 18.144367218 3.5516023636 ) - weight 1139 4 1 ( -1.1578457355 17.664396286 3.8355109692 ) - weight 1140 4 0.9169060588 ( 0.7558166385 18.8933048248 4.0214138031 ) - weight 1141 5 0.0830939412 ( 5.8794775009 -2.9218640327 -1.7469667196 ) - weight 1142 4 0.8770711422 ( -1.1020498276 18.5250988007 4.2568383217 ) - weight 1143 5 0.1229288578 ( 5.7578883171 -2.9138281345 0.1577167511 ) - weight 1144 4 0.654335618 ( -3.3755159378 20.8853626251 2.7471702099 ) - weight 1145 5 0.345664382 ( 4.3379297256 0.0588708818 1.6292365789 ) - weight 1146 4 0.8225660324 ( -2.5272901058 17.9881591797 3.6397314072 ) - weight 1147 5 0.1774339676 ( 4.845023632 -3.046022892 1.5177307129 ) - weight 1148 5 1 ( -2.9585042 13.4222288132 2.9467895031 ) - weight 1149 4 1 ( 2.3138632774 18.1554508209 1.7360018492 ) - weight 1150 4 0.7043881416 ( 1.5729597807 21.356086731 -0.9751998782 ) - weight 1151 5 0.2956118584 ( 1.5628207922 -0.037446972 -3.9254481792 ) - weight 1152 4 0.3755814731 ( 0.0112195238 22.0369548798 -1.4311510324 ) - weight 1153 5 0.6244184971 ( 0.9928492308 1.0160213709 -2.6309051514 ) - weight 1154 4 0.8626533151 ( 2.7784559727 18.9235649109 1.4585478306 ) - weight 1155 5 0.1373466849 ( 3.7041716576 -2.9773032665 -4.1811480522 ) - weight 1156 4 0.4863468111 ( 0.0290130079 20.419916153 -2.3281507492 ) - weight 1157 5 0.5136532187 ( -0.1524644196 -0.4311223626 -2.5135409832 ) - weight 1158 4 0.617266953 ( 1.0358257294 20.5015716553 -2.3361346722 ) - weight 1159 5 0.3827330768 ( 0.0097527783 -0.5657129288 -3.5014550686 ) - weight 1160 4 0.6248319149 ( 1.2921717167 22.23412323 0.5512488484 ) - weight 1161 5 0.3751681149 ( 3.1541526318 0.6655974984 -3.5340070724 ) - weight 1162 5 1 ( -3.5182230473 5.0890407562 4.9524793625 ) - weight 1163 5 1 ( -5.125330925 4.9398303032 3.1959486008 ) - weight 1164 5 1 ( -1.4154094458 5.23082304 5.3571982384 ) - weight 1165 5 1 ( -3.2136383057 5.5779824257 4.5103478432 ) - weight 1166 5 1 ( -5.0881505013 4.9770407677 0.9784239531 ) - weight 1167 5 1 ( -4.7360014915 5.3952684402 2.8805751801 ) - weight 1168 5 1 ( -0.9684872031 4.5295906067 5.5064682961 ) - weight 1169 5 0.0995258093 ( 1.662203908 17.7509384155 -4.9855794907 ) - weight 1170 6 0.7898067236 ( 3.780479908 3.4226677418 1.4216383696 ) - weight 1171 7 0.110667482 ( 3.2743525505 0.480841428 2.8662443161 ) - weight 1172 5 0.1063148081 ( -2.1207802296 19.7758102417 -2.6203401089 ) - weight 1173 6 0.8936851621 ( 2.4857244492 0.8340483904 -2.5315992832 ) - weight 1174 5 1 ( -4.2934184074 10.1069526672 3.3138370514 ) - weight 1175 5 1 ( -2.5899543762 10.1437473297 4.2293992043 ) - weight 1176 5 1 ( -4.2699742317 8.7750883102 4.414700985 ) - weight 1177 5 1 ( -0.896458149 8.3218650818 4.6289658546 ) - weight 1178 5 1 ( 0.3682994246 9.9554424286 3.9135465622 ) - weight 1179 5 1 ( 2.3701901436 9.6355848312 2.3855106831 ) - weight 1180 5 1 ( 2.0288498402 10.1795930862 1.9184105396 ) - weight 1181 5 1 ( 0.5099385977 10.6941623688 3.014092207 ) - weight 1182 5 1 ( 2.2596232891 7.5083928108 2.5266880989 ) - weight 1183 5 1 ( -4.5968909264 9.8963222504 1.2540916204 ) - weight 1184 5 1 ( -3.2063951492 11.2567272186 1.4226033688 ) - weight 1185 5 1 ( -2.0835285187 11.4152135849 2.7410218716 ) - weight 1186 5 1 ( -3.0089509487 10.6117181778 -0.5483562946 ) - weight 1187 5 1 ( -4.7889208794 8.202460289 0.5818423033 ) - weight 1188 5 1 ( -3.881572485 9.6545791626 -0.7520799041 ) - weight 1189 5 1 ( -5.0881595612 8.7070827484 3.1567678452 ) - weight 1190 5 1 ( -2.0462095737 9.1960659027 -2.5867063999 ) - weight 1191 5 1 ( -1.6649211645 9.9800834656 -2.2770884037 ) - weight 1192 5 1 ( 3.1572799683 9.6367607117 -1.442193985 ) - weight 1193 5 1 ( 2.0805270672 9.5653982162 -2.7649805546 ) - weight 1194 4 1 ( 1.6225969791 15.7898540497 -4.2202334404 ) - weight 1195 4 1 ( 2.3269748688 16.7183456421 0.6146816611 ) - weight 1196 4 1 ( 2.340490818 16.5626525879 -2.9631495476 ) - weight 1197 4 0.8935781121 ( 1.5288146734 17.6302509308 -3.5205104351 ) - weight 1198 5 0.1064219028 ( -1.5549808741 -3.2889606953 -3.6620447636 ) - weight 1199 4 0.8599565029 ( -6.2631754875 17.3383979797 1.7552473545 ) - weight 1200 5 0.1400434971 ( 2.321388483 -2.6233105659 4.8915848732 ) - weight 1201 4 0.7713285685 ( -5.8933882713 18.2386894226 2.0838477612 ) - weight 1202 5 0.2286714315 ( 2.8516919613 -1.875472784 4.4281597137 ) - weight 1203 4 0.6509902477 ( -2.7651283741 18.485584259 -6.5357074738 ) - weight 1204 5 0.3490097523 ( -5.0093669891 -1.138027668 -0.2412763387 ) - weight 1205 4 0.5030454993 ( -5.7292814255 18.6685504913 -5.0557985306 ) - weight 1206 5 0.4969545305 ( -3.9976181984 -0.5290729403 2.8595862389 ) - weight 1207 4 0.7249910831 ( -6.0907945633 17.2753696442 -5.1007180214 ) - weight 1208 5 0.2750089169 ( -4.3344483376 -1.7939556837 3.4598197937 ) - weight 1209 4 0.6980623603 ( 1.237295866 18.7613372803 -3.9902939796 ) - weight 1210 5 0.3019376695 ( -1.8648725748 -2.0688369274 -3.6793456078 ) - weight 1211 4 0.661098361 ( -5.7626075745 18.7943973541 1.7776662111 ) - weight 1212 5 0.338901639 ( 2.6685707569 -1.3242530823 4.1413064003 ) - weight 1213 4 0.7913669944 ( -0.1645787358 18.0434989929 -5.4681735039 ) - weight 1214 5 0.2086330354 ( -3.6425523758 -2.2646536827 -2.468485117 ) - weight 1215 4 0.5249487162 ( -6.8781695366 19.4281616211 1.2342784405 ) - weight 1216 5 0.475051254 ( 2.0746688843 -0.3996763825 4.9979529381 ) - weight 1217 4 0.9213094711 ( -7.0403594971 15.7653608322 1.182415843 ) - weight 1218 5 0.0786905214 ( 1.3757749796 -3.902203083 5.8279857635 ) - weight 1219 4 0.9338607788 ( -4.8067159653 11.7147073746 -5.5744233131 ) - weight 1220 5 0.0661392212 ( -5.5425815582 -7.3841910362 3.1701798439 ) - weight 1221 4 1 ( 0.4255798459 15.4466333389 3.3929886818 ) - weight 1222 4 1 ( 2.3584513664 12.5087146759 2.2568845749 ) - weight 1223 3 0.5226224661 ( 4.5210051537 -2.8630027771 5.1874666214 ) - weight 1224 4 0.4773775041 ( 4.3348898888 1.3320757151 0.9743085504 ) - weight 1225 3 0.3407817781 ( 2.3781831264 -6.9575843811 -5.0705609322 ) - weight 1226 4 0.6592182517 ( -4.5130314827 4.2813305855 -5.3185925484 ) - weight 1227 3 0.4126182199 ( 0.6710220575 -6.7529602051 -3.2513923645 ) - weight 1228 4 0.5873817801 ( -2.2055294514 3.9156365395 -6.2171173096 ) - weight 1229 3 0.4119746685 ( 2.4439246655 -5.2881507874 4.8690805435 ) - weight 1230 4 0.5880253315 ( 4.7635946274 3.3402681351 -1.4915282726 ) - weight 1231 3 0.6267764568 ( 1.1631516218 -6.7135238647 2.4224381447 ) - weight 1232 4 0.3732235432 ( 2.924438715 4.3538002968 -3.782463789 ) - weight 1233 3 0.1250320077 ( 5.548268795 -8.981716156 -5.383043766 ) - weight 1234 4 0.8749679923 ( -5.9392027855 6.7889728546 -2.8850836754 ) - weight 1235 3 0.1838332713 ( 1.2151947021 -10.2311553955 -3.6204602718 ) - weight 1236 4 0.8161666989 ( -2.7591481209 7.4016418457 -6.4844198227 ) - weight 1237 3 0.0663084388 ( 5.0440044403 -9.1647224426 5.3758664131 ) - weight 1238 4 0.9336915612 ( 4.297413826 7.6285309792 0.3628000021 ) - weight 1239 3 0.2613720298 ( 1.540268898 -9.4691123962 1.9814689159 ) - weight 1240 4 0.7386279702 ( 2.3660974503 7.0960884094 -4.0955934525 ) - weight 1241 3 0.3120176494 ( 0.4770362675 -9.0535240173 -1.5733042955 ) - weight 1242 4 0.6879823208 ( -0.5780690312 6.2602667809 -6.2340216637 ) - weight 1243 4 1 ( 1.0753076077 11.2008686066 3.198731184 ) - weight 1244 3 0.1108867526 ( 8.5155363083 -7.8049240112 4.1910905838 ) - weight 1245 4 0.8891132474 ( 1.9637942314 6.8007597923 3.3915445805 ) - weight 1246 4 0.9323524833 ( -7.0678682327 12.84973526 -0.9881807566 ) - weight 1247 5 0.0676475167 ( -1.2369278669 -6.4239754677 5.9940156937 ) - weight 1248 4 0.9057416916 ( -7.5516734123 14.1976165771 -3.1757831573 ) - weight 1249 5 0.0942583084 ( -3.2114238739 -4.7207875252 5.801735878 ) - weight 1250 4 0.5097686648 ( -8.0624351501 18.9518413544 -0.5080246329 ) - weight 1251 5 0.490231365 ( 0.1145020127 -0.3724427521 5.904589653 ) - weight 1252 3 0.2257421017 ( 8.6921253204 -5.6849021912 -1.9335128069 ) - weight 1253 4 0.7742578983 ( -3.8153269291 4.3225250244 1.8114966154 ) - weight 1254 3 0.755829215 ( 2.5996456146 -3.1819915771 5.2685208321 ) - weight 1255 4 0.2441708148 ( 5.0911245346 1.3241738081 -0.8223528862 ) - weight 1256 3 0.3560082912 ( 9.2955503464 -4.163143158 -0.6279870272 ) - weight 1257 4 0.6439917088 ( -2.8021838665 3.0198731422 3.1002590656 ) - weight 1258 3 0.6028003693 ( 1.4196438789 -5.479839325 -4.5613222122 ) - weight 1259 4 0.3971996009 ( -3.6902012825 2.7008731365 -5.7509770393 ) - weight 1260 3 0.8913513422 ( 1.5633721352 -4.9879570007 5.1678905487 ) - weight 1261 4 0.1086486876 ( 5.3567857742 2.9159967899 -2.141831398 ) - weight 1262 3 0.8820733428 ( 1.5458381176 -1.6829986572 7.1447806358 ) - weight 1263 17 0.1179266572 ( 2.0648140907 -3.9439475536 6.1096639633 ) - weight 1264 3 0.9283687472 ( 1.6073291302 -4.1433410645 6.2953686714 ) - weight 1265 4 0.0716312751 ( 6.3990149498 2.1713774204 -1.5537701845 ) - weight 1266 3 0.6439720392 ( 4.2982382774 -2.0082244873 7.3487462997 ) - weight 1267 4 0.2472280413 ( 6.4383196831 0.6036970615 1.6788995266 ) - weight 1268 17 0.1087999046 ( 4.8243842125 -4.2705850601 6.075586319 ) - weight 1269 3 0.6023227572 ( 9.5180206299 -1.333480835 1.1821365356 ) - weight 1270 4 0.2356233895 ( -1.176284194 0.401712805 4.4547762871 ) - weight 1271 17 0.162053898 ( 9.681558609 -2.0602145195 -0.0277409032 ) - weight 1272 3 0.5815145373 ( 9.3864803314 -1.9524116516 1.9860262871 ) - weight 1273 4 0.3509689569 ( -0.3807979524 1.0434114933 4.4999580383 ) - weight 1274 17 0.0675165281 ( 9.5963830948 -2.8560984135 0.6093864441 ) - weight 1275 3 0.615749836 ( 7.5035843849 -2.0293502808 4.8258552551 ) - weight 1276 4 0.3239196539 ( 2.9420316219 0.9952923059 3.7434313297 ) - weight 1277 17 0.0603304803 ( 7.8796153069 -3.6399018764 3.4473795891 ) - weight 1278 3 0.5772765279 ( 8.9240169525 0.1087417603 0.8441859484 ) - weight 1279 4 0.094845064 ( -1.2750173807 -1.1404762268 4.0560760498 ) - weight 1280 17 0.3278784454 ( 9.0691337585 -0.5874040127 0.0253832974 ) - weight 1281 3 0.7094534636 ( 3.8729000092 -0.8295249939 -8.9261922836 ) - weight 1282 17 0.2905465364 ( 3.4654686451 0.7822611928 -9.3861713409 ) - weight 1283 3 0.4537308812 ( 3.9236824512 1.0521888733 -8.9932060242 ) - weight 1284 17 0.5462691188 ( 3.5123205185 2.6253633499 -9.0005607605 ) - weight 1285 3 0.3106232285 ( 2.458206892 1.9493141174 8.0350952148 ) - weight 1286 17 0.6893767715 ( 3.0267877579 -0.6201750636 7.7966485023 ) - weight 1287 3 0.2235922813 ( 5.1096987724 2.0013809204 7.7044014931 ) - weight 1288 17 0.7764077187 ( 5.654923439 -0.4534242153 7.3410429955 ) - weight 1289 17 1 ( 4.8672480583 1.3290891647 7.2130708694 ) - weight 1290 3 0.4141060114 ( 5.1330666542 1.2630386353 7.5839781761 ) - weight 1291 17 0.5858939886 ( 5.6713395119 -1.1407259703 7.045165062 ) - weight 1292 3 0.3944361806 ( 2.7175819874 1.1817436218 7.8684301376 ) - weight 1293 17 0.6055638194 ( 3.2761673927 -1.32145679 7.4357733727 ) - weight 1294 3 0.5463812351 ( 9.0013618469 0.7265815735 -2.6053204536 ) - weight 1295 17 0.4536187649 ( 8.9483289719 0.843044579 -3.1724326611 ) - weight 1296 2 0.0525413826 ( 7.2182264328 3.4171409607 -4.4578661919 ) - weight 1297 3 0.0612702444 ( 7.1502876282 3.4065132141 -4.3001909256 ) - weight 1298 17 0.8861883879 ( 7.0030117035 3.826107502 -4.0658369064 ) - weight 1299 4 0.4810909033 ( 0.5828952193 19.8544960022 -4.1859664917 ) - weight 1300 5 0.5189090967 ( -1.9707285166 -0.8451013565 -3.2884616852 ) - weight 1301 4 0.4008352458 ( -3.8144423962 19.4866962433 -6.6175451279 ) - weight 1302 5 0.599164784 ( -5.0813336372 0.0654560998 0.5689274669 ) - weight 1303 4 0.1214690804 ( -7.2442059517 21.4261608124 -3.199338913 ) - weight 1304 5 0.8785309196 ( -1.9566363096 2.2111718655 4.1523766518 ) - weight 1305 5 1 ( -4.1878781319 3.4777452946 2.181283474 ) - weight 1306 5 1 ( -4.0796403885 2.88412714 -0.4037202895 ) - weight 1307 4 0.0571544766 ( -1.3781067133 22.8463935852 -4.7168483734 ) - weight 1308 5 0.9428455234 ( -2.2822625637 2.5397832394 -2.0538299084 ) - weight 1309 5 1 ( -2.4310252666 3.1694676876 4.0180592537 ) - weight 1310 4 0.2063748837 ( 0.6114964485 21.6057815552 -2.7492108345 ) - weight 1311 5 0.7936251163 ( -0.2701180279 0.6490582228 -3.3750665188 ) - weight 1312 5 1 ( -0.878950119 2.6256654263 4.7856736183 ) - weight 1313 3 0.1783798933 ( 10.1692819595 -6.8604316711 0.3459020853 ) - weight 1314 4 0.8216201067 ( -2.2137639523 5.8874320984 3.7468664646 ) - weight 1315 5 1 ( -3.5107929707 7.1544299126 -0.9511592388 ) - weight 1316 5 1 ( -1.2094997168 3.9121067524 -2.2402222157 ) - weight 1317 5 1 ( -3.1296360493 7.4151477814 -2.6844007969 ) - weight 1318 5 1 ( -1.8017199039 6.6393055916 -3.6088409424 ) - weight 1319 5 1 ( -1.4778610468 5.2404136658 -3.8496501446 ) - weight 1320 5 1 ( -2.1072573662 4.0550179482 -3.5148129463 ) - weight 1321 5 1 ( -3.312766552 3.7765133381 -2.8071403503 ) - weight 1322 5 1 ( -4.4635181427 4.7800736427 -2.086782217 ) - weight 1323 6 1 ( -2.1370241642 -1.1222180128 -3.3506839275 ) - weight 1324 6 1 ( -0.5658060908 -1.1267360449 -4.0579733849 ) - weight 1325 6 1 ( -2.9217739105 -0.0591393709 -2.0328450203 ) - weight 1326 6 1 ( 0.7693743706 -0.4285986722 -4.0102496147 ) - weight 1327 6 0.1469175518 ( -0.9245644212 8.0665035248 4.2226190567 ) - weight 1328 7 0.8530824184 ( -2.3673853874 4.5443754196 1.0755363703 ) - weight 1329 6 0.2691477239 ( -2.0999734402 6.0272164345 1.9594042301 ) - weight 1330 7 0.7308522463 ( -2.654638052 1.3487360477 0.4690739512 ) - weight 1331 6 1 ( 2.0763778687 1.8456496 -2.518409729 ) - weight 1332 8 1 ( -0.4472899437 1.0112099648 1.4965937138 ) - weight 1333 8 1 ( 2.5165486336 0.7591984272 1.0422780514 ) - weight 1334 7 0.3830572069 ( 3.7322149277 4.2597174644 0.2420522869 ) - weight 1335 8 0.6169427633 ( 3.7487363815 -0.7306381464 0.2448583692 ) - weight 1336 5 1 ( 3.2782211304 10.4518594742 0.2345400155 ) - weight 1337 5 1 ( 0.352648139 10.2063922882 -3.2412974834 ) - weight 1338 5 1 ( 1.6682488918 13.3981027603 2.1721248627 ) - weight 1339 5 1 ( 3.652967453 13.08735466 0.8763127327 ) - weight 1340 3 0.60470891 ( 6.9311394691 0.2659263611 4.7454075813 ) - weight 1341 4 0.1477793157 ( 3.0801765919 -1.3639061451 3.6109232903 ) - weight 1342 17 0.2475117892 ( 7.3034963608 -1.400808692 3.9543392658 ) - weight 1343 5 1 ( -4.5623869896 7.1684999466 3.9666895866 ) - weight 1344 5 1 ( -4.4641895294 6.8975949287 1.2760201693 ) - weight 1345 5 1 ( -2.1210997105 7.0766324997 4.4080858231 ) - weight 1346 4 0.1127029806 ( -7.5810952187 21.1954135895 -0.782112956 ) - weight 1347 5 0.8872970343 ( 0.3041761518 1.7328647375 4.9707098007 ) - weight 1348 4 0.1564201862 ( -5.1138968468 21.4935340881 1.1991686821 ) - weight 1349 5 0.8435798287 ( 2.6654806137 1.2273346186 2.9042875767 ) - weight 1350 5 1 ( 3.2564399242 2.4832935333 2.4041802883 ) - weight 1351 5 1 ( 2.8671550751 3.936040163 2.7010238171 ) - weight 1352 5 1 ( 0.9485575557 4.3144721985 4.8201656342 ) - weight 1353 5 1 ( 1.2667204142 3.0631227493 6.2410588264 ) - weight 1354 5 1 ( 1.3877271414 1.7745479345 6.3324046135 ) - weight 1355 4 0.0979859829 ( -7.6941308975 20.7632484436 1.3950991631 ) - weight 1356 5 0.9020140171 ( 2.3318519592 1.0443909168 5.5659666061 ) - weight 1357 4 0.1117024943 ( -6.379242897 21.4460468292 2.3763875961 ) - weight 1358 5 0.8882974982 ( 3.606828928 1.2920020819 4.3530387878 ) - weight 1359 5 1 ( 4.229537487 2.4456539154 3.7436652184 ) - weight 1360 5 1 ( 3.8621149063 3.8132314682 4.017472744 ) - weight 1361 5 1 ( 2.850070715 4.5555472374 4.8407993317 ) - weight 1362 5 1 ( 1.8023693562 4.2357888222 5.7209253311 ) - weight 1363 5 1 ( 2.6485412121 7.4402632713 1.0672787428 ) - weight 1364 5 1 ( 2.5837745667 6.3442721367 -0.6233466864 ) - weight 1365 5 1 ( 1.37802279 6.2354869843 -2.1077165604 ) - weight 1366 5 1 ( 2.5637817383 9.0058193207 1.024225235 ) - weight 1367 5 1 ( 3.0018618107 10.7806806564 1.1646435261 ) - weight 1368 5 1 ( 3.5934970379 6.3966078758 1.3023967743 ) - weight 1369 4 1 ( 1.1633307934 16.7673015594 2.7058975697 ) - weight 1370 5 1 ( -3.8327929974 13.396238327 1.1877777576 ) - weight 1371 5 1 ( -4.1629199982 14.6708211899 1.6496021748 ) - weight 1372 5 1 ( -2.4852693081 14.6146764755 3.5301582813 ) - weight 1373 5 1 ( -0.3751538098 6.0833444595 -3.3862018585 ) - weight 1374 5 1 ( 3.8464910984 6.2431206703 0.2100706697 ) - weight 1375 5 1 ( 0.7290213108 6.0003066063 -3.4577474594 ) - weight 1376 5 1 ( 3.6466805935 6.1667761803 -1.5993791819 ) - weight 1377 5 1 ( 2.5240468979 6.0827975273 -2.9682133198 ) - weight 1378 5 1 ( 3.8898243904 12.7316913605 -0.2237233669 ) - weight 1379 5 1 ( 3.8443069458 12.3161296844 -2.0352976322 ) - weight 1380 5 1 ( 2.6564259529 12.2394762039 -3.4955608845 ) - weight 1381 5 1 ( 0.774928391 12.4884548187 -3.9085876942 ) - weight 1382 5 1 ( -3.2273137569 4.3247013092 4.8094992638 ) - weight 1383 5 1 ( -4.8211283684 4.1704277992 3.0763905048 ) - weight 1384 5 1 ( 2.3121359348 4.7184886932 4.0702018738 ) - weight 1385 5 1 ( 0.1309463978 3.1198656559 4.9630079269 ) - weight 1386 5 1 ( -5.1099247932 4.1994366646 0.6826284528 ) - weight 1387 5 1 ( -3.8831179142 4.4496417046 -1.2984983921 ) - weight 1388 5 1 ( -3.9903991222 5.942243576 -0.4982332587 ) - weight 1389 5 1 ( -2.3862202168 7.5177755356 -2.261105299 ) - weight 1390 5 1 ( 3.1181900501 5.4344820976 1.3478331566 ) - weight 1391 5 1 ( 2.9915220737 4.3416147232 1.5175254345 ) - weight 1392 5 1 ( -0.3854646683 12.7791929245 -3.9055070877 ) - weight 1393 5 1 ( -0.6283808947 10.4730806351 -3.1622338295 ) - weight 1394 5 1 ( -1.4896155596 11.2336483002 -2.1449124813 ) - weight 1395 5 1 ( 2.8856470585 6.5548405647 1.2341843843 ) - weight 1396 5 1 ( 3.0285086632 14.5907888412 -4.0568151474 ) - weight 1397 5 1 ( 2.5414946079 13.3914079666 0.6928366423 ) - weight 1398 5 1 ( 0.7024942636 13.348400116 1.8402805328 ) - weight 1399 5 1 ( 4.303940773 14.6853284836 -2.5447614193 ) - weight 1400 4 0.9364672303 ( -1.6958599091 17.3909835815 2.7929236889 ) - weight 1401 5 0.0635327697 ( 4.0482411385 -3.6866235733 0.6693513989 ) - weight 1402 4 0.7988651991 ( -2.7518396378 17.6752719879 2.6435346603 ) - weight 1403 5 0.2011348009 ( 3.7875256538 -3.1661820412 1.6071135998 ) - weight 1404 4 0.5771669745 ( -3.5403409004 20.3627681732 2.3067491055 ) - weight 1405 5 0.4228330255 ( 3.7948560715 -0.3520902097 1.8036645651 ) - weight 1406 4 0.3044187725 ( -3.9295914173 21.2870388031 1.2646981478 ) - weight 1407 5 0.6955811977 ( 2.8777215481 0.7661437392 1.812605381 ) - weight 1408 4 1 ( 0.6033952832 17.8546047211 2.0907402039 ) - weight 1409 4 1 ( 2.2900784016 17.5862426758 -0.3613339365 ) - weight 1410 4 0.8178261518 ( 2.0264077187 17.8224544525 -1.493745923 ) - weight 1411 5 0.182173878 ( 0.527202189 -3.4831557274 -3.8003091812 ) - weight 1412 5 0.1172697619 ( 4.3399119377 17.0443344116 -3.0355508327 ) - weight 1413 6 0.6770974398 ( 1.3802000284 3.6789526939 3.7975585461 ) - weight 1414 7 0.2056327909 ( 0.252748698 1.498986721 4.0087471008 ) - weight 1415 5 0.0709621161 ( 3.4628479481 17.0006370544 -4.08934021 ) - weight 1416 6 0.7818242311 ( 2.6199462414 3.6706302166 3.2105462551 ) - weight 1417 7 0.1472136676 ( 1.6098921299 1.4485735893 3.8157606125 ) - weight 1418 5 0.357545346 ( 3.5840806961 16.5214252472 -4.4845638275 ) - weight 1419 6 0.5105105639 ( 3.0882651806 3.7010807991 3.6351542473 ) - weight 1420 7 0.1319440752 ( 1.9233599901 1.8394159079 4.2024412155 ) - weight 1421 5 0.3325402141 ( 4.7685413361 16.5839862823 -3.0836625099 ) - weight 1422 6 0.5499057174 ( 1.4312735796 3.7263586521 4.424536705 ) - weight 1423 7 0.1175540611 ( 0.1070246845 1.9204907417 4.4549045563 ) - weight 1424 5 0.4304984212 ( 4.6754350662 17.7426967621 -0.451398313 ) - weight 1425 6 0.5104330778 ( -1.1838850975 2.8672299385 3.5861237049 ) - weight 1426 7 0.059068501 ( -2.0630085468 0.1212874874 3.8770487309 ) - weight 1427 5 0.3538155556 ( 1.152330637 17.1743412018 -5.0760302544 ) - weight 1428 6 0.5456925631 ( 4.2751846313 2.832349062 1.5076986551 ) - weight 1429 7 0.1004918665 ( 3.758620739 0.2016397119 3.4030368328 ) - weight 1430 5 1 ( -1.6448326111 12.4533481598 2.1622643471 ) - weight 1431 5 1 ( -2.5923762321 12.3437929153 0.9611747861 ) - weight 1432 5 1 ( -2.6468617916 15.216094017 3.1559422016 ) - weight 1433 5 1 ( -3.4386959076 15.3783750534 1.8783024549 ) - weight 1434 5 1 ( -2.489700079 3.616584301 -1.4956499338 ) - weight 1435 5 1 ( -0.4269738495 5.1550660133 -2.8048391342 ) - weight 1436 5 1 ( -0.4701639414 6.2825074196 -2.7287414074 ) - weight 1437 5 1 ( -0.8215753436 9.7685937881 -2.463745594 ) - weight 1438 5 1 ( -1.0354841948 6.6805539131 -2.8075251579 ) - weight 1439 5 1 ( -2.1368255615 11.8210735321 -1.1061005592 ) - weight 1440 3 0.5825697184 ( 7.7756619453 0.2518005371 -1.944960475 ) - weight 1441 17 0.4174302518 ( 7.7625589371 0.2064550668 -2.5786850452 ) - weight 1442 5 1 ( 1.351006031 12.0735931396 2.2025308609 ) - weight 1443 5 1 ( 3.0850484371 14.4694309235 2.3129010201 ) - weight 1444 5 1 ( 2.388556242 14.8004264832 3.0345108509 ) - weight 1445 5 1 ( 0.6146295667 16.5243091583 3.1264028549 ) - weight 1446 5 0.9486664534 ( 2.4974191189 16.7393741608 3.4217340946 ) - weight 1447 6 0.0513335578 ( -3.2013783455 -1.1757239103 3.0066349506 ) - weight 1448 5 0.9489473701 ( 4.0137782097 15.9226989746 2.1694192886 ) - weight 1449 6 0.0510526337 ( -2.4254543781 0.0247746576 4.5850334167 ) - weight 1450 5 1 ( 1.9721335173 15.6841220856 3.5195548534 ) - weight 1451 5 0.901320219 ( 3.6295182705 16.5782585144 2.7116913795 ) - weight 1452 6 0.0986797214 ( -2.9828643799 -0.1567517817 3.8585236073 ) - weight 1453 5 1 ( 3.7621896267 15.1197729111 2.1693861485 ) - weight 1454 5 0.9036762714 ( 3.7302186489 15.7333068848 0.6004226208 ) - weight 1455 6 0.0963237435 ( -0.9278099537 0.5950239301 4.4855213165 ) - weight 1456 5 0.25 ( -1.6991760731 19.4681587219 2.3327729702 ) - weight 1457 6 0.75 ( -1.7110059261 -1.76235497 -1.8593860865 ) - weight 1458 5 0.8230245113 ( -1.8291454315 17.2562294006 1.8988302946 ) - weight 1459 6 0.1769755185 ( -0.4475976825 -2.8175451756 -0.3140051663 ) - weight 1460 5 0.3717112839 ( -0.5667885542 19.4145832062 2.5892217159 ) - weight 1461 6 0.6282887459 ( -2.3439846039 -1.2106134892 -1.0557337999 ) - weight 1462 6 1 ( -2.2401411533 0.4269585013 -0.5985571742 ) - weight 1463 5 1 ( 4.3196249008 14.9650468826 -1.6217439175 ) - weight 1464 5 1 ( 0.5186161995 12.3493032455 2.2358272076 ) - weight 1465 5 0.7532988191 ( 3.481030941 17.0108261108 0.6878813505 ) - weight 1466 6 0.246701166 ( -1.3951478004 1.0869412422 3.3713343143 ) - weight 1467 3 0.7483199835 ( 2.2808992863 -4.013671875 5.5935192108 ) - weight 1468 4 0.2516800463 ( 5.5043897629 2.1099462509 -1.1550529003 ) - weight 1469 3 0.888089776 ( 0.9945722222 -6.6571540833 4.2814383507 ) - weight 1470 4 0.1119101942 ( 4.7224898338 4.3985080719 -3.2799785137 ) - weight 1471 3 0.7350515723 ( 1.7938239574 -5.3760185242 4.5010042191 ) - weight 1472 4 0.2649484277 ( 4.6498060226 3.2904675007 -2.233420372 ) - weight 1473 3 0.8052905798 ( 2.5846002102 -1.5636558533 5.8292813301 ) - weight 1474 4 0.1022787392 ( 5.6279087067 -0.2302984297 -0.3436375558 ) - weight 1475 17 0.0924307182 ( 3.0263457298 -3.4973247051 4.8059029579 ) - weight 1476 5 1 ( -3.2235546112 14.7460422516 -2.772039175 ) - weight 1477 5 1 ( -3.5301985741 15.6403837204 -3.0164139271 ) - weight 1478 5 1 ( -2.5234622955 14.0347566605 -2.7247803211 ) - weight 1479 5 0.6971091032 ( -2.5157797337 17.1038093567 0.8313326836 ) - weight 1480 6 0.3028909266 ( 0.7716283202 -2.7566308975 -0.6935147047 ) - weight 1481 5 0.2251555175 ( -3.0799901485 19.2364559174 -0.3555200696 ) - weight 1482 6 0.7748444676 ( 1.1660437584 -1.304133296 -2.6959688663 ) - weight 1483 5 1 ( 0.3722975552 14.6224975586 -3.9375119209 ) - weight 1484 5 1 ( -0.9475761056 15.6293535233 3.0329756737 ) - weight 1485 5 0.8075404167 ( 0.6941460371 17.367855072 2.303576231 ) - weight 1486 6 0.1924596131 ( -1.8070422411 -1.3711123466 1.2993831635 ) - weight 1487 6 1 ( -2.7563483715 1.8655918837 -0.094848074 ) - weight 1488 6 1 ( -2.5631649494 1.9458229542 -0.3665916622 ) - weight 1489 6 0.7385284901 ( 2.9947731495 4.390709877 -1.4334517717 ) - weight 1490 7 0.2614715397 ( 3.3312115669 -0.6680801511 -0.0290495194 ) - weight 1491 6 0.6177253723 ( 3.1328260899 4.5455322266 2.8736019135 ) - weight 1492 7 0.3822745979 ( 2.1397197247 2.0443272591 3.1041493416 ) - weight 1493 6 0.5818145275 ( 1.1143350601 4.5579762459 3.8530673981 ) - weight 1494 7 0.4181855023 ( -0.0770615935 2.1396598816 3.4367234707 ) - weight 1495 6 0.5504769087 ( -0.5401303172 4.6905021667 3.4742810726 ) - weight 1496 7 0.4495231211 ( -1.5425099134 1.6091682911 2.7516412735 ) - weight 1497 6 0.5998160839 ( 3.9822556973 4.6996765137 0.5799119473 ) - weight 1498 7 0.4001839161 ( 3.6348011494 1.0079637766 1.4618984461 ) - weight 1499 6 0.514654398 ( -1.9074280262 4.9122614861 2.4463167191 ) - weight 1500 7 0.4853456616 ( -2.5435211658 0.8317744732 1.5815871954 ) - weight 1501 5 0.0641056076 ( 1.6486455202 20.0048046112 1.8856242895 ) - weight 1502 6 0.9358943701 ( -2.8389790058 0.9048441052 -0.0401646942 ) - weight 1503 5 0.0929720625 ( 3.6915407181 19.5849266052 0.7362514138 ) - weight 1504 6 0.8028796315 ( -2.5056433678 2.6012120247 1.5975164175 ) - weight 1505 7 0.1041482985 ( -2.6946485043 -1.5893549919 2.3127269745 ) - weight 1506 6 0.6469980478 ( -2.4940507412 3.2530550957 0.4257948995 ) - weight 1507 7 0.3530019224 ( -2.3714435101 -1.7838140726 1.0259910822 ) - weight 1508 5 0.221952945 ( -0.8453344107 19.3779964447 -4.2301344872 ) - weight 1509 6 0.7780470252 ( 3.4937524796 2.3047447205 -1.4373477697 ) - weight 1510 5 1 ( -0.7928808331 12.9620494843 -2.6813831329 ) - weight 1511 6 1 ( 2.7456257343 2.0124146938 -2.3290300369 ) - weight 1512 5 0.6193848848 ( -1.5239847898 17.8485336304 -3.4574520588 ) - weight 1513 6 0.3806150854 ( 3.6962614059 0.6164066195 -0.7264544964 ) - weight 1514 5 0.7943415046 ( 0.4985198975 15.9463949203 -3.7686667442 ) - weight 1515 6 0.205658555 ( 3.9041395187 1.0334924459 2.0282390118 ) - weight 1516 5 0.86826998 ( -3.2826039791 16.7336158752 -1.1647691727 ) - weight 1517 6 0.1317299902 ( 2.883866787 -2.3601989746 -0.9948053956 ) - weight 1518 5 0.5162470341 ( -2.6479344368 17.5744571686 -1.6726512909 ) - weight 1519 6 0.4837529361 ( 2.7408647537 -1.2203159332 -1.2138565779 ) - weight 1520 5 0.5819576979 ( 2.3704199791 17.5650177002 1.8794186115 ) - weight 1521 6 0.4180422723 ( -2.1764955521 0.0343063325 2.2569732666 ) - weight 1522 4 0.8398042917 ( -2.0773439407 17.0067443848 -6.2636594772 ) - weight 1523 5 0.1601957083 ( -4.8896398544 -2.7523932457 -0.5781915784 ) - weight 1524 4 1 ( -6.7837600708 9.7420730591 -3.2796785831 ) - weight 1525 5 1 ( -3.2106053829 14.975438118 -1.479516983 ) - weight 1526 5 1 ( -1.9164733887 12.959113121 -2.0818612576 ) - weight 1527 4 0.6834487915 ( -7.3610773087 18.217590332 -0.6974437833 ) - weight 1528 5 0.3165512383 ( -0.0860380307 -1.2068376541 5.3297190666 ) - weight 1529 3 0.4456541538 ( 7.0214524269 -2.3929901123 4.3822588921 ) - weight 1530 4 0.5543458462 ( 2.6968035698 1.2399263382 3.0789914131 ) - weight 1531 3 0.682189703 ( 3.6369364262 -2.0150985718 6.144033432 ) - weight 1532 4 0.2551205456 ( 5.5466976166 0.4144032001 0.65036726 ) - weight 1533 17 0.062689811 ( 4.095015049 -3.9966232777 4.9434790611 ) - weight 1534 17 0.8284341097 ( 2.636146307 0.780561626 7.7648005486 ) - weight 1535 18 0.1715659201 ( 2.1711149216 0.8739738464 1.0930681229 ) - weight 1536 3 0.5035423636 ( 8.4498071671 -1.8765449524 1.5924158096 ) - weight 1537 4 0.4964576364 ( -0.4160282314 0.7821130157 3.5158224106 ) - weight 1538 3 0.5111525059 ( 8.3219251633 0.493183136 -0.6540173292 ) - weight 1539 17 0.4888474941 ( 8.3820295334 0.1377604008 -1.3001152277 ) - weight 1540 3 0.2529966235 ( 9.6126346588 0.9142570496 -0.6379578114 ) - weight 1541 17 0.7470033765 ( 9.6715326309 0.5604189634 -1.2550143003 ) - weight 1542 17 1 ( 8.833067894 2.2275571823 1.6158591509 ) - weight 1543 3 0.5771152973 ( 6.4818458557 -0.2328224182 -4.8620820045 ) - weight 1544 4 0.1738158762 ( -5.7445998192 -1.6158623695 -0.2380129397 ) - weight 1545 17 0.2490688711 ( 6.3034162521 0.4198944271 -5.4498806 ) - weight 1546 3 0.3415644169 ( 9.2207612991 1.6964797974 -2.2897474766 ) - weight 1547 17 0.6584355831 ( 9.1854820251 1.7114975452 -2.6452014446 ) - weight 1548 17 0.9400740266 ( 6.4109091759 1.6970877647 5.3661446571 ) - weight 1549 18 0.0599259473 ( 6.0859704018 1.1855773926 -1.2348527908 ) - weight 1550 3 0.5783585906 ( 8.1920776367 -0.8163146973 -1.0460239649 ) - weight 1551 4 0.1819866151 ( -2.7865197659 -0.4867532849 2.5552880764 ) - weight 1552 17 0.2396547496 ( 8.2298927307 -1.0406640768 -1.9882171154 ) - weight 1553 3 0.5168976188 ( 8.5529117584 -2.4308357239 -1.5962525606 ) - weight 1554 4 0.4053937197 ( -3.4361579418 1.1235626936 2.3988158703 ) - weight 1555 17 0.0777087063 ( 8.5585451126 -2.4702808857 -2.9304561615 ) - weight 1556 3 0.4595703781 ( 7.4836421013 -3.0989532471 -3.8217885494 ) - weight 1557 4 0.5404295921 ( -5.1402983665 1.4440643787 0.5184131861 ) - weight 1558 3 0.5718590021 ( 4.3932647705 -3.5176467896 -5.3897557259 ) - weight 1559 4 0.3662455082 ( -5.5112962723 1.2209020853 -2.9452288151 ) - weight 1560 17 0.061895553 ( 4.1879878044 -2.6701238155 -6.6362328529 ) - weight 1561 3 0.8336464763 ( 1.913808465 -3.3067474365 -7.8268809319 ) - weight 1562 4 0.0789414868 ( -6.9088802338 0.4226432443 -6.0341286659 ) - weight 1563 17 0.0874120444 ( 1.5727149248 -1.9135081768 -8.8087062836 ) - weight 1564 3 0.6841779947 ( 2.444637537 -3.2959518433 -5.5065488815 ) - weight 1565 4 0.3158220053 ( -4.9279484749 0.6631758809 -4.7364811897 ) - weight 1566 3 0.7716712356 ( 4.1899290085 -1.6877632141 -7.9363541603 ) - weight 1567 4 0.0819741115 ( -7.811809063 -0.78888309 -3.6823759079 ) - weight 1568 17 0.1463547051 ( 3.8387975693 -0.2844035923 -8.6515216827 ) - weight 1569 2 0.0738857314 ( 4.1294512749 3.7327461243 -6.7396769524 ) - weight 1570 17 0.8506604433 ( 3.7883405685 4.6385579109 -6.0286440849 ) - weight 1571 19 0.0754538476 ( 4.0615124702 -5.8018012047 -4.1480336189 ) - weight 1572 3 0.5406886339 ( 5.0050058365 0.8726997375 -6.4387798309 ) - weight 1573 17 0.4593113959 ( 4.7385001183 1.8516794443 -6.628964901 ) - weight 1574 3 0.6925443411 ( 3.8358399868 -1.8299789429 -6.1626839638 ) - weight 1575 4 0.1600997746 ( -6.0285792351 -0.5864648819 -3.416615963 ) - weight 1576 17 0.1473558843 ( 3.5871117115 -0.8539636731 -6.9474773407 ) - weight 1577 4 1 ( 2.8338091373 13.960899353 0.2138654143 ) - weight 1578 4 0.9065700769 ( -1.992970705 12.5866651535 -6.21611166 ) - weight 1579 5 0.0934299231 ( -5.582429409 -7.0536794662 0.1737803966 ) - weight 1580 4 0.938369453 ( -3.387894392 15.7490758896 -6.6811723709 ) - weight 1581 5 0.061630547 ( -5.7131323814 -3.6334097385 0.8428149819 ) - weight 1582 4 0.8470793366 ( -7.1869430542 16.3925991058 -4.4982452393 ) - weight 1583 5 0.1529206634 ( -4.0683145523 -2.4958639145 4.7940964699 ) - weight 1584 4 0.8603097796 ( -8.3686380386 16.5947608948 -0.7231552005 ) - weight 1585 5 0.1396902204 ( -0.5434149504 -2.5587704182 6.5995612144 ) - weight 1586 4 0.2151181996 ( -6.1626496315 21.1772251129 -5.6608657837 ) - weight 1587 5 0.7848817706 ( -4.2267346382 2.0725460052 2.6969444752 ) - weight 1588 4 0.1819262058 ( -3.9238123894 21.6810626984 -6.8785619736 ) - weight 1589 5 0.8180738091 ( -4.9788928032 2.2473409176 0.2164742798 ) - weight 1590 4 0.3353833854 ( -8.020149231 20.1779575348 -2.0005748272 ) - weight 1591 5 0.6646165848 ( -1.1227660179 1.0067596436 5.3570284843 ) - weight 1592 4 0.2997517288 ( -6.7959914207 20.6584434509 0.6710505486 ) - weight 1593 5 0.7002482414 ( 1.7486584187 0.8493843079 4.5842628479 ) - weight 1594 4 0.2811096311 ( 0.0963116735 21.4078407288 -4.3335037231 ) - weight 1595 5 0.7188903689 ( -1.9254169464 0.7816175818 -3.1363315582 ) - weight 1596 4 0.5023835301 ( -1.2970503569 19.380241394 -6.4432663918 ) - weight 1597 5 0.4976164401 ( -4.5395646095 -0.5978908539 -1.8070830107 ) - weight 1598 3 0.3274889588 ( 4.6096715927 -6.3897628784 -5.1972723007 ) - weight 1599 4 0.6725110412 ( -5.4209074974 4.094268322 -3.2070086002 ) - weight 1600 3 0.0973081291 ( 2.6723082066 -9.8318786621 -4.8259959221 ) - weight 1601 4 0.9026918411 ( -4.4015431404 7.1736769676 -5.4911985397 ) - weight 1602 3 0.3993753195 ( 6.6437540054 1.3305397034 5.4829316139 ) - weight 1603 17 0.6006246805 ( 7.0589232445 -0.548935771 4.9414715767 ) - weight 1604 3 0.5583897829 ( 2.5144910812 0.7969169617 7.1620235443 ) - weight 1605 4 0.0565090142 ( 6.9092555046 -2.4702448845 0.4895557463 ) - weight 1606 17 0.3851011992 ( 3.0328595638 -1.5278377533 6.6699037552 ) - weight 1607 3 0.3739424348 ( 9.0320224762 1.3259239197 1.6488970518 ) - weight 1608 17 0.6260575652 ( 9.223156929 0.4018507898 1.0923460722 ) - weight 1609 3 0.0579726622 ( 9.316608429 -9.6764068604 -3.3686742783 ) - weight 1610 4 0.9420273304 ( -5.3964157104 8.2528944016 1.152610898 ) - weight 1611 4 1 ( -3.5463778973 12.1414651871 3.6239085197 ) - weight 1612 4 1 ( 2.9600803852 12.8367824554 -1.9657230377 ) - weight 1613 4 0.9135693312 ( 0.5351151228 12.7332611084 -4.885456562 ) - weight 1614 5 0.0864306688 ( -3.8706223965 -7.6308269501 -2.0443198681 ) - weight 1615 4 1 ( -3.4446520805 16.3130283356 3.4163951874 ) - weight 1616 4 0.9345930815 ( 1.4839606285 16.9266834259 -4.7235326767 ) - weight 1617 5 0.0654069185 ( -2.8523700237 -3.7974889278 -3.7116556168 ) - weight 1618 3 0.6283817291 ( 2.1810204983 0.476852417 6.8841814995 ) - weight 1619 17 0.3716182709 ( 2.683989048 -1.7762539387 6.3421554565 ) - weight 1620 4 0.431024462 ( -1.840850234 22.3113594055 1.2332150936 ) - weight 1621 5 0.5689755678 ( 3.3452165127 1.316156745 -0.3991806805 ) - weight 1622 4 0.7502797246 ( -0.6238874197 22.1975498199 2.8037691116 ) - weight 1623 5 0.2497202754 ( 5.0428967476 0.7341661453 -1.2592736483 ) - weight 1624 4 0.683310926 ( 0.5737296939 22.4956684113 1.8676444292 ) - weight 1625 5 0.316689074 ( 4.3683156967 0.8938485384 -2.6445291042 ) - weight 1626 4 0.171483025 ( -3.9636771679 22.3372173309 1.7308732271 ) - weight 1627 5 0.8285169601 ( 3.5047953129 1.7265244722 1.7364361286 ) - weight 1628 4 0.0982733443 ( -1.0788463354 23.4189605713 1.7287540436 ) - weight 1629 5 0.9017266631 ( 4.1340589523 2.1583814621 -1.2485175133 ) - weight 1630 4 0.6876799464 ( -2.1909549236 21.5007629395 3.1140387058 ) - weight 1631 5 0.3123200536 ( 4.9833140373 0.3521401584 0.4401337504 ) - weight 1632 4 0.4544913769 ( -2.8182148933 21.977804184 1.6678284407 ) - weight 1633 5 0.5455086231 ( 3.559871912 1.1430391073 0.6867948174 ) - weight 1634 4 0.355009973 ( 0.2007293254 22.7945690155 0.1932315528 ) - weight 1635 5 0.644990027 ( 2.7319061756 1.4890226126 -2.6524167061 ) - weight 1636 3 0.4564072788 ( 7.7421154976 0.9609069824 -5.0669183731 ) - weight 1637 17 0.5435926914 ( 7.5498490334 1.6451598406 -5.430958271 ) - weight 1638 5 1 ( 3.6207389832 14.6275529861 0.5796841979 ) - weight 1639 5 1 ( 2.0255737305 6.4516925812 2.4558346272 ) - weight 1640 5 1 ( -4.4393386841 6.5631198883 -2.0527768135 ) - weight 1641 11 0.0772493333 ( -6.9313054085 18.863325119 -2.6953072548 ) - weight 1642 12 0.3773581684 ( 0.7272777557 6.158015728 4.1379103661 ) - weight 1643 13 0.3850193918 ( 1.9412107468 3.1125352383 2.2996909618 ) - weight 1644 14 0.1603731215 ( 1.8895343542 -2.0009653568 2.3064527512 ) - weight 1645 12 0.2775797844 ( -0.9061502218 6.8485250473 5.0343637466 ) - weight 1646 13 0.1956718862 ( 0.6805953383 4.5590076447 2.8164937496 ) - weight 1647 14 0.5267482996 ( 0.6672192216 -0.5202461481 2.8182489872 ) - weight 1648 13 1 ( 3.2310903072 3.3491265774 -0.9709453583 ) - weight 1649 12 0.3528324366 ( 3.1293540001 6.1779665947 0.268740207 ) - weight 1650 13 0.6471675634 ( 3.1424796581 0.2486465573 -1.0313661098 ) - weight 1651 14 1 ( -0.4330863953 1.6822992563 -0.3003239632 ) - weight 1652 12 1 ( -0.5448915958 1.6135697365 -5.8859462738 ) - weight 1653 11 0.287640214 ( 2.9111557007 19.4860248566 1.2350620031 ) - weight 1654 12 0.7123598456 ( 0.278613627 -1.9037854671 -2.7552502155 ) - weight 1655 12 1 ( 2.4337468147 0.1752854884 -5.5105004311 ) - weight 1656 12 0.9354602098 ( 2.6349396706 3.2221169472 -1.8921701908 ) - weight 1657 13 0.0645397902 ( 1.8537237644 -3.1952280998 -0.6710016131 ) - weight 1658 12 1 ( 3.7444143295 3.5296485424 -2.3596532345 ) - weight 1659 12 1 ( 4.0272045135 2.3043913841 -3.3948881626 ) - weight 1660 12 1 ( 3.5917243958 0.8323549032 -4.6216030121 ) - weight 1661 14 1 ( 2.1035068035 0.7169764042 -0.3198903799 ) - weight 1662 11 1 ( -2.1055445671 13.766661644 1.8253041506 ) - weight 1663 11 1 ( -0.8660775423 14.7647485733 2.875649929 ) - weight 1664 11 1 ( 2.0358424187 13.5692873001 3.3797631264 ) - weight 1665 11 1 ( 3.46083498 15.184967041 2.7928473949 ) - weight 1666 11 1 ( 1.290328145 16.8398094177 3.1759316921 ) - weight 1667 11 1 ( 2.6891028881 16.7278842926 2.8095314503 ) - weight 1668 11 1 ( -0.075363934 16.9656925201 3.0119187832 ) - weight 1669 11 1 ( 0.8180075884 14.8928775787 2.5515859127 ) - weight 1670 11 1 ( -2.8883926868 12.9765939713 -0.0271940082 ) - weight 1671 11 1 ( -3.137771368 12.6819543839 -1.4814245701 ) - weight 1672 11 1 ( -2.2789607048 13.5454263687 -3.8536934853 ) - weight 1673 11 0.7490617037 ( 0.7520534992 17.381811142 2.2169036865 ) - weight 1674 12 0.2509383261 ( 1.1983286142 -2.2158911228 0.2630549967 ) - weight 1675 11 0.7843534946 ( -2.2443571091 15.5000562668 -3.1411325932 ) - weight 1676 12 0.2156464756 ( -2.7741129398 1.5857429504 3.5789728165 ) - weight 1677 11 0.7167745233 ( -3.2475838661 15.604640007 -1.9363913536 ) - weight 1678 12 0.2832255065 ( -1.3215456009 1.6230846643 4.1768498421 ) - weight 1679 11 0.102107048 ( -4.6560254097 18.0674133301 -1.0524805784 ) - weight 1680 12 0.6951047182 ( 0.8930486441 3.3805439472 3.2618811131 ) - weight 1681 13 0.2027882487 ( 1.6606292725 0.4219938815 3.3912572861 ) - weight 1682 12 0.2530679703 ( -4.0557389259 6.5741434097 3.3150467873 ) - weight 1683 13 0.0652528852 ( -2.8384242058 4.0511622429 2.2598598003 ) - weight 1684 14 0.6816791892 ( -2.8639266491 -0.9378237724 2.2633752823 ) - weight 1685 12 0.2156105489 ( -4.2929830551 6.3436589241 0.9978496432 ) - weight 1686 13 0.4578246772 ( -3.7384915352 2.5404884815 0.7150121927 ) - weight 1687 14 0.3265647888 ( -3.8033270836 -2.4297785759 0.723762393 ) - weight 1688 14 1 ( -3.0088918209 0.8490065336 -0.9489414096 ) - weight 1689 12 0.3368065059 ( -3.3372263908 6.3783578873 -2.333933115 ) - weight 1690 13 0.6631934643 ( -3.7671144009 0.3467943966 -1.9687049389 ) - weight 1691 12 1 ( -1.7735852003 0.6175384521 -2.5889418125 ) - weight 1692 12 1 ( 0.5832096338 0.5238048434 -6.0707826614 ) - weight 1693 12 0.9460912943 ( -1.1468732357 3.1448004246 -3.553486824 ) - weight 1694 13 0.0539087057 ( -2.2400147915 -3.3702352047 -1.1989575624 ) - weight 1695 12 0.2486905903 ( -2.7620997429 6.9178786278 4.6218013763 ) - weight 1696 14 0.7513093948 ( -1.2133380175 -0.2333092988 2.7910885811 ) - weight 1697 13 1 ( -3.9324524403 3.3335974216 -1.8139874935 ) - weight 1698 12 1 ( -1.6218069792 3.410220623 -4.7102684975 ) - weight 1699 11 1 ( 0.8174681067 13.8548431396 -3.4014923573 ) - weight 1700 11 1 ( 0.0940736681 15.0062026978 -4.1511311531 ) - weight 1701 11 1 ( 1.7607572079 13.6801605225 -2.6132423878 ) - weight 1702 11 1 ( 3.7505521774 13.4132375717 2.0793693066 ) - weight 1703 11 1 ( -2.1237633228 14.7475557327 -4.2552313805 ) - weight 1704 11 1 ( 3.6371738911 16.6583633423 1.6823775768 ) - weight 1705 11 1 ( 3.7340435982 16.6625614166 0.2820144594 ) - weight 1706 11 1 ( -4.0234246254 13.6683387756 -1.7987692356 ) - weight 1707 11 1 ( -1.855396986 12.6002569199 -2.9618799686 ) - weight 1708 11 1 ( 2.0540599823 11.7860412598 -1.8182497025 ) - weight 1709 11 1 ( 1.7199016809 5.8761711121 4.482442379 ) - weight 1710 11 1 ( -0.1512209475 5.9631524086 3.8843717575 ) - weight 1711 11 1 ( -2.057933569 5.4196763039 3.769217968 ) - weight 1712 11 1 ( -3.5996551514 2.8228242397 1.7947330475 ) - weight 1713 10 0.0944344103 ( 0.246446386 22.2496337891 -2.7220282555 ) - weight 1714 11 0.9055656195 ( 0.2802421749 1.4083228111 -2.6555838585 ) - weight 1715 11 0.9191969633 ( 2.134185791 15.7128610611 -4.5637178421 ) - weight 1716 12 0.0808030665 ( -5.654147625 -0.305083245 0.5177887678 ) - weight 1717 11 0.8827454448 ( 3.0749769211 15.9730005264 -3.8697693348 ) - weight 1718 12 0.1172545776 ( -5.3565917015 -1.1398386955 -0.287797153 ) - weight 1719 11 1 ( 1.8974927664 14.1028385162 -3.7768988609 ) - weight 1720 11 1 ( 1.5763276815 14.7836122513 -4.4741911888 ) - weight 1721 10 0.0954859555 ( -0.369143039 23.4025802612 -0.2771966159 ) - weight 1722 11 0.9045140743 ( -2.3900434971 2.0608217716 -3.0151100159 ) - weight 1723 11 1 ( 0.8799197674 2.6412138939 -2.7065439224 ) - weight 1724 11 1 ( -0.372159332 12.7897815704 -2.9984276295 ) - weight 1725 11 1 ( -3.3544380665 4.4476413727 1.3400330544 ) - weight 1726 11 1 ( -3.4976813793 4.3550953865 -1.0609765053 ) - weight 1727 11 1 ( -2.6319465637 4.2806777954 -0.3292982876 ) - weight 1728 11 1 ( -3.2727005482 5.1453294754 -0.898576498 ) - weight 1729 11 1 ( -2.2672204971 5.0488395691 -2.4918830395 ) - weight 1730 11 1 ( 0.2711603343 4.1593265533 -2.8839483261 ) - weight 1731 11 1 ( -2.2427251339 4.2619738579 -2.6418302059 ) - weight 1732 11 1 ( -1.3102258444 4.1805362701 -1.9269524813 ) - weight 1733 11 1 ( 0.4552910924 4.1826019287 -2.1550152302 ) - weight 1734 10 1 ( -0.7707071304 18.1440315247 3.5540380478 ) - weight 1735 10 1 ( 1.161891818 17.6637763977 3.8370091915 ) - weight 1736 10 0.9169060588 ( -0.7515257001 18.8929138184 4.0239267349 ) - weight 1737 11 0.0830939412 ( -5.8683485985 -2.9665021896 -1.7461003065 ) - weight 1738 10 0.8770711422 ( 1.1064002514 18.524438858 4.2584600449 ) - weight 1739 11 0.1229288578 ( -5.749935627 -2.9574677944 0.158778891 ) - weight 1740 10 0.654335618 ( 3.379483223 20.8845806122 2.7480237484 ) - weight 1741 11 0.345664382 ( -4.3335762024 0.0165135246 1.6311752796 ) - weight 1742 10 0.8225660324 ( 2.5312888622 17.9873847961 3.640640974 ) - weight 1743 11 0.1774339676 ( -4.839287281 -3.0886309147 1.520377636 ) - weight 1744 11 1 ( 2.9555044174 13.3833427429 2.9541978836 ) - weight 1745 10 1 ( -2.3107118607 18.1555213928 1.7391420603 ) - weight 1746 10 0.7043881416 ( -1.570630908 21.3563728333 -0.972031951 ) - weight 1747 11 0.2956118584 ( -1.5491799116 -0.0815074667 -3.9188299179 ) - weight 1748 10 0.3755814731 ( -0.0090104891 22.0370903015 -1.4286185503 ) - weight 1749 11 0.6244184971 ( -0.9817717075 0.9728272557 -2.6238663197 ) - weight 1750 10 0.8626533151 ( -2.7753314972 18.9237270355 1.4619880915 ) - weight 1751 11 0.1373466849 ( -3.6889691353 -3.0223174095 -4.1766262054 ) - weight 1752 10 0.4863468111 ( -0.0274238549 20.4201545715 -2.3257949352 ) - weight 1753 11 0.5136532187 ( 0.1639021188 -0.4738154113 -2.5038707256 ) - weight 1754 10 0.617266953 ( -1.034229517 20.5019416809 -2.333309412 ) - weight 1755 11 0.3827330768 ( 0.0033829145 -0.6089619994 -3.4919862747 ) - weight 1756 10 0.6248319149 ( -1.2890313864 22.2341976166 0.5543887019 ) - weight 1757 11 0.3751681149 ( -3.1414325237 0.6211180687 -3.5303919315 ) - weight 1758 11 1 ( 3.515090704 5.0513744354 4.9649848938 ) - weight 1759 11 1 ( 5.1251797676 4.901907444 3.2112083435 ) - weight 1760 11 1 ( 1.4115513563 5.1925477982 5.3661289215 ) - weight 1761 11 1 ( 3.2110548019 5.5399780273 4.5221014023 ) - weight 1762 11 1 ( 5.0916800499 4.9379959106 0.9936065078 ) - weight 1763 11 1 ( 4.7362012863 5.3570375443 2.8949592113 ) - weight 1764 11 1 ( 0.9646511674 4.4912171364 5.5150051117 ) - weight 1765 11 0.0995258093 ( -1.6536487341 17.7063064575 -4.9880213737 ) - weight 1766 12 0.7898067236 ( -3.7483358383 3.4226677418 1.5043480396 ) - weight 1767 13 0.110667482 ( -3.2743525505 0.4808414876 2.8662443161 ) - weight 1768 11 0.1063148081 ( 2.1246094704 19.7338180542 -2.6174962521 ) - weight 1769 12 0.8936851621 ( -2.5407409668 0.83404845 -2.4763798714 ) - weight 1770 11 1 ( 4.2910819054 10.0687665939 3.3251266479 ) - weight 1771 11 1 ( 2.586081028 10.1053609848 4.2378311157 ) - weight 1772 11 1 ( 4.2663168907 8.7374429703 4.426615715 ) - weight 1773 11 1 ( 0.8926233649 8.2830247879 4.6354875565 ) - weight 1774 11 1 ( -0.3715696633 9.9157562256 3.9171452522 ) - weight 1775 11 1 ( -2.3707885742 9.5943622589 2.3859367371 ) - weight 1776 11 1 ( -2.0288801193 10.1382694244 1.9191339016 ) - weight 1777 11 1 ( -0.5119946599 10.6539726257 3.0170869827 ) - weight 1778 11 1 ( -2.2596375942 7.4672842026 2.5283620358 ) - weight 1779 11 1 ( 4.5980668068 9.8572244644 1.2659952641 ) - weight 1780 11 1 ( 3.2067685127 11.2171764374 1.4315099716 ) - weight 1781 11 1 ( 2.0816457272 11.3758878708 2.7479765415 ) - weight 1782 11 1 ( 3.0128567219 10.5711069107 -0.5394530296 ) - weight 1783 11 1 ( 4.7918691635 8.1631011963 0.5949138999 ) - weight 1784 11 1 ( 3.8861849308 9.6142034531 -0.7412440181 ) - weight 1785 11 1 ( 5.0866231918 8.6691255569 3.1700816154 ) - weight 1786 11 1 ( 2.054058075 9.1540651321 -2.5786957741 ) - weight 1787 11 1 ( 1.6719523668 9.9380893707 -2.2701056004 ) - weight 1788 11 1 ( -3.1515004635 9.5933227539 -1.4430738688 ) - weight 1789 11 1 ( -2.0725178719 9.5217151642 -2.764029026 ) - weight 1790 10 1 ( -1.6224735975 15.790517807 -4.2176785469 ) - weight 1791 10 1 ( -2.3245227337 16.718547821 0.6176638007 ) - weight 1792 10 1 ( -2.339692831 16.5632648468 -2.9601786137 ) - weight 1793 10 0.8935781121 ( -1.5281325579 17.6308231354 -3.5177881718 ) - weight 1794 11 0.1064219028 ( 1.5694308281 -3.3316853046 -3.6486070156 ) - weight 1795 10 0.8599565029 ( 6.2662286758 17.33735466 1.7543765306 ) - weight 1796 11 0.1400434971 ( -2.3214402199 -2.6632592678 4.8982191086 ) - weight 1797 10 0.7713285685 ( 5.8967084885 18.2376556396 2.0832488537 ) - weight 1798 11 0.2286714315 ( -2.8512587547 -1.9158579111 4.4335374832 ) - weight 1799 10 0.6509902477 ( 2.7645440102 18.4859409332 -6.53484869 ) - weight 1800 11 0.3490097523 ( 5.0172839165 -1.1777106524 -0.2231650054 ) - weight 1801 10 0.5030454993 ( 5.7293963432 18.6683540344 -5.0562729836 ) - weight 1802 11 0.4969545305 ( 4.0001358986 -0.5675978661 2.875702858 ) - weight 1803 10 0.7249910831 ( 6.0907077789 17.2751312256 -5.1015162468 ) - weight 1804 11 0.2750089169 ( 4.336452961 -1.8320504427 3.477129221 ) - weight 1805 10 0.6980623007 ( -1.2366813421 18.7619247437 -3.987575531 ) - weight 1806 11 0.3019376695 ( 1.8788809776 -2.1114509106 -3.6660017967 ) - weight 1807 10 0.661098361 ( 5.7658605576 18.7934150696 1.7771903276 ) - weight 1808 11 0.338901639 ( -2.6678721905 -1.3647110462 4.1467137337 ) - weight 1809 10 0.7913669944 ( 0.1644247919 18.0440711975 -5.4661769867 ) - weight 1810 11 0.2086330354 ( 3.6546161175 -2.3059763908 -2.4520838261 ) - weight 1811 10 0.5249487162 ( 6.8812565804 19.4270954132 1.2333656549 ) - weight 1812 11 0.475051254 ( -2.0757544041 -0.4394773543 5.003885746 ) - weight 1813 10 0.9213094711 ( 7.0429463387 15.7642803192 1.1810103655 ) - weight 1814 11 0.0786905214 ( -1.3768953085 -3.9413187504 5.836833477 ) - weight 1815 10 0.9338607788 ( 4.8056902885 11.7146902084 -5.5752706528 ) - weight 1816 11 0.0661392212 ( 5.5472202301 -7.421962738 3.1922979355 ) - weight 1817 10 1 ( -0.4220239818 15.446269989 3.3949568272 ) - weight 1818 10 1 ( -2.3557960987 12.5087327957 2.2593996525 ) - weight 1819 3 0.5226224661 ( -4.5210051537 -2.8630027771 5.1874666214 ) - weight 1820 10 0.4773775041 ( -4.3342728615 1.3324980736 0.9764493704 ) - weight 1821 3 0.3407817781 ( -2.3781831264 -6.9575843811 -5.0705609322 ) - weight 1822 10 0.6592182517 ( 4.511156559 4.2813229561 -5.3201551437 ) - weight 1823 3 0.4126182199 ( -0.6710220575 -6.7529602051 -3.2513923645 ) - weight 1824 10 0.5873817801 ( 2.2031970024 3.9160313606 -6.2176680565 ) - weight 1825 3 0.4119746685 ( -2.4439246655 -5.2881507874 4.8690805435 ) - weight 1826 10 0.5880253315 ( -4.7638430595 3.3410279751 -1.4889618158 ) - weight 1827 3 0.6267764568 ( -1.1631516218 -6.7135238647 2.4224381447 ) - weight 1828 10 0.3732235432 ( -2.9256019592 4.3545832634 -3.7806212902 ) - weight 1829 3 0.1250320077 ( -5.548268795 -8.981716156 -5.383043766 ) - weight 1830 10 0.8749679923 ( 5.938765049 6.7885012627 -2.8870117664 ) - weight 1831 3 0.1838332713 ( -1.2151947021 -10.2311553955 -3.6204602718 ) - weight 1832 10 0.8161666989 ( 2.7571463585 7.401995182 -6.4848246574 ) - weight 1833 3 0.0663084388 ( -5.0440044403 -9.1647224426 5.3758664131 ) - weight 1834 10 0.9336915612 ( -4.2962574959 7.6290178299 0.3656433523 ) - weight 1835 3 0.2613720298 ( -1.540268898 -9.4691123962 1.9814689159 ) - weight 1836 10 0.7386279702 ( -2.3670473099 7.0968346596 -4.0936927795 ) - weight 1837 3 0.3120176494 ( -0.4770362675 -9.0535240173 -1.5733042955 ) - weight 1838 10 0.6879823208 ( 0.5760336518 6.2608747482 -6.233561039 ) - weight 1839 10 1 ( -1.0723922253 11.2006130219 3.2005107403 ) - weight 1840 3 0.1108867526 ( -8.5155363083 -7.8049240112 4.1910905838 ) - weight 1841 10 0.8891132474 ( -1.9613627195 6.8005971909 3.3932271004 ) - weight 1842 10 0.9323524833 ( 7.0690846443 12.8488998413 -0.9899317622 ) - weight 1843 11 0.0676475167 ( 1.2364983559 -6.4619989395 6.0084767342 ) - weight 1844 10 0.9057416916 ( 7.5520658493 14.1969680786 -3.1776008606 ) - weight 1845 11 0.0942583084 ( 3.2106559277 -4.7581453323 5.81863451 ) - weight 1846 10 0.5097686648 ( 8.064663887 18.9508209229 -0.5095326304 ) - weight 1847 11 0.490231365 ( -0.1171115264 -0.4110342264 5.9137730598 ) - weight 1848 3 0.2257421017 ( -8.6921253204 -5.6849021912 -1.9335128069 ) - weight 1849 10 0.7742578983 ( 3.8167142868 4.3217926025 1.8102564812 ) - weight 1850 3 0.755829215 ( -2.5996456146 -3.1819915771 5.2685208321 ) - weight 1851 10 0.2441708148 ( -5.0913295746 1.3248997927 -0.8198673129 ) - weight 1852 3 0.3560082912 ( -9.2955503464 -4.163143158 -0.6279870272 ) - weight 1853 10 0.6439917088 ( 2.8039903641 3.0191249847 3.099332571 ) - weight 1854 3 0.6028003693 ( -1.4196438789 -5.479839325 -4.5613222122 ) - weight 1855 10 0.3971996009 ( 3.6879236698 2.7010216713 -5.7523446083 ) - weight 1856 3 0.8913513422 ( -1.5633721352 -4.9879570007 5.1678905487 ) - weight 1857 10 0.1086486876 ( -5.3573865891 2.9169082642 -2.1390426159 ) - weight 1858 3 0.8820733428 ( -1.5458381176 -1.6829986572 7.1447806358 ) - weight 1859 17 0.1179266572 ( -1.0217636824 -3.9867091179 6.2819161415 ) - weight 1860 3 0.9283687472 ( -1.6073291302 -4.1433410645 6.2953686714 ) - weight 1861 10 0.0716312751 ( -6.3994431496 2.1723568439 -1.5505902767 ) - weight 1862 3 0.6439720392 ( -4.2982382774 -2.0082244873 7.3487462997 ) - weight 1863 10 0.2472280413 ( -6.4374756813 0.6043121815 1.6819177866 ) - weight 1864 17 0.1087999046 ( -3.7579162121 -4.3894844055 6.5545377731 ) - weight 1865 3 0.6023226976 ( -9.5180206299 -1.333480835 1.1821365356 ) - weight 1866 10 0.2356233597 ( 1.1783692837 0.4010211825 4.4542927742 ) - weight 1867 17 0.1620538831 ( -9.3230905533 -2.3235054016 1.0328491926 ) - weight 1868 3 0.5815145373 ( -9.3864803314 -1.9524116516 1.9860262871 ) - weight 1869 10 0.3509689569 ( 0.3829872012 1.0428179502 4.4999117851 ) - weight 1870 17 0.0675165281 ( -9.1456193924 -3.1157503128 1.6553189754 ) - weight 1871 3 0.615749836 ( -7.5035843849 -2.0293502808 4.8258552551 ) - weight 1872 10 0.3239196539 ( -2.9401938915 0.9952170849 3.7448971272 ) - weight 1873 17 0.0603304803 ( -7.1028051376 -3.8474686146 4.2835016251 ) - weight 1874 3 0.5772765279 ( -8.9240169525 0.1087417603 0.8441859484 ) - weight 1875 10 0.094845064 ( 1.2767199278 -1.1411350965 4.0553717613 ) - weight 1876 17 0.3278784454 ( -8.7494668961 -0.8342632055 1.0197837353 ) - weight 1877 3 0.7094534636 ( -3.8729000092 -0.8295249939 -8.9261922836 ) - weight 1878 17 0.2905465364 ( -4.267557621 0.6751277447 -8.954615593 ) - weight 1879 3 0.4537308812 ( -3.9236824512 1.0521888733 -8.9932060242 ) - weight 1880 17 0.5462691188 ( -4.3221035004 2.5168251991 -8.5633459091 ) - weight 1881 3 0.3106232285 ( -2.458206892 1.9493141174 8.0350952148 ) - weight 1882 17 0.6893767715 ( -1.8815186024 -0.6881748438 8.0705652237 ) - weight 1883 3 0.2235922813 ( -5.1096987724 2.0013809204 7.7044014931 ) - weight 1884 17 0.7764077187 ( -4.547621727 -0.5947704315 7.9104151726 ) - weight 1885 17 1 ( -3.8286015987 1.2086167336 7.6983590126 ) - weight 1886 3 0.4141060114 ( -5.1330666542 1.2630386353 7.5839781761 ) - weight 1887 17 0.5858939886 ( -4.5778641701 -1.2827186584 7.61714077 ) - weight 1888 3 0.3944361806 ( -2.7175819874 1.1817436218 7.8684301376 ) - weight 1889 17 0.6055638194 ( -2.150033474 -1.3966314793 7.7385926247 ) - weight 1890 3 0.5463812351 ( -9.0013618469 0.7265815735 -2.6053204536 ) - weight 1891 17 0.4536187649 ( -9.0247068405 0.5940458775 -2.1694135666 ) - weight 1892 2 0.0525413863 ( -7.0823488235 3.4171409607 -4.4578661919 ) - weight 1893 3 0.0612702481 ( -7.1502876282 3.4065132141 -4.3001909256 ) - weight 1894 17 0.8861883879 ( -7.2739806175 3.6283140182 -3.2690823078 ) - weight 1895 10 0.4810909033 ( -0.5822280645 19.8550205231 -4.1834220886 ) - weight 1896 11 0.5189090967 ( 1.9836140871 -0.8874794841 -3.2755541801 ) - weight 1897 10 0.4008352458 ( 3.8139507771 19.4869270325 -6.6170506477 ) - weight 1898 11 0.599164784 ( 5.0874371529 0.0262052324 0.5865555406 ) - weight 1899 10 0.1214690804 ( 7.2455272675 21.4255542755 -3.2001900673 ) - weight 1900 11 0.8785309196 ( 1.9559477568 2.1725041866 4.1637206078 ) - weight 1901 11 1 ( 4.1899824142 3.4389541149 2.1957142353 ) - weight 1902 11 1 ( 4.0862803459 2.8440029621 -0.3891690075 ) - weight 1903 10 0.0571544766 ( 1.3789200783 22.8467235565 -4.7148575783 ) - weight 1904 11 0.9428455234 ( 2.2917869091 2.4981412888 -2.0420980453 ) - weight 1905 11 1 ( 2.4301908016 3.1309158802 4.0297145844 ) - weight 1906 10 0.2063748837 ( -0.6099454165 21.6061458588 -2.7464532852 ) - weight 1907 11 0.7936251163 ( 0.2825748026 0.6059800386 -3.3657388687 ) - weight 1908 11 1 ( 0.8770484328 2.58689785 4.7950143814 ) - weight 1909 3 0.1783798933 ( -10.1692819595 -6.8604316711 0.3459020853 ) - weight 1910 10 0.8216201067 ( 2.2162387371 5.8866863251 3.7465362549 ) - weight 1911 11 1 ( 3.5167007446 7.1138119698 -0.9396903515 ) - weight 1912 11 1 ( 1.2188075781 3.8699572086 -2.2309634686 ) - weight 1913 11 1 ( 3.1383316517 7.3735170364 -2.6736946106 ) - weight 1914 11 1 ( 1.8122564554 6.5967001915 -3.5999574661 ) - weight 1915 11 1 ( 1.4893381596 5.1975636482 -3.8406062126 ) - weight 1916 11 1 ( 2.1186323166 4.0125784874 -3.5041282177 ) - weight 1917 11 1 ( 3.3230679035 3.7348926067 -2.7943091393 ) - weight 1918 11 1 ( 4.4722313881 4.7392568588 -2.0725371838 ) - weight 1919 12 1 ( 2.0628979206 -1.1222180128 -3.3968234062 ) - weight 1920 12 1 ( 0.4765205979 -1.1267359257 -4.0694241524 ) - weight 1921 12 1 ( 2.8764095306 -0.0591394082 -2.0965423584 ) - weight 1922 12 1 ( -0.8572891951 -0.4285986125 -3.9923796654 ) - weight 1923 12 0.1469175518 ( 1.0171072483 8.0665035248 4.2012882233 ) - weight 1924 13 0.8530824184 ( 2.3673853874 4.5443754196 1.0755363703 ) - weight 1925 12 0.2691477239 ( 2.1425123215 6.0272159576 1.912797451 ) - weight 1926 13 0.7308522463 ( 2.654638052 1.3487359285 0.4690739512 ) - weight 1927 12 1 ( -2.131203413 1.8456496 -2.472186327 ) - weight 1928 14 1 ( 0.4520548284 1.0090888739 1.496593833 ) - weight 1929 14 1 ( -2.5129394531 0.7710604668 1.0422781706 ) - weight 1930 13 0.3830572069 ( -3.7322149277 4.2597174644 0.2420523763 ) - weight 1931 14 0.6169427633 ( -3.7521409988 -0.7129473686 0.2448585182 ) - weight 1932 11 1 ( -3.2755489349 10.4092121124 0.2330484986 ) - weight 1933 11 1 ( -0.3440947533 10.1631383896 -3.2377872467 ) - weight 1934 11 1 ( -1.6699420214 13.35704422 2.1718389988 ) - weight 1935 11 1 ( -3.6523790359 13.0448818207 0.8728779554 ) - weight 1936 3 0.60470891 ( -6.9311394691 0.2659263611 4.7454075813 ) - weight 1937 10 0.1477793157 ( -3.0787060261 -1.363948226 3.6121826172 ) - weight 1938 17 0.2475117892 ( -6.5359225273 -1.5925401449 4.7266740799 ) - weight 1939 11 1 ( 4.5600948334 7.1307444572 3.9798958302 ) - weight 1940 11 1 ( 4.4664840698 6.8584575653 1.2892023325 ) - weight 1941 11 1 ( 2.1181106567 7.0381550789 4.4172701836 ) - weight 1942 10 0.1127029806 ( 7.5834903717 21.194486618 -0.7831446528 ) - weight 1943 11 0.8872970343 ( -0.3060404658 1.6937330961 4.9785261154 ) - weight 1944 10 0.1564201862 ( 5.1172361374 21.4927024841 1.1992977858 ) - weight 1945 11 0.8435798287 ( -2.6637039185 1.1862595081 2.908425808 ) - weight 1946 11 1 ( -3.2543129921 2.4417402744 2.40670681 ) - weight 1947 11 1 ( -2.8660829067 3.8947851658 2.7034721375 ) - weight 1948 11 1 ( -0.951164484 4.2750163078 4.8256173134 ) - weight 1949 11 1 ( -1.271212101 3.0242536068 6.2466039658 ) - weight 1950 11 1 ( -1.3918745518 1.735678196 6.3383927345 ) - weight 1951 10 0.0979859829 ( 7.6974644661 20.7620582581 1.393966198 ) - weight 1952 11 0.9020140171 ( -2.3344397545 1.0047740936 5.5707483292 ) - weight 1953 10 0.1117024943 ( 6.3831133842 21.4449157715 2.3759329319 ) - weight 1954 11 0.8882974982 ( -3.6074893475 1.2512871027 4.3555746078 ) - weight 1955 11 1 ( -4.2296266556 2.4043939114 3.7445876598 ) - weight 1956 11 1 ( -3.8631870747 3.7722499371 4.0183229446 ) - weight 1957 11 1 ( -2.8528022766 4.5153675079 4.8429627419 ) - weight 1958 11 1 ( -1.8064454794 4.1964530945 5.7249927521 ) - weight 1959 11 1 ( -2.6460971832 7.3982758522 1.0683410168 ) - weight 1960 11 1 ( -2.5780918598 6.3014655113 -0.6216258407 ) - weight 1961 11 1 ( -1.3698269129 6.1924042702 -2.1039302349 ) - weight 1962 11 1 ( -2.5618691444 8.9638433456 1.0246458054 ) - weight 1963 11 1 ( -3.0008661747 10.7386045456 1.1634465456 ) - weight 1964 11 1 ( -3.5910413265 6.354373455 1.3024064302 ) - weight 1965 10 1 ( -1.159916997 16.7671146393 2.7083535194 ) - weight 1966 11 1 ( 3.832732439 13.3568115234 1.1966582537 ) - weight 1967 11 1 ( 4.1615986824 14.6317520142 1.6583943367 ) - weight 1968 11 1 ( 2.4808390141 14.5758991241 3.5361812115 ) - weight 1969 11 1 ( 0.3855357468 6.0402998924 -3.3794169426 ) - weight 1970 11 1 ( -3.8421561718 6.2002429962 0.2097373605 ) - weight 1971 11 1 ( -0.7184865475 5.956799984 -3.452760458 ) - weight 1972 11 1 ( -3.6393020153 6.1230716705 -1.5993386507 ) - weight 1973 11 1 ( -2.5143568516 6.0388426781 -2.9662585258 ) - weight 1974 11 1 ( -3.8872659206 12.6885786057 -0.2273731977 ) - weight 1975 11 1 ( -3.8385703564 12.2721300125 -2.0386610031 ) - weight 1976 11 1 ( -2.6482288837 12.1952047348 -3.49690485 ) - weight 1977 11 1 ( -0.7661416531 12.4447040558 -3.9069211483 ) - weight 1978 11 1 ( 3.2247142792 4.2868518829 4.8219022751 ) - weight 1979 11 1 ( 4.8214735985 4.1323280334 3.0915284157 ) - weight 1980 11 1 ( -2.3136470318 4.6781311035 4.0731811523 ) - weight 1981 11 1 ( -0.1333324015 3.0807967186 4.9704189301 ) - weight 1982 11 1 ( 5.1142463684 4.1602525711 0.6982365847 ) - weight 1983 11 1 ( 3.8906457424 4.4089941978 -1.2850561142 ) - weight 1984 11 1 ( 3.9960186481 5.9020371437 -0.4853599072 ) - weight 1985 11 1 ( 2.3941721916 7.4760689735 -2.2516894341 ) - weight 1986 11 1 ( -3.1154403687 5.3924536705 1.3491157293 ) - weight 1987 11 1 ( -2.9886341095 4.2997202873 1.5195653439 ) - weight 1988 11 1 ( 0.3941325545 12.7358913422 -3.9020531178 ) - weight 1989 11 1 ( 0.6366984248 10.4302444458 -3.1572229862 ) - weight 1990 11 1 ( 1.4959439039 11.1916532516 -2.1388487816 ) - weight 1991 11 1 ( -2.8831398487 6.5128450394 1.235294342 ) - weight 1992 11 1 ( -3.0202815533 14.5460929871 -4.0599541664 ) - weight 1993 11 1 ( -2.5407192707 13.3492736816 0.6911016107 ) - weight 1994 11 1 ( -0.7036168575 13.3075485229 1.8416287899 ) - weight 1995 11 1 ( -4.2982673645 14.6408958435 -2.5500745773 ) - weight 1996 10 0.9364672303 ( 1.6993942261 17.3904132843 2.7941448689 ) - weight 1997 11 0.0635327697 ( -4.0408463478 -3.7293477058 0.6736472845 ) - weight 1998 10 0.7988651991 ( 2.7553424835 17.6745815277 2.6443059444 ) - weight 1999 11 0.2011348009 ( -3.7818937302 -3.208337307 1.6115820408 ) - weight 2000 10 0.5771669745 ( 3.5440392494 20.3620147705 2.3074674606 ) - weight 2001 11 0.4228330255 ( -3.7906355858 -0.3941507041 1.8067131042 ) - weight 2002 10 0.3044187725 ( 3.9329340458 21.2863540649 1.2653445005 ) - weight 2003 11 0.6955811977 ( -2.8739480972 0.7244415283 1.8166224957 ) - weight 2004 10 1 ( -0.6001212597 17.8544120789 2.093064785 ) - weight 2005 10 1 ( -2.2879588604 17.5865516663 -0.3582693636 ) - weight 2006 10 0.8178261518 ( -2.0247750282 17.8228569031 -1.4907747507 ) - weight 2007 11 0.182173878 ( -0.5124440789 -3.5267531872 -3.790242672 ) - weight 2008 11 0.1172697619 ( -4.3343296051 16.9996414185 -3.0421028137 ) - weight 2009 12 0.6770974398 ( -1.2964390516 3.6789526939 3.8269634247 ) - weight 2010 13 0.2056327909 ( -0.2527486682 1.4989866018 4.0087471008 ) - weight 2011 11 0.0709621161 ( -3.4554941654 16.9557571411 -4.0944080353 ) - weight 2012 12 0.7818242311 ( -2.5487821102 3.6706299782 3.2673287392 ) - weight 2013 13 0.1472136676 ( -1.6098921299 1.4485735893 3.8157608509 ) - weight 2014 11 0.357545346 ( -3.5758838654 16.4763011932 -4.489593029 ) - weight 2015 12 0.5105105639 ( -3.0076599121 3.7010807991 3.7021226883 ) - weight 2016 13 0.1319440752 ( -1.9233598709 1.8394159079 4.2024412155 ) - weight 2017 11 0.3325402141 ( -4.7627005577 16.5391044617 -3.0906982422 ) - weight 2018 12 0.5499057174 ( -1.3337262869 3.7263586521 4.4549121857 ) - weight 2019 13 0.1175540611 ( -0.1070246398 1.9204907417 4.4549045563 ) - weight 2020 11 0.4304984212 ( -4.6744265556 17.6991653442 -0.4588625729 ) - weight 2021 12 0.5104330778 ( 1.2623822689 2.8672299385 3.5592496395 ) - weight 2022 13 0.059068501 ( 2.0630085468 0.1212873906 3.8770487309 ) - weight 2023 11 0.3538155556 ( -1.1434032917 17.1298618317 -5.0773339272 ) - weight 2024 12 0.5456925631 ( -4.2410306931 2.832349062 1.6012556553 ) - weight 2025 13 0.1004918665 ( -3.758620739 0.2016397864 3.4030368328 ) - weight 2026 11 1 ( 1.6435148716 12.4135637283 2.1679699421 ) - weight 2027 11 1 ( 2.5931005478 12.3037748337 0.9685155153 ) - weight 2028 11 1 ( 2.6428229809 15.1771917343 3.1619338989 ) - weight 2029 11 1 ( 3.4367218018 15.339140892 1.8855340481 ) - weight 2030 11 1 ( 2.4978795052 3.5753009319 -1.4841119051 ) - weight 2031 11 1 ( 0.4367446601 5.1123323441 -2.7975046635 ) - weight 2032 11 1 ( 0.4793736339 6.2398281097 -2.7218990326 ) - weight 2033 11 1 ( 0.8290002346 9.7261810303 -2.4580614567 ) - weight 2034 11 1 ( 1.0446709394 6.6380534172 -2.7999398708 ) - weight 2035 11 1 ( 2.1411960125 11.7798471451 -1.0992540121 ) - weight 2036 3 0.5825697184 ( -7.7756619453 0.2518005371 -1.944960475 ) - weight 2037 17 0.4174302518 ( -7.7631192207 -0.0086379098 -1.7122454643 ) - weight 2038 11 1 ( -1.3522400856 12.0326728821 2.2034356594 ) - weight 2039 11 1 ( -3.0873866081 14.427895546 2.3097188473 ) - weight 2040 11 1 ( -2.3922252655 14.7595205307 3.0323221684 ) - weight 2041 11 1 ( -0.6191183329 16.4841327667 3.1263072491 ) - weight 2042 11 0.9486664534 ( -2.5024800301 16.6986198425 3.4183938503 ) - weight 2043 12 0.0513335578 ( 3.2666580677 -1.1757240295 2.9355788231 ) - weight 2044 11 0.9489473701 ( -4.0164361 15.8807325363 2.1639633179 ) - weight 2045 12 0.0510526337 ( 2.5255968571 0.0247745309 4.5306425095 ) - weight 2046 11 1 ( -1.9769517183 15.6436185837 3.5176172256 ) - weight 2047 11 0.9013202786 ( -3.6333324909 16.5367126465 2.7065470219 ) - weight 2048 12 0.0986797288 ( 3.0669116974 -0.1567519158 3.792062521 ) - weight 2049 11 1 ( -3.7645385265 15.0779037476 2.1647508144 ) - weight 2050 11 0.9036762714 ( -3.7301898003 15.6906661987 0.5955362916 ) - weight 2051 12 0.0963237435 ( 1.026127696 0.5950238109 4.464056015 ) - weight 2052 11 0.25 ( 1.6948721409 19.428478241 2.3350605965 ) - weight 2053 12 0.75 ( 1.6697443724 -1.76235497 -1.8965262175 ) - weight 2054 11 0.8230245113 ( 1.8264163733 17.2163829803 1.9024415016 ) - weight 2055 12 0.1769755185 ( 0.4405913651 -2.8175449371 -0.3237626255 ) - weight 2056 11 0.3717112839 ( 0.562079668 19.3745937347 2.5896496773 ) - weight 2057 12 0.6282887459 ( 2.3202257156 -1.2106134892 -1.1069736481 ) - weight 2058 12 1 ( 2.2264509201 0.4269584417 -0.6476259828 ) - weight 2059 11 1 ( -4.3155970573 14.9210691452 -1.6272244453 ) - weight 2060 11 1 ( -0.5200131536 12.308719635 2.2379808426 ) - weight 2061 11 0.7532988191 ( -3.4816401005 16.9683246613 0.6827710867 ) - weight 2062 12 0.246701166 ( 1.4688754082 1.086941123 3.3398709297 ) - weight 2063 3 0.7483199835 ( -2.2808992863 -4.013671875 5.5935192108 ) - weight 2064 10 0.2516800463 ( -5.5046439171 2.1107637882 -1.1522887945 ) - weight 2065 3 0.888089776 ( -0.9945722222 -6.6571540833 4.2814383507 ) - weight 2066 10 0.1119101942 ( -4.7234177589 4.3994669914 -3.2773098946 ) - weight 2067 3 0.7350515723 ( -1.7938239574 -5.3760185242 4.5010042191 ) - weight 2068 10 0.2649484277 ( -4.6503996849 3.2912974358 -2.2309114933 ) - weight 2069 3 0.8052905798 ( -2.5846002102 -1.5636558533 5.8292813301 ) - weight 2070 10 0.1022787392 ( -5.6280965805 -0.2295573056 -0.3410845101 ) - weight 2071 17 0.0924307182 ( -2.1343302727 -3.568820715 5.0939040184 ) - weight 2072 11 1 ( 3.2295722961 14.7044019699 -2.7648425102 ) - weight 2073 11 1 ( 3.5362782478 15.598739624 -3.0091533661 ) - weight 2074 11 1 ( 2.529676199 13.9928703308 -2.7183945179 ) - weight 2075 11 0.6971091032 ( 2.5148868561 17.0636940002 0.8361655474 ) - weight 2076 12 0.3028909266 ( -0.7866777778 -2.7566306591 -0.6763955951 ) - weight 2077 11 0.2251555175 ( 3.0802521706 19.1959667206 -0.3508120775 ) - weight 2078 12 0.7748444676 ( -1.2249896526 -1.304133296 -2.6697018147 ) - weight 2079 11 1 ( -0.3642852902 14.5788879395 -3.9362418652 ) - weight 2080 11 1 ( 0.9435853958 15.5897340775 3.0359301567 ) - weight 2081 11 0.8075404167 ( -0.6975887418 17.3272361755 2.302927494 ) - weight 2082 12 0.1924596131 ( 1.8351521492 -1.3711123466 1.259370923 ) - weight 2083 12 1 ( 2.7535994053 1.8655917645 -0.1553789526 ) - weight 2084 12 1 ( 2.5544929504 1.945822835 -0.4228129387 ) - weight 2085 12 0.7385284901 ( -3.0255417824 4.390709877 -1.3673141003 ) - weight 2086 13 0.2614715397 ( -3.3312115669 -0.6680800915 -0.0290494934 ) - weight 2087 12 0.6177253723 ( -3.0689404011 4.5455322266 2.9417331219 ) - weight 2088 13 0.3822745979 ( -2.1397197247 2.0443272591 3.1041493416 ) - weight 2089 12 0.5818145275 ( -1.0294187069 4.5579762459 3.8766181469 ) - weight 2090 13 0.4181855023 ( 0.0770616308 2.1396596432 3.4367237091 ) - weight 2091 12 0.5504769087 ( 0.6163258553 4.6905021667 3.4615767002 ) - weight 2092 13 0.4495231211 ( 1.5425099134 1.6091681719 2.7516412735 ) - weight 2093 12 0.5998160839 ( -3.9685547352 4.6996765137 0.6672575474 ) - weight 2094 13 0.4001839161 ( -3.6348011494 1.0079638958 1.4618985653 ) - weight 2095 12 0.514654398 ( 1.9607104063 4.9122614861 2.403822422 ) - weight 2096 13 0.4853456318 ( 2.5435211658 0.831774354 1.5815871954 ) - weight 2097 11 0.064105615 ( -1.6524063349 19.9636096954 1.8820673227 ) - weight 2098 12 0.9358944297 ( 2.8374114037 0.9048440456 -0.1025240645 ) - weight 2099 11 0.0929720625 ( -3.6932218075 19.5423679352 0.7295030951 ) - weight 2100 12 0.8028796315 ( 2.5401341915 2.6012117863 1.5420849323 ) - weight 2101 13 0.1041482985 ( 2.6946485043 -1.5893551111 2.3127269745 ) - weight 2102 12 0.6469980478 ( 2.5028030872 3.2530548573 0.37090078 ) - weight 2103 13 0.3530019224 ( 2.3714435101 -1.7838140726 1.0259910822 ) - weight 2104 11 0.2219529599 ( 0.8520006537 19.3347091675 -4.2292141914 ) - weight 2105 12 0.7780470848 ( -3.5244863033 2.3047449589 -1.3602472544 ) - weight 2106 11 1 ( 0.7994382381 12.9195165634 -2.6773438454 ) - weight 2107 12 1 ( -2.7961292267 2.0124146938 -2.2681498528 ) - weight 2108 11 0.6193848848 ( 1.5299518108 17.8058948517 -3.454637289 ) - weight 2109 12 0.3806150854 ( -3.7113287449 0.6164067388 -0.6450766325 ) - weight 2110 11 0.7943415046 ( -0.4912987053 15.9028196335 -3.7682695389 ) - weight 2111 12 0.205658555 ( -3.8586392403 1.0334925652 2.1135189533 ) - weight 2112 11 0.86826998 ( 3.2851781845 16.6928005219 -1.1584707499 ) - weight 2113 12 0.1317299902 ( -2.9050254822 -2.3601989746 -0.9312101603 ) - weight 2114 11 0.5162470341 ( 2.6510317326 17.5331439972 -1.667829752 ) - weight 2115 12 0.4837529361 ( -2.7668702602 -1.220315814 -1.1533501148 ) - weight 2116 11 0.5819576979 ( -2.3732295036 17.5235404968 1.8758795261 ) - weight 2117 12 0.4180422723 ( 2.2255535126 0.0343062468 2.2086136341 ) - weight 2118 10 0.8398042917 ( 2.0766916275 17.0071601868 -6.2626552582 ) - weight 2119 11 0.1601957083 ( 4.8987402916 -2.7922902107 -0.5594718456 ) - weight 2120 10 1 ( 6.7835259438 9.7415370941 -3.2816545963 ) - weight 2121 11 1 ( 3.214381218 14.9344387054 -1.472458601 ) - weight 2122 11 1 ( 1.9220314026 12.9173135757 -2.0759496689 ) - weight 2123 10 0.6834487915 ( 7.3631243706 18.2166824341 -0.6987153292 ) - weight 2124 11 0.3165512383 ( 0.0847073868 -1.2456386089 5.3396549225 ) - weight 2125 3 0.4456541538 ( -7.0214524269 -2.3929901123 4.3822588921 ) - weight 2126 10 0.5543458462 ( -2.6952376366 1.2398952246 3.0803732872 ) - weight 2127 3 0.682189703 ( -3.6369364262 -2.0150985718 6.144033432 ) - weight 2128 10 0.2551205456 ( -5.5463480949 0.4150200784 0.6529567242 ) - weight 2129 17 0.062689811 ( -3.1668624878 -4.0972294807 5.3487420082 ) - weight 2130 17 0.8284341097 ( -1.5356787443 0.7227650881 7.9976167679 ) - weight 2131 18 0.1715659201 ( -2.0076012611 0.8739738464 1.0930681229 ) - weight 2132 3 0.5035423636 ( -8.4498071671 -1.8765449524 1.5924158096 ) - weight 2133 10 0.4964576364 ( 0.4177339971 0.7816274762 3.5157299042 ) - weight 2134 3 0.5111525059 ( -8.3219251633 0.493183136 -0.6540173292 ) - weight 2135 17 0.4888474941 ( -8.2343740463 -0.0924434885 -0.3728057444 ) - weight 2136 3 0.2529966533 ( -9.6126346588 0.9142570496 -0.6379578114 ) - weight 2137 17 0.7470033765 ( -9.5220327377 0.29451105 -0.1838813871 ) - weight 2138 17 1 ( -8.4157629013 1.988591671 2.5784623623 ) - weight 2139 3 0.5771152973 ( -6.4818458557 -0.2328224182 -4.8620820045 ) - weight 2140 10 0.1738158762 ( 5.7442789078 -1.6166108847 -0.2408128083 ) - weight 2141 17 0.2490688711 ( -6.6388969421 0.2405914068 -4.7276105881 ) - weight 2142 3 0.3415644169 ( -9.2207612991 1.6964797974 -2.2897474766 ) - weight 2143 17 0.6584355831 ( -9.2256288528 1.4564298391 -1.6177349091 ) - weight 2144 17 0.9400740266 ( -5.5777144432 1.5309972763 6.0351920128 ) - weight 2145 18 0.0599259473 ( -5.9224562645 1.1855773926 -1.2348527908 ) - weight 2146 3 0.5783586502 ( -8.1920776367 -0.8163146973 -1.0460239649 ) - weight 2147 10 0.18198663 ( 2.7876214981 -0.4874369204 2.5539681911 ) - weight 2148 17 0.2396547645 ( -8.1272439957 -1.2672761679 -1.0753765106 ) - weight 2149 3 0.5168976188 ( -8.5529117584 -2.4308357239 -1.5962525606 ) - weight 2150 10 0.4053937197 ( 3.4373977184 1.1228123903 2.397383213 ) - weight 2151 17 0.0777087063 ( -8.5190696716 -2.7068743706 -1.9774078131 ) - weight 2152 3 0.4595703781 ( -7.4836421013 -3.0989532471 -3.8217885494 ) - weight 2153 10 0.5404295921 ( 5.1407203674 1.4433077574 0.5162389278 ) - weight 2154 3 0.5718590021 ( -4.3932647705 -3.5176467896 -5.3897557259 ) - weight 2155 10 0.3662455082 ( 5.5101075172 1.2204933167 -2.9475977421 ) - weight 2156 17 0.061895553 ( -4.5840520859 -2.7916517258 -6.1466927528 ) - weight 2157 3 0.8336464763 ( -1.913808465 -3.3067474365 -7.8268809319 ) - weight 2158 10 0.0789414868 ( 6.9061770439 0.4224061072 -6.0372266769 ) - weight 2159 17 0.0874120444 ( -2.2485899925 -1.9664485455 -8.595451355 ) - weight 2160 3 0.6841779947 ( -2.444637537 -3.2959518433 -5.5065488815 ) - weight 2161 10 0.3158220053 ( 4.925868988 0.6630477309 -4.7386469841 ) - weight 2162 3 0.7716712356 ( -4.1899290085 -1.6877632141 -7.9363541603 ) - weight 2163 10 0.0819741115 ( 7.8100223541 -0.7895064354 -3.6860249043 ) - weight 2164 17 0.1463547051 ( -4.52724123 -0.4003068209 -8.1846389771 ) - weight 2165 2 0.0738857314 ( -3.993573904 3.7327461243 -6.7396769524 ) - weight 2166 17 0.8506604433 ( -4.3212885857 4.5262069702 -5.5760712624 ) - weight 2167 19 0.0754538476 ( -4.0615124702 -5.8018012047 -4.1480336189 ) - weight 2168 3 0.5406886339 ( -5.0050058365 0.8726997375 -6.4387798309 ) - weight 2169 17 0.4593113661 ( -5.255004406 1.7132292986 -6.0712590218 ) - weight 2170 3 0.6925443411 ( -3.8358399868 -1.8299789429 -6.1626839638 ) - weight 2171 10 0.1600997746 ( 6.0269403458 -0.5868868828 -3.4194276333 ) - weight 2172 17 0.1473558843 ( -4.071917057 -0.960071981 -6.5200510025 ) - weight 2173 10 1 ( -2.8318982124 13.9612131119 0.2167639583 ) - weight 2174 10 0.9065700769 ( 1.9917657375 12.5870866776 -6.2155742645 ) - weight 2175 11 0.0934299231 ( 5.5919327736 -7.0929327011 0.1958042085 ) - weight 2176 10 0.938369453 ( 3.3868877888 15.7493696213 -6.6809105873 ) - weight 2177 11 0.061630547 ( 5.7202038765 -3.6722791195 0.863345027 ) - weight 2178 10 0.8470793366 ( 7.187016964 16.3921489716 -4.4996452332 ) - weight 2179 11 0.1529206634 ( 4.0683670044 -2.533395052 4.8113117218 ) - weight 2180 10 0.8603097796 ( 8.3704624176 16.5937252045 -0.7250724435 ) - weight 2181 11 0.1396902204 ( 0.5404887795 -2.596760273 6.6109333038 ) - weight 2182 10 0.2151181996 ( 6.1628146172 21.1770420074 -5.6612510681 ) - weight 2183 11 0.7848817706 ( 4.228521347 2.0340275764 2.7121419907 ) - weight 2184 10 0.1819262058 ( 3.9234867096 21.6813087463 -6.877866745 ) - weight 2185 11 0.8180738091 ( 4.9847435951 2.2078738213 0.2328411043 ) - weight 2186 10 0.3353833854 ( 8.0218553543 20.1771125793 -2.0019233227 ) - weight 2187 11 0.6646165848 ( 1.1205356121 0.9683719277 5.3675842285 ) - weight 2188 10 0.2997517288 ( 6.7989807129 20.657453537 0.6703159213 ) - weight 2189 11 0.7002482414 ( -1.7495365143 0.809502244 4.5901150703 ) - weight 2190 10 0.2811096311 ( -0.0955100358 21.4083194733 -4.3310041428 ) - weight 2191 11 0.7188903689 ( 1.937422514 0.7392976284 -3.1243133545 ) - weight 2192 10 0.5023835897 ( 1.2966246605 19.3807792664 -6.441634655 ) - weight 2193 11 0.4976164699 ( 4.5498833656 -0.6385374665 -1.7900220156 ) - weight 2194 3 0.3274889588 ( -4.6096715927 -6.3897628784 -5.1972723007 ) - weight 2195 10 0.6725110412 ( 5.4199728966 4.0939011574 -3.20900774 ) - weight 2196 3 0.0973081291 ( -2.6723082066 -9.8318786621 -4.8259959221 ) - weight 2197 10 0.9026918411 ( 4.3999652863 7.1737031937 -5.4923796654 ) - weight 2198 3 0.3993753195 ( -6.6437540054 1.3305397034 5.4829316139 ) - weight 2199 17 0.6006246805 ( -6.2066726685 -0.732717514 5.6817827225 ) - weight 2200 3 0.5583897829 ( -2.5144910812 0.7969169617 7.1620235443 ) - weight 2201 10 0.0565090142 ( -6.9093542099 -2.469432354 0.4924379885 ) - weight 2202 17 0.3851011992 ( -1.9878294468 -1.5973944664 6.9500927925 ) - weight 2203 3 0.3739424348 ( -9.0320224762 1.3259239197 1.6488970518 ) - weight 2204 17 0.6260575652 ( -8.8110990524 0.1520039588 2.0987815857 ) - weight 2205 3 0.0579726622 ( -9.316608429 -9.6764068604 -3.3686742783 ) - weight 2206 10 0.9420273304 ( 5.3980126381 8.25203228 1.1510976553 ) - weight 2207 10 1 ( 3.5496091843 12.1405601501 3.6236846447 ) - weight 2208 10 1 ( -2.9593110085 12.8373622894 -1.9628950357 ) - weight 2209 10 0.9135693312 ( -0.535693109 12.7338590622 -4.8837475777 ) - weight 2210 11 0.0864306688 ( 3.8840463161 -7.671848774 -2.0248558521 ) - weight 2211 10 1 ( 3.4483308792 16.3121585846 3.4166944027 ) - weight 2212 10 0.9345930815 ( -1.4839195013 16.9273872375 -4.720911026 ) - weight 2213 11 0.0654069185 ( 2.8670966625 -3.8397374153 -3.6958022118 ) - weight 2214 3 0.6283817291 ( -2.1810204983 0.476852417 6.8841814995 ) - weight 2215 17 0.3716182709 ( -1.6708586216 -1.8365861177 6.5851860046 ) - weight 2216 10 0.431024462 ( 1.8443117142 22.3109493256 1.2349326611 ) - weight 2217 11 0.5689755678 ( -3.3379693031 1.2731691599 -0.3962140083 ) - weight 2218 10 0.7502797246 ( 0.628051579 22.1971168518 2.8060293198 ) - weight 2219 11 0.2497202754 ( -5.0339899063 0.6900937557 -1.2588427067 ) - weight 2220 10 0.683310926 ( -0.5699542761 22.4954986572 1.8704859018 ) - weight 2221 11 0.316689074 ( -4.3571634293 0.8493446112 -2.6430521011 ) - weight 2222 10 0.171483025 ( 3.9673690796 22.336473465 1.7316240072 ) - weight 2223 11 0.8285169601 ( -3.5012640953 1.6845418215 1.7389284372 ) - weight 2224 10 0.0982733443 ( 1.0826781988 23.418592453 1.730946064 ) - weight 2225 11 0.9017266631 ( -4.1257200241 2.1146650314 -1.24728477 ) - weight 2226 10 0.6876799464 ( 2.1951699257 21.5000915527 3.1155035496 ) - weight 2227 11 0.3123200536 ( -4.9770913124 0.3089396656 0.4408524334 ) - weight 2228 10 0.4544913769 ( 2.8218314648 21.9772167206 1.6690613031 ) - weight 2229 11 0.5455086231 ( -3.5543670654 1.1005110741 0.6894888282 ) - weight 2230 10 0.355009973 ( -0.1976798624 22.79454422 0.1959369481 ) - weight 2231 11 0.644990027 ( -2.720972538 1.4451463223 -2.6485114098 ) - weight 2232 3 0.4564072788 ( -7.7421154976 0.9609069824 -5.0669183731 ) - weight 2233 17 0.5435926914 ( -7.908847332 1.4309948683 -4.568256855 ) - weight 2234 11 1 ( -3.6202497482 14.5849456787 0.5755332708 ) - weight 2235 11 1 ( -2.0250632763 6.4106388092 2.4584269524 ) - weight 2236 11 1 ( 4.4473080635 6.522310257 -2.0394637585 ) - weight 2237 3 0.5706210136 ( 0 -6.4435005188 -0.7945626974 ) - weight 2238 10 0.2444686294 ( -0.3330979347 3.668150425 -5.9213366508 ) - weight 2239 4 0.1849103719 ( 0.3308681846 3.6674599648 -5.921916008 ) - weight 2240 3 1 ( 0 -6.9307518005 4.3343024254 ) - weight 2241 3 1 ( 0 -6.2899169922 5.701294899 ) - weight 2242 3 0.8529544473 ( 0 -7.0987930298 2.1572291851 ) - weight 2243 10 0.0950579122 ( -3.0892817974 4.5170712471 -5.0128941536 ) - weight 2244 4 0.051987648 ( 3.0875768661 4.5161261559 -5.0148296356 ) - weight 2245 3 1 ( 0 -3.7084846497 7.0728874207 ) - weight 2246 3 1 ( 0 -5.3432731628 6.1642313004 ) - weight 2247 3 0.9083166122 ( 0 -1.7062454224 7.495516777 ) - weight 2248 17 0.0916833803 ( 0.541659534 -4.0722556114 6.5300312042 ) - weight 2249 17 0.9216430187 ( 0.5605891943 0.6935340166 8.0523357391 ) - weight 2250 18 0.0783569664 ( 0.0817569122 0.8587875366 1.2734565735 ) - weight 2251 17 1 ( 0.081125766 3.7080118656 0.2092006356 ) - weight 2252 3 0.5332571268 ( 0 0.3627929688 7.7244319916 ) - weight 2253 17 0.4667428732 ( 0.5548006296 -2.1192321777 7.2503423691 ) - weight 2254 3 0.6114505529 ( 0 -6.3574485779 -3.6433954239 ) - weight 2255 10 0.2373570949 ( 2.3294017315 3.3859276772 -6.8984241486 ) - weight 2256 4 0.1511923671 ( -2.3321139812 3.3854715824 -6.897755146 ) - weight 2257 3 0.7903205156 ( 0 -4.299747467 -5.589805603 ) - weight 2258 10 0.1313618273 ( 4.1395335197 1.2282072306 -7.198943615 ) - weight 2259 4 0.0783176422 ( -4.142663002 1.2279520035 -7.197201252 ) - weight 2260 3 0.8056060076 ( 0 -2.7871551514 -8.9534168243 ) - weight 2261 17 0.1943940073 ( -0.4026074111 -1.1647173166 -9.6684360504 ) - weight 2262 3 0.404081285 ( 0 1.5977706909 -9.9344148636 ) - weight 2263 17 0.595918715 ( -0.4589225352 3.3270010948 -9.5624780655 ) - weight 2264 17 1 ( -0.3374337852 4.9841151237 -6.9741506577 ) - weight 2265 17 1 ( 8.8036231995 3.0174238682 -0.9907625914 ) - weight 2266 17 1 ( -8.6983013153 2.7749519348 -0.0140348468 ) -} - -mesh { - // meshes: npcplayerarmmesh - shader "models/characters/male_npc/marine/marine2" - - numverts 234 - vert 0 ( 0.6892012358 0.1287859678 ) 198 3 - vert 1 ( 0.678588748 0.1864956617 ) 196 1 - vert 2 ( 0.7339951992 0.1759041548 ) 31 2 - vert 3 ( 0.6746309996 0.0066125393 ) 156 1 - vert 4 ( 0.6742375493 0.037699759 ) 0 3 - vert 5 ( 0.7503640056 0.0266385674 ) 17 2 - vert 6 ( 0.7935445905 0.2292523384 ) 8 2 - vert 7 ( 0.7950570583 0.2787386179 ) 3 2 - vert 8 ( 0.8341670036 0.2777048349 ) 183 2 - vert 9 ( 0.917901814 0.2129709125 ) 5 3 - vert 10 ( 0.8471309543 0.2394387722 ) 24 2 - vert 11 ( 0.897477746 0.2606310844 ) 26 1 - vert 12 ( 0.8345287442 0.2047099471 ) 10 2 - vert 13 ( 0.8579492569 0.1703155041 ) 177 2 - vert 14 ( 0.7965861559 0.1753524542 ) 12 2 - vert 15 ( 0.8064574003 0.144697547 ) 191 2 - vert 16 ( 0.7179743052 0.2419897914 ) 14 1 - vert 17 ( 0.679875195 0.2467265725 ) 197 1 - vert 18 ( 0.7722386122 0.2588187456 ) 15 1 - vert 19 ( 0.6807342768 0.2821919322 ) 153 3 - vert 20 ( 0.7193593979 0.2930397987 ) 16 1 - vert 21 ( 0.7516230941 0.308840394 ) 17 2 - vert 22 ( 0.6860916615 0.3187592626 ) 156 1 - vert 23 ( 0.807146728 0.2980099916 ) 181 2 - vert 24 ( 0.8661316633 0.2954487801 ) 179 2 - vert 25 ( 0.7183576822 0.1012596488 ) 27 2 - vert 26 ( 0.7525360584 0.1319494843 ) 22 2 - vert 27 ( 0.8066537976 0.1075088978 ) 33 2 - vert 28 ( 0.8242529631 0.1078128815 ) 173 2 - vert 29 ( 0.8711097836 0.1343283653 ) 187 2 - vert 30 ( 0.9827861786 0.1666784286 ) 150 3 - vert 31 ( 0.8036630154 0.0820199251 ) 171 2 - vert 32 ( 0.7453377843 0.0694212914 ) 29 2 - vert 33 ( 0.8680710196 0.0273209214 ) 179 2 - vert 34 ( 0.87234056 0.0675657988 ) 189 2 - vert 35 ( 0.9717440605 0.0449967384 ) 160 3 - vert 36 ( 0.8069608212 0.0372695923 ) 181 2 - vert 37 ( 0.8223848343 0.079164505 ) 175 2 - vert 38 ( 0.9664084911 0.23391366 ) 163 4 - vert 39 ( 0.9693170786 0.2536504269 ) 160 3 - vert 40 ( 0.8898932338 0.0980235338 ) 185 2 - vert 41 ( 0.9890729189 0.0804445744 ) 35 3 - vert 42 ( 0.6881553531 0.0778922439 ) 19 3 - vert 43 ( 0.8541458845 0.3220047355 ) 150 3 - vert 44 ( 0.837493062 0.3399941921 ) 157 3 - vert 45 ( 0.8126410246 0.3228954673 ) 38 3 - vert 46 ( 0.9912706614 0.1175416708 ) 38 3 - vert 47 ( 0.9278725386 0.4118318558 ) 102 2 - vert 48 ( 0.9395094514 0.3789896965 ) 147 3 - vert 49 ( 0.9386466146 0.3999456763 ) 41 2 - vert 50 ( 0.6749148369 0.3546446562 ) 66 2 - vert 51 ( 0.7283997536 0.3689396381 ) 43 3 - vert 52 ( 0.6946493387 0.3748873472 ) 41 2 - vert 53 ( 0.9142100811 0.4110491276 ) 126 3 - vert 54 ( 0.6943199635 0.4136072397 ) 102 2 - vert 55 ( 0.7252914906 0.3387631774 ) 83 2 - vert 56 ( 0.7861574888 0.3374982476 ) 113 4 - vert 57 ( 0.7365289927 0.4275733829 ) 142 2 - vert 58 ( 0.7038624883 0.4392943382 ) 46 2 - vert 59 ( 0.7230203152 0.4433073997 ) 109 2 - vert 60 ( 0.9325876236 0.4340229034 ) 46 2 - vert 61 ( 0.9354342818 0.4667528272 ) 48 2 - vert 62 ( 0.9280785322 0.478763938 ) 50 2 - vert 63 ( 0.7003704309 0.4619246721 ) 48 2 - vert 64 ( 0.7182919979 0.4647607803 ) 63 1 - vert 65 ( 0.8563842177 0.4686590433 ) 121 5 - vert 66 ( 0.8783878088 0.4474788904 ) 134 4 - vert 67 ( 0.8703999519 0.483458221 ) 138 4 - vert 68 ( 0.8125691414 0.3461306691 ) 52 4 - vert 69 ( 0.8071279526 0.4110658169 ) 99 3 - vert 70 ( 0.8074552417 0.4590307474 ) 56 2 - vert 71 ( 0.7788736224 0.4778406024 ) 132 2 - vert 72 ( 0.7554546595 0.4745789766 ) 138 4 - vert 73 ( 0.8201881647 0.4488726854 ) 91 3 - vert 74 ( 0.8266327381 0.4640107155 ) 56 2 - vert 75 ( 0.8486112356 0.4842085838 ) 132 2 - vert 76 ( 0.8229140043 0.4289427996 ) 89 2 - vert 77 ( 0.8675720692 0.436275363 ) 117 4 - vert 78 ( 0.8288050294 0.4070213437 ) 87 2 - vert 79 ( 0.8066686392 0.431165576 ) 58 3 - vert 80 ( 0.9206453562 0.4363577366 ) 61 2 - vert 81 ( 0.8856689334 0.33799088 ) 167 4 - vert 82 ( 0.8785381913 0.4087275267 ) 94 5 - vert 83 ( 0.9502669573 0.4085544944 ) 77 2 - vert 84 ( 0.9695452452 0.4046721458 ) 74 3 - vert 85 ( 0.9723471403 0.4295176268 ) 81 2 - vert 86 ( 0.9571654201 0.3766009212 ) 144 3 - vert 87 ( 0.9873473048 0.401676774 ) 70 2 - vert 88 ( 0.9553870559 0.426817596 ) 72 2 - vert 89 ( 0.9388959408 0.4156811237 ) 68 2 - vert 90 ( 0.6719590425 0.3949234486 ) 72 2 - vert 91 ( 0.6628922224 0.4018360376 ) 81 2 - vert 92 ( 0.6582326293 0.3899405003 ) 79 2 - vert 93 ( 0.9254279733 0.3435356617 ) 85 2 - vert 94 ( 0.9501863718 0.340477705 ) 104 2 - vert 95 ( 0.9649311304 0.3407807946 ) 83 2 - vert 96 ( 0.9743753076 0.3744565845 ) 66 2 - vert 97 ( 0.6601161957 0.3706606627 ) 70 2 - vert 98 ( 0.6796995997 0.3784372807 ) 68 2 - vert 99 ( 0.8881253004 0.4392631054 ) 109 2 - vert 100 ( 0.9025087357 0.437538147 ) 111 2 - vert 101 ( 0.8979417086 0.4786269069 ) 63 1 - vert 102 ( 0.911457181 0.4798519611 ) 64 2 - vert 103 ( 0.8941028714 0.4077472687 ) 106 3 - vert 104 ( 0.8857492208 0.4264067411 ) 142 2 - vert 105 ( 0.7173301578 0.4751109481 ) 64 2 - vert 106 ( 0.6988962293 0.4720472693 ) 50 2 - vert 107 ( 0.9152733684 0.4601750374 ) 129 3 - vert 108 ( 0.7451138496 0.4509702325 ) 134 4 - vert 109 ( 0.9856037498 0.4272305369 ) 79 2 - vert 110 ( 0.7929831147 0.3236703873 ) 35 3 - vert 111 ( 0.92616117 0.3216837645 ) 163 4 - vert 112 ( 0.7564870715 0.3203434944 ) 160 3 - vert 113 ( 0.9648541212 0.3249017 ) 160 3 - vert 114 ( 0.9684703946 0.2138465643 ) 193 3 - vert 115 ( 0.8936831355 0.3203366995 ) 193 3 - vert 116 ( 0.6886357069 0.1012681127 ) 201 3 - vert 117 ( 0.678588748 0.1864956617 ) 358 1 - vert 118 ( 0.6892012358 0.1287859678 ) 360 1 - vert 119 ( 0.7339951992 0.1759041548 ) 223 1 - vert 120 ( 0.6742375493 0.037699759 ) 204 1 - vert 121 ( 0.6746309996 0.0066125393 ) 333 1 - vert 122 ( 0.7503640056 0.0266385674 ) 216 1 - vert 123 ( 0.7950570583 0.2787386179 ) 205 2 - vert 124 ( 0.7935445905 0.2292523384 ) 208 2 - vert 125 ( 0.8341670036 0.2777048349 ) 350 1 - vert 126 ( 0.8471309543 0.2394387722 ) 219 1 - vert 127 ( 0.917901814 0.2129709125 ) 207 1 - vert 128 ( 0.897477746 0.2606310844 ) 220 1 - vert 129 ( 0.8345287442 0.2047099471 ) 210 1 - vert 130 ( 0.8579492569 0.1703155041 ) 346 1 - vert 131 ( 0.7965861559 0.1753524542 ) 211 2 - vert 132 ( 0.8064574003 0.144697547 ) 354 2 - vert 133 ( 0.7179743052 0.2419897914 ) 213 1 - vert 134 ( 0.679875195 0.2467265725 ) 359 1 - vert 135 ( 0.7722386122 0.2588187456 ) 214 1 - vert 136 ( 0.6807342768 0.2821919322 ) 332 1 - vert 137 ( 0.7193593979 0.2930397987 ) 215 1 - vert 138 ( 0.7516230941 0.308840394 ) 216 1 - vert 139 ( 0.6860916615 0.3187592626 ) 333 1 - vert 140 ( 0.807146728 0.2980099916 ) 348 2 - vert 141 ( 0.8661316633 0.2954487801 ) 347 1 - vert 142 ( 0.7525360584 0.1319494843 ) 218 1 - vert 143 ( 0.7183576822 0.1012596488 ) 221 1 - vert 144 ( 0.8066537976 0.1075088978 ) 224 2 - vert 145 ( 0.8242529631 0.1078128815 ) 344 1 - vert 146 ( 0.8711097836 0.1343283653 ) 352 1 - vert 147 ( 0.9827861786 0.1666784286 ) 330 2 - vert 148 ( 0.8036630154 0.0820199251 ) 342 2 - vert 149 ( 0.7453377843 0.0694212914 ) 222 1 - vert 150 ( 0.87234056 0.0675657988 ) 353 1 - vert 151 ( 0.8680710196 0.0273209214 ) 347 1 - vert 152 ( 0.9717440605 0.0449967384 ) 336 2 - vert 153 ( 0.8223848343 0.079164505 ) 345 1 - vert 154 ( 0.8069608212 0.0372695923 ) 348 2 - vert 155 ( 0.9664084911 0.23391366 ) 338 2 - vert 156 ( 0.9693170786 0.2536504269 ) 336 2 - vert 157 ( 0.8898932338 0.0980235338 ) 351 1 - vert 158 ( 0.9890729189 0.0804445744 ) 226 2 - vert 159 ( 0.6881553531 0.0778922439 ) 217 1 - vert 160 ( 0.837493062 0.3399941921 ) 334 2 - vert 161 ( 0.8541458845 0.3220047355 ) 330 2 - vert 162 ( 0.8126410246 0.3228954673 ) 228 2 - vert 163 ( 0.9912706614 0.1175416708 ) 228 2 - vert 164 ( 0.9395094514 0.3789896965 ) 328 2 - vert 165 ( 0.9278725386 0.4118318558 ) 292 2 - vert 166 ( 0.9386466146 0.3999456763 ) 230 3 - vert 167 ( 0.7283997536 0.3689396381 ) 233 3 - vert 168 ( 0.6749148369 0.3546446562 ) 256 2 - vert 169 ( 0.6946493387 0.3748873472 ) 230 3 - vert 170 ( 0.9142100811 0.4110491276 ) 310 2 - vert 171 ( 0.6943199635 0.4136072397 ) 292 2 - vert 172 ( 0.7861574888 0.3374982476 ) 302 2 - vert 173 ( 0.7252914906 0.3387631774 ) 272 4 - vert 174 ( 0.7365289927 0.4275733829 ) 322 4 - vert 175 ( 0.7038624883 0.4392943382 ) 236 2 - vert 176 ( 0.7230203152 0.4433073997 ) 298 2 - vert 177 ( 0.9354342818 0.4667528272 ) 238 2 - vert 178 ( 0.9325876236 0.4340229034 ) 236 2 - vert 179 ( 0.9280785322 0.478763938 ) 240 2 - vert 180 ( 0.7003704309 0.4619246721 ) 238 2 - vert 181 ( 0.7182919979 0.4647607803 ) 252 2 - vert 182 ( 0.8783878088 0.4474788904 ) 315 5 - vert 183 ( 0.8563842177 0.4686590433 ) 308 2 - vert 184 ( 0.8703999519 0.483458221 ) 320 2 - vert 185 ( 0.8125691414 0.3461306691 ) 242 2 - vert 186 ( 0.8071279526 0.4110658169 ) 289 3 - vert 187 ( 0.7788736224 0.4778406024 ) 313 2 - vert 188 ( 0.8074552417 0.4590307474 ) 244 3 - vert 189 ( 0.7554546595 0.4745789766 ) 320 2 - vert 190 ( 0.8201881647 0.4488726854 ) 283 3 - vert 191 ( 0.8266327381 0.4640107155 ) 244 3 - vert 192 ( 0.8486112356 0.4842085838 ) 313 2 - vert 193 ( 0.8229140043 0.4289427996 ) 280 3 - vert 194 ( 0.8675720692 0.436275363 ) 304 4 - vert 195 ( 0.8288050294 0.4070213437 ) 278 2 - vert 196 ( 0.8066686392 0.431165576 ) 247 3 - vert 197 ( 0.9206453562 0.4363577366 ) 250 2 - vert 198 ( 0.8856689334 0.33799088 ) 340 2 - vert 199 ( 0.8785381913 0.4087275267 ) 286 3 - vert 200 ( 0.9695452452 0.4046721458 ) 264 2 - vert 201 ( 0.9502669573 0.4085544944 ) 266 2 - vert 202 ( 0.9723471403 0.4295176268 ) 270 2 - vert 203 ( 0.9571654201 0.3766009212 ) 326 2 - vert 204 ( 0.9873473048 0.401676774 ) 260 2 - vert 205 ( 0.9553870559 0.426817596 ) 262 2 - vert 206 ( 0.9388959408 0.4156811237 ) 258 2 - vert 207 ( 0.6628922224 0.4018360376 ) 270 2 - vert 208 ( 0.6719590425 0.3949234486 ) 262 2 - vert 209 ( 0.6582326293 0.3899405003 ) 268 2 - vert 210 ( 0.9254279733 0.3435356617 ) 276 2 - vert 211 ( 0.9649311304 0.3407807946 ) 272 4 - vert 212 ( 0.9501863718 0.340477705 ) 294 2 - vert 213 ( 0.9743753076 0.3744565845 ) 256 2 - vert 214 ( 0.6601161957 0.3706606627 ) 260 2 - vert 215 ( 0.6796995997 0.3784372807 ) 258 2 - vert 216 ( 0.9025087357 0.437538147 ) 300 2 - vert 217 ( 0.8881253004 0.4392631054 ) 298 2 - vert 218 ( 0.8979417086 0.4786269069 ) 252 2 - vert 219 ( 0.911457181 0.4798519611 ) 254 2 - vert 220 ( 0.8941028714 0.4077472687 ) 296 2 - vert 221 ( 0.8857492208 0.4264067411 ) 322 4 - vert 222 ( 0.7173301578 0.4751109481 ) 254 2 - vert 223 ( 0.6988962293 0.4720472693 ) 240 2 - vert 224 ( 0.9152733684 0.4601750374 ) 312 1 - vert 225 ( 0.7451138496 0.4509702325 ) 315 5 - vert 226 ( 0.9856037498 0.4272305369 ) 268 2 - vert 227 ( 0.7929831147 0.3236703873 ) 226 2 - vert 228 ( 0.92616117 0.3216837645 ) 338 2 - vert 229 ( 0.7564870715 0.3203434944 ) 336 2 - vert 230 ( 0.9648541212 0.3249017 ) 336 2 - vert 231 ( 0.9684703946 0.2138465643 ) 356 2 - vert 232 ( 0.8936831355 0.3203366995 ) 356 2 - vert 233 ( 0.6886357069 0.1012681127 ) 361 1 - - numtris 320 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 8 7 6 - tri 3 11 10 9 - tri 4 9 10 12 - tri 5 9 12 13 - tri 6 12 6 14 - tri 7 13 12 14 - tri 8 13 14 15 - tri 9 6 16 14 - tri 10 14 16 2 - tri 11 16 1 2 - tri 12 16 17 1 - tri 13 18 16 6 - tri 14 7 18 6 - tri 15 19 17 16 - tri 16 18 19 16 - tri 17 18 20 19 - tri 18 7 20 18 - tri 19 7 21 20 - tri 20 21 22 20 - tri 21 24 23 8 - tri 22 8 23 7 - tri 23 23 21 7 - tri 24 27 26 25 - tri 25 29 15 28 - tri 26 15 14 26 - tri 27 14 2 26 - tri 28 30 9 13 - tri 29 27 15 26 - tri 30 31 27 25 - tri 31 31 25 32 - tri 32 35 34 33 - tri 33 34 37 36 - tri 34 33 34 36 - tri 35 38 11 9 - tri 36 39 11 38 - tri 37 41 40 34 - tri 38 30 29 40 - tri 39 41 34 35 - tri 40 34 40 37 - tri 41 8 6 10 - tri 42 11 8 10 - tri 43 10 6 12 - tri 44 25 26 0 - tri 45 32 25 42 - tri 46 26 2 0 - tri 47 45 44 43 - tri 48 46 30 40 - tri 49 41 46 40 - tri 50 49 48 47 - tri 51 52 51 50 - tri 52 47 48 53 - tri 53 52 54 51 - tri 54 51 56 55 - tri 55 58 57 54 - tri 56 58 59 57 - tri 57 62 61 60 - tri 58 63 59 58 - tri 59 64 59 63 - tri 60 67 66 65 - tri 61 69 68 56 - tri 62 60 47 53 - tri 63 72 71 70 - tri 64 74 65 73 - tri 65 75 65 74 - tri 66 65 76 73 - tri 67 65 77 76 - tri 68 69 76 78 - tri 69 79 76 69 - tri 70 73 76 79 - tri 71 60 53 80 - tri 72 62 60 80 - tri 73 67 65 75 - tri 74 69 78 68 - tri 75 78 44 68 - tri 76 53 48 81 - tri 77 82 81 44 - tri 78 51 55 50 - tri 79 85 84 83 - tri 80 87 86 84 - tri 81 85 83 88 - tri 82 88 83 89 - tri 83 92 91 90 - tri 84 86 93 48 - tri 85 48 93 81 - tri 86 96 95 94 - tri 87 87 96 86 - tri 88 98 50 97 - tri 89 83 48 49 - tri 90 101 100 99 - tri 91 102 100 101 - tri 92 78 82 44 - tri 93 89 83 49 - tri 94 98 52 50 - tri 95 77 82 78 - tri 96 76 77 78 - tri 97 104 103 82 - tri 98 103 81 82 - tri 99 53 81 103 - tri 100 96 93 86 - tri 101 96 94 93 - tri 102 69 56 51 - tri 103 69 51 57 - tri 104 57 51 54 - tri 105 104 100 103 - tri 106 99 100 104 - tri 107 106 105 63 - tri 108 105 64 63 - tri 109 107 80 100 - tri 110 102 107 100 - tri 111 62 107 102 - tri 112 62 80 107 - tri 113 66 82 77 - tri 114 66 104 82 - tri 115 65 66 77 - tri 116 72 70 79 - tri 117 70 73 79 - tri 118 79 57 108 - tri 119 79 69 57 - tri 120 72 79 108 - tri 121 80 103 100 - tri 122 80 53 103 - tri 123 84 48 83 - tri 124 84 86 48 - tri 125 85 87 84 - tri 126 109 87 85 - tri 127 92 98 97 - tri 128 92 90 98 - tri 129 20 22 19 - tri 130 68 44 45 - tri 131 56 68 110 - tri 132 68 45 110 - tri 133 44 81 43 - tri 134 93 111 81 - tri 135 55 56 112 - tri 136 56 110 112 - tri 137 94 111 93 - tri 138 94 113 111 - tri 139 95 113 94 - tri 140 39 24 11 - tri 141 24 8 11 - tri 142 40 28 37 - tri 143 40 29 28 - tri 144 30 13 29 - tri 145 29 13 15 - tri 146 5 32 4 - tri 147 32 42 4 - tri 148 36 31 32 - tri 149 36 32 5 - tri 150 28 15 27 - tri 151 36 37 31 - tri 152 30 114 9 - tri 153 81 115 43 - tri 154 111 115 81 - tri 155 38 9 114 - tri 156 37 28 27 - tri 157 37 27 31 - tri 158 25 116 42 - tri 159 25 0 116 - tri 160 119 118 117 - tri 161 122 121 120 - tri 162 125 124 123 - tri 163 128 127 126 - tri 164 127 129 126 - tri 165 127 130 129 - tri 166 129 131 124 - tri 167 130 131 129 - tri 168 130 132 131 - tri 169 124 131 133 - tri 170 131 119 133 - tri 171 133 119 117 - tri 172 133 117 134 - tri 173 135 124 133 - tri 174 123 124 135 - tri 175 136 133 134 - tri 176 135 133 136 - tri 177 135 136 137 - tri 178 123 135 137 - tri 179 123 137 138 - tri 180 138 137 139 - tri 181 141 125 140 - tri 182 125 123 140 - tri 183 140 123 138 - tri 184 144 143 142 - tri 185 146 145 132 - tri 186 132 142 131 - tri 187 131 142 119 - tri 188 147 130 127 - tri 189 144 142 132 - tri 190 148 143 144 - tri 191 148 149 143 - tri 192 152 151 150 - tri 193 150 154 153 - tri 194 151 154 150 - tri 195 155 127 128 - tri 196 156 155 128 - tri 197 158 150 157 - tri 198 147 157 146 - tri 199 158 152 150 - tri 200 150 153 157 - tri 201 125 126 124 - tri 202 128 126 125 - tri 203 126 129 124 - tri 204 143 118 142 - tri 205 149 159 143 - tri 206 142 118 119 - tri 207 162 161 160 - tri 208 163 157 147 - tri 209 158 157 163 - tri 210 166 165 164 - tri 211 169 168 167 - tri 212 165 170 164 - tri 213 169 167 171 - tri 214 167 173 172 - tri 215 175 171 174 - tri 216 175 174 176 - tri 217 179 178 177 - tri 218 180 175 176 - tri 219 181 180 176 - tri 220 184 183 182 - tri 221 186 172 185 - tri 222 178 170 165 - tri 223 189 188 187 - tri 224 191 190 183 - tri 225 192 191 183 - tri 226 183 190 193 - tri 227 183 193 194 - tri 228 186 195 193 - tri 229 196 186 193 - tri 230 190 196 193 - tri 231 178 197 170 - tri 232 179 197 178 - tri 233 184 192 183 - tri 234 186 185 195 - tri 235 195 185 160 - tri 236 170 198 164 - tri 237 199 160 198 - tri 238 167 168 173 - tri 239 202 201 200 - tri 240 204 200 203 - tri 241 202 205 201 - tri 242 205 206 201 - tri 243 209 208 207 - tri 244 203 164 210 - tri 245 164 198 210 - tri 246 213 212 211 - tri 247 204 203 213 - tri 248 215 214 168 - tri 249 201 166 164 - tri 250 218 217 216 - tri 251 219 218 216 - tri 252 195 160 199 - tri 253 206 166 201 - tri 254 215 168 169 - tri 255 194 195 199 - tri 256 193 195 194 - tri 257 221 199 220 - tri 258 220 199 198 - tri 259 170 220 198 - tri 260 213 203 210 - tri 261 213 210 212 - tri 262 186 167 172 - tri 263 186 174 167 - tri 264 174 171 167 - tri 265 221 220 216 - tri 266 217 221 216 - tri 267 223 180 222 - tri 268 222 180 181 - tri 269 224 216 197 - tri 270 219 216 224 - tri 271 179 219 224 - tri 272 179 224 197 - tri 273 182 194 199 - tri 274 182 199 221 - tri 275 183 194 182 - tri 276 189 196 188 - tri 277 188 196 190 - tri 278 196 225 174 - tri 279 196 174 186 - tri 280 189 225 196 - tri 281 197 216 220 - tri 282 197 220 170 - tri 283 200 201 164 - tri 284 200 164 203 - tri 285 202 200 204 - tri 286 226 202 204 - tri 287 209 214 215 - tri 288 209 215 208 - tri 289 137 136 139 - tri 290 185 162 160 - tri 291 172 227 185 - tri 292 185 227 162 - tri 293 160 161 198 - tri 294 210 198 228 - tri 295 173 229 172 - tri 296 172 229 227 - tri 297 212 210 228 - tri 298 212 228 230 - tri 299 211 212 230 - tri 300 156 128 141 - tri 301 141 128 125 - tri 302 157 153 145 - tri 303 157 145 146 - tri 304 147 146 130 - tri 305 146 132 130 - tri 306 122 120 149 - tri 307 149 120 159 - tri 308 154 149 148 - tri 309 154 122 149 - tri 310 145 144 132 - tri 311 154 148 153 - tri 312 147 127 231 - tri 313 198 161 232 - tri 314 228 198 232 - tri 315 155 231 127 - tri 316 153 144 145 - tri 317 153 148 144 - tri 318 143 159 233 - tri 319 143 233 118 - - numweights 362 - weight 0 23 0.0576419383 ( -1.9732186794 7.9749250412 -3.6290724277 ) - weight 1 24 0.0576419383 ( -2.670797348 -1.8051134348 -4.0931510925 ) - weight 2 25 0.8847161531 ( -2.0204322338 4.574631691 -1.4873862267 ) - weight 3 25 0.5551297069 ( 1.1205506325 11.2560138702 -1.1015797853 ) - weight 4 26 0.4448702335 ( 1.5657212734 -0.1051112488 -0.9827913642 ) - weight 5 26 0.8932403922 ( 0.1229631975 6.5929331779 2.1687953472 ) - weight 6 27 0.0533797592 ( 2.0164794922 -1.8390936852 2.3137421608 ) - weight 7 28 0.0533797592 ( 1.4617888927 -2.6500937939 1.9084113836 ) - weight 8 25 0.5678648949 ( 2.0095412731 10.9471683502 1.3677694798 ) - weight 9 26 0.4321351349 ( 1.5756648779 -0.3235476315 1.6507544518 ) - weight 10 25 0.2775050104 ( 2.4579071999 13.2332677841 2.2894203663 ) - weight 11 26 0.7224949598 ( 0.9086527228 1.9031646252 2.5854053497 ) - weight 12 25 0.5112586617 ( 0.9905480742 11.3299398422 2.8930010796 ) - weight 13 26 0.4887413383 ( 0.019335879 -0.4072645009 2.6909587383 ) - weight 14 25 1 ( 2.6560173035 6.5141134262 0.8726161718 ) - weight 15 25 1 ( 2.5828256607 9.7114229202 -0.2929700315 ) - weight 16 25 1 ( 1.4948009253 6.1746864319 -1.8959311247 ) - weight 17 25 0.9422889948 ( -0.1770550758 8.9655971527 -1.3759829998 ) - weight 18 26 0.0577109754 ( 1.2597341537 -2.655708313 -1.6199061871 ) - weight 19 23 0.0829836801 ( -3.0189864635 8.2031240463 -2.2921538353 ) - weight 20 24 0.0829836801 ( -3.1777486801 -2.820366621 -2.8104515076 ) - weight 21 25 0.8340325952 ( -2.8108625412 4.2625246048 -0.0004881943 ) - weight 22 25 0.8640651107 ( -0.6310817003 8.9488735199 2.4362194538 ) - weight 23 26 0.1359348744 ( -0.4778713882 -3.130022049 1.7705304623 ) - weight 24 25 0.0857474729 ( 2.7882032394 13.9643688202 0.995023191 ) - weight 25 26 0.9142525196 ( 1.4198474884 2.8056604862 1.4703947306 ) - weight 26 26 1 ( 0.8895722628 5.7064995766 0.500092566 ) - weight 27 25 0.9239218235 ( -2.4895153046 7.3979530334 1.3433667421 ) - weight 28 26 0.0760781541 ( -1.2261632681 -5.0888957977 0.1407056749 ) - weight 29 25 0.8646072745 ( -2.1944584846 8.9422683716 -0.3140411377 ) - weight 30 26 0.1353926808 ( -0.8797674775 -3.3980233669 -1.3559337854 ) - weight 31 25 0.9419451356 ( 0.3864062428 7.8312726021 2.4723131657 ) - weight 32 26 0.0580548979 ( 0.7632476687 -3.8714420795 2.2127242088 ) - weight 33 25 0.5 ( -2.2408697605 12.3473997116 1.5317767859 ) - weight 34 26 0.5 ( -2.6676316261 -0.3443991244 0.2198314369 ) - weight 35 26 0.2454880476 ( -1.2637517452 10.4955511093 0.1805298477 ) - weight 36 27 0.2454880476 ( -1.2455832958 -0.54720819 -0.6521609426 ) - weight 37 28 0.5090239048 ( -0.9051418304 -0.216931954 -1.1873867512 ) - weight 38 26 0.2666286826 ( -1.7569172382 10.5040969849 0.635492146 ) - weight 39 27 0.2666286826 ( -1.6803820133 -0.857210815 -0.2458061278 ) - weight 40 28 0.4667426348 ( -1.3949788809 -0.6685038805 -1.1072720289 ) - weight 41 36 0.2241006345 ( -0.0300707389 -0.3171514273 -1.8243727684 ) - weight 42 37 0.7758994102 ( 0.031686075 -0.4291681349 -0.3834321797 ) - weight 43 28 0.3141590655 ( -0.5433802605 2.5222628117 -1.1417521238 ) - weight 44 36 0.4663588703 ( 0.6771164536 -0.9101995826 -0.8207290769 ) - weight 45 37 0.219482094 ( 0.7388733029 -1.1568924189 0.5272951126 ) - weight 46 32 0.5211151838 ( 1.7004147768 0.1181314811 -0.6270828843 ) - weight 47 33 0.4788847566 ( -0.0636660606 0.1203930527 -0.6337025762 ) - weight 48 33 0.5670523047 ( 1.7716449499 0.0704614073 -0.7418365479 ) - weight 49 34 0.4329476655 ( -0.0309336372 0.28210482 0.6582835913 ) - weight 50 33 0.5 ( 2.0595469475 -0.3556416929 -0.7964100838 ) - weight 51 34 0.5 ( 0.4599271417 0.1287846118 0.7128571272 ) - weight 52 26 0.1444834173 ( -2.0553836823 11.4521369934 0.5126720071 ) - weight 53 27 0.1444834173 ( -2.5282385349 -0.4730849862 -0.6153123379 ) - weight 54 28 0.632081449 ( -2.1372218132 -0.1619500816 -1.5493428707 ) - weight 55 29 0.0789516494 ( -2.6759002209 -0.3189115524 1.4831682444 ) - weight 56 30 0.6102965474 ( 1.682221055 0.0088743437 0.6707113981 ) - weight 57 31 0.3897034526 ( -0.0534028374 0.3368496001 -0.7043007612 ) - weight 58 28 0.0535494126 ( -4.5596528053 3.2622430325 -2.0584928989 ) - weight 59 29 0.4566688836 ( 1.3125394583 0.870613575 0.7552391887 ) - weight 60 30 0.4897817373 ( 0.2795977592 0.6782312393 0.7430691719 ) - weight 61 32 0.5 ( 2.1563048363 -0.5969324708 -0.5548586249 ) - weight 62 33 0.5 ( -0.2719247341 -0.7016655803 -0.5614783168 ) - weight 63 33 1 ( 1.8193057775 0.0817919746 -0.0653976277 ) - weight 64 33 0.5 ( 2.0910246372 -0.3683001399 -0.0935819596 ) - weight 65 34 0.5 ( 0.4810967445 0.1022717133 0.0100290291 ) - weight 66 36 0.4978984892 ( 0.0412862562 1.0010617971 -1.6932739019 ) - weight 67 37 0.502101481 ( 0.1030430719 0.8577065468 -0.0690651238 ) - weight 68 37 0.5195088387 ( 0.2027581781 -0.0768486485 -1.4537329674 ) - weight 69 38 0.4804911315 ( 0.1578423381 -0.0664023682 0.022227658 ) - weight 70 37 0.5 ( 0.0341354012 0.7546498775 -1.5967175961 ) - weight 71 38 0.5 ( 0.0549456328 0.7869881988 -0.0152534926 ) - weight 72 37 0.5 ( -0.1672382802 -0.3891269863 -2.2933869362 ) - weight 73 38 0.5 ( -0.2878312171 -0.247570619 -0.8191918731 ) - weight 74 36 0.0554554202 ( -0.9177626967 0.5303177834 -3.1208570004 ) - weight 75 37 0.4722723067 ( -0.8560058475 0.5914710164 -1.548494935 ) - weight 76 38 0.4722723067 ( -0.8416300416 0.691716969 0.0762873143 ) - weight 77 37 0.5218823552 ( -0.7537373304 -0.2359314561 -1.3381561041 ) - weight 78 38 0.4781176746 ( -0.8003178835 -0.1601269394 0.1856100559 ) - weight 79 37 0.5 ( -0.0401894636 0.106853731 -2.6549606323 ) - weight 80 38 0.5 ( -0.1394073516 0.2753535509 -1.1312727928 ) - weight 81 37 0.5 ( -0.662396431 0.0584688596 -2.6866650581 ) - weight 82 38 0.5 ( -0.7642349005 0.2814101279 -1.1248227358 ) - weight 83 28 0.5302380919 ( 0.1792138219 1.6791321039 -0.930318594 ) - weight 84 36 0.4697618783 ( 0.9685338736 -0.0906692743 -0.0988138169 ) - weight 85 28 0.5636335015 ( 0.4677617252 1.5595424175 0.8588085771 ) - weight 86 36 0.4363665283 ( -0.5263146162 0.7332199812 0.5218085051 ) - weight 87 28 0.4873713851 ( -4.12180233 1.9585779905 -1.3777822256 ) - weight 88 29 0.5126286149 ( 0.1842724234 -0.144959569 0.9793970585 ) - weight 89 29 0.5077987909 ( 1.5357599258 -0.0634772107 0.9164494872 ) - weight 90 30 0.4922012389 ( -0.1938492656 -0.1502261013 0.9376151562 ) - weight 91 29 0.2177000046 ( 2.3106832504 0.6776840687 1.0195406675 ) - weight 92 30 0.6617738605 ( 0.8829037547 -0.1511318088 0.9701079726 ) - weight 93 31 0.1205260754 ( -0.1298268586 1.1484341621 -1.0036972761 ) - weight 94 28 0.2938368917 ( -3.3662679195 3.4394023418 0.502723217 ) - weight 95 32 0.3892431259 ( 0.5450658798 -0.902651906 0.9229545593 ) - weight 96 33 0.0943958238 ( -1.5988359451 0.2621091306 0.9163348675 ) - weight 97 29 0.1590775549 ( 0.4754417539 -0.6906510592 -1.4531766176 ) - weight 98 30 0.0634465888 ( -1.5462933779 0.1254119724 -1.3487943411 ) - weight 99 28 0.4310248494 ( -3.729467392 2.400203228 -2.2374305725 ) - weight 100 29 0.4612576663 ( 0.1305479109 0.8961555958 1.0132749081 ) - weight 101 30 0.1077174768 ( -0.5374426246 1.5151256323 1.0535392761 ) - weight 102 28 0.42453444 ( -1.7773190737 4.5783843994 0.1625697166 ) - weight 103 32 0.57546556 ( 0.3012800217 0.1543779224 -0.7386710644 ) - weight 104 28 0.5385727286 ( 0.8282727003 1.6771986485 -0.1800425351 ) - weight 105 36 0.4614272714 ( 0.4596131444 0.7524142265 0.0212080199 ) - weight 106 28 0.3769321442 ( -2.8331918716 3.7657351494 0.7189971209 ) - weight 107 32 0.5692532063 ( 0.4815347493 -0.8673289418 0.2655707002 ) - weight 108 33 0.0538146645 ( -1.6166557074 0.3325816691 0.2589510083 ) - weight 109 32 0.5839850903 ( 1.776145339 0.1403758973 0.1117812693 ) - weight 110 33 0.4160149395 ( 0.0044353423 0.0804915801 0.10516157 ) - weight 111 32 0.5 ( 2.1845498085 -0.5749771595 0.2121121585 ) - weight 112 33 0.5 ( -0.2365788221 -0.7071862221 0.2054924518 ) - weight 113 26 0.1239280999 ( -0.9500282407 11.2576093674 -0.3757827282 ) - weight 114 27 0.1239280999 ( -1.4577889442 0.122007072 -1.356262207 ) - weight 115 28 0.6744834781 ( -0.9860488772 0.6877509952 -1.5919133425 ) - weight 116 36 0.0776602998 ( 1.6157441139 -1.3155305386 0.8281248808 ) - weight 117 32 0.2470460832 ( 2.059322834 -0.5193263292 1.4241733551 ) - weight 118 33 0.2470460832 ( -0.2818799317 -0.577854991 1.4175536633 ) - weight 119 29 0.2529539168 ( 2.0918385983 -0.4458423257 -1.3172973394 ) - weight 120 30 0.2529539168 ( -0.2037777603 -0.8160167933 -1.2988274097 ) - weight 121 33 0.0778858811 ( 1.4364619255 -0.5408954024 1.946818471 ) - weight 122 34 0.0618004724 ( 0.4583257139 0.7788239717 -2.0303714275 ) - weight 123 29 0.0822327659 ( 3.4308817387 0.675237298 -0.8879614472 ) - weight 124 30 0.4319386482 ( 1.5631076097 -0.9322624803 -0.9845206738 ) - weight 125 31 0.3461421728 ( 0.8138157725 0.72137326 0.9509313107 ) - weight 126 28 0.3074325621 ( -2.2991728783 4.3965601921 0.9811779261 ) - weight 127 32 0.6011430025 ( 0.6514456868 -0.7549290657 -0.5772532225 ) - weight 128 33 0.0914243981 ( -1.4183552265 0.2858875096 -0.5838729143 ) - weight 129 32 0.1486402601 ( 3.0542192459 0.2815180719 -0.2869996727 ) - weight 130 33 0.7487152219 ( 0.9831618071 -0.7534679174 -0.2936193645 ) - weight 131 34 0.1026445702 ( 0.5316784978 1.2740889788 0.2100664377 ) - weight 132 30 0.5 ( 2.566026926 -0.2897580266 -0.4936056733 ) - weight 133 31 0.5 ( 0.4865948558 -0.4238714874 0.46001634 ) - weight 134 32 0.3526614308 ( 2.0317559242 0.5135233998 0.99615556 ) - weight 135 33 0.4830437601 ( 0.4513477981 0.1500980705 0.9895358682 ) - weight 136 29 0.0732576028 ( 2.0288460255 0.65239501 -1.5189020634 ) - weight 137 30 0.0910372213 ( 0.4957798123 0.0199846812 -1.5487444401 ) - weight 138 33 0.2102573812 ( 2.3750114441 0.2399440408 1.3907501698 ) - weight 139 34 0.2102573812 ( -0.0198925864 -0.3445160091 -1.4743031263 ) - weight 140 30 0.2897426188 ( 2.4537773132 -0.0023028285 -1.3609247208 ) - weight 141 31 0.2897426188 ( 0.1790080369 -0.398955524 1.3273354769 ) - weight 142 28 0.0648507923 ( -3.0011298656 4.3721418381 -0.3167573214 ) - weight 143 32 0.9351491928 ( 0.8527961373 0.2686532736 0.4666398168 ) - weight 144 36 0.4720931351 ( -0.8034633994 0.9792686105 -1.6167784929 ) - weight 145 37 0.4720931351 ( -0.7417065501 0.8254180551 0.0036256199 ) - weight 146 38 0.0558137372 ( -0.6144689322 0.7327861786 1.6330740452 ) - weight 147 28 0.0823455304 ( 0.1117459312 3.3898308277 0.6572881341 ) - weight 148 36 0.4902983308 ( -1.080850482 0.18361561 -1.183400631 ) - weight 149 37 0.4273560941 ( -1.0190937519 -0.0230741352 0.3213376999 ) - weight 150 26 0.3139925897 ( -1.670992732 10.1100673676 1.9553810358 ) - weight 151 27 0.3139925897 ( -1.6380577087 -0.8986822367 1.1330475807 ) - weight 152 28 0.372014761 ( -1.7629878521 -1.2890841961 0.0692474321 ) - weight 153 23 0.0550973006 ( 2.1794025898 8.7608327866 -3.0771989822 ) - weight 154 24 0.0554679967 ( -3.2663593292 2.3945295811 -3.6750831604 ) - weight 155 25 0.8894346952 ( 2.2380998135 4.751762867 -1.4901894331 ) - weight 156 25 1 ( -0.5326313376 4.9252338409 -2.067032814 ) - weight 157 26 0.2214462459 ( -1.5470708609 10.8529729843 1.6950386763 ) - weight 158 27 0.2214462459 ( -2.0286898613 -0.3495099247 0.7077715397 ) - weight 159 28 0.5571075678 ( -2.0795121193 -0.6105877757 -0.2036964595 ) - weight 160 26 0.3137998581 ( 0.0663032606 9.770318985 -0.1006719545 ) - weight 161 27 0.3064055443 ( 0.2167652994 -0.0618919246 -0.6614980102 ) - weight 162 28 0.3797945976 ( 0.4115706086 0.2229745239 -0.5189310312 ) - weight 163 26 0.2855843902 ( 1.061689496 9.7388658524 1.2303955555 ) - weight 164 27 0.2853357792 ( 0.5995862484 0.814462781 0.6982718706 ) - weight 165 28 0.3760794401 ( 0.2448079586 0.4413438737 1.1205898523 ) - weight 166 36 0.0530004464 ( -0.4249186218 0.6924955249 1.6865686178 ) - weight 167 26 0.21819897 ( 0.5208261609 10.6585912704 1.9128838778 ) - weight 168 27 0.21819897 ( -0.5693057775 1.0921424627 1.0992753506 ) - weight 169 28 0.4795914888 ( -1.0170484781 0.5265590549 1.1889653206 ) - weight 170 36 0.0840106234 ( -0.8389621973 -0.4924027026 1.8562822342 ) - weight 171 25 0.5 ( -2.5537135601 12.2838668823 0.0029187377 ) - weight 172 26 0.5 ( -2.3830349445 -0.3757121861 -1.315531373 ) - weight 173 25 0.4760326147 ( -2.01603508 13.2829170227 1.5820043087 ) - weight 174 26 0.5239673853 ( -2.788985014 0.6068931222 0.312473923 ) - weight 175 25 0.4804644883 ( -2.3227314949 13.2864608765 -0.1156587526 ) - weight 176 26 0.5195354819 ( -2.4610674381 0.6549631357 -1.3805396557 ) - weight 177 25 0.1664403081 ( 1.3096828461 14.8465747833 3.1187214851 ) - weight 178 26 0.8335596919 ( -0.9120449424 3.000774622 2.8841178417 ) - weight 179 25 0.0791453645 ( 0.1545709968 15.5579462051 -1.6851907969 ) - weight 180 26 0.9208546281 ( -0.4623253345 3.7102663517 -2.03647995 ) - weight 181 25 0.4947118759 ( -0.4999478757 12.2164554596 -1.546538949 ) - weight 182 26 0.5052881241 ( -0.0104868067 0.3325961828 -2.0174086094 ) - weight 183 25 0.1302652061 ( 1.5364876986 13.4725828171 -1.1465518475 ) - weight 184 26 0.8697347641 ( 1.2334004641 2.1258440018 -0.9582007527 ) - weight 185 25 0.0713815168 ( -1.001311183 17.1201839447 0.4302506447 ) - weight 186 26 0.9286184907 ( -2.7267596722 4.6504788399 -0.5397911668 ) - weight 187 25 0.1465780139 ( -0.6501053572 15.8056097031 2.2796070576 ) - weight 188 26 0.8534219861 ( -2.6469535828 3.3635296822 1.3599352837 ) - weight 189 25 0.1597477943 ( -1.417155385 16.0143890381 -0.7445948124 ) - weight 190 26 0.8402522206 ( -2.3219130039 3.5715372562 -1.7431008816 ) - weight 191 25 0.5 ( -0.4332461655 12.0141830444 3.0086653233 ) - weight 192 26 0.5 ( -1.4927688837 -0.2157097012 2.2601435184 ) - weight 193 26 0.3371406496 ( 0.2327859849 9.5721025467 2.0899467468 ) - weight 194 27 0.3314296901 ( -0.0230151098 0.1857070178 1.5172668695 ) - weight 195 28 0.3314296901 ( -0.5023810267 -0.4730388522 1.3641711473 ) - weight 196 25 1 ( 0.6936362982 5.6406226158 2.8790411949 ) - weight 197 25 1 ( 2.7844467163 5.6824707985 1.3094838858 ) - weight 198 23 0.0639448762 ( -2.5107598305 10.7263212204 0.1061423272 ) - weight 199 24 0.0639448762 ( -6.015663147 -2.1281073093 -0.8499259949 ) - weight 200 25 0.8721102476 ( -1.5854575634 5.4325375557 3.0827074051 ) - weight 201 23 0.0773928612 ( -3.2473232746 9.869556427 -0.6053477526 ) - weight 202 24 0.0773928612 ( -5.1048583984 -2.9249250889 -1.4141120911 ) - weight 203 25 0.8452143073 ( -2.5377743244 5.0285778046 2.2384922504 ) - weight 204 41 1 ( 2.0248129368 4.5064892769 1.6773761511 ) - weight 205 41 0.9000452161 ( 1.1078927517 11.2447729111 -1.2226729393 ) - weight 206 42 0.0999547541 ( 0.9370999932 -0.2287580222 -1.4919786453 ) - weight 207 42 1 ( -1.8059424162 6.6882419586 -0.2636964619 ) - weight 208 41 0.9001843333 ( -1.5059559345 11.0064239502 -1.5298566818 ) - weight 209 42 0.0998156518 ( -1.7033461332 -0.3031648695 -1.4152692556 ) - weight 210 42 1 ( -2.4964866638 1.9983602762 -0.8231247663 ) - weight 211 41 0.8999999762 ( -2.749475956 11.4071855545 -0.1866363436 ) - weight 212 42 0.1000000015 ( -2.6969263554 -0.2617001832 0.1728971004 ) - weight 213 41 1 ( -1.2849700451 6.5742998123 -2.3188569546 ) - weight 214 41 1 ( -0.0512501895 9.7427463531 -2.4789223671 ) - weight 215 41 1 ( 1.6652872562 6.153441906 -1.8215146065 ) - weight 216 41 1 ( 1.6107679605 8.9280567169 -0.0457982942 ) - weight 217 41 1 ( 0.7487913966 4.2154641151 2.7819712162 ) - weight 218 41 1 ( -1.9977859259 8.9904842377 1.2633039951 ) - weight 219 42 1 ( -1.3516397476 2.8153262138 -1.4070422649 ) - weight 220 42 1 ( -0.2118676901 5.6792283058 -1.0375438929 ) - weight 221 41 1 ( -0.5516916513 7.3853526115 2.8079137802 ) - weight 222 41 1 ( 1.0345931053 8.8962373734 2.1599192619 ) - weight 223 41 1 ( -2.2928366661 7.8905725479 0.2689422071 ) - weight 224 41 0.5 ( -0.6640770435 12.3411693573 2.6609942913 ) - weight 225 42 0.5 ( -0.1424403936 -0.2164218426 2.7811086178 ) - weight 226 42 0.6999999881 ( 0.4302443862 10.5333194733 0.8858450055 ) - weight 227 46 0.3000000119 ( 0.9130241275 -0.3809525967 -1.1391375065 ) - weight 228 42 0.6999999881 ( -0.0078338543 10.5882968903 1.3911576271 ) - weight 229 46 0.3000000119 ( 1.3985220194 -0.8210185766 -0.994535923 ) - weight 230 59 0.3166817725 ( -0.4410687387 0.4872480929 1.8593075275 ) - weight 231 60 0.5998155475 ( -0.3339439631 0.7220923305 0.4574312866 ) - weight 232 61 0.0835027024 ( -0.2909750044 0.8321256638 -0.9289692044 ) - weight 233 43 0.355802983 ( 0.6383082271 2.2177963257 -1.6232813597 ) - weight 234 59 0.42191872 ( -1.0247074366 1.0213285685 0.7487921715 ) - weight 235 60 0.2222782522 ( -0.9175826311 1.4063925743 -0.567370832 ) - weight 236 56 0.4102822542 ( -1.5851795673 -0.7560670376 0.302413553 ) - weight 237 57 0.5897177458 ( -0.2754021883 -0.5443707705 0.3521769941 ) - weight 238 57 0.5 ( -2.109742403 -0.6643938422 0.2943594456 ) - weight 239 58 0.5 ( 0.5027621984 0.2124748379 -0.2108638734 ) - weight 240 57 0.5 ( -2.439902544 -0.2688985467 0.3391640484 ) - weight 241 58 0.5 ( 0.0290756393 0.4150660932 -0.2556684911 ) - weight 242 42 0.5 ( 0.1746926308 11.5403633118 1.6425572634 ) - weight 243 46 0.5 ( 2.148412466 -0.3837129176 -1.4939117432 ) - weight 244 53 0.069197543 ( -2.5861494541 -1.5594825745 -1.3677345514 ) - weight 245 54 0.4924564362 ( -1.7130000591 -0.2956345677 -1.2634768486 ) - weight 246 55 0.4383460283 ( 0.3192409277 -0.2249470353 1.2970533371 ) - weight 247 53 0.4709459245 ( -1.1423761845 -0.9994550943 -1.2176892757 ) - weight 248 54 0.4479533136 ( -0.276314348 -0.8900156617 -1.2062805891 ) - weight 249 55 0.0811007842 ( 1.3013832569 -1.4302482605 1.2398570776 ) - weight 250 56 0.4561607838 ( -2.1036410332 -0.081423454 0.2818691432 ) - weight 251 57 0.5438392758 ( -0.1394620091 0.2955498695 0.3316325843 ) - weight 252 57 0.5 ( -2.0969643593 -0.647783637 -0.3835272193 ) - weight 253 58 0.5 ( 0.4905242622 0.1954627484 0.4670228064 ) - weight 254 57 0.5 ( -2.4110171795 -0.2257177234 -0.3625620306 ) - weight 255 58 0.5 ( -0.0039839754 0.3749911487 0.4460575879 ) - weight 256 59 0.4617009461 ( -0.4744462669 -0.8366077542 1.7802085876 ) - weight 257 60 0.5382990241 ( -0.367321521 -0.5776497126 0.1937620789 ) - weight 258 60 0.5 ( -0.6409515142 0.4167560041 1.5116868019 ) - weight 259 61 0.5 ( -0.5600696802 0.4315469563 0.1035342664 ) - weight 260 60 0.5 ( -0.493714571 -0.4070169628 1.7116553783 ) - weight 261 61 0.5 ( -0.4743456841 -0.4191246033 0.1998535544 ) - weight 262 60 0.5 ( -0.3804749846 0.7671043873 2.3770430088 ) - weight 263 61 0.5 ( -0.2183971852 0.6562422514 0.9822865725 ) - weight 264 60 0.5 ( 0.3956457078 -0.2429682165 1.7702257633 ) - weight 265 61 0.5 ( 0.4279209375 -0.3354018331 0.2143333852 ) - weight 266 60 0.5 ( 0.3228072524 0.5739750862 1.5121668577 ) - weight 267 61 0.5 ( 0.4120932519 0.5092855096 0.0544927344 ) - weight 268 60 0.5 ( -0.5536772609 0.2871197462 2.7410342693 ) - weight 269 61 0.5 ( -0.4111564755 0.1525970399 1.3017536402 ) - weight 270 60 0.5 ( 0.0594971217 0.3390644789 2.8496928215 ) - weight 271 61 0.5 ( 0.2096090168 0.1418060213 1.3726164103 ) - weight 272 42 0.1021443084 ( 1.3280529976 10.9252214432 -1.0832469463 ) - weight 273 43 0.4573689997 ( -0.0940590054 1.419007659 -1.3018926382 ) - weight 274 59 0.3763922155 ( -1.2093800306 0.1654653996 0.0338726006 ) - weight 275 60 0.0640944466 ( -1.1022552252 0.6590531468 -1.395075798 ) - weight 276 42 0.5 ( -0.0538079068 10.3411169052 -2.1068780422 ) - weight 277 46 0.5 ( -0.4620539546 1.6641776562 0.6368813515 ) - weight 278 46 0.6894210577 ( 4.1486310959 1.7268168926 -1.5909707546 ) - weight 279 53 0.3105789125 ( -0.0658656433 0.0929000676 -1.2677611113 ) - weight 280 43 0.0985767394 ( 5.2365159988 2.6387865543 -1.4672034979 ) - weight 281 53 0.4643151462 ( -1.4118026495 -0.0660721883 -1.2851238251 ) - weight 282 54 0.4371080995 ( 0.1695078909 -0.0298885908 -1.3051015139 ) - weight 283 53 0.2835289836 ( -2.1368019581 -0.8302375674 -1.5106915236 ) - weight 284 54 0.5160970092 ( -0.8951952457 -0.0804075897 -1.4610137939 ) - weight 285 55 0.2003739923 ( 0.3480853438 -1.0701069832 1.4945901632 ) - weight 286 46 0.6263788342 ( 3.3898363113 3.4524209499 0.0662843585 ) - weight 287 56 0.1961994022 ( -0.4911676049 0.5089589357 -1.105525732 ) - weight 288 53 0.1774217635 ( -0.4999884963 0.3408877552 1.1919162273 ) - weight 289 46 0.6593160033 ( 3.7668893337 2.051453352 -2.5057599545 ) - weight 290 53 0.2632933259 ( 0.0497339219 -0.9332521558 -1.4147411585 ) - weight 291 54 0.0773906857 ( 0.6153554916 -1.6675416231 -1.4606759548 ) - weight 292 46 0.6583693027 ( 1.8129783869 4.5462493896 -0.4384952486 ) - weight 293 56 0.3416306973 ( -0.1919894814 -0.6765120625 0.4574503899 ) - weight 294 42 0.5 ( 1.0091743469 10.3208465576 -1.8024432659 ) - weight 295 46 0.5 ( -0.8131384254 1.6434646845 -0.4116096497 ) - weight 296 46 0.6092338562 ( 2.8576776981 3.8085730076 0.2318148315 ) - weight 297 56 0.3907661438 ( -0.4411796331 0.4165125191 -0.4525384903 ) - weight 298 56 0.4046732485 ( -1.6399065256 -0.7139576077 -0.4374390543 ) - weight 299 57 0.5953267217 ( -0.2822460532 -0.4756582677 -0.3876756132 ) - weight 300 56 0.4919973314 ( -2.1104235649 -0.0320435129 -0.4843159318 ) - weight 301 57 0.5080026388 ( -0.1081519201 0.3343320489 -0.4345524907 ) - weight 302 42 0.5 ( 1.0162092447 11.2493715286 0.5217643976 ) - weight 303 46 0.5 ( 1.0045393705 0.4604843557 -1.6609110832 ) - weight 304 56 0.0753543749 ( -1.9501200914 0.0405432917 -1.6913391352 ) - weight 305 57 0.0753543749 ( 0.054572016 0.267347604 -1.6415756941 ) - weight 306 53 0.4202261269 ( -2.0914611816 0.0287104249 0.9451522231 ) - weight 307 54 0.4290650785 ( -0.1083634198 0.5137882233 0.9470648766 ) - weight 308 54 0.5350014567 ( -1.832524538 0.5594405532 0.4377813935 ) - weight 309 55 0.4649985135 ( -0.5341176391 -0.356167376 -0.4042049348 ) - weight 310 46 0.5402864218 ( 2.3266673088 4.4726247787 0.4018701613 ) - weight 311 56 0.4597135782 ( -0.6210423112 0.208786875 0.3698696196 ) - weight 312 57 1 ( -1.365729928 0.2472849786 -0.0473287441 ) - weight 313 54 0.5 ( -2.73700881 -0.1043511257 -0.1954204738 ) - weight 314 55 0.5 ( -0.1582221836 0.7009107471 0.2289969474 ) - weight 315 56 0.1159686744 ( -1.8373789787 -1.0219355822 -1.3609366417 ) - weight 316 57 0.1635749489 ( -0.6418563128 -0.5429359674 -1.3111732006 ) - weight 317 53 0.1880443096 ( -1.9741501808 -1.0805433989 1.025970459 ) - weight 318 54 0.439424336 ( -0.7843179703 -0.3680208921 1.0744837523 ) - weight 319 55 0.0929877609 ( 0.6554291844 -1.0936629772 -1.0409072638 ) - weight 320 54 0.5 ( -2.7070970535 -0.432346344 0.6642289758 ) - weight 321 55 0.5 ( 0.1645352989 0.7665091753 -0.6306524873 ) - weight 322 56 0.6651306152 ( -0.6999974251 -0.7237315178 -0.7712486386 ) - weight 323 57 0.1595718265 ( 0.3548170328 -1.16679883 -0.7214852571 ) - weight 324 53 0.1077049747 ( -0.7035999894 -0.9295470715 1.331251502 ) - weight 325 54 0.067592591 ( 0.2553741932 -1.1374908686 1.3137539625 ) - weight 326 59 0.4626750648 ( 0.3727392256 -0.8000719547 1.8097087145 ) - weight 327 60 0.5373249054 ( 0.4798639715 -0.5456040502 0.2280868888 ) - weight 328 59 0.5387811661 ( 0.6901986003 -0.018047018 1.3790346384 ) - weight 329 60 0.4612188637 ( 0.7973233461 0.2890157998 -0.0888560414 ) - weight 330 42 0.6999999881 ( -1.3488999605 10.2636079788 1.3617026806 ) - weight 331 46 0.3000000119 ( 1.7519131899 -1.2801697254 0.2580786943 ) - weight 332 41 1 ( 1.0647922754 4.7522816658 -2.4680337906 ) - weight 333 41 1 ( 2.2601931095 4.8678407669 0.1005170047 ) - weight 334 42 0.5 ( -1.053371191 10.9850378036 1.196639061 ) - weight 335 46 0.5 ( 2.0761289597 -0.6467821002 -0.1007354259 ) - weight 336 42 0.6999999881 ( 0.6303012967 9.7362775803 -0.4175288081 ) - weight 337 46 0.3000000119 ( -0.4054782689 0.1540133655 -0.5479985476 ) - weight 338 42 0.6999999881 ( -0.7312836051 9.7340755463 -1.3712610006 ) - weight 339 46 0.3000000119 ( -0.2502955198 0.5898589492 1.0487107038 ) - weight 340 42 0.5 ( -1.346383214 10.712518692 -0.8530721068 ) - weight 341 46 0.5 ( 1.0116113424 0.6747577786 1.1165457964 ) - weight 342 41 0.5 ( 0.8937210441 12.2379264832 2.6171696186 ) - weight 343 42 0.5 ( 1.3793295622 -0.3440266848 2.4536216259 ) - weight 344 42 1 ( -0.1803760976 0.7429106236 2.8617823124 ) - weight 345 42 1 ( 1.5016064644 0.6839817762 2.4828398228 ) - weight 346 42 1 ( -2.6786980629 3.1893005371 0.9537760615 ) - weight 347 42 1 ( 2.25608325 3.6084442139 0.3291476071 ) - weight 348 41 0.9000392556 ( 1.9339050055 12.1685695648 0.2641876936 ) - weight 349 42 0.0999607816 ( 2.0427761078 0.2203280926 0.03191581 ) - weight 350 42 1 ( 1.041942358 2.0126121044 -1.2607418299 ) - weight 351 42 1 ( 0.8838022351 4.7272696495 2.5911853313 ) - weight 352 42 1 ( -1.0833854675 3.5438094139 2.6252820492 ) - weight 353 42 1 ( 2.0145277977 3.5674910545 2.2008733749 ) - weight 354 41 0.9003438354 ( -2.5210382938 12.0707864761 1.2332955599 ) - weight 355 42 0.0996561348 ( -2.2090342045 -0.027969582 1.6615499258 ) - weight 356 42 0.6999999881 ( -1.5719277859 9.6509819031 -0.510951817 ) - weight 357 46 0.3000000119 ( 0.4874614477 -0.2885828316 1.4198894501 ) - weight 358 41 1 ( -2.8150191307 5.7149615288 0.0391411632 ) - weight 359 41 1 ( -1.7608675957 5.7549648285 -2.3533289433 ) - weight 360 41 1 ( -2.5009636879 5.4747600555 2.3024837971 ) - weight 361 41 1 ( -1.473195076 5.0364227295 3.0334706306 ) -} diff --git a/base/animation/mp_jumpsuit.md5mesh b/base/animation/mp_jumpsuit.md5mesh deleted file mode 100644 index f99a0beac..000000000 --- a/base/animation/mp_jumpsuit.md5mesh +++ /dev/null @@ -1,6412 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:29 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_jumpsuit.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh jumpsuitmesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} - -mesh { - // meshes: jumpsuitmesh - shader "models/characters/male_npc/jumpsuit/jumpsuit" - - numverts 644 - vert 0 ( 0.8851889968 0.8249670267 ) 0 3 - vert 1 ( 0.9167770147 0.9147850275 ) 3 3 - vert 2 ( 0.9290639758 0.8345429897 ) 6 2 - vert 3 ( 0.633020997 0.6062430143 ) 8 2 - vert 4 ( 0.6279270053 0.6710920334 ) 10 2 - vert 5 ( 0.7075179815 0.6906809807 ) 12 2 - vert 6 ( 0.7152150273 0.6038039923 ) 14 3 - vert 7 ( 0.8111619949 0.5993410349 ) 17 3 - vert 8 ( 0.797977984 0.6077589989 ) 20 2 - vert 9 ( 0.8745650053 0.6222590208 ) 22 2 - vert 10 ( 0.7644000053 0.5801950097 ) 24 3 - vert 11 ( 0.7102059722 0.5641139746 ) 27 4 - vert 12 ( 0.7319250107 0.5876079798 ) 0 3 - vert 13 ( 0.932197988 0.7495700121 ) 20 2 - vert 14 ( 0.9878820181 0.890460968 ) 14 3 - vert 15 ( 0.9349120259 0.6673409939 ) 22 2 - vert 16 ( 0.9803060293 0.6969209909 ) 31 3 - vert 17 ( 0.9712280035 0.640410006 ) 34 3 - vert 18 ( 0.8932440281 0.9510400295 ) 37 2 - vert 19 ( 0.8684700131 0.9948850274 ) 10 2 - vert 20 ( 0.9479979873 0.9782099724 ) 8 2 - vert 21 ( 0.8667160273 0.6727199554 ) 39 3 - vert 22 ( 0.8237410188 0.7295470238 ) 42 3 - vert 23 ( 0.8402420282 0.7758100033 ) 45 3 - vert 24 ( 0.6826739907 0.5811840296 ) 42 3 - vert 25 ( 0.6717619896 0.5613700151 ) 48 3 - vert 26 ( 0.6514260173 0.5942590237 ) 45 3 - vert 27 ( 0.9902799726 0.611019969 ) 45 3 - vert 28 ( 0.9905899763 0.5975819826 ) 51 3 - vert 29 ( 0.9204319715 0.6187050343 ) 54 2 - vert 30 ( 0.8585289717 0.9232029915 ) 39 3 - vert 31 ( 0.6278529763 0.5874730349 ) 51 3 - vert 32 ( 0.9243559837 0.6973209977 ) 12 2 - vert 33 ( 0.8195310235 0.8209300041 ) 54 2 - vert 34 ( 0.8666120172 0.8175060153 ) 34 3 - vert 35 ( 0.9273049831 0.633498013 ) 54 2 - vert 36 ( 0.9103090167 0.6286840439 ) 10 2 - vert 37 ( 0.3481059968 0.3744029999 ) 56 5 - vert 38 ( 0.2541770041 0.4076070189 ) 61 5 - vert 39 ( 0.3406270146 0.4230279922 ) 66 3 - vert 40 ( 0.2611120045 0.4667109847 ) 69 3 - vert 41 ( 0.2287870049 0.366707027 ) 72 7 - vert 42 ( 0.1349650025 0.41841501 ) 79 5 - vert 43 ( 0.4336949885 0.4282619953 ) 84 4 - vert 44 ( 0.3723700047 0.5127630234 ) 88 3 - vert 45 ( 0.2032680064 0.5360209942 ) 91 4 - vert 46 ( 0.1482540071 0.5093989968 ) 95 4 - vert 47 ( 0.1554899961 0.5774390101 ) 99 2 - vert 48 ( 0.1800889969 0.4502369761 ) 101 5 - vert 49 ( 0.5775920153 0.5124340057 ) 106 5 - vert 50 ( 0.4381119907 0.5541030169 ) 111 3 - vert 51 ( 0.5775920153 0.5785360336 ) 114 4 - vert 52 ( 0.0669780001 0.6471740007 ) 118 2 - vert 53 ( 0.0065890001 0.59651196 ) 120 4 - vert 54 ( 0.0262550004 0.6786299944 ) 124 4 - vert 55 ( 0.477730006 0.6102319956 ) 128 3 - vert 56 ( 0.5775920153 0.6367610097 ) 124 4 - vert 57 ( 0.5070220232 0.65951401 ) 118 2 - vert 58 ( 0.0065890001 0.5515210032 ) 131 5 - vert 59 ( 0.7002540231 0.108009994 ) 136 2 - vert 60 ( 0.6616839767 0.0640410185 ) 138 2 - vert 61 ( 0.6562669873 0.162981987 ) 140 2 - vert 62 ( 0.5873320103 0.0721330047 ) 142 2 - vert 63 ( 0.5857499838 0.1638799906 ) 144 2 - vert 64 ( 0.9500690103 0.082242012 ) 142 2 - vert 65 ( 0.9095330238 0.0776680112 ) 146 2 - vert 66 ( 0.9484869838 0.1739889979 ) 144 2 - vert 67 ( 0.8626260161 0.1591299772 ) 148 1 - vert 68 ( 0.8223549724 0.0810359716 ) 149 2 - vert 69 ( 0.8216770291 0.1840500236 ) 151 1 - vert 70 ( 0.8705809712 0.0477510095 ) 152 2 - vert 71 ( 0.8397700191 0.0088210106 ) 154 3 - vert 72 ( 0.6747339964 0.0345870256 ) 118 2 - vert 73 ( 0.1165380031 0.610532999 ) 157 2 - vert 74 ( 0.9396790266 0.0486869812 ) 128 3 - vert 75 ( 0.5769420266 0.0385779738 ) 128 3 - vert 76 ( 0.7078279853 0.2049900293 ) 159 1 - vert 77 ( 0.887845993 0.2735739946 ) 160 3 - vert 78 ( 0.7376840115 0.157975018 ) 163 2 - vert 79 ( 0.6246330142 0.2245169878 ) 165 2 - vert 80 ( 0.7565789819 0.2561839819 ) 167 2 - vert 81 ( 0.0065890001 0.5087260008 ) 169 4 - vert 82 ( 0.9825749993 0.2901970148 ) 173 2 - vert 83 ( 0.9431530237 0.2816219926 ) 175 2 - vert 84 ( 0.9265419841 0.3301920295 ) 177 2 - vert 85 ( 0.8849400282 0.3162469864 ) 179 2 - vert 86 ( 0.9196789861 0.363763988 ) 181 1 - vert 87 ( 0.8798360229 0.3612269759 ) 182 1 - vert 88 ( 0.8043770194 0.2991089821 ) 183 2 - vert 89 ( 0.7701420188 0.3423240185 ) 185 2 - vert 90 ( 0.828963995 0.356325984 ) 187 2 - vert 91 ( 0.8504130244 0.3271620274 ) 189 2 - vert 92 ( 0.8518270254 0.2754150033 ) 191 2 - vert 93 ( 0.9873700142 0.2346259952 ) 165 2 - vert 94 ( 0.6971799731 0.2464299798 ) 193 2 - vert 95 ( 0.6198379993 0.2800880075 ) 173 2 - vert 96 ( 0.7516549826 0.2809749842 ) 195 2 - vert 97 ( 0.7999449968 0.2740920186 ) 197 2 - vert 98 ( 0.7743420005 0.1307820082 ) 199 2 - vert 99 ( 0.919664979 0.4355540276 ) 201 1 - vert 100 ( 0.8858860135 0.4413160086 ) 202 1 - vert 101 ( 0.9187830091 0.4915729761 ) 203 1 - vert 102 ( 0.9643340111 0.4460340142 ) 204 1 - vert 103 ( 0.9670060277 0.3808689713 ) 205 2 - vert 104 ( 0.8286380172 0.4186260104 ) 207 1 - vert 105 ( 0.8234199882 0.5302729607 ) 208 1 - vert 106 ( 0.7991189957 0.466835022 ) 209 1 - vert 107 ( 0.7234879732 0.5203169584 ) 210 1 - vert 108 ( 0.8661540151 0.4794849753 ) 211 1 - vert 109 ( 0.8763359785 0.5453959703 ) 212 1 - vert 110 ( 0.9250190258 0.5525410175 ) 213 2 - vert 111 ( 0.97596699 0.5522789955 ) 215 2 - vert 112 ( 0.6653469801 0.5165799856 ) 217 1 - vert 113 ( 0.6015980244 0.4359250069 ) 204 1 - vert 114 ( 0.61322999 0.5421699882 ) 215 2 - vert 115 ( 0.6808559895 0.4363690019 ) 218 1 - vert 116 ( 0.74792099 0.4414539933 ) 219 1 - vert 117 ( 0.7089049816 0.37252599 ) 220 1 - vert 118 ( 0.8737609982 0.6103760004 ) 221 2 - vert 119 ( 0.2043370008 0.9363080263 ) 223 1 - vert 120 ( 0.1917700022 0.9874539971 ) 224 1 - vert 121 ( 0.2633219957 0.9902449846 ) 225 2 - vert 122 ( 0.2603709996 0.9215610027 ) 227 2 - vert 123 ( 0.5775920153 0.3795220256 ) 229 3 - vert 124 ( 0.4588179886 0.3752769828 ) 232 3 - vert 125 ( 0.5775920153 0.4263960123 ) 235 3 - vert 126 ( 0.3677870035 0.2736859918 ) 238 4 - vert 127 ( 0.3043830097 0.3146250248 ) 242 4 - vert 128 ( 0.3868750036 0.3268780112 ) 246 3 - vert 129 ( 0.4728420079 0.2558709979 ) 249 4 - vert 130 ( 0.2187130004 0.899075985 ) 253 1 - vert 131 ( 0.2690410018 0.8628900051 ) 254 2 - vert 132 ( 0.1635289937 0.9143019915 ) 256 2 - vert 133 ( 0.1683640033 0.9854789972 ) 258 1 - vert 134 ( 0.1685930043 0.6515290141 ) 258 1 - vert 135 ( 0.183961004 0.6999030113 ) 259 1 - vert 136 ( 0.1921020001 0.6548619866 ) 224 1 - vert 137 ( 0.2472400069 0.1630690098 ) 260 6 - vert 138 ( 0.1861670017 0.2110670209 ) 266 4 - vert 139 ( 0.2551909983 0.2385969758 ) 270 5 - vert 140 ( 0.0627510026 0.8454350233 ) 275 4 - vert 141 ( 0.1106910035 0.8663179874 ) 279 4 - vert 142 ( 0.1359120011 0.8428989649 ) 283 3 - vert 143 ( 0.2829760015 0.2189210057 ) 286 4 - vert 144 ( 0.300853014 0.2472869754 ) 290 4 - vert 145 ( 0.3460890055 0.2240419984 ) 294 4 - vert 146 ( 0.2999300063 0.8250650167 ) 298 2 - vert 147 ( 0.2727189958 0.799405992 ) 300 2 - vert 148 ( 0.2603009939 0.7136909962 ) 302 2 - vert 149 ( 0.2954480052 0.7122550011 ) 304 2 - vert 150 ( 0.263936013 0.6731899977 ) 225 2 - vert 151 ( 0.2846580148 0.9553740025 ) 306 2 - vert 152 ( 0.2911350131 0.9950889945 ) 308 2 - vert 153 ( 0.2938460112 0.9138000011 ) 310 2 - vert 154 ( 0.2402170002 0.80576998 ) 312 1 - vert 155 ( 0.2677659988 0.7409399748 ) 313 2 - vert 156 ( 0.2038889974 0.7419040203 ) 315 1 - vert 157 ( 0.2918660045 0.681499958 ) 308 2 - vert 158 ( 0.2447099984 0.2737269998 ) 316 4 - vert 159 ( 0.1515060067 0.2566670179 ) 320 4 - vert 160 ( 0.1032959968 0.1600930095 ) 324 5 - vert 161 ( 0.0998020023 0.2631400228 ) 329 5 - vert 162 ( 0.5775920153 0.1599289775 ) 334 5 - vert 163 ( 0.4683189988 0.1387779713 ) 339 5 - vert 164 ( 0.0065890001 0.2649289966 ) 344 6 - vert 165 ( 0.406866014 0.1940310001 ) 350 5 - vert 166 ( 0.0065890001 0.1631810069 ) 355 4 - vert 167 ( 0.0065890001 0.0881519914 ) 359 3 - vert 168 ( 0.0661609992 0.058588028 ) 362 3 - vert 169 ( 0.1489060074 0.8846759796 ) 365 3 - vert 170 ( 0.111270003 0.9061470032 ) 260 6 - vert 171 ( 0.1432790011 0.9405339956 ) 286 4 - vert 172 ( 0.1273680031 0.9811329842 ) 294 4 - vert 173 ( 0.1018000022 0.7043390274 ) 368 3 - vert 174 ( 0.1274189949 0.6441459656 ) 294 4 - vert 175 ( 0.5290349722 0.0110189915 ) 371 4 - vert 176 ( 0.3896870017 0.0040079951 ) 375 3 - vert 177 ( 0.4449689984 0.0699130297 ) 378 3 - vert 178 ( 0.0793519989 0.6812579632 ) 350 5 - vert 179 ( 0.7603120208 0.0036579967 ) 99 2 - vert 180 ( 0.6042690277 0.3707600236 ) 205 2 - vert 181 ( 0.7208219767 0.0257869959 ) 157 2 - vert 182 ( 0.416602999 0.5872989893 ) 381 3 - vert 183 ( 0.9086660147 0.0305550098 ) 381 3 - vert 184 ( 0.203339994 0.1467779875 ) 384 4 - vert 185 ( 0.1226560026 0.3631550074 ) 388 6 - vert 186 ( 0.0065890001 0.4279379845 ) 394 5 - vert 187 ( 0.0065890001 0.3656870127 ) 399 5 - vert 188 ( 0.7987790108 0.0148829818 ) 404 2 - vert 189 ( 0.2247759998 0.5843609571 ) 404 2 - vert 190 ( 0.2846649885 0.5689849854 ) 154 3 - vert 191 ( 0.0755100027 0.8883000016 ) 406 4 - vert 192 ( 0.2742730081 0.0773720145 ) 410 4 - vert 193 ( 0.2226510048 0.0935739875 ) 414 3 - vert 194 ( 0.255629003 0.1107159853 ) 406 4 - vert 195 ( 0.9255869985 0.6043000221 ) 417 2 - vert 196 ( 0.8402969837 0.6819820404 ) 34 3 - vert 197 ( 0.843535006 0.6373449564 ) 31 3 - vert 198 ( 0.7736589909 0.6870989799 ) 419 3 - vert 199 ( 0.8996700048 0.768558979 ) 419 3 - vert 200 ( 0.7821429968 0.6192190051 ) 422 3 - vert 201 ( 0.9902340174 0.7758809924 ) 422 3 - vert 202 ( 0.27838099 0.5233770013 ) 425 3 - vert 203 ( 0.4570020139 0.5060349703 ) 428 3 - vert 204 ( 0.877572 0.0149059892 ) 431 2 - vert 205 ( 0.3460389972 0.5719139576 ) 431 2 - vert 206 ( 0.4124470055 0.1296200156 ) 433 4 - vert 207 ( 0.0435540006 0.7115600109 ) 433 4 - vert 208 ( 0.062804997 0.7602419853 ) 437 3 - vert 209 ( 0.3789699972 0.0994259715 ) 440 4 - vert 210 ( 0.0159210004 0.7509840131 ) 440 4 - vert 211 ( 0.0442270003 0.8014060259 ) 444 4 - vert 212 ( 0.3345260024 0.0731779933 ) 448 4 - vert 213 ( 0.0077530001 0.8201950192 ) 448 4 - vert 214 ( 0.4661230147 0.3288850188 ) 452 3 - vert 215 ( 0.5775920153 0.3309460282 ) 455 3 - vert 216 ( 0.5775920153 0.2686849833 ) 458 3 - vert 217 ( 0.8384780288 0.8386750221 ) 42 3 - vert 218 ( 0.5007230043 0.8608759642 ) 461 1 - vert 219 ( 0.4004510045 0.8904989958 ) 462 1 - vert 220 ( 0.4774749875 0.898590982 ) 463 3 - vert 221 ( 0.4339909852 0.8469029665 ) 466 1 - vert 222 ( 0.5118749738 0.8208619952 ) 467 1 - vert 223 ( 0.4504519999 0.8016870022 ) 468 1 - vert 224 ( 0.519701004 0.7612500191 ) 469 1 - vert 225 ( 0.3528000116 0.7389389873 ) 470 1 - vert 226 ( 0.4434280097 0.7510669827 ) 471 1 - vert 227 ( 0.5172349811 0.7290819883 ) 472 1 - vert 228 ( 0.4215759933 0.7003450394 ) 473 1 - vert 229 ( 0.3455109894 0.7057470083 ) 474 1 - vert 230 ( 0.4768890142 0.9415969849 ) 475 1 - vert 231 ( 0.4011979997 0.933701992 ) 476 1 - vert 232 ( 0.4865309894 0.9777920246 ) 477 1 - vert 233 ( 0.570964992 0.8845490217 ) 478 2 - vert 234 ( 0.5789020061 0.8460580111 ) 480 2 - vert 235 ( 0.5926210284 0.8259350061 ) 482 1 - vert 236 ( 0.7997699976 0.9733999968 ) 483 3 - vert 237 ( 0.756724 0.9381579757 ) 486 3 - vert 238 ( 0.7890049815 0.9327999949 ) 480 2 - vert 239 ( 0.6045969725 0.8296480179 ) 489 2 - vert 240 ( 0.8025349975 0.8614699841 ) 482 1 - vert 241 ( 0.7491949797 0.9943079948 ) 491 2 - vert 242 ( 0.6942149997 0.9865270257 ) 493 1 - vert 243 ( 0.7694820166 0.828707993 ) 494 2 - vert 244 ( 0.8027639985 0.8125270009 ) 496 2 - vert 245 ( 0.7869669795 0.8019449711 ) 498 2 - vert 246 ( 0.5959810019 0.7842389941 ) 496 2 - vert 247 ( 0.6046180129 0.7234239578 ) 500 2 - vert 248 ( 0.6153159738 0.7025020123 ) 502 2 - vert 249 ( 0.8136299849 0.7713860273 ) 500 2 - vert 250 ( 0.7985380292 0.7631790042 ) 504 2 - vert 251 ( 0.6761140227 0.733044982 ) 506 3 - vert 252 ( 0.6491540074 0.7684370279 ) 509 3 - vert 253 ( 0.6686120033 0.7034319639 ) 512 2 - vert 254 ( 0.6734960079 0.9662230015 ) 514 1 - vert 255 ( 0.700568974 0.8474110365 ) 515 3 - vert 256 ( 0.7166720033 0.7589269876 ) 518 3 - vert 257 ( 0.74871701 0.7289980054 ) 521 2 - vert 258 ( 0.7685890198 0.7389019728 ) 512 2 - vert 259 ( 0.7017890215 0.775538981 ) 523 3 - vert 260 ( 0.7011880279 0.7465590239 ) 518 3 - vert 261 ( 0.6883950233 0.7056699991 ) 521 2 - vert 262 ( 0.6925330162 0.8118289709 ) 526 3 - vert 263 ( 0.6550170183 0.7908899784 ) 529 3 - vert 264 ( 0.6797599792 0.8512650132 ) 532 3 - vert 265 ( 0.707852006 0.8104299903 ) 535 3 - vert 266 ( 0.6074820161 0.7819190025 ) 538 2 - vert 267 ( 0.6490619779 0.9733939767 ) 540 1 - vert 268 ( 0.6052020192 0.9690830112 ) 541 2 - vert 269 ( 0.6357730031 0.8398550153 ) 543 2 - vert 270 ( 0.5714309812 0.828256011 ) 545 2 - vert 271 ( 0.5528270006 0.8322100043 ) 547 2 - vert 272 ( 0.5588089824 0.7859380245 ) 549 2 - vert 273 ( 0.5543259978 0.8860200047 ) 551 3 - vert 274 ( 0.5358489752 0.8347740173 ) 554 2 - vert 275 ( 0.5730850101 0.793734014 ) 556 2 - vert 276 ( 0.5840579867 0.8170059919 ) 558 2 - vert 277 ( 0.8161879778 0.8996319771 ) 556 2 - vert 278 ( 0.8266770244 0.8883939981 ) 549 2 - vert 279 ( 0.8267859817 0.9110990167 ) 560 2 - vert 280 ( 0.5714660287 0.952252984 ) 562 2 - vert 281 ( 0.5482320189 0.9537770152 ) 564 1 - vert 282 ( 0.5351210237 0.9507679939 ) 491 2 - vert 283 ( 0.5381690264 0.8871129751 ) 483 3 - vert 284 ( 0.8036159873 0.9287400246 ) 558 2 - vert 285 ( 0.818508029 0.9463310242 ) 554 2 - vert 286 ( 0.6376190186 0.781965971 ) 498 2 - vert 287 ( 0.6241390109 0.782755971 ) 565 2 - vert 288 ( 0.6422780156 0.7077629566 ) 504 2 - vert 289 ( 0.6305840015 0.7032589912 ) 567 2 - vert 290 ( 0.6214889884 0.8390759826 ) 569 2 - vert 291 ( 0.6353539824 0.8060629964 ) 494 2 - vert 292 ( 0.5176740289 0.8607789874 ) 541 2 - vert 293 ( 0.528603971 0.8226339817 ) 540 1 - vert 294 ( 0.5028409958 0.8987259865 ) 562 2 - vert 295 ( 0.5392010212 0.7466000319 ) 514 1 - vert 296 ( 0.5311419964 0.6905180216 ) 493 1 - vert 297 ( 0.5001900196 0.6796820164 ) 477 1 - vert 298 ( 0.5029720068 0.9707750082 ) 493 1 - vert 299 ( 0.4968389869 0.941429019 ) 491 2 - vert 300 ( 0.4974350035 0.9217699766 ) 564 1 - vert 301 ( 0.8029379845 0.7442569733 ) 567 2 - vert 302 ( 0.8184109926 0.7529680133 ) 502 2 - vert 303 ( 0.6204379797 0.7389010191 ) 571 2 - vert 304 ( 0.7697860003 0.7841470242 ) 509 3 - vert 305 ( 0.0282600001 0.8698080182 ) 410 4 - vert 306 ( 0.7046319842 0.2813230157 ) 573 2 - vert 307 ( 0.7586479783 0.3050389886 ) 575 2 - vert 308 ( 0.695694983 0.3050810099 ) 577 2 - vert 309 ( 0.5461469889 0.7879520059 ) 560 2 - vert 310 ( 0.1138980016 0.8113780022 ) 579 3 - vert 311 ( 0.1568849981 0.1397330165 ) 582 4 - vert 312 ( 0.1609240025 0.0286160111 ) 586 3 - vert 313 ( 0.1804230064 0.0740810037 ) 589 3 - vert 314 ( 0.2538779974 0.0489689708 ) 592 3 - vert 315 ( 0.2719900012 0.0071799755 ) 595 3 - vert 316 ( 0.3432950079 0.0435640216 ) 598 3 - vert 317 ( 0.4060660005 0.9733899832 ) 473 1 - vert 318 ( 0.3240619898 0.7848359942 ) 601 2 - vert 319 ( 0.3027069867 0.7717610002 ) 603 2 - vert 320 ( 0.3004209995 0.7371799946 ) 605 2 - vert 321 ( 0.3276099861 0.7369199991 ) 607 2 - vert 322 ( 0.3222169876 0.9879009724 ) 609 2 - vert 323 ( 0.3231050074 0.6688380241 ) 609 2 - vert 324 ( 0.3229289949 0.7101849914 ) 611 2 - vert 325 ( 0.109232001 0.7468780279 ) 613 3 - vert 326 ( 0.9167770147 0.9147850275 ) 616 3 - vert 327 ( 0.8851889968 0.8249670267 ) 619 3 - vert 328 ( 0.9290639758 0.8345429897 ) 622 2 - vert 329 ( 0.6279270053 0.6710920334 ) 624 2 - vert 330 ( 0.633020997 0.6062430143 ) 626 2 - vert 331 ( 0.7075179815 0.6906809807 ) 628 2 - vert 332 ( 0.7152150273 0.6038039923 ) 630 3 - vert 333 ( 0.797977984 0.6077589989 ) 633 2 - vert 334 ( 0.8111619949 0.5993410349 ) 635 3 - vert 335 ( 0.8745650053 0.6222590208 ) 638 2 - vert 336 ( 0.7644000053 0.5801950097 ) 640 3 - vert 337 ( 0.7102059722 0.5641139746 ) 643 4 - vert 338 ( 0.7319250107 0.5876079798 ) 619 3 - vert 339 ( 0.932197988 0.7495700121 ) 633 2 - vert 340 ( 0.9878820181 0.890460968 ) 630 3 - vert 341 ( 0.9349120259 0.6673409939 ) 638 2 - vert 342 ( 0.9803060293 0.6969209909 ) 647 3 - vert 343 ( 0.9712280035 0.640410006 ) 650 3 - vert 344 ( 0.8684700131 0.9948850274 ) 624 2 - vert 345 ( 0.8932440281 0.9510400295 ) 653 2 - vert 346 ( 0.9479979873 0.9782099724 ) 626 2 - vert 347 ( 0.8237410188 0.7295470238 ) 655 3 - vert 348 ( 0.8667160273 0.6727199554 ) 658 3 - vert 349 ( 0.8402420282 0.7758100033 ) 661 3 - vert 350 ( 0.6717619896 0.5613700151 ) 664 3 - vert 351 ( 0.6826739907 0.5811840296 ) 655 3 - vert 352 ( 0.6514260173 0.5942590237 ) 661 3 - vert 353 ( 0.9905899763 0.5975819826 ) 667 3 - vert 354 ( 0.9902799726 0.611019969 ) 661 3 - vert 355 ( 0.9204319715 0.6187050343 ) 670 2 - vert 356 ( 0.8585289717 0.9232029915 ) 658 3 - vert 357 ( 0.6278529763 0.5874730349 ) 667 3 - vert 358 ( 0.9243559837 0.6973209977 ) 628 2 - vert 359 ( 0.8195310235 0.8209300041 ) 670 2 - vert 360 ( 0.8666120172 0.8175060153 ) 650 3 - vert 361 ( 0.9273049831 0.633498013 ) 670 2 - vert 362 ( 0.9103090167 0.6286840439 ) 624 2 - vert 363 ( 0.2541770041 0.4076070189 ) 672 5 - vert 364 ( 0.3481059968 0.3744029999 ) 677 5 - vert 365 ( 0.3406270146 0.4230279922 ) 682 3 - vert 366 ( 0.2611120045 0.4667109847 ) 685 3 - vert 367 ( 0.2287870049 0.366707027 ) 688 7 - vert 368 ( 0.1349650025 0.41841501 ) 695 5 - vert 369 ( 0.4336949885 0.4282619953 ) 700 4 - vert 370 ( 0.3723700047 0.5127630234 ) 704 3 - vert 371 ( 0.1482540071 0.5093989968 ) 707 4 - vert 372 ( 0.2032680064 0.5360209942 ) 711 4 - vert 373 ( 0.1554899961 0.5774390101 ) 715 2 - vert 374 ( 0.1800889969 0.4502369761 ) 717 5 - vert 375 ( 0.4381119907 0.5541030169 ) 722 3 - vert 376 ( 0.0669780001 0.6471740007 ) 725 2 - vert 377 ( 0.477730006 0.6102319956 ) 727 3 - vert 378 ( 0.5070220232 0.65951401 ) 725 2 - vert 379 ( 0.6616839767 0.0640410185 ) 730 2 - vert 380 ( 0.7002540231 0.108009994 ) 732 2 - vert 381 ( 0.6562669873 0.162981987 ) 734 2 - vert 382 ( 0.5873320103 0.0721330047 ) 736 2 - vert 383 ( 0.5857499838 0.1638799906 ) 738 2 - vert 384 ( 0.9095330238 0.0776680112 ) 740 2 - vert 385 ( 0.9500690103 0.082242012 ) 736 2 - vert 386 ( 0.9484869838 0.1739889979 ) 738 2 - vert 387 ( 0.8223549724 0.0810359716 ) 742 2 - vert 388 ( 0.8626260161 0.1591299772 ) 744 1 - vert 389 ( 0.8216770291 0.1840500236 ) 745 1 - vert 390 ( 0.8397700191 0.0088210106 ) 746 3 - vert 391 ( 0.8705809712 0.0477510095 ) 749 2 - vert 392 ( 0.6747339964 0.0345870256 ) 725 2 - vert 393 ( 0.1165380031 0.610532999 ) 751 2 - vert 394 ( 0.9396790266 0.0486869812 ) 727 3 - vert 395 ( 0.5769420266 0.0385779738 ) 727 3 - vert 396 ( 0.7078279853 0.2049900293 ) 753 1 - vert 397 ( 0.887845993 0.2735739946 ) 754 3 - vert 398 ( 0.7376840115 0.157975018 ) 757 2 - vert 399 ( 0.6246330142 0.2245169878 ) 759 2 - vert 400 ( 0.7565789819 0.2561839819 ) 761 2 - vert 401 ( 0.9431530237 0.2816219926 ) 763 2 - vert 402 ( 0.9825749993 0.2901970148 ) 765 2 - vert 403 ( 0.9265419841 0.3301920295 ) 767 2 - vert 404 ( 0.8849400282 0.3162469864 ) 769 2 - vert 405 ( 0.9196789861 0.363763988 ) 771 1 - vert 406 ( 0.8798360229 0.3612269759 ) 772 1 - vert 407 ( 0.7701420188 0.3423240185 ) 773 2 - vert 408 ( 0.8043770194 0.2991089821 ) 775 2 - vert 409 ( 0.828963995 0.356325984 ) 777 2 - vert 410 ( 0.8504130244 0.3271620274 ) 779 2 - vert 411 ( 0.8518270254 0.2754150033 ) 781 2 - vert 412 ( 0.9873700142 0.2346259952 ) 759 2 - vert 413 ( 0.6971799731 0.2464299798 ) 783 2 - vert 414 ( 0.6198379993 0.2800880075 ) 765 2 - vert 415 ( 0.7516549826 0.2809749842 ) 785 2 - vert 416 ( 0.7999449968 0.2740920186 ) 787 2 - vert 417 ( 0.7743420005 0.1307820082 ) 789 2 - vert 418 ( 0.8858860135 0.4413160086 ) 791 1 - vert 419 ( 0.919664979 0.4355540276 ) 792 1 - vert 420 ( 0.9187830091 0.4915729761 ) 793 1 - vert 421 ( 0.9643340111 0.4460340142 ) 794 1 - vert 422 ( 0.9670060277 0.3808689713 ) 795 2 - vert 423 ( 0.8286380172 0.4186260104 ) 797 1 - vert 424 ( 0.7991189957 0.466835022 ) 798 1 - vert 425 ( 0.8234199882 0.5302729607 ) 799 1 - vert 426 ( 0.7234879732 0.5203169584 ) 800 1 - vert 427 ( 0.8661540151 0.4794849753 ) 801 1 - vert 428 ( 0.8763359785 0.5453959703 ) 802 1 - vert 429 ( 0.9250190258 0.5525410175 ) 803 2 - vert 430 ( 0.97596699 0.5522789955 ) 805 2 - vert 431 ( 0.6015980244 0.4359250069 ) 794 1 - vert 432 ( 0.6653469801 0.5165799856 ) 807 1 - vert 433 ( 0.61322999 0.5421699882 ) 805 2 - vert 434 ( 0.6808559895 0.4363690019 ) 808 1 - vert 435 ( 0.74792099 0.4414539933 ) 809 1 - vert 436 ( 0.7089049816 0.37252599 ) 810 1 - vert 437 ( 0.8737609982 0.6103760004 ) 811 2 - vert 438 ( 0.1917700022 0.9874539971 ) 813 1 - vert 439 ( 0.2043370008 0.9363080263 ) 814 1 - vert 440 ( 0.2633219957 0.9902449846 ) 815 2 - vert 441 ( 0.2603709996 0.9215610027 ) 817 2 - vert 442 ( 0.4588179886 0.3752769828 ) 819 3 - vert 443 ( 0.3043830097 0.3146250248 ) 822 4 - vert 444 ( 0.3677870035 0.2736859918 ) 826 4 - vert 445 ( 0.3868750036 0.3268780112 ) 830 3 - vert 446 ( 0.4728420079 0.2558709979 ) 833 4 - vert 447 ( 0.2187130004 0.899075985 ) 837 1 - vert 448 ( 0.2690410018 0.8628900051 ) 838 2 - vert 449 ( 0.1683640033 0.9854789972 ) 840 1 - vert 450 ( 0.1635289937 0.9143019915 ) 841 2 - vert 451 ( 0.183961004 0.6999030113 ) 843 1 - vert 452 ( 0.1685930043 0.6515290141 ) 840 1 - vert 453 ( 0.1921020001 0.6548619866 ) 813 1 - vert 454 ( 0.1861670017 0.2110670209 ) 844 4 - vert 455 ( 0.2472400069 0.1630690098 ) 848 6 - vert 456 ( 0.2551909983 0.2385969758 ) 854 5 - vert 457 ( 0.1106910035 0.8663179874 ) 859 4 - vert 458 ( 0.0627510026 0.8454350233 ) 863 4 - vert 459 ( 0.1359120011 0.8428989649 ) 867 3 - vert 460 ( 0.2829760015 0.2189210057 ) 870 4 - vert 461 ( 0.300853014 0.2472869754 ) 874 4 - vert 462 ( 0.3460890055 0.2240419984 ) 878 4 - vert 463 ( 0.2727189958 0.799405992 ) 882 2 - vert 464 ( 0.2999300063 0.8250650167 ) 884 2 - vert 465 ( 0.2954480052 0.7122550011 ) 886 2 - vert 466 ( 0.2603009939 0.7136909962 ) 888 2 - vert 467 ( 0.263936013 0.6731899977 ) 815 2 - vert 468 ( 0.2846580148 0.9553740025 ) 890 2 - vert 469 ( 0.2911350131 0.9950889945 ) 892 2 - vert 470 ( 0.2938460112 0.9138000011 ) 894 2 - vert 471 ( 0.2402170002 0.80576998 ) 896 1 - vert 472 ( 0.2677659988 0.7409399748 ) 897 2 - vert 473 ( 0.2038889974 0.7419040203 ) 899 1 - vert 474 ( 0.2918660045 0.681499958 ) 892 2 - vert 475 ( 0.1515060067 0.2566670179 ) 900 4 - vert 476 ( 0.2447099984 0.2737269998 ) 904 4 - vert 477 ( 0.1032959968 0.1600930095 ) 908 5 - vert 478 ( 0.0998020023 0.2631400228 ) 913 5 - vert 479 ( 0.4683189988 0.1387779713 ) 918 5 - vert 480 ( 0.406866014 0.1940310001 ) 923 5 - vert 481 ( 0.0661609992 0.058588028 ) 928 3 - vert 482 ( 0.111270003 0.9061470032 ) 848 6 - vert 483 ( 0.1489060074 0.8846759796 ) 931 3 - vert 484 ( 0.1432790011 0.9405339956 ) 870 4 - vert 485 ( 0.1273680031 0.9811329842 ) 878 4 - vert 486 ( 0.1018000022 0.7043390274 ) 934 3 - vert 487 ( 0.1274189949 0.6441459656 ) 878 4 - vert 488 ( 0.3896870017 0.0040079951 ) 937 3 - vert 489 ( 0.4449689984 0.0699130297 ) 940 3 - vert 490 ( 0.0793519989 0.6812579632 ) 923 5 - vert 491 ( 0.7603120208 0.0036579967 ) 715 2 - vert 492 ( 0.6042690277 0.3707600236 ) 795 2 - vert 493 ( 0.7208219767 0.0257869959 ) 751 2 - vert 494 ( 0.416602999 0.5872989893 ) 943 3 - vert 495 ( 0.9086660147 0.0305550098 ) 943 3 - vert 496 ( 0.203339994 0.1467779875 ) 946 4 - vert 497 ( 0.1226560026 0.3631550074 ) 950 6 - vert 498 ( 0.7987790108 0.0148829818 ) 956 2 - vert 499 ( 0.2247759998 0.5843609571 ) 956 2 - vert 500 ( 0.2846649885 0.5689849854 ) 746 3 - vert 501 ( 0.0755100027 0.8883000016 ) 958 4 - vert 502 ( 0.2226510048 0.0935739875 ) 962 3 - vert 503 ( 0.2742730081 0.0773720145 ) 965 4 - vert 504 ( 0.255629003 0.1107159853 ) 958 4 - vert 505 ( 0.9255869985 0.6043000221 ) 969 2 - vert 506 ( 0.843535006 0.6373449564 ) 647 3 - vert 507 ( 0.8402969837 0.6819820404 ) 650 3 - vert 508 ( 0.7736589909 0.6870989799 ) 971 3 - vert 509 ( 0.8996700048 0.768558979 ) 971 3 - vert 510 ( 0.7821429968 0.6192190051 ) 974 3 - vert 511 ( 0.9902340174 0.7758809924 ) 974 3 - vert 512 ( 0.27838099 0.5233770013 ) 977 3 - vert 513 ( 0.4570020139 0.5060349703 ) 980 3 - vert 514 ( 0.877572 0.0149059892 ) 983 2 - vert 515 ( 0.3460389972 0.5719139576 ) 983 2 - vert 516 ( 0.4124470055 0.1296200156 ) 985 4 - vert 517 ( 0.0435540006 0.7115600109 ) 985 4 - vert 518 ( 0.062804997 0.7602419853 ) 989 3 - vert 519 ( 0.3789699972 0.0994259715 ) 992 4 - vert 520 ( 0.0159210004 0.7509840131 ) 992 4 - vert 521 ( 0.0442270003 0.8014060259 ) 996 4 - vert 522 ( 0.3345260024 0.0731779933 ) 1000 4 - vert 523 ( 0.0077530001 0.8201950192 ) 1000 4 - vert 524 ( 0.4661230147 0.3288850188 ) 1004 3 - vert 525 ( 0.8384780288 0.8386750221 ) 655 3 - vert 526 ( 0.4004510045 0.8904989958 ) 1007 1 - vert 527 ( 0.5007230043 0.8608759642 ) 1008 1 - vert 528 ( 0.4774749875 0.898590982 ) 1009 3 - vert 529 ( 0.4339909852 0.8469029665 ) 1012 1 - vert 530 ( 0.5118749738 0.8208619952 ) 1013 1 - vert 531 ( 0.4504519999 0.8016870022 ) 1014 1 - vert 532 ( 0.519701004 0.7612500191 ) 1015 1 - vert 533 ( 0.3528000116 0.7389389873 ) 1016 1 - vert 534 ( 0.4434280097 0.7510669827 ) 1017 1 - vert 535 ( 0.5172349811 0.7290819883 ) 1018 1 - vert 536 ( 0.4215759933 0.7003450394 ) 1019 1 - vert 537 ( 0.3455109894 0.7057470083 ) 1020 1 - vert 538 ( 0.4011979997 0.933701992 ) 1021 1 - vert 539 ( 0.4768890142 0.9415969849 ) 1022 1 - vert 540 ( 0.4865309894 0.9777920246 ) 1023 1 - vert 541 ( 0.5789020061 0.8460580111 ) 1024 2 - vert 542 ( 0.570964992 0.8845490217 ) 1026 2 - vert 543 ( 0.5926210284 0.8259350061 ) 1028 1 - vert 544 ( 0.756724 0.9381579757 ) 1029 3 - vert 545 ( 0.7997699976 0.9733999968 ) 1032 3 - vert 546 ( 0.7890049815 0.9327999949 ) 1024 2 - vert 547 ( 0.6045969725 0.8296480179 ) 1035 1 - vert 548 ( 0.8025349975 0.8614699841 ) 1028 1 - vert 549 ( 0.6942149997 0.9865270257 ) 1036 1 - vert 550 ( 0.7491949797 0.9943079948 ) 1037 2 - vert 551 ( 0.7694820166 0.828707993 ) 1039 2 - vert 552 ( 0.8027639985 0.8125270009 ) 1041 1 - vert 553 ( 0.7869669795 0.8019449711 ) 1042 2 - vert 554 ( 0.6046180129 0.7234239578 ) 1044 2 - vert 555 ( 0.5959810019 0.7842389941 ) 1041 1 - vert 556 ( 0.6153159738 0.7025020123 ) 1046 2 - vert 557 ( 0.8136299849 0.7713860273 ) 1044 2 - vert 558 ( 0.7985380292 0.7631790042 ) 1048 2 - vert 559 ( 0.6491540074 0.7684370279 ) 1050 2 - vert 560 ( 0.6761140227 0.733044982 ) 1052 2 - vert 561 ( 0.6686120033 0.7034319639 ) 1054 2 - vert 562 ( 0.6734960079 0.9662230015 ) 1056 1 - vert 563 ( 0.700568974 0.8474110365 ) 1057 3 - vert 564 ( 0.74871701 0.7289980054 ) 1060 2 - vert 565 ( 0.7166720033 0.7589269876 ) 1062 3 - vert 566 ( 0.7685890198 0.7389019728 ) 1054 2 - vert 567 ( 0.7017890215 0.775538981 ) 1065 3 - vert 568 ( 0.7011880279 0.7465590239 ) 1062 3 - vert 569 ( 0.6883950233 0.7056699991 ) 1060 2 - vert 570 ( 0.6925330162 0.8118289709 ) 1068 3 - vert 571 ( 0.6550170183 0.7908899784 ) 1071 2 - vert 572 ( 0.6797599792 0.8512650132 ) 1073 3 - vert 573 ( 0.707852006 0.8104299903 ) 1076 3 - vert 574 ( 0.6074820161 0.7819190025 ) 1079 2 - vert 575 ( 0.6490619779 0.9733939767 ) 1081 1 - vert 576 ( 0.6052020192 0.9690830112 ) 1082 2 - vert 577 ( 0.6357730031 0.8398550153 ) 1084 2 - vert 578 ( 0.5528270006 0.8322100043 ) 1086 2 - vert 579 ( 0.5714309812 0.828256011 ) 1088 2 - vert 580 ( 0.5588089824 0.7859380245 ) 1090 2 - vert 581 ( 0.5543259978 0.8860200047 ) 1092 3 - vert 582 ( 0.5358489752 0.8347740173 ) 1095 2 - vert 583 ( 0.5730850101 0.793734014 ) 1097 2 - vert 584 ( 0.5840579867 0.8170059919 ) 1099 2 - vert 585 ( 0.8266770244 0.8883939981 ) 1090 2 - vert 586 ( 0.8161879778 0.8996319771 ) 1097 2 - vert 587 ( 0.8267859817 0.9110990167 ) 1101 2 - vert 588 ( 0.5714660287 0.952252984 ) 1103 2 - vert 589 ( 0.5351210237 0.9507679939 ) 1037 2 - vert 590 ( 0.5482320189 0.9537770152 ) 1105 1 - vert 591 ( 0.5381690264 0.8871129751 ) 1032 3 - vert 592 ( 0.8036159873 0.9287400246 ) 1099 2 - vert 593 ( 0.818508029 0.9463310242 ) 1095 2 - vert 594 ( 0.6241390109 0.782755971 ) 1106 2 - vert 595 ( 0.6376190186 0.781965971 ) 1042 2 - vert 596 ( 0.6422780156 0.7077629566 ) 1048 2 - vert 597 ( 0.6305840015 0.7032589912 ) 1108 2 - vert 598 ( 0.6214889884 0.8390759826 ) 1110 2 - vert 599 ( 0.6353539824 0.8060629964 ) 1039 2 - vert 600 ( 0.5176740289 0.8607789874 ) 1082 2 - vert 601 ( 0.528603971 0.8226339817 ) 1081 1 - vert 602 ( 0.5028409958 0.8987259865 ) 1103 2 - vert 603 ( 0.5392010212 0.7466000319 ) 1056 1 - vert 604 ( 0.5311419964 0.6905180216 ) 1036 1 - vert 605 ( 0.5001900196 0.6796820164 ) 1023 1 - vert 606 ( 0.5029720068 0.9707750082 ) 1036 1 - vert 607 ( 0.4968389869 0.941429019 ) 1037 2 - vert 608 ( 0.4974350035 0.9217699766 ) 1105 1 - vert 609 ( 0.8029379845 0.7442569733 ) 1108 2 - vert 610 ( 0.8184109926 0.7529680133 ) 1046 2 - vert 611 ( 0.6204379797 0.7389010191 ) 1112 2 - vert 612 ( 0.7697860003 0.7841470242 ) 1050 2 - vert 613 ( 0.0282600001 0.8698080182 ) 965 4 - vert 614 ( 0.7046319842 0.2813230157 ) 1114 2 - vert 615 ( 0.7586479783 0.3050389886 ) 1116 2 - vert 616 ( 0.695694983 0.3050810099 ) 1118 2 - vert 617 ( 0.5461469889 0.7879520059 ) 1101 2 - vert 618 ( 0.1138980016 0.8113780022 ) 1120 3 - vert 619 ( 0.1568849981 0.1397330165 ) 1123 4 - vert 620 ( 0.1609240025 0.0286160111 ) 1127 3 - vert 621 ( 0.1804230064 0.0740810037 ) 1130 3 - vert 622 ( 0.2538779974 0.0489689708 ) 1133 3 - vert 623 ( 0.2719900012 0.0071799755 ) 1136 3 - vert 624 ( 0.3432950079 0.0435640216 ) 1139 3 - vert 625 ( 0.4060660005 0.9733899832 ) 1019 1 - vert 626 ( 0.3240619898 0.7848359942 ) 1142 2 - vert 627 ( 0.3027069867 0.7717610002 ) 1144 2 - vert 628 ( 0.3004209995 0.7371799946 ) 1146 2 - vert 629 ( 0.3276099861 0.7369199991 ) 1148 2 - vert 630 ( 0.3222169876 0.9879009724 ) 1150 2 - vert 631 ( 0.3231050074 0.6688380241 ) 1150 2 - vert 632 ( 0.3229289949 0.7101849914 ) 1152 2 - vert 633 ( 0.109232001 0.7468780279 ) 1154 3 - vert 634 ( 0.3695369959 0.1779459715 ) 586 3 - vert 635 ( 0.2719840109 0.1439909935 ) 1136 3 - vert 636 ( 0.2801170051 0.1779459715 ) 1127 3 - vert 637 ( 0.3511709869 0.1982280016 ) 362 3 - vert 638 ( 0.2984839976 0.1982280016 ) 928 3 - vert 639 ( 0.3248269856 0.2080720067 ) 359 3 - vert 640 ( 0.3625769913 0.1138330102 ) 375 3 - vert 641 ( 0.3248269856 0.0980470181 ) 371 4 - vert 642 ( 0.2870770097 0.1138330102 ) 937 3 - vert 643 ( 0.3776699901 0.1439909935 ) 595 3 - - numtris 930 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 5 3 6 - tri 3 9 8 7 - tri 4 8 10 7 - tri 5 12 11 10 - tri 6 14 2 13 - tri 7 16 13 15 - tri 8 17 16 15 - tri 9 20 19 18 - tri 10 20 18 1 - tri 11 14 20 2 - tri 12 20 1 2 - tri 13 23 22 21 - tri 14 26 25 24 - tri 15 29 28 27 - tri 16 18 30 1 - tri 17 31 25 26 - tri 18 32 23 21 - tri 19 34 33 23 - tri 20 17 15 35 - tri 21 19 30 18 - tri 22 32 21 36 - tri 23 39 38 37 - tri 24 40 38 39 - tri 25 42 41 38 - tri 26 44 39 43 - tri 27 47 46 45 - tri 28 45 46 48 - tri 29 45 48 40 - tri 30 40 48 38 - tri 31 48 42 38 - tri 32 51 50 49 - tri 33 54 53 52 - tri 34 56 55 51 - tri 35 56 57 55 - tri 36 55 50 51 - tri 37 44 40 39 - tri 38 47 58 46 - tri 39 61 60 59 - tri 40 63 62 60 - tri 41 61 63 60 - tri 42 66 65 64 - tri 43 69 68 67 - tri 44 68 71 70 - tri 45 67 68 70 - tri 46 60 62 72 - tri 47 52 53 73 - tri 48 64 65 74 - tri 49 62 75 72 - tri 50 76 61 59 - tri 51 77 65 66 - tri 52 76 59 78 - tri 53 79 63 61 - tri 54 80 76 78 - tri 55 77 67 65 - tri 56 67 70 65 - tri 57 53 58 47 - tri 58 73 53 47 - tri 59 58 81 46 - tri 60 84 83 82 - tri 61 86 85 84 - tri 62 86 87 85 - tri 63 90 89 88 - tri 64 90 88 91 - tri 65 91 92 85 - tri 66 87 91 85 - tri 67 82 83 93 - tri 68 95 79 94 - tri 69 94 79 76 - tri 70 96 94 80 - tri 71 88 97 92 - tri 72 96 80 97 - tri 73 83 77 66 - tri 74 83 66 93 - tri 75 79 61 76 - tri 76 94 76 80 - tri 77 91 88 92 - tri 78 85 92 77 - tri 79 84 85 77 - tri 80 84 77 83 - tri 81 69 98 68 - tri 82 101 100 99 - tri 83 101 99 102 - tri 84 103 84 82 - tri 85 104 89 90 - tri 86 104 90 87 - tri 87 87 90 91 - tri 88 100 87 86 - tri 89 99 100 86 - tri 90 99 86 103 - tri 91 103 86 84 - tri 92 107 106 105 - tri 93 105 106 108 - tri 94 109 105 108 - tri 95 109 108 100 - tri 96 109 100 101 - tri 97 110 109 101 - tri 98 111 110 101 - tri 99 111 101 102 - tri 100 114 113 112 - tri 101 112 113 115 - tri 102 107 116 106 - tri 103 116 117 89 - tri 104 108 106 104 - tri 105 108 104 100 - tri 106 100 104 87 - tri 107 102 99 103 - tri 108 115 117 116 - tri 109 31 114 25 - tri 110 25 114 112 - tri 111 25 107 11 - tri 112 25 112 107 - tri 113 10 11 107 - tri 114 10 107 105 - tri 115 7 10 105 - tri 116 7 105 109 - tri 117 118 7 109 - tri 118 121 120 119 - tri 119 121 119 122 - tri 120 125 124 123 - tri 121 43 124 125 - tri 122 128 127 126 - tri 123 38 41 37 - tri 124 37 41 127 - tri 125 128 126 129 - tri 126 37 127 128 - tri 127 43 39 37 - tri 128 122 119 130 - tri 129 122 130 131 - tri 130 119 133 132 - tri 131 120 133 119 - tri 132 136 135 134 - tri 133 139 138 137 - tri 134 142 141 140 - tri 135 139 137 143 - tri 136 144 139 143 - tri 137 144 143 145 - tri 138 131 147 146 - tri 139 150 149 148 - tri 140 152 121 151 - tri 141 151 121 122 - tri 142 151 122 153 - tri 143 153 122 131 - tri 144 131 142 154 - tri 145 148 155 135 - tri 146 149 155 148 - tri 147 155 156 135 - tri 148 157 149 150 - tri 149 131 154 147 - tri 150 41 159 158 - tri 151 41 158 127 - tri 152 158 144 126 - tri 153 127 158 126 - tri 154 161 160 159 - tri 155 129 163 162 - tri 156 164 160 161 - tri 157 126 165 129 - tri 158 129 165 163 - tri 159 158 159 138 - tri 160 126 145 165 - tri 161 126 144 145 - tri 162 164 166 160 - tri 163 159 160 138 - tri 164 166 167 160 - tri 165 160 167 168 - tri 166 132 170 169 - tri 167 133 171 132 - tri 168 172 171 133 - tri 169 174 134 173 - tri 170 134 135 173 - tri 171 171 170 132 - tri 172 170 141 169 - tri 173 177 176 175 - tri 174 162 163 177 - tri 175 162 177 175 - tri 176 174 173 178 - tri 177 46 42 48 - tri 178 158 139 144 - tri 179 158 138 139 - tri 180 169 141 142 - tri 181 78 179 98 - tri 182 97 80 98 - tri 183 80 78 98 - tri 184 97 98 69 - tri 185 113 117 115 - tri 186 113 180 117 - tri 187 92 97 69 - tri 188 92 67 77 - tri 189 92 69 67 - tri 190 24 11 12 - tri 191 24 25 11 - tri 192 59 60 181 - tri 193 60 72 181 - tri 194 78 59 179 - tri 195 59 181 179 - tri 196 55 182 50 - tri 197 65 183 74 - tri 198 65 70 183 - tri 199 138 184 137 - tri 200 185 164 161 - tri 201 186 185 42 - tri 202 187 164 185 - tri 203 186 187 185 - tri 204 42 185 41 - tri 205 41 185 159 - tri 206 185 161 159 - tri 207 68 188 71 - tri 208 98 188 68 - tri 209 98 179 188 - tri 210 47 45 189 - tri 211 189 45 190 - tri 212 170 191 141 - tri 213 194 193 192 - tri 214 29 9 118 - tri 215 29 118 195 - tri 216 8 12 10 - tri 217 2 0 13 - tri 218 29 195 28 - tri 219 9 7 118 - tri 220 112 115 116 - tri 221 112 116 107 - tri 222 195 118 110 - tri 223 118 109 110 - tri 224 28 110 111 - tri 225 28 195 110 - tri 226 198 197 196 - tri 227 199 34 23 - tri 228 199 23 32 - tri 229 198 5 6 - tri 230 198 6 200 - tri 231 14 13 201 - tri 232 201 13 16 - tri 233 198 200 197 - tri 234 202 40 44 - tri 235 190 202 44 - tri 236 190 45 202 - tri 237 45 40 202 - tri 238 50 203 49 - tri 239 50 44 203 - tri 240 44 43 203 - tri 241 70 204 183 - tri 242 70 71 204 - tri 243 205 190 44 - tri 244 49 43 125 - tri 245 49 203 43 - tri 246 205 44 50 - tri 247 182 205 50 - tri 248 131 169 142 - tri 249 130 169 131 - tri 250 119 132 130 - tri 251 130 132 169 - tri 252 163 206 177 - tri 253 165 206 163 - tri 254 178 173 207 - tri 255 173 208 207 - tri 256 206 209 177 - tri 257 207 208 210 - tri 258 208 211 210 - tri 259 209 212 177 - tri 260 210 211 213 - tri 261 124 37 128 - tri 262 43 37 124 - tri 263 123 124 214 - tri 264 124 128 214 - tri 265 214 128 129 - tri 266 123 214 215 - tri 267 215 214 129 - tri 268 215 129 216 - tri 269 216 129 162 - tri 270 30 0 1 - tri 271 30 217 0 - tri 272 220 219 218 - tri 273 222 218 221 - tri 274 219 221 218 - tri 275 224 222 223 - tri 276 223 222 221 - tri 277 226 223 225 - tri 278 228 227 226 - tri 279 226 225 229 - tri 280 228 226 229 - tri 281 223 221 146 - tri 282 232 231 230 - tri 283 235 234 233 - tri 284 238 237 236 - tri 285 235 233 239 - tri 286 240 237 238 - tri 287 237 242 241 - tri 288 244 243 240 - tri 289 244 245 243 - tri 290 248 247 246 - tri 291 249 245 244 - tri 292 250 245 249 - tri 293 253 252 251 - tri 294 255 254 242 - tri 295 246 235 239 - tri 296 258 257 256 - tri 297 260 251 259 - tri 298 261 251 260 - tri 299 251 262 259 - tri 300 251 263 262 - tri 301 255 262 264 - tri 302 265 262 255 - tri 303 259 262 265 - tri 304 246 239 266 - tri 305 248 246 266 - tri 306 253 251 261 - tri 307 255 264 254 - tri 308 264 267 254 - tri 309 239 233 268 - tri 310 269 268 267 - tri 311 237 241 236 - tri 312 272 271 270 - tri 313 274 273 271 - tri 314 275 272 270 - tri 315 275 270 276 - tri 316 279 278 277 - tri 317 273 280 233 - tri 318 233 280 268 - tri 319 283 282 281 - tri 320 274 283 273 - tri 321 285 284 236 - tri 322 270 233 234 - tri 323 288 287 286 - tri 324 289 287 288 - tri 325 264 269 267 - tri 326 276 270 234 - tri 327 284 238 236 - tri 328 263 269 264 - tri 329 262 263 264 - tri 330 291 290 269 - tri 331 290 268 269 - tri 332 239 268 290 - tri 333 231 153 219 - tri 334 219 153 131 - tri 335 292 218 222 - tri 336 293 292 222 - tri 337 224 293 222 - tri 338 220 218 294 - tri 339 294 218 292 - tri 340 295 293 224 - tri 341 297 296 227 - tri 342 227 296 295 - tri 343 227 295 224 - tri 344 232 230 298 - tri 345 283 280 273 - tri 346 283 281 280 - tri 347 255 242 237 - tri 348 230 299 298 - tri 349 230 300 299 - tri 350 300 220 294 - tri 351 230 220 300 - tri 352 255 237 243 - tri 353 243 237 240 - tri 354 291 287 290 - tri 355 286 287 291 - tri 356 302 301 249 - tri 357 301 250 249 - tri 358 303 266 287 - tri 359 289 303 287 - tri 360 248 303 289 - tri 361 248 266 303 - tri 362 252 269 263 - tri 363 252 291 269 - tri 364 251 252 263 - tri 365 258 256 265 - tri 366 256 259 265 - tri 367 265 243 304 - tri 368 265 255 243 - tri 369 258 265 304 - tri 370 290 287 266 - tri 371 266 239 290 - tri 372 221 219 131 - tri 373 131 146 221 - tri 374 220 230 231 - tri 375 231 219 220 - tri 376 151 153 231 - tri 377 213 211 140 - tri 378 140 305 213 - tri 379 89 104 106 - tri 380 106 116 89 - tri 381 306 95 94 - tri 382 306 94 96 - tri 383 307 306 96 - tri 384 307 96 97 - tri 385 307 97 88 - tri 386 307 88 89 - tri 387 307 89 117 - tri 388 308 180 95 - tri 389 308 95 306 - tri 390 308 306 307 - tri 391 308 307 117 - tri 392 308 117 180 - tri 393 233 270 271 - tri 394 271 273 233 - tri 395 272 274 271 - tri 396 309 274 272 - tri 397 284 285 279 - tri 398 279 277 284 - tri 399 310 156 154 - tri 400 310 154 142 - tri 401 310 142 140 - tri 402 305 140 141 - tri 403 141 191 305 - tri 404 194 137 184 - tri 405 184 193 194 - tri 406 211 208 310 - tri 407 310 140 211 - tri 408 311 193 184 - tri 409 311 184 138 - tri 410 311 138 160 - tri 411 313 168 312 - tri 412 313 192 193 - tri 413 313 193 311 - tri 414 314 212 192 - tri 415 314 192 313 - tri 416 314 313 312 - tri 417 314 312 315 - tri 418 316 177 212 - tri 419 316 212 314 - tri 420 316 314 315 - tri 421 316 315 176 - tri 422 316 176 177 - tri 423 317 231 232 - tri 424 297 227 228 - tri 425 226 227 224 - tri 426 224 223 226 - tri 427 155 147 154 - tri 428 154 156 155 - tri 429 186 42 46 - tri 430 46 81 186 - tri 431 313 311 160 - tri 432 160 168 313 - tri 433 319 318 146 - tri 434 319 146 147 - tri 435 319 147 155 - tri 436 320 319 155 - tri 437 320 155 149 - tri 438 321 319 320 - tri 439 321 320 149 - tri 440 318 319 321 - tri 441 321 225 318 - tri 442 322 231 317 - tri 443 323 228 229 - tri 444 322 152 151 - tri 445 322 151 231 - tri 446 324 321 149 - tri 447 157 323 324 - tri 448 324 149 157 - tri 449 229 225 321 - tri 450 229 321 324 - tri 451 229 324 323 - tri 452 223 146 318 - tri 453 318 225 223 - tri 454 136 150 148 - tri 455 148 135 136 - tri 456 325 156 310 - tri 457 325 310 208 - tri 458 325 208 173 - tri 459 325 173 135 - tri 460 325 135 156 - tri 461 328 327 326 - tri 462 331 330 329 - tri 463 331 332 330 - tri 464 335 334 333 - tri 465 333 334 336 - tri 466 338 336 337 - tri 467 340 339 328 - tri 468 342 341 339 - tri 469 343 341 342 - tri 470 346 345 344 - tri 471 346 326 345 - tri 472 340 328 346 - tri 473 346 328 326 - tri 474 349 348 347 - tri 475 352 351 350 - tri 476 355 354 353 - tri 477 345 326 356 - tri 478 357 352 350 - tri 479 358 348 349 - tri 480 360 349 359 - tri 481 343 361 341 - tri 482 344 345 356 - tri 483 358 362 348 - tri 484 365 364 363 - tri 485 366 365 363 - tri 486 368 363 367 - tri 487 370 369 365 - tri 488 373 372 371 - tri 489 372 374 371 - tri 490 372 366 374 - tri 491 366 363 374 - tri 492 374 363 368 - tri 493 51 49 375 - tri 494 54 376 53 - tri 495 56 51 377 - tri 496 56 377 378 - tri 497 377 51 375 - tri 498 370 365 366 - tri 499 373 371 58 - tri 500 381 380 379 - tri 501 383 379 382 - tri 502 381 379 383 - tri 503 386 385 384 - tri 504 389 388 387 - tri 505 387 391 390 - tri 506 388 391 387 - tri 507 379 392 382 - tri 508 376 393 53 - tri 509 385 394 384 - tri 510 382 392 395 - tri 511 396 380 381 - tri 512 397 386 384 - tri 513 396 398 380 - tri 514 399 381 383 - tri 515 400 398 396 - tri 516 397 384 388 - tri 517 388 384 391 - tri 518 53 373 58 - tri 519 393 373 53 - tri 520 58 371 81 - tri 521 403 402 401 - tri 522 405 403 404 - tri 523 405 404 406 - tri 524 409 408 407 - tri 525 409 410 408 - tri 526 410 404 411 - tri 527 406 404 410 - tri 528 402 412 401 - tri 529 414 413 399 - tri 530 413 396 399 - tri 531 415 400 413 - tri 532 408 411 416 - tri 533 415 416 400 - tri 534 401 386 397 - tri 535 401 412 386 - tri 536 399 396 381 - tri 537 413 400 396 - tri 538 410 411 408 - tri 539 404 397 411 - tri 540 403 397 404 - tri 541 403 401 397 - tri 542 389 387 417 - tri 543 420 419 418 - tri 544 420 421 419 - tri 545 422 402 403 - tri 546 423 409 407 - tri 547 423 406 409 - tri 548 406 410 409 - tri 549 418 405 406 - tri 550 419 405 418 - tri 551 419 422 405 - tri 552 422 403 405 - tri 553 426 425 424 - tri 554 425 427 424 - tri 555 428 427 425 - tri 556 428 418 427 - tri 557 428 420 418 - tri 558 429 420 428 - tri 559 430 420 429 - tri 560 430 421 420 - tri 561 433 432 431 - tri 562 432 434 431 - tri 563 426 424 435 - tri 564 435 407 436 - tri 565 427 423 424 - tri 566 427 418 423 - tri 567 418 406 423 - tri 568 421 422 419 - tri 569 434 435 436 - tri 570 357 350 433 - tri 571 350 432 433 - tri 572 350 337 426 - tri 573 350 426 432 - tri 574 336 426 337 - tri 575 336 425 426 - tri 576 334 425 336 - tri 577 334 428 425 - tri 578 437 428 334 - tri 579 440 439 438 - tri 580 440 441 439 - tri 581 125 123 442 - tri 582 369 125 442 - tri 583 445 444 443 - tri 584 363 364 367 - tri 585 364 443 367 - tri 586 445 446 444 - tri 587 364 445 443 - tri 588 369 364 365 - tri 589 441 447 439 - tri 590 441 448 447 - tri 591 439 450 449 - tri 592 438 439 449 - tri 593 453 452 451 - tri 594 456 455 454 - tri 595 459 458 457 - tri 596 456 460 455 - tri 597 461 460 456 - tri 598 461 462 460 - tri 599 448 464 463 - tri 600 467 466 465 - tri 601 469 468 440 - tri 602 468 441 440 - tri 603 468 470 441 - tri 604 470 448 441 - tri 605 448 471 459 - tri 606 466 451 472 - tri 607 465 466 472 - tri 608 472 451 473 - tri 609 474 467 465 - tri 610 448 463 471 - tri 611 367 476 475 - tri 612 367 443 476 - tri 613 476 444 461 - tri 614 443 444 476 - tri 615 478 475 477 - tri 616 446 162 479 - tri 617 164 478 477 - tri 618 444 446 480 - tri 619 446 479 480 - tri 620 476 454 475 - tri 621 444 480 462 - tri 622 444 462 461 - tri 623 164 477 166 - tri 624 475 454 477 - tri 625 166 477 167 - tri 626 477 481 167 - tri 627 450 483 482 - tri 628 449 450 484 - tri 629 485 449 484 - tri 630 487 486 452 - tri 631 452 486 451 - tri 632 484 450 482 - tri 633 482 483 457 - tri 634 489 175 488 - tri 635 162 489 479 - tri 636 162 175 489 - tri 637 487 490 486 - tri 638 371 374 368 - tri 639 476 461 456 - tri 640 476 456 454 - tri 641 483 459 457 - tri 642 398 417 491 - tri 643 416 417 400 - tri 644 400 417 398 - tri 645 416 389 417 - tri 646 431 434 436 - tri 647 431 436 492 - tri 648 411 389 416 - tri 649 411 397 388 - tri 650 411 388 389 - tri 651 351 338 337 - tri 652 351 337 350 - tri 653 380 493 379 - tri 654 379 493 392 - tri 655 398 491 380 - tri 656 380 491 493 - tri 657 377 375 494 - tri 658 384 394 495 - tri 659 384 495 391 - tri 660 454 455 496 - tri 661 497 478 164 - tri 662 186 368 497 - tri 663 187 497 164 - tri 664 186 497 187 - tri 665 368 367 497 - tri 666 367 475 497 - tri 667 497 475 478 - tri 668 387 390 498 - tri 669 417 387 498 - tri 670 417 498 491 - tri 671 373 499 372 - tri 672 499 500 372 - tri 673 482 457 501 - tri 674 504 503 502 - tri 675 355 437 335 - tri 676 355 505 437 - tri 677 333 336 338 - tri 678 328 339 327 - tri 679 355 353 505 - tri 680 335 437 334 - tri 681 432 435 434 - tri 682 432 426 435 - tri 683 505 429 437 - tri 684 437 429 428 - tri 685 353 430 429 - tri 686 353 429 505 - tri 687 508 507 506 - tri 688 509 349 360 - tri 689 509 358 349 - tri 690 508 332 331 - tri 691 508 510 332 - tri 692 340 511 339 - tri 693 511 342 339 - tri 694 508 506 510 - tri 695 512 370 366 - tri 696 500 370 512 - tri 697 500 512 372 - tri 698 372 512 366 - tri 699 375 49 513 - tri 700 375 513 370 - tri 701 370 513 369 - tri 702 391 495 514 - tri 703 391 514 390 - tri 704 515 370 500 - tri 705 49 125 369 - tri 706 49 369 513 - tri 707 515 375 370 - tri 708 494 375 515 - tri 709 448 459 483 - tri 710 447 448 483 - tri 711 439 447 450 - tri 712 447 483 450 - tri 713 479 489 516 - tri 714 480 479 516 - tri 715 490 517 486 - tri 716 486 517 518 - tri 717 516 489 519 - tri 718 517 520 518 - tri 719 518 520 521 - tri 720 519 489 522 - tri 721 520 523 521 - tri 722 442 445 364 - tri 723 369 442 364 - tri 724 123 524 442 - tri 725 442 524 445 - tri 726 524 446 445 - tri 727 123 215 524 - tri 728 215 446 524 - tri 729 215 216 446 - tri 730 216 162 446 - tri 731 356 326 327 - tri 732 356 327 525 - tri 733 528 527 526 - tri 734 530 529 527 - tri 735 526 527 529 - tri 736 532 531 530 - tri 737 531 529 530 - tri 738 534 533 531 - tri 739 536 534 535 - tri 740 534 537 533 - tri 741 536 537 534 - tri 742 531 464 529 - tri 743 540 539 538 - tri 744 543 542 541 - tri 745 546 545 544 - tri 746 543 547 542 - tri 747 548 546 544 - tri 748 544 550 549 - tri 749 552 548 551 - tri 750 552 551 553 - tri 751 556 555 554 - tri 752 557 552 553 - tri 753 558 557 553 - tri 754 561 560 559 - tri 755 563 549 562 - tri 756 555 547 543 - tri 757 566 565 564 - tri 758 568 567 560 - tri 759 569 568 560 - tri 760 560 567 570 - tri 761 560 570 571 - tri 762 563 572 570 - tri 763 573 563 570 - tri 764 567 573 570 - tri 765 555 574 547 - tri 766 556 574 555 - tri 767 561 569 560 - tri 768 563 562 572 - tri 769 572 562 575 - tri 770 547 576 542 - tri 771 577 575 576 - tri 772 544 545 550 - tri 773 580 579 578 - tri 774 582 578 581 - tri 775 583 579 580 - tri 776 583 584 579 - tri 777 587 586 585 - tri 778 581 542 588 - tri 779 542 576 588 - tri 780 591 590 589 - tri 781 582 581 591 - tri 782 593 545 592 - tri 783 579 541 542 - tri 784 596 595 594 - tri 785 597 596 594 - tri 786 572 575 577 - tri 787 584 541 579 - tri 788 592 545 546 - tri 789 571 572 577 - tri 790 570 572 571 - tri 791 599 577 598 - tri 792 598 577 576 - tri 793 547 598 576 - tri 794 538 526 470 - tri 795 526 448 470 - tri 796 600 530 527 - tri 797 601 530 600 - tri 798 532 530 601 - tri 799 528 602 527 - tri 800 602 600 527 - tri 801 603 532 601 - tri 802 605 535 604 - tri 803 535 603 604 - tri 804 535 532 603 - tri 805 540 606 539 - tri 806 591 581 588 - tri 807 591 588 590 - tri 808 563 544 549 - tri 809 539 606 607 - tri 810 539 607 608 - tri 811 608 602 528 - tri 812 539 608 528 - tri 813 563 551 544 - tri 814 551 548 544 - tri 815 599 598 594 - tri 816 595 599 594 - tri 817 610 557 609 - tri 818 609 557 558 - tri 819 611 594 574 - tri 820 597 594 611 - tri 821 556 597 611 - tri 822 556 611 574 - tri 823 559 571 577 - tri 824 559 577 599 - tri 825 560 571 559 - tri 826 566 573 565 - tri 827 565 573 567 - tri 828 573 612 551 - tri 829 573 551 563 - tri 830 566 612 573 - tri 831 598 574 594 - tri 832 574 598 547 - tri 833 529 448 526 - tri 834 448 529 464 - tri 835 528 538 539 - tri 836 538 528 526 - tri 837 468 538 470 - tri 838 523 458 521 - tri 839 458 523 613 - tri 840 407 424 423 - tri 841 424 407 435 - tri 842 614 413 414 - tri 843 614 415 413 - tri 844 615 415 614 - tri 845 615 416 415 - tri 846 615 408 416 - tri 847 615 407 408 - tri 848 615 436 407 - tri 849 616 414 492 - tri 850 616 614 414 - tri 851 616 615 614 - tri 852 616 436 615 - tri 853 616 492 436 - tri 854 542 578 579 - tri 855 578 542 581 - tri 856 580 578 582 - tri 857 617 580 582 - tri 858 592 587 593 - tri 859 587 592 586 - tri 860 618 471 473 - tri 861 618 459 471 - tri 862 618 458 459 - tri 863 613 457 458 - tri 864 457 613 501 - tri 865 504 496 455 - tri 866 496 504 502 - tri 867 521 618 518 - tri 868 618 521 458 - tri 869 619 496 502 - tri 870 619 454 496 - tri 871 619 477 454 - tri 872 621 620 481 - tri 873 621 502 503 - tri 874 621 619 502 - tri 875 622 503 522 - tri 876 622 621 503 - tri 877 622 620 621 - tri 878 622 623 620 - tri 879 624 522 489 - tri 880 624 622 522 - tri 881 624 623 622 - tri 882 624 488 623 - tri 883 624 489 488 - tri 884 625 540 538 - tri 885 605 536 535 - tri 886 534 532 535 - tri 887 532 534 531 - tri 888 472 471 463 - tri 889 471 472 473 - tri 890 186 371 368 - tri 891 371 186 81 - tri 892 621 477 619 - tri 893 477 621 481 - tri 894 627 464 626 - tri 895 627 463 464 - tri 896 627 472 463 - tri 897 628 472 627 - tri 898 628 465 472 - tri 899 629 628 627 - tri 900 629 465 628 - tri 901 626 629 627 - tri 902 629 626 533 - tri 903 630 625 538 - tri 904 631 537 536 - tri 905 630 468 469 - tri 906 630 538 468 - tri 907 632 465 629 - tri 908 474 632 631 - tri 909 632 474 465 - tri 910 537 629 533 - tri 911 537 632 629 - tri 912 537 631 632 - tri 913 531 626 464 - tri 914 626 531 533 - tri 915 453 466 467 - tri 916 466 453 451 - tri 917 633 618 473 - tri 918 633 518 618 - tri 919 633 486 518 - tri 920 633 451 486 - tri 921 633 473 451 - tri 922 636 635 634 - tri 923 637 636 634 - tri 924 639 638 637 - tri 925 637 638 636 - tri 926 642 641 640 - tri 927 642 640 643 - tri 928 643 634 635 - tri 929 635 642 643 - - numweights 1157 - weight 0 5 0.0935239866 ( 3.8127360344 18.653427124 -1.0291671753 ) - weight 1 6 0.6671485305 ( -0.7151768804 3.1304476261 2.3139109612 ) - weight 2 7 0.2393274605 ( -1.2482603788 -0.3180599511 2.8520338535 ) - weight 3 6 0.0843834653 ( -0.103548944 6.4286642075 4.4149246216 ) - weight 4 7 0.5620473027 ( -1.5335928202 3.6064872742 2.4241364002 ) - weight 5 8 0.3535692692 ( -1.5020233393 -1.489027977 2.4291889668 ) - weight 6 6 0.4737676382 ( -1.7838802338 5.0132069588 1.860653758 ) - weight 7 7 0.5262323618 ( -2.2546744347 0.5913563371 1.1049093008 ) - weight 8 7 0.5011257529 ( -2.0092220306 4.9650716782 -0.9881344438 ) - weight 9 8 0.4988743067 ( -2.0064079762 -0.1527582258 -0.9877608418 ) - weight 10 7 0.5046935678 ( 2.2403481007 4.8383469582 -0.8591219783 ) - weight 11 8 0.495306462 ( 2.2448923588 -0.1879273951 -0.8583108187 ) - weight 12 6 0.4963374138 ( 2.4411556721 6.207262516 -1.945104003 ) - weight 13 7 0.5036625266 ( 2.8364603519 0.282594353 -1.678165555 ) - weight 14 6 0.4661476612 ( -2.9416100979 6.680390358 -0.1249469966 ) - weight 15 7 0.4800623953 ( -2.864084959 0.4030626416 -1.661968708 ) - weight 16 8 0.0537899137 ( -2.7632496357 -4.7343444824 -1.6458108425 ) - weight 17 5 0.6232063174 ( 2.7473978996 19.8591384888 3.444442749 ) - weight 18 6 0.2971909642 ( -4.5151796341 0.6758175492 0.8521854877 ) - weight 19 7 0.079602696 ( -4.244515419 -4.0007386208 2.6026239395 ) - weight 20 5 0.3033103049 ( 1.7648807764 19.9354686737 0.9160862565 ) - weight 21 6 0.6966896653 ( -2.0447351933 1.4687639475 0.0572685003 ) - weight 22 5 0.5 ( -1.1340595484 20.9681053162 2.7353503704 ) - weight 23 6 0.5 ( -2.8432769775 -0.802236855 -2.5856084824 ) - weight 24 5 0.2689843774 ( 4.0151314735 18.6074390411 0.8103916645 ) - weight 25 6 0.5431468487 ( -2.3177797794 2.2326209545 2.543315649 ) - weight 26 7 0.1878687739 ( -2.7789907455 -1.2632453442 3.2885482311 ) - weight 27 5 0.1060663685 ( 3.8994646072 17.6567077637 -2.6287512779 ) - weight 28 6 0.4873141348 ( 0.9746853113 3.5118246078 3.06127882 ) - weight 29 7 0.3494953811 ( 0.1032667458 0.833692193 3.4895937443 ) - weight 30 8 0.0571241342 ( 0.193809092 -4.2224025726 3.5042312145 ) - weight 31 5 0.3997223675 ( -1.1646174192 23.7804584503 2.4665853977 ) - weight 32 6 0.416490972 ( -3.686072588 0.8614727259 -4.7079334259 ) - weight 33 7 0.1837866157 ( -1.7758827209 -6.9593877792 -1.4948219061 ) - weight 34 5 0.4107972383 ( -3.0434248447 23.3945465088 0.2558149397 ) - weight 35 6 0.4213652015 ( -0.9571701884 0.6585357189 -5.7463259697 ) - weight 36 7 0.1678375453 ( 1.146812439 -7.0609116554 -1.6127066612 ) - weight 37 7 0.5249262452 ( 0.3187460601 4.7918243408 1.1942294836 ) - weight 38 8 0.475073725 ( 0.3245765269 -0.2685232162 1.1951892376 ) - weight 39 6 0.1096295714 ( 2.9207594395 6.0545563698 3.1228327751 ) - weight 40 7 0.5836595297 ( 1.7587673664 3.2957522869 2.2837507725 ) - weight 41 8 0.3067108989 ( 1.7962508202 -1.7296113968 2.2898790836 ) - weight 42 5 0.0803422183 ( 2.1394081116 18.4398002625 -3.2200272083 ) - weight 43 6 0.6961277723 ( 1.8512949944 3.1415815353 1.2850141525 ) - weight 44 7 0.2235300243 ( 1.5025411844 -0.2899706364 2.5730495453 ) - weight 45 5 0.120941259 ( 0.4943208694 19.4355697632 -3.2106790543 ) - weight 46 6 0.7397739887 ( 2.0982830524 2.6337282658 -0.5532013774 ) - weight 47 7 0.13928473 ( 2.3319923878 -1.7106441259 1.5772321224 ) - weight 48 5 0.1834091842 ( 1.6726700068 17.7061920166 -4.2953872681 ) - weight 49 6 0.5260417461 ( 3.2151074409 3.02911973 1.4844964743 ) - weight 50 7 0.2905490696 ( 2.7451124191 0.0778421387 3.055911541 ) - weight 51 5 0.307454288 ( -1.149764657 19.6340618134 -3.7381052971 ) - weight 52 6 0.5233104229 ( 3.1009352207 1.9830664396 -1.8149154186 ) - weight 53 7 0.1692353189 ( 3.7135105133 -2.7122011185 1.2472529411 ) - weight 54 5 0.5 ( -2.5818476677 20.652261734 0.7198092341 ) - weight 55 6 0.5 ( -0.4718604386 -0.7988773584 -3.3822419643 ) - weight 56 3 0.1069236025 ( 7.5292000771 5.1090126038 -3.0387847424 ) - weight 57 4 0.055033993 ( -4.3879656792 -6.5620675087 2.3409717083 ) - weight 58 17 0.5240889192 ( 7.4537115097 5.1802768707 -2.4545266628 ) - weight 59 19 0.1887804121 ( 7.5292000771 -4.1088476181 -0.740428865 ) - weight 60 22 0.1251730919 ( 7.5292000771 -11.8313484192 -1.787248373 ) - weight 61 3 0.2396446764 ( 7.9216599464 3.2589836121 1.2398151159 ) - weight 62 4 0.1261993945 ( -0.5354180932 -4.3802709579 3.851167202 ) - weight 63 17 0.5096623302 ( 8.0911417007 2.3610069752 1.2235774994 ) - weight 64 19 0.0713101402 ( 7.9216599464 -5.5756540298 3.6842184067 ) - weight 65 18 0.0531834662 ( 8.0034170151 0.8318443298 -5.31199646 ) - weight 66 3 0.2767252028 ( 7.8065271378 2.3994979858 -2.7645223141 ) - weight 67 4 0.2168948948 ( -4.2420196533 -3.8324959278 2.1935374737 ) - weight 68 17 0.5063799024 ( 7.7463254929 2.4884467125 -2.8570537567 ) - weight 69 3 0.2621211112 ( 8.6405496597 -0.0342292786 1.0405751467 ) - weight 70 4 0.3809435368 ( -0.99144876 -1.0345871449 3.8375825882 ) - weight 71 17 0.3569353521 ( 8.7974081039 -0.7773231864 0.1970192641 ) - weight 72 3 0.0989223495 ( 7.5270900726 5.537853241 2.3491351604 ) - weight 73 4 0.0575829931 ( 0.6518375874 -6.6106204987 4.2933073044 ) - weight 74 17 0.3998931944 ( 7.7609038353 4.3004517555 2.8694877625 ) - weight 75 19 0.1923786998 ( 7.5270900726 -3.208101511 4.5889468193 ) - weight 76 22 0.1035134494 ( 7.5270900726 -11.402507782 3.6006715298 ) - weight 77 20 0.0805758238 ( 3.502407074 -8.95545578 -3.1930763721 ) - weight 78 18 0.0671336129 ( 7.6088471413 3.1107139587 -4.2026767731 ) - weight 79 3 0.2820416689 ( 4.8764200211 2.6567230225 5.4821052551 ) - weight 80 4 0.1240752786 ( 4.5087399483 -4.0127034187 2.4177827835 ) - weight 81 17 0.387751013 ( 5.2944560051 0.7139340043 5.3586630821 ) - weight 82 19 0.0845782757 ( 4.8764200211 -5.8027129173 7.9630250931 ) - weight 83 18 0.1215537339 ( 4.9581770897 0.2295837402 -1.06970644 ) - weight 84 3 0.1464416832 ( 4.9807500839 2.1081008911 -5.6871747971 ) - weight 85 4 0.120930925 ( -5.9728474617 -4.2296123505 -1.4750263691 ) - weight 86 17 0.5861251354 ( 4.7574305534 2.8695614338 -5.6017003059 ) - weight 87 19 0.1465022862 ( 4.9807500839 -7.3309221268 -3.1148078442 ) - weight 88 3 0.375176847 ( 7.0446190834 -2.6003761292 -4.0200066566 ) - weight 89 4 0.4408628345 ( -5.1675906181 0.8655105233 0.1374388933 ) - weight 90 17 0.1839603484 ( 6.9136018753 -2.072681427 -5.2357439995 ) - weight 91 3 0.2094427347 ( 8.0489702225 -3.8961181641 3.9736251831 ) - weight 92 4 0.5674699545 ( 1.943436265 2.8640480042 3.605142355 ) - weight 93 17 0.1501680017 ( 8.3751783371 -5.23913908 2.1414616108 ) - weight 94 18 0.0729193389 ( 8.1307268143 -6.3232574463 -2.578186512 ) - weight 95 3 0.3470622599 ( 5.1477098465 -2.4127578735 4.9502854347 ) - weight 96 4 0.2832652926 ( 3.8927381039 0.9797498584 1.5505919456 ) - weight 97 17 0.2488396764 ( 5.5347690582 -4.0745296478 3.6068253517 ) - weight 98 18 0.120832786 ( 5.2294669151 -4.8398971558 -1.6015262604 ) - weight 99 3 0.206284374 ( 5.9700078964 -6.2046012878 5.3384180069 ) - weight 100 4 0.7937155962 ( 3.9469256401 4.8738737106 1.7449091673 ) - weight 101 3 0.2200269848 ( 6.8720397949 0.8836936951 4.5903654099 ) - weight 102 4 0.3166716397 ( 2.9589474201 -1.9919536114 3.6161334515 ) - weight 103 17 0.3024932444 ( 7.2355937958 -0.7647639513 3.9562478065 ) - weight 104 19 0.0659813955 ( 6.8720397949 -7.6472587585 7.2305750847 ) - weight 105 18 0.0948267728 ( 6.9537968636 -1.5434455872 -1.9614462852 ) - weight 106 3 0.2185422033 ( 0 -2.5818481445 -7.0576448441 ) - weight 107 10 0.1087745428 ( 5.5038557053 -0.562292695 -7.395067215 ) - weight 108 4 0.0951625928 ( -5.5073075294 -0.5623930097 -7.3924965858 ) - weight 109 17 0.4620711505 ( -0.2937788069 -1.42146492 -7.7820806503 ) - weight 110 19 0.1154495254 ( 0 -12.1231765747 -4.067756176 ) - weight 111 3 0.2082437575 ( 5.176129818 -4.9036064148 -6.1572346687 ) - weight 112 4 0.7098788619 ( -6.5128006935 2.6633388996 -2.7473640442 ) - weight 113 17 0.0818773657 ( 4.9255042076 -3.8198180199 -7.7574191093 ) - weight 114 3 0.2549369335 ( 0 -6.2650184631 -6.3029046059 ) - weight 115 10 0.3233954608 ( 4.8149065971 3.1105694771 -7.8083562851 ) - weight 116 4 0.2400700003 ( -4.8180699348 3.110332489 -7.8065209389 ) - weight 117 17 0.1815975606 ( -0.2504522204 -5.1776771545 -7.938190937 ) - weight 118 3 0.0799444988 ( 1.1937500238 -8.7768783569 2.1950352192 ) - weight 119 4 0.9200555086 ( 2.6918127537 6.3714570999 -4.2126102448 ) - weight 120 3 0.4288753271 ( 0 -7.2666091919 5.427775383 ) - weight 121 10 0.3995797038 ( -6.1456022263 4.9089226723 -3.9038434029 ) - weight 122 17 0.0763886496 ( 0.4229588211 -8.9714450836 3.1868207455 ) - weight 123 18 0.0951563269 ( 0.0817569122 -9.6937484741 -1.1240363121 ) - weight 124 3 0.2210763693 ( 0 -9.5092086792 -2.2535846233 ) - weight 125 10 0.4381532967 ( 1.0444489717 6.5804786682 -6.99279356 ) - weight 126 4 0.2796563208 ( -1.0467895269 6.5798449516 -6.9930768013 ) - weight 127 17 0.0611140542 ( -0.0179970842 -9.3003149033 -4.7962832451 ) - weight 128 3 0.2145216614 ( 2.6130399704 -8.0310783386 -5.003554821 ) - weight 129 4 0.6947645545 ( -4.5385065079 5.3811607361 -5.276611805 ) - weight 130 17 0.0907137543 ( 2.4328689575 -7.1681132317 -7.2502908707 ) - weight 131 3 0.4877370298 ( 0 -4.7597465515 6.4924154282 ) - weight 132 10 0.2625775337 ( -7.1520009041 2.5185716152 -3.0724582672 ) - weight 133 4 0.0545964688 ( 7.1509222984 2.5173203945 -3.0760211945 ) - weight 134 17 0.0868727341 ( 0.4840755165 -6.7945189476 4.8223872185 ) - weight 135 18 0.1082161888 ( 0.0817569122 -7.1868858337 -0.0593962669 ) - weight 136 3 0.0884010941 ( 3.3562099934 -13.1236286163 3.4472453594 ) - weight 137 4 0.9115989208 ( 3.0757451057 11.0990447998 -2.5874919891 ) - weight 138 3 0.0799444988 ( 1.0088499784 -10.5870780945 1.3821251392 ) - weight 139 4 0.9200555086 ( 1.9894014597 8.0630159378 -4.998155117 ) - weight 140 3 0.0662936196 ( 2.4494698048 -16.4921951294 0.7676100731 ) - weight 141 4 0.9337064028 ( 0.8773890138 14.0701951981 -4.9727296829 ) - weight 142 3 0.0882157311 ( 2.123239994 -10.3164672852 -4.2167248726 ) - weight 143 4 0.9117842913 ( -3.6392309666 7.5987606049 -5.8729019165 ) - weight 144 3 0.1049511358 ( 2.9273700714 -15.950920105 -4.2486548424 ) - weight 145 4 0.8950488567 ( -3.9794986248 13.271905899 -6.1800642014 ) - weight 146 3 0.1228495687 ( 5.6060552597 -9.2707214355 -5.7493681908 ) - weight 147 4 0.8771504164 ( -6.3034706116 7.0575084686 -3.0125772953 ) - weight 148 4 1 ( -6.1815371513 12.4698343277 0.3328567743 ) - weight 149 3 0.1095804423 ( 10.4930238724 -9.5163421631 0.3507947028 ) - weight 150 4 0.8904195428 ( -2.3358850479 8.5535488129 3.5581846237 ) - weight 151 4 1 ( -3.917453289 14.6396093369 2.2394332886 ) - weight 152 3 0.1663484424 ( 8.5809659958 -7.2308349609 -3.2218973637 ) - weight 153 4 0.8336515427 ( -4.9872536659 5.7339248657 0.9767885804 ) - weight 154 3 0.2347732633 ( 9.3699684143 -5.0844078064 -0.0834435076 ) - weight 155 4 0.6872122884 ( -2.3235960007 3.9758450985 3.1889481544 ) - weight 156 17 0.0780144259 ( 9.461098671 -5.3982696533 -2.149497509 ) - weight 157 3 0.1630153507 ( 3.3091499805 -8.0478057861 4.5056352615 ) - weight 158 4 0.8369846344 ( 4.1044864655 6.1750159264 -1.3297125101 ) - weight 159 4 1 ( 2.0208208561 17.0193157196 -1.7541565895 ) - weight 160 3 0.0671593621 ( 7.8446297646 -21.3117198944 -5.241314888 ) - weight 161 4 0.7200645804 ( -6.6764502525 19.3096656799 -2.9902544022 ) - weight 162 5 0.21277605 ( -2.0252971649 0.0139190787 4.038459301 ) - weight 163 3 0.0609805807 ( 6.9160900116 -15.648229599 4.1621651649 ) - weight 164 4 0.9390194416 ( 2.4695301056 14.2361764908 0.4700190425 ) - weight 165 4 0.9282485247 ( -1.5941865444 17.5156898499 -5.0876231194 ) - weight 166 5 0.0717514902 ( -3.583676815 -2.5219893456 -0.9201021194 ) - weight 167 4 0.6559420824 ( -0.7508656979 19.7827892303 0.8460713029 ) - weight 168 5 0.3440578878 ( 2.7071833611 -1.3105490208 -1.0510600805 ) - weight 169 3 0.5260931849 ( 0 -2.3752593994 5.7769050598 ) - weight 170 10 0.1452362388 ( -6.4938931465 0.1250177622 -2.8839716911 ) - weight 171 17 0.1640932709 ( 0.4430009425 -4.3081684113 4.7036094666 ) - weight 172 18 0.1645772755 ( 0.0817569122 -4.8023986816 -0.7749066353 ) - weight 173 4 0.5014052391 ( -2.1492013931 20.8788642883 -5.5200419426 ) - weight 174 5 0.4985947609 ( -3.5182363987 0.9090329409 -1.0926314592 ) - weight 175 4 0.740267396 ( -4.2334899902 20.033618927 -5.3216814995 ) - weight 176 5 0.2597326636 ( -3.7921729088 0.5087782741 1.1125438213 ) - weight 177 4 0.3635103106 ( -5.4528450966 22.8845691681 -5.2548179626 ) - weight 178 5 0.6364896297 ( -3.4310176373 3.5183131695 1.7694147825 ) - weight 179 4 0.2838164866 ( -7.1263494492 21.893579483 -3.203895092 ) - weight 180 5 0.7161834836 ( -1.8632599115 2.6389324665 3.9506502151 ) - weight 181 5 1 ( -4.1741204262 5.6770710945 2.53515625 ) - weight 182 5 1 ( -1.9457143545 5.4498543739 4.9774689674 ) - weight 183 4 0.3121370077 ( -4.4071116447 21.7299919128 1.1965153217 ) - weight 184 5 0.6878629327 ( 2.8127121925 1.305783987 2.1779036522 ) - weight 185 4 0.0533990003 ( -3.1070792675 24.6861858368 0.271330595 ) - weight 186 5 0.9466010332 ( 2.6169657707 4.0141019821 0.2000684142 ) - weight 187 4 0.0613344088 ( -6.7894105911 24.7612800598 0.0435621142 ) - weight 188 5 0.9386655688 ( 1.837200284 4.902736187 3.6956906319 ) - weight 189 4 0.2215298414 ( -7.4662833214 22.7176418304 -0.8179263473 ) - weight 190 5 0.7784701586 ( 0.546154201 3.1861352921 4.5693378448 ) - weight 191 4 0.6404342651 ( -6.2111821175 19.7123451233 -0.6909929514 ) - weight 192 5 0.3595657051 ( 0.3528687954 -0.0065741558 3.9428799152 ) - weight 193 4 0.8282259107 ( 0.7223988771 19.3566360474 -2.3801381588 ) - weight 194 5 0.1717740893 ( -0.2764886916 -1.6007701159 -2.9937427044 ) - weight 195 4 0.6559420824 ( -1.144947052 21.2384357452 0.2804422975 ) - weight 196 5 0.3440578878 ( 2.3433480263 0.2584503591 -1.047824502 ) - weight 197 4 0.3121370077 ( -3.7774112225 20.3179531097 1.7202266455 ) - weight 198 5 0.6878629327 ( 3.1797053814 -0.26559183 1.9314409494 ) - weight 199 3 0.0721886456 ( 9.0645103455 -13.3509693146 3.1552453041 ) - weight 200 4 0.9278113842 ( 0.7759150267 12.2740039825 2.5166134834 ) - weight 201 5 1 ( -3.6398761272 10.0534420013 1.8198467493 ) - weight 202 5 1 ( -2.7982206345 10.4494514465 4.7135415077 ) - weight 203 5 1 ( -4.2860569954 13.5659074783 1.7814621925 ) - weight 204 5 1 ( -3.0162653923 10.52094841 -1.1173174381 ) - weight 205 4 0.0812822282 ( -3.5907011032 26.3055477142 -5.7982292175 ) - weight 206 5 0.918717742 ( -3.0890066624 6.5048732758 -0.7662224174 ) - weight 207 5 1 ( 2.0402960777 8.7431297302 4.251139164 ) - weight 208 5 1 ( 1.801984787 15.6448259354 3.10176301 ) - weight 209 5 1 ( 2.0115163326 11.7242155075 1.4887131453 ) - weight 210 5 1 ( 2.9223980904 15.0317459106 -1.369388938 ) - weight 211 5 1 ( -0.7952164412 12.6624107361 3.927521944 ) - weight 212 5 1 ( -2.0613574982 16.8246326447 4.3019156456 ) - weight 213 5 0.9168231487 ( -4.2305979729 17.2965717316 0.732529223 ) - weight 214 6 0.0831768736 ( 1.4446171522 -3.6887888908 -1.9841297865 ) - weight 215 5 0.8543199301 ( -2.0448555946 16.9572963715 -2.4853451252 ) - weight 216 6 0.1456800848 ( 3.4254362583 -0.7313295603 -0.3788008988 ) - weight 217 5 1 ( 0.6453074217 15.0546197891 -3.2220330238 ) - weight 218 5 1 ( 0.44538185 10.1214313507 -1.5377562046 ) - weight 219 5 1 ( 2.0674369335 10.2083835602 -0.3427814245 ) - weight 220 5 1 ( 1.1055467129 6.0715780258 -1.8681554794 ) - weight 221 5 0.5 ( -1.6463179588 20.7951831818 3.617836237 ) - weight 222 6 0.5 ( -3.3181433678 -1.7031702995 -2.7697622776 ) - weight 223 25 1 ( 0.9275852442 7.2957701683 -3.3785088062 ) - weight 224 25 1 ( -2.7143802643 7.1327629089 -3.1395363808 ) - weight 225 25 0.8784247637 ( -2.3203058243 10.7307872772 -2.6311776638 ) - weight 226 26 0.1215752512 ( -0.7492275238 -1.5532993078 -3.6283137798 ) - weight 227 25 0.8984447718 ( 1.7512421608 9.9629249573 -2.1052036285 ) - weight 228 26 0.1015552133 ( 2.8900485039 -1.0475037098 -1.6424628496 ) - weight 229 17 0.449130863 ( -0.2770932019 5.6961083412 -5.7161598206 ) - weight 230 19 0.4540952146 ( 0 -4.7206392288 -4.4291324615 ) - weight 231 22 0.096773915 ( 0 -12.116558075 -5.5154485703 ) - weight 232 17 0.5152887702 ( 3.7515227795 5.7953419685 -5.1341805458 ) - weight 233 19 0.3591423929 ( 3.9909200668 -4.4172315598 -3.6816065311 ) - weight 234 22 0.125568822 ( 3.9909200668 -11.880027771 -4.7441482544 ) - weight 235 3 0.0887620747 ( 0 2.2120819092 -6.3957047462 ) - weight 236 17 0.6063475609 ( -0.2557795048 3.0720183849 -5.985669136 ) - weight 237 19 0.3048903346 ( 0 -7.289618969 -3.8297348022 ) - weight 238 17 0.1273706257 ( 7.1239795685 10.8273582458 -1.9103651047 ) - weight 239 19 0.4415688813 ( 7.2477998734 1.4065550566 -2.0803947449 ) - weight 240 22 0.363877058 ( 7.2477998734 -6.2195167542 -2.6372585297 ) - weight 241 24 0.0671834275 ( 0.3733787537 -2.9420530796 -8.4418182373 ) - weight 242 17 0.3153382242 ( 8.0714769363 7.9519610405 0.2049596161 ) - weight 243 19 0.3789919317 ( 8.0361099243 -0.61992836 0.9049345851 ) - weight 244 22 0.2489299327 ( 8.0361099243 -8.5005493164 0.1584016085 ) - weight 245 20 0.0567399301 ( 4.0114269257 -6.0534973145 -6.6353464127 ) - weight 246 17 0.316473484 ( 5.8579230309 7.9936280251 -2.7965316772 ) - weight 247 19 0.4292660952 ( 5.9940099716 -1.5676822662 -2.0686321259 ) - weight 248 22 0.2542604208 ( 5.9940099716 -9.1832771301 -2.8869585991 ) - weight 249 17 0.1202539653 ( 3.6167609692 12.4521036148 -4.3350858688 ) - weight 250 19 0.4247384965 ( 3.9039299488 2.1368479729 -5.0978207588 ) - weight 251 22 0.3653951585 ( 3.9039299488 -5.2268371582 -5.5788183212 ) - weight 252 24 0.089612402 ( 3.7172486782 -5.8836126328 -7.4491386414 ) - weight 253 25 1 ( 2.712013483 7.632484436 -1.6183480024 ) - weight 254 25 0.8327695727 ( 3.1037318707 9.9404001236 1.0208822489 ) - weight 255 26 0.1672303826 ( 2.9835219383 -0.9043157697 1.7594350576 ) - weight 256 22 0.0771214515 ( 10.5706396103 -2.2360191345 2.5162315369 ) - weight 257 25 0.9228785634 ( 1.9276038408 4.9491381645 -2.2725217342 ) - weight 258 25 1 ( -2.4587037563 5.8695721626 -2.9298191071 ) - weight 259 25 1 ( -4.010948658 6.6789679527 -0.6567108631 ) - weight 260 19 0.0508285165 ( 8.6673402786 8.395565033 4.8748426437 ) - weight 261 22 0.3103339374 ( 8.6673402786 0.1311225891 4.9053516388 ) - weight 262 23 0.0798272043 ( 4.5237116814 6.4591140747 -1.8480153084 ) - weight 263 24 0.1801317483 ( -1.0461616516 4.6005573273 -2.091178894 ) - weight 264 25 0.2787561417 ( 4.3732790947 1.9897115231 -1.8317598104 ) - weight 265 20 0.1001224369 ( 4.64265728 2.5781745911 -1.8883962631 ) - weight 266 19 0.189502582 ( 7.2366700172 5.6184434891 5.9579463005 ) - weight 267 22 0.4047628939 ( 7.2366700172 -2.7304496765 5.7401714325 ) - weight 268 24 0.1485210061 ( 0.3845086098 5.435377121 -4.9527511597 ) - weight 269 20 0.2572135329 ( 3.2119870186 -0.2833976746 -1.0535764694 ) - weight 270 19 0.2537808418 ( 9.0340995789 3.8217997551 3.0478274822 ) - weight 271 22 0.4020117223 ( 9.0340995789 -4.2643585205 2.6834015846 ) - weight 272 24 0.076381281 ( -1.4129209518 2.3786070347 -6.4866600037 ) - weight 273 25 0.0616703294 ( 1.6802309752 4.8661475182 -4.8092479706 ) - weight 274 20 0.2061558366 ( 5.0094165802 -1.8173065186 -4.1103463173 ) - weight 275 22 0.2104583681 ( 8.9566698074 5.3679389954 1.8660715818 ) - weight 276 23 0.0883276537 ( 1.4721133709 5.7074985504 3.3354201317 ) - weight 277 24 0.2880037725 ( -1.3354911804 1.5612771511 3.1456375122 ) - weight 278 25 0.4132102728 ( 2.0479469299 -0.7543227673 3.0476136208 ) - weight 279 22 0.2019269764 ( 10.2034502029 2.9910697937 3.9270217419 ) - weight 280 23 0.115218088 ( 3.4485721588 7.4492001534 1.211374402 ) - weight 281 24 0.2169577181 ( -2.5822715759 3.6222271919 0.7687683105 ) - weight 282 25 0.4658972621 ( 3.9222977161 1.6043533087 1.5065294504 ) - weight 283 22 0.1066465601 ( 11.6929721832 2.5999641418 1.9945477247 ) - weight 284 24 0.082949616 ( -4.0717935562 1.689753294 0.3776626587 ) - weight 285 25 0.8104037642 ( 2.1257953644 3.0762648582 2.3504195213 ) - weight 286 19 0.0934283361 ( 9.1123199463 4.7844085693 1.4842790365 ) - weight 287 22 0.3328987956 ( 9.1123199463 -3.1680488586 1.2105116844 ) - weight 288 25 0.504265368 ( 0.3697837889 4.3194146156 -3.6425309181 ) - weight 289 20 0.0694075301 ( 5.0876369476 -0.7209968567 -5.5832362175 ) - weight 290 19 0.3896191418 ( 8.652299881 3.1292157173 0.7079356313 ) - weight 291 22 0.4093904197 ( 8.652299881 -4.7486000061 0.2916916609 ) - weight 292 25 0.0671922043 ( -0.7797638774 4.8728508949 -5.0304207802 ) - weight 293 20 0.1337981522 ( 4.6276168823 -2.3015480042 -6.5020561218 ) - weight 294 19 0.1736020893 ( 8.3155002594 4.2229170799 -1.6327527761 ) - weight 295 22 0.331809938 ( 8.3155002594 -3.4533996582 -1.9438083172 ) - weight 296 24 0.1214219555 ( -0.6943216324 -2.2486028671 -5.6757011414 ) - weight 297 25 0.3731659949 ( -2.8624002934 3.8847255707 -3.8160603046 ) - weight 298 25 0.4205686748 ( 1.4400048256 11.4228773117 3.0691380501 ) - weight 299 26 0.5794312954 ( 0.3222328722 -0.1931181401 3.0135536194 ) - weight 300 25 0.88492769 ( -0.1448078603 10.4199743271 2.6888926029 ) - weight 301 26 0.1150723174 ( -0.6133205891 -1.6069338322 2.1259191036 ) - weight 302 25 0.8383777142 ( -3.9867646694 10.588809967 -0.4868829846 ) - weight 303 26 0.1616222858 ( -2.9237706661 -2.3876690865 -2.224593401 ) - weight 304 25 0.2587660253 ( -4.1667289734 12.4313373566 -0.6045203805 ) - weight 305 26 0.7412339449 ( -3.6336395741 -0.6912592053 -2.4683389664 ) - weight 306 25 0.4776410162 ( -0.1146772653 11.5581302643 -3.0020635128 ) - weight 307 26 0.5223590136 ( 1.0531570911 -0.0487227812 -3.2105703354 ) - weight 308 25 0.3601590693 ( -2.5787878036 12.179060936 -2.3499720097 ) - weight 309 26 0.6398409009 ( -1.5417722464 -0.2875441611 -3.5137608051 ) - weight 310 25 0.5487061739 ( 3.0538058281 11.579331398 -1.5442295074 ) - weight 311 26 0.4512938261 ( 3.3163597584 0.8432571292 -0.7111103535 ) - weight 312 25 1 ( 0.443833679 8.7419500351 3.0878815651 ) - weight 313 25 0.8383777142 ( -3.2075200081 10.664648056 1.8308862448 ) - weight 314 26 0.1616222858 ( -3.0806663036 -2.2640073299 0.2136681527 ) - weight 315 25 1 ( -2.4460561275 7.2530703545 2.0786616802 ) - weight 316 17 0.1560927927 ( 8.1256017685 9.4902143478 3.4665868282 ) - weight 317 19 0.3652572036 ( 7.9296998978 1.8955587149 3.4872529507 ) - weight 318 22 0.3252667487 ( 7.9296998978 -6.2217674255 2.9518215656 ) - weight 319 20 0.1533832401 ( 3.9050168991 -3.7747154236 -3.8419263363 ) - weight 320 17 0.2015561014 ( 6.5957527161 9.4027004242 7.7644276619 ) - weight 321 19 0.2642347813 ( 6.1617097855 3.202600956 7.4854254723 ) - weight 322 22 0.3287962675 ( 6.1617097855 -5.2711982727 7.0494017601 ) - weight 323 20 0.2054128349 ( 2.1370267868 -2.8241462708 0.2556538582 ) - weight 324 19 0.0948961601 ( 3.5566899776 8.5650749207 7.0386481285 ) - weight 325 22 0.4634767175 ( 3.5566899776 0.109790802 7.0756816864 ) - weight 326 23 0.0722427592 ( 7.0183763504 1.5669150352 -2.6681184769 ) - weight 327 24 0.1664817035 ( 4.0644884109 6.7708873749 -2.1125106812 ) - weight 328 20 0.2029026896 ( -0.467993021 2.556842804 0.2819337845 ) - weight 329 17 0.1906848699 ( 4.3153686523 8.8220100403 8.6066560745 ) - weight 330 19 0.2058832794 ( 3.8301301003 2.9158346653 8.3387737274 ) - weight 331 22 0.2979409397 ( 3.8301301003 -5.6318588257 7.8742418289 ) - weight 332 20 0.1714980751 ( -0.1945528984 -3.1848068237 1.080493927 ) - weight 333 18 0.133992821 ( 3.9118869305 8.881362915 0.0708937645 ) - weight 334 17 0.0863279849 ( -0.2875749469 17.6150417328 -2.9451155663 ) - weight 335 19 0.2839872241 ( 0 7.451417923 -5.6864366531 ) - weight 336 22 0.4494484961 ( 0 0.1189002991 -5.698038578 ) - weight 337 39 0.0605599955 ( 5.5000338554 -2.7487328053 -3.3631818295 ) - weight 338 40 0.1196763366 ( -7.6211800575 -6.0028300285 -2.1034240723 ) - weight 339 19 0.1344032288 ( 4.1019601822 8.4969930649 -5.6311721802 ) - weight 340 22 0.4274182618 ( 4.1019601822 1.1555709839 -5.5510883331 ) - weight 341 23 0.1332542896 ( -5.6173138618 1.1336624622 -1.6792143583 ) - weight 342 24 0.2516222596 ( 3.5192184448 -5.8558826447 -1.0667304993 ) - weight 343 25 0.0533020496 ( -6.303914547 -2.160040617 -1.9119106531 ) - weight 344 17 0.1166878492 ( 0.5271523595 8.5231132507 9.3968696594 ) - weight 345 19 0.2024046481 ( 0 2.8710224628 8.9652366638 ) - weight 346 22 0.3595457375 ( 0 -5.7315597534 8.4943418503 ) - weight 347 21 0.1797282845 ( 4.2523598671 -3.4128341675 1.7005939484 ) - weight 348 20 0.0608123504 ( -4.0246829987 -3.2845077515 1.7005939484 ) - weight 349 18 0.0808211118 ( 0.0817569122 8.7816619873 0.6909937859 ) - weight 350 19 0.1979081333 ( 6.7445898056 5.6682634354 -4.2771639824 ) - weight 351 22 0.3774667084 ( 6.7445898056 -1.7812194824 -4.4509482384 ) - weight 352 23 0.0570001341 ( -4.6894865036 4.2793111801 -4.1414427757 ) - weight 353 24 0.1939489841 ( 0.8765888214 -4.7557425499 -4.0035209656 ) - weight 354 25 0.1736759692 ( -5.297978878 1.6762918234 -2.9555516243 ) - weight 355 19 0.1394121796 ( 0 8.4040679932 7.1718149185 ) - weight 356 22 0.5321753025 ( 0 -0.062297821 7.1941814423 ) - weight 357 21 0.2532346845 ( 4.2523598671 2.2564277649 0.4004335403 ) - weight 358 20 0.0751778483 ( -4.0246829987 2.3847541809 0.4004335403 ) - weight 359 22 0.8149345517 ( 0 4.1182136536 4.7094516754 ) - weight 360 39 0.0842731968 ( -4.8858919144 -2.7320172787 0.6917703748 ) - weight 361 40 0.1007922292 ( -7.6211800575 4.4046597481 1.8958892822 ) - weight 362 22 0.8149345517 ( 1.8106399775 4.6890602112 4.1403317451 ) - weight 363 23 0.0842731968 ( 4.2014536858 -1.0768156052 1.5402439833 ) - weight 364 24 0.1007922292 ( 5.8105387688 3.8355374336 2.466758728 ) - weight 365 22 0.1055573449 ( 11.1468296051 0.6763305664 4.0388617516 ) - weight 366 24 0.0612346157 ( -3.5256509781 3.7340672016 -1.5459709167 ) - weight 367 25 0.8332080245 ( 3.848783493 3.7106661797 0.1579997689 ) - weight 368 22 0.2346942276 ( 8.8396902084 -0.3195800781 -4.1728482246 ) - weight 369 24 0.2036777884 ( -1.2185115814 -4.4776425362 -2.5418815613 ) - weight 370 25 0.561627984 ( -4.6214380264 2.5355131626 -0.6302115917 ) - weight 371 22 0.7616530061 ( 0 6.7909126282 -1.6510283947 ) - weight 372 39 0.0707426295 ( 1.4614092112 -3.5664117336 3.2636539936 ) - weight 373 40 0.0967006236 ( -7.6211800575 -1.9558200836 4.5685882568 ) - weight 374 23 0.0709036738 ( -1.461405158 -3.5664477348 3.2635588646 ) - weight 375 22 0.7280092239 ( 2.5946099758 6.8535728455 -0.7384383678 ) - weight 376 23 0.0894822627 ( -0.7176495194 -0.963170588 3.7519469261 ) - weight 377 24 0.1825084984 ( 5.0265684128 -1.0432327986 4.6312713623 ) - weight 378 22 0.4795843363 ( 3.6837999821 4.6725578308 -3.5961685181 ) - weight 379 23 0.1561301053 ( -3.6395392418 0.2794250846 1.744884491 ) - weight 380 24 0.3642855883 ( 3.9373786449 -3.9009628296 2.4502563477 ) - weight 381 3 0.2082437575 ( 5.6810097694 -6.2914772034 -5.7304348946 ) - weight 382 4 0.7098788619 ( -6.2991318703 4.1430869102 -2.3896796703 ) - weight 383 17 0.0818773657 ( 5.4540524483 -5.2624826431 -7.7063932419 ) - weight 384 22 0.4028716385 ( 7.2713699341 0.9188499451 5.3783316612 ) - weight 385 23 0.1384224147 ( 5.0855317116 4.9873733521 -1.2900773287 ) - weight 386 24 0.3638387024 ( 0.3498086929 5.0735373497 -1.3034515381 ) - weight 387 20 0.0948672518 ( 3.2466869354 3.365901947 -1.4154162407 ) - weight 388 3 0.0863266289 ( 4.6218099594 5.7357635498 6.0177950859 ) - weight 389 17 0.3341448307 ( 5.0710177422 3.5698933601 6.6337518692 ) - weight 390 19 0.1688850224 ( 4.6218099594 -2.6885046959 8.2260131836 ) - weight 391 22 0.1109910384 ( 4.6218099594 -11.2045974731 7.2693314552 ) - weight 392 20 0.1000070646 ( 0.5971269608 -8.7575454712 0.4755835533 ) - weight 393 18 0.1996454149 ( 4.703567028 3.3086242676 -0.5340166092 ) - weight 394 3 0.3293448985 ( 0 2.1261405945 6.6738853455 ) - weight 395 17 0.1964480728 ( 0.4944929779 -0.1551338881 6.6572794914 ) - weight 396 19 0.0816393122 ( 0 -6.2264919281 9.1968278885 ) - weight 397 22 0.0585389286 ( 0 -14.8142204285 7.9254217148 ) - weight 398 18 0.3340287805 ( 0.0817569122 -0.3009986877 0.1220736504 ) - weight 399 17 0.2491469532 ( 0.4801656008 3.2712416649 7.2511429787 ) - weight 400 19 0.2161560208 ( 0 -2.7933306694 8.6433525085 ) - weight 401 22 0.1518869698 ( 0 -11.3456993103 7.6758418083 ) - weight 402 21 0.0964680836 ( 4.2523598671 -9.0269737244 0.8820939064 ) - weight 403 18 0.2863419354 ( 0.0817569122 3.1675224304 -0.1275062561 ) - weight 404 3 0.1723360568 ( 8.5654697418 -6.0981559753 3.1811532974 ) - weight 405 4 0.8276639581 ( 1.0094703436 5.0615859032 3.3994979858 ) - weight 406 22 0.2993527055 ( 8.5918798447 3.382183075 4.2053413391 ) - weight 407 23 0.1691163778 ( 3.8300075531 5.8166432381 1.3412022591 ) - weight 408 24 0.4106554091 ( -0.9707012177 3.9005470276 1.1598815918 ) - weight 409 25 0.1208755374 ( 4.0736279488 0.0592301488 0.8605539799 ) - weight 410 22 0.3157365322 ( 7.269780159 5.4760780334 2.5088114738 ) - weight 411 23 0.1305618137 ( 2.2220599651 4.0694847107 3.1776385307 ) - weight 412 24 0.4652858675 ( 0.351398468 2.2040171623 3.2537765503 ) - weight 413 25 0.0884157941 ( 2.5161170959 -2.2030422688 2.0716865063 ) - weight 414 22 0.3791531324 ( 6.9991698265 4.0735282898 3.9729616642 ) - weight 415 23 0.1587525159 ( 3.7005879879 4.1218686104 1.7650798559 ) - weight 416 24 0.4620943964 ( 0.6220088005 3.6681673527 1.8512268066 ) - weight 417 5 0.6010227203 ( -3.4498386383 20.4180221558 0.1943686754 ) - weight 418 6 0.3989772201 ( 0.3946889639 -1.1931943893 -3.8041069508 ) - weight 419 5 0.1546468437 ( -0.6949374676 22.9932975769 -2.6968610287 ) - weight 420 6 0.4815303087 ( 0.7621283531 3.5413177013 -3.9776346684 ) - weight 421 7 0.3638228774 ( 2.0435094833 -3.3795995712 -1.8090840578 ) - weight 422 5 0.1531316042 ( 2.0245609283 23.5965881348 0.8108910918 ) - weight 423 6 0.4677073956 ( -3.4629607201 3.6919410229 -2.4978067875 ) - weight 424 7 0.3791610003 ( -2.4314396381 -3.4236733913 -1.6171352863 ) - weight 425 3 0.2347732633 ( 9.1127099991 -3.1918373108 0.2019149363 ) - weight 426 4 0.6872122884 ( -1.9571065903 2.0914943218 3.3995251656 ) - weight 427 17 0.0780144259 ( 9.2206459045 -3.6336505413 -1.4026806355 ) - weight 428 3 0.2305311114 ( 4.4013199806 -2.2253265381 -6.4352645874 ) - weight 429 4 0.3362547457 ( -6.4858551025 -0.120478034 -3.0643055439 ) - weight 430 17 0.433214128 ( 4.1360116005 -1.1642773151 -7.3383512497 ) - weight 431 3 0.1663484424 ( 7.9021692276 -5.2774772644 -3.180637598 ) - weight 432 4 0.8336515427 ( -4.6991004944 3.7011501789 0.7260549664 ) - weight 433 22 0.3324160576 ( 6.5781202316 1.6232719421 -4.6563382149 ) - weight 434 23 0.1443967223 ( -4.8837399483 3.553899765 -0.810301125 ) - weight 435 24 0.2850297987 ( 1.0430583954 -4.9611325264 -0.599029541 ) - weight 436 25 0.2381574363 ( -5.1004142761 -0.4250291288 -0.2711749673 ) - weight 437 22 0.2266537994 ( 8.715880394 3.7594718933 -3.1219182014 ) - weight 438 24 0.2749993503 ( -1.094701767 -3.4267127514 1.5371704102 ) - weight 439 25 0.4983468354 ( -3.096886158 0.0588836893 2.4194600582 ) - weight 440 22 0.3057387173 ( 6.6514701843 4.0911598206 -3.5549983978 ) - weight 441 23 0.1308492124 ( -3.7894015312 3.2985389233 1.648563385 ) - weight 442 24 0.3803289235 ( 0.9697084427 -3.8597927094 1.8688583374 ) - weight 443 25 0.183083117 ( -3.7029452324 -1.809912324 1.5830038786 ) - weight 444 22 0.2374293655 ( 8.3510599136 5.5010185242 -1.598618269 ) - weight 445 23 0.0753508359 ( -1.9464309216 4.8695836067 3.3334989548 ) - weight 446 24 0.3531977534 ( -0.7298812866 -1.9034126997 3.278717041 ) - weight 447 25 0.3340220451 ( -1.418797493 -1.2700814009 3.3704550266 ) - weight 448 22 0.3466660976 ( 6.7255301476 5.7394523621 -0.8456683159 ) - weight 449 23 0.1131498292 ( -1.0904506445 3.2780127525 3.3153164387 ) - weight 450 24 0.4739112258 ( 0.8956484795 -1.1504627466 3.5171508789 ) - weight 451 25 0.0662728474 ( -0.8193630576 -2.7458558083 2.5166988373 ) - weight 452 17 0.3154843152 ( 3.2073581219 8.2088813782 -4.1278982162 ) - weight 453 19 0.464012742 ( 3.4249699116 -1.8104203939 -3.5469682217 ) - weight 454 22 0.2205028981 ( 3.4249699116 -9.2951393127 -4.3809084892 ) - weight 455 17 0.2327790856 ( -0.226689592 8.1117658615 -4.2132954597 ) - weight 456 19 0.5544282198 ( 0 -1.9473525286 -3.7924025059 ) - weight 457 22 0.2127926946 ( 0 -9.4099693298 -4.6374282837 ) - weight 458 17 0.1374716908 ( -0.2365594208 11.5200738907 -3.5440423489 ) - weight 459 19 0.5412513018 ( 0 1.4932602644 -4.2685842514 ) - weight 460 22 0.3212770224 ( 0 -5.9408187866 -4.8093585968 ) - weight 461 26 1 ( 1.4142169952 10.4120969772 2.8854954243 ) - weight 462 26 1 ( 2.2627801895 5.51841259 0.2142424136 ) - weight 463 26 0.3331983984 ( 3.0434458256 10.0306482315 0.1456521749 ) - weight 464 36 0.3078258038 ( -0.9099646211 1.8968099356 -0.1852007806 ) - weight 465 37 0.3589757979 ( -0.8482078314 1.533490777 1.5495654345 ) - weight 466 26 1 ( 0.9834482074 6.7014627457 2.6421263218 ) - weight 467 26 1 ( -1.2640975714 10.7678928375 3.1602845192 ) - weight 468 26 1 ( -2.1119251251 7.6590094566 1.8955845833 ) - weight 469 26 1 ( -3.2091207504 11.0667295456 1.0070046186 ) - weight 470 26 1 ( -3.3371822834 2.1001322269 0.5224716067 ) - weight 471 26 1 ( -3.4709730148 7.1876959801 -0.8652487993 ) - weight 472 26 1 ( -3.3170304298 11.1045560837 -1.0486624241 ) - weight 473 26 1 ( -1.4335671663 6.7024683952 -2.7854459286 ) - weight 474 26 1 ( -3.2083516121 1.9957014322 -2.0983309746 ) - weight 475 26 1 ( 1.8206892014 10.2446804047 -1.8300275803 ) - weight 476 26 1 ( 1.484651804 6.0889515877 -2.227080822 ) - weight 477 26 1 ( -1.0843970776 10.6558227539 -2.6841449738 ) - weight 478 37 0.5 ( -1.0091346502 -0.3506052792 0.3158343434 ) - weight 479 38 0.5 ( -0.9653936028 -0.4461877644 1.8302928209 ) - weight 480 37 0.5 ( 0.0332228728 -0.7310032248 -0.3986127973 ) - weight 481 38 0.5 ( -0.0052703591 -0.8234678507 1.0072073936 ) - weight 482 32 1 ( 0.3017202914 0.1539534479 -0.7368940115 ) - weight 483 26 0.3331983984 ( 2.4964060783 11.5712203979 -1.2105666399 ) - weight 484 36 0.3078258038 ( 0.0385772921 0.6906418204 -1.6539998055 ) - weight 485 37 0.3589757979 ( 0.1003341079 0.5448454022 -0.0736389756 ) - weight 486 26 0.2839439809 ( 0.6076005101 12.1952381134 -0.728942275 ) - weight 487 36 0.4689332843 ( 0.6791445017 -1.0267057419 -0.743319869 ) - weight 488 37 0.2471227348 ( 0.7409012914 -1.2830889225 0.5876302123 ) - weight 489 32 0.4101817906 ( 0.6515015364 -0.7548061609 -0.5771866441 ) - weight 490 33 0.5898182392 ( -1.4182274342 0.2859310508 -0.5838063359 ) - weight 491 26 0.8549714684 ( 0.7184249163 10.4335622787 -0.7542367578 ) - weight 492 36 0.1450285167 ( 1.0854455233 0.4008005261 0.2124883533 ) - weight 493 26 1 ( -1.5944448709 10.5482110977 -0.780995667 ) - weight 494 32 0.8064539433 ( 0.8528350592 0.2682539523 0.4677162766 ) - weight 495 33 0.1935460418 ( -0.5352481604 0.8404892087 0.4610965848 ) - weight 496 32 0.4101817906 ( 1.7004761696 0.1182702929 -0.6270506978 ) - weight 497 33 0.5898182392 ( -0.0635229647 0.1204435527 -0.6336703897 ) - weight 498 32 0.8064539433 ( 1.7762019634 0.1405121684 0.1118120328 ) - weight 499 33 0.1935460418 ( 0.0045734025 0.0805437341 0.1051923409 ) - weight 500 33 0.5 ( 1.7717843056 0.0705038235 -0.7417898774 ) - weight 501 34 0.5 ( -0.0309342127 0.2819591165 0.6582369804 ) - weight 502 33 0.5 ( 2.0596888065 -0.3555833697 -0.7964020371 ) - weight 503 34 0.5 ( 0.4599120617 0.1286318153 0.7128491402 ) - weight 504 33 0.5 ( 1.8194402456 0.0818448663 -0.0653548837 ) - weight 505 34 0.5 ( -0.0281031765 0.2330542058 -0.0181980524 ) - weight 506 29 0.2609394193 ( 3.4309368134 0.6753624678 -0.8879337907 ) - weight 507 30 0.6099424958 ( 1.5632354021 -0.9322100282 -0.9845014811 ) - weight 508 31 0.12911807 ( 0.8138022423 0.7212357521 0.950912118 ) - weight 509 29 0.2609394193 ( 2.0289063454 0.6525265574 -1.5188808441 ) - weight 510 30 0.6099424958 ( 0.4959153235 0.0200381149 -1.5487322807 ) - weight 511 31 0.12911807 ( -0.4049782157 1.4699165821 1.5151429176 ) - weight 512 30 0.5 ( 2.4539115429 -0.0022552877 -1.3609032631 ) - weight 513 31 0.5 ( 0.1790011078 -0.3990978897 1.3273139 ) - weight 514 26 1 ( -2.256975174 10.8294582367 0.3255695701 ) - weight 515 26 0.2443206161 ( -1.5937421322 14.4684305191 0.0114921983 ) - weight 516 29 0.5839904547 ( 0.130099684 0.8935907483 1.015707612 ) - weight 517 30 0.1716888845 ( -0.5393765569 1.5135895014 1.0561078787 ) - weight 518 29 0.0691876858 ( 2.7896294594 1.3589675426 0.7738748193 ) - weight 519 30 0.4924322069 ( 1.6821824312 0.0087606357 0.6709818244 ) - weight 520 31 0.4383800626 ( -0.0533050038 0.3369191885 -0.7045711875 ) - weight 521 30 0.5 ( 2.566161871 -0.2897028327 -0.4935825169 ) - weight 522 31 0.5 ( 0.4865807891 -0.4240167439 0.4599931836 ) - weight 523 29 0.2834812105 ( 2.3106944561 0.6775743961 1.0197726488 ) - weight 524 30 0.5160946846 ( 0.8828514218 -0.1512182653 0.9703441262 ) - weight 525 31 0.2004240751 ( -0.1297591031 1.1485091448 -1.0039334297 ) - weight 526 29 0.2834812105 ( 1.535684824 -0.0638165399 0.9168609977 ) - weight 527 30 0.5160946846 ( -0.1941106617 -0.1504181623 0.9380452037 ) - weight 528 31 0.2004240751 ( -0.4399882555 2.1798217297 -0.9716345668 ) - weight 529 29 0.2609394193 ( 2.0918910503 -0.4460756183 -1.3169000149 ) - weight 530 30 0.6099424958 ( -0.2038748562 -0.8162207007 -1.2984223366 ) - weight 531 31 0.12911807 ( 0.1949292421 2.3804912567 1.2648329735 ) - weight 532 26 0.2443206161 ( -1.5851364136 14.2736988068 1.0361591578 ) - weight 533 29 0.5839904547 ( 0.1833594888 -0.1475297064 0.9815279245 ) - weight 534 30 0.1716888845 ( -1.2219905853 0.7250332832 1.068510294 ) - weight 535 26 0.2443206161 ( -1.3515815735 15.6122865677 0.3233171701 ) - weight 536 29 0.5839904547 ( 1.3121798038 0.8675627112 0.7582329512 ) - weight 537 30 0.1716888845 ( 0.2774288952 0.6762843132 0.746216476 ) - weight 538 33 0.5 ( -0.2717907727 -0.7016150355 -0.5614560246 ) - weight 539 34 0.5 ( 0.1214045286 2.4612157345 0.4779031277 ) - weight 540 26 1 ( -1.6943989992 10.706820488 1.6243963242 ) - weight 541 26 0.7828121781 ( 0.4625955224 10.5008792877 1.8324626684 ) - weight 542 36 0.2171877921 ( -0.7024562955 -0.3876839578 1.9279164076 ) - weight 543 32 0.8064539433 ( 0.5449220538 -0.9030780792 0.9237840772 ) - weight 544 33 0.1935460418 ( -1.599244833 0.2619217634 0.9171643853 ) - weight 545 37 0.5 ( -0.7680109739 -0.5373968482 -1.3274434805 ) - weight 546 38 0.5 ( -0.8404526711 -0.4586361349 0.163670972 ) - weight 547 37 0.5 ( -0.8789610863 0.2909032404 -1.5237985849 ) - weight 548 38 0.5 ( -0.8894810081 0.3931641579 0.0689145401 ) - weight 549 37 0.5 ( -0.6989086866 -0.2194852084 -2.6562364101 ) - weight 550 38 0.5 ( -0.8232285976 0.0056672487 -1.1230531931 ) - weight 551 26 0.3331983984 ( 2.952205658 11.7601833344 -0.5206296444 ) - weight 552 36 0.3078258038 ( -0.8045962453 0.6618306637 -1.5662406683 ) - weight 553 37 0.3589757979 ( -0.742839396 0.5040310621 0.0092220074 ) - weight 554 37 0.5 ( 0.0090534491 0.4610291719 -1.5815186501 ) - weight 555 38 0.5 ( 0.005024286 0.4965930879 -0.0311204586 ) - weight 556 37 0.5 ( -0.1952857673 -0.6723154783 -2.279715538 ) - weight 557 38 0.5 ( -0.3398726881 -0.5272213817 -0.8352059722 ) - weight 558 37 0.5 ( 0.185577929 -0.3597683311 -1.4530291557 ) - weight 559 38 0.5 ( 0.1158538982 -0.3451501131 -0.0073675248 ) - weight 560 37 0.5 ( -0.0767475292 -0.1661862135 -2.6328368187 ) - weight 561 38 0.5 ( -0.1985102147 0.0054486445 -1.1371861696 ) - weight 562 26 0.6501254439 ( 1.7420004606 10.4314002991 0.5649607182 ) - weight 563 36 0.3498745561 ( -0.5262141824 0.7162458897 0.5142179728 ) - weight 564 26 1 ( 1.511102438 10.3411369324 -0.4202666581 ) - weight 565 33 0.5 ( -0.2364538312 -0.7071331143 0.2055225968 ) - weight 566 34 0.5 ( 0.1368438303 2.4289546013 -0.2890755236 ) - weight 567 33 0.5 ( 2.0911660194 -0.3682411611 -0.0935789272 ) - weight 568 34 0.5 ( 0.4810808599 0.1021193564 0.0100259921 ) - weight 569 32 0.8064539433 ( 0.4815154672 -0.8676565289 0.2664010823 ) - weight 570 33 0.1935460418 ( -1.6169074774 0.3323712051 0.2597813904 ) - weight 571 33 0.5 ( 0.9833032489 -0.7534092069 -0.2936167121 ) - weight 572 34 0.5 ( 0.531662941 1.2739366293 0.2100637704 ) - weight 573 4 0.211769715 ( -0.2060718834 21.3827342987 -1.9706429243 ) - weight 574 5 0.7882302999 ( 0.3228330016 0.502282083 -2.3997702599 ) - weight 575 4 0.2941013873 ( -1.8384666443 22.617975235 0.4862731397 ) - weight 576 5 0.7058986425 ( 2.670879364 1.7133342028 -0.5978268981 ) - weight 577 4 0.211769715 ( -0.62570858 22.7841949463 -2.3957443237 ) - weight 578 5 0.7882302999 ( 0.082568787 2.005297184 -2.3355960846 ) - weight 579 22 0.1330899894 ( 11.3521499634 3.570941925 -0.3750983477 ) - weight 580 24 0.1222179085 ( -3.7309713364 -0.6798927784 1.3486404419 ) - weight 581 25 0.7446920872 ( -0.129434973 2.274491787 3.3226730824 ) - weight 582 22 0.4312410653 ( 5.3821601868 1.10679245 5.9322113991 ) - weight 583 23 0.1283100247 ( 5.7598204613 3.1315970421 -1.4025417566 ) - weight 584 24 0.3281306624 ( 2.2390184402 5.6274170876 -1.1155090332 ) - weight 585 20 0.1123182103 ( 1.3574771881 3.5538444519 -0.8615365028 ) - weight 586 22 0.7518678904 ( 3.0729999542 5.6567344666 2.9678616524 ) - weight 587 23 0.0723678172 ( 2.9501898289 -0.0638554767 2.686054945 ) - weight 588 24 0.175764218 ( 4.5481786728 2.6630673409 3.4344329834 ) - weight 589 22 0.4648121297 ( 4.5032200813 4.459690094 4.0668215752 ) - weight 590 23 0.1376403272 ( 3.9548487663 1.6073743105 1.7459436655 ) - weight 591 24 0.3975475132 ( 3.1179585457 3.7620272636 2.2373886108 ) - weight 592 22 0.4866587222 ( 5.2658500671 5.7421607971 1.9103716612 ) - weight 593 23 0.0868105441 ( 1.7537978888 2.0149586201 3.1119091511 ) - weight 594 24 0.4265308082 ( 2.3553285599 1.6055772305 3.519859314 ) - weight 595 22 0.7110148072 ( 3.6320300102 6.6992988586 1.0049716234 ) - weight 596 23 0.0715909079 ( 0.9553978443 0.1941411495 3.7845242023 ) - weight 597 24 0.217394352 ( 3.9891486168 0.7001771927 4.4769973755 ) - weight 598 22 0.5249072909 ( 4.6104397774 6.0181846619 -0.6713583469 ) - weight 599 23 0.0834142864 ( -0.7804118991 1.1610393524 3.2522113323 ) - weight 600 24 0.3916783631 ( 3.0107388496 -0.9761527777 3.7958831787 ) - weight 601 25 0.146963343 ( -0.4951398969 13.0806560516 3.1095454693 ) - weight 602 26 0.8530366421 ( -1.9260792732 0.7654191256 2.2917861938 ) - weight 603 25 0.3857780397 ( -1.2215526104 12.0899715424 2.9997074604 ) - weight 604 26 0.6142219305 ( -2.2066631317 -0.3902872801 1.96496737 ) - weight 605 25 0.0593079589 ( -3.2306706905 12.3572864532 1.7115132809 ) - weight 606 26 0.9406920671 ( -3.603880167 -0.6601116657 0.0304296091 ) - weight 607 25 0.0593079589 ( -2.8961610794 13.704782486 1.7667094469 ) - weight 608 26 0.9406920671 ( -3.7632584572 0.7148704529 0.1517249048 ) - weight 609 25 0.1007401645 ( -1.7324892282 13.6813201904 -2.5044190884 ) - weight 610 26 0.8992598653 ( -1.2273775339 1.4116054773 -3.4093267918 ) - weight 611 25 0.0593079589 ( -3.5300974846 13.7525482178 -0.5543946624 ) - weight 612 26 0.9406920671 ( -3.5173060894 0.753947854 -2.2419462204 ) - weight 613 22 0.1032253429 ( 10.456870079 2.0270195007 -3.0863785744 ) - weight 614 24 0.1232035086 ( -2.835691452 -3.3911731243 -0.1952819824 ) - weight 615 25 0.7735711336 ( -3.0894238949 2.4802644253 2.0064713955 ) - weight 616 12 0.0843834653 ( 0.2005146742 6.4286642075 4.4115843773 ) - weight 617 13 0.5620473027 ( 1.5335928202 3.6064870358 2.4241364002 ) - weight 618 14 0.3535692692 ( 1.4949829578 -1.4960964918 2.4291889668 ) - weight 619 11 0.0935239866 ( -3.8111169338 18.6099414825 -1.035648942 ) - weight 620 12 0.6671485305 ( 0.7658381462 3.1304476261 2.2976410389 ) - weight 621 13 0.2393274605 ( 1.2482603788 -0.3180600107 2.8520338535 ) - weight 622 12 0.4737676382 ( 1.8243260384 5.0132069588 1.8210150003 ) - weight 623 13 0.5262323618 ( 2.2546744347 0.5913562775 1.1049093008 ) - weight 624 13 0.5046935678 ( -2.2403481007 4.8383469582 -0.8591219187 ) - weight 625 14 0.495306462 ( -2.2457540035 -0.1773362309 -0.8583106995 ) - weight 626 13 0.5011257529 ( 2.0092220306 4.9650716782 -0.9881343842 ) - weight 627 14 0.4988743067 ( 2.0056653023 -0.1622206718 -0.9877607226 ) - weight 628 12 0.4963374138 ( -2.4832983017 6.207262516 -1.8910052776 ) - weight 629 13 0.5036625266 ( -2.8364603519 0.2825944424 -1.6781654358 ) - weight 630 12 0.4661476612 ( 2.9381551743 6.680390358 -0.1895405501 ) - weight 631 13 0.4800623953 ( 2.864084959 0.4030625522 -1.661968708 ) - weight 632 14 0.0537899137 ( 2.7408871651 -4.7473258972 -1.6458107233 ) - weight 633 11 0.3033103049 ( -1.7669993639 19.893743515 0.9123718739 ) - weight 634 12 0.6966896653 ( 2.0454998016 1.4687638283 0.0123342369 ) - weight 635 11 0.6232063174 ( -2.7536978722 19.8182964325 3.4391257763 ) - weight 636 12 0.2971909642 ( 4.5328111649 0.67581743 0.7527865767 ) - weight 637 13 0.079602696 ( 4.244515419 -4.0007386208 2.6026237011 ) - weight 638 11 0.5 ( 1.1285079718 20.9284076691 2.73594594 ) - weight 639 12 0.5 ( 2.7857880592 -0.802236855 -2.6474480629 ) - weight 640 11 0.2689843774 ( -4.0165576935 18.5647926331 0.8035916686 ) - weight 641 12 0.5431467891 ( 2.3730924129 2.2326204777 2.4917821884 ) - weight 642 13 0.1878687739 ( 2.7789888382 -1.263245821 3.2885482311 ) - weight 643 11 0.1060663685 ( -3.8947963715 17.6123886108 -2.6348767281 ) - weight 644 12 0.4873141348 ( -0.9071973562 3.5118243694 3.0819528103 ) - weight 645 13 0.3494953811 ( -0.103266716 0.8336921334 3.4895937443 ) - weight 646 14 0.0571241342 ( -0.2137238085 -4.2214417458 3.5042312145 ) - weight 647 11 0.3997223675 ( 1.1584303379 23.7406368256 2.4658257961 ) - weight 648 12 0.416490972 ( 3.5817551613 0.8614726663 -4.7877759933 ) - weight 649 13 0.1837866157 ( 1.7758827209 -6.9593873024 -1.4948220253 ) - weight 650 11 0.4107972383 ( 3.041066885 23.354347229 0.2583816051 ) - weight 651 12 0.4213652015 ( 0.8306990862 0.6585357785 -5.7659673691 ) - weight 652 13 0.1678375453 ( -1.146812439 -7.0609116554 -1.6127067804 ) - weight 653 13 0.5249262452 ( -0.3187460303 4.7918243408 1.1942294836 ) - weight 654 14 0.475073725 ( -0.3258395195 -0.2669892311 1.1951893568 ) - weight 655 11 0.0803422183 ( -2.1340589523 18.395866394 -3.2236111164 ) - weight 656 12 0.6961277723 ( -1.8226180077 3.1415815353 1.3253749609 ) - weight 657 13 0.2235300243 ( -1.5025411844 -0.2899706066 2.5730495453 ) - weight 658 12 0.1096295714 ( -2.851449728 6.0545563698 3.1862447262 ) - weight 659 13 0.5836595297 ( -1.7587673664 3.2957522869 2.2837510109 ) - weight 660 14 0.3067108989 ( -1.8043893576 -1.7211194038 2.2898793221 ) - weight 661 11 0.120941259 ( -0.4893733263 19.3922729492 -3.2120206356 ) - weight 662 12 0.7397739887 ( -2.1099298 2.6337282658 -0.5069710016 ) - weight 663 13 0.13928473 ( -2.3319923878 -1.7106440067 1.5772321224 ) - weight 664 11 0.1834091842 ( -1.6652474403 17.6618995667 -4.2978248596 ) - weight 665 12 0.5260417461 ( -3.1817188263 3.02911973 1.5547704697 ) - weight 666 13 0.2905490696 ( -2.7451124191 0.0778421834 3.055911541 ) - weight 667 11 0.307454288 ( 1.1555119753 19.5911369324 -3.7368063927 ) - weight 668 12 0.5233104229 ( -3.1400585175 1.9830665588 -1.746353507 ) - weight 669 13 0.1692353189 ( -3.7135102749 -2.7122008801 1.2472529411 ) - weight 670 11 0.5 ( 2.5797736645 20.61211586 0.7229776978 ) - weight 671 12 0.5 ( 0.3974426091 -0.7988772988 -3.3917920589 ) - weight 672 3 0.2396446764 ( -7.9216599464 3.2589836121 1.2398151159 ) - weight 673 10 0.1261993945 ( 0.5366060138 -4.3808102608 3.8504302502 ) - weight 674 17 0.5096623302 ( -7.7260513306 2.141875267 2.1062855721 ) - weight 675 19 0.0713101402 ( -7.9216599464 -5.5756540298 3.6842184067 ) - weight 676 18 0.0531834662 ( -7.8399028778 0.8318443298 -5.31199646 ) - weight 677 3 0.1069236025 ( -7.5292000771 5.1090126038 -3.0387847424 ) - weight 678 10 0.055033993 ( 4.3881797791 -6.5629343987 2.3382258415 ) - weight 679 17 0.5240889192 ( -7.5798559189 4.9720015526 -1.6155502796 ) - weight 680 19 0.1887804121 ( -7.5292000771 -4.1088476181 -0.740428865 ) - weight 681 22 0.1251730919 ( -7.5292000771 -11.8313484192 -1.787248373 ) - weight 682 3 0.2767252028 ( -7.8065271378 2.3994979858 -2.7645223141 ) - weight 683 10 0.2168948948 ( 4.242521286 -3.833327055 2.1911702156 ) - weight 684 17 0.5063799024 ( -7.8409814835 2.2725000381 -1.9871748686 ) - weight 685 3 0.2621211112 ( -8.6405496597 -0.0342292786 1.0405751467 ) - weight 686 10 0.3809435368 ( 0.9930652976 -1.035184145 3.8370196819 ) - weight 687 17 0.3569353521 ( -8.4551935196 -1.016340971 1.1598330736 ) - weight 688 3 0.0989223495 ( -7.5270900726 5.537853241 2.3491351604 ) - weight 689 10 0.0575829931 ( -0.650737524 -6.611055851 4.2928581238 ) - weight 690 17 0.3998931944 ( -7.268450737 4.0922346115 3.7082290649 ) - weight 691 19 0.1923786998 ( -7.5270900726 -3.208101511 4.5889468193 ) - weight 692 22 0.1035134494 ( -7.5270900726 -11.402507782 3.6006715298 ) - weight 693 21 0.0805758238 ( -3.2747302055 -9.083782196 -3.1930763721 ) - weight 694 18 0.0671336129 ( -7.445333004 3.1107139587 -4.2026767731 ) - weight 695 3 0.2820416689 ( -4.8764200211 2.6567230225 5.4821052551 ) - weight 696 10 0.1240752786 ( -4.5081586838 -4.0124230385 2.4193921089 ) - weight 697 17 0.387751013 ( -4.4423007965 0.5790408254 5.9020409584 ) - weight 698 19 0.0845782757 ( -4.8764200211 -5.8027129173 7.9630250931 ) - weight 699 18 0.1215537339 ( -4.7946629524 0.2295837402 -1.06970644 ) - weight 700 3 0.1464416832 ( -4.9807500839 2.1081008911 -5.6871747971 ) - weight 701 10 0.120930925 ( 5.9716215134 -4.2302489281 -1.4782290459 ) - weight 702 17 0.5861251354 ( -5.1876420975 2.731782198 -5.0466971397 ) - weight 703 19 0.1465022862 ( -4.9807500839 -7.3309221268 -3.1148078442 ) - weight 704 3 0.375176847 ( -7.0446190834 -2.6003761292 -4.0200066566 ) - weight 705 10 0.4408628345 ( 5.16776371 0.8647939563 0.135186106 ) - weight 706 17 0.1839603484 ( -7.152402401 -2.2675521374 -4.4507641792 ) - weight 707 3 0.3470622599 ( -5.1477098465 -2.4127578735 4.9502854347 ) - weight 708 10 0.2832652926 ( -3.8919038773 0.9800488949 1.5524904728 ) - weight 709 17 0.2488396764 ( -4.7436728477 -4.2169270515 4.1804332733 ) - weight 710 18 0.120832786 ( -5.0659527779 -4.8398971558 -1.6015262604 ) - weight 711 3 0.2094427347 ( -8.0489702225 -3.8961181641 3.9736251831 ) - weight 712 10 0.5674699545 ( -1.9414188862 2.8638586998 3.6063656807 ) - weight 713 17 0.1501680017 ( -7.6962146759 -5.461792469 3.0383558273 ) - weight 714 18 0.0729193389 ( -7.9672131538 -6.3232574463 -2.578186512 ) - weight 715 3 0.206284374 ( -5.9700078964 -6.2046012878 5.3384180069 ) - weight 716 10 0.7937155962 ( -3.9454965591 4.8741574287 1.7472774982 ) - weight 717 3 0.2200269848 ( -6.8720397949 0.8836936951 4.5903654099 ) - weight 718 10 0.3166716397 ( -2.9575560093 -1.9920120239 3.6172657013 ) - weight 719 17 0.3024932444 ( -6.4858207703 -0.9548606277 4.7219967842 ) - weight 720 19 0.0659813955 ( -6.8720397949 -7.6472587585 7.2305750847 ) - weight 721 18 0.0948267728 ( -6.7902827263 -1.5434455872 -1.9614462852 ) - weight 722 3 0.2082437575 ( -5.176129818 -4.9036064148 -6.1572346687 ) - weight 723 10 0.7098788619 ( 6.5118899345 2.6627771854 -2.7500255108 ) - weight 724 17 0.0818773657 ( -5.4096837044 -3.9630019665 -7.1806445122 ) - weight 725 3 0.0799444988 ( -1.1937500238 -8.7768783569 2.1950352192 ) - weight 726 10 0.9200555086 ( -2.692909956 6.37225914 -4.2106437683 ) - weight 727 3 0.2145216614 ( -2.6130399704 -8.0310783386 -5.003554821 ) - weight 728 10 0.6947645545 ( 4.5367937088 5.3811445236 -5.2780604362 ) - weight 729 17 0.0907137543 ( -2.7845926285 -7.2403960228 -6.9591207504 ) - weight 730 3 0.0799444988 ( -1.0088499784 -10.5870780945 1.3821251392 ) - weight 731 10 0.9200555086 ( -1.9906377792 8.0638160706 -4.9963154793 ) - weight 732 3 0.0884010941 ( -3.3562099934 -13.1236286163 3.4472453594 ) - weight 733 10 0.9115989208 ( -3.0754854679 11.0997104645 -2.5848097801 ) - weight 734 3 0.0662936196 ( -2.4494698048 -16.4921951294 0.7676100731 ) - weight 735 10 0.9337064028 ( -0.8778330684 14.070848465 -4.9707117081 ) - weight 736 3 0.0882157311 ( -2.123239994 -10.3164672852 -4.2167248726 ) - weight 737 10 0.9117842913 ( 3.6375341415 7.5989294052 -5.8736863136 ) - weight 738 3 0.1049511358 ( -2.9273700714 -15.950920105 -4.2486548424 ) - weight 739 10 0.8950488567 ( 3.9783990383 13.2720651627 -6.1803560257 ) - weight 740 3 0.1228495687 ( -5.6060552597 -9.2707214355 -5.7493681908 ) - weight 741 10 0.8771504164 ( 6.30300951 7.0570039749 -3.0146408081 ) - weight 742 3 0.1095804423 ( -10.4930238724 -9.5163421631 0.3507947028 ) - weight 743 10 0.8904195428 ( 2.3386201859 8.5528087616 3.558103323 ) - weight 744 10 1 ( 6.1833076477 12.4689626694 0.3314670324 ) - weight 745 10 1 ( 3.9203770161 14.6388139725 2.2393255234 ) - weight 746 3 0.2347732633 ( -9.3699684143 -5.0844078064 -0.0834435076 ) - weight 747 10 0.6872122884 ( 2.3255674839 3.9751489162 3.1883494854 ) - weight 748 17 0.0780144259 ( -9.2479343414 -5.6574649811 -1.1054048538 ) - weight 749 3 0.1663484424 ( -8.5809659958 -7.2308349609 -3.2218973637 ) - weight 750 10 0.8336515427 ( 4.9884428978 5.7331357002 0.975174427 ) - weight 751 3 0.1630153507 ( -3.3091499805 -8.0478057861 4.5056352615 ) - weight 752 10 0.8369846344 ( -4.1042923927 6.1756715775 -1.3271232843 ) - weight 753 10 1 ( -2.0194113255 17.0197486877 -1.7512795925 ) - weight 754 3 0.0671593621 ( -7.8446297646 -21.3117198944 -5.241314888 ) - weight 755 10 0.7200645804 ( 6.6775922775 19.3091106415 -2.9910881519 ) - weight 756 11 0.21277605 ( 2.0256447792 -0.0247785393 4.0510172844 ) - weight 757 3 0.0609805807 ( -6.9160900116 -15.648229599 4.1621651649 ) - weight 758 10 0.9390194416 ( -2.4674665928 14.2364139557 0.4727826416 ) - weight 759 10 0.9282485247 ( 1.5941376686 17.51603508 -5.0863404274 ) - weight 760 11 0.0717514902 ( 3.5932602882 -2.562561512 -0.903672576 ) - weight 761 10 0.6559420824 ( 0.7538217902 19.7825641632 0.8479977846 ) - weight 762 11 0.3440578878 ( -2.6978392601 -1.353615284 -1.0457158089 ) - weight 763 10 0.740267396 ( 4.2336611748 20.0336475372 -5.3213167191 ) - weight 764 11 0.2597326636 ( 3.7972021103 0.4693011642 1.1278017759 ) - weight 765 10 0.5014052391 ( 2.149392128 20.8791847229 -5.5186281204 ) - weight 766 11 0.4985947609 ( 3.5267856121 0.8683485389 -1.0780266523 ) - weight 767 10 0.3635103106 ( 5.4534173012 22.884431839 -5.2546839714 ) - weight 768 11 0.6364896297 ( 3.4337935448 3.4790241718 1.7825651169 ) - weight 769 10 0.2838164866 ( 7.1277294159 21.8929901123 -3.204638958 ) - weight 770 11 0.7161834836 ( 1.8627427816 2.600127697 3.9616250992 ) - weight 771 11 1 ( 4.1747879982 5.6384506226 2.5484638214 ) - weight 772 11 1 ( 1.9424036741 5.411593914 4.9871740341 ) - weight 773 10 0.0533990003 ( 3.1104099751 24.6857204437 0.2727412879 ) - weight 774 11 0.9466010332 ( -2.6117572784 3.971694231 0.2028980851 ) - weight 775 10 0.3121370077 ( 4.4104804993 21.7292518616 1.1969943047 ) - weight 776 11 0.6878629327 ( -2.8097553253 1.2642891407 2.1817588806 ) - weight 777 10 0.0613344088 ( 6.7926464081 24.7603626251 0.0432994515 ) - weight 778 11 0.9386655688 ( -1.8381592035 4.8623752594 3.699369669 ) - weight 779 10 0.2215298414 ( 7.4688601494 22.7167358398 -0.8187316656 ) - weight 780 11 0.7784701586 ( -0.5479092002 3.1467094421 4.5760245323 ) - weight 781 10 0.6404342651 ( 6.21342659 19.7115879059 -0.6915683746 ) - weight 782 11 0.3595657051 ( -0.3523505926 -0.046237547 3.9514863491 ) - weight 783 10 0.8282259107 ( -0.7209715843 19.3569717407 -2.37758708 ) - weight 784 11 0.1717740893 ( 0.2891767919 -1.6436548233 -2.9832799435 ) - weight 785 10 0.6559420824 ( 1.1478339434 21.2382259369 0.2823551893 ) - weight 786 11 0.3440578878 ( -2.3346142769 0.215525791 -1.0426588058 ) - weight 787 10 0.3121370077 ( 3.7808356285 20.3172340393 1.7208317518 ) - weight 788 11 0.6878629327 ( -3.1757318974 -0.3073510826 1.9354708195 ) - weight 789 3 0.0721886456 ( -9.0645103455 -13.3509693146 3.1552453041 ) - weight 790 10 0.9278113842 ( -0.7731717825 12.2737874985 2.518378973 ) - weight 791 11 1 ( 2.793422699 10.4113874435 4.7221670151 ) - weight 792 11 1 ( 3.6400504112 10.014257431 1.8300765753 ) - weight 793 11 1 ( 4.2849411964 13.5269527435 1.7910120487 ) - weight 794 11 1 ( 3.0211541653 10.480055809 -1.1083557606 ) - weight 795 10 0.0812822282 ( 3.5914700031 26.3057136536 -5.7968540192 ) - weight 796 11 0.918717742 ( 3.0948572159 6.464184761 -0.7551316023 ) - weight 797 11 1 ( -2.0436594486 8.7029666901 4.2525582314 ) - weight 798 11 1 ( -2.0114254951 11.6826839447 1.4886935949 ) - weight 799 11 1 ( -1.8060920238 15.6041793823 3.1001291275 ) - weight 800 11 1 ( -2.9188184738 14.9884338379 -1.3725756407 ) - weight 801 11 1 ( 0.7908785343 12.6231794357 3.931704998 ) - weight 802 11 1 ( 2.0547904968 16.7860774994 4.3061261177 ) - weight 803 11 0.9168231487 ( 4.2297925949 17.2570705414 0.7401224375 ) - weight 804 12 0.0831768736 ( -1.487857461 -3.6887886524 -1.9519144297 ) - weight 805 11 0.8543199301 ( 2.0495455265 16.9153442383 -2.481218338 ) - weight 806 12 0.1456800848 ( -3.4329314232 -0.7313294411 -0.3034566343 ) - weight 807 11 1 ( -0.6386532187 15.01126194 -3.22143507 ) - weight 808 11 1 ( -0.4396337867 10.07899189 -1.5343606472 ) - weight 809 11 1 ( -2.0637106895 10.1659154892 -0.3421333134 ) - weight 810 11 1 ( -1.0976872444 6.0287203789 -1.8638337851 ) - weight 811 11 0.5 ( 1.6393619776 20.7561244965 3.6193704605 ) - weight 812 12 0.5 ( 3.2564940453 -1.7031702995 -2.8419897556 ) - weight 813 41 1 ( 3.8567478657 7.0149393082 2.004317522 ) - weight 814 41 1 ( 3.2663300037 7.2312960625 -1.5945971012 ) - weight 815 41 0.8784247637 ( 3.3650350571 10.6294660568 1.7742807865 ) - weight 816 42 0.1215752512 ( 3.5733771324 -1.7166399956 0.8082985282 ) - weight 817 41 0.8984447718 ( 1.9083660841 9.9396057129 -2.078766346 ) - weight 818 42 0.1015552133 ( 1.5035066605 -1.2628608942 -2.7907962799 ) - weight 819 17 0.5152887702 ( -4.2171545029 5.684943676 -4.689473629 ) - weight 820 19 0.3591423929 ( -3.9909200668 -4.4172315598 -3.6816065311 ) - weight 821 22 0.125568822 ( -3.9909200668 -11.880027771 -4.7441482544 ) - weight 822 17 0.3153382242 ( -7.9742379189 7.729663372 1.1004208326 ) - weight 823 19 0.3789919317 ( -8.0361099243 -0.61992836 0.9049345851 ) - weight 824 22 0.2489299327 ( -8.0361099243 -8.5005493164 0.1584016085 ) - weight 825 21 0.0567399301 ( -3.7837500572 -6.1818237305 -6.6353464127 ) - weight 826 17 0.1273706257 ( -7.3477153778 10.6268663406 -1.1027450562 ) - weight 827 19 0.4415688813 ( -7.2477998734 1.4065550566 -2.0803947449 ) - weight 828 22 0.363877058 ( -7.2477998734 -6.2195167542 -2.6372585297 ) - weight 829 40 0.0671834275 ( -0.3733801842 -2.9420502186 -8.4418411255 ) - weight 830 17 0.316473484 ( -6.1103277206 7.8278198242 -2.1286211014 ) - weight 831 19 0.4292660952 ( -5.9940099716 -1.5676822662 -2.0686321259 ) - weight 832 22 0.2542604208 ( -5.9940099716 -9.1832771301 -2.8869585991 ) - weight 833 17 0.1202539653 ( -4.1782231331 12.3441114426 -3.9000723362 ) - weight 834 19 0.4247384965 ( -3.9039299488 2.1368479729 -5.0978207588 ) - weight 835 22 0.3653951585 ( -3.9039299488 -5.2268371582 -5.5788183212 ) - weight 836 40 0.089612402 ( -3.7172501087 -5.8836097717 -7.4491615295 ) - weight 837 41 1 ( 1.1561261415 7.6366343498 -2.9281888008 ) - weight 838 41 0.8327695727 ( -1.4427342415 10.009853363 -2.6848526001 ) - weight 839 42 0.1672303826 ( -1.8871777058 -0.938195467 -2.7915349007 ) - weight 840 41 1 ( 3.5619637966 5.7611265182 1.7897075415 ) - weight 841 22 0.0771214515 ( -10.5706396103 -2.2360191345 2.5162317753 ) - weight 842 41 0.9228785634 ( 1.9020212889 4.9268174171 -2.3415699005 ) - weight 843 41 1 ( 1.7224888802 6.5966973305 3.8268032074 ) - weight 844 19 0.189502582 ( -7.2366700172 5.6184434891 5.9579463005 ) - weight 845 22 0.4047628939 ( -7.2366700172 -2.7304496765 5.7401714325 ) - weight 846 40 0.1485210061 ( -0.3845100403 5.435379982 -4.9527740479 ) - weight 847 21 0.2572135329 ( -2.9843101501 -0.4117240906 -1.0535764694 ) - weight 848 19 0.0508285165 ( -8.6673402786 8.395565033 4.8748426437 ) - weight 849 22 0.3103339374 ( -8.6673402786 0.1311225891 4.9053516388 ) - weight 850 39 0.0798272043 ( -4.5237159729 6.4590725899 -1.8480627537 ) - weight 851 40 0.1801317483 ( 1.0461602211 4.6005601883 -2.0912017822 ) - weight 852 41 0.2787561417 ( 0.8411581516 2.0180459023 -4.6540184021 ) - weight 853 21 0.1001224369 ( -4.4149804115 2.449848175 -1.8883962631 ) - weight 854 19 0.2537808418 ( -9.0340995789 3.8217997551 3.0478274822 ) - weight 855 22 0.4020117223 ( -9.0340995789 -4.2643585205 2.6834015846 ) - weight 856 40 0.076381281 ( 1.4129195213 2.3786098957 -6.4866828918 ) - weight 857 41 0.0616703294 ( 4.4256262779 4.7823185921 -2.6786162853 ) - weight 858 21 0.2061558366 ( -4.7817397118 -1.9456329346 -4.1103463173 ) - weight 859 22 0.2019269764 ( -10.2034502029 2.9910697937 3.9270217419 ) - weight 860 39 0.115218088 ( -3.448577404 7.4492030144 1.2113131285 ) - weight 861 40 0.2169577181 ( 2.5822701454 3.6222300529 0.7687454224 ) - weight 862 41 0.4658972621 ( -2.3162212372 1.7012797594 -3.4595828056 ) - weight 863 22 0.2104583681 ( -8.9566698074 5.3679389954 1.866071701 ) - weight 864 39 0.0883276537 ( -1.4721175432 5.7075328827 3.3353836536 ) - weight 865 40 0.2880037725 ( 1.3354897499 1.5612798929 3.145614624 ) - weight 866 41 0.4132102728 ( -3.4515111446 -0.6518012881 -1.3088597059 ) - weight 867 22 0.1066465601 ( -11.6929721832 2.5999641418 1.9945477247 ) - weight 868 40 0.082949616 ( 4.0717921257 1.6897560358 0.3776397705 ) - weight 869 41 0.8104037642 ( -2.6917729378 3.1627426147 -1.5027531385 ) - weight 870 19 0.0934283361 ( -9.1123199463 4.7844085693 1.4842790365 ) - weight 871 22 0.3328987956 ( -9.1123199463 -3.1680488586 1.2105116844 ) - weight 872 41 0.504265368 ( 3.573382616 4.2410945892 -1.1429809332 ) - weight 873 21 0.0694075301 ( -4.8599600792 -0.8493232727 -5.5832362175 ) - weight 874 19 0.3896191418 ( -8.652299881 3.1292157173 0.7079356313 ) - weight 875 22 0.4093904197 ( -8.652299881 -4.7486000061 0.2916916609 ) - weight 876 41 0.0671922043 ( 5.1998958588 4.7442626953 -0.3334945738 ) - weight 877 21 0.1337981522 ( -4.3999400139 -2.4298744202 -6.5020561218 ) - weight 878 19 0.1736020893 ( -8.3155002594 4.2229170799 -1.6327527761 ) - weight 879 22 0.331809938 ( -8.3155002594 -3.4533996582 -1.9438083172 ) - weight 880 40 0.1214219555 ( 0.6943202019 -2.2486000061 -5.6757240295 ) - weight 881 41 0.3731659949 ( 4.4652991295 3.7504241467 1.9602122307 ) - weight 882 41 0.88492769 ( -2.3163232803 10.4746017456 0.8628383279 ) - weight 883 42 0.1150723174 ( -2.1769552231 -1.4616116285 0.8426533341 ) - weight 884 41 0.4205686748 ( -3.020647049 11.5113430023 -0.5832348466 ) - weight 885 42 0.5794312954 ( -3.0170423985 -0.0437080227 -0.1298863143 ) - weight 886 41 0.2587660253 ( 1.855265975 12.3455028534 4.0511870384 ) - weight 887 42 0.7412339449 ( 2.5525527 -0.6670584679 3.6831521988 ) - weight 888 41 0.8383777142 ( 1.652395606 10.5092658997 3.883228302 ) - weight 889 42 0.1616222858 ( 2.1964707375 -2.3770570755 3.0584583282 ) - weight 890 41 0.4776410162 ( 3.2464129925 11.4837055206 -0.4490172267 ) - weight 891 42 0.5223590136 ( 3.1797749996 -0.2718236148 -1.0476199389 ) - weight 892 41 0.3601590693 ( 3.1873018742 12.0793809891 2.1052527428 ) - weight 893 42 0.6398409009 ( 3.5515034199 -0.4130382538 1.5455430746 ) - weight 894 41 0.5487061739 ( 1.1080173254 11.5891532898 -3.2024078369 ) - weight 895 42 0.4512938261 ( 0.6612677574 0.6554979682 -3.2752218246 ) - weight 896 41 1 ( -2.8816866875 8.815788269 0.3626794219 ) - weight 897 41 0.8383777142 ( -0.7790476084 10.6502408981 3.6524939537 ) - weight 898 42 0.1616222858 ( -0.2255709469 -2.1135749817 3.2805392742 ) - weight 899 41 1 ( -1.2811198235 7.2579083443 2.9313261509 ) - weight 900 17 0.2015561014 ( -5.707344532 9.2322530746 8.4510250092 ) - weight 901 19 0.2642347813 ( -6.1617097855 3.202600956 7.4854254723 ) - weight 902 22 0.3287962675 ( -6.1617097855 -5.2711982727 7.0494017601 ) - weight 903 21 0.2054128349 ( -1.9093499184 -2.9524726868 0.2556538582 ) - weight 904 17 0.1560927927 ( -7.7076444626 9.270860672 4.3501906395 ) - weight 905 19 0.3652572036 ( -7.9296998978 1.8955587149 3.4872529507 ) - weight 906 22 0.3252667487 ( -7.9296998978 -6.2217674255 2.951821804 ) - weight 907 21 0.1533832401 ( -3.6773400307 -3.9030418396 -3.8419260979 ) - weight 908 19 0.0948961601 ( -3.5566899776 8.5650749207 7.0386481285 ) - weight 909 22 0.4634767175 ( -3.5566899776 0.109790802 7.0756816864 ) - weight 910 39 0.0722427592 ( -7.0183758736 1.5668594837 -2.6680972576 ) - weight 911 40 0.1664817035 ( -4.0644903183 6.7708902359 -2.1125335693 ) - weight 912 21 0.2029026896 ( 0.6956698895 2.4285163879 0.2819337845 ) - weight 913 17 0.1906848699 ( -3.3322589397 8.7160596848 9.033446312 ) - weight 914 19 0.2058832794 ( -3.8301301003 2.9158346653 8.3387737274 ) - weight 915 22 0.2979409397 ( -3.8301301003 -5.6318588257 7.8742418289 ) - weight 916 21 0.1714980751 ( 0.4222297668 -3.3131332397 1.080493927 ) - weight 917 18 0.133992821 ( -3.74837327 8.881362915 0.0708937645 ) - weight 918 19 0.1344032288 ( -4.1019601822 8.4969930649 -5.6311721802 ) - weight 919 22 0.4274182618 ( -4.1019601822 1.1555709839 -5.5510883331 ) - weight 920 39 0.1332542896 ( 5.6173143387 1.1336321831 -1.6791850328 ) - weight 921 40 0.2516222596 ( -3.5192198753 -5.8558797836 -1.0667533875 ) - weight 922 41 0.0533020496 ( 3.23756814 -2.3043978214 5.6805362701 ) - weight 923 19 0.1979081333 ( -6.7445898056 5.6682634354 -4.2771639824 ) - weight 924 22 0.3774667084 ( -6.7445898056 -1.7812194824 -4.4509482384 ) - weight 925 39 0.0570001341 ( 4.6894845963 4.2792453766 -4.1414580345 ) - weight 926 40 0.1939489841 ( -0.8765902519 -4.7557396889 -4.0035438538 ) - weight 927 41 0.1736759692 ( 4.1239147186 1.5230221748 4.5041923523 ) - weight 928 22 0.8149345517 ( -1.8106399775 4.6890602112 4.1403317451 ) - weight 929 39 0.0842731968 ( -4.2014517784 -1.0768090487 1.5403031111 ) - weight 930 40 0.1007922292 ( -5.8105401993 3.8355400562 2.4667358398 ) - weight 931 22 0.1055573449 ( -11.1468296051 0.6763305664 4.0388617516 ) - weight 932 40 0.0612346157 ( 3.5256495476 3.7340700626 -1.5459938049 ) - weight 933 41 0.8332080245 ( -0.932436645 3.7749972343 -3.6724853516 ) - weight 934 22 0.2346942276 ( -8.8396902084 -0.3195800781 -4.1728482246 ) - weight 935 40 0.2036777884 ( 1.2185101509 -4.4776396751 -2.5419044495 ) - weight 936 41 0.561627984 ( 1.7286127806 2.4455888271 4.3834686279 ) - weight 937 22 0.7280092239 ( -2.5946099758 6.8535728455 -0.7384383678 ) - weight 938 39 0.0894822627 ( 0.717651248 -0.9631283879 3.7520051003 ) - weight 939 40 0.1825084984 ( -5.0265703201 -1.0432300568 4.6312484741 ) - weight 940 22 0.4795843363 ( -3.6837999821 4.6725578308 -3.5961685181 ) - weight 941 39 0.1561301053 ( 3.6395401955 0.2794415355 1.7449256182 ) - weight 942 40 0.3642855883 ( -3.9373800755 -3.900960207 2.4502334595 ) - weight 943 3 0.2082437575 ( -5.6810097694 -6.2914772034 -5.7304348946 ) - weight 944 10 0.7098788619 ( 6.2985768318 4.1425123215 -2.392074585 ) - weight 945 17 0.0818773657 ( -5.8892302513 -5.4196324348 -7.0733599663 ) - weight 946 22 0.4028716385 ( -7.2713699341 0.9188499451 5.3783316612 ) - weight 947 39 0.1384224147 ( -5.0855345726 4.9873390198 -1.2901040316 ) - weight 948 40 0.3638387024 ( -0.3498101234 5.0735402107 -1.3034744263 ) - weight 949 21 0.0948672518 ( -3.019010067 3.237575531 -1.4154162407 ) - weight 950 3 0.0863266289 ( -4.6218099594 5.7357635498 6.0177950859 ) - weight 951 17 0.3341448307 ( -4.1573586464 3.4420433044 7.1487588882 ) - weight 952 19 0.1688850224 ( -4.6218099594 -2.6885046959 8.2260131836 ) - weight 953 22 0.1109910384 ( -4.6218099594 -11.2045974731 7.2693314552 ) - weight 954 21 0.1000070646 ( -0.3694500923 -8.8858718872 0.4755835533 ) - weight 955 18 0.1996454149 ( -4.5400528908 3.3086242676 -0.5340166092 ) - weight 956 3 0.1723360568 ( -8.5654697418 -6.0981559753 3.1811532974 ) - weight 957 10 0.8276639581 ( -1.0072613955 5.0612983704 3.4005458355 ) - weight 958 22 0.2993527055 ( -8.5918798447 3.382183075 4.2053418159 ) - weight 959 39 0.1691163778 ( -3.8300116062 5.8166475296 1.3411639929 ) - weight 960 40 0.4106554091 ( 0.9706997871 3.9005498886 1.1598587036 ) - weight 961 41 0.1208755374 ( -1.7615330219 0.1445468962 -3.7702181339 ) - weight 962 22 0.3791531324 ( -6.9991698265 4.0735282898 3.9729616642 ) - weight 963 39 0.1587525159 ( -3.7005906105 4.121878624 1.7650655508 ) - weight 964 40 0.4620943964 ( -0.622010231 3.6681699753 1.8512039185 ) - weight 965 22 0.3157365322 ( -7.269780159 5.4760780334 2.5088117123 ) - weight 966 39 0.1305618137 ( -2.2220628262 4.0695161819 3.1776251793 ) - weight 967 40 0.4652858675 ( -0.3513998985 2.2040197849 3.2537536621 ) - weight 968 41 0.0884157941 ( -2.6450941563 -2.1145343781 -2.0020470619 ) - weight 969 11 0.6010227203 ( 3.4487290382 20.3779506683 0.1991010308 ) - weight 970 12 0.3989772201 ( -0.4781655371 -1.1931943893 -3.7945179939 ) - weight 971 11 0.1546468437 ( 0.6976568103 22.9507160187 -2.6980013847 ) - weight 972 12 0.4815303087 ( -0.8493284583 3.5413177013 -3.959931612 ) - weight 973 13 0.3638228774 ( -2.0435094833 -3.3795995712 -1.8090840578 ) - weight 974 11 0.1531316042 ( -2.0279140472 23.5547103882 0.804913342 ) - weight 975 12 0.4677073956 ( 3.4072511196 3.6919410229 -2.5732812881 ) - weight 976 13 0.3791610003 ( 2.4314396381 -3.4236733913 -1.6171352863 ) - weight 977 3 0.2347732633 ( -9.1127099991 -3.1918373108 0.2019149363 ) - weight 978 10 0.6872122884 ( 1.9589291811 2.090821743 3.398878336 ) - weight 979 17 0.0780144259 ( -8.9747190475 -3.8857293129 -0.3872541487 ) - weight 980 3 0.2305311114 ( -4.4013199806 -2.2253265381 -6.4352645874 ) - weight 981 10 0.3362547457 ( 6.4844374657 -0.1209997609 -3.0672729015 ) - weight 982 17 0.433214128 ( -4.652112484 -1.2860280275 -6.8479132652 ) - weight 983 3 0.1663484424 ( -7.9021692276 -5.2774772644 -3.180637598 ) - weight 984 10 0.8336515427 ( 4.6999111176 3.7004268169 0.7243401408 ) - weight 985 22 0.3324160576 ( -6.5781202316 1.6232719421 -4.6563382149 ) - weight 986 39 0.1443967223 ( 4.8837380409 3.5538811684 -0.8103061318 ) - weight 987 40 0.2850297987 ( -1.0430598259 -4.9611296654 -0.5990524292 ) - weight 988 41 0.2381574363 ( 1.4116080999 -0.5133979917 4.9002285004 ) - weight 989 22 0.2266537994 ( -8.715880394 3.7594718933 -3.1219182014 ) - weight 990 40 0.2749993503 ( 1.0947003365 -3.4267098904 1.537147522 ) - weight 991 41 0.4983468354 ( -1.6504063606 0.0637289509 3.5665097237 ) - weight 992 22 0.3057387173 ( -6.6514701843 4.0911598206 -3.5549983978 ) - weight 993 39 0.1308492124 ( 3.7893998623 3.2985541821 1.6485618353 ) - weight 994 40 0.3803289235 ( -0.9697098732 -3.8597900867 1.8688354492 ) - weight 995 41 0.183083117 ( -0.7465817332 -1.8331073523 3.9466121197 ) - weight 996 22 0.2374293655 ( -8.3510599136 5.5010185242 -1.598618269 ) - weight 997 39 0.0753508359 ( 1.9464275837 4.8696212769 3.3334746361 ) - weight 998 40 0.3531977534 ( 0.7298798561 -1.9034099579 3.2786941528 ) - weight 999 41 0.3340220451 ( -2.9916303158 -1.2160393 2.1347858906 ) - weight 1000 22 0.3466660976 ( -6.7255301476 5.7394523621 -0.8456683159 ) - weight 1001 39 0.1131498292 ( 1.0904487371 3.2780492306 3.3153147697 ) - weight 1002 40 0.4739112258 ( -0.89564991 -1.1504600048 3.5171279907 ) - weight 1003 41 0.0662728474 ( -2.3346624374 -2.7009248734 1.3412877321 ) - weight 1004 17 0.3154843152 ( -3.6312856674 8.1141386032 -3.746254921 ) - weight 1005 19 0.464012742 ( -3.4249699116 -1.8104203939 -3.5469682217 ) - weight 1006 22 0.2205028981 ( -3.4249699116 -9.2951393127 -4.3809084892 ) - weight 1007 42 1 ( 0.0200959053 5.4158701897 -2.4085371494 ) - weight 1008 42 1 ( -2.3583996296 10.481262207 -1.7054251432 ) - weight 1009 42 0.3331983984 ( 0.248769179 9.7673711777 -3.3772816658 ) - weight 1010 59 0.3078258038 ( 0.6891350746 -1.8510463238 0.3459380269 ) - weight 1011 60 0.3589757979 ( 0.7962598205 -1.38128829 -1.3684102297 ) - weight 1012 42 1 ( -2.2997217178 6.7847065926 -1.1140681505 ) - weight 1013 42 1 ( -2.5291166306 10.9682922363 0.9606371522 ) - weight 1014 42 1 ( -1.4059451818 7.8345994949 1.9115628004 ) - weight 1015 42 1 ( -0.3025646508 11.2339267731 2.8264009953 ) - weight 1016 42 1 ( -0.293094039 2.2679579258 3.347484827 ) - weight 1017 42 1 ( 1.3673355579 7.2730493546 3.2096087933 ) - weight 1018 42 1 ( 1.7550338507 11.1643619537 2.8721296787 ) - weight 1019 42 1 ( 3.1937220097 6.5948843956 1.1412689686 ) - weight 1020 42 1 ( 2.3130483627 2.0149121284 3.1472373009 ) - weight 1021 42 1 ( 2.5116844177 5.8856468201 -1.7285711765 ) - weight 1022 42 1 ( 2.325469017 10.0279474258 -2.2449808121 ) - weight 1023 42 1 ( 3.2931993008 10.5279865265 0.61454916 ) - weight 1024 60 0.5 ( -0.3340330124 0.7221202254 0.457556814 ) - weight 1025 61 0.5 ( -0.2910535634 0.8321457505 -0.9288354516 ) - weight 1026 60 0.5 ( 0.7972320318 0.2890482843 -0.0887236521 ) - weight 1027 61 0.5 ( 0.7628896832 0.3759047389 -1.5972530842 ) - weight 1028 56 1 ( -0.1920321435 -0.6766704321 0.4574462771 ) - weight 1029 42 0.2839439809 ( 1.4370514154 12.0446329117 -1.197181344 ) - weight 1030 59 0.4689332843 ( -1.0247991085 1.0213754177 0.7489199042 ) - weight 1031 60 0.2471227348 ( -0.9176743031 1.4064210653 -0.5672377944 ) - weight 1032 42 0.3331983984 ( 1.8360934258 11.1354932785 -3.1549258232 ) - weight 1033 59 0.3078258038 ( -0.4745385349 -0.83656317 1.7803317308 ) - weight 1034 60 0.3589757979 ( -0.367413789 -0.5776227713 0.1938902736 ) - weight 1035 56 1 ( -0.6210756302 0.2086301744 0.3698640764 ) - weight 1036 42 1 ( 1.4042080641 10.5487747192 1.1848039627 ) - weight 1037 42 0.8549714684 ( 1.299110651 10.3256940842 -1.1235650778 ) - weight 1038 59 0.1450285167 ( -1.2780147791 -0.3512305021 -0.2664779723 ) - weight 1039 56 0.8064539433 ( -0.700035274 -0.7238830328 -0.7712592483 ) - weight 1040 57 0.1935460418 ( 0.3546808064 -1.1668750048 -0.7214958072 ) - weight 1041 56 1 ( -1.5852206945 -0.7562256455 0.3024045527 ) - weight 1042 56 0.8064539433 ( -1.6399468184 -0.7141164541 -0.4374460876 ) - weight 1043 57 0.1935460418 ( -0.2823893428 -0.4757377803 -0.3876826763 ) - weight 1044 57 0.5 ( -2.10988307 -0.6644704342 0.2943509221 ) - weight 1045 58 0.5 ( 0.5027952194 0.2126314491 -0.2108553648 ) - weight 1046 57 0.5 ( -2.4400420189 -0.2689769864 0.3391590714 ) - weight 1047 58 0.5 ( 0.0291106682 0.4152223766 -0.2556635141 ) - weight 1048 57 0.5 ( -2.0971038342 -0.6478699446 -0.3835316896 ) - weight 1049 58 0.5 ( 0.4905668199 0.1956212372 0.467027247 ) - weight 1050 54 0.5349572301 ( -0.7844588757 -0.3680962622 1.0744719505 ) - weight 1051 55 0.4650427997 ( 0.6554608941 -1.0935063362 -1.040895462 ) - weight 1052 54 0.5349572301 ( -1.8326605558 0.5593644977 0.437767446 ) - weight 1053 55 0.4650427997 ( -0.5340838432 -0.356015265 -0.4041909873 ) - weight 1054 54 0.5 ( -2.7072348595 -0.4324189425 0.6642146707 ) - weight 1055 55 0.5 ( 0.1645652354 0.7666620016 -0.6306381822 ) - weight 1056 42 1 ( 0.3383007348 10.923584938 1.8646985292 ) - weight 1057 42 0.2443206161 ( 0.8235411048 14.5025577545 1.027395606 ) - weight 1058 53 0.5839904547 ( 0.0496862121 -0.9334039688 -1.4147603512 ) - weight 1059 54 0.1716888845 ( 0.6152150631 -1.6676182747 -1.46068573 ) - weight 1060 54 0.5 ( -2.7371511459 -0.1044312343 -0.1954369098 ) - weight 1061 55 0.5 ( -0.1581863463 0.7010700107 0.2290133983 ) - weight 1062 53 0.0691876858 ( -2.5861945152 -1.5596307516 -1.3677567244 ) - weight 1063 54 0.4924322069 ( -1.7131363153 -0.2957104146 -1.2634898424 ) - weight 1064 55 0.4383800626 ( 0.3192744255 -0.2247947752 1.2970663309 ) - weight 1065 53 0.2834812105 ( -2.1368486881 -0.8303858638 -1.5107094049 ) - weight 1066 54 0.5160946846 ( -0.8953325152 -0.0804822817 -1.4610224962 ) - weight 1067 55 0.2004240751 ( 0.3481174409 -1.0699540377 1.4945989847 ) - weight 1068 53 0.2834812105 ( -1.4118542671 -0.0662220046 -1.2851476669 ) - weight 1069 54 0.5160946846 ( 0.169365719 -0.0299610998 -1.3051159382 ) - weight 1070 55 0.2004240751 ( 0.6056656837 -2.1042671204 1.3386923075 ) - weight 1071 54 0.5349572301 ( -0.1085064635 0.5137090087 0.9470515847 ) - weight 1072 55 0.4650427997 ( 0.0050781346 -1.9943363667 -0.9134751558 ) - weight 1073 42 0.2443206161 ( -0.2098778188 14.3643980026 1.0577930212 ) - weight 1074 53 0.5839904547 ( -0.0659167022 0.0927545503 -1.2677874565 ) - weight 1075 54 0.1716888845 ( 1.2499855757 -0.8464744687 -1.3569766283 ) - weight 1076 42 0.2443206161 ( 0.5661029816 15.6500272751 0.7421413064 ) - weight 1077 53 0.5839904547 ( -1.1424219608 -0.9996068478 -1.2177131176 ) - weight 1078 54 0.1716888845 ( -0.2764536738 -0.890093565 -1.2062951326 ) - weight 1079 57 0.5 ( -0.1396016479 0.295471102 0.3316333294 ) - weight 1080 58 0.5 ( 0.1494941264 -1.9503929615 -0.2481377721 ) - weight 1081 42 1 ( -0.9832507372 10.8479213715 1.3476501703 ) - weight 1082 42 0.7828121781 ( -1.2674965858 10.5668239594 -0.7904796004 ) - weight 1083 59 0.2171877921 ( 0.6984576583 0.4209268987 -1.7677748203 ) - weight 1084 56 0.8064539433 ( -0.4912111163 0.5088008642 -1.1055318117 ) - weight 1085 57 0.1935460418 ( 1.3954418898 -0.4741027951 -1.0557683706 ) - weight 1086 60 0.5 ( 0.3955566585 -0.2429424375 1.7703517675 ) - weight 1087 61 0.5 ( 0.4278422296 -0.3353838623 0.2144673467 ) - weight 1088 60 0.5 ( 0.3227148652 0.5740038157 1.5122992992 ) - weight 1089 61 0.5 ( 0.4120118618 0.509305954 0.0546336956 ) - weight 1090 60 0.5 ( 0.0594020523 0.3390905261 2.8498191833 ) - weight 1091 61 0.5 ( 0.2095243484 0.1418247223 1.372751236 ) - weight 1092 42 0.3331983984 ( 1.1503784657 11.3424434662 -3.6097767353 ) - weight 1093 59 0.3078258038 ( 0.3726433516 -0.8000218272 1.8098319769 ) - weight 1094 60 0.3589757979 ( 0.4797680974 -0.5455716848 0.2282160521 ) - weight 1095 60 0.5 ( -0.493804872 -0.4069849551 1.7117886543 ) - weight 1096 61 0.5 ( -0.4744246602 -0.4191011786 0.1999955028 ) - weight 1097 60 0.5 ( -0.3805698156 0.7671362758 2.3771731853 ) - weight 1098 61 0.5 ( -0.218480885 0.6562663317 0.9824256301 ) - weight 1099 60 0.5 ( -0.6410399675 0.4167833328 1.5118175745 ) - weight 1100 61 0.5 ( -0.5601473451 0.431565851 0.1036731899 ) - weight 1101 60 0.5 ( -0.5537670255 0.2871520817 2.741158247 ) - weight 1102 61 0.5 ( -0.4112354517 0.1526217908 1.3018864393 ) - weight 1103 42 0.6501254439 ( -0.0536363535 10.3412094116 -2.1068847179 ) - weight 1104 59 0.3498745561 ( 0.3647232056 -0.6521641016 -0.3555502295 ) - weight 1105 42 1 ( 0.9338626266 10.2193365097 -1.8980699778 ) - weight 1106 57 0.5 ( -0.1082864031 0.3342523575 -0.4345587492 ) - weight 1107 58 0.5 ( 0.1213467866 -1.9915312529 0.5180543065 ) - weight 1108 57 0.5 ( -2.4111566544 -0.2257967442 -0.3625616431 ) - weight 1109 58 0.5 ( -0.0039483686 0.3751474619 0.4460572302 ) - weight 1110 56 0.8064539433 ( -0.4412201345 0.4163615704 -0.4525457621 ) - weight 1111 57 0.1935460418 ( 1.3623896837 -0.5738608837 -0.402782321 ) - weight 1112 57 0.5 ( -1.3658697605 0.2472067475 -0.0473303087 ) - weight 1113 58 0.5 ( -0.1566425413 -0.761972487 0.1308258772 ) - weight 1114 10 0.211769715 ( 0.2079494447 21.3829021454 -1.9682843685 ) - weight 1115 11 0.7882302999 ( -0.31194368 0.4594621956 -2.391358614 ) - weight 1116 10 0.2941013873 ( 1.8416267633 22.6176490784 0.4880268872 ) - weight 1117 11 0.7058986425 ( -2.6634552479 1.6705076694 -0.5939351916 ) - weight 1118 10 0.211769715 ( 0.6275741458 22.7843570709 -2.3934173584 ) - weight 1119 11 0.7882302999 ( -0.0723657086 1.9626016617 -2.3275358677 ) - weight 1120 22 0.1330899894 ( -11.3521499634 3.570941925 -0.3750983477 ) - weight 1121 40 0.1222179085 ( 3.7309699059 -0.6798900366 1.3486175537 ) - weight 1122 41 0.7446920872 ( -3.1466681957 2.3469040394 0.9059098363 ) - weight 1123 22 0.4312410653 ( -5.3821601868 1.10679245 5.9322113991 ) - weight 1124 39 0.1283100247 ( -5.7598214149 3.131560564 -1.4025423527 ) - weight 1125 40 0.3281306624 ( -2.2390198708 5.6274199486 -1.1155319214 ) - weight 1126 21 0.1123182103 ( -1.1298003197 3.4255180359 -0.8615365028 ) - weight 1127 22 0.7518678904 ( -3.0729999542 5.6567344666 2.9678616524 ) - weight 1128 39 0.0723678172 ( -2.9501888752 -0.0638315827 2.6860997677 ) - weight 1129 40 0.175764218 ( -4.5481801033 2.6630699635 3.4344100952 ) - weight 1130 22 0.4648121297 ( -4.5032200813 4.459690094 4.0668215752 ) - weight 1131 39 0.1376403272 ( -3.9548492432 1.6073839664 1.7459648848 ) - weight 1132 40 0.3975475132 ( -3.1179599762 3.7620298862 2.2373657227 ) - weight 1133 22 0.4866587222 ( -5.2658500671 5.7421607971 1.9103716612 ) - weight 1134 39 0.0868105441 ( -1.7537987232 2.0149896145 3.1119248867 ) - weight 1135 40 0.4265308082 ( -2.3553299904 1.6055799723 3.5198364258 ) - weight 1136 22 0.7110148072 ( -3.6320300102 6.6992988586 1.0049716234 ) - weight 1137 39 0.0715909079 ( -0.9553971291 0.1941823661 3.7845659256 ) - weight 1138 40 0.217394352 ( -3.9891500473 0.7001799345 4.4769744873 ) - weight 1139 22 0.5249072909 ( -4.6104397774 6.0181846619 -0.6713583469 ) - weight 1140 39 0.0834142864 ( 0.7804117799 1.1610746384 3.2522397041 ) - weight 1141 40 0.3916783631 ( -3.0107402802 -0.9761500359 3.7958602905 ) - weight 1142 41 0.146963343 ( -2.5777122974 13.1381340027 1.3277875185 ) - weight 1143 42 0.8530366421 ( -2.1746573448 0.9714481235 2.0505940914 ) - weight 1144 41 0.3857780397 ( -2.3313033581 12.1336078644 1.9996540546 ) - weight 1145 42 0.6142219305 ( -1.9012117386 -0.1870006025 2.3737337589 ) - weight 1146 41 0.0593079589 ( -0.6139689684 12.339140892 3.665779829 ) - weight 1147 42 0.9406920671 ( 0.0593021363 -0.5007272959 3.7248136997 ) - weight 1148 41 0.0593079589 ( -0.7089703083 13.6927700043 3.3668627739 ) - weight 1149 42 0.9406920671 ( 0.0165495016 0.8844855428 3.825050354 ) - weight 1150 41 0.1007401645 ( 3.184128046 13.5912265778 1.2619410753 ) - weight 1151 42 0.8992598653 ( 3.5279135704 1.2738859653 1.1574836969 ) - weight 1152 41 0.0593079589 ( 1.6958975792 13.6776227951 3.4566550255 ) - weight 1153 42 0.9406920671 ( 2.3999507427 0.7818817496 3.5079507828 ) - weight 1154 22 0.1032253429 ( -10.456870079 2.0270195007 -3.0863785744 ) - weight 1155 40 0.1232035086 ( 2.8356900215 -3.3911702633 -0.1953048706 ) - weight 1156 41 0.7735711336 ( -1.1876658201 2.4749224186 3.4909017086 ) -} diff --git a/base/animation/mp_labcoat.md5mesh b/base/animation/mp_labcoat.md5mesh deleted file mode 100644 index 1408d3075..000000000 --- a/base/animation/mp_labcoat.md5mesh +++ /dev/null @@ -1,6531 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:30 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_labcoat.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh labcoatmesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} - -mesh { - // meshes: labcoatmesh - shader "models/characters/male_npc/labcoat/labcoat" - - numverts 664 - vert 0 ( 0.8851889968 0.8249670267 ) 0 3 - vert 1 ( 0.9167770147 0.9147850275 ) 3 3 - vert 2 ( 0.9290639758 0.8345429897 ) 6 2 - vert 3 ( 0.633020997 0.6062430143 ) 8 2 - vert 4 ( 0.6279270053 0.6710920334 ) 10 2 - vert 5 ( 0.7075179815 0.6906809807 ) 12 2 - vert 6 ( 0.7152150273 0.6038039923 ) 14 3 - vert 7 ( 0.8113960028 0.5987670422 ) 17 3 - vert 8 ( 0.7982649803 0.6073759794 ) 20 2 - vert 9 ( 0.8745399714 0.622206986 ) 22 2 - vert 10 ( 0.7648239732 0.579185009 ) 24 3 - vert 11 ( 0.7108520269 0.5627390146 ) 27 4 - vert 12 ( 0.7324820161 0.5867669582 ) 0 3 - vert 13 ( 0.932197988 0.7495700121 ) 20 2 - vert 14 ( 0.9878820181 0.890460968 ) 14 3 - vert 15 ( 0.9349120259 0.6673409939 ) 22 2 - vert 16 ( 0.9803060293 0.6969209909 ) 31 3 - vert 17 ( 0.9712280035 0.640410006 ) 34 3 - vert 18 ( 0.8932440281 0.9510400295 ) 37 2 - vert 19 ( 0.8684700131 0.9948850274 ) 10 2 - vert 20 ( 0.9479979873 0.9782099724 ) 8 2 - vert 21 ( 0.8667160273 0.6727199554 ) 39 3 - vert 22 ( 0.8237410188 0.7295470238 ) 42 3 - vert 23 ( 0.8402420282 0.7758100033 ) 45 3 - vert 24 ( 0.683431983 0.5801969767 ) 42 3 - vert 25 ( 0.6725640297 0.5599319935 ) 48 3 - vert 26 ( 0.6523110271 0.593569994 ) 45 3 - vert 27 ( 0.9897819757 0.6107109785 ) 45 3 - vert 28 ( 0.9900910258 0.5969679952 ) 51 3 - vert 29 ( 0.9202200174 0.6185719967 ) 54 2 - vert 30 ( 0.8585289717 0.9232029915 ) 39 3 - vert 31 ( 0.6288350224 0.5866290331 ) 51 3 - vert 32 ( 0.9243559837 0.6973209977 ) 12 2 - vert 33 ( 0.8195310235 0.8209300041 ) 54 2 - vert 34 ( 0.8666120172 0.8175060153 ) 34 3 - vert 35 ( 0.9273049831 0.633498013 ) 54 2 - vert 36 ( 0.9103090167 0.6286840439 ) 10 2 - vert 37 ( 0.3748750091 0.3151479959 ) 56 5 - vert 38 ( 0.2510960102 0.3575590253 ) 61 5 - vert 39 ( 0.343088001 0.3657950163 ) 66 3 - vert 40 ( 0.248428002 0.4210450053 ) 69 3 - vert 41 ( 0.2626729906 0.3087499738 ) 72 7 - vert 42 ( 0.1585620046 0.358009994 ) 79 5 - vert 43 ( 0.7009400129 0.0962569714 ) 84 2 - vert 44 ( 0.6625279784 0.0512880087 ) 86 4 - vert 45 ( 0.6571320295 0.1524789929 ) 90 2 - vert 46 ( 0.620438993 0.0975469947 ) 92 3 - vert 47 ( 0.5378500223 0.6089279652 ) 95 3 - vert 48 ( 0.4563330114 0.6081140041 ) 98 3 - vert 49 ( 0.5527309775 0.6666370034 ) 92 3 - vert 50 ( 0.7084829807 0.1954429746 ) 101 1 - vert 51 ( 0.7453309894 0.1380500197 ) 102 2 - vert 52 ( 0.6256279945 0.2154139876 ) 104 2 - vert 53 ( 0.757035017 0.2478020191 ) 106 2 - vert 54 ( 0.3678930104 0.5143569708 ) 108 2 - vert 55 ( 0.3652400076 0.6079750061 ) 110 1 - vert 56 ( 0.9821090102 0.2825890183 ) 111 2 - vert 57 ( 0.9428480268 0.2738190293 ) 113 2 - vert 58 ( 0.926304996 0.3234940171 ) 115 2 - vert 59 ( 0.8848720193 0.3092319965 ) 117 2 - vert 60 ( 0.9194689989 0.3578289747 ) 119 1 - vert 61 ( 0.8797889948 0.3552349806 ) 120 1 - vert 62 ( 0.8046380281 0.291703999 ) 121 2 - vert 63 ( 0.7705429792 0.3359019756 ) 123 2 - vert 64 ( 0.8291239738 0.3502219915 ) 125 2 - vert 65 ( 0.8504869938 0.3203949928 ) 127 2 - vert 66 ( 0.8518949747 0.2674710155 ) 129 2 - vert 67 ( 0.9868850112 0.2257530093 ) 104 2 - vert 68 ( 0.6978790164 0.2378259897 ) 131 2 - vert 69 ( 0.6208519936 0.2722499967 ) 111 2 - vert 70 ( 0.7521319985 0.2731570005 ) 133 2 - vert 71 ( 0.8002240062 0.2661169767 ) 135 2 - vert 72 ( 0.9481599927 0.1637359858 ) 92 3 - vert 73 ( 0.8877660036 0.2655869722 ) 137 3 - vert 74 ( 0.9194560051 0.431253016 ) 140 1 - vert 75 ( 0.8858140111 0.437146008 ) 141 1 - vert 76 ( 0.9185770154 0.4885470271 ) 142 1 - vert 77 ( 0.9639430046 0.4419720173 ) 143 1 - vert 78 ( 0.9666029811 0.3753240108 ) 144 2 - vert 79 ( 0.8288000226 0.4139400125 ) 146 1 - vert 80 ( 0.8236029744 0.5281270146 ) 147 1 - vert 81 ( 0.7994019985 0.4632459879 ) 148 1 - vert 82 ( 0.7240790129 0.5179449916 ) 149 1 - vert 83 ( 0.8661630154 0.4761840105 ) 150 1 - vert 84 ( 0.8763030171 0.5435949564 ) 151 1 - vert 85 ( 0.9247879982 0.550902009 ) 152 2 - vert 86 ( 0.9755280018 0.5506340265 ) 154 2 - vert 87 ( 0.6661750078 0.514122963 ) 156 1 - vert 88 ( 0.6026859879 0.4316329956 ) 143 1 - vert 89 ( 0.6142709851 0.5402950048 ) 154 2 - vert 90 ( 0.6816210151 0.4320870042 ) 157 1 - vert 91 ( 0.7484120131 0.437286973 ) 158 1 - vert 92 ( 0.7095559835 0.3667910099 ) 159 1 - vert 93 ( 0.8737390041 0.6100530028 ) 160 2 - vert 94 ( 0.2043370008 0.9363080263 ) 162 1 - vert 95 ( 0.1917700022 0.9874539971 ) 163 1 - vert 96 ( 0.2633219957 0.9902449846 ) 164 2 - vert 97 ( 0.2603709996 0.9215610027 ) 166 2 - vert 98 ( 0.5906730294 0.3194029927 ) 168 3 - vert 99 ( 0.4789839983 0.3158739805 ) 171 3 - vert 100 ( 0.5928189754 0.3614609838 ) 174 3 - vert 101 ( 0.4638589919 0.3632079959 ) 177 4 - vert 102 ( 0.3933829963 0.2314299941 ) 181 4 - vert 103 ( 0.3337610066 0.2654590011 ) 185 4 - vert 104 ( 0.4113320112 0.2756440043 ) 189 3 - vert 105 ( 0.4921709895 0.2166209817 ) 192 4 - vert 106 ( 0.2187130004 0.899075985 ) 196 1 - vert 107 ( 0.2690410018 0.8628900051 ) 197 2 - vert 108 ( 0.1635289937 0.9143019915 ) 199 2 - vert 109 ( 0.1683640033 0.9854789972 ) 201 1 - vert 110 ( 0.1685930043 0.6515290141 ) 201 1 - vert 111 ( 0.183961004 0.6999030113 ) 202 1 - vert 112 ( 0.1921020001 0.6548619866 ) 163 1 - vert 113 ( 0.2800259888 0.1394820213 ) 203 6 - vert 114 ( 0.2225950062 0.1793789864 ) 209 4 - vert 115 ( 0.2875019908 0.2022629976 ) 213 5 - vert 116 ( 0.0627510026 0.8454350233 ) 218 4 - vert 117 ( 0.1106910035 0.8663179874 ) 222 4 - vert 118 ( 0.1359120011 0.8428989649 ) 226 3 - vert 119 ( 0.3136300147 0.1859080195 ) 229 4 - vert 120 ( 0.3304409981 0.2094860077 ) 233 4 - vert 121 ( 0.3729789853 0.1901649833 ) 237 4 - vert 122 ( 0.2999300063 0.8250650167 ) 241 2 - vert 123 ( 0.2727189958 0.799405992 ) 243 2 - vert 124 ( 0.2603009939 0.7136909962 ) 245 2 - vert 125 ( 0.2954480052 0.7122550011 ) 247 2 - vert 126 ( 0.263936013 0.6731899977 ) 164 2 - vert 127 ( 0.2846580148 0.9553740025 ) 249 2 - vert 128 ( 0.2911350131 0.9950889945 ) 251 2 - vert 129 ( 0.2938460112 0.9138000011 ) 253 2 - vert 130 ( 0.2402170002 0.80576998 ) 255 1 - vert 131 ( 0.2677659988 0.7409399748 ) 256 2 - vert 132 ( 0.2038889974 0.7419040203 ) 258 1 - vert 133 ( 0.2918660045 0.681499958 ) 251 2 - vert 134 ( 0.2776469886 0.2314630151 ) 259 4 - vert 135 ( 0.1722279936 0.216489017 ) 263 4 - vert 136 ( 0.1251160055 0.1187459826 ) 267 5 - vert 137 ( 0.0528450012 0.1990990043 ) 272 5 - vert 138 ( 0.5906730294 0.1368719935 ) 277 5 - vert 139 ( 0.4879179895 0.1192910075 ) 282 5 - vert 140 ( 0.4301300049 0.1652190089 ) 287 5 - vert 141 ( 0.0438820012 0.1111990213 ) 292 4 - vert 142 ( 0.1489060074 0.8846759796 ) 296 3 - vert 143 ( 0.111270003 0.9061470032 ) 203 6 - vert 144 ( 0.1432790011 0.9405339956 ) 229 4 - vert 145 ( 0.1273680031 0.9811329842 ) 237 4 - vert 146 ( 0.1274189949 0.6441459656 ) 237 4 - vert 147 ( 0.1018000022 0.7043390274 ) 299 3 - vert 148 ( 0.5450130105 0.0130950212 ) 302 4 - vert 149 ( 0.4139760137 0.0072669983 ) 306 3 - vert 150 ( 0.4659610093 0.0620489717 ) 309 3 - vert 151 ( 0.0793519989 0.6812579632 ) 287 5 - vert 152 ( 0.7798069715 0.1416540146 ) 312 1 - vert 153 ( 0.8238999844 0.147265017 ) 313 1 - vert 154 ( 0.6053469777 0.3649849892 ) 144 2 - vert 155 ( 0.8626490235 0.14854002 ) 314 1 - vert 156 ( 0.7214239836 0.0121629834 ) 315 3 - vert 157 ( 0.4749259949 0.5132960081 ) 318 3 - vert 158 ( 0.2387440056 0.1259409785 ) 321 4 - vert 159 ( 0.1477479935 0.2995790243 ) 325 6 - vert 160 ( 0.0602619983 0.3586530089 ) 331 6 - vert 161 ( 0.0577390008 0.3033360243 ) 337 5 - vert 162 ( 0.2883780003 0.5109490156 ) 342 3 - vert 163 ( 0.2241510004 0.5268880129 ) 345 2 - vert 164 ( 0.2785539925 0.6102370024 ) 347 1 - vert 165 ( 0.2345979959 0.6124429703 ) 348 1 - vert 166 ( 0.0755100027 0.8883000016 ) 349 4 - vert 167 ( 0.3054459989 0.0682489872 ) 353 4 - vert 168 ( 0.2569029927 0.0817170143 ) 357 3 - vert 169 ( 0.2879140079 0.0959659815 ) 349 4 - vert 170 ( 0.9253529906 0.6038390398 ) 360 2 - vert 171 ( 0.8402969837 0.6819820404 ) 34 3 - vert 172 ( 0.843535006 0.6373449564 ) 31 3 - vert 173 ( 0.7736589909 0.6870989799 ) 362 3 - vert 174 ( 0.8996700048 0.768558979 ) 362 3 - vert 175 ( 0.7821429968 0.6192190051 ) 365 3 - vert 176 ( 0.9902340174 0.7758809924 ) 365 3 - vert 177 ( 0.3528459966 0.465354979 ) 368 3 - vert 178 ( 0.4353789985 0.1116790175 ) 371 4 - vert 179 ( 0.0435540006 0.7115600109 ) 371 4 - vert 180 ( 0.062804997 0.7602419853 ) 375 3 - vert 181 ( 0.4038980007 0.0865809917 ) 378 4 - vert 182 ( 0.0159210004 0.7509840131 ) 378 4 - vert 183 ( 0.0442270003 0.8014060259 ) 382 4 - vert 184 ( 0.3621050119 0.0647630095 ) 386 4 - vert 185 ( 0.0077530001 0.8201950192 ) 386 4 - vert 186 ( 0.4858529866 0.2773119807 ) 390 3 - vert 187 ( 0.5906730294 0.2790259719 ) 393 3 - vert 188 ( 0.5906730294 0.2272719741 ) 396 3 - vert 189 ( 0.8384780288 0.8386750221 ) 42 3 - vert 190 ( 0.5007230043 0.8608759642 ) 399 1 - vert 191 ( 0.4004510045 0.8904989958 ) 400 1 - vert 192 ( 0.4774749875 0.898590982 ) 401 3 - vert 193 ( 0.4339909852 0.8469029665 ) 404 1 - vert 194 ( 0.5118749738 0.8208619952 ) 405 1 - vert 195 ( 0.4504519999 0.8016870022 ) 406 1 - vert 196 ( 0.519701004 0.7612500191 ) 407 1 - vert 197 ( 0.3528000116 0.7389389873 ) 408 1 - vert 198 ( 0.4434280097 0.7510669827 ) 409 1 - vert 199 ( 0.4215759933 0.7003450394 ) 410 1 - vert 200 ( 0.5172349811 0.7290819883 ) 411 1 - vert 201 ( 0.3455109894 0.7057470083 ) 412 1 - vert 202 ( 0.4768890142 0.9415969849 ) 413 1 - vert 203 ( 0.4011979997 0.933701992 ) 414 1 - vert 204 ( 0.4865309894 0.9777920246 ) 415 1 - vert 205 ( 0.5926210284 0.8259350061 ) 416 1 - vert 206 ( 0.570964992 0.8845490217 ) 417 2 - vert 207 ( 0.5789020061 0.8460580111 ) 419 2 - vert 208 ( 0.7997699976 0.9733999968 ) 421 3 - vert 209 ( 0.756724 0.9381579757 ) 424 3 - vert 210 ( 0.7890049815 0.9327999949 ) 419 2 - vert 211 ( 0.6045969725 0.8296480179 ) 427 2 - vert 212 ( 0.8025349975 0.8614699841 ) 416 1 - vert 213 ( 0.7491949797 0.9943079948 ) 429 2 - vert 214 ( 0.6942149997 0.9865270257 ) 431 1 - vert 215 ( 0.7694820166 0.828707993 ) 432 2 - vert 216 ( 0.8027639985 0.8125270009 ) 434 2 - vert 217 ( 0.7869669795 0.8019449711 ) 436 2 - vert 218 ( 0.5959810019 0.7842389941 ) 434 2 - vert 219 ( 0.6046180129 0.7234239578 ) 438 2 - vert 220 ( 0.6153159738 0.7025020123 ) 440 2 - vert 221 ( 0.8136299849 0.7713860273 ) 438 2 - vert 222 ( 0.7985380292 0.7631790042 ) 442 2 - vert 223 ( 0.6761140227 0.733044982 ) 444 3 - vert 224 ( 0.6491540074 0.7684370279 ) 447 3 - vert 225 ( 0.6686120033 0.7034319639 ) 450 2 - vert 226 ( 0.6734960079 0.9662230015 ) 452 1 - vert 227 ( 0.700568974 0.8474110365 ) 453 3 - vert 228 ( 0.7166720033 0.7589269876 ) 456 3 - vert 229 ( 0.74871701 0.7289980054 ) 459 2 - vert 230 ( 0.7685890198 0.7389019728 ) 450 2 - vert 231 ( 0.7017890215 0.775538981 ) 461 3 - vert 232 ( 0.7011880279 0.7465590239 ) 456 3 - vert 233 ( 0.6883950233 0.7056699991 ) 459 2 - vert 234 ( 0.6925330162 0.8118289709 ) 464 3 - vert 235 ( 0.6550170183 0.7908899784 ) 467 3 - vert 236 ( 0.6797599792 0.8512650132 ) 470 3 - vert 237 ( 0.707852006 0.8104299903 ) 473 3 - vert 238 ( 0.6074820161 0.7819190025 ) 476 2 - vert 239 ( 0.6490619779 0.9733939767 ) 478 1 - vert 240 ( 0.6052020192 0.9690830112 ) 479 2 - vert 241 ( 0.6357730031 0.8398550153 ) 481 2 - vert 242 ( 0.5714309812 0.828256011 ) 483 2 - vert 243 ( 0.5528270006 0.8322100043 ) 485 2 - vert 244 ( 0.5588089824 0.7859380245 ) 487 2 - vert 245 ( 0.5543259978 0.8860200047 ) 489 3 - vert 246 ( 0.5358489752 0.8347740173 ) 492 2 - vert 247 ( 0.5730850101 0.793734014 ) 494 2 - vert 248 ( 0.5840579867 0.8170059919 ) 496 2 - vert 249 ( 0.8161879778 0.8996319771 ) 494 2 - vert 250 ( 0.8266770244 0.8883939981 ) 487 2 - vert 251 ( 0.8267859817 0.9110990167 ) 498 2 - vert 252 ( 0.5714660287 0.952252984 ) 500 2 - vert 253 ( 0.5482320189 0.9537770152 ) 502 1 - vert 254 ( 0.5351210237 0.9507679939 ) 429 2 - vert 255 ( 0.5381690264 0.8871129751 ) 421 3 - vert 256 ( 0.818508029 0.9463310242 ) 492 2 - vert 257 ( 0.8036159873 0.9287400246 ) 496 2 - vert 258 ( 0.6376190186 0.781965971 ) 436 2 - vert 259 ( 0.6241390109 0.782755971 ) 503 2 - vert 260 ( 0.6422780156 0.7077629566 ) 442 2 - vert 261 ( 0.6305840015 0.7032589912 ) 505 2 - vert 262 ( 0.6214889884 0.8390759826 ) 507 2 - vert 263 ( 0.6353539824 0.8060629964 ) 432 2 - vert 264 ( 0.5176740289 0.8607789874 ) 479 2 - vert 265 ( 0.528603971 0.8226339817 ) 478 1 - vert 266 ( 0.5028409958 0.8987259865 ) 500 2 - vert 267 ( 0.5392010212 0.7466000319 ) 452 1 - vert 268 ( 0.5311419964 0.6905180216 ) 431 1 - vert 269 ( 0.5001900196 0.6796820164 ) 415 1 - vert 270 ( 0.5029720068 0.9707750082 ) 431 1 - vert 271 ( 0.4968389869 0.941429019 ) 429 2 - vert 272 ( 0.4974350035 0.9217699766 ) 502 1 - vert 273 ( 0.8029379845 0.7442569733 ) 505 2 - vert 274 ( 0.8184109926 0.7529680133 ) 440 2 - vert 275 ( 0.6204379797 0.7389010191 ) 509 2 - vert 276 ( 0.7697860003 0.7841470242 ) 447 3 - vert 277 ( 0.0282600001 0.8698080182 ) 353 4 - vert 278 ( 0.7053009868 0.2735130191 ) 511 2 - vert 279 ( 0.7590960264 0.2977690101 ) 513 2 - vert 280 ( 0.6963999867 0.2978109717 ) 515 2 - vert 281 ( 0.5461469889 0.7879520059 ) 498 2 - vert 282 ( 0.1138980016 0.8113780022 ) 517 3 - vert 283 ( 0.1950599998 0.120085001 ) 520 4 - vert 284 ( 0.2171940058 0.0655140281 ) 524 3 - vert 285 ( 0.2862679958 0.0446400046 ) 527 3 - vert 286 ( 0.1988579929 0.0277220011 ) 530 3 - vert 287 ( 0.3032990098 0.009904027 ) 533 3 - vert 288 ( 0.370352 0.0401480198 ) 536 3 - vert 289 ( 0.4060660005 0.9733899832 ) 410 1 - vert 290 ( 0.3027069867 0.7717610002 ) 539 2 - vert 291 ( 0.3240619898 0.7848359942 ) 541 2 - vert 292 ( 0.3004209995 0.7371799946 ) 543 2 - vert 293 ( 0.3276099861 0.7369199991 ) 545 2 - vert 294 ( 0.3222169876 0.9879009724 ) 547 2 - vert 295 ( 0.3231050074 0.6688380241 ) 547 2 - vert 296 ( 0.3229289949 0.7101849914 ) 549 2 - vert 297 ( 0.109232001 0.7468780279 ) 551 3 - vert 298 ( 0.1181280017 0.0632529855 ) 554 3 - vert 299 ( 0.1088190004 0.0349550247 ) 557 3 - vert 300 ( 0.0400529988 0.0509030223 ) 560 5 - vert 301 ( 0.0050969999 0.2059280276 ) 565 6 - vert 302 ( 0.0050969999 0.1247289777 ) 571 4 - vert 303 ( 0.0050969999 0.2996760011 ) 575 5 - vert 304 ( 0.0050969999 0.3579769731 ) 580 6 - vert 305 ( 0.0050969999 0.4193829894 ) 586 4 - vert 306 ( 0.0510179996 0.4332749844 ) 590 4 - vert 307 ( 0.0607799999 0.4337900281 ) 594 4 - vert 308 ( 0.1606809944 0.4493049979 ) 598 4 - vert 309 ( 0.1704750061 0.5299440026 ) 602 2 - vert 310 ( 0.0769840032 0.6088839769 ) 604 2 - vert 311 ( 0.169847995 0.6108210087 ) 606 2 - vert 312 ( 0.0709109977 0.5330560207 ) 608 3 - vert 313 ( 0.0581829995 0.5341030359 ) 315 3 - vert 314 ( 0.0459109992 0.5968589783 ) 611 2 - vert 315 ( 0.0282819998 0.5871779919 ) 84 2 - vert 316 ( 0.1733900011 0.62332201 ) 102 2 - vert 317 ( 0.0790690035 0.6173540354 ) 611 2 - vert 318 ( 0.1190219969 0.6439819932 ) 84 2 - vert 319 ( 0.2783190012 0.6204890013 ) 313 1 - vert 320 ( 0.2354460061 0.6233119965 ) 312 1 - vert 321 ( 0.907754004 0.1535429955 ) 613 1 - vert 322 ( 0.4578419924 0.6432880163 ) 613 1 - vert 323 ( 0.5928189754 0.6053659916 ) 614 4 - vert 324 ( 0.5928189754 0.5169570446 ) 618 4 - vert 325 ( 0.4667449892 0.4496610165 ) 622 3 - vert 326 ( 0.0050969999 0.5013149977 ) 625 5 - vert 327 ( 0.0268239994 0.5732979774 ) 86 4 - vert 328 ( 0.5537840128 0.7444770336 ) 86 4 - vert 329 ( 0.5908079743 0.6659530401 ) 630 4 - vert 330 ( 0.0050969999 0.5715099573 ) 634 3 - vert 331 ( 0.570381999 0.7390149832 ) 634 3 - vert 332 ( 0.5928189754 0.4565629959 ) 637 5 - vert 333 ( 0.4612129927 0.4114339948 ) 642 3 - vert 334 ( 0.3372229934 0.4129520059 ) 645 3 - vert 335 ( 0.5928189754 0.4105759859 ) 648 5 - vert 336 ( 0.9167770147 0.9147850275 ) 653 3 - vert 337 ( 0.8851889968 0.8249670267 ) 656 3 - vert 338 ( 0.9290639758 0.8345429897 ) 659 2 - vert 339 ( 0.6279270053 0.6710920334 ) 661 2 - vert 340 ( 0.633020997 0.6062430143 ) 663 2 - vert 341 ( 0.7075179815 0.6906809807 ) 665 2 - vert 342 ( 0.7152150273 0.6038039923 ) 667 3 - vert 343 ( 0.7982649803 0.6073759794 ) 670 2 - vert 344 ( 0.8113960028 0.5987670422 ) 672 3 - vert 345 ( 0.8745399714 0.622206986 ) 675 2 - vert 346 ( 0.7648239732 0.579185009 ) 677 3 - vert 347 ( 0.7108520269 0.5627390146 ) 680 4 - vert 348 ( 0.7324820161 0.5867669582 ) 656 3 - vert 349 ( 0.932197988 0.7495700121 ) 670 2 - vert 350 ( 0.9878820181 0.890460968 ) 667 3 - vert 351 ( 0.9349120259 0.6673409939 ) 675 2 - vert 352 ( 0.9803060293 0.6969209909 ) 684 3 - vert 353 ( 0.9712280035 0.640410006 ) 687 3 - vert 354 ( 0.8684700131 0.9948850274 ) 661 2 - vert 355 ( 0.8932440281 0.9510400295 ) 690 2 - vert 356 ( 0.9479979873 0.9782099724 ) 663 2 - vert 357 ( 0.8237410188 0.7295470238 ) 692 3 - vert 358 ( 0.8667160273 0.6727199554 ) 695 3 - vert 359 ( 0.8402420282 0.7758100033 ) 698 3 - vert 360 ( 0.6725640297 0.5599319935 ) 701 3 - vert 361 ( 0.683431983 0.5801969767 ) 692 3 - vert 362 ( 0.6523110271 0.593569994 ) 698 3 - vert 363 ( 0.9900910258 0.5969679952 ) 704 3 - vert 364 ( 0.9897819757 0.6107109785 ) 698 3 - vert 365 ( 0.9202200174 0.6185719967 ) 707 2 - vert 366 ( 0.8585289717 0.9232029915 ) 695 3 - vert 367 ( 0.6288350224 0.5866290331 ) 704 3 - vert 368 ( 0.9243559837 0.6973209977 ) 665 2 - vert 369 ( 0.8195310235 0.8209300041 ) 707 2 - vert 370 ( 0.8666120172 0.8175060153 ) 687 3 - vert 371 ( 0.9273049831 0.633498013 ) 707 2 - vert 372 ( 0.9103090167 0.6286840439 ) 661 2 - vert 373 ( 0.2510960102 0.3575590253 ) 709 5 - vert 374 ( 0.3748750091 0.3151479959 ) 714 5 - vert 375 ( 0.343088001 0.3657950163 ) 719 3 - vert 376 ( 0.248428002 0.4210450053 ) 722 3 - vert 377 ( 0.2626729906 0.3087499738 ) 725 7 - vert 378 ( 0.1585620046 0.358009994 ) 732 5 - vert 379 ( 0.6625279784 0.0512880087 ) 737 4 - vert 380 ( 0.7009400129 0.0962569714 ) 741 2 - vert 381 ( 0.6571320295 0.1524789929 ) 743 2 - vert 382 ( 0.620438993 0.0975469947 ) 745 3 - vert 383 ( 0.4563330114 0.6081140041 ) 748 3 - vert 384 ( 0.5378500223 0.6089279652 ) 751 3 - vert 385 ( 0.5527309775 0.6666370034 ) 745 3 - vert 386 ( 0.7084829807 0.1954429746 ) 754 1 - vert 387 ( 0.7453309894 0.1380500197 ) 755 2 - vert 388 ( 0.6256279945 0.2154139876 ) 757 2 - vert 389 ( 0.757035017 0.2478020191 ) 759 2 - vert 390 ( 0.3652400076 0.6079750061 ) 761 1 - vert 391 ( 0.3678930104 0.5143569708 ) 762 2 - vert 392 ( 0.9428480268 0.2738190293 ) 764 2 - vert 393 ( 0.9821090102 0.2825890183 ) 766 2 - vert 394 ( 0.926304996 0.3234940171 ) 768 2 - vert 395 ( 0.8848720193 0.3092319965 ) 770 2 - vert 396 ( 0.9194689989 0.3578289747 ) 772 1 - vert 397 ( 0.8797889948 0.3552349806 ) 773 1 - vert 398 ( 0.7705429792 0.3359019756 ) 774 2 - vert 399 ( 0.8046380281 0.291703999 ) 776 2 - vert 400 ( 0.8291239738 0.3502219915 ) 778 2 - vert 401 ( 0.8504869938 0.3203949928 ) 780 2 - vert 402 ( 0.8518949747 0.2674710155 ) 782 2 - vert 403 ( 0.9868850112 0.2257530093 ) 757 2 - vert 404 ( 0.6978790164 0.2378259897 ) 784 2 - vert 405 ( 0.6208519936 0.2722499967 ) 766 2 - vert 406 ( 0.7521319985 0.2731570005 ) 786 2 - vert 407 ( 0.8002240062 0.2661169767 ) 788 2 - vert 408 ( 0.8877660036 0.2655869722 ) 790 3 - vert 409 ( 0.9481599927 0.1637359858 ) 745 3 - vert 410 ( 0.8858140111 0.437146008 ) 793 1 - vert 411 ( 0.9194560051 0.431253016 ) 794 1 - vert 412 ( 0.9185770154 0.4885470271 ) 795 1 - vert 413 ( 0.9639430046 0.4419720173 ) 796 1 - vert 414 ( 0.9666029811 0.3753240108 ) 797 2 - vert 415 ( 0.8288000226 0.4139400125 ) 799 1 - vert 416 ( 0.7994019985 0.4632459879 ) 800 1 - vert 417 ( 0.8236029744 0.5281270146 ) 801 1 - vert 418 ( 0.7240790129 0.5179449916 ) 802 1 - vert 419 ( 0.8661630154 0.4761840105 ) 803 1 - vert 420 ( 0.8763030171 0.5435949564 ) 804 1 - vert 421 ( 0.9247879982 0.550902009 ) 805 2 - vert 422 ( 0.9755280018 0.5506340265 ) 807 2 - vert 423 ( 0.6026859879 0.4316329956 ) 796 1 - vert 424 ( 0.6661750078 0.514122963 ) 809 1 - vert 425 ( 0.6142709851 0.5402950048 ) 807 2 - vert 426 ( 0.6816210151 0.4320870042 ) 810 1 - vert 427 ( 0.7484120131 0.437286973 ) 811 1 - vert 428 ( 0.7095559835 0.3667910099 ) 812 1 - vert 429 ( 0.8737390041 0.6100530028 ) 813 2 - vert 430 ( 0.1917700022 0.9874539971 ) 815 1 - vert 431 ( 0.2043370008 0.9363080263 ) 816 1 - vert 432 ( 0.2633219957 0.9902449846 ) 817 2 - vert 433 ( 0.2603709996 0.9215610027 ) 819 2 - vert 434 ( 0.4789839983 0.3158739805 ) 821 3 - vert 435 ( 0.4638589919 0.3632079959 ) 824 4 - vert 436 ( 0.3337610066 0.2654590011 ) 828 4 - vert 437 ( 0.3933829963 0.2314299941 ) 832 4 - vert 438 ( 0.4113320112 0.2756440043 ) 836 3 - vert 439 ( 0.4921709895 0.2166209817 ) 839 4 - vert 440 ( 0.2187130004 0.899075985 ) 843 1 - vert 441 ( 0.2690410018 0.8628900051 ) 844 2 - vert 442 ( 0.1683640033 0.9854789972 ) 846 1 - vert 443 ( 0.1635289937 0.9143019915 ) 847 2 - vert 444 ( 0.183961004 0.6999030113 ) 849 1 - vert 445 ( 0.1685930043 0.6515290141 ) 846 1 - vert 446 ( 0.1921020001 0.6548619866 ) 815 1 - vert 447 ( 0.2225950062 0.1793789864 ) 850 4 - vert 448 ( 0.2800259888 0.1394820213 ) 854 6 - vert 449 ( 0.2875019908 0.2022629976 ) 860 5 - vert 450 ( 0.1106910035 0.8663179874 ) 865 4 - vert 451 ( 0.0627510026 0.8454350233 ) 869 4 - vert 452 ( 0.1359120011 0.8428989649 ) 873 3 - vert 453 ( 0.3136300147 0.1859080195 ) 876 4 - vert 454 ( 0.3304409981 0.2094860077 ) 880 4 - vert 455 ( 0.3729789853 0.1901649833 ) 884 4 - vert 456 ( 0.2727189958 0.799405992 ) 888 2 - vert 457 ( 0.2999300063 0.8250650167 ) 890 2 - vert 458 ( 0.2954480052 0.7122550011 ) 892 2 - vert 459 ( 0.2603009939 0.7136909962 ) 894 2 - vert 460 ( 0.263936013 0.6731899977 ) 817 2 - vert 461 ( 0.2846580148 0.9553740025 ) 896 2 - vert 462 ( 0.2911350131 0.9950889945 ) 898 2 - vert 463 ( 0.2938460112 0.9138000011 ) 900 2 - vert 464 ( 0.2402170002 0.80576998 ) 902 1 - vert 465 ( 0.2677659988 0.7409399748 ) 903 2 - vert 466 ( 0.2038889974 0.7419040203 ) 905 1 - vert 467 ( 0.2918660045 0.681499958 ) 898 2 - vert 468 ( 0.1722279936 0.216489017 ) 906 4 - vert 469 ( 0.2776469886 0.2314630151 ) 910 4 - vert 470 ( 0.0528450012 0.1990990043 ) 914 5 - vert 471 ( 0.1251160055 0.1187459826 ) 919 5 - vert 472 ( 0.4879179895 0.1192910075 ) 924 5 - vert 473 ( 0.4301300049 0.1652190089 ) 929 5 - vert 474 ( 0.0438820012 0.1111990213 ) 934 4 - vert 475 ( 0.111270003 0.9061470032 ) 854 6 - vert 476 ( 0.1489060074 0.8846759796 ) 938 3 - vert 477 ( 0.1432790011 0.9405339956 ) 876 4 - vert 478 ( 0.1273680031 0.9811329842 ) 884 4 - vert 479 ( 0.1018000022 0.7043390274 ) 941 3 - vert 480 ( 0.1274189949 0.6441459656 ) 884 4 - vert 481 ( 0.4139760137 0.0072669983 ) 944 3 - vert 482 ( 0.4659610093 0.0620489717 ) 947 3 - vert 483 ( 0.0793519989 0.6812579632 ) 929 5 - vert 484 ( 0.7798069715 0.1416540146 ) 950 1 - vert 485 ( 0.8238999844 0.147265017 ) 951 1 - vert 486 ( 0.6053469777 0.3649849892 ) 797 2 - vert 487 ( 0.8626490235 0.14854002 ) 952 1 - vert 488 ( 0.7214239836 0.0121629834 ) 953 3 - vert 489 ( 0.4749259949 0.5132960081 ) 956 3 - vert 490 ( 0.2387440056 0.1259409785 ) 959 4 - vert 491 ( 0.1477479935 0.2995790243 ) 963 6 - vert 492 ( 0.0602619983 0.3586530089 ) 969 6 - vert 493 ( 0.0577390008 0.3033360243 ) 975 5 - vert 494 ( 0.2241510004 0.5268880129 ) 980 2 - vert 495 ( 0.2883780003 0.5109490156 ) 982 3 - vert 496 ( 0.2785539925 0.6102370024 ) 985 1 - vert 497 ( 0.2345979959 0.6124429703 ) 986 1 - vert 498 ( 0.0755100027 0.8883000016 ) 987 4 - vert 499 ( 0.2569029927 0.0817170143 ) 991 3 - vert 500 ( 0.3054459989 0.0682489872 ) 994 4 - vert 501 ( 0.2879140079 0.0959659815 ) 987 4 - vert 502 ( 0.9253529906 0.6038390398 ) 998 2 - vert 503 ( 0.843535006 0.6373449564 ) 684 3 - vert 504 ( 0.8402969837 0.6819820404 ) 687 3 - vert 505 ( 0.7736589909 0.6870989799 ) 1000 3 - vert 506 ( 0.8996700048 0.768558979 ) 1000 3 - vert 507 ( 0.7821429968 0.6192190051 ) 1003 3 - vert 508 ( 0.9902340174 0.7758809924 ) 1003 3 - vert 509 ( 0.3528459966 0.465354979 ) 1006 3 - vert 510 ( 0.4353789985 0.1116790175 ) 1009 4 - vert 511 ( 0.0435540006 0.7115600109 ) 1009 4 - vert 512 ( 0.062804997 0.7602419853 ) 1013 3 - vert 513 ( 0.4038980007 0.0865809917 ) 1016 4 - vert 514 ( 0.0159210004 0.7509840131 ) 1016 4 - vert 515 ( 0.0442270003 0.8014060259 ) 1020 4 - vert 516 ( 0.3621050119 0.0647630095 ) 1024 4 - vert 517 ( 0.0077530001 0.8201950192 ) 1024 4 - vert 518 ( 0.4858529866 0.2773119807 ) 1028 3 - vert 519 ( 0.8384780288 0.8386750221 ) 692 3 - vert 520 ( 0.4004510045 0.8904989958 ) 1031 1 - vert 521 ( 0.5007230043 0.8608759642 ) 1032 1 - vert 522 ( 0.4774749875 0.898590982 ) 1033 3 - vert 523 ( 0.4339909852 0.8469029665 ) 1036 1 - vert 524 ( 0.5118749738 0.8208619952 ) 1037 1 - vert 525 ( 0.4504519999 0.8016870022 ) 1038 1 - vert 526 ( 0.519701004 0.7612500191 ) 1039 1 - vert 527 ( 0.3528000116 0.7389389873 ) 1040 1 - vert 528 ( 0.4434280097 0.7510669827 ) 1041 1 - vert 529 ( 0.4215759933 0.7003450394 ) 1042 1 - vert 530 ( 0.5172349811 0.7290819883 ) 1043 1 - vert 531 ( 0.3455109894 0.7057470083 ) 1044 1 - vert 532 ( 0.4011979997 0.933701992 ) 1045 1 - vert 533 ( 0.4768890142 0.9415969849 ) 1046 1 - vert 534 ( 0.4865309894 0.9777920246 ) 1047 1 - vert 535 ( 0.570964992 0.8845490217 ) 1048 2 - vert 536 ( 0.5926210284 0.8259350061 ) 1050 1 - vert 537 ( 0.5789020061 0.8460580111 ) 1051 2 - vert 538 ( 0.756724 0.9381579757 ) 1053 3 - vert 539 ( 0.7997699976 0.9733999968 ) 1056 3 - vert 540 ( 0.7890049815 0.9327999949 ) 1051 2 - vert 541 ( 0.6045969725 0.8296480179 ) 1059 1 - vert 542 ( 0.8025349975 0.8614699841 ) 1050 1 - vert 543 ( 0.6942149997 0.9865270257 ) 1060 1 - vert 544 ( 0.7491949797 0.9943079948 ) 1061 2 - vert 545 ( 0.7694820166 0.828707993 ) 1063 2 - vert 546 ( 0.8027639985 0.8125270009 ) 1065 1 - vert 547 ( 0.7869669795 0.8019449711 ) 1066 2 - vert 548 ( 0.6046180129 0.7234239578 ) 1068 2 - vert 549 ( 0.5959810019 0.7842389941 ) 1065 1 - vert 550 ( 0.6153159738 0.7025020123 ) 1070 2 - vert 551 ( 0.8136299849 0.7713860273 ) 1068 2 - vert 552 ( 0.7985380292 0.7631790042 ) 1072 2 - vert 553 ( 0.6491540074 0.7684370279 ) 1074 2 - vert 554 ( 0.6761140227 0.733044982 ) 1076 2 - vert 555 ( 0.6686120033 0.7034319639 ) 1078 2 - vert 556 ( 0.6734960079 0.9662230015 ) 1080 1 - vert 557 ( 0.700568974 0.8474110365 ) 1081 3 - vert 558 ( 0.74871701 0.7289980054 ) 1084 2 - vert 559 ( 0.7166720033 0.7589269876 ) 1086 3 - vert 560 ( 0.7685890198 0.7389019728 ) 1078 2 - vert 561 ( 0.7017890215 0.775538981 ) 1089 3 - vert 562 ( 0.7011880279 0.7465590239 ) 1086 3 - vert 563 ( 0.6883950233 0.7056699991 ) 1084 2 - vert 564 ( 0.6925330162 0.8118289709 ) 1092 3 - vert 565 ( 0.6550170183 0.7908899784 ) 1095 2 - vert 566 ( 0.6797599792 0.8512650132 ) 1097 3 - vert 567 ( 0.707852006 0.8104299903 ) 1100 3 - vert 568 ( 0.6074820161 0.7819190025 ) 1103 2 - vert 569 ( 0.6490619779 0.9733939767 ) 1105 1 - vert 570 ( 0.6052020192 0.9690830112 ) 1106 2 - vert 571 ( 0.6357730031 0.8398550153 ) 1108 2 - vert 572 ( 0.5528270006 0.8322100043 ) 1110 2 - vert 573 ( 0.5714309812 0.828256011 ) 1112 2 - vert 574 ( 0.5588089824 0.7859380245 ) 1114 2 - vert 575 ( 0.5543259978 0.8860200047 ) 1116 3 - vert 576 ( 0.5358489752 0.8347740173 ) 1119 2 - vert 577 ( 0.5730850101 0.793734014 ) 1121 2 - vert 578 ( 0.5840579867 0.8170059919 ) 1123 2 - vert 579 ( 0.8266770244 0.8883939981 ) 1114 2 - vert 580 ( 0.8161879778 0.8996319771 ) 1121 2 - vert 581 ( 0.8267859817 0.9110990167 ) 1125 2 - vert 582 ( 0.5714660287 0.952252984 ) 1127 2 - vert 583 ( 0.5351210237 0.9507679939 ) 1061 2 - vert 584 ( 0.5482320189 0.9537770152 ) 1129 1 - vert 585 ( 0.5381690264 0.8871129751 ) 1056 3 - vert 586 ( 0.818508029 0.9463310242 ) 1119 2 - vert 587 ( 0.8036159873 0.9287400246 ) 1123 2 - vert 588 ( 0.6241390109 0.782755971 ) 1130 2 - vert 589 ( 0.6376190186 0.781965971 ) 1066 2 - vert 590 ( 0.6422780156 0.7077629566 ) 1072 2 - vert 591 ( 0.6305840015 0.7032589912 ) 1132 2 - vert 592 ( 0.6214889884 0.8390759826 ) 1134 2 - vert 593 ( 0.6353539824 0.8060629964 ) 1063 2 - vert 594 ( 0.5176740289 0.8607789874 ) 1106 2 - vert 595 ( 0.528603971 0.8226339817 ) 1105 1 - vert 596 ( 0.5028409958 0.8987259865 ) 1127 2 - vert 597 ( 0.5392010212 0.7466000319 ) 1080 1 - vert 598 ( 0.5311419964 0.6905180216 ) 1060 1 - vert 599 ( 0.5001900196 0.6796820164 ) 1047 1 - vert 600 ( 0.5029720068 0.9707750082 ) 1060 1 - vert 601 ( 0.4968389869 0.941429019 ) 1061 2 - vert 602 ( 0.4974350035 0.9217699766 ) 1129 1 - vert 603 ( 0.8029379845 0.7442569733 ) 1132 2 - vert 604 ( 0.8184109926 0.7529680133 ) 1070 2 - vert 605 ( 0.6204379797 0.7389010191 ) 1136 2 - vert 606 ( 0.7697860003 0.7841470242 ) 1074 2 - vert 607 ( 0.0282600001 0.8698080182 ) 994 4 - vert 608 ( 0.7053009868 0.2735130191 ) 1138 2 - vert 609 ( 0.7590960264 0.2977690101 ) 1140 2 - vert 610 ( 0.6963999867 0.2978109717 ) 1142 2 - vert 611 ( 0.5461469889 0.7879520059 ) 1125 2 - vert 612 ( 0.1138980016 0.8113780022 ) 1144 3 - vert 613 ( 0.1950599998 0.120085001 ) 1147 4 - vert 614 ( 0.2171940058 0.0655140281 ) 1151 3 - vert 615 ( 0.2862679958 0.0446400046 ) 1154 3 - vert 616 ( 0.1988579929 0.0277220011 ) 1157 3 - vert 617 ( 0.3032990098 0.009904027 ) 1160 3 - vert 618 ( 0.370352 0.0401480198 ) 1163 3 - vert 619 ( 0.4060660005 0.9733899832 ) 1042 1 - vert 620 ( 0.3027069867 0.7717610002 ) 1166 2 - vert 621 ( 0.3240619898 0.7848359942 ) 1168 2 - vert 622 ( 0.3004209995 0.7371799946 ) 1170 2 - vert 623 ( 0.3276099861 0.7369199991 ) 1172 2 - vert 624 ( 0.3222169876 0.9879009724 ) 1174 2 - vert 625 ( 0.3231050074 0.6688380241 ) 1174 2 - vert 626 ( 0.3229289949 0.7101849914 ) 1176 2 - vert 627 ( 0.109232001 0.7468780279 ) 1178 3 - vert 628 ( 0.1181280017 0.0632529855 ) 1181 3 - vert 629 ( 0.1088190004 0.0349550247 ) 1184 3 - vert 630 ( 0.0510179996 0.4332749844 ) 1187 4 - vert 631 ( 0.0607799999 0.4337900281 ) 1191 4 - vert 632 ( 0.1606809944 0.4493049979 ) 1195 4 - vert 633 ( 0.0769840032 0.6088839769 ) 1199 2 - vert 634 ( 0.1704750061 0.5299440026 ) 1201 2 - vert 635 ( 0.169847995 0.6108210087 ) 1203 2 - vert 636 ( 0.0709109977 0.5330560207 ) 1205 3 - vert 637 ( 0.0581829995 0.5341030359 ) 953 3 - vert 638 ( 0.0459109992 0.5968589783 ) 1208 2 - vert 639 ( 0.0282819998 0.5871779919 ) 741 2 - vert 640 ( 0.1733900011 0.62332201 ) 755 2 - vert 641 ( 0.0790690035 0.6173540354 ) 1208 2 - vert 642 ( 0.1190219969 0.6439819932 ) 741 2 - vert 643 ( 0.2783190012 0.6204890013 ) 951 1 - vert 644 ( 0.2354460061 0.6233119965 ) 950 1 - vert 645 ( 0.907754004 0.1535429955 ) 1210 1 - vert 646 ( 0.4578419924 0.6432880163 ) 1210 1 - vert 647 ( 0.4667449892 0.4496610165 ) 1211 3 - vert 648 ( 0.0268239994 0.5732979774 ) 737 4 - vert 649 ( 0.5537840128 0.7444770336 ) 737 4 - vert 650 ( 0.3372229934 0.4129520059 ) 1214 3 - vert 651 ( 0.4612129927 0.4114339948 ) 1217 3 - vert 652 ( 0.787711978 0.1272839904 ) 530 3 - vert 653 ( 0.787711978 0.0184599757 ) 1157 3 - vert 654 ( 0.7402999997 0.0408120155 ) 1184 3 - vert 655 ( 0.7402999997 0.1049320102 ) 557 3 - vert 656 ( 0.7172859907 0.0728719831 ) 560 5 - vert 657 ( 0.8670870066 0.0085620284 ) 1160 3 - vert 658 ( 0.8670870066 0.1371819973 ) 533 3 - vert 659 ( 0.9375870228 0.0269309878 ) 944 3 - vert 660 ( 0.9375870228 0.1188129783 ) 306 3 - vert 661 ( 0.9744899869 0.0728719831 ) 302 4 - vert 662 ( 0.3585230112 0.6269749999 ) 314 1 - vert 663 ( 0.3585230112 0.6269749999 ) 952 1 - - numtris 966 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 5 3 6 - tri 3 9 8 7 - tri 4 8 10 7 - tri 5 12 11 10 - tri 6 14 2 13 - tri 7 16 13 15 - tri 8 17 16 15 - tri 9 20 19 18 - tri 10 20 18 1 - tri 11 14 20 2 - tri 12 20 1 2 - tri 13 23 22 21 - tri 14 26 25 24 - tri 15 29 28 27 - tri 16 18 30 1 - tri 17 31 25 26 - tri 18 32 23 21 - tri 19 34 33 23 - tri 20 17 15 35 - tri 21 19 30 18 - tri 22 32 21 36 - tri 23 39 38 37 - tri 24 40 38 39 - tri 25 42 41 38 - tri 26 45 44 43 - tri 27 45 46 44 - tri 28 49 48 47 - tri 29 50 45 43 - tri 30 50 43 51 - tri 31 52 46 45 - tri 32 53 50 51 - tri 33 48 55 54 - tri 34 58 57 56 - tri 35 60 59 58 - tri 36 60 61 59 - tri 37 64 63 62 - tri 38 64 62 65 - tri 39 65 66 59 - tri 40 61 65 59 - tri 41 56 57 67 - tri 42 69 52 68 - tri 43 68 52 50 - tri 44 70 68 53 - tri 45 62 71 66 - tri 46 70 53 71 - tri 47 57 73 72 - tri 48 57 72 67 - tri 49 52 45 50 - tri 50 68 50 53 - tri 51 65 62 66 - tri 52 59 66 73 - tri 53 58 59 73 - tri 54 58 73 57 - tri 55 76 75 74 - tri 56 76 74 77 - tri 57 78 58 56 - tri 58 79 63 64 - tri 59 79 64 61 - tri 60 61 64 65 - tri 61 75 61 60 - tri 62 74 75 60 - tri 63 74 60 78 - tri 64 78 60 58 - tri 65 82 81 80 - tri 66 80 81 83 - tri 67 84 80 83 - tri 68 84 83 75 - tri 69 84 75 76 - tri 70 85 84 76 - tri 71 86 85 76 - tri 72 86 76 77 - tri 73 89 88 87 - tri 74 87 88 90 - tri 75 82 91 81 - tri 76 91 92 63 - tri 77 83 81 79 - tri 78 83 79 75 - tri 79 75 79 61 - tri 80 77 74 78 - tri 81 90 92 91 - tri 82 31 89 25 - tri 83 25 89 87 - tri 84 25 82 11 - tri 85 25 87 82 - tri 86 10 11 82 - tri 87 10 82 80 - tri 88 7 10 80 - tri 89 7 80 84 - tri 90 93 7 84 - tri 91 96 95 94 - tri 92 96 94 97 - tri 93 100 99 98 - tri 94 101 99 100 - tri 95 104 103 102 - tri 96 38 41 37 - tri 97 37 41 103 - tri 98 104 102 105 - tri 99 37 103 104 - tri 100 39 37 101 - tri 101 97 94 106 - tri 102 97 106 107 - tri 103 94 109 108 - tri 104 95 109 94 - tri 105 112 111 110 - tri 106 115 114 113 - tri 107 118 117 116 - tri 108 115 113 119 - tri 109 120 115 119 - tri 110 120 119 121 - tri 111 107 123 122 - tri 112 126 125 124 - tri 113 128 96 127 - tri 114 127 96 97 - tri 115 127 97 129 - tri 116 129 97 107 - tri 117 107 118 130 - tri 118 124 131 111 - tri 119 125 131 124 - tri 120 131 132 111 - tri 121 133 125 126 - tri 122 107 130 123 - tri 123 41 135 134 - tri 124 41 134 103 - tri 125 134 120 102 - tri 126 103 134 102 - tri 127 135 137 136 - tri 128 105 139 138 - tri 129 102 140 105 - tri 130 105 140 139 - tri 131 134 135 114 - tri 132 102 121 140 - tri 133 102 120 121 - tri 134 137 141 136 - tri 135 135 136 114 - tri 136 108 143 142 - tri 137 109 144 108 - tri 138 109 145 144 - tri 139 110 147 146 - tri 140 110 111 147 - tri 141 144 143 108 - tri 142 143 117 142 - tri 143 150 149 148 - tri 144 138 139 150 - tri 145 138 150 148 - tri 146 146 147 151 - tri 147 134 115 120 - tri 148 134 114 115 - tri 149 142 117 118 - tri 150 71 53 152 - tri 151 53 51 152 - tri 152 71 152 153 - tri 153 88 92 90 - tri 154 88 154 92 - tri 155 71 153 66 - tri 156 73 66 155 - tri 157 66 153 155 - tri 158 24 11 12 - tri 159 24 25 11 - tri 160 43 44 156 - tri 161 48 54 157 - tri 162 114 158 113 - tri 163 160 159 42 - tri 164 161 137 159 - tri 165 160 161 159 - tri 166 42 159 41 - tri 167 41 159 135 - tri 168 159 137 135 - tri 169 164 163 162 - tri 170 165 163 164 - tri 171 163 40 162 - tri 172 143 166 117 - tri 173 169 168 167 - tri 174 29 9 93 - tri 175 29 93 170 - tri 176 8 12 10 - tri 177 2 0 13 - tri 178 29 170 28 - tri 179 9 7 93 - tri 180 87 90 91 - tri 181 87 91 82 - tri 182 170 93 85 - tri 183 93 84 85 - tri 184 28 85 86 - tri 185 28 170 85 - tri 186 173 172 171 - tri 187 174 34 23 - tri 188 174 23 32 - tri 189 173 5 6 - tri 190 173 6 175 - tri 191 14 13 176 - tri 192 176 13 16 - tri 193 173 175 172 - tri 194 162 177 54 - tri 195 107 142 118 - tri 196 106 142 107 - tri 197 94 108 106 - tri 198 106 108 142 - tri 199 139 178 150 - tri 200 140 178 139 - tri 201 151 147 179 - tri 202 147 180 179 - tri 203 178 181 150 - tri 204 179 180 182 - tri 205 180 183 182 - tri 206 181 184 150 - tri 207 182 183 185 - tri 208 99 37 104 - tri 209 101 37 99 - tri 210 98 99 186 - tri 211 99 104 186 - tri 212 186 104 105 - tri 213 98 186 187 - tri 214 187 186 105 - tri 215 187 105 188 - tri 216 188 105 138 - tri 217 30 0 1 - tri 218 30 189 0 - tri 219 192 191 190 - tri 220 194 190 193 - tri 221 190 191 193 - tri 222 196 194 195 - tri 223 194 193 195 - tri 224 198 195 197 - tri 225 200 198 199 - tri 226 198 197 201 - tri 227 199 198 201 - tri 228 195 193 122 - tri 229 204 203 202 - tri 230 207 206 205 - tri 231 210 209 208 - tri 232 205 206 211 - tri 233 210 212 209 - tri 234 209 214 213 - tri 235 216 215 212 - tri 236 216 217 215 - tri 237 220 219 218 - tri 238 221 217 216 - tri 239 222 217 221 - tri 240 225 224 223 - tri 241 227 226 214 - tri 242 218 205 211 - tri 243 230 229 228 - tri 244 232 223 231 - tri 245 233 223 232 - tri 246 223 234 231 - tri 247 223 235 234 - tri 248 227 234 236 - tri 249 237 234 227 - tri 250 231 234 237 - tri 251 218 211 238 - tri 252 220 218 238 - tri 253 225 223 233 - tri 254 227 236 226 - tri 255 236 239 226 - tri 256 211 206 240 - tri 257 241 240 239 - tri 258 209 213 208 - tri 259 244 243 242 - tri 260 246 245 243 - tri 261 244 242 247 - tri 262 247 242 248 - tri 263 251 250 249 - tri 264 245 252 206 - tri 265 206 252 240 - tri 266 255 254 253 - tri 267 246 255 245 - tri 268 257 208 256 - tri 269 242 206 207 - tri 270 260 259 258 - tri 271 261 259 260 - tri 272 236 241 239 - tri 273 248 242 207 - tri 274 257 210 208 - tri 275 235 241 236 - tri 276 234 235 236 - tri 277 263 262 241 - tri 278 262 240 241 - tri 279 211 240 262 - tri 280 203 129 191 - tri 281 191 129 107 - tri 282 264 190 194 - tri 283 265 264 194 - tri 284 196 265 194 - tri 285 192 190 266 - tri 286 266 190 264 - tri 287 267 265 196 - tri 288 269 268 200 - tri 289 200 268 267 - tri 290 200 267 196 - tri 291 204 202 270 - tri 292 255 252 245 - tri 293 255 253 252 - tri 294 227 214 209 - tri 295 202 271 270 - tri 296 202 272 271 - tri 297 272 192 266 - tri 298 202 192 272 - tri 299 227 209 215 - tri 300 215 209 212 - tri 301 263 259 262 - tri 302 258 259 263 - tri 303 274 273 221 - tri 304 273 222 221 - tri 305 275 238 259 - tri 306 261 275 259 - tri 307 220 275 261 - tri 308 220 238 275 - tri 309 224 241 235 - tri 310 224 263 241 - tri 311 223 224 235 - tri 312 230 228 237 - tri 313 228 231 237 - tri 314 237 215 276 - tri 315 237 227 215 - tri 316 230 237 276 - tri 317 238 262 259 - tri 318 238 211 262 - tri 319 191 107 193 - tri 320 193 107 122 - tri 321 202 203 192 - tri 322 192 203 191 - tri 323 203 127 129 - tri 324 116 185 183 - tri 325 116 277 185 - tri 326 81 63 79 - tri 327 81 91 63 - tri 328 69 68 278 - tri 329 278 68 70 - tri 330 279 278 70 - tri 331 279 70 71 - tri 332 279 71 62 - tri 333 63 279 62 - tri 334 92 279 63 - tri 335 154 69 280 - tri 336 280 69 278 - tri 337 280 278 279 - tri 338 92 280 279 - tri 339 154 280 92 - tri 340 243 206 242 - tri 341 243 245 206 - tri 342 244 246 243 - tri 343 281 246 244 - tri 344 251 257 256 - tri 345 251 249 257 - tri 346 132 130 282 - tri 347 130 118 282 - tri 348 118 116 282 - tri 349 117 277 116 - tri 350 117 166 277 - tri 351 113 158 169 - tri 352 158 168 169 - tri 353 282 183 180 - tri 354 282 116 183 - tri 355 158 283 168 - tri 356 114 283 158 - tri 357 114 136 283 - tri 358 168 284 167 - tri 359 283 284 168 - tri 360 167 285 184 - tri 361 284 285 167 - tri 362 284 286 285 - tri 363 285 286 287 - tri 364 150 184 288 - tri 365 285 288 184 - tri 366 285 287 288 - tri 367 288 287 149 - tri 368 150 288 149 - tri 369 204 289 203 - tri 370 269 200 199 - tri 371 200 196 198 - tri 372 196 195 198 - tri 373 131 123 130 - tri 374 131 130 132 - tri 375 136 284 283 - tri 376 291 122 290 - tri 377 290 122 123 - tri 378 131 290 123 - tri 379 292 290 131 - tri 380 125 292 131 - tri 381 293 290 292 - tri 382 125 293 292 - tri 383 293 291 290 - tri 384 197 291 293 - tri 385 289 294 203 - tri 386 199 201 295 - tri 387 294 128 127 - tri 388 203 294 127 - tri 389 296 293 125 - tri 390 295 296 133 - tri 391 133 296 125 - tri 392 201 197 293 - tri 393 201 293 296 - tri 394 295 201 296 - tri 395 195 122 291 - tri 396 195 291 197 - tri 397 126 124 112 - tri 398 124 111 112 - tri 399 132 282 297 - tri 400 297 282 180 - tri 401 147 297 180 - tri 402 111 297 147 - tri 403 111 132 297 - tri 404 141 298 136 - tri 405 298 300 299 - tri 406 136 298 284 - tri 407 298 286 284 - tri 408 298 299 286 - tri 409 301 141 137 - tri 410 301 302 141 - tri 411 161 303 137 - tri 412 303 301 137 - tri 413 160 304 161 - tri 414 304 303 161 - tri 415 306 305 304 - tri 416 306 304 160 - tri 417 141 300 298 - tri 418 302 300 141 - tri 419 307 306 160 - tri 420 308 307 160 - tri 421 308 160 42 - tri 422 311 310 309 - tri 423 310 312 309 - tri 424 312 308 309 - tri 425 312 307 308 - tri 426 313 306 312 - tri 427 312 306 307 - tri 428 314 313 312 - tri 429 314 312 310 - tri 430 40 42 38 - tri 431 308 42 40 - tri 432 315 313 314 - tri 433 316 310 311 - tri 434 316 317 310 - tri 435 316 318 317 - tri 436 163 308 40 - tri 437 309 308 163 - tri 438 311 309 163 - tri 439 165 311 163 - tri 440 165 164 319 - tri 441 165 319 320 - tri 442 316 311 165 - tri 443 316 165 320 - tri 444 55 162 54 - tri 445 164 162 55 - tri 446 162 40 177 - tri 447 73 155 321 - tri 448 322 48 49 - tri 449 73 321 72 - tri 450 47 48 157 - tri 451 47 324 323 - tri 452 47 157 324 - tri 453 54 177 157 - tri 454 157 177 325 - tri 455 327 326 313 - tri 456 49 47 323 - tri 457 49 329 328 - tri 458 49 323 329 - tri 459 327 330 326 - tri 460 329 331 328 - tri 461 326 305 306 - tri 462 313 326 306 - tri 463 324 157 332 - tri 464 157 325 332 - tri 465 325 334 333 - tri 466 177 334 325 - tri 467 333 39 101 - tri 468 334 39 333 - tri 469 333 101 335 - tri 470 335 101 100 - tri 471 332 325 333 - tri 472 332 333 335 - tri 473 40 39 334 - tri 474 177 40 334 - tri 475 338 337 336 - tri 476 341 340 339 - tri 477 341 342 340 - tri 478 345 344 343 - tri 479 343 344 346 - tri 480 348 346 347 - tri 481 350 349 338 - tri 482 352 351 349 - tri 483 353 351 352 - tri 484 356 355 354 - tri 485 356 336 355 - tri 486 350 338 356 - tri 487 356 338 336 - tri 488 359 358 357 - tri 489 362 361 360 - tri 490 365 364 363 - tri 491 355 336 366 - tri 492 367 362 360 - tri 493 368 358 359 - tri 494 370 359 369 - tri 495 353 371 351 - tri 496 354 355 366 - tri 497 368 372 358 - tri 498 375 374 373 - tri 499 376 375 373 - tri 500 378 373 377 - tri 501 381 380 379 - tri 502 381 379 382 - tri 503 385 384 383 - tri 504 386 380 381 - tri 505 386 387 380 - tri 506 388 381 382 - tri 507 389 387 386 - tri 508 383 391 390 - tri 509 394 393 392 - tri 510 396 394 395 - tri 511 396 395 397 - tri 512 400 399 398 - tri 513 400 401 399 - tri 514 401 395 402 - tri 515 397 395 401 - tri 516 393 403 392 - tri 517 405 404 388 - tri 518 404 386 388 - tri 519 406 389 404 - tri 520 399 402 407 - tri 521 406 407 389 - tri 522 392 409 408 - tri 523 392 403 409 - tri 524 388 386 381 - tri 525 404 389 386 - tri 526 401 402 399 - tri 527 395 408 402 - tri 528 394 408 395 - tri 529 394 392 408 - tri 530 412 411 410 - tri 531 412 413 411 - tri 532 414 393 394 - tri 533 415 400 398 - tri 534 415 397 400 - tri 535 397 401 400 - tri 536 410 396 397 - tri 537 411 396 410 - tri 538 411 414 396 - tri 539 414 394 396 - tri 540 418 417 416 - tri 541 417 419 416 - tri 542 420 419 417 - tri 543 420 410 419 - tri 544 420 412 410 - tri 545 421 412 420 - tri 546 422 412 421 - tri 547 422 413 412 - tri 548 425 424 423 - tri 549 424 426 423 - tri 550 418 416 427 - tri 551 427 398 428 - tri 552 419 415 416 - tri 553 419 410 415 - tri 554 410 397 415 - tri 555 413 414 411 - tri 556 426 427 428 - tri 557 367 360 425 - tri 558 360 424 425 - tri 559 360 347 418 - tri 560 360 418 424 - tri 561 346 418 347 - tri 562 346 417 418 - tri 563 344 417 346 - tri 564 344 420 417 - tri 565 429 420 344 - tri 566 432 431 430 - tri 567 432 433 431 - tri 568 100 98 434 - tri 569 435 100 434 - tri 570 438 437 436 - tri 571 373 374 377 - tri 572 374 436 377 - tri 573 438 439 437 - tri 574 374 438 436 - tri 575 375 435 374 - tri 576 433 440 431 - tri 577 433 441 440 - tri 578 431 443 442 - tri 579 430 431 442 - tri 580 446 445 444 - tri 581 449 448 447 - tri 582 452 451 450 - tri 583 449 453 448 - tri 584 454 453 449 - tri 585 454 455 453 - tri 586 441 457 456 - tri 587 460 459 458 - tri 588 462 461 432 - tri 589 461 433 432 - tri 590 461 463 433 - tri 591 463 441 433 - tri 592 441 464 452 - tri 593 459 444 465 - tri 594 458 459 465 - tri 595 465 444 466 - tri 596 467 460 458 - tri 597 441 456 464 - tri 598 377 469 468 - tri 599 377 436 469 - tri 600 469 437 454 - tri 601 436 437 469 - tri 602 468 471 470 - tri 603 439 138 472 - tri 604 437 439 473 - tri 605 439 472 473 - tri 606 469 447 468 - tri 607 437 473 455 - tri 608 437 455 454 - tri 609 470 471 474 - tri 610 468 447 471 - tri 611 443 476 475 - tri 612 442 443 477 - tri 613 442 477 478 - tri 614 445 480 479 - tri 615 445 479 444 - tri 616 477 443 475 - tri 617 475 476 450 - tri 618 482 148 481 - tri 619 138 482 472 - tri 620 138 148 482 - tri 621 480 483 479 - tri 622 469 454 449 - tri 623 469 449 447 - tri 624 476 452 450 - tri 625 407 484 389 - tri 626 389 484 387 - tri 627 407 485 484 - tri 628 423 426 428 - tri 629 423 428 486 - tri 630 407 402 485 - tri 631 408 487 402 - tri 632 402 487 485 - tri 633 361 348 347 - tri 634 361 347 360 - tri 635 380 488 379 - tri 636 383 489 391 - tri 637 447 448 490 - tri 638 492 378 491 - tri 639 493 491 470 - tri 640 492 491 493 - tri 641 378 377 491 - tri 642 377 468 491 - tri 643 491 468 470 - tri 644 496 495 494 - tri 645 497 496 494 - tri 646 494 495 376 - tri 647 475 450 498 - tri 648 501 500 499 - tri 649 365 429 345 - tri 650 365 502 429 - tri 651 343 346 348 - tri 652 338 349 337 - tri 653 365 363 502 - tri 654 345 429 344 - tri 655 424 427 426 - tri 656 424 418 427 - tri 657 502 421 429 - tri 658 429 421 420 - tri 659 363 422 421 - tri 660 363 421 502 - tri 661 505 504 503 - tri 662 506 359 370 - tri 663 506 368 359 - tri 664 505 342 341 - tri 665 505 507 342 - tri 666 350 508 349 - tri 667 508 352 349 - tri 668 505 503 507 - tri 669 495 391 509 - tri 670 441 452 476 - tri 671 440 441 476 - tri 672 431 440 443 - tri 673 440 476 443 - tri 674 472 482 510 - tri 675 473 472 510 - tri 676 483 511 479 - tri 677 479 511 512 - tri 678 510 482 513 - tri 679 511 514 512 - tri 680 512 514 515 - tri 681 513 482 516 - tri 682 514 517 515 - tri 683 434 438 374 - tri 684 435 434 374 - tri 685 98 518 434 - tri 686 434 518 438 - tri 687 518 439 438 - tri 688 98 187 518 - tri 689 187 439 518 - tri 690 187 188 439 - tri 691 188 138 439 - tri 692 366 336 337 - tri 693 366 337 519 - tri 694 522 521 520 - tri 695 524 523 521 - tri 696 521 523 520 - tri 697 526 525 524 - tri 698 524 525 523 - tri 699 528 527 525 - tri 700 530 529 528 - tri 701 528 531 527 - tri 702 529 531 528 - tri 703 525 457 523 - tri 704 534 533 532 - tri 705 537 536 535 - tri 706 540 539 538 - tri 707 536 541 535 - tri 708 540 538 542 - tri 709 538 544 543 - tri 710 546 542 545 - tri 711 546 545 547 - tri 712 550 549 548 - tri 713 551 546 547 - tri 714 552 551 547 - tri 715 555 554 553 - tri 716 557 543 556 - tri 717 549 541 536 - tri 718 560 559 558 - tri 719 562 561 554 - tri 720 563 562 554 - tri 721 554 561 564 - tri 722 554 564 565 - tri 723 557 566 564 - tri 724 567 557 564 - tri 725 561 567 564 - tri 726 549 568 541 - tri 727 550 568 549 - tri 728 555 563 554 - tri 729 557 556 566 - tri 730 566 556 569 - tri 731 541 570 535 - tri 732 571 569 570 - tri 733 538 539 544 - tri 734 574 573 572 - tri 735 576 572 575 - tri 736 574 577 573 - tri 737 577 578 573 - tri 738 581 580 579 - tri 739 575 535 582 - tri 740 535 570 582 - tri 741 585 584 583 - tri 742 576 575 585 - tri 743 587 586 539 - tri 744 573 537 535 - tri 745 590 589 588 - tri 746 591 590 588 - tri 747 566 569 571 - tri 748 578 537 573 - tri 749 587 539 540 - tri 750 565 566 571 - tri 751 564 566 565 - tri 752 593 571 592 - tri 753 592 571 570 - tri 754 541 592 570 - tri 755 532 520 463 - tri 756 520 441 463 - tri 757 594 524 521 - tri 758 595 524 594 - tri 759 526 524 595 - tri 760 522 596 521 - tri 761 596 594 521 - tri 762 597 526 595 - tri 763 599 530 598 - tri 764 530 597 598 - tri 765 530 526 597 - tri 766 534 600 533 - tri 767 585 575 582 - tri 768 585 582 584 - tri 769 557 538 543 - tri 770 533 600 601 - tri 771 533 601 602 - tri 772 602 596 522 - tri 773 533 602 522 - tri 774 557 545 538 - tri 775 545 542 538 - tri 776 593 592 588 - tri 777 589 593 588 - tri 778 604 551 603 - tri 779 603 551 552 - tri 780 605 588 568 - tri 781 591 588 605 - tri 782 550 591 605 - tri 783 550 605 568 - tri 784 553 565 571 - tri 785 553 571 593 - tri 786 554 565 553 - tri 787 560 567 559 - tri 788 559 567 561 - tri 789 567 606 545 - tri 790 567 545 557 - tri 791 560 606 567 - tri 792 568 588 592 - tri 793 568 592 541 - tri 794 520 523 441 - tri 795 523 457 441 - tri 796 533 522 532 - tri 797 522 520 532 - tri 798 532 463 461 - tri 799 451 515 517 - tri 800 451 517 607 - tri 801 416 415 398 - tri 802 416 398 427 - tri 803 405 608 404 - tri 804 608 406 404 - tri 805 609 406 608 - tri 806 609 407 406 - tri 807 609 399 407 - tri 808 398 399 609 - tri 809 428 398 609 - tri 810 486 610 405 - tri 811 610 608 405 - tri 812 610 609 608 - tri 813 428 609 610 - tri 814 486 428 610 - tri 815 572 573 535 - tri 816 572 535 575 - tri 817 574 572 576 - tri 818 611 574 576 - tri 819 581 586 587 - tri 820 581 587 580 - tri 821 466 612 464 - tri 822 464 612 452 - tri 823 452 612 451 - tri 824 450 451 607 - tri 825 450 607 498 - tri 826 448 501 490 - tri 827 490 501 499 - tri 828 612 512 515 - tri 829 612 515 451 - tri 830 490 499 613 - tri 831 447 490 613 - tri 832 447 613 471 - tri 833 499 500 614 - tri 834 613 499 614 - tri 835 500 516 615 - tri 836 614 500 615 - tri 837 614 615 616 - tri 838 615 617 616 - tri 839 482 618 516 - tri 840 615 516 618 - tri 841 615 618 617 - tri 842 618 481 617 - tri 843 482 481 618 - tri 844 534 532 619 - tri 845 599 529 530 - tri 846 530 528 526 - tri 847 526 528 525 - tri 848 465 464 456 - tri 849 465 466 464 - tri 850 471 613 614 - tri 851 621 620 457 - tri 852 620 456 457 - tri 853 465 456 620 - tri 854 622 465 620 - tri 855 458 465 622 - tri 856 623 622 620 - tri 857 458 622 623 - tri 858 623 620 621 - tri 859 527 623 621 - tri 860 619 532 624 - tri 861 529 625 531 - tri 862 624 461 462 - tri 863 532 461 624 - tri 864 626 458 623 - tri 865 625 467 626 - tri 866 467 458 626 - tri 867 531 623 527 - tri 868 531 626 623 - tri 869 625 626 531 - tri 870 525 621 457 - tri 871 525 527 621 - tri 872 460 446 459 - tri 873 459 446 444 - tri 874 466 627 612 - tri 875 627 512 612 - tri 876 479 512 627 - tri 877 444 479 627 - tri 878 444 627 466 - tri 879 474 471 628 - tri 880 628 629 300 - tri 881 471 614 628 - tri 882 628 614 616 - tri 883 628 616 629 - tri 884 301 470 474 - tri 885 301 474 302 - tri 886 493 470 303 - tri 887 303 470 301 - tri 888 492 493 304 - tri 889 304 493 303 - tri 890 630 304 305 - tri 891 630 492 304 - tri 892 474 628 300 - tri 893 302 474 300 - tri 894 631 492 630 - tri 895 632 492 631 - tri 896 632 378 492 - tri 897 635 634 633 - tri 898 633 634 636 - tri 899 636 634 632 - tri 900 636 632 631 - tri 901 637 636 630 - tri 902 636 631 630 - tri 903 638 636 637 - tri 904 638 633 636 - tri 905 376 373 378 - tri 906 632 376 378 - tri 907 639 638 637 - tri 908 640 635 633 - tri 909 640 633 641 - tri 910 640 641 642 - tri 911 494 376 632 - tri 912 634 494 632 - tri 913 635 494 634 - tri 914 497 494 635 - tri 915 497 643 496 - tri 916 497 644 643 - tri 917 640 497 635 - tri 918 640 644 497 - tri 919 390 391 495 - tri 920 496 390 495 - tri 921 495 509 376 - tri 922 408 645 487 - tri 923 646 385 383 - tri 924 408 409 645 - tri 925 384 489 383 - tri 926 384 323 324 - tri 927 384 324 489 - tri 928 391 489 509 - tri 929 489 647 509 - tri 930 648 637 326 - tri 931 385 323 384 - tri 932 385 649 329 - tri 933 385 329 323 - tri 934 648 326 330 - tri 935 329 649 331 - tri 936 326 630 305 - tri 937 637 630 326 - tri 938 324 332 489 - tri 939 489 332 647 - tri 940 647 651 650 - tri 941 509 647 650 - tri 942 651 435 375 - tri 943 650 651 375 - tri 944 651 335 435 - tri 945 335 100 435 - tri 946 332 651 647 - tri 947 332 335 651 - tri 948 376 650 375 - tri 949 509 650 376 - tri 950 654 653 652 - tri 951 656 654 655 - tri 952 654 652 655 - tri 953 652 653 657 - tri 954 652 657 658 - tri 955 658 657 659 - tri 956 658 659 660 - tri 957 661 660 659 - tri 958 55 48 322 - tri 959 322 662 55 - tri 960 390 646 383 - tri 961 646 390 663 - tri 962 55 662 319 - tri 963 319 164 55 - tri 964 390 643 663 - tri 965 643 390 496 - - numweights 1220 - weight 0 5 0.0935239866 ( 3.8127360344 18.653427124 -1.0291671753 ) - weight 1 6 0.6671485305 ( -0.7151768804 3.1304476261 2.3139109612 ) - weight 2 7 0.2393274605 ( -1.2482603788 -0.3180599511 2.8520338535 ) - weight 3 6 0.0843834653 ( -0.103548944 6.4286642075 4.4149246216 ) - weight 4 7 0.5620473027 ( -1.5335928202 3.6064872742 2.4241364002 ) - weight 5 8 0.3535692692 ( -1.5020233393 -1.489027977 2.4291889668 ) - weight 6 6 0.4737676382 ( -1.7838802338 5.0132069588 1.860653758 ) - weight 7 7 0.5262323618 ( -2.2546744347 0.5913563371 1.1049093008 ) - weight 8 7 0.5011257529 ( -2.0092220306 4.9650716782 -0.9881344438 ) - weight 9 8 0.4988743067 ( -2.0064079762 -0.1527582258 -0.9877608418 ) - weight 10 7 0.5046935678 ( 2.2403481007 4.8383469582 -0.8591219783 ) - weight 11 8 0.495306462 ( 2.2448923588 -0.1879273951 -0.8583108187 ) - weight 12 6 0.4963374138 ( 2.4411556721 6.207262516 -1.945104003 ) - weight 13 7 0.5036625266 ( 2.8364603519 0.282594353 -1.678165555 ) - weight 14 6 0.4661476612 ( -2.9416100979 6.680390358 -0.1249469966 ) - weight 15 7 0.4800623953 ( -2.864084959 0.4030626416 -1.661968708 ) - weight 16 8 0.0537899137 ( -2.7632496357 -4.7343444824 -1.6458108425 ) - weight 17 5 0.6232063174 ( 2.7473978996 19.8591384888 3.444442749 ) - weight 18 6 0.2971909642 ( -4.5151796341 0.6758175492 0.8521854877 ) - weight 19 7 0.079602696 ( -4.244515419 -4.0007386208 2.6026239395 ) - weight 20 5 0.3033103049 ( 1.7648807764 19.9354686737 0.9160862565 ) - weight 21 6 0.6966896653 ( -2.0447351933 1.4687639475 0.0572685003 ) - weight 22 5 0.5 ( -1.1340595484 20.9681053162 2.7353503704 ) - weight 23 6 0.5 ( -2.8432769775 -0.802236855 -2.5856084824 ) - weight 24 5 0.2689843774 ( 4.015130043 18.6074390411 0.8103903532 ) - weight 25 6 0.5431467891 ( -2.3177781105 2.2326207161 2.5433149338 ) - weight 26 7 0.1878687739 ( -2.7789888382 -1.2632457018 3.2885482311 ) - weight 27 5 0.1060663685 ( 3.8994646072 17.6567077637 -2.6287512779 ) - weight 28 6 0.4873141348 ( 0.9746853113 3.5118246078 3.06127882 ) - weight 29 7 0.3494953811 ( 0.1032667458 0.833692193 3.4895937443 ) - weight 30 8 0.0571241342 ( 0.193809092 -4.2224025726 3.5042312145 ) - weight 31 5 0.3997223675 ( -1.1646174192 23.7804584503 2.4665853977 ) - weight 32 6 0.416490972 ( -3.686072588 0.8614727259 -4.7079334259 ) - weight 33 7 0.1837866157 ( -1.7758827209 -6.9593877792 -1.4948219061 ) - weight 34 5 0.4107972383 ( -3.0434248447 23.3945465088 0.2558149397 ) - weight 35 6 0.4213652015 ( -0.9571701884 0.6585357189 -5.7463259697 ) - weight 36 7 0.1678375453 ( 1.146812439 -7.0609116554 -1.6127066612 ) - weight 37 7 0.5249262452 ( 0.3187460601 4.7918243408 1.1942294836 ) - weight 38 8 0.475073725 ( 0.3245765269 -0.2685232162 1.1951892376 ) - weight 39 6 0.1096295714 ( 2.9207594395 6.0545563698 3.1228327751 ) - weight 40 7 0.5836595297 ( 1.7587673664 3.2957522869 2.2837507725 ) - weight 41 8 0.3067108989 ( 1.7962508202 -1.7296113968 2.2898790836 ) - weight 42 5 0.0803422183 ( 2.1394081116 18.4398002625 -3.2200272083 ) - weight 43 6 0.6961277723 ( 1.8512949944 3.1415815353 1.2850141525 ) - weight 44 7 0.2235300243 ( 1.5025411844 -0.2899706364 2.5730495453 ) - weight 45 5 0.120941259 ( 0.4943208694 19.4355697632 -3.2106790543 ) - weight 46 6 0.7397739887 ( 2.0982830524 2.6337282658 -0.5532013774 ) - weight 47 7 0.13928473 ( 2.3319923878 -1.7106441259 1.5772321224 ) - weight 48 5 0.1834091842 ( 1.6726700068 17.7061920166 -4.2953872681 ) - weight 49 6 0.5260417461 ( 3.2151074409 3.02911973 1.4844964743 ) - weight 50 7 0.2905490696 ( 2.7451124191 0.0778421387 3.055911541 ) - weight 51 5 0.307454288 ( -1.149764657 19.6340618134 -3.7381052971 ) - weight 52 6 0.5233104229 ( 3.1009352207 1.9830664396 -1.8149154186 ) - weight 53 7 0.1692353189 ( 3.7135105133 -2.7122011185 1.2472529411 ) - weight 54 5 0.5 ( -2.5818476677 20.652261734 0.7198092341 ) - weight 55 6 0.5 ( -0.4718604386 -0.7988773584 -3.3822419643 ) - weight 56 3 0.1069236025 ( 7.8959798813 5.1963424683 -3.1774246693 ) - weight 57 4 0.055033993 ( -4.6473588943 -6.595079422 2.6459312439 ) - weight 58 17 0.5240889192 ( 7.8119277954 5.3034553528 -2.5882546902 ) - weight 59 19 0.1887804121 ( 7.8959798813 -4.0340409279 -0.8862079978 ) - weight 60 22 0.1251730919 ( 7.8959798813 -11.7440185547 -1.9258882999 ) - weight 61 3 0.2396446764 ( 8.9375400543 2.2950515747 1.6243751049 ) - weight 62 4 0.1261993945 ( -0.540705204 -3.2331793308 4.7417941093 ) - weight 63 17 0.5096623302 ( 9.1274223328 1.3470206261 1.3073476553 ) - weight 64 19 0.0713101402 ( 8.9375400543 -6.5020551682 4.1520137787 ) - weight 65 18 0.0531834662 ( 9.0192966461 -0.1320877075 -4.9274363518 ) - weight 66 3 0.2251323164 ( 8.6952495575 1.7104263306 -2.571845293 ) - weight 67 4 0.3628976941 ( -4.3803491592 -2.9905240536 2.9509806633 ) - weight 68 17 0.4119699895 ( 8.6446428299 1.7856203318 -2.8858983517 ) - weight 69 3 0.2515031099 ( 9.0758104324 -1.4819068909 1.7993451357 ) - weight 70 4 0.4060203135 ( -0.4429805875 0.5151007771 4.2358341217 ) - weight 71 17 0.3424766064 ( 9.2755088806 -2.3588471413 0.5591740012 ) - weight 72 3 0.0989223495 ( 8.4342899323 5.5740737915 1.8654052019 ) - weight 73 4 0.0575829931 ( -0.1221968755 -6.5253100395 4.9655508995 ) - weight 74 17 0.3998931944 ( 8.638838768 4.4645085335 2.3589646816 ) - weight 75 19 0.1923786998 ( 8.4342899323 -3.2145380974 4.103905201 ) - weight 76 22 0.1035134494 ( 8.4342899323 -11.3662872314 3.1169416904 ) - weight 77 20 0.0805758238 ( 4.4096069336 -8.9192352295 -3.6768062115 ) - weight 78 18 0.0671336129 ( 8.516046524 3.1469345093 -4.6864061356 ) - weight 79 3 0.2790404558 ( 6.444149971 2.2682609558 5.2955350876 ) - weight 80 4 0.1333959997 ( 3.7762153149 -3.3769116402 3.7226448059 ) - weight 81 17 0.3836249709 ( 6.8488903046 0.4034765065 4.9969472885 ) - weight 82 19 0.0836782604 ( 6.444149971 -6.2060699463 7.8113207817 ) - weight 83 18 0.1202602759 ( 6.5259070396 -0.1588783264 -1.2562766075 ) - weight 84 3 0.0532003716 ( 3.5289063454 -11.8854789734 3.4735531807 ) - weight 85 4 0.9467996359 ( 3.0445535183 9.9132080078 -2.1920824051 ) - weight 86 3 0.174553141 ( 1.0088499784 -10.5870780945 1.3821251392 ) - weight 87 10 0.0889235511 ( -2.7075951099 7.7206482887 -6.8508563042 ) - weight 88 4 0.6818998456 ( 1.9894014597 8.0630159378 -4.998155117 ) - weight 89 17 0.054623533 ( 1.1979006529 -11.2070074081 -1.5894020796 ) - weight 90 3 0.0597552843 ( 3.3046152592 -16.349653244 0.7676105499 ) - weight 91 4 0.9402447343 ( 0.5745386481 14.0756530762 -4.1604218483 ) - weight 92 3 0.1727394462 ( 2.5361399651 -13.0034599304 -3.9219045639 ) - weight 93 4 0.7542150021 ( -3.5220792294 10.3306970596 -5.8844122887 ) - weight 94 17 0.0730455071 ( 2.4181890488 -12.2552556992 -7.3959774971 ) - weight 95 3 0.2580770552 ( 2.3561799526 -12.6595573425 -8.5002851486 ) - weight 96 4 0.6327911019 ( -7.7369976044 9.6447715759 -7.5803456306 ) - weight 97 17 0.1091318205 ( 1.9756994247 -10.8226957321 -11.7392702103 ) - weight 98 3 0.1491877884 ( 6.2747101784 -12.6114120483 -7.7310824394 ) - weight 99 4 0.7921545506 ( -8.4083137512 10.3177986145 -3.7015266418 ) - weight 100 17 0.0586576648 ( 5.9319243431 -10.9067935944 -11.2006797791 ) - weight 101 4 1 ( 2.0208208561 17.0193157196 -1.7541565895 ) - weight 102 3 0.0563600622 ( 6.9160900116 -13.04296875 4.1621651649 ) - weight 103 4 0.9436399341 ( 2.4811067581 11.6752967834 0.9487066865 ) - weight 104 4 0.9282485247 ( -1.5941865444 17.5156898499 -5.0876231194 ) - weight 105 5 0.0717514902 ( -3.583676815 -2.5219893456 -0.9201021194 ) - weight 106 4 0.6559420824 ( -0.7508656979 19.7827892303 0.8460713029 ) - weight 107 5 0.3440578878 ( 2.7071833611 -1.3105490208 -1.0510600805 ) - weight 108 3 0.192728743 ( 8.801817894 -7.0334854126 -4.1119995117 ) - weight 109 4 0.8072712421 ( -5.8969087601 5.5158557892 0.9062381983 ) - weight 110 4 1 ( -6.5119538307 11.1498479843 0.7489375472 ) - weight 111 4 0.5014052391 ( -2.1492013931 20.8788642883 -5.5200419426 ) - weight 112 5 0.4985947609 ( -3.5182363987 0.9090329409 -1.0926314592 ) - weight 113 4 0.740267396 ( -4.2334899902 20.033618927 -5.3216814995 ) - weight 114 5 0.2597326636 ( -3.7921729088 0.5087782741 1.1125438213 ) - weight 115 4 0.3635103106 ( -5.4528450966 22.8845691681 -5.2548179626 ) - weight 116 5 0.6364896297 ( -3.4310176373 3.5183131695 1.7694147825 ) - weight 117 4 0.2838164866 ( -7.1263494492 21.893579483 -3.203895092 ) - weight 118 5 0.7161834836 ( -1.8632599115 2.6389324665 3.9506502151 ) - weight 119 5 1 ( -4.1741204262 5.6770710945 2.53515625 ) - weight 120 5 1 ( -1.9457143545 5.4498543739 4.9774689674 ) - weight 121 4 0.3121370077 ( -4.4071116447 21.7299919128 1.1965153217 ) - weight 122 5 0.6878629327 ( 2.8127121925 1.305783987 2.1779036522 ) - weight 123 4 0.0533990003 ( -3.1070792675 24.6861858368 0.271330595 ) - weight 124 5 0.9466010332 ( 2.6169657707 4.0141019821 0.2000684142 ) - weight 125 4 0.0613344088 ( -6.7894105911 24.7612800598 0.0435621142 ) - weight 126 5 0.9386655688 ( 1.837200284 4.902736187 3.6956906319 ) - weight 127 4 0.2215298414 ( -7.4662833214 22.7176418304 -0.8179263473 ) - weight 128 5 0.7784701586 ( 0.546154201 3.1861352921 4.5693378448 ) - weight 129 4 0.6404342651 ( -6.2111821175 19.7123451233 -0.6909929514 ) - weight 130 5 0.3595657051 ( 0.3528687954 -0.0065741558 3.9428799152 ) - weight 131 4 0.8282259107 ( 0.7223988771 19.3566360474 -2.3801381588 ) - weight 132 5 0.1717740893 ( -0.2764886916 -1.6007701159 -2.9937427044 ) - weight 133 4 0.6559420824 ( -1.144947052 21.2384357452 0.2804422975 ) - weight 134 5 0.3440578878 ( 2.3433480263 0.2584503591 -1.047824502 ) - weight 135 4 0.3121370077 ( -3.7774112225 20.3179531097 1.7202266455 ) - weight 136 5 0.6878629327 ( 3.1797053814 -0.26559183 1.9314409494 ) - weight 137 3 0.0671593621 ( 7.8446297646 -21.3117198944 -5.241314888 ) - weight 138 4 0.7200645804 ( -6.6764502525 19.3096656799 -2.9902544022 ) - weight 139 5 0.21277605 ( -2.0252971649 0.0139190787 4.038459301 ) - weight 140 5 1 ( -3.6398761272 10.0534420013 1.8198467493 ) - weight 141 5 1 ( -2.7982206345 10.4494514465 4.7135415077 ) - weight 142 5 1 ( -4.2860569954 13.5659074783 1.7814621925 ) - weight 143 5 1 ( -3.0162653923 10.52094841 -1.1173174381 ) - weight 144 4 0.0812822282 ( -3.5907011032 26.3055477142 -5.7982292175 ) - weight 145 5 0.918717742 ( -3.0890066624 6.5048732758 -0.7662224174 ) - weight 146 5 1 ( 2.0402960777 8.7431297302 4.251139164 ) - weight 147 5 1 ( 1.801984787 15.6448259354 3.10176301 ) - weight 148 5 1 ( 2.0115163326 11.7242155075 1.4887131453 ) - weight 149 5 1 ( 2.9223980904 15.0317459106 -1.369388938 ) - weight 150 5 1 ( -0.7952164412 12.6624107361 3.927521944 ) - weight 151 5 1 ( -2.0613574982 16.8246326447 4.3019156456 ) - weight 152 5 0.9168231487 ( -4.2305979729 17.2965717316 0.732529223 ) - weight 153 6 0.0831768736 ( 1.4446171522 -3.6887888908 -1.9841297865 ) - weight 154 5 0.8543199301 ( -2.0448555946 16.9572963715 -2.4853451252 ) - weight 155 6 0.1456800848 ( 3.4254362583 -0.7313295603 -0.3788008988 ) - weight 156 5 1 ( 0.6453074217 15.0546197891 -3.2220330238 ) - weight 157 5 1 ( 0.44538185 10.1214313507 -1.5377562046 ) - weight 158 5 1 ( 2.0674369335 10.2083835602 -0.3427814245 ) - weight 159 5 1 ( 1.1055467129 6.0715780258 -1.8681554794 ) - weight 160 5 0.5 ( -1.6463179588 20.7951831818 3.617836237 ) - weight 161 6 0.5 ( -3.3181433678 -1.7031702995 -2.7697622776 ) - weight 162 25 1 ( 0.9275852442 7.2957701683 -3.3785088062 ) - weight 163 25 1 ( -2.7143802643 7.1327629089 -3.1395363808 ) - weight 164 25 0.8784247637 ( -2.3203058243 10.7307872772 -2.6311776638 ) - weight 165 26 0.1215752512 ( -0.7492275238 -1.5532993078 -3.6283137798 ) - weight 166 25 0.8984447718 ( 1.7512421608 9.9629249573 -2.1052036285 ) - weight 167 26 0.1015552133 ( 2.8900485039 -1.0475037098 -1.6424628496 ) - weight 168 17 0.449130863 ( -0.2770932019 5.6961083412 -5.7161598206 ) - weight 169 19 0.4540952146 ( 0 -4.7206392288 -4.4291324615 ) - weight 170 22 0.096773915 ( 0 -12.116558075 -5.5154485703 ) - weight 171 17 0.5152887702 ( 3.7515227795 5.7953419685 -5.1341805458 ) - weight 172 19 0.3591423929 ( 3.9909200668 -4.4172315598 -3.6816065311 ) - weight 173 22 0.125568822 ( 3.9909200668 -11.880027771 -4.7441482544 ) - weight 174 3 0.0887620747 ( 0 2.0629615784 -7.0419249535 ) - weight 175 17 0.6063475609 ( -0.2928763926 3.0827322006 -6.647746563 ) - weight 176 19 0.3048903346 ( 0 -7.4949612617 -4.4603471756 ) - weight 177 3 0.1464416832 ( 4.6321001053 1.9589729309 -6.3333845139 ) - weight 178 4 0.120930925 ( -6.4539165497 -4.1871528625 -2.0478725433 ) - weight 179 17 0.5861251354 ( 4.3722596169 2.8754427433 -6.2443447113 ) - weight 180 19 0.1465022862 ( 4.6321001053 -7.5362710953 -3.7454090118 ) - weight 181 17 0.1273706257 ( 7.3636469841 10.8545312881 -1.947201252 ) - weight 182 19 0.4415688813 ( 7.4895000458 1.4214830399 -2.1102924347 ) - weight 183 22 0.363877058 ( 7.4895000458 -6.2020187378 -2.665728569 ) - weight 184 24 0.0671834275 ( 0.1316785812 -2.970523119 -8.4243202209 ) - weight 185 17 0.3153382242 ( 8.411324501 8.011341095 0.2487125695 ) - weight 186 19 0.3789919317 ( 8.3737802505 -0.5478342175 0.9463784099 ) - weight 187 22 0.2489299327 ( 8.3737802505 -8.4323768616 0.2060216665 ) - weight 188 20 0.0567399301 ( 4.3490972519 -5.9853248596 -6.5877261162 ) - weight 189 17 0.316473484 ( 6.4286837578 8.4252567291 -3.6584334373 ) - weight 190 19 0.4292660952 ( 6.6178197861 -1.4368979931 -2.9898827076 ) - weight 191 22 0.2542604208 ( 6.6178197861 -8.972026825 -3.7931485176 ) - weight 192 17 0.1202539653 ( 4.2121686935 12.5123434067 -4.0768246651 ) - weight 193 19 0.4247384965 ( 4.4847998619 2.2807955742 -4.8395433426 ) - weight 194 22 0.3653951585 ( 4.4847998619 -5.1061477661 -5.3088884354 ) - weight 195 24 0.089612402 ( 3.1363787651 -5.6136827469 -7.3284492493 ) - weight 196 25 1 ( 2.712013483 7.632484436 -1.6183480024 ) - weight 197 25 0.8327695727 ( 3.1037318707 9.9404001236 1.0208822489 ) - weight 198 26 0.1672303826 ( 2.9835219383 -0.9043157697 1.7594350576 ) - weight 199 22 0.0771214515 ( 10.5706396103 -2.2360191345 2.5162315369 ) - weight 200 25 0.9228785634 ( 1.9276038408 4.9491381645 -2.2725217342 ) - weight 201 25 1 ( -2.4587037563 5.8695721626 -2.9298191071 ) - weight 202 25 1 ( -4.010948658 6.6789679527 -0.6567108631 ) - weight 203 19 0.0508285165 ( 8.6673402786 8.395565033 4.8748426437 ) - weight 204 22 0.3103339374 ( 8.6673402786 0.1311225891 4.9053516388 ) - weight 205 23 0.0798272043 ( 4.5237116814 6.4591140747 -1.8480153084 ) - weight 206 24 0.1801317483 ( -1.0461616516 4.6005573273 -2.091178894 ) - weight 207 25 0.2787561417 ( 4.3732790947 1.9897115231 -1.8317598104 ) - weight 208 20 0.1001224369 ( 4.64265728 2.5781745911 -1.8883962631 ) - weight 209 19 0.189502582 ( 7.2366700172 5.6184434891 5.9579463005 ) - weight 210 22 0.4047628939 ( 7.2366700172 -2.7304496765 5.7401714325 ) - weight 211 24 0.1485210061 ( 0.3845086098 5.435377121 -4.9527511597 ) - weight 212 20 0.2572135329 ( 3.2119870186 -0.2833976746 -1.0535764694 ) - weight 213 19 0.2537808418 ( 9.0340995789 3.8217997551 3.0478274822 ) - weight 214 22 0.4020117223 ( 9.0340995789 -4.2643585205 2.6834015846 ) - weight 215 24 0.076381281 ( -1.4129209518 2.3786070347 -6.4866600037 ) - weight 216 25 0.0616703294 ( 1.6802309752 4.8661475182 -4.8092479706 ) - weight 217 20 0.2061558366 ( 5.0094165802 -1.8173065186 -4.1103463173 ) - weight 218 22 0.2104583681 ( 8.9566698074 5.3679389954 1.8660715818 ) - weight 219 23 0.0883276537 ( 1.4721133709 5.7074985504 3.3354201317 ) - weight 220 24 0.2880037725 ( -1.3354911804 1.5612771511 3.1456375122 ) - weight 221 25 0.4132102728 ( 2.0479469299 -0.7543227673 3.0476136208 ) - weight 222 22 0.2019269764 ( 10.2034502029 2.9910697937 3.9270217419 ) - weight 223 23 0.115218088 ( 3.4485721588 7.4492001534 1.211374402 ) - weight 224 24 0.2169577181 ( -2.5822715759 3.6222271919 0.7687683105 ) - weight 225 25 0.4658972621 ( 3.9222977161 1.6043533087 1.5065294504 ) - weight 226 22 0.1066465601 ( 11.6276416779 2.5019798279 1.9945477247 ) - weight 227 24 0.082949616 ( -4.0064630508 1.689753294 0.2796783447 ) - weight 228 25 0.8104037642 ( 2.1068224907 3.0796408653 2.2342402935 ) - weight 229 19 0.0934283361 ( 9.1123199463 4.7844085693 1.4842790365 ) - weight 230 22 0.3328987956 ( 9.1123199463 -3.1680488586 1.2105116844 ) - weight 231 25 0.504265368 ( 0.3697837889 4.3194146156 -3.6425309181 ) - weight 232 20 0.0694075301 ( 5.0876369476 -0.7209968567 -5.5832362175 ) - weight 233 19 0.3896191418 ( 8.652299881 3.1292157173 0.7079356313 ) - weight 234 22 0.4093904197 ( 8.652299881 -4.7486000061 0.2916916609 ) - weight 235 25 0.0671922043 ( -0.7797638774 4.8728508949 -5.0304207802 ) - weight 236 20 0.1337981522 ( 4.6276168823 -2.3015480042 -6.5020561218 ) - weight 237 19 0.1736020893 ( 8.3155002594 4.2229170799 -1.6327527761 ) - weight 238 22 0.331809938 ( 8.3155002594 -3.4533996582 -1.9438083172 ) - weight 239 24 0.1214219555 ( -0.6943216324 -2.2486028671 -5.6757011414 ) - weight 240 25 0.3731659949 ( -2.8624002934 3.8847255707 -3.8160603046 ) - weight 241 25 0.4205686748 ( 1.4400048256 11.4228773117 3.0691380501 ) - weight 242 26 0.5794312954 ( 0.3222328722 -0.1931181401 3.0135536194 ) - weight 243 25 0.88492769 ( -0.1448078603 10.4199743271 2.6888926029 ) - weight 244 26 0.1150723174 ( -0.6133205891 -1.6069338322 2.1259191036 ) - weight 245 25 0.8383777142 ( -3.9867646694 10.588809967 -0.4868829846 ) - weight 246 26 0.1616222858 ( -2.9237706661 -2.3876690865 -2.224593401 ) - weight 247 25 0.2587660253 ( -4.1667289734 12.4313373566 -0.6045203805 ) - weight 248 26 0.7412339449 ( -3.6336395741 -0.6912592053 -2.4683389664 ) - weight 249 25 0.4776410162 ( -0.1146772653 11.5581302643 -3.0020635128 ) - weight 250 26 0.5223590136 ( 1.0531570911 -0.0487227812 -3.2105703354 ) - weight 251 25 0.3601590693 ( -2.5787878036 12.179060936 -2.3499720097 ) - weight 252 26 0.6398409009 ( -1.5417722464 -0.2875441611 -3.5137608051 ) - weight 253 25 0.5487061739 ( 3.0538058281 11.579331398 -1.5442295074 ) - weight 254 26 0.4512938261 ( 3.3163597584 0.8432571292 -0.7111103535 ) - weight 255 25 1 ( 0.443833679 8.7419500351 3.0878815651 ) - weight 256 25 0.8383777142 ( -3.2075200081 10.664648056 1.8308862448 ) - weight 257 26 0.1616222858 ( -3.0806663036 -2.2640073299 0.2136681527 ) - weight 258 25 1 ( -2.403983593 6.6894264221 1.8346095085 ) - weight 259 17 0.1560927927 ( 8.3652687073 9.5174016953 3.4297437668 ) - weight 260 19 0.3652572036 ( 8.1714000702 1.9104971886 3.4573440552 ) - weight 261 22 0.3252667487 ( 8.1714000702 -6.2042579651 2.9233415127 ) - weight 262 20 0.1533832401 ( 4.1467170715 -3.7572059631 -3.8704063892 ) - weight 263 17 0.2015561014 ( 6.2955598831 9.2145462036 7.1821675301 ) - weight 264 19 0.2642347813 ( 5.8918499947 2.8338274956 6.9797315598 ) - weight 265 22 0.3287962675 ( 5.8918499947 -5.5940971375 6.5132517815 ) - weight 266 20 0.2054128349 ( 1.867166996 -3.1470451355 -0.2804961205 ) - weight 267 19 0.0948961601 ( 3.5795500278 8.8181762695 6.6815099716 ) - weight 268 22 0.4634767175 ( 3.5795500278 0.3933029175 6.7421717644 ) - weight 269 23 0.0722427592 ( 6.6840867996 1.5225815773 -2.3880908489 ) - weight 270 24 0.1664817035 ( 4.0416283607 6.4373774529 -1.8289985657 ) - weight 271 20 0.2029026896 ( -0.4451329708 2.8403549194 -0.0515761375 ) - weight 272 17 0.1906848699 ( 2.4328575134 9.174571991 8.9040555954 ) - weight 273 19 0.2058832794 ( 1.9390300512 3.336438179 8.3973207474 ) - weight 274 22 0.2979409397 ( 1.9390300512 -5.2180290222 7.9695315361 ) - weight 275 20 0.1714980751 ( -2.0856528282 -2.7709770203 1.1757836342 ) - weight 276 18 0.133992821 ( 2.0207870007 9.2951927185 0.1661834717 ) - weight 277 17 0.0863279849 ( -0.2875749469 17.6150417328 -2.9451155663 ) - weight 278 19 0.2839872241 ( 0 7.451417923 -5.6864366531 ) - weight 279 22 0.4494484961 ( 0 0.1189002991 -5.698038578 ) - weight 280 39 0.0605599955 ( 5.5000338554 -2.7487328053 -3.3631818295 ) - weight 281 40 0.1196763366 ( -7.6211800575 -6.0028300285 -2.1034240723 ) - weight 282 19 0.1344032288 ( 4.1019601822 8.4969930649 -5.6311721802 ) - weight 283 22 0.4274182618 ( 4.1019601822 1.1555709839 -5.5510883331 ) - weight 284 23 0.1332542896 ( -5.6173138618 1.1336624622 -1.6792143583 ) - weight 285 24 0.2516222596 ( 3.5192184448 -5.8558826447 -1.0667304993 ) - weight 286 25 0.0533020496 ( -6.303914547 -2.160040617 -1.9119106531 ) - weight 287 19 0.1979081333 ( 6.7445898056 5.6682634354 -4.2771639824 ) - weight 288 22 0.3774667084 ( 6.7445898056 -1.7812194824 -4.4509482384 ) - weight 289 23 0.0570001341 ( -4.6894865036 4.2793111801 -4.1414427757 ) - weight 290 24 0.1939489841 ( 0.8765888214 -4.7557425499 -4.0035209656 ) - weight 291 25 0.1736759692 ( -5.297978878 1.6762918234 -2.9555516243 ) - weight 292 19 0.1394121796 ( 1.4000600576 8.4774703979 7.1653380394 ) - weight 293 22 0.5321753025 ( 1.4000600576 0.011390686 7.1941814423 ) - weight 294 21 0.0751778483 ( 5.6524200439 2.330116272 0.4004335403 ) - weight 295 20 0.2532346845 ( -2.6246228218 2.458442688 0.4004335403 ) - weight 296 22 0.1055573449 ( 11.1468296051 0.6763305664 4.0388617516 ) - weight 297 24 0.0612346157 ( -3.5256509781 3.7340672016 -1.5459709167 ) - weight 298 25 0.8332080245 ( 3.848783493 3.7106661797 0.1579997689 ) - weight 299 22 0.2346942276 ( 8.8396902084 -0.3195800781 -4.1728482246 ) - weight 300 24 0.2036777884 ( -1.2185115814 -4.4776425362 -2.5418815613 ) - weight 301 25 0.561627984 ( -4.6214380264 2.5355131626 -0.6302115917 ) - weight 302 22 0.7616530061 ( 0 6.7909126282 -1.6510283947 ) - weight 303 39 0.0707426295 ( 1.4614092112 -3.5664117336 3.2636539936 ) - weight 304 40 0.0967006236 ( -7.6211800575 -1.9558200836 4.5685882568 ) - weight 305 23 0.0709036738 ( -1.461405158 -3.5664477348 3.2635588646 ) - weight 306 22 0.7280092239 ( 2.5946099758 6.8535728455 -0.7384383678 ) - weight 307 23 0.0894822627 ( -0.7176495194 -0.963170588 3.7519469261 ) - weight 308 24 0.1825084984 ( 5.0265684128 -1.0432327986 4.6312713623 ) - weight 309 22 0.4795843363 ( 3.6837999821 4.6725578308 -3.5961685181 ) - weight 310 23 0.1561301053 ( -3.6395392418 0.2794250846 1.744884491 ) - weight 311 24 0.3642855883 ( 3.9373786449 -3.9009628296 2.4502563477 ) - weight 312 4 1 ( 0.231378153 11.9146661758 2.3785026073 ) - weight 313 4 1 ( -3.2244670391 11.9806871414 2.1581840515 ) - weight 314 4 1 ( -5.5193796158 11.3364896774 0.3575074077 ) - weight 315 3 0.2448486388 ( 2.6553499699 -8.3733863831 3.7454252243 ) - weight 316 4 0.6956244707 ( 3.624350071 6.3310770988 -2.2551803589 ) - weight 317 17 0.0595268682 ( 2.9773528576 -9.6042203903 1.1421186924 ) - weight 318 3 0.3425111175 ( 4.8471999168 -6.9701766968 -7.3589849472 ) - weight 319 4 0.5228202343 ( -7.5287618637 4.5554394722 -3.8477687836 ) - weight 320 17 0.134668678 ( 4.5281291008 -5.5409913063 -9.4014291763 ) - weight 321 22 0.4028716385 ( 7.2713699341 0.9188499451 5.3783316612 ) - weight 322 23 0.1384224147 ( 5.0855317116 4.9873733521 -1.2900773287 ) - weight 323 24 0.3638387024 ( 0.3498086929 5.0735373497 -1.3034515381 ) - weight 324 20 0.0948672518 ( 3.2466869354 3.365901947 -1.4154162407 ) - weight 325 3 0.0863266289 ( 5.78895998 5.7444610596 5.3466253281 ) - weight 326 17 0.3341448307 ( 6.1977138519 3.7559199333 5.9204964638 ) - weight 327 19 0.1688850224 ( 5.78895998 -2.7388324738 7.5566763878 ) - weight 328 22 0.1109910384 ( 5.78895998 -11.1958999634 6.5981616974 ) - weight 329 20 0.1000070646 ( 1.7642769814 -8.7488479614 -0.1955862045 ) - weight 330 18 0.1996454149 ( 5.8707170486 3.3173217773 -1.205186367 ) - weight 331 3 0.2953130901 ( 2.1477301121 2.2299842834 6.3577151299 ) - weight 332 4 0.1033319831 ( 6.2938389778 -3.997066021 0.1357386559 ) - weight 333 17 0.1761487424 ( 2.6205313206 0.0514074787 6.2562885284 ) - weight 334 19 0.0732033625 ( 2.1477301121 -6.1508393288 8.872754097 ) - weight 335 22 0.052489996 ( 2.1477301121 -14.7103767395 7.6092514992 ) - weight 336 18 0.2995128632 ( 2.2294869423 -0.1971549988 -0.1940965652 ) - weight 337 17 0.2491469532 ( 2.5400130749 3.2282612324 7.1184353828 ) - weight 338 19 0.2161560208 ( 2.0632500648 -2.8667340279 8.6498289108 ) - weight 339 22 0.1518869698 ( 2.0632500648 -11.4193878174 7.6758418083 ) - weight 340 20 0.0964680836 ( -1.9614329338 -8.9723358154 0.8820939064 ) - weight 341 18 0.2863419652 ( 2.1450068951 3.0938339233 -0.1275062561 ) - weight 342 3 0.1918237954 ( 9.7403774261 -6.8306808472 -0.1620233953 ) - weight 343 4 0.7444337606 ( -2.53627491 5.7499799728 3.1812460423 ) - weight 344 17 0.0637424588 ( 9.826385498 -7.0690746307 -2.6670143604 ) - weight 345 3 0.2450447083 ( 8.8855085373 -7.779296875 3.0419225693 ) - weight 346 4 0.7549552917 ( 0.758254528 6.7589211464 3.3363471031 ) - weight 347 4 1 ( -2.3931720257 11.8119659424 3.4592211246 ) - weight 348 4 1 ( 0.1853495985 11.8749380112 3.0206782818 ) - weight 349 22 0.2993527055 ( 8.5918798447 3.382183075 4.2053413391 ) - weight 350 23 0.1691163778 ( 3.8300075531 5.8166432381 1.3412022591 ) - weight 351 24 0.4106554091 ( -0.9707012177 3.9005470276 1.1598815918 ) - weight 352 25 0.1208755374 ( 4.0736279488 0.0592301488 0.8605539799 ) - weight 353 22 0.3157365322 ( 7.269780159 5.4760780334 2.5088114738 ) - weight 354 23 0.1305618137 ( 2.2220599651 4.0694847107 3.1776385307 ) - weight 355 24 0.4652858675 ( 0.351398468 2.2040171623 3.2537765503 ) - weight 356 25 0.0884157941 ( 2.5161170959 -2.2030422688 2.0716865063 ) - weight 357 22 0.3791531324 ( 6.9991698265 4.0735282898 3.9729616642 ) - weight 358 23 0.1587525159 ( 3.7005879879 4.1218686104 1.7650798559 ) - weight 359 24 0.4620943964 ( 0.6220088005 3.6681673527 1.8512268066 ) - weight 360 5 0.6010227203 ( -3.4498386383 20.4180221558 0.1943686754 ) - weight 361 6 0.3989772201 ( 0.3946889639 -1.1931943893 -3.8041069508 ) - weight 362 5 0.1546468437 ( -0.6949374676 22.9932975769 -2.6968610287 ) - weight 363 6 0.4815303087 ( 0.7621283531 3.5413177013 -3.9776346684 ) - weight 364 7 0.3638228774 ( 2.0435094833 -3.3795995712 -1.8090840578 ) - weight 365 5 0.1531316042 ( 2.0245609283 23.5965881348 0.8108910918 ) - weight 366 6 0.4677073956 ( -3.4629607201 3.6919410229 -2.4978067875 ) - weight 367 7 0.3791610003 ( -2.4314396381 -3.4236733913 -1.6171352863 ) - weight 368 3 0.3039846122 ( 9.0277471542 -4.1181297302 -3.3883121014 ) - weight 369 4 0.5469626784 ( -5.2875618935 2.7387690544 1.9015026093 ) - weight 370 17 0.1490527093 ( 8.9297227859 -3.6702415943 -5.099840641 ) - weight 371 22 0.3324160576 ( 6.5781202316 1.6232719421 -4.6563382149 ) - weight 372 23 0.1443967223 ( -4.8837399483 3.553899765 -0.810301125 ) - weight 373 24 0.2850297987 ( 1.0430583954 -4.9611325264 -0.599029541 ) - weight 374 25 0.2381574363 ( -5.1004142761 -0.4250291288 -0.2711749673 ) - weight 375 22 0.2266537994 ( 8.715880394 3.7594718933 -3.1219182014 ) - weight 376 24 0.2749993503 ( -1.094701767 -3.4267127514 1.5371704102 ) - weight 377 25 0.4983468354 ( -3.096886158 0.0588836893 2.4194600582 ) - weight 378 22 0.3057387173 ( 6.6514701843 4.0911598206 -3.5549983978 ) - weight 379 23 0.1308492124 ( -3.7894015312 3.2985389233 1.648563385 ) - weight 380 24 0.3803289235 ( 0.9697084427 -3.8597927094 1.8688583374 ) - weight 381 25 0.183083117 ( -3.7029452324 -1.809912324 1.5830038786 ) - weight 382 22 0.2374293655 ( 8.3510599136 5.5010185242 -1.598618269 ) - weight 383 23 0.0753508359 ( -1.9464309216 4.8695836067 3.3334989548 ) - weight 384 24 0.3531977534 ( -0.7298812866 -1.9034126997 3.278717041 ) - weight 385 25 0.3340220451 ( -1.418797493 -1.2700814009 3.3704550266 ) - weight 386 22 0.3466660976 ( 6.7255301476 5.7394523621 -0.8456683159 ) - weight 387 23 0.1131498292 ( -1.0904506445 3.2780127525 3.3153164387 ) - weight 388 24 0.4739112258 ( 0.8956484795 -1.1504627466 3.5171508789 ) - weight 389 25 0.0662728474 ( -0.8193630576 -2.7458558083 2.5166988373 ) - weight 390 17 0.3154843152 ( 3.4382812977 8.5811357498 -5.0335621834 ) - weight 391 19 0.464012742 ( 3.7111198902 -1.7517273426 -4.5096726418 ) - weight 392 22 0.2205028981 ( 3.7111198902 -9.1520576477 -5.334728241 ) - weight 393 17 0.449130863 ( -0.2814445794 8.4800519943 -5.1030197144 ) - weight 394 19 0.4540952146 ( 0 -1.8886709213 -4.7551064491 ) - weight 395 22 0.096773915 ( 0 -9.2668991089 -5.5912485123 ) - weight 396 17 0.1374716908 ( -0.2889641821 11.9718589783 -4.3709249496 ) - weight 397 19 0.5412513018 ( 0 1.651348114 -5.1989598274 ) - weight 398 22 0.3212770224 ( 0 -5.7015686035 -5.7222385406 ) - weight 399 26 1 ( 1.3738867044 10.347694397 2.9754035473 ) - weight 400 26 1 ( 2.2627801895 5.51841259 0.2142424136 ) - weight 401 26 0.3331983984 ( 3.0434458256 10.0306482315 0.1456521749 ) - weight 402 36 0.3078258038 ( -0.9099646211 1.8968099356 -0.1852007806 ) - weight 403 37 0.3589757979 ( -0.8482078314 1.533490777 1.5495654345 ) - weight 404 26 1 ( 0.9834482074 6.7014627457 2.6421263218 ) - weight 405 26 1 ( -1.3044602871 10.7035245895 3.250203371 ) - weight 406 26 1 ( -2.1119251251 7.6590094566 1.8955845833 ) - weight 407 26 1 ( -3.3610804081 11.0113306046 1.061011672 ) - weight 408 26 1 ( -3.3371822834 2.1001322269 0.5224716067 ) - weight 409 26 1 ( -3.4709730148 7.1876959801 -0.8652487993 ) - weight 410 26 1 ( -1.4335671663 6.7024683952 -2.7854459286 ) - weight 411 26 1 ( -3.468973875 11.049115181 -0.9946525097 ) - weight 412 26 1 ( -3.2083516121 1.9957014322 -2.0983309746 ) - weight 413 26 1 ( 1.8206892014 10.2446804047 -1.8300275803 ) - weight 414 26 1 ( 1.484651804 6.0889515877 -2.227080822 ) - weight 415 26 1 ( -1.0843970776 10.6558227539 -2.6841449738 ) - weight 416 32 1 ( 0.3017202914 0.1539534479 -0.7368940115 ) - weight 417 37 0.254422605 ( -1.004109621 -0.3972257674 0.3013441265 ) - weight 418 38 0.745577395 ( -0.9653754234 -0.4910493195 1.8103898764 ) - weight 419 37 0.254422605 ( 0.033903908 -0.7176336646 -0.4466316104 ) - weight 420 38 0.745577395 ( -0.0062878295 -0.8046805263 0.9610445499 ) - weight 421 26 0.3331983984 ( 2.4612901211 11.5458126068 -1.1704618931 ) - weight 422 36 0.3078258038 ( 0.0368421115 0.6801607013 -1.5959119797 ) - weight 423 37 0.3589757979 ( 0.0985989273 0.5263347626 -0.0175907016 ) - weight 424 26 0.2839439809 ( 0.6076005101 12.1952381134 -0.728942275 ) - weight 425 36 0.4689332843 ( 0.6791445017 -1.0267057419 -0.743319869 ) - weight 426 37 0.2471227348 ( 0.7409012914 -1.2830889225 0.5876302123 ) - weight 427 32 0.4101817906 ( 0.6515015364 -0.7548061609 -0.5771866441 ) - weight 428 33 0.5898182392 ( -1.4182274342 0.2859310508 -0.5838063359 ) - weight 429 26 0.8549714684 ( 0.7184249163 10.4335622787 -0.7542367578 ) - weight 430 36 0.1450285167 ( 1.0854455233 0.4008005261 0.2124883533 ) - weight 431 26 1 ( -1.5944448709 10.5482110977 -0.780995667 ) - weight 432 32 0.8064539433 ( 0.8528350592 0.2682539523 0.4677162766 ) - weight 433 33 0.1935460418 ( -0.5352481604 0.8404892087 0.4610965848 ) - weight 434 32 0.4101817906 ( 1.7004761696 0.1182702929 -0.6270506978 ) - weight 435 33 0.5898182392 ( -0.0635229647 0.1204435527 -0.6336703897 ) - weight 436 32 0.8064539433 ( 1.7762019634 0.1405121684 0.1118120328 ) - weight 437 33 0.1935460418 ( 0.0045734025 0.0805437341 0.1051923409 ) - weight 438 33 0.5 ( 1.7717843056 0.0705038235 -0.7417898774 ) - weight 439 34 0.5 ( -0.0309342127 0.2819591165 0.6582369804 ) - weight 440 33 0.5 ( 2.0596888065 -0.3555833697 -0.7964020371 ) - weight 441 34 0.5 ( 0.4599120617 0.1286318153 0.7128491402 ) - weight 442 33 0.5 ( 1.8194402456 0.0818448663 -0.0653548837 ) - weight 443 34 0.5 ( -0.0281031765 0.2330542058 -0.0181980524 ) - weight 444 29 0.2609394193 ( 3.4309368134 0.6753624678 -0.8879337907 ) - weight 445 30 0.6099424958 ( 1.5632354021 -0.9322100282 -0.9845014811 ) - weight 446 31 0.12911807 ( 0.8138022423 0.7212357521 0.950912118 ) - weight 447 29 0.2609394193 ( 2.0289063454 0.6525265574 -1.5188808441 ) - weight 448 30 0.6099424958 ( 0.4959153235 0.0200381149 -1.5487322807 ) - weight 449 31 0.12911807 ( -0.4049782157 1.4699165821 1.5151429176 ) - weight 450 30 0.5 ( 2.4539115429 -0.0022552877 -1.3609032631 ) - weight 451 31 0.5 ( 0.1790011078 -0.3990978897 1.3273139 ) - weight 452 26 1 ( -2.256975174 10.8294582367 0.3255695701 ) - weight 453 26 0.2443206161 ( -1.5937421322 14.4684305191 0.0114921983 ) - weight 454 29 0.5839904547 ( 0.130099684 0.8935907483 1.015707612 ) - weight 455 30 0.1716888845 ( -0.5393765569 1.5135895014 1.0561078787 ) - weight 456 29 0.0691876858 ( 2.7896294594 1.3589675426 0.7738748193 ) - weight 457 30 0.4924322069 ( 1.6821824312 0.0087606357 0.6709818244 ) - weight 458 31 0.4383800626 ( -0.0533050038 0.3369191885 -0.7045711875 ) - weight 459 30 0.5 ( 2.566161871 -0.2897028327 -0.4935825169 ) - weight 460 31 0.5 ( 0.4865807891 -0.4240167439 0.4599931836 ) - weight 461 29 0.2834812105 ( 2.3106944561 0.6775743961 1.0197726488 ) - weight 462 30 0.5160946846 ( 0.8828514218 -0.1512182653 0.9703441262 ) - weight 463 31 0.2004240751 ( -0.1297591031 1.1485091448 -1.0039334297 ) - weight 464 29 0.2834812105 ( 1.535684824 -0.0638165399 0.9168609977 ) - weight 465 30 0.5160946846 ( -0.1941106617 -0.1504181623 0.9380452037 ) - weight 466 31 0.2004240751 ( -0.4399882555 2.1798217297 -0.9716345668 ) - weight 467 29 0.2609394193 ( 2.0918910503 -0.4460756183 -1.3169000149 ) - weight 468 30 0.6099424958 ( -0.2038748562 -0.8162207007 -1.2984223366 ) - weight 469 31 0.12911807 ( 0.1949292421 2.3804912567 1.2648329735 ) - weight 470 26 0.2443206161 ( -1.5851364136 14.2736988068 1.0361591578 ) - weight 471 29 0.5839904547 ( 0.1833594888 -0.1475297064 0.9815279245 ) - weight 472 30 0.1716888845 ( -1.2219905853 0.7250332832 1.068510294 ) - weight 473 26 0.2443206161 ( -1.3515815735 15.6122865677 0.3233171701 ) - weight 474 29 0.5839904547 ( 1.3121798038 0.8675627112 0.7582329512 ) - weight 475 30 0.1716888845 ( 0.2774288952 0.6762843132 0.746216476 ) - weight 476 33 0.5 ( -0.2717907727 -0.7016150355 -0.5614560246 ) - weight 477 34 0.5 ( 0.1214045286 2.4612157345 0.4779031277 ) - weight 478 26 1 ( -1.6943989992 10.706820488 1.6243963242 ) - weight 479 26 0.7828121781 ( 0.4625955224 10.5008792877 1.8324626684 ) - weight 480 36 0.2171877921 ( -0.7024562955 -0.3876839578 1.9279164076 ) - weight 481 32 0.8064539433 ( 0.5449220538 -0.9030780792 0.9237840772 ) - weight 482 33 0.1935460418 ( -1.599244833 0.2619217634 0.9171643853 ) - weight 483 37 0.254422605 ( -0.7746930122 -0.4592142403 -1.3552651405 ) - weight 484 38 0.745577395 ( -0.8418673873 -0.3774567246 0.145255819 ) - weight 485 37 0.2129600346 ( -0.8933224082 0.4041991234 -1.4816302061 ) - weight 486 38 0.7870399952 ( -0.8912465572 0.5015468597 0.1243261695 ) - weight 487 37 0.2129600346 ( -0.7217264771 0.0013161431 -2.6631321907 ) - weight 488 38 0.7870399952 ( -0.8268585801 0.2268794179 -1.103728652 ) - weight 489 26 0.3331983984 ( 2.9069874287 11.7396965027 -0.4752157629 ) - weight 490 36 0.3078258038 ( -0.8053517342 0.6403286457 -1.502491951 ) - weight 491 37 0.3589757979 ( -0.7435948849 0.4738155603 0.069332473 ) - weight 492 37 0.2129600346 ( -0.006632912 0.5838101506 -1.5316987038 ) - weight 493 38 0.7870399952 ( 0.0032355634 0.6135781407 0.0330243297 ) - weight 494 37 0.2793242335 ( -0.2083842158 -0.5226740837 -2.3211326599 ) - weight 495 38 0.7206758261 ( -0.3421795368 -0.3732011914 -0.858699739 ) - weight 496 37 0.254422605 ( 0.1748185605 -0.247811228 -1.482062459 ) - weight 497 38 0.745577395 ( 0.1132908612 -0.2300676256 -0.0229412988 ) - weight 498 37 0.2129600346 ( -0.0995892882 0.0552975312 -2.6405959129 ) - weight 499 38 0.7870399952 ( -0.2021555603 0.2274390757 -1.1186400652 ) - weight 500 26 0.6501254439 ( 1.7420004606 10.4314002991 0.5649607182 ) - weight 501 36 0.3498745561 ( -0.5262141824 0.7162458897 0.5142179728 ) - weight 502 26 1 ( 1.511102438 10.3411369324 -0.4202666581 ) - weight 503 33 0.5 ( -0.2364538312 -0.7071331143 0.2055225968 ) - weight 504 34 0.5 ( 0.1368438303 2.4289546013 -0.2890755236 ) - weight 505 33 0.5 ( 2.0911660194 -0.3682411611 -0.0935789272 ) - weight 506 34 0.5 ( 0.4810808599 0.1021193564 0.0100259921 ) - weight 507 32 0.8064539433 ( 0.4815154672 -0.8676565289 0.2664010823 ) - weight 508 33 0.1935460418 ( -1.6169074774 0.3323712051 0.2597813904 ) - weight 509 33 0.5 ( 0.9833032489 -0.7534092069 -0.2936167121 ) - weight 510 34 0.5 ( 0.531662941 1.2739366293 0.2100637704 ) - weight 511 4 0.211769715 ( -0.2060718834 21.3827342987 -1.9706429243 ) - weight 512 5 0.7882302999 ( 0.3228330016 0.502282083 -2.3997702599 ) - weight 513 4 0.2941013873 ( -1.8384666443 22.617975235 0.4862731397 ) - weight 514 5 0.7058986425 ( 2.670879364 1.7133342028 -0.5978268981 ) - weight 515 4 0.211769715 ( -0.62570858 22.7841949463 -2.3957443237 ) - weight 516 5 0.7882302999 ( 0.082568787 2.005297184 -2.3355960846 ) - weight 517 22 0.1330899894 ( 11.2868204117 3.4729499817 -0.3750983477 ) - weight 518 24 0.1222179085 ( -3.6656417847 -0.6798927784 1.2506484985 ) - weight 519 25 0.7446920872 ( -0.1484085619 2.2778730392 3.2064881325 ) - weight 520 22 0.4312410653 ( 5.3821601868 1.10679245 5.9322113991 ) - weight 521 23 0.1283100247 ( 5.7598204613 3.1315970421 -1.4025417566 ) - weight 522 24 0.3281306624 ( 2.2390184402 5.6274170876 -1.1155090332 ) - weight 523 20 0.1123182103 ( 1.3574771881 3.5538444519 -0.8615365028 ) - weight 524 22 0.4648121297 ( 4.0500798225 4.7070732117 4.0569815636 ) - weight 525 23 0.1376403272 ( 3.9741854668 1.120603919 1.9171510935 ) - weight 526 24 0.3975475132 ( 3.5710988045 3.752187252 2.4847717285 ) - weight 527 22 0.4866587222 ( 5.2421598434 5.5526542664 1.9103716612 ) - weight 528 23 0.0868105441 ( 1.7553220987 2.0221531391 2.9210691452 ) - weight 529 24 0.4265308082 ( 2.3790187836 1.6055772305 3.3303527832 ) - weight 530 22 0.7518678904 ( 3.0729999542 5.6567344666 2.9678616524 ) - weight 531 23 0.0723678172 ( 2.9501898289 -0.0638554767 2.686054945 ) - weight 532 24 0.175764218 ( 4.5481786728 2.6630673409 3.4344329834 ) - weight 533 22 0.7110148072 ( 3.6320300102 6.6992988586 1.0049716234 ) - weight 534 23 0.0715909079 ( 0.9553978443 0.1941411495 3.7845242023 ) - weight 535 24 0.217394352 ( 3.9891486168 0.7001771927 4.4769973755 ) - weight 536 22 0.5249072909 ( 4.5867500305 5.8286705017 -0.6713583469 ) - weight 537 23 0.0834142864 ( -0.7788876295 1.1682354212 3.0613641739 ) - weight 538 24 0.3916783631 ( 3.0344285965 -0.9761527777 3.6063690186 ) - weight 539 25 0.3857780397 ( -1.2215526104 12.0899715424 2.9997074604 ) - weight 540 26 0.6142219305 ( -2.2066631317 -0.3902872801 1.96496737 ) - weight 541 25 0.146963343 ( -0.4951398969 13.0806560516 3.1095454693 ) - weight 542 26 0.8530366421 ( -1.9260792732 0.7654191256 2.2917861938 ) - weight 543 25 0.0593079589 ( -3.2306706905 12.3572864532 1.7115132809 ) - weight 544 26 0.9406920671 ( -3.603880167 -0.6601116657 0.0304296091 ) - weight 545 25 0.0593079589 ( -2.8961610794 13.704782486 1.7667094469 ) - weight 546 26 0.9406920671 ( -3.7632584572 0.7148704529 0.1517249048 ) - weight 547 25 0.1007401645 ( -1.7324892282 13.6813201904 -2.5044190884 ) - weight 548 26 0.8992598653 ( -1.2273775339 1.4116054773 -3.4093267918 ) - weight 549 25 0.0593079589 ( -3.5300974846 13.7525482178 -0.5543946624 ) - weight 550 26 0.9406920671 ( -3.5173060894 0.753947854 -2.2419462204 ) - weight 551 22 0.1032253429 ( 10.456870079 2.0270195007 -3.0863785744 ) - weight 552 24 0.1232035086 ( -2.835691452 -3.3911731243 -0.1952819824 ) - weight 553 25 0.7735711336 ( -3.0894238949 2.4802644253 2.0064713955 ) - weight 554 22 0.8149345517 ( 2.3048799038 3.7849845886 5.9193916321 ) - weight 555 23 0.0842731968 ( 5.9450268745 -0.3314335346 0.7458642125 ) - weight 556 24 0.1007922292 ( 5.3162984848 5.6145973206 1.5626831055 ) - weight 557 22 0.8149345517 ( 1.8106399775 4.6890602112 4.1403317451 ) - weight 558 23 0.0842731968 ( 4.2014536858 -1.0768156052 1.5402439833 ) - weight 559 24 0.1007922292 ( 5.8105387688 3.8355374336 2.466758728 ) - weight 560 22 0.7081469893 ( 0 4.1182136536 4.7094516754 ) - weight 561 39 0.0580335744 ( -4.8858919144 -2.7320172787 0.6917703748 ) - weight 562 40 0.0559075251 ( -7.6211800575 4.4046597481 1.8958892822 ) - weight 563 23 0.0608324744 ( 4.8858952522 -2.7320113182 0.6916880012 ) - weight 564 21 0.1170794815 ( 4.2523598671 6.4369392395 -2.0842962265 ) - weight 565 17 0.1166878492 ( 0.4455222189 8.9692087173 8.0448865891 ) - weight 566 19 0.2024046481 ( 0 2.8528363705 7.5393362045 ) - weight 567 22 0.3595457375 ( 0 -5.6243476868 7.0723614693 ) - weight 568 21 0.1797282845 ( 4.2523598671 -3.3056221008 0.2786135674 ) - weight 569 20 0.0608123504 ( -4.0246829987 -3.1772956848 0.2786135674 ) - weight 570 18 0.0808211118 ( 0.0817569122 8.888874054 -0.7309865952 ) - weight 571 19 0.1394121796 ( 0 7.6542425156 6.9932894707 ) - weight 572 22 0.5321753025 ( 0 -0.7935295105 6.9504418373 ) - weight 573 21 0.2532346845 ( 4.2523598671 1.5251960754 0.1566939354 ) - weight 574 20 0.0751778483 ( -4.0246829987 1.6535224915 0.1566939354 ) - weight 575 17 0.2491469532 ( 0.4429515898 3.5669803619 6.6577248573 ) - weight 576 19 0.2161560208 ( 0 -2.7068157196 7.984940052 ) - weight 577 22 0.1518869698 ( 0 -11.2016487122 7.0275816917 ) - weight 578 21 0.0964680836 ( 4.2523598671 -8.8829231262 0.2338337898 ) - weight 579 18 0.2863419652 ( 0.0817569122 3.3115730286 -0.7757663727 ) - weight 580 3 0.3012105525 ( 0 2.2702026367 5.8363952637 ) - weight 581 10 0.0854251087 ( -6.5703468323 -4.4372768402 -2.0101983547 ) - weight 582 17 0.1796664894 ( 0.4464160502 0.186133042 5.8805112839 ) - weight 583 19 0.0746652707 ( 0 -6.1565976143 8.3499164581 ) - weight 584 22 0.0535382256 ( 0 -14.6701583862 7.087931633 ) - weight 585 18 0.3054943085 ( 0.0817569122 -0.1569366455 -0.7154164314 ) - weight 586 3 0.4885969758 ( 0 -1.383026123 5.4094052315 ) - weight 587 10 0.2061578184 ( -6.1548333168 -0.8758280277 -2.8298521042 ) - weight 588 17 0.1523978114 ( 0.4219042659 -3.2567675114 4.5865883827 ) - weight 589 18 0.1528473794 ( 0.0817569122 -3.8101654053 -1.1424064636 ) - weight 590 3 0.4010512531 ( 2.1574800014 -2.1150360107 5.6972951889 ) - weight 591 4 0.3483966589 ( 5.6536464691 0.2298346609 -0.8835330606 ) - weight 592 17 0.1250915676 ( 2.5923531055 -4.0066213608 4.568965435 ) - weight 593 18 0.1254605204 ( 2.2392368317 -4.542175293 -0.8545165062 ) - weight 594 3 0.3874215484 ( 2.2408599854 -2.2401275635 6.591545105 ) - weight 595 4 0.3705413938 ( 6.4595313072 0.428953737 -0.5185884237 ) - weight 596 17 0.1208403111 ( 2.7269308567 -4.3419766426 5.4006562233 ) - weight 597 18 0.1211967245 ( 2.3226168156 -4.6672668457 0.0397334099 ) - weight 598 3 0.2841071188 ( 6.6758599281 -3.1631278992 5.3717050552 ) - weight 599 4 0.413276881 ( 3.7410595417 2.0066757202 2.9642076492 ) - weight 600 17 0.2037015706 ( 7.0845909119 -4.883026123 3.7492241859 ) - weight 601 18 0.0989144072 ( 6.7576169968 -5.5902671814 -1.1801066399 ) - weight 602 3 0.2415263206 ( 6.9015197754 -7.9605789185 4.9454550743 ) - weight 603 4 0.7584736943 ( 3.2411570549 6.7312808037 2.1418004036 ) - weight 604 3 0.0694552287 ( 3.2414617538 -12.6572685242 7.3027234077 ) - weight 605 4 0.9305447936 ( 6.7230143547 10.8882513046 -1.2652360201 ) - weight 606 3 0.0569545068 ( 7.107629776 -12.7721977234 5.1543951035 ) - weight 607 4 0.9430454969 ( 3.341966629 11.5104980469 1.5199215412 ) - weight 608 3 0.2204308957 ( 2.8709900379 -8.1457481384 7.1078953743 ) - weight 609 4 0.7259786129 ( 6.6923952103 6.3770184517 -0.8446788788 ) - weight 610 17 0.0535904989 ( 3.385663271 -10.1891098022 4.4429841042 ) - weight 611 3 0.0598914735 ( 3.0956466198 -12.6031303406 6.6354465485 ) - weight 612 4 0.9401085377 ( 6.1511688232 10.7639760971 -1.6216058731 ) - weight 613 4 1 ( -5.8941936493 11.1655092239 -2.4860715866 ) - weight 614 3 0.2549369335 ( 0 -12.4476776123 -8.729724884 ) - weight 615 10 0.3233954608 ( 7.1110687256 9.0196752548 -9.7894763947 ) - weight 616 4 0.2400700003 ( -7.1143689156 9.0195102692 -9.7872667313 ) - weight 617 17 0.1815975606 ( -0.3897661567 -10.5944566727 -11.7792606354 ) - weight 618 3 0.2549369335 ( 0 -7.1879882813 -7.8847050667 ) - weight 619 10 0.3233954608 ( 6.2976026535 3.9080994129 -8.5291366577 ) - weight 620 4 0.2400700003 ( -6.3009915352 3.9079728127 -8.5267152786 ) - weight 621 17 0.1815975606 ( -0.3412570059 -5.6929726601 -9.6932382584 ) - weight 622 3 0.2178441584 ( 4.8472700119 -3.1843490601 -6.782854557 ) - weight 623 4 0.3727830052 ( -6.973341465 0.8740363717 -2.9515554905 ) - weight 624 17 0.4093729258 ( 4.5612721443 -2.0052709579 -7.9310541153 ) - weight 625 3 0.4609292448 ( 0 -6.2573661804 5.8062353134 ) - weight 626 10 0.3031090796 ( -6.5038881302 3.9431068897 -3.5866148472 ) - weight 627 4 0.0515956432 ( 6.5027599335 3.9418811798 -3.5900447369 ) - weight 628 17 0.0820978731 ( 0.4446846843 -8.0829677582 3.7966890335 ) - weight 629 18 0.1022682115 ( 0.0817569122 -8.6845054626 -0.7455763817 ) - weight 630 3 0.2376738042 ( 0 -12.8357467651 -3.439874649 ) - weight 631 10 0.3959723413 ( 2.1682360172 9.768119812 -8.0170927048 ) - weight 632 4 0.3006516397 ( -2.1706299782 9.7675151825 -8.0172271729 ) - weight 633 17 0.0657022223 ( -0.0860972106 -12.2435073853 -6.7472105026 ) - weight 634 3 0.0635128096 ( 0 -10.433467865 1.2413551807 ) - weight 635 10 0.1958739907 ( -2.2182240486 7.731470108 -5.9444403648 ) - weight 636 4 0.7406132221 ( 2.216511488 7.7305316925 -5.9463458061 ) - weight 637 3 0.2185422033 ( 0 -3.5949287415 -7.5547347069 ) - weight 638 10 0.1087745428 ( 5.973045826 0.3990656435 -7.7543458939 ) - weight 639 4 0.0951625928 ( -5.9765372276 0.3989852667 -7.7516708374 ) - weight 640 17 0.4620711505 ( -0.3223147392 -2.2851319313 -8.5078191757 ) - weight 641 19 0.1154495254 ( 0 -13.176027298 -4.4738788605 ) - weight 642 3 0.2178441584 ( 4.8128800392 -0.9101257324 -6.3873047829 ) - weight 643 4 0.3727830052 ( -6.5812325478 -1.3398913145 -2.4276194572 ) - weight 644 17 0.4093729258 ( 4.5496459007 0.1063352078 -6.9979314804 ) - weight 645 3 0.2251323164 ( 8.735039711 -1.0005874634 -2.5254654884 ) - weight 646 4 0.3628976941 ( -4.3631567955 -0.3157050908 2.5055847168 ) - weight 647 17 0.4119699895 ( 8.6870298386 -0.8561355472 -3.4963572025 ) - weight 648 3 0.2185422033 ( 0 -0.859046936 -7.3067646027 ) - weight 649 10 0.1087745428 ( 5.7289843559 -2.2730636597 -7.1655359268 ) - weight 650 4 0.0951625928 ( -5.7325534821 -2.2731084824 -7.1626672745 ) - weight 651 17 0.4620711505 ( -0.3080797791 0.3105072379 -7.6083779335 ) - weight 652 19 0.1154495254 ( 0 -10.4289388657 -4.467335701 ) - weight 653 12 0.0843834653 ( 0.2005146742 6.4286642075 4.4115843773 ) - weight 654 13 0.5620473027 ( 1.5335928202 3.6064870358 2.4241364002 ) - weight 655 14 0.3535692692 ( 1.4949829578 -1.4960964918 2.4291889668 ) - weight 656 11 0.0935239866 ( -3.8111169338 18.6099414825 -1.035648942 ) - weight 657 12 0.6671485305 ( 0.7658381462 3.1304476261 2.2976410389 ) - weight 658 13 0.2393274605 ( 1.2482603788 -0.3180600107 2.8520338535 ) - weight 659 12 0.4737676382 ( 1.8243260384 5.0132069588 1.8210150003 ) - weight 660 13 0.5262323618 ( 2.2546744347 0.5913562775 1.1049093008 ) - weight 661 13 0.5046935678 ( -2.2403481007 4.8383469582 -0.8591219187 ) - weight 662 14 0.495306462 ( -2.2457540035 -0.1773362309 -0.8583106995 ) - weight 663 13 0.5011257529 ( 2.0092220306 4.9650716782 -0.9881343842 ) - weight 664 14 0.4988743067 ( 2.0056653023 -0.1622206718 -0.9877607226 ) - weight 665 12 0.4963374138 ( -2.4832983017 6.207262516 -1.8910052776 ) - weight 666 13 0.5036625266 ( -2.8364603519 0.2825944424 -1.6781654358 ) - weight 667 12 0.4661476612 ( 2.9381551743 6.680390358 -0.1895405501 ) - weight 668 13 0.4800623953 ( 2.864084959 0.4030625522 -1.661968708 ) - weight 669 14 0.0537899137 ( 2.7408871651 -4.7473258972 -1.6458107233 ) - weight 670 11 0.3033103049 ( -1.7669993639 19.893743515 0.9123718739 ) - weight 671 12 0.6966896653 ( 2.0454998016 1.4687638283 0.0123342369 ) - weight 672 11 0.6232063174 ( -2.7536978722 19.8182964325 3.4391257763 ) - weight 673 12 0.2971909642 ( 4.5328111649 0.67581743 0.7527865767 ) - weight 674 13 0.079602696 ( 4.244515419 -4.0007386208 2.6026237011 ) - weight 675 11 0.5 ( 1.1285079718 20.9284076691 2.73594594 ) - weight 676 12 0.5 ( 2.7857880592 -0.802236855 -2.6474480629 ) - weight 677 11 0.2689843774 ( -4.016559124 18.5647945404 0.8035929799 ) - weight 678 12 0.5431468487 ( 2.3730940819 2.2326209545 2.4917829037 ) - weight 679 13 0.1878687739 ( 2.7789907455 -1.2632454634 3.2885482311 ) - weight 680 11 0.1060663685 ( -3.8947963715 17.6123886108 -2.6348767281 ) - weight 681 12 0.4873141348 ( -0.9071973562 3.5118243694 3.0819528103 ) - weight 682 13 0.3494953811 ( -0.103266716 0.8336921334 3.4895937443 ) - weight 683 14 0.0571241342 ( -0.2137238085 -4.2214417458 3.5042312145 ) - weight 684 11 0.3997223675 ( 1.1584303379 23.7406368256 2.4658257961 ) - weight 685 12 0.416490972 ( 3.5817551613 0.8614726663 -4.7877759933 ) - weight 686 13 0.1837866157 ( 1.7758827209 -6.9593873024 -1.4948220253 ) - weight 687 11 0.4107972383 ( 3.041066885 23.354347229 0.2583816051 ) - weight 688 12 0.4213652015 ( 0.8306990862 0.6585357785 -5.7659673691 ) - weight 689 13 0.1678375453 ( -1.146812439 -7.0609116554 -1.6127067804 ) - weight 690 13 0.5249262452 ( -0.3187460303 4.7918243408 1.1942294836 ) - weight 691 14 0.475073725 ( -0.3258395195 -0.2669892311 1.1951893568 ) - weight 692 11 0.0803422183 ( -2.1340589523 18.395866394 -3.2236111164 ) - weight 693 12 0.6961277723 ( -1.8226180077 3.1415815353 1.3253749609 ) - weight 694 13 0.2235300243 ( -1.5025411844 -0.2899706066 2.5730495453 ) - weight 695 12 0.1096295714 ( -2.851449728 6.0545563698 3.1862447262 ) - weight 696 13 0.5836595297 ( -1.7587673664 3.2957522869 2.2837510109 ) - weight 697 14 0.3067108989 ( -1.8043893576 -1.7211194038 2.2898793221 ) - weight 698 11 0.120941259 ( -0.4893733263 19.3922729492 -3.2120206356 ) - weight 699 12 0.7397739887 ( -2.1099298 2.6337282658 -0.5069710016 ) - weight 700 13 0.13928473 ( -2.3319923878 -1.7106440067 1.5772321224 ) - weight 701 11 0.1834091842 ( -1.6652474403 17.6618995667 -4.2978248596 ) - weight 702 12 0.5260417461 ( -3.1817188263 3.02911973 1.5547704697 ) - weight 703 13 0.2905490696 ( -2.7451124191 0.0778421834 3.055911541 ) - weight 704 11 0.307454288 ( 1.1555119753 19.5911369324 -3.7368063927 ) - weight 705 12 0.5233104229 ( -3.1400585175 1.9830665588 -1.746353507 ) - weight 706 13 0.1692353189 ( -3.7135102749 -2.7122008801 1.2472529411 ) - weight 707 11 0.5 ( 2.5797736645 20.61211586 0.7229776978 ) - weight 708 12 0.5 ( 0.3974426091 -0.7988772988 -3.3917920589 ) - weight 709 3 0.2396446764 ( -8.9375400543 2.2950515747 1.6243751049 ) - weight 710 10 0.1261993945 ( 0.5424489975 -3.2338209152 4.7411856651 ) - weight 711 17 0.5096623302 ( -8.7181806564 1.0997873545 2.3032550812 ) - weight 712 19 0.0713101402 ( -8.9375400543 -6.5020551682 4.1520137787 ) - weight 713 18 0.0531834662 ( -8.8557834625 -0.1320877075 -4.9274363518 ) - weight 714 3 0.1069236025 ( -7.8959798813 5.1963424683 -3.1774246693 ) - weight 715 10 0.055033993 ( 4.6477079391 -6.5960149765 2.6430633068 ) - weight 716 17 0.5240889192 ( -7.9539899826 5.0850338936 -1.7084081173 ) - weight 717 19 0.1887804121 ( -7.8959798813 -4.0340409279 -0.8862079978 ) - weight 718 22 0.1251730919 ( -7.8959798813 -11.7440185547 -1.9258882999 ) - weight 719 3 0.2251323164 ( -8.6952495575 1.7104263306 -2.571845293 ) - weight 720 10 0.3628976941 ( 4.3813061714 -2.9914600849 2.9486465454 ) - weight 721 17 0.4119699895 ( -8.7171773911 1.5450893641 -1.9169894457 ) - weight 722 3 0.2515031099 ( -9.0758104324 -1.4819068909 1.7993451357 ) - weight 723 10 0.4060203135 ( 0.4449805021 0.5145294666 4.2356987 ) - weight 724 17 0.3424766064 ( -8.8461780548 -2.6099052429 1.5704886913 ) - weight 725 3 0.0989223495 ( -8.4342899323 5.5740737915 1.8654052019 ) - weight 726 10 0.0575829931 ( 0.1236150041 -6.5259232521 4.9647574425 ) - weight 727 17 0.3998931944 ( -8.2019233704 4.2311964035 3.2987949848 ) - weight 728 19 0.1923786998 ( -8.4342899323 -3.2145380974 4.103905201 ) - weight 729 22 0.1035134494 ( -8.4342899323 -11.3662872314 3.1169416904 ) - weight 730 21 0.0805758238 ( -4.1819300652 -9.0475616455 -3.6768062115 ) - weight 731 18 0.0671336129 ( -8.3525333405 3.1469345093 -4.6864066124 ) - weight 732 3 0.2790404558 ( -6.444149971 2.2682609558 5.2955350876 ) - weight 733 10 0.1333959997 ( -3.7749552727 -3.3768761158 3.7239918709 ) - weight 734 17 0.3836249709 ( -6.0181555748 0.2252162695 5.7150168419 ) - weight 735 19 0.0836782604 ( -6.444149971 -6.2060699463 7.8113207817 ) - weight 736 18 0.1202602759 ( -6.3623929024 -0.1588783264 -1.2562766075 ) - weight 737 3 0.174553141 ( -1.0088499784 -10.5870780945 1.3821251392 ) - weight 738 10 0.6818998456 ( -1.9906377792 8.0638160706 -4.9963154793 ) - weight 739 4 0.0889235511 ( 2.7054669857 7.7195429802 -6.8529834747 ) - weight 740 17 0.054623533 ( -0.8164719343 -11.234913826 -1.476986289 ) - weight 741 3 0.0532003716 ( -3.5289063454 -11.8854789734 3.4735531807 ) - weight 742 10 0.9467996359 ( -3.044267416 9.9138250351 -2.1895499229 ) - weight 743 3 0.0597552843 ( -3.3046152592 -16.349653244 0.7676105499 ) - weight 744 10 0.9402447343 ( -0.5746109486 14.0761737823 -4.1585416794 ) - weight 745 3 0.1727394462 ( -2.5361399651 -13.0034599304 -3.9219045639 ) - weight 746 10 0.7542150021 ( 3.5207321644 10.3308830261 -5.8848314285 ) - weight 747 17 0.0730455071 ( -2.6457262039 -12.3254108429 -7.1133761406 ) - weight 748 3 0.1491877884 ( -6.2747101784 -12.6114120483 -7.7310824394 ) - weight 749 10 0.7921545506 ( 8.4079618454 10.3170986176 -3.7041788101 ) - weight 750 17 0.0586576648 ( -6.5968008041 -11.0803670883 -10.501490593 ) - weight 751 3 0.2580770552 ( -2.3561799526 -12.6595573425 -8.5002851486 ) - weight 752 10 0.6327911019 ( 7.7347865105 9.6446037292 -7.5827679634 ) - weight 753 17 0.1091318205 ( -2.7288894653 -10.8878726959 -11.4767217636 ) - weight 754 10 1 ( -2.0194113255 17.0197486877 -1.7512795925 ) - weight 755 3 0.0563600622 ( -6.9160900116 -13.04296875 4.1621651649 ) - weight 756 10 0.9436399341 ( -2.4791574478 11.6754808426 0.9511828423 ) - weight 757 10 0.9282485247 ( 1.5941376686 17.51603508 -5.0863404274 ) - weight 758 11 0.0717514902 ( 3.5932602882 -2.562561512 -0.903672576 ) - weight 759 10 0.6559420824 ( 0.7538217902 19.7825641632 0.8479977846 ) - weight 760 11 0.3440578878 ( -2.6978392601 -1.353615284 -1.0457158089 ) - weight 761 10 1 ( 6.5137424469 11.1488857269 0.7472459674 ) - weight 762 3 0.192728743 ( -8.801817894 -7.0334854126 -4.1119995117 ) - weight 763 10 0.8072712421 ( 5.8980374336 5.5149564743 0.9041836262 ) - weight 764 10 0.740267396 ( 4.2336611748 20.0336475372 -5.3213167191 ) - weight 765 11 0.2597326636 ( 3.7972021103 0.4693011642 1.1278017759 ) - weight 766 10 0.5014052391 ( 2.149392128 20.8791847229 -5.5186281204 ) - weight 767 11 0.4985947609 ( 3.5267856121 0.8683485389 -1.0780266523 ) - weight 768 10 0.3635103106 ( 5.4534173012 22.884431839 -5.2546839714 ) - weight 769 11 0.6364896297 ( 3.4337935448 3.4790241718 1.7825651169 ) - weight 770 10 0.2838164866 ( 7.1277294159 21.8929901123 -3.204638958 ) - weight 771 11 0.7161834836 ( 1.8627427816 2.600127697 3.9616250992 ) - weight 772 11 1 ( 4.1747879982 5.6384506226 2.5484638214 ) - weight 773 11 1 ( 1.9424036741 5.411593914 4.9871740341 ) - weight 774 10 0.0533990003 ( 3.1104099751 24.6857204437 0.2727412879 ) - weight 775 11 0.9466010332 ( -2.6117572784 3.971694231 0.2028980851 ) - weight 776 10 0.3121370077 ( 4.4104804993 21.7292518616 1.1969943047 ) - weight 777 11 0.6878629327 ( -2.8097553253 1.2642891407 2.1817588806 ) - weight 778 10 0.0613344088 ( 6.7926464081 24.7603626251 0.0432994515 ) - weight 779 11 0.9386655688 ( -1.8381592035 4.8623752594 3.699369669 ) - weight 780 10 0.2215298414 ( 7.4688601494 22.7167358398 -0.8187316656 ) - weight 781 11 0.7784701586 ( -0.5479092002 3.1467094421 4.5760245323 ) - weight 782 10 0.6404342651 ( 6.21342659 19.7115879059 -0.6915683746 ) - weight 783 11 0.3595657051 ( -0.3523505926 -0.046237547 3.9514863491 ) - weight 784 10 0.8282259107 ( -0.7209715843 19.3569717407 -2.37758708 ) - weight 785 11 0.1717740893 ( 0.2891767919 -1.6436548233 -2.9832799435 ) - weight 786 10 0.6559420824 ( 1.1478339434 21.2382259369 0.2823551893 ) - weight 787 11 0.3440578878 ( -2.3346142769 0.215525791 -1.0426588058 ) - weight 788 10 0.3121370077 ( 3.7808356285 20.3172340393 1.7208317518 ) - weight 789 11 0.6878629327 ( -3.1757318974 -0.3073510826 1.9354708195 ) - weight 790 3 0.0671593621 ( -7.8446297646 -21.3117198944 -5.241314888 ) - weight 791 10 0.7200645804 ( 6.6775922775 19.3091106415 -2.9910881519 ) - weight 792 11 0.21277605 ( 2.0256447792 -0.0247785393 4.0510172844 ) - weight 793 11 1 ( 2.793422699 10.4113874435 4.7221670151 ) - weight 794 11 1 ( 3.6400504112 10.014257431 1.8300765753 ) - weight 795 11 1 ( 4.2849411964 13.5269527435 1.7910120487 ) - weight 796 11 1 ( 3.0211541653 10.480055809 -1.1083557606 ) - weight 797 10 0.0812822282 ( 3.5914700031 26.3057136536 -5.7968540192 ) - weight 798 11 0.918717742 ( 3.0948572159 6.464184761 -0.7551316023 ) - weight 799 11 1 ( -2.0436594486 8.7029666901 4.2525582314 ) - weight 800 11 1 ( -2.0114254951 11.6826839447 1.4886935949 ) - weight 801 11 1 ( -1.8060920238 15.6041793823 3.1001291275 ) - weight 802 11 1 ( -2.9188184738 14.9884338379 -1.3725756407 ) - weight 803 11 1 ( 0.7908785343 12.6231794357 3.931704998 ) - weight 804 11 1 ( 2.0547904968 16.7860774994 4.3061261177 ) - weight 805 11 0.9168231487 ( 4.2297925949 17.2570705414 0.7401224375 ) - weight 806 12 0.0831768736 ( -1.487857461 -3.6887886524 -1.9519144297 ) - weight 807 11 0.8543199301 ( 2.0495455265 16.9153442383 -2.481218338 ) - weight 808 12 0.1456800848 ( -3.4329314232 -0.7313294411 -0.3034566343 ) - weight 809 11 1 ( -0.6386532187 15.01126194 -3.22143507 ) - weight 810 11 1 ( -0.4396337867 10.07899189 -1.5343606472 ) - weight 811 11 1 ( -2.0637106895 10.1659154892 -0.3421333134 ) - weight 812 11 1 ( -1.0976872444 6.0287203789 -1.8638337851 ) - weight 813 11 0.5 ( 1.6393619776 20.7561244965 3.6193704605 ) - weight 814 12 0.5 ( 3.2564940453 -1.7031702995 -2.8419897556 ) - weight 815 41 1 ( 3.8567478657 7.0149393082 2.004317522 ) - weight 816 41 1 ( 3.2663300037 7.2312960625 -1.5945971012 ) - weight 817 41 0.8784247637 ( 3.3650350571 10.6294660568 1.7742807865 ) - weight 818 42 0.1215752512 ( 3.5733771324 -1.7166399956 0.8082985282 ) - weight 819 41 0.8984447718 ( 1.9083660841 9.9396057129 -2.078766346 ) - weight 820 42 0.1015552133 ( 1.5035066605 -1.2628608942 -2.7907962799 ) - weight 821 17 0.5152887702 ( -4.2171545029 5.684943676 -4.689473629 ) - weight 822 19 0.3591423929 ( -3.9909200668 -4.4172315598 -3.6816065311 ) - weight 823 22 0.125568822 ( -3.9909200668 -11.880027771 -4.7441482544 ) - weight 824 3 0.1464416832 ( -4.6321001053 1.9589729309 -6.3333845139 ) - weight 825 10 0.120930925 ( 6.4524345398 -4.1877865791 -2.0512900352 ) - weight 826 17 0.5861251354 ( -4.876663208 2.7473080158 -5.7281908989 ) - weight 827 19 0.1465022862 ( -4.6321001053 -7.5362710953 -3.7454090118 ) - weight 828 17 0.3153382242 ( -8.3086175919 7.7797026634 1.1818003654 ) - weight 829 19 0.3789919317 ( -8.3737802505 -0.5478342175 0.9463784099 ) - weight 830 22 0.2489299327 ( -8.3737802505 -8.4323768616 0.2060216665 ) - weight 831 21 0.0567399301 ( -4.1214203835 -6.1136512756 -6.5877261162 ) - weight 832 17 0.1273706257 ( -7.5906515121 10.647354126 -1.1126486063 ) - weight 833 19 0.4415688813 ( -7.4895000458 1.4214830399 -2.1102924347 ) - weight 834 22 0.363877058 ( -7.4895000458 -6.2020187378 -2.665728569 ) - weight 835 40 0.0671834275 ( -0.1316800117 -2.9705202579 -8.4243431091 ) - weight 836 17 0.316473484 ( -6.7851295471 8.2421922684 -2.9210119247 ) - weight 837 19 0.4292660952 ( -6.6178197861 -1.4368979931 -2.9898827076 ) - weight 838 22 0.2542604208 ( -6.6178197861 -8.972026825 -3.7931485176 ) - weight 839 17 0.1202539653 ( -4.7426395416 12.3882827759 -3.5770847797 ) - weight 840 19 0.4247384965 ( -4.4847998619 2.2807955742 -4.8395433426 ) - weight 841 22 0.3653951585 ( -4.4847998619 -5.1061477661 -5.3088884354 ) - weight 842 40 0.089612402 ( -3.1363801956 -5.6136798859 -7.3284721375 ) - weight 843 41 1 ( 1.1561261415 7.6366343498 -2.9281888008 ) - weight 844 41 0.8327695727 ( -1.4427342415 10.009853363 -2.6848526001 ) - weight 845 42 0.1672303826 ( -1.8871777058 -0.938195467 -2.7915349007 ) - weight 846 41 1 ( 3.5619637966 5.7611265182 1.7897075415 ) - weight 847 22 0.0771214515 ( -10.5706396103 -2.2360191345 2.5162317753 ) - weight 848 41 0.9228785634 ( 1.9020212889 4.9268174171 -2.3415699005 ) - weight 849 41 1 ( 1.7224888802 6.5966973305 3.8268032074 ) - weight 850 19 0.189502582 ( -7.2366700172 5.6184434891 5.9579463005 ) - weight 851 22 0.4047628939 ( -7.2366700172 -2.7304496765 5.7401714325 ) - weight 852 40 0.1485210061 ( -0.3845100403 5.435379982 -4.9527740479 ) - weight 853 21 0.2572135329 ( -2.9843101501 -0.4117240906 -1.0535764694 ) - weight 854 19 0.0508285165 ( -8.6673402786 8.395565033 4.8748426437 ) - weight 855 22 0.3103339374 ( -8.6673402786 0.1311225891 4.9053516388 ) - weight 856 39 0.0798272043 ( -4.5237159729 6.4590725899 -1.8480627537 ) - weight 857 40 0.1801317483 ( 1.0461602211 4.6005601883 -2.0912017822 ) - weight 858 41 0.2787561417 ( 0.8411581516 2.0180459023 -4.6540184021 ) - weight 859 21 0.1001224369 ( -4.4149804115 2.449848175 -1.8883962631 ) - weight 860 19 0.2537808418 ( -9.0340995789 3.8217997551 3.0478274822 ) - weight 861 22 0.4020117223 ( -9.0340995789 -4.2643585205 2.6834015846 ) - weight 862 40 0.076381281 ( 1.4129195213 2.3786098957 -6.4866828918 ) - weight 863 41 0.0616703294 ( 4.4256262779 4.7823185921 -2.6786162853 ) - weight 864 21 0.2061558366 ( -4.7817397118 -1.9456329346 -4.1103463173 ) - weight 865 22 0.2019269764 ( -10.2034502029 2.9910697937 3.9270217419 ) - weight 866 39 0.115218088 ( -3.448577404 7.4492030144 1.2113131285 ) - weight 867 40 0.2169577181 ( 2.5822701454 3.6222300529 0.7687454224 ) - weight 868 41 0.4658972621 ( -2.3162212372 1.7012797594 -3.4595828056 ) - weight 869 22 0.2104583681 ( -8.9566698074 5.3679389954 1.866071701 ) - weight 870 39 0.0883276537 ( -1.4721175432 5.7075328827 3.3353836536 ) - weight 871 40 0.2880037725 ( 1.3354897499 1.5612798929 3.145614624 ) - weight 872 41 0.4132102728 ( -3.4515111446 -0.6518012881 -1.3088597059 ) - weight 873 22 0.1066465601 ( -11.6276416779 2.5019798279 1.9945477247 ) - weight 874 40 0.082949616 ( 4.0064616203 1.6897560358 0.2796554565 ) - weight 875 41 0.8104037642 ( -2.5742735863 3.1631753445 -1.5106711388 ) - weight 876 19 0.0934283361 ( -9.1123199463 4.7844085693 1.4842790365 ) - weight 877 22 0.3328987956 ( -9.1123199463 -3.1680488586 1.2105116844 ) - weight 878 41 0.504265368 ( 3.573382616 4.2410945892 -1.1429809332 ) - weight 879 21 0.0694075301 ( -4.8599600792 -0.8493232727 -5.5832362175 ) - weight 880 19 0.3896191418 ( -8.652299881 3.1292157173 0.7079356313 ) - weight 881 22 0.4093904197 ( -8.652299881 -4.7486000061 0.2916916609 ) - weight 882 41 0.0671922043 ( 5.1998958588 4.7442626953 -0.3334945738 ) - weight 883 21 0.1337981522 ( -4.3999400139 -2.4298744202 -6.5020561218 ) - weight 884 19 0.1736020893 ( -8.3155002594 4.2229170799 -1.6327527761 ) - weight 885 22 0.331809938 ( -8.3155002594 -3.4533996582 -1.9438083172 ) - weight 886 40 0.1214219555 ( 0.6943202019 -2.2486000061 -5.6757240295 ) - weight 887 41 0.3731659949 ( 4.4652991295 3.7504241467 1.9602122307 ) - weight 888 41 0.88492769 ( -2.3163232803 10.4746017456 0.8628383279 ) - weight 889 42 0.1150723174 ( -2.1769552231 -1.4616116285 0.8426533341 ) - weight 890 41 0.4205686748 ( -3.020647049 11.5113430023 -0.5832348466 ) - weight 891 42 0.5794312954 ( -3.0170423985 -0.0437080227 -0.1298863143 ) - weight 892 41 0.2587660253 ( 1.855265975 12.3455028534 4.0511870384 ) - weight 893 42 0.7412339449 ( 2.5525527 -0.6670584679 3.6831521988 ) - weight 894 41 0.8383777142 ( 1.652395606 10.5092658997 3.883228302 ) - weight 895 42 0.1616222858 ( 2.1964707375 -2.3770570755 3.0584583282 ) - weight 896 41 0.4776410162 ( 3.2464129925 11.4837055206 -0.4490172267 ) - weight 897 42 0.5223590136 ( 3.1797749996 -0.2718236148 -1.0476199389 ) - weight 898 41 0.3601590693 ( 3.1873018742 12.0793809891 2.1052527428 ) - weight 899 42 0.6398409009 ( 3.5515034199 -0.4130382538 1.5455430746 ) - weight 900 41 0.5487061739 ( 1.1080173254 11.5891532898 -3.2024078369 ) - weight 901 42 0.4512938261 ( 0.6612677574 0.6554979682 -3.2752218246 ) - weight 902 41 1 ( -2.8816866875 8.815788269 0.3626794219 ) - weight 903 41 0.8383777142 ( -0.7790476084 10.6502408981 3.6524939537 ) - weight 904 42 0.1616222858 ( -0.2255709469 -2.1135749817 3.2805392742 ) - weight 905 41 1 ( -1.0676083565 6.6896262169 2.8288831711 ) - weight 906 17 0.2015561014 ( -5.4687080383 9.0515642166 7.8386945724 ) - weight 907 19 0.2642347813 ( -5.8918499947 2.8338274956 6.9797315598 ) - weight 908 22 0.3287962675 ( -5.8918499947 -5.5940971375 6.5132517815 ) - weight 909 21 0.2054128349 ( -1.6394901276 -3.2753715515 -0.2804961205 ) - weight 910 17 0.1560927927 ( -7.9505810738 9.2913618088 4.3402805328 ) - weight 911 19 0.3652572036 ( -8.1714000702 1.9104971886 3.4573440552 ) - weight 912 22 0.3252667487 ( -8.1714000702 -6.2042579651 2.9233417511 ) - weight 913 21 0.1533832401 ( -3.9190402031 -3.8855323792 -3.8704061508 ) - weight 914 17 0.1906848699 ( -1.4388072491 9.1209344864 9.1201210022 ) - weight 915 19 0.2058832794 ( -1.9390300512 3.336438179 8.3973207474 ) - weight 916 22 0.2979409397 ( -1.9390300512 -5.2180290222 7.9695315361 ) - weight 917 21 0.1714980751 ( 2.3133299351 -2.8993034363 1.1757836342 ) - weight 918 18 0.133992821 ( -1.8572731018 9.2951927185 0.1661834717 ) - weight 919 19 0.0948961601 ( -3.5795500278 8.8181762695 6.6815099716 ) - weight 920 22 0.4634767175 ( -3.5795500278 0.3933029175 6.7421717644 ) - weight 921 39 0.0722427592 ( -6.6840863228 1.5225303173 -2.3880689144 ) - weight 922 40 0.1664817035 ( -4.0416302681 6.4373803139 -1.8290214539 ) - weight 923 21 0.2029026896 ( 0.6728098392 2.7120285034 -0.0515761375 ) - weight 924 19 0.1344032288 ( -4.1019601822 8.4969930649 -5.6311721802 ) - weight 925 22 0.4274182618 ( -4.1019601822 1.1555709839 -5.5510883331 ) - weight 926 39 0.1332542896 ( 5.6173143387 1.1336321831 -1.6791850328 ) - weight 927 40 0.2516222596 ( -3.5192198753 -5.8558797836 -1.0667533875 ) - weight 928 41 0.0533020496 ( 3.23756814 -2.3043978214 5.6805362701 ) - weight 929 19 0.1979081333 ( -6.7445898056 5.6682634354 -4.2771639824 ) - weight 930 22 0.3774667084 ( -6.7445898056 -1.7812194824 -4.4509482384 ) - weight 931 39 0.0570001341 ( 4.6894845963 4.2792453766 -4.1414580345 ) - weight 932 40 0.1939489841 ( -0.8765902519 -4.7557396889 -4.0035438538 ) - weight 933 41 0.1736759692 ( 4.1239147186 1.5230221748 4.5041923523 ) - weight 934 19 0.1394121796 ( -1.4000600576 8.4774703979 7.1653380394 ) - weight 935 22 0.5321753025 ( -1.4000600576 0.011390686 7.1941814423 ) - weight 936 21 0.2532346845 ( 2.8522996902 2.330116272 0.4004335403 ) - weight 937 20 0.0751778483 ( -5.4247431755 2.458442688 0.4004335403 ) - weight 938 22 0.1055573449 ( -11.1468296051 0.6763305664 4.0388617516 ) - weight 939 40 0.0612346157 ( 3.5256495476 3.7340700626 -1.5459938049 ) - weight 940 41 0.8332080245 ( -0.932436645 3.7749972343 -3.6724853516 ) - weight 941 22 0.2346942276 ( -8.8396902084 -0.3195800781 -4.1728482246 ) - weight 942 40 0.2036777884 ( 1.2185101509 -4.4776396751 -2.5419044495 ) - weight 943 41 0.561627984 ( 1.7286127806 2.4455888271 4.3834686279 ) - weight 944 22 0.7280092239 ( -2.5946099758 6.8535728455 -0.7384383678 ) - weight 945 39 0.0894822627 ( 0.717651248 -0.9631283879 3.7520051003 ) - weight 946 40 0.1825084984 ( -5.0265703201 -1.0432300568 4.6312484741 ) - weight 947 22 0.4795843363 ( -3.6837999821 4.6725578308 -3.5961685181 ) - weight 948 39 0.1561301053 ( 3.6395401955 0.2794415355 1.7449256182 ) - weight 949 40 0.3642855883 ( -3.9373800755 -3.900960207 2.4502334595 ) - weight 950 10 1 ( -0.2287447602 11.9143943787 2.3799784184 ) - weight 951 10 1 ( 3.2270081043 11.9799909592 2.1580889225 ) - weight 952 10 1 ( 5.5210142136 11.3357019424 0.3562905788 ) - weight 953 3 0.2448486388 ( -2.6553499699 -8.3733863831 3.7454252243 ) - weight 954 10 0.6956244707 ( -3.6245586872 6.3317761421 -2.2527923584 ) - weight 955 17 0.0595268682 ( -2.3245892525 -9.6776733398 1.4380034208 ) - weight 956 3 0.3425111175 ( -4.8471999168 -6.9701766968 -7.3589849472 ) - weight 957 10 0.5228202343 ( 7.5275940895 4.5548715591 -3.8506779671 ) - weight 958 17 0.134668678 ( -5.1502838135 -5.6750760078 -8.8613071442 ) - weight 959 22 0.4028716385 ( -7.2713699341 0.9188499451 5.3783316612 ) - weight 960 39 0.1384224147 ( -5.0855345726 4.9873390198 -1.2901040316 ) - weight 961 40 0.3638387024 ( -0.3498101234 5.0735402107 -1.3034744263 ) - weight 962 21 0.0948672518 ( -3.019010067 3.237575531 -1.4154162407 ) - weight 963 3 0.0863266289 ( -5.78895998 5.7444610596 5.3466253281 ) - weight 964 17 0.3341448307 ( -5.3611130714 3.5957839489 6.5655584335 ) - weight 965 19 0.1688850224 ( -5.78895998 -2.7388324738 7.5566763878 ) - weight 966 22 0.1109910384 ( -5.78895998 -11.1958999634 6.5981616974 ) - weight 967 21 0.1000070646 ( -1.5366001129 -8.8771743774 -0.1955862045 ) - weight 968 18 0.1996454149 ( -5.7072029114 3.3173217773 -1.205186367 ) - weight 969 3 0.2953130901 ( -2.1477301121 2.2299842834 6.3577151299 ) - weight 970 10 0.1033319831 ( -6.2942972183 -3.9962930679 0.1381653249 ) - weight 971 17 0.1761487424 ( -1.6678453684 -0.0080037555 6.4956092834 ) - weight 972 19 0.0732033625 ( -2.1477301121 -6.1508393288 8.872754097 ) - weight 973 22 0.052489996 ( -2.1477301121 -14.7103767395 7.6092514992 ) - weight 974 18 0.2995128632 ( -2.0659732819 -0.1971549988 -0.1940965652 ) - weight 975 17 0.2491469532 ( -1.5796819925 3.171186924 7.3483424187 ) - weight 976 19 0.2161560208 ( -2.0632500648 -2.8667340279 8.6498289108 ) - weight 977 22 0.1518869698 ( -2.0632500648 -11.4193878174 7.6758418083 ) - weight 978 21 0.0964680836 ( 2.1891098022 -9.1006622314 0.8820939064 ) - weight 979 18 0.2863419652 ( -1.9814931154 3.0938339233 -0.1275062561 ) - weight 980 3 0.2450447083 ( -8.8855085373 -7.779296875 3.0419225693 ) - weight 981 10 0.7549552917 ( -0.7558537126 6.7586083412 3.3374741077 ) - weight 982 3 0.1918237954 ( -9.7403774261 -6.8306808472 -0.1620233953 ) - weight 983 10 0.7444337606 ( 2.5384733677 5.7492570877 3.180753231 ) - weight 984 17 0.0637424588 ( -9.6222438812 -7.3385162354 -1.5816470385 ) - weight 985 10 1 ( 2.3962855339 11.8112287521 3.4594862461 ) - weight 986 10 1 ( -0.182428062 11.874587059 3.0221283436 ) - weight 987 22 0.2993527055 ( -8.5918798447 3.382183075 4.2053418159 ) - weight 988 39 0.1691163778 ( -3.8300116062 5.8166475296 1.3411639929 ) - weight 989 40 0.4106554091 ( 0.9706997871 3.9005498886 1.1598587036 ) - weight 990 41 0.1208755374 ( -1.7615330219 0.1445468962 -3.7702181339 ) - weight 991 22 0.3791531324 ( -6.9991698265 4.0735282898 3.9729616642 ) - weight 992 39 0.1587525159 ( -3.7005906105 4.121878624 1.7650655508 ) - weight 993 40 0.4620943964 ( -0.622010231 3.6681699753 1.8512039185 ) - weight 994 22 0.3157365322 ( -7.269780159 5.4760780334 2.5088117123 ) - weight 995 39 0.1305618137 ( -2.2220628262 4.0695161819 3.1776251793 ) - weight 996 40 0.4652858675 ( -0.3513998985 2.2040197849 3.2537536621 ) - weight 997 41 0.0884157941 ( -2.6450941563 -2.1145343781 -2.0020470619 ) - weight 998 11 0.6010227203 ( 3.4487290382 20.3779506683 0.1991010308 ) - weight 999 12 0.3989772201 ( -0.4781655371 -1.1931943893 -3.7945179939 ) - weight 1000 11 0.1546468437 ( 0.6976568103 22.9507160187 -2.6980013847 ) - weight 1001 12 0.4815303087 ( -0.8493284583 3.5413177013 -3.959931612 ) - weight 1002 13 0.3638228774 ( -2.0435094833 -3.3795995712 -1.8090840578 ) - weight 1003 11 0.1531316042 ( -2.0279140472 23.5547103882 0.804913342 ) - weight 1004 12 0.4677073956 ( 3.4072511196 3.6919410229 -2.5732812881 ) - weight 1005 13 0.3791610003 ( 2.4314396381 -3.4236733913 -1.6171352863 ) - weight 1006 3 0.3039846122 ( -9.0277471542 -4.1181297302 -3.3883121014 ) - weight 1007 10 0.5469626784 ( 5.2887840271 2.7378349304 1.8994089365 ) - weight 1008 17 0.1490527093 ( -9.0959968567 -3.919970274 -4.0938816071 ) - weight 1009 22 0.3324160576 ( -6.5781202316 1.6232719421 -4.6563382149 ) - weight 1010 39 0.1443967223 ( 4.8837380409 3.5538811684 -0.8103061318 ) - weight 1011 40 0.2850297987 ( -1.0430598259 -4.9611296654 -0.5990524292 ) - weight 1012 41 0.2381574363 ( 1.4116080999 -0.5133979917 4.9002285004 ) - weight 1013 22 0.2266537994 ( -8.715880394 3.7594718933 -3.1219182014 ) - weight 1014 40 0.2749993503 ( 1.0947003365 -3.4267098904 1.537147522 ) - weight 1015 41 0.4983468354 ( -1.6504063606 0.0637289509 3.5665097237 ) - weight 1016 22 0.3057387173 ( -6.6514701843 4.0911598206 -3.5549983978 ) - weight 1017 39 0.1308492124 ( 3.7893998623 3.2985541821 1.6485618353 ) - weight 1018 40 0.3803289235 ( -0.9697098732 -3.8597900867 1.8688354492 ) - weight 1019 41 0.183083117 ( -0.7465817332 -1.8331073523 3.9466121197 ) - weight 1020 22 0.2374293655 ( -8.3510599136 5.5010185242 -1.598618269 ) - weight 1021 39 0.0753508359 ( 1.9464275837 4.8696212769 3.3334746361 ) - weight 1022 40 0.3531977534 ( 0.7298798561 -1.9034099579 3.2786941528 ) - weight 1023 41 0.3340220451 ( -2.9916303158 -1.2160393 2.1347858906 ) - weight 1024 22 0.3466660976 ( -6.7255301476 5.7394523621 -0.8456683159 ) - weight 1025 39 0.1131498292 ( 1.0904487371 3.2780492306 3.3153147697 ) - weight 1026 40 0.4739112258 ( -0.89564991 -1.1504600048 3.5171279907 ) - weight 1027 41 0.0662728474 ( -2.3346624374 -2.7009248734 1.3412877321 ) - weight 1028 17 0.3154843152 ( -3.9717187881 8.4784784317 -4.6200332642 ) - weight 1029 19 0.464012742 ( -3.7111198902 -1.7517273426 -4.5096726418 ) - weight 1030 22 0.2205028981 ( -3.7111198902 -9.1520576477 -5.334728241 ) - weight 1031 42 1 ( 0.0200959053 5.4158701897 -2.4085371494 ) - weight 1032 42 1 ( -2.4503111839 10.4237537384 -1.6595650911 ) - weight 1033 42 0.3331983984 ( 0.248769179 9.7673711777 -3.3772816658 ) - weight 1034 59 0.3078258038 ( 0.6891350746 -1.8510463238 0.3459380269 ) - weight 1035 60 0.3589757979 ( 0.7962598205 -1.38128829 -1.3684102297 ) - weight 1036 42 1 ( -2.2997217178 6.7847065926 -1.1140681505 ) - weight 1037 42 1 ( -2.6210236549 10.9107751846 1.0064938068 ) - weight 1038 42 1 ( -1.4059451818 7.8345994949 1.9115628004 ) - weight 1039 42 1 ( -0.354624331 11.1882925034 2.9822368622 ) - weight 1040 42 1 ( -0.293094039 2.2679579258 3.347484827 ) - weight 1041 42 1 ( 1.3673355579 7.2730493546 3.2096087933 ) - weight 1042 42 1 ( 3.1937220097 6.5948843956 1.1412689686 ) - weight 1043 42 1 ( 1.7029709816 11.118724823 3.0279657841 ) - weight 1044 42 1 ( 2.3130483627 2.0149121284 3.1472373009 ) - weight 1045 42 1 ( 2.5116844177 5.8856468201 -1.7285711765 ) - weight 1046 42 1 ( 2.325469017 10.0279474258 -2.2449808121 ) - weight 1047 42 1 ( 3.2931993008 10.5279865265 0.61454916 ) - weight 1048 60 0.2154719234 ( 0.7972320318 0.2890482843 -0.0887236521 ) - weight 1049 61 0.7845280766 ( 0.7628896832 0.3759047389 -1.5972530842 ) - weight 1050 56 1 ( -0.1920321435 -0.6766704321 0.4574462771 ) - weight 1051 60 0.2154719234 ( -0.3340330124 0.7221202254 0.457556814 ) - weight 1052 61 0.7845280766 ( -0.2910535634 0.8321457505 -0.9288354516 ) - weight 1053 42 0.2839439809 ( 1.4370514154 12.0446329117 -1.197181344 ) - weight 1054 59 0.4689332843 ( -1.0247991085 1.0213754177 0.7489199042 ) - weight 1055 60 0.2471227348 ( -0.9176743031 1.4064210653 -0.5672377944 ) - weight 1056 42 0.3331983984 ( 1.8360934258 11.1354932785 -3.1549258232 ) - weight 1057 59 0.3078258038 ( -0.4745385349 -0.83656317 1.7803317308 ) - weight 1058 60 0.3589757979 ( -0.367413789 -0.5776227713 0.1938902736 ) - weight 1059 56 1 ( -0.6210756302 0.2086301744 0.3698640764 ) - weight 1060 42 1 ( 1.4042080641 10.5487747192 1.1848039627 ) - weight 1061 42 0.8549714684 ( 1.299110651 10.3256940842 -1.1235650778 ) - weight 1062 59 0.1450285167 ( -1.2780147791 -0.3512305021 -0.2664779723 ) - weight 1063 56 0.8064539433 ( -0.700035274 -0.7238830328 -0.7712592483 ) - weight 1064 57 0.1935460418 ( 0.3546808064 -1.1668750048 -0.7214958072 ) - weight 1065 56 1 ( -1.5852206945 -0.7562256455 0.3024045527 ) - weight 1066 56 0.8064539433 ( -1.6399468184 -0.7141164541 -0.4374460876 ) - weight 1067 57 0.1935460418 ( -0.2823893428 -0.4757377803 -0.3876826763 ) - weight 1068 57 0.5 ( -2.10988307 -0.6644704342 0.2943509221 ) - weight 1069 58 0.5 ( 0.5027952194 0.2126314491 -0.2108553648 ) - weight 1070 57 0.5 ( -2.4400420189 -0.2689769864 0.3391590714 ) - weight 1071 58 0.5 ( 0.0291106682 0.4152223766 -0.2556635141 ) - weight 1072 57 0.5 ( -2.0971038342 -0.6478699446 -0.3835316896 ) - weight 1073 58 0.5 ( 0.4905668199 0.1956212372 0.467027247 ) - weight 1074 54 0.5349572301 ( -0.7844588757 -0.3680962622 1.0744719505 ) - weight 1075 55 0.4650427997 ( 0.6554608941 -1.0935063362 -1.040895462 ) - weight 1076 54 0.5349572301 ( -1.8326605558 0.5593644977 0.437767446 ) - weight 1077 55 0.4650427997 ( -0.5340838432 -0.356015265 -0.4041909873 ) - weight 1078 54 0.5 ( -2.7072348595 -0.4324189425 0.6642146707 ) - weight 1079 55 0.5 ( 0.1645652354 0.7666620016 -0.6306381822 ) - weight 1080 42 1 ( 0.3383007348 10.923584938 1.8646985292 ) - weight 1081 42 0.2443206161 ( 0.8235411048 14.5025577545 1.027395606 ) - weight 1082 53 0.5839904547 ( 0.0496862121 -0.9334039688 -1.4147603512 ) - weight 1083 54 0.1716888845 ( 0.6152150631 -1.6676182747 -1.46068573 ) - weight 1084 54 0.5 ( -2.7371511459 -0.1044312343 -0.1954369098 ) - weight 1085 55 0.5 ( -0.1581863463 0.7010700107 0.2290133983 ) - weight 1086 53 0.0691876858 ( -2.5861945152 -1.5596307516 -1.3677567244 ) - weight 1087 54 0.4924322069 ( -1.7131363153 -0.2957104146 -1.2634898424 ) - weight 1088 55 0.4383800626 ( 0.3192744255 -0.2247947752 1.2970663309 ) - weight 1089 53 0.2834812105 ( -2.1368486881 -0.8303858638 -1.5107094049 ) - weight 1090 54 0.5160946846 ( -0.8953325152 -0.0804822817 -1.4610224962 ) - weight 1091 55 0.2004240751 ( 0.3481174409 -1.0699540377 1.4945989847 ) - weight 1092 53 0.2834812105 ( -1.4118542671 -0.0662220046 -1.2851476669 ) - weight 1093 54 0.5160946846 ( 0.169365719 -0.0299610998 -1.3051159382 ) - weight 1094 55 0.2004240751 ( 0.6056656837 -2.1042671204 1.3386923075 ) - weight 1095 54 0.5349572301 ( -0.1085064635 0.5137090087 0.9470515847 ) - weight 1096 55 0.4650427997 ( 0.0050781346 -1.9943363667 -0.9134751558 ) - weight 1097 42 0.2443206161 ( -0.2098778188 14.3643980026 1.0577930212 ) - weight 1098 53 0.5839904547 ( -0.0659167022 0.0927545503 -1.2677874565 ) - weight 1099 54 0.1716888845 ( 1.2499855757 -0.8464744687 -1.3569766283 ) - weight 1100 42 0.2443206161 ( 0.5661029816 15.6500272751 0.7421413064 ) - weight 1101 53 0.5839904547 ( -1.1424219608 -0.9996068478 -1.2177131176 ) - weight 1102 54 0.1716888845 ( -0.2764536738 -0.890093565 -1.2062951326 ) - weight 1103 57 0.5 ( -0.1396016479 0.295471102 0.3316333294 ) - weight 1104 58 0.5 ( 0.1494941264 -1.9503929615 -0.2481377721 ) - weight 1105 42 1 ( -0.9832507372 10.8479213715 1.3476501703 ) - weight 1106 42 0.7828121781 ( -1.2674965858 10.5668239594 -0.7904796004 ) - weight 1107 59 0.2171877921 ( 0.6984576583 0.4209268987 -1.7677748203 ) - weight 1108 56 0.8064539433 ( -0.4912111163 0.5088008642 -1.1055318117 ) - weight 1109 57 0.1935460418 ( 1.3954418898 -0.4741027951 -1.0557683706 ) - weight 1110 60 0.2129600346 ( 0.3955566585 -0.2429424375 1.7703517675 ) - weight 1111 61 0.7870399952 ( 0.4278422296 -0.3353838623 0.2144673467 ) - weight 1112 60 0.2154719234 ( 0.3227148652 0.5740038157 1.5122992992 ) - weight 1113 61 0.7845280766 ( 0.4120118618 0.509305954 0.0546336956 ) - weight 1114 60 0.2793242335 ( 0.0594020523 0.3390905261 2.8498191833 ) - weight 1115 61 0.7206758261 ( 0.2095243484 0.1418247223 1.372751236 ) - weight 1116 42 0.3331983984 ( 1.1503784657 11.3424434662 -3.6097767353 ) - weight 1117 59 0.3078258038 ( 0.3726433516 -0.8000218272 1.8098319769 ) - weight 1118 60 0.3589757979 ( 0.4797680974 -0.5455716848 0.2282160521 ) - weight 1119 60 0.2129600346 ( -0.493804872 -0.4069849551 1.7117886543 ) - weight 1120 61 0.7870399952 ( -0.4744246602 -0.4191011786 0.1999955028 ) - weight 1121 60 0.2829802334 ( -0.3805698156 0.7671362758 2.3771731853 ) - weight 1122 61 0.7170197964 ( -0.218480885 0.6562663317 0.9824256301 ) - weight 1123 60 0.2154719234 ( -0.6410399675 0.4167833328 1.5118175745 ) - weight 1124 61 0.7845280766 ( -0.5601473451 0.431565851 0.1036731899 ) - weight 1125 60 0.2793242335 ( -0.5537670255 0.2871520817 2.741158247 ) - weight 1126 61 0.7206758261 ( -0.4112354517 0.1526217908 1.3018864393 ) - weight 1127 42 0.6501254439 ( -0.0536363535 10.3412094116 -2.1068847179 ) - weight 1128 59 0.3498745561 ( 0.3647232056 -0.6521641016 -0.3555502295 ) - weight 1129 42 1 ( 0.9338626266 10.2193365097 -1.8980699778 ) - weight 1130 57 0.5 ( -0.1082864031 0.3342523575 -0.4345587492 ) - weight 1131 58 0.5 ( 0.1213467866 -1.9915312529 0.5180543065 ) - weight 1132 57 0.5 ( -2.4111566544 -0.2257967442 -0.3625616431 ) - weight 1133 58 0.5 ( -0.0039483686 0.3751474619 0.4460572302 ) - weight 1134 56 0.8064539433 ( -0.4412201345 0.4163615704 -0.4525457621 ) - weight 1135 57 0.1935460418 ( 1.3623896837 -0.5738608837 -0.402782321 ) - weight 1136 57 0.5 ( -1.3658697605 0.2472067475 -0.0473303087 ) - weight 1137 58 0.5 ( -0.1566425413 -0.761972487 0.1308258772 ) - weight 1138 10 0.211769715 ( 0.2079494447 21.3829021454 -1.9682843685 ) - weight 1139 11 0.7882302999 ( -0.31194368 0.4594621956 -2.391358614 ) - weight 1140 10 0.2941013873 ( 1.8416267633 22.6176490784 0.4880268872 ) - weight 1141 11 0.7058986425 ( -2.6634552479 1.6705076694 -0.5939351916 ) - weight 1142 10 0.211769715 ( 0.6275741458 22.7843570709 -2.3934173584 ) - weight 1143 11 0.7882302999 ( -0.0723657086 1.9626016617 -2.3275358677 ) - weight 1144 22 0.1330899894 ( -11.2868204117 3.4729499817 -0.3750983477 ) - weight 1145 40 0.1222179085 ( 3.6656403542 -0.6798900366 1.2506256104 ) - weight 1146 41 0.7446920872 ( -3.0291631222 2.3473417759 0.8979914784 ) - weight 1147 22 0.4312410653 ( -5.3821601868 1.10679245 5.9322113991 ) - weight 1148 39 0.1283100247 ( -5.7598214149 3.131560564 -1.4025423527 ) - weight 1149 40 0.3281306624 ( -2.2390198708 5.6274199486 -1.1155319214 ) - weight 1150 21 0.1123182103 ( -1.1298003197 3.4255180359 -0.8615365028 ) - weight 1151 22 0.4648121297 ( -4.0500798225 4.7070732117 4.0569815636 ) - weight 1152 39 0.1376403272 ( -3.9741852283 1.1206159592 1.9171792269 ) - weight 1153 40 0.3975475132 ( -3.571100235 3.7521898746 2.4847488403 ) - weight 1154 22 0.4866587222 ( -5.2421598434 5.5526542664 1.9103716612 ) - weight 1155 39 0.0868105441 ( -1.7553229332 2.0221812725 2.9210848808 ) - weight 1156 40 0.4265308082 ( -2.3790202141 1.6055799723 3.330329895 ) - weight 1157 22 0.7518678904 ( -3.0729999542 5.6567344666 2.9678616524 ) - weight 1158 39 0.0723678172 ( -2.9501888752 -0.0638315827 2.6860997677 ) - weight 1159 40 0.175764218 ( -4.5481801033 2.6630699635 3.4344100952 ) - weight 1160 22 0.7110148072 ( -3.6320300102 6.6992988586 1.0049716234 ) - weight 1161 39 0.0715909079 ( -0.9553971291 0.1941823661 3.7845659256 ) - weight 1162 40 0.217394352 ( -3.9891500473 0.7001799345 4.4769744873 ) - weight 1163 22 0.5249072909 ( -4.5867500305 5.8286705017 -0.6713583469 ) - weight 1164 39 0.0834142864 ( 0.7788875699 1.1682679653 3.0613920689 ) - weight 1165 40 0.3916783631 ( -3.034430027 -0.9761500359 3.6063461304 ) - weight 1166 41 0.3857780397 ( -2.3313033581 12.1336078644 1.9996540546 ) - weight 1167 42 0.6142219305 ( -1.9012117386 -0.1870006025 2.3737337589 ) - weight 1168 41 0.146963343 ( -2.5777122974 13.1381340027 1.3277875185 ) - weight 1169 42 0.8530366421 ( -2.1746573448 0.9714481235 2.0505940914 ) - weight 1170 41 0.0593079589 ( -0.6139689684 12.339140892 3.665779829 ) - weight 1171 42 0.9406920671 ( 0.0593021363 -0.5007272959 3.7248136997 ) - weight 1172 41 0.0593079589 ( -0.7089703083 13.6927700043 3.3668627739 ) - weight 1173 42 0.9406920671 ( 0.0165495016 0.8844855428 3.825050354 ) - weight 1174 41 0.1007401645 ( 3.184128046 13.5912265778 1.2619410753 ) - weight 1175 42 0.8992598653 ( 3.5279135704 1.2738859653 1.1574836969 ) - weight 1176 41 0.0593079589 ( 1.6958975792 13.6776227951 3.4566550255 ) - weight 1177 42 0.9406920671 ( 2.3999507427 0.7818817496 3.5079507828 ) - weight 1178 22 0.1032253429 ( -10.456870079 2.0270195007 -3.0863785744 ) - weight 1179 40 0.1232035086 ( 2.8356900215 -3.3911702633 -0.1953048706 ) - weight 1180 41 0.7735711336 ( -1.1876658201 2.4749224186 3.4909017086 ) - weight 1181 22 0.8149345517 ( -2.3048799038 3.7849845886 5.9193916321 ) - weight 1182 39 0.0842731968 ( -5.9450249672 -0.3314397633 0.7459124923 ) - weight 1183 40 0.1007922292 ( -5.3163003922 5.6145997047 1.5626602173 ) - weight 1184 22 0.8149345517 ( -1.8106399775 4.6890602112 4.1403317451 ) - weight 1185 39 0.0842731968 ( -4.2014517784 -1.0768090487 1.5403031111 ) - weight 1186 40 0.1007922292 ( -5.8105401993 3.8355400562 2.4667358398 ) - weight 1187 3 0.4010512531 ( -2.1574800014 -2.1150360107 5.6972951889 ) - weight 1188 10 0.3483966589 ( -5.6540212631 0.2306408286 -0.8809156418 ) - weight 1189 17 0.1250915676 ( -1.7154912949 -4.0663022995 4.8093729019 ) - weight 1190 18 0.1254605204 ( -2.0757231712 -4.542175293 -0.8545165062 ) - weight 1191 3 0.3874215484 ( -2.2408599854 -2.2401275635 6.591545105 ) - weight 1192 10 0.3705413938 ( -6.459713459 0.429822892 -0.5155801773 ) - weight 1193 17 0.1208403111 ( -1.7473984957 -4.4039640427 5.6503543854 ) - weight 1194 18 0.1211967245 ( -2.1591031551 -4.6672668457 0.0397334099 ) - weight 1195 3 0.2841071188 ( -6.6758599281 -3.1631278992 5.3717050552 ) - weight 1196 10 0.413276881 ( -3.7394461632 2.0067932606 2.9661540985 ) - weight 1197 17 0.2037015706 ( -6.2451109886 -5.0676960945 4.4931130409 ) - weight 1198 18 0.0989144072 ( -6.5941028595 -5.5902671814 -1.1801066399 ) - weight 1199 3 0.0694552287 ( -3.2414617538 -12.6572685242 7.3027234077 ) - weight 1200 10 0.9305447936 ( -6.7221779823 10.8892393112 -1.2609120607 ) - weight 1201 3 0.2415263206 ( -6.9015197754 -7.9605789185 4.9454550743 ) - weight 1202 10 0.7584736943 ( -3.2393052578 6.7314271927 2.1440587044 ) - weight 1203 3 0.0569545068 ( -7.107629776 -12.7721977234 5.1543951035 ) - weight 1204 10 0.9430454969 ( -3.3397777081 11.5107278824 1.5227720737 ) - weight 1205 3 0.2204308957 ( -2.8709900379 -8.1457481384 7.1078953743 ) - weight 1206 10 0.7259786129 ( -6.6919531822 6.3779549599 -0.8408844471 ) - weight 1207 17 0.0535904989 ( -2.3468477726 -10.2685279846 4.7628974915 ) - weight 1208 3 0.0598914735 ( -3.0956466198 -12.6031303406 6.6354465485 ) - weight 1209 10 0.9401085377 ( -6.1505112648 10.7649307251 -1.617557168 ) - weight 1210 10 1 ( 5.8945074081 11.1649971008 -2.4874789715 ) - weight 1211 3 0.2178441584 ( -4.8472700119 -3.1843490601 -6.782854557 ) - weight 1212 10 0.3727830052 ( 6.9721045494 0.8734383583 -2.9546318054 ) - weight 1213 17 0.4093729258 ( -5.1172804832 -2.1393578053 -7.3909244537 ) - weight 1214 3 0.2251323164 ( -8.735039711 -1.0005874634 -2.5254654884 ) - weight 1215 10 0.3628976941 ( 4.3642578125 -0.3165878952 2.5035641193 ) - weight 1216 17 0.4119699895 ( -8.754240036 -1.0977671146 -2.523014307 ) - weight 1217 3 0.2178441584 ( -4.8128800392 -0.9101257324 -6.3873047829 ) - weight 1218 10 0.3727830052 ( 6.5799474716 -1.340498209 -2.4307696819 ) - weight 1219 17 0.4093729258 ( -5.0602402687 -0.0268003009 -6.4616336823 ) -} diff --git a/base/animation/mp_security.md5mesh b/base/animation/mp_security.md5mesh deleted file mode 100644 index 1a80eeb73..000000000 --- a/base/animation/mp_security.md5mesh +++ /dev/null @@ -1,8055 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:28 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_security.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh securitybodymesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: securitybodymesh - shader "models/characters/male_npc/security/dsecurity" - - numverts 949 - vert 0 ( 0.6188631654 0.1287155747 ) 0 1 - vert 1 ( 0.6071884632 0.1777162552 ) 208 1 - vert 2 ( 0.6750283241 0.1688122153 ) 22 1 - vert 3 ( 0.6028345227 0.0249794722 ) 206 1 - vert 4 ( 0.5788876414 0.0652775168 ) 210 2 - vert 5 ( 0.6138037443 0.0513752699 ) 1 1 - vert 6 ( 0.6950880885 0.043764174 ) 14 1 - vert 7 ( 0.748005867 0.2135049701 ) 5 2 - vert 8 ( 0.7498592138 0.2549623251 ) 2 2 - vert 9 ( 0.7977881432 0.2540962696 ) 231 2 - vert 10 ( 0.9004045129 0.1998651028 ) 4 1 - vert 11 ( 0.8136754632 0.2220386267 ) 17 2 - vert 12 ( 0.875375092 0.2397925854 ) 19 1 - vert 13 ( 0.7982314825 0.1929443479 ) 7 2 - vert 14 ( 0.8269331455 0.1641303301 ) 226 1 - vert 15 ( 0.7517331839 0.1683499813 ) 9 2 - vert 16 ( 0.7638302445 0.1426687241 ) 237 2 - vert 17 ( 0.6469066143 0.2241757512 ) 11 1 - vert 18 ( 0.6174865961 0.227865696 ) 207 1 - vert 19 ( 0.7218953967 0.2382743359 ) 12 1 - vert 20 ( 0.6213927269 0.2589709163 ) 205 1 - vert 21 ( 0.6570923328 0.2669430971 ) 13 1 - vert 22 ( 0.6966311932 0.2801801562 ) 14 1 - vert 23 ( 0.6154423952 0.2900197506 ) 206 1 - vert 24 ( 0.7646750212 0.2711068988 ) 229 2 - vert 25 ( 0.8369605541 0.2689613104 ) 227 2 - vert 26 ( 0.6558645964 0.1062784195 ) 20 1 - vert 27 ( 0.6977499127 0.1319890022 ) 16 1 - vert 28 ( 0.7640708685 0.1115137339 ) 23 2 - vert 29 ( 0.7856383324 0.1117683649 ) 222 2 - vert 30 ( 0.8430612087 0.1339819431 ) 234 1 - vert 31 ( 0.9799197912 0.1610833406 ) 203 2 - vert 32 ( 0.6177125573 0.0855022669 ) 15 1 - vert 33 ( 0.7604057789 0.0901602507 ) 220 2 - vert 34 ( 0.6889286041 0.079605639 ) 21 1 - vert 35 ( 0.8393372893 0.0443358421 ) 227 2 - vert 36 ( 0.8445695639 0.0780512094 ) 235 2 - vert 37 ( 0.9663878679 0.0591437817 ) 214 2 - vert 38 ( 0.7644470334 0.0526703596 ) 229 2 - vert 39 ( 0.7833491564 0.0877680779 ) 224 2 - vert 40 ( 0.9598491192 0.2174099684 ) 216 2 - vert 41 ( 0.9634135962 0.2339445353 ) 214 2 - vert 42 ( 0.8660802245 0.1035673022 ) 233 1 - vert 43 ( 0.9876241684 0.0888404846 ) 25 2 - vert 44 ( 0.0273829401 0.8572122455 ) 203 2 - vert 45 ( 0.0523183048 0.8376634121 ) 212 2 - vert 46 ( 0.0234167874 0.8138532639 ) 27 2 - vert 47 ( 0.9903174639 0.1199187636 ) 27 2 - vert 48 ( 0.5967226028 0.2613251209 ) 29 2 - vert 49 ( 0.5935539007 0.2883989215 ) 31 2 - vert 50 ( 0.9124531746 0.4048453569 ) 644 1 - vert 51 ( 0.8587197065 0.4221718907 ) 645 1 - vert 52 ( 0.9042024016 0.469457984 ) 643 1 - vert 53 ( 0.5315648913 0.0926959515 ) 36 2 - vert 54 ( 0.5538491607 0.0473433137 ) 34 2 - vert 55 ( 0.1703063548 0.9144909382 ) 140 4 - vert 56 ( 0.1225809753 0.9316527247 ) 198 5 - vert 57 ( 0.1538040042 0.9271814823 ) 38 4 - vert 58 ( 0.0551351309 0.6746143103 ) 78 5 - vert 59 ( 0.0827802718 0.7249526978 ) 42 6 - vert 60 ( 0.0877094567 0.690602541 ) 38 4 - vert 61 ( 0.1675328314 0.9011368155 ) 169 5 - vert 62 ( 0.1455476284 0.6835899949 ) 140 4 - vert 63 ( 0.0348400772 0.7030842304 ) 111 3 - vert 64 ( 0.0418494642 0.7785394788 ) 159 2 - vert 65 ( 0.1713779569 0.7228521109 ) 189 4 - vert 66 ( 0.1835959852 0.6754909754 ) 48 4 - vert 67 ( 0.1948688924 0.7131741047 ) 151 4 - vert 68 ( 0.2069728076 0.9243959188 ) 48 4 - vert 69 ( 0.2558167875 0.9310382605 ) 52 3 - vert 70 ( 0.271854192 0.9176818132 ) 55 3 - vert 71 ( 0.2151166499 0.6666226387 ) 52 3 - vert 72 ( 0.2245014906 0.7026742697 ) 72 3 - vert 73 ( 0.246858716 0.8340933919 ) 165 4 - vert 74 ( 0.2177821994 0.8594763279 ) 181 4 - vert 75 ( 0.2707093358 0.8460851312 ) 185 4 - vert 76 ( 0.0589274168 0.8096601367 ) 58 2 - vert 77 ( 0.1549892724 0.7954079509 ) 135 5 - vert 78 ( 0.2339172363 0.7880893946 ) 60 4 - vert 79 ( 0.2540736496 0.7637111545 ) 177 4 - vert 80 ( 0.2443723232 0.7306768894 ) 185 4 - vert 81 ( 0.2130345404 0.8017730713 ) 126 4 - vert 82 ( 0.2364186645 0.8055216074 ) 60 4 - vert 83 ( 0.2681286931 0.8148130178 ) 177 4 - vert 84 ( 0.1835639477 0.8079066277 ) 122 4 - vert 85 ( 0.199765861 0.8507326841 ) 161 4 - vert 86 ( 0.1514880359 0.8175091743 ) 117 5 - vert 87 ( 0.1849797368 0.7914831042 ) 64 4 - vert 88 ( 0.2061184645 0.9031195641 ) 68 4 - vert 89 ( 0.0549782217 0.8855749369 ) 218 2 - vert 90 ( 0.1598757505 0.8663176298 ) 130 5 - vert 91 ( 0.167844981 0.9432963133 ) 99 4 - vert 92 ( 0.1648423374 0.9670735598 ) 95 4 - vert 93 ( 0.2020416558 0.9661806226 ) 107 4 - vert 94 ( 0.1210826337 0.9494975805 ) 193 5 - vert 95 ( 0.1629428267 0.9889290929 ) 87 4 - vert 96 ( 0.1956252158 0.9463093281 ) 91 4 - vert 97 ( 0.1773877144 0.9335473776 ) 83 4 - vert 98 ( 0.1195256412 0.6686362624 ) 91 4 - vert 99 ( 0.124263823 0.6545932293 ) 107 4 - vert 100 ( 0.1059358716 0.6520473957 ) 103 4 - vert 101 ( 0.0679329932 0.9238728881 ) 114 3 - vert 102 ( 0.0663550496 0.950502634 ) 144 2 - vert 103 ( 0.069412291 0.9722158909 ) 111 3 - vert 104 ( 0.1232393384 0.9801303148 ) 78 5 - vert 105 ( 0.0773382485 0.6572369337 ) 87 4 - vert 106 ( 0.0957912207 0.6791262031 ) 83 4 - vert 107 ( 0.2066445053 0.8705096245 ) 151 4 - vert 108 ( 0.2057541609 0.8850086927 ) 155 4 - vert 109 ( 0.2661289573 0.8712117672 ) 72 3 - vert 110 ( 0.2703808844 0.8918572664 ) 75 3 - vert 111 ( 0.1602372825 0.8818544745 ) 146 5 - vert 112 ( 0.1871483922 0.8703837991 ) 189 4 - vert 113 ( 0.2390293479 0.6995559931 ) 75 3 - vert 114 ( 0.2292314768 0.6627855301 ) 55 3 - vert 115 ( 0.2425981015 0.9010356665 ) 174 3 - vert 116 ( 0.2073580623 0.7272874713 ) 181 4 - vert 117 ( 0.2005434334 0.9824656844 ) 103 4 - vert 118 ( 0.8455055952 0.4686719775 ) 647 1 - vert 119 ( 0.822804153 0.4304978251 ) 646 1 - vert 120 ( 0.5590677857 0.1182786226 ) 209 1 - vert 121 ( 0.5797170997 0.0108968019 ) 31 2 - vert 122 ( 0.0217129588 0.789418757 ) 25 2 - vert 123 ( 0.0353556573 0.9283709526 ) 216 2 - vert 124 ( 0.0112642348 0.7448965311 ) 214 2 - vert 125 ( 0.0447991788 0.9749445915 ) 214 2 - vert 126 ( 0.9623759985 0.2005986571 ) 239 2 - vert 127 ( 0.0295299888 0.8965368271 ) 239 2 - vert 128 ( 0.9879174232 0.6862155795 ) 242 2 - vert 129 ( 0.9388756752 0.6724613309 ) 249 2 - vert 130 ( 0.972536087 0.7084615231 ) 482 2 - vert 131 ( 0.9202525616 0.7019796371 ) 463 2 - vert 132 ( 0.9112924337 0.6765912771 ) 246 2 - vert 133 ( 0.8698544502 0.7013212442 ) 465 2 - vert 134 ( 0.8702476621 0.6780282855 ) 252 2 - vert 135 ( 0.8342367411 0.7062469721 ) 478 2 - vert 136 ( 0.745393455 0.6653122306 ) 248 1 - vert 137 ( 0.7200672626 0.6504083872 ) 241 1 - vert 138 ( 0.7024546266 0.6862155795 ) 242 2 - vert 139 ( 0.9618584514 0.6575762033 ) 251 1 - vert 140 ( 0.6763958931 0.6575762033 ) 251 1 - vert 141 ( 0.9108582735 0.6568702459 ) 526 1 - vert 142 ( 0.8784794807 0.6660529375 ) 284 1 - vert 143 ( 0.8140940666 0.6780543923 ) 244 2 - vert 144 ( 0.7263786793 0.6993805766 ) 459 2 - vert 145 ( 0.6870735884 0.7084615231 ) 482 2 - vert 146 ( 0.9033032656 0.7426263094 ) 474 2 - vert 147 ( 0.9414386749 0.7429386377 ) 476 2 - vert 148 ( 0.7580233812 0.6270763278 ) 261 1 - vert 149 ( 0.934448719 0.6516754627 ) 263 1 - vert 150 ( 0.6798405647 0.6422004104 ) 264 1 - vert 151 ( 0.8174781799 0.6418691278 ) 265 1 - vert 152 ( 0.7946724892 0.6628842354 ) 254 1 - vert 153 ( 0.965303123 0.6422004104 ) 264 1 - vert 154 ( 0.8649144173 0.6515339613 ) 283 1 - vert 155 ( 0.7738344669 0.6704357862 ) 259 1 - vert 156 ( 0.7677738667 0.652739048 ) 260 1 - vert 157 ( 0.9294445515 0.7955862284 ) 275 2 - vert 158 ( 0.8951789141 0.7780878544 ) 277 2 - vert 159 ( 0.6896111965 0.7738951445 ) 480 2 - vert 160 ( 0.6559761167 0.7429386377 ) 476 2 - vert 161 ( 0.6439819932 0.7955862284 ) 275 2 - vert 162 ( 0.8652394414 0.744279623 ) 472 2 - vert 163 ( 0.8174699545 0.7434339523 ) 450 3 - vert 164 ( 0.6864213347 0.5948352218 ) 589 2 - vert 165 ( 0.8273035288 0.5910165906 ) 271 2 - vert 166 ( 0.8699347973 0.5999336839 ) 268 1 - vert 167 ( 0.8434215784 0.5011422038 ) 599 2 - vert 168 ( 0.7731509209 0.4708537459 ) 308 2 - vert 169 ( 0.7735415101 0.5576218963 ) 273 2 - vert 170 ( 0.9443054199 0.5550022125 ) 593 2 - vert 171 ( 0.934859395 0.5353260636 ) 604 2 - vert 172 ( 0.9251310825 0.5725519061 ) 606 2 - vert 173 ( 0.1634294093 0.5585889816 ) 266 2 - vert 174 ( 0.1133777499 0.5567508936 ) 539 3 - vert 175 ( 0.1177283525 0.6154744029 ) 591 2 - vert 176 ( 0.7121255398 0.5386981964 ) 591 2 - vert 177 ( 0.6683347225 0.5467085838 ) 640 2 - vert 178 ( 0.6484963298 0.5452998281 ) 604 2 - vert 179 ( 0.6560624838 0.5659992695 ) 593 2 - vert 180 ( 0.7388110161 0.4869110584 ) 266 2 - vert 181 ( 0.7388352752 0.5686026216 ) 269 2 - vert 182 ( 0.9016491175 0.6268107891 ) 262 1 - vert 183 ( 0.9066958427 0.5740314722 ) 281 2 - vert 184 ( 0.8774037957 0.5486786962 ) 279 2 - vert 185 ( 0.6560863853 0.8009089231 ) 447 1 - vert 186 ( 0.6937819123 0.8098731041 ) 446 1 - vert 187 ( 0.8622498512 0.7759051323 ) 467 2 - vert 188 ( 0.8328042626 0.7840059996 ) 255 1 - vert 189 ( 0.8650101423 0.802781105 ) 443 1 - vert 190 ( 0.8288022876 0.8116526604 ) 442 1 - vert 191 ( 0.7864276171 0.7981469631 ) 470 2 - vert 192 ( 0.4191250205 0.5681769252 ) 608 1 - vert 193 ( 0.3924738765 0.5466394424 ) 603 1 - vert 194 ( 0.384944886 0.6044014692 ) 595 2 - vert 195 ( 0.0551613271 0.6174724102 ) 285 2 - vert 196 ( 0.0566022992 0.6374822855 ) 1859 3 - vert 197 ( 0.0097253323 0.5896497369 ) 1853 3 - vert 198 ( 0.0093650818 0.5266046524 ) 1862 5 - vert 199 ( 0.7798309326 0.7138189673 ) 294 2 - vert 200 ( 0.7705295086 0.697170496 ) 457 2 - vert 201 ( 0.7573854923 0.7094732523 ) 296 2 - vert 202 ( 0.7946046591 0.6982773542 ) 461 2 - vert 203 ( 0.76988554 0.7513962984 ) 302 4 - vert 204 ( 0.7391120195 0.7149907351 ) 306 2 - vert 205 ( 0.701865077 0.7568195462 ) 453 2 - vert 206 ( 0.7473942041 0.7523978949 ) 298 4 - vert 207 ( 0.4938405752 0.5774159431 ) 1911 1 - vert 208 ( 0.455693841 0.6215332747 ) 604 2 - vert 209 ( 0.2232377827 0.4655563235 ) 310 3 - vert 210 ( 0.1195133626 0.4611729383 ) 290 4 - vert 211 ( 0.1112764776 0.4731173515 ) 313 4 - vert 212 ( 0.4938405752 0.461509347 ) 1916 1 - vert 213 ( 0.4313886166 0.4580843449 ) 317 1 - vert 214 ( 0.4938405752 0.5192149878 ) 1915 1 - vert 215 ( 0.4303025901 0.5145717859 ) 490 1 - vert 216 ( 0.4274894893 0.424115181 ) 318 1 - vert 217 ( 0.4938405752 0.4193115234 ) 1917 1 - vert 218 ( 0.5247628689 0.5198583603 ) 336 4 - vert 219 ( 0.551227808 0.537430048 ) 421 4 - vert 220 ( 0.5064602494 0.4615738988 ) 556 4 - vert 221 ( 0.6172237992 0.600184679 ) 323 3 - vert 222 ( 0.5910843015 0.5265257955 ) 522 4 - vert 223 ( 0.5764282942 0.5873571634 ) 527 4 - vert 224 ( 0.5051008463 0.5424079895 ) 331 5 - vert 225 ( 0.5251142979 0.5869086981 ) 326 5 - vert 226 ( 0.6008902788 0.4384219646 ) 412 5 - vert 227 ( 0.5749715567 0.4107431769 ) 319 4 - vert 228 ( 0.580258131 0.4519261122 ) 425 4 - vert 229 ( 0.2781122327 0.6600117683 ) 391 4 - vert 230 ( 0.2878908515 0.5823018551 ) 556 4 - vert 231 ( 0.2308325469 0.6550593376 ) 560 4 - vert 232 ( 0.3145714104 0.6135299206 ) 336 4 - vert 233 ( 0.5638722181 0.3707660437 ) 417 4 - vert 234 ( 0.5322157145 0.3347574472 ) 378 4 - vert 235 ( 0.5068874955 0.3912551999 ) 340 4 - vert 236 ( 0.5822953582 0.6296640635 ) 616 4 - vert 237 ( 0.5574269891 0.6279833317 ) 382 4 - vert 238 ( 0.3544726372 0.6364587545 ) 326 5 - vert 239 ( 0.3256314695 0.6107097268 ) 331 5 - vert 240 ( 0.3433493674 0.6634830236 ) 386 5 - vert 241 ( 0.5293139219 0.6287755966 ) 386 5 - vert 242 ( 0.2789261341 0.6702955365 ) 368 5 - vert 243 ( 0.8108724356 0.9424161911 ) 359 1 - vert 244 ( 0.7775202394 0.9413175583 ) 351 1 - vert 245 ( 0.7906151414 0.9632388353 ) 348 3 - vert 246 ( 0.7581079602 0.9557496905 ) 396 3 - vert 247 ( 0.8742101192 0.9639419913 ) 434 2 - vert 248 ( 0.8221622705 0.9791785479 ) 542 3 - vert 249 ( 0.7951606512 0.8565899134 ) 347 1 - vert 250 ( 0.7760159969 0.8198644519 ) 353 1 - vert 251 ( 0.7597598433 0.8586047888 ) 362 1 - vert 252 ( 0.9185439348 0.802230835 ) 445 1 - vert 253 ( 0.88840276 0.8045030832 ) 444 1 - vert 254 ( 0.9068934321 0.8716615438 ) 357 1 - vert 255 ( 0.8361234665 0.9048016071 ) 360 1 - vert 256 ( 0.7937387228 0.9002698064 ) 361 1 - vert 257 ( 0.7511045933 0.8963410258 ) 408 1 - vert 258 ( 0.8669617176 0.861639142 ) 358 1 - vert 259 ( 0.8766562939 0.9097957611 ) 355 1 - vert 260 ( 0.5778733492 0.3040692806 ) 545 4 - vert 261 ( 0.6398966908 0.3756346703 ) 429 5 - vert 262 ( 0.6335241199 0.3105093241 ) 560 4 - vert 263 ( 0.7006047964 0.351860404 ) 552 4 - vert 264 ( 0.68599087 0.3245232105 ) 391 4 - vert 265 ( 0.7470995188 0.358605504 ) 531 4 - vert 266 ( 0.736520648 0.309165597 ) 373 5 - vert 267 ( 0.6980329156 0.3079166412 ) 368 5 - vert 268 ( 0.6010156274 0.3795252442 ) 363 5 - vert 269 ( 0.5712647438 0.666496098 ) 531 4 - vert 270 ( 0.5226227045 0.6674368382 ) 373 5 - vert 271 ( 0.734546721 0.9393354654 ) 395 1 - vert 272 ( 0.7269695997 0.9619019032 ) 399 3 - vert 273 ( 0.6972332001 0.9425508976 ) 407 1 - vert 274 ( 0.6544161439 0.9617003798 ) 436 2 - vert 275 ( 0.6974976659 0.9781697392 ) 549 3 - vert 276 ( 0.7443760633 0.8169766068 ) 403 1 - vert 277 ( 0.7335227728 0.8530617952 ) 409 1 - vert 278 ( 0.9344593883 0.9087136984 ) 639 1 - vert 279 ( 0.9060950279 0.9303109646 ) 354 1 - vert 280 ( 0.9309384227 0.9515029788 ) 404 1 - vert 281 ( 0.9056704044 0.9113996625 ) 410 1 - vert 282 ( 0.9342336655 0.863527298 ) 405 1 - vert 283 ( 0.9540240765 0.8492467403 ) 411 1 - vert 284 ( 0.9415490627 0.8009089231 ) 447 1 - vert 285 ( 0.7065313458 0.9021935463 ) 406 1 - vert 286 ( 0.6489968896 0.9087136984 ) 639 1 - vert 287 ( 0.7046477795 0.8707490563 ) 402 1 - vert 288 ( 0.8818972111 0.9527765512 ) 356 1 - vert 289 ( 0.9398787022 0.9617003798 ) 436 2 - vert 290 ( 0.0097253323 0.6174724102 ) 1856 3 - vert 291 ( 0.8375202417 0.8562242985 ) 352 1 - vert 292 ( 0.7491956949 0.8000423908 ) 469 1 - vert 293 ( 0.6685611606 0.8492467403 ) 411 1 - vert 294 ( 0.75872159 0.7284451723 ) 438 4 - vert 295 ( 0.7465679646 0.7665836811 ) 448 2 - vert 296 ( 0.7470253706 0.6972100139 ) 455 2 - vert 297 ( 0.7776852846 0.7651633024 ) 256 3 - vert 298 ( 0.8220176101 0.7701721191 ) 484 2 - vert 299 ( 0.7806951404 0.780654192 ) 486 2 - vert 300 ( 0.7411664724 0.7815235853 ) 488 2 - vert 301 ( 0.6316955686 0.539937675 ) 542 3 - vert 302 ( 0.6323796511 0.4825131893 ) 491 4 - vert 303 ( 0.597433269 0.4785282612 ) 512 5 - vert 304 ( 0.6234145164 0.4316730499 ) 507 5 - vert 305 ( 0.6723697782 0.4414018989 ) 495 4 - vert 306 ( 0.654749155 0.404148221 ) 517 5 - vert 307 ( 0.7730110288 0.973187983 ) 503 4 - vert 308 ( 0.7449417114 0.9721304774 ) 499 4 - vert 309 ( 0.6577829123 0.4922040701 ) 503 4 - vert 310 ( 0.5823059678 0.483476162 ) 535 4 - vert 311 ( 0.8865513802 0.9878162146 ) 323 3 - vert 312 ( 0.686142087 0.4659346938 ) 499 4 - vert 313 ( 0.4938405752 0.4052873254 ) 1923 3 - vert 314 ( 0.4006614685 0.4061611295 ) 863 3 - vert 315 ( 0.6472201943 0.9889752865 ) 620 3 - vert 316 ( 0.1388162971 0.630843401 ) 640 2 - vert 317 ( 0.2315425575 0.5644084215 ) 340 4 - vert 318 ( 0.1854722798 0.6231247187 ) 545 4 - vert 319 ( 0.1984389126 0.5888723135 ) 378 4 - vert 320 ( 0.4447640479 0.5278431177 ) 564 1 - vert 321 ( 0.4216860533 0.5486477613 ) 566 1 - vert 322 ( 0.4502677619 0.5506768823 ) 565 1 - vert 323 ( 0.4938405752 0.5624330044 ) 1914 1 - vert 324 ( 0.3308973908 0.5432168245 ) 609 2 - vert 325 ( 0.3061485589 0.5715066195 ) 599 2 - vert 326 ( 0.3407124579 0.5820630789 ) 597 2 - vert 327 ( 0.3594710529 0.5437998176 ) 611 2 - vert 328 ( 0.4088308215 0.4239915013 ) 569 1 - vert 329 ( 0.4079264402 0.4751372337 ) 568 1 - vert 330 ( 0.3932903409 0.4944604635 ) 567 1 - vert 331 ( 0.3337671459 0.4885939956 ) 570 2 - vert 332 ( 0.3519207835 0.4326373935 ) 573 1 - vert 333 ( 0.367459774 0.4645684361 ) 577 1 - vert 334 ( 0.33777982 0.4789742827 ) 572 1 - vert 335 ( 0.0774939656 0.4253462553 ) 842 5 - vert 336 ( 0.1069657207 0.4117678404 ) 847 4 - vert 337 ( 0.3018787801 0.5310918093 ) 601 2 - vert 338 ( 0.2286183536 0.5303949118 ) 308 2 - vert 339 ( 0.1439307928 0.5389575362 ) 578 3 - vert 340 ( 0.3589897156 0.4062440395 ) 581 2 - vert 341 ( 0.3288226426 0.4180244207 ) 574 3 - vert 342 ( 0.3541322947 0.3947893381 ) 860 3 - vert 343 ( 0.212649852 0.4559247494 ) 583 3 - vert 344 ( 0.2124633789 0.4074966908 ) 851 5 - vert 345 ( 0.295052886 0.4036608338 ) 856 4 - vert 346 ( 0.0093650818 0.425721705 ) 1878 3 - vert 347 ( 0.3190254867 0.4473839998 ) 287 3 - vert 348 ( 0.262906462 0.4561910629 ) 586 3 - vert 349 ( 0.4938405752 0.6230149269 ) 1909 2 - vert 350 ( 0.0787962973 0.6446386576 ) 1912 2 - vert 351 ( 0.9097238183 0.5257812738 ) 595 2 - vert 352 ( 0.8825437427 0.5110060573 ) 597 2 - vert 353 ( 0.0093650818 0.4675011635 ) 1867 3 - vert 354 ( 0.9094944 0.9760050178 ) 623 3 - vert 355 ( 0.9326827526 0.9889752865 ) 620 3 - vert 356 ( 0.6391683817 0.6333078742 ) 623 3 - vert 357 ( 0.6186243892 0.6495701671 ) 613 3 - vert 358 ( 0.6090469956 0.6800134182 ) 620 3 - vert 359 ( 0.61962533 0.6259011626 ) 344 3 - vert 360 ( 0.7204926014 0.3928611875 ) 626 4 - vert 361 ( 0.7579321861 0.4269043803 ) 620 3 - vert 362 ( 0.7211619616 0.4401774406 ) 549 3 - vert 363 ( 0.6341335773 0.4015330076 ) 630 5 - vert 364 ( 0.6721040606 0.3867303133 ) 635 4 - vert 365 ( 0.4408987164 0.6390709877 ) 640 2 - vert 366 ( 0.466876924 0.6459610462 ) 1912 2 - vert 367 ( 0.3172201514 0.6833396554 ) 373 5 - vert 368 ( 0.1388162971 0.630843401 ) 1912 2 - vert 369 ( 0.0787962973 0.6446386576 ) 640 2 - vert 370 ( 0.466876924 0.6459610462 ) 640 2 - vert 371 ( 0.4408987164 0.6390709877 ) 1912 2 - vert 372 ( 0.950093925 0.440998733 ) 642 1 - vert 373 ( 0.9046775699 0.4928504825 ) 208 1 - vert 374 ( 0.9719032049 0.4428100586 ) 0 1 - vert 375 ( 0.9460786581 0.3970065713 ) 648 1 - vert 376 ( 0.9756503701 0.3952539563 ) 209 1 - vert 377 ( 0.8178055882 0.4802870154 ) 207 1 - vert 378 ( 0.7965644002 0.4297861457 ) 33 1 - vert 379 ( 0.9048620462 0.357222259 ) 649 1 - vert 380 ( 0.9388618469 0.3512775898 ) 650 3 - vert 381 ( 0.8245270848 0.3758257031 ) 655 2 - vert 382 ( 0.8012051582 0.3747473955 ) 653 2 - vert 383 ( 0.8564575315 0.3695956469 ) 657 2 - vert 384 ( 0.9682284594 0.3496643305 ) 659 2 - vert 385 ( 0.7708232999 0.3824968338 ) 29 2 - vert 386 ( 0.9915254116 0.3501280546 ) 36 2 - vert 387 ( 0.764909029 0.4199460745 ) 205 1 - vert 388 ( 0.7925951481 0.3462982178 ) 663 4 - vert 389 ( 0.7662457228 0.3600251079 ) 661 2 - vert 390 ( 0.561688602 0.2625313401 ) 661 2 - vert 391 ( 0.5759554505 0.2937509418 ) 667 2 - vert 392 ( 0.8233408332 0.3488204479 ) 669 3 - vert 393 ( 0.9914909601 0.3319371343 ) 676 4 - vert 394 ( 0.9701109529 0.3296480775 ) 672 4 - vert 395 ( 0.9015637636 0.3301431537 ) 680 4 - vert 396 ( 0.9399214983 0.3327356577 ) 684 4 - vert 397 ( 0.5300602913 0.0490809083 ) 688 4 - vert 398 ( 0.5089550614 0.0767536163 ) 676 4 - vert 399 ( 0.8558390141 0.3424976468 ) 692 5 - vert 400 ( 0.5518918633 0.0089600682 ) 667 2 - vert 401 ( 0.24702923 0.056795001 ) 704 4 - vert 402 ( 0.2468391806 0.0082832575 ) 907 3 - vert 403 ( 0.180007726 0.0613898039 ) 912 3 - vert 404 ( 0.3550749421 0.0102859735 ) 905 2 - vert 405 ( 0.347266525 0.0399858356 ) 702 2 - vert 406 ( 0.2130548954 0.0783062577 ) 708 5 - vert 407 ( 0.3922063112 0.0709888935 ) 722 4 - vert 408 ( 0.1103003621 0.0797612667 ) 910 2 - vert 409 ( 0.0093650818 0.1056534052 ) 1897 4 - vert 410 ( 0.0925641954 0.1063870788 ) 788 4 - vert 411 ( 0.2802728117 0.046277523 ) 713 4 - vert 412 ( 0.3505480886 0.0650349855 ) 717 5 - vert 413 ( 0.083874166 0.1815125942 ) 729 3 - vert 414 ( 0.0965228677 0.3617821932 ) 732 3 - vert 415 ( 0.0513322651 0.3739336729 ) 739 3 - vert 416 ( 0.1073260009 0.3915848136 ) 838 4 - vert 417 ( 0.0093650818 0.3572389483 ) 1874 4 - vert 418 ( 0.0093650818 0.3977475166 ) 1870 4 - vert 419 ( 0.0578081608 0.3110636473 ) 735 4 - vert 420 ( 0.1576044858 0.1620275974 ) 755 3 - vert 421 ( 0.1222535968 0.1674438715 ) 742 3 - vert 422 ( 0.1444258094 0.2205191851 ) 806 2 - vert 423 ( 0.1824056208 0.1900250912 ) 758 2 - vert 424 ( 0.1862074435 0.2645644546 ) 745 3 - vert 425 ( 0.2371795177 0.2540616989 ) 760 1 - vert 426 ( 0.2340686321 0.285172224 ) 748 3 - vert 427 ( 0.4938405752 0.3213783503 ) 1926 4 - vert 428 ( 0.4938405752 0.2766448259 ) 1930 3 - vert 429 ( 0.4372490346 0.3222288489 ) 776 4 - vert 430 ( 0.4940881133 0.095235467 ) 1943 3 - vert 431 ( 0.4185279906 0.1344797015 ) 811 5 - vert 432 ( 0.4938405752 0.1690883636 ) 1938 5 - vert 433 ( 0.428922087 0.2030869722 ) 783 5 - vert 434 ( 0.3882690668 0.1523826122 ) 915 6 - vert 435 ( 0.3936232924 0.2016937137 ) 866 6 - vert 436 ( 0.4938405752 0.2332305908 ) 1933 5 - vert 437 ( 0.4130477905 0.2399291992 ) 924 5 - vert 438 ( 0.4221341908 0.2745028734 ) 780 3 - vert 439 ( 0.3932344019 0.3226995468 ) 761 4 - vert 440 ( 0.4940881133 0.0708108544 ) 1946 3 - vert 441 ( 0.4437904954 0.0743006468 ) 921 3 - vert 442 ( 0.3362599611 0.3014298677 ) 765 3 - vert 443 ( 0.2762045264 0.3304995298 ) 751 4 - vert 444 ( 0.3660609126 0.2011561394 ) 771 5 - vert 445 ( 0.3034223616 0.2632719874 ) 803 3 - vert 446 ( 0.3380084336 0.2682123184 ) 798 5 - vert 447 ( 0.0093650818 0.1746872663 ) 1892 3 - vert 448 ( 0.0802102685 0.2218263745 ) 792 2 - vert 449 ( 0.2288490832 0.1999977827 ) 768 3 - vert 450 ( 0.0509798229 0.2562607527 ) 726 3 - vert 451 ( 0.0093650818 0.2766834497 ) 1885 4 - vert 452 ( 0.0798471272 0.2886747122 ) 902 3 - vert 453 ( 0.0093650818 0.3042780161 ) 1881 4 - vert 454 ( 0.2139489353 0.1501144171 ) 794 4 - vert 455 ( 0.1606835723 0.1331404448 ) 697 5 - vert 456 ( 0.4400574565 0.0111424327 ) 1951 2 - vert 457 ( 0.3914140165 0.3679138422 ) 808 3 - vert 458 ( 0.4938405752 0.3675917387 ) 1918 5 - vert 459 ( 0.353936404 0.3622125387 ) 816 4 - vert 460 ( 0.3041800857 0.2214561105 ) 820 4 - vert 461 ( 0.1109604836 0.2496719956 ) 831 3 - vert 462 ( 0.2283400893 0.3581427336 ) 827 4 - vert 463 ( 0.1693162918 0.290597856 ) 824 3 - vert 464 ( 0.1139373779 0.349927783 ) 834 4 - vert 465 ( 0.0099842846 0.2218263745 ) 1895 2 - vert 466 ( 0.0109267831 0.2562607527 ) 1889 3 - vert 467 ( 0.9691210985 0.3037109375 ) 872 6 - vert 468 ( 0.3478776813 0.1142273545 ) 872 6 - vert 469 ( 0.3482938409 0.1539620757 ) 676 4 - vert 470 ( 0.8284341097 0.310080409 ) 878 5 - vert 471 ( 0.8500990868 0.3097743988 ) 883 4 - vert 472 ( 0.9015080333 0.3006564379 ) 887 4 - vert 473 ( 0.9370734692 0.2986869812 ) 891 5 - vert 474 ( 0.8997855783 0.2657402158 ) 713 4 - vert 475 ( 0.8730151653 0.2692120075 ) 704 4 - vert 476 ( 0.8473278284 0.2768980861 ) 708 5 - vert 477 ( 0.2414392233 0.1182127595 ) 878 5 - vert 478 ( 0.3257909715 0.0821592808 ) 891 5 - vert 479 ( 0.3716933131 0.086319983 ) 896 6 - vert 480 ( 0.2705033422 0.1606909633 ) 663 4 - vert 481 ( 0.2840547562 0.18321383 ) 661 2 - vert 482 ( 0.3135349154 0.1873478889 ) 667 2 - vert 483 ( 0.3347135186 0.182977736 ) 688 4 - vert 484 ( 0.0589729548 0.0657583475 ) 912 3 - vert 485 ( 0.0811483562 0.0169489384 ) 1903 3 - vert 486 ( 0.0208202004 0.0460392237 ) 910 2 - vert 487 ( 0.0133805871 0.0132383108 ) 1901 2 - vert 488 ( 0.178339988 0.0154081583 ) 1949 2 - vert 489 ( 0.183524251 0.0489068031 ) 905 2 - vert 490 ( 0.2068976462 0.0149554014 ) 1951 2 - vert 491 ( 0.1332207918 0.0161233544 ) 1906 3 - vert 492 ( 0.1170584857 0.0669660568 ) 907 3 - vert 493 ( 0.033706218 0.0799274445 ) 1901 2 - vert 494 ( 0.6071884632 0.1777162552 ) 1136 1 - vert 495 ( 0.6188631654 0.1287155747 ) 929 1 - vert 496 ( 0.6750283241 0.1688122153 ) 951 1 - vert 497 ( 0.5788876414 0.0652775168 ) 1138 2 - vert 498 ( 0.6028345227 0.0249794722 ) 1134 1 - vert 499 ( 0.6138037443 0.0513752699 ) 930 1 - vert 500 ( 0.6950880885 0.043764174 ) 943 1 - vert 501 ( 0.7498592138 0.2549623251 ) 931 2 - vert 502 ( 0.748005867 0.2135049701 ) 934 2 - vert 503 ( 0.7977881432 0.2540962696 ) 1159 2 - vert 504 ( 0.8136754632 0.2220386267 ) 946 2 - vert 505 ( 0.9004045129 0.1998651028 ) 933 1 - vert 506 ( 0.875375092 0.2397925854 ) 948 1 - vert 507 ( 0.7982314825 0.1929443479 ) 936 2 - vert 508 ( 0.8269331455 0.1641303301 ) 1154 1 - vert 509 ( 0.7517331839 0.1683499813 ) 938 2 - vert 510 ( 0.7638302445 0.1426687241 ) 1165 2 - vert 511 ( 0.6469066143 0.2241757512 ) 940 1 - vert 512 ( 0.6174865961 0.227865696 ) 1135 1 - vert 513 ( 0.7218953967 0.2382743359 ) 941 1 - vert 514 ( 0.6213927269 0.2589709163 ) 1133 1 - vert 515 ( 0.6570923328 0.2669430971 ) 942 1 - vert 516 ( 0.6966311932 0.2801801562 ) 943 1 - vert 517 ( 0.6154423952 0.2900197506 ) 1134 1 - vert 518 ( 0.7646750212 0.2711068988 ) 1157 2 - vert 519 ( 0.8369605541 0.2689613104 ) 1155 2 - vert 520 ( 0.6977499127 0.1319890022 ) 945 1 - vert 521 ( 0.6558645964 0.1062784195 ) 949 1 - vert 522 ( 0.7640708685 0.1115137339 ) 952 2 - vert 523 ( 0.7856383324 0.1117683649 ) 1150 2 - vert 524 ( 0.8430612087 0.1339819431 ) 1162 1 - vert 525 ( 0.9799197912 0.1610833406 ) 1131 2 - vert 526 ( 0.6177125573 0.0855022669 ) 944 1 - vert 527 ( 0.7604057789 0.0901602507 ) 1148 2 - vert 528 ( 0.6889286041 0.079605639 ) 950 1 - vert 529 ( 0.8445695639 0.0780512094 ) 1163 2 - vert 530 ( 0.8393372893 0.0443358421 ) 1155 2 - vert 531 ( 0.9663878679 0.0591437817 ) 1142 2 - vert 532 ( 0.7833491564 0.0877680779 ) 1152 2 - vert 533 ( 0.7644470334 0.0526703596 ) 1157 2 - vert 534 ( 0.9598491192 0.2174099684 ) 1144 2 - vert 535 ( 0.9634135962 0.2339445353 ) 1142 2 - vert 536 ( 0.8660802245 0.1035673022 ) 1161 1 - vert 537 ( 0.9876241684 0.0888404846 ) 954 2 - vert 538 ( 0.0523183048 0.8376634121 ) 1140 2 - vert 539 ( 0.0273829401 0.8572122455 ) 1131 2 - vert 540 ( 0.0234167874 0.8138532639 ) 956 2 - vert 541 ( 0.9903174639 0.1199187636 ) 956 2 - vert 542 ( 0.5967226028 0.2613251209 ) 958 2 - vert 543 ( 0.5935539007 0.2883989215 ) 960 2 - vert 544 ( 0.8587197065 0.4221718907 ) 1571 1 - vert 545 ( 0.9124531746 0.4048453569 ) 1570 1 - vert 546 ( 0.9042024016 0.469457984 ) 1569 1 - vert 547 ( 0.5315648913 0.0926959515 ) 965 2 - vert 548 ( 0.5538491607 0.0473433137 ) 963 2 - vert 549 ( 0.1225809753 0.9316527247 ) 1126 5 - vert 550 ( 0.1703063548 0.9144909382 ) 1069 4 - vert 551 ( 0.1538040042 0.9271814823 ) 967 4 - vert 552 ( 0.0827802718 0.7249526978 ) 971 6 - vert 553 ( 0.0551351309 0.6746143103 ) 1007 5 - vert 554 ( 0.0877094567 0.690602541 ) 967 4 - vert 555 ( 0.1675328314 0.9011368155 ) 1098 5 - vert 556 ( 0.1455476284 0.6835899949 ) 1069 4 - vert 557 ( 0.0418494642 0.7785394788 ) 1088 2 - vert 558 ( 0.0348400772 0.7030842304 ) 1040 3 - vert 559 ( 0.1713779569 0.7228521109 ) 1117 4 - vert 560 ( 0.1835959852 0.6754909754 ) 977 4 - vert 561 ( 0.1948688924 0.7131741047 ) 1080 4 - vert 562 ( 0.2558167875 0.9310382605 ) 981 3 - vert 563 ( 0.2069728076 0.9243959188 ) 977 4 - vert 564 ( 0.271854192 0.9176818132 ) 984 3 - vert 565 ( 0.2151166499 0.6666226387 ) 981 3 - vert 566 ( 0.2245014906 0.7026742697 ) 1001 3 - vert 567 ( 0.2177821994 0.8594763279 ) 1109 4 - vert 568 ( 0.246858716 0.8340933919 ) 1094 4 - vert 569 ( 0.2707093358 0.8460851312 ) 1113 4 - vert 570 ( 0.0589274168 0.8096601367 ) 987 2 - vert 571 ( 0.1549892724 0.7954079509 ) 1064 5 - vert 572 ( 0.2540736496 0.7637111545 ) 1106 3 - vert 573 ( 0.2339172363 0.7880893946 ) 989 4 - vert 574 ( 0.2443723232 0.7306768894 ) 1113 4 - vert 575 ( 0.2130345404 0.8017730713 ) 1055 4 - vert 576 ( 0.2364186645 0.8055216074 ) 989 4 - vert 577 ( 0.2681286931 0.8148130178 ) 1106 3 - vert 578 ( 0.1835639477 0.8079066277 ) 1051 4 - vert 579 ( 0.199765861 0.8507326841 ) 1090 4 - vert 580 ( 0.1514880359 0.8175091743 ) 1046 5 - vert 581 ( 0.1849797368 0.7914831042 ) 993 4 - vert 582 ( 0.2061184645 0.9031195641 ) 997 4 - vert 583 ( 0.0549782217 0.8855749369 ) 1146 2 - vert 584 ( 0.1598757505 0.8663176298 ) 1059 5 - vert 585 ( 0.1648423374 0.9670735598 ) 1024 4 - vert 586 ( 0.167844981 0.9432963133 ) 1028 4 - vert 587 ( 0.2020416558 0.9661806226 ) 1036 4 - vert 588 ( 0.1210826337 0.9494975805 ) 1121 5 - vert 589 ( 0.1629428267 0.9889290929 ) 1016 4 - vert 590 ( 0.1956252158 0.9463093281 ) 1020 4 - vert 591 ( 0.1773877144 0.9335473776 ) 1012 4 - vert 592 ( 0.124263823 0.6545932293 ) 1036 4 - vert 593 ( 0.1195256412 0.6686362624 ) 1020 4 - vert 594 ( 0.1059358716 0.6520473957 ) 1032 4 - vert 595 ( 0.0679329932 0.9238728881 ) 1043 3 - vert 596 ( 0.069412291 0.9722158909 ) 1040 3 - vert 597 ( 0.0663550496 0.950502634 ) 1073 2 - vert 598 ( 0.1232393384 0.9801303148 ) 1007 5 - vert 599 ( 0.0773382485 0.6572369337 ) 1016 4 - vert 600 ( 0.0957912207 0.6791262031 ) 1012 4 - vert 601 ( 0.2057541609 0.8850086927 ) 1084 4 - vert 602 ( 0.2066445053 0.8705096245 ) 1080 4 - vert 603 ( 0.2661289573 0.8712117672 ) 1001 3 - vert 604 ( 0.2703808844 0.8918572664 ) 1004 3 - vert 605 ( 0.1602372825 0.8818544745 ) 1075 5 - vert 606 ( 0.1871483922 0.8703837991 ) 1117 4 - vert 607 ( 0.2390293479 0.6995559931 ) 1004 3 - vert 608 ( 0.2292314768 0.6627855301 ) 984 3 - vert 609 ( 0.2425981015 0.9010356665 ) 1103 3 - vert 610 ( 0.2073580623 0.7272874713 ) 1109 4 - vert 611 ( 0.2005434334 0.9824656844 ) 1032 4 - vert 612 ( 0.8455055952 0.4686719775 ) 1573 1 - vert 613 ( 0.822804153 0.4304978251 ) 1572 1 - vert 614 ( 0.5590677857 0.1182786226 ) 1137 1 - vert 615 ( 0.5797170997 0.0108968019 ) 960 2 - vert 616 ( 0.0217129588 0.789418757 ) 954 2 - vert 617 ( 0.0353556573 0.9283709526 ) 1144 2 - vert 618 ( 0.0112642348 0.7448965311 ) 1142 2 - vert 619 ( 0.0447991788 0.9749445915 ) 1142 2 - vert 620 ( 0.9623759985 0.2005986571 ) 1167 2 - vert 621 ( 0.0295299888 0.8965368271 ) 1167 2 - vert 622 ( 0.9388756752 0.6724613309 ) 1177 2 - vert 623 ( 0.9879174232 0.6862155795 ) 1170 2 - vert 624 ( 0.972536087 0.7084615231 ) 1410 2 - vert 625 ( 0.9202525616 0.7019796371 ) 1391 2 - vert 626 ( 0.9112924337 0.6765912771 ) 1174 2 - vert 627 ( 0.8702476621 0.6780282855 ) 1180 2 - vert 628 ( 0.8698544502 0.7013212442 ) 1393 2 - vert 629 ( 0.8342367411 0.7062469721 ) 1406 2 - vert 630 ( 0.7200672626 0.6504083872 ) 1169 1 - vert 631 ( 0.745393455 0.6653122306 ) 1176 1 - vert 632 ( 0.7024546266 0.6862155795 ) 1170 2 - vert 633 ( 0.9618584514 0.6575762033 ) 1179 1 - vert 634 ( 0.6763958931 0.6575762033 ) 1179 1 - vert 635 ( 0.9108582735 0.6568702459 ) 1454 1 - vert 636 ( 0.8784794807 0.6660529375 ) 1212 1 - vert 637 ( 0.8140940666 0.6780543923 ) 1172 2 - vert 638 ( 0.7263786793 0.6993805766 ) 1387 2 - vert 639 ( 0.6870735884 0.7084615231 ) 1410 2 - vert 640 ( 0.9033032656 0.7426263094 ) 1402 2 - vert 641 ( 0.9414386749 0.7429386377 ) 1404 2 - vert 642 ( 0.7580233812 0.6270763278 ) 1189 1 - vert 643 ( 0.934448719 0.6516754627 ) 1191 1 - vert 644 ( 0.6798405647 0.6422004104 ) 1192 1 - vert 645 ( 0.7946724892 0.6628842354 ) 1182 1 - vert 646 ( 0.8174781799 0.6418691278 ) 1193 1 - vert 647 ( 0.965303123 0.6422004104 ) 1192 1 - vert 648 ( 0.8649144173 0.6515339613 ) 1211 1 - vert 649 ( 0.7738344669 0.6704357862 ) 1187 1 - vert 650 ( 0.7677738667 0.652739048 ) 1188 1 - vert 651 ( 0.9294445515 0.7955862284 ) 1203 2 - vert 652 ( 0.8951789141 0.7780878544 ) 1205 2 - vert 653 ( 0.6559761167 0.7429386377 ) 1404 2 - vert 654 ( 0.6896111965 0.7738951445 ) 1408 2 - vert 655 ( 0.6439819932 0.7955862284 ) 1203 2 - vert 656 ( 0.8652394414 0.744279623 ) 1400 2 - vert 657 ( 0.8174699545 0.7434339523 ) 1378 3 - vert 658 ( 0.6864213347 0.5948352218 ) 1515 2 - vert 659 ( 0.8273035288 0.5910165906 ) 1199 2 - vert 660 ( 0.8699347973 0.5999336839 ) 1196 1 - vert 661 ( 0.7731509209 0.4708537459 ) 1236 2 - vert 662 ( 0.8434215784 0.5011422038 ) 1525 2 - vert 663 ( 0.7735415101 0.5576218963 ) 1201 2 - vert 664 ( 0.934859395 0.5353260636 ) 1530 2 - vert 665 ( 0.9443054199 0.5550022125 ) 1519 2 - vert 666 ( 0.9251310825 0.5725519061 ) 1532 2 - vert 667 ( 0.1133777499 0.5567508936 ) 1467 3 - vert 668 ( 0.1634294093 0.5585889816 ) 1194 2 - vert 669 ( 0.1177283525 0.6154744029 ) 1517 2 - vert 670 ( 0.6683347225 0.5467085838 ) 1566 2 - vert 671 ( 0.7121255398 0.5386981964 ) 1517 2 - vert 672 ( 0.6484963298 0.5452998281 ) 1530 2 - vert 673 ( 0.6560624838 0.5659992695 ) 1519 2 - vert 674 ( 0.7388110161 0.4869110584 ) 1194 2 - vert 675 ( 0.7388352752 0.5686026216 ) 1197 2 - vert 676 ( 0.9016491175 0.6268107891 ) 1190 1 - vert 677 ( 0.9066958427 0.5740314722 ) 1209 2 - vert 678 ( 0.8774037957 0.5486786962 ) 1207 2 - vert 679 ( 0.6560863853 0.8009089231 ) 1375 1 - vert 680 ( 0.6937819123 0.8098731041 ) 1374 1 - vert 681 ( 0.8328042626 0.7840059996 ) 1183 1 - vert 682 ( 0.8622498512 0.7759051323 ) 1395 2 - vert 683 ( 0.8650101423 0.802781105 ) 1371 1 - vert 684 ( 0.8288022876 0.8116526604 ) 1370 1 - vert 685 ( 0.7864276171 0.7981469631 ) 1398 2 - vert 686 ( 0.3924738765 0.5466394424 ) 1529 1 - vert 687 ( 0.4191250205 0.5681769252 ) 1534 1 - vert 688 ( 0.384944886 0.6044014692 ) 1521 2 - vert 689 ( 0.0551613271 0.6174724102 ) 1213 2 - vert 690 ( 0.7705295086 0.697170496 ) 1385 2 - vert 691 ( 0.7798309326 0.7138189673 ) 1222 2 - vert 692 ( 0.7573854923 0.7094732523 ) 1224 2 - vert 693 ( 0.7946046591 0.6982773542 ) 1389 2 - vert 694 ( 0.76988554 0.7513962984 ) 1230 4 - vert 695 ( 0.701865077 0.7568195462 ) 1381 2 - vert 696 ( 0.7391120195 0.7149907351 ) 1234 2 - vert 697 ( 0.7473942041 0.7523978949 ) 1226 4 - vert 698 ( 0.455693841 0.6215332747 ) 1530 2 - vert 699 ( 0.1195133626 0.4611729383 ) 1218 4 - vert 700 ( 0.2232377827 0.4655563235 ) 1238 3 - vert 701 ( 0.1112764776 0.4731173515 ) 1241 4 - vert 702 ( 0.4313886166 0.4580843449 ) 1245 1 - vert 703 ( 0.4303025901 0.5145717859 ) 1418 1 - vert 704 ( 0.4274894893 0.424115181 ) 1246 1 - vert 705 ( 0.551227808 0.537430048 ) 1349 4 - vert 706 ( 0.5247628689 0.5198583603 ) 1264 4 - vert 707 ( 0.5064602494 0.4615738988 ) 1484 4 - vert 708 ( 0.5910843015 0.5265257955 ) 1450 4 - vert 709 ( 0.6172237992 0.600184679 ) 1251 3 - vert 710 ( 0.5764282942 0.5873571634 ) 1455 4 - vert 711 ( 0.5051008463 0.5424079895 ) 1259 5 - vert 712 ( 0.5251142979 0.5869086981 ) 1254 5 - vert 713 ( 0.5749715567 0.4107431769 ) 1247 4 - vert 714 ( 0.6008902788 0.4384219646 ) 1340 5 - vert 715 ( 0.580258131 0.4519261122 ) 1353 4 - vert 716 ( 0.2878908515 0.5823018551 ) 1484 4 - vert 717 ( 0.2781122327 0.6600117683 ) 1319 4 - vert 718 ( 0.2308325469 0.6550593376 ) 1488 4 - vert 719 ( 0.3145714104 0.6135299206 ) 1264 4 - vert 720 ( 0.5322157145 0.3347574472 ) 1306 4 - vert 721 ( 0.5638722181 0.3707660437 ) 1345 4 - vert 722 ( 0.5068874955 0.3912551999 ) 1268 4 - vert 723 ( 0.5822953582 0.6296640635 ) 1542 4 - vert 724 ( 0.5574269891 0.6279833317 ) 1310 4 - vert 725 ( 0.3256314695 0.6107097268 ) 1259 5 - vert 726 ( 0.3544726372 0.6364587545 ) 1254 5 - vert 727 ( 0.3433493674 0.6634830236 ) 1314 5 - vert 728 ( 0.5293139219 0.6287755966 ) 1314 5 - vert 729 ( 0.2789261341 0.6702955365 ) 1296 5 - vert 730 ( 0.7775202394 0.9413175583 ) 1279 1 - vert 731 ( 0.8108724356 0.9424161911 ) 1287 1 - vert 732 ( 0.7906151414 0.9632388353 ) 1276 3 - vert 733 ( 0.7581079602 0.9557496905 ) 1324 3 - vert 734 ( 0.8742101192 0.9639419913 ) 1362 2 - vert 735 ( 0.8221622705 0.9791785479 ) 1470 3 - vert 736 ( 0.7760159969 0.8198644519 ) 1281 1 - vert 737 ( 0.7951606512 0.8565899134 ) 1275 1 - vert 738 ( 0.7597598433 0.8586047888 ) 1290 1 - vert 739 ( 0.88840276 0.8045030832 ) 1372 1 - vert 740 ( 0.9185439348 0.802230835 ) 1373 1 - vert 741 ( 0.9068934321 0.8716615438 ) 1285 1 - vert 742 ( 0.7937387228 0.9002698064 ) 1289 1 - vert 743 ( 0.8361234665 0.9048016071 ) 1288 1 - vert 744 ( 0.7511045933 0.8963410258 ) 1336 1 - vert 745 ( 0.8669617176 0.861639142 ) 1286 1 - vert 746 ( 0.8766562939 0.9097957611 ) 1283 1 - vert 747 ( 0.6398966908 0.3756346703 ) 1357 5 - vert 748 ( 0.5778733492 0.3040692806 ) 1473 4 - vert 749 ( 0.6335241199 0.3105093241 ) 1488 4 - vert 750 ( 0.68599087 0.3245232105 ) 1319 4 - vert 751 ( 0.7006047964 0.351860404 ) 1480 4 - vert 752 ( 0.736520648 0.309165597 ) 1301 5 - vert 753 ( 0.7470995188 0.358605504 ) 1459 4 - vert 754 ( 0.6980329156 0.3079166412 ) 1296 5 - vert 755 ( 0.6010156274 0.3795252442 ) 1291 5 - vert 756 ( 0.5712647438 0.666496098 ) 1459 4 - vert 757 ( 0.5226227045 0.6674368382 ) 1301 5 - vert 758 ( 0.734546721 0.9393354654 ) 1323 1 - vert 759 ( 0.7269695997 0.9619019032 ) 1327 3 - vert 760 ( 0.6972332001 0.9425508976 ) 1335 1 - vert 761 ( 0.6544161439 0.9617003798 ) 1364 2 - vert 762 ( 0.6974976659 0.9781697392 ) 1477 3 - vert 763 ( 0.7335227728 0.8530617952 ) 1337 1 - vert 764 ( 0.7443760633 0.8169766068 ) 1331 1 - vert 765 ( 0.9060950279 0.9303109646 ) 1282 1 - vert 766 ( 0.9344593883 0.9087136984 ) 1565 1 - vert 767 ( 0.9309384227 0.9515029788 ) 1332 1 - vert 768 ( 0.9056704044 0.9113996625 ) 1338 1 - vert 769 ( 0.9342336655 0.863527298 ) 1333 1 - vert 770 ( 0.9540240765 0.8492467403 ) 1339 1 - vert 771 ( 0.9415490627 0.8009089231 ) 1375 1 - vert 772 ( 0.6489968896 0.9087136984 ) 1565 1 - vert 773 ( 0.7065313458 0.9021935463 ) 1334 1 - vert 774 ( 0.7046477795 0.8707490563 ) 1330 1 - vert 775 ( 0.8818972111 0.9527765512 ) 1284 1 - vert 776 ( 0.9398787022 0.9617003798 ) 1364 2 - vert 777 ( 0.8375202417 0.8562242985 ) 1280 1 - vert 778 ( 0.7491956949 0.8000423908 ) 1397 1 - vert 779 ( 0.6685611606 0.8492467403 ) 1339 1 - vert 780 ( 0.75872159 0.7284451723 ) 1366 4 - vert 781 ( 0.7465679646 0.7665836811 ) 1376 2 - vert 782 ( 0.7470253706 0.6972100139 ) 1383 2 - vert 783 ( 0.7776852846 0.7651633024 ) 1184 3 - vert 784 ( 0.8220176101 0.7701721191 ) 1412 2 - vert 785 ( 0.7806951404 0.780654192 ) 1414 2 - vert 786 ( 0.7411664724 0.7815235853 ) 1416 2 - vert 787 ( 0.6323796511 0.4825131893 ) 1419 4 - vert 788 ( 0.6316955686 0.539937675 ) 1470 3 - vert 789 ( 0.597433269 0.4785282612 ) 1440 5 - vert 790 ( 0.6234145164 0.4316730499 ) 1435 5 - vert 791 ( 0.6723697782 0.4414018989 ) 1423 4 - vert 792 ( 0.654749155 0.404148221 ) 1445 5 - vert 793 ( 0.7730110288 0.973187983 ) 1431 4 - vert 794 ( 0.7449417114 0.9721304774 ) 1427 4 - vert 795 ( 0.6577829123 0.4922040701 ) 1431 4 - vert 796 ( 0.5823059678 0.483476162 ) 1463 4 - vert 797 ( 0.8865513802 0.9878162146 ) 1251 3 - vert 798 ( 0.686142087 0.4659346938 ) 1427 4 - vert 799 ( 0.4006614685 0.4061611295 ) 1787 3 - vert 800 ( 0.6472201943 0.9889752865 ) 1546 3 - vert 801 ( 0.1388162971 0.630843401 ) 1566 2 - vert 802 ( 0.2315425575 0.5644084215 ) 1268 4 - vert 803 ( 0.1854722798 0.6231247187 ) 1473 4 - vert 804 ( 0.1984389126 0.5888723135 ) 1306 4 - vert 805 ( 0.4216860533 0.5486477613 ) 1494 1 - vert 806 ( 0.4447640479 0.5278431177 ) 1492 1 - vert 807 ( 0.4502677619 0.5506768823 ) 1493 1 - vert 808 ( 0.3061485589 0.5715066195 ) 1525 2 - vert 809 ( 0.3308973908 0.5432168245 ) 1535 2 - vert 810 ( 0.3407124579 0.5820630789 ) 1523 2 - vert 811 ( 0.3594710529 0.5437998176 ) 1537 2 - vert 812 ( 0.4088308215 0.4239915013 ) 1497 1 - vert 813 ( 0.4079264402 0.4751372337 ) 1496 1 - vert 814 ( 0.3932903409 0.4944604635 ) 1495 1 - vert 815 ( 0.3337671459 0.4885939956 ) 1498 1 - vert 816 ( 0.3519207835 0.4326373935 ) 1500 1 - vert 817 ( 0.367459774 0.4645684361 ) 1504 1 - vert 818 ( 0.33777982 0.4789742827 ) 1499 1 - vert 819 ( 0.0774939656 0.4253462553 ) 1767 4 - vert 820 ( 0.1069657207 0.4117678404 ) 1771 3 - vert 821 ( 0.3018787801 0.5310918093 ) 1527 2 - vert 822 ( 0.2286183536 0.5303949118 ) 1236 2 - vert 823 ( 0.1439307928 0.5389575362 ) 1505 3 - vert 824 ( 0.3589897156 0.4062440395 ) 1508 2 - vert 825 ( 0.3288226426 0.4180244207 ) 1501 3 - vert 826 ( 0.3541322947 0.3947893381 ) 1783 4 - vert 827 ( 0.212649852 0.4559247494 ) 1510 2 - vert 828 ( 0.2124633789 0.4074966908 ) 1774 5 - vert 829 ( 0.295052886 0.4036608338 ) 1779 4 - vert 830 ( 0.3190254867 0.4473839998 ) 1215 3 - vert 831 ( 0.262906462 0.4561910629 ) 1512 3 - vert 832 ( 0.9097238183 0.5257812738 ) 1521 2 - vert 833 ( 0.8825437427 0.5110060573 ) 1523 2 - vert 834 ( 0.9094944 0.9760050178 ) 1549 3 - vert 835 ( 0.9326827526 0.9889752865 ) 1546 3 - vert 836 ( 0.6186243892 0.6495701671 ) 1539 3 - vert 837 ( 0.6391683817 0.6333078742 ) 1549 3 - vert 838 ( 0.6090469956 0.6800134182 ) 1546 3 - vert 839 ( 0.61962533 0.6259011626 ) 1272 3 - vert 840 ( 0.7204926014 0.3928611875 ) 1552 4 - vert 841 ( 0.7579321861 0.4269043803 ) 1546 3 - vert 842 ( 0.7211619616 0.4401774406 ) 1477 3 - vert 843 ( 0.6341335773 0.4015330076 ) 1556 5 - vert 844 ( 0.6721040606 0.3867303133 ) 1561 4 - vert 845 ( 0.4408987164 0.6390709877 ) 1566 2 - vert 846 ( 0.3172201514 0.6833396554 ) 1301 5 - vert 847 ( 0.0787962973 0.6446386576 ) 1566 2 - vert 848 ( 0.466876924 0.6459610462 ) 1566 2 - vert 849 ( 0.9046775699 0.4928504825 ) 1136 1 - vert 850 ( 0.950093925 0.440998733 ) 1568 1 - vert 851 ( 0.9719032049 0.4428100586 ) 929 1 - vert 852 ( 0.9460786581 0.3970065713 ) 1574 1 - vert 853 ( 0.9756503701 0.3952539563 ) 1137 1 - vert 854 ( 0.8178055882 0.4802870154 ) 1135 1 - vert 855 ( 0.7965644002 0.4297861457 ) 962 1 - vert 856 ( 0.9048620462 0.357222259 ) 1575 1 - vert 857 ( 0.9388618469 0.3512775898 ) 1576 3 - vert 858 ( 0.8245270848 0.3758257031 ) 1581 2 - vert 859 ( 0.8012051582 0.3747473955 ) 1579 2 - vert 860 ( 0.8564575315 0.3695956469 ) 1583 2 - vert 861 ( 0.9682284594 0.3496643305 ) 1585 2 - vert 862 ( 0.7708232999 0.3824968338 ) 958 2 - vert 863 ( 0.9915254116 0.3501280546 ) 965 2 - vert 864 ( 0.764909029 0.4199460745 ) 1133 1 - vert 865 ( 0.7925951481 0.3462982178 ) 1589 4 - vert 866 ( 0.7662457228 0.3600251079 ) 1587 2 - vert 867 ( 0.561688602 0.2625313401 ) 1587 2 - vert 868 ( 0.5759554505 0.2937509418 ) 1593 2 - vert 869 ( 0.8233408332 0.3488204479 ) 1595 3 - vert 870 ( 0.9914909601 0.3319371343 ) 1602 4 - vert 871 ( 0.9701109529 0.3296480775 ) 1598 4 - vert 872 ( 0.9015637636 0.3301431537 ) 1606 4 - vert 873 ( 0.9399214983 0.3327356577 ) 1610 4 - vert 874 ( 0.5300602913 0.0490809083 ) 1614 4 - vert 875 ( 0.5089550614 0.0767536163 ) 1602 4 - vert 876 ( 0.8558390141 0.3424976468 ) 1618 5 - vert 877 ( 0.5518918633 0.0089600682 ) 1593 2 - vert 878 ( 0.2468391806 0.0082832575 ) 1831 3 - vert 879 ( 0.24702923 0.056795001 ) 1630 4 - vert 880 ( 0.180007726 0.0613898039 ) 1836 3 - vert 881 ( 0.3550749421 0.0102859735 ) 1829 2 - vert 882 ( 0.347266525 0.0399858356 ) 1628 2 - vert 883 ( 0.2130548954 0.0783062577 ) 1634 5 - vert 884 ( 0.3922063112 0.0709888935 ) 1648 4 - vert 885 ( 0.1103003621 0.0797612667 ) 1834 2 - vert 886 ( 0.0925641954 0.1063870788 ) 1715 4 - vert 887 ( 0.2802728117 0.046277523 ) 1639 4 - vert 888 ( 0.3505480886 0.0650349855 ) 1643 5 - vert 889 ( 0.083874166 0.1815125942 ) 1655 3 - vert 890 ( 0.0513322651 0.3739336729 ) 1665 3 - vert 891 ( 0.0965228677 0.3617821932 ) 1658 3 - vert 892 ( 0.1073260009 0.3915848136 ) 1763 4 - vert 893 ( 0.0578081608 0.3110636473 ) 1661 4 - vert 894 ( 0.1222535968 0.1674438715 ) 1668 3 - vert 895 ( 0.1576044858 0.1620275974 ) 1681 3 - vert 896 ( 0.1444258094 0.2205191851 ) 1733 2 - vert 897 ( 0.1824056208 0.1900250912 ) 1684 2 - vert 898 ( 0.1862074435 0.2645644546 ) 1671 3 - vert 899 ( 0.2371795177 0.2540616989 ) 1686 1 - vert 900 ( 0.2340686321 0.285172224 ) 1674 3 - vert 901 ( 0.4372490346 0.3222288489 ) 1702 5 - vert 902 ( 0.4185279906 0.1344797015 ) 1738 5 - vert 903 ( 0.428922087 0.2030869722 ) 1710 5 - vert 904 ( 0.3882690668 0.1523826122 ) 1839 6 - vert 905 ( 0.3936232924 0.2016937137 ) 1790 6 - vert 906 ( 0.4130477905 0.2399291992 ) 1848 5 - vert 907 ( 0.4221341908 0.2745028734 ) 1707 3 - vert 908 ( 0.3932344019 0.3226995468 ) 1687 4 - vert 909 ( 0.4437904954 0.0743006468 ) 1845 3 - vert 910 ( 0.3362599611 0.3014298677 ) 1691 3 - vert 911 ( 0.2762045264 0.3304995298 ) 1677 4 - vert 912 ( 0.3034223616 0.2632719874 ) 1730 3 - vert 913 ( 0.3660609126 0.2011561394 ) 1697 5 - vert 914 ( 0.3380084336 0.2682123184 ) 1725 5 - vert 915 ( 0.0802102685 0.2218263745 ) 1719 2 - vert 916 ( 0.2288490832 0.1999977827 ) 1694 3 - vert 917 ( 0.0509798229 0.2562607527 ) 1652 3 - vert 918 ( 0.0798471272 0.2886747122 ) 1826 3 - vert 919 ( 0.1606835723 0.1331404448 ) 1623 5 - vert 920 ( 0.2139489353 0.1501144171 ) 1721 4 - vert 921 ( 0.3914140165 0.3679138422 ) 1735 3 - vert 922 ( 0.353936404 0.3622125387 ) 1743 3 - vert 923 ( 0.3041800857 0.2214561105 ) 1746 4 - vert 924 ( 0.1109604836 0.2496719956 ) 1757 3 - vert 925 ( 0.2283400893 0.3581427336 ) 1753 4 - vert 926 ( 0.1693162918 0.290597856 ) 1750 3 - vert 927 ( 0.1139373779 0.349927783 ) 1760 3 - vert 928 ( 0.9691210985 0.3037109375 ) 1796 6 - vert 929 ( 0.3482938409 0.1539620757 ) 1602 4 - vert 930 ( 0.3478776813 0.1142273545 ) 1796 6 - vert 931 ( 0.8284341097 0.310080409 ) 1802 5 - vert 932 ( 0.8500990868 0.3097743988 ) 1807 4 - vert 933 ( 0.9015080333 0.3006564379 ) 1811 4 - vert 934 ( 0.9370734692 0.2986869812 ) 1815 5 - vert 935 ( 0.8730151653 0.2692120075 ) 1630 4 - vert 936 ( 0.8997855783 0.2657402158 ) 1639 4 - vert 937 ( 0.8473278284 0.2768980861 ) 1634 5 - vert 938 ( 0.2414392233 0.1182127595 ) 1802 5 - vert 939 ( 0.3257909715 0.0821592808 ) 1815 5 - vert 940 ( 0.3716933131 0.086319983 ) 1820 6 - vert 941 ( 0.2705033422 0.1606909633 ) 1589 4 - vert 942 ( 0.2840547562 0.18321383 ) 1587 2 - vert 943 ( 0.3135349154 0.1873478889 ) 1593 2 - vert 944 ( 0.3347135186 0.182977736 ) 1614 4 - vert 945 ( 0.0589729548 0.0657583475 ) 1836 3 - vert 946 ( 0.0208202004 0.0460392237 ) 1834 2 - vert 947 ( 0.183524251 0.0489068031 ) 1829 2 - vert 948 ( 0.1170584857 0.0669660568 ) 1831 3 - - numtris 1472 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 6 5 3 - tri 3 9 8 7 - tri 4 12 11 10 - tri 5 10 11 13 - tri 6 10 13 14 - tri 7 13 7 15 - tri 8 14 13 15 - tri 9 14 15 16 - tri 10 7 17 15 - tri 11 15 17 2 - tri 12 17 1 2 - tri 13 17 18 1 - tri 14 19 17 7 - tri 15 8 19 7 - tri 16 20 18 17 - tri 17 19 20 17 - tri 18 19 21 20 - tri 19 8 21 19 - tri 20 8 22 21 - tri 21 22 23 21 - tri 22 25 24 9 - tri 23 9 24 8 - tri 24 24 22 8 - tri 25 28 27 26 - tri 26 30 16 29 - tri 27 16 15 27 - tri 28 15 2 27 - tri 29 31 10 14 - tri 30 28 16 27 - tri 31 5 32 4 - tri 32 33 28 26 - tri 33 33 26 34 - tri 34 37 36 35 - tri 35 36 39 38 - tri 36 35 36 38 - tri 37 40 12 10 - tri 38 41 12 40 - tri 39 43 42 36 - tri 40 31 30 42 - tri 41 43 36 37 - tri 42 36 42 39 - tri 43 9 7 11 - tri 44 12 9 11 - tri 45 11 7 13 - tri 46 26 27 0 - tri 47 32 26 0 - tri 48 34 26 32 - tri 49 27 2 0 - tri 50 46 45 44 - tri 51 47 31 42 - tri 52 43 47 42 - tri 53 49 48 20 - tri 54 23 49 20 - tri 55 52 51 50 - tri 56 54 4 53 - tri 57 57 56 55 - tri 58 60 59 58 - tri 59 55 56 61 - tri 60 60 62 59 - tri 61 59 64 63 - tri 62 66 65 62 - tri 63 66 67 65 - tri 64 70 69 68 - tri 65 71 67 66 - tri 66 72 67 71 - tri 67 75 74 73 - tri 68 77 76 64 - tri 69 68 55 61 - tri 70 80 79 78 - tri 71 82 73 81 - tri 72 83 73 82 - tri 73 73 84 81 - tri 74 73 85 84 - tri 75 77 84 86 - tri 76 87 84 77 - tri 77 81 84 87 - tri 78 68 61 88 - tri 79 70 68 88 - tri 80 75 73 83 - tri 81 77 86 76 - tri 82 86 45 76 - tri 83 61 56 89 - tri 84 90 89 45 - tri 85 59 63 58 - tri 86 93 92 91 - tri 87 95 94 92 - tri 88 93 91 96 - tri 89 96 91 97 - tri 90 100 99 98 - tri 91 94 101 56 - tri 92 56 101 89 - tri 93 104 103 102 - tri 94 95 104 94 - tri 95 106 58 105 - tri 96 91 56 57 - tri 97 109 108 107 - tri 98 110 108 109 - tri 99 86 90 45 - tri 100 97 91 57 - tri 101 106 60 58 - tri 102 85 90 86 - tri 103 84 85 86 - tri 104 112 111 90 - tri 105 111 89 90 - tri 106 61 89 111 - tri 107 104 101 94 - tri 108 104 102 101 - tri 109 77 64 59 - tri 110 77 59 65 - tri 111 65 59 62 - tri 112 112 108 111 - tri 113 107 108 112 - tri 114 114 113 71 - tri 115 113 72 71 - tri 116 115 88 108 - tri 117 110 115 108 - tri 118 70 115 110 - tri 119 70 88 115 - tri 120 74 90 85 - tri 121 74 112 90 - tri 122 73 74 85 - tri 123 80 78 87 - tri 124 78 81 87 - tri 125 87 65 116 - tri 126 87 77 65 - tri 127 80 87 116 - tri 128 88 111 108 - tri 129 88 61 111 - tri 130 92 56 91 - tri 131 92 94 56 - tri 132 93 95 92 - tri 133 117 95 93 - tri 134 100 106 105 - tri 135 100 98 106 - tri 136 21 23 20 - tri 137 118 51 52 - tri 138 118 119 51 - tri 139 32 0 120 - tri 140 3 54 121 - tri 141 3 4 54 - tri 142 76 45 46 - tri 143 64 76 122 - tri 144 76 46 122 - tri 145 45 89 44 - tri 146 101 123 89 - tri 147 63 64 124 - tri 148 64 122 124 - tri 149 102 123 101 - tri 150 102 125 123 - tri 151 103 125 102 - tri 152 41 25 12 - tri 153 25 9 12 - tri 154 42 29 39 - tri 155 42 30 29 - tri 156 31 14 30 - tri 157 30 14 16 - tri 158 6 34 5 - tri 159 34 32 5 - tri 160 38 33 34 - tri 161 38 34 6 - tri 162 29 16 28 - tri 163 38 39 33 - tri 164 31 126 10 - tri 165 89 127 44 - tri 166 123 127 89 - tri 167 40 10 126 - tri 168 39 29 28 - tri 169 39 28 33 - tri 170 32 53 4 - tri 171 32 120 53 - tri 172 130 129 128 - tri 173 130 131 129 - tri 174 131 132 129 - tri 175 135 134 133 - tri 176 138 137 136 - tri 177 128 129 139 - tri 178 138 140 137 - tri 179 129 132 141 - tri 180 132 142 141 - tri 181 135 143 134 - tri 182 145 138 144 - tri 183 147 146 131 - tri 184 147 131 130 - tri 185 136 137 148 - tri 186 129 141 149 - tri 187 140 150 137 - tri 188 143 152 151 - tri 189 143 151 134 - tri 190 129 149 139 - tri 191 139 149 153 - tri 192 134 151 154 - tri 193 143 155 152 - tri 194 155 156 152 - tri 195 152 156 151 - tri 196 157 146 147 - tri 197 157 158 146 - tri 198 161 160 159 - tri 199 163 135 162 - tri 200 136 156 155 - tri 201 136 148 156 - tri 202 137 150 164 - tri 203 154 151 165 - tri 204 154 165 166 - tri 205 156 148 151 - tri 206 165 168 167 - tri 207 165 169 168 - tri 208 172 171 170 - tri 209 175 174 173 - tri 210 164 177 176 - tri 211 179 178 177 - tri 212 164 179 177 - tri 213 169 180 168 - tri 214 181 180 169 - tri 215 137 181 148 - tri 216 141 182 172 - tri 217 182 183 172 - tri 218 166 165 184 - tri 219 165 167 184 - tri 220 149 141 172 - tri 221 149 172 170 - tri 222 150 179 164 - tri 223 149 170 153 - tri 224 148 181 169 - tri 225 137 164 181 - tri 226 186 185 159 - tri 227 189 188 187 - tri 228 190 188 189 - tri 229 191 188 190 - tri 230 182 184 183 - tri 231 182 166 184 - tri 232 154 166 182 - tri 233 131 134 132 - tri 234 131 133 134 - tri 235 132 134 142 - tri 236 146 133 131 - tri 237 146 162 133 - tri 238 134 154 142 - tri 239 194 193 192 - tri 240 195 174 175 - tri 241 196 195 175 - tri 242 195 197 174 - tri 243 197 198 174 - tri 244 201 200 199 - tri 245 199 202 135 - tri 246 163 199 135 - tri 247 203 199 163 - tri 248 206 205 204 - tri 249 199 200 202 - tri 250 208 192 207 - tri 251 211 210 209 - tri 252 214 213 212 - tri 253 214 215 213 - tri 254 212 213 216 - tri 255 212 216 217 - tri 256 220 219 218 - tri 257 223 222 221 - tri 258 224 219 223 - tri 259 225 224 223 - tri 260 224 218 219 - tri 261 228 227 226 - tri 262 231 230 229 - tri 263 229 230 232 - tri 264 235 234 233 - tri 265 237 223 236 - tri 266 240 239 238 - tri 267 241 225 237 - tri 268 225 223 237 - tri 269 242 229 239 - tri 270 239 229 232 - tri 271 245 244 243 - tri 272 245 246 244 - tri 273 245 243 247 - tri 274 248 245 247 - tri 275 251 250 249 - tri 276 249 250 190 - tri 277 254 253 252 - tri 278 243 256 255 - tri 279 244 257 256 - tri 280 244 256 243 - tri 281 257 251 256 - tri 282 256 251 249 - tri 283 259 258 254 - tri 284 254 258 253 - tri 285 262 261 260 - tri 286 262 264 263 - tri 287 267 266 265 - tri 288 267 265 263 - tri 289 267 263 264 - tri 290 233 268 227 - tri 291 268 226 227 - tri 292 237 236 269 - tri 293 270 241 237 - tri 294 270 237 269 - tri 295 246 271 244 - tri 296 272 271 246 - tri 297 272 273 271 - tri 298 272 274 273 - tri 299 275 274 272 - tri 300 251 277 276 - tri 301 251 276 250 - tri 302 277 186 276 - tri 303 280 279 278 - tri 304 279 281 278 - tri 305 254 252 282 - tri 306 282 252 283 - tri 307 283 252 284 - tri 308 273 286 285 - tri 309 273 285 271 - tri 310 271 257 244 - tri 311 271 285 257 - tri 312 285 277 257 - tri 313 285 287 277 - tri 314 257 277 251 - tri 315 286 287 285 - tri 316 279 259 281 - tri 317 288 259 279 - tri 318 281 259 254 - tri 319 278 254 282 - tri 320 278 281 254 - tri 321 289 247 280 - tri 322 247 288 280 - tri 323 280 288 279 - tri 324 260 261 268 - tri 325 258 189 253 - tri 326 196 290 195 - tri 327 290 197 195 - tri 328 151 169 165 - tri 329 148 169 151 - tri 330 164 176 181 - tri 331 181 176 180 - tri 332 249 190 291 - tri 333 258 291 190 - tri 334 258 190 189 - tri 335 276 186 292 - tri 336 293 185 186 - tri 337 287 186 277 - tri 338 287 293 186 - tri 339 255 249 291 - tri 340 255 256 249 - tri 341 206 294 203 - tri 342 206 204 294 - tri 343 294 204 201 - tri 344 294 201 199 - tri 345 203 294 199 - tri 346 295 205 206 - tri 347 295 206 203 - tri 348 252 158 157 - tri 349 252 253 158 - tri 350 185 161 159 - tri 351 284 252 157 - tri 352 158 162 146 - tri 353 158 187 162 - tri 354 201 296 200 - tri 355 204 296 201 - tri 356 204 144 296 - tri 357 200 155 202 - tri 358 202 155 143 - tri 359 135 202 143 - tri 360 144 136 296 - tri 361 144 138 136 - tri 362 253 187 158 - tri 363 253 189 187 - tri 364 162 135 133 - tri 365 250 191 190 - tri 366 295 203 297 - tri 367 297 203 163 - tri 368 250 292 191 - tri 369 276 292 250 - tri 370 205 145 204 - tri 371 204 145 144 - tri 372 297 163 298 - tri 373 298 163 162 - tri 374 187 298 162 - tri 375 188 298 187 - tri 376 191 298 188 - tri 377 299 295 297 - tri 378 299 297 298 - tri 379 191 299 298 - tri 380 292 299 191 - tri 381 300 205 295 - tri 382 300 295 299 - tri 383 292 300 299 - tri 384 186 300 292 - tri 385 205 160 145 - tri 386 159 160 205 - tri 387 300 159 205 - tri 388 186 159 300 - tri 389 303 302 301 - tri 390 303 304 302 - tri 391 304 305 302 - tri 392 306 305 304 - tri 393 307 246 245 - tri 394 308 246 307 - tri 395 308 272 246 - tri 396 301 302 309 - tri 397 226 304 303 - tri 398 219 222 223 - tri 399 274 286 273 - tri 400 289 280 278 - tri 401 142 154 182 - tri 402 142 182 141 - tri 403 219 310 222 - tri 404 220 310 219 - tri 405 220 228 310 - tri 406 228 226 310 - tri 407 226 303 310 - tri 408 310 303 222 - tri 409 222 303 301 - tri 410 222 301 221 - tri 411 311 248 247 - tri 412 248 307 245 - tri 413 305 312 309 - tri 414 305 309 302 - tri 415 235 233 227 - tri 416 260 268 233 - tri 417 260 233 234 - tri 418 235 227 228 - tri 419 220 235 228 - tri 420 216 314 313 - tri 421 216 313 217 - tri 422 315 274 275 - tri 423 275 272 308 - tri 424 196 175 316 - tri 425 231 317 230 - tri 426 231 318 317 - tri 427 318 319 317 - tri 428 322 321 320 - tri 429 192 321 322 - tri 430 323 322 214 - tri 431 322 320 214 - tri 432 320 215 214 - tri 433 193 215 320 - tri 434 321 193 320 - tri 435 192 193 321 - tri 436 207 192 323 - tri 437 192 322 323 - tri 438 326 325 324 - tri 439 326 324 327 - tri 440 247 243 255 - tri 441 288 255 259 - tri 442 247 255 288 - tri 443 174 198 211 - tri 444 200 136 155 - tri 445 296 136 200 - tri 446 328 314 216 - tri 447 213 328 216 - tri 448 215 329 213 - tri 449 329 328 213 - tri 450 193 330 215 - tri 451 215 330 329 - tri 452 194 327 193 - tri 453 194 326 327 - tri 454 327 324 331 - tri 455 327 331 330 - tri 456 193 327 330 - tri 457 333 332 328 - tri 458 329 333 328 - tri 459 334 332 333 - tri 460 330 333 329 - tri 461 330 331 334 - tri 462 330 334 333 - tri 463 286 293 287 - tri 464 278 282 283 - tri 465 259 255 258 - tri 466 255 291 258 - tri 467 211 335 210 - tri 468 210 335 336 - tri 469 325 337 324 - tri 470 325 338 337 - tri 471 339 211 209 - tri 472 339 209 338 - tri 473 173 339 338 - tri 474 173 174 339 - tri 475 174 211 339 - tri 476 328 332 340 - tri 477 332 341 340 - tri 478 328 340 314 - tri 479 340 342 314 - tri 480 209 210 343 - tri 481 210 336 343 - tri 482 343 336 344 - tri 483 209 343 344 - tri 484 341 345 342 - tri 485 341 342 340 - tri 486 211 346 335 - tri 487 331 347 334 - tri 488 334 347 332 - tri 489 347 341 332 - tri 490 338 348 337 - tri 491 338 209 348 - tri 492 209 344 348 - tri 493 348 344 345 - tri 494 348 345 347 - tri 495 337 348 347 - tri 496 347 345 341 - tri 497 349 208 207 - tri 498 196 316 350 - tri 499 183 351 172 - tri 500 184 167 352 - tri 501 183 184 351 - tri 502 184 352 351 - tri 503 208 194 192 - tri 504 172 351 171 - tri 505 211 353 346 - tri 506 198 353 211 - tri 507 355 354 289 - tri 508 358 357 356 - tri 509 221 356 359 - tri 510 311 247 354 - tri 511 354 247 289 - tri 512 236 359 357 - tri 513 357 359 356 - tri 514 223 359 236 - tri 515 223 221 359 - tri 516 269 357 358 - tri 517 269 236 357 - tri 518 263 265 360 - tri 519 265 361 360 - tri 520 360 361 362 - tri 521 360 362 306 - tri 522 362 312 305 - tri 523 306 362 305 - tri 524 363 304 226 - tri 525 363 306 304 - tri 526 268 363 226 - tri 527 261 363 268 - tri 528 262 263 364 - tri 529 263 360 364 - tri 530 364 360 306 - tri 531 364 306 363 - tri 532 261 364 363 - tri 533 262 364 261 - tri 534 337 347 331 - tri 535 324 337 331 - tri 536 365 208 349 - tri 537 366 365 349 - tri 538 242 239 240 - tri 539 242 240 367 - tri 540 196 369 368 - tri 541 371 370 349 - tri 542 374 373 372 - tri 543 373 52 372 - tri 544 376 372 375 - tri 545 374 372 376 - tri 546 118 52 373 - tri 547 377 118 373 - tri 548 377 119 118 - tri 549 377 378 119 - tri 550 52 50 372 - tri 551 372 50 375 - tri 552 375 50 379 - tri 553 375 379 380 - tri 554 378 381 119 - tri 555 378 382 381 - tri 556 51 379 50 - tri 557 51 383 379 - tri 558 119 381 51 - tri 559 381 383 51 - tri 560 376 375 384 - tri 561 384 375 380 - tri 562 385 382 378 - tri 563 386 376 384 - tri 564 387 378 377 - tri 565 387 385 378 - tri 566 385 388 382 - tri 567 389 388 385 - tri 568 49 390 48 - tri 569 49 391 390 - tri 570 382 392 381 - tri 571 388 392 382 - tri 572 386 384 393 - tri 573 393 384 394 - tri 574 380 379 395 - tri 575 380 395 396 - tri 576 397 54 53 - tri 577 397 53 398 - tri 578 384 380 396 - tri 579 384 396 394 - tri 580 381 392 383 - tri 581 392 399 383 - tri 582 121 54 400 - tri 583 397 400 54 - tri 584 383 395 379 - tri 585 383 399 395 - tri 586 403 402 401 - tri 587 405 402 404 - tri 588 406 403 401 - tri 589 407 405 404 - tri 590 410 409 408 - tri 591 412 411 405 - tri 592 407 412 405 - tri 593 413 409 410 - tri 594 416 415 414 - tri 595 418 417 415 - tri 596 415 419 414 - tri 597 418 415 416 - tri 598 422 421 420 - tri 599 422 420 423 - tri 600 424 422 423 - tri 601 424 423 425 - tri 602 426 424 425 - tri 603 335 418 416 - tri 604 335 346 418 - tri 605 429 428 427 - tri 606 432 431 430 - tri 607 433 431 432 - tri 608 435 434 431 - tri 609 433 435 431 - tri 610 436 433 432 - tri 611 437 433 436 - tri 612 437 435 433 - tri 613 439 438 429 - tri 614 429 438 428 - tri 615 430 441 440 - tri 616 431 441 430 - tri 617 443 426 442 - tri 618 439 442 438 - tri 619 446 445 444 - tri 620 413 447 409 - tri 621 448 421 422 - tri 622 448 447 413 - tri 623 445 425 449 - tri 624 452 451 450 - tri 625 453 451 452 - tri 626 415 417 419 - tri 627 417 453 419 - tri 628 420 455 454 - tri 629 423 420 454 - tri 630 425 423 449 - tri 631 449 423 454 - tri 632 442 445 446 - tri 633 442 426 445 - tri 634 426 425 445 - tri 635 441 407 404 - tri 636 441 404 456 - tri 637 441 456 440 - tri 638 405 411 402 - tri 639 401 402 411 - tri 640 457 439 429 - tri 641 457 429 458 - tri 642 458 429 427 - tri 643 314 457 458 - tri 644 314 458 313 - tri 645 438 446 437 - tri 646 442 446 438 - tri 647 428 438 437 - tri 648 428 437 436 - tri 649 437 444 435 - tri 650 446 444 437 - tri 651 431 407 441 - tri 652 444 434 435 - tri 653 459 443 442 - tri 654 459 442 439 - tri 655 457 459 439 - tri 656 342 459 457 - tri 657 314 342 457 - tri 658 335 416 336 - tri 659 336 416 344 - tri 660 410 403 406 - tri 661 410 408 403 - tri 662 455 410 406 - tri 663 421 455 420 - tri 664 421 410 455 - tri 665 421 413 410 - tri 666 445 449 460 - tri 667 419 453 452 - tri 668 461 448 422 - tri 669 462 426 443 - tri 670 461 450 448 - tri 671 345 459 342 - tri 672 345 443 459 - tri 673 344 462 345 - tri 674 345 462 443 - tri 675 463 461 424 - tri 676 424 461 422 - tri 677 462 463 426 - tri 678 463 424 426 - tri 679 414 419 464 - tri 680 464 419 452 - tri 681 416 414 464 - tri 682 452 461 463 - tri 683 464 452 463 - tri 684 452 450 461 - tri 685 462 464 463 - tri 686 344 464 462 - tri 687 344 416 464 - tri 688 445 460 444 - tri 689 465 447 448 - tri 690 450 465 448 - tri 691 451 466 450 - tri 692 466 465 450 - tri 693 393 394 467 - tri 694 434 469 468 - tri 695 392 470 399 - tri 696 470 471 399 - tri 697 399 471 395 - tri 698 471 472 395 - tri 699 394 396 467 - tri 700 467 396 473 - tri 701 396 395 472 - tri 702 396 472 473 - tri 703 472 475 474 - tri 704 471 475 472 - tri 705 471 476 475 - tri 706 470 476 471 - tri 707 455 406 477 - tri 708 454 455 477 - tri 709 473 472 474 - tri 710 478 411 412 - tri 711 479 412 407 - tri 712 431 479 407 - tri 713 468 478 479 - tri 714 479 478 412 - tri 715 388 470 392 - tri 716 480 454 477 - tri 717 449 480 481 - tri 718 449 454 480 - tri 719 460 481 482 - tri 720 460 449 481 - tri 721 460 483 444 - tri 722 460 482 483 - tri 723 448 413 421 - tri 724 486 485 484 - tri 725 487 485 486 - tri 726 490 489 488 - tri 727 492 491 488 - tri 728 492 488 489 - tri 729 409 493 408 - tri 730 434 468 479 - tri 731 479 431 434 - tri 732 444 483 469 - tri 733 444 469 434 - tri 734 491 492 484 - tri 735 484 485 491 - tri 736 496 495 494 - tri 737 499 498 497 - tri 738 500 498 499 - tri 739 503 502 501 - tri 740 506 505 504 - tri 741 505 507 504 - tri 742 505 508 507 - tri 743 507 509 502 - tri 744 508 509 507 - tri 745 508 510 509 - tri 746 502 509 511 - tri 747 509 496 511 - tri 748 511 496 494 - tri 749 511 494 512 - tri 750 513 502 511 - tri 751 501 502 513 - tri 752 514 511 512 - tri 753 513 511 514 - tri 754 513 514 515 - tri 755 501 513 515 - tri 756 501 515 516 - tri 757 516 515 517 - tri 758 519 503 518 - tri 759 503 501 518 - tri 760 518 501 516 - tri 761 522 521 520 - tri 762 524 523 510 - tri 763 510 520 509 - tri 764 509 520 496 - tri 765 525 508 505 - tri 766 522 520 510 - tri 767 499 497 526 - tri 768 527 521 522 - tri 769 527 528 521 - tri 770 531 530 529 - tri 771 529 533 532 - tri 772 530 533 529 - tri 773 534 505 506 - tri 774 535 534 506 - tri 775 537 529 536 - tri 776 525 536 524 - tri 777 537 531 529 - tri 778 529 532 536 - tri 779 503 504 502 - tri 780 506 504 503 - tri 781 504 507 502 - tri 782 521 495 520 - tri 783 526 495 521 - tri 784 528 526 521 - tri 785 520 495 496 - tri 786 540 539 538 - tri 787 541 536 525 - tri 788 537 536 541 - tri 789 543 514 542 - tri 790 517 514 543 - tri 791 546 545 544 - tri 792 548 547 497 - tri 793 551 550 549 - tri 794 554 553 552 - tri 795 550 555 549 - tri 796 554 552 556 - tri 797 552 558 557 - tri 798 560 556 559 - tri 799 560 559 561 - tri 800 564 563 562 - tri 801 565 560 561 - tri 802 566 565 561 - tri 803 569 568 567 - tri 804 571 557 570 - tri 805 563 555 550 - tri 806 574 573 572 - tri 807 576 575 568 - tri 808 577 576 568 - tri 809 568 575 578 - tri 810 568 578 579 - tri 811 571 580 578 - tri 812 581 571 578 - tri 813 575 581 578 - tri 814 563 582 555 - tri 815 564 582 563 - tri 816 569 577 568 - tri 817 571 570 580 - tri 818 580 570 538 - tri 819 555 583 549 - tri 820 584 538 583 - tri 821 552 553 558 - tri 822 587 586 585 - tri 823 589 585 588 - tri 824 587 590 586 - tri 825 590 591 586 - tri 826 594 593 592 - tri 827 588 549 595 - tri 828 549 583 595 - tri 829 598 597 596 - tri 830 589 588 598 - tri 831 600 599 553 - tri 832 586 551 549 - tri 833 603 602 601 - tri 834 604 603 601 - tri 835 580 538 584 - tri 836 591 551 586 - tri 837 600 553 554 - tri 838 579 580 584 - tri 839 578 580 579 - tri 840 606 584 605 - tri 841 605 584 583 - tri 842 555 605 583 - tri 843 598 588 595 - tri 844 598 595 597 - tri 845 571 552 557 - tri 846 571 559 552 - tri 847 559 556 552 - tri 848 606 605 601 - tri 849 602 606 601 - tri 850 608 565 607 - tri 851 607 565 566 - tri 852 609 601 582 - tri 853 604 601 609 - tri 854 564 604 609 - tri 855 564 609 582 - tri 856 567 579 584 - tri 857 567 584 606 - tri 858 568 579 567 - tri 859 574 581 573 - tri 860 573 581 575 - tri 861 581 610 559 - tri 862 581 559 571 - tri 863 574 610 581 - tri 864 582 601 605 - tri 865 582 605 555 - tri 866 585 586 549 - tri 867 585 549 588 - tri 868 587 585 589 - tri 869 611 587 589 - tri 870 594 599 600 - tri 871 594 600 593 - tri 872 515 514 517 - tri 873 612 546 544 - tri 874 612 544 613 - tri 875 526 614 495 - tri 876 498 615 548 - tri 877 498 548 497 - tri 878 570 540 538 - tri 879 557 616 570 - tri 880 570 616 540 - tri 881 538 539 583 - tri 882 595 583 617 - tri 883 558 618 557 - tri 884 557 618 616 - tri 885 597 595 617 - tri 886 597 617 619 - tri 887 596 597 619 - tri 888 535 506 519 - tri 889 519 506 503 - tri 890 536 532 523 - tri 891 536 523 524 - tri 892 525 524 508 - tri 893 524 510 508 - tri 894 500 499 528 - tri 895 528 499 526 - tri 896 533 528 527 - tri 897 533 500 528 - tri 898 523 522 510 - tri 899 533 527 532 - tri 900 525 505 620 - tri 901 583 539 621 - tri 902 617 583 621 - tri 903 534 620 505 - tri 904 532 522 523 - tri 905 532 527 522 - tri 906 526 497 547 - tri 907 526 547 614 - tri 908 624 623 622 - tri 909 624 622 625 - tri 910 625 622 626 - tri 911 629 628 627 - tri 912 632 631 630 - tri 913 623 633 622 - tri 914 632 630 634 - tri 915 622 635 626 - tri 916 626 635 636 - tri 917 629 627 637 - tri 918 639 638 632 - tri 919 641 625 640 - tri 920 641 624 625 - tri 921 631 642 630 - tri 922 622 643 635 - tri 923 634 630 644 - tri 924 637 646 645 - tri 925 637 627 646 - tri 926 622 633 643 - tri 927 633 647 643 - tri 928 627 648 646 - tri 929 637 645 649 - tri 930 649 645 650 - tri 931 645 646 650 - tri 932 651 641 640 - tri 933 651 640 652 - tri 934 655 654 653 - tri 935 657 656 629 - tri 936 631 649 650 - tri 937 631 650 642 - tri 938 630 658 644 - tri 939 648 659 646 - tri 940 648 660 659 - tri 941 650 646 642 - tri 942 659 662 661 - tri 943 659 661 663 - tri 944 666 665 664 - tri 945 669 668 667 - tri 946 658 671 670 - tri 947 673 670 672 - tri 948 658 670 673 - tri 949 663 661 674 - tri 950 675 663 674 - tri 951 630 642 675 - tri 952 635 666 676 - tri 953 676 666 677 - tri 954 660 678 659 - tri 955 659 678 662 - tri 956 643 666 635 - tri 957 643 665 666 - tri 958 644 658 673 - tri 959 643 647 665 - tri 960 642 663 675 - tri 961 630 675 658 - tri 962 680 654 679 - tri 963 683 682 681 - tri 964 684 683 681 - tri 965 685 684 681 - tri 966 676 677 678 - tri 967 676 678 660 - tri 968 648 676 660 - tri 969 625 626 627 - tri 970 625 627 628 - tri 971 626 636 627 - tri 972 640 625 628 - tri 973 640 628 656 - tri 974 627 636 648 - tri 975 688 687 686 - tri 976 689 669 667 - tri 977 196 669 689 - tri 978 689 667 197 - tri 979 197 667 198 - tri 980 692 691 690 - tri 981 691 629 693 - tri 982 657 629 691 - tri 983 694 657 691 - tri 984 697 696 695 - tri 985 691 693 690 - tri 986 698 207 687 - tri 987 701 700 699 - tri 988 214 212 702 - tri 989 214 702 703 - tri 990 212 704 702 - tri 991 212 217 704 - tri 992 707 706 705 - tri 993 710 709 708 - tri 994 711 710 705 - tri 995 712 710 711 - tri 996 711 705 706 - tri 997 715 714 713 - tri 998 718 717 716 - tri 999 717 719 716 - tri 1000 722 721 720 - tri 1001 724 723 710 - tri 1002 727 726 725 - tri 1003 728 724 712 - tri 1004 712 724 710 - tri 1005 729 725 717 - tri 1006 725 719 717 - tri 1007 732 731 730 - tri 1008 732 730 733 - tri 1009 732 734 731 - tri 1010 735 734 732 - tri 1011 738 737 736 - tri 1012 737 684 736 - tri 1013 741 740 739 - tri 1014 731 743 742 - tri 1015 730 742 744 - tri 1016 730 731 742 - tri 1017 744 742 738 - tri 1018 742 737 738 - tri 1019 746 741 745 - tri 1020 741 739 745 - tri 1021 749 748 747 - tri 1022 749 751 750 - tri 1023 754 753 752 - tri 1024 754 751 753 - tri 1025 754 750 751 - tri 1026 721 713 755 - tri 1027 755 713 714 - tri 1028 724 756 723 - tri 1029 757 724 728 - tri 1030 757 756 724 - tri 1031 733 730 758 - tri 1032 759 733 758 - tri 1033 759 758 760 - tri 1034 759 760 761 - tri 1035 762 759 761 - tri 1036 738 764 763 - tri 1037 738 736 764 - tri 1038 763 764 680 - tri 1039 767 766 765 - tri 1040 765 766 768 - tri 1041 741 769 740 - tri 1042 769 770 740 - tri 1043 770 771 740 - tri 1044 760 773 772 - tri 1045 760 758 773 - tri 1046 758 730 744 - tri 1047 758 744 773 - tri 1048 773 744 763 - tri 1049 773 763 774 - tri 1050 744 738 763 - tri 1051 772 773 774 - tri 1052 765 768 746 - tri 1053 775 765 746 - tri 1054 768 741 746 - tri 1055 766 769 741 - tri 1056 766 741 768 - tri 1057 776 767 734 - tri 1058 734 767 775 - tri 1059 767 765 775 - tri 1060 748 755 747 - tri 1061 745 739 683 - tri 1062 196 689 290 - tri 1063 290 689 197 - tri 1064 646 659 663 - tri 1065 642 646 663 - tri 1066 658 675 671 - tri 1067 675 674 671 - tri 1068 737 777 684 - tri 1069 745 684 777 - tri 1070 745 683 684 - tri 1071 764 778 680 - tri 1072 779 680 679 - tri 1073 774 763 680 - tri 1074 774 680 779 - tri 1075 743 777 737 - tri 1076 743 737 742 - tri 1077 697 694 780 - tri 1078 697 780 696 - tri 1079 780 692 696 - tri 1080 780 691 692 - tri 1081 694 691 780 - tri 1082 781 697 695 - tri 1083 781 694 697 - tri 1084 740 651 652 - tri 1085 740 652 739 - tri 1086 679 654 655 - tri 1087 771 651 740 - tri 1088 652 640 656 - tri 1089 652 656 682 - tri 1090 692 690 782 - tri 1091 696 692 782 - tri 1092 696 782 638 - tri 1093 690 693 649 - tri 1094 693 637 649 - tri 1095 629 637 693 - tri 1096 638 782 631 - tri 1097 638 631 632 - tri 1098 739 652 682 - tri 1099 739 682 683 - tri 1100 656 628 629 - tri 1101 736 684 685 - tri 1102 781 783 694 - tri 1103 783 657 694 - tri 1104 736 685 778 - tri 1105 764 736 778 - tri 1106 695 696 639 - tri 1107 696 638 639 - tri 1108 783 784 657 - tri 1109 784 656 657 - tri 1110 682 656 784 - tri 1111 681 682 784 - tri 1112 685 681 784 - tri 1113 785 783 781 - tri 1114 785 784 783 - tri 1115 685 784 785 - tri 1116 778 685 785 - tri 1117 786 781 695 - tri 1118 786 785 781 - tri 1119 778 785 786 - tri 1120 680 778 786 - tri 1121 695 639 653 - tri 1122 654 695 653 - tri 1123 786 695 654 - tri 1124 680 786 654 - tri 1125 789 788 787 - tri 1126 789 787 790 - tri 1127 790 787 791 - tri 1128 792 790 791 - tri 1129 793 732 733 - tri 1130 794 793 733 - tri 1131 794 733 759 - tri 1132 788 795 787 - tri 1133 714 789 790 - tri 1134 705 710 708 - tri 1135 761 760 772 - tri 1136 776 766 767 - tri 1137 636 676 648 - tri 1138 636 635 676 - tri 1139 705 708 796 - tri 1140 707 705 796 - tri 1141 707 796 715 - tri 1142 715 796 714 - tri 1143 714 796 789 - tri 1144 796 708 789 - tri 1145 708 788 789 - tri 1146 708 709 788 - tri 1147 797 734 735 - tri 1148 735 732 793 - tri 1149 791 795 798 - tri 1150 791 787 795 - tri 1151 722 713 721 - tri 1152 748 721 755 - tri 1153 748 720 721 - tri 1154 722 715 713 - tri 1155 707 715 722 - tri 1156 704 313 799 - tri 1157 704 217 313 - tri 1158 800 762 761 - tri 1159 762 794 759 - tri 1160 196 801 669 - tri 1161 718 716 802 - tri 1162 718 802 803 - tri 1163 803 802 804 - tri 1164 807 806 805 - tri 1165 687 807 805 - tri 1166 323 214 807 - tri 1167 807 214 806 - tri 1168 806 214 703 - tri 1169 686 806 703 - tri 1170 805 806 686 - tri 1171 687 805 686 - tri 1172 207 323 687 - tri 1173 687 323 807 - tri 1174 810 809 808 - tri 1175 810 811 809 - tri 1176 734 743 731 - tri 1177 775 746 743 - tri 1178 734 775 743 - tri 1179 667 701 198 - tri 1180 690 649 631 - tri 1181 782 690 631 - tri 1182 812 704 799 - tri 1183 702 704 812 - tri 1184 703 702 813 - tri 1185 813 702 812 - tri 1186 686 703 814 - tri 1187 703 813 814 - tri 1188 688 686 811 - tri 1189 688 811 810 - tri 1190 811 815 809 - tri 1191 811 814 815 - tri 1192 686 814 811 - tri 1193 817 812 816 - tri 1194 813 812 817 - tri 1195 818 817 816 - tri 1196 814 813 817 - tri 1197 814 818 815 - tri 1198 814 817 818 - tri 1199 772 774 779 - tri 1200 766 770 769 - tri 1201 746 745 743 - tri 1202 743 745 777 - tri 1203 701 699 819 - tri 1204 699 820 819 - tri 1205 808 809 821 - tri 1206 808 821 822 - tri 1207 823 700 701 - tri 1208 823 822 700 - tri 1209 668 822 823 - tri 1210 668 823 667 - tri 1211 667 823 701 - tri 1212 812 824 816 - tri 1213 816 824 825 - tri 1214 812 799 824 - tri 1215 824 799 826 - tri 1216 700 827 699 - tri 1217 699 827 820 - tri 1218 827 828 820 - tri 1219 700 828 827 - tri 1220 825 826 829 - tri 1221 825 824 826 - tri 1222 701 819 346 - tri 1223 815 818 830 - tri 1224 818 816 830 - tri 1225 830 816 825 - tri 1226 822 821 831 - tri 1227 822 831 700 - tri 1228 700 831 828 - tri 1229 831 829 828 - tri 1230 831 830 829 - tri 1231 821 830 831 - tri 1232 830 825 829 - tri 1233 349 207 698 - tri 1234 196 350 801 - tri 1235 677 666 832 - tri 1236 678 833 662 - tri 1237 677 832 678 - tri 1238 678 832 833 - tri 1239 698 687 688 - tri 1240 666 664 832 - tri 1241 701 346 353 - tri 1242 198 701 353 - tri 1243 835 776 834 - tri 1244 838 837 836 - tri 1245 709 839 837 - tri 1246 797 834 734 - tri 1247 834 776 734 - tri 1248 723 836 839 - tri 1249 836 837 839 - tri 1250 710 723 839 - tri 1251 710 839 709 - tri 1252 756 838 836 - tri 1253 756 836 723 - tri 1254 751 840 753 - tri 1255 753 840 841 - tri 1256 840 842 841 - tri 1257 840 792 842 - tri 1258 842 791 798 - tri 1259 792 791 842 - tri 1260 843 714 790 - tri 1261 843 790 792 - tri 1262 755 714 843 - tri 1263 747 755 843 - tri 1264 749 844 751 - tri 1265 751 844 840 - tri 1266 844 792 840 - tri 1267 844 843 792 - tri 1268 747 843 844 - tri 1269 749 747 844 - tri 1270 821 815 830 - tri 1271 809 815 821 - tri 1272 845 349 698 - tri 1273 366 349 845 - tri 1274 729 727 725 - tri 1275 729 846 727 - tri 1276 196 368 847 - tri 1277 371 349 848 - tri 1278 851 850 849 - tri 1279 849 850 546 - tri 1280 853 852 850 - tri 1281 851 853 850 - tri 1282 612 849 546 - tri 1283 854 849 612 - tri 1284 854 612 613 - tri 1285 854 613 855 - tri 1286 546 850 545 - tri 1287 850 852 545 - tri 1288 852 856 545 - tri 1289 852 857 856 - tri 1290 855 613 858 - tri 1291 855 858 859 - tri 1292 544 545 856 - tri 1293 544 856 860 - tri 1294 613 544 858 - tri 1295 858 544 860 - tri 1296 853 861 852 - tri 1297 861 857 852 - tri 1298 862 855 859 - tri 1299 863 861 853 - tri 1300 864 854 855 - tri 1301 864 855 862 - tri 1302 862 859 865 - tri 1303 866 862 865 - tri 1304 543 542 867 - tri 1305 543 867 868 - tri 1306 859 858 869 - tri 1307 865 859 869 - tri 1308 863 870 861 - tri 1309 870 871 861 - tri 1310 857 872 856 - tri 1311 857 873 872 - tri 1312 874 547 548 - tri 1313 874 875 547 - tri 1314 861 873 857 - tri 1315 861 871 873 - tri 1316 858 860 869 - tri 1317 869 860 876 - tri 1318 615 877 548 - tri 1319 874 548 877 - tri 1320 860 856 872 - tri 1321 860 872 876 - tri 1322 880 879 878 - tri 1323 882 881 878 - tri 1324 883 879 880 - tri 1325 884 881 882 - tri 1326 886 885 409 - tri 1327 888 882 887 - tri 1328 884 882 888 - tri 1329 889 886 409 - tri 1330 892 891 890 - tri 1331 418 890 417 - tri 1332 890 891 893 - tri 1333 418 892 890 - tri 1334 896 895 894 - tri 1335 896 897 895 - tri 1336 898 897 896 - tri 1337 898 899 897 - tri 1338 900 899 898 - tri 1339 819 892 418 - tri 1340 819 418 346 - tri 1341 901 427 428 - tri 1342 432 430 902 - tri 1343 903 432 902 - tri 1344 905 902 904 - tri 1345 903 902 905 - tri 1346 436 432 903 - tri 1347 906 436 903 - tri 1348 906 903 905 - tri 1349 908 901 907 - tri 1350 901 428 907 - tri 1351 430 440 909 - tri 1352 902 430 909 - tri 1353 911 910 900 - tri 1354 908 907 910 - tri 1355 914 913 912 - tri 1356 889 409 447 - tri 1357 915 896 894 - tri 1358 915 889 447 - tri 1359 912 916 899 - tri 1360 918 917 451 - tri 1361 453 918 451 - tri 1362 890 893 417 - tri 1363 417 893 453 - tri 1364 895 920 919 - tri 1365 897 920 895 - tri 1366 899 916 897 - tri 1367 916 920 897 - tri 1368 910 914 912 - tri 1369 910 912 900 - tri 1370 900 912 899 - tri 1371 909 881 884 - tri 1372 909 456 881 - tri 1373 909 440 456 - tri 1374 882 878 887 - tri 1375 879 887 878 - tri 1376 921 901 908 - tri 1377 921 458 901 - tri 1378 458 427 901 - tri 1379 799 458 921 - tri 1380 799 313 458 - tri 1381 907 906 914 - tri 1382 910 907 914 - tri 1383 428 906 907 - tri 1384 428 436 906 - tri 1385 906 905 913 - tri 1386 914 906 913 - tri 1387 902 909 884 - tri 1388 913 905 904 - tri 1389 922 910 911 - tri 1390 922 908 910 - tri 1391 921 908 922 - tri 1392 826 921 922 - tri 1393 799 921 826 - tri 1394 819 820 892 - tri 1395 820 828 892 - tri 1396 886 883 880 - tri 1397 886 880 885 - tri 1398 919 883 886 - tri 1399 894 895 919 - tri 1400 894 919 886 - tri 1401 894 886 889 - tri 1402 912 923 916 - tri 1403 893 918 453 - tri 1404 924 896 915 - tri 1405 925 911 900 - tri 1406 924 915 917 - tri 1407 829 826 922 - tri 1408 829 922 911 - tri 1409 828 829 925 - tri 1410 829 911 925 - tri 1411 926 898 924 - tri 1412 898 896 924 - tri 1413 925 900 926 - tri 1414 926 900 898 - tri 1415 891 927 893 - tri 1416 927 918 893 - tri 1417 892 927 891 - tri 1418 918 926 924 - tri 1419 927 926 918 - tri 1420 918 924 917 - tri 1421 925 926 927 - tri 1422 828 925 927 - tri 1423 828 927 892 - tri 1424 912 913 923 - tri 1425 465 915 447 - tri 1426 917 915 465 - tri 1427 451 917 466 - tri 1428 466 917 465 - tri 1429 870 928 871 - tri 1430 904 930 929 - tri 1431 869 876 931 - tri 1432 931 876 932 - tri 1433 876 872 932 - tri 1434 932 872 933 - tri 1435 871 928 873 - tri 1436 928 934 873 - tri 1437 873 933 872 - tri 1438 873 934 933 - tri 1439 933 936 935 - tri 1440 932 933 935 - tri 1441 932 935 937 - tri 1442 931 932 937 - tri 1443 919 938 883 - tri 1444 920 938 919 - tri 1445 934 936 933 - tri 1446 939 888 887 - tri 1447 940 884 888 - tri 1448 902 884 940 - tri 1449 930 940 939 - tri 1450 940 888 939 - tri 1451 865 869 931 - tri 1452 941 938 920 - tri 1453 916 942 941 - tri 1454 916 941 920 - tri 1455 923 943 942 - tri 1456 923 942 916 - tri 1457 923 913 944 - tri 1458 923 944 943 - tri 1459 915 894 889 - tri 1460 946 945 485 - tri 1461 487 946 485 - tri 1462 490 488 947 - tri 1463 948 488 491 - tri 1464 948 947 488 - tri 1465 409 885 493 - tri 1466 904 940 930 - tri 1467 940 904 902 - tri 1468 913 929 944 - tri 1469 913 904 929 - tri 1470 491 945 948 - tri 1471 945 491 485 - - numweights 1953 - weight 0 25 1 ( -1.8056508303 5.4791040421 2.8306708336 ) - weight 1 25 1 ( -2.1407258511 5.1148152351 -1.6056373119 ) - weight 2 25 0.8400517106 ( 1.1206485033 11.2555532455 -1.1009367704 ) - weight 3 26 0.1599482894 ( 1.565729022 -0.1055700853 -0.9821394086 ) - weight 4 26 1 ( 0.1229709238 6.5924744606 2.1694471836 ) - weight 5 25 0.7382956743 ( 2.0096392632 10.9467067719 1.3684126139 ) - weight 6 26 0.2617043257 ( 1.5756726265 -0.3240064681 1.6514064074 ) - weight 7 25 0.1995867491 ( 2.4580051899 13.2328071594 2.2900633812 ) - weight 8 26 0.8004132509 ( 0.9086604714 1.9027057886 2.5860574245 ) - weight 9 25 0.759510994 ( 0.9906459451 11.3294792175 2.8936440945 ) - weight 10 26 0.2404890209 ( 0.0193436053 -0.4077233374 2.6916108131 ) - weight 11 25 1 ( 2.5736057758 6.8328204155 1.0239388943 ) - weight 12 25 1 ( 2.5829236507 9.7109622955 -0.2923270166 ) - weight 13 25 1 ( 1.4948987961 6.1742253304 -1.8952881098 ) - weight 14 25 1 ( -0.1769572049 8.9651355743 -1.3753398657 ) - weight 15 25 1 ( -3.4306297302 5.8840856552 0.0850157365 ) - weight 16 25 1 ( -0.6309838295 8.9484119415 2.4368624687 ) - weight 17 25 0.1505377889 ( 2.7883012295 13.9639072418 0.9956662655 ) - weight 18 26 0.8494622111 ( 1.4198551178 2.8052017689 1.4710466862 ) - weight 19 26 1 ( 0.8895800114 5.7060408592 0.5007445216 ) - weight 20 25 1 ( -2.4894173145 7.3974924088 1.344009757 ) - weight 21 25 1 ( -2.1943604946 8.9418077469 -0.3133981228 ) - weight 22 25 1 ( 0.4729765058 7.8725948334 2.5929327011 ) - weight 23 25 0.3000000119 ( -2.2407720089 12.3469381332 1.5324198008 ) - weight 24 26 0.6999999881 ( -2.6676237583 -0.3448579609 0.2204833925 ) - weight 25 27 0.5998643041 ( -1.2453964949 -0.5474277139 -0.651417613 ) - weight 26 26 0.4001356959 ( -1.2637439966 10.495092392 0.1811818033 ) - weight 27 27 0.5170600414 ( -1.6801952124 -0.8574303389 -0.2450627834 ) - weight 28 26 0.4829399288 ( -1.7569094896 10.5036382675 0.6361441612 ) - weight 29 25 0.7760010362 ( 2.4385674 3.5362300873 -1.5406000614 ) - weight 30 19 0.2239989787 ( 9.8887062073 7.3279299736 2.9806351662 ) - weight 31 25 0.7162629962 ( 0.6799666882 3.7905170918 -2.4175429344 ) - weight 32 19 0.2837370336 ( 9.4104957581 6.1214318275 1.4832890034 ) - weight 33 25 1 ( 3.2810928822 4.6542468071 0.1517866254 ) - weight 34 25 0.7619376183 ( -2.1257236004 3.5903303623 -1.7630674839 ) - weight 35 19 0.2380623817 ( 9.321146965 6.1671380997 -1.4029263258 ) - weight 36 25 0.7907838821 ( -3.3504097462 2.4882290363 0.568428278 ) - weight 37 19 0.2092161477 ( 9.6178569794 8.38763237 -3.1725945473 ) - weight 38 32 0.1029800475 ( -1.6879472733 0.8688889146 -1.244576335 ) - weight 39 37 0.3853266835 ( 0.0313141122 -0.4290539026 -0.3827362955 ) - weight 40 38 0.1990568191 ( 0.0204080418 -0.5262781978 1.0566848516 ) - weight 41 36 0.3126364052 ( -0.0304427035 -0.3169409037 -1.8236997128 ) - weight 42 32 0.1125121787 ( -2.2563376427 0.7695412636 -0.0091885794 ) - weight 43 37 0.1705894917 ( 0.7385013103 -1.1567782164 0.5279909372 ) - weight 44 27 0.2955290675 ( -0.8960599303 1.9035881758 -1.8788650036 ) - weight 45 38 0.1114777327 ( 0.7138968706 -1.4101064205 1.8293694258 ) - weight 46 26 0.1089752018 ( 0.7183340192 12.1508588791 -0.8016439676 ) - weight 47 36 0.200916335 ( 0.6767445207 -0.909989059 -0.8200560808 ) - weight 48 32 0.3978355229 ( 1.7001546621 0.1173796952 -0.6270302534 ) - weight 49 34 0.1280509979 ( -0.6060287356 2.0264549255 0.5500969887 ) - weight 50 33 0.4113521576 ( -0.0643918291 0.1200672686 -0.6336499453 ) - weight 51 36 0.0627613515 ( -2.347442627 -2.8077485561 -2.747146368 ) - weight 52 32 0.1056255177 ( 2.9943721294 1.4196317196 -0.7351642251 ) - weight 53 34 0.4471872449 ( -0.0308301412 0.2828935683 0.6582309604 ) - weight 54 33 0.4471872449 ( 1.7709192038 0.0701356232 -0.741783917 ) - weight 55 32 0.0923827365 ( 3.5019783974 1.3372459412 -0.789737761 ) - weight 56 34 0.4538086057 ( 0.4600306153 0.129573375 0.7128045559 ) - weight 57 33 0.4538086057 ( 2.0588212013 -0.3559674919 -0.7963574529 ) - weight 58 27 0.5601757765 ( -2.5280516148 -0.4733045101 -0.6145689487 ) - weight 59 26 0.4398242235 ( -2.0553758144 11.4516782761 0.5133239627 ) - weight 60 30 0.3754678667 ( 1.6814974546 0.0085405316 0.6707378626 ) - weight 61 29 0.203484565 ( 2.7892992496 1.3583472967 0.7735859156 ) - weight 62 36 0.0623502769 ( -0.0773193687 -6.2420291901 -2.0439517498 ) - weight 63 31 0.3586972952 ( -0.0532910116 0.337638557 -0.7043271661 ) - weight 64 30 0.3506007493 ( 0.2788742185 0.6778973937 0.7430955768 ) - weight 65 29 0.3517852724 ( 1.3122479916 0.8698718548 0.7552173138 ) - weight 66 36 0.0872321427 ( 0.2149843872 -5.0622630119 -1.072696805 ) - weight 67 31 0.2103818804 ( -1.0974594355 1.4887697697 -0.7766849399 ) - weight 68 32 0.3978355229 ( 2.1560444832 -0.5976842642 -0.554805994 ) - weight 69 34 0.1280509979 ( 0.1215179712 2.4621472359 0.4778727591 ) - weight 70 33 0.4113521576 ( -0.2726505101 -0.7019913793 -0.5614256859 ) - weight 71 36 0.0627613515 ( -3.1074645519 -3.0610628128 -2.4598016739 ) - weight 72 32 0.1056255177 ( 3.0187864304 1.4621039629 -0.0587253198 ) - weight 73 34 0.4471872449 ( -0.0279876459 0.2339869142 -0.0182079189 ) - weight 74 33 0.4471872449 ( 1.8185800314 0.0814661905 -0.0653450117 ) - weight 75 32 0.1056255177 ( 3.5327699184 1.3514924049 -0.0869096518 ) - weight 76 34 0.4471872449 ( 0.481200248 0.1030604839 0.009976414 ) - weight 77 33 0.4471872449 ( 2.0902988911 -0.3686259091 -0.0935293511 ) - weight 78 37 0.2149324864 ( 0.1026711091 0.8578207493 -0.068369247 ) - weight 79 27 0.3749307394 ( 1.0994107723 2.8029990196 -2.0452713966 ) - weight 80 38 0.1144503877 ( 0.2236491591 0.7050786018 1.5065940619 ) - weight 81 26 0.0842022523 ( 2.7004389763 11.3541316986 -1.3066394329 ) - weight 82 36 0.2114840895 ( 0.0409142897 1.0012723207 -1.6926008463 ) - weight 83 32 0.0765034929 ( -1.3376681805 1.7226612568 -1.9133930206 ) - weight 84 37 0.3910259008 ( 0.2023862153 -0.0767344236 -1.4530371428 ) - weight 85 38 0.3910259008 ( 0.1575242132 -0.0663405284 0.0229560882 ) - weight 86 36 0.1414447427 ( 0.1406294107 -0.1179414243 -2.9327859879 ) - weight 87 32 0.0799935088 ( -1.6031005383 1.679900527 -2.7306966782 ) - weight 88 37 0.380770117 ( 0.0337634385 0.7547641397 -1.5960217714 ) - weight 89 38 0.380770117 ( 0.0546275042 0.7870500684 -0.0145250624 ) - weight 90 36 0.1584662348 ( -0.0279933792 0.6853483915 -3.190778017 ) - weight 91 32 0.1242041737 ( -0.4470231235 2.0412135124 -2.1248395443 ) - weight 92 37 0.3546818793 ( -0.167610243 -0.389012754 -2.2926909924 ) - weight 93 38 0.3546818793 ( -0.288149327 -0.2475087792 -0.8184634447 ) - weight 94 36 0.1664320678 ( -0.2293670624 -0.5447015762 -3.7204482555 ) - weight 95 32 0.0842471495 ( -1.0194188356 1.0061918497 -2.8942096233 ) - weight 96 37 0.3830957711 ( -0.85637784 0.5915852785 -1.5477991104 ) - weight 97 38 0.3830957711 ( -0.8419481516 0.691778779 0.0770157427 ) - weight 98 36 0.1495613307 ( -0.9181346297 0.530528307 -3.1201841831 ) - weight 99 32 0.0870144144 ( -0.757525146 0.9543811679 -2.0768826008 ) - weight 100 37 0.3888939917 ( -0.754109323 -0.2358172238 -1.3374601603 ) - weight 101 38 0.3876707852 ( -0.8006359935 -0.1600650996 0.1863384843 ) - weight 102 36 0.1364208311 ( -0.8158661127 -0.2592757344 -2.7960746288 ) - weight 103 32 0.1242041737 ( -0.5737019777 2.3710000515 -2.6425914764 ) - weight 104 37 0.3546818793 ( -0.0405614264 0.1069679633 -2.6542646885 ) - weight 105 38 0.3546818793 ( -0.1397254765 0.2754153907 -1.1305444241 ) - weight 106 36 0.1664320678 ( -0.1023182422 -0.1042289585 -4.147901535 ) - weight 107 32 0.1242041737 ( -0.1620617658 1.9436644316 -2.8386130333 ) - weight 108 37 0.3546818793 ( -0.6627684236 0.0585830919 -2.6859691143 ) - weight 109 38 0.3546818793 ( -0.7645530701 0.2814719677 -1.124094367 ) - weight 110 36 0.1664320678 ( -0.7245252132 -0.1565761119 -4.1725196838 ) - weight 111 27 0.7850186229 ( -0.1419442296 1.1249120235 -1.55841434 ) - weight 112 26 0.1623037457 ( 0.6570063233 11.0233058929 -0.7508473992 ) - weight 113 36 0.0526776575 ( 0.9681619406 -0.0904587433 -0.0981407911 ) - weight 114 27 0.5909968019 ( 0.7209427357 1.6923491955 -0.0644334108 ) - weight 115 26 0.3177656233 ( 1.7483013868 10.4134740829 0.5666188598 ) - weight 116 36 0.0912375227 ( -0.5266865492 0.7334305048 0.5224815011 ) - weight 117 27 0.3651000857 ( -4.3505458832 1.7892889977 -0.7689010501 ) - weight 118 30 0.1751504093 ( -1.2204219103 0.7259185314 1.0662477016 ) - weight 119 29 0.2886814177 ( 0.1839808971 -0.1457013041 0.9793751836 ) - weight 120 36 0.0766451731 ( 0.1734440774 -4.3336482048 0.2771242559 ) - weight 121 31 0.0944228768 ( -1.5742748976 2.911036253 -1.0998369455 ) - weight 122 30 0.3702871203 ( -0.1945728064 -0.1505599171 0.9376416206 ) - weight 123 29 0.3747090697 ( 1.5354684591 -0.0642189458 0.9164276123 ) - weight 124 36 0.0803197324 ( -0.3814571202 -5.3850541115 -0.3738368154 ) - weight 125 31 0.1746840924 ( -0.4399852753 2.1803052425 -0.9712309241 ) - weight 126 30 0.3585439324 ( 0.8821802139 -0.1514656097 0.9701343775 ) - weight 127 29 0.298817724 ( 2.3103916645 0.6769422889 1.0195188522 ) - weight 128 36 0.0749930069 ( -0.1612966955 -6.0340003967 -1.2050119638 ) - weight 129 31 0.267645359 ( -0.1297150403 1.1492230892 -1.0037237406 ) - weight 130 32 0.4341444671 ( 0.5448057055 -0.9034036994 0.9230071902 ) - weight 131 27 0.1862728596 ( -3.0208928585 3.7795760632 -0.0134179462 ) - weight 132 34 0.0880223438 ( -1.182896018 3.4561591148 -0.999940455 ) - weight 133 33 0.1982116103 ( -1.5995616913 0.2617833614 0.9163874984 ) - weight 134 36 0.0933486745 ( -1.848315239 -3.1703491211 -0.6498054862 ) - weight 135 27 0.3128781319 ( -4.2649078369 1.7919490337 -1.8084269762 ) - weight 136 30 0.1958076358 ( -0.5381661654 1.5147918463 1.0535657406 ) - weight 137 29 0.2703956962 ( 0.1302563846 0.8954138756 1.0132530928 ) - weight 138 36 0.0939889401 ( 0.8920051455 -4.2568044662 -0.4750193357 ) - weight 139 31 0.1269296557 ( -2.1338338852 2.0308725834 -1.0871549845 ) - weight 140 32 0.5142737031 ( 0.3010198474 0.153626129 -0.7386184335 ) - weight 141 34 0.1192490458 ( -1.8736628294 2.6197471619 0.6616851687 ) - weight 142 33 0.2179925293 ( -0.996914804 1.1637592316 -0.7452381253 ) - weight 143 36 0.148484692 ( -1.5374094248 -1.857555747 -2.1050219536 ) - weight 144 27 0.8857021332 ( 0.7182796001 1.3341218233 -1.110707283 ) - weight 145 26 0.1142978817 ( 1.4116690159 10.4360809326 -0.4865622222 ) - weight 146 32 0.4396588802 ( 0.481274575 -0.8680806756 0.2656233013 ) - weight 147 27 0.185038507 ( -2.4471759796 4.0886626244 -0.1263421029 ) - weight 148 34 0.0843911767 ( -1.2555168867 3.4529771805 -0.3425565362 ) - weight 149 33 0.2022229284 ( -1.6173814535 0.3322558999 0.2590036094 ) - weight 150 36 0.0886885747 ( -2.0217988491 -2.6256127357 -0.9823761582 ) - weight 151 32 0.3978355229 ( 1.7758851051 0.1396241039 0.1118338779 ) - weight 152 34 0.1280509979 ( -0.5482412577 1.9726911783 -0.1887671202 ) - weight 153 33 0.4113521576 ( 0.003709574 0.080165796 0.105214186 ) - weight 154 36 0.0627613515 ( -2.1101696491 -3.4300932884 -2.4176943302 ) - weight 155 32 0.4187633991 ( 2.1842894554 -0.5757289529 0.2121647745 ) - weight 156 34 0.1101265997 ( 0.1369622946 2.4298784733 -0.2890979946 ) - weight 157 33 0.4189509749 ( -0.2373045981 -0.7075120211 0.2055450678 ) - weight 158 36 0.0521590374 ( -2.8323271275 -3.6756985188 -2.0909569263 ) - weight 159 27 0.7043999434 ( -1.4576021433 0.121787563 -1.3555189371 ) - weight 160 26 0.2956000865 ( -0.9500204921 11.25715065 -0.3751307726 ) - weight 161 32 0.4197631776 ( 2.0590627193 -0.5200781226 1.4242259264 ) - weight 162 34 0.1101526022 ( 0.0000681965 2.4361059666 -1.5011591911 ) - weight 163 33 0.4197631776 ( -0.2826057076 -0.5781807899 1.4176062346 ) - weight 164 36 0.0503210165 ( -2.2823245525 -4.5441422462 -1.4343189001 ) - weight 165 30 0.390830338 ( 1.5623840094 -0.9325962663 -0.9844942689 ) - weight 166 29 0.1519301385 ( 3.4305901527 0.6744955182 -0.8879833221 ) - weight 167 36 0.0664092004 ( -1.8456630707 -5.8209867477 -2.6230919361 ) - weight 168 31 0.390830338 ( 0.8139275908 0.7221621871 0.9509049058 ) - weight 169 32 0.4396588802 ( 0.6511855125 -0.7556808591 -0.5772006512 ) - weight 170 27 0.185038507 ( -1.8582292795 4.6919231415 -0.3290100992 ) - weight 171 34 0.0843911767 ( -1.1538107395 3.2764573097 0.5002673864 ) - weight 172 33 0.2022229284 ( -1.4190809727 0.2855617106 -0.583820343 ) - weight 173 36 0.0886885747 ( -2.3436727524 -2.0911858082 -1.5845726728 ) - weight 174 32 0.1056255177 ( 3.0539588928 0.2807662785 -0.2869470716 ) - weight 175 34 0.4471872449 ( 0.5317820311 1.2748777866 0.2100138217 ) - weight 176 33 0.4471872449 ( 0.9824360013 -0.7537936568 -0.2935667634 ) - weight 177 30 0.390830338 ( 2.5653033257 -0.2900918424 -0.4935792685 ) - weight 178 29 0.1519301385 ( 3.6860907078 1.8076354265 -0.3308748901 ) - weight 179 36 0.0664092004 ( -0.8648519516 -6.2962508202 -3.3099615574 ) - weight 180 31 0.390830338 ( 0.4867066741 -0.4230825305 0.4599899352 ) - weight 181 32 0.4031164646 ( 2.0314958096 0.5127716064 0.9962081909 ) - weight 182 34 0.1120185927 ( -0.4864929318 1.5246254206 -1.0731414557 ) - weight 183 33 0.4346669614 ( 0.4506220222 0.1497722864 0.9895884991 ) - weight 184 36 0.0501979589 ( -1.6725181341 -4.3187832832 -2.3443119526 ) - weight 185 30 0.390830338 ( 2.4530537128 -0.0026366401 -1.3608983755 ) - weight 186 29 0.1519301385 ( 3.4460763931 1.9784474373 -1.2030498981 ) - weight 187 36 0.0664092004 ( -1.2076601982 -5.5819978714 -3.7787883282 ) - weight 188 31 0.390830338 ( 0.1791198552 -0.3981665969 1.3273090124 ) - weight 189 32 0.460752517 ( 0.8525359035 0.2679014802 0.4666924179 ) - weight 190 34 0.1419114918 ( -1.4314773083 2.2708907127 -0.5436256528 ) - weight 191 33 0.2896903455 ( -0.5357097983 0.840465486 0.460072726 ) - weight 192 36 0.1076456532 ( -1.3459329605 -3.147633791 -1.8422706127 ) - weight 193 32 0.0785421878 ( -2.1443417072 0.0130352639 -2.4198019505 ) - weight 194 37 0.2892561853 ( -0.7420785427 0.8255322576 0.0043214909 ) - weight 195 27 0.1920417696 ( 1.1190673113 3.3551902771 -1.401356101 ) - weight 196 38 0.1539168805 ( -0.6147871017 0.7328479886 1.6338025331 ) - weight 197 36 0.2862429619 ( -0.8038353324 0.9794791341 -1.6161054373 ) - weight 198 32 0.0881515816 ( -1.7118420601 -0.3871145248 -1.6777454615 ) - weight 199 37 0.2584609687 ( -1.0194656849 -0.0229599047 0.3220335841 ) - weight 200 27 0.2784707844 ( 0.3135505021 3.3193113804 -0.9036825299 ) - weight 201 38 0.1109498441 ( -0.9464027286 -0.1217519939 1.873622179 ) - weight 202 36 0.2639667988 ( -1.081222415 0.1838261485 -1.1827275753 ) - weight 203 27 0.4359621406 ( -1.6378709078 -0.8989017606 1.1337908506 ) - weight 204 26 0.5640378594 ( -1.6709849834 10.1096086502 1.9560329914 ) - weight 205 25 1 ( 2.256264925 4.7436695099 -1.4625415802 ) - weight 206 25 1 ( -0.4726947546 4.8994936943 -1.976949811 ) - weight 207 25 1 ( 2.8245692253 6.0138640404 1.1555082798 ) - weight 208 25 1 ( 0.5499517918 5.937473774 2.8722803593 ) - weight 209 25 1 ( -2.4441351891 3.7350418568 2.3613767624 ) - weight 210 25 0.9291076064 ( -3.0744674206 4.1992955208 -1.0784034729 ) - weight 211 19 0.0708923936 ( 10.1063575745 6.157535553 -2.4626765251 ) - weight 212 27 0.4500148296 ( -2.0285029411 -0.3497294486 0.7085148692 ) - weight 213 26 0.5499851704 ( -1.5470631123 10.852514267 1.6956906319 ) - weight 214 27 0.4748129249 ( 0.2169521153 -0.0621114336 -0.6607546806 ) - weight 215 26 0.5251870751 ( 0.0663109869 9.7698602676 -0.1000199988 ) - weight 216 27 0.4948313832 ( 0.599773109 0.814243257 0.6990152597 ) - weight 217 26 0.5051686168 ( 1.0616971254 9.738407135 1.2310475111 ) - weight 218 27 0.4533844888 ( -0.5691189766 1.0919229984 1.1000186205 ) - weight 219 26 0.5466154814 ( 0.5208338499 10.6581325531 1.9135358334 ) - weight 220 25 0.3000000119 ( -2.5536158085 12.2834062576 0.0035617675 ) - weight 221 26 0.6999999881 ( -2.3830273151 -0.3761710227 -1.3148794174 ) - weight 222 25 0.1473560929 ( -2.0159373283 13.2824554443 1.5826474428 ) - weight 223 26 0.8526439071 ( -2.7889771461 0.6064342856 0.3131258786 ) - weight 224 25 0.2184428126 ( -2.3226335049 13.2859992981 -0.1150157228 ) - weight 225 26 0.7815572023 ( -2.4610598087 0.6545042992 -1.3798877001 ) - weight 226 26 1 ( -0.9120371938 3.0003159046 2.8847696781 ) - weight 227 27 0.200000003 ( 4.633992672 -4.6509852409 -1.088567853 ) - weight 228 26 0.8000000119 ( -0.4623176157 3.7098076344 -2.0358281136 ) - weight 229 25 0.5985938907 ( -0.4998500049 12.2159948349 -1.5458959341 ) - weight 230 26 0.4014061093 ( -0.0104790814 0.3321373463 -2.0167565346 ) - weight 231 25 0.3085092306 ( 1.5365855694 13.4721221924 -1.1459088326 ) - weight 232 26 0.6914907694 ( 1.2334082127 2.125385046 -0.9575487971 ) - weight 233 26 1 ( -2.7267520428 4.6500201225 -0.5391392112 ) - weight 234 26 1 ( -2.646945715 3.3630707264 1.3605872393 ) - weight 235 27 0.200000003 ( 3.4359431267 -6.0962872505 -0.8906679749 ) - weight 236 26 0.8000000119 ( -2.3219053745 3.5710785389 -1.742448926 ) - weight 237 25 0.3810751438 ( -0.4331482947 12.0137214661 3.0093083382 ) - weight 238 26 0.6189248562 ( -1.4927611351 -0.2161685377 2.2607953548 ) - weight 239 27 0.3592396379 ( -0.0228283014 0.1854875088 1.5180102587 ) - weight 240 26 0.6407603621 ( 0.2327937037 9.5716438293 2.0905985832 ) - weight 241 4 1 ( 1.6858422756 14.6930027008 -2.3183946609 ) - weight 242 5 0.0596043728 ( -2.0416178703 -3.5781881809 -2.5362832546 ) - weight 243 4 0.9403956532 ( 0.4291037023 17.057592392 -3.7452423573 ) - weight 244 5 0.0954229087 ( 2.6704740524 -4.3784747124 2.0805425644 ) - weight 245 4 0.9045770764 ( -3.1232097149 16.2238636017 1.8086137772 ) - weight 246 5 0.0673919022 ( -3.8999459743 -3.8213925362 3.1131160259 ) - weight 247 4 0.9326081276 ( -5.256688118 15.4522314072 -4.468313694 ) - weight 248 4 1 ( 1.6987347603 15.9099941254 0.0430456437 ) - weight 249 5 0.0587438978 ( -4.3927507401 -4.2240509987 0.4301279485 ) - weight 250 4 0.9412561059 ( -2.6591598988 15.4792346954 -5.3932642937 ) - weight 251 4 1 ( -0.7749836445 14.7089853287 -4.8435926437 ) - weight 252 5 0.1004734635 ( -0.6051927805 -3.9020266533 5.1836018562 ) - weight 253 4 0.8995265365 ( -6.7259297371 15.5486412048 -0.8654196858 ) - weight 254 4 1 ( -1.508046627 15.4348602295 2.8382749557 ) - weight 255 5 1 ( 2.5076770782 2.6049315929 2.8370354176 ) - weight 256 6 0.0565896407 ( 6.0073471069 -7.1478953362 15.0102386475 ) - weight 257 5 0.6264543533 ( 3.1373734474 1.0058882236 -0.6527998447 ) - weight 258 4 0.3169560134 ( -1.562268734 22.0230865479 1.0256620646 ) - weight 259 4 1 ( -0.1165639684 16.1319789886 1.8115611076 ) - weight 260 4 1 ( 1.2975665331 15.0853481293 2.3624184132 ) - weight 261 4 1 ( 2.3888902664 13.2969789505 1.6866415739 ) - weight 262 4 1 ( -6.9526233673 11.5397834778 -3.3963956833 ) - weight 263 4 1 ( -3.1578683853 13.8206787109 -6.0674667358 ) - weight 264 4 1 ( 0.0541162863 13.6302900314 -5.5940008163 ) - weight 265 4 1 ( -3.6083216667 13.618844986 3.9820439816 ) - weight 266 3 0.5315479636 ( 3.7084290981 -2.7477302551 4.6042766571 ) - weight 267 4 0.4684520066 ( 4.0785565376 1.0400314331 0.0455021448 ) - weight 268 4 1 ( -5.6320075989 8.6354112625 0.2477746755 ) - weight 269 3 0.1597939581 ( 3.6681900024 -8.4924659729 4.7243947983 ) - weight 270 4 0.840206027 ( 4.1796078682 6.6883792877 -1.0052080154 ) - weight 271 3 0.1570782363 ( 11.3637037277 -9.3978271484 -0.9165611267 ) - weight 272 4 0.8429217935 ( -3.829202652 8.4974508286 3.9392039776 ) - weight 273 3 0.2233601809 ( 6.7271490097 -7.6255226135 3.8477036953 ) - weight 274 4 0.7766398191 ( 2.2782444954 6.2961831093 1.6609517336 ) - weight 275 5 0.8861713409 ( -4.0107345581 3.001529932 1.5396687984 ) - weight 276 4 0.1138286591 ( -5.210911274 22.3287391663 -5.7918839455 ) - weight 277 5 0.899436295 ( -2.3929839134 2.6345231533 4.5116157532 ) - weight 278 4 0.1005637199 ( -7.7486562729 21.6945323944 -3.6142907143 ) - weight 279 3 0.3695607185 ( 7.080242157 -6.6127700806 -4.0962405205 ) - weight 280 4 0.6304392815 ( -5.2693328857 4.8103351593 -0.5935825109 ) - weight 281 3 0.3345544934 ( 4.455555439 -8.2828369141 -6.0770320892 ) - weight 282 4 0.6654455066 ( -6.1971096992 5.8678984642 -4.0027508736 ) - weight 283 4 1 ( -6.4897594452 13.6727561951 -0.2730446756 ) - weight 284 4 1 ( -7.1494312286 14.5907363892 -1.6771994829 ) - weight 285 3 0.7712626457 ( 0.8684953451 -6.4339332581 4.6402726173 ) - weight 286 4 0.2287374139 ( 5.1036987305 4.1824922562 -3.2299575806 ) - weight 287 3 0.8672531247 ( 6.8744492531 2.0751686096 -1.6135793924 ) - weight 288 17 0.0509745032 ( 6.8818559647 1.8839337826 -1.7680704594 ) - weight 289 4 0.0817723572 ( -2.8366611004 -3.5926074982 1.6777378321 ) - weight 290 3 0.5833309889 ( 3.2489125729 1.4852218628 6.7376856804 ) - weight 291 18 0.0901030451 ( 3.3306694031 -0.9419174194 0.1858739853 ) - weight 292 17 0.2715701461 ( 3.7417104244 -0.7475819588 6.3836650848 ) - weight 293 4 0.0549957789 ( 6.2549619675 -3.051207304 1.1434544325 ) - weight 294 5 0.2459147424 ( 3.6929144859 -1.983733058 -0.5225681067 ) - weight 295 4 0.7540852427 ( -0.964296937 19.2005710602 1.9948165417 ) - weight 296 5 0.1811946183 ( 2.9428470135 -2.344203949 -2.5148921013 ) - weight 297 4 0.8188053966 ( 0.9181202054 19.0957832336 0.942475915 ) - weight 298 7 0.0643709078 ( 4.649977684 2.3647472858 19.786272049 ) - weight 299 6 0.0719461441 ( 8.8068571091 -6.0503139496 14.7155065536 ) - weight 300 5 0.3476630747 ( 2.5549285412 0.750059545 -3.6064612865 ) - weight 301 4 0.5160198808 ( 1.2511520386 22.2273979187 -0.0568013936 ) - weight 302 7 0.0719838515 ( 2.3048570156 2.596228838 20.2884635925 ) - weight 303 6 0.0802049935 ( 6.7325658798 -6.0332899094 15.9412298203 ) - weight 304 5 0.364195466 ( 4.1868395805 0.643591404 -1.8370264769 ) - weight 305 4 0.4836156964 ( -0.1799799502 22.0720100403 1.875317812 ) - weight 306 5 0.2345089465 ( 1.3585892916 -1.8614307642 -3.3048593998 ) - weight 307 4 0.7654910684 ( 1.3315845728 19.4406871796 -0.8116847873 ) - weight 308 3 0.6725519896 ( 6.3025302887 -1.5085716248 3.5197236538 ) - weight 309 4 0.32744807 ( 2.1494920254 0.1884246171 2.2803637981 ) - weight 310 3 0.7070791721 ( 6.0205597878 1.2947502136 3.6651484966 ) - weight 311 17 0.1655518413 ( 6.3324050903 -0.1550431699 3.2062458992 ) - weight 312 4 0.127368927 ( 2.397974968 -2.6050658226 2.5868544579 ) - weight 313 3 0.6082166433 ( 2.6010766029 0.9662094116 5.8599977493 ) - weight 314 18 0.0689166188 ( 2.6828334332 -1.4609298706 -0.6918139458 ) - weight 315 17 0.203364253 ( 3.0445582867 -1.0491472483 5.4442830086 ) - weight 316 4 0.1195024401 ( 5.6620197296 -2.7121343613 0.1470354795 ) - weight 317 3 1 ( 3.633108139 1.987323761 -10.4137458801 ) - weight 318 3 1 ( 3.2783942223 3.7895317078 -8.8841781616 ) - weight 319 7 0.3454541266 ( -0.37828511 4.6323928833 3.0278494358 ) - weight 320 8 0.3419183493 ( -0.3690134585 -0.4365150034 3.0293495655 ) - weight 321 6 0.1897278875 ( 1.3624457121 6.7487959862 5.1220760345 ) - weight 322 5 0.1228995919 ( 7.1839489937 17.742893219 -4.6486430168 ) - weight 323 7 0.0952559859 ( -1.1915769577 -5.2674460411 4.8168168068 ) - weight 324 6 0.2685072124 ( -1.50025177 -1.9196830988 0.8173012137 ) - weight 325 5 0.6362367868 ( -0.0953703076 17.3090801239 2.3293201923 ) - weight 326 7 0.2313687354 ( -2.4571859837 -6.428853035 -1.1581681967 ) - weight 327 8 0.1366661787 ( -2.2100565434 -11.554186821 -1.1183812618 ) - weight 328 6 0.2826185524 ( -4.1380615234 1.0991520882 -3.9345054626 ) - weight 329 5 0.2862697542 ( -0.322358489 23.5082569122 2.7413277626 ) - weight 330 4 0.0630767867 ( -10.1708164215 42.5745124817 -4.7517256737 ) - weight 331 7 0.2899672389 ( -2.5934128761 -2.7834627628 -1.0891140699 ) - weight 332 8 0.1375834346 ( -2.4243872166 -7.9123363495 -1.0619370937 ) - weight 333 6 0.3056590259 ( -3.357789278 3.8555676937 -1.6749601364 ) - weight 334 5 0.213157177 ( 2.6368575096 23.0331993103 0.6605688334 ) - weight 335 4 0.053633038 ( -7.6035881042 43.0065345764 -2.1953816414 ) - weight 336 7 0.3076890707 ( -1.9244483709 -2.5423638821 -0.4398162365 ) - weight 337 8 0.1259461194 ( -1.7607917786 -7.6547112465 -0.413477242 ) - weight 338 6 0.3496141732 ( -2.5380301476 3.5790083408 -1.2521841526 ) - weight 339 5 0.2167506218 ( 2.4253697395 22.2526340485 0.1378610879 ) - weight 340 7 0.4093997777 ( -1.360886693 6.1779055595 -0.208042413 ) - weight 341 8 0.4093997777 ( -1.3842735291 1.0763828754 -0.211868763 ) - weight 342 6 0.1142960414 ( 0.1862641275 10.0690994263 3.9315748215 ) - weight 343 5 0.0669044331 ( 8.9583511353 20.8949928284 -5.5093841553 ) - weight 344 7 0.1103651822 ( -0.693110168 -6.640879631 4.895216465 ) - weight 345 6 0.2735842466 ( -1.3493474722 -3.0556550026 -0.0924966708 ) - weight 346 5 0.6160505414 ( -1.4836412668 17.3075084686 2.7915298939 ) - weight 347 5 1 ( 3.6818425655 6.787894249 0.2966994941 ) - weight 348 7 0.0765797049 ( -1.3765590191 0.1397345662 7.0997986794 ) - weight 349 6 0.0956912264 ( 0.0929998383 0.7731610537 5.7866029739 ) - weight 350 5 0.8277291059 ( 4.3161196709 14.4703178406 -0.3096219003 ) - weight 351 5 1 ( 3.0984635353 12.9437532425 -0.8103874922 ) - weight 352 5 1 ( 2.8465774059 6.976213932 3.1593792439 ) - weight 353 5 1 ( 4.5091161728 3.955603838 -1.5454479456 ) - weight 354 5 1 ( -2.41457057 12.7935743332 3.2477605343 ) - weight 355 5 1 ( 0.290643394 11.0979213715 3.5015251637 ) - weight 356 5 1 ( -0.1849416941 14.3153181076 4.351837635 ) - weight 357 5 1 ( -3.267178297 8.6119594574 3.8306789398 ) - weight 358 5 1 ( 0.8601892591 7.6312618256 5.1862511635 ) - weight 359 5 1 ( 2.9706270695 13.1213731766 0.8247174621 ) - weight 360 5 1 ( 2.3148543835 10.4960517883 2.0127387047 ) - weight 361 5 1 ( 2.8854553699 10.0222034454 0.1452220678 ) - weight 362 5 1 ( 2.835568428 6.8752179146 -2.0894274712 ) - weight 363 7 0.3035651743 ( 2.8953797817 4.2157902718 2.692003727 ) - weight 364 8 0.2966812253 ( 2.9128530025 -0.7840178013 2.6949470043 ) - weight 365 6 0.2075200379 ( 4.3053441048 6.4199142456 3.62727952 ) - weight 366 5 0.1410585046 ( 4.8376493454 17.5456752777 -6.9851388931 ) - weight 367 4 0.0511751026 ( 1.2829290628 39.497505188 -0.7360101938 ) - weight 368 7 0.2733933628 ( 2.4691598415 -3.5225453377 -1.6306425333 ) - weight 369 8 0.1384337693 ( 2.6529033184 -8.5446138382 -1.6009058952 ) - weight 370 6 0.2976273298 ( 1.1656864882 3.2885317802 -4.0594468117 ) - weight 371 5 0.2348119617 ( -1.0666902065 22.761089325 -2.9001657963 ) - weight 372 4 0.0557335354 ( -4.6849813461 42.7772331238 -6.4260191917 ) - weight 373 7 0.2278146297 ( 1.4413039684 -6.9950733185 -1.5749655962 ) - weight 374 8 0.1359871626 ( 1.6997041702 -12.0381603241 -1.5332176685 ) - weight 375 6 0.2867776155 ( -0.6539509296 0.6645985842 -5.7688131332 ) - weight 376 5 0.2848953605 ( -3.1720116138 23.2981643677 -0.0023714979 ) - weight 377 4 0.0645252243 ( -7.9211797714 42.3981132507 -8.0075769424 ) - weight 378 7 0.399825573 ( 1.2918527126 6.7775063515 0.035774745 ) - weight 379 8 0.399825573 ( 1.2549874783 1.7335406542 0.0298728757 ) - weight 380 6 0.124025479 ( 2.9007251263 10.1902093887 3.6613395214 ) - weight 381 5 0.0763233975 ( 7.803776741 20.1199893951 -7.8593459129 ) - weight 382 7 0.2138165981 ( -0.5239654779 -7.688990593 0.5854745507 ) - weight 383 6 0.3502906263 ( -2.275806427 -1.1135326624 -3.9746165276 ) - weight 384 5 0.3701814711 ( -2.4785354137 21.6138916016 2.383759737 ) - weight 385 4 0.0657113343 ( -9.7562522888 40.441318512 -6.6604423523 ) - weight 386 7 0.2225397378 ( -0.6149929166 -7.5309691429 -1.2819886208 ) - weight 387 8 0.1344955415 ( -0.3446564972 -12.6169881821 -1.2383886576 ) - weight 388 6 0.2893813252 ( -2.6828210354 0.2080290765 -5.242878437 ) - weight 389 5 0.2891934216 ( -2.3258943558 23.4362869263 1.9639407396 ) - weight 390 4 0.0643899143 ( -9.7162036896 42.3089561462 -6.8365449905 ) - weight 391 7 0.2891643643 ( 2.0049800873 -3.1144583225 -0.8588693738 ) - weight 392 8 0.1298304945 ( 2.1800267696 -8.143901825 -0.8305489421 ) - weight 393 6 0.3379357457 ( 0.9735939503 3.1392762661 -3.1010861397 ) - weight 394 5 0.2430694252 ( -0.4479712546 22.0400104523 -2.6265571117 ) - weight 395 5 1 ( 1.3371957541 12.8582162857 -2.3173294067 ) - weight 396 7 0.0972699225 ( 1.1043465137 0.7429358959 7.1777420044 ) - weight 397 6 0.1169090569 ( 2.6131818295 1.0149048567 5.4473958015 ) - weight 398 5 0.7858210206 ( 3.2675538063 13.887169838 -2.5646755695 ) - weight 399 7 0.0935955346 ( 3.0123860836 -0.627584219 6.4024562836 ) - weight 400 6 0.1265636981 ( 3.9396009445 0.3303875625 3.4745662212 ) - weight 401 5 0.7798407674 ( 1.0021510124 14.4721021652 -3.3683001995 ) - weight 402 5 1 ( -0.8961507678 8.0259666443 -2.5462536812 ) - weight 403 5 1 ( 1.9876238108 3.8447201252 -3.3795337677 ) - weight 404 5 1 ( -3.5848181248 14.3105916977 0.9687321782 ) - weight 405 5 1 ( -4.1435894966 7.9334740639 0.9077156782 ) - weight 406 5 1 ( -0.2799199224 10.3010234833 -1.9260947704 ) - weight 407 5 1 ( -0.5091210008 13.2676448822 -1.7744108438 ) - weight 408 5 1 ( 1.8263561726 9.7308139801 -1.5238622427 ) - weight 409 5 1 ( 1.0101976395 6.5797524452 -2.7370555401 ) - weight 410 5 1 ( -1.8118582964 11.3381376266 2.7125473022 ) - weight 411 5 1 ( -3.6564412117 6.7563052177 -0.9684539437 ) - weight 412 7 0.282959491 ( -0.0087337149 1.701251626 3.1271054745 ) - weight 413 8 0.1922333837 ( 0.0632672906 -3.3587019444 3.1387441158 ) - weight 414 6 0.2532799542 ( 1.0118557215 4.4156169891 3.3412418365 ) - weight 415 5 0.2202683538 ( 4.646985054 17.9279518127 -3.1427953243 ) - weight 416 4 0.051258862 ( -2.5345566273 39.1182174683 -0.2574335337 ) - weight 417 7 0.3828782141 ( 1.3052539825 5.8771119118 1.7943944931 ) - weight 418 8 0.3828782141 ( 1.2875529528 0.8397275805 1.7915966511 ) - weight 419 6 0.1435996592 ( 3.0304994583 8.3751602173 4.4310064316 ) - weight 420 5 0.09064392 ( 7.1118674278 18.5054683685 -6.9547924995 ) - weight 421 7 0.2478968799 ( -2.1448323727 -2.650626421 1.2201017141 ) - weight 422 8 0.110683158 ( -1.9789278507 -7.7619314194 1.2468053102 ) - weight 423 6 0.3652938306 ( -2.4545621872 2.4496533871 -0.0139565021 ) - weight 424 5 0.2761261463 ( 2.5003287792 20.6818618774 0.7232443094 ) - weight 425 7 0.3306698203 ( -1.2980607748 1.9335983992 2.897998333 ) - weight 426 8 0.2349759191 ( -1.2307263613 -3.154835701 2.9088346958 ) - weight 427 6 0.2830759585 ( -0.1999603659 4.8285355568 3.7015736103 ) - weight 428 5 0.1512783021 ( 5.6194968224 18.350730896 -2.3401012421 ) - weight 429 7 0.2864736021 ( 3.1662523746 1.2262210846 2.2421891689 ) - weight 430 8 0.2033683956 ( 3.2477707863 -3.768632412 2.2554762363 ) - weight 431 6 0.2773667574 ( 3.7409727573 4.3999233246 1.4331166744 ) - weight 432 5 0.1797308028 ( 2.3070747852 18.291595459 -5.4841303825 ) - weight 433 4 0.0530604012 ( -0.7163581252 39.5086517334 -3.0198569298 ) - weight 434 6 0.0615476109 ( -1.8385465145 -3.2585310936 3.0993773937 ) - weight 435 5 0.938452363 ( 0.7059574723 15.0088739395 3.4164059162 ) - weight 436 6 0.0809971318 ( 2.3323407173 -3.6210093498 0.7825809717 ) - weight 437 5 0.919002831 ( -2.6856915951 14.9335565567 0.0420496315 ) - weight 438 3 0.0533679426 ( 9.1839742661 -21.6981430054 3.4954879284 ) - weight 439 6 0.0612880252 ( 8.4794311523 -6.8663516045 16.6638240814 ) - weight 440 5 0.2456846684 ( 3.462113142 -1.0202190876 -2.8240311146 ) - weight 441 4 0.6396593451 ( 1.0145184994 20.5228977203 1.2111690044 ) - weight 442 5 1 ( 2.7179527283 3.7053837776 2.4891989231 ) - weight 443 5 1 ( 0.6623873711 3.3035414219 4.1629962921 ) - weight 444 5 1 ( -1.645506382 3.6441397667 4.9050455093 ) - weight 445 5 1 ( -3.8388104439 3.5294132233 2.6372163296 ) - weight 446 5 1 ( -1.5510952473 3.6889302731 -1.6632031202 ) - weight 447 5 1 ( -3.1880047321 3.2676892281 0.3956328928 ) - weight 448 5 0.6365789771 ( 1.7845596075 1.1130880117 -2.5867187977 ) - weight 449 4 0.3634209931 ( 0.0706423968 22.2573566437 -0.6655974388 ) - weight 450 6 0.0577177703 ( 4.1479444504 -9.2337141037 15.2843389511 ) - weight 451 5 0.4858627915 ( 2.7130281925 0.3760530651 2.0502336025 ) - weight 452 4 0.4564194679 ( -4.1011686325 20.8372364044 1.20144701 ) - weight 453 5 0.5414208174 ( -1.4073127508 0.6734797359 -2.0470099449 ) - weight 454 4 0.4585791528 ( -0.8510909081 21.1881732941 -3.6117548943 ) - weight 455 5 0.1075842753 ( 1.9856535196 -3.1848568916 -2.9890902042 ) - weight 456 4 0.8924157023 ( 1.4063936472 18.2079429626 0.0363255218 ) - weight 457 5 0.0955377892 ( 3.6543211937 -3.2376387119 -1.4408408403 ) - weight 458 4 0.9044622183 ( 0.1828734726 18.152015686 1.955748558 ) - weight 459 5 0.1006611288 ( -0.0393475033 -2.8687682152 -3.4951329231 ) - weight 460 4 0.899338901 ( 1.5131883621 18.2636013031 -2.0713076591 ) - weight 461 5 0.1112167835 ( 3.5849909782 -3.0396351814 0.7791119814 ) - weight 462 4 0.8887832165 ( -2.0115132332 17.9177055359 2.2750737667 ) - weight 463 5 0.2970406115 ( -3.6154201031 -2.1194272041 1.9965270758 ) - weight 464 4 0.7029593587 ( -4.4983935356 17.3557529449 -4.6295938492 ) - weight 465 5 0.3277237117 ( -0.263397634 -2.3713662624 3.8945336342 ) - weight 466 4 0.6722762585 ( -5.7558522224 17.3283252716 -0.9799360037 ) - weight 467 5 0.9171078801 ( 0.7893771529 2.2300651073 4.4633631706 ) - weight 468 4 0.082892105 ( -7.1224894524 21.8537063599 -0.4716935754 ) - weight 469 5 1 ( 1.9011212587 3.5586428642 -2.1922030449 ) - weight 470 5 0.9495714903 ( 3.1771814823 3.4319419861 -0.0814554319 ) - weight 471 4 0.0504284948 ( -2.6245291233 24.2707309723 0.8427767754 ) - weight 472 5 0.6455161572 ( 0.3316878378 -0.0628499985 3.9994142056 ) - weight 473 4 0.3544839025 ( -6.2570004463 19.643743515 -0.6934630275 ) - weight 474 5 0.6242326498 ( -2.3410615921 -0.0238933749 3.1565637589 ) - weight 475 4 0.3757673502 ( -5.8666453362 19.383852005 -3.4567189217 ) - weight 476 5 0.5640794039 ( -3.5998430252 -0.0338187926 0.4616221786 ) - weight 477 4 0.4359205365 ( -3.4600813389 19.6627502441 -5.1824083328 ) - weight 478 5 0.2531460226 ( 1.874494195 -2.2195158005 2.9838488102 ) - weight 479 4 0.7468539476 ( -4.5783133507 18.0089244843 0.9103482366 ) - weight 480 5 0.8430315852 ( -2.0136215687 1.9838973284 -1.6399120092 ) - weight 481 4 0.1569683999 ( -1.617202878 22.2770214081 -4.3031411171 ) - weight 482 5 0.2316240966 ( -2.6479346752 -1.9065085649 -1.6584495306 ) - weight 483 4 0.7683759332 ( -0.8681231141 18.4081878662 -4.3977913857 ) - weight 484 5 0.8101177812 ( 2.6703231335 1.5505559444 2.1602129936 ) - weight 485 4 0.1898822337 ( -4.4643139839 21.9459037781 1.0215554237 ) - weight 486 5 0.8353561163 ( 3.2594959736 2.1321310997 -0.4837278724 ) - weight 487 4 0.1646438986 ( -1.9465714693 23.1020812988 1.0237057209 ) - weight 488 5 0.814422965 ( 1.3349963427 2.2406749725 -2.4633917809 ) - weight 489 4 0.1855769753 ( -0.3584519327 23.2489032745 -1.2325896025 ) - weight 490 3 1 ( 3.5605592728 -0.9402542114 -10.0702943802 ) - weight 491 7 0.2127243578 ( -0.7489172816 1.0672720671 5.6971912384 ) - weight 492 6 0.2376018465 ( 0.6474048495 2.3373126984 5.1027665138 ) - weight 493 5 0.4894949496 ( 4.6406164169 15.621137619 -1.6482343674 ) - weight 494 4 0.0601788051 ( -3.4853577614 36.6062736511 0.3267386556 ) - weight 495 7 0.2052899897 ( 2.6740829945 0.6437221169 5.4105315208 ) - weight 496 6 0.2387989908 ( 3.7399291992 1.9614058733 3.5949583054 ) - weight 497 5 0.4949769378 ( 2.1977565289 15.3504524231 -4.0849666595 ) - weight 498 4 0.0609341487 ( -1.4558415413 36.3832092285 -2.467864275 ) - weight 499 7 0.144764781 ( 1.9012364149 -0.1424336433 6.0528030396 ) - weight 500 6 0.1900095046 ( 2.9360177517 1.0017402172 3.8411567211 ) - weight 501 5 0.609782517 ( 2.0626478195 14.9514875412 -2.880633831 ) - weight 502 4 0.0554431528 ( -2.553445816 35.7495269775 -2.3210318089 ) - weight 503 7 0.1450792402 ( 0.0213944893 0.1579835564 6.2173757553 ) - weight 504 6 0.18486543 ( 1.2557165623 1.2555338144 4.7148365974 ) - weight 505 5 0.613668859 ( 3.457793951 15.0851325989 -1.5818473101 ) - weight 506 4 0.0563864931 ( -3.6184849739 35.8739776611 -0.7394680381 ) - weight 507 7 0.2166175842 ( 1.0601168871 2.1764745712 4.1900992393 ) - weight 508 8 0.1798899919 ( 1.1216083765 -2.8570065498 4.2000880241 ) - weight 509 6 0.1984419227 ( 2.3486933708 4.0263023376 4.0892620087 ) - weight 510 5 0.34866786 ( 4.3804268837 16.6451530457 -4.0268802643 ) - weight 511 4 0.0563826486 ( -1.4495460987 37.9965362549 -0.5080674887 ) - weight 512 7 0.2083445042 ( -1.7949187756 0.9830421209 3.9741177559 ) - weight 513 8 0.1518875808 ( -1.7071772814 -4.112095356 3.9882357121 ) - weight 514 6 0.2189562321 ( -0.6986145377 3.44658494 4.088891983 ) - weight 515 5 0.3701981008 ( 5.1915559769 17.498758316 -1.1571098566 ) - weight 516 4 0.0506135561 ( -4.2740516663 38.4251976013 0.7004751563 ) - weight 517 7 0.2018170059 ( 3.1148092747 0.5609053969 3.383256197 ) - weight 518 8 0.1440035552 ( 3.2105140686 -4.4309477806 3.3988378048 ) - weight 519 6 0.2207396328 ( 3.7481014729 3.1642713547 1.9026253223 ) - weight 520 5 0.381893903 ( 1.8311607838 17.2641830444 -4.8020329475 ) - weight 521 4 0.0515459254 ( -1.2290374041 38.3063087463 -3.2169854641 ) - weight 522 7 0.1746111363 ( -1.7333593369 -1.835300684 3.4948346615 ) - weight 523 8 0.0948143303 ( -1.5851924419 -6.9301123619 3.5187041759 ) - weight 524 6 0.3026814759 ( -1.4254000187 1.5909122229 2.0383262634 ) - weight 525 5 0.4278930426 ( 2.9242489338 18.2899608612 0.3952677846 ) - weight 526 4 1 ( -6.134906292 13.8642892838 -5.2118673325 ) - weight 527 7 0.1767944098 ( -1.7115221024 -5.94217062 1.9369847775 ) - weight 528 6 0.3593078852 ( -2.7143409252 -0.5588553548 -1.5687338114 ) - weight 529 5 0.4111023843 ( -0.3507812917 20.2947635651 2.528034687 ) - weight 530 4 0.0527953431 ( -9.2842712402 39.500087738 -4.3845758438 ) - weight 531 7 0.1673135906 ( 1.387262702 -6.3924193382 1.6067962646 ) - weight 532 6 0.3562460244 ( 0.0552371256 -0.9051148295 -3.0260455608 ) - weight 533 5 0.4237859249 ( -2.6160032749 20.1267032623 0.3474979699 ) - weight 534 4 0.0526544377 ( -7.4962301254 39.3587608337 -6.9724607468 ) - weight 535 7 0.2688274384 ( -1.3400793076 0.2123179436 3.2957470417 ) - weight 536 8 0.1586259007 ( -1.2358734608 -4.8752355576 3.3125350475 ) - weight 537 6 0.3140856326 ( -0.586591959 3.2590801716 2.9873590469 ) - weight 538 5 0.2584609985 ( 4.2940340042 18.173116684 -1.1849485636 ) - weight 539 3 0.7255700827 ( 2.3333964348 -2.6678695679 5.0437517166 ) - weight 540 17 0.0511449911 ( 2.7304620743 -4.3835334778 3.7927222252 ) - weight 541 4 0.2232849449 ( 4.977763176 0.7579114437 -1.0508857965 ) - weight 542 7 0.1333481669 ( -1.5634135008 -2.1334505081 5.4980597496 ) - weight 543 6 0.2369383126 ( -0.9517428875 0.0698144436 3.3003070354 ) - weight 544 5 0.6297135353 ( 2.6146233082 16.3376102448 0.8676553369 ) - weight 545 7 0.3436498046 ( 3.610657692 5.4473099709 -0.7394995689 ) - weight 546 8 0.3436498046 ( 3.6018269062 0.4506751001 -0.7407955527 ) - weight 547 6 0.1936228275 ( 4.6272883415 9.5083684921 1.5873577595 ) - weight 548 5 0.1190775931 ( 5.3176145554 20.6280193329 -9.0031261444 ) - weight 549 7 0.1345758885 ( 2.8363058567 -2.8042650223 5.0056824684 ) - weight 550 6 0.2668638527 ( 2.968269825 -0.4308902025 1.1948969364 ) - weight 551 5 0.598560214 ( -0.6268100142 16.1257629395 -2.2142577171 ) - weight 552 7 0.2299160063 ( 2.1700699329 -3.234916687 0.8006601334 ) - weight 553 8 0.1060122997 ( 2.3475372791 -8.2550544739 0.8293872476 ) - weight 554 6 0.3735997975 ( 1.4201873541 1.9743751287 -1.9878195524 ) - weight 555 5 0.290471822 ( -0.6196397543 20.403383255 -2.3302707672 ) - weight 556 7 0.3476153314 ( -2.6393868923 1.2659093142 -0.7909229398 ) - weight 557 8 0.2039622068 ( -2.5571608543 -3.8638730049 -0.7777548432 ) - weight 558 6 0.3159118295 ( -2.3483402729 6.7685699463 0.9677420855 ) - weight 559 5 0.1325106919 ( 5.862552166 22.2705345154 -1.6849976778 ) - weight 560 7 0.3161017895 ( 3.5401434898 0.3613545597 -1.452067852 ) - weight 561 8 0.1993993074 ( 3.6403861046 -4.6380572319 -1.4357669353 ) - weight 562 6 0.3147033155 ( 3.1725332737 6.0746736526 -1.9443693161 ) - weight 563 5 0.1697955579 ( 1.3399884701 21.9388122559 -6.029914856 ) - weight 564 3 1 ( 2.4393417835 -1.5507469177 -9.3843774796 ) - weight 565 3 1 ( 2.0570471287 -2.5874023438 -9.0592861176 ) - weight 566 3 1 ( 2.8372831345 -2.4603347778 -7.1695895195 ) - weight 567 3 1 ( 4.9008808136 0.2130050659 -8.0067882538 ) - weight 568 3 1 ( 4.3490715027 0.8817405701 -8.5133266449 ) - weight 569 3 1 ( 4.3093891144 3.043712616 -8.4343519211 ) - weight 570 3 0.939707458 ( 7.3951106071 0.2782669067 -3.2532851696 ) - weight 571 4 0.0602925085 ( -4.5623803139 -1.8513028622 1.2554448843 ) - weight 572 3 1 ( 8.5496740341 0.7149887085 -4.0596828461 ) - weight 573 3 1 ( 7.9788990021 3.1995353699 -3.3510596752 ) - weight 574 3 0.833533287 ( 6.7701330185 3.3089599609 -2.7425200939 ) - weight 575 17 0.1058692336 ( 6.7129034996 3.3514900208 -2.5588700771 ) - weight 576 4 0.0605974719 ( -3.8496007919 -4.9013662338 1.4155646563 ) - weight 577 3 1 ( 7.160451889 1.2705993652 -6.9593849182 ) - weight 578 3 0.7273254395 ( 3.7306587696 -1.8947105408 5.8403820992 ) - weight 579 17 0.0704036281 ( 4.171151638 -3.8054456711 4.673043251 ) - weight 580 4 0.202270925 ( 5.2300887108 0.2909796238 0.6529461741 ) - weight 581 3 0.9335158467 ( 5.7466959953 3.8326377869 -4.9486117363 ) - weight 582 17 0.0664841607 ( 5.5645112991 4.3762359619 -4.5132479668 ) - weight 583 3 0.6088041067 ( 6.2323412895 1.7132644653 4.4671297073 ) - weight 584 17 0.3321590424 ( 6.5898756981 0.0611637011 4.0723538399 ) - weight 585 4 0.0590368398 ( 3.0744447708 -2.9248280525 3.1375994682 ) - weight 586 3 0.740485847 ( 7.4737606049 1.7016983032 2.1003034115 ) - weight 587 17 0.1179619804 ( 7.6933779716 0.6364219189 1.7070878744 ) - weight 588 4 0.1415522099 ( 0.4210855663 -2.866134882 3.4528162479 ) - weight 589 3 0.0681025982 ( 0.9762268066 -10.5221939087 0.4071492553 ) - weight 590 4 0.9318974018 ( 1.0897656679 7.9261255264 -5.3556022644 ) - weight 591 3 0.5049455166 ( 1.6513501406 -6.3452148438 3.1895129681 ) - weight 592 4 0.4950544536 ( 3.4699532986 4.1280241013 -2.9989895821 ) - weight 593 3 0.1718951166 ( 0.3147409856 -7.1571731567 -3.813833952 ) - weight 594 4 0.8281048536 ( -2.6067092419 4.2133412361 -6.8146891594 ) - weight 595 3 0.7416662574 ( 3.9283571243 -4.9997177124 -5.656545639 ) - weight 596 4 0.2583337426 ( -5.6023106575 2.5800983906 -3.7377896309 ) - weight 597 3 0.8021942973 ( 6.6330957413 -4.0208969116 -3.9222574234 ) - weight 598 4 0.1978057176 ( -4.9364709854 2.1985523701 -0.4678451121 ) - weight 599 3 0.6507291198 ( 9.0773057938 -3.2442054749 -0.5589654446 ) - weight 600 4 0.3492708504 ( -2.6561191082 2.0842204094 3.0925018787 ) - weight 601 3 0.8790286183 ( 9.0366792679 -1.4263534546 -0.2203686833 ) - weight 602 4 0.1209713668 ( -2.3170702457 0.3138816953 3.5070269108 ) - weight 603 3 1 ( 4.5356354713 -2.2324028015 -7.1859068871 ) - weight 604 3 0.7236207724 ( 0.8121445775 -5.7375869751 -4.7804937363 ) - weight 605 4 0.2763792276 ( -3.6806528568 2.8356285095 -6.4330878258 ) - weight 606 3 0.278526336 ( 2.505641222 -8.2148284912 -5.7358665466 ) - weight 607 4 0.7214736938 ( -5.1858439445 5.4927544594 -5.6640138626 ) - weight 608 3 1 ( 2.4304387569 -3.3657417297 -6.0171556473 ) - weight 609 3 0.8667687178 ( 8.3641290665 -1.9775505066 -3.1054530144 ) - weight 610 4 0.1332312971 ( -4.7780928612 0.5412865877 1.7832205296 ) - weight 611 3 0.9462394714 ( 7.258852005 -1.9894180298 -5.8444795609 ) - weight 612 4 0.0537605248 ( -6.9465990067 0.1750069708 -0.1884452999 ) - weight 613 7 0.1016506925 ( 0.7945479751 -6.7303395271 4.8787183762 ) - weight 614 6 0.2594518661 ( 0.038751509 -3.2157046795 -0.6111171842 ) - weight 615 5 0.6388974786 ( -2.4691007137 17.0730323792 1.6982355118 ) - weight 616 7 0.1428305209 ( -0.1974931657 -7.1519165039 2.404800415 ) - weight 617 6 0.3172379136 ( -1.4834601879 -1.8882421255 -2.4007701874 ) - weight 618 5 0.4840363264 ( -2.2285680771 19.7149276733 2.1928796768 ) - weight 619 4 0.0558952838 ( -9.1284608841 38.6820259094 -6.1959609985 ) - weight 620 7 0.083662428 ( 1.6481533051 -5.4658851624 4.3666615486 ) - weight 621 6 0.2615793943 ( 1.0620567799 -1.9786320925 -0.5007220507 ) - weight 622 5 0.654758215 ( -2.0045552254 17.2739429474 0.1706485152 ) - weight 623 7 0.0667252541 ( 0.308321774 -5.6894173622 5.4881191254 ) - weight 624 6 0.1860086769 ( -0.0499204174 -2.775049448 0.6092369556 ) - weight 625 5 0.7472660542 ( -1.3402583599 16.4396076202 1.5725675821 ) - weight 626 7 0.1340976954 ( 2.3247125149 -3.4799058437 3.0181970596 ) - weight 627 8 0.0738698542 ( 2.5072305202 -8.4890031815 3.0477583408 ) - weight 628 6 0.3448124826 ( 1.9336231947 0.3579707444 -0.5300730467 ) - weight 629 5 0.4472199082 ( -0.8747335672 18.2379760742 -1.8329348564 ) - weight 630 7 0.2646489143 ( 1.9292984009 1.2352389097 2.8481075764 ) - weight 631 8 0.1765218228 ( 2.0108625889 -3.7840323448 2.8613598347 ) - weight 632 6 0.2590146661 ( 2.6846964359 4.1042146683 2.2662494183 ) - weight 633 5 0.2473214418 ( 3.083776474 17.9155216217 -4.4105491638 ) - weight 634 4 0.0524931625 ( -1.5513541698 39.0766677856 -2.0131561756 ) - weight 635 7 0.2493312061 ( 2.6578202248 -0.7320805192 2.6633791924 ) - weight 636 8 0.138061747 ( 2.7813954353 -5.7359127998 2.6834375858 ) - weight 637 6 0.3237291873 ( 2.8574774265 2.6660039425 0.7375533581 ) - weight 638 5 0.2888779044 ( 1.0818386078 18.2010173798 -3.8223719597 ) - weight 639 5 1 ( -2.6096160412 11.0932798386 0.6067078114 ) - weight 640 3 0.4810942113 ( 0.2447296828 -5.9556617737 -1.4486429691 ) - weight 641 4 0.5189057589 ( -0.3653141856 3.1842691898 -5.8349852562 ) - weight 642 25 1 ( -1.8255153894 4.9820408821 3.8346762657 ) - weight 643 25 1 ( 0.8778755665 5.8953647614 3.4897301197 ) - weight 644 25 1 ( 0.0099414997 3.0228860378 4.2391757965 ) - weight 645 25 1 ( 3.0410499573 3.6939957142 3.0369729996 ) - weight 646 25 1 ( 3.9181816578 4.5311059952 0.9661721587 ) - weight 647 25 1 ( 3.1524927616 5.9717550278 1.7729581594 ) - weight 648 25 1 ( -2.2104358673 3.2541790009 3.5169045925 ) - weight 649 25 1 ( 0.1166709214 1.1084251404 3.7477328777 ) - weight 650 23 0.0603290237 ( -2.7672336102 6.952229023 1.7570525408 ) - weight 651 24 0.0603290237 ( -2.5804653168 -2.6066014767 1.3873748779 ) - weight 652 25 0.87934196 ( -2.1481137276 1.3443427086 3.011017561 ) - weight 653 25 0.8074488044 ( 3.4532454014 2.772411108 -0.4214020967 ) - weight 654 19 0.1925511956 ( 10.0099906921 8.8643655777 3.6808135509 ) - weight 655 25 0.9459140301 ( 4.1030759811 2.6468076706 0.4092708826 ) - weight 656 19 0.0540859886 ( 10.4489917755 9.7282943726 4.1155304909 ) - weight 657 25 0.9465995431 ( 3.2084012032 1.7929573059 2.521484375 ) - weight 658 19 0.0534004718 ( 10.8585739136 11.7013483047 2.7261962891 ) - weight 659 25 0.8305544257 ( -2.4430963993 1.8181079626 1.866936326 ) - weight 660 19 0.1694456041 ( 9.9061231613 9.9890346527 -2.6150872707 ) - weight 661 25 0.4730896652 ( 2.4707279205 2.5427651405 -2.8838136196 ) - weight 662 19 0.5269103646 ( 8.317943573 6.8482556343 3.2886078358 ) - weight 663 23 0.0811879858 ( 4.2014994621 5.8216772079 -1.7951412201 ) - weight 664 24 0.0815184191 ( -0.4475841522 4.2390818596 -1.9363136292 ) - weight 665 25 0.4901721179 ( 3.971984148 1.4176681042 -1.9888314009 ) - weight 666 19 0.3471215069 ( 8.0687627792 8.5180597305 4.5011544228 ) - weight 667 25 0.5052517653 ( 0.1248020381 3.2294492722 -2.9028835297 ) - weight 668 19 0.4947482347 ( 8.6178388596 5.9463543892 1.0365190506 ) - weight 669 25 0.7788330317 ( 4.4076499939 1.0978821516 -0.2869901359 ) - weight 670 22 0.0702832192 ( 8.822013855 1.8969993591 4.7038331032 ) - weight 671 19 0.1508837491 ( 8.822013855 10.1368961334 4.5188946724 ) - weight 672 23 0.1050024852 ( -3.2980058193 5.5827555656 0.4966287613 ) - weight 673 24 0.1050024852 ( -1.0632133484 -3.2363021374 0.3640136719 ) - weight 674 25 0.6263005137 ( -3.0563628674 0.7086001635 1.4245878458 ) - weight 675 19 0.163694486 ( 8.6843919754 10.1524448395 -3.1474831104 ) - weight 676 23 0.0926442668 ( -3.5321965218 5.6398463249 -1.023475647 ) - weight 677 24 0.0926442668 ( -0.8901510239 -3.4821374416 -1.1454353333 ) - weight 678 25 0.5098309517 ( -3.5026264191 1.4442635775 0.1484726071 ) - weight 679 19 0.3048804998 ( 8.5113296509 8.6272296906 -3.2596957684 ) - weight 680 23 0.0952894464 ( -0.3688555062 5.774266243 3.4286460876 ) - weight 681 24 0.0952894464 ( -1.5346889496 -0.2706707716 3.226890564 ) - weight 682 25 0.678137064 ( 0.2714618742 -0.6096554995 3.5224692822 ) - weight 683 22 0.131284073 ( 9.1558675766 5.4491920471 0.0341236591 ) - weight 684 23 0.1499208361 ( -2.7616055012 5.8185639381 1.8216013908 ) - weight 685 24 0.1499208361 ( -1.4739379883 -2.6723060608 1.6336975098 ) - weight 686 25 0.5775595307 ( -2.3003306389 0.3003794551 2.5910589695 ) - weight 687 22 0.122598812 ( 9.0951166153 3.8559989929 -2.3675115108 ) - weight 688 23 0.0526392497 ( -1.8222351074 6.3481841087 -3.711486578 ) - weight 689 24 0.0526392497 ( -1.0456647873 -1.7585984468 -3.9124450684 ) - weight 690 25 0.4430772066 ( -2.1251008511 3.1438159943 -2.2733156681 ) - weight 691 19 0.4516443014 ( 8.6668434143 6.0224175453 -1.2996242046 ) - weight 692 23 0.0716030672 ( 2.8934276104 6.3362236023 2.3204774857 ) - weight 693 24 0.0718849227 ( -1.7001152039 3.0090520382 2.0426712036 ) - weight 694 25 0.6563013196 ( 3.3798689842 0.1578751951 2.1314172745 ) - weight 695 22 0.138011381 ( 9.3212938309 4.2649726868 3.3138465881 ) - weight 696 19 0.0621992871 ( 9.3212938309 12.3735332489 2.9261572361 ) - weight 697 20 0.1290044338 ( 0.4094176292 4.7723426819 -0.7690458298 ) - weight 698 25 0.0764867887 ( 5.2971348763 -2.7499263287 -2.6502709389 ) - weight 699 22 0.3060672581 ( 4.4341006279 2.3252906799 6.0247020721 ) - weight 700 21 0.0632745922 ( 8.686460495 4.6440162659 -0.7690458298 ) - weight 701 19 0.4251669943 ( 4.4341006279 10.6796255112 5.7970070839 ) - weight 702 25 0.0919046253 ( -2.2104570866 -5.1100330353 1.6019939184 ) - weight 703 22 0.9080953598 ( 4.1291065216 6.1981391907 -2.0328297615 ) - weight 704 23 0.111001648 ( 1.6846551895 1.9647772312 3.4220235348 ) - weight 705 24 0.0891765058 ( 2.3504519463 1.5366053581 3.8340072632 ) - weight 706 25 0.1500965506 ( 1.7162941694 -4.1585283279 1.5107238293 ) - weight 707 22 0.649725318 ( 5.2707266808 6.0563087463 1.8413997889 ) - weight 708 23 0.1072058529 ( 3.7523417473 2.2670571804 2.2852313519 ) - weight 709 24 0.0931440294 ( 2.3685188293 3.6074204445 2.6633682251 ) - weight 710 25 0.1410497874 ( 3.6140003204 -3.5292677879 0.2216391563 ) - weight 711 22 0.5160495639 ( 5.2526597977 4.8856697083 3.912214756 ) - weight 712 19 0.1425507665 ( 5.2526597977 13.044421196 3.4676542282 ) - weight 713 23 0.1135413796 ( -0.5692016482 1.80458951 3.6659920216 ) - weight 714 24 0.0882926509 ( 2.3239831924 -0.7202247381 4.1005935669 ) - weight 715 25 0.1216077283 ( -0.4750436842 -4.2551617622 2.1054940224 ) - weight 716 22 0.6765582561 ( 5.2971954346 6.32289505 -0.4154303074 ) - weight 717 23 0.1129395142 ( -3.1228830814 1.4915858507 2.8157565594 ) - weight 718 24 0.0887360871 ( 2.6046257019 -3.2973031998 3.311882019 ) - weight 719 25 0.1095810533 ( -3.1445698738 -3.9869213104 1.7262350321 ) - weight 720 39 0.0537326299 ( 2.4773373604 -8.389966011 1.2030831575 ) - weight 721 22 0.6350107193 ( 5.0165529251 5.5341835022 -2.9925088882 ) - weight 722 23 0.0914017186 ( -3.8113386631 0.1860364079 1.8491221666 ) - weight 723 24 0.061802078 ( 4.0015463829 -4.0772562027 2.5681762695 ) - weight 724 22 0.7597923875 ( 3.6196322441 4.7904777527 -3.7724618912 ) - weight 725 19 0.0870038196 ( 3.6196322441 12.2741622925 -4.1789150238 ) - weight 726 17 0.0596817918 ( 2.1308577061 8.837720871 10.8589677811 ) - weight 727 22 0.0719239861 ( 1.5239515305 -5.0739479065 9.9274139404 ) - weight 728 19 0.868394196 ( 1.5239515305 3.6520473957 10.3349628448 ) - weight 729 20 0.103534773 ( -1.3824956417 2.7881393433 1.6832141876 ) - weight 730 22 0.37153247 ( 2.6421873569 0.3410873413 8.4769620895 ) - weight 731 19 0.5249327421 ( 2.6421873569 8.9186401367 8.4141759872 ) - weight 732 18 0.143268615 ( 2.8050186634 4.1625137329 0.2868571281 ) - weight 733 17 0.5675147772 ( 3.222723484 4.1749172211 7.7406396866 ) - weight 734 19 0.289216578 ( 2.7232618332 -1.7657701969 8.9686584473 ) - weight 735 20 0.094052501 ( -2.3515679836 -5.3680610657 2.5406947136 ) - weight 736 17 0.4901732206 ( 2.24573493 6.3220038414 9.6156568527 ) - weight 737 21 0.0709384456 ( 5.9254746437 -5.4963874817 2.5406947136 ) - weight 738 19 0.3448358178 ( 1.6731148958 0.8693724275 9.9852170944 ) - weight 739 18 0.1721023619 ( 1.4771124125 3.5550079346 1.2471613884 ) - weight 740 17 0.6206626296 ( 1.9521341324 3.3359508514 8.5987319946 ) - weight 741 19 0.2072349936 ( 1.395355463 -2.2865200043 9.9786424637 ) - weight 742 20 0.0829953179 ( -0.5074756145 2.2373695374 0.9335846901 ) - weight 743 22 0.2855619788 ( 3.5172073841 -0.2096824646 7.727332592 ) - weight 744 19 0.6314427257 ( 3.5172073841 8.3041143417 7.715857029 ) - weight 745 17 0.0628961921 ( 6.2300915718 9.7015161514 7.2735953331 ) - weight 746 22 0.0539472364 ( 5.8281311989 -5.099445343 6.4809465408 ) - weight 747 19 0.8831565976 ( 5.8281311989 3.323725462 6.9040746689 ) - weight 748 20 0.0991675779 ( 3.234556675 -4.0736579895 -2.1612222195 ) - weight 749 17 0.1918828785 ( 7.5527296066 8.7865304947 5.0604176521 ) - weight 750 19 0.7089495063 ( 7.2592396736 1.7454966307 5.1877274513 ) - weight 751 20 0.0926690698 ( 4.1542367935 -6.3154258728 -4.3839635849 ) - weight 752 3 0.0550959557 ( 8.1789197922 8.1778831482 1.1582477093 ) - weight 753 17 0.3726654649 ( 8.3432941437 7.1581788063 2.315350771 ) - weight 754 19 0.4795694947 ( 8.1789197922 -0.6829606295 3.1706259251 ) - weight 755 20 0.0619742945 ( 0.5028457642 2.4684944153 0.8914880753 ) - weight 756 22 0.168408528 ( 4.5275287628 0.0214424133 7.6852359772 ) - weight 757 19 0.7696171999 ( 4.5275287628 8.5306444168 7.653608799 ) - weight 758 22 0.0798309669 ( 6.2138233185 -1.6987228394 6.9659352303 ) - weight 759 19 0.9201690555 ( 6.2138233185 6.7539143562 7.0882835388 ) - weight 760 19 1 ( 7.7301111221 3.3008527756 5.119559288 ) - weight 761 3 0.0600100607 ( 4.8108649254 8.5944099426 -6.5108242035 ) - weight 762 17 0.4095980227 ( 4.5405435562 9.3605604172 -4.8275165558 ) - weight 763 22 0.0737395361 ( 4.8108649254 -8.3459510803 -5.2592878342 ) - weight 764 19 0.4566524029 ( 4.8108649254 -0.9421098232 -4.5053758621 ) - weight 765 17 0.2797969878 ( 6.924721241 9.6104536057 -1.3191415071 ) - weight 766 22 0.0568300672 ( 6.9990987778 -7.2581253052 -1.78312397 ) - weight 767 19 0.6633729339 ( 6.9990987778 0.4470392466 -1.1382784843 ) - weight 768 20 0.064367786 ( 3.5722675323 0.5503120422 -1.950483799 ) - weight 769 25 0.1625600159 ( 3.9493012428 2.2903218269 -4.0659689903 ) - weight 770 19 0.7730721831 ( 7.596950531 6.3700938225 4.9912319183 ) - weight 771 23 0.0819378868 ( -4.4637479782 4.4625430107 -4.5191497803 ) - weight 772 24 0.08182358 ( 0.7713661194 -4.5227508545 -4.4058113098 ) - weight 773 25 0.1527400464 ( -5.1062784195 1.9910515547 -3.2578289509 ) - weight 774 22 0.0618891604 ( 6.8498125076 -2.1835098267 -4.217956543 ) - weight 775 19 0.6216093302 ( 6.8498125076 5.2880086899 -4.0097150803 ) - weight 776 18 0.074824363 ( 2.4083220959 6.1913414001 -13.44145298 ) - weight 777 17 0.3822825551 ( 2.0385942459 9.4406814575 -5.0503554344 ) - weight 778 22 0.103139542 ( 2.3265652657 -8.3218803406 -5.6381044388 ) - weight 779 19 0.4397535026 ( 2.3265652657 -0.9514278769 -4.8848419189 ) - weight 780 17 0.299821496 ( 3.3704733849 12.1207962036 -5.7154126167 ) - weight 781 22 0.0852135643 ( 3.73037076 -5.8809547424 -6.8507189751 ) - weight 782 19 0.614964962 ( 3.73037076 1.3734697104 -6.3073058128 ) - weight 783 20 0.0870492309 ( -0.730512619 0.2186355591 -13.6559562683 ) - weight 784 17 0.0947004631 ( 2.9343328476 15.6624650955 -4.8222136497 ) - weight 785 22 0.214722231 ( 3.2941703796 -2.2284164429 -6.8622078896 ) - weight 786 21 0.0763065293 ( 7.5465302467 0.0903091431 -13.6559562683 ) - weight 787 19 0.5272215605 ( 3.2941703796 5.0108623505 -6.6397857666 ) - weight 788 23 0.0858657882 ( 5.2979001999 -0.2778771222 0.8129232526 ) - weight 789 39 0.0611941852 ( -5.6080303192 -5.0251774788 0.0382012948 ) - weight 790 22 0.5666524768 ( 2.4100449085 3.842540741 5.2777018547 ) - weight 791 19 0.286287576 ( 2.4100449085 12.1253471375 4.9195413589 ) - weight 792 22 0.1728690118 ( 3.0167717934 -2.7448730469 9.4543800354 ) - weight 793 19 0.8271310329 ( 3.0167717934 5.9305319786 9.6590480804 ) - weight 794 20 0.11865969 ( 2.1683359146 3.1566200256 -0.7816853523 ) - weight 795 25 0.1455741674 ( 5.2732925415 -0.3806591034 -2.9511315823 ) - weight 796 22 0.1275289357 ( 6.1930189133 0.7095680237 6.0120625496 ) - weight 797 19 0.6082372069 ( 6.1930189133 9.0690450668 5.9264287949 ) - weight 798 23 0.0500451624 ( -3.5165264606 5.3113613129 -7.2377686501 ) - weight 799 24 0.0500451624 ( 0.4333376884 -3.5517680645 -7.2256584167 ) - weight 800 17 0.1471123099 ( 7.0291185379 12.1535215378 -2.204785347 ) - weight 801 22 0.060705293 ( 7.1878409386 -5.0033569336 -3.2469735146 ) - weight 802 19 0.692092061 ( 7.1878409386 2.5644180775 -2.7946429253 ) - weight 803 17 0.0882978588 ( 7.7811055183 10.8802022934 1.5581493378 ) - weight 804 25 0.0594077036 ( -0.5006882548 4.4357395172 -6.1103172302 ) - weight 805 19 0.852294445 ( 7.7113251686 2.5876910686 1.2143377066 ) - weight 806 22 0.1241166219 ( 4.4618620872 -3.2965545654 7.6446428299 ) - weight 807 19 0.8758834004 ( 4.4618620872 5.2219204903 7.9048042297 ) - weight 808 3 0.4214345217 ( 4.2138977051 6.2819366455 -5.6449556351 ) - weight 809 17 0.2924469113 ( 3.99426651 6.8996782303 -4.5124397278 ) - weight 810 19 0.2861185968 ( 4.2138977051 -3.1695289612 -3.4396061897 ) - weight 811 23 0.1238846853 ( -6.1000328064 0.5420299768 -1.6492097378 ) - weight 812 40 0.0606948659 ( -11.1763267517 -6.3748574257 -0.9418373108 ) - weight 813 39 0.0867915154 ( 5.6425466537 -6.460911274 -2.7920634747 ) - weight 814 22 0.4406973124 ( 3.5551466942 1.2804870605 -6.0700659752 ) - weight 815 19 0.2879316211 ( 3.5551466942 8.5758104324 -6.1591205597 ) - weight 816 3 0.2818386555 ( 7.3179450035 6.1070823669 -3.6608753204 ) - weight 817 18 0.0547244027 ( 7.3997020721 3.6799430847 -10.2126865387 ) - weight 818 17 0.3285991251 ( 7.2070932388 6.2956595421 -2.8050544262 ) - weight 819 19 0.3348378241 ( 7.3179450035 -3.1693181992 -1.4478360415 ) - weight 820 23 0.0575322956 ( -0.0192135014 6.2486820221 -5.4829688072 ) - weight 821 24 0.0575324968 ( -0.5468864441 0.0160076618 -5.6447639465 ) - weight 822 25 0.2394847125 ( -0.639721036 3.7105095387 -4.2409133911 ) - weight 823 19 0.6454505324 ( 8.1680650711 4.4527797699 0.6203741431 ) - weight 824 20 0.0796245411 ( 1.5714087486 -4.3449020386 0.6071043015 ) - weight 825 17 0.2219376862 ( 6.0512428284 7.8343844414 7.7700705528 ) - weight 826 19 0.6984377503 ( 5.5960917473 1.7186210155 7.9691810608 ) - weight 827 20 0.106299758 ( 3.2438931465 -7.6039772034 -1.970107317 ) - weight 828 3 0.0926221386 ( 7.2685761452 6.8893318176 3.5721042156 ) - weight 829 17 0.37471053 ( 7.5730218887 5.3143701553 4.3944950104 ) - weight 830 19 0.4263675809 ( 7.2685761452 -1.7543619871 5.688395977 ) - weight 831 17 0.0715875253 ( 4.0679769516 9.1960840225 9.3542432785 ) - weight 832 22 0.0749636889 ( 3.5466682911 -5.088684082 8.4944286346 ) - weight 833 19 0.8534488082 ( 3.5466682911 3.5114176273 8.9088182449 ) - weight 834 18 0.1277374774 ( 4.1387939453 5.0340919495 0.336514473 ) - weight 835 17 0.4421193004 ( 4.5571494102 5.0273227692 7.9244384766 ) - weight 836 22 0.0506835431 ( 4.0570368767 -9.4791297913 8.1398620605 ) - weight 837 19 0.3794595897 ( 4.0570368767 -0.8932005167 8.9415178299 ) - weight 838 3 0.1202486232 ( 2.8713064194 5.0997123718 6.2222933769 ) - weight 839 18 0.1675754935 ( 2.9530632496 2.6725730896 -0.3295183182 ) - weight 840 17 0.5405387282 ( 3.3351402283 2.8791782856 6.7761797905 ) - weight 841 19 0.1716371924 ( 2.8713064194 -3.3041200638 8.485625267 ) - weight 842 3 0.2958280146 ( 1.7950662374 3.0419692993 6.4724926949 ) - weight 843 18 0.1491696388 ( 1.8768231869 0.6148300171 -0.0793190002 ) - weight 844 17 0.4509178102 ( 2.2750377655 0.8069860339 6.5827860832 ) - weight 845 4 0.0520113297 ( 6.5299096107 -4.8472995758 0.0006883774 ) - weight 846 19 0.0520732142 ( 1.7950662374 -5.3319087029 8.9157190323 ) - weight 847 3 0.407371074 ( 2.900220871 3.6319847107 7.0007915497 ) - weight 848 18 0.1387829781 ( 2.9819777012 1.2048454285 0.4489798546 ) - weight 849 17 0.3970761597 ( 3.4086976051 1.2678294182 7.1752591133 ) - weight 850 19 0.0567697696 ( 2.900220871 -4.6977424622 9.3901147842 ) - weight 851 3 0.4249811471 ( 6.358253479 3.8093528748 4.1738572121 ) - weight 852 18 0.0765370801 ( 6.4400105476 1.3822135925 -2.377954483 ) - weight 853 17 0.2950636446 ( 6.6987447739 2.1677882671 4.286198616 ) - weight 854 4 0.0677497238 ( 2.7648942471 -4.9840970039 3.5363955498 ) - weight 855 19 0.1356684268 ( 6.358253479 -4.7695307732 6.5585312843 ) - weight 856 3 0.5413859487 ( 7.4205164909 4.1601028442 0.1617401242 ) - weight 857 17 0.2140661031 ( 7.5289363861 3.4879674911 0.4240202606 ) - weight 858 4 0.0810237825 ( -1.3614509106 -5.4260520935 3.1807801723 ) - weight 859 19 0.1635241956 ( 7.4205164909 -4.772778511 2.5311129093 ) - weight 860 3 0.7066246271 ( 5.7542610168 4.3418273926 -4.5260896683 ) - weight 861 17 0.1827720404 ( 5.5963191986 4.7688970566 -3.9815888405 ) - weight 862 19 0.1106032729 ( 5.7542610168 -5.0037884712 -2.1545469761 ) - weight 863 3 0.7992858291 ( 3.6426603794 3.8363189697 -6.4675378799 ) - weight 864 17 0.1054382473 ( 3.3767502308 4.7160682678 -5.8668842316 ) - weight 865 19 0.0952759013 ( 3.6426603794 -5.6779818535 -4.0440502167 ) - weight 866 20 0.0742564574 ( 1.1112108231 0.2899017334 -12.4811029434 ) - weight 867 17 0.0605752133 ( 4.8404626846 15.4745073318 -3.7692921162 ) - weight 868 25 0.0511426926 ( -6.7351255417 0.6012163758 -3.9737610817 ) - weight 869 22 0.1611460447 ( 5.1358938217 -2.1571502686 -5.6873550415 ) - weight 870 21 0.0595895164 ( 9.388253212 0.1615753174 -12.4811029434 ) - weight 871 19 0.5932900906 ( 5.1358938217 5.1851148605 -5.4757437706 ) - weight 872 23 0.1318016648 ( -4.1578140259 3.9190831184 0.6416856647 ) - weight 873 24 0.1290110648 ( 0.4966897964 -4.1984715462 0.7751693726 ) - weight 874 25 0.3656567335 ( -4.1211056709 -0.7862137556 1.0246231556 ) - weight 875 39 0.0515754297 ( 3.2410106659 -10.1147012711 -1.6486709118 ) - weight 876 22 0.1448136866 ( 7.1244888306 2.9974708557 -3.8936772346 ) - weight 877 19 0.1771414727 ( 7.1244888306 10.4774398804 -4.1420669556 ) - weight 878 23 0.0985166207 ( 5.0278534889 4.0742707253 0.6220319867 ) - weight 879 24 0.0979153141 ( 0.9380335808 4.9778122902 0.7307739258 ) - weight 880 25 0.3668260872 ( 4.8810238838 -1.2666740417 -0.7450587749 ) - weight 881 22 0.2166462541 ( 6.6831450462 2.9530754089 5.2826066017 ) - weight 882 19 0.2200956494 ( 6.6831450462 11.2397556305 5.0026059151 ) - weight 883 23 0.1435491592 ( 3.4330570698 4.4749522209 2.2666320801 ) - weight 884 24 0.1437141746 ( 0.1764192581 3.4288108349 2.289352417 ) - weight 885 25 0.3799183071 ( 3.6248652935 -1.5220993757 1.1954188347 ) - weight 886 22 0.3328183591 ( 7.4447593689 4.5116539001 3.7336051464 ) - weight 887 23 0.156258285 ( -0.2468321323 3.8473155499 3.4860498905 ) - weight 888 24 0.1507516354 ( 0.3617796898 -0.2706707716 3.5939483643 ) - weight 889 25 0.3186547756 ( 0.1149288788 -2.3688180447 2.7400567532 ) - weight 890 22 0.3743353188 ( 7.2593989372 5.8162498474 0.0341236591 ) - weight 891 23 0.1602704972 ( -2.816624403 3.7462182045 2.2516946793 ) - weight 892 24 0.1538378745 ( 0.494427681 -2.8543515205 2.391998291 ) - weight 893 25 0.2565502524 ( -2.5961081982 -1.7407828569 2.1127319336 ) - weight 894 39 0.0551610962 ( 1.8995301723 -10.2920007706 -0.0393870436 ) - weight 895 22 0.3741802573 ( 7.126750946 4.6142997742 -2.549557209 ) - weight 896 23 0.1409281343 ( -4.4414873123 1.6617176533 1.2189378738 ) - weight 897 24 0.1164635196 ( 2.608912468 -4.6189217567 1.7085113525 ) - weight 898 25 0.1498096138 ( -4.6459274292 -3.0421450138 0.6441932917 ) - weight 899 39 0.0716580003 ( 3.7964932919 -8.2114114761 -0.3923596144 ) - weight 900 22 0.382319957 ( 5.0122661591 3.9308128357 -4.3141274452 ) - weight 901 19 0.1388208419 ( 5.0122661591 11.370215416 -4.6429252625 ) - weight 902 20 0.0650246665 ( -1.4911022186 -4.4371871948 2.8860850334 ) - weight 903 17 0.2580180466 ( 3.1246092319 7.154276371 10.126660347 ) - weight 904 19 0.6769573092 ( 2.53358078 1.8270013332 10.2474527359 ) - weight 905 22 0.9465700984 ( 2.4110500813 7.1069450378 -1.3874628544 ) - weight 906 19 0.0534298941 ( 2.4110500813 14.7912912369 -2.0067493916 ) - weight 907 23 0.050450813 ( 0.8638019562 0.2245918363 3.5613021851 ) - weight 908 25 0.0518364236 ( 0.677493751 -5.7219815254 1.0658063889 ) - weight 909 22 0.8977127671 ( 3.6320309639 6.4740867615 0.9131856561 ) - weight 910 22 0.8253623247 ( 1.8106377125 4.6900215149 4.140335083 ) - weight 911 19 0.1746376157 ( 1.8106377125 12.8695802689 3.7120878696 ) - weight 912 23 0.0829045624 ( 3.0786943436 -0.0841167569 2.8616437912 ) - weight 913 22 0.8328667283 ( 3.0730025768 5.8332939148 3.0966331959 ) - weight 914 19 0.084228754 ( 3.0730025768 13.9166936874 2.5719387531 ) - weight 915 23 0.1140296981 ( -4.9899950027 2.9895880222 -2.0534129143 ) - weight 916 24 0.1081208363 ( 1.7918419838 -5.1158871651 -1.735004425 ) - weight 917 25 0.1804821044 ( -5.4721579552 -0.3763943613 -1.5881813765 ) - weight 918 39 0.0599147715 ( 4.2398576736 -8.4930486679 -3.9273967743 ) - weight 919 22 0.1659332365 ( 5.8293366432 0.4872970581 -4.8110928535 ) - weight 920 19 0.3715193272 ( 5.8293366432 7.8963460922 -4.8353033066 ) - weight 921 23 0.0608512871 ( -5.071454525 -1.5550415516 1.9790018797 ) - weight 922 22 0.8387778997 ( 2.0068097115 5.1991233826 -5.1391825676 ) - weight 923 19 0.1003707871 ( 2.0068097115 12.5611000061 -5.5762639046 ) - weight 924 20 0.0638045073 ( -0.0007600784 -1.5040931702 -13.0935106277 ) - weight 925 17 0.1389597207 ( 3.6951696873 13.8652896881 -4.732963562 ) - weight 926 22 0.1094966531 ( 4.0239229202 -3.9511451721 -6.2997627258 ) - weight 927 21 0.0539900064 ( 8.2762823105 -1.6324195862 -13.0935106277 ) - weight 928 19 0.6337491274 ( 4.0239229202 3.3442363739 -5.9281001091 ) - weight 929 41 1 ( -2.2043852806 5.5120339394 2.4600522518 ) - weight 930 41 1 ( 2.1811738014 5.0418376923 1.7733217478 ) - weight 931 42 0.1599482894 ( 0.9364245534 -0.2291804403 -1.491946578 ) - weight 932 41 0.8400517106 ( 1.1072325706 11.2443275452 -1.2226268053 ) - weight 933 42 1 ( -1.806617856 6.6878194809 -0.2636643648 ) - weight 934 42 0.2617043257 ( -1.7040215731 -0.3035872877 -1.4152371883 ) - weight 935 41 0.7382956743 ( -1.5066159964 11.005979538 -1.5298105478 ) - weight 936 42 0.8004132509 ( -2.4971621037 1.9979377985 -0.8230926394 ) - weight 937 41 0.1995867491 ( -2.4468085766 13.3193426132 -1.7325708866 ) - weight 938 42 0.2404890209 ( -2.6976015568 -0.2621226013 0.1729292125 ) - weight 939 41 0.759510994 ( -2.750136137 11.4067411423 -0.1865902543 ) - weight 940 41 1 ( -1.4053552151 6.8949842453 -2.2008185387 ) - weight 941 41 1 ( -0.0519102998 9.7423009872 -2.4788763523 ) - weight 942 41 1 ( 1.6646270752 6.1529974937 -1.8214684725 ) - weight 943 41 1 ( 1.6101078987 8.9276123047 -0.0457521938 ) - weight 944 41 1 ( 0.8481068611 5.8283238411 3.4220509529 ) - weight 945 41 1 ( -1.9984459877 8.9900398254 1.2633500099 ) - weight 946 42 0.8494622111 ( -1.3523151875 2.8149037361 -1.4070101976 ) - weight 947 41 0.1505377889 ( -1.2428777218 14.0261325836 -2.3409016132 ) - weight 948 42 1 ( -0.2125431001 5.6788058281 -1.0375118256 ) - weight 949 41 1 ( -0.5523517132 7.3849081993 2.8079600334 ) - weight 950 41 1 ( 1.0339329243 8.8957929611 2.1599655151 ) - weight 951 41 1 ( -2.428861618 7.9360132217 0.2125213444 ) - weight 952 42 0.6999999881 ( -0.1431158036 -0.2168442607 2.7811408043 ) - weight 953 41 0.3000000119 ( -0.6647371054 12.3407249451 2.6610405445 ) - weight 954 42 0.4001356959 ( 0.4295689762 10.5328969955 0.8858771324 ) - weight 955 43 0.5998643041 ( 1.0320802927 -0.4470918775 -1.0050358772 ) - weight 956 42 0.4829399288 ( -0.0085092597 10.5878744125 1.3911898136 ) - weight 957 43 0.5170600414 ( 1.5149816275 -0.8514216542 -0.7735196948 ) - weight 958 41 0.7760010362 ( 1.0370160341 3.5393157005 -2.6875545979 ) - weight 959 19 0.2239989787 ( -9.8887062073 7.3279299736 2.9806351662 ) - weight 960 41 0.7162629962 ( 2.2967495918 3.7452018261 -1.1719523668 ) - weight 961 19 0.2837370336 ( -9.4104957581 6.1214318275 1.4832890034 ) - weight 962 41 1 ( -0.7731289268 4.7089004517 -3.1111459732 ) - weight 963 41 0.7619376183 ( 2.2917516232 3.5146150589 1.7067825794 ) - weight 964 19 0.2380623817 ( -9.321146965 6.1671380997 -1.4029263258 ) - weight 965 41 0.7907838821 ( 0.2717847526 2.4460463524 3.4179959297 ) - weight 966 19 0.2092161477 ( -9.6178569794 8.38763237 -3.1725945473 ) - weight 967 61 0.199056834 ( -0.2905708849 0.8320210576 -0.929648459 ) - weight 968 56 0.1029800549 ( 1.8417170048 -1.2539637089 0.961512804 ) - weight 969 59 0.312636435 ( -0.4406112432 0.4870167971 1.8586968184 ) - weight 970 60 0.3853267133 ( -0.3334864974 0.7219488621 0.4567943215 ) - weight 971 42 0.1089752018 ( 1.436237812 12.0441226959 -1.1971395016 ) - weight 972 61 0.1114777327 ( -0.8718705177 1.6762108803 -1.8288452625 ) - weight 973 56 0.1125121787 ( 2.429292202 -0.9855142236 -0.2392414957 ) - weight 974 59 0.200916335 ( -1.0242499113 1.0210973024 0.7481815219 ) - weight 975 60 0.1705894917 ( -0.9171251655 1.4062490463 -0.5680078268 ) - weight 976 43 0.2955290675 ( 0.6382633448 2.2174341679 -1.6225725412 ) - weight 977 57 0.4113521576 ( -0.274708271 -0.5439791083 0.3522036374 ) - weight 978 58 0.1280509979 ( 0.9147189856 -1.5797700882 -0.2687080801 ) - weight 979 56 0.3978355229 ( -1.5849891901 -0.7552933097 0.3024401963 ) - weight 980 59 0.0627613515 ( 1.7011916637 3.0641961098 2.9524025917 ) - weight 981 57 0.4471872449 ( -2.109048605 -0.6640021801 0.2943860888 ) - weight 982 58 0.4471872449 ( 0.502586484 0.211697638 -0.2108905166 ) - weight 983 56 0.1056255177 ( -2.7547802925 -2.1733195782 0.2446226478 ) - weight 984 57 0.4538086057 ( -2.4392085075 -0.2685068846 0.3391907215 ) - weight 985 58 0.4538086057 ( 0.0288998783 0.4142889082 -0.2556951344 ) - weight 986 56 0.0923827365 ( -3.2690601349 -2.142683506 0.2894272804 ) - weight 987 42 0.4398242235 ( 0.1740172207 11.539940834 1.6425894499 ) - weight 988 43 0.5601757765 ( 2.2957489491 -0.4316098392 -1.2394688129 ) - weight 989 54 0.3754678667 ( -1.712297678 -0.2952645123 -1.2634038925 ) - weight 990 53 0.203484565 ( -2.5859029293 -1.5587339401 -1.3676148653 ) - weight 991 55 0.3586972952 ( 0.3190882802 -0.2257261574 1.296980381 ) - weight 992 59 0.0623502769 ( -0.5154666901 6.4157423973 1.8140758276 ) - weight 993 54 0.3506007493 ( -0.2756119668 -0.8896455765 -1.206207633 ) - weight 994 53 0.3517852724 ( -1.1421295404 -0.99870646 -1.2175695896 ) - weight 995 55 0.2103818804 ( 1.301230669 -1.4310272932 1.2397841215 ) - weight 996 59 0.0872321427 ( -0.6637560725 5.1893162727 0.8682877421 ) - weight 997 57 0.4189509749 ( -0.1387680918 0.2959415317 0.3316592276 ) - weight 998 58 0.1101265997 ( 0.1492830515 -1.9513264894 -0.2481636703 ) - weight 999 56 0.4187633991 ( -2.1034507751 -0.0806497037 0.2818957865 ) - weight 1000 59 0.0521590374 ( 2.4873962402 3.321105957 2.7517836094 ) - weight 1001 57 0.4472717047 ( -2.0962703228 -0.6473919749 -0.383500576 ) - weight 1002 58 0.4472079277 ( 0.4903485179 0.1946855485 0.4669961631 ) - weight 1003 56 0.1055203751 ( -2.758118391 -2.1526303291 -0.4332640171 ) - weight 1004 57 0.458153218 ( -2.4103233814 -0.2253260463 -0.3625353873 ) - weight 1005 58 0.458153218 ( -0.004159736 0.3742139339 0.4460309446 ) - weight 1006 56 0.0836935341 ( -3.2807073593 -2.0920546055 -0.4122988284 ) - weight 1007 42 0.0842022598 ( 1.8352814913 11.1349878311 -3.1548860073 ) - weight 1008 61 0.1144503951 ( -0.4541496038 -0.4210610688 -1.3333712816 ) - weight 1009 59 0.2114841044 ( -0.4739887714 -0.8368390203 1.7795979977 ) - weight 1010 60 0.2149325013 ( -0.3668640256 -0.5777932405 0.1931250989 ) - weight 1011 43 0.3749307394 ( -1.2663887739 3.2077684402 -1.1642353535 ) - weight 1012 61 0.391025871 ( -0.5596655607 0.4314423501 0.1028550044 ) - weight 1013 56 0.0765034854 ( 1.5556576252 -2.1961464882 1.535446763 ) - weight 1014 59 0.1414447278 ( -0.7476187944 0.3322912455 2.9453177452 ) - weight 1015 60 0.391025871 ( -0.6404940486 0.4166125059 1.5110497475 ) - weight 1016 61 0.380770117 ( -0.4739415944 -0.4192292094 0.1991742998 ) - weight 1017 56 0.0799935088 ( 1.7953228951 -2.2083435059 2.3616912365 ) - weight 1018 59 0.1584662348 ( -0.6003818512 -0.455370903 3.2586510181 ) - weight 1019 60 0.380770117 ( -0.4932571054 -0.4071604908 1.7110184431 ) - weight 1020 61 0.3612612188 ( -0.2179930806 0.6561376452 0.9816073179 ) - weight 1021 56 0.1223678738 ( 0.6934676766 -2.612575531 1.6859425306 ) - weight 1022 59 0.1551097184 ( -0.487142235 0.8003450036 3.7530994415 ) - weight 1023 60 0.3612612188 ( -0.3800174892 0.7669608593 2.3764061928 ) - weight 1024 61 0.3830957711 ( 0.428325057 -0.3355064392 0.2136541158 ) - weight 1025 56 0.0842471495 ( 1.1475819349 -1.6088715792 2.5675294399 ) - weight 1026 59 0.1495613307 ( 0.2889784276 -0.2847376466 3.2936763763 ) - weight 1027 60 0.3830957711 ( 0.3961031735 -0.2431117296 1.7695888281 ) - weight 1028 61 0.3876707852 ( 0.4124973416 0.5091808438 0.0538134724 ) - weight 1029 56 0.0870144144 ( 0.9026433229 -1.5026067495 1.7502112389 ) - weight 1030 59 0.1364208311 ( 0.2161399722 0.4880290329 2.9237811565 ) - weight 1031 60 0.3888939917 ( 0.3232647181 0.5738315582 1.5115298033 ) - weight 1032 61 0.3546818793 ( -0.4107523859 0.1524924338 1.3010743856 ) - weight 1033 56 0.1242041737 ( 0.8372097611 -2.9778051376 2.1746342182 ) - weight 1034 59 0.1664320678 ( -0.6603445411 0.3760493994 4.1807069778 ) - weight 1035 60 0.3546818793 ( -0.5532197952 0.286976248 2.7403972149 ) - weight 1036 61 0.3546818793 ( 0.2100131214 0.1417014152 1.3719371557 ) - weight 1037 56 0.1242041737 ( 0.3828077614 -2.6101620197 2.3956437111 ) - weight 1038 59 0.1664320678 ( -0.0471701473 0.4426954985 4.2810225487 ) - weight 1039 60 0.3546818793 ( 0.059954606 0.3389209807 2.8490557671 ) - weight 1040 42 0.1623037457 ( 1.3273775578 10.9247989655 -1.083214879 ) - weight 1041 59 0.0526776575 ( -1.2089225054 0.1652341187 0.0332619809 ) - weight 1042 43 0.7850186229 ( -0.0941038802 1.4186453819 -1.3011838198 ) - weight 1043 42 0.3177656531 ( -0.0544833131 10.3406953812 -2.1068460941 ) - weight 1044 59 0.0912375301 ( 0.3653004766 -0.6524424553 -0.3563072681 ) - weight 1045 43 0.5909968615 ( -0.5756945014 1.6951096058 0.4280286133 ) - weight 1046 54 0.1751504093 ( 1.2508269548 -0.846034646 -1.3568865061 ) - weight 1047 53 0.2886814177 ( -0.0656189919 0.0936487168 -1.2676413059 ) - weight 1048 55 0.0944228768 ( 1.6980779171 -2.9056222439 1.3904628754 ) - weight 1049 59 0.0766451731 ( -0.440099597 4.4043750763 -0.4311225712 ) - weight 1050 43 0.3651000857 ( 4.2268133163 1.7417582273 -1.349444747 ) - weight 1051 54 0.3702871203 ( 0.170210287 -0.029518513 -1.3050285578 ) - weight 1052 53 0.3747090697 ( -1.4115560055 -0.0653235465 -1.2850040197 ) - weight 1053 55 0.1746840924 ( 0.605484426 -2.1052031517 1.3386049271 ) - weight 1054 59 0.0803197324 ( 0.011231401 5.4944267273 0.2361160517 ) - weight 1055 54 0.3585439324 ( -0.8944928646 -0.0800375193 -1.4609407187 ) - weight 1056 53 0.298817724 ( -2.1365551949 -0.8294889331 -1.5105717182 ) - weight 1057 55 0.267645359 ( 0.3479326963 -1.0708861351 1.4945172071 ) - weight 1058 59 0.0749930069 ( -0.322637707 6.1736660004 1.0026792288 ) - weight 1059 57 0.1885546297 ( 1.3962807655 -0.4736344516 -1.0557357073 ) - weight 1060 58 0.0936132297 ( 1.327496171 -3.2005007267 1.139231205 ) - weight 1061 56 0.2777002156 ( -0.4909772277 0.5097327232 -1.1054991484 ) - weight 1062 59 0.0931945071 ( 1.466070056 3.3255031109 0.7946532369 ) - weight 1063 43 0.3469373882 ( 3.2539691925 3.5805659294 0.0549535342 ) - weight 1064 54 0.1958076358 ( 0.6160579324 -1.6671715975 -1.4606028795 ) - weight 1065 53 0.2703956962 ( 0.0499805696 -0.9325035214 -1.4146213531 ) - weight 1066 55 0.1269296557 ( 2.3021848202 -2.0616717339 1.494179368 ) - weight 1067 59 0.0939889401 ( -1.2468358278 4.3446087837 0.2273299098 ) - weight 1068 43 0.3128781319 ( 3.9263579845 1.9642170668 -2.3231971264 ) - weight 1069 57 0.2179925293 ( 0.7380669117 -1.5039759874 0.5072404742 ) - weight 1070 58 0.1192490458 ( 2.1252479553 -2.2739796638 -0.4237449169 ) - weight 1071 56 0.5142737031 ( -0.1917991042 -0.6757382751 0.4574770331 ) - weight 1072 59 0.148484692 ( 0.9940998554 2.0701665878 2.2572257519 ) - weight 1073 42 0.1142978817 ( 1.0084989071 10.3204240799 -1.8024111986 ) - weight 1074 43 0.8857021332 ( -0.8214198351 1.5628852844 -0.6420922279 ) - weight 1075 57 0.1982116252 ( 1.3632212877 -0.5733952522 -0.4027484059 ) - weight 1076 58 0.0880223513 ( 1.4135501385 -3.1401693821 0.486243993 ) - weight 1077 56 0.4341444969 ( -0.4409892559 0.417286247 -0.452511847 ) - weight 1078 59 0.0933486819 ( 1.6046042442 2.7994074821 1.1707772017 ) - weight 1079 43 0.1862728745 ( 2.6969475746 3.9282062054 0.1343925893 ) - weight 1080 57 0.4346669614 ( -0.2815521359 -0.4752665758 -0.3876489699 ) - weight 1081 58 0.1120185927 ( 0.8469377756 -1.5929591656 0.4711445272 ) - weight 1082 56 0.4031164646 ( -1.6397161484 -0.7131838202 -0.437412411 ) - weight 1083 59 0.0501979589 ( 1.4977709055 3.6665809155 2.5678217411 ) - weight 1084 57 0.4197631776 ( -0.1074579954 0.334723711 -0.4345258474 ) - weight 1085 58 0.1101526022 ( 0.1211333498 -1.9924601316 0.5180214047 ) - weight 1086 56 0.4197631776 ( -2.1102330685 -0.0312697627 -0.4842892885 ) - weight 1087 59 0.0503210165 ( 2.251531601 3.9132869244 2.3237493038 ) - weight 1088 42 0.2956000865 ( 1.0155339241 11.2489490509 0.5217964649 ) - weight 1089 43 0.7043999434 ( 1.1471666098 0.3454690874 -1.5943076611 ) - weight 1090 54 0.3611391187 ( -0.1076610237 0.5141583085 0.9471378326 ) - weight 1091 53 0.3611391187 ( -2.0912144184 0.0294590704 0.9452719688 ) - weight 1092 55 0.1901330203 ( 0.0048906859 -1.995275259 -0.9135614634 ) - weight 1093 59 0.08758872 ( 1.7754977942 4.7407298088 1.5644067526 ) - weight 1094 54 0.3840218186 ( -1.8318221569 0.5598106384 0.4378543496 ) - weight 1095 53 0.1898619235 ( -3.3416888714 -1.1039226055 0.3240273893 ) - weight 1096 55 0.3672960997 ( -0.5342702866 -0.3569464982 -0.4042778909 ) - weight 1097 59 0.0588201806 ( 1.1717028618 6.0578947067 2.6296269894 ) - weight 1098 57 0.2022229135 ( 1.0886839628 -0.5847870708 0.419659704 ) - weight 1099 58 0.0843911693 ( 1.3455737829 -2.8739368916 -0.3361641467 ) - weight 1100 56 0.4396588504 ( -0.620851934 0.2095606178 0.3698962629 ) - weight 1101 59 0.0886885673 ( 1.85600245 2.2983779907 1.83230865 ) - weight 1102 43 0.1850384921 ( 2.1307058334 4.5826253891 0.1888130158 ) - weight 1103 57 0.5435784459 ( -1.3650358915 0.2476766557 -0.0473020934 ) - weight 1104 58 0.2667270303 ( -0.1568530351 -0.7629061341 0.1307976544 ) - weight 1105 56 0.1896944791 ( -2.9087450504 -1.0066970587 -0.0970655307 ) - weight 1106 54 0.4445983768 ( -2.7363064289 -0.1039810553 -0.1953475028 ) - weight 1107 53 0.1108032838 ( -3.5050151348 -2.1777858734 -0.3686475456 ) - weight 1108 55 0.4445983768 ( -0.1583748162 0.7001316547 0.2289239764 ) - weight 1109 54 0.3547707498 ( -0.7836155891 -0.3676508069 1.0745567083 ) - weight 1110 53 0.3089473248 ( -1.9739035368 -1.0797947645 1.0260901451 ) - weight 1111 55 0.245002836 ( 0.6552765369 -1.0944421291 -1.0409802198 ) - weight 1112 59 0.0912791565 ( 1.0589766502 4.5417337418 2.3997125626 ) - weight 1113 54 0.390830338 ( -2.7063946724 -0.4319762588 0.6643019319 ) - weight 1114 53 0.1519301385 ( -3.2959206104 -2.4343471527 0.490380168 ) - weight 1115 55 0.390830338 ( 0.1643826514 0.765730083 -0.6307254434 ) - weight 1116 59 0.0664092004 ( 0.3963106573 5.8552498817 3.705498457 ) - weight 1117 57 0.2896903455 ( 0.3555109501 -1.1664071083 -0.7214585543 ) - weight 1118 58 0.1419114918 ( 1.6919890642 -2.0045571327 0.8049541712 ) - weight 1119 56 0.460752517 ( -0.6998070478 -0.7229577899 -0.7712219954 ) - weight 1120 59 0.1076456532 ( 0.8171212077 3.343362093 1.9142171144 ) - weight 1121 61 0.1539168805 ( 0.3930913508 -0.4617661834 -1.3546860218 ) - weight 1122 56 0.0785421878 ( 2.1868271828 -0.4773238301 2.2262918949 ) - weight 1123 59 0.2862429619 ( 0.3731967211 -0.8003032804 1.8090980053 ) - weight 1124 60 0.2892561853 ( 0.4803214669 -0.5457475781 0.2274499089 ) - weight 1125 43 0.1920417696 ( -1.1052318811 3.6140320301 -0.4369756579 ) - weight 1126 61 0.1109498441 ( 0.7633737922 0.3757760525 -1.5980736017 ) - weight 1127 56 0.0881515816 ( 1.7377837896 -0.0483794622 1.5106170177 ) - weight 1128 59 0.2639667988 ( 0.6906561255 -0.0182783008 1.3784240484 ) - weight 1129 60 0.2584609687 ( 0.7977808714 0.2888723016 -0.0894930288 ) - weight 1130 43 0.2784707844 ( -0.2193055451 3.4443356991 -0.1468698978 ) - weight 1131 42 0.5640378594 ( -1.3495754004 10.2631855011 1.3617348671 ) - weight 1132 43 0.4359621406 ( 1.7584429979 -1.177587986 0.5452261567 ) - weight 1133 41 1 ( 1.0335417986 4.7451124191 -2.4795181751 ) - weight 1134 41 1 ( 2.1582181454 4.8451223373 0.0623746216 ) - weight 1135 41 1 ( -1.6115453243 6.0833845139 -2.4239187241 ) - weight 1136 41 1 ( -2.7681519985 6.0092234612 0.1806515008 ) - weight 1137 41 1 ( -1.64742136 3.7476885319 2.9565672874 ) - weight 1138 41 0.9291076064 ( 1.8564112186 4.1235489845 2.7927827835 ) - weight 1139 19 0.0708923936 ( -10.1063575745 6.157535553 -2.4626765251 ) - weight 1140 42 0.5499851704 ( -1.0540465117 10.9846153259 1.1966712475 ) - weight 1141 43 0.4500148296 ( 2.095708847 -0.5672896504 0.1594398916 ) - weight 1142 42 0.5251870751 ( 0.6296259165 9.7358551025 -0.4174966812 ) - weight 1143 43 0.4748129249 ( -0.354581207 0.0853402987 -0.5954406857 ) - weight 1144 42 0.5051686168 ( -0.7319589853 9.7336530685 -1.3712289333 ) - weight 1145 43 0.4948313832 ( -0.3708435595 0.6732262373 0.9594384432 ) - weight 1146 42 0.5466154814 ( -1.3470586538 10.7120962143 -0.8530399799 ) - weight 1147 43 0.4533844888 ( 0.8749363422 0.8161497116 1.1378307343 ) - weight 1148 42 0.6999999881 ( 1.3786541224 -0.3444491029 2.4536538124 ) - weight 1149 41 0.3000000119 ( 0.8930609822 12.2374820709 2.6172156334 ) - weight 1150 42 0.8526439071 ( -0.1810515076 0.7424882054 2.8618142605 ) - weight 1151 41 0.1473560929 ( -0.7406031489 13.2806510925 2.4634304047 ) - weight 1152 42 0.7815572023 ( 1.5009310246 0.6835593581 2.4828720093 ) - weight 1153 41 0.2184428126 ( 0.9818617702 13.2407283783 2.3759300709 ) - weight 1154 42 1 ( -2.6793735027 3.1888782978 0.9538081884 ) - weight 1155 42 0.8000000119 ( 2.2554078102 3.6080217361 0.329179734 ) - weight 1156 43 0.200000003 ( -5.1281805038 -4.140540123 -0.9205898046 ) - weight 1157 42 0.4014061093 ( 2.042100668 0.2199056745 0.031947922 ) - weight 1158 41 0.5985938907 ( 1.9332448244 12.1681251526 0.264233768 ) - weight 1159 42 0.6914907694 ( 1.0412669182 2.0121896267 -1.2607097626 ) - weight 1160 41 0.3085092306 ( 1.1136412621 13.4657354355 -1.6144281626 ) - weight 1161 42 1 ( 0.8831268549 4.7268471718 2.5912175179 ) - weight 1162 42 1 ( -1.0840609074 3.5433869362 2.6253142357 ) - weight 1163 42 0.8000000119 ( 2.0138523579 3.5670685768 2.2009055614 ) - weight 1164 43 0.200000003 ( -4.0391888618 -5.6402978897 -1.278650403 ) - weight 1165 42 0.6189248562 ( -2.2097096443 -0.0283920001 1.6615819931 ) - weight 1166 41 0.3810751438 ( -2.5216984749 12.0703411102 1.2333415747 ) - weight 1167 42 0.6407603621 ( -1.5726031065 9.6505594254 -0.5109196901 ) - weight 1168 43 0.3592396379 ( 0.3548727632 -0.1358046085 1.4814767838 ) - weight 1169 10 1 ( -1.6849927902 14.6934576035 -2.3159365654 ) - weight 1170 10 0.9403956532 ( -0.4285988212 17.0580463409 -3.7430877686 ) - weight 1171 11 0.0596043728 ( 2.0543029308 -3.6201627254 -2.5218918324 ) - weight 1172 10 0.904577136 ( 3.1261425018 16.2232208252 1.8090498447 ) - weight 1173 11 0.0954229161 ( -2.6651656628 -4.4199619293 2.0874774456 ) - weight 1174 10 0.9326081276 ( 5.2566537857 15.4520292282 -4.4689397812 ) - weight 1175 11 0.0673919022 ( 3.9033098221 -3.8598277569 3.1307160854 ) - weight 1176 10 1 ( -1.6966485977 15.9101800919 0.0456484966 ) - weight 1177 10 0.9412561059 ( 2.658706665 15.479475975 -5.3927006721 ) - weight 1178 11 0.0587438978 ( 4.400739193 -4.2636361122 0.4487544298 ) - weight 1179 10 1 ( 0.7746815085 14.7094078064 -4.8422560692 ) - weight 1180 10 0.8995265365 ( 6.7275528908 15.5478363037 -0.8667061329 ) - weight 1181 11 0.1004734635 ( 0.605142951 -3.9406995773 5.1957502365 ) - weight 1182 10 1 ( 1.5113474131 15.4343090057 2.8393585682 ) - weight 1183 11 1 ( -2.5063192844 2.5638833046 2.8407478333 ) - weight 1184 10 0.3169560134 ( 1.5655978918 22.0227355957 1.0274738073 ) - weight 1185 12 0.0565896407 ( -5.6761398315 -7.1478953362 15.1385908127 ) - weight 1186 11 0.6264543533 ( -3.1295845509 0.9628543258 -0.6493313909 ) - weight 1187 10 1 ( 0.119486548 16.1317272186 1.8133599758 ) - weight 1188 10 1 ( -1.2945282459 15.0852165222 2.3647434711 ) - weight 1189 10 1 ( -2.3863928318 13.2970666885 1.6892609596 ) - weight 1190 10 1 ( 6.9525694847 11.5392379761 -3.3982434273 ) - weight 1191 10 1 ( 3.1568915844 13.8209323883 -6.0673203468 ) - weight 1192 10 1 ( -0.0549013168 13.6309070587 -5.5924086571 ) - weight 1193 10 1 ( 3.6119086742 13.6178913116 3.981960535 ) - weight 1194 3 0.5315479636 ( -3.7084290981 -2.7477302551 4.6042766571 ) - weight 1195 10 0.4684520066 ( -4.0784015656 1.0405266285 0.0474926233 ) - weight 1196 10 1 ( 5.6332411766 8.6346216202 0.2461977303 ) - weight 1197 3 0.1597939581 ( -3.6681900024 -8.4924659729 4.7243947983 ) - weight 1198 10 0.840206027 ( -4.1791987419 6.6890072823 -1.0025258064 ) - weight 1199 3 0.1570782363 ( -11.3637037277 -9.3978271484 -0.9165611267 ) - weight 1200 10 0.8429217935 ( 3.8321042061 8.4964723587 3.9384343624 ) - weight 1201 3 0.2233601809 ( -6.7271490097 -7.6255226135 3.8477036953 ) - weight 1202 10 0.7766398191 ( -2.276668787 6.2962594032 1.6627204418 ) - weight 1203 10 0.1138286591 ( 5.211165905 22.3286933899 -5.7917032242 ) - weight 1204 11 0.8861713409 ( 4.0140914917 2.9623498917 1.5540436506 ) - weight 1205 10 0.1005637199 ( 7.7498230934 21.6939086914 -3.6153414249 ) - weight 1206 11 0.899436295 ( 2.3915333748 2.5962033272 4.5234746933 ) - weight 1207 3 0.3695607185 ( -7.080242157 -6.6127700806 -4.0962405205 ) - weight 1208 10 0.6304392815 ( 5.2696847916 4.809689045 -0.595430851 ) - weight 1209 3 0.3345544934 ( -4.455555439 -8.2828369141 -6.0770320892 ) - weight 1210 10 0.6654455066 ( 6.196041584 5.867521286 -4.004901886 ) - weight 1211 10 1 ( 6.4914097786 13.6719141006 -0.2744376659 ) - weight 1212 10 1 ( 7.1505594254 14.5899686813 -1.6787887812 ) - weight 1213 3 0.7712626457 ( -0.8684953451 -6.4339332581 4.6402726173 ) - weight 1214 10 0.2287374139 ( -5.104631424 4.1834950447 -3.2271392345 ) - weight 1215 3 0.8643651009 ( -6.8744492531 2.0751686096 -1.6135793924 ) - weight 1216 10 0.0835514218 ( 2.8369584084 -3.5931971073 1.6760400534 ) - weight 1217 17 0.0520835221 ( -6.8443698883 1.6937704086 -1.002052784 ) - weight 1218 3 0.5887928009 ( -3.2489125729 1.4852218628 6.7376856804 ) - weight 1219 18 0.0889219642 ( -3.1671557426 -0.9419174194 0.1858739853 ) - weight 1220 10 0.0542748906 ( -6.2548370361 -3.0505545139 1.1459712982 ) - weight 1221 17 0.2680103779 ( -2.7453994751 -0.8374544978 6.7456903458 ) - weight 1222 10 0.7540852427 ( 0.9677019715 19.2001876831 1.9965788126 ) - weight 1223 11 0.2459147424 ( -3.6841902733 -2.0269157887 -0.5185301304 ) - weight 1224 10 0.8188053966 ( -0.9152092338 19.0957641602 0.9450861812 ) - weight 1225 11 0.1811946183 ( -2.930665493 -2.388092041 -2.5094213486 ) - weight 1226 10 0.5160198808 ( -1.2482904196 22.2275371552 -0.0536809936 ) - weight 1227 12 0.0719461441 ( -8.4814491272 -6.0503139496 14.9054317474 ) - weight 1228 13 0.0643709078 ( -4.6499772072 2.3647470474 19.786272049 ) - weight 1229 11 0.3476630747 ( -2.542121172 0.7057752013 -3.6018900871 ) - weight 1230 10 0.4836156964 ( 0.1837037355 22.0717411041 1.8777666092 ) - weight 1231 12 0.0802049935 ( -6.380730629 -6.0332899094 16.0852890015 ) - weight 1232 13 0.0719838515 ( -2.3048567772 2.5962285995 20.2884635925 ) - weight 1233 11 0.364195466 ( -4.1769366264 0.5995609164 -1.8351233006 ) - weight 1234 10 0.7654910684 ( -1.3294299841 19.4409217834 -0.8088459969 ) - weight 1235 11 0.2345089465 ( -1.3452800512 -1.9051021338 -3.2969896793 ) - weight 1236 3 0.6883750558 ( -6.3025302887 -1.5085716248 3.5197236538 ) - weight 1237 10 0.311624974 ( -2.1484274864 0.1884137243 2.2813756466 ) - weight 1238 3 0.7614241242 ( -6.0205597878 1.2947502136 3.6651484966 ) - weight 1239 10 0.1037384644 ( -2.3971335888 -2.6050794125 2.5876603127 ) - weight 1240 17 0.1348374039 ( -5.6888580322 -0.3215859234 3.8771150112 ) - weight 1241 3 0.6358070374 ( -2.6010766029 0.9662094116 5.8599977493 ) - weight 1242 18 0.064063333 ( -2.5193197727 -1.4609298706 -0.6918139458 ) - weight 1243 10 0.1110867634 ( -5.6623063087 -2.7114448547 0.1493203938 ) - weight 1244 17 0.1890428066 ( -2.1490161419 -1.1210991144 5.7341198921 ) - weight 1245 3 1 ( -3.633108139 1.987323761 -10.4137458801 ) - weight 1246 3 1 ( -3.2783942223 3.7895317078 -8.8841781616 ) - weight 1247 14 0.3419183493 ( 0.3669503629 -0.4382508099 3.0293495655 ) - weight 1248 12 0.1897278875 ( -1.2495909929 6.7487959862 5.1507711411 ) - weight 1249 13 0.3454541266 ( 0.3782851398 4.6323928833 3.0278494358 ) - weight 1250 11 0.1228995919 ( -7.1759438515 17.6962985992 -4.6602797508 ) - weight 1251 12 0.2685072422 ( 1.5178449154 -1.919683218 0.7841451764 ) - weight 1252 13 0.0952559859 ( 1.1915769577 -5.2674460411 4.8168168068 ) - weight 1253 11 0.6362367868 ( 0.0919061899 17.2687797546 2.3300161362 ) - weight 1254 14 0.1366661787 ( 2.1555314064 -11.5644826889 -1.1183812618 ) - weight 1255 10 0.0630767867 ( 10.1741771698 42.5737037659 -4.751496315 ) - weight 1256 12 0.2826185524 ( 4.0506262779 1.0991520882 -4.0244646072 ) - weight 1257 13 0.2313687354 ( 2.4571859837 -6.428853035 -1.1581681967 ) - weight 1258 11 0.2862697542 ( 0.3158197105 23.4682483673 2.7393009663 ) - weight 1259 14 0.1375834495 ( 2.3870379925 -7.9236841202 -1.0619370937 ) - weight 1260 10 0.0536330454 ( 7.6081728935 43.0057678223 -2.1939306259 ) - weight 1261 12 0.3056590557 ( 3.3201818466 3.8555674553 -1.7483226061 ) - weight 1262 13 0.2899672687 ( 2.5934128761 -2.7834627628 -1.0891140699 ) - weight 1263 11 0.2131572068 ( -2.639742136 22.9910087585 0.6538530588 ) - weight 1264 14 0.1259461194 ( 1.7246651649 -7.6629319191 -0.4134772122 ) - weight 1265 12 0.3496141732 ( 2.5099084377 3.5790083408 -1.3076394796 ) - weight 1266 13 0.3076890707 ( 1.9244483709 -2.5423638821 -0.4398162663 ) - weight 1267 11 0.2167506218 ( -2.4270832539 22.2102661133 0.131888777 ) - weight 1268 14 0.4093997777 ( 1.3893353939 1.0698413849 -0.2118686438 ) - weight 1269 12 0.1142960414 ( -0.0998471379 10.0690994263 3.934718132 ) - weight 1270 13 0.4093997777 ( 1.360886693 6.1779050827 -0.2080423683 ) - weight 1271 11 0.0669044331 ( -8.9501237869 20.8472824097 -5.525551796 ) - weight 1272 12 0.2735842466 ( 1.3469898701 -3.0556550026 -0.1221179813 ) - weight 1273 13 0.1103651822 ( 0.6931102276 -6.640879631 4.8952159882 ) - weight 1274 11 0.6160505414 ( 1.4794056416 17.2679748535 2.7945382595 ) - weight 1275 11 1 ( -3.6778619289 6.7451229095 0.2963678837 ) - weight 1276 12 0.0956912264 ( 0.0341475643 0.7731609344 5.787250042 ) - weight 1277 13 0.0765797049 ( 1.3765591383 0.1397344619 7.0997986794 ) - weight 1278 11 0.8277291059 ( -4.3140869141 14.4269971848 -0.3148512244 ) - weight 1279 11 1 ( -3.095010519 12.9006528854 -0.8128241897 ) - weight 1280 11 1 ( -2.8474400043 6.9351949692 3.1603405476 ) - weight 1281 11 1 ( -4.5009741783 3.911593914 -1.5457384586 ) - weight 1282 11 1 ( 2.4113123417 12.7546291351 3.254576683 ) - weight 1283 11 1 ( -0.293667376 11.0580587387 3.5046823025 ) - weight 1284 11 1 ( 0.1792610288 14.2760639191 4.3541769981 ) - weight 1285 11 1 ( 3.2645583153 8.573636055 3.8410058022 ) - weight 1286 11 1 ( -0.8646838665 7.5920219421 5.1901907921 ) - weight 1287 11 1 ( -2.9699668884 13.0791387558 0.8224024177 ) - weight 1288 11 1 ( -2.3151631355 10.4546642303 2.012827158 ) - weight 1289 11 1 ( -2.8824694157 9.9796628952 0.1445998549 ) - weight 1290 11 1 ( -2.8276472092 6.8315811157 -2.0883891582 ) - weight 1291 14 0.2966812253 ( -2.9165189266 -0.7702693343 2.6949472427 ) - weight 1292 10 0.0511751026 ( -1.2781329155 39.4977264404 -0.7309015393 ) - weight 1293 12 0.2075200379 ( -4.2246179581 6.4199142456 3.7209875584 ) - weight 1294 13 0.3035651743 ( -2.8953795433 4.2157902718 2.692003727 ) - weight 1295 11 0.1410585046 ( -4.8256788254 17.4988193512 -6.9927649498 ) - weight 1296 14 0.1384337842 ( -2.6931784153 -8.5320053101 -1.600905776 ) - weight 1297 10 0.0557335392 ( 4.6876044273 42.7773284912 -6.4232606888 ) - weight 1298 12 0.2976273596 ( -1.2545865774 3.2885317802 -4.0328583717 ) - weight 1299 13 0.2733933926 ( -2.4691598415 -3.5225453377 -1.6306425333 ) - weight 1300 11 0.2348119766 ( 1.0698370934 22.7185516357 -2.9005703926 ) - weight 1301 14 0.1359871626 ( -1.7564687729 -12.0300092697 -1.5332176685 ) - weight 1302 10 0.0645252243 ( 7.9230308533 42.3979682922 -8.0063400269 ) - weight 1303 12 0.2867776155 ( 0.527058959 0.6645986438 -5.7817873955 ) - weight 1304 13 0.2278146148 ( -1.4413039684 -6.9950733185 -1.5749657154 ) - weight 1305 11 0.2848953605 ( 3.1701207161 23.2578849792 0.0004579568 ) - weight 1306 14 0.399825573 ( -1.2467964888 1.7394410372 0.0298730265 ) - weight 1307 12 0.124025479 ( -2.8195898533 10.1902093887 3.7241816521 ) - weight 1308 13 0.399825573 ( -1.2918527126 6.7775058746 0.035774827 ) - weight 1309 11 0.0763233975 ( -7.7913370132 20.0715503693 -7.8731989861 ) - weight 1310 10 0.0657113343 ( 9.7584638596 40.4407806396 -6.6602673531 ) - weight 1311 12 0.3502906263 ( 2.1879394054 -1.1135326624 -4.0236539841 ) - weight 1312 13 0.2138165981 ( 0.5239654779 -7.688990593 0.5854744911 ) - weight 1313 11 0.3701814711 ( 2.4733190536 21.5745372772 2.3862726688 ) - weight 1314 14 0.1344955564 ( 0.2851388454 -12.6184740067 -1.2383886576 ) - weight 1315 10 0.0643899217 ( 9.7185783386 42.3084411621 -6.8361382484 ) - weight 1316 12 0.289381355 ( 2.566993475 0.2080290914 -5.3005518913 ) - weight 1317 13 0.2225397527 ( 0.6149929166 -7.5309691429 -1.2819886208 ) - weight 1318 11 0.2891934514 ( 2.3206753731 23.3966636658 1.9652886391 ) - weight 1319 14 0.1298304945 ( -2.2184169292 -8.1335287094 -0.8305488825 ) - weight 1320 12 0.3379357457 ( -1.0414862633 3.1392762661 -3.0789489746 ) - weight 1321 13 0.2891643643 ( -2.0049800873 -3.1144580841 -0.8588693738 ) - weight 1322 11 0.2430694252 ( 0.4509409964 21.9973697662 -2.6276323795 ) - weight 1323 11 1 ( -1.3312017918 12.8150424957 -2.3167870045 ) - weight 1324 12 0.1169090569 ( -2.4928781986 1.0149047375 5.5034899712 ) - weight 1325 13 0.0972699225 ( -1.1043463945 0.7429358363 7.1777420044 ) - weight 1326 11 0.7858210206 ( -3.2615411282 13.8431282043 -2.5678629875 ) - weight 1327 12 0.1265636981 ( -3.8623178005 0.3303876221 3.5602760315 ) - weight 1328 13 0.0935955346 ( -3.0123860836 -0.6275841594 6.4024562836 ) - weight 1329 11 0.7798407674 ( -0.9950281978 14.4285335541 -3.3680050373 ) - weight 1330 11 1 ( 0.9043842554 7.9835419655 -2.5395736694 ) - weight 1331 11 1 ( -1.9763872623 3.8007674217 -3.3755655289 ) - weight 1332 11 1 ( 3.5847706795 14.2709589005 0.9767425656 ) - weight 1333 11 1 ( 4.1460995674 7.8940286636 0.9198462367 ) - weight 1334 11 1 ( 0.2862447202 10.2586708069 -1.9215801954 ) - weight 1335 11 1 ( 0.5140500069 13.2254562378 -1.7709983587 ) - weight 1336 11 1 ( -1.820478797 9.6878490448 -1.5225719213 ) - weight 1337 11 1 ( -1.0010864735 6.5364975929 -2.7328279018 ) - weight 1338 11 1 ( 1.8100532293 11.2986927032 2.7190880775 ) - weight 1339 11 1 ( 3.6625311375 6.7157349586 -0.9565432668 ) - weight 1340 14 0.1922333688 ( -0.0791094154 -3.3583660126 3.1387441158 ) - weight 1341 10 0.0512588583 ( 2.5395216942 39.1178855896 -0.2541119456 ) - weight 1342 12 0.2532799244 ( -0.9382084012 4.4156165123 3.3626646996 ) - weight 1343 13 0.2829594612 ( 0.0087337457 1.701251626 3.1271054745 ) - weight 1344 11 0.2202683389 ( -4.6415638924 17.8830871582 -3.1503007412 ) - weight 1345 14 0.3828782439 ( -1.2835776806 0.8457915783 1.7915967703 ) - weight 1346 12 0.1435996592 ( -2.9324240685 8.3751602173 4.4965138435 ) - weight 1347 13 0.3828782439 ( -1.3052539825 5.8771119118 1.7943946123 ) - weight 1348 11 0.0906439275 ( -7.1003141403 18.4577484131 -6.9666867256 ) - weight 1349 14 0.110683158 ( 1.9422931671 -7.7711796761 1.2468053102 ) - weight 1350 12 0.3652938306 ( 2.4536631107 2.4496531487 -0.0678769946 ) - weight 1351 13 0.2478968799 ( 2.1448323727 -2.650626421 1.2201017141 ) - weight 1352 11 0.2761261463 ( -2.5024123192 20.6397571564 0.717931807 ) - weight 1353 14 0.2349759191 ( 1.2158315182 -3.1606059074 2.9088346958 ) - weight 1354 12 0.2830759585 ( 0.2812313437 4.8285355568 3.696287632 ) - weight 1355 13 0.3306698203 ( 1.2980607748 1.9335983992 2.897998333 ) - weight 1356 11 0.1512783021 ( -5.6155743599 18.305891037 -2.3494391441 ) - weight 1357 14 0.2033683956 ( -3.2655110359 -3.7532708645 2.2554764748 ) - weight 1358 10 0.0530604012 ( 0.720112443 39.5088729858 -3.0156598091 ) - weight 1359 12 0.2773667574 ( -3.7085859776 4.3999233246 1.514955759 ) - weight 1360 13 0.2864736021 ( -3.1662523746 1.2262212038 2.2421891689 ) - weight 1361 11 0.1797308028 ( -2.2978961468 18.246465683 -5.4879159927 ) - weight 1362 12 0.0615476109 ( 1.9061925411 -3.2585310936 3.0582387447 ) - weight 1363 11 0.938452363 ( -0.7103455067 14.9688072205 3.4169156551 ) - weight 1364 12 0.0809971318 ( -2.3145854473 -3.6210093498 0.8336309195 ) - weight 1365 11 0.919002831 ( 2.6869492531 14.89311409 0.0482520908 ) - weight 1366 3 0.0533679463 ( -9.1839742661 -21.6981430054 3.4954879284 ) - weight 1367 10 0.6396594048 ( -1.0112993717 20.5228595734 1.2139863968 ) - weight 1368 12 0.061288029 ( -8.1112995148 -6.8663516045 16.8460865021 ) - weight 1369 11 0.2456846833 ( -3.4499258995 -1.0644624233 -2.820086956 ) - weight 1370 11 1 ( -2.7164390087 3.6640803814 2.4920113087 ) - weight 1371 11 1 ( -0.6635105014 3.2638678551 4.1694312096 ) - weight 1372 11 1 ( 1.6430124044 3.6057276726 4.9151535034 ) - weight 1373 11 1 ( 3.8401358128 3.4907150269 2.6510391235 ) - weight 1374 11 1 ( 1.5595271587 3.6472010612 -1.6532646418 ) - weight 1375 11 1 ( 3.1931664944 3.2276203632 0.4085057974 ) - weight 1376 10 0.3634209931 ( -0.0680550486 22.2574100494 -0.663012743 ) - weight 1377 11 0.6365789771 ( -1.773591876 1.0696103573 -2.5810472965 ) - weight 1378 10 0.4564194679 ( 4.1044239998 20.8365364075 1.2019636631 ) - weight 1379 12 0.0577177703 ( -3.8111641407 -9.2337141037 15.3717765808 ) - weight 1380 11 0.4858627915 ( -2.7095005512 0.3345331848 2.0547199249 ) - weight 1381 10 0.4585791528 ( 0.852193594 21.1884441376 -3.6097130775 ) - weight 1382 11 0.5414208174 ( 1.4175457954 0.63150388 -2.0358023643 ) - weight 1383 10 0.8924157023 ( -1.4040119648 18.2080917358 0.0390574634 ) - weight 1384 11 0.1075842753 ( -1.9723596573 -3.2286121845 -2.9816038609 ) - weight 1385 10 0.9044622183 ( -0.1796224415 18.1517848969 1.9579150677 ) - weight 1386 11 0.0955377892 ( -3.643584013 -3.2812650204 -1.4361100197 ) - weight 1387 10 0.899338901 ( -1.511762023 18.264005661 -2.0685203075 ) - weight 1388 11 0.1006611288 ( 0.0533597209 -2.9119946957 -3.4844305515 ) - weight 1389 10 0.8887832165 ( 2.0148794651 17.9171543121 2.2762110233 ) - weight 1390 11 0.1112167835 ( -3.5780289173 -3.0821256638 0.7838557959 ) - weight 1391 10 0.7029593587 ( 4.4985327721 17.3556671143 -4.629655838 ) - weight 1392 11 0.2970406115 ( 3.6199891567 -2.1585302353 2.012803793 ) - weight 1393 10 0.6722762585 ( 5.7576546669 17.3276596069 -0.9805759192 ) - weight 1394 11 0.3277237117 ( 0.2649064064 -2.4108154774 3.905349493 ) - weight 1395 10 0.082892105 ( 7.1251120567 21.852804184 -0.4724406004 ) - weight 1396 11 0.9171078801 ( -0.7905869484 2.19049263 4.4701228142 ) - weight 1397 11 1 ( -1.8917527199 3.5153164864 -2.187949419 ) - weight 1398 10 0.0504284985 ( 2.6280670166 24.2702636719 0.844360292 ) - weight 1399 11 0.9495715499 ( -3.1712789536 3.3891775608 -0.0792674273 ) - weight 1400 10 0.3544838727 ( 6.2592349052 19.6429786682 -0.6940672994 ) - weight 1401 11 0.6455160975 ( -0.3312421739 -0.1024769619 4.0080838203 ) - weight 1402 10 0.37576738 ( 5.8675837517 19.3834552765 -3.4571743011 ) - weight 1403 11 0.6242326498 ( 2.3428924084 -0.0629095808 3.1696677208 ) - weight 1404 10 0.4359205365 ( 3.4602680206 19.6628627777 -5.1817326546 ) - weight 1405 11 0.5640794635 ( 3.6061658859 -0.0736951232 0.4768321514 ) - weight 1406 10 0.7468539476 ( 4.5810675621 18.0081958771 0.9103237391 ) - weight 1407 11 0.2531460226 ( -1.8715236187 -2.2602450848 2.9910285473 ) - weight 1408 10 0.1569684148 ( 1.6181312799 22.2772731781 -4.3013248444 ) - weight 1409 11 0.8430315852 ( 2.0226707458 1.942358613 -1.6283502579 ) - weight 1410 10 0.7683759332 ( 0.8685053587 18.4085464478 -4.3960752487 ) - weight 1411 11 0.2316240966 ( 2.6585123539 -1.9478107691 -1.6438854933 ) - weight 1412 10 0.1898822337 ( 4.4676308632 21.9451751709 1.0220328569 ) - weight 1413 11 0.8101177812 ( -2.6674313545 1.5091071129 2.164182663 ) - weight 1414 10 0.1646438986 ( 1.9500399828 23.1016807556 1.0254653692 ) - weight 1415 11 0.8353561163 ( -3.2524223328 2.0891342163 -0.4810263216 ) - weight 1416 10 0.1855769753 ( 0.3609091341 23.2489681244 -1.2300875187 ) - weight 1417 11 0.814422965 ( -1.3246691227 2.1974320412 -2.4575355053 ) - weight 1418 3 1 ( -3.5605592728 -0.9402542114 -10.0702943802 ) - weight 1419 10 0.0601788051 ( 3.4902629852 36.6057510376 0.3293388188 ) - weight 1420 12 0.2376018465 ( -0.5351467729 2.3373126984 5.1157579422 ) - weight 1421 13 0.2127243578 ( 0.7489173412 1.0672719479 5.6971912384 ) - weight 1422 11 0.4894949496 ( -4.6367964745 15.5770235062 -1.6545778513 ) - weight 1423 10 0.060934145 ( 1.4594416618 36.3832702637 -2.4643621445 ) - weight 1424 12 0.2387989759 ( -3.6600496769 1.9614058733 3.6762526035 ) - weight 1425 13 0.2052899748 ( -2.6740829945 0.6437221169 5.4105315208 ) - weight 1426 11 0.494976908 ( -2.1897764206 15.306063652 -4.0871014595 ) - weight 1427 10 0.0554431565 ( 2.5570304394 35.7494316101 -2.3181035519 ) - weight 1428 12 0.1900095195 ( -2.8509235382 1.0017402172 3.9047307968 ) - weight 1429 13 0.1447647959 ( -1.9012364149 -0.1424336433 6.0528030396 ) - weight 1430 11 0.6097825766 ( -2.056520462 14.907752037 -2.8823459148 ) - weight 1431 10 0.0563864931 ( 3.622808218 35.8735618591 -0.7370122075 ) - weight 1432 12 0.18486543 ( -1.1518340111 1.2555338144 4.7412858009 ) - weight 1433 13 0.1450792402 ( -0.0213944279 0.1579834968 6.2173757553 ) - weight 1434 11 0.613668859 ( -3.4538800716 15.0415077209 -1.5859524012 ) - weight 1435 14 0.1798899919 ( -1.1350722313 -2.8516843319 4.2000880241 ) - weight 1436 10 0.0563826486 ( 1.4542510509 37.9963760376 -0.5043784976 ) - weight 1437 12 0.1984419227 ( -2.2582900524 4.0263023376 4.1398730278 ) - weight 1438 13 0.2166175842 ( -1.0601167679 2.1764745712 4.1900992393 ) - weight 1439 11 0.34866786 ( -4.3730392456 16.5999488831 -4.0332989693 ) - weight 1440 14 0.1518875808 ( 1.6877616644 -4.1201024055 3.9882357121 ) - weight 1441 10 0.0506135561 ( 4.279364109 38.4245300293 0.7029228806 ) - weight 1442 12 0.2189562321 ( 0.7882741094 3.44658494 4.0725574493 ) - weight 1443 13 0.2083445042 ( 1.7949187756 0.9830420017 3.9741177559 ) - weight 1444 11 0.3701981008 ( -5.1892766953 17.4546756744 -1.1653107405 ) - weight 1445 14 0.1440035552 ( -3.2313790321 -4.4157547951 3.3988380432 ) - weight 1446 10 0.0515459254 ( 1.2325453758 38.3064880371 -3.213160038 ) - weight 1447 12 0.2207396328 ( -3.7053983212 3.1642713547 1.9845076799 ) - weight 1448 13 0.2018170059 ( -3.1148092747 0.5609054565 3.383256197 ) - weight 1449 11 0.381893903 ( -1.8227236271 17.2195777893 -4.8045129776 ) - weight 1450 14 0.0948143303 ( 1.5524858236 -6.9375123978 3.5187041759 ) - weight 1451 12 0.3026814759 ( 1.469835639 1.5909121037 2.0065200329 ) - weight 1452 13 0.1746111363 ( 1.7333594561 -1.8353008032 3.4948346615 ) - weight 1453 11 0.4278930128 ( -2.9248640537 18.2475280762 0.3904457688 ) - weight 1454 10 1 ( 6.1343255043 13.8640575409 -5.2130761147 ) - weight 1455 10 0.0527953431 ( 9.2874002457 39.4993515015 -4.3842930794 ) - weight 1456 12 0.3593078852 ( 2.6792225838 -0.5588554144 -1.6279861927 ) - weight 1457 13 0.1767944098 ( 1.7115222216 -5.94217062 1.9369846582 ) - weight 1458 11 0.4111023843 ( 0.3458356559 20.2546596527 2.5276625156 ) - weight 1459 10 0.0526544414 ( 7.4981589317 39.3585510254 -6.9713773727 ) - weight 1460 12 0.3562460542 ( -0.1217024997 -0.9051147699 -3.0241017342 ) - weight 1461 13 0.1673136055 ( -1.387262702 -6.3924188614 1.6067962646 ) - weight 1462 11 0.4237859547 ( 2.6147520542 20.0863857269 0.3509867489 ) - weight 1463 14 0.1586259156 ( 1.2128635645 -4.8810110092 3.3125350475 ) - weight 1464 12 0.3140856624 ( 0.652079165 3.2590801716 2.973751545 ) - weight 1465 13 0.2688274682 ( 1.3400794268 0.2123178691 3.2957470417 ) - weight 1466 11 0.2584610283 ( -4.2919692993 18.1293678284 -1.1919915676 ) - weight 1467 3 0.7255700827 ( -2.3333964348 -2.6678695679 5.0437517166 ) - weight 1468 10 0.2232849449 ( -4.9781455994 0.758648932 -1.0485167503 ) - weight 1469 17 0.0511449911 ( -1.928634882 -4.4480805397 4.0527319908 ) - weight 1470 12 0.2369382977 ( 1.0240170956 0.0698143691 3.2786018848 ) - weight 1471 13 0.1333481669 ( 1.56341362 -2.1334505081 5.4980597496 ) - weight 1472 11 0.6297135353 ( -2.6152739525 16.2955341339 0.8643248081 ) - weight 1473 14 0.3436497748 ( -3.5996608734 0.4676597714 -0.7407954335 ) - weight 1474 12 0.1936228126 ( -4.5912995338 9.5083684921 1.6886309385 ) - weight 1475 13 0.3436497748 ( -3.6106579304 5.4473104477 -0.7394995093 ) - weight 1476 11 0.1190775856 ( -5.3034687042 20.5799674988 -9.0130901337 ) - weight 1477 12 0.2668638527 ( -2.9413030148 -0.4308901727 1.2598179579 ) - weight 1478 13 0.1345758885 ( -2.8363058567 -2.8042650223 5.0056824684 ) - weight 1479 11 0.5985602736 ( 0.6313707232 16.083398819 -2.2120778561 ) - weight 1480 14 0.1060122997 ( -2.3864498138 -8.2438898087 0.8293873072 ) - weight 1481 12 0.3735997975 ( -1.4635146856 1.9743751287 -1.9561399221 ) - weight 1482 13 0.2299160063 ( -2.1700699329 -3.234916687 0.8006600738 ) - weight 1483 11 0.290471822 ( 0.6227460504 20.360956192 -2.3302419186 ) - weight 1484 14 0.2039621919 ( 2.5389065742 -3.8758919239 -0.7777547836 ) - weight 1485 12 0.3159117997 ( 2.3690335751 6.7685694695 0.9159182906 ) - weight 1486 13 0.3476153314 ( 2.6393868923 1.2659091949 -0.7909229398 ) - weight 1487 11 0.132510677 ( -5.8612308502 22.2259292603 -1.6967020035 ) - weight 1488 14 0.1993993074 ( -3.6622233391 -4.6208343506 -1.4357668161 ) - weight 1489 12 0.3147033155 ( -3.2144832611 6.0746736526 -1.8742032051 ) - weight 1490 13 0.3161017895 ( -3.5401434898 0.3613546491 -1.452067852 ) - weight 1491 11 0.1697955579 ( -1.3313069344 21.893781662 -6.0339126587 ) - weight 1492 3 1 ( -2.4393417835 -1.5507469177 -9.3843774796 ) - weight 1493 3 1 ( -2.0570471287 -2.5874023438 -9.0592861176 ) - weight 1494 3 1 ( -2.8372831345 -2.4603347778 -7.1695895195 ) - weight 1495 3 1 ( -4.9008808136 0.2130050659 -8.0067882538 ) - weight 1496 3 1 ( -4.3490715027 0.8817405701 -8.5133266449 ) - weight 1497 3 1 ( -4.3093891144 3.043712616 -8.4343519211 ) - weight 1498 3 1 ( -7.3951106071 0.2782669067 -3.2532851696 ) - weight 1499 3 1 ( -8.5496740341 0.7149887085 -4.0596828461 ) - weight 1500 3 1 ( -7.9788990021 3.1995353699 -3.3510596752 ) - weight 1501 3 0.8062427044 ( -6.7701330185 3.3089599609 -2.7425200939 ) - weight 1502 10 0.0705318451 ( 3.8496081829 -4.9020571709 1.4132546186 ) - weight 1503 17 0.123225458 ( -6.8050332069 3.1642122269 -1.8044763803 ) - weight 1504 3 1 ( -7.160451889 1.2705993652 -6.9593849182 ) - weight 1505 3 0.7432190776 ( -3.7306587696 -1.8947105408 5.8403820992 ) - weight 1506 10 0.1904809624 ( -5.2297539711 0.2915550768 0.6553769708 ) - weight 1507 17 0.0662999451 ( -3.2778615952 -3.9086441994 5.0887494087 ) - weight 1508 3 0.9007977247 ( -5.7466959953 3.8326377869 -4.9486117363 ) - weight 1509 17 0.0992022604 ( -5.9099268913 4.2172689438 -3.8728957176 ) - weight 1510 3 0.7015556693 ( -6.2323412895 1.7132644653 4.4671297073 ) - weight 1511 17 0.2984443307 ( -5.8542518616 -0.1112374216 4.7668218613 ) - weight 1512 3 0.7783125639 ( -7.4737606049 1.7016983032 2.1003034115 ) - weight 1513 10 0.1209196001 ( -0.4198827147 -2.8665041924 3.4526894093 ) - weight 1514 17 0.1007678807 ( -7.229493618 0.429680258 2.539886713 ) - weight 1515 3 0.0681025982 ( -0.9762268066 -10.5221939087 0.4071492553 ) - weight 1516 10 0.9318974018 ( -1.0911831856 7.9268498421 -5.3541893959 ) - weight 1517 3 0.5049455166 ( -1.6513501406 -6.3452148438 3.1895129681 ) - weight 1518 10 0.4950544536 ( -3.470788002 4.1287879944 -2.9969239235 ) - weight 1519 3 0.1718951166 ( -0.3147409856 -7.1571731567 -3.813833952 ) - weight 1520 10 0.8281048536 ( 2.6041424274 4.2137522697 -6.8153886795 ) - weight 1521 3 0.7416662574 ( -3.9283571243 -4.9997177124 -5.656545639 ) - weight 1522 10 0.2583337426 ( 5.6009368896 2.5797681808 -3.7400445938 ) - weight 1523 3 0.8021942973 ( -6.6330957413 -4.0208969116 -3.9222574234 ) - weight 1524 10 0.1978057176 ( 4.9365406036 2.1979351044 -0.4698399007 ) - weight 1525 3 0.6507291198 ( -9.0773057938 -3.2442054749 -0.5589654446 ) - weight 1526 10 0.3492708504 ( 2.6578006744 2.0834922791 3.0915350914 ) - weight 1527 3 0.8790286183 ( -9.0366792679 -1.4263534546 -0.2203686833 ) - weight 1528 10 0.1209713668 ( 2.3187110424 0.3131501973 3.5060126781 ) - weight 1529 3 1 ( -4.5356354713 -2.2324028015 -7.1859068871 ) - weight 1530 3 0.7236207724 ( -0.8121445775 -5.7375869751 -4.7804937363 ) - weight 1531 10 0.2763792276 ( 3.6780810356 2.8358564377 -6.4344353676 ) - weight 1532 3 0.278526336 ( -2.505641222 -8.2148284912 -5.7358665466 ) - weight 1533 10 0.7214736938 ( 5.183968544 5.4926986694 -5.6657452583 ) - weight 1534 3 1 ( -2.4304387569 -3.3657417297 -6.0171556473 ) - weight 1535 3 0.8667687178 ( -8.3641290665 -1.9775505066 -3.1054530144 ) - weight 1536 10 0.1332312971 ( 4.7789759636 0.5404324532 1.7811084986 ) - weight 1537 3 0.9462394714 ( -7.258852005 -1.9894180298 -5.8444795609 ) - weight 1538 10 0.0537605248 ( 6.9465332031 0.1740965247 -0.1915895343 ) - weight 1539 12 0.2594518661 ( -0.0521676578 -3.2157046795 -0.6101183891 ) - weight 1540 13 0.1016506925 ( -0.7945479155 -6.7303395271 4.8787183762 ) - weight 1541 11 0.6388974786 ( 2.4667754173 17.0333328247 1.7030045986 ) - weight 1542 10 0.0558952838 ( 9.1306562424 38.6815185547 -6.1957006454 ) - weight 1543 12 0.3172379136 ( 1.4303600788 -1.8882421255 -2.4327807426 ) - weight 1544 13 0.1428305209 ( 0.1974931806 -7.1519165039 2.404800415 ) - weight 1545 11 0.4840363264 ( 2.224401474 19.6753826141 2.1959261894 ) - weight 1546 12 0.2615793943 ( -1.0728007555 -1.9786319733 -0.4772690833 ) - weight 1547 13 0.083662428 ( -1.6481533051 -5.4658851624 4.3666610718 ) - weight 1548 11 0.654758215 ( 2.0046982765 17.2333011627 0.1745456457 ) - weight 1549 12 0.1860086769 ( 0.06329263 -2.775049448 0.6079931855 ) - weight 1550 13 0.0667252541 ( -0.3083217144 -5.6894173622 5.4881191254 ) - weight 1551 11 0.7472660542 ( 1.3383880854 16.3994102478 1.5757732391 ) - weight 1552 14 0.0738698542 ( -2.5472450256 -8.4770822525 3.0477583408 ) - weight 1553 12 0.3448125124 ( -1.944801569 0.357970804 -0.4874656796 ) - weight 1554 13 0.1340977103 ( -2.3247125149 -3.4799058437 3.0181970596 ) - weight 1555 11 0.447219938 ( 0.8778449893 18.1958961487 -1.8313988447 ) - weight 1556 14 0.1765218228 ( -2.0286893845 -3.7745051384 2.8613600731 ) - weight 1557 10 0.0524931625 ( 1.5555120707 39.0766677856 -2.0093901157 ) - weight 1558 12 0.2590146661 ( -2.6342616081 4.1042146683 2.3246822357 ) - weight 1559 13 0.2646489143 ( -1.9292982817 1.2352390289 2.8481075764 ) - weight 1560 11 0.2473214418 ( -3.0762405396 17.8706283569 -4.4154424667 ) - weight 1561 14 0.1380617321 ( -2.8084204197 -5.7227296829 2.6834375858 ) - weight 1562 12 0.3237291873 ( -2.8405845165 2.6660039425 0.8001508713 ) - weight 1563 13 0.2493311912 ( -2.6578202248 -0.7320804596 2.6633791924 ) - weight 1564 11 0.2888779044 ( -1.0753955841 18.1571884155 -3.8240737915 ) - weight 1565 11 1 ( 2.6114122868 11.0530910492 0.614703238 ) - weight 1566 3 0.4810942113 ( -0.2447296828 -5.9556617737 -1.4486429691 ) - weight 1567 10 0.5189057589 ( 0.3630612493 3.1848592758 -5.8347787857 ) - weight 1568 41 1 ( -3.1900980473 5.0376186371 2.7025253773 ) - weight 1569 41 1 ( -3.4448232651 5.9864349365 0.0013527125 ) - weight 1570 41 1 ( -4.0512795448 3.1180500984 0.9865902662 ) - weight 1571 41 1 ( -3.5521287918 3.8105933666 -2.2312550545 ) - weight 1572 41 1 ( -1.7138345242 4.6145730019 -3.5475459099 ) - weight 1573 41 1 ( -2.2882165909 6.0605959892 -2.6032176018 ) - weight 1574 41 1 ( -2.8378231525 3.2970001698 2.9867773056 ) - weight 1575 41 1 ( -3.6464164257 1.1949076653 0.750630796 ) - weight 1576 40 0.0603290237 ( 2.5804638863 -2.6065986156 1.3873519897 ) - weight 1577 41 0.87934196 ( -2.4086923599 1.3774354458 2.7908215523 ) - weight 1578 39 0.0603290237 ( 2.7672286034 6.9522447586 1.756999135 ) - weight 1579 41 0.8074488044 ( -0.3027048707 2.8175728321 -3.4290599823 ) - weight 1580 19 0.1925511956 ( -10.0099906921 8.8643655777 3.6808135509 ) - weight 1581 41 0.9459140301 ( -1.2622244358 2.7213592529 -3.8741877079 ) - weight 1582 19 0.0540859886 ( -10.4489917755 9.7282943726 4.1155304909 ) - weight 1583 41 0.9465995431 ( -3.1372811794 1.90130198 -2.5315716267 ) - weight 1584 19 0.0534004718 ( -10.8585739136 11.7013483047 2.7261962891 ) - weight 1585 41 0.8305544257 ( -1.215696454 1.8202985525 2.8228135109 ) - weight 1586 19 0.1694456041 ( -9.9061231613 9.9890346527 -2.6150872707 ) - weight 1587 41 0.4730896652 ( 2.311760664 2.5162849426 -3.0349223614 ) - weight 1588 19 0.5269103646 ( -8.317943573 6.8482556343 3.2886078358 ) - weight 1589 40 0.0815184191 ( 0.4475827217 4.2390847206 -1.9363365173 ) - weight 1590 41 0.4901720881 ( 1.0704855919 1.436178565 -4.3050456047 ) - weight 1591 39 0.0811879784 ( -4.2015028 5.8216362 -1.7951796055 ) - weight 1592 19 0.3471214771 ( -8.0687627792 8.5180597305 4.5011544228 ) - weight 1593 41 0.5052517653 ( 2.88088727 3.1643733978 -0.7477094531 ) - weight 1594 19 0.4947482347 ( -8.6178388596 5.9463543892 1.0365190506 ) - weight 1595 41 0.7788330317 ( -0.6934893131 1.1621602774 -4.3455200195 ) - weight 1596 22 0.0702832192 ( -8.822013855 1.8969993591 4.70383358 ) - weight 1597 19 0.1508837491 ( -8.822013855 10.1368961334 4.5188946724 ) - weight 1598 40 0.1050024852 ( 1.0632119179 -3.2362992764 0.3639907837 ) - weight 1599 41 0.6263005137 ( -0.6743445396 0.6912797093 3.3076121807 ) - weight 1600 39 0.1050024852 ( 3.298002243 5.5827541351 0.4965948164 ) - weight 1601 19 0.163694486 ( -8.6843919754 10.1524448395 -3.1474831104 ) - weight 1602 40 0.0926442742 ( 0.8901495934 -3.4821345806 -1.1454582214 ) - weight 1603 41 0.5098309517 ( 0.6882993579 1.3905004263 3.4596450329 ) - weight 1604 39 0.0926442742 ( 3.5321929455 5.6398234367 -1.0235103369 ) - weight 1605 19 0.3048804998 ( -8.5113296509 8.6272296906 -3.2596957684 ) - weight 1606 40 0.0952894315 ( 1.5346875191 -0.2706680298 3.2268676758 ) - weight 1607 41 0.6781370044 ( -3.5065419674 -0.525116086 0.5304982662 ) - weight 1608 39 0.0952894315 ( 0.3688513041 5.7743034363 3.4286088943 ) - weight 1609 22 0.1312840581 ( -9.1558675766 5.4491920471 0.0341236591 ) - weight 1610 40 0.149920851 ( 1.4739365578 -2.6723031998 1.6336746216 ) - weight 1611 41 0.5775595903 ( -1.9921746254 0.3218915462 2.832470417 ) - weight 1612 39 0.149920851 ( 2.7616014481 5.8185806274 1.8215639591 ) - weight 1613 22 0.1225988194 ( -9.0951166153 3.8559989929 -2.3675115108 ) - weight 1614 40 0.0526392497 ( 1.0456633568 -1.758595705 -3.9124679565 ) - weight 1615 41 0.4430772066 ( 2.776843071 3.0567092896 1.585386157 ) - weight 1616 39 0.0526392497 ( 1.8222314119 6.3481216431 -3.7115316391 ) - weight 1617 19 0.4516443014 ( -8.6668434143 6.0224175453 -1.2996242046 ) - weight 1618 40 0.0718849227 ( 1.7001137733 3.0090548992 2.0426483154 ) - weight 1619 41 0.6563013196 ( -2.8386166096 0.2607755661 -2.8045539856 ) - weight 1620 39 0.0716030672 ( -2.8934321404 6.3362421989 2.3204319477 ) - weight 1621 22 0.138011381 ( -9.3212938309 4.2649726868 3.3138465881 ) - weight 1622 19 0.0621992871 ( -9.3212938309 12.3735332489 2.9261572361 ) - weight 1623 20 0.0632745847 ( -8.4587841034 4.7723426819 -0.7690458298 ) - weight 1624 41 0.0764867812 ( 1.306034565 -2.7233970165 -5.7899084091 ) - weight 1625 22 0.3060672283 ( -4.4341006279 2.3252906799 6.0247020721 ) - weight 1626 21 0.1290044188 ( -0.1817407608 4.6440162659 -0.7690458298 ) - weight 1627 19 0.4251669645 ( -4.4341006279 10.6796255112 5.7970070839 ) - weight 1628 41 0.0919046253 ( -1.1891056299 -5.107407093 2.462761879 ) - weight 1629 22 0.9080953598 ( -4.1291065216 6.1981391907 -2.0328297615 ) - weight 1630 40 0.0891765058 ( -2.3504533768 1.5366080999 3.833984375 ) - weight 1631 41 0.1500965506 ( -1.9676885605 -4.0949077606 -1.3715204 ) - weight 1632 39 0.111001648 ( -1.684656024 1.9648126364 3.4220399857 ) - weight 1633 22 0.649725318 ( -5.2707266808 6.0563087463 1.8413997889 ) - weight 1634 40 0.0931440294 ( -2.3685202599 3.6074230671 2.6633453369 ) - weight 1635 41 0.1410497874 ( -1.1275857687 -3.4644777775 -3.5059480667 ) - weight 1636 39 0.1072058529 ( -3.7523424625 2.267074585 2.2852432728 ) - weight 1637 22 0.5160495639 ( -5.2526597977 4.8856697083 3.912214756 ) - weight 1638 19 0.1425507665 ( -5.2526597977 13.044421196 3.4676542282 ) - weight 1639 40 0.0882926509 ( -2.323984623 -0.7202219963 4.1005706787 ) - weight 1640 41 0.1216077283 ( -2.0514426231 -4.2134113312 0.8965168595 ) - weight 1641 39 0.1135413796 ( 0.569200933 1.8046303988 3.666011095 ) - weight 1642 22 0.6765582561 ( -5.2971954346 6.32289505 -0.4154303074 ) - weight 1643 23 0.0537326299 ( -2.4773287773 -8.3899736404 1.2029196024 ) - weight 1644 40 0.0887360871 ( -2.6046271324 -3.2973005772 3.3118591309 ) - weight 1645 41 0.1095810533 ( -1.0689406395 -3.9970026016 3.4124693871 ) - weight 1646 39 0.1129395142 ( 3.122882843 1.4916169643 2.8157804012 ) - weight 1647 22 0.6350107193 ( -5.0165529251 5.5341835022 -2.9925088882 ) - weight 1648 40 0.061802078 ( -4.0015478134 -4.0772538185 2.5681533813 ) - weight 1649 39 0.0914017186 ( 3.8113396168 0.186054498 1.8491646051 ) - weight 1650 22 0.7597923875 ( -3.6196322441 4.7904777527 -3.7724618912 ) - weight 1651 19 0.0870038196 ( -3.6196322441 12.2741622925 -4.1789150238 ) - weight 1652 17 0.0596817918 ( -0.9120191336 8.7955646515 11.0287809372 ) - weight 1653 22 0.0719239861 ( -1.5239515305 -5.0739479065 9.9274148941 ) - weight 1654 19 0.868394196 ( -1.5239515305 3.6520473957 10.3349628448 ) - weight 1655 22 0.37153247 ( -2.6421873569 0.3410873413 8.4769620895 ) - weight 1656 21 0.103534773 ( 1.6101725101 2.6598129272 1.6832141876 ) - weight 1657 19 0.5249327421 ( -2.6421873569 8.9186401367 8.4141759872 ) - weight 1658 18 0.1414450258 ( -2.641505003 4.1625137329 0.2868571281 ) - weight 1659 17 0.5602910519 ( -2.2148184776 4.0995850563 8.0440921783 ) - weight 1660 19 0.2982639372 ( -2.7232618332 -1.7657701969 8.9686584473 ) - weight 1661 20 0.0702714249 ( -5.6977977753 -5.3680610657 2.5406947136 ) - weight 1662 17 0.4855641425 ( -1.0949766636 6.27572155 9.8020915985 ) - weight 1663 21 0.093168132 ( 2.5792450905 -5.4963874817 2.5406947136 ) - weight 1664 19 0.3509963155 ( -1.6731148958 0.8693724275 9.9852170944 ) - weight 1665 18 0.1713802963 ( -1.3135985136 3.5550079346 1.2471613884 ) - weight 1666 17 0.6180585027 ( -0.833974719 3.2973520756 8.7542152405 ) - weight 1667 19 0.2105612308 ( -1.395355463 -2.2865200043 9.9786424637 ) - weight 1668 22 0.2855619788 ( -3.5172073841 -0.2096824646 7.727332592 ) - weight 1669 21 0.0829953179 ( 0.735152483 2.1090431213 0.9335846901 ) - weight 1670 19 0.6314427257 ( -3.5172073841 8.3041143417 7.715857029 ) - weight 1671 17 0.0628961921 ( -5.4069485664 9.5402956009 7.9230222702 ) - weight 1672 22 0.0539472364 ( -5.8281311989 -5.099445343 6.4809465408 ) - weight 1673 19 0.8831565976 ( -5.8281311989 3.323725462 6.9040746689 ) - weight 1674 17 0.1918828785 ( -6.9418077469 8.5857229233 5.8693122864 ) - weight 1675 21 0.0991675779 ( -3.0068798065 -4.2019844055 -2.1612222195 ) - weight 1676 19 0.7089495063 ( -7.2592396736 1.7454966307 5.1877274513 ) - weight 1677 3 0.1821741015 ( -8.1789197922 8.1778831482 1.1582477093 ) - weight 1678 17 0.3237217963 ( -7.987569809 6.9319310188 3.2267251015 ) - weight 1679 21 0.0804984793 ( -3.9265599251 -6.4437522888 -4.3839635849 ) - weight 1680 19 0.4136056602 ( -8.1789197922 -0.6829606295 3.1706259251 ) - weight 1681 22 0.168408528 ( -4.5275287628 0.0214424133 7.6852359772 ) - weight 1682 21 0.0619742945 ( -0.2751688957 2.3401679993 0.8914880753 ) - weight 1683 19 0.7696171999 ( -4.5275287628 8.5306444168 7.653608799 ) - weight 1684 22 0.0798309743 ( -6.2138233185 -1.6987228394 6.9659352303 ) - weight 1685 19 0.9201690555 ( -6.2138233185 6.7539143562 7.0882835388 ) - weight 1686 19 1 ( -7.7301111221 3.3008527756 5.119559288 ) - weight 1687 3 0.0991472378 ( -4.8108649254 8.5944099426 -6.5108242035 ) - weight 1688 17 0.3873375058 ( -5.0653195381 9.2274799347 -4.2914433479 ) - weight 1689 22 0.069731988 ( -4.8108649254 -8.3459510803 -5.2592878342 ) - weight 1690 19 0.443783313 ( -4.8108649254 -0.9421098232 -4.5053758621 ) - weight 1691 17 0.2797969878 ( -7.0503921509 9.416841507 -0.5392340422 ) - weight 1692 22 0.0568300672 ( -6.9990987778 -7.2581253052 -1.78312397 ) - weight 1693 19 0.6633729339 ( -6.9990987778 0.4470392466 -1.1382784843 ) - weight 1694 41 0.1625600308 ( 3.1202549934 2.2610082626 -4.7462286949 ) - weight 1695 21 0.064367786 ( -3.3445906639 0.4219856262 -1.950483799 ) - weight 1696 19 0.7730721831 ( -7.596950531 6.3700938225 4.9912319183 ) - weight 1697 40 0.08182358 ( -0.7713675499 -4.5227479935 -4.405834198 ) - weight 1698 41 0.1527400464 ( 4.3827528954 1.8338996172 4.2520961761 ) - weight 1699 39 0.0819378868 ( 4.4637460709 4.4624714851 -4.5191674232 ) - weight 1700 22 0.0618891604 ( -6.8498125076 -2.1835098267 -4.217956543 ) - weight 1701 19 0.6216093302 ( -6.8498125076 5.2880086899 -4.0097150803 ) - weight 1702 3 0.0522639193 ( -2.3265652657 8.6184806824 -6.8896408081 ) - weight 1703 18 0.0703556612 ( -2.2448084354 6.1913414001 -13.44145298 ) - weight 1704 17 0.359451741 ( -2.6068630219 9.3763227463 -4.7911071777 ) - weight 1705 22 0.0969797894 ( -2.3265652657 -8.3218803406 -5.6381044388 ) - weight 1706 19 0.4209489226 ( -2.3265652657 -0.9514278769 -4.8848419189 ) - weight 1707 17 0.299821496 ( -4.0779647827 12.0176057816 -5.299738884 ) - weight 1708 22 0.0852135643 ( -3.73037076 -5.8809547424 -6.8507189751 ) - weight 1709 19 0.614964962 ( -3.73037076 1.3734697104 -6.3073058128 ) - weight 1710 20 0.0763065293 ( -7.3188533783 0.2186355591 -13.6559553146 ) - weight 1711 17 0.0947004631 ( -3.643143177 15.5713405609 -4.455145359 ) - weight 1712 22 0.214722231 ( -3.2941703796 -2.2284164429 -6.8622078896 ) - weight 1713 21 0.0870492309 ( 0.9581894875 0.0903091431 -13.6559562683 ) - weight 1714 19 0.5272215605 ( -3.2941703796 5.0108623505 -6.6397857666 ) - weight 1715 23 0.0611941852 ( 5.6080360413 -5.0251612663 0.0380865559 ) - weight 1716 39 0.0858657882 ( -5.2978982925 -0.2778818309 0.8129709363 ) - weight 1717 22 0.5666524768 ( -2.4100449085 3.842540741 5.2777018547 ) - weight 1718 19 0.286287576 ( -2.4100449085 12.1253471375 4.9195413589 ) - weight 1719 22 0.1728690118 ( -3.0167717934 -2.7448730469 9.4543809891 ) - weight 1720 19 0.8271310329 ( -3.0167717934 5.9305319786 9.6590480804 ) - weight 1721 41 0.1455741674 ( 1.6653842926 -0.3622587621 -5.8100786209 ) - weight 1722 22 0.1275289357 ( -6.1930189133 0.7095680237 6.0120625496 ) - weight 1723 21 0.11865969 ( -1.9406590462 3.0282936096 -0.7816853523 ) - weight 1724 19 0.6082372069 ( -6.1930189133 9.0690450668 5.9264287949 ) - weight 1725 40 0.0500451624 ( -0.433339119 -3.5517652035 -7.2256813049 ) - weight 1726 17 0.1471123099 ( -7.3228569031 11.9546890259 -1.4038463831 ) - weight 1727 39 0.0500451624 ( 3.5165240765 5.3112502098 -7.2377986908 ) - weight 1728 22 0.060705293 ( -7.1878409386 -5.0033569336 -3.2469735146 ) - weight 1729 19 0.692092061 ( -7.1878409386 2.5644180775 -2.7946429253 ) - weight 1730 41 0.0594077036 ( 6.1765432358 4.287332058 -0.8555094004 ) - weight 1731 17 0.0882978588 ( -7.6161117554 10.6668891907 2.4174199104 ) - weight 1732 19 0.852294445 ( -7.7113251686 2.5876910686 1.2143377066 ) - weight 1733 22 0.1241166219 ( -4.4618620872 -3.2965545654 7.6446428299 ) - weight 1734 19 0.8758834004 ( -4.4618620872 5.2219204903 7.9048042297 ) - weight 1735 3 0.347307235 ( -4.2138977051 6.2819366455 -5.6449556351 ) - weight 1736 17 0.3161298037 ( -4.4196305275 6.7831120491 -4.042886734 ) - weight 1737 19 0.3365629315 ( -4.2138977051 -3.1695289612 -3.4396061897 ) - weight 1738 23 0.0867915154 ( -5.6425395012 -6.4608654976 -2.7922000885 ) - weight 1739 24 0.0606948659 ( 11.176325798 -6.3748602867 -0.9418144226 ) - weight 1740 39 0.1238846853 ( 6.1000337601 0.5420006514 -1.6491719484 ) - weight 1741 22 0.4406973124 ( -3.5551466942 1.2804870605 -6.0700659752 ) - weight 1742 19 0.2879316509 ( -3.5551466942 8.5758104324 -6.1591205597 ) - weight 1743 3 0.3187047243 ( -7.3179450035 6.1070823669 -3.6608753204 ) - weight 1744 17 0.3373079896 ( -7.4046611786 6.0932278633 -1.989618063 ) - weight 1745 19 0.3439872563 ( -7.3179450035 -3.1693181992 -1.4478360415 ) - weight 1746 40 0.0575324968 ( 0.5468850136 0.0160104036 -5.6447868347 ) - weight 1747 41 0.2394847125 ( 4.3695383072 3.6025440693 -0.3025549948 ) - weight 1748 39 0.0575322956 ( 0.019210171 6.2485928535 -5.4830121994 ) - weight 1749 19 0.6454505324 ( -8.1680650711 4.4527797699 0.6203741431 ) - weight 1750 17 0.2211470157 ( -5.1224837303 7.6795835495 8.3936414719 ) - weight 1751 21 0.0793408677 ( -1.3437318802 -4.4732284546 0.6071043015 ) - weight 1752 19 0.6995120645 ( -5.5960917473 1.7186210155 7.9691810608 ) - weight 1753 3 0.1902632564 ( -7.2685761452 6.8893318176 3.5721042156 ) - weight 1754 17 0.3352842927 ( -6.9401574135 5.1133041382 5.2044301033 ) - weight 1755 21 0.0951151028 ( -3.0162162781 -7.7323036194 -1.970107317 ) - weight 1756 19 0.3793374002 ( -7.2685761452 -1.7543619871 5.688395977 ) - weight 1757 17 0.0715875253 ( -3.0136620998 9.0979747772 9.7494478226 ) - weight 1758 22 0.0749636889 ( -3.5466682911 -5.088684082 8.4944286346 ) - weight 1759 19 0.8534488082 ( -3.5466682911 3.5114176273 8.9088182449 ) - weight 1760 18 0.1327728927 ( -3.9752800465 5.0340919495 0.336514473 ) - weight 1761 17 0.4595475793 ( -3.5435433388 4.9150953293 8.3765125275 ) - weight 1762 19 0.4076794684 ( -4.0570368767 -0.8932005167 8.9415178299 ) - weight 1763 3 0.140446201 ( -2.8713064194 5.0997123718 6.2222933769 ) - weight 1764 18 0.1639315784 ( -2.7895495892 2.6725730896 -0.3295183182 ) - weight 1765 17 0.5287848711 ( -2.3980026245 2.7997512817 7.0961289406 ) - weight 1766 19 0.1668373644 ( -2.8713064194 -3.3041200638 8.485625267 ) - weight 1767 3 0.3118911088 ( -1.7950662374 3.0419692993 6.4724926949 ) - weight 1768 18 0.1574070901 ( -1.713309288 0.6148300171 -0.0793190002 ) - weight 1769 10 0.0548834912 ( -6.5305404663 -4.8464808464 0.0031257221 ) - weight 1770 17 0.475818336 ( -1.30917418 0.7573302984 6.7828097343 ) - weight 1771 3 0.4392207563 ( -2.900220871 3.6319847107 7.0007915497 ) - weight 1772 18 0.1452370584 ( -2.8184640408 1.2048454285 0.4489798546 ) - weight 1773 17 0.4155421555 ( -2.3821787834 1.18760252 7.4984297752 ) - weight 1774 3 0.439315021 ( -6.358253479 3.8093528748 4.1738572121 ) - weight 1775 18 0.078426294 ( -6.2764964104 1.3822135925 -2.377954483 ) - weight 1776 10 0.0694220588 ( -2.7639284134 -4.9841713905 3.5370972157 ) - weight 1777 17 0.3023468852 ( -5.9967918396 1.9919042587 4.9946966171 ) - weight 1778 19 0.1104898155 ( -6.358253479 -4.7695307732 6.5585312843 ) - weight 1779 3 0.5316781402 ( -7.4205164909 4.1601028442 0.1617401242 ) - weight 1780 10 0.1000787318 ( 1.3621966839 -5.4266219139 3.1795465946 ) - weight 1781 17 0.2644095421 ( -7.2876224518 3.2826986313 1.2508860826 ) - weight 1782 19 0.1038336158 ( -7.4205164909 -4.772778511 2.5311129093 ) - weight 1783 3 0.6088260412 ( -5.7542610168 4.3418273926 -4.5260896683 ) - weight 1784 10 0.0523319058 ( 5.1511530876 -6.2138624191 0.0475756861 ) - weight 1785 17 0.2037265301 ( -5.8932242393 4.6097207069 -3.3403933048 ) - weight 1786 19 0.1351155192 ( -5.7542610168 -5.0037884712 -2.1545469761 ) - weight 1787 3 0.7236922383 ( -3.6426603794 3.8363189697 -6.4675378799 ) - weight 1788 17 0.1298229992 ( -3.8965563774 4.6153035164 -5.4609837532 ) - weight 1789 19 0.1464847326 ( -3.6426603794 -5.6779818535 -4.0440502167 ) - weight 1790 20 0.0595895164 ( -9.1605768204 0.2899017334 -12.4811029434 ) - weight 1791 41 0.0511426926 ( 5.4139080048 0.4020498395 5.6605949402 ) - weight 1792 17 0.0605752133 ( -5.4143857956 15.3324365616 -3.1970009804 ) - weight 1793 22 0.1611460447 ( -5.1358938217 -2.1571502686 -5.6873550415 ) - weight 1794 21 0.0742564574 ( -0.8835339546 0.1615753174 -12.4811029434 ) - weight 1795 19 0.5932900906 ( -5.1358938217 5.1851148605 -5.4757437706 ) - weight 1796 23 0.0515754223 ( -3.2410001755 -10.1146697998 -1.6488589048 ) - weight 1797 40 0.1290110499 ( -0.496691227 -4.198469162 0.7751464844 ) - weight 1798 41 0.3656567037 ( -0.0816293955 -0.8292276859 4.2375922203 ) - weight 1799 39 0.1318016499 ( 4.1578116417 3.919084549 0.6416754127 ) - weight 1800 22 0.1448136717 ( -7.1244888306 2.9974708557 -3.8936772346 ) - weight 1801 19 0.1771414578 ( -7.1244888306 10.4774398804 -4.1420669556 ) - weight 1802 40 0.0979153141 ( -0.9380350113 4.9778151512 0.7307510376 ) - weight 1803 41 0.3668260872 ( -0.4159949124 -1.2042227983 -4.9356579781 ) - weight 1804 39 0.0985166207 ( -5.0278553963 4.0742635727 0.6220181584 ) - weight 1805 22 0.2166462541 ( -6.6831450462 2.9530754089 5.2826070786 ) - weight 1806 19 0.2200956494 ( -6.6831450462 11.2397556305 5.0026059151 ) - weight 1807 40 0.1437141895 ( -0.1764206886 3.4288134575 2.2893295288 ) - weight 1808 41 0.3799183071 ( -2.0263359547 -1.4358223677 -3.2737934589 ) - weight 1809 39 0.1435491741 ( -3.4330599308 4.4749698639 2.2666127682 ) - weight 1810 22 0.3328183591 ( -7.4447593689 4.5116539001 3.7336051464 ) - weight 1811 40 0.1507516354 ( -0.3617811203 -0.2706680298 3.5939254761 ) - weight 1812 41 0.3186547756 ( -2.7546138763 -2.3038737774 0.4863381088 ) - weight 1813 39 0.156258285 ( 0.2468296289 3.8473534584 3.4860401154 ) - weight 1814 22 0.3743353188 ( -7.2593989372 5.8162498474 0.0341236591 ) - weight 1815 23 0.0551610962 ( -1.8995196819 -10.2919902802 -0.0395773426 ) - weight 1816 40 0.1538378745 ( -0.4944291115 -2.8543488979 2.3919754028 ) - weight 1817 41 0.2565502524 ( -1.5119162798 -1.7341077328 2.9900863171 ) - weight 1818 39 0.1602704972 ( 2.8166222572 3.7462410927 2.251686573 ) - weight 1819 22 0.3741802573 ( -7.126750946 4.6142997742 -2.549557209 ) - weight 1820 23 0.0716580003 ( -3.7964847088 -8.2113981247 -0.3925207555 ) - weight 1821 40 0.1164635196 ( -2.6089138985 -4.6189193726 1.7084884644 ) - weight 1822 41 0.1498096138 ( 0.3498179018 -3.1013920307 4.6382331848 ) - weight 1823 39 0.1409281343 ( 4.4414868355 1.6617273092 1.2189595699 ) - weight 1824 22 0.382319957 ( -5.0122661591 3.9308128357 -4.3141274452 ) - weight 1825 19 0.1388208419 ( -5.0122661591 11.370215416 -4.6429252625 ) - weight 1826 17 0.2525490522 ( -1.9341961145 7.0841917992 10.4089765549 ) - weight 1827 21 0.063646391 ( 1.7187790871 -4.5655136108 2.8860850334 ) - weight 1828 19 0.683804512 ( -2.53358078 1.8270013332 10.2474527359 ) - weight 1829 22 0.9465700984 ( -2.4110500813 7.1069450378 -1.3874628544 ) - weight 1830 19 0.0534298941 ( -2.4110500813 14.7912912369 -2.0067493916 ) - weight 1831 41 0.0518364236 ( -1.3388719559 -5.6846284866 -0.4777522981 ) - weight 1832 39 0.050450813 ( -0.8638013005 0.2246299833 3.5613434315 ) - weight 1833 22 0.8977127671 ( -3.6320309639 6.4740867615 0.9131856561 ) - weight 1834 22 0.8253623247 ( -1.8106377125 4.6900215149 4.140335083 ) - weight 1835 19 0.1746376157 ( -1.8106377125 12.8695802689 3.7120878696 ) - weight 1836 39 0.0829045624 ( -3.0786933899 -0.0840904936 2.8616888523 ) - weight 1837 22 0.8328667283 ( -3.0730025768 5.8332939148 3.0966331959 ) - weight 1838 19 0.084228754 ( -3.0730025768 13.9166936874 2.5719387531 ) - weight 1839 23 0.0599147789 ( -4.2398481369 -8.4929857254 -3.9275622368 ) - weight 1840 40 0.1081208512 ( -1.7918434143 -5.115884304 -1.7350273132 ) - weight 1841 41 0.1804821342 ( 2.7794332504 -0.5006632209 4.9631333351 ) - weight 1842 39 0.114029713 ( 4.9899945259 2.9895517826 -2.0534098148 ) - weight 1843 22 0.1659332514 ( -5.8293366432 0.4872970581 -4.8110928535 ) - weight 1844 19 0.371519357 ( -5.8293366432 7.8963460922 -4.8353033066 ) - weight 1845 39 0.0608512871 ( 5.0714569092 -1.5550205708 1.9790691137 ) - weight 1846 22 0.8387778997 ( -2.0068097115 5.1991233826 -5.1391825676 ) - weight 1847 19 0.1003707871 ( -2.0068097115 12.5611000061 -5.5762639046 ) - weight 1848 20 0.0539900064 ( -8.0486059189 -1.5040931702 -13.0935106277 ) - weight 1849 17 0.1389597207 ( -4.339404583 13.7539787292 -4.2845788002 ) - weight 1850 22 0.1094966531 ( -4.0239229202 -3.9511451721 -6.2997627258 ) - weight 1851 21 0.0638045073 ( 0.2284369469 -1.6324195862 -13.0935106277 ) - weight 1852 19 0.6337491274 ( -4.0239229202 3.3442363739 -5.9281001091 ) - weight 1853 3 0.7413187027 ( 0 -5.1984939575 5.673406601 ) - weight 1854 10 0.178443104 ( -6.3844809532 2.8930361271 -3.4384698868 ) - weight 1855 4 0.0802381486 ( 6.3832840919 2.8918428421 -3.4417250156 ) - weight 1856 3 0.6934309006 ( 0 -6.4339332581 4.9000563622 ) - weight 1857 10 0.225762248 ( -5.6560645103 4.0538043976 -3.9348635674 ) - weight 1858 4 0.0808068588 ( 5.6547913551 4.0526490211 -3.937918663 ) - weight 1859 3 0.542861104 ( 0 -7.271396637 3.5398442745 ) - weight 1860 10 0.2784681618 ( -4.380877018 4.7826557159 -4.5627131462 ) - weight 1861 4 0.178670764 ( 4.3794121742 4.7815942764 -4.5652694702 ) - weight 1862 3 0.7236195207 ( 0 -1.3579444885 6.1505203247 ) - weight 1863 18 0.0611175634 ( 0.0817569122 -3.7850837708 -0.4012913704 ) - weight 1864 10 0.0655163899 ( -6.8476872444 -0.8490688205 -2.5669493675 ) - weight 1865 17 0.0970704108 ( 0.4644486904 -3.4106917381 5.3107280731 ) - weight 1866 4 0.0526760519 ( 6.8464016914 -0.850222826 -2.5699882507 ) - weight 1867 3 0.6594268084 ( 0 1.2102432251 6.1666622162 ) - weight 1868 18 0.1118366793 ( 0.0817569122 -1.2168960571 -0.3851494789 ) - weight 1869 17 0.2287364751 ( 0.465375334 -0.9220430255 5.9451375008 ) - weight 1870 3 0.0924839675 ( 0 4.7916221619 7.7315945625 ) - weight 1871 18 0.2437934577 ( 0.0817569122 2.3644828796 1.1797828674 ) - weight 1872 17 0.5497845411 ( 0.5552117825 2.1774051189 8.324347496 ) - weight 1873 19 0.1139379889 ( 0 -3.4783596992 10.0161647797 ) - weight 1874 3 0.0609722324 ( 0 6.8167800903 8.9189844131 ) - weight 1875 18 0.217455104 ( 0.0817569122 4.3896408081 2.3671731949 ) - weight 1876 17 0.4903882742 ( 0.6233750582 3.8572907448 9.9627914429 ) - weight 1877 19 0.231184423 ( 0 -1.3566752672 11.0209608078 ) - weight 1878 3 0.401619792 ( 0 3.2093658447 7.1787643433 ) - weight 1879 18 0.1838271618 ( 0.0817569122 0.7822265625 0.6269526482 ) - weight 1880 17 0.4145531058 ( 0.5234760046 0.7747376561 7.4074649811 ) - weight 1881 20 0.0816420168 ( -4.0246829987 -5.0288200378 3.0966849327 ) - weight 1882 17 0.4254934788 ( 0.6072963476 6.4943728447 10.329331398 ) - weight 1883 21 0.0615779161 ( 4.2523598671 -5.1571464539 3.0966849327 ) - weight 1884 19 0.4312866628 ( 0 1.2561686039 10.5092391968 ) - weight 1885 20 0.0571901202 ( -4.0246829987 -3.5292396545 3.3706479073 ) - weight 1886 17 0.0625942349 ( 0.6230234504 7.883878231 10.9560880661 ) - weight 1887 22 0.0754338428 ( 0 -5.9762916565 10.164396286 ) - weight 1888 19 0.8047818542 ( 0 2.7740252018 10.6503372192 ) - weight 1889 17 0.0596817918 ( 0.6094192863 8.8166427612 10.9438743591 ) - weight 1890 22 0.0719239861 ( 0 -5.0739479065 9.9274139404 ) - weight 1891 19 0.868394196 ( 0 3.6520473957 10.3349628448 ) - weight 1892 22 0.37153247 ( 0 0.6967811584 8.5550251007 ) - weight 1893 21 0.103534773 ( 4.2523598671 3.0155067444 1.7612771988 ) - weight 1894 19 0.5249327421 ( 0 9.2798185349 8.4606733322 ) - weight 1895 22 0.1728690118 ( 0 -3.3234443665 9.4951934814 ) - weight 1896 19 0.8271310329 ( 0 5.3577866554 9.7505559921 ) - weight 1897 23 0.0611941852 ( 5.7624468803 -2.6173989773 0.3403273523 ) - weight 1898 39 0.0858657882 ( -5.7624435425 -2.6174106598 0.3404080272 ) - weight 1899 22 0.5666524768 ( 0 3.7529792786 5.587823391 ) - weight 1900 19 0.286287576 ( 0 12.0633897781 5.2363343239 ) - weight 1901 22 0.8253623247 ( 0 4.1191749573 4.7094497681 ) - weight 1902 19 0.1746376157 ( 0 12.3509645462 4.3291740417 ) - weight 1903 39 0.0829045624 ( -3.0563151836 -3.0520541668 1.9203937054 ) - weight 1904 22 0.8328667283 ( 0 5.3823432922 2.8760764599 ) - weight 1905 19 0.084228754 ( 0 13.4481019974 2.3918712139 ) - weight 1906 41 0.0518364236 ( 0.7239339948 -8.6716833115 -0.605815649 ) - weight 1907 39 0.050450813 ( -1.0974917412 -3.3446290493 2.9290099144 ) - weight 1908 22 0.8977127671 ( 0 6.4249153137 0.9131856561 ) - weight 1909 3 0.7236207724 ( 0 -5.8034477234 -4.6051521301 ) - weight 1910 4 0.2763792276 ( -3.2287955284 2.7742657661 -7.1307415962 ) - weight 1911 3 1 ( 0 -3.7764472961 -6.0171556473 ) - weight 1912 3 0.4810942113 ( 0 -5.9556617737 -1.4486429691 ) - weight 1913 4 0.5189057589 ( -0.2784615755 3.1426086426 -6.0599598885 ) - weight 1914 3 1 ( 0 -3.110408783 -9.5110578537 ) - weight 1915 3 1 ( 0 -1.1892356873 -10.9292411804 ) - weight 1916 3 1 ( 0 1.8350715637 -11.1396818161 ) - weight 1917 3 1 ( 0 4.0030708313 -9.326420784 ) - weight 1918 3 0.3334618807 ( 0 6.298412323 -6.4844498634 ) - weight 1919 18 0.0678634793 ( 0.0817569122 3.8712730408 -13.0362615585 ) - weight 1920 17 0.3383588791 ( -0.2608740032 7.0593161583 -5.0871138573 ) - weight 1921 22 0.093544513 ( 0 -10.6419487 -5.2329134941 ) - weight 1922 19 0.1667711884 ( 0 -3.2269034386 -4.277299881 ) - weight 1923 3 0.7805210352 ( 0 3.875164032 -6.7810230255 ) - weight 1924 17 0.1174537167 ( -0.2778990567 4.7787919044 -5.9583234787 ) - weight 1925 19 0.1020251885 ( 0 -5.6668405533 -4.3597364426 ) - weight 1926 18 0.0757854879 ( 0.0817569122 6.2348365784 -13.674287796 ) - weight 1927 17 0.3778569102 ( -0.2975005209 9.5067214966 -5.1358551979 ) - weight 1928 22 0.104464367 ( 0 -8.2783851624 -5.8709397316 ) - weight 1929 19 0.4418932498 ( 0 -0.9285658002 -5.1205992699 ) - weight 1930 17 0.3031003475 ( -0.373631686 12.046210289 -5.8696188927 ) - weight 1931 22 0.0848145187 ( 0 -5.9904975891 -7.1971287727 ) - weight 1932 19 0.6120851636 ( 0 1.2339035273 -6.6427469254 ) - weight 1933 20 0.054006543 ( -4.0246829987 -1.3230361938 -13.4977312088 ) - weight 1934 17 0.1386959404 ( -0.3453222215 14.0825881958 -4.8568143845 ) - weight 1935 22 0.1095301956 ( 0 -3.7700881958 -6.7039837837 ) - weight 1936 21 0.0638240501 ( 4.2523598671 -1.4513626099 -13.4977321625 ) - weight 1937 19 0.6339432597 ( 0 3.4890639782 -6.3466706276 ) - weight 1938 20 0.0780259147 ( -4.0246829987 1.9574928284 -15.1195812225 ) - weight 1939 17 0.0743017644 ( -0.4384260774 17.6565933228 -5.6378927231 ) - weight 1940 22 0.2195604742 ( 0 -0.4895591736 -8.3258342743 ) - weight 1941 21 0.0890106782 ( 4.2523598671 1.8291664124 -15.1195821762 ) - weight 1942 19 0.539101243 ( 0 6.6143465042 -8.250582695 ) - weight 1943 39 0.0608512796 ( 6.8155360222 -3.4391424656 0.3406294584 ) - weight 1944 22 0.8387778997 ( 0 3.8855552673 -7.016272068 ) - weight 1945 19 0.1003707871 ( 0 11.0876312256 -7.3306341171 ) - weight 1946 39 0.0608512871 ( 5.4356679916 -3.6152935028 1.9723176956 ) - weight 1947 22 0.8387779593 ( 0 5.5243110657 -5.6335391998 ) - weight 1948 19 0.1003707945 ( 0 12.8415784836 -6.0972890854 ) - weight 1949 22 0.9465700984 ( 0 7.0184364319 -0.787604332 ) - weight 1950 19 0.0534298941 ( 0 14.7558488846 -1.4014331102 ) - weight 1951 22 0.9465700984 ( 0 6.9066047668 -1.8640949726 ) - weight 1952 19 0.0534298941 ( 0 14.5498332977 -2.4639282227 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} diff --git a/base/animation/mp_soldier.md5mesh b/base/animation/mp_soldier.md5mesh deleted file mode 100644 index 27114ee06..000000000 --- a/base/animation/mp_soldier.md5mesh +++ /dev/null @@ -1,7924 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:28 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_soldier.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh marinebodymesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: marinebodymesh - shader "models/characters/male_npc/marine/marine" - - numverts 961 - vert 0 ( 0.1113319993 0.7144190073 ) 0 4 - vert 1 ( 0.1140540019 0.5849939585 ) 4 6 - vert 2 ( 0.0755819976 0.7149720192 ) 10 4 - vert 3 ( 0.0878639966 0.7418110371 ) 14 4 - vert 4 ( 0.0771259964 0.5961179733 ) 18 5 - vert 5 ( 0.0065159998 0.6685389876 ) 23 5 - vert 6 ( 0.0065159998 0.5965949893 ) 28 5 - vert 7 ( 0.0065159998 0.7364040017 ) 33 5 - vert 8 ( 0.7266179919 0.8000400066 ) 38 2 - vert 9 ( 0.7041410208 0.7505249977 ) 40 3 - vert 10 ( 0.6799460053 0.7962620258 ) 43 2 - vert 11 ( 0.7241439819 0.7523819804 ) 45 2 - vert 12 ( 0.7345380187 0.7539520264 ) 47 3 - vert 13 ( 0.7249150276 0.7177790403 ) 50 2 - vert 14 ( 0.704366982 0.7126190066 ) 52 2 - vert 15 ( 0.7368519902 0.7151950002 ) 54 2 - vert 16 ( 0.7568039894 0.777576983 ) 56 2 - vert 17 ( 0.9015840292 0.8468999863 ) 58 1 - vert 18 ( 0.8701090217 0.8927010298 ) 59 1 - vert 19 ( 0.9042909741 0.9045029879 ) 60 1 - vert 20 ( 0.734070003 0.8368970156 ) 61 1 - vert 21 ( 0.6791769862 0.83267802 ) 62 2 - vert 22 ( 0.7839429975 0.8137180209 ) 64 2 - vert 23 ( 0.8039349914 0.8621749878 ) 66 1 - vert 24 ( 0.7422800064 0.8775190115 ) 67 1 - vert 25 ( 0.6955360174 0.8862699866 ) 68 1 - vert 26 ( 0.8159909844 0.8497760296 ) 69 1 - vert 27 ( 0.7301239967 0.9030950069 ) 70 1 - vert 28 ( 0.8420280218 0.9083549976 ) 71 1 - vert 29 ( 0.8047969937 0.9199159741 ) 72 1 - vert 30 ( 0.6573690176 0.9002029896 ) 73 1 - vert 31 ( 0.7329789996 0.9312850237 ) 74 1 - vert 32 ( 0.6533820033 0.9263920188 ) 75 1 - vert 33 ( 0.7674570084 0.9810230136 ) 76 2 - vert 34 ( 0.7148280144 0.9588119984 ) 78 2 - vert 35 ( 0.7286459804 0.9787729979 ) 80 2 - vert 36 ( 0.868991971 0.8366839886 ) 82 1 - vert 37 ( 0.8979229927 0.8103759885 ) 83 1 - vert 38 ( 0.2880809903 0.9381070137 ) 84 4 - vert 39 ( 0.2428800017 0.9283080101 ) 88 2 - vert 40 ( 0.2801589966 0.9951519966 ) 90 2 - vert 41 ( 0.2602320015 0.9096509814 ) 92 4 - vert 42 ( 0.3308880031 0.934671998 ) 96 4 - vert 43 ( 0.396728009 0.9623540044 ) 100 3 - vert 44 ( 0.3365319967 0.9943330288 ) 103 3 - vert 45 ( 0.402839005 0.9280309677 ) 106 2 - vert 46 ( 0.3863759935 0.8592050076 ) 108 1 - vert 47 ( 0.4510799944 0.946927011 ) 109 3 - vert 48 ( 0.4349130094 0.8711069822 ) 112 2 - vert 49 ( 0.4385879934 0.9677169919 ) 114 3 - vert 50 ( 0.4149670005 0.9764750004 ) 117 3 - vert 51 ( 0.2995730042 0.8568370342 ) 80 2 - vert 52 ( 0.1483460069 0.8560280204 ) 120 2 - vert 53 ( 0.2727760077 0.8909019828 ) 122 4 - vert 54 ( 0.165241003 0.8861150146 ) 126 3 - vert 55 ( 0.1703960001 0.9069539905 ) 129 3 - vert 56 ( 0.1953860074 0.9247580171 ) 132 3 - vert 57 ( 0.2252960056 0.7543720007 ) 103 3 - vert 58 ( 0.1481419951 0.7589809895 ) 90 2 - vert 59 ( 0.1468330026 0.8477370143 ) 135 2 - vert 60 ( 0.1145529971 0.8041529655 ) 137 2 - vert 61 ( 0.3770430088 0.8254489899 ) 139 3 - vert 62 ( 0.3803679943 0.7724460363 ) 109 3 - vert 63 ( 0.344987005 0.7649760246 ) 114 3 - vert 64 ( 0.4699060023 0.8589860201 ) 142 2 - vert 65 ( 0.4345059991 0.8588770032 ) 144 1 - vert 66 ( 0.3030669987 0.7613469958 ) 117 3 - vert 67 ( 0.3381139934 0.8322799802 ) 145 3 - vert 68 ( 0.2960549891 0.770227015 ) 100 3 - vert 69 ( 0.2921499908 0.8304219842 ) 148 3 - vert 70 ( 0.2967909873 0.836574018 ) 151 3 - vert 71 ( 0.4184370041 0.8095629811 ) 154 1 - vert 72 ( 0.3814359903 0.8405669928 ) 155 1 - vert 73 ( 0.4092260003 0.8773649931 ) 156 2 - vert 74 ( 0.8919050097 0.7766100168 ) 158 2 - vert 75 ( 0.8541039824 0.7786849737 ) 160 2 - vert 76 ( 0.6808059812 0.750222981 ) 162 2 - vert 77 ( 0.6849370003 0.7136059999 ) 164 2 - vert 78 ( 0.672532022 0.7460399866 ) 166 2 - vert 79 ( 0.6798319817 0.7077220082 ) 168 2 - vert 80 ( 0.6351929903 0.8153170347 ) 170 1 - vert 81 ( 0.5888410211 0.8704550266 ) 171 1 - vert 82 ( 0.6525160074 0.8732110262 ) 172 1 - vert 83 ( 0.6414099932 0.7711870074 ) 173 2 - vert 84 ( 0.5575019717 0.8443549871 ) 175 1 - vert 85 ( 0.5793939829 0.9110640287 ) 176 1 - vert 86 ( 0.6623129845 0.9541170001 ) 177 2 - vert 87 ( 0.6163240075 0.9738110304 ) 179 1 - vert 88 ( 0.6468039751 0.9751800299 ) 120 2 - vert 89 ( 0.9491220117 0.8502910137 ) 180 1 - vert 90 ( 0.9394869804 0.8753409982 ) 181 1 - vert 91 ( 0.9763280153 0.8443549871 ) 175 1 - vert 92 ( 0.9290239811 0.8091560006 ) 182 1 - vert 93 ( 0.9781579971 0.8110690117 ) 183 1 - vert 94 ( 0.9359740019 0.777485013 ) 184 2 - vert 95 ( 0.1567460001 0.9326919913 ) 186 3 - vert 96 ( 0.142772004 0.9950249791 ) 135 2 - vert 97 ( 0.1199629977 0.925417006 ) 189 3 - vert 98 ( 0.0984729975 0.9889780283 ) 192 2 - vert 99 ( 0.0671190023 0.9296090007 ) 194 3 - vert 100 ( 0.0691400021 0.9647510052 ) 148 3 - vert 101 ( 0.1062429994 0.8627759814 ) 197 2 - vert 102 ( 0.0722839981 0.8739880323 ) 199 2 - vert 103 ( 0.0371010005 0.8736259937 ) 201 2 - vert 104 ( 0.0511349998 0.9777719975 ) 151 3 - vert 105 ( 0.2250619978 0.8450019956 ) 192 2 - vert 106 ( 0.4998059869 0.861899972 ) 201 2 - vert 107 ( 0.0954750031 0.8413829803 ) 203 1 - vert 108 ( 0.0685229972 0.8131780028 ) 204 1 - vert 109 ( 0.0443269983 0.8613319993 ) 205 1 - vert 110 ( 0.050175 0.3232129812 ) 206 1 - vert 111 ( 0.0065159998 0.3214889765 ) 207 1 - vert 112 ( 0.0065159998 0.3697590232 ) 208 2 - vert 113 ( 0.0590239987 0.3620380163 ) 210 1 - vert 114 ( 0.0589749999 0.2394239902 ) 211 1 - vert 115 ( 0.0801289976 0.2233279943 ) 212 1 - vert 116 ( 0.0065159998 0.241335988 ) 213 1 - vert 117 ( 0.0465070009 0.4203100204 ) 214 2 - vert 118 ( 0.0065159998 0.4406909943 ) 216 2 - vert 119 ( 0.0619609989 0.4318109751 ) 218 2 - vert 120 ( 0.060029 0.4576629996 ) 220 5 - vert 121 ( 0.0065159998 0.4609590173 ) 225 5 - vert 122 ( 0.092869997 0.3302260041 ) 230 1 - vert 123 ( 0.1114730015 0.3644940257 ) 231 2 - vert 124 ( 0.1236369982 0.3769310117 ) 233 2 - vert 125 ( 0.1390209943 0.4031000137 ) 235 2 - vert 126 ( 0.1319220066 0.4433910251 ) 237 5 - vert 127 ( 0.0923580006 0.2776380181 ) 242 1 - vert 128 ( 0.1795710027 0.3727359772 ) 243 2 - vert 129 ( 0.1975470036 0.3964560032 ) 245 5 - vert 130 ( 0.2266270071 0.3543310165 ) 250 5 - vert 131 ( 0.1951809973 0.3377540112 ) 255 3 - vert 132 ( 0.2126490027 0.3043640256 ) 258 3 - vert 133 ( 0.1838500053 0.3102939725 ) 261 2 - vert 134 ( 0.5059810281 0.6366209984 ) 263 4 - vert 135 ( 0.4374749959 0.7047590017 ) 267 4 - vert 136 ( 0.5059810281 0.7197639942 ) 271 4 - vert 137 ( 0.4360510111 0.6340789795 ) 275 4 - vert 138 ( 0.3648679852 0.6730520129 ) 279 4 - vert 139 ( 0.2609710097 0.6615290046 ) 283 3 - vert 140 ( 0.1720129997 0.6700060368 ) 286 4 - vert 141 ( 0.2455070019 0.7123420238 ) 290 3 - vert 142 ( 0.1789309978 0.733438015 ) 293 4 - vert 143 ( 0.0895859972 0.7682989836 ) 297 4 - vert 144 ( 0.6967930198 0.4908130169 ) 293 4 - vert 145 ( 0.6549950242 0.5056320429 ) 297 4 - vert 146 ( 0.6647830009 0.5649769902 ) 301 2 - vert 147 ( 0.6981599927 0.6405650377 ) 303 2 - vert 148 ( 0.6634619832 0.6449390054 ) 305 1 - vert 149 ( 0.7041609883 0.6749880314 ) 306 1 - vert 150 ( 0.6137850285 0.5639289618 ) 307 2 - vert 151 ( 0.0065159998 0.754437983 ) 309 5 - vert 152 ( 0.6051589847 0.6676850319 ) 314 1 - vert 153 ( 0.6680549979 0.6914640069 ) 315 1 - vert 154 ( 0.6247270107 0.7169979811 ) 316 2 - vert 155 ( 0.831438005 0.7114639878 ) 318 2 - vert 156 ( 0.7931979895 0.6886389852 ) 320 1 - vert 157 ( 0.775233984 0.7200039625 ) 321 2 - vert 158 ( 0.7634339929 0.6712529659 ) 323 1 - vert 159 ( 0.7854220271 0.4997559786 ) 324 3 - vert 160 ( 0.3582600057 0.7040259838 ) 327 3 - vert 161 ( 0.3119899929 0.6755549908 ) 330 3 - vert 162 ( 0.3432019949 0.7501469851 ) 333 2 - vert 163 ( 0.8750720024 0.5566110015 ) 335 2 - vert 164 ( 0.8672090173 0.7044849992 ) 337 2 - vert 165 ( 0.0065159998 0.7831220031 ) 339 4 - vert 166 ( 0.0084809996 0.7973729968 ) 343 4 - vert 167 ( 0.0429849997 0.7849299908 ) 347 3 - vert 168 ( 0.4615980089 0.7631250024 ) 350 3 - vert 169 ( 0.5059810281 0.784916997 ) 343 4 - vert 170 ( 0.9633529782 0.533115983 ) 353 4 - vert 171 ( 0.9105299711 0.5090619922 ) 350 3 - vert 172 ( 0.9190840125 0.5449849963 ) 357 2 - vert 173 ( 0.9549890161 0.5179150105 ) 343 4 - vert 174 ( 0.9668049812 0.6705080271 ) 359 3 - vert 175 ( 0.8322579861 0.5167169571 ) 333 2 - vert 176 ( 0.9363179803 0.7234449983 ) 362 2 - vert 177 ( 0.8840529919 0.7304940224 ) 364 2 - vert 178 ( 0.9387699962 0.7510370016 ) 366 2 - vert 179 ( 0.9924079776 0.7201700211 ) 368 2 - vert 180 ( 0.231716007 0.1300470233 ) 370 1 - vert 181 ( 0.2651230097 0.0813800097 ) 371 1 - vert 182 ( 0.1575219929 0.1377019882 ) 372 1 - vert 183 ( 0.1275950074 0.2032880187 ) 373 1 - vert 184 ( 0.1097650006 0.1816179752 ) 374 1 - vert 185 ( 0.1622789949 0.2744349837 ) 375 1 - vert 186 ( 0.1449230015 0.2588300109 ) 376 1 - vert 187 ( 0.1543660015 0.3100489974 ) 377 1 - vert 188 ( 0.2011130005 0.2450569868 ) 378 2 - vert 189 ( 0.1798920035 0.2896710038 ) 380 1 - vert 190 ( 0.1195449978 0.2624899745 ) 381 1 - vert 191 ( 0.3347890079 0.1231290102 ) 382 1 - vert 192 ( 0.2832069993 0.1324700117 ) 383 2 - vert 193 ( 0.3146199882 0.154779017 ) 385 3 - vert 194 ( 0.2759419978 0.1056579947 ) 388 1 - vert 195 ( 0.2557039857 0.0573949814 ) 389 1 - vert 196 ( 0.3680300117 0.0830249786 ) 390 1 - vert 197 ( 0.3490389884 0.0520790219 ) 391 1 - vert 198 ( 0.4238780141 0.0786089897 ) 392 1 - vert 199 ( 0.4317390025 0.0372989774 ) 393 1 - vert 200 ( 0.5061429739 0.1317269802 ) 394 1 - vert 201 ( 0.4318900108 0.1638159752 ) 395 2 - vert 202 ( 0.5074750185 0.2028980255 ) 397 3 - vert 203 ( 0.4227589965 0.2057480216 ) 400 3 - vert 204 ( 0.2406419963 0.1769019961 ) 403 2 - vert 205 ( 0.2051759958 0.1735619903 ) 405 1 - vert 206 ( 0.1744340062 0.220081985 ) 406 1 - vert 207 ( 0.2465550005 0.1521580219 ) 407 2 - vert 208 ( 0.1797610074 0.1598939896 ) 409 1 - vert 209 ( 0.158870995 0.3460299969 ) 410 1 - vert 210 ( 0.1897740066 0.4437699914 ) 411 4 - vert 211 ( 0.2535789907 0.419484973 ) 415 4 - vert 212 ( 0.2562269866 0.4546560049 ) 419 4 - vert 213 ( 0.3023479879 0.4379019737 ) 423 5 - vert 214 ( 0.1785210073 0.4856939912 ) 428 5 - vert 215 ( 0.267313987 0.4916909933 ) 433 3 - vert 216 ( 0.3238539994 0.4838550091 ) 436 3 - vert 217 ( 0.3259119987 0.5254420042 ) 439 4 - vert 218 ( 0.2617740035 0.5288079977 ) 443 6 - vert 219 ( 0.2601180077 0.5753580332 ) 449 7 - vert 220 ( 0.1771450043 0.5328660011 ) 456 6 - vert 221 ( 0.1156420037 0.5386649966 ) 462 7 - vert 222 ( 0.1676560044 0.5788570046 ) 469 6 - vert 223 ( 0.0065159998 0.5438269973 ) 475 7 - vert 224 ( 0.0065159998 0.5852819681 ) 482 6 - vert 225 ( 0.3238320053 0.5771999955 ) 488 5 - vert 226 ( 0.3985019922 0.5732070208 ) 493 4 - vert 227 ( 0.374740988 0.5363789797 ) 497 3 - vert 228 ( 0.3424969912 0.4310389757 ) 500 4 - vert 229 ( 0.3764939904 0.3386369944 ) 504 5 - vert 230 ( 0.3347069919 0.3750389814 ) 509 4 - vert 231 ( 0.3833549917 0.4279819727 ) 513 3 - vert 232 ( 0.4275760055 0.5332919955 ) 516 3 - vert 233 ( 0.5059810281 0.5782610178 ) 519 4 - vert 234 ( 0.1162030026 0.4921140075 ) 523 5 - vert 235 ( 0.3679859936 0.4906420112 ) 528 3 - vert 236 ( 0.4232780039 0.3225439787 ) 531 5 - vert 237 ( 0.5059810281 0.2613589764 ) 536 5 - vert 238 ( 0.405806005 0.2649800181 ) 541 5 - vert 239 ( 0.5059810281 0.3332290053 ) 546 4 - vert 240 ( 0.0065159998 0.4996799827 ) 550 5 - vert 241 ( 0.0967779979 0.0295510292 ) 555 1 - vert 242 ( 0.0973929986 0.1248580217 ) 556 1 - vert 243 ( 0.1206220016 0.1036149859 ) 557 1 - vert 244 ( 0.1202600002 0.0474590063 ) 558 1 - vert 245 ( 0.1317780018 0.0747280121 ) 559 1 - vert 246 ( 0.0235169996 0.1227089763 ) 560 1 - vert 247 ( 0.0229979996 0.0422390103 ) 561 1 - vert 248 ( 0.0050789998 0.0837709904 ) 562 1 - vert 249 ( 0.0576220006 0.0236719847 ) 563 1 - vert 250 ( 0.0583489984 0.136318028 ) 564 1 - vert 251 ( 0.0364320017 0.2071629763 ) 559 1 - vert 252 ( 0.0754119977 0.1795169711 ) 558 1 - vert 253 ( 0.6215360165 0.1438580155 ) 565 1 - vert 254 ( 0.6050410271 0.1750259995 ) 566 1 - vert 255 ( 0.6485999823 0.1894659996 ) 567 1 - vert 256 ( 0.5503559709 0.1505730152 ) 568 3 - vert 257 ( 0.5684760213 0.1924020052 ) 571 1 - vert 258 ( 0.6194599867 0.2412859797 ) 572 1 - vert 259 ( 0.5446100235 0.2326490283 ) 573 3 - vert 260 ( 0.5871199965 0.2764289975 ) 576 3 - vert 261 ( 0.6012679935 0.214146018 ) 579 1 - vert 262 ( 0.5271469951 0.1277109981 ) 580 4 - vert 263 ( 0.519307971 0.1888660192 ) 584 3 - vert 264 ( 0.5277119875 0.3224319816 ) 587 3 - vert 265 ( 0.5723069906 0.3127070069 ) 590 3 - vert 266 ( 0.6145589948 0.2983120084 ) 593 3 - vert 267 ( 0.5191360116 0.2777770162 ) 596 4 - vert 268 ( 0.6892009974 0.1287860274 ) 600 1 - vert 269 ( 0.6886360049 0.1012679935 ) 601 1 - vert 270 ( 0.6238200068 0.1026129723 ) 602 1 - vert 271 ( 0.6785889864 0.1864960194 ) 603 1 - vert 272 ( 0.7339950204 0.175903976 ) 604 1 - vert 273 ( 0.6746309996 0.0066130161 ) 605 2 - vert 274 ( 0.6742380261 0.0376999974 ) 607 2 - vert 275 ( 0.7503640056 0.0266389847 ) 609 1 - vert 276 ( 0.7935450077 0.2292519808 ) 610 2 - vert 277 ( 0.7950569987 0.2787389755 ) 612 2 - vert 278 ( 0.8341670036 0.2777050138 ) 614 1 - vert 279 ( 0.9179019928 0.2129709721 ) 615 2 - vert 280 ( 0.8471310139 0.2394390106 ) 617 1 - vert 281 ( 0.8974779844 0.2606310248 ) 618 2 - vert 282 ( 0.8345289826 0.2047100067 ) 620 1 - vert 283 ( 0.8579490185 0.1703159809 ) 621 1 - vert 284 ( 0.7965859771 0.1753519773 ) 622 2 - vert 285 ( 0.8064569831 0.1446980238 ) 624 2 - vert 286 ( 0.7179740071 0.2419899702 ) 626 1 - vert 287 ( 0.6798750162 0.2467269897 ) 627 1 - vert 288 ( 0.7722390294 0.258818984 ) 628 2 - vert 289 ( 0.6807339787 0.2821919918 ) 630 2 - vert 290 ( 0.7193589807 0.2930399776 ) 632 2 - vert 291 ( 0.7516229749 0.3088399768 ) 609 1 - vert 292 ( 0.6860920191 0.3187590241 ) 605 2 - vert 293 ( 0.8071470261 0.2980099916 ) 634 2 - vert 294 ( 0.866132021 0.2954490185 ) 636 2 - vert 295 ( 0.7183579803 0.1012600064 ) 638 1 - vert 296 ( 0.7525359988 0.1319490075 ) 639 2 - vert 297 ( 0.8066539764 0.107509017 ) 641 2 - vert 298 ( 0.8242530227 0.1078130007 ) 643 2 - vert 299 ( 0.8711100221 0.1343280077 ) 645 2 - vert 300 ( 0.9827859998 0.1666780114 ) 647 2 - vert 301 ( 0.8036630154 0.0820199847 ) 649 2 - vert 302 ( 0.7453380227 0.0694209933 ) 651 1 - vert 303 ( 0.8680710196 0.027320981 ) 636 2 - vert 304 ( 0.8723409772 0.0675659776 ) 652 2 - vert 305 ( 0.9717440009 0.0449969769 ) 654 2 - vert 306 ( 0.806961 0.0372700095 ) 634 2 - vert 307 ( 0.8223850131 0.0791649818 ) 656 2 - vert 308 ( 0.9664080143 0.2339140177 ) 658 2 - vert 309 ( 0.969317019 0.2536500096 ) 654 2 - vert 310 ( 0.8898929954 0.0980240107 ) 660 2 - vert 311 ( 0.9890729785 0.0804449916 ) 662 2 - vert 312 ( 0.6881549954 0.0778920054 ) 664 1 - vert 313 ( 0.8541460037 0.3220049739 ) 647 2 - vert 314 ( 0.8374930024 0.3399940133 ) 665 2 - vert 315 ( 0.8126410246 0.3228949904 ) 667 2 - vert 316 ( 0.991271019 0.1175420284 ) 667 2 - vert 317 ( 0.9278730154 0.411831975 ) 669 2 - vert 318 ( 0.9395089746 0.3789899945 ) 671 2 - vert 319 ( 0.9386469722 0.3999459743 ) 673 2 - vert 320 ( 0.6749150157 0.3546450138 ) 675 2 - vert 321 ( 0.728399992 0.3689399958 ) 677 2 - vert 322 ( 0.6946489811 0.3748869896 ) 673 2 - vert 323 ( 0.9142100215 0.4110490084 ) 679 1 - vert 324 ( 0.6943200231 0.4136070013 ) 669 2 - vert 325 ( 0.7252910137 0.3387629986 ) 680 3 - vert 326 ( 0.786157012 0.3374980092 ) 683 3 - vert 327 ( 0.7365289927 0.4275730252 ) 686 3 - vert 328 ( 0.7038620114 0.4392939806 ) 689 1 - vert 329 ( 0.7230200171 0.4433069825 ) 690 1 - vert 330 ( 0.9325879812 0.4340230227 ) 689 1 - vert 331 ( 0.9354339838 0.466753006 ) 691 1 - vert 332 ( 0.9280790091 0.4787639976 ) 692 1 - vert 333 ( 0.7003700137 0.4619250298 ) 691 1 - vert 334 ( 0.7182919979 0.4647610188 ) 693 1 - vert 335 ( 0.8563839793 0.4686589837 ) 694 1 - vert 336 ( 0.8783879876 0.4474790096 ) 695 2 - vert 337 ( 0.8704000115 0.4834579825 ) 697 1 - vert 338 ( 0.8125690222 0.3461310267 ) 698 2 - vert 339 ( 0.8071280122 0.4110659957 ) 700 2 - vert 340 ( 0.8074550033 0.4590309858 ) 702 1 - vert 341 ( 0.77887398 0.4778410196 ) 703 1 - vert 342 ( 0.7554550171 0.4745789766 ) 697 1 - vert 343 ( 0.8201879859 0.4488729835 ) 704 1 - vert 344 ( 0.8266329765 0.4640110135 ) 702 1 - vert 345 ( 0.8486109972 0.4842090011 ) 703 1 - vert 346 ( 0.8229140043 0.4289429784 ) 705 3 - vert 347 ( 0.8675720096 0.4362750053 ) 708 2 - vert 348 ( 0.8288050294 0.4070209861 ) 710 2 - vert 349 ( 0.8066689968 0.4311659932 ) 712 3 - vert 350 ( 0.9206449986 0.436357975 ) 715 1 - vert 351 ( 0.885668993 0.3379909992 ) 716 2 - vert 352 ( 0.8785380125 0.4087280035 ) 718 2 - vert 353 ( 0.9502670169 0.4085540175 ) 720 1 - vert 354 ( 0.9695450068 0.4046720266 ) 721 1 - vert 355 ( 0.9723470211 0.4295179844 ) 722 1 - vert 356 ( 0.9571650028 0.3766009808 ) 723 2 - vert 357 ( 0.9873470068 0.4016770124 ) 725 1 - vert 358 ( 0.9553869963 0.4268180132 ) 726 1 - vert 359 ( 0.9388960004 0.4156810045 ) 727 1 - vert 360 ( 0.6719589829 0.3949229717 ) 726 1 - vert 361 ( 0.662891984 0.401835978 ) 722 1 - vert 362 ( 0.6582329869 0.3899409771 ) 728 1 - vert 363 ( 0.9254279733 0.3435360193 ) 729 4 - vert 364 ( 0.9501860142 0.340478003 ) 733 3 - vert 365 ( 0.9649310112 0.3407809734 ) 680 3 - vert 366 ( 0.9743750095 0.3744570017 ) 675 2 - vert 367 ( 0.6601160169 0.3706610203 ) 725 1 - vert 368 ( 0.679700017 0.3784369826 ) 727 1 - vert 369 ( 0.8881250024 0.4392629862 ) 690 1 - vert 370 ( 0.9025089741 0.4375380278 ) 736 1 - vert 371 ( 0.8979420066 0.4786270261 ) 693 1 - vert 372 ( 0.9114570022 0.4798520207 ) 737 1 - vert 373 ( 0.8941029906 0.4077469707 ) 738 1 - vert 374 ( 0.8857489824 0.4264069796 ) 686 3 - vert 375 ( 0.7173299789 0.4751110077 ) 737 1 - vert 376 ( 0.6988959908 0.4720469713 ) 692 1 - vert 377 ( 0.9152730107 0.4601749778 ) 739 1 - vert 378 ( 0.7451140285 0.4509699941 ) 695 2 - vert 379 ( 0.9856039882 0.4272310138 ) 728 1 - vert 380 ( 0.7929829955 0.3236700296 ) 662 2 - vert 381 ( 0.9261609912 0.3216840029 ) 658 2 - vert 382 ( 0.7564870119 0.3203430176 ) 654 2 - vert 383 ( 0.964854002 0.324901998 ) 654 2 - vert 384 ( 0.9684699774 0.2138469815 ) 740 2 - vert 385 ( 0.8936830163 0.3203369975 ) 740 2 - vert 386 ( 0.6591830254 0.2872549891 ) 742 1 - vert 387 ( 0.6338350177 0.3373150229 ) 743 2 - vert 388 ( 0.1525540054 0.2092919946 ) 745 1 - vert 389 ( 0.2533960044 0.2069010139 ) 596 4 - vert 390 ( 0.2199510038 0.2656080127 ) 587 3 - vert 391 ( 0.2721250057 0.1604350209 ) 746 3 - vert 392 ( 0.2930789888 0.1885640025 ) 584 3 - vert 393 ( 0.3293479979 0.2079889774 ) 580 4 - vert 394 ( 0.2728169858 0.3897690177 ) 749 3 - vert 395 ( 0.30409199 0.3898140192 ) 752 3 - vert 396 ( 0.5059810281 0.4857630134 ) 755 3 - vert 397 ( 0.4221470058 0.4826949835 ) 758 3 - vert 398 ( 0.5059810281 0.532845974 ) 761 3 - vert 399 ( 0.4368599951 0.4198120236 ) 764 3 - vert 400 ( 0.5059810281 0.4152190089 ) 767 3 - vert 401 ( 0.3681820035 0.2114120126 ) 770 4 - vert 402 ( 0.3384110034 0.2618330121 ) 774 3 - vert 403 ( 0.4078730047 0.124785006 ) 777 1 - vert 404 ( 0.4499480128 0.1207879782 ) 778 1 - vert 405 ( 0.5542899966 0.3567519784 ) 258 3 - vert 406 ( 0.596134007 0.3489469886 ) 779 2 - vert 407 ( 0.2432550043 0.3346539736 ) 779 2 - vert 408 ( 0.6163349748 0.0692210197 ) 781 3 - vert 409 ( 0.6279810071 0.0384929776 ) 784 4 - vert 410 ( 0.6434649825 0.3630729914 ) 788 4 - vert 411 ( 0.6343989968 0.0070509911 ) 788 4 - vert 412 ( 0.3647029996 0.2810729742 ) 792 5 - vert 413 ( 0.483927995 0.0733219981 ) 797 1 - vert 414 ( 0.3497880101 0.3132119775 ) 798 5 - vert 415 ( 0.3280769885 0.3136879802 ) 781 3 - vert 416 ( 0.285048008 0.348886013 ) 788 4 - vert 417 ( 0.3108820021 0.340839982 ) 784 4 - vert 418 ( 0.3387089968 0.3333929777 ) 803 4 - vert 419 ( 0.3816170096 0.1763650179 ) 807 3 - vert 420 ( 0.2986379862 0.0374180079 ) 561 1 - vert 421 ( 0.2425269932 0.0346480012 ) 563 1 - vert 422 ( 0.3267560005 0.0088989735 ) 562 1 - vert 423 ( 0.1589429975 0.1027749777 ) 374 1 - vert 424 ( 0.1013299972 0.1503189802 ) 555 1 - vert 425 ( 0.1658499986 0.0738989711 ) 555 1 - vert 426 ( 0.3890689909 0.1418799758 ) 810 2 - vert 427 ( 0.0402080007 0.2810630202 ) 812 1 - vert 428 ( 0.0065159998 0.2817900181 ) 813 1 - vert 429 ( 0.2045989931 0.5922920108 ) 814 6 - vert 430 ( 0.1605589986 0.5968669653 ) 820 6 - vert 431 ( 0.3437829912 0.5931780338 ) 826 5 - vert 432 ( 0.3059329987 0.5957419872 ) 831 6 - vert 433 ( 0.3085429966 0.6246919632 ) 837 4 - vert 434 ( 0.285898 0.6023510098 ) 841 7 - vert 435 ( 0.2898739874 0.6368750334 ) 848 4 - vert 436 ( 0.3452390134 0.633047998 ) 852 4 - vert 437 ( 0.8994579911 0.7528679967 ) 856 2 - vert 438 ( 0.8490179777 0.7567310333 ) 858 2 - vert 439 ( 0.8048490286 0.7480499744 ) 860 2 - vert 440 ( 0.7894909978 0.7785140276 ) 862 2 - vert 441 ( 0.5059810281 0.6101770401 ) 864 4 - vert 442 ( 0.4315229952 0.5993089676 ) 868 4 - vert 443 ( 0.3875670135 0.5959990025 ) 872 4 - vert 444 ( 0.2522189915 0.635357976 ) 876 4 - vert 445 ( 0.2501319945 0.5896309614 ) 880 6 - vert 446 ( 0.3149810135 0.653504014 ) 886 3 - vert 447 ( 0.709495008 0.7045869827 ) 889 2 - vert 448 ( 0.8441479802 0.7307699919 ) 891 2 - vert 449 ( 0.2934280038 0.7219760418 ) 324 3 - vert 450 ( 0.7434340119 0.4853699803 ) 290 3 - vert 451 ( 0.6254940033 0.5146830082 ) 347 3 - vert 452 ( 0.5445259809 0.533115983 ) 353 4 - vert 453 ( 0.5361629725 0.5179150105 ) 343 4 - vert 454 ( 0.547977984 0.6705080271 ) 359 3 - vert 455 ( 0.9038760066 0.6887279749 ) 893 3 - vert 456 ( 0.5735809803 0.7201700211 ) 368 2 - vert 457 ( 0.5199440122 0.7510370016 ) 366 2 - vert 458 ( 0.600022018 0.7551559806 ) 896 2 - vert 459 ( 0.8718739748 0.9073569775 ) 898 1 - vert 460 ( 0.5171480179 0.777485013 ) 184 2 - vert 461 ( 0.009513 0.866418004 ) 142 2 - vert 462 ( 0.5090919733 0.9344699979 ) 139 3 - vert 463 ( 0.8207579851 0.982032001 ) 155 1 - vert 464 ( 0.7927100062 0.992174983 ) 108 1 - vert 465 ( 0.4180650115 0.7926020026 ) 899 1 - vert 466 ( 0.4634110034 0.7972790003 ) 900 1 - vert 467 ( 0.4704009891 0.7775039673 ) 901 1 - vert 468 ( 0.0730660036 0.7969409823 ) 901 1 - vert 469 ( 0.0261439998 0.8045679927 ) 900 1 - vert 470 ( 0.5728420019 0.9460589886 ) 902 1 - vert 471 ( 0.5299739838 0.950699985 ) 901 1 - vert 472 ( 0.5741479993 0.9755619764 ) 203 1 - vert 473 ( 0.8704159856 0.9541760087 ) 899 1 - vert 474 ( 0.8163290024 0.9539530277 ) 903 1 - vert 475 ( 0.0306299999 0.9714379907 ) 145 3 - vert 476 ( 0.0191229992 0.9466019869 ) 139 3 - vert 477 ( 0.6119499803 0.9860330224 ) 197 2 - vert 478 ( 0.8543279767 0.8052660227 ) 904 1 - vert 479 ( 0.8270549774 0.8075270057 ) 905 1 - vert 480 ( 0.8478990197 0.8757280111 ) 906 1 - vert 481 ( 0.5206599832 0.8753409982 ) 181 1 - vert 482 ( 0.5232509971 0.9213680029 ) 907 1 - vert 483 ( 0.5302960277 0.8502910137 ) 180 1 - vert 484 ( 0.5843650103 0.9352009892 ) 908 1 - vert 485 ( 0.9488000274 0.950699985 ) 901 1 - vert 486 ( 0.9420779943 0.9213680029 ) 907 1 - vert 487 ( 0.5593309999 0.8110690117 ) 183 1 - vert 488 ( 0.2135220021 0.9624720216 ) 909 2 - vert 489 ( 0.2032800019 0.9954429865 ) 137 2 - vert 490 ( 0.378320992 0.6392099857 ) 911 4 - vert 491 ( 0.8749319911 0.5100799799 ) 915 3 - vert 492 ( 0.3984470069 0.7525379658 ) 915 3 - vert 493 ( 0.5807430148 0.1112229824 ) 918 3 - vert 494 ( 0.5710319877 0.0789110065 ) 774 3 - vert 495 ( 0.5979750156 0.0865190029 ) 921 3 - vert 496 ( 0.4668169916 0.8244280219 ) 924 1 - vert 497 ( 0.0193520002 0.8318600059 ) 924 1 - vert 498 ( 0.7620570064 0.7480289936 ) 925 2 - vert 499 ( 0.6472489834 0.7385339737 ) 927 2 - vert 500 ( 0.1140540019 0.5849939585 ) 929 6 - vert 501 ( 0.1113319993 0.7144190073 ) 935 4 - vert 502 ( 0.0755819976 0.7149720192 ) 939 4 - vert 503 ( 0.0878639966 0.7418110371 ) 943 4 - vert 504 ( 0.0771259964 0.5961179733 ) 947 5 - vert 505 ( 0.7041410208 0.7505249977 ) 952 3 - vert 506 ( 0.7266179919 0.8000400066 ) 955 2 - vert 507 ( 0.6799460053 0.7962620258 ) 957 2 - vert 508 ( 0.7241439819 0.7523819804 ) 959 2 - vert 509 ( 0.7345380187 0.7539520264 ) 961 3 - vert 510 ( 0.704366982 0.7126190066 ) 964 2 - vert 511 ( 0.7249150276 0.7177790403 ) 966 2 - vert 512 ( 0.7368519902 0.7151950002 ) 968 2 - vert 513 ( 0.7568039894 0.777576983 ) 970 2 - vert 514 ( 0.8701090217 0.8927010298 ) 972 1 - vert 515 ( 0.9015840292 0.8468999863 ) 973 1 - vert 516 ( 0.9042909741 0.9045029879 ) 974 1 - vert 517 ( 0.734070003 0.8368970156 ) 975 1 - vert 518 ( 0.6791769862 0.83267802 ) 976 2 - vert 519 ( 0.7839429975 0.8137180209 ) 978 2 - vert 520 ( 0.8039349914 0.8621749878 ) 980 1 - vert 521 ( 0.7422800064 0.8775190115 ) 981 1 - vert 522 ( 0.6955360174 0.8862699866 ) 982 1 - vert 523 ( 0.8159909844 0.8497760296 ) 983 1 - vert 524 ( 0.7301239967 0.9030950069 ) 984 1 - vert 525 ( 0.8420280218 0.9083549976 ) 985 1 - vert 526 ( 0.8047969937 0.9199159741 ) 986 1 - vert 527 ( 0.6573690176 0.9002029896 ) 987 1 - vert 528 ( 0.7329789996 0.9312850237 ) 988 1 - vert 529 ( 0.6533820033 0.9263920188 ) 989 1 - vert 530 ( 0.7674570084 0.9810230136 ) 990 2 - vert 531 ( 0.7148280144 0.9588119984 ) 992 2 - vert 532 ( 0.7286459804 0.9787729979 ) 994 2 - vert 533 ( 0.868991971 0.8366839886 ) 996 1 - vert 534 ( 0.8979229927 0.8103759885 ) 997 1 - vert 535 ( 0.2428800017 0.9283080101 ) 998 2 - vert 536 ( 0.2880809903 0.9381070137 ) 1000 4 - vert 537 ( 0.2801589966 0.9951519966 ) 1004 2 - vert 538 ( 0.2602320015 0.9096509814 ) 1006 4 - vert 539 ( 0.3308880031 0.934671998 ) 1010 4 - vert 540 ( 0.396728009 0.9623540044 ) 1014 3 - vert 541 ( 0.3365319967 0.9943330288 ) 1017 3 - vert 542 ( 0.402839005 0.9280309677 ) 1020 2 - vert 543 ( 0.3863759935 0.8592050076 ) 1022 1 - vert 544 ( 0.4349130094 0.8711069822 ) 1023 2 - vert 545 ( 0.4510799944 0.946927011 ) 1025 3 - vert 546 ( 0.4385879934 0.9677169919 ) 1028 3 - vert 547 ( 0.4149670005 0.9764750004 ) 1031 3 - vert 548 ( 0.1483460069 0.8560280204 ) 1034 2 - vert 549 ( 0.2995730042 0.8568370342 ) 994 2 - vert 550 ( 0.2727760077 0.8909019828 ) 1036 4 - vert 551 ( 0.165241003 0.8861150146 ) 1040 3 - vert 552 ( 0.1703960001 0.9069539905 ) 1043 3 - vert 553 ( 0.1953860074 0.9247580171 ) 1046 3 - vert 554 ( 0.1481419951 0.7589809895 ) 1004 2 - vert 555 ( 0.2252960056 0.7543720007 ) 1017 3 - vert 556 ( 0.1468330026 0.8477370143 ) 1049 2 - vert 557 ( 0.1145529971 0.8041529655 ) 1051 2 - vert 558 ( 0.3803679943 0.7724460363 ) 1025 3 - vert 559 ( 0.3770430088 0.8254489899 ) 1053 3 - vert 560 ( 0.344987005 0.7649760246 ) 1028 3 - vert 561 ( 0.4345059991 0.8588770032 ) 1056 1 - vert 562 ( 0.4699060023 0.8589860201 ) 1057 2 - vert 563 ( 0.3030669987 0.7613469958 ) 1031 3 - vert 564 ( 0.3381139934 0.8322799802 ) 1059 3 - vert 565 ( 0.2921499908 0.8304219842 ) 1062 3 - vert 566 ( 0.2960549891 0.770227015 ) 1014 3 - vert 567 ( 0.2967909873 0.836574018 ) 1065 3 - vert 568 ( 0.3814359903 0.8405669928 ) 1068 1 - vert 569 ( 0.4184370041 0.8095629811 ) 1069 1 - vert 570 ( 0.4092260003 0.8773649931 ) 1070 2 - vert 571 ( 0.8541039824 0.7786849737 ) 1072 2 - vert 572 ( 0.8919050097 0.7766100168 ) 1074 2 - vert 573 ( 0.6808059812 0.750222981 ) 1076 2 - vert 574 ( 0.6849370003 0.7136059999 ) 1078 2 - vert 575 ( 0.672532022 0.7460399866 ) 1080 2 - vert 576 ( 0.6798319817 0.7077220082 ) 1082 2 - vert 577 ( 0.6351929903 0.8153170347 ) 1084 1 - vert 578 ( 0.5888410211 0.8704550266 ) 1085 1 - vert 579 ( 0.6525160074 0.8732110262 ) 1086 1 - vert 580 ( 0.6414099932 0.7711870074 ) 1087 2 - vert 581 ( 0.5575019717 0.8443549871 ) 1089 1 - vert 582 ( 0.5793939829 0.9110640287 ) 1090 1 - vert 583 ( 0.6623129845 0.9541170001 ) 1091 2 - vert 584 ( 0.6163240075 0.9738110304 ) 1093 1 - vert 585 ( 0.6468039751 0.9751800299 ) 1034 2 - vert 586 ( 0.9491220117 0.8502910137 ) 1094 1 - vert 587 ( 0.9394869804 0.8753409982 ) 1095 1 - vert 588 ( 0.9290239811 0.8091560006 ) 1096 1 - vert 589 ( 0.9763280153 0.8443549871 ) 1089 1 - vert 590 ( 0.9359740019 0.777485013 ) 1097 2 - vert 591 ( 0.9781579971 0.8110690117 ) 1099 1 - vert 592 ( 0.1567460001 0.9326919913 ) 1100 3 - vert 593 ( 0.142772004 0.9950249791 ) 1049 2 - vert 594 ( 0.1199629977 0.925417006 ) 1103 3 - vert 595 ( 0.0984729975 0.9889780283 ) 1106 2 - vert 596 ( 0.0691400021 0.9647510052 ) 1062 3 - vert 597 ( 0.0671190023 0.9296090007 ) 1108 3 - vert 598 ( 0.0722839981 0.8739880323 ) 1111 2 - vert 599 ( 0.1062429994 0.8627759814 ) 1113 2 - vert 600 ( 0.0371010005 0.8736259937 ) 1115 2 - vert 601 ( 0.0511349998 0.9777719975 ) 1065 3 - vert 602 ( 0.2250619978 0.8450019956 ) 1106 2 - vert 603 ( 0.4998059869 0.861899972 ) 1115 2 - vert 604 ( 0.0685229972 0.8131780028 ) 1117 1 - vert 605 ( 0.0954750031 0.8413829803 ) 1118 1 - vert 606 ( 0.0443269983 0.8613319993 ) 1119 1 - vert 607 ( 0.050175 0.3232129812 ) 1120 1 - vert 608 ( 0.0590239987 0.3620380163 ) 1121 1 - vert 609 ( 0.0801289976 0.2233279943 ) 1122 1 - vert 610 ( 0.0589749999 0.2394239902 ) 1123 1 - vert 611 ( 0.0465070009 0.4203100204 ) 1124 2 - vert 612 ( 0.0619609989 0.4318109751 ) 1126 2 - vert 613 ( 0.060029 0.4576629996 ) 1128 5 - vert 614 ( 0.092869997 0.3302260041 ) 1133 1 - vert 615 ( 0.1114730015 0.3644940257 ) 1134 2 - vert 616 ( 0.1236369982 0.3769310117 ) 1136 2 - vert 617 ( 0.1390209943 0.4031000137 ) 1138 2 - vert 618 ( 0.1319220066 0.4433910251 ) 1140 5 - vert 619 ( 0.0923580006 0.2776380181 ) 1145 1 - vert 620 ( 0.1795710027 0.3727359772 ) 1146 2 - vert 621 ( 0.1975470036 0.3964560032 ) 1148 5 - vert 622 ( 0.1951809973 0.3377540112 ) 1153 3 - vert 623 ( 0.2266270071 0.3543310165 ) 1156 5 - vert 624 ( 0.2126490027 0.3043640256 ) 1161 3 - vert 625 ( 0.1838500053 0.3102939725 ) 1164 2 - vert 626 ( 0.4374749959 0.7047590017 ) 1166 4 - vert 627 ( 0.3648679852 0.6730520129 ) 1170 4 - vert 628 ( 0.4360510111 0.6340789795 ) 1174 4 - vert 629 ( 0.1720129997 0.6700060368 ) 1178 4 - vert 630 ( 0.2609710097 0.6615290046 ) 1182 3 - vert 631 ( 0.2455070019 0.7123420238 ) 1185 3 - vert 632 ( 0.1789309978 0.733438015 ) 1188 4 - vert 633 ( 0.0895859972 0.7682989836 ) 1192 4 - vert 634 ( 0.6549950242 0.5056320429 ) 1192 4 - vert 635 ( 0.6967930198 0.4908130169 ) 1188 4 - vert 636 ( 0.6647830009 0.5649769902 ) 1196 2 - vert 637 ( 0.6634619832 0.6449390054 ) 1198 1 - vert 638 ( 0.6981599927 0.6405650377 ) 1199 2 - vert 639 ( 0.7041609883 0.6749880314 ) 1201 1 - vert 640 ( 0.6137850285 0.5639289618 ) 1202 2 - vert 641 ( 0.6051589847 0.6676850319 ) 1204 1 - vert 642 ( 0.6680549979 0.6914640069 ) 1205 1 - vert 643 ( 0.6247270107 0.7169979811 ) 1206 2 - vert 644 ( 0.7931979895 0.6886389852 ) 1208 1 - vert 645 ( 0.831438005 0.7114639878 ) 1209 2 - vert 646 ( 0.775233984 0.7200039625 ) 1211 2 - vert 647 ( 0.7634339929 0.6712529659 ) 1213 1 - vert 648 ( 0.7854220271 0.4997559786 ) 1214 3 - vert 649 ( 0.3119899929 0.6755549908 ) 1217 3 - vert 650 ( 0.3582600057 0.7040259838 ) 1220 3 - vert 651 ( 0.3432019949 0.7501469851 ) 1223 2 - vert 652 ( 0.8750720024 0.5566110015 ) 1225 2 - vert 653 ( 0.8672090173 0.7044849992 ) 1227 2 - vert 654 ( 0.0429849997 0.7849299908 ) 1229 3 - vert 655 ( 0.4615980089 0.7631250024 ) 1232 3 - vert 656 ( 0.9105299711 0.5090619922 ) 1232 3 - vert 657 ( 0.9633529782 0.533115983 ) 1235 4 - vert 658 ( 0.9190840125 0.5449849963 ) 1239 2 - vert 659 ( 0.9668049812 0.6705080271 ) 1241 3 - vert 660 ( 0.8322579861 0.5167169571 ) 1223 2 - vert 661 ( 0.8840529919 0.7304940224 ) 1244 2 - vert 662 ( 0.9363179803 0.7234449983 ) 1246 2 - vert 663 ( 0.9387699962 0.7510370016 ) 1248 2 - vert 664 ( 0.9924079776 0.7201700211 ) 1250 2 - vert 665 ( 0.2651230097 0.0813800097 ) 1252 1 - vert 666 ( 0.231716007 0.1300470233 ) 1253 1 - vert 667 ( 0.1575219929 0.1377019882 ) 1254 1 - vert 668 ( 0.1097650006 0.1816179752 ) 1255 1 - vert 669 ( 0.1275950074 0.2032880187 ) 1256 1 - vert 670 ( 0.1449230015 0.2588300109 ) 1257 1 - vert 671 ( 0.1622789949 0.2744349837 ) 1258 1 - vert 672 ( 0.1543660015 0.3100489974 ) 1259 1 - vert 673 ( 0.2011130005 0.2450569868 ) 1260 2 - vert 674 ( 0.1798920035 0.2896710038 ) 1262 1 - vert 675 ( 0.1195449978 0.2624899745 ) 1263 1 - vert 676 ( 0.2832069993 0.1324700117 ) 1264 2 - vert 677 ( 0.3347890079 0.1231290102 ) 1266 1 - vert 678 ( 0.3146199882 0.154779017 ) 1267 3 - vert 679 ( 0.2759419978 0.1056579947 ) 1270 1 - vert 680 ( 0.3680300117 0.0830249786 ) 1271 1 - vert 681 ( 0.2557039857 0.0573949814 ) 1272 1 - vert 682 ( 0.3490389884 0.0520790219 ) 1273 1 - vert 683 ( 0.4238780141 0.0786089897 ) 1274 1 - vert 684 ( 0.4318900108 0.1638159752 ) 1275 2 - vert 685 ( 0.4227589965 0.2057480216 ) 1277 3 - vert 686 ( 0.2051759958 0.1735619903 ) 1280 1 - vert 687 ( 0.2406419963 0.1769019961 ) 1281 2 - vert 688 ( 0.1744340062 0.220081985 ) 1283 1 - vert 689 ( 0.2465550005 0.1521580219 ) 1284 2 - vert 690 ( 0.1797610074 0.1598939896 ) 1286 1 - vert 691 ( 0.158870995 0.3460299969 ) 1287 1 - vert 692 ( 0.1897740066 0.4437699914 ) 1288 4 - vert 693 ( 0.2535789907 0.419484973 ) 1292 4 - vert 694 ( 0.2562269866 0.4546560049 ) 1296 4 - vert 695 ( 0.3023479879 0.4379019737 ) 1300 5 - vert 696 ( 0.1785210073 0.4856939912 ) 1305 5 - vert 697 ( 0.267313987 0.4916909933 ) 1310 3 - vert 698 ( 0.3238539994 0.4838550091 ) 1313 3 - vert 699 ( 0.3259119987 0.5254420042 ) 1316 4 - vert 700 ( 0.2617740035 0.5288079977 ) 1320 6 - vert 701 ( 0.2601180077 0.5753580332 ) 1326 7 - vert 702 ( 0.1156420037 0.5386649966 ) 1333 7 - vert 703 ( 0.1771450043 0.5328660011 ) 1340 6 - vert 704 ( 0.1676560044 0.5788570046 ) 1346 6 - vert 705 ( 0.3238320053 0.5771999955 ) 1352 5 - vert 706 ( 0.374740988 0.5363789797 ) 1357 3 - vert 707 ( 0.3985019922 0.5732070208 ) 1360 4 - vert 708 ( 0.3424969912 0.4310389757 ) 1364 4 - vert 709 ( 0.3347069919 0.3750389814 ) 1368 4 - vert 710 ( 0.3764939904 0.3386369944 ) 1372 5 - vert 711 ( 0.3833549917 0.4279819727 ) 1377 3 - vert 712 ( 0.4275760055 0.5332919955 ) 1380 3 - vert 713 ( 0.1162030026 0.4921140075 ) 1383 5 - vert 714 ( 0.3679859936 0.4906420112 ) 1388 3 - vert 715 ( 0.4232780039 0.3225439787 ) 1391 5 - vert 716 ( 0.405806005 0.2649800181 ) 1396 5 - vert 717 ( 0.0967779979 0.0295510292 ) 1401 1 - vert 718 ( 0.1202600002 0.0474590063 ) 1402 1 - vert 719 ( 0.0229979996 0.0422390103 ) 1403 1 - vert 720 ( 0.0576220006 0.0236719847 ) 1404 1 - vert 721 ( 0.0754119977 0.1795169711 ) 1402 1 - vert 722 ( 0.6050410271 0.1750259995 ) 1405 1 - vert 723 ( 0.6215360165 0.1438580155 ) 1406 1 - vert 724 ( 0.6485999823 0.1894659996 ) 1407 1 - vert 725 ( 0.5503559709 0.1505730152 ) 1408 3 - vert 726 ( 0.5684760213 0.1924020052 ) 1411 1 - vert 727 ( 0.5446100235 0.2326490283 ) 1412 3 - vert 728 ( 0.6194599867 0.2412859797 ) 1415 1 - vert 729 ( 0.5871199965 0.2764289975 ) 1416 3 - vert 730 ( 0.6012679935 0.214146018 ) 1419 1 - vert 731 ( 0.519307971 0.1888660192 ) 1420 3 - vert 732 ( 0.5271469951 0.1277109981 ) 1423 4 - vert 733 ( 0.5277119875 0.3224319816 ) 1427 3 - vert 734 ( 0.5723069906 0.3127070069 ) 1430 3 - vert 735 ( 0.6145589948 0.2983120084 ) 1433 3 - vert 736 ( 0.5191360116 0.2777770162 ) 1436 4 - vert 737 ( 0.6892009974 0.1287860274 ) 1440 1 - vert 738 ( 0.6886360049 0.1012679935 ) 1441 1 - vert 739 ( 0.6238200068 0.1026129723 ) 1442 1 - vert 740 ( 0.6785889864 0.1864960194 ) 1443 1 - vert 741 ( 0.7339950204 0.175903976 ) 1444 1 - vert 742 ( 0.6742380261 0.0376999974 ) 1445 2 - vert 743 ( 0.6746309996 0.0066130161 ) 1447 2 - vert 744 ( 0.7503640056 0.0266389847 ) 1449 1 - vert 745 ( 0.7950569987 0.2787389755 ) 1450 2 - vert 746 ( 0.7935450077 0.2292519808 ) 1452 2 - vert 747 ( 0.8341670036 0.2777050138 ) 1454 1 - vert 748 ( 0.8471310139 0.2394390106 ) 1455 1 - vert 749 ( 0.9179019928 0.2129709721 ) 1456 2 - vert 750 ( 0.8974779844 0.2606310248 ) 1458 2 - vert 751 ( 0.8345289826 0.2047100067 ) 1460 1 - vert 752 ( 0.8579490185 0.1703159809 ) 1461 1 - vert 753 ( 0.7965859771 0.1753519773 ) 1462 2 - vert 754 ( 0.8064569831 0.1446980238 ) 1464 2 - vert 755 ( 0.7179740071 0.2419899702 ) 1466 1 - vert 756 ( 0.6798750162 0.2467269897 ) 1467 1 - vert 757 ( 0.7722390294 0.258818984 ) 1468 2 - vert 758 ( 0.6807339787 0.2821919918 ) 1470 2 - vert 759 ( 0.7193589807 0.2930399776 ) 1472 2 - vert 760 ( 0.7516229749 0.3088399768 ) 1449 1 - vert 761 ( 0.6860920191 0.3187590241 ) 1447 2 - vert 762 ( 0.8071470261 0.2980099916 ) 1474 2 - vert 763 ( 0.866132021 0.2954490185 ) 1476 2 - vert 764 ( 0.7525359988 0.1319490075 ) 1478 2 - vert 765 ( 0.7183579803 0.1012600064 ) 1480 1 - vert 766 ( 0.8066539764 0.107509017 ) 1481 2 - vert 767 ( 0.8242530227 0.1078130007 ) 1483 2 - vert 768 ( 0.8711100221 0.1343280077 ) 1485 2 - vert 769 ( 0.9827859998 0.1666780114 ) 1487 2 - vert 770 ( 0.8036630154 0.0820199847 ) 1489 2 - vert 771 ( 0.7453380227 0.0694209933 ) 1491 1 - vert 772 ( 0.8723409772 0.0675659776 ) 1492 2 - vert 773 ( 0.8680710196 0.027320981 ) 1476 2 - vert 774 ( 0.9717440009 0.0449969769 ) 1494 2 - vert 775 ( 0.8223850131 0.0791649818 ) 1496 2 - vert 776 ( 0.806961 0.0372700095 ) 1474 2 - vert 777 ( 0.9664080143 0.2339140177 ) 1498 2 - vert 778 ( 0.969317019 0.2536500096 ) 1494 2 - vert 779 ( 0.8898929954 0.0980240107 ) 1500 2 - vert 780 ( 0.9890729785 0.0804449916 ) 1502 2 - vert 781 ( 0.6881549954 0.0778920054 ) 1504 1 - vert 782 ( 0.8374930024 0.3399940133 ) 1505 2 - vert 783 ( 0.8541460037 0.3220049739 ) 1487 2 - vert 784 ( 0.8126410246 0.3228949904 ) 1507 2 - vert 785 ( 0.991271019 0.1175420284 ) 1507 2 - vert 786 ( 0.9395089746 0.3789899945 ) 1509 2 - vert 787 ( 0.9278730154 0.411831975 ) 1511 2 - vert 788 ( 0.9386469722 0.3999459743 ) 1513 2 - vert 789 ( 0.728399992 0.3689399958 ) 1515 2 - vert 790 ( 0.6749150157 0.3546450138 ) 1517 2 - vert 791 ( 0.6946489811 0.3748869896 ) 1513 2 - vert 792 ( 0.9142100215 0.4110490084 ) 1519 1 - vert 793 ( 0.6943200231 0.4136070013 ) 1511 2 - vert 794 ( 0.786157012 0.3374980092 ) 1520 3 - vert 795 ( 0.7252910137 0.3387629986 ) 1523 3 - vert 796 ( 0.7365289927 0.4275730252 ) 1526 3 - vert 797 ( 0.7038620114 0.4392939806 ) 1529 1 - vert 798 ( 0.7230200171 0.4433069825 ) 1530 1 - vert 799 ( 0.9354339838 0.466753006 ) 1531 1 - vert 800 ( 0.9325879812 0.4340230227 ) 1529 1 - vert 801 ( 0.9280790091 0.4787639976 ) 1532 1 - vert 802 ( 0.7003700137 0.4619250298 ) 1531 1 - vert 803 ( 0.7182919979 0.4647610188 ) 1533 1 - vert 804 ( 0.8783879876 0.4474790096 ) 1534 2 - vert 805 ( 0.8563839793 0.4686589837 ) 1536 1 - vert 806 ( 0.8704000115 0.4834579825 ) 1537 1 - vert 807 ( 0.8125690222 0.3461310267 ) 1538 2 - vert 808 ( 0.8071280122 0.4110659957 ) 1540 2 - vert 809 ( 0.77887398 0.4778410196 ) 1542 1 - vert 810 ( 0.8074550033 0.4590309858 ) 1543 1 - vert 811 ( 0.7554550171 0.4745789766 ) 1537 1 - vert 812 ( 0.8201879859 0.4488729835 ) 1544 1 - vert 813 ( 0.8266329765 0.4640110135 ) 1543 1 - vert 814 ( 0.8486109972 0.4842090011 ) 1542 1 - vert 815 ( 0.8229140043 0.4289429784 ) 1545 3 - vert 816 ( 0.8675720096 0.4362750053 ) 1548 2 - vert 817 ( 0.8288050294 0.4070209861 ) 1550 2 - vert 818 ( 0.8066689968 0.4311659932 ) 1552 3 - vert 819 ( 0.9206449986 0.436357975 ) 1555 1 - vert 820 ( 0.885668993 0.3379909992 ) 1556 2 - vert 821 ( 0.8785380125 0.4087280035 ) 1558 2 - vert 822 ( 0.9695450068 0.4046720266 ) 1560 1 - vert 823 ( 0.9502670169 0.4085540175 ) 1561 1 - vert 824 ( 0.9723470211 0.4295179844 ) 1562 1 - vert 825 ( 0.9571650028 0.3766009808 ) 1563 2 - vert 826 ( 0.9873470068 0.4016770124 ) 1565 1 - vert 827 ( 0.9553869963 0.4268180132 ) 1566 1 - vert 828 ( 0.9388960004 0.4156810045 ) 1567 1 - vert 829 ( 0.662891984 0.401835978 ) 1562 1 - vert 830 ( 0.6719589829 0.3949229717 ) 1566 1 - vert 831 ( 0.6582329869 0.3899409771 ) 1568 1 - vert 832 ( 0.9254279733 0.3435360193 ) 1569 4 - vert 833 ( 0.9649310112 0.3407809734 ) 1523 3 - vert 834 ( 0.9501860142 0.340478003 ) 1573 3 - vert 835 ( 0.9743750095 0.3744570017 ) 1517 2 - vert 836 ( 0.6601160169 0.3706610203 ) 1565 1 - vert 837 ( 0.679700017 0.3784369826 ) 1567 1 - vert 838 ( 0.9025089741 0.4375380278 ) 1576 1 - vert 839 ( 0.8881250024 0.4392629862 ) 1530 1 - vert 840 ( 0.8979420066 0.4786270261 ) 1533 1 - vert 841 ( 0.9114570022 0.4798520207 ) 1577 1 - vert 842 ( 0.8941029906 0.4077469707 ) 1578 1 - vert 843 ( 0.8857489824 0.4264069796 ) 1526 3 - vert 844 ( 0.7173299789 0.4751110077 ) 1577 1 - vert 845 ( 0.6988959908 0.4720469713 ) 1532 1 - vert 846 ( 0.9152730107 0.4601749778 ) 1579 1 - vert 847 ( 0.7451140285 0.4509699941 ) 1534 2 - vert 848 ( 0.9856039882 0.4272310138 ) 1568 1 - vert 849 ( 0.7929829955 0.3236700296 ) 1502 2 - vert 850 ( 0.9261609912 0.3216840029 ) 1498 2 - vert 851 ( 0.7564870119 0.3203430176 ) 1494 2 - vert 852 ( 0.964854002 0.324901998 ) 1494 2 - vert 853 ( 0.9684699774 0.2138469815 ) 1580 2 - vert 854 ( 0.8936830163 0.3203369975 ) 1580 2 - vert 855 ( 0.6591830254 0.2872549891 ) 1582 1 - vert 856 ( 0.6338350177 0.3373150229 ) 1583 2 - vert 857 ( 0.1525540054 0.2092919946 ) 1585 1 - vert 858 ( 0.2533960044 0.2069010139 ) 1436 4 - vert 859 ( 0.2199510038 0.2656080127 ) 1427 3 - vert 860 ( 0.2721250057 0.1604350209 ) 1586 3 - vert 861 ( 0.2930789888 0.1885640025 ) 1420 3 - vert 862 ( 0.3293479979 0.2079889774 ) 1423 4 - vert 863 ( 0.2728169858 0.3897690177 ) 1589 3 - vert 864 ( 0.30409199 0.3898140192 ) 1592 3 - vert 865 ( 0.4221470058 0.4826949835 ) 1595 3 - vert 866 ( 0.4368599951 0.4198120236 ) 1598 3 - vert 867 ( 0.3681820035 0.2114120126 ) 1601 4 - vert 868 ( 0.3384110034 0.2618330121 ) 1605 3 - vert 869 ( 0.4078730047 0.124785006 ) 1608 1 - vert 870 ( 0.4499480128 0.1207879782 ) 1609 1 - vert 871 ( 0.5542899966 0.3567519784 ) 1161 3 - vert 872 ( 0.596134007 0.3489469886 ) 1610 2 - vert 873 ( 0.2432550043 0.3346539736 ) 1610 2 - vert 874 ( 0.6163349748 0.0692210197 ) 1612 3 - vert 875 ( 0.6279810071 0.0384929776 ) 1615 4 - vert 876 ( 0.6434649825 0.3630729914 ) 1619 4 - vert 877 ( 0.6343989968 0.0070509911 ) 1619 4 - vert 878 ( 0.3647029996 0.2810729742 ) 1623 5 - vert 879 ( 0.3497880101 0.3132119775 ) 1628 5 - vert 880 ( 0.3280769885 0.3136879802 ) 1612 3 - vert 881 ( 0.285048008 0.348886013 ) 1619 4 - vert 882 ( 0.3108820021 0.340839982 ) 1615 4 - vert 883 ( 0.3387089968 0.3333929777 ) 1633 4 - vert 884 ( 0.3816170096 0.1763650179 ) 1637 3 - vert 885 ( 0.2986379862 0.0374180079 ) 1403 1 - vert 886 ( 0.2425269932 0.0346480012 ) 1404 1 - vert 887 ( 0.1589429975 0.1027749777 ) 1255 1 - vert 888 ( 0.1013299972 0.1503189802 ) 1401 1 - vert 889 ( 0.1658499986 0.0738989711 ) 1401 1 - vert 890 ( 0.3890689909 0.1418799758 ) 1640 2 - vert 891 ( 0.0402080007 0.2810630202 ) 1642 1 - vert 892 ( 0.1605589986 0.5968669653 ) 1643 6 - vert 893 ( 0.2045989931 0.5922920108 ) 1649 6 - vert 894 ( 0.3059329987 0.5957419872 ) 1655 6 - vert 895 ( 0.3437829912 0.5931780338 ) 1661 5 - vert 896 ( 0.3085429966 0.6246919632 ) 1666 4 - vert 897 ( 0.285898 0.6023510098 ) 1670 7 - vert 898 ( 0.2898739874 0.6368750334 ) 1677 4 - vert 899 ( 0.3452390134 0.633047998 ) 1681 4 - vert 900 ( 0.8490179777 0.7567310333 ) 1685 2 - vert 901 ( 0.8994579911 0.7528679967 ) 1687 2 - vert 902 ( 0.8048490286 0.7480499744 ) 1689 2 - vert 903 ( 0.7894909978 0.7785140276 ) 1691 2 - vert 904 ( 0.3875670135 0.5959990025 ) 1693 4 - vert 905 ( 0.4315229952 0.5993089676 ) 1697 4 - vert 906 ( 0.2522189915 0.635357976 ) 1701 4 - vert 907 ( 0.2501319945 0.5896309614 ) 1705 6 - vert 908 ( 0.3149810135 0.653504014 ) 1711 3 - vert 909 ( 0.709495008 0.7045869827 ) 1714 2 - vert 910 ( 0.8441479802 0.7307699919 ) 1716 2 - vert 911 ( 0.2934280038 0.7219760418 ) 1214 3 - vert 912 ( 0.7434340119 0.4853699803 ) 1185 3 - vert 913 ( 0.5445259809 0.533115983 ) 1235 4 - vert 914 ( 0.6254940033 0.5146830082 ) 1229 3 - vert 915 ( 0.547977984 0.6705080271 ) 1241 3 - vert 916 ( 0.9038760066 0.6887279749 ) 1718 3 - vert 917 ( 0.5735809803 0.7201700211 ) 1250 2 - vert 918 ( 0.5199440122 0.7510370016 ) 1248 2 - vert 919 ( 0.600022018 0.7551559806 ) 1721 2 - vert 920 ( 0.8718739748 0.9073569775 ) 1723 1 - vert 921 ( 0.5171480179 0.777485013 ) 1097 2 - vert 922 ( 0.009513 0.866418004 ) 1057 2 - vert 923 ( 0.5090919733 0.9344699979 ) 1053 3 - vert 924 ( 0.8207579851 0.982032001 ) 1068 1 - vert 925 ( 0.7927100062 0.992174983 ) 1022 1 - vert 926 ( 0.4180650115 0.7926020026 ) 1724 1 - vert 927 ( 0.4634110034 0.7972790003 ) 1725 1 - vert 928 ( 0.4704009891 0.7775039673 ) 1726 1 - vert 929 ( 0.0261439998 0.8045679927 ) 1725 1 - vert 930 ( 0.0730660036 0.7969409823 ) 1726 1 - vert 931 ( 0.5299739838 0.950699985 ) 1726 1 - vert 932 ( 0.5728420019 0.9460589886 ) 1727 1 - vert 933 ( 0.5741479993 0.9755619764 ) 1118 1 - vert 934 ( 0.8163290024 0.9539530277 ) 1728 1 - vert 935 ( 0.8704159856 0.9541760087 ) 1724 1 - vert 936 ( 0.0306299999 0.9714379907 ) 1059 3 - vert 937 ( 0.0191229992 0.9466019869 ) 1053 3 - vert 938 ( 0.6119499803 0.9860330224 ) 1113 2 - vert 939 ( 0.8543279767 0.8052660227 ) 1729 1 - vert 940 ( 0.8270549774 0.8075270057 ) 1730 1 - vert 941 ( 0.8478990197 0.8757280111 ) 1731 1 - vert 942 ( 0.5232509971 0.9213680029 ) 1732 1 - vert 943 ( 0.5206599832 0.8753409982 ) 1095 1 - vert 944 ( 0.5302960277 0.8502910137 ) 1094 1 - vert 945 ( 0.5843650103 0.9352009892 ) 1733 1 - vert 946 ( 0.9488000274 0.950699985 ) 1726 1 - vert 947 ( 0.9420779943 0.9213680029 ) 1732 1 - vert 948 ( 0.5593309999 0.8110690117 ) 1099 1 - vert 949 ( 0.2135220021 0.9624720216 ) 1734 2 - vert 950 ( 0.2032800019 0.9954429865 ) 1051 2 - vert 951 ( 0.378320992 0.6392099857 ) 1736 4 - vert 952 ( 0.8749319911 0.5100799799 ) 1740 3 - vert 953 ( 0.3984470069 0.7525379658 ) 1740 3 - vert 954 ( 0.5807430148 0.1112229824 ) 1743 3 - vert 955 ( 0.5710319877 0.0789110065 ) 1605 3 - vert 956 ( 0.5979750156 0.0865190029 ) 1746 3 - vert 957 ( 0.4668169916 0.8244280219 ) 1749 1 - vert 958 ( 0.0193520002 0.8318600059 ) 1749 1 - vert 959 ( 0.7620570064 0.7480289936 ) 1750 2 - vert 960 ( 0.6472489834 0.7385339737 ) 1752 2 - - numtris 1528 - tri 0 2 1 0 - tri 1 3 2 0 - tri 2 2 5 4 - tri 3 5 6 4 - tri 4 2 4 1 - tri 5 7 5 2 - tri 6 10 9 8 - tri 7 8 9 11 - tri 8 8 11 12 - tri 9 9 14 13 - tri 10 9 13 11 - tri 11 11 13 12 - tri 12 12 13 15 - tri 13 8 12 16 - tri 14 19 18 17 - tri 15 21 8 20 - tri 16 20 8 16 - tri 17 23 20 22 - tri 18 24 20 23 - tri 19 25 20 24 - tri 20 25 21 20 - tri 21 23 22 26 - tri 22 27 25 24 - tri 23 27 24 23 - tri 24 29 23 28 - tri 25 28 23 26 - tri 26 31 30 27 - tri 27 32 30 31 - tri 28 31 27 29 - tri 29 29 27 23 - tri 30 33 31 29 - tri 31 33 34 31 - tri 32 35 34 33 - tri 33 18 36 17 - tri 34 17 36 37 - tri 35 40 39 38 - tri 36 38 39 41 - tri 37 42 38 41 - tri 38 44 42 43 - tri 39 43 42 45 - tri 40 45 42 46 - tri 41 49 48 47 - tri 42 49 50 45 - tri 43 50 43 45 - tri 44 53 52 51 - tri 45 54 52 53 - tri 46 56 55 41 - tri 47 56 41 39 - tri 48 59 58 57 - tri 49 59 60 58 - tri 50 63 62 61 - tri 51 48 65 64 - tri 52 67 66 63 - tri 53 70 69 68 - tri 54 70 68 66 - tri 55 65 72 71 - tri 56 73 72 65 - tri 57 37 75 74 - tri 58 10 76 9 - tri 59 76 77 9 - tri 60 9 77 14 - tri 61 76 78 77 - tri 62 78 79 77 - tri 63 21 10 8 - tri 64 21 80 10 - tri 65 82 81 80 - tri 66 80 83 10 - tri 67 81 84 80 - tri 68 30 82 25 - tri 69 30 25 27 - tri 70 30 81 82 - tri 71 85 81 30 - tri 72 32 85 30 - tri 73 87 32 86 - tri 74 86 31 34 - tri 75 86 32 31 - tri 76 87 86 88 - tri 77 90 17 89 - tri 78 90 19 17 - tri 79 89 92 91 - tri 80 92 94 93 - tri 81 92 37 74 - tri 82 92 74 94 - tri 83 17 37 92 - tri 84 89 17 92 - tri 85 96 95 56 - tri 86 95 55 56 - tri 87 98 97 95 - tri 88 97 55 95 - tri 89 98 100 99 - tri 90 97 102 101 - tri 91 99 103 102 - tri 92 104 99 100 - tri 93 105 59 57 - tri 94 105 57 68 - tri 95 105 68 69 - tri 96 67 63 61 - tri 97 106 48 64 - tri 98 67 70 66 - tri 99 102 108 107 - tri 100 109 108 102 - tri 101 25 82 21 - tri 102 82 80 21 - tri 103 112 111 110 - tri 104 112 110 113 - tri 105 116 115 114 - tri 106 117 112 113 - tri 107 118 112 117 - tri 108 120 118 119 - tri 109 118 117 119 - tri 110 121 118 120 - tri 111 123 113 122 - tri 112 113 110 122 - tri 113 117 123 124 - tri 114 117 113 123 - tri 115 120 119 125 - tri 116 120 125 126 - tri 117 127 114 115 - tri 118 125 124 128 - tri 119 125 128 129 - tri 120 129 131 130 - tri 121 129 128 131 - tri 122 130 131 132 - tri 123 131 133 132 - tri 124 136 135 134 - tri 125 135 138 137 - tri 126 135 137 134 - tri 127 141 140 139 - tri 128 143 3 142 - tri 129 146 145 144 - tri 130 149 148 147 - tri 131 148 146 147 - tri 132 148 150 146 - tri 133 143 151 3 - tri 134 0 1 140 - tri 135 152 150 148 - tri 136 154 152 153 - tri 137 142 140 141 - tri 138 157 156 155 - tri 139 157 158 156 - tri 140 156 158 159 - tri 141 162 161 160 - tri 142 164 155 163 - tri 143 167 166 165 - tri 144 168 135 136 - tri 145 169 168 136 - tri 146 172 171 170 - tri 147 170 171 173 - tri 148 163 171 172 - tri 149 174 172 170 - tri 150 155 175 163 - tri 151 165 151 143 - tri 152 167 165 143 - tri 153 149 147 158 - tri 154 3 0 142 - tri 155 142 0 140 - tri 156 178 177 176 - tri 157 178 176 179 - tri 158 182 181 180 - tri 159 127 184 183 - tri 160 187 186 185 - tri 161 189 185 188 - tri 162 127 183 190 - tri 163 193 192 191 - tri 164 191 192 194 - tri 165 197 196 195 - tri 166 197 198 196 - tri 167 197 199 198 - tri 168 202 201 200 - tri 169 202 203 201 - tri 170 180 181 194 - tri 171 188 205 204 - tri 172 188 206 205 - tri 173 122 127 190 - tri 174 187 185 189 - tri 175 204 205 207 - tri 176 205 180 207 - tri 177 205 208 180 - tri 178 206 208 205 - tri 179 182 180 208 - tri 180 183 182 208 - tri 181 128 209 131 - tri 182 210 126 125 - tri 183 212 210 211 - tri 184 212 211 213 - tri 185 215 214 212 - tri 186 215 212 213 - tri 187 215 213 216 - tri 188 217 215 216 - tri 189 219 218 217 - tri 190 222 221 220 - tri 191 224 223 221 - tri 192 224 221 1 - tri 193 1 221 222 - tri 194 225 219 217 - tri 195 225 227 226 - tri 196 225 217 227 - tri 197 216 213 228 - tri 198 228 230 229 - tri 199 228 229 231 - tri 200 226 227 232 - tri 201 233 226 232 - tri 202 220 215 218 - tri 203 221 234 220 - tri 204 218 215 217 - tri 205 227 235 232 - tri 206 231 229 236 - tri 207 239 238 237 - tri 208 239 236 238 - tri 209 122 110 127 - tri 210 122 186 187 - tri 211 122 190 186 - tri 212 124 123 128 - tri 213 119 117 124 - tri 214 119 124 125 - tri 215 209 122 187 - tri 216 128 123 209 - tri 217 123 122 209 - tri 218 209 133 131 - tri 219 240 121 120 - tri 220 240 120 234 - tri 221 221 240 234 - tri 222 223 240 221 - tri 223 220 214 215 - tri 224 220 234 214 - tri 225 234 120 126 - tri 226 234 126 214 - tri 227 214 126 210 - tri 228 214 210 212 - tri 229 210 129 211 - tri 230 210 125 129 - tri 231 243 242 241 - tri 232 243 241 244 - tri 233 245 243 244 - tri 234 248 247 246 - tri 235 250 246 249 - tri 236 249 246 247 - tri 237 242 250 249 - tri 238 242 249 241 - tri 239 116 251 115 - tri 240 115 251 252 - tri 241 255 254 253 - tri 242 253 254 256 - tri 243 254 257 256 - tri 244 260 259 258 - tri 245 261 257 254 - tri 246 259 256 257 - tri 247 256 263 262 - tri 248 265 264 260 - tri 249 266 265 260 - tri 250 264 267 260 - tri 251 259 263 256 - tri 252 267 263 259 - tri 253 260 267 259 - tri 254 268 255 253 - tri 255 269 268 253 - tri 256 269 253 270 - tri 257 272 271 268 - tri 258 275 274 273 - tri 259 278 277 276 - tri 260 281 280 279 - tri 261 279 280 282 - tri 262 279 282 283 - tri 263 282 276 284 - tri 264 283 282 284 - tri 265 283 284 285 - tri 266 276 286 284 - tri 267 284 286 272 - tri 268 286 271 272 - tri 269 286 287 271 - tri 270 288 286 276 - tri 271 277 288 276 - tri 272 289 287 286 - tri 273 288 289 286 - tri 274 288 290 289 - tri 275 277 290 288 - tri 276 277 291 290 - tri 277 291 292 290 - tri 278 294 293 278 - tri 279 278 293 277 - tri 280 293 291 277 - tri 281 297 296 295 - tri 282 299 285 298 - tri 283 285 284 296 - tri 284 284 272 296 - tri 285 300 279 283 - tri 286 297 285 296 - tri 287 301 297 295 - tri 288 301 295 302 - tri 289 305 304 303 - tri 290 304 307 306 - tri 291 303 304 306 - tri 292 308 281 279 - tri 293 309 281 308 - tri 294 311 310 304 - tri 295 300 299 310 - tri 296 311 304 305 - tri 297 304 310 307 - tri 298 278 276 280 - tri 299 281 278 280 - tri 300 280 276 282 - tri 301 295 296 268 - tri 302 302 295 312 - tri 303 296 272 268 - tri 304 315 314 313 - tri 305 316 300 310 - tri 306 311 316 310 - tri 307 319 318 317 - tri 308 322 321 320 - tri 309 317 318 323 - tri 310 322 324 321 - tri 311 321 326 325 - tri 312 328 327 324 - tri 313 328 329 327 - tri 314 332 331 330 - tri 315 333 329 328 - tri 316 334 329 333 - tri 317 337 336 335 - tri 318 339 338 326 - tri 319 330 317 323 - tri 320 342 341 340 - tri 321 344 335 343 - tri 322 345 335 344 - tri 323 335 346 343 - tri 324 335 347 346 - tri 325 339 346 348 - tri 326 349 346 339 - tri 327 343 346 349 - tri 328 330 323 350 - tri 329 332 330 350 - tri 330 337 335 345 - tri 331 339 348 338 - tri 332 348 314 338 - tri 333 323 318 351 - tri 334 352 351 314 - tri 335 321 325 320 - tri 336 355 354 353 - tri 337 357 356 354 - tri 338 355 353 358 - tri 339 358 353 359 - tri 340 362 361 360 - tri 341 356 363 318 - tri 342 318 363 351 - tri 343 366 365 364 - tri 344 357 366 356 - tri 345 368 320 367 - tri 346 353 318 319 - tri 347 371 370 369 - tri 348 372 370 371 - tri 349 348 352 314 - tri 350 359 353 319 - tri 351 368 322 320 - tri 352 347 352 348 - tri 353 346 347 348 - tri 354 374 373 352 - tri 355 373 351 352 - tri 356 323 351 373 - tri 357 366 363 356 - tri 358 366 364 363 - tri 359 339 326 321 - tri 360 339 321 327 - tri 361 327 321 324 - tri 362 374 370 373 - tri 363 369 370 374 - tri 364 376 375 333 - tri 365 375 334 333 - tri 366 377 350 370 - tri 367 372 377 370 - tri 368 332 377 372 - tri 369 332 350 377 - tri 370 336 352 347 - tri 371 336 374 352 - tri 372 335 336 347 - tri 373 342 340 349 - tri 374 340 343 349 - tri 375 349 327 378 - tri 376 349 339 327 - tri 377 342 349 378 - tri 378 350 373 370 - tri 379 350 323 373 - tri 380 354 318 353 - tri 381 354 356 318 - tri 382 355 357 354 - tri 383 379 357 355 - tri 384 362 368 367 - tri 385 362 360 368 - tri 386 290 292 289 - tri 387 338 314 315 - tri 388 326 338 380 - tri 389 338 315 380 - tri 390 314 351 313 - tri 391 363 381 351 - tri 392 325 326 382 - tri 393 326 380 382 - tri 394 364 381 363 - tri 395 364 383 381 - tri 396 365 383 364 - tri 397 309 294 281 - tri 398 294 278 281 - tri 399 310 298 307 - tri 400 310 299 298 - tri 401 300 283 299 - tri 402 299 283 285 - tri 403 275 302 274 - tri 404 302 312 274 - tri 405 306 301 302 - tri 406 306 302 275 - tri 407 298 285 297 - tri 408 306 307 301 - tri 409 300 384 279 - tri 410 351 385 313 - tri 411 381 385 351 - tri 412 308 279 384 - tri 413 307 298 297 - tri 414 307 297 301 - tri 415 261 259 257 - tri 416 258 259 261 - tri 417 255 261 254 - tri 418 255 258 261 - tri 419 287 258 271 - tri 420 271 258 255 - tri 421 271 255 268 - tri 422 287 260 258 - tri 423 289 386 287 - tri 424 295 269 312 - tri 425 295 268 269 - tri 426 289 387 386 - tri 427 387 266 386 - tri 428 386 266 287 - tri 429 287 266 260 - tri 430 312 269 270 - tri 431 206 388 208 - tri 432 186 388 206 - tri 433 190 388 186 - tri 434 190 183 388 - tri 435 183 208 388 - tri 436 185 206 188 - tri 437 185 186 206 - tri 438 390 188 389 - tri 439 188 204 389 - tri 440 180 194 192 - tri 441 207 180 192 - tri 442 204 207 391 - tri 443 391 207 192 - tri 444 389 204 392 - tri 445 204 391 392 - tri 446 127 115 184 - tri 447 184 182 183 - tri 448 115 252 184 - tri 449 189 188 390 - tri 450 133 187 189 - tri 451 209 187 133 - tri 452 133 189 390 - tri 453 196 194 181 - tri 454 195 196 181 - tri 455 391 192 193 - tri 456 393 392 193 - tri 457 392 391 193 - tri 458 211 129 130 - tri 459 211 130 394 - tri 460 213 211 394 - tri 461 213 394 395 - tri 462 228 395 230 - tri 463 213 395 228 - tri 464 235 228 231 - tri 465 235 216 228 - tri 466 227 216 235 - tri 467 227 217 216 - tri 468 232 397 396 - tri 469 232 235 397 - tri 470 235 231 397 - tri 471 233 232 398 - tri 472 232 396 398 - tri 473 396 397 399 - tri 474 397 231 399 - tri 475 231 236 399 - tri 476 399 236 239 - tri 477 399 239 400 - tri 478 396 399 400 - tri 479 402 393 401 - tri 480 238 401 203 - tri 481 404 403 196 - tri 482 198 404 196 - tri 483 133 390 132 - tri 484 405 264 265 - tri 485 406 405 265 - tri 486 130 132 407 - tri 487 406 265 266 - tri 488 406 266 387 - tri 489 312 270 408 - tri 490 274 312 408 - tri 491 274 408 409 - tri 492 292 410 289 - tri 493 410 387 289 - tri 494 273 274 409 - tri 495 273 409 411 - tri 496 229 412 236 - tri 497 236 412 238 - tri 498 412 401 238 - tri 499 201 403 404 - tri 500 201 404 200 - tri 501 200 404 413 - tri 502 198 413 404 - tri 503 199 413 198 - tri 504 412 402 401 - tri 505 415 402 414 - tri 506 414 402 412 - tri 507 229 414 412 - tri 508 395 394 416 - tri 509 395 416 417 - tri 510 395 417 230 - tri 511 410 406 387 - tri 512 394 130 407 - tri 513 394 407 416 - tri 514 230 417 418 - tri 515 417 415 418 - tri 516 418 415 414 - tri 517 393 193 419 - tri 518 203 401 419 - tri 519 401 393 419 - tri 520 238 202 237 - tri 521 238 203 202 - tri 522 230 418 229 - tri 523 229 418 414 - tri 524 197 195 420 - tri 525 195 421 420 - tri 526 197 420 422 - tri 527 197 422 199 - tri 528 423 195 182 - tri 529 182 195 181 - tri 530 184 252 424 - tri 531 423 425 421 - tri 532 423 421 195 - tri 533 193 191 426 - tri 534 426 191 403 - tri 535 201 426 403 - tri 536 203 426 201 - tri 537 203 419 426 - tri 538 419 193 426 - tri 539 196 191 194 - tri 540 403 191 196 - tri 541 427 116 114 - tri 542 427 114 127 - tri 543 110 427 127 - tri 544 110 111 427 - tri 545 111 428 427 - tri 546 428 116 427 - tri 547 6 224 4 - tri 548 4 224 1 - tri 549 140 430 429 - tri 550 433 432 431 - tri 551 433 434 432 - tri 552 435 434 433 - tri 553 436 433 431 - tri 554 436 435 433 - tri 555 74 438 437 - tri 556 74 75 438 - tri 557 440 439 438 - tri 558 75 440 438 - tri 559 94 437 178 - tri 560 94 74 437 - tri 561 44 38 42 - tri 562 44 40 38 - tri 563 98 95 96 - tri 564 134 137 441 - tri 565 137 443 442 - tri 566 140 1 430 - tri 567 430 1 222 - tri 568 140 429 444 - tri 569 444 429 445 - tri 570 140 444 139 - tri 571 139 435 446 - tri 572 139 444 435 - tri 573 446 435 436 - tri 574 429 219 445 - tri 575 429 222 219 - tri 576 430 222 429 - tri 577 219 220 218 - tri 578 222 220 219 - tri 579 445 219 434 - tri 580 225 431 432 - tri 581 442 226 233 - tri 582 441 442 233 - tri 583 137 442 441 - tri 584 442 443 226 - tri 585 436 431 443 - tri 586 138 446 436 - tri 587 225 226 431 - tri 588 443 431 226 - tri 589 13 447 15 - tri 590 14 447 13 - tri 591 77 447 14 - tri 592 77 79 447 - tri 593 20 16 22 - tri 594 22 16 440 - tri 595 10 78 76 - tri 596 10 83 78 - tri 597 15 158 157 - tri 598 15 447 149 - tri 599 15 149 158 - tri 600 439 155 448 - tri 601 439 157 155 - tri 602 154 153 79 - tri 603 449 141 139 - tri 604 449 139 161 - tri 605 158 147 450 - tri 606 158 450 159 - tri 607 155 156 175 - tri 608 156 159 175 - tri 609 150 452 451 - tri 610 452 453 451 - tri 611 147 144 450 - tri 612 147 146 144 - tri 613 162 449 161 - tri 614 454 150 152 - tri 615 454 452 150 - tri 616 164 163 455 - tri 617 455 163 172 - tri 618 455 172 174 - tri 619 176 455 174 - tri 620 435 445 434 - tri 621 444 445 435 - tri 622 176 177 455 - tri 623 177 164 455 - tri 624 179 176 174 - tri 625 456 152 154 - tri 626 456 454 152 - tri 627 178 437 177 - tri 628 437 438 177 - tri 629 438 448 177 - tri 630 177 448 164 - tri 631 448 155 164 - tri 632 458 457 456 - tri 633 458 456 154 - tri 634 153 152 148 - tri 635 153 148 149 - tri 636 79 149 447 - tri 637 79 153 149 - tri 638 438 439 448 - tri 639 22 440 75 - tri 640 459 28 18 - tri 641 459 18 19 - tri 642 460 458 83 - tri 643 460 457 458 - tri 644 42 51 46 - tri 645 42 53 51 - tri 646 97 52 54 - tri 647 97 101 52 - tri 648 42 41 53 - tri 649 97 54 55 - tri 650 88 86 35 - tri 651 35 86 34 - tri 652 150 451 146 - tri 653 146 451 145 - tri 654 55 54 53 - tri 655 55 53 41 - tri 656 103 461 109 - tri 657 103 109 102 - tri 658 45 73 48 - tri 659 45 46 73 - tri 660 49 45 48 - tri 661 48 73 65 - tri 662 462 47 106 - tri 663 47 48 106 - tri 664 464 33 463 - tri 665 464 35 33 - tri 666 466 71 465 - tri 667 466 465 467 - tri 668 108 469 468 - tri 669 107 108 468 - tri 670 472 471 470 - tri 671 72 465 71 - tri 672 463 474 473 - tri 673 473 459 19 - tri 674 475 99 104 - tri 675 475 476 103 - tri 676 475 103 99 - tri 677 463 33 474 - tri 678 33 29 474 - tri 679 474 29 28 - tri 680 73 46 72 - tri 681 473 474 28 - tri 682 473 28 459 - tri 683 87 472 470 - tri 684 98 99 97 - tri 685 99 102 97 - tri 686 477 87 88 - tri 687 477 472 87 - tri 688 102 107 101 - tri 689 478 75 37 - tri 690 478 37 36 - tri 691 479 22 75 - tri 692 479 75 478 - tri 693 479 26 22 - tri 694 480 36 18 - tri 695 480 18 28 - tri 696 480 28 26 - tri 697 26 479 478 - tri 698 478 36 480 - tri 699 480 26 478 - tri 700 85 482 481 - tri 701 85 481 81 - tri 702 481 483 81 - tri 703 81 483 84 - tri 704 471 482 85 - tri 705 484 32 87 - tri 706 484 87 470 - tri 707 484 470 471 - tri 708 484 471 85 - tri 709 484 85 32 - tri 710 486 485 473 - tri 711 473 19 486 - tri 712 90 486 19 - tri 713 83 487 460 - tri 714 487 83 80 - tri 715 487 80 84 - tri 716 93 91 92 - tri 717 219 225 432 - tri 718 432 434 219 - tri 719 488 56 39 - tri 720 488 39 40 - tri 721 488 40 489 - tri 722 488 489 96 - tri 723 488 96 56 - tri 724 3 151 7 - tri 725 7 2 3 - tri 726 490 137 138 - tri 727 490 138 436 - tri 728 490 436 443 - tri 729 490 443 137 - tri 730 160 138 135 - tri 731 139 446 161 - tri 732 491 163 175 - tri 733 492 162 160 - tri 734 492 160 135 - tri 735 492 135 168 - tri 736 491 171 163 - tri 737 160 161 138 - tri 738 161 446 138 - tri 739 493 270 253 - tri 740 493 253 256 - tri 741 493 256 262 - tri 742 493 262 494 - tri 743 495 408 270 - tri 744 495 270 493 - tri 745 495 493 494 - tri 746 495 494 408 - tri 747 496 71 466 - tri 748 497 469 108 - tri 749 497 108 109 - tri 750 497 109 461 - tri 751 496 64 65 - tri 752 496 65 71 - tri 753 498 15 157 - tri 754 498 157 439 - tri 755 498 439 440 - tri 756 498 440 16 - tri 757 498 16 12 - tri 758 498 12 15 - tri 759 499 78 83 - tri 760 499 83 458 - tri 761 499 458 154 - tri 762 499 154 79 - tri 763 499 79 78 - tri 764 502 501 500 - tri 765 503 501 502 - tri 766 502 504 5 - tri 767 5 504 6 - tri 768 502 500 504 - tri 769 7 502 5 - tri 770 507 506 505 - tri 771 506 508 505 - tri 772 506 509 508 - tri 773 505 511 510 - tri 774 505 508 511 - tri 775 508 509 511 - tri 776 509 512 511 - tri 777 506 513 509 - tri 778 516 515 514 - tri 779 518 517 506 - tri 780 517 513 506 - tri 781 520 519 517 - tri 782 521 520 517 - tri 783 522 521 517 - tri 784 522 517 518 - tri 785 520 523 519 - tri 786 524 521 522 - tri 787 524 520 521 - tri 788 526 525 520 - tri 789 525 523 520 - tri 790 528 524 527 - tri 791 529 528 527 - tri 792 528 526 524 - tri 793 526 520 524 - tri 794 530 526 528 - tri 795 530 528 531 - tri 796 532 530 531 - tri 797 514 515 533 - tri 798 515 534 533 - tri 799 537 536 535 - tri 800 536 538 535 - tri 801 539 538 536 - tri 802 541 540 539 - tri 803 540 542 539 - tri 804 542 543 539 - tri 805 546 545 544 - tri 806 546 542 547 - tri 807 547 542 540 - tri 808 550 549 548 - tri 809 551 550 548 - tri 810 553 538 552 - tri 811 553 535 538 - tri 812 556 555 554 - tri 813 556 554 557 - tri 814 560 559 558 - tri 815 544 562 561 - tri 816 564 560 563 - tri 817 567 566 565 - tri 818 567 563 566 - tri 819 561 569 568 - tri 820 570 561 568 - tri 821 534 572 571 - tri 822 507 505 573 - tri 823 573 505 574 - tri 824 505 510 574 - tri 825 573 574 575 - tri 826 575 574 576 - tri 827 518 506 507 - tri 828 518 507 577 - tri 829 579 577 578 - tri 830 577 507 580 - tri 831 578 577 581 - tri 832 527 522 579 - tri 833 527 524 522 - tri 834 527 579 578 - tri 835 582 527 578 - tri 836 529 527 582 - tri 837 584 583 529 - tri 838 583 531 528 - tri 839 583 528 529 - tri 840 584 585 583 - tri 841 587 586 515 - tri 842 587 515 516 - tri 843 586 589 588 - tri 844 588 591 590 - tri 845 588 572 534 - tri 846 588 590 572 - tri 847 515 588 534 - tri 848 586 588 515 - tri 849 593 553 592 - tri 850 592 553 552 - tri 851 595 592 594 - tri 852 594 592 552 - tri 853 595 597 596 - tri 854 594 599 598 - tri 855 597 598 600 - tri 856 601 596 597 - tri 857 602 555 556 - tri 858 602 566 555 - tri 859 602 565 566 - tri 860 564 559 560 - tri 861 603 562 544 - tri 862 564 563 567 - tri 863 598 605 604 - tri 864 606 598 604 - tri 865 522 518 579 - tri 866 579 518 577 - tri 867 112 607 111 - tri 868 112 608 607 - tri 869 116 610 609 - tri 870 611 608 112 - tri 871 118 611 112 - tri 872 613 612 118 - tri 873 118 612 611 - tri 874 121 613 118 - tri 875 615 614 608 - tri 876 608 614 607 - tri 877 611 616 615 - tri 878 611 615 608 - tri 879 613 617 612 - tri 880 613 618 617 - tri 881 619 609 610 - tri 882 617 620 616 - tri 883 617 621 620 - tri 884 621 623 622 - tri 885 621 622 620 - tri 886 623 624 622 - tri 887 622 624 625 - tri 888 136 134 626 - tri 889 626 628 627 - tri 890 626 134 628 - tri 891 631 630 629 - tri 892 633 632 503 - tri 893 636 635 634 - tri 894 639 638 637 - tri 895 637 638 636 - tri 896 637 636 640 - tri 897 633 503 151 - tri 898 501 629 500 - tri 899 641 637 640 - tri 900 643 642 641 - tri 901 632 631 629 - tri 902 646 645 644 - tri 903 646 644 647 - tri 904 644 648 647 - tri 905 651 650 649 - tri 906 653 652 645 - tri 907 654 165 166 - tri 908 655 136 626 - tri 909 169 136 655 - tri 910 658 657 656 - tri 911 657 173 656 - tri 912 652 658 656 - tri 913 659 657 658 - tri 914 645 652 660 - tri 915 165 633 151 - tri 916 654 633 165 - tri 917 639 647 638 - tri 918 503 632 501 - tri 919 632 629 501 - tri 920 663 662 661 - tri 921 663 664 662 - tri 922 667 666 665 - tri 923 619 669 668 - tri 924 672 671 670 - tri 925 674 673 671 - tri 926 619 675 669 - tri 927 678 677 676 - tri 928 677 679 676 - tri 929 682 681 680 - tri 930 682 680 683 - tri 931 682 683 199 - tri 932 202 200 684 - tri 933 202 684 685 - tri 934 666 679 665 - tri 935 673 687 686 - tri 936 673 686 688 - tri 937 614 675 619 - tri 938 672 674 671 - tri 939 687 689 686 - tri 940 686 689 666 - tri 941 686 666 690 - tri 942 688 686 690 - tri 943 667 690 666 - tri 944 669 690 667 - tri 945 620 622 691 - tri 946 692 617 618 - tri 947 694 693 692 - tri 948 694 695 693 - tri 949 697 694 696 - tri 950 697 695 694 - tri 951 697 698 695 - tri 952 699 698 697 - tri 953 701 699 700 - tri 954 704 703 702 - tri 955 224 702 223 - tri 956 224 500 702 - tri 957 500 704 702 - tri 958 705 699 701 - tri 959 705 707 706 - tri 960 705 706 699 - tri 961 698 708 695 - tri 962 708 710 709 - tri 963 708 711 710 - tri 964 707 712 706 - tri 965 233 712 707 - tri 966 703 700 697 - tri 967 702 703 713 - tri 968 700 699 697 - tri 969 706 712 714 - tri 970 711 715 710 - tri 971 239 237 716 - tri 972 239 716 715 - tri 973 614 619 607 - tri 974 614 672 670 - tri 975 614 670 675 - tri 976 616 620 615 - tri 977 612 616 611 - tri 978 612 617 616 - tri 979 691 672 614 - tri 980 620 691 615 - tri 981 615 691 614 - tri 982 691 622 625 - tri 983 240 613 121 - tri 984 240 713 613 - tri 985 702 713 240 - tri 986 223 702 240 - tri 987 703 697 696 - tri 988 703 696 713 - tri 989 713 618 613 - tri 990 713 696 618 - tri 991 696 692 618 - tri 992 696 694 692 - tri 993 692 693 621 - tri 994 692 621 617 - tri 995 243 717 242 - tri 996 243 718 717 - tri 997 245 718 243 - tri 998 248 246 719 - tri 999 250 720 246 - tri 1000 720 719 246 - tri 1001 242 720 250 - tri 1002 242 717 720 - tri 1003 116 609 251 - tri 1004 609 721 251 - tri 1005 724 723 722 - tri 1006 723 725 722 - tri 1007 722 725 726 - tri 1008 729 728 727 - tri 1009 730 722 726 - tri 1010 727 726 725 - tri 1011 725 732 731 - tri 1012 734 729 733 - tri 1013 735 729 734 - tri 1014 733 729 736 - tri 1015 727 725 731 - tri 1016 736 727 731 - tri 1017 729 727 736 - tri 1018 737 723 724 - tri 1019 738 723 737 - tri 1020 738 739 723 - tri 1021 741 737 740 - tri 1022 744 743 742 - tri 1023 747 746 745 - tri 1024 750 749 748 - tri 1025 749 751 748 - tri 1026 749 752 751 - tri 1027 751 753 746 - tri 1028 752 753 751 - tri 1029 752 754 753 - tri 1030 746 753 755 - tri 1031 753 741 755 - tri 1032 755 741 740 - tri 1033 755 740 756 - tri 1034 757 746 755 - tri 1035 745 746 757 - tri 1036 758 755 756 - tri 1037 757 755 758 - tri 1038 757 758 759 - tri 1039 745 757 759 - tri 1040 745 759 760 - tri 1041 760 759 761 - tri 1042 763 747 762 - tri 1043 747 745 762 - tri 1044 762 745 760 - tri 1045 766 765 764 - tri 1046 768 767 754 - tri 1047 754 764 753 - tri 1048 753 764 741 - tri 1049 769 752 749 - tri 1050 766 764 754 - tri 1051 770 765 766 - tri 1052 770 771 765 - tri 1053 774 773 772 - tri 1054 772 776 775 - tri 1055 773 776 772 - tri 1056 777 749 750 - tri 1057 778 777 750 - tri 1058 780 772 779 - tri 1059 769 779 768 - tri 1060 780 774 772 - tri 1061 772 775 779 - tri 1062 747 748 746 - tri 1063 750 748 747 - tri 1064 748 751 746 - tri 1065 765 737 764 - tri 1066 771 781 765 - tri 1067 764 737 741 - tri 1068 784 783 782 - tri 1069 785 779 769 - tri 1070 780 779 785 - tri 1071 788 787 786 - tri 1072 791 790 789 - tri 1073 787 792 786 - tri 1074 791 789 793 - tri 1075 789 795 794 - tri 1076 797 793 796 - tri 1077 797 796 798 - tri 1078 801 800 799 - tri 1079 802 797 798 - tri 1080 803 802 798 - tri 1081 806 805 804 - tri 1082 808 794 807 - tri 1083 800 792 787 - tri 1084 811 810 809 - tri 1085 813 812 805 - tri 1086 814 813 805 - tri 1087 805 812 815 - tri 1088 805 815 816 - tri 1089 808 817 815 - tri 1090 818 808 815 - tri 1091 812 818 815 - tri 1092 800 819 792 - tri 1093 801 819 800 - tri 1094 806 814 805 - tri 1095 808 807 817 - tri 1096 817 807 782 - tri 1097 792 820 786 - tri 1098 821 782 820 - tri 1099 789 790 795 - tri 1100 824 823 822 - tri 1101 826 822 825 - tri 1102 824 827 823 - tri 1103 827 828 823 - tri 1104 831 830 829 - tri 1105 825 786 832 - tri 1106 786 820 832 - tri 1107 835 834 833 - tri 1108 826 825 835 - tri 1109 837 836 790 - tri 1110 823 788 786 - tri 1111 840 839 838 - tri 1112 841 840 838 - tri 1113 817 782 821 - tri 1114 828 788 823 - tri 1115 837 790 791 - tri 1116 816 817 821 - tri 1117 815 817 816 - tri 1118 843 821 842 - tri 1119 842 821 820 - tri 1120 792 842 820 - tri 1121 835 825 832 - tri 1122 835 832 834 - tri 1123 808 789 794 - tri 1124 808 796 789 - tri 1125 796 793 789 - tri 1126 843 842 838 - tri 1127 839 843 838 - tri 1128 845 802 844 - tri 1129 844 802 803 - tri 1130 846 838 819 - tri 1131 841 838 846 - tri 1132 801 841 846 - tri 1133 801 846 819 - tri 1134 804 816 821 - tri 1135 804 821 843 - tri 1136 805 816 804 - tri 1137 811 818 810 - tri 1138 810 818 812 - tri 1139 818 847 796 - tri 1140 818 796 808 - tri 1141 811 847 818 - tri 1142 819 838 842 - tri 1143 819 842 792 - tri 1144 822 823 786 - tri 1145 822 786 825 - tri 1146 824 822 826 - tri 1147 848 824 826 - tri 1148 831 836 837 - tri 1149 831 837 830 - tri 1150 759 758 761 - tri 1151 807 784 782 - tri 1152 794 849 807 - tri 1153 807 849 784 - tri 1154 782 783 820 - tri 1155 832 820 850 - tri 1156 795 851 794 - tri 1157 794 851 849 - tri 1158 834 832 850 - tri 1159 834 850 852 - tri 1160 833 834 852 - tri 1161 778 750 763 - tri 1162 763 750 747 - tri 1163 779 775 767 - tri 1164 779 767 768 - tri 1165 769 768 752 - tri 1166 768 754 752 - tri 1167 744 742 771 - tri 1168 771 742 781 - tri 1169 776 771 770 - tri 1170 776 744 771 - tri 1171 767 766 754 - tri 1172 776 770 775 - tri 1173 769 749 853 - tri 1174 820 783 854 - tri 1175 850 820 854 - tri 1176 777 853 749 - tri 1177 775 766 767 - tri 1178 775 770 766 - tri 1179 730 726 727 - tri 1180 728 730 727 - tri 1181 724 722 730 - tri 1182 724 730 728 - tri 1183 756 740 728 - tri 1184 740 724 728 - tri 1185 740 737 724 - tri 1186 756 728 729 - tri 1187 758 756 855 - tri 1188 765 781 738 - tri 1189 765 738 737 - tri 1190 758 855 856 - tri 1191 856 855 735 - tri 1192 855 756 735 - tri 1193 756 729 735 - tri 1194 781 739 738 - tri 1195 688 690 857 - tri 1196 670 688 857 - tri 1197 675 670 857 - tri 1198 675 857 669 - tri 1199 669 857 690 - tri 1200 671 673 688 - tri 1201 671 688 670 - tri 1202 859 858 673 - tri 1203 673 858 687 - tri 1204 666 676 679 - tri 1205 689 676 666 - tri 1206 687 860 689 - tri 1207 860 676 689 - tri 1208 858 861 687 - tri 1209 687 861 860 - tri 1210 619 668 609 - tri 1211 668 669 667 - tri 1212 609 668 721 - tri 1213 674 859 673 - tri 1214 625 674 672 - tri 1215 691 625 672 - tri 1216 625 859 674 - tri 1217 680 665 679 - tri 1218 681 665 680 - tri 1219 860 678 676 - tri 1220 862 678 861 - tri 1221 861 678 860 - tri 1222 693 623 621 - tri 1223 693 863 623 - tri 1224 695 863 693 - tri 1225 695 864 863 - tri 1226 708 709 864 - tri 1227 695 708 864 - tri 1228 714 711 708 - tri 1229 714 708 698 - tri 1230 706 714 698 - tri 1231 706 698 699 - tri 1232 712 396 865 - tri 1233 712 865 714 - tri 1234 714 865 711 - tri 1235 233 398 712 - tri 1236 712 398 396 - tri 1237 396 866 865 - tri 1238 865 866 711 - tri 1239 711 866 715 - tri 1240 866 239 715 - tri 1241 866 400 239 - tri 1242 396 400 866 - tri 1243 868 867 862 - tri 1244 716 685 867 - tri 1245 870 680 869 - tri 1246 683 680 870 - tri 1247 625 624 859 - tri 1248 871 734 733 - tri 1249 872 734 871 - tri 1250 623 873 624 - tri 1251 872 735 734 - tri 1252 872 856 735 - tri 1253 781 874 739 - tri 1254 742 874 781 - tri 1255 742 875 874 - tri 1256 761 758 876 - tri 1257 876 758 856 - tri 1258 743 875 742 - tri 1259 743 877 875 - tri 1260 710 715 878 - tri 1261 715 716 878 - tri 1262 878 716 867 - tri 1263 684 870 869 - tri 1264 684 200 870 - tri 1265 200 413 870 - tri 1266 683 870 413 - tri 1267 199 683 413 - tri 1268 878 867 868 - tri 1269 880 879 868 - tri 1270 879 878 868 - tri 1271 710 878 879 - tri 1272 864 881 863 - tri 1273 864 882 881 - tri 1274 864 709 882 - tri 1275 876 856 872 - tri 1276 863 873 623 - tri 1277 863 881 873 - tri 1278 709 883 882 - tri 1279 882 883 880 - tri 1280 883 879 880 - tri 1281 862 884 678 - tri 1282 685 884 867 - tri 1283 867 884 862 - tri 1284 716 237 202 - tri 1285 716 202 685 - tri 1286 709 710 883 - tri 1287 710 879 883 - tri 1288 682 885 681 - tri 1289 681 885 886 - tri 1290 682 422 885 - tri 1291 682 199 422 - tri 1292 887 667 681 - tri 1293 667 665 681 - tri 1294 668 888 721 - tri 1295 887 886 889 - tri 1296 887 681 886 - tri 1297 678 890 677 - tri 1298 890 869 677 - tri 1299 684 869 890 - tri 1300 685 684 890 - tri 1301 685 890 884 - tri 1302 884 890 678 - tri 1303 680 679 677 - tri 1304 869 680 677 - tri 1305 891 610 116 - tri 1306 891 619 610 - tri 1307 607 619 891 - tri 1308 607 891 111 - tri 1309 111 891 428 - tri 1310 428 891 116 - tri 1311 6 504 224 - tri 1312 504 500 224 - tri 1313 629 893 892 - tri 1314 896 895 894 - tri 1315 896 894 897 - tri 1316 898 896 897 - tri 1317 899 895 896 - tri 1318 899 896 898 - tri 1319 572 901 900 - tri 1320 572 900 571 - tri 1321 903 900 902 - tri 1322 571 900 903 - tri 1323 590 663 901 - tri 1324 590 901 572 - tri 1325 541 539 536 - tri 1326 541 536 537 - tri 1327 595 593 592 - tri 1328 134 441 628 - tri 1329 628 905 904 - tri 1330 629 892 500 - tri 1331 892 704 500 - tri 1332 629 906 893 - tri 1333 906 907 893 - tri 1334 629 630 906 - tri 1335 630 908 898 - tri 1336 630 898 906 - tri 1337 908 899 898 - tri 1338 893 907 701 - tri 1339 893 701 704 - tri 1340 892 893 704 - tri 1341 701 700 703 - tri 1342 704 701 703 - tri 1343 907 897 701 - tri 1344 705 894 895 - tri 1345 905 233 707 - tri 1346 441 233 905 - tri 1347 628 441 905 - tri 1348 905 707 904 - tri 1349 899 904 895 - tri 1350 627 899 908 - tri 1351 705 895 707 - tri 1352 904 707 895 - tri 1353 511 512 909 - tri 1354 510 511 909 - tri 1355 574 510 909 - tri 1356 574 909 576 - tri 1357 517 519 513 - tri 1358 519 903 513 - tri 1359 507 573 575 - tri 1360 507 575 580 - tri 1361 512 646 647 - tri 1362 512 639 909 - tri 1363 512 647 639 - tri 1364 902 910 645 - tri 1365 902 645 646 - tri 1366 643 576 642 - tri 1367 911 630 631 - tri 1368 911 649 630 - tri 1369 647 912 638 - tri 1370 647 648 912 - tri 1371 645 660 644 - tri 1372 644 660 648 - tri 1373 640 914 913 - tri 1374 913 914 453 - tri 1375 638 912 635 - tri 1376 638 635 636 - tri 1377 651 649 911 - tri 1378 915 641 640 - tri 1379 915 640 913 - tri 1380 653 916 652 - tri 1381 916 658 652 - tri 1382 916 659 658 - tri 1383 662 659 916 - tri 1384 898 897 907 - tri 1385 906 898 907 - tri 1386 662 916 661 - tri 1387 661 916 653 - tri 1388 664 659 662 - tri 1389 917 643 641 - tri 1390 917 641 915 - tri 1391 663 661 901 - tri 1392 901 661 900 - tri 1393 900 661 910 - tri 1394 661 653 910 - tri 1395 910 653 645 - tri 1396 919 917 918 - tri 1397 919 643 917 - tri 1398 642 637 641 - tri 1399 642 639 637 - tri 1400 576 909 639 - tri 1401 576 639 642 - tri 1402 900 910 902 - tri 1403 519 571 903 - tri 1404 920 514 525 - tri 1405 920 516 514 - tri 1406 921 580 919 - tri 1407 921 919 918 - tri 1408 539 543 549 - tri 1409 539 549 550 - tri 1410 594 551 548 - tri 1411 594 548 599 - tri 1412 539 550 538 - tri 1413 594 552 551 - tri 1414 585 532 583 - tri 1415 532 531 583 - tri 1416 640 636 914 - tri 1417 636 634 914 - tri 1418 552 550 551 - tri 1419 552 538 550 - tri 1420 600 606 922 - tri 1421 600 598 606 - tri 1422 542 544 570 - tri 1423 542 570 543 - tri 1424 546 544 542 - tri 1425 544 561 570 - tri 1426 923 603 545 - tri 1427 545 603 544 - tri 1428 925 924 530 - tri 1429 925 530 532 - tri 1430 927 926 569 - tri 1431 927 928 926 - tri 1432 604 930 929 - tri 1433 605 930 604 - tri 1434 933 932 931 - tri 1435 568 569 926 - tri 1436 924 935 934 - tri 1437 935 516 920 - tri 1438 936 601 597 - tri 1439 936 600 937 - tri 1440 936 597 600 - tri 1441 924 934 530 - tri 1442 530 934 526 - tri 1443 934 525 526 - tri 1444 570 568 543 - tri 1445 935 525 934 - tri 1446 935 920 525 - tri 1447 584 932 933 - tri 1448 595 594 597 - tri 1449 597 594 598 - tri 1450 938 585 584 - tri 1451 938 584 933 - tri 1452 598 599 605 - tri 1453 939 534 571 - tri 1454 939 533 534 - tri 1455 940 571 519 - tri 1456 940 939 571 - tri 1457 940 519 523 - tri 1458 941 514 533 - tri 1459 941 525 514 - tri 1460 941 523 525 - tri 1461 523 939 940 - tri 1462 939 941 533 - tri 1463 941 939 523 - tri 1464 582 943 942 - tri 1465 582 578 943 - tri 1466 943 578 944 - tri 1467 578 581 944 - tri 1468 931 582 942 - tri 1469 945 584 529 - tri 1470 945 932 584 - tri 1471 945 931 932 - tri 1472 945 582 931 - tri 1473 945 529 582 - tri 1474 947 935 946 - tri 1475 935 947 516 - tri 1476 587 516 947 - tri 1477 580 921 948 - tri 1478 948 577 580 - tri 1479 948 581 577 - tri 1480 591 588 589 - tri 1481 701 894 705 - tri 1482 894 701 897 - tri 1483 949 535 553 - tri 1484 949 537 535 - tri 1485 949 950 537 - tri 1486 949 593 950 - tri 1487 949 553 593 - tri 1488 503 7 151 - tri 1489 7 503 502 - tri 1490 951 627 628 - tri 1491 951 899 627 - tri 1492 951 904 899 - tri 1493 951 628 904 - tri 1494 650 626 627 - tri 1495 630 649 908 - tri 1496 952 660 652 - tri 1497 953 650 651 - tri 1498 953 626 650 - tri 1499 953 655 626 - tri 1500 952 652 656 - tri 1501 650 627 649 - tri 1502 649 627 908 - tri 1503 954 723 739 - tri 1504 954 725 723 - tri 1505 954 732 725 - tri 1506 954 955 732 - tri 1507 956 739 874 - tri 1508 956 954 739 - tri 1509 956 955 954 - tri 1510 956 874 955 - tri 1511 957 927 569 - tri 1512 958 604 929 - tri 1513 958 606 604 - tri 1514 958 922 606 - tri 1515 957 561 562 - tri 1516 957 569 561 - tri 1517 959 646 512 - tri 1518 959 902 646 - tri 1519 959 903 902 - tri 1520 959 513 903 - tri 1521 959 509 513 - tri 1522 959 512 509 - tri 1523 960 580 575 - tri 1524 960 919 580 - tri 1525 960 643 919 - tri 1526 960 576 643 - tri 1527 960 575 576 - - numweights 1754 - weight 0 3 0.2993961573 ( 2.698390007 -3.0038146973 5.225025177 ) - weight 1 18 0.1550484151 ( 2.7801468372 -5.4309539795 -1.3267865181 ) - weight 2 17 0.2199983746 ( 3.1052598953 -4.7481369972 3.8670885563 ) - weight 3 4 0.3255570233 ( 5.0162091255 1.1628274918 -0.7139816284 ) - weight 4 3 0.2965093255 ( 2.9546298981 3.4700737 5.5409750938 ) - weight 5 18 0.1987033039 ( 3.0363867283 1.0429344177 -1.0108366013 ) - weight 6 17 0.2874504924 ( 3.3792145252 1.462583065 5.7187418938 ) - weight 7 22 0.0892368034 ( 2.9546298981 -13.470287323 6.7925114632 ) - weight 8 4 0.0641049966 ( 5.2494192123 -5.1352658272 0.8210580945 ) - weight 9 19 0.0639951378 ( 2.9546298981 -4.9873356819 7.9501786232 ) - weight 10 3 0.4058934152 ( 1.9773199558 -3.0314559937 6.2920651436 ) - weight 11 18 0.1903107464 ( 2.059076786 -5.4585952759 -0.2597465515 ) - weight 12 17 0.2105636597 ( 2.4466333389 -5.0416016579 4.9345011711 ) - weight 13 4 0.1932321787 ( 6.2695603371 1.1411877871 -1.0104988813 ) - weight 14 3 0.3426049352 ( 1.9608099461 -4.3739852905 5.1643152237 ) - weight 15 18 0.1170412377 ( 2.0425667763 -6.8011245728 -1.3874964714 ) - weight 16 17 0.2267267555 ( 2.3654110432 -6.0735421181 3.5192348957 ) - weight 17 4 0.3136270642 ( 5.2151241302 2.3798923492 -1.664909482 ) - weight 18 3 0.4035560191 ( 2.1414299011 2.9136734009 6.6546053886 ) - weight 19 18 0.2582558692 ( 2.2231867313 0.4865341187 0.1027936935 ) - weight 20 17 0.2200717628 ( 2.6312847137 0.6434550285 6.7090339661 ) - weight 21 4 0.0549555458 ( 6.5766744614 -4.6496090889 0.3589117825 ) - weight 22 19 0.0631608218 ( 2.1414299011 -5.4437012672 9.1084032059 ) - weight 23 3 0.3488970995 ( 0 -0.7088775635 7.0264353752 ) - weight 24 18 0.2357621342 ( 0.0817569122 -3.1360168457 0.4746236801 ) - weight 25 10 0.0621720627 ( -7.6693429947 -1.4263263941 -2.1424839497 ) - weight 26 17 0.0989268646 ( 0.5147314668 -2.9914371967 6.3158211708 ) - weight 27 4 0.2542417645 ( 7.6681761742 -1.4275387526 -2.1458323002 ) - weight 28 3 0.3999068141 ( 0 2.889793396 7.3176450729 ) - weight 29 18 0.2745150328 ( 0.0817569122 0.4626541138 0.7658333778 ) - weight 30 17 0.2120525688 ( 0.5314486027 0.4311733246 7.4650359154 ) - weight 31 4 0.052953016 ( 7.9564180374 -4.9447278976 -1.383249402 ) - weight 32 19 0.0605725758 ( 0 -5.4092116356 9.7709760666 ) - weight 33 3 0.380453527 ( 0 -4.103515625 6.6814451218 ) - weight 34 18 0.1478621066 ( 0.0817569122 -6.5306549072 0.1296334267 ) - weight 35 10 0.2436818331 ( -7.3316373825 1.8866200447 -2.8860740662 ) - weight 36 17 0.0948179513 ( 0.4949269295 -6.2030892372 5.1636557579 ) - weight 37 4 0.1331845969 ( 7.3305616379 1.8853666782 -2.8896467686 ) - weight 38 5 0.8161436319 ( 3.8878180981 2.8083443642 -0.9422174096 ) - weight 39 4 0.1838563681 ( -1.551076293 23.9488277435 1.4582973719 ) - weight 40 17 0.0628809556 ( 10.1577386856 -22.6902294159 -1.9907970428 ) - weight 41 5 0.4662843645 ( 4.3943181038 -0.9579893947 -3.2046582699 ) - weight 42 4 0.4708346725 ( 1.5129363537 20.8127384186 2.0390136242 ) - weight 43 5 0.8272587657 ( 1.8893568516 2.6524467468 -3.3368186951 ) - weight 44 4 0.1727412343 ( 0.4822210371 23.904592514 -0.9115152955 ) - weight 45 5 0.5181785822 ( 5.3544354439 -0.8416907191 -1.4499435425 ) - weight 46 4 0.4818214178 ( -0.0556480698 20.7613315582 3.2845153809 ) - weight 47 17 0.0574238077 ( 12.0703048706 -21.8741645813 -4.0665569305 ) - weight 48 5 0.4668849707 ( 5.1271290779 -0.6304965019 -0.3782848716 ) - weight 49 4 0.4756912291 ( -1.1696680784 20.7271003723 3.2344005108 ) - weight 50 5 0.3280668557 ( 5.0139102936 -3.2652232647 -1.2108880281 ) - weight 51 4 0.6719331741 ( 0.1777221411 18.313785553 3.3253929615 ) - weight 52 5 0.3864535093 ( 3.958927393 -3.6053898335 -2.957447052 ) - weight 53 4 0.6135464311 ( 1.7714664936 18.1309146881 2.0193655491 ) - weight 54 5 0.3906511068 ( 3.8813905716 -3.2169439793 0.084704347 ) - weight 55 4 0.6093488932 ( -1.2579119205 17.9261112213 2.4581241608 ) - weight 56 5 0.7487922907 ( 3.7095022202 1.3580366373 1.2399996519 ) - weight 57 4 0.2512077391 ( -3.3744945526 22.1081066132 1.8874269724 ) - weight 58 5 1 ( -4.2577934265 7.5677294731 3.8658027649 ) - weight 59 5 1 ( -1.2351732254 10.4706535339 4.1677079201 ) - weight 60 5 1 ( -3.3146660328 11.5184268951 2.9426195621 ) - weight 61 5 1 ( 3.1554095745 5.5837798119 -0.4485310316 ) - weight 62 5 0.9363083243 ( 1.6754149199 5.3300714493 -2.7917129993 ) - weight 63 4 0.0636916757 ( -0.6477109194 26.3573722839 -1.3802423477 ) - weight 64 5 0.9264044166 ( 2.4693384171 4.1782531738 2.1783468723 ) - weight 65 4 0.0735955834 ( -5.0732617378 24.4508781433 0.4740161598 ) - weight 66 5 1 ( 2.2793114185 7.7247605324 2.8431830406 ) - weight 67 5 1 ( 3.4153053761 8.4807701111 -0.2062401772 ) - weight 68 5 1 ( 2.7190690041 9.0635175705 -2.3901698589 ) - weight 69 5 1 ( 2.1975445747 6.9456353188 4.4191513062 ) - weight 70 5 1 ( 2.7374165058 10.372590065 -0.7578687668 ) - weight 71 5 1 ( 0.7603302002 11.2705554962 3.2701146603 ) - weight 72 5 1 ( 2.1957287788 11.8166103363 1.823038578 ) - weight 73 5 1 ( 1.0239574909 10.2770709991 -2.6037693024 ) - weight 74 5 1 ( 2.8841826916 12.3765068054 -0.7622697353 ) - weight 75 5 1 ( 1.1666094065 12.1185693741 -2.9122829437 ) - weight 76 6 0.0678309724 ( -1.0919933319 0.9708321691 4.6769046783 ) - weight 77 5 0.9321690202 ( 4.1606378555 15.8592729568 0.5396974087 ) - weight 78 6 0.1074483991 ( 1.72080338 1.4492480755 5.9508976936 ) - weight 79 5 0.8925516009 ( 4.225479126 14.0924396515 -2.0367069244 ) - weight 80 6 0.3582289219 ( 0.628177464 1.5100712776 4.4678373337 ) - weight 81 5 0.6417710781 ( 3.6980719566 15.6490268707 -1.2025152445 ) - weight 82 5 1 ( -2.1428427696 6.6770496368 5.8459920883 ) - weight 83 5 1 ( -3.8036692142 4.8705377579 3.6413507462 ) - weight 84 7 0.3494953811 ( -2.4943253994 3.6975522041 2.7471454144 ) - weight 85 8 0.0571241342 ( -2.4645109177 -1.4174586535 2.7518808842 ) - weight 86 6 0.4873141348 ( -0.9316865802 6.3577523232 5.0021162033 ) - weight 87 5 0.1060663685 ( 7.7436475754 18.4994010925 -2.516793251 ) - weight 88 7 0.5249263048 ( -0.5293371677 5.7498178482 3.7259202003 ) - weight 89 8 0.4750737548 ( -0.5440317392 0.6798231602 3.7235510349 ) - weight 90 7 0.5011256933 ( -2.6995339394 5.7909731865 0.3445320129 ) - weight 91 8 0.4988742769 ( -2.7143614292 0.6627620459 0.3420407772 ) - weight 92 7 0.3499529958 ( -0.6416786909 2.480966568 3.7681331635 ) - weight 93 8 0.0571989305 ( -0.5862910151 -2.5905196667 3.7770707607 ) - weight 94 6 0.4879522324 ( 0.7256572843 4.6461119652 4.4745788574 ) - weight 95 5 0.1048958525 ( 5.6605443954 17.3202953339 -2.9913318157 ) - weight 96 7 0.3494953811 ( -2.6240487099 0.8974570632 2.1076357365 ) - weight 97 8 0.0571241342 ( -2.5341441631 -4.2218856812 2.1220607758 ) - weight 98 6 0.4873141348 ( -1.8665388823 4.6316509247 2.9014120102 ) - weight 99 5 0.1060663685 ( 5.6059412956 19.4786205292 -0.8622012734 ) - weight 100 7 0.3791610003 ( -2.2633793354 -2.1904680729 -0.388630569 ) - weight 101 6 0.4677073956 ( -2.7636320591 3.8389770985 -0.901691854 ) - weight 102 5 0.1531316042 ( 2.9119970798 22.2204647064 0.1968847662 ) - weight 103 7 0.4800624251 ( -3.3226504326 1.7190711498 -0.7083392143 ) - weight 104 8 0.0537899137 ( -3.2499859333 -3.4251763821 -0.6967391372 ) - weight 105 6 0.4661476612 ( -2.8701136112 7.1096286774 1.5066817999 ) - weight 106 6 0.6878799796 ( -2.8391826153 2.474501133 0.2516874969 ) - weight 107 5 0.3121200204 ( 2.8423197269 20.6454181671 1.0407831669 ) - weight 108 5 1 ( 2.3688318729 16.8878383636 0.3538792133 ) - weight 109 7 0.1837866157 ( -2.3550980091 -6.6992425919 -0.8607495427 ) - weight 110 6 0.416490972 ( -4.0503282547 0.6949005127 -3.904948473 ) - weight 111 5 0.3997223675 ( -0.593882978 23.2316646576 2.8888425827 ) - weight 112 6 0.5006880164 ( -3.1174147129 -2.0217015743 -1.2455921173 ) - weight 113 5 0.4993120134 ( -0.9100345373 19.4096488953 3.6728556156 ) - weight 114 7 0.1837866157 ( -2.8476109505 -4.7555894852 -1.3539992571 ) - weight 115 6 0.416490972 ( -4.1351985931 2.5323867798 -2.9668159485 ) - weight 116 5 0.3997223675 ( 1.2341464758 23.5701389313 1.990291357 ) - weight 117 7 0.3791610003 ( -3.0071241856 -2.4892652035 -1.1524087191 ) - weight 118 6 0.4677073956 ( -3.6906523705 4.1497044563 -1.4211868048 ) - weight 119 5 0.1531316042 ( 3.1222548485 23.1328716278 0.7877306938 ) - weight 120 6 0.3806169331 ( 3.6287479401 1.3644057512 2.9656193256 ) - weight 121 5 0.6193830371 ( 1.4410797358 15.5353069305 -3.6873402596 ) - weight 122 7 0.3138300776 ( -1.0931190252 2.3419041634 4.724357605 ) - weight 123 8 0.0512947291 ( -1.0347180367 -2.7359178066 4.7337708473 ) - weight 124 6 0.4375846982 ( 0.4466215372 3.9590725899 5.2411413193 ) - weight 125 5 0.1972905397 ( 5.8427562714 16.4814720154 -2.3583407402 ) - weight 126 7 0.2687388957 ( 3.5328960419 1.7962034941 4.1677770615 ) - weight 127 6 0.4865542054 ( 4.6000242233 3.5796954632 3.0933737755 ) - weight 128 5 0.2447068244 ( 2.5598807335 16.2778320313 -5.7033133507 ) - weight 129 7 0.2911455631 ( 2.8106846809 2.182425499 3.3188474178 ) - weight 130 6 0.5271217823 ( 3.845518589 4.4679136276 2.9110867977 ) - weight 131 5 0.1817326397 ( 3.2957699299 17.1885967255 -5.5604352951 ) - weight 132 7 0.5836595297 ( 3.0403802395 5.4717907906 3.3257956505 ) - weight 133 8 0.3067108989 ( 3.0308542252 0.4769861102 3.3243906498 ) - weight 134 6 0.1096295714 ( 4.8739180565 6.9663300514 4.8013358116 ) - weight 135 7 0.5046935678 ( 4.5119667053 4.9490132332 -0.911067903 ) - weight 136 8 0.4953064919 ( 4.5136213303 -0.0287803728 -0.9106392264 ) - weight 137 7 0.5249263048 ( 1.0769515038 7.1227507591 0.3099584579 ) - weight 138 8 0.4750737548 ( 1.0327157974 2.0750460625 0.302860707 ) - weight 139 7 0.1678375602 ( 1.9595971107 -7.0594010353 -1.2271975279 ) - weight 140 6 0.4213652015 ( -0.110463053 0.3573599756 -5.7060923576 ) - weight 141 5 0.4107972682 ( -3.5362012386 22.8748989105 -0.2885893881 ) - weight 142 6 0.240669325 ( -0.9439319372 -2.4775254726 -2.1752688885 ) - weight 143 5 0.7593306899 ( -2.6621258259 19.0179042816 2.0688560009 ) - weight 144 5 1 ( -0.7059044242 18.5749492645 3.1288278103 ) - weight 145 7 0.3638229072 ( 2.6398720741 -5.0778713226 -2.1087787151 ) - weight 146 6 0.4815303087 ( 0.8533915281 2.3917098045 -5.3917293549 ) - weight 147 5 0.1546468437 ( -2.4051907063 23.3825092316 -2.193731308 ) - weight 148 7 0.3638229072 ( 2.6372582912 -2.597776413 -1.0621535778 ) - weight 149 6 0.4815303087 ( 1.6621860266 3.6215064526 -3.137898922 ) - weight 150 5 0.1546468437 ( -0.4323529303 22.0665168762 -3.4674575329 ) - weight 151 7 0.3638229072 ( 3.1218242645 -2.923065424 -1.9404640198 ) - weight 152 6 0.4815303087 ( 1.8735022545 3.9008951187 -4.1325516701 ) - weight 153 5 0.1546468437 ( -0.9999123216 22.8783397675 -3.8292133808 ) - weight 154 5 1 ( -0.3363295197 15.7739887238 3.0710904598 ) - weight 155 5 1 ( 2.2130551338 16.2762508392 1.861179471 ) - weight 156 6 0.0679571778 ( -2.3299331665 -0.001808617 0.9716612697 ) - weight 157 5 0.9320428371 ( 1.5494645834 18.5608196259 1.9856507778 ) - weight 158 5 0.7307804823 ( -3.0575885773 2.3152019978 3.1476593018 ) - weight 159 4 0.2692195177 ( -6.4679012299 21.5268917084 -4.4719657898 ) - weight 160 5 0.7554550767 ( -1.1517215967 2.2824749947 4.3019695282 ) - weight 161 4 0.2445449233 ( -7.2789201736 21.6042175293 -2.3978149891 ) - weight 162 5 0.5773497224 ( 2.5208466053 -0.8100056052 -4.480679512 ) - weight 163 4 0.4226502776 ( 2.4218072891 20.8751525879 -0.0418715067 ) - weight 164 5 0.4041851461 ( 2.4115941525 -3.3943634033 -4.0101184845 ) - weight 165 4 0.5958148837 ( 2.5020096302 18.268163681 0.2889437377 ) - weight 166 5 0.4961496294 ( 1.5609407425 -0.9741119146 -4.3582692146 ) - weight 167 4 0.5038503408 ( 2.1898999214 20.5301876068 -0.9310017228 ) - weight 168 5 0.2995138168 ( 1.2290812731 -3.6068441868 -3.1954739094 ) - weight 169 4 0.7004861832 ( 1.5781595707 17.7093849182 -0.6813129187 ) - weight 170 5 1 ( -0.5712785125 4.3974399567 -2.5845658779 ) - weight 171 5 1 ( -2.5667204857 8.5903348923 -3.0991485119 ) - weight 172 5 1 ( 0.741738379 8.3396472931 -3.1911435127 ) - weight 173 5 0.7584241033 ( -0.7133479118 1.2204447985 -3.0228631496 ) - weight 174 4 0.2415758371 ( 0.0812014863 22.0175361633 -3.1921887398 ) - weight 175 5 1 ( -4.1719765663 7.0256857872 -1.6126760244 ) - weight 176 5 1 ( -2.2410752773 11.4931564331 -2.6118865013 ) - weight 177 6 0.0550869107 ( 4.3739752769 1.2255403996 4.6923189163 ) - weight 178 5 0.9449130893 ( 2.2159044743 13.8881349564 -4.179895401 ) - weight 179 5 1 ( -0.2372596264 15.616353035 -4.3995432854 ) - weight 180 5 1 ( -5.3756160736 7.7229771614 0.1208727509 ) - weight 181 5 1 ( -5.6898884773 9.6124973297 0.8927577138 ) - weight 182 5 1 ( -4.9261484146 4.8091440201 1.6876786947 ) - weight 183 5 1 ( -3.2221794128 4.5438623428 -1.0616217852 ) - weight 184 5 0.7210726738 ( -3.4796197414 2.2913730145 0.8934414983 ) - weight 185 4 0.278927356 ( -4.3537788391 21.8525123596 -5.2993922234 ) - weight 186 7 0.5836595297 ( 4.3761320114 3.5273792744 2.0219321251 ) - weight 187 8 0.3067108989 ( 4.4080691338 -1.4428473711 2.0272607803 ) - weight 188 6 0.1096295714 ( 5.4138197899 6.2197165489 2.2683331966 ) - weight 189 7 0.2905490696 ( 3.6716406345 0.3628133535 1.6486035585 ) - weight 190 6 0.5260417461 ( 3.8945426941 4.0837593079 0.3242026269 ) - weight 191 5 0.1834091842 ( 1.3066592216 18.885187149 -5.4769897461 ) - weight 192 7 0.5036625862 ( 4.0375976563 0.8078240752 -1.6356568336 ) - weight 193 6 0.4963374436 ( 3.7195682526 6.4998006821 -1.967184186 ) - weight 194 7 0.1692353189 ( 3.2534415722 -2.9061031342 0.565579772 ) - weight 195 6 0.5233104229 ( 2.485001564 2.3021318913 -2.297369957 ) - weight 196 5 0.307454288 ( -1.0299835205 20.4040050507 -3.4113316536 ) - weight 197 6 0.2164441943 ( 3.1877169609 0.7535933256 1.417429924 ) - weight 198 5 0.7835558057 ( 0.1904278398 16.5231437683 -3.0357739925 ) - weight 199 6 0.1526855826 ( 2.8497700691 -0.2926419079 -1.1933891773 ) - weight 200 5 0.8473144174 ( -2.086104393 18.0243415833 -2.2683103085 ) - weight 201 6 0.5 ( 0.8309375048 -2.4827189445 -3.5898940563 ) - weight 202 5 0.5 ( -4.2965474129 19.3864059448 0.5377694368 ) - weight 203 5 1 ( -1.8005094528 16.0602855682 -2.6819884777 ) - weight 204 5 1 ( -3.3115811348 15.6246986389 -0.3779873252 ) - weight 205 5 1 ( -3.5788626671 18.4124717712 0.0744775608 ) - weight 206 22 1 ( 1.7510401011 -0.3758468628 10.405831337 ) - weight 207 22 1 ( 0.000000071 -0.2896270752 10.802520752 ) - weight 208 22 0.9387524128 ( 0 -2.7040863037 11.1199111938 ) - weight 209 19 0.0612475909 ( 0 6.1175503731 11.3145484924 ) - weight 210 22 1 ( 2.1411099434 -2.3178787231 10.4711513519 ) - weight 211 22 1 ( 1.4680099487 3.8153495789 7.5456018448 ) - weight 212 22 1 ( 2.649600029 4.1038856506 5.4536514282 ) - weight 213 22 1 ( 0 3.719669342 7.5771517754 ) - weight 214 22 0.8961666822 ( 1.3614399433 -5.2326774597 9.032541275 ) - weight 215 19 0.1038333252 ( 1.3614399433 3.4152784348 9.4575052261 ) - weight 216 22 0.8665010929 ( 0 -6.2521476746 8.1296615601 ) - weight 217 19 0.1334988922 ( 0 2.3203961849 8.6477241516 ) - weight 218 22 0.8395406604 ( 1.6664299965 -5.8079566956 7.9944214821 ) - weight 219 19 0.1604593247 ( 1.6664299965 2.7509813309 8.4739656448 ) - weight 220 20 0.0742525235 ( -2.4782428741 -4.6540336609 0.952773571 ) - weight 221 18 0.0514105596 ( 1.6281969547 7.4121360779 -0.0568265915 ) - weight 222 17 0.082559742 ( 2.0281128883 7.3952012062 8.2561483383 ) - weight 223 22 0.6282635927 ( 1.5464400053 -7.1010856628 7.7465214729 ) - weight 224 19 0.163513571 ( 1.5464400053 1.4410680532 8.3406829834 ) - weight 225 20 0.0754575953 ( -4.0246829987 -4.8189239502 1.0721035004 ) - weight 226 18 0.0558094978 ( 0.0817569122 7.2472457886 0.0625033379 ) - weight 227 17 0.0838996321 ( 0.4910732806 7.1850757599 8.4182033539 ) - weight 228 22 0.6384598613 ( 0 -7.2659759521 7.8658514023 ) - weight 229 19 0.1463733912 ( 0 1.287304163 8.4740438461 ) - weight 230 22 1 ( 3.1945099831 -0.7266159058 9.1527709961 ) - weight 231 22 0.9379876256 ( 3.7911200523 -2.4407157898 8.6227111816 ) - weight 232 19 0.062012367 ( 3.7911200523 6.1604132652 8.8038644791 ) - weight 233 22 0.8737977743 ( 3.9777700901 -3.0628471375 7.9290118217 ) - weight 234 19 0.126202181 ( 3.9777700901 5.4797177315 8.1675310135 ) - weight 235 22 0.8407360911 ( 4.3908100128 -4.371837616 7.4161314964 ) - weight 236 19 0.1592639238 ( 4.3908100128 4.1307144165 7.7716879845 ) - weight 237 20 0.0983735695 ( -0.3745930195 -3.9401741028 0.005923748 ) - weight 238 18 0.0533885434 ( 3.7318468094 8.125995636 -1.0036764145 ) - weight 239 17 0.1093793511 ( 4.0739388466 8.3448810577 7.393497467 ) - weight 240 22 0.5654591918 ( 3.6500899792 -6.3872261047 6.7996716499 ) - weight 241 19 0.173399359 ( 3.6500899792 2.0689425468 7.3347539902 ) - weight 242 22 1 ( 2.4722099304 1.9038238525 7.3857517242 ) - weight 243 22 0.8982512355 ( 6.2419500351 -2.8530273438 6.7008314133 ) - weight 244 19 0.1017487347 ( 6.2419500351 5.5807762146 6.9256620407 ) - weight 245 20 0.0671572387 ( 2.9524970055 -1.5924568176 -0.7351861 ) - weight 246 17 0.0658963397 ( 7.3529982567 10.8477201462 7.0556874275 ) - weight 247 25 0.1072412506 ( 4.8195490837 3.0045952797 -6.3430294991 ) - weight 248 22 0.6361353993 ( 6.9771800041 -4.0395088196 6.0585618019 ) - weight 249 19 0.1235697716 ( 6.9771800041 4.3424348831 6.390162468 ) - weight 250 20 0.1189748794 ( 4.3319969177 0.5146446228 -1.9614863396 ) - weight 251 24 0.0686988086 ( -0.7355012894 4.5274672508 -4.1547088623 ) - weight 252 25 0.1991942376 ( 4.0148243904 2.9308123589 -3.6609256268 ) - weight 253 22 0.5254926085 ( 8.3566799164 -1.9324073792 4.8322615623 ) - weight 254 19 0.0876394585 ( 8.3566799164 6.3335971832 4.9834070206 ) - weight 255 20 0.0753040016 ( 3.1552271843 1.3438835144 -0.4256362915 ) - weight 256 25 0.0678025484 ( 5.5069956779 1.4669491053 -3.9094977379 ) - weight 257 22 0.8568934202 ( 7.179910183 -1.1031684875 6.3681116104 ) - weight 258 24 0.1195673719 ( 0.3474287987 5.5712571144 -1.602230072 ) - weight 259 25 0.1591295004 ( 5.2429804802 0.5547832847 -2.3867588043 ) - weight 260 22 0.721303165 ( 7.2737498283 0.6200714111 5.8760514259 ) - weight 261 24 0.0923882127 ( 1.1369185448 6.3111872673 -1.9519081116 ) - weight 262 22 0.9076117873 ( 6.4842600822 0.2703933716 6.6159815788 ) - weight 263 3 0.228978619 ( 0 0.8876724243 -10.0816850662 ) - weight 264 17 0.4475009739 ( -0.4673767388 2.6732456684 -9.8762626648 ) - weight 265 4 0.2007077932 ( -8.3190555573 -4.1823534966 -7.8076486588 ) - weight 266 19 0.122812584 ( 0 -8.9328775406 -7.3850421906 ) - weight 267 3 0.1972438842 ( 2.6951899529 -2.520614624 -7.0929346085 ) - weight 268 17 0.3190617561 ( 2.3949406147 -1.3162691593 -7.9516830444 ) - weight 269 4 0.421169579 ( -6.4965291023 -0.1662263274 -4.9158987999 ) - weight 270 19 0.062524803 ( 2.6951899529 -12.065281868 -4.108291626 ) - weight 271 3 0.230407387 ( 0 -3.271156311 -6.8441047668 ) - weight 272 10 0.2720878422 ( 5.3073468208 0.1301013082 -7.4472193718 ) - weight 273 17 0.2008628398 ( -0.2815203369 -2.141831398 -7.7412519455 ) - weight 274 4 0.2966419458 ( -5.3107328415 0.1299694926 -7.4448184967 ) - weight 275 3 0.1813982129 ( 3.4160699844 1.0148239136 -8.7502756119 ) - weight 276 17 0.4655880928 ( 3.0194907188 2.5236442089 -8.7458963394 ) - weight 277 4 0.2088200301 ( -8.2860956192 -3.6335644722 -4.1805152893 ) - weight 278 19 0.1441936195 ( 3.4160699844 -8.6891956329 -6.069961071 ) - weight 279 3 0.1992882937 ( 6.1590600014 -0.9346160889 -5.6005349159 ) - weight 280 17 0.3540285528 ( 5.9387712479 -0.0880630836 -6.3165011406 ) - weight 281 4 0.3922216594 ( -6.3235416412 -1.0321407318 -0.9207379222 ) - weight 282 19 0.0544615164 ( 6.1590600014 -10.3542480469 -2.761067152 ) - weight 283 3 0.2318673581 ( 8.2407598495 -0.3582458496 1.2500151396 ) - weight 284 17 0.2079937756 ( 8.4103002548 -1.1477025747 0.3441610932 ) - weight 285 4 0.5601388812 ( -0.6552016139 -0.7696338296 3.4834339619 ) - weight 286 3 0.3105493188 ( 5.3668899536 -0.782245636 5.1301150322 ) - weight 287 18 0.1053828746 ( 5.4486470222 -3.2093849182 -1.4216966629 ) - weight 288 17 0.2222522348 ( 5.7639107704 -2.5322749615 4.1617074013 ) - weight 289 4 0.3618155122 ( 3.9903204441 -0.5732147694 2.1142649651 ) - weight 290 3 0.1634391248 ( 7.5889902115 -2.8999176025 2.0655453205 ) - weight 291 17 0.1255707443 ( 7.8064222336 -3.8196804523 0.5582940578 ) - weight 292 4 0.7109901309 ( 0.3272484839 1.6742998362 2.7011499405 ) - weight 293 3 0.2218398154 ( 5.0421299934 -3.955165863 4.4169454575 ) - weight 294 18 0.0730421096 ( 5.1238870621 -6.3823051453 -2.1348662376 ) - weight 295 17 0.1441233009 ( 5.3987464905 -5.444671154 2.7243113518 ) - weight 296 4 0.5609947443 ( 3.4247360229 2.4409537315 0.9844840765 ) - weight 297 3 0.2988711596 ( 1.9142600298 -5.6988983154 4.9153752327 ) - weight 298 18 0.068852976 ( 1.9960169792 -8.1260375977 -1.6364364624 ) - weight 299 17 0.0783879459 ( 2.3046472073 -7.3001885414 2.9614009857 ) - weight 300 4 0.5538879633 ( 4.9930238724 3.6570615768 -2.0377933979 ) - weight 301 3 0.1712329835 ( 3.5819699764 -9.658367157 4.7623753548 ) - weight 302 4 0.8287670016 ( 4.2405338287 7.822373867 -1.2854690552 ) - weight 303 3 0.0713142753 ( 7.6723899841 -14.3153362274 4.8165154457 ) - weight 304 4 0.9286857247 ( 2.8187980652 13.1000757217 1.6379466057 ) - weight 305 4 1 ( 2.7772831917 13.3528299332 -1.6404926777 ) - weight 306 4 1 ( 2.0170965195 15.4658517838 1.9271478653 ) - weight 307 3 0.0998161286 ( 0.6950399876 -10.0085983276 2.0434751511 ) - weight 308 4 0.9001838565 ( 2.7216346264 7.4867973328 -4.950135231 ) - weight 309 3 0.3702009916 ( 0 -5.0055847168 5.2862653732 ) - weight 310 18 0.1009000689 ( 0.0817569122 -7.432723999 -1.2655463219 ) - weight 311 10 0.2223942727 ( -6.0234746933 2.6765515804 -3.537974596 ) - weight 312 17 0.0865348428 ( 0.414835304 -6.7429895401 3.5944683552 ) - weight 313 4 0.219969824 ( 6.0222039223 2.6753938198 -3.5410399437 ) - weight 314 4 1 ( 1.1765203476 14.7099990845 -5.3677287102 ) - weight 315 4 1 ( 2.1131527424 16.6026268005 -1.4075143337 ) - weight 316 5 0.3371713161 ( -2.2024664879 -2.5021989346 -3.5181751251 ) - weight 317 4 0.6628287435 ( 1.121892333 18.2545051575 -4.2301945686 ) - weight 318 5 0.0750278234 ( 0.1063678116 -2.5668697357 6.5856132507 ) - weight 319 4 0.9249721766 ( -8.2527170181 16.7000961304 -0.0923267752 ) - weight 320 4 1 ( -5.7697691917 15.4351568222 2.586609602 ) - weight 321 5 0.3026379347 ( 3.5712275505 -2.6363241673 3.1372683048 ) - weight 322 4 0.6973620653 ( -4.3743767738 17.8657264709 2.6464571953 ) - weight 323 4 1 ( -3.0904977322 14.5610561371 3.8086977005 ) - weight 324 3 0.14986296 ( 9.3841495514 -3.3818283081 -1.219914794 ) - weight 325 17 0.1202153414 ( 9.4100160599 -3.4722850323 -2.841247797 ) - weight 326 4 0.729921639 ( -3.3835465908 2.2259340286 3.1192202568 ) - weight 327 3 0.1863135993 ( 6.5873398781 -2.4839172363 -5.4120049477 ) - weight 328 17 0.2193037421 ( 6.3771677017 -1.6311485767 -6.5309710503 ) - weight 329 4 0.5943826437 ( -6.3061628342 0.5767379999 -0.7460707426 ) - weight 330 3 0.1998521388 ( 8.6325597763 -1.0597953796 -2.6692247391 ) - weight 331 17 0.1354093254 ( 8.5764665604 -0.8804370165 -3.6442070007 ) - weight 332 4 0.6647385359 ( -4.4614505768 -0.2849123776 2.3504571915 ) - weight 333 3 0.1155277118 ( 7.4725899696 -4.7909049988 -4.7723345757 ) - weight 334 4 0.8844723105 ( -6.0325565338 3.0394468307 -0.1334996372 ) - weight 335 3 0.1103929654 ( 4.7616200447 -8.1659545898 -6.01755476 ) - weight 336 4 0.8896070123 ( -6.249604702 5.8092298508 -3.679213047 ) - weight 337 5 0.1316302568 ( -3.097820282 -2.6734855175 6.0461602211 ) - weight 338 4 0.8683697581 ( -8.2063779831 16.1523227692 -3.2965419292 ) - weight 339 3 0.3930873275 ( 0 -6.4403648376 3.6974253654 ) - weight 340 10 0.169102788 ( -4.5319018364 3.9766952991 -4.3551912308 ) - weight 341 17 0.1038755998 ( 0.323626399 -7.7533245087 1.7092866898 ) - weight 342 4 0.3339342475 ( 4.5304269791 3.9756381512 -4.3577241898 ) - weight 343 3 0.234931469 ( 0 -6.5301361084 -2.6305346489 ) - weight 344 10 0.3257513344 ( 1.3834265471 3.6259431839 -6.5771274567 ) - weight 345 17 0.0711769611 ( -0.0396362655 -6.3183317184 -4.4437589645 ) - weight 346 4 0.3681402504 ( -1.385961175 3.6254007816 -6.5769181252 ) - weight 347 3 0.2302151769 ( 0.4771699905 -6.5307846069 2.9339251518 ) - weight 348 17 0.0870902091 ( 0.756180048 -7.650829792 0.9211295843 ) - weight 349 4 0.6826946139 ( 3.6468877792 4.0928416252 -4.2014522552 ) - weight 350 3 0.1804637611 ( 1.3150800467 -5.4401054382 -5.6257348061 ) - weight 351 17 0.1681870967 ( 1.1013327837 -4.5217614174 -7.1565718651 ) - weight 352 4 0.6513491273 ( -4.6480317116 2.5702605247 -6.210310936 ) - weight 353 3 0.1705142111 ( 0.1665000021 -7.6281356812 -2.1573746204 ) - weight 354 10 0.0960386172 ( 0.886914432 4.7097678185 -6.7668795586 ) - weight 355 17 0.0726470575 ( 0.1537513733 -7.4954957962 -4.2591195107 ) - weight 356 4 0.6608000994 ( -1.0075739622 4.7658257484 -6.4609012604 ) - weight 357 3 0.1035555899 ( 1.5106099844 -8.0483856201 -4.9563946724 ) - weight 358 4 0.8964444399 ( -4.1032500267 5.2137742043 -6.2768163681 ) - weight 359 3 0.0648362264 ( 1.7901200056 -17.2447357178 -2.618904829 ) - weight 360 5 0.0541830696 ( -5.9347920418 -5.1323280334 -0.2401473522 ) - weight 361 4 0.8809807301 ( -2.0579988956 14.4630155563 -6.8959388733 ) - weight 362 5 0.1730842143 ( -5.610891819 -1.2642885447 1.5051972866 ) - weight 363 4 0.8269158006 ( -4.5161533356 17.9352760315 -6.7786431313 ) - weight 364 5 0.275066644 ( -3.7967493534 -0.7975314856 4.7096180916 ) - weight 365 4 0.7249333262 ( -7.4254808426 18.0978736877 -4.4793686867 ) - weight 366 5 0.4167443216 ( -4.5113611221 0.5403873324 1.0470705032 ) - weight 367 4 0.5832556486 ( -4.2885727882 19.9540367126 -6.0380268097 ) - weight 368 5 0.1514768004 ( -4.6734733582 -1.8370355368 -1.836192131 ) - weight 369 4 0.8485231996 ( -1.0255125761 18.1638889313 -6.4114384651 ) - weight 370 22 1 ( 6.1977901459 8.4980354309 3.8981716633 ) - weight 371 22 1 ( 4.7289199829 8.8134422302 0.2027816772 ) - weight 372 22 1 ( 4.7475600243 6.5352897644 5.4856314659 ) - weight 373 22 1 ( 4.1528902054 5.0905418396 6.5792217255 ) - weight 374 22 1 ( 3.978290081 4.4368476868 3.9854016304 ) - weight 375 22 1 ( 6.4211301804 2.0640411377 8.17192173 ) - weight 376 22 1 ( 5.7784399986 2.8446540833 8.8613109589 ) - weight 377 22 1 ( 5.7889099121 0.282623291 8.0855417252 ) - weight 378 24 0.0668390542 ( 0.1734485626 5.8462371826 1.2844314575 ) - weight 379 22 0.9331609607 ( 7.4477300644 3.5067329407 6.1510314941 ) - weight 380 22 1 ( 6.3436799049 1.3019523621 6.7690014839 ) - weight 381 22 1 ( 4.4503002167 2.6615486145 9.1099510193 ) - weight 382 22 1 ( 6.6125397682 8.991985321 -2.9377484322 ) - weight 383 24 0.0571298972 ( -0.22134161 -0.6442227364 6.8833770752 ) - weight 384 22 0.9428701401 ( 7.842520237 9.1056785583 -0.3394283056 ) - weight 385 24 0.111378029 ( -1.1370315552 -1.5324827433 4.9099502563 ) - weight 386 25 0.105331108 ( -0.8092665076 -1.8872258663 4.8576965332 ) - weight 387 22 0.783290863 ( 8.7582101822 7.1322517395 -1.2276883125 ) - weight 388 22 1 ( 6.2344698906 9.68957901 -0.1023983955 ) - weight 389 22 1 ( 4.1863298416 6.6580924988 0.3246916533 ) - weight 390 22 1 ( 4.038189888 8.2165260315 -3.3059682846 ) - weight 391 22 1 ( 3.0047702789 5.9508857727 -2.8457283974 ) - weight 392 22 1 ( 2.3421602249 7.295627594 -4.156358242 ) - weight 393 22 1 ( 0.0000001957 6.2235450745 -3.2658481598 ) - weight 394 22 1 ( 0.0000001957 6.9030418396 -6.7167687416 ) - weight 395 24 0.1057041064 ( 3.7261583805 -7.1904129982 3.7854766846 ) - weight 396 22 0.8942958713 ( 3.8950202465 6.0077781677 -6.8856186867 ) - weight 397 40 0.184688434 ( -7.6211800575 -6.776910305 1.1497573853 ) - weight 398 39 0.0978074223 ( 6.2725095749 -3.3218820095 -0.1605001241 ) - weight 399 22 0.7175041437 ( 0 3.3720817566 -6.4721183777 ) - weight 400 23 0.0978074223 ( -6.3388447762 0.8740983009 0.6034272909 ) - weight 401 24 0.184688434 ( 3.3614988327 -6.5687427521 1.2279129028 ) - weight 402 22 0.7175041437 ( 4.2596797943 3.450214386 -6.2639484406 ) - weight 403 24 0.1474835575 ( -1.0070514679 3.8792972565 3.6388397217 ) - weight 404 22 0.8525164723 ( 8.6282300949 5.8611412048 4.184091568 ) - weight 405 22 1 ( 7.3468298912 6.4065589905 5.9920315742 ) - weight 406 22 1 ( 6.6628699303 4.7827949524 7.4596414566 ) - weight 407 24 0.0617888346 ( -0.1698112488 3.5671372414 5.2967605591 ) - weight 408 22 0.938211143 ( 7.7909898758 7.5190620422 3.8719315529 ) - weight 409 22 1 ( 5.9484601021 6.9797859192 6.1427016258 ) - weight 410 22 1 ( 5.8876700401 -1.5171470642 7.8475914001 ) - weight 411 20 0.1071231738 ( 1.7128071785 -3.9590950012 -1.1628661156 ) - weight 412 17 0.1051118597 ( 6.090801239 8.6365280151 6.1401515007 ) - weight 413 22 0.5924144983 ( 5.7374901772 -6.4061470032 5.6308817863 ) - weight 414 19 0.1953504384 ( 5.7374901772 1.9473655224 6.1721506119 ) - weight 415 20 0.1891750991 ( 3.8313169479 -2.7443466187 -3.9023964405 ) - weight 416 25 0.147641018 ( 1.6463904381 4.4379987717 -6.260491848 ) - weight 417 22 0.4659926295 ( 7.8559999466 -5.1913986206 2.8913514614 ) - weight 418 19 0.1971912086 ( 7.8559999466 2.9166250229 3.3364536762 ) - weight 419 20 0.1440529972 ( 2.7443470955 -4.50365448 -4.2844562531 ) - weight 420 17 0.1465977579 ( 6.9414420128 8.8731412888 2.9268403053 ) - weight 421 22 0.4667060375 ( 6.7690300941 -6.9507064819 2.5092916489 ) - weight 422 19 0.2426431775 ( 6.7690300941 1.1305451393 3.1105048656 ) - weight 423 20 0.1900876909 ( 3.8894371986 -3.6656036377 -7.2585363388 ) - weight 424 17 0.0643401444 ( 7.9139142036 10.4177236557 0.1832520068 ) - weight 425 25 0.0508734323 ( -1.7721178532 5.0716166496 -6.4281134605 ) - weight 426 22 0.3889924586 ( 7.9141201973 -6.1126556396 -0.4647883177 ) - weight 427 19 0.3057062328 ( 7.9141201973 1.7039493322 0.0742753819 ) - weight 428 20 0.1501688957 ( 0.9611668587 -6.0561943054 -1.1531462669 ) - weight 429 18 0.0615025461 ( 5.067606926 6.0099754333 -2.1627464294 ) - weight 430 17 0.1669694334 ( 5.3409585953 6.58847332 5.6861801147 ) - weight 431 22 0.4150598645 ( 4.9858498573 -8.5032463074 5.640601635 ) - weight 432 19 0.2062992305 ( 4.9858498573 -0.1407634318 6.3661546707 ) - weight 433 17 0.3197784126 ( 6.8418030739 7.216105938 1.9130408764 ) - weight 434 22 0.3531831205 ( 6.7031202316 -8.803188324 1.9198416471 ) - weight 435 19 0.3270384371 ( 6.7031202316 -0.7665764093 2.6861577034 ) - weight 436 17 0.335439384 ( 6.5263638496 8.4403867722 -1.3919247389 ) - weight 437 22 0.2969803214 ( 6.5892701149 -8.4112586975 -1.5950684547 ) - weight 438 19 0.3675802648 ( 6.5892701149 -0.6851024628 -0.8495974541 ) - weight 439 3 0.0602750927 ( 6.1856298447 6.4489326477 -2.8100347519 ) - weight 440 17 0.4647755027 ( 6.1254887581 6.4071178436 -1.8351897001 ) - weight 441 22 0.1959326863 ( 6.1856298447 -10.4914283752 -1.5584983826 ) - weight 442 19 0.2790167034 ( 6.1856298447 -2.7540073395 -0.6303348541 ) - weight 443 20 0.0673497766 ( 2.4817171097 -8.2127838135 -4.6182165146 ) - weight 444 3 0.0944565237 ( 6.5064001083 6.2805252075 0.9239951372 ) - weight 445 17 0.3342530727 ( 6.6600856781 5.3499293327 1.7244161367 ) - weight 446 22 0.2158056498 ( 6.5064001083 -10.6598358154 2.1755316257 ) - weight 447 4 0.0554682016 ( -0.3149863183 -7.6131448746 2.9953896999 ) - weight 448 19 0.2326668203 ( 6.5064001083 -2.5935649872 3.1040458679 ) - weight 449 20 0.0763881281 ( 3.3531069756 -10.5411949158 -4.3854165077 ) - weight 450 3 0.1467750371 ( 7.3777899742 3.9521141052 1.1567951441 ) - weight 451 18 0.062722981 ( 7.4595470428 1.524974823 -5.3950161934 ) - weight 452 17 0.3791099787 ( 7.5434026718 3.0461657047 1.3404378891 ) - weight 453 22 0.1106511429 ( 7.3777899742 -12.9882469177 2.4083316326 ) - weight 454 4 0.0629120395 ( -0.4169381261 -5.1599297523 3.4496557713 ) - weight 455 19 0.1614407301 ( 7.3777899742 -4.8925032616 3.5405979156 ) - weight 456 3 0.0887356102 ( 4.7174100876 6.0775718689 4.2193751335 ) - weight 457 18 0.092637077 ( 4.7991671562 3.6504325867 -2.3324365616 ) - weight 458 17 0.2894819677 ( 5.0632200241 4.3355441093 4.9682178497 ) - weight 459 22 0.2918421626 ( 4.7174100876 -10.8627891541 5.4709115028 ) - weight 460 4 0.0670044422 ( 3.3998498917 -7.4898438454 2.4606075287 ) - weight 461 19 0.170298785 ( 4.7174100876 -2.5060892105 6.404510498 ) - weight 462 1 0.0607584976 ( 3.0031886101 5.7981109619 5.2397899628 ) - weight 463 20 0.0813488662 ( -1.0894329548 -8.7058258057 -0.1447463036 ) - weight 464 3 0.1548574418 ( 2.9352500439 5.7874832153 5.397465229 ) - weight 465 18 0.1817961633 ( 3.0170068741 3.3603439331 -1.1543464661 ) - weight 466 17 0.210098654 ( 3.3516283035 3.7459757328 6.1391167641 ) - weight 467 22 0.1946305186 ( 2.9352500439 -11.1528778076 6.6490015984 ) - weight 468 19 0.1165098697 ( 2.9352500439 -2.6915082932 7.6035385132 ) - weight 469 3 0.2131532431 ( 4.5985898972 3.7770729065 4.6188354492 ) - weight 470 18 0.135866642 ( 4.6803469658 1.3499336243 -1.9329762459 ) - weight 471 17 0.3338316679 ( 4.9675273895 2.0050866604 4.8076176643 ) - weight 472 22 0.1285075098 ( 4.5985898972 -13.1632881165 5.8703718185 ) - weight 473 4 0.0772697851 ( 3.8052499294 -5.2210812569 2.067735672 ) - weight 474 19 0.1113710925 ( 4.5985898972 -4.7625746727 7.0046248436 ) - weight 475 1 0.0682225302 ( 0.0679385737 5.5399017334 5.7622199059 ) - weight 476 20 0.0913423747 ( -4.0246829987 -8.9640350342 0.3776836395 ) - weight 477 3 0.0816377029 ( 0 5.5292739868 5.9198951721 ) - weight 478 18 0.1959606707 ( 0.0817569122 3.1021347046 -0.631916523 ) - weight 479 17 0.2359087318 ( 0.4512094259 3.329110384 6.7466454506 ) - weight 480 22 0.2185403854 ( 0 -11.4110870361 7.1714315414 ) - weight 481 19 0.1083876044 ( 0 -2.9027998447 8.1466417313 ) - weight 482 3 0.2669036984 ( 0 3.4557037354 5.9681453705 ) - weight 483 18 0.2351030111 ( 0.0817569122 1.0285644531 -0.5836663246 ) - weight 484 17 0.2690600157 ( 0.4539792836 1.3050194979 6.2937989235 ) - weight 485 22 0.0612899773 ( 0 -13.4846572876 7.2196817398 ) - weight 486 4 0.0671887174 ( 6.6972899437 -5.5945081711 -1.7490170002 ) - weight 487 19 0.1004546583 ( 0 -4.9641041756 8.376958847 ) - weight 488 3 0.0958259404 ( 6.9475197792 3.8599739075 -2.9940247536 ) - weight 489 17 0.4570136666 ( 6.8755598068 3.949221611 -2.6796872616 ) - weight 490 22 0.127003774 ( 6.9475197792 -13.0803871155 -1.7424883842 ) - weight 491 4 0.0932059735 ( -4.1452364922 -5.4302244186 1.5923289061 ) - weight 492 19 0.2269506603 ( 6.9475197792 -5.3491182327 -0.5860593319 ) - weight 493 3 0.0707394406 ( 3.9025700092 4.059715271 -5.7335548401 ) - weight 494 17 0.5343282819 ( 3.6783661842 4.759926796 -5.1163549423 ) - weight 495 22 0.1061162949 ( 3.9025700092 -12.880645752 -4.4820184708 ) - weight 496 19 0.2888159454 ( 3.9025700092 -5.3909373283 -3.3325431347 ) - weight 497 17 0.4509834349 ( 4.3374037743 6.3212270737 -3.7598829269 ) - weight 498 22 0.194998771 ( 4.5065398216 -11.0385169983 -3.5053982735 ) - weight 499 19 0.3540177643 ( 4.5065398216 -3.4700992107 -2.5216143131 ) - weight 500 20 0.0890728533 ( 2.6146569252 -3.3222961426 -9.7411165237 ) - weight 501 17 0.2058718204 ( 6.4987211227 11.3304424286 -2.0684807301 ) - weight 502 22 0.3525308967 ( 6.6393399239 -5.7693481445 -2.947368145 ) - weight 503 19 0.3525243998 ( 6.6393399239 1.8277248144 -2.4288711548 ) - weight 504 23 0.1092495471 ( -4.9758806229 3.0537950993 -3.6992185116 ) - weight 505 24 0.2156514823 ( 1.9940786362 -5.1147828102 -3.3696594238 ) - weight 506 25 0.1801882088 ( -5.693230629 0.4039458334 -3.0217761993 ) - weight 507 22 0.2771679461 ( 5.6270999908 -1.1473579407 -4.8099884987 ) - weight 508 19 0.2177427709 ( 5.6270999908 6.2681145668 -4.6905274391 ) - weight 509 20 0.125429675 ( 3.5616669655 -0.5211257935 -9.6704063416 ) - weight 510 17 0.2899022996 ( 7.4482283592 14.0451831818 -1.3778268099 ) - weight 511 22 0.3207769692 ( 7.5863499641 -2.9681777954 -2.8766584396 ) - weight 512 19 0.2638911307 ( 7.5863499641 4.6242690086 -2.6046407223 ) - weight 513 17 0.3516447544 ( 4.4324555397 11.7706518173 -3.207123518 ) - weight 514 22 0.2957075536 ( 4.646009922 -5.6164474487 -4.2751483917 ) - weight 515 19 0.3526476622 ( 4.646009922 1.8633300066 -3.7649517059 ) - weight 516 17 0.3825561702 ( 2.4431176186 6.7495102882 -4.8443131447 ) - weight 517 22 0.2105682194 ( 2.6817200184 -10.8841285706 -4.7679085732 ) - weight 518 19 0.4068756104 ( 2.6817200184 -3.4272749424 -3.7928082943 ) - weight 519 3 0.055075109 ( 0 3.8069038391 -6.6780948639 ) - weight 520 17 0.3843449354 ( -0.2719903886 4.6877841949 -5.8750386238 ) - weight 521 22 0.2254393846 ( 0 -13.1334571838 -5.4265584946 ) - weight 522 19 0.3351406157 ( 0 -5.725789547 -4.2512068748 ) - weight 523 20 0.0661183149 ( -0.9215528965 -6.3773040771 0.1309437752 ) - weight 524 18 0.1023409292 ( 3.1848869324 5.6888656616 -0.8786563873 ) - weight 525 17 0.2209153026 ( 3.5350577831 5.9419093132 6.9579157829 ) - weight 526 22 0.4562958181 ( 3.1031301022 -8.8243560791 6.9246916771 ) - weight 527 19 0.1543296725 ( 3.1031301022 -0.3477668762 7.6734986305 ) - weight 528 17 0.3431998193 ( 4.6049256325 8.4975299835 -3.0309755802 ) - weight 529 22 0.2507736087 ( 4.7631101608 -8.750705719 -3.3072581291 ) - weight 530 19 0.4060266018 ( 4.7631101608 -1.1737266779 -2.5253255367 ) - weight 531 23 0.1313540637 ( -5.5091114044 0.5103373528 -3.2987205982 ) - weight 532 24 0.2480341196 ( 4.400428772 -5.8042726517 -2.5646781921 ) - weight 533 25 0.05254196 ( -6.5305438042 -2.0133810043 -3.6295170784 ) - weight 534 22 0.3339982033 ( 3.2207500935 -0.342376709 -5.4994783401 ) - weight 535 19 0.2340716571 ( 3.2207500935 7.0093784332 -5.4481015205 ) - weight 536 40 0.2472046912 ( -7.6211800575 -5.5548601151 0.4958190918 ) - weight 537 41 0.0523662642 ( 4.2073030472 -6.5815987587 5.3291268349 ) - weight 538 39 0.1309148073 ( 5.0529918671 -3.1389496326 -0.7932350039 ) - weight 539 22 0.4461642802 ( 0.000000071 2.7181434631 -5.2500681877 ) - weight 540 19 0.123349987 ( 0.000000071 10.0799760818 -5.4686574936 ) - weight 541 23 0.1335179359 ( -5.3030104637 0.828121841 -0.3293764591 ) - weight 542 24 0.2521201074 ( 3.6233785152 -5.5476427078 0.3146972656 ) - weight 543 25 0.0534075163 ( -5.8412585258 -3.0487856865 -0.906781137 ) - weight 544 22 0.4550358355 ( 3.9978001118 2.5369987488 -5.2428483963 ) - weight 545 19 0.1059186161 ( 3.9978001118 9.9001665115 -5.4455442429 ) - weight 546 40 0.2496988177 ( -7.6211800575 -5.7879695892 -3.0991706848 ) - weight 547 39 0.1322356611 ( 5.285618782 -2.5747025013 -4.3436999321 ) - weight 548 22 0.3362398744 ( 0 -0.8768463135 -5.4831781387 ) - weight 549 19 0.2818256021 ( 0 6.4784097672 -5.3848876953 ) - weight 550 20 0.0673249289 ( -4.0246829987 -6.7557449341 0.5916337967 ) - weight 551 18 0.114848949 ( 0.0817569122 5.3104248047 -0.4179663658 ) - weight 552 17 0.2249468118 ( 0.4634914398 5.4208831787 7.4860072136 ) - weight 553 22 0.4646228254 ( 0 -9.202796936 7.3853816986 ) - weight 554 19 0.1282564998 ( 0 -0.6842513084 8.1656684875 ) - weight 555 22 1 ( 3.0730001926 5.6761817932 2.9678616524 ) - weight 556 22 1 ( 0.0000001957 5.6761817932 2.9678616524 ) - weight 557 22 1 ( 0 4.7085075378 4.1403317451 ) - weight 558 22 1 ( 1.8106399775 4.7085075378 4.1403317451 ) - weight 559 22 1 ( 0 4.1376609802 4.7094516754 ) - weight 560 22 1 ( 0.0000001957 6.8730201721 -0.7384383678 ) - weight 561 22 1 ( 2.5946102142 6.8730201721 -0.7384383678 ) - weight 562 22 1 ( 0.0000001957 6.8103599548 -1.6510283947 ) - weight 563 22 1 ( 3.6320302486 6.7187461853 1.0049716234 ) - weight 564 22 1 ( 0.0000001957 6.7187461853 1.0049716234 ) - weight 565 25 1 ( -1.1281112432 3.2115557194 3.7636034489 ) - weight 566 25 1 ( 0.5289787054 2.8104121685 4.6490859985 ) - weight 567 25 1 ( 0.9440149665 4.5776171684 3.3953385353 ) - weight 568 24 0.0574692227 ( -2.573381424 -0.8266327381 2.9897003174 ) - weight 569 25 0.7908906341 ( -0.1958264112 0.3835963607 4.011680603 ) - weight 570 22 0.1516401172 ( 10.194560051 5.2120018005 -0.5218383074 ) - weight 571 25 1 ( 1.5515848398 1.3933095932 4.3236718178 ) - weight 572 25 1 ( 2.8664252758 3.5626397133 2.6387221813 ) - weight 573 24 0.1086138338 ( -2.4968614578 2.4482471943 2.5968399048 ) - weight 574 25 0.7952347398 ( 2.9792280197 0.4962151349 3.122084856 ) - weight 575 22 0.0961514935 ( 10.1180400848 4.8191413879 2.7530415058 ) - weight 576 24 0.0748372078 ( -2.7695417404 3.7821571827 0.5155715942 ) - weight 577 25 0.7072091103 ( 4.0689301491 1.9009798765 1.3829661608 ) - weight 578 22 0.2179537117 ( 10.3907203674 2.7378730774 4.0869517326 ) - weight 579 25 1 ( 2.3306992054 2.8398814201 4.0516767502 ) - weight 580 23 0.0554707944 ( -2.1070919037 5.223107338 3.2050299644 ) - weight 581 24 0.2600125968 ( -1.0677509308 -2.0426228046 3.0949783325 ) - weight 582 25 0.2458960116 ( -1.5427999496 -0.8860183954 3.4368944168 ) - weight 583 22 0.4386205673 ( 8.6889295578 5.3172798157 -1.7378282547 ) - weight 584 24 0.2063500881 ( -1.7650518417 1.0242772102 3.6531448364 ) - weight 585 25 0.2027421594 ( 1.6260355711 -0.688880384 3.7879941463 ) - weight 586 22 0.5909077525 ( 9.3862304688 5.8754463196 1.329071641 ) - weight 587 24 0.1246283874 ( 0.3298487663 4.9970273972 0.1645965576 ) - weight 588 25 0.144440949 ( 4.8951306343 -0.443482697 -0.8589529395 ) - weight 589 22 0.730930686 ( 7.2913298607 2.3868980408 5.3018217087 ) - weight 590 24 0.0973157212 ( -1.0908813477 4.5953969955 -1.0204582214 ) - weight 591 25 0.3694535792 ( 4.5043792725 1.4070755243 -0.9419186115 ) - weight 592 22 0.533230722 ( 8.7120599747 1.2018432617 4.9001913071 ) - weight 593 24 0.0684367046 ( -3.2308015823 3.7022070885 -1.284488678 ) - weight 594 25 0.7754676938 ( 3.8181028366 3.3194591999 0.2063726783 ) - weight 595 22 0.1560956091 ( 10.8519802094 0.9378128052 4.0070014 ) - weight 596 23 0.0715175495 ( 3.7325153351 5.5464401245 2.1959314346 ) - weight 597 24 0.2081722021 ( -0.8482513428 3.7949571609 2.0469741821 ) - weight 598 25 0.2271322608 ( 4.0653195381 -0.5519701242 1.5234578848 ) - weight 599 22 0.4931779802 ( 8.4694299698 4.2692756653 4.0997514725 ) - weight 600 25 1 ( -1.5830858946 5.4213819504 3.0982613564 ) - weight 601 25 1 ( -2.5354032516 5.0174221992 2.2540555 ) - weight 602 25 1 ( -2.8744716644 2.8395271301 2.3294734955 ) - weight 603 25 1 ( 0.6960055828 5.6294689178 2.8946013451 ) - weight 604 25 1 ( 0.3887794316 7.8201184273 2.4878771305 ) - weight 605 25 0.8457428217 ( -0.5302638412 4.9140777588 -2.0514688492 ) - weight 606 22 0.1542572081 ( 10.4064798355 -2.339176178 0.0558216572 ) - weight 607 25 0.8852949142 ( -2.0180630684 4.5634789467 -1.4718253613 ) - weight 608 22 0.1147050709 ( 10.2919797897 -1.8515586853 -1.5003182888 ) - weight 609 25 1 ( -0.1746837348 8.9544458389 -1.3604260683 ) - weight 610 25 0.4811653197 ( 2.0119104385 10.9360103607 1.3833312988 ) - weight 611 26 0.5188346505 ( 1.5758523941 -0.3346517384 1.6665326357 ) - weight 612 25 0.5809344053 ( 1.1229199171 11.2448568344 -1.0860222578 ) - weight 613 26 0.4190655649 ( 1.5659102201 -0.1162143722 -0.9670171738 ) - weight 614 26 1 ( 1.2335861921 2.1147413254 -0.9424261451 ) - weight 615 27 0.1508826464 ( 2.0210018158 -1.844409585 2.3317263126 ) - weight 616 26 0.8491173387 ( 0.1231479943 6.5818271637 2.1845672131 ) - weight 617 26 1 ( 1.4200353622 2.7945554256 1.4861675501 ) - weight 618 27 0.1094805077 ( 3.5369489193 -2.0457139015 0.982883811 ) - weight 619 26 0.8905194998 ( 0.8897596598 5.6954011917 0.5158699751 ) - weight 620 26 1 ( 0.9088428617 1.8920631409 2.6011853218 ) - weight 621 26 1 ( -0.9118607044 2.989675045 2.8998944759 ) - weight 622 25 0.541898489 ( 0.9929211736 11.3187875748 2.9085614681 ) - weight 623 26 0.4581014812 ( 0.0195257217 -0.4183622897 2.7067365646 ) - weight 624 25 0.3774873018 ( -0.4308776259 12.0030269623 3.0242240429 ) - weight 625 26 0.6225126386 ( -1.4925814867 -0.2268116623 2.2759184837 ) - weight 626 25 1 ( 2.6583817005 6.5029587746 0.8881762028 ) - weight 627 25 1 ( 2.7868199348 5.6713180542 1.3250441551 ) - weight 628 25 0.8924782276 ( 2.585190773 9.7002668381 -0.2774112523 ) - weight 629 26 0.1075217649 ( 3.0629501343 -1.1862761974 0.3715212941 ) - weight 630 25 0.8474637866 ( 2.2404658794 4.740606308 -1.4746260643 ) - weight 631 22 0.1525362581 ( 10.8875398636 -1.4334869385 2.6993215084 ) - weight 632 25 0.9353270531 ( 1.4971725941 6.1635313034 -1.8803771734 ) - weight 633 22 0.0646729767 ( 11.7384300232 -2.6748580933 2.0088016987 ) - weight 634 25 0.4052144587 ( -0.4975776374 12.2053050995 -1.5309814215 ) - weight 635 26 0.5947855711 ( -0.010299216 0.3214998543 -2.0016343594 ) - weight 636 27 0.0733807161 ( 4.6383261681 -4.6560759544 -1.0713249445 ) - weight 637 26 0.9266192317 ( -0.4621373117 3.699164629 -2.0207047462 ) - weight 638 25 1 ( -2.4871511459 7.3867959976 1.3589299917 ) - weight 639 25 0.9477779269 ( -0.6287089586 8.9377183914 2.4517829418 ) - weight 640 26 0.0522220917 ( -0.4776822627 -3.1411223412 1.7863112688 ) - weight 641 25 0.5390533209 ( -2.2384989262 12.3362436295 1.5473351479 ) - weight 642 26 0.4609467089 ( -2.6674418449 -0.3555003405 0.2356069386 ) - weight 643 25 0.2506759465 ( -2.013669014 13.2717657089 1.5975626707 ) - weight 644 26 0.7493240237 ( -2.7888011932 0.5957955122 0.3282473683 ) - weight 645 27 0.0520080328 ( 2.6772122383 -6.1217055321 2.1589133739 ) - weight 646 26 0.9479919672 ( -2.6467673779 3.3524217606 1.3757107258 ) - weight 647 26 0.7400000095 ( -1.6708077192 10.0989665985 1.9711524248 ) - weight 648 28 0.2599999905 ( -1.7633882761 -1.3015118837 0.0839914158 ) - weight 649 25 0.5885920525 ( -2.5513489246 12.2727108002 0.0184727758 ) - weight 650 26 0.4114079177 ( -2.382848978 -0.3868158162 -1.2997621298 ) - weight 651 25 1 ( -2.1920900345 8.9311103821 -0.2984839976 ) - weight 652 27 0.128326267 ( 3.4402766228 -6.1013822556 -0.8734220862 ) - weight 653 26 0.8716737032 ( -2.3217282295 3.5604324341 -1.7273231745 ) - weight 654 26 0.7400000095 ( 0.0664902031 9.7592115402 -0.0848962963 ) - weight 655 28 0.2599999905 ( 0.4111739695 0.2105418444 -0.5041811466 ) - weight 656 25 0.3038563728 ( -2.3203678131 13.275305748 -0.1001034379 ) - weight 657 26 0.6961435676 ( -2.460883379 0.6438606381 -1.3647696972 ) - weight 658 26 0.5789999962 ( 1.0618783236 9.7277650833 1.246176362 ) - weight 659 28 0.4210000038 ( 0.2444045395 0.4289160073 1.1353436708 ) - weight 660 27 0.169024393 ( 2.130712986 -5.5576424599 0.0014207772 ) - weight 661 26 0.8309755921 ( -2.7265717983 4.639377594 -0.5240203142 ) - weight 662 26 0.7400000095 ( -1.2635630369 10.4844512939 0.1963063478 ) - weight 663 28 0.2599999905 ( -0.9055434465 -0.2293582559 -1.1726366282 ) - weight 664 25 1 ( -3.369143486 4.0614218712 0.0757966414 ) - weight 665 26 0.298999995 ( -1.5468860865 10.8418693542 1.7108075619 ) - weight 666 28 0.7009999752 ( -2.0799090862 -0.6230171919 -0.1889538914 ) - weight 667 26 0.5820000172 ( -1.7567296028 10.4930000305 0.6512708068 ) - weight 668 28 0.417999953 ( -1.3953841925 -0.680929482 -1.0925214291 ) - weight 669 32 0.7909759283 ( 0.2949892282 0.1361899525 -0.7373996377 ) - weight 670 36 0.2090241015 ( -1.5460392237 -1.8526740074 -2.0894150734 ) - weight 671 37 0.3135154545 ( -1.0280950069 -0.0203136262 0.3381706774 ) - weight 672 36 0.6864845753 ( -1.089851737 0.1887056828 -1.1671199799 ) - weight 673 37 0.45128721 ( 0.0226834193 -0.4264033139 -0.3665919006 ) - weight 674 36 0.54871279 ( -0.0390733965 -0.3120560944 -1.8080854416 ) - weight 675 37 0.2882056236 ( 0.0940432847 0.8604723811 -0.0522278585 ) - weight 676 36 0.7117943764 ( 0.0322864652 1.0061577559 -1.6769896746 ) - weight 677 37 0.0534666963 ( 0.7298722863 -1.1541278362 0.5441275239 ) - weight 678 36 0.9465333223 ( 0.668115437 -0.9051055908 -0.8044494987 ) - weight 679 32 1 ( 0.6451454759 -0.7731177211 -0.5759800076 ) - weight 680 27 0.1874251366 ( -0.1376114786 1.1198172569 -1.5411764383 ) - weight 681 26 0.2358868569 ( 0.6571826339 11.0126628876 -0.7357293367 ) - weight 682 36 0.5766880512 ( 0.9595393538 -0.0855754763 -0.0825305805 ) - weight 683 27 0.5593713522 ( -1.4532668591 0.1166912094 -1.3382780552 ) - weight 684 26 0.3634250164 ( -0.9498434067 11.2465028763 -0.3600106537 ) - weight 685 36 0.077203624 ( 1.6067484617 -1.3104338646 0.8444111943 ) - weight 686 32 0.7059418559 ( 0.8465000987 0.250459522 0.4679184854 ) - weight 687 30 0.1873759627 ( -0.5427486897 0.8252126575 -1.710406661 ) - weight 688 29 0.1066821665 ( 0.7308334112 0.5243682265 -1.7465867996 ) - weight 689 33 1 ( -0.0812223479 0.1125101373 -0.6324262023 ) - weight 690 33 1 ( -0.0131214242 0.0726094171 0.1064359546 ) - weight 691 34 1 ( -0.0284271408 0.3011895716 0.6570073962 ) - weight 692 34 1 ( 0.4624316096 0.1478698701 0.7115844488 ) - weight 693 34 1 ( -0.0255939364 0.2522805631 -0.0194271114 ) - weight 694 31 1 ( 0.8165181875 0.7404671311 0.9502924681 ) - weight 695 30 0.5691296458 ( 0.4782723188 0.0119086066 -1.5481082201 ) - weight 696 31 0.4308703542 ( -0.4022612274 1.4891514778 1.5145189762 ) - weight 697 31 1 ( 0.1817143112 -0.3798622191 1.3266962767 ) - weight 698 26 0.7400000095 ( -2.0552022457 11.441034317 0.5284511447 ) - weight 699 28 0.2599999905 ( -2.1376266479 -0.1743840724 -1.5345944166 ) - weight 700 30 0.0996929035 ( -0.5549507141 1.5070507526 1.0541734695 ) - weight 701 29 0.9003071189 ( 0.1234919131 0.8782093525 1.0127407312 ) - weight 702 31 1 ( -0.0507001281 0.3559434414 -0.7049387097 ) - weight 703 31 1 ( 0.4892955422 -0.4047851264 0.4593759477 ) - weight 704 31 1 ( -0.1271226704 1.167527914 -1.0043309927 ) - weight 705 30 0.548068881 ( -0.2113553584 -0.1583049893 0.9382539392 ) - weight 706 29 0.0776808113 ( 1.5287079811 -0.0814251527 0.9159198999 ) - weight 707 31 0.3742503226 ( -0.4373892546 2.1986055374 -0.9718433022 ) - weight 708 30 0.793235898 ( -0.2212827653 -0.8240890503 -1.2981902361 ) - weight 709 31 0.206764102 ( 0.1974636018 2.3994259834 1.264600873 ) - weight 710 30 0.2869230807 ( -1.2372074127 0.7181710601 1.0668632984 ) - weight 711 29 0.7130769491 ( 0.1772198081 -0.1629114598 0.9788705111 ) - weight 712 30 0.2508835793 ( 0.2620891035 0.6701579094 0.7437081337 ) - weight 713 29 0.5495494604 ( 1.3054817915 0.8526678681 0.754709661 ) - weight 714 31 0.1995669752 ( -1.0948694944 1.507070899 -0.7772974372 ) - weight 715 33 1 ( -0.2894859016 -0.7095484734 -0.5602113008 ) - weight 716 26 0.2790000141 ( 0.5210154653 10.6474914551 1.928660512 ) - weight 717 28 0.7209999561 ( -1.017449975 0.5141332746 1.2037159204 ) - weight 718 30 0.2420762479 ( -1.5637950897 0.117332615 -1.3481564522 ) - weight 719 29 0.7579237819 ( 0.4683932662 -0.7085962892 -1.4537067413 ) - weight 720 37 1 ( -0.7627375722 -0.233167246 -1.3213231564 ) - weight 721 37 1 ( -0.8650085926 0.5942379236 -1.5316550732 ) - weight 722 38 1 ( -0.7719288468 0.2829086781 -1.1071960926 ) - weight 723 37 0.3279237747 ( -0.7507029176 0.828178525 0.0204612371 ) - weight 724 36 0.6720762253 ( -0.8124597073 0.9843589664 -1.6004951 ) - weight 725 37 1 ( 0.0251329783 0.7574108839 -1.5798853636 ) - weight 726 38 1 ( -0.2955265641 -0.2460772097 -0.8015696406 ) - weight 727 37 1 ( 0.1937542409 -0.0740830749 -1.4368978739 ) - weight 728 38 1 ( -0.1471066028 0.2768458724 -1.1136438847 ) - weight 729 27 0.179741621 ( 0.7252705097 1.6872566938 -0.0471936092 ) - weight 730 26 0.1084745452 ( 1.7484762669 10.4028348923 0.5817400813 ) - weight 731 36 0.6378537416 ( -0.5353118777 0.7383086681 0.5380918384 ) - weight 732 28 0.0739300773 ( 0.4673574865 1.5471144915 0.8735522032 ) - weight 733 27 0.1446991563 ( 0.7226153016 1.3290280104 -1.0934616327 ) - weight 734 26 0.2423756719 ( 1.4118485451 10.4254341125 -0.4714372456 ) - weight 735 36 0.6129251719 ( 0.4506123364 0.7575109601 0.0374959297 ) - weight 736 33 1 ( -0.2541444004 -0.7150674462 0.2067667991 ) - weight 737 34 1 ( 0.4836007059 0.1213574037 0.0087616835 ) - weight 738 32 1 ( 0.4752412438 -0.8855237365 0.2668460608 ) - weight 739 34 1 ( 0.5341833234 1.2931745052 0.2087971568 ) - weight 740 26 0.6650000215 ( 0.2329693288 9.561000824 2.1057262421 ) - weight 741 28 0.3349999785 ( -0.5027853251 -0.485471189 1.3789211512 ) - weight 742 25 1 ( 3.2354946136 5.0531058311 0.0221791249 ) - weight 743 25 0.7295026779 ( 2.6004126072 3.8817636967 -1.3587388992 ) - weight 744 22 0.2704973221 ( 10.2911701202 -0.7991676331 3.049441576 ) - weight 745 22 1 ( 5.149720192 5.3225593567 7.448571682 ) - weight 746 24 0.0878749788 ( -1.6015615463 1.6416671276 4.7487335205 ) - weight 747 25 0.083104074 ( 2.3523433208 -1.4656430483 4.4788856506 ) - weight 748 22 0.8290209174 ( 9.2227401733 6.9710350037 1.9464615583 ) - weight 749 25 0.3092687428 ( 0.8927694559 4.5938763618 -4.1910834312 ) - weight 750 22 0.5065450072 ( 9.0798397064 -3.7049980164 1.810831666 ) - weight 751 19 0.1841862947 ( 9.0798397064 4.3023018837 2.1294701099 ) - weight 752 20 0.341480881 ( 4.8387365341 -1.2602272034 -7.5999865532 ) - weight 753 22 0.3810738027 ( 8.8634195328 -3.7072792053 -0.8062384129 ) - weight 754 19 0.2774453163 ( 8.8634195328 4.0700054169 -0.4772709608 ) - weight 755 17 0.302408725 ( -0.2472007573 9.0744123459 -4.3418579102 ) - weight 756 22 0.2587559521 ( 0 -8.5066566467 -4.9947285652 ) - weight 757 19 0.4388353229 ( 0 -1.0789402723 -4.2277154922 ) - weight 758 17 0.3154180646 ( 2.5873289108 9.1581516266 -4.0424132347 ) - weight 759 22 0.269887358 ( 2.814330101 -8.3532371521 -4.5620083809 ) - weight 760 19 0.4146945775 ( 2.814330101 -0.8880811334 -3.8101546764 ) - weight 761 17 0.3492805064 ( -0.258138299 6.834499836 -5.0939035416 ) - weight 762 22 0.2048721761 ( 0 -10.8617782593 -5.1852583885 ) - weight 763 19 0.4458473325 ( 0 -3.4416937828 -4.2105073929 ) - weight 764 17 0.2977738082 ( 2.2074844837 12.3575124741 -3.874904871 ) - weight 765 22 0.3386747539 ( 2.4700300694 -5.2077674866 -5.191078186 ) - weight 766 19 0.3635514379 ( 2.4700300694 2.1899237633 -4.7132573128 ) - weight 767 17 0.2836880684 ( -0.2740236819 12.61145401 -3.9444284439 ) - weight 768 22 0.3226542175 ( 0 -4.9780578613 -5.4619784355 ) - weight 769 19 0.3936577737 ( 0 2.394933939 -5.0032992363 ) - weight 770 23 0.1009265333 ( -3.6426856518 2.8528060913 1.8553417921 ) - weight 771 24 0.2933551073 ( 1.3849086761 -3.7395424843 2.1447372437 ) - weight 772 25 0.1412155479 ( -3.5945601463 -2.3100340366 1.5499675274 ) - weight 773 22 0.4645028114 ( 6.2362699509 4.3670387268 -3.4347481728 ) - weight 774 24 0.2322865874 ( -0.7717113495 -3.9490230083 0.4720993042 ) - weight 775 25 0.512103498 ( -3.7773423195 0.4196757972 1.4611719847 ) - weight 776 22 0.2556099892 ( 8.3928899765 2.6944007874 -3.6442284584 ) - weight 777 22 1 ( 4.2365198135 7.6505012512 -5.7434782982 ) - weight 778 22 1 ( 2.4068701267 7.4192390442 -5.9572482109 ) - weight 779 25 0.4340919256 ( 2.932071209 2.2319264412 -2.7768473625 ) - weight 780 22 0.5659080744 ( 8.1742696762 -0.9481163025 3.6321415901 ) - weight 781 24 0.1136212125 ( -1.3156118393 -3.2669928074 -2.1217079163 ) - weight 782 25 0.7095959783 ( -3.3649554253 2.3524487019 -0.4317503572 ) - weight 783 22 0.1767828166 ( 8.9367904663 0.1005935669 -2.9621982574 ) - weight 784 24 0.1517526507 ( -1.0405216217 -1.6369827986 -3.4798698425 ) - weight 785 25 0.4663812518 ( -1.9525446892 2.887526989 -1.9470053911 ) - weight 786 22 0.2398799211 ( 8.6617002487 -1.2575683594 -1.3321883678 ) - weight 787 19 0.1419861317 ( 8.6617002487 6.4640078545 -1.2164998055 ) - weight 788 20 0.0681705624 ( 5.1309671402 0.7870140076 -5.8339962959 ) - weight 789 25 0.5091480017 ( 0.3120762408 3.4866728783 -2.3610994816 ) - weight 790 22 0.3169594109 ( 9.1556501389 -1.6600379944 0.959751606 ) - weight 791 19 0.1057220027 ( 9.1556501389 6.2645430565 1.101944685 ) - weight 792 23 0.1327841133 ( -4.7697796822 3.3715770245 -0.7298592925 ) - weight 793 24 0.2621071935 ( 1.2170286179 -4.8581528664 -0.4902687073 ) - weight 794 25 0.2119719684 ( -5.0039429665 -0.6314677 -0.2990279496 ) - weight 795 22 0.3082503676 ( 6.4041500092 1.7320327759 -4.5533585548 ) - weight 796 19 0.0848862678 ( 6.4041500092 9.1589174271 -4.6879711151 ) - weight 797 22 1 ( 0.0000001957 7.3696784973 -5.0027384758 ) - weight 798 23 0.1241197512 ( -4.1481900215 4.4266061783 -2.1865730286 ) - weight 799 24 0.2450042963 ( 0.4520988464 -4.1859526634 -2.09790802 ) - weight 800 25 0.3763213754 ( -4.4567022324 0.9114508033 -1.269288063 ) - weight 801 22 0.1927692145 ( 7.1690797806 0.1243934631 -3.8811583519 ) - weight 802 19 0.0617853254 ( 7.1690797806 7.6165823936 -3.8770709038 ) - weight 803 24 0.1269659251 ( -0.2150216103 -3.6572029591 -3.1073379517 ) - weight 804 25 0.3796184063 ( -3.9879703522 2.0309309959 -1.7895088196 ) - weight 805 22 0.3577547967 ( 7.8362002373 -0.8850364685 -3.3524084091 ) - weight 806 19 0.1356608868 ( 7.8362002373 6.6575331688 -3.2616446018 ) - weight 807 23 0.0997047126 ( -5.1769123077 2.8848717213 3.1039326191 ) - weight 808 24 0.2326328158 ( 1.0538988113 -5.2556128502 3.3718566895 ) - weight 809 22 0.6676625013 ( 6.5672798157 5.5941581726 -4.9508185387 ) - weight 810 24 0.1075652987 ( 1.3275485039 -5.7862925529 5.2486038208 ) - weight 811 22 0.8924347162 ( 6.2936301231 7.470905304 -5.4814982414 ) - weight 812 22 1 ( 1.0997800827 1.7325439453 8.7468214035 ) - weight 813 22 1 ( 0.000000071 1.6961708069 8.8199119568 ) - weight 814 3 0.2389344126 ( 6.7000699043 3.4666023254 4.1606354713 ) - weight 815 18 0.1017972678 ( 6.781826973 1.0394630432 -2.3911762238 ) - weight 816 17 0.4301412404 ( 7.0392384529 1.8430429697 4.1717619896 ) - weight 817 22 0.0612391159 ( 6.7000699043 -13.4737586975 5.4121718407 ) - weight 818 4 0.0995619521 ( 2.6297023296 -4.5899138451 3.7830412388 ) - weight 819 19 0.0683260784 ( 6.7000699043 -5.1121168137 6.5754861832 ) - weight 820 3 0.2851259112 ( 4.9098901749 3.2377624512 5.3748550415 ) - weight 821 18 0.1547364146 ( 4.9916472435 0.8106231689 -1.1769566536 ) - weight 822 17 0.3558102846 ( 5.3217144012 1.304117322 5.3928723335 ) - weight 823 22 0.0550546609 ( 4.9098901749 -13.7025985718 6.6263914108 ) - weight 824 4 0.0823570341 ( 4.3991756439 -4.5855789185 2.517977953 ) - weight 825 19 0.0669156983 ( 4.9098901749 -5.2333488464 7.8051204681 ) - weight 826 3 0.1532056183 ( 8.3290700912 3.938873291 -5.1523947716 ) - weight 827 17 0.4891270399 ( 8.1309289932 4.5640769005 -4.8289823532 ) - weight 828 22 0.0722299665 ( 8.3290700912 -13.0014877319 -3.9008584023 ) - weight 829 4 0.1211145595 ( -6.6530399323 -5.4221568108 2.1255486012 ) - weight 830 19 0.1643228829 ( 8.3290700912 -5.4602313042 -2.7430109978 ) - weight 831 20 0.0899846256 ( 5.0327968597 -10.0838050842 -7.2081561089 ) - weight 832 3 0.1501714587 ( 9.0574798584 4.4095039368 -1.6659448147 ) - weight 833 17 0.4465884566 ( 9.0582799911 4.1922917366 -1.3780111074 ) - weight 834 22 0.077391997 ( 9.0574798584 -12.5308570862 -0.4144083261 ) - weight 835 4 0.0741098821 ( -3.6499845982 -5.5191884041 4.0952315331 ) - weight 836 19 0.1617535055 ( 9.0574798584 -4.684984684 0.6885805726 ) - weight 837 3 0.205977872 ( 9.7783403397 2.6523742676 -2.0264546871 ) - weight 838 17 0.5380318761 ( 9.7572565079 2.5836122036 -2.1908423901 ) - weight 839 4 0.1332240999 ( -4.2506599426 -3.6942601204 4.3095602989 ) - weight 840 19 0.1227661818 ( 9.7783403397 -6.4670004845 0.4839066565 ) - weight 841 20 0.09038122 ( 4.7781772614 -10.6103057861 -5.9079461098 ) - weight 842 3 0.1670063883 ( 8.80286026 3.8830032349 -0.3657348454 ) - weight 843 18 0.0519815497 ( 8.8846168518 1.4558639526 -6.9175462723 ) - weight 844 17 0.4485567212 ( 8.8787202835 3.3650286198 -0.2308519781 ) - weight 845 22 0.0554484874 ( 8.80286026 -13.0573577881 0.8858016133 ) - weight 846 4 0.0744365007 ( -2.3463995457 -4.9549059868 4.2170166969 ) - weight 847 19 0.1121891588 ( 8.80286026 -5.0951676369 2.0300347805 ) - weight 848 3 0.2443084568 ( 9.6978797913 1.7875518799 -0.7430948019 ) - weight 849 17 0.4512748122 ( 9.7506008148 1.4344559908 -1.1512269974 ) - weight 850 4 0.2439872175 ( -3.0261387825 -2.7689397335 4.5234179497 ) - weight 851 19 0.0604295246 ( 9.6978797913 -7.2156767845 1.8383123875 ) - weight 852 3 0.1979503036 ( 8.1422700882 1.0664329529 -5.3806447983 ) - weight 853 17 0.476829946 ( 7.9313340187 1.8285751343 -5.7318100929 ) - weight 854 4 0.2352806479 ( -6.8129005432 -2.6462631226 1.3465969563 ) - weight 855 19 0.089939177 ( 8.1422700882 -8.3416166306 -2.7179079056 ) - weight 856 5 0.6677125096 ( -3.7182207108 0.6958633661 3.0973136425 ) - weight 857 4 0.3322874904 ( -6.1764717102 19.8569965363 -4.9052596092 ) - weight 858 5 0.5231878757 ( -1.0564134121 0.7334514856 4.9299936295 ) - weight 859 4 0.4768120944 ( -7.5396575928 20.0044517517 -1.9786010981 ) - weight 860 5 0.3629415035 ( 1.7129393816 -0.3118667603 4.119383812 ) - weight 861 4 0.6370584965 ( -6.1054859161 19.6154556274 0.7067158818 ) - weight 862 5 0.6341163516 ( 2.3046956062 1.7164517641 2.864771843 ) - weight 863 4 0.3658836484 ( -5.2360067368 21.9127807617 0.7745708227 ) - weight 864 3 0.1321325004 ( 0 2.2104225159 -9.5075950623 ) - weight 865 17 0.4308211207 ( -0.4344205558 3.8189380169 -9.0013055801 ) - weight 866 4 0.1932267398 ( -7.7764625549 -5.4427905083 -7.3647732735 ) - weight 867 19 0.2438196838 ( 0 -7.5647878647 -6.9294352531 ) - weight 868 3 0.1128543392 ( 3.2787399292 2.754032135 -7.8051748276 ) - weight 869 17 0.5744569898 ( 2.9366414547 3.9823844433 -7.4034609795 ) - weight 870 22 0.0647919625 ( 3.2787399292 -14.1863288879 -6.5536384583 ) - weight 871 19 0.247896716 ( 3.2787399292 -6.873650074 -5.2813839912 ) - weight 872 3 0.157916829 ( 7.0973801613 3.7977333069 -7.1476049423 ) - weight 873 17 0.5533049703 ( 6.7867331505 4.8899846077 -6.727604866 ) - weight 874 4 0.114159368 ( -8.0818662643 -5.6313443184 0.2728367746 ) - weight 875 19 0.17461887 ( 7.0973801613 -5.7761917114 -4.7180938721 ) - weight 876 3 0.2760950029 ( 8.8229598999 0.9508743286 1.9491151571 ) - weight 877 18 0.0683797151 ( 8.9047164917 -1.4762649536 -4.6026964188 ) - weight 878 17 0.3746005893 ( 9.0316734314 -0.0372558683 1.3045245409 ) - weight 879 4 0.2809247375 ( -0.2024161667 -1.9089030027 4.5025238991 ) - weight 880 3 0.2091378719 ( 8.3410196304 3.8580245972 2.0640451908 ) - weight 881 18 0.0578273162 ( 8.4227762222 1.4308853149 -4.4877662659 ) - weight 882 17 0.3407049477 ( 8.5571250916 2.7499418259 2.1431734562 ) - weight 883 22 0.0526651032 ( 8.3410196304 -13.0823364258 3.3155815601 ) - weight 884 4 0.2564763725 ( 0.0889864638 -4.8406071663 4.6336488724 ) - weight 885 19 0.0831884593 ( 8.3410196304 -4.9064865112 4.452606678 ) - weight 886 3 0.2438114583 ( 8.2908096313 0.0431938171 -2.8124547005 ) - weight 887 17 0.3629753292 ( 8.227057457 0.2197847962 -3.498197794 ) - weight 888 4 0.3932131827 ( -4.4691700935 -1.4372130632 2.1890985966 ) - weight 889 5 0.2857022882 ( 3.1747083664 -4.0142126083 -1.9667092562 ) - weight 890 4 0.7142977715 ( 0.7813677788 17.4170837402 1.4960614443 ) - weight 891 5 0.2749372125 ( -0.9259396195 -1.0953246355 5.7573385239 ) - weight 892 4 0.7250627875 ( -7.9275612831 18.1028022766 -1.4502040148 ) - weight 893 3 0.0556513965 ( 4.4196300507 -17.8060760498 -6.3857645988 ) - weight 894 5 0.0745863691 ( -5.5242152214 -3.6030664444 4.108581543 ) - weight 895 4 0.8697622418 ( -6.5153102875 15.2014007568 -5.893032074 ) - weight 896 5 0.5737704039 ( -2.4618759155 0.3726374805 -1.9331029654 ) - weight 897 4 0.4262295961 ( -1.0603154898 20.6963806152 -4.5760941505 ) - weight 898 5 1 ( -1.24911201 11.5237121582 4.1516447067 ) - weight 899 5 1 ( -0.0998372883 14.6091995239 2.2291593552 ) - weight 900 5 1 ( -2.3712365627 15.5987167358 1.9076052904 ) - weight 901 5 1 ( -2.3610329628 14.4957351685 -0.3921383917 ) - weight 902 5 1 ( -2.0443096161 13.9897861481 -2.4450483322 ) - weight 903 5 1 ( 2.1512875557 14.2766017914 1.9873234034 ) - weight 904 5 1 ( -1.0440961123 4.255177021 5.5432019234 ) - weight 905 5 1 ( 0.9681818485 4.0952515602 4.7074446678 ) - weight 906 5 1 ( 0.1401751637 9.1353540421 5.2270798683 ) - weight 907 5 1 ( -4.3292503357 12.6982507706 0.3159910738 ) - weight 908 5 1 ( -1.5782091618 13.1344013214 -2.657720089 ) - weight 909 7 0.5249263048 ( 1.2609685659 6.9606413841 1.9680178165 ) - weight 910 8 0.4750737548 ( 1.2200421095 1.9226528406 1.9614708424 ) - weight 911 3 0.1840003878 ( 6.9930300713 0.7581634521 -7.7029747963 ) - weight 912 17 0.5841546655 ( 6.6506733894 2.0721018314 -7.9922533035 ) - weight 913 4 0.120524399 ( -8.5775527954 -2.6998000145 -0.5748957992 ) - weight 914 19 0.111320518 ( 6.9930300713 -8.8528118134 -5.004155159 ) - weight 915 3 0.1622728109 ( 4.1420898438 -4.9105262756 -6.0743045807 ) - weight 916 17 0.0862264261 ( 3.8979299068 -3.8607840538 -7.6211209297 ) - weight 917 4 0.7515007854 ( -6.0683279037 2.4998624325 -3.6703393459 ) - weight 918 24 0.0791042745 ( -2.4411916733 -2.8426129818 1.5174942017 ) - weight 919 25 0.7689301968 ( -2.3798243999 1.1592524052 3.0749032497 ) - weight 920 22 0.1519655436 ( 10.0623703003 3.7397956848 -2.5378184319 ) - weight 921 24 0.0786700621 ( -2.0081110001 -3.7371928692 0.0158462524 ) - weight 922 25 0.8028289676 ( -3.4929041862 1.6886470318 1.7620539665 ) - weight 923 22 0.1185009629 ( 9.6292896271 2.2381477356 -3.4323983192 ) - weight 924 5 1 ( -2.7618734837 17.2124633789 2.1291768551 ) - weight 925 5 0.4522682428 ( 3.5603883266 -0.7084299326 1.7904951572 ) - weight 926 4 0.5477317572 ( -3.4880070686 19.9805335999 2.1243109703 ) - weight 927 5 0.5447970033 ( -0.6668633223 -1.1521900892 -3.370871067 ) - weight 928 4 0.4552030265 ( 0.9300144315 19.7946014404 -2.8909451962 ) - weight 929 3 0.2965093255 ( -2.9546298981 3.4700737 5.5409750938 ) - weight 930 18 0.1987032741 ( -2.8728730679 1.0429344177 -1.0108366013 ) - weight 931 10 0.0641049966 ( -5.249712944 -5.134706974 0.8228775263 ) - weight 932 17 0.2874504924 ( -2.5203003883 1.3808511496 6.0479755402 ) - weight 933 22 0.0892368034 ( -2.9546298981 -13.470287323 6.7925114632 ) - weight 934 19 0.0639951378 ( -2.9546298981 -4.9873356819 7.9501786232 ) - weight 935 3 0.2993961275 ( -2.698390007 -3.0038146973 5.225025177 ) - weight 936 18 0.1550484151 ( -2.6166331768 -5.4309539795 -1.3267865181 ) - weight 937 10 0.3255570233 ( -5.0163850784 1.1635314226 -0.7115487456 ) - weight 938 17 0.2199983895 ( -2.28262043 -4.8227806091 4.1677694321 ) - weight 939 3 0.4058933854 ( -1.9773199558 -3.0314559937 6.2920651436 ) - weight 940 18 0.1903107464 ( -1.8955630064 -5.4585952759 -0.2597465515 ) - weight 941 10 0.1932321787 ( -6.2698745728 1.1420885324 -1.0074959993 ) - weight 942 17 0.2105636597 ( -1.5014849901 -5.0962986946 5.1548333168 ) - weight 943 3 0.3426049352 ( -1.9608099461 -4.3739852905 5.1643152237 ) - weight 944 18 0.1170412377 ( -1.8790529966 -6.8011245728 -1.3874964714 ) - weight 945 10 0.3136270344 ( -5.2155766487 2.380730629 -1.6622464657 ) - weight 946 17 0.2267267704 ( -1.549741745 -6.1277828217 3.7377271652 ) - weight 947 3 0.4035560191 ( -2.1414299011 2.9136734009 6.6546053886 ) - weight 948 18 0.2582558692 ( -2.0596730709 0.4865341187 0.1027936935 ) - weight 949 10 0.0549555458 ( -6.5771160126 -4.6488246918 0.3613930345 ) - weight 950 17 0.2200717628 ( -1.6445122957 0.5842180848 6.9476528168 ) - weight 951 19 0.0631608218 ( -2.1414299011 -5.4437012672 9.1084032059 ) - weight 952 10 0.4708346725 ( -1.5093013048 20.8126716614 2.042091608 ) - weight 953 17 0.0628809556 ( -9.4447813034 -22.9618015289 -0.8968416452 ) - weight 954 11 0.4662843645 ( -4.3815193176 -1.0027827024 -3.2022976875 ) - weight 955 10 0.1838563681 ( 1.5548534393 23.9484272003 1.4603344202 ) - weight 956 11 0.8161436319 ( -3.880240202 2.7648758888 -0.9409000874 ) - weight 957 10 0.1727412343 ( -0.4795318544 23.9047279358 -0.9085543156 ) - weight 958 11 0.8272587657 ( -1.8777322769 2.608553648 -3.3320906162 ) - weight 959 10 0.4818214178 ( 0.0598451495 20.7609176636 3.2868709564 ) - weight 960 11 0.5181785822 ( -5.3446035385 -0.8859782219 -1.4492431879 ) - weight 961 10 0.4756912291 ( 1.1738376617 20.7265472412 3.236243248 ) - weight 962 17 0.0574238077 ( -11.5981988907 -22.2020683289 -2.7456915379 ) - weight 963 11 0.4668849707 ( -5.11916399 -0.6741610765 -0.3773130774 ) - weight 964 10 0.6135464311 ( -1.7681889534 18.1308841705 2.0222551823 ) - weight 965 11 0.3864535093 ( -3.9455213547 -3.6498908997 -2.9530375004 ) - weight 966 10 0.6719331741 ( -0.173824504 18.3133964539 3.3275754452 ) - weight 967 11 0.3280668557 ( -5.0035438538 -3.3092594147 -1.2084087133 ) - weight 968 10 0.6093488932 ( 1.2613629103 17.9256362915 2.4596066475 ) - weight 969 11 0.3906511068 ( -3.8732025623 -3.2598958015 0.0890441537 ) - weight 970 10 0.2512077391 ( 3.3782281876 22.107421875 1.888420701 ) - weight 971 11 0.7487922907 ( -3.7050015926 1.3157271147 1.2423360348 ) - weight 972 11 1 ( 1.2312787771 10.4317131042 4.1737194061 ) - weight 973 11 1 ( 4.2555155754 7.5298061371 3.8783018589 ) - weight 974 11 1 ( 3.3124060631 11.4796772003 2.9515733719 ) - weight 975 11 1 ( -3.1497242451 5.5408396721 -0.4473823309 ) - weight 976 10 0.0636916757 ( 0.6505047083 26.3574142456 -1.3775171041 ) - weight 977 11 0.9363083243 ( -1.6657303572 5.286532402 -2.7879683971 ) - weight 978 10 0.0735955834 ( 5.0766544342 24.4501342773 0.4745018482 ) - weight 979 11 0.9264044166 ( -2.4674892426 4.1368904114 2.1813373566 ) - weight 980 11 1 ( -2.2799363136 7.6838026047 2.8447155952 ) - weight 981 11 1 ( -3.4111392498 8.4378509521 -0.2069736272 ) - weight 982 11 1 ( -2.7114899158 9.0197753906 -2.3900315762 ) - weight 983 11 1 ( -2.2004950047 6.9054961205 4.421207428 ) - weight 984 11 1 ( -2.7330610752 10.329656601 -0.7584182024 ) - weight 985 11 1 ( -0.7630344629 11.2303962708 3.2724034786 ) - weight 986 11 1 ( -2.1962304115 11.7751741409 1.822665453 ) - weight 987 11 1 ( -1.016492486 10.2338762283 -2.6014137268 ) - weight 988 11 1 ( -2.8805916309 12.3335132599 -0.7640658021 ) - weight 989 11 1 ( -1.1593395472 12.0751647949 -2.9110856056 ) - weight 990 12 0.0678309724 ( 1.1944760084 0.9708321095 4.6517863274 ) - weight 991 11 0.9321690202 ( -4.1605558395 15.8164367676 0.5340311527 ) - weight 992 12 0.1074483991 ( -1.5896538496 1.4492480755 5.9872655869 ) - weight 993 11 0.8925516009 ( -4.2204241753 14.0482912064 -2.0415935516 ) - weight 994 12 0.3582289219 ( -0.5298726559 1.5100711584 4.4805598259 ) - weight 995 11 0.6417710781 ( -3.6950068474 15.6054983139 -1.2073030472 ) - weight 996 11 1 ( 2.1376123428 6.639298439 5.8554105759 ) - weight 997 11 1 ( 3.8028049469 4.8323273659 3.6544427872 ) - weight 998 14 0.475073725 ( 0.5472323895 0.677249372 3.7235510349 ) - weight 999 13 0.5249262452 ( 0.5293371677 5.7498178482 3.7259202003 ) - weight 1000 14 0.0571241342 ( 2.4577975273 -1.4290678501 2.7518808842 ) - weight 1001 12 0.4873141348 ( 1.0413523912 6.3577518463 4.9804410934 ) - weight 1002 13 0.3494953811 ( 2.4943253994 3.6975519657 2.7471454144 ) - weight 1003 11 0.1060663685 ( -7.739484787 18.4536533356 -2.5297439098 ) - weight 1004 14 0.4988742769 ( 2.7174572945 0.64995116 0.3420408964 ) - weight 1005 13 0.5011256933 ( 2.6995339394 5.7909731865 0.3445320725 ) - weight 1006 14 0.0571989305 ( 0.5740651488 -2.5932562351 3.7770707607 ) - weight 1007 12 0.4879522324 ( -0.6271808743 4.6461119652 4.489440918 ) - weight 1008 13 0.3499529958 ( 0.6416787505 2.4809663296 3.7681331635 ) - weight 1009 11 0.1048958525 ( -5.6551399231 17.2751140594 -3.0002219677 ) - weight 1010 14 0.0571241342 ( 2.5142014027 -4.233792305 2.1220607758 ) - weight 1011 12 0.4873141348 ( 1.9298291206 4.6316509247 2.8597061634 ) - weight 1012 13 0.3494953811 ( 2.6240487099 0.897456944 2.1076357365 ) - weight 1013 11 0.1060663685 ( -5.6049151421 19.4345245361 -0.8720831275 ) - weight 1014 12 0.4677073956 ( 2.7431559563 3.83897686 -0.9621880054 ) - weight 1015 13 0.3791610003 ( 2.2633793354 -2.1904680729 -0.3886306286 ) - weight 1016 11 0.1531316042 ( -2.9137957096 22.177936554 0.1901177913 ) - weight 1017 14 0.0537899137 ( 3.2337932587 -3.4404683113 -0.6967390776 ) - weight 1018 12 0.4661476612 ( 2.902520895 7.1096286774 1.4432651997 ) - weight 1019 13 0.4800624251 ( 3.3226504326 1.7190710306 -0.7083392143 ) - weight 1020 12 0.6878799796 ( 2.8440265656 2.474501133 0.1892532408 ) - weight 1021 11 0.3121200204 ( -2.8449180126 20.6033401489 1.0349186659 ) - weight 1022 11 1 ( -2.3688387871 16.8456001282 0.3506837487 ) - weight 1023 12 0.5006880164 ( 3.0892980099 -2.0217015743 -1.313777566 ) - weight 1024 11 0.4993120134 ( 0.9035217166 19.3703327179 3.67385602 ) - weight 1025 12 0.416490972 ( 3.9635634422 0.6949004531 -3.9929871559 ) - weight 1026 13 0.1837866157 ( 2.3550980091 -6.6992425919 -0.8607496023 ) - weight 1027 11 0.3997223675 ( 0.5872045755 23.1918334961 2.8874061108 ) - weight 1028 12 0.416490972 ( 4.0690231323 2.5323865414 -3.0569455624 ) - weight 1029 13 0.1837866157 ( 2.8476109505 -4.7555894852 -1.3539993763 ) - weight 1030 11 0.3997223675 ( -1.2394555807 23.5291538239 1.9856418371 ) - weight 1031 12 0.4677073956 ( 3.658539772 4.1497044563 -1.5019230843 ) - weight 1032 13 0.3791610003 ( 3.0071241856 -2.4892652035 -1.1524088383 ) - weight 1033 11 0.1531316042 ( -3.1253890991 23.0905570984 0.7801562548 ) - weight 1034 12 0.3806169331 ( -3.562721014 1.3644057512 3.0446231365 ) - weight 1035 11 0.6193830371 ( -1.4338343143 15.4914093018 -3.6883075237 ) - weight 1036 14 0.0512947254 ( 1.0218013525 -2.7407681942 4.7337708473 ) - weight 1037 12 0.4375846684 ( -0.3313719928 3.9590725899 5.2496886253 ) - weight 1038 13 0.3138300478 ( 1.0931190252 2.3419041634 4.724357605 ) - weight 1039 11 0.1972905248 ( -5.8380832672 16.4365386963 -2.3671159744 ) - weight 1040 12 0.4865542054 ( -4.5309562683 3.5796954632 3.1936845779 ) - weight 1041 13 0.2687388957 ( -3.5328960419 1.7962034941 4.1677775383 ) - weight 1042 11 0.2447068244 ( -2.5495610237 16.2324943542 -5.706512928 ) - weight 1043 12 0.5271217823 ( -3.7806372643 4.4679136276 2.9948658943 ) - weight 1044 13 0.2911455631 ( -2.8106846809 2.1824257374 3.3188474178 ) - weight 1045 11 0.1817326397 ( -3.2860379219 17.1430454254 -5.5653166771 ) - weight 1046 14 0.3067108989 ( -3.0285704136 0.4912771583 3.3243908882 ) - weight 1047 12 0.1096295714 ( -4.767261982 6.9663300514 4.907251358 ) - weight 1048 13 0.5836595297 ( -3.0403802395 5.4717907906 3.3257958889 ) - weight 1049 14 0.495306462 ( -4.5137066841 -0.007489481 -0.9106391072 ) - weight 1050 13 0.5046935081 ( -4.5119667053 4.9490132332 -0.9110678434 ) - weight 1051 14 0.475073725 ( -1.0229164362 2.0798943043 0.3028608561 ) - weight 1052 13 0.5249262452 ( -1.0769515038 7.1227507591 0.3099585474 ) - weight 1053 12 0.4213652015 ( -0.01491985 0.3573600352 -5.7071423531 ) - weight 1054 13 0.1678375602 ( -1.9595971107 -7.0594005585 -1.2271976471 ) - weight 1055 11 0.4107972682 ( 3.5349497795 22.8346176147 -0.284941107 ) - weight 1056 11 1 ( 0.7006198168 18.5352840424 3.1299064159 ) - weight 1057 12 0.240669325 ( 0.8959159851 -2.4775252342 -2.1954813004 ) - weight 1058 11 0.7593306899 ( 2.6584336758 18.9784641266 2.0729734898 ) - weight 1059 12 0.4815303087 ( -0.9716356993 2.3917098045 -5.3716802597 ) - weight 1060 13 0.3638229072 ( -2.6398720741 -5.0778708458 -2.1087787151 ) - weight 1061 11 0.1546468437 ( 2.4069194794 23.340839386 -2.1922183037 ) - weight 1062 12 0.4815303087 ( -1.7307209969 3.6215064526 -3.1006252766 ) - weight 1063 13 0.3638229072 ( -2.6372582912 -2.5977761745 -1.0621535778 ) - weight 1064 11 0.1546468437 ( 0.4367134869 22.0234508514 -3.4685707092 ) - weight 1065 12 0.4815303087 ( -1.9638375044 3.9008951187 -4.0903954506 ) - weight 1066 13 0.3638229072 ( -3.1218242645 -2.9230651855 -1.9404640198 ) - weight 1067 11 0.1546468437 ( 1.0045620203 22.8353118896 -3.8297865391 ) - weight 1068 11 1 ( -2.2153379917 16.2348270416 1.8585470915 ) - weight 1069 11 1 ( 0.3322205245 15.7341518402 3.0729541779 ) - weight 1070 12 0.0679571778 ( 2.3507173061 -0.0018086863 0.9202408195 ) - weight 1071 11 0.9320428371 ( -1.5528358221 18.5197124481 1.9829810858 ) - weight 1072 10 0.2445449084 ( 7.2806305885 21.603515625 -2.3986618519 ) - weight 1073 11 0.7554550171 ( 1.1507575512 2.2435712814 4.3119368553 ) - weight 1074 10 0.2692195177 ( 6.4686546326 21.5265331268 -4.4724507332 ) - weight 1075 11 0.7307804823 ( 3.0585324764 2.2764573097 3.1607871056 ) - weight 1076 10 0.4226502776 ( -2.4191145897 20.8754425049 -0.0383709371 ) - weight 1077 11 0.5773497224 ( -2.5059816837 -0.8547130823 -4.4752697945 ) - weight 1078 10 0.5958148837 ( -2.4995048046 18.2684249878 0.292182982 ) - weight 1079 11 0.4041851461 ( -2.3965177536 -3.4387931824 -4.0032353401 ) - weight 1080 10 0.5038503408 ( -2.1876580715 20.5305480957 -0.9276463985 ) - weight 1081 11 0.4961496294 ( -1.5462179184 -1.0183876753 -4.3511791229 ) - weight 1082 10 0.7004861832 ( -1.5761703253 17.7096366882 -0.6785594225 ) - weight 1083 11 0.2995138168 ( -1.2152820826 -3.6504104137 -3.1865158081 ) - weight 1084 11 1 ( 0.5809739828 4.3548717499 -2.576612711 ) - weight 1085 11 1 ( 2.5756552219 8.5482797623 -3.0899672508 ) - weight 1086 11 1 ( -0.7325488925 8.2962684631 -3.1873478889 ) - weight 1087 10 0.2415758371 ( -0.0797993168 22.0178794861 -3.1896264553 ) - weight 1088 11 0.7584241033 ( 0.7249971628 1.1777135134 -3.0130836964 ) - weight 1089 11 1 ( 4.1790351868 6.9849925041 -1.6000403166 ) - weight 1090 11 1 ( 2.248080492 11.4512176514 -2.6047000885 ) - weight 1091 12 0.0550869107 ( -4.2698349953 1.2255403996 4.7872776985 ) - weight 1092 11 0.9449130893 ( -2.2072029114 13.8436927795 -4.1813287735 ) - weight 1093 11 1 ( 0.2456579357 15.5727472305 -4.3977541924 ) - weight 1094 11 1 ( 5.3795161247 7.683614254 0.1351621896 ) - weight 1095 11 1 ( 5.6917738914 9.573641777 0.906624496 ) - weight 1096 11 1 ( 4.9285612106 4.7703909874 1.7026741505 ) - weight 1097 10 0.278927356 ( 4.3541970253 21.8525218964 -5.2988739014 ) - weight 1098 11 0.7210726738 ( 3.4843277931 2.2516653538 0.9072877169 ) - weight 1099 11 1 ( 3.2292773724 4.5030784607 -1.0493279696 ) - weight 1100 14 0.3067108989 ( -4.4148259163 -1.4220386744 2.0272610188 ) - weight 1101 12 0.1096295714 ( -5.3626804352 6.2197165489 2.3867211342 ) - weight 1102 13 0.5836595297 ( -4.3761320114 3.5273792744 2.0219323635 ) - weight 1103 12 0.5260417461 ( -3.8864805698 4.0837593079 0.4096829891 ) - weight 1104 13 0.2905490696 ( -3.6716406345 0.3628134429 1.6486035585 ) - weight 1105 11 0.1834091842 ( -1.2977226973 18.8404464722 -5.4794054031 ) - weight 1106 12 0.4963374436 ( -3.7618875504 6.4998006821 -1.8849948645 ) - weight 1107 13 0.5036625862 ( -4.0375976563 0.8078241944 -1.6356568336 ) - weight 1108 12 0.5233104229 ( -2.5348722935 2.3021321297 -2.2422227859 ) - weight 1109 13 0.1692353189 ( -3.2534415722 -2.9061028957 0.565579772 ) - weight 1110 11 0.307454288 ( 1.0348900557 20.3611965179 -3.4106178284 ) - weight 1111 12 0.1526855826 ( -2.8752996922 -0.2926418185 -1.1304950714 ) - weight 1112 11 0.8473144174 ( 2.0900216103 17.9825134277 -2.2646489143 ) - weight 1113 12 0.2164441943 ( -3.1558082104 0.7535933852 1.4871183634 ) - weight 1114 11 0.7835558057 ( -0.1846503019 16.4800548553 -3.0351531506 ) - weight 1115 12 0.5 ( -0.9096027613 -2.4827189445 -3.5707731247 ) - weight 1116 11 0.5 ( 4.2952618599 19.3468322754 0.5444276929 ) - weight 1117 11 1 ( 3.3132717609 15.5842876434 -0.3710872531 ) - weight 1118 11 1 ( 1.8058729172 16.0181407928 -2.6778199673 ) - weight 1119 11 1 ( 3.5787250996 18.3723907471 0.0804280341 ) - weight 1120 22 1 ( -1.7510398626 -0.3758468628 10.4058322906 ) - weight 1121 22 1 ( -2.1411099434 -2.3178787231 10.4711523056 ) - weight 1122 22 1 ( -2.649600029 4.1038856506 5.4536514282 ) - weight 1123 22 1 ( -1.4680099487 3.8153495789 7.5456018448 ) - weight 1124 22 0.8961666822 ( -1.3614399433 -5.2326774597 9.0325422287 ) - weight 1125 19 0.1038333252 ( -1.3614399433 3.4152784348 9.4575052261 ) - weight 1126 22 0.8395406604 ( -1.6664299965 -5.8079566956 7.9944214821 ) - weight 1127 19 0.1604593247 ( -1.6664299965 2.7509813309 8.4739656448 ) - weight 1128 18 0.0514105596 ( -1.4646830559 7.4121360779 -0.0568265915 ) - weight 1129 17 0.082559742 ( -1.0596667528 7.3524231911 8.4284677505 ) - weight 1130 22 0.6282635927 ( -1.5464400053 -7.1010856628 7.7465214729 ) - weight 1131 21 0.0742525235 ( 2.705919981 -4.7823600769 0.952773571 ) - weight 1132 19 0.163513571 ( -1.5464400053 1.4410680532 8.3406829834 ) - weight 1133 22 1 ( -3.1945099831 -0.7266159058 9.1527719498 ) - weight 1134 22 0.9379876256 ( -3.7911200523 -2.4407157898 8.6227121353 ) - weight 1135 19 0.062012367 ( -3.7911200523 6.1604132652 8.8038644791 ) - weight 1136 22 0.8737977743 ( -3.9777700901 -3.0628471375 7.9290118217 ) - weight 1137 19 0.126202181 ( -3.9777700901 5.4797177315 8.1675310135 ) - weight 1138 22 0.8407360911 ( -4.3908100128 -4.371837616 7.4161314964 ) - weight 1139 19 0.1592639238 ( -4.3908100128 4.1307144165 7.7716879845 ) - weight 1140 18 0.0533885434 ( -3.568333149 8.125995636 -1.0036764145 ) - weight 1141 17 0.1093793511 ( -3.214202404 8.2439107895 7.8002257347 ) - weight 1142 22 0.5654591918 ( -3.6500899792 -6.3872261047 6.7996716499 ) - weight 1143 21 0.0983735695 ( 0.6022698879 -4.0685005188 0.005923748 ) - weight 1144 19 0.173399359 ( -3.6500899792 2.0689425468 7.3347539902 ) - weight 1145 22 1 ( -2.4722099304 1.9038238525 7.3857517242 ) - weight 1146 22 0.8982512355 ( -6.2419500351 -2.8530273438 6.7008314133 ) - weight 1147 19 0.1017487347 ( -6.2419500351 5.5807762146 6.9256620407 ) - weight 1148 41 0.1072412506 ( 5.1577458382 2.9374084473 -6.1040344238 ) - weight 1149 17 0.0658963397 ( -6.5783500671 10.654715538 7.8331522942 ) - weight 1150 22 0.6361353993 ( -6.9771800041 -4.0395088196 6.0585618019 ) - weight 1151 21 0.0671572387 ( -2.724820137 -1.7207832336 -0.7351861 ) - weight 1152 19 0.1235697716 ( -6.9771800041 4.3424348831 6.390162468 ) - weight 1153 41 0.0678025484 ( 2.5928883553 1.4666678905 -6.2361097336 ) - weight 1154 22 0.8568934202 ( -7.179910183 -1.1031684875 6.3681116104 ) - weight 1155 21 0.0753040016 ( -2.9275503159 1.2155570984 -0.4256362915 ) - weight 1156 40 0.068698816 ( 0.7354998589 4.5274701118 -4.1547317505 ) - weight 1157 41 0.1991942525 ( 2.7275547981 2.9114971161 -4.7111206055 ) - weight 1158 22 0.5254926682 ( -8.3566799164 -1.9324073792 4.8322615623 ) - weight 1159 21 0.1189748868 ( -4.1043200493 0.3863182068 -1.9614863396 ) - weight 1160 19 0.0876394659 ( -8.3566799164 6.3335971832 4.9834070206 ) - weight 1161 40 0.1195673719 ( -0.3474302292 5.5712599754 -1.6022529602 ) - weight 1162 41 0.1591295004 ( 1.146941781 0.5851337314 -5.642291069 ) - weight 1163 22 0.721303165 ( -7.2737498283 0.6200714111 5.8760514259 ) - weight 1164 40 0.0923882127 ( -1.1369199753 6.3111901283 -1.9519309998 ) - weight 1165 22 0.9076117873 ( -6.4842600822 0.2703933716 6.6159815788 ) - weight 1166 3 0.1972438842 ( -2.6951899529 -2.520614624 -7.0929346085 ) - weight 1167 10 0.4211695492 ( 6.4942598343 -0.1665377319 -4.9188761711 ) - weight 1168 17 0.3190617561 ( -2.9865500927 -1.3908243179 -7.6513586044 ) - weight 1169 19 0.062524803 ( -2.6951899529 -12.065281868 -4.108291626 ) - weight 1170 3 0.1992882937 ( -6.1590600014 -0.9346160889 -5.6005349159 ) - weight 1171 10 0.3922216892 ( 6.3229842186 -1.0328863859 -0.9237354398 ) - weight 1172 17 0.354028523 ( -6.3590350151 -0.2584370673 -5.6301989555 ) - weight 1173 19 0.0544615164 ( -6.1590600014 -10.3542480469 -2.761067152 ) - weight 1174 3 0.1813982129 ( -3.4160699844 1.0148239136 -8.7502756119 ) - weight 1175 10 0.2088200301 ( 8.2837114334 -3.6341922283 -4.1847062111 ) - weight 1176 17 0.4655880928 ( -3.8013825417 2.4291477203 -8.3652448654 ) - weight 1177 19 0.1441936195 ( -3.4160699844 -8.6891956329 -6.069961071 ) - weight 1178 3 0.3105494976 ( -5.3668899536 -0.782245636 5.1301150322 ) - weight 1179 18 0.1053828672 ( -5.285132885 -3.2093849182 -1.4216966629 ) - weight 1180 10 0.3618154526 ( -3.9894304276 -0.5729674697 2.1160304546 ) - weight 1181 17 0.2222521901 ( -4.9521679878 -2.6807358265 4.7597379684 ) - weight 1182 3 0.2318675071 ( -8.2407598495 -0.3582458496 1.2500151396 ) - weight 1183 10 0.560138762 ( 0.656690836 -0.770146668 3.4830548763 ) - weight 1184 17 0.207993716 ( -8.0440397263 -1.3756612539 1.2624263763 ) - weight 1185 3 0.1634391248 ( -7.5889902115 -2.8999176025 2.0655453205 ) - weight 1186 10 0.7109901309 ( -0.3257987499 1.6740039587 2.7014989853 ) - weight 1187 17 0.1255707443 ( -7.3465285301 -4.0296096802 1.403932929 ) - weight 1188 3 0.2218398005 ( -5.0421299934 -3.955165863 4.4169454575 ) - weight 1189 18 0.0730421096 ( -4.9603729248 -6.3823051453 -2.1348662376 ) - weight 1190 10 0.5609948039 ( -3.4239704609 2.4412567616 0.9863359332 ) - weight 1191 17 0.1441233009 ( -4.6688838005 -5.584148407 3.2861545086 ) - weight 1192 3 0.2988711596 ( -1.9142600298 -5.6988983154 4.9153752327 ) - weight 1193 18 0.068852976 ( -1.8325030804 -8.1260375977 -1.6364364624 ) - weight 1194 10 0.5538879633 ( -4.9934802055 3.6579136848 -2.0350859165 ) - weight 1195 17 0.0783879459 ( -1.5175592899 -7.3531417847 3.174706459 ) - weight 1196 3 0.1712329835 ( -3.5819699764 -9.658367157 4.7623753548 ) - weight 1197 10 0.8287670016 ( -4.2401051521 7.8230419159 -1.2826292515 ) - weight 1198 10 1 ( -2.7762982845 13.3533477783 -1.6376892328 ) - weight 1199 3 0.0713142753 ( -7.6723899841 -14.3153362274 4.8165154457 ) - weight 1200 10 0.9286857247 ( -2.8163487911 13.1002244949 1.6407397985 ) - weight 1201 10 1 ( -2.0142076015 15.4658632278 1.9298450947 ) - weight 1202 3 0.0998161286 ( -0.6950399876 -10.0085983276 2.0434751511 ) - weight 1203 10 0.9001838565 ( -2.7229239941 7.4876875877 -4.9480271339 ) - weight 1204 10 1 ( -1.1770615578 14.710735321 -5.365500927 ) - weight 1205 10 1 ( -2.1116390228 16.6030330658 -1.4046429396 ) - weight 1206 10 0.6628287435 ( -1.1214532852 18.2551040649 -4.2275867462 ) - weight 1207 11 0.3371713161 ( 2.2163727283 -2.5446019173 -3.5040524006 ) - weight 1208 10 1 ( 5.772954464 15.4340810776 2.5857465267 ) - weight 1209 10 0.9249721766 ( 8.2548427582 16.6990032196 -0.0941790715 ) - weight 1210 11 0.0750278234 ( -0.1092666686 -2.6051175594 6.5959067345 ) - weight 1211 10 0.6973620653 ( 4.3779053688 17.8648262024 2.646509409 ) - weight 1212 11 0.3026379347 ( -3.5683493614 -2.6776316166 3.1418299675 ) - weight 1213 10 1 ( 3.0941278934 14.5601882935 3.808958292 ) - weight 1214 3 0.14986296 ( -9.3841495514 -3.3818283081 -1.219914794 ) - weight 1215 10 0.729921639 ( 3.3852584362 2.2251083851 3.1179375648 ) - weight 1216 17 0.1202153414 ( -9.3273324966 -3.7318725586 -1.7955750227 ) - weight 1217 3 0.1998521388 ( -8.6325597763 -1.0597953796 -2.6692247391 ) - weight 1218 10 0.6647385359 ( 4.4624848366 -0.285790205 2.3483951092 ) - weight 1219 17 0.1354093254 ( -8.6601810455 -1.1192337275 -2.6822834015 ) - weight 1220 3 0.1863135993 ( -6.5873398781 -2.4839172363 -5.4120049477 ) - weight 1221 10 0.5943826437 ( 6.3058948517 0.575974524 -0.7488765121 ) - weight 1222 17 0.2193037421 ( -6.775785923 -1.813369751 -5.7969455719 ) - weight 1223 3 0.1155277118 ( -7.4725899696 -4.7909049988 -4.7723345757 ) - weight 1224 10 0.8844723105 ( 6.0328884125 3.0386486053 -0.1358990222 ) - weight 1225 3 0.1103929654 ( -4.7616200447 -8.1659545898 -6.01755476 ) - weight 1226 10 0.8896070123 ( 6.2486772537 5.8088088036 -3.681394577 ) - weight 1227 10 0.8683697581 ( 8.2069692612 16.1516017914 -3.2984352112 ) - weight 1228 11 0.1316302568 ( 3.0958566666 -2.7107656002 6.0618453026 ) - weight 1229 3 0.2302151769 ( -0.4771699905 -6.5307846069 2.9339251518 ) - weight 1230 10 0.6826946139 ( -3.6482760906 4.0937662125 -4.1993098259 ) - weight 1231 17 0.0870902091 ( -0.1965861619 -7.6640291214 0.9743004441 ) - weight 1232 3 0.1804637611 ( -1.3150800467 -5.4401054382 -5.6257348061 ) - weight 1233 10 0.6513491273 ( 4.6455273628 2.5703372955 -6.2121310234 ) - weight 1234 17 0.1681870967 ( -1.5244899988 -4.558139801 -7.0100326538 ) - weight 1235 3 0.1705142111 ( -0.1665000021 -7.6281356812 -2.1573746204 ) - weight 1236 10 0.6608000994 ( 1.0052406788 4.7664041519 -6.4608073235 ) - weight 1237 17 0.0726470575 ( -0.1786994934 -7.5001015663 -4.2405662537 ) - weight 1238 4 0.0960386172 ( -0.8893948793 4.7091393471 -6.7670207024 ) - weight 1239 3 0.1035555899 ( -1.5106099844 -8.0483856201 -4.9563946724 ) - weight 1240 10 0.8964444399 ( 4.1010584831 5.2139291763 -6.2780852318 ) - weight 1241 3 0.0648362264 ( -1.7901200056 -17.2447357178 -2.618904829 ) - weight 1242 10 0.8809807301 ( 2.0567274094 14.4635066986 -6.895216465 ) - weight 1243 11 0.0541830696 ( 5.9442443848 -5.171652317 -0.2184968144 ) - weight 1244 10 0.7249333262 ( 7.4257850647 18.0973911285 -4.4806828499 ) - weight 1245 11 0.275066644 ( 3.7962887287 -0.8352098465 4.7255315781 ) - weight 1246 10 0.8269158006 ( 4.5153861046 17.9354343414 -6.7786464691 ) - weight 1247 11 0.1730842143 ( 5.6159472466 -1.3028670549 1.5243711472 ) - weight 1248 10 0.5832556486 ( 4.2884063721 19.9541397095 -6.0376958847 ) - weight 1249 11 0.4167443216 ( 4.5164861679 0.501155138 1.0635108948 ) - weight 1250 10 0.8485231996 ( 1.0249433517 18.1644592285 -6.4098215103 ) - weight 1251 11 0.1514768004 ( 4.6843175888 -1.8776446581 -1.8182883263 ) - weight 1252 22 1 ( -4.7289199829 8.8134422302 0.2027816772 ) - weight 1253 22 1 ( -6.1977901459 8.4980354309 3.8981716633 ) - weight 1254 22 1 ( -4.7475600243 6.5352897644 5.4856314659 ) - weight 1255 22 1 ( -3.978290081 4.4368476868 3.9854016304 ) - weight 1256 22 1 ( -4.1528902054 5.0905418396 6.5792217255 ) - weight 1257 22 1 ( -5.7784399986 2.8446540833 8.8613119125 ) - weight 1258 22 1 ( -6.4211301804 2.0640411377 8.17192173 ) - weight 1259 22 1 ( -5.7889099121 0.282623291 8.0855417252 ) - weight 1260 40 0.0668390542 ( -0.1734499931 5.8462395668 1.2844085693 ) - weight 1261 22 0.9331609607 ( -7.4477300644 3.5067329407 6.1510314941 ) - weight 1262 22 1 ( -6.3436799049 1.3019523621 6.7690014839 ) - weight 1263 22 1 ( -4.4503002167 2.6615486145 9.109951973 ) - weight 1264 40 0.0571298972 ( 0.2213401794 -0.6442199945 6.883354187 ) - weight 1265 22 0.9428701401 ( -7.842520237 9.1056785583 -0.3394283056 ) - weight 1266 22 1 ( -6.6125397682 8.991985321 -2.9377484322 ) - weight 1267 40 0.111378029 ( 1.1370301247 -1.5324800014 4.9099273682 ) - weight 1268 41 0.105331108 ( -4.5938420296 -1.7893601656 1.873054266 ) - weight 1269 22 0.783290863 ( -8.7582101822 7.1322517395 -1.2276883125 ) - weight 1270 22 1 ( -6.2344698906 9.68957901 -0.1023983955 ) - weight 1271 22 1 ( -4.038189888 8.2165260315 -3.3059682846 ) - weight 1272 22 1 ( -4.1863298416 6.6580924988 0.3246916533 ) - weight 1273 22 1 ( -3.0047698021 5.9508857727 -2.8457283974 ) - weight 1274 22 1 ( -2.3421599865 7.295627594 -4.156358242 ) - weight 1275 40 0.1057041064 ( -3.7261602879 -7.190410614 3.7854537964 ) - weight 1276 22 0.8942958713 ( -3.8950197697 6.0077781677 -6.8856186867 ) - weight 1277 40 0.184688434 ( -3.3615002632 -6.5687403679 1.2278900146 ) - weight 1278 39 0.0978074223 ( 6.338845253 0.8741009831 0.6034603715 ) - weight 1279 22 0.7175041437 ( -4.2596797943 3.450214386 -6.2639484406 ) - weight 1280 22 1 ( -7.3468298912 6.4065589905 5.9920315742 ) - weight 1281 40 0.1474835575 ( 1.0070500374 3.8792998791 3.6388168335 ) - weight 1282 22 0.8525164723 ( -8.6282300949 5.8611412048 4.184091568 ) - weight 1283 22 1 ( -6.6628699303 4.7827949524 7.4596414566 ) - weight 1284 40 0.0617888346 ( 0.1698098183 3.567139864 5.2967376709 ) - weight 1285 22 0.938211143 ( -7.7909898758 7.5190620422 3.8719315529 ) - weight 1286 22 1 ( -5.9484601021 6.9797859192 6.1427016258 ) - weight 1287 22 1 ( -5.8876700401 -1.5171470642 7.8475914001 ) - weight 1288 17 0.1051118597 ( -5.3652558327 8.4778156281 6.77947855 ) - weight 1289 22 0.5924144983 ( -5.7374901772 -6.4061470032 5.6308817863 ) - weight 1290 21 0.1071231738 ( -1.4851303101 -4.0874214172 -1.1628661156 ) - weight 1291 19 0.1953504384 ( -5.7374901772 1.9473655224 6.1721506119 ) - weight 1292 41 0.147641018 ( 5.8350968361 4.3208684921 -2.9803140163 ) - weight 1293 22 0.4659926295 ( -7.8559999466 -5.1913986206 2.8913516998 ) - weight 1294 21 0.1891750991 ( -3.6036400795 -2.8726730347 -3.9023962021 ) - weight 1295 19 0.1971912086 ( -7.8559999466 2.9166250229 3.3364536762 ) - weight 1296 17 0.1465977579 ( -6.5742926598 8.6858940125 3.6811113358 ) - weight 1297 22 0.4667060673 ( -6.7690300941 -6.9507064819 2.5092916489 ) - weight 1298 21 0.1440529972 ( -2.5166702271 -4.631980896 -4.2844562531 ) - weight 1299 19 0.2426431924 ( -6.7690300941 1.1305451393 3.1105048656 ) - weight 1300 41 0.0508734323 ( 6.7911081314 4.8952140808 0.316948086 ) - weight 1301 17 0.0643401444 ( -7.8882241249 10.1988010406 1.0651199818 ) - weight 1302 22 0.3889924586 ( -7.9141201973 -6.1126556396 -0.4647883177 ) - weight 1303 21 0.1900876909 ( -3.6617603302 -3.7939300537 -7.2585363388 ) - weight 1304 19 0.3057062328 ( -7.9141201973 1.7039493322 0.0742753819 ) - weight 1305 18 0.0615025498 ( -4.9040927887 6.0099754333 -2.1627464294 ) - weight 1306 17 0.1669694483 ( -4.6142969131 6.4505529404 6.2417516708 ) - weight 1307 22 0.4150598943 ( -4.9858498573 -8.5032463074 5.640601635 ) - weight 1308 21 0.1501689106 ( -0.7334899902 -6.1845207214 -1.1531462669 ) - weight 1309 19 0.2062992454 ( -4.9858498573 -0.1407634318 6.3661546707 ) - weight 1310 17 0.3197784126 ( -6.5423293114 7.0306820869 2.6599674225 ) - weight 1311 22 0.3531831205 ( -6.7031202316 -8.803188324 1.9198416471 ) - weight 1312 19 0.3270384371 ( -6.7031202316 -0.7665764093 2.6861577034 ) - weight 1313 17 0.335439384 ( -6.6304440498 8.2581129074 -0.6576844454 ) - weight 1314 22 0.2969803214 ( -6.5892701149 -8.4112586975 -1.5950684547 ) - weight 1315 19 0.3675802648 ( -6.5892701149 -0.6851024628 -0.8495974541 ) - weight 1316 3 0.0602750927 ( -6.1856298447 6.4489326477 -2.8100347519 ) - weight 1317 17 0.4647755027 ( -6.2253699303 6.2360086441 -1.1459268332 ) - weight 1318 22 0.1959326863 ( -6.1856298447 -10.4914283752 -1.5584983826 ) - weight 1319 19 0.2790167034 ( -6.1856298447 -2.7540073395 -0.6303348541 ) - weight 1320 3 0.0944565237 ( -6.5064001083 6.2805252075 0.9239951372 ) - weight 1321 10 0.0554682016 ( 0.3153631687 -7.6135573387 2.9943840504 ) - weight 1322 17 0.3342530727 ( -6.3312554359 5.1699471474 2.4494223595 ) - weight 1323 22 0.2158056498 ( -6.5064001083 -10.6598358154 2.1755316257 ) - weight 1324 21 0.0673497766 ( -2.2540402412 -8.3411102295 -4.6182160378 ) - weight 1325 19 0.2326668203 ( -6.5064001083 -2.5935649872 3.1040458679 ) - weight 1326 3 0.1467750371 ( -7.3777899742 3.9521141052 1.1567951441 ) - weight 1327 18 0.062722981 ( -7.2960329056 1.524974823 -5.3950166702 ) - weight 1328 10 0.0629120395 ( 0.4178413153 -5.1604075432 3.4488837719 ) - weight 1329 17 0.3791099787 ( -7.1878442764 2.8420786858 2.16254282 ) - weight 1330 22 0.1106511429 ( -7.3777899742 -12.9882469177 2.4083316326 ) - weight 1331 21 0.0763881281 ( -3.1254301071 -10.6695213318 -4.3854160309 ) - weight 1332 19 0.1614407152 ( -7.3777899742 -4.8925032616 3.5405979156 ) - weight 1333 1 0.0607584976 ( -2.8673114777 5.7981109619 5.2397899628 ) - weight 1334 3 0.1548574418 ( -2.9352500439 5.7874832153 5.397465229 ) - weight 1335 18 0.1817961633 ( -2.8534932137 3.3603439331 -1.1543464661 ) - weight 1336 17 0.210098654 ( -2.5091907978 3.6647799015 6.466190815 ) - weight 1337 22 0.1946305186 ( -2.9352500439 -11.1528778076 6.6490015984 ) - weight 1338 21 0.0813488662 ( 1.3171098232 -8.8341522217 -0.1447463036 ) - weight 1339 19 0.1165098697 ( -2.9352500439 -2.6915082932 7.6035385132 ) - weight 1340 3 0.0887356102 ( -4.7174100876 6.0775718689 4.2193751335 ) - weight 1341 18 0.092637077 ( -4.635653019 3.6504325867 -2.3324365616 ) - weight 1342 10 0.0670044422 ( -3.3997011185 -7.4897127151 2.4613127708 ) - weight 1343 17 0.2894819677 ( -4.3560414314 4.2050495148 5.4938774109 ) - weight 1344 22 0.2918421626 ( -4.7174100876 -10.8627891541 5.4709115028 ) - weight 1345 19 0.170298785 ( -4.7174100876 -2.5060892105 6.404510498 ) - weight 1346 3 0.2131532431 ( -4.5985898972 3.7770729065 4.6188354492 ) - weight 1347 18 0.135866642 ( -4.5168328285 1.3499336243 -1.9329762459 ) - weight 1348 10 0.0772697851 ( -3.8049855232 -5.220852375 2.0688855648 ) - weight 1349 17 0.3338316679 ( -4.2144856453 1.8778789043 5.320037365 ) - weight 1350 22 0.1285075098 ( -4.5985898972 -13.1632881165 5.8703718185 ) - weight 1351 19 0.1113710925 ( -4.5985898972 -4.7625746727 7.0046248436 ) - weight 1352 3 0.0958259404 ( -6.9475197792 3.8599739075 -2.9940247536 ) - weight 1353 10 0.0932059735 ( 4.1452555656 -5.4309740067 1.5898234844 ) - weight 1354 17 0.4570136666 ( -6.9965653419 3.7570371628 -1.9055272341 ) - weight 1355 22 0.127003774 ( -6.9475197792 -13.0803871155 -1.7424883842 ) - weight 1356 19 0.2269506603 ( -6.9475197792 -5.3491182327 -0.5860593319 ) - weight 1357 17 0.4509834349 ( -4.6608123779 6.1965656281 -3.2577207088 ) - weight 1358 22 0.194998771 ( -4.5065398216 -11.0385169983 -3.5053982735 ) - weight 1359 19 0.3540177643 ( -4.5065398216 -3.4700992107 -2.5216143131 ) - weight 1360 3 0.0707394406 ( -3.9025700092 4.059715271 -5.7335548401 ) - weight 1361 17 0.5343282819 ( -4.1139025688 4.6519727707 -4.6814928055 ) - weight 1362 22 0.1061162949 ( -3.9025700092 -12.880645752 -4.4820184708 ) - weight 1363 19 0.2888159454 ( -3.9025700092 -5.3909373283 -3.3325431347 ) - weight 1364 17 0.2058718204 ( -6.7580609322 11.1467828751 -1.3286612034 ) - weight 1365 22 0.3525308967 ( -6.6393399239 -5.7693481445 -2.947368145 ) - weight 1366 21 0.0890728533 ( -2.3869800568 -3.4506225586 -9.7411155701 ) - weight 1367 19 0.3525243998 ( -6.6393399239 1.8277248144 -2.4288711548 ) - weight 1368 17 0.2899022698 ( -7.6994504929 13.8353271484 -0.5324822068 ) - weight 1369 22 0.3207769394 ( -7.5863499641 -2.9681777954 -2.8766584396 ) - weight 1370 21 0.1254296601 ( -3.333990097 -0.6494522095 -9.6704063416 ) - weight 1371 19 0.2638911009 ( -7.5863499641 4.6242690086 -2.6046407223 ) - weight 1372 40 0.2156514823 ( -1.9940800667 -5.1147799492 -3.369682312 ) - weight 1373 41 0.1801882088 ( 4.2453861237 0.2432823926 4.8605413437 ) - weight 1374 39 0.1092495471 ( 4.975880146 3.053735733 -3.6992163658 ) - weight 1375 22 0.2771679461 ( -5.6270999908 -1.1473579407 -4.8099884987 ) - weight 1376 19 0.2177427709 ( -5.6270999908 6.2681145668 -4.6905274391 ) - weight 1377 17 0.3516447544 ( -4.8442406654 11.6421318054 -2.6894199848 ) - weight 1378 22 0.2957075536 ( -4.646009922 -5.6164474487 -4.2751483917 ) - weight 1379 19 0.3526476622 ( -4.646009922 1.8633300066 -3.7649517059 ) - weight 1380 17 0.3825561702 ( -2.9114775658 6.6753277779 -4.5454897881 ) - weight 1381 22 0.2105682194 ( -2.6817200184 -10.8841285706 -4.7679085732 ) - weight 1382 19 0.4068756104 ( -2.6817200184 -3.4272749424 -3.7928082943 ) - weight 1383 18 0.1023409218 ( -3.0213732719 5.6888656616 -0.8786563873 ) - weight 1384 17 0.2209153026 ( -2.6609675884 5.8560695648 7.3036961555 ) - weight 1385 22 0.4562957883 ( -3.1031301022 -8.8243560791 6.9246916771 ) - weight 1386 21 0.0661183074 ( 1.1492297649 -6.5056304932 0.1309437752 ) - weight 1387 19 0.1543296576 ( -3.1031301022 -0.3477668762 7.6734986305 ) - weight 1388 17 0.3431998193 ( -4.905585289 8.3657712936 -2.5002236366 ) - weight 1389 22 0.2507736087 ( -4.7631101608 -8.750705719 -3.3072581291 ) - weight 1390 19 0.4060266018 ( -4.7631101608 -1.1737266779 -2.5253255367 ) - weight 1391 40 0.2480341196 ( -4.4004297256 -5.8042697906 -2.5647010803 ) - weight 1392 41 0.05254196 ( 4.9649486542 -2.200419426 5.5120491982 ) - weight 1393 39 0.1313540637 ( 5.5091128349 0.5102841258 -3.2986824512 ) - weight 1394 22 0.3339982033 ( -3.2207500935 -0.342376709 -5.4994783401 ) - weight 1395 19 0.2340716571 ( -3.2207500935 7.0093784332 -5.4481015205 ) - weight 1396 40 0.2521201074 ( -3.6233799458 -5.5476403236 0.3146743774 ) - weight 1397 41 0.0534075163 ( 2.1310667992 -3.1625232697 5.449280262 ) - weight 1398 39 0.1335179359 ( 5.3030114174 0.8281104565 -0.3293428719 ) - weight 1399 22 0.4550358355 ( -3.9978001118 2.5369987488 -5.2428483963 ) - weight 1400 19 0.1059186161 ( -3.9978001118 9.9001665115 -5.4455442429 ) - weight 1401 22 1 ( -3.0729997158 5.6761817932 2.9678616524 ) - weight 1402 22 1 ( -1.8106399775 4.7085075378 4.1403317451 ) - weight 1403 22 1 ( -2.5946097374 6.8730201721 -0.7384383678 ) - weight 1404 22 1 ( -3.6320297718 6.7187461853 1.0049716234 ) - weight 1405 41 1 ( -4.5737071037 2.9233417511 0.5721877813 ) - weight 1406 41 1 ( -3.3249344826 3.2774739265 1.988556385 ) - weight 1407 41 1 ( -3.4019043446 4.6681251526 -0.0984543338 ) - weight 1408 40 0.0574692227 ( 2.5733799934 -0.8266299963 2.9896774292 ) - weight 1409 41 0.7908906341 ( -3.8510656357 0.4712993801 1.1072950363 ) - weight 1410 22 0.1516401172 ( -10.194560051 5.2120018005 -0.5218383074 ) - weight 1411 41 1 ( -4.5257015228 1.5159267187 -0.512558639 ) - weight 1412 40 0.1086138338 ( 2.4968600273 2.4482498169 2.5968170166 ) - weight 1413 41 0.7952347398 ( -3.70333004 0.614985168 -2.1855094433 ) - weight 1414 22 0.0961514935 ( -10.1180400848 4.8191413879 2.7530417442 ) - weight 1415 41 1 ( -3.1281425953 3.6674330235 -2.1531996727 ) - weight 1416 40 0.0748372078 ( 2.7695403099 3.7821600437 0.5155487061 ) - weight 1417 41 0.7072091103 ( -2.2215948105 1.9973571301 -3.6273336411 ) - weight 1418 22 0.2179537117 ( -10.3907203674 2.7378730774 4.0869517326 ) - weight 1419 41 1 ( -4.400613308 2.9683535099 -1.3177791834 ) - weight 1420 40 0.2063500881 ( 1.7650504112 1.024279952 3.6531219482 ) - weight 1421 41 0.2027421594 ( -4.0747642517 -0.5764046907 -0.7289233804 ) - weight 1422 22 0.5909077525 ( -9.3862304688 5.8754463196 1.329071641 ) - weight 1423 40 0.2600125968 ( 1.0677495003 -2.0426199436 3.0949554443 ) - weight 1424 41 0.2458960116 ( -3.0182487965 -0.8326212168 2.2747046947 ) - weight 1425 39 0.0554707944 ( 2.107088089 5.2231431007 3.2050008774 ) - weight 1426 22 0.4386205673 ( -8.6889295578 5.3172798157 -1.7378282547 ) - weight 1427 40 0.1246283874 ( -0.3298501968 4.9970297813 0.1645736694 ) - weight 1428 41 0.144440949 ( -0.2871128619 -0.3837065697 -4.9665980339 ) - weight 1429 22 0.730930686 ( -7.2913298607 2.3868980408 5.3018217087 ) - weight 1430 40 0.0973157212 ( 1.0908799171 4.5953998566 -1.0204811096 ) - weight 1431 41 0.3694535792 ( -0.0699094236 1.4579395056 -4.5854182243 ) - weight 1432 22 0.533230722 ( -8.7120599747 1.2018432617 4.9001917839 ) - weight 1433 40 0.0684367046 ( 3.2308001518 3.7022099495 -1.2845115662 ) - weight 1434 41 0.7754676938 ( -0.9826384187 3.3845436573 -3.6357438564 ) - weight 1435 22 0.1560956091 ( -10.8519802094 0.9378128052 4.0070018768 ) - weight 1436 40 0.2081722021 ( 0.8482499123 3.794960022 2.0469512939 ) - weight 1437 41 0.2271322608 ( -2.4207425117 -0.451512754 -3.6177968979 ) - weight 1438 39 0.0715175495 ( -3.7325191498 5.546456337 2.1958971024 ) - weight 1439 22 0.4931779802 ( -8.4694299698 4.2692756653 4.0997519493 ) - weight 1440 41 1 ( -2.5169320107 5.4640002251 2.3035945892 ) - weight 1441 41 1 ( -1.489172101 5.0256624222 3.0345840454 ) - weight 1442 41 1 ( -1.5416847467 2.8448455334 3.3588709831 ) - weight 1443 41 1 ( -2.8309929371 5.7042036057 0.0402557924 ) - weight 1444 41 1 ( -2.308814764 7.8798141479 0.2700538337 ) - weight 1445 41 0.8852949142 ( 2.0088386536 4.4957323074 1.6784909964 ) - weight 1446 22 0.1147050709 ( -10.2919797897 -1.8515586853 -1.5003182888 ) - weight 1447 41 0.8457428217 ( 2.2442164421 4.8570804596 0.1016341746 ) - weight 1448 22 0.1542572081 ( -10.4064798355 -2.339176178 0.0558216572 ) - weight 1449 41 1 ( 1.5947971344 8.917301178 -0.0446864404 ) - weight 1450 42 0.4190655649 ( 0.9207583666 -0.2389800698 -1.4912035465 ) - weight 1451 41 0.5809344053 ( 1.0919215679 11.2340106964 -1.2215590477 ) - weight 1452 42 0.5188346505 ( -1.7196917534 -0.3133876324 -1.4144927263 ) - weight 1453 41 0.4811653197 ( -1.5219312906 10.9956617355 -1.5287417173 ) - weight 1454 42 1 ( 1.0256003141 2.0023908615 -1.2599636316 ) - weight 1455 42 1 ( -1.3679801226 2.8051021099 -1.4062660933 ) - weight 1456 42 0.8491173387 ( -1.8222820759 6.6780166626 -0.262917161 ) - weight 1457 43 0.1508826464 ( -1.6347914934 -2.2106258869 2.3158690929 ) - weight 1458 42 0.8905194998 ( -0.2282122225 5.669011116 -1.0367674828 ) - weight 1459 43 0.1094805077 ( -3.4104855061 -2.0681056976 1.3236019611 ) - weight 1460 42 1 ( -2.5128338337 1.988139987 -0.8223508 ) - weight 1461 42 1 ( -2.6950418949 3.1790823936 0.9545557499 ) - weight 1462 42 0.4581014812 ( -2.7132713795 -0.2719167471 0.1736711562 ) - weight 1463 41 0.541898489 ( -2.765450716 11.3964281082 -0.1855254322 ) - weight 1464 42 0.6225126386 ( -2.225376606 -0.0381903648 1.6623265743 ) - weight 1465 41 0.3774873018 ( -2.5370104313 12.0600261688 1.2344105244 ) - weight 1466 41 1 ( -1.3009425402 6.5635404587 -2.3177375793 ) - weight 1467 41 1 ( -1.7768422365 5.7442073822 -2.3522181511 ) - weight 1468 42 0.1075217649 ( -0.5194612145 -1.2987929583 -2.898473978 ) - weight 1469 41 0.8924782276 ( -0.0672216415 9.7319850922 -2.477804184 ) - weight 1470 41 0.8474637866 ( 1.0488160849 4.7415208817 -2.4669156075 ) - weight 1471 22 0.1525362581 ( -10.8875398636 -1.4334869385 2.6993217468 ) - weight 1472 41 0.9353270531 ( 1.6493190527 6.1426820755 -1.8204036951 ) - weight 1473 22 0.0646729767 ( -11.7384300232 -2.6748580933 2.0088016987 ) - weight 1474 42 0.5947855711 ( 2.02643466 0.2101128846 0.0326919444 ) - weight 1475 41 0.4052144587 ( 1.9179337025 12.1578149796 0.2653007507 ) - weight 1476 42 0.9266192317 ( 2.2397406101 3.5982236862 0.3299235702 ) - weight 1477 43 0.0733807161 ( -5.1292219162 -4.14894104 -0.9041473269 ) - weight 1478 42 0.0522220917 ( -1.924045682 -3.0165319443 0.7669928074 ) - weight 1479 41 0.9477779269 ( -2.0137636662 8.979724884 1.2644159794 ) - weight 1480 41 1 ( -0.5676671863 7.3745908737 2.8090343475 ) - weight 1481 42 0.4609467089 ( -0.158783257 -0.2266419679 2.7818830013 ) - weight 1482 41 0.5390533209 ( -0.6800493598 12.33040905 2.6621069908 ) - weight 1483 42 0.7493240237 ( -0.196716547 0.7326942682 2.8625621796 ) - weight 1484 41 0.2506759465 ( -0.7559140325 13.2703409195 2.4645016193 ) - weight 1485 42 0.9479919672 ( -1.0997285843 3.5335826874 2.6260602474 ) - weight 1486 43 0.0520080328 ( -2.6647129059 -6.3296236992 1.4621362686 ) - weight 1487 42 0.7400000095 ( -1.3652385473 10.2533884048 1.3624815941 ) - weight 1488 46 0.2599999905 ( 1.7520929575 -1.2905029058 0.2743632793 ) - weight 1489 42 0.4114079177 ( 1.3629930019 -0.3542493582 2.4543995857 ) - weight 1490 41 0.5885920525 ( 0.8777543306 12.2271652222 2.6182873249 ) - weight 1491 41 1 ( 1.0186223984 8.8854751587 2.1610341072 ) - weight 1492 42 0.8716737032 ( 1.9981828928 3.5572674274 2.2016527653 ) - weight 1493 43 0.128326267 ( -4.0402297974 -5.6487035751 -1.2622059584 ) - weight 1494 42 0.7400000095 ( 0.6139580011 9.7260513306 -0.4167514741 ) - weight 1495 46 0.2599999905 ( -0.4053022861 0.1436761469 -0.5317075253 ) - weight 1496 42 0.6961435676 ( 1.4852691889 0.6737602949 2.4836196899 ) - weight 1497 41 0.3038563728 ( 0.9665541649 13.2304134369 2.3770029545 ) - weight 1498 42 0.5789999962 ( -0.7476317286 9.7238559723 -1.3704857826 ) - weight 1499 46 0.4210000038 ( -0.2501127422 0.5795270205 1.0650049448 ) - weight 1500 42 0.8309755921 ( 0.8674641252 4.7170491219 2.5919613838 ) - weight 1501 43 0.169024393 ( -2.5363163948 -5.3498811722 -0.6103554368 ) - weight 1502 42 0.7400000095 ( 0.4139006436 10.523100853 0.8866202831 ) - weight 1503 46 0.2599999905 ( 0.9132051468 -0.3912835121 -1.122846961 ) - weight 1504 41 1 ( 0.7961574197 4.0071516037 3.3408105373 ) - weight 1505 42 0.298999995 ( -1.0697075129 10.974814415 1.1974182129 ) - weight 1506 46 0.7009999752 ( 2.076305151 -0.6571171284 -0.0844520405 ) - weight 1507 42 0.5820000172 ( -0.0241795164 10.578081131 1.391933918 ) - weight 1508 46 0.417999953 ( 1.3987067938 -0.8313487768 -0.9782450199 ) - weight 1509 59 0.6864845753 ( 0.7012686133 -0.0236390103 1.364263773 ) - weight 1510 60 0.3135154545 ( 0.8083933592 0.2855468988 -0.104264304 ) - weight 1511 56 0.7909759283 ( -0.187387675 -0.6577931046 0.4580964148 ) - weight 1512 59 0.2090241015 ( 1.0047127008 2.0648038387 2.2430665493 ) - weight 1513 59 0.54871279 ( -0.4299964309 0.4816505611 1.8445304632 ) - weight 1514 60 0.45128721 ( -0.322871685 0.7186188102 0.4420161843 ) - weight 1515 59 0.9465333223 ( -1.0136377811 1.015732646 0.7340225577 ) - weight 1516 60 0.0534666963 ( -0.9065129757 1.4029196501 -0.5827784538 ) - weight 1517 59 0.7117943764 ( -0.4633772075 -0.8422058225 1.7654343843 ) - weight 1518 60 0.2882056236 ( -0.3562524617 -0.5811241269 0.178349629 ) - weight 1519 56 1 ( -0.6164311767 0.2275075018 0.370514214 ) - weight 1520 42 0.3634250164 ( 0.9998697042 11.2391462326 0.5225436687 ) - weight 1521 59 0.077203624 ( -1.7421474457 1.3296120167 -1.0365190506 ) - weight 1522 43 0.5593713522 ( 1.146122694 0.3370631039 -1.5778678656 ) - weight 1523 42 0.235886842 ( 1.3117157221 10.9149999619 -1.0824670792 ) - weight 1524 59 0.5766879916 ( -1.1983163357 0.1598694324 0.0190985799 ) - weight 1525 43 0.1874251217 ( -0.0951456651 1.4102414846 -1.2847472429 ) - weight 1526 54 0.1873759627 ( 0.2723721862 -1.1285324097 1.3155150414 ) - weight 1527 53 0.1066821665 ( -0.69763273 -0.9114277363 1.3341443539 ) - weight 1528 56 0.7059418559 ( -0.6953908205 -0.7050057054 -0.7706091404 ) - weight 1529 57 1 ( -0.2586162686 -0.5348937511 0.3528181314 ) - weight 1530 57 1 ( -0.2654597163 -0.4661820531 -0.3870325387 ) - weight 1531 58 1 ( 0.4985071719 0.1936699897 -0.2115055025 ) - weight 1532 58 1 ( 0.0248226132 0.3962609172 -0.2563136518 ) - weight 1533 58 1 ( 0.4862787724 0.1766597927 0.4663771093 ) - weight 1534 54 0.5691296458 ( -0.7673224211 -0.3590674698 1.0762521029 ) - weight 1535 55 0.4308703542 ( 0.6517369747 -1.1125144958 -1.0426757336 ) - weight 1536 55 1 ( -0.5378077626 -0.3750234246 -0.4059711993 ) - weight 1537 55 1 ( 0.1608413309 0.747653842 -0.6324183941 ) - weight 1538 42 0.7400000095 ( 0.1583463103 11.5301418304 1.6433401108 ) - weight 1539 46 0.2599999905 ( 2.1485965252 -0.3940517008 -1.4776217937 ) - weight 1540 54 0.0996929035 ( 0.6323515177 -1.6585894823 -1.4589054585 ) - weight 1541 53 0.9003071189 ( 0.055703681 -0.9151391983 -1.4118391275 ) - weight 1542 55 1 ( -0.1619102508 0.682061851 0.2272331566 ) - weight 1543 55 1 ( 0.3155505061 -0.2438029349 1.2952861786 ) - weight 1544 55 1 ( 0.3443935215 -1.0889621973 1.4928187132 ) - weight 1545 54 0.548068881 ( 0.1865021884 -0.0209322907 -1.3033356667 ) - weight 1546 53 0.0776808113 ( -1.4058367014 -0.0479571857 -1.2822264433 ) - weight 1547 55 0.3742503226 ( 0.6019417644 -2.12327528 1.3369121552 ) - weight 1548 54 0.793235898 ( -0.0913700089 0.5227378011 0.9488317966 ) - weight 1549 55 0.206764102 ( 0.0013542289 -2.0133442879 -0.9152553678 ) - weight 1550 54 0.2869230807 ( 1.2671220303 -0.8374456763 -1.3551963568 ) - weight 1551 53 0.7130769491 ( -0.059899237 0.1110193729 -1.2648662329 ) - weight 1552 54 0.2508835793 ( -0.2593171895 -0.8810647726 -1.2045148611 ) - weight 1553 53 0.5495494604 ( -1.1364045143 -0.9813420177 -1.214791894 ) - weight 1554 55 0.1995669752 ( 1.2976939678 -1.4491006136 1.2380913496 ) - weight 1555 57 1 ( -0.1226720363 0.3050268292 0.3322834671 ) - weight 1556 42 0.2790000141 ( -1.3627271652 10.7023000717 -0.8522974849 ) - weight 1557 46 0.7209999561 ( 1.0117923021 0.6644273996 1.1328365803 ) - weight 1558 54 0.2420762479 ( 1.2869706154 -0.3525551558 1.1074186563 ) - weight 1559 53 0.7579237819 ( -0.4940260053 0.3589997888 1.1948136091 ) - weight 1560 60 1 ( 0.4067179859 -0.2464438081 1.7548111677 ) - weight 1561 60 1 ( 0.3338762224 0.57050246 1.4967586994 ) - weight 1562 61 1 ( 0.2193833739 0.139272511 1.3561792374 ) - weight 1563 59 0.6720762253 ( 0.3838046789 -0.8056645393 1.7949346304 ) - weight 1564 60 0.3279237747 ( 0.4909294248 -0.5490730405 0.2126753926 ) - weight 1565 60 1 ( -0.4826435447 -0.4104863107 1.6962480545 ) - weight 1566 61 1 ( -0.2086218596 0.6537141204 0.9658535719 ) - weight 1567 60 1 ( -0.6298786402 0.4132819772 1.4962769747 ) - weight 1568 61 1 ( -0.4013764262 0.1500695795 1.2853143215 ) - weight 1569 42 0.1084745452 ( -0.070148088 10.3309001923 -2.106096983 ) - weight 1570 46 0.0739300773 ( -0.4618702531 1.6538442373 0.6531656384 ) - weight 1571 59 0.6378537416 ( 0.3759093285 -0.6578020453 -0.3704706728 ) - weight 1572 43 0.179741621 ( -0.576730907 1.6867072582 0.4444664121 ) - weight 1573 42 0.2423756719 ( 0.9928299189 10.3106222153 -1.8016662598 ) - weight 1574 59 0.6129251719 ( -0.6650521755 -0.6765273213 0.0024368151 ) - weight 1575 43 0.1446991563 ( -0.8224627972 1.5544809103 -0.625647366 ) - weight 1576 57 1 ( -0.0913567841 0.3438081145 -0.4339086115 ) - weight 1577 58 1 ( -0.0082364241 0.3561860025 0.4454070926 ) - weight 1578 56 1 ( -0.4365756512 0.4352388978 -0.4518956244 ) - weight 1579 58 1 ( -0.1609305888 -0.7809339166 0.1301757395 ) - weight 1580 42 0.6650000215 ( -1.5882745981 9.6407613754 -0.5101709962 ) - weight 1581 46 0.3349999785 ( 0.4876451194 -0.2989197671 1.4361805916 ) - weight 1582 41 1 ( -0.6263200045 5.1039280891 -3.0920109749 ) - weight 1583 41 0.7295026779 ( 0.8321101665 3.8914551735 -2.8001251221 ) - weight 1584 22 0.2704973221 ( -10.2911701202 -0.7991676331 3.049441576 ) - weight 1585 22 1 ( -5.149720192 5.3225593567 7.448571682 ) - weight 1586 40 0.0878749788 ( 1.6015601158 1.6416698694 4.7487106323 ) - weight 1587 41 0.083104074 ( -4.9323511124 -1.325460434 -1.2872011662 ) - weight 1588 22 0.8290209174 ( -9.2227401733 6.9710350037 1.9464616776 ) - weight 1589 41 0.3092687428 ( 3.9956858158 4.5114550591 -1.7741059065 ) - weight 1590 22 0.5065450072 ( -9.0798397064 -3.7049980164 1.810831666 ) - weight 1591 19 0.1841862947 ( -9.0798397064 4.3023018837 2.1294701099 ) - weight 1592 22 0.3810738027 ( -8.8634195328 -3.7072792053 -0.8062384129 ) - weight 1593 21 0.341480881 ( -4.6110596657 -1.3885536194 -7.5999860764 ) - weight 1594 19 0.2774453163 ( -8.8634195328 4.0700054169 -0.4772709608 ) - weight 1595 17 0.3154180646 ( -3.0320491791 9.0803003311 -3.7288134098 ) - weight 1596 22 0.269887358 ( -2.814330101 -8.3532371521 -4.5620083809 ) - weight 1597 19 0.4146945775 ( -2.814330101 -0.8880811334 -3.8101546764 ) - weight 1598 17 0.2977738082 ( -2.7244291306 12.289185524 -3.5996701717 ) - weight 1599 22 0.3386747539 ( -2.4700300694 -5.2077674866 -5.191078186 ) - weight 1600 19 0.3635514379 ( -2.4700300694 2.1899237633 -4.7132573128 ) - weight 1601 40 0.2933551073 ( -1.3849101067 -3.7395398617 2.1447143555 ) - weight 1602 41 0.1412155479 ( -0.7519243956 -2.3320336342 3.8282716274 ) - weight 1603 39 0.1009265333 ( 3.6426842213 2.8528242111 1.8553464413 ) - weight 1604 22 0.4645028114 ( -6.2362699509 4.3670387268 -3.4347481728 ) - weight 1605 40 0.2322865874 ( 0.771709919 -3.9490201473 0.472076416 ) - weight 1606 41 0.512103498 ( -0.5536352396 0.3916503489 4.0149159431 ) - weight 1607 22 0.2556099892 ( -8.3928899765 2.6944007874 -3.6442284584 ) - weight 1608 22 1 ( -4.2365198135 7.6505012512 -5.7434782982 ) - weight 1609 22 1 ( -2.4068698883 7.4192390442 -5.9572482109 ) - weight 1610 41 0.4340919256 ( 2.094825983 2.2154459953 -3.4630992413 ) - weight 1611 22 0.5659080744 ( -8.1742696762 -0.9481163025 3.6321415901 ) - weight 1612 40 0.1136212125 ( 1.3156104088 -3.2669899464 -2.1217308044 ) - weight 1613 41 0.7095959783 ( 1.2452841997 2.2873952389 3.2032077312 ) - weight 1614 22 0.1767828166 ( -8.9367904663 0.1005935669 -2.9621982574 ) - weight 1615 40 0.1517526507 ( 1.0405201912 -1.6369800568 -3.4798927307 ) - weight 1616 41 0.4663812518 ( 2.4133751392 2.8107094765 1.4888811111 ) - weight 1617 22 0.2398799211 ( -8.6617002487 -1.2575683594 -1.3321883678 ) - weight 1618 19 0.1419861317 ( -8.6617002487 6.4640078545 -1.2164998055 ) - weight 1619 41 0.5091480017 ( 2.317538023 3.4368126392 -0.8041010499 ) - weight 1620 22 0.3169594109 ( -9.1556501389 -1.6600379944 0.9597516656 ) - weight 1621 21 0.0681705624 ( -4.9032902718 0.6586875916 -5.8339962959 ) - weight 1622 19 0.1057220027 ( -9.1556501389 6.2645430565 1.101944685 ) - weight 1623 40 0.2621071935 ( -1.2170300484 -4.8581500053 -0.4902915955 ) - weight 1624 41 0.2119719684 ( 1.4114917517 -0.7188299298 4.7977733612 ) - weight 1625 39 0.1327841133 ( 4.7697782516 3.3715593815 -0.7298617363 ) - weight 1626 22 0.3082503676 ( -6.4041500092 1.7320327759 -4.5533585548 ) - weight 1627 19 0.0848862678 ( -6.4041500092 9.1589174271 -4.6879711151 ) - weight 1628 40 0.2450042963 ( -0.4521002769 -4.1859498024 -2.0979309082 ) - weight 1629 41 0.3763213754 ( 2.2715055943 0.810320437 4.0605144501 ) - weight 1630 39 0.1241197512 ( 4.1481876373 4.4265675545 -2.1865904331 ) - weight 1631 22 0.1927692145 ( -7.1690797806 0.1243934631 -3.8811583519 ) - weight 1632 19 0.0617853254 ( -7.1690797806 7.6165823936 -3.8770709038 ) - weight 1633 40 0.1269659251 ( 0.2150201797 -3.657200098 -3.1073608398 ) - weight 1634 41 0.3796184063 ( 2.7003214359 1.9251374006 3.4975979328 ) - weight 1635 22 0.3577547967 ( -7.8362002373 -0.8850364685 -3.3524084091 ) - weight 1636 19 0.1356608868 ( -7.8362002373 6.6575331688 -3.2616446018 ) - weight 1637 40 0.2326328158 ( -1.0539002419 -5.255610466 3.3718338013 ) - weight 1638 39 0.0997047126 ( 5.1769108772 2.8849086761 3.1039369106 ) - weight 1639 22 0.6676625013 ( -6.5672798157 5.5941581726 -4.9508185387 ) - weight 1640 40 0.1075652987 ( -1.3275499344 -5.7862901688 5.2485809326 ) - weight 1641 22 0.8924347162 ( -6.2936301231 7.470905304 -5.4814982414 ) - weight 1642 22 1 ( -1.0997798443 1.7325439453 8.7468214035 ) - weight 1643 3 0.2851259112 ( -4.9098901749 3.2377624512 5.3748550415 ) - weight 1644 18 0.1547363997 ( -4.8281331062 0.8106231689 -1.1769566536 ) - weight 1645 10 0.0823570341 ( -4.3986229897 -4.5853242874 2.5194716454 ) - weight 1646 17 0.3558102846 ( -4.4818725586 1.1682983637 5.9399800301 ) - weight 1647 22 0.0550546609 ( -4.9098901749 -13.7025985718 6.6263914108 ) - weight 1648 19 0.0669156909 ( -4.9098901749 -5.2333488464 7.8051204681 ) - weight 1649 3 0.2389346063 ( -6.7000699043 3.4666023254 4.1606354713 ) - weight 1650 18 0.1017972454 ( -6.6183128357 1.0394630432 -2.3911762238 ) - weight 1651 10 0.0995619148 ( -2.628572464 -4.590034008 3.7837262154 ) - weight 1652 17 0.4301410913 ( -6.3388032913 1.6577033997 4.9183487892 ) - weight 1653 22 0.0612390973 ( -6.7000699043 -13.4737586975 5.4121718407 ) - weight 1654 19 0.068326056 ( -6.7000699043 -5.1121168137 6.5754861832 ) - weight 1655 3 0.1501714736 ( -9.0574798584 4.4095039368 -1.6659448147 ) - weight 1656 10 0.0741098896 ( 3.6511356831 -5.5201601982 4.092941761 ) - weight 1657 17 0.4465885162 ( -9.0268068314 3.9417405128 -0.3687389195 ) - weight 1658 22 0.0773920044 ( -9.0574798584 -12.5308570862 -0.4144083261 ) - weight 1659 21 0.0899846405 ( -4.8051199913 -10.2121315002 -7.2081561089 ) - weight 1660 19 0.1617535204 ( -9.0574798584 -4.684984684 0.6885805726 ) - weight 1661 3 0.1532055885 ( -8.3290700912 3.938873291 -5.1523947716 ) - weight 1662 10 0.1211145446 ( 6.6533036232 -5.4232931137 2.1218986511 ) - weight 1663 17 0.4891269803 ( -8.4997406006 4.3336753845 -3.9008767605 ) - weight 1664 22 0.0722299516 ( -8.3290700912 -13.0014877319 -3.9008584023 ) - weight 1665 19 0.1643228531 ( -8.3290700912 -5.4602313042 -2.7430109978 ) - weight 1666 3 0.205977872 ( -9.7783403397 2.6523742676 -2.0264546871 ) - weight 1667 10 0.1332240999 ( 4.2521457672 -3.6953341961 4.3072052002 ) - weight 1668 17 0.5380318761 ( -9.7671737671 2.3131203651 -1.1012449265 ) - weight 1669 19 0.1227661818 ( -9.7783403397 -6.4670004845 0.4839066565 ) - weight 1670 3 0.1670063883 ( -8.80286026 3.8830032349 -0.3657348454 ) - weight 1671 18 0.0519815423 ( -8.7211036682 1.4558639526 -6.9175462723 ) - weight 1672 10 0.0744365007 ( 2.3476798534 -4.955722332 4.2153868675 ) - weight 1673 17 0.4485567212 ( -8.6979665756 3.1215209961 0.7500480413 ) - weight 1674 22 0.0554484949 ( -8.80286026 -13.0573577881 0.8858016133 ) - weight 1675 21 0.09038122 ( -4.5505003929 -10.7386322021 -5.9079461098 ) - weight 1676 19 0.1121891439 ( -8.80286026 -5.0951676369 2.0300347805 ) - weight 1677 3 0.2443086207 ( -9.6978797913 1.7875518799 -0.7430948019 ) - weight 1678 10 0.2439871728 ( 3.0278429985 -2.7698793411 4.521727562 ) - weight 1679 17 0.451274693 ( -9.6131734848 1.166189909 -0.0705952868 ) - weight 1680 19 0.0604295172 ( -9.6978797913 -7.2156767845 1.8383123875 ) - weight 1681 3 0.1979502738 ( -8.1422700882 1.0664329529 -5.3806447983 ) - weight 1682 10 0.2352806181 ( 6.8131690025 -2.6473317146 1.3431911469 ) - weight 1683 17 0.4768299162 ( -8.3263521194 1.6033408642 -4.8245196342 ) - weight 1684 19 0.0899391696 ( -8.1422700882 -8.3416166306 -2.7179079056 ) - weight 1685 10 0.4768120944 ( 7.5413513184 20.0036678314 -1.979749918 ) - weight 1686 11 0.5231878757 ( 1.0549999475 0.6948249936 4.9405760765 ) - weight 1687 10 0.3322874904 ( 6.1768097878 19.8567237854 -4.9058022499 ) - weight 1688 11 0.6677125096 ( 3.7198712826 0.6573489904 3.1123518944 ) - weight 1689 10 0.6370584965 ( 6.108355999 19.6145515442 0.7061774135 ) - weight 1690 11 0.3629415035 ( -1.712595582 -0.3519669473 4.1258769035 ) - weight 1691 10 0.3658836484 ( 5.2392063141 21.9119815826 0.7746920586 ) - weight 1692 11 0.6341163516 ( -2.3030421734 1.6754959822 2.8692667484 ) - weight 1693 3 0.157916829 ( -7.0973801613 3.7977333069 -7.1476049423 ) - weight 1694 10 0.114159368 ( 8.0812559128 -5.6324548721 0.2685103714 ) - weight 1695 17 0.5533049703 ( -7.384619236 4.6936540604 -5.9367456436 ) - weight 1696 19 0.17461887 ( -7.0973801613 -5.7761917114 -4.7180938721 ) - weight 1697 3 0.1128543392 ( -3.2787399292 2.754032135 -7.8051748276 ) - weight 1698 17 0.5744569898 ( -3.6100244522 3.8916866779 -7.0381121635 ) - weight 1699 22 0.0647919625 ( -3.2787399292 -14.1863288879 -6.5536384583 ) - weight 1700 19 0.247896716 ( -3.2787399292 -6.873650074 -5.2813839912 ) - weight 1701 3 0.2760951817 ( -8.8229598999 0.9508743286 1.9491151571 ) - weight 1702 18 0.0683797002 ( -8.7412033081 -1.4762649536 -4.6026964188 ) - weight 1703 10 0.2809245884 ( 0.2042228431 -1.9094734192 4.5022215843 ) - weight 1704 17 0.3746004701 ( -8.585146904 -0.2813195586 2.287664175 ) - weight 1705 3 0.2091381103 ( -8.3410196304 3.8580245972 2.0640451908 ) - weight 1706 18 0.0578273088 ( -8.2592630386 1.4308853149 -4.4877662659 ) - weight 1707 10 0.2564762831 ( -0.0875009373 -4.8411545753 4.6331443787 ) - weight 1708 17 0.3407048285 ( -8.0974035263 2.5192096233 3.0726106167 ) - weight 1709 22 0.0526650846 ( -8.3410196304 -13.0823364258 3.3155817986 ) - weight 1710 19 0.0831884444 ( -8.3410196304 -4.9064865112 4.452606678 ) - weight 1711 3 0.2438114733 ( -8.2908096313 0.0431938171 -2.8124547005 ) - weight 1712 10 0.3932131827 ( 4.4699811935 -1.4380733967 2.1869013309 ) - weight 1713 17 0.3629753292 ( -8.3272171021 -0.0095583769 -2.5743553638 ) - weight 1714 10 0.7142977715 ( -0.7784221768 17.4169845581 1.4984173775 ) - weight 1715 11 0.2857022882 ( -3.1627964973 -4.0579161644 -1.9607902765 ) - weight 1716 10 0.7250627875 ( 7.9292492867 18.1019077301 -1.4517472982 ) - weight 1717 11 0.2749372125 ( 0.9238523841 -1.1335878372 5.7686171532 ) - weight 1718 3 0.0556513965 ( -4.4196300507 -17.8060760498 -6.3857645988 ) - weight 1719 10 0.8697622418 ( 6.5145921707 15.2011985779 -5.8942613602 ) - weight 1720 11 0.0745863691 ( 5.5258340836 -3.6403775215 4.1287770271 ) - weight 1721 10 0.4262295961 ( 1.060913682 20.6967353821 -4.574203968 ) - weight 1722 11 0.5737704039 ( 2.4720335007 0.3311256468 -1.9199882746 ) - weight 1723 11 1 ( 1.2448385954 11.4847688675 4.1571531296 ) - weight 1724 11 1 ( 0.0975800231 14.5688514709 2.2312130928 ) - weight 1725 11 1 ( 2.3691306114 15.5590848923 1.9129484892 ) - weight 1726 11 1 ( 2.36318326 14.4549503326 -0.3862571418 ) - weight 1727 11 1 ( 2.050075531 13.9478540421 -2.4394385815 ) - weight 1728 11 1 ( -2.1530103683 14.2352638245 1.9857937098 ) - weight 1729 11 1 ( 1.0403044224 4.2168512344 5.5520019531 ) - weight 1730 11 1 ( -0.9705165625 4.0557317734 4.7129735947 ) - weight 1731 11 1 ( -0.1453182399 9.096411705 5.2314667702 ) - weight 1732 11 1 ( 4.3309102058 12.6585798264 0.3260489404 ) - weight 1733 11 1 ( 1.5846595764 13.0921831131 -2.6524586678 ) - weight 1734 14 0.475073725 ( -1.2109595537 1.9283863306 1.9614709616 ) - weight 1735 13 0.5249262452 ( -1.2609685659 6.9606413841 1.9680178165 ) - weight 1736 3 0.1840003878 ( -6.9930300713 0.7581634521 -7.7029747963 ) - weight 1737 10 0.120524399 ( 8.5769367218 -2.7008779049 -0.5791134834 ) - weight 1738 17 0.5841546655 ( -7.3123226166 1.8786582947 -7.2130222321 ) - weight 1739 19 0.111320518 ( -6.9930300713 -8.8528118134 -5.004155159 ) - weight 1740 3 0.162272796 ( -4.1420898438 -4.9105262756 -6.0743045807 ) - weight 1741 10 0.7515007854 ( 6.0669741631 2.499464035 -3.6728162766 ) - weight 1742 17 0.0862264261 ( -4.3725886345 -3.9753639698 -7.1595687866 ) - weight 1743 40 0.0791042745 ( 2.4411902428 -2.8426101208 1.5174713135 ) - weight 1744 41 0.7689301968 ( -2.4230225086 1.1901230812 3.0290198326 ) - weight 1745 22 0.1519655436 ( -10.0623703003 3.7397956848 -2.5378184319 ) - weight 1746 40 0.0786700621 ( 2.0081095695 -3.7371900082 0.0158233643 ) - weight 1747 41 0.8028289676 ( -0.8784660697 1.6715497971 3.8198120594 ) - weight 1748 22 0.1185009629 ( -9.6292896271 2.2381477356 -3.4323983192 ) - weight 1749 11 1 ( 2.7587761879 17.1730937958 2.1343634129 ) - weight 1750 10 0.5477317572 ( 3.4915723801 19.9798069 2.1250095367 ) - weight 1751 11 0.4522682428 ( -3.5560090542 -0.7504063845 1.7941125631 ) - weight 1752 10 0.4552030265 ( -0.9287635088 19.7950229645 -2.8882491589 ) - weight 1753 11 0.5447970033 ( 0.6800063848 -1.195112586 -3.3599817753 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} diff --git a/base/animation/mp_suit.md5mesh b/base/animation/mp_suit.md5mesh deleted file mode 100644 index eb4b1df11..000000000 --- a/base/animation/mp_suit.md5mesh +++ /dev/null @@ -1,6446 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:29 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_suit.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh suitmesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} - -mesh { - // meshes: suitmesh - shader "models/characters/male_npc/suit/suit" - - numverts 645 - vert 0 ( 0.8851889968 0.8249670267 ) 0 3 - vert 1 ( 0.9167770147 0.9147850275 ) 3 3 - vert 2 ( 0.9290639758 0.8345429897 ) 6 2 - vert 3 ( 0.633020997 0.6062430143 ) 8 2 - vert 4 ( 0.6279270053 0.6710920334 ) 10 2 - vert 5 ( 0.7075179815 0.6906809807 ) 12 2 - vert 6 ( 0.7152150273 0.6038039923 ) 14 3 - vert 7 ( 0.8113960028 0.5987670422 ) 17 3 - vert 8 ( 0.7982649803 0.6073759794 ) 20 2 - vert 9 ( 0.8745399714 0.622206986 ) 22 2 - vert 10 ( 0.7648239732 0.579185009 ) 24 3 - vert 11 ( 0.7108520269 0.5627390146 ) 27 4 - vert 12 ( 0.7324820161 0.5867669582 ) 0 3 - vert 13 ( 0.932197988 0.7495700121 ) 20 2 - vert 14 ( 0.9878820181 0.890460968 ) 14 3 - vert 15 ( 0.9349120259 0.6673409939 ) 22 2 - vert 16 ( 0.9803060293 0.6969209909 ) 31 3 - vert 17 ( 0.9712280035 0.640410006 ) 34 3 - vert 18 ( 0.8932440281 0.9510400295 ) 37 2 - vert 19 ( 0.8684700131 0.9948850274 ) 10 2 - vert 20 ( 0.9479979873 0.9782099724 ) 8 2 - vert 21 ( 0.8667160273 0.6727199554 ) 39 3 - vert 22 ( 0.8237410188 0.7295470238 ) 42 3 - vert 23 ( 0.8402420282 0.7758100033 ) 45 3 - vert 24 ( 0.683431983 0.5801969767 ) 42 3 - vert 25 ( 0.6725640297 0.5599319935 ) 48 3 - vert 26 ( 0.6523110271 0.593569994 ) 45 3 - vert 27 ( 0.9897819757 0.6107109785 ) 45 3 - vert 28 ( 0.9900910258 0.5969679952 ) 51 3 - vert 29 ( 0.9202200174 0.6185719967 ) 54 2 - vert 30 ( 0.8585289717 0.9232029915 ) 39 3 - vert 31 ( 0.6288350224 0.5866290331 ) 51 3 - vert 32 ( 0.9243559837 0.6973209977 ) 12 2 - vert 33 ( 0.8195310235 0.8209300041 ) 54 2 - vert 34 ( 0.8666120172 0.8175060153 ) 34 3 - vert 35 ( 0.9273049831 0.633498013 ) 54 2 - vert 36 ( 0.9103090167 0.6286840439 ) 10 2 - vert 37 ( 0.3748750091 0.3151479959 ) 56 5 - vert 38 ( 0.2510960102 0.3575590253 ) 61 5 - vert 39 ( 0.343088001 0.3657950163 ) 66 3 - vert 40 ( 0.248428002 0.4210450053 ) 69 3 - vert 41 ( 0.2626729906 0.3087499738 ) 72 7 - vert 42 ( 0.1585620046 0.358009994 ) 79 6 - vert 43 ( 0.7007610202 0.0517129898 ) 85 2 - vert 44 ( 0.6619229913 0.0087419748 ) 87 3 - vert 45 ( 0.6571320295 0.1524789929 ) 90 2 - vert 46 ( 0.6193689704 0.0529459715 ) 92 3 - vert 47 ( 0.5928189754 0.5169570446 ) 95 4 - vert 48 ( 0.4749259949 0.5132960081 ) 99 3 - vert 49 ( 0.5486500263 0.6074789762 ) 92 3 - vert 50 ( 0.7084829807 0.1954429746 ) 102 1 - vert 51 ( 0.7476850152 0.0802720189 ) 103 2 - vert 52 ( 0.6256279945 0.2154139876 ) 105 1 - vert 53 ( 0.9821090102 0.2825890183 ) 106 2 - vert 54 ( 0.9428480268 0.2738190293 ) 108 2 - vert 55 ( 0.926304996 0.3234940171 ) 110 2 - vert 56 ( 0.8848720193 0.3092319965 ) 112 2 - vert 57 ( 0.9194689989 0.3578289747 ) 114 1 - vert 58 ( 0.8797889948 0.3552349806 ) 115 1 - vert 59 ( 0.8046380281 0.291703999 ) 116 2 - vert 60 ( 0.7705429792 0.3359019756 ) 118 2 - vert 61 ( 0.8291239738 0.3502219915 ) 120 2 - vert 62 ( 0.8504869938 0.3203949928 ) 122 2 - vert 63 ( 0.8518949747 0.2674710155 ) 124 2 - vert 64 ( 0.9868850112 0.2257530093 ) 105 1 - vert 65 ( 0.6978790164 0.2378259897 ) 126 1 - vert 66 ( 0.6208519936 0.2722499967 ) 106 2 - vert 67 ( 0.757035017 0.2478020191 ) 127 2 - vert 68 ( 0.7521319985 0.2731570005 ) 129 2 - vert 69 ( 0.8002240062 0.2661169767 ) 131 2 - vert 70 ( 0.9527609944 0.1048169732 ) 92 3 - vert 71 ( 0.8877660036 0.2655869722 ) 133 3 - vert 72 ( 0.9194560051 0.431253016 ) 136 1 - vert 73 ( 0.8858140111 0.437146008 ) 137 1 - vert 74 ( 0.9185770154 0.4885470271 ) 138 1 - vert 75 ( 0.9639430046 0.4419720173 ) 139 1 - vert 76 ( 0.9666029811 0.3753240108 ) 140 2 - vert 77 ( 0.8288000226 0.4139400125 ) 142 1 - vert 78 ( 0.8236029744 0.5281270146 ) 143 1 - vert 79 ( 0.7994019985 0.4632459879 ) 144 1 - vert 80 ( 0.7240790129 0.5179449916 ) 145 1 - vert 81 ( 0.8661630154 0.4761840105 ) 146 1 - vert 82 ( 0.8763030171 0.5435949564 ) 147 1 - vert 83 ( 0.9247879982 0.550902009 ) 148 2 - vert 84 ( 0.9755280018 0.5506340265 ) 150 2 - vert 85 ( 0.6661750078 0.514122963 ) 152 1 - vert 86 ( 0.6026859879 0.4316329956 ) 139 1 - vert 87 ( 0.6142709851 0.5402950048 ) 150 2 - vert 88 ( 0.6816210151 0.4320870042 ) 153 1 - vert 89 ( 0.7484120131 0.437286973 ) 154 1 - vert 90 ( 0.7095559835 0.3667910099 ) 155 1 - vert 91 ( 0.8737390041 0.6100530028 ) 156 2 - vert 92 ( 0.2043370008 0.9363080263 ) 158 1 - vert 93 ( 0.1917700022 0.9874539971 ) 159 1 - vert 94 ( 0.2633219957 0.9902449846 ) 160 2 - vert 95 ( 0.2603709996 0.9215610027 ) 162 2 - vert 96 ( 0.5906730294 0.3194029927 ) 164 3 - vert 97 ( 0.4789839983 0.3158739805 ) 167 3 - vert 98 ( 0.5928189754 0.3614609838 ) 170 3 - vert 99 ( 0.4638589919 0.3632079959 ) 173 4 - vert 100 ( 0.3933829963 0.2314299941 ) 177 4 - vert 101 ( 0.3337610066 0.2654590011 ) 181 4 - vert 102 ( 0.4113320112 0.2756440043 ) 185 3 - vert 103 ( 0.4921709895 0.2166209817 ) 188 4 - vert 104 ( 0.2187130004 0.899075985 ) 192 1 - vert 105 ( 0.2690410018 0.8628900051 ) 193 2 - vert 106 ( 0.1635289937 0.9143019915 ) 195 2 - vert 107 ( 0.1683640033 0.9854789972 ) 197 1 - vert 108 ( 0.1685930043 0.6515290141 ) 197 1 - vert 109 ( 0.183961004 0.6999030113 ) 198 1 - vert 110 ( 0.1921020001 0.6548619866 ) 159 1 - vert 111 ( 0.2800259888 0.1394820213 ) 199 6 - vert 112 ( 0.2225950062 0.1793789864 ) 205 4 - vert 113 ( 0.2875019908 0.2022629976 ) 209 5 - vert 114 ( 0.0627510026 0.8454350233 ) 214 4 - vert 115 ( 0.1106910035 0.8663179874 ) 218 4 - vert 116 ( 0.1359120011 0.8428989649 ) 222 3 - vert 117 ( 0.3136300147 0.1859080195 ) 225 4 - vert 118 ( 0.3304409981 0.2094860077 ) 229 4 - vert 119 ( 0.3729789853 0.1901649833 ) 233 4 - vert 120 ( 0.2999300063 0.8250650167 ) 237 2 - vert 121 ( 0.2727189958 0.799405992 ) 239 2 - vert 122 ( 0.2603009939 0.7136909962 ) 241 2 - vert 123 ( 0.2954480052 0.7122550011 ) 243 2 - vert 124 ( 0.263936013 0.6731899977 ) 160 2 - vert 125 ( 0.2846580148 0.9553740025 ) 245 2 - vert 126 ( 0.2911350131 0.9950889945 ) 247 2 - vert 127 ( 0.2938460112 0.9138000011 ) 249 2 - vert 128 ( 0.2402170002 0.80576998 ) 251 1 - vert 129 ( 0.2677659988 0.7409399748 ) 252 2 - vert 130 ( 0.2038889974 0.7419040203 ) 254 1 - vert 131 ( 0.2918660045 0.681499958 ) 247 2 - vert 132 ( 0.2776469886 0.2314630151 ) 255 4 - vert 133 ( 0.1722279936 0.216489017 ) 259 4 - vert 134 ( 0.1251160055 0.1187459826 ) 263 5 - vert 135 ( 0.0528450012 0.1990990043 ) 268 5 - vert 136 ( 0.5906730294 0.1368719935 ) 273 5 - vert 137 ( 0.4879179895 0.1192910075 ) 278 5 - vert 138 ( 0.4301300049 0.1652190089 ) 283 5 - vert 139 ( 0.0438820012 0.1111990213 ) 288 4 - vert 140 ( 0.1489060074 0.8846759796 ) 292 3 - vert 141 ( 0.111270003 0.9061470032 ) 199 6 - vert 142 ( 0.1432790011 0.9405339956 ) 225 4 - vert 143 ( 0.1273680031 0.9811329842 ) 233 4 - vert 144 ( 0.1274189949 0.6441459656 ) 233 4 - vert 145 ( 0.1018000022 0.7043390274 ) 295 3 - vert 146 ( 0.5450130105 0.0130950212 ) 298 4 - vert 147 ( 0.4139760137 0.0072669983 ) 302 3 - vert 148 ( 0.4659610093 0.0620489717 ) 305 3 - vert 149 ( 0.0793519989 0.6812579632 ) 283 5 - vert 150 ( 0.6053469777 0.3649849892 ) 140 2 - vert 151 ( 0.8663030267 0.0902959704 ) 308 2 - vert 152 ( 0.2387440056 0.1259409785 ) 310 4 - vert 153 ( 0.1477479935 0.2995790243 ) 314 6 - vert 154 ( 0.0602619983 0.3586530089 ) 320 5 - vert 155 ( 0.0577390008 0.3033360243 ) 325 5 - vert 156 ( 0.2883780003 0.5109490156 ) 330 2 - vert 157 ( 0.2241510004 0.5268880129 ) 332 2 - vert 158 ( 0.0755100027 0.8883000016 ) 334 4 - vert 159 ( 0.3054459989 0.0682489872 ) 338 4 - vert 160 ( 0.2569029927 0.0817170143 ) 342 3 - vert 161 ( 0.2879140079 0.0959659815 ) 334 4 - vert 162 ( 0.9253529906 0.6038390398 ) 345 2 - vert 163 ( 0.8402969837 0.6819820404 ) 34 3 - vert 164 ( 0.843535006 0.6373449564 ) 31 3 - vert 165 ( 0.7736589909 0.6870989799 ) 347 3 - vert 166 ( 0.8996700048 0.768558979 ) 347 3 - vert 167 ( 0.7821429968 0.6192190051 ) 350 3 - vert 168 ( 0.9902340174 0.7758809924 ) 350 3 - vert 169 ( 0.3528459966 0.465354979 ) 353 3 - vert 170 ( 0.3678930104 0.5143569708 ) 356 2 - vert 171 ( 0.4353789985 0.1116790175 ) 358 4 - vert 172 ( 0.0435540006 0.7115600109 ) 358 4 - vert 173 ( 0.062804997 0.7602419853 ) 362 3 - vert 174 ( 0.4038980007 0.0865809917 ) 365 4 - vert 175 ( 0.0159210004 0.7509840131 ) 365 4 - vert 176 ( 0.0442270003 0.8014060259 ) 369 4 - vert 177 ( 0.3621050119 0.0647630095 ) 373 4 - vert 178 ( 0.0077530001 0.8201950192 ) 373 4 - vert 179 ( 0.4858529866 0.2773119807 ) 377 3 - vert 180 ( 0.5906730294 0.2790259719 ) 380 3 - vert 181 ( 0.5906730294 0.2272719741 ) 383 3 - vert 182 ( 0.8384780288 0.8386750221 ) 42 3 - vert 183 ( 0.5007230043 0.8608759642 ) 386 1 - vert 184 ( 0.4004510045 0.8904989958 ) 387 1 - vert 185 ( 0.4774749875 0.898590982 ) 388 3 - vert 186 ( 0.4339909852 0.8469029665 ) 391 1 - vert 187 ( 0.5118749738 0.8208619952 ) 392 1 - vert 188 ( 0.4504519999 0.8016870022 ) 393 1 - vert 189 ( 0.519701004 0.7612500191 ) 394 1 - vert 190 ( 0.3528000116 0.7389389873 ) 395 1 - vert 191 ( 0.4434280097 0.7510669827 ) 396 1 - vert 192 ( 0.4215759933 0.7003450394 ) 397 1 - vert 193 ( 0.5172349811 0.7290819883 ) 398 1 - vert 194 ( 0.3455109894 0.7057470083 ) 399 1 - vert 195 ( 0.4768890142 0.9415969849 ) 400 1 - vert 196 ( 0.4011979997 0.933701992 ) 401 1 - vert 197 ( 0.4865309894 0.9777920246 ) 402 1 - vert 198 ( 0.5926210284 0.8259350061 ) 403 1 - vert 199 ( 0.570964992 0.8845490217 ) 404 2 - vert 200 ( 0.5789020061 0.8460580111 ) 406 2 - vert 201 ( 0.7997699976 0.9733999968 ) 408 3 - vert 202 ( 0.756724 0.9381579757 ) 411 3 - vert 203 ( 0.7890049815 0.9327999949 ) 406 2 - vert 204 ( 0.6045969725 0.8296480179 ) 414 2 - vert 205 ( 0.8025349975 0.8614699841 ) 403 1 - vert 206 ( 0.7491949797 0.9943079948 ) 416 2 - vert 207 ( 0.6942149997 0.9865270257 ) 418 1 - vert 208 ( 0.7694820166 0.828707993 ) 419 2 - vert 209 ( 0.8027639985 0.8125270009 ) 421 2 - vert 210 ( 0.7869669795 0.8019449711 ) 423 2 - vert 211 ( 0.5959810019 0.7842389941 ) 421 2 - vert 212 ( 0.6046180129 0.7234239578 ) 425 2 - vert 213 ( 0.6153159738 0.7025020123 ) 427 2 - vert 214 ( 0.8136299849 0.7713860273 ) 425 2 - vert 215 ( 0.7985380292 0.7631790042 ) 429 2 - vert 216 ( 0.6761140227 0.733044982 ) 431 3 - vert 217 ( 0.6491540074 0.7684370279 ) 434 3 - vert 218 ( 0.6686120033 0.7034319639 ) 437 2 - vert 219 ( 0.6734960079 0.9662230015 ) 439 1 - vert 220 ( 0.700568974 0.8474110365 ) 440 3 - vert 221 ( 0.7166720033 0.7589269876 ) 443 3 - vert 222 ( 0.74871701 0.7289980054 ) 446 2 - vert 223 ( 0.7685890198 0.7389019728 ) 437 2 - vert 224 ( 0.7017890215 0.775538981 ) 448 3 - vert 225 ( 0.7011880279 0.7465590239 ) 443 3 - vert 226 ( 0.6883950233 0.7056699991 ) 446 2 - vert 227 ( 0.6925330162 0.8118289709 ) 451 3 - vert 228 ( 0.6550170183 0.7908899784 ) 454 3 - vert 229 ( 0.6797599792 0.8512650132 ) 457 3 - vert 230 ( 0.707852006 0.8104299903 ) 460 3 - vert 231 ( 0.6074820161 0.7819190025 ) 463 2 - vert 232 ( 0.6490619779 0.9733939767 ) 465 1 - vert 233 ( 0.6052020192 0.9690830112 ) 466 2 - vert 234 ( 0.6357730031 0.8398550153 ) 468 2 - vert 235 ( 0.5714309812 0.828256011 ) 470 2 - vert 236 ( 0.5528270006 0.8322100043 ) 472 2 - vert 237 ( 0.5588089824 0.7859380245 ) 474 2 - vert 238 ( 0.5543259978 0.8860200047 ) 476 3 - vert 239 ( 0.5358489752 0.8347740173 ) 479 2 - vert 240 ( 0.5730850101 0.793734014 ) 481 2 - vert 241 ( 0.5840579867 0.8170059919 ) 483 2 - vert 242 ( 0.8161879778 0.8996319771 ) 481 2 - vert 243 ( 0.8266770244 0.8883939981 ) 474 2 - vert 244 ( 0.8267859817 0.9110990167 ) 485 2 - vert 245 ( 0.5714660287 0.952252984 ) 487 2 - vert 246 ( 0.5482320189 0.9537770152 ) 489 1 - vert 247 ( 0.5351210237 0.9507679939 ) 416 2 - vert 248 ( 0.5381690264 0.8871129751 ) 408 3 - vert 249 ( 0.818508029 0.9463310242 ) 479 2 - vert 250 ( 0.8036159873 0.9287400246 ) 483 2 - vert 251 ( 0.6376190186 0.781965971 ) 423 2 - vert 252 ( 0.6241390109 0.782755971 ) 490 2 - vert 253 ( 0.6422780156 0.7077629566 ) 429 2 - vert 254 ( 0.6305840015 0.7032589912 ) 492 2 - vert 255 ( 0.6214889884 0.8390759826 ) 494 2 - vert 256 ( 0.6353539824 0.8060629964 ) 419 2 - vert 257 ( 0.5176740289 0.8607789874 ) 466 2 - vert 258 ( 0.528603971 0.8226339817 ) 465 1 - vert 259 ( 0.5028409958 0.8987259865 ) 487 2 - vert 260 ( 0.5392010212 0.7466000319 ) 439 1 - vert 261 ( 0.5311419964 0.6905180216 ) 418 1 - vert 262 ( 0.5001900196 0.6796820164 ) 402 1 - vert 263 ( 0.5029720068 0.9707750082 ) 418 1 - vert 264 ( 0.4968389869 0.941429019 ) 416 2 - vert 265 ( 0.4974350035 0.9217699766 ) 489 1 - vert 266 ( 0.8029379845 0.7442569733 ) 492 2 - vert 267 ( 0.8184109926 0.7529680133 ) 427 2 - vert 268 ( 0.6204379797 0.7389010191 ) 496 2 - vert 269 ( 0.7697860003 0.7841470242 ) 434 3 - vert 270 ( 0.0282600001 0.8698080182 ) 338 4 - vert 271 ( 0.7053009868 0.2735130191 ) 498 2 - vert 272 ( 0.7590960264 0.2977690101 ) 500 2 - vert 273 ( 0.6963999867 0.2978109717 ) 502 2 - vert 274 ( 0.5461469889 0.7879520059 ) 485 2 - vert 275 ( 0.1138980016 0.8113780022 ) 504 3 - vert 276 ( 0.1950599998 0.120085001 ) 507 4 - vert 277 ( 0.2171940058 0.0655140281 ) 511 3 - vert 278 ( 0.2862679958 0.0446400046 ) 514 3 - vert 279 ( 0.1988579929 0.0277220011 ) 517 3 - vert 280 ( 0.3032990098 0.009904027 ) 520 3 - vert 281 ( 0.370352 0.0401480198 ) 523 3 - vert 282 ( 0.4060660005 0.9733899832 ) 397 1 - vert 283 ( 0.3027069867 0.7717610002 ) 526 2 - vert 284 ( 0.3240619898 0.7848359942 ) 528 2 - vert 285 ( 0.3004209995 0.7371799946 ) 530 2 - vert 286 ( 0.3276099861 0.7369199991 ) 532 2 - vert 287 ( 0.3222169876 0.9879009724 ) 534 2 - vert 288 ( 0.3231050074 0.6688380241 ) 534 2 - vert 289 ( 0.3229289949 0.7101849914 ) 536 2 - vert 290 ( 0.109232001 0.7468780279 ) 538 3 - vert 291 ( 0.1181280017 0.0632529855 ) 541 3 - vert 292 ( 0.1088190004 0.0349550247 ) 544 3 - vert 293 ( 0.0400529988 0.0509030223 ) 547 5 - vert 294 ( 0.0050969999 0.2059280276 ) 552 6 - vert 295 ( 0.0050969999 0.1247289777 ) 558 4 - vert 296 ( 0.0050969999 0.2996760011 ) 562 5 - vert 297 ( 0.0050969999 0.3579769731 ) 567 5 - vert 298 ( 0.0050969999 0.4193829894 ) 572 4 - vert 299 ( 0.0510179996 0.4332749844 ) 576 4 - vert 300 ( 0.0643810034 0.4337900281 ) 580 4 - vert 301 ( 0.1606809944 0.4493049979 ) 584 4 - vert 302 ( 0.1704750061 0.5299440026 ) 588 2 - vert 303 ( 0.0877180025 0.5262299776 ) 590 3 - vert 304 ( 0.0485789999 0.5306900144 ) 85 2 - vert 305 ( 0.1740169972 0.542445004 ) 103 2 - vert 306 ( 0.0957330018 0.5882369876 ) 85 2 - vert 307 ( 0.2881439924 0.5212010145 ) 593 1 - vert 308 ( 0.224999994 0.5377570391 ) 594 2 - vert 309 ( 0.9119070172 0.0950769782 ) 596 3 - vert 310 ( 0.4764350057 0.5484700203 ) 596 3 - vert 311 ( 0.4667449892 0.4496610165 ) 599 3 - vert 312 ( 0.5867260098 0.6067939997 ) 602 4 - vert 313 ( 0.5497019887 0.6853179932 ) 87 3 - vert 314 ( 0.5662999749 0.6798570156 ) 606 3 - vert 315 ( 0.0050969999 0.5013149977 ) 609 4 - vert 316 ( 0.5928189754 0.4565629959 ) 613 5 - vert 317 ( 0.4612129927 0.4114339948 ) 618 3 - vert 318 ( 0.3372229934 0.4129520059 ) 621 3 - vert 319 ( 0.5928189754 0.4105759859 ) 624 5 - vert 320 ( 0.3611760139 0.5333570242 ) 308 2 - vert 321 ( 0.0182460006 0.5993820429 ) 606 3 - vert 322 ( 0.0385180004 0.5988340378 ) 87 3 - vert 323 ( 0.7916830182 0.2140489817 ) 629 1 - vert 324 ( 0.8271239996 0.0890780091 ) 593 1 - vert 325 ( 0.7825430036 0.0837159753 ) 594 2 - vert 326 ( 0.752662003 0.2067930102 ) 630 2 - vert 327 ( 0.9167770147 0.9147850275 ) 632 3 - vert 328 ( 0.8851889968 0.8249670267 ) 635 3 - vert 329 ( 0.9290639758 0.8345429897 ) 638 2 - vert 330 ( 0.6279270053 0.6710920334 ) 640 2 - vert 331 ( 0.633020997 0.6062430143 ) 642 2 - vert 332 ( 0.7075179815 0.6906809807 ) 644 2 - vert 333 ( 0.7152150273 0.6038039923 ) 646 3 - vert 334 ( 0.7982649803 0.6073759794 ) 649 2 - vert 335 ( 0.8113960028 0.5987670422 ) 651 3 - vert 336 ( 0.8745399714 0.622206986 ) 654 2 - vert 337 ( 0.7648239732 0.579185009 ) 656 3 - vert 338 ( 0.7108520269 0.5627390146 ) 659 4 - vert 339 ( 0.7324820161 0.5867669582 ) 635 3 - vert 340 ( 0.932197988 0.7495700121 ) 649 2 - vert 341 ( 0.9878820181 0.890460968 ) 646 3 - vert 342 ( 0.9349120259 0.6673409939 ) 654 2 - vert 343 ( 0.9803060293 0.6969209909 ) 663 3 - vert 344 ( 0.9712280035 0.640410006 ) 666 3 - vert 345 ( 0.8684700131 0.9948850274 ) 640 2 - vert 346 ( 0.8932440281 0.9510400295 ) 669 2 - vert 347 ( 0.9479979873 0.9782099724 ) 642 2 - vert 348 ( 0.8237410188 0.7295470238 ) 671 3 - vert 349 ( 0.8667160273 0.6727199554 ) 674 3 - vert 350 ( 0.8402420282 0.7758100033 ) 677 3 - vert 351 ( 0.6725640297 0.5599319935 ) 680 3 - vert 352 ( 0.683431983 0.5801969767 ) 671 3 - vert 353 ( 0.6523110271 0.593569994 ) 677 3 - vert 354 ( 0.9900910258 0.5969679952 ) 683 3 - vert 355 ( 0.9897819757 0.6107109785 ) 677 3 - vert 356 ( 0.9202200174 0.6185719967 ) 686 2 - vert 357 ( 0.8585289717 0.9232029915 ) 674 3 - vert 358 ( 0.6288350224 0.5866290331 ) 683 3 - vert 359 ( 0.9243559837 0.6973209977 ) 644 2 - vert 360 ( 0.8195310235 0.8209300041 ) 686 2 - vert 361 ( 0.8666120172 0.8175060153 ) 666 3 - vert 362 ( 0.9273049831 0.633498013 ) 686 2 - vert 363 ( 0.9103090167 0.6286840439 ) 640 2 - vert 364 ( 0.2510960102 0.3575590253 ) 688 5 - vert 365 ( 0.3748750091 0.3151479959 ) 693 5 - vert 366 ( 0.343088001 0.3657950163 ) 698 3 - vert 367 ( 0.248428002 0.4210450053 ) 701 3 - vert 368 ( 0.2626729906 0.3087499738 ) 704 7 - vert 369 ( 0.1585620046 0.358009994 ) 711 6 - vert 370 ( 0.6619229913 0.0087419748 ) 717 3 - vert 371 ( 0.7007610202 0.0517129898 ) 720 2 - vert 372 ( 0.6571320295 0.1524789929 ) 722 2 - vert 373 ( 0.6193689704 0.0529459715 ) 724 3 - vert 374 ( 0.4749259949 0.5132960081 ) 727 3 - vert 375 ( 0.5486500263 0.6074789762 ) 724 3 - vert 376 ( 0.7084829807 0.1954429746 ) 730 1 - vert 377 ( 0.7476850152 0.0802720189 ) 731 2 - vert 378 ( 0.6256279945 0.2154139876 ) 733 1 - vert 379 ( 0.9428480268 0.2738190293 ) 734 2 - vert 380 ( 0.9821090102 0.2825890183 ) 736 2 - vert 381 ( 0.926304996 0.3234940171 ) 738 2 - vert 382 ( 0.8848720193 0.3092319965 ) 740 2 - vert 383 ( 0.9194689989 0.3578289747 ) 742 1 - vert 384 ( 0.8797889948 0.3552349806 ) 743 1 - vert 385 ( 0.7705429792 0.3359019756 ) 744 2 - vert 386 ( 0.8046380281 0.291703999 ) 746 2 - vert 387 ( 0.8291239738 0.3502219915 ) 748 2 - vert 388 ( 0.8504869938 0.3203949928 ) 750 2 - vert 389 ( 0.8518949747 0.2674710155 ) 752 2 - vert 390 ( 0.9868850112 0.2257530093 ) 733 1 - vert 391 ( 0.6978790164 0.2378259897 ) 754 1 - vert 392 ( 0.6208519936 0.2722499967 ) 736 2 - vert 393 ( 0.757035017 0.2478020191 ) 755 2 - vert 394 ( 0.7521319985 0.2731570005 ) 757 2 - vert 395 ( 0.8002240062 0.2661169767 ) 759 2 - vert 396 ( 0.8877660036 0.2655869722 ) 761 3 - vert 397 ( 0.9527609944 0.1048169732 ) 724 3 - vert 398 ( 0.8858140111 0.437146008 ) 764 1 - vert 399 ( 0.9194560051 0.431253016 ) 765 1 - vert 400 ( 0.9185770154 0.4885470271 ) 766 1 - vert 401 ( 0.9639430046 0.4419720173 ) 767 1 - vert 402 ( 0.9666029811 0.3753240108 ) 768 2 - vert 403 ( 0.8288000226 0.4139400125 ) 770 1 - vert 404 ( 0.7994019985 0.4632459879 ) 771 1 - vert 405 ( 0.8236029744 0.5281270146 ) 772 1 - vert 406 ( 0.7240790129 0.5179449916 ) 773 1 - vert 407 ( 0.8661630154 0.4761840105 ) 774 1 - vert 408 ( 0.8763030171 0.5435949564 ) 775 1 - vert 409 ( 0.9247879982 0.550902009 ) 776 2 - vert 410 ( 0.9755280018 0.5506340265 ) 778 2 - vert 411 ( 0.6026859879 0.4316329956 ) 767 1 - vert 412 ( 0.6661750078 0.514122963 ) 780 1 - vert 413 ( 0.6142709851 0.5402950048 ) 778 2 - vert 414 ( 0.6816210151 0.4320870042 ) 781 1 - vert 415 ( 0.7484120131 0.437286973 ) 782 1 - vert 416 ( 0.7095559835 0.3667910099 ) 783 1 - vert 417 ( 0.8737390041 0.6100530028 ) 784 2 - vert 418 ( 0.1917700022 0.9874539971 ) 786 1 - vert 419 ( 0.2043370008 0.9363080263 ) 787 1 - vert 420 ( 0.2633219957 0.9902449846 ) 788 2 - vert 421 ( 0.2603709996 0.9215610027 ) 790 2 - vert 422 ( 0.4789839983 0.3158739805 ) 792 3 - vert 423 ( 0.4638589919 0.3632079959 ) 795 4 - vert 424 ( 0.3337610066 0.2654590011 ) 799 4 - vert 425 ( 0.3933829963 0.2314299941 ) 803 4 - vert 426 ( 0.4113320112 0.2756440043 ) 807 3 - vert 427 ( 0.4921709895 0.2166209817 ) 810 4 - vert 428 ( 0.2187130004 0.899075985 ) 814 1 - vert 429 ( 0.2690410018 0.8628900051 ) 815 2 - vert 430 ( 0.1683640033 0.9854789972 ) 817 1 - vert 431 ( 0.1635289937 0.9143019915 ) 818 2 - vert 432 ( 0.183961004 0.6999030113 ) 820 1 - vert 433 ( 0.1685930043 0.6515290141 ) 817 1 - vert 434 ( 0.1921020001 0.6548619866 ) 786 1 - vert 435 ( 0.2225950062 0.1793789864 ) 821 4 - vert 436 ( 0.2800259888 0.1394820213 ) 825 6 - vert 437 ( 0.2875019908 0.2022629976 ) 831 5 - vert 438 ( 0.1106910035 0.8663179874 ) 836 4 - vert 439 ( 0.0627510026 0.8454350233 ) 840 4 - vert 440 ( 0.1359120011 0.8428989649 ) 844 3 - vert 441 ( 0.3136300147 0.1859080195 ) 847 4 - vert 442 ( 0.3304409981 0.2094860077 ) 851 4 - vert 443 ( 0.3729789853 0.1901649833 ) 855 4 - vert 444 ( 0.2727189958 0.799405992 ) 859 2 - vert 445 ( 0.2999300063 0.8250650167 ) 861 2 - vert 446 ( 0.2954480052 0.7122550011 ) 863 2 - vert 447 ( 0.2603009939 0.7136909962 ) 865 2 - vert 448 ( 0.263936013 0.6731899977 ) 788 2 - vert 449 ( 0.2846580148 0.9553740025 ) 867 2 - vert 450 ( 0.2911350131 0.9950889945 ) 869 2 - vert 451 ( 0.2938460112 0.9138000011 ) 871 2 - vert 452 ( 0.2402170002 0.80576998 ) 873 1 - vert 453 ( 0.2677659988 0.7409399748 ) 874 2 - vert 454 ( 0.2038889974 0.7419040203 ) 876 1 - vert 455 ( 0.2918660045 0.681499958 ) 869 2 - vert 456 ( 0.1722279936 0.216489017 ) 877 4 - vert 457 ( 0.2776469886 0.2314630151 ) 881 4 - vert 458 ( 0.0528450012 0.1990990043 ) 885 5 - vert 459 ( 0.1251160055 0.1187459826 ) 890 5 - vert 460 ( 0.4879179895 0.1192910075 ) 895 5 - vert 461 ( 0.4301300049 0.1652190089 ) 900 5 - vert 462 ( 0.0438820012 0.1111990213 ) 905 4 - vert 463 ( 0.111270003 0.9061470032 ) 825 6 - vert 464 ( 0.1489060074 0.8846759796 ) 909 3 - vert 465 ( 0.1432790011 0.9405339956 ) 847 4 - vert 466 ( 0.1273680031 0.9811329842 ) 855 4 - vert 467 ( 0.1018000022 0.7043390274 ) 912 3 - vert 468 ( 0.1274189949 0.6441459656 ) 855 4 - vert 469 ( 0.4139760137 0.0072669983 ) 915 3 - vert 470 ( 0.4659610093 0.0620489717 ) 918 3 - vert 471 ( 0.0793519989 0.6812579632 ) 900 5 - vert 472 ( 0.6053469777 0.3649849892 ) 768 2 - vert 473 ( 0.8663030267 0.0902959704 ) 921 2 - vert 474 ( 0.2387440056 0.1259409785 ) 923 4 - vert 475 ( 0.1477479935 0.2995790243 ) 927 6 - vert 476 ( 0.0602619983 0.3586530089 ) 933 5 - vert 477 ( 0.0577390008 0.3033360243 ) 938 5 - vert 478 ( 0.2883780003 0.5109490156 ) 943 2 - vert 479 ( 0.2241510004 0.5268880129 ) 945 2 - vert 480 ( 0.0755100027 0.8883000016 ) 947 4 - vert 481 ( 0.2569029927 0.0817170143 ) 951 3 - vert 482 ( 0.3054459989 0.0682489872 ) 954 4 - vert 483 ( 0.2879140079 0.0959659815 ) 947 4 - vert 484 ( 0.9253529906 0.6038390398 ) 958 2 - vert 485 ( 0.843535006 0.6373449564 ) 663 3 - vert 486 ( 0.8402969837 0.6819820404 ) 666 3 - vert 487 ( 0.7736589909 0.6870989799 ) 960 3 - vert 488 ( 0.8996700048 0.768558979 ) 960 3 - vert 489 ( 0.7821429968 0.6192190051 ) 963 3 - vert 490 ( 0.9902340174 0.7758809924 ) 963 3 - vert 491 ( 0.3528459966 0.465354979 ) 966 3 - vert 492 ( 0.3678930104 0.5143569708 ) 969 2 - vert 493 ( 0.4353789985 0.1116790175 ) 971 4 - vert 494 ( 0.0435540006 0.7115600109 ) 971 4 - vert 495 ( 0.062804997 0.7602419853 ) 975 3 - vert 496 ( 0.4038980007 0.0865809917 ) 978 4 - vert 497 ( 0.0159210004 0.7509840131 ) 978 4 - vert 498 ( 0.0442270003 0.8014060259 ) 982 4 - vert 499 ( 0.3621050119 0.0647630095 ) 986 4 - vert 500 ( 0.0077530001 0.8201950192 ) 986 4 - vert 501 ( 0.4858529866 0.2773119807 ) 990 3 - vert 502 ( 0.8384780288 0.8386750221 ) 671 3 - vert 503 ( 0.4004510045 0.8904989958 ) 993 1 - vert 504 ( 0.5007230043 0.8608759642 ) 994 1 - vert 505 ( 0.4774749875 0.898590982 ) 995 3 - vert 506 ( 0.4339909852 0.8469029665 ) 998 1 - vert 507 ( 0.5118749738 0.8208619952 ) 999 1 - vert 508 ( 0.4504519999 0.8016870022 ) 1000 1 - vert 509 ( 0.519701004 0.7612500191 ) 1001 1 - vert 510 ( 0.3528000116 0.7389389873 ) 1002 1 - vert 511 ( 0.4434280097 0.7510669827 ) 1003 1 - vert 512 ( 0.4215759933 0.7003450394 ) 1004 1 - vert 513 ( 0.5172349811 0.7290819883 ) 1005 1 - vert 514 ( 0.3455109894 0.7057470083 ) 1006 1 - vert 515 ( 0.4011979997 0.933701992 ) 1007 1 - vert 516 ( 0.4768890142 0.9415969849 ) 1008 1 - vert 517 ( 0.4865309894 0.9777920246 ) 1009 1 - vert 518 ( 0.570964992 0.8845490217 ) 1010 2 - vert 519 ( 0.5926210284 0.8259350061 ) 1012 1 - vert 520 ( 0.5789020061 0.8460580111 ) 1013 2 - vert 521 ( 0.756724 0.9381579757 ) 1015 3 - vert 522 ( 0.7997699976 0.9733999968 ) 1018 3 - vert 523 ( 0.7890049815 0.9327999949 ) 1013 2 - vert 524 ( 0.6045969725 0.8296480179 ) 1021 1 - vert 525 ( 0.8025349975 0.8614699841 ) 1012 1 - vert 526 ( 0.6942149997 0.9865270257 ) 1022 1 - vert 527 ( 0.7491949797 0.9943079948 ) 1023 2 - vert 528 ( 0.7694820166 0.828707993 ) 1025 2 - vert 529 ( 0.8027639985 0.8125270009 ) 1027 1 - vert 530 ( 0.7869669795 0.8019449711 ) 1028 2 - vert 531 ( 0.6046180129 0.7234239578 ) 1030 2 - vert 532 ( 0.5959810019 0.7842389941 ) 1027 1 - vert 533 ( 0.6153159738 0.7025020123 ) 1032 2 - vert 534 ( 0.8136299849 0.7713860273 ) 1030 2 - vert 535 ( 0.7985380292 0.7631790042 ) 1034 2 - vert 536 ( 0.6491540074 0.7684370279 ) 1036 2 - vert 537 ( 0.6761140227 0.733044982 ) 1038 2 - vert 538 ( 0.6686120033 0.7034319639 ) 1040 2 - vert 539 ( 0.6734960079 0.9662230015 ) 1042 1 - vert 540 ( 0.700568974 0.8474110365 ) 1043 3 - vert 541 ( 0.74871701 0.7289980054 ) 1046 2 - vert 542 ( 0.7166720033 0.7589269876 ) 1048 3 - vert 543 ( 0.7685890198 0.7389019728 ) 1040 2 - vert 544 ( 0.7017890215 0.775538981 ) 1051 3 - vert 545 ( 0.7011880279 0.7465590239 ) 1048 3 - vert 546 ( 0.6883950233 0.7056699991 ) 1046 2 - vert 547 ( 0.6925330162 0.8118289709 ) 1054 3 - vert 548 ( 0.6550170183 0.7908899784 ) 1057 2 - vert 549 ( 0.6797599792 0.8512650132 ) 1059 3 - vert 550 ( 0.707852006 0.8104299903 ) 1062 3 - vert 551 ( 0.6074820161 0.7819190025 ) 1065 2 - vert 552 ( 0.6490619779 0.9733939767 ) 1067 1 - vert 553 ( 0.6052020192 0.9690830112 ) 1068 2 - vert 554 ( 0.6357730031 0.8398550153 ) 1070 2 - vert 555 ( 0.5528270006 0.8322100043 ) 1072 2 - vert 556 ( 0.5714309812 0.828256011 ) 1074 2 - vert 557 ( 0.5588089824 0.7859380245 ) 1076 2 - vert 558 ( 0.5543259978 0.8860200047 ) 1078 3 - vert 559 ( 0.5358489752 0.8347740173 ) 1081 2 - vert 560 ( 0.5730850101 0.793734014 ) 1083 2 - vert 561 ( 0.5840579867 0.8170059919 ) 1085 2 - vert 562 ( 0.8266770244 0.8883939981 ) 1076 2 - vert 563 ( 0.8161879778 0.8996319771 ) 1083 2 - vert 564 ( 0.8267859817 0.9110990167 ) 1087 2 - vert 565 ( 0.5714660287 0.952252984 ) 1089 2 - vert 566 ( 0.5351210237 0.9507679939 ) 1023 2 - vert 567 ( 0.5482320189 0.9537770152 ) 1091 1 - vert 568 ( 0.5381690264 0.8871129751 ) 1018 3 - vert 569 ( 0.818508029 0.9463310242 ) 1081 2 - vert 570 ( 0.8036159873 0.9287400246 ) 1085 2 - vert 571 ( 0.6241390109 0.782755971 ) 1092 2 - vert 572 ( 0.6376190186 0.781965971 ) 1028 2 - vert 573 ( 0.6422780156 0.7077629566 ) 1034 2 - vert 574 ( 0.6305840015 0.7032589912 ) 1094 2 - vert 575 ( 0.6214889884 0.8390759826 ) 1096 2 - vert 576 ( 0.6353539824 0.8060629964 ) 1025 2 - vert 577 ( 0.5176740289 0.8607789874 ) 1068 2 - vert 578 ( 0.528603971 0.8226339817 ) 1067 1 - vert 579 ( 0.5028409958 0.8987259865 ) 1089 2 - vert 580 ( 0.5392010212 0.7466000319 ) 1042 1 - vert 581 ( 0.5311419964 0.6905180216 ) 1022 1 - vert 582 ( 0.5001900196 0.6796820164 ) 1009 1 - vert 583 ( 0.5029720068 0.9707750082 ) 1022 1 - vert 584 ( 0.4968389869 0.941429019 ) 1023 2 - vert 585 ( 0.4974350035 0.9217699766 ) 1091 1 - vert 586 ( 0.8029379845 0.7442569733 ) 1094 2 - vert 587 ( 0.8184109926 0.7529680133 ) 1032 2 - vert 588 ( 0.6204379797 0.7389010191 ) 1098 2 - vert 589 ( 0.7697860003 0.7841470242 ) 1036 2 - vert 590 ( 0.0282600001 0.8698080182 ) 954 4 - vert 591 ( 0.7053009868 0.2735130191 ) 1100 2 - vert 592 ( 0.7590960264 0.2977690101 ) 1102 2 - vert 593 ( 0.6963999867 0.2978109717 ) 1104 2 - vert 594 ( 0.5461469889 0.7879520059 ) 1087 2 - vert 595 ( 0.1138980016 0.8113780022 ) 1106 3 - vert 596 ( 0.1950599998 0.120085001 ) 1109 4 - vert 597 ( 0.2171940058 0.0655140281 ) 1113 3 - vert 598 ( 0.2862679958 0.0446400046 ) 1116 3 - vert 599 ( 0.1988579929 0.0277220011 ) 1119 3 - vert 600 ( 0.3032990098 0.009904027 ) 1122 3 - vert 601 ( 0.370352 0.0401480198 ) 1125 3 - vert 602 ( 0.4060660005 0.9733899832 ) 1004 1 - vert 603 ( 0.3027069867 0.7717610002 ) 1128 2 - vert 604 ( 0.3240619898 0.7848359942 ) 1130 2 - vert 605 ( 0.3004209995 0.7371799946 ) 1132 2 - vert 606 ( 0.3276099861 0.7369199991 ) 1134 2 - vert 607 ( 0.3222169876 0.9879009724 ) 1136 2 - vert 608 ( 0.3231050074 0.6688380241 ) 1136 2 - vert 609 ( 0.3229289949 0.7101849914 ) 1138 2 - vert 610 ( 0.109232001 0.7468780279 ) 1140 3 - vert 611 ( 0.1181280017 0.0632529855 ) 1143 3 - vert 612 ( 0.1088190004 0.0349550247 ) 1146 3 - vert 613 ( 0.0510179996 0.4332749844 ) 1149 4 - vert 614 ( 0.0643810034 0.4337900281 ) 1153 4 - vert 615 ( 0.1606809944 0.4493049979 ) 1157 4 - vert 616 ( 0.1704750061 0.5299440026 ) 1161 2 - vert 617 ( 0.0877180025 0.5262299776 ) 1163 3 - vert 618 ( 0.0485789999 0.5306900144 ) 720 2 - vert 619 ( 0.1740169972 0.542445004 ) 731 2 - vert 620 ( 0.0957330018 0.5882369876 ) 720 2 - vert 621 ( 0.2881439924 0.5212010145 ) 1166 1 - vert 622 ( 0.224999994 0.5377570391 ) 1167 2 - vert 623 ( 0.9119070172 0.0950769782 ) 1169 3 - vert 624 ( 0.4764350057 0.5484700203 ) 1169 3 - vert 625 ( 0.4667449892 0.4496610165 ) 1172 3 - vert 626 ( 0.5497019887 0.6853179932 ) 717 3 - vert 627 ( 0.3372229934 0.4129520059 ) 1175 3 - vert 628 ( 0.4612129927 0.4114339948 ) 1178 3 - vert 629 ( 0.3611760139 0.5333570242 ) 921 2 - vert 630 ( 0.0385180004 0.5988340378 ) 717 3 - vert 631 ( 0.7916830182 0.2140489817 ) 1181 1 - vert 632 ( 0.7825430036 0.0837159753 ) 1167 2 - vert 633 ( 0.8271239996 0.0890780091 ) 1166 1 - vert 634 ( 0.752662003 0.2067930102 ) 1182 2 - vert 635 ( 0.3647669852 0.6765489578 ) 517 3 - vert 636 ( 0.3647669852 0.5591269732 ) 1119 3 - vert 637 ( 0.326436013 0.583245039 ) 1146 3 - vert 638 ( 0.326436013 0.6524310112 ) 544 3 - vert 639 ( 0.3078300059 0.6178380251 ) 547 5 - vert 640 ( 0.4289390147 0.5484470129 ) 1122 3 - vert 641 ( 0.4289390147 0.6872290373 ) 520 3 - vert 642 ( 0.4859350026 0.5682669878 ) 915 3 - vert 643 ( 0.4859350026 0.6674090028 ) 302 3 - vert 644 ( 0.5157709718 0.6178380251 ) 298 4 - - numtris 936 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 5 3 6 - tri 3 9 8 7 - tri 4 8 10 7 - tri 5 12 11 10 - tri 6 14 2 13 - tri 7 16 13 15 - tri 8 17 16 15 - tri 9 20 19 18 - tri 10 20 18 1 - tri 11 14 20 2 - tri 12 20 1 2 - tri 13 23 22 21 - tri 14 26 25 24 - tri 15 29 28 27 - tri 16 18 30 1 - tri 17 31 25 26 - tri 18 32 23 21 - tri 19 34 33 23 - tri 20 17 15 35 - tri 21 19 30 18 - tri 22 32 21 36 - tri 23 39 38 37 - tri 24 40 38 39 - tri 25 42 41 38 - tri 26 45 44 43 - tri 27 45 46 44 - tri 28 49 48 47 - tri 29 50 45 43 - tri 30 50 43 51 - tri 31 52 46 45 - tri 32 55 54 53 - tri 33 57 56 55 - tri 34 57 58 56 - tri 35 61 60 59 - tri 36 61 59 62 - tri 37 62 63 56 - tri 38 58 62 56 - tri 39 53 54 64 - tri 40 66 52 65 - tri 41 65 52 50 - tri 42 68 65 67 - tri 43 59 69 63 - tri 44 68 67 69 - tri 45 54 71 70 - tri 46 54 70 64 - tri 47 52 45 50 - tri 48 65 50 67 - tri 49 62 59 63 - tri 50 56 63 71 - tri 51 55 56 71 - tri 52 55 71 54 - tri 53 74 73 72 - tri 54 74 72 75 - tri 55 76 55 53 - tri 56 77 60 61 - tri 57 77 61 58 - tri 58 58 61 62 - tri 59 73 58 57 - tri 60 72 73 57 - tri 61 72 57 76 - tri 62 76 57 55 - tri 63 80 79 78 - tri 64 78 79 81 - tri 65 82 78 81 - tri 66 82 81 73 - tri 67 82 73 74 - tri 68 83 82 74 - tri 69 84 83 74 - tri 70 84 74 75 - tri 71 87 86 85 - tri 72 85 86 88 - tri 73 80 89 79 - tri 74 89 90 60 - tri 75 81 79 77 - tri 76 81 77 73 - tri 77 73 77 58 - tri 78 75 72 76 - tri 79 88 90 89 - tri 80 31 87 25 - tri 81 25 87 85 - tri 82 25 80 11 - tri 83 25 85 80 - tri 84 10 11 80 - tri 85 10 80 78 - tri 86 7 10 78 - tri 87 7 78 82 - tri 88 91 7 82 - tri 89 94 93 92 - tri 90 94 92 95 - tri 91 98 97 96 - tri 92 99 97 98 - tri 93 102 101 100 - tri 94 38 41 37 - tri 95 37 41 101 - tri 96 102 100 103 - tri 97 37 101 102 - tri 98 39 37 99 - tri 99 95 92 104 - tri 100 95 104 105 - tri 101 92 107 106 - tri 102 93 107 92 - tri 103 110 109 108 - tri 104 113 112 111 - tri 105 116 115 114 - tri 106 113 111 117 - tri 107 118 113 117 - tri 108 118 117 119 - tri 109 105 121 120 - tri 110 124 123 122 - tri 111 126 94 125 - tri 112 125 94 95 - tri 113 125 95 127 - tri 114 127 95 105 - tri 115 105 116 128 - tri 116 122 129 109 - tri 117 123 129 122 - tri 118 129 130 109 - tri 119 131 123 124 - tri 120 105 128 121 - tri 121 41 133 132 - tri 122 41 132 101 - tri 123 132 118 100 - tri 124 101 132 100 - tri 125 133 135 134 - tri 126 103 137 136 - tri 127 100 138 103 - tri 128 103 138 137 - tri 129 132 133 112 - tri 130 100 119 138 - tri 131 100 118 119 - tri 132 135 139 134 - tri 133 133 134 112 - tri 134 106 141 140 - tri 135 107 142 106 - tri 136 107 143 142 - tri 137 108 145 144 - tri 138 108 109 145 - tri 139 142 141 106 - tri 140 141 115 140 - tri 141 148 147 146 - tri 142 136 137 148 - tri 143 136 148 146 - tri 144 144 145 149 - tri 145 132 113 118 - tri 146 132 112 113 - tri 147 140 115 116 - tri 148 86 90 88 - tri 149 86 150 90 - tri 150 71 63 151 - tri 151 24 11 12 - tri 152 24 25 11 - tri 153 112 152 111 - tri 154 154 153 42 - tri 155 155 135 153 - tri 156 154 155 153 - tri 157 42 153 41 - tri 158 41 153 133 - tri 159 153 135 133 - tri 160 157 40 156 - tri 161 141 158 115 - tri 162 161 160 159 - tri 163 29 9 91 - tri 164 29 91 162 - tri 165 8 12 10 - tri 166 2 0 13 - tri 167 29 162 28 - tri 168 9 7 91 - tri 169 85 88 89 - tri 170 85 89 80 - tri 171 162 91 83 - tri 172 91 82 83 - tri 173 28 83 84 - tri 174 28 162 83 - tri 175 165 164 163 - tri 176 166 34 23 - tri 177 166 23 32 - tri 178 165 5 6 - tri 179 165 6 167 - tri 180 14 13 168 - tri 181 168 13 16 - tri 182 165 167 164 - tri 183 170 156 169 - tri 184 105 140 116 - tri 185 104 140 105 - tri 186 92 106 104 - tri 187 104 106 140 - tri 188 137 171 148 - tri 189 138 171 137 - tri 190 149 145 172 - tri 191 145 173 172 - tri 192 171 174 148 - tri 193 172 173 175 - tri 194 173 176 175 - tri 195 174 177 148 - tri 196 175 176 178 - tri 197 97 37 102 - tri 198 99 37 97 - tri 199 96 97 179 - tri 200 97 102 179 - tri 201 179 102 103 - tri 202 96 179 180 - tri 203 180 179 103 - tri 204 180 103 181 - tri 205 181 103 136 - tri 206 30 0 1 - tri 207 30 182 0 - tri 208 185 184 183 - tri 209 187 183 186 - tri 210 183 184 186 - tri 211 189 187 188 - tri 212 187 186 188 - tri 213 191 188 190 - tri 214 193 191 192 - tri 215 191 190 194 - tri 216 192 191 194 - tri 217 188 186 120 - tri 218 197 196 195 - tri 219 200 199 198 - tri 220 203 202 201 - tri 221 198 199 204 - tri 222 203 205 202 - tri 223 202 207 206 - tri 224 209 208 205 - tri 225 209 210 208 - tri 226 213 212 211 - tri 227 214 210 209 - tri 228 215 210 214 - tri 229 218 217 216 - tri 230 220 219 207 - tri 231 211 198 204 - tri 232 223 222 221 - tri 233 225 216 224 - tri 234 226 216 225 - tri 235 216 227 224 - tri 236 216 228 227 - tri 237 220 227 229 - tri 238 230 227 220 - tri 239 224 227 230 - tri 240 211 204 231 - tri 241 213 211 231 - tri 242 218 216 226 - tri 243 220 229 219 - tri 244 229 232 219 - tri 245 204 199 233 - tri 246 234 233 232 - tri 247 202 206 201 - tri 248 237 236 235 - tri 249 239 238 236 - tri 250 237 235 240 - tri 251 240 235 241 - tri 252 244 243 242 - tri 253 238 245 199 - tri 254 199 245 233 - tri 255 248 247 246 - tri 256 239 248 238 - tri 257 250 201 249 - tri 258 235 199 200 - tri 259 253 252 251 - tri 260 254 252 253 - tri 261 229 234 232 - tri 262 241 235 200 - tri 263 250 203 201 - tri 264 228 234 229 - tri 265 227 228 229 - tri 266 256 255 234 - tri 267 255 233 234 - tri 268 204 233 255 - tri 269 196 127 184 - tri 270 184 127 105 - tri 271 257 183 187 - tri 272 258 257 187 - tri 273 189 258 187 - tri 274 185 183 259 - tri 275 259 183 257 - tri 276 260 258 189 - tri 277 262 261 193 - tri 278 193 261 260 - tri 279 193 260 189 - tri 280 197 195 263 - tri 281 248 245 238 - tri 282 248 246 245 - tri 283 220 207 202 - tri 284 195 264 263 - tri 285 195 265 264 - tri 286 265 185 259 - tri 287 195 185 265 - tri 288 220 202 208 - tri 289 208 202 205 - tri 290 256 252 255 - tri 291 251 252 256 - tri 292 267 266 214 - tri 293 266 215 214 - tri 294 268 231 252 - tri 295 254 268 252 - tri 296 213 268 254 - tri 297 213 231 268 - tri 298 217 234 228 - tri 299 217 256 234 - tri 300 216 217 228 - tri 301 223 221 230 - tri 302 221 224 230 - tri 303 230 208 269 - tri 304 230 220 208 - tri 305 223 230 269 - tri 306 231 255 252 - tri 307 231 204 255 - tri 308 184 105 186 - tri 309 186 105 120 - tri 310 195 196 185 - tri 311 185 196 184 - tri 312 196 125 127 - tri 313 114 178 176 - tri 314 114 270 178 - tri 315 79 60 77 - tri 316 79 89 60 - tri 317 66 65 271 - tri 318 271 65 68 - tri 319 272 271 68 - tri 320 272 68 69 - tri 321 272 69 59 - tri 322 60 272 59 - tri 323 90 272 60 - tri 324 150 66 273 - tri 325 273 66 271 - tri 326 273 271 272 - tri 327 90 273 272 - tri 328 150 273 90 - tri 329 236 199 235 - tri 330 236 238 199 - tri 331 237 239 236 - tri 332 274 239 237 - tri 333 244 250 249 - tri 334 244 242 250 - tri 335 130 128 275 - tri 336 128 116 275 - tri 337 116 114 275 - tri 338 115 270 114 - tri 339 115 158 270 - tri 340 111 152 161 - tri 341 152 160 161 - tri 342 275 176 173 - tri 343 275 114 176 - tri 344 152 276 160 - tri 345 112 276 152 - tri 346 112 134 276 - tri 347 160 277 159 - tri 348 276 277 160 - tri 349 159 278 177 - tri 350 277 278 159 - tri 351 277 279 278 - tri 352 278 279 280 - tri 353 148 177 281 - tri 354 278 281 177 - tri 355 278 280 281 - tri 356 281 280 147 - tri 357 148 281 147 - tri 358 197 282 196 - tri 359 262 193 192 - tri 360 193 189 191 - tri 361 189 188 191 - tri 362 129 121 128 - tri 363 129 128 130 - tri 364 134 277 276 - tri 365 284 120 283 - tri 366 283 120 121 - tri 367 129 283 121 - tri 368 285 283 129 - tri 369 123 285 129 - tri 370 286 283 285 - tri 371 123 286 285 - tri 372 286 284 283 - tri 373 190 284 286 - tri 374 282 287 196 - tri 375 192 194 288 - tri 376 287 126 125 - tri 377 196 287 125 - tri 378 289 286 123 - tri 379 288 289 131 - tri 380 131 289 123 - tri 381 194 190 286 - tri 382 194 286 289 - tri 383 288 194 289 - tri 384 188 120 284 - tri 385 188 284 190 - tri 386 124 122 110 - tri 387 122 109 110 - tri 388 130 275 290 - tri 389 290 275 173 - tri 390 145 290 173 - tri 391 109 290 145 - tri 392 109 130 290 - tri 393 139 291 134 - tri 394 291 293 292 - tri 395 134 291 277 - tri 396 291 279 277 - tri 397 291 292 279 - tri 398 294 139 135 - tri 399 294 295 139 - tri 400 155 296 135 - tri 401 296 294 135 - tri 402 154 297 155 - tri 403 297 296 155 - tri 404 299 298 297 - tri 405 299 297 154 - tri 406 139 293 291 - tri 407 295 293 139 - tri 408 300 299 154 - tri 409 301 300 154 - tri 410 301 154 42 - tri 411 303 301 302 - tri 412 303 300 301 - tri 413 303 304 299 - tri 414 303 299 300 - tri 415 40 42 38 - tri 416 301 42 40 - tri 417 305 303 302 - tri 418 305 306 303 - tri 419 157 301 40 - tri 420 302 301 157 - tri 421 307 157 156 - tri 422 308 157 307 - tri 423 305 302 157 - tri 424 305 157 308 - tri 425 156 40 169 - tri 426 71 151 309 - tri 427 49 310 48 - tri 428 71 309 70 - tri 429 170 169 48 - tri 430 48 169 311 - tri 431 313 49 312 - tri 432 49 47 312 - tri 433 313 312 314 - tri 434 315 298 299 - tri 435 315 299 304 - tri 436 47 48 316 - tri 437 48 311 316 - tri 438 311 318 317 - tri 439 169 318 311 - tri 440 317 39 99 - tri 441 318 39 317 - tri 442 317 99 319 - tri 443 319 99 98 - tri 444 316 311 317 - tri 445 316 317 319 - tri 446 40 39 318 - tri 447 169 40 318 - tri 448 310 170 48 - tri 449 310 320 170 - tri 450 320 307 170 - tri 451 307 156 170 - tri 452 322 321 315 - tri 453 322 315 304 - tri 454 69 67 323 - tri 455 69 323 63 - tri 456 63 323 151 - tri 457 323 325 324 - tri 458 67 50 326 - tri 459 50 51 326 - tri 460 67 326 323 - tri 461 323 326 325 - tri 462 326 51 325 - tri 463 323 324 151 - tri 464 329 328 327 - tri 465 332 331 330 - tri 466 332 333 331 - tri 467 336 335 334 - tri 468 334 335 337 - tri 469 339 337 338 - tri 470 341 340 329 - tri 471 343 342 340 - tri 472 344 342 343 - tri 473 347 346 345 - tri 474 347 327 346 - tri 475 341 329 347 - tri 476 347 329 327 - tri 477 350 349 348 - tri 478 353 352 351 - tri 479 356 355 354 - tri 480 346 327 357 - tri 481 358 353 351 - tri 482 359 349 350 - tri 483 361 350 360 - tri 484 344 362 342 - tri 485 345 346 357 - tri 486 359 363 349 - tri 487 366 365 364 - tri 488 367 366 364 - tri 489 369 364 368 - tri 490 372 371 370 - tri 491 372 370 373 - tri 492 375 47 374 - tri 493 376 371 372 - tri 494 376 377 371 - tri 495 378 372 373 - tri 496 381 380 379 - tri 497 383 381 382 - tri 498 383 382 384 - tri 499 387 386 385 - tri 500 387 388 386 - tri 501 388 382 389 - tri 502 384 382 388 - tri 503 380 390 379 - tri 504 392 391 378 - tri 505 391 376 378 - tri 506 394 393 391 - tri 507 386 389 395 - tri 508 394 395 393 - tri 509 379 397 396 - tri 510 379 390 397 - tri 511 378 376 372 - tri 512 391 393 376 - tri 513 388 389 386 - tri 514 382 396 389 - tri 515 381 396 382 - tri 516 381 379 396 - tri 517 400 399 398 - tri 518 400 401 399 - tri 519 402 380 381 - tri 520 403 387 385 - tri 521 403 384 387 - tri 522 384 388 387 - tri 523 398 383 384 - tri 524 399 383 398 - tri 525 399 402 383 - tri 526 402 381 383 - tri 527 406 405 404 - tri 528 405 407 404 - tri 529 408 407 405 - tri 530 408 398 407 - tri 531 408 400 398 - tri 532 409 400 408 - tri 533 410 400 409 - tri 534 410 401 400 - tri 535 413 412 411 - tri 536 412 414 411 - tri 537 406 404 415 - tri 538 415 385 416 - tri 539 407 403 404 - tri 540 407 398 403 - tri 541 398 384 403 - tri 542 401 402 399 - tri 543 414 415 416 - tri 544 358 351 413 - tri 545 351 412 413 - tri 546 351 338 406 - tri 547 351 406 412 - tri 548 337 406 338 - tri 549 337 405 406 - tri 550 335 405 337 - tri 551 335 408 405 - tri 552 417 408 335 - tri 553 420 419 418 - tri 554 420 421 419 - tri 555 98 96 422 - tri 556 423 98 422 - tri 557 426 425 424 - tri 558 364 365 368 - tri 559 365 424 368 - tri 560 426 427 425 - tri 561 365 426 424 - tri 562 366 423 365 - tri 563 421 428 419 - tri 564 421 429 428 - tri 565 419 431 430 - tri 566 418 419 430 - tri 567 434 433 432 - tri 568 437 436 435 - tri 569 440 439 438 - tri 570 437 441 436 - tri 571 442 441 437 - tri 572 442 443 441 - tri 573 429 445 444 - tri 574 448 447 446 - tri 575 450 449 420 - tri 576 449 421 420 - tri 577 449 451 421 - tri 578 451 429 421 - tri 579 429 452 440 - tri 580 447 432 453 - tri 581 446 447 453 - tri 582 453 432 454 - tri 583 455 448 446 - tri 584 429 444 452 - tri 585 368 457 456 - tri 586 368 424 457 - tri 587 457 425 442 - tri 588 424 425 457 - tri 589 456 459 458 - tri 590 427 136 460 - tri 591 425 427 461 - tri 592 427 460 461 - tri 593 457 435 456 - tri 594 425 461 443 - tri 595 425 443 442 - tri 596 458 459 462 - tri 597 456 435 459 - tri 598 431 464 463 - tri 599 430 431 465 - tri 600 430 465 466 - tri 601 433 468 467 - tri 602 433 467 432 - tri 603 465 431 463 - tri 604 463 464 438 - tri 605 470 146 469 - tri 606 136 470 460 - tri 607 136 146 470 - tri 608 468 471 467 - tri 609 457 442 437 - tri 610 457 437 435 - tri 611 464 440 438 - tri 612 411 414 416 - tri 613 411 416 472 - tri 614 396 473 389 - tri 615 352 339 338 - tri 616 352 338 351 - tri 617 435 436 474 - tri 618 476 369 475 - tri 619 477 475 458 - tri 620 476 475 477 - tri 621 369 368 475 - tri 622 368 456 475 - tri 623 475 456 458 - tri 624 479 478 367 - tri 625 463 438 480 - tri 626 483 482 481 - tri 627 356 417 336 - tri 628 356 484 417 - tri 629 334 337 339 - tri 630 329 340 328 - tri 631 356 354 484 - tri 632 336 417 335 - tri 633 412 415 414 - tri 634 412 406 415 - tri 635 484 409 417 - tri 636 417 409 408 - tri 637 354 410 409 - tri 638 354 409 484 - tri 639 487 486 485 - tri 640 488 350 361 - tri 641 488 359 350 - tri 642 487 333 332 - tri 643 487 489 333 - tri 644 341 490 340 - tri 645 490 343 340 - tri 646 487 485 489 - tri 647 492 491 478 - tri 648 429 440 464 - tri 649 428 429 464 - tri 650 419 428 431 - tri 651 428 464 431 - tri 652 460 470 493 - tri 653 461 460 493 - tri 654 471 494 467 - tri 655 467 494 495 - tri 656 493 470 496 - tri 657 494 497 495 - tri 658 495 497 498 - tri 659 496 470 499 - tri 660 497 500 498 - tri 661 422 426 365 - tri 662 423 422 365 - tri 663 96 501 422 - tri 664 422 501 426 - tri 665 501 427 426 - tri 666 96 180 501 - tri 667 180 427 501 - tri 668 180 181 427 - tri 669 181 136 427 - tri 670 357 327 328 - tri 671 357 328 502 - tri 672 505 504 503 - tri 673 507 506 504 - tri 674 504 506 503 - tri 675 509 508 507 - tri 676 507 508 506 - tri 677 511 510 508 - tri 678 513 512 511 - tri 679 511 514 510 - tri 680 512 514 511 - tri 681 508 445 506 - tri 682 517 516 515 - tri 683 520 519 518 - tri 684 523 522 521 - tri 685 519 524 518 - tri 686 523 521 525 - tri 687 521 527 526 - tri 688 529 525 528 - tri 689 529 528 530 - tri 690 533 532 531 - tri 691 534 529 530 - tri 692 535 534 530 - tri 693 538 537 536 - tri 694 540 526 539 - tri 695 532 524 519 - tri 696 543 542 541 - tri 697 545 544 537 - tri 698 546 545 537 - tri 699 537 544 547 - tri 700 537 547 548 - tri 701 540 549 547 - tri 702 550 540 547 - tri 703 544 550 547 - tri 704 532 551 524 - tri 705 533 551 532 - tri 706 538 546 537 - tri 707 540 539 549 - tri 708 549 539 552 - tri 709 524 553 518 - tri 710 554 552 553 - tri 711 521 522 527 - tri 712 557 556 555 - tri 713 559 555 558 - tri 714 557 560 556 - tri 715 560 561 556 - tri 716 564 563 562 - tri 717 558 518 565 - tri 718 518 553 565 - tri 719 568 567 566 - tri 720 559 558 568 - tri 721 570 569 522 - tri 722 556 520 518 - tri 723 573 572 571 - tri 724 574 573 571 - tri 725 549 552 554 - tri 726 561 520 556 - tri 727 570 522 523 - tri 728 548 549 554 - tri 729 547 549 548 - tri 730 576 554 575 - tri 731 575 554 553 - tri 732 524 575 553 - tri 733 515 503 451 - tri 734 503 429 451 - tri 735 577 507 504 - tri 736 578 507 577 - tri 737 509 507 578 - tri 738 505 579 504 - tri 739 579 577 504 - tri 740 580 509 578 - tri 741 582 513 581 - tri 742 513 580 581 - tri 743 513 509 580 - tri 744 517 583 516 - tri 745 568 558 565 - tri 746 568 565 567 - tri 747 540 521 526 - tri 748 516 583 584 - tri 749 516 584 585 - tri 750 585 579 505 - tri 751 516 585 505 - tri 752 540 528 521 - tri 753 528 525 521 - tri 754 576 575 571 - tri 755 572 576 571 - tri 756 587 534 586 - tri 757 586 534 535 - tri 758 588 571 551 - tri 759 574 571 588 - tri 760 533 574 588 - tri 761 533 588 551 - tri 762 536 548 554 - tri 763 536 554 576 - tri 764 537 548 536 - tri 765 543 550 542 - tri 766 542 550 544 - tri 767 550 589 528 - tri 768 550 528 540 - tri 769 543 589 550 - tri 770 551 571 575 - tri 771 551 575 524 - tri 772 503 506 429 - tri 773 506 445 429 - tri 774 516 505 515 - tri 775 505 503 515 - tri 776 515 451 449 - tri 777 439 498 500 - tri 778 439 500 590 - tri 779 404 403 385 - tri 780 404 385 415 - tri 781 392 591 391 - tri 782 591 394 391 - tri 783 592 394 591 - tri 784 592 395 394 - tri 785 592 386 395 - tri 786 385 386 592 - tri 787 416 385 592 - tri 788 472 593 392 - tri 789 593 591 392 - tri 790 593 592 591 - tri 791 416 592 593 - tri 792 472 416 593 - tri 793 555 556 518 - tri 794 555 518 558 - tri 795 557 555 559 - tri 796 594 557 559 - tri 797 564 569 570 - tri 798 564 570 563 - tri 799 454 595 452 - tri 800 452 595 440 - tri 801 440 595 439 - tri 802 438 439 590 - tri 803 438 590 480 - tri 804 436 483 474 - tri 805 474 483 481 - tri 806 595 495 498 - tri 807 595 498 439 - tri 808 474 481 596 - tri 809 435 474 596 - tri 810 435 596 459 - tri 811 481 482 597 - tri 812 596 481 597 - tri 813 482 499 598 - tri 814 597 482 598 - tri 815 597 598 599 - tri 816 598 600 599 - tri 817 470 601 499 - tri 818 598 499 601 - tri 819 598 601 600 - tri 820 601 469 600 - tri 821 470 469 601 - tri 822 517 515 602 - tri 823 582 512 513 - tri 824 513 511 509 - tri 825 509 511 508 - tri 826 453 452 444 - tri 827 453 454 452 - tri 828 459 596 597 - tri 829 604 603 445 - tri 830 603 444 445 - tri 831 453 444 603 - tri 832 605 453 603 - tri 833 446 453 605 - tri 834 606 605 603 - tri 835 446 605 606 - tri 836 606 603 604 - tri 837 510 606 604 - tri 838 602 515 607 - tri 839 512 608 514 - tri 840 607 449 450 - tri 841 515 449 607 - tri 842 609 446 606 - tri 843 608 455 609 - tri 844 455 446 609 - tri 845 514 606 510 - tri 846 514 609 606 - tri 847 608 609 514 - tri 848 508 604 445 - tri 849 508 510 604 - tri 850 448 434 447 - tri 851 447 434 432 - tri 852 454 610 595 - tri 853 610 495 595 - tri 854 467 495 610 - tri 855 432 467 610 - tri 856 432 610 454 - tri 857 462 459 611 - tri 858 611 612 293 - tri 859 459 597 611 - tri 860 611 597 599 - tri 861 611 599 612 - tri 862 294 458 462 - tri 863 294 462 295 - tri 864 477 458 296 - tri 865 296 458 294 - tri 866 476 477 297 - tri 867 297 477 296 - tri 868 613 297 298 - tri 869 613 476 297 - tri 870 462 611 293 - tri 871 295 462 293 - tri 872 614 476 613 - tri 873 615 476 614 - tri 874 615 369 476 - tri 875 617 616 615 - tri 876 617 615 614 - tri 877 617 613 618 - tri 878 617 614 613 - tri 879 367 364 369 - tri 880 615 367 369 - tri 881 619 616 617 - tri 882 619 617 620 - tri 883 479 367 615 - tri 884 616 479 615 - tri 885 621 478 479 - tri 886 622 621 479 - tri 887 619 479 616 - tri 888 619 622 479 - tri 889 478 491 367 - tri 890 396 623 473 - tri 891 375 374 624 - tri 892 396 397 623 - tri 893 492 374 491 - tri 894 374 625 491 - tri 895 626 312 375 - tri 896 375 312 47 - tri 897 626 314 312 - tri 898 315 613 298 - tri 899 315 618 613 - tri 900 47 316 374 - tri 901 374 316 625 - tri 902 625 628 627 - tri 903 491 625 627 - tri 904 628 423 366 - tri 905 627 628 366 - tri 906 628 319 423 - tri 907 319 98 423 - tri 908 316 628 625 - tri 909 316 319 628 - tri 910 367 627 366 - tri 911 491 627 367 - tri 912 624 374 492 - tri 913 624 492 629 - tri 914 629 492 621 - tri 915 621 492 478 - tri 916 630 315 321 - tri 917 630 618 315 - tri 918 395 631 393 - tri 919 395 389 631 - tri 920 389 473 631 - tri 921 631 633 632 - tri 922 393 634 376 - tri 923 376 634 377 - tri 924 393 631 634 - tri 925 631 632 634 - tri 926 634 632 377 - tri 927 631 473 633 - tri 928 637 636 635 - tri 929 639 637 638 - tri 930 637 635 638 - tri 931 635 636 640 - tri 932 635 640 641 - tri 933 641 640 642 - tri 934 641 642 643 - tri 935 644 643 642 - - numweights 1184 - weight 0 5 0.0935239866 ( 3.8127360344 18.653427124 -1.0291671753 ) - weight 1 6 0.6671485305 ( -0.7151768804 3.1304476261 2.3139109612 ) - weight 2 7 0.2393274605 ( -1.2482603788 -0.3180599511 2.8520338535 ) - weight 3 6 0.0843834653 ( -0.103548944 6.4286642075 4.4149246216 ) - weight 4 7 0.5620473027 ( -1.5335928202 3.6064872742 2.4241364002 ) - weight 5 8 0.3535692692 ( -1.5020233393 -1.489027977 2.4291889668 ) - weight 6 6 0.4737676382 ( -1.783880949 5.0132074356 1.8606542349 ) - weight 7 7 0.5262323618 ( -2.2546753883 0.5913566947 1.1049093008 ) - weight 8 7 0.5011257529 ( -2.0092220306 4.9650716782 -0.9881344438 ) - weight 9 8 0.4988743067 ( -2.0064079762 -0.1527582258 -0.9877608418 ) - weight 10 7 0.5046935678 ( 2.2403481007 4.8383469582 -0.8591219783 ) - weight 11 8 0.495306462 ( 2.2448923588 -0.1879273951 -0.8583108187 ) - weight 12 6 0.4963374138 ( 2.4411556721 6.207262516 -1.9451041222 ) - weight 13 7 0.5036625266 ( 2.8364603519 0.2825942934 -1.678165555 ) - weight 14 6 0.4661476612 ( -2.9416100979 6.680390358 -0.124947004 ) - weight 15 7 0.4800623953 ( -2.864084959 0.4030625224 -1.661968708 ) - weight 16 8 0.0537899137 ( -2.7632496357 -4.7343444824 -1.6458107233 ) - weight 17 5 0.6232063174 ( 2.4141130447 19.4039840698 3.0864076614 ) - weight 18 6 0.2971909642 ( -3.9112217426 0.4099190235 0.9569070339 ) - weight 19 7 0.079602696 ( -3.6844074726 -3.9935793877 2.9668514729 ) - weight 20 5 0.3033103049 ( 1.7648807764 19.9354686737 0.9160862565 ) - weight 21 6 0.6966896653 ( -2.0447351933 1.4687639475 0.0572685003 ) - weight 22 5 0.5 ( -1.1340595484 20.9681034088 2.7353503704 ) - weight 23 6 0.5 ( -2.8432769775 -0.8022369742 -2.5856082439 ) - weight 24 5 0.2689843774 ( 3.6818537712 18.1522884369 0.4523608088 ) - weight 25 6 0.5431467891 ( -1.7138297558 1.9667268991 2.6480391026 ) - weight 26 7 0.1878687739 ( -2.2188911438 -1.2560834885 3.6527729034 ) - weight 27 5 0.1060663685 ( 3.8994646072 17.6567077637 -2.6287515163 ) - weight 28 6 0.4873141348 ( 0.9746851921 3.5118248463 3.0612783432 ) - weight 29 7 0.3494953811 ( 0.1032667458 0.833692193 3.4895932674 ) - weight 30 8 0.0571241342 ( 0.193809092 -4.2224025726 3.5042307377 ) - weight 31 5 0.3997223675 ( -1.1646162271 23.7804584503 2.4665870667 ) - weight 32 6 0.416490972 ( -3.6860747337 0.8614725471 -4.7079329491 ) - weight 33 7 0.1837866157 ( -1.7758848667 -6.9593877792 -1.4948216677 ) - weight 34 5 0.4107972383 ( -3.0434253216 23.3945465088 0.2558147609 ) - weight 35 6 0.4213652015 ( -0.9571697712 0.6585354805 -5.7463259697 ) - weight 36 7 0.1678375453 ( 1.1468127966 -7.0609121323 -1.612706542 ) - weight 37 7 0.5249262452 ( 0.3187460601 4.7918243408 1.1942294836 ) - weight 38 8 0.475073725 ( 0.3245765269 -0.2685232162 1.1951892376 ) - weight 39 6 0.1096295714 ( 2.9207594395 6.0545563698 3.1228327751 ) - weight 40 7 0.5836595297 ( 1.7587673664 3.2957522869 2.2837510109 ) - weight 41 8 0.3067108989 ( 1.7962508202 -1.7296113968 2.2898793221 ) - weight 42 5 0.0803422183 ( 2.1394081116 18.4398002625 -3.2200272083 ) - weight 43 6 0.6961277723 ( 1.8512949944 3.1415815353 1.2850141525 ) - weight 44 7 0.2235300243 ( 1.5025411844 -0.2899706662 2.5730495453 ) - weight 45 5 0.120941259 ( 0.4943208694 19.4355697632 -3.2106790543 ) - weight 46 6 0.7397739887 ( 2.0982830524 2.6337282658 -0.5532013774 ) - weight 47 7 0.13928473 ( 2.3319923878 -1.7106441259 1.5772321224 ) - weight 48 5 0.1834091842 ( 1.6726700068 17.7061920166 -4.2953872681 ) - weight 49 6 0.5260417461 ( 3.2151074409 3.02911973 1.4844964743 ) - weight 50 7 0.2905490696 ( 2.7451124191 0.0778421164 3.055911541 ) - weight 51 5 0.307454288 ( -0.8569551706 18.9894447327 -3.3947553635 ) - weight 52 6 0.5233104229 ( 2.9472596645 1.6302223206 -1.1285903454 ) - weight 53 7 0.1692353189 ( 3.3826670647 -2.6122379303 1.9541528225 ) - weight 54 5 0.5 ( -2.5818479061 20.652261734 0.7198096514 ) - weight 55 6 0.5 ( -0.4718607068 -0.7988776565 -3.3822422028 ) - weight 56 3 0.1069236025 ( 7.8959803581 5.1963424683 -3.1774251461 ) - weight 57 4 0.055033993 ( -4.6473593712 -6.595079422 2.6459314823 ) - weight 58 17 0.5240889192 ( 7.8119282722 5.3034553528 -2.588255167 ) - weight 59 19 0.1887804121 ( 7.8959803581 -4.0340409279 -0.8862084746 ) - weight 60 22 0.1251730919 ( 7.8959803581 -11.7440185547 -1.9258887768 ) - weight 61 3 0.2396446764 ( 8.9375400543 2.2950553894 1.6243751049 ) - weight 62 4 0.1261993945 ( -0.540705204 -3.2331829071 4.7417945862 ) - weight 63 17 0.5096623302 ( 9.1274223328 1.3470243216 1.307348609 ) - weight 64 19 0.0713101402 ( 8.9375400543 -6.5020513535 4.1520133018 ) - weight 65 18 0.0531834662 ( 9.0192966461 -0.1320838928 -4.9274363518 ) - weight 66 3 0.2287210673 ( 8.6952495575 1.7104187012 -2.5718455315 ) - weight 67 4 0.3527418673 ( -4.3803491592 -2.9905166626 2.9509792328 ) - weight 68 17 0.4185370207 ( 8.6446428299 1.7856129408 -2.8859004974 ) - weight 69 3 0.2374471128 ( 9.0758094788 -1.4819068909 1.7993447781 ) - weight 70 4 0.4392165542 ( -0.4429805875 0.5151005983 4.235833168 ) - weight 71 17 0.323336333 ( 9.2755079269 -2.3588469028 0.5591737032 ) - weight 72 3 0.0989223495 ( 8.4342899323 5.5740737915 1.8654049635 ) - weight 73 4 0.0575829931 ( -0.122197099 -6.5253105164 4.9655504227 ) - weight 74 17 0.3998931944 ( 8.638838768 4.4645085335 2.3589644432 ) - weight 75 19 0.1923786998 ( 8.4342899323 -3.2145380974 4.103905201 ) - weight 76 22 0.1035134494 ( 8.4342899323 -11.3662872314 3.116941452 ) - weight 77 20 0.0805758238 ( 4.4096069336 -8.9192352295 -3.6768064499 ) - weight 78 18 0.0671336129 ( 8.516046524 3.1469345093 -4.6864066124 ) - weight 79 3 0.2791765332 ( 6.444149971 2.2682647705 5.2955346107 ) - weight 80 4 0.0813388303 ( 3.776214838 -3.3769154549 3.7226452827 ) - weight 81 17 0.3838120401 ( 6.8488903046 0.403480351 4.9969477654 ) - weight 82 19 0.0837190822 ( 6.444149971 -6.2060661316 7.811319828 ) - weight 83 22 0.0516345128 ( 6.444149971 -14.6720962524 6.5470709801 ) - weight 84 18 0.1203189269 ( 6.5259070396 -0.1588745117 -1.2562770844 ) - weight 85 3 0.2173970491 ( 3.0921401978 -7.1752662659 3.609495163 ) - weight 86 4 0.7826029658 ( 3.3475801945 5.2183027267 -1.6808229685 ) - weight 87 3 0.1548608094 ( 1.0088498592 -8.7325363159 1.4380851984 ) - weight 88 10 0.0788915828 ( -2.7682247162 5.9015431404 -6.4908056259 ) - weight 89 4 0.7662476301 ( 2.0499591827 6.2439441681 -4.6379246712 ) - weight 90 3 0.0597552843 ( 3.0285470486 -16.1775856018 0.7946404219 ) - weight 91 4 0.9402447343 ( 0.6985477209 13.8613948822 -4.3731813431 ) - weight 92 3 0.2056824863 ( 1.4231300354 -8.4189376831 -3.8824949265 ) - weight 93 4 0.7073415518 ( -3.0698652267 5.6375350952 -6.0515060425 ) - weight 94 17 0.0869759843 ( 1.3092769384 -7.8306627274 -6.191204071 ) - weight 95 3 0.2549369335 ( -0.0000000767 -7.2712364197 -8.0562448502 ) - weight 96 10 0.3233954608 ( 6.4583187103 3.97803092 -8.6042089462 ) - weight 97 4 0.2400700003 ( -6.4617328644 3.9779164791 -8.6017217636 ) - weight 98 17 0.1815975606 ( -0.3511044681 -5.732506752 -9.8795070648 ) - weight 99 3 0.3385702968 ( 5.1066098213 -7.2581672668 -7.5305352211 ) - weight 100 4 0.5283104777 ( -7.7824854851 4.8707962036 -3.7219288349 ) - weight 101 17 0.1331192106 ( 4.7772631645 -5.7756457329 -9.6514911652 ) - weight 102 4 1 ( 2.0208208561 17.0193157196 -1.7541565895 ) - weight 103 3 0.0721849874 ( 6.9160900116 -8.1293678284 4.1621651649 ) - weight 104 4 0.9278150201 ( 2.5029408932 6.8453984261 1.8515261412 ) - weight 105 4 1 ( -1.5941867828 17.5156898499 -5.0876231194 ) - weight 106 4 0.6035490036 ( -2.14920187 20.8788642883 -5.5200414658 ) - weight 107 5 0.3964509964 ( -3.5182361603 0.9090330601 -1.0926308632 ) - weight 108 4 0.740267396 ( -4.2334904671 20.033618927 -5.3216814995 ) - weight 109 5 0.2597326636 ( -3.7921729088 0.5087783933 1.1125444174 ) - weight 110 4 0.3635103106 ( -4.8802652359 22.6644039154 -6.2131309509 ) - weight 111 5 0.6364896297 ( -4.3122873306 3.3127806187 1.0796296597 ) - weight 112 4 0.2838164866 ( -7.1263494492 21.893579483 -3.203895092 ) - weight 113 5 0.7161834836 ( -1.8632599115 2.6389324665 3.9506502151 ) - weight 114 5 1 ( -4.5441460609 5.457485199 2.5080103874 ) - weight 115 5 1 ( -1.9457143545 5.4498543739 4.9774689674 ) - weight 116 4 0.3121370077 ( -4.4071116447 21.7299919128 1.1965162754 ) - weight 117 5 0.6878629327 ( 2.8127129078 1.3057841063 2.177904129 ) - weight 118 4 0.0533990003 ( -3.1070792675 24.6861858368 0.2713306248 ) - weight 119 5 0.9466010332 ( 2.6169657707 4.0141019821 0.2000683695 ) - weight 120 4 0.0613344088 ( -6.7894115448 24.7612800598 0.0435630083 ) - weight 121 5 0.9386655688 ( 1.8372007608 4.9027342796 3.6956923008 ) - weight 122 4 0.2215298414 ( -7.4662842751 22.7176418304 -0.8179256916 ) - weight 123 5 0.7784701586 ( 0.5461547971 3.1861355305 4.5693383217 ) - weight 124 4 0.7058917284 ( -6.3476676941 19.5804576874 -0.1700688452 ) - weight 125 5 0.2941082716 ( 0.8161998391 -0.175528273 4.196185112 ) - weight 126 4 1 ( 0.7223988771 19.3566379547 -2.3801383972 ) - weight 127 4 0.7103045583 ( -0.7508655787 19.7827892303 0.8460713625 ) - weight 128 5 0.2896954417 ( 2.7071833611 -1.3105490208 -1.0510600805 ) - weight 129 4 0.7103045583 ( -1.1449471712 21.2384376526 0.28044191 ) - weight 130 5 0.2896954417 ( 2.3433480263 0.2584522367 -1.0478247404 ) - weight 131 4 0.3121370077 ( -3.777410984 20.3179550171 1.7202264071 ) - weight 132 5 0.6878629327 ( 3.1797053814 -0.2655899823 1.9314404726 ) - weight 133 3 0.051912196 ( 7.8446297646 -21.3117198944 -5.241314888 ) - weight 134 4 0.7836181521 ( -6.6764502525 19.3096656799 -2.9902544022 ) - weight 135 5 0.1644695997 ( -2.0252971649 0.0139190787 4.038459301 ) - weight 136 5 1 ( -4.5033550262 10.0860862732 1.9963954687 ) - weight 137 5 1 ( -3.661698103 10.4820842743 4.8900823593 ) - weight 138 5 1 ( -4.2860569954 13.5659074783 1.7814621925 ) - weight 139 5 1 ( -2.9659795761 10.5464754105 -1.4613250494 ) - weight 140 4 0.0812822282 ( -3.5907013416 26.3055477142 -5.7982287407 ) - weight 141 5 0.918717742 ( -3.089006424 6.5048732758 -0.7662221789 ) - weight 142 5 1 ( 1.2005630732 8.8299980164 4.2510929108 ) - weight 143 5 1 ( 1.8019845486 15.6448259354 3.1017632484 ) - weight 144 5 1 ( 2.7532973289 12.1564188004 1.5125521421 ) - weight 145 5 1 ( 2.9223973751 15.0317459106 -1.3693894148 ) - weight 146 5 1 ( -0.0095647275 13.1138210297 4.1795659065 ) - weight 147 5 1 ( -1.732221365 16.3549785614 4.1250948906 ) - weight 148 5 0.9168231487 ( -3.7261488438 17.3036441803 0.5642309785 ) - weight 149 6 0.0831768736 ( 1.3875783682 -3.2722742558 -1.6583921909 ) - weight 150 5 0.8543199301 ( -1.939458251 16.9476909637 -2.4218735695 ) - weight 151 6 0.1456800848 ( 3.3351011276 -0.7040598989 -0.2992684841 ) - weight 152 5 1 ( 0.6453074217 15.0546197891 -3.2220330238 ) - weight 153 5 1 ( 0.4033931494 10.081618309 -1.8114974499 ) - weight 154 5 1 ( 2.0674369335 10.2083835602 -0.3427814245 ) - weight 155 5 1 ( 1.1055467129 6.0715761185 -1.8681550026 ) - weight 156 5 0.5 ( -1.6836607456 20.16355896 3.0478773117 ) - weight 157 6 0.5 ( -2.5834205151 -1.7617925406 -2.3432145119 ) - weight 158 25 1 ( 0.9275875688 7.2957715988 -3.3785128593 ) - weight 159 25 1 ( -2.7143790722 7.1327643394 -3.1395404339 ) - weight 160 25 0.8784247637 ( -2.3203017712 10.7307882309 -2.6311776638 ) - weight 161 26 0.1215752512 ( -0.7492240667 -1.5532972813 -3.6283123493 ) - weight 162 25 0.8984447718 ( 1.7512446642 9.9629249573 -2.1052041054 ) - weight 163 26 0.1015552133 ( 2.8900508881 -1.0475029945 -1.6424623728 ) - weight 164 17 0.449130863 ( -0.2770932019 5.6961083412 -5.7161602974 ) - weight 165 19 0.4540952146 ( 0.0000000303 -4.7206392288 -4.4291329384 ) - weight 166 22 0.096773915 ( 0.0000000303 -12.116558075 -5.5154490471 ) - weight 167 17 0.5152887702 ( 3.7515227795 5.7953419685 -5.1341810226 ) - weight 168 19 0.3591423929 ( 3.9909200668 -4.4172315598 -3.681607008 ) - weight 169 22 0.125568822 ( 3.9909200668 -11.880027771 -4.7441487312 ) - weight 170 3 0.0887620747 ( 0.0000000219 2.0629615784 -7.0419249535 ) - weight 171 17 0.6063475609 ( -0.2928763628 3.0827322006 -6.647746563 ) - weight 172 19 0.3048903346 ( 0.0000000219 -7.4949612617 -4.4603471756 ) - weight 173 3 0.1464416832 ( 4.6321001053 1.9589729309 -6.3333845139 ) - weight 174 4 0.120930925 ( -6.4539165497 -4.1871528625 -2.0478725433 ) - weight 175 17 0.5861251354 ( 4.3722596169 2.8754427433 -6.2443447113 ) - weight 176 19 0.1465022862 ( 4.6321001053 -7.5362710953 -3.7454090118 ) - weight 177 17 0.1273706257 ( 7.3636474609 10.8545312881 -1.947201252 ) - weight 178 19 0.4415688813 ( 7.4895005226 1.4214830399 -2.1102924347 ) - weight 179 22 0.363877058 ( 7.4895005226 -6.2020187378 -2.665728569 ) - weight 180 24 0.0671834275 ( 0.1316781044 -2.970523119 -8.4243202209 ) - weight 181 17 0.3153382242 ( 8.411324501 8.011341095 0.2487125695 ) - weight 182 19 0.3789919317 ( 8.3737802505 -0.5478342175 0.9463784099 ) - weight 183 22 0.2489299327 ( 8.3737802505 -8.4323768616 0.2060216665 ) - weight 184 20 0.0567399301 ( 4.3490972519 -5.9853248596 -6.5877261162 ) - weight 185 17 0.316473484 ( 6.4286842346 8.4252567291 -3.6584334373 ) - weight 186 19 0.4292660952 ( 6.6178202629 -1.4368979931 -2.9898827076 ) - weight 187 22 0.2542604208 ( 6.6178202629 -8.972026825 -3.7931485176 ) - weight 188 17 0.1202539653 ( 4.2121686935 12.5123434067 -4.0768246651 ) - weight 189 19 0.4247384965 ( 4.4847998619 2.2807955742 -4.8395433426 ) - weight 190 22 0.3653951585 ( 4.4847998619 -5.1061477661 -5.3088884354 ) - weight 191 24 0.089612402 ( 3.1363787651 -5.6136827469 -7.3284492493 ) - weight 192 25 1 ( 2.7120165825 7.6324834824 -1.6183490753 ) - weight 193 25 0.8327695727 ( 3.1037299633 9.9404010773 1.020878315 ) - weight 194 26 0.1672303826 ( 2.9835214615 -0.904315412 1.7594306469 ) - weight 195 22 0.0771214515 ( 10.5706386566 -2.2360191345 2.516232729 ) - weight 196 25 0.9228785634 ( 1.9276049137 4.9491372108 -2.2725224495 ) - weight 197 25 1 ( -2.45870471 5.8695688248 -2.9298121929 ) - weight 198 25 1 ( -4.0109500885 6.6789622307 -0.6567005515 ) - weight 199 19 0.0508285165 ( 8.6673402786 8.3955688477 4.8748421669 ) - weight 200 22 0.3103339374 ( 8.6673402786 0.1311264038 4.9053516388 ) - weight 201 23 0.0798272043 ( 4.5237116814 6.4591135979 -1.8480114937 ) - weight 202 24 0.1801317483 ( -1.0461616516 4.6005573273 -2.0911750793 ) - weight 203 25 0.2787561417 ( 4.3732795715 1.9897093773 -1.831756711 ) - weight 204 20 0.1001224369 ( 4.64265728 2.5781784058 -1.8883962631 ) - weight 205 19 0.189502582 ( 7.2366695404 5.6184434891 5.9579463005 ) - weight 206 22 0.4047628939 ( 7.2366695404 -2.7304496765 5.7401714325 ) - weight 207 24 0.1485210061 ( 0.3845090866 5.435377121 -4.9527511597 ) - weight 208 20 0.2572135329 ( 3.2119865417 -0.2833976746 -1.0535764694 ) - weight 209 19 0.2537808418 ( 9.0340995789 3.8217997551 3.0478274822 ) - weight 210 22 0.4020117223 ( 9.0340995789 -4.2643585205 2.6834013462 ) - weight 211 24 0.076381281 ( -1.4129209518 2.3786070347 -6.4866600037 ) - weight 212 25 0.0616703294 ( 1.6802308559 4.8661475182 -4.8092479706 ) - weight 213 20 0.2061558366 ( 5.0094165802 -1.8173065186 -4.1103463173 ) - weight 214 22 0.2104583681 ( 8.9566688538 5.367931366 1.8660709858 ) - weight 215 23 0.0883276537 ( 1.4721127748 5.7074990273 3.3354125023 ) - weight 216 24 0.2880037725 ( -1.3354902267 1.5612765551 3.1456298828 ) - weight 217 25 0.4132102728 ( 2.0479450226 -0.7543191314 3.0476071835 ) - weight 218 22 0.2019269764 ( 10.2034502029 2.9910697937 3.9270219803 ) - weight 219 23 0.115218088 ( 3.4485723972 7.4492001534 1.211374402 ) - weight 220 24 0.2169577181 ( -2.5822715759 3.6222274303 0.7687683105 ) - weight 221 25 0.4658972621 ( 3.9222979546 1.6043533087 1.5065294504 ) - weight 222 22 0.1066465601 ( 11.6276416779 2.5019798279 1.9945480824 ) - weight 223 24 0.082949616 ( -4.0064630508 1.6897536516 0.2796783447 ) - weight 224 25 0.8104037642 ( 2.1068229675 3.0796408653 2.2342400551 ) - weight 225 19 0.0934283361 ( 9.1123189926 4.7844085693 1.4842780828 ) - weight 226 22 0.3328987956 ( 9.1123189926 -3.1680488586 1.2105107307 ) - weight 227 25 0.504265368 ( 0.3697827458 4.319413662 -3.642531395 ) - weight 228 20 0.0694075301 ( 5.087635994 -0.7209968567 -5.5832371712 ) - weight 229 19 0.3896191418 ( 8.652299881 3.1292157173 0.7079356313 ) - weight 230 22 0.4093904197 ( 8.652299881 -4.7486000061 0.2916916609 ) - weight 231 25 0.0671922043 ( -0.7797638774 4.8728508949 -5.0304207802 ) - weight 232 20 0.1337981522 ( 4.6276168823 -2.3015480042 -6.5020561218 ) - weight 233 19 0.1736020893 ( 8.3155002594 4.2229170799 -1.632753253 ) - weight 234 22 0.331809938 ( 8.3155002594 -3.4533996582 -1.943808794 ) - weight 235 24 0.1214219555 ( -0.6943216324 -2.248603344 -5.6757011414 ) - weight 236 25 0.3731659949 ( -2.8624007702 3.8847255707 -3.8160603046 ) - weight 237 25 0.4205686748 ( 1.4400014877 11.4228773117 3.0691342354 ) - weight 238 26 0.5794312954 ( 0.3222310543 -0.1931182146 3.0135490894 ) - weight 239 25 0.88492769 ( -0.14480865 10.4199752808 2.6888885498 ) - weight 240 26 0.1150723174 ( -0.613319993 -1.6069331169 2.1259150505 ) - weight 241 25 0.8383777142 ( -3.9867637157 10.588809967 -0.4868831635 ) - weight 242 26 0.1616222858 ( -2.9237699509 -2.387668848 -2.224593401 ) - weight 243 25 0.2587660253 ( -4.1667275429 12.4313373566 -0.6045206189 ) - weight 244 26 0.7412339449 ( -3.6336381435 -0.6912587881 -2.468338728 ) - weight 245 25 0.4776410162 ( -0.114676401 11.558131218 -3.0020632744 ) - weight 246 26 0.5223590136 ( 1.0531574488 -0.0487218201 -3.2105696201 ) - weight 247 25 0.3601590693 ( -2.5787849426 12.179060936 -2.3499720097 ) - weight 248 26 0.6398409009 ( -1.5417699814 -0.2875425816 -3.513759613 ) - weight 249 25 0.5487061739 ( 3.0538060665 11.5793333054 -1.5442327261 ) - weight 250 26 0.4512938261 ( 3.3163604736 0.843259573 -0.7111133337 ) - weight 251 25 1 ( 0.4438336492 8.7419519424 3.0878827572 ) - weight 252 25 0.8383777142 ( -3.2075200081 10.664645195 1.8308894634 ) - weight 253 26 0.1616222858 ( -3.0806667805 -2.2640097141 0.2136711776 ) - weight 254 25 1 ( -2.4039828777 6.6894249916 1.8346130848 ) - weight 255 17 0.1560927927 ( 8.3652687073 9.5174016953 3.4297437668 ) - weight 256 19 0.3652572036 ( 8.1714000702 1.9104971886 3.4573442936 ) - weight 257 22 0.3252667487 ( 8.1714000702 -6.2042579651 2.9233417511 ) - weight 258 20 0.1533832401 ( 4.1467170715 -3.7572059631 -3.8704061508 ) - weight 259 17 0.2015561014 ( 6.2955594063 9.2145423889 7.1821665764 ) - weight 260 19 0.2642347813 ( 5.8918495178 2.8338236809 6.9797320366 ) - weight 261 22 0.3287962675 ( 5.8918495178 -5.5941009521 6.5132517815 ) - weight 262 20 0.2054128349 ( 1.8671665192 -3.1470489502 -0.2804961205 ) - weight 263 19 0.0948961601 ( 3.5795500278 8.8181762695 6.6815099716 ) - weight 264 22 0.4634767175 ( 3.5795500278 0.3933029175 6.7421717644 ) - weight 265 23 0.0722427592 ( 6.6840867996 1.5225815773 -2.3880908489 ) - weight 266 24 0.1664817035 ( 4.0416283607 6.4373774529 -1.8289985657 ) - weight 267 20 0.2029026896 ( -0.4451329708 2.8403549194 -0.0515761375 ) - weight 268 17 0.1906848699 ( 2.4328575134 9.174571991 8.9040555954 ) - weight 269 19 0.2058832794 ( 1.939029932 3.336438179 8.3973207474 ) - weight 270 22 0.2979409397 ( 1.939029932 -5.2180290222 7.9695315361 ) - weight 271 20 0.1714980751 ( -2.0856530666 -2.7709770203 1.1757836342 ) - weight 272 18 0.133992821 ( 2.0207867622 9.2951927185 0.1661834717 ) - weight 273 17 0.0863279849 ( -0.2875749767 17.6150417328 -2.9451155663 ) - weight 274 19 0.2839872241 ( -0.0000000175 7.451417923 -5.6864366531 ) - weight 275 22 0.4494484961 ( -0.0000000175 0.1189002991 -5.698038578 ) - weight 276 39 0.0605599955 ( 5.5000338554 -2.7487328053 -3.3631818295 ) - weight 277 40 0.1196763366 ( -7.6211800575 -6.0028300285 -2.1034240723 ) - weight 278 19 0.1344032288 ( 4.1019601822 8.4969930649 -5.6311721802 ) - weight 279 22 0.4274182618 ( 4.1019601822 1.1555709839 -5.5510883331 ) - weight 280 23 0.1332542896 ( -5.6173138618 1.1336624622 -1.6792143583 ) - weight 281 24 0.2516222596 ( 3.5192184448 -5.8558826447 -1.0667304993 ) - weight 282 25 0.0533020496 ( -6.303914547 -2.160040617 -1.9119106531 ) - weight 283 19 0.1979081333 ( 6.5984601974 6.1081485748 -4.9428539276 ) - weight 284 22 0.3774667084 ( 6.5984601974 -1.284526825 -5.0753984451 ) - weight 285 23 0.0570001341 ( -5.3032402992 4.0157251358 -3.6811993122 ) - weight 286 24 0.1939489841 ( 1.0227184296 -5.3801927567 -3.5068283081 ) - weight 287 25 0.1736759692 ( -5.8687024117 1.2798073292 -2.53713727 ) - weight 288 19 0.1394121796 ( 1.4000599384 8.4774665833 7.1653380394 ) - weight 289 22 0.5321753025 ( 1.4000599384 0.0113868713 7.1941809654 ) - weight 290 21 0.0751778483 ( 5.6524200439 2.3301124573 0.4004330635 ) - weight 291 20 0.2532346845 ( -2.6246230602 2.4584388733 0.4004330635 ) - weight 292 22 0.1055573449 ( 11.1468305588 0.6763343811 4.0388622284 ) - weight 293 24 0.0612346157 ( -3.5256519318 3.7340679169 -1.5459671021 ) - weight 294 25 0.8332080245 ( 3.8487846851 3.7106647491 0.1580032706 ) - weight 295 22 0.2346942276 ( 9.0930109024 -0.3227005005 -4.5201997757 ) - weight 296 24 0.2036777884 ( -1.4718322754 -4.8249940872 -2.5450019836 ) - weight 297 25 0.561627984 ( -4.9376349449 2.749475956 -0.4325408638 ) - weight 298 22 0.7616530061 ( 0.000000016 6.7909126282 -1.6510283947 ) - weight 299 39 0.0707426295 ( 1.4614092112 -3.5664117336 3.2636539936 ) - weight 300 40 0.0967006236 ( -7.6211800575 -1.9558200836 4.5685882568 ) - weight 301 23 0.0709036738 ( -1.461405158 -3.5664477348 3.2635588646 ) - weight 302 22 0.7280092239 ( 2.5946099758 6.8535728455 -0.7384383678 ) - weight 303 23 0.0894822627 ( -0.7176495194 -0.963170588 3.7519469261 ) - weight 304 24 0.1825084984 ( 5.0265684128 -1.0432327986 4.6312713623 ) - weight 305 22 0.4795843363 ( 3.6837999821 4.6725578308 -3.5961685181 ) - weight 306 23 0.1561301053 ( -3.6395392418 0.2794250846 1.744884491 ) - weight 307 24 0.3642855883 ( 3.9373786449 -3.9009628296 2.4502563477 ) - weight 308 3 0.0785324425 ( 8.728518486 -7.9854354858 -3.2010765076 ) - weight 309 4 0.9214675426 ( -5.0235066414 6.5022315979 0.9810284972 ) - weight 310 22 0.4028716385 ( 7.2713694572 0.9188461304 5.3783316612 ) - weight 311 23 0.1384224147 ( 5.0855321884 4.9873733521 -1.2900811434 ) - weight 312 24 0.3638387024 ( 0.3498091698 5.0735373497 -1.3034553528 ) - weight 313 20 0.0948672518 ( 3.2466864586 3.3658981323 -1.4154160023 ) - weight 314 3 0.0863266289 ( 5.7889595032 5.7444572449 5.3466248512 ) - weight 315 17 0.3341448307 ( 6.1977133751 3.755916357 5.9204950333 ) - weight 316 19 0.1688850224 ( 5.7889595032 -2.7388362885 7.5566763878 ) - weight 317 22 0.1109910384 ( 5.7889595032 -11.1959037781 6.5981612206 ) - weight 318 20 0.1000070646 ( 1.7642765045 -8.7488517761 -0.1955866814 ) - weight 319 18 0.1996454149 ( 5.8707165718 3.3173179626 -1.2051868439 ) - weight 320 3 0.3293448985 ( 2.1477301121 2.2299842834 6.3577151299 ) - weight 321 17 0.1964480728 ( 2.6205313206 0.0514074787 6.2562885284 ) - weight 322 19 0.0816393122 ( 2.1477301121 -6.1508393288 8.872754097 ) - weight 323 22 0.0585389286 ( 2.1477301121 -14.7103767395 7.6092514992 ) - weight 324 18 0.3340287805 ( 2.2294869423 -0.1971549988 -0.1940965652 ) - weight 325 17 0.2491469532 ( 2.5400130749 3.2282612324 7.1184353828 ) - weight 326 19 0.2161560208 ( 2.0632500648 -2.8667340279 8.6498289108 ) - weight 327 22 0.1518869698 ( 2.0632500648 -11.4193878174 7.6758418083 ) - weight 328 20 0.0964680836 ( -1.9614329338 -8.9723358154 0.8820939064 ) - weight 329 18 0.2863419652 ( 2.1450068951 3.0938339233 -0.1275062561 ) - weight 330 3 0.0720492378 ( 9.740404129 -7.2863502502 -0.1620242 ) - weight 331 4 0.9279507399 ( -2.538310051 6.1978917122 3.097546339 ) - weight 332 3 0.1854663789 ( 8.8855390549 -7.3435897827 3.0419325829 ) - weight 333 4 0.8145336509 ( 0.7601891756 6.3306422234 3.4164350033 ) - weight 334 22 0.2993527055 ( 8.5918798447 3.3821754456 4.2053432465 ) - weight 335 23 0.1691163778 ( 3.8300094604 5.8166446686 1.3411947489 ) - weight 336 24 0.4106554091 ( -0.9707012177 3.9005489349 1.1598739624 ) - weight 337 25 0.1208755374 ( 4.0736289024 0.0592345297 0.860547483 ) - weight 338 22 0.3157365322 ( 7.2697792053 5.4760704041 2.5088114738 ) - weight 339 23 0.1305618137 ( 2.2220602036 4.0694847107 3.1776309013 ) - weight 340 24 0.4652858675 ( 0.3513994217 2.2040171623 3.2537689209 ) - weight 341 25 0.0884157941 ( 2.5161159039 -2.2030386925 2.0716798306 ) - weight 342 22 0.3791531324 ( 6.9991693497 4.0735206604 3.9729626179 ) - weight 343 23 0.1587525159 ( 3.7005889416 4.1218690872 1.7650722265 ) - weight 344 24 0.4620943964 ( 0.6220092773 3.6681683064 1.8512191772 ) - weight 345 5 0.6010227203 ( -3.0424702168 19.8325691223 0.3229868114 ) - weight 346 6 0.3989772201 ( 0.3539059162 -1.3238992691 -3.0924193859 ) - weight 347 5 0.1546468437 ( -0.6949375868 22.9932975769 -2.6968607903 ) - weight 348 6 0.4815303087 ( 0.7621282339 3.5413174629 -3.9776346684 ) - weight 349 7 0.3638228774 ( 2.0435092449 -3.3795998096 -1.8090840578 ) - weight 350 5 0.1531316042 ( 2.0245606899 23.5965881348 0.8108915091 ) - weight 351 6 0.4677073956 ( -3.4629609585 3.6919407845 -2.4978070259 ) - weight 352 7 0.3791610003 ( -2.4314398766 -3.4236738682 -1.6171352863 ) - weight 353 3 0.2864744067 ( 9.0277490616 -4.1181182861 -3.3883128166 ) - weight 354 4 0.5730586648 ( -5.2875628471 2.7387580872 1.9015061855 ) - weight 355 17 0.1404669136 ( 8.9297246933 -3.6702303886 -5.0998387337 ) - weight 356 3 0.0967469141 ( 8.8018436432 -7.2985687256 -4.1120114326 ) - weight 357 4 0.9032530785 ( -5.8981070518 5.7764267921 0.8575515747 ) - weight 358 22 0.3324160576 ( 6.5781202316 1.6232719421 -4.6563386917 ) - weight 359 23 0.1443967223 ( -4.8837404251 3.553899765 -0.810301125 ) - weight 360 24 0.2850297987 ( 1.0430583954 -4.9611330032 -0.599029541 ) - weight 361 25 0.2381574363 ( -5.100414753 -0.425029099 -0.2711748779 ) - weight 362 22 0.2266537994 ( 8.715880394 3.7594718933 -3.1219177246 ) - weight 363 24 0.2749993503 ( -1.094701767 -3.4267122746 1.5371704102 ) - weight 364 25 0.4983468354 ( -3.0968859196 0.0588836819 2.4194600582 ) - weight 365 22 0.3057387173 ( 6.6514701843 4.0911598206 -3.5549983978 ) - weight 366 23 0.1308492124 ( -3.7894015312 3.2985389233 1.648563385 ) - weight 367 24 0.3803289235 ( 0.9697084427 -3.8597927094 1.8688583374 ) - weight 368 25 0.183083117 ( -3.7029452324 -1.809912324 1.5830038786 ) - weight 369 22 0.2374293655 ( 8.3510599136 5.5010185242 -1.5986175537 ) - weight 370 23 0.0753508359 ( -1.9464302063 4.8695840836 3.3334989548 ) - weight 371 24 0.3531977534 ( -0.7298812866 -1.9034119844 3.278717041 ) - weight 372 25 0.3340220451 ( -1.4187968969 -1.2700814009 3.3704547882 ) - weight 373 22 0.3466660976 ( 6.7255296707 5.7394447327 -0.8456685543 ) - weight 374 23 0.1131498292 ( -1.0904508829 3.2780134678 3.3153088093 ) - weight 375 24 0.4739112258 ( 0.8956489563 -1.150462985 3.5171432495 ) - weight 376 25 0.0662728474 ( -0.8193642497 -2.7458517551 2.5166924 ) - weight 377 17 0.3154843152 ( 3.4382810593 8.5811395645 -5.0335617065 ) - weight 378 19 0.464012742 ( 3.7111198902 -1.7517236471 -4.5096735954 ) - weight 379 22 0.2205028981 ( 3.7111198902 -9.152053833 -5.3347287178 ) - weight 380 17 0.449130863 ( -0.2814445794 8.4800519943 -5.1030201912 ) - weight 381 19 0.4540952146 ( 0.000000026 -1.8886710405 -4.755106926 ) - weight 382 22 0.096773915 ( 0.000000026 -9.2668991089 -5.5912489891 ) - weight 383 17 0.1374716908 ( -0.2889642119 11.971862793 -4.3709244728 ) - weight 384 19 0.5412513018 ( -0.0000000157 1.6513518095 -5.1989607811 ) - weight 385 22 0.3212770224 ( -0.0000000157 -5.7015647888 -5.7222390175 ) - weight 386 26 1 ( 1.3738869429 10.347694397 2.9754035473 ) - weight 387 26 1 ( 2.2627801895 5.51841259 0.2142424136 ) - weight 388 26 0.3331983984 ( 3.0434453487 10.0306501389 0.1456489563 ) - weight 389 36 0.3078258038 ( -0.9099624753 1.8968087435 -0.185203746 ) - weight 390 37 0.3589757979 ( -0.848205626 1.5334900618 1.549562335 ) - weight 391 26 1 ( 0.9834462404 6.7014622688 2.6421215534 ) - weight 392 26 1 ( -1.3044497967 10.7035274506 3.2501916885 ) - weight 393 26 1 ( -2.1119155884 7.6590123177 1.8955726624 ) - weight 394 26 1 ( -3.3610711098 11.0113315582 1.0610027313 ) - weight 395 26 1 ( -3.3371810913 2.1001307964 0.5224706531 ) - weight 396 26 1 ( -3.470972538 7.1876959801 -0.8652486801 ) - weight 397 26 1 ( -1.4335670471 6.7024683952 -2.7854459286 ) - weight 398 26 1 ( -3.4689741135 11.049115181 -0.9946525097 ) - weight 399 26 1 ( -3.2083516121 1.9957014322 -2.0983309746 ) - weight 400 26 1 ( 1.8206882477 10.244682312 -1.8300266266 ) - weight 401 26 1 ( 1.4846509695 6.0889511108 -2.227080822 ) - weight 402 26 1 ( -1.0843976736 10.6558237076 -2.6841440201 ) - weight 403 32 1 ( 0.3017202914 0.1539534479 -0.7368940115 ) - weight 404 37 0.5 ( -1.0091338158 -0.350605607 0.3158347905 ) - weight 405 38 0.5 ( -0.965392828 -0.4461881816 1.8302931786 ) - weight 406 37 0.5 ( 0.0332200043 -0.7310042977 -0.3986097872 ) - weight 407 38 0.5 ( -0.0052731233 -0.8234690428 1.0072104931 ) - weight 408 26 0.3331983984 ( 2.4964044094 11.5712194443 -1.210562706 ) - weight 409 36 0.3078258038 ( 0.0385755748 0.6906408072 -1.6539959908 ) - weight 410 37 0.3589757979 ( 0.1003323868 0.5448438525 -0.0736352727 ) - weight 411 26 0.2839439809 ( 0.6076012254 12.1952381134 -0.7289421558 ) - weight 412 36 0.4689332843 ( 0.6791439056 -1.0267056227 -0.7433202267 ) - weight 413 37 0.2471227348 ( 0.7409006953 -1.2830886841 0.5876298547 ) - weight 414 32 0.4101817906 ( 0.6515015364 -0.7548061609 -0.5771866441 ) - weight 415 33 0.5898182392 ( -1.4182274342 0.2859310508 -0.5838063359 ) - weight 416 26 0.8549714684 ( 0.7184262872 10.4335622787 -0.7542364597 ) - weight 417 36 0.1450285167 ( 1.0854444504 0.4008009136 0.2124875933 ) - weight 418 26 1 ( -1.5944453478 10.5482130051 -0.780998826 ) - weight 419 32 0.8064539433 ( 0.8528338075 0.2682503462 0.4677165449 ) - weight 420 33 0.1935460418 ( -0.5352516174 0.840487659 0.461096853 ) - weight 421 32 0.4101817906 ( 1.700478673 0.1182811782 -0.6270560622 ) - weight 422 33 0.5898182392 ( -0.0635133013 0.120449163 -0.6336757541 ) - weight 423 32 0.8064539433 ( 1.7762082815 0.1405255646 0.1118030921 ) - weight 424 33 0.1935460418 ( 0.0045874459 0.080548346 0.1051833928 ) - weight 425 33 0.5 ( 1.7718011141 0.0705116019 -0.7417999506 ) - weight 426 34 0.5 ( -0.0309368484 0.2819408476 0.658246994 ) - weight 427 33 0.5 ( 2.0596923828 -0.3555820882 -0.7964026928 ) - weight 428 34 0.5 ( 0.4599118531 0.1286280304 0.7128497362 ) - weight 429 33 0.5 ( 1.8194415569 0.0818415582 -0.0653562695 ) - weight 430 34 0.5 ( -0.0280996095 0.2330538183 -0.0181966648 ) - weight 431 29 0.2609394193 ( 3.4309384823 0.6753618121 -0.887933135 ) - weight 432 30 0.6099424958 ( 1.5632362366 -0.9322116375 -0.9845008254 ) - weight 433 31 0.12911807 ( 0.8138040304 0.7212354541 0.9509115219 ) - weight 434 29 0.2609394193 ( 2.0289061069 0.6525307894 -1.5188814402 ) - weight 435 30 0.6099424958 ( 0.4959180057 0.020041341 -1.548732996 ) - weight 436 31 0.12911807 ( -0.4049805105 1.4699130058 1.5151436329 ) - weight 437 30 0.5 ( 2.4539160728 -0.0022466178 -1.3609035015 ) - weight 438 31 0.5 ( 0.1789940745 -0.3991045952 1.3273142576 ) - weight 439 26 1 ( -2.256975174 10.8294582367 0.3255695701 ) - weight 440 26 0.2443206161 ( -1.5937422514 14.4684305191 0.0114921732 ) - weight 441 29 0.5839904547 ( 0.1300996393 0.8935907483 1.0157077312 ) - weight 442 30 0.1716888845 ( -0.5393765569 1.5135896206 1.0561079979 ) - weight 443 29 0.0691876858 ( 2.7896282673 1.3589762449 0.7738754749 ) - weight 444 30 0.4924322069 ( 1.6821876764 0.0087676775 0.6709821224 ) - weight 445 31 0.4383800626 ( -0.0533102602 0.3369122148 -0.7045714855 ) - weight 446 30 0.5 ( 2.5661590099 -0.2897056043 -0.4935804307 ) - weight 447 31 0.5 ( 0.4865826368 -0.4240132272 0.4599910975 ) - weight 448 29 0.2834812105 ( 2.310696125 0.6775736809 1.0197733641 ) - weight 449 30 0.5160946846 ( 0.8828521967 -0.1512198895 0.9703447819 ) - weight 450 31 0.2004240751 ( -0.1297573149 1.1485087872 -1.003934145 ) - weight 451 29 0.2834812105 ( 1.5356853008 -0.0638208091 0.9168611169 ) - weight 452 30 0.5160946846 ( -0.1941132993 -0.15042153 0.9380455017 ) - weight 453 31 0.2004240751 ( -0.4399857819 2.1798253059 -0.9716348648 ) - weight 454 29 0.2609394193 ( 2.0918915272 -0.44607988 -1.3168998957 ) - weight 455 30 0.6099424958 ( -0.2038774937 -0.8162240982 -1.2984220982 ) - weight 456 31 0.12911807 ( 0.1949317157 2.3804945946 1.2648327351 ) - weight 457 26 0.2443206161 ( -1.5851362944 14.2736988068 1.0361591578 ) - weight 458 29 0.5839904547 ( 0.1833595335 -0.1475297213 0.9815278649 ) - weight 459 30 0.1716888845 ( -1.2219905853 0.7250332236 1.0685101748 ) - weight 460 26 0.2443206161 ( -1.3515813351 15.612285614 0.3233117461 ) - weight 461 29 0.5839904547 ( 1.3121774197 0.8675677776 0.758232832 ) - weight 462 30 0.1716888845 ( 0.2774306834 0.6762894988 0.7462162375 ) - weight 463 33 0.5 ( -0.2717975378 -0.7016180754 -0.561452508 ) - weight 464 34 0.5 ( 0.1214054748 2.4612231255 0.4778995514 ) - weight 465 26 1 ( -1.6943991184 10.7068223953 1.6243932247 ) - weight 466 26 0.7828121781 ( 0.462595135 10.500878334 1.8324614763 ) - weight 467 36 0.2171877921 ( -0.7024546266 -0.3876825273 1.9279168844 ) - weight 468 32 0.8064539433 ( 0.5449203849 -0.9030775428 0.9237832427 ) - weight 469 33 0.1935460418 ( -1.5992455482 0.2619233727 0.9171635509 ) - weight 470 37 0.5 ( -0.7680109739 -0.5373968482 -1.3274434805 ) - weight 471 38 0.5 ( -0.8404526711 -0.4586361349 0.163670972 ) - weight 472 37 0.5 ( -0.8789598942 0.2909027636 -1.5237979889 ) - weight 473 38 0.5 ( -0.889479816 0.3931635022 0.0689150915 ) - weight 474 37 0.5 ( -0.6989042759 -0.2194848061 -2.6562383175 ) - weight 475 38 0.5 ( -0.8232243061 0.0056675375 -1.1230555773 ) - weight 476 26 0.3331983984 ( 2.9522051811 11.7601833344 -0.5206297636 ) - weight 477 36 0.3078258038 ( -0.8045958281 0.6618305445 -1.5662404299 ) - weight 478 37 0.3589757979 ( -0.7428390384 0.5040309429 0.0092222393 ) - weight 479 37 0.5 ( 0.0090584308 0.461027056 -1.5815156698 ) - weight 480 38 0.5 ( 0.0050292318 0.4965902269 -0.0311180558 ) - weight 481 37 0.5 ( -0.1952883154 -0.6723145843 -2.279712677 ) - weight 482 38 0.5 ( -0.3398749828 -0.5272206068 -0.8352028728 ) - weight 483 37 0.5 ( 0.1855770499 -0.3597683907 -1.4530209303 ) - weight 484 38 0.5 ( 0.1158535182 -0.3451510668 -0.0073592602 ) - weight 485 37 0.5 ( -0.0767436922 -0.1661878526 -2.6328344345 ) - weight 486 38 0.5 ( -0.1985064149 0.0054464429 -1.1371843815 ) - weight 487 26 0.6501254439 ( 1.7420002222 10.4314002991 0.5649607182 ) - weight 488 36 0.3498745561 ( -0.5262140036 0.7162458301 0.514218092 ) - weight 489 26 1 ( 1.5111025572 10.3411369324 -0.4202666283 ) - weight 490 33 0.5 ( -0.2364605963 -0.7071360946 0.2055261582 ) - weight 491 34 0.5 ( 0.1368447691 2.4289619923 -0.2890790999 ) - weight 492 33 0.5 ( 2.0911688805 -0.3682382703 -0.0935803801 ) - weight 493 34 0.5 ( 0.4810789227 0.1021158546 0.0100274431 ) - weight 494 32 0.8064539433 ( 0.481515348 -0.8676604033 0.2664029002 ) - weight 495 33 0.1935460418 ( -1.6169104576 0.3323686123 0.2597832084 ) - weight 496 33 0.5 ( 0.98329705 -0.75341326 -0.2936115861 ) - weight 497 34 0.5 ( 0.5316650271 1.2739437819 0.2100586593 ) - weight 498 4 0.211769715 ( -0.2060724497 21.3827362061 -1.9706434011 ) - weight 499 5 0.7882302999 ( 0.3228326738 0.50228405 -2.3997702599 ) - weight 500 4 0.2941013873 ( -1.8384666443 22.617975235 0.4862731397 ) - weight 501 5 0.7058986425 ( 2.670879364 1.7133342028 -0.5978268981 ) - weight 502 4 0.211769715 ( -0.6257090569 22.7841968536 -2.3957448006 ) - weight 503 5 0.7882302999 ( 0.0825685337 2.0052990913 -2.3355960846 ) - weight 504 22 0.1330899894 ( 11.2868204117 3.4729499817 -0.3750984669 ) - weight 505 24 0.1222179085 ( -3.6656417847 -0.6798928976 1.2506484985 ) - weight 506 25 0.7446920872 ( -0.1484086812 2.2778730392 3.2064881325 ) - weight 507 22 0.4312410653 ( 5.3821601868 1.10679245 5.9322118759 ) - weight 508 23 0.1283100247 ( 5.7598209381 3.1315970421 -1.4025417566 ) - weight 509 24 0.3281306624 ( 2.2390184402 5.6274175644 -1.1155090332 ) - weight 510 20 0.1123182103 ( 1.3574771881 3.5538444519 -0.861536026 ) - weight 511 22 0.4648121297 ( 4.0500798225 4.7070732117 4.0569810867 ) - weight 512 23 0.1376403272 ( 3.9741852283 1.120603919 1.9171510935 ) - weight 513 24 0.3975475132 ( 3.5710988045 3.7521870136 2.4847717285 ) - weight 514 22 0.4866587222 ( 5.2421598434 5.5526542664 1.9103718996 ) - weight 515 23 0.0868105441 ( 1.7553223372 2.0221531391 2.9210691452 ) - weight 516 24 0.4265308082 ( 2.3790187836 1.6055774689 3.3303527832 ) - weight 517 22 0.7518678904 ( 3.0729999542 5.6567344666 2.9678616524 ) - weight 518 23 0.0723678172 ( 2.9501900673 -0.0638554692 2.686054945 ) - weight 519 24 0.175764218 ( 4.5481786728 2.6630673409 3.4344329834 ) - weight 520 22 0.7110148072 ( 3.6320300102 6.6992988586 1.0049717426 ) - weight 521 23 0.0715909079 ( 0.9553979039 0.1941411644 3.7845242023 ) - weight 522 24 0.217394352 ( 3.9891486168 0.7001773119 4.4769973755 ) - weight 523 22 0.5249072909 ( 4.5867500305 5.8286705017 -0.6713585854 ) - weight 524 23 0.0834142864 ( -0.7788878679 1.1682354212 3.0613639355 ) - weight 525 24 0.3916783631 ( 3.0344285965 -0.9761530161 3.6063690186 ) - weight 526 25 0.3857780397 ( -1.2215543985 12.089972496 2.9997034073 ) - weight 527 26 0.6142219305 ( -2.2066636086 -0.3902868927 1.9649629593 ) - weight 528 25 0.146963343 ( -0.4951398969 13.0806560516 3.1095454693 ) - weight 529 26 0.8530366421 ( -1.9260792732 0.7654191256 2.2917861938 ) - weight 530 25 0.0593079589 ( -3.2306723595 12.3572874069 1.7115147114 ) - weight 531 26 0.9406920671 ( -3.6038825512 -0.6601107717 0.0304302424 ) - weight 532 25 0.0593079589 ( -2.8961625099 13.7047843933 1.7667065859 ) - weight 533 26 0.9406920671 ( -3.7632594109 0.7148723602 0.1517215818 ) - weight 534 25 0.1007401645 ( -1.7324889898 13.6813201904 -2.5044190884 ) - weight 535 26 0.8992598653 ( -1.2273772955 1.4116054773 -3.4093267918 ) - weight 536 25 0.0593079589 ( -3.5300970078 13.7525482178 -0.554394722 ) - weight 537 26 0.9406920671 ( -3.5173056126 0.7539480329 -2.2419462204 ) - weight 538 22 0.1032253429 ( 10.456870079 2.0270195007 -3.0863790512 ) - weight 539 24 0.1232035086 ( -2.835691452 -3.3911736012 -0.1952819824 ) - weight 540 25 0.7735711336 ( -3.0894243717 2.4802644253 2.0064713955 ) - weight 541 22 0.8149345517 ( 2.3048799038 3.7849845886 5.9193916321 ) - weight 542 23 0.0842731968 ( 5.9450268745 -0.3314335346 0.7458642125 ) - weight 543 24 0.1007922292 ( 5.3162984848 5.6145973206 1.5626831055 ) - weight 544 22 0.8149345517 ( 1.8106400967 4.6890602112 4.1403317451 ) - weight 545 23 0.0842731968 ( 4.2014536858 -1.076815486 1.5402439833 ) - weight 546 24 0.1007922292 ( 5.8105382919 3.8355374336 2.466758728 ) - weight 547 22 0.7081469893 ( 0.0000000008 4.1182136536 4.7094516754 ) - weight 548 39 0.0580335744 ( -4.8858919144 -2.7320172787 0.6917703748 ) - weight 549 40 0.0559075251 ( -7.6211800575 4.4046602249 1.8958892822 ) - weight 550 23 0.0608324744 ( 4.8858957291 -2.7320113182 0.6916880012 ) - weight 551 21 0.1170794815 ( 4.2523598671 6.4369392395 -2.0842959881 ) - weight 552 17 0.1166878492 ( 0.4455221891 8.9692087173 8.0448865891 ) - weight 553 19 0.2024046481 ( -0.0000000176 2.8528363705 7.5393362045 ) - weight 554 22 0.3595457375 ( -0.0000000176 -5.6243476868 7.0723614693 ) - weight 555 21 0.1797282845 ( 4.2523598671 -3.3056221008 0.2786135674 ) - weight 556 20 0.0608123504 ( -4.0246829987 -3.1772956848 0.2786135674 ) - weight 557 18 0.0808211118 ( 0.0817568973 8.888874054 -0.7309865952 ) - weight 558 19 0.1394121796 ( -0.0000000032 7.6542425156 6.9932889938 ) - weight 559 22 0.5321753025 ( -0.0000000032 -0.7935295105 6.9504413605 ) - weight 560 21 0.2532346845 ( 4.2523598671 1.5251960754 0.1566934586 ) - weight 561 20 0.0751778483 ( -4.0246829987 1.6535224915 0.1566934586 ) - weight 562 17 0.2491469532 ( 0.4429515898 3.5669841766 6.657725811 ) - weight 563 19 0.2161560208 ( 0.000000001 -2.7068119049 7.9849395752 ) - weight 564 22 0.1518869698 ( 0.000000001 -11.2016448975 7.0275816917 ) - weight 565 21 0.0964680836 ( 4.2523598671 -8.8829193115 0.2338337898 ) - weight 566 18 0.2863419652 ( 0.0817569122 3.3115768433 -0.7757663727 ) - weight 567 3 0.3293448985 ( 0.0000000242 2.2702064514 5.8363952637 ) - weight 568 17 0.1964480728 ( 0.4464160502 0.1861367524 5.8805122375 ) - weight 569 19 0.0816393122 ( 0.0000000242 -6.1565937996 8.3499164581 ) - weight 570 22 0.0585389286 ( 0.0000000242 -14.6701545715 7.087931633 ) - weight 571 18 0.3340287805 ( 0.0817569345 -0.1569328308 -0.7154164314 ) - weight 572 3 0.5536454916 ( -0.0000000318 -1.383026123 5.4094052315 ) - weight 573 10 0.100471057 ( -6.1548333168 -0.8758280277 -2.8298521042 ) - weight 574 17 0.1726870537 ( 0.4219042361 -3.2567675114 4.5865883827 ) - weight 575 18 0.1731964052 ( 0.0817568824 -3.8101654053 -1.1424064636 ) - weight 576 3 0.4008017182 ( 2.1574800014 -2.1150360107 5.6972951889 ) - weight 577 4 0.3488021493 ( 5.6536464691 0.2298346609 -0.8835330606 ) - weight 578 17 0.1250136942 ( 2.5923531055 -4.0066213608 4.568965435 ) - weight 579 18 0.1253824681 ( 2.2392368317 -4.542175293 -0.8545165062 ) - weight 580 3 0.3689664006 ( 2.2408599854 -2.2401275635 6.591545105 ) - weight 581 4 0.4005262256 ( 6.4595313072 0.428953737 -0.5185884237 ) - weight 582 17 0.115083985 ( 2.7269308567 -4.3419766426 5.4006562233 ) - weight 583 18 0.1154234186 ( 2.3226168156 -4.6672668457 0.0397334099 ) - weight 584 3 0.2517192662 ( 6.6758599281 -3.1631278992 5.3717050552 ) - weight 585 4 0.4801626801 ( 3.7410595417 2.0066757202 2.9642076492 ) - weight 586 17 0.1804798096 ( 7.0845909119 -4.883026123 3.7492241859 ) - weight 587 18 0.0876382738 ( 6.7576169968 -5.5902671814 -1.1801066399 ) - weight 588 3 0.1905488819 ( 6.9014000893 -7.3547172546 4.9453716278 ) - weight 589 4 0.8094511032 ( 3.2438137531 6.1357135773 2.2529816628 ) - weight 590 3 0.2546746433 ( 2.8709900379 -7.365196228 7.1078958511 ) - weight 591 4 0.6834095716 ( 6.6958642006 5.6097631454 -0.7012609839 ) - weight 592 17 0.0619157404 ( 3.385663271 -9.431552887 4.6310477257 ) - weight 593 4 1 ( -2.7694809437 6.6280665398 2.6437215805 ) - weight 594 3 0.0569108799 ( 8.6981983185 -8.0943946838 2.307477951 ) - weight 595 4 0.9430891275 ( 0.1366993338 6.985874176 2.8506083488 ) - weight 596 3 0.1544193178 ( 5.4406056404 -8.223487854 -5.3938894272 ) - weight 597 4 0.7848661542 ( -5.9077644348 6.0245819092 -2.8485155106 ) - weight 598 17 0.0607145987 ( 5.2333641052 -7.2218551636 -7.8323974609 ) - weight 599 3 0.2152129114 ( 5.1066699028 -3.1478462219 -6.9544053078 ) - weight 600 4 0.3803589642 ( -7.2256202698 0.87042588 -2.7661027908 ) - weight 601 17 0.4044281542 ( 4.8103961945 -1.9249911308 -8.1029338837 ) - weight 602 3 0.2210763693 ( 0.0000000395 -7.9221572876 -3.4398748875 ) - weight 603 10 0.4381532967 ( 2.1461865902 4.9381327629 -7.1148171425 ) - weight 604 4 0.2796563208 ( -2.14879632 4.9376277924 -7.1144094467 ) - weight 605 17 0.0611140542 ( -0.0860971883 -7.4746675491 -5.5633497238 ) - weight 606 3 0.1548608094 ( -0.0000000167 -8.5789260864 1.2973151207 ) - weight 607 10 0.0788915828 ( -2.2788536549 5.9123644829 -5.5843901634 ) - weight 608 4 0.7662476301 ( 2.2770690918 5.9114599228 -5.5861153603 ) - weight 609 3 0.395593375 ( -0.0000000282 -7.2518959045 5.8062353134 ) - weight 610 10 0.4461740255 ( -6.4994254112 4.920715332 -3.7692387104 ) - weight 611 17 0.0704606622 ( 0.4446846545 -9.0481996536 3.5570709705 ) - weight 612 18 0.0877719074 ( 0.0817568824 -9.6790351868 -0.7455763817 ) - weight 613 3 0.2185422033 ( 0.0000000011 -3.5584259033 -7.7262840271 ) - weight 614 10 0.1087745428 ( 6.1332345009 0.351282835 -7.8074316978 ) - weight 615 4 0.0951625928 ( -6.1367554665 0.3512171805 -7.8046784401 ) - weight 616 17 0.4620711505 ( -0.3321626782 -2.2084400654 -8.6652450562 ) - weight 617 19 0.1154495254 ( 0.0000000011 -13.1547441483 -4.6479725838 ) - weight 618 3 0.2679378986 ( 4.8128800392 -0.9101257324 -6.387304306 ) - weight 619 4 0.2285530865 ( -6.5812325478 -1.3398913145 -2.4276192188 ) - weight 620 17 0.503508985 ( 4.5496459007 0.1063350961 -6.9979310036 ) - weight 621 3 0.2287210673 ( 8.735039711 -1.0005874634 -2.5254654884 ) - weight 622 4 0.3527418673 ( -4.3631567955 -0.3157050908 2.5055847168 ) - weight 623 17 0.4185370207 ( 8.6870298386 -0.8561355472 -3.4963572025 ) - weight 624 3 0.2185422033 ( 0.0000001289 -0.859046936 -7.3067646027 ) - weight 625 10 0.1087745428 ( 5.7289843559 -2.2730636597 -7.1655359268 ) - weight 626 4 0.0951625928 ( -5.7325534821 -2.2731084824 -7.1626672745 ) - weight 627 17 0.4620711505 ( -0.3080796301 0.3105072379 -7.6083779335 ) - weight 628 19 0.1154495254 ( 0.0000001289 -10.4289388657 -4.467335701 ) - weight 629 4 1 ( -3.1933557987 15.5926094055 2.8035349846 ) - weight 630 3 0.0545195229 ( 8.8855199814 -16.3318901062 3.2250254154 ) - weight 631 4 0.9454804659 ( 0.8914284706 15.1785106659 1.8286502361 ) - weight 632 12 0.0843834653 ( 0.2005139738 6.4286637306 4.4115839005 ) - weight 633 13 0.5620473027 ( 1.5335919857 3.6064865589 2.4241364002 ) - weight 634 14 0.3535692692 ( 1.4949821234 -1.4960969687 2.4291889668 ) - weight 635 11 0.0935239866 ( -3.8111162186 18.6099414825 -1.0356494188 ) - weight 636 12 0.6671485305 ( 0.7658373713 3.1304473877 2.2976405621 ) - weight 637 13 0.2393274605 ( 1.2482595444 -0.3180602491 2.8520338535 ) - weight 638 12 0.4737676382 ( 1.8243252039 5.0132069588 1.8210145235 ) - weight 639 13 0.5262323618 ( 2.254673481 0.5913560987 1.1049090624 ) - weight 640 13 0.5046935678 ( -2.2403481007 4.8383469582 -0.8591220379 ) - weight 641 14 0.495306462 ( -2.2457537651 -0.1773366779 -0.8583108187 ) - weight 642 13 0.5011257529 ( 2.0092220306 4.9650716782 -0.9881343246 ) - weight 643 14 0.4988743067 ( 2.0056653023 -0.1622206718 -0.987760663 ) - weight 644 12 0.4963374138 ( -2.4832983017 6.207262516 -1.8910052776 ) - weight 645 13 0.5036625266 ( -2.8364603519 0.2825944126 -1.678165555 ) - weight 646 12 0.4661476612 ( 2.9381554127 6.6803898811 -0.1895406246 ) - weight 647 13 0.4800623953 ( 2.864084959 0.4030622244 -1.6619685888 ) - weight 648 14 0.0537899137 ( 2.7408871651 -4.7473263741 -1.6458106041 ) - weight 649 11 0.3033103049 ( -1.7669993639 19.893743515 0.9123718739 ) - weight 650 12 0.6966896653 ( 2.0454998016 1.4687638283 0.0123342369 ) - weight 651 11 0.6232063174 ( -2.4196417332 19.3630924225 3.0818741322 ) - weight 652 12 0.2971909642 ( 3.9312999249 0.4099192321 0.8707507253 ) - weight 653 13 0.079602696 ( 3.6844074726 -3.9935793877 2.9668507576 ) - weight 654 11 0.5 ( 1.1285079718 20.9284076691 2.73594594 ) - weight 655 12 0.5 ( 2.7857880592 -0.802236855 -2.6474480629 ) - weight 656 11 0.2689843774 ( -3.6825115681 18.1095924377 0.4463469386 ) - weight 657 12 0.5431468487 ( 1.7715919018 1.9667264223 2.6097512245 ) - weight 658 13 0.1878687739 ( 2.2188930511 -1.2560831308 3.652774334 ) - weight 659 11 0.1060663685 ( -3.8947956562 17.6123886108 -2.6348772049 ) - weight 660 12 0.4873141348 ( -0.9071980715 3.5118243694 3.0819518566 ) - weight 661 13 0.3494953811 ( -0.1032676175 0.8336918354 3.4895932674 ) - weight 662 14 0.0571241342 ( -0.2137247175 -4.2214417458 3.5042307377 ) - weight 663 11 0.3997223675 ( 1.158430934 23.7406368256 2.4658248425 ) - weight 664 12 0.416490972 ( 3.5817542076 0.8614727855 -4.7877764702 ) - weight 665 13 0.1837866157 ( 1.7758816481 -6.9593873024 -1.4948221445 ) - weight 666 11 0.4107972383 ( 3.0410678387 23.354347229 0.2583812177 ) - weight 667 12 0.4213652015 ( 0.8306982517 0.6585352421 -5.7659673691 ) - weight 668 13 0.1678375453 ( -1.1468132734 -7.0609121323 -1.6127064228 ) - weight 669 13 0.5249262452 ( -0.318746835 4.791823864 1.1942292452 ) - weight 670 14 0.475073725 ( -0.3258403242 -0.2669897974 1.1951891184 ) - weight 671 11 0.0803422183 ( -2.1340589523 18.395866394 -3.2236113548 ) - weight 672 12 0.6961277723 ( -1.8226180077 3.1415815353 1.3253749609 ) - weight 673 13 0.2235300243 ( -1.5025411844 -0.2899705768 2.5730495453 ) - weight 674 12 0.1096295714 ( -2.8514502048 6.0545558929 3.1862442493 ) - weight 675 13 0.5836595297 ( -1.7587682009 3.2957515717 2.2837510109 ) - weight 676 14 0.3067108989 ( -1.804390192 -1.7211198807 2.2898793221 ) - weight 677 11 0.120941259 ( -0.4893733263 19.3922748566 -3.2120206356 ) - weight 678 12 0.7397739887 ( -2.1099298 2.6337285042 -0.5069711804 ) - weight 679 13 0.13928473 ( -2.3319923878 -1.7106440067 1.577231884 ) - weight 680 11 0.1834091842 ( -1.6652473211 17.661901474 -4.2978253365 ) - weight 681 12 0.5260417461 ( -3.1817188263 3.0291199684 1.554770112 ) - weight 682 13 0.2905490696 ( -2.7451124191 0.0778421834 3.0559110641 ) - weight 683 11 0.307454288 ( 0.8623791933 18.9465789795 -3.3936226368 ) - weight 684 12 0.5233104229 ( -2.9713423252 1.6302224398 -1.0635700226 ) - weight 685 13 0.1692353189 ( -3.3826670647 -2.6122376919 1.9541528225 ) - weight 686 11 0.5 ( 2.5797746181 20.61211586 0.722977221 ) - weight 687 12 0.5 ( 0.397441864 -0.7988775969 -3.3917925358 ) - weight 688 3 0.2396446764 ( -8.9375400543 2.2950515747 1.6243751049 ) - weight 689 10 0.1261993945 ( 0.5424489975 -3.2338209152 4.7411856651 ) - weight 690 17 0.5096623302 ( -8.7181806564 1.0997873545 2.3032550812 ) - weight 691 19 0.0713101402 ( -8.9375400543 -6.5020551682 4.1520137787 ) - weight 692 18 0.0531834662 ( -8.8557834625 -0.1320877075 -4.9274363518 ) - weight 693 3 0.1069236025 ( -7.8959794044 5.1963424683 -3.1774241924 ) - weight 694 10 0.055033993 ( 4.6477074623 -6.5960149765 2.64306283 ) - weight 695 17 0.5240889192 ( -7.9539895058 5.0850338936 -1.7084076405 ) - weight 696 19 0.1887804121 ( -7.8959794044 -4.0340409279 -0.886207521 ) - weight 697 22 0.1251730919 ( -7.8959794044 -11.7440185547 -1.9258878231 ) - weight 698 3 0.2287210673 ( -8.6952495575 1.7104263306 -2.5718448162 ) - weight 699 10 0.3527418673 ( 4.3813056946 -2.9914598465 2.9486467838 ) - weight 700 17 0.4185370207 ( -8.7171773911 1.5450892448 -1.9169889688 ) - weight 701 3 0.2374471128 ( -9.0758104324 -1.4819068909 1.7993452549 ) - weight 702 10 0.4392165542 ( 0.4449803829 0.5145294666 4.2356991768 ) - weight 703 17 0.323336333 ( -8.8461780548 -2.6099052429 1.5704888105 ) - weight 704 3 0.0989223495 ( -8.4342899323 5.5740737915 1.8654054403 ) - weight 705 10 0.0575829931 ( 0.1236147806 -6.5259227753 4.9647574425 ) - weight 706 17 0.3998931944 ( -8.2019233704 4.2311964035 3.2987952232 ) - weight 707 19 0.1923786998 ( -8.4342899323 -3.2145380974 4.1039056778 ) - weight 708 22 0.1035134494 ( -8.4342899323 -11.3662872314 3.1169419289 ) - weight 709 21 0.0805758238 ( -4.1819300652 -9.0475616455 -3.6768059731 ) - weight 710 18 0.0671336129 ( -8.3525333405 3.1469345093 -4.6864061356 ) - weight 711 3 0.2791765332 ( -6.444149971 2.2682609558 5.2955350876 ) - weight 712 10 0.0813388303 ( -3.7749552727 -3.3768761158 3.7239918709 ) - weight 713 17 0.3838120401 ( -6.0181555748 0.2252162695 5.7150168419 ) - weight 714 19 0.0837190822 ( -6.444149971 -6.2060699463 7.8113207817 ) - weight 715 22 0.0516345128 ( -6.444149971 -14.6721000671 6.5470714569 ) - weight 716 18 0.1203189269 ( -6.3623929024 -0.1588783264 -1.2562766075 ) - weight 717 3 0.1548608094 ( -1.0088499784 -8.7325363159 1.4380851984 ) - weight 718 10 0.7662476301 ( -2.0512673855 6.2447109222 -4.6362652779 ) - weight 719 4 0.0788915828 ( 2.7660245895 5.9004707336 -6.4927530289 ) - weight 720 3 0.2173970491 ( -3.0921397209 -7.1752662659 3.609495163 ) - weight 721 10 0.7826029658 ( -3.347671032 5.2189002037 -1.6786891222 ) - weight 722 3 0.0597552843 ( -3.0285468102 -16.1775875092 0.7946403027 ) - weight 723 10 0.9402447343 ( -0.6987450123 13.86195755 -4.3712697029 ) - weight 724 3 0.2056824863 ( -1.4231300354 -8.4189376831 -3.8824949265 ) - weight 725 10 0.7073415518 ( 3.0678319931 5.6377983093 -6.0522542 ) - weight 726 17 0.0869759843 ( -1.5322893858 -7.8700299263 -6.0326251984 ) - weight 727 3 0.3385702968 ( -5.1066098213 -7.2581672668 -7.5305342674 ) - weight 728 10 0.5283104777 ( 7.7814154625 4.8701810837 -3.7249174118 ) - weight 729 17 0.1331192106 ( -5.4191141129 -5.9169063568 -9.0824623108 ) - weight 730 10 1 ( -2.0194113255 17.0197486877 -1.7512795925 ) - weight 731 3 0.0721849874 ( -6.9160900116 -8.1293678284 4.1621651649 ) - weight 732 10 0.9278150201 ( -2.5012068748 6.8454823494 1.8534601927 ) - weight 733 10 1 ( 1.5941376686 17.51603508 -5.0863404274 ) - weight 734 10 0.740267396 ( 4.2336611748 20.0336494446 -5.3213171959 ) - weight 735 11 0.2597326636 ( 3.7972025871 0.4693029821 1.1278011799 ) - weight 736 10 0.6035490036 ( 2.149392128 20.8791847229 -5.5186281204 ) - weight 737 11 0.3964509964 ( 3.5267856121 0.8683485985 -1.0780265331 ) - weight 738 10 0.3635103106 ( 4.8803710938 22.6644496918 -6.2127604485 ) - weight 739 11 0.6364896297 ( 4.3162903786 3.2734870911 1.0943518877 ) - weight 740 10 0.2838164866 ( 7.1277294159 21.8929920197 -3.2046394348 ) - weight 741 11 0.7161834836 ( 1.8627429008 2.6001296043 3.9616248608 ) - weight 742 11 1 ( 4.5449433327 5.4189944267 2.522043705 ) - weight 743 11 1 ( 1.9424042702 5.4115934372 4.9871730804 ) - weight 744 10 0.0533990003 ( 3.1104099751 24.6857204437 0.2727412581 ) - weight 745 11 0.9466010332 ( -2.6117572784 3.971694231 0.2028981447 ) - weight 746 10 0.3121370077 ( 4.4104804993 21.7292518616 1.1969943047 ) - weight 747 11 0.6878629327 ( -2.8097553253 1.2642891407 2.1817586422 ) - weight 748 10 0.0613344088 ( 6.7926473618 24.7603607178 0.0433005095 ) - weight 749 11 0.9386655688 ( -1.8381597996 4.8623733521 3.6993708611 ) - weight 750 10 0.2215298414 ( 7.4688601494 22.7167358398 -0.8187316656 ) - weight 751 11 0.7784701586 ( -0.5479092002 3.1467094421 4.5760245323 ) - weight 752 10 0.7058917284 ( 6.3501329422 19.5796222687 -0.1707217842 ) - weight 753 11 0.2941082716 ( -0.8160378933 -0.2152439654 4.2041039467 ) - weight 754 10 1 ( -0.7209718823 19.3569736481 -2.3775877953 ) - weight 755 10 0.7103045583 ( 0.7538217902 19.7825641632 0.8479977846 ) - weight 756 11 0.2896954417 ( -2.6978392601 -1.353615284 -1.0457158089 ) - weight 757 10 0.7103045583 ( 1.1478338242 21.2382240295 0.2823555768 ) - weight 758 11 0.2896954417 ( -2.3346145153 0.2155238986 -1.0426585674 ) - weight 759 10 0.3121370077 ( 3.7808358669 20.317232132 1.7208321095 ) - weight 760 11 0.6878629327 ( -3.1757318974 -0.3073529005 1.9354714155 ) - weight 761 3 0.051912196 ( -7.8446297646 -21.3117198944 -5.241314888 ) - weight 762 10 0.7836181521 ( 6.6775922775 19.3091106415 -2.9910881519 ) - weight 763 11 0.1644695997 ( 2.0256447792 -0.0247785393 4.0510172844 ) - weight 764 11 1 ( 3.6565918922 10.4444408417 4.9001312256 ) - weight 765 11 1 ( 4.5032229424 10.0473222733 2.0080478191 ) - weight 766 11 1 ( 4.2849411964 13.5269527435 1.7910120487 ) - weight 767 11 1 ( 2.971432209 10.5053901672 -1.4524589777 ) - weight 768 10 0.0812822282 ( 3.5914702415 26.3057136536 -5.7968535423 ) - weight 769 11 0.918717742 ( 3.0948569775 6.464184761 -0.7551311851 ) - weight 770 11 1 ( -1.2039601803 8.7901582718 4.2538671494 ) - weight 771 11 1 ( -2.7534117699 12.114613533 1.511080265 ) - weight 772 11 1 ( -1.8060926199 15.6041793823 3.1001300812 ) - weight 773 11 1 ( -2.9188184738 14.9884338379 -1.3725758791 ) - weight 774 11 1 ( 0.0046346094 13.0744123459 4.1822147369 ) - weight 775 11 1 ( 1.7261306047 16.3162078857 4.1289916039 ) - weight 776 11 0.9168231487 ( 3.7256224155 17.2638645172 0.5709806085 ) - weight 777 12 0.0831768736 ( -1.4236763716 -3.2722740173 -1.6275085211 ) - weight 778 11 0.8543199301 ( 1.9440462589 16.9057292938 -2.4179177284 ) - weight 779 12 0.1456800848 ( -3.3408706188 -0.7040597796 -0.2259279639 ) - weight 780 11 1 ( -0.6386532187 15.01126194 -3.22143507 ) - weight 781 11 1 ( -0.3971737325 10.039059639 -1.8080117702 ) - weight 782 11 1 ( -2.063710928 10.1659154892 -0.342133522 ) - weight 783 11 1 ( -1.0976873636 6.0287184715 -1.8638336658 ) - weight 784 11 0.5 ( 1.6778975725 20.1242313385 3.049790144 ) - weight 785 12 0.5 ( 2.5313193798 -1.7617923021 -2.3994040489 ) - weight 786 41 1 ( 3.8567552567 7.0149421692 2.0043172836 ) - weight 787 41 1 ( 3.2663300037 7.2312960625 -1.5945982933 ) - weight 788 41 0.8784247637 ( 3.3650388718 10.6294679642 1.7742804289 ) - weight 789 42 0.1215752512 ( 3.5733807087 -1.7166386843 0.8082980514 ) - weight 790 41 0.8984447718 ( 1.908369422 9.9396085739 -2.0787651539 ) - weight 791 42 0.1015552133 ( 1.5035102367 -1.2628592253 -2.7907953262 ) - weight 792 17 0.5152887702 ( -4.2171549797 5.684943676 -4.6894741058 ) - weight 793 19 0.3591423929 ( -3.9909203053 -4.4172315598 -3.681607008 ) - weight 794 22 0.125568822 ( -3.9909203053 -11.880027771 -4.7441487312 ) - weight 795 3 0.1464416832 ( -4.6320996284 1.9589767456 -6.333384037 ) - weight 796 10 0.120930925 ( 6.452434063 -4.1877903938 -2.0512895584 ) - weight 797 17 0.5861251354 ( -4.8766627312 2.7473115921 -5.7281894684 ) - weight 798 19 0.1465022862 ( -4.6320996284 -7.5362672806 -3.7454090118 ) - weight 799 17 0.3153382242 ( -8.3086175919 7.7796988487 1.1817994118 ) - weight 800 19 0.3789919317 ( -8.3737802505 -0.5478380322 0.9463787079 ) - weight 801 22 0.2489299327 ( -8.3737802505 -8.4323806763 0.2060216665 ) - weight 802 21 0.0567399301 ( -4.1214203835 -6.1136550903 -6.5877261162 ) - weight 803 17 0.1273706257 ( -7.5906515121 10.647354126 -1.1126486063 ) - weight 804 19 0.4415688813 ( -7.4895000458 1.4214830399 -2.1102924347 ) - weight 805 22 0.363877058 ( -7.4895000458 -6.2020187378 -2.665728569 ) - weight 806 40 0.0671834275 ( -0.1316800117 -2.9705202579 -8.4243431091 ) - weight 807 17 0.316473484 ( -6.7851295471 8.2421922684 -2.9210119247 ) - weight 808 19 0.4292660952 ( -6.6178197861 -1.4368979931 -2.9898827076 ) - weight 809 22 0.2542604208 ( -6.6178197861 -8.972026825 -3.7931485176 ) - weight 810 17 0.1202539653 ( -4.7426395416 12.3882827759 -3.5770843029 ) - weight 811 19 0.4247384965 ( -4.4847998619 2.2807955742 -4.8395428658 ) - weight 812 22 0.3653951585 ( -4.4847998619 -5.1061477661 -5.3088879585 ) - weight 813 40 0.089612402 ( -3.1363801956 -5.613679409 -7.3284721375 ) - weight 814 41 1 ( 1.1561223269 7.6366329193 -2.9281907082 ) - weight 815 41 0.8327695727 ( -1.4427342415 10.009853363 -2.6848526001 ) - weight 816 42 0.1672303826 ( -1.8871777058 -0.938195467 -2.7915349007 ) - weight 817 41 1 ( 3.5619676113 5.7611279488 1.7897080183 ) - weight 818 22 0.0771214515 ( -10.5706396103 -2.2360153198 2.5162334442 ) - weight 819 41 0.9228785634 ( 1.9020180702 4.9268155098 -2.341571331 ) - weight 820 41 1 ( 1.7224894762 6.5966963768 3.8268036842 ) - weight 821 19 0.189502582 ( -7.2366704941 5.6184434891 5.9579463005 ) - weight 822 22 0.4047628939 ( -7.2366704941 -2.7304496765 5.7401714325 ) - weight 823 40 0.1485210061 ( -0.3845095634 5.435379982 -4.9527740479 ) - weight 824 21 0.2572135329 ( -2.984310627 -0.4117240906 -1.0535764694 ) - weight 825 19 0.0508285165 ( -8.6673402786 8.395565033 4.8748426437 ) - weight 826 22 0.3103339374 ( -8.6673402786 0.1311225891 4.9053516388 ) - weight 827 39 0.0798272043 ( -4.5237154961 6.4590725899 -1.8480627537 ) - weight 828 40 0.1801317483 ( 1.0461602211 4.6005597115 -2.0912017822 ) - weight 829 41 0.2787561417 ( 0.8411581516 2.0180459023 -4.6540184021 ) - weight 830 21 0.1001224369 ( -4.4149804115 2.449848175 -1.8883965015 ) - weight 831 19 0.2537808418 ( -9.0340986252 3.8217959404 3.0478277206 ) - weight 832 22 0.4020117223 ( -9.0340986252 -4.2643623352 2.6834015846 ) - weight 833 40 0.076381281 ( 1.4129185677 2.3786098957 -6.4866867065 ) - weight 834 41 0.0616703294 ( 4.4256300926 4.7823200226 -2.6786165237 ) - weight 835 21 0.2061558366 ( -4.7817387581 -1.9456367493 -4.1103463173 ) - weight 836 22 0.2019269764 ( -10.2034502029 2.9910697937 3.9270217419 ) - weight 837 39 0.115218088 ( -3.448577404 7.4492030144 1.2113131285 ) - weight 838 40 0.2169577181 ( 2.5822701454 3.6222300529 0.7687454224 ) - weight 839 41 0.4658972621 ( -2.3162212372 1.7012797594 -3.4595828056 ) - weight 840 22 0.2104583681 ( -8.9566707611 5.3679389954 1.8660719395 ) - weight 841 39 0.0883276537 ( -1.4721176624 5.7075338364 3.3353838921 ) - weight 842 40 0.2880037725 ( 1.3354907036 1.5612801313 3.145614624 ) - weight 843 41 0.4132102728 ( -3.4515116215 -0.6518004537 -1.3088598251 ) - weight 844 22 0.1066465601 ( -11.6276416779 2.5019798279 1.9945477247 ) - weight 845 40 0.082949616 ( 4.0064616203 1.6897560358 0.2796554565 ) - weight 846 41 0.8104037642 ( -2.5742735863 3.1631753445 -1.5106711388 ) - weight 847 19 0.0934283361 ( -9.1123180389 4.7844009399 1.4842799902 ) - weight 848 22 0.3328987956 ( -9.1123180389 -3.168056488 1.2105119228 ) - weight 849 41 0.504265368 ( 3.573390007 4.2410974503 -1.1429817677 ) - weight 850 21 0.0694075301 ( -4.8599581718 -0.8493309021 -5.5832362175 ) - weight 851 19 0.3896191418 ( -8.652299881 3.1292119026 0.7079359889 ) - weight 852 22 0.4093904197 ( -8.652299881 -4.7486038208 0.2916916609 ) - weight 853 41 0.0671922043 ( 5.1998987198 4.7442646027 -0.3334948123 ) - weight 854 21 0.1337981522 ( -4.3999400139 -2.4298782349 -6.5020561218 ) - weight 855 19 0.1736020893 ( -8.3154993057 4.2229094505 -1.6327515841 ) - weight 856 22 0.331809938 ( -8.3154993057 -3.4534072876 -1.9438078403 ) - weight 857 40 0.1214219555 ( 0.6943192482 -2.2485995293 -5.6757316589 ) - weight 858 41 0.3731659949 ( 4.4653058052 3.7504274845 1.960211277 ) - weight 859 41 0.88492769 ( -2.3163278103 10.4746017456 0.862836659 ) - weight 860 42 0.1150723174 ( -2.1769599915 -1.4616115093 0.8426523805 ) - weight 861 41 0.4205686748 ( -3.0206503868 11.5113401413 -0.5832348466 ) - weight 862 42 0.5794312954 ( -3.0170457363 -0.0437099785 -0.1298863739 ) - weight 863 41 0.2587660253 ( 1.8552689552 12.3455047607 4.0511846542 ) - weight 864 42 0.7412339449 ( 2.5525553226 -0.6670557857 3.6831498146 ) - weight 865 41 0.8383777142 ( 1.652402997 10.5092687607 3.8832278252 ) - weight 866 42 0.1616222858 ( 2.1964781284 -2.3770544529 3.0584573746 ) - weight 867 41 0.4776410162 ( 3.2464129925 11.4837055206 -0.4490174055 ) - weight 868 42 0.5223590136 ( 3.1797749996 -0.2718235552 -1.0476200581 ) - weight 869 41 0.3601590693 ( 3.1873018742 12.0793809891 2.1052513123 ) - weight 870 42 0.6398409009 ( 3.5515031815 -0.4130378366 1.5455417633 ) - weight 871 41 0.5487061739 ( 1.1080173254 11.5891532898 -3.2024080753 ) - weight 872 42 0.4512938261 ( 0.6612677574 0.6554980278 -3.2752220631 ) - weight 873 41 1 ( -2.881683588 8.8157901764 0.3626789749 ) - weight 874 41 0.8383777142 ( -0.7790445089 10.6502428055 3.6524932384 ) - weight 875 42 0.1616222858 ( -0.2255678177 -2.1135728359 3.280538559 ) - weight 876 41 1 ( -1.0676083565 6.6896262169 2.8288831711 ) - weight 877 17 0.2015561014 ( -5.4687080383 9.0515642166 7.8386945724 ) - weight 878 19 0.2642347813 ( -5.8918499947 2.8338274956 6.9797315598 ) - weight 879 22 0.3287962675 ( -5.8918499947 -5.5940971375 6.5132517815 ) - weight 880 21 0.2054128349 ( -1.6394901276 -3.2753715515 -0.2804961205 ) - weight 881 17 0.1560927927 ( -7.9505810738 9.2913618088 4.3402805328 ) - weight 882 19 0.3652572036 ( -8.1714000702 1.9104971886 3.4573440552 ) - weight 883 22 0.3252667487 ( -8.1714000702 -6.2042579651 2.9233417511 ) - weight 884 21 0.1533832401 ( -3.9190402031 -3.8855323792 -3.8704061508 ) - weight 885 17 0.1906848699 ( -1.4388073683 9.1209344864 9.1201210022 ) - weight 886 19 0.2058832794 ( -1.9390301704 3.336438179 8.3973207474 ) - weight 887 22 0.2979409397 ( -1.9390301704 -5.2180290222 7.9695315361 ) - weight 888 21 0.1714980751 ( 2.3133296967 -2.8993034363 1.1757836342 ) - weight 889 18 0.133992821 ( -1.857273221 9.2951927185 0.1661834717 ) - weight 890 19 0.0948961601 ( -3.5795497894 8.8181762695 6.6815094948 ) - weight 891 22 0.4634767175 ( -3.5795497894 0.3933029175 6.7421712875 ) - weight 892 39 0.0722427592 ( -6.6840858459 1.5225300789 -2.3880689144 ) - weight 893 40 0.1664817035 ( -4.0416302681 6.437379837 -1.8290214539 ) - weight 894 21 0.2029026896 ( 0.6728100777 2.7120285034 -0.0515766144 ) - weight 895 19 0.1344032288 ( -4.1019601822 8.4969930649 -5.631172657 ) - weight 896 22 0.4274182618 ( -4.1019601822 1.1555709839 -5.55108881 ) - weight 897 39 0.1332542896 ( 5.6173148155 1.1336321831 -1.6791850328 ) - weight 898 40 0.2516222596 ( -3.5192198753 -5.8558802605 -1.0667533875 ) - weight 899 41 0.0533020496 ( 3.23756814 -2.3043978214 5.680536747 ) - weight 900 19 0.1979081333 ( -6.5984597206 6.1081447601 -4.9428534508 ) - weight 901 22 0.3774667084 ( -6.5984597206 -1.2845306396 -5.0753984451 ) - weight 902 39 0.0570001341 ( 5.3032388687 4.0156664848 -3.681214571 ) - weight 903 40 0.1939489841 ( -1.0227203369 -5.3801898956 -3.506855011 ) - weight 904 41 0.1736759692 ( 3.8360071182 1.1269651651 5.1509070396 ) - weight 905 19 0.1394121796 ( -1.4000600576 8.4774703979 7.1653375626 ) - weight 906 22 0.5321753025 ( -1.4000600576 0.011390686 7.1941809654 ) - weight 907 21 0.2532346845 ( 2.8522996902 2.330116272 0.4004330635 ) - weight 908 20 0.0751778483 ( -5.4247431755 2.458442688 0.4004330635 ) - weight 909 22 0.1055573449 ( -11.1468296051 0.6763343811 4.0388612747 ) - weight 910 40 0.0612346157 ( 3.5256495476 3.7340695858 -1.5459899902 ) - weight 911 41 0.8332080245 ( -0.9324397445 3.7749950886 -3.6724846363 ) - weight 912 22 0.2346942276 ( -9.0930099487 -0.3227043152 -4.5201997757 ) - weight 913 40 0.2036777884 ( 1.4718298912 -4.8249912262 -2.5450286865 ) - weight 914 41 0.561627984 ( 1.6135157347 2.6588461399 4.7385854721 ) - weight 915 22 0.7280092239 ( -2.5946097374 6.8535728455 -0.7384381294 ) - weight 916 39 0.0894822627 ( 0.7176510096 -0.9631285667 3.7520051003 ) - weight 917 40 0.1825084984 ( -5.0265703201 -1.0432298183 4.6312484741 ) - weight 918 22 0.4795843363 ( -3.6837997437 4.6725578308 -3.5961689949 ) - weight 919 39 0.1561301053 ( 3.6395406723 0.2794412673 1.744925499 ) - weight 920 40 0.3642855883 ( -3.9373803139 -3.9009606838 2.4502334595 ) - weight 921 3 0.0785324425 ( -8.728518486 -7.9854354858 -3.2010769844 ) - weight 922 10 0.9214675426 ( 5.0247983932 6.5014371872 0.9794854522 ) - weight 923 22 0.4028716385 ( -7.2713694572 0.9188499451 5.3783311844 ) - weight 924 39 0.1384224147 ( -5.0855340958 4.9873385429 -1.2901041508 ) - weight 925 40 0.3638387024 ( -0.3498106003 5.0735397339 -1.3034744263 ) - weight 926 21 0.0948672518 ( -3.0190095901 3.237575531 -1.4154167175 ) - weight 927 3 0.0863266289 ( -5.78895998 5.7444572449 5.3466253281 ) - weight 928 17 0.3341448307 ( -5.3611130714 3.5957801342 6.5655574799 ) - weight 929 19 0.1688850224 ( -5.78895998 -2.7388362885 7.5566768646 ) - weight 930 22 0.1109910384 ( -5.78895998 -11.1959037781 6.5981616974 ) - weight 931 21 0.1000070646 ( -1.5366001129 -8.8771781921 -0.1955862045 ) - weight 932 18 0.1996454149 ( -5.7072029114 3.3173179626 -1.205186367 ) - weight 933 3 0.3293448985 ( -2.1477303505 2.2299880981 6.3577156067 ) - weight 934 17 0.1964480728 ( -1.6678456068 -0.0080001717 6.495610714 ) - weight 935 19 0.0816393122 ( -2.1477303505 -6.1508355141 8.872754097 ) - weight 936 22 0.0585389286 ( -2.1477303505 -14.7103729248 7.609251976 ) - weight 937 18 0.3340287805 ( -2.0659735203 -0.1971511841 -0.1940960884 ) - weight 938 17 0.2491469532 ( -1.5796819925 3.1711866856 7.3483428955 ) - weight 939 19 0.2161560208 ( -2.0632500648 -2.8667340279 8.6498298645 ) - weight 940 22 0.1518869698 ( -2.0632500648 -11.4193878174 7.6758422852 ) - weight 941 21 0.0964680836 ( 2.1891098022 -9.1006622314 0.8820943832 ) - weight 942 18 0.2863419652 ( -1.9814931154 3.0938339233 -0.1275057793 ) - weight 943 3 0.0720492378 ( -9.740404129 -7.2863502502 -0.1620242298 ) - weight 944 10 0.9279507399 ( 2.5405285358 6.197177887 3.0971035957 ) - weight 945 3 0.1854663789 ( -8.8855390549 -7.3435897827 3.0419328213 ) - weight 946 10 0.8145336509 ( -0.757807672 6.3303203583 3.4175140858 ) - weight 947 22 0.2993527055 ( -8.591878891 3.3821754456 4.2053408623 ) - weight 948 39 0.1691163778 ( -3.8300106525 5.8166475296 1.3411563635 ) - weight 949 40 0.4106554091 ( 0.9706988335 3.9005489349 1.1598510742 ) - weight 950 41 0.1208755374 ( -1.7615261078 0.1445503533 -3.7702176571 ) - weight 951 22 0.3791531324 ( -6.9991688728 4.0735206604 3.9729607105 ) - weight 952 39 0.1587525159 ( -3.7005896568 4.121878624 1.7650578022 ) - weight 953 40 0.4620943964 ( -0.6220111847 3.6681690216 1.8511962891 ) - weight 954 22 0.3157365322 ( -7.2697792053 5.4760704041 2.508810997 ) - weight 955 39 0.1305618137 ( -2.2220621109 4.0695161819 3.1776175499 ) - weight 956 40 0.4652858675 ( -0.3514008522 2.2040193081 3.2537460327 ) - weight 957 41 0.0884157941 ( -2.6450872421 -2.1145310402 -2.0020470619 ) - weight 958 11 0.6010227203 ( 3.0413722992 19.7924041748 0.3273327351 ) - weight 959 12 0.3989772201 ( -0.4217576683 -1.3238987923 -3.0838978291 ) - weight 960 11 0.1546468437 ( 0.6976569295 22.9507160187 -2.6980011463 ) - weight 961 12 0.4815303087 ( -0.8493283391 3.5413177013 -3.9599318504 ) - weight 962 13 0.3638228774 ( -2.0435092449 -3.3795998096 -1.8090840578 ) - weight 963 11 0.1531316042 ( -2.0279147625 23.5547084808 0.8049142361 ) - weight 964 12 0.4677073956 ( 3.4072520733 3.6919407845 -2.5732808113 ) - weight 965 13 0.3791610003 ( 2.4314408302 -3.4236733913 -1.6171350479 ) - weight 966 3 0.2864744067 ( -9.0277490616 -4.1181182861 -3.388313055 ) - weight 967 10 0.5730586648 ( 5.2887854576 2.7378239632 1.8994123936 ) - weight 968 17 0.1404669136 ( -9.095998764 -3.9199588299 -4.0938796997 ) - weight 969 3 0.0967469141 ( -8.8018436432 -7.2985687256 -4.1120114326 ) - weight 970 10 0.9032530785 ( 5.8992471695 5.7755327225 0.8555262685 ) - weight 971 22 0.3324160576 ( -6.5781202316 1.6232719421 -4.6563386917 ) - weight 972 39 0.1443967223 ( 4.8837385178 3.5538811684 -0.8103061914 ) - weight 973 40 0.2850297987 ( -1.0430598259 -4.9611301422 -0.5990524292 ) - weight 974 41 0.2381574363 ( 1.4116080999 -0.5133979917 4.9002289772 ) - weight 975 22 0.2266537994 ( -8.7158813477 3.7594718933 -3.1219177246 ) - weight 976 40 0.2749993503 ( 1.0947012901 -3.4267094135 1.537147522 ) - weight 977 41 0.4983468354 ( -1.6504069567 0.0637297407 3.5665092468 ) - weight 978 22 0.3057387173 ( -6.6514706612 4.0911598206 -3.554997921 ) - weight 979 39 0.1308492124 ( 3.7893993855 3.2985546589 1.6485619545 ) - weight 980 40 0.3803289235 ( -0.9697093964 -3.8597896099 1.8688354492 ) - weight 981 41 0.183083117 ( -0.7465820313 -1.8331069946 3.9466116428 ) - weight 982 22 0.2374293655 ( -8.3510599136 5.5010185242 -1.5986173153 ) - weight 983 39 0.0753508359 ( 1.94642663 4.8696212769 3.3334746361 ) - weight 984 40 0.3531977534 ( 0.7298798561 -1.9034090042 3.2786941528 ) - weight 985 41 0.3340220451 ( -2.9916303158 -1.2160393 2.1347849369 ) - weight 986 22 0.3466660976 ( -6.7255306244 5.7394599915 -0.8456678391 ) - weight 987 39 0.1131498292 ( 1.0904482603 3.2780485153 3.3153223991 ) - weight 988 40 0.4739112258 ( -0.8956494331 -1.150459528 3.5171356201 ) - weight 989 41 0.0662728474 ( -2.3346691132 -2.700928688 1.3412877321 ) - weight 990 17 0.3154843152 ( -3.9717187881 8.4784784317 -4.6200332642 ) - weight 991 19 0.464012742 ( -3.7111198902 -1.7517273426 -4.5096726418 ) - weight 992 22 0.2205028981 ( -3.7111198902 -9.1520576477 -5.334728241 ) - weight 993 42 1 ( 0.0200959574 5.4158697128 -2.408536911 ) - weight 994 42 1 ( -2.4503121376 10.4237546921 -1.6595644951 ) - weight 995 42 0.3331983984 ( 0.2487650216 9.7673711777 -3.3772807121 ) - weight 996 59 0.3078258038 ( 0.6891379356 -1.8510456085 0.3459349573 ) - weight 997 60 0.3589757979 ( 0.7962626815 -1.3812872171 -1.3684132099 ) - weight 998 42 1 ( -2.2997245789 6.7847042084 -1.1140668392 ) - weight 999 42 1 ( -2.6210319996 10.9107751846 1.0064997673 ) - weight 1000 42 1 ( -1.4059451818 7.8345999718 1.9115674496 ) - weight 1001 42 1 ( -0.3546287119 11.1882925034 2.9822413921 ) - weight 1002 42 1 ( -0.2930903435 2.2679593563 3.3474867344 ) - weight 1003 42 1 ( 1.367339015 7.2730507851 3.2096095085 ) - weight 1004 42 1 ( 3.1937260628 6.5948848724 1.1412677765 ) - weight 1005 42 1 ( 1.7029708624 11.118724823 3.0279650688 ) - weight 1006 42 1 ( 2.3130483627 2.0149121284 3.1472373009 ) - weight 1007 42 1 ( 2.5116844177 5.8856468201 -1.7285714149 ) - weight 1008 42 1 ( 2.3254649639 10.0279464722 -2.2449798584 ) - weight 1009 42 1 ( 3.2931983471 10.5279884338 0.6145492196 ) - weight 1010 60 0.5 ( 0.7972288132 0.2890473306 -0.0887209848 ) - weight 1011 61 0.5 ( 0.7628865242 0.3759037554 -1.5972503424 ) - weight 1012 56 1 ( -0.192030713 -0.6766708493 0.457447499 ) - weight 1013 60 0.5 ( -0.3340336978 0.7221184373 0.4575567245 ) - weight 1014 61 0.5 ( -0.2910544276 0.8321440816 -0.92883569 ) - weight 1015 42 0.2839439809 ( 1.4370516539 12.0446329117 -1.1971801519 ) - weight 1016 59 0.4689332843 ( -1.024799943 1.0213756561 0.7489191294 ) - weight 1017 60 0.2471227348 ( -0.9176751971 1.406421423 -0.5672385097 ) - weight 1018 42 0.3331983984 ( 1.8360946178 11.1354913712 -3.154925108 ) - weight 1019 59 0.3078258038 ( -0.4745402932 -0.8365646005 1.7803310156 ) - weight 1020 60 0.3589757979 ( -0.3674155176 -0.5776240826 0.1938893199 ) - weight 1021 56 1 ( -0.6210756302 0.2086301744 0.3698640764 ) - weight 1022 42 1 ( 1.4042071104 10.5487756729 1.1848043203 ) - weight 1023 42 0.8549714684 ( 1.2991079092 10.3256912231 -1.1235631704 ) - weight 1024 59 0.1450285167 ( -1.2780139446 -0.3512311578 -0.2664821148 ) - weight 1025 56 0.8064539433 ( -0.700034976 -0.7238830924 -0.7712596059 ) - weight 1026 57 0.1935460418 ( 0.3546809554 -1.1668753624 -0.7214961648 ) - weight 1027 56 1 ( -1.5852181911 -0.7562341094 0.3024048507 ) - weight 1028 56 0.8064539433 ( -1.63994205 -0.7141295075 -0.4374438822 ) - weight 1029 57 0.1935460418 ( -0.2823956013 -0.4757501781 -0.3876804411 ) - weight 1030 57 0.5 ( -2.1098926067 -0.6644847393 0.2943530083 ) - weight 1031 58 0.5 ( 0.5028061271 0.2126446962 -0.210857451 ) - weight 1032 57 0.5 ( -2.4400420189 -0.2689769864 0.3391590714 ) - weight 1033 58 0.5 ( 0.0291106682 0.4152223766 -0.2556635141 ) - weight 1034 57 0.5 ( -2.0971076488 -0.6478713155 -0.3835310936 ) - weight 1035 58 0.5 ( 0.4905670881 0.1956251264 0.4670266509 ) - weight 1036 54 0.5349572301 ( -0.7844588757 -0.3680962622 1.0744719505 ) - weight 1037 55 0.4650427997 ( 0.6554608941 -1.0935063362 -1.040895462 ) - weight 1038 54 0.5349572301 ( -1.8326598406 0.5593630075 0.4377685189 ) - weight 1039 55 0.4650427997 ( -0.5340822339 -0.3560154736 -0.4041920602 ) - weight 1040 54 0.5 ( -2.7072377205 -0.4324220717 0.6642158628 ) - weight 1041 55 0.5 ( 0.1645674556 0.7666656375 -0.6306393743 ) - weight 1042 42 1 ( 0.3383016884 10.9235830307 1.8646979332 ) - weight 1043 42 0.2443206161 ( 0.8235411048 14.5025568008 1.0273958445 ) - weight 1044 53 0.5839904547 ( 0.0496863015 -0.9334039688 -1.4147605896 ) - weight 1045 54 0.1716888845 ( 0.6152151227 -1.6676183939 -1.4606859684 ) - weight 1046 54 0.5 ( -2.7371506691 -0.1044326127 -0.1954353899 ) - weight 1047 55 0.5 ( -0.1581848562 0.7010698915 0.2290118635 ) - weight 1048 53 0.0691876858 ( -2.5861926079 -1.5596357584 -1.3677552938 ) - weight 1049 54 0.4924322069 ( -1.7131382227 -0.2957152426 -1.2634882927 ) - weight 1050 55 0.4383800626 ( 0.3192784786 -0.2247915119 1.2970647812 ) - weight 1051 53 0.2834812105 ( -2.1368472576 -0.8303865194 -1.5107085705 ) - weight 1052 54 0.5160946846 ( -0.8953318 -0.0804838464 -1.4610216618 ) - weight 1053 55 0.2004240751 ( 0.3481191397 -1.0699542761 1.4945981503 ) - weight 1054 53 0.2834812105 ( -1.4118533134 -0.0662304759 -1.2851474285 ) - weight 1055 54 0.5160946846 ( 0.1693605781 -0.0299678799 -1.3051153421 ) - weight 1056 55 0.2004240751 ( 0.6056706905 -2.1042602062 1.3386918306 ) - weight 1057 54 0.5349572301 ( -0.1085033268 0.5137109756 0.9470528364 ) - weight 1058 55 0.4650427997 ( 0.0050771101 -1.9943399429 -0.9134764075 ) - weight 1059 42 0.2443206161 ( -0.2098780572 14.3643989563 1.0577919483 ) - weight 1060 53 0.5839904547 ( -0.0659171119 0.0927545279 -1.2677865028 ) - weight 1061 54 0.1716888845 ( 1.2499853373 -0.8464742303 -1.3569755554 ) - weight 1062 42 0.2443206161 ( 0.5661039352 15.6500263214 0.7421406507 ) - weight 1063 53 0.5839904547 ( -1.1424202919 -0.9996075034 -1.2177124023 ) - weight 1064 54 0.1716888845 ( -0.2764528692 -0.8900951743 -1.2062945366 ) - weight 1065 57 0.5 ( -0.1396027952 0.2954653203 0.3316337764 ) - weight 1066 58 0.5 ( 0.1494993269 -1.9503902197 -0.2481382042 ) - weight 1067 42 1 ( -0.9832507372 10.8479213715 1.3476502895 ) - weight 1068 42 0.7828121781 ( -1.2674953938 10.566822052 -0.7904794216 ) - weight 1069 59 0.2171877921 ( 0.6984562874 0.420925349 -1.7677752972 ) - weight 1070 56 0.8064539433 ( -0.4912101924 0.5088045597 -1.1055316925 ) - weight 1071 57 0.1935460418 ( 1.3954452276 -0.4741009474 -1.0557682514 ) - weight 1072 60 0.5 ( 0.3955530822 -0.2429452986 1.7703546286 ) - weight 1073 61 0.5 ( 0.4278385937 -0.3353867233 0.2144701183 ) - weight 1074 60 0.5 ( 0.3227119744 0.5740048289 1.5123018026 ) - weight 1075 61 0.5 ( 0.4120092392 0.509306848 0.0546364635 ) - weight 1076 60 0.5 ( 0.0593952425 0.3390888274 2.8498241901 ) - weight 1077 61 0.5 ( 0.2095177323 0.1418229789 1.3727564812 ) - weight 1078 42 0.3331983984 ( 1.1503825188 11.3424444199 -3.6097779274 ) - weight 1079 59 0.3078258038 ( 0.3726408184 -0.8000226021 1.809835434 ) - weight 1080 60 0.3589757979 ( 0.4797655642 -0.5455729365 0.2282192856 ) - weight 1081 60 0.5 ( -0.4938145578 -0.4069877565 1.7117966413 ) - weight 1082 61 0.5 ( -0.4744340777 -0.4191041291 0.2000037879 ) - weight 1083 60 0.5 ( -0.3805701435 0.7671364546 2.3771727085 ) - weight 1084 61 0.5 ( -0.2184812278 0.6562665701 0.9824253917 ) - weight 1085 60 0.5 ( -0.6410441995 0.416782856 1.5118194818 ) - weight 1086 61 0.5 ( -0.560151577 0.4315655231 0.1036752239 ) - weight 1087 60 0.5 ( -0.5537763834 0.2871511877 2.7411661148 ) - weight 1088 61 0.5 ( -0.4112443626 0.1526207626 1.3018946648 ) - weight 1089 42 0.6501254439 ( -0.0536364056 10.3412094116 -2.1068849564 ) - weight 1090 59 0.3498745561 ( 0.3647233546 -0.6521641612 -0.3555500805 ) - weight 1091 42 1 ( 0.9338593483 10.2193346024 -1.8980697393 ) - weight 1092 57 0.5 ( -0.108284913 0.3342497647 -0.434559375 ) - weight 1093 58 0.5 ( 0.1213496923 -1.9915318489 0.5180549622 ) - weight 1094 57 0.5 ( -2.4111599922 -0.2257986069 -0.3625617921 ) - weight 1095 58 0.5 ( -0.0039475276 0.3751511872 0.4460573494 ) - weight 1096 56 0.8064539433 ( -0.4412187338 0.4163572788 -0.4525457919 ) - weight 1097 57 0.1935460418 ( 1.362387538 -0.5738648176 -0.4027823508 ) - weight 1098 57 0.5 ( -1.3658713102 0.2472017705 -0.0473318174 ) - weight 1099 58 0.5 ( -0.1566382051 -0.7619695663 0.1308273822 ) - weight 1100 10 0.211769715 ( 0.2079494447 21.3829021454 -1.9682843685 ) - weight 1101 11 0.7882302999 ( -0.31194368 0.4594621956 -2.391358614 ) - weight 1102 10 0.2941013873 ( 1.8416267633 22.6176490784 0.4880268872 ) - weight 1103 11 0.7058986425 ( -2.6634552479 1.6705076694 -0.5939351916 ) - weight 1104 10 0.211769715 ( 0.6275740266 22.7843570709 -2.3934173584 ) - weight 1105 11 0.7882302999 ( -0.0723657683 1.9626016617 -2.3275361061 ) - weight 1106 22 0.1330899894 ( -11.2868213654 3.4729499817 -0.3750984669 ) - weight 1107 40 0.1222179085 ( 3.6656413078 -0.6798901558 1.2506256104 ) - weight 1108 41 0.7446920872 ( -3.029163599 2.3473424911 0.8979916573 ) - weight 1109 22 0.4312410653 ( -5.3821597099 1.10679245 5.9322109222 ) - weight 1110 39 0.1283100247 ( -5.7598209381 3.1315600872 -1.4025424719 ) - weight 1111 40 0.3281306624 ( -2.2390203476 5.6274194717 -1.1155319214 ) - weight 1112 21 0.1123182103 ( -1.1297998428 3.4255180359 -0.8615369797 ) - weight 1113 22 0.4648121297 ( -4.0500793457 4.7070732117 4.0569810867 ) - weight 1114 39 0.1376403272 ( -3.9741845131 1.1206154823 1.9171791077 ) - weight 1115 40 0.3975475132 ( -3.5711007118 3.7521891594 2.4847488403 ) - weight 1116 22 0.4866587222 ( -5.2421598434 5.5526542664 1.9103720188 ) - weight 1117 39 0.0868105441 ( -1.7553232908 2.0221812725 2.9210848808 ) - weight 1118 40 0.4265308082 ( -2.3790202141 1.6055802107 3.330329895 ) - weight 1119 22 0.7518678904 ( -3.0729999542 5.6567344666 2.9678616524 ) - weight 1120 39 0.0723678172 ( -2.9501886368 -0.0638315901 2.6860997677 ) - weight 1121 40 0.175764218 ( -4.5481801033 2.663069725 3.4344100952 ) - weight 1122 22 0.7110148072 ( -3.6320300102 6.6992988586 1.0049717426 ) - weight 1123 39 0.0715909079 ( -0.9553972483 0.1941823661 3.7845659256 ) - weight 1124 40 0.217394352 ( -3.9891500473 0.7001799941 4.4769744873 ) - weight 1125 22 0.5249072909 ( -4.5867500305 5.8286705017 -0.6713585854 ) - weight 1126 39 0.0834142864 ( 0.7788878083 1.1682679653 3.0613920689 ) - weight 1127 40 0.3916783631 ( -3.034430027 -0.9761502743 3.6063461304 ) - weight 1128 41 0.3857780397 ( -2.3313035965 12.1336078644 1.9996507168 ) - weight 1129 42 0.6142219305 ( -1.9012125731 -0.1869996786 2.3737304211 ) - weight 1130 41 0.146963343 ( -2.5777080059 13.1381349564 1.3277878761 ) - weight 1131 42 0.8530366421 ( -2.1746530533 0.9714484215 2.050593853 ) - weight 1132 41 0.0593079589 ( -0.6139680743 12.3391389847 3.665776968 ) - weight 1133 42 0.9406920671 ( 0.0593024381 -0.5007280111 3.7248103619 ) - weight 1134 41 0.0593079589 ( -0.7089693546 13.6927680969 3.3668608665 ) - weight 1135 42 0.9406920671 ( 0.0165500101 0.8844845295 3.8250477314 ) - weight 1136 41 0.1007401645 ( 3.184128046 13.5912265778 1.2619413137 ) - weight 1137 42 0.8992598653 ( 3.5279135704 1.2738858461 1.1574839354 ) - weight 1138 41 0.0593079589 ( 1.6958975792 13.6776227951 3.4566555023 ) - weight 1139 42 0.9406920671 ( 2.3999507427 0.7818815708 3.5079512596 ) - weight 1140 22 0.1032253429 ( -10.4568710327 2.0270195007 -3.0863785744 ) - weight 1141 40 0.1232035086 ( 2.8356909752 -3.3911702633 -0.1953048706 ) - weight 1142 41 0.7735711336 ( -1.187666297 2.4749233723 3.490901947 ) - weight 1143 22 0.8149345517 ( -2.3048799038 3.7849845886 5.9193911552 ) - weight 1144 39 0.0842731968 ( -5.9450244904 -0.3314397931 0.7459124923 ) - weight 1145 40 0.1007922292 ( -5.3163003922 5.6145992279 1.5626602173 ) - weight 1146 22 0.8149345517 ( -1.8106398582 4.6890602112 4.1403317451 ) - weight 1147 39 0.0842731968 ( -4.2014517784 -1.0768091679 1.5403029919 ) - weight 1148 40 0.1007922292 ( -5.8105401993 3.8355400562 2.4667358398 ) - weight 1149 3 0.4008017182 ( -2.1574802399 -2.115032196 5.6972956657 ) - weight 1150 10 0.3488021493 ( -5.65402174 0.2306371629 -0.8809145689 ) - weight 1151 17 0.1250136942 ( -1.7154915333 -4.0662989616 4.8093743324 ) - weight 1152 18 0.1253824681 ( -2.0757234097 -4.5421714783 -0.8545160294 ) - weight 1153 3 0.3689664006 ( -2.2408604622 -2.2401237488 6.5915455818 ) - weight 1154 10 0.4005262256 ( -6.4597139359 0.4298192561 -0.515578866 ) - weight 1155 17 0.115083985 ( -1.7473989725 -4.403960228 5.6503558159 ) - weight 1156 18 0.1154234186 ( -2.159103632 -4.667263031 0.0397338867 ) - weight 1157 3 0.2517192662 ( -6.6758599281 -3.1631240845 5.3717055321 ) - weight 1158 10 0.4801626801 ( -3.73944664 2.0067896843 2.9661550522 ) - weight 1159 17 0.1804798096 ( -6.2451109886 -5.0676922798 4.4931144714 ) - weight 1160 18 0.0876382738 ( -6.5941028595 -5.5902633667 -1.180106163 ) - weight 1161 3 0.1905488819 ( -6.9014000893 -7.3547172546 4.9453721046 ) - weight 1162 10 0.8094511032 ( -3.2419888973 6.1358475685 2.2551732063 ) - weight 1163 3 0.2546746433 ( -2.8709902763 -7.365196228 7.1078958511 ) - weight 1164 10 0.6834095716 ( -6.695456028 5.610683918 -0.6975524426 ) - weight 1165 17 0.0619157404 ( -2.346848011 -9.5109710693 4.950961113 ) - weight 1166 10 1 ( 2.7715482712 6.627374649 2.643222332 ) - weight 1167 3 0.0569108799 ( -8.6981992722 -8.0943946838 2.307477951 ) - weight 1168 10 0.9430891275 ( -0.134490639 6.9855360985 2.8514783382 ) - weight 1169 3 0.1544193178 ( -5.4406051636 -8.223487854 -5.3938894272 ) - weight 1170 10 0.7848661542 ( 5.9072437286 6.0241103172 -2.8505167961 ) - weight 1171 17 0.0607145987 ( -5.6299023628 -7.3723549843 -7.22615242 ) - weight 1172 3 0.2152129114 ( -5.1066699028 -3.1478424072 -6.9544043541 ) - weight 1173 10 0.3803589642 ( 7.2244668007 0.8697702289 -2.7692937851 ) - weight 1174 17 0.4044281542 ( -5.386100769 -2.0662500858 -7.5338978767 ) - weight 1175 3 0.2287210673 ( -8.735039711 -1.0005874634 -2.5254650116 ) - weight 1176 10 0.3527418673 ( 4.3642573357 -0.3165878654 2.5035643578 ) - weight 1177 17 0.4185370207 ( -8.7542390823 -1.0977672338 -2.5230138302 ) - weight 1178 3 0.2679378986 ( -4.8128805161 -0.9101219177 -6.3873052597 ) - weight 1179 10 0.2285530865 ( 6.5799479485 -1.3405019045 -2.4307687283 ) - weight 1180 17 0.503508985 ( -5.0602412224 -0.02679649 -6.4616332054 ) - weight 1181 10 1 ( 3.1966612339 15.5918416977 2.8038680553 ) - weight 1182 3 0.0545195229 ( -8.8855199814 -16.3318901062 3.2250254154 ) - weight 1183 10 0.9454804659 ( -0.8886219263 15.1783876419 1.8308005333 ) -} diff --git a/base/animation/mp_tshirt.md5mesh b/base/animation/mp_tshirt.md5mesh deleted file mode 100644 index 27b1ddc72..000000000 --- a/base/animation/mp_tshirt.md5mesh +++ /dev/null @@ -1,7656 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:30 sparhawk - * Initial revision - * - ***************************************************************************/ - -MD5Version 10 -commandline "mesh models/characters/male_npc/cycles/tweakedplayermoves/makemesh.mb -dest models/md5/characters/npcs_as_player/mp_tshirt.md5mesh -game Doom -prefix MP_ -keep Lknee Rknee Lhand Lhand1 Rhand Rhand1 Body2 Body SPINNER PISTOL_ATTACHER SHOTGUN_ATTACHER MGATTACHER pgATTACHER NADE_ATTACHER CHAINSAW_ATTACHER RL_ATTACHER FL_ATTACHER BFG_ATTACHER CHAINGUN_ATTACHER PDA_ATTACHER SOUL_ATTACHER loneckadjust headcontrol neckcontrol loneckcontrol eyecontrol jawcontrol jawadjust Jaw -parent Body2 Body -parent Hips Body2 -parent SPINNER Body2 -parent Waist SPINNER -parent PISTOL_ATTACHER Rhand1 -parent SHOTGUN_ATTACHER Rhand1 -parent MGATTACHER Rhand1 -parent pgATTACHER Rhand1 -parent NADE_ATTACHER Rhand1 -parent CHAINSAW_ATTACHER Rhand1 -parent RL_ATTACHER Lhand1 -parent FL_ATTACHER Rhand1 -parent BFG_ATTACHER Rhand1 -parent CHAINGUN_ATTACHER Rhand -parent headcontrol neckcontrol -parent neckcontrol loneckcontrol -parent loneckcontrol Shoulders -parent PDA_ATTACHER Rhand -parent SOUL_ATTACHER Rhand -keepmesh soldiermesh -keepmesh head_skullmesh -keepmesh skeletonmesh -keepmesh head_bfx1mesh -keepmesh head_bfx2mesh -keepmesh head_bfx3mesh -keepmesh head_bfx4mesh -keepmesh head_bfxflamemesh -keepmesh head_bfxmodelmesh -keepmesh head_stumpmesh -keepmesh berserkbodyfxmesh" - -numJoints 75 -numMeshes 11 - -joints { - "origin" -1 ( 0 0 0 ) ( -0.7071067095 0 0 ) // - "Body" 0 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // origin - "Body2" 1 ( 0 0.0000026805 44.9718170166 ) ( -0.7071067095 0 0 ) // Body - "Hips" 2 ( 0.0679385737 0.1576778442 44.9824447632 ) ( -0.7071067095 0 0 ) // Body2 - "Lupleg" 3 ( 5.0049409866 -0.5456646681 43.2305450439 ) ( 0.359025985 -0.5408498049 0.6186864972 ) // Hips - "Lloleg" 4 ( 7.4817695618 1.9062656164 22.9086914063 ) ( 0.628723681 -0.1521502733 0.2126665264 ) // Lupleg - "Lankle_r" 5 ( 9.6917295456 4.0939569473 4.7831821442 ) ( 0.2043810189 -0.3825196326 0.8556543589 ) // Lloleg - "Lball_r" 6 ( 11.3632144928 1.2932736874 0.8464386463 ) ( 0.0124899801 -0.063287504 0.9774723053 ) // Lankle_r - "Ltoe_r" 7 ( 13.3476066589 -3.327845335 0.193531394 ) ( 0.0128018185 -0.0614631735 0.9796780944 ) // Lball_r - "Lknee" 5 ( 6.2718114853 -9.8725738525 31.6549110413 ) ( -0.6854641438 0.004605562 0.0027808254 ) // Lloleg - "Rupleg" 3 ( -4.8690609932 -0.5456620455 43.2305145264 ) ( 0.3693974912 0.5310505033 -0.6117249131 ) // Hips - "Rloleg" 10 ( -7.3507957458 1.912774682 22.8669433594 ) ( 0.6329697371 0.1371328831 -0.1997751892 ) // Rupleg - "Rankle_r" 11 ( -9.555932045 4.0940499306 4.7821817398 ) ( 0.1949646622 0.3855498433 -0.8578744531 ) // Rloleg - "Rball_r" 12 ( -11.2275152206 1.2929196358 0.8457994461 ) ( 0.0124807386 0.0632374212 -0.9774768949 ) // Rankle_r - "Rtoe_r" 13 ( -13.2118682861 -3.3282866478 0.193405956 ) ( 0.0129368575 0.061382845 -0.9801291227 ) // Rball_r - "Rknee" 11 ( -6.5483474731 -9.8574075699 31.6721076965 ) ( -0.6834561229 0.006874477 0.0129089803 ) // Rloleg - "SPINNER" 2 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.7071067095 0 0 ) // Body2 - "Waist" 16 ( -0.0526839644 0.0000027213 45.6551704407 ) ( -0.6158075929 0.0176901035 0.0226186067 ) // SPINNER - "Belly" 17 ( -0.013818346 -6.3941335678 47.4095840454 ) ( -0.7071067691 -0.0000000003 -0 ) // Waist - "Chest" 17 ( 0.0679385811 2.0977575779 54.1193237305 ) ( -0.7375252247 0.0000002161 -0.0000026001 ) // Waist - "Lrib" 19 ( 4.0926237106 -5.3844823837 59.4758224487 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Rrib" 19 ( -4.184419632 -5.3845081329 59.6041145325 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Shoulders" 19 ( 0.0679085478 1.4092681408 61.9228134155 ) ( -0.7071043253 0.0000003303 -0.0000025881 ) // Chest - "Lshldr" 22 ( 2.9618220329 1.4092978239 64.918296814 ) ( 0.0552712493 -0.0589446761 0.7271142602 ) // Shoulders - "Luparm_orbit" 23 ( 7.6890788078 1.1045134068 64.145149231 ) ( -0.0000020851 0.0000034379 1 ) // Lshldr - "Luparm" 24 ( 7.6890788078 1.0835175514 64.145149231 ) ( 0.2663819492 -0.1605339199 0.6489054561 ) // Luparm_orbit - "Lloarm" 25 ( 17.5499267578 1.1995677948 57.6129608154 ) ( 0.1732702255 -0.2471979409 0.7897747159 ) // Luparm - "Lhand" 26 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.1407561004 -0.1183491424 0.9693421125 ) // Lloarm - "Lhand1" 27 ( 25.295135498 -1.9486477375 52.4573440552 ) ( 0.0497920923 -0.3133003414 0.9474034309 ) // Lhand - "Lfings1" 28 ( 28.7278347015 -3.0631246567 49.9685325623 ) ( 0.6872298717 -0.2966228426 -0.0111149279 ) // Lhand1 - "Lfings2" 29 ( 29.9613494873 -3.6908257008 49.1079216003 ) ( 0.5176700354 -0.5113924146 -0.2740879953 ) // Lfings1 - "Lfings3" 30 ( 30.5616397858 -4.0782957077 47.2171936035 ) ( -0.6681255698 0.155485779 0.1012966931 ) // Lfings2 - "Lindex1" 28 ( 27.6196136475 -4.7952623367 49.9493637085 ) ( 0.6201820374 -0.3667625487 0.1266580969 ) // Lhand1 - "Lindex2" 32 ( 28.8809947968 -5.923623085 49.2438964844 ) ( 0.4238429368 -0.5826642513 -0.1541451216 ) // Lindex1 - "Lindex3" 33 ( 29.3013114929 -6.499663353 47.3154525757 ) ( -0.6345726848 0.2800964713 0.2145120353 ) // Lindex2 - "RL_ATTACHER" 28 ( 23.6067371368 -6.1035737991 51.8303375244 ) ( -0.7071069479 0.0000017222 -0.000005363 ) // Lhand1 - "lthumb1" 28 ( 25.3892097473 -3.485537529 51.3089447021 ) ( 0.1219631806 -0.2759809196 -0.78329283 ) // Lhand1 - "Lthumb2" 36 ( 25.1003551483 -4.4255404472 50.156867981 ) ( 0.181819275 -0.1869008243 -0.8091855049 ) // lthumb1 - "Lthumb3" 37 ( 25.2551994324 -5.1197094917 48.8432350159 ) ( 0.0945132151 -0.2684400082 -0.8124375939 ) // Lthumb2 - "Rshldr" 22 ( -2.8260338306 1.4092777967 64.9182281494 ) ( 0.0552693531 0.0589425489 -0.7271163464 ) // Shoulders - "Ruparm_orbit" 39 ( -7.553278923 1.1044671535 64.145111084 ) ( -0.000002126 0.0000034703 1 ) // Rshldr - "Ruparm" 40 ( -7.553278923 1.0834671259 64.145111084 ) ( 0.6114100218 -0.3118825257 -0.3526444137 ) // Ruparm_orbit - "Rloarm" 41 ( -17.3874149323 1.1073672771 57.6175727844 ) ( 0.656062901 -0.2223614007 -0.456345737 ) // Ruparm - "Rhand" 42 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0538253896 0.2292846292 -0.966281414 ) // Rloarm - "CHAINGUN_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "PDA_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "Rhand1" 43 ( -25.1591758728 -1.9487988949 52.4572029114 ) ( 0.0129949553 0.3203192055 -0.9444009662 ) // Rhand - "BFG_ATTACHER" 46 ( 0.067937851 -0.0000098944 0.0000052985 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "CHAINSAW_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "FL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "MGATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "NADE_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "PISTOL_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "Rfings1" 46 ( -28.8342132568 -2.8897218704 50.259765625 ) ( -0.6824486852 -0.0044931043 -0.2550282776 ) // Rhand1 - "Rfings2" 53 ( -30.1599235535 -3.4556515217 49.4992637634 ) ( -0.6513322592 0.2673344016 -0.4711902738 ) // Rfings1 - "Rfings3" 54 ( -30.9369773865 -3.779364109 47.6616897583 ) ( 0.7072024345 0.0610166714 -0.1745528579 ) // Rfings2 - "Rindex1" 46 ( -27.7943382263 -4.6573653221 50.1085472107 ) ( -0.7059381604 -0.1380773485 -0.3268930912 ) // Rhand1 - "Rindex2" 56 ( -29.1295032501 -5.6483945847 49.4119644165 ) ( -0.7028012872 0.1532463431 -0.5432026982 ) // Rindex1 - "Rindex3" 57 ( -29.7374897003 -6.165746212 47.5172729492 ) ( 0.6713247299 0.1773936749 -0.296843946 ) // Rindex2 - "Rthumb1" 46 ( -25.4081516266 -3.4550125599 51.2913818359 ) ( -0.5477092266 0.7807102799 -0.2679643035 ) // Rhand1 - "Rthumb2" 59 ( -24.9777889252 -4.3026256561 50.0808258057 ) ( -0.5367621183 0.7975903749 -0.2125160694 ) // Rthumb1 - "Rthumb3" 60 ( -25.0639019012 -5.0469741821 48.7885437012 ) ( -0.4982216358 0.8357143402 -0.156237781 ) // Rthumb2 - "SHOTGUN_ATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "pgATTACHER" 46 ( -18.5845298767 -5.8511447906 52.0336036682 ) ( -0.7071067095 0.0000003545 -0.0000008873 ) // Rhand1 - "SOUL_ATTACHER" 43 ( 0.067937851 -0.000007391 0.0000012385 ) ( -0.7071066499 0.0000002737 -0.0000008984 ) // Rhand - "loneckcontrol" 22 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // Shoulders - "loneckadjust" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "Loneck" 66 ( 0.0678879097 -0.03347826 68.0385894775 ) ( 0.6856863499 -0.1727198958 0.6856886148 ) // loneckadjust - "neckcontrol" 65 ( 0.0678879097 -0.03347826 68.0385894775 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // loneckcontrol - "headcontrol" 68 ( 0.0696866289 -1.7671910524 71.2621154785 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // neckcontrol - "Head" 69 ( 0.0696803778 -0.4627248049 71.7656707764 ) ( 0.5145410895 -0.485021621 0.5145410299 ) // headcontrol - "jawcontrol" 69 ( 0.0696917325 -3.1014347076 71.0590591431 ) ( -0.7071043253 0.0000003295 -0.0000025885 ) // headcontrol - "jawadjust" 71 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawcontrol - "Jaw" 72 ( 0.069686234 -2.0003700256 71.5382461548 ) ( -0.6139163971 0.0000006483 -0.0000025277 ) // jawadjust - "eyecontrol" 0 ( 0.0701786503 -14.5579156876 72.6545181274 ) ( -0.7071067095 0 0 ) // origin -} - -mesh { - // meshes: head_skullmesh - shader "models/monsters/skeleton/skeleton01head" - - numverts 47 - vert 0 ( 0.431652993 0.0235379934 ) 0 1 - vert 1 ( 0.2767089903 0 ) 1 1 - vert 2 ( 0.3910669982 0.0830360055 ) 2 1 - vert 3 ( 0.2649079859 0.0577679873 ) 3 1 - vert 4 ( 0.4579260051 0.2761570215 ) 4 1 - vert 5 ( 0.4105390012 0.1933550239 ) 5 1 - vert 6 ( 0.2929770052 0.240522027 ) 6 1 - vert 7 ( 0.5097659826 0.1421430111 ) 7 1 - vert 8 ( 0.1615529954 0.0649949908 ) 8 1 - vert 9 ( 0.1349239945 0.0052270293 ) 9 1 - vert 10 ( 0.012317 0.0662459731 ) 10 1 - vert 11 ( 0.0906269997 0.1010850072 ) 11 1 - vert 12 ( 0 0.1645900011 ) 12 1 - vert 13 ( 0.3204059899 0.1343759894 ) 13 1 - vert 14 ( 0.1471959949 0.146337986 ) 14 1 - vert 15 ( 0.1382360011 0.2002469897 ) 15 1 - vert 16 ( 0.1205860004 0.2648890018 ) 16 1 - vert 17 ( 0.0042770002 0.265263021 ) 17 1 - vert 18 ( 0.0937250033 0.3530319929 ) 18 1 - vert 19 ( 0.0313609987 0.3569120169 ) 19 1 - vert 20 ( 0.1808059961 0.3317109942 ) 20 1 - vert 21 ( 0.2396620065 0.312056005 ) 21 1 - vert 22 ( 0.2518700063 0.2532950044 ) 22 1 - vert 23 ( 0.3910669982 0.0830360055 ) 23 1 - vert 24 ( 0.2649079859 0.0577679873 ) 24 1 - vert 25 ( 0.4105390012 0.1933550239 ) 25 1 - vert 26 ( 0.2929770052 0.240522027 ) 26 1 - vert 27 ( 0.1615529954 0.0649949908 ) 27 1 - vert 28 ( 0.0906269997 0.1010850072 ) 28 1 - vert 29 ( 0.3204059899 0.1343759894 ) 29 1 - vert 30 ( 0.1471959949 0.146337986 ) 30 1 - vert 31 ( 0.1382360011 0.2002469897 ) 31 1 - vert 32 ( 0.1205860004 0.2648890018 ) 32 1 - vert 33 ( 0.0937250033 0.3530319929 ) 33 1 - vert 34 ( 0.1808059961 0.3317109942 ) 34 1 - vert 35 ( 0.2518700063 0.2532950044 ) 35 1 - vert 36 ( 0.2396620065 0.312056005 ) 36 1 - vert 37 ( 0.5442860126 0.3401780128 ) 37 1 - vert 38 ( 0.3938719928 0.3740440011 ) 38 2 - vert 39 ( 0.5459169745 0.3911079764 ) 40 1 - vert 40 ( 0.2891559899 0.3022159934 ) 41 1 - vert 41 ( 0.2723540068 0.3524320126 ) 42 1 - vert 42 ( 0.3976919949 0.2761920094 ) 43 2 - vert 43 ( 0.5699639916 0.3104850054 ) 45 1 - vert 44 ( 0.5442860126 0.3401780128 ) 46 1 - vert 45 ( 0.2891559899 0.3022159934 ) 47 1 - vert 46 ( 0.2656590044 0.2756670117 ) 47 1 - - numtris 74 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 10 9 8 - tri 5 8 9 1 - tri 6 12 10 11 - tri 7 11 10 8 - tri 8 6 13 5 - tri 9 12 11 14 - tri 10 15 12 14 - tri 11 14 8 3 - tri 12 14 11 8 - tri 13 14 3 13 - tri 14 13 3 2 - tri 15 5 2 7 - tri 16 5 13 2 - tri 17 7 2 0 - tri 18 8 1 3 - tri 19 18 17 16 - tri 20 19 17 18 - tri 21 18 16 20 - tri 22 20 22 21 - tri 23 20 16 22 - tri 24 22 15 6 - tri 25 15 14 13 - tri 26 6 15 13 - tri 27 16 15 22 - tri 28 17 12 15 - tri 29 16 17 15 - tri 30 23 0 1 - tri 31 23 1 24 - tri 32 26 4 25 - tri 33 4 7 25 - tri 34 10 27 9 - tri 35 27 1 9 - tri 36 12 28 10 - tri 37 28 27 10 - tri 38 26 25 29 - tri 39 12 30 28 - tri 40 31 30 12 - tri 41 30 24 27 - tri 42 30 27 28 - tri 43 30 29 24 - tri 44 29 23 24 - tri 45 25 7 23 - tri 46 25 23 29 - tri 47 7 0 23 - tri 48 27 24 1 - tri 49 33 32 17 - tri 50 19 33 17 - tri 51 33 34 32 - tri 52 34 36 35 - tri 53 34 35 32 - tri 54 35 26 31 - tri 55 31 29 30 - tri 56 26 29 31 - tri 57 32 35 31 - tri 58 17 31 12 - tri 59 32 31 17 - tri 60 39 38 37 - tri 61 37 38 40 - tri 62 38 41 40 - tri 63 37 40 42 - tri 64 37 42 43 - tri 65 39 37 43 - tri 66 39 44 38 - tri 67 44 45 38 - tri 68 38 45 41 - tri 69 44 42 45 - tri 70 44 43 42 - tri 71 39 43 44 - tri 72 42 40 46 - tri 73 41 46 40 - - numweights 48 - weight 0 70 1 ( -4.8517251015 -4.2843666077 -0.0018064925 ) - weight 1 70 1 ( -2.5029315948 -6.5715589523 -0.0018064925 ) - weight 2 70 1 ( -4.2453141212 -3.5569999218 2.4039134979 ) - weight 3 70 1 ( -2.2776155472 -5.514734745 2.6082134247 ) - weight 4 70 1 ( -2.4940359592 0.8336980343 -0.0018064925 ) - weight 5 70 1 ( -3.0465950966 -0.4414356649 2.4651834965 ) - weight 6 70 1 ( -0.2046299279 -0.4018440545 2.8948833942 ) - weight 7 70 1 ( -4.8742823601 -1.5074599981 -0.0018064925 ) - weight 8 70 1 ( -0.187556833 -6.2722463608 2.024513483 ) - weight 9 70 1 ( -0.2813148499 -6.9986782074 -0.0018064925 ) - weight 10 70 1 ( 1.6830482483 -6.136267662 -0.0018064925 ) - weight 11 70 1 ( 1.3423842192 -5.8143057823 1.7474935055 ) - weight 12 70 1 ( 2.9342989922 -4.8164916039 -0.0018064925 ) - weight 13 70 1 ( -2.318665266 -2.8665668964 3.4796733856 ) - weight 14 70 1 ( 1.4595835209 -4.5529961586 2.5273535252 ) - weight 15 70 1 ( 2.4298193455 -3.2438440323 2.6587533951 ) - weight 16 70 1 ( 3.7369399071 -1.7537704706 1.3304535151 ) - weight 17 70 1 ( 4.5810084343 -2.2800803185 -0.0018064925 ) - weight 18 70 1 ( 5.0443282127 0.3964088857 0.8281934857 ) - weight 19 70 1 ( 5.0443282127 0.3964088857 -0.0018064925 ) - weight 20 70 1 ( 3.4553546906 0.6924918294 1.9738434553 ) - weight 21 70 1 ( 1.9448387623 0.8570235968 2.3753836155 ) - weight 22 70 1 ( 0.8364742994 -0.5417711139 2.6860535145 ) - weight 23 70 1 ( -4.2453141212 -3.5569999218 -2.4075264931 ) - weight 24 70 1 ( -2.2776155472 -5.514734745 -2.6118264198 ) - weight 25 70 1 ( -3.0465950966 -0.4414356649 -2.4687964916 ) - weight 26 70 1 ( -0.2046299279 -0.4018440545 -2.8984963894 ) - weight 27 70 1 ( -0.187556833 -6.2722463608 -2.0281264782 ) - weight 28 70 1 ( 1.3423842192 -5.8143057823 -1.7511065006 ) - weight 29 70 1 ( -2.318665266 -2.8665668964 -3.4832863808 ) - weight 30 70 1 ( 1.4595835209 -4.5529961586 -2.5309665203 ) - weight 31 70 1 ( 2.4298193455 -3.2438440323 -2.6623663902 ) - weight 32 70 1 ( 3.7369399071 -1.7537704706 -1.3340665102 ) - weight 33 70 1 ( 5.0443282127 0.3964088857 -0.8318064809 ) - weight 34 70 1 ( 3.4553546906 0.6924918294 -1.9774564505 ) - weight 35 70 1 ( 0.8364742994 -0.5417711139 -2.6896665096 ) - weight 36 70 1 ( 1.9448387623 0.8570235968 -2.3789966106 ) - weight 37 67 1 ( -3.2606282234 -0.674664855 2.052560091 ) - weight 38 70 0.200000003 ( 1.3539756536 1.6153081656 -0.0018064925 ) - weight 39 67 0.8000000119 ( 1.47524786 1.0917340517 0 ) - weight 40 67 1 ( -2.7478621006 1.2878991365 0 ) - weight 41 70 1 ( -0.9897010326 -1.4229291677 1.1682235003 ) - weight 42 70 1 ( -0.039117787 -1.5783829689 -0.0018064925 ) - weight 43 70 0.200000003 ( -2.1899316311 1.9511066675 -0.0018064925 ) - weight 44 67 0.8000000119 ( 1.1856505871 -2.4562475681 0 ) - weight 45 67 1 ( -3.544451952 -1.4427450895 0 ) - weight 46 67 1 ( -3.2606282234 -0.674664855 -2.052560091 ) - weight 47 70 1 ( -0.9897010326 -1.4229291677 -1.1718364954 ) -} - -mesh { - // meshes: head_bfx4mesh - shader "models/items/powerups/blite3" - - numverts 8 - vert 0 ( 0 1 ) 0 1 - vert 1 ( 0 0 ) 1 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 0 ) 5 1 - vert 5 ( 0 1 ) 4 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 3 1 - tri 2 6 5 4 - tri 3 6 4 7 - - numweights 8 - weight 0 70 1 ( 4.1548233032 -5.0475759506 -0.7493189573 ) - weight 1 70 1 ( 3.4117124081 -6.0098485947 -0.7466371655 ) - weight 2 70 1 ( 3.1687374115 -5.8187217712 -1.5939632654 ) - weight 3 70 1 ( 3.9117999077 -4.8564229012 -1.596801877 ) - weight 4 70 1 ( 4.1548233032 -5.0475759506 0.7489252687 ) - weight 5 70 1 ( 3.4117124081 -6.0098485947 0.7462435365 ) - weight 6 70 1 ( 3.1687374115 -5.8187217712 1.5935696363 ) - weight 7 70 1 ( 3.9117999077 -4.8564229012 1.5964082479 ) -} - -mesh { - // meshes: head_bfx3mesh - shader "models/items/powerups/blite2" - - numverts 8 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - - numtris 4 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - - numweights 8 - weight 0 70 1 ( 4.9815778732 -3.5685434341 0.7713071108 ) - weight 1 70 1 ( 4.4492573738 -4.2095718384 0.7760922313 ) - weight 2 70 1 ( 4.2402997017 -4.0297203064 1.6247986555 ) - weight 3 70 1 ( 4.7725839615 -3.388654232 1.6201705933 ) - weight 4 70 1 ( 4.9815778732 -3.5685434341 -0.7717007399 ) - weight 5 70 1 ( 4.4492573738 -4.2095718384 -0.7764858603 ) - weight 6 70 1 ( 4.2402997017 -4.0297203064 -1.6251922846 ) - weight 7 70 1 ( 4.7725839615 -3.388654232 -1.6205643415 ) -} - -mesh { - // meshes: head_bfx2mesh - shader "models/items/powerups/blite1" - - numverts 16 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - vert 4 ( 0 1 ) 4 1 - vert 5 ( 0 0 ) 5 1 - vert 6 ( 1 1 ) 7 1 - vert 7 ( 1 0 ) 6 1 - vert 8 ( 0 1 ) 8 1 - vert 9 ( 0 0 ) 9 1 - vert 10 ( 1 1 ) 11 1 - vert 11 ( 1 0 ) 10 1 - vert 12 ( 0 0 ) 13 1 - vert 13 ( 0 1 ) 12 1 - vert 14 ( 1 1 ) 15 1 - vert 15 ( 1 0 ) 14 1 - - numtris 8 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 6 7 5 - tri 4 10 9 8 - tri 5 10 11 9 - tri 6 14 13 12 - tri 7 14 12 15 - - numweights 16 - weight 0 70 1 ( 4.8506779671 -3.7651526928 1.613476634 ) - weight 1 70 1 ( 4.051404953 -4.866830349 1.399371624 ) - weight 2 70 1 ( 2.8768217564 -4.4568595886 3.0111789703 ) - weight 3 70 1 ( 3.676094532 -3.3551814556 3.2252838612 ) - weight 4 70 1 ( 4.8506779671 -3.7651526928 -1.6138703823 ) - weight 5 70 1 ( 4.051404953 -4.866830349 -1.3997652531 ) - weight 6 70 1 ( 2.8768217564 -4.4568595886 -3.0115725994 ) - weight 7 70 1 ( 3.676094532 -3.3551814556 -3.2256777287 ) - weight 8 70 1 ( 5.3682045937 -3.1983680725 -1.5267416239 ) - weight 9 70 1 ( 4.5979914665 -4.3253655434 -1.3419976234 ) - weight 10 70 1 ( 3.4123165607 -3.9063351154 -2.9412596226 ) - weight 11 70 1 ( 4.1885280609 -2.7843756676 -3.1338384151 ) - weight 12 70 1 ( 5.3682045937 -3.1983680725 1.5263479948 ) - weight 13 70 1 ( 4.5979914665 -4.3253655434 1.3416039944 ) - weight 14 70 1 ( 3.4123165607 -3.9063351154 2.9408659935 ) - weight 15 70 1 ( 4.1885280609 -2.7843756676 3.1334447861 ) -} - -mesh { - // meshes: head_bfx1mesh - shader "models/items/powerups/berserkerfx" - - numverts 60 - vert 0 ( 0.1494305432 0.3869812489 ) 17 1 - vert 1 ( 0.1100263596 0.3216068745 ) 21 1 - vert 2 ( 0.0163724422 0.3971676826 ) 4 1 - vert 3 ( 0.0642609596 0.291307807 ) 1 1 - vert 4 ( 0.019579947 0.2758712173 ) 2 1 - vert 5 ( 0.1544233561 0.1464606524 ) 6 1 - vert 6 ( 0.1351719499 0.2028001547 ) 24 1 - vert 7 ( 0.171954602 0.2357563972 ) 5 1 - vert 8 ( 0.1278462112 0.0496608615 ) 7 1 - vert 9 ( 0.089523375 0.0932300091 ) 22 1 - vert 10 ( 0.2883290946 0.3198521137 ) 8 1 - vert 11 ( 0.3885064721 0.3162279725 ) 14 1 - vert 12 ( 0.3764350414 0.1383455992 ) 9 1 - vert 13 ( 0.5307995081 0.2516872287 ) 11 1 - vert 14 ( 0.3052866757 0.4512680769 ) 29 1 - vert 15 ( 0.657755971 0.1422971487 ) 12 1 - vert 16 ( 0.7270016074 0.0501540899 ) 15 1 - vert 17 ( 0.6093223095 0.0132830143 ) 13 1 - vert 18 ( 0.397133708 0.4132919312 ) 30 1 - vert 19 ( 0.5898922086 0.3569136858 ) 23 1 - vert 20 ( 0.7742574215 0.2692213058 ) 18 1 - vert 21 ( 0.3144330978 0.0056509972 ) 10 1 - vert 22 ( 0.4609167278 0.4617749453 ) 31 1 - vert 23 ( 0.8475543857 0.1806005239 ) 19 1 - vert 24 ( 0.7961168885 0.3383333683 ) 20 1 - vert 25 ( 0.9255080223 0.3171625137 ) 27 1 - vert 26 ( 0.0348297954 0.1663915515 ) 3 1 - vert 27 ( 0.6848887205 0.3628741503 ) 25 1 - vert 28 ( 0.1598546505 0.4307519794 ) 26 1 - vert 29 ( 0.266798079 0.4894410968 ) 16 1 - vert 30 ( 0.1471122503 0.4926059246 ) 0 1 - vert 31 ( 0.9909909964 0.9373573065 ) 31 1 - vert 32 ( 0.9882833958 0.8554439545 ) 30 1 - vert 33 ( 0.8673883677 0.8946229815 ) 28 1 - vert 34 ( 0.9284396172 0.7744396925 ) 29 1 - vert 35 ( 0.1100263596 0.3216068745 ) 45 1 - vert 36 ( 0.1494305432 0.3869812489 ) 42 1 - vert 37 ( 0.0642609596 0.291307807 ) 33 1 - vert 38 ( 0.1351719499 0.2028001547 ) 47 1 - vert 39 ( 0.1544233561 0.1464606524 ) 35 1 - vert 40 ( 0.171954602 0.2357563972 ) 34 1 - vert 41 ( 0.2883290946 0.3198521137 ) 36 1 - vert 42 ( 0.3764350414 0.1383455992 ) 37 1 - vert 43 ( 0.3885064721 0.3162279725 ) 40 1 - vert 44 ( 0.5307995081 0.2516872287 ) 38 1 - vert 45 ( 0.3052866757 0.4512680769 ) 51 1 - vert 46 ( 0.657755971 0.1422971487 ) 39 1 - vert 47 ( 0.397133708 0.4132919312 ) 52 1 - vert 48 ( 0.5898922086 0.3569136858 ) 46 1 - vert 49 ( 0.7742574215 0.2692213058 ) 43 1 - vert 50 ( 0.4609167278 0.4617749453 ) 53 1 - vert 51 ( 0.7961168885 0.3383333683 ) 44 1 - vert 52 ( 0.6848887205 0.3628741503 ) 48 1 - vert 53 ( 0.1598546505 0.4307519794 ) 49 1 - vert 54 ( 0.266798079 0.4894410968 ) 41 1 - vert 55 ( 0.1471122503 0.4926059246 ) 32 1 - vert 56 ( 0.9882833958 0.8554439545 ) 52 1 - vert 57 ( 0.9909909964 0.9373573065 ) 53 1 - vert 58 ( 0.8673883677 0.8946229815 ) 50 1 - vert 59 ( 0.9284396172 0.7744396925 ) 51 1 - - numtris 90 - tri 0 2 1 0 - tri 1 2 4 3 - tri 2 2 3 1 - tri 3 7 6 5 - tri 4 9 8 5 - tri 5 0 7 10 - tri 6 10 12 11 - tri 7 11 12 13 - tri 8 14 10 11 - tri 9 13 12 15 - tri 10 15 17 16 - tri 11 14 11 18 - tri 12 18 11 19 - tri 13 19 11 13 - tri 14 19 13 15 - tri 15 19 15 20 - tri 16 12 21 17 - tri 17 12 17 15 - tri 18 22 18 19 - tri 19 20 16 23 - tri 20 20 15 16 - tri 21 25 24 23 - tri 22 24 20 23 - tri 23 3 4 26 - tri 24 1 3 6 - tri 25 0 6 7 - tri 26 0 1 6 - tri 27 8 21 12 - tri 28 5 8 12 - tri 29 6 26 9 - tri 30 6 9 5 - tri 31 3 26 6 - tri 32 10 5 12 - tri 33 10 7 5 - tri 34 22 19 27 - tri 35 27 19 20 - tri 36 24 27 20 - tri 37 29 28 14 - tri 38 30 28 29 - tri 39 30 2 28 - tri 40 28 2 0 - tri 41 28 10 14 - tri 42 28 0 10 - tri 43 33 32 31 - tri 44 33 34 32 - tri 45 2 36 35 - tri 46 2 37 4 - tri 47 2 35 37 - tri 48 40 39 38 - tri 49 9 39 8 - tri 50 36 41 40 - tri 51 41 43 42 - tri 52 43 44 42 - tri 53 45 43 41 - tri 54 44 46 42 - tri 55 46 16 17 - tri 56 45 47 43 - tri 57 47 48 43 - tri 58 48 44 43 - tri 59 48 46 44 - tri 60 48 49 46 - tri 61 42 17 21 - tri 62 42 46 17 - tri 63 50 48 47 - tri 64 49 23 16 - tri 65 49 16 46 - tri 66 25 23 51 - tri 67 51 23 49 - tri 68 37 26 4 - tri 69 35 38 37 - tri 70 36 40 38 - tri 71 36 38 35 - tri 72 8 42 21 - tri 73 39 42 8 - tri 74 38 9 26 - tri 75 38 39 9 - tri 76 37 38 26 - tri 77 41 42 39 - tri 78 41 39 40 - tri 79 50 52 48 - tri 80 52 49 48 - tri 81 51 49 52 - tri 82 54 45 53 - tri 83 55 54 53 - tri 84 55 53 2 - tri 85 53 36 2 - tri 86 53 45 41 - tri 87 53 41 36 - tri 88 58 57 56 - tri 89 58 56 59 - - numweights 54 - weight 0 70 1 ( 3.9069023132 -4.7999677658 1.7643375397 ) - weight 1 70 1 ( 2.1467900276 -7.893951416 0.5111920834 ) - weight 2 70 1 ( 2.106869936 -7.9774017334 -0.000196819 ) - weight 3 70 1 ( 0.5962907672 -7.2906813622 -0.000196819 ) - weight 4 70 1 ( 3.3947947025 -6.4896345139 -0.000196819 ) - weight 5 70 1 ( 0.7972456217 -6.999256134 1.238973856 ) - weight 6 70 1 ( -0.3486454785 -7.1954402924 0.7279815078 ) - weight 7 70 1 ( -0.5673989654 -7.2733287811 -0.000196819 ) - weight 8 70 1 ( 1.1374293566 -6.244038105 2.6036653519 ) - weight 9 70 1 ( -2.0832393169 -6.3243179321 1.7982712984 ) - weight 10 70 1 ( -1.9365749359 -6.733522892 -0.000196819 ) - weight 11 70 1 ( -2.8617854118 -4.8248257637 2.8299491405 ) - weight 12 70 1 ( -4.5855116844 -4.3972535133 1.6666179895 ) - weight 13 70 1 ( -4.2134232521 -5.4797501564 -0.000196819 ) - weight 14 70 1 ( -0.7850980759 -5.392572403 3.1516666412 ) - weight 15 70 1 ( -5.0721178055 -4.0412044525 -0.000196819 ) - weight 16 70 1 ( 2.9572603703 -4.2790794373 2.8649995327 ) - weight 17 70 1 ( 2.8004574776 -6.2531204224 1.4517887831 ) - weight 18 70 1 ( -4.5080265999 -2.2752606869 1.4241397381 ) - weight 19 70 1 ( -4.9373059273 -2.0626568794 -0.000196819 ) - weight 20 70 1 ( -4.1891136169 -1.1446833611 1.5468600988 ) - weight 21 70 1 ( 2.2864582539 -7.4785046577 0.971288681 ) - weight 22 70 1 ( -0.4000812173 -6.5351777077 -0.000196819 ) - weight 23 70 1 ( -2.5621809959 -3.310188055 3.1197772026 ) - weight 24 70 1 ( 0.4051122665 -6.7873086929 0.749587059 ) - weight 25 70 1 ( -3.4999494553 -2.0152528286 2.8079488277 ) - weight 26 70 1 ( 3.1531260014 -5.6937632561 1.8332060575 ) - weight 27 70 1 ( -4.5069513321 -0.1208883002 -0.000196819 ) - weight 28 70 1 ( 1.3984042406 -3.7052609921 4.1880507469 ) - weight 29 70 1 ( 1.9070271254 -4.7368865013 3.1153585911 ) - weight 30 70 1 ( -0.1177325845 -4.2787289619 3.4099709988 ) - weight 31 70 1 ( -1.1169528961 -2.9698262215 4.046860218 ) - weight 32 70 1 ( 3.9069023132 -4.7999677658 -1.7647311687 ) - weight 33 70 1 ( 2.1467900276 -7.893951416 -0.511585772 ) - weight 34 70 1 ( 0.7972456217 -6.999256134 -1.239367485 ) - weight 35 70 1 ( -0.3486454785 -7.1954402924 -0.7283751965 ) - weight 36 70 1 ( 1.1374293566 -6.244038105 -2.6040589809 ) - weight 37 70 1 ( -2.0832393169 -6.3243179321 -1.7986649275 ) - weight 38 70 1 ( -2.8617854118 -4.8248257637 -2.8303427696 ) - weight 39 70 1 ( -4.5855116844 -4.3972535133 -1.6670116186 ) - weight 40 70 1 ( -0.7850980759 -5.392572403 -3.1520602703 ) - weight 41 70 1 ( 2.9572603703 -4.2790794373 -2.8653931618 ) - weight 42 70 1 ( 2.8004574776 -6.2531204224 -1.4521825314 ) - weight 43 70 1 ( -4.5080265999 -2.2752606869 -1.4245333672 ) - weight 44 70 1 ( -4.1891136169 -1.1446833611 -1.5472537279 ) - weight 45 70 1 ( 2.2864582539 -7.4785046577 -0.9716823697 ) - weight 46 70 1 ( -2.5621809959 -3.310188055 -3.1201708317 ) - weight 47 70 1 ( 0.4051122665 -6.7873086929 -0.7499807477 ) - weight 48 70 1 ( -3.4999494553 -2.0152528286 -2.8083426952 ) - weight 49 70 1 ( 3.1531260014 -5.6937632561 -1.8335996866 ) - weight 50 70 1 ( 1.3984042406 -3.7052609921 -4.1884441376 ) - weight 51 70 1 ( 1.9070271254 -4.7368865013 -3.1157522202 ) - weight 52 70 1 ( -0.1177325845 -4.2787289619 -3.4103646278 ) - weight 53 70 1 ( -1.1169528961 -2.9698262215 -4.0472536087 ) -} - -mesh { - // meshes: head_bfxflamemesh - shader "models/items/powerups/berserkerflame1" - - numverts 4 - vert 0 ( 0 0 ) 1 1 - vert 1 ( 0 1 ) 0 1 - vert 2 ( 1 1 ) 3 1 - vert 3 ( 1 0 ) 2 1 - - numtris 2 - tri 0 2 1 0 - tri 1 2 0 3 - - numweights 4 - weight 0 70 1 ( -0.2435768992 -3.4949643612 -10.5795507431 ) - weight 1 70 1 ( -18.3665409088 -18.1556072235 -10.6467313766 ) - weight 2 70 1 ( -18.3638801575 -18.1490573883 10.5797796249 ) - weight 3 70 1 ( -0.2457267493 -3.4923057556 10.650891304 ) -} - -mesh { - // meshes: head_bfxmodelmesh - shader "models/items/powerups/berserker" - - numverts 238 - vert 0 ( 0.0743311346 0.5817067623 ) 65 1 - vert 1 ( 0.0817542076 0.5337443352 ) 0 1 - vert 2 ( 0.0130193233 0.585028708 ) 66 1 - vert 3 ( 0.1064482927 0.5775771141 ) 64 1 - vert 4 ( 0.1164567471 0.541005075 ) 5 1 - vert 5 ( 0.0118026733 0.5357590318 ) 26 1 - vert 6 ( 0.1494305432 0.3869812489 ) 43 1 - vert 7 ( 0.1100263596 0.3216068745 ) 48 1 - vert 8 ( 0.0163724422 0.3971676826 ) 6 1 - vert 9 ( 0.0642609596 0.291307807 ) 2 1 - vert 10 ( 0.019579947 0.2758712173 ) 3 1 - vert 11 ( 0.1349100769 0.5160099864 ) 60 1 - vert 12 ( 0.1471122503 0.4926059246 ) 1 1 - vert 13 ( 0.1544233561 0.1464606524 ) 8 1 - vert 14 ( 0.1351719499 0.2028001547 ) 52 1 - vert 15 ( 0.171954602 0.2357563972 ) 7 1 - vert 16 ( 0.1278462112 0.0496608615 ) 9 1 - vert 17 ( 0.089523375 0.0932300091 ) 49 1 - vert 18 ( 0.2883290946 0.3198521137 ) 10 1 - vert 19 ( 0.3885064721 0.3162279725 ) 16 1 - vert 20 ( 0.3764350414 0.1383455992 ) 11 1 - vert 21 ( 0.5307995081 0.2516872287 ) 13 1 - vert 22 ( 0.3052866757 0.4512680769 ) 101 1 - vert 23 ( 0.657755971 0.1422971487 ) 14 1 - vert 24 ( 0.7270016074 0.0501540899 ) 17 1 - vert 25 ( 0.6093223095 0.0132830143 ) 15 1 - vert 26 ( 0.397133708 0.4132919312 ) 105 1 - vert 27 ( 0.5898922086 0.3569136858 ) 51 1 - vert 28 ( 0.2466555238 0.5318109989 ) 20 1 - vert 29 ( 0.2427662313 0.5158968568 ) 19 1 - vert 30 ( 0.1593426764 0.538028121 ) 21 1 - vert 31 ( 0.1536732614 0.5215650201 ) 22 1 - vert 32 ( 0.2293274105 0.5821720958 ) 68 1 - vert 33 ( 0.2238923311 0.559289515 ) 23 1 - vert 34 ( 0.1467296779 0.5874612331 ) 24 1 - vert 35 ( 0.1408945024 0.5649029016 ) 25 1 - vert 36 ( 0.7742574215 0.2692213058 ) 44 1 - vert 37 ( 0.0661771894 0.6510509253 ) 67 1 - vert 38 ( 0.2432101071 0.6114165783 ) 37 1 - vert 39 ( 0.1275528967 0.6174051762 ) 27 1 - vert 40 ( 0.1597544551 0.6488865614 ) 63 1 - vert 41 ( 0.2996183336 0.5545572042 ) 63 1 - vert 42 ( 0.3426653147 0.5920432806 ) 67 1 - vert 43 ( 0.3815406859 0.5899544954 ) 80 1 - vert 44 ( 0.1605748832 0.7848508358 ) 28 1 - vert 45 ( 0.097034812 0.8164480329 ) 77 1 - vert 46 ( 0.1688461602 0.8620938659 ) 30 1 - vert 47 ( 0.349774003 0.746160388 ) 29 1 - vert 48 ( 0.26157552 0.7108705044 ) 36 1 - vert 49 ( 0.2672157288 0.84705019 ) 31 1 - vert 50 ( 0.1850287914 0.9066070914 ) 32 1 - vert 51 ( 0.4470309019 0.8052583337 ) 72 2 - vert 52 ( 0.4225035906 0.7153644562 ) 34 1 - vert 53 ( 0.2747118473 0.6423062086 ) 35 1 - vert 54 ( 0.2488479614 0.6532441378 ) 42 1 - vert 55 ( 0.1091002524 0.888207972 ) 39 1 - vert 56 ( 0.1316922605 0.9272050858 ) 38 1 - vert 57 ( 0.0135852098 0.6524245739 ) 80 1 - vert 58 ( 0.3754219711 0.4416062832 ) 79 1 - vert 59 ( 0.3934007585 0.5881235003 ) 40 1 - vert 60 ( 0.4256639183 0.565484345 ) 77 1 - vert 61 ( 0.2246386707 0.9195722342 ) 33 1 - vert 62 ( 0.3168055713 0.4899734259 ) 41 1 - vert 63 ( 0.3652048707 0.4438020587 ) 69 1 - vert 64 ( 0.225854218 0.7068527341 ) 78 1 - vert 65 ( 0.6638988256 0.4384673834 ) 47 1 - vert 66 ( 0.4609167278 0.4617749453 ) 107 1 - vert 67 ( 0.475409776 0.5405245423 ) 106 1 - vert 68 ( 0.7889475822 0.4386638999 ) 56 1 - vert 69 ( 0.6515895128 0.5515316725 ) 50 1 - vert 70 ( 0.7961168885 0.3383333683 ) 46 1 - vert 71 ( 0.8676953912 0.3911019564 ) 81 1 - vert 72 ( 0.3144330978 0.0056509972 ) 12 1 - vert 73 ( 0.8475543857 0.1806005239 ) 45 1 - vert 74 ( 0.9255080223 0.3171625137 ) 82 1 - vert 75 ( 0.0348297954 0.1663915515 ) 4 1 - vert 76 ( 0.2854136825 0.5073700547 ) 102 1 - vert 77 ( 0.266798079 0.4894410968 ) 18 1 - vert 78 ( 0.6848887205 0.3628741503 ) 53 1 - vert 79 ( 0.950463295 0.4250696301 ) 55 1 - vert 80 ( 0.8749890327 0.4829963446 ) 54 1 - vert 81 ( 0.8360295296 0.6227073669 ) 74 1 - vert 82 ( 0.5049229264 0.5774653554 ) 57 1 - vert 83 ( 0.3803475499 0.6215609908 ) 103 1 - vert 84 ( 0.1598546505 0.4307519794 ) 58 1 - vert 85 ( 0.2279381156 0.5059960485 ) 59 1 - vert 86 ( 0.1502091885 0.5516627431 ) 62 1 - vert 87 ( 0.2998312712 0.6052771211 ) 104 1 - vert 88 ( 0.2396148741 0.5452057719 ) 61 1 - vert 89 ( 0.292817682 0.5620313883 ) 100 1 - vert 90 ( 0.0740072131 0.720738709 ) 69 1 - vert 91 ( 0.1052111685 0.793738246 ) 79 1 - vert 92 ( 0.204020232 0.6526802778 ) 41 1 - vert 93 ( 0.4375052154 0.8826436996 ) 71 1 - vert 94 ( 0.5916964412 0.692491889 ) 75 2 - vert 95 ( 0.2214886546 0.9477272034 ) 70 1 - vert 96 ( 0.4423643947 0.5212873816 ) 28 1 - vert 97 ( 0.4372642934 0.4644472599 ) 78 1 - vert 98 ( 0.0576105714 0.8487878442 ) 40 1 - vert 99 ( 0.9042165279 0.0152364969 ) 104 1 - vert 100 ( 0.842820704 0.0223935843 ) 103 1 - vert 101 ( 0.9554662704 0.1086400747 ) 85 1 - vert 102 ( 0.6818042397 0.846958518 ) 83 1 - vert 103 ( 0.7435188293 0.6985300779 ) 104 1 - vert 104 ( 0.6031317711 0.7962729931 ) 85 1 - vert 105 ( 0.9750410318 0.9862402678 ) 106 1 - vert 106 ( 0.9909909964 0.9373573065 ) 107 1 - vert 107 ( 0.7357161045 0.9546700716 ) 89 1 - vert 108 ( 0.7396953106 0.9920763969 ) 87 1 - vert 109 ( 0.6082983613 0.9590015411 ) 88 1 - vert 110 ( 0.7632403374 0.0322519541 ) 106 1 - vert 111 ( 0.87943995 0.1649194956 ) 87 1 - vert 112 ( 0.5595197678 0.8911667466 ) 91 1 - vert 113 ( 0.5093224049 0.8565453291 ) 93 1 - vert 114 ( 0.3523478508 0.9342952967 ) 90 1 - vert 115 ( 0.8673883677 0.8946229815 ) 84 1 - vert 116 ( 0.9882833958 0.8554439545 ) 105 1 - vert 117 ( 0.9284396172 0.7744396925 ) 101 1 - vert 118 ( 0.5997328758 0.9220203161 ) 92 1 - vert 119 ( 0.8598161936 0.7328016758 ) 102 1 - vert 120 ( 0.7122753263 0.9052348733 ) 95 1 - vert 121 ( 0.9274712801 0.1453864574 ) 96 1 - vert 122 ( 0.9555841684 0.207895875 ) 93 1 - vert 123 ( 0.6027491093 0.9895306826 ) 97 1 - vert 124 ( 0.514575541 0.9533077478 ) 94 1 - vert 125 ( 0.9116995335 0.2396963835 ) 97 1 - vert 126 ( 0.506065309 0.9332823753 ) 98 1 - vert 127 ( 0.4287562966 0.9512686729 ) 86 1 - vert 128 ( 0.9688926935 0.3494240642 ) 90 1 - vert 129 ( 0.9275205135 0.3084656 ) 99 1 - vert 130 ( 0.4294970632 0.9844075441 ) 99 1 - vert 131 ( 0.8032346964 0.710926652 ) 100 1 - vert 132 ( 0.0817542076 0.5337443352 ) 108 1 - vert 133 ( 0.0743311346 0.5817067623 ) 159 1 - vert 134 ( 0.1064482927 0.5775771141 ) 158 1 - vert 135 ( 0.1164567471 0.541005075 ) 111 1 - vert 136 ( 0.1100263596 0.3216068745 ) 144 1 - vert 137 ( 0.1494305432 0.3869812489 ) 140 1 - vert 138 ( 0.0642609596 0.291307807 ) 110 1 - vert 139 ( 0.1349100769 0.5160099864 ) 154 1 - vert 140 ( 0.1471122503 0.4926059246 ) 109 1 - vert 141 ( 0.1351719499 0.2028001547 ) 147 1 - vert 142 ( 0.1544233561 0.1464606524 ) 113 1 - vert 143 ( 0.171954602 0.2357563972 ) 112 1 - vert 144 ( 0.2883290946 0.3198521137 ) 114 1 - vert 145 ( 0.3764350414 0.1383455992 ) 115 1 - vert 146 ( 0.3885064721 0.3162279725 ) 118 1 - vert 147 ( 0.5307995081 0.2516872287 ) 116 1 - vert 148 ( 0.3052866757 0.4512680769 ) 187 1 - vert 149 ( 0.657755971 0.1422971487 ) 117 1 - vert 150 ( 0.397133708 0.4132919312 ) 191 1 - vert 151 ( 0.5898922086 0.3569136858 ) 146 1 - vert 152 ( 0.2427662313 0.5158968568 ) 120 1 - vert 153 ( 0.2466555238 0.5318109989 ) 121 1 - vert 154 ( 0.1593426764 0.538028121 ) 122 1 - vert 155 ( 0.1536732614 0.5215650201 ) 123 1 - vert 156 ( 0.2238923311 0.559289515 ) 124 1 - vert 157 ( 0.2293274105 0.5821720958 ) 161 1 - vert 158 ( 0.1467296779 0.5874612331 ) 125 1 - vert 159 ( 0.1408945024 0.5649029016 ) 126 1 - vert 160 ( 0.7742574215 0.2692213058 ) 141 1 - vert 161 ( 0.0661771894 0.6510509253 ) 160 1 - vert 162 ( 0.1275528967 0.6174051762 ) 127 1 - vert 163 ( 0.2432101071 0.6114165783 ) 137 1 - vert 164 ( 0.1597544551 0.6488865614 ) 157 1 - vert 165 ( 0.3426653147 0.5920432806 ) 160 1 - vert 166 ( 0.2996183336 0.5545572042 ) 157 1 - vert 167 ( 0.097034812 0.8164480329 ) 166 1 - vert 168 ( 0.1605748832 0.7848508358 ) 128 1 - vert 169 ( 0.1688461602 0.8620938659 ) 130 1 - vert 170 ( 0.26157552 0.7108705044 ) 136 1 - vert 171 ( 0.349774003 0.746160388 ) 129 1 - vert 172 ( 0.2672157288 0.84705019 ) 131 1 - vert 173 ( 0.1850287914 0.9066070914 ) 132 1 - vert 174 ( 0.4470309019 0.8052583337 ) 162 2 - vert 175 ( 0.4225035906 0.7153644562 ) 134 1 - vert 176 ( 0.2747118473 0.6423062086 ) 135 1 - vert 177 ( 0.2488479614 0.6532441378 ) 139 1 - vert 178 ( 0.4256639183 0.565484345 ) 166 1 - vert 179 ( 0.2246386707 0.9195722342 ) 133 1 - vert 180 ( 0.3168055713 0.4899734259 ) 138 1 - vert 181 ( 0.225854218 0.7068527341 ) 167 1 - vert 182 ( 0.4609167278 0.4617749453 ) 193 1 - vert 183 ( 0.6638988256 0.4384673834 ) 143 1 - vert 184 ( 0.475409776 0.5405245423 ) 192 1 - vert 185 ( 0.7889475822 0.4386638999 ) 150 1 - vert 186 ( 0.6515895128 0.5515316725 ) 145 1 - vert 187 ( 0.7961168885 0.3383333683 ) 142 1 - vert 188 ( 0.8676953912 0.3911019564 ) 168 1 - vert 189 ( 0.2854136825 0.5073700547 ) 188 1 - vert 190 ( 0.266798079 0.4894410968 ) 119 1 - vert 191 ( 0.6848887205 0.3628741503 ) 148 1 - vert 192 ( 0.8749890327 0.4829963446 ) 149 1 - vert 193 ( 0.5049229264 0.5774653554 ) 151 1 - vert 194 ( 0.3803475499 0.6215609908 ) 189 1 - vert 195 ( 0.1598546505 0.4307519794 ) 152 1 - vert 196 ( 0.2279381156 0.5059960485 ) 153 1 - vert 197 ( 0.1502091885 0.5516627431 ) 156 1 - vert 198 ( 0.2998312712 0.6052771211 ) 190 1 - vert 199 ( 0.2396148741 0.5452057719 ) 155 1 - vert 200 ( 0.292817682 0.5620313883 ) 186 1 - vert 201 ( 0.204020232 0.6526802778 ) 138 1 - vert 202 ( 0.5916964412 0.692491889 ) 164 2 - vert 203 ( 0.4423643947 0.5212873816 ) 128 1 - vert 204 ( 0.4372642934 0.4644472599 ) 167 1 - vert 205 ( 0.842820704 0.0223935843 ) 189 1 - vert 206 ( 0.9042165279 0.0152364969 ) 190 1 - vert 207 ( 0.9554662704 0.1086400747 ) 171 1 - vert 208 ( 0.7435188293 0.6985300779 ) 190 1 - vert 209 ( 0.6818042397 0.846958518 ) 169 1 - vert 210 ( 0.6031317711 0.7962729931 ) 171 1 - vert 211 ( 0.9909909964 0.9373573065 ) 193 1 - vert 212 ( 0.9750410318 0.9862402678 ) 192 1 - vert 213 ( 0.7357161045 0.9546700716 ) 175 1 - vert 214 ( 0.7396953106 0.9920763969 ) 173 1 - vert 215 ( 0.6082983613 0.9590015411 ) 174 1 - vert 216 ( 0.7632403374 0.0322519541 ) 192 1 - vert 217 ( 0.87943995 0.1649194956 ) 173 1 - vert 218 ( 0.5093224049 0.8565453291 ) 179 1 - vert 219 ( 0.5595197678 0.8911667466 ) 177 1 - vert 220 ( 0.3523478508 0.9342952967 ) 176 1 - vert 221 ( 0.8673883677 0.8946229815 ) 170 1 - vert 222 ( 0.9882833958 0.8554439545 ) 191 1 - vert 223 ( 0.9284396172 0.7744396925 ) 187 1 - vert 224 ( 0.5997328758 0.9220203161 ) 178 1 - vert 225 ( 0.8598161936 0.7328016758 ) 188 1 - vert 226 ( 0.7122753263 0.9052348733 ) 181 1 - vert 227 ( 0.9274712801 0.1453864574 ) 182 1 - vert 228 ( 0.9555841684 0.207895875 ) 179 1 - vert 229 ( 0.6027491093 0.9895306826 ) 183 1 - vert 230 ( 0.514575541 0.9533077478 ) 180 1 - vert 231 ( 0.9116995335 0.2396963835 ) 183 1 - vert 232 ( 0.506065309 0.9332823753 ) 184 1 - vert 233 ( 0.4287562966 0.9512686729 ) 172 1 - vert 234 ( 0.9688926935 0.3494240642 ) 176 1 - vert 235 ( 0.9275205135 0.3084656 ) 185 1 - vert 236 ( 0.4294970632 0.9844075441 ) 185 1 - vert 237 ( 0.8032346964 0.710926652 ) 186 1 - - numtris 376 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 3 1 4 - tri 3 2 5 1 - tri 4 8 7 6 - tri 5 8 10 9 - tri 6 8 9 7 - tri 7 1 11 4 - tri 8 1 12 11 - tri 9 5 12 1 - tri 10 5 8 12 - tri 11 15 14 13 - tri 12 17 16 13 - tri 13 6 15 18 - tri 14 18 20 19 - tri 15 19 20 21 - tri 16 22 18 19 - tri 17 21 20 23 - tri 18 23 25 24 - tri 19 22 19 26 - tri 20 26 19 27 - tri 21 30 29 28 - tri 22 30 31 29 - tri 23 34 33 32 - tri 24 34 35 33 - tri 25 27 19 21 - tri 26 27 21 23 - tri 27 27 23 36 - tri 28 37 2 0 - tri 29 40 39 38 - tri 30 43 42 41 - tri 31 46 45 44 - tri 32 49 48 47 - tri 33 50 46 49 - tri 34 49 47 51 - tri 35 47 52 51 - tri 36 54 38 53 - tri 37 37 0 39 - tri 38 56 55 50 - tri 39 57 2 37 - tri 40 37 39 40 - tri 41 60 59 58 - tri 42 50 55 46 - tri 43 61 50 49 - tri 44 43 41 62 - tri 45 43 62 63 - tri 46 44 64 48 - tri 47 67 66 65 - tri 48 69 65 68 - tri 49 68 65 70 - tri 50 68 70 71 - tri 51 20 72 25 - tri 52 20 25 23 - tri 53 66 26 27 - tri 54 36 24 73 - tri 55 36 23 24 - tri 56 74 70 73 - tri 57 70 36 73 - tri 58 9 10 75 - tri 59 7 9 14 - tri 60 6 14 15 - tri 61 6 7 14 - tri 62 16 72 20 - tri 63 13 16 20 - tri 64 14 75 17 - tri 65 14 17 13 - tri 66 9 75 14 - tri 67 18 13 20 - tri 68 18 15 13 - tri 69 77 22 76 - tri 70 66 27 78 - tri 71 78 27 36 - tri 72 70 78 36 - tri 73 65 78 70 - tri 74 65 66 78 - tri 75 71 70 74 - tri 76 81 80 79 - tri 77 79 71 74 - tri 78 80 71 79 - tri 79 83 67 82 - tri 80 82 67 65 - tri 81 82 65 69 - tri 82 77 84 22 - tri 83 12 84 77 - tri 84 12 8 84 - tri 85 84 8 6 - tri 86 84 18 22 - tri 87 84 6 18 - tri 88 31 85 29 - tri 89 31 11 85 - tri 90 86 4 30 - tri 91 4 11 31 - tri 92 30 4 31 - tri 93 29 85 76 - tri 94 34 3 35 - tri 95 39 3 34 - tri 96 3 4 35 - tri 97 35 4 86 - tri 98 85 77 76 - tri 99 53 38 87 - tri 100 38 32 87 - tri 101 32 33 88 - tri 102 32 88 89 - tri 103 32 89 87 - tri 104 48 64 54 - tri 105 48 54 53 - tri 106 39 0 3 - tri 107 52 83 82 - tri 108 52 82 69 - tri 109 47 53 52 - tri 110 47 48 53 - tri 111 52 53 83 - tri 112 53 87 83 - tri 113 11 12 85 - tri 114 85 12 77 - tri 115 86 30 88 - tri 116 30 28 88 - tri 117 35 86 33 - tri 118 86 88 33 - tri 119 39 34 32 - tri 120 39 32 38 - tri 121 91 90 64 - tri 122 64 90 54 - tri 123 54 90 92 - tri 124 40 38 92 - tri 125 54 92 38 - tri 126 49 51 93 - tri 127 69 68 94 - tri 128 52 69 94 - tri 129 51 52 94 - tri 130 93 51 94 - tri 131 81 93 94 - tri 132 94 80 81 - tri 133 46 44 48 - tri 134 48 49 46 - tri 135 56 50 61 - tri 136 61 95 56 - tri 137 96 60 58 - tri 138 58 97 96 - tri 139 55 98 46 - tri 140 46 98 45 - tri 141 93 95 61 - tri 142 61 49 93 - tri 143 80 94 68 - tri 144 68 71 80 - tri 145 89 88 28 - tri 146 28 29 76 - tri 147 89 28 76 - tri 148 101 100 99 - tri 149 104 103 102 - tri 150 107 106 105 - tri 151 108 107 105 - tri 152 109 107 108 - tri 153 111 110 100 - tri 154 114 113 112 - tri 155 107 115 106 - tri 156 115 116 106 - tri 157 115 117 116 - tri 158 118 112 102 - tri 159 109 118 107 - tri 160 102 119 117 - tri 161 118 120 107 - tri 162 118 102 120 - tri 163 120 102 117 - tri 164 120 117 115 - tri 165 107 120 115 - tri 166 121 100 101 - tri 167 122 121 101 - tri 168 121 111 100 - tri 169 124 109 123 - tri 170 123 109 108 - tri 171 125 111 121 - tri 172 125 121 122 - tri 173 127 126 124 - tri 174 127 114 126 - tri 175 114 112 126 - tri 176 126 112 118 - tri 177 126 118 109 - tri 178 124 126 109 - tri 179 113 102 112 - tri 180 113 104 102 - tri 181 129 122 128 - tri 182 127 130 114 - tri 183 127 124 130 - tri 184 130 124 123 - tri 185 129 125 122 - tri 186 102 103 131 - tri 187 119 102 131 - tri 188 2 133 132 - tri 189 133 134 132 - tri 190 134 135 132 - tri 191 2 132 5 - tri 192 8 137 136 - tri 193 8 138 10 - tri 194 8 136 138 - tri 195 132 135 139 - tri 196 132 139 140 - tri 197 5 132 140 - tri 198 5 140 8 - tri 199 143 142 141 - tri 200 17 142 16 - tri 201 137 144 143 - tri 202 144 146 145 - tri 203 146 147 145 - tri 204 148 146 144 - tri 205 147 149 145 - tri 206 149 24 25 - tri 207 148 150 146 - tri 208 150 151 146 - tri 209 154 153 152 - tri 210 154 152 155 - tri 211 158 157 156 - tri 212 158 156 159 - tri 213 151 147 146 - tri 214 151 149 147 - tri 215 151 160 149 - tri 216 161 133 2 - tri 217 164 163 162 - tri 218 43 166 165 - tri 219 169 168 167 - tri 220 172 171 170 - tri 221 173 172 169 - tri 222 172 174 171 - tri 223 171 174 175 - tri 224 177 176 163 - tri 225 161 162 133 - tri 226 56 173 55 - tri 227 57 161 2 - tri 228 161 164 162 - tri 229 178 58 59 - tri 230 173 169 55 - tri 231 179 172 173 - tri 232 43 180 166 - tri 233 43 63 180 - tri 234 168 170 181 - tri 235 184 183 182 - tri 236 186 185 183 - tri 237 185 187 183 - tri 238 185 188 187 - tri 239 145 25 72 - tri 240 145 149 25 - tri 241 182 151 150 - tri 242 160 73 24 - tri 243 160 24 149 - tri 244 74 73 187 - tri 245 187 73 160 - tri 246 138 75 10 - tri 247 136 141 138 - tri 248 137 143 141 - tri 249 137 141 136 - tri 250 16 145 72 - tri 251 142 145 16 - tri 252 141 17 75 - tri 253 141 142 17 - tri 254 138 141 75 - tri 255 144 145 142 - tri 256 144 142 143 - tri 257 190 189 148 - tri 258 182 191 151 - tri 259 191 160 151 - tri 260 187 160 191 - tri 261 183 187 191 - tri 262 183 191 182 - tri 263 188 74 187 - tri 264 81 79 192 - tri 265 79 74 188 - tri 266 192 79 188 - tri 267 194 193 184 - tri 268 193 183 184 - tri 269 193 186 183 - tri 270 190 148 195 - tri 271 140 190 195 - tri 272 140 195 8 - tri 273 195 137 8 - tri 274 195 148 144 - tri 275 195 144 137 - tri 276 155 152 196 - tri 277 155 196 139 - tri 278 197 154 135 - tri 279 135 155 139 - tri 280 154 155 135 - tri 281 152 189 196 - tri 282 158 159 134 - tri 283 162 158 134 - tri 284 134 159 135 - tri 285 159 197 135 - tri 286 196 189 190 - tri 287 176 198 163 - tri 288 163 198 157 - tri 289 157 199 156 - tri 290 157 200 199 - tri 291 157 198 200 - tri 292 170 177 181 - tri 293 170 176 177 - tri 294 162 134 133 - tri 295 175 193 194 - tri 296 175 186 193 - tri 297 171 175 176 - tri 298 171 176 170 - tri 299 175 194 176 - tri 300 176 194 198 - tri 301 139 196 140 - tri 302 196 190 140 - tri 303 197 199 154 - tri 304 154 199 153 - tri 305 159 156 197 - tri 306 197 156 199 - tri 307 162 157 158 - tri 308 162 163 157 - tri 309 91 181 90 - tri 310 181 177 90 - tri 311 177 201 90 - tri 312 164 201 163 - tri 313 177 163 201 - tri 314 172 93 174 - tri 315 186 202 185 - tri 316 175 202 186 - tri 317 174 202 175 - tri 318 93 202 174 - tri 319 81 202 93 - tri 320 202 81 192 - tri 321 169 170 168 - tri 322 170 169 172 - tri 323 56 179 173 - tri 324 179 56 95 - tri 325 203 58 178 - tri 326 58 203 204 - tri 327 55 169 98 - tri 328 169 167 98 - tri 329 93 179 95 - tri 330 179 93 172 - tri 331 192 185 202 - tri 332 185 192 188 - tri 333 200 153 199 - tri 334 153 189 152 - tri 335 200 189 153 - tri 336 207 206 205 - tri 337 210 209 208 - tri 338 213 212 211 - tri 339 214 212 213 - tri 340 215 214 213 - tri 341 217 205 216 - tri 342 220 219 218 - tri 343 213 211 221 - tri 344 221 211 222 - tri 345 221 222 223 - tri 346 224 209 219 - tri 347 215 213 224 - tri 348 209 223 225 - tri 349 224 213 226 - tri 350 224 226 209 - tri 351 226 223 209 - tri 352 226 221 223 - tri 353 213 221 226 - tri 354 227 207 205 - tri 355 228 207 227 - tri 356 227 205 217 - tri 357 230 229 215 - tri 358 229 214 215 - tri 359 231 227 217 - tri 360 231 228 227 - tri 361 233 230 232 - tri 362 233 232 220 - tri 363 220 232 219 - tri 364 232 224 219 - tri 365 232 215 224 - tri 366 230 215 232 - tri 367 218 219 209 - tri 368 218 209 210 - tri 369 235 234 228 - tri 370 233 220 236 - tri 371 233 236 230 - tri 372 236 229 230 - tri 373 235 228 231 - tri 374 209 237 208 - tri 375 225 237 209 - - numweights 194 - weight 0 70 1 ( 4.4887771606 -4.25035429 0.9133175611 ) - weight 1 70 1 ( 3.8874094486 -4.7847633362 1.7486270666 ) - weight 2 70 1 ( 2.1441733837 -7.8673629761 0.4991912842 ) - weight 3 70 1 ( 2.10044384 -7.9488215446 -0.000196819 ) - weight 4 70 1 ( 0.6108383536 -7.2652573586 -0.000196819 ) - weight 5 70 1 ( 4.1262793541 -3.9484825134 1.1602625847 ) - weight 6 70 1 ( 3.3718860149 -6.4713830948 -0.000196819 ) - weight 7 70 1 ( 0.7892714739 -6.9711165428 1.2408051491 ) - weight 8 70 1 ( -0.3563652635 -7.1672329903 0.729588151 ) - weight 9 70 1 ( -0.5707774162 -7.2442407608 -0.000196819 ) - weight 10 70 1 ( 1.133454442 -6.2225852013 2.5841271877 ) - weight 11 70 1 ( -2.0723819733 -6.3002233505 1.7856583595 ) - weight 12 70 1 ( -1.9240305424 -6.707057476 -0.000196819 ) - weight 13 70 1 ( -2.849489212 -4.8132295609 2.806027174 ) - weight 14 70 1 ( -4.5629930496 -4.3876209259 1.6505608559 ) - weight 15 70 1 ( -4.1937913895 -5.4580202103 -0.000196819 ) - weight 16 70 1 ( -0.7819896936 -5.3808164597 3.1250216961 ) - weight 17 70 1 ( -5.0430912971 -4.0372943878 -0.000196819 ) - weight 18 70 1 ( 2.9429101944 -4.265376091 2.8434529305 ) - weight 19 70 1 ( 3.3543937206 -4.1321368217 2.7955918312 ) - weight 20 70 1 ( 3.5317664146 -3.8530778885 2.8677370548 ) - weight 21 70 1 ( 4.3023290634 -4.0544700623 1.8916699886 ) - weight 22 70 1 ( 4.1223516464 -4.3449792862 1.7923140526 ) - weight 23 70 1 ( 3.9617552757 -3.5987238884 2.6413722038 ) - weight 24 70 1 ( 4.9154062271 -3.3812501431 1.7669038773 ) - weight 25 70 1 ( 4.6825790405 -3.7926645279 1.6705178022 ) - weight 26 70 1 ( 4.7244958878 -4.3291063309 -0.000196819 ) - weight 27 70 1 ( 4.6673407555 -2.6788442135 1.2334491014 ) - weight 28 73 1 ( 1.2972511053 -1.7493789196 2.150645256 ) - weight 29 73 1 ( 2.6974179745 -2.2848064899 0.0417033285 ) - weight 30 73 1 ( 0.8991217017 -3.0184726715 2.3828954697 ) - weight 31 73 1 ( 1.6005080938 -3.378770113 1.3058120012 ) - weight 32 73 1 ( 0.92118752 -3.846729517 2.5373146534 ) - weight 33 73 1 ( 0.7171260715 -4.0515351295 2.247895956 ) - weight 34 73 1 ( 2.7730481625 -1.6923462152 -0.2819142342 ) - weight 35 70 1 ( 2.9992008209 -1.4594067335 2.2303438187 ) - weight 36 73 1 ( 1.8727338314 -1.8747084141 1.0810736418 ) - weight 37 70 1 ( 3.4948494434 -2.2764029503 2.2544636726 ) - weight 38 73 1 ( -0.000196819 -3.7760791779 2.8126583099 ) - weight 39 73 1 ( -0.000196819 -3.0103018284 2.8193683624 ) - weight 40 73 1 ( -0.000196819 -2.0894749165 3.2591309547 ) - weight 41 70 1 ( 2.8694124222 -1.5967087746 0.9182719588 ) - weight 42 70 1 ( 2.9920320511 -1.3359388113 1.7448128462 ) - weight 43 70 1 ( 2.7869455814 -6.2306337357 1.438765645 ) - weight 44 70 1 ( -4.4826045036 -2.2766797543 1.4096599817 ) - weight 45 70 1 ( -4.908469677 -2.067794323 -0.000196819 ) - weight 46 70 1 ( -4.1629624367 -1.1505990028 1.5350675583 ) - weight 47 70 1 ( -2.729380846 -1.3311377764 3.1537709236 ) - weight 48 70 1 ( 2.277077198 -7.4603338242 0.9503208995 ) - weight 49 70 1 ( -0.4126923382 -6.5087409019 -0.000196819 ) - weight 50 70 1 ( -1.4109973907 -0.2290366739 3.1543638706 ) - weight 51 70 1 ( -2.5485818386 -3.3042793274 3.0945227146 ) - weight 52 70 1 ( 0.4078196585 -6.758395195 0.7457323074 ) - weight 53 70 1 ( -3.4792275429 -2.0115077496 2.7875921726 ) - weight 54 70 1 ( -3.4704446793 1.4056558609 0.4874826074 ) - weight 55 70 1 ( -3.7928869724 1.1635768414 -0.000196819 ) - weight 56 70 1 ( -3.6526641846 -0.1681361496 2.3784661293 ) - weight 57 70 1 ( -0.1323593557 -1.1602547169 3.513478756 ) - weight 58 70 1 ( 3.1370837688 -5.6770358086 1.8153011799 ) - weight 59 70 1 ( 3.2877397537 -4.2516384125 2.5019567013 ) - weight 60 70 1 ( 3.9598371983 -4.3617691994 1.475830555 ) - weight 61 70 1 ( 3.6325700283 -3.6260886192 2.672940731 ) - weight 62 70 1 ( 4.3329534531 -3.8162527084 1.7402470112 ) - weight 63 70 1 ( 4.4285254478 -1.9096144438 1.3212800026 ) - weight 64 70 1 ( 4.7254619598 -3.4860298634 1.183868885 ) - weight 65 70 1 ( 4.8337774277 -3.4597153664 0.7459252477 ) - weight 66 70 1 ( 5.1389789581 -3.5392053127 -0.000196819 ) - weight 67 70 1 ( 5.5218462944 -2.3942141533 0.664809525 ) - weight 68 70 1 ( 4.1950445175 -3.1803154945 2.7291297913 ) - weight 69 70 1 ( 1.8622117043 -1.1128208637 -0.000196819 ) - weight 70 73 1 ( -0.000196819 -4.0344085693 2.3589715958 ) - weight 71 73 1 ( -0.000196819 -3.002733469 -0.1739234179 ) - weight 72 73 0.8500000238 ( 1.9292938709 -2.4755923748 -0.8213019967 ) - weight 73 70 0.150000006 ( 2.0802259445 0.9743623734 1.9292938709 ) - weight 74 70 1 ( -3.0968606472 1.7720307112 -0.000196819 ) - weight 75 73 0.400000006 ( 2.3082699776 -2.0018084049 -2.5602154732 ) - weight 76 70 0.6000000238 ( 0.3025345504 1.2711869478 2.3082699776 ) - weight 77 73 1 ( 0.7971792817 -1.8741992712 2.9980430603 ) - weight 78 73 1 ( 1.3540520668 -1.4049056768 1.0492879152 ) - weight 79 73 1 ( -0.000196819 -1.8581477404 0.0621748604 ) - weight 80 70 1 ( 5.6001462936 -2.4375803471 -0.000196819 ) - weight 81 70 1 ( -4.1634478569 0.283195436 1.0509252548 ) - weight 82 70 1 ( -4.4783549309 -0.1272273213 -0.000196819 ) - weight 83 70 1 ( 3.470187664 -2.6731569767 3.6536631584 ) - weight 84 70 1 ( 1.402459383 -3.6863002777 4.1660995483 ) - weight 85 70 1 ( 3.3802790642 -1.7286604643 3.3161401749 ) - weight 86 70 1 ( 5.8984589577 -1.9205169678 3.8506913185 ) - weight 87 70 1 ( 2.682413578 -1.3458734751 4.614669323 ) - weight 88 70 1 ( 4.1753239632 -1.4524481297 4.8923954964 ) - weight 89 70 1 ( 2.8058311939 -1.8604311943 4.9600214958 ) - weight 90 70 1 ( 6.1652317047 -2.2046825886 3.2152576447 ) - weight 91 70 1 ( 4.4566030502 -2.1743910313 3.8996226788 ) - weight 92 70 1 ( 4.3051753044 -1.9741355181 4.6384487152 ) - weight 93 70 1 ( 4.3783588409 -1.6219723225 3.5631942749 ) - weight 94 70 1 ( 5.2433872223 -1.5383089781 4.379181385 ) - weight 95 70 1 ( 3.297533989 -2.5083007813 4.3896508217 ) - weight 96 70 1 ( 3.3441519737 -1.3388106823 3.8425657749 ) - weight 97 70 1 ( 4.2006893158 -1.164031744 4.398870945 ) - weight 98 70 1 ( 5.1187753677 -1.9920721054 4.3406510353 ) - weight 99 70 1 ( 5.2477722168 -1.4336153269 3.8268764019 ) - weight 100 70 1 ( 3.0641376972 -3.12768507 2.7560362816 ) - weight 101 70 1 ( 1.9013035297 -4.722638607 3.0904173851 ) - weight 102 70 1 ( 2.5339148045 -3.9699876308 2.5223965645 ) - weight 103 70 1 ( 1.4775955677 -1.3917653561 2.8867590427 ) - weight 104 70 1 ( 2.5929832458 -2.0062406063 2.5614790916 ) - weight 105 70 1 ( -0.1135415658 -4.2647647858 3.3845703602 ) - weight 106 70 1 ( -0.3966183066 -1.963514924 3.9864997864 ) - weight 107 70 1 ( -1.1065473557 -2.9565877914 4.0228943825 ) - weight 108 70 1 ( 4.4887771606 -4.25035429 -0.9137111902 ) - weight 109 70 1 ( 3.8874094486 -4.7847633362 -1.7490208149 ) - weight 110 70 1 ( 2.1441733837 -7.8673629761 -0.4995849431 ) - weight 111 70 1 ( 4.1262793541 -3.9484825134 -1.160656333 ) - weight 112 70 1 ( 0.7892714739 -6.9711165428 -1.2411987782 ) - weight 113 70 1 ( -0.3563652635 -7.1672329903 -0.7299818397 ) - weight 114 70 1 ( 1.133454442 -6.2225852013 -2.5845208168 ) - weight 115 70 1 ( -2.0723819733 -6.3002233505 -1.7860519886 ) - weight 116 70 1 ( -2.849489212 -4.8132295609 -2.8064208031 ) - weight 117 70 1 ( -4.5629930496 -4.3876209259 -1.6509546041 ) - weight 118 70 1 ( -0.7819896936 -5.3808164597 -3.1254153252 ) - weight 119 70 1 ( 2.9429101944 -4.265376091 -2.8438465595 ) - weight 120 70 1 ( 3.3543937206 -4.1321368217 -2.7959854603 ) - weight 121 70 1 ( 3.5317664146 -3.8530778885 -2.8681306839 ) - weight 122 70 1 ( 4.3023290634 -4.0544700623 -1.8920636177 ) - weight 123 70 1 ( 4.1223516464 -4.3449792862 -1.7927076817 ) - weight 124 70 1 ( 3.9617552757 -3.5987238884 -2.6417658329 ) - weight 125 70 1 ( 4.9154062271 -3.3812501431 -1.7672976255 ) - weight 126 70 1 ( 4.6825790405 -3.7926645279 -1.6709114313 ) - weight 127 70 1 ( 4.6673407555 -2.6788442135 -1.2338427305 ) - weight 128 73 1 ( -1.2976447344 -1.7493789196 2.150645256 ) - weight 129 73 1 ( -2.6978116035 -2.2848064899 0.0417033285 ) - weight 130 73 1 ( -0.8995153308 -3.0184726715 2.3828954697 ) - weight 131 73 1 ( -1.6009017229 -3.378770113 1.3058120012 ) - weight 132 73 1 ( -0.9215811491 -3.846729517 2.5373146534 ) - weight 133 73 1 ( -0.7175197005 -4.0515351295 2.247895956 ) - weight 134 73 1 ( -2.7734417915 -1.6923462152 -0.2819142342 ) - weight 135 70 1 ( 2.9992008209 -1.4594067335 -2.2307374477 ) - weight 136 73 1 ( -1.8731274605 -1.8747084141 1.0810736418 ) - weight 137 70 1 ( 3.4948494434 -2.2764029503 -2.2548575401 ) - weight 138 70 1 ( 2.8694124222 -1.5967087746 -0.9186655879 ) - weight 139 70 1 ( 2.9920320511 -1.3359388113 -1.7452064753 ) - weight 140 70 1 ( 2.7869455814 -6.2306337357 -1.4391592741 ) - weight 141 70 1 ( -4.4826045036 -2.2766797543 -1.4100536108 ) - weight 142 70 1 ( -4.1629624367 -1.1505990028 -1.5354611874 ) - weight 143 70 1 ( -2.729380846 -1.3311377764 -3.1541645527 ) - weight 144 70 1 ( 2.277077198 -7.4603338242 -0.9507145882 ) - weight 145 70 1 ( -1.4109973907 -0.2290366739 -3.1547574997 ) - weight 146 70 1 ( -2.5485818386 -3.3042793274 -3.0949163437 ) - weight 147 70 1 ( 0.4078196585 -6.758395195 -0.7461259365 ) - weight 148 70 1 ( -3.4792275429 -2.0115077496 -2.7879858017 ) - weight 149 70 1 ( -3.4704446793 1.4056558609 -0.4878762364 ) - weight 150 70 1 ( -3.6526641846 -0.1681361496 -2.3788597584 ) - weight 151 70 1 ( -0.1323593557 -1.1602547169 -3.513872385 ) - weight 152 70 1 ( 3.1370837688 -5.6770358086 -1.815694809 ) - weight 153 70 1 ( 3.2877397537 -4.2516384125 -2.5023503304 ) - weight 154 70 1 ( 3.9598371983 -4.3617691994 -1.476224184 ) - weight 155 70 1 ( 3.6325700283 -3.6260886192 -2.6733343601 ) - weight 156 70 1 ( 4.3329534531 -3.8162527084 -1.7406407595 ) - weight 157 70 1 ( 4.4285254478 -1.9096144438 -1.3216736317 ) - weight 158 70 1 ( 4.7254619598 -3.4860298634 -1.1842625141 ) - weight 159 70 1 ( 4.8337774277 -3.4597153664 -0.7463188767 ) - weight 160 70 1 ( 5.5218462944 -2.3942141533 -0.6652031541 ) - weight 161 70 1 ( 4.1950445175 -3.1803154945 -2.7295234203 ) - weight 162 73 0.8500000238 ( -1.9296875 -2.4755923748 -0.8213019967 ) - weight 163 70 0.150000006 ( 2.0802259445 0.9743623734 -1.9296875 ) - weight 164 73 0.400000006 ( -2.3086636066 -2.0018084049 -2.5602154732 ) - weight 165 70 0.6000000238 ( 0.3025345504 1.2711869478 -2.3086636066 ) - weight 166 73 1 ( -0.7975729108 -1.8741992712 2.9980430603 ) - weight 167 73 1 ( -1.3544456959 -1.4049056768 1.0492879152 ) - weight 168 70 1 ( -4.1634478569 0.283195436 -1.0513190031 ) - weight 169 70 1 ( 3.470187664 -2.6731569767 -3.6540567875 ) - weight 170 70 1 ( 1.402459383 -3.6863002777 -4.166492939 ) - weight 171 70 1 ( 3.3802790642 -1.7286604643 -3.3165338039 ) - weight 172 70 1 ( 5.8984589577 -1.9205169678 -3.8510849476 ) - weight 173 70 1 ( 2.682413578 -1.3458734751 -4.6150627136 ) - weight 174 70 1 ( 4.1753239632 -1.4524481297 -4.8927884102 ) - weight 175 70 1 ( 2.8058311939 -1.8604311943 -4.9604148865 ) - weight 176 70 1 ( 6.1652317047 -2.2046825886 -3.2156512737 ) - weight 177 70 1 ( 4.4566030502 -2.1743910313 -3.9000163078 ) - weight 178 70 1 ( 4.3051753044 -1.9741355181 -4.6388421059 ) - weight 179 70 1 ( 4.3783588409 -1.6219723225 -3.563587904 ) - weight 180 70 1 ( 5.2433872223 -1.5383089781 -4.3795742989 ) - weight 181 70 1 ( 3.297533989 -2.5083007813 -4.3900442123 ) - weight 182 70 1 ( 3.3441519737 -1.3388106823 -3.842959404 ) - weight 183 70 1 ( 4.2006893158 -1.164031744 -4.3992643356 ) - weight 184 70 1 ( 5.1187753677 -1.9920721054 -4.3410439491 ) - weight 185 70 1 ( 5.2477722168 -1.4336153269 -3.827270031 ) - weight 186 70 1 ( 3.0641376972 -3.12768507 -2.7564299107 ) - weight 187 70 1 ( 1.9013035297 -4.722638607 -3.0908110142 ) - weight 188 70 1 ( 2.5339148045 -3.9699876308 -2.5227901936 ) - weight 189 70 1 ( 1.4775955677 -1.3917653561 -2.8871526718 ) - weight 190 70 1 ( 2.5929832458 -2.0062406063 -2.5618727207 ) - weight 191 70 1 ( -0.1135415658 -4.2647647858 -3.3849639893 ) - weight 192 70 1 ( -0.3966183066 -1.963514924 -3.9868934155 ) - weight 193 70 1 ( -1.1065473557 -2.9565877914 -4.0232877731 ) -} - -mesh { - // meshes: head_stumpmesh - shader "models/characters/male_npc/marine/stump" - - numverts 101 - vert 0 ( 0.6934543848 0.8219865561 ) 19 1 - vert 1 ( 0.7389683127 0.9222109318 ) 8 1 - vert 2 ( 0.8260887265 0.8814315796 ) 57 2 - vert 3 ( 0.7937546372 0.8003970981 ) 31 2 - vert 4 ( 0.4094181657 0 ) 55 1 - vert 5 ( 0.4141213596 0.1367310286 ) 10 1 - vert 6 ( 0.5291227698 0.1914750934 ) 9 1 - vert 7 ( 0.4312846959 0.2731864452 ) 2 1 - vert 8 ( 0.5156006217 0.3436330557 ) 30 1 - vert 9 ( 0.6989002824 0.2258033752 ) 25 2 - vert 10 ( 0.7253223062 0.4188582897 ) 4 2 - vert 11 ( 0.5311965346 0.4342027903 ) 47 1 - vert 12 ( 0.3251782358 0.5312978029 ) 24 1 - vert 13 ( 0.2796489298 0.5450556874 ) 7 1 - vert 14 ( 0.3760869205 0.6070556045 ) 51 1 - vert 15 ( 0.1240544021 0.3849787116 ) 60 1 - vert 16 ( 0 0.3308757544 ) 39 1 - vert 17 ( 0.0341201089 0.5533587337 ) 59 1 - vert 18 ( 0.2208663076 0.588950038 ) 37 1 - vert 19 ( 0.2016890049 0.4718087912 ) 42 1 - vert 20 ( 0.4058504403 0.3057384491 ) 11 1 - vert 21 ( 0.6538209319 0.0479912758 ) 28 2 - vert 22 ( 0.6438126564 0.5478579402 ) 6 1 - vert 23 ( 0.3622787297 0.727658689 ) 48 1 - vert 24 ( 0.3729195893 0.3939875364 ) 46 1 - vert 25 ( 0.366119653 0.4189833403 ) 33 1 - vert 26 ( 0.5044714212 0.4996220469 ) 52 1 - vert 27 ( 0.5925530791 0.937029779 ) 16 1 - vert 28 ( 0.606331408 1 ) 0 1 - vert 29 ( 0.3790971637 0.8568054438 ) 56 1 - vert 30 ( 0.3898959458 0.9900559187 ) 44 1 - vert 31 ( 0.4953245521 0.8836978078 ) 43 1 - vert 32 ( 0.479424715 0.813652575 ) 27 1 - vert 33 ( 0.5992856026 0.7975356579 ) 18 1 - vert 34 ( 0.5590468645 0.691598773 ) 35 1 - vert 35 ( 0.3048637807 0.9480588436 ) 38 1 - vert 36 ( 0.3250518739 0.0053791404 ) 22 1 - vert 37 ( 0.3928112984 0.2988572121 ) 21 1 - vert 38 ( 0.3627870977 0.3235811591 ) 49 1 - vert 39 ( 0.3364901245 0.4411129951 ) 15 1 - vert 40 ( 0.3705801964 0.3660951853 ) 36 1 - vert 41 ( 0.2957169116 0.4016543031 ) 14 1 - vert 42 ( 0.1561716348 0.3229953051 ) 53 1 - vert 43 ( 0.3668615222 0.2563686967 ) 40 1 - vert 44 ( 0.0882276818 0.1640927792 ) 17 1 - vert 45 ( 0.6883695722 0.6435326338 ) 23 1 - vert 46 ( 0.8859171867 0.0649355054 ) 1 1 - vert 47 ( 0.9059584737 0.2427613735 ) 62 1 - vert 48 ( 0.9871087074 0.2483940721 ) 20 1 - vert 49 ( 0.99861449 0.0695917606 ) 50 1 - vert 50 ( 0.9508090615 0.4187806249 ) 12 1 - vert 51 ( 0.8922979236 0.4159110188 ) 3 1 - vert 52 ( 0.9031966329 0.7232593894 ) 61 1 - vert 53 ( 0.9088200927 0.8882303834 ) 45 1 - vert 54 ( 0.9739143848 0.7513062954 ) 41 1 - vert 55 ( 1 0.9089155793 ) 34 1 - vert 56 ( 0.8899032474 0.6129068136 ) 54 1 - vert 57 ( 0.9403423071 0.6142997742 ) 13 1 - vert 58 ( 0.6934543848 0.8219865561 ) 78 1 - vert 59 ( 0.7937546372 0.8003970981 ) 87 2 - vert 60 ( 0.4141213596 0.1367310286 ) 70 1 - vert 61 ( 0.5291227698 0.1914750934 ) 69 1 - vert 62 ( 0.4312846959 0.2731864452 ) 63 1 - vert 63 ( 0.5156006217 0.3436330557 ) 86 1 - vert 64 ( 0.6989002824 0.2258033752 ) 83 2 - vert 65 ( 0.7253223062 0.4188582897 ) 65 2 - vert 66 ( 0.5311965346 0.4342027903 ) 98 1 - vert 67 ( 0.2796489298 0.5450556874 ) 68 1 - vert 68 ( 0.3251782358 0.5312978029 ) 82 1 - vert 69 ( 0.3760869205 0.6070556045 ) 101 1 - vert 70 ( 0.1240544021 0.3849787116 ) 106 1 - vert 71 ( 0.2208663076 0.588950038 ) 92 1 - vert 72 ( 0.2016890049 0.4718087912 ) 95 1 - vert 73 ( 0.4058504403 0.3057384491 ) 71 1 - vert 74 ( 0.6438126564 0.5478579402 ) 67 1 - vert 75 ( 0.3622787297 0.727658689 ) 99 1 - vert 76 ( 0.366119653 0.4189833403 ) 89 1 - vert 77 ( 0.3729195893 0.3939875364 ) 97 1 - vert 78 ( 0.5044714212 0.4996220469 ) 102 1 - vert 79 ( 0.5925530791 0.937029779 ) 76 1 - vert 80 ( 0.3790971637 0.8568054438 ) 105 1 - vert 81 ( 0.4953245521 0.8836978078 ) 96 1 - vert 82 ( 0.479424715 0.813652575 ) 85 1 - vert 83 ( 0.5992856026 0.7975356579 ) 77 1 - vert 84 ( 0.5590468645 0.691598773 ) 90 1 - vert 85 ( 0.3627870977 0.3235811591 ) 100 1 - vert 86 ( 0.3928112984 0.2988572121 ) 80 1 - vert 87 ( 0.3364901245 0.4411129951 ) 75 1 - vert 88 ( 0.2957169116 0.4016543031 ) 74 1 - vert 89 ( 0.3705801964 0.3660951853 ) 91 1 - vert 90 ( 0.1561716348 0.3229953051 ) 103 1 - vert 91 ( 0.3668615222 0.2563686967 ) 93 1 - vert 92 ( 0.6883695722 0.6435326338 ) 81 1 - vert 93 ( 0.9059584737 0.2427613735 ) 108 1 - vert 94 ( 0.9871087074 0.2483940721 ) 79 1 - vert 95 ( 0.9508090615 0.4187806249 ) 72 1 - vert 96 ( 0.8922979236 0.4159110188 ) 64 1 - vert 97 ( 0.9031966329 0.7232593894 ) 107 1 - vert 98 ( 0.9739143848 0.7513062954 ) 94 1 - vert 99 ( 0.8899032474 0.6129068136 ) 104 1 - vert 100 ( 0.9403423071 0.6142997742 ) 73 1 - - numtris 190 - tri 0 2 1 0 - tri 1 2 0 3 - tri 2 6 5 4 - tri 3 8 7 6 - tri 4 6 7 5 - tri 5 10 8 9 - tri 6 9 8 6 - tri 7 10 11 8 - tri 8 14 13 12 - tri 9 17 16 15 - tri 10 18 17 15 - tri 11 18 15 19 - tri 12 8 20 7 - tri 13 9 6 21 - tri 14 21 6 4 - tri 15 10 22 11 - tri 16 23 18 14 - tri 17 23 17 18 - tri 18 26 25 24 - tri 19 26 24 11 - tri 20 28 27 1 - tri 21 31 30 29 - tri 22 31 29 32 - tri 23 31 32 33 - tri 24 33 32 34 - tri 25 30 35 29 - tri 26 32 23 34 - tri 27 34 26 22 - tri 28 22 26 11 - tri 29 26 12 25 - tri 30 4 5 36 - tri 31 20 38 37 - tri 32 7 20 37 - tri 33 13 19 39 - tri 34 13 39 12 - tri 35 24 41 40 - tri 36 41 38 40 - tri 37 15 42 41 - tri 38 7 37 43 - tri 39 42 38 41 - tri 40 7 43 5 - tri 41 44 42 16 - tri 42 15 16 42 - tri 43 44 36 5 - tri 44 44 5 43 - tri 45 44 43 42 - tri 46 43 38 42 - tri 47 43 37 38 - tri 48 11 24 8 - tri 49 20 40 38 - tri 50 19 15 41 - tri 51 19 41 39 - tri 52 25 41 24 - tri 53 25 39 41 - tri 54 27 31 33 - tri 55 27 33 0 - tri 56 27 0 1 - tri 57 34 22 45 - tri 58 3 0 45 - tri 59 47 9 46 - tri 60 46 9 21 - tri 61 49 48 47 - tri 62 49 47 46 - tri 63 50 47 48 - tri 64 50 51 47 - tri 65 51 9 47 - tri 66 51 10 9 - tri 67 52 3 45 - tri 68 53 3 52 - tri 69 53 2 3 - tri 70 54 53 52 - tri 71 55 53 54 - tri 72 52 45 56 - tri 73 56 45 22 - tri 74 54 52 57 - tri 75 52 56 57 - tri 76 56 22 10 - tri 77 56 10 51 - tri 78 57 51 50 - tri 79 57 56 51 - tri 80 14 12 26 - tri 81 18 19 13 - tri 82 14 18 13 - tri 83 12 39 25 - tri 84 8 24 20 - tri 85 24 40 20 - tri 86 35 23 29 - tri 87 35 17 23 - tri 88 32 29 23 - tri 89 34 23 14 - tri 90 14 26 34 - tri 91 33 34 45 - tri 92 45 0 33 - tri 93 30 31 27 - tri 94 27 28 30 - tri 95 2 58 1 - tri 96 2 59 58 - tri 97 61 4 60 - tri 98 63 61 62 - tri 99 61 60 62 - tri 100 65 64 63 - tri 101 64 61 63 - tri 102 65 63 66 - tri 103 69 68 67 - tri 104 17 70 16 - tri 105 71 70 17 - tri 106 71 72 70 - tri 107 63 62 73 - tri 108 64 21 61 - tri 109 21 4 61 - tri 110 65 66 74 - tri 111 75 69 71 - tri 112 75 71 17 - tri 113 78 77 76 - tri 114 78 66 77 - tri 115 28 1 79 - tri 116 81 80 30 - tri 117 81 82 80 - tri 118 81 83 82 - tri 119 83 84 82 - tri 120 30 80 35 - tri 121 82 84 75 - tri 122 84 74 78 - tri 123 74 66 78 - tri 124 78 76 68 - tri 125 4 36 60 - tri 126 73 86 85 - tri 127 62 86 73 - tri 128 67 87 72 - tri 129 67 68 87 - tri 130 77 89 88 - tri 131 88 89 85 - tri 132 70 88 90 - tri 133 62 91 86 - tri 134 90 88 85 - tri 135 62 60 91 - tri 136 44 16 90 - tri 137 70 90 16 - tri 138 44 60 36 - tri 139 44 91 60 - tri 140 44 90 91 - tri 141 91 90 85 - tri 142 91 85 86 - tri 143 66 63 77 - tri 144 73 85 89 - tri 145 72 88 70 - tri 146 72 87 88 - tri 147 76 77 88 - tri 148 76 88 87 - tri 149 79 83 81 - tri 150 79 58 83 - tri 151 79 1 58 - tri 152 84 92 74 - tri 153 59 92 58 - tri 154 93 46 64 - tri 155 46 21 64 - tri 156 49 93 94 - tri 157 49 46 93 - tri 158 95 94 93 - tri 159 95 93 96 - tri 160 96 93 64 - tri 161 96 64 65 - tri 162 97 92 59 - tri 163 53 97 59 - tri 164 53 59 2 - tri 165 98 97 53 - tri 166 55 98 53 - tri 167 97 99 92 - tri 168 99 74 92 - tri 169 98 100 97 - tri 170 97 100 99 - tri 171 99 65 74 - tri 172 99 96 65 - tri 173 100 95 96 - tri 174 100 96 99 - tri 175 69 78 68 - tri 176 71 67 72 - tri 177 69 67 71 - tri 178 68 76 87 - tri 179 63 73 77 - tri 180 77 73 89 - tri 181 35 80 75 - tri 182 35 75 17 - tri 183 82 75 80 - tri 184 84 69 75 - tri 185 69 84 78 - tri 186 83 92 84 - tri 187 92 83 58 - tri 188 30 79 81 - tri 189 79 30 28 - - numweights 109 - weight 0 70 1 ( 4.5948514938 1.2733103037 -0.0018726568 ) - weight 1 67 1 ( 0.1956117898 -2.5141088963 -0.0000661643 ) - weight 2 70 1 ( -1.5851825476 -0.7455028296 2.5103943348 ) - weight 3 67 1 ( 0.4461757541 -0.5139107704 2.6862590313 ) - weight 4 67 0.5 ( 1.8181900978 -0.2432794124 2.3661592007 ) - weight 5 70 0.5 ( 0.0146074221 1.289788723 2.3643527031 ) - weight 6 70 1 ( 1.1192467213 0.6609039903 2.0957787037 ) - weight 7 70 1 ( 2.0495042801 -1.3878480196 1.5300028324 ) - weight 8 70 1 ( 3.3775622845 1.185913682 -0.0018726568 ) - weight 9 70 1 ( -1.8449232578 0.1841350645 1.5422996283 ) - weight 10 70 1 ( -2.5388903618 -0.3984746337 1.3380333185 ) - weight 11 70 1 ( -1.2977044582 -1.3128910065 3.073990345 ) - weight 12 67 1 ( -0.0037434045 -0.5735861659 2.8351340294 ) - weight 13 67 1 ( 0.1396546662 1.5130099058 2.6250426769 ) - weight 14 70 1 ( 0.4430404305 -2.3472788334 2.5017483234 ) - weight 15 70 1 ( 1.328909874 -2.3702480793 2.856801033 ) - weight 16 70 1 ( 4.3915553093 1.3148425817 0.5990073085 ) - weight 17 70 1 ( -0.7394750118 -1.2813248634 -0.0018726568 ) - weight 18 70 1 ( 3.2935509682 1.0542823076 1.4096714258 ) - weight 19 70 1 ( 2.9874815941 1.1436245441 0.8167769909 ) - weight 20 67 1 ( -0.4394708872 -2.0896379948 1.8147902489 ) - weight 21 70 1 ( -1.4685382843 -1.4477311373 2.7788691521 ) - weight 22 70 1 ( -2.7998161316 -0.5070508122 -0.0018726568 ) - weight 23 70 1 ( 1.724660635 1.0418182611 1.6976376772 ) - weight 24 70 1 ( 2.0989899635 -1.557541728 2.1681694984 ) - weight 25 67 0.75 ( 1.851863265 -1.6157864332 1.4586036205 ) - weight 26 70 0.25 ( -1.3582217693 1.2740004063 1.456797123 ) - weight 27 70 1 ( 3.8008205891 0.2631819248 1.3563210964 ) - weight 28 67 0.75 ( 2.0251722336 -1.9972069263 -0.0000661643 ) - weight 29 70 0.25 ( -1.7418678999 1.1056754589 -0.0018726568 ) - weight 30 70 1 ( -0.694203496 -0.2963911891 2.5187981129 ) - weight 31 67 0.5 ( 1.400599122 2.2281973362 0.6773722768 ) - weight 32 70 0.5 ( 2.491314888 1.6751438379 0.6755657792 ) - weight 33 70 1 ( 0.7261958122 -1.8704828024 3.1051597595 ) - weight 34 67 1 ( -0.2027609944 3.1487262249 -0.0000661643 ) - weight 35 70 1 ( 2.5747048855 0.6029689312 1.8973873854 ) - weight 36 70 1 ( -0.3603162169 -1.9876096249 3.1897392273 ) - weight 37 70 1 ( 1.6425191164 -0.6437701583 1.1831865311 ) - weight 38 70 1 ( 4.8392887115 -0.6053027511 -0.0018726568 ) - weight 39 70 1 ( 0.2846706212 -2.2587878704 -0.0018726568 ) - weight 40 70 1 ( -1.4652709961 -1.0955753326 2.1284000874 ) - weight 41 67 1 ( -0.0239702966 2.6213450432 1.6061544418 ) - weight 42 70 1 ( 1.1827713251 -1.738391161 1.3662173748 ) - weight 43 70 1 ( 4.402463913 0.5214454532 1.0715105534 ) - weight 44 70 1 ( 5.0844430923 -0.1062965095 -0.0018726568 ) - weight 45 67 1 ( 0.4767629504 2.7768836021 -0.0000661643 ) - weight 46 70 1 ( 0.1136903837 -1.7352030277 3.0457286835 ) - weight 47 70 1 ( 0.288192749 -0.2355328947 2.55382061 ) - weight 48 70 1 ( 3.176877737 -0.614336133 1.4251824617 ) - weight 49 70 1 ( -1.0259548426 -1.8456300497 3.0439329147 ) - weight 50 67 1 ( -0.7282770872 -2.6196122169 -0.0000661643 ) - weight 51 70 1 ( 2.2374584675 -0.6523260474 1.966258049 ) - weight 52 70 1 ( 1.0601652861 -0.2672623098 2.7983062267 ) - weight 53 70 1 ( 0.0031122344 -1.9381494522 1.0483416319 ) - weight 54 67 1 ( 0.538662374 1.4729852676 2.4772350788 ) - weight 55 70 1 ( -2.7462072372 -0.1308515817 -0.0018726568 ) - weight 56 70 1 ( 4.4247112274 -0.5174238086 1.0932381153 ) - weight 57 67 0.5 ( 1.306355238 2.5154461861 -0.0000661643 ) - weight 58 70 0.5 ( 2.7797672749 1.7656372786 -0.0018726568 ) - weight 59 70 1 ( 1.0376255512 -0.7337554693 -0.0018726568 ) - weight 60 70 1 ( 0.5679870844 -2.1695978642 0.8530730605 ) - weight 61 67 1 ( 0.474745959 2.2628893852 1.671806097 ) - weight 62 67 1 ( 0.2182498723 -2.0278580189 1.7640482187 ) - weight 63 70 1 ( -1.5851825476 -0.7455028296 -2.5141398907 ) - weight 64 67 1 ( 0.4461757541 -0.5139107704 -2.686391592 ) - weight 65 67 0.5 ( 1.8181900978 -0.2432794124 -2.3662917614 ) - weight 66 70 0.5 ( 0.0146074221 1.289788723 -2.368098259 ) - weight 67 70 1 ( 1.1192467213 0.6609039903 -2.0995242596 ) - weight 68 70 1 ( 2.0495042801 -1.3878480196 -1.5337481499 ) - weight 69 70 1 ( -1.8449232578 0.1841350645 -1.5460449457 ) - weight 70 70 1 ( -2.5388903618 -0.3984746337 -1.341778636 ) - weight 71 70 1 ( -1.2977044582 -1.3128910065 -3.0777359009 ) - weight 72 67 1 ( -0.0037434045 -0.5735861659 -2.8352665901 ) - weight 73 67 1 ( 0.1396546662 1.5130099058 -2.6251752377 ) - weight 74 70 1 ( 0.4430404305 -2.3472788334 -2.5054938793 ) - weight 75 70 1 ( 1.328909874 -2.3702480793 -2.8605465889 ) - weight 76 70 1 ( 4.3915553093 1.3148425817 -0.6027526259 ) - weight 77 70 1 ( 3.2935509682 1.0542823076 -1.4134167433 ) - weight 78 70 1 ( 2.9874815941 1.1436245441 -0.8205223083 ) - weight 79 67 1 ( -0.4394708872 -2.0896379948 -1.8149225712 ) - weight 80 70 1 ( -1.4685382843 -1.4477311373 -2.7826147079 ) - weight 81 70 1 ( 1.724660635 1.0418182611 -1.7013829947 ) - weight 82 70 1 ( 2.0989899635 -1.557541728 -2.1719150543 ) - weight 83 67 0.75 ( 1.851863265 -1.6157864332 -1.4587359428 ) - weight 84 70 0.25 ( -1.3582217693 1.2740004063 -1.4605424404 ) - weight 85 70 1 ( 3.8008205891 0.2631819248 -1.3600664139 ) - weight 86 70 1 ( -0.694203496 -0.2963911891 -2.5225436687 ) - weight 87 67 0.5 ( 1.400599122 2.2281973362 -0.6775045991 ) - weight 88 70 0.5 ( 2.491314888 1.6751438379 -0.6793110967 ) - weight 89 70 1 ( 0.7261958122 -1.8704828024 -3.1089053154 ) - weight 90 70 1 ( 2.5747048855 0.6029689312 -1.9011327028 ) - weight 91 70 1 ( -0.3603162169 -1.9876096249 -3.1934847832 ) - weight 92 70 1 ( 1.6425191164 -0.6437701583 -1.1869318485 ) - weight 93 70 1 ( -1.4652709961 -1.0955753326 -2.1321456432 ) - weight 94 67 1 ( -0.0239702966 2.6213450432 -1.6062867641 ) - weight 95 70 1 ( 1.1827713251 -1.738391161 -1.3699626923 ) - weight 96 70 1 ( 4.402463913 0.5214454532 -1.0752558708 ) - weight 97 70 1 ( 0.1136903837 -1.7352030277 -3.0494742393 ) - weight 98 70 1 ( 0.288192749 -0.2355328947 -2.5575661659 ) - weight 99 70 1 ( 3.176877737 -0.614336133 -1.4289277792 ) - weight 100 70 1 ( -1.0259548426 -1.8456300497 -3.0476784706 ) - weight 101 70 1 ( 2.2374584675 -0.6523260474 -1.9700033665 ) - weight 102 70 1 ( 1.0601652861 -0.2672623098 -2.8020517826 ) - weight 103 70 1 ( 0.0031122344 -1.9381494522 -1.0520869493 ) - weight 104 67 1 ( 0.538662374 1.4729852676 -2.4773676395 ) - weight 105 70 1 ( 4.4247112274 -0.5174238086 -1.0969834328 ) - weight 106 70 1 ( 0.5679870844 -2.1695978642 -0.856818378 ) - weight 107 67 1 ( 0.474745959 2.2628893852 -1.6719384193 ) - weight 108 67 1 ( 0.2182498723 -2.0278580189 -1.764180541 ) -} - -mesh { - // meshes: soldiermesh - shader "models/characters/male_npc/soldier/soldier" - - numverts 859 - vert 0 ( 0.0977350026 0.5801950097 ) 0 4 - vert 1 ( 0.0537669994 0.5374909639 ) 4 4 - vert 2 ( 0.0802770033 0.5959479809 ) 8 4 - vert 3 ( 0.1559399962 0.593618989 ) 12 4 - vert 4 ( 0.4229699969 0.5442509651 ) 16 4 - vert 5 ( 0.4001600146 0.5009059906 ) 20 4 - vert 6 ( 0.4140540063 0.5756520033 ) 24 3 - vert 7 ( 0.4263220131 0.4909489751 ) 27 4 - vert 8 ( 0.4089609981 0.4506909847 ) 31 4 - vert 9 ( 0.4661200047 0.4774569869 ) 35 3 - vert 10 ( 0.4610170126 0.5676040053 ) 38 5 - vert 11 ( 0.4661200047 0.4454489946 ) 43 4 - vert 12 ( 0.3593530059 0.502472043 ) 47 4 - vert 13 ( 0.3492580056 0.4542530179 ) 51 5 - vert 14 ( 0.2927469909 0.5144940019 ) 56 4 - vert 15 ( 0.2438320071 0.4694370031 ) 60 5 - vert 16 ( 0.1268739998 0.5218780041 ) 65 5 - vert 17 ( 0.4875909984 0.7850450277 ) 70 4 - vert 18 ( 0.501330018 0.833065033 ) 74 4 - vert 19 ( 0.5321450233 0.7971050143 ) 78 4 - vert 20 ( 0.527493 0.7104359865 ) 82 3 - vert 21 ( 0.4898490012 0.3308830261 ) 85 2 - vert 22 ( 0.5338050127 0.3161150217 ) 87 2 - vert 23 ( 0.4741660058 0.3951740265 ) 89 3 - vert 24 ( 0.4595679939 0.8330010176 ) 92 3 - vert 25 ( 0.4992260039 0.4821460247 ) 95 3 - vert 26 ( 0.589910984 0.3965389729 ) 98 2 - vert 27 ( 0.5716040134 0.4827600121 ) 100 3 - vert 28 ( 0.5639020205 0.5490509868 ) 103 3 - vert 29 ( 0.5081449747 0.5488619804 ) 106 3 - vert 30 ( 0.4862830043 0.4918850064 ) 109 3 - vert 31 ( 0.5829150081 0.4924759865 ) 112 3 - vert 32 ( 0.5190560222 0.5774669647 ) 115 2 - vert 33 ( 0.4733340144 0.6302369833 ) 117 1 - vert 34 ( 0.5112810135 0.6217579842 ) 118 2 - vert 35 ( 0.5955759883 0.6822559834 ) 95 3 - vert 36 ( 0.609070003 0.7593790293 ) 89 3 - vert 37 ( 0.5241159797 0.67513901 ) 120 2 - vert 38 ( 0.6185759902 0.6687619686 ) 109 3 - vert 39 ( 0.5494279861 0.8385199904 ) 122 2 - vert 40 ( 0.5599139929 0.8966199756 ) 87 2 - vert 41 ( 0.5910789967 0.8339700103 ) 85 2 - vert 42 ( 0.8919839859 0.9213370085 ) 124 1 - vert 43 ( 0.8535649776 0.9448459744 ) 125 1 - vert 44 ( 0.8781870008 0.9453350306 ) 126 1 - vert 45 ( 0.9422659874 0.9171689749 ) 127 1 - vert 46 ( 0.924405992 0.9283440113 ) 128 1 - vert 47 ( 0.934664011 0.9610649943 ) 129 1 - vert 48 ( 0.7713090181 0.9185889959 ) 130 1 - vert 49 ( 0.7117850184 0.9155640006 ) 131 1 - vert 50 ( 0.7216209769 0.9516559839 ) 132 1 - vert 51 ( 0.8787090182 0.9745879769 ) 133 3 - vert 52 ( 0.8553580046 0.9746490121 ) 136 3 - vert 53 ( 0.9055380225 0.9909920096 ) 139 1 - vert 54 ( 0.8473979831 0.9899860024 ) 140 3 - vert 55 ( 0.4794029891 0.6629630327 ) 139 1 - vert 56 ( 0.7605239749 0.9580150247 ) 143 1 - vert 57 ( 0.74416399 0.9722880125 ) 144 1 - vert 58 ( 0.4427919984 0.7468309999 ) 144 1 - vert 59 ( 0.4337419868 0.8579019904 ) 145 3 - vert 60 ( 0.4850060046 0.8799200058 ) 148 3 - vert 61 ( 0.523778975 0.8859429955 ) 151 2 - vert 62 ( 0.4716799855 0.6076129675 ) 153 2 - vert 63 ( 0.4075230062 0.9607509971 ) 100 3 - vert 64 ( 0.3988110125 0.8936679959 ) 155 3 - vert 65 ( 0.394347012 0.9896720052 ) 112 3 - vert 66 ( 0.3550690114 0.875962019 ) 115 2 - vert 67 ( 0.3526349962 0.9818210006 ) 103 3 - vert 68 ( 0.6151559949 0.5710170269 ) 103 3 - vert 69 ( 0.6058449745 0.6210620403 ) 106 3 - vert 70 ( 0.5195450187 0.9315680265 ) 158 2 - vert 71 ( 0.4597109854 0.9573209882 ) 98 2 - vert 72 ( 0.666786015 0.9181720018 ) 160 1 - vert 73 ( 0.6479740143 0.9120259881 ) 161 1 - vert 74 ( 0.6379150152 0.9437299967 ) 162 2 - vert 75 ( 0.9726229906 0.9240419865 ) 162 2 - vert 76 ( 0.9495090246 0.9532920122 ) 164 2 - vert 77 ( 0.9721109867 0.9635840058 ) 166 2 - vert 78 ( 0.9396569729 0.8899279833 ) 168 1 - vert 79 ( 0.978546977 0.8670679927 ) 169 1 - vert 80 ( 0.9408730268 0.874285996 ) 170 1 - vert 81 ( 0.8010870218 0.711452961 ) 171 2 - vert 82 ( 0.7650160193 0.7246769667 ) 173 2 - vert 83 ( 0.8155189753 0.7483010292 ) 175 2 - vert 84 ( 0.9123610258 0.9656270146 ) 177 1 - vert 85 ( 0.8066300154 0.7665590048 ) 178 2 - vert 86 ( 0.752530992 0.7550070286 ) 180 2 - vert 87 ( 0.7681649923 0.7735170126 ) 182 2 - vert 88 ( 0.7297629714 0.7690969706 ) 184 2 - vert 89 ( 0.6955400109 0.7595160007 ) 186 2 - vert 90 ( 0.8301010132 0.9127190113 ) 188 1 - vert 91 ( 0.8408420086 0.9305070043 ) 189 1 - vert 92 ( 0.6772639751 0.9037290215 ) 190 1 - vert 93 ( 0.678704977 0.8685560226 ) 191 1 - vert 94 ( 0.6432170272 0.8894940019 ) 169 1 - vert 95 ( 0.7579299808 0.6115549803 ) 192 2 - vert 96 ( 0.7100189924 0.6072689891 ) 194 1 - vert 97 ( 0.7244579792 0.6272779703 ) 195 1 - vert 98 ( 0.7032920122 0.670502007 ) 196 2 - vert 99 ( 0.7287060022 0.6930609941 ) 198 2 - vert 100 ( 0.759378016 0.6292409897 ) 200 2 - vert 101 ( 0.7155330181 0.9671120048 ) 202 1 - vert 102 ( 0.4258460104 0.7753620148 ) 202 1 - vert 103 ( 0.3732529879 0.8241159916 ) 166 2 - vert 104 ( 0.4041680098 0.8348730206 ) 203 2 - vert 105 ( 0.9038299918 0.8346620202 ) 205 1 - vert 106 ( 0.8732990026 0.8482810259 ) 206 1 - vert 107 ( 0.9140599966 0.8845689893 ) 207 1 - vert 108 ( 0.8934400082 0.8897830248 ) 208 1 - vert 109 ( 0.8858129978 0.7430869937 ) 209 2 - vert 110 ( 0.865835011 0.7806869745 ) 211 2 - vert 111 ( 0.9011470079 0.8023619652 ) 213 1 - vert 112 ( 0.8329390287 0.8720459938 ) 214 1 - vert 113 ( 0.9532859921 0.8276849985 ) 215 1 - vert 114 ( 0.9279770255 0.8277959824 ) 216 1 - vert 115 ( 0.9159590006 0.7293330431 ) 217 2 - vert 116 ( 0.9224870205 0.794788003 ) 219 1 - vert 117 ( 0.6432409883 0.815631032 ) 220 2 - vert 118 ( 0.6259819865 0.8491230011 ) 215 1 - vert 119 ( 0.7726150155 0.9083110094 ) 222 1 - vert 120 ( 0.7819550037 0.861676991 ) 223 1 - vert 121 ( 0.7129809856 0.9011930227 ) 224 1 - vert 122 ( 0.7129340172 0.8587610126 ) 225 1 - vert 123 ( 0.7923910022 0.8011859655 ) 226 2 - vert 124 ( 0.8403609991 0.650011003 ) 228 2 - vert 125 ( 0.7988709807 0.6290609837 ) 230 2 - vert 126 ( 0.8054479957 0.6605190039 ) 232 2 - vert 127 ( 0.988041997 0.518945992 ) 234 2 - vert 128 ( 0.93551898 0.5865709782 ) 236 3 - vert 129 ( 0.9685389996 0.6313810349 ) 239 2 - vert 130 ( 0.8923829794 0.6343989968 ) 241 2 - vert 131 ( 0.8554819822 0.6791859865 ) 243 2 - vert 132 ( 0.9029909968 0.6752110124 ) 245 2 - vert 133 ( 0.8880580068 0.5439299941 ) 247 2 - vert 134 ( 0.8512319922 0.5821909904 ) 249 1 - vert 135 ( 0.8218709826 0.6916069984 ) 250 2 - vert 136 ( 0.7669389844 0.6977820396 ) 252 2 - vert 137 ( 0.7972249985 0.5779629946 ) 254 2 - vert 138 ( 0.7575719953 0.5729500055 ) 256 2 - vert 139 ( 0.8024590015 0.4328410029 ) 258 1 - vert 140 ( 0.7664840221 0.4008550048 ) 259 3 - vert 141 ( 0.7135609984 0.3225979805 ) 262 4 - vert 142 ( 0.6906639934 0.3498520255 ) 266 3 - vert 143 ( 0.7104619741 0.4436630011 ) 269 3 - vert 144 ( 0.0956069976 0.6785979867 ) 272 3 - vert 145 ( 0.075567998 0.6963919997 ) 275 4 - vert 146 ( 0.1145659983 0.6984109879 ) 279 4 - vert 147 ( 0.1579069942 0.6584489942 ) 283 3 - vert 148 ( 0.182919994 0.6894710064 ) 286 4 - vert 149 ( 0.4152779877 0.6884410381 ) 286 4 - vert 150 ( 0.4432039857 0.6503549814 ) 290 4 - vert 151 ( 0.4248049855 0.6525720358 ) 294 3 - vert 152 ( 0.6540570259 0.5408209562 ) 234 2 - vert 153 ( 0.6677730083 0.3816210032 ) 283 3 - vert 154 ( 0.6078990102 0.3760970235 ) 286 4 - vert 155 ( 0.9418830276 0.3542219996 ) 286 4 - vert 156 ( 0.9014589787 0.366820991 ) 294 3 - vert 157 ( 0.7350249887 0.3181409836 ) 12 4 - vert 158 ( 0.8507739902 0.4169740081 ) 297 3 - vert 159 ( 0.1047170013 0.6168589592 ) 262 4 - vert 160 ( 0.067309998 0.6261379719 ) 300 4 - vert 161 ( 0.4610170126 0.6071609855 ) 304 4 - vert 162 ( 0.0144509999 0.6295149922 ) 308 5 - vert 163 ( 0.0500289984 0.6861320138 ) 313 5 - vert 164 ( 0.1066080034 0.6443809867 ) 266 3 - vert 165 ( 0.9332659841 0.6750910282 ) 318 2 - vert 166 ( 0.8840469718 0.709939003 ) 320 2 - vert 167 ( 0.9193720222 0.7085800171 ) 322 2 - vert 168 ( 0.8601080179 0.7186459899 ) 324 2 - vert 169 ( 0.6837400198 0.6937539577 ) 326 2 - vert 170 ( 0.6159399748 0.695874989 ) 318 2 - vert 171 ( 0.641053021 0.740696013 ) 328 2 - vert 172 ( 0.6345549822 0.6532559991 ) 239 2 - vert 173 ( 0.5808050036 0.3401960135 ) 158 2 - vert 174 ( 0.6575149894 0.7567790151 ) 330 2 - vert 175 ( 0.637206018 0.7647919655 ) 332 2 - vert 176 ( 0.665463984 0.7874619961 ) 334 1 - vert 177 ( 0.6372410059 0.7954400182 ) 335 2 - vert 178 ( 0.8433820009 0.7335389853 ) 337 2 - vert 179 ( 0.8390750289 0.7059049606 ) 339 2 - vert 180 ( 0.8256829977 0.7402650118 ) 341 2 - vert 181 ( 0.8165649772 0.7104519606 ) 343 2 - vert 182 ( 0.6244829893 0.7942379713 ) 345 2 - vert 183 ( 0.6805660129 0.7969350219 ) 347 1 - vert 184 ( 0.6240170002 0.7535859942 ) 348 2 - vert 185 ( 0.8464630246 0.6974079609 ) 350 2 - vert 186 ( 0.8393149972 0.7581170201 ) 352 2 - vert 187 ( 0.8549889922 0.7435079813 ) 354 2 - vert 188 ( 0.9178630114 0.898720026 ) 356 1 - vert 189 ( 0.7301040292 0.7203940153 ) 357 2 - vert 190 ( 0.8139719963 0.9678419828 ) 359 3 - vert 191 ( 0.6579520106 0.9384769797 ) 362 2 - vert 192 ( 0.6774749756 0.9429699779 ) 364 1 - vert 193 ( 0.9356790185 0.9765809774 ) 117 1 - vert 194 ( 0.9500700235 0.9693490267 ) 153 2 - vert 195 ( 0.4823220074 0.5735390186 ) 166 2 - vert 196 ( 0.66010499 0.9635859728 ) 365 2 - vert 197 ( 0.6375370026 0.9813799858 ) 166 2 - vert 198 ( 0.6630769968 0.9902089834 ) 203 2 - vert 199 ( 0.6758469939 0.9619219899 ) 367 2 - vert 200 ( 0.7604320049 0.3262789845 ) 369 3 - vert 201 ( 0.045008 0.4866610169 ) 372 6 - vert 202 ( 0.0144499997 0.4874190092 ) 378 5 - vert 203 ( 0.0144499997 0.5482740402 ) 383 5 - vert 204 ( 0.1096090004 0.4702090025 ) 388 6 - vert 205 ( 0.2221000046 0.5125030279 ) 394 5 - vert 206 ( 0.2316150069 0.5859429836 ) 369 3 - vert 207 ( 0.2811740041 0.5451920033 ) 399 3 - vert 208 ( 0.3673590124 0.5281560421 ) 402 3 - vert 209 ( 0.0700780004 0.5237990022 ) 405 5 - vert 210 ( 0.479162991 0.7012659907 ) 140 3 - vert 211 ( 0.7439510226 0.6670149565 ) 410 2 - vert 212 ( 0.9513220191 0.7321490049 ) 348 2 - vert 213 ( 0.9517869949 0.772800982 ) 345 2 - vert 214 ( 0.7854130268 0.3479629755 ) 412 3 - vert 215 ( 0.3016929924 0.6012629867 ) 412 3 - vert 216 ( 0.8183220029 0.3567929864 ) 415 3 - vert 217 ( 0.3644619882 0.6122540236 ) 415 3 - vert 218 ( 0.8571969867 0.3464599848 ) 418 3 - vert 219 ( 0.4147590101 0.6178449988 ) 418 3 - vert 220 ( 0.9705460072 0.7941930294 ) 220 2 - vert 221 ( 0.7130640149 0.8012939692 ) 421 1 - vert 222 ( 0.752128005 0.8113850355 ) 422 1 - vert 223 ( 0.9683570266 0.7192590237 ) 328 2 - vert 224 ( 0.6283329725 0.1382210255 ) 423 1 - vert 225 ( 0.6168709993 0.1939079762 ) 424 4 - vert 226 ( 0.683472991 0.1837890148 ) 428 1 - vert 227 ( 0.6125959754 0.0203300118 ) 429 2 - vert 228 ( 0.5890859962 0.066125989 ) 431 2 - vert 229 ( 0.6121709943 0.050327003 ) 433 1 - vert 230 ( 0.7031670213 0.0416780114 ) 434 2 - vert 231 ( 0.7551190257 0.2345799804 ) 436 2 - vert 232 ( 0.7569389939 0.2816950083 ) 438 2 - vert 233 ( 0.8039929867 0.2807109952 ) 440 1 - vert 234 ( 0.904738009 0.2190790176 ) 441 1 - vert 235 ( 0.8195909858 0.244279027 ) 442 1 - vert 236 ( 0.8801649809 0.2644550204 ) 443 1 - vert 237 ( 0.8044279814 0.2112140059 ) 444 1 - vert 238 ( 0.8326060176 0.178467989 ) 445 1 - vert 239 ( 0.758777976 0.1832640171 ) 446 2 - vert 240 ( 0.7706549764 0.1540780067 ) 448 2 - vert 241 ( 0.6641979814 0.2467070222 ) 450 1 - vert 242 ( 0.62698102 0.2509009838 ) 451 2 - vert 243 ( 0.7294849753 0.2627300024 ) 453 2 - vert 244 ( 0.6308159828 0.2862499952 ) 455 2 - vert 245 ( 0.6658639908 0.2953109741 ) 457 1 - vert 246 ( 0.7046819925 0.3103539944 ) 434 2 - vert 247 ( 0.6249740124 0.3215360045 ) 429 2 - vert 248 ( 0.7714840174 0.3000429869 ) 458 2 - vert 249 ( 0.8424509764 0.2976040244 ) 460 1 - vert 250 ( 0.6646590233 0.1127219796 ) 461 2 - vert 251 ( 0.7057800293 0.141941011 ) 463 2 - vert 252 ( 0.7708910108 0.1186720133 ) 465 2 - vert 253 ( 0.7920650244 0.1189609766 ) 467 2 - vert 254 ( 0.8484399915 0.1442059875 ) 469 1 - vert 255 ( 0.5993899703 0.1343240142 ) 470 3 - vert 256 ( 0.9828019738 0.1750059724 ) 473 2 - vert 257 ( 0.6272029877 0.0891109705 ) 475 2 - vert 258 ( 0.7672929764 0.0944049954 ) 477 2 - vert 259 ( 0.6971200109 0.0824099779 ) 479 2 - vert 260 ( 0.8447840214 0.0423269868 ) 460 1 - vert 261 ( 0.8499209881 0.0806429982 ) 481 1 - vert 262 ( 0.9695169926 0.0591560006 ) 482 2 - vert 263 ( 0.7712600231 0.0517989993 ) 458 2 - vert 264 ( 0.7898179889 0.0916860104 ) 484 2 - vert 265 ( 0.9630979896 0.239018023 ) 486 4 - vert 266 ( 0.9665970206 0.2578089833 ) 482 2 - vert 267 ( 0.8710389733 0.1096410155 ) 490 1 - vert 268 ( 0.9903659821 0.092904985 ) 491 2 - vert 269 ( 0.215068996 0.9843890071 ) 473 2 - vert 270 ( 0.1976130009 0.9519709945 ) 493 3 - vert 271 ( 0.1715629995 0.9827839732 ) 496 2 - vert 272 ( 0.9930099845 0.1282240152 ) 496 2 - vert 273 ( 0.1152990013 0.2394660115 ) 498 4 - vert 274 ( 0.0863609985 0.2128599882 ) 502 5 - vert 275 ( 0.0970619991 0.2845360041 ) 507 5 - vert 276 ( 0.050193999 0.2608619928 ) 512 5 - vert 277 ( 0.0144490004 0.295953989 ) 517 6 - vert 278 ( 0.0506610014 0.3025169969 ) 523 5 - vert 279 ( 0.0545670018 0.1862319708 ) 528 6 - vert 280 ( 0.0144490004 0.2409790158 ) 534 4 - vert 281 ( 0.1091400012 0.2066959739 ) 538 6 - vert 282 ( 0.0919760019 0.1516609788 ) 544 5 - vert 283 ( 0.0467259996 0.1174889803 ) 549 4 - vert 284 ( 0.0051540001 0.1093770266 ) 553 6 - vert 285 ( 0.0431809984 0.3530650139 ) 559 6 - vert 286 ( 0.2199179977 0.2631700039 ) 565 6 - vert 287 ( 0.1429059952 0.2838019729 ) 571 4 - vert 288 ( 0.0902210027 0.3160759807 ) 575 5 - vert 289 ( 0.1574420035 0.3197630048 ) 580 4 - vert 290 ( 0.2320220023 0.2345510125 ) 584 4 - vert 291 ( 0.1418270022 0.2262470126 ) 588 5 - vert 292 ( 0.606595993 0.2889260054 ) 593 2 - vert 293 ( 0.6034849882 0.3196939826 ) 595 2 - vert 294 ( 0.5877169967 0.2828620076 ) 597 5 - vert 295 ( 0.5869389772 0.2568969727 ) 602 4 - vert 296 ( 0.5655059814 0.2483479977 ) 606 4 - vert 297 ( 0.5764700174 0.1848019958 ) 610 3 - vert 298 ( 0.5633820295 0.1403350234 ) 613 3 - vert 299 ( 0.5865359902 0.2269070148 ) 616 3 - vert 300 ( 0.5648850203 0.2282369733 ) 619 4 - vert 301 ( 0.5545930266 0.1944239736 ) 623 3 - vert 302 ( 0.5738310218 0.3019539714 ) 626 4 - vert 303 ( 0.564504981 0.0457450151 ) 630 4 - vert 304 ( 0.542626977 0.0972859859 ) 634 3 - vert 305 ( 0.5187540054 0.0748500228 ) 637 4 - vert 306 ( 0.2118099928 0.2207630277 ) 641 4 - vert 307 ( 0.1190309972 0.1921330094 ) 645 5 - vert 308 ( 0.5583509803 0.2779840231 ) 650 4 - vert 309 ( 0.4998509884 0.1677280068 ) 654 4 - vert 310 ( 0.5417019725 0.1627069712 ) 658 3 - vert 311 ( 0.5104789734 0.1228410006 ) 661 3 - vert 312 ( 0.5533699989 0.0029299855 ) 641 4 - vert 313 ( 0.1711599976 0.2002900243 ) 650 4 - vert 314 ( 0.1470360011 0.0744979978 ) 664 3 - vert 315 ( 0.0615929998 0.0328950286 ) 667 2 - vert 316 ( 0.1151390001 0.0934939981 ) 669 3 - vert 317 ( 0.3166800141 0.0121610165 ) 672 3 - vert 318 ( 0.1398299932 0.0091909766 ) 675 2 - vert 319 ( 0.3113580048 0.0656139851 ) 677 3 - vert 320 ( 0.4395529926 0.1239839792 ) 680 5 - vert 321 ( 0.2724170089 0.1898289919 ) 637 4 - vert 322 ( 0.175751999 0.1184769869 ) 685 4 - vert 323 ( 0.1547770053 0.1485090256 ) 689 5 - vert 324 ( 0.2154349983 0.0968260169 ) 694 4 - vert 325 ( 0.2372210026 0.1265230179 ) 654 4 - vert 326 ( 0.2031159997 0.4328520298 ) 698 6 - vert 327 ( 0.1025720015 0.4367600083 ) 704 7 - vert 328 ( 0.088436 0.3515689969 ) 711 5 - vert 329 ( 0.1433719993 0.3597120047 ) 716 5 - vert 330 ( 0.2372799963 0.3046429753 ) 721 4 - vert 331 ( 0.0940710008 0.3845310211 ) 725 6 - vert 332 ( 0.2239650041 0.3851090074 ) 731 3 - vert 333 ( 0.1400510073 0.3962470293 ) 734 7 - vert 334 ( 0.0479080006 0.4352710247 ) 741 5 - vert 335 ( 0.3146969974 0.3020730019 ) 746 4 - vert 336 ( 0.3045719862 0.3410009742 ) 750 3 - vert 337 ( 0.2845790088 0.2492619753 ) 753 7 - vert 338 ( 0.3328540027 0.2181609869 ) 760 6 - vert 339 ( 0.314891994 0.1592360139 ) 766 5 - vert 340 ( 0.3898859918 0.2495729923 ) 771 4 - vert 341 ( 0.382788986 0.3152559996 ) 775 3 - vert 342 ( 0.38756001 0.3619350195 ) 778 3 - vert 343 ( 0.3108879924 0.3810989857 ) 781 3 - vert 344 ( 0.3877089918 0.3966420293 ) 784 3 - vert 345 ( 0.3141449988 0.4216560125 ) 787 5 - vert 346 ( 0.4661200047 0.3686410189 ) 792 3 - vert 347 ( 0.4661200047 0.4262840152 ) 795 3 - vert 348 ( 0.2676410079 0.1396930218 ) 661 3 - vert 349 ( 0.3561750054 0.1170480251 ) 798 4 - vert 350 ( 0.2901819944 0.0998780131 ) 802 4 - vert 351 ( 0.3838919997 0.182238996 ) 806 5 - vert 352 ( 0.4661209881 0.257569015 ) 811 4 - vert 353 ( 0.2923490107 0.8225120306 ) 815 2 - vert 354 ( 0.3045459986 0.8816969991 ) 817 2 - vert 355 ( 0.3036420047 0.8439320326 ) 819 2 - vert 356 ( 0.0271990001 0.9255689979 ) 821 2 - vert 357 ( 0.0832609981 0.8998079896 ) 823 2 - vert 358 ( 0.0478839986 0.8890889883 ) 819 2 - vert 359 ( 0.2780280113 0.8239219785 ) 825 1 - vert 360 ( 0.0475389995 0.8193119764 ) 815 2 - vert 361 ( 0.0800030008 0.9541890025 ) 826 2 - vert 362 ( 0.1438030005 0.9564689994 ) 828 2 - vert 363 ( 0.0917820036 0.7941440344 ) 830 3 - vert 364 ( 0.057542 0.7730209827 ) 833 2 - vert 365 ( 0.0776230022 0.765789032 ) 835 1 - vert 366 ( 0.2972910106 0.7825210094 ) 833 2 - vert 367 ( 0.3002749979 0.7235380411 ) 836 1 - vert 368 ( 0.2925649881 0.701892972 ) 837 1 - vert 369 ( 0.0538810007 0.7322390079 ) 836 1 - vert 370 ( 0.0726670027 0.7271280289 ) 838 1 - vert 371 ( 0.217415005 0.7201030254 ) 839 1 - vert 372 ( 0.2404790074 0.7582719922 ) 840 2 - vert 373 ( 0.2321060002 0.6934329867 ) 842 1 - vert 374 ( 0.1714880019 0.9409120083 ) 843 2 - vert 375 ( 0.1657840014 0.8238919973 ) 845 2 - vert 376 ( 0.1661269963 0.7374539971 ) 847 1 - vert 377 ( 0.1361680031 0.7035570145 ) 848 1 - vert 378 ( 0.1116200015 0.7094349861 ) 842 1 - vert 379 ( 0.1794739962 0.7557600141 ) 849 1 - vert 380 ( 0.1862290055 0.7284799814 ) 847 1 - vert 381 ( 0.2092670053 0.6920809746 ) 848 1 - vert 382 ( 0.1823309958 0.7916759849 ) 850 3 - vert 383 ( 0.2291419953 0.7784619927 ) 853 2 - vert 384 ( 0.1885060072 0.8311809897 ) 855 2 - vert 385 ( 0.1653030068 0.7876700163 ) 857 3 - vert 386 ( 0.2847729921 0.7783129811 ) 860 1 - vert 387 ( 0.2481109947 0.9555810094 ) 861 3 - vert 388 ( 0.2406370044 0.8281059861 ) 864 2 - vert 389 ( 0.3158220053 0.8284180164 ) 866 1 - vert 390 ( 0.3360300064 0.8354139924 ) 867 1 - vert 391 ( 0.3389669955 0.7906399965 ) 868 1 - vert 392 ( 0.3230530024 0.8860020041 ) 869 2 - vert 393 ( 0.3546899855 0.8408119678 ) 871 1 - vert 394 ( 0.3211889863 0.7955060005 ) 872 1 - vert 395 ( 0.3039030135 0.8155750036 ) 873 1 - vert 396 ( 0.0241 0.8529819846 ) 872 1 - vert 397 ( 0.0145960003 0.8405250311 ) 868 1 - vert 398 ( 0.0097120004 0.8619620204 ) 874 1 - vert 399 ( 0.289786011 0.9455879927 ) 875 4 - vert 400 ( 0.3157379925 0.9510989785 ) 879 3 - vert 401 ( 0.3311930001 0.950553 ) 826 2 - vert 402 ( 0.3410930037 0.8898659945 ) 821 2 - vert 403 ( 0.0116870003 0.8967059851 ) 871 1 - vert 404 ( 0.0322140008 0.8826919794 ) 873 1 - vert 405 ( 0.2506859899 0.7730770111 ) 835 1 - vert 406 ( 0.2657620013 0.7761859894 ) 882 1 - vert 407 ( 0.2609750032 0.7021399736 ) 838 1 - vert 408 ( 0.275142014 0.6999319792 ) 883 1 - vert 409 ( 0.2569510043 0.8298720121 ) 884 1 - vert 410 ( 0.2481950074 0.7962459922 ) 830 3 - vert 411 ( 0.0716580003 0.708476007 ) 883 1 - vert 412 ( 0.0523359999 0.7139970064 ) 837 1 - vert 413 ( 0.2791419923 0.7353919744 ) 885 1 - vert 414 ( 0.1007810012 0.7519800067 ) 840 2 - vert 415 ( 0.3528630137 0.7947610021 ) 874 1 - vert 416 ( 0.0144499997 0.4357699752 ) 886 7 - vert 417 ( 0.0144499997 0.3580049872 ) 893 6 - vert 418 ( 0.4073280096 0.4359210134 ) 899 4 - vert 419 ( 0.225236997 0.3506410122 ) 903 4 - vert 420 ( 0.3852880001 0.6363370419 ) 907 2 - vert 421 ( 0.3768070042 0.7744669914 ) 909 2 - vert 422 ( 0.3974719942 0.7476450205 ) 911 4 - vert 423 ( 0.4024690092 0.6662579775 ) 549 4 - vert 424 ( 0.4091559947 0.7077040076 ) 553 6 - vert 425 ( 0.4661209881 0.3191949725 ) 915 3 - vert 426 ( 0.0489920005 0.3879129887 ) 918 5 - vert 427 ( 0.0144499997 0.396295011 ) 923 6 - vert 428 ( 0.076839 0.0960199833 ) 907 2 - vert 429 ( 0.209296003 0.0652779937 ) 929 3 - vert 430 ( 0.5899009705 0.0043249726 ) 595 2 - vert 431 ( 0.5699959993 0.3181679845 ) 641 4 - vert 432 ( 0.1929699928 0.2089939713 ) 626 4 - vert 433 ( 0.1509580016 0.9813879728 ) 491 2 - vert 434 ( 0.2905550003 0.9849680066 ) 486 4 - vert 435 ( 0.112703003 0.987383008 ) 482 2 - vert 436 ( 0.3311130106 0.9791690111 ) 482 2 - vert 437 ( 0.9655780196 0.2199130058 ) 932 2 - vert 438 ( 0.2565110028 0.9873960018 ) 932 2 - vert 439 ( 0.5089240074 0.2117750049 ) 934 4 - vert 440 ( 0.4701620042 0.2312800288 ) 685 4 - vert 441 ( 0.5303670168 0.248142004 ) 938 4 - vert 442 ( 0.4859330058 0.2575619817 ) 689 5 - vert 443 ( 0.0537559986 0.5374909639 ) 942 4 - vert 444 ( 0.0977229998 0.5801950097 ) 946 4 - vert 445 ( 0.0802640021 0.5959489942 ) 950 4 - vert 446 ( 0.1559260041 0.5936200023 ) 954 4 - vert 447 ( 0.4001519978 0.5009070039 ) 958 4 - vert 448 ( 0.4229629934 0.544252038 ) 962 4 - vert 449 ( 0.4140479863 0.5756520033 ) 966 3 - vert 450 ( 0.4263139963 0.4909489751 ) 969 4 - vert 451 ( 0.408953011 0.450691998 ) 973 4 - vert 452 ( 0.3492470086 0.4542539716 ) 977 5 - vert 453 ( 0.3593429923 0.5024729967 ) 982 4 - vert 454 ( 0.2927339971 0.5144959688 ) 986 4 - vert 455 ( 0.2438160032 0.4694390297 ) 990 5 - vert 456 ( 0.126861006 0.5218789577 ) 995 5 - vert 457 ( 0.501330018 0.833065033 ) 1000 4 - vert 458 ( 0.4875909984 0.7850450277 ) 1004 4 - vert 459 ( 0.5321450233 0.7971050143 ) 1008 4 - vert 460 ( 0.527493 0.7104359865 ) 1012 3 - vert 461 ( 0.5338050127 0.3161150217 ) 1015 2 - vert 462 ( 0.4898490012 0.3308830261 ) 1017 2 - vert 463 ( 0.4741660058 0.3951740265 ) 1019 3 - vert 464 ( 0.4595679939 0.8330010176 ) 1022 3 - vert 465 ( 0.4992260039 0.4821460247 ) 1025 3 - vert 466 ( 0.589910984 0.3965389729 ) 1028 2 - vert 467 ( 0.5716040134 0.4827600121 ) 1030 3 - vert 468 ( 0.5081449747 0.5488619804 ) 1033 3 - vert 469 ( 0.5639020205 0.5490509868 ) 1036 3 - vert 470 ( 0.4862830043 0.4918850064 ) 1039 3 - vert 471 ( 0.5829150081 0.4924759865 ) 1042 3 - vert 472 ( 0.4733340144 0.6302369833 ) 1045 1 - vert 473 ( 0.5190560222 0.5774669647 ) 1046 2 - vert 474 ( 0.5112810135 0.6217579842 ) 1048 2 - vert 475 ( 0.5955759883 0.6822559834 ) 1025 3 - vert 476 ( 0.609070003 0.7593790293 ) 1019 3 - vert 477 ( 0.5241159797 0.67513901 ) 1050 2 - vert 478 ( 0.6185759902 0.6687619686 ) 1039 3 - vert 479 ( 0.5599139929 0.8966199756 ) 1015 2 - vert 480 ( 0.5494279861 0.8385199904 ) 1052 2 - vert 481 ( 0.5910789967 0.8339700103 ) 1017 2 - vert 482 ( 0.8535649776 0.9448459744 ) 1054 1 - vert 483 ( 0.8919839859 0.9213370085 ) 1055 1 - vert 484 ( 0.8781870008 0.9453350306 ) 1056 1 - vert 485 ( 0.924405992 0.9283440113 ) 1057 1 - vert 486 ( 0.9422659874 0.9171689749 ) 1058 1 - vert 487 ( 0.934664011 0.9610649943 ) 1059 1 - vert 488 ( 0.7117850184 0.9155640006 ) 1060 1 - vert 489 ( 0.7713090181 0.9185889959 ) 1061 1 - vert 490 ( 0.7216209769 0.9516559839 ) 1062 1 - vert 491 ( 0.8553580046 0.9746490121 ) 1063 3 - vert 492 ( 0.8787090182 0.9745879769 ) 1066 3 - vert 493 ( 0.9055380225 0.9909920096 ) 1069 1 - vert 494 ( 0.8473979831 0.9899860024 ) 1070 3 - vert 495 ( 0.4794029891 0.6629630327 ) 1069 1 - vert 496 ( 0.7605239749 0.9580150247 ) 1073 1 - vert 497 ( 0.74416399 0.9722880125 ) 1074 1 - vert 498 ( 0.4427919984 0.7468309999 ) 1074 1 - vert 499 ( 0.4337419868 0.8579019904 ) 1075 3 - vert 500 ( 0.4850060046 0.8799200058 ) 1078 3 - vert 501 ( 0.523778975 0.8859429955 ) 1081 2 - vert 502 ( 0.4716799855 0.6076129675 ) 1083 2 - vert 503 ( 0.3988110125 0.8936679959 ) 1085 3 - vert 504 ( 0.4075230062 0.9607509971 ) 1030 3 - vert 505 ( 0.394347012 0.9896720052 ) 1042 3 - vert 506 ( 0.3550690114 0.875962019 ) 1046 2 - vert 507 ( 0.3526349962 0.9818210006 ) 1036 3 - vert 508 ( 0.6151559949 0.5710170269 ) 1036 3 - vert 509 ( 0.6058449745 0.6210620403 ) 1033 3 - vert 510 ( 0.5195450187 0.9315680265 ) 1088 2 - vert 511 ( 0.4597109854 0.9573209882 ) 1028 2 - vert 512 ( 0.6479740143 0.9120259881 ) 1090 1 - vert 513 ( 0.666786015 0.9181720018 ) 1091 1 - vert 514 ( 0.6379150152 0.9437299967 ) 1092 2 - vert 515 ( 0.9726229906 0.9240419865 ) 1092 2 - vert 516 ( 0.9495090246 0.9532920122 ) 1094 2 - vert 517 ( 0.9721109867 0.9635840058 ) 1096 2 - vert 518 ( 0.9396569729 0.8899279833 ) 1098 1 - vert 519 ( 0.978546977 0.8670679927 ) 1099 1 - vert 520 ( 0.9408730268 0.874285996 ) 1100 1 - vert 521 ( 0.7650160193 0.7246769667 ) 1101 2 - vert 522 ( 0.8010870218 0.711452961 ) 1103 2 - vert 523 ( 0.8155189753 0.7483010292 ) 1105 2 - vert 524 ( 0.9123610258 0.9656270146 ) 1107 1 - vert 525 ( 0.752530992 0.7550070286 ) 1108 2 - vert 526 ( 0.8066300154 0.7665590048 ) 1110 2 - vert 527 ( 0.7681649923 0.7735170126 ) 1112 2 - vert 528 ( 0.7297629714 0.7690969706 ) 1114 2 - vert 529 ( 0.6955400109 0.7595160007 ) 1116 2 - vert 530 ( 0.8301010132 0.9127190113 ) 1118 1 - vert 531 ( 0.8408420086 0.9305070043 ) 1119 1 - vert 532 ( 0.6772639751 0.9037290215 ) 1120 1 - vert 533 ( 0.6432170272 0.8894940019 ) 1099 1 - vert 534 ( 0.678704977 0.8685560226 ) 1121 1 - vert 535 ( 0.7100189924 0.6072689891 ) 1122 1 - vert 536 ( 0.7579299808 0.6115549803 ) 1123 2 - vert 537 ( 0.7244579792 0.6272779703 ) 1125 1 - vert 538 ( 0.7032920122 0.670502007 ) 1126 2 - vert 539 ( 0.7287060022 0.6930609941 ) 1128 2 - vert 540 ( 0.759378016 0.6292409897 ) 1130 2 - vert 541 ( 0.7155330181 0.9671120048 ) 1132 1 - vert 542 ( 0.4258460104 0.7753620148 ) 1132 1 - vert 543 ( 0.3732529879 0.8241159916 ) 1096 2 - vert 544 ( 0.4041680098 0.8348730206 ) 1133 2 - vert 545 ( 0.8732990026 0.8482810259 ) 1135 1 - vert 546 ( 0.9038299918 0.8346620202 ) 1136 1 - vert 547 ( 0.9140599966 0.8845689893 ) 1137 1 - vert 548 ( 0.8934400082 0.8897830248 ) 1138 1 - vert 549 ( 0.865835011 0.7806869745 ) 1139 2 - vert 550 ( 0.8858129978 0.7430869937 ) 1141 2 - vert 551 ( 0.9011470079 0.8023619652 ) 1143 1 - vert 552 ( 0.8329390287 0.8720459938 ) 1144 1 - vert 553 ( 0.9279770255 0.8277959824 ) 1145 1 - vert 554 ( 0.9532859921 0.8276849985 ) 1146 1 - vert 555 ( 0.9159590006 0.7293330431 ) 1147 2 - vert 556 ( 0.9224870205 0.794788003 ) 1149 1 - vert 557 ( 0.6259819865 0.8491230011 ) 1146 1 - vert 558 ( 0.6432409883 0.815631032 ) 1150 2 - vert 559 ( 0.7726150155 0.9083110094 ) 1152 1 - vert 560 ( 0.7819550037 0.861676991 ) 1153 1 - vert 561 ( 0.7129809856 0.9011930227 ) 1154 1 - vert 562 ( 0.7129340172 0.8587610126 ) 1155 1 - vert 563 ( 0.7923910022 0.8011859655 ) 1156 2 - vert 564 ( 0.7988709807 0.6290609837 ) 1158 2 - vert 565 ( 0.8403609991 0.650011003 ) 1160 2 - vert 566 ( 0.8054479957 0.6605190039 ) 1162 2 - vert 567 ( 0.93551898 0.5865709782 ) 1164 3 - vert 568 ( 0.988041997 0.518945992 ) 1167 2 - vert 569 ( 0.9685389996 0.6313810349 ) 1169 2 - vert 570 ( 0.8923829794 0.6343989968 ) 1171 2 - vert 571 ( 0.8554819822 0.6791859865 ) 1173 2 - vert 572 ( 0.9029909968 0.6752110124 ) 1175 2 - vert 573 ( 0.8880580068 0.5439299941 ) 1177 2 - vert 574 ( 0.8512319922 0.5821909904 ) 1179 1 - vert 575 ( 0.8218709826 0.6916069984 ) 1180 2 - vert 576 ( 0.7669389844 0.6977820396 ) 1182 2 - vert 577 ( 0.7575719953 0.5729500055 ) 1184 2 - vert 578 ( 0.7972249985 0.5779629946 ) 1186 2 - vert 579 ( 0.8024590015 0.4328410029 ) 1188 1 - vert 580 ( 0.7664840221 0.4008550048 ) 1189 3 - vert 581 ( 0.6906639934 0.3498520255 ) 1192 4 - vert 582 ( 0.7135609984 0.3225979805 ) 1196 4 - vert 583 ( 0.7104619741 0.4436630011 ) 1200 3 - vert 584 ( 0.0956069976 0.6785979867 ) 1203 4 - vert 585 ( 0.1579069942 0.6584489942 ) 1207 3 - vert 586 ( 0.424800992 0.6525709629 ) 1210 3 - vert 587 ( 0.6540570259 0.5408209562 ) 1167 2 - vert 588 ( 0.6677730083 0.3816210032 ) 1207 3 - vert 589 ( 0.9014589787 0.366820991 ) 1210 3 - vert 590 ( 0.7350249887 0.3181409836 ) 954 4 - vert 591 ( 0.8507739902 0.4169740081 ) 1213 3 - vert 592 ( 0.1047040001 0.6168589592 ) 1196 4 - vert 593 ( 0.0672969967 0.6261379719 ) 1216 4 - vert 594 ( 0.1065910012 0.6443859935 ) 1192 4 - vert 595 ( 0.9332659841 0.6750910282 ) 1220 2 - vert 596 ( 0.8840469718 0.709939003 ) 1222 2 - vert 597 ( 0.9193720222 0.7085800171 ) 1224 2 - vert 598 ( 0.8601080179 0.7186459899 ) 1226 2 - vert 599 ( 0.6159399748 0.695874989 ) 1220 2 - vert 600 ( 0.6837400198 0.6937539577 ) 1228 2 - vert 601 ( 0.641053021 0.740696013 ) 1230 2 - vert 602 ( 0.6345549822 0.6532559991 ) 1169 2 - vert 603 ( 0.5808050036 0.3401960135 ) 1088 2 - vert 604 ( 0.637206018 0.7647919655 ) 1232 2 - vert 605 ( 0.6575149894 0.7567790151 ) 1234 2 - vert 606 ( 0.665463984 0.7874619961 ) 1236 1 - vert 607 ( 0.6372410059 0.7954400182 ) 1237 2 - vert 608 ( 0.8390750289 0.7059049606 ) 1239 2 - vert 609 ( 0.8433820009 0.7335389853 ) 1241 2 - vert 610 ( 0.8256829977 0.7402650118 ) 1243 2 - vert 611 ( 0.8165649772 0.7104519606 ) 1245 2 - vert 612 ( 0.6244829893 0.7942379713 ) 1247 2 - vert 613 ( 0.6805660129 0.7969350219 ) 1249 1 - vert 614 ( 0.6240170002 0.7535859942 ) 1250 2 - vert 615 ( 0.8464630246 0.6974079609 ) 1252 2 - vert 616 ( 0.8393149972 0.7581170201 ) 1254 2 - vert 617 ( 0.8549889922 0.7435079813 ) 1256 2 - vert 618 ( 0.9178630114 0.898720026 ) 1258 1 - vert 619 ( 0.7301040292 0.7203940153 ) 1259 2 - vert 620 ( 0.8139719963 0.9678419828 ) 1261 3 - vert 621 ( 0.6579520106 0.9384769797 ) 1264 2 - vert 622 ( 0.6774749756 0.9429699779 ) 1266 1 - vert 623 ( 0.9356790185 0.9765809774 ) 1045 1 - vert 624 ( 0.9500700235 0.9693490267 ) 1083 2 - vert 625 ( 0.4823220074 0.5735390186 ) 1096 2 - vert 626 ( 0.6375370026 0.9813799858 ) 1096 2 - vert 627 ( 0.66010499 0.9635859728 ) 1267 2 - vert 628 ( 0.6630769968 0.9902089834 ) 1133 2 - vert 629 ( 0.6758469939 0.9619219899 ) 1269 2 - vert 630 ( 0.7604320049 0.3262789845 ) 1271 3 - vert 631 ( 0.0449980013 0.4866619706 ) 1274 6 - vert 632 ( 0.1095969975 0.4702100158 ) 1280 6 - vert 633 ( 0.2220849991 0.5125039816 ) 1286 5 - vert 634 ( 0.2315990031 0.5859439969 ) 1271 3 - vert 635 ( 0.2811610103 0.5451929569 ) 1291 3 - vert 636 ( 0.3673500121 0.5281569958 ) 1294 3 - vert 637 ( 0.0700670034 0.5237990022 ) 1297 5 - vert 638 ( 0.479162991 0.7012659907 ) 1070 3 - vert 639 ( 0.7439510226 0.6670149565 ) 1302 2 - vert 640 ( 0.9513220191 0.7321490049 ) 1250 2 - vert 641 ( 0.9517869949 0.772800982 ) 1247 2 - vert 642 ( 0.7854130268 0.3479629755 ) 1304 3 - vert 643 ( 0.3016810119 0.6012650132 ) 1304 3 - vert 644 ( 0.8183220029 0.3567929864 ) 1307 3 - vert 645 ( 0.3644540012 0.6122549772 ) 1307 3 - vert 646 ( 0.8571969867 0.3464599848 ) 1310 3 - vert 647 ( 0.41475299 0.6178460121 ) 1310 3 - vert 648 ( 0.9705460072 0.7941930294 ) 1150 2 - vert 649 ( 0.7130640149 0.8012939692 ) 1313 1 - vert 650 ( 0.752128005 0.8113850355 ) 1314 1 - vert 651 ( 0.9683570266 0.7192590237 ) 1230 2 - vert 652 ( 0.6168709993 0.1939079762 ) 1315 4 - vert 653 ( 0.6283329725 0.1382210255 ) 1319 1 - vert 654 ( 0.683472991 0.1837890148 ) 1320 1 - vert 655 ( 0.5890859962 0.066125989 ) 1321 2 - vert 656 ( 0.6125959754 0.0203300118 ) 1323 2 - vert 657 ( 0.6121709943 0.050327003 ) 1325 1 - vert 658 ( 0.7031670213 0.0416780114 ) 1326 2 - vert 659 ( 0.7569389939 0.2816950083 ) 1328 2 - vert 660 ( 0.7551190257 0.2345799804 ) 1330 2 - vert 661 ( 0.8039929867 0.2807109952 ) 1332 1 - vert 662 ( 0.8195909858 0.244279027 ) 1333 1 - vert 663 ( 0.904738009 0.2190790176 ) 1334 1 - vert 664 ( 0.8801649809 0.2644550204 ) 1335 1 - vert 665 ( 0.8044279814 0.2112140059 ) 1336 1 - vert 666 ( 0.8326060176 0.178467989 ) 1337 1 - vert 667 ( 0.758777976 0.1832640171 ) 1338 2 - vert 668 ( 0.7706549764 0.1540780067 ) 1340 2 - vert 669 ( 0.6641979814 0.2467070222 ) 1342 2 - vert 670 ( 0.62698102 0.2509009838 ) 1344 2 - vert 671 ( 0.7294849753 0.2627300024 ) 1346 2 - vert 672 ( 0.6308159828 0.2862499952 ) 1348 2 - vert 673 ( 0.6658639908 0.2953109741 ) 1350 1 - vert 674 ( 0.7046819925 0.3103539944 ) 1326 2 - vert 675 ( 0.6249740124 0.3215360045 ) 1323 2 - vert 676 ( 0.7714840174 0.3000429869 ) 1351 2 - vert 677 ( 0.8424509764 0.2976040244 ) 1353 1 - vert 678 ( 0.7057800293 0.141941011 ) 1354 2 - vert 679 ( 0.6646590233 0.1127219796 ) 1356 2 - vert 680 ( 0.7708910108 0.1186720133 ) 1358 2 - vert 681 ( 0.7920650244 0.1189609766 ) 1360 2 - vert 682 ( 0.8484399915 0.1442059875 ) 1362 1 - vert 683 ( 0.5993899703 0.1343240142 ) 1363 3 - vert 684 ( 0.9828019738 0.1750059724 ) 1366 2 - vert 685 ( 0.6272029877 0.0891109705 ) 1368 2 - vert 686 ( 0.7672929764 0.0944049954 ) 1370 2 - vert 687 ( 0.6971200109 0.0824099779 ) 1372 2 - vert 688 ( 0.8499209881 0.0806429982 ) 1374 1 - vert 689 ( 0.8447840214 0.0423269868 ) 1353 1 - vert 690 ( 0.9695169926 0.0591560006 ) 1375 2 - vert 691 ( 0.7898179889 0.0916860104 ) 1377 2 - vert 692 ( 0.7712600231 0.0517989993 ) 1351 2 - vert 693 ( 0.9630979896 0.239018023 ) 1379 3 - vert 694 ( 0.9665970206 0.2578089833 ) 1375 2 - vert 695 ( 0.8710389733 0.1096410155 ) 1382 1 - vert 696 ( 0.9903659821 0.092904985 ) 1383 2 - vert 697 ( 0.1976130009 0.9519709945 ) 1385 3 - vert 698 ( 0.215068996 0.9843890071 ) 1366 2 - vert 699 ( 0.1715629995 0.9827839732 ) 1388 2 - vert 700 ( 0.9930099845 0.1282240152 ) 1388 2 - vert 701 ( 0.0863519982 0.2128610015 ) 1390 5 - vert 702 ( 0.1152879968 0.2394670248 ) 1395 4 - vert 703 ( 0.0970520005 0.2845370173 ) 1399 5 - vert 704 ( 0.0501849987 0.2608630061 ) 1404 5 - vert 705 ( 0.0506520011 0.3025180101 ) 1409 5 - vert 706 ( 0.0545589998 0.1862329841 ) 1414 5 - vert 707 ( 0.1091289967 0.2066969872 ) 1419 6 - vert 708 ( 0.0919670016 0.1516619921 ) 1425 5 - vert 709 ( 0.0467189997 0.1174899936 ) 911 4 - vert 710 ( 0.0431720018 0.3530650139 ) 1430 5 - vert 711 ( 0.2199030071 0.2631719708 ) 1435 5 - vert 712 ( 0.1428939998 0.2838039994 ) 1440 4 - vert 713 ( 0.0902109966 0.3160769939 ) 1444 5 - vert 714 ( 0.1574289948 0.3197640181 ) 1449 4 - vert 715 ( 0.1418150067 0.2262480259 ) 1453 5 - vert 716 ( 0.2320069969 0.2345520258 ) 1458 4 - vert 717 ( 0.606595993 0.2889260054 ) 1462 2 - vert 718 ( 0.6034849882 0.3196939826 ) 1464 2 - vert 719 ( 0.5877169967 0.2828620076 ) 1466 4 - vert 720 ( 0.5869389772 0.2568969727 ) 1470 4 - vert 721 ( 0.5655059814 0.2483479977 ) 1474 4 - vert 722 ( 0.5764700174 0.1848019958 ) 1478 3 - vert 723 ( 0.5633820295 0.1403350234 ) 1481 3 - vert 724 ( 0.5865359902 0.2269070148 ) 1484 4 - vert 725 ( 0.5648850203 0.2282369733 ) 1488 4 - vert 726 ( 0.5545930266 0.1944239736 ) 1492 4 - vert 727 ( 0.5738310218 0.3019539714 ) 1496 4 - vert 728 ( 0.542626977 0.0972859859 ) 1500 3 - vert 729 ( 0.564504981 0.0457450151 ) 1503 4 - vert 730 ( 0.5187540054 0.0748500228 ) 1507 4 - vert 731 ( 0.2117999941 0.2207649946 ) 1511 4 - vert 732 ( 0.1190200001 0.1921340227 ) 1515 5 - vert 733 ( 0.5583509803 0.2779840231 ) 1520 4 - vert 734 ( 0.5417019725 0.1627069712 ) 1524 4 - vert 735 ( 0.4998509884 0.1677280068 ) 1528 4 - vert 736 ( 0.5104789734 0.1228410006 ) 1532 3 - vert 737 ( 0.5533699989 0.0029299855 ) 1511 4 - vert 738 ( 0.1711509973 0.2002919912 ) 1520 4 - vert 739 ( 0.0615790002 0.0328959823 ) 1535 2 - vert 740 ( 0.147025004 0.074499011 ) 1537 3 - vert 741 ( 0.1151290014 0.0934950113 ) 1540 3 - vert 742 ( 0.1398169994 0.0091919899 ) 1543 2 - vert 743 ( 0.3113279939 0.0656160116 ) 1545 3 - vert 744 ( 0.2724060118 0.1898310184 ) 1507 4 - vert 745 ( 0.1757439971 0.1184780002 ) 1548 3 - vert 746 ( 0.1547700018 0.1485099792 ) 1551 4 - vert 747 ( 0.2154199928 0.0968269706 ) 1555 4 - vert 748 ( 0.2372100055 0.1265249848 ) 1528 4 - vert 749 ( 0.2030999959 0.4328529835 ) 1559 6 - vert 750 ( 0.1025599986 0.4367610216 ) 1565 7 - vert 751 ( 0.0884260014 0.3515700102 ) 1572 5 - vert 752 ( 0.1433590055 0.3597130179 ) 1577 5 - vert 753 ( 0.2372650057 0.3046439886 ) 1582 4 - vert 754 ( 0.0940599963 0.3845319748 ) 1586 6 - vert 755 ( 0.2239490002 0.3851100206 ) 1592 3 - vert 756 ( 0.1400379986 0.396247983 ) 1595 7 - vert 757 ( 0.0478979982 0.4352710247 ) 1602 6 - vert 758 ( 0.3146849871 0.3020740151 ) 1608 4 - vert 759 ( 0.3045589924 0.3410019875 ) 1612 3 - vert 760 ( 0.2845659852 0.2492629886 ) 1615 7 - vert 761 ( 0.3328419924 0.2181620002 ) 1622 6 - vert 762 ( 0.3148790002 0.1592370272 ) 1628 5 - vert 763 ( 0.389876008 0.2495740056 ) 1633 4 - vert 764 ( 0.3827790022 0.3152570128 ) 1637 3 - vert 765 ( 0.3875510097 0.3619359732 ) 1640 3 - vert 766 ( 0.3108749986 0.381099999 ) 1643 3 - vert 767 ( 0.3876999915 0.3966420293 ) 1646 3 - vert 768 ( 0.3141329885 0.4216579795 ) 1649 5 - vert 769 ( 0.2676300108 0.1396939754 ) 1532 3 - vert 770 ( 0.2901690006 0.0998790264 ) 1654 4 - vert 771 ( 0.3561620116 0.1170489788 ) 1658 5 - vert 772 ( 0.3838810027 0.182238996 ) 1663 5 - vert 773 ( 0.3045459986 0.8816969991 ) 1668 2 - vert 774 ( 0.2923490107 0.8225120306 ) 1670 2 - vert 775 ( 0.3036420047 0.8439320326 ) 1672 2 - vert 776 ( 0.0832609981 0.8998079896 ) 1674 2 - vert 777 ( 0.0271990001 0.9255689979 ) 1676 2 - vert 778 ( 0.0478839986 0.8890889883 ) 1672 2 - vert 779 ( 0.2780280113 0.8239219785 ) 1678 1 - vert 780 ( 0.0475389995 0.8193119764 ) 1670 2 - vert 781 ( 0.1438030005 0.9564689994 ) 1679 2 - vert 782 ( 0.0800030008 0.9541890025 ) 1681 2 - vert 783 ( 0.0917820036 0.7941440344 ) 1683 3 - vert 784 ( 0.057542 0.7730209827 ) 1686 2 - vert 785 ( 0.0776230022 0.765789032 ) 1688 1 - vert 786 ( 0.3002749979 0.7235380411 ) 1689 1 - vert 787 ( 0.2972910106 0.7825210094 ) 1686 2 - vert 788 ( 0.2925649881 0.701892972 ) 1690 1 - vert 789 ( 0.0538810007 0.7322390079 ) 1689 1 - vert 790 ( 0.0726670027 0.7271280289 ) 1691 1 - vert 791 ( 0.2404790074 0.7582719922 ) 1692 2 - vert 792 ( 0.217415005 0.7201030254 ) 1694 1 - vert 793 ( 0.2321060002 0.6934329867 ) 1695 1 - vert 794 ( 0.1714880019 0.9409120083 ) 1696 2 - vert 795 ( 0.1657840014 0.8238919973 ) 1698 2 - vert 796 ( 0.1361680031 0.7035570145 ) 1700 1 - vert 797 ( 0.1661269963 0.7374539971 ) 1701 1 - vert 798 ( 0.1116200015 0.7094349861 ) 1695 1 - vert 799 ( 0.1794739962 0.7557600141 ) 1702 1 - vert 800 ( 0.1862290055 0.7284799814 ) 1701 1 - vert 801 ( 0.2092670053 0.6920809746 ) 1700 1 - vert 802 ( 0.1823309958 0.7916759849 ) 1703 3 - vert 803 ( 0.2291419953 0.7784619927 ) 1706 2 - vert 804 ( 0.1885060072 0.8311809897 ) 1708 2 - vert 805 ( 0.1653030068 0.7876700163 ) 1710 3 - vert 806 ( 0.2847729921 0.7783129811 ) 1713 1 - vert 807 ( 0.2481109947 0.9555810094 ) 1714 3 - vert 808 ( 0.2406370044 0.8281059861 ) 1717 2 - vert 809 ( 0.3360300064 0.8354139924 ) 1719 1 - vert 810 ( 0.3158220053 0.8284180164 ) 1720 1 - vert 811 ( 0.3389669955 0.7906399965 ) 1721 1 - vert 812 ( 0.3230530024 0.8860020041 ) 1722 2 - vert 813 ( 0.3546899855 0.8408119678 ) 1724 1 - vert 814 ( 0.3211889863 0.7955060005 ) 1725 1 - vert 815 ( 0.3039030135 0.8155750036 ) 1726 1 - vert 816 ( 0.0145960003 0.8405250311 ) 1721 1 - vert 817 ( 0.0241 0.8529819846 ) 1725 1 - vert 818 ( 0.0097120004 0.8619620204 ) 1727 1 - vert 819 ( 0.289786011 0.9455879927 ) 1728 3 - vert 820 ( 0.3311930001 0.950553 ) 1681 2 - vert 821 ( 0.3157379925 0.9510989785 ) 1731 3 - vert 822 ( 0.3410930037 0.8898659945 ) 1676 2 - vert 823 ( 0.0116870003 0.8967059851 ) 1724 1 - vert 824 ( 0.0322140008 0.8826919794 ) 1726 1 - vert 825 ( 0.2657620013 0.7761859894 ) 1734 1 - vert 826 ( 0.2506859899 0.7730770111 ) 1688 1 - vert 827 ( 0.2609750032 0.7021399736 ) 1691 1 - vert 828 ( 0.275142014 0.6999319792 ) 1735 1 - vert 829 ( 0.2569510043 0.8298720121 ) 1736 1 - vert 830 ( 0.2481950074 0.7962459922 ) 1683 3 - vert 831 ( 0.0716580003 0.708476007 ) 1735 1 - vert 832 ( 0.0523359999 0.7139970064 ) 1690 1 - vert 833 ( 0.2791419923 0.7353919744 ) 1737 1 - vert 834 ( 0.1007810012 0.7519800067 ) 1692 2 - vert 835 ( 0.3528630137 0.7947610021 ) 1727 1 - vert 836 ( 0.4073199928 0.4359210134 ) 1738 4 - vert 837 ( 0.2252209932 0.3506429791 ) 1742 4 - vert 838 ( 0.3176499903 0.7588160038 ) 1543 2 - vert 839 ( 0.3248110116 0.6421890259 ) 675 2 - vert 840 ( 0.3065010011 0.6992959976 ) 672 3 - vert 841 ( 0.3443560004 0.7844359875 ) 1535 2 - vert 842 ( 0.3543800116 0.621178031 ) 667 2 - vert 843 ( 0.0489830002 0.3879129887 ) 1746 5 - vert 844 ( 0.0768319964 0.0960209966 ) 909 2 - vert 845 ( 0.2092819959 0.065279007 ) 1751 3 - vert 846 ( 0.5899009705 0.0043249726 ) 1464 2 - vert 847 ( 0.5699959993 0.3181679845 ) 1511 4 - vert 848 ( 0.1929610074 0.2089949846 ) 1496 4 - vert 849 ( 0.1509580016 0.9813879728 ) 1383 2 - vert 850 ( 0.2905550003 0.9849680066 ) 1379 3 - vert 851 ( 0.112703003 0.987383008 ) 1375 2 - vert 852 ( 0.3311130106 0.9791690111 ) 1375 2 - vert 853 ( 0.9655780196 0.2199130058 ) 1754 2 - vert 854 ( 0.2565110028 0.9873960018 ) 1754 2 - vert 855 ( 0.5089240074 0.2117750049 ) 1756 4 - vert 856 ( 0.4701620042 0.2312800288 ) 1548 3 - vert 857 ( 0.4859330058 0.2575619817 ) 1551 4 - vert 858 ( 0.5303670168 0.248142004 ) 1760 4 - - numtris 1352 - tri 0 2 1 0 - tri 1 3 2 0 - tri 2 6 5 4 - tri 3 4 5 7 - tri 4 5 8 7 - tri 5 10 4 9 - tri 6 4 7 9 - tri 7 7 8 9 - tri 8 9 8 11 - tri 9 14 13 12 - tri 10 14 15 13 - tri 11 5 12 13 - tri 12 5 13 8 - tri 13 3 0 16 - tri 14 0 1 16 - tri 15 19 18 17 - tri 16 19 17 20 - tri 17 23 22 21 - tri 18 24 17 18 - tri 19 26 23 25 - tri 20 26 25 27 - tri 21 30 29 28 - tri 22 31 30 28 - tri 23 31 25 30 - tri 24 34 33 32 - tri 25 36 20 35 - tri 26 35 20 37 - tri 27 38 35 37 - tri 28 41 40 39 - tri 29 41 39 19 - tri 30 36 41 19 - tri 31 36 19 20 - tri 32 44 43 42 - tri 33 47 46 45 - tri 34 50 49 48 - tri 35 53 52 51 - tri 36 53 54 52 - tri 37 34 55 33 - tri 38 57 50 56 - tri 39 24 58 17 - tri 40 60 59 24 - tri 41 61 60 18 - tri 42 60 24 18 - tri 43 31 27 25 - tri 44 32 33 62 - tri 45 65 64 63 - tri 46 65 66 64 - tri 47 65 67 66 - tri 48 69 32 68 - tri 49 69 34 32 - tri 50 40 61 39 - tri 51 70 61 40 - tri 52 71 60 70 - tri 53 70 60 61 - tri 54 74 73 72 - tri 55 76 45 75 - tri 56 76 47 45 - tri 57 77 76 75 - tri 58 50 72 49 - tri 59 75 45 78 - tri 60 75 78 79 - tri 61 78 80 79 - tri 62 83 82 81 - tri 63 51 52 44 - tri 64 51 44 84 - tri 65 87 86 85 - tri 66 88 86 87 - tri 67 88 89 86 - tri 68 37 55 34 - tri 69 91 90 42 - tri 70 72 73 92 - tri 71 92 94 93 - tri 72 73 94 92 - tri 73 97 96 95 - tri 74 99 98 97 - tri 75 98 96 97 - tri 76 97 95 100 - tri 77 37 20 55 - tri 78 101 50 57 - tri 79 24 102 58 - tri 80 64 66 103 - tri 81 64 103 104 - tri 82 107 106 105 - tri 83 107 108 106 - tri 84 111 110 109 - tri 85 105 110 111 - tri 86 106 110 105 - tri 87 108 112 106 - tri 88 80 114 113 - tri 89 80 107 105 - tri 90 80 105 114 - tri 91 79 80 113 - tri 92 116 111 115 - tri 93 114 105 116 - tri 94 105 111 116 - tri 95 93 118 117 - tri 96 94 118 93 - tri 97 90 119 112 - tri 98 119 120 112 - tri 99 121 120 119 - tri 100 121 122 120 - tri 101 112 120 123 - tri 102 121 93 122 - tri 103 92 93 121 - tri 104 126 125 124 - tri 105 129 128 127 - tri 106 129 130 128 - tri 107 132 131 130 - tri 108 130 133 128 - tri 109 130 134 133 - tri 110 136 126 135 - tri 111 125 138 137 - tri 112 134 137 139 - tri 113 138 140 137 - tri 114 143 142 141 - tri 115 146 145 144 - tri 116 146 144 147 - tri 117 146 147 148 - tri 118 151 150 149 - tri 119 96 152 143 - tri 120 137 140 139 - tri 121 152 142 143 - tri 122 152 154 153 - tri 123 128 156 155 - tri 124 128 155 127 - tri 125 138 157 140 - tri 126 96 143 138 - tri 127 134 139 158 - tri 128 131 124 130 - tri 129 160 2 159 - tri 130 159 2 3 - tri 131 151 161 150 - tri 132 163 162 160 - tri 133 163 160 164 - tri 134 145 163 144 - tri 135 144 163 164 - tri 136 165 130 129 - tri 137 165 132 130 - tri 138 166 131 132 - tri 139 115 109 166 - tri 140 115 166 167 - tri 141 167 166 132 - tri 142 167 132 165 - tri 143 109 168 166 - tri 144 171 170 169 - tri 145 169 170 172 - tri 146 152 153 142 - tri 147 39 18 19 - tri 148 61 18 39 - tri 149 26 173 22 - tri 150 26 22 23 - tri 151 176 175 174 - tri 152 177 175 176 - tri 153 117 177 176 - tri 154 180 179 178 - tri 155 180 181 179 - tri 156 117 182 177 - tri 157 183 176 89 - tri 158 177 182 175 - tri 159 182 184 175 - tri 160 185 179 135 - tri 161 186 180 178 - tri 162 186 83 180 - tri 163 186 178 187 - tri 164 188 108 107 - tri 165 89 189 86 - tri 166 109 187 168 - tri 167 166 168 185 - tri 168 86 189 82 - tri 169 190 48 91 - tri 170 49 119 48 - tri 171 49 121 119 - tri 172 91 48 90 - tri 173 48 119 90 - tri 174 72 92 49 - tri 175 49 92 121 - tri 176 50 48 56 - tri 177 85 83 186 - tri 178 185 135 131 - tri 179 181 135 179 - tri 180 81 135 181 - tri 181 96 138 95 - tri 182 190 56 48 - tri 183 53 51 84 - tri 184 143 141 157 - tri 185 78 188 80 - tri 186 188 107 80 - tri 187 93 117 183 - tri 188 85 82 83 - tri 189 86 82 85 - tri 190 52 43 44 - tri 191 54 190 52 - tri 192 54 57 190 - tri 193 57 56 190 - tri 194 147 144 164 - tri 195 164 160 159 - tri 196 74 72 191 - tri 197 192 191 72 - tri 198 193 47 76 - tri 199 194 193 76 - tri 200 52 190 43 - tri 201 71 59 60 - tri 202 193 84 47 - tri 203 53 84 193 - tri 204 50 192 72 - tri 205 74 94 73 - tri 206 32 62 195 - tri 207 198 197 196 - tri 208 198 196 199 - tri 209 198 199 101 - tri 210 199 192 50 - tri 211 199 50 101 - tri 212 197 74 196 - tri 213 196 74 191 - tri 214 77 194 76 - tri 215 196 191 192 - tri 216 196 192 199 - tri 217 125 95 138 - tri 218 166 185 131 - tri 219 140 157 200 - tri 220 203 202 201 - tri 221 203 201 1 - tri 222 205 16 204 - tri 223 205 204 15 - tri 224 206 16 205 - tri 225 3 16 206 - tri 226 207 205 14 - tri 227 14 205 15 - tri 228 161 6 10 - tri 229 6 208 5 - tri 230 208 12 5 - tri 231 10 6 4 - tri 232 160 1 2 - tri 233 1 201 209 - tri 234 45 46 188 - tri 235 45 188 78 - tri 236 84 44 42 - tri 237 175 184 174 - tri 238 174 184 171 - tri 239 117 176 183 - tri 240 38 37 69 - tri 241 69 37 34 - tri 242 71 63 64 - tri 243 71 64 59 - tri 244 20 210 55 - tri 245 64 104 59 - tri 246 138 143 157 - tri 247 136 100 126 - tri 248 100 95 125 - tri 249 126 100 125 - tri 250 135 124 131 - tri 251 135 126 124 - tri 252 130 124 134 - tri 253 189 98 99 - tri 254 189 169 98 - tri 255 162 203 160 - tri 256 160 203 1 - tri 257 134 158 133 - tri 258 128 133 156 - tri 259 133 158 156 - tri 260 206 205 207 - tri 261 136 211 100 - tri 262 99 211 136 - tri 263 99 97 211 - tri 264 211 97 100 - tri 265 213 115 212 - tri 266 212 115 167 - tri 267 111 109 115 - tri 268 139 140 214 - tri 269 140 200 214 - tri 270 215 206 207 - tri 271 215 207 208 - tri 272 158 139 216 - tri 273 139 214 216 - tri 274 217 215 208 - tri 275 217 208 6 - tri 276 158 216 218 - tri 277 219 217 6 - tri 278 219 6 161 - tri 279 151 219 161 - tri 280 158 218 156 - tri 281 207 14 208 - tri 282 208 14 12 - tri 283 209 201 204 - tri 284 1 209 16 - tri 285 16 209 204 - tri 286 43 91 42 - tri 287 190 91 43 - tri 288 17 58 210 - tri 289 20 17 210 - tri 290 47 84 46 - tri 291 112 123 85 - tri 292 123 87 85 - tri 293 116 115 213 - tri 294 113 213 220 - tri 295 93 183 221 - tri 296 93 221 122 - tri 297 221 89 88 - tri 298 221 183 89 - tri 299 122 222 120 - tri 300 122 221 222 - tri 301 222 221 88 - tri 302 222 88 87 - tri 303 222 87 123 - tri 304 120 222 123 - tri 305 84 188 46 - tri 306 84 42 188 - tri 307 42 108 188 - tri 308 42 90 108 - tri 309 90 112 108 - tri 310 89 171 169 - tri 311 89 169 189 - tri 312 174 171 89 - tri 313 176 174 89 - tri 314 113 116 213 - tri 315 113 114 116 - tri 316 82 99 136 - tri 317 189 99 82 - tri 318 172 152 96 - tri 319 98 172 96 - tri 320 169 172 98 - tri 321 124 137 134 - tri 322 124 125 137 - tri 323 187 178 168 - tri 324 178 179 168 - tri 325 168 179 185 - tri 326 81 136 135 - tri 327 82 136 81 - tri 328 180 81 181 - tri 329 83 81 180 - tri 330 110 187 109 - tri 331 110 186 187 - tri 332 112 85 106 - tri 333 106 85 186 - tri 334 106 186 110 - tri 335 59 102 24 - tri 336 59 104 102 - tri 337 223 167 165 - tri 338 212 167 223 - tri 339 226 225 224 - tri 340 229 228 227 - tri 341 230 229 227 - tri 342 233 232 231 - tri 343 236 235 234 - tri 344 234 235 237 - tri 345 234 237 238 - tri 346 237 231 239 - tri 347 238 237 239 - tri 348 238 239 240 - tri 349 231 241 239 - tri 350 239 241 226 - tri 351 241 225 226 - tri 352 241 242 225 - tri 353 243 241 231 - tri 354 232 243 231 - tri 355 244 242 241 - tri 356 243 244 241 - tri 357 243 245 244 - tri 358 232 245 243 - tri 359 232 246 245 - tri 360 246 247 245 - tri 361 249 248 233 - tri 362 233 248 232 - tri 363 248 246 232 - tri 364 252 251 250 - tri 365 254 240 253 - tri 366 240 239 251 - tri 367 239 226 251 - tri 368 224 225 255 - tri 369 256 234 238 - tri 370 252 240 251 - tri 371 229 257 228 - tri 372 258 252 250 - tri 373 258 250 259 - tri 374 262 261 260 - tri 375 261 264 263 - tri 376 260 261 263 - tri 377 265 236 234 - tri 378 266 236 265 - tri 379 268 267 261 - tri 380 256 254 267 - tri 381 268 261 262 - tri 382 261 267 264 - tri 383 233 231 235 - tri 384 236 233 235 - tri 385 235 231 237 - tri 386 250 251 224 - tri 387 257 250 224 - tri 388 259 250 257 - tri 389 251 226 224 - tri 390 271 270 269 - tri 391 272 256 267 - tri 392 268 272 267 - tri 393 275 274 273 - tri 394 275 276 274 - tri 395 278 277 276 - tri 396 276 280 279 - tri 397 276 279 274 - tri 398 277 280 276 - tri 399 273 274 281 - tri 400 274 279 282 - tri 401 279 283 282 - tri 402 279 284 283 - tri 403 285 277 278 - tri 404 274 282 281 - tri 405 287 273 286 - tri 406 287 275 273 - tri 407 288 275 287 - tri 408 289 288 287 - tri 409 286 291 290 - tri 410 293 292 244 - tri 411 244 292 242 - tri 412 247 293 244 - tri 413 292 294 242 - tri 414 294 295 242 - tri 415 294 296 295 - tri 416 255 225 297 - tri 417 255 297 298 - tri 418 225 299 297 - tri 419 299 300 297 - tri 420 300 301 297 - tri 421 293 302 294 - tri 422 293 294 292 - tri 423 228 304 303 - tri 424 303 304 305 - tri 425 290 291 306 - tri 426 291 281 307 - tri 427 281 282 307 - tri 428 302 308 294 - tri 429 294 308 296 - tri 430 311 310 309 - tri 431 301 309 310 - tri 432 312 303 305 - tri 433 305 304 311 - tri 434 291 307 313 - tri 435 316 315 314 - tri 436 319 318 317 - tri 437 320 319 317 - tri 438 290 306 321 - tri 439 323 316 322 - tri 440 322 316 314 - tri 441 324 322 314 - tri 442 280 284 279 - tri 443 325 322 324 - tri 444 313 307 323 - tri 445 296 300 299 - tri 446 295 296 299 - tri 447 15 204 326 - tri 448 204 327 326 - tri 449 329 328 289 - tri 450 328 288 289 - tri 451 329 289 330 - tri 452 331 285 328 - tri 453 331 328 329 - tri 454 333 329 332 - tri 455 333 331 329 - tri 456 326 333 332 - tri 457 326 327 333 - tri 458 327 331 333 - tri 459 202 334 201 - tri 460 336 330 335 - tri 461 286 290 337 - tri 462 337 290 321 - tri 463 337 321 338 - tri 464 338 321 339 - tri 465 335 337 338 - tri 466 335 338 340 - tri 467 341 335 340 - tri 468 336 335 341 - tri 469 342 336 341 - tri 470 343 336 342 - tri 471 345 343 344 - tri 472 13 345 344 - tri 473 346 342 341 - tri 474 347 344 346 - tri 475 327 334 331 - tri 476 343 332 336 - tri 477 344 343 342 - tri 478 344 342 346 - tri 479 321 348 339 - tri 480 339 350 349 - tri 481 349 350 319 - tri 482 339 348 350 - tri 483 320 349 319 - tri 484 351 349 320 - tri 485 340 338 351 - tri 486 341 340 352 - tri 487 352 340 351 - tri 488 352 351 320 - tri 489 298 297 310 - tri 490 297 301 310 - tri 491 355 354 353 - tri 492 358 357 356 - tri 493 353 354 359 - tri 494 358 360 357 - tri 495 357 362 361 - tri 496 364 363 360 - tri 497 364 365 363 - tri 498 368 367 366 - tri 499 369 365 364 - tri 500 370 365 369 - tri 501 373 372 371 - tri 502 375 374 362 - tri 503 366 353 359 - tri 504 378 377 376 - tri 505 380 371 379 - tri 506 381 371 380 - tri 507 371 382 379 - tri 508 371 383 382 - tri 509 375 382 384 - tri 510 385 382 375 - tri 511 379 382 385 - tri 512 366 359 386 - tri 513 368 366 386 - tri 514 373 371 381 - tri 515 375 384 374 - tri 516 384 270 374 - tri 517 359 354 387 - tri 518 388 387 270 - tri 519 357 361 356 - tri 520 391 390 389 - tri 521 393 392 390 - tri 522 391 389 394 - tri 523 394 389 395 - tri 524 398 397 396 - tri 525 392 399 354 - tri 526 354 399 387 - tri 527 402 401 400 - tri 528 393 402 392 - tri 529 404 356 403 - tri 530 389 354 355 - tri 531 407 406 405 - tri 532 408 406 407 - tri 533 384 388 270 - tri 534 395 389 355 - tri 535 404 358 356 - tri 536 383 388 384 - tri 537 382 383 384 - tri 538 410 409 388 - tri 539 409 387 388 - tri 540 359 387 409 - tri 541 402 399 392 - tri 542 402 400 399 - tri 543 375 362 357 - tri 544 375 357 363 - tri 545 363 357 360 - tri 546 410 406 409 - tri 547 405 406 410 - tri 548 412 411 369 - tri 549 411 370 369 - tri 550 413 386 406 - tri 551 408 413 406 - tri 552 368 413 408 - tri 553 368 386 413 - tri 554 372 388 383 - tri 555 372 410 388 - tri 556 371 372 383 - tri 557 378 376 385 - tri 558 376 379 385 - tri 559 385 363 414 - tri 560 385 375 363 - tri 561 378 385 414 - tri 562 386 409 406 - tri 563 386 359 409 - tri 564 390 354 389 - tri 565 390 392 354 - tri 566 391 393 390 - tri 567 415 393 391 - tri 568 398 404 403 - tri 569 398 396 404 - tri 570 204 334 327 - tri 571 201 334 204 - tri 572 15 345 13 - tri 573 15 326 345 - tri 574 202 416 334 - tri 575 417 277 285 - tri 576 13 344 418 - tri 577 418 344 347 - tri 578 13 418 8 - tri 579 345 332 343 - tri 580 326 332 345 - tri 581 419 330 336 - tri 582 332 419 336 - tri 583 332 329 419 - tri 584 329 330 419 - tri 585 288 276 275 - tri 586 328 285 288 - tri 587 285 278 288 - tri 588 288 278 276 - tri 589 273 281 291 - tri 590 286 273 291 - tri 591 422 421 420 - tri 592 423 422 420 - tri 593 424 422 423 - tri 594 346 341 425 - tri 595 425 341 352 - tri 596 426 417 285 - tri 597 426 285 331 - tri 598 334 426 331 - tri 599 427 417 426 - tri 600 334 427 426 - tri 601 334 416 427 - tri 602 8 418 11 - tri 603 11 418 347 - tri 604 330 286 337 - tri 605 335 330 337 - tri 606 289 286 330 - tri 607 289 287 286 - tri 608 428 315 316 - tri 609 282 428 316 - tri 610 282 283 428 - tri 611 324 314 429 - tri 612 314 315 429 - tri 613 429 315 318 - tri 614 319 429 318 - tri 615 351 339 349 - tri 616 338 339 351 - tri 617 245 247 244 - tri 618 242 299 225 - tri 619 242 295 299 - tri 620 257 224 255 - tri 621 304 255 298 - tri 622 227 303 430 - tri 623 227 228 303 - tri 624 293 431 302 - tri 625 430 303 312 - tri 626 432 291 313 - tri 627 306 291 432 - tri 628 374 270 271 - tri 629 362 374 433 - tri 630 374 271 433 - tri 631 270 387 269 - tri 632 399 434 387 - tri 633 361 362 435 - tri 634 362 433 435 - tri 635 400 434 399 - tri 636 400 436 434 - tri 637 401 436 400 - tri 638 266 249 236 - tri 639 249 233 236 - tri 640 267 253 264 - tri 641 267 254 253 - tri 642 256 238 254 - tri 643 254 238 240 - tri 644 230 259 229 - tri 645 259 257 229 - tri 646 263 258 259 - tri 647 263 259 230 - tri 648 253 240 252 - tri 649 263 264 258 - tri 650 256 437 234 - tri 651 387 438 269 - tri 652 434 438 387 - tri 653 265 234 437 - tri 654 264 253 252 - tri 655 264 252 258 - tri 656 307 282 323 - tri 657 282 316 323 - tri 658 301 439 309 - tri 659 300 439 301 - tri 660 439 440 309 - tri 661 308 442 441 - tri 662 441 442 440 - tri 663 441 440 439 - tri 664 300 441 439 - tri 665 296 441 300 - tri 666 308 441 296 - tri 667 298 310 311 - tri 668 304 298 311 - tri 669 350 429 319 - tri 670 350 324 429 - tri 671 257 304 228 - tri 672 257 255 304 - tri 673 348 325 350 - tri 674 350 325 324 - tri 675 445 444 443 - tri 676 446 444 445 - tri 677 449 448 447 - tri 678 448 450 447 - tri 679 447 450 451 - tri 680 10 9 448 - tri 681 448 9 450 - tri 682 450 9 451 - tri 683 9 11 451 - tri 684 454 453 452 - tri 685 454 452 455 - tri 686 447 452 453 - tri 687 447 451 452 - tri 688 446 456 444 - tri 689 444 456 443 - tri 690 459 458 457 - tri 691 459 460 458 - tri 692 463 462 461 - tri 693 464 457 458 - tri 694 466 465 463 - tri 695 466 467 465 - tri 696 470 469 468 - tri 697 471 469 470 - tri 698 471 470 465 - tri 699 474 473 472 - tri 700 476 475 460 - tri 701 475 477 460 - tri 702 478 477 475 - tri 703 481 480 479 - tri 704 481 459 480 - tri 705 476 459 481 - tri 706 476 460 459 - tri 707 484 483 482 - tri 708 487 486 485 - tri 709 490 489 488 - tri 710 493 492 491 - tri 711 493 491 494 - tri 712 474 472 495 - tri 713 497 496 490 - tri 714 464 458 498 - tri 715 500 464 499 - tri 716 501 457 500 - tri 717 500 457 464 - tri 718 471 465 467 - tri 719 473 502 472 - tri 720 505 504 503 - tri 721 505 503 506 - tri 722 505 506 507 - tri 723 509 508 473 - tri 724 509 473 474 - tri 725 479 480 501 - tri 726 510 479 501 - tri 727 511 510 500 - tri 728 510 501 500 - tri 729 514 513 512 - tri 730 516 515 486 - tri 731 516 486 487 - tri 732 517 515 516 - tri 733 490 488 513 - tri 734 515 518 486 - tri 735 515 519 518 - tri 736 518 519 520 - tri 737 523 522 521 - tri 738 492 484 491 - tri 739 492 524 484 - tri 740 527 526 525 - tri 741 528 527 525 - tri 742 528 525 529 - tri 743 477 474 495 - tri 744 531 483 530 - tri 745 513 532 512 - tri 746 532 534 533 - tri 747 512 532 533 - tri 748 537 536 535 - tri 749 539 537 538 - tri 750 538 537 535 - tri 751 537 540 536 - tri 752 477 495 460 - tri 753 541 497 490 - tri 754 464 498 542 - tri 755 503 543 506 - tri 756 503 544 543 - tri 757 547 546 545 - tri 758 547 545 548 - tri 759 551 550 549 - tri 760 546 551 549 - tri 761 545 546 549 - tri 762 548 545 552 - tri 763 520 554 553 - tri 764 520 546 547 - tri 765 520 553 546 - tri 766 519 554 520 - tri 767 556 555 551 - tri 768 553 556 546 - tri 769 546 556 551 - tri 770 534 558 557 - tri 771 533 534 557 - tri 772 530 552 559 - tri 773 559 552 560 - tri 774 561 559 560 - tri 775 561 560 562 - tri 776 552 563 560 - tri 777 561 562 534 - tri 778 532 561 534 - tri 779 566 565 564 - tri 780 569 568 567 - tri 781 569 567 570 - tri 782 572 570 571 - tri 783 570 567 573 - tri 784 570 573 574 - tri 785 576 575 566 - tri 786 564 578 577 - tri 787 574 579 578 - tri 788 577 578 580 - tri 789 583 582 581 - tri 790 146 584 145 - tri 791 146 585 584 - tri 792 146 148 585 - tri 793 586 149 150 - tri 794 535 583 587 - tri 795 578 579 580 - tri 796 587 583 581 - tri 797 587 588 154 - tri 798 567 155 589 - tri 799 567 568 155 - tri 800 577 580 590 - tri 801 535 577 583 - tri 802 574 591 579 - tri 803 571 570 565 - tri 804 593 592 445 - tri 805 592 446 445 - tri 806 586 150 161 - tri 807 163 593 162 - tri 808 163 594 593 - tri 809 145 584 163 - tri 810 584 594 163 - tri 811 595 569 570 - tri 812 595 570 572 - tri 813 596 572 571 - tri 814 555 596 550 - tri 815 555 597 596 - tri 816 597 572 596 - tri 817 597 595 572 - tri 818 550 596 598 - tri 819 601 600 599 - tri 820 600 602 599 - tri 821 587 581 588 - tri 822 480 459 457 - tri 823 501 480 457 - tri 824 466 461 603 - tri 825 466 463 461 - tri 826 606 605 604 - tri 827 607 606 604 - tri 828 558 606 607 - tri 829 610 609 608 - tri 830 610 608 611 - tri 831 558 607 612 - tri 832 613 529 606 - tri 833 607 604 612 - tri 834 612 604 614 - tri 835 615 575 608 - tri 836 616 609 610 - tri 837 616 610 523 - tri 838 616 617 609 - tri 839 618 547 548 - tri 840 529 525 619 - tri 841 550 598 617 - tri 842 596 615 598 - tri 843 525 521 619 - tri 844 620 531 489 - tri 845 488 489 559 - tri 846 488 559 561 - tri 847 531 530 489 - tri 848 489 530 559 - tri 849 513 488 532 - tri 850 488 561 532 - tri 851 490 496 489 - tri 852 526 616 523 - tri 853 615 571 575 - tri 854 611 608 575 - tri 855 522 611 575 - tri 856 535 536 577 - tri 857 620 489 496 - tri 858 493 524 492 - tri 859 583 590 582 - tri 860 518 520 618 - tri 861 618 520 547 - tri 862 534 613 558 - tri 863 526 523 521 - tri 864 525 526 521 - tri 865 491 484 482 - tri 866 494 491 620 - tri 867 494 620 497 - tri 868 497 620 496 - tri 869 585 594 584 - tri 870 594 592 593 - tri 871 514 621 513 - tri 872 622 513 621 - tri 873 623 516 487 - tri 874 624 516 623 - tri 875 491 482 620 - tri 876 511 500 499 - tri 877 623 487 524 - tri 878 493 623 524 - tri 879 490 513 622 - tri 880 514 512 533 - tri 881 473 625 502 - tri 882 628 627 626 - tri 883 628 629 627 - tri 884 628 541 629 - tri 885 629 490 622 - tri 886 629 541 490 - tri 887 626 627 514 - tri 888 627 621 514 - tri 889 517 516 624 - tri 890 627 622 621 - tri 891 627 629 622 - tri 892 564 577 536 - tri 893 596 571 615 - tri 894 580 630 590 - tri 895 203 631 202 - tri 896 203 443 631 - tri 897 633 632 456 - tri 898 633 455 632 - tri 899 634 633 456 - tri 900 446 634 456 - tri 901 635 454 633 - tri 902 454 455 633 - tri 903 161 10 449 - tri 904 449 447 636 - tri 905 636 447 453 - tri 906 10 448 449 - tri 907 593 445 443 - tri 908 443 637 631 - tri 909 486 618 485 - tri 910 486 518 618 - tri 911 524 483 484 - tri 912 604 605 614 - tri 913 605 601 614 - tri 914 558 613 606 - tri 915 478 509 477 - tri 916 509 474 477 - tri 917 511 503 504 - tri 918 511 499 503 - tri 919 460 495 638 - tri 920 503 499 544 - tri 921 577 590 583 - tri 922 576 566 540 - tri 923 540 564 536 - tri 924 566 564 540 - tri 925 575 571 565 - tri 926 575 565 566 - tri 927 570 574 565 - tri 928 619 539 538 - tri 929 619 538 600 - tri 930 162 593 203 - tri 931 593 443 203 - tri 932 574 573 591 - tri 933 567 589 573 - tri 934 573 589 591 - tri 935 634 635 633 - tri 936 576 540 639 - tri 937 539 576 639 - tri 938 539 639 537 - tri 939 639 540 537 - tri 940 641 640 555 - tri 941 640 597 555 - tri 942 551 555 550 - tri 943 579 642 580 - tri 944 580 642 630 - tri 945 643 635 634 - tri 946 643 636 635 - tri 947 591 644 579 - tri 948 579 644 642 - tri 949 645 636 643 - tri 950 645 449 636 - tri 951 591 646 644 - tri 952 647 449 645 - tri 953 647 161 449 - tri 954 586 161 647 - tri 955 591 589 646 - tri 956 635 636 454 - tri 957 636 453 454 - tri 958 637 632 631 - tri 959 443 456 637 - tri 960 456 632 637 - tri 961 482 483 531 - tri 962 620 482 531 - tri 963 458 638 498 - tri 964 460 638 458 - tri 965 487 485 524 - tri 966 552 526 563 - tri 967 563 526 527 - tri 968 556 641 555 - tri 969 554 648 641 - tri 970 534 649 613 - tri 971 534 562 649 - tri 972 649 528 529 - tri 973 649 529 613 - tri 974 562 560 650 - tri 975 562 650 649 - tri 976 650 528 649 - tri 977 650 527 528 - tri 978 650 563 527 - tri 979 560 563 650 - tri 980 524 485 618 - tri 981 524 618 483 - tri 982 483 618 548 - tri 983 483 548 530 - tri 984 530 548 552 - tri 985 529 600 601 - tri 986 529 619 600 - tri 987 605 529 601 - tri 988 606 529 605 - tri 989 554 641 556 - tri 990 554 556 553 - tri 991 521 576 539 - tri 992 619 521 539 - tri 993 602 535 587 - tri 994 538 535 602 - tri 995 600 538 602 - tri 996 565 574 578 - tri 997 565 578 564 - tri 998 617 598 609 - tri 999 609 598 608 - tri 1000 598 615 608 - tri 1001 522 575 576 - tri 1002 521 522 576 - tri 1003 610 611 522 - tri 1004 523 610 522 - tri 1005 549 550 617 - tri 1006 549 617 616 - tri 1007 552 545 526 - tri 1008 545 616 526 - tri 1009 545 549 616 - tri 1010 499 464 542 - tri 1011 499 542 544 - tri 1012 651 595 597 - tri 1013 640 651 597 - tri 1014 654 653 652 - tri 1015 657 656 655 - tri 1016 658 656 657 - tri 1017 661 660 659 - tri 1018 664 663 662 - tri 1019 663 665 662 - tri 1020 663 666 665 - tri 1021 665 667 660 - tri 1022 666 667 665 - tri 1023 666 668 667 - tri 1024 660 667 669 - tri 1025 667 654 669 - tri 1026 669 654 652 - tri 1027 669 652 670 - tri 1028 671 660 669 - tri 1029 659 660 671 - tri 1030 672 669 670 - tri 1031 671 669 672 - tri 1032 671 672 673 - tri 1033 659 671 673 - tri 1034 659 673 674 - tri 1035 674 673 675 - tri 1036 677 661 676 - tri 1037 661 659 676 - tri 1038 676 659 674 - tri 1039 680 679 678 - tri 1040 682 681 668 - tri 1041 668 678 667 - tri 1042 667 678 654 - tri 1043 653 683 652 - tri 1044 684 666 663 - tri 1045 680 678 668 - tri 1046 657 655 685 - tri 1047 686 679 680 - tri 1048 686 687 679 - tri 1049 690 689 688 - tri 1050 688 692 691 - tri 1051 689 692 688 - tri 1052 693 663 664 - tri 1053 694 693 664 - tri 1054 696 688 695 - tri 1055 684 695 682 - tri 1056 696 690 688 - tri 1057 688 691 695 - tri 1058 661 662 660 - tri 1059 664 662 661 - tri 1060 662 665 660 - tri 1061 679 653 678 - tri 1062 685 653 679 - tri 1063 687 685 679 - tri 1064 678 653 654 - tri 1065 699 698 697 - tri 1066 700 695 684 - tri 1067 696 695 700 - tri 1068 703 702 701 - tri 1069 703 701 704 - tri 1070 705 704 277 - tri 1071 704 706 280 - tri 1072 704 701 706 - tri 1073 277 704 280 - tri 1074 702 707 701 - tri 1075 701 708 706 - tri 1076 706 708 709 - tri 1077 706 709 284 - tri 1078 710 705 277 - tri 1079 701 707 708 - tri 1080 712 711 702 - tri 1081 712 702 703 - tri 1082 713 712 703 - tri 1083 714 712 713 - tri 1084 711 716 715 - tri 1085 718 672 717 - tri 1086 672 670 717 - tri 1087 675 672 718 - tri 1088 717 670 719 - tri 1089 719 670 720 - tri 1090 719 720 721 - tri 1091 683 722 652 - tri 1092 683 723 722 - tri 1093 652 722 724 - tri 1094 724 722 725 - tri 1095 725 722 726 - tri 1096 718 719 727 - tri 1097 718 717 719 - tri 1098 655 729 728 - tri 1099 729 730 728 - tri 1100 716 731 715 - tri 1101 715 732 707 - tri 1102 707 732 708 - tri 1103 727 719 733 - tri 1104 719 721 733 - tri 1105 736 735 734 - tri 1106 726 734 735 - tri 1107 737 730 729 - tri 1108 730 736 728 - tri 1109 715 738 732 - tri 1110 741 740 739 - tri 1111 743 317 742 - tri 1112 320 317 743 - tri 1113 716 744 731 - tri 1114 746 745 741 - tri 1115 745 740 741 - tri 1116 747 740 745 - tri 1117 280 706 284 - tri 1118 748 747 745 - tri 1119 738 746 732 - tri 1120 721 724 725 - tri 1121 720 724 721 - tri 1122 455 749 632 - tri 1123 632 749 750 - tri 1124 752 714 751 - tri 1125 751 714 713 - tri 1126 752 753 714 - tri 1127 754 751 710 - tri 1128 754 752 751 - tri 1129 756 755 752 - tri 1130 756 752 754 - tri 1131 749 755 756 - tri 1132 749 756 750 - tri 1133 750 756 754 - tri 1134 202 631 757 - tri 1135 759 758 753 - tri 1136 711 760 716 - tri 1137 760 744 716 - tri 1138 760 761 744 - tri 1139 761 762 744 - tri 1140 758 761 760 - tri 1141 758 763 761 - tri 1142 764 763 758 - tri 1143 759 764 758 - tri 1144 765 764 759 - tri 1145 766 765 759 - tri 1146 768 767 766 - tri 1147 452 767 768 - tri 1148 346 764 765 - tri 1149 347 346 767 - tri 1150 750 754 757 - tri 1151 766 759 755 - tri 1152 767 765 766 - tri 1153 767 346 765 - tri 1154 744 762 769 - tri 1155 762 771 770 - tri 1156 771 743 770 - tri 1157 762 770 769 - tri 1158 320 743 771 - tri 1159 772 320 771 - tri 1160 763 772 761 - tri 1161 764 352 763 - tri 1162 352 772 763 - tri 1163 352 320 772 - tri 1164 723 734 722 - tri 1165 722 734 726 - tri 1166 775 774 773 - tri 1167 778 777 776 - tri 1168 774 779 773 - tri 1169 778 776 780 - tri 1170 776 782 781 - tri 1171 784 780 783 - tri 1172 784 783 785 - tri 1173 788 787 786 - tri 1174 789 784 785 - tri 1175 790 789 785 - tri 1176 793 792 791 - tri 1177 795 781 794 - tri 1178 787 779 774 - tri 1179 798 797 796 - tri 1180 800 799 792 - tri 1181 801 800 792 - tri 1182 792 799 802 - tri 1183 792 802 803 - tri 1184 795 804 802 - tri 1185 805 795 802 - tri 1186 799 805 802 - tri 1187 787 806 779 - tri 1188 788 806 787 - tri 1189 793 801 792 - tri 1190 795 794 804 - tri 1191 804 794 697 - tri 1192 779 807 773 - tri 1193 808 697 807 - tri 1194 776 777 782 - tri 1195 811 810 809 - tri 1196 813 809 812 - tri 1197 811 814 810 - tri 1198 814 815 810 - tri 1199 818 817 816 - tri 1200 812 773 819 - tri 1201 773 807 819 - tri 1202 822 821 820 - tri 1203 813 812 822 - tri 1204 824 823 777 - tri 1205 810 775 773 - tri 1206 827 826 825 - tri 1207 828 827 825 - tri 1208 804 697 808 - tri 1209 815 775 810 - tri 1210 824 777 778 - tri 1211 803 804 808 - tri 1212 802 804 803 - tri 1213 830 808 829 - tri 1214 829 808 807 - tri 1215 779 829 807 - tri 1216 822 812 819 - tri 1217 822 819 821 - tri 1218 795 776 781 - tri 1219 795 783 776 - tri 1220 783 780 776 - tri 1221 830 829 825 - tri 1222 826 830 825 - tri 1223 832 789 831 - tri 1224 831 789 790 - tri 1225 833 825 806 - tri 1226 828 825 833 - tri 1227 788 828 833 - tri 1228 788 833 806 - tri 1229 791 803 808 - tri 1230 791 808 830 - tri 1231 792 803 791 - tri 1232 798 805 797 - tri 1233 797 805 799 - tri 1234 805 834 783 - tri 1235 805 783 795 - tri 1236 798 834 805 - tri 1237 806 825 829 - tri 1238 806 829 779 - tri 1239 809 810 773 - tri 1240 809 773 812 - tri 1241 811 809 813 - tri 1242 835 811 813 - tri 1243 818 823 824 - tri 1244 818 824 817 - tri 1245 632 750 757 - tri 1246 631 632 757 - tri 1247 455 452 768 - tri 1248 455 768 749 - tri 1249 202 757 416 - tri 1250 417 710 277 - tri 1251 452 836 767 - tri 1252 836 347 767 - tri 1253 452 451 836 - tri 1254 768 766 755 - tri 1255 749 768 755 - tri 1256 837 759 753 - tri 1257 755 759 837 - tri 1258 755 837 752 - tri 1259 752 837 753 - tri 1260 713 703 704 - tri 1261 751 713 710 - tri 1262 710 713 705 - tri 1263 713 704 705 - tri 1264 702 715 707 - tri 1265 711 715 702 - tri 1266 840 839 838 - tri 1267 842 841 838 - tri 1268 842 838 839 - tri 1269 421 841 842 - tri 1270 420 421 842 - tri 1271 346 425 764 - tri 1272 425 352 764 - tri 1273 843 710 417 - tri 1274 843 754 710 - tri 1275 757 754 843 - tri 1276 427 843 417 - tri 1277 757 843 427 - tri 1278 757 427 416 - tri 1279 451 11 836 - tri 1280 11 347 836 - tri 1281 753 760 711 - tri 1282 758 760 753 - tri 1283 714 753 711 - tri 1284 714 711 712 - tri 1285 844 741 739 - tri 1286 708 741 844 - tri 1287 708 844 709 - tri 1288 747 845 740 - tri 1289 740 845 739 - tri 1290 845 742 739 - tri 1291 743 742 845 - tri 1292 772 771 762 - tri 1293 761 772 762 - tri 1294 673 672 675 - tri 1295 670 652 724 - tri 1296 670 724 720 - tri 1297 685 683 653 - tri 1298 728 723 683 - tri 1299 656 846 729 - tri 1300 656 729 655 - tri 1301 718 727 847 - tri 1302 846 737 729 - tri 1303 848 738 715 - tri 1304 731 848 715 - tri 1305 794 699 697 - tri 1306 781 849 794 - tri 1307 794 849 699 - tri 1308 697 698 807 - tri 1309 819 807 850 - tri 1310 782 851 781 - tri 1311 781 851 849 - tri 1312 821 819 850 - tri 1313 821 850 852 - tri 1314 820 821 852 - tri 1315 694 664 677 - tri 1316 677 664 661 - tri 1317 695 691 681 - tri 1318 695 681 682 - tri 1319 684 682 666 - tri 1320 682 668 666 - tri 1321 658 657 687 - tri 1322 687 657 685 - tri 1323 692 687 686 - tri 1324 692 658 687 - tri 1325 681 680 668 - tri 1326 692 686 691 - tri 1327 684 663 853 - tri 1328 807 698 854 - tri 1329 850 807 854 - tri 1330 693 853 663 - tri 1331 691 680 681 - tri 1332 691 686 680 - tri 1333 732 746 708 - tri 1334 708 746 741 - tri 1335 726 735 855 - tri 1336 725 726 855 - tri 1337 855 735 856 - tri 1338 733 858 857 - tri 1339 858 856 857 - tri 1340 858 855 856 - tri 1341 725 855 858 - tri 1342 721 725 858 - tri 1343 733 721 858 - tri 1344 723 736 734 - tri 1345 728 736 723 - tri 1346 770 743 845 - tri 1347 770 845 747 - tri 1348 685 655 728 - tri 1349 685 728 683 - tri 1350 769 770 748 - tri 1351 770 747 748 - - numweights 1764 - weight 0 3 0.2989006937 ( 4.0866098404 -2.8471412659 6.4127655029 ) - weight 1 18 0.1044220254 ( 4.168366909 -5.2742805481 -0.1390461922 ) - weight 2 17 0.216313526 ( 4.5593738556 -4.8625760078 4.9783420563 ) - weight 3 4 0.3803637922 ( 5.6346516609 1.3274410963 1.0044068098 ) - weight 4 3 0.3220692277 ( 2.2474899292 0.0133972168 5.8791251183 ) - weight 5 18 0.2241343707 ( 2.3292467594 -2.4137420654 -0.6726865768 ) - weight 6 17 0.2419008166 ( 2.6926527023 -1.9833818674 5.2529492378 ) - weight 7 4 0.2118955553 ( 5.801153183 -1.8344190121 -0.3464198112 ) - weight 8 3 0.2706798315 ( 3.4398300648 -2.9727020264 5.0742454529 ) - weight 9 18 0.0820683613 ( 3.521586895 -5.3998413086 -1.4775662422 ) - weight 10 17 0.1771882027 ( 3.8368215561 -4.6714172363 3.6871788502 ) - weight 11 4 0.4700636268 ( 4.6122527122 1.2480124235 -0.0791598707 ) - weight 12 3 0.1700060666 ( 6.583920002 -3.2363624573 3.5967652798 ) - weight 13 18 0.0517478064 ( 6.6656770706 -5.6635017395 -2.9550464153 ) - weight 14 17 0.1442716569 ( 6.8909106255 -4.5284328461 2.0168907642 ) - weight 15 4 0.6339744925 ( 2.1139774323 1.9400219917 2.2483944893 ) - weight 16 3 0.1894543469 ( 3.8803699017 -2.40209198 -8.9853553772 ) - weight 17 17 0.4399712682 ( 3.4695298672 -0.7296451926 -9.82280159 ) - weight 18 4 0.2641336918 ( -8.6858310699 -0.2121068984 -4.4633436203 ) - weight 19 19 0.106440641 ( 3.8803699017 -12.1135501862 -6.0038051605 ) - weight 20 3 0.1577714682 ( 4.5955500603 0.1378479004 -7.0744948387 ) - weight 21 17 0.4331905842 ( 4.2932252884 1.2857265472 -7.3991746902 ) - weight 22 4 0.295035243 ( -7.1418991089 -2.454625845 -2.6740567684 ) - weight 23 19 0.1140027195 ( 4.5955500603 -9.4154872894 -4.3235855103 ) - weight 24 3 0.2021251768 ( 3.6253700256 -3.7588424683 -6.7796049118 ) - weight 25 17 0.3010104895 ( 3.3415739536 -2.5805225372 -7.9982438087 ) - weight 26 4 0.4968643188 ( -6.5392136574 1.230964303 -4.1792478561 ) - weight 27 3 0.1403784007 ( 3.6341600418 0.3311271667 -9.5344247818 ) - weight 28 17 0.502785027 ( 3.1922063828 2.0517232418 -9.6825685501 ) - weight 29 4 0.2179938853 ( -9.0996303558 -2.9787244797 -4.3786058426 ) - weight 30 19 0.138842687 ( 3.6341600418 -9.4391679764 -6.7909827232 ) - weight 31 3 0.1612562537 ( 3.7402501106 3.2062568665 -7.2569146156 ) - weight 32 17 0.5152344108 ( 3.4288640022 4.2957925797 -6.7889852524 ) - weight 33 22 0.0584010631 ( 3.7402501106 -13.7341041565 -6.0053782463 ) - weight 34 19 0.2651082575 ( 3.7402501106 -6.3749866486 -4.7749934196 ) - weight 35 3 0.233121261 ( 0 0.9186477661 -10.4483251572 ) - weight 36 17 0.5231345296 ( -0.4884240627 2.7914998531 -10.2240514755 ) - weight 37 19 0.2437442392 ( 0 -8.9342479706 -7.7529859543 ) - weight 38 3 0.2416281402 ( 0 -3.8032722473 -9.3679552078 ) - weight 39 10 0.175872013 ( 7.6688499451 0.4780739248 -8.4245557785 ) - weight 40 17 0.3734616339 ( -0.4264043868 -2.0511879921 -10.3149185181 ) - weight 41 4 0.1183245108 ( -7.6726365089 0.4781373739 -8.4211158752 ) - weight 42 19 0.0907137394 ( 0 -13.5429353714 -6.2617692947 ) - weight 43 3 0.0588277243 ( 0 3.3220977783 -8.4476156235 ) - weight 44 17 0.5344693065 ( -0.3735713959 4.6428985596 -7.7064056396 ) - weight 45 22 0.0834311321 ( 0 -13.6182632446 -7.1960787773 ) - weight 46 19 0.3232718408 ( 0 -6.3642492294 -5.9712677002 ) - weight 47 3 0.2502370775 ( 7.0197200775 0.232837677 -5.7562747002 ) - weight 48 17 0.4181198776 ( 6.7890715599 1.0943640471 -6.2340736389 ) - weight 49 4 0.1907435954 ( -6.7693958282 -2.0439882278 0.0307437535 ) - weight 50 19 0.1408994794 ( 7.0197200775 -9.2050018311 -3.0188162327 ) - weight 51 3 0.1223682761 ( 6.4507799149 2.8663978577 -5.0570845604 ) - weight 52 17 0.4652246237 ( 6.2612071037 3.4742908478 -4.890381813 ) - weight 53 22 0.0779194087 ( 6.4507799149 -14.0739631653 -3.8055481911 ) - weight 54 4 0.1248696223 ( -5.9021105766 -4.6810879707 0.2349975705 ) - weight 55 19 0.2096180469 ( 6.4507799149 -6.5201787949 -2.5538055897 ) - weight 56 3 0.1879220307 ( 8.5345602036 0.0633277893 -2.3120148182 ) - weight 57 17 0.3800631762 ( 8.4991350174 0.1223218068 -3.0220308304 ) - weight 58 4 0.3526526392 ( -4.0877261162 -1.380833745 2.5910708904 ) - weight 59 19 0.0793621838 ( 8.5345602036 -9.0711259842 0.4270128608 ) - weight 60 3 0.2205083519 ( 8.1109304428 2.7250976563 -0.4794548452 ) - weight 61 17 0.4265399277 ( 8.1814031601 2.2590177059 -0.5814703703 ) - weight 62 22 0.0848226324 ( 8.1109304428 -14.2152633667 0.7720816135 ) - weight 63 4 0.0903976262 ( -2.2123010159 -3.9423925877 3.3286032677 ) - weight 64 19 0.1777314693 ( 8.1109304428 -6.2585868835 2.0185275078 ) - weight 65 3 0.3686598539 ( 6.0281300545 0.6308784485 4.3858852386 ) - weight 66 18 0.1251238883 ( 6.1098871231 -1.7962608337 -2.1659264565 ) - weight 67 17 0.2653119862 ( 6.3813371658 -0.9726183414 3.7442245483 ) - weight 68 4 0.1831025779 ( 3.0661528111 -1.901272893 2.7227158546 ) - weight 69 19 0.0578016862 ( 6.0281300545 -7.9170680046 7.0491070747 ) - weight 70 7 0.3494953811 ( -0.5761880875 1.0240461826 3.1873538494 ) - weight 71 8 0.0571241342 ( -0.489547044 -4.0477013588 3.2013347149 ) - weight 72 6 0.4873141348 ( 0.3178459406 3.8975038528 3.1564416885 ) - weight 73 5 0.1060663685 ( 4.4627971649 18.0488548279 -2.2850666046 ) - weight 74 7 0.3494953811 ( 0.5832822323 3.3450553417 3.0524516106 ) - weight 75 8 0.0571241342 ( 0.6199220419 -1.7028552294 3.0584046841 ) - weight 76 6 0.4873141348 ( 1.9641122818 5.6813688278 4.0823397636 ) - weight 77 5 0.1060663685 ( 5.5780282021 17.7024021149 -4.605817318 ) - weight 78 7 0.3494953811 ( -1.5776381493 2.9995830059 2.3893027306 ) - weight 79 8 0.0571241342 ( -1.5330485106 -2.0968537331 2.3964548111 ) - weight 80 6 0.4873141348 ( -0.3013328612 5.9892659187 4.0416998863 ) - weight 81 5 0.1060663685 ( 6.6243243217 18.7708015442 -2.8759377003 ) - weight 82 7 0.1878687739 ( -1.9319030046 -1.4930874109 2.393882513 ) - weight 83 6 0.5431468487 ( -1.741746068 2.5706710815 1.4827879667 ) - weight 84 5 0.2689843774 ( 3.2996952534 19.3603000641 0.1088482067 ) - weight 85 7 0.5011256933 ( -1.456594944 4.4071464539 -0.1252334863 ) - weight 86 8 0.4988742769 ( -1.4420142174 -0.6957237124 -0.122935161 ) - weight 87 7 0.5249263048 ( 0.6222586632 5.0415902138 0.007741862 ) - weight 88 8 0.475073725 ( 0.6227542758 -0.016414145 0.0078448029 ) - weight 89 7 0.4800623953 ( -2.4153130054 1.2322865725 -1.0752211809 ) - weight 90 8 0.0537899099 ( -2.3323965073 -3.8936684132 -1.0619350672 ) - weight 91 6 0.4661476314 ( -2.1984517574 6.9092669487 0.6679038405 ) - weight 92 7 0.2905490696 ( 1.8073853254 0.8656568527 3.0101549625 ) - weight 93 6 0.5260417461 ( 2.5091855526 3.7259614468 2.2043323517 ) - weight 94 5 0.1834091842 ( 2.8697378635 17.8222980499 -4.0595364571 ) - weight 95 7 0.3791610003 ( -1.5808162689 -3.1772892475 -0.7384021282 ) - weight 96 6 0.4677073956 ( -2.4251711369 3.2602276802 -1.9564627409 ) - weight 97 5 0.1531316042 ( 1.7089807987 22.5592727661 0.1937833875 ) - weight 98 7 0.5036625862 ( 2.9108216763 0.8922801614 -1.3845491409 ) - weight 99 6 0.4963374436 ( 2.7182271481 6.4812078476 -1.3868546486 ) - weight 100 7 0.3638229072 ( 1.75063622 -3.3772475719 -1.1255561113 ) - weight 101 6 0.4815303087 ( 0.6160238385 3.1260755062 -3.3782868385 ) - weight 102 5 0.1546468437 ( -0.5027903914 22.3764095306 -2.3287305832 ) - weight 103 7 0.1678375602 ( 1.1521804333 -6.6728992462 -1.5053383112 ) - weight 104 6 0.4213652015 ( -0.8359954357 0.8865969777 -5.4374322891 ) - weight 105 5 0.4107972682 ( -2.7391681671 23.2427425385 0.0401903428 ) - weight 106 7 0.1837866157 ( -1.4152913094 -6.5319981575 -1.5181310177 ) - weight 107 6 0.416490972 ( -3.2429027557 1.1788779497 -4.5811047554 ) - weight 108 5 0.3997223675 ( -1.0496716499 23.6893405914 1.9264776707 ) - weight 109 7 0.3791610003 ( -2.2127685547 -3.6307926178 -1.6257162094 ) - weight 110 6 0.4677073956 ( -3.3078055382 3.5238323212 -2.6939072609 ) - weight 111 5 0.1531316042 ( 1.7266693115 23.5910968781 0.7659527063 ) - weight 112 7 0.3638229072 ( 2.2358968258 -3.8864245415 -2.1053133011 ) - weight 113 6 0.4815303087 ( 0.7632584572 3.3294949532 -4.5579500198 ) - weight 114 5 0.1546468437 ( -1.2172914743 23.3090229034 -2.6014666557 ) - weight 115 6 0.5 ( 0.1155995429 -1.5601656437 -2.5245828629 ) - weight 116 5 0.5 ( -2.7217340469 19.3723430634 0.6699290872 ) - weight 117 5 1 ( -1.0659971237 17.4484367371 2.1444709301 ) - weight 118 6 0.5 ( -2.0709235668 -1.4688818455 -1.8953888416 ) - weight 119 5 0.5 ( -1.3970252275 19.7935276031 2.473495245 ) - weight 120 6 0.6966896653 ( -2.0378599167 1.0884995461 0.1724392623 ) - weight 121 5 0.3033103049 ( 1.5970509052 19.6393127441 1.1211149693 ) - weight 122 7 0.5249263048 ( -0.7978597283 4.5842022896 1.7085199356 ) - weight 123 8 0.475073725 ( -0.7873610854 -0.4982495606 1.7101948261 ) - weight 124 5 1 ( 1.2575666904 14.2139930725 2.7510755062 ) - weight 125 5 1 ( 3.2227299213 15.0173406601 2.331007719 ) - weight 126 5 1 ( 2.2313902378 15.380027771 3.1738255024 ) - weight 127 5 1 ( -3.1864819527 15.1383256912 2.4639122486 ) - weight 128 5 1 ( -1.7753560543 15.3922204971 3.7217018604 ) - weight 129 5 1 ( -1.6201505661 17.0721645355 2.9271759987 ) - weight 130 5 1 ( 3.2743682861 13.1825485229 -0.3018763363 ) - weight 131 5 1 ( 1.8130064011 13.0749416351 -1.7743618488 ) - weight 132 5 1 ( 2.691192627 14.8538961411 -2.9120459557 ) - weight 133 7 0.1878687739 ( -3.4448332787 -3.5566775799 5.4417228699 ) - weight 134 6 0.5431468487 ( -3.0999000072 -0.85477525 2.985594511 ) - weight 135 5 0.2689843774 ( 2.6483256817 16.8914527893 3.1612577438 ) - weight 136 7 0.1878687739 ( -3.397002697 -2.2758014202 5.6093244553 ) - weight 137 6 0.5431468487 ( -2.7072396278 0.0155044869 3.8570604324 ) - weight 138 5 0.2689843774 ( 3.6314072609 16.5676441193 2.3868420124 ) - weight 139 5 1 ( 1.6768172979 17.8368167877 2.2193171978 ) - weight 140 7 0.1878687739 ( -2.3599994183 -1.7826063633 4.5199642181 ) - weight 141 6 0.5431468487 ( -1.8104616404 1.0186555386 3.0235137939 ) - weight 142 5 0.2689843774 ( 3.3664131165 17.3918571472 1.0617867708 ) - weight 143 5 1 ( 4.173763752 15.0714168549 -1.2653129101 ) - weight 144 5 1 ( 3.475836277 15.9433584213 -1.4065577984 ) - weight 145 7 0.2235300392 ( 2.7394030094 -1.0681368113 2.5013728142 ) - weight 146 6 0.6961277723 ( 2.8211665154 2.5067002773 0.3923874497 ) - weight 147 5 0.0803422183 ( 0.7642717361 18.384803772 -3.7164976597 ) - weight 148 7 0.5836595297 ( 2.5317275524 3.1661231518 2.3664588928 ) - weight 149 8 0.3067108989 ( 2.5718054771 -1.8423575163 2.3730349541 ) - weight 150 6 0.1096295714 ( 3.6391115189 5.8493552208 2.8718855381 ) - weight 151 7 0.5249263048 ( 1.5070672035 4.6519842148 1.6140637398 ) - weight 152 8 0.475073725 ( 1.5155906677 -0.3814097345 1.6155047417 ) - weight 153 6 0.0831768736 ( 0.1321668178 -2.4316897392 -0.3260155022 ) - weight 154 5 0.9168231487 ( -1.816161871 17.2534008026 1.2024260759 ) - weight 155 7 0.1692353189 ( 2.2954478264 -3.5839407444 1.4296443462 ) - weight 156 6 0.5233104229 ( 1.5745203495 1.2962656021 -1.7653169632 ) - weight 157 5 0.307454288 ( -0.9625296593 19.8079605103 -2.0831730366 ) - weight 158 7 0.5046935678 ( 2.6985425949 3.728107214 -0.4356541336 ) - weight 159 8 0.495306462 ( 2.7267453671 -1.2866209745 -0.4310051203 ) - weight 160 5 1 ( -0.4396395385 13.5571908951 -1.6527118683 ) - weight 161 5 1 ( -1.4494247437 13.4018945694 -0.8934326768 ) - weight 162 6 0.1456800848 ( 2.4235975742 -3.0623643398 0.5832758546 ) - weight 163 5 0.8543199301 ( -2.49847579 15.3521289825 -0.345096916 ) - weight 164 6 0.0831768736 ( 0.0378030688 -3.4747741222 -0.5638074279 ) - weight 165 5 0.9168231487 ( -2.6020419598 16.8966140747 1.8416209221 ) - weight 166 6 0.1456800848 ( 1.4052219391 -1.9071899652 -0.7484126687 ) - weight 167 5 0.8543199301 ( -2.2572360039 17.3655605316 -0.1639789194 ) - weight 168 5 1 ( -2.5468671322 13.5582675934 2.1878042221 ) - weight 169 5 1 ( -1.5313721895 12.180182457 -0.5699907541 ) - weight 170 5 1 ( -2.0684287548 12.6266307831 1.7649912834 ) - weight 171 5 0.6441458464 ( 2.7278609276 2.1518306732 2.1695785522 ) - weight 172 4 0.3558541834 ( -4.5926356316 22.5357398987 0.997985363 ) - weight 173 5 0.6754188538 ( 3.1508452892 2.5657637119 -0.3770811558 ) - weight 174 4 0.3245811462 ( -2.158752203 23.4832820892 0.8792029023 ) - weight 175 5 0.9386656284 ( 2.4967861176 4.2872395515 2.6011621952 ) - weight 176 4 0.0613344125 ( -5.5001029968 24.4821338654 0.5647578835 ) - weight 177 5 1 ( 0.7013505101 16.7211456299 2.9008755684 ) - weight 178 5 0.9386656284 ( 2.7524647713 5.174726963 1.9018158913 ) - weight 179 4 0.0613344125 ( -4.9750938416 25.5148258209 0.5632737279 ) - weight 180 5 0.7058986425 ( 1.7502532005 4.8893461227 -0.4799583554 ) - weight 181 4 0.2941013873 ( -2.7721064091 25.5124378204 -0.8171461821 ) - weight 182 5 0.7058986425 ( 3.0194499493 5.0543651581 -0.2718565762 ) - weight 183 4 0.2941013873 ( -2.8112621307 25.8492622375 0.4344180524 ) - weight 184 5 0.7882302999 ( 1.5361274481 4.9476194382 -1.84223032 ) - weight 185 4 0.211769715 ( -1.5036495924 25.7864971161 -1.2871870995 ) - weight 186 5 0.9187178016 ( -0.236244157 4.9261798859 -1.6848590374 ) - weight 187 4 0.0812822357 ( -1.9256629944 25.434803009 -2.9797418118 ) - weight 188 5 1 ( 3.2777893543 13.3646116257 1.5480787754 ) - weight 189 5 1 ( 2.854691267 14.2326364517 1.3125208616 ) - weight 190 5 1 ( -0.2975830436 12.7496728897 -2.3175909519 ) - weight 191 5 1 ( -0.2374247909 10.8279714584 -1.9541374445 ) - weight 192 5 0.1274539977 ( 3.7350518703 -3.7936515808 -0.1493276954 ) - weight 193 4 0.8725460172 ( -0.9318772554 17.3868427277 2.3501017094 ) - weight 194 4 1 ( 1.8304656744 17.6557636261 -1.4042714834 ) - weight 195 4 1 ( 1.984677434 18.6847667694 0.2954209149 ) - weight 196 5 0.7428333163 ( 0.0346176885 0.0930861458 -2.8943650723 ) - weight 197 4 0.2571666539 ( 0.313593775 21.0300121307 -2.2879252434 ) - weight 198 5 0.5807925463 ( 1.897177577 0.8901851177 -3.0070285797 ) - weight 199 4 0.4192074835 ( 0.5410717726 22.1392421722 -0.6041640043 ) - weight 200 5 0.0764129907 ( 4.5442404747 -3.0068583488 -0.2687218189 ) - weight 201 4 0.9235870242 ( -0.8590193391 18.3081092834 3.0089211464 ) - weight 202 5 1 ( 2.4274702072 15.7503805161 -2.5108332634 ) - weight 203 6 0.1456800848 ( 2.4751031399 0.0577870458 -0.1804649532 ) - weight 204 5 0.8543199301 ( -1.0422794819 17.6058139801 -2.1119277477 ) - weight 205 5 1 ( -2.3612496853 10.4881496429 5.0398783684 ) - weight 206 5 1 ( 0.9914241433 10.349407196 3.9973475933 ) - weight 207 5 1 ( -0.7869594097 12.8352861404 3.1171131134 ) - weight 208 5 1 ( 0.7855074406 12.6755657196 2.6946597099 ) - weight 209 5 0.7223932147 ( -2.2529606819 5.4064440727 5.6656012535 ) - weight 210 4 0.2776068151 ( -9.4311571121 24.1852092743 -3.6378781796 ) - weight 211 5 0.9386656284 ( 0.4089305401 6.7861819267 5.063647747 ) - weight 212 4 0.0613344125 ( -8.7320079803 26.0854892731 -1.3461933136 ) - weight 213 5 1 ( -2.9314472675 8.8499107361 5.4597048759 ) - weight 214 5 1 ( 2.7366597652 11.0486335754 1.8867264986 ) - weight 215 5 1 ( -3.1793384552 10.3020086288 0.3344196081 ) - weight 216 5 1 ( -3.8899297714 10.4614372253 2.8776609898 ) - weight 217 5 0.6364896894 ( -4.7696485519 5.2434587479 3.5497655869 ) - weight 218 4 0.3635103405 ( -7.745595932 23.993932724 -6.4591083527 ) - weight 219 5 1 ( -4.6681127548 8.8292016983 3.5580010414 ) - weight 220 5 0.9187178016 ( -2.5629706383 8.3531913757 -0.8516231775 ) - weight 221 4 0.0812822357 ( -3.8208782673 28.1994228363 -5.5521697998 ) - weight 222 5 1 ( 3.5463733673 12.792014122 -0.366117686 ) - weight 223 5 1 ( 2.9208080769 10.1991100311 0.1929748058 ) - weight 224 5 1 ( 1.8076323271 12.5073652267 -2.2356123924 ) - weight 225 5 1 ( 1.3574851751 10.0735054016 -1.6403418779 ) - weight 226 5 0.9466009736 ( 3.4651329517 6.830303669 0.9585307837 ) - weight 227 4 0.0533989966 ( -4.307703495 27.4139881134 0.857196331 ) - weight 228 5 0.4464862049 ( -0.1908811778 -0.3789134026 4.4578361511 ) - weight 229 4 0.5535137653 ( -6.7128286362 19.1634864807 -1.0738557577 ) - weight 230 5 0.2686306834 ( 2.3580155373 -2.271697998 3.2768042088 ) - weight 231 4 0.7313693166 ( -4.7748150826 17.9860649109 1.4425165653 ) - weight 232 5 0.4192591608 ( 2.2613904476 -0.5098884106 3.3391191959 ) - weight 233 4 0.580740869 ( -5.2255716324 19.6627254486 1.1218546629 ) - weight 234 3 0.1034077033 ( 1.8285499811 -16.5847930908 0.3800151944 ) - weight 235 4 0.896592319 ( 0.7349757552 14.0286598206 -5.6954598427 ) - weight 236 3 0.0991234705 ( 3.4762499332 -19.5002632141 -3.4779047966 ) - weight 237 5 0.1427565664 ( -4.9235186577 -2.5790815353 0.8212569356 ) - weight 238 4 0.7581199408 ( -3.4694919586 16.9076290131 -6.0593528748 ) - weight 239 5 0.5029425621 ( -3.8357784748 -0.3178263903 -0.9095681906 ) - weight 240 4 0.4970574677 ( -2.1134195328 19.6035728455 -5.629049778 ) - weight 241 5 0.3234854639 ( -3.1243703365 -0.4504140019 2.9183681011 ) - weight 242 4 0.6765145659 ( -5.667371273 18.8822917938 -4.2056894302 ) - weight 243 5 0.4464862049 ( -0.4896158278 1.389500618 5.0816698074 ) - weight 244 4 0.5535137653 ( -7.7379813194 20.7074012756 -1.4874835014 ) - weight 245 5 0.6364896894 ( -3.6925430298 1.9902536869 3.3919715881 ) - weight 246 4 0.3635103405 ( -6.7327232361 21.0588531494 -5.0004119873 ) - weight 247 3 0.0679782704 ( 4.6116900444 -16.5367126465 -5.5437746048 ) - weight 248 4 0.9320217371 ( -5.7906565666 14.0446987152 -5.190155983 ) - weight 249 4 1 ( -7.2585186958 15.5527744293 -2.2463724613 ) - weight 250 5 0.6878629923 ( 1.9960228205 1.3573014736 3.807847023 ) - weight 251 4 0.3121370375 ( -6.1169934273 21.3368263245 0.6984450817 ) - weight 252 5 0.4718588889 ( 4.1646060944 0.8772957921 -0.3499240279 ) - weight 253 4 0.5281411409 ( -1.6677527428 22.0169620514 2.0991201401 ) - weight 254 5 0.053799402 ( 2.8294627666 -5.1324739456 4.281560421 ) - weight 255 4 0.9462006092 ( -5.0609407425 15.1107807159 2.4753329754 ) - weight 256 3 0.0560320839 ( 10.5247402191 -16.245344162 2.2468152046 ) - weight 257 4 0.9439678788 ( -0.6044585705 15.3047018051 3.0109472275 ) - weight 258 4 1 ( -4.7203769684 7.5207357407 0.2110334039 ) - weight 259 3 0.0739362165 ( 9.0113201141 -7.0935401917 0.4436051846 ) - weight 260 17 0.0861107036 ( 9.1332969666 -7.4799513817 -2.1029090881 ) - weight 261 4 0.8399530649 ( -1.712506175 5.9262194633 2.6735551357 ) - weight 262 3 0.2247006595 ( 4.079100132 -4.1766815186 4.2738552094 ) - weight 263 18 0.0643688887 ( 4.1608572006 -6.6038208008 -2.2779564857 ) - weight 264 17 0.118977949 ( 4.4290904999 -5.6385622025 2.5859494209 ) - weight 265 4 0.5919525027 ( 3.6317486763 2.4848442078 0.008681885 ) - weight 266 3 0.2129372805 ( 1.9173300266 -6.228061676 3.7980952263 ) - weight 267 17 0.0829416811 ( 2.2435736656 -7.5449719429 1.7511575222 ) - weight 268 4 0.7041210532 ( 3.9450414181 4.1003141403 -2.5211129189 ) - weight 269 3 0.1179350466 ( 4.7489600182 -10.6977920532 4.4494051933 ) - weight 270 17 0.0683260411 ( 5.1079230309 -12.0005292892 1.1475549936 ) - weight 271 4 0.8137389421 ( 3.5291645527 9.021062851 -0.5126043558 ) - weight 272 3 0.2110836059 ( 0.9472100139 -7.9706916809 3.3553352356 ) - weight 273 17 0.078609392 ( 1.2496364117 -9.1431827545 0.9563370943 ) - weight 274 4 0.7103070617 ( 3.8676507473 5.6174354553 -3.8872327805 ) - weight 275 3 0.2587772906 ( 0 -8.2653121948 3.4104752541 ) - weight 276 10 0.1301027685 ( -4.2554922104 5.750685215 -4.790312767 ) - weight 277 17 0.0880951136 ( 0.3071537614 -9.455488205 0.9915534258 ) - weight 278 4 0.5230247974 ( 4.2540493011 5.7496142387 -4.7929224968 ) - weight 279 3 0.195755437 ( 0 -8.446269989 1.318975091 ) - weight 280 10 0.0685061365 ( -2.299695015 5.7834682465 -5.5524816513 ) - weight 281 17 0.0703611895 ( 0.187089175 -9.1280288696 -1.0785849094 ) - weight 282 4 0.6653772593 ( 2.2979083061 5.7825641632 -5.5542016029 ) - weight 283 3 0.1514492929 ( 1.0451300144 -8.0715408325 1.4885851145 ) - weight 284 17 0.0546934046 ( 1.2402323484 -8.7906808853 -0.8821863532 ) - weight 285 4 0.793857336 ( 2.0872330666 5.6038837433 -4.4655437469 ) - weight 286 3 0.1273640245 ( 0 -7.7240333557 -1.6977348328 ) - weight 287 10 0.3696421683 ( 0.516869247 4.864238739 -6.4712567329 ) - weight 288 17 0.0626992956 ( 0.0139120175 -7.7014327049 -3.8275845051 ) - weight 289 4 0.4402945042 ( -0.5191946626 4.8635959625 -6.4715852737 ) - weight 290 3 0.2216161489 ( 0 -7.6111412048 -4.0704946518 ) - weight 291 10 0.1496277452 ( 2.7342493534 4.5886597633 -7.2774925232 ) - weight 292 17 0.1156710908 ( -0.122298561 -7.0211253166 -6.0994477272 ) - weight 293 4 0.5130850077 ( -2.7369785309 4.5882129669 -7.2767763138 ) - weight 294 3 0.1491072923 ( 0.7362200022 -7.9641609192 -3.9595546722 ) - weight 295 17 0.0904275626 ( 0.619075954 -7.3802480698 -6.1180272102 ) - weight 296 4 0.7604651451 ( -2.8961083889 5.0682330132 -6.6262311935 ) - weight 297 3 0.0598057099 ( 4.7044801712 -9.3245429993 -5.5001549721 ) - weight 298 17 0.0538356081 ( 4.4923524857 -8.275094986 -8.1596336365 ) - weight 299 4 0.8863587379 ( -5.7507591248 6.9742064476 -3.764516592 ) - weight 300 3 0.3716317713 ( 2.3271501064 -4.636882782 4.4688053131 ) - weight 301 18 0.1213932484 ( 2.4089069366 -7.0640220642 -2.083006382 ) - weight 302 17 0.1563836187 ( 2.6912207603 -6.1563310623 2.7615749836 ) - weight 303 4 0.3505913913 ( 4.4337148666 2.652479887 -1.6185451746 ) - weight 304 3 0.1881700307 ( 0 -5.4316215515 -5.9888248444 ) - weight 305 10 0.3119108975 ( 4.5175871849 2.313141346 -7.5458564758 ) - weight 306 17 0.1955161542 ( -0.2324221581 -4.4443793297 -7.4330706596 ) - weight 307 4 0.3044028878 ( -4.5207343102 2.3128957748 -7.5440654755 ) - weight 308 3 0.3642802238 ( 0 -4.7954101563 5.9942350388 ) - weight 309 18 0.1686480939 ( 0.0817569122 -7.2225494385 -0.5575766563 ) - weight 310 10 0.2480384856 ( -6.6861777306 2.5190677643 -3.252635479 ) - weight 311 17 0.1583780795 ( 0.4554769695 -6.709300518 4.3310875893 ) - weight 312 4 0.0606551506 ( 6.6850166321 2.5178563595 -3.2559857368 ) - weight 313 3 0.3638873994 ( 0 -7.5076408386 4.7202653885 ) - weight 314 18 0.0927037746 ( 0.0817569122 -9.9347801208 -1.8315463066 ) - weight 315 10 0.3552671075 ( -5.4831905365 5.0967707634 -4.1946883202 ) - weight 316 17 0.1111477315 ( 0.3823435307 -9.0351924896 2.4432125092 ) - weight 317 4 0.0769940317 ( 5.4819345474 5.0956082344 -4.197783947 ) - weight 318 5 0.6407039165 ( -4.4538583755 2.1888995171 1.32033813 ) - weight 319 4 0.3592960536 ( -4.8947649002 21.5079479218 -6.1540799141 ) - weight 320 5 0.7223932147 ( -2.1729876995 3.5294866562 4.5672168732 ) - weight 321 4 0.2776068151 ( -7.9590129852 22.587562561 -3.5108659267 ) - weight 322 5 0.6364896894 ( -4.1871986389 3.9582738876 2.6030676365 ) - weight 323 4 0.3635103405 ( -6.4680523872 23.0260944366 -5.8948779106 ) - weight 324 5 0.7932439446 ( -0.1989620924 3.4920659065 4.7679481506 ) - weight 325 4 0.2067560852 ( -7.838619709 22.8498210907 -1.5474004745 ) - weight 326 5 0.7428333163 ( -1.1365029812 1.570915699 -2.4168467522 ) - weight 327 4 0.2571666837 ( -0.6437100172 22.1716003418 -3.5384733677 ) - weight 328 5 0.9187178016 ( -2.5107607841 4.2435569763 -0.4669108987 ) - weight 329 4 0.0812822357 ( -3.3076016903 24.1600646973 -4.8739657402 ) - weight 330 5 0.9187178016 ( -2.7076752186 4.9531168938 -1.7398343086 ) - weight 331 4 0.0812822357 ( -2.2615361214 25.0505714417 -5.3986825943 ) - weight 332 5 0.9187178016 ( -4.0131053925 5.639503479 -0.7921165228 ) - weight 333 4 0.0812822357 ( -3.5244710445 25.3157978058 -6.585313797 ) - weight 334 5 1 ( -1.9448297024 6.7114286423 -2.0899279118 ) - weight 335 5 0.9187178016 ( -3.6335773468 7.4648041725 -0.7714256048 ) - weight 336 4 0.0812822357 ( -3.8747928143 27.1426792145 -6.4589505196 ) - weight 337 5 0.7932439446 ( 1.6315803528 3.8475811481 5.2334136963 ) - weight 338 4 0.2067560852 ( -8.0796251297 23.4184837341 0.2726194859 ) - weight 339 5 0.6928315163 ( 1.4923386574 2.1785550117 5.2045512199 ) - weight 340 4 0.3071684539 ( -7.7174897194 21.7852268219 0.3574346006 ) - weight 341 5 0.9386656284 ( 3.2008824348 4.1371994019 3.8414530754 ) - weight 342 4 0.0613344125 ( -6.5553636551 24.2254085541 1.5012949705 ) - weight 343 5 0.6878629923 ( 3.0460882187 1.9702942371 3.672960043 ) - weight 344 4 0.3121370375 ( -5.9547877312 22.1338024139 1.6122883558 ) - weight 345 5 0.9187178016 ( -3.8820462227 7.4429960251 0.2457889766 ) - weight 346 4 0.0812822357 ( -4.8898935318 26.8895511627 -6.5082945824 ) - weight 347 5 1 ( -0.5467959046 6.9947953224 -1.5470839739 ) - weight 348 5 0.9187178016 ( -3.9937455654 5.2372570038 0.1720338166 ) - weight 349 4 0.0812822357 ( -4.3657417297 24.7500305176 -6.3324627876 ) - weight 350 5 0.6928315163 ( 0.5123724341 2.1260225773 4.847137928 ) - weight 351 4 0.3071684539 ( -7.5134487152 21.6343097687 -0.6556939483 ) - weight 352 5 0.9386656284 ( 1.857170105 5.1011123657 4.0542292595 ) - weight 353 4 0.0613344125 ( -7.1744680405 24.8897476196 0.102964364 ) - weight 354 5 0.7932439446 ( 0.5991621017 4.655983448 4.6730318069 ) - weight 355 4 0.2067560852 ( -7.8715023994 24.1295452118 -0.9457846284 ) - weight 356 5 1 ( -1.3248393536 13.7199192047 3.555103302 ) - weight 357 5 0.7882302999 ( 1.5251891613 2.5039641857 -2.1349527836 ) - weight 358 4 0.2117697299 ( -0.7019255757 23.4747600555 -1.0219211578 ) - weight 359 7 0.1878687739 ( -2.104678154 -1.0625439882 5.8598227501 ) - weight 360 6 0.5431468487 ( -1.1329863071 0.6955801249 4.3709368706 ) - weight 361 5 0.2689843774 ( 3.7972447872 15.9523229599 0.7139032483 ) - weight 362 6 0.1456800848 ( 3.5740437508 -2.7338397503 1.4819729328 ) - weight 363 5 0.8543199301 ( -2.1355040073 14.4210252762 -1.4588339329 ) - weight 364 5 1 ( -0.9918316603 14.5103340149 -2.7648191452 ) - weight 365 6 0.1456800848 ( 3.4609808922 -1.7974903584 -0.1559256762 ) - weight 366 5 0.8543199301 ( -2.5884375572 16.1951560974 -1.9274060726 ) - weight 367 6 0.1456800848 ( 4.0167298317 -0.5935641527 0.9252431393 ) - weight 368 5 0.8543199301 ( -1.3163084984 15.8349695206 -3.013304472 ) - weight 369 3 0.1879103929 ( 8.1206798553 -3.2090530396 0.8102852106 ) - weight 370 17 0.1970130503 ( 8.2651758194 -3.81041646 -0.7620831132 ) - weight 371 4 0.6150766015 ( -1.0363560915 1.9816988707 2.6961772442 ) - weight 372 3 0.2795987427 ( 1.9693599939 2.7528877258 6.4345850945 ) - weight 373 18 0.2394046038 ( 2.0511169434 0.3257484436 -0.1172266006 ) - weight 374 17 0.2705895603 ( 2.4468679428 0.5379494429 6.4666953087 ) - weight 375 22 0.0606285706 ( 1.9693599939 -14.1874732971 7.6861214638 ) - weight 376 4 0.0552089736 ( 6.4313297272 -4.5360994339 0.0946021527 ) - weight 377 19 0.0945695937 ( 1.9693599939 -5.6232032776 8.9033670425 ) - weight 378 3 0.1849493384 ( 0 2.7365379333 6.6083450317 ) - weight 379 18 0.3242035806 ( 0.0817569122 0.3093986511 0.0565333366 ) - weight 380 17 0.2736625969 ( 0.4907305539 0.4530467391 6.7408413887 ) - weight 381 22 0.0876600891 ( 0 -14.2038230896 7.8598814011 ) - weight 382 19 0.1295244098 ( 0 -5.6242175102 9.0778913498 ) - weight 383 3 0.410590291 ( 0 -0.450302124 6.6337952614 ) - weight 384 18 0.2185405195 ( 0.0817569122 -2.8774414063 0.0819835663 ) - weight 385 10 0.1001498476 ( -7.3034911156 -1.7077412605 -2.2318470478 ) - weight 386 17 0.2157476395 ( 0.4921915531 -2.6460340023 5.9976763725 ) - weight 387 19 0.0549716577 ( 0 -8.7964868546 9.3833465576 ) - weight 388 3 0.2186862677 ( 5.3479399681 3.3707275391 4.6170454025 ) - weight 389 18 0.1539705843 ( 5.4296970367 0.9435882568 -1.9347662926 ) - weight 390 17 0.3338294923 ( 5.7155389786 1.621506691 4.6662302017 ) - weight 391 22 0.0800246894 ( 5.3479399681 -13.5696334839 5.8685817719 ) - weight 392 4 0.0935320854 ( 3.5358326435 -4.6942200661 2.6813127995 ) - weight 393 19 0.1199568436 ( 5.3479399681 -5.1675047874 7.0385565758 ) - weight 394 3 0.2420700639 ( 8.1792898178 0.6259078979 0.6979751587 ) - weight 395 18 0.0568721816 ( 8.2610464096 -1.8012313843 -5.8538365364 ) - weight 396 17 0.3226864934 ( 8.3172416687 -0.0606041774 0.0498101339 ) - weight 397 4 0.3113427758 ( -1.1451135874 -1.7857388258 3.4155933857 ) - weight 398 19 0.0670284852 ( 8.1792898178 -8.2461633682 3.3759064674 ) - weight 399 3 0.1812586039 ( 7.6562199593 -1.4332427979 -1.4200248718 ) - weight 400 17 0.2627734542 ( 7.6734485626 -1.5568679571 -2.469386816 ) - weight 401 4 0.555967927 ( -2.9487416744 0.0025309771 1.8191459179 ) - weight 402 3 0.1693509668 ( 6.0396299362 -1.0798034668 -5.4591846466 ) - weight 403 17 0.2872132957 ( 5.8276524544 -0.2646254599 -6.2078680992 ) - weight 404 4 0.5434356928 ( -6.1496539116 -0.8999626637 -1.0080014467 ) - weight 405 3 0.3638526201 ( 3.6178998947 0.8198280334 6.5375151634 ) - weight 406 18 0.1646958143 ( 3.6996567249 -1.6073112488 -0.0142965317 ) - weight 407 17 0.2958500087 ( 4.0985980034 -1.3401217461 6.0088362694 ) - weight 408 4 0.109652102 ( 5.9339156151 -2.3482058048 1.290720582 ) - weight 409 19 0.0659494549 ( 3.6178998947 -7.5397348404 9.1758022308 ) - weight 410 5 0.0716839954 ( 4.0966405869 -0.8913480639 -2.4952168465 ) - weight 411 4 0.9283159971 ( 0.7682322264 20.6942310333 1.8724853992 ) - weight 412 3 0.1023400202 ( 7.8418898582 -4.4684715271 -2.0312447548 ) - weight 413 17 0.13692756 ( 7.8237242699 -4.3530917168 -3.8032631874 ) - weight 414 4 0.7607324123 ( -3.5995492935 2.9753084183 1.2193793058 ) - weight 415 3 0.0734095275 ( 6.2762699127 -5.4256515503 -4.842004776 ) - weight 416 17 0.1297186464 ( 6.0993318558 -4.6276316643 -6.6701135635 ) - weight 417 4 0.796871841 ( -5.6759471893 3.4549031258 -1.3741303682 ) - weight 418 3 0.127938062 ( 2.8462500572 -5.969833374 -5.8070545197 ) - weight 419 17 0.1344723105 ( 2.6195688248 -4.9710917473 -7.5451993942 ) - weight 420 4 0.7375895977 ( -5.3633008003 3.3390517235 -4.963186264 ) - weight 421 5 1 ( 1.0077054501 6.9793996811 -2.3599107265 ) - weight 422 5 1 ( 2.6606097221 7.3528084755 -1.0472817421 ) - weight 423 25 1 ( -1.8057914972 5.4797496796 2.8297646046 ) - weight 424 24 0.0607873201 ( -5.2623910904 0.2113772035 -0.391582489 ) - weight 425 25 0.8037958145 ( 0.699169457 4.5157976151 2.6459546089 ) - weight 426 26 0.0549921282 ( 2.0442841053 -6.9243040085 2.6118826866 ) - weight 427 22 0.0804247707 ( 12.8835697174 1.8307189941 0.5161716342 ) - weight 428 25 1 ( 0.3863715529 7.8314619064 2.4720568657 ) - weight 429 25 0.8992074132 ( -0.4728373587 4.9001421928 -1.9778535366 ) - weight 430 22 0.1007925943 ( 10.4430799484 -2.2646942139 0.1008116007 ) - weight 431 25 0.8986232877 ( -3.0746035576 4.1999440193 -1.079303503 ) - weight 432 22 0.1013767645 ( 10.1063604355 -1.4544410706 -2.6004781723 ) - weight 433 25 1 ( -2.1408622265 5.1154699326 -1.6065423489 ) - weight 434 25 0.8999999762 ( -0.1770916283 8.9657888412 -1.3762464523 ) - weight 435 26 0.1000000089 ( 1.2597332001 -2.6555161476 -1.6201722622 ) - weight 436 25 0.75 ( 2.0095024109 10.947353363 1.367511034 ) - weight 437 26 0.2499999851 ( 1.5756622553 -0.3233630657 1.6504925489 ) - weight 438 25 0.75 ( 1.1205120087 11.2561998367 -1.1018426418 ) - weight 439 26 0.2499999851 ( 1.5657202005 -0.1049256474 -0.9830572605 ) - weight 440 26 1 ( 1.2333962917 2.1260302067 -0.9584661722 ) - weight 441 26 1 ( 0.1229579225 6.5931158066 2.1685273647 ) - weight 442 26 1 ( 1.4198451042 2.8058440685 1.4701274633 ) - weight 443 26 1 ( 0.889569521 5.7066898346 0.4998298883 ) - weight 444 26 1 ( 0.9086529016 1.903351903 2.5851452351 ) - weight 445 26 1 ( -0.9120508432 3.0009636879 2.8838543892 ) - weight 446 25 0.5280484557 ( 0.9905132651 11.3301305771 2.8927409649 ) - weight 447 26 0.4719515741 ( 0.0193356462 -0.4070735574 2.6906964779 ) - weight 448 25 0.3612080812 ( -0.4332855046 12.0143699646 3.0084037781 ) - weight 449 26 0.6387919784 ( -1.4927716255 -0.2155229449 2.259878397 ) - weight 450 25 1 ( 2.6559736729 6.5143017769 0.8723558784 ) - weight 451 25 0.8688632846 ( 2.9200022221 4.7868690491 0.8565477729 ) - weight 452 22 0.1311367303 ( 12.3231697083 0.5033569336 2.9923815727 ) - weight 453 25 0.8999999762 ( 2.5827827454 9.7116098404 -0.2932316065 ) - weight 454 26 0.1000000164 ( 3.0627598763 -1.1749874353 0.3554812074 ) - weight 455 25 0.9024001956 ( 2.2561295033 4.7443184853 -1.4634464979 ) - weight 456 22 0.0975997746 ( 10.8985900879 -1.4246940613 2.7129116058 ) - weight 457 25 1 ( 1.4947646856 6.1748747826 -1.8961975574 ) - weight 458 25 0.3708793223 ( -0.4999855161 12.2166490555 -1.5468018055 ) - weight 459 26 0.6291206479 ( -0.0104892915 0.3327885866 -2.0176742077 ) - weight 460 26 1 ( -0.4623274803 3.7104535103 -2.036744833 ) - weight 461 25 0.8000000119 ( -2.4895591736 7.3981394768 1.3431096077 ) - weight 462 26 0.200000003 ( -1.2261711359 -5.0887117386 0.140443176 ) - weight 463 25 0.9000000358 ( -0.6311168671 8.9490613937 2.4359624386 ) - weight 464 26 0.1000000089 ( -0.4778723419 -3.1298334599 1.7702711821 ) - weight 465 25 0.5123454332 ( -2.2409067154 12.3475866318 1.5315147638 ) - weight 466 26 0.4876546264 ( -2.667632103 -0.344211638 0.2195668668 ) - weight 467 25 0.2187086195 ( -2.0160768032 13.2831096649 1.5817422867 ) - weight 468 26 0.7812913656 ( -2.7889912128 0.6070842147 0.3122073114 ) - weight 469 26 1 ( -2.6469573975 3.3637104034 1.359670639 ) - weight 470 24 0.0817779079 ( -4.1295909882 -2.8317828178 -0.5565834045 ) - weight 471 25 0.8301161528 ( -2.4442703724 3.7356910706 2.3604674339 ) - weight 472 22 0.0881059989 ( 11.7507696152 1.6657180786 -2.5269882679 ) - weight 473 26 0.6716382504 ( -1.6709980965 10.1102552414 1.9551123381 ) - weight 474 28 0.3283617496 ( -1.7629814148 -1.2888746262 0.0689950958 ) - weight 475 25 0.9420899749 ( -3.4307696819 5.8847341537 0.0841115788 ) - weight 476 22 0.0579100251 ( 12.1043300629 -1.5341339111 -3.1667585373 ) - weight 477 25 0.5465575457 ( -2.5537569523 12.2840538025 0.0026523962 ) - weight 478 26 0.4534424543 ( -2.3830392361 -0.3755270839 -1.3158022165 ) - weight 479 25 0.9000000358 ( -2.1944980621 8.9424533844 -0.3143043816 ) - weight 480 26 0.1000000089 ( -0.8797691464 -3.3978385925 -1.3562003374 ) - weight 481 26 1 ( -2.3219182491 3.571721077 -1.7433632612 ) - weight 482 26 0.5592964292 ( 0.0663003474 9.7705001831 -0.1009363085 ) - weight 483 28 0.4407036304 ( 0.4115808308 0.2231795043 -0.5191771388 ) - weight 484 25 0.2554214001 ( -2.3227756023 13.2866487503 -0.1159238145 ) - weight 485 26 0.7445786595 ( -2.4610733986 0.6551493406 -1.3808096647 ) - weight 486 27 0.0534318425 ( 0.5995090604 0.8145555854 0.6979750395 ) - weight 487 26 0.4462548494 ( 1.0616884232 9.7390546799 1.2301362753 ) - weight 488 36 0.191060856 ( -0.4247736037 0.6924083829 1.686296463 ) - weight 489 28 0.3092524111 ( 0.2448114008 0.4415536821 1.1203476191 ) - weight 490 26 1 ( -2.7267620564 4.6506662369 -0.5400604606 ) - weight 491 26 0.5768595338 ( -1.2637536526 10.4957399368 0.1802661717 ) - weight 492 28 0.423140496 ( -0.9051367044 -0.216721192 -1.1876330376 ) - weight 493 27 0.0748104453 ( -2.0287647247 -0.3494243026 0.7074637413 ) - weight 494 26 0.2395055592 ( -1.5470763445 10.8531579971 1.6947674751 ) - weight 495 28 0.6856840253 ( -2.0795021057 -0.6103798151 -0.2039500922 ) - weight 496 26 0.5043939948 ( -1.7569200993 10.5042886734 0.6352306008 ) - weight 497 28 0.4956060052 ( -1.3949774504 -0.668292284 -1.1075178385 ) - weight 498 20 0.2104368061 ( 2.9346170425 0.9206390381 -1.3216862679 ) - weight 499 24 0.1395905167 ( 0.6618785858 5.1672673225 -3.748714447 ) - weight 500 22 0.3596084118 ( 6.9593000412 -1.5264129639 5.4720616341 ) - weight 501 19 0.2903642058 ( 6.9593000412 6.7942552567 5.5850467682 ) - weight 502 23 0.0940121636 ( 6.2288618088 3.2766597271 -2.5073685646 ) - weight 503 20 0.2112037539 ( 1.2925667763 2.4400787354 -0.3957061768 ) - weight 504 24 0.1697467417 ( 2.3039288521 6.0932474136 -2.2292747498 ) - weight 505 22 0.3728870749 ( 5.3172497749 -0.0069732666 6.3980417252 ) - weight 506 19 0.152150318 ( 5.3172497749 8.3892021179 6.3738937378 ) - weight 507 20 0.2617237568 ( 1.753177166 -1.3353309631 -0.5282363892 ) - weight 508 24 0.0747493804 ( 1.8433184624 5.9607172012 -6.0046844482 ) - weight 509 17 0.0655012801 ( 6.1675362587 11.0309038162 7.3849802017 ) - weight 510 22 0.3634669483 ( 5.7778601646 -3.7823829651 6.2655115128 ) - weight 511 19 0.2345586121 ( 5.7778601646 4.6167554855 6.5737113953 ) - weight 512 20 0.1555825621 ( -1.28967309 0.0708389282 0.6981534958 ) - weight 513 17 0.058374837 ( 3.2001059055 12.0585689545 9.0816078186 ) - weight 514 22 0.2766284049 ( 2.7350099087 -2.3762130737 7.4919013977 ) - weight 515 21 0.0669329613 ( 6.9873700142 -0.0574874878 0.6981534958 ) - weight 516 19 0.4424812198 ( 2.7350099087 6.125275135 7.6717615128 ) - weight 517 20 0.158964932 ( -4.0246829987 -1.7787399292 0.6243338585 ) - weight 518 18 0.0666702762 ( 0.0817569196 10.2874298096 -0.385266304 ) - weight 519 17 0.0974983945 ( 0.4653686285 10.2434053421 8.7168312073 ) - weight 520 22 0.1818190664 ( 0.0000000039 -4.2257919312 7.4180817604 ) - weight 521 21 0.1431285143 ( 4.2523598671 -1.9070663452 0.6243338585 ) - weight 522 19 0.3519187868 ( 0.0000000039 4.2763662338 7.7607941628 ) - weight 523 20 0.2872291505 ( -1.4900529385 -2.1767807007 0.2234835625 ) - weight 524 17 0.1094022095 ( 2.9728076458 9.9885673523 8.0913124084 ) - weight 525 22 0.2259044498 ( 2.5346300602 -4.6238327026 7.0172314644 ) - weight 526 21 0.0738607794 ( 6.7869901657 -2.3051071167 0.2234835625 ) - weight 527 19 0.3036034107 ( 2.5346300602 3.8446335793 7.3964805603 ) - weight 528 23 0.0918402001 ( 6.0347757339 0.5179898143 -1.5922067165 ) - weight 529 20 0.1768344939 ( -1.2648329735 3.7876701355 -0.755086422 ) - weight 530 24 0.1033061519 ( 4.8613286018 5.7338671684 -0.8816833496 ) - weight 531 22 0.397562623 ( 2.7598500252 1.3406181335 6.0386614799 ) - weight 532 21 0.0633079335 ( 7.0122098923 3.6593437195 -0.755086422 ) - weight 533 19 0.167148605 ( 2.7598500252 9.6999912262 5.897459507 ) - weight 534 20 0.1835365295 ( -4.0246829987 1.078338623 0.4390735626 ) - weight 535 22 0.3235634565 ( 0.0000000011 -1.3687133789 7.2328214645 ) - weight 536 21 0.1393430084 ( 4.2523598671 0.950012207 0.4390735626 ) - weight 537 19 0.3535570502 ( 0.0000000011 7.1061043739 7.3251314163 ) - weight 538 23 0.1228629202 ( 5.3150629997 4.5582141876 -2.0834405422 ) - weight 539 20 0.1074648574 ( 2.6817069054 2.6520309448 -1.2218360901 ) - weight 540 24 0.2040383965 ( 0.914788723 5.2671175003 -2.0173225403 ) - weight 541 25 0.1123785824 ( 4.831612587 0.3368949592 -2.9950358868 ) - weight 542 22 0.3799530566 ( 6.706389904 0.2049789429 5.5719118118 ) - weight 543 19 0.0733022243 ( 6.706389904 8.5277223587 5.5323314667 ) - weight 544 23 0.1540609747 ( 5.0778336525 2.6781880856 0.4881379604 ) - weight 545 20 0.0765600428 ( 1.2587270737 5.4928703308 -1.5513062477 ) - weight 546 24 0.2358609885 ( 2.3377685547 4.9376473427 0.8235168457 ) - weight 547 22 0.465770483 ( 5.2834100723 3.0458183289 5.2424416542 ) - weight 548 19 0.0677475333 ( 5.2834100723 11.3286094666 4.9544444084 ) - weight 549 20 0.0787646174 ( -2.2140431404 7.1359443665 -2.6534161568 ) - weight 550 24 0.2420327365 ( 5.8105387688 3.8355374336 2.4665908813 ) - weight 551 22 0.5372200012 ( 1.8106399775 4.6888923645 4.1403317451 ) - weight 552 19 0.1419826597 ( 1.8106399775 12.8684558868 3.7121837139 ) - weight 553 40 0.056749247 ( -7.6211800575 4.4046597481 1.8957214355 ) - weight 554 20 0.0972060412 ( -4.0246829987 6.5650978088 -2.0842962265 ) - weight 555 24 0.0587999895 ( 7.621178627 4.4046573639 1.8957443237 ) - weight 556 22 0.4545437098 ( -0.0000000446 4.1180458069 4.7094516754 ) - weight 557 21 0.1236807853 ( 4.2523598671 6.4367713928 -2.0842962265 ) - weight 558 19 0.2090202272 ( -0.0000000446 12.3498401642 4.3292751312 ) - weight 559 20 0.1548763067 ( -2.1677229404 -4.8569412231 -0.0008964539 ) - weight 560 18 0.0996189713 ( 1.9387170076 7.2092285156 -1.0104966164 ) - weight 561 17 0.1707363576 ( 2.283374548 7.4319605827 7.2659106255 ) - weight 562 22 0.2051438242 ( 1.8569600582 -7.3039932251 6.7928514481 ) - weight 563 21 0.0677613318 ( 6.1093201637 -4.9852676392 -0.0008964539 ) - weight 564 19 0.3018632233 ( 1.8569600582 1.1551240683 7.4085383415 ) - weight 565 20 0.1842600703 ( 4.0875968933 -0.4923400879 -6.7608261108 ) - weight 566 24 0.0768201277 ( -0.491101265 -0.2718727589 -5.161693573 ) - weight 567 17 0.0615049861 ( 8.1403188705 13.38052845 1.4190165997 ) - weight 568 25 0.0510131679 ( -0.8704104424 3.3902337551 -3.8365001678 ) - weight 569 22 0.3334853351 ( 8.112279892 -2.9393920898 0.0329216719 ) - weight 570 19 0.2929163277 ( 8.112279892 4.908677578 0.2911489308 ) - weight 571 20 0.243614018 ( 2.6115269661 -1.675239563 -3.3389365673 ) - weight 572 17 0.0818250254 ( 6.8631196022 11.3889627457 4.5318598747 ) - weight 573 22 0.3493157327 ( 6.6362099648 -4.1222915649 3.4548113346 ) - weight 574 19 0.3252451718 ( 6.6362099648 4.0311188698 3.8037650585 ) - weight 575 20 0.2450965345 ( 0.946846962 -3.0064620972 -0.6592960358 ) - weight 576 18 0.0501337275 ( 5.0532870293 9.0597076416 -1.6688961983 ) - weight 577 17 0.1160457954 ( 5.35501194 9.4293746948 6.9002799988 ) - weight 578 22 0.2894206345 ( 4.9715299606 -5.4535140991 6.1344518661 ) - weight 579 19 0.2993033528 ( 4.9715299606 2.9405722618 6.5900411606 ) - weight 580 20 0.19186306 ( 2.6019868851 -3.6352996826 -3.8948161602 ) - weight 581 17 0.1432489753 ( 6.8216843605 9.6202230453 3.5215280056 ) - weight 582 22 0.347635448 ( 6.6266698837 -6.0823516846 2.8989317417 ) - weight 583 19 0.3172525764 ( 6.6266698837 2.0297861099 3.4223139286 ) - weight 584 24 0.0640168265 ( -1.09745121 -0.5379728079 -4.7699050903 ) - weight 585 25 0.4718873501 ( -1.0204299688 3.6624834538 -3.1326949596 ) - weight 586 22 0.3388321102 ( 8.718629837 -2.5476036072 -0.2331783772 ) - weight 587 19 0.1252637058 ( 8.718629837 5.2755613327 -0.0083570555 ) - weight 588 20 0.201011315 ( 3.5163969994 1.3848800659 -3.0210163593 ) - weight 589 24 0.0857693925 ( 0.080098629 3.4679369926 -3.2844734192 ) - weight 590 25 0.2306322753 ( 2.9894869328 1.77917099 -3.2516310215 ) - weight 591 22 0.3318935037 ( 7.541079998 -1.062171936 3.7727315426 ) - weight 592 19 0.1506935209 ( 7.541079998 7.1073389053 3.8514893055 ) - weight 593 25 0.8331401944 ( 2.4343247414 3.9572303295 -1.3264718056 ) - weight 594 22 0.1668597758 ( 10.3534202576 -0.8371734619 2.8791415691 ) - weight 595 25 0.7959624529 ( 0.4169529974 4.1534180641 -2.0459644794 ) - weight 596 22 0.2040375024 ( 9.8898496628 -1.7785720825 1.0016915798 ) - weight 597 20 0.0681952983 ( 5.874007225 2.0633087158 -3.2335062027 ) - weight 598 24 0.0738774687 ( -2.2775115967 3.2554471493 -2.6060447693 ) - weight 599 25 0.6116636992 ( 3.1137094498 3.3132555485 -1.3294196129 ) - weight 600 22 0.193616733 ( 9.8986902237 -0.3837432861 3.5602416992 ) - weight 601 19 0.0526468344 ( 9.8986902237 7.764465332 3.5801920891 ) - weight 602 23 0.0688558817 ( 2.924271822 8.4479007721 -0.2393156886 ) - weight 603 24 0.0820177272 ( -3.3664216995 3.1473970413 -0.8238525391 ) - weight 604 25 0.6934348941 ( 3.3416187763 3.1725318432 0.7446737289 ) - weight 605 22 0.1556914747 ( 10.9876003265 1.3984489441 3.4521915913 ) - weight 606 23 0.0840814263 ( 3.6347248554 7.8946933746 0.8604786992 ) - weight 607 24 0.1270969361 ( -2.9526510239 3.8326470852 0.350692749 ) - weight 608 25 0.589654386 ( 4.1179738045 2.1448817253 1.3459540606 ) - weight 609 22 0.1991672963 ( 10.5738296509 2.5729942322 4.1374416351 ) - weight 610 24 0.1135665625 ( -4.4194612503 -0.4394327402 1.3595809937 ) - weight 611 25 0.7514148951 ( 0.1823620647 2.8259165287 3.6841597557 ) - weight 612 22 0.1350185126 ( 12.0406398773 3.5818824768 -0.1346383095 ) - weight 613 24 0.1358478814 ( -3.2964611053 -2.3047628403 0.6204376221 ) - weight 614 25 0.7201118469 ( -1.8683185577 2.3670701981 2.7508392334 ) - weight 615 22 0.1440403163 ( 10.9176397324 2.8427391052 -1.9999682903 ) - weight 616 24 0.1038469896 ( -4.3386716843 1.946947217 0.4851913452 ) - weight 617 25 0.7552931905 ( 2.4211442471 3.2276699543 2.5473473072 ) - weight 618 22 0.1408598125 ( 11.9598503113 2.7074928284 2.2517416477 ) - weight 619 23 0.0560161285 ( 2.0771822929 8.3642549515 1.7806239128 ) - weight 620 24 0.1561784446 ( -3.6632509232 2.3176870346 1.1831817627 ) - weight 621 25 0.6057688594 ( 2.8008503914 2.267198801 2.6663017273 ) - weight 622 22 0.1820365787 ( 11.2844295502 3.4054832458 2.6224815845 ) - weight 623 24 0.1756464243 ( -3.8119211197 0.1195671558 1.912361145 ) - weight 624 25 0.6305294037 ( 0.7372195721 2.0017898083 3.694175005 ) - weight 625 22 0.1938241869 ( 11.4330997467 4.1346626282 0.4243615866 ) - weight 626 20 0.1253100932 ( 4.8970870972 1.3132781982 -4.3805861473 ) - weight 627 25 0.4839760363 ( 1.7859374285 2.9684195518 -2.3045201302 ) - weight 628 22 0.2676346898 ( 8.9217700958 -1.1337738037 2.4131615162 ) - weight 629 19 0.1230791807 ( 8.9217700958 6.916516304 2.503474474 ) - weight 630 24 0.0967348367 ( -1.6407709122 -1.7257128954 -3.471534729 ) - weight 631 25 0.6512354612 ( -1.9752682447 3.3737258911 -1.5846021175 ) - weight 632 22 0.180927977 ( 9.2619495392 -1.2492332458 -1.4209184647 ) - weight 633 19 0.0711017624 ( 9.2619495392 6.4645118713 -1.3056191206 ) - weight 634 24 0.1041585356 ( -1.9966812134 -3.4164330959 -1.3928833008 ) - weight 635 25 0.7479298711 ( -3.3505475521 2.4888799191 0.5675254464 ) - weight 636 22 0.147911638 ( 9.6178598404 0.8294181824 -3.111638546 ) - weight 637 24 0.1259333193 ( -1.0042209625 -3.0659229755 -2.195892334 ) - weight 638 25 0.5319606066 ( -3.2087612152 2.1381547451 -0.701153636 ) - weight 639 22 0.2778026462 ( 8.6253995895 0.0264091492 -2.7611284256 ) - weight 640 19 0.0643034428 ( 8.6253995895 7.6174211502 -2.7527635098 ) - weight 641 24 0.0655119568 ( -1.1221809387 0.8254870772 -3.6436424255 ) - weight 642 25 0.587156117 ( 0.4658185542 3.0096256733 -2.4305951595 ) - weight 643 22 0.2731430233 ( 8.7433595657 -1.4213409424 1.1302814484 ) - weight 644 19 0.0741889477 ( 8.7433595657 6.5173048973 1.2508345842 ) - weight 645 23 0.0959173739 ( 4.6711220741 4.8067708015 -1.3537731171 ) - weight 646 20 0.0971729085 ( 3.0852370262 3.3321304321 -1.8410961628 ) - weight 647 24 0.2226695716 ( 0.5112586021 4.6478571892 -1.337223053 ) - weight 648 25 0.1994424909 ( 4.3469529152 0.2826055288 -2.1169626713 ) - weight 649 22 0.3847976625 ( 7.1099200249 0.8850784302 4.9526515007 ) - weight 650 23 0.0856437981 ( 4.0311717987 6.5106563568 -1.6418874264 ) - weight 651 24 0.1542672366 ( -1.1617517471 4.1144471169 -1.8960456848 ) - weight 652 25 0.4562948942 ( 3.9298620224 1.9788918495 -1.5300893784 ) - weight 653 22 0.3037941158 ( 8.7829303741 0.3262557983 4.4192414284 ) - weight 654 23 0.0719581246 ( -1.8160912991 5.5418410301 2.96114254 ) - weight 655 24 0.2809319496 ( -1.3237409592 -1.7345126867 2.8029327393 ) - weight 656 25 0.3640708923 ( -1.2474185228 -0.5132326484 3.2971308231 ) - weight 657 22 0.2830390632 ( 8.9449195862 5.0252342224 -1.429718256 ) - weight 658 24 0.1750897914 ( -3.0472517014 -1.8818126917 1.9183349609 ) - weight 659 25 0.6372856498 ( -1.3181471825 1.406490922 3.5875761509 ) - weight 660 22 0.1876246035 ( 10.6684303284 4.1406364441 -1.577018261 ) - weight 661 24 0.2244457453 ( -0.9760417938 -3.2124330997 0.9799041748 ) - weight 662 25 0.5226775408 ( -2.9664721489 0.2809490263 1.8678979874 ) - weight 663 22 0.2528767288 ( 8.5972204208 3.202205658 -2.9076385498 ) - weight 664 23 0.1007315144 ( 0.8902480006 2.287992239 3.7238340378 ) - weight 665 24 0.3619578183 ( 1.9324884415 0.7674973607 4.0798110962 ) - weight 666 22 0.5373107195 ( 5.6886901855 6.3021125793 1.0722917318 ) - weight 667 24 0.3483259678 ( 3.9891486168 0.7001771927 4.4768295288 ) - weight 668 22 0.6516740322 ( 3.6320300102 6.699131012 1.0049716234 ) - weight 669 23 0.1211490557 ( 2.7652511597 2.5030479431 3.116527319 ) - weight 670 24 0.3135183454 ( 1.9389486313 2.6459772587 3.4457931519 ) - weight 671 22 0.5653325915 ( 5.6822299957 5.668094635 2.9507715702 ) - weight 672 40 0.1206549853 ( -7.6211800575 -1.9558200836 4.5684204102 ) - weight 673 24 0.2468876839 ( 7.621178627 -1.9558228254 4.5684432983 ) - weight 674 22 0.6324573159 ( -0.0000001187 6.7907447815 -1.6510283947 ) - weight 675 24 0.3476862311 ( 5.0265684128 -1.0432327986 4.6311035156 ) - weight 676 22 0.6523137689 ( 2.5946099758 6.8534049988 -0.7384383678 ) - weight 677 23 0.1838343889 ( -3.1084904671 0.4851455092 2.8909130096 ) - weight 678 24 0.2588930726 ( 3.5847086906 -3.3460726738 3.5481796265 ) - weight 679 22 0.557272613 ( 4.0364699364 5.7704811096 -3.0412783623 ) - weight 680 23 0.1532030255 ( -5.0335879326 -3.0746033192 -1.1796858311 ) - weight 681 40 0.1250952035 ( -7.6211800575 -5.5354204178 0.1041412354 ) - weight 682 24 0.1344639808 ( 7.621178627 -5.535422802 0.1041641235 ) - weight 683 22 0.4825930893 ( -0.00000006 2.3264656067 -5.2306284904 ) - weight 684 19 0.1046447232 ( -0.00000006 9.6915225983 -5.4148669243 ) - weight 685 23 0.1499707699 ( 2.1735146046 4.4499354362 3.0411651134 ) - weight 686 24 0.3624812961 ( -0.0044913292 2.1783173084 3.057800293 ) - weight 687 25 0.0957007706 ( 2.5045313835 -1.7990114689 2.1201601028 ) - weight 688 22 0.3918471634 ( 7.6256699562 5.2801017761 2.4831116199 ) - weight 689 23 0.1247226298 ( 4.3769903183 4.5209698677 1.4115442038 ) - weight 690 20 0.0661666319 ( 3.2672071457 6.1073722839 -2.1241061687 ) - weight 691 24 0.3122898638 ( 0.3292884827 4.3648471832 1.4380187988 ) - weight 692 25 0.1047990248 ( 4.4277219772 -1.1693739891 0.2705898583 ) - weight 693 22 0.3920218647 ( 7.2918901443 3.660320282 4.6696414948 ) - weight 694 23 0.1146829724 ( -1.1264588833 4.0224151611 2.7906820774 ) - weight 695 24 0.3696548045 ( 0.2445087433 -1.1445628405 2.8794555664 ) - weight 696 25 0.0813261494 ( -0.8226075768 -1.8460566998 2.371701479 ) - weight 697 22 0.4343360364 ( 7.3766698837 5.1017570496 -0.8397684097 ) - weight 698 3 0.1475392133 ( 6.8201799393 4.7823600769 0.5552852154 ) - weight 699 18 0.0640172362 ( 6.9019370079 2.3552207947 -5.9965262413 ) - weight 700 17 0.3788931668 ( 6.9521818161 3.9889273643 0.9887138605 ) - weight 701 22 0.1365314722 ( 6.8201799393 -12.158000946 1.8068215847 ) - weight 702 4 0.0695524886 ( -0.7777072787 -6.1126346588 2.88022542 ) - weight 703 19 0.2034664452 ( 6.8201799393 -4.1183390617 2.868442297 ) - weight 704 20 0.0538627617 ( 0.9126567841 -9.3866004944 -1.0557360649 ) - weight 705 3 0.114181459 ( 4.9373397827 5.1067085266 4.4864754677 ) - weight 706 18 0.1328125447 ( 5.0190968513 2.6795692444 -2.0653362274 ) - weight 707 17 0.3192258179 ( 5.2981204987 3.3320755959 4.9808526039 ) - weight 708 22 0.1314626485 ( 4.9373397827 -11.8336524963 5.738011837 ) - weight 709 4 0.0768659338 ( 3.5671958923 -6.479572773 2.5773737431 ) - weight 710 19 0.1715888679 ( 4.9373397827 -3.4497187138 6.7559099197 ) - weight 711 20 0.1665703803 ( 0.6660971642 -4.8628616333 -0.6275062561 ) - weight 712 18 0.0854403004 ( 4.7725372314 7.2033081055 -1.6371064186 ) - weight 713 17 0.1877293289 ( 5.0765500069 7.6161336899 6.4994506836 ) - weight 714 22 0.2634829283 ( 4.6907801628 -7.3099136353 6.1662416458 ) - weight 715 19 0.2967770994 ( 4.6907801628 1.0941513777 6.7848739624 ) - weight 716 20 0.120076336 ( 2.0508670807 -5.6409988403 -3.2366862297 ) - weight 717 18 0.0528191477 ( 6.157307148 6.4251708984 -4.2462863922 ) - weight 718 17 0.2405500114 ( 6.3092541695 7.5076813698 3.70667696 ) - weight 719 22 0.2564888299 ( 6.0755500793 -8.0880508423 3.5570616722 ) - weight 720 19 0.3300656974 ( 6.0755500793 0.0896949023 4.2541851997 ) - weight 721 20 0.1041463017 ( 3.5877971649 -3.2565002441 -6.9693861008 ) - weight 722 17 0.1671096236 ( 7.6293702126 10.7410516739 0.5787947774 ) - weight 723 22 0.3098323047 ( 7.6124801636 -5.7035522461 -0.1756383181 ) - weight 724 19 0.4189118147 ( 7.6124801636 2.1368839741 0.3263486922 ) - weight 725 20 0.1070277318 ( 0.8172168732 -6.6099510193 -0.7687864304 ) - weight 726 3 0.0618816391 ( 4.8418998718 7.8833580017 4.7734251022 ) - weight 727 18 0.1324060559 ( 4.9236569405 5.4562187195 -1.7783865929 ) - weight 728 17 0.2653489411 ( 5.2193102837 5.9565849304 5.9332022667 ) - weight 729 22 0.2074470818 ( 4.8418998718 -9.0570030212 6.0249614716 ) - weight 730 19 0.2258885652 ( 4.8418998718 -0.6585941911 6.7976989746 ) - weight 731 17 0.3818058968 ( 6.8327636719 6.5366053581 0.507807672 ) - weight 732 22 0.2454663068 ( 6.7629899979 -9.8012428284 0.7211816311 ) - weight 733 19 0.3727278411 ( 6.7629899979 -1.8661230803 1.5798594952 ) - weight 734 20 0.0737030283 ( 1.932487011 -7.5092391968 -2.8866963387 ) - weight 735 3 0.0897874162 ( 5.9571700096 6.9840698242 2.6555151939 ) - weight 736 18 0.0678954646 ( 6.0389270782 4.556930542 -3.8962965012 ) - weight 737 17 0.3082535267 ( 6.2111606598 5.6086540222 3.602265358 ) - weight 738 22 0.1890437752 ( 5.9571700096 -9.9562911987 3.9070515633 ) - weight 739 4 0.0526313446 ( 1.5018496513 -8.278219223 3.2224874496 ) - weight 740 19 0.2186855078 ( 5.9571700096 -1.7405531406 4.7670273781 ) - weight 741 3 0.172700569 ( 1.9684400558 5.3082885742 5.4040851593 ) - weight 742 18 0.2459449619 ( 2.0501968861 2.881149292 -1.1477265358 ) - weight 743 17 0.2929162383 ( 2.3867928982 3.2659332752 6.0839414597 ) - weight 744 22 0.1273532808 ( 1.9684400558 -11.6320724487 6.6556215286 ) - weight 745 19 0.16108495 ( 1.9684400558 -3.1682665348 7.6522507668 ) - weight 746 24 0.0605125986 ( 1.3824486732 -3.3477628231 -8.1791954041 ) - weight 747 17 0.1689686179 ( 6.0932836533 11.1658763885 -2.1839783192 ) - weight 748 22 0.3607285321 ( 6.2387299538 -5.9568939209 -3.0429682732 ) - weight 749 19 0.4097902477 ( 6.2387299538 1.6325021982 -2.5076172352 ) - weight 750 17 0.2895463407 ( 5.9020609856 9.0910482407 -1.9186052084 ) - weight 751 22 0.3117902875 ( 6.0043401718 -7.9066619873 -2.2977383137 ) - weight 752 19 0.3986633718 ( 6.0043401718 -0.2442189455 -1.5938987732 ) - weight 753 23 0.0556329079 ( -2.8664929867 5.0968933105 -4.789255619 ) - weight 754 20 0.0677017048 ( 3.3037071228 -0.1052207947 -9.38027668 ) - weight 755 24 0.0725714639 ( 0.2927885056 -2.8913228512 -4.7745742798 ) - weight 756 17 0.0710932612 ( 7.2073493004 14.3754806519 -0.9821292758 ) - weight 757 25 0.1695101112 ( -3.490899086 2.5686855316 -3.5467398167 ) - weight 758 22 0.3341759443 ( 7.3283901215 -2.5522727966 -2.5865283012 ) - weight 759 19 0.2293145955 ( 7.3283901215 5.0640654564 -2.3521888256 ) - weight 760 23 0.0546624474 ( -4.7111229897 3.8722419739 -4.1596765518 ) - weight 761 24 0.1477607191 ( 1.2790484428 -4.80337286 -3.9559440613 ) - weight 762 17 0.0748926923 ( 6.1129527092 15.6162757874 -2.5826053619 ) - weight 763 25 0.1665531695 ( -5.3819174767 1.3212622404 -3.1383471489 ) - weight 764 22 0.3399968147 ( 6.3421301842 -1.7336425781 -4.4985785484 ) - weight 765 19 0.2161341608 ( 6.3421301842 5.7114696503 -4.3287916183 ) - weight 766 23 0.1327341795 ( -4.5177969933 3.9846088886 -0.9652491212 ) - weight 767 24 0.2522764802 ( 0.6673088074 -4.5702028275 -0.8213348389 ) - weight 768 25 0.1857205629 ( -4.702021122 0.0037913581 -0.2999709845 ) - weight 769 22 0.3443171978 ( 6.9538698196 1.4009666443 -4.2654085159 ) - weight 770 19 0.0849515572 ( 6.9538698196 8.8544416428 -4.3720369339 ) - weight 771 24 0.0859681219 ( 4.1757087708 -5.6105628014 -5.718914032 ) - weight 772 17 0.1470585614 ( 3.1747319698 14.059337616 -3.6281003952 ) - weight 773 22 0.3850519061 ( 3.4454700947 -3.4966125488 -5.3057684898 ) - weight 774 19 0.381921351 ( 3.4454700947 3.8843758106 -4.9779033661 ) - weight 775 17 0.2564366758 ( 3.2059226036 10.6031646729 -3.5615780354 ) - weight 776 22 0.3357651234 ( 3.4251000881 -6.834941864 -4.4081783295 ) - weight 777 19 0.4077982605 ( 3.4251000881 0.6378588676 -3.7903687954 ) - weight 778 17 0.3584515452 ( 3.1408448219 8.2021579742 -4.0212240219 ) - weight 779 22 0.2501184046 ( 3.3525300026 -9.2759628296 -4.2797484398 ) - weight 780 19 0.3914300203 ( 3.3525300026 -1.7824268341 -3.4478852749 ) - weight 781 17 0.3964992762 ( 5.2913842201 7.0102972984 -2.1869134903 ) - weight 782 22 0.2107944041 ( 5.3808398247 -9.9907608032 -2.0922684669 ) - weight 783 19 0.3927063346 ( 5.3808398247 -2.3021924496 -1.2060447931 ) - weight 784 17 0.4625631869 ( 3.317076683 6.4253606796 -4.4233384132 ) - weight 785 22 0.1673343629 ( 3.5262999535 -11.0973014832 -4.2318682671 ) - weight 786 19 0.3701024652 ( 3.5262999535 -3.592508316 -3.2401058674 ) - weight 787 3 0.0810937807 ( 5.3706297874 4.8362388611 -3.1762747765 ) - weight 788 17 0.4351503253 ( 5.2908082008 4.9187550545 -2.5332028866 ) - weight 789 22 0.1511040479 ( 5.3706297874 -12.1041221619 -1.9247384071 ) - weight 790 4 0.0540700927 ( -3.751657486 -6.6709213257 0.2586658597 ) - weight 791 19 0.2785817385 ( 5.3706297874 -4.3926501274 -0.8534116745 ) - weight 792 17 0.3703182042 ( -0.1894687265 7.7811222076 -3.6284191608 ) - weight 793 22 0.2096323222 ( 0 -9.5899543762 -3.989048481 ) - weight 794 19 0.4200495183 ( 0 -2.0696525574 -3.1307122707 ) - weight 795 17 0.5077348948 ( -0.2497932017 4.9502978325 -5.4121198654 ) - weight 796 22 0.132455036 ( 0 -12.7671432495 -5.039888382 ) - weight 797 19 0.3598100841 ( 0 -5.3269076347 -3.8982300758 ) - weight 798 23 0.1587653309 ( -4.8064312935 0.333888799 0.6214014292 ) - weight 799 24 0.341963619 ( 3.9892585278 -5.0736227036 1.3326721191 ) - weight 800 22 0.4370694458 ( 3.6319200993 3.5549736023 -4.768828392 ) - weight 801 19 0.0622016639 ( 3.6319200993 10.9558649063 -5.0628323555 ) - weight 802 23 0.1169716492 ( -3.559296608 3.4655766487 1.8332631588 ) - weight 803 24 0.3126016557 ( 0.7903084755 -3.6176428795 2.0242385864 ) - weight 804 25 0.1636657417 ( -3.4258654118 -1.7572934628 1.7712110281 ) - weight 805 22 0.4067609012 ( 6.8308701515 4.2465400696 -3.312848568 ) - weight 806 23 0.1274844557 ( -5.718416214 0.9235868454 -2.8849439621 ) - weight 807 24 0.203381151 ( 3.9134385586 -5.9826126099 -2.2228736877 ) - weight 808 17 0.0744129121 ( 3.4152114391 17.545507431 -3.1608846188 ) - weight 809 22 0.4018339217 ( 3.7077400684 -0.0005722046 -5.6778182983 ) - weight 810 19 0.1928875744 ( 3.7077400684 7.3341851234 -5.6557936668 ) - weight 811 24 0.0688953698 ( 7.621178627 -5.2977228165 -6.0978622437 ) - weight 812 17 0.1616402864 ( -0.2470974326 13.5686473846 -3.2243156433 ) - weight 813 22 0.4030251205 ( -0.0000000028 -3.8755607605 -4.9929285049 ) - weight 814 19 0.3664392829 ( -0.0000000028 3.5343909264 -4.6329669952 ) - weight 815 32 0.7909759283 ( 0.3013904393 0.1546860039 -0.7386940718 ) - weight 816 36 0.2090241015 ( -1.5368877649 -1.857853651 -2.1059734821 ) - weight 817 37 0.3135154545 ( -1.0189431906 -0.0231241882 0.3210504949 ) - weight 818 36 0.6864845753 ( -1.0807000399 0.1835258454 -1.183678031 ) - weight 819 37 0.4512871802 ( 0.0318348072 -0.4292137325 -0.3837123215 ) - weight 820 36 0.54871279 ( -0.0299220085 -0.3172357976 -1.8246438503 ) - weight 821 37 0.2882056236 ( 0.1031946689 0.8576620221 -0.0693482757 ) - weight 822 36 0.7117943764 ( 0.0414378531 1.0009781122 -1.6935479641 ) - weight 823 37 0.0534667037 ( 0.7390236259 -1.1569381952 0.527007103 ) - weight 824 36 0.9465333223 ( 0.6772668362 -0.9102852941 -0.8210077882 ) - weight 825 32 1 ( 0.6515467167 -0.7546216249 -0.5772744417 ) - weight 826 26 0.1501512825 ( 0.6569923162 11.0239515305 -0.7517694831 ) - weight 827 36 0.8498487473 ( 0.9686909318 -0.0907552466 -0.0990887731 ) - weight 828 26 0.2271368206 ( -0.9500332475 11.2577915192 -0.3760506511 ) - weight 829 28 0.7728632092 ( -0.9860389233 0.6879566908 -1.5921638012 ) - weight 830 32 0.7059418559 ( 0.8529013395 0.2689555585 0.4666240215 ) - weight 831 30 0.1873759627 ( -0.5249474645 0.833425343 -1.7110564709 ) - weight 832 29 0.1066821665 ( 0.7380059361 0.542617023 -1.7460485697 ) - weight 833 32 0.3800835013 ( 1.7005238533 0.1184403673 -0.6271010041 ) - weight 834 33 0.6199164987 ( -0.063366361 0.1205253154 -0.633720696 ) - weight 835 33 1 ( 0.0047345622 0.0806246027 0.1051414907 ) - weight 836 34 1 ( -0.030973414 0.2817834914 0.6583018303 ) - weight 837 34 1 ( 0.459885329 0.1284638047 0.7128788829 ) - weight 838 34 1 ( -0.0281402096 0.2328744829 -0.0181326438 ) - weight 839 31 1 ( 0.8137669563 0.7210566998 0.9509422779 ) - weight 840 30 0.5691296458 ( 0.496073544 0.0201213323 -1.5487580299 ) - weight 841 31 0.4308703542 ( -0.4050124586 1.469741106 1.5151686668 ) - weight 842 31 1 ( 0.1789630949 -0.3992726207 1.3273460865 ) - weight 843 26 0.228164196 ( -2.0553922653 11.4523229599 0.5124111176 ) - weight 844 28 0.771835804 ( -2.1372196674 -0.1617464721 -1.5495903492 ) - weight 845 30 0.0996929035 ( -0.5371494889 1.5152635574 1.0535236597 ) - weight 846 29 0.9003071189 ( 0.1306644529 0.8964582086 1.0132789612 ) - weight 847 31 1 ( -0.0534513444 0.3365330696 -0.7042888999 ) - weight 848 31 1 ( 0.4865443408 -0.424195528 0.4600257576 ) - weight 849 31 1 ( -0.1298738867 1.1481175423 -1.0036811829 ) - weight 850 30 0.548068881 ( -0.1935541183 -0.150092259 0.9376041889 ) - weight 851 29 0.0776808113 ( 1.5358805656 -0.063176319 0.9164581299 ) - weight 852 31 0.3742503226 ( -0.4401404858 2.1791951656 -0.9711934924 ) - weight 853 30 0.793235898 ( -0.2034815252 -0.8158763051 -1.2988400459 ) - weight 854 31 0.206764102 ( 0.1947123855 2.3800156116 1.2652506828 ) - weight 855 30 0.2869230807 ( -1.2194061279 0.7263837457 1.0662133694 ) - weight 856 29 0.7130769491 ( 0.1843923777 -0.1446626335 0.9794086218 ) - weight 857 30 0.2508835793 ( 0.2798903584 0.678370595 0.7430583239 ) - weight 858 29 0.5495494604 ( 1.312654376 0.8709167242 0.7552478313 ) - weight 859 31 0.1995669752 ( -1.0976207256 1.4876605272 -0.776647687 ) - weight 860 33 1 ( -0.2716299295 -0.7015333176 -0.5615057945 ) - weight 861 27 0.0804401562 ( -0.5693823695 1.0922350883 1.0989742279 ) - weight 862 26 0.1950167269 ( 0.5208252072 10.658780098 1.912620306 ) - weight 863 28 0.7245431542 ( -1.0170431137 0.5267705321 1.1887196302 ) - weight 864 30 0.2420762628 ( -1.5459938049 0.1255453378 -1.348806262 ) - weight 865 29 0.7579237223 ( 0.4755658209 -0.6903474331 -1.4531685114 ) - weight 866 37 1 ( -0.7535862327 -0.2359776348 -1.3384435177 ) - weight 867 37 1 ( -0.8558571935 0.5914275646 -1.5487754345 ) - weight 868 38 1 ( -0.7641019225 0.2813872397 -1.1251176596 ) - weight 869 37 0.3279238045 ( -0.7415515184 0.8253681064 0.0033408168 ) - weight 870 36 0.6720762253 ( -0.8033083081 0.9791792631 -1.6170535088 ) - weight 871 37 1 ( 0.0342843644 0.7546004653 -1.5970057249 ) - weight 872 38 1 ( -0.2876996398 -0.2475986332 -0.819491148 ) - weight 873 37 1 ( 0.2029056251 -0.0768934712 -1.4540183544 ) - weight 874 38 1 ( -0.1392796934 0.275324434 -1.1315653324 ) - weight 875 27 0.0804907233 ( 0.7206745744 1.6926574707 -0.0654819608 ) - weight 876 26 0.0865155682 ( 1.7482863665 10.4141235352 0.5657001138 ) - weight 877 36 0.7271223068 ( -0.5261606574 0.7331290245 0.5215334296 ) - weight 878 28 0.1058714092 ( 0.4677643478 1.5597521067 0.8585562706 ) - weight 879 26 0.2002442926 ( 1.4116584063 10.4367227554 -0.4874773324 ) - weight 880 36 0.7039310336 ( 0.4597637355 0.7523312569 0.0209376123 ) - weight 881 28 0.0958246663 ( 0.8282811642 1.6774045229 -0.1802879721 ) - weight 882 33 1 ( -0.2362884134 -0.7070522904 0.2054723203 ) - weight 883 34 1 ( 0.481054455 0.1019513234 0.0100561501 ) - weight 884 32 1 ( 0.4816427231 -0.8670278192 0.2655512094 ) - weight 885 34 1 ( 0.5316370726 1.273768425 0.2100916207 ) - weight 886 1 0.0870729014 ( 0.0679385737 5.3494148254 5.6673798561 ) - weight 887 3 0.0578332841 ( 0 5.3387870789 5.8250551224 ) - weight 888 18 0.2770702541 ( 0.0817569122 2.9116477966 -0.7267565727 ) - weight 889 17 0.251304239 ( 0.4457650483 3.167047739 6.6088557243 ) - weight 890 22 0.1137764752 ( 0 -11.6015739441 7.0765914917 ) - weight 891 21 0.0554567203 ( 4.2523598671 -9.2828483582 0.2828435898 ) - weight 892 19 0.1574861258 ( 0 -3.1008853912 8.0689105988 ) - weight 893 20 0.0984087512 ( -4.0246829987 -5.0569114685 0.437473774 ) - weight 894 18 0.1377525628 ( 0.0817569122 7.0092582703 -0.5721263885 ) - weight 895 17 0.1938979477 ( 0.4546417296 7.1067523956 7.7459454536 ) - weight 896 22 0.1629235893 ( 0 -7.5039634705 7.2312216759 ) - weight 897 21 0.1325069219 ( 4.2523598671 -5.1852378845 0.437473774 ) - weight 898 19 0.2745102644 ( 0 0.9944577217 7.8627882004 ) - weight 899 3 0.0655534565 ( 3.1403698921 3.6771392822 -6.2063446045 ) - weight 900 17 0.5141583085 ( 2.8902821541 4.4918031693 -5.6241707802 ) - weight 901 22 0.0935055837 ( 3.1403698921 -13.2632217407 -4.9548082352 ) - weight 902 19 0.3267826438 ( 3.1403698921 -5.8135881424 -3.7698769569 ) - weight 903 20 0.0783546641 ( 2.9092769623 -5.5809898376 -6.3233261108 ) - weight 904 17 0.2564292252 ( 6.9890565872 8.3202514648 0.6825386882 ) - weight 905 22 0.317520082 ( 6.9339599609 -8.0280418396 0.4704216719 ) - weight 906 19 0.3476960361 ( 6.9339599609 -0.1218248978 1.1742166281 ) - weight 907 24 0.3524007499 ( 4.5481786728 2.6630673409 3.4342651367 ) - weight 908 22 0.6475992203 ( 3.0729999542 5.6565666199 2.9678616524 ) - weight 909 40 0.3378937542 ( -4.5481801033 2.6630699635 3.4342422485 ) - weight 910 22 0.6621062756 ( -3.0729999542 5.6565666199 2.9678616524 ) - weight 911 40 0.228695035 ( -5.8105401993 3.8355400562 2.4665679932 ) - weight 912 22 0.5610228777 ( -1.8106398582 4.6888923645 4.1403317451 ) - weight 913 21 0.0736490563 ( 2.4417200089 7.0076179504 -2.6534161568 ) - weight 914 19 0.1366330385 ( -1.8106398582 12.8684558868 3.7121837139 ) - weight 915 17 0.263050884 ( -0.2081583887 10.3442058563 -3.3270344734 ) - weight 916 22 0.2775782049 ( 0.0000000075 -7.0297622681 -4.3146185875 ) - weight 917 19 0.4593708813 ( 0.0000000075 0.4520157576 -3.6800475121 ) - weight 918 20 0.0885559097 ( -1.8578529358 -6.6862297058 -0.0188961029 ) - weight 919 18 0.2181270719 ( 2.2485868931 5.379940033 -1.0284962654 ) - weight 920 17 0.259214282 ( 2.5917000771 5.6651763916 6.7904639244 ) - weight 921 22 0.1964760423 ( 2.1668300629 -9.1332817078 6.774851799 ) - weight 922 19 0.2376267314 ( 2.1668300629 -0.6686669588 7.5513916016 ) - weight 923 1 0.0863308311 ( 0.0679385737 7.4130973816 5.6244001389 ) - weight 924 18 0.2418361455 ( 0.0817569122 4.9753303528 -0.76973629 ) - weight 925 17 0.2470486164 ( 0.4432977438 5.1802744865 7.064426899 ) - weight 926 22 0.1510022879 ( 0 -9.5378913879 7.0336117744 ) - weight 927 21 0.078649357 ( 4.2523598671 -7.219165802 0.2398638725 ) - weight 928 19 0.1951327771 ( 0 -1.0489673615 7.8447127342 ) - weight 929 23 0.1114774719 ( -1.4474338293 1.7304900885 3.7460358143 ) - weight 930 24 0.3288436532 ( 2.3275885582 -1.6005128622 4.1915283203 ) - weight 931 22 0.5596789122 ( 5.2935900688 6.4138298035 -1.2957184315 ) - weight 932 26 0.5467997789 ( 0.232779026 9.5722894669 2.0896861553 ) - weight 933 28 0.4532001913 ( -0.5023785233 -0.4728339016 1.363924861 ) - weight 934 23 0.0643626675 ( 1.0519639254 6.4328122139 3.044033289 ) - weight 935 24 0.2483460903 ( -2.0300416946 1.1850371361 2.7412185669 ) - weight 936 25 0.4390696883 ( 1.7008849382 0.0520681739 3.1772031784 ) - weight 937 22 0.2482215762 ( 9.6512203217 4.96352005 1.4898315668 ) - weight 938 23 0.1135391444 ( 3.9930100441 6.583258152 1.5403448343 ) - weight 939 24 0.2351882309 ( -1.7472610474 4.1139574051 1.2329330444 ) - weight 940 25 0.3721637726 ( 4.3757205009 0.6470030546 1.3265891075 ) - weight 941 22 0.2791088521 ( 9.3684396744 3.4552345276 4.4187517166 ) - weight 942 3 0.3218889236 ( -2.2474899292 0.0133972168 5.8791251183 ) - weight 943 18 0.2238315195 ( -2.165733099 -2.4137420654 -0.6726865768 ) - weight 944 10 0.2116614133 ( -5.8015508652 -1.8336549997 -0.3439709842 ) - weight 945 17 0.2426181436 ( -1.7949146032 -2.0455527306 5.5033864975 ) - weight 946 3 0.3036911786 ( -4.0866098404 -2.8471412659 6.4127655029 ) - weight 947 18 0.1061030775 ( -4.0048527718 -5.2742805481 -0.1390461922 ) - weight 948 10 0.372621268 ( -5.634021759 1.3280289173 1.0071407557 ) - weight 949 17 0.2175845057 ( -3.6003675461 -4.9756212234 5.4337115288 ) - weight 950 3 0.3058054447 ( -3.4398300648 -2.9727020264 5.0742454529 ) - weight 951 18 0.0927217975 ( -3.3580732346 -5.3998413086 -1.4775662422 ) - weight 952 10 0.4232395291 ( -4.6121277809 1.2485911846 -0.0769018382 ) - weight 953 17 0.178233251 ( -3.0314934254 -4.7665710449 4.0704779625 ) - weight 954 3 0.1699172705 ( -6.583920002 -3.2363624573 3.5967652798 ) - weight 955 18 0.0517219007 ( -6.5021629333 -5.6635017395 -2.9550464153 ) - weight 956 10 0.6336570382 ( -2.1126997471 1.9400100708 2.2495901585 ) - weight 957 17 0.1447037905 ( -6.2552146912 -4.710559845 2.7505347729 ) - weight 958 3 0.1577720791 ( -4.5955500603 0.1378479004 -7.0744948387 ) - weight 959 10 0.2950363755 ( 7.1403565407 -2.4552774429 -2.6775903702 ) - weight 960 17 0.433188349 ( -4.8827176094 1.1586028337 -6.8870940208 ) - weight 961 19 0.114003174 ( -4.5955500603 -9.4154872894 -4.3235855103 ) - weight 962 3 0.189454332 ( -3.8803699017 -2.40209198 -8.9853553772 ) - weight 963 10 0.2641336918 ( 8.6837615967 -0.212754488 -4.4673256874 ) - weight 964 17 0.4399713278 ( -4.2784118652 -0.8369852901 -9.3904132843 ) - weight 965 19 0.1064406335 ( -3.8803699017 -12.1135501862 -6.0038051605 ) - weight 966 3 0.2021252066 ( -3.6253700256 -3.7588424683 -6.7796049118 ) - weight 967 10 0.4968642592 ( 6.5374627113 1.2305631638 -4.1820850372 ) - weight 968 17 0.3010105193 ( -3.8972091675 -2.6808085442 -7.5942697525 ) - weight 969 3 0.1403784007 ( -3.6341600418 0.3311271667 -9.5344247818 ) - weight 970 10 0.2179938704 ( 9.0972414017 -2.9794354439 -4.3830933571 ) - weight 971 17 0.5027850866 ( -4.0641279221 1.9511938095 -9.2776145935 ) - weight 972 19 0.138842687 ( -3.6341600418 -9.4391679764 -6.7909827232 ) - weight 973 3 0.1612571478 ( -3.7402501106 3.2062568665 -7.2569146156 ) - weight 974 17 0.5152321458 ( -4.0393004417 4.1923284531 -6.3722105026 ) - weight 975 22 0.0584009439 ( -3.7402501106 -13.7341041565 -6.0053782463 ) - weight 976 19 0.2651097775 ( -3.7402501106 -6.3749866486 -4.7749934196 ) - weight 977 3 0.1223687679 ( -6.4507799149 2.8663978577 -5.0570845604 ) - weight 978 10 0.1248719096 ( 5.9016070366 -4.6819109917 0.2317753881 ) - weight 979 17 0.4652113318 ( -6.6190767288 3.2958471775 -4.1715736389 ) - weight 980 22 0.0779258981 ( -6.4507799149 -14.0739631653 -3.8055481911 ) - weight 981 19 0.2096221 ( -6.4507799149 -6.5201787949 -2.5538055897 ) - weight 982 3 0.250241667 ( -7.0197200775 0.232837677 -5.7562747002 ) - weight 983 10 0.1907470971 ( 6.769141674 -2.0449006557 0.0274268333 ) - weight 984 17 0.4181091785 ( -7.2272162437 0.9001821876 -5.4518685341 ) - weight 985 19 0.1409020573 ( -7.0197200775 -9.2050018311 -3.0188162327 ) - weight 986 3 0.1879170984 ( -8.5345602036 0.0633277893 -2.3120148182 ) - weight 987 10 0.3526567817 ( 4.088727951 -1.3816905022 2.5890543461 ) - weight 988 17 0.3800626695 ( -8.5418376923 -0.11376407 -2.0710275173 ) - weight 989 19 0.0793634579 ( -8.5345602036 -9.0711259842 0.4270128608 ) - weight 990 3 0.2204527855 ( -8.1109304428 2.7250976563 -0.4794548452 ) - weight 991 10 0.0903242528 ( 2.2133069038 -3.943089962 3.3271505833 ) - weight 992 17 0.4266190529 ( -8.0137062073 2.0346503258 0.3223281205 ) - weight 993 22 0.0848533735 ( -8.1109304428 -14.2152633667 0.7720816135 ) - weight 994 19 0.177750513 ( -8.1109304428 -6.2585868835 2.0185275078 ) - weight 995 3 0.3677097261 ( -6.0281300545 0.6308784485 4.3858852386 ) - weight 996 18 0.1247458234 ( -5.9463729858 -1.7962608337 -2.1659264565 ) - weight 997 10 0.1836168617 ( -3.0651578903 -1.9012150764 2.7239074707 ) - weight 998 17 0.2661482096 ( -5.6550412178 -1.1393705606 4.4159374237 ) - weight 999 19 0.0577793568 ( -6.0281300545 -7.9170680046 7.0491070747 ) - weight 1000 14 0.0571241342 ( -0.6279473901 -1.6999121904 3.0584046841 ) - weight 1001 12 0.4873141348 ( -1.8739540577 5.681368351 4.1245040894 ) - weight 1002 13 0.3494953811 ( -0.5832822323 3.3450553417 3.0524516106 ) - weight 1003 11 0.1060663685 ( -5.570081234 17.6564483643 -4.6147584915 ) - weight 1004 14 0.0571241342 ( 0.470448792 -4.0499653816 3.2013347149 ) - weight 1005 12 0.4873141348 ( -0.2484259158 3.8975038528 3.1626627445 ) - weight 1006 13 0.3494953811 ( 0.5761881471 1.0240461826 3.1873540878 ) - weight 1007 11 0.1060663685 ( -4.4588518143 18.0044898987 -2.2923269272 ) - weight 1008 14 0.0571241342 ( 1.5231406689 -2.1040616035 2.3964548111 ) - weight 1009 12 0.4873141348 ( 0.3900515437 5.9892659187 4.0341048241 ) - weight 1010 13 0.3494953811 ( 1.5776381493 2.9995830059 2.3893027306 ) - weight 1011 11 0.1060663685 ( -6.6196694374 18.7253074646 -2.8871588707 ) - weight 1012 12 0.5431468487 ( 1.7739008665 2.5706710815 1.4441660643 ) - weight 1013 13 0.1878687739 ( 1.9319031239 -1.4930875301 2.393882513 ) - weight 1014 11 0.2689843774 ( -3.300245285 19.3175792694 0.102865912 ) - weight 1015 14 0.475073725 ( -0.6228247285 -0.0134764556 0.0078449287 ) - weight 1016 13 0.5249263048 ( -0.6222586632 5.0415902138 0.0077419197 ) - weight 1017 14 0.4988742769 ( 1.4387165308 -0.7025178671 -0.1229350641 ) - weight 1018 13 0.5011256933 ( 1.456594944 4.4071464539 -0.1252334565 ) - weight 1019 14 0.0537899099 ( 2.3140044212 -3.9046270847 -1.0619350672 ) - weight 1020 12 0.4661476314 ( 2.2125942707 6.9092664719 0.6194453239 ) - weight 1021 13 0.4800623953 ( 2.4153130054 1.2322864532 -1.0752211809 ) - weight 1022 12 0.5260417461 ( -2.4601535797 3.7259614468 2.2589242458 ) - weight 1023 13 0.2905490696 ( -1.8073852062 0.8656568527 3.0101549625 ) - weight 1024 11 0.1834091842 ( -2.8627512455 17.7776622772 -4.0640268326 ) - weight 1025 12 0.4677073956 ( 2.3816046715 3.2602274418 -2.0092687607 ) - weight 1026 13 0.3791610003 ( 1.5808162689 -3.1772892475 -0.7384021878 ) - weight 1027 11 0.1531316042 ( -1.710906744 22.5172080994 0.1888510436 ) - weight 1028 12 0.4963374436 ( -2.7480387688 6.4812078476 -1.3268036842 ) - weight 1029 13 0.5036625862 ( -2.9108216763 0.892280221 -1.3845491409 ) - weight 1030 12 0.4815303087 ( -0.6900922656 3.1260755062 -3.3639380932 ) - weight 1031 13 0.3638229072 ( -1.75063622 -3.3772473335 -1.1255561113 ) - weight 1032 11 0.1546468437 ( 0.5051342845 22.3339385986 -2.3298830986 ) - weight 1033 12 0.416490972 ( 3.1414785385 1.1788779497 -4.6512422562 ) - weight 1034 13 0.1837866157 ( 1.4152913094 -6.5319981575 -1.5181310177 ) - weight 1035 11 0.3997223675 ( 1.0444195271 23.6492061615 1.9255729914 ) - weight 1036 12 0.4213652015 ( 0.7163395882 0.8865970373 -5.4544863701 ) - weight 1037 13 0.1678375602 ( -1.1521804333 -6.6728992462 -1.5053383112 ) - weight 1038 11 0.4107972682 ( 2.7372283936 23.2023181915 0.0423263945 ) - weight 1039 12 0.4677073956 ( 3.2478251457 3.5238323212 -2.7659256458 ) - weight 1040 13 0.3791610003 ( 2.2127685547 -3.6307926178 -1.6257162094 ) - weight 1041 11 0.1531316042 ( -1.7299458981 23.5493125916 0.7604740262 ) - weight 1042 12 0.4815303087 ( -0.8632071614 3.3294949532 -4.5400824547 ) - weight 1043 13 0.3638229072 ( -2.2358968258 -3.8864245415 -2.1053133011 ) - weight 1044 11 0.1546468437 ( 1.2197295427 23.2666912079 -2.6018948555 ) - weight 1045 11 1 ( 1.0627858639 17.4084186554 2.1467142105 ) - weight 1046 12 0.5 ( -0.1710337847 -1.5601655245 -2.5214340687 ) - weight 1047 11 0.5 ( 2.7202358246 19.3322277069 0.6739707589 ) - weight 1048 12 0.5 ( 2.0287842751 -1.4688818455 -1.9404271841 ) - weight 1049 11 0.5 ( 1.3923619986 19.7538013458 2.4751167297 ) - weight 1050 12 0.6966896653 ( 2.041156292 1.0884995461 0.127628237 ) - weight 1051 11 0.3033103049 ( -1.5993971825 19.5977554321 1.1178280115 ) - weight 1052 14 0.475073725 ( 0.7850021124 -0.5019580126 1.7101949453 ) - weight 1053 13 0.5249263048 ( 0.7978597879 4.5842022896 1.7085200548 ) - weight 1054 11 1 ( -3.2253091335 14.9757604599 2.3273222446 ) - weight 1055 11 1 ( -1.2605392933 14.1733818054 2.7510647774 ) - weight 1056 11 1 ( -2.2355148792 15.3392515182 3.1716089249 ) - weight 1057 11 1 ( 1.7703081369 15.3532648087 3.7261528969 ) - weight 1058 11 1 ( 3.1836252213 15.0992860794 2.4708430767 ) - weight 1059 11 1 ( 1.6157793999 17.0327510834 2.930529356 ) - weight 1060 11 1 ( -1.8079998493 13.0318565369 -1.7747212648 ) - weight 1061 11 1 ( -3.2718541622 13.1396341324 -0.3047262728 ) - weight 1062 11 1 ( -2.6849746704 14.8099021912 -2.9147562981 ) - weight 1063 12 0.5431468487 ( 2.791321516 0.0155043649 3.7966547012 ) - weight 1064 13 0.1878687739 ( 3.397002697 -2.2758016586 5.6093244553 ) - weight 1065 11 0.2689843774 ( -3.6346759796 16.5259342194 2.3817005157 ) - weight 1066 12 0.5431468487 ( 3.164741993 -0.8547753692 2.9167728424 ) - weight 1067 13 0.1878687739 ( 3.4448332787 -3.5566778183 5.4417228699 ) - weight 1068 11 0.2689843774 ( -2.6530108452 16.8505096436 3.1575906277 ) - weight 1069 11 1 ( -1.6802988052 17.7957763672 2.2167971134 ) - weight 1070 12 0.5431468487 ( 1.8764477968 1.0186554193 2.9830102921 ) - weight 1071 13 0.1878687739 ( 2.3599994183 -1.7826064825 4.5199642181 ) - weight 1072 11 0.2689843774 ( -3.3677923679 17.3495883942 1.0566763878 ) - weight 1073 11 1 ( -4.1703705788 15.0276737213 -1.2706042528 ) - weight 1074 11 1 ( -3.4725449085 15.899813652 -1.4111224413 ) - weight 1075 12 0.6961277723 ( -2.8118655682 2.5067002773 0.4542705417 ) - weight 1076 13 0.2235300392 ( -2.7394030094 -1.0681368113 2.5013728142 ) - weight 1077 11 0.0803422183 ( -0.7580763698 18.3411521912 -3.7177624702 ) - weight 1078 14 0.3067108989 ( -2.5804672241 -1.8302059174 2.3730351925 ) - weight 1079 12 0.1096295714 ( -3.5751414299 5.8493552208 2.9511394501 ) - weight 1080 13 0.5836595297 ( -2.5317275524 3.1661231518 2.3664588928 ) - weight 1081 14 0.475073725 ( -1.5173728466 -0.3742565215 1.6155048609 ) - weight 1082 13 0.5249263048 ( -1.5070670843 4.6519842148 1.614063859 ) - weight 1083 12 0.0831768736 ( -0.139297083 -2.4316897392 -0.323033303 ) - weight 1084 11 0.9168231487 ( 1.8145941496 17.2132015228 1.2060180902 ) - weight 1085 12 0.5233104229 ( -1.6129223108 1.2962657213 -1.7303005457 ) - weight 1086 13 0.1692353189 ( -2.2954478264 -3.5839407444 1.4296443462 ) - weight 1087 11 0.307454288 ( 0.9654531479 19.7657909393 -2.082275629 ) - weight 1088 14 0.495306462 ( -2.7327840328 -1.2737447023 -0.4310050011 ) - weight 1089 13 0.5046935678 ( -2.6985425949 3.728107214 -0.435654074 ) - weight 1090 11 1 ( 1.4528329372 13.3605079651 -0.8885222673 ) - weight 1091 11 1 ( 0.4442543685 13.5150356293 -1.6495600939 ) - weight 1092 12 0.1456800848 ( -2.4101986885 -3.0623643398 0.6363787055 ) - weight 1093 11 0.8543199301 ( 2.5002176762 15.3114204407 -0.3394150734 ) - weight 1094 12 0.0831768736 ( -0.0501801074 -3.4747738838 -0.5628409386 ) - weight 1095 11 0.9168231487 ( 2.5995457172 16.8570384979 1.8466995955 ) - weight 1096 12 0.1456800848 ( -1.4213246107 -1.9071899652 -0.7173609734 ) - weight 1097 11 0.8543199301 ( 2.2579007149 17.3248500824 -0.1597061604 ) - weight 1098 11 1 ( 2.5450799465 13.5188446045 2.1944601536 ) - weight 1099 11 1 ( 1.534711957 12.1389904022 -0.5643333197 ) - weight 1100 11 1 ( 2.0677056313 12.5868110657 1.7713165283 ) - weight 1101 10 0.3245811462 ( 2.1622042656 23.4828701019 0.8809092045 ) - weight 1102 11 0.6754188538 ( -3.1441166401 2.5228619576 -0.3744156361 ) - weight 1103 10 0.3558541834 ( 4.5960187912 22.5349979401 0.9984716177 ) - weight 1104 11 0.6441458464 ( -2.7252163887 2.1103641987 2.1731517315 ) - weight 1105 10 0.0613344125 ( 5.5035405159 24.4813232422 0.5650521517 ) - weight 1106 11 0.9386656284 ( -2.4956834316 4.2460775375 2.6040518284 ) - weight 1107 11 1 ( -0.7055392265 16.6808223724 2.9005372524 ) - weight 1108 10 0.2941013873 ( 2.7750475407 25.512140274 -0.8154879212 ) - weight 1109 11 0.7058986425 ( -1.7442501783 4.8469333649 -0.4761215448 ) - weight 1110 10 0.0613344125 ( 4.9786653519 25.5140857697 0.5639258027 ) - weight 1111 11 0.9386656284 ( -2.7505383492 5.1331167221 1.9038367271 ) - weight 1112 10 0.2941013873 ( 2.8148183823 25.8488178253 0.4360967577 ) - weight 1113 11 0.7058986425 ( -3.0138554573 5.0115656853 -0.270216912 ) - weight 1114 10 0.211769715 ( 1.5064116716 25.7864189148 -1.2849180698 ) - weight 1115 11 0.7882302999 ( -1.5278775692 4.9046087265 -1.8380639553 ) - weight 1116 10 0.0812822357 ( 1.9276061058 25.4348621368 -2.9777057171 ) - weight 1117 11 0.9187178016 ( 0.2442374974 4.8839321136 -1.6777296066 ) - weight 1118 11 1 ( -3.2784276009 13.3226203918 1.5451292992 ) - weight 1119 11 1 ( -2.8552718163 14.1906909943 1.3098424673 ) - weight 1120 11 1 ( 0.3036168516 12.7071313858 -2.3142709732 ) - weight 1121 11 1 ( 0.2435934097 10.7855882645 -1.9499571323 ) - weight 1122 10 1 ( -1.8288136721 17.6561317444 -1.4014087915 ) - weight 1123 10 0.8725460172 ( 0.9352088571 17.386423111 2.3516714573 ) - weight 1124 11 0.1274539977 ( -3.726252079 -3.8366634846 -0.1444553286 ) - weight 1125 10 1 ( -1.9821153879 18.684961319 0.2984714508 ) - weight 1126 10 0.2571666539 ( -0.311906904 21.0302829742 -2.2853696346 ) - weight 1127 11 0.7428333163 ( -0.0227471665 0.0501305461 -2.8852679729 ) - weight 1128 10 0.4192074835 ( -0.5384716392 22.1393508911 -0.601377964 ) - weight 1129 11 0.5807925463 ( -1.8854236603 0.8464540839 -3.0014326572 ) - weight 1130 10 0.9235870242 ( 0.8627715707 18.3076229095 3.0106294155 ) - weight 1131 11 0.0764129907 ( -4.5355434418 -3.0502426624 -0.2655907571 ) - weight 1132 11 1 ( -2.4222662449 15.7066888809 -2.5135531425 ) - weight 1133 12 0.1456800848 ( -2.4784703255 0.0577871054 -0.1260462701 ) - weight 1134 11 0.8543199301 ( 1.0460990667 17.5636615753 -2.1097960472 ) - weight 1135 11 1 ( -0.9949848056 10.3095226288 3.9997110367 ) - weight 1136 11 1 ( 2.3558936119 10.4500799179 5.0477561951 ) - weight 1137 11 1 ( 0.7839050889 12.7956476212 3.1211972237 ) - weight 1138 11 1 ( -0.7877941132 12.6351089478 2.6962049007 ) - weight 1139 10 0.0613344125 ( 8.7347812653 26.0844764709 -1.3471918106 ) - weight 1140 11 0.9386656284 ( -0.4128960669 6.7470550537 5.0687618256 ) - weight 1141 10 0.2776068151 ( 9.432636261 24.1843700409 -3.6394128799 ) - weight 1142 11 0.7223932147 ( 2.248519659 5.3686461449 5.6758389473 ) - weight 1143 11 1 ( 2.9260220528 8.8122701645 5.4693508148 ) - weight 1144 11 1 ( -2.7369706631 11.0070209503 1.8858362436 ) - weight 1145 11 1 ( 3.888184309 10.4228773117 2.8881018162 ) - weight 1146 11 1 ( 3.181892395 10.2619037628 0.3437602222 ) - weight 1147 10 0.3635103405 ( 7.7457618713 23.9936332703 -6.4598946571 ) - weight 1148 11 0.6364896894 ( 4.7687921524 5.2055749893 3.5642805099 ) - weight 1149 11 1 ( 4.6658611298 8.7912817001 3.5705535412 ) - weight 1150 10 0.0812822357 ( 3.8220057487 28.1995296478 -5.5506830215 ) - weight 1151 11 0.9187178016 ( 2.5682523251 8.312256813 -0.8423328996 ) - weight 1152 11 1 ( -3.5436015129 12.7489624023 -0.3692253232 ) - weight 1153 11 1 ( -2.9179697037 10.1565799713 0.1922051609 ) - weight 1154 11 1 ( -1.8016387224 12.4640512466 -2.2356784344 ) - weight 1155 11 1 ( -1.3515464067 10.0306634903 -1.6384416819 ) - weight 1156 10 0.0533989966 ( 4.3116564751 27.4132995605 0.8583703041 ) - weight 1157 11 0.9466009736 ( -3.4622716904 6.787946701 0.9585379362 ) - weight 1158 10 0.7313693166 ( 4.7778096199 17.985250473 1.442399621 ) - weight 1159 11 0.2686307132 ( -2.3555121422 -2.3124675751 3.2832040787 ) - weight 1160 10 0.5535137653 ( 6.7148265839 19.1627063751 -1.0747230053 ) - weight 1161 11 0.4464862049 ( 0.1906840652 -0.4181095958 4.4675335884 ) - weight 1162 10 0.580740869 ( 5.2286376953 19.6618862152 1.1217234135 ) - weight 1163 11 0.4192591608 ( -2.2596695423 -0.5505899787 3.3447990417 ) - weight 1164 3 0.0991234779 ( -3.4762499332 -19.5002632141 -3.4779047966 ) - weight 1165 10 0.7581200004 ( 3.4689199924 16.9078407288 -6.0589957237 ) - weight 1166 11 0.1427565515 ( 4.9302210808 -2.6182668209 0.839944303 ) - weight 1167 3 0.1030853167 ( -1.8285499811 -16.5847930908 0.3800151944 ) - weight 1168 10 0.8969147205 ( -0.7357553244 14.02937603 -5.6935114861 ) - weight 1169 10 0.4970574677 ( 2.1133944988 19.6039123535 -5.6277656555 ) - weight 1170 11 0.5029425621 ( 3.8444948196 -0.358296454 -0.8938210607 ) - weight 1171 10 0.6765145659 ( 5.6679024696 18.8820056915 -4.2061109543 ) - weight 1172 11 0.3234854639 ( 3.1267614365 -0.4892466962 2.932990551 ) - weight 1173 10 0.5535137653 ( 7.7399907112 20.7065353394 -1.4886425734 ) - weight 1174 11 0.4464862049 ( 0.4876977801 1.3507310152 5.0909795761 ) - weight 1175 10 0.3635103405 ( 6.733174324 21.0585193634 -5.0010709763 ) - weight 1176 11 0.6364896894 ( 3.6932039261 1.9518762827 3.4063191414 ) - weight 1177 3 0.0679782704 ( -4.6116900444 -16.5367126465 -5.5437746048 ) - weight 1178 10 0.9320217371 ( 5.7901091576 14.0445098877 -5.1911864281 ) - weight 1179 10 1 ( 7.2595119476 15.5520582199 -2.2479016781 ) - weight 1180 10 0.3121370375 ( 6.1200838089 21.3359203339 0.6980981231 ) - weight 1181 11 0.6878629923 ( -1.9958025217 1.3169360161 3.8130340576 ) - weight 1182 10 0.5281411409 ( 1.6715714931 22.0164737701 2.100883007 ) - weight 1183 11 0.4718588889 ( -4.1572709084 0.8340165615 -0.3481029272 ) - weight 1184 3 0.0560320839 ( -10.5247402191 -16.245344162 2.2468152046 ) - weight 1185 10 0.9439678788 ( 0.6078214049 15.3042488098 3.0124285221 ) - weight 1186 10 0.9462006092 ( 5.0640335083 15.1098098755 2.4747567177 ) - weight 1187 11 0.053799402 ( -2.8275306225 -5.1729230881 4.2886042595 ) - weight 1188 10 1 ( 4.7214488983 7.5200686455 0.2097454667 ) - weight 1189 3 0.0739208758 ( -9.0113201141 -7.0935401917 0.4436051846 ) - weight 1190 10 0.8397787809 ( 1.7144957781 5.9256615639 2.6734585762 ) - weight 1191 17 0.0863003582 ( -8.8596220016 -7.7292256355 -1.098780632 ) - weight 1192 3 0.2600899935 ( -1.9173300266 -6.228061676 3.7980952263 ) - weight 1193 18 0.0514350347 ( -1.8355730772 -8.6552009583 -2.7537164688 ) - weight 1194 10 0.5973545909 ( -3.9456613064 4.1010856628 -2.5188333988 ) - weight 1195 17 0.0911203474 ( -1.5847626925 -7.5980095863 1.964805007 ) - weight 1196 3 0.2159355134 ( -4.079100132 -4.1766815186 4.2738552094 ) - weight 1197 18 0.061971426 ( -3.9973433018 -6.6038208008 -2.2779564857 ) - weight 1198 10 0.598956883 ( -3.6314229965 2.4852855206 0.0106333978 ) - weight 1199 17 0.1231361777 ( -3.7156565189 -5.7513995171 3.0404822826 ) - weight 1200 3 0.1172183082 ( -4.7489600182 -10.6977920532 4.4494051933 ) - weight 1201 10 0.8107878566 ( -3.5282275677 9.0215501785 -0.5099526644 ) - weight 1202 17 0.0719938651 ( -4.3743338585 -12.131896019 1.6767301559 ) - weight 1203 3 0.3475687504 ( -0.9472100139 -7.9706916809 3.3553352356 ) - weight 1204 18 0.0668434426 ( -0.865453124 -10.3978309631 -3.1964764595 ) - weight 1205 10 0.4931578338 ( -3.8686974049 5.6183524132 -3.8848149776 ) - weight 1206 17 0.0924299806 ( -0.6416596174 -9.1693849564 1.0618844032 ) - weight 1207 3 0.2083981186 ( -1.0451300144 -8.0715408325 1.4885851145 ) - weight 1208 10 0.7212069035 ( -2.0885457993 5.6046361923 -4.4639410973 ) - weight 1209 17 0.0703949779 ( -0.8465807438 -8.8195915222 -0.7657278776 ) - weight 1210 3 0.1491072923 ( -0.7362200022 -7.9641609192 -3.9595546722 ) - weight 1211 10 0.7604651451 ( 2.8937387466 5.068584919 -6.6269655228 ) - weight 1212 17 0.0904275626 ( -0.8509358764 -7.4006137848 -6.0359902382 ) - weight 1213 3 0.0598057099 ( -4.7044801712 -9.3245429993 -5.5001549721 ) - weight 1214 10 0.8863587379 ( 5.7499442101 6.9738602638 -3.7663371563 ) - weight 1215 17 0.0538356192 ( -4.9010915756 -8.4052314758 -7.6354146004 ) - weight 1216 3 0.3410162032 ( -2.3271501064 -4.636882782 4.4688053131 ) - weight 1217 18 0.1115094125 ( -2.2453932762 -7.0640220642 -2.083006382 ) - weight 1218 10 0.3881037533 ( -4.4341106415 2.6532115936 -1.6162080765 ) - weight 1219 17 0.1593706906 ( -1.9554042816 -6.2207055092 3.020888567 ) - weight 1220 10 0.3592960536 ( 4.8947477341 21.5079841614 -6.1538481712 ) - weight 1221 11 0.6407039165 ( 4.4578928947 2.1497812271 1.3358578682 ) - weight 1222 10 0.2776068151 ( 7.9603428841 22.5869007111 -3.5119109154 ) - weight 1223 11 0.7223932147 ( 2.1710999012 3.4911093712 4.5782613754 ) - weight 1224 10 0.3635103405 ( 6.4683504105 23.0258960724 -5.8951916695 ) - weight 1225 11 0.6364896894 ( 4.1884150505 3.9196927547 2.617256403 ) - weight 1226 10 0.2067560852 ( 7.840880394 22.8489494324 -1.5483607054 ) - weight 1227 11 0.7932439446 ( 0.1967572123 3.4530267715 4.7757225037 ) - weight 1228 10 0.2571666837 ( 0.6449739337 22.1718921661 -3.5362243652 ) - weight 1229 11 0.7428333163 ( 1.1470068693 1.528650403 -2.4065384865 ) - weight 1230 10 0.0812822357 ( 3.3085138798 24.160161972 -4.8727064133 ) - weight 1231 11 0.9187178016 ( 2.5169847012 4.2027955055 -0.4556528926 ) - weight 1232 10 0.0812822357 ( 3.5247519016 25.3160629272 -6.5840210915 ) - weight 1233 11 0.9187178016 ( 4.0193309784 5.5991592407 -0.7790534496 ) - weight 1234 10 0.0812822357 ( 2.2623245716 25.0508651733 -5.3968434334 ) - weight 1235 11 0.9187178016 ( 2.7157461643 4.9117956161 -1.7286012173 ) - weight 1236 11 1 ( 1.9528076649 6.6696376801 -2.0808444023 ) - weight 1237 10 0.0812822357 ( 3.8753688335 27.1428852081 -6.4576091766 ) - weight 1238 11 0.9187178016 ( 3.6390659809 7.4243235588 -0.7599076629 ) - weight 1239 10 0.3071684539 ( 7.7204818726 21.7841510773 0.3564078808 ) - weight 1240 11 0.6928315163 ( -1.4947624207 2.1390814781 5.210164547 ) - weight 1241 10 0.2067560852 ( 8.0827903748 23.4173736572 0.2716140151 ) - weight 1242 11 0.7932439446 ( -1.6346949339 3.8080677986 5.2379603386 ) - weight 1243 10 0.0613344125 ( 6.5591959953 24.2243556976 1.5010778904 ) - weight 1244 11 0.9386656284 ( -3.2017872334 4.0963850021 3.8432428837 ) - weight 1245 10 0.3121370375 ( 5.958398819 22.1328144073 1.6121064425 ) - weight 1246 11 0.6878629923 ( -3.0458776951 1.9294559956 3.676091671 ) - weight 1247 10 0.0812822357 ( 4.8904137611 26.889629364 -6.5074453354 ) - weight 1248 11 0.9187178016 ( 3.8858482838 7.4031190872 0.257730186 ) - weight 1249 11 1 ( 0.5537624359 6.952735424 -1.5404719114 ) - weight 1250 10 0.0812822357 ( 4.3660645485 24.7501564026 -6.3316192627 ) - weight 1251 11 0.9187178016 ( 3.9985198975 5.1973867416 0.1852643192 ) - weight 1252 10 0.3071684539 ( 7.515958786 21.6333789825 -0.6566445827 ) - weight 1253 11 0.6928315163 ( -0.5141820312 2.0867488384 4.8544106483 ) - weight 1254 10 0.0613344125 ( 7.1777477264 24.8887729645 0.102540493 ) - weight 1255 11 0.9386656284 ( -1.8588026762 5.0609226227 4.0577750206 ) - weight 1256 10 0.2067560852 ( 7.8742041588 24.1285991669 -0.9466136694 ) - weight 1257 11 0.7932439446 ( -0.6016560197 4.6165885925 4.6788949966 ) - weight 1258 11 1 ( 1.3207137585 13.6807069778 3.5596404076 ) - weight 1259 10 0.2117697299 ( 0.7045083046 23.4747562408 -1.0195502043 ) - weight 1260 11 0.7882302999 ( -1.5155103207 2.4608118534 -2.1295454502 ) - weight 1261 12 0.5431468487 ( 1.2287373543 0.6955800653 4.344991684 ) - weight 1262 13 0.1878687739 ( 2.104678154 -1.0625441074 5.8598227501 ) - weight 1263 11 0.2689843774 ( -3.7974894047 15.9097127914 0.7087955475 ) - weight 1264 12 0.1456800848 ( -3.5406241417 -2.7338395119 1.5601328611 ) - weight 1265 11 0.8543199301 ( 2.1394605637 14.3796215057 -1.4532893896 ) - weight 1266 11 1 ( 0.9979313612 14.4678354263 -2.7612226009 ) - weight 1267 12 0.1456800848 ( -3.4635710716 -1.7974902391 -0.0798543245 ) - weight 1268 11 0.8543199301 ( 2.5924906731 16.1536922455 -1.921993494 ) - weight 1269 12 0.1456800848 ( -3.9954340458 -0.5935640335 1.0132627487 ) - weight 1270 11 0.8543199301 ( 1.3223114014 15.7924728394 -3.0098292828 ) - weight 1271 3 0.1878461093 ( -8.1206798553 -3.2090530396 0.8102852106 ) - weight 1272 10 0.6148968339 ( 1.0378433466 1.9812264442 2.6959385872 ) - weight 1273 17 0.1972570866 ( -7.9494009018 -4.03505373 0.142801702 ) - weight 1274 3 0.2786260843 ( -1.9693599939 2.7528877258 6.4345850945 ) - weight 1275 18 0.2412805408 ( -1.8876030445 0.3257484436 -0.1172266006 ) - weight 1276 10 0.0551613122 ( -6.4318776131 -4.5353035927 0.0970300213 ) - weight 1277 17 0.2700432241 ( -1.4853566885 0.4834723473 6.6861405373 ) - weight 1278 22 0.0605197549 ( -1.9693599939 -14.1874732971 7.6861214638 ) - weight 1279 19 0.0943691283 ( -1.9693599939 -5.6232032776 8.9033670425 ) - weight 1280 3 0.2181934863 ( -5.3479399681 3.3707275391 4.6170454025 ) - weight 1281 18 0.1552526653 ( -5.2661828995 0.9435882568 -1.9347662926 ) - weight 1282 10 0.0934470817 ( -3.5352194309 -4.6940960884 2.6823997498 ) - weight 1283 17 0.3332818449 ( -4.9627027512 1.4735702276 5.262149334 ) - weight 1284 22 0.0799631029 ( -5.3479399681 -13.5696334839 5.8685817719 ) - weight 1285 19 0.1198618561 ( -5.3479399681 -5.1675047874 7.0385565758 ) - weight 1286 3 0.2420467585 ( -8.1792898178 0.6259078979 0.6979751587 ) - weight 1287 18 0.0568250678 ( -8.097533226 -1.8012313843 -5.8538365364 ) - weight 1288 10 0.3111597598 ( 1.1464397907 -1.7863074541 3.4148745537 ) - weight 1289 17 0.3228418231 ( -8.0143613815 -0.286862433 0.9612258673 ) - weight 1290 19 0.0671265945 ( -8.1792898178 -8.2461633682 3.3759064674 ) - weight 1291 3 0.1812590361 ( -7.6562199593 -1.4332427979 -1.4200248718 ) - weight 1292 10 0.5559865236 ( 2.9495708942 0.0019104274 1.8178077936 ) - weight 1293 17 0.2627543807 ( -7.6137399673 -1.7686568499 -1.6162565947 ) - weight 1294 3 0.1693525314 ( -6.0396299362 -1.0798034668 -5.4591846466 ) - weight 1295 10 0.5434408784 ( 6.1490740776 -0.9006757736 -1.0109044313 ) - weight 1296 17 0.2872065604 ( -6.2316875458 -0.4316957295 -5.5348739624 ) - weight 1297 3 0.3636357486 ( -3.6178998947 0.8198280334 6.5375151634 ) - weight 1298 18 0.164281413 ( -3.5361430645 -1.6073112488 -0.0142965317 ) - weight 1299 10 0.1094316542 ( -5.9336323738 -2.3476119041 1.2931711674 ) - weight 1300 17 0.296444118 ( -3.1252691746 -1.4402012825 6.4119777679 ) - weight 1301 19 0.0662071034 ( -3.6178998947 -7.5397348404 9.1758022308 ) - weight 1302 10 0.9283159971 ( -0.7646887302 20.6940860748 1.8752098083 ) - weight 1303 11 0.0716839954 ( -4.085050106 -0.9356721044 -2.4923946857 ) - weight 1304 3 0.1023416594 ( -7.8418898582 -4.4684715271 -2.0312447548 ) - weight 1305 10 0.7607446313 ( 3.6004910469 2.9746718407 1.2180837393 ) - weight 1306 17 0.1369137466 ( -7.8341913223 -4.570016861 -2.9294438362 ) - weight 1307 3 0.073409535 ( -6.2762699127 -5.4256515503 -4.842004776 ) - weight 1308 10 0.7968719006 ( 5.675766468 3.454293251 -1.37631917 ) - weight 1309 17 0.1297186315 ( -6.432507515 -4.8012480736 -5.9707503319 ) - weight 1310 3 0.1279380769 ( -2.8462500572 -5.969833374 -5.8070545197 ) - weight 1311 10 0.7375896573 ( 5.3614654541 3.3388929367 -4.9652452469 ) - weight 1312 17 0.1344723403 ( -3.0635437965 -5.0498256683 -7.2280426025 ) - weight 1313 11 1 ( -0.9993764758 6.9363341331 -2.3558793068 ) - weight 1314 11 1 ( -2.6546089649 7.3097600937 -1.0461925268 ) - weight 1315 40 0.0648640916 ( 5.2623896599 0.2113799453 -0.3916053772 ) - weight 1316 42 0.054200843 ( -3.0292124748 -6.8557052612 -1.5554412603 ) - weight 1317 41 0.792229712 ( -2.6183409691 4.5853748322 -0.031161692 ) - weight 1318 22 0.088705346 ( -12.8835697174 1.8307189941 0.5161716342 ) - weight 1319 41 1 ( -2.2034544945 5.5126566887 2.4599895477 ) - weight 1320 41 1 ( -2.2925741673 7.8907551765 0.2689195573 ) - weight 1321 41 0.8994785547 ( 1.8573349714 4.1241745949 2.7927172184 ) - weight 1322 22 0.1005214527 ( -10.1063604355 -1.4544410706 -2.6004781723 ) - weight 1323 41 0.9012724757 ( 2.1591470242 4.8457479477 0.0623148903 ) - weight 1324 22 0.0987275392 ( -10.4430799484 -2.2646942139 0.1008114815 ) - weight 1325 41 1 ( 2.1821029186 5.0424695015 1.7732554674 ) - weight 1326 42 0.1751072109 ( 1.4469791651 -2.7943427563 -1.0891802311 ) - weight 1327 41 0.8248927593 ( 1.6110378504 8.9282426834 -0.0458206125 ) - weight 1328 42 0.2499999702 ( 0.9373752475 -0.2285873443 -1.4919937849 ) - weight 1329 41 0.7500000596 ( 1.1081621647 11.2449522018 -1.2226932049 ) - weight 1330 42 0.2499999851 ( -1.7030748129 -0.3029949367 -1.4152827263 ) - weight 1331 41 0.75 ( -1.5056906939 11.0066022873 -1.5298757553 ) - weight 1332 42 1 ( 1.0422173738 2.0127835274 -1.2607536316 ) - weight 1333 42 1 ( -1.3513631821 2.8154947758 -1.4070562124 ) - weight 1334 42 1 ( -1.8056651354 6.6884093285 -0.26370731 ) - weight 1335 42 1 ( -0.2115952969 5.6794037819 -1.0375576019 ) - weight 1336 42 1 ( -2.4962170124 1.9985327721 -0.823141098 ) - weight 1337 42 1 ( -2.6784250736 3.1894750595 0.9537656307 ) - weight 1338 42 0.458101511 ( -2.6966545582 -0.2615238726 0.1728804708 ) - weight 1339 41 0.541898489 ( -2.7492101192 11.4073696136 -0.1866602004 ) - weight 1340 42 0.6225160956 ( -2.2087597847 -0.0277975872 1.6615362167 ) - weight 1341 41 0.3774839342 ( -2.5207698345 12.0709667206 1.2332760096 ) - weight 1342 41 0.9465382099 ( -1.2847018242 6.5744814873 -2.3188717365 ) - weight 1343 22 0.0534618273 ( -13.7131099701 -0.5152740479 2.7017917633 ) - weight 1344 41 0.8632076979 ( -1.3737902641 4.8516249657 -2.5978245735 ) - weight 1345 22 0.1367922574 ( -12.3231697083 0.5033569336 2.9923818111 ) - weight 1346 42 0.1075217947 ( -0.502844274 -1.2884002924 -2.8992643356 ) - weight 1347 41 0.8924782276 ( -0.0509810075 9.7429256439 -2.4789383411 ) - weight 1348 41 0.9031683803 ( 1.0344703197 4.7457380295 -2.4795851707 ) - weight 1349 22 0.0968315899 ( -10.8985900879 -1.4246940613 2.7129116058 ) - weight 1350 41 1 ( 1.6655596495 6.1536235809 -1.8215377331 ) - weight 1351 42 0.5947889686 ( 2.0430514812 0.2205056995 0.031901475 ) - weight 1352 41 0.4052110314 ( 1.9341742992 12.168756485 0.2641662359 ) - weight 1353 42 1 ( 2.2563576698 3.6086163521 0.3291334212 ) - weight 1354 42 0.1232460067 ( -1.9074287415 -3.0061392784 0.7662026286 ) - weight 1355 41 0.8767539859 ( -1.9975229502 8.9906663895 1.263281703 ) - weight 1356 42 0.1999999881 ( -0.3615294695 -5.0165266991 1.5548927784 ) - weight 1357 41 0.8000000119 ( -0.5514265299 7.3855323792 2.8079001904 ) - weight 1358 42 0.4609466791 ( -0.142166391 -0.2162491828 2.7810926437 ) - weight 1359 41 0.5390533209 ( -0.663808763 12.3413505554 2.6609725952 ) - weight 1360 42 0.7493240237 ( -0.1800996661 0.7430870533 2.861771822 ) - weight 1361 41 0.2506759763 ( -0.7396733761 13.2812814713 2.4633672237 ) - weight 1362 42 1 ( -1.083111763 3.5439755917 2.6252696514 ) - weight 1363 40 0.0858102515 ( 4.1295895576 -2.8317801952 -0.5566062927 ) - weight 1364 41 0.8180595636 ( -1.6464886665 3.7483146191 2.9564990997 ) - weight 1365 22 0.0961302221 ( -11.7507696152 1.6657180786 -2.5269885063 ) - weight 1366 42 0.6769491434 ( -1.3486216068 10.2637815475 1.3616914749 ) - weight 1367 43 0.3230508566 ( 1.7585068941 -1.1770786047 0.5442247987 ) - weight 1368 41 0.9405311346 ( 0.8490356207 5.8289494514 3.4219884872 ) - weight 1369 22 0.0594688691 ( -12.1043300629 -1.5341339111 -3.1667585373 ) - weight 1370 42 0.4114079475 ( 1.3796098232 -0.3438566029 2.4536092281 ) - weight 1371 41 0.5885920525 ( 0.893994987 12.2381067276 2.6171529293 ) - weight 1372 42 0.1739317775 ( 1.2114337683 -3.4267618656 1.0886069536 ) - weight 1373 41 0.8260681629 ( 1.0348631144 8.8964157104 2.1598997116 ) - weight 1374 42 1 ( 2.0147998333 3.5676603317 2.2008626461 ) - weight 1375 42 0.5472053885 ( 0.6305749416 9.7364444733 -0.4175415933 ) - weight 1376 43 0.4527946413 ( -0.354521662 0.0858460665 -0.5964356661 ) - weight 1377 42 0.6961436272 ( 1.5018861294 0.6841530204 2.4828295708 ) - weight 1378 41 0.3038563728 ( 0.9827948213 13.2413539886 2.3758687973 ) - weight 1379 42 0.4764319956 ( -0.7310147882 9.734249115 -1.371276021 ) - weight 1380 59 0.1922429055 ( 0.4109789133 -0.6637012362 -1.5243489742 ) - weight 1381 43 0.3313251436 ( -0.3707777262 0.673737824 0.9584468603 ) - weight 1382 42 1 ( 0.8840810061 4.7274417877 2.5911712646 ) - weight 1383 42 0.5268752575 ( 0.4305175543 10.5334939957 0.8858301044 ) - weight 1384 43 0.4731247723 ( 1.0321447849 -0.4465796947 -1.0060315132 ) - weight 1385 42 0.2153184563 ( -1.0530905724 10.9852075577 1.1966280937 ) - weight 1386 46 0.0747896805 ( 2.0761227608 -0.6466100216 -0.1010147333 ) - weight 1387 43 0.7098918557 ( 2.0957694054 -0.5667824149 0.1584371775 ) - weight 1388 42 0.4178506434 ( -0.0075625898 10.5884742737 1.3911437988 ) - weight 1389 43 0.5821493864 ( 1.5150495768 -0.8509085178 -0.7745146751 ) - weight 1390 40 0.1692856401 ( -2.3039302826 6.0932502747 -2.2292976379 ) - weight 1391 39 0.095947735 ( -6.2288627625 3.2766070366 -2.5073711872 ) - weight 1392 22 0.3743245602 ( -5.3172497749 -0.0069732666 6.3980417252 ) - weight 1393 21 0.2051592022 ( -1.0648899078 2.3117523193 -0.3957061768 ) - weight 1394 19 0.1552828997 ( -5.3172497749 8.3892021179 6.3738937378 ) - weight 1395 40 0.1379436105 ( -0.6618800163 5.1672701836 -3.7487373352 ) - weight 1396 22 0.3586037457 ( -6.9593000412 -1.5264129639 5.4720616341 ) - weight 1397 21 0.2115510106 ( -2.7069401741 0.7923126221 -1.3216862679 ) - weight 1398 19 0.2919015884 ( -6.9593000412 6.7942552567 5.5850467682 ) - weight 1399 40 0.0756776929 ( -1.8433198929 5.9607200623 -6.0047073364 ) - weight 1400 17 0.0660997555 ( -5.3691277504 10.8710746765 8.0288057327 ) - weight 1401 22 0.3658838272 ( -5.7778601646 -3.7823829651 6.2655115128 ) - weight 1402 21 0.2541330159 ( -1.5255002975 -1.4636573792 -0.5282363892 ) - weight 1403 19 0.2382057607 ( -5.7778601646 4.6167554855 6.5737113953 ) - weight 1404 20 0.1024025828 ( -6.7596926689 0.0708389282 0.6981534958 ) - weight 1405 17 0.0583666265 ( -2.2608933449 11.9829120636 9.3863697052 ) - weight 1406 22 0.2766293287 ( -2.7350099087 -2.3762130737 7.4919013977 ) - weight 1407 21 0.1758731008 ( 1.5173499584 -0.0574874878 0.6981534958 ) - weight 1408 19 0.3867283762 ( -2.7350099087 6.125275135 7.6717615128 ) - weight 1409 20 0.0538338795 ( -6.5593128204 -2.1767807007 0.2234835625 ) - weight 1410 17 0.1097829714 ( -2.088092804 9.9184532166 8.3737459183 ) - weight 1411 22 0.2268086672 ( -2.5346300602 -4.6238327026 7.0172314644 ) - weight 1412 21 0.3038957119 ( 1.7177298069 -2.3051071167 0.2234835625 ) - weight 1413 19 0.305678755 ( -2.5346300602 3.8446335793 7.3964805603 ) - weight 1414 40 0.1079444885 ( -4.8613300323 5.7338700294 -0.8817062378 ) - weight 1415 39 0.095863536 ( -6.0347743034 0.5179504156 -1.5921704769 ) - weight 1416 22 0.4226267338 ( -2.7598500252 1.3406181335 6.0386614799 ) - weight 1417 21 0.1990941018 ( 1.4925098419 3.6593437195 -0.755086422 ) - weight 1418 19 0.1744710505 ( -2.7598500252 9.6999912262 5.897459507 ) - weight 1419 40 0.1939979792 ( -0.9147901535 5.2671203613 -2.0173454285 ) - weight 1420 41 0.1499870867 ( 1.8269389868 0.3468859494 -5.3824033737 ) - weight 1421 39 0.1120208204 ( -5.3150653839 4.5581684113 -2.0834612846 ) - weight 1422 22 0.3791788816 ( -6.706389904 0.2049789429 5.5719118118 ) - weight 1423 21 0.0979815647 ( -2.4540300369 2.5237045288 -1.2218360901 ) - weight 1424 19 0.0668336302 ( -6.706389904 8.5277223587 5.5323314667 ) - weight 1425 40 0.234101072 ( -2.3377699852 4.9376497269 0.8234939575 ) - weight 1426 39 0.151872009 ( -5.0778346062 2.6781790257 0.4881438613 ) - weight 1427 22 0.4724108279 ( -5.2834100723 3.0458183289 5.2424416542 ) - weight 1428 21 0.0748311952 ( -1.0310502052 5.3645439148 -1.5513062477 ) - weight 1429 19 0.0667849407 ( -5.2834100723 11.3286094666 4.9544444084 ) - weight 1430 18 0.1035705134 ( -1.7752031088 7.2092285156 -1.0104966164 ) - weight 1431 17 0.1793337017 ( -1.424421072 7.380592823 7.4728312492 ) - weight 1432 22 0.2148930579 ( -1.8569600582 -7.3039932251 6.7928514481 ) - weight 1433 21 0.1897529215 ( 2.3953998089 -4.9852676392 -0.0008964539 ) - weight 1434 19 0.3124498129 ( -1.8569600582 1.1551240683 7.4085383415 ) - weight 1435 40 0.0815275982 ( 0.4910998344 -0.2718701363 -5.1617164612 ) - weight 1436 17 0.0615869239 ( -8.0574855804 13.156124115 2.3229653835 ) - weight 1437 22 0.3325373828 ( -8.112279892 -2.9393920898 0.0329215527 ) - weight 1438 21 0.2024751306 ( -3.8599200249 -0.6206665039 -6.7608261108 ) - weight 1439 19 0.3218729794 ( -8.112279892 4.908677578 0.2911488116 ) - weight 1440 17 0.0821124837 ( -6.3874130249 11.2053899765 5.2713308334 ) - weight 1441 22 0.3500007987 ( -6.6362099648 -4.1222915649 3.454811573 ) - weight 1442 21 0.2431944013 ( -2.3838500977 -1.803565979 -3.3389363289 ) - weight 1443 19 0.3246923387 ( -6.6362099648 4.0311188698 3.8037652969 ) - weight 1444 18 0.0508767888 ( -4.889772892 9.0597076416 -1.6688961983 ) - weight 1445 17 0.1164982542 ( -4.5716509819 9.2918510437 7.4542560577 ) - weight 1446 22 0.2913883328 ( -4.9715299606 -5.4535140991 6.1344518661 ) - weight 1447 21 0.2373414934 ( -0.7191700935 -3.1347885132 -0.6592960358 ) - weight 1448 19 0.3038951457 ( -4.9715299606 2.9405722618 6.5900411606 ) - weight 1449 17 0.1433633715 ( -6.4097995758 9.4369134903 4.2599358559 ) - weight 1450 22 0.3488012254 ( -6.6266698837 -6.0823516846 2.8989317417 ) - weight 1451 21 0.1913605779 ( -2.3743100166 -3.7636260986 -3.8948161602 ) - weight 1452 19 0.3164748847 ( -6.6266698837 2.0297861099 3.4223136902 ) - weight 1453 40 0.0830702633 ( -0.0801000595 3.4679398537 -3.2844963074 ) - weight 1454 41 0.2401334941 ( 2.5323307514 1.7530235052 -3.6317951679 ) - weight 1455 22 0.3283133507 ( -7.541079998 -1.062171936 3.7727315426 ) - weight 1456 21 0.1991699189 ( -3.2887201309 1.2565536499 -3.0210163593 ) - weight 1457 19 0.1493130177 ( -7.541079998 7.1073389053 3.8514893055 ) - weight 1458 40 0.0631914958 ( 1.0974497795 -0.5379699469 -4.7699279785 ) - weight 1459 41 0.4758155644 ( 3.3759055138 3.573526144 0.3197355568 ) - weight 1460 22 0.3346864879 ( -8.718629837 -2.5476036072 -0.2331782579 ) - weight 1461 19 0.1263064742 ( -8.718629837 5.2755613327 -0.0083569372 ) - weight 1462 41 0.8354642391 ( 0.8403681517 3.9649412632 -2.6302630901 ) - weight 1463 22 0.1645357162 ( -10.3534202576 -0.8371734619 2.879142046 ) - weight 1464 41 0.8016968966 ( 2.0041029453 4.112142086 -0.8274868131 ) - weight 1465 22 0.1983030736 ( -9.8898496628 -1.7785720825 1.0016914606 ) - weight 1466 40 0.0795945823 ( 2.2775101662 3.2554500103 -2.6060676575 ) - weight 1467 41 0.6468813419 ( 0.672326684 3.3321244717 -3.299277544 ) - weight 1468 22 0.2058532536 ( -9.8986902237 -0.3837432861 3.5602416992 ) - weight 1469 21 0.0676708817 ( -5.6463303566 1.9349822998 -3.2335062027 ) - weight 1470 40 0.0915071294 ( 3.366420269 3.1473996639 -0.8238754272 ) - weight 1471 41 0.6722839475 ( -1.402238369 3.2421872616 -3.0508818626 ) - weight 1472 39 0.0702659339 ( -2.924277544 8.447883606 -0.2393910438 ) - weight 1473 22 0.1659429818 ( -10.9876003265 1.3984489441 3.4521913528 ) - weight 1474 40 0.1500607431 ( 2.9526495934 3.8326499462 0.3506698608 ) - weight 1475 41 0.5410900116 ( -2.1904191971 2.2411170006 -3.6809294224 ) - weight 1476 39 0.0928304717 ( -3.6347305775 7.8946905136 0.8604110479 ) - weight 1477 22 0.2160188258 ( -10.5738296509 2.5729942322 4.1374416351 ) - weight 1478 40 0.1394342631 ( 4.4194598198 -0.4394298792 1.3595581055 ) - weight 1479 41 0.7044921517 ( -3.5551998615 2.9113519192 0.6903645992 ) - weight 1480 22 0.156073615 ( -12.0406398773 3.5818824768 -0.1346381903 ) - weight 1481 40 0.1505005956 ( 3.2964596748 -2.3047599792 0.6204147339 ) - weight 1482 41 0.69200176 ( -2.1926093102 2.3983840942 2.470007658 ) - weight 1483 22 0.1574976742 ( -10.9176397324 2.8427391052 -1.9999682903 ) - weight 1484 40 0.1167786345 ( 4.3386702538 1.9469498396 0.485168457 ) - weight 1485 41 0.6686697006 ( -2.9466729164 3.3233273029 -1.7439450026 ) - weight 1486 39 0.0635740086 ( -1.6637589931 9.1183710098 1.1963964701 ) - weight 1487 22 0.1509776562 ( -11.9598503113 2.7074928284 2.2517416477 ) - weight 1488 40 0.2023779899 ( 3.6632494926 2.317690134 1.1831588745 ) - weight 1489 41 0.5041594505 ( -3.1734714508 2.3720610142 -2.0967719555 ) - weight 1490 39 0.0833940431 ( -2.0771887302 8.3642663956 1.7805497646 ) - weight 1491 22 0.2100685388 ( -11.2844295502 3.4054832458 2.622481823 ) - weight 1492 40 0.21779567 ( 3.8119196892 0.1195698977 1.9123382568 ) - weight 1493 41 0.5065205693 ( -3.7122163773 2.0967354774 0.1436493695 ) - weight 1494 39 0.060067974 ( 0.1259425581 8.2536582947 2.5013246536 ) - weight 1495 22 0.2156157792 ( -11.4330997467 4.1346626282 0.4243615866 ) - weight 1496 41 0.5535457134 ( 1.9143215418 2.9438529015 -2.2318480015 ) - weight 1497 22 0.2617037296 ( -8.9217700958 -1.1337738037 2.4131615162 ) - weight 1498 21 0.093204923 ( -4.6694102287 1.1849517822 -4.3805861473 ) - weight 1499 19 0.0915455744 ( -8.9217700958 6.916516304 2.5034742355 ) - weight 1500 40 0.1077788919 ( 1.9966797829 -3.4164302349 -1.392906189 ) - weight 1501 41 0.7407969832 ( 0.2727117538 2.4466743469 3.4179315567 ) - weight 1502 22 0.1514241099 ( -9.6178598404 0.8294181824 -3.111638546 ) - weight 1503 40 0.0957343802 ( 1.6407694817 -1.7257101536 -3.4715576172 ) - weight 1504 41 0.6556051373 ( 2.0782561302 3.3045735359 1.5985864401 ) - weight 1505 22 0.1770816594 ( -9.2619495392 -1.2492332458 -1.4209184647 ) - weight 1506 19 0.0715788603 ( -9.2619495392 6.4645118713 -1.3056191206 ) - weight 1507 40 0.1257757396 ( 1.004219532 -3.0659201145 -2.1959152222 ) - weight 1508 41 0.5331090689 ( 1.4665535688 2.0695960522 2.9875690937 ) - weight 1509 22 0.2766729593 ( -8.6253995895 0.0264091492 -2.7611284256 ) - weight 1510 19 0.0644422546 ( -8.6253995895 7.6174211502 -2.7527635098 ) - weight 1511 40 0.0597746707 ( 1.1221795082 0.8254899383 -3.6436653137 ) - weight 1512 41 0.6176533103 ( 2.3379807472 2.9608576298 -0.9746568203 ) - weight 1513 22 0.2640878558 ( -8.7433595657 -1.4213409424 1.1302815676 ) - weight 1514 19 0.0584842339 ( -8.7433595657 6.5173048973 1.2508345842 ) - weight 1515 40 0.213553071 ( -0.5112600327 4.6478600502 -1.3372459412 ) - weight 1516 41 0.2301270068 ( 1.0808078051 0.3047070205 -4.7113113403 ) - weight 1517 39 0.0846458524 ( -4.6711249352 4.8067359924 -1.3537971973 ) - weight 1518 22 0.3859202266 ( -7.1099200249 0.8850784302 4.9526519775 ) - weight 1519 21 0.0857538655 ( -2.8575601578 3.2038040161 -1.8410961628 ) - weight 1520 40 0.1662043035 ( 1.1617503166 4.1144499779 -1.896068573 ) - weight 1521 41 0.4407901764 ( 0.6479181647 2.0069105625 -4.1537432671 ) - weight 1522 39 0.0833031684 ( -4.0311760902 6.510617733 -1.6419355869 ) - weight 1523 22 0.3097023368 ( -8.7829303741 0.3262557983 4.4192419052 ) - weight 1524 40 0.1999219507 ( 3.0472502708 -1.8818099499 1.9183120728 ) - weight 1525 41 0.5449860692 ( -3.1569068432 1.4660462141 2.1144711971 ) - weight 1526 39 0.0538640618 ( 2.073975563 7.3724842072 2.3635678291 ) - weight 1527 22 0.2012279034 ( -10.6684303284 4.1406364441 -1.577018261 ) - weight 1528 40 0.3014736176 ( 1.3237395287 -1.7345099449 2.8029098511 ) - weight 1529 41 0.3223048151 ( -2.939677 -0.458378911 1.9592329264 ) - weight 1530 39 0.0734284371 ( 1.8160873652 5.5418729782 2.961108923 ) - weight 1531 22 0.3027931154 ( -8.9449195862 5.0252342224 -1.429718256 ) - weight 1532 40 0.2335041612 ( 0.9760403633 -3.2124302387 0.9798812866 ) - weight 1533 41 0.5032482743 ( -1.1373518705 0.2753029168 3.316403389 ) - weight 1534 22 0.2632475495 ( -8.5972204208 3.202205658 -2.9076385498 ) - weight 1535 40 0.3598757386 ( -3.9891500473 0.7001799345 4.4768066406 ) - weight 1536 22 0.6401242614 ( -3.6320300102 6.699131012 1.0049716234 ) - weight 1537 40 0.362981379 ( -1.932489872 0.7674999833 4.079788208 ) - weight 1538 39 0.0987991989 ( -0.8902490735 2.2880325317 3.7238459587 ) - weight 1539 22 0.5382193923 ( -5.6886901855 6.3021125793 1.0722917318 ) - weight 1540 40 0.3148397207 ( -1.9389500618 2.6459798813 3.4457702637 ) - weight 1541 39 0.1166440994 ( -2.7652523518 2.5030782223 3.116535902 ) - weight 1542 22 0.5685161948 ( -5.6822299957 5.668094635 2.9507718086 ) - weight 1543 40 0.3429679275 ( -5.0265703201 -1.0432300568 4.6310806274 ) - weight 1544 22 0.6570320725 ( -2.5946099758 6.8534049988 -0.7384383678 ) - weight 1545 40 0.2182182074 ( -3.5847101212 -3.3460700512 3.5481567383 ) - weight 1546 39 0.1965454072 ( 3.1084911823 0.4851777256 2.8909509182 ) - weight 1547 22 0.5852363706 ( -4.0364699364 5.7704811096 -3.0412783623 ) - weight 1548 40 0.4073469341 ( 0.0044898987 2.1783196926 3.0577774048 ) - weight 1549 39 0.1675021797 ( -2.1735174656 4.4499650002 3.0411465168 ) - weight 1550 22 0.4251508713 ( -7.6256699562 5.2801017761 2.4831116199 ) - weight 1551 40 0.3590153456 ( -0.3292899132 4.3648500443 1.4379959106 ) - weight 1552 39 0.1555428654 ( -4.3769931793 4.5209741592 1.4115240574 ) - weight 1553 22 0.4029247463 ( -7.2918901443 3.660320282 4.6696419716 ) - weight 1554 21 0.0825170577 ( -3.0395302773 5.9790458679 -2.1241061687 ) - weight 1555 40 0.3742092252 ( -0.2445101738 -1.1445600986 2.8794326782 ) - weight 1556 41 0.0675348863 ( -2.1695859432 -1.8048164845 1.3209780455 ) - weight 1557 39 0.1153045446 ( 1.1264563799 4.0224442482 2.7906699181 ) - weight 1558 22 0.4429512918 ( -7.3766698837 5.1017570496 -0.8397684097 ) - weight 1559 3 0.147518307 ( -6.8201799393 4.7823600769 0.5552852154 ) - weight 1560 18 0.0638706163 ( -6.7384228706 2.3552207947 -5.9965262413 ) - weight 1561 10 0.069427222 ( 0.7782264948 -6.1130943298 2.8791799545 ) - weight 1562 17 0.379175812 ( -6.6656842232 3.8002653122 1.7486844063 ) - weight 1563 22 0.1365248114 ( -6.8201799393 -12.158000946 1.8068217039 ) - weight 1564 19 0.2034832239 ( -6.8201799393 -4.1183390617 2.868442297 ) - weight 1565 3 0.1138401479 ( -4.9373397827 5.1067085266 4.4864754677 ) - weight 1566 18 0.1344936937 ( -4.8555827141 2.6795692444 -2.0653362274 ) - weight 1567 10 0.0767604038 ( -3.5668621063 -6.4794330597 2.5782711506 ) - weight 1568 17 0.3185524046 ( -4.5602750778 3.195497036 5.531018734 ) - weight 1569 22 0.1311376691 ( -4.9373397827 -11.8336524963 5.738011837 ) - weight 1570 21 0.0539095215 ( -0.6849799156 -9.5149269104 -1.0557360649 ) - weight 1571 19 0.1713061035 ( -4.9373397827 -3.4497187138 6.7559099197 ) - weight 1572 18 0.0852944255 ( -4.6090230942 7.2033081055 -1.6371064186 ) - weight 1573 17 0.1881149262 ( -4.2895393372 7.4863753319 7.0221428871 ) - weight 1574 22 0.2643887103 ( -4.6907801628 -7.3099136353 6.1662416458 ) - weight 1575 21 0.1651633531 ( -0.4384202957 -4.9911880493 -0.6275062561 ) - weight 1576 19 0.2970385253 ( -4.6907801628 1.0941513777 6.7848739624 ) - weight 1577 18 0.0526687019 ( -5.9937930107 6.4251708984 -4.2462863922 ) - weight 1578 17 0.2406663895 ( -5.8218078613 7.3396172523 4.3836736679 ) - weight 1579 22 0.2571163774 ( -6.0755500793 -8.0880508423 3.5570616722 ) - weight 1580 21 0.1198813245 ( -1.8231902122 -5.7693252563 -3.2366862297 ) - weight 1581 19 0.3296672106 ( -6.0755500793 0.0896949023 4.2541851997 ) - weight 1582 17 0.1670393497 ( -7.5704827309 10.5304727554 1.4270509481 ) - weight 1583 22 0.3104808629 ( -7.6124801636 -5.7035522461 -0.1756384373 ) - weight 1584 21 0.1040245444 ( -3.3601202965 -3.3848266602 -6.9693861008 ) - weight 1585 19 0.4184552431 ( -7.6124801636 2.1368839741 0.326348573 ) - weight 1586 3 0.061922621 ( -4.8418998718 7.8833580017 4.7734251022 ) - weight 1587 18 0.1345044971 ( -4.7601428032 5.4562187195 -1.7783865929 ) - weight 1588 17 0.2648192942 ( -4.4485201836 5.8226466179 6.4727334976 ) - weight 1589 22 0.2071083784 ( -4.8418998718 -9.0570030212 6.0249614716 ) - weight 1590 21 0.106047526 ( -0.5895400047 -6.7382774353 -0.7687864304 ) - weight 1591 19 0.2255976796 ( -4.8418998718 -0.6585941911 6.7976989746 ) - weight 1592 17 0.3817138374 ( -6.6709108353 6.3495254517 1.2614055872 ) - weight 1593 22 0.2457210273 ( -6.7629899979 -9.8012428284 0.7211816311 ) - weight 1594 19 0.3725651205 ( -6.7629899979 -1.8661230803 1.5798594952 ) - weight 1595 3 0.0897622928 ( -5.9571700096 6.9840698242 2.6555151939 ) - weight 1596 18 0.0676555783 ( -5.875412941 4.556930542 -3.8962965012 ) - weight 1597 10 0.0524910428 ( -1.5014554262 -8.278421402 3.2222356796 ) - weight 1598 17 0.3086533546 ( -5.6835317612 5.4438648224 4.2660708427 ) - weight 1599 22 0.1891150326 ( -5.9571700096 -9.9562911987 3.9070515633 ) - weight 1600 21 0.0736104324 ( -1.7048101425 -7.6375656128 -2.8866963387 ) - weight 1601 19 0.2187122554 ( -5.9571700096 -1.7405531406 4.7670273781 ) - weight 1602 3 0.1646142751 ( -1.9684400558 5.3082885742 5.4040851593 ) - weight 1603 18 0.2286447436 ( -1.8866831064 2.881149292 -1.1477265358 ) - weight 1604 17 0.2764995694 ( -1.5435950756 3.2114815712 6.3032841682 ) - weight 1605 22 0.120833531 ( -1.9684400558 -11.6320724487 6.6556215286 ) - weight 1606 21 0.0558817945 ( 2.2839198112 -9.3133468628 -0.1381263733 ) - weight 1607 19 0.1535260826 ( -1.9684400558 -3.1682665348 7.6522507668 ) - weight 1608 40 0.0604646243 ( -1.3824501038 -3.3477599621 -8.1792182922 ) - weight 1609 17 0.168906033 ( -6.3635997772 10.9932985306 -1.4887984991 ) - weight 1610 22 0.3611638844 ( -6.2387299538 -5.9568939209 -3.0429682732 ) - weight 1611 19 0.4094654918 ( -6.2387299538 1.6325021982 -2.5076172352 ) - weight 1612 17 0.2894129753 ( -6.086815834 8.9249534607 -1.2495434284 ) - weight 1613 22 0.3122178316 ( -6.0043401718 -7.9066619873 -2.2977383137 ) - weight 1614 19 0.3983691931 ( -6.0043401718 -0.2442189455 -1.5938987732 ) - weight 1615 40 0.0726572126 ( -0.2927899361 -2.8913199902 -4.774597168 ) - weight 1616 41 0.1697103977 ( 4.3119664192 2.4308509827 2.619546175 ) - weight 1617 17 0.0710553229 ( -7.4252605438 14.1727600098 -0.1655290127 ) - weight 1618 39 0.0556986518 ( 2.8664906025 5.0968165398 -4.7892827988 ) - weight 1619 22 0.3335112035 ( -7.3283901215 -2.5522727966 -2.5865283012 ) - weight 1620 21 0.067781657 ( -3.0760302544 -0.2335472107 -9.3802757263 ) - weight 1621 19 0.229585588 ( -7.3283901215 5.0640654564 -2.3521888256 ) - weight 1622 40 0.1474560797 ( -1.2790498734 -4.8033699989 -3.9559669495 ) - weight 1623 41 0.1665356904 ( 4.3117895126 1.162627697 4.5405898094 ) - weight 1624 17 0.0749027953 ( -6.5503902435 15.4408378601 -1.8759037256 ) - weight 1625 39 0.054656703 ( 4.7111215591 3.8721759319 -4.1596860886 ) - weight 1626 22 0.3403372765 ( -6.3421301842 -1.7336425781 -4.4985785484 ) - weight 1627 19 0.2161114663 ( -6.3421301842 5.7114696503 -4.3287916183 ) - weight 1628 40 0.2507022917 ( -0.6673102379 -4.5701999664 -0.8213577271 ) - weight 1629 41 0.188060835 ( 1.3601955175 -0.0789612979 4.5102863312 ) - weight 1630 39 0.1305755228 ( 4.5177946091 3.9845876694 -0.9652602673 ) - weight 1631 22 0.3470914364 ( -6.9538698196 1.4009666443 -4.2654085159 ) - weight 1632 19 0.0835699588 ( -6.9538698196 8.8544416428 -4.3720369339 ) - weight 1633 40 0.0858983994 ( -4.1757097244 -5.6105599403 -5.7189369202 ) - weight 1634 17 0.1470492333 ( -3.7048444748 13.9640274048 -3.2441728115 ) - weight 1635 22 0.3854408562 ( -3.4454700947 -3.4966125488 -5.3057684898 ) - weight 1636 19 0.3816115856 ( -3.4454700947 3.8843758106 -4.9779033661 ) - weight 1637 17 0.2563970089 ( -3.6329810619 10.5084190369 -3.1799201965 ) - weight 1638 22 0.3359697759 ( -3.4251000881 -6.834941864 -4.4081783295 ) - weight 1639 19 0.407633245 ( -3.4251000881 0.6378588676 -3.7903687954 ) - weight 1640 17 0.3583992422 ( -3.5531580448 8.109418869 -3.6476523876 ) - weight 1641 22 0.2501963377 ( -3.3525300026 -9.2759628296 -4.2797484398 ) - weight 1642 19 0.3914044797 ( -3.3525300026 -1.7824268341 -3.4478852749 ) - weight 1643 17 0.3964067996 ( -5.4525485039 6.8614506721 -1.5873281956 ) - weight 1644 22 0.2108740211 ( -5.3808398247 -9.9907608032 -2.0922684669 ) - weight 1645 19 0.3927191496 ( -5.3808398247 -2.3021924496 -1.2060447931 ) - weight 1646 17 0.4625355601 ( -3.7238929272 6.327814579 -4.0304040909 ) - weight 1647 22 0.1673413664 ( -3.5262999535 -11.0973014832 -4.2318682671 ) - weight 1648 19 0.3701230586 ( -3.5262999535 -3.592508316 -3.2401058674 ) - weight 1649 3 0.0810885727 ( -5.3706297874 4.8362388611 -3.1762747765 ) - weight 1650 10 0.0540716648 ( 3.7509067059 -6.6714673042 0.2561985254 ) - weight 1651 17 0.4351097345 ( -5.4327383041 4.7701907158 -1.9347553253 ) - weight 1652 22 0.151138708 ( -5.3706297874 -12.1041221619 -1.9247384071 ) - weight 1653 19 0.2785913348 ( -5.3706297874 -4.3926501274 -0.8534116745 ) - weight 1654 40 0.3114421368 ( -0.790309906 -3.6176402569 2.0242156982 ) - weight 1655 41 0.1607022882 ( -0.9913873672 -1.7717634439 3.7201809883 ) - weight 1656 39 0.1148536578 ( 3.5592947006 3.4655942917 1.8332591057 ) - weight 1657 22 0.4130018651 ( -6.8308701515 4.2465400696 -3.312848568 ) - weight 1658 40 0.279579699 ( -3.9892599583 -5.0736203194 1.332649231 ) - weight 1659 24 0.0524114147 ( 11.2530984879 -5.0736227036 1.3326721191 ) - weight 1660 39 0.1643039882 ( 4.8064322472 0.3338904083 0.6214419007 ) - weight 1661 22 0.4393332601 ( -3.6319200993 3.5549736023 -4.768828392 ) - weight 1662 19 0.0643716156 ( -3.6319200993 10.9558649063 -5.0628323555 ) - weight 1663 40 0.1612264365 ( -3.9134399891 -5.9826097488 -2.2228965759 ) - weight 1664 17 0.0778655931 ( -3.9880399704 17.442943573 -2.7477324009 ) - weight 1665 39 0.1351353526 ( 5.7184171677 0.9235396981 -2.8849115372 ) - weight 1666 22 0.4213090241 ( -3.7077400684 -0.0005722046 -5.6778182983 ) - weight 1667 19 0.2044635564 ( -3.7077400684 7.3341851234 -5.6557936668 ) - weight 1668 59 0.6864845753 ( 0.6900131702 -0.0179487485 1.3792867661 ) - weight 1669 60 0.3135154545 ( 0.7971379161 0.2890777886 -0.0885925964 ) - weight 1670 56 0.7909759283 ( -0.1920713037 -0.6768296361 0.4574407935 ) - weight 1671 59 0.2090241015 ( 0.9934572577 2.070494175 2.2580895424 ) - weight 1672 59 0.54871279 ( -0.4412519038 0.4873408377 1.8595534563 ) - weight 1673 60 0.4512871802 ( -0.3341271281 0.7221497297 0.4576878846 ) - weight 1674 59 0.9465333223 ( -1.0248931646 1.0214229822 0.7490455508 ) - weight 1675 60 0.0534667 ( -0.9177684784 1.40645051 -0.5671067238 ) - weight 1676 59 0.7117943764 ( -0.4746326804 -0.8365155458 1.7804573774 ) - weight 1677 60 0.2882056236 ( -0.3675079048 -0.577593267 0.1940213293 ) - weight 1678 56 1 ( -0.6211147904 0.2084709853 0.3698585927 ) - weight 1679 42 0.2104768008 ( 1.0164866447 11.2495384216 0.5217535496 ) - weight 1680 43 0.7895231843 ( 1.1472268105 0.3459745944 -1.5953069925 ) - weight 1681 42 0.1171501949 ( 1.3283326626 10.9253921509 -1.0832571983 ) - weight 1682 59 0.8828498125 ( -1.2095717192 0.1655596942 0.0341215804 ) - weight 1683 54 0.1873759627 ( 0.2550911903 -1.1376373768 1.3137197495 ) - weight 1684 53 0.1066821665 ( -0.7037009597 -0.9298465848 1.3311984539 ) - weight 1685 56 0.7059418559 ( -0.7000744343 -0.7240422368 -0.7712647319 ) - weight 1686 57 0.6199164987 ( -0.2756886482 -0.5445300937 0.3521625102 ) - weight 1687 56 0.3800835013 ( -1.5852597952 -0.7563848495 0.3023990691 ) - weight 1688 57 1 ( -0.2825321257 -0.4758183658 -0.3876881599 ) - weight 1689 58 1 ( 0.5028313994 0.2127913535 -0.2108498812 ) - weight 1690 58 1 ( 0.0291468296 0.415382266 -0.2556580305 ) - weight 1691 58 1 ( 0.4906029701 0.1957811415 0.4670327306 ) - weight 1692 54 0.5691296458 ( -0.7846034169 -0.3681724072 1.0744569302 ) - weight 1693 55 0.4308703542 ( 0.6554923058 -1.0933461189 -1.0408804417 ) - weight 1694 55 1 ( -0.5340524316 -0.3558549583 -0.404175967 ) - weight 1695 55 1 ( 0.164596647 0.7668223381 -0.6306231618 ) - weight 1696 42 0.139783144 ( 0.1749632359 11.5405349731 1.6425499916 ) - weight 1697 43 0.8602169156 ( 2.2958164215 -0.4311053753 -1.2404638529 ) - weight 1698 54 0.0996929035 ( 0.6150705218 -1.6676944494 -1.4607007504 ) - weight 1699 53 0.9003071189 ( 0.0496354662 -0.9335580468 -1.4147849083 ) - weight 1700 55 1 ( -0.1581549346 0.7012303472 0.2290284038 ) - weight 1701 55 1 ( 0.3193058372 -0.2246344835 1.2970813513 ) - weight 1702 55 1 ( 0.3481488228 -1.0697937012 1.4946140051 ) - weight 1703 54 0.548068881 ( 0.1692212075 -0.0300372392 -1.3051309586 ) - weight 1704 53 0.0776808113 ( -1.4119049311 -0.0663760304 -1.2851723433 ) - weight 1705 55 0.3742503226 ( 0.6056970954 -2.1041069031 1.3387073278 ) - weight 1706 54 0.793235898 ( -0.1086509824 0.513632834 0.9470365644 ) - weight 1707 55 0.206764102 ( 0.0051095383 -1.9941760302 -0.9134601355 ) - weight 1708 54 0.2869230807 ( 1.249841094 -0.8465506434 -1.3569916487 ) - weight 1709 53 0.7130769491 ( -0.0659674481 0.0926005244 -1.2678121328 ) - weight 1710 54 0.2508835793 ( -0.2765981853 -0.8901697397 -1.206310153 ) - weight 1711 53 0.5495494604 ( -1.1424726248 -0.9997608662 -1.2177376747 ) - weight 1712 55 0.1995669752 ( 1.3014492989 -1.4299321175 1.2398866415 ) - weight 1713 57 1 ( -0.1397444159 0.2953905165 0.3316278458 ) - weight 1714 42 0.1812395453 ( -1.3461102247 10.7126932144 -0.853087604 ) - weight 1715 46 0.0796369612 ( 1.0116097927 0.6749345064 1.11627388 ) - weight 1716 43 0.7391234636 ( 0.875000596 0.8166624904 1.1368354559 ) - weight 1717 54 0.2420762628 ( 1.2696895599 -0.3616601229 1.1056233644 ) - weight 1718 53 0.7579237223 ( -0.5000941753 0.3405809402 1.1918678284 ) - weight 1719 60 1 ( 0.3954625428 -0.2429129183 1.7704828978 ) - weight 1720 60 1 ( 0.3226207495 0.5740333796 1.5124303102 ) - weight 1721 61 1 ( 0.2094412148 0.1418462396 1.3728909492 ) - weight 1722 59 0.6720762253 ( 0.372549206 -0.7999742627 1.8099576235 ) - weight 1723 60 0.3279238045 ( 0.4796739817 -0.5455421209 0.2283471078 ) - weight 1724 60 1 ( -0.4938989878 -0.406955421 1.7119196653 ) - weight 1725 61 1 ( -0.2185640186 0.6562878489 0.9825653434 ) - weight 1726 60 1 ( -0.6411340833 0.4168128669 1.5119487047 ) - weight 1727 61 1 ( -0.4113186002 0.152643308 1.3020261526 ) - weight 1728 42 0.0815734416 ( -0.0535311624 10.341293335 -2.1068871021 ) - weight 1729 59 0.7680218816 ( 0.3646538556 -0.6521117687 -0.3554476798 ) - weight 1730 43 0.1504046619 ( -0.5756267309 1.6956187487 0.4270273447 ) - weight 1731 42 0.1052538678 ( 1.0094468594 10.3210144043 -1.8024564981 ) - weight 1732 59 0.7648326159 ( -0.6763076186 -0.6708370447 0.0174598154 ) - weight 1733 43 0.1299135387 ( -0.8213586807 1.5633924007 -0.6430864334 ) - weight 1734 57 1 ( -0.1084291711 0.334171772 -0.434564203 ) - weight 1735 58 1 ( -0.0039122077 0.3753073812 0.4460626841 ) - weight 1736 56 1 ( -0.4412592947 0.4162023664 -0.4525512457 ) - weight 1737 58 1 ( -0.1566063762 -0.7618125677 0.1308313608 ) - weight 1738 3 0.0655540898 ( -3.1403698921 3.6771392822 -6.2063446045 ) - weight 1739 17 0.514154315 ( -3.3801002502 4.4049334526 -5.2742400169 ) - weight 1740 22 0.0935057774 ( -3.1403698921 -13.2632217407 -4.9548082352 ) - weight 1741 19 0.3267858326 ( -3.1403698921 -5.8135881424 -3.7698769569 ) - weight 1742 17 0.2562843561 ( -6.8559937477 8.1284418106 1.4551876783 ) - weight 1743 22 0.3181611598 ( -6.9339599609 -8.0280418396 0.4704216123 ) - weight 1744 21 0.0782543495 ( -2.6816000938 -5.7093162537 -6.3233261108 ) - weight 1745 19 0.3473002017 ( -6.9339599609 -0.1218249053 1.1742165089 ) - weight 1746 18 0.210460037 ( -2.0850732327 5.379940033 -1.0284962654 ) - weight 1747 17 0.2493996769 ( -1.7348134518 5.6052370071 7.0319132805 ) - weight 1748 22 0.1892086715 ( -2.1668300629 -9.1332817078 6.774851799 ) - weight 1749 21 0.1221582294 ( 2.0855298042 -6.8145561218 -0.0188961029 ) - weight 1750 19 0.2287734002 ( -2.1668300629 -0.6686669588 7.5513916016 ) - weight 1751 40 0.3291226625 ( -2.3275899887 -1.6005101204 4.1915054321 ) - weight 1752 39 0.1110722423 ( 1.4474331141 1.7305330038 3.7460560799 ) - weight 1753 22 0.5598050952 ( -5.2935900688 6.4138298035 -1.2957184315 ) - weight 1754 42 0.5569466352 ( -1.5716576576 9.6511545181 -0.510961175 ) - weight 1755 43 0.4430533648 ( 0.3549399376 -0.1352982223 1.4804825783 ) - weight 1756 40 0.2958102226 ( 2.0300402641 1.1850399971 2.7411956787 ) - weight 1757 41 0.3504113257 ( -3.4780595303 0.1516100317 -0.9329114556 ) - weight 1758 39 0.0763942376 ( -1.0519686937 6.4328427315 3.0439865589 ) - weight 1759 22 0.2773842216 ( -9.6512203217 4.96352005 1.489831686 ) - weight 1760 40 0.2858607769 ( 1.7472596169 4.1139597893 1.2329101563 ) - weight 1761 41 0.2514301538 ( -2.2687036991 0.7475438118 -3.952147007 ) - weight 1762 39 0.1578629613 ( -3.9930143356 6.5832648277 1.5402956009 ) - weight 1763 22 0.304846108 ( -9.3684396744 3.4552345276 4.4187517166 ) -} - -mesh { - // meshes: berserkbodyfxmesh - shader "models/items/powerups/atom" - - numverts 200 - vert 0 ( 0.0833333135 1.0000001192 ) 1 1 - vert 1 ( 0 0.0000001192 ) 24 1 - vert 2 ( 0 1.0000001192 ) 0 1 - vert 3 ( 0.0833333135 0.0000001192 ) 25 1 - vert 4 ( 0.1666666269 1.0000001192 ) 2 1 - vert 5 ( 0.1666666269 0.0000001192 ) 26 1 - vert 6 ( 0.25 1.0000001192 ) 3 1 - vert 7 ( 0.25 0.0000001192 ) 27 1 - vert 8 ( 0.3333333135 1.0000001192 ) 4 1 - vert 9 ( 0.3333333135 0.0000001192 ) 28 1 - vert 10 ( 0.4166666865 1.0000001192 ) 5 1 - vert 11 ( 0.4166666865 0.0000001192 ) 29 1 - vert 12 ( 0.5 1.0000001192 ) 6 1 - vert 13 ( 0.5 0.0000001192 ) 30 1 - vert 14 ( 0.5833333731 0.0000001192 ) 31 1 - vert 15 ( 0.5833333731 1.0000001192 ) 7 1 - vert 16 ( 0.6666666269 0.0000001192 ) 32 1 - vert 17 ( 0.6666666269 1.0000001192 ) 8 1 - vert 18 ( 0.75 0.0000001192 ) 33 1 - vert 19 ( 0.75 1.0000001192 ) 9 1 - vert 20 ( 0.8333333731 0.0000001192 ) 34 1 - vert 21 ( 0.8333333731 1.0000001192 ) 10 1 - vert 22 ( 0.9166666269 0.0000001192 ) 35 1 - vert 23 ( 0.9166666269 1.0000001192 ) 11 1 - vert 24 ( 1 0.0000001192 ) 36 1 - vert 25 ( 1 1.0000001192 ) 12 1 - vert 26 ( 1.0833332539 0.0000001192 ) 37 1 - vert 27 ( 1.0833332539 1.0000001192 ) 13 1 - vert 28 ( 1.1666667461 0.0000001192 ) 38 1 - vert 29 ( 1.1666667461 1.0000001192 ) 14 1 - vert 30 ( 1.25 0.0000001192 ) 39 1 - vert 31 ( 1.25 1.0000001192 ) 15 1 - vert 32 ( 1.3333332539 0.0000001192 ) 40 1 - vert 33 ( 1.3333332539 1.0000001192 ) 16 1 - vert 34 ( 1.4166667461 0.0000001192 ) 41 1 - vert 35 ( 1.4166667461 1.0000001192 ) 17 1 - vert 36 ( 1.5 0.0000001192 ) 42 1 - vert 37 ( 1.5 1.0000001192 ) 18 1 - vert 38 ( -0.4166666865 1.0000001192 ) 19 1 - vert 39 ( -0.5 0.0000001192 ) 42 1 - vert 40 ( -0.5 1.0000001192 ) 18 1 - vert 41 ( -0.4166666865 0.0000001192 ) 43 1 - vert 42 ( -0.3333333135 1.0000001192 ) 20 1 - vert 43 ( -0.3333333135 0.0000001192 ) 44 1 - vert 44 ( -0.25 1.0000001192 ) 21 1 - vert 45 ( -0.25 0.0000001192 ) 45 1 - vert 46 ( -0.1666666865 1.0000001192 ) 22 1 - vert 47 ( -0.1666666865 0.0000001192 ) 46 1 - vert 48 ( -0.0833333135 1.0000001192 ) 23 1 - vert 49 ( -0.0833333135 0.0000001192 ) 47 1 - vert 50 ( 0 0.0000001192 ) 72 1 - vert 51 ( 0.0833333135 1.0000001192 ) 49 1 - vert 52 ( 0 1.0000001192 ) 48 1 - vert 53 ( 0.0833333135 0.0000001192 ) 73 1 - vert 54 ( 0.1666666269 1.0000001192 ) 50 1 - vert 55 ( 0.1666666269 0.0000001192 ) 74 1 - vert 56 ( 0.25 1.0000001192 ) 51 1 - vert 57 ( 0.25 0.0000001192 ) 75 1 - vert 58 ( 0.3333333135 1.0000001192 ) 52 1 - vert 59 ( 0.3333333135 0.0000001192 ) 76 1 - vert 60 ( 0.4166666865 1.0000001192 ) 53 1 - vert 61 ( 0.4166666865 0.0000001192 ) 77 1 - vert 62 ( 0.5 1.0000001192 ) 54 1 - vert 63 ( 0.5 0.0000001192 ) 78 1 - vert 64 ( 0.5833333731 0.0000001192 ) 79 1 - vert 65 ( 0.5833333731 1.0000001192 ) 55 1 - vert 66 ( 0.6666666269 0.0000001192 ) 80 1 - vert 67 ( 0.6666666269 1.0000001192 ) 56 1 - vert 68 ( 0.75 0.0000001192 ) 81 1 - vert 69 ( 0.75 1.0000001192 ) 57 1 - vert 70 ( 0.8333333731 0.0000001192 ) 82 1 - vert 71 ( 0.8333333731 1.0000001192 ) 58 1 - vert 72 ( 0.9166666269 0.0000001192 ) 83 1 - vert 73 ( 0.9166666269 1.0000001192 ) 59 1 - vert 74 ( 1 0.0000001192 ) 84 1 - vert 75 ( 1 1.0000001192 ) 60 1 - vert 76 ( 1.0833332539 0.0000001192 ) 85 1 - vert 77 ( 1.0833332539 1.0000001192 ) 61 1 - vert 78 ( 1.1666667461 0.0000001192 ) 86 1 - vert 79 ( 1.1666667461 1.0000001192 ) 62 1 - vert 80 ( 1.25 0.0000001192 ) 87 1 - vert 81 ( 1.25 1.0000001192 ) 63 1 - vert 82 ( 1.3333332539 0.0000001192 ) 88 1 - vert 83 ( 1.3333332539 1.0000001192 ) 64 1 - vert 84 ( 1.4166667461 0.0000001192 ) 89 1 - vert 85 ( 1.4166667461 1.0000001192 ) 65 1 - vert 86 ( 1.5 0.0000001192 ) 90 1 - vert 87 ( 1.5 1.0000001192 ) 66 1 - vert 88 ( -0.5 0.0000001192 ) 90 1 - vert 89 ( -0.4166666865 1.0000001192 ) 67 1 - vert 90 ( -0.5 1.0000001192 ) 66 1 - vert 91 ( -0.4166666865 0.0000001192 ) 91 1 - vert 92 ( -0.3333333135 1.0000001192 ) 68 1 - vert 93 ( -0.3333333135 0.0000001192 ) 92 1 - vert 94 ( -0.25 1.0000001192 ) 69 1 - vert 95 ( -0.25 0.0000001192 ) 93 1 - vert 96 ( -0.1666666865 1.0000001192 ) 70 1 - vert 97 ( -0.1666666865 0.0000001192 ) 94 1 - vert 98 ( -0.0833333135 1.0000001192 ) 71 1 - vert 99 ( -0.0833333135 0.0000001192 ) 95 1 - vert 100 ( 0.0833333135 1.0000001192 ) 97 1 - vert 101 ( 0 0.0000001192 ) 120 1 - vert 102 ( 0 1.0000001192 ) 96 1 - vert 103 ( 0.0833333135 0.0000001192 ) 121 1 - vert 104 ( 0.1666666269 1.0000001192 ) 98 1 - vert 105 ( 0.1666666269 0.0000001192 ) 122 1 - vert 106 ( 0.25 1.0000001192 ) 99 1 - vert 107 ( 0.25 0.0000001192 ) 123 1 - vert 108 ( 0.3333333135 1.0000001192 ) 100 1 - vert 109 ( 0.3333333135 0.0000001192 ) 124 1 - vert 110 ( 0.4166666865 1.0000001192 ) 101 1 - vert 111 ( 0.4166666865 0.0000001192 ) 125 1 - vert 112 ( 0.5 1.0000001192 ) 102 1 - vert 113 ( 0.5 0.0000001192 ) 126 1 - vert 114 ( 0.5833333731 0.0000001192 ) 127 1 - vert 115 ( 0.5833333731 1.0000001192 ) 103 1 - vert 116 ( 0.6666666269 0.0000001192 ) 128 1 - vert 117 ( 0.6666666269 1.0000001192 ) 104 1 - vert 118 ( 0.75 0.0000001192 ) 129 1 - vert 119 ( 0.75 1.0000001192 ) 105 1 - vert 120 ( 0.8333333731 0.0000001192 ) 130 1 - vert 121 ( 0.8333333731 1.0000001192 ) 106 1 - vert 122 ( 0.9166666269 0.0000001192 ) 131 1 - vert 123 ( 0.9166666269 1.0000001192 ) 107 1 - vert 124 ( 1 0.0000001192 ) 132 1 - vert 125 ( 1 1.0000001192 ) 108 1 - vert 126 ( 1.0833332539 0.0000001192 ) 133 1 - vert 127 ( 1.0833332539 1.0000001192 ) 109 1 - vert 128 ( 1.1666667461 0.0000001192 ) 134 1 - vert 129 ( 1.1666667461 1.0000001192 ) 110 1 - vert 130 ( 1.25 0.0000001192 ) 135 1 - vert 131 ( 1.25 1.0000001192 ) 111 1 - vert 132 ( 1.3333332539 0.0000001192 ) 136 1 - vert 133 ( 1.3333332539 1.0000001192 ) 112 1 - vert 134 ( 1.4166667461 0.0000001192 ) 137 1 - vert 135 ( 1.4166667461 1.0000001192 ) 113 1 - vert 136 ( 1.5 0.0000001192 ) 138 1 - vert 137 ( 1.5 1.0000001192 ) 114 1 - vert 138 ( -0.4166666865 1.0000001192 ) 115 1 - vert 139 ( -0.5 0.0000001192 ) 138 1 - vert 140 ( -0.5 1.0000001192 ) 114 1 - vert 141 ( -0.4166666865 0.0000001192 ) 139 1 - vert 142 ( -0.3333333135 1.0000001192 ) 116 1 - vert 143 ( -0.3333333135 0.0000001192 ) 140 1 - vert 144 ( -0.25 1.0000001192 ) 117 1 - vert 145 ( -0.25 0.0000001192 ) 141 1 - vert 146 ( -0.1666666865 1.0000001192 ) 118 1 - vert 147 ( -0.1666666865 0.0000001192 ) 142 1 - vert 148 ( -0.0833333135 1.0000001192 ) 119 1 - vert 149 ( -0.0833333135 0.0000001192 ) 143 1 - vert 150 ( 0 0.0000001192 ) 168 1 - vert 151 ( 0.0833333135 1.0000001192 ) 145 1 - vert 152 ( 0 1.0000001192 ) 144 1 - vert 153 ( 0.0833333135 0.0000001192 ) 169 1 - vert 154 ( 0.1666666269 1.0000001192 ) 146 1 - vert 155 ( 0.1666666269 0.0000001192 ) 170 1 - vert 156 ( 0.25 1.0000001192 ) 147 1 - vert 157 ( 0.25 0.0000001192 ) 171 1 - vert 158 ( 0.3333333135 1.0000001192 ) 148 1 - vert 159 ( 0.3333333135 0.0000001192 ) 172 1 - vert 160 ( 0.4166666865 1.0000001192 ) 149 1 - vert 161 ( 0.4166666865 0.0000001192 ) 173 1 - vert 162 ( 0.5 1.0000001192 ) 150 1 - vert 163 ( 0.5 0.0000001192 ) 174 1 - vert 164 ( 0.5833333731 0.0000001192 ) 175 1 - vert 165 ( 0.5833333731 1.0000001192 ) 151 1 - vert 166 ( 0.6666666269 0.0000001192 ) 176 1 - vert 167 ( 0.6666666269 1.0000001192 ) 152 1 - vert 168 ( 0.75 0.0000001192 ) 177 1 - vert 169 ( 0.75 1.0000001192 ) 153 1 - vert 170 ( 0.8333333731 0.0000001192 ) 178 1 - vert 171 ( 0.8333333731 1.0000001192 ) 154 1 - vert 172 ( 0.9166666269 0.0000001192 ) 179 1 - vert 173 ( 0.9166666269 1.0000001192 ) 155 1 - vert 174 ( 1 0.0000001192 ) 180 1 - vert 175 ( 1 1.0000001192 ) 156 1 - vert 176 ( 1.0833332539 0.0000001192 ) 181 1 - vert 177 ( 1.0833332539 1.0000001192 ) 157 1 - vert 178 ( 1.1666667461 0.0000001192 ) 182 1 - vert 179 ( 1.1666667461 1.0000001192 ) 158 1 - vert 180 ( 1.25 0.0000001192 ) 183 1 - vert 181 ( 1.25 1.0000001192 ) 159 1 - vert 182 ( 1.3333332539 0.0000001192 ) 184 1 - vert 183 ( 1.3333332539 1.0000001192 ) 160 1 - vert 184 ( 1.4166667461 0.0000001192 ) 185 1 - vert 185 ( 1.4166667461 1.0000001192 ) 161 1 - vert 186 ( 1.5 0.0000001192 ) 186 1 - vert 187 ( 1.5 1.0000001192 ) 162 1 - vert 188 ( -0.5 0.0000001192 ) 186 1 - vert 189 ( -0.4166666865 1.0000001192 ) 163 1 - vert 190 ( -0.5 1.0000001192 ) 162 1 - vert 191 ( -0.4166666865 0.0000001192 ) 187 1 - vert 192 ( -0.3333333135 1.0000001192 ) 164 1 - vert 193 ( -0.3333333135 0.0000001192 ) 188 1 - vert 194 ( -0.25 1.0000001192 ) 165 1 - vert 195 ( -0.25 0.0000001192 ) 189 1 - vert 196 ( -0.1666666865 1.0000001192 ) 166 1 - vert 197 ( -0.1666666865 0.0000001192 ) 190 1 - vert 198 ( -0.0833333135 1.0000001192 ) 167 1 - vert 199 ( -0.0833333135 0.0000001192 ) 191 1 - - numtris 192 - tri 0 2 1 0 - tri 1 0 1 3 - tri 2 0 3 4 - tri 3 4 3 5 - tri 4 4 5 6 - tri 5 6 5 7 - tri 6 6 7 8 - tri 7 8 7 9 - tri 8 8 9 10 - tri 9 10 9 11 - tri 10 10 11 12 - tri 11 12 11 13 - tri 12 15 12 14 - tri 13 12 13 14 - tri 14 17 15 16 - tri 15 15 14 16 - tri 16 19 17 18 - tri 17 17 16 18 - tri 18 21 19 20 - tri 19 19 18 20 - tri 20 23 21 22 - tri 21 21 20 22 - tri 22 25 23 24 - tri 23 23 22 24 - tri 24 27 25 26 - tri 25 25 24 26 - tri 26 29 27 28 - tri 27 27 26 28 - tri 28 31 29 30 - tri 29 29 28 30 - tri 30 33 31 32 - tri 31 31 30 32 - tri 32 35 33 34 - tri 33 33 32 34 - tri 34 37 35 36 - tri 35 35 34 36 - tri 36 40 39 38 - tri 37 38 39 41 - tri 38 38 41 42 - tri 39 42 41 43 - tri 40 42 43 44 - tri 41 44 43 45 - tri 42 44 45 46 - tri 43 46 45 47 - tri 44 46 47 48 - tri 45 48 47 49 - tri 46 48 49 2 - tri 47 2 49 1 - tri 48 52 51 50 - tri 49 51 53 50 - tri 50 51 54 53 - tri 51 54 55 53 - tri 52 54 56 55 - tri 53 56 57 55 - tri 54 56 58 57 - tri 55 58 59 57 - tri 56 58 60 59 - tri 57 60 61 59 - tri 58 60 62 61 - tri 59 62 63 61 - tri 60 65 64 62 - tri 61 62 64 63 - tri 62 67 66 65 - tri 63 65 66 64 - tri 64 69 68 67 - tri 65 67 68 66 - tri 66 71 70 69 - tri 67 69 70 68 - tri 68 73 72 71 - tri 69 71 72 70 - tri 70 75 74 73 - tri 71 73 74 72 - tri 72 77 76 75 - tri 73 75 76 74 - tri 74 79 78 77 - tri 75 77 78 76 - tri 76 81 80 79 - tri 77 79 80 78 - tri 78 83 82 81 - tri 79 81 82 80 - tri 80 85 84 83 - tri 81 83 84 82 - tri 82 87 86 85 - tri 83 85 86 84 - tri 84 90 89 88 - tri 85 89 91 88 - tri 86 89 92 91 - tri 87 92 93 91 - tri 88 92 94 93 - tri 89 94 95 93 - tri 90 94 96 95 - tri 91 96 97 95 - tri 92 96 98 97 - tri 93 98 99 97 - tri 94 98 52 99 - tri 95 52 50 99 - tri 96 102 101 100 - tri 97 100 101 103 - tri 98 100 103 104 - tri 99 104 103 105 - tri 100 104 105 106 - tri 101 106 105 107 - tri 102 106 107 108 - tri 103 108 107 109 - tri 104 108 109 110 - tri 105 110 109 111 - tri 106 110 111 112 - tri 107 112 111 113 - tri 108 115 112 114 - tri 109 112 113 114 - tri 110 117 115 116 - tri 111 115 114 116 - tri 112 119 117 118 - tri 113 117 116 118 - tri 114 121 119 120 - tri 115 119 118 120 - tri 116 123 121 122 - tri 117 121 120 122 - tri 118 125 123 124 - tri 119 123 122 124 - tri 120 127 125 126 - tri 121 125 124 126 - tri 122 129 127 128 - tri 123 127 126 128 - tri 124 131 129 130 - tri 125 129 128 130 - tri 126 133 131 132 - tri 127 131 130 132 - tri 128 135 133 134 - tri 129 133 132 134 - tri 130 137 135 136 - tri 131 135 134 136 - tri 132 140 139 138 - tri 133 138 139 141 - tri 134 138 141 142 - tri 135 142 141 143 - tri 136 142 143 144 - tri 137 144 143 145 - tri 138 144 145 146 - tri 139 146 145 147 - tri 140 146 147 148 - tri 141 148 147 149 - tri 142 148 149 102 - tri 143 102 149 101 - tri 144 152 151 150 - tri 145 151 153 150 - tri 146 151 154 153 - tri 147 154 155 153 - tri 148 154 156 155 - tri 149 156 157 155 - tri 150 156 158 157 - tri 151 158 159 157 - tri 152 158 160 159 - tri 153 160 161 159 - tri 154 160 162 161 - tri 155 162 163 161 - tri 156 165 164 162 - tri 157 162 164 163 - tri 158 167 166 165 - tri 159 165 166 164 - tri 160 169 168 167 - tri 161 167 168 166 - tri 162 171 170 169 - tri 163 169 170 168 - tri 164 173 172 171 - tri 165 171 172 170 - tri 166 175 174 173 - tri 167 173 174 172 - tri 168 177 176 175 - tri 169 175 176 174 - tri 170 179 178 177 - tri 171 177 178 176 - tri 172 181 180 179 - tri 173 179 180 178 - tri 174 183 182 181 - tri 175 181 182 180 - tri 176 185 184 183 - tri 177 183 184 182 - tri 178 187 186 185 - tri 179 185 186 184 - tri 180 190 189 188 - tri 181 189 191 188 - tri 182 189 192 191 - tri 183 192 193 191 - tri 184 192 194 193 - tri 185 194 195 193 - tri 186 194 196 195 - tri 187 196 197 195 - tri 188 196 198 197 - tri 189 198 199 197 - tri 190 198 152 199 - tri 191 152 150 199 - - numweights 192 - weight 0 19 1 ( -8.7130708694 22.7473716736 -1.0865210295 ) - weight 1 19 1 ( -8.3702049255 21.8558540344 -5.0402579308 ) - weight 2 19 1 ( -7.3649687767 19.9481563568 -8.6295309067 ) - weight 3 19 1 ( -5.7658720016 17.1542987823 -11.6097364426 ) - weight 4 19 1 ( -3.6818885803 13.6646604538 -13.7777795792 ) - weight 5 19 1 ( -1.2550398111 9.7170696259 -14.9859104156 ) - weight 6 19 1 ( 1.3492918015 5.5805382729 -15.151799202 ) - weight 7 19 1 ( 3.9536235332 1.5369670391 -14.2641363144 ) - weight 8 19 1 ( 6.3804750443 -2.1380825043 -12.3834199905 ) - weight 9 19 1 ( 8.4644575119 -5.1941604614 -9.6378135681 ) - weight 10 19 1 ( 10.0635547638 -7.4229989052 -6.2144289017 ) - weight 11 19 1 ( 11.0687885284 -8.672712326 -2.346560955 ) - weight 12 19 1 ( 11.411655426 -8.8581228256 1.7021991014 ) - weight 13 19 1 ( 11.0687885284 -7.9666099548 5.6559362411 ) - weight 14 19 1 ( 10.0635547638 -6.0589127541 9.2452087402 ) - weight 15 19 1 ( 8.4644575119 -3.2650520802 12.2254142761 ) - weight 16 19 1 ( 6.3804750443 0.2245832086 14.3934583664 ) - weight 17 19 1 ( 3.9536235332 4.1721782684 15.6015892029 ) - weight 18 19 1 ( 1.3492918015 8.3087091446 15.7674770355 ) - weight 19 19 1 ( -1.2550398111 12.3522806168 14.8798151016 ) - weight 20 19 1 ( -3.6818885803 16.0273265839 12.9990987778 ) - weight 21 19 1 ( -5.7658720016 19.0834083557 10.2534914017 ) - weight 22 19 1 ( -7.3649687767 21.3122425079 6.8301072121 ) - weight 23 19 1 ( -8.3702049255 22.5619564056 2.9622392654 ) - weight 24 19 1 ( -11.4116802216 21.3346614838 -0.9618701935 ) - weight 25 19 1 ( -11.0688142776 20.4431438446 -4.9156074524 ) - weight 26 19 1 ( -10.0635795593 18.5354557037 -8.5048809052 ) - weight 27 19 1 ( -8.4644813538 15.7415904999 -11.4850854874 ) - weight 28 19 1 ( -6.3804974556 12.251958847 -13.6531295776 ) - weight 29 19 1 ( -3.9536485672 8.3043642044 -14.8612594604 ) - weight 30 19 1 ( -1.3493177891 4.1678328514 -15.0271482468 ) - weight 31 19 1 ( 1.2550139427 0.1242618635 -14.1394863129 ) - weight 32 19 1 ( 3.6818642616 -3.5507876873 -12.258769989 ) - weight 33 19 1 ( 5.7658486366 -6.606865406 -9.5131626129 ) - weight 34 19 1 ( 7.3649454117 -8.8357038498 -6.0897784233 ) - weight 35 19 1 ( 8.3701791763 -10.0854139328 -2.2219109535 ) - weight 36 19 1 ( 8.7130451202 -10.2708282471 1.8268495798 ) - weight 37 19 1 ( 8.3701791763 -9.3793115616 5.7805862427 ) - weight 38 19 1 ( 7.3649454117 -7.4716181755 9.3698596954 ) - weight 39 19 1 ( 5.7658486366 -4.6777572632 12.3500642776 ) - weight 40 19 1 ( 3.6818642616 -1.1881220341 14.5181083679 ) - weight 41 19 1 ( 1.2550139427 2.7594730854 15.7262392044 ) - weight 42 19 1 ( -1.3493177891 6.8960042 15.892127037 ) - weight 43 19 1 ( -3.9536485672 10.9395751953 15.0044660568 ) - weight 44 19 1 ( -6.3804974556 14.6146249771 13.1237487793 ) - weight 45 19 1 ( -8.4644813538 17.6706981659 10.3781423569 ) - weight 46 19 1 ( -10.0635795593 19.8995418549 6.9547572136 ) - weight 47 19 1 ( -11.0688142776 21.1492481232 3.0868899822 ) - weight 48 19 1 ( -8.7130708694 -10.2750082016 1.8272184134 ) - weight 49 19 1 ( -8.3702049255 -10.0895938873 -2.22154212 ) - weight 50 19 1 ( -7.3649687767 -8.839887619 -6.0894093513 ) - weight 51 19 1 ( -5.7658720016 -6.6110453606 -9.512793541 ) - weight 52 19 1 ( -3.6818885803 -3.5549676418 -12.2584009171 ) - weight 53 19 1 ( -1.2550398111 0.120078139 -14.1391172409 ) - weight 54 19 1 ( 1.3492918015 4.1636528969 -15.0267791748 ) - weight 55 19 1 ( 3.9536235332 8.3001842499 -14.8608913422 ) - weight 56 19 1 ( 6.3804740906 12.2477788925 -13.6527605057 ) - weight 57 19 1 ( 8.4644575119 15.7374105453 -11.4847164154 ) - weight 58 19 1 ( 10.0635547638 18.5312747955 -8.5045118332 ) - weight 59 19 1 ( 11.0687885284 20.4389724731 -4.9152393341 ) - weight 60 19 1 ( 11.411655426 21.3304824829 -0.9615013599 ) - weight 61 19 1 ( 11.0687885284 21.1450748444 3.0872581005 ) - weight 62 19 1 ( 10.0635547638 19.8953609467 6.9551258087 ) - weight 63 19 1 ( 8.4644575119 17.666519165 10.3785104752 ) - weight 64 19 1 ( 6.3804740906 14.6104450226 13.1241168976 ) - weight 65 19 1 ( 3.9536235332 10.9353952408 15.0048351288 ) - weight 66 19 1 ( 1.3492918015 6.8918242455 15.892496109 ) - weight 67 19 1 ( -1.2550398111 2.7552893162 15.72660923 ) - weight 68 19 1 ( -3.6818885803 -1.1923019886 14.5184774399 ) - weight 69 19 1 ( -5.7658720016 -4.6819372177 12.3504333496 ) - weight 70 19 1 ( -7.3649687767 -7.4758019447 9.3702287674 ) - weight 71 19 1 ( -8.3702049255 -9.3834915161 5.7809553146 ) - weight 72 19 1 ( -11.4116802216 -8.8623027802 1.702567935 ) - weight 73 19 1 ( -11.0688142776 -8.6768884659 -2.3461925983 ) - weight 74 19 1 ( -10.0635795593 -7.4271821976 -6.2140598297 ) - weight 75 19 1 ( -8.4644813538 -5.198340416 -9.6374444962 ) - weight 76 19 1 ( -6.3804974556 -2.1422624588 -12.3830509186 ) - weight 77 19 1 ( -3.9536485672 1.5327833891 -14.2637672424 ) - weight 78 19 1 ( -1.3493177891 5.5763583183 -15.15143013 ) - weight 79 19 1 ( 1.2550139427 9.7128896713 -14.9855413437 ) - weight 80 19 1 ( 3.6818642616 13.6604881287 -13.7774114609 ) - weight 81 19 1 ( 5.7658486366 17.1501197815 -11.6093673706 ) - weight 82 19 1 ( 7.3649454117 19.943977356 -8.6291618347 ) - weight 83 19 1 ( 8.3701791763 21.8516731262 -5.0398893356 ) - weight 84 19 1 ( 8.7130451202 22.7431907654 -1.0861521959 ) - weight 85 19 1 ( 8.3701791763 22.5577774048 2.962608099 ) - weight 86 19 1 ( 7.3649454117 21.3080635071 6.8304758072 ) - weight 87 19 1 ( 5.7658486366 19.0792274475 10.2538604736 ) - weight 88 19 1 ( 3.6818642616 16.0231533051 12.9994668961 ) - weight 89 19 1 ( 1.2550139427 12.3481006622 14.8801841736 ) - weight 90 19 1 ( -1.3493177891 8.3045291901 15.7678451538 ) - weight 91 19 1 ( -3.9536485672 4.1679944992 15.6019582748 ) - weight 92 19 1 ( -6.3804974556 0.2204032838 14.3938264847 ) - weight 93 19 1 ( -8.4644813538 -3.2692317963 12.2257833481 ) - weight 94 19 1 ( -10.0635795593 -6.0630965233 9.2455778122 ) - weight 95 19 1 ( -11.0688142776 -7.9707860947 5.6563048363 ) - weight 96 19 1 ( -0.8230085969 8.9617033005 16.5407924652 ) - weight 97 19 1 ( -5.5744194984 6.4254136086 16.2053947449 ) - weight 98 19 1 ( -10.00203228 3.9640464783 14.7831144333 ) - weight 99 19 1 ( -13.804107666 1.7453427315 12.3708791733 ) - weight 100 19 1 ( -16.721540451 -0.0794939473 9.1330804825 ) - weight 101 19 1 ( -18.5555152893 -1.3861038685 5.290365696 ) - weight 102 19 1 ( -19.1810531616 -2.0854516029 1.1046108007 ) - weight 103 19 1 ( -18.5555171967 -2.1298692226 -3.1389317513 ) - weight 104 19 1 ( -16.721540451 -1.5163309574 -7.1510725021 ) - weight 105 19 1 ( -13.804107666 -0.2866515219 -10.6583881378 ) - weight 106 19 1 ( -10.00203228 1.4753719568 -13.4218626022 ) - weight 107 19 1 ( -5.5744194984 3.6496579647 -15.2531700134 ) - weight 108 19 1 ( -0.8230085969 6.0880289078 -16.0275115967 ) - weight 109 19 1 ( 3.9284024239 8.6243257523 -15.6921129227 ) - weight 110 19 1 ( 8.356013298 11.0856895447 -14.2698326111 ) - weight 111 19 1 ( 12.1580886841 13.304397583 -11.8575983047 ) - weight 112 19 1 ( 15.0755243301 15.1292304993 -8.6197986603 ) - weight 113 19 1 ( 16.9095020294 16.4358444214 -4.7770829201 ) - weight 114 19 1 ( 17.5350399017 17.135187149 -0.5913280249 ) - weight 115 19 1 ( 16.9095020294 17.179605484 3.6522147655 ) - weight 116 19 1 ( 15.0755243301 16.5660667419 7.6643538475 ) - weight 117 19 1 ( 12.1580886841 15.336391449 11.1716690063 ) - weight 118 19 1 ( 8.356013298 13.5743646622 13.9351444244 ) - weight 119 19 1 ( 3.9284033775 11.4000816345 15.7664527893 ) - weight 120 19 1 ( 0.8181299567 6.3843297958 16.7682094574 ) - weight 121 19 1 ( -3.9332809448 3.8480365276 16.4328098297 ) - weight 122 19 1 ( -8.3608932495 1.3866690397 15.0105295181 ) - weight 123 19 1 ( -12.1629686356 -0.8320346475 12.5982952118 ) - weight 124 19 1 ( -15.0804042816 -2.6568713188 9.3604955673 ) - weight 125 19 1 ( -16.9143791199 -3.9634811878 5.5177812576 ) - weight 126 19 1 ( -17.5399150848 -4.6628289223 1.3320264816 ) - weight 127 19 1 ( -16.9143829346 -4.7072429657 -2.911516428 ) - weight 128 19 1 ( -15.0804042816 -4.0937085152 -6.9236569405 ) - weight 129 19 1 ( -12.1629686356 -2.8640289307 -10.4309720993 ) - weight 130 19 1 ( -8.3608932495 -1.1020054817 -13.1944475174 ) - weight 131 19 1 ( -3.9332809448 1.0722807646 -15.0257539749 ) - weight 132 19 1 ( 0.8181299567 3.5106556416 -15.8000965118 ) - weight 133 19 1 ( 5.5695419312 6.0469450951 -15.4646968842 ) - weight 134 19 1 ( 9.9971523285 8.50831604 -14.0424165726 ) - weight 135 19 1 ( 13.7992277145 10.727016449 -11.6301822662 ) - weight 136 19 1 ( 16.7166652679 12.551856041 -8.3923835754 ) - weight 137 19 1 ( 18.5506381989 13.8584699631 -4.5496673584 ) - weight 138 19 1 ( 19.1761779785 14.5578145981 -0.3639126718 ) - weight 139 19 1 ( 18.5506381989 14.6022319794 3.8796300888 ) - weight 140 19 1 ( 16.7166652679 13.9886932373 7.8917694092 ) - weight 141 19 1 ( 13.7992277145 12.7590103149 11.3990850449 ) - weight 142 19 1 ( 9.9971523285 10.9969902039 14.162560463 ) - weight 143 19 1 ( 5.5695419312 8.8227005005 15.9938688278 ) - weight 144 19 1 ( 0.8229850531 8.9617033005 16.5407924652 ) - weight 145 19 1 ( 5.5743966103 6.4254136086 16.2053947449 ) - weight 146 19 1 ( 10.0020074844 3.9640464783 14.7831144333 ) - weight 147 19 1 ( 13.8040838242 1.7453427315 12.3708791733 ) - weight 148 19 1 ( 16.7215194702 -0.0794939473 9.1330804825 ) - weight 149 19 1 ( 18.5554943085 -1.3861038685 5.290365696 ) - weight 150 19 1 ( 19.1810321808 -2.0854516029 1.1046108007 ) - weight 151 19 1 ( 18.5554962158 -2.1298692226 -3.1389317513 ) - weight 152 19 1 ( 16.7215194702 -1.5163309574 -7.1510725021 ) - weight 153 19 1 ( 13.8040838242 -0.2866515219 -10.6583881378 ) - weight 154 19 1 ( 10.0020074844 1.4753719568 -13.4218626022 ) - weight 155 19 1 ( 5.5743966103 3.6496579647 -15.2531700134 ) - weight 156 19 1 ( 0.8229850531 6.0880289078 -16.0275115967 ) - weight 157 19 1 ( -3.9284272194 8.6243257523 -15.6921129227 ) - weight 158 19 1 ( -8.3560380936 11.0856895447 -14.2698326111 ) - weight 159 19 1 ( -12.1581144333 13.304397583 -11.8575983047 ) - weight 160 19 1 ( -15.0755491257 15.1292304993 -8.6197986603 ) - weight 161 19 1 ( -16.9095249176 16.4358444214 -4.7770829201 ) - weight 162 19 1 ( -17.5350608826 17.135187149 -0.5913280249 ) - weight 163 19 1 ( -16.9095249176 17.179605484 3.6522147655 ) - weight 164 19 1 ( -15.0755491257 16.5660667419 7.6643538475 ) - weight 165 19 1 ( -12.1581144333 15.336391449 11.1716690063 ) - weight 166 19 1 ( -8.3560380936 13.5743646622 13.9351444244 ) - weight 167 19 1 ( -3.9284272194 11.4000816345 15.7664527893 ) - weight 168 19 1 ( -0.8181535006 6.3843297958 16.7682094574 ) - weight 169 19 1 ( 3.9332582951 3.8480365276 16.4328098297 ) - weight 170 19 1 ( 8.3608694077 1.3866690397 15.0105295181 ) - weight 171 19 1 ( 12.1629447937 -0.8320346475 12.5982952118 ) - weight 172 19 1 ( 15.0803813934 -2.6568713188 9.3604955673 ) - weight 173 19 1 ( 16.9143562317 -3.9634811878 5.5177812576 ) - weight 174 19 1 ( 17.5398921967 -4.6628251076 1.332026124 ) - weight 175 19 1 ( 16.914358139 -4.7072429657 -2.911516428 ) - weight 176 19 1 ( 15.0803813934 -4.0937085152 -6.9236569405 ) - weight 177 19 1 ( 12.1629447937 -2.8640289307 -10.4309720993 ) - weight 178 19 1 ( 8.3608694077 -1.1020054817 -13.1944475174 ) - weight 179 19 1 ( 3.9332582951 1.0722807646 -15.0257539749 ) - weight 180 19 1 ( -0.8181535006 3.5106556416 -15.8000965118 ) - weight 181 19 1 ( -5.5695643425 6.0469450951 -15.4646968842 ) - weight 182 19 1 ( -9.9971780777 8.5083122253 -14.0424165726 ) - weight 183 19 1 ( -13.7992544174 10.727016449 -11.6301822662 ) - weight 184 19 1 ( -16.7166881561 12.551856041 -8.3923835754 ) - weight 185 19 1 ( -18.5506649017 13.8584699631 -4.5496673584 ) - weight 186 19 1 ( -19.176202774 14.5578145981 -0.3639126718 ) - weight 187 19 1 ( -18.5506649017 14.6022319794 3.8796300888 ) - weight 188 19 1 ( -16.7166881561 13.9886932373 7.8917694092 ) - weight 189 19 1 ( -13.7992544174 12.7590103149 11.3990850449 ) - weight 190 19 1 ( -9.9971780777 10.9969863892 14.162560463 ) - weight 191 19 1 ( -5.5695662498 8.8227005005 15.9938688278 ) -} - -mesh { - // meshes: skeletonmesh - shader "models/monsters/skeleton/skeleton01" - - numverts 372 - vert 0 ( 0.8026440144 0.6206830144 ) 0 1 - vert 1 ( 0.7668219805 0.5835820436 ) 1 1 - vert 2 ( 0.7401260138 0.6223009825 ) 2 1 - vert 3 ( 0.6888970137 0.9726120234 ) 3 1 - vert 4 ( 0.6371999979 0.9106199741 ) 4 1 - vert 5 ( 0.6149479747 0.9653829932 ) 5 1 - vert 6 ( 0.6791059971 0.9119340181 ) 6 1 - vert 7 ( 0.7289540172 0.9764590263 ) 7 1 - vert 8 ( 0.5308520198 0.6667929888 ) 8 1 - vert 9 ( 0.5844609737 0.7127549648 ) 9 1 - vert 10 ( 0.6253830194 0.7026699781 ) 10 1 - vert 11 ( 0.5966519713 0.6402909756 ) 11 1 - vert 12 ( 0.5374540091 0.6089029908 ) 0 1 - vert 13 ( 0.7990319729 0.6895979643 ) 8 1 - vert 14 ( 0.7294830084 0.6895849705 ) 12 1 - vert 15 ( 0.7028179765 0.622699976 ) 13 1 - vert 16 ( 0.5796539783 0.942399025 ) 14 1 - vert 17 ( 0.6729739904 0.6381289959 ) 15 1 - vert 18 ( 0.7918499708 0.7283949852 ) 9 1 - vert 19 ( 0.7538610101 0.9771040082 ) 14 1 - vert 20 ( 0.5886870027 0.6082040071 ) 16 1 - vert 21 ( 0.5768579841 0.5737160444 ) 1 1 - vert 22 ( 0.6288759708 0.6016839743 ) 17 1 - vert 23 ( 0.6342300177 0.2943660021 ) 18 1 - vert 24 ( 0.6109859943 0.3197550178 ) 19 1 - vert 25 ( 0.6600620151 0.3993710279 ) 20 1 - vert 26 ( 0.7065430284 0.3011270165 ) 21 1 - vert 27 ( 0.7182130218 0.1945279837 ) 18 1 - vert 28 ( 0.7491179705 0.1550670266 ) 22 2 - vert 29 ( 0.6223570108 0.1684280038 ) 24 2 - vert 30 ( 0.6904489994 0.2206670046 ) 19 1 - vert 31 ( 0.588737011 0.2635300159 ) 26 2 - vert 32 ( 0.8046090007 0.2368130088 ) 28 1 - vert 33 ( 0.8096550107 0.2689930201 ) 19 1 - vert 34 ( 0.9298340082 0.2670969963 ) 26 2 - vert 35 ( 0.8681640029 0.1429920197 ) 29 2 - vert 36 ( 0.7927600145 0.1931170225 ) 31 1 - vert 37 ( 0.7428609729 0.4145510197 ) 32 1 - vert 38 ( 0.7051759958 0.4012230039 ) 33 1 - vert 39 ( 0.7438089848 0.5267189741 ) 34 1 - vert 40 ( 0.7097600102 0.5271840096 ) 35 1 - vert 41 ( 0.6095650196 0.3886600137 ) 32 1 - vert 42 ( 0.5822100043 0.532671988 ) 34 1 - vert 43 ( 0.6270830035 0.5551760197 ) 36 2 - vert 44 ( 0.6788089871 0.5328630209 ) 38 1 - vert 45 ( 0.5856580138 0.3256009817 ) 28 1 - vert 46 ( 0.7418850064 0.2916539907 ) 39 1 - vert 47 ( 0.1707790047 0.8662129641 ) 40 1 - vert 48 ( 0.2291119993 0.9183689952 ) 3 1 - vert 49 ( 0.2415399998 0.854896009 ) 5 1 - vert 50 ( 0.3366569877 0.8804069757 ) 14 1 - vert 51 ( 0.3310590088 0.92395401 ) 7 1 - vert 52 ( 0.3786109984 0.96618402 ) 41 1 - vert 53 ( 0.3850030005 0.8501830101 ) 42 1 - vert 54 ( 0.1186010018 0.9743800163 ) 43 1 - vert 55 ( 0.1264079958 0.800737977 ) 44 1 - vert 56 ( 0.0295180008 0.85096699 ) 45 1 - vert 57 ( 0.7779960036 0.299004972 ) 31 1 - vert 58 ( 0.7543010116 0.3283979893 ) 46 1 - vert 59 ( 0.7882750034 0.340692997 ) 28 1 - vert 60 ( 0.0270659998 0.9261540174 ) 47 1 - vert 61 ( 0.7452110052 0.1171090007 ) 48 2 - vert 62 ( 0.5251039863 0.1227070093 ) 50 2 - vert 63 ( 0.5251039863 0.0515329838 ) 52 2 - vert 64 ( 0.6964409947 0.0499389768 ) 54 2 - vert 65 ( 0.8045489788 0.0307829976 ) 54 2 - vert 66 ( 0.9730749726 0.0309100151 ) 56 2 - vert 67 ( 0.9344189763 0.0043249726 ) 52 2 - vert 68 ( 0.7632390261 0.0729789734 ) 58 2 - vert 69 ( 0.8439909816 0.063552022 ) 60 2 - vert 70 ( 0.9845280051 0.0645599961 ) 62 2 - vert 71 ( 0.5279669762 0.1925209761 ) 64 2 - vert 72 ( 0.5265349746 0.2659410238 ) 66 2 - vert 73 ( 0.6909919977 0.2670210004 ) 39 1 - vert 74 ( 0.6527500153 0.2667300105 ) 31 1 - vert 75 ( 0.9858170152 0.2695270181 ) 66 2 - vert 76 ( 0.7668219805 0.5835820436 ) 68 1 - vert 77 ( 0.8026440144 0.6206830144 ) 69 1 - vert 78 ( 0.7401260138 0.6223009825 ) 70 1 - vert 79 ( 0.6371999979 0.9106199741 ) 71 1 - vert 80 ( 0.6888970137 0.9726120234 ) 72 1 - vert 81 ( 0.6149479747 0.9653829932 ) 73 1 - vert 82 ( 0.6791059971 0.9119340181 ) 74 1 - vert 83 ( 0.7289540172 0.9764590263 ) 75 1 - vert 84 ( 0.5844609737 0.7127549648 ) 76 1 - vert 85 ( 0.5308520198 0.6667929888 ) 77 1 - vert 86 ( 0.6253830194 0.7026699781 ) 78 1 - vert 87 ( 0.5966519713 0.6402909756 ) 79 1 - vert 88 ( 0.5374540091 0.6089029908 ) 69 1 - vert 89 ( 0.7990319729 0.6895979643 ) 77 1 - vert 90 ( 0.7294830084 0.6895849705 ) 80 1 - vert 91 ( 0.7028179765 0.622699976 ) 81 1 - vert 92 ( 0.5796539783 0.942399025 ) 82 1 - vert 93 ( 0.6729739904 0.6381289959 ) 83 1 - vert 94 ( 0.7918499708 0.7283949852 ) 76 1 - vert 95 ( 0.7538610101 0.9771040082 ) 82 1 - vert 96 ( 0.5768579841 0.5737160444 ) 68 1 - vert 97 ( 0.5886870027 0.6082040071 ) 84 1 - vert 98 ( 0.6288759708 0.6016839743 ) 85 1 - vert 99 ( 0.6109859943 0.3197550178 ) 86 1 - vert 100 ( 0.6342300177 0.2943660021 ) 87 1 - vert 101 ( 0.6600620151 0.3993710279 ) 88 1 - vert 102 ( 0.7065430284 0.3011270165 ) 89 1 - vert 103 ( 0.7491179705 0.1550670266 ) 90 2 - vert 104 ( 0.7182130218 0.1945279837 ) 87 1 - vert 105 ( 0.6223570108 0.1684280038 ) 92 2 - vert 106 ( 0.6904489994 0.2206670046 ) 86 1 - vert 107 ( 0.588737011 0.2635300159 ) 94 2 - vert 108 ( 0.8096550107 0.2689930201 ) 86 1 - vert 109 ( 0.8046090007 0.2368130088 ) 96 1 - vert 110 ( 0.9298340082 0.2670969963 ) 94 2 - vert 111 ( 0.7927600145 0.1931170225 ) 97 1 - vert 112 ( 0.8681640029 0.1429920197 ) 98 2 - vert 113 ( 0.7051759958 0.4012230039 ) 100 1 - vert 114 ( 0.7428609729 0.4145510197 ) 101 1 - vert 115 ( 0.7438089848 0.5267189741 ) 102 1 - vert 116 ( 0.7097600102 0.5271840096 ) 103 1 - vert 117 ( 0.5822100043 0.532671988 ) 102 1 - vert 118 ( 0.6095650196 0.3886600137 ) 101 1 - vert 119 ( 0.6270830035 0.5551760197 ) 104 2 - vert 120 ( 0.6788089871 0.5328630209 ) 106 1 - vert 121 ( 0.5856580138 0.3256009817 ) 96 1 - vert 122 ( 0.7418850064 0.2916539907 ) 107 1 - vert 123 ( 0.2291119993 0.9183689952 ) 72 1 - vert 124 ( 0.1707790047 0.8662129641 ) 108 1 - vert 125 ( 0.2415399998 0.854896009 ) 73 1 - vert 126 ( 0.3310590088 0.92395401 ) 75 1 - vert 127 ( 0.3366569877 0.8804069757 ) 82 1 - vert 128 ( 0.3786109984 0.96618402 ) 109 1 - vert 129 ( 0.3850030005 0.8501830101 ) 110 1 - vert 130 ( 0.1186010018 0.9743800163 ) 111 1 - vert 131 ( 0.1264079958 0.800737977 ) 112 1 - vert 132 ( 0.0295180008 0.85096699 ) 113 1 - vert 133 ( 0.7779960036 0.299004972 ) 97 1 - vert 134 ( 0.7543010116 0.3283979893 ) 114 1 - vert 135 ( 0.7882750034 0.340692997 ) 96 1 - vert 136 ( 0.0270659998 0.9261540174 ) 115 1 - vert 137 ( 0.7452110052 0.1171090007 ) 116 2 - vert 138 ( 0.6964409947 0.0499389768 ) 118 2 - vert 139 ( 0.8045489788 0.0307829976 ) 118 2 - vert 140 ( 0.7632390261 0.0729789734 ) 120 2 - vert 141 ( 0.8439909816 0.063552022 ) 122 2 - vert 142 ( 0.6527500153 0.2667300105 ) 97 1 - vert 143 ( 0.6909919977 0.2670210004 ) 107 1 - vert 144 ( 0.8717240095 0.4802880287 ) 124 1 - vert 145 ( 0.8108659983 0.3807780147 ) 125 1 - vert 146 ( 0.8367549777 0.4778929949 ) 126 1 - vert 147 ( 0.8495640159 0.3780949712 ) 127 1 - vert 148 ( 0.9646239877 0.3814439774 ) 125 1 - vert 149 ( 0.9226760268 0.3641819954 ) 128 1 - vert 150 ( 0.9630079865 0.4679120183 ) 126 1 - vert 151 ( 0.9065719843 0.4723510146 ) 129 1 - vert 152 ( 0.8823249936 0.3745369911 ) 130 1 - vert 153 ( 0.9541329741 0.5380940437 ) 131 1 - vert 154 ( 0.9447050095 0.5820820332 ) 132 1 - vert 155 ( 0.98724401 0.564136982 ) 133 1 - vert 156 ( 0.9154840112 0.5530990362 ) 134 1 - vert 157 ( 0.9818940163 0.5374100208 ) 135 1 - vert 158 ( 0.8870570064 0.5537520051 ) 136 1 - vert 159 ( 0.8386009932 0.5174820423 ) 135 1 - vert 160 ( 0.8558560014 0.3233230114 ) 137 1 - vert 161 ( 0.8454189897 0.284619987 ) 138 1 - vert 162 ( 0.806877017 0.3265219927 ) 139 1 - vert 163 ( 0.9731519818 0.3037179708 ) 139 1 - vert 164 ( 0.9293509722 0.2808030248 ) 138 1 - vert 165 ( 0.9315080047 0.314432025 ) 140 1 - vert 166 ( 0.893016994 0.3161299825 ) 141 1 - vert 167 ( 0.9883210063 0.5862360001 ) 142 1 - vert 168 ( 0.9733719826 0.7403509617 ) 143 1 - vert 169 ( 0.8645979762 0.7005209923 ) 144 1 - vert 170 ( 0.8352749944 0.5617209673 ) 142 1 - vert 171 ( 0.8126869798 0.7159180045 ) 143 1 - vert 172 ( 0.8420159817 0.7602089643 ) 145 1 - vert 173 ( 0.8933320045 0.7110099792 ) 146 1 - vert 174 ( 0.8756759763 0.7600719929 ) 147 1 - vert 175 ( 0.9313480258 0.7706699967 ) 148 1 - vert 176 ( 0.9717509747 0.7697210312 ) 149 1 - vert 177 ( 0.933619976 0.7429389954 ) 150 1 - vert 178 ( 0.8016880155 0.7549489737 ) 149 1 - vert 179 ( 0.9202539921 0.5761120319 ) 151 1 - vert 180 ( 0.8861579895 0.5804849863 ) 152 1 - vert 181 ( 0.8773210049 0.7865970135 ) 145 1 - vert 182 ( 0.9322090149 0.7844650149 ) 149 1 - vert 183 ( 0.8206250072 0.5392270088 ) 133 1 - vert 184 ( 0.8482810259 0.8981170058 ) 153 1 - vert 185 ( 0.7897199988 0.8616859913 ) 154 3 - vert 186 ( 0.8015120029 0.9534640312 ) 157 3 - vert 187 ( 0.8729519844 0.9907349944 ) 160 2 - vert 188 ( 0.9272400141 0.9562820196 ) 162 2 - vert 189 ( 0.8227530122 0.7990909815 ) 164 3 - vert 190 ( 0.8966109753 0.7954459786 ) 167 1 - vert 191 ( 0.9852830172 0.9051989913 ) 168 4 - vert 192 ( 0.9680870175 0.8457790017 ) 172 2 - vert 193 ( 0.9114339948 0.8721209764 ) 174 1 - vert 194 ( 0.2660759985 0.4170609713 ) 175 1 - vert 195 ( 0.2450699955 0.3586040139 ) 176 1 - vert 196 ( 0.1257019937 0.5028610229 ) 177 2 - vert 197 ( 0.0104240002 0.4867990017 ) 179 1 - vert 198 ( 0.5756260157 0.747789979 ) 180 1 - vert 199 ( 0.492080003 0.8160920143 ) 181 1 - vert 200 ( 0.5640619993 0.8331360221 ) 182 1 - vert 201 ( 0.2439880073 0.6243480444 ) 183 1 - vert 202 ( 0.1405580044 0.5949649811 ) 184 1 - vert 203 ( 0.174921006 0.7193800211 ) 185 1 - vert 204 ( 0.2636289895 0.7209919691 ) 186 1 - vert 205 ( 0.0263589993 0.5314589739 ) 187 1 - vert 206 ( 0.006304 0.7300570011 ) 188 1 - vert 207 ( 0.3532910049 0.6952010393 ) 189 1 - vert 208 ( 0.2484299988 0.4642819762 ) 190 1 - vert 209 ( 0.3334769905 0.5614709854 ) 191 1 - vert 210 ( 0.3538120091 0.7960569859 ) 192 1 - vert 211 ( 0.4279470146 0.6008620262 ) 180 1 - vert 212 ( 0.1184170023 0.7840999961 ) 193 1 - vert 213 ( 0.4899739921 0.7472749949 ) 194 1 - vert 214 ( 0.4266610146 0.7429720163 ) 182 1 - vert 215 ( 0.2511610091 0.8109970093 ) 195 1 - vert 216 ( 0.5307220221 0.4036250114 ) 196 1 - vert 217 ( 0.293592006 0.3762480021 ) 176 1 - vert 218 ( 0.2733629942 0.4424099922 ) 197 1 - vert 219 ( 0.0259210002 0.3825129867 ) 196 1 - vert 220 ( 0.5643960238 0.9227529764 ) 198 2 - vert 221 ( 0.4856219888 0.9214929938 ) 200 2 - vert 222 ( 0.4753719866 0.8704279661 ) 202 2 - vert 223 ( 0.3949109912 0.8805750012 ) 198 2 - vert 224 ( 0.5035470128 0.6328110099 ) 204 1 - vert 225 ( 0.516651988 0.5222820044 ) 205 1 - vert 226 ( 0.4824169874 0.9738000035 ) 206 2 - vert 227 ( 0.4628440142 0.9760860205 ) 206 2 - vert 228 ( 0.2450699955 0.3586040139 ) 208 1 - vert 229 ( 0.2660759985 0.4170609713 ) 209 1 - vert 230 ( 0.1257019937 0.5028610229 ) 210 2 - vert 231 ( 0.5756260157 0.747789979 ) 212 1 - vert 232 ( 0.5640619993 0.8331360221 ) 213 1 - vert 233 ( 0.1405580044 0.5949649811 ) 214 1 - vert 234 ( 0.2439880073 0.6243480444 ) 215 1 - vert 235 ( 0.174921006 0.7193800211 ) 216 1 - vert 236 ( 0.2636289895 0.7209919691 ) 217 1 - vert 237 ( 0.3532910049 0.6952010393 ) 218 1 - vert 238 ( 0.2484299988 0.4642819762 ) 219 1 - vert 239 ( 0.3334769905 0.5614709854 ) 220 1 - vert 240 ( 0.3538120091 0.7960569859 ) 221 1 - vert 241 ( 0.4279470146 0.6008620262 ) 212 1 - vert 242 ( 0.1184170023 0.7840999961 ) 222 1 - vert 243 ( 0.4266610146 0.7429720163 ) 213 1 - vert 244 ( 0.2511610091 0.8109970093 ) 223 1 - vert 245 ( 0.293592006 0.3762480021 ) 208 1 - vert 246 ( 0.2733629942 0.4424099922 ) 224 1 - vert 247 ( 0.5643960238 0.9227529764 ) 225 2 - vert 248 ( 0.3949109912 0.8805750012 ) 225 2 - vert 249 ( 0.5139200091 0.6911820173 ) 227 1 - vert 250 ( 0.8108659983 0.3807780147 ) 228 1 - vert 251 ( 0.8717240095 0.4802880287 ) 229 1 - vert 252 ( 0.8367549777 0.4778929949 ) 230 1 - vert 253 ( 0.8495640159 0.3780949712 ) 231 1 - vert 254 ( 0.9226760268 0.3641819954 ) 232 1 - vert 255 ( 0.9646239877 0.3814439774 ) 228 1 - vert 256 ( 0.9630079865 0.4679120183 ) 230 1 - vert 257 ( 0.9065719843 0.4723510146 ) 233 1 - vert 258 ( 0.8823249936 0.3745369911 ) 234 1 - vert 259 ( 0.9447050095 0.5820820332 ) 235 1 - vert 260 ( 0.9541329741 0.5380940437 ) 236 1 - vert 261 ( 0.98724401 0.564136982 ) 237 1 - vert 262 ( 0.9154840112 0.5530990362 ) 238 1 - vert 263 ( 0.9818940163 0.5374100208 ) 239 1 - vert 264 ( 0.8870570064 0.5537520051 ) 240 1 - vert 265 ( 0.8386009932 0.5174820423 ) 239 1 - vert 266 ( 0.8454189897 0.284619987 ) 241 1 - vert 267 ( 0.8558560014 0.3233230114 ) 242 1 - vert 268 ( 0.806877017 0.3265219927 ) 243 1 - vert 269 ( 0.9293509722 0.2808030248 ) 241 1 - vert 270 ( 0.9731519818 0.3037179708 ) 243 1 - vert 271 ( 0.9315080047 0.314432025 ) 244 1 - vert 272 ( 0.893016994 0.3161299825 ) 245 1 - vert 273 ( 0.9883210063 0.5862360001 ) 246 1 - vert 274 ( 0.9733719826 0.7403509617 ) 247 1 - vert 275 ( 0.8352749944 0.5617209673 ) 246 1 - vert 276 ( 0.8645979762 0.7005209923 ) 248 1 - vert 277 ( 0.8126869798 0.7159180045 ) 247 1 - vert 278 ( 0.8420159817 0.7602089643 ) 249 1 - vert 279 ( 0.8933320045 0.7110099792 ) 250 1 - vert 280 ( 0.8756759763 0.7600719929 ) 251 1 - vert 281 ( 0.9313480258 0.7706699967 ) 252 1 - vert 282 ( 0.9717509747 0.7697210312 ) 253 1 - vert 283 ( 0.933619976 0.7429389954 ) 254 1 - vert 284 ( 0.8016880155 0.7549489737 ) 253 1 - vert 285 ( 0.9202539921 0.5761120319 ) 255 1 - vert 286 ( 0.8861579895 0.5804849863 ) 256 1 - vert 287 ( 0.8773210049 0.7865970135 ) 249 1 - vert 288 ( 0.9322090149 0.7844650149 ) 253 1 - vert 289 ( 0.8206250072 0.5392270088 ) 237 1 - vert 290 ( 0.8482810259 0.8981170058 ) 257 1 - vert 291 ( 0.7897199988 0.8616859913 ) 258 3 - vert 292 ( 0.8015120029 0.9534640312 ) 261 3 - vert 293 ( 0.8729519844 0.9907349944 ) 264 2 - vert 294 ( 0.9272400141 0.9562820196 ) 266 2 - vert 295 ( 0.8227530122 0.7990909815 ) 268 3 - vert 296 ( 0.8966109753 0.7954459786 ) 271 1 - vert 297 ( 0.9852830172 0.9051989913 ) 272 2 - vert 298 ( 0.9680870175 0.8457790017 ) 274 2 - vert 299 ( 0.9114339948 0.8721209764 ) 276 1 - vert 300 ( 0.2450699955 0.3586040139 ) 277 1 - vert 301 ( 0.2660759985 0.4170609713 ) 278 1 - vert 302 ( 0.1257019937 0.5028610229 ) 279 1 - vert 303 ( 0.0104240002 0.4867990017 ) 280 1 - vert 304 ( 0.1405580044 0.5949649811 ) 281 1 - vert 305 ( 0.2439880073 0.6243480444 ) 282 1 - vert 306 ( 0.174921006 0.7193800211 ) 283 1 - vert 307 ( 0.2636289895 0.7209919691 ) 284 1 - vert 308 ( 0.0263589993 0.5314589739 ) 285 1 - vert 309 ( 0.006304 0.7300570011 ) 286 1 - vert 310 ( 0.3532910049 0.6952010393 ) 287 1 - vert 311 ( 0.2484299988 0.4642819762 ) 288 1 - vert 312 ( 0.3334769905 0.5614709854 ) 289 1 - vert 313 ( 0.3538120091 0.7960569859 ) 290 1 - vert 314 ( 0.4279470146 0.6008620262 ) 291 1 - vert 315 ( 0.1184170023 0.7840999961 ) 292 1 - vert 316 ( 0.2511610091 0.8109970093 ) 293 1 - vert 317 ( 0.293592006 0.3762480021 ) 277 1 - vert 318 ( 0.5307220221 0.4036250114 ) 294 1 - vert 319 ( 0.2733629942 0.4424099922 ) 295 1 - vert 320 ( 0.0259210002 0.3825129867 ) 294 1 - vert 321 ( 0.4266610146 0.7429720163 ) 296 1 - vert 322 ( 0.516651988 0.5222820044 ) 297 1 - vert 323 ( 0.2660759985 0.4170609713 ) 298 1 - vert 324 ( 0.2450699955 0.3586040139 ) 299 1 - vert 325 ( 0.1257019937 0.5028610229 ) 300 1 - vert 326 ( 0.2439880073 0.6243480444 ) 301 1 - vert 327 ( 0.1405580044 0.5949649811 ) 302 1 - vert 328 ( 0.174921006 0.7193800211 ) 303 1 - vert 329 ( 0.2636289895 0.7209919691 ) 304 1 - vert 330 ( 0.3532910049 0.6952010393 ) 305 1 - vert 331 ( 0.2484299988 0.4642819762 ) 306 1 - vert 332 ( 0.3334769905 0.5614709854 ) 307 1 - vert 333 ( 0.3538120091 0.7960569859 ) 308 1 - vert 334 ( 0.4279470146 0.6008620262 ) 309 1 - vert 335 ( 0.1184170023 0.7840999961 ) 310 1 - vert 336 ( 0.2511610091 0.8109970093 ) 311 1 - vert 337 ( 0.293592006 0.3762480021 ) 299 1 - vert 338 ( 0.2733629942 0.4424099922 ) 312 1 - vert 339 ( 0.4266610146 0.7429720163 ) 313 1 - vert 340 ( 0.7897199988 0.8616859913 ) 314 3 - vert 341 ( 0.8482810259 0.8981170058 ) 317 1 - vert 342 ( 0.8015120029 0.9534640312 ) 318 3 - vert 343 ( 0.8729519844 0.9907349944 ) 321 2 - vert 344 ( 0.9272400141 0.9562820196 ) 323 2 - vert 345 ( 0.8227530122 0.7990909815 ) 325 1 - vert 346 ( 0.8966109753 0.7954459786 ) 326 1 - vert 347 ( 0.9680870175 0.8457790017 ) 327 2 - vert 348 ( 0.9852830172 0.9051989913 ) 329 2 - vert 349 ( 0.9114339948 0.8721209764 ) 331 1 - vert 350 ( 0.7897199988 0.8616859913 ) 332 3 - vert 351 ( 0.8482810259 0.8981170058 ) 335 1 - vert 352 ( 0.8015120029 0.9534640312 ) 336 3 - vert 353 ( 0.8729519844 0.9907349944 ) 339 2 - vert 354 ( 0.9272400141 0.9562820196 ) 341 2 - vert 355 ( 0.8227530122 0.7990909815 ) 343 3 - vert 356 ( 0.8966109753 0.7954459786 ) 346 1 - vert 357 ( 0.9680870175 0.8457790017 ) 347 2 - vert 358 ( 0.9852830172 0.9051989913 ) 349 4 - vert 359 ( 0.9114339948 0.8721209764 ) 353 1 - vert 360 ( 0.4773229063 0.487958312 ) 354 1 - vert 361 ( 0.4917426109 0.4699620605 ) 355 1 - vert 362 ( 0.3910925388 0.4360863566 ) 356 1 - vert 363 ( 0.4272986948 0.3971681595 ) 357 1 - vert 364 ( 0.3781959713 0.3941164613 ) 358 1 - vert 365 ( 0.3953500688 0.3804553747 ) 359 1 - vert 366 ( 0.469283253 0.4946552515 ) 360 1 - vert 367 ( 0.4338584542 0.4004658461 ) 362 1 - vert 368 ( 0.4489762783 0.5055828094 ) 361 1 - vert 369 ( 0.3890351355 0.429038763 ) 363 1 - vert 370 ( 0.3783749342 0.3945943713 ) 365 1 - vert 371 ( 0.3949126303 0.3801929951 ) 364 1 - - numtris 470 - tri 0 2 1 0 - tri 1 5 4 3 - tri 2 3 4 6 - tri 3 7 3 6 - tri 4 10 9 8 - tri 5 10 8 11 - tri 6 8 12 11 - tri 7 13 2 0 - tri 8 14 2 13 - tri 9 14 15 2 - tri 10 16 9 4 - tri 11 4 9 10 - tri 12 10 11 17 - tri 13 6 10 17 - tri 14 6 4 10 - tri 15 18 14 13 - tri 16 7 14 18 - tri 17 7 18 19 - tri 18 7 6 14 - tri 19 12 21 20 - tri 20 20 21 22 - tri 21 11 20 22 - tri 22 25 24 23 - tri 23 25 23 26 - tri 24 29 28 27 - tri 25 30 29 27 - tri 26 31 29 30 - tri 27 34 33 32 - tri 28 34 36 35 - tri 29 34 32 36 - tri 30 39 38 37 - tri 31 39 40 38 - tri 32 43 42 41 - tri 33 43 41 25 - tri 34 43 25 44 - tri 35 25 41 24 - tri 36 41 45 24 - tri 37 38 26 46 - tri 38 25 26 38 - tri 39 11 12 20 - tri 40 2 39 1 - tri 41 2 40 39 - tri 42 22 21 43 - tri 43 21 42 43 - tri 44 49 48 47 - tri 45 52 51 50 - tri 46 53 52 50 - tri 47 52 48 51 - tri 48 54 48 52 - tri 49 55 49 47 - tri 50 56 55 47 - tri 51 53 50 49 - tri 52 55 53 49 - tri 53 58 46 57 - tri 54 59 58 57 - tri 55 37 58 59 - tri 56 38 58 37 - tri 57 38 46 58 - tri 58 44 38 40 - tri 59 44 25 38 - tri 60 2 15 40 - tri 61 15 44 40 - tri 62 17 11 22 - tri 63 15 43 44 - tri 64 15 22 43 - tri 65 17 22 15 - tri 66 6 17 15 - tri 67 6 15 14 - tri 68 56 47 60 - tri 69 60 48 54 - tri 70 60 47 48 - tri 71 5 16 4 - tri 72 28 62 61 - tri 73 62 63 61 - tri 74 61 63 64 - tri 75 67 66 65 - tri 76 61 64 68 - tri 77 68 65 69 - tri 78 69 65 66 - tri 79 69 66 70 - tri 80 72 71 31 - tri 81 35 69 70 - tri 82 36 28 35 - tri 83 27 28 36 - tri 84 31 71 29 - tri 85 71 62 29 - tri 86 29 62 28 - tri 87 28 61 35 - tri 88 35 61 68 - tri 89 35 68 69 - tri 90 23 74 73 - tri 91 26 23 73 - tri 92 75 34 70 - tri 93 34 35 70 - tri 94 78 77 76 - tri 95 81 80 79 - tri 96 80 82 79 - tri 97 83 82 80 - tri 98 86 85 84 - tri 99 86 87 85 - tri 100 85 87 88 - tri 101 89 77 78 - tri 102 90 89 78 - tri 103 90 78 91 - tri 104 92 79 84 - tri 105 79 86 84 - tri 106 86 93 87 - tri 107 82 93 86 - tri 108 82 86 79 - tri 109 94 89 90 - tri 110 83 94 90 - tri 111 83 95 94 - tri 112 83 90 82 - tri 113 88 97 96 - tri 114 97 98 96 - tri 115 87 98 97 - tri 116 101 100 99 - tri 117 101 102 100 - tri 118 105 104 103 - tri 119 106 104 105 - tri 120 107 106 105 - tri 121 110 109 108 - tri 122 110 112 111 - tri 123 110 111 109 - tri 124 115 114 113 - tri 125 115 113 116 - tri 126 119 118 117 - tri 127 119 101 118 - tri 128 119 120 101 - tri 129 101 99 118 - tri 130 118 99 121 - tri 131 113 122 102 - tri 132 101 113 102 - tri 133 87 97 88 - tri 134 78 76 115 - tri 135 78 115 116 - tri 136 98 119 96 - tri 137 96 119 117 - tri 138 125 124 123 - tri 139 128 127 126 - tri 140 129 127 128 - tri 141 128 126 123 - tri 142 130 128 123 - tri 143 131 124 125 - tri 144 132 124 131 - tri 145 129 125 127 - tri 146 131 125 129 - tri 147 134 133 122 - tri 148 135 133 134 - tri 149 114 135 134 - tri 150 113 114 134 - tri 151 113 134 122 - tri 152 120 116 113 - tri 153 120 113 101 - tri 154 78 116 91 - tri 155 91 116 120 - tri 156 93 98 87 - tri 157 91 120 119 - tri 158 91 119 98 - tri 159 93 91 98 - tri 160 82 91 93 - tri 161 82 90 91 - tri 162 132 136 124 - tri 163 136 130 123 - tri 164 136 123 124 - tri 165 81 79 92 - tri 166 103 137 62 - tri 167 62 137 63 - tri 168 137 138 63 - tri 169 67 139 66 - tri 170 137 140 138 - tri 171 140 141 139 - tri 172 141 66 139 - tri 173 141 70 66 - tri 174 72 107 71 - tri 175 112 70 141 - tri 176 111 112 103 - tri 177 104 111 103 - tri 178 107 105 71 - tri 179 71 105 62 - tri 180 105 103 62 - tri 181 103 112 137 - tri 182 112 140 137 - tri 183 112 141 140 - tri 184 100 143 142 - tri 185 102 143 100 - tri 186 75 70 110 - tri 187 110 70 112 - tri 188 146 145 144 - tri 189 144 145 147 - tri 190 150 149 148 - tri 191 150 151 149 - tri 192 151 152 149 - tri 193 155 154 153 - tri 194 154 156 153 - tri 195 155 153 157 - tri 196 153 156 151 - tri 197 153 151 150 - tri 198 157 153 150 - tri 199 159 144 158 - tri 200 159 146 144 - tri 201 158 144 156 - tri 202 156 144 151 - tri 203 162 161 160 - tri 204 165 164 163 - tri 205 161 166 160 - tri 206 165 166 164 - tri 207 145 162 160 - tri 208 145 160 147 - tri 209 149 165 163 - tri 210 148 149 163 - tri 211 149 166 165 - tri 212 152 166 149 - tri 213 152 160 166 - tri 214 147 160 152 - tri 215 144 147 151 - tri 216 151 147 152 - tri 217 168 154 167 - tri 218 171 170 169 - tri 219 172 171 169 - tri 220 174 169 173 - tri 221 172 169 174 - tri 222 176 175 168 - tri 223 175 177 168 - tri 224 178 171 172 - tri 225 175 174 177 - tri 226 174 173 177 - tri 227 177 179 154 - tri 228 168 177 154 - tri 229 177 180 179 - tri 230 177 173 180 - tri 231 182 181 175 - tri 232 181 174 175 - tri 233 173 169 180 - tri 234 169 170 180 - tri 235 183 159 158 - tri 236 167 154 155 - tri 237 170 183 158 - tri 238 170 158 180 - tri 239 180 158 156 - tri 240 180 156 179 - tri 241 154 179 156 - tri 242 186 185 184 - tri 243 187 186 184 - tri 244 187 184 188 - tri 245 184 185 189 - tri 246 184 189 190 - tri 247 188 192 191 - tri 248 188 184 193 - tri 249 188 193 192 - tri 250 193 190 192 - tri 251 184 190 193 - tri 252 196 195 194 - tri 253 196 197 195 - tri 254 200 199 198 - tri 255 203 202 201 - tri 256 204 203 201 - tri 257 206 205 196 - tri 258 206 196 202 - tri 259 204 201 207 - tri 260 201 202 208 - tri 261 207 201 209 - tri 262 201 208 209 - tri 263 203 206 202 - tri 264 202 196 208 - tri 265 210 204 207 - tri 266 207 209 211 - tri 267 196 205 197 - tri 268 212 206 203 - tri 269 214 211 213 - tri 270 215 212 203 - tri 271 218 217 216 - tri 272 197 219 195 - tri 273 214 207 211 - tri 274 210 207 214 - tri 275 215 204 210 - tri 276 215 203 204 - tri 277 220 199 200 - tri 278 221 199 220 - tri 279 222 214 213 - tri 280 223 214 222 - tri 281 213 211 224 - tri 282 224 211 225 - tri 283 226 221 220 - tri 284 227 223 222 - tri 285 225 211 209 - tri 286 225 209 218 - tri 287 218 216 225 - tri 288 230 229 228 - tri 289 230 228 197 - tri 290 232 231 199 - tri 291 235 234 233 - tri 292 236 234 235 - tri 293 206 230 205 - tri 294 206 233 230 - tri 295 236 237 234 - tri 296 234 238 233 - tri 297 237 239 234 - tri 298 234 239 238 - tri 299 235 233 206 - tri 300 233 238 230 - tri 301 240 237 236 - tri 302 237 241 239 - tri 303 230 197 205 - tri 304 242 235 206 - tri 305 243 213 241 - tri 306 244 235 242 - tri 307 246 216 245 - tri 308 197 228 219 - tri 309 243 241 237 - tri 310 240 243 237 - tri 311 244 240 236 - tri 312 244 236 235 - tri 313 247 232 199 - tri 314 221 247 199 - tri 315 222 213 243 - tri 316 248 222 243 - tri 317 213 224 241 - tri 318 224 225 241 - tri 319 226 247 221 - tri 320 227 222 248 - tri 321 225 239 241 - tri 322 225 246 239 - tri 323 246 225 216 - tri 324 199 249 198 - tri 325 199 231 249 - tri 326 252 251 250 - tri 327 251 253 250 - tri 328 256 255 254 - tri 329 256 254 257 - tri 330 257 254 258 - tri 331 261 260 259 - tri 332 259 260 262 - tri 333 261 263 260 - tri 334 260 257 262 - tri 335 260 256 257 - tri 336 263 256 260 - tri 337 265 264 251 - tri 338 265 251 252 - tri 339 264 262 251 - tri 340 262 257 251 - tri 341 268 267 266 - tri 342 271 270 269 - tri 343 266 267 272 - tri 344 271 269 272 - tri 345 250 267 268 - tri 346 250 253 267 - tri 347 254 270 271 - tri 348 255 270 254 - tri 349 254 271 272 - tri 350 258 254 272 - tri 351 258 272 267 - tri 352 253 258 267 - tri 353 251 257 253 - tri 354 257 258 253 - tri 355 274 273 259 - tri 356 277 276 275 - tri 357 278 276 277 - tri 358 280 279 276 - tri 359 278 280 276 - tri 360 282 274 281 - tri 361 281 274 283 - tri 362 284 278 277 - tri 363 281 283 280 - tri 364 280 283 279 - tri 365 283 259 285 - tri 366 274 259 283 - tri 367 283 285 286 - tri 368 283 286 279 - tri 369 288 281 287 - tri 370 287 281 280 - tri 371 279 286 276 - tri 372 276 286 275 - tri 373 289 264 265 - tri 374 273 261 259 - tri 375 275 264 289 - tri 376 275 286 264 - tri 377 286 262 264 - tri 378 286 285 262 - tri 379 259 262 285 - tri 380 292 291 290 - tri 381 293 292 290 - tri 382 293 290 294 - tri 383 290 291 295 - tri 384 290 295 296 - tri 385 294 298 297 - tri 386 294 290 299 - tri 387 294 299 298 - tri 388 299 296 298 - tri 389 290 296 299 - tri 390 302 301 300 - tri 391 302 300 303 - tri 392 306 305 304 - tri 393 307 305 306 - tri 394 309 302 308 - tri 395 309 304 302 - tri 396 307 310 305 - tri 397 305 311 304 - tri 398 310 312 305 - tri 399 305 312 311 - tri 400 306 304 309 - tri 401 304 311 302 - tri 402 313 310 307 - tri 403 310 314 312 - tri 404 302 303 308 - tri 405 315 306 309 - tri 406 316 306 315 - tri 407 319 318 317 - tri 408 303 300 320 - tri 409 321 314 310 - tri 410 313 321 310 - tri 411 316 313 307 - tri 412 316 307 306 - tri 413 322 312 314 - tri 414 322 319 312 - tri 415 319 322 318 - tri 416 325 324 323 - tri 417 325 303 324 - tri 418 328 327 326 - tri 419 329 328 326 - tri 420 309 308 325 - tri 421 309 325 327 - tri 422 329 326 330 - tri 423 326 327 331 - tri 424 330 326 332 - tri 425 326 331 332 - tri 426 328 309 327 - tri 427 327 325 331 - tri 428 333 329 330 - tri 429 330 332 334 - tri 430 325 308 303 - tri 431 335 309 328 - tri 432 336 335 328 - tri 433 338 337 318 - tri 434 303 320 324 - tri 435 339 330 334 - tri 436 333 330 339 - tri 437 336 329 333 - tri 438 336 328 329 - tri 439 322 334 332 - tri 440 322 332 338 - tri 441 338 318 322 - tri 442 342 341 340 - tri 443 343 341 342 - tri 444 343 344 341 - tri 445 341 345 340 - tri 446 341 346 345 - tri 447 344 348 347 - tri 448 344 349 341 - tri 449 344 347 349 - tri 450 349 347 346 - tri 451 341 349 346 - tri 452 352 351 350 - tri 453 353 351 352 - tri 454 353 354 351 - tri 455 351 355 350 - tri 456 351 356 355 - tri 457 354 358 357 - tri 458 354 359 351 - tri 459 354 357 359 - tri 460 359 357 356 - tri 461 351 359 356 - tri 462 362 361 360 - tri 463 365 364 363 - tri 464 362 363 364 - tri 465 361 363 362 - tri 466 368 367 366 - tri 467 371 370 369 - tri 468 369 367 371 - tri 469 369 368 367 - - numweights 366 - weight 0 5 1 ( -2.6899678707 1.0871751308 1.8058979511 ) - weight 1 5 1 ( -2.2649798393 -0.6712075472 1.8503963947 ) - weight 2 5 1 ( 0.4134475887 1.3870702982 3.6037931442 ) - weight 3 6 1 ( -1.7440931797 1.8530415297 0.4308057725 ) - weight 4 5 1 ( -0.3448497951 17.2868461609 0.6211572886 ) - weight 5 6 1 ( 0.1139039919 1.781314373 -1.893302083 ) - weight 6 5 1 ( 1.3602592945 17.1904315948 1.6350427866 ) - weight 7 6 1 ( -3.5899174213 -0.5911718607 -1.316524148 ) - weight 8 5 1 ( -2.7329525948 3.8486106396 2.7285325527 ) - weight 9 5 1 ( -1.5916725397 6.2675614357 1.7774949074 ) - weight 10 5 1 ( -0.5701870322 5.996679306 0.2521500289 ) - weight 11 5 1 ( -1.3729881048 1.169867754 -1.2268105745 ) - weight 12 5 1 ( 1.0926809311 4.0552887917 4.3002490997 ) - weight 13 5 1 ( 1.566562891 0.8306041956 2.1184928417 ) - weight 14 6 1 ( -2.2401156425 -0.9601020813 -2.416731596 ) - weight 15 5 1 ( 1.385201335 1.2934436798 0.8326619864 ) - weight 16 5 1 ( -2.5451953411 0.0308376737 0.4767605066 ) - weight 17 5 1 ( -0.4516384304 -0.6455978155 0.012372341 ) - weight 18 4 1 ( -0.6219847202 2.2531809807 -0.456617415 ) - weight 19 4 1 ( -1.2913143635 3.7553355694 -1.6515777111 ) - weight 20 4 1 ( -1.874937892 9.0500249863 -0.1764525473 ) - weight 21 4 1 ( -2.2960281372 2.749679327 1.8207947016 ) - weight 22 3 0.6999999881 ( 4.8828401566 -2.7044487 0.6354151964 ) - weight 23 17 0.3000000119 ( 5.0226368904 -3.323397398 -0.6295486689 ) - weight 24 3 0.6999999881 ( 2.6502299309 -4.961151123 0.5032252073 ) - weight 25 17 0.3000000119 ( 2.7861196995 -5.5127024651 -1.1769644022 ) - weight 26 3 0.6999999881 ( 1.7464599609 -7.3955802917 -3.3951346874 ) - weight 27 17 0.3000000119 ( 1.6600509882 -6.9502091408 -5.4904317856 ) - weight 28 4 1 ( -2.4328999519 3.7446737289 -1.8653916121 ) - weight 29 3 0.6999999881 ( 3.630120039 -2.5410995483 -2.8197247982 ) - weight 30 17 0.3000000119 ( 3.5736367702 -2.3510918617 -3.8682219982 ) - weight 31 4 1 ( -2.9375293255 1.8682713509 -0.6170748472 ) - weight 32 4 1 ( -2.5628876686 8.5439157486 -1.5739315748 ) - weight 33 4 1 ( -3.3842778206 8.9216270447 -0.1642317027 ) - weight 34 4 1 ( -3.6740412712 15.0591812134 -2.1367576122 ) - weight 35 4 1 ( -3.8299701214 14.9496240616 -0.75174582 ) - weight 36 5 0.3999999762 ( -0.3550735712 -3.304063797 0.486051321 ) - weight 37 4 0.6000000238 ( -2.2832870483 17.0460510254 -1.5780124664 ) - weight 38 4 1 ( -2.7775797844 15.5354709625 -0.4101122916 ) - weight 39 4 1 ( -3.7897229195 1.924828887 0.6117858887 ) - weight 40 6 1 ( 0.6586187482 3.0574450493 0.2747755349 ) - weight 41 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 42 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 43 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 44 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 45 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 46 4 1 ( -3.9875535965 3.4547400475 -0.6553001404 ) - weight 47 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 48 3 0.6999999881 ( 6.1800704002 -1.4027709961 1.8338754177 ) - weight 49 17 0.3000000119 ( 6.3865265846 -2.3303997517 0.7730341554 ) - weight 50 3 0.6999999881 ( -0 -1.7511024475 0.1084551811 ) - weight 51 17 0.3000000119 ( 0.1175981015 -2.338917017 -0.6383993626 ) - weight 52 3 0.6999999881 ( 0.0000000475 2.67786026 0.1172848791 ) - weight 53 17 0.3000000119 ( 0.1181050241 1.9574490786 0.4372529984 ) - weight 54 3 0.6999999881 ( 4.8107204437 2.7770385742 -0.1645846367 ) - weight 55 17 0.3000000119 ( 4.9047112465 2.1880440712 -0.0799947158 ) - weight 56 3 0.6999999881 ( 0.0000005244 3.2641983032 -1.3634146452 ) - weight 57 17 0.3000000119 ( 0.0331045128 2.8826799393 -0.8561867476 ) - weight 58 3 0.6999999881 ( 6.6058506966 1.2185897827 -0.2284646332 ) - weight 59 17 0.3000000119 ( 6.6932139397 0.7157000899 -0.61739254 ) - weight 60 3 0.6999999881 ( 4.3842306137 2.3628807068 -2.6403346062 ) - weight 61 17 0.3000000119 ( 4.3368020058 2.3757019043 -2.5548729897 ) - weight 62 3 0.6999999881 ( 0.0000005244 2.3006477356 -3.3062844276 ) - weight 63 17 0.3000000119 ( -0.0784278139 2.4148499966 -2.9708662033 ) - weight 64 3 0.6999999881 ( -0 -6.40625 1.7182451487 ) - weight 65 17 0.3000000119 ( 0.2100096494 -7.2441453934 -0.200201571 ) - weight 66 3 0.6999999881 ( -0 -7.5456199646 -3.2928147316 ) - weight 67 17 0.3000000119 ( -0.0776550919 -7.1445965767 -5.3301358223 ) - weight 68 11 1 ( 2.2692363262 -0.7109053731 1.863699317 ) - weight 69 11 1 ( 2.6936204433 1.0476187468 1.8190294504 ) - weight 70 11 1 ( -0.4129011929 1.3472138643 3.6116020679 ) - weight 71 11 1 ( 0.3442397714 17.2457885742 0.6222824454 ) - weight 72 12 1 ( 1.7531366348 1.8530414104 0.3923861086 ) - weight 73 12 1 ( -0.1554701775 1.781314373 -1.8903428316 ) - weight 74 11 1 ( -1.3625189066 17.1492233276 1.633374095 ) - weight 75 12 1 ( 3.5601284504 -0.5911719203 -1.3950728178 ) - weight 76 11 1 ( 1.5933787823 6.2275657654 1.7862062454 ) - weight 77 11 1 ( 2.7340044975 3.8095309734 2.7403533459 ) - weight 78 11 1 ( 0.5745403767 5.9555273056 0.2592974603 ) - weight 79 11 1 ( 1.3816635609 1.1282881498 -1.2159096003 ) - weight 80 11 1 ( -1.0943217278 4.0155177116 4.3055911064 ) - weight 81 11 1 ( -1.563325882 0.7895608544 2.124661684 ) - weight 82 12 1 ( 2.1864824295 -0.9601020813 -2.4653611183 ) - weight 83 11 1 ( -1.3800005913 1.2518279552 0.8389032483 ) - weight 84 11 1 ( 2.5514698029 -0.0094382362 0.4901812375 ) - weight 85 11 1 ( 0.4589500129 -0.6869136691 0.0226445049 ) - weight 86 10 1 ( 1.291046381 3.7553272247 -1.6517294645 ) - weight 87 10 1 ( 0.6220672727 2.2531228065 -0.4566352665 ) - weight 88 10 1 ( 1.8760317564 9.0497722626 -0.1762659699 ) - weight 89 10 1 ( 2.2972152233 2.7491431236 1.820068717 ) - weight 90 3 0.6999999881 ( -4.8828401566 -2.7044487 0.6354151964 ) - weight 91 17 0.3000000119 ( -4.7269392014 -3.4584681988 -0.0854552835 ) - weight 92 3 0.6999999881 ( -2.6502299309 -4.961151123 0.5032252073 ) - weight 93 17 0.3000000119 ( -2.5055992603 -5.5860137939 -0.8816500902 ) - weight 94 3 0.6999999881 ( -1.7464599609 -7.3955802917 -3.3951346874 ) - weight 95 17 0.3000000119 ( -1.8271087408 -6.9985203743 -5.2958240509 ) - weight 96 10 1 ( 2.4325327873 3.7445414066 -1.866065979 ) - weight 97 10 1 ( 2.9374883175 1.8679306507 -0.6181942821 ) - weight 98 3 0.6999999881 ( -3.630120039 -2.5410995483 -2.8197247982 ) - weight 99 17 0.3000000119 ( -3.6746306419 -2.4515094757 -3.4637188911 ) - weight 100 10 1 ( 3.3853602409 8.9211759567 -0.1647492051 ) - weight 101 10 1 ( 2.563277483 8.5437335968 -1.5741169453 ) - weight 102 10 1 ( 3.6750206947 15.0589179993 -2.1367058754 ) - weight 103 10 1 ( 3.8315677643 14.9491825104 -0.7517779469 ) - weight 104 10 0.6000000238 ( 2.2847802639 17.0459060669 -1.5770984888 ) - weight 105 11 0.3999999762 ( 0.3626201749 -3.3451797962 0.4974914193 ) - weight 106 10 1 ( 2.7794098854 15.5351266861 -0.4095968008 ) - weight 107 10 1 ( 3.7902505398 1.9242370129 0.6102834344 ) - weight 108 12 1 ( -0.6524233818 3.0574450493 0.2891783416 ) - weight 109 12 1 ( 5.0106716156 0.9053530693 -3.6504743099 ) - weight 110 12 1 ( 3.3387277126 0.733915329 -4.6873145103 ) - weight 111 12 1 ( 2.4959359169 6.9807777405 1.7068595886 ) - weight 112 12 1 ( -1.2105718851 6.3511171341 -0.8626311421 ) - weight 113 12 1 ( -1.9455769062 8.52318573 1.1350343227 ) - weight 114 10 1 ( 3.9877011776 3.4542672634 -0.6567179561 ) - weight 115 12 1 ( -0.564451158 8.9724168777 2.3275995255 ) - weight 116 3 0.6999999881 ( -6.1800694466 -1.4027709961 1.8338754177 ) - weight 117 17 0.3000000119 ( -5.953230381 -2.5013549328 1.4616774321 ) - weight 118 3 0.6999999881 ( -4.8107194901 2.7770385742 -0.1645846367 ) - weight 119 17 0.3000000119 ( -4.7008624077 2.0549683571 0.4560623169 ) - weight 120 3 0.6999999881 ( -6.6058497429 1.2185897827 -0.2284646332 ) - weight 121 17 0.3000000119 ( -6.4966993332 0.5329667926 0.1186952889 ) - weight 122 3 0.6999999881 ( -4.38422966 2.3628807068 -2.6403346062 ) - weight 123 17 0.3000000119 ( -4.417198658 2.2544238567 -2.0663394928 ) - weight 124 25 1 ( 0.6777581573 7.9519200325 0.6349455714 ) - weight 125 25 1 ( 1.1529927254 3.9185302258 -0.1941897273 ) - weight 126 25 1 ( 0.02931525 7.7794094086 -0.3195793629 ) - weight 127 25 1 ( 1.0269221067 3.90107131 0.8855068088 ) - weight 128 23 1 ( 0.1869719177 6.8134241104 -1.0747961998 ) - weight 129 25 1 ( -0.3621887267 7.2669796944 0.5099079013 ) - weight 130 25 1 ( 0.324067533 3.3856942654 0.923316896 ) - weight 131 25 1 ( -0.8722677827 10.0385942459 -0.6067591906 ) - weight 132 25 1 ( -1.4109836817 12.5594806671 0.1638013422 ) - weight 133 25 1 ( -0.0465809591 11.7850046158 -1.3652210236 ) - weight 134 25 1 ( -0.7750240564 11.9444990158 1.7597953081 ) - weight 135 25 1 ( 0.292026639 10.4777374268 -0.7143133879 ) - weight 136 25 1 ( 0.8056500554 12.0637969971 1.5543088913 ) - weight 137 25 1 ( 2.0551874638 0.7699283957 0.8910750747 ) - weight 138 25 1 ( 0.8544714451 0.0598058775 0.0164857991 ) - weight 139 25 1 ( 2.0478918552 0.7716006041 -0.7880921364 ) - weight 140 25 1 ( -0.2122484148 0.6277328134 -0.6480253339 ) - weight 141 25 1 ( 0.3840408027 0.7547831535 1.2944793701 ) - weight 142 25 1 ( 0.5854663849 12.8653936386 -0.6182157993 ) - weight 143 26 1 ( -1.0345290899 8.0171842575 0.0920845047 ) - weight 144 26 1 ( 0.5642696023 6.4945859909 1.4618453979 ) - weight 145 36 1 ( 0.0373068079 0.6321765184 1.2806857824 ) - weight 146 26 1 ( 0.1559688449 6.9293165207 1.6813747883 ) - weight 147 36 1 ( -0.264529705 0.1475747079 2.1487343311 ) - weight 148 26 1 ( -1.6982132196 9.5094766617 0.8710772991 ) - weight 149 26 1 ( -1.4600764513 9.5645647049 -0.0198428165 ) - weight 150 26 1 ( -1.3875607252 7.9833545685 0.5915039182 ) - weight 151 26 1 ( -1.9164613485 0.3477898836 0.4795096219 ) - weight 152 26 1 ( -0.0644018129 1.8024277687 1.532481432 ) - weight 153 53 1 ( -0.7257300615 0.0632333905 -0.5097473264 ) - weight 154 53 0.6763292551 ( 2.1792988777 -1.2119925022 -2.1074550152 ) - weight 155 56 0.1335486472 ( 3.0106232166 -1.4392008781 -3.2074313164 ) - weight 156 59 0.1901221275 ( -2.7626104355 3.0153596401 -0.7864025235 ) - weight 157 54 0.3812146485 ( -2.2033104897 -2.641702652 -1.4817008972 ) - weight 158 53 0.2426904887 ( -1.3060411215 -3.5814328194 -1.6228842735 ) - weight 159 55 0.3760948479 ( 2.4254767895 0.9188229442 1.5152773857 ) - weight 160 54 0.5 ( -3.3525524139 -0.4142085612 0.6368940473 ) - weight 161 55 0.5 ( -0.0383077115 1.3795313835 -0.6033175588 ) - weight 162 57 0.5 ( -1.5030175447 0.2725478411 -0.6169183254 ) - weight 163 58 0.5 ( -0.2203240246 -0.6378903389 0.7004138827 ) - weight 164 53 0.2432710975 ( 4.5148906708 0.939170897 -1.4748704433 ) - weight 165 56 0.1235347167 ( 5.045463562 0.9572698474 -2.4334733486 ) - weight 166 59 0.6331941485 ( -1.9480568171 0.8664643168 -3.0670621395 ) - weight 167 59 1 ( 0.434607029 -0.0892723948 -2.0300762653 ) - weight 168 61 0.4448421597 ( 1.7663196325 1.2188661098 0.5445787311 ) - weight 169 56 0.0551155768 ( -0.6017512083 -0.9491522312 1.6617600918 ) - weight 170 59 0.0552001186 ( 1.4708142281 1.4237459898 3.2809429169 ) - weight 171 60 0.4448421597 ( 1.5779389143 1.4503269196 1.996180892 ) - weight 172 59 0.5809060335 ( 1.5179005861 0.3639834523 0.6898238063 ) - weight 173 60 0.4190939665 ( 1.6250252724 0.7637779117 -0.7177914381 ) - weight 174 56 1 ( 0.2121644318 1.0180077553 -0.7577211857 ) - weight 175 23 1 ( 1.8148230314 5.931145668 -0.3435919285 ) - weight 176 23 1 ( 1.6346585751 5.5263376236 2.0344257355 ) - weight 177 22 0.583085835 ( 3.5533299446 1.5058097839 3.3042814732 ) - weight 178 19 0.416914165 ( 3.5533299446 9.6242084503 3.1591424942 ) - weight 179 22 1 ( 0 3.3939781189 3.420681715 ) - weight 180 19 1 ( 2.8266301155 3.5193488598 -2.4283123016 ) - weight 181 19 1 ( 0 -0.4760894775 2.5715219975 ) - weight 182 19 1 ( 1.8643100262 -1.8514120579 0.6337348223 ) - weight 183 19 1 ( 6.758890152 2.8914825916 2.1825277805 ) - weight 184 19 1 ( 5.2957100868 5.2341880798 5.1125178337 ) - weight 185 19 1 ( 5.6946501732 0.030095391 7.0999073982 ) - weight 186 19 1 ( 6.3690500259 -0.5535885096 3.51644063 ) - weight 187 22 1 ( 0 1.5523986816 3.9858016968 ) - weight 188 19 1 ( 0 1.1753904819 8.6219129562 ) - weight 189 19 1 ( 5.4150500298 -0.4673207104 0.0298947375 ) - weight 190 19 1 ( 5.6383600235 8.9551715851 -0.4074867368 ) - weight 191 19 1 ( 6.3565201759 4.7367730141 -1.3220449686 ) - weight 192 19 1 ( 5.0064101219 -3.593462944 2.5845403671 ) - weight 193 19 1 ( 1.7497999668 -0.8630791903 8.3791923523 ) - weight 194 19 1 ( -0 -1.7675423622 -0.2312142402 ) - weight 195 19 1 ( 5.1232600212 -3.7621974945 7.0747184753 ) - weight 196 22 1 ( -0 4.1167411804 -2.0508882999 ) - weight 197 23 1 ( -1.0666117668 7.1288871765 -1.0445464849 ) - weight 198 3 0.6999999881 ( 2.413850069 1.6968994141 -0.0032248199 ) - weight 199 17 0.3000000119 ( 2.5210564137 1.0677599907 -0.0503498763 ) - weight 200 3 0.6999999881 ( -0 1.6626396179 2.5169951916 ) - weight 201 17 0.3000000119 ( 0.2558626533 0.3949125707 2.5178260803 ) - weight 202 3 0.6999999881 ( -0 2.5009880066 -2.316524744 ) - weight 203 17 0.3000000119 ( -0.0216102228 2.3712129593 -1.963578701 ) - weight 204 19 1 ( -0 2.5912082195 -2.6006515026 ) - weight 205 19 1 ( -0 6.9119086266 -3.62109375 ) - weight 206 3 0.6999999881 ( -0 -1.6990814209 0.2766751647 ) - weight 207 17 0.3000000119 ( 0.1272549331 -2.3288917542 -0.462870419 ) - weight 208 39 1 ( -1.6346623898 5.5263538361 2.03439188 ) - weight 209 39 1 ( -1.8148268461 5.9311265945 -0.3436316848 ) - weight 210 22 0.583085835 ( -3.5533299446 1.5058097839 3.3042817116 ) - weight 211 19 0.416914165 ( -3.5533299446 9.6242084503 3.1591424942 ) - weight 212 19 1 ( -2.8266301155 3.5193488598 -2.4283123016 ) - weight 213 19 1 ( -1.8643100262 -1.8514120579 0.6337348223 ) - weight 214 19 1 ( -5.2957100868 5.2341880798 5.1125178337 ) - weight 215 19 1 ( -6.758890152 2.8914825916 2.1825277805 ) - weight 216 19 1 ( -5.6946501732 0.030095391 7.0999073982 ) - weight 217 19 1 ( -6.3690500259 -0.5535885096 3.51644063 ) - weight 218 19 1 ( -5.4150500298 -0.4673207104 0.0298947375 ) - weight 219 19 1 ( -5.6383600235 8.9551715851 -0.4074867368 ) - weight 220 19 1 ( -6.3565201759 4.7367730141 -1.3220449686 ) - weight 221 19 1 ( -5.0064101219 -3.593462944 2.5845403671 ) - weight 222 19 1 ( -1.7497999668 -0.8630791903 8.3791923523 ) - weight 223 19 1 ( -5.1232600212 -3.7621974945 7.0747184753 ) - weight 224 39 1 ( 1.0666069984 7.1288619041 -1.0446026325 ) - weight 225 3 0.6999999881 ( -2.413850069 1.6968994141 -0.0032248199 ) - weight 226 17 0.3000000119 ( -2.2986824512 1.0009872913 0.2186246961 ) - weight 227 19 1 ( -0 6.7484283447 -2.8186290264 ) - weight 228 41 1 ( 0.024596978 3.9311044216 -1.1260004044 ) - weight 229 41 1 ( -0.5624598861 7.9746866226 -0.4286085963 ) - weight 230 41 1 ( 0.5120666027 7.7691469193 -0.0230195802 ) - weight 231 41 1 ( -0.9959337115 3.9371061325 -0.7512713671 ) - weight 232 39 1 ( -0.1869764477 6.8133964539 -1.074848175 ) - weight 233 41 1 ( -0.2165630311 7.2701511383 0.5461999178 ) - weight 234 41 1 ( -0.8824561238 3.411396265 -0.0643945634 ) - weight 235 42 1 ( 0.8549844623 0.2528648973 1.57695508 ) - weight 236 41 1 ( 1.0620903969 10.0059461594 0.8097110987 ) - weight 237 41 1 ( 1.6533892155 11.7471590042 -0.1523270905 ) - weight 238 41 1 ( -1.2099196911 11.9685525894 1.2878966331 ) - weight 239 41 1 ( 0.9066777229 10.461315155 -0.3428868353 ) - weight 240 41 1 ( -1.3758742809 12.108669281 -0.2957111299 ) - weight 241 41 1 ( -0.2138080299 0.0740898624 -0.8262922764 ) - weight 242 41 1 ( -1.3251268864 0.8241202831 -1.781971097 ) - weight 243 41 1 ( 0.3087968826 0.7860037088 -2.1672999859 ) - weight 244 41 1 ( 0.6962512136 0.6087246537 0.0613773689 ) - weight 245 41 1 ( -1.3276546001 0.7913125157 -0.0630722716 ) - weight 246 41 1 ( 0.8087035418 12.8550338745 -0.5811187029 ) - weight 247 42 1 ( 0.3878561854 8.0463161469 0.7637005448 ) - weight 248 42 1 ( -1.1190600395 6.5313410759 -0.714397788 ) - weight 249 59 1 ( 0.1200741157 -0.4936034679 -1.4324579239 ) - weight 250 42 1 ( -1.2999851704 6.9946331978 -0.3187713027 ) - weight 251 59 1 ( 0.2045968026 -0.0353807509 -2.2132627964 ) - weight 252 42 1 ( -0.0451344959 9.600692749 1.3655314445 ) - weight 253 42 1 ( 0.7755446434 9.6114082336 0.9833311439 ) - weight 254 42 1 ( -0.0989032313 8.054813385 1.1354370117 ) - weight 255 42 1 ( -0.3652009368 0.4545969665 2.0071790218 ) - weight 256 42 1 ( -1.4103574753 1.8816424608 0.1294049323 ) - weight 257 29 1 ( 0.7787700891 -0.1017866284 -0.0366858616 ) - weight 258 32 0.1325315982 ( -2.665828228 0.8784331679 3.4696369171 ) - weight 259 29 0.6834952831 ( -1.81985116 0.603322506 2.1558337212 ) - weight 260 36 0.1839731187 ( 2.2480390072 -3.365432024 1.1250917912 ) - weight 261 30 0.3905737996 ( 1.9261958599 2.123497963 1.8193899393 ) - weight 262 29 0.2220368236 ( 1.4494894743 3.0001437664 1.940521121 ) - weight 263 31 0.3873893619 ( -2.008739233 -0.5044685602 -1.8529793024 ) - weight 264 30 0.5 ( 3.2961053848 0.697748661 -0.6755973101 ) - weight 265 31 0.5 ( -0.2494784594 -1.4069179296 0.6420080066 ) - weight 266 34 0.4921174049 ( -0.4170491099 0.1914337277 -0.2589419484 ) - weight 267 33 0.5078825951 ( 1.7475426197 0.4663470387 0.1753890216 ) - weight 268 32 0.1231126115 ( -4.784204483 -0.9365236759 2.4948964119 ) - weight 269 29 0.2450744808 ( -4.2458729744 -0.936281085 1.4660912752 ) - weight 270 36 0.6318128705 ( 1.8313311338 -1.0786170959 2.9495201111 ) - weight 271 36 1 ( -0.4501805604 0.1570405662 1.8298476934 ) - weight 272 37 0.5 ( -0.3598984778 -1.0330058336 -2.2583928108 ) - weight 273 38 0.5 ( -0.534078002 -0.8734534979 -0.842764318 ) - weight 274 37 0.4282596707 ( -0.8022220135 -0.2802945077 0.3133172393 ) - weight 275 36 0.5717403293 ( -0.8639788628 -0.0721941888 -1.1553294659 ) - weight 276 32 1 ( -0.2635084689 -0.6292151213 0.189261511 ) - weight 277 23 1 ( 1.6417124271 5.4552531242 1.9403328896 ) - weight 278 23 1 ( 1.8200638294 5.856010437 -0.4139024317 ) - weight 279 19 1 ( 3.5178000927 9.5680742264 3.1525809765 ) - weight 280 22 1 ( 0 3.3197593689 3.4080517292 ) - weight 281 19 1 ( 5.2427601814 5.2219552994 5.0864219666 ) - weight 282 19 1 ( 6.6913099289 2.9026758671 2.1857364178 ) - weight 283 19 1 ( 5.6377000809 0.0698989853 7.053940773 ) - weight 284 19 1 ( 6.3053598404 -0.507943213 3.5062994957 ) - weight 285 22 1 ( 0 1.4965896606 3.9675216675 ) - weight 286 19 1 ( 0 1.2037447691 8.5607242584 ) - weight 287 19 1 ( 5.3608999252 -0.422534436 0.0546339974 ) - weight 288 19 1 ( 5.5819802284 8.9057312012 -0.3783785999 ) - weight 289 19 1 ( 6.2929601669 4.7295179367 -1.2837893963 ) - weight 290 19 1 ( 4.9563498497 -3.5174195766 2.5837233067 ) - weight 291 19 1 ( 2.7983601093 3.5242595673 -2.3789935112 ) - weight 292 19 1 ( 1.7323000431 -0.8143367767 8.3204307556 ) - weight 293 19 1 ( 5.0720300674 -3.6844627857 7.029009819 ) - weight 294 22 1 ( -0 4.0352973938 -2.0088083744 ) - weight 295 23 1 ( -1.0325536728 7.0417790413 -1.1078439951 ) - weight 296 19 1 ( 1.8456599712 -1.7927941084 0.6524350047 ) - weight 297 19 1 ( -0 6.8828892708 -3.5598459244 ) - weight 298 39 1 ( -1.8200676441 5.8559908867 -0.4139411449 ) - weight 299 39 1 ( -1.6417161226 5.4552679062 1.9402999878 ) - weight 300 19 1 ( -3.5178000927 9.5680742264 3.1525809765 ) - weight 301 19 1 ( -6.6913099289 2.9026758671 2.1857364178 ) - weight 302 19 1 ( -5.2427601814 5.2219552994 5.0864219666 ) - weight 303 19 1 ( -5.6377000809 0.0698989853 7.053940773 ) - weight 304 19 1 ( -6.3053598404 -0.507943213 3.5062994957 ) - weight 305 19 1 ( -5.3608999252 -0.422534436 0.0546339974 ) - weight 306 19 1 ( -5.5819802284 8.9057312012 -0.3783785999 ) - weight 307 19 1 ( -6.2929601669 4.7295179367 -1.2837893963 ) - weight 308 19 1 ( -4.9563498497 -3.5174195766 2.5837233067 ) - weight 309 19 1 ( -2.7983601093 3.5242595673 -2.3789935112 ) - weight 310 19 1 ( -1.7323000431 -0.8143367767 8.3204307556 ) - weight 311 19 1 ( -5.0720300674 -3.6844627857 7.029009819 ) - weight 312 39 1 ( 1.0325490236 7.0417518616 -1.1078989506 ) - weight 313 19 1 ( -1.8456599712 -1.7927941084 0.6524350047 ) - weight 314 32 0.1325315982 ( -2.7226519585 0.8793641329 3.5344920158 ) - weight 315 29 0.6834952831 ( -1.8575342894 0.5922801495 2.232606411 ) - weight 316 36 0.1839731187 ( 2.3055043221 -3.380559206 1.1875809431 ) - weight 317 29 1 ( 0.8214605451 -0.1346284747 -0.027725393 ) - weight 318 30 0.392377615 ( 2.0200583935 2.1253066063 1.8834825754 ) - weight 319 29 0.2162517756 ( 1.5129262209 3.0632345676 2.0106399059 ) - weight 320 31 0.3913706541 ( -1.9835004807 -0.5948922634 -1.9170718193 ) - weight 321 30 0.5 ( 3.4323377609 0.6554694176 -0.6886695623 ) - weight 322 31 0.5 ( -0.1698361784 -1.5252560377 0.6550801992 ) - weight 323 34 0.4997155666 ( -0.3311471641 0.1199345365 -0.2221266925 ) - weight 324 33 0.5002844334 ( 1.8407101631 0.4046130478 0.1385737509 ) - weight 325 26 1 ( -2.0891292095 9.6569690704 0.7699396014 ) - weight 326 36 1 ( -0.4761613905 0.2508462667 1.9141391516 ) - weight 327 37 0.4282596707 ( -0.8409990072 -0.1932945997 0.3174948096 ) - weight 328 36 0.5717403293 ( -0.9027558565 0.0145337041 -1.1633735895 ) - weight 329 37 0.5 ( -0.3849956691 -0.9692876339 -2.333748579 ) - weight 330 38 0.5 ( -0.5579230189 -0.7995530963 -0.908631742 ) - weight 331 32 1 ( -0.2460349053 -0.6749010682 0.1526608318 ) - weight 332 53 0.6763292551 ( 2.1326296329 -1.2100896835 -2.0336310863 ) - weight 333 56 0.1335486472 ( 2.945694685 -1.4268049002 -3.1503152847 ) - weight 334 59 0.1901221275 ( -2.6948583126 3.0098881721 -0.7315270305 ) - weight 335 53 1 ( -0.6864708662 0.0339166857 -0.485650897 ) - weight 336 54 0.3812146485 ( -2.103461504 -2.6230142117 -1.4306868315 ) - weight 337 53 0.2426904887 ( -1.2493715286 -3.5014081001 -1.5653854609 ) - weight 338 55 0.3760948479 ( 2.4362680912 0.817814827 1.46426332 ) - weight 339 54 0.5 ( -3.2182223797 -0.4623371959 0.6243477464 ) - weight 340 55 0.5 ( 0.0463905968 1.2646961212 -0.5907712579 ) - weight 341 57 0.5 ( -1.4179691076 0.1944057047 -0.6394454241 ) - weight 342 58 0.5 ( -0.1210389361 -0.6968981028 0.7229409814 ) - weight 343 53 0.2432710975 ( 4.4409985542 0.711753428 -1.4260338545 ) - weight 344 56 0.1235347167 ( 4.9655766487 0.7383880615 -2.3608603477 ) - weight 345 59 0.6331941485 ( -2.0333101749 0.8859165907 -2.8392086029 ) - weight 346 59 1 ( 0.4022890031 0.0108417217 -1.9634371996 ) - weight 347 59 0.5809060335 ( 1.4611737728 0.4404588342 0.6946668625 ) - weight 348 60 0.4190939665 ( 1.5682984591 0.8388220072 -0.7022889853 ) - weight 349 61 0.4448421597 ( 1.7121735811 1.2849235535 0.4891456068 ) - weight 350 56 0.0551155768 ( -0.5591433644 -0.9449994564 1.5693720579 ) - weight 351 59 0.0552001186 ( 1.4154963493 1.4684261084 3.2080607414 ) - weight 352 60 0.4448421597 ( 1.5226210356 1.5047709942 1.9302718639 ) - weight 353 56 1 ( 0.2303572297 0.9631506801 -0.777526319 ) - weight 354 6 1 ( -5.089659214 0.9053531289 -3.5395145416 ) - weight 355 6 1 ( -3.4408967495 0.733915329 -4.6128349304 ) - weight 356 6 1 ( -2.4578356743 6.9807777405 1.7612802982 ) - weight 357 6 1 ( 1.1913286448 6.3511171341 -0.88901788 ) - weight 358 6 1 ( 0.6154494882 8.9724168777 2.3146374226 ) - weight 359 6 1 ( 1.9700427055 8.52318573 1.0920182467 ) - weight 360 12 1 ( 5.0106730461 0.905353725 -3.6504733562 ) - weight 361 12 1 ( 3.3387289047 0.7339162827 -4.6873130798 ) - weight 362 12 1 ( 2.495937109 6.9807786942 1.7068607807 ) - weight 363 12 1 ( -1.2105705738 6.3511180878 -0.8626300693 ) - weight 364 12 1 ( -0.5644499063 8.9724178314 2.3276007175 ) - weight 365 12 1 ( -1.9455757141 8.5231866837 1.1350353956 ) -} diff --git a/base/def/npcs_as_player.def b/base/def/npcs_as_player.def deleted file mode 100644 index d9a445673..000000000 --- a/base/def/npcs_as_player.def +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:03 sparhawk - * Initial revision - * - ***************************************************************************/ - -model model_mp_labcoat { - inherit model_sp_marine - mesh models/md5/characters/npcs_as_player/mp_labcoat.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_labcoat_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_labcoat" - - "def_head" "head_player" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} - - -model model_mp_tshirt { - inherit model_sp_marine - - mesh models/md5/characters/npcs_as_player/mp_tshirt.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_tshirt_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_tshirt " - - "def_head" "head_player" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} - -model model_mp_jumpsuit { - inherit model_sp_marine - - mesh models/md5/characters/npcs_as_player/mp_jumpsuit.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_jumpsuit_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_jumpsuit" - - "def_head" "head_player" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} - -model model_mp_greenarmor { - inherit model_sp_marine - - mesh models/md5/characters/npcs_as_player/mp_greenarmor.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_greenarmor_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_greenarmor" - - "def_head" "head_player" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} - -model model_mp_suit { - inherit model_sp_marine - - mesh models/md5/characters/npcs_as_player/mp_suit.md5mesh - - - //mesh models/md5/characters/npcs_as_player/mp_greenarmor.md5mesh - //mesh models/md5/characters/npcs_as_player/mp_jumpsuit.md5mesh - //mesh models/md5/characters/npcs_as_player/mp_tshirt.md5mesh - //mesh models/md5/characters/npcs_as_player/mp_labcoat.md5mesh - //mesh models/md5/characters/npcs/playermoves/mpplayer.md5mesh - //mesh models/md5/characters/npcs_as_player/mp_security.md5mesh - //mesh models/md5/characters/npcs_as_player/mp_soldier.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_suit_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_suit" - - "def_head" "head_player" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} - -model model_mp_security { - inherit model_sp_marine - - - mesh models/md5/characters/npcs_as_player/mp_security.md5mesh - - channel torso ( *Waist ) - channel legs ( *origin -*Waist SPINNER eyecontrol) - - skin skins/characters/player/marine_mp.skin - - anim run_forward models/md5/characters/npcs/playermoves/run_270.md5anim { - frame 10 rightfoot - frame 19 leftfoot - } - anim walk models/md5/characters/npcs/playermoves/jog.md5anim - anim walk_backwards models/md5/characters/npcs/playermoves/jog_back.md5anim - - anim walk_strafe_left models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim - - anim walk_strafe_right models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim -} - - -entityDef player_security_mp { - "inherit" "player_doommarine_mp" - "model" "model_mp_security" - - "def_head" "head_security_helmet" - "head_joint" "Shoulders" - "copy_joint neckcontrol" "neckcontrol" - "copy_joint headcontrol" "headcontrol" - "copy_joint_world eyecontrol" "eyecontrol" -} \ No newline at end of file diff --git a/base/default.cfg b/base/default.cfg new file mode 100644 index 000000000..b214e7f56 --- /dev/null +++ b/base/default.cfg @@ -0,0 +1 @@ +# greebo: stub default.cfg needed by TypeInfo.exe during compilation \ No newline at end of file diff --git a/base/maps/fred/cyberdemon/monster_wakeups.mb b/base/maps/fred/cyberdemon/monster_wakeups.mb deleted file mode 100644 index 2bdf646fd..000000000 Binary files a/base/maps/fred/cyberdemon/monster_wakeups.mb and /dev/null differ diff --git a/base/maps/fred/underground/impintro.mb b/base/maps/fred/underground/impintro.mb deleted file mode 100644 index b9543c8f2..000000000 Binary files a/base/maps/fred/underground/impintro.mb and /dev/null differ diff --git a/base/maps/fred/underground/impscurry.mb b/base/maps/fred/underground/impscurry.mb deleted file mode 100644 index 09a543533..000000000 Binary files a/base/maps/fred/underground/impscurry.mb and /dev/null differ diff --git a/base/maps/fred/underground/impstairs.mb b/base/maps/fred/underground/impstairs.mb deleted file mode 100644 index 02af04095..000000000 Binary files a/base/maps/fred/underground/impstairs.mb and /dev/null differ diff --git a/base/models/monsters/imp/animation/cycles/alert_walk.ma b/base/models/monsters/imp/animation/cycles/alert_walk.ma deleted file mode 100644 index af3396e2b..000000000 --- a/base/models/monsters/imp/animation/cycles/alert_walk.ma +++ /dev/null @@ -1,5038 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:23 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 3.0 scene -//Name: alert_walk.ma -//Last modified: Mon, Jan 14, 2002 02:02:03 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "3.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 273.17597229932943 48.934370114983906 -1.2380914161180385 ; - setAttr ".r" -type "double3" -5.1301089129425543 -989.40000000007569 2.5444437451708134e-014 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 194.07847403604214; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 74.469721999318679 34.424558581462414 -14.017358632247062 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 119.53135691131881; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 53.87093898441433 63.573141174024713 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.40937350974679; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 236.26034545898437 35.115294513738675 -5.9814899087285243 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 120.64423498480028; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 1 20.18 1 27.38 1 30.960000000000001 - 1 32.76 1 56.18 1 63.380000000000003 1 66.96 1 68.760000000000005 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 1 20.18 1 27.38 1 30.960000000000001 - 1 32.76 1 56.18 1 63.380000000000003 1 66.96 1 68.760000000000005 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 1 20.18 1 27.38 1 30.960000000000001 - 1 32.76 1 56.18 1 63.380000000000003 1 66.96 1 68.760000000000005 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 -38.367703938541368 20.18 -38.367703938541368 - 27.38 -38.367703938541368 30.960000000000001 -38.36770393854141 32.76 -38.36770393854141 - 56.18 -38.36770393854141 63.380000000000003 -38.36770393854141 66.96 -38.367703938541446 - 68.760000000000005 -38.367703938541446; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20.18 0 27.36 -22.261750778216175 - 30.960000000000001 9.6638522443422588 32.76 0 48.920000000000002 0 56.18 - 0 63.36 -22.261750778216175 66.96 9.6638522443422588 68.760000000000005 0 - 84.92 0; - setAttr -s 11 ".kit[2:10]" 9 3 3 3 3 9 3 - 3 1; - setAttr -s 11 ".kot[2:10]" 9 3 3 3 1 9 3 - 3 3; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 0.9361724853515625 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0.35154101252555847 0 0 0; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 0 20.18 0 27.38 0 30.960000000000001 - 0 32.76 0 56.18 0 63.380000000000003 0 66.96 0 68.760000000000005 0; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 -3.515667513182728 20.18 -3.515667513182728 - 27.38 -3.5156675131827297 30.960000000000001 -3.5156675131827422 32.76 -3.5156675131827422 - 56.18 -3.5156675131827422 63.380000000000003 -3.515667513182744 66.96 -3.5156675131827564 - 68.760000000000005 -3.5156675131827564; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 0 20.18 0 27.38 8.6414253885234693 - 30.960000000000001 0 32.76 0 56.18 0 63.380000000000003 8.6414253885234693 - 66.96 0 68.760000000000005 0; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 -4.579364761070849 20.18 -4.579364761070849 - 27.38 29.058010331813129 30.960000000000001 55.894887262743886 32.76 55.894887262743886 - 56.18 55.894887262743886 63.380000000000003 89.532262355627864 66.96 116.36913928655862 - 68.760000000000005 116.36913928655862; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 3 1; - setAttr -s 9 ".kot[2:8]" 9 3 3 1 9 3 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 0.0074271988123655319 1 1; - setAttr -s 9 ".koy[5:8]" 0 0.99997240304946899 0 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 1 20.18 1 27.38 1 30.960000000000001 - 1 32.76 1 56.18 1 63.380000000000003 1 66.96 1 68.760000000000005 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 38.14 1 45.32 1 48.920000000000002 1 50.8 1 74.14 1 81.32 1 84.92 1 87 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 38.14 1 45.32 1 48.920000000000002 1 50.8 1 74.14 1 81.32 1 84.92 1 87 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 38.14 1 45.32 1 48.920000000000002 1 50.8 1 74.14 1 81.32 1 84.92 1 87 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 36.23707061730854 14.800000000000001 36.23707061730854 - 38.14 36.237070617308525 45.32 36.237070617308518 48.920000000000002 36.23707061730854 - 50.8 36.237070617308547 74.14 36.237070617308525 81.32 36.237070617308518 - 84.92 36.23707061730854 87 36.23707061730854; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 14.439669496646856 14.800000000000001 0 38.14 0.37406996600235581 45.32 - -19.289764981099978 48.920000000000002 14.439669496646856 50.8 0 74.14 0 - 81.32 -4.8500954844531243 84.92 28.879338993293711 87 0; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 0.16945751011371613; - setAttr -s 13 ".kiy[11:12]" 0 -0.98553746938705444; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 0 12.2 0 13 0 14.800000000000001 - 0 38.14 0 45.32 0 48.920000000000002 0 50.8 -2.4645435772743767e-016 74.14 - 0 81.32 0 84.92 0 87 0; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 4.3568593517583993 8.2 4.3568593517583993 - 12.2 4.3568593517583993 13 4.3568593517583993 14.800000000000001 4.3568593517583993 - 38.14 4.3568593517583993 45.32 4.3568593517583851 48.920000000000002 4.3568593517583851 - 50.8 4.3568593517583851 74.14 4.3568593517583851 81.32 4.3568593517583709 - 84.92 4.3568593517583709 87 4.3568593517583709; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 14.800000000000001 0 38.14 0 45.32 6.5824344037117717 48.920000000000002 - 0 50.8 0 74.14 0 81.32 6.5824344037117717 84.92 0 87 0; - setAttr -s 13 ".kit[1:12]" 9 3 3 3 3 9 3 - 3 3 9 1 9; - setAttr -s 13 ".kot[1:12]" 9 3 3 3 3 9 3 - 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 26.486563744388956 14.800000000000001 26.486563744388956 - 38.14 26.486563744388956 45.32 56.871344609681749 48.920000000000002 87.942743472173689 - 50.8 87.942743472173689 74.14 87.942743472173689 81.32 118.32752433746649 - 84.92 149.3989231999584 87 149.3989231999584; - setAttr -s 13 ".kit[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 1 9; - setAttr -s 13 ".kot[0:12]" 9 9 9 3 3 3 9 - 3 3 3 9 3 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 38.14 1 45.32 1 48.920000000000002 1 50.8 1 74.14 1 81.32 1 84.92 1 87 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 9 9 9 - 9 9 9 9 1 9; - setAttr -s 13 ".kix[11:12]" 1 1; - setAttr -s 13 ".kiy[11:12]" 0 0; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 39.810015293345415 8.2 42.615692635353568 - 12.2 40.447669234710872 13 40.107672137817332 20.18 38.183846451726367 27.36 - 43.367038081518743 30.960000000000001 40.588689499324786 38.14 36.621745586517861 - 45.32 42.871635672617217 48.920000000000002 40.089447556570718 53 36.703921348424487 - 56.18 38.473976621555792 63.36 42.85782356873348 66.96 40.079474986539523 - 74.14 36.112531073732598 81.32 42.362421159831939 84 40.107672137817332 84.92 - 39.580233043785441; - setAttr -s 18 ".kit[17]" 1; - setAttr -s 18 ".kix[17]" 0.053836248815059662; - setAttr -s 18 ".kiy[17]" -0.99854975938796997; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 14.373557394032371 20.18 17.766738474032827 27.36 - 35.34397057886077 30.960000000000001 41.914896186039009 38.14 52.424347152494377 - 45.32 64.065722338788731 48.920000000000002 71.902844383318509 53 77.335296396755339 - 56.18 81.537204655015927 63.36 93.976111281605242 66.96 100.54703688878348 - 74.14 111.05648785523886 81.32 122.6978630415332 84.92 135.03101987952178; - setAttr -s 17 ".kit[16]" 1; - setAttr -s 17 ".kot[11:16]" 1 9 9 9 9 9; - setAttr -s 17 ".kix[16]" 0.012161445803940296; - setAttr -s 17 ".kiy[16]" 0.99992603063583374; - setAttr -s 17 ".kox[11:16]" 0.028520654886960983 0.023621529340744019 - 0.026288146153092384 0.027001934126019478 0.018731871619820595 0.012161428108811378; - setAttr -s 17 ".koy[11:16]" 0.99959319829940796 0.9997209906578064 - 0.99965441226959229 0.99963539838790894 0.99982452392578125 0.99992603063583374; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 8.2 1 12.2 1 13 1 20.18 1 27.36 - 1 30.960000000000001 1 38.14 1 45.32 1 48.920000000000002 1 53 1 56.18 1 - 63.36 1 66.96 1 74.14 1 81.32 1 84.92 1; - setAttr -s 17 ".kit[16]" 1; - setAttr -s 17 ".kot[10:16]" 5 1 9 9 9 9 9; - setAttr -s 17 ".kix[16]" 1; - setAttr -s 17 ".kiy[16]" 0; - setAttr -s 17 ".kox[11:16]" 1 1 1 1 1 1; - setAttr -s 17 ".koy[11:16]" 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 8.2 1 12.2 1 13 1 20.18 1 27.36 - 1 30.960000000000001 1 38.14 1 45.32 1 48.920000000000002 1 53 1 56.18 1 - 63.36 1 66.96 1 74.14 1 81.32 1 84.92 1; - setAttr -s 17 ".kit[16]" 1; - setAttr -s 17 ".kot[11:16]" 1 9 9 9 9 9; - setAttr -s 17 ".kix[16]" 1; - setAttr -s 17 ".kiy[16]" 0; - setAttr -s 17 ".kox[11:16]" 1 1 1 1 1 1; - setAttr -s 17 ".koy[11:16]" 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 8.2 1 12.2 1 13 1 20.18 1 27.36 - 1 30.960000000000001 1 38.14 1 45.32 1 48.920000000000002 1 53 1 56.18 1 - 63.36 1 66.96 1 74.14 1 81.32 1 84.92 1; - setAttr -s 17 ".kit[16]" 1; - setAttr -s 17 ".kot[11:16]" 1 9 9 9 9 9; - setAttr -s 17 ".kix[16]" 1; - setAttr -s 17 ".kiy[16]" 0; - setAttr -s 17 ".kox[11:16]" 1 1 1 1 1 1; - setAttr -s 17 ".koy[11:16]" 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 8.2 1 12.2 1 13 1 20.18 1 27.36 - 1 30.960000000000001 1 38.14 1 45.32 1 48.920000000000002 1 53 1 56.18 1 - 63.36 1 66.96 1 74.14 1 81.32 1 84.92 1; - setAttr -s 17 ".kit[16]" 1; - setAttr -s 17 ".kot[11:16]" 1 9 9 9 9 9; - setAttr -s 17 ".kix[16]" 1; - setAttr -s 17 ".kiy[16]" 0; - setAttr -s 17 ".kox[11:16]" 1 1 1 1 1 1; - setAttr -s 17 ".koy[11:16]" 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 19.46 1 26.648 - 1 30.24 1 37.42 1 48.920000000000002 1 55.46 1 62.648000000000003 1 66.24 - 1 73.42 1 84.92 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[9:13]" 1 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[9:13]" 1 1 1 1 1; - setAttr -s 14 ".koy[9:13]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 -3.8400390622218046 12.2 - -3.7361029995962118 13 -3.5030932678670625 26.648 2.447352367704295 42.696 - -3.5030932678670634 49.236 -3.5030932678670634 62.648000000000003 2.4317904001098896 - 84 -3.5030932678670625 84.92 -3.874666468198229; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[6:9]" 1 9 9 3; - setAttr -s 10 ".kox[6:9]" 0.052472542971372604 1 0.14558303356170654 - 1; - setAttr -s 10 ".koy[6:9]" 0.9986223578453064 0 -0.98934602737426758 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287 19.46 0.21813466524646566 26.648 - -0.86763382127902322 30.24 -0.42972806484138226 37.42 -0.031333305538134112 - 48.920000000000002 0.54296989172209287 55.46 0.54296989172209287 62.648000000000003 - -0.54279859480339598 66.24 -0.10489283836575503 73.42 0.29350192093749311 - 84 0.54296989172209287 84.92 0.8678051181977201; - setAttr -s 15 ".kit[14]" 1; - setAttr -s 15 ".kot[9:14]" 1 9 9 9 9 9; - setAttr -s 15 ".kix[14]" 0.64064252376556396; - setAttr -s 15 ".kiy[14]" 0.76783925294876099; - setAttr -s 15 ".kox[9:14]" 0.37389755249023438 0.56976407766342163 - 0.47288861870765686 0.75239390134811401 0.64064246416091919 0.11719497293233871; - setAttr -s 15 ".koy[9:14]" -0.92747002840042114 -0.8218083381652832 - 0.88112223148345947 0.65871345996856689 0.76783931255340576 0.99310892820358276; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 0 12.2 0 13 0 19.46 0 26.648 - 0 30.24 0 37.42 0 48.920000000000002 0 55.46 0 62.648000000000003 0 66.24 - 0 73.42 0 84.92 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[9:13]" 1 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[9:13]" 1 1 1 1 1; - setAttr -s 14 ".koy[9:13]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 19.46 1 26.648 - 1 30.24 1 37.42 1 48.920000000000002 1 55.46 1 62.648000000000003 1 66.24 - 1 73.42 1 84.92 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[9:13]" 1 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[9:13]" 1 1 1 1 1; - setAttr -s 14 ".koy[9:13]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 19.46 1 26.648 - 1 30.24 1 37.42 1 48.920000000000002 1 55.46 1 62.648000000000003 1 66.24 - 1 73.42 1 84.92 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[9:13]" 1 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[9:13]" 1 1 1 1 1; - setAttr -s 14 ".koy[9:13]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 19.46 1 26.648 - 1 30.24 1 37.42 1 48.920000000000002 1 55.46 1 62.648000000000003 1 66.24 - 1 73.42 1 84.92 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[9:13]" 1 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[9:13]" 1 1 1 1 1; - setAttr -s 14 ".koy[9:13]" 0 0 0 0 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperShadeEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"HyperShade\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild hyperShadePanel1VisorEd;\n" - + ";\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperShadeEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"HyperShade\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild hyperShadePanel1VisorEd;\n" - + ";\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild visorPanel1VisorEd;\n" - + ";\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild visorPanel1VisorEd;\n" - + ";\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"Texture View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"Texture View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Texture View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureMaxSize 1024\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureMaxSize 1024\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "\tgrid -spacing 8cm -size 400cm -divisions 2 -style 2;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".a" -type "string" ( - "playbackOptions -min 13 -max 84 -animationStartTime 13 -animationEndTime 90;"); -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 20.18 0 27.36 0 30.960000000000001 - 0 38.14 0 45.32 0 48.920000000000002 0 53 0 56.18 0 63.36 0 66.96 0 74.14 - 0 81.32 0 84.92 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[8:13]" 1 9 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[8:13]" 1 1 1 1 1 1; - setAttr -s 14 ".koy[8:13]" 0 0 0 0 0 0; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 20.18 0 27.36 0 30.960000000000001 - 0 38.14 0 45.32 0 48.920000000000002 0 53 0 56.18 0 63.36 0 66.96 0 74.14 - 0 81.32 0 84.92 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[8:13]" 1 9 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[8:13]" 1 1 1 1 1 1; - setAttr -s 14 ".koy[8:13]" 0 0 0 0 0 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 20.18 0 27.36 0 30.960000000000001 - 0 38.14 0 45.32 0 48.920000000000002 0 53 0 56.18 0 63.36 0 66.96 0 74.14 - 0 81.32 0 84.92 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[8:13]" 1 9 9 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[8:13]" 1 1 1 1 1 1; - setAttr -s 14 ".koy[8:13]" 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 1 20.18 1 29.16 - 1 50.8 1 56.18 1 65.16 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 6.7758528420198658 - 20.18 6.7758528420198658 29.16 6.7758528420198658 50.8 6.7758528420198658 - 56.18 6.7758528420198658 65.16 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 -6.9388939039072284e-018 - 20.18 -6.9388939039072284e-018 29.16 -6.9388939039072284e-018 50.8 0 56.18 - 0 65.16 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 -9.5120444723942321e-016 - 20.18 -9.5120444723942321e-016 29.16 -9.5120444723942321e-016 50.8 0 56.18 - 0 65.16 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 -12.784757077400341 - 20.18 -37.624757077399877 29.16 -12.784757077400341 50.8 -12.784757077400341 - 56.18 -37.624757077399877 65.16 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 3.2695897469829736 - 20.18 3.2695897469829753 29.16 3.2695897469829736 50.8 3.2695897469829736 - 56.18 3.2695897469829753 65.16 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 -6.9162979482121409 - 20.18 -6.9162979482121507 29.16 -6.9162979482121409 50.8 -6.9162979482121409 - 56.18 -6.9162979482121507 65.16 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 1 20.18 1 29.16 - 1 50.8 1 56.18 1 65.16 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 1 20.18 1 29.16 - 1 50.8 1 56.18 1 65.16 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 14.800000000000001 1 20.18 1 29.16 - 1 50.8 1 56.18 1 65.16 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 1 38.14 1 44.420000000000002 - 1 68.760000000000005 1 74.14 1 80.42 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 6.7758528420198658 38.14 - 6.7758528420198658 44.420000000000002 6.7758528420198658 68.760000000000005 - 6.7758528420198658 74.14 6.7758528420198658 80.42 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 -6.9388939039072284e-018 - 38.14 -6.9388939039072284e-018 44.420000000000002 -6.9388939039072284e-018 - 68.760000000000005 0 74.14 0 80.42 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 -9.5120444723942321e-016 - 38.14 -9.5120444723942321e-016 44.420000000000002 -9.5120444723942321e-016 - 68.760000000000005 0 74.14 0 80.42 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 -2.1064832569487142 38.14 - -26.31570375597023 44.420000000000002 0 68.760000000000005 0 74.14 -24.209220499021516 - 80.42 2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 0.36693656610454173 38.14 - 0.36693656610454845 44.420000000000002 0.36693656610454845 68.760000000000005 - 0.36693656610454845 74.14 0.36693656610455516 80.42 0.36693656610455516; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 12.728045273286209 38.14 - 12.728045273286213 44.420000000000002 12.728045273286213 68.760000000000005 - 12.728045273286213 74.14 12.728045273286217 80.42 12.728045273286217; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 1 38.14 1 44.420000000000002 - 1 68.760000000000005 1 74.14 1 80.42 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 1 38.14 1 44.420000000000002 - 1 68.760000000000005 1 74.14 1 80.42 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 32.76 1 38.14 1 44.420000000000002 - 1 68.760000000000005 1 74.14 1 80.42 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 265.23418249311436; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -81.468105380373373; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -290.27584299004701; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 114.19854190937365; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 69.980822956494734; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 167.20200742159128; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 23 1 28 1 35 1 42 1 48 1 59 - 1 64 1 71 1 78 1 84 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 9 9 9 - 9 9 9 1; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -0.0180767416209342 23 -0.0180767416209342 - 28 -0.0180767416209342 35 -0.0180767416209342 42 -0.0180767416209342 48 -0.0180767416209342 - 59 -0.0180767416209342 64 -0.0180767416209342 71 -0.0180767416209342 78 -0.0180767416209342 - 84 -0.0180767416209342; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 4.350740136846035 23 4.350740136846035 - 28 4.350740136846035 35 4.350740136846035 42 4.350740136846035 48 4.350740136846035 - 59 4.350740136846035 64 4.350740136846035 71 4.350740136846035 78 4.350740136846035 - 84 4.350740136846035; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 2.679538405939565 23 2.679538405939565 - 28 2.679538405939565 35 2.679538405939565 42 2.679538405939565 48 2.679538405939565 - 59 2.679538405939565 64 2.679538405939565 71 2.679538405939565 78 2.679538405939565 - 84 2.679538405939565; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 23 0 28 0 35 0 42 0 48 0 59 - 0 64 0 71 0 78 0 84 0; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 23 0 28 0 35 0 42 0 48 0 59 - 0 64 0 71 0 78 0 84 0; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 15.460139794067871 23 13.411789172213926 - 40.072000000000003 -6.2435230119135241 48 15.460139794067871 56.052 27.979778945448555 - 78 -2.2524697631211974 84 17.508490415921816; - setAttr -s 7 ".kit[6]" 1; - setAttr -s 7 ".kot[4:6]" 1 9 9; - setAttr -s 7 ".kix[6]" 0.39454412460327148; - setAttr -s 7 ".kiy[6]" 0.9188770055770874; - setAttr -s 7 ".kox[4:6]" 0.97055000066757202 0.98790758848190308 - 0.58689373731613159; - setAttr -s 7 ".koy[4:6]" -0.24089980125427246 -0.15504378080368042 - 0.80966395139694214; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 23 1 28 1 35 1 42 1 48 1 59 - 1 64 1 71 1 78 1 84 1; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 23 1 28 1 35 1 42 1 48 1 59 - 1 64 1 71 1 78 1 84 1; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 23 1 28 1 35 1 42 1 48 1 59 - 1 64 1 71 1 78 1 84 1; - setAttr -s 11 ".kit[10]" 1; - setAttr -s 11 ".kot[6:10]" 1 9 9 9 9; - setAttr -s 11 ".kix[10]" 1; - setAttr -s 11 ".kiy[10]" 0; - setAttr -s 11 ".kox[6:10]" 1 1 1 1 1; - setAttr -s 11 ".koy[6:10]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 19 1 30 1 34 1 44 1 48 1 54 - 1 61 1 65 1 73 1 84 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 19 0 30 0 34 0 44 0 48 0 54 - 0 61 0 65 0 73 0 84 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 2.6456615572060826 19 2.6456615572060826 - 30 2.6456615572060826 34 2.6456615572060826 44 2.6456615572060826 48 2.6456615572060826 - 54 2.6456615572060826 61 2.6456615572060826 65 2.6456615572060826 73 2.6456615572060826 - 84 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1.9935618776130362 19 1.9935618776130362 - 30 1.9935618776130362 34 1.9935618776130362 44 1.9935618776130362 48 1.9935618776130362 - 54 1.9935618776130362 61 1.9935618776130362 65 1.9935618776130362 73 1.9935618776130362 - 84 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -17.95159746835068 19 -23.484731306813593 - 30 -23.484731306813593 34 -32.219905066211403 44 -25.525505148091106 48 -30.12694598566533 - 54 -30.12694598566533 61 -28.787430988354068 65 -21.573277656701777 73 -21.573277656701777 - 84 -17.95159746835068; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 7.3584054193558028 19 50.73339349985249 - 30 50.73339349985249 34 4.8302394460846791 44 1.668777896530254 48 -33.812791552872021 - 54 -33.812791552872021 61 -23.643593769513455 65 41.515228333439509 73 41.515228333439509 - 84 7.3584054193558028; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -11.599233410804867 19 -1.7902230628270306 - 30 -1.7902230628270306 34 -14.932631302878169 44 -18.699987918861986 48 -5.7490810680395539 - 54 -5.7490810680395539 61 -4.3072199275505918 65 0.46438813050997746 73 0.46438813050997746 - 84 -11.599233410804867; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 19 1 30 1 34 1 44 1 48 1 54 - 1 61 1 65 1 73 1 84 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 19 1 30 1 34 1 44 1 48 1 54 - 1 61 1 65 1 73 1 84 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 19 1 30 1 34 1 44 1 48 1 54 - 1 61 1 65 1 73 1 84 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 6.3533140211779946; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 2.2916645882841449; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 84 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.3867499999998705; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 2.1192000000001707; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 12.54585578602153; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -32.060235945248785; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -45.414526683630967; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 3.3867545965885748; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 2.1192573708760349; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -15.371355069466052; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 21.291401824830025; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -33.106939592632678; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 52.069256159810102; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0.21742569259672084; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0.034116996666525123; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 22.079465110337001; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 34.079593860034244; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 -14.999999999999998 24 0 31 - -20 41.212000000000003 0 49.880000000000003 -20 60.604 0 68.94 -20 77.728 - 0 84 -14.999999999999998; -select -ne :time1; - setAttr ".o" 51; -select -ne :renderPartition; - setAttr -s 10 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 10 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_LHAND_ROT; -select -ne IMP_RHAND_ROT; -select -ne IMP_Rwing_meshShape3Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig5; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape5Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Body2; - setAttr ".r" -type "double3" -19.391120486928465 0 0 ; -select -ne IMP_Waist; -select -ne IMP_Chest; -select -ne IMP_Neck; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of alert_walk.ma diff --git a/base/models/monsters/imp/animation/cycles/crouched_range1.ma b/base/models/monsters/imp/animation/cycles/crouched_range1.ma deleted file mode 100644 index 93b11d4a2..000000000 --- a/base/models/monsters/imp/animation/cycles/crouched_range1.ma +++ /dev/null @@ -1,3325 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: crouched_range1.ma -//Last modified: Mon, Mar 17, 2003 11:28:00 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 215.91678831270457 27.86232346612212 18.28583780782219 ; - setAttr ".r" -type "double3" 3.8698910859558748 -632.99999999990246 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 209.5391232990635; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 2.135389162041502 36.441689858375305 -6.299518173101017 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.844702467344078; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" -3.6684068597071455 19.984003231577383 106.55011898601731 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 273.7481826529646; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 123.60961890421174 24.660295089083245 -2.8420819372169097 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 129.413875487924; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 40 -ast 13 -aet 40 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 20 1 24 1 27 1 32.352 - 1 35.5 1 40.216 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -1.2001205060656153 13 -4.2389271891461249 - 16 -4.7423884819592566 20 -6.0987900494037266 24 -2.6088069975126364 27 2.6235077448511923 - 32.352 2.1636262761833138 35.5 0.31361201025851249 40.216 -1.2001205060656119; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 24.308717053682987 13 20.155539502307036 - 16 25.004799550519444 20 28.810589687488743 24 29.046859062308819 27 28.984856197955406 - 32.352 25.276001885080746 35.5 24.824829406692874 40.216 18.986520163220263; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.1404449135882881 13 11.767930230611864 - 16 4.5925598453809924 20 -5.6151300061933709 24 5.8494752348327985 27 10.736243015300197 - 32.352 20.851192900824852 35.5 22.606579497070189 40.216 26.070798335642717; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 13 58.458782316994593 16 -14.788861782012807 - 20 -24.201426222996165 24 18.562611538922731 27 30.771611418691929 32.352 - 34.678859151438672 35.5 51.207848702634251 40.216 81.644151831707816; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 13 -15.385814908734108 16 -27.332442762085201 - 20 -32.809734126515927 24 -1.9841515246148438 27 16.715888289907102 32.352 - 43.299861939772583 35.5 15.57177798162297 40.216 -7.3481092974231892; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 7.4260738755503946 13 -19.72573676005727 - 16 8.0697213230076255 20 18.667874007462952 24 18.307699644446426 27 13.244320239293765 - 32.352 10.574652291287512 35.5 17.760706054817945 40.216 1.0762063516224274; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 20 1 24 1 27 1 32.352 - 1 35.5 1 40.216 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 20 1 24 1 27 1 32.352 - 1 35.5 1 40.216 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 20 1 24 1 27 1 32.352 - 1 35.5 1 40.216 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 13 1 21.248000000000001 1 27.252 - 1 47 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -2.5294371750177831 13 -2.5294371750177831 - 21.248000000000001 -2.5294371750177831 27.252 -2.5294371750177831 47 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 13.481673551673362 13 13.481673551673362 - 21.248000000000001 13.481673551673362 27.252 13.481673551673362 47 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.26635088939205875 13 -0.26635088939205875 - 21.248000000000001 -0.26635088939205875 27.252 -0.26635088939205875 47 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 381.16196782277632 13 479.932108271083 - 21.248000000000001 372.3957711595607 27.252 385.98228388481618 47 381.16196782277632; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 75.751325538588631 13 84.463988850699025 - 21.248000000000001 64.866122663288962 27.252 49.298310807185892 47 75.751325538588631; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 463.09277358333418 13 555.54322007309202 - 21.248000000000001 495.95342612174886 27.252 508.83224127088977 47 463.09277358333418; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 15.445123296459185 13 15.445123296459185 - 21.248000000000001 15.445123296459185 27.252 15.445123296459185 47 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 15.445123296459185 13 15.445123296459185 - 21.248000000000001 15.445123296459185 27.252 15.445123296459185 47 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 15.445123296459185 13 15.445123296459185 - 21.248000000000001 15.445123296459185 27.252 15.445123296459185 47 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 13 0 21.248000000000001 0 27.252 - 0 47 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 9 1 19.748000000000001 1 21.996 - 1 22.748000000000001 1 23.5 1 24.996 1 34.716 1 40.216 1 47 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -7.5406347832540632e-013 9 -7.5406347832540632e-013 - 19.748000000000001 0 21.996 0 22.748000000000001 0 23.5 0 24.996 0 34.716 - 0 40.216 0 47 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 13.71946295727715 9 13.71946295727715 - 19.748000000000001 13.71946295727715 21.996 13.71946295727715 22.748000000000001 - 13.71946295727715 23.5 13.71946295727715 24.996 13.71946295727715 34.716 - 13.71946295727715 40.216 13.71946295727715 47 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.0908609005564358e-013 9 -3.0908609005564358e-013 - 19.748000000000001 0 21.996 0 22.748000000000001 0 23.5 0 24.996 0 34.716 - 0 40.216 0 47 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -68.093999364879608 9 -46.317877549410063 - 19.748000000000001 -46.317877549410063 21.996 -64.084514494695426 22.748000000000001 - -105.14000111374591 23.5 -127.95658311233549 24.996 -78.193850510728424 34.716 - -50.020221334767591 40.216 -9.3508281633480621 47 -68.093999364879608; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -46.964928234761999 9 -27.886019785280197 - 19.748000000000001 -27.886019785280197 21.996 -22.344703260420218 22.748000000000001 - -21.258018933078645 23.5 -23.343968520999372 24.996 -26.436651396566955 34.716 - -3.0711624244072948 40.216 -59.046376365301818 47 -46.964928234761999; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -8.4936064149666777 9 -2.4986082250665138 - 19.748000000000001 -2.4986082250665138 21.996 -26.782647994304011 22.748000000000001 - -31.850380379981701 23.5 -25.669139185074823 24.996 -12.095435449498716 34.716 - 4.2060158939137837 40.216 -110.87741027199286 47 -8.4936064149666777; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.445123296459183 9 15.445123296459183 - 19.748000000000001 15.445123296459183 21.996 15.445123296459183 22.748000000000001 - 15.445123296459183 23.5 15.445123296459183 24.996 15.445123296459183 34.716 - 15.445123296459183 40.216 15.445123296459183 47 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.445123296459185 9 15.445123296459185 - 19.748000000000001 15.445123296459185 21.996 15.445123296459185 22.748000000000001 - 15.445123296459185 23.5 15.445123296459185 24.996 15.445123296459185 34.716 - 15.445123296459185 40.216 15.445123296459185 47 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.445123296459181 9 15.445123296459181 - 19.748000000000001 15.445123296459181 21.996 15.445123296459181 22.748000000000001 - 15.445123296459181 23.5 15.445123296459181 24.996 15.445123296459181 34.716 - 15.445123296459181 40.216 15.445123296459181 47 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 9 0 19.748000000000001 0 21.996 - 0 22.748000000000001 0 23.5 0 24.996 0 34.716 0 40.216 0 47 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 30 1 - 37.068 1 40.216 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.496 0 23.784 0 30 0 - 37.068 0 40.216 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.6456615572060826 15 2.6456615572060826 - 20.496 2.6456615572060826 23.784 2.6456615572060826 30 2.6456615572060826 - 37.068 2.6456615572060826 40.216 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.9935618776130362 15 1.9935618776130362 - 20.496 1.9935618776130362 23.784 1.9935618776130362 30 1.9935618776130362 - 37.068 1.9935618776130362 40.216 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -9.9434571155923468 15 16.44150276754625 - 20.496 12.675976700382648 23.784 -45.649449387870973 30 3.1517638763609526 - 37.068 -13.514453587483541 40.216 -9.9434571155923468; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 14.833474866504869 15 34.344553603540056 - 20.496 37.179745371426705 23.784 -13.493500612622606 30 -33.235459571592422 - 37.068 -13.769461302845983 40.216 14.833474866504869; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 3.1435925562010367 15 8.8630668501778267 - 20.496 -7.1062367200072947 23.784 15.985486372504006 30 -5.5786099656959571 - 37.068 -5.331638232444285 40.216 3.1435925562010367; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 30 1 - 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 30 1 - 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 30 1 - 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 20.496 1 21.852 1 - 23.784 1 25.716000000000001 1 32.352 1 37.068 1 40.216 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -5.0348979650608028 13 -5.0348979650608028 - 17 -5.0348979650608028 20.496 -5.0348979650608028 21.852 -5.0348979650608028 - 23.784 -5.0348979650608028 25.716000000000001 -5.0348979650608028 32.352 - -5.0348979650608028 37.068 -5.0348979650608028 40.216 -5.0348979650608028; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.1192000000002627 13 2.1192000000002627 - 17 2.1192000000002627 20.496 2.1192000000002627 21.852 2.1192000000002627 - 23.784 2.1192000000002627 25.716000000000001 2.1192000000002627 32.352 2.1192000000002627 - 37.068 2.1192000000002627 40.216 2.1192000000002627; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.0821100000000254 13 -3.0821100000000254 - 17 -3.0821100000000254 20.496 -3.0821100000000254 21.852 -3.0821100000000254 - 23.784 -3.0821100000000254 25.716000000000001 -3.0821100000000254 32.352 - -3.0821100000000254 37.068 -3.0821100000000254 40.216 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 19.728379252162242 13 12.366107941537216 - 17 25.168504911061437 20.496 -17.426332397284337 21.852 -89.844380222410493 - 23.784 -63.596150190640813 25.716000000000001 8.3339937642174959 32.352 54.742627521851915 - 37.068 26.094182569657068 40.216 15.94768596194448; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -24.222716507540518 13 -19.295970392787069 - 17 35.327391901448387 20.496 48.301282097984959 21.852 78.458331309810106 - 23.784 15.027189127823997 25.716000000000001 -20.903729923844121 32.352 -66.929413317275902 - 37.068 -59.244279747823505 40.216 14.481594283529713; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -21.297446334349367 13 -69.156025153639121 - 17 32.217843652272087 20.496 39.209010507096984 21.852 -67.885084423062381 - 23.784 -43.165919275880505 25.716000000000001 -68.879333066047366 32.352 - -125.51381654940607 37.068 -52.836138665247198 40.216 -46.741367468337145; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 20.496 1 21.852 1 - 23.784 1 25.716000000000001 1 32.352 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 20.496 1 21.852 1 - 23.784 1 25.716000000000001 1 32.352 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 20.496 1 21.852 1 - 23.784 1 25.716000000000001 1 32.352 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 37.068 1 40.216 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 15 -12.41287000000041 - 20.496 -12.41287000000041 23.784 -12.41287000000041 32.352 -12.41287000000041 - 37.068 -12.41287000000041 40.216 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 15 -6.7285999999993047 - 20.496 -6.7285999999993047 23.784 -6.7285999999993047 32.352 -6.7285999999993047 - 37.068 -6.7285999999993047 40.216 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 15 -3.8687599999999316 - 20.496 -3.8687599999999316 23.784 -3.8687599999999316 32.352 -3.8687599999999316 - 37.068 -3.8687599999999316 40.216 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 90.793506250366335 15 21.134577280630594 - 20.496 21.134577280630594 23.784 -14.299138396576012 32.352 65.690144057376898 - 37.068 54.435598113118274 40.216 65.634894667613835; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.496 0 23.784 0 32.352 - 0 37.068 0 40.216 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.496 0 23.784 0 32.352 - 0 37.068 0 40.216 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 37.068 1 40.216 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.496 0 23.784 0 32.352 - 0 40.216 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.6268319407172029 15 5.6268319407172029 - 20.496 5.6268319407172029 23.784 5.6268319407172029 32.352 5.6268319407172029 - 40.216 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.1098668596606802 15 -2.1098668596606802 - 20.496 -2.1098668596606802 23.784 -2.1098668596606802 32.352 -2.1098668596606802 - 40.216 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 380.4969630522524 15 379.433050571156 - 20.496 358.37355790700991 23.784 370.57775972606669 32.352 343.50895925312733 - 40.216 380.4969630522524; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.44667534838539324 15 -6.9674788006233612 - 20.496 -17.806527739623135 23.784 5.7746523367004814 32.352 5.7746523367004858 - 40.216 -0.44667534838539324; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -14.64190619217311 15 -8.3548948179625633 - 20.496 4.3389536467292613 23.784 -15.526956291994356 32.352 -15.526956291994363 - 40.216 -14.64190619217311; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 17 1 20.496 1 23.784 1 - 32.352 1 36.284 1 40.216 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.8522027930141798 13 4.8522027930141798 - 17 4.8522027930141798 20.496 4.8522027930141798 23.784 4.8522027930141798 - 32.352 4.8522027930141798 36.284 4.8522027930141798 40.216 4.8522027930141798; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.1192573708759381 13 2.1192573708759381 - 17 2.1192573708759381 20.496 2.1192573708759381 23.784 2.1192573708759381 - 32.352 2.1192573708759381 36.284 2.1192573708759381 40.216 2.1192573708759381; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0821078932592165 13 -3.0821078932592165 - 17 -3.0821078932592165 20.496 -3.0821078932592165 23.784 -3.0821078932592165 - 32.352 -3.0821078932592165 36.284 -3.0821078932592165 40.216 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.6924731551639023 13 31.72580265255699 - 17 57.255362707236877 20.496 85.112493157833782 23.784 10.087247679141608 - 32.352 -23.735501853314606 36.284 -14.066731647876816 40.216 3.6924731551639023; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 26.532243660045506 13 -22.100881306080115 - 17 69.573695619577791 20.496 34.288655309405577 23.784 8.5975472149865571 - 32.352 -11.768620226723483 36.284 -21.145042740255761 40.216 26.532243660045506; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -10.744921003054214 13 23.318529815383215 - 17 24.777770451168621 20.496 25.582570603086292 23.784 -13.827942179427399 - 32.352 -49.851286224846412 36.284 -27.368829862872076 40.216 -10.744921003054214; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 17 1 20.496 1 23.784 1 - 32.352 1 36.284 1 40.216 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 17 1 20.496 1 23.784 1 - 32.352 1 36.284 1 40.216 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 17 1 20.496 1 23.784 1 - 32.352 1 36.284 1 40.216 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 12.412879749935719 15 12.412879749935719 - 20.496 12.412879749935719 23.784 12.412879749935719 32.352 12.412879749935719 - 40.216 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7286993982861674 15 -6.7286993982861674 - 20.496 -6.7286993982861674 23.784 -6.7286993982861674 32.352 -6.7286993982861674 - 40.216 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.868763862603668 15 -3.868763862603668 - 20.496 -3.868763862603668 23.784 -3.868763862603668 32.352 -3.868763862603668 - 40.216 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 100.14946556910684 15 23.343760525941349 - 20.496 48.903760525939461 23.784 40.544717614210725 32.352 -0.85528238578618754 - 40.216 100.14946556910684; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.496 0 23.784 0 32.352 - 0 40.216 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.496 0 23.784 0 32.352 - 0 40.216 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.496 1 23.784 1 32.352 - 1 40.216 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 13 1 21.248000000000001 1 27.252 - 0 47 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 13 0 21.248000000000001 0 27.252 - 0.70000000000000007 47 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 13 0 21.248000000000001 0 27.252 - 0 47 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.40000000000000002 9 0.40000000000000002 - 19.748000000000001 0.40000000000000002 21.996 0.43214285889871429 22.748000000000001 - 0.40000000000000002 23.5 0.25462962976789572 24.996 0 34.716 0 40.216 0.23771293763343451 - 47 0.40000000000000002; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 9 0 19.748000000000001 0 21.996 - 0 22.748000000000001 0 23.5 -0.015873015546539724 24.996 0 34.716 1 40.216 - 0.44778363292642265 47 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 9 0 19.748000000000001 0 21.996 - -0.072321425466413652 22.748000000000001 0 23.5 0.34136904692279668 24.996 - 0.90000000000000002 34.716 0 40.216 -0.03785938224844386 47 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.728440897496945 47 -32.728440897496945; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 63.973526898130061 47 63.973526898130061; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -50.42468749206914 47 -50.42468749206914; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 20.84759696357262 47 20.84759696357262; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 118.90795532169373 47 118.90795532169373; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 72.231170463587219 47 72.231170463587219; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 47 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 1 17 1 24 1 30 1 40.216 1 47 - 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 -19.334754862982241 17 -19.334754862982241 - 24 -19.334754862982241 30 -15.103876397920999 40.216 -15.103876397920999 - 47 -15.103876397920994; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 -0.42835364100675832 17 -0.42835364100675832 - 24 -0.42835364100675832 30 -0.42835364100675832 40.216 -0.42835364100675832 - 47 -0.42835364100675832; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 -25.551409609373867 17 -25.551409609373867 - 24 -25.551409609373867 30 19.251437806126233 40.216 19.251437806126233 47 - -7.3620493586843594; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 1 17 1 24 1 30 1 40.216 1 47 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 1 17 1 24 1 30 1 40.216 1 47 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 1 17 1 24 1 30 1 40.216 1 47 - 1; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 8.3529092540640555 17 8.3529092540640555 - 24 8.3529092540640555 30 7.9194328960359774 40.216 7.9194328960359774 47 - 7.9194328960359774; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 -18.828612908107161 17 -18.828612908107161 - 24 -18.828612908107161 30 -18.933196426616185 40.216 -18.933196426616185 - 47 -18.933196426616185; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 -7.4174554225137843 17 -7.4174554225137843 - 24 -7.4174554225137843 30 -7.5028766617919045 40.216 -7.5028766617919045 - 47 -7.5028766617919045; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 7.1689522478599503 47 7.1689522478599503; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.63757578585061037 47 -0.63757578585061037; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.7485750141607372 47 -7.7485750141607372; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 6.6367499380041135 47 6.6367499380041135; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 18.269136761036329 47 18.269136761036329; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 7.5100622010532465 47 7.5100622010532465; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 47 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 40.216 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 40.216 0; -select -ne :time1; - setAttr ".o" 15; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Lshldr; - setAttr ".t" -type "double3" 1.085679155728795 4.1537911794025533 4.6185070801020824 ; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".t" -type "double3" -1.08568 4.1537988160630093 4.6185075120832098 ; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; - setAttr ".t" -type "double3" -29.775800000000025 57.582500000000032 -1.0893083480314791 ; - setAttr ".r" -type "double3" 9.4749040322149245 -58.854902956455234 -8.3632933901642268 ; - setAttr ".s" -type "double3" 1 0.99999999999999978 1 ; -select -ne IMP_Lhand_GOAL; - setAttr ".t" -type "double3" 29.775846152470962 57.582470209590937 -1.0893063224582775 ; - setAttr ".r" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; - setAttr ".s" -type "double3" 1 0.99999999999999989 0.99999999999999978 ; -select -ne IMP_RHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of crouched_range1.ma diff --git a/base/models/monsters/imp/animation/cycles/evade_left.ma b/base/models/monsters/imp/animation/cycles/evade_left.ma deleted file mode 100644 index 4572be5f0..000000000 --- a/base/models/monsters/imp/animation/cycles/evade_left.ma +++ /dev/null @@ -1,6668 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:21 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: evade_left.ma -//Last modified: Sat, Mar 15, 2003 03:49:21 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 96.243061857072064 47.348563423592665 353.25149948863555 ; - setAttr ".r" -type "double3" -4.5301089138720707 -1096.9999999997533 -1.0393374410808209e-016 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 346.38000252453105; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 194.28877947793808 1.0941968209790858 23.717483046321654 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.844702467344078; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 153.05375786838462 54.400442838962256 132.55619597414841 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 395.72592690570622; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 114.81837383334553 25.972268477568978 -7.8712905798098438 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 73.72154669888242; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1.57\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1.57\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 45 -ast 1 -aet 45 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 16 1 21 1 24 1 29 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 10 -7.3924057183505063 - 13 44.661848586983389 16 89.041193172527116 21 142.59161926657595 24 142.59161926657595 - 29 189.38452625564292; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 34.598237896940624 - 16 37.234461237845331 21 0 24 0 29 0; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 10 -7.3620493586843594 - 13 -7.3620493586843594 16 -7.3620493586843594 21 -7.3620493586843594 24 -7.3620493586843594 - 29 -7.3620493586843594; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.3462904043098467 10 5.3462904043098467 - 13 -72.768496676064444 16 -80.35970826630934 21 5.3462904043098467 24 5.3462904043098467 - 29 5.3462904043098467; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -29.54838557779286 10 -29.54838557779286 - 13 22.958300153786801 16 68.838508843797726 21 -29.54838557779286 24 -29.54838557779286 - 29 -29.54838557779286; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -5.3030645628451412 10 -5.3030645628451412 - 13 53.852959554793856 16 68.496480867268431 21 -5.3030645628451412 24 -5.3030645628451412 - 29 -5.3030645628451412; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 16 1 21 1 24 1 29 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 16 1 21 1 24 1 29 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 16 1 21 1 24 1 29 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 13 1 16 1 19 1 23 1 27 - 1 31 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.1689522478599503 9 7.1689522478599503 - 13 43.069347494217084 16 98.202152718406552 19 145.72742530422528 23 145.72742530422528 - 27 189.45464031869824 31 207.64238631638784; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 13 24.390954936443215 16 - 19.802196910757786 19 0 23 0 27 9.4092780588150333 31 0; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.7485750141607372 9 -7.7485750141607372 - 13 -7.7485750141607372 16 -7.7485750141607372 19 -7.7485750141607372 23 -7.7485750141607372 - 27 -7.7485750141607372 31 -7.7485750141607372; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 10.109326515514191 9 10.109326515514191 - 13 -93.367059919828051 16 -93.367059919828051 19 10.109326515514191 23 10.109326515514191 - 27 -8.5272292692284424 31 10.109326515514191; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 63.314403926397745 9 63.314403926397745 - 13 63.314403926397794 16 63.314403926397794 19 63.314403926397745 23 63.314403926397745 - 27 43.78428004279283 31 63.314403926397745; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 11.590164763476968 9 11.590164763476968 - 13 11.590164763477112 16 11.590164763477112 19 11.590164763476968 23 11.590164763476968 - 27 15.921263764911073 31 11.590164763476968; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 13 1 16 1 19 1 23 1 27 - 1 31 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 13 1 16 1 19 1 23 1 27 - 1 31 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 13 1 16 1 19 1 23 1 27 - 1 31 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 3 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 3 3 9 9; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 6 1 9 1 13 1 16 1 19 1 - 23 1 26 1 29 1 33 1 40 1 45 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1.980821395062172 4 0.35680768721390826 - 6 0.35680768721390826 9 5.2288488107587057 13 76.026073665017392 16 127.92607524836441 - 19 156.72628094953961 23 173.2500381605301 26 180.68536617275998 29 196.29999349137438 - 33 202.35443786147448 40 197.60543903706468 45 195.82324131509654; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 41.235789592866901 4 28.487281986258019 - 6 28.487281986258019 9 26.4572648514477 13 37.430998556893037 16 22.382674114235176 - 19 17.899623226788087 23 17.829699492490715 26 21.299223734959607 29 19.751653475081305 - 33 23.653435991710396 40 28.963423664632668 45 28.963423664632661; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -2.4191866633612995 4 -2.4191866633612995 - 6 -2.4191866633612995 9 -2.4191866633612995 13 -2.4191866633612995 16 -2.4191866633612995 - 19 -2.4191866633612995 23 -2.4191866633612995 26 -2.4191866633612995 29 -2.4191866633612995 - 33 -2.4191866633612995 40 -2.4191866633612995 45 -2.4191866633612995; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 4 0 6 0 9 0 13 67.806819592999048 - 16 83.843825080512147 19 85.944988543812059 23 69.653021907394603 26 69.653021907394603 - 29 69.558978480369575 33 34.763576216953595 40 0.72884664293396573 45 -0.23911503155070893; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 4 0 6 0 9 0 13 79.787982073431593 - 16 51.356142507473848 19 18.732700454133358 23 5.54779786746795 26 5.54779786746795 - 29 -7.7221477539118188 33 -18.778562317305241 40 6.5623024696936509 45 4.2139802068251075; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 7.4260738755503946 4 7.4260738755503946 - 6 11.844180171017102 9 7.4260738755503946 13 15.327544119167559 16 32.387105725753109 - 19 35.898324941078286 23 19.372344496238604 26 19.372344496238604 29 24.292652475305839 - 33 14.827941263172626 40 12.584418533959726 45 4.1544232095724958; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 6 1 9 1 13 1 16 1 19 1 - 23 1 26 1 29 1 33 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 6 1 9 1 13 1 16 1 19 1 - 23 1 26 1 29 1 33 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 6 1 9 1 13 1 16 1 19 1 - 23 1 26 1 29 1 33 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.83371697884823759; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1086667563431649; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.4408920985006262e-016; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.660431799163181; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4125540166489063; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 380.4969630522524; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.44667534838539324; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.64190619217311; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -15.409205020920503; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 27.72702953106549; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 4 1 7 1 10 1 13 1 15 1 18 1 - 20 1 25 1 30 1 37 1 45 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 4 0 7 0 10 0 13 1.1859316927665806 - 15 2.4131955366740243 18 4.0291364392835423 20 4.2668706739778308 25 -0.2678147835455133 - 30 0 37 0 45 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 2.6456615572060826 4 2.6456615572060826 - 7 2.6456615572060826 10 2.6456615572060826 13 5.4202718352236703 15 6.928969584323621 - 18 7.3566724401850045 20 7.8627074434449327 25 8.5695981482480175 30 2.6456615572060826 - 37 2.6456615572060826 45 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1.9935618776130362 4 1.9935618776130362 - 7 1.9935618776130362 10 1.9935618776130362 13 1.4276339454770048 15 1.288544401304579 - 18 1.1642487251838649 20 4.7340644850760718 25 4.8101943206532267 30 1.9935618776130362 - 37 1.9935618776130362 45 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -9.2446596468972171 4 -40.606911302231161 - 7 -10.844360786932633 10 -66.506889618516993 13 -66.506889618516993 15 -82.852613545010968 - 18 -82.852613545010968 20 -82.852613545010968 25 -82.852613545010968 30 -9.2446596468972171 - 37 -43.496136888137173 45 -17.367866815871153; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 5.4602836565267197 4 2.7843384913023184 - 7 31.615599159324002 10 7.863469677494642 13 7.863469677494642 15 -33.555235657396103 - 18 -33.555235657396103 20 -33.555235657396103 25 -33.555235657396103 30 5.4602836565267197 - 37 15.923028080671992 45 6.1403198129355623; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -15.091352590275809 4 -24.104550835567942 - 7 -36.249603559884086 10 -49.899036148213398 13 -49.899036148213398 15 3.4707581396095861 - 18 3.4707581396095861 20 3.4707581396095861 25 3.4707581396095861 30 -15.091352590275809 - 37 -43.330489347556714 45 -18.1682718064956; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 4 1 7 1 10 1 13 1 15 1 18 1 - 20 1 25 1 30 1 37 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 4 1 7 1 10 1 13 1 15 1 18 1 - 20 1 25 1 30 1 37 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 4 1 7 1 10 1 13 1 15 1 18 1 - 20 1 25 1 30 1 37 1 45 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3533140211779946; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.2846953468686371; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.2916645882841449; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 7 1 11 1 16 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 4.8522027930141798 3 4.8522027930141798 - 7 4.8522027930141798 11 4.8522027930141798 16 4.8522027930141798; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.1192573708759381 3 2.1192573708759381 - 7 2.1192573708759381 11 2.1192573708759381 16 2.1192573708759381; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.0821078932592165 3 -3.0821078932592165 - 7 -3.0821078932592165 11 -3.0821078932592165 16 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -17.481282422130235 3 -27.390076877368823 - 7 37.24653626158932 11 -31.482596463959496 16 -29.163904653600898; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 30.702824881409519 3 17.806004426746732 - 7 27.812137987587136 11 33.096108784313422 16 2.7526078842974271; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -30.797032566082748 3 -21.361498695366969 - 7 5.6545970514074098 11 21.770551535360042 16 90.440354206014277; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 7 1 11 1 16 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 7 1 11 1 16 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 7 1 11 1 16 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 9 1 12 1 14 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.412879749935719 3 12.412879749935719 - 9 12.412879749935719 12 12.412879749935719 14 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -6.7286993982861674 3 -6.7286993982861674 - 9 -6.7286993982861674 12 -6.7286993982861674 14 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.868763862603668 3 -3.868763862603668 - 9 -3.868763862603668 12 -3.868763862603668 14 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 19.580561221118923 3 68.42776489322064 - 9 17.175136610542655 12 55.814391261738727 14 15.806253711107317; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 3 0 9 0 12 0 14 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 3 0 9 0 12 0 14 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 9 1 12 1 14 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 9 1 12 1 14 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 3 1 9 1 12 1 14 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 4 1 8 1 11 1 27 1 28 1 33 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -5.0348979650608028 4 -5.0348979650608028 - 8 -5.0348979650608028 11 -5.0348979650608028 27 -5.0348979650608028 28 -5.0348979650608028 - 33 -5.0348979650608028; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.1192000000002627 4 2.1192000000002627 - 8 2.1192000000002627 11 2.1192000000002627 27 2.1192000000002627 28 2.1192000000002627 - 33 2.1192000000002627; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821100000000254 4 -3.0821100000000254 - 8 -3.0821100000000254 11 -3.0821100000000254 27 -3.0821100000000254 28 -3.0821100000000254 - 33 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 49.111805173615501 4 26.865783815836878 - 8 52.775377247588047 11 41.289989492490918 27 8.0248009334483061 28 7.0894858407022818 - 33 49.111805173615501; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -36.514345314725674 4 -23.135870169038757 - 8 -35.629704958336106 11 -48.539618785010752 27 -6.0559569172937886 28 -19.242910567460086 - 33 -36.514345314725674; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -10.891726707689953 4 20.908237141696016 - 8 -20.544565556503006 11 21.099297360629748 27 18.436636678135734 28 19.327983944975848 - 33 -10.891726707689953; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 4 1 8 1 11 1 27 1 28 1 33 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 4 1 8 1 11 1 27 1 28 1 33 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 4 1 8 1 11 1 27 1 28 1 33 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8 1 10 1 27 1 28 1 36 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.41287000000041 8 -12.41287000000041 - 10 -12.41287000000041 27 -12.41287000000041 28 -12.41287000000041 36 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7285999999993047 8 -6.7285999999993047 - 10 -6.7285999999993047 27 -6.7285999999993047 28 -6.7285999999993047 36 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8687599999999316 8 -3.8687599999999316 - 10 -3.8687599999999316 27 -3.8687599999999316 28 -3.8687599999999316 36 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 8.5757406876636644 8 90.482712851025227 - 10 2.8996132775250416 27 73.578403957263049 28 25.193122787417277 36 8.5757406876636644; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8 -7.9513867036587919e-016 - 10 -4.9696166897867449e-017 27 -1.1377197465107351e-014 28 -3.975693351829396e-016 - 36 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8 -6.0762097104242079 10 -7.7617551342514091 - 27 -21.037912454922978 28 -13.766850995367436 36 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8 1 10 1 27 1 28 1 36 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8 1 10 1 27 1 28 1 36 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8 1 10 1 27 1 28 1 36 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6829523665849453; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1851256367233773; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.609353754287454; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.838773336231448; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.61608909736457995; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1993957867164236; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -21.447112172188898; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.369311790170695; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.716593707894834; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 45.543464667899237; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35449716056366781; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.6720434721822404; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 15 1 16 1 17 1 18 1 19 1 20 - 1 23 1 27 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 0 17 0 18 0 19 0 20 - 0 23 0 27 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 0 17 0 18 0 19 0 20 - 0 23 0 27 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 0 17 0 18 0 19 0 20 - 0 23 0 27 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 15 1 16 1 17 1 18 1 19 1 20 - 1 23 1 27 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 15 1 16 1 17 1 18 1 19 1 20 - 1 23 1 27 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 15 1 16 1 17 1 18 1 19 1 20 - 1 23 1 27 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -0.62641265712556182 15 0.88521876431148194 - 16 0.88521876431148128 17 0.88521876431148128 18 0.88521876431148128 19 0.88521876431148128 - 20 0.88521876431148128 23 0.88521876431148128 27 0.88521876431148128; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -0.065597307411484215 15 1.7931664209366429 - 16 1.8476115968306783 17 1.8553246628811348 18 1.85305611378406 19 1.8503716645561981 - 20 1.8476115968306783 23 1.8472736293482159 27 1.8476115968306783; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -1.8982371232945405 15 0.030690815580227682 - 16 0.030690815580227505 17 0.030690815580227505 18 0.030690815580227505 19 - 0.030690815580227505 20 0.030690815580227505 23 0.030690815580227505 27 0.030690815580227505; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 0 17 0 18 0 19 0 20 - 0 23 0 27 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 0 17 0 18 0 19 0 20 - 0 23 0 27 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 15 0 16 150.11494232427569 - 17 129.62453892526975 18 158.7379579384714 19 11.728328809258208 20 -9.1673247220931664 - 23 -29.412498049467576 27 -32.085636527326102; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 15 1 16 1 19 1 22 1 25 1 27 - 1 29 1 33 1 37 1 45 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 0 19 0 22 -36.720000000000091 - 25 0 27 0 29 0 33 0 37 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 0 19 0 22 0 25 0 27 - 0 29 0 33 0 37 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 0 19 0 22 0 25 0 27 - 0 29 0 33 0 37 0 45 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 15 1 16 1 19 1 22 1 25 1 27 - 1 29 1 33 1 37 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 15 1 16 1 19 1 22 1 25 1 27 - 1 29 1 33 1 37 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 15 1 16 1 19 1 22 1 25 1 27 - 1 29 1 33 1 37 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.77384169665487335 15 -0.77256394048258148 - 16 -0.56892562490961829 19 -0.56892562490961829 22 -0.56892563033467058 25 - -0.56892562490961829 27 -0.56892562490961829 29 -0.56892562490961829 33 -0.56892562490961829 - 37 -0.56892562490961829 45 -0.56892562490961829; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -0.055607839605639378 15 1.7174237709091136 - 16 1.90222629624391 19 1.90222629624391 22 1.9022262935963981 25 1.90222629624391 - 27 1.90222629624391 29 1.90222629624391 33 1.90222629624391 37 1.90222629624391 - 45 1.90222629624391; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -1.8433873159737919 15 -0.67349873718077324 - 16 -0.67349873718077335 19 -0.67349873718077335 22 -0.67349874007568011 25 - -0.67349873718077335 27 -0.67349873718077335 29 -0.67349873718077335 33 -0.67349873718077335 - 37 -0.67349873718077335 45 -0.67349873718077335; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 0 19 0 22 0 25 0 27 - 0 29 0 33 0 37 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 0 19 0 22 0 25 0 27 - 0 29 0 33 0 37 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 15 0 16 -30.939720937064457 - 19 -73.338597776745374 22 -40.10704565915762 25 71.046766596222085 27 99.694656352763232 - 29 114.29446930238211 33 -16.042818263663065 37 -38.961130068895997 45 -13.750987083139773; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; - setAttr -s 21 ".kot[0:20]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 -118.97547160373531 9 -118.97547160373531 - 10 49.36751442293145 11 31.246451589074802 12 27.499287785400611 14 172.80952365414802 - 20 152.01145457075089 23 132.59234713351307 24 153.13585694641509 25 157.07331048036531 - 26 142.34244083288752 27 125.72198480637725 31 174.75205502874962 32 172.94213015055158 - 33 170.16979218249284 34 177.8709039823012 35 6.495249267510272 36 18.498573706510516 - 37 32.058537131537008 38 42.014192532975237 45 42.976787459114973; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 30.32938199865233 9 30.32938199865233 - 10 128.43220692569164 11 148.36301684471073 12 160.12501170767601 14 -3.7751792039897984 - 20 -26.093807416200683 23 -20.263781656987064 24 -9.9837206212622167 25 -1.2279459567065136 - 26 18.326475619188681 27 13.528103990635621 31 42.552823230610045 32 41.14665019696205 - 33 36.473302490707532 34 42.008961170860886 35 133.93228603705396 36 129.59918451099145 - 37 126.69478832944695 38 126.33136654231023 45 129.68991614285133; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 -92.904446145666853 9 -92.904446145666853 - 10 47.860052041014882 11 20.58134914925914 12 10.777124148826646 14 175.83050447375061 - 20 188.56948191265693 23 177.95911861847375 24 168.10562139883081 25 162.50180151716663 - 26 -169.11011395898447 27 -134.85551310402207 31 -127.70203442587594 32 -132.75131858802945 - 33 -135.11754626580043 34 -131.70406253008724 35 54.05449913566936 36 63.147396427857323 - 37 74.310383928402572 38 83.278967284915524 45 91.631499459581079; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; - setAttr -s 21 ".kot[0:20]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 0 9 0 10 0 11 0 12 0 14 0 20 - 0 23 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 45 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 0 9 0 10 0 11 0 12 0 14 0 20 - 0 23 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 45 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 9 1 10 1 11 1 12 1 14 1 20 - 1 23 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 45 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 0 9 0 10 0 11 0 12 0 14 0 20 - 0 23 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 45 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 0 9 0 10 0 11 0 12 0 14 0 20 - 0 23 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 45 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 0 9 0 10 0 11 0 12 0 14 0 20 - 0 23 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 45 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; - setAttr -s 20 ".kot[0:19]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 -71.101691513482606 7 -71.101691513482606 - 8 -71.827592311342002 9 -79.443703249199913 10 -58.90603626327438 13 -109.50747689164899 - 17 -170.34787630707439 19 -137.02422391912842 20 -131.95986042386926 21 -136.3479766761773 - 22 -126.73812630997121 23 -125.61129381361019 24 -141.3003762691514 25 -136.3200476635941 - 26 72.798452555060209 27 -62.832003574750665 28 -5.9990110165840074 34 -59.21762677141168 - 39 -41.369209871423429 45 -41.204074093088032; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 32.578198345223548 7 32.578198345223548 - 8 62.487885305837814 9 59.112457931831145 10 34.943509636414866 13 44.114712381842708 - 17 -4.9809698025834912 19 33.579340597544707 20 40.739657272199267 21 36.830722023048367 - 22 37.189245835857633 23 32.049999532028295 24 20.147015437083262 25 26.127184020227396 - 26 131.29179111595292 27 59.692030141415188 28 36.990416367205533 34 54.86214499298147 - 39 52.7394968734664 45 52.892980898329021; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 -95.56444850608456 7 -95.56444850608456 - 8 -99.477616598378319 9 -119.38720068907355 10 -125.2827358435091 13 174.57332512589068 - 17 104.05915418194965 19 143.01469336004226 20 159.54527590880679 21 164.78556366805955 - 22 172.29117132421618 23 175.59330398050494 24 173.60274048601272 25 176.00552908298368 - 26 16.181596890999533 27 -115.97589405630949 28 -56.97521822066598 34 -107.65371266623818 - 39 -78.508952712223049 45 -70.72890385017304; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; - setAttr -s 20 ".kot[0:19]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 7 0 8 0 9 0 10 0 13 0 17 0 - 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 34 0 39 0 45 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 7 0 8 0 9 0 10 0 13 0 17 0 - 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 34 0 39 0 45 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 7 1 8 1 9 1 10 1 13 1 17 1 - 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 34 1 39 1 45 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 7 0 8 0 9 0 10 0 13 0 17 0 - 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 34 0 39 0 45 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 7 0 8 0 9 0 10 0 13 0 17 0 - 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 34 0 39 0 45 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 7 0 8 0 9 0 10 0 13 0 17 0 - 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 34 0 39 0 45 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 1 16 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 -2.5294371750177831 16 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 13.481673551673362 16 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 -0.26635088939205875 16 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 141.20709981379272 16 141.20709981379272; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 64.064019952206479 16 64.064019952206479; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 252.95011708695623 16 252.95011708695623; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 1 16 1 27 1 28 1 35 1 45 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 -7.5406347832540632e-013 16 - -7.5406347832540632e-013 27 -7.5406347832540632e-013 28 -7.5406347832540632e-013 - 35 -7.5406347832540632e-013 45 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 13.71946295727715 16 13.71946295727715 - 27 13.71946295727715 28 13.71946295727715 35 13.71946295727715 45 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 -3.0908609005564358e-013 16 - -3.0908609005564358e-013 27 -3.0908609005564358e-013 28 -3.0908609005564358e-013 - 35 -3.0908609005564358e-013 45 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 68.596496127541187 16 68.596496127541187 - 27 68.596496127541187 28 -51.230408051626149 35 -97.098906726543134 45 -22.685689711154296; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 -60.802874383230787 16 -60.802874383230787 - 27 -60.802874383230787 28 -34.851792253347078 35 -70.436677320898951 45 -65.995171569339448; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 -157.43468421330525 16 -157.43468421330525 - 27 -157.43468421330525 28 -22.464240352923998 35 12.708185868042497 45 -50.282674432336023; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 15.445123296459183 16 15.445123296459183 - 27 15.445123296459183 28 15.445123296459183 35 15.445123296459183 45 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 15.445123296459185 16 15.445123296459185 - 27 15.445123296459185 28 15.445123296459185 35 15.445123296459185 45 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 15.445123296459181 16 15.445123296459181 - 27 15.445123296459181 28 15.445123296459181 35 15.445123296459181 45 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 1 27 1 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 0 27 0 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 0 27 0 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 0 27 0 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 0 27 0 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 15 0 16 0 27 0 28 0 35 0 45 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 26 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 196.54714775303006 22 196.54714775303006 - 26 196.54714775303006 28 218.34584861669333; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 4.9066744168273893 22 4.9066744168273893 - 26 4.9066744168273893 28 9.447711366843965; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 19.59814651487952 22 19.59814651487952 - 26 19.59814651487952 28 19.59814651487952; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 42.472616804532848 22 42.472616804532848 - 26 42.472616804532848 28 83.852039527407641; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -22.427603687930525 22 -22.427603687930525 - 26 -22.427603687930525 28 -41.694751676144996; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 19.642103577178901 22 19.642103577178901 - 26 19.642103577178901 28 -25.712336361356837; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 26 1 28 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0.99999999999999978 22 0.99999999999999978 - 26 0.99999999999999978 28 0.99999999999999978; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 26 1 28 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 1 19 1 26 1 29 1 32 1 39 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 210.93838145165938 19 234.21472658770114 - 26 234.21472658770114 29 240.79677759578391 32 268.39243710582895 39 269.6905841887189 - 45 267.53584043732548; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 36.783579662303822 19 4.8970113899078349 - 26 4.8970113899078349 29 11.707426458117652 32 16.734654688029256 39 31.243423357859207 - 45 35.096697373687562; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 10.203948167497494 19 19.122827147844461 - 26 19.122827147844461 29 19.13925581288693 32 22.173700907990355 39 9.2911691386924282 - 45 4.3468212578158969; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 33.892693033620276 19 23.543272438365097 - 26 23.543272438365097 29 72.581125790558175 32 72.581125790558175 39 76.974140618984393 - 45 81.078993636583192; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 54.671688625550239 19 59.874098618067919 - 26 59.874098618067919 29 16.773330119468056 32 16.773330119468056 39 42.082342809778652 - 45 65.731199807821241; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 39.468648652835569 19 -9.5268991771414822 - 26 -9.5268991771414822 29 -26.706149112208294 32 -26.706149112208294 39 -11.179175897427658 - 45 3.3292985382165443; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 1 19 1 26 1 29 1 32 1 39 1 45 - 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 0.99999999999999989 19 0.99999999999999989 - 26 0.99999999999999989 29 0.99999999999999989 32 0.99999999999999989 39 0.99999999999999989 - 45 0.99999999999999989; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 16 0.99999999999999978 19 0.99999999999999978 - 26 0.99999999999999978 29 0.99999999999999978 32 0.99999999999999978 39 0.99999999999999978 - 45 0.99999999999999978; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -select -ne :time1; - setAttr ".o" 40; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339262 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds"; -select -ne IMP_effector4; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds"; -select -ne IMP_effector3; -select -ne IMP_Hips; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; -select -ne IMP_Rhand_IK; -select -ne IMP_Lhand_IK; -select -ne IMP_LIK; -select -ne IMP_RIK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".IK"; - setAttr -k on ".FIST"; - setAttr -k on ".NEUTRAL"; - setAttr -k on ".SPREAD"; -select -ne IMP_RHAND_ROT; - setAttr -k on ".IK"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of evade_left.ma diff --git a/base/models/monsters/imp/animation/cycles/evade_left_on4.ma b/base/models/monsters/imp/animation/cycles/evade_left_on4.ma deleted file mode 100644 index dd4787992..000000000 --- a/base/models/monsters/imp/animation/cycles/evade_left_on4.ma +++ /dev/null @@ -1,3993 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:22 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: evade_left_on4.ma -//Last modified: Mon, Mar 11, 2002 12:04:46 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models/monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 290.61912513732136 133.33639061234817 -83.243161724210324 ; - setAttr ".r" -type "double3" -28.530108916131731 -3146.5999999998376 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 261.006139783967; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 62.337787547236459 22.326658319428709 -16.948466692435431 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 76.66589438746432 21.396720735023585 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 60.115549445093862; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 244.57946441084826 26.28323495217823 -29.202469550505398 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 356.53685523265978; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 24 -ast 1 -aet 24 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8 1 14 1 16 1 19 1 24 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -101.9398414115052 8 -122.91679239462809 - 14 -85.756568903317614 16 -107.31556999364231 19 -110.22646182871867 24 -110.22646182871867; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 58.394371741366072 8 65.041880265742478 - 14 68.203379643034111 16 36.510122131504247 19 45.477172176443773 24 45.477172176443773; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -11.517195461058266 8 -39.906542486589139 - 14 -19.979773537409152 16 1.4537233025118634 19 -18.607842770268135 24 -18.607842770268135; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.52893863520222695 8 0.52893863520222695 - 14 0.52893863520222695 16 0.52893863520222695 19 0.52893863520222695 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.52893863520222695 8 0.52893863520222695 - 14 0.52893863520222695 16 0.52893863520222695 19 0.52893863520222695 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.52893863520222695 8 0.52893863520222695 - 14 0.52893863520222695 16 0.52893863520222695 19 0.52893863520222695 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 10 1 14 1 17 1 21 1 24 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 104.02743330242008 5 113.23797033591281 - 10 209.11193502995798 14 98.200323709881829 17 146.35835519959036 21 117.07933282151511 - 24 117.07933282151511; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 67.988981015108081 5 70.935145826032269 - 10 64.96994813957285 14 80.114069834969214 17 66.880150770454705 21 69.27287893008922 - 24 69.27287893008922; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 37.800067484309146 5 49.124165965019955 - 10 140.09645669565285 14 4.6648432222299911 17 85.330618768227396 21 48.97945149635548 - 24 48.97945149635548; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.5814880999021691 5 0.5814880999021691 - 10 0.5814880999021691 14 0.5814880999021691 17 0.5814880999021691 21 0.5814880999021691 - 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.5814880999021691 5 0.5814880999021691 - 10 0.5814880999021691 14 0.5814880999021691 17 0.5814880999021691 21 0.5814880999021691 - 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.5814880999021691 5 0.5814880999021691 - 10 0.5814880999021691 14 0.5814880999021691 17 0.5814880999021691 21 0.5814880999021691 - 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.148 1 7.3 1 11.5 1 12.548 - 1 14.648 1 16.748000000000001 1 19.9 1 24 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 13.576151682531137 4.148 14.55934850508574 - 7.3 20.808087224532915 11.5 46.79219705567516 12.548 70.47668158261267 14.648 - 84.331960813149735 16.748000000000001 95.59491359178736 19.9 101.25649337914118 - 24 101.25649337914118; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 21.681999630647688 4.148 17.474611388237843 - 7.3 17.474611388237843 11.5 35.408849541152719 12.548 34.255627036058527 - 14.648 22.074891409620573 16.748000000000001 21.323520025201621 19.9 26.015932934335911 - 24 26.015932934335911; - setAttr -s 9 ".kit[1:8]" 1 9 9 9 9 9 9 - 9; - setAttr -s 9 ".kot[1:8]" 1 9 9 9 9 9 9 - 9; - setAttr -s 9 ".kix[1:8]" 0.029673773795366287 0.017078431323170662 - 0.01302949246019125 0.0098365629091858864 0.013530971482396126 0.055441375821828842 - 0.064261630177497864 1; - setAttr -s 9 ".kiy[1:8]" -0.99955964088439941 0.99985414743423462 - 0.99991512298583984 -0.99995160102844238 -0.999908447265625 0.99846196174621582 - 0.99793308973312378 0; - setAttr -s 9 ".kox[1:8]" 0.029673777520656586 0.017078431323170662 - 0.01302949246019125 0.0098365629091858864 0.013530971482396126 0.055441375821828842 - 0.064261630177497864 1; - setAttr -s 9 ".koy[1:8]" -0.99955964088439941 0.99985414743423462 - 0.99991512298583984 -0.99995160102844238 -0.999908447265625 0.99846196174621582 - 0.99793308973312378 0; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 53.227781741534002 4.148 53.227781741534031 - 7.3 53.227781741534031 11.5 53.227781741534031 12.548 53.227781741534031 - 14.648 52.271578036381456 16.748000000000001 53.227781741534031 19.9 52.148343279028765 - 24 52.148343279028765; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 77.619347049814735 4.148 77.619347049814735 - 7.3 77.619347049814735 11.5 77.619347049814735 12.548 77.619347049814735 - 14.648 98.169328532833021 16.748000000000001 77.619347049814735 19.9 82.446429016956358 - 24 82.446429016956358; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4.148 0 7.3 0 11.5 0 12.548 - 0 14.648 18.317387210898726 16.748000000000001 0 19.9 -0.80839780164645469 - 24 -0.80839780164645469; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 7.4260738755503866 4.148 7.4260738755503866 - 7.3 7.4260738755503866 11.5 7.4260738755503866 12.548 7.4260738755503866 - 14.648 6.4639128255278093 16.748000000000001 7.4260738755503866 19.9 10.230028851047811 - 24 10.230028851047811; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.148 1 7.3 1 11.5 1 12.548 - 1 14.648 1 16.748000000000001 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.148 1 7.3 1 11.5 1 12.548 - 1 14.648 1 16.748000000000001 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.148 1 7.3 1 11.5 1 12.548 - 1 14.648 1 16.748000000000001 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 56.808405044991083 6.2480000000000002 - 52.420320839678453 10.448 52.420320839678453 14.648 -61.878181048440688; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 75.282535127877466 6.2480000000000002 - 66.030075273971008 10.448 66.030075273971008 14.648 83.737732760244796; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 54.213650971955524 6.2480000000000002 - 24.09270632929826 10.448 24.09270632929826 14.648 22.017722616107687; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 0 10.448 - 0 14.648 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 0 10.448 - 0 14.648 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 10.448 - 1 14.648 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 0 10.448 - 0 14.648 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 0 10.448 - 0 14.648 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 0 10.448 - 0 14.648 0; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 9.4 1 - 14.648 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.0180767416209342 6.2480000000000002 - -0.0180767416209342 9.4 -0.0180767416209342 14.648 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.350740136846035 6.2480000000000002 - 4.350740136846035 9.4 4.350740136846035 14.648 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.679538405939565 6.2480000000000002 - 2.679538405939565 9.4 2.679538405939565 14.648 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 40.837233780478478 - 9.4 40.837233780478478 14.648 13.087201259522407; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 -38.808567262648374 - 9.4 -38.808567262648374 14.648 10.003098609531897; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.2480000000000002 -54.053782918450658 - 9.4 -54.053782918450658 14.648 -7.8227516112741773; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 9.4 1 - 14.648 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 9.4 1 - 14.648 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.2480000000000002 1 9.4 1 - 14.648 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2.052 1 3.1000000000000001 - 1 6.2480000000000002 1 7.3 1 8.3480000000000008 1 9.4 1 10.448 1 15.7 1 19.9 - 1 24 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 2.052 0 3.1000000000000001 - 0 6.2480000000000002 0 7.3 0 8.3480000000000008 0 9.4 0 10.448 0 15.7 0 19.9 - 0 24 0; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 2.052 0 3.1000000000000001 - 0 6.2480000000000002 0 7.3 0 8.3480000000000008 0 9.4 0 10.448 0 15.7 0 19.9 - 0 24 0; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 2.052 0 3.1000000000000001 - 0 6.2480000000000002 0 7.3 0 8.3480000000000008 0 9.4 0 10.448 0 15.7 0 19.9 - 0 24 0; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2.052 1 3.1000000000000001 - 1 6.2480000000000002 1 7.3 1 8.3480000000000008 1 9.4 1 10.448 1 15.7 1 19.9 - 1 24 1; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2.052 1 3.1000000000000001 - 1 6.2480000000000002 1 7.3 1 8.3480000000000008 1 9.4 1 10.448 1 15.7 1 19.9 - 1 24 1; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2.052 1 3.1000000000000001 - 1 6.2480000000000002 1 7.3 1 8.3480000000000008 1 9.4 1 10.448 1 15.7 1 19.9 - 1 24 1; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.0581001958067302 2.052 1.0948127264905012 - 3.1000000000000001 1.11684024445622 6.2480000000000002 1.1765277123777598 - 7.3 1.1524035889765496 8.3480000000000008 1.1131105080938628 9.4 1.0581001958067302 - 10.448 1.0581001958067302 15.7 1.0581001958067302 19.9 1.0581001958067302 - 24 1.0581001958067302; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.97887915067413922 2.052 1.0895724057742924 - 3.1000000000000001 1.1559883597396188 6.2480000000000002 1.3359541681539751 - 7.3 1.263216665078136 8.3480000000000008 1.1447427008728364 9.4 0.97887915067413922 - 10.448 0.97887915067413922 15.7 0.97887915067413922 19.9 0.97887915067413922 - 24 0.97887915067413922; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -1.386441338106027 2.052 -0.67404945747880174 - 3.1000000000000001 -0.24661433000295552 6.2480000000000002 0.91159695183735756 - 7.3 0.44347805005498775 8.3480000000000008 -0.31898836719534573 9.4 -1.386441338106027 - 10.448 -1.386441338106027 15.7 -1.386441338106027 19.9 -1.386441338106027 - 24 -1.386441338106027; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 2.052 0 3.1000000000000001 - 0 6.2480000000000002 0 7.3 0 8.3480000000000008 0 9.4 0 10.448 0 15.7 0 19.9 - 0 24 0; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 2.052 0 3.1000000000000001 - 0 6.2480000000000002 0 7.3 0 8.3480000000000008 0 9.4 0 10.448 0 15.7 0 19.9 - 0 24 0; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -42.398876839680931 2.052 -79.835938750022891 - 3.1000000000000001 -121.54955865475144 6.2480000000000002 -161.57409822689218 - 7.3 -151.81259393356905 8.3480000000000008 -86.361008444923414 9.4 4.5836623610465832 - 10.448 35.52338329811105 15.7 35.52338329811105 19.9 -19.480565034447981 - 24 -19.480565034447981; - setAttr -s 11 ".kit[7:10]" 9 9 9 9; - setAttr -s 11 ".kot[7:10]" 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 1 9 1 10 1 12 1 15 1 16 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 78.600584314139496 9 78.600584314139496 - 10 78.60058431413951 12 78.600584314139525 15 78.600584314139567 16 78.600584314139567; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 3.8609192673090504 9 3.8609192673090504 - 10 11.650169469057218 12 45.219404550437929 15 2.9376454189586578 16 2.9376454189586578; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 5.5906769424741469 9 5.5906769424741469 - 10 -3.9287856975982827 12 -44.041952373396228 15 -109.41754773597665 16 -109.41754773597665; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 -156.60826252478512 9 63.816585291251073 - 10 59.107681594040649 12 -17.802315010244776 15 47.926788216705674 16 47.926788216705674; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 77.351754812025419 9 50.582462417110868 - 10 31.315654088460462 12 47.685109442991177 15 60.562683961022834 16 60.562683961022834; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 168.36778920107275 9 390.32776901852361 - 10 307.42961870043928 12 274.13421065140358 15 379.52938672271426 16 379.52938672271426; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 1 9 1 10 1 12 1 15 1 16 1; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 0.99999999999999978 9 0.99999999999999978 - 10 0.99999999999999978 12 0.99999999999999978 15 0.99999999999999978 16 0.99999999999999978; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 8 1 9 1 10 1 12 1 15 1 16 1; - setAttr -s 6 ".kit[0:5]" 3 3 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 11 1 13 1 14 1 15 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 88.672217622939343 10 88.672217622939343 - 11 88.672217622939357 13 88.672217622939371 14 88.672217622939371 15 88.672217622939371; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 6.9402665812079611 10 6.9402665812079611 - 11 15.766560710230296 13 22.346652926270433 14 4.4894214231679452 15 4.4894214231679452; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -18.214943034405117 10 -18.214943034405117 - 11 -44.34302944236854 13 -105.95117977708449 14 -130.90878855173327 15 -130.90878855173327; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 47.631355515172437 10 47.631355515172437 - 11 -6.2028584671555107 13 -50.80968975122483 14 -170.25837577939981 15 -142.25236212754626; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 79.910841797573624 10 79.910841797573624 - 11 37.543026169911336 13 37.167755942030972 14 34.499931339409237 15 34.499931339409251; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 3.4514964971630411 10 3.4514964971630411 - 11 -55.209808881598896 13 -184.46032272634824 14 -195.42099951082329 15 -195.42099951082295; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 11 1 13 1 14 1 15 1; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.99999999999999989 10 0.99999999999999989 - 11 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 15 0.99999999999999989; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.99999999999999978 10 0.99999999999999978 - 11 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 15 0.99999999999999978; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 1 11.496 1 12.548 1 14.648 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 8.6016776801509778 11.496 - 23.943543845639425 12.548 58.696844245565899 14.648 103.68873848940657; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 0 11.496 4.9009001170382902 - 12.548 9.3843161913381756 14.648 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 37.961325025704973 11.496 - 37.961325025704973 12.548 34.209617387686897 14.648 25.299311326735271; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 -174.49049195404214 11.496 - -228.3002848052127 12.548 -218.33550891026076 14.648 -174.49049195404214; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 129.78625356110399 11.496 - 214.20249850929133 12.548 198.56986145828409 14.648 129.78625356110399; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 -169.93906815090079 11.496 - -139.71790683106434 12.548 -145.31441785935041 14.648 -169.93906815090079; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 1 11.496 1 12.548 1 14.648 - 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 1 11.496 1 12.548 1 14.648 - 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 10.448 1 11.496 1 12.548 1 14.648 - 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.3480000000000008 1 9.4 1 - 13.6 1 16.748000000000001 1 20.948 1 24 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.3480000000000008 0 9.4 0 - 13.6 0 16.748000000000001 0 20.948 0 24 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.3480000000000008 - 2.3128351505039433 9.4 2.3128351505039433 13.6 2.3128351505039433 16.748000000000001 - 2.3128351505039433 20.948 2.3128351505039433 24 2.3128351505039433; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.3480000000000008 - 0.23421866920666501 9.4 0.23421866920666501 13.6 0.23421866920666501 16.748000000000001 - 0.23421866920666501 20.948 0.23421866920666501 24 0.23421866920666501; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.217512413782917 8.3480000000000008 - 8.662326612251162 9.4 15.105799979787687 13.6 -17.402688213908618 16.748000000000001 - 4.523335013660879 20.948 7 24 7; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -21.147354328081303 8.3480000000000008 - -43.813935085996356 9.4 -51.415767461384647 13.6 -29.124215902374598 16.748000000000001 - -28.679561594640489 20.948 -26.903356467361473 24 -26.903356467361473; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.5257740956338841 8.3480000000000008 - 12.170119715244907 9.4 18.134672583594401 13.6 12.242743575723321 16.748000000000001 - -3.5025542051434257 20.948 15.011069830747704 24 15.011069830747704; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.3480000000000008 1 9.4 1 - 13.6 1 16.748000000000001 1 20.948 1 24 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.3480000000000008 1 9.4 1 - 13.6 1 16.748000000000001 1 20.948 1 24 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.3480000000000008 1 9.4 1 - 13.6 1 16.748000000000001 1 20.948 1 24 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.352 1 9.4 1 12.552 1 15.7 - 1 16 1 18 1 20 1 23 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -7.3924057388556301 8.352 -7.3924057388556301 - 9.4 1.0005270907739217 12.552 42.060650594550999 15.7 78.247632690892758 - 16 79.601175143374789 18 79.601175143374789 20 83.864309177434677 23 90.213595640482083; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.207994295172762 8.352 1.207994295172762 - 9.4 7.8892951001951186 12.552 15.013491798849937 15.7 0.5189435796591102 - 16 -0.11863116110308392 18 -0.11863116110308392 20 4.1819934621864316 23 - 0.51894357965911109; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 36.754381567957459 8.352 36.754381567957459 - 9.4 36.754381567957459 12.552 36.754381567957459 15.7 36.754381567957452 - 16 36.754381567957452 18 36.754381567957452 20 36.754381567957452 23 36.754381567957452; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.4372903291937864 8.352 3.4372903291937864 - 9.4 -28.917754385025109 12.552 -57.607006987276243 15.7 -22.860713320210614 - 16 -22.530475317558079 18 -22.530475317558079 20 -75.734706693290704 23 -22.860713320210614; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -46.578931290797854 8.352 -46.578931290797854 - 9.4 -16.34768974477679 12.552 -11.628400129848393 15.7 -72.027271396680575 - 16 -73.708913302325314 18 -73.708913302325314 20 -53.799720133747385 23 -72.027271396680575; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.1476086226841948 8.352 -5.1476086226841948 - 9.4 47.86757225877497 12.552 43.927458420423172 15.7 29.87443107305014 16 - 29.111838973357571 18 29.111838973357571 20 75.093448201936937 23 29.87443107305014; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.352 1 9.4 1 12.552 1 15.7 - 1 16 1 18 1 20 1 23 1; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.352 1 9.4 1 12.552 1 15.7 - 1 16 1 18 1 20 1 23 1; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.352 1 9.4 1 12.552 1 15.7 - 1 16 1 18 1 20 1 23 1; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 3 3 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 9 9 9 3 3 - 9 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 1 9.4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 6.7758528420198658 - 9.4 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 0 9.4 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 0 9.4 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 -61.864687108561675 - 9.4 0; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 3.2695897469829776 - 9.4 3.2695897469829776; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 -6.9162979482121454 - 9.4 -6.9162979482121454; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 1 9.4 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 1 9.4 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8.3480000000000008 1 9.4 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15.7 1 16.748000000000001 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -7.5406347832540632e-013 15.7 - -7.5406347832540632e-013 16.748000000000001 -7.5406347832540632e-013; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.71946295727715 15.7 13.71946295727715 - 16.748000000000001 13.71946295727715; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.0908609005564358e-013 15.7 - -3.0908609005564358e-013 16.748000000000001 -3.0908609005564358e-013; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 77.739160914831501 15.7 77.739160914831501 - 16.748000000000001 77.739160914831501; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -76.726154744596627 15.7 -76.726154744596627 - 16.748000000000001 -76.726154744596627; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -173.86213662459591 15.7 -173.86213662459591 - 16.748000000000001 -173.86213662459591; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459183 15.7 15.445123296459183 - 16.748000000000001 15.445123296459183; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 15.7 15.445123296459185 - 16.748000000000001 15.445123296459185; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459181 15.7 15.445123296459181 - 16.748000000000001 15.445123296459181; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15.7 1 16.748000000000001 1; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 15.7 0 16.748000000000001 0; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 15.7 0 16.748000000000001 0; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 15.7 0 16.748000000000001 0; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 15.7 0 16.748000000000001 1; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 15.7 0 16.748000000000001 0; - setAttr -s 3 ".kit[0:2]" 9 3 3; - setAttr -s 3 ".kot[0:2]" 9 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 14 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.5294371750177831 14 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 13.481673551673362 14 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.26635088939205875 14 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 141.20709981379272 14 141.20709981379272; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 64.064019952206479 14 64.064019952206479; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 252.95011708695623 14 252.95011708695623; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 14 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 14 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 14 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 14 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 14 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 14 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 14 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 14 0 15 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 14 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -25.200000000000212; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -43.200000000003328; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3.1000000000000001 1 8.3480000000000008 - 1 10.448 1 13.6 1 16.748000000000001 1 20.948 1 24 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3.1000000000000001 0 8.3480000000000008 - 0 10.448 0 13.6 0 16.748000000000001 0 20.948 0 24 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.6456615572060826 3.1000000000000001 - 2.6456615572060826 8.3480000000000008 2.6456615572060826 10.448 2.6456615572060826 - 13.6 2.6456615572060826 16.748000000000001 2.6456615572060826 20.948 2.6456615572060826 - 24 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9935618776130362 3.1000000000000001 - 1.9935618776130362 8.3480000000000008 1.9935618776130362 10.448 1.9935618776130362 - 13.6 1.9935618776130362 16.748000000000001 1.9935618776130362 20.948 1.9935618776130362 - 24 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -33.760436965417369 3.1000000000000001 - -38.112442118408026 8.3480000000000008 -4.4156089923617543 10.448 37.560223385014758 - 13.6 -8.2219839863983015 16.748000000000001 19.067477033895589 20.948 -16.674252396807258 - 24 -16.674252396807258; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3.1000000000000001 -10.061401502697167 - 8.3480000000000008 20.576507925215502 10.448 -1.9628521001355861 13.6 12.759316520938423 - 16.748000000000001 8.5013965314338051 20.948 13.077341204772472 24 13.077341204772472; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3.1000000000000001 1.521158556358126 - 8.3480000000000008 -9.5466690815521389 10.448 -15.878049514360852 13.6 23.380677886033382 - 16.748000000000001 25.589777156250406 20.948 13.296647852743098 24 13.296647852743098; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3.1000000000000001 1 8.3480000000000008 - 1 10.448 1 13.6 1 16.748000000000001 1 20.948 1 24 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3.1000000000000001 1 8.3480000000000008 - 1 10.448 1 13.6 1 16.748000000000001 1 20.948 1 24 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3.1000000000000001 1 8.3480000000000008 - 1 10.448 1 13.6 1 16.748000000000001 1 20.948 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.2480000000000002 1 8.3480000000000008 - 1 13.6 1 15.7 1 19.9 1 24 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.2480000000000002 0 8.3480000000000008 - 0 13.6 0 15.7 0 19.9 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.2480000000000002 0 8.3480000000000008 - 0 13.6 0 15.7 0 19.9 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.2480000000000002 0 8.3480000000000008 - 0 13.6 0 15.7 0 19.9 0 24 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.2480000000000002 1 8.3480000000000008 - 1 13.6 1 15.7 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.2480000000000002 1 8.3480000000000008 - 1 13.6 1 15.7 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.2480000000000002 1 8.3480000000000008 - 1 13.6 1 15.7 1 19.9 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.34393481011973803 6.2480000000000002 - -0.34393481011973803 8.3480000000000008 -0.34393481011973803 13.6 -0.34393481011973803 - 15.7 -0.34393481011973803 19.9 -0.34393481011973803 24 -0.34393481011973803; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.2390100792205283 6.2480000000000002 - 1.2390100792205283 8.3480000000000008 1.2390100792205283 13.6 1.2390100792205283 - 15.7 1.2390100792205283 19.9 1.2390100792205283 24 1.2390100792205283; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.5318494932524733 6.2480000000000002 - -1.5318494932524733 8.3480000000000008 -1.5318494932524733 13.6 -1.5318494932524733 - 15.7 -1.5318494932524733 19.9 -1.5318494932524733 24 -1.5318494932524733; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.2480000000000002 0 8.3480000000000008 - 0 13.6 0 15.7 0 19.9 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.2480000000000002 0 8.3480000000000008 - 0 13.6 0 15.7 0 19.9 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -34.377467707849391 6.2480000000000002 - -34.377467707849391 8.3480000000000008 -6.8754935415698784 13.6 30.939720937064457 - 15.7 -55.003948332559027 19.9 -24.064227395494576 24 -24.064227395494576; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 -88.999627454702534 15 56.048447197952193 - 24 37.269639207816134; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 6.0265376079649862 15 67.068101451165148 - 24 78.190603860868208; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 -95.054620395662354 15 -28.957084042025638 - 24 -9.5368667231700393; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 0 15 0 24 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 0 15 0 24 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 1 15 1 24 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 0 15 0 24 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 0 15 0 24 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 10 0 15 0 24 0; -select -ne :time1; - setAttr ".o" 15; -select -ne :renderPartition; - setAttr -s 10 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 10 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_Rwing_meshShape3Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig5; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape5Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933642 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 38.595655661674861 -5.9679249907787391e-015 - -11.035466676095478 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FLAT"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of evade_left_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/evade_right.ma b/base/models/monsters/imp/animation/cycles/evade_right.ma deleted file mode 100644 index 9dba2a9f0..000000000 --- a/base/models/monsters/imp/animation/cycles/evade_right.ma +++ /dev/null @@ -1,6761 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:23 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: evade_right.ma -//Last modified: Sat, Mar 15, 2003 06:01:38 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" -181.47145194704797 43.659324603195387 174.01058706371148 ; - setAttr ".r" -type "double3" 2.0698910859751112 -1073.39999999984 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 191.02600546262966; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -203.41311067007797 50.558908253946889 -15.625628150939114 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.844702467344078; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" -161.50975652176419 44.933753950034784 128.83073041954563 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 494.36694633206719; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 114.81837383334553 25.528544910413544 0.63144622590610755 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 174.246942643533; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 45 -ast 1 -aet 45 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 11 1 13 1 17 1 21 1 27 - 1 32 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.3924057183505063 10 -7.3924057183505063 - 11 -19.348518022558906 13 -60.900908325709324 17 -123.42549562148771 21 -215.74236275726096 - 27 -215.74236275726096 32 -254.94273096778028; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10 0 11 8.2320773242090652 - 13 16.072150966312922 17 34.888327707362251 21 0 27 0 32 0; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.3620493586843594 10 -7.3620493586843594 - 11 -7.3620493586843594 13 -7.3620493586843594 17 -7.3620493586843594 21 -17.054140485168649 - 27 -17.054140485168649 32 -7.3620493586843594; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.3462904043098467 10 5.3462904043098467 - 11 -33.319971652020691 13 -69.38632030035204 17 -128.03337603787173 21 5.3462904043098467 - 27 5.3462904043098467 32 5.3462904043098467; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -29.54838557779286 10 -29.54838557779286 - 11 -17.318993366105985 13 -45.256872994581308 17 -45.25687299458135 21 -29.54838557779286 - 27 -29.54838557779286 32 -29.54838557779286; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -5.3030645628451412 10 -5.3030645628451412 - 11 -51.845587077867314 13 -29.817799000132865 17 -29.817799000132887 21 -5.3030645628451412 - 27 -5.3030645628451412 32 -5.3030645628451412; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 11 1 13 1 17 1 21 1 27 - 1 32 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 11 1 13 1 17 1 21 1 27 - 1 32 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 11 1 13 1 17 1 21 1 27 - 1 32 1; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 3 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 3 9; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 9 1 12 1 17 1 23 1 28 1 36 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599503 9 7.1689522478599503 - 12 -40.500970729111103 17 -126.90270612487122 23 -192.44885021820645 28 -192.44885021820645 - 36 -240.57713783918689; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 9 0 12 29.335337216597555 17 - 48.586652264989702 23 0 28 0 36 0; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.7485750141607372 9 -7.7485750141607372 - 12 -7.7485750141607372 17 -7.7485750141607372 23 -15.839364128443274 28 -15.839364128443274 - 36 -7.7485750141607372; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 10.109326515514191 9 10.109326515514191 - 12 -58.692488770796899 17 -56.90881149643576 23 10.109326515514191 28 10.109326515514191 - 36 10.109326515514191; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 63.314403926397745 9 63.314403926397745 - 12 -26.253220044302779 17 -59.835251238756534 23 63.314403926397745 28 63.314403926397745 - 36 63.314403926397745; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.590164763476968 9 11.590164763476968 - 12 -68.508554169546244 17 -101.93964446779664 23 11.590164763476968 28 11.590164763476968 - 36 11.590164763476968; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 9 1 12 1 17 1 23 1 28 1 36 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 9 1 12 1 17 1 23 1 28 1 36 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 9 1 12 1 17 1 23 1 28 1 36 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6 1 8 1 13 1 18 1 22 1 26 1 - 30 1 34 1 40 1 45 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.980821395062172 6 0.27381129552116867 - 8 0.27381129552116867 13 -89.486469772009983 18 -163.7809187093039 22 -188.94763624315323 - 26 -222.68067202046453 30 -232.5480632695718 34 -249.56610325481512 40 -252.92974140662727 - 45 -249.95037122056658; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 41.235789592866901 6 28.575464687937778 - 8 28.575464687937778 13 38.959776126812251 18 25.833189089737733 22 22.695657312046894 - 26 18.610008285812537 30 26.026168909772956 34 18.641620404936621 40 30.252279948468125 - 45 34.377561744552153; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.4191866633612995 6 -2.4191866633612995 - 8 -2.4191866633612995 13 -2.4191866633612995 18 -2.4191866633612995 22 -2.4191866633612995 - 26 -2.4191866633612995 30 -2.4191866633612995 34 -2.4191866633612995 40 -2.4191866633612995 - 45 -2.4191866633612995; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 6 0 8 0 13 -55.093024598977294 - 18 96.529499589172943 22 88.663861170259622 26 59.081074706613009 30 63.305289935707883 - 34 63.314281585782879 40 0 45 0; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 6 0 8 0 13 -50.641682296221134 - 18 -81.753658486587128 22 -32.757963920499364 26 16.650682494581492 30 14.794441917685115 - 34 4.3713184575550841 40 0 45 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 7.4260738755503946 6 7.4260738755503946 - 8 7.4260738755503946 13 85.229016109225597 18 -10.629102369323554 22 -15.278829354574315 - 26 -3.8870159881599129 30 3.2011179096204359 34 8.0219449693505691 40 7.4260738755503946 - 45 7.4260738755503946; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6 1 8 1 13 1 18 1 22 1 26 1 - 30 1 34 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6 1 8 1 13 1 18 1 22 1 26 1 - 30 1 34 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6 1 8 1 13 1 18 1 22 1 26 1 - 30 1 34 1 40 1 45 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.83371697884823759; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1086667563431649; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.4408920985006262e-016; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.660431799163181; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4125540166489063; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 380.4969630522524; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.44667534838539324; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.64190619217311; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -15.409205020920503; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 27.72702953106549; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 9 1 11 1 15 1 18 1 21 1 - 25 1 32 1 36 1 40 1 45 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 5 1.0045479787101599 9 0.48172586076062163 - 11 0.48172586076062163 15 1.0176773803096548 18 0.85091633815985268 21 1.6685837614423624 - 25 0.84112426497708892 32 0.32892658188899154 36 0.32892658188899154 40 0.32892658188899154 - 45 0.32892658188899154; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 2.6456615572060826 5 4.7090199692127062 - 9 2.7344596386744482 11 2.7344596386744482 15 5.4214043640009457 18 6.3226416784689832 - 21 7.0243503467677391 25 2.5370090587556109 32 3.4222381910604791 36 3.4222381910604791 - 40 3.4222381910604791 45 3.4222381910604791; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1.9935618776130362 5 1.2030900792391837 - 9 1.4044116585435196 11 1.4044116585435196 15 0.88194280673764525 18 -0.45026579339231154 - 21 2.1783174597526882 25 1.60178846783233 32 1.2213328102643177 36 1.2213328102643177 - 40 1.2213328102643177 45 1.2213328102643177; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -24.316046252136612 5 -35.607483432720834 - 9 5.3696607675236967 11 -18.731473595249764 15 -18.731473595249764 18 -110.81935227877935 - 21 -110.81935227877935 25 -27.749355562739837 32 -67.275052464201821 36 -53.720328249997209 - 40 -24.500935453127642 45 -40.164806473441651; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 6.4543875548351615 5 10.405879934601728 - 9 13.708255652475101 11 30.889010882153709 15 30.889010882153709 18 30.725557219150485 - 21 30.725557219150485 25 -1.3787051342395047 32 6.4543875548351703 36 13.08874297433267 - 40 5.6586217812526618 45 5.4463091479820571; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -26.223968767469305 5 -28.432242496026841 - 9 -19.163725819891209 11 -26.000853887311774 15 -26.000853887311774 18 -88.304274939159413 - 21 -88.304274939159413 25 -6.7592627310601845 32 -26.223968767469341 36 -11.464091618090949 - 40 -14.404932426890696 45 -23.94613380208822; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 9 1 11 1 15 1 18 1 21 1 - 25 1 32 1 36 1 40 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 9 1 11 1 15 1 18 1 21 1 - 25 1 32 1 36 1 40 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 9 1 11 1 15 1 18 1 21 1 - 25 1 32 1 36 1 40 1 45 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3533140211779946; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.2846953468686371; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.2916645882841449; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 12 1 16 1 17 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.8522027930141798 4 4.8522027930141798 - 9 4.8522027930141798 12 4.8522027930141798 16 4.8522027930141798 17 4.8522027930141798; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 2.1192573708759381 4 2.1192573708759381 - 9 2.1192573708759381 12 2.1192573708759381 16 2.1192573708759381 17 2.1192573708759381; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.0821078932592165 4 -3.0821078932592165 - 9 -3.0821078932592165 12 -3.0821078932592165 16 -3.0821078932592165 17 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -17.481282422130235 4 -32.49398556467856 - 9 58.300120009523553 12 26.499821896526665 16 97.255399282535478 17 -4.4232060444338455; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 30.702824881409519 4 13.554764457740612 - 9 30.767308778444345 12 -28.127726850988847 16 -30.652940176857967 17 7.7033018727937677; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -30.797032566082748 4 -14.40028272298267 - 9 -2.1549523877148045 12 70.43309220207999 16 -12.060183319555254 17 -147.51753765718018; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 12 1 16 1 17 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 12 1 16 1 17 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 12 1 16 1 17 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9 1 11 1 16 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.412879749935719 5 12.412879749935719 - 9 12.412879749935719 11 12.412879749935719 16 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -6.7286993982861674 5 -6.7286993982861674 - 9 -6.7286993982861674 11 -6.7286993982861674 16 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.868763862603668 5 -3.868763862603668 - 9 -3.868763862603668 11 -3.868763862603668 16 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 19.580561221118923 5 81.833245262733868 - 9 -9.8452210009996435 11 30.842555455095432 16 7.0825554550955419; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 9 0 11 0 16 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 9 0 11 0 16 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9 1 11 1 16 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9 1 11 1 16 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9 1 11 1 16 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 11 1 15 1 17 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -5.0348979650608028 4 -5.0348979650608028 - 9 -5.0348979650608028 11 -5.0348979650608028 15 -5.0348979650608028 17 -5.0348979650608028; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 2.1192000000002627 4 2.1192000000002627 - 9 2.1192000000002627 11 2.1192000000002627 15 2.1192000000002627 17 2.1192000000002627; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.0821100000000254 4 -3.0821100000000254 - 9 -3.0821100000000254 11 -3.0821100000000254 15 -3.0821100000000254 17 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 49.111805173615501 4 53.85590746074616 - 9 54.1450938353222 11 -44.561996213979185 15 -35.968732317044832 17 -57.385164359939679; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -36.514345314725674 4 -56.538010589070929 - 9 -15.911490233161476 11 29.7374114824018 15 40.145879395545997 17 40.865840102241911; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -10.891726707689953 4 -14.098958158541281 - 9 -25.411720294645246 11 14.293546717624292 15 29.179200202391808 17 -33.267262032252461; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 11 1 15 1 17 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 11 1 15 1 17 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 9 1 11 1 15 1 17 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.5757406876636644; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6829523665849453; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1851256367233773; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.609353754287454; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.838773336231448; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.61608909736457995; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1993957867164236; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -21.447112172188898; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.369311790170695; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.716593707894834; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 45.543464667899237; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35449716056366781; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.6720434721822404; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 18 1 20 1 22 1 25 1 29 1 34 - 1 37 1 41 1 45 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 0 20 0 22 0 25 0 29 0 34 - 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 0 20 0 22 0 25 0 29 0 34 - 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 0 20 0 22 0 25 0 29 0 34 - 0 37 0 41 0 45 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 18 1 20 1 22 1 25 1 29 1 34 - 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 18 1 20 1 22 1 25 1 29 1 34 - 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 18 1 20 1 22 1 25 1 29 1 34 - 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.59456568175818736 18 0.65023971941977621 - 20 0.65023971941977621 22 0.65023971941977621 25 0.65023971941977621 29 0.65023971941977621 - 34 0.65023971941977621 37 0.65023971941977621 41 0.65023971941977621 45 0.65023971941977621; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.01570234954633545 18 1.4981953923287352 - 20 1.4981953923287352 22 1.4981953923287352 25 1.4981953923287352 29 1.4981953923287352 - 34 1.4981953923287352 37 1.4981953923287352 41 1.4981953923287352 45 1.4981953923287352; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.9095143587556849 18 -1.1543824642181839 - 20 -1.1543824642181839 22 -1.1543824642181839 25 -1.1543824642181839 29 -1.1543824642181839 - 34 -1.1543824642181839 37 -1.1543824642181839 41 -1.1543824642181839 45 -1.1543824642181839; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 0 20 0 22 0 25 0 29 0 34 - 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 0 20 0 22 0 25 0 29 0 34 - 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 18 14.896902673401405 20 -41.252961249419272 - 22 -77.922260137791952 25 -119.17522138721124 29 -68.754935415698796 34 -89.381416040408425 - 37 -126.05071492878112 41 -2.2918311805232952 45 6.8754935415698784; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 16 1 17 1 18 1 19 1 21 1 22 - 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 41 1 45 1; - setAttr -s 20 ".kot[0:19]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 0 17 0 18 0 19 0 21 0 22 - 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 0 17 0 18 0 19 0 21 0 22 - 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 0 17 0 18 0 19 0 21 0 22 - 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 41 0 45 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 16 1 17 1 18 1 19 1 21 1 22 - 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 16 1 17 1 18 1 19 1 21 1 22 - 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 1 16 1 17 1 18 1 19 1 21 1 22 - 1 24 1 25 1 26 1 27 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 41 1 45 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0.73927397107071957 16 -1.2652072168122088 - 17 -1.4026980137766707 18 -1.4976405410595273 19 -1.5081897108270841 21 -1.4976405410595273 - 22 -1.4976405410595273 24 -1.4976405410595273 25 -1.4976405410595273 26 -1.4976405410595273 - 27 -1.4976405410595273 31 -1.4976405410595273 32 -1.4976405410595273 33 -1.4976405410595273 - 34 -1.4976405410595273 35 -1.4976405410595273 36 -1.4976405410595273 37 -1.4976405410595273 - 41 -1.4976405410595273 45 -1.4976405410595273; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 6.4652061646075516e-006 16 1.1789902393549623 - 17 1.2598587530098335 18 1.3157014787377521 19 1.3219062261414272 21 1.3157014787377521 - 22 1.3157014787377521 24 1.3157014787377521 25 1.3157014787377521 26 1.3157014787377521 - 27 1.3157014787377521 31 1.3157014787377521 32 1.3157014787377521 33 1.3157014787377521 - 34 1.3157014787377521 35 1.3157014787377521 36 1.3157014787377521 37 1.3157014787377521 - 41 1.3157014787377521 45 1.3157014787377521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 -1.8583524949953731 16 -0.33759493128799023 - 17 -0.23328356930462457 18 -0.16125268563269213 19 -0.15324925437095768 21 - -0.16125268563269213 22 -0.16125268563269213 24 -0.16125268563269213 25 -0.16125268563269213 - 26 -0.16125268563269213 27 -0.16125268563269213 31 -0.16125268563269213 32 - -0.16125268563269213 33 -0.16125268563269213 34 -0.16125268563269213 35 -0.16125268563269213 - 36 -0.16125268563269213 37 -0.16125268563269213 41 -0.16125268563269213 45 - -0.16125268563269213; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 0 17 0 18 0 19 0 21 0 22 - 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 0 17 0 18 0 19 0 21 0 22 - 0 24 0 25 0 26 0 27 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 41 0 45 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 1 0 16 -7.9401244772263269 17 212.84123170770133 - 18 197.09748152500319 19 168.75195412243781 21 101.98648753328654 22 124.26211650444068 - 24 7.7485719148273509 25 -29.983082828727671 26 154.82829254120327 27 155.8445202755839 - 31 134.13410932448505 32 126.93084777060139 33 308.31327904425535 34 296.56267434275554 - 35 -85.943669269623484 36 147.65124773796106 37 153.5526890950606 41 159.28226704636887 - 45 40.10704565915762; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -118.97547160373531 9 -118.97547160373531 - 12 -85.985337349337328 25 -102.93672689813974 28 -62.899559419927165 32 -114.07151536662252 - 39 -125.52491524567115 45 -119.50197649855403; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 30.32938199865233 9 30.32938199865233 - 12 37.245009823418314 25 48.715862720072344 28 8.4037778138611046 32 40.598392244729872 - 39 52.914597008011093 45 45.04807994191291; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -92.904446145666853 9 -92.904446145666853 - 12 -20.674664705102941 25 -27.783635024484074 28 -19.162398594019983 32 -42.260674161204932 - 39 -79.080236994601165 45 -85.686499942464067; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 12 0 25 0 28 0 32 0 39 - 0 45 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 12 0 25 0 28 0 32 0 39 - 0 45 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9 1 12 1 25 1 28 1 32 1 39 - 1 45 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 12 0 25 0 28 0 32 0 39 - 0 45 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 12 0 25 0 28 0 32 0 39 - 0 45 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9 0 12 0 25 0 28 0 32 0 39 - 0 45 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -71.101691513482606 10 -71.101691513482606 - 13 -34.699963036536381 23 -34.699963036536381 29 -45.103595312723911 38 -50.555321930002272 - 45 -55.522263330279564; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 32.578198345223548 10 32.578198345223548 - 13 38.286793904901621 23 38.286793904901621 29 56.078043307420586 38 59.684297968483477 - 45 46.853012329718709; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -95.56444850608456 10 -95.56444850608456 - 13 -20.183339439302241 23 -20.183339439302241 29 -42.017590779473302 38 -67.317769193345626 - 45 -77.314964248426634; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 0 23 0 29 0 38 0 45 - 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 0 23 0 29 0 38 0 45 - 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 13 1 23 1 29 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 0 23 0 29 0 38 0 45 - 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 0 23 0 29 0 38 0 45 - 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 13 0 23 0 29 0 38 0 45 - 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 1 18 1 25 1 27 1 31 1 35 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 -7.5406347832540632e-013 18 - -7.5406347832540632e-013 25 -7.5406347832540632e-013 27 -7.5406347832540632e-013 - 31 0 35 0 45 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 13.71946295727715 18 13.71946295727715 - 25 13.71946295727715 27 13.71946295727715 31 13.71946295727715 35 13.71946295727715 - 45 13.71946295727715; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 -3.0908609005564358e-013 18 - -3.0908609005564358e-013 25 -3.0908609005564358e-013 27 -3.0908609005564358e-013 - 31 0 35 0 45 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 68.596496127541187 18 68.596496127541187 - 25 68.596496127541187 27 68.596496127541187 31 68.596496127541187 35 68.596496127541187 - 45 68.596496127541187; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 -60.802874383230787 18 -60.802874383230787 - 25 -60.802874383230787 27 -60.802874383230787 31 -60.802874383230787 35 -60.802874383230787 - 45 -60.802874383230787; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 -157.43468421330525 18 -157.43468421330525 - 25 -157.43468421330525 27 -157.43468421330525 31 -157.43468421330525 35 -157.43468421330525 - 45 -157.43468421330525; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 15.445123296459183 18 15.445123296459183 - 25 15.445123296459183 27 15.445123296459183 31 15.445123296459183 35 15.445123296459183 - 45 15.445123296459183; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 15.445123296459185 18 15.445123296459185 - 25 15.445123296459185 27 15.445123296459185 31 15.445123296459185 35 15.445123296459185 - 45 15.445123296459185; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 15.445123296459181 18 15.445123296459181 - 25 15.445123296459181 27 15.445123296459181 31 15.445123296459181 35 15.445123296459181 - 45 15.445123296459181; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 1 25 1 27 1 31 1 35 1 45 - 1; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 0 25 0 27 0 31 0 35 0 45 - 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 0 25 0 27 0 31 0 35 0 45 - 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 0 25 0 27 0 31 0 35 0 45 - 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 1 25 1 27 0 31 1 35 1 45 - 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 17 0 18 0 25 0 27 0 31 0 35 0 45 - 0; - setAttr -s 7 ".kit[4:6]" 3 3 9; - setAttr -s 7 ".kot[4:6]" 3 3 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 1 18 1 25 1 27 1 31 1 35 1 41 - 1 45 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 -29.775800000000025 18 -256.16747389996857 - 25 -256.16747389996857 27 -275.21427074565281 31 -312.34346966002465 35 -312.34346966002465 - 41 -338.38212863893472 45 -334.04235214244972; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 57.582500000000032 18 2.8530964054389258 - 25 2.8530964054389258 27 12.979241563903999 31 3.5763924881864373 35 3.5763924881864373 - 41 38.005250054063751 45 42.530988707402258; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 -1.0893083480314791 18 7.6203306566260096 - 25 7.6203306566260096 27 10.694320893563958 31 18.891628192065127 35 18.891628192065127 - 41 11.392327486491034 45 4.2835812496106671; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 9.4749040322149245 18 11.833209691143011 - 25 11.833209691143011 27 75.103578925601127 31 21.674012543676721 35 21.674012543676721 - 41 31.529072427271199 45 113.98416912290742; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 -58.854902956455234 18 -34.058892508253493 - 25 -34.058892508253493 27 -23.422672010672223 31 -34.829033134343341 35 -34.829033134343341 - 41 -54.474866962940382 45 -58.517155185316824; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 -8.3632933901642268 18 22.085021569182445 - 25 22.085021569182445 27 25.194074500427362 31 17.743684897226686 35 17.743684897226686 - 41 40.34231482853253 45 -32.001863360350264; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 1 18 1 25 1 27 1 31 1 35 1 41 - 1 45 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 0.99999999999999978 18 0.99999999999999978 - 25 0.99999999999999978 27 0.99999999999999978 31 0.99999999999999978 35 0.99999999999999978 - 41 0.99999999999999978 45 0.99999999999999978; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 17 1 18 1 25 1 27 1 31 1 35 1 41 - 1 45 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 9 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 17 1 18 1 32 1 37 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -2.5294371750177831 17 -2.5294371750177831 - 18 -2.5294371750177831 32 -2.5294371750177831 37 -2.5294371750177831; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 13.481673551673362 17 13.481673551673362 - 18 13.481673551673362 32 13.481673551673362 37 13.481673551673362; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -0.26635088939205875 17 -0.26635088939205875 - 18 -0.26635088939205875 32 -0.26635088939205875 37 -0.26635088939205875; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 141.20709981379272 17 141.20709981379272 - 18 141.20709981379272 32 141.20709981379272 37 141.20709981379272; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 64.064019952206479 17 64.064019952206479 - 18 64.064019952206479 32 64.064019952206479 37 64.064019952206479; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 252.95011708695623 17 252.95011708695623 - 18 252.95011708695623 32 252.95011708695623 37 252.95011708695623; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 17 15.445123296459185 - 18 15.445123296459185 32 15.445123296459185 37 15.445123296459185; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 17 15.445123296459185 - 18 15.445123296459185 32 15.445123296459185 37 15.445123296459185; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 17 15.445123296459185 - 18 15.445123296459185 32 15.445123296459185 37 15.445123296459185; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 1 18 1 32 1 37 1; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 0 18 0 32 0 37 0; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 0 18 0 32 0 37 0; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 0 18 0 32 0 37 0; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 1 18 1 32 1 37 0; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 17 0 18 0 32 0 37 0; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 1 16 1 17 1 24 1 28 1 32 1 36 - 1 40 1 45 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 -206.88865853722038 16 -211.17994602026099 - 17 -229.23137394771175 24 -229.23137394771175 28 -267.72116117165649 32 -267.72116117165649 - 36 -286.29993014077189 40 -290.06584483559186 45 -288.35220685767081; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 28.40171532491458 16 20.462833481289397 - 17 4.4236924775667426 24 4.4236924775667426 28 4.6769147619348068 32 4.6769147619348068 - 36 16.694846728567967 40 30.934385347355949 45 41.254733220814508; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 -1.0893063224582775 16 7.4246571938054409 - 17 18.253096229053455 24 18.253096229053455 28 18.749055268835804 32 18.749055268835804 - 36 20.484911908074046 40 14.698723110613262 45 -1.0893063224582775; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 33.892693033620276 16 61.056584871414856 - 17 43.34718215529864 24 43.34718215529864 28 43.34718215529864 32 43.34718215529864 - 36 92.668682959165807 40 147.45095890393804 45 129.5516037268701; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 54.671688625550239 16 -48.275981394864523 - 17 15.73443129033811 24 15.73443129033811 28 15.73443129033811 32 15.73443129033811 - 36 23.340335538886229 40 58.489650676729525 45 42.895523767144475; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 39.468648652835569 16 42.099155883550317 - 17 5.3123671240544006 24 5.3123671240544006 28 5.3123671240544006 32 5.3123671240544006 - 36 13.592652910979442 40 61.927997852063406 45 54.921697495561858; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 1 16 1 17 1 24 1 28 1 32 1 36 - 1 40 1 45 1; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 0.99999999999999989 16 0.99999999999999989 - 17 0.99999999999999989 24 0.99999999999999989 28 0.99999999999999989 32 0.99999999999999989 - 36 0.99999999999999989 40 0.99999999999999989 45 0.99999999999999989; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 15 0.99999999999999978 16 0.99999999999999978 - 17 0.99999999999999978 24 0.99999999999999978 28 0.99999999999999978 32 0.99999999999999978 - 36 0.99999999999999978 40 0.99999999999999978 45 0.99999999999999978; - setAttr -s 9 ".kit[2:8]" 3 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 3 3 3 3 9 9 9; -select -ne :time1; - setAttr ".o" 10; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339262 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds"; -select -ne IMP_effector4; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds"; -select -ne IMP_effector3; -select -ne IMP_Hips; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; -select -ne IMP_Rhand_IK; -select -ne IMP_Lhand_IK; -select -ne IMP_LIK; -select -ne IMP_RIK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".IK"; - setAttr -k on ".FIST"; - setAttr -k on ".NEUTRAL"; - setAttr -k on ".SPREAD"; - setAttr -k on ".FLAT"; -select -ne IMP_RHAND_ROT; - setAttr -k on ".IK"; - setAttr -k on ".Flat"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of evade_right.ma diff --git a/base/models/monsters/imp/animation/cycles/evade_right_on4.ma b/base/models/monsters/imp/animation/cycles/evade_right_on4.ma deleted file mode 100644 index 2b2f8e168..000000000 --- a/base/models/monsters/imp/animation/cycles/evade_right_on4.ma +++ /dev/null @@ -1,3522 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:16 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: evade_right_on4.ma -//Last modified: Mon, Mar 11, 2002 12:07:19 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models/monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" -36.708244961240176 248.85578626218432 85.523956670379803 ; - setAttr ".r" -type "double3" -67.530108918382709 -3695.3999999999119 5.0888874903416268e-014 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 269.12582418624578; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 80.204115004634218 28.805043590971543 66.957987037023315 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 76.66589438746432 21.396720735023585 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 60.115549445093862; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111795 7.8084980196880238 122.14600941808962 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 238.83255290169387; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 24 -ast 1 -aet 24 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 5 1 8 1 11 1 15 1 17 1 20 1 - 24 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -10.257394651041173 5 -13.711240201914212 - 8 -39.301095874291647 11 -73.421592650918427 15 -108.94705105952399 17 -117.4212099079374 - 20 -121.39099694276437 24 -121.39099694276437; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 21.681999630647688 5 19.129504779363465 - 8 34.444473887068796 11 33.049736625708469 15 17.81741059764569 17 17.506624367936844 - 20 21.391452239297401 24 21.391452239297401; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 53.227781741534002 5 53.227781741534002 - 8 53.227781741534002 11 53.227781741534002 15 53.227781741534002 17 53.227781741534002 - 20 53.227781741534002 24 53.227781741534002; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 79.752987820342497 5 79.752987820342497 - 8 79.752987820342497 11 70.382763445707056 15 60.550943296857113 17 78.086487805062163 - 20 68.397485559748958 24 70.158065532583052; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 6.9857884984286871 5 6.9857884984286871 - 8 6.9857884984286871 11 3.0072049973966433 15 11.773550776271001 17 3.3934152759483123 - 20 -0.99090885294514897 24 -15.722099836591301; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 41.35815596170147 5 41.35815596170147 - 8 41.35815596170147 11 68.769014414717418 15 2.4354309147268673 17 23.097887314238889 - 20 51.218880796810843 24 36.253415047194032; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 5 1 8 1 11 1 15 1 17 1 20 1 - 24 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 5 1 8 1 11 1 15 1 17 1 20 1 - 24 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 5 1 8 1 11 1 15 1 17 1 20 1 - 24 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6 1 7 1 12 1 14 1 15 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 70.897464225582198 6 70.897464225582198 - 7 70.897464225582198 12 95.519042693076443 14 97.430227385079704 15 97.430227385079704; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 3.2712897606351277 6 3.2712897606351277 - 7 3.2712897606351277 12 16.139348577234678 14 6.7168832728223276 15 3.8593201811273836; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 17.819650345705028 6 17.819650345705028 - 7 17.819650345705028 12 107.24458114759318 14 156.47889541416967 15 161.75439650652956; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 47.926788216705674 6 47.926788216705674 - 7 47.926788216705674 12 151.14215408228196 14 47.926788216705674 15 47.926788216705674; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 60.562683961022834 6 60.562683961022834 - 7 60.562683961022834 12 74.061884998035652 14 60.562683961022834 15 60.562683961022834; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 379.52938672271426 6 379.52938672271426 - 7 379.52938672271426 12 430.81766516115317 14 379.52938672271426 15 379.52938672271426; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6 1 7 1 12 1 14 1 15 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.99999999999999978 6 0.99999999999999978 - 7 0.99999999999999978 12 0.99999999999999978 14 0.99999999999999978 15 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6 1 7 1 12 1 14 1 15 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 12 1 16 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 80.066896075585134 6 80.066896075585134 - 12 73.942251432467771 16 80.066896075585106; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.9380007991706787 6 3.9380007991706787 - 12 23.305784258541383 16 4.8962919382919274; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -17.909945588977081 6 -17.909945588977081 - 12 69.841534024783044 16 124.71360209560586; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -145.5461118496099 6 -145.5461118496099 - 12 -145.5461118496099 16 -145.5461118496099; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 44.064065416125516 6 44.064065416125516 - 12 44.064065416125516 16 44.064065416125516; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -192.55645467766422 6 -192.55645467766422 - 12 -192.55645467766422 16 -192.55645467766422; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 12 1 16 1; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 6 0.99999999999999989 - 12 0.99999999999999989 16 0.99999999999999989; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999978 6 0.99999999999999978 - 12 0.99999999999999978 16 0.99999999999999978; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 11 1 13 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -7.392405718350501 8 -7.392405718350501 - 11 -90.282055242638393 13 -118.73671104948349; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.207994295172762 8 1.207994295172762 - 11 15.311606303782971 13 0.46569892629855225; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 36.754381567957459 8 36.754381567957459 - 11 36.754381567957424 13 36.754381567957424; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.4372903291937864 8 3.4372903291937864 - 11 3.4372903291937864 13 3.4372903291937864; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -46.578931290797854 8 -46.578931290797854 - 11 -46.578931290797854 13 -46.578931290797854; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -5.1476086226841948 8 -5.1476086226841948 - 11 -5.1476086226841948 13 -5.1476086226841948; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 11 1 13 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 11 1 13 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 11 1 13 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 1 11 1 14 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 7.1689522478599548 11 -53.94669978945084 - 14 -97.247262973780295; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 0 11 12.866453060486485 14 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 37.961325025704973 11 37.961325025704973 - 14 37.961325025704973; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 -174.49049195404214 11 -253.35989456252619 - 14 -174.49049195404214; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 129.78625356110399 11 145.59064814497023 - 14 129.78625356110399; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 -169.93906815090079 11 -257.25001545368173 - 14 -169.93906815090079; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 1 11 1 14 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 1 11 1 14 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 7 1 11 1 14 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 8 1 13 1 17 1 20 1 24 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -101.9398414115052 5 -109.61427926971746 - 8 -131.60181020630517 13 -146.7261989959492 17 -135.52723873319516 20 -135.9004550577132 - 24 -153.98749123166127; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.394371741366072 5 38.26576308313841 - 8 5.2747624587317681 13 53.005924714186371 17 47.89491595426118 20 45.464115421292156 - 24 37.652284178867312; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -11.517195461058266 5 -28.898295577134391 - 8 -6.1129009337406002 13 -65.356232441561005 17 -31.97735539195649 20 -43.760969339079224 - 24 -61.430067750541625; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 5 0.52893863520222695 - 8 0.52893863520222695 13 0.52893863520222695 17 0.52893863520222695 20 0.52893863520222695 - 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 5 0.52893863520222695 - 8 0.52893863520222695 13 0.52893863520222695 17 0.52893863520222695 20 0.52893863520222695 - 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 5 0.52893863520222695 - 8 0.52893863520222695 13 0.52893863520222695 17 0.52893863520222695 20 0.52893863520222695 - 24 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 11 1 14 1 18 1 24 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 140.83562241632796 7 83.667606362009593 - 11 46.96586164936538 14 -52.939007570804471 18 3.2562034655028462 24 67.660084859355194; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 80.125836085899181 7 70.750625527851341 - 11 68.352192308410068 14 65.698342248318326 18 88.98429970034222 24 40.676156771167484; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 66.108980440622702 7 3.1000829158710292 - 11 -53.227695322299596 14 -138.7517287585257 18 -59.31641985021944 24 -20.205032077673156; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.5814880999021691 7 0.5814880999021691 - 11 0.5814880999021691 14 0.5814880999021691 18 0.5814880999021691 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.5814880999021691 7 0.5814880999021691 - 11 0.5814880999021691 14 0.5814880999021691 18 0.5814880999021691 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.5814880999021691 7 0.5814880999021691 - 11 0.5814880999021691 14 0.5814880999021691 18 0.5814880999021691 24 0.5814880999021691; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 14 1 24 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8 0 14 0 24 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.3128351505039433 8 2.3128351505039433 - 14 2.3128351505039433 24 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.23421866920666501 8 0.23421866920666501 - 14 0.23421866920666501 24 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 40.728736411742872 8 60.838085026852497 - 14 48.12002723340386 24 37.315675009367183; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -37.00452856756916 8 -26.790467775090715 - 14 -30.978364268694595 24 -26.695378496473804; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -18.743583249686989 8 -37.7929405165332 - 14 -15.477421707056619 24 -39.020796450401441; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 14 1 24 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 14 1 24 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8 1 14 1 24 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 10 1 14 1 18 1 21 1 24 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 10 0 14 0 18 0 21 0 24 - 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.6456615572060826 8 2.6456615572060826 - 10 2.6456615572060826 14 2.6456615572060826 18 2.6456615572060826 21 2.6456615572060826 - 24 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.9935618776130362 8 1.9935618776130362 - 10 1.9935618776130362 14 1.9935618776130362 18 1.9935618776130362 21 1.9935618776130362 - 24 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -33.760436965417369 8 -16.42564419994897 - 10 14.837012606338414 14 -49.169464871087222 18 -17.391114929918906 21 -38.856526008307952 - 24 -38.856526008307952; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 26.662692484676995 10 20.475444586198606 - 14 20.953763244931881 18 12.099013087476216 21 5.527344385301677 24 5.527344385301677; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 18.246880713952525 10 -5.5359899245973549 - 14 2.6722875253197977 18 -11.790684578396359 21 -18.362980318959082 24 -18.362980318959082; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 10 1 14 1 18 1 21 1 24 - 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 10 1 14 1 18 1 21 1 24 - 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 10 1 14 1 18 1 21 1 24 - 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 20 1 24 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 16 0 20 0 24 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 5.6268319407172029 16 5.6268319407172029 - 20 5.6268319407172029 24 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -2.1098668596606802 16 -2.1098668596606802 - 20 -2.1098668596606802 24 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -25.200000000000212 16 -44.696929289869928 - 20 -22.325455407893244 24 -25.503886534340776; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 16 26.684389155858408 20 -8.8414088646753743 - 24 4.118274147859232; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 16 -6.2525518417550012 20 - 3.7383043845217774 24 -5.3460649716280528; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 20 1 24 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 20 1 24 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 20 1 24 1; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 13 1 15 1; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15 1 16 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 5 1 9 1 13 1 21 1 24 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 5 0 9 0 13 0 21 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 5 0 9 0 13 0 21 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 5 0 9 0 13 0 21 0 24 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 5 1 9 1 13 1 21 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 5 1 9 1 13 1 21 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 5 1 9 1 13 1 21 1 24 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.27427147149852044 5 0.27427147149852044 - 9 0.27427147149852044 13 0.27427147149852044 21 0.27427147149852044 24 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -1.1074984126668126 5 -1.1074984126668126 - 9 -1.1074984126668126 13 -1.1074984126668126 21 -1.1074984126668126 24 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -1.642626684874722 5 -1.642626684874722 - 9 -1.642626684874722 13 -1.642626684874722 21 -1.642626684874722 24 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 5 0 9 0 13 0 21 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 5 0 9 0 13 0 21 0 24 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -73.338597776745374 5 -73.338597776745374 - 9 -53.858032742297382 13 -110.00789666511805 21 -71.046766596222071 24 -71.046766596222071; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6 1 11 1 14 1 24 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6 0 11 0 14 0 24 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6 0 11 0 14 0 24 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6 0 11 0 14 0 24 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6 1 11 1 14 1 24 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6 1 11 1 14 1 24 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6 1 11 1 14 1 24 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.2742786288673521 6 -0.2742786288673521 - 11 -0.2742786288673521 14 -0.2742786288673521 24 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -1.1075115373407667 6 -1.1075115373407667 - 11 -1.1075115373407667 14 -1.1075115373407667 24 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -1.6426166407301896 6 -1.6426166407301896 - 11 -1.6426166407301896 14 -1.6426166407301896 24 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6 0 11 0 14 0 24 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6 0 11 0 14 0 24 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 65.317188644913855 6 65.317188644913855 - 11 65.317188644913855 14 34.377467707849398 24 46.982539200727508; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 1 19 1 24 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 0 19 0 24 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 5.7384771804188404 19 5.7384771804188404 - 24 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 2.0494561358638701 19 2.0494561358638701 - 24 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 0 19 -46.177456689271374 24 - -46.177456689271374; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 0 19 11.352206308347323 24 11.352206308347323; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 0 19 16.03124533733682 24 16.03124533733682; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 1 19 1 24 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 1 19 1 24 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 12 1 19 1 24 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 15 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 15 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 15 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 15 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 77.739160914831501 15 77.739160914831501; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -76.726154744596627 15 -76.726154744596627; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -173.86213662459591 15 -173.86213662459591; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 15 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 15 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 15 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 15 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 15 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 15 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 15 1; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 15 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 1 16 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 -2.5294371750177831 16 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 13.481673551673362 16 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 -0.26635088939205875 16 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 141.20709981379272 16 141.20709981379272; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 64.064019952206479 16 64.064019952206479; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 252.95011708695623 16 252.95011708695623; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 15.445123296459185 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 15 0 16 0; -select -ne :time1; - setAttr ".o" 8; -select -ne :renderPartition; - setAttr -s 10 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 10 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_Rwing_meshShape3Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig5; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape5Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933642 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".t" -type "double3" 6.7758528420198658 0 0 ; - setAttr ".r" -type "double3" -61.864687108561675 3.2695897469829776 -6.9162979482121454 ; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 13.810902907327028 -2.1355365310635326e-015 - -3.9488837846571188 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_LIK; - setAttr ".r" -type "double3" 147.27534424644941 87.000055140219231 -156.0818969756412 ; - setAttr ".twi" 0; -select -ne IMP_RIK; - setAttr ".r" -type "double3" 149.94545168528418 71.592719744457327 85.696896394004312 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FLAT"; -select -ne IMP_RHAND_ROT; - setAttr -k on ".Fist"; - setAttr -k on ".NEUTRAL"; - setAttr -k on ".SPREAD"; - setAttr -k on ".Flat"; - setAttr -k on ".PIVOT"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of evade_right_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/faster_walk.ma b/base/models/monsters/imp/animation/cycles/faster_walk.ma deleted file mode 100644 index 428bc8d1a..000000000 --- a/base/models/monsters/imp/animation/cycles/faster_walk.ma +++ /dev/null @@ -1,5119 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:23 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: faster_walk.ma -//Last modified: Tue, Mar 05, 2002 01:37:50 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 12.684157521845801 63.831465349298178 288.05649768819018 ; - setAttr ".r" -type "double3" -8.1301089134393294 -715.79999999997347 9.9659972922832434e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 187.6851720013949; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -10.650735381098212 59.295549680729671 8.9281548195491052 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" -3.5473018837574113 117.71913367126459 31.995626876928817 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 75.845993495743997; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 6.3303333839252574 35.629877806451418 220.67478433882468 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 154.38679635451356; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 110.32325451487078 48.561044814200933 111.49210537271142 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 294.96878890016455; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 5.157268050779404 43.723772604318889 -2.5230565692280926 ; - setAttr ".sp" -type "double3" 5.157268050779404 43.723772604318889 -2.5230565692280926 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode brush -n "brush1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 1 1 1 2 1 7 1 12 1 14 1 20 - 1 25 1 27 1 37 1; - setAttr -s 10 ".kot[0:9]" 5 9 5 9 9 9 9 - 9 9 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 -5.6843418860808042e-015 1 - 0 2 0 7 0 12 0 14 0 20 -1.1368683772161604e-014 25 -2.2737367544323207e-014 - 27 -2.2737367544323207e-014 37 0; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -7 40.086469901054748 4 35.896501771048037 - 5 37.256241022323422 10 43.141692018137256 15 37.124516947029896 17 36.07321372829405 - 23 43.141692018137213 28 37.32124624578725 30 35.896501771048037 40 38.394456442510076; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 -41.125124238045991 1 -2.824937990121533 - 2 -0.31070995818191305 7 20.677752323607063 12 41.706475235890508 14 45.770850252550318 - 20 69.980388395263205 25 90.478975435808366 27 94.89060727030261 37 135.3801885253111; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 1 1 1 2 1 7 1 12 1 14 1 20 - 1 25 1 27 1 37 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 1 1 1 2 1 7 1 12 1 14 1 20 - 1 25 1 27 1 37 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -10 1 1 1 2 1 7 1 12 1 14 1 20 - 1 25 1 27 1 37 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 12 1 13 1 27 1 37 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 3.6743555252464164 1 3.6743555252464377 - 7 3.6743555252464271 12 3.6743555252464164 13 3.6743555252464164 27 3.6743555252464164 - 37 3.6743555252464049; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0.36007121149764132 1 -0.34677661748667798 - 7 15.380587577414429 12 0.36007121149764132 13 0.36007121149764132 27 0.36007121149764132 - 37 17.805786318718539; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -34.884704416485064 1 -34.356698919460719 - 7 9.6445784348131269 12 63.718437352113554 13 63.718437352113554 27 63.718437352113554 - 37 108.54423311372283; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -0.1598739788580984 1 2.2716906196567397 - 7 -34.360426388667022 12 25.926093948270953 13 -0.1598739788580984 27 -0.1598739788580984 - 37 -59.040249377982953; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 35.775906649747775 1 35.77590664974776 - 7 35.77590664974776 12 35.775906649747775 13 35.775906649747775 27 35.775906649747775 - 37 35.775906649747775; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 6.873373609368449 1 6.8733736093684392 - 7 6.8733736093684383 12 6.8733736093684472 13 6.873373609368449 27 6.873373609368449 - 37 6.8733736093684676; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 12 1 13 1 27 1 37 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 12 1 13 1 27 1 37 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 12 1 13 1 27 1 37 - 1; - setAttr -s 7 ".kit[0:6]" 9 3 9 9 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 14 1 20 1 25 1 26 1 37 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -4.3324646448840198 1 -4.3324646448840145 - 14 -4.3324646448840145 20 -4.3324646448840261 25 -4.3324646448840491 26 -4.3324646448840491 - 37 -4.3324646448840145; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 7.710132089165632 1 0.58944344826701212 - 14 0.58944344826701212 20 14.903111985199478 25 1.1195793200052462 26 1.1195793200052462 - 37 0.58944344826701212; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -67.687208756627626 1 15.465685357884491 - 14 15.465685357884491 20 59.643674669404362 25 112.83397380047424 26 112.83397380047424 - 37 112.94833687911279; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -20.986200778437397 1 1.2642495235096893 - 14 1.2642495235096893 20 -39.721101051469908 25 27.044951041961923 26 -1.6826227392144211 - 37 1.2642495235096893; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -23.360356069512932 1 -23.360356069512921 - 14 -23.360356069512921 20 -23.360356069512932 25 -23.360356069512932 26 -23.360356069512939 - 37 -23.360356069512921; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 -10.103037396887252 1 -10.103037396887252 - 14 -10.103037396887252 20 -10.103037396887252 25 -10.103037396887236 26 -10.103037396887247 - 37 -10.103037396887252; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 14 1 20 1 25 1 26 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 14 1 20 1 25 1 26 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 14 1 20 1 25 1 26 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 1 1 1 12 1 20 1 25 1 37 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 6.7758528420198658 1 6.7758528420198658 - 12 6.7758528420198658 20 6.7758528420198658 25 6.7758528420198658 37 6.7758528420198658; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 -6.9388939039072284e-018 1 - -6.9388939039072284e-018 12 -6.9388939039072284e-018 20 -6.9388939039072284e-018 - 25 -6.9388939039072284e-018 37 -6.9388939039072284e-018; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 -9.5120444723942321e-016 1 - -9.5120444723942321e-016 12 -9.5120444723942321e-016 20 -9.5120444723942321e-016 - 25 -9.5120444723942321e-016 37 -9.5120444723942321e-016; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 2.5472317890722982 1 -41.976694058084021 - 7 0 12 0 20 0 25 -28.257292980906676 37 0.61057011086353752; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 9 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 0.366936566104546 1 0.366936566104546 - 12 0.366936566104546 20 0.366936566104546 25 0.36693656610454645 37 0.366936566104546; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 12.728045273286229 1 12.728045273286229 - 12 12.728045273286229 20 12.728045273286229 25 12.728045273286208 37 12.728045273286229; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 1 1 1 12 1 20 1 25 1 37 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 1 1 1 12 1 20 1 25 1 37 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" -10 1 1 1 12 1 20 1 25 1 37 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 1 9 1 14 1 20 1 37 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 6.7758528420198658 9 6.7758528420198658 - 14 6.7758528420198658 20 6.7758528420198658 37 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 -3.4694469519536142e-018 9 - 0 14 -6.9388939039072284e-018 20 0 37 -2.4424906541753442e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 -4.7560222361971161e-016 9 - 0 14 -9.5120444723942321e-016 20 0 37 -3.3482396542827689e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 -35.018897830542357 9 -12.784757077400341 - 14 -48.359382027098292 20 -12.784757077400341 37 -25.707239603296582; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 3.2695897469829864 9 3.2695897469829736 - 14 3.2695897469829993 20 3.2695897469829736 37 3.2695897469829829; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 -6.9162979482121454 9 -6.9162979482121409 - 14 -6.9162979482121507 20 -6.9162979482121409 37 -6.9162979482121454; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 1 9 1 14 1 20 1 37 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 1 9 1 14 1 20 1 37 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" -10 1 9 1 14 1 20 1 37 1; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 23.600487998008958 1 23.600487998008958 - 2 23.600487998008958 37 23.600487998008958; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 2 0 37 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 2 0 37 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 27 -ast 1 -aet 27 "; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; - setAttr -s 7 ".kot[1:6]" 5 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1.8461538440400267 1 0 7 -3 - 14 0 20 3 27 0 37 -1.6328773239939711; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -9 -35.182052601841725 1 -1.3228864214471787 - 4 7.0364105203683467 11 14.999999999999998 17 0 22 -14.999999999999998 27 - -1.3228864214471787 37 39.356805647428878; - setAttr -s 8 ".kit[2:7]" 1 9 9 9 9 9; - setAttr -s 8 ".kot[2:7]" 1 9 9 9 9 9; - setAttr -s 8 ".kix[2:7]" 0.65024280548095703 0.97524851560592651 - 0.65865468978881836 0.99846822023391724 0.5501396656036377 0.50613796710968018; - setAttr -s 8 ".kiy[2:7]" 0.75972646474838257 -0.22111169993877411 - -0.75244534015655518 -0.055328056216239929 0.83507263660430908 0.86245250701904297; - setAttr -s 8 ".kox[2:7]" 0.65024280548095703 0.97524851560592651 - 0.65865468978881836 0.99846822023391724 0.5501396656036377 0.50613796710968018; - setAttr -s 8 ".koy[2:7]" 0.75972646474838257 -0.22111169993877411 - -0.75244534015655518 -0.055328056216239929 0.83507263660430908 0.86245250701904297; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 9 9 9 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 2.3128351505039433 1 2.3128351505039433 - 7 2.3128351505039433 14 2.3128351505039433 20 2.3128351505039433 27 2.3128351505039433 - 37 2.3128351505039433; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0.23421866920666501 1 0.23421866920666501 - 7 0.23421866920666501 14 0.23421866920666501 20 0.23421866920666501 27 0.23421866920666501 - 37 0.23421866920666501; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -5 21.364179104477618 1 3.6029850746268708 - 7 23.602985074626861 14 3.6029850746268708 20 23.602985074626861 27 3.6029850746268708 - 33 22.370227579304654; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 7 0 14 0 20 0 27 0 37 - 0; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -4 -8.6918048200807281 1 -7.1137026800707206 - 5 0 11 14.999999999999998 18 0 22 -9.157210362119006 27 -7.1137026800707206 - 37 14.999999999999998; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 7 1 14 1 20 1 27 1 37 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 9; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -119.07714728137809 1 -119.07714728137809 - 27 -119.07714728137809 37 -119.07714728137809; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 48.416650877426726 1 48.416650877426726 - 27 48.416650877426726 37 48.416650877426726; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -86.607460853317946 1 -86.607460853317946 - 27 -86.607460853317946 37 -86.607460853317946; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -78.889985643448554 1 -78.889985643448554 - 27 -78.889985643448554 37 -78.889985643448554; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -13.246264962567121 1 -13.246264962567121 - 27 -13.246264962567121 37 -13.246264962567121; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -89.936433438042329 1 -89.936433438042329 - 27 -89.936433438042329 37 -89.936433438042329; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 1 1 1 7 1 10 1 14 1 20 1 23 - 1 27 1 37 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 0 1 0 7 0 10 0 14 0 20 0 23 - 0 27 0 37 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 2.6456615572060826 1 2.6456615572060826 - 7 2.6456615572060826 10 2.6456615572060826 14 2.6456615572060826 20 2.6456615572060826 - 23 2.6456615572060826 27 2.6456615572060826 37 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 1.9935618776130362 1 1.9935618776130362 - 7 1.9935618776130362 10 1.9935618776130362 14 1.9935618776130362 20 1.9935618776130362 - 23 1.9935618776130362 27 1.9935618776130362 37 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 -29.479035024077582 1 -23.693152361148933 - 7 -35.731531292359662 10 -45.006918225362483 14 -15.661118177195773 20 -43.239590421134672 - 23 -44.712838604107233 27 -23.693152361148933 37 -22.598573597529384; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 4.0768141353883358 1 0.55398927497563877 - 7 -7.7347794716882836 10 -7.9704522679985823 14 -2.4930277752993955 20 9.7521713463874313 - 23 15.455713477293854 27 0.55398927497563877 37 -6.42396442470256; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 -3.7123988281007385 1 1.8375833169844473 - 7 -8.7024861271338096 10 -16.685621088131612 14 -12.527970035809851 20 5.5370173928543096 - 23 4.3674225004005276 27 1.8375833169844473 37 -13.112545260029481; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 1 1 1 7 1 10 1 14 1 20 1 23 - 1 27 1 37 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 1 1 1 7 1 10 1 14 1 20 1 23 - 1 27 1 37 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -10 1 1 1 7 1 10 1 14 1 20 1 23 - 1 27 1 37 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 5.7384771804188404 1 5.7384771804188404 - 27 5.7384771804188404 37 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 2.0494561358638701 1 2.0494561358638701 - 27 2.0494561358638701 37 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 -21.710651858293986 1 -21.710651858293986 - 27 -21.710651858293986 37 -21.710651858293986; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 0 1 0 27 0 37 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -10 1 1 1 27 1 37 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 5 1 12 1 16 1 27 1 37 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 5 0 12 0 16 0 27 0 37 - 0; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 5 0 12 0 16 0 27 0 37 - 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 0 1 0 5 0 12 0 16 0 27 0 37 - 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 5 1 12 1 16 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 5 1 12 1 16 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -10 1 1 1 5 1 12 1 16 1 27 1 37 - 1; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 13.663320674475715 37 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 3.4694469519536142e-018 37 - 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -2.4865668606186692e-016 37 - -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 6.2353930143209828 37 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.58855436141337392 37 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.10942982456140288 37 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 13.663320674475715 37 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 3.4694469519536142e-018 37 - 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -2.4865668606186692e-016 37 - -2.4865668606186692e-016; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 6.2353930143209828 37 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.58855436141337392 37 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.10942982456140288 37 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 5.5258192723085173 37 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.1525507362789047 37 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.1924108426844384 37 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 6.3533140211779946 37 6.3533140211779946; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.74525677667777757 37 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.8072476834435935 37 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -3.9684923358091311 37 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 2.2916645882841449 37 2.2916645882841449; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.085679155728795 37 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.1537911794025533 37 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.6185070801020824 37 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 12.890532588149956 37 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.69008032694306476 37 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.645694319339265 37 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.08568 37 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.1537988160630093 37 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.6185075120832098 37 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -12.890500000000031 37 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.6900999999992341 37 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.6456900000000347 37 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -4.0846345617354372 37 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.282468147773308 37 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 7.7712681071056613 37 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.4264261331675518 37 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.3937238431314825 37 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 7.7712681071056613 37 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.0180767416209342 37 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.350740136846035 37 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 2.679538405939565 37 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -3.6380577235397413 37 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -5.9996743942435486 37 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -2.7995714837697929 37 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.60142623279023677 37 0.0021786876903948128; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 12.204902534508774 37 25.393570148895222; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 23.323871494868747 37 18.142153566221971; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 19.149140381761772 37 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.3756686479080088 37 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.21075234496274775 37 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 53.559066451080305 37 45.402355483242701; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.6897575879217771 37 0.58471181966348262; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.7015360618535791 37 3.9855215137577433; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 20.742856452934195 37 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.84893801560717619 37 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.16812918533366403 37 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 5.9175729778873523 37 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.85605761867933861 37 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.5874050102942485 37 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 2.9900427762468107 37 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.91245575548367119 37 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.39837671684541476 37 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 5.169754565364844 37 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.0564808409517294 37 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.42012489059707847 37 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.46895946313800008 37 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 3.744537024733662 37 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.043574269372096713 37 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.1287329396630019 37 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.85810195764911135 37 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.32542761684201271 37 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 3.8784880075680586 37 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -5.9996743942435486 37 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -2.7995714837697929 37 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -42.354965893391601 37 -33.944271030088423; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.028894978266546502 37 19.270755096834087; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 59.486602238419721 37 75.96484358326839; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 18.980231639280721 37 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.663797374263001 37 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.41525250862709329 37 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 46.187124588692967 37 49.719823997466847; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.35950722327966583 37 -0.38700473403488028; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -6.7663386033092356 37 -7.2838733188027858; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 20.799371406295553 37 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.32904719010364564 37 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.16941601589852961 37 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 6.1142991392184163 37 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.13638708324248117 37 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.0994349581901075 37 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 2.5124344559409741 37 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.5859239079718024 37 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.3423521551430217 37 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.6684103441767562 37 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.21264207246076725 37 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.3825986145063745 37 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.4623854590403933 37 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 3.8711962578925494 37 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.1098661950250604 37 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 4.9497075072661634 37 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.748040561262465 37 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -0.35737371225579673 37 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.67839399942384448 37 0.57317615434286473; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.30088797397781147 37 -0.38352861621642798; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.8572151218061679 37 -1.87733185575701; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.51347031355984363 37 0.53283476441238975; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.2516744696598314 37 -1.3363140344435747; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.4729763267262115 37 -1.3893710502180909; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -29.775800000000025 37 -29.775800000000025; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 57.582500000000032 37 57.582500000000032; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.0893083480314791 37 -1.0893083480314791; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 9.4749040322149245 37 9.4749040322149245; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -58.854902956455234 37 -58.854902956455234; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -8.3632933901642268 37 -8.3632933901642268; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.99999999999999978 37 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 29.775846152470962 37 29.775846152470962; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 57.582470209590937 37 57.582470209590937; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 -1.0893063224582775 37 -1.0893063224582775; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 33.892693033620276 37 33.892693033620276; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 54.671688625550239 37 54.671688625550239; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 39.468648652835569 37 39.468648652835569; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.99999999999999989 37 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0.99999999999999978 37 0.99999999999999978; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1 37 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 0 37 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.25 37 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.25 37 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" -10 1.25 37 1.25; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 546.78270526667472; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 76.960397338127308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 655.27786737025758; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.30000000000000004; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -74.7753782868716; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -49.578494055900329; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.8616814853366312; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.20000000000000001; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 12 1 20 1 27 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 4.5862437917087604 7 4.5862437917087604 - 12 4.5862437917087604 20 4.5862437917087604 27 4.5862437917087604; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.1192573708760238 7 2.1192573708760238 - 12 2.1192573708760238 20 2.1192573708760238 27 2.1192573708760238; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.0821078932592156 7 -3.0821078932592156 - 12 -3.0821078932592156 20 -3.0821078932592156 27 -3.0821078932592156; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 33.833507887598437 7 41.339343334391636 - 12 42.492127617052276 20 45.789921070629916 27 33.833507887598437; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 4.8712264543763144 7 9.1800304293202135 - 12 16.100468733726935 20 -16.844212192081354 27 4.8712264543763144; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -14.816960711377872 7 -21.898625378200059 - 12 -7.1305873595194731 20 -17.255046190103553 27 -14.816960711377872; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 12 1 20 1 27 1; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 12 1 20 1 27 1; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 12 1 20 1 27 1; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 11 1 20 1 27 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -5.1163481771664303 7 -5.1163481771664303 - 11 -5.1163481771664303 20 -5.1163481771664303 27 -5.1163481771664303; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.1192000000003057 7 2.1192000000003057 - 11 2.1192000000003057 20 2.1192000000003057 27 2.1192000000003057; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.0821100000000254 7 -3.0821100000000254 - 11 -3.0821100000000254 20 -3.0821100000000254 27 -3.0821100000000254; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 20.411921406039347 7 -3.8946091670189968 - 11 -11.514247283429711 20 33.696104212256273 27 20.411921406039347; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -10.261334385534996 7 24.289284796413273 - 11 10.903357984809865 20 5.7588181109745902 27 -10.261334385534996; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -34.390814768422921 7 -41.623807150567039 - 11 -46.964746804403177 20 -45.237250683529936 27 -34.390814768422921; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 11 1 20 1 27 1; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 11 1 20 1 27 1; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 11 1 20 1 27 1; - setAttr -s 5 ".kit[1:4]" 3 9 9 9; - setAttr -s 5 ".kot[1:4]" 3 9 9 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 27 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.412879749935719 27 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.7286993982861674 27 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.868763862603668 27 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 74.789032252040684 27 74.789032252040684; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 27 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 27 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 27 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 27 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 27 1; -select -ne :time1; - setAttr ".o" 18; -select -ne :renderPartition; - setAttr -s 10 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 10 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -parent -s -nc -r "IMP_Rwing_mesh3" "group1"; -parent -s -nc -r "IMP_Rwing_mesh4" "group1"; -parent -s -nc -r "IMP_Lwing_mesh3" "group1"; -parent -s -nc -r "IMP_Lwing_mesh4" "group1"; -parent -s -nc -r "IMP_polySurface1" "group1"; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339262 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 66.223080698633211 0 0 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of faster_walk.ma diff --git a/base/models/monsters/imp/animation/cycles/fireball_sight.ma b/base/models/monsters/imp/animation/cycles/fireball_sight.ma deleted file mode 100644 index 236488701..000000000 --- a/base/models/monsters/imp/animation/cycles/fireball_sight.ma +++ /dev/null @@ -1,3560 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:18 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: fireball_sight.ma -//Last modified: Thu, Jun 12, 2003 10:48:19 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 241.76400946183819 30.873367884408811 -3.2175017530603043 ; - setAttr ".r" -type "double3" 0.86989108496551348 -988.60000000019909 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 228.12368588918991; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -6.9316948918523984 59.305906725678959 -4.7946797848537992 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0.29568055424639472 100 -0.14784027712319636 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 178.29537421057617; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 37.571909435650774 34.82387541167617 127.09388547702065 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 219.13258766383063; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 127.11916103066812 19.851472725958565 1.6259490563075989 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 259.16343835317059; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" 88.590374758182563 -1.4210854715202004e-014 - 91.573349781690126 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; -createNode transform -n "group2"; - setAttr ".t" -type "double3" -121.6853497728795 136.16005447072979 -192.57631437792818 ; - setAttr ".rp" -type "double3" 88.590374758182563 -1.4210854715202004e-014 - 91.573349781690126 ; - setAttr ".sp" -type "double3" 88.590374758182563 -1.4210854715202004e-014 - 91.573349781690126 ; -createNode transform -n "pointLight2" -p "group2"; - setAttr ".t" -type "double3" 88.590374758182563 -1.4210854715202004e-014 - 91.573349781690126 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + " global int $gUseScenePanelConfig;\n" - + " int $useSceneConfig = $gUseScenePanelConfig;\n" - + " int $menusOkayInPanels = `optionVar -q allowMenusInPanels`; int $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + " int $nPanes = 0;\n" - + " string $editorName;\n" - + " string $panelName;\n" - + " string $itemFilterName;\n" - + " string $panelConfig;\n" - + " //\n" - + " // get current state of the UI\n" - + " //\n" - + " sceneUIReplacement -update $gMainPane;\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " outlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " outlinerPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " blendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " blendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " devicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " devicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + " panelConfiguration -edit -label \"Current Layout\"\n" - + " -defaultImage \"\"\n" - + " -image \"\"\n" - + " -sc false\n" - + " -configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + " -removeAllPanels\n" - + " -ap false\n" - + " \"Side View\"\n" - + " \"modelPanel\"\n" - + " \"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " \"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " $configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + " }\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 45 -ast 1 -aet 45 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 18 1 30 1 34 1 38 1 41 - 1 45 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.9351316984681297 8 0.91731839574265939 - 18 0.97413980566454927 30 -1.4282385205699499 34 -1.4282385205699499 38 -6.566745922466402 - 41 -2.7077750243854894 45 4.8623314944728655; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 40.804255806723305 8 29.124005518721248 - 18 34.096447225666665 30 40.788883351735599 34 40.468005859122286 38 39.252215977022956 - 41 36.148220195862706 45 36.701135930062001; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.0672187280711443 8 2.1097422081330039 - 18 1.6902599999466696 30 -8.1779183618980849 34 -8.1779183618981062 38 16.922556785826949 - 41 33.018362946928086 45 57.869270470143888; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 23.215089789075556 8 0 18 0 30 - 0 34 -33.950383810889072 38 37.461608016634102 41 26.178509984420071 45 -9.2510636298403259; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 12.318822891794072 8 0 18 0 30 - 0 34 -23.056938717746196 38 36.886995769308108 41 38.275393167085809 45 26.428932776604245; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 11.401002963902446 8 7.4260738755503946 - 18 7.4260738755503946 30 7.4260738755503946 34 18.385962308731834 38 40.365492896559651 - 41 23.37707298169812 45 -9.7976138758408862; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 18 1 30 1 34 1 38 1 41 - 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 18 1 30 1 34 1 38 1 41 - 1 45 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 18 1 30 1 34 1 38 1 41 - 1 45 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8 1 18 1 30 1 34 1 35 1 36 - 1 37 1 42 1 45 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -5.0348979650608028 8 -5.0348979650608028 - 18 -5.0348979650608028 30 -6.2199817008084626 34 -6.2199817008084626 35 -6.2199817008084626 - 36 -6.2199817008084626 37 -6.2199817008084626 42 -6.2199817008084626 45 -6.2199817008084626; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.1192000000002627 8 2.1192000000002627 - 18 2.1192000000002627 30 2.1277580611321651 34 2.1277580611321651 35 2.1277580611321651 - 36 2.1277580611321651 37 2.1277580611321651 42 2.1277580611321651 45 2.1277580611321651; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.0821100000000254 8 -3.0821100000000254 - 18 -3.0821100000000254 30 -2.7324520154531551 34 -2.7324520154531551 35 -2.7324520154531551 - 36 -2.7324520154531551 37 -2.7324520154531551 42 -2.7324520154531551 45 -2.7324520154531551; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 31.940321307213264 8 65.038381239716927 - 18 47.064631447682991 30 58.290886048096787 34 32.218539720631931 35 -62.585510531818379 - 36 -33.413183135026713 37 -57.095826891097886 42 49.629941562279662 45 15.107458549102834; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -2.2052652861200825 8 18.501734974366343 - 18 18.50173497436635 30 18.50173497436635 34 58.985277509087467 35 49.084219351307091 - 36 -30.875837333431615 37 -36.210870973157071 42 -58.844870484978266 45 4.103209984633458; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -34.707867610792576 8 13.567778760137189 - 18 13.567778760137205 30 13.567778760137205 34 73.059431526716182 35 -73.908333429412579 - 36 -106.54743722915313 37 -70.676105745184444 42 -108.6469697694076 45 -45.940926821855051; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8 1 18 1 30 1 34 1 35 1 36 - 1 37 1 42 1 45 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8 1 18 1 30 1 34 1 35 1 36 - 1 37 1 42 1 45 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8 1 18 1 30 1 34 1 35 1 36 - 1 37 1 42 1 45 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 5 1 12 1 21 1 30 1 33 1 34 - 1 35 1 36 1 41 1 45 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -12.41287000000041 5 -12.41287000000041 - 12 -12.41287000000041 21 -12.41287000000041 30 -12.41287000000041 33 -12.41287000000041 - 34 -12.41287000000041 35 -12.41287000000041 36 -12.41287000000041 41 -12.41287000000041 - 45 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -6.7285999999993047 5 -6.7285999999993047 - 12 -6.7285999999993047 21 -6.7285999999993047 30 -6.7285999999993047 33 -6.7285999999993047 - 34 -6.7285999999993047 35 -6.7285999999993047 36 -6.7285999999993047 41 -6.7285999999993047 - 45 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -3.8687599999999316 5 -3.8687599999999316 - 12 -3.8687599999999316 21 -3.8687599999999316 30 -3.8687599999999316 33 -3.8687599999999316 - 34 -3.8687599999999316 35 -3.8687599999999316 36 -3.8687599999999316 41 -3.8687599999999316 - 45 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 57.961586471209856 5 81.110228589443906 - 12 30.834497008980886 21 65.998076874258572 30 61.738862630859551 33 87.00506772841986 - 34 72.789443705735181 35 38.213418653841728 36 -25.494937967944303 41 69.441223577296228 - 45 57.222418398392762; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -5.2887853607791371 5 -11.44087308691792 - 12 25.641717791411043 21 5.9224858482368701 30 1.1172810544475298 33 1.1172810544475309 - 34 1.1172810544475322 35 1.1172810544475349 36 1.1172810544475373 41 1.1172810544475396 - 45 1.1172810544475396; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 14.583763310498302 5 9.0419279874758853 - 12 0 21 7.4903693424533149 30 0.44561393551996281 33 0.44561393551996242 - 34 0.44561393551996087 35 0.44561393551996087 36 0.44561393551996076 41 0.44561393551995943 - 45 0.44561393551995954; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 5 1 12 1 21 1 30 1 33 1 34 - 1 35 1 36 1 41 1 45 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 5 1 12 1 21 1 30 1 33 1 34 - 1 35 1 36 1 41 1 45 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 5 1 12 1 21 1 30 1 33 1 34 - 1 35 1 36 1 41 1 45 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8 1 10 1 20 1 30 1 34 1 35 - 1 36 1 37 1 42 1 45 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -7.5406347832540632e-013 8 -7.5406347832540632e-013 - 10 -7.5406347832540632e-013 20 0 30 -7.5406347832540632e-013 34 -7.5406347832540632e-013 - 35 -7.5406347832540632e-013 36 -7.5406347832540632e-013 37 -7.5406347832540632e-013 - 42 -7.5406347832540632e-013 45 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 13.71946295727715 8 13.71946295727715 - 10 13.71946295727715 20 13.71946295727715 30 13.71946295727715 34 13.71946295727715 - 35 13.71946295727715 36 13.71946295727715 37 13.71946295727715 42 13.71946295727715 - 45 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -3.0908609005564358e-013 8 -3.0908609005564358e-013 - 10 -3.0908609005564358e-013 20 0 30 -3.0908609005564358e-013 34 -3.0908609005564358e-013 - 35 -3.0908609005564358e-013 36 -3.0908609005564358e-013 37 -3.0908609005564358e-013 - 42 -3.0908609005564358e-013 45 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -48.569547311799454 8 -69.560191178009234 - 10 -63.492804161352758 20 -74.874224959295631 30 -73.999855483301502 34 -73.990528875785742 - 35 -122.10677743663402 36 -4.4504900431748959 37 -62.722447845877966 42 -105.62610775474525 - 45 -38.975401645017975; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -32.889753356806992 8 -37.384523867019041 - 10 -38.027731475280135 20 -42.322423011138909 30 -48.746762782396459 34 -48.815289072588072 - 35 -44.84917231799686 36 -60.189492034373409 37 -80.203703397900426 42 -12.774050064366868 - 45 -75.369123770413069; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 26.977971776757382 8 -33.43338141634856 - 10 -16.454575415663374 20 -49.765917915844696 30 -10.471962981770419 34 -10.052827480285586 - 35 -4.4820601772528681 36 -114.95229793006214 37 -61.044282212554577 42 36.319928956575247 - 45 -83.583544167075559; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 15.445123296459183 8 15.445123296459183 - 10 15.445123296459183 20 15.445123296459183 30 15.445123296459183 34 15.445123296459183 - 35 15.445123296459183 36 15.445123296459183 37 15.445123296459183 42 15.445123296459183 - 45 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 15.445123296459185 8 15.445123296459185 - 10 15.445123296459185 20 15.445123296459185 30 15.445123296459185 34 15.445123296459185 - 35 15.445123296459185 36 15.445123296459185 37 15.445123296459185 42 15.445123296459185 - 45 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 15.445123296459181 8 15.445123296459181 - 10 15.445123296459181 20 15.445123296459181 30 15.445123296459181 34 15.445123296459181 - 35 15.445123296459181 36 15.445123296459181 37 15.445123296459181 42 15.445123296459181 - 45 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 10 0 20 0 30 0 34 0 35 - 0 36 0 37 0 42 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.60000000000000009 8 0.30000000000000004 - 10 0.2279871636900575 20 0 30 0 34 0 35 0 36 -0.012500000448031311 37 0 42 - 0.30859375159899038 45 0.5; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 10 0 20 0 30 0 34 0 35 - 0 36 0 37 0 42 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 10 0 20 0 30 0 34 -0.09142856801650967 - 35 0 36 0.59095238824114849 37 1 42 0.41672247430549136 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 10 0 20 0 30 0 34 0 35 - 0 36 0 37 0 42 0 45 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 10 0 20 0 30 0 34 0 35 - 0 36 0 37 0 42 0 45 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 25 1 34 1 38 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 18 0 25 0 34 0 38 0 45 - 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 8 5.6268319407172029 - 18 5.6268319407172029 25 5.6268319407172029 34 5.6268319407172029 38 5.6268319407172029 - 45 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 8 -2.1098668596606802 - 18 -2.1098668596606802 25 -2.1098668596606802 34 -2.1098668596606802 38 -2.1098668596606802 - 45 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 388.51728050493159 8 380.4969630522524 - 18 380.4969630522524 25 369.86665109620941 34 349.72579507479213 38 358.24745809430311 - 45 387.46016934156279; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.9499348899011157 8 -26.897824913597933 - 18 -26.897824913597933 25 -20.663115375305324 34 -51.557478907796501 38 -22.262188592102795 - 45 -23.624537036180595; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -10.43966184801843 8 -14.64190619217311 - 18 -14.64190619217311 25 -9.2091045431301524 34 -5.1626671971276155 38 11.543087366789198 - 45 4.0767414247465963; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 25 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 25 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 25 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 13 1 21 1 25 1 30 1 - 36 1 42 1 45 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 5 0 8 0 13 0 21 0 25 0 30 0 - 36 0 42 0 45 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 5 2.6456615572060826 - 8 2.6456615572060826 13 2.6456615572060826 21 2.6456615572060826 25 2.6456615572060826 - 30 2.6456615572060826 36 2.6456615572060826 42 2.6456615572060826 45 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 5 1.9935618776130362 - 8 1.9935618776130362 13 1.9935618776130362 21 1.9935618776130362 25 1.9935618776130362 - 30 1.9935618776130362 36 1.9935618776130362 42 1.9935618776130362 45 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -76.327548081948208 5 -85.883935007724929 - 8 -56.852671545437737 13 -51.449887235299663 21 -75.5667390637323 25 -68.342647021412475 - 30 -18.523939320156298 36 -71.504758111902902 42 -24.200136315501474 45 -48.353330840478058; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -13.611888470041892 5 18.243263805755607 - 8 24.782068079513845 13 31.486339613760748 21 33.149405017427782 25 11.452098302165654 - 30 36.610264797691158 36 11.270554481019648 42 13.158886505184897 45 -2.207125664438248; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.7155314437783642 5 9.8360642051169975 - 8 -0.32864929394781528 13 28.778656200772364 21 -7.7875513794450066 25 13.938645210195018 - 30 7.0314972256006714 36 -23.683658851335913 42 5.1604918840587715 45 -11.265086184671198; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 13 1 21 1 25 1 30 1 - 36 1 42 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 13 1 21 1 25 1 30 1 - 36 1 42 1 45 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 13 1 21 1 25 1 30 1 - 36 1 42 1 45 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 8 1 18 1 27 1 33 1 36 1 - 41 1 45 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 0 8 0 18 0 27 0 33 0 36 0 - 41 0 45 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.74525677667777757 4 0.74525677667777757 - 8 0.74525677667777757 18 0.74525677667777757 27 0.74525677667777757 33 0.74525677667777757 - 36 0.74525677667777757 41 0.74525677667777757 45 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.8072476834435935 4 1.8072476834435935 - 8 1.8072476834435935 18 1.8072476834435935 27 1.8072476834435935 33 1.8072476834435935 - 36 1.8072476834435935 41 1.8072476834435935 45 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.2846953468686371 4 46.232685014389354 - 8 26.878413316899401 18 36.119327588086598 27 23.989525394254262 33 3.0678269290393638 - 36 40.6279891307044 41 -5.0920108692945218 45 -5.0920108692945218; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 0 8 0.90924276228525258 18 - 0 27 0 33 0 36 0 41 0 45 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 0 8 1.0063211988043246 18 - 0 27 0 33 0 36 0 41 0 45 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 8 1 18 1 27 1 33 1 36 1 - 41 1 45 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 8 1 18 1 27 1 33 1 36 1 - 41 1 45 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 8 1 18 1 27 1 33 1 36 1 - 41 1 45 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 30 1 34 1 38 1 45 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 4.8522027930141798 8 4.8522027930141798 - 18 4.8522027930141798 30 4.8522027930141798 34 4.8522027930141798 38 4.8522027930141798 - 45 4.8522027930141798; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.1192573708759381 8 2.1192573708759381 - 18 2.1192573708759381 30 2.1192573708759381 34 2.1192573708759381 38 2.1192573708759381 - 45 2.1192573708759381; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821078932592165 8 -3.0821078932592165 - 18 -3.0821078932592165 30 -3.0821078932592165 34 -3.0821078932592165 38 -3.0821078932592165 - 45 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 51.486523353806625 8 -1.3442983168949751 - 18 -21.015583313530914 30 30.458693343477311 34 30.458693343477311 38 -35.371710065831074 - 45 22.833740088130437; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.031818642264513 8 -22.973142628990303 - 18 8.6817658064403975 30 -5.9410051207909653 34 -5.9410051207909653 38 -16.96600986389392 - 45 -10.630585580132509; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 16.6797554034653 8 -13.139526269139402 - 18 -39.816984296489842 30 -0.34575463937104267 34 -0.34575463937104267 38 - -31.937929080393381 45 -19.356856565374102; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 30 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 30 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 18 1 30 1 34 1 38 1 45 - 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8 1 18 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 12.412879749935719 8 12.412879749935719 - 18 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.7286993982861674 8 -6.7286993982861674 - 18 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.868763862603668 8 -3.868763862603668 - 18 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 65.952802270811603 8 70.580773385849568 - 18 70.580773385849568; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.1449149634462352 8 0 18 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 37.222210667095659 8 0 18 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8 1 18 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8 1 18 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8 1 18 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 13 1 23 1 30 1 34 1 37 - 1 45 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.5294371750177831 8 -2.5294371750177831 - 13 -2.5294371750177831 23 -2.5294371750177831 30 -2.5294371750177831 34 -2.5294371750177831 - 37 -2.5294371750177831 45 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.481673551673362 8 13.481673551673362 - 13 13.481673551673362 23 13.481673551673362 30 13.481673551673362 34 13.481673551673362 - 37 13.481673551673362 45 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.26635088939205875 8 -0.26635088939205875 - 13 -0.26635088939205875 23 -0.26635088939205875 30 -0.26635088939205875 34 - -0.26635088939205875 37 -0.26635088939205875 45 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -28.421435366308085 8 26.390084081057353 - 13 3.0380246299693914 23 28.948901241573878 30 28.948901241573878 34 28.948901241573878 - 37 28.948901241573878 45 -54.939650473111243; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 54.131467498825614 8 54.127627159682071 - 13 56.788026968748248 23 56.504185642602366 30 56.504185642602366 34 56.504185642602366 - 37 56.504185642602366 45 76.949742942700709; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.771254315237687 8 70.007400753511178 - 13 113.08245469121493 23 120.32357274286399 30 120.32357274286399 34 120.32357274286399 - 37 120.32357274286399 45 40.627341124577775; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 8 15.445123296459185 - 13 15.445123296459185 23 15.445123296459185 30 15.445123296459185 34 15.445123296459185 - 37 15.445123296459185 45 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 8 15.445123296459185 - 13 15.445123296459185 23 15.445123296459185 30 15.445123296459185 34 15.445123296459185 - 37 15.445123296459185 45 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 8 15.445123296459185 - 13 15.445123296459185 23 15.445123296459185 30 15.445123296459185 34 15.445123296459185 - 37 15.445123296459185 45 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 0 13 0 23 0 30 0 34 0 37 - 0 45 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5 8 0 13 0 23 0.40000000000000002 - 30 0.40000000000000002 34 0.40000000000000002 37 0 45 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 0 13 0 23 0 30 0 34 0 37 - 0 45 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 1 13 0 23 0 30 0 34 0 37 - 0 45 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 0 13 0 23 0 30 0 34 0 37 - 0 45 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 0 13 0 23 0 30 0 34 0 37 - 0 45 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 11 1 18 1 30 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 11 0 18 0 30 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.3128351505039433 5 2.3128351505039433 - 11 2.3128351505039433 18 2.3128351505039433 30 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.23421866920666501 5 0.23421866920666501 - 11 0.23421866920666501 18 0.23421866920666501 30 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.660431799163181 5 24.518180372533728 - 11 12.962570565749525 18 16.489138987116863 30 12.660431799163181; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 4.5006804094794566 11 6.2570163582771574 - 18 8.4179753606874126 30 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.4125540166489063 5 5.2109464812994872 - 11 -6.4568909071620268 18 -1.3975197628886351 30 2.4125540166489063; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 11 1 18 1 30 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 11 1 18 1 30 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 11 1 18 1 30 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -119.26198145440978 20 -114.8330168291658 - 30 -116.84358878592195; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 24.555774544790623 20 29.73075397194285 - 30 26.838610524516177; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -80.908776226967035 20 -87.095207656294406 - 30 -84.902102416105592; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 30 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 30 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 30 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 30 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 30 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 30 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -88.999627454702548 9 -70.169793940375726 - 22 -72.030028513411608 30 -72.920839076588123; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.0265376079649862 9 45.856437617457921 - 22 31.7727914601907 30 32.212936342090103; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -95.054620395662354 9 -95.109573445610067 - 22 -91.264425040577976 30 -89.170725795633828; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 22 0 30 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 22 0 30 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 22 1 30 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 22 0 30 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 22 0 30 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 22 0 30 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 40 1 45 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -7.3924057183505072 40 -7.3924057183505072 - 45 -7.3924057183505028; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 40 0 45 0; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 3.5548340896225601 40 3.5548340896225601 - 45 46.214597861712484; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.3462904043098467 40 5.3462904043098467 - 45 5.3462904043098467; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -29.54838557779286 40 -29.54838557779286 - 45 -29.54838557779286; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -5.3030645628451412 40 -5.3030645628451412 - 45 -5.3030645628451412; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 40 1 45 1; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 40 1 45 1; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 40 1 45 1; - setAttr -s 3 ".kit[2]" 9; - setAttr -s 3 ".kot[2]" 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 1 41 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 7.1689522478599503 41 7.1689522478599601; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 0 41 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 -7.7485750141607372 41 48.221202671600928; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 10.109326515514191 41 10.109326515514191; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 63.314403926397745 41 63.314403926397745; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 11.590164763476968 41 11.590164763476968; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 1 41 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 1 41 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 36 1 41 1; -select -ne :time1; - setAttr ".o" 45; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049338562 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Lshldr; - setAttr ".t" -type "double3" 1.085679155728795 4.1537911794025533 4.6185070801020824 ; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".t" -type "double3" -1.08568 4.1537988160630093 4.6185075120832098 ; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Lhand_GOAL; - setAttr ".t" -type "double3" 29.775846152470962 57.582470209590937 -1.0893063224582775 ; - setAttr ".r" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; - setAttr ".s" -type "double3" 1 0.99999999999999989 0.99999999999999978 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of fireball_sight.ma diff --git a/base/models/monsters/imp/animation/cycles/hangonceiling.ma b/base/models/monsters/imp/animation/cycles/hangonceiling.ma deleted file mode 100644 index 183111c4f..000000000 --- a/base/models/monsters/imp/animation/cycles/hangonceiling.ma +++ /dev/null @@ -1,15088 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: hangonceiling.ma -//Last modified: Thu, Nov 13, 2003 11:50:50 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t ntsc; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 19.301318547708213 -1866.3844677837733 -239.54411304250246 ; - setAttr ".r" -type "double3" 2884.4698910871207 836.19999999995593 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 70.454614523478128; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 14.390916678323805 -1865.2431864557052 -197.54707023689525 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 5.9875010717481931 142.96388800891717 -185.39427026945194 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 156.52825255984675; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" -4.0561499602604556 -1903.7356619512748 1103.492859775622 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 374.16740408740458; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 1582.7428818399978 -1956.3528219514606 -206.72520976666121 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 673.31254653302335; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "celing"; -createNode transform -n "m0" -p "celing"; -createNode mesh -n "polySurfaceShape1" -p "m0"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 432 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.249763 1.001008 - 0.249763 0.16771799 -0.000224 0.16771799 -0.000224 1.001008 -0.00038000001 - 0.49998599 -0.00042 -1.9999999e-005 -0.250359 -1.9999999e-005 -0.250319 0.49998599 - 0.25001001 4.9999999e-006 7.0000001e-006 4.9999999e-006 7.0000001e-006 1.000038 - 0.25001001 1.000038 9.4997454 4.9999999e-006 9.249711 4.9999999e-006 9.249711 - 1.000038 9.4997454 1.000038 0.25025201 4.9999999e-006 0.041930001 4.9999999e-006 - 0.041930001 1.000038 0.25025201 1.000038 0.249942 4.9999999e-006 0.499928 - 4.9999999e-006 0.499928 1.000038 0.249942 1.000038 0.249763 1.001002 0.249763 - 0.167712 -0.000224 0.167712 -0.000224 1.001002 -0.000378 0.49997401 -0.00041800001 - -3.2e-005 -0.25035599 -3.2e-005 -0.25031599 0.49997401 0.250016 4.9999999e-006 - 1.3e-005 4.9999999e-006 1.3e-005 1.000038 0.250016 1.000038 9.4997454 4.9999999e-006 - 9.249711 4.9999999e-006 9.249711 1.000038 9.4997454 1.000038 0.25025001 4.9999999e-006 - 0.041928001 4.9999999e-006 0.041928001 1.000038 0.25025001 1.000038 0.249942 - 4.9999999e-006 0.499928 4.9999999e-006 0.499928 1.000038 0.249942 1.000038 - 0.249763 1.001014 0.249763 0.167724 -0.000224 0.167724 -0.000224 1.001014 - -0.00038700001 0.499991 -0.00042699999 -1.5e-005 -0.25036499 -1.5e-005 -0.25032499 - 0.499991 0.250011 4.9999999e-006 8e-006 4.9999999e-006 8e-006 1.000038 0.250011 - 1.000038 9.4997454 4.9999999e-006 9.249711 4.9999999e-006 9.249711 1.000038 - 9.4997454 1.000038 0.25025299 4.9999999e-006 0.041931 4.9999999e-006 0.041931 - 1.000038 0.25025299 1.000038 0.249942 4.9999999e-006 0.499928 4.9999999e-006 - 0.499928 1.000038 0.249942 1.000038 -0.00028599999 0.167724 0.24969999 0.167724 - 0.24969999 1.001014 -0.00028599999 1.001014 -0.25008601 0.499991 -0.250126 - -1.5e-005 -0.00018800001 -1.5e-005 -0.00014800001 0.499991 8e-006 4.9999999e-006 - 0.250011 4.9999999e-006 0.250011 1.000038 8e-006 1.000038 9.2495956 4.9999999e-006 - 9.49963 4.9999999e-006 9.49963 1.000038 9.2495956 1.000038 0.041931 4.9999999e-006 - 0.25025299 4.9999999e-006 0.25025299 1.000038 0.041931 1.000038 0.49998999 - 4.9999999e-006 0.25000399 4.9999999e-006 0.25000399 1.000038 0.49998999 1.000038 - -0.00028599999 0.167712 0.24969999 0.167712 0.24969999 1.001002 -0.00028599999 - 1.001002 -0.25007701 0.49997401 -0.250117 -3.2e-005 -0.000179 -3.2e-005 -0.000139 - 0.49997401 1.3e-005 4.9999999e-006 0.250016 4.9999999e-006 0.250016 1.000038 - 1.3e-005 1.000038 9.2495956 4.9999999e-006 9.49963 4.9999999e-006 9.49963 - 1.000038 9.2495956 1.000038 0.041928001 4.9999999e-006 0.25025001 4.9999999e-006 - 0.25025001 1.000038 0.041928001 1.000038 0.49998999 4.9999999e-006 0.25000399 - 4.9999999e-006 0.25000399 1.000038 0.49998999 1.000038 -0.00028599999 0.16771799 - 0.24969999 0.16771799 0.24969999 1.001008 -0.00028599999 1.001008 -0.25008199 - 0.49998599 -0.25012201 -1.9999999e-005 -0.000183 -1.9999999e-005 -0.000143 - 0.49998599 7.0000001e-006 4.9999999e-006 0.25001001 4.9999999e-006 0.25001001 - 1.000038 7.0000001e-006 1.000038 9.2495956 4.9999999e-006 9.49963 4.9999999e-006 - 9.49963 1.000038 9.2495956 1.000038 0.041930001 4.9999999e-006 0.25025201 - 4.9999999e-006 0.25025201 1.000038 0.041930001 1.000038 0.49998999 4.9999999e-006 - 0.25000399 4.9999999e-006 0.25000399 1.000038 0.49998999 1.000038 -0.00028199999 - 0.16771799 0.249705 0.16771799 0.249705 1.001008 -0.00028199999 1.001008 - -0.25009799 0.49998599 -0.25013801 -1.9999999e-005 -0.000199 -1.9999999e-005 - -0.000159 0.49998599 7.0000001e-006 4.9999999e-006 0.25001001 4.9999999e-006 - 0.25001001 1.000038 7.0000001e-006 1.000038 9.2496014 4.9999999e-006 9.4996357 - 4.9999999e-006 9.4996357 1.000038 9.2496014 1.000038 0.041930001 4.9999999e-006 - 0.25025201 4.9999999e-006 0.25025201 1.000038 0.041930001 1.000038 0.499984 - 4.9999999e-006 0.249998 4.9999999e-006 0.249998 1.000038 0.499984 1.000038 - -0.00028199999 0.167712 0.249705 0.167712 0.249705 1.001002 -0.00028199999 - 1.001002 -0.25009301 0.49997401 -0.25013301 -3.2e-005 -0.000195 -3.2e-005 - -0.000155 0.49997401 1.3e-005 4.9999999e-006 0.250016 4.9999999e-006 0.250016 - 1.000038 1.3e-005 1.000038 9.2496014 4.9999999e-006 9.4996357 4.9999999e-006 - 9.4996357 1.000038 9.2496014 1.000038 0.041928001 4.9999999e-006 0.25025001 - 4.9999999e-006 0.25025001 1.000038 0.041928001 1.000038 0.499984 4.9999999e-006 - 0.249998 4.9999999e-006 0.249998 1.000038 0.499984 1.000038 -0.00028199999 - 0.167724 0.249705 0.167724 0.249705 1.001014 -0.00028199999 1.001014 -0.25010201 - 0.499991 -0.25014201 -1.5e-005 -0.000203 -1.5e-005 -0.000163 0.499991 8e-006 - 4.9999999e-006 0.250011 4.9999999e-006 0.250011 1.000038 8e-006 1.000038 - 9.2496014 4.9999999e-006 9.4996357 4.9999999e-006 9.4996357 1.000038 9.2496014 - 1.000038 0.041931 4.9999999e-006 0.25025299 4.9999999e-006 0.25025299 1.000038 - 0.041931 1.000038 0.499984 4.9999999e-006 0.249998 4.9999999e-006 0.249998 - 1.000038 0.499984 1.000038 0.24975801 1.001008 0.24975801 0.16771799 -0.000228 - 0.16771799 -0.000228 1.001008 -0.00036500001 0.49998599 -0.000405 -1.9999999e-005 - -0.25034401 -1.9999999e-005 -0.25030401 0.49998599 0.25001001 4.9999999e-006 - 7.0000001e-006 4.9999999e-006 7.0000001e-006 1.000038 0.25001001 1.000038 - 9.4997349 4.9999999e-006 9.2497005 4.9999999e-006 9.2497005 1.000038 9.4997349 - 1.000038 0.25025201 4.9999999e-006 0.041930001 4.9999999e-006 0.041930001 - 1.000038 0.25025201 1.000038 0.249946 4.9999999e-006 0.499933 4.9999999e-006 - 0.499933 1.000038 0.249946 1.000038 0.24975801 1.001002 0.24975801 0.167712 - -0.000228 0.167712 -0.000228 1.001002 -0.000363 0.49997401 -0.00040300001 - -3.2e-005 -0.250341 -3.2e-005 -0.250301 0.49997401 0.250016 4.9999999e-006 - 1.3e-005 4.9999999e-006; - setAttr ".uvst[0].uvsp[250:431]" 1.3e-005 1.000038 0.250016 1.000038 - 9.4997349 4.9999999e-006 9.2497005 4.9999999e-006 9.2497005 1.000038 9.4997349 - 1.000038 0.25025001 4.9999999e-006 0.041928001 4.9999999e-006 0.041928001 - 1.000038 0.25025001 1.000038 0.249946 4.9999999e-006 0.499933 4.9999999e-006 - 0.499933 1.000038 0.249946 1.000038 0.24975801 1.001014 0.24975801 0.167724 - -0.000228 0.167724 -0.000228 1.001014 -0.00037200001 0.499991 -0.00041199999 - -1.5e-005 -0.25035 -1.5e-005 -0.25031 0.499991 0.250011 4.9999999e-006 8e-006 - 4.9999999e-006 8e-006 1.000038 0.250011 1.000038 9.4997349 4.9999999e-006 - 9.2497005 4.9999999e-006 9.2497005 1.000038 9.4997349 1.000038 0.25025299 - 4.9999999e-006 0.041931 4.9999999e-006 0.041931 1.000038 0.25025299 1.000038 - 0.249946 4.9999999e-006 0.499933 4.9999999e-006 0.499933 1.000038 0.249946 - 1.000038 0.24973699 1.00088 0.24973699 0.16759001 -0.00024699999 0.16759001 - -0.00024699999 1.00088 -0.25017801 0.001599 -0.25013801 0.50164503 -0.000202 - 0.50164503 -0.00024199999 0.001599 0.251524 4.9999999e-006 0.001561 4.9999999e-006 - 0.001561 1.000038 0.251524 1.000038 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 - 9.249711 1.000038 9.4997435 1.000038 0.250222 4.9999999e-006 0.041898999 - 4.9999999e-006 0.041898999 1.000038 0.250222 1.000038 0.24997 4.9999999e-006 - 0.49995399 4.9999999e-006 0.49995399 1.000038 0.24997 1.000038 0.24973699 - 1.000875 0.24973699 0.167585 -0.00024699999 0.167585 -0.00024699999 1.000875 - -0.250175 0.0016139999 -0.250135 0.50165999 -0.000199 0.50165999 -0.000239 - 0.0016139999 0.25155199 4.9999999e-006 0.001588 4.9999999e-006 0.001588 1.000038 - 0.25155199 1.000038 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 9.249711 - 1.000038 9.4997435 1.000038 0.25022101 4.9999999e-006 0.041898001 4.9999999e-006 - 0.041898001 1.000038 0.25022101 1.000038 0.24997 4.9999999e-006 0.49995399 - 4.9999999e-006 0.49995399 1.000038 0.24997 1.000038 0.24973699 1.0008661 - 0.24973699 0.167576 -0.00024699999 0.167576 -0.00024699999 1.0008661 -0.25016901 - 0.001645 -0.25012901 0.50169098 -0.000193 0.50169098 -0.000233 0.001645 0.25160199 - 4.9999999e-006 0.001639 4.9999999e-006 0.001639 1.000038 0.25160199 1.000038 - 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 9.249711 1.000038 9.4997435 - 1.000038 0.25021699 4.9999999e-006 0.041894 4.9999999e-006 0.041894 1.000038 - 0.25021699 1.000038 0.24997 4.9999999e-006 0.49995399 4.9999999e-006 0.49995399 - 1.000038 0.24997 1.000038 0.24973699 1.000862 0.24973699 0.16757201 -0.00024699999 - 0.16757201 -0.00024699999 1.000862 -0.250166 0.00166 -0.250126 0.501706 -0.00019000001 - 0.501706 -0.00023000001 0.00166 0.25162601 4.9999999e-006 0.001663 4.9999999e-006 - 0.001663 1.000038 0.25162601 1.000038 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 - 9.249711 1.000038 9.4997435 1.000038 0.25021699 4.9999999e-006 0.041894998 - 4.9999999e-006 0.041894998 1.000038 0.25021699 1.000038 0.24997 4.9999999e-006 - 0.49995399 4.9999999e-006 0.49995399 1.000038 0.24997 1.000038 0.24973699 - 1.0008841 0.24973699 0.167594 -0.00024699999 0.167594 -0.00024699999 1.0008841 - -0.25018099 0.001584 -0.25014099 0.50163001 -0.000205 0.50163001 -0.000245 - 0.001584 0.25149399 4.9999999e-006 0.001531 4.9999999e-006 0.001531 1.000038 - 0.25149399 1.000038 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 9.249711 - 1.000038 9.4997435 1.000038 0.25022301 4.9999999e-006 0.041900001 4.9999999e-006 - 0.041900001 1.000038 0.25022301 1.000038 0.24997 4.9999999e-006 0.49995399 - 4.9999999e-006 0.49995399 1.000038 0.24997 1.000038 0.24973699 1.0008579 - 0.24973699 0.167567 -0.00024699999 0.167567 -0.00024699999 1.0008579 -0.25016299 - 0.0016749999 -0.25012299 0.50172102 -0.000187 0.50172102 -0.000227 0.0016749999 - 0.251654 4.9999999e-006 0.001691 4.9999999e-006 0.001691 1.000038 0.251654 - 1.000038 9.4997435 4.9999999e-006 9.249711 4.9999999e-006 9.249711 1.000038 - 9.4997435 1.000038 0.25021601 4.9999999e-006 0.041894 4.9999999e-006 0.041894 - 1.000038 0.25021601 1.000038 0.24997 4.9999999e-006 0.49995399 4.9999999e-006 - 0.49995399 1.000038 0.24997 1.000038; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 432 ".vt"; - setAttr ".vt[0:165]" -183.99951 -2064 4 -183.99951 -2064 -36.000488 - -232 -2064 -36.000488 -232 -2064 4 -232 -1968 4 -232 -1968 -36.000488 -183.99951 - -1968 -36.000488 -183.99951 -1968 4 -183.99951 -2064 -36.000488 -183.99951 - -2064 4 -183.99951 -1968 4 -183.99951 -1968 -36.000488 -232 -2064 -36.000488 - -183.99951 -2064 -36.000488 -183.99951 -1968 -36.000488 -232 -1968 -36.000488 - -232 -2064 4 -232 -2064 -36.000488 -232 -1968 -36.000488 -232 -1968 4 -183.99951 - -2064 4 -232 -2064 4 -232 -1968 4 -183.99951 -1968 4 -183.99951 -2064 100 - -183.99951 -2064 59.999512 -232 -2064 59.999512 -232 -2064 100 -232 -1968 - 100 -232 -1968 59.999512 -183.99951 -1968 59.999512 -183.99951 -1968 100 - -183.99951 -2064 59.999512 -183.99951 -2064 100 -183.99951 -1968 100 -183.99951 - -1968 59.999512 -232 -2064 59.999512 -183.99951 -2064 59.999512 -183.99951 - -1968 59.999512 -232 -1968 59.999512 -232 -2064 100 -232 -2064 59.999512 - -232 -1968 59.999512 -232 -1968 100 -183.99951 -2064 100 -232 -2064 100 -232 - -1968 100 -183.99951 -1968 100 -183.99951 -2064 -92 -183.99951 -2064 -132.00049 - -232 -2064 -132.00049 -232 -2064 -92 -232 -1968 -92 -232 -1968 -132.00049 - -183.99951 -1968 -132.00049 -183.99951 -1968 -92 -183.99951 -2064 -132.00049 - -183.99951 -2064 -92 -183.99951 -1968 -92 -183.99951 -1968 -132.00049 -232 - -2064 -132.00049 -183.99951 -2064 -132.00049 -183.99951 -1968 -132.00049 - -232 -1968 -132.00049 -232 -2064 -92 -232 -2064 -132.00049 -232 -1968 -132.00049 - -232 -1968 -92 -183.99951 -2064 -92 -232 -2064 -92 -232 -1968 -92 -183.99951 - -1968 -92 -24 -2064 -132.00049 -72.000488 -2064 -132.00049 -72.000488 -2064 - -92 -24 -2064 -92 -72.000488 -1968 -92 -72.000488 -1968 -132.00049 -24 -1968 - -132.00049 -24 -1968 -92 -72.000488 -2064 -92 -72.000488 -2064 -132.00049 - -72.000488 -1968 -132.00049 -72.000488 -1968 -92 -72.000488 -2064 -132.00049 - -24 -2064 -132.00049 -24 -1968 -132.00049 -72.000488 -1968 -132.00049 -24 - -2064 -132.00049 -24 -2064 -92 -24 -1968 -92 -24 -1968 -132.00049 -24 -2064 - -92 -72.000488 -2064 -92 -72.000488 -1968 -92 -24 -1968 -92 -24 -2064 59.999512 - -72.000488 -2064 59.999512 -72.000488 -2064 100 -24 -2064 100 -72.000488 - -1968 100 -72.000488 -1968 59.999512 -24 -1968 59.999512 -24 -1968 100 -72.000488 - -2064 100 -72.000488 -2064 59.999512 -72.000488 -1968 59.999512 -72.000488 - -1968 100 -72.000488 -2064 59.999512 -24 -2064 59.999512 -24 -1968 59.999512 - -72.000488 -1968 59.999512 -24 -2064 59.999512 -24 -2064 100 -24 -1968 100 - -24 -1968 59.999512 -24 -2064 100 -72.000488 -2064 100 -72.000488 -1968 100 - -24 -1968 100 -24 -2064 -36.000488 -72.000488 -2064 -36.000488 -72.000488 - -2064 4 -24 -2064 4 -72.000488 -1968 4 -72.000488 -1968 -36.000488 -24 -1968 - -36.000488 -24 -1968 4 -72.000488 -2064 4 -72.000488 -2064 -36.000488 -72.000488 - -1968 -36.000488 -72.000488 -1968 4 -72.000488 -2064 -36.000488 -24 -2064 - -36.000488 -24 -1968 -36.000488 -72.000488 -1968 -36.000488 -24 -2064 -36.000488 - -24 -2064 4 -24 -1968 4 -24 -1968 -36.000488 -24 -2064 4 -72.000488 -2064 - 4 -72.000488 -1968 4 -24 -1968 4 232 -2064 -36.000488 183.99951 -2064 -36.000488 - 183.99951 -2064 4 232 -2064 4 183.99951 -1968 4 183.99951 -1968 -36.000488 - 232 -1968 -36.000488 232 -1968 4 183.99951 -2064 4 183.99951 -2064 -36.000488 - 183.99951 -1968 -36.000488 183.99951 -1968 4 183.99951 -2064 -36.000488 232 - -2064 -36.000488 232 -1968 -36.000488 183.99951 -1968 -36.000488 232 -2064 - -36.000488 232 -2064 4 232 -1968 4 232 -1968 -36.000488 232 -2064 4 183.99951 - -2064 4; - setAttr ".vt[166:331]" 183.99951 -1968 4 232 -1968 4 232 -2064 59.999512 - 183.99951 -2064 59.999512 183.99951 -2064 100 232 -2064 100 183.99951 -1968 - 100 183.99951 -1968 59.999512 232 -1968 59.999512 232 -1968 100 183.99951 - -2064 100 183.99951 -2064 59.999512 183.99951 -1968 59.999512 183.99951 -1968 - 100 183.99951 -2064 59.999512 232 -2064 59.999512 232 -1968 59.999512 183.99951 - -1968 59.999512 232 -2064 59.999512 232 -2064 100 232 -1968 100 232 -1968 - 59.999512 232 -2064 100 183.99951 -2064 100 183.99951 -1968 100 232 -1968 - 100 232 -2064 -132.00049 183.99951 -2064 -132.00049 183.99951 -2064 -92 232 - -2064 -92 183.99951 -1968 -92 183.99951 -1968 -132.00049 232 -1968 -132.00049 - 232 -1968 -92 183.99951 -2064 -92 183.99951 -2064 -132.00049 183.99951 -1968 - -132.00049 183.99951 -1968 -92 183.99951 -2064 -132.00049 232 -2064 -132.00049 - 232 -1968 -132.00049 183.99951 -1968 -132.00049 232 -2064 -132.00049 232 - -2064 -92 232 -1968 -92 232 -1968 -132.00049 232 -2064 -92 183.99951 -2064 - -92 183.99951 -1968 -92 232 -1968 -92 72.000488 -2064 4 72.000488 -2064 -36.000488 - 24 -2064 -36.000488 24 -2064 4 24 -1968 4 24 -1968 -36.000488 72.000488 -1968 - -36.000488 72.000488 -1968 4 72.000488 -2064 -36.000488 72.000488 -2064 4 - 72.000488 -1968 4 72.000488 -1968 -36.000488 24 -2064 -36.000488 72.000488 - -2064 -36.000488 72.000488 -1968 -36.000488 24 -1968 -36.000488 24 -2064 - 4 24 -2064 -36.000488 24 -1968 -36.000488 24 -1968 4 72.000488 -2064 4 24 - -2064 4 24 -1968 4 72.000488 -1968 4 72.000488 -2064 100 72.000488 -2064 - 59.999512 24 -2064 59.999512 24 -2064 100 24 -1968 100 24 -1968 59.999512 - 72.000488 -1968 59.999512 72.000488 -1968 100 72.000488 -2064 59.999512 72.000488 - -2064 100 72.000488 -1968 100 72.000488 -1968 59.999512 24 -2064 59.999512 - 72.000488 -2064 59.999512 72.000488 -1968 59.999512 24 -1968 59.999512 24 - -2064 100 24 -2064 59.999512 24 -1968 59.999512 24 -1968 100 72.000488 -2064 - 100 24 -2064 100 24 -1968 100 72.000488 -1968 100 72.000488 -2064 -92 72.000488 - -2064 -132.00049 24 -2064 -132.00049 24 -2064 -92 24 -1968 -92 24 -1968 -132.00049 - 72.000488 -1968 -132.00049 72.000488 -1968 -92 72.000488 -2064 -132.00049 - 72.000488 -2064 -92 72.000488 -1968 -92 72.000488 -1968 -132.00049 24 -2064 - -132.00049 72.000488 -2064 -132.00049 72.000488 -1968 -132.00049 24 -1968 - -132.00049 24 -2064 -92 24 -2064 -132.00049 24 -1968 -132.00049 24 -1968 - -92 72.000488 -2064 -92 24 -2064 -92 24 -1968 -92 72.000488 -1968 -92 108 - -2064 -248 148.00049 -2064 -248 148.00049 -2064 -296 108 -2064 -296 148.00049 - -1968 -248 108 -1968 -248 108 -1968 -296 148.00049 -1968 -296 148.00049 -2064 - -248 108 -2064 -248 108 -1968 -248 148.00049 -1968 -248 148.00049 -2064 -296 - 148.00049 -2064 -248 148.00049 -1968 -248 148.00049 -1968 -296 108 -2064 - -296 148.00049 -2064 -296 148.00049 -1968 -296 108 -1968 -296 108 -2064 -248 - 108 -2064 -296 108 -1968 -296 108 -1968 -248 44 -2064 -248 84.000488 -2064 - -248 84.000488 -2064 -296 44 -2064 -296 84.000488 -1968 -248 44 -1968 -248 - 44 -1968 -296 84.000488 -1968 -296 84.000488 -2064 -248 44 -2064 -248 44 - -1968 -248 84.000488 -1968 -248 84.000488 -2064 -296 84.000488 -2064 -248 - 84.000488 -1968 -248 84.000488 -1968 -296 44 -2064 -296 84.000488 -2064 -296 - 84.000488 -1968 -296 44 -1968 -296; - setAttr ".vt[332:431]" 44 -2064 -248 44 -2064 -296 44 -1968 -296 44 - -1968 -248 -84 -2064 -248 -43.999512 -2064 -248 -43.999512 -2064 -296 -84 - -2064 -296 -43.999512 -1968 -248 -84 -1968 -248 -84 -1968 -296 -43.999512 - -1968 -296 -43.999512 -2064 -248 -84 -2064 -248 -84 -1968 -248 -43.999512 - -1968 -248 -43.999512 -2064 -296 -43.999512 -2064 -248 -43.999512 -1968 -248 - -43.999512 -1968 -296 -84 -2064 -296 -43.999512 -2064 -296 -43.999512 -1968 - -296 -84 -1968 -296 -84 -2064 -248 -84 -2064 -296 -84 -1968 -296 -84 -1968 - -248 -148 -2064 -248 -107.99951 -2064 -248 -107.99951 -2064 -296 -148 -2064 - -296 -107.99951 -1968 -248 -148 -1968 -248 -148 -1968 -296 -107.99951 -1968 - -296 -107.99951 -2064 -248 -148 -2064 -248 -148 -1968 -248 -107.99951 -1968 - -248 -107.99951 -2064 -296 -107.99951 -2064 -248 -107.99951 -1968 -248 -107.99951 - -1968 -296 -148 -2064 -296 -107.99951 -2064 -296 -107.99951 -1968 -296 -148 - -1968 -296 -148 -2064 -248 -148 -2064 -296 -148 -1968 -296 -148 -1968 -248 - 172 -2064 -248 212.00049 -2064 -248 212.00049 -2064 -296 172 -2064 -296 212.00049 - -1968 -248 172 -1968 -248 172 -1968 -296 212.00049 -1968 -296 212.00049 -2064 - -248 172 -2064 -248 172 -1968 -248 212.00049 -1968 -248 212.00049 -2064 -296 - 212.00049 -2064 -248 212.00049 -1968 -248 212.00049 -1968 -296 172 -2064 - -296 212.00049 -2064 -296 212.00049 -1968 -296 172 -1968 -296 172 -2064 -248 - 172 -2064 -296 172 -1968 -296 172 -1968 -248 -212 -2064 -248 -171.99951 -2064 - -248 -171.99951 -2064 -296 -212 -2064 -296 -171.99951 -1968 -248 -212 -1968 - -248 -212 -1968 -296 -171.99951 -1968 -296 -171.99951 -2064 -248 -212 -2064 - -248 -212 -1968 -248 -171.99951 -1968 -248 -171.99951 -2064 -296 -171.99951 - -2064 -248 -171.99951 -1968 -248 -171.99951 -1968 -296 -212 -2064 -296 -171.99951 - -2064 -296 -171.99951 -1968 -296 -212 -1968 -296 -212 -2064 -248 -212 -2064 - -296 -212 -1968 -296 -212 -1968 -248; - setAttr -s 540 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:497]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0 314 313 0 313 312 0 312 314 0 - 315 314 0 312 315 0 318 317 0 317 316 - 0 316 318 0 319 318 0 316 319 0 322 - 321 0 321 320 0 320 322 0 323 322 0 - 320 323 0 326 325 0 325 324 0 324 326 - 0 327 326 0 324 327 0 330 329 0 329 - 328 0 328 330 0 331 330 0 328 331 0 - 334 333 0 333 332 0 332 334 0 335 334 - 0 332 335 0 338 337 0 337 336 0 336 - 338 0 339 338 0 336 339 0 342 341 0 - 341 340 0 340 342 0 343 342 0 340 343 - 0 346 345 0 345 344 0 344 346 0 347 - 346 0 344 347 0 350 349 0 349 348 0 - 348 350 0 351 350 0 348 351 0 354 353 - 0 353 352 0 352 354 0 355 354 0 352 - 355 0 358 357 0 357 356 0 356 358 0 - 359 358 0 356 359 0 362 361 0 361 360 - 0 360 362 0 363 362 0 360 363 0 366 - 365 0 365 364 0 364 366 0 367 366 0 - 364 367 0 370 369 0 369 368 0 368 370 - 0 371 370 0 368 371 0 374 373 0 373 - 372 0 372 374 0 375 374 0 372 375 0 - 378 377 0 377 376 0 376 378 0 379 378 - 0 376 379 0 382 381 0 381 380 0 380 - 382 0 383 382 0 380 383 0 386 385 0 - 385 384 0 384 386 0 387 386 0 384 387 - 0 390 389 0 389 388 0 388 390 0 391 - 390 0 388 391 0 394 393 0 393 392 0 - 392 394 0 395 394 0 392 395 0 398 397 - 0 397 396 0 396 398 0; - setAttr ".ed[498:539]" 399 398 0 396 399 0 402 - 401 0 401 400 0 400 402 0 403 402 0 - 400 403 0 406 405 0 405 404 0 404 406 - 0 407 406 0 404 407 0 410 409 0 409 - 408 0 408 410 0 411 410 0 408 411 0 - 414 413 0 413 412 0 412 414 0 415 414 - 0 412 415 0 418 417 0 417 416 0 416 - 418 0 419 418 0 416 419 0 422 421 0 - 421 420 0 420 422 0 423 422 0 420 423 - 0 426 425 0 425 424 0 424 426 0 427 - 426 0 424 427 0 430 429 0 429 428 0 - 428 430 0 431 430 0 428 431 0; - setAttr -s 648 ".n"; - setAttr ".n[0:165]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 -1.2417482e-010 0 1 -1.2417482e-010 - 0 1 -1.2417482e-010 0 1 1.2417482e-010 0 1 1.2417482e-010 0 1 1.2417482e-010 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 -1.2417482e-010 0 1 - -1.2417482e-010 0 1 -1.2417482e-010 0 1 1.2417482e-010 0 1 1.2417482e-010 - 0 1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 1.2417482e-010 - 0 1 1.2417482e-010 0 1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 - 0 -1 1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 0 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 - 0 -1 -1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr ".n[166:331]" -type "float3" 0 0 -1 0 0 -1 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 - 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 - 0 -1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 - 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 - 0 -1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 - 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 - 0 -1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 -1.2417482e-010 - 0 -1 -1.2417482e-010 0 -1 -1.2417482e-010 0 -1 1.2417482e-010 0 -1 1.2417482e-010 - 0 -1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0; - setAttr ".n[332:497]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 1 -1.2417482e-010 - 0 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 1.2417482e-010 0 1 1.2417482e-010 - 0 1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 1.2417482e-010 - 0 1 1.2417482e-010 0 1 1.2417482e-010 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 1 -1.2417482e-010 0 1 -1.2417482e-010 0 1 -1.2417482e-010 - 0 1 1.2417482e-010 0 1 1.2417482e-010 0 1 1.2417482e-010 0 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1; - setAttr ".n[498:647]" -type "float3" -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0; - setAttr -s 216 ".fc[0:215]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 - f 3 390 391 392 - mu 0 3 314 313 312 - f 3 393 -393 394 - mu 0 3 315 314 312 - f 3 395 396 397 - mu 0 3 318 317 316 - f 3 398 -398 399 - mu 0 3 319 318 316 - f 3 400 401 402 - mu 0 3 322 321 320 - f 3 403 -403 404 - mu 0 3 323 322 320 - f 3 405 406 407 - mu 0 3 326 325 324 - f 3 408 -408 409 - mu 0 3 327 326 324 - f 3 410 411 412 - mu 0 3 330 329 328 - f 3 413 -413 414 - mu 0 3 331 330 328 - f 3 415 416 417 - mu 0 3 334 333 332 - f 3 418 -418 419 - mu 0 3 335 334 332 - f 3 420 421 422 - mu 0 3 338 337 336 - f 3 423 -423 424 - mu 0 3 339 338 336 - f 3 425 426 427 - mu 0 3 342 341 340 - f 3 428 -428 429 - mu 0 3 343 342 340 - f 3 430 431 432 - mu 0 3 346 345 344 - f 3 433 -433 434 - mu 0 3 347 346 344 - f 3 435 436 437 - mu 0 3 350 349 348 - f 3 438 -438 439 - mu 0 3 351 350 348 - f 3 440 441 442 - mu 0 3 354 353 352 - f 3 443 -443 444 - mu 0 3 355 354 352 - f 3 445 446 447 - mu 0 3 358 357 356 - f 3 448 -448 449 - mu 0 3 359 358 356 - f 3 450 451 452 - mu 0 3 362 361 360 - f 3 453 -453 454 - mu 0 3 363 362 360 - f 3 455 456 457 - mu 0 3 366 365 364 - f 3 458 -458 459 - mu 0 3 367 366 364 - f 3 460 461 462 - mu 0 3 370 369 368 - f 3 463 -463 464 - mu 0 3 371 370 368 - f 3 465 466 467 - mu 0 3 374 373 372 - f 3 468 -468 469 - mu 0 3 375 374 372 - f 3 470 471 472 - mu 0 3 378 377 376 - f 3 473 -473 474 - mu 0 3 379 378 376 - f 3 475 476 477 - mu 0 3 382 381 380 - f 3 478 -478 479 - mu 0 3 383 382 380 - f 3 480 481 482 - mu 0 3 386 385 384 - f 3 483 -483 484 - mu 0 3 387 386 384 - f 3 485 486 487 - mu 0 3 390 389 388 - f 3 488 -488 489 - mu 0 3 391 390 388 - f 3 490 491 492 - mu 0 3 394 393 392 - f 3 493 -493 494 - mu 0 3 395 394 392 - f 3 495 496 497 - mu 0 3 398 397 396 - f 3 498 -498 499 - mu 0 3 399 398 396 - f 3 500 501 502 - mu 0 3 402 401 400 - f 3 503 -503 504 - mu 0 3 403 402 400 - f 3 505 506 507 - mu 0 3 406 405 404 - f 3 508 -508 509 - mu 0 3 407 406 404 - f 3 510 511 512 - mu 0 3 410 409 408 - f 3 513 -513 514 - mu 0 3 411 410 408 - f 3 515 516 517 - mu 0 3 414 413 412 - f 3 518 -518 519 - mu 0 3 415 414 412 - f 3 520 521 522 - mu 0 3 418 417 416 - f 3 523 -523 524 - mu 0 3 419 418 416 - f 3 525 526 527 - mu 0 3 422 421 420 - f 3 528 -528 529 - mu 0 3 423 422 420 - f 3 530 531 532 - mu 0 3 426 425 424 - f 3 533 -533 534 - mu 0 3 427 426 424 - f 3 535 536 537 - mu 0 3 430 429 428 - f 3 538 -538 539 - mu 0 3 431 430 428 ; -createNode transform -n "m2" -p "celing"; -createNode mesh -n "polySurfaceShape2" -p "m2"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 48 ".uvst[0].uvsp[0:47]" -type "float2" 0 0 1 0 - 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 - 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 1 - 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 48 ".vt[0:47]" -236 -2064 12 -236 -2064 -40 -236 - -1856 12 -236 -1856 -40 -236 -2064 108 -236 -2064 56 -236 -1856 108 -236 - -1856 56 -236 -2064 -84 -236 -2064 -136 -236 -1856 -84 -236 -1856 -136 -20 - -1856 -84 -20 -1856 -136 -20 -2064 -84 -20 -2064 -136 -20 -1856 108 -20 -1856 - 56 -20 -2064 108 -20 -2064 56 -20 -1856 12 -20 -1856 -40 -20 -2064 12 -20 - -2064 -40 236 -1856 12 236 -1856 -40 236 -2064 12 236 -2064 -40 236 -1856 - 108 236 -1856 56 236 -2064 108 236 -2064 56 236 -1856 -84 236 -1856 -136 - 236 -2064 -84 236 -2064 -136 20 -2064 12 20 -2064 -40 20 -1856 12 20 -1856 - -40 20 -2064 108 20 -2064 56 20 -1856 108 20 -1856 56 20 -2064 -84 20 -2064 - -136 20 -1856 -84 20 -1856 -136; - setAttr -s 60 ".ed[0:59]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0 6 - 4 0 4 5 0 5 6 0 5 7 0 - 7 6 0 10 8 0 8 9 0 9 10 - 0 9 11 0 11 10 0 14 12 0 12 - 13 0 13 14 0 13 15 0 15 14 0 - 18 16 0 16 17 0 17 18 0 17 19 - 0 19 18 0 22 20 0 20 21 0 21 - 22 0 21 23 0 23 22 0 26 24 0 - 24 25 0 25 26 0 25 27 0 27 26 - 0 30 28 0 28 29 0 29 30 0 29 - 31 0 31 30 0 34 32 0 32 33 0 - 33 34 0 33 35 0 35 34 0 38 36 - 0 36 37 0 37 38 0 37 39 0 39 - 38 0 42 40 0 40 41 0 41 42 0 - 41 43 0 43 42 0 46 44 0 44 45 - 0 45 46 0 45 47 0 47 46 0; - setAttr -s 72 ".n[0:71]" -type "float3" 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0; - setAttr -s 24 ".fc[0:23]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 - f 3 5 6 7 - mu 0 3 6 4 5 - f 3 -8 8 9 - mu 0 3 6 5 7 - f 3 10 11 12 - mu 0 3 10 8 9 - f 3 -13 13 14 - mu 0 3 10 9 11 - f 3 15 16 17 - mu 0 3 14 12 13 - f 3 -18 18 19 - mu 0 3 14 13 15 - f 3 20 21 22 - mu 0 3 18 16 17 - f 3 -23 23 24 - mu 0 3 18 17 19 - f 3 25 26 27 - mu 0 3 22 20 21 - f 3 -28 28 29 - mu 0 3 22 21 23 - f 3 30 31 32 - mu 0 3 26 24 25 - f 3 -33 33 34 - mu 0 3 26 25 27 - f 3 35 36 37 - mu 0 3 30 28 29 - f 3 -38 38 39 - mu 0 3 30 29 31 - f 3 40 41 42 - mu 0 3 34 32 33 - f 3 -43 43 44 - mu 0 3 34 33 35 - f 3 45 46 47 - mu 0 3 38 36 37 - f 3 -48 48 49 - mu 0 3 38 37 39 - f 3 50 51 52 - mu 0 3 42 40 41 - f 3 -53 53 54 - mu 0 3 42 41 43 - f 3 55 56 57 - mu 0 3 46 44 45 - f 3 -58 58 59 - mu 0 3 46 45 47 ; -createNode transform -n "m10" -p "celing"; -createNode mesh -n "polySurfaceShape3" -p "m10"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 24 ".uvst[0].uvsp[0:23]" -type "float2" 0.56246901 - 1 0.56246901 -1 -2.9373069 -1 -2.9373069 1 0.56246901 1 0.56246901 3 -2.9373069 - 3 -2.9373069 1 0.56246901 1 0.56246901 -1 -2.9373069 -1 -2.9373069 1 0.56246901 - 1 0.56246901 3 -2.9373069 3 -2.9373069 1 0.56246901 1 0.56246901 -1 -2.9373069 - -1 -2.9373069 1 0.56246901 1 0.56246901 3 -2.9373069 3 -2.9373069 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 24 ".vt[0:23]" 288 -2144 -336 288 -2144 -272 288 - -1696 -272 288 -1696 -336 224 -2144 -272 224 -2144 -336 224 -1696 -336 224 - -1696 -272 -224 -2144 -336 -224 -2144 -272 -224 -1696 -272 -224 -1696 -336 - -288 -2144 -272 -288 -2144 -336 -288 -1696 -336 -288 -1696 -272 32 -2144 - -336 32 -2144 -272 32 -1696 -272 32 -1696 -336 -32 -2144 -272 -32 -2144 -336 - -32 -1696 -336 -32 -1696 -272; - setAttr -s 30 ".ed[0:29]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0; - setAttr -s 36 ".n[0:35]" -type "float3" 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0; - setAttr -s 12 ".fc[0:11]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 ; -createNode transform -n "m12" -p "celing"; -createNode mesh -n "polySurfaceShape4" -p "m12"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 456 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 2.0001199 97 2.0001199 - 96 3.0001841 96 3.0001841 97 -11.876429 -3 -11.876429 2 -12.001436 2 -12.001436 - -3 12.001436 -3 12.001436 2 11.876429 2 11.876429 -3 -1.99842 -3 -1.99842 - 2 -2.9986119 2 -2.9986119 -3 -17.75144 -109 -17.75144 -117 -17.626415 -117 - -17.626415 -109 1.000057 96 1.000057 97 3.000185 97 3.000185 96 -12.000955 - -3 -12.000955 2 -11.875947 2 -11.875947 -3 11.875947 -3 11.875947 2 12.000955 - 2 12.000955 -3 -3.000185 -3 -3.000185 2 -1.000057 2 -1.000057 -3 1.000057 - -119 1.000057 -118 3.000185 -118 3.000185 -119 1.000057 96 1.000057 97 3.000185 - 97 3.000185 96 -12.000772 -3 -12.000772 2 -11.875764 2 -11.875764 -3 1.000057 - -3 1.000057 2 3.000185 2 3.000185 -3 11.875764 -3 11.875764 2 12.000772 2 - 12.000772 -3 1.000057 -124 1.000057 -123 3.000185 -123 3.000185 -124 1.000057 - 97 1.000057 96 3.000185 96 3.000185 97 -11.875879 -3 -11.875879 2 -12.000887 - 2 -12.000887 -3 12.000887 -3 12.000887 2 11.875879 2 11.875879 -3 -1.000057 - -3 -1.000057 2 -3.000185 2 -3.000185 -3 -3.000185 -107 -3.000185 -108 -1.000057 - -108 -1.000057 -107 2.0001199 97 2.0001199 96 3.0001841 96 3.0001841 97 -11.876552 - -3 -11.876552 2 -12.001559 2 -12.001559 -3 2.9985819 -3 2.9985819 2 1.99839 - 2 1.99839 -3 12.001559 -3 12.001559 2 11.876552 2 11.876552 -3 -19.876848 - -109 -19.876848 -117 -19.751823 -117 -19.751823 -109 2.0001199 97 2.0001199 - 96 3.0001841 96 3.0001841 97 -11.876588 -3 -11.876588 2 -12.001596 2 -12.001596 - -3 2.9985819 -3 2.9985819 2 1.99839 2 1.99839 -3 12.001596 -3 12.001596 2 - 11.876588 2 11.876588 -3 -1.99842 -3 -1.99842 2 -2.9986119 2 -2.9986119 -3 - -20.501968 -109 -20.501968 -117 -20.376944 -117 -20.376944 -109 1.000057 - 96 1.000057 97 3.000185 97 3.000185 96 -12.000951 -3 -12.000951 2 -11.875943 - 2 -11.875943 -3 11.875943 -3 11.875943 2 12.000951 2 12.000951 -3 -3.000185 - -3 -3.000185 2 -1.000057 2 -1.000057 -3 1.000057 -103 1.000057 -102 3.000185 - -102 3.000185 -103 17.00107 -3 14.625917 -3 14.625917 1 17.00107 1 14.625917 - -3 14.375902 -3 14.375902 1 14.625917 1 14.375902 -3 12.00075 -3 12.00075 - 1 14.375902 1 2.750042 96 3.0000579 96 3.0000579 97 2.750042 97 12.001436 - -3 12.001436 2 11.876429 2 11.876429 -3 -2.7486629 2 -2.9987111 2 -2.9987111 - -3 -2.7486629 -3 -19.751926 -125 -19.751926 -127 -19.626902 -127 -19.626902 - -125 -17.751553 -3 -17.751553 2 -17.876577 2 -17.876577 -3 2.75209 97 3.002106 - 97 3.002106 96 2.75209 96 11.876429 -3 11.876429 2 12.001436 2 12.001436 - -3 -2.7469981 -3 -2.997046 -3 -2.997046 2 -2.7469981 2 -19.751926 -127 -19.751926 - -125 -19.626902 -125 -19.626902 -127 -17.876577 -3 -17.876577 2 -17.751553 - 2 -17.751553 -3 2.750042 96 3.0000579 96 3.0000579 97 2.750042 97 12.001559 - -3 12.001559 2 11.876552 2 11.876552 -3 -2.7486629 2 -2.9987111 2 -2.9987111 - -3 -2.7486629 -3 -19.751818 -125 -19.751818 -127 -19.626793 -127 -19.626793 - -125 -17.751665 -3 -17.751665 2 -17.87669 2 -17.87669 -3 2.75209 97 3.002106 - 97 3.002106 96 2.75209 96 11.876552 -3 11.876552 2 12.001559 2 12.001559 - -3 -2.7469981 -3 -2.997046 -3 -2.997046 2 -2.7469981 2 -19.751818 -127 -19.751818 - -125 -19.626793 -125 -19.626793 -127 -17.87669 -3 -17.87669 2 -17.751665 - 2 -17.751665 -3 2.75209 97 3.002106 97 3.002106 96 2.75209 96 11.876588 -3 - 11.876588 2 12.001596 2 12.001596 -3 -2.7469981 -3 -2.997046 -3 -2.997046 - 2 -2.7469981 2 -19.751785 -127 -19.751785 -125; - setAttr ".uvst[0].uvsp[250:455]" -19.62676 -125 -19.62676 -127 -17.876722 - -3 -17.876722 2 -17.751698 2 -17.751698 -3 2.750042 96 3.0000579 96 3.0000579 - 97 2.750042 97 12.001596 -3 12.001596 2 11.876588 2 11.876588 -3 -2.7486629 - 2 -2.9987111 2 -2.9987111 -3 -2.7486629 -3 -19.751785 -125 -19.751785 -127 - -19.62676 -127 -19.62676 -125 -17.751698 -3 -17.751698 2 -17.876722 2 -17.876722 - -3 2.751863 97 3.001879 97 3.001879 96 2.751863 96 11.876588 -3 11.876588 - 2 12.001596 2 12.001596 -3 -2.7471759 -3 -2.9972241 -3 -2.9972241 2 -2.7471759 - 2 -19.751785 -127 -19.751785 -125 -19.62676 -125 -19.62676 -127 -17.876722 - -3 -17.876722 2 -17.751698 2 -17.751698 -3 2.7541931 96 3.004209 96 3.004209 - 97 2.7541931 97 12.001596 -3 12.001596 2 11.876588 2 11.876588 -3 -2.748481 - 2 -2.998529 2 -2.998529 -3 -2.748481 -3 -19.751785 -125 -19.751785 -127 -19.62676 - -127 -19.62676 -125 -17.751698 -3 -17.751698 2 -17.876722 2 -17.876722 -3 - 2.7541931 96 3.004209 96 3.004209 97 2.7541931 97 12.001559 -3 12.001559 - 2 11.876552 2 11.876552 -3 -2.748481 2 -2.998529 2 -2.998529 -3 -2.748481 - -3 -19.751818 -125 -19.751818 -127 -19.626793 -127 -19.626793 -125 -17.751665 - -3 -17.751665 2 -17.87669 2 -17.87669 -3 2.751863 97 3.001879 97 3.001879 - 96 2.751863 96 11.876552 -3 11.876552 2 12.001559 2 12.001559 -3 -2.7471759 - -3 -2.9972241 -3 -2.9972241 2 -2.7471759 2 -19.751818 -127 -19.751818 -125 - -19.626793 -125 -19.626793 -127 -17.87669 -3 -17.87669 2 -17.751665 2 -17.751665 - -3 -13.999063 33 -14.49903 33 -14.49903 37 -13.999063 37 -13.999111 33 -14.499079 - 33 -14.499079 37 -13.999111 37 -13.999107 33 -14.499075 33 -14.499075 37 - -13.999107 37 2.7541931 96 3.004209 96 3.004209 97 2.7541931 97 12.001436 - -3 12.001436 2 11.876429 2 11.876429 -3 -2.748481 2 -2.998529 2 -2.998529 - -3 -2.748481 -3 -19.751926 -125 -19.751926 -127 -19.626902 -127 -19.626902 - -125 -17.751553 -3 -17.751553 2 -17.876577 2 -17.876577 -3 2.751863 97 3.001879 - 97 3.001879 96 2.751863 96 11.876429 -3 11.876429 2 12.001436 2 12.001436 - -3 -2.7471759 -3 -2.9972241 -3 -2.9972241 2 -2.7471759 2 -19.751926 -127 - -19.751926 -125 -19.626902 -125 -19.626902 -127 -17.876577 -3 -17.876577 - 2 -17.751553 2 -17.751553 -3 2.751863 97 3.001879 97 3.001879 96 2.751863 - 96 11.876429 -3 11.876429 2 12.001436 2 12.001436 -3 -2.7471759 -3 -2.9972241 - -3 -2.9972241 2 -2.7471759 2 -19.751926 -127 -19.751926 -125 -19.626902 -125 - -19.626902 -127 -17.876577 -3 -17.876577 2 -17.751553 2 -17.751553 -3 2.7541931 - 96 3.004209 96 3.004209 97 2.7541931 97 12.001436 -3 12.001436 2 11.876429 - 2 11.876429 -3 -2.748481 2 -2.998529 2 -2.998529 -3 -2.748481 -3 -19.751926 - -125 -19.751926 -127 -19.626902 -127 -19.626902 -125 -17.751553 -3 -17.751553 - 2 -17.876577 2 -17.876577 -3 17.12607 33 12.12575 33 12.12575 37 17.12607 - 37 -0.62504703 -222 -1.937631 -222 -1.937631 -218 -0.62504703 -218; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 456 ".vt"; - setAttr ".vt[0:165]" -64 -2064 128 -64 -2064 112 64 -2064 112 64 - -2064 128 -64 -2144 112 -64 -2064 112 -64 -2064 128 -64 -2144 128 64 -2144 - 128 64 -2064 128 64 -2064 112 64 -2144 112 -64 -2144 128 -64 -2064 128 64 - -2064 128 64 -2144 128 64 -2144 112 -64 -2144 112 -64 -2144 128 64 -2144 - 128 -80 -2064 112 -96 -2064 112 -96 -2064 -144 -80 -2064 -144 -96 -2144 112 - -96 -2064 112 -80 -2064 112 -80 -2144 112 -80 -2144 -144 -80 -2064 -144 -96 - -2064 -144 -96 -2144 -144 -96 -2144 -144 -96 -2064 -144 -96 -2064 112 -96 - -2144 112 -96 -2144 112 -80 -2144 112 -80 -2144 -144 -96 -2144 -144 -160 - -2064 112 -176 -2064 112 -176 -2064 -144 -160 -2064 -144 -176 -2144 112 -176 - -2064 112 -160 -2064 112 -160 -2144 112 -160 -2144 112 -160 -2064 112 -160 - -2064 -144 -160 -2144 -144 -160 -2144 -144 -160 -2064 -144 -176 -2064 -144 - -176 -2144 -144 -176 -2144 112 -160 -2144 112 -160 -2144 -144 -176 -2144 - -144 96 -2064 112 80 -2064 112 80 -2064 -144 96 -2064 -144 80 -2144 112 80 - -2064 112 96 -2064 112 96 -2144 112 96 -2144 -144 96 -2064 -144 80 -2064 - -144 80 -2144 -144 96 -2144 112 96 -2064 112 96 -2064 -144 96 -2144 -144 - 96 -2144 -144 80 -2144 -144 80 -2144 112 96 -2144 112 -64 -2064 -144 -64 - -2064 -160 64 -2064 -160 64 -2064 -144 -64 -2144 -160 -64 -2064 -160 -64 - -2064 -144 -64 -2144 -144 64 -2144 -160 64 -2064 -160 -64 -2064 -160 -64 - -2144 -160 64 -2144 -144 64 -2064 -144 64 -2064 -160 64 -2144 -160 64 -2144 - -160 -64 -2144 -160 -64 -2144 -144 64 -2144 -144 -64 -2064 -224 -64 -2064 - -240 64 -2064 -240 64 -2064 -224 -64 -2144 -240 -64 -2064 -240 -64 -2064 - -224 -64 -2144 -224 64 -2144 -240 64 -2064 -240 -64 -2064 -240 -64 -2144 - -240 64 -2144 -224 64 -2064 -224 64 -2064 -240 64 -2144 -240 -64 -2144 -224 - -64 -2064 -224 64 -2064 -224 64 -2144 -224 64 -2144 -240 -64 -2144 -240 -64 - -2144 -224 64 -2144 -224 176 -2064 112 160 -2064 112 160 -2064 -144 176 -2064 - -144 160 -2144 112 160 -2064 112 176 -2064 112 176 -2144 112 176 -2144 -144 - 176 -2064 -144 160 -2064 -144 160 -2144 -144 160 -2144 -144 160 -2064 -144 - 160 -2064 112 160 -2144 112 160 -2144 112 176 -2144 112 176 -2144 -144 160 - -2144 -144 -320 -2208 -336 -16 -2208 -336 -16 -2144 -336 -320 -2144 -336 - -16 -2208 -336 16 -2208 -336 16 -2144 -336 -16 -2144 -336 16 -2208 -336 320 - -2208 -336 320 -2144 -336 16 -2144 -336 -224 -2064 112 -192 -2064 112 -192 - -2064 128 -224 -2064 128 -192 -2144 128 -192 -2064 128 -192 -2064 112 -192 - -2144 112 -224 -2064 128 -192 -2064 128; - setAttr ".vt[166:331]" -192 -2144 128 -224 -2144 128 -192 -2144 112 - -224 -2144 112 -224 -2144 128 -192 -2144 128 -224 -2144 112 -224 -2064 112 - -224 -2064 128 -224 -2144 128 -224 -2064 128 -256 -2064 128 -256 -2064 112 - -224 -2064 112 -256 -2144 112 -256 -2064 112 -256 -2064 128 -256 -2144 128 - -224 -2144 128 -256 -2144 128 -256 -2064 128 -224 -2064 128 -224 -2144 112 - -256 -2144 112 -256 -2144 128 -224 -2144 128 -224 -2144 128 -224 -2064 128 - -224 -2064 112 -224 -2144 112 -224 -2064 -160 -192 -2064 -160 -192 -2064 - -144 -224 -2064 -144 -192 -2144 -144 -192 -2064 -144 -192 -2064 -160 -192 - -2144 -160 -224 -2064 -144 -192 -2064 -144 -192 -2144 -144 -224 -2144 -144 - -192 -2144 -160 -224 -2144 -160 -224 -2144 -144 -192 -2144 -144 -224 -2144 - -160 -224 -2064 -160 -224 -2064 -144 -224 -2144 -144 -224 -2064 -144 -256 - -2064 -144 -256 -2064 -160 -224 -2064 -160 -256 -2144 -160 -256 -2064 -160 - -256 -2064 -144 -256 -2144 -144 -224 -2144 -144 -256 -2144 -144 -256 -2064 - -144 -224 -2064 -144 -224 -2144 -160 -256 -2144 -160 -256 -2144 -144 -224 - -2144 -144 -224 -2144 -144 -224 -2064 -144 -224 -2064 -160 -224 -2144 -160 - -224 -2064 -224 -256 -2064 -224 -256 -2064 -240 -224 -2064 -240 -256 -2144 - -240 -256 -2064 -240 -256 -2064 -224 -256 -2144 -224 -224 -2144 -224 -256 - -2144 -224 -256 -2064 -224 -224 -2064 -224 -224 -2144 -240 -256 -2144 -240 - -256 -2144 -224 -224 -2144 -224 -224 -2144 -224 -224 -2064 -224 -224 -2064 - -240 -224 -2144 -240 -224 -2064 -240 -192 -2064 -240 -192 -2064 -224 -224 - -2064 -224 -192 -2144 -224 -192 -2064 -224 -192 -2064 -240 -192 -2144 -240 - -224 -2064 -224 -192 -2064 -224 -192 -2144 -224 -224 -2144 -224 -192 -2144 - -240 -224 -2144 -240 -224 -2144 -224 -192 -2144 -224 -224 -2144 -240 -224 - -2064 -240 -224 -2064 -224 -224 -2144 -224 224 -2064 -224 192 -2064 -224 - 192 -2064 -240 224 -2064 -240 192 -2144 -240 192 -2064 -240 192 -2064 -224 - 192 -2144 -224 224 -2144 -224 192 -2144 -224 192 -2064 -224 224 -2064 -224 - 224 -2144 -240 192 -2144 -240 192 -2144 -224 224 -2144 -224 224 -2144 -224 - 224 -2064 -224 224 -2064 -240 224 -2144 -240 224 -2064 -240 256 -2064 -240 - 256 -2064 -224 224 -2064 -224 256 -2144 -224 256 -2064 -224 256 -2064 -240 - 256 -2144 -240 224 -2064 -224 256 -2064 -224 256 -2144 -224 224 -2144 -224 - 256 -2144 -240 224 -2144 -240 224 -2144 -224 256 -2144 -224 224 -2144 -240 - 224 -2064 -240 224 -2064 -224 224 -2144 -224 224 -2064 -160 256 -2064 -160 - 256 -2064 -144 224 -2064 -144 256 -2144 -144 256 -2064 -144 256 -2064 -160 - 256 -2144 -160 224 -2064 -144 256 -2064 -144 256 -2144 -144 224 -2144 -144 - 256 -2144 -160 224 -2144 -160 224 -2144 -144 256 -2144 -144; - setAttr ".vt[332:455]" 224 -2144 -160 224 -2064 -160 224 -2064 -144 - 224 -2144 -144 224 -2064 -144 192 -2064 -144 192 -2064 -160 224 -2064 -160 - 192 -2144 -160 192 -2064 -160 192 -2064 -144 192 -2144 -144 224 -2144 -144 - 192 -2144 -144 192 -2064 -144 224 -2064 -144 224 -2144 -160 192 -2144 -160 - 192 -2144 -144 224 -2144 -144 224 -2144 -144 224 -2064 -144 224 -2064 -160 - 224 -2144 -160 288 -1696 -272 224 -1696 -272 224 -1696 -336 288 -1696 -336 - -224 -1696 -272 -288 -1696 -272 -288 -1696 -336 -224 -1696 -336 32 -1696 - -272 -32 -1696 -272 -32 -1696 -336 32 -1696 -336 224 -2064 112 256 -2064 - 112 256 -2064 128 224 -2064 128 256 -2144 128 256 -2064 128 256 -2064 112 - 256 -2144 112 224 -2064 128 256 -2064 128 256 -2144 128 224 -2144 128 256 - -2144 112 224 -2144 112 224 -2144 128 256 -2144 128 224 -2144 112 224 -2064 - 112 224 -2064 128 224 -2144 128 224 -2064 128 192 -2064 128 192 -2064 112 - 224 -2064 112 192 -2144 112 192 -2064 112 192 -2064 128 192 -2144 128 224 - -2144 128 192 -2144 128 192 -2064 128 224 -2064 128 224 -2144 112 192 -2144 - 112 192 -2144 128 224 -2144 128 224 -2144 128 224 -2064 128 224 -2064 112 - 224 -2144 112 320 -2064 128 288 -2064 128 288 -2064 112 320 -2064 112 288 - -2144 112 288 -2064 112 288 -2064 128 288 -2144 128 320 -2144 128 288 -2144 - 128 288 -2064 128 320 -2064 128 320 -2144 112 288 -2144 112 288 -2144 128 - 320 -2144 128 320 -2144 128 320 -2064 128 320 -2064 112 320 -2144 112 320 - -2064 112 352 -2064 112 352 -2064 128 320 -2064 128 352 -2144 128 352 -2064 - 128 352 -2064 112 352 -2144 112 320 -2064 128 352 -2064 128 352 -2144 128 - 320 -2144 128 352 -2144 112 320 -2144 112 320 -2144 128 352 -2144 128 320 - -2144 112 320 -2064 112 320 -2064 128 320 -2144 128 -320 -1696 -336 320 -1696 - -336 320 -1632 -336 -320 -1632 -336 320 -1696 72 488 -1696 72 488 -1632 72 - 320 -1632 72; - setAttr -s 570 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:497]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0 314 313 0 313 312 0 312 314 0 - 315 314 0 312 315 0 318 317 0 317 316 - 0 316 318 0 319 318 0 316 319 0 322 - 321 0 321 320 0 320 322 0 323 322 0 - 320 323 0 326 325 0 325 324 0 324 326 - 0 327 326 0 324 327 0 330 329 0 329 - 328 0 328 330 0 331 330 0 328 331 0 - 334 333 0 333 332 0 332 334 0 335 334 - 0 332 335 0 338 337 0 337 336 0 336 - 338 0 339 338 0 336 339 0 342 341 0 - 341 340 0 340 342 0 343 342 0 340 343 - 0 346 345 0 345 344 0 344 346 0 347 - 346 0 344 347 0 350 349 0 349 348 0 - 348 350 0 351 350 0 348 351 0 354 353 - 0 353 352 0 352 354 0 355 354 0 352 - 355 0 358 357 0 357 356 0 356 358 0 - 359 358 0 356 359 0 362 361 0 361 360 - 0 360 362 0 363 362 0 360 363 0 366 - 365 0 365 364 0 364 366 0 367 366 0 - 364 367 0 370 369 0 369 368 0 368 370 - 0 371 370 0 368 371 0 374 373 0 373 - 372 0 372 374 0 375 374 0 372 375 0 - 378 377 0 377 376 0 376 378 0 379 378 - 0 376 379 0 382 381 0 381 380 0 380 - 382 0 383 382 0 380 383 0 386 385 0 - 385 384 0 384 386 0 387 386 0 384 387 - 0 390 389 0 389 388 0 388 390 0 391 - 390 0 388 391 0 394 393 0 393 392 0 - 392 394 0 395 394 0 392 395 0 398 397 - 0 397 396 0 396 398 0; - setAttr ".ed[498:569]" 399 398 0 396 399 0 402 - 401 0 401 400 0 400 402 0 403 402 0 - 400 403 0 406 405 0 405 404 0 404 406 - 0 407 406 0 404 407 0 410 409 0 409 - 408 0 408 410 0 411 410 0 408 411 0 - 414 413 0 413 412 0 412 414 0 415 414 - 0 412 415 0 418 417 0 417 416 0 416 - 418 0 419 418 0 416 419 0 422 421 0 - 421 420 0 420 422 0 423 422 0 420 423 - 0 426 425 0 425 424 0 424 426 0 427 - 426 0 424 427 0 430 429 0 429 428 0 - 428 430 0 431 430 0 428 431 0 434 433 - 0 433 432 0 432 434 0 435 434 0 432 - 435 0 438 437 0 437 436 0 436 438 0 - 439 438 0 436 439 0 442 441 0 441 440 - 0 440 442 0 443 442 0 440 443 0 446 - 445 0 445 444 0 444 446 0 447 446 0 - 444 447 0 450 449 0 449 448 0 448 450 - 0 451 450 0 448 451 0 454 453 0 453 - 452 0 452 454 0 455 454 0 452 455 0; - setAttr -s 684 ".n"; - setAttr ".n[0:165]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1; - setAttr ".n[166:331]" -type "float3" 0 0 -1 0 0 -1 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 -1 0 0 -1 0 0; - setAttr ".n[332:497]" -type "float3" -1 0 0 -1 0 0 -1 0 0 -1 0 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr ".n[498:663]" -type "float3" -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr ".n[664:683]" -type "float3" 0 -1 0 0 -1 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr -s 228 ".fc[0:227]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 - f 3 390 391 392 - mu 0 3 314 313 312 - f 3 393 -393 394 - mu 0 3 315 314 312 - f 3 395 396 397 - mu 0 3 318 317 316 - f 3 398 -398 399 - mu 0 3 319 318 316 - f 3 400 401 402 - mu 0 3 322 321 320 - f 3 403 -403 404 - mu 0 3 323 322 320 - f 3 405 406 407 - mu 0 3 326 325 324 - f 3 408 -408 409 - mu 0 3 327 326 324 - f 3 410 411 412 - mu 0 3 330 329 328 - f 3 413 -413 414 - mu 0 3 331 330 328 - f 3 415 416 417 - mu 0 3 334 333 332 - f 3 418 -418 419 - mu 0 3 335 334 332 - f 3 420 421 422 - mu 0 3 338 337 336 - f 3 423 -423 424 - mu 0 3 339 338 336 - f 3 425 426 427 - mu 0 3 342 341 340 - f 3 428 -428 429 - mu 0 3 343 342 340 - f 3 430 431 432 - mu 0 3 346 345 344 - f 3 433 -433 434 - mu 0 3 347 346 344 - f 3 435 436 437 - mu 0 3 350 349 348 - f 3 438 -438 439 - mu 0 3 351 350 348 - f 3 440 441 442 - mu 0 3 354 353 352 - f 3 443 -443 444 - mu 0 3 355 354 352 - f 3 445 446 447 - mu 0 3 358 357 356 - f 3 448 -448 449 - mu 0 3 359 358 356 - f 3 450 451 452 - mu 0 3 362 361 360 - f 3 453 -453 454 - mu 0 3 363 362 360 - f 3 455 456 457 - mu 0 3 366 365 364 - f 3 458 -458 459 - mu 0 3 367 366 364 - f 3 460 461 462 - mu 0 3 370 369 368 - f 3 463 -463 464 - mu 0 3 371 370 368 - f 3 465 466 467 - mu 0 3 374 373 372 - f 3 468 -468 469 - mu 0 3 375 374 372 - f 3 470 471 472 - mu 0 3 378 377 376 - f 3 473 -473 474 - mu 0 3 379 378 376 - f 3 475 476 477 - mu 0 3 382 381 380 - f 3 478 -478 479 - mu 0 3 383 382 380 - f 3 480 481 482 - mu 0 3 386 385 384 - f 3 483 -483 484 - mu 0 3 387 386 384 - f 3 485 486 487 - mu 0 3 390 389 388 - f 3 488 -488 489 - mu 0 3 391 390 388 - f 3 490 491 492 - mu 0 3 394 393 392 - f 3 493 -493 494 - mu 0 3 395 394 392 - f 3 495 496 497 - mu 0 3 398 397 396 - f 3 498 -498 499 - mu 0 3 399 398 396 - f 3 500 501 502 - mu 0 3 402 401 400 - f 3 503 -503 504 - mu 0 3 403 402 400 - f 3 505 506 507 - mu 0 3 406 405 404 - f 3 508 -508 509 - mu 0 3 407 406 404 - f 3 510 511 512 - mu 0 3 410 409 408 - f 3 513 -513 514 - mu 0 3 411 410 408 - f 3 515 516 517 - mu 0 3 414 413 412 - f 3 518 -518 519 - mu 0 3 415 414 412 - f 3 520 521 522 - mu 0 3 418 417 416 - f 3 523 -523 524 - mu 0 3 419 418 416 - f 3 525 526 527 - mu 0 3 422 421 420 - f 3 528 -528 529 - mu 0 3 423 422 420 - f 3 530 531 532 - mu 0 3 426 425 424 - f 3 533 -533 534 - mu 0 3 427 426 424 - f 3 535 536 537 - mu 0 3 430 429 428 - f 3 538 -538 539 - mu 0 3 431 430 428 - f 3 540 541 542 - mu 0 3 434 433 432 - f 3 543 -543 544 - mu 0 3 435 434 432 - f 3 545 546 547 - mu 0 3 438 437 436 - f 3 548 -548 549 - mu 0 3 439 438 436 - f 3 550 551 552 - mu 0 3 442 441 440 - f 3 553 -553 554 - mu 0 3 443 442 440 - f 3 555 556 557 - mu 0 3 446 445 444 - f 3 558 -558 559 - mu 0 3 447 446 444 - f 3 560 561 562 - mu 0 3 450 449 448 - f 3 563 -563 564 - mu 0 3 451 450 448 - f 3 565 566 567 - mu 0 3 454 453 452 - f 3 568 -568 569 - mu 0 3 455 454 452 ; -createNode transform -n "m14" -p "celing"; -createNode mesh -n "polySurfaceShape5" -p "m14"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 57.000114 - 0.37496901 58.000126 0.37496901 58.000126 3.8751931 57.000114 3.8751931 57.000328 - 0.37496901 57.99987 0.37496901 57.99987 3.8751931 57.000328 3.8751931 56.999943 - 0.37496901 58.000111 0.37496901 58.000111 3.8751931 56.999943 3.8751931 76.000015 - 0.37496901 75.000015 0.37496901 75.000015 3.8751931 76.000015 3.8751931; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" 271.99677 -2144 -240 239.99648 -2144 - -240 239.99648 -1696 -240 271.99677 -1696 -240 -240.0105 -2144 -240 -271.99585 - -2144 -240 -271.99585 -1696 -240 -240.0105 -1696 -240 16.001865 -2144 -240 - -16.00359 -2144 -240 -16.00359 -1696 -240 16.001865 -1696 -240 320 -2144 - 112 288 -2144 112 288 -1696 112 320 -1696 112; - setAttr -s 20 ".ed[0:19]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0; - setAttr -s 24 ".n[0:23]" -type "float3" 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1; - setAttr -s 8 ".fc[0:7]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 ; -createNode transform -n "m16" -p "celing"; -createNode mesh -n "polySurfaceShape6" -p "m16"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 100 ".uvst[0].uvsp[0:99]" -type "float2" 6.625 -15.751068 - 6.625 -15.501053 7.875 -15.501053 7.875 -15.751068 6.625 17.501053 6.625 - 17.751068 7.875 17.751068 7.875 17.501053 -32.5 2.125073 -33 2.125073 -33 - 4.0001931 -32.5 4.0001931 7.875 2.125073 6.625 2.125073 6.625 4.0001931 7.875 - 4.0001931 34 2.125073 33.5 2.125073 33.5 4.0001931 34 4.0001931 -5.625 2.125073 - -6.875 2.125073 -6.875 4.0001931 -5.625 4.0001931 6 -15.751068 6 -15.501053 - 6.625 -15.501053 6.625 -15.751068 6 17.501053 6 17.751068 6.625 17.751068 - 6.625 17.501053 -32.5 0.49996901 -33 0.49996901 -33 4.0001931 -32.5 4.0001931 - 6.625 0.49996901 6 0.49996901 6 4.0001931 6.625 4.0001931 34 0.49996901 33.5 - 0.49996901 33.5 4.0001931 34 4.0001931 -5 0.49996901 -5.625 0.49996901 -5.625 - 4.0001931 -5 4.0001931 34 0.49996901 33.5 0.49996901 33.5 4.0001931 34 4.0001931 - 2.5 -15.751057 2.5 -15.501041 8.5 -15.501041 8.5 -15.751057 2.5 17.501043 - 2.5 17.751059 8.5 17.751059 8.5 17.501043 8.5 0.49996901 2.5 0.49996901 2.5 - 4.0001931 8.5 4.0001931 34 0.49996901 33.5 0.49996901 33.5 4.0001931 34 4.0001931 - -1.5 0.49996901 -7.5 0.49996901 -7.5 4.0001931 -1.5 4.0001931 27.25 19.751202 - 27.25 20.751265 27.875 20.751265 27.875 19.751202 27.25 13.750817 27.25 14.750881 - 27.875 14.750881 27.875 13.750817 36 0.49996901 34 0.49996901 34 4.0001931 - 36 4.0001931 27.875 0.49996901 27.25 0.49996901 27.25 4.0001931 27.875 4.0001931 - 24 0.49996901 22 0.49996901 22 4.0001931 24 4.0001931 30.75 0.49996901 30.125 - 0.49996901 30.125 4.0001931 30.75 4.0001931 30.75 0.49996901 30.125 0.49996901 - 30.125 4.0001931 30.75 4.0001931; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 100 ".vt[0:99]" -320 -1936 -152 -288 -1936 -152 - -288 -1936 -232 -320 -1936 -232 -288 -1696 -152 -320 -1696 -152 -320 -1696 - -232 -288 -1696 -232 -288 -1936 -152 -320 -1936 -152 -320 -1696 -152 -288 - -1696 -152 -288 -1936 -232 -288 -1936 -152 -288 -1696 -152 -288 -1696 -232 - -320 -1936 -232 -288 -1936 -232 -288 -1696 -232 -320 -1696 -232 -320 -1936 - -152 -320 -1936 -232 -320 -1696 -232 -320 -1696 -152 -320 -2144 -232 -288 - -2144 -232 -288 -2144 -272 -320 -2144 -272 -288 -1696 -232 -320 -1696 -232 - -320 -1696 -272 -288 -1696 -272 -288 -2144 -232 -320 -2144 -232 -320 -1696 - -232 -288 -1696 -232 -288 -2144 -272 -288 -2144 -232 -288 -1696 -232 -288 - -1696 -272 -320 -2144 -272 -288 -2144 -272 -288 -1696 -272 -320 -1696 -272 - -320 -2144 -232 -320 -2144 -272 -320 -1696 -272 -320 -1696 -232 -320 -2144 - -152 -288 -2144 -152 -288 -1696 -152 -320 -1696 -152 288 -2144 112 320 -2144 - 112 320 -2144 -272 288 -2144 -272 320 -1696 112 288 -1696 112 288 -1696 -272 - 320 -1696 -272 320 -2144 -272 320 -2144 112 320 -1696 112 320 -1696 -272 - 288 -2144 -272 320 -2144 -272 320 -1696 -272 288 -1696 -272 288 -2144 112 - 288 -2144 -272 288 -1696 -272 288 -1696 112 320 -2144 112 448 -2144 112 448 - -2144 72 320 -2144 72 448 -1696 112 320 -1696 112 320 -1696 72 448 -1696 - 72 448 -2144 112 320 -2144 112 320 -1696 112 448 -1696 112 448 -2144 72 448 - -2144 112 448 -1696 112 448 -1696 72 320 -2144 72 448 -2144 72 448 -1696 - 72 320 -1696 72 320 -2144 112 320 -2144 72 320 -1696 72 320 -1696 112 448 - -2144 72 488 -2144 72 488 -1696 72 448 -1696 72; - setAttr -s 125 ".ed[0:124]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0 30 29 0 29 28 0 28 30 0 31 - 30 0 28 31 0 34 33 0 33 32 0 - 32 34 0 35 34 0 32 35 0 38 37 - 0 37 36 0 36 38 0 39 38 0 36 - 39 0 42 41 0 41 40 0 40 42 0 - 43 42 0 40 43 0 46 45 0 45 44 - 0 44 46 0 47 46 0 44 47 0 50 - 49 0 49 48 0 48 50 0 51 50 0 - 48 51 0 54 53 0 53 52 0 52 54 - 0 55 54 0 52 55 0 58 57 0 57 - 56 0 56 58 0 59 58 0 56 59 0 - 62 61 0 61 60 0 60 62 0 63 62 - 0 60 63 0 66 65 0 65 64 0 64 - 66 0 67 66 0 64 67 0 70 69 0 - 69 68 0 68 70 0 71 70 0 68 71 - 0 74 73 0 73 72 0 72 74 0 75 - 74 0 72 75 0 78 77 0 77 76 0 - 76 78 0 79 78 0 76 79 0 82 81 - 0 81 80 0 80 82 0 83 82 0 80 - 83 0 86 85 0 85 84 0 84 86 0 - 87 86 0 84 87 0 90 89 0 89 88 - 0 88 90 0 91 90 0 88 91 0 94 - 93 0 93 92 0 92 94 0 95 94 0 - 92 95 0 98 97 0 97 96 0 96 98 - 0 99 98 0 96 99 0; - setAttr -s 150 ".n[0:149]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1; - setAttr -s 50 ".fc[0:49]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 ; -createNode transform -n "m18" -p "celing"; -createNode mesh -n "polySurfaceShape7" -p "m18"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 0 0 1 0 - 0 0.33333299 1 0.33333299 0 0.66666698 1 0.66666698 0 1 1 1 0 0 1 0 0 0.33333299 - 1 0.33333299 0 0.66666698 1 0.66666698 0 1 1 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" -184 -1936 -303 -72 -1936 -303 -184 - -1898.6666 -299.44446 -72 -1898.6666 -299.44446 -184 -1861.3334 -288.77777 - -72 -1861.3334 -288.77777 -184 -1824 -271 -72 -1824 -271 72 -1936 -303 184 - -1936 -303 72 -1898.6666 -299.44446 184 -1898.6666 -299.44446 72 -1861.3334 - -288.77777 184 -1861.3334 -288.77777 72 -1824 -271 184 -1824 -271; - setAttr -s 26 ".ed[0:25]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0 4 - 2 0 3 4 0 3 5 0 5 4 0 - 6 4 0 5 6 0 5 7 0 7 6 - 0 10 8 0 8 9 0 9 10 0 9 - 11 0 11 10 0 12 10 0 11 12 0 - 11 13 0 13 12 0 14 12 0 13 14 - 0 13 15 0 15 14 0; - setAttr -s 36 ".n[0:35]" -type "float3" -2.0881986e-007 -0.094808631 - 0.9954955 -2.0881986e-007 -0.094808631 0.9954955 -2.0881986e-007 -0.094808631 - 0.9954955 -2.0882014e-007 -0.094808765 0.9954955 -2.0882014e-007 -0.094808765 - 0.9954955 -2.0882014e-007 -0.094808765 0.9954955 1.4555302e-007 -0.27472287 - 0.96152347 1.4555302e-007 -0.27472287 0.96152347 1.4555302e-007 -0.27472287 - 0.96152347 1.4555263e-007 -0.27472216 0.96152365 1.4555263e-007 -0.27472216 - 0.96152365 1.4555263e-007 -0.27472216 0.96152365 6.8335829e-008 -0.42993209 - 0.90286124 6.8335829e-008 -0.42993209 0.90286124 6.8335829e-008 -0.42993209 - 0.90286124 6.8335908e-008 -0.42993256 0.902861 6.8335908e-008 -0.42993256 - 0.902861 6.8335908e-008 -0.42993256 0.902861 -2.0881986e-007 -0.094808631 - 0.9954955 -2.0881986e-007 -0.094808631 0.9954955 -2.0881986e-007 -0.094808631 - 0.9954955 -2.0882014e-007 -0.094808765 0.9954955 -2.0882014e-007 -0.094808765 - 0.9954955 -2.0882014e-007 -0.094808765 0.9954955 1.4555302e-007 -0.27472287 - 0.96152347 1.4555302e-007 -0.27472287 0.96152347 1.4555302e-007 -0.27472287 - 0.96152347 1.4555263e-007 -0.27472216 0.96152365 1.4555263e-007 -0.27472216 - 0.96152365 1.4555263e-007 -0.27472216 0.96152365 6.8335829e-008 -0.42993209 - 0.90286124 6.8335829e-008 -0.42993209 0.90286124 6.8335829e-008 -0.42993209 - 0.90286124 6.8335908e-008 -0.42993256 0.902861 6.8335908e-008 -0.42993256 - 0.902861 6.8335908e-008 -0.42993256 0.902861; - setAttr -s 12 ".fc[0:11]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 - f 3 5 -5 6 - mu 0 3 4 2 3 - f 3 -7 7 8 - mu 0 3 4 3 5 - f 3 9 -9 10 - mu 0 3 6 4 5 - f 3 -11 11 12 - mu 0 3 6 5 7 - f 3 13 14 15 - mu 0 3 10 8 9 - f 3 -16 16 17 - mu 0 3 10 9 11 - f 3 18 -18 19 - mu 0 3 12 10 11 - f 3 -20 20 21 - mu 0 3 12 11 13 - f 3 22 -22 23 - mu 0 3 14 12 13 - f 3 -24 24 25 - mu 0 3 14 13 15 ; -createNode transform -n "m20" -p "celing"; -createNode mesh -n "polySurfaceShape8" -p "m20"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 456 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 1 0 0 0 0 1 1 1 5 - 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 111 15 109 - 15 109 16 111 16 0 0 1 0 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 - 0 0 5 0 5 1 0 1 0 0 5 0 119 0 121 0 121 1 119 1 1 0 0 0 0 1 1 1 5 0 0 0 0 - 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 127 15 125 15 125 16 - 127 16 1 0 0 0 0 1 1 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 - 0 0 0 0 1 5 1 127 59 125 59 125 60 127 60 1 0 0 0 0 1 1 1 5 0 0 0 0 1 5 1 - 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 127 49 125 49 125 50 127 - 50 0 0 1 0 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 - 1 0 0 5 0 119 0 121 0 121 1 119 1 0 0 1 0 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 1 - 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 119 0 121 0 121 1 119 1 1 0 0 0 0 - 1 1 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 111 - 49 109 49 109 50 111 50 1 0 0 0 0 1 1 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 - 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 111 59 109 59 109 60 111 60 0 0 1 0 1 1 0 1 - 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 103 0 105 - 0 105 1 103 1 0 0 1 0 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 1; - setAttr ".uvst[0].uvsp[250:455]" 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 - 0 5 0 103 0 105 0 105 1 103 1 1 0 0 0 0 1 1 1 5 3.1e-005 0 3.1e-005 0 1.000031 - 5 1.000031 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 127 15 125 15 - 125 16 127 16 1 0 0 0 0 1 1 1 5 3.1e-005 0 3.1e-005 0 1.000031 5 1.000031 - 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 5 0 0 0 0 1 5 1 127 15 125 15 125 16 127 - 16 0 0 1 0 1 1 0 1 5 0.99998498 0 0.99998498 0 -1.5e-005 5 -1.5e-005 5 1 - 0 1 0 0 5 0 5 0.99996901 0 0.99996901 0 -3.1e-005 5 -3.1e-005 5 1 0 1 0 0 - 5 0 125 -5 127 -5 127 -4 125 -4 0 1 1 1 1 0 0 0 5 -1.5e-005 0 -1.5e-005 0 - 0.99998498 5 0.99998498 5 0 0 0 0 1 5 1 5 -3.1e-005 0 -3.1e-005 0 0.99996901 - 5 0.99996901 5 0 0 0 0 1 5 1 127 -5 125 -5 125 -4 127 -4 0 0 1 0 1 1 0 1 - 5 1.000031 0 1.000031 0 3.1e-005 5 3.1e-005 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 - 0 5 1 0 1 0 0 5 0 127 16 125 16 125 15 127 15 0 0 1 0 1 1 0 1 5 1.000031 - 0 1.000031 0 3.1e-005 5 3.1e-005 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 - 0 0 5 0 127 16 125 16 125 15 127 15 0 0 1 0 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 - 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 103 0 105 0 105 1 103 1 0 0 1 0 - 1 1 0 1 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 5 1 0 1 0 0 5 0 103 - 0 105 0 105 1 103 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 456 ".vt"; - setAttr ".vt[0:165]" 96 -2064 128 64 -2064 128 64 -2064 112 96 - -2064 112 64 -2144 128 64 -2064 128 96 -2064 128 96 -2144 128 96 -2144 128 - 96 -2064 128 96 -2064 112 96 -2144 112 96 -2144 112 96 -2064 112 64 -2064 - 112 64 -2144 112 64 -2144 112 64 -2064 112 64 -2064 128 64 -2144 128 64 -2144 - 128 96 -2144 128 96 -2144 112 64 -2144 112 -64 -2064 128 -96 -2064 128 -96 - -2064 112 -64 -2064 112 -96 -2144 128 -96 -2064 128 -64 -2064 128 -64 -2144 - 128 -96 -2144 112 -96 -2064 112 -96 -2064 128 -96 -2144 128 -64 -2144 112 - -64 -2064 112 -96 -2064 112 -96 -2144 112 -64 -2144 128 -64 -2064 128 -64 - -2064 112 -64 -2144 112 -64 -2144 112 -96 -2144 112 -96 -2144 128 -64 -2144 - 128 -160 -2064 128 -192 -2064 128 -192 -2064 112 -160 -2064 112 -192 -2144 - 128 -192 -2064 128 -160 -2064 128 -160 -2144 128 -160 -2144 128 -160 -2064 - 128 -160 -2064 112 -160 -2144 112 -160 -2144 112 -160 -2064 112 -192 -2064 - 112 -192 -2144 112 -192 -2144 112 -192 -2064 112 -192 -2064 128 -192 -2144 - 128 -192 -2144 128 -160 -2144 128 -160 -2144 112 -192 -2144 112 -160 -2064 - -224 -192 -2064 -224 -192 -2064 -240 -160 -2064 -240 -192 -2144 -224 -192 - -2064 -224 -160 -2064 -224 -160 -2144 -224 -160 -2144 -224 -160 -2064 -224 - -160 -2064 -240 -160 -2144 -240 -160 -2144 -240 -160 -2064 -240 -192 -2064 - -240 -192 -2144 -240 -192 -2144 -240 -192 -2064 -240 -192 -2064 -224 -192 - -2144 -224 -192 -2144 -224 -160 -2144 -224 -160 -2144 -240 -192 -2144 -240 - -160 -2064 -144 -192 -2064 -144 -192 -2064 -160 -160 -2064 -160 -192 -2144 - -144 -192 -2064 -144 -160 -2064 -144 -160 -2144 -144 -160 -2144 -144 -160 - -2064 -144 -160 -2064 -160 -160 -2144 -160 -160 -2144 -160 -160 -2064 -160 - -192 -2064 -160 -192 -2144 -160 -192 -2144 -160 -192 -2064 -160 -192 -2064 - -144 -192 -2144 -144 -192 -2144 -144 -160 -2144 -144 -160 -2144 -160 -192 - -2144 -160 -64 -2064 -144 -96 -2064 -144 -96 -2064 -160 -64 -2064 -160 -96 - -2144 -144 -96 -2064 -144 -64 -2064 -144 -64 -2144 -144 -96 -2144 -160 -96 - -2064 -160 -96 -2064 -144 -96 -2144 -144 -64 -2144 -160 -64 -2064 -160 -96 - -2064 -160 -96 -2144 -160 -64 -2144 -144 -64 -2064 -144 -64 -2064 -160 -64 - -2144 -160 -64 -2144 -160 -96 -2144 -160 -96 -2144 -144 -64 -2144 -144 -64 - -2064 -224 -96 -2064 -224 -96 -2064 -240 -64 -2064 -240 -96 -2144 -224 -96 - -2064 -224 -64 -2064 -224 -64 -2144 -224 -96 -2144 -240 -96 -2064 -240 -96 - -2064 -224 -96 -2144 -224 -64 -2144 -240 -64 -2064 -240 -96 -2064 -240 -96 - -2144 -240 -64 -2144 -224 -64 -2064 -224 -64 -2064 -240 -64 -2144 -240 -64 - -2144 -240 -96 -2144 -240; - setAttr ".vt[166:331]" -96 -2144 -224 -64 -2144 -224 96 -2064 -144 - 64 -2064 -144 64 -2064 -160 96 -2064 -160 64 -2144 -144 64 -2064 -144 96 - -2064 -144 96 -2144 -144 96 -2144 -144 96 -2064 -144 96 -2064 -160 96 -2144 - -160 96 -2144 -160 96 -2064 -160 64 -2064 -160 64 -2144 -160 64 -2144 -160 - 64 -2064 -160 64 -2064 -144 64 -2144 -144 64 -2144 -144 96 -2144 -144 96 - -2144 -160 64 -2144 -160 96 -2064 -224 64 -2064 -224 64 -2064 -240 96 -2064 - -240 64 -2144 -224 64 -2064 -224 96 -2064 -224 96 -2144 -224 96 -2144 -224 - 96 -2064 -224 96 -2064 -240 96 -2144 -240 96 -2144 -240 96 -2064 -240 64 - -2064 -240 64 -2144 -240 64 -2144 -240 64 -2064 -240 64 -2064 -224 64 -2144 - -224 64 -2144 -224 96 -2144 -224 96 -2144 -240 64 -2144 -240 192 -2064 -224 - 160 -2064 -224 160 -2064 -240 192 -2064 -240 160 -2144 -224 160 -2064 -224 - 192 -2064 -224 192 -2144 -224 160 -2144 -240 160 -2064 -240 160 -2064 -224 - 160 -2144 -224 192 -2144 -240 192 -2064 -240 160 -2064 -240 160 -2144 -240 - 192 -2144 -224 192 -2064 -224 192 -2064 -240 192 -2144 -240 192 -2144 -240 - 160 -2144 -240 160 -2144 -224 192 -2144 -224 192 -2064 -144 160 -2064 -144 - 160 -2064 -160 192 -2064 -160 160 -2144 -144 160 -2064 -144 192 -2064 -144 - 192 -2144 -144 160 -2144 -160 160 -2064 -160 160 -2064 -144 160 -2144 -144 - 192 -2144 -160 192 -2064 -160 160 -2064 -160 160 -2144 -160 192 -2144 -144 - 192 -2064 -144 192 -2064 -160 192 -2144 -160 192 -2144 -160 160 -2144 -160 - 160 -2144 -144 192 -2144 -144 -256 -2064 128 -288 -2064 128 -288 -2064 112 - -256 -2064 112 -288 -2144 128 -288 -2064 128 -256 -2064 128 -256 -2144 128 - -256 -2144 128 -256 -2064 128 -256 -2064 112 -256 -2144 112 -256 -2144 112 - -256 -2064 112 -288 -2064 112 -288 -2144 112 -288 -2144 112 -288 -2064 112 - -288 -2064 128 -288 -2144 128 -288 -2144 128 -256 -2144 128 -256 -2144 112 - -288 -2144 112 -256 -2064 -224 -288 -2064 -224 -288 -2064 -240 -256 -2064 - -240 -288 -2144 -224 -288 -2064 -224 -256 -2064 -224 -256 -2144 -224 -256 - -2144 -224 -256 -2064 -224 -256 -2064 -240 -256 -2144 -240 -256 -2144 -240 - -256 -2064 -240 -288 -2064 -240 -288 -2144 -240 -288 -2144 -240 -288 -2064 - -240 -288 -2064 -224 -288 -2144 -224 -288 -2144 -224 -256 -2144 -224 -256 - -2144 -240 -288 -2144 -240 -288 -2064 -160 -256 -2064 -160 -256 -2064 -144 - -288 -2064 -144 -256 -2144 -160 -256 -2064 -160 -288 -2064 -160 -288 -2144 - -160 -256 -2144 -144 -256 -2064 -144 -256 -2064 -160 -256 -2144 -160 -288 - -2144 -144 -288 -2064 -144 -256 -2064 -144 -256 -2144 -144 -288 -2144 -160 - -288 -2064 -160 -288 -2064 -144 -288 -2144 -144; - setAttr ".vt[332:455]" -256 -2144 -160 -288 -2144 -160 -288 -2144 - -144 -256 -2144 -144 288 -2064 -144 256 -2064 -144 256 -2064 -160 288 -2064 - -160 288 -2144 -160 288 -2064 -160 256 -2064 -160 256 -2144 -160 256 -2144 - -160 256 -2064 -160 256 -2064 -144 256 -2144 -144 256 -2144 -144 256 -2064 - -144 288 -2064 -144 288 -2144 -144 288 -2144 -144 288 -2064 -144 288 -2064 - -160 288 -2144 -160 288 -2144 -160 256 -2144 -160 256 -2144 -144 288 -2144 - -144 288 -2064 -224 256 -2064 -224 256 -2064 -240 288 -2064 -240 256 -2144 - -224 256 -2064 -224 288 -2064 -224 288 -2144 -224 256 -2144 -240 256 -2064 - -240 256 -2064 -224 256 -2144 -224 288 -2144 -240 288 -2064 -240 256 -2064 - -240 256 -2144 -240 288 -2144 -224 288 -2064 -224 288 -2064 -240 288 -2144 - -240 288 -2144 -240 256 -2144 -240 256 -2144 -224 288 -2144 -224 288 -2064 - 128 256 -2064 128 256 -2064 112 288 -2064 112 256 -2144 128 256 -2064 128 - 288 -2064 128 288 -2144 128 256 -2144 112 256 -2064 112 256 -2064 128 256 - -2144 128 288 -2144 112 288 -2064 112 256 -2064 112 256 -2144 112 288 -2144 - 128 288 -2064 128 288 -2064 112 288 -2144 112 288 -2144 112 256 -2144 112 - 256 -2144 128 288 -2144 128 192 -2064 128 160 -2064 128 160 -2064 112 192 - -2064 112 160 -2144 128 160 -2064 128 192 -2064 128 192 -2144 128 160 -2144 - 112 160 -2064 112 160 -2064 128 160 -2144 128 192 -2144 112 192 -2064 112 - 160 -2064 112 160 -2144 112 192 -2144 128 192 -2064 128 192 -2064 112 192 - -2144 112 192 -2144 112 160 -2144 112 160 -2144 128 192 -2144 128 384 -2064 - 128 352 -2064 128 352 -2064 112 384 -2064 112 352 -2144 128 352 -2064 128 - 384 -2064 128 384 -2144 128 352 -2144 112 352 -2064 112 352 -2064 128 352 - -2144 128 384 -2144 112 384 -2064 112 352 -2064 112 352 -2144 112 384 -2144 - 128 384 -2064 128 384 -2064 112 384 -2144 112 384 -2144 112 352 -2144 112 - 352 -2144 128 384 -2144 128; - setAttr -s 570 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:497]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0 314 313 0 313 312 0 312 314 0 - 315 314 0 312 315 0 318 317 0 317 316 - 0 316 318 0 319 318 0 316 319 0 322 - 321 0 321 320 0 320 322 0 323 322 0 - 320 323 0 326 325 0 325 324 0 324 326 - 0 327 326 0 324 327 0 330 329 0 329 - 328 0 328 330 0 331 330 0 328 331 0 - 334 333 0 333 332 0 332 334 0 335 334 - 0 332 335 0 338 337 0 337 336 0 336 - 338 0 339 338 0 336 339 0 342 341 0 - 341 340 0 340 342 0 343 342 0 340 343 - 0 346 345 0 345 344 0 344 346 0 347 - 346 0 344 347 0 350 349 0 349 348 0 - 348 350 0 351 350 0 348 351 0 354 353 - 0 353 352 0 352 354 0 355 354 0 352 - 355 0 358 357 0 357 356 0 356 358 0 - 359 358 0 356 359 0 362 361 0 361 360 - 0 360 362 0 363 362 0 360 363 0 366 - 365 0 365 364 0 364 366 0 367 366 0 - 364 367 0 370 369 0 369 368 0 368 370 - 0 371 370 0 368 371 0 374 373 0 373 - 372 0 372 374 0 375 374 0 372 375 0 - 378 377 0 377 376 0 376 378 0 379 378 - 0 376 379 0 382 381 0 381 380 0 380 - 382 0 383 382 0 380 383 0 386 385 0 - 385 384 0 384 386 0 387 386 0 384 387 - 0 390 389 0 389 388 0 388 390 0 391 - 390 0 388 391 0 394 393 0 393 392 0 - 392 394 0 395 394 0 392 395 0 398 397 - 0 397 396 0 396 398 0; - setAttr ".ed[498:569]" 399 398 0 396 399 0 402 - 401 0 401 400 0 400 402 0 403 402 0 - 400 403 0 406 405 0 405 404 0 404 406 - 0 407 406 0 404 407 0 410 409 0 409 - 408 0 408 410 0 411 410 0 408 411 0 - 414 413 0 413 412 0 412 414 0 415 414 - 0 412 415 0 418 417 0 417 416 0 416 - 418 0 419 418 0 416 419 0 422 421 0 - 421 420 0 420 422 0 423 422 0 420 423 - 0 426 425 0 425 424 0 424 426 0 427 - 426 0 424 427 0 430 429 0 429 428 0 - 428 430 0 431 430 0 428 431 0 434 433 - 0 433 432 0 432 434 0 435 434 0 432 - 435 0 438 437 0 437 436 0 436 438 0 - 439 438 0 436 439 0 442 441 0 441 440 - 0 440 442 0 443 442 0 440 443 0 446 - 445 0 445 444 0 444 446 0 447 446 0 - 444 447 0 450 449 0 449 448 0 448 450 - 0 451 450 0 448 451 0 454 453 0 453 - 452 0 452 454 0 455 454 0 452 455 0; - setAttr -s 684 ".n"; - setAttr ".n[0:165]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1; - setAttr ".n[166:331]" -type "float3" 0 0 -1 0 0 -1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 1 0 0 1; - setAttr ".n[332:497]" -type "float3" 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0; - setAttr ".n[498:663]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 - -1 0 0 -1 0 0 -1 0 0; - setAttr ".n[664:683]" -type "float3" -1 0 0 -1 0 0 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr -s 228 ".fc[0:227]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 - f 3 390 391 392 - mu 0 3 314 313 312 - f 3 393 -393 394 - mu 0 3 315 314 312 - f 3 395 396 397 - mu 0 3 318 317 316 - f 3 398 -398 399 - mu 0 3 319 318 316 - f 3 400 401 402 - mu 0 3 322 321 320 - f 3 403 -403 404 - mu 0 3 323 322 320 - f 3 405 406 407 - mu 0 3 326 325 324 - f 3 408 -408 409 - mu 0 3 327 326 324 - f 3 410 411 412 - mu 0 3 330 329 328 - f 3 413 -413 414 - mu 0 3 331 330 328 - f 3 415 416 417 - mu 0 3 334 333 332 - f 3 418 -418 419 - mu 0 3 335 334 332 - f 3 420 421 422 - mu 0 3 338 337 336 - f 3 423 -423 424 - mu 0 3 339 338 336 - f 3 425 426 427 - mu 0 3 342 341 340 - f 3 428 -428 429 - mu 0 3 343 342 340 - f 3 430 431 432 - mu 0 3 346 345 344 - f 3 433 -433 434 - mu 0 3 347 346 344 - f 3 435 436 437 - mu 0 3 350 349 348 - f 3 438 -438 439 - mu 0 3 351 350 348 - f 3 440 441 442 - mu 0 3 354 353 352 - f 3 443 -443 444 - mu 0 3 355 354 352 - f 3 445 446 447 - mu 0 3 358 357 356 - f 3 448 -448 449 - mu 0 3 359 358 356 - f 3 450 451 452 - mu 0 3 362 361 360 - f 3 453 -453 454 - mu 0 3 363 362 360 - f 3 455 456 457 - mu 0 3 366 365 364 - f 3 458 -458 459 - mu 0 3 367 366 364 - f 3 460 461 462 - mu 0 3 370 369 368 - f 3 463 -463 464 - mu 0 3 371 370 368 - f 3 465 466 467 - mu 0 3 374 373 372 - f 3 468 -468 469 - mu 0 3 375 374 372 - f 3 470 471 472 - mu 0 3 378 377 376 - f 3 473 -473 474 - mu 0 3 379 378 376 - f 3 475 476 477 - mu 0 3 382 381 380 - f 3 478 -478 479 - mu 0 3 383 382 380 - f 3 480 481 482 - mu 0 3 386 385 384 - f 3 483 -483 484 - mu 0 3 387 386 384 - f 3 485 486 487 - mu 0 3 390 389 388 - f 3 488 -488 489 - mu 0 3 391 390 388 - f 3 490 491 492 - mu 0 3 394 393 392 - f 3 493 -493 494 - mu 0 3 395 394 392 - f 3 495 496 497 - mu 0 3 398 397 396 - f 3 498 -498 499 - mu 0 3 399 398 396 - f 3 500 501 502 - mu 0 3 402 401 400 - f 3 503 -503 504 - mu 0 3 403 402 400 - f 3 505 506 507 - mu 0 3 406 405 404 - f 3 508 -508 509 - mu 0 3 407 406 404 - f 3 510 511 512 - mu 0 3 410 409 408 - f 3 513 -513 514 - mu 0 3 411 410 408 - f 3 515 516 517 - mu 0 3 414 413 412 - f 3 518 -518 519 - mu 0 3 415 414 412 - f 3 520 521 522 - mu 0 3 418 417 416 - f 3 523 -523 524 - mu 0 3 419 418 416 - f 3 525 526 527 - mu 0 3 422 421 420 - f 3 528 -528 529 - mu 0 3 423 422 420 - f 3 530 531 532 - mu 0 3 426 425 424 - f 3 533 -533 534 - mu 0 3 427 426 424 - f 3 535 536 537 - mu 0 3 430 429 428 - f 3 538 -538 539 - mu 0 3 431 430 428 - f 3 540 541 542 - mu 0 3 434 433 432 - f 3 543 -543 544 - mu 0 3 435 434 432 - f 3 545 546 547 - mu 0 3 438 437 436 - f 3 548 -548 549 - mu 0 3 439 438 436 - f 3 550 551 552 - mu 0 3 442 441 440 - f 3 553 -553 554 - mu 0 3 443 442 440 - f 3 555 556 557 - mu 0 3 446 445 444 - f 3 558 -558 559 - mu 0 3 447 446 444 - f 3 560 561 562 - mu 0 3 450 449 448 - f 3 563 -563 564 - mu 0 3 451 450 448 - f 3 565 566 567 - mu 0 3 454 453 452 - f 3 568 -568 569 - mu 0 3 455 454 452 ; -createNode transform -n "m22" -p "celing"; -createNode mesh -n "polySurfaceShape9" -p "m22"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 196 ".uvst[0].uvsp[0:195]" -type "float2" 1 14 -0.25 - 14 -0.25 13 1 13 1 13 -0.25 13 -0.25 14 1 14 1 14 -0.25 14 -0.25 13 1 13 - -26 14 -26 13 -27 13 -27 14 1 -53 -0.25 -53 -0.25 -51 1 -51 1 13 -0.25 13 - -0.25 14 1 14 1 53 -0.25 53 -0.25 55 1 55 1 -12.005489 -0.25 -12.005489 -0.25 - -11.005746 1 -11.005746 31.5 -59.493378 31.5 -61.492867 31 -61.492867 31 - -59.493378 -27 13 -26 13 -26 14 -27 14 1 -51 -0.25 -51 -0.25 -53 1 -53 1 - 14 -0.25 14 -0.25 13 1 13 1 55 -0.25 55 -0.25 53 1 53 1 -11.004308 -0.25 - -11.004308 -0.25 -12.004052 1 -12.004052 30 33.48436 30 35.483849 29.5 35.483849 - 29.5 33.48436 -26 14 -26 13 -27 13 -27 14 1 -53 -0.25 -53 -0.25 -51 1 -51 - 1 13 -0.25 13 -0.25 14 1 14 1 53 -0.25 53 -0.25 55 1 55 1 -12.005371 -0.25 - -12.005371 -0.25 -11.005627 1 -11.005627 27.5 -51.495319 27.5 -53.494808 - 27 -53.494808 27 -51.495319 -27 13 -26 13 -26 14 -27 14 1 -51 -0.25 -51 -0.25 - -53 1 -53 1 14 -0.25 14 -0.25 13 1 13 1 55 -0.25 55 -0.25 53 1 53 1 -11.004373 - -0.25 -11.004373 -0.25 -12.004116 1 -12.004116 26 25.486315 26 27.485802 - 25.5 27.485802 25.5 25.486315 4.75 75.5 5.25 75.5 5.25 78 4.75 78 -27 11 - -27 10 -26 10 -26 11 4.75 75.499992 5.25 75.499992 5.25 77.999992 4.75 77.999992 - -60.25 77.999992 -60.75 77.999992 -60.75 75.499992 -60.25 75.499992 -29.5 - 78 -29.5 75.5 -28.5 75.5 -28.5 78 -26 141 -26 142 -27 142 -27 141 -27 78 - -27 75.5 -26 75.5 -26 78 -27 10 -27 11 -26 11 -26 10 4.75 77.999992 5.25 - 77.999992 5.25 75.499992 4.75 75.499992 -60.25 75.499992 -60.75 75.499992 - -60.75 77.999992 -60.25 77.999992 -28.5 78 -28.5 75.5 -29.5 75.5 -29.5 78 - -26 142 -26 141 -27 141 -27 142 -26 78 -26 75.5 -27 75.5 -27 78 -27.125 142.125 - -27.125 142 -25.875 142 -25.875 142.125 -27.125 10 -27.125 9.875 -25.875 - 9.875 -25.875 10 -66.25 78 -66.3125 78 -66.3125 75.5 -66.25 75.5 -25.875 - 78 -27.125 78 -27.125 75.5 -25.875 75.5 -0.1875 78 -0.25 78 -0.25 75.5 -0.1875 - 75.5 -39.375 78 -40.625 78 -40.625 75.5 -39.375 75.5 4.75 77.999992 5.25 - 77.999992 5.25 75.499992 4.75 75.499992 1 13 -0.25 13 -0.25 14 1 14 1 13 - -0.25 13 -0.25 14 1 14; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 196 ".vt"; - setAttr ".vt[0:165]" 96 -2144 128 96 -2064 128 64 -2064 128 64 - -2144 128 -64 -2144 128 -64 -2064 128 -96 -2064 128 -96 -2144 128 -160 -2144 - 128 -160 -2064 128 -192 -2064 128 -192 -2144 128 -160 -2064 -160 -192 -2064 - -160 -192 -2064 -224 -160 -2064 -224 -192 -2144 -224 -192 -2064 -224 -192 - -2064 -160 -192 -2144 -160 -192 -2144 -160 -192 -2064 -160 -160 -2064 -160 - -160 -2144 -160 -160 -2144 -160 -160 -2064 -160 -160 -2064 -224 -160 -2144 - -224 -160 -2144 -224 -160 -2064 -224 -192 -2064 -224 -192 -2144 -224 -192 - -2144 -224 -192 -2144 -160 -160 -2144 -160 -160 -2144 -224 -64 -2064 -224 - -64 -2064 -160 -96 -2064 -160 -96 -2064 -224 -64 -2144 -160 -64 -2064 -160 - -64 -2064 -224 -64 -2144 -224 -96 -2144 -160 -96 -2064 -160 -64 -2064 -160 - -64 -2144 -160 -96 -2144 -224 -96 -2064 -224 -96 -2064 -160 -96 -2144 -160 - -64 -2144 -224 -64 -2064 -224 -96 -2064 -224 -96 -2144 -224 -96 -2144 -224 - -96 -2144 -160 -64 -2144 -160 -64 -2144 -224 96 -2064 -160 64 -2064 -160 - 64 -2064 -224 96 -2064 -224 64 -2144 -224 64 -2064 -224 64 -2064 -160 64 - -2144 -160 64 -2144 -160 64 -2064 -160 96 -2064 -160 96 -2144 -160 96 -2144 - -160 96 -2064 -160 96 -2064 -224 96 -2144 -224 96 -2144 -224 96 -2064 -224 - 64 -2064 -224 64 -2144 -224 64 -2144 -224 64 -2144 -160 96 -2144 -160 96 - -2144 -224 192 -2064 -224 192 -2064 -160 160 -2064 -160 160 -2064 -224 192 - -2144 -160 192 -2064 -160 192 -2064 -224 192 -2144 -224 160 -2144 -160 160 - -2064 -160 192 -2064 -160 192 -2144 -160 160 -2144 -224 160 -2064 -224 160 - -2064 -160 160 -2144 -160 192 -2144 -224 192 -2064 -224 160 -2064 -224 160 - -2144 -224 160 -2144 -224 160 -2144 -160 192 -2144 -160 192 -2144 -224 -256 - -2064 128 -288 -2064 128 -288 -2144 128 -256 -2144 128 -256 -2064 -160 -288 - -2064 -160 -288 -2064 -224 -256 -2064 -224 -256 -2064 -224 -288 -2064 -224 - -288 -2144 -224 -256 -2144 -224 -256 -2144 -160 -288 -2144 -160 -288 -2064 - -160 -256 -2064 -160 -288 -2144 -224 -288 -2064 -224 -288 -2064 -160 -288 - -2144 -160 -256 -2144 -224 -288 -2144 -224 -288 -2144 -160 -256 -2144 -160 - -256 -2144 -160 -256 -2064 -160 -256 -2064 -224 -256 -2144 -224 288 -2064 - -160 256 -2064 -160 256 -2064 -224 288 -2064 -224 256 -2144 -224 288 -2144 - -224 288 -2064 -224 256 -2064 -224 256 -2064 -160 288 -2064 -160 288 -2144 - -160 256 -2144 -160 288 -2144 -160 288 -2064 -160 288 -2064 -224 288 -2144 - -224 288 -2144 -224 256 -2144 -224 256 -2144 -160 288 -2144 -160 256 -2144 - -224 256 -2064 -224 256 -2064 -160 256 -2144 -160 -292 -2144 -152 -288 -2144 - -152 -288 -2144 -232 -292 -2144 -232 -288 -2064 -152 -292 -2064 -152; - setAttr ".vt[166:195]" -292 -2064 -232 -288 -2064 -232 -288 -2144 - -152 -292 -2144 -152 -292 -2064 -152 -288 -2064 -152 -288 -2144 -232 -288 - -2144 -152 -288 -2064 -152 -288 -2064 -232 -292 -2144 -232 -288 -2144 -232 - -288 -2064 -232 -292 -2064 -232 -292 -2144 -152 -292 -2144 -232 -292 -2064 - -232 -292 -2064 -152 256 -2144 128 288 -2144 128 288 -2064 128 256 -2064 - 128 192 -2144 128 192 -2064 128 160 -2064 128 160 -2144 128 384 -2144 128 - 384 -2064 128 352 -2064 128 352 -2144 128; - setAttr -s 245 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:244]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0; - setAttr -s 294 ".n"; - setAttr ".n[0:165]" -type "float3" 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr ".n[166:293]" -type "float3" 0 0 -1 0 0 -1 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1; - setAttr -s 98 ".fc[0:97]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 ; -createNode transform -n "m24" -p "celing"; -createNode mesh -n "polySurfaceShape10" -p "m24"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 168 ".uvst[0].uvsp[0:167]" -type "float2" -26 25 -27 - 25 -27 26 -26 26 1 -107.00002 -0.25 -107.00002 -0.25 -103.00002 1 -103.00002 - 1 25 -0.25 25 -0.25 26 1 26 1 105 -0.25 105 -0.25 109 1 109 1 -24 -0.25 -24 - -0.25 -23 1 -23 31 -9 30 -9 30 -8 31 -8 -26 25 -27 25 -27 26 -26 26 1 -107 - -0.25 -107 -0.25 -103 1 -103 1 25 -0.25 25 -0.25 26 1 26 1 105 -0.25 105 - -0.25 109 1 109 1 -24 -0.25 -24 -0.25 -23 1 -23 31 25 30 25 30 26 31 26 -26 - 25 -27 25 -27 26 -26 26 1 -107 -0.25 -107 -0.25 -103 1 -103 1 25 -0.25 25 - -0.25 26 1 26 1 105 -0.25 105 -0.25 109 1 109 1 -24 -0.25 -24 -0.25 -23 1 - -23 31 35 30 35 30 36 31 36 -26 25 -27 25 -27 26 -26 26 1 -107 -0.25 -107 - -0.25 -103 1 -103 1 25 -0.25 25 -0.25 26 1 26 1 105 -0.25 105 -0.25 109 1 - 109 1 -24 -0.25 -24 -0.25 -23 1 -23 27 25 26 25 26 26 27 26 -26 25 -27 25 - -27 26 -26 26 1 -107 -0.25 -107 -0.25 -103 1 -103 1 25 -0.25 25 -0.25 26 - 1 26 1 105 -0.25 105 -0.25 109 1 109 1 -24 -0.25 -24 -0.25 -23 1 -23 27 35 - 26 35 26 36 27 36 -26 25 -27 25 -27 26 -26 26 1 -107 -0.25 -107 -0.25 -103 - 1 -103 1 25 -0.25 25 -0.25 26 1 26 1 105 -0.25 105 -0.25 109 1 109 1 -24 - -0.25 -24 -0.25 -23 1 -23 27 -9 26 -9 26 -8 27 -8 -26 25 -27 25 -27 26 -26 - 26 1 -107 -0.25 -107 -0.25 -103 1 -103 1 25 -0.25 25 -0.25 26 1 26 1 105 - -0.25 105 -0.25 109 1 109 1 -24 -0.25 -24 -0.25 -23 1 -23 27 -9 26 -9 26 - -8 27 -8; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 168 ".vt"; - setAttr ".vt[0:165]" -96 -2064 128 -160 -2064 128 -160 -2064 112 - -96 -2064 112 -160 -2144 128 -160 -2064 128 -96 -2064 128 -96 -2144 128 -96 - -2144 128 -96 -2064 128 -96 -2064 112 -96 -2144 112 -96 -2144 112 -96 -2064 - 112 -160 -2064 112 -160 -2144 112 -160 -2144 112 -160 -2064 112 -160 -2064 - 128 -160 -2144 128 -160 -2144 128 -96 -2144 128 -96 -2144 112 -160 -2144 - 112 -96 -2064 -144 -160 -2064 -144 -160 -2064 -160 -96 -2064 -160 -160 -2144 - -144 -160 -2064 -144 -96 -2064 -144 -96 -2144 -144 -96 -2144 -144 -96 -2064 - -144 -96 -2064 -160 -96 -2144 -160 -96 -2144 -160 -96 -2064 -160 -160 -2064 - -160 -160 -2144 -160 -160 -2144 -160 -160 -2064 -160 -160 -2064 -144 -160 - -2144 -144 -160 -2144 -144 -96 -2144 -144 -96 -2144 -160 -160 -2144 -160 - -96 -2064 -224 -160 -2064 -224 -160 -2064 -240 -96 -2064 -240 -160 -2144 - -224 -160 -2064 -224 -96 -2064 -224 -96 -2144 -224 -96 -2144 -224 -96 -2064 - -224 -96 -2064 -240 -96 -2144 -240 -96 -2144 -240 -96 -2064 -240 -160 -2064 - -240 -160 -2144 -240 -160 -2144 -240 -160 -2064 -240 -160 -2064 -224 -160 - -2144 -224 -160 -2144 -224 -96 -2144 -224 -96 -2144 -240 -160 -2144 -240 - 160 -2064 -144 96 -2064 -144 96 -2064 -160 160 -2064 -160 96 -2144 -144 96 - -2064 -144 160 -2064 -144 160 -2144 -144 160 -2144 -144 160 -2064 -144 160 - -2064 -160 160 -2144 -160 160 -2144 -160 160 -2064 -160 96 -2064 -160 96 - -2144 -160 96 -2144 -160 96 -2064 -160 96 -2064 -144 96 -2144 -144 96 -2144 - -144 160 -2144 -144 160 -2144 -160 96 -2144 -160 160 -2064 -224 96 -2064 - -224 96 -2064 -240 160 -2064 -240 96 -2144 -224 96 -2064 -224 160 -2064 -224 - 160 -2144 -224 160 -2144 -224 160 -2064 -224 160 -2064 -240 160 -2144 -240 - 160 -2144 -240 160 -2064 -240 96 -2064 -240 96 -2144 -240 96 -2144 -240 96 - -2064 -240 96 -2064 -224 96 -2144 -224 96 -2144 -224 160 -2144 -224 160 -2144 - -240 96 -2144 -240 160 -2064 128 96 -2064 128 96 -2064 112 160 -2064 112 - 96 -2144 128 96 -2064 128 160 -2064 128 160 -2144 128 160 -2144 128 160 -2064 - 128 160 -2064 112 160 -2144 112 160 -2144 112 160 -2064 112 96 -2064 112 - 96 -2144 112 96 -2144 112 96 -2064 112 96 -2064 128 96 -2144 128 96 -2144 - 128 160 -2144 128 160 -2144 112 96 -2144 112 448 -2064 128 384 -2064 128 - 384 -2064 112 448 -2064 112 384 -2144 128 384 -2064 128 448 -2064 128 448 - -2144 128 448 -2144 128 448 -2064 128 448 -2064 112 448 -2144 112 448 -2144 - 112 448 -2064 112 384 -2064 112 384 -2144 112 384 -2144 112 384 -2064 112 - 384 -2064 128 384 -2144 128 384 -2144 128 448 -2144 128; - setAttr ".vt[166:167]" 448 -2144 112 384 -2144 112; - setAttr -s 210 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:209]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0; - setAttr -s 252 ".n"; - setAttr ".n[0:165]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1; - setAttr ".n[166:251]" -type "float3" 0 0 -1 0 0 -1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0; - setAttr -s 84 ".fc[0:83]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 ; -createNode transform -n "m26" -p "celing"; -createNode mesh -n "polySurfaceShape11" -p "m26"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 8 ".uvst[0].uvsp[0:7]" -type "float2" 3.5001919 - 16.000957 3.5001919 16.50099 4.0002241 16.50099 4.0002241 16.000957 3.5001919 - 14.000829 3.5001919 14.500861 4.0002241 14.500861 4.0002241 14.000829; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 8 ".vt[0:7]" -96 -2064 -160 -160 -2064 -160 -160 - -2064 -224 -96 -2064 -224 160 -2064 -160 96 -2064 -160 96 -2064 -224 160 - -2064 -224; - setAttr -s 10 ".ed[0:9]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0; - setAttr -s 12 ".n[0:11]" -type "float3" 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0; - setAttr -s 4 ".fc[0:3]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 ; -createNode transform -n "m30" -p "celing"; -createNode mesh -n "polySurfaceShape13" -p "m30"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 488 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.96880502 32.34375 - 1.000057 32.28125 3.000185 32.28125 3.0314369 32.34375 3.0314369 32.34375 - 3.000185 32.28125 1.000057 32.28125 0.96880502 32.34375 -10.695675 3.390625 - -10.739872 3.390625 -10.739872 3.640625 -10.695675 3.640625 3.000185 3.390625 - 0.99997801 3.390625 0.99997801 3.640625 3.000185 3.640625 13.568483 3.390625 - 13.524286 3.390625 13.524286 3.640625 13.568483 3.640625 -0.96872902 3.390625 - -3.0314369 3.390625 -3.0314369 3.640625 -0.96872902 3.640625 1.000057 31.265625 - 0.96880502 31.203125 3.0314369 31.203125 3.000185 31.265625 0.96880502 31.203125 - 1.000057 31.265625 3.000185 31.265625 3.0314369 31.203125 -11.712209 3.390625 - -11.756406 3.390625 -11.756406 3.640625 -11.712209 3.640625 3.0314369 3.390625 - 0.96872902 3.390625 0.96872902 3.640625 3.0314369 3.640625 8.9277954 3.390625 - 8.8835983 3.390625 8.8835983 3.640625 8.9277954 3.640625 -0.99997801 3.390625 - -3.000185 3.390625 -3.000185 3.640625 -0.99997801 3.640625 -15.998971 5.28125 - -15.499029 5.28125 -15.467781 5.34375 -16.03022 5.34375 -15.499029 5.28125 - -15.998971 5.28125 -16.03022 5.34375 -15.467781 5.34375 -15.626022 3.390625 - -16.126028 3.390625 -16.126028 3.640625 -15.626022 3.640625 -8.8835983 3.390625 - -8.9277954 3.390625 -8.9277954 3.640625 -8.8835983 3.640625 16.15728 3.390625 - 15.594774 3.390625 15.594774 3.640625 16.15728 3.640625 -13.524286 3.390625 - -13.568483 3.390625 -13.568483 3.640625 -13.524286 3.640625 -16.022408 1.28125 - -15.459971 1.28125 -15.49122 1.34375 -15.991158 1.34375 -15.459971 1.28125 - -16.022408 1.28125 -15.991158 1.34375 -15.49122 1.34375 -15.594774 3.390625 - -16.15728 3.390625 -16.15728 3.640625 -15.594774 3.640625 11.756406 3.390625 - 11.712209 3.390625 11.712209 3.640625 11.756406 3.640625 16.126028 3.390625 - 15.626022 3.390625 15.626022 3.640625 16.126028 3.640625 10.739872 3.390625 - 10.695675 3.390625 10.695675 3.640625 10.739872 3.640625 13.750876 -0.3125 - 13.750876 0.9375 14.750941 0.9375 14.750941 -0.3125 1.000057 -0.3125 1.000057 - 0.9375 3.000185 0.9375 3.000185 -0.3125 -3.000185 -0.3125 -3.000185 0.9375 - -1.000057 0.9375 -1.000057 -0.3125 -3.000185 -0.3125 -3.000185 0.9375 -1.000057 - 0.9375 -1.000057 -0.3125 -14.750941 -0.3125 -14.750941 0.9375 -13.750876 - 0.9375 -13.750876 -0.3125 1.000057 -0.3125 1.000057 0.9375 3.000185 0.9375 - 3.000185 -0.3125 -16.022406 1.28125 -15.459932 1.28125 -15.49118 1.34375 - -15.991158 1.34375 -15.459932 1.28125 -16.022406 1.28125 -15.991158 1.34375 - -15.49118 1.34375 -15.594735 3.390625 -16.157282 3.390625 -16.157282 3.640625 - -15.594735 3.640625 11.756409 3.390625 11.712212 3.390625 11.712212 3.640625 - 11.756409 3.640625 16.126026 3.390625 15.625981 3.390625 15.625981 3.640625 - 16.126026 3.640625 10.739875 3.390625 10.695678 3.390625 10.695678 3.640625 - 10.739875 3.640625 -15.998971 5.28125 -15.49899 5.28125 -15.467742 5.34375 - -16.030218 5.34375 -15.49899 5.28125 -15.998971 5.28125 -16.030218 5.34375 - -15.467742 5.34375 -15.625983 3.390625 -16.126028 3.390625 -16.126028 3.640625 - -15.625983 3.640625 -8.8836002 3.390625 -8.9277973 3.390625 -8.9277973 3.640625 - -8.8836002 3.640625 16.15728 3.390625 15.594733 3.390625 15.594733 3.640625 - 16.15728 3.640625 -13.524289 3.390625 -13.568486 3.390625 -13.568486 3.640625 - -13.524289 3.640625 1.000057 31.265625 0.96880502 31.203125 3.0314369 31.203125 - 3.000185 31.265625 0.96880502 31.203125 1.000057 31.265625 3.000185 31.265625 - 3.0314369 31.203125 -11.712212 3.390625 -11.756409 3.390625 -11.756409 3.640625 - -11.712212 3.640625 3.0314369 3.390625 0.96872902 3.390625 0.96872902 3.640625 - 3.0314369 3.640625 8.9277973 3.390625 8.8836002 3.390625 8.8836002 3.640625 - 8.9277973 3.640625 -0.99997801 3.390625 -3.000185 3.390625 -3.000185 3.640625 - -0.99997801 3.640625 0.96880502 32.34375 1.000057 32.28125 3.000185 32.28125 - 3.0314369 32.34375 1.000057 32.28125 0.96880502 32.34375 3.0314369 32.34375 - 3.000185 32.28125 -10.695678 3.390625 -10.739875 3.390625 -10.739875 3.640625 - -10.695678 3.640625 3.000185 3.390625 0.99997801 3.390625 0.99997801 3.640625 - 3.000185 3.640625 13.568486 3.390625 13.524289 3.390625 13.524289 3.640625 - 13.568486 3.640625 -0.96872902 3.390625 -3.0314369 3.390625 -3.0314369 3.640625 - -0.96872902 3.640625 0.96880502 32.34375 1.000057 32.28125 3.000185 32.28125 - 3.0314369 32.34375 1.000057 32.28125 0.96880502 32.34375 3.0314369 32.34375 - 3.000185 32.28125 -10.695675 3.390625 -10.739872 3.390625 -10.739872 3.640625 - -10.695675 3.640625 3.000185 3.390625 0.99997801 3.390625 0.99997801 3.640625 - 3.000185 3.640625 13.568486 3.390625 13.524289 3.390625 13.524289 3.640625 - 13.568486 3.640625 -0.96872902 3.390625 -3.0314369 3.390625 -3.0314369 3.640625 - -0.96872902 3.640625 1.000057 31.265625 0.96880502 31.203125 3.0314369 31.203125 - 3.000185 31.265625 0.96880502 31.203125 1.000057 31.265625 3.000185 31.265625 - 3.0314369 31.203125 -11.712212 3.390625 -11.756409 3.390625; - setAttr ".uvst[0].uvsp[250:487]" -11.756409 3.640625 -11.712212 3.640625 - 3.0314369 3.390625 0.96872902 3.390625 0.96872902 3.640625 3.0314369 3.640625 - 8.9277945 3.390625 8.8835974 3.390625 8.8835974 3.640625 8.9277945 3.640625 - -0.99997801 3.390625 -3.000185 3.390625 -3.000185 3.640625 -0.99997801 3.640625 - -15.998972 5.28125 -15.499071 5.28125 -15.467823 5.34375 -16.03022 5.34375 - -15.499071 5.28125 -15.998972 5.28125 -16.03022 5.34375 -15.467823 5.34375 - -15.62606 3.390625 -16.126026 3.390625 -16.126026 3.640625 -15.62606 3.640625 - -8.8835974 3.390625 -8.9277945 3.390625 -8.9277945 3.640625 -8.8835974 3.640625 - 16.157276 3.390625 15.59481 3.390625 15.59481 3.640625 16.157276 3.640625 - -13.524289 3.390625 -13.568486 3.390625 -13.568486 3.640625 -13.524289 3.640625 - -16.022408 1.28125 -15.460014 1.28125 -15.491261 1.34375 -15.991159 1.34375 - -15.460014 1.28125 -16.022408 1.28125 -15.991159 1.34375 -15.491261 1.34375 - -15.594811 3.390625 -16.157278 3.390625 -16.157278 3.640625 -15.594811 3.640625 - 11.756409 3.390625 11.712212 3.390625 11.712212 3.640625 11.756409 3.640625 - 16.126024 3.390625 15.626059 3.390625 15.626059 3.640625 16.126024 3.640625 - 10.739872 3.390625 10.695675 3.390625 10.695675 3.640625 10.739872 3.640625 - -16.022413 1.28125 -15.45998 1.28125 -15.491228 1.34375 -15.991165 1.34375 - -15.45998 1.28125 -16.022413 1.28125 -15.991165 1.34375 -15.491228 1.34375 - -15.594771 3.390625 -16.157276 3.390625 -16.157276 3.640625 -15.594771 3.640625 - 11.756403 3.390625 11.712206 3.390625 11.712206 3.640625 11.756403 3.640625 - 16.126022 3.390625 15.626018 3.390625 15.626018 3.640625 16.126022 3.640625 - 10.739871 3.390625 10.695674 3.390625 10.695674 3.640625 10.739871 3.640625 - -15.998978 5.28125 -15.499038 5.28125 -15.46779 5.34375 -16.030226 5.34375 - -15.46779 5.34375 -15.499038 5.28125 -15.998978 5.28125 -16.030226 5.34375 - -15.626019 3.390625 -16.126024 3.390625 -16.126024 3.640625 -15.626019 3.640625 - -8.8835964 3.390625 -8.9277945 3.390625 -8.9277945 3.640625 -8.8835964 3.640625 - 16.157274 3.390625 15.594769 3.390625 15.594769 3.640625 16.157274 3.640625 - -13.524282 3.390625 -13.56848 3.390625 -13.56848 3.640625 -13.524282 3.640625 - 1.000057 31.265625 0.96880502 31.203125 3.0314369 31.203125 3.000185 31.265625 - 0.96880502 31.203125 1.000057 31.265625 3.000185 31.265625 3.0314369 31.203125 - -11.712206 3.390625 -11.756403 3.390625 -11.756403 3.640625 -11.712206 3.640625 - 3.0314369 3.390625 0.96872902 3.390625 0.96872902 3.640625 3.0314369 3.640625 - 8.9277945 3.390625 8.8835964 3.390625 8.8835964 3.640625 8.9277945 3.640625 - -0.99997801 3.390625 -3.000185 3.390625 -3.000185 3.640625 -0.99997801 3.640625 - 0.96880502 32.34375 1.000057 32.28125 3.000185 32.28125 3.0314369 32.34375 - 1.000057 32.28125 0.96880502 32.34375 3.0314369 32.34375 3.000185 32.28125 - -10.695674 3.390625 -10.739871 3.390625 -10.739871 3.640625 -10.695674 3.640625 - 3.000185 3.390625 0.99997801 3.390625 0.99997801 3.640625 3.000185 3.640625 - 13.56848 3.390625 13.524282 3.390625 13.524282 3.640625 13.56848 3.640625 - -0.96872902 3.390625 -3.0314369 3.390625 -3.0314369 3.640625 -0.96872902 - 3.640625 16.00102 -0.3125 15.751005 -0.3125 15.751005 0.9375 16.00102 0.9375 - 16.000994 0.9375 15.750978 0.9375 15.750978 -0.3125 16.000994 -0.3125 16.001022 - -0.3125 15.751007 -0.3125 15.751007 0.9375 16.001022 0.9375 16.000994 0.9375 - 15.750978 0.9375 15.750978 -0.3125 16.000994 -0.3125 16.000994 0.9375 15.750978 - 0.9375 15.750978 -0.3125 16.000994 -0.3125 16.001022 -0.3125 15.751007 -0.3125 - 15.751007 0.9375 16.001022 0.9375 16.001261 0.9375 15.751245 0.9375 15.751245 - -0.3125 16.001261 -0.3125 16.002811 -0.3125 15.752796 -0.3125 15.752796 0.9375 - 16.002811 0.9375 16.002811 -0.3125 15.752796 -0.3125 15.752796 0.9375 16.002811 - 0.9375 16.001261 0.9375 15.751245 0.9375 15.751245 -0.3125 16.001261 -0.3125 - -0.49996901 -12.659086 -0.49996901 -12.100069 2.9998069 -12.100069 2.9998069 - -12.659086 -0.49996901 -12.097698 -0.49996901 -12.656714 2.9998069 -12.656714 - 2.9998069 -12.097698 -0.49996901 -12.659032 -0.49996901 -12.100015 2.9998069 - -12.100015 2.9998069 -12.659032 -0.49996901 -12.097642 -0.49996901 -12.656659 - 2.9998069 -12.656659 2.9998069 -12.097642 -0.49996901 -12.659141 -0.49996901 - -12.100124 2.9998069 -12.100124 2.9998069 -12.659141 -0.49996901 -12.097753 - -0.49996901 -12.65677 2.9998069 -12.65677 2.9998069 -12.097753 16.002811 - -0.3125 15.752796 -0.3125 15.752796 0.9375 16.002811 0.9375 16.001261 0.9375 - 15.751245 0.9375 15.751245 -0.3125 16.001261 -0.3125 16.001261 0.9375 15.751245 - 0.9375 15.751245 -0.3125 16.001261 -0.3125 16.00281 -0.3125 15.752793 -0.3125 - 15.752793 0.9375 16.00281 0.9375; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 488 ".vt"; - setAttr ".vt[0:165]" -244 -1864 116 -240 -1864 112 -240 -1864 -144 - -244 -1864 -148 -244 -1848 -148 -240 -1848 -144 -240 -1848 112 -244 -1848 - 116 -240 -1864 112 -244 -1864 116 -244 -1848 116 -240 -1848 112 -240 -1864 - -144.00002 -240 -1864 112.01013 -240 -1848 112.01013 -240 -1848 -144.00002 - -244 -1864 -148 -240 -1864 -144 -240 -1848 -144 -244 -1848 -148 -244 -1864 - 116.0097 -244 -1864 -148 -244 -1848 -148 -244 -1848 116.0097 -176 -1864 112 - -172 -1864 116 -172 -1864 -148.00002 -176 -1864 -144.00002 -172 -1848 116 - -176 -1848 112 -176 -1848 -144.00002 -172 -1848 -148.00002 -172 -1864 116 - -176 -1864 112 -176 -1848 112 -172 -1848 116 -172 -1864 -148.00002 -172 -1864 - 116.0097 -172 -1848 116.0097 -172 -1848 -148.00002 -176 -1864 -144 -172 -1864 - -148 -172 -1848 -148 -176 -1848 -144 -176 -1864 112.01013 -176 -1864 -144.00002 - -176 -1848 -144.00002 -176 -1848 112.01013 -240 -1864 -144 -176.0033 -1864 - -144 -172.0033 -1864 -148 -244 -1864 -148 -176.0033 -1848 -144 -240 -1848 - -144 -244 -1848 -148 -172.0033 -1848 -148 -176.0033 -1864 -144 -240 -1864 - -144 -240 -1848 -144 -176.0033 -1848 -144 -172 -1864 -148 -176 -1864 -144 - -176 -1848 -144 -172 -1848 -148 -244 -1864 -148 -172.00372 -1864 -148 -172.00372 - -1848 -148 -244 -1848 -148 -240 -1864 -144 -244 -1864 -148 -244 -1848 -148 - -240 -1848 -144 -244 -1864 116 -172.00372 -1864 116 -176.00372 -1864 112 - -240 -1864 112 -172.00372 -1848 116 -244 -1848 116 -240 -1848 112 -176.00372 - -1848 112 -172.00372 -1864 116 -244 -1864 116 -244 -1848 116 -172.00372 -1848 - 116 -176 -1864 112 -172 -1864 116 -172 -1848 116 -176 -1848 112 -240 -1864 - 112 -176.0033 -1864 112 -176.0033 -1848 112 -240 -1848 112 -244 -1864 116 - -240 -1864 112 -240 -1848 112 -244 -1848 116 64 -2144 112 64 -2064 112 -64 - -2064 112 -64 -2144 112 -80 -2144 112 -80 -2064 112 -80 -2064 -144 -80 -2144 - -144 -176 -2144 -144 -176 -2064 -144 -176 -2064 112 -176 -2144 112 80 -2144 - -144 80 -2064 -144 80 -2064 112 80 -2144 112 -64 -2144 -144 -64 -2064 -144 - 64 -2064 -144 64 -2144 -144 176 -2144 112 176 -2064 112 176 -2064 -144 176 - -2144 -144 -84 -1864 116 -11.998718 -1864 116 -15.998718 -1864 112 -80 -1864 - 112 -11.998718 -1848 116 -84 -1848 116 -80 -1848 112 -15.998718 -1848 112 - -11.998718 -1864 116 -84 -1864 116 -84 -1848 116 -11.998718 -1848 116 -16 - -1864 112 -12 -1864 116 -12 -1848 116 -16 -1848 112 -80 -1864 112 -15.998291 - -1864 112 -15.998291 -1848 112 -80 -1848 112 -84 -1864 116 -80 -1864 112 - -80 -1848 112 -84 -1848 116 -80 -1864 -144 -15.998291 -1864 -144 -11.998291 - -1864 -148 -84 -1864 -148 -15.998291 -1848 -144 -80 -1848 -144 -84 -1848 - -148 -11.998291 -1848 -148 -15.998291 -1864 -144 -80 -1864 -144 -80 -1848 - -144 -15.998291 -1848 -144 -12 -1864 -148 -16 -1864 -144 -16 -1848 -144 -12 - -1848 -148 -84 -1864 -148 -11.998718 -1864 -148 -11.998718 -1848 -148 -84 - -1848 -148 -80 -1864 -144 -84 -1864 -148; - setAttr ".vt[166:331]" -84 -1848 -148 -80 -1848 -144 -16 -1864 112 - -12 -1864 116 -12 -1864 -148.00002 -16 -1864 -144.00002 -12 -1848 116 -16 - -1848 112 -16 -1848 -144.00002 -12 -1848 -148.00002 -12 -1864 116 -16 -1864 - 112 -16 -1848 112 -12 -1848 116 -12 -1864 -148 -12 -1864 116.0097 -12 -1848 - 116.0097 -12 -1848 -148 -16 -1864 -144 -12 -1864 -148 -12 -1848 -148 -16 - -1848 -144 -16 -1864 112.01013 -16 -1864 -144.00002 -16 -1848 -144.00002 - -16 -1848 112.01013 -84 -1864 116 -80 -1864 112 -80 -1864 -144 -84 -1864 - -148 -80 -1848 112 -84 -1848 116 -84 -1848 -148 -80 -1848 -144 -80 -1864 - 112 -84 -1864 116 -84 -1848 116 -80 -1848 112 -80 -1864 -144.00002 -80 -1864 - 112.01013 -80 -1848 112.01013 -80 -1848 -144.00002 -84 -1864 -148 -80 -1864 - -144 -80 -1848 -144 -84 -1848 -148 -84 -1864 116.0097 -84 -1864 -148 -84 - -1848 -148 -84 -1848 116.0097 12 -1864 116 16 -1864 112 16 -1864 -144 12 - -1864 -148 16 -1848 112 12 -1848 116 12 -1848 -148 16 -1848 -144 16 -1864 - 112 12 -1864 116 12 -1848 116 16 -1848 112 16 -1864 -144.00002 16 -1864 112.01013 - 16 -1848 112.01013 16 -1848 -144.00002 12 -1864 -148 16 -1864 -144 16 -1848 - -144 12 -1848 -148 12 -1864 116.0097 12 -1864 -148 12 -1848 -148 12 -1848 - 116.0097 80 -1864 112 84 -1864 116 84 -1864 -148.00002 80 -1864 -144.00002 - 84 -1848 116 80 -1848 112 80 -1848 -144.00002 84 -1848 -148.00002 84 -1864 - 116 80 -1864 112 80 -1848 112 84 -1848 116 84 -1864 -148 84 -1864 116.0097 - 84 -1848 116.0097 84 -1848 -148 80 -1864 -144 84 -1864 -148 84 -1848 -148 - 80 -1848 -144 80 -1864 112.01013 80 -1864 -144.00002 80 -1848 -144.00002 - 80 -1848 112.01013 16 -1864 -144 79.991455 -1864 -144 83.991455 -1864 -148 - 12.000002 -1864 -148 79.991455 -1848 -144 16 -1848 -144 12.000002 -1848 -148 - 83.991455 -1848 -148 79.991455 -1864 -144 16 -1864 -144 16 -1848 -144 79.991455 - -1848 -144 84 -1864 -148 80 -1864 -144 80 -1848 -144 84 -1848 -148 12.000001 - -1864 -148 83.991028 -1864 -148 83.991028 -1848 -148 12.000001 -1848 -148 - 16 -1864 -144 12 -1864 -148 12 -1848 -148 16 -1848 -144 12.000001 -1864 116 - 83.991028 -1864 116 79.991028 -1864 112 15.999999 -1864 112 83.991028 -1848 - 116 12.000001 -1848 116 15.999999 -1848 112 79.991028 -1848 112 83.991028 - -1864 116 12.000001 -1864 116 12.000001 -1848 116 83.991028 -1848 116 80 - -1864 112 84 -1864 116 84 -1848 116 80 -1848 112 16 -1864 112 79.991455 -1864 - 112 79.991455 -1848 112 16 -1848 112 12 -1864 116 16 -1864 112 16 -1848 112 - 12 -1848 116 172 -1864 116 243.99603 -1864 116 239.99603 -1864 112 176 -1864 - 112 243.99603 -1848 116 172 -1848 116 176 -1848 112 239.99603 -1848 112 243.99603 - -1864 116 172 -1864 116 172 -1848 116 243.99603 -1848 116 240 -1864 112 244 - -1864 116 244 -1848 116 240 -1848 112 176 -1864 112 239.99646 -1864 112 239.99646 - -1848 112 176 -1848 112; - setAttr ".vt[332:487]" 172 -1864 116 176 -1864 112 176 -1848 112 172 - -1848 116 176 -1864 -144 239.99646 -1864 -144 243.99646 -1864 -148 172 -1864 - -148 243.99646 -1848 -148 239.99646 -1848 -144 176 -1848 -144 172 -1848 -148 - 239.99646 -1864 -144 176 -1864 -144 176 -1848 -144 239.99646 -1848 -144 244 - -1864 -148 240 -1864 -144 240 -1848 -144 244 -1848 -148 172 -1864 -148 243.99603 - -1864 -148 243.99603 -1848 -148 172 -1848 -148 176 -1864 -144 172 -1864 -148 - 172 -1848 -148 176 -1848 -144 240 -1864 112 244 -1864 116 244 -1864 -148.00002 - 240 -1864 -144.00002 244 -1848 116 240 -1848 112 240 -1848 -144.00002 244 - -1848 -148.00002 244 -1864 116 240 -1864 112 240 -1848 112 244 -1848 116 - 244 -1864 -148 244 -1864 116.0097 244 -1848 116.0097 244 -1848 -148 240 -1864 - -144 244 -1864 -148 244 -1848 -148 240 -1848 -144 240 -1864 112.01013 240 - -1864 -144.00002 240 -1848 -144.00002 240 -1848 112.01013 172 -1864 116 176 - -1864 112 176 -1864 -144 172 -1864 -148 176 -1848 112 172 -1848 116 172 -1848 - -148 176 -1848 -144 176 -1864 112 172 -1864 116 172 -1848 116 176 -1848 112 - 176 -1864 -144.00002 176 -1864 112.01013 176 -1848 112.01013 176 -1848 -144.00002 - 172 -1864 -148 176 -1864 -144 176 -1848 -144 172 -1848 -148 172 -1864 116.0097 - 172 -1864 -148.00002 172 -1848 -148.00002 172 -1848 116.0097 -224 -2144 112 - -192 -2144 112 -192 -2064 112 -224 -2064 112 -224 -2064 112 -256 -2064 112 - -256 -2144 112 -224 -2144 112 -224 -2144 -160 -192 -2144 -160 -192 -2064 - -160 -224 -2064 -160 -224 -2064 -160 -256 -2064 -160 -256 -2144 -160 -224 - -2144 -160 -224 -2064 -240 -256 -2064 -240 -256 -2144 -240 -224 -2144 -240 - -224 -2144 -240 -192 -2144 -240 -192 -2064 -240 -224 -2064 -240 224 -2064 - -240 192 -2064 -240 192 -2144 -240 224 -2144 -240 224 -2144 -240 256 -2144 - -240 256 -2064 -240 224 -2064 -240 224 -2144 -160 256 -2144 -160 256 -2064 - -160 224 -2064 -160 224 -2064 -160 192 -2064 -160 192 -2144 -160 224 -2144 - -160 288.00021 -2144 -272 272.00018 -2144 -240 272.00018 -1696 -240 288.00021 - -1696 -272 239.99994 -2144 -240 223.99992 -2144 -272 223.99992 -1696 -272 - 239.99994 -1696 -240 -224.00774 -2144 -272 -240.00775 -2144 -240 -240.00775 - -1696 -240 -224.00774 -1696 -272 -271.99237 -2144 -240 -287.9924 -2144 -272 - -287.9924 -1696 -272 -271.99237 -1696 -240 32.007942 -2144 -272 16.007925 - -2144 -240 16.007925 -1696 -240 32.007942 -1696 -272 -16.007925 -2144 -240 - -32.007942 -2144 -272 -32.007942 -1696 -272 -16.007925 -1696 -240 224 -2144 - 112 256 -2144 112 256 -2064 112 224 -2064 112 224 -2064 112 192 -2064 112 - 192 -2144 112 224 -2144 112 320 -2064 112 288 -2064 112 288 -2144 112 320 - -2144 112 320 -2144 112 352 -2144 112 352 -2064 112 320 -2064 112; - setAttr -s 610 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:497]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0 314 313 0 313 312 0 312 314 0 - 315 314 0 312 315 0 318 317 0 317 316 - 0 316 318 0 319 318 0 316 319 0 322 - 321 0 321 320 0 320 322 0 323 322 0 - 320 323 0 326 325 0 325 324 0 324 326 - 0 327 326 0 324 327 0 330 329 0 329 - 328 0 328 330 0 331 330 0 328 331 0 - 334 333 0 333 332 0 332 334 0 335 334 - 0 332 335 0 338 337 0 337 336 0 336 - 338 0 339 338 0 336 339 0 342 341 0 - 341 340 0 340 342 0 343 342 0 340 343 - 0 346 345 0 345 344 0 344 346 0 347 - 346 0 344 347 0 350 349 0 349 348 0 - 348 350 0 351 350 0 348 351 0 354 353 - 0 353 352 0 352 354 0 355 354 0 352 - 355 0 358 357 0 357 356 0 356 358 0 - 359 358 0 356 359 0 362 361 0 361 360 - 0 360 362 0 363 362 0 360 363 0 366 - 365 0 365 364 0 364 366 0 367 366 0 - 364 367 0 370 369 0 369 368 0 368 370 - 0 371 370 0 368 371 0 374 373 0 373 - 372 0 372 374 0 375 374 0 372 375 0 - 378 377 0 377 376 0 376 378 0 379 378 - 0 376 379 0 382 381 0 381 380 0 380 - 382 0 383 382 0 380 383 0 386 385 0 - 385 384 0 384 386 0 387 386 0 384 387 - 0 390 389 0 389 388 0 388 390 0 391 - 390 0 388 391 0 394 393 0 393 392 0 - 392 394 0 395 394 0 392 395 0 398 397 - 0 397 396 0 396 398 0; - setAttr ".ed[498:609]" 399 398 0 396 399 0 402 - 401 0 401 400 0 400 402 0 403 402 0 - 400 403 0 406 405 0 405 404 0 404 406 - 0 407 406 0 404 407 0 410 409 0 409 - 408 0 408 410 0 411 410 0 408 411 0 - 414 413 0 413 412 0 412 414 0 415 414 - 0 412 415 0 418 417 0 417 416 0 416 - 418 0 419 418 0 416 419 0 422 421 0 - 421 420 0 420 422 0 423 422 0 420 423 - 0 426 425 0 425 424 0 424 426 0 427 - 426 0 424 427 0 430 429 0 429 428 0 - 428 430 0 431 430 0 428 431 0 434 433 - 0 433 432 0 432 434 0 435 434 0 432 - 435 0 438 437 0 437 436 0 436 438 0 - 439 438 0 436 439 0 442 441 0 441 440 - 0 440 442 0 443 442 0 440 443 0 446 - 445 0 445 444 0 444 446 0 447 446 0 - 444 447 0 450 449 0 449 448 0 448 450 - 0 451 450 0 448 451 0 454 453 0 453 - 452 0 452 454 0 455 454 0 452 455 0 - 458 457 0 457 456 0 456 458 0 459 458 - 0 456 459 0 462 461 0 461 460 0 460 - 462 0 463 462 0 460 463 0 466 465 0 - 465 464 0 464 466 0 467 466 0 464 467 - 0 470 469 0 469 468 0 468 470 0 471 - 470 0 468 471 0 474 473 0 473 472 0 - 472 474 0 475 474 0 472 475 0 478 477 - 0 477 476 0 476 478 0 479 478 0 476 - 479 0 482 481 0 481 480 0 480 482 0 - 483 482 0 480 483 0 486 485 0 485 484 - 0 484 486 0 487 486 0 484 487 0; - setAttr -s 732 ".n"; - setAttr ".n[0:165]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 1 8.34432e-007 0 1 8.34432e-007 0 1 - 8.34432e-007 0 1 -8.34432e-007 0 1 -8.34432e-007 0 1 -8.34432e-007 0 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 -1 -3.4677791e-007 - 0 -1 -3.4677791e-007 0 -1 -3.4677791e-007 0 -1 3.4677791e-007 0 -1 3.4677791e-007 - 0 -1 3.4677791e-007 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 1 -2.8898159e-008 0 1 -2.8898159e-008 0 1 -2.8898159e-008 - 0 1 2.8898159e-008 0 1 2.8898159e-008 0 1 2.8898159e-008 0 -0.70710677 0 - -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -1 -3.5761371e-007 - 0 -1 -3.5761371e-007 0 -1 -3.5761371e-007 0 -1 3.5761371e-007 0 -1 3.5761371e-007 - 0 -1 3.5761371e-007 0 0 -1 -2.2889362e-005 0 -1 -2.2889362e-005 0 -1 -2.2889362e-005 - 0 -1 2.0345984e-005 0 -1 2.0345984e-005 0 -1 2.0345984e-005 0 1 -2.2889362e-005 - 0 1 -2.2889362e-005 0 1 -2.2889362e-005 0 1 2.0345984e-005 0 1 2.0345984e-005 - 0 1 2.0345984e-005 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - 0 -1 -1.6955088e-005 0 -1 -1.6955088e-005 0 -1 -1.6955088e-005 0 -1 1.9074596e-005 - 0 -1 1.9074596e-005 0 -1 1.9074596e-005 0 1 -1.6955088e-005 0 1 -1.6955088e-005 - 0 1 -1.6955088e-005 0 1 1.9074596e-005 0 1 1.9074596e-005 0 1 1.9074596e-005 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0.70710677 0 -0.70710677 0.70710677 0 - -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 - -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0; - setAttr ".n[166:331]" -type "float3" -1 0 0 -1 0 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 -1.0172345e-005 - 0 -1 -1.0172345e-005 0 -1 -1.0172345e-005 0 -1 1.1443863e-005 0 -1 1.1443863e-005 - 0 -1 1.1443863e-005 0 1 -1.0172345e-005 0 1 -1.0172345e-005 0 1 -1.0172345e-005 - 0 1 1.1443863e-005 0 1 1.1443863e-005 0 1 1.1443863e-005 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 0 -1 -1.5258382e-005 - 0 -1 -1.5258382e-005 0 -1 -1.5258382e-005 0 -1 1.3563046e-005 0 -1 1.3563046e-005 - 0 -1 1.3563046e-005 0 1 -1.5258382e-005 0 1 -1.5258382e-005 0 1 -1.5258382e-005 - 0 1 1.3563046e-005 0 1 1.3563046e-005 0 1 1.3563046e-005 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -1 -1.1920457e-007 0 -1 -1.1920457e-007 0 -1 -1.1920457e-007 - 0 -1 1.1920457e-007 0 -1 1.1920457e-007 0 -1 1.1920457e-007 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 1 -3.5761371e-007 - 0 1 -3.5761371e-007 0 1 -3.5761371e-007 0 1 3.5761371e-007 0 1 3.5761371e-007 - 0 1 3.5761371e-007 0 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 -1 -3.4677791e-007 0 -1 -3.4677791e-007 0 -1 -3.4677791e-007 - 0 -1 3.4677791e-007 0 -1 3.4677791e-007 0 -1 3.4677791e-007 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0; - setAttr ".n[332:497]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 1 -1.1920457e-007 - 0 1 -1.1920457e-007 0 1 -1.1920457e-007 0 1 1.1920457e-007 0 1 1.1920457e-007 - 0 1 1.1920457e-007 0 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0.70710677 0 - 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 1 -3.4677791e-007 - 0 1 -3.4677791e-007 0 1 -3.4677791e-007 0 1 3.4677791e-007 0 1 3.4677791e-007 - 0 1 3.4677791e-007 0 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -1 -3.5761371e-007 0 -1 -3.5761371e-007 0 -1 -3.5761371e-007 - 0 -1 3.5761371e-007 0 -1 3.5761371e-007 0 -1 3.5761371e-007 0 0 -1 1.5260826e-005 - 0 -1 1.5260826e-005 0 -1 1.5260826e-005 0 -1 -4.313239e-005 0 -1 -4.313239e-005 - 0 -1 -4.313239e-005 0 1 -1.8241457e-005 0 1 -1.8241457e-005 0 1 -1.8241457e-005 - 0 1 1.6956223e-005 0 1 1.6956223e-005 0 1 1.6956223e-005 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 0 -1 4.6100004e-006 0 -1 - 4.6100004e-006 0 -1 4.6100004e-006 0 -1 2.9448824e-005 0 -1 2.9448824e-005 - 0 -1 2.9448824e-005 0 1 4.7159774e-006 0 1 4.7159774e-006 0 1 4.7159774e-006 - 0 1 -3.815232e-006 0 1 -3.815232e-006 0 1 -3.815232e-006 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 0 -1 2.3737202e-005 0 - -1 2.3737202e-005 0 -1 2.3737202e-005 0 -1 -2.6704536e-005 0 -1 -2.6704536e-005 - 0 -1 -2.6704536e-005 0 1 2.3737202e-005 0 1 2.3737202e-005 0 1 2.3737202e-005 - 0 1 -2.6704536e-005 0 1 -2.6704536e-005 0 1 -2.6704536e-005 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr ".n[498:663]" -type "float3" -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 0 -1 2.288945e-005 0 -1 2.288945e-005 - 0 -1 2.288945e-005 0 -1 3.3910088e-005 0 -1 3.3910088e-005 0 -1 3.3910088e-005 - 0 1 2.288945e-005 0 1 2.288945e-005 0 1 2.288945e-005 0 1 -3.3910088e-005 - 0 1 -3.3910088e-005 0 1 -3.3910088e-005 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 1 -3.4677791e-007 0 1 -3.4677791e-007 - 0 1 -3.4677791e-007 0 1 3.4677791e-007 0 1 3.4677791e-007 0 1 3.4677791e-007 - 0 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -1 8.34432e-007 0 -1 8.34432e-007 0 -1 8.34432e-007 0 -1 -8.34432e-007 0 - -1 -8.34432e-007 0 -1 -8.34432e-007 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 1 -3.5761371e-007 0 1 -3.5761371e-007 - 0 1 -3.5761371e-007 0 1 3.5761371e-007 0 1 3.5761371e-007 0 1 3.5761371e-007 - 0 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - -1 -2.8898159e-008 0 -1 -2.8898159e-008 0 -1 -2.8898159e-008 0 -1 2.8898159e-008 - 0 -1 2.8898159e-008 0 -1 2.8898159e-008 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr ".n[664:731]" -type "float3" 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0.89442682 -6.0927988e-008 0.44721437 0.89442682 - -6.0927988e-008 0.44721437 0.89442682 -6.0927988e-008 0.44721437 0.89442682 - 6.0927988e-008 0.44721437 0.89442682 6.0927988e-008 0.44721437 0.89442682 - 6.0927988e-008 0.44721437 -0.89442706 -3.0464005e-008 0.44721377 -0.89442706 - -3.0464005e-008 0.44721377 -0.89442706 -3.0464005e-008 0.44721377 -0.894427 - 3.0464001e-008 0.44721398 -0.894427 3.0464001e-008 0.44721398 -0.894427 3.0464001e-008 - 0.44721398 0.89442706 -3.0464005e-008 0.44721377 0.89442706 -3.0464005e-008 - 0.44721377 0.89442706 -3.0464005e-008 0.44721377 0.894427 3.0464001e-008 - 0.44721398 0.894427 3.0464001e-008 0.44721398 0.894427 3.0464001e-008 0.44721398 - -0.89442682 -6.0927988e-008 0.44721437 -0.89442682 -6.0927988e-008 0.44721437 - -0.89442682 -6.0927988e-008 0.44721437 -0.89442682 6.0927988e-008 0.44721437 - -0.89442682 6.0927988e-008 0.44721437 -0.89442682 6.0927988e-008 0.44721437 - 0.89442706 3.8080006e-009 0.44721383 0.89442706 3.8080006e-009 0.44721383 - 0.89442706 3.8080006e-009 0.44721383 0.894427 -3.8080001e-009 0.44721395 - 0.894427 -3.8080001e-009 0.44721395 0.894427 -3.8080001e-009 0.44721395 -0.89442706 - 3.8080006e-009 0.44721383 -0.89442706 3.8080006e-009 0.44721383 -0.89442706 - 3.8080006e-009 0.44721383 -0.894427 -3.8080001e-009 0.44721395 -0.894427 - -3.8080001e-009 0.44721395 -0.894427 -3.8080001e-009 0.44721395 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1; - setAttr -s 244 ".fc[0:243]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 - f 3 390 391 392 - mu 0 3 314 313 312 - f 3 393 -393 394 - mu 0 3 315 314 312 - f 3 395 396 397 - mu 0 3 318 317 316 - f 3 398 -398 399 - mu 0 3 319 318 316 - f 3 400 401 402 - mu 0 3 322 321 320 - f 3 403 -403 404 - mu 0 3 323 322 320 - f 3 405 406 407 - mu 0 3 326 325 324 - f 3 408 -408 409 - mu 0 3 327 326 324 - f 3 410 411 412 - mu 0 3 330 329 328 - f 3 413 -413 414 - mu 0 3 331 330 328 - f 3 415 416 417 - mu 0 3 334 333 332 - f 3 418 -418 419 - mu 0 3 335 334 332 - f 3 420 421 422 - mu 0 3 338 337 336 - f 3 423 -423 424 - mu 0 3 339 338 336 - f 3 425 426 427 - mu 0 3 342 341 340 - f 3 428 -428 429 - mu 0 3 343 342 340 - f 3 430 431 432 - mu 0 3 346 345 344 - f 3 433 -433 434 - mu 0 3 347 346 344 - f 3 435 436 437 - mu 0 3 350 349 348 - f 3 438 -438 439 - mu 0 3 351 350 348 - f 3 440 441 442 - mu 0 3 354 353 352 - f 3 443 -443 444 - mu 0 3 355 354 352 - f 3 445 446 447 - mu 0 3 358 357 356 - f 3 448 -448 449 - mu 0 3 359 358 356 - f 3 450 451 452 - mu 0 3 362 361 360 - f 3 453 -453 454 - mu 0 3 363 362 360 - f 3 455 456 457 - mu 0 3 366 365 364 - f 3 458 -458 459 - mu 0 3 367 366 364 - f 3 460 461 462 - mu 0 3 370 369 368 - f 3 463 -463 464 - mu 0 3 371 370 368 - f 3 465 466 467 - mu 0 3 374 373 372 - f 3 468 -468 469 - mu 0 3 375 374 372 - f 3 470 471 472 - mu 0 3 378 377 376 - f 3 473 -473 474 - mu 0 3 379 378 376 - f 3 475 476 477 - mu 0 3 382 381 380 - f 3 478 -478 479 - mu 0 3 383 382 380 - f 3 480 481 482 - mu 0 3 386 385 384 - f 3 483 -483 484 - mu 0 3 387 386 384 - f 3 485 486 487 - mu 0 3 390 389 388 - f 3 488 -488 489 - mu 0 3 391 390 388 - f 3 490 491 492 - mu 0 3 394 393 392 - f 3 493 -493 494 - mu 0 3 395 394 392 - f 3 495 496 497 - mu 0 3 398 397 396 - f 3 498 -498 499 - mu 0 3 399 398 396 - f 3 500 501 502 - mu 0 3 402 401 400 - f 3 503 -503 504 - mu 0 3 403 402 400 - f 3 505 506 507 - mu 0 3 406 405 404 - f 3 508 -508 509 - mu 0 3 407 406 404 - f 3 510 511 512 - mu 0 3 410 409 408 - f 3 513 -513 514 - mu 0 3 411 410 408 - f 3 515 516 517 - mu 0 3 414 413 412 - f 3 518 -518 519 - mu 0 3 415 414 412 - f 3 520 521 522 - mu 0 3 418 417 416 - f 3 523 -523 524 - mu 0 3 419 418 416 - f 3 525 526 527 - mu 0 3 422 421 420 - f 3 528 -528 529 - mu 0 3 423 422 420 - f 3 530 531 532 - mu 0 3 426 425 424 - f 3 533 -533 534 - mu 0 3 427 426 424 - f 3 535 536 537 - mu 0 3 430 429 428 - f 3 538 -538 539 - mu 0 3 431 430 428 - f 3 540 541 542 - mu 0 3 434 433 432 - f 3 543 -543 544 - mu 0 3 435 434 432 - f 3 545 546 547 - mu 0 3 438 437 436 - f 3 548 -548 549 - mu 0 3 439 438 436 - f 3 550 551 552 - mu 0 3 442 441 440 - f 3 553 -553 554 - mu 0 3 443 442 440 - f 3 555 556 557 - mu 0 3 446 445 444 - f 3 558 -558 559 - mu 0 3 447 446 444 - f 3 560 561 562 - mu 0 3 450 449 448 - f 3 563 -563 564 - mu 0 3 451 450 448 - f 3 565 566 567 - mu 0 3 454 453 452 - f 3 568 -568 569 - mu 0 3 455 454 452 - f 3 570 571 572 - mu 0 3 458 457 456 - f 3 573 -573 574 - mu 0 3 459 458 456 - f 3 575 576 577 - mu 0 3 462 461 460 - f 3 578 -578 579 - mu 0 3 463 462 460 - f 3 580 581 582 - mu 0 3 466 465 464 - f 3 583 -583 584 - mu 0 3 467 466 464 - f 3 585 586 587 - mu 0 3 470 469 468 - f 3 588 -588 589 - mu 0 3 471 470 468 - f 3 590 591 592 - mu 0 3 474 473 472 - f 3 593 -593 594 - mu 0 3 475 474 472 - f 3 595 596 597 - mu 0 3 478 477 476 - f 3 598 -598 599 - mu 0 3 479 478 476 - f 3 600 601 602 - mu 0 3 482 481 480 - f 3 603 -603 604 - mu 0 3 483 482 480 - f 3 605 606 607 - mu 0 3 486 485 484 - f 3 608 -608 609 - mu 0 3 487 486 484 ; -createNode transform -n "m32" -p "celing"; -createNode mesh -n "polySurfaceShape14" -p "m32"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 0 1 1 1 - 0 0 1 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" 16 -1944 -239.5 -16 -1944 -239.5 - 16 -2064 -239.5 -16 -2064 -239.5; - setAttr -s 5 ".ed[0:4]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 ; -createNode transform -n "m34" -p "celing"; -createNode mesh -n "polySurfaceShape15" -p "m34"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 0 1 1 1 - 0 0 1 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" 16 -1944 -239 -16 -1944 -239 16 - -2064 -239 -16 -2064 -239; - setAttr -s 5 ".ed[0:4]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 ; -createNode transform -n "m36" -p "celing"; -createNode mesh -n "polySurfaceShape16" -p "m36"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 20 ".uvst[0].uvsp[0:19]" -type "float2" 0.000139 - 0.00056999997 0.000139 1.000562 1.000141 1.000562 1.000141 0.00056999997 - 0.000139 -0.00056199997 0.000139 0.99943 1.000141 0.99943 1.000141 -0.00056199997 - 1.000141 9.9999997e-006 0.000139 9.9999997e-006 0.000139 1.0000221 1.000141 - 1.0000221 0.99944502 9.9999997e-006 -0.00054699997 9.9999997e-006 -0.00054699997 - 1.0000221 0.99944502 1.0000221 0.000139 9.9999997e-006 1.000141 9.9999997e-006 - 1.000141 1.0000221 0.000139 1.0000221; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 20 ".vt[0:19]" -14 -2032 -234 14 -2032 -234 14 - -2032 -240 -14 -2032 -240 14 -1980 -234 -14 -1980 -234 -14 -1980 -240 14 - -1980 -240 14 -2032 -240 14 -2032 -234 14 -1980 -234 14 -1980 -240 -14 -2032 - -240 14 -2032 -240 14 -1980 -240 -14 -1980 -240 -14 -2032 -234 -14 -2032 - -240 -14 -1980 -240 -14 -1980 -234; - setAttr -s 25 ".ed[0:24]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0; - setAttr -s 30 ".n[0:29]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0; - setAttr -s 10 ".fc[0:9]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 ; -createNode transform -n "m38" -p "celing"; -createNode mesh -n "polySurfaceShape17" -p "m38"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 1.000562 - 9.9999997e-006 0.00056999997 9.9999997e-006 0.00056999997 1.0000221 1.000562 - 1.0000221; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" 14 -2032 -234 -14 -2032 -234 -14 - -1980 -234 14 -1980 -234; - setAttr -s 5 ".ed[0:4]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 ; -createNode transform -n "m40" -p "celing"; -createNode mesh -n "polySurfaceShape18" -p "m40"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 0 -0.00031199999 - 0 0.49968001 4 0.49968001 4 -0.00031199999 0.99936002 0.499892 -0.00062399998 - 0.499892 -0.00062399998 0.99988002 0.99936002 0.99988002 1.0006239 0.499892 - 0.00063999998 0.499892 0.00063999998 0.99988002 1.0006239 0.99988002 4 0.499892 - 0 0.499892 0 0.99988002 4 0.99988002; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" 16 -1947.9929 -228 16 -1947.9929 - -240 -16 -1947.9929 -240 -16 -1947.9929 -228 16 -1947.9929 -240 16 -1947.9929 - -228 16 -1940.0023 -228 16 -1940.0023 -240 -16 -1947.9929 -228 -16 -1947.9929 - -240 -16 -1940.0023 -240 -16 -1940.0023 -228 16 -1947.9929 -228 -16 -1947.9929 - -228 -16 -1940.0023 -228 16 -1940.0023 -228; - setAttr -s 20 ".ed[0:19]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0; - setAttr -s 24 ".n[0:23]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1; - setAttr -s 8 ".fc[0:7]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 ; -createNode transform -n "m42" -p "celing"; -createNode mesh -n "polySurfaceShape19" -p "m42"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 8 ".uvst[0].uvsp[0:7]" -type "float2" 1 1.000312 - 1 0.50032002 0 0.50032002 0 1.000312 1 0.499892 0 0.499892 0 0.99988002 1 - 0.99988002; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 8 ".vt[0:7]" -16 -1940.0023 -228 -16 -1940.0023 - -240 16 -1940.0023 -240 16 -1940.0023 -228 -16 -1947.9929 -240 16 -1947.9929 - -240 16 -1940.0023 -240 -16 -1940.0023 -240; - setAttr -s 10 ".ed[0:9]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0; - setAttr -s 12 ".n[0:11]" -type "float3" 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr -s 4 ".fc[0:3]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 ; -createNode transform -n "m44" -p "celing"; -createNode mesh -n "polySurfaceShape20" -p "m44"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 32 ".uvst[0].uvsp[0:31]" -type "float2" -0.00051899999 - 0 -0.00051899999 1 0.99951297 1 0.99951297 0 0.00048799999 -6.1999999e-005 - 1.00052 -6.1999999e-005 1.00052 0.99993402 0.00048799999 0.99993402 -0.00074699998 - 0 -0.00074699998 1 0.99928498 1 0.99928498 0 0.00083600002 -4.7000001e-005 - 1.000868 -4.7000001e-005 1.000868 0.99994898 0.00083600002 0.99994898 0.030598 - 0.002504 0.030471001 1.0031869 1.0303349 1.003149 1.030462 0.0024649999 0.000482 - -6.1999999e-005 1.001274 -6.1999999e-005 1.001274 0.99993402 0.000482 0.99993402 - -0.0040000002 -0.0044749998 -0.0038149999 0.99559599 0.99699599 0.99559599 - 0.99681097 -0.0044740001 0.0060049999 -6.1999999e-005 1.00721 -6.1999999e-005 - 1.00721 0.99993402 0.0060049999 0.99993402; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 32 ".vt[0:31]" 208 -1968 2 208 -1968 -30 186 -1968 - -30 186 -1968 2 186 -1968 -30 208 -1968 -30 208 -1956 -30 186 -1956 -30 48 - -1968 62 48 -1968 94 70 -1968 94 70 -1968 62 70 -1968 94 48 -1968 94 48 -1956 - 94 70 -1956 94 -204.53488 -1968 -129.1037 -217.56053 -1968 -99.847641 -197.4583 - -1968 -90.897537 -184.43265 -1968 -120.15359 -197.45726 -1968 -90.899864 - -217.57053 -1968 -99.854881 -217.57053 -1956 -99.854881 -197.45726 -1956 - -90.899864 -46.322155 -1968 3.376225 -41.868179 -1968 -28.315479 -63.670975 - -1968 -31.37966 -68.124947 -1968 0.31204501 -63.67049 -1968 -31.383095 -41.862877 - -1968 -28.318237 -41.862877 -1956 -28.318237 -63.67049 -1956 -31.383095; - setAttr -s 40 ".ed[0:39]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0 30 29 0 29 28 0 28 30 0 31 - 30 0 28 31 0; - setAttr -s 48 ".n[0:47]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 - 3.464495e-006 0 -1 3.464495e-006 0 -1 3.464495e-006 0 -1 2.7715992e-006 0 - -1 2.7715992e-006 0 -1 2.7715992e-006 -0.40674043 -4.0925926e-007 0.91354376 - -0.40674043 -4.0925926e-007 0.91354376 -0.40674043 -4.0925926e-007 0.91354376 - -0.40673304 4.0925184e-007 0.91354704 -0.40673304 4.0925184e-007 0.91354704 - -0.40673304 4.0925184e-007 0.91354704 0 -1 -1.9056824e-006 0 -1 -1.9056824e-006 - 0 -1 -1.9056824e-006 0 -1 1.9056829e-006 0 -1 1.9056829e-006 0 -1 1.9056829e-006 - 0.13917331 -9.9833795e-009 -0.99026805 0.13917331 -9.9833795e-009 -0.99026805 - 0.13917331 -9.9833795e-009 -0.99026805 0.13917249 9.9833297e-009 -0.99026817 - 0.13917249 9.9833297e-009 -0.99026817 0.13917249 9.9833297e-009 -0.99026817; - setAttr -s 16 ".fc[0:15]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 ; -createNode transform -n "m46" -p "celing"; -createNode mesh -n "polySurfaceShape21" -p "m46"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 0.00048799999 - 1 0.00048799999 0 1.00052 0 1.00052 1 0.00071400002 0 1.000746 0 1.000746 - 1 0.00071400002 1 -0.0083360001 0.001603 0.99181199 0.001622 0.99206102 1.0023381 - -0.0080869999 1.002319 -0.01225 1.002764 -0.012466 0.002694 0.98819298 0.002695 - 0.98840898 1.0027651; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" 186 -1956 2 186 -1956 -30 208 -1956 - -30 208 -1956 2 70 -1956 94 48 -1956 94 48 -1956 62 70 -1956 62 -197.4583 - -1956 -90.897537 -217.56053 -1956 -99.847641 -204.53488 -1956 -129.1037 -184.43265 - -1956 -120.15359 -68.124947 -1956 0.31204501 -63.670975 -1956 -31.37966 -41.868179 - -1956 -28.315479 -46.322155 -1956 3.376225; - setAttr -s 20 ".ed[0:19]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0; - setAttr -s 24 ".n[0:23]" -type "float3" 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -5.1967424e-007 - 0 1 -5.1967424e-007 0 1 -5.1967424e-007 0 1 4.3306213e-006 0 1 4.3306213e-006 - 0 1 4.3306213e-006 0 1 -4.244474e-006 0 1 -4.244474e-006 0 1 -4.244474e-006 - 0 1 -3.8546773e-006 0 1 -3.8546773e-006 0 1 -3.8546773e-006; - setAttr -s 8 ".fc[0:7]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 ; -createNode transform -n "m48" -p "celing"; -createNode mesh -n "polySurfaceShape22" -p "m48"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 1 -6.1999999e-005 - 0 -6.1999999e-005 0 0.99993402 1 0.99993402 1 -6.1999999e-005 0 -6.1999999e-005 - 0 0.99993402 1 0.99993402 1.000289 -6.1999999e-005 -0.00047299999 -6.1999999e-005 - -0.00047299999 0.99993402 1.000289 0.99993402 1.00137 -6.1999999e-005 0.001026 - -6.1999999e-005 0.001026 0.99993402 1.00137 0.99993402; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" 208 -1968 -30 208 -1968 2 208 -1956 - 2 208 -1956 -30 48 -1968 94 48 -1968 62 48 -1956 62 48 -1956 94 -217.56288 - -1968 -99.850212 -204.5378 -1968 -129.105 -204.5378 -1956 -129.105 -217.56288 - -1956 -99.850212 -41.863693 -1968 -28.322756 -46.318756 -1968 3.376699 -46.318756 - -1956 3.376699 -41.863693 -1956 -28.322756; - setAttr -s 20 ".ed[0:19]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0; - setAttr -s 24 ".n[0:23]" -type "float3" 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -0.91354722 -3.2013764e-007 - -0.40673271 -0.91354722 -3.2013764e-007 -0.40673271 -0.91354722 -3.2013764e-007 - -0.40673271 -0.91354382 3.2013665e-007 -0.40674034 -0.91354382 3.2013665e-007 - -0.40674034 -0.91354382 3.2013665e-007 -0.40674034 0.99026829 3.0311904e-007 - 0.1391717 0.99026829 3.0311904e-007 0.1391717 0.99026829 3.0311904e-007 0.1391717 - 0.99026775 -3.031189e-007 0.13917513 0.99026775 -3.031189e-007 0.13917513 - 0.99026775 -3.031189e-007 0.13917513; - setAttr -s 8 ".fc[0:7]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 ; -createNode transform -n "m50" -p "celing"; -createNode mesh -n "polySurfaceShape23" -p "m50"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 8 ".uvst[0].uvsp[0:7]" -type "float2" 1 -6.1999999e-005 - 0 -6.1999999e-005 0 0.99993402 1 0.99993402 1.000931 -6.1999999e-005 0.001152 - -6.1999999e-005 0.001152 0.99993402 1.000931 0.99993402; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 8 ".vt[0:7]" 186 -1968 2 186 -1968 -30 186 -1956 - -30 186 -1956 2 -68.125328 -1968 0.311988 -63.671642 -1968 -31.377672 -63.671642 - -1956 -31.377672 -68.125328 -1956 0.311988; - setAttr -s 10 ".ed[0:9]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0; - setAttr -s 12 ".n[0:11]" -type "float3" -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -0.99026811 -3.4113182e-007 -0.13917261 -0.99026811 - -3.4113182e-007 -0.13917261 -0.99026811 -3.4113182e-007 -0.13917261 -0.99026793 - 3.4113179e-007 -0.13917379 -0.99026793 3.4113179e-007 -0.13917379 -0.99026793 - 3.4113179e-007 -0.13917379; - setAttr -s 4 ".fc[0:3]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 ; -createNode transform -n "m52" -p "celing"; -createNode mesh -n "polySurfaceShape24" -p "m52"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 312 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 2.7501359 -26.5 2.7501359 - -27.5 2.250104 -27.5 2.250104 -26.5 -13.250869 -0.25 -13.750901 -0.25 -13.750901 - 1 -13.250869 1 -1.250105 -0.25 -1.750137 -0.25 -1.750137 1 -1.250105 1 14.750902 - -0.25 14.25087 -0.25 14.25087 1 14.750902 1 2.7501359 -0.25 2.250104 -0.25 - 2.250104 1 2.7501359 1 2.7501371 -26.5 2.7501371 -27.5 2.2501049 -27.5 2.2501049 - -26.5 -13.250869 -0.25 -13.750901 -0.25 -13.750901 1 -13.250869 1 -1.250105 - -0.25 -1.750137 -0.25 -1.750137 1 -1.250105 1 14.750902 -0.25 14.25087 -0.25 - 14.25087 1 14.750902 1 2.7501371 -0.25 2.2501049 -0.25 2.2501049 1 2.7501371 - 1 2.7501371 -26.5 2.7501371 -27.5 2.2501049 -27.5 2.2501049 -26.5 -13.250869 - -0.25 -13.750901 -0.25 -13.750901 1 -13.250869 1 -1.250105 -0.25 -1.750137 - -0.25 -1.750137 1 -1.250105 1 14.750896 -0.25 14.250864 -0.25 14.250864 1 - 14.750896 1 2.7501371 -0.25 2.2501049 -0.25 2.2501049 1 2.7501371 1 2.7501359 - -26.5 2.7501359 -27.5 2.250104 -27.5 2.250104 -26.5 -13.250869 -0.25 -13.750901 - -0.25 -13.750901 1 -13.250869 1 -1.250101 -0.25 -1.750133 -0.25 -1.750133 - 1 -1.250101 1 14.750896 -0.25 14.250864 -0.25 14.250864 1 14.750896 1 2.7501359 - -0.25 2.250104 -0.25 2.250104 1 2.7501359 1 2.750139 -26.5 2.750139 -27.5 - 2.250107 -27.5 2.250107 -26.5 -13.250869 -0.25 -13.750901 -0.25 -13.750901 - 1 -13.250869 1 -1.250103 -0.25 -1.7501349 -0.25 -1.7501349 1 -1.250103 1 - 14.750896 -0.25 14.250864 -0.25 14.250864 1 14.750896 1 2.750139 -0.25 2.250107 - -0.25 2.250107 1 2.750139 1 2.750139 -26.5 2.750139 -27.5 2.250107 -27.5 - 2.250107 -26.5 -13.250869 -0.25 -13.750901 -0.25 -13.750901 1 -13.250869 - 1 -1.250107 -0.25 -1.750139 -0.25 -1.750139 1 -1.250107 1 14.750902 -0.25 - 14.25087 -0.25 14.25087 1 14.750902 1 2.750139 -0.25 2.250107 -0.25 2.250107 - 1 2.750139 1 2.750139 -26.5 2.750139 -27.5 2.250107 -27.5 2.250107 -26.5 - -13.250874 -0.25 -13.750906 -0.25 -13.750906 1 -13.250874 1 -1.250107 -0.25 - -1.750139 -0.25 -1.750139 1 -1.250107 1 14.750907 -0.25 14.250875 -0.25 14.250875 - 1 14.750907 1 2.750139 -0.25 2.250107 -0.25 2.250107 1 2.750139 1 2.750139 - -26.5 2.750139 -27.5 2.250107 -27.5 2.250107 -26.5 -13.250875 -0.25 -13.750907 - -0.25 -13.750907 1 -13.250875 1 -1.250103 -0.25 -1.7501349 -0.25 -1.7501349 - 1 -1.250103 1 14.750903 -0.25 14.250871 -0.25 14.250871 1 14.750903 1 2.750139 - -0.25 2.250107 -0.25 2.250107 1 2.750139 1 2.7501359 -26.5 2.7501359 -27.5 - 2.250104 -27.5 2.250104 -26.5 -13.250875 -0.25 -13.750907 -0.25 -13.750907 - 1 -13.250875 1 -1.250101 -0.25 -1.750133 -0.25 -1.750133 1 -1.250101 1 14.750903 - -0.25 14.250871 -0.25 14.250871 1 14.750903 1 2.7501359 -0.25 2.250104 -0.25 - 2.250104 1 2.7501359 1 2.7501371 -26.5 2.7501371 -27.5 2.2501049 -27.5 2.2501049 - -26.5 -13.250875 -0.25 -13.750907 -0.25 -13.750907 1 -13.250875 1 -1.250105 - -0.25 -1.750137 -0.25 -1.750137 1 -1.250105 1 14.750903 -0.25 14.250871 -0.25 - 14.250871 1 14.750903 1 2.7501371 -0.25 2.2501049 -0.25 2.2501049 1 2.7501371 - 1 2.7501371 -26.5 2.7501371 -27.5 2.2501049 -27.5 2.2501049 -26.5 -13.250874 - -0.25 -13.750906 -0.25 -13.750906 1 -13.250874 1 -1.250105 -0.25 -1.750137 - -0.25 -1.750137 1 -1.250105 1 15.750983 -0.25 15.250951 -0.25 15.250951 1 - 15.750983 1 2.7501371 -0.25 2.2501049 -0.25 2.2501049 1 2.7501371 1 2.7501359 - -26.5 2.7501359 -27.5 2.250104 -27.5 2.250104 -26.5 -13.250874 -0.25 -13.750906 - -0.25 -13.750906 1 -13.250874 1 -1.250105 -0.25 -1.750137 -0.25 -1.750137 - 1 -1.250105 1 14.750907 -0.25 14.250875 -0.25 14.250875 1 14.750907 1 2.7501359 - -0.25 2.250104 -0.25 2.250104 1 2.7501359 1 14.374116 9 14.124129 9 13.999137 - 9.5 14.499107 9.5 0.49996901 30.000044 0.49996901 29.00001 -2.9998069 29.00001 - -2.9998069 30.000044 -14.12408 8.0527878 -14.374066 8.0527878; - setAttr ".uvst[0].uvsp[250:311]" -14.499058 8.5527878 -13.999087 8.5527878 - 4.0002761 -32 4.0002761 -31 4.500308 -31 4.500308 -32 -16.001013 0 -16.501045 - 0 -16.501045 7 -16.001013 7 16.501045 0 16.001013 0 16.001013 7 16.501045 - 7 4.0002761 -32 4.0002761 -31 4.500308 -31 4.500308 -32 -16.001024 0 -16.501057 - 0 -16.501057 7 -16.001024 7 16.501053 0 16.00102 0 16.00102 7 16.501053 7 - 14.374043 9 14.124173 9 13.999181 9.5 14.499035 9.5 0.49996901 29.999935 - 0.49996901 29.000135 -2.9998069 29.000135 -2.9998069 29.999935 -14.124185 - 8.0527878 -14.374054 8.0527878 -14.499046 8.5527878 -13.999192 8.5527878 - 14.374109 9 14.124083 9 13.99909 9.5 14.499102 9.5 0.49996901 30.000061 0.49996901 - 28.999945 -2.9998069 28.999945 -2.9998069 30.000061 -14.124084 8.0527878 - -14.374111 8.0527878 -14.499104 8.5527878 -13.999092 8.5527878 4.0002761 - -32 4.0002761 -31 4.500308 -31 4.500308 -32 -16.001017 0 -16.501047 0 -16.501047 - 7 -16.001017 7 16.501047 0 16.001017 0 16.001017 7 16.501047 7; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 312 ".vt"; - setAttr ".vt[0:165]" 80 -2144 -48 16 -2144 -48 16 -2144 16 80 -2144 - 16 80 -2144 16 16 -2144 16 16 -2064 16 80 -2064 16 16 -2144 16 16 -2144 -48 - 16 -2064 -48 16 -2064 16 16 -2144 -48 80 -2144 -48 80 -2064 -48 16 -2064 - -48 80 -2144 -48 80 -2144 16 80 -2064 16 80 -2064 -48 80 -2144 48 16 -2144 - 48 16 -2144 112 80 -2144 112 80 -2144 112 16 -2144 112 16 -2064 112 80 -2064 - 112 16 -2144 112 16 -2144 48 16 -2064 48 16 -2064 112 16 -2144 48 80 -2144 - 48 80 -2064 48 16 -2064 48 80 -2144 48 80 -2144 112 80 -2064 112 80 -2064 - 48 240 -2144 48 176 -2144 48 176 -2144 112 240 -2144 112 240 -2144 112 176 - -2144 112 176 -2064 112 240 -2064 112 176 -2144 112 176 -2144 48 176 -2064 - 48 176 -2064 112 176 -2144 48 240 -2144 48 240 -2064 48 176 -2064 48 240 - -2144 48 240 -2144 112 240 -2064 112 240 -2064 48 240 -2144 -48 176 -2144 - -48 176 -2144 16 240 -2144 16 240 -2144 16 176 -2144 16 176 -2064 16 240 - -2064 16 176 -2144 16 176 -2144 -48 176 -2064 -48 176 -2064 16 176 -2144 - -48 240 -2144 -48 240 -2064 -48 176 -2064 -48 240 -2144 -48 240 -2144 16 - 240 -2064 16 240 -2064 -48 240 -2144 -144 176 -2144 -144 176 -2144 -80 240 - -2144 -80 240 -2144 -80 176 -2144 -80 176 -2064 -80 240 -2064 -80 176 -2144 - -80 176 -2144 -144 176 -2064 -144 176 -2064 -80 176 -2144 -144 240 -2144 - -144 240 -2064 -144 176 -2064 -144 240 -2144 -144 240 -2144 -80 240 -2064 - -80 240 -2064 -144 80 -2144 -144 16 -2144 -144 16 -2144 -80 80 -2144 -80 - 80 -2144 -80 16 -2144 -80 16 -2064 -80 80 -2064 -80 16 -2144 -80 16 -2144 - -144 16 -2064 -144 16 -2064 -80 16 -2144 -144 80 -2144 -144 80 -2064 -144 - 16 -2064 -144 80 -2144 -144 80 -2144 -80 80 -2064 -80 80 -2064 -144 -176 - -2144 -144 -240 -2144 -144 -240 -2144 -80 -176 -2144 -80 -176 -2144 -80 -240 - -2144 -80 -240 -2064 -80 -176 -2064 -80 -240 -2144 -80 -240 -2144 -144 -240 - -2064 -144 -240 -2064 -80 -240 -2144 -144 -176 -2144 -144 -176 -2064 -144 - -240 -2064 -144 -176 -2144 -144 -176 -2144 -80 -176 -2064 -80 -176 -2064 - -144 -16 -2144 -144 -80 -2144 -144 -80 -2144 -80 -16 -2144 -80 -16 -2144 - -80 -80 -2144 -80 -80 -2064 -80 -16 -2064 -80 -80 -2144 -80 -80 -2144 -144 - -80 -2064 -144 -80 -2064 -80 -80 -2144 -144 -16 -2144 -144 -16 -2064 -144 - -80 -2064 -144 -16 -2144 -144 -16 -2144 -80 -16 -2064 -80 -16 -2064 -144 - -16 -2144 -48 -80 -2144 -48 -80 -2144 16 -16 -2144 16 -16 -2144 16 -80 -2144 - 16; - setAttr ".vt[166:311]" -80 -2064 16 -16 -2064 16 -80 -2144 16 -80 - -2144 -48 -80 -2064 -48 -80 -2064 16 -80 -2144 -48 -16 -2144 -48 -16 -2064 - -48 -80 -2064 -48 -16 -2144 -48 -16 -2144 16 -16 -2064 16 -16 -2064 -48 -16 - -2144 48 -80 -2144 48 -80 -2144 112 -16 -2144 112 -16 -2144 112 -80 -2144 - 112 -80 -2064 112 -16 -2064 112 -80 -2144 112 -80 -2144 48 -80 -2064 48 -80 - -2064 112 -80 -2144 48 -16 -2144 48 -16 -2064 48 -80 -2064 48 -16 -2144 48 - -16 -2144 112 -16 -2064 112 -16 -2064 48 -176 -2144 48 -240 -2144 48 -240 - -2144 112 -176 -2144 112 -176 -2144 112 -240 -2144 112 -240 -2064 112 -176 - -2064 112 -240 -2144 112 -240 -2144 48 -240 -2064 48 -240 -2064 112 -240 - -2144 48 -176 -2144 48 -176 -2064 48 -240 -2064 48 -176 -2144 48 -176 -2144 - 112 -176 -2064 112 -176 -2064 48 -176 -2144 -48 -240 -2144 -48 -240 -2144 - 16 -176 -2144 16 -176 -2144 16 -240 -2144 16 -240 -2064 16 -176 -2064 16 - -240 -2144 16 -240 -2144 -48 -240 -2064 -48 -240 -2064 16 -240 -2144 -48 - -176 -2144 -48 -176 -2064 -48 -240 -2064 -48 -176 -2144 -48 -176 -2144 16 - -176 -2064 16 -176 -2064 -48 239.99648 -2144 -240 271.99677 -2144 -240 287.9968 - -2144 -272 223.99646 -2144 -272 223.99646 -2144 -272 287.99863 -2144 -272 - 287.99863 -1696 -272 223.99646 -1696 -272 271.99677 -1696 -240 239.99648 - -1696 -240 223.99646 -1696 -272 287.9968 -1696 -272 224 -2144 -272 288 -2144 - -272 288 -2144 -336 224 -2144 -336 288 -2144 -272 224 -2144 -272 224 -1696 - -272 288 -1696 -272 224 -2144 -336 288 -2144 -336 288 -1696 -336 224 -1696 - -336 -288 -2144 -272 -224 -2144 -272 -224 -2144 -336 -288 -2144 -336 -224 - -2144 -272 -288 -2144 -272 -288 -1696 -272 -224 -1696 -272 -288 -2144 -336 - -224 -2144 -336 -224 -1696 -336 -288 -1696 -336 -271.99585 -2144 -240 -240.0105 - -2144 -240 -224.01048 -2144 -272 -287.99585 -2144 -272 -287.99585 -2144 -272 - -224.00864 -2144 -272 -224.00864 -1696 -272 -287.99585 -1696 -272 -240.0105 - -1696 -240 -271.99585 -1696 -240 -287.99585 -1696 -272 -224.01048 -1696 -272 - -16.00359 -2144 -240 16.001865 -2144 -240 32.001884 -2144 -272 -32.003609 - -2144 -272 -32.003609 -2144 -272 32.003731 -2144 -272 32.003731 -1696 -272 - -32.003609 -1696 -272 16.001865 -1696 -240 -16.00359 -1696 -240 -32.003609 - -1696 -272 32.001884 -1696 -272 -32 -2144 -272 32 -2144 -272 32 -2144 -336 - -32 -2144 -336 32 -2144 -272 -32 -2144 -272 -32 -1696 -272 32 -1696 -272 - -32 -2144 -336 32 -2144 -336 32 -1696 -336 -32 -1696 -336; - setAttr -s 390 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:389]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0; - setAttr -s 468 ".n"; - setAttr ".n[0:165]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0; - setAttr ".n[166:331]" -type "float3" -1 0 0 -1 0 0 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0; - setAttr ".n[332:467]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 0 -1 -9.5366659e-007 0 -1 -9.5366659e-007 0 -1 -9.5366659e-007 0 - -1 -1.4305036e-006 0 -1 -1.4305036e-006 0 -1 -1.4305036e-006 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 -3.8146609e-006 0 1 -3.8146609e-006 0 1 -3.8146609e-006 - 0 1 -9.5366931e-007 0 1 -9.5366931e-007 0 1 -9.5366931e-007 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 -1 2.8623344e-006 0 -1 2.8623344e-006 0 -1 2.8623344e-006 0 -1 0 - 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 - 0 1 2.384731e-006 0 1 2.384731e-006 0 1 2.384731e-006 0 -1 4.0524251e-006 - 0 -1 4.0524251e-006 0 -1 4.0524251e-006 0 -1 2.026384e-006 0 -1 2.026384e-006 - 0 -1 2.026384e-006 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 -5.4826928e-006 - 0 1 -5.4826928e-006 0 1 -5.4826928e-006 0 1 2.9799764e-006 0 1 2.9799764e-006 - 0 1 2.9799764e-006 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr -s 156 ".fc[0:155]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 ; -createNode transform -n "m54" -p "celing"; -createNode mesh -n "polySurfaceShape25" -p "m54"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 16 ".uvst[0].uvsp[0:15]" -type "float2" 1.00052 - -6.1999999e-005 0.00048799999 -6.1999999e-005 0.00048799999 0.99993402 1.00052 - 0.99993402 1.0008529 -4.7000001e-005 0.00082100002 -4.7000001e-005 0.00082100002 - 0.99994898 1.0008529 0.99994898 1.000929 -6.1999999e-005 0.000482 -6.1999999e-005 - 0.000482 0.99993402 1.000929 0.99993402 0.99541199 -6.1999999e-005 -0.0055010002 - -6.1999999e-005 -0.0055010002 0.99993402 0.99541199 0.99993402; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 16 ".vt[0:15]" 208 -1968 2 186 -1968 2 186 -1956 - 2 208 -1956 2 48 -1968 62 70 -1968 62 70 -1956 62 48 -1956 62 -204.53928 - -1968 -129.10487 -184.43294 -1968 -120.15295 -184.43294 -1956 -120.15295 - -204.53928 -1956 -129.10487 -46.316002 -1968 3.377075 -68.124947 -1968 0.31202999 - -68.124947 -1956 0.31202999 -46.316002 -1956 3.377075; - setAttr -s 20 ".ed[0:19]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0; - setAttr -s 24 ".n[0:23]" -type "float3" 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0.40673923 -3.4430309e-007 - -0.9135443 0.40673923 -3.4430309e-007 -0.9135443 0.40673923 -3.4430309e-007 - -0.9135443 0.40674257 3.4430582e-007 -0.91354281 0.40674257 3.4430582e-007 - -0.91354281 0.40674257 3.4430582e-007 -0.91354281 -0.13917224 3.4642682e-008 - 0.99026817 -0.13917224 3.4642682e-008 0.99026817 -0.13917224 3.4642682e-008 - 0.99026817 -0.13917409 -3.464314e-008 0.99026793 -0.13917409 -3.464314e-008 - 0.99026793 -0.13917409 -3.464314e-008 0.99026793; - setAttr -s 8 ".fc[0:7]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 ; -createNode transform -n "m56" -p "celing"; -createNode mesh -n "polySurfaceShape26" -p "m56"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 8 ".uvst[0].uvsp[0:7]" -type "float2" 1 -6.1999999e-005 - 0 -6.1999999e-005 0 0.99993402 1 0.99993402 0.99973297 -6.1999999e-005 -0.001092 - -6.1999999e-005 -0.001092 0.99993402 0.99973297 0.99993402; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 8 ".vt[0:7]" 70 -1968 62 70 -1968 94 70 -1956 - 94 70 -1956 62 -184.435 -1968 -120.15465 -197.46132 -1968 -90.897087 -197.46132 - -1956 -90.897087 -184.435 -1956 -120.15465; - setAttr -s 10 ".ed[0:9]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0; - setAttr -s 12 ".n[0:11]" -type "float3" 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0.91354483 4.7147455e-007 0.40673807 0.91354483 4.7147455e-007 - 0.40673807 0.91354483 4.7147455e-007 0.40673807 0.91354465 -4.7147458e-007 - 0.40673843 0.91354465 -4.7147458e-007 0.40673843 0.91354465 -4.7147458e-007 - 0.40673843; - setAttr -s 4 ".fc[0:3]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 ; -createNode transform -n "m58" -p "celing"; -createNode mesh -n "polySurfaceShape27" -p "m58"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 400 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0 1 0.064396001 1 - 0.128791 1 0.193187 1 0.25758299 1 0 0.62435001 0.064396001 0.62435001 0.128791 - 0.62435001 0.193187 0.62435001 0.25758299 0.62435001 0 1 0.064396001 1 0.128791 - 1 0.193187 1 0.25758299 1 0 0.963422 0.064396001 0.963422 0.128791 0.963422 - 0.193187 0.963422 0.25758299 0.963422 0 0.91997898 0.064396001 0.91997898 - 0.128791 0.91997898 0.193187 0.91997898 0.25758299 0.91997898 0 1 0.0625 - 1 0.125 1 0.1875 1 0.25 1 0 0.95655698 0.0625 0.95655698 0.125 0.95655698 - 0.1875 0.95655698 0.25 0.95655698 0 0.91997898 0.0625 0.91997898 0.125 0.91997898 - 0.1875 0.91997898 0.25 0.91997898 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 - 0.75 0.0625 0.75 0.125 0.75 0.1875 0.75 0.25 0.75 0 1 0.0625 1 0.125 1 0.1875 - 1 0.25 1 0 0.9375 0.0625 0.9375 0.125 0.9375 0.1875 0.9375 0.25 0.9375 0 - 0.875 0.0625 0.875 0.125 0.875 0.1875 0.875 0.25 0.875 0 0.8125 0.0625 0.8125 - 0.125 0.8125 0.1875 0.8125 0.25 0.8125 0 1 0.0625 1 0.125 1 0.1875 1 0.25 - 1 0 -1.0625 0.0625 -1.0625 0.125 -1.0625 0.1875 -1.0625 0.25 -1.0625 0 1 - 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.46875 0.0625 0.46875 0.125 0.46875 0.1875 - 0.46875 0.25 0.46875 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 -0.84375 0.0625 - -0.84375 0.125 -0.84375 0.1875 -0.84375 0.25 -0.84375 0 1 0.0625 1 0.125 - 1 0.1875 1 0.25 1 0 0.95655698 0.0625 0.95655698 0.125 0.95655698 0.1875 - 0.95655698 0.25 0.95655698 0 0.91997898 0.0625 0.91997898 0.125 0.91997898 - 0.1875 0.91997898 0.25 0.91997898 0 1 0.064396001 1 0.128791 1 0.193187 1 - 0.25758299 1 0 0.963422 0.064396001 0.963422 0.128791 0.963422 0.193187 0.963422 - 0.25758299 0.963422 0 0.91997898 0.064396001 0.91997898 0.128791 0.91997898 - 0.193187 0.91997898 0.25758299 0.91997898 0 1 0.064396001 1 0.128791 1 0.193187 - 1 0.25758299 1 0 0.62435001 0.064396001 0.62435001 0.128791 0.62435001 0.193187 - 0.62435001 0.25758299 0.62435001 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.65625 - 0.0625 0.65625 0.125 0.65625 0.1875 0.65625 0.25 0.65625 0 1 0.0625 1 0.125 - 1 0.1875 1 0.25 1 0 0.65625 0.0625 0.65625 0.125 0.65625 0.1875 0.65625 0.25 - 0.65625 0 1 0.064396001 1 0.128791 1 0.193187 1 0.25758299 1 0 0.62435001 - 0.064396001 0.62435001 0.128791 0.62435001 0.193187 0.62435001 0.25758299 - 0.62435001 0 1 0.064396001 1 0.128791 1 0.193187 1 0.25758299 1 0 0.963422 - 0.064396001 0.963422 0.128791 0.963422 0.193187 0.963422 0.25758299 0.963422 - 0 0.91997898 0.064396001 0.91997898 0.128791 0.91997898 0.193187 0.91997898 - 0.25758299 0.91997898 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.95655698 0.0625 - 0.95655698 0.125 0.95655698 0.1875 0.95655698 0.25 0.95655698 0 0.91997898 - 0.0625 0.91997898 0.125 0.91997898 0.1875 0.91997898 0.25 0.91997898 0 0.91997898 - 0.0625 0.91997898 0.125 0.91997898 0.1875 0.91997898 0.25 0.91997898 0 0.95655698 - 0.0625 0.95655698 0.125 0.95655698 0.1875 0.95655698 0.25 0.95655698 0 1 - 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.91997898 0.064396001 0.91997898 0.128791 - 0.91997898 0.193187 0.91997898 0.25758299 0.91997898 0 0.963422 0.064396001 - 0.963422 0.128791 0.963422 0.193187 0.963422 0.25758299 0.963422 0 1 0.064396001 - 1 0.128791 1 0.193187 1 0.25758299 1 0 0.62435001 0.064396001 0.62435001 - 0.128791 0.62435001 0.193187 0.62435001 0.25758299 0.62435001 0 1 0.064396001 - 1 0.128791 1 0.193187 1 0.25758299 1 0 0.65625 0.0625 0.65625 0.125 0.65625 - 0.1875 0.65625 0.25 0.65625 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1; - setAttr ".uvst[0].uvsp[250:399]" 0 0.65625 0.0625 0.65625 0.125 0.65625 - 0.1875 0.65625 0.25 0.65625 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.62435001 - 0.064396001 0.62435001 0.128791 0.62435001 0.193187 0.62435001 0.25758299 - 0.62435001 0 1 0.064396001 1 0.128791 1 0.193187 1 0.25758299 1 0 0.91997898 - 0.064396001 0.91997898 0.128791 0.91997898 0.193187 0.91997898 0.25758299 - 0.91997898 0 0.963422 0.064396001 0.963422 0.128791 0.963422 0.193187 0.963422 - 0.25758299 0.963422 0 1 0.064396001 1 0.128791 1 0.193187 1 0.25758299 1 - 0 0.91997898 0.0625 0.91997898 0.125 0.91997898 0.1875 0.91997898 0.25 0.91997898 - 0 0.95655698 0.0625 0.95655698 0.125 0.95655698 0.1875 0.95655698 0.25 0.95655698 - 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 -0.84375 0.0625 -0.84375 0.125 -0.84375 - 0.1875 -0.84375 0.25 -0.84375 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.46875 - 0.0625 0.46875 0.125 0.46875 0.1875 0.46875 0.25 0.46875 0 1 0.0625 1 0.125 - 1 0.1875 1 0.25 1 0 -1.0625 0.0625 -1.0625 0.125 -1.0625 0.1875 -1.0625 0.25 - -1.0625 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.8125 0.0625 0.8125 0.125 - 0.8125 0.1875 0.8125 0.25 0.8125 0 0.875 0.0625 0.875 0.125 0.875 0.1875 - 0.875 0.25 0.875 0 0.9375 0.0625 0.9375 0.125 0.9375 0.1875 0.9375 0.25 0.9375 - 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.75 0.0625 0.75 0.125 0.75 0.1875 - 0.75 0.25 0.75 0 1 0.0625 1 0.125 1 0.1875 1 0.25 1 0 0.91997898 0.0625 0.91997898 - 0.125 0.91997898 0.1875 0.91997898 0.25 0.91997898 0 0.95655698 0.0625 0.95655698 - 0.125 0.95655698 0.1875 0.95655698 0.25 0.95655698 0 1 0.0625 1 0.125 1 0.1875 - 1 0.25 1 0 0.91997898 0.064396001 0.91997898 0.128791 0.91997898 0.193187 - 0.91997898 0.25758299 0.91997898 0 0.963422 0.064396001 0.963422 0.128791 - 0.963422 0.193187 0.963422 0.25758299 0.963422 0 1 0.064396001 1 0.128791 - 1 0.193187 1 0.25758299 1 0 0.62435001 0.064396001 0.62435001 0.128791 0.62435001 - 0.193187 0.62435001 0.25758299 0.62435001 0 1 0.064396001 1 0.128791 1 0.193187 - 1 0.25758299 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 400 ".vt"; - setAttr ".vt[0:165]" -179.75 -2036.25 -146 -180.5 -2035.5 -147 - -179.75 -2036.25 -148 -179 -2037 -147 -179.75 -2036.25 -146 -188.25 -2044.75 - -146 -189 -2044 -147 -188.25 -2044.75 -148 -187.5 -2045.5 -147 -188.25 -2044.75 - -146 -188.25 -2044.75 -148 -187.5 -2045.5 -147 -188.25 -2044.75 -146 -189 - -2044 -147 -188.25 -2044.75 -148 -188.8125 -2045.6875 -148 -187.875 -2046.125 - -147 -188.8125 -2045.6875 -146 -189.75 -2045.25 -147 -188.8125 -2045.6875 - -148 -189 -2047 -148 -188 -2047 -147 -189 -2047 -146 -190 -2047 -147 -189 - -2047 -148 -179 -2034 -146 -180 -2034 -147 -179 -2034 -148 -178 -2034 -147 - -179 -2034 -146 -179.1875 -2035.3125 -146 -180.125 -2034.875 -147 -179.1875 - -2035.3125 -148 -178.25 -2035.75 -147 -179.1875 -2035.3125 -146 -179.75 -2036.25 - -146 -180.5 -2035.5 -147 -179.75 -2036.25 -148 -179 -2037 -147 -179.75 -2036.25 - -146 -179 -2026 -146 -180 -2026 -147 -179 -2026 -148 -178 -2026 -147 -179 - -2026 -146 -179 -2034 -146 -180 -2034 -147 -179 -2034 -148 -178 -2034 -147 - -179 -2034 -146 -182 -2023 -146 -182 -2024 -147 -182 -2023 -148 -182 -2022 - -147 -182 -2023 -146 -180.33333 -2023.3334 -146 -180.88889 -2024.2222 -147 - -180.33333 -2023.3334 -148 -179.77777 -2022.4445 -147 -180.33333 -2023.3334 - -146 -179.33333 -2024.3334 -146 -180.22223 -2024.8889 -147 -179.33333 -2024.3334 - -148 -178.44444 -2023.7778 -147 -179.33333 -2024.3334 -146 -179 -2026 -146 - -180 -2026 -147 -179 -2026 -148 -178 -2026 -147 -179 -2026 -146 -248 -2023 - -146 -248 -2024 -147 -248 -2023 -148 -248 -2022 -147 -248 -2023 -146 -182 - -2023 -146 -182 -2024 -147 -182 -2023 -148 -182 -2022 -147 -182 -2023 -146 - -189 -2047 -146 -190 -2047 -147 -189 -2047 -148 -188 -2047 -147 -189 -2047 - -146 -189 -2064 -146 -190 -2064 -147 -189 -2064 -148 -188 -2064 -147 -189 - -2064 -146 -248 -2048 -146 -248 -2049 -147 -248 -2048 -148 -248 -2047 -147 - -248 -2048 -146 -189 -2048 -146 -189 -2049 -147 -189 -2048 -148 -189 -2047 - -147 -189 -2048 -146 -248 -2047 -147 -248 -2048 -148 -248 -2049 -147 -248 - -2048 -146 -248 -2047 -147 -249.3125 -2047 -147.1875 -248.875 -2048 -148.125 - -249.3125 -2049 -147.1875 -249.75 -2048 -146.25 -249.3125 -2047 -147.1875 - -250.25 -2047 -147.75 -249.5 -2048 -148.5 -250.25 -2049 -147.75 -251 -2048 - -147 -250.25 -2047 -147.75 -258.75 -2049 -156.25 -259.5 -2048 -155.5 -258.75 - -2047 -156.25 -258 -2048 -157 -258.75 -2049 -156.25 -259.6875 -2049 -156.8125 - -260.125 -2048 -155.875 -259.6875 -2047 -156.8125 -259.25 -2048 -157.75 -259.6875 - -2049 -156.8125 -261 -2049 -157 -261 -2048 -156 -261 -2047 -157 -261 -2048 - -158 -261 -2049 -157 -250.25 -2047 -147.75 -249.5 -2048 -148.5 -250.25 -2049 - -147.75 -251 -2048 -147 -250.25 -2047 -147.75 -258.75 -2047 -156.25 -258 - -2048 -157 -258.75 -2049 -156.25 -259.5 -2048 -155.5 -258.75 -2047 -156.25 - -272 -2048 -156 -272 -2049 -157 -272 -2048 -158 -272 -2047 -157 -272 -2048 - -156 -261 -2048 -156 -261 -2049 -157 -261 -2048 -158 -261 -2047 -157 -261 - -2048 -156 -272 -2023 -156 -272 -2024 -157 -272 -2023 -158 -272 -2022 -157 - -272 -2023 -156 -261 -2023 -156 -261 -2024 -157 -261 -2023 -158 -261 -2022 - -157 -261 -2023 -156 -250.25 -2022 -147.75 -249.5 -2023 -148.5 -250.25 -2024 - -147.75 -251 -2023 -147 -250.25 -2022 -147.75 -258.75 -2022 -156.25; - setAttr ".vt[166:331]" -258 -2023 -157 -258.75 -2024 -156.25 -259.5 - -2023 -155.5 -258.75 -2022 -156.25 -258.75 -2024 -156.25 -259.5 -2023 -155.5 - -258.75 -2022 -156.25 -258 -2023 -157 -258.75 -2024 -156.25 -259.6875 -2024 - -156.8125 -260.125 -2023 -155.875 -259.6875 -2022 -156.8125 -259.25 -2023 - -157.75 -259.6875 -2024 -156.8125 -261 -2024 -157 -261 -2023 -156 -261 -2022 - -157 -261 -2023 -158 -261 -2024 -157 -248 -2022 -147 -248 -2023 -148 -248 - -2024 -147 -248 -2023 -146 -248 -2022 -147 -249.3125 -2022 -147.1875 -248.875 - -2023 -148.125 -249.3125 -2024 -147.1875 -249.75 -2023 -146.25 -249.3125 - -2022 -147.1875 -250.25 -2022 -147.75 -249.5 -2023 -148.5 -250.25 -2024 -147.75 - -251 -2023 -147 -250.25 -2022 -147.75 -250.25 -2022 -236.25 -249.5 -2023 - -235.5 -250.25 -2024 -236.25 -251 -2023 -237 -250.25 -2022 -236.25 -249.3125 - -2022 -236.8125 -248.875 -2023 -235.875 -249.3125 -2024 -236.8125 -249.75 - -2023 -237.75 -249.3125 -2022 -236.8125 -248 -2022 -237 -248 -2023 -236 -248 - -2024 -237 -248 -2023 -238 -248 -2022 -237 -261 -2024 -227 -261 -2023 -228 - -261 -2022 -227 -261 -2023 -226 -261 -2024 -227 -259.6875 -2024 -227.1875 - -260.125 -2023 -228.125 -259.6875 -2022 -227.1875 -259.25 -2023 -226.25 -259.6875 - -2024 -227.1875 -258.75 -2024 -227.75 -259.5 -2023 -228.5 -258.75 -2022 -227.75 - -258 -2023 -227 -258.75 -2024 -227.75 -258.75 -2022 -227.75 -258 -2023 -227 - -258.75 -2024 -227.75 -259.5 -2023 -228.5 -258.75 -2022 -227.75 -250.25 -2022 - -236.25 -249.5 -2023 -235.5 -250.25 -2024 -236.25 -251 -2023 -237 -250.25 - -2022 -236.25 -261 -2023 -228 -261 -2024 -227 -261 -2023 -226 -261 -2022 - -227 -261 -2023 -228 -272 -2023 -228 -272 -2024 -227 -272 -2023 -226 -272 - -2022 -227 -272 -2023 -228 -261 -2048 -228 -261 -2049 -227 -261 -2048 -226 - -261 -2047 -227 -261 -2048 -228 -272 -2048 -228 -272 -2049 -227 -272 -2048 - -226 -272 -2047 -227 -272 -2048 -228 -258.75 -2047 -227.75 -258 -2048 -227 - -258.75 -2049 -227.75 -259.5 -2048 -228.5 -258.75 -2047 -227.75 -250.25 -2047 - -236.25 -249.5 -2048 -235.5 -250.25 -2049 -236.25 -251 -2048 -237 -250.25 - -2047 -236.25 -261 -2049 -227 -261 -2048 -228 -261 -2047 -227 -261 -2048 - -226 -261 -2049 -227 -259.6875 -2049 -227.1875 -260.125 -2048 -228.125 -259.6875 - -2047 -227.1875 -259.25 -2048 -226.25 -259.6875 -2049 -227.1875 -258.75 -2049 - -227.75 -259.5 -2048 -228.5 -258.75 -2047 -227.75 -258 -2048 -227 -258.75 - -2049 -227.75 -250.25 -2047 -236.25 -249.5 -2048 -235.5 -250.25 -2049 -236.25 - -251 -2048 -237 -250.25 -2047 -236.25 -249.3125 -2047 -236.8125 -248.875 - -2048 -235.875 -249.3125 -2049 -236.8125 -249.75 -2048 -237.75 -249.3125 - -2047 -236.8125 -248 -2047 -237 -248 -2048 -236 -248 -2049 -237 -248 -2048 - -238 -248 -2047 -237 -189 -2048 -238 -189 -2049 -237 -189 -2048 -236 -189 - -2047 -237 -189 -2048 -238 -248 -2048 -238 -248 -2049 -237 -248 -2048 -236 - -248 -2047 -237 -248 -2048 -238 -189 -2064 -238 -190 -2064 -237 -189 -2064 - -236 -188 -2064 -237 -189 -2064 -238 -189 -2047 -238 -190 -2047 -237 -189 - -2047 -236 -188 -2047 -237 -189 -2047 -238 -182 -2023 -238 -182 -2024 -237 - -182 -2023 -236 -182 -2022 -237 -182 -2023 -238 -248 -2023 -238 -248 -2024 - -237 -248 -2023 -236 -248 -2022 -237 -248 -2023 -238 -179 -2026 -238 -180 - -2026 -237; - setAttr ".vt[332:399]" -179 -2026 -236 -178 -2026 -237 -179 -2026 - -238 -179.33333 -2024.3334 -238 -180.22223 -2024.8889 -237 -179.33333 -2024.3334 - -236 -178.44444 -2023.7778 -237 -179.33333 -2024.3334 -238 -180.33333 -2023.3334 - -238 -180.88889 -2024.2222 -237 -180.33333 -2023.3334 -236 -179.77777 -2022.4445 - -237 -180.33333 -2023.3334 -238 -182 -2023 -238 -182 -2024 -237 -182 -2023 - -236 -182 -2022 -237 -182 -2023 -238 -179 -2034 -238 -180 -2034 -237 -179 - -2034 -236 -178 -2034 -237 -179 -2034 -238 -179 -2026 -238 -180 -2026 -237 - -179 -2026 -236 -178 -2026 -237 -179 -2026 -238 -179.75 -2036.25 -238 -180.5 - -2035.5 -237 -179.75 -2036.25 -236 -179 -2037 -237 -179.75 -2036.25 -238 - -179.1875 -2035.3125 -238 -180.125 -2034.875 -237 -179.1875 -2035.3125 -236 - -178.25 -2035.75 -237 -179.1875 -2035.3125 -238 -179 -2034 -238 -180 -2034 - -237 -179 -2034 -236 -178 -2034 -237 -179 -2034 -238 -189 -2047 -236 -188 - -2047 -237 -189 -2047 -238 -190 -2047 -237 -189 -2047 -236 -188.8125 -2045.6875 - -236 -187.875 -2046.125 -237 -188.8125 -2045.6875 -238 -189.75 -2045.25 -237 - -188.8125 -2045.6875 -236 -188.25 -2044.75 -236 -187.5 -2045.5 -237 -188.25 - -2044.75 -238 -189 -2044 -237 -188.25 -2044.75 -236 -188.25 -2044.75 -238 - -189 -2044 -237 -188.25 -2044.75 -236 -187.5 -2045.5 -237 -188.25 -2044.75 - -238 -179.75 -2036.25 -238 -180.5 -2035.5 -237 -179.75 -2036.25 -236 -179 - -2037 -237 -179.75 -2036.25 -238; - setAttr -s 752 ".ed"; - setAttr ".ed[0:165]" 5 0 0 0 1 0 - 1 5 0 1 6 0 6 5 0 1 2 - 0 2 6 0 2 7 0 7 6 0 2 - 3 0 3 7 0 3 8 0 8 7 0 - 3 4 0 4 8 0 4 9 0 9 8 - 0 15 10 0 10 11 0 11 15 0 11 - 16 0 16 15 0 20 15 0 16 20 0 - 16 21 0 21 20 0 11 12 0 12 16 - 0 12 17 0 17 16 0 17 21 0 17 - 22 0 22 21 0 12 13 0 13 17 0 - 13 18 0 18 17 0 18 22 0 18 23 - 0 23 22 0 13 14 0 14 18 0 14 - 19 0 19 18 0 19 23 0 19 24 0 - 24 23 0 30 25 0 25 26 0 26 30 - 0 26 31 0 31 30 0 35 30 0 31 - 35 0 31 36 0 36 35 0 26 27 0 - 27 31 0 27 32 0 32 31 0 32 36 - 0 32 37 0 37 36 0 27 28 0 28 - 32 0 28 33 0 33 32 0 33 37 0 - 33 38 0 38 37 0 28 29 0 29 33 - 0 29 34 0 34 33 0 34 38 0 34 - 39 0 39 38 0 45 40 0 40 41 0 - 41 45 0 41 46 0 46 45 0 41 42 - 0 42 46 0 42 47 0 47 46 0 42 - 43 0 43 47 0 43 48 0 48 47 0 - 43 44 0 44 48 0 44 49 0 49 48 - 0 55 50 0 50 51 0 51 55 0 51 - 56 0 56 55 0 60 55 0 56 60 0 - 56 61 0 61 60 0 65 60 0 61 65 - 0 61 66 0 66 65 0 51 52 0 52 - 56 0 52 57 0 57 56 0 57 61 0 - 57 62 0 62 61 0 62 66 0 62 67 - 0 67 66 0 52 53 0 53 57 0 53 - 58 0 58 57 0 58 62 0 58 63 0 - 63 62 0 63 67 0 63 68 0 68 67 - 0 53 54 0 54 58 0 54 59 0 59 - 58 0 59 63 0 59 64 0 64 63 0 - 64 68 0 64 69 0 69 68 0 75 70 - 0 70 71 0 71 75 0 71 76 0 76 - 75 0 71 72 0 72 76 0 72 77 0 - 77 76 0 72 73 0 73 77 0 73 78 - 0 78 77 0 73 74 0 74 78 0 74 - 79 0 79 78 0 85 80 0 80 81 0 - 81 85 0 81 86 0 86 85 0 81 82 - 0 82 86 0 82 87 0 87 86 0 82 - 83 0 83 87 0 83 88 0; - setAttr ".ed[166:331]" 88 87 0 83 84 0 84 - 88 0 84 89 0 89 88 0 95 90 0 - 90 91 0 91 95 0 91 96 0 96 95 - 0 91 92 0 92 96 0 92 97 0 97 - 96 0 92 93 0 93 97 0 93 98 0 - 98 97 0 93 94 0 94 98 0 94 99 - 0 99 98 0 105 100 0 100 101 0 101 - 105 0 101 106 0 106 105 0 110 105 0 - 106 110 0 106 111 0 111 110 0 101 102 - 0 102 106 0 102 107 0 107 106 0 107 - 111 0 107 112 0 112 111 0 102 103 0 - 103 107 0 103 108 0 108 107 0 108 112 - 0 108 113 0 113 112 0 103 104 0 104 - 108 0 104 109 0 109 108 0 109 113 0 - 109 114 0 114 113 0 120 115 0 115 116 - 0 116 120 0 116 121 0 121 120 0 125 - 120 0 121 125 0 121 126 0 126 125 0 - 116 117 0 117 121 0 117 122 0 122 121 - 0 122 126 0 122 127 0 127 126 0 117 - 118 0 118 122 0 118 123 0 123 122 0 - 123 127 0 123 128 0 128 127 0 118 119 - 0 119 123 0 119 124 0 124 123 0 124 - 128 0 124 129 0 129 128 0 135 130 0 - 130 131 0 131 135 0 131 136 0 136 135 - 0 131 132 0 132 136 0 132 137 0 137 - 136 0 132 133 0 133 137 0 133 138 0 - 138 137 0 133 134 0 134 138 0 134 139 - 0 139 138 0 145 140 0 140 141 0 141 - 145 0 141 146 0 146 145 0 141 142 0 - 142 146 0 142 147 0 147 146 0 142 143 - 0 143 147 0 143 148 0 148 147 0 143 - 144 0 144 148 0 144 149 0 149 148 0 - 155 150 0 150 151 0 151 155 0 151 156 - 0 156 155 0 151 152 0 152 156 0 152 - 157 0 157 156 0 152 153 0 153 157 0 - 153 158 0 158 157 0 153 154 0 154 158 - 0 154 159 0 159 158 0 165 160 0 160 - 161 0 161 165 0 161 166 0 166 165 0 - 161 162 0 162 166 0 162 167 0 167 166 - 0 162 163 0 163 167 0 163 168 0 168 - 167 0 163 164 0 164 168 0 164 169 0 - 169 168 0 175 170 0 170 171 0 171 175 - 0 171 176 0 176 175 0 180 175 0 176 - 180 0 176 181 0 181 180 0 171 172 0 - 172 176 0 172 177 0 177 176 0 177 181 - 0 177 182 0 182 181 0; - setAttr ".ed[332:497]" 172 173 0 173 177 0 173 - 178 0 178 177 0 178 182 0 178 183 0 - 183 182 0 173 174 0 174 178 0 174 179 - 0 179 178 0 179 183 0 179 184 0 184 - 183 0 190 185 0 185 186 0 186 190 0 - 186 191 0 191 190 0 195 190 0 191 195 - 0 191 196 0 196 195 0 186 187 0 187 - 191 0 187 192 0 192 191 0 192 196 0 - 192 197 0 197 196 0 187 188 0 188 192 - 0 188 193 0 193 192 0 193 197 0 193 - 198 0 198 197 0 188 189 0 189 193 0 - 189 194 0 194 193 0 194 198 0 194 199 - 0 199 198 0 205 200 0 200 201 0 201 - 205 0 201 206 0 206 205 0 210 205 0 - 206 210 0 206 211 0 211 210 0 201 202 - 0 202 206 0 202 207 0 207 206 0 207 - 211 0 207 212 0 212 211 0 202 203 0 - 203 207 0 203 208 0 208 207 0 208 212 - 0 208 213 0 213 212 0 203 204 0 204 - 208 0 204 209 0 209 208 0 209 213 0 - 209 214 0 214 213 0 220 215 0 215 216 - 0 216 220 0 216 221 0 221 220 0 225 - 220 0 221 225 0 221 226 0 226 225 0 - 216 217 0 217 221 0 217 222 0 222 221 - 0 222 226 0 222 227 0 227 226 0 217 - 218 0 218 222 0 218 223 0 223 222 0 - 223 227 0 223 228 0 228 227 0 218 219 - 0 219 223 0 219 224 0 224 223 0 224 - 228 0 224 229 0 229 228 0 235 230 0 - 230 231 0 231 235 0 231 236 0 236 235 - 0 231 232 0 232 236 0 232 237 0 237 - 236 0 232 233 0 233 237 0 233 238 0 - 238 237 0 233 234 0 234 238 0 234 239 - 0 239 238 0 245 240 0 240 241 0 241 - 245 0 241 246 0 246 245 0 241 242 0 - 242 246 0 242 247 0 247 246 0 242 243 - 0 243 247 0 243 248 0 248 247 0 243 - 244 0 244 248 0 244 249 0 249 248 0 - 255 250 0 250 251 0 251 255 0 251 256 - 0 256 255 0 251 252 0 252 256 0 252 - 257 0 257 256 0 252 253 0 253 257 0 - 253 258 0 258 257 0 253 254 0 254 258 - 0 254 259 0 259 258 0 265 260 0 260 - 261 0 261 265 0 261 266 0 266 265 0 - 261 262 0 262 266 0 262 267 0 267 266 - 0 262 263 0 263 267 0; - setAttr ".ed[498:663]" 263 268 0 268 267 0 263 - 264 0 264 268 0 264 269 0 269 268 0 - 275 270 0 270 271 0 271 275 0 271 276 - 0 276 275 0 280 275 0 276 280 0 276 - 281 0 281 280 0 271 272 0 272 276 0 - 272 277 0 277 276 0 277 281 0 277 282 - 0 282 281 0 272 273 0 273 277 0 273 - 278 0 278 277 0 278 282 0 278 283 0 - 283 282 0 273 274 0 274 278 0 274 279 - 0 279 278 0 279 283 0 279 284 0 284 - 283 0 290 285 0 285 286 0 286 290 0 - 286 291 0 291 290 0 295 290 0 291 295 - 0 291 296 0 296 295 0 286 287 0 287 - 291 0 287 292 0 292 291 0 292 296 0 - 292 297 0 297 296 0 287 288 0 288 292 - 0 288 293 0 293 292 0 293 297 0 293 - 298 0 298 297 0 288 289 0 289 293 0 - 289 294 0 294 293 0 294 298 0 294 299 - 0 299 298 0 305 300 0 300 301 0 301 - 305 0 301 306 0 306 305 0 301 302 0 - 302 306 0 302 307 0 307 306 0 302 303 - 0 303 307 0 303 308 0 308 307 0 303 - 304 0 304 308 0 304 309 0 309 308 0 - 315 310 0 310 311 0 311 315 0 311 316 - 0 316 315 0 311 312 0 312 316 0 312 - 317 0 317 316 0 312 313 0 313 317 0 - 313 318 0 318 317 0 313 314 0 314 318 - 0 314 319 0 319 318 0 325 320 0 320 - 321 0 321 325 0 321 326 0 326 325 0 - 321 322 0 322 326 0 322 327 0 327 326 - 0 322 323 0 323 327 0 323 328 0 328 - 327 0 323 324 0 324 328 0 324 329 0 - 329 328 0 335 330 0 330 331 0 331 335 - 0 331 336 0 336 335 0 340 335 0 336 - 340 0 336 341 0 341 340 0 345 340 0 - 341 345 0 341 346 0 346 345 0 331 332 - 0 332 336 0 332 337 0 337 336 0 337 - 341 0 337 342 0 342 341 0 342 346 0 - 342 347 0 347 346 0 332 333 0 333 337 - 0 333 338 0 338 337 0 338 342 0 338 - 343 0 343 342 0 343 347 0 343 348 0 - 348 347 0 333 334 0 334 338 0 334 339 - 0 339 338 0 339 343 0 339 344 0 344 - 343 0 344 348 0 344 349 0 349 348 0 - 355 350 0 350 351 0 351 355 0 351 356 - 0 356 355 0 351 352 0; - setAttr ".ed[664:751]" 352 356 0 352 357 0 357 - 356 0 352 353 0 353 357 0 353 358 0 - 358 357 0 353 354 0 354 358 0 354 359 - 0 359 358 0 365 360 0 360 361 0 361 - 365 0 361 366 0 366 365 0 370 365 0 - 366 370 0 366 371 0 371 370 0 361 362 - 0 362 366 0 362 367 0 367 366 0 367 - 371 0 367 372 0 372 371 0 362 363 0 - 363 367 0 363 368 0 368 367 0 368 372 - 0 368 373 0 373 372 0 363 364 0 364 - 368 0 364 369 0 369 368 0 369 373 0 - 369 374 0 374 373 0 380 375 0 375 376 - 0 376 380 0 376 381 0 381 380 0 385 - 380 0 381 385 0 381 386 0 386 385 0 - 376 377 0 377 381 0 377 382 0 382 381 - 0 382 386 0 382 387 0 387 386 0 377 - 378 0 378 382 0 378 383 0 383 382 0 - 383 387 0 383 388 0 388 387 0 378 379 - 0 379 383 0 379 384 0 384 383 0 384 - 388 0 384 389 0 389 388 0 395 390 0 - 390 391 0 391 395 0 391 396 0 396 395 - 0 391 392 0 392 396 0 392 397 0 397 - 396 0 392 393 0 393 397 0 393 398 0 - 398 397 0 393 394 0 394 398 0 394 399 - 0 399 398 0; - setAttr -s 1152 ".n"; - setAttr ".n[0:165]" -type "float3" -0.48507124 0.48507124 0.72760689 - -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 - 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 - 0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 - -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 - 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 0.48507124 -0.48507124 - -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 - 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 - -0.48507124 -0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 - 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 - 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 - 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 - -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 - -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 - -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 - -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 - -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 - -0.7035265 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.59761429 -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 -0.14004973 - -0.70016527 0.70011044 -0.14004973 -0.70016527 0.70011044 -0.14004973 -0.70016527 - 0.70011044 -0.14000282 -0.70017749 0.70010757 -0.14000282 -0.70017749 0.70010757 - -0.14000282 -0.70017749 0.70010757 -0.49467322 -0.49468079 0.71455532 -0.49467322 - -0.49468079 0.71455532 -0.49467322 -0.49468079 0.71455532 -0.49466631 -0.49460971 - 0.71460927 -0.49466631 -0.49460971 0.71460927 -0.49466631 -0.49460971 0.71460927 - -0.70013368 -0.14002161 0.70014763 -0.70013368 -0.14002161 0.70014763 -0.70013368 - -0.14002161 0.70014763 -0.70006388 -0.14002046 0.70021772 -0.70006388 -0.14002046 - 0.70021772 -0.70006388 -0.14002046 0.70021772 -0.13998072 -0.70007664 -0.7002129 - -0.13998072 -0.70007664 -0.7002129 -0.13998072 -0.70007664 -0.7002129 -0.14004515 - -0.70014238 -0.70013422; - setAttr ".n[166:331]" -type "float3" -0.14004515 -0.70014238 -0.70013422 - -0.14004515 -0.70014238 -0.70013422 -0.49473438 -0.49467775 -0.71451509 -0.49473438 - -0.49467775 -0.71451509 -0.49473438 -0.49467775 -0.71451509 -0.49469352 -0.49468598 - -0.71453768 -0.49469352 -0.49468598 -0.71453768 -0.49469352 -0.49468598 -0.71453768 - -0.7001617 -0.14003041 -0.70011789 -0.7001617 -0.14003041 -0.70011789 -0.7001617 - -0.14003041 -0.70011789 -0.70016569 -0.140028 -0.70011437 -0.70016569 -0.140028 - -0.70011437 -0.70016569 -0.140028 -0.70011437 0.14003897 0.70011151 -0.70016634 - 0.14003897 0.70011151 -0.70016634 0.14003897 0.70011151 -0.70016634 0.14003928 - 0.70017236 -0.70010549 0.14003928 0.70017236 -0.70010549 0.14003928 0.70017236 - -0.70010549 0.49468932 0.49468178 -0.71454346 0.49468932 0.49468178 -0.71454346 - 0.49468932 0.49468178 -0.71454346 0.49468854 0.49466592 -0.71455503 0.49468854 - 0.49466592 -0.71455503 0.49468854 0.49466592 -0.71455503 0.70013648 0.14002858 - -0.70014346 0.70013648 0.14002858 -0.70014346 0.70013648 0.14002858 -0.70014346 - 0.70013928 0.14003555 -0.70013928 0.70013928 0.14003555 -0.70013928 0.70013928 - 0.14003555 -0.70013928 0.14002749 0.70011824 0.70016193 0.14002749 0.70011824 - 0.70016193 0.14002749 0.70011824 0.70016193 0.14005812 0.70020729 0.7000668 - 0.14005812 0.70020729 0.7000668 0.14005812 0.70020729 0.7000668 0.49466854 - 0.49464589 0.71458268 0.49466854 0.49464589 0.71458268 0.49466854 0.49464589 - 0.71458268 0.49470854 0.49470854 0.71451169 0.49470854 0.49470854 0.71451169 - 0.49470854 0.49470854 0.71451169 0.70012903 0.14002869 0.70015097 0.70012903 - 0.14002869 0.70015097 0.70012903 0.14002869 0.70015097 0.70011544 0.14001796 - 0.7001667 0.70011544 0.14001796 0.7001667 0.70011544 0.14001796 0.7001667 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 - -0.7035265 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 - -0.7035265 -0.7035265 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 -0.10050378 - -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.7035265 -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.59761429; - setAttr ".n[332:497]" -type "float3" -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.10050378 - -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.7035265 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 - -0.59761429 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 - -0.71713716 -0.59761429 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.48507124 - 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 - -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 - 0.48507124 0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 - -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 - -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 - -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 - -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 - 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 - -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 - 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 - 0.48507124 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0.48507124 - 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 - -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 - 0.48507124 0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 - -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 - -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 - -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 - -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 - 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 - -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 - 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 - 0.48507124 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429; - setAttr ".n[498:663]" -type "float3" -0.10050378 0.7035265 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.10050378 0.7035265 - -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.10050378 - -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 - -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 - -0.59761429 0.35856858 0.71713716 -0.59761429 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 - -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 - -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 - 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 - 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 - 0.59761429 0.35856858 0.71713716 0.59761429 0.10050378 0.7035265 0.7035265 - 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 - 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 - 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 - -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 - 0.59761429 0.35856858 -0.71713716 0.59761429 0.10050378 -0.7035265 0.7035265 - 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 - -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 - 0.7035265 -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 - -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 - -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.10050378 -0.7035265 - -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 - -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 - -0.7035265 -0.7035265 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 - -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 - -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.10050378 - 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 - -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 - -0.10050378 0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 - -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 - -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 - -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 - -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 - -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.10050378 0.7035265 -0.7035265 - -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 - 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 - -0.7035265 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 - -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.35856858 - 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 0.10050378 0.7035265 - 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 - 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 - 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 - 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 - 0.59761429 0.35856858 0.71713716 0.59761429 0.10050378 -0.7035265 0.7035265 - 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 - -0.7035265 0.7035265; - setAttr ".n[664:829]" -type "float3" 0.10050378 -0.7035265 0.7035265 - 0.10050378 -0.7035265 0.7035265 0.35856858 -0.71713716 0.59761429 0.35856858 - -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 - 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 - 0.48507124 0.72760689 0.48507124 0.48507124 0.72760689 0.48507124 0.48507124 - 0.72760689 0.48507124 0.48507124 0.72760689 0.48507124 0.48507124 0.72760689 - 0.48507124 0.48507124 0.72760689 0.48507124 0.48507124 -0.72760689 0.48507124 - 0.48507124 -0.72760689 0.48507124 0.48507124 -0.72760689 0.48507124 0.48507124 - -0.72760689 0.48507124 0.48507124 -0.72760689 0.48507124 0.48507124 -0.72760689 - 0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 -0.72760689 -0.48507124 - -0.48507124 -0.72760689 -0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 - -0.72760689 -0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 0.72760689 - -0.48507124 -0.48507124 0.72760689 -0.48507124 -0.48507124 0.72760689 -0.48507124 - -0.48507124 0.72760689 -0.48507124 -0.48507124 0.72760689 -0.48507124 -0.48507124 - 0.72760689 -0.48507124 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 - 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 - 0 -0.70710677 -0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 - 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0.48507124 0.72760689 0.48507124 0.48507124 0.72760689 - 0.48507124 0.48507124 0.72760689 0.48507124 0.48507124 0.72760689 0.48507124 - 0.48507124 0.72760689 0.48507124 0.48507124 0.72760689 0.48507124 0.48507124 - -0.72760689 0.48507124 0.48507124 -0.72760689 0.48507124 0.48507124 -0.72760689 - 0.48507124 0.48507124 -0.72760689 0.48507124 0.48507124 -0.72760689 0.48507124 - 0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 - -0.72760689 -0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 -0.72760689 - -0.48507124 -0.48507124 -0.72760689 -0.48507124 -0.48507124 -0.72760689 -0.48507124 - -0.48507124 0.72760689 -0.48507124 -0.48507124 0.72760689 -0.48507124 -0.48507124 - 0.72760689 -0.48507124 -0.48507124 0.72760689 -0.48507124 -0.48507124 0.72760689 - -0.48507124 -0.48507124 0.72760689 -0.48507124 -0.10050378 -0.7035265 -0.7035265 - -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 - -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 - -0.7035265 -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 - -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 - -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.10050378 0.7035265 - -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 - -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 - 0.7035265 -0.7035265 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 - -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 - -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 0.10050378 - 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 - 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 - 0.7035265 0.7035265 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 - 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 - 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.10050378 - -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 - 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 - 0.10050378 -0.7035265 0.7035265 0.35856858 -0.71713716 0.59761429 0.35856858 - -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 - 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 - 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 - 0.71713716 0.59761429 0.35856858 0.71713716 0.59761429 0.35856858 0.71713716 - 0.59761429 0.35856858 0.71713716 0.59761429 0.10050378 0.7035265 0.7035265 - 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 - 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 0.10050378 0.7035265 0.7035265 - 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429; - setAttr ".n[830:995]" -type "float3" 0.35856858 -0.71713716 0.59761429 - 0.35856858 -0.71713716 0.59761429 0.35856858 -0.71713716 0.59761429 0.35856858 - -0.71713716 0.59761429 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 - 0.7035265 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 - 0.10050378 -0.7035265 0.7035265 0.10050378 -0.7035265 0.7035265 -0.35856858 - -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 - -0.59761429 -0.35856858 -0.71713716 -0.59761429 -0.35856858 -0.71713716 -0.59761429 - -0.35856858 -0.71713716 -0.59761429 -0.10050378 -0.7035265 -0.7035265 -0.10050378 - -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 - -0.7035265 -0.10050378 -0.7035265 -0.7035265 -0.10050378 -0.7035265 -0.7035265 - -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.35856858 - 0.71713716 -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.35856858 0.71713716 - -0.59761429 -0.35856858 0.71713716 -0.59761429 -0.10050378 0.7035265 -0.7035265 - -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 - 0.7035265 -0.7035265 -0.10050378 0.7035265 -0.7035265 -0.10050378 0.7035265 - -0.7035265 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 - -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 - 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 - 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 -0.70015073 -0.14003143 - -0.70012867 -0.70015073 -0.14003143 -0.70012867 -0.70015073 -0.14003143 -0.70012867 - -0.70008421 -0.14003414 -0.70019466 -0.70008421 -0.14003414 -0.70019466 -0.70008421 - -0.14003414 -0.70019466 -0.49468455 -0.49469209 -0.71453965 -0.49468455 -0.49469209 - -0.71453965 -0.49468455 -0.49469209 -0.71453965 -0.49472329 -0.49466667 -0.71453047 - -0.49472329 -0.49466667 -0.71453047 -0.49472329 -0.49466667 -0.71453047 -0.14005199 - -0.70017022 -0.70010507 -0.14005199 -0.70017022 -0.70010507 -0.14005199 -0.70017022 - -0.70010507 -0.13999423 -0.70014423 -0.70014256 -0.13999423 -0.70014423 -0.70014256 - -0.13999423 -0.70014423 -0.70014256 -0.70011181 -0.14003006 0.70016783 -0.70011181 - -0.14003006 0.70016783 -0.70011181 -0.14003006 0.70016783 -0.70017922 -0.14003713 - 0.70009905 -0.70017922 -0.14003713 0.70009905 -0.70017922 -0.14003713 0.70009905 - -0.49466327 -0.49460667 0.71461356 -0.49466327 -0.49460667 0.71461356 -0.49466327 - -0.49460667 0.71461356 -0.49473152 -0.49472398 0.71448505 -0.49473152 -0.49472398 - 0.71448505 -0.49473152 -0.49472398 0.71448505 -0.13998413 -0.70008409 0.70020479 - -0.13998413 -0.70008409 0.70020479 -0.13998413 -0.70008409 0.70020479 -0.14004526 - -0.70014936 0.7001273 -0.14004526 -0.70014936 0.7001273 -0.14004526 -0.70014936 - 0.7001273 0.70007879 0.14001705 0.70020342 0.70007879 0.14001705 0.70020342 - 0.70007879 0.14001705 0.70020342 0.70013505 0.14003471 0.70014369 0.70013505 - 0.14003471 0.70014369 0.70013505 0.14003471 0.70014369 0.49468291 0.49468291 - 0.71454722 0.49468291 0.49468291 0.71454722 0.49468291 0.49468291 0.71454722 - 0.49466172 0.49464473 0.71458822 0.49466172 0.49464473 0.71458822 0.49466172 - 0.49464473 0.71458822 0.14001864 0.70001626 0.70026565 0.14001864 0.70001626 - 0.70026565 0.14001864 0.70001626 0.70026565 0.14002286 0.70009512 0.70018601 - 0.14002286 0.70009512 0.70018601 0.14002286 0.70009512 0.70018601 0.70016122 - 0.14003512 -0.70011747 0.70016122 0.14003512 -0.70011747 0.70016122 0.14003512 - -0.70011747 0.70010972 0.14001682 -0.7001726 0.70010972 0.14001682 -0.7001726 - 0.70010972 0.14001682 -0.7001726; - setAttr ".n[996:1151]" -type "float3" 0.49467972 0.49466273 -0.71456331 - 0.49467972 0.49466273 -0.71456331 0.49467972 0.49466273 -0.71456331 0.49467275 - 0.49468029 -0.71455598 0.49467275 0.49468029 -0.71455598 0.49467275 0.49468029 - -0.71455598 0.14002733 0.70012224 -0.700158 0.14002733 0.70012224 -0.700158 - 0.14002733 0.70012224 -0.700158 0.1400359 0.70010257 -0.70017594 0.1400359 - 0.70010257 -0.70017594 0.1400359 0.70010257 -0.70017594 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 - -0.70710677 0 -0.70710677 -0.70710677 0 -0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 - -0.70710677 0 0.70710677 -0.70710677 0 0.70710677 0.70710677 0 0.70710677 - 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 0.70710677 0.70710677 - 0 0.70710677 0.70710677 0 0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 0 -0.70710677 0.70710677 - 0 -0.70710677 0.70710677 0 -0.70710677 -0.59761429 0.35856858 -0.71713716 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 - -0.71713716 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.59761429 0.35856858 - 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 - -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 - -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 0.59761429 - -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - 0.59761429 -0.35856858 0.71713716 0.7035265 -0.10050378 0.7035265 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 - 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.7035265 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 - -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 - 0.7035265 -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.7035265 - -0.10050378 0.7035265 0.7035265 -0.10050378 0.7035265 0.59761429 -0.35856858 - 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 - 0.59761429 -0.35856858 0.71713716 0.59761429 -0.35856858 0.71713716 0.59761429 - -0.35856858 0.71713716 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 - -0.7035265 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 - 0.7035265 -0.10050378 -0.7035265 0.7035265 -0.10050378 -0.7035265 0.59761429 - -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 - -0.71713716 0.59761429 -0.35856858 -0.71713716 0.59761429 -0.35856858 -0.71713716 - 0.59761429 -0.35856858 -0.71713716 -0.7035265 0.10050378 -0.7035265 -0.7035265 - 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 - -0.7035265 -0.7035265 0.10050378 -0.7035265 -0.7035265 0.10050378 -0.7035265 - -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 - 0.35856858 -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.59761429 0.35856858 - -0.71713716 -0.59761429 0.35856858 -0.71713716 -0.7035265 0.10050378 0.7035265 - -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 - 0.10050378 0.7035265 -0.7035265 0.10050378 0.7035265 -0.7035265 0.10050378 - 0.7035265 -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 - -0.59761429 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.59761429 - 0.35856858 0.71713716 -0.59761429 0.35856858 0.71713716 -0.48507124 0.48507124 - -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 - -0.48507124 0.48507124 -0.72760689 -0.48507124 0.48507124 -0.72760689 -0.48507124 - 0.48507124 -0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 - 0.72760689 -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 - -0.48507124 0.48507124 0.72760689 -0.48507124 0.48507124 0.72760689 0.48507124 - -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 - 0.72760689 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 0.72760689 - 0.48507124 -0.48507124 0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 - -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 - -0.72760689 0.48507124 -0.48507124 -0.72760689 0.48507124 -0.48507124 -0.72760689; - setAttr -s 384 ".fc[0:383]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 5 0 1 - f 3 -3 3 4 - mu 0 3 5 1 6 - f 3 -4 5 6 - mu 0 3 6 1 2 - f 3 -7 7 8 - mu 0 3 6 2 7 - f 3 -8 9 10 - mu 0 3 7 2 3 - f 3 -11 11 12 - mu 0 3 7 3 8 - f 3 -12 13 14 - mu 0 3 8 3 4 - f 3 -15 15 16 - mu 0 3 8 4 9 - f 3 17 18 19 - mu 0 3 15 10 11 - f 3 -20 20 21 - mu 0 3 15 11 16 - f 3 22 -22 23 - mu 0 3 20 15 16 - f 3 -24 24 25 - mu 0 3 20 16 21 - f 3 -21 26 27 - mu 0 3 16 11 12 - f 3 -28 28 29 - mu 0 3 16 12 17 - f 3 -25 -30 30 - mu 0 3 21 16 17 - f 3 -31 31 32 - mu 0 3 21 17 22 - f 3 -29 33 34 - mu 0 3 17 12 13 - f 3 -35 35 36 - mu 0 3 17 13 18 - f 3 -32 -37 37 - mu 0 3 22 17 18 - f 3 -38 38 39 - mu 0 3 22 18 23 - f 3 -36 40 41 - mu 0 3 18 13 14 - f 3 -42 42 43 - mu 0 3 18 14 19 - f 3 -39 -44 44 - mu 0 3 23 18 19 - f 3 -45 45 46 - mu 0 3 23 19 24 - f 3 47 48 49 - mu 0 3 30 25 26 - f 3 -50 50 51 - mu 0 3 30 26 31 - f 3 52 -52 53 - mu 0 3 35 30 31 - f 3 -54 54 55 - mu 0 3 35 31 36 - f 3 -51 56 57 - mu 0 3 31 26 27 - f 3 -58 58 59 - mu 0 3 31 27 32 - f 3 -55 -60 60 - mu 0 3 36 31 32 - f 3 -61 61 62 - mu 0 3 36 32 37 - f 3 -59 63 64 - mu 0 3 32 27 28 - f 3 -65 65 66 - mu 0 3 32 28 33 - f 3 -62 -67 67 - mu 0 3 37 32 33 - f 3 -68 68 69 - mu 0 3 37 33 38 - f 3 -66 70 71 - mu 0 3 33 28 29 - f 3 -72 72 73 - mu 0 3 33 29 34 - f 3 -69 -74 74 - mu 0 3 38 33 34 - f 3 -75 75 76 - mu 0 3 38 34 39 - f 3 77 78 79 - mu 0 3 45 40 41 - f 3 -80 80 81 - mu 0 3 45 41 46 - f 3 -81 82 83 - mu 0 3 46 41 42 - f 3 -84 84 85 - mu 0 3 46 42 47 - f 3 -85 86 87 - mu 0 3 47 42 43 - f 3 -88 88 89 - mu 0 3 47 43 48 - f 3 -89 90 91 - mu 0 3 48 43 44 - f 3 -92 92 93 - mu 0 3 48 44 49 - f 3 94 95 96 - mu 0 3 55 50 51 - f 3 -97 97 98 - mu 0 3 55 51 56 - f 3 99 -99 100 - mu 0 3 60 55 56 - f 3 -101 101 102 - mu 0 3 60 56 61 - f 3 103 -103 104 - mu 0 3 65 60 61 - f 3 -105 105 106 - mu 0 3 65 61 66 - f 3 -98 107 108 - mu 0 3 56 51 52 - f 3 -109 109 110 - mu 0 3 56 52 57 - f 3 -102 -111 111 - mu 0 3 61 56 57 - f 3 -112 112 113 - mu 0 3 61 57 62 - f 3 -106 -114 114 - mu 0 3 66 61 62 - f 3 -115 115 116 - mu 0 3 66 62 67 - f 3 -110 117 118 - mu 0 3 57 52 53 - f 3 -119 119 120 - mu 0 3 57 53 58 - f 3 -113 -121 121 - mu 0 3 62 57 58 - f 3 -122 122 123 - mu 0 3 62 58 63 - f 3 -116 -124 124 - mu 0 3 67 62 63 - f 3 -125 125 126 - mu 0 3 67 63 68 - f 3 -120 127 128 - mu 0 3 58 53 54 - f 3 -129 129 130 - mu 0 3 58 54 59 - f 3 -123 -131 131 - mu 0 3 63 58 59 - f 3 -132 132 133 - mu 0 3 63 59 64 - f 3 -126 -134 134 - mu 0 3 68 63 64 - f 3 -135 135 136 - mu 0 3 68 64 69 - f 3 137 138 139 - mu 0 3 75 70 71 - f 3 -140 140 141 - mu 0 3 75 71 76 - f 3 -141 142 143 - mu 0 3 76 71 72 - f 3 -144 144 145 - mu 0 3 76 72 77 - f 3 -145 146 147 - mu 0 3 77 72 73 - f 3 -148 148 149 - mu 0 3 77 73 78 - f 3 -149 150 151 - mu 0 3 78 73 74 - f 3 -152 152 153 - mu 0 3 78 74 79 - f 3 154 155 156 - mu 0 3 85 80 81 - f 3 -157 157 158 - mu 0 3 85 81 86 - f 3 -158 159 160 - mu 0 3 86 81 82 - f 3 -161 161 162 - mu 0 3 86 82 87 - f 3 -162 163 164 - mu 0 3 87 82 83 - f 3 -165 165 166 - mu 0 3 87 83 88 - f 3 -166 167 168 - mu 0 3 88 83 84 - f 3 -169 169 170 - mu 0 3 88 84 89 - f 3 171 172 173 - mu 0 3 95 90 91 - f 3 -174 174 175 - mu 0 3 95 91 96 - f 3 -175 176 177 - mu 0 3 96 91 92 - f 3 -178 178 179 - mu 0 3 96 92 97 - f 3 -179 180 181 - mu 0 3 97 92 93 - f 3 -182 182 183 - mu 0 3 97 93 98 - f 3 -183 184 185 - mu 0 3 98 93 94 - f 3 -186 186 187 - mu 0 3 98 94 99 - f 3 188 189 190 - mu 0 3 105 100 101 - f 3 -191 191 192 - mu 0 3 105 101 106 - f 3 193 -193 194 - mu 0 3 110 105 106 - f 3 -195 195 196 - mu 0 3 110 106 111 - f 3 -192 197 198 - mu 0 3 106 101 102 - f 3 -199 199 200 - mu 0 3 106 102 107 - f 3 -196 -201 201 - mu 0 3 111 106 107 - f 3 -202 202 203 - mu 0 3 111 107 112 - f 3 -200 204 205 - mu 0 3 107 102 103 - f 3 -206 206 207 - mu 0 3 107 103 108 - f 3 -203 -208 208 - mu 0 3 112 107 108 - f 3 -209 209 210 - mu 0 3 112 108 113 - f 3 -207 211 212 - mu 0 3 108 103 104 - f 3 -213 213 214 - mu 0 3 108 104 109 - f 3 -210 -215 215 - mu 0 3 113 108 109 - f 3 -216 216 217 - mu 0 3 113 109 114 - f 3 218 219 220 - mu 0 3 120 115 116 - f 3 -221 221 222 - mu 0 3 120 116 121 - f 3 223 -223 224 - mu 0 3 125 120 121 - f 3 -225 225 226 - mu 0 3 125 121 126 - f 3 -222 227 228 - mu 0 3 121 116 117 - f 3 -229 229 230 - mu 0 3 121 117 122 - f 3 -226 -231 231 - mu 0 3 126 121 122 - f 3 -232 232 233 - mu 0 3 126 122 127 - f 3 -230 234 235 - mu 0 3 122 117 118 - f 3 -236 236 237 - mu 0 3 122 118 123 - f 3 -233 -238 238 - mu 0 3 127 122 123 - f 3 -239 239 240 - mu 0 3 127 123 128 - f 3 -237 241 242 - mu 0 3 123 118 119 - f 3 -243 243 244 - mu 0 3 123 119 124 - f 3 -240 -245 245 - mu 0 3 128 123 124 - f 3 -246 246 247 - mu 0 3 128 124 129 - f 3 248 249 250 - mu 0 3 135 130 131 - f 3 -251 251 252 - mu 0 3 135 131 136 - f 3 -252 253 254 - mu 0 3 136 131 132 - f 3 -255 255 256 - mu 0 3 136 132 137 - f 3 -256 257 258 - mu 0 3 137 132 133 - f 3 -259 259 260 - mu 0 3 137 133 138 - f 3 -260 261 262 - mu 0 3 138 133 134 - f 3 -263 263 264 - mu 0 3 138 134 139 - f 3 265 266 267 - mu 0 3 145 140 141 - f 3 -268 268 269 - mu 0 3 145 141 146 - f 3 -269 270 271 - mu 0 3 146 141 142 - f 3 -272 272 273 - mu 0 3 146 142 147 - f 3 -273 274 275 - mu 0 3 147 142 143 - f 3 -276 276 277 - mu 0 3 147 143 148 - f 3 -277 278 279 - mu 0 3 148 143 144 - f 3 -280 280 281 - mu 0 3 148 144 149 - f 3 282 283 284 - mu 0 3 155 150 151 - f 3 -285 285 286 - mu 0 3 155 151 156 - f 3 -286 287 288 - mu 0 3 156 151 152 - f 3 -289 289 290 - mu 0 3 156 152 157 - f 3 -290 291 292 - mu 0 3 157 152 153 - f 3 -293 293 294 - mu 0 3 157 153 158 - f 3 -294 295 296 - mu 0 3 158 153 154 - f 3 -297 297 298 - mu 0 3 158 154 159 - f 3 299 300 301 - mu 0 3 165 160 161 - f 3 -302 302 303 - mu 0 3 165 161 166 - f 3 -303 304 305 - mu 0 3 166 161 162 - f 3 -306 306 307 - mu 0 3 166 162 167 - f 3 -307 308 309 - mu 0 3 167 162 163 - f 3 -310 310 311 - mu 0 3 167 163 168 - f 3 -311 312 313 - mu 0 3 168 163 164 - f 3 -314 314 315 - mu 0 3 168 164 169 - f 3 316 317 318 - mu 0 3 175 170 171 - f 3 -319 319 320 - mu 0 3 175 171 176 - f 3 321 -321 322 - mu 0 3 180 175 176 - f 3 -323 323 324 - mu 0 3 180 176 181 - f 3 -320 325 326 - mu 0 3 176 171 172 - f 3 -327 327 328 - mu 0 3 176 172 177 - f 3 -324 -329 329 - mu 0 3 181 176 177 - f 3 -330 330 331 - mu 0 3 181 177 182 - f 3 -328 332 333 - mu 0 3 177 172 173 - f 3 -334 334 335 - mu 0 3 177 173 178 - f 3 -331 -336 336 - mu 0 3 182 177 178 - f 3 -337 337 338 - mu 0 3 182 178 183 - f 3 -335 339 340 - mu 0 3 178 173 174 - f 3 -341 341 342 - mu 0 3 178 174 179 - f 3 -338 -343 343 - mu 0 3 183 178 179 - f 3 -344 344 345 - mu 0 3 183 179 184 - f 3 346 347 348 - mu 0 3 190 185 186 - f 3 -349 349 350 - mu 0 3 190 186 191 - f 3 351 -351 352 - mu 0 3 195 190 191 - f 3 -353 353 354 - mu 0 3 195 191 196 - f 3 -350 355 356 - mu 0 3 191 186 187 - f 3 -357 357 358 - mu 0 3 191 187 192 - f 3 -354 -359 359 - mu 0 3 196 191 192 - f 3 -360 360 361 - mu 0 3 196 192 197 - f 3 -358 362 363 - mu 0 3 192 187 188 - f 3 -364 364 365 - mu 0 3 192 188 193 - f 3 -361 -366 366 - mu 0 3 197 192 193 - f 3 -367 367 368 - mu 0 3 197 193 198 - f 3 -365 369 370 - mu 0 3 193 188 189 - f 3 -371 371 372 - mu 0 3 193 189 194 - f 3 -368 -373 373 - mu 0 3 198 193 194 - f 3 -374 374 375 - mu 0 3 198 194 199 - f 3 376 377 378 - mu 0 3 205 200 201 - f 3 -379 379 380 - mu 0 3 205 201 206 - f 3 381 -381 382 - mu 0 3 210 205 206 - f 3 -383 383 384 - mu 0 3 210 206 211 - f 3 -380 385 386 - mu 0 3 206 201 202 - f 3 -387 387 388 - mu 0 3 206 202 207 - f 3 -384 -389 389 - mu 0 3 211 206 207 - f 3 -390 390 391 - mu 0 3 211 207 212 - f 3 -388 392 393 - mu 0 3 207 202 203 - f 3 -394 394 395 - mu 0 3 207 203 208 - f 3 -391 -396 396 - mu 0 3 212 207 208 - f 3 -397 397 398 - mu 0 3 212 208 213 - f 3 -395 399 400 - mu 0 3 208 203 204 - f 3 -401 401 402 - mu 0 3 208 204 209 - f 3 -398 -403 403 - mu 0 3 213 208 209 - f 3 -404 404 405 - mu 0 3 213 209 214 - f 3 406 407 408 - mu 0 3 220 215 216 - f 3 -409 409 410 - mu 0 3 220 216 221 - f 3 411 -411 412 - mu 0 3 225 220 221 - f 3 -413 413 414 - mu 0 3 225 221 226 - f 3 -410 415 416 - mu 0 3 221 216 217 - f 3 -417 417 418 - mu 0 3 221 217 222 - f 3 -414 -419 419 - mu 0 3 226 221 222 - f 3 -420 420 421 - mu 0 3 226 222 227 - f 3 -418 422 423 - mu 0 3 222 217 218 - f 3 -424 424 425 - mu 0 3 222 218 223 - f 3 -421 -426 426 - mu 0 3 227 222 223 - f 3 -427 427 428 - mu 0 3 227 223 228 - f 3 -425 429 430 - mu 0 3 223 218 219 - f 3 -431 431 432 - mu 0 3 223 219 224 - f 3 -428 -433 433 - mu 0 3 228 223 224 - f 3 -434 434 435 - mu 0 3 228 224 229 - f 3 436 437 438 - mu 0 3 235 230 231 - f 3 -439 439 440 - mu 0 3 235 231 236 - f 3 -440 441 442 - mu 0 3 236 231 232 - f 3 -443 443 444 - mu 0 3 236 232 237 - f 3 -444 445 446 - mu 0 3 237 232 233 - f 3 -447 447 448 - mu 0 3 237 233 238 - f 3 -448 449 450 - mu 0 3 238 233 234 - f 3 -451 451 452 - mu 0 3 238 234 239 - f 3 453 454 455 - mu 0 3 245 240 241 - f 3 -456 456 457 - mu 0 3 245 241 246 - f 3 -457 458 459 - mu 0 3 246 241 242 - f 3 -460 460 461 - mu 0 3 246 242 247 - f 3 -461 462 463 - mu 0 3 247 242 243 - f 3 -464 464 465 - mu 0 3 247 243 248 - f 3 -465 466 467 - mu 0 3 248 243 244 - f 3 -468 468 469 - mu 0 3 248 244 249 - f 3 470 471 472 - mu 0 3 255 250 251 - f 3 -473 473 474 - mu 0 3 255 251 256 - f 3 -474 475 476 - mu 0 3 256 251 252 - f 3 -477 477 478 - mu 0 3 256 252 257 - f 3 -478 479 480 - mu 0 3 257 252 253 - f 3 -481 481 482 - mu 0 3 257 253 258 - f 3 -482 483 484 - mu 0 3 258 253 254 - f 3 -485 485 486 - mu 0 3 258 254 259 - f 3 487 488 489 - mu 0 3 265 260 261 - f 3 -490 490 491 - mu 0 3 265 261 266 - f 3 -491 492 493 - mu 0 3 266 261 262 - f 3 -494 494 495 - mu 0 3 266 262 267 - f 3 -495 496 497 - mu 0 3 267 262 263 - f 3 -498 498 499 - mu 0 3 267 263 268 - f 3 -499 500 501 - mu 0 3 268 263 264 - f 3 -502 502 503 - mu 0 3 268 264 269 - f 3 504 505 506 - mu 0 3 275 270 271 - f 3 -507 507 508 - mu 0 3 275 271 276 - f 3 509 -509 510 - mu 0 3 280 275 276 - f 3 -511 511 512 - mu 0 3 280 276 281 - f 3 -508 513 514 - mu 0 3 276 271 272 - f 3 -515 515 516 - mu 0 3 276 272 277 - f 3 -512 -517 517 - mu 0 3 281 276 277 - f 3 -518 518 519 - mu 0 3 281 277 282 - f 3 -516 520 521 - mu 0 3 277 272 273 - f 3 -522 522 523 - mu 0 3 277 273 278 - f 3 -519 -524 524 - mu 0 3 282 277 278 - f 3 -525 525 526 - mu 0 3 282 278 283 - f 3 -523 527 528 - mu 0 3 278 273 274 - f 3 -529 529 530 - mu 0 3 278 274 279 - f 3 -526 -531 531 - mu 0 3 283 278 279 - f 3 -532 532 533 - mu 0 3 283 279 284 - f 3 534 535 536 - mu 0 3 290 285 286 - f 3 -537 537 538 - mu 0 3 290 286 291 - f 3 539 -539 540 - mu 0 3 295 290 291 - f 3 -541 541 542 - mu 0 3 295 291 296 - f 3 -538 543 544 - mu 0 3 291 286 287 - f 3 -545 545 546 - mu 0 3 291 287 292 - f 3 -542 -547 547 - mu 0 3 296 291 292 - f 3 -548 548 549 - mu 0 3 296 292 297 - f 3 -546 550 551 - mu 0 3 292 287 288 - f 3 -552 552 553 - mu 0 3 292 288 293 - f 3 -549 -554 554 - mu 0 3 297 292 293 - f 3 -555 555 556 - mu 0 3 297 293 298 - f 3 -553 557 558 - mu 0 3 293 288 289 - f 3 -559 559 560 - mu 0 3 293 289 294 - f 3 -556 -561 561 - mu 0 3 298 293 294 - f 3 -562 562 563 - mu 0 3 298 294 299 - f 3 564 565 566 - mu 0 3 305 300 301 - f 3 -567 567 568 - mu 0 3 305 301 306 - f 3 -568 569 570 - mu 0 3 306 301 302 - f 3 -571 571 572 - mu 0 3 306 302 307 - f 3 -572 573 574 - mu 0 3 307 302 303 - f 3 -575 575 576 - mu 0 3 307 303 308 - f 3 -576 577 578 - mu 0 3 308 303 304 - f 3 -579 579 580 - mu 0 3 308 304 309 - f 3 581 582 583 - mu 0 3 315 310 311 - f 3 -584 584 585 - mu 0 3 315 311 316 - f 3 -585 586 587 - mu 0 3 316 311 312 - f 3 -588 588 589 - mu 0 3 316 312 317 - f 3 -589 590 591 - mu 0 3 317 312 313 - f 3 -592 592 593 - mu 0 3 317 313 318 - f 3 -593 594 595 - mu 0 3 318 313 314 - f 3 -596 596 597 - mu 0 3 318 314 319 - f 3 598 599 600 - mu 0 3 325 320 321 - f 3 -601 601 602 - mu 0 3 325 321 326 - f 3 -602 603 604 - mu 0 3 326 321 322 - f 3 -605 605 606 - mu 0 3 326 322 327 - f 3 -606 607 608 - mu 0 3 327 322 323 - f 3 -609 609 610 - mu 0 3 327 323 328 - f 3 -610 611 612 - mu 0 3 328 323 324 - f 3 -613 613 614 - mu 0 3 328 324 329 - f 3 615 616 617 - mu 0 3 335 330 331 - f 3 -618 618 619 - mu 0 3 335 331 336 - f 3 620 -620 621 - mu 0 3 340 335 336 - f 3 -622 622 623 - mu 0 3 340 336 341 - f 3 624 -624 625 - mu 0 3 345 340 341 - f 3 -626 626 627 - mu 0 3 345 341 346 - f 3 -619 628 629 - mu 0 3 336 331 332 - f 3 -630 630 631 - mu 0 3 336 332 337 - f 3 -623 -632 632 - mu 0 3 341 336 337 - f 3 -633 633 634 - mu 0 3 341 337 342 - f 3 -627 -635 635 - mu 0 3 346 341 342 - f 3 -636 636 637 - mu 0 3 346 342 347 - f 3 -631 638 639 - mu 0 3 337 332 333 - f 3 -640 640 641 - mu 0 3 337 333 338 - f 3 -634 -642 642 - mu 0 3 342 337 338 - f 3 -643 643 644 - mu 0 3 342 338 343 - f 3 -637 -645 645 - mu 0 3 347 342 343 - f 3 -646 646 647 - mu 0 3 347 343 348 - f 3 -641 648 649 - mu 0 3 338 333 334 - f 3 -650 650 651 - mu 0 3 338 334 339 - f 3 -644 -652 652 - mu 0 3 343 338 339 - f 3 -653 653 654 - mu 0 3 343 339 344 - f 3 -647 -655 655 - mu 0 3 348 343 344 - f 3 -656 656 657 - mu 0 3 348 344 349 - f 3 658 659 660 - mu 0 3 355 350 351 - f 3 -661 661 662 - mu 0 3 355 351 356 - f 3 -662 663 664 - mu 0 3 356 351 352 - f 3 -665 665 666 - mu 0 3 356 352 357 - f 3 -666 667 668 - mu 0 3 357 352 353 - f 3 -669 669 670 - mu 0 3 357 353 358 - f 3 -670 671 672 - mu 0 3 358 353 354 - f 3 -673 673 674 - mu 0 3 358 354 359 - f 3 675 676 677 - mu 0 3 365 360 361 - f 3 -678 678 679 - mu 0 3 365 361 366 - f 3 680 -680 681 - mu 0 3 370 365 366 - f 3 -682 682 683 - mu 0 3 370 366 371 - f 3 -679 684 685 - mu 0 3 366 361 362 - f 3 -686 686 687 - mu 0 3 366 362 367 - f 3 -683 -688 688 - mu 0 3 371 366 367 - f 3 -689 689 690 - mu 0 3 371 367 372 - f 3 -687 691 692 - mu 0 3 367 362 363 - f 3 -693 693 694 - mu 0 3 367 363 368 - f 3 -690 -695 695 - mu 0 3 372 367 368 - f 3 -696 696 697 - mu 0 3 372 368 373 - f 3 -694 698 699 - mu 0 3 368 363 364 - f 3 -700 700 701 - mu 0 3 368 364 369 - f 3 -697 -702 702 - mu 0 3 373 368 369 - f 3 -703 703 704 - mu 0 3 373 369 374 - f 3 705 706 707 - mu 0 3 380 375 376 - f 3 -708 708 709 - mu 0 3 380 376 381 - f 3 710 -710 711 - mu 0 3 385 380 381 - f 3 -712 712 713 - mu 0 3 385 381 386 - f 3 -709 714 715 - mu 0 3 381 376 377 - f 3 -716 716 717 - mu 0 3 381 377 382 - f 3 -713 -718 718 - mu 0 3 386 381 382 - f 3 -719 719 720 - mu 0 3 386 382 387 - f 3 -717 721 722 - mu 0 3 382 377 378 - f 3 -723 723 724 - mu 0 3 382 378 383 - f 3 -720 -725 725 - mu 0 3 387 382 383 - f 3 -726 726 727 - mu 0 3 387 383 388 - f 3 -724 728 729 - mu 0 3 383 378 379 - f 3 -730 730 731 - mu 0 3 383 379 384 - f 3 -727 -732 732 - mu 0 3 388 383 384 - f 3 -733 733 734 - mu 0 3 388 384 389 - f 3 735 736 737 - mu 0 3 395 390 391 - f 3 -738 738 739 - mu 0 3 395 391 396 - f 3 -739 740 741 - mu 0 3 396 391 392 - f 3 -742 742 743 - mu 0 3 396 392 397 - f 3 -743 744 745 - mu 0 3 397 392 393 - f 3 -746 746 747 - mu 0 3 397 393 398 - f 3 -747 748 749 - mu 0 3 398 393 394 - f 3 -750 750 751 - mu 0 3 398 394 399 ; -createNode transform -n "m60" -p "celing"; -createNode mesh -n "polySurfaceShape28" -p "m60"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 24 ".uvst[0].uvsp[0:23]" -type "float2" -0.0031570001 - -0.125 -0.0031570001 1.125 0.66346699 1.125 0.66346699 -0.125 0.66346699 - -0.125 -0.0031570001 -0.125 -0.0031570001 1.125 0.66346699 1.125 1.125 0 - -0.125 0 -0.125 1.0000319 1.125 1.0000319 0.654706 -4.9999999e-006 -0.012046 - -4.9999999e-006 -0.012046 0.99989498 0.654706 0.99989498 1.125 0 -0.125 0 - -0.125 1.0000319 1.125 1.0000319 1.01232 -4.9999999e-006 0.345568 -4.9999999e-006 - 0.345568 0.99989498 1.01232 0.99989498; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 24 ".vt[0:23]" -300 -2064 -232 -300 -2064 -152 - -292 -2064 -152 -292 -2064 -232 -292 -1932 -152 -300 -1932 -152 -300 -1932 - -232 -292 -1932 -232 -300 -2064 -152 -300 -2064 -232 -300 -1932 -232 -300 - -1932 -152 -292 -2064 -152 -300 -2064 -152 -300 -1932 -152 -292 -1932 -152 - -292 -2064 -232 -292 -2064 -152 -292 -1932 -152 -292 -1932 -232 -300 -2064 - -232 -292 -2064 -232 -292 -1932 -232 -300 -1932 -232; - setAttr -s 30 ".ed[0:29]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0; - setAttr -s 36 ".n[0:35]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1; - setAttr -s 12 ".fc[0:11]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 ; -createNode transform -n "m62" -p "celing"; -createNode mesh -n "polySurfaceShape29" -p "m62"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 12 ".uvst[0].uvsp[0:11]" -type "float2" -2 1 -2 - 0 0 1 0 0 -2 1 -2 0 0 1 0 0 -3 1 -3 0 0 1 0 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 12 ".vt[0:11]" -160 -1856 112 -96 -1856 112 -160 - -1856 -144 -96 -1856 -144 96 -1856 112 160 -1856 112 96 -1856 -144 160 -1856 - -144 -192 -1856 -224 -192 -1856 -160 192 -1856 -224 192 -1856 -160; - setAttr -s 15 ".ed[0:14]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0 6 - 4 0 4 5 0 5 6 0 5 7 0 - 7 6 0 10 8 0 8 9 0 9 10 - 0 9 11 0 11 10 0; - setAttr -s 18 ".n[0:17]" -type "float3" 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0; - setAttr -s 6 ".fc[0:5]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 - f 3 5 6 7 - mu 0 3 6 4 5 - f 3 -8 8 9 - mu 0 3 6 5 7 - f 3 10 11 12 - mu 0 3 10 8 9 - f 3 -13 13 14 - mu 0 3 10 9 11 ; -createNode transform -n "m64" -p "celing"; -createNode mesh -n "polySurfaceShape30" -p "m64"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 40 ".uvst[0].uvsp[0:39]" -type "float2" 0 1 1 1 - 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 - 1 1 1 0 0 1 0 0 1 -1 1 0 2 -1 2 0 2 -1 2 0 1 -1 1 0 1 1 1 0 0 1 0 0 1 1 1 - 0 0 1 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 40 ".vt[0:39]" -134 -1801 -100 -122 -1801 -100 - -134 -1801 -60 -122 -1801 -60 122 -1801 -100 134 -1801 -100 122 -1801 -60 - 134 -1801 -60 -108 -1801 -198 -108 -1801 -186 -148 -1801 -198 -148 -1801 - -186 148 -1801 -198 148 -1801 -186 108 -1801 -198 108 -1801 -186 -108 -1801 - 154 -108 -1801 166 -148 -1801 154 -148 -1801 166 148 -1801 154 148 -1801 - 166 108 -1801 154 108 -1801 166 -279 -1950 -176 -285 -1950 -176 -279 -1950 - -208 -285 -1950 -208 -265 -1928 -204 -265 -1918 -204 -265 -1928 -180 -265 - -1918 -180 122 -1801 28 134 -1801 28 122 -1801 68 134 -1801 68 -134 -1801 - 20 -122 -1801 20 -134 -1801 60 -122 -1801 60; - setAttr -s 50 ".ed[0:49]" 2 0 0 0 1 - 0 1 2 0 1 3 0 3 2 0 6 - 4 0 4 5 0 5 6 0 5 7 0 - 7 6 0 10 8 0 8 9 0 9 10 - 0 9 11 0 11 10 0 14 12 0 12 - 13 0 13 14 0 13 15 0 15 14 0 - 18 16 0 16 17 0 17 18 0 17 19 - 0 19 18 0 22 20 0 20 21 0 21 - 22 0 21 23 0 23 22 0 26 24 0 - 24 25 0 25 26 0 25 27 0 27 26 - 0 30 28 0 28 29 0 29 30 0 29 - 31 0 31 30 0 34 32 0 32 33 0 - 33 34 0 33 35 0 35 34 0 38 36 - 0 36 37 0 37 38 0 37 39 0 39 - 38 0; - setAttr -s 60 ".n[0:59]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr -s 20 ".fc[0:19]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 0 1 - f 3 -3 3 4 - mu 0 3 2 1 3 - f 3 5 6 7 - mu 0 3 6 4 5 - f 3 -8 8 9 - mu 0 3 6 5 7 - f 3 10 11 12 - mu 0 3 10 8 9 - f 3 -13 13 14 - mu 0 3 10 9 11 - f 3 15 16 17 - mu 0 3 14 12 13 - f 3 -18 18 19 - mu 0 3 14 13 15 - f 3 20 21 22 - mu 0 3 18 16 17 - f 3 -23 23 24 - mu 0 3 18 17 19 - f 3 25 26 27 - mu 0 3 22 20 21 - f 3 -28 28 29 - mu 0 3 22 21 23 - f 3 30 31 32 - mu 0 3 26 24 25 - f 3 -33 33 34 - mu 0 3 26 25 27 - f 3 35 36 37 - mu 0 3 30 28 29 - f 3 -38 38 39 - mu 0 3 30 29 31 - f 3 40 41 42 - mu 0 3 34 32 33 - f 3 -43 43 44 - mu 0 3 34 33 35 - f 3 45 46 47 - mu 0 3 38 36 37 - f 3 -48 48 49 - mu 0 3 38 37 39 ; -createNode transform -n "m66" -p "celing"; -createNode mesh -n "polySurfaceShape31" -p "m66"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 28 ".uvst[0].uvsp[0:27]" -type "float2" -4.2e-005 - 0 -4.2e-005 1 0.999942 1 0.999942 0 -4.2e-005 0 -4.2e-005 1 0.999942 1 0.999942 - 0 0.001671 0 0.001671 1 1.0016069 1 1.0016069 0 0.001653 0 0.001653 1 1.0015889 - 1 1.0015889 0 0.001671 0 0.001671 1 1.0016069 1 1.0016069 0 0.001653 0 0.001653 - 1 1.0015889 1 1.0015889 0 -3.9999999e-005 0 -3.9999999e-005 1 0.99994397 - 1 0.99994397 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 28 ".vt[0:27]" -136 -1800 -56 -120 -1800 -56 -120 - -1800 -104 -136 -1800 -104 120 -1800 -56 136 -1800 -56 136 -1800 -104 120 - -1800 -104 -152 -1800 -200 -152 -1800 -184 -104 -1800 -184 -104 -1800 -200 - 104 -1800 -200 104 -1800 -184 152 -1800 -184 152 -1800 -200 -152 -1800 152 - -152 -1800 168 -104 -1800 168 -104 -1800 152 104 -1800 152 104 -1800 168 - 152 -1800 168 152 -1800 152 -136 -1800 64 -120 -1800 64 -120 -1800 16 -136 - -1800 16; - setAttr -s 35 ".ed[0:34]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0; - setAttr -s 42 ".n[0:41]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr -s 14 ".fc[0:13]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 ; -createNode transform -n "m68" -p "celing"; -createNode mesh -n "polySurfaceShape32" -p "m68"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 0 -0.00054400001 - 0 0.99947 1 0.99947 1 -0.00054400001; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" -16 -1944.0029 -240 -16 -1940.0029 - -228 16 -1940.0029 -228 16 -1944.0029 -240; - setAttr -s 5 ".ed[0:4]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0 -0.94868332 0.31622776 - 0 -0.94868332 0.31622776 0 -0.94868332 0.31622776 0 -0.94868332 0.31622776 - 0 -0.94868332 0.31622776 0 -0.94868332 0.31622776; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 ; -createNode transform -n "m70" -p "celing"; -createNode mesh -n "polySurfaceShape33" -p "m70"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 20 ".uvst[0].uvsp[0:19]" -type "float2" 38.531479 - -5.0937052 38.531479 -4.999928 38.625233 -4.999928 38.625233 -5.124958 50.186588 - -5.0937052 50.186588 -4.999928 50.436604 -4.999928 50.436604 -5.0937052 51.124767 - -5.124958 51.124767 -4.999928 51.218521 -4.999928 51.218521 -5.0937052 39.313393 - -5.124958 39.313393 -4.999928 39.563408 -4.999928 39.563408 -5.124958 51.124767 - -0.56220502 51.218521 -0.56220502 51.218521 -0.81222099 51.124767 -0.81222099; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 20 ".vt[0:19]" 16 -1940.0026 -228 16 -1928 -228 - 16 -1928 -240 16 -1944.0027 -240 -16 -1940.0026 -228 -16 -1928 -228 16 -1928 - -228 16 -1940.0026 -228 -16 -1944.0027 -240 -16 -1928 -240 -16 -1928 -228 - -16 -1940.0026 -228 16 -1944.0027 -240 16 -1928 -240 -16 -1928 -240 -16 -1944.0027 - -240 16 -1928 -240 16 -1928 -228 -16 -1928 -228 -16 -1928 -240; - setAttr -s 25 ".ed[0:24]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0; - setAttr -s 30 ".n[0:29]" -type "float3" 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0; - setAttr -s 10 ".fc[0:9]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 ; -createNode transform -n "m72" -p "celing"; -createNode mesh -n "polySurfaceShape34" -p "m72"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 174 ".uvst[0].uvsp[0:173]" -type "float2" 0.0074809999 - 0.79844302 0.0108 0.89370698 0.156238 0.89370698 0.195613 0.79842401 0.0108 - 0.923437 0.156238 0.923437 0.0108 0.953462 0.156238 0.953462 0.208646 0.85422599 - 0.211964 0.89110303 0.570149 0.666637 0.55447 0.73651099 0.723804 0.67628801 - 0.58164799 0.0074049998 0.58164799 0.062692001 0.67649299 0.0074049998 0.200811 - 0.66936803 0.200811 0.712008 0.25620499 0.71312398 0.200811 0.63353902 0.25635201 - 0.63392001 0.25561199 0.50036103 0.51972002 0.91311902 0.71670902 0.86250198 - 0.414435 0.76756197 0.99002498 0.72715801 0.41900501 0.97205698 0.67646301 - 0.062752999 0.98939002 0.0071120001 0.94810402 0.46093801 0.73897499 0.52886498 - 0.65377301 0.493238 0.58164799 0.530927 0.58164799 0.494744 0.65377301 0.33081299 - 0.26829299 0.27458099 0.26223499 0.50230002 0.28692999 0.312511 0.73477501 - 0.106739 0.58164799 0.107484 0.73157299 0.27241501 0.58164799 0.27396199 - 0.48530799 0.50646001 0.53918898 0.671992 0.54157901 0.50759399 0.48530799 - 0.67237902 0.436921 0.72017503 0.58164799 0.33235499 0.275013 0.91537499 - 0.288975 0.99715501 0.31738499 0.98160702 0.0108 0.99576598 0.35883999 0.85600603 - 0.29493999 0.84652901 0.33276999 0.81849599 0.0074809999 0.720204 0.70867699 - 0.310473 0.58164799 0.312002 0.33196601 0.49472699 0.33196601 0.320335 0.258995 - 0.112779 0.200956 0.113928 0.26157501 0.276191 0.30671901 0.0075630001 0.244828 - 0.069164 0.30690899 0.068811998 0.244828 0.0059199999 0.51113403 0.70270097 - 0.25379899 0.67085999 0.34274 0.53743601 0.34274 0.67253602 0.42590401 0.67253602 - 0.42590401 0.53743601 0.28451401 0.50646001 0.28333601 0.67237902 0.010628 - 0.66936803 0.010628 0.712008 0.010628 0.63353902 0.011391 0.0059199999 0.464371 - 0.49419799 0.544577 0.49344999 0.464371 0.202236 0.54176497 0.122997 0.44884899 - 0.185569 0.415016 0.179869 0.28376299 0.115134 0.28376299 0.17857599 0.156238 - 0.89370698 0.195613 0.79842401 0.156238 0.923437 0.156238 0.953462 0.208646 - 0.85422599 0.211964 0.89110303 0.570149 0.666637 0.723804 0.67628801 0.55447 - 0.73651099 0.58164799 0.0074049998 0.67649299 0.0074049998 0.58164799 0.062692001 - 0.200811 0.66936803 0.25620499 0.71312398 0.200811 0.712008 0.200811 0.63353902 - 0.25635201 0.63392001 0.25561199 0.50036103 0.71670902 0.86250198 0.51972002 - 0.91311902 0.414435 0.76756197 0.99002498 0.72715801 0.41900501 0.97205698 - 0.98939002 0.0071120001 0.67646301 0.062752999 0.94810402 0.46093801 0.73897499 - 0.52886498 0.65377301 0.493238 0.58164799 0.530927 0.58164799 0.494744 0.65377301 - 0.33081299 0.26829299 0.27458099 0.28692999 0.312511 0.26223499 0.50230002 - 0.73477501 0.106739 0.73157299 0.27241501 0.58164799 0.107484 0.58164799 - 0.27396199 0.48530799 0.50646001 0.54157901 0.50759399 0.436921 0.72017503 - 0.58164799 0.33235499 0.275013 0.91537499 0.31738499 0.98160702 0.288975 - 0.99715501 0.35883999 0.85600603 0.29493999 0.84652901 0.33276999 0.81849599 - 0.70867699 0.310473 0.58164799 0.312002 0.33196601 0.320335 0.33196601 0.49472699 - 0.258995 0.112779 0.26157501 0.276191 0.200956 0.113928 0.30671901 0.0075630001 - 0.30690899 0.068811998 0.244828 0.069164 0.244828 0.0059199999 0.51113403 - 0.70270097 0.25379899 0.67085999 0.34274 0.53743601 0.42590401 0.53743601 - 0.28451401 0.50646001 0.010628 0.712008 0.010628 0.66936803 0.010628 0.63353902 - 0.011391 0.0059199999 0.464371 0.49419799 0.464371 0.202236 0.544577 0.49344999 - 0.54176497 0.122997 0.44884899 0.185569 0.415016 0.179869 0.0074809999 0.79844302 - 0.0108 0.89370698 0.0108 0.923437 0.0108 0.953462 0.53918898 0.671992 0.48530799 - 0.67237902 0.0108 0.99576598 0.0074809999 0.720204 0.34274 0.67253602 0.42590401 - 0.67253602 0.28333601 0.67237902 0.28376299 0.115134 0.28376299 0.17857599; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 174 ".vt"; - setAttr ".vt[0:165]" -266.95117 -1929.764 -192 -265 -1913.5 -192 - -265 -1913.5 -204.83423 -266.96109 -1929.7671 -208.41742 -270 -1913 -192 - -270 -1913 -204.83423 -280.5 -1915.5 -192 -280.5 -1915.5 -204.83423 -265.39999 - -1917.8 -208.39723 -270.39999 -1917.3 -208.39723 -270.33002 -1949.8263 -229.82539 - -268.24844 -1937.897 -228.50949 -269.04572 -1947.6837 -234.41383 -265.74423 - -2064.2312 -230.79047 -265.72797 -2052.9353 -230.79047 -265.7619 -2064.2312 - -234.5731 -274.79965 -1948.4811 -221.12927 -274.79965 -1946.3502 -215.15959 - -270.06332 -1940.6859 -218.64384 -274.79965 -1954.7128 -223.86816 -270.33002 - -1949.8263 -229.82539 -270.11404 -1977.8762 -230.79047 -288.15131 -1921.0875 - -223.29071 -288.15131 -1927.9788 -234.32782 -267.18057 -1932.5957 -215.08228 - -288.15131 -1938.9656 -240.51169 -288.15131 -1912.2668 -215.7459 -265.74585 - -2052.9248 -234.57056 -288.15131 -2064.2312 -240.54231 -284.30688 -1984.5912 - -240.54231 -270.07791 -1977.8492 -235.2567 -264.24551 -1979.1707 -234.33855 - -270.11404 -1977.8762 -230.79047 -264.24515 -1979.1727 -230.79047 -264.26053 - -2009.036 -234.33855 -269.60419 -2016.866 -230.79047 -270.11404 -1977.8762 - -230.79047 -268.03549 -2010.3716 -230.79047 -269.79218 -2045.2949 -235.21144 - -269.82474 -2045.2881 -230.79047 -269.57434 -2016.901 -235.17694 -269.60419 - -2016.866 -230.79047 -274.79965 -1946.3502 -215.15959 -270.26447 -1940.681 - -192 -270.06332 -1940.6859 -218.64384 -274.79965 -1945.8667 -192 -270.06332 - -1940.6859 -218.64384 -264.26016 -2009.032 -230.79047 -277.33823 -1918.9519 - -208.39723 -288.15131 -1908.47 -207.89804 -288.15131 -1910.4554 -210.21997 - -288.15131 -1908.707 -192 -276.04352 -1922.0717 -212.92613 -267.42487 -1921.5544 - -208.39865 -269.16589 -1926.3403 -211.57364 -270.26447 -1940.681 -192 -268.01651 - -2010.3784 -234.93021 -268.03549 -2010.3716 -230.79047 -264.24515 -1979.1727 - -230.79047 -264.26016 -2009.032 -230.79047 -269.82474 -2045.2881 -230.79047 - -274.78723 -2045.0883 -223.86816 -269.60419 -2016.866 -230.79047 -265.74423 - -2064.2312 -230.79047 -271.0361 -2052.874 -223.86816 -265.72797 -2052.9353 - -230.79047 -271.0361 -2064.2312 -223.86816 -269.98975 -1943.6692 -224.87241 - -269.98975 -1943.6692 -224.87241 -286.79965 -1948.2496 -210.32208 -286.79965 - -1947.9664 -192 -279.79965 -1947.9664 -192 -279.79965 -1948.2496 -210.32208 - -292.21747 -1946.3502 -215.15959 -292.21747 -1945.8667 -192 -292.21747 -1948.4811 - -221.12927 -292.21747 -1946.3502 -215.15959 -292.21747 -1954.7128 -223.86816 - -292.21747 -2064.2312 -223.86816 -292.21747 -2064.2312 -223.86816 -292.21747 - -2064.2312 -239.93806 -292.21747 -1954.7128 -223.86816 -292.21747 -1925.0862 - -239.42126 -292.21747 -1948.4811 -221.12927 -292.21747 -1946.3502 -215.15959 - -292.21747 -1922.1464 -192 -292.21747 -1945.8667 -192 -265 -1913.5 -179.16577 - -266.96109 -1929.7671 -175.58258 -270 -1913 -179.16577 -280.5 -1915.5 -179.16577 - -265.39999 -1917.8 -175.60277 -270.39999 -1917.3 -175.60277 -270.33002 -1949.8263 - -154.17461 -269.04572 -1947.6837 -149.58617 -268.24844 -1937.897 -155.49051 - -265.74423 -2064.2312 -153.20953 -265.7619 -2064.2312 -149.4269 -265.72797 - -2052.9353 -153.20953 -274.79965 -1948.4811 -162.87073 -270.06332 -1940.6859 - -165.35616 -274.79965 -1946.3502 -168.84041 -274.79965 -1954.7128 -160.13184 - -270.33002 -1949.8263 -154.17461 -270.11404 -1977.8762 -153.20953 -288.15131 - -1927.9788 -149.67218 -288.15131 -1921.0875 -160.70929 -267.18057 -1932.5957 - -168.91772 -288.15131 -1938.9656 -143.48831 -288.15131 -1912.2668 -168.2541 - -288.15131 -2064.2312 -143.45769 -265.74585 -2052.9248 -149.42944 -284.30688 - -1984.5912 -143.45769 -270.07791 -1977.8492 -148.7433 -264.28091 -1979.1707 - -149.66145 -270.11404 -1977.8762 -153.20953 -264.24478 -1979.1727 -153.20953 - -264.28091 -2009.036 -149.66145 -269.60419 -2016.866 -153.20953 -268.03549 - -2010.3716 -153.20953 -270.11404 -1977.8762 -153.20953 -269.79218 -2045.2949 - -148.78856 -269.57434 -2016.901 -148.82306 -269.82474 -2045.2881 -153.20953 - -269.60419 -2016.866 -153.20953 -274.79965 -1946.3502 -168.84041 -270.06332 - -1940.6859 -165.35616 -270.06332 -1940.6859 -165.35616 -264.24478 -2009.032 - -153.20953 -277.33823 -1918.9519 -175.60277 -288.15131 -1910.4554 -173.78003 - -288.15131 -1908.47 -176.10196 -276.04352 -1922.0717 -171.07387 -267.42487 - -1921.5544 -175.60135 -269.16589 -1926.3403 -172.42636 -268.01651 -2010.3784 - -149.06979 -268.03549 -2010.3716 -153.20953 -264.24478 -2009.032 -153.20953 - -264.24478 -1979.1727 -153.20953 -269.82474 -2045.2881 -153.20953 -269.60419 - -2016.866 -153.20953 -274.78723 -2045.0883 -160.13184 -265.74423 -2064.2312 - -153.20953 -265.72797 -2052.9353 -153.20953 -271.0361 -2052.874 -160.13184 - -271.0361 -2064.2312 -160.13184 -269.98975 -1943.6692 -159.12759 -269.98975 - -1943.6692 -159.12759 -286.79965 -1948.2496 -173.67792 -279.79965 -1948.2496 - -173.67792 -292.21747 -1946.3502 -168.84041 -292.21747 -1946.3502 -168.84041 - -292.21747 -1948.4811 -162.87073 -292.21747 -1954.7128 -160.13184 -292.21747 - -2064.2312 -160.13184 -292.21747 -2064.2312 -160.13184 -292.21747 -1954.7128 - -160.13184 -292.21747 -2064.2312 -144.06194 -292.21747 -1925.0862 -144.57874 - -292.21747 -1948.4811 -162.87073 -292.21747 -1946.3502 -168.84041 -266.95117 - -1929.764 -192 -265 -1913.5 -192 -270 -1913 -192 -280.5 -1915.5 -192 -270.26447 - -1940.681 -192; - setAttr ".vt[166:173]" -274.79965 -1945.8667 -192 -288.15131 -1908.707 - -192 -270.26447 -1940.681 -192 -286.79965 -1947.9664 -192 -279.79965 -1947.9664 - -192 -292.21747 -1945.8667 -192 -292.21747 -1922.1464 -192 -292.21747 -1945.8667 - -192; - setAttr -s 372 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 0 3 0 3 2 0 2 4 - 0 4 1 0 5 4 0 2 5 0 4 - 7 0 7 6 0 6 4 0 5 7 0 - 8 2 0 3 8 0 2 9 0 9 5 - 0 8 9 0 12 11 0 11 10 0 10 - 12 0 15 14 0 14 13 0 13 15 0 - 18 17 0 17 16 0 16 18 0 20 16 - 0 16 19 0 19 20 0 19 21 0 21 - 20 0 23 22 0 22 11 0 11 23 0 - 22 24 0 24 11 0 25 11 0 12 25 - 0 25 23 0 22 26 0 26 24 0 28 - 27 0 27 15 0 15 28 0 12 29 0 - 29 25 0 12 30 0 30 29 0 30 32 - 0 32 31 0 31 30 0 32 33 0 33 - 31 0 31 29 0 33 34 0 34 31 0 - 37 36 0 36 35 0 35 37 0 29 28 - 0 28 25 0 40 39 0 39 38 0 38 - 40 0 40 41 0 41 39 0 39 14 0 - 14 38 0 27 38 0 14 27 0 28 38 - 0 44 43 0 43 42 0 42 44 0 43 - 45 0 45 42 0 24 46 0 46 11 0 - 33 47 0 47 34 0 29 40 0 40 28 - 0 5 48 0 48 7 0 9 48 0 50 - 49 0 49 48 0 48 50 0 7 51 0 - 51 6 0 49 7 0 49 51 0 48 52 - 0 52 50 0 26 50 0 52 26 0 52 - 24 0 53 8 0 3 53 0 53 9 0 - 53 48 0 53 52 0 52 54 0 54 24 - 0 54 3 0 3 24 0 54 53 0 24 - 55 0 55 46 0 56 41 0 40 56 0 - 29 56 0 47 56 0 56 34 0 47 57 - 0 57 56 0 57 41 0 59 58 0 58 - 37 0 37 59 0 58 36 0 31 56 0 - 62 61 0 61 60 0 60 62 0 65 64 - 0 64 63 0 63 65 0 64 66 0 66 - 63 0 12 32 0 10 32 0 11 67 0 - 67 10 0 68 16 0 20 68 0 68 18 - 0 46 67 0 24 0 0 0 55 0 71 - 70 0 70 69 0 69 71 0 69 72 0 - 72 71 0 45 71 0 72 45 0 72 42 - 0 73 42 0 72 73 0 69 73 0 70 - 74 0 74 69 0 74 73 0 76 75 0 - 75 16 0 16 76 0 17 76 0 16 77 - 0 77 19 0 75 77 0 77 61 0 61 - 19 0 77 78 0 78 61 0; - setAttr ".ed[166:331]" 64 61 0 78 64 0 78 - 66 0 81 80 0 80 79 0 79 81 0 - 81 82 0 82 80 0 83 82 0 81 83 - 0 84 82 0 83 84 0 85 82 0 84 - 85 0 86 85 0 84 86 0 62 21 0 - 21 61 0 60 64 0 65 60 0 162 87 - 0 87 161 0 161 162 0 87 88 0 88 - 161 0 163 87 0 162 163 0 163 89 0 - 89 87 0 90 163 0 163 164 0 164 90 - 0 90 89 0 87 91 0 91 88 0 89 - 92 0 92 87 0 92 91 0 95 94 0 - 94 93 0 93 95 0 98 97 0 97 96 - 0 96 98 0 101 100 0 100 99 0 99 - 101 0 99 103 0 103 102 0 102 99 0 - 103 104 0 104 102 0 106 105 0 105 95 - 0 95 106 0 107 106 0 95 107 0 95 - 108 0 108 94 0 105 108 0 109 106 0 - 107 109 0 111 110 0 110 97 0 97 111 - 0 108 112 0 112 94 0 113 94 0 112 - 113 0 115 113 0 113 114 0 114 115 0 - 114 116 0 116 115 0 112 114 0 114 117 - 0 117 116 0 120 119 0 119 118 0 118 - 120 0 108 110 0 110 112 0 123 122 0 - 122 121 0 121 123 0 124 122 0 123 124 - 0 121 98 0 98 123 0 121 111 0 111 - 98 0 121 110 0 165 126 0 126 125 0 - 125 165 0 166 165 0 125 166 0 95 127 - 0 127 107 0 128 116 0 117 128 0 122 - 112 0 110 122 0 90 129 0 129 89 0 - 129 92 0 131 130 0 130 129 0 129 131 - 0 167 90 0 164 167 0 90 131 0 167 - 131 0 130 132 0 132 129 0 130 109 0 - 109 132 0 107 132 0 91 133 0 133 88 - 0 92 133 0 129 133 0 132 133 0 134 - 132 0 107 134 0 88 134 0 107 88 0 - 133 134 0 168 107 0 127 168 0 124 135 - 0 135 122 0 135 112 0 117 135 0 135 - 128 0 136 128 0 135 136 0 124 136 0 - 138 137 0 137 119 0 119 138 0 120 138 - 0 135 114 0 141 140 0 140 139 0 139 - 141 0 144 143 0 143 142 0 142 144 0 - 142 145 0 145 144 0 115 94 0 115 93 - 0 146 95 0 93 146 0 99 147 0 147 - 103 0 100 147 0 146 127 0 161 107 0 - 168 161 0 169 170 0 170 148 0 148 169 - 0 170 149 0 149 148 0; - setAttr ".ed[332:371]" 170 166 0 166 149 0 125 - 149 0 125 150 0 150 149 0 150 148 0 - 171 169 0 148 171 0 150 171 0 152 151 - 0 151 99 0 99 152 0 151 101 0 153 - 99 0 102 153 0 153 152 0 102 141 0 - 141 153 0 141 154 0 154 153 0 141 144 - 0 144 154 0 145 154 0 157 156 0 156 - 155 0 155 157 0 158 156 0 157 158 0 - 158 159 0 159 156 0 158 160 0 160 159 - 0 158 172 0 172 160 0 172 173 0 173 - 160 0 104 140 0 141 104 0 144 139 0 - 139 143 0; - setAttr -s 624 ".n"; - setAttr ".n[0:165]" -type "float3" 0.99288052 -0.11911437 2.2341132e-007 - 0.99288052 -0.11911437 2.2341132e-007 0.99288052 -0.11911437 2.2341132e-007 - 0.99282646 -0.11956296 -0.00057789154 0.99282646 -0.11956296 -0.00057789154 - 0.99282646 -0.11956296 -0.00057789154 0.099503346 0.99503726 0 0.099503346 - 0.99503726 0 0.099503346 0.99503726 0 0.099503718 0.9950372 0 0.099503718 - 0.9950372 0 0.099503718 0.9950372 0 -0.23162033 0.97280622 0 -0.23162033 - 0.97280622 0 -0.23162033 0.97280622 0 -0.23162052 0.97280622 0 -0.23162052 - 0.97280622 0 -0.23162052 0.97280622 0 0.99059159 -0.12929918 0.044832647 - 0.99059159 -0.12929918 0.044832647 0.99059159 -0.12929918 0.044832647 0.063326545 - 0.63324934 -0.77135277 0.063326545 0.63324934 -0.77135277 0.063326545 0.63324934 - -0.77135277 0.063324504 0.63325882 -0.77134508 0.063324504 0.63325882 -0.77134508 - 0.063324504 0.63325882 -0.77134508 0.9650467 -0.18847834 0.18210085 0.9650467 - -0.18847834 0.18210085 0.9650467 -0.18847834 0.18210085 0.99998802 -0.0014395419 - -0.004671305 0.99998802 -0.0014395419 -0.004671305 0.99998802 -0.0014395419 - -0.004671305 0.80845904 -0.55430335 0.19784272 0.80845904 -0.55430335 0.19784272 - 0.80845904 -0.55430335 0.19784272 0.85659361 -0.20762059 0.47237816 0.85659361 - -0.20762059 0.47237816 0.85659361 -0.20762059 0.47237816 0.80536246 -0.014188173 - 0.59261286 0.80536246 -0.014188173 0.59261286 0.80536246 -0.014188173 0.59261286 - 0.50011486 0.73453653 -0.45862973 0.50011486 0.73453653 -0.45862973 0.50011486 - 0.73453653 -0.45862973 0.55162036 0.75990111 -0.34389722 0.55162036 0.75990111 - -0.34389722 0.55162036 0.75990111 -0.34389722 0.44778517 0.43485814 -0.78127259 - 0.44778517 0.43485814 -0.78127259 0.44778517 0.43485814 -0.78127259 0.44662595 - 0.43884903 -0.77970302 0.44662595 0.43884903 -0.77970302 0.44662595 0.43884903 - -0.77970302 0.54743069 0.54395568 -0.63594955 0.54743069 0.54395568 -0.63594955 - 0.54743069 0.54395568 -0.63594955 0.25761163 -0.00014788783 -0.96624851 0.25761163 - -0.00014788783 -0.96624851 0.25761163 -0.00014788783 -0.96624851 0.31518486 - 0.02719434 -0.94864058 0.31518486 0.02719434 -0.94864058 0.31518486 0.02719434 - -0.94864058 0.34211779 0.014545841 -0.9395445 0.34211779 0.014545841 -0.9395445 - 0.34211779 0.014545841 -0.9395445 0.21980801 0.97551322 0.0076443283 0.21980801 - 0.97551322 0.0076443283 0.21980801 0.97551322 0.0076443283 0.21571079 0.97645712 - 0.00057469431 0.21571079 0.97645712 0.00057469431 0.21571079 0.97645712 0.00057469431 - 0.21183687 0.28562608 -0.93463516 0.21183687 0.28562608 -0.93463516 0.21183687 - 0.28562608 -0.93463516 0.99999988 -0.00050218112 -0.00010351989 0.99999988 - -0.00050218112 -0.00010351989 0.99999988 -0.00050218112 -0.00010351989 1.4712921e-006 - 0 1 1.4712921e-006 0 1 1.4712921e-006 0 1 -0.005063904 0.00024447139 -0.99998713 - -0.005063904 0.00024447139 -0.99998713 -0.005063904 0.00024447139 -0.99998713 - 0.99994332 -0.0076808459 0.0073766918 0.99994332 -0.0076808459 0.0073766918 - 0.99994332 -0.0076808459 0.0073766918 0.99994636 -0.0077586225 0.0068655959 - 0.99994636 -0.0077586225 0.0068655959 0.99994636 -0.0077586225 0.0068655959 - 0.88146293 0.47221813 0.0057634963 0.88146293 0.47221813 0.0057634963 0.88146293 - 0.47221813 0.0057634963 0.88354939 0.46832895 -0.0029002614 0.88354939 0.46832895 - -0.0029002614 0.88354939 0.46832895 -0.0029002614 0.23653811 0.043914121 - -0.97062927 0.23653811 0.043914121 -0.97062927 0.23653811 0.043914121 -0.97062927 - 0.99998778 -0.0014184361 -0.0047348808 0.99998778 -0.0014184361 -0.0047348808 - 0.99998778 -0.0014184361 -0.0047348808 0.76892459 -0.63931203 0.0059264139 - 0.76892459 -0.63931203 0.0059264139 0.76892459 -0.63931203 0.0059264139 0.75266999 - -0.65825462 0.013737487 0.75266999 -0.65825462 0.013737487 0.75266999 -0.65825462 - 0.013737487 0.92978895 -0.36160332 0.068815738 0.92978895 -0.36160332 0.068815738 - 0.92978895 -0.36160332 0.068815738 0.99999988 -0.00050246093 -0.00010266948 - 0.99999988 -0.00050246093 -0.00010266948 0.99999988 -0.00050246093 -0.00010266948 - 0.31276006 -0.015097798 -0.94971216 0.31276006 -0.015097798 -0.94971216 0.31276006 - -0.015097798 -0.94971216 0.27978018 -0.00098008534 -0.96006358 0.27978018 - -0.00098008534 -0.96006358 0.27978018 -0.00098008534 -0.96006358 -0.15213497 - 0.63896203 -0.75404406 -0.15213497 0.63896203 -0.75404406 -0.15213497 0.63896203 - -0.75404406 -0.15212242 0.63895482 -0.7540527 -0.15212242 0.63895482 -0.7540527 - -0.15212242 0.63895482 -0.7540527 0.57715994 0.62066495 -0.53071779 0.57715994 - 0.62066495 -0.53071779 0.57715994 0.62066495 -0.53071779 0.66391736 0.74780595 - -6.8648474e-006 0.66391736 0.74780595 -6.8648474e-006 0.66391736 0.74780595 - -6.8648474e-006 0.69178843 0.71751648 -0.08123339 0.69178843 0.71751648 -0.08123339 - 0.69178843 0.71751648 -0.08123339 0.67414337 0.7385183 0.011017781 0.67414337 - 0.7385183 0.011017781 0.67414337 0.7385183 0.011017781 0.61830199 0.71861321 - -0.31827298 0.61830199 0.71861321 -0.31827298 0.61830199 0.71861321 -0.31827298 - 0.64411044 0.72687542 -0.23827261 0.64411044 0.72687542 -0.23827261 0.64411044 - 0.72687542 -0.23827261 0.61462724 0.61803502 -0.49016944 0.61462724 0.61803502 - -0.49016944 0.61462724 0.61803502 -0.49016944 -0.0032054679 0.002104501 -0.99999267 - -0.0032054679 0.002104501 -0.99999267 -0.0032054679 0.002104501 -0.99999267 - 3.7762165e-005 0.00035861688 -0.99999994 3.7762165e-005 0.00035861688 -0.99999994 - 3.7762165e-005 0.00035861688 -0.99999994 -7.0096525e-005 0.00028596868 -1 - -7.0096525e-005 0.00028596868 -1 -7.0096525e-005 0.00028596868 -1 0.21827288 - 0.83170044 -0.51052064 0.21827288 0.83170044 -0.51052064 0.21827288 0.83170044 - -0.51052064 0.47236392 0.54045826 -0.69625944 0.47236392 0.54045826 -0.69625944 - 0.47236392 0.54045826 -0.69625944 0.897057 0.39539951 -0.19735244 0.897057 - 0.39539951 -0.19735244 0.897057 0.39539951 -0.19735244 0.84292632 0.048823304 - -0.53580922; - setAttr ".n[166:331]" -type "float3" 0.84292632 0.048823304 -0.53580922 - 0.84292632 0.048823304 -0.53580922 0.40807575 0.39698204 -0.82211888 0.40807575 - 0.39698204 -0.82211888 0.40807575 0.39698204 -0.82211888 0.94095927 -0.33844388 - 0.0071634678 0.94095927 -0.33844388 0.0071634678 0.94095927 -0.33844388 0.0071634678 - 0.97253621 -0.23259754 0.0084718559 0.97253621 -0.23259754 0.0084718559 0.97253621 - -0.23259754 0.0084718559 0.2814334 -0.030937877 -0.95908189 0.2814334 -0.030937877 - -0.95908189 0.2814334 -0.030937877 -0.95908189 0.33640796 -0.94171578 0.0010571991 - 0.33640796 -0.94171578 0.0010571991 0.33640796 -0.94171578 0.0010571991 0.33439985 - -0.94242632 0.0030683025 0.33439985 -0.94242632 0.0030683025 0.33439985 -0.94242632 - 0.0030683025 0.97203428 -0.23478884 0.0048516314 0.97203428 -0.23478884 0.0048516314 - 0.97203428 -0.23478884 0.0048516314 7.089119e-007 0 1 7.089119e-007 0 1 7.089119e-007 - 0 1 -2.3767482e-006 0 1 -2.3767482e-006 0 1 -2.3767482e-006 0 1 0.2998611 - -0.018150916 -0.95381016 0.2998611 -0.018150916 -0.95381016 0.2998611 -0.018150916 - -0.95381016 0.15563329 -7.8220779e-005 -0.9878149 0.15563329 -7.8220779e-005 - -0.9878149 0.15563329 -7.8220779e-005 -0.9878149 0.81262964 -0.0063060597 - 0.58274633 0.81262964 -0.0063060597 0.58274633 0.81262964 -0.0063060597 0.58274633 - 0.79353881 -0.0011432025 0.60851866 0.79353881 -0.0011432025 0.60851866 0.79353881 - -0.0011432025 0.60851866 0.79444599 -1.0079387e-006 0.60733479 0.79444599 - -1.0079387e-006 0.60733479 0.79444599 -1.0079387e-006 0.60733479 0.99937654 - -0.034417219 0.0078779478 0.99937654 -0.034417219 0.0078779478 0.99937654 - -0.034417219 0.0078779478 0.96320915 -0.001830549 0.26874682 0.96320915 -0.001830549 - 0.26874682 0.96320915 -0.001830549 0.26874682 0.96813047 -0.18727522 0.16628696 - 0.96813047 -0.18727522 0.16628696 0.96813047 -0.18727522 0.16628696 0.78021353 - -0.41768348 0.46562576 0.78021353 -0.41768348 0.46562576 0.78021353 -0.41768348 - 0.46562576 0.77887923 -0.56200725 0.27837932 0.77887923 -0.56200725 0.27837932 - 0.77887923 -0.56200725 0.27837932 0.96877611 -0.21895885 0.11631798 0.96877611 - -0.21895885 0.11631798 0.96877611 -0.21895885 0.11631798 0.95657325 -0.29032037 - 0.026108516 0.95657325 -0.29032037 0.026108516 0.95657325 -0.29032037 0.026108516 - 0.99710941 -0.075976543 -0.00058789091 0.99710941 -0.075976543 -0.00058789091 - 0.99710941 -0.075976543 -0.00058789091 -1.765784e-008 -0.99988049 0.015460744 - -1.765784e-008 -0.99988049 0.015460744 -1.765784e-008 -0.99988049 0.015460744 - -1.7657882e-008 -0.99988049 0.01546078 -1.7657882e-008 -0.99988049 0.01546078 - -1.7657882e-008 -0.99988049 0.01546078 0.38715211 -0.92190582 0.014246181 - 0.38715211 -0.92190582 0.014246181 0.38715211 -0.92190582 0.014246181 0.3713856 - -0.92827648 0.019377328 0.3713856 -0.92827648 0.019377328 0.3713856 -0.92827648 - 0.019377328 -2.0165547e-007 -0.93082839 -0.36545661 -2.0165547e-007 -0.93082839 - -0.36545661 -2.0165547e-007 -0.93082839 -0.36545661 5.0176641e-007 -0.93082201 - -0.36547282 5.0176641e-007 -0.93082201 -0.36547282 5.0176641e-007 -0.93082201 - -0.36547282 -0.36133149 -0.93232608 0.014408951 -0.36133149 -0.93232608 0.014408951 - -0.36133149 -0.93232608 0.014408951 -0.34630656 -0.93791693 0.019585647 -0.34630656 - -0.93791693 0.019585647 -0.34630656 -0.93791693 0.019585647 -9.6907911e-008 - -0.94180065 0.33617193 -9.6907911e-008 -0.94180065 0.33617193 -9.6907911e-008 - -0.94180065 0.33617193 -9.6908749e-008 -0.94180924 0.33614787 -9.6908749e-008 - -0.94180924 0.33614787 -9.6908749e-008 -0.94180924 0.33614787 -8.9105407e-007 - -0.40235195 0.91548502 -8.9105407e-007 -0.40235195 0.91548502 -8.9105407e-007 - -0.40235195 0.91548502 -8.9107704e-007 -0.40236279 0.91548032 -8.9107704e-007 - -0.40236279 0.91548032 -8.9107704e-007 -0.40236279 0.91548032 -8.5725975e-007 - 0 1 -8.5725975e-007 0 1 -8.5725975e-007 0 1 7.187773e-007 0 1 7.187773e-007 - 0 1 7.187773e-007 0 1 2.9182755e-007 0 1 2.9182755e-007 0 1 2.9182755e-007 - 0 1 2.5174003e-007 0 1 2.5174003e-007 0 1 2.5174003e-007 0 1 -1 -1.3486877e-007 - 0 -1 -1.3486877e-007 0 -1 -1.3486877e-007 0 -1 -1.0890954e-007 0 -1 -1.0890954e-007 - 0 -1 -1.0890954e-007 0 -1 -9.1122547e-007 0 -1 -9.1122547e-007 0 -1 -9.1122547e-007 - 0 -1 6.646444e-007 0 -1 6.646444e-007 0 -1 6.646444e-007 0 -1 -8.3380377e-007 - 0 -1 -8.3380377e-007 0 -1 -8.3380377e-007 0 -1 1.3891007e-007 0 -1 1.3891007e-007 - 0 -1 1.3891007e-007 0 0.78004467 0.010200712 0.62564069 0.78004467 0.010200712 - 0.62564069 0.78004467 0.010200712 0.62564069 0.82830101 0.00011392836 0.5602833 - 0.82830101 0.00011392836 0.5602833 0.82830101 0.00011392836 0.5602833 0.73171771 - 0.39199558 0.5576098 0.73171771 0.39199558 0.5576098 0.73171771 0.39199558 - 0.5576098 0.76109481 0.36669114 0.53504413 0.76109481 0.36669114 0.53504413 - 0.76109481 0.36669114 0.53504413 0.99288052 -0.1191144 2.2341138e-007 0.99288052 - -0.1191144 2.2341138e-007 0.99288052 -0.1191144 2.2341138e-007 0.99282628 - -0.11956459 0.00057738926 0.99282628 -0.11956459 0.00057738926 0.99282628 - -0.11956459 0.00057738926 0.099503346 0.99503726 0 0.099503346 0.99503726 - 0 0.099503346 0.99503726 0 0.099503718 0.9950372 0 0.099503718 0.9950372 - 0 0.099503718 0.9950372 0 -0.23162033 0.97280622 0 -0.23162033 0.97280622 - 0 -0.23162033 0.97280622 0 -0.23162052 0.97280622 0 -0.23162052 0.97280622 - 0 -0.23162052 0.97280622 0 0.99059147 -0.12929909 -0.044835333 0.99059147 - -0.12929909 -0.044835333; - setAttr ".n[332:497]" -type "float3" 0.99059147 -0.12929909 -0.044835333 - 0.063321374 0.63323426 0.77136552 0.063321374 0.63323426 0.77136552 0.063321374 - 0.63323426 0.77136552 0.06332279 0.63324946 0.77135295 0.06332279 0.63324946 - 0.77135295 0.06332279 0.63324946 0.77135295 0.96504647 -0.18847923 -0.18210143 - 0.96504647 -0.18847923 -0.18210143 0.96504647 -0.18847923 -0.18210143 0.99998802 - -0.0014395419 0.0046713161 0.99998802 -0.0014395419 0.0046713161 0.99998802 - -0.0014395419 0.0046713161 0.80845833 -0.5543046 -0.19784231 0.80845833 -0.5543046 - -0.19784231 0.80845833 -0.5543046 -0.19784231 0.85659349 -0.20762047 -0.47237837 - 0.85659349 -0.20762047 -0.47237837 0.85659349 -0.20762047 -0.47237837 0.80536336 - -0.014187645 -0.59261161 0.80536336 -0.014187645 -0.59261161 0.80536336 -0.014187645 - -0.59261161 0.50011629 0.73454082 0.45862123 0.50011629 0.73454082 0.45862123 - 0.50011629 0.73454082 0.45862123 0.5516203 0.75990117 0.34389713 0.5516203 - 0.75990117 0.34389713 0.5516203 0.75990117 0.34389713 0.44779047 0.43486294 - 0.78126687 0.44779047 0.43486294 0.78126687 0.44779047 0.43486294 0.78126687 - 0.44662619 0.43884897 0.7797029 0.44662619 0.43884897 0.7797029 0.44662619 - 0.43884897 0.7797029 0.54743606 0.54396111 0.63594031 0.54743606 0.54396111 - 0.63594031 0.54743606 0.54396111 0.63594031 0.25760815 -0.00014752454 0.96624947 - 0.25760815 -0.00014752454 0.96624947 0.25760815 -0.00014752454 0.96624947 - 0.31518412 0.027194444 0.94864082 0.31518412 0.027194444 0.94864082 0.31518412 - 0.027194444 0.94864082 0.34211975 0.014545413 0.93954378 0.34211975 0.014545413 - 0.93954378 0.34211975 0.014545413 0.93954378 0.22108299 0.97522455 -0.0077006337 - 0.22108299 0.97522455 -0.0077006337 0.22108299 0.97522455 -0.0077006337 0.21569796 - 0.97645879 0.0016108342 0.21569796 0.97645879 0.0016108342 0.21569796 0.97645879 - 0.0016108342 0.21278244 0.28387633 0.93495339 0.21278244 0.28387633 0.93495339 - 0.21278244 0.28387633 0.93495339 0.99994814 2.2067142e-007 0.010183261 0.99994814 - 2.2067142e-007 0.010183261 0.99994814 2.2067142e-007 0.010183261 7.1914496e-006 - 0 -1 7.1914496e-006 0 -1 7.1914496e-006 0 -1 -0.0050668996 0.00024447139 - 0.99998713 -0.0050668996 0.00024447139 0.99998713 -0.0050668996 0.00024447139 - 0.99998713 0.99994332 -0.0076812962 -0.0073767104 0.99994332 -0.0076812962 - -0.0073767104 0.99994332 -0.0076812962 -0.0073767104 0.99994636 -0.0077586337 - -0.0068659 0.99994636 -0.0077586337 -0.0068659 0.99994636 -0.0077586337 -0.0068659 - 0.88146269 0.47221881 -0.0057370551 0.88146269 0.47221881 -0.0057370551 0.88146269 - 0.47221881 -0.0057370551 0.88355166 0.46832478 0.0028835041 0.88355166 0.46832478 - 0.0028835041 0.88355166 0.46832478 0.0028835041 0.23654473 0.043915328 0.97062767 - 0.23654473 0.043915328 0.97062767 0.23654473 0.043915328 0.97062767 0.99998778 - -0.0014190752 0.0047348482 0.99998778 -0.0014190752 0.0047348482 0.99998778 - -0.0014190752 0.0047348482 0.76892465 -0.63931197 -0.0059172651 0.76892465 - -0.63931197 -0.0059172651 0.76892465 -0.63931197 -0.0059172651 0.75266767 - -0.65825725 -0.013737433 0.75266767 -0.65825725 -0.013737433 0.75266767 -0.65825725 - -0.013737433 0.92978829 -0.3616052 -0.06881433 0.92978829 -0.3616052 -0.06881433 - 0.92978829 -0.3616052 -0.06881433 0.99994814 2.2071661e-007 0.010183288 0.99994814 - 2.2071661e-007 0.010183288 0.99994814 2.2071661e-007 0.010183288 0.31276077 - -0.015097781 0.94971192 0.31276077 -0.015097781 0.94971192 0.31276077 -0.015097781 - 0.94971192 0.27977985 -0.000980051 0.9600637 0.27977985 -0.000980051 0.9600637 - 0.27977985 -0.000980051 0.9600637 -0.15213111 0.63895756 0.75404859 -0.15213111 - 0.63895756 0.75404859 -0.15213111 0.63895756 0.75404859 -0.152119 0.63894391 - 0.75406271 -0.152119 0.63894391 0.75406271 -0.152119 0.63894391 0.75406271 - 0.57715201 0.62066251 0.53072935 0.57715201 0.62066251 0.53072935 0.57715201 - 0.62066251 0.53072935 0.66391736 0.74780595 6.8648474e-006 0.66391736 0.74780595 - 6.8648474e-006 0.66391736 0.74780595 6.8648474e-006 0.69178706 0.71751505 - 0.081257716 0.69178706 0.71751505 0.081257716 0.69178706 0.71751505 0.081257716 - 0.67414373 0.73851818 -0.011010649 0.67414373 0.73851818 -0.011010649 0.67414373 - 0.73851818 -0.011010649 0.61830533 0.71861708 0.31825784 0.61830533 0.71861708 - 0.31825784 0.61830533 0.71861708 0.31825784 0.64410871 0.72687316 0.23828438 - 0.64410871 0.72687316 0.23828438 0.64410871 0.72687316 0.23828438 0.61463618 - 0.61804372 0.49014723 0.61463618 0.61804372 0.49014723 0.61463618 0.61804372 - 0.49014723 -0.0032130571 0.0021045126 0.99999261 -0.0032130571 0.0021045126 - 0.99999261 -0.0032130571 0.0021045126 0.99999261 3.5890185e-005 0.00035862619 - 0.99999994 3.5890185e-005 0.00035862619 0.99999994 3.5890185e-005 0.00035862619 - 0.99999994 -6.77883e-005 0.00028595462 1 -6.77883e-005 0.00028595462 1 -6.77883e-005 - 0.00028595462 1 0.21827473 0.83170688 0.51050943 0.21827473 0.83170688 0.51050943 - 0.21827473 0.83170688 0.51050943 0.47235197 0.54044503 0.6962778 0.47235197 - 0.54044503 0.6962778 0.47235197 0.54044503 0.6962778 0.89705545 0.39540258 - 0.19735341 0.89705545 0.39540258 0.19735341 0.89705545 0.39540258 0.19735341 - 0.84292126 0.04882377 0.53581715 0.84292126 0.04882377 0.53581715 0.84292126 - 0.04882377 0.53581715 0.40806949 0.39697617 0.82212484 0.40806949 0.39697617 - 0.82212484 0.40806949 0.39697617 0.82212484 0.94095981 -0.33844253 -0.0071647353 - 0.94095981 -0.33844253 -0.0071647353 0.94095981 -0.33844253 -0.0071647353 - 0.97253633 -0.23259704 -0.0084720151 0.97253633 -0.23259704 -0.0084720151 - 0.97253633 -0.23259704 -0.0084720151 0.28143105 -0.030937552 0.9590826 0.28143105 - -0.030937552 0.9590826 0.28143105 -0.030937552 0.9590826 0.3385185 -0.94095683 - 0.0023484509 0.3385185 -0.94095683 0.0023484509 0.3385185 -0.94095683 0.0023484509 - 0.33319405 -0.94285333 -0.0030597886 0.33319405 -0.94285333 -0.0030597886 - 0.33319405 -0.94285333 -0.0030597886; - setAttr ".n[498:623]" -type "float3" 0.97203422 -0.23478949 -0.0048418916 - 0.97203422 -0.23478949 -0.0048418916 0.97203422 -0.23478949 -0.0048418916 - 3.9480346e-006 0 -1 3.9480346e-006 0 -1 3.9480346e-006 0 -1 3.7357913e-007 - 0 -1 3.7357913e-007 0 -1 3.7357913e-007 0 -1 0.30027407 -0.017862296 0.9536857 - 0.30027407 -0.017862296 0.9536857 0.30027407 -0.017862296 0.9536857 0.15643865 - -8.4816918e-008 0.98768765 0.15643865 -8.4816918e-008 0.98768765 0.15643865 - -8.4816918e-008 0.98768765 0.81263053 -0.0063060517 -0.58274508 0.81263053 - -0.0063060517 -0.58274508 0.81263053 -0.0063060517 -0.58274508 0.79354197 - -0.0011432051 -0.60851443 0.79354197 -0.0011432051 -0.60851443 0.79354197 - -0.0011432051 -0.60851443 0.79444689 -1.0079367e-006 -0.6073336 0.79444689 - -1.0079367e-006 -0.6073336 0.79444689 -1.0079367e-006 -0.6073336 0.99937654 - -0.034416556 -0.0078772092 0.99937654 -0.034416556 -0.0078772092 0.99937654 - -0.034416556 -0.0078772092 0.96320951 -0.0018307539 -0.26874527 0.96320951 - -0.0018307539 -0.26874527 0.96320951 -0.0018307539 -0.26874527 0.96813059 - -0.18727276 -0.16628909 0.96813059 -0.18727276 -0.16628909 0.96813059 -0.18727276 - -0.16628909 0.78021157 -0.41768479 -0.46562797 0.78021157 -0.41768479 -0.46562797 - 0.78021157 -0.41768479 -0.46562797 0.77887917 -0.56200659 -0.27838087 0.77887917 - -0.56200659 -0.27838087 0.77887917 -0.56200659 -0.27838087 0.96877658 -0.21895774 - -0.11631585 0.96877658 -0.21895774 -0.11631585 0.96877658 -0.21895774 -0.11631585 - 0.95657331 -0.29032043 -0.026107734 0.95657331 -0.29032043 -0.026107734 0.95657331 - -0.29032043 -0.026107734 0.99711001 -0.075968996 0.00058879697 0.99711001 - -0.075968996 0.00058879697 0.99711001 -0.075968996 0.00058879697 1.7657907e-008 - -0.99988049 -0.015460802 1.7657907e-008 -0.99988049 -0.015460802 1.7657907e-008 - -0.99988049 -0.015460802 -1.7657882e-008 -0.99988049 -0.01546078 -1.7657882e-008 - -0.99988049 -0.01546078 -1.7657882e-008 -0.99988049 -0.01546078 0.38715056 - -0.92190641 -0.014246133 0.38715056 -0.92190641 -0.014246133 0.38715056 -0.92190641 - -0.014246133 0.37138644 -0.92827594 -0.019386191 0.37138644 -0.92827594 -0.019386191 - 0.37138644 -0.92827594 -0.019386191 2.0165581e-007 -0.93082798 0.36545768 - 2.0165581e-007 -0.93082798 0.36545768 2.0165581e-007 -0.93082798 0.36545768 - 5.0175635e-007 -0.9308033 0.36552036 5.0175635e-007 -0.9308033 0.36552036 - 5.0175635e-007 -0.9308033 0.36552036 -0.36133406 -0.93232507 -0.014409042 - -0.36133406 -0.93232507 -0.014409042 -0.36133406 -0.93232507 -0.014409042 - -0.34630609 -0.93791699 -0.019588646 -0.34630609 -0.93791699 -0.019588646 - -0.34630609 -0.93791699 -0.019588646 -9.6907151e-008 -0.94179326 -0.33619255 - -9.6907151e-008 -0.94179326 -0.33619255 -9.6907151e-008 -0.94179326 -0.33619255 - 9.6908657e-008 -0.9418093 -0.33614758 9.6908657e-008 -0.9418093 -0.33614758 - 9.6908657e-008 -0.9418093 -0.33614758 1.384967e-007 -0.40235195 -0.91548502 - 1.384967e-007 -0.40235195 -0.91548502 1.384967e-007 -0.40235195 -0.91548502 - -1.3850028e-007 -0.40236261 -0.91548038 -1.3850028e-007 -0.40236261 -0.91548038 - -1.3850028e-007 -0.40236261 -0.91548038 -3.8349486e-007 0 -1 -3.8349486e-007 - 0 -1 -3.8349486e-007 0 -1 -1.0350143e-006 0 -1 -1.0350143e-006 0 -1 -1.0350143e-006 - 0 -1 4.4692342e-007 0 -1 4.4692342e-007 0 -1 4.4692342e-007 0 -1 2.5174003e-007 - 0 -1 2.5174003e-007 0 -1 2.5174003e-007 0 -1 -1 -1.3486877e-007 0 -1 -1.3486877e-007 - 0 -1 -1.3486877e-007 0 -1 -2.0059279e-008 0 -1 -2.0059279e-008 0 -1 -2.0059279e-008 - 0 -1 -2.0745063e-007 0 -1 -2.0745063e-007 0 -1 -2.0745063e-007 0 -1 -1.1150998e-006 - 0 -1 -1.1150998e-006 0 -1 -1.1150998e-006 0 -1 -7.528904e-007 0 -1 -7.528904e-007 - 0 -1 -7.528904e-007 0 -1 -1.389101e-007 0 -1 -1.389101e-007 0 -1 -1.389101e-007 - 0 0.78004485 0.010200519 -0.62564045 0.78004485 0.010200519 -0.62564045 0.78004485 - 0.010200519 -0.62564045 0.82830089 0.00011392829 -0.56028354 0.82830089 0.00011392829 - -0.56028354 0.82830089 0.00011392829 -0.56028354 0.73171598 0.39199525 -0.5576123 - 0.73171598 0.39199525 -0.5576123 0.73171598 0.39199525 -0.5576123 0.76109451 - 0.36669156 -0.53504431 0.76109451 0.36669156 -0.53504431 0.76109451 0.36669156 - -0.53504431; - setAttr -s 208 ".fc[0:207]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 -3 3 4 - mu 0 3 2 0 3 - f 3 5 6 -1 - mu 0 3 2 4 1 - f 3 7 -6 8 - mu 0 3 5 4 2 - f 3 9 10 11 - mu 0 3 4 7 6 - f 3 -8 12 -10 - mu 0 3 4 5 7 - f 3 13 -5 14 - mu 0 3 8 2 3 - f 3 -9 15 16 - mu 0 3 5 2 9 - f 3 -16 -14 17 - mu 0 3 9 2 8 - f 3 18 19 20 - mu 0 3 12 11 10 - f 3 21 22 23 - mu 0 3 15 14 13 - f 3 24 25 26 - mu 0 3 18 17 16 - f 3 27 28 29 - mu 0 3 20 16 19 - f 3 -30 30 31 - mu 0 3 20 19 21 - f 3 32 33 34 - mu 0 3 23 22 11 - f 3 35 36 -34 - mu 0 3 22 24 11 - f 3 37 -19 38 - mu 0 3 25 11 12 - f 3 -35 -38 39 - mu 0 3 23 11 25 - f 3 40 41 -36 - mu 0 3 22 26 24 - f 3 42 43 44 - mu 0 3 28 27 15 - f 3 -39 45 46 - mu 0 3 25 12 29 - f 3 47 48 -46 - mu 0 3 12 30 29 - f 3 49 50 51 - mu 0 3 30 32 31 - f 3 -51 52 53 - mu 0 3 31 32 33 - f 3 -52 54 -49 - mu 0 3 30 31 29 - f 3 -54 55 56 - mu 0 3 31 33 34 - f 3 57 58 59 - mu 0 3 37 36 35 - f 3 -47 60 61 - mu 0 3 25 29 28 - f 3 62 63 64 - mu 0 3 40 39 38 - f 3 65 66 -63 - mu 0 3 40 41 39 - f 3 -64 67 68 - mu 0 3 38 39 14 - f 3 69 -69 70 - mu 0 3 27 38 14 - f 3 -70 -43 71 - mu 0 3 38 27 28 - f 3 -71 -22 -44 - mu 0 3 27 14 15 - f 3 72 73 74 - mu 0 3 44 43 42 - f 3 75 76 -74 - mu 0 3 43 45 42 - f 3 -37 77 78 - mu 0 3 11 24 46 - f 3 79 80 -56 - mu 0 3 33 47 34 - f 3 81 82 -61 - mu 0 3 29 40 28 - f 3 -65 -72 -83 - mu 0 3 40 38 28 - f 3 -13 83 84 - mu 0 3 7 5 48 - f 3 -17 85 -84 - mu 0 3 5 9 48 - f 3 86 87 88 - mu 0 3 50 49 48 - f 3 89 90 -11 - mu 0 3 7 51 6 - f 3 91 -85 -88 - mu 0 3 49 7 48 - f 3 92 -90 -92 - mu 0 3 49 51 7 - f 3 -89 93 94 - mu 0 3 50 48 52 - f 3 95 -95 96 - mu 0 3 26 50 52 - f 3 -97 97 -42 - mu 0 3 26 52 24 - f 3 98 -15 99 - mu 0 3 53 8 3 - f 3 -18 -99 100 - mu 0 3 9 8 53 - f 3 -86 -101 101 - mu 0 3 48 9 53 - f 3 -102 102 -94 - mu 0 3 48 53 52 - f 3 103 104 -98 - mu 0 3 52 54 24 - f 3 105 106 -105 - mu 0 3 54 3 24 - f 3 107 -100 -106 - mu 0 3 54 53 3 - f 3 -103 -108 -104 - mu 0 3 52 53 54 - f 3 108 109 -78 - mu 0 3 24 55 46 - f 3 110 -66 111 - mu 0 3 56 41 40 - f 3 112 -112 -82 - mu 0 3 29 56 40 - f 3 -81 113 114 - mu 0 3 34 47 56 - f 3 115 116 -114 - mu 0 3 47 57 56 - f 3 -117 117 -111 - mu 0 3 56 57 41 - f 3 118 119 120 - mu 0 3 59 58 37 - f 3 121 -58 -120 - mu 0 3 58 36 37 - f 3 -55 122 -113 - mu 0 3 29 31 56 - f 3 -57 -115 -123 - mu 0 3 31 34 56 - f 3 123 124 125 - mu 0 3 62 61 60 - f 3 126 127 128 - mu 0 3 65 64 63 - f 3 -128 129 130 - mu 0 3 63 64 66 - f 3 -48 131 -50 - mu 0 3 30 12 32 - f 3 -21 132 -132 - mu 0 3 12 10 32 - f 3 133 134 -20 - mu 0 3 11 67 10 - f 3 135 -28 136 - mu 0 3 68 16 20 - f 3 137 -27 -136 - mu 0 3 68 18 16 - f 3 -79 138 -134 - mu 0 3 11 46 67 - f 3 139 140 -109 - mu 0 3 24 0 55 - f 3 -4 -140 -107 - mu 0 3 3 0 24 - f 3 141 142 143 - mu 0 3 71 70 69 - f 3 -144 144 145 - mu 0 3 71 69 72 - f 3 146 -146 147 - mu 0 3 45 71 72 - f 3 -77 -148 148 - mu 0 3 42 45 72 - f 3 149 -149 150 - mu 0 3 73 42 72 - f 3 151 -151 -145 - mu 0 3 69 73 72 - f 3 152 153 -143 - mu 0 3 70 74 69 - f 3 154 -152 -154 - mu 0 3 74 73 69 - f 3 155 156 157 - mu 0 3 76 75 16 - f 3 158 -158 -26 - mu 0 3 17 76 16 - f 3 159 160 -29 - mu 0 3 16 77 19 - f 3 -157 161 -160 - mu 0 3 16 75 77 - f 3 -161 162 163 - mu 0 3 19 77 61 - f 3 -163 164 165 - mu 0 3 61 77 78 - f 3 166 -166 167 - mu 0 3 64 61 78 - f 3 -168 168 -130 - mu 0 3 64 78 66 - f 3 169 170 171 - mu 0 3 81 80 79 - f 3 172 173 -170 - mu 0 3 81 82 80 - f 3 174 -173 175 - mu 0 3 83 82 81 - f 3 176 -175 177 - mu 0 3 84 82 83 - f 3 178 -177 179 - mu 0 3 85 82 84 - f 3 180 -180 181 - mu 0 3 86 85 84 - f 3 182 183 -124 - mu 0 3 62 21 61 - f 3 -31 -164 -184 - mu 0 3 21 19 61 - f 3 184 -127 185 - mu 0 3 60 64 65 - f 3 -125 -167 -185 - mu 0 3 60 61 64 - f 3 186 187 188 - mu 0 3 162 87 161 - f 3 -188 189 190 - mu 0 3 161 87 88 - f 3 191 -187 192 - mu 0 3 163 87 162 - f 3 193 194 -192 - mu 0 3 163 89 87 - f 3 195 196 197 - mu 0 3 90 163 164 - f 3 -194 -196 198 - mu 0 3 89 163 90 - f 3 199 200 -190 - mu 0 3 87 91 88 - f 3 -195 201 202 - mu 0 3 87 89 92 - f 3 -203 203 -200 - mu 0 3 87 92 91 - f 3 204 205 206 - mu 0 3 95 94 93 - f 3 207 208 209 - mu 0 3 98 97 96 - f 3 210 211 212 - mu 0 3 101 100 99 - f 3 213 214 215 - mu 0 3 99 103 102 - f 3 -215 216 217 - mu 0 3 102 103 104 - f 3 218 219 220 - mu 0 3 106 105 95 - f 3 221 -221 222 - mu 0 3 107 106 95 - f 3 223 224 -205 - mu 0 3 95 108 94 - f 3 -220 225 -224 - mu 0 3 95 105 108 - f 3 226 -222 227 - mu 0 3 109 106 107 - f 3 228 229 230 - mu 0 3 111 110 97 - f 3 -225 231 232 - mu 0 3 94 108 112 - f 3 233 -233 234 - mu 0 3 113 94 112 - f 3 235 236 237 - mu 0 3 115 113 114 - f 3 -238 238 239 - mu 0 3 115 114 116 - f 3 -237 -235 240 - mu 0 3 114 113 112 - f 3 -239 241 242 - mu 0 3 116 114 117 - f 3 243 244 245 - mu 0 3 120 119 118 - f 3 -232 246 247 - mu 0 3 112 108 110 - f 3 248 249 250 - mu 0 3 123 122 121 - f 3 251 -249 252 - mu 0 3 124 122 123 - f 3 -251 253 254 - mu 0 3 123 121 98 - f 3 255 256 -254 - mu 0 3 121 111 98 - f 3 -256 257 -229 - mu 0 3 111 121 110 - f 3 -257 -231 -208 - mu 0 3 98 111 97 - f 3 258 259 260 - mu 0 3 165 126 125 - f 3 261 -261 262 - mu 0 3 166 165 125 - f 3 -223 263 264 - mu 0 3 107 95 127 - f 3 265 -243 266 - mu 0 3 128 116 117 - f 3 267 -248 268 - mu 0 3 122 112 110 - f 3 -250 -269 -258 - mu 0 3 121 122 110 - f 3 -199 269 270 - mu 0 3 89 90 129 - f 3 -202 -271 271 - mu 0 3 92 89 129 - f 3 272 273 274 - mu 0 3 131 130 129 - f 3 275 -198 276 - mu 0 3 167 90 164 - f 3 277 -275 -270 - mu 0 3 90 131 129 - f 3 278 -278 -276 - mu 0 3 167 131 90 - f 3 -274 279 280 - mu 0 3 129 130 132 - f 3 281 282 -280 - mu 0 3 130 109 132 - f 3 -283 -228 283 - mu 0 3 132 109 107 - f 3 284 285 -201 - mu 0 3 91 133 88 - f 3 -204 286 -285 - mu 0 3 91 92 133 - f 3 -272 287 -287 - mu 0 3 92 129 133 - f 3 -288 -281 288 - mu 0 3 133 129 132 - f 3 289 -284 290 - mu 0 3 134 132 107 - f 3 291 -291 292 - mu 0 3 88 134 107 - f 3 293 -292 -286 - mu 0 3 133 134 88 - f 3 -289 -290 -294 - mu 0 3 133 132 134 - f 3 294 -265 295 - mu 0 3 168 107 127 - f 3 296 297 -252 - mu 0 3 124 135 122 - f 3 298 -268 -298 - mu 0 3 135 112 122 - f 3 -267 299 300 - mu 0 3 128 117 135 - f 3 301 -301 302 - mu 0 3 136 128 135 - f 3 -303 -297 303 - mu 0 3 136 135 124 - f 3 304 305 306 - mu 0 3 138 137 119 - f 3 307 -307 -244 - mu 0 3 120 138 119 - f 3 -241 -299 308 - mu 0 3 114 112 135 - f 3 -242 -309 -300 - mu 0 3 117 114 135 - f 3 309 310 311 - mu 0 3 141 140 139 - f 3 312 313 314 - mu 0 3 144 143 142 - f 3 -315 315 316 - mu 0 3 144 142 145 - f 3 -234 -236 317 - mu 0 3 94 113 115 - f 3 -206 -318 318 - mu 0 3 93 94 115 - f 3 319 -207 320 - mu 0 3 146 95 93 - f 3 321 322 -214 - mu 0 3 99 147 103 - f 3 323 -322 -212 - mu 0 3 100 147 99 - f 3 -264 -320 324 - mu 0 3 127 95 146 - f 3 325 -295 326 - mu 0 3 161 107 168 - f 3 -191 -293 -326 - mu 0 3 161 88 107 - f 3 327 328 329 - mu 0 3 169 170 148 - f 3 -329 330 331 - mu 0 3 148 170 149 - f 3 332 333 -331 - mu 0 3 170 166 149 - f 3 -263 334 -334 - mu 0 3 166 125 149 - f 3 335 336 -335 - mu 0 3 125 150 149 - f 3 337 -332 -337 - mu 0 3 150 148 149 - f 3 338 -330 339 - mu 0 3 171 169 148 - f 3 340 -340 -338 - mu 0 3 150 171 148 - f 3 341 342 343 - mu 0 3 152 151 99 - f 3 344 -213 -343 - mu 0 3 151 101 99 - f 3 345 -216 346 - mu 0 3 153 99 102 - f 3 -344 -346 347 - mu 0 3 152 99 153 - f 3 -347 348 349 - mu 0 3 153 102 141 - f 3 -350 350 351 - mu 0 3 153 141 154 - f 3 352 353 -351 - mu 0 3 141 144 154 - f 3 -354 -317 354 - mu 0 3 154 144 145 - f 3 355 356 357 - mu 0 3 157 156 155 - f 3 358 -356 359 - mu 0 3 158 156 157 - f 3 360 361 -359 - mu 0 3 158 159 156 - f 3 362 363 -361 - mu 0 3 158 160 159 - f 3 364 365 -363 - mu 0 3 158 172 160 - f 3 366 367 -366 - mu 0 3 172 173 160 - f 3 368 -310 369 - mu 0 3 104 140 141 - f 3 -218 -370 -349 - mu 0 3 102 104 141 - f 3 370 371 -313 - mu 0 3 144 139 143 - f 3 -312 -371 -353 - mu 0 3 141 139 144 ; -createNode transform -n "m4" -p "celing"; -createNode mesh -n "polySurfaceShape35" -p "m4"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 56 ".uvst[0].uvsp[0:55]" -type "float2" 0 0 0 1 - 1 1 1 0 -34 9 -37 9 -37 10 -34 10 -34 9 -37 9 -37 10 -34 10 0 0 0 1 1 1 1 - 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 - 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 - 0 0 1 1 1 1 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 56 ".vt[0:55]" 80 -2064 16 16 -2064 16 16 -2064 - -48 80 -2064 -48 -32 -2064 -240 -224 -2064 -240 -224 -2064 -304 -32 -2064 - -304 224 -2064 -240 32 -2064 -240 32 -2064 -304 224 -2064 -304 80 -2064 112 - 16 -2064 112 16 -2064 48 80 -2064 48 240 -2064 112 176 -2064 112 176 -2064 - 48 240 -2064 48 240 -2064 16 176 -2064 16 176 -2064 -48 240 -2064 -48 240 - -2064 -80 176 -2064 -80 176 -2064 -144 240 -2064 -144 80 -2064 -80 16 -2064 - -80 16 -2064 -144 80 -2064 -144 -176 -2064 -80 -240 -2064 -80 -240 -2064 - -144 -176 -2064 -144 -16 -2064 -80 -80 -2064 -80 -80 -2064 -144 -16 -2064 - -144 -16 -2064 16 -80 -2064 16 -80 -2064 -48 -16 -2064 -48 -16 -2064 112 - -80 -2064 112 -80 -2064 48 -16 -2064 48 -176 -2064 112 -240 -2064 112 -240 - -2064 48 -176 -2064 48 -176 -2064 16 -240 -2064 16 -240 -2064 -48 -176 -2064 - -48; - setAttr -s 70 ".ed[0:69]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0 30 29 0 29 28 0 28 30 0 31 - 30 0 28 31 0 34 33 0 33 32 0 - 32 34 0 35 34 0 32 35 0 38 37 - 0 37 36 0 36 38 0 39 38 0 36 - 39 0 42 41 0 41 40 0 40 42 0 - 43 42 0 40 43 0 46 45 0 45 44 - 0 44 46 0 47 46 0 44 47 0 50 - 49 0 49 48 0 48 50 0 51 50 0 - 48 51 0 54 53 0 53 52 0 52 54 - 0 55 54 0 52 55 0; - setAttr -s 84 ".n[0:83]" -type "float3" 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0; - setAttr -s 28 ".fc[0:27]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 ; -createNode transform -n "m75" -p "celing"; -createNode mesh -n "polySurfaceShape36" -p "m75"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 1 0 1 1 - 0 1 0 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" -279.79965 -1948.4504 -210.32208 - -286.79965 -1948.4504 -210.32208 -286.79965 -1948.4504 -173.67792 -279.79965 - -1948.4504 -173.67792; - setAttr -s 5 ".ed[0:4]" 2 1 0 1 0 - 0 0 2 0 0 3 0 3 2 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0 -1 1.9035568e-006 - 0 -1 1.9035568e-006 0 -1 1.9035568e-006 0 -1 1.9035613e-006 0 -1 1.9035613e-006 - 0 -1 1.9035613e-006; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 -3 3 4 - mu 0 3 2 0 3 ; -createNode transform -n "m77" -p "celing"; -createNode mesh -n "polySurfaceShape37" -p "m77"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4 ".uvst[0].uvsp[0:3]" -type "float2" 1 0 0 0 - 0 1 1 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 4 ".vt[0:3]" -266.83945 -1930 -208.5 -266.83945 - -1930 -175.5 -264.83945 -1914 -175.5 -264.83945 -1914 -208.5; - setAttr -s 5 ".ed[0:4]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0; - setAttr -s 6 ".n[0:5]" -type "float3" 0.99227774 -0.12403621 - 0 0.99227774 -0.12403621 0 0.99227774 -0.12403621 0 0.99227804 -0.12403326 - 0 0.99227804 -0.12403326 0 0.99227804 -0.12403326 0; - setAttr -s 2 ".fc[0:1]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 ; -createNode transform -n "m5" -p "celing"; -createNode mesh -n "polySurfaceShape38" -p "m5"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 576 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" -250 1.1250089 -250 - 4.0001931 -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 - 4.0001931 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 - -39.25 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 - -13.813445 -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 - -39.25 15.875949 -39.75 15.875949 -39.75 15.813445 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -13.813445 - -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 -39.25 - 15.875949 -39.75 15.875949 -39.75 15.813445 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -13.813445 - -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 -39.25 - 15.875949 -39.75 15.875949 -39.75 15.813445 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -13.813445 - -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 -39.25 - 15.875949 -39.75 15.875949 -39.75 15.813445 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -13.813445 - -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 -39.25 - 15.875949 -39.75 15.875949 -39.75 15.813445 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -13.813445 - -39.75 -13.875949 -39.25 -13.875949 -39.25 -13.813445 -39.25 15.813445 -39.25 - 15.875949 -39.75 15.875949 -39.75 15.813445 -251 1.1250089 -251 4.0001931 - -250 4.0001931 -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 - 39.75 1.1250089 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 41.25 -12.688373 - 41.25 -12.625869 41.75 -12.625869 41.75 -12.688373 41.25 14.625869 41.25 - 14.688373 41.75 14.688373 41.75 14.625869 -251 1.1250089 -251 4.0001931 -250 - 4.0001931 -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 - 39.75 1.1250089 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 55.25 -12.688373 - 55.25 -12.625869 55.75 -12.625869 55.75 -12.688373 55.25 14.625869 55.25 - 14.688373 55.75 14.688373 55.75 14.625869 -251 1.1250089 -251 4.0001931 -250 - 4.0001931 -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 - 39.75 1.1250089 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 7.25 -12.688373 - 7.25 -12.625869 7.75 -12.625869 7.75 -12.688373 7.25 14.625869 7.25 14.688373 - 7.75 14.688373 7.75 14.625869 -251 1.1250089 -251 4.0001931 -250 4.0001931 - -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 - 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 1.1250089 - -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 -6.75 -12.688373 -6.75 - -12.625869 -6.25 -12.625869 -6.25 -12.688373 -6.75 14.625869 -6.75 14.688373 - -6.25 14.688373 -6.25 14.625869 -251 1.1250089 -251 4.0001931 -250 4.0001931 - -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 - 250 1.1250089 250 4.0001931; - setAttr ".uvst[0].uvsp[250:499]" 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 17.25 -12.688373 - 17.25 -12.625869 17.75 -12.625869 17.75 -12.688373 17.25 14.625869 17.25 - 14.688373 17.75 14.688373 17.75 14.625869 -251 1.1250089 -251 4.0001931 -250 - 4.0001931 -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 - 39.75 1.1250089 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 31.25 -12.688373 - 31.25 -12.625869 31.75 -12.625869 31.75 -12.688373 31.25 14.625869 31.25 - 14.688373 31.75 14.688373 31.75 14.625869 -250 1.1250089 -250 4.0001931 -251 - 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -250 1.1250089 -250 4.0001931 - -251 4.0001931 -251 1.1250089 39.75 1.1250089 39.75 4.0001931 39.25 4.0001931 - 39.25 1.1250089 251 1.1250089 251 4.0001931 250 4.0001931 250 1.1250089 -39.25 - 1.1250089 -39.25 4.0001931 -39.75 4.0001931 -39.75 1.1250089 -39.75 -11.813317 - -39.75 -11.875821 -39.25 -11.875821 -39.25 -11.813317 -39.25 13.813317 -39.25 - 13.875821 -39.75 13.875821 -39.75 13.813317 -251 1.1250089 -251 4.0001931 - -250 4.0001931 -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 - 39.75 1.1250089 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 - 1.1250089 -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 31.25 -14.6885 - 31.25 -14.625997 31.75 -14.625997 31.75 -14.6885 31.25 16.625998 31.25 16.688499 - 31.75 16.688499 31.75 16.625998 -251 1.1250089 -251 4.0001931 -250 4.0001931 - -250 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 - 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 1.1250089 - -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 17.25 -14.6885 17.25 -14.625997 - 17.75 -14.625997 17.75 -14.6885 17.25 16.625998 17.25 16.688499 17.75 16.688499 - 17.75 16.625998 -251 1.1250089 -251 4.0001931 -250 4.0001931 -250 1.1250089 - 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 250 1.1250089 - 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 1.1250089 -39.75 4.0001931 - -39.25 4.0001931 -39.25 1.1250089 55.25 -14.6885 55.25 -14.625997 55.75 -14.625997 - 55.75 -14.6885; - setAttr ".uvst[0].uvsp[500:575]" 55.25 16.625998 55.25 16.688499 55.75 - 16.688499 55.75 16.625998 -251 1.1250089 -251 4.0001931 -250 4.0001931 -250 - 1.1250089 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 - 250 1.1250089 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 1.1250089 - -39.75 4.0001931 -39.25 4.0001931 -39.25 1.1250089 41.25 -14.6885 41.25 -14.625997 - 41.75 -14.625997 41.75 -14.6885 41.25 16.625998 41.25 16.688499 41.75 16.688499 - 41.75 16.625998 -251 1.1250089 -251 4.0001931 -250 4.0001931 -250 1.1250089 - 39.25 1.1250089 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 250 1.1250089 - 250 4.0001931 251 4.0001931 251 1.1250089 -39.75 1.1250089 -39.75 4.0001931 - -39.25 4.0001931 -39.25 1.1250089 7.25 -14.6885 7.25 -14.625997 7.75 -14.625997 - 7.75 -14.6885 7.25 16.625998 7.25 16.688499 7.75 16.688499 7.75 16.625998 - -251 1.1250089 -251 4.0001931 -250 4.0001931 -250 1.1250089 39.25 1.1250089 - 39.25 4.0001931 39.75 4.0001931 39.75 1.1250089 250 1.1250089 250 4.0001931 - 251 4.0001931 251 1.1250089 -39.75 1.1250089 -39.75 4.0001931 -39.25 4.0001931 - -39.25 1.1250089 -6.75 -14.6885 -6.75 -14.625997 -6.25 -14.625997 -6.25 -14.6885 - -6.75 16.625998 -6.75 16.688499 -6.25 16.688499 -6.25 16.625998; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 576 ".vt"; - setAttr ".vt[0:165]" -80 -2064 -138 -80 -1696 -138 -72 -1696 -138 - -72 -2064 -138 -80 -2064 -142 -80 -1696 -142 -80 -1696 -138 -80 -2064 -138 - -72 -2064 -142 -72 -1696 -142 -80 -1696 -142 -80 -2064 -142 -72 -2064 -138 - -72 -1696 -138 -72 -1696 -142 -72 -2064 -142 -72 -2064 -142 -80 -2064 -142 - -80 -2064 -138 -72 -2064 -138 -72 -1696 -138 -80 -1696 -138 -80 -1696 -142 - -72 -1696 -142 -80 -2064 -82 -80 -1696 -82 -72 -1696 -82 -72 -2064 -82 -80 - -2064 -86 -80 -1696 -86 -80 -1696 -82 -80 -2064 -82 -72 -2064 -86 -72 -1696 - -86 -80 -1696 -86 -80 -2064 -86 -72 -2064 -82 -72 -1696 -82 -72 -1696 -86 - -72 -2064 -86 -72 -2064 -86 -80 -2064 -86 -80 -2064 -82 -72 -2064 -82 -72 - -1696 -82 -80 -1696 -82 -80 -1696 -86 -72 -1696 -86 -80 -2064 -42 -80 -1696 - -42 -72 -1696 -42 -72 -2064 -42 -80 -2064 -46 -80 -1696 -46 -80 -1696 -42 - -80 -2064 -42 -72 -2064 -46 -72 -1696 -46 -80 -1696 -46 -80 -2064 -46 -72 - -2064 -42 -72 -1696 -42 -72 -1696 -46 -72 -2064 -46 -72 -2064 -46 -80 -2064 - -46 -80 -2064 -42 -72 -2064 -42 -72 -1696 -42 -80 -1696 -42 -80 -1696 -46 - -72 -1696 -46 -80 -2064 14 -80 -1696 14 -72 -1696 14 -72 -2064 14 -80 -2064 - 10 -80 -1696 10 -80 -1696 14 -80 -2064 14 -72 -2064 10 -72 -1696 10 -80 -1696 - 10 -80 -2064 10 -72 -2064 14 -72 -1696 14 -72 -1696 10 -72 -2064 10 -72 -2064 - 10 -80 -2064 10 -80 -2064 14 -72 -2064 14 -72 -1696 14 -80 -1696 14 -80 -1696 - 10 -72 -1696 10 -80 -2064 54 -80 -1696 54 -72 -1696 54 -72 -2064 54 -80 -2064 - 50 -80 -1696 50 -80 -1696 54 -80 -2064 54 -72 -2064 50 -72 -1696 50 -80 -1696 - 50 -80 -2064 50 -72 -2064 54 -72 -1696 54 -72 -1696 50 -72 -2064 50 -72 -2064 - 50 -80 -2064 50 -80 -2064 54 -72 -2064 54 -72 -1696 54 -80 -1696 54 -80 -1696 - 50 -72 -1696 50 -80 -2064 110 -80 -1696 110 -72 -1696 110 -72 -2064 110 -80 - -2064 106 -80 -1696 106 -80 -1696 110 -80 -2064 110 -72 -2064 106 -72 -1696 - 106 -80 -1696 106 -80 -2064 106 -72 -2064 110 -72 -1696 110 -72 -1696 106 - -72 -2064 106 -72 -2064 106 -80 -2064 106 -80 -2064 110 -72 -2064 110 -72 - -1696 110 -80 -1696 110 -80 -1696 106 -72 -1696 106 72 -2064 -82 72 -1696 - -82 80 -1696 -82 80 -2064 -82 80 -2064 -82 80 -1696 -82 80 -1696 -86 80 -2064 - -86 80 -2064 -86 80 -1696 -86 72 -1696 -86 72 -2064 -86 72 -2064 -86 72 -1696 - -86 72 -1696 -82 72 -2064 -82 72 -2064 -82 80 -2064 -82 80 -2064 -86 72 -2064 - -86 80 -1696 -82 72 -1696 -82; - setAttr ".vt[166:331]" 72 -1696 -86 80 -1696 -86 72 -2064 -138 72 - -1696 -138 80 -1696 -138 80 -2064 -138 80 -2064 -138 80 -1696 -138 80 -1696 - -142 80 -2064 -142 80 -2064 -142 80 -1696 -142 72 -1696 -142 72 -2064 -142 - 72 -2064 -142 72 -1696 -142 72 -1696 -138 72 -2064 -138 72 -2064 -138 80 - -2064 -138 80 -2064 -142 72 -2064 -142 80 -1696 -138 72 -1696 -138 72 -1696 - -142 80 -1696 -142 72 -2064 54 72 -1696 54 80 -1696 54 80 -2064 54 80 -2064 - 54 80 -1696 54 80 -1696 50 80 -2064 50 80 -2064 50 80 -1696 50 72 -1696 50 - 72 -2064 50 72 -2064 50 72 -1696 50 72 -1696 54 72 -2064 54 72 -2064 54 80 - -2064 54 80 -2064 50 72 -2064 50 80 -1696 54 72 -1696 54 72 -1696 50 80 -1696 - 50 72 -2064 110 72 -1696 110 80 -1696 110 80 -2064 110 80 -2064 110 80 -1696 - 110 80 -1696 106 80 -2064 106 80 -2064 106 80 -1696 106 72 -1696 106 72 -2064 - 106 72 -2064 106 72 -1696 106 72 -1696 110 72 -2064 110 72 -2064 110 80 -2064 - 110 80 -2064 106 72 -2064 106 80 -1696 110 72 -1696 110 72 -1696 106 80 -1696 - 106 72 -2064 14 72 -1696 14 80 -1696 14 80 -2064 14 80 -2064 14 80 -1696 - 14 80 -1696 10 80 -2064 10 80 -2064 10 80 -1696 10 72 -1696 10 72 -2064 10 - 72 -2064 10 72 -1696 10 72 -1696 14 72 -2064 14 72 -2064 14 80 -2064 14 80 - -2064 10 72 -2064 10 80 -1696 14 72 -1696 14 72 -1696 10 80 -1696 10 72 -2064 - -42 72 -1696 -42 80 -1696 -42 80 -2064 -42 80 -2064 -42 80 -1696 -42 80 -1696 - -46 80 -2064 -46 80 -2064 -46 80 -1696 -46 72 -1696 -46 72 -2064 -46 72 -2064 - -46 72 -1696 -46 72 -1696 -42 72 -2064 -42 72 -2064 -42 80 -2064 -42 80 -2064 - -46 72 -2064 -46 80 -1696 -42 72 -1696 -42 72 -1696 -46 80 -1696 -46 176 - -2064 -82 176 -1696 -82 184 -1696 -82 184 -2064 -82 176 -2064 -86 176 -1696 - -86 176 -1696 -82 176 -2064 -82 184 -2064 -86 184 -1696 -86 176 -1696 -86 - 176 -2064 -86 184 -2064 -82 184 -1696 -82 184 -1696 -86 184 -2064 -86 184 - -2064 -86 176 -2064 -86 176 -2064 -82 184 -2064 -82 184 -1696 -82 176 -1696 - -82 176 -1696 -86 184 -1696 -86 176 -2064 -138 176 -1696 -138 184 -1696 -138 - 184 -2064 -138 176 -2064 -142 176 -1696 -142 176 -1696 -138 176 -2064 -138 - 184 -2064 -142 184 -1696 -142 176 -1696 -142 176 -2064 -142 184 -2064 -138 - 184 -1696 -138 184 -1696 -142 184 -2064 -142 184 -2064 -142 176 -2064 -142 - 176 -2064 -138 184 -2064 -138; - setAttr ".vt[332:497]" 184 -1696 -138 176 -1696 -138 176 -1696 -142 - 184 -1696 -142 176 -2064 54 176 -1696 54 184 -1696 54 184 -2064 54 176 -2064 - 50 176 -1696 50 176 -1696 54 176 -2064 54 184 -2064 50 184 -1696 50 176 -1696 - 50 176 -2064 50 184 -2064 54 184 -1696 54 184 -1696 50 184 -2064 50 184 -2064 - 50 176 -2064 50 176 -2064 54 184 -2064 54 184 -1696 54 176 -1696 54 176 -1696 - 50 184 -1696 50 176 -2064 110 176 -1696 110 184 -1696 110 184 -2064 110 176 - -2064 106 176 -1696 106 176 -1696 110 176 -2064 110 184 -2064 106 184 -1696 - 106 176 -1696 106 176 -2064 106 184 -2064 110 184 -1696 110 184 -1696 106 - 184 -2064 106 184 -2064 106 176 -2064 106 176 -2064 110 184 -2064 110 184 - -1696 110 176 -1696 110 176 -1696 106 184 -1696 106 176 -2064 14 176 -1696 - 14 184 -1696 14 184 -2064 14 176 -2064 10 176 -1696 10 176 -1696 14 176 -2064 - 14 184 -2064 10 184 -1696 10 176 -1696 10 176 -2064 10 184 -2064 14 184 -1696 - 14 184 -1696 10 184 -2064 10 184 -2064 10 176 -2064 10 176 -2064 14 184 -2064 - 14 184 -1696 14 176 -1696 14 176 -1696 10 184 -1696 10 176 -2064 -42 176 - -1696 -42 184 -1696 -42 184 -2064 -42 176 -2064 -46 176 -1696 -46 176 -1696 - -42 176 -2064 -42 184 -2064 -46 184 -1696 -46 176 -1696 -46 176 -2064 -46 - 184 -2064 -42 184 -1696 -42 184 -1696 -46 184 -2064 -46 184 -2064 -46 176 - -2064 -46 176 -2064 -42 184 -2064 -42 184 -1696 -42 176 -1696 -42 176 -1696 - -46 184 -1696 -46 -184 -2064 -42 -184 -1696 -42 -176 -1696 -42 -176 -2064 - -42 -176 -2064 -42 -176 -1696 -42 -176 -1696 -46 -176 -2064 -46 -176 -2064 - -46 -176 -1696 -46 -184 -1696 -46 -184 -2064 -46 -184 -2064 -46 -184 -1696 - -46 -184 -1696 -42 -184 -2064 -42 -184 -2064 -42 -176 -2064 -42 -176 -2064 - -46 -184 -2064 -46 -176 -1696 -42 -184 -1696 -42 -184 -1696 -46 -176 -1696 - -46 -184 -2064 14 -184 -1696 14 -176 -1696 14 -176 -2064 14 -176 -2064 14 - -176 -1696 14 -176 -1696 10 -176 -2064 10 -176 -2064 10 -176 -1696 10 -184 - -1696 10 -184 -2064 10 -184 -2064 10 -184 -1696 10 -184 -1696 14 -184 -2064 - 14 -184 -2064 14 -176 -2064 14 -176 -2064 10 -184 -2064 10 -176 -1696 14 - -184 -1696 14 -184 -1696 10 -176 -1696 10 -184 -2064 -138 -184 -1696 -138 - -176 -1696 -138 -176 -2064 -138 -176 -2064 -138 -176 -1696 -138 -176 -1696 - -142 -176 -2064 -142 -176 -2064 -142 -176 -1696 -142 -184 -1696 -142 -184 - -2064 -142 -184 -2064 -142 -184 -1696 -142 -184 -1696 -138 -184 -2064 -138 - -184 -2064 -138 -176 -2064 -138; - setAttr ".vt[498:575]" -176 -2064 -142 -184 -2064 -142 -176 -1696 - -138 -184 -1696 -138 -184 -1696 -142 -176 -1696 -142 -184 -2064 -82 -184 - -1696 -82 -176 -1696 -82 -176 -2064 -82 -176 -2064 -82 -176 -1696 -82 -176 - -1696 -86 -176 -2064 -86 -176 -2064 -86 -176 -1696 -86 -184 -1696 -86 -184 - -2064 -86 -184 -2064 -86 -184 -1696 -86 -184 -1696 -82 -184 -2064 -82 -184 - -2064 -82 -176 -2064 -82 -176 -2064 -86 -184 -2064 -86 -176 -1696 -82 -184 - -1696 -82 -184 -1696 -86 -176 -1696 -86 -184 -2064 54 -184 -1696 54 -176 - -1696 54 -176 -2064 54 -176 -2064 54 -176 -1696 54 -176 -1696 50 -176 -2064 - 50 -176 -2064 50 -176 -1696 50 -184 -1696 50 -184 -2064 50 -184 -2064 50 - -184 -1696 50 -184 -1696 54 -184 -2064 54 -184 -2064 54 -176 -2064 54 -176 - -2064 50 -184 -2064 50 -176 -1696 54 -184 -1696 54 -184 -1696 50 -176 -1696 - 50 -184 -2064 110 -184 -1696 110 -176 -1696 110 -176 -2064 110 -176 -2064 - 110 -176 -1696 110 -176 -1696 106 -176 -2064 106 -176 -2064 106 -176 -1696 - 106 -184 -1696 106 -184 -2064 106 -184 -2064 106 -184 -1696 106 -184 -1696 - 110 -184 -2064 110 -184 -2064 110 -176 -2064 110 -176 -2064 106 -184 -2064 - 106 -176 -1696 110 -184 -1696 110 -184 -1696 106 -176 -1696 106; - setAttr -s 720 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:331]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0 198 - 197 0 197 196 0 196 198 0 199 198 0 - 196 199 0 202 201 0 201 200 0 200 202 - 0 203 202 0 200 203 0 206 205 0 205 - 204 0 204 206 0 207 206 0 204 207 0 - 210 209 0 209 208 0 208 210 0 211 210 - 0 208 211 0 214 213 0 213 212 0 212 - 214 0 215 214 0 212 215 0 218 217 0 - 217 216 0 216 218 0 219 218 0 216 219 - 0 222 221 0 221 220 0 220 222 0 223 - 222 0 220 223 0 226 225 0 225 224 0 - 224 226 0 227 226 0 224 227 0 230 229 - 0 229 228 0 228 230 0 231 230 0 228 - 231 0 234 233 0 233 232 0 232 234 0 - 235 234 0 232 235 0 238 237 0 237 236 - 0 236 238 0 239 238 0 236 239 0 242 - 241 0 241 240 0 240 242 0 243 242 0 - 240 243 0 246 245 0 245 244 0 244 246 - 0 247 246 0 244 247 0 250 249 0 249 - 248 0 248 250 0 251 250 0 248 251 0 - 254 253 0 253 252 0 252 254 0 255 254 - 0 252 255 0 258 257 0 257 256 0 256 - 258 0 259 258 0 256 259 0 262 261 0 - 261 260 0 260 262 0 263 262 0 260 263 - 0 266 265 0 265 264 0; - setAttr ".ed[332:497]" 264 266 0 267 266 0 264 - 267 0 270 269 0 269 268 0 268 270 0 - 271 270 0 268 271 0 274 273 0 273 272 - 0 272 274 0 275 274 0 272 275 0 278 - 277 0 277 276 0 276 278 0 279 278 0 - 276 279 0 282 281 0 281 280 0 280 282 - 0 283 282 0 280 283 0 286 285 0 285 - 284 0 284 286 0 287 286 0 284 287 0 - 290 289 0 289 288 0 288 290 0 291 290 - 0 288 291 0 294 293 0 293 292 0 292 - 294 0 295 294 0 292 295 0 298 297 0 - 297 296 0 296 298 0 299 298 0 296 299 - 0 302 301 0 301 300 0 300 302 0 303 - 302 0 300 303 0 306 305 0 305 304 0 - 304 306 0 307 306 0 304 307 0 310 309 - 0 309 308 0 308 310 0 311 310 0 308 - 311 0 314 313 0 313 312 0 312 314 0 - 315 314 0 312 315 0 318 317 0 317 316 - 0 316 318 0 319 318 0 316 319 0 322 - 321 0 321 320 0 320 322 0 323 322 0 - 320 323 0 326 325 0 325 324 0 324 326 - 0 327 326 0 324 327 0 330 329 0 329 - 328 0 328 330 0 331 330 0 328 331 0 - 334 333 0 333 332 0 332 334 0 335 334 - 0 332 335 0 338 337 0 337 336 0 336 - 338 0 339 338 0 336 339 0 342 341 0 - 341 340 0 340 342 0 343 342 0 340 343 - 0 346 345 0 345 344 0 344 346 0 347 - 346 0 344 347 0 350 349 0 349 348 0 - 348 350 0 351 350 0 348 351 0 354 353 - 0 353 352 0 352 354 0 355 354 0 352 - 355 0 358 357 0 357 356 0 356 358 0 - 359 358 0 356 359 0 362 361 0 361 360 - 0 360 362 0 363 362 0 360 363 0 366 - 365 0 365 364 0 364 366 0 367 366 0 - 364 367 0 370 369 0 369 368 0 368 370 - 0 371 370 0 368 371 0 374 373 0 373 - 372 0 372 374 0 375 374 0 372 375 0 - 378 377 0 377 376 0 376 378 0 379 378 - 0 376 379 0 382 381 0 381 380 0 380 - 382 0 383 382 0 380 383 0 386 385 0 - 385 384 0 384 386 0 387 386 0 384 387 - 0 390 389 0 389 388 0 388 390 0 391 - 390 0 388 391 0 394 393 0 393 392 0 - 392 394 0 395 394 0 392 395 0 398 397 - 0 397 396 0 396 398 0; - setAttr ".ed[498:663]" 399 398 0 396 399 0 402 - 401 0 401 400 0 400 402 0 403 402 0 - 400 403 0 406 405 0 405 404 0 404 406 - 0 407 406 0 404 407 0 410 409 0 409 - 408 0 408 410 0 411 410 0 408 411 0 - 414 413 0 413 412 0 412 414 0 415 414 - 0 412 415 0 418 417 0 417 416 0 416 - 418 0 419 418 0 416 419 0 422 421 0 - 421 420 0 420 422 0 423 422 0 420 423 - 0 426 425 0 425 424 0 424 426 0 427 - 426 0 424 427 0 430 429 0 429 428 0 - 428 430 0 431 430 0 428 431 0 434 433 - 0 433 432 0 432 434 0 435 434 0 432 - 435 0 438 437 0 437 436 0 436 438 0 - 439 438 0 436 439 0 442 441 0 441 440 - 0 440 442 0 443 442 0 440 443 0 446 - 445 0 445 444 0 444 446 0 447 446 0 - 444 447 0 450 449 0 449 448 0 448 450 - 0 451 450 0 448 451 0 454 453 0 453 - 452 0 452 454 0 455 454 0 452 455 0 - 458 457 0 457 456 0 456 458 0 459 458 - 0 456 459 0 462 461 0 461 460 0 460 - 462 0 463 462 0 460 463 0 466 465 0 - 465 464 0 464 466 0 467 466 0 464 467 - 0 470 469 0 469 468 0 468 470 0 471 - 470 0 468 471 0 474 473 0 473 472 0 - 472 474 0 475 474 0 472 475 0 478 477 - 0 477 476 0 476 478 0 479 478 0 476 - 479 0 482 481 0 481 480 0 480 482 0 - 483 482 0 480 483 0 486 485 0 485 484 - 0 484 486 0 487 486 0 484 487 0 490 - 489 0 489 488 0 488 490 0 491 490 0 - 488 491 0 494 493 0 493 492 0 492 494 - 0 495 494 0 492 495 0 498 497 0 497 - 496 0 496 498 0 499 498 0 496 499 0 - 502 501 0 501 500 0 500 502 0 503 502 - 0 500 503 0 506 505 0 505 504 0 504 - 506 0 507 506 0 504 507 0 510 509 0 - 509 508 0 508 510 0 511 510 0 508 511 - 0 514 513 0 513 512 0 512 514 0 515 - 514 0 512 515 0 518 517 0 517 516 0 - 516 518 0 519 518 0 516 519 0 522 521 - 0 521 520 0 520 522 0 523 522 0 520 - 523 0 526 525 0 525 524 0 524 526 0 - 527 526 0 524 527 0 530 529 0 529 528 - 0 528 530 0 531 530 0; - setAttr ".ed[664:719]" 528 531 0 534 533 0 533 - 532 0 532 534 0 535 534 0 532 535 0 - 538 537 0 537 536 0 536 538 0 539 538 - 0 536 539 0 542 541 0 541 540 0 540 - 542 0 543 542 0 540 543 0 546 545 0 - 545 544 0 544 546 0 547 546 0 544 547 - 0 550 549 0 549 548 0 548 550 0 551 - 550 0 548 551 0 554 553 0 553 552 0 - 552 554 0 555 554 0 552 555 0 558 557 - 0 557 556 0 556 558 0 559 558 0 556 - 559 0 562 561 0 561 560 0 560 562 0 - 563 562 0 560 563 0 566 565 0 565 564 - 0 564 566 0 567 566 0 564 567 0 570 - 569 0 569 568 0 568 570 0 571 570 0 - 568 571 0 574 573 0 573 572 0 572 574 - 0 575 574 0 572 575 0; - setAttr -s 864 ".n"; - setAttr ".n[0:165]" -type "float3" 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 - 0 1 0 0 1 0 0 1 0 0; - setAttr ".n[166:331]" -type "float3" 1 0 0 1 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 1 0 0 1 0 0; - setAttr ".n[332:497]" -type "float3" 1 0 0 1 0 0 1 0 0 1 0 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr ".n[498:663]" -type "float3" 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1; - setAttr ".n[664:829]" -type "float3" 0 0 -1 0 0 -1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 0 1 0 0 1; - setAttr ".n[830:863]" -type "float3" 0 0 1 0 0 1 0 0 1 0 0 1 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0; - setAttr -s 288 ".fc[0:287]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 - f 3 245 246 247 - mu 0 3 198 197 196 - f 3 248 -248 249 - mu 0 3 199 198 196 - f 3 250 251 252 - mu 0 3 202 201 200 - f 3 253 -253 254 - mu 0 3 203 202 200 - f 3 255 256 257 - mu 0 3 206 205 204 - f 3 258 -258 259 - mu 0 3 207 206 204 - f 3 260 261 262 - mu 0 3 210 209 208 - f 3 263 -263 264 - mu 0 3 211 210 208 - f 3 265 266 267 - mu 0 3 214 213 212 - f 3 268 -268 269 - mu 0 3 215 214 212 - f 3 270 271 272 - mu 0 3 218 217 216 - f 3 273 -273 274 - mu 0 3 219 218 216 - f 3 275 276 277 - mu 0 3 222 221 220 - f 3 278 -278 279 - mu 0 3 223 222 220 - f 3 280 281 282 - mu 0 3 226 225 224 - f 3 283 -283 284 - mu 0 3 227 226 224 - f 3 285 286 287 - mu 0 3 230 229 228 - f 3 288 -288 289 - mu 0 3 231 230 228 - f 3 290 291 292 - mu 0 3 234 233 232 - f 3 293 -293 294 - mu 0 3 235 234 232 - f 3 295 296 297 - mu 0 3 238 237 236 - f 3 298 -298 299 - mu 0 3 239 238 236 - f 3 300 301 302 - mu 0 3 242 241 240 - f 3 303 -303 304 - mu 0 3 243 242 240 - f 3 305 306 307 - mu 0 3 246 245 244 - f 3 308 -308 309 - mu 0 3 247 246 244 - f 3 310 311 312 - mu 0 3 250 249 248 - f 3 313 -313 314 - mu 0 3 251 250 248 - f 3 315 316 317 - mu 0 3 254 253 252 - f 3 318 -318 319 - mu 0 3 255 254 252 - f 3 320 321 322 - mu 0 3 258 257 256 - f 3 323 -323 324 - mu 0 3 259 258 256 - f 3 325 326 327 - mu 0 3 262 261 260 - f 3 328 -328 329 - mu 0 3 263 262 260 - f 3 330 331 332 - mu 0 3 266 265 264 - f 3 333 -333 334 - mu 0 3 267 266 264 - f 3 335 336 337 - mu 0 3 270 269 268 - f 3 338 -338 339 - mu 0 3 271 270 268 - f 3 340 341 342 - mu 0 3 274 273 272 - f 3 343 -343 344 - mu 0 3 275 274 272 - f 3 345 346 347 - mu 0 3 278 277 276 - f 3 348 -348 349 - mu 0 3 279 278 276 - f 3 350 351 352 - mu 0 3 282 281 280 - f 3 353 -353 354 - mu 0 3 283 282 280 - f 3 355 356 357 - mu 0 3 286 285 284 - f 3 358 -358 359 - mu 0 3 287 286 284 - f 3 360 361 362 - mu 0 3 290 289 288 - f 3 363 -363 364 - mu 0 3 291 290 288 - f 3 365 366 367 - mu 0 3 294 293 292 - f 3 368 -368 369 - mu 0 3 295 294 292 - f 3 370 371 372 - mu 0 3 298 297 296 - f 3 373 -373 374 - mu 0 3 299 298 296 - f 3 375 376 377 - mu 0 3 302 301 300 - f 3 378 -378 379 - mu 0 3 303 302 300 - f 3 380 381 382 - mu 0 3 306 305 304 - f 3 383 -383 384 - mu 0 3 307 306 304 - f 3 385 386 387 - mu 0 3 310 309 308 - f 3 388 -388 389 - mu 0 3 311 310 308 - f 3 390 391 392 - mu 0 3 314 313 312 - f 3 393 -393 394 - mu 0 3 315 314 312 - f 3 395 396 397 - mu 0 3 318 317 316 - f 3 398 -398 399 - mu 0 3 319 318 316 - f 3 400 401 402 - mu 0 3 322 321 320 - f 3 403 -403 404 - mu 0 3 323 322 320 - f 3 405 406 407 - mu 0 3 326 325 324 - f 3 408 -408 409 - mu 0 3 327 326 324 - f 3 410 411 412 - mu 0 3 330 329 328 - f 3 413 -413 414 - mu 0 3 331 330 328 - f 3 415 416 417 - mu 0 3 334 333 332 - f 3 418 -418 419 - mu 0 3 335 334 332 - f 3 420 421 422 - mu 0 3 338 337 336 - f 3 423 -423 424 - mu 0 3 339 338 336 - f 3 425 426 427 - mu 0 3 342 341 340 - f 3 428 -428 429 - mu 0 3 343 342 340 - f 3 430 431 432 - mu 0 3 346 345 344 - f 3 433 -433 434 - mu 0 3 347 346 344 - f 3 435 436 437 - mu 0 3 350 349 348 - f 3 438 -438 439 - mu 0 3 351 350 348 - f 3 440 441 442 - mu 0 3 354 353 352 - f 3 443 -443 444 - mu 0 3 355 354 352 - f 3 445 446 447 - mu 0 3 358 357 356 - f 3 448 -448 449 - mu 0 3 359 358 356 - f 3 450 451 452 - mu 0 3 362 361 360 - f 3 453 -453 454 - mu 0 3 363 362 360 - f 3 455 456 457 - mu 0 3 366 365 364 - f 3 458 -458 459 - mu 0 3 367 366 364 - f 3 460 461 462 - mu 0 3 370 369 368 - f 3 463 -463 464 - mu 0 3 371 370 368 - f 3 465 466 467 - mu 0 3 374 373 372 - f 3 468 -468 469 - mu 0 3 375 374 372 - f 3 470 471 472 - mu 0 3 378 377 376 - f 3 473 -473 474 - mu 0 3 379 378 376 - f 3 475 476 477 - mu 0 3 382 381 380 - f 3 478 -478 479 - mu 0 3 383 382 380 - f 3 480 481 482 - mu 0 3 386 385 384 - f 3 483 -483 484 - mu 0 3 387 386 384 - f 3 485 486 487 - mu 0 3 390 389 388 - f 3 488 -488 489 - mu 0 3 391 390 388 - f 3 490 491 492 - mu 0 3 394 393 392 - f 3 493 -493 494 - mu 0 3 395 394 392 - f 3 495 496 497 - mu 0 3 398 397 396 - f 3 498 -498 499 - mu 0 3 399 398 396 - f 3 500 501 502 - mu 0 3 402 401 400 - f 3 503 -503 504 - mu 0 3 403 402 400 - f 3 505 506 507 - mu 0 3 406 405 404 - f 3 508 -508 509 - mu 0 3 407 406 404 - f 3 510 511 512 - mu 0 3 410 409 408 - f 3 513 -513 514 - mu 0 3 411 410 408 - f 3 515 516 517 - mu 0 3 414 413 412 - f 3 518 -518 519 - mu 0 3 415 414 412 - f 3 520 521 522 - mu 0 3 418 417 416 - f 3 523 -523 524 - mu 0 3 419 418 416 - f 3 525 526 527 - mu 0 3 422 421 420 - f 3 528 -528 529 - mu 0 3 423 422 420 - f 3 530 531 532 - mu 0 3 426 425 424 - f 3 533 -533 534 - mu 0 3 427 426 424 - f 3 535 536 537 - mu 0 3 430 429 428 - f 3 538 -538 539 - mu 0 3 431 430 428 - f 3 540 541 542 - mu 0 3 434 433 432 - f 3 543 -543 544 - mu 0 3 435 434 432 - f 3 545 546 547 - mu 0 3 438 437 436 - f 3 548 -548 549 - mu 0 3 439 438 436 - f 3 550 551 552 - mu 0 3 442 441 440 - f 3 553 -553 554 - mu 0 3 443 442 440 - f 3 555 556 557 - mu 0 3 446 445 444 - f 3 558 -558 559 - mu 0 3 447 446 444 - f 3 560 561 562 - mu 0 3 450 449 448 - f 3 563 -563 564 - mu 0 3 451 450 448 - f 3 565 566 567 - mu 0 3 454 453 452 - f 3 568 -568 569 - mu 0 3 455 454 452 - f 3 570 571 572 - mu 0 3 458 457 456 - f 3 573 -573 574 - mu 0 3 459 458 456 - f 3 575 576 577 - mu 0 3 462 461 460 - f 3 578 -578 579 - mu 0 3 463 462 460 - f 3 580 581 582 - mu 0 3 466 465 464 - f 3 583 -583 584 - mu 0 3 467 466 464 - f 3 585 586 587 - mu 0 3 470 469 468 - f 3 588 -588 589 - mu 0 3 471 470 468 - f 3 590 591 592 - mu 0 3 474 473 472 - f 3 593 -593 594 - mu 0 3 475 474 472 - f 3 595 596 597 - mu 0 3 478 477 476 - f 3 598 -598 599 - mu 0 3 479 478 476 - f 3 600 601 602 - mu 0 3 482 481 480 - f 3 603 -603 604 - mu 0 3 483 482 480 - f 3 605 606 607 - mu 0 3 486 485 484 - f 3 608 -608 609 - mu 0 3 487 486 484 - f 3 610 611 612 - mu 0 3 490 489 488 - f 3 613 -613 614 - mu 0 3 491 490 488 - f 3 615 616 617 - mu 0 3 494 493 492 - f 3 618 -618 619 - mu 0 3 495 494 492 - f 3 620 621 622 - mu 0 3 498 497 496 - f 3 623 -623 624 - mu 0 3 499 498 496 - f 3 625 626 627 - mu 0 3 502 501 500 - f 3 628 -628 629 - mu 0 3 503 502 500 - f 3 630 631 632 - mu 0 3 506 505 504 - f 3 633 -633 634 - mu 0 3 507 506 504 - f 3 635 636 637 - mu 0 3 510 509 508 - f 3 638 -638 639 - mu 0 3 511 510 508 - f 3 640 641 642 - mu 0 3 514 513 512 - f 3 643 -643 644 - mu 0 3 515 514 512 - f 3 645 646 647 - mu 0 3 518 517 516 - f 3 648 -648 649 - mu 0 3 519 518 516 - f 3 650 651 652 - mu 0 3 522 521 520 - f 3 653 -653 654 - mu 0 3 523 522 520 - f 3 655 656 657 - mu 0 3 526 525 524 - f 3 658 -658 659 - mu 0 3 527 526 524 - f 3 660 661 662 - mu 0 3 530 529 528 - f 3 663 -663 664 - mu 0 3 531 530 528 - f 3 665 666 667 - mu 0 3 534 533 532 - f 3 668 -668 669 - mu 0 3 535 534 532 - f 3 670 671 672 - mu 0 3 538 537 536 - f 3 673 -673 674 - mu 0 3 539 538 536 - f 3 675 676 677 - mu 0 3 542 541 540 - f 3 678 -678 679 - mu 0 3 543 542 540 - f 3 680 681 682 - mu 0 3 546 545 544 - f 3 683 -683 684 - mu 0 3 547 546 544 - f 3 685 686 687 - mu 0 3 550 549 548 - f 3 688 -688 689 - mu 0 3 551 550 548 - f 3 690 691 692 - mu 0 3 554 553 552 - f 3 693 -693 694 - mu 0 3 555 554 552 - f 3 695 696 697 - mu 0 3 558 557 556 - f 3 698 -698 699 - mu 0 3 559 558 556 - f 3 700 701 702 - mu 0 3 562 561 560 - f 3 703 -703 704 - mu 0 3 563 562 560 - f 3 705 706 707 - mu 0 3 566 565 564 - f 3 708 -708 709 - mu 0 3 567 566 564 - f 3 710 711 712 - mu 0 3 570 569 568 - f 3 713 -713 714 - mu 0 3 571 570 568 - f 3 715 716 717 - mu 0 3 574 573 572 - f 3 718 -718 719 - mu 0 3 575 574 572 ; -createNode transform -n "m6" -p "celing"; -createNode mesh -n "polySurfaceShape39" -p "m6"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 96 ".uvst[0].uvsp[0:95]" -type "float2" 18 -13.50092 - 18 -13.750936 17 -13.750936 17 -13.50092 -58 0.49996901 -59 0.49996901 -59 - 4.0001931 -58 4.0001931 59 0.49996901 58 0.49996901 58 4.0001931 59 4.0001931 - -17 0.49996901 -18 0.49996901 -18 4.0001931 -17 4.0001931 18 0.49996901 17 - 0.49996901 17 4.0001931 18 4.0001931 17 13.500797 17 13.750813 18 13.750813 - 18 13.500797 18 -14.750999 18 -15.001017 17 -15.001017 17 -14.750999 -63 - 0.49996901 -64 0.49996901 -64 4.0001931 -63 4.0001931 64 0.49996901 63 0.49996901 - 63 4.0001931 64 4.0001931 -17 0.49996901 -18 0.49996901 -18 4.0001931 -17 - 4.0001931 18 0.49996901 17 0.49996901 17 4.0001931 18 4.0001931 17 14.750876 - 17 15.000893 18 15.000893 18 14.750876 18 -13.500925 18 -13.750941 17 -13.750941 - 17 -13.500925 -58 0.49996901 -59 0.49996901 -59 4.0001931 -58 4.0001931 59 - 0.49996901 58 0.49996901 58 4.0001931 59 4.0001931 -17 0.49996901 -18 0.49996901 - -18 4.0001931 -17 4.0001931 18 0.49996901 17 0.49996901 17 4.0001931 18 4.0001931 - 17 15.500925 17 15.750941 18 15.750941 18 15.500925 18 -14.751005 18 -15.00102 - 17 -15.00102 17 -14.751005 -63 0.49996901 -64 0.49996901 -64 4.0001931 -63 - 4.0001931 64 0.49996901 63 0.49996901 63 4.0001931 64 4.0001931 -17 0.49996901 - -18 0.49996901 -18 4.0001931 -17 4.0001931 18 0.49996901 17 0.49996901 17 - 4.0001931 18 4.0001931 17 16.751005 17 17.00102 18 17.00102 18 16.751005; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 96 ".vt[0:95]" 224 -2144 -336 192 -2144 -336 192 - -2144 -304 224 -2144 -304 224 -2144 -304 192 -2144 -304 192 -1696 -304 224 - -1696 -304 192 -2144 -336 224 -2144 -336 224 -1696 -336 192 -1696 -336 192 - -2144 -304 192 -2144 -336 192 -1696 -336 192 -1696 -304 224 -2144 -336 224 - -2144 -304 224 -1696 -304 224 -1696 -336 224 -1696 -304 192 -1696 -304 192 - -1696 -336 224 -1696 -336 64 -2144 -336 32 -2144 -336 32 -2144 -304 64 -2144 - -304 64 -2144 -304 32 -2144 -304 32 -1696 -304 64 -1696 -304 32 -2144 -336 - 64 -2144 -336 64 -1696 -336 32 -1696 -336 32 -2144 -304 32 -2144 -336 32 - -1696 -336 32 -1696 -304 64 -2144 -336 64 -2144 -304 64 -1696 -304 64 -1696 - -336 64 -1696 -304 32 -1696 -304 32 -1696 -336 64 -1696 -336 -32 -2144 -336 - -64 -2144 -336 -64 -2144 -304 -32 -2144 -304 -32 -2144 -304 -64 -2144 -304 - -64 -1696 -304 -32 -1696 -304 -64 -2144 -336 -32 -2144 -336 -32 -1696 -336 - -64 -1696 -336 -64 -2144 -304 -64 -2144 -336 -64 -1696 -336 -64 -1696 -304 - -32 -2144 -336 -32 -2144 -304 -32 -1696 -304 -32 -1696 -336 -32 -1696 -304 - -64 -1696 -304 -64 -1696 -336 -32 -1696 -336 -192 -2144 -336 -224 -2144 -336 - -224 -2144 -304 -192 -2144 -304 -192 -2144 -304 -224 -2144 -304 -224 -1696 - -304 -192 -1696 -304 -224 -2144 -336 -192 -2144 -336 -192 -1696 -336 -224 - -1696 -336 -224 -2144 -304 -224 -2144 -336 -224 -1696 -336 -224 -1696 -304 - -192 -2144 -336 -192 -2144 -304 -192 -1696 -304 -192 -1696 -336 -192 -1696 - -304 -224 -1696 -304 -224 -1696 -336 -192 -1696 -336; - setAttr -s 120 ".ed[0:119]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0 30 29 0 29 28 0 28 30 0 31 - 30 0 28 31 0 34 33 0 33 32 0 - 32 34 0 35 34 0 32 35 0 38 37 - 0 37 36 0 36 38 0 39 38 0 36 - 39 0 42 41 0 41 40 0 40 42 0 - 43 42 0 40 43 0 46 45 0 45 44 - 0 44 46 0 47 46 0 44 47 0 50 - 49 0 49 48 0 48 50 0 51 50 0 - 48 51 0 54 53 0 53 52 0 52 54 - 0 55 54 0 52 55 0 58 57 0 57 - 56 0 56 58 0 59 58 0 56 59 0 - 62 61 0 61 60 0 60 62 0 63 62 - 0 60 63 0 66 65 0 65 64 0 64 - 66 0 67 66 0 64 67 0 70 69 0 - 69 68 0 68 70 0 71 70 0 68 71 - 0 74 73 0 73 72 0 72 74 0 75 - 74 0 72 75 0 78 77 0 77 76 0 - 76 78 0 79 78 0 76 79 0 82 81 - 0 81 80 0 80 82 0 83 82 0 80 - 83 0 86 85 0 85 84 0 84 86 0 - 87 86 0 84 87 0 90 89 0 89 88 - 0 88 90 0 91 90 0 88 91 0 94 - 93 0 93 92 0 92 94 0 95 94 0 - 92 95 0; - setAttr -s 144 ".n[0:143]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0; - setAttr -s 48 ".fc[0:47]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 ; -createNode transform -n "m7" -p "celing"; -createNode mesh -n "polySurfaceShape40" -p "m7"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 48 ".uvst[0].uvsp[0:47]" -type "float2" 4.2502809 - -13.750936 4.2502809 -14.750999 4.0002651 -14.750999 4.0002651 -13.750936 - -15.000936 0.49996901 -16.000999 0.49996901 -16.000999 4.0001931 -15.000936 - 4.0001931 15.501007 0.49996901 14.500943 0.49996901 14.500943 4.0001931 15.501007 - 4.0001931 4.2502809 0.49996901 4.0002651 0.49996901 4.0002651 4.0001931 4.2502809 - 4.0001931 -4.5002642 0.49996901 -4.7502799 0.49996901 -4.7502799 4.0001931 - -4.5002642 4.0001931 4.0002651 13.750813 4.0002651 14.750876 4.2502809 14.750876 - 4.2502809 13.750813 4.2502809 -13.750941 4.2502809 -14.751005 4.0002651 -14.751005 - 4.0002651 -13.750941 -15.000942 0.49996901 -16.001005 0.49996901 -16.001005 - 4.0001931 -15.000942 4.0001931 15.501005 0.49996901 14.500941 0.49996901 - 14.500941 4.0001931 15.501005 4.0001931 4.2502809 0.49996901 4.0002651 0.49996901 - 4.0002651 4.0001931 4.2502809 4.0001931 -4.5002642 0.49996901 -4.7502799 - 0.49996901 -4.7502799 4.0001931 -4.5002642 4.0001931 4.0002651 15.750941 - 4.0002651 16.751005 4.2502809 16.751005 4.2502809 15.750941; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 48 ".vt[0:47]" 192 -2144 -336 64 -2144 -336 64 - -2144 -304 192 -2144 -304 192 -2144 -304 64 -2144 -304 64 -1696 -304 192 - -1696 -304 64 -2144 -336 192 -2144 -336 192 -1696 -336 64 -1696 -336 192 - -2144 -336 192 -2144 -304 192 -1696 -304 192 -1696 -336 64 -2144 -304 64 - -2144 -336 64 -1696 -336 64 -1696 -304 192 -1696 -304 64 -1696 -304 64 -1696 - -336 192 -1696 -336 -64 -2144 -336 -192 -2144 -336 -192 -2144 -304 -64 -2144 - -304 -64 -2144 -304 -192 -2144 -304 -192 -1696 -304 -64 -1696 -304 -192 -2144 - -336 -64 -2144 -336 -64 -1696 -336 -192 -1696 -336 -64 -2144 -336 -64 -2144 - -304 -64 -1696 -304 -64 -1696 -336 -192 -2144 -304 -192 -2144 -336 -192 -1696 - -336 -192 -1696 -304 -64 -1696 -304 -192 -1696 -304 -192 -1696 -336 -64 -1696 - -336; - setAttr -s 60 ".ed[0:59]" 2 1 0 1 0 - 0 0 2 0 3 2 0 0 3 0 6 - 5 0 5 4 0 4 6 0 7 6 0 - 4 7 0 10 9 0 9 8 0 8 10 - 0 11 10 0 8 11 0 14 13 0 13 - 12 0 12 14 0 15 14 0 12 15 0 - 18 17 0 17 16 0 16 18 0 19 18 - 0 16 19 0 22 21 0 21 20 0 20 - 22 0 23 22 0 20 23 0 26 25 0 - 25 24 0 24 26 0 27 26 0 24 27 - 0 30 29 0 29 28 0 28 30 0 31 - 30 0 28 31 0 34 33 0 33 32 0 - 32 34 0 35 34 0 32 35 0 38 37 - 0 37 36 0 36 38 0 39 38 0 36 - 39 0 42 41 0 41 40 0 40 42 0 - 43 42 0 40 43 0 46 45 0 45 44 - 0 44 46 0 47 46 0 44 47 0; - setAttr -s 72 ".n[0:71]" -type "float3" 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0; - setAttr -s 24 ".fc[0:23]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 ; -createNode transform -n "m8" -p "celing"; -createNode mesh -n "polySurfaceShape41" -p "m8"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 196 ".uvst[0].uvsp[0:195]" -type "float2" 2 -32.25 - 2 -29.25 3 -29.25 3 -32.25 2 -32.25 2 -29.25 3 -29.25 3 -32.25 24.25 0 24.25 - 1.25 26.25 1.25 26.25 0 26.75 0 26.75 1.25 27.75 1.25 27.75 0 -1 31 -1 32 - 3 32 3 31 -34.25 0 -34.25 1.25 -33.25 1.25 -33.25 0 -1.25 0 -1.25 1.25 2.75 - 1.25 2.75 0 26.75 0 26.75 1.25 27.75 1.25 27.75 0 -9.25 0 -9.25 1.25 -5.25 - 1.25 -5.25 0 -1.25 -30 -1.25 -29 2.75 -29 2.75 -30 -34.25 0 -34.25 1.25 -33.25 - 1.25 -33.25 0 3 0 3 1.25 4 1.25 4 0 26.75 0 26.75 1.25 27.75 1.25 27.75 0 - -10.5 0 -10.5 1.25 -9.5 1.25 -9.5 0 3 -30 3 -29 4 -29 4 -30 -1 26 -1 27 3 - 27 3 26 -30 -1 -30 0.25 -29 0.25 -29 -1 -1 -1 -1 0.25 3 0.25 3 -1 23 -1 23 - 0.25 24 0.25 24 -1 -9 -1 -9 0.25 -5 0.25 -5 -1 -1 -27 -1 -26 3 -26 3 -27 - -31 7 -33 7 -33 8 -31 8 -32.75 0 -32.75 1.25 -30.75 1.25 -30.75 0 3 0 3 1.25 - 4 1.25 4 0 24.25 0 24.25 1.25 26.25 1.25 26.25 0 -10.5 0 -10.5 1.25 -9.5 - 1.25 -9.5 0 3 -28.5 3 -26.5 4 -26.5 4 -28.5 -30.25 0 -30.25 1.25 -29.25 1.25 - -29.25 0 3 0 3 1.25 4 1.25 4 0 22.75 0 22.75 1.25 23.75 1.25 23.75 0 -10.5 - 0 -10.5 1.25 -9.5 1.25 -9.5 0 3 -26 3 -25 4 -25 4 -26 29.25 0 28.25 0 28.25 - 1.25 29.25 1.25 -42 9 -41 9 -41 8 -42 8 29.25 0 28.25 0 28.25 1.25 29.25 - 1.25 -2.5 0 -2.5 1.25 -1.5 1.25 -1.5 0 -35.75 1.25 -34.75 1.25 -34.75 0 -35.75 - 0 -1.5 -30.5 -1.5 -31.5 -2.5 -31.5 -2.5 -30.5 -5 0 -5 1.25 -4 1.25 -4 0 -34 - 52 -35 52 -35 51 -34 51 29.25 1.25 28.25 1.25 28.25 0 29.25 0 -1.5 0 -1.5 - 1.25 -2.5 1.25 -2.5 0 -35.75 0 -34.75 0 -34.75 1.25 -35.75 1.25 -1.5 -31.5 - -1.5 -30.5 -2.5 -30.5 -2.5 -31.5 -4 0 -4 1.25 -5 1.25 -5 0 29.25 1.25 28.25 - 1.25 28.25 0 29.25 0 29.25 1.25 28.25 1.25 28.25 0 29.25 0 22.75 0 22.75 - 1.25 23.75 1.25 23.75 0 22.75 0 22.75 1.25 23.75 1.25 23.75 0; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 196 ".vt"; - setAttr ".vt[0:165]" -224 -2144 -240 -32 -2144 -240 -32 -2144 -304 - -224 -2144 -304 32 -2144 -240 224 -2144 -240 224 -2144 -304 32 -2144 -304 - 64 -2144 128 64 -2064 128 -64 -2064 128 -64 -2144 128 -96 -2144 128 -96 -2064 - 128 -160 -2064 128 -160 -2144 128 -96 -2064 112 -160 -2064 112 -160 -2064 - -144 -96 -2064 -144 -160 -2144 112 -160 -2064 112 -96 -2064 112 -96 -2144 - 112 -96 -2144 112 -96 -2064 112 -96 -2064 -144 -96 -2144 -144 -96 -2144 -144 - -96 -2064 -144 -160 -2064 -144 -160 -2144 -144 -160 -2144 -144 -160 -2064 - -144 -160 -2064 112 -160 -2144 112 -160 -2144 112 -96 -2144 112 -96 -2144 - -144 -160 -2144 -144 -160 -2144 -160 -160 -2064 -160 -96 -2064 -160 -96 -2144 - -160 -96 -2144 -160 -96 -2064 -160 -96 -2064 -224 -96 -2144 -224 -96 -2144 - -224 -96 -2064 -224 -160 -2064 -224 -160 -2144 -224 -160 -2144 -224 -160 - -2064 -224 -160 -2064 -160 -160 -2144 -160 -160 -2144 -160 -96 -2144 -160 - -96 -2144 -224 -160 -2144 -224 160 -2064 112 96 -2064 112 96 -2064 -144 160 - -2064 -144 96 -2144 112 96 -2064 112 160 -2064 112 160 -2144 112 160 -2144 - 112 160 -2064 112 160 -2064 -144 160 -2144 -144 160 -2144 -144 160 -2064 - -144 96 -2064 -144 96 -2144 -144 96 -2144 -144 96 -2064 -144 96 -2064 112 - 96 -2144 112 96 -2144 112 160 -2144 112 160 -2144 -144 96 -2144 -144 64 -2064 - -160 -64 -2064 -160 -64 -2064 -224 64 -2064 -224 -64 -2144 -160 -64 -2064 - -160 64 -2064 -160 64 -2144 -160 64 -2144 -160 64 -2064 -160 64 -2064 -224 - 64 -2144 -224 64 -2144 -224 64 -2064 -224 -64 -2064 -224 -64 -2144 -224 -64 - -2144 -224 -64 -2064 -224 -64 -2064 -160 -64 -2144 -160 -64 -2144 -160 64 - -2144 -160 64 -2144 -224 -64 -2144 -224 96 -2144 -160 96 -2064 -160 160 -2064 - -160 160 -2144 -160 160 -2144 -160 160 -2064 -160 160 -2064 -224 160 -2144 - -224 160 -2144 -224 160 -2064 -224 96 -2064 -224 96 -2144 -224 96 -2144 -224 - 96 -2064 -224 96 -2064 -160 96 -2144 -160 96 -2144 -160 160 -2144 -160 160 - -2144 -224 96 -2144 -224 -256 -2144 128 -192 -2144 128 -192 -2064 128 -256 - -2064 128 -256 -2064 -224 -192 -2064 -224 -192 -2064 -160 -256 -2064 -160 - -256 -2144 -224 -192 -2144 -224 -192 -2064 -224 -256 -2064 -224 -192 -2144 - -160 -192 -2064 -160 -192 -2064 -224 -192 -2144 -224 -256 -2064 -160 -192 - -2064 -160 -192 -2144 -160 -256 -2144 -160 -192 -2144 -224 -256 -2144 -224 - -256 -2144 -160 -192 -2144 -160 -256 -2144 -224 -256 -2064 -224 -256 -2064 - -160 -256 -2144 -160 256 -2064 -160 192 -2064 -160 192 -2064 -224 256 -2064 - -224 256 -2064 -224 192 -2064 -224 192 -2144 -224 256 -2144 -224 192 -2144 - -224 192 -2064 -224; - setAttr ".vt[166:195]" 192 -2064 -160 192 -2144 -160 256 -2144 -160 - 192 -2144 -160 192 -2064 -160 256 -2064 -160 256 -2144 -224 192 -2144 -224 - 192 -2144 -160 256 -2144 -160 256 -2144 -160 256 -2064 -160 256 -2064 -224 - 256 -2144 -224 256 -2064 128 192 -2064 128 192 -2144 128 256 -2144 128 352 - -2064 128 288 -2064 128 288 -2144 128 352 -2144 128 160 -2144 128 160 -2064 - 128 96 -2064 128 96 -2144 128 448 -2144 128 448 -2064 128 384 -2064 128 384 - -2144 128; - setAttr -s 245 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:244]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0 174 173 0 - 173 172 0 172 174 0 175 174 0 172 175 - 0 178 177 0 177 176 0 176 178 0 179 - 178 0 176 179 0 182 181 0 181 180 0 - 180 182 0 183 182 0 180 183 0 186 185 - 0 185 184 0 184 186 0 187 186 0 184 - 187 0 190 189 0 189 188 0 188 190 0 - 191 190 0 188 191 0 194 193 0 193 192 - 0 192 194 0 195 194 0 192 195 0; - setAttr -s 294 ".n"; - setAttr ".n[0:165]" -type "float3" 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1; - setAttr ".n[166:293]" -type "float3" 0 0 1 0 0 1 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1; - setAttr -s 98 ".fc[0:97]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 - f 3 215 216 217 - mu 0 3 174 173 172 - f 3 218 -218 219 - mu 0 3 175 174 172 - f 3 220 221 222 - mu 0 3 178 177 176 - f 3 223 -223 224 - mu 0 3 179 178 176 - f 3 225 226 227 - mu 0 3 182 181 180 - f 3 228 -228 229 - mu 0 3 183 182 180 - f 3 230 231 232 - mu 0 3 186 185 184 - f 3 233 -233 234 - mu 0 3 187 186 184 - f 3 235 236 237 - mu 0 3 190 189 188 - f 3 238 -238 239 - mu 0 3 191 190 188 - f 3 240 241 242 - mu 0 3 194 193 192 - f 3 243 -243 244 - mu 0 3 195 194 192 ; -createNode transform -n "m9" -p "celing"; -createNode mesh -n "polySurfaceShape42" -p "m9"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 172 ".uvst[0].uvsp[0:171]" -type "float2" -30.25 -1 - -33.25 -1 -33.25 1.5 -30.25 1.5 3 -1 2 -1 2 1.5 3 1.5 33.25 -1 30.25 -1 30.25 - 1.5 33.25 1.5 -2 -1 -3 -1 -3 1.5 -2 1.5 -30.25 -1 -33.25 -1 -33.25 1.5 -30.25 - 1.5 3 -1 2 -1 2 1.5 3 1.5 33.25 -1 30.25 -1 30.25 1.5 33.25 1.5 -2 -1 -3 - -1 -3 1.5 -2 1.5 3.125 61.5 3.125 62 3.875 62 3.875 61.5 -30.375 8.5 -30.625 - 8.5 -30.625 9 -30.375 9 3.875 8.5 3.125 8.5 3.125 9 3.875 9 30.624996 8.5 - 30.374996 8.5 30.374996 9 30.624996 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 - 9 3.125 61.5 3.125 62 3.875 62 3.875 61.5 -30.375 8.5 -30.625 8.5 -30.625 - 9 -30.375 9 3.875 8.5 3.125 8.5 3.125 9 3.875 9 30.624996 8.5 30.374996 8.5 - 30.374996 9 30.624996 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 9 3.875015 - 61.5 3.125015 61.5 3.125015 62 3.875015 62 -30.375 8.5 -30.625 8.5 -30.625 - 9 -30.375 9 3.875 8.5 3.125 8.5 3.125 9 3.875 9 30.625008 8.5 30.375008 8.5 - 30.375008 9 30.625008 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 9 3.875015 - 61.5 3.125015 61.5 3.125015 62 3.875015 62 -30.375 8.5 -30.625 8.5 -30.625 - 9 -30.375 9 3.875 8.5 3.125 8.5 3.125 9 3.875 9 30.625008 8.5 30.375008 8.5 - 30.375008 9 30.625008 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 9 3.875015 - 61.5 3.125015 61.5 3.125015 62 3.875015 62 -30.375 8.5 -30.625 8.5 -30.625 - 9 -30.375 9 3.874985 8.5 3.124985 8.5 3.124985 9 3.874985 9 30.625008 8.5 - 30.375008 8.5 30.375008 9 30.625008 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 - 9 3.875015 61.5 3.125015 61.5 3.125015 62 3.875015 62 -30.375 8.5 -30.625 - 8.5 -30.625 9 -30.375 9 3.874985 8.5 3.124985 8.5 3.124985 9 3.874985 9 30.625008 - 8.5 30.375008 8.5 30.375008 9 30.625008 9 -3.1249919 8.5 -3.8749919 8.5 -3.8749919 - 9 -3.1249919 9 3.125 61.5 3.125 62 3.875 62 3.875 61.5 -30.375 8.5 -30.625 - 8.5 -30.625 9 -30.375 9 3.875 8.5 3.125 8.5 3.125 9 3.875 9 30.625011 8.5 - 30.375011 8.5 30.375011 9 30.625011 9 -3.125 8.5 -3.875 8.5 -3.875 9 -3.125 - 9; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 172 ".vt"; - setAttr ".vt[0:165]" -32 -2144 -240 -224 -2144 -240 -224 -2064 - -240 -32 -2064 -240 -32 -2144 -304 -32 -2144 -240 -32 -2064 -240 -32 -2064 - -304 -224 -2144 -304 -32 -2144 -304 -32 -2064 -304 -224 -2064 -304 -224 -2144 - -240 -224 -2144 -304 -224 -2064 -304 -224 -2064 -240 224 -2144 -240 32 -2144 - -240 32 -2064 -240 224 -2064 -240 224 -2144 -304 224 -2144 -240 224 -2064 - -240 224 -2064 -304 32 -2144 -304 224 -2144 -304 224 -2064 -304 32 -2064 - -304 32 -2144 -240 32 -2144 -304 32 -2064 -304 32 -2064 -240 -120 -1784 -56 - -136 -1784 -56 -136 -1784 -104 -120 -1784 -104 -120 -1800 -56 -136 -1800 - -56 -136 -1784 -56 -120 -1784 -56 -120 -1800 -104 -120 -1800 -56 -120 -1784 - -56 -120 -1784 -104 -136 -1800 -104 -120 -1800 -104 -120 -1784 -104 -136 - -1784 -104 -136 -1800 -56 -136 -1800 -104 -136 -1784 -104 -136 -1784 -56 - 136 -1784 -56 120 -1784 -56 120 -1784 -104 136 -1784 -104 136 -1800 -56 120 - -1800 -56 120 -1784 -56 136 -1784 -56 136 -1800 -104 136 -1800 -56 136 -1784 - -56 136 -1784 -104 120 -1800 -104 136 -1800 -104 136 -1784 -104 120 -1784 - -104 120 -1800 -56 120 -1800 -104 120 -1784 -104 120 -1784 -56 -104 -1784 - -184 -152 -1784 -184 -152 -1784 -200 -104 -1784 -200 -152 -1800 -184 -152 - -1800 -200 -152 -1784 -200 -152 -1784 -184 -104 -1800 -184 -152 -1800 -184 - -152 -1784 -184 -104 -1784 -184 -104 -1800 -200 -104 -1800 -184 -104 -1784 - -184 -104 -1784 -200 -152 -1800 -200 -104 -1800 -200 -104 -1784 -200 -152 - -1784 -200 152 -1784 -184 104 -1784 -184 104 -1784 -200 152 -1784 -200 104 - -1800 -184 104 -1800 -200 104 -1784 -200 104 -1784 -184 152 -1800 -184 104 - -1800 -184 104 -1784 -184 152 -1784 -184 152 -1800 -200 152 -1800 -184 152 - -1784 -184 152 -1784 -200 104 -1800 -200 152 -1800 -200 152 -1784 -200 104 - -1784 -200 -104 -1784 168 -152 -1784 168 -152 -1784 152 -104 -1784 152 -152 - -1800 168 -152 -1800 152 -152 -1784 152 -152 -1784 168 -104 -1800 168 -152 - -1800 168 -152 -1784 168 -104 -1784 168 -104 -1800 152 -104 -1800 168 -104 - -1784 168 -104 -1784 152 -152 -1800 152 -104 -1800 152 -104 -1784 152 -152 - -1784 152 152 -1784 168 104 -1784 168 104 -1784 152 152 -1784 152 104 -1800 - 168 104 -1800 152 104 -1784 152 104 -1784 168 152 -1800 168 104 -1800 168 - 104 -1784 168 152 -1784 168 152 -1800 152 152 -1800 168 152 -1784 168 152 - -1784 152 104 -1800 152 152 -1800 152 152 -1784 152 104 -1784 152 -120 -1784 - 64 -136 -1784 64 -136 -1784 16 -120 -1784 16 -120 -1800 64 -136 -1800 64 - -136 -1784 64 -120 -1784 64 -120 -1800 16 -120 -1800 64 -120 -1784 64 -120 - -1784 16 -136 -1800 16 -120 -1800 16; - setAttr ".vt[166:171]" -120 -1784 16 -136 -1784 16 -136 -1800 64 -136 - -1800 16 -136 -1784 16 -136 -1784 64; - setAttr -s 215 ".ed"; - setAttr ".ed[0:165]" 2 1 0 1 0 0 - 0 2 0 3 2 0 0 3 0 6 5 - 0 5 4 0 4 6 0 7 6 0 4 - 7 0 10 9 0 9 8 0 8 10 0 - 11 10 0 8 11 0 14 13 0 13 12 - 0 12 14 0 15 14 0 12 15 0 18 - 17 0 17 16 0 16 18 0 19 18 0 - 16 19 0 22 21 0 21 20 0 20 22 - 0 23 22 0 20 23 0 26 25 0 25 - 24 0 24 26 0 27 26 0 24 27 0 - 30 29 0 29 28 0 28 30 0 31 30 - 0 28 31 0 34 33 0 33 32 0 32 - 34 0 35 34 0 32 35 0 38 37 0 - 37 36 0 36 38 0 39 38 0 36 39 - 0 42 41 0 41 40 0 40 42 0 43 - 42 0 40 43 0 46 45 0 45 44 0 - 44 46 0 47 46 0 44 47 0 50 49 - 0 49 48 0 48 50 0 51 50 0 48 - 51 0 54 53 0 53 52 0 52 54 0 - 55 54 0 52 55 0 58 57 0 57 56 - 0 56 58 0 59 58 0 56 59 0 62 - 61 0 61 60 0 60 62 0 63 62 0 - 60 63 0 66 65 0 65 64 0 64 66 - 0 67 66 0 64 67 0 70 69 0 69 - 68 0 68 70 0 71 70 0 68 71 0 - 74 73 0 73 72 0 72 74 0 75 74 - 0 72 75 0 78 77 0 77 76 0 76 - 78 0 79 78 0 76 79 0 82 81 0 - 81 80 0 80 82 0 83 82 0 80 83 - 0 86 85 0 85 84 0 84 86 0 87 - 86 0 84 87 0 90 89 0 89 88 0 - 88 90 0 91 90 0 88 91 0 94 93 - 0 93 92 0 92 94 0 95 94 0 92 - 95 0 98 97 0 97 96 0 96 98 0 - 99 98 0 96 99 0 102 101 0 101 100 - 0 100 102 0 103 102 0 100 103 0 106 - 105 0 105 104 0 104 106 0 107 106 0 - 104 107 0 110 109 0 109 108 0 108 110 - 0 111 110 0 108 111 0 114 113 0 113 - 112 0 112 114 0 115 114 0 112 115 0 - 118 117 0 117 116 0 116 118 0 119 118 - 0 116 119 0 122 121 0 121 120 0 120 - 122 0 123 122 0 120 123 0 126 125 0 - 125 124 0 124 126 0 127 126 0 124 127 - 0 130 129 0 129 128 0 128 130 0 131 - 130 0 128 131 0 134 133 0; - setAttr ".ed[166:214]" 133 132 0 132 134 0 135 - 134 0 132 135 0 138 137 0 137 136 0 - 136 138 0 139 138 0 136 139 0 142 141 - 0 141 140 0 140 142 0 143 142 0 140 - 143 0 146 145 0 145 144 0 144 146 0 - 147 146 0 144 147 0 150 149 0 149 148 - 0 148 150 0 151 150 0 148 151 0 154 - 153 0 153 152 0 152 154 0 155 154 0 - 152 155 0 158 157 0 157 156 0 156 158 - 0 159 158 0 156 159 0 162 161 0 161 - 160 0 160 162 0 163 162 0 160 163 0 - 166 165 0 165 164 0 164 166 0 167 166 - 0 164 167 0 170 169 0 169 168 0 168 - 170 0 171 170 0 168 171 0; - setAttr -s 258 ".n"; - setAttr ".n[0:165]" -type "float3" 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1; - setAttr ".n[166:257]" -type "float3" 0 0 -1 0 0 -1 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 - 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 - -1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 - 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 - 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0; - setAttr -s 86 ".fc[0:85]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 2 1 0 - f 3 3 -3 4 - mu 0 3 3 2 0 - f 3 5 6 7 - mu 0 3 6 5 4 - f 3 8 -8 9 - mu 0 3 7 6 4 - f 3 10 11 12 - mu 0 3 10 9 8 - f 3 13 -13 14 - mu 0 3 11 10 8 - f 3 15 16 17 - mu 0 3 14 13 12 - f 3 18 -18 19 - mu 0 3 15 14 12 - f 3 20 21 22 - mu 0 3 18 17 16 - f 3 23 -23 24 - mu 0 3 19 18 16 - f 3 25 26 27 - mu 0 3 22 21 20 - f 3 28 -28 29 - mu 0 3 23 22 20 - f 3 30 31 32 - mu 0 3 26 25 24 - f 3 33 -33 34 - mu 0 3 27 26 24 - f 3 35 36 37 - mu 0 3 30 29 28 - f 3 38 -38 39 - mu 0 3 31 30 28 - f 3 40 41 42 - mu 0 3 34 33 32 - f 3 43 -43 44 - mu 0 3 35 34 32 - f 3 45 46 47 - mu 0 3 38 37 36 - f 3 48 -48 49 - mu 0 3 39 38 36 - f 3 50 51 52 - mu 0 3 42 41 40 - f 3 53 -53 54 - mu 0 3 43 42 40 - f 3 55 56 57 - mu 0 3 46 45 44 - f 3 58 -58 59 - mu 0 3 47 46 44 - f 3 60 61 62 - mu 0 3 50 49 48 - f 3 63 -63 64 - mu 0 3 51 50 48 - f 3 65 66 67 - mu 0 3 54 53 52 - f 3 68 -68 69 - mu 0 3 55 54 52 - f 3 70 71 72 - mu 0 3 58 57 56 - f 3 73 -73 74 - mu 0 3 59 58 56 - f 3 75 76 77 - mu 0 3 62 61 60 - f 3 78 -78 79 - mu 0 3 63 62 60 - f 3 80 81 82 - mu 0 3 66 65 64 - f 3 83 -83 84 - mu 0 3 67 66 64 - f 3 85 86 87 - mu 0 3 70 69 68 - f 3 88 -88 89 - mu 0 3 71 70 68 - f 3 90 91 92 - mu 0 3 74 73 72 - f 3 93 -93 94 - mu 0 3 75 74 72 - f 3 95 96 97 - mu 0 3 78 77 76 - f 3 98 -98 99 - mu 0 3 79 78 76 - f 3 100 101 102 - mu 0 3 82 81 80 - f 3 103 -103 104 - mu 0 3 83 82 80 - f 3 105 106 107 - mu 0 3 86 85 84 - f 3 108 -108 109 - mu 0 3 87 86 84 - f 3 110 111 112 - mu 0 3 90 89 88 - f 3 113 -113 114 - mu 0 3 91 90 88 - f 3 115 116 117 - mu 0 3 94 93 92 - f 3 118 -118 119 - mu 0 3 95 94 92 - f 3 120 121 122 - mu 0 3 98 97 96 - f 3 123 -123 124 - mu 0 3 99 98 96 - f 3 125 126 127 - mu 0 3 102 101 100 - f 3 128 -128 129 - mu 0 3 103 102 100 - f 3 130 131 132 - mu 0 3 106 105 104 - f 3 133 -133 134 - mu 0 3 107 106 104 - f 3 135 136 137 - mu 0 3 110 109 108 - f 3 138 -138 139 - mu 0 3 111 110 108 - f 3 140 141 142 - mu 0 3 114 113 112 - f 3 143 -143 144 - mu 0 3 115 114 112 - f 3 145 146 147 - mu 0 3 118 117 116 - f 3 148 -148 149 - mu 0 3 119 118 116 - f 3 150 151 152 - mu 0 3 122 121 120 - f 3 153 -153 154 - mu 0 3 123 122 120 - f 3 155 156 157 - mu 0 3 126 125 124 - f 3 158 -158 159 - mu 0 3 127 126 124 - f 3 160 161 162 - mu 0 3 130 129 128 - f 3 163 -163 164 - mu 0 3 131 130 128 - f 3 165 166 167 - mu 0 3 134 133 132 - f 3 168 -168 169 - mu 0 3 135 134 132 - f 3 170 171 172 - mu 0 3 138 137 136 - f 3 173 -173 174 - mu 0 3 139 138 136 - f 3 175 176 177 - mu 0 3 142 141 140 - f 3 178 -178 179 - mu 0 3 143 142 140 - f 3 180 181 182 - mu 0 3 146 145 144 - f 3 183 -183 184 - mu 0 3 147 146 144 - f 3 185 186 187 - mu 0 3 150 149 148 - f 3 188 -188 189 - mu 0 3 151 150 148 - f 3 190 191 192 - mu 0 3 154 153 152 - f 3 193 -193 194 - mu 0 3 155 154 152 - f 3 195 196 197 - mu 0 3 158 157 156 - f 3 198 -198 199 - mu 0 3 159 158 156 - f 3 200 201 202 - mu 0 3 162 161 160 - f 3 203 -203 204 - mu 0 3 163 162 160 - f 3 205 206 207 - mu 0 3 166 165 164 - f 3 208 -208 209 - mu 0 3 167 166 164 - f 3 210 211 212 - mu 0 3 170 169 168 - f 3 213 -213 214 - mu 0 3 171 170 168 ; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 5.157268050779404 64.417731710601458 89.372250876656295 ; - setAttr ".sp" -type "double3" 5.157268050779404 64.417731710601458 89.372250876656295 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode brush -n "brush1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode phong -n "m1"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m0__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo1"; -createNode file -n "file1"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/servertex1.tga"; -createNode place2dTexture -n "place2dTexture1"; -createNode phong -n "m3"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m1__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo2"; -createNode file -n "file2"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel21.tga"; -createNode place2dTexture -n "place2dTexture2"; -createNode phong -n "m11"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m10__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo3"; -createNode file -n "file3"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel10.tga"; -createNode place2dTexture -n "place2dTexture3"; -createNode phong -n "m13"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m11__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo4"; -createNode file -n "file4"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel2c.tga"; -createNode place2dTexture -n "place2dTexture4"; -createNode phong -n "m15"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m12__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo5"; -createNode file -n "file5"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel15.tga"; -createNode place2dTexture -n "place2dTexture5"; -createNode phong -n "m17"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m13__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo6"; -createNode file -n "file6"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel2d.tga"; -createNode place2dTexture -n "place2dTexture6"; -createNode phong -n "m19"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m14__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo7"; -createNode file -n "file7"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel12a.tga"; -createNode place2dTexture -n "place2dTexture7"; -createNode phong -n "m21"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m15__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo8"; -createNode file -n "file8"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/reactorwalk1a.tga"; -createNode place2dTexture -n "place2dTexture8"; -createNode phong -n "m23"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m16__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo9"; -createNode file -n "file9"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel16.tga"; -createNode place2dTexture -n "place2dTexture9"; -createNode phong -n "m25"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m17__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo10"; -createNode file -n "file10"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/sofloor2.tga"; -createNode place2dTexture -n "place2dTexture10"; -createNode phong -n "m27"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m18__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo11"; -createNode file -n "file11"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/sofloor1.tga"; -createNode place2dTexture -n "place2dTexture11"; -createNode phong -n "m29"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m19__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo12"; -createNode file -n "file12"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/sofloor3.tga"; -createNode place2dTexture -n "place2dTexture12"; -createNode phong -n "m31"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m2__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo13"; -createNode file -n "file13"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel9.tga"; -createNode place2dTexture -n "place2dTexture13"; -createNode phong -n "m33"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m20__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo14"; -createNode file -n "file14"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel20_shadow.tga"; -createNode place2dTexture -n "place2dTexture14"; -createNode phong -n "m35"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m21__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo15"; -createNode file -n "file15"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel20.tga"; -createNode place2dTexture -n "place2dTexture15"; -createNode phong -n "m37"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m22__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo16"; -createNode file -n "file16"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/elec_box1s.tga"; -createNode place2dTexture -n "place2dTexture16"; -createNode phong -n "m39"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m23__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo17"; -createNode file -n "file17"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/elec_box1.tga"; -createNode place2dTexture -n "place2dTexture17"; -createNode phong -n "m41"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m24__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo18"; -createNode file -n "file18"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/decals/lightgrate.tga"; -createNode place2dTexture -n "place2dTexture18"; -createNode phong -n "m43"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m25__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo19"; -createNode file -n "file19"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/common/nodraw.tga"; -createNode place2dTexture -n "place2dTexture19"; -createNode phong -n "m45"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m26__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo20"; -createNode file -n "file20"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer3e.tga"; -createNode place2dTexture -n "place2dTexture20"; -createNode phong -n "m47"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m27__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo21"; -createNode file -n "file21"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer3a.tga"; -createNode place2dTexture -n "place2dTexture21"; -createNode phong -n "m49"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m28__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo22"; -createNode file -n "file22"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer3f.tga"; -createNode place2dTexture -n "place2dTexture22"; -createNode phong -n "m51"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m29__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo23"; -createNode file -n "file23"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer2.tga"; -createNode place2dTexture -n "place2dTexture23"; -createNode phong -n "m53"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m3__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo24"; -createNode file -n "file24"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel13.tga"; -createNode place2dTexture -n "place2dTexture24"; -createNode phong -n "m55"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m30__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo25"; -createNode file -n "file25"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer3b.tga"; -createNode place2dTexture -n "place2dTexture25"; -createNode phong -n "m57"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m31__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo26"; -createNode file -n "file26"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/object/cdplayer3.tga"; -createNode place2dTexture -n "place2dTexture26"; -createNode phong -n "m59"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m32__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo27"; -createNode file -n "file27"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_trim/bluetex4s_ed.tga"; -createNode place2dTexture -n "place2dTexture27"; -createNode phong -n "m61"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m33__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo28"; -createNode file -n "file28"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_door/smalldoortex.tga"; -createNode place2dTexture -n "place2dTexture28"; -createNode phong -n "m63"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m34__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo29"; -createNode file -n "file29"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel32.tga"; -createNode place2dTexture -n "place2dTexture29"; -createNode phong -n "m65"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m35__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo30"; -createNode file -n "file30"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/sfx/flare.tga"; -createNode place2dTexture -n "place2dTexture30"; -createNode phong -n "m67"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m36__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo31"; -createNode file -n "file31"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_light/striplight3.tga"; -createNode place2dTexture -n "place2dTexture31"; -createNode phong -n "m69"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m37__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo32"; -createNode file -n "file32"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_light/striplight2_break.tga"; -createNode place2dTexture -n "place2dTexture32"; -createNode phong -n "m71"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m38__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo33"; -createNode file -n "file33"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel2b.tga"; -createNode place2dTexture -n "place2dTexture33"; -createNode phong -n "m73"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m39__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo34"; -createNode file -n "file34"; - setAttr ".ftn" -type "string" "p:/doom/base/models//mapobjects/doors/smalldoor.tga"; -createNode place2dTexture -n "place2dTexture34"; -createNode phong -n "m74"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m4__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo35"; -createNode file -n "file35"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/diafloor.tga"; -createNode place2dTexture -n "place2dTexture35"; -createNode phong -n "m76"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m40__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo36"; -createNode file -n "file36"; - setAttr ".ftn" -type "string" "p:/doom/base/models//mapobjects/doors/smalldoor_light.tga"; -createNode place2dTexture -n "place2dTexture36"; -createNode phong -n "m78"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m41__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo37"; -createNode file -n "file37"; - setAttr ".ftn" -type "string" "p:/doom/base/models//mapobjects/doors/smalldoor_sign.tga"; -createNode place2dTexture -n "place2dTexture37"; -createNode phong -n "m79"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m5__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo38"; -createNode file -n "file38"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel15b.tga"; -createNode place2dTexture -n "place2dTexture38"; -createNode phong -n "m80"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m6__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo39"; -createNode file -n "file39"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/skpanel8.tga"; -createNode place2dTexture -n "place2dTexture39"; -createNode phong -n "m81"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m7__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo40"; -createNode file -n "file40"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/cpuwall2.tga"; -createNode place2dTexture -n "place2dTexture40"; -createNode phong -n "m82"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m8__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo41"; -createNode file -n "file41"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_floor/sfloor.tga"; -createNode place2dTexture -n "place2dTexture41"; -createNode phong -n "m83"; - setAttr ".dc" 1; - setAttr ".ambc" -type "float3" 1 1 1 ; - setAttr ".sc" -type "float3" 0.22 0.22 0.22 ; - setAttr ".rfl" 0; - setAttr ".cp" 0; -createNode shadingEngine -n "m9__Grp"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo42"; -createNode file -n "file42"; - setAttr ".ftn" -type "string" "p:/doom/base/textures/base_wall/sopanel4.tga"; -createNode place2dTexture -n "place2dTexture42"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 80 -ast -1 -aet 80 "; - setAttr ".st" 6; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 76 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 0 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.71946295727715 76 13.71946295727715 - 80 13.71946295727715; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 77.739160914831501 76 77.739160914831501 - 80 77.739160914831501; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -76.726154744596627 76 -76.726154744596627 - 80 -76.726154744596627; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -173.86213662459591 76 -173.86213662459591 - 80 -173.86213662459591; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459183 76 15.445123296459183 - 80 15.445123296459183; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 76 15.445123296459185 - 80 15.445123296459185; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459181 76 15.445123296459181 - 80 15.445123296459181; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 76 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 76 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 0 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -2.5294371750177831 76 -2.5294371750177831 - 80 -2.5294371750177831; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.481673551673362 76 13.481673551673362 - 80 13.481673551673362; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.26635088939205875 76 -0.26635088939205875 - 80 -0.26635088939205875; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 141.20709981379272 76 141.20709981379272 - 80 141.20709981379272; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 64.064019952206479 76 64.064019952206479 - 80 64.064019952206479; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 252.95011708695623 76 252.95011708695623 - 80 252.95011708695623; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 76 15.445123296459185 - 80 15.445123296459185; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 76 15.445123296459185 - 80 15.445123296459185; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 76 15.445123296459185 - 80 15.445123296459185; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 76 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 76 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 24 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 0 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -1.3928135170643221 24 -1.3928135170643221 - 80 -1.3928135170643221; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.44973750691804415 24 0.44973750691804415 - 80 0.44973750691804415; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -5.1782975386865164 24 -5.1782975386865164 - 80 -5.1782975386865164; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 24 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 24 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 24 0 80 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 24 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 24 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 24 1 80 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 3; - setAttr -s 3 ".kot[1:2]" 1 3; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.6268319407172029 80 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.1098668596606802 80 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.5034509212546858 80 -2.5034509212546858; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 17.229505560996021 80 17.229505560996021; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -142.678044214414 80 -142.678044214414; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 164.9078898628814 80 164.9078898628814; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -157.12647963025248 80 -157.12647963025248; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.4915788739693325 80 2.4915788739693325; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 14.603740357826355 80 14.603740357826355; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 125.92485631929448 80 125.92485631929448; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -137.58597201509437 80 -137.58597201509437; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 165.12489592367604 80 165.12489592367604; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -182.62675256644729 80 -182.62675256644729; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -172.2204383035033 80 -172.2204383035033; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.5980362269744237 80 -5.5980362269744237; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -57.346922185479528 80 -57.346922185479528; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -91.885862339470236 80 -91.885862339470236; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 160.37306160509956 80 160.37306160509956; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -187.63669417839347 80 -187.63669417839347; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -63.051499853687716 80 -63.051499853687716; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -78.570879654325907 80 -78.570879654325907; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -89.986666011427459 80 -89.986666011427459; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.99999999999999978 80 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.6456615572060826 80 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.9935618776130362 80 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -69.271227102448961 80 -69.271227102448961; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3502596558895279 80 -6.3502596558895279; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -16.64046839726176 80 -16.64046839726176; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 27 1 64 1 80 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -123.23464042896244 27 -121.08621343304297 - 64 -123.21666472111816 80 -123.23464042896244; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 143.53605237544164 27 143.53605237544181 - 64 143.53605237544167 80 143.53605237544164; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -168.9417024479302 27 -170.01591594588993 - 64 -168.72050169771376 80 -168.9417024479302; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -71.291577733818073 27 -76.291700380394332 - 64 -68.467022335389743 80 -71.291577733818073; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -100.37236481072833 27 -104.10452038343382 - 64 -99.260837000052021 80 -100.37236481072833; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 27 5.1135360967872554 64 -2.8611166300148163 - 80 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 27 1 64 1 80 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 27 1 64 1 80 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 27 1 64 1 80 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -87.904755753207809 80 -87.904755753207809; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 161.22675962506509 80 161.22675962506509; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -153.01654730490762 80 -153.01654730490762; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -113.12792264325252 80 -113.12792264325252; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -48.71948422824385 80 -48.71948422824385; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -31.820365996468631 80 -31.820365996468631; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.99999999999999989 80 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.99999999999999978 80 0.99999999999999978; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 23 1 35 1 45 1 60 1 64 - 1 80 1; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 5 5 5 5 5 5 - 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 23 0 35 0 45 0 60 0 64 - 0 80 0; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.3128351505039433 20 2.3128351505039433 - 23 2.3128351505039433 35 2.3128351505039433 45 2.3128351505039433 60 2.3128351505039433 - 64 2.3128351505039433 80 2.3128351505039433; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.23421866920666501 20 0.23421866920666501 - 23 0.23421866920666501 35 0.23421866920666501 45 0.23421866920666501 60 0.23421866920666501 - 64 0.23421866920666501 80 0.23421866920666501; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 -9.8208105571793372 23 -9.8208105571793372 - 35 0 45 0 60 -9.8208105571793372 64 -9.8208105571793372 80 0; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 23 0 35 0 45 0 60 0 64 - 0 80 0; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 23 0 35 0 45 0 60 0 64 - 0 80 0; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 23 1 35 1 45 1 60 1 64 - 1 80 1; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 23 1 35 1 45 1 60 1 64 - 1 80 1; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 23 1 35 1 45 1 60 1 64 - 1 80 1; - setAttr -s 8 ".kbd[1:7]" yes yes yes yes yes yes no; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.0180767416209342 80 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.350740136846035 80 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.679538405939565 80 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -70.481910650545785 80 -70.481910650545785; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8295251468455538 80 -5.8295251468455538; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.906702437419133 80 8.906702437419133; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.0520377321840098 80 -1.0520377321840098; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.1269976388583669 80 -1.1269976388583669; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.2740066452219365 80 -1.2740066452219365; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -161.57409822689215 80 -161.57409822689215; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.2553960033597158 80 -1.2553960033597158; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.3879724291646272 80 -1.3879724291646272; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.70534630546503241 80 -0.70534630546503241; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.1673247220931664 80 -9.1673247220931664; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -22.970956099823336 80 -22.970956099823336; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.9948614426892801 80 -6.9948614426892801; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 171.63031494333711 80 171.63031494333711; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 10.738943211098208 80 10.738943211098208; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 26.326652837683234 80 26.326652837683234; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 95.958161138362598 80 95.958161138362598; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -24.621645877377262 80 -24.621645877377262; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1940.7867903712797 80 -1940.7867903712797; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -193.03588964948031 80 -193.03588964948031; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 54 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 54 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 46 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 46 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultRenderGlobals; - setAttr ".fs" 1; - setAttr ".ef" 10; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_locator5" "group1"; -parent -s -nc -r "IMP_locator6" "group1"; -parent -s -nc -r "IMP_camera" "group1"; -parent -s -nc -r "IMP_locator14" "group1"; -select -ne IMP_ALL; - setAttr ".t" -type "double3" 129.42165465882579 -2061.4711462861542 18.141238410432443 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933642 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".t" -type "double3" 6.7758528420198658 -6.9388939039072284e-018 - -9.5120444723942321e-016 ; - setAttr ".r" -type "double3" -12.784757077400341 3.2695897469829736 -6.9162979482121409 ; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -3.3867499999998705 2.1192000000001707 -3.0821100000000254 ; - setAttr ".r" -type "double3" -58.791714103708735 2.1750129202527693 -26.175703378394829 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[2].llnk"; -connectAttr "m0__Grp.msg" "lightLinker1.lnk[2].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[3].llnk"; -connectAttr "m1__Grp.msg" "lightLinker1.lnk[3].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[4].llnk"; -connectAttr "m10__Grp.msg" "lightLinker1.lnk[4].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[5].llnk"; -connectAttr "m11__Grp.msg" "lightLinker1.lnk[5].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[6].llnk"; -connectAttr "m12__Grp.msg" "lightLinker1.lnk[6].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[7].llnk"; -connectAttr "m13__Grp.msg" "lightLinker1.lnk[7].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[8].llnk"; -connectAttr "m14__Grp.msg" "lightLinker1.lnk[8].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[9].llnk"; -connectAttr "m15__Grp.msg" "lightLinker1.lnk[9].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[10].llnk"; -connectAttr "m16__Grp.msg" "lightLinker1.lnk[10].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[11].llnk"; -connectAttr "m17__Grp.msg" "lightLinker1.lnk[11].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[12].llnk"; -connectAttr "m18__Grp.msg" "lightLinker1.lnk[12].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[13].llnk"; -connectAttr "m19__Grp.msg" "lightLinker1.lnk[13].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[14].llnk"; -connectAttr "m2__Grp.msg" "lightLinker1.lnk[14].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[15].llnk"; -connectAttr "m20__Grp.msg" "lightLinker1.lnk[15].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[16].llnk"; -connectAttr "m21__Grp.msg" "lightLinker1.lnk[16].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[17].llnk"; -connectAttr "m22__Grp.msg" "lightLinker1.lnk[17].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[18].llnk"; -connectAttr "m23__Grp.msg" "lightLinker1.lnk[18].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[19].llnk"; -connectAttr "m24__Grp.msg" "lightLinker1.lnk[19].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[20].llnk"; -connectAttr "m25__Grp.msg" "lightLinker1.lnk[20].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[21].llnk"; -connectAttr "m26__Grp.msg" "lightLinker1.lnk[21].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[22].llnk"; -connectAttr "m27__Grp.msg" "lightLinker1.lnk[22].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[23].llnk"; -connectAttr "m28__Grp.msg" "lightLinker1.lnk[23].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[24].llnk"; -connectAttr "m29__Grp.msg" "lightLinker1.lnk[24].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[25].llnk"; -connectAttr "m3__Grp.msg" "lightLinker1.lnk[25].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[26].llnk"; -connectAttr "m30__Grp.msg" "lightLinker1.lnk[26].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[27].llnk"; -connectAttr "m31__Grp.msg" "lightLinker1.lnk[27].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[28].llnk"; -connectAttr "m32__Grp.msg" "lightLinker1.lnk[28].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[29].llnk"; -connectAttr "m33__Grp.msg" "lightLinker1.lnk[29].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[30].llnk"; -connectAttr "m34__Grp.msg" "lightLinker1.lnk[30].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[31].llnk"; -connectAttr "m35__Grp.msg" "lightLinker1.lnk[31].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[32].llnk"; -connectAttr "m36__Grp.msg" "lightLinker1.lnk[32].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[33].llnk"; -connectAttr "m37__Grp.msg" "lightLinker1.lnk[33].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[34].llnk"; -connectAttr "m38__Grp.msg" "lightLinker1.lnk[34].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[35].llnk"; -connectAttr "m39__Grp.msg" "lightLinker1.lnk[35].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[36].llnk"; -connectAttr "m4__Grp.msg" "lightLinker1.lnk[36].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[37].llnk"; -connectAttr "m40__Grp.msg" "lightLinker1.lnk[37].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[38].llnk"; -connectAttr "m41__Grp.msg" "lightLinker1.lnk[38].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[39].llnk"; -connectAttr "m5__Grp.msg" "lightLinker1.lnk[39].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[40].llnk"; -connectAttr "m6__Grp.msg" "lightLinker1.lnk[40].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[41].llnk"; -connectAttr "m7__Grp.msg" "lightLinker1.lnk[41].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[42].llnk"; -connectAttr "m8__Grp.msg" "lightLinker1.lnk[42].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[43].llnk"; -connectAttr "m9__Grp.msg" "lightLinker1.lnk[43].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "file1.oc" "m1.c"; -connectAttr "m1.oc" "m0__Grp.ss"; -connectAttr "polySurfaceShape1.iog" "m0__Grp.dsm" -na; -connectAttr "m0__Grp.msg" "materialInfo1.sg"; -connectAttr "place2dTexture1.c" "file1.c"; -connectAttr "place2dTexture1.tf" "file1.tf"; -connectAttr "place2dTexture1.rf" "file1.rf"; -connectAttr "place2dTexture1.s" "file1.s"; -connectAttr "place2dTexture1.wu" "file1.wu"; -connectAttr "place2dTexture1.wv" "file1.wv"; -connectAttr "place2dTexture1.re" "file1.re"; -connectAttr "place2dTexture1.of" "file1.of"; -connectAttr "place2dTexture1.r" "file1.ro"; -connectAttr "place2dTexture1.o" "file1.uv"; -connectAttr "place2dTexture1.ofs" "file1.fs"; -connectAttr "file2.oc" "m3.c"; -connectAttr "m3.oc" "m1__Grp.ss"; -connectAttr "polySurfaceShape2.iog" "m1__Grp.dsm" -na; -connectAttr "m1__Grp.msg" "materialInfo2.sg"; -connectAttr "place2dTexture2.c" "file2.c"; -connectAttr "place2dTexture2.tf" "file2.tf"; -connectAttr "place2dTexture2.rf" "file2.rf"; -connectAttr "place2dTexture2.s" "file2.s"; -connectAttr "place2dTexture2.wu" "file2.wu"; -connectAttr "place2dTexture2.wv" "file2.wv"; -connectAttr "place2dTexture2.re" "file2.re"; -connectAttr "place2dTexture2.of" "file2.of"; -connectAttr "place2dTexture2.r" "file2.ro"; -connectAttr "place2dTexture2.o" "file2.uv"; -connectAttr "place2dTexture2.ofs" "file2.fs"; -connectAttr "file3.oc" "m11.c"; -connectAttr "m11.oc" "m10__Grp.ss"; -connectAttr "polySurfaceShape3.iog" "m10__Grp.dsm" -na; -connectAttr "m10__Grp.msg" "materialInfo3.sg"; -connectAttr "place2dTexture3.c" "file3.c"; -connectAttr "place2dTexture3.tf" "file3.tf"; -connectAttr "place2dTexture3.rf" "file3.rf"; -connectAttr "place2dTexture3.s" "file3.s"; -connectAttr "place2dTexture3.wu" "file3.wu"; -connectAttr "place2dTexture3.wv" "file3.wv"; -connectAttr "place2dTexture3.re" "file3.re"; -connectAttr "place2dTexture3.of" "file3.of"; -connectAttr "place2dTexture3.r" "file3.ro"; -connectAttr "place2dTexture3.o" "file3.uv"; -connectAttr "place2dTexture3.ofs" "file3.fs"; -connectAttr "file4.oc" "m13.c"; -connectAttr "m13.oc" "m11__Grp.ss"; -connectAttr "polySurfaceShape4.iog" "m11__Grp.dsm" -na; -connectAttr "m11__Grp.msg" "materialInfo4.sg"; -connectAttr "place2dTexture4.c" "file4.c"; -connectAttr "place2dTexture4.tf" "file4.tf"; -connectAttr "place2dTexture4.rf" "file4.rf"; -connectAttr "place2dTexture4.s" "file4.s"; -connectAttr "place2dTexture4.wu" "file4.wu"; -connectAttr "place2dTexture4.wv" "file4.wv"; -connectAttr "place2dTexture4.re" "file4.re"; -connectAttr "place2dTexture4.of" "file4.of"; -connectAttr "place2dTexture4.r" "file4.ro"; -connectAttr "place2dTexture4.o" "file4.uv"; -connectAttr "place2dTexture4.ofs" "file4.fs"; -connectAttr "file5.oc" "m15.c"; -connectAttr "m15.oc" "m12__Grp.ss"; -connectAttr "polySurfaceShape5.iog" "m12__Grp.dsm" -na; -connectAttr "m12__Grp.msg" "materialInfo5.sg"; -connectAttr "place2dTexture5.c" "file5.c"; -connectAttr "place2dTexture5.tf" "file5.tf"; -connectAttr "place2dTexture5.rf" "file5.rf"; -connectAttr "place2dTexture5.s" "file5.s"; -connectAttr "place2dTexture5.wu" "file5.wu"; -connectAttr "place2dTexture5.wv" "file5.wv"; -connectAttr "place2dTexture5.re" "file5.re"; -connectAttr "place2dTexture5.of" "file5.of"; -connectAttr "place2dTexture5.r" "file5.ro"; -connectAttr "place2dTexture5.o" "file5.uv"; -connectAttr "place2dTexture5.ofs" "file5.fs"; -connectAttr "file6.oc" "m17.c"; -connectAttr "m17.oc" "m13__Grp.ss"; -connectAttr "polySurfaceShape6.iog" "m13__Grp.dsm" -na; -connectAttr "m13__Grp.msg" "materialInfo6.sg"; -connectAttr "place2dTexture6.c" "file6.c"; -connectAttr "place2dTexture6.tf" "file6.tf"; -connectAttr "place2dTexture6.rf" "file6.rf"; -connectAttr "place2dTexture6.s" "file6.s"; -connectAttr "place2dTexture6.wu" "file6.wu"; -connectAttr "place2dTexture6.wv" "file6.wv"; -connectAttr "place2dTexture6.re" "file6.re"; -connectAttr "place2dTexture6.of" "file6.of"; -connectAttr "place2dTexture6.r" "file6.ro"; -connectAttr "place2dTexture6.o" "file6.uv"; -connectAttr "place2dTexture6.ofs" "file6.fs"; -connectAttr "file7.oc" "m19.c"; -connectAttr "m19.oc" "m14__Grp.ss"; -connectAttr "polySurfaceShape7.iog" "m14__Grp.dsm" -na; -connectAttr "m14__Grp.msg" "materialInfo7.sg"; -connectAttr "place2dTexture7.c" "file7.c"; -connectAttr "place2dTexture7.tf" "file7.tf"; -connectAttr "place2dTexture7.rf" "file7.rf"; -connectAttr "place2dTexture7.s" "file7.s"; -connectAttr "place2dTexture7.wu" "file7.wu"; -connectAttr "place2dTexture7.wv" "file7.wv"; -connectAttr "place2dTexture7.re" "file7.re"; -connectAttr "place2dTexture7.of" "file7.of"; -connectAttr "place2dTexture7.r" "file7.ro"; -connectAttr "place2dTexture7.o" "file7.uv"; -connectAttr "place2dTexture7.ofs" "file7.fs"; -connectAttr "file8.oc" "m21.c"; -connectAttr "m21.oc" "m15__Grp.ss"; -connectAttr "polySurfaceShape8.iog" "m15__Grp.dsm" -na; -connectAttr "m15__Grp.msg" "materialInfo8.sg"; -connectAttr "place2dTexture8.c" "file8.c"; -connectAttr "place2dTexture8.tf" "file8.tf"; -connectAttr "place2dTexture8.rf" "file8.rf"; -connectAttr "place2dTexture8.s" "file8.s"; -connectAttr "place2dTexture8.wu" "file8.wu"; -connectAttr "place2dTexture8.wv" "file8.wv"; -connectAttr "place2dTexture8.re" "file8.re"; -connectAttr "place2dTexture8.of" "file8.of"; -connectAttr "place2dTexture8.r" "file8.ro"; -connectAttr "place2dTexture8.o" "file8.uv"; -connectAttr "place2dTexture8.ofs" "file8.fs"; -connectAttr "file9.oc" "m23.c"; -connectAttr "m23.oc" "m16__Grp.ss"; -connectAttr "polySurfaceShape9.iog" "m16__Grp.dsm" -na; -connectAttr "m16__Grp.msg" "materialInfo9.sg"; -connectAttr "place2dTexture9.c" "file9.c"; -connectAttr "place2dTexture9.tf" "file9.tf"; -connectAttr "place2dTexture9.rf" "file9.rf"; -connectAttr "place2dTexture9.s" "file9.s"; -connectAttr "place2dTexture9.wu" "file9.wu"; -connectAttr "place2dTexture9.wv" "file9.wv"; -connectAttr "place2dTexture9.re" "file9.re"; -connectAttr "place2dTexture9.of" "file9.of"; -connectAttr "place2dTexture9.r" "file9.ro"; -connectAttr "place2dTexture9.o" "file9.uv"; -connectAttr "place2dTexture9.ofs" "file9.fs"; -connectAttr "file10.oc" "m25.c"; -connectAttr "m25.oc" "m17__Grp.ss"; -connectAttr "polySurfaceShape10.iog" "m17__Grp.dsm" -na; -connectAttr "m17__Grp.msg" "materialInfo10.sg"; -connectAttr "place2dTexture10.c" "file10.c"; -connectAttr "place2dTexture10.tf" "file10.tf"; -connectAttr "place2dTexture10.rf" "file10.rf"; -connectAttr "place2dTexture10.s" "file10.s"; -connectAttr "place2dTexture10.wu" "file10.wu"; -connectAttr "place2dTexture10.wv" "file10.wv"; -connectAttr "place2dTexture10.re" "file10.re"; -connectAttr "place2dTexture10.of" "file10.of"; -connectAttr "place2dTexture10.r" "file10.ro"; -connectAttr "place2dTexture10.o" "file10.uv"; -connectAttr "place2dTexture10.ofs" "file10.fs"; -connectAttr "file11.oc" "m27.c"; -connectAttr "m27.oc" "m18__Grp.ss"; -connectAttr "polySurfaceShape11.iog" "m18__Grp.dsm" -na; -connectAttr "m18__Grp.msg" "materialInfo11.sg"; -connectAttr "place2dTexture11.c" "file11.c"; -connectAttr "place2dTexture11.tf" "file11.tf"; -connectAttr "place2dTexture11.rf" "file11.rf"; -connectAttr "place2dTexture11.s" "file11.s"; -connectAttr "place2dTexture11.wu" "file11.wu"; -connectAttr "place2dTexture11.wv" "file11.wv"; -connectAttr "place2dTexture11.re" "file11.re"; -connectAttr "place2dTexture11.of" "file11.of"; -connectAttr "place2dTexture11.r" "file11.ro"; -connectAttr "place2dTexture11.o" "file11.uv"; -connectAttr "place2dTexture11.ofs" "file11.fs"; -connectAttr "file12.oc" "m29.c"; -connectAttr "m29.oc" "m19__Grp.ss"; -connectAttr "m19__Grp.msg" "materialInfo12.sg"; -connectAttr "place2dTexture12.c" "file12.c"; -connectAttr "place2dTexture12.tf" "file12.tf"; -connectAttr "place2dTexture12.rf" "file12.rf"; -connectAttr "place2dTexture12.s" "file12.s"; -connectAttr "place2dTexture12.wu" "file12.wu"; -connectAttr "place2dTexture12.wv" "file12.wv"; -connectAttr "place2dTexture12.re" "file12.re"; -connectAttr "place2dTexture12.of" "file12.of"; -connectAttr "place2dTexture12.r" "file12.ro"; -connectAttr "place2dTexture12.o" "file12.uv"; -connectAttr "place2dTexture12.ofs" "file12.fs"; -connectAttr "file13.oc" "m31.c"; -connectAttr "m31.oc" "m2__Grp.ss"; -connectAttr "polySurfaceShape13.iog" "m2__Grp.dsm" -na; -connectAttr "m2__Grp.msg" "materialInfo13.sg"; -connectAttr "place2dTexture13.c" "file13.c"; -connectAttr "place2dTexture13.tf" "file13.tf"; -connectAttr "place2dTexture13.rf" "file13.rf"; -connectAttr "place2dTexture13.s" "file13.s"; -connectAttr "place2dTexture13.wu" "file13.wu"; -connectAttr "place2dTexture13.wv" "file13.wv"; -connectAttr "place2dTexture13.re" "file13.re"; -connectAttr "place2dTexture13.of" "file13.of"; -connectAttr "place2dTexture13.r" "file13.ro"; -connectAttr "place2dTexture13.o" "file13.uv"; -connectAttr "place2dTexture13.ofs" "file13.fs"; -connectAttr "file14.oc" "m33.c"; -connectAttr "m33.oc" "m20__Grp.ss"; -connectAttr "polySurfaceShape14.iog" "m20__Grp.dsm" -na; -connectAttr "m20__Grp.msg" "materialInfo14.sg"; -connectAttr "place2dTexture14.c" "file14.c"; -connectAttr "place2dTexture14.tf" "file14.tf"; -connectAttr "place2dTexture14.rf" "file14.rf"; -connectAttr "place2dTexture14.s" "file14.s"; -connectAttr "place2dTexture14.wu" "file14.wu"; -connectAttr "place2dTexture14.wv" "file14.wv"; -connectAttr "place2dTexture14.re" "file14.re"; -connectAttr "place2dTexture14.of" "file14.of"; -connectAttr "place2dTexture14.r" "file14.ro"; -connectAttr "place2dTexture14.o" "file14.uv"; -connectAttr "place2dTexture14.ofs" "file14.fs"; -connectAttr "file15.oc" "m35.c"; -connectAttr "m35.oc" "m21__Grp.ss"; -connectAttr "polySurfaceShape15.iog" "m21__Grp.dsm" -na; -connectAttr "m21__Grp.msg" "materialInfo15.sg"; -connectAttr "place2dTexture15.c" "file15.c"; -connectAttr "place2dTexture15.tf" "file15.tf"; -connectAttr "place2dTexture15.rf" "file15.rf"; -connectAttr "place2dTexture15.s" "file15.s"; -connectAttr "place2dTexture15.wu" "file15.wu"; -connectAttr "place2dTexture15.wv" "file15.wv"; -connectAttr "place2dTexture15.re" "file15.re"; -connectAttr "place2dTexture15.of" "file15.of"; -connectAttr "place2dTexture15.r" "file15.ro"; -connectAttr "place2dTexture15.o" "file15.uv"; -connectAttr "place2dTexture15.ofs" "file15.fs"; -connectAttr "file16.oc" "m37.c"; -connectAttr "m37.oc" "m22__Grp.ss"; -connectAttr "polySurfaceShape16.iog" "m22__Grp.dsm" -na; -connectAttr "m22__Grp.msg" "materialInfo16.sg"; -connectAttr "place2dTexture16.c" "file16.c"; -connectAttr "place2dTexture16.tf" "file16.tf"; -connectAttr "place2dTexture16.rf" "file16.rf"; -connectAttr "place2dTexture16.s" "file16.s"; -connectAttr "place2dTexture16.wu" "file16.wu"; -connectAttr "place2dTexture16.wv" "file16.wv"; -connectAttr "place2dTexture16.re" "file16.re"; -connectAttr "place2dTexture16.of" "file16.of"; -connectAttr "place2dTexture16.r" "file16.ro"; -connectAttr "place2dTexture16.o" "file16.uv"; -connectAttr "place2dTexture16.ofs" "file16.fs"; -connectAttr "file17.oc" "m39.c"; -connectAttr "m39.oc" "m23__Grp.ss"; -connectAttr "polySurfaceShape17.iog" "m23__Grp.dsm" -na; -connectAttr "m23__Grp.msg" "materialInfo17.sg"; -connectAttr "place2dTexture17.c" "file17.c"; -connectAttr "place2dTexture17.tf" "file17.tf"; -connectAttr "place2dTexture17.rf" "file17.rf"; -connectAttr "place2dTexture17.s" "file17.s"; -connectAttr "place2dTexture17.wu" "file17.wu"; -connectAttr "place2dTexture17.wv" "file17.wv"; -connectAttr "place2dTexture17.re" "file17.re"; -connectAttr "place2dTexture17.of" "file17.of"; -connectAttr "place2dTexture17.r" "file17.ro"; -connectAttr "place2dTexture17.o" "file17.uv"; -connectAttr "place2dTexture17.ofs" "file17.fs"; -connectAttr "file18.oc" "m41.c"; -connectAttr "m41.oc" "m24__Grp.ss"; -connectAttr "polySurfaceShape18.iog" "m24__Grp.dsm" -na; -connectAttr "m24__Grp.msg" "materialInfo18.sg"; -connectAttr "place2dTexture18.c" "file18.c"; -connectAttr "place2dTexture18.tf" "file18.tf"; -connectAttr "place2dTexture18.rf" "file18.rf"; -connectAttr "place2dTexture18.s" "file18.s"; -connectAttr "place2dTexture18.wu" "file18.wu"; -connectAttr "place2dTexture18.wv" "file18.wv"; -connectAttr "place2dTexture18.re" "file18.re"; -connectAttr "place2dTexture18.of" "file18.of"; -connectAttr "place2dTexture18.r" "file18.ro"; -connectAttr "place2dTexture18.o" "file18.uv"; -connectAttr "place2dTexture18.ofs" "file18.fs"; -connectAttr "file19.oc" "m43.c"; -connectAttr "m43.oc" "m25__Grp.ss"; -connectAttr "polySurfaceShape19.iog" "m25__Grp.dsm" -na; -connectAttr "m25__Grp.msg" "materialInfo19.sg"; -connectAttr "place2dTexture19.c" "file19.c"; -connectAttr "place2dTexture19.tf" "file19.tf"; -connectAttr "place2dTexture19.rf" "file19.rf"; -connectAttr "place2dTexture19.s" "file19.s"; -connectAttr "place2dTexture19.wu" "file19.wu"; -connectAttr "place2dTexture19.wv" "file19.wv"; -connectAttr "place2dTexture19.re" "file19.re"; -connectAttr "place2dTexture19.of" "file19.of"; -connectAttr "place2dTexture19.r" "file19.ro"; -connectAttr "place2dTexture19.o" "file19.uv"; -connectAttr "place2dTexture19.ofs" "file19.fs"; -connectAttr "file20.oc" "m45.c"; -connectAttr "m45.oc" "m26__Grp.ss"; -connectAttr "polySurfaceShape20.iog" "m26__Grp.dsm" -na; -connectAttr "m26__Grp.msg" "materialInfo20.sg"; -connectAttr "place2dTexture20.c" "file20.c"; -connectAttr "place2dTexture20.tf" "file20.tf"; -connectAttr "place2dTexture20.rf" "file20.rf"; -connectAttr "place2dTexture20.s" "file20.s"; -connectAttr "place2dTexture20.wu" "file20.wu"; -connectAttr "place2dTexture20.wv" "file20.wv"; -connectAttr "place2dTexture20.re" "file20.re"; -connectAttr "place2dTexture20.of" "file20.of"; -connectAttr "place2dTexture20.r" "file20.ro"; -connectAttr "place2dTexture20.o" "file20.uv"; -connectAttr "place2dTexture20.ofs" "file20.fs"; -connectAttr "file21.oc" "m47.c"; -connectAttr "m47.oc" "m27__Grp.ss"; -connectAttr "polySurfaceShape21.iog" "m27__Grp.dsm" -na; -connectAttr "m27__Grp.msg" "materialInfo21.sg"; -connectAttr "place2dTexture21.c" "file21.c"; -connectAttr "place2dTexture21.tf" "file21.tf"; -connectAttr "place2dTexture21.rf" "file21.rf"; -connectAttr "place2dTexture21.s" "file21.s"; -connectAttr "place2dTexture21.wu" "file21.wu"; -connectAttr "place2dTexture21.wv" "file21.wv"; -connectAttr "place2dTexture21.re" "file21.re"; -connectAttr "place2dTexture21.of" "file21.of"; -connectAttr "place2dTexture21.r" "file21.ro"; -connectAttr "place2dTexture21.o" "file21.uv"; -connectAttr "place2dTexture21.ofs" "file21.fs"; -connectAttr "file22.oc" "m49.c"; -connectAttr "m49.oc" "m28__Grp.ss"; -connectAttr "polySurfaceShape22.iog" "m28__Grp.dsm" -na; -connectAttr "m28__Grp.msg" "materialInfo22.sg"; -connectAttr "place2dTexture22.c" "file22.c"; -connectAttr "place2dTexture22.tf" "file22.tf"; -connectAttr "place2dTexture22.rf" "file22.rf"; -connectAttr "place2dTexture22.s" "file22.s"; -connectAttr "place2dTexture22.wu" "file22.wu"; -connectAttr "place2dTexture22.wv" "file22.wv"; -connectAttr "place2dTexture22.re" "file22.re"; -connectAttr "place2dTexture22.of" "file22.of"; -connectAttr "place2dTexture22.r" "file22.ro"; -connectAttr "place2dTexture22.o" "file22.uv"; -connectAttr "place2dTexture22.ofs" "file22.fs"; -connectAttr "file23.oc" "m51.c"; -connectAttr "m51.oc" "m29__Grp.ss"; -connectAttr "polySurfaceShape23.iog" "m29__Grp.dsm" -na; -connectAttr "m29__Grp.msg" "materialInfo23.sg"; -connectAttr "place2dTexture23.c" "file23.c"; -connectAttr "place2dTexture23.tf" "file23.tf"; -connectAttr "place2dTexture23.rf" "file23.rf"; -connectAttr "place2dTexture23.s" "file23.s"; -connectAttr "place2dTexture23.wu" "file23.wu"; -connectAttr "place2dTexture23.wv" "file23.wv"; -connectAttr "place2dTexture23.re" "file23.re"; -connectAttr "place2dTexture23.of" "file23.of"; -connectAttr "place2dTexture23.r" "file23.ro"; -connectAttr "place2dTexture23.o" "file23.uv"; -connectAttr "place2dTexture23.ofs" "file23.fs"; -connectAttr "file24.oc" "m53.c"; -connectAttr "m53.oc" "m3__Grp.ss"; -connectAttr "polySurfaceShape24.iog" "m3__Grp.dsm" -na; -connectAttr "m3__Grp.msg" "materialInfo24.sg"; -connectAttr "place2dTexture24.c" "file24.c"; -connectAttr "place2dTexture24.tf" "file24.tf"; -connectAttr "place2dTexture24.rf" "file24.rf"; -connectAttr "place2dTexture24.s" "file24.s"; -connectAttr "place2dTexture24.wu" "file24.wu"; -connectAttr "place2dTexture24.wv" "file24.wv"; -connectAttr "place2dTexture24.re" "file24.re"; -connectAttr "place2dTexture24.of" "file24.of"; -connectAttr "place2dTexture24.r" "file24.ro"; -connectAttr "place2dTexture24.o" "file24.uv"; -connectAttr "place2dTexture24.ofs" "file24.fs"; -connectAttr "file25.oc" "m55.c"; -connectAttr "m55.oc" "m30__Grp.ss"; -connectAttr "polySurfaceShape25.iog" "m30__Grp.dsm" -na; -connectAttr "m30__Grp.msg" "materialInfo25.sg"; -connectAttr "place2dTexture25.c" "file25.c"; -connectAttr "place2dTexture25.tf" "file25.tf"; -connectAttr "place2dTexture25.rf" "file25.rf"; -connectAttr "place2dTexture25.s" "file25.s"; -connectAttr "place2dTexture25.wu" "file25.wu"; -connectAttr "place2dTexture25.wv" "file25.wv"; -connectAttr "place2dTexture25.re" "file25.re"; -connectAttr "place2dTexture25.of" "file25.of"; -connectAttr "place2dTexture25.r" "file25.ro"; -connectAttr "place2dTexture25.o" "file25.uv"; -connectAttr "place2dTexture25.ofs" "file25.fs"; -connectAttr "file26.oc" "m57.c"; -connectAttr "m57.oc" "m31__Grp.ss"; -connectAttr "polySurfaceShape26.iog" "m31__Grp.dsm" -na; -connectAttr "m31__Grp.msg" "materialInfo26.sg"; -connectAttr "place2dTexture26.c" "file26.c"; -connectAttr "place2dTexture26.tf" "file26.tf"; -connectAttr "place2dTexture26.rf" "file26.rf"; -connectAttr "place2dTexture26.s" "file26.s"; -connectAttr "place2dTexture26.wu" "file26.wu"; -connectAttr "place2dTexture26.wv" "file26.wv"; -connectAttr "place2dTexture26.re" "file26.re"; -connectAttr "place2dTexture26.of" "file26.of"; -connectAttr "place2dTexture26.r" "file26.ro"; -connectAttr "place2dTexture26.o" "file26.uv"; -connectAttr "place2dTexture26.ofs" "file26.fs"; -connectAttr "file27.oc" "m59.c"; -connectAttr "m59.oc" "m32__Grp.ss"; -connectAttr "polySurfaceShape27.iog" "m32__Grp.dsm" -na; -connectAttr "m32__Grp.msg" "materialInfo27.sg"; -connectAttr "place2dTexture27.c" "file27.c"; -connectAttr "place2dTexture27.tf" "file27.tf"; -connectAttr "place2dTexture27.rf" "file27.rf"; -connectAttr "place2dTexture27.s" "file27.s"; -connectAttr "place2dTexture27.wu" "file27.wu"; -connectAttr "place2dTexture27.wv" "file27.wv"; -connectAttr "place2dTexture27.re" "file27.re"; -connectAttr "place2dTexture27.of" "file27.of"; -connectAttr "place2dTexture27.r" "file27.ro"; -connectAttr "place2dTexture27.o" "file27.uv"; -connectAttr "place2dTexture27.ofs" "file27.fs"; -connectAttr "file28.oc" "m61.c"; -connectAttr "m61.oc" "m33__Grp.ss"; -connectAttr "polySurfaceShape28.iog" "m33__Grp.dsm" -na; -connectAttr "m33__Grp.msg" "materialInfo28.sg"; -connectAttr "place2dTexture28.c" "file28.c"; -connectAttr "place2dTexture28.tf" "file28.tf"; -connectAttr "place2dTexture28.rf" "file28.rf"; -connectAttr "place2dTexture28.s" "file28.s"; -connectAttr "place2dTexture28.wu" "file28.wu"; -connectAttr "place2dTexture28.wv" "file28.wv"; -connectAttr "place2dTexture28.re" "file28.re"; -connectAttr "place2dTexture28.of" "file28.of"; -connectAttr "place2dTexture28.r" "file28.ro"; -connectAttr "place2dTexture28.o" "file28.uv"; -connectAttr "place2dTexture28.ofs" "file28.fs"; -connectAttr "file29.oc" "m63.c"; -connectAttr "m63.oc" "m34__Grp.ss"; -connectAttr "polySurfaceShape29.iog" "m34__Grp.dsm" -na; -connectAttr "m34__Grp.msg" "materialInfo29.sg"; -connectAttr "place2dTexture29.c" "file29.c"; -connectAttr "place2dTexture29.tf" "file29.tf"; -connectAttr "place2dTexture29.rf" "file29.rf"; -connectAttr "place2dTexture29.s" "file29.s"; -connectAttr "place2dTexture29.wu" "file29.wu"; -connectAttr "place2dTexture29.wv" "file29.wv"; -connectAttr "place2dTexture29.re" "file29.re"; -connectAttr "place2dTexture29.of" "file29.of"; -connectAttr "place2dTexture29.r" "file29.ro"; -connectAttr "place2dTexture29.o" "file29.uv"; -connectAttr "place2dTexture29.ofs" "file29.fs"; -connectAttr "file30.oc" "m65.c"; -connectAttr "m65.oc" "m35__Grp.ss"; -connectAttr "polySurfaceShape30.iog" "m35__Grp.dsm" -na; -connectAttr "m35__Grp.msg" "materialInfo30.sg"; -connectAttr "place2dTexture30.c" "file30.c"; -connectAttr "place2dTexture30.tf" "file30.tf"; -connectAttr "place2dTexture30.rf" "file30.rf"; -connectAttr "place2dTexture30.s" "file30.s"; -connectAttr "place2dTexture30.wu" "file30.wu"; -connectAttr "place2dTexture30.wv" "file30.wv"; -connectAttr "place2dTexture30.re" "file30.re"; -connectAttr "place2dTexture30.of" "file30.of"; -connectAttr "place2dTexture30.r" "file30.ro"; -connectAttr "place2dTexture30.o" "file30.uv"; -connectAttr "place2dTexture30.ofs" "file30.fs"; -connectAttr "file31.oc" "m67.c"; -connectAttr "m67.oc" "m36__Grp.ss"; -connectAttr "polySurfaceShape31.iog" "m36__Grp.dsm" -na; -connectAttr "m36__Grp.msg" "materialInfo31.sg"; -connectAttr "place2dTexture31.c" "file31.c"; -connectAttr "place2dTexture31.tf" "file31.tf"; -connectAttr "place2dTexture31.rf" "file31.rf"; -connectAttr "place2dTexture31.s" "file31.s"; -connectAttr "place2dTexture31.wu" "file31.wu"; -connectAttr "place2dTexture31.wv" "file31.wv"; -connectAttr "place2dTexture31.re" "file31.re"; -connectAttr "place2dTexture31.of" "file31.of"; -connectAttr "place2dTexture31.r" "file31.ro"; -connectAttr "place2dTexture31.o" "file31.uv"; -connectAttr "place2dTexture31.ofs" "file31.fs"; -connectAttr "file32.oc" "m69.c"; -connectAttr "m69.oc" "m37__Grp.ss"; -connectAttr "polySurfaceShape32.iog" "m37__Grp.dsm" -na; -connectAttr "m37__Grp.msg" "materialInfo32.sg"; -connectAttr "place2dTexture32.c" "file32.c"; -connectAttr "place2dTexture32.tf" "file32.tf"; -connectAttr "place2dTexture32.rf" "file32.rf"; -connectAttr "place2dTexture32.s" "file32.s"; -connectAttr "place2dTexture32.wu" "file32.wu"; -connectAttr "place2dTexture32.wv" "file32.wv"; -connectAttr "place2dTexture32.re" "file32.re"; -connectAttr "place2dTexture32.of" "file32.of"; -connectAttr "place2dTexture32.r" "file32.ro"; -connectAttr "place2dTexture32.o" "file32.uv"; -connectAttr "place2dTexture32.ofs" "file32.fs"; -connectAttr "file33.oc" "m71.c"; -connectAttr "m71.oc" "m38__Grp.ss"; -connectAttr "polySurfaceShape33.iog" "m38__Grp.dsm" -na; -connectAttr "m38__Grp.msg" "materialInfo33.sg"; -connectAttr "place2dTexture33.c" "file33.c"; -connectAttr "place2dTexture33.tf" "file33.tf"; -connectAttr "place2dTexture33.rf" "file33.rf"; -connectAttr "place2dTexture33.s" "file33.s"; -connectAttr "place2dTexture33.wu" "file33.wu"; -connectAttr "place2dTexture33.wv" "file33.wv"; -connectAttr "place2dTexture33.re" "file33.re"; -connectAttr "place2dTexture33.of" "file33.of"; -connectAttr "place2dTexture33.r" "file33.ro"; -connectAttr "place2dTexture33.o" "file33.uv"; -connectAttr "place2dTexture33.ofs" "file33.fs"; -connectAttr "file34.oc" "m73.c"; -connectAttr "m73.oc" "m39__Grp.ss"; -connectAttr "polySurfaceShape34.iog" "m39__Grp.dsm" -na; -connectAttr "m39__Grp.msg" "materialInfo34.sg"; -connectAttr "place2dTexture34.c" "file34.c"; -connectAttr "place2dTexture34.tf" "file34.tf"; -connectAttr "place2dTexture34.rf" "file34.rf"; -connectAttr "place2dTexture34.s" "file34.s"; -connectAttr "place2dTexture34.wu" "file34.wu"; -connectAttr "place2dTexture34.wv" "file34.wv"; -connectAttr "place2dTexture34.re" "file34.re"; -connectAttr "place2dTexture34.of" "file34.of"; -connectAttr "place2dTexture34.r" "file34.ro"; -connectAttr "place2dTexture34.o" "file34.uv"; -connectAttr "place2dTexture34.ofs" "file34.fs"; -connectAttr "file35.oc" "m74.c"; -connectAttr "m74.oc" "m4__Grp.ss"; -connectAttr "polySurfaceShape35.iog" "m4__Grp.dsm" -na; -connectAttr "m4__Grp.msg" "materialInfo35.sg"; -connectAttr "place2dTexture35.c" "file35.c"; -connectAttr "place2dTexture35.tf" "file35.tf"; -connectAttr "place2dTexture35.rf" "file35.rf"; -connectAttr "place2dTexture35.s" "file35.s"; -connectAttr "place2dTexture35.wu" "file35.wu"; -connectAttr "place2dTexture35.wv" "file35.wv"; -connectAttr "place2dTexture35.re" "file35.re"; -connectAttr "place2dTexture35.of" "file35.of"; -connectAttr "place2dTexture35.r" "file35.ro"; -connectAttr "place2dTexture35.o" "file35.uv"; -connectAttr "place2dTexture35.ofs" "file35.fs"; -connectAttr "file36.oc" "m76.c"; -connectAttr "m76.oc" "m40__Grp.ss"; -connectAttr "polySurfaceShape36.iog" "m40__Grp.dsm" -na; -connectAttr "m40__Grp.msg" "materialInfo36.sg"; -connectAttr "place2dTexture36.c" "file36.c"; -connectAttr "place2dTexture36.tf" "file36.tf"; -connectAttr "place2dTexture36.rf" "file36.rf"; -connectAttr "place2dTexture36.s" "file36.s"; -connectAttr "place2dTexture36.wu" "file36.wu"; -connectAttr "place2dTexture36.wv" "file36.wv"; -connectAttr "place2dTexture36.re" "file36.re"; -connectAttr "place2dTexture36.of" "file36.of"; -connectAttr "place2dTexture36.r" "file36.ro"; -connectAttr "place2dTexture36.o" "file36.uv"; -connectAttr "place2dTexture36.ofs" "file36.fs"; -connectAttr "file37.oc" "m78.c"; -connectAttr "m78.oc" "m41__Grp.ss"; -connectAttr "polySurfaceShape37.iog" "m41__Grp.dsm" -na; -connectAttr "m41__Grp.msg" "materialInfo37.sg"; -connectAttr "place2dTexture37.c" "file37.c"; -connectAttr "place2dTexture37.tf" "file37.tf"; -connectAttr "place2dTexture37.rf" "file37.rf"; -connectAttr "place2dTexture37.s" "file37.s"; -connectAttr "place2dTexture37.wu" "file37.wu"; -connectAttr "place2dTexture37.wv" "file37.wv"; -connectAttr "place2dTexture37.re" "file37.re"; -connectAttr "place2dTexture37.of" "file37.of"; -connectAttr "place2dTexture37.r" "file37.ro"; -connectAttr "place2dTexture37.o" "file37.uv"; -connectAttr "place2dTexture37.ofs" "file37.fs"; -connectAttr "file38.oc" "m79.c"; -connectAttr "m79.oc" "m5__Grp.ss"; -connectAttr "polySurfaceShape38.iog" "m5__Grp.dsm" -na; -connectAttr "m5__Grp.msg" "materialInfo38.sg"; -connectAttr "place2dTexture38.c" "file38.c"; -connectAttr "place2dTexture38.tf" "file38.tf"; -connectAttr "place2dTexture38.rf" "file38.rf"; -connectAttr "place2dTexture38.s" "file38.s"; -connectAttr "place2dTexture38.wu" "file38.wu"; -connectAttr "place2dTexture38.wv" "file38.wv"; -connectAttr "place2dTexture38.re" "file38.re"; -connectAttr "place2dTexture38.of" "file38.of"; -connectAttr "place2dTexture38.r" "file38.ro"; -connectAttr "place2dTexture38.o" "file38.uv"; -connectAttr "place2dTexture38.ofs" "file38.fs"; -connectAttr "file39.oc" "m80.c"; -connectAttr "m80.oc" "m6__Grp.ss"; -connectAttr "polySurfaceShape39.iog" "m6__Grp.dsm" -na; -connectAttr "m6__Grp.msg" "materialInfo39.sg"; -connectAttr "place2dTexture39.c" "file39.c"; -connectAttr "place2dTexture39.tf" "file39.tf"; -connectAttr "place2dTexture39.rf" "file39.rf"; -connectAttr "place2dTexture39.s" "file39.s"; -connectAttr "place2dTexture39.wu" "file39.wu"; -connectAttr "place2dTexture39.wv" "file39.wv"; -connectAttr "place2dTexture39.re" "file39.re"; -connectAttr "place2dTexture39.of" "file39.of"; -connectAttr "place2dTexture39.r" "file39.ro"; -connectAttr "place2dTexture39.o" "file39.uv"; -connectAttr "place2dTexture39.ofs" "file39.fs"; -connectAttr "file40.oc" "m81.c"; -connectAttr "m81.oc" "m7__Grp.ss"; -connectAttr "polySurfaceShape40.iog" "m7__Grp.dsm" -na; -connectAttr "m7__Grp.msg" "materialInfo40.sg"; -connectAttr "place2dTexture40.c" "file40.c"; -connectAttr "place2dTexture40.tf" "file40.tf"; -connectAttr "place2dTexture40.rf" "file40.rf"; -connectAttr "place2dTexture40.s" "file40.s"; -connectAttr "place2dTexture40.wu" "file40.wu"; -connectAttr "place2dTexture40.wv" "file40.wv"; -connectAttr "place2dTexture40.re" "file40.re"; -connectAttr "place2dTexture40.of" "file40.of"; -connectAttr "place2dTexture40.r" "file40.ro"; -connectAttr "place2dTexture40.o" "file40.uv"; -connectAttr "place2dTexture40.ofs" "file40.fs"; -connectAttr "file41.oc" "m82.c"; -connectAttr "m82.oc" "m8__Grp.ss"; -connectAttr "polySurfaceShape41.iog" "m8__Grp.dsm" -na; -connectAttr "m8__Grp.msg" "materialInfo41.sg"; -connectAttr "place2dTexture41.c" "file41.c"; -connectAttr "place2dTexture41.tf" "file41.tf"; -connectAttr "place2dTexture41.rf" "file41.rf"; -connectAttr "place2dTexture41.s" "file41.s"; -connectAttr "place2dTexture41.wu" "file41.wu"; -connectAttr "place2dTexture41.wv" "file41.wv"; -connectAttr "place2dTexture41.re" "file41.re"; -connectAttr "place2dTexture41.of" "file41.of"; -connectAttr "place2dTexture41.r" "file41.ro"; -connectAttr "place2dTexture41.o" "file41.uv"; -connectAttr "place2dTexture41.ofs" "file41.fs"; -connectAttr "file42.oc" "m83.c"; -connectAttr "m83.oc" "m9__Grp.ss"; -connectAttr "polySurfaceShape42.iog" "m9__Grp.dsm" -na; -connectAttr "m9__Grp.msg" "materialInfo42.sg"; -connectAttr "place2dTexture42.c" "file42.c"; -connectAttr "place2dTexture42.tf" "file42.tf"; -connectAttr "place2dTexture42.rf" "file42.rf"; -connectAttr "place2dTexture42.s" "file42.s"; -connectAttr "place2dTexture42.wu" "file42.wu"; -connectAttr "place2dTexture42.wv" "file42.wv"; -connectAttr "place2dTexture42.re" "file42.re"; -connectAttr "place2dTexture42.of" "file42.of"; -connectAttr "place2dTexture42.r" "file42.ro"; -connectAttr "place2dTexture42.o" "file42.uv"; -connectAttr "place2dTexture42.ofs" "file42.fs"; -connectAttr "m0__Grp.pa" ":renderPartition.st" -na; -connectAttr "m1__Grp.pa" ":renderPartition.st" -na; -connectAttr "m10__Grp.pa" ":renderPartition.st" -na; -connectAttr "m11__Grp.pa" ":renderPartition.st" -na; -connectAttr "m12__Grp.pa" ":renderPartition.st" -na; -connectAttr "m13__Grp.pa" ":renderPartition.st" -na; -connectAttr "m14__Grp.pa" ":renderPartition.st" -na; -connectAttr "m15__Grp.pa" ":renderPartition.st" -na; -connectAttr "m16__Grp.pa" ":renderPartition.st" -na; -connectAttr "m17__Grp.pa" ":renderPartition.st" -na; -connectAttr "m18__Grp.pa" ":renderPartition.st" -na; -connectAttr "m19__Grp.pa" ":renderPartition.st" -na; -connectAttr "m2__Grp.pa" ":renderPartition.st" -na; -connectAttr "m20__Grp.pa" ":renderPartition.st" -na; -connectAttr "m21__Grp.pa" ":renderPartition.st" -na; -connectAttr "m22__Grp.pa" ":renderPartition.st" -na; -connectAttr "m23__Grp.pa" ":renderPartition.st" -na; -connectAttr "m24__Grp.pa" ":renderPartition.st" -na; -connectAttr "m25__Grp.pa" ":renderPartition.st" -na; -connectAttr "m26__Grp.pa" ":renderPartition.st" -na; -connectAttr "m27__Grp.pa" ":renderPartition.st" -na; -connectAttr "m28__Grp.pa" ":renderPartition.st" -na; -connectAttr "m29__Grp.pa" ":renderPartition.st" -na; -connectAttr "m3__Grp.pa" ":renderPartition.st" -na; -connectAttr "m30__Grp.pa" ":renderPartition.st" -na; -connectAttr "m31__Grp.pa" ":renderPartition.st" -na; -connectAttr "m32__Grp.pa" ":renderPartition.st" -na; -connectAttr "m33__Grp.pa" ":renderPartition.st" -na; -connectAttr "m34__Grp.pa" ":renderPartition.st" -na; -connectAttr "m35__Grp.pa" ":renderPartition.st" -na; -connectAttr "m36__Grp.pa" ":renderPartition.st" -na; -connectAttr "m37__Grp.pa" ":renderPartition.st" -na; -connectAttr "m38__Grp.pa" ":renderPartition.st" -na; -connectAttr "m39__Grp.pa" ":renderPartition.st" -na; -connectAttr "m4__Grp.pa" ":renderPartition.st" -na; -connectAttr "m40__Grp.pa" ":renderPartition.st" -na; -connectAttr "m41__Grp.pa" ":renderPartition.st" -na; -connectAttr "m5__Grp.pa" ":renderPartition.st" -na; -connectAttr "m6__Grp.pa" ":renderPartition.st" -na; -connectAttr "m7__Grp.pa" ":renderPartition.st" -na; -connectAttr "m8__Grp.pa" ":renderPartition.st" -na; -connectAttr "m9__Grp.pa" ":renderPartition.st" -na; -connectAttr "m1.msg" ":defaultShaderList1.s" -na; -connectAttr "m3.msg" ":defaultShaderList1.s" -na; -connectAttr "m11.msg" ":defaultShaderList1.s" -na; -connectAttr "m13.msg" ":defaultShaderList1.s" -na; -connectAttr "m15.msg" ":defaultShaderList1.s" -na; -connectAttr "m17.msg" ":defaultShaderList1.s" -na; -connectAttr "m19.msg" ":defaultShaderList1.s" -na; -connectAttr "m21.msg" ":defaultShaderList1.s" -na; -connectAttr "m23.msg" ":defaultShaderList1.s" -na; -connectAttr "m25.msg" ":defaultShaderList1.s" -na; -connectAttr "m27.msg" ":defaultShaderList1.s" -na; -connectAttr "m29.msg" ":defaultShaderList1.s" -na; -connectAttr "m31.msg" ":defaultShaderList1.s" -na; -connectAttr "m33.msg" ":defaultShaderList1.s" -na; -connectAttr "m35.msg" ":defaultShaderList1.s" -na; -connectAttr "m37.msg" ":defaultShaderList1.s" -na; -connectAttr "m39.msg" ":defaultShaderList1.s" -na; -connectAttr "m41.msg" ":defaultShaderList1.s" -na; -connectAttr "m43.msg" ":defaultShaderList1.s" -na; -connectAttr "m45.msg" ":defaultShaderList1.s" -na; -connectAttr "m47.msg" ":defaultShaderList1.s" -na; -connectAttr "m49.msg" ":defaultShaderList1.s" -na; -connectAttr "m51.msg" ":defaultShaderList1.s" -na; -connectAttr "m53.msg" ":defaultShaderList1.s" -na; -connectAttr "m55.msg" ":defaultShaderList1.s" -na; -connectAttr "m57.msg" ":defaultShaderList1.s" -na; -connectAttr "m59.msg" ":defaultShaderList1.s" -na; -connectAttr "m61.msg" ":defaultShaderList1.s" -na; -connectAttr "m63.msg" ":defaultShaderList1.s" -na; -connectAttr "m65.msg" ":defaultShaderList1.s" -na; -connectAttr "m67.msg" ":defaultShaderList1.s" -na; -connectAttr "m69.msg" ":defaultShaderList1.s" -na; -connectAttr "m71.msg" ":defaultShaderList1.s" -na; -connectAttr "m73.msg" ":defaultShaderList1.s" -na; -connectAttr "m74.msg" ":defaultShaderList1.s" -na; -connectAttr "m76.msg" ":defaultShaderList1.s" -na; -connectAttr "m78.msg" ":defaultShaderList1.s" -na; -connectAttr "m79.msg" ":defaultShaderList1.s" -na; -connectAttr "m80.msg" ":defaultShaderList1.s" -na; -connectAttr "m81.msg" ":defaultShaderList1.s" -na; -connectAttr "m82.msg" ":defaultShaderList1.s" -na; -connectAttr "m83.msg" ":defaultShaderList1.s" -na; -connectAttr "place2dTexture1.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture2.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture3.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture4.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture5.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture6.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture7.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture8.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture9.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture10.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture11.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture12.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture13.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture14.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture15.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture16.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture17.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture18.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture19.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture20.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture21.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture22.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture23.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture24.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture25.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture26.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture27.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture28.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture29.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture30.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture31.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture32.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture33.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture34.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture35.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture36.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture37.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture38.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture39.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture40.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture41.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "place2dTexture42.msg" ":defaultRenderUtilityList1.u" -na; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "file1.msg" ":defaultTextureList1.tx" -na; -connectAttr "file2.msg" ":defaultTextureList1.tx" -na; -connectAttr "file3.msg" ":defaultTextureList1.tx" -na; -connectAttr "file4.msg" ":defaultTextureList1.tx" -na; -connectAttr "file5.msg" ":defaultTextureList1.tx" -na; -connectAttr "file6.msg" ":defaultTextureList1.tx" -na; -connectAttr "file7.msg" ":defaultTextureList1.tx" -na; -connectAttr "file8.msg" ":defaultTextureList1.tx" -na; -connectAttr "file9.msg" ":defaultTextureList1.tx" -na; -connectAttr "file10.msg" ":defaultTextureList1.tx" -na; -connectAttr "file11.msg" ":defaultTextureList1.tx" -na; -connectAttr "file12.msg" ":defaultTextureList1.tx" -na; -connectAttr "file13.msg" ":defaultTextureList1.tx" -na; -connectAttr "file14.msg" ":defaultTextureList1.tx" -na; -connectAttr "file15.msg" ":defaultTextureList1.tx" -na; -connectAttr "file16.msg" ":defaultTextureList1.tx" -na; -connectAttr "file17.msg" ":defaultTextureList1.tx" -na; -connectAttr "file18.msg" ":defaultTextureList1.tx" -na; -connectAttr "file19.msg" ":defaultTextureList1.tx" -na; -connectAttr "file20.msg" ":defaultTextureList1.tx" -na; -connectAttr "file21.msg" ":defaultTextureList1.tx" -na; -connectAttr "file22.msg" ":defaultTextureList1.tx" -na; -connectAttr "file23.msg" ":defaultTextureList1.tx" -na; -connectAttr "file24.msg" ":defaultTextureList1.tx" -na; -connectAttr "file25.msg" ":defaultTextureList1.tx" -na; -connectAttr "file26.msg" ":defaultTextureList1.tx" -na; -connectAttr "file27.msg" ":defaultTextureList1.tx" -na; -connectAttr "file28.msg" ":defaultTextureList1.tx" -na; -connectAttr "file29.msg" ":defaultTextureList1.tx" -na; -connectAttr "file30.msg" ":defaultTextureList1.tx" -na; -connectAttr "file31.msg" ":defaultTextureList1.tx" -na; -connectAttr "file32.msg" ":defaultTextureList1.tx" -na; -connectAttr "file33.msg" ":defaultTextureList1.tx" -na; -connectAttr "file34.msg" ":defaultTextureList1.tx" -na; -connectAttr "file35.msg" ":defaultTextureList1.tx" -na; -connectAttr "file36.msg" ":defaultTextureList1.tx" -na; -connectAttr "file37.msg" ":defaultTextureList1.tx" -na; -connectAttr "file38.msg" ":defaultTextureList1.tx" -na; -connectAttr "file39.msg" ":defaultTextureList1.tx" -na; -connectAttr "file40.msg" ":defaultTextureList1.tx" -na; -connectAttr "file41.msg" ":defaultTextureList1.tx" -na; -connectAttr "file42.msg" ":defaultTextureList1.tx" -na; -// End of hangonceiling.ma diff --git a/base/models/monsters/imp/animation/cycles/idle1.ma b/base/models/monsters/imp/animation/cycles/idle1.ma deleted file mode 100644 index 8bd7d9a32..000000000 --- a/base/models/monsters/imp/animation/cycles/idle1.ma +++ /dev/null @@ -1,3899 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: idle1.ma -//Last modified: Mon, Mar 15, 2004 09:03:52 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 5.8711063441747324 98.768851845814268 140.49110704030613 ; - setAttr ".r" -type "double3" -24.330108913997901 -1078.1999999997452 -9.9441402124844403e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 170.48929411001259; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 3.9531652941561504 56.318156118230391 -4.763884112293848 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.844702467344078; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 5.1059932995061814 44.280459012095776 104.70346136378367 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 151.20059350228843; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 114.81837383334553 25.972268477568978 -7.8712905798098438 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 73.72154669888242; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 23 1 40 1 49 1 80 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 5 5 5 5 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.980821395062172 13 1.980821395062172 - 23 1.980821395062172 40 1.980821395062172 49 1.980821395062172 80 1.980821395062172; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 41.235789592866901 13 41.496141335445174 - 23 41.496141335445174 40 41.235789592866901 49 41.235789592866901 80 41.235789592866901; - setAttr -s 6 ".kit[1:5]" 9 9 3 3 3; - setAttr -s 6 ".kot[1:5]" 9 9 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.4191866633612995 13 -3.0885816009192122 - 23 -3.0885816009192122 40 -2.4191866633612995 49 -2.4191866633612995 80 -2.4191866633612995; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 13 0 23 0 40 0 49 0 80 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 13 0 23 0 40 0 49 0 80 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 3.0904095398860574 13 3.0904095398860574 - 23 3.0904095398860574 40 3.0904095398860574 49 3.0904095398860574 80 3.0904095398860574; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 23 1 40 1 49 1 80 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 23 1 40 1 49 1 80 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 23 1 40 1 49 1 80 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 3; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 378.60212429646663 10 380.4969630522524 - 31 375.68266902829299 50 380.4969630522524 68 375.68266902829299 80 378.60212429646663; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 46 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.8522027930141798 17 5.6263356976128209 - 46 4.8522027930141798 80 4.8522027930141798; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.1192573708759381 17 2.1968799275302229 - 46 2.1192573708759381 80 2.1192573708759381; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.0821078932592165 17 -3.0171620595005368 - 46 -3.0821078932592165 80 -3.0821078932592165; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -17.481282422130235 17 -17.481282422130235 - 46 -17.481282422130235 80 -17.481282422130235; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 30.702824881409519 17 30.702824881409519 - 46 30.702824881409519 80 30.702824881409519; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -30.797032566082748 17 -30.797032566082748 - 46 -30.797032566082748 80 -30.797032566082748; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 46 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 46 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 46 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 16 1 43 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -5.0348979650608028 16 -6.1662787952208804 - 43 -5.0348979650608028 80 -5.0348979650608028; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.1192000000002627 16 2.0633398577805862 - 43 2.1192000000002627 80 2.1192000000002627; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.0821100000000254 16 -3.1088246861360456 - 43 -3.0821100000000254 80 -3.0821100000000254; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 16 1 43 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 16 1 43 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 16 1 43 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 1 1 1 80 1 159 1; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 0 1 0 80 0 159 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 2.6456615572060826 1 2.6456615572060826 - 80 2.6456615572060826 159 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 1.9935618776130362 1 1.9935618776130362 - 80 1.9935618776130362 159 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" -78 -9.2446596468972171 -27 -5.3045001525067814 - -12 -5.3045001525067814 1 -9.2446596468972171 52 -5.3045001525067814 67 -5.3045001525067814 - 80 -9.2446596468972171 131 -5.3045001525067814 146 -5.3045001525067814 159 - -9.2446596468972171; - setAttr -s 10 ".kit[0:9]" 3 9 9 3 9 9 3 - 9 9 3; - setAttr -s 10 ".kot[0:9]" 3 9 9 3 9 9 3 - 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" -78 10.991937960107386 -75 17.126690608674242 - -54 18.015092919464646 -35 -28.26880744722245 -12 -28.26880744722245 1 10.991937480873231 - 4 17.126690608674242 25 18.015092919464646 44 -28.26880744722245 67 -28.26880744722245 - 80 10.991937480873219 83 17.126690608674242 104 18.015092919464646 123 -28.26880744722245 - 146 -28.26880744722245 159 10.991937960107391; - setAttr -s 16 ".kit[0:15]" 3 1 9 9 1 1 1 - 9 9 1 1 1 9 9 1 3; - setAttr -s 16 ".kot[0:15]" 3 1 9 9 1 1 1 - 9 9 1 1 1 9 9 1 3; - setAttr -s 16 ".kix[1:15]" 0.88576847314834595 0.9031442403793335 - 0.90793687105178833 0.89885169267654419 0.54166662693023682 0.88576847314834595 - 0.9031442403793335 0.90793687105178833 0.89885169267654419 0.54166686534881592 - 0.88576793670654297 0.9031442403793335 0.90793687105178833 0.89885169267654419 - 1; - setAttr -s 16 ".kiy[1:15]" 0.46412739157676697 -0.42933720350265503 - -0.41910701990127563 0.43825292587280273 0.6181299090385437 0.46412739157676697 - -0.42933720350265503 -0.41910701990127563 0.43825292587280273 0.6181299090385437 - 0.46412837505340576 -0.42933720350265503 -0.41910701990127563 0.43825292587280273 - 0; - setAttr -s 16 ".kox[1:15]" 0.88576853275299072 0.9031442403793335 - 0.90793687105178833 0.89885157346725464 0.12500001490116119 0.88576853275299072 - 0.9031442403793335 0.90793687105178833 0.89885145425796509 0.12500010430812836 - 0.88576853275299072 0.9031442403793335 0.90793687105178833 0.89885157346725464 - 1; - setAttr -s 16 ".koy[1:15]" 0.46412727236747742 -0.42933720350265503 - -0.41910701990127563 0.43825322389602661 0.14264534413814545 0.46412727236747742 - -0.42933720350265503 -0.41910701990127563 0.43825337290763855 0.14264534413814545 - 0.46412727236747742 -0.42933720350265503 -0.41910701990127563 0.43825313448905945 - 0; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -78 -14.753841314248957 -46 -14.482509651228581 - -27 -24.930397477970629 -12 -24.930397477970629 1 -14.753841314248957 33 - -14.482509651228581 52 -24.930397477970629 67 -24.930397477970629 80 -14.753841314248957 - 112 -14.482509651228581 131 -24.930397477970629 146 -24.930397477970629 159 - -14.753841314248957; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 3 9 9 - 9 3 9 9 9 3; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 3 9 9 - 9 3 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 1 1 1 80 1 159 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 1 1 1 80 1 159 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" -78 1 1 1 80 1 159 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 28 1 46 1 80 1; - setAttr -s 5 ".kit[1:4]" 9 9 9 3; - setAttr -s 5 ".kot[1:4]" 5 5 5 3; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 9 0 28 0 46 0 80 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.74525677667777757 9 0.74525677667777757 - 28 0.74525677667777757 46 0.74525677667777757 80 0.74525677667777757; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.8072476834435935 9 1.8072476834435935 - 28 1.8072476834435935 46 1.8072476834435935 80 1.8072476834435935; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -5.2846953468686371 28 -4.773336916696497 - 46 -4.773336916696497 80 -5.2846953468686371; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 9 0 28 0 46 0 80 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 9 0 28 0 46 0 80 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 28 1 46 1 80 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 28 1 46 1 80 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 28 1 46 1 80 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 3; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 55 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -12.41287000000041 22 -12.41287000000041 - 55 -12.41287000000041 80 -12.41287000000041; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.7285999999993047 22 -6.7285999999993047 - 55 -6.7285999999993047 80 -6.7285999999993047; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.8687599999999316 22 -3.8687599999999316 - 55 -3.8687599999999316 80 -3.8687599999999316; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.752731508236391 22 17.575740687663522 - 55 6.4870119110025382 80 12.752731508236391; - setAttr -s 4 ".kit[0:3]" 3 1 1 3; - setAttr -s 4 ".kot[0:3]" 3 1 1 3; - setAttr -s 4 ".kix[1:3]" 1 1 1; - setAttr -s 4 ".kiy[1:3]" 0 0 0; - setAttr -s 4 ".kox[1:3]" 1 1 1; - setAttr -s 4 ".koy[1:3]" 0 0 0; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 22 0 55 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 22 0 55 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 55 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 55 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 55 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 49.111805173615501 16 51.190846457835931 - 43 48.532274277619457 80 49.111805173615501; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -36.514345314725674 16 -32.919913206550518 - 43 -37.39496101549193 80 -36.514345314725674; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -10.891726707689953 16 -14.539579744065646 - 43 -9.9277851245267712 80 -10.891726707689953; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 26 1 54 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.412879749935719 26 12.412879749935719 - 54 12.412879749935719 80 12.412879749935719; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.7286993982861674 26 -6.7286993982861674 - 54 -6.7286993982861674 80 -6.7286993982861674; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.868763862603668 26 -3.868763862603668 - 54 -3.868763862603668 80 -3.868763862603668; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 18.897592227293046 26 26.060561221119134 - 54 11.300561221118764 80 18.897592227293046; - setAttr -s 4 ".kit[0:3]" 3 1 1 3; - setAttr -s 4 ".kot[0:3]" 3 1 1 3; - setAttr -s 4 ".kix[1:3]" 1 1 1; - setAttr -s 4 ".kiy[1:3]" 0 0 0; - setAttr -s 4 ".kox[1:3]" 1 1 1; - setAttr -s 4 ".koy[1:3]" 0 0 0; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 26 0 54 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 26 0 54 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 26 1 54 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 26 1 54 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 26 1 54 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 80 -ast 1 -aet 80 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.9724690136323719 10 4.4264261331675518 - 31 5.8137795257559475 50 4.4264261331675518 68 5.8137795257559475 80 4.9724690136323719; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.4986441414986604 10 4.3937238431314825 - 31 4.6602991197236454 50 4.3937238431314825 68 4.6602991197236454 80 4.4986441414986604; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 7.7764710405847595 10 7.7712681071056613 - 31 7.7844874121673691 50 7.7712681071056613 68 7.7844874121673691 80 7.7764710405847595; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -1.0516037765407065 10 0 31 -2.6718525581737946 - 50 0 68 -2.6718525581737946 80 -1.0516037765407065; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.3076118790011737 10 0 31 10.944524996277053 - 50 0 68 10.944524996277053 80 4.3076118790011737; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.35741472225497312 10 0 31 0.90809814617374629 - 50 0 68 0.90809814617374629 80 0.35741472225497312; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -4.3542158758964167 10 -4.0846345617354372 - 31 -4.769570789566667 50 -4.0846345617354372 68 -4.769570789566667 80 -4.3542158758964167; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.3425967083877488 10 4.282468147773308 - 31 4.4352392314085174 50 4.282468147773308 68 4.4352392314085174 80 4.3425967083877488; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 7.7168791003633874 10 7.7712681071056613 - 31 7.6330797418271441 50 7.7712681071056613 68 7.6330797418271441 80 7.7168791003633874; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10 0 31 0 50 0 68 0 80 0; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.6982462339184181 10 0 31 -6.8555441350667934 - 50 0 68 -6.8555441350667934 80 -2.6982462339184181; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10 0 31 0 50 0 68 0 80 0; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10 1 31 1 50 1 68 1 80 1; - setAttr -s 6 ".kit[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kot[1:5]" 1 3 3 1 3; - setAttr -s 6 ".kix[1:5]" 1 1 1 1 1; - setAttr -s 6 ".kiy[1:5]" 0 0 0 0 0; - setAttr -s 6 ".kox[1:5]" 1 1 1 1 1; - setAttr -s 6 ".koy[1:5]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 34 1 57 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 34 0 57 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.7384771804188404 34 5.7384771804188404 - 57 5.7384771804188404 80 5.7384771804188404; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.0494561358638701 34 2.0494561358638701 - 57 2.0494561358638701 80 2.0494561358638701; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -15.409205020920503 34 -15.409205020920503 - 57 -15.409205020920503 80 -15.409205020920503; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 34 7.7133668323055993 57 7.7133668323055993 - 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 27.72702953106549 34 19.576116982883828 - 57 19.576116982883828 80 27.72702953106549; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 34 1 57 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 34 1 57 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 34 1 57 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 53 1 80 1; - setAttr -s 4 ".kit[1:3]" 9 9 3; - setAttr -s 4 ".kot[1:3]" 5 5 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 22 0 53 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.3128351505039433 22 2.3128351505039433 - 53 2.3128351505039433 80 2.3128351505039433; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.23421866920666501 22 0.23421866920666501 - 53 0.23421866920666501 80 0.23421866920666501; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.660431799163181 22 12.660431799163181 - 53 12.660431799163181 80 12.660431799163181; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 22 0 53 0 80 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.4125540166489063 80 2.4125540166489063; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 53 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 53 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 22 1 53 1 80 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 42 1 80 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 5 3; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.83371697884823759 42 -0.41730905073131686 - 80 0.83371697884823759; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.1086667563431649 42 0.054392104378450198 - 80 -0.1086667563431649; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 42 0 80 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 42 0 80 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 42 0 80 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 42 0 80 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 42 1 80 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 42 1 80 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 42 1 80 1; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.08568 80 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537988160630093 80 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185075120832098 80 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8119691574396866 80 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9186219656239931 80 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.1258655568218376 80 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.085679155728795 80 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537911794025533 80 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185070801020824 80 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3244262317670241 80 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0332012531196431 80 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.463963295533194 80 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.1689522478599503 80 7.1689522478599503; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.7485750141607372 80 -7.7485750141607372; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 10.109326515514191 80 10.109326515514191; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 63.314403926397745 80 63.314403926397745; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 11.590164763476968 80 11.590164763476968; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.3924057183505063 80 -7.3924057183505063; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.3620493586843594 80 -7.3620493586843594; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.3462904043098467 80 5.3462904043098467; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -29.54838557779286 80 -29.54838557779286; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.3030645628451412 80 -5.3030645628451412; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -71.101691513482606 80 -71.101691513482606; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 32.578198345223548 80 32.578198345223548; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -95.56444850608456 80 -95.56444850608456; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -118.97547160373531 80 -118.97547160373531; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 30.32938199865233 80 30.32938199865233; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -92.904446145666853 80 -92.904446145666853; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 55.093539413074161 80 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -43.06669930639881 80 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 45.347904894038919 80 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 80 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 80 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 80 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -31.985789116916926 80 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -63.633495633976999 80 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -40.765251761238815 80 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 80 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 80 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 80 0.5814880999021691; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 80 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.6268319407172029 80 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.1098668596606802 80 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.44667534838539324 80 -0.44667534838539324; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.9286194788863922 80 -7.9286194788863922; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 80 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_locator13; - setAttr ".t" -type "double3" 0.0032893248995669033 0.42074550807650996 - -88.322777837915837 ; - setAttr ".r" -type "double3" 179.72494022541443 -0.0085757562239429132 -179.99989705255965 ; - setAttr ".s" -type "double3" 1 1.0000000000000002 87.843121583379272 ; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339262 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rhand_IK; - setAttr -av ".hse" no; -select -ne IMP_Lhand_IK; - setAttr -av ".hse" no; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Lhand_GOAL; - setAttr ".t" -type "double3" 29.775846152470962 57.582470209590937 -1.0893063224582775 ; - setAttr ".r" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; - setAttr ".s" -type "double3" 1 0.99999999999999989 0.99999999999999978 ; -select -ne IMP_LHAND_ROT; - setAttr ".t" -type "double3" -2.5294371750177831 13.481673551673362 -0.26635088939205875 ; - setAttr ".r" -type "double3" 24.903303255498034 83.297592472246265 122.54479644421183 ; - setAttr ".s" -type "double3" 15.445123296459185 15.445123296459185 15.445123296459185 ; - setAttr -k on ".FIST" 0; - setAttr -k on ".NEUTRAL" 0; - setAttr -k on ".SPREAD" 0; -select -ne IMP_RHAND_ROT; - setAttr ".t" -type "double3" -7.5406347832540632e-013 13.71946295727715 - -3.0908609005564358e-013 ; - setAttr ".r" -type "double3" 42.502651823312135 -65.486895657701496 -128.05434783736132 ; - setAttr ".s" -type "double3" 15.445123296459183 15.445123296459185 15.445123296459181 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of idle1.ma diff --git a/base/models/monsters/imp/animation/cycles/imp.mb b/base/models/monsters/imp/animation/cycles/imp.mb deleted file mode 100644 index 4716592dd..000000000 Binary files a/base/models/monsters/imp/animation/cycles/imp.mb and /dev/null differ diff --git a/base/models/monsters/imp/animation/cycles/initial.ma b/base/models/monsters/imp/animation/cycles/initial.ma deleted file mode 100644 index eb453c3e4..000000000 --- a/base/models/monsters/imp/animation/cycles/initial.ma +++ /dev/null @@ -1,1854 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: initial.ma -//Last modified: Fri, May 31, 2002 08:46:09 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models/monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 11.249051938753507 54.624273604756127 98.26262699333823 ; - setAttr ".r" -type "double3" -1.5301089135585337 0.20000000000011725 4.1543142611227324e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".coi" 99.105982553874313; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 29.792071675181425 75.222265216099515 -0.27282936421645054 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" -5.2241325907688658 100 0.82558364258219386 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".coi" 100; - setAttr ".ow" 108.97434250849653; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0.95737795752868049 59.434093209221679 128.57047479880799 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".coi" 100; - setAttr ".ow" 9.9769651305726086; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 81.286829083090353 -4.0081060210518338 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".coi" 100; - setAttr ".ow" 27.019133995446666; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 5.157268050779404 64.417731710601458 89.372250876656295 ; - setAttr ".sp" -type "double3" 5.157268050779404 64.417731710601458 89.372250876656295 ; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode renderLayer -s -n "globalRender"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.3867545965885748; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.1192573708760349; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.223431660231931; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.9513867036587939e-016; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.874026122734275; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -37.478544156921508; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.2284820667708982; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -24.929602737243009; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.3867499999998705; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.1192000000001707; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -29.487085084354458; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6393582492177674; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.4047897830479883; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -41.027555489142713; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.0746302064873596; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 16.456121544155422; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.7235646039452819; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42835364100675832; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.3620493586843594; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.275274082326419; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.8287037947059579; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -10.103037396887247; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.2919620845744326; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.63757578585061037; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.7485750141607372; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7675548761553177; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.3217214319949511; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.8733736093684374; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 46.137710844738756; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.0800268972133189; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.290092833979712; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 56 -ast 1 -aet 56 "; - setAttr ".st" 6; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 11 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 11 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_locator5" "group1"; -parent -s -nc -r "IMP_locator6" "group1"; -parent -s -nc -r "IMP_camera" "group1"; -parent -s -nc -r "IMP_locator14" "group1"; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339251 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537529 ; -select -ne IMP_Body; -select -ne IMP_Neck; - setAttr ".t" -type "double3" 0 5.7384771804188404 2.0494561358638701 ; - setAttr -av ".ty"; - setAttr -av ".tz"; - setAttr ".r" -type "double3" 0 0 0 ; - setAttr -av ".rx"; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".r" -type "double3" 12.223431660231931 7.9513867036587939e-016 - 28.874026122734275 ; - setAttr -av ".rz"; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".r" -type "double3" -37.478544156921508 -3.2284820667708982 -24.929602737243009 ; - setAttr -av ".rz"; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr ".ra" -type "double3" 6.5004949211009606 20.509769230607578 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".r" -type "double3" -29.487085084354458 -3.6393582492177674 -6.4047897830479883 ; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr -av ".rz"; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".r" -type "double3" -41.027555489142713 -5.0746302064873596 16.456121544155422 ; - setAttr -av ".rz"; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rupleg; - setAttr ".t" -type "double3" -3.6380577235397413 -5.9996743942435486 -2.7995714837697929 ; - setAttr ".r" -type "double3" 5.7891550984925217 1.4693303794425669 -6.2062241685753783 ; - setAttr ".ra" -type "double3" 139.70607085520152 -3.1805546814635176e-015 - 90 ; - setAttr ".jo" -type "double3" 167.105269716604 49.095322549761697 -9.9739354817997672 ; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of initial.ma diff --git a/base/models/monsters/imp/animation/cycles/jump_loop.ma b/base/models/monsters/imp/animation/cycles/jump_loop.ma deleted file mode 100644 index 321a46250..000000000 --- a/base/models/monsters/imp/animation/cycles/jump_loop.ma +++ /dev/null @@ -1,9102 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:22 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: jump_loop.ma -//Last modified: Fri, Nov 14, 2003 06:00:17 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 171.97482207923173 77.985508363295281 387.86392829450068 ; - setAttr ".r" -type "double3" -10.530108906709254 -1828.9999999996903 4.5456251664174258e-016 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 422.07663625494683; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 321.86076409630709 -0.21736587382737405 -12.426890028134988 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 323.73305882333466 10.301210904531827 263.89064011796228 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 592.73879183280201; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 503.1108425748202 36.340240485514421 -5.2639934679697946 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 135.35344906692279; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "group2"; - setAttr ".t" -type "double3" 297.75049857774576 -2.8421709430404007e-014 - 115.34478773732499 ; - setAttr ".rp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; - setAttr ".sp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode transform -n "pointLight2" -p "group2"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 1\n" - + " -showDeformers 1\n" - + " -showExpressions 1\n" - + " -showConstraints 1\n" - + " -showUnderworld 1\n" - + " -showInvisible 1\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 1\n" - + " -showDeformers 1\n" - + " -showExpressions 1\n" - + " -showConstraints 1\n" - + " -showUnderworld 1\n" - + " -showInvisible 1\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 20 -max 40 -ast 20 -aet 40 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -1.08568 20 -1.08568 40 -1.08568; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.1537988160630093 20 4.1537988160630093 - 40 4.1537988160630093; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.6185075120832098 20 4.6185075120832098 - 40 4.6185075120832098; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -5.8119691574396866 20 -5.8119691574396866 - 40 -5.8119691574396866; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.9186219656239931 20 5.9186219656239931 - 40 5.9186219656239931; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -4.1258655568218376 20 -4.1258655568218376 - 40 -4.1258655568218376; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.085679155728795 20 1.085679155728795 - 40 1.085679155728795; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.1537911794025533 20 4.1537911794025533 - 40 4.1537911794025533; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.6185070801020824 20 4.6185070801020824 - 40 4.6185070801020824; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.3244262317670241 20 -6.3244262317670241 - 40 -6.3244262317670241; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.0332012531196431 20 1.0332012531196431 - 40 1.0332012531196431; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 8.463963295533194 20 8.463963295533194 - 40 8.463963295533194; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 29 1 40 1 48 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.71946295727715 20 13.71946295727715 - 28 13.71946295727715 29 13.71946295727715 40 13.71946295727715 48 13.71946295727715; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 68.596496127541187 20 68.596496127541187 - 28 68.596496127541187 29 68.596496127541187 40 68.596496127541187 48 68.596496127541187; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -60.802874383230787 20 -60.802874383230787 - 28 -60.802874383230787 29 -60.802874383230787 40 -60.802874383230787 48 -60.802874383230787; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -157.43468421330525 20 -157.43468421330525 - 28 -157.43468421330525 29 -157.43468421330525 40 -157.43468421330525 48 -157.43468421330525; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459183 20 15.445123296459183 - 28 15.445123296459183 29 15.445123296459183 40 15.445123296459183 48 15.445123296459183; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 40 15.445123296459185 48 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459181 20 15.445123296459181 - 28 15.445123296459181 29 15.445123296459181 40 15.445123296459181 48 15.445123296459181; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 29 1 40 1 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.010024364806417531 20 0.21060231619815561 - 28 0.20000000000000001 29 0.21060231619815561 40 0.21060231619815561 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.42673163973887457 20 1.0386541206168749 - 28 1 29 1.0386541206168749 40 1.0386541206168749 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 29 1 40 1 48 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.5294371750177831 20 -2.5294371750177831 - 28 -2.5294371750177831 29 -2.5294371750177831 40 -2.5294371750177831 48 -2.5294371750177831; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.481673551673362 20 13.481673551673362 - 28 13.481673551673362 29 13.481673551673362 40 13.481673551673362 48 13.481673551673362; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.26635088939205875 20 -0.26635088939205875 - 28 -0.26635088939205875 29 -0.26635088939205875 40 -0.26635088939205875 48 - -0.26635088939205875; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 73.167297059293915 20 73.167297059293915 - 28 73.167297059293915 29 73.167297059293915 40 73.167297059293915 48 73.167297059293915; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 61.241182877125034 20 61.241182877125034 - 28 61.241182877125034 29 61.241182877125034 40 61.241182877125034 48 61.241182877125034; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 177.69376467901077 20 177.69376467901077 - 28 177.69376467901077 29 177.69376467901077 40 177.69376467901077 48 177.69376467901077; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 40 15.445123296459185 48 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 40 15.445123296459185 48 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 40 15.445123296459185 48 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 29 1 40 1 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0.53328935673265621 28 0.5 - 29 0.53328935673265621 40 0.53328935673265621 48 0.19999999999999996; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 1.0599738906558223 28 1 - 29 1.0599738906558223 40 1.0599738906558223 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 33 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 216.45671880619176 24 326.34196719872944 - 28 376.25890537498935 33 422.24399536815679 40 452.12705893044222; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 45.180676105655813 24 47.352161952212526 - 28 40.953996742171839 33 44.019345773294937 40 46.686918115049941; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -33.189851895069083 24 -22.152488095589188 - 28 -22.922258526519585 33 -35.380631374451525 40 -33.630936833678902; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 358.04876736035584 24 372.9737147923201 - 28 365.36849059365238 33 350.02397115764808 40 358.04876736035584; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 155.91713557661092 24 154.99028448406145 - 28 154.8732078201553 33 157.52674216854078 40 155.91713557661092; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 418.4296026462676 24 433.04458652607644 - 28 385.70429242164181 33 387.66011097169678 40 418.4296026462676; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 211.86572767566457 24 320.55258754716897 - 29 386.48000429024364 35 428.6028833204648 40 447.53606779991503; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 46.670221532664833 24 46.497874050790898 - 29 50.674611106597567 35 52.624594276509029 40 46.582508638644455; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 26.743704905701577 24 25.927144713027886 - 29 23.118404530995839 35 16.026576332394026 40 26.919130693742314; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -294.84643525493948 24 -343.93712456946542 - 29 -327.50442520725397 35 -313.18978161968118 40 -294.84643525493948; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 56.583233323599366 24 35.558533015590569 - 29 50.789917778648196 35 54.399581628601872 40 56.583233323599366; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 97.316003029379416 24 108.00241227863057 - 29 78.706026094922095 35 108.90443818984369 40 97.316003029379416; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 40 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 20 0 25 0 29 0 40 - 0; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 11 5.6268319407172029 - 18 5.6268319407172029 20 5.6268319407172029 25 5.6268319407172029 29 5.6268319407172029 - 40 5.6268319407172029; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 11 -2.1098668596606802 - 18 -2.1098668596606802 20 -2.1098668596606802 25 -2.1098668596606802 29 -2.1098668596606802 - 40 -2.1098668596606802; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 360.76739391711288 11 336.00205489946853 - 18 342.74743969676229 20 344.2807686922356 25 329.36780663304643 29 344.2807686922356 - 40 344.2807686922356; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.39334696132271052 11 22.934613158314267 - 18 3.3751297566513738 20 1.4505595646430978 25 5.3414742141381781 29 1.4505595646430978 - 40 1.4505595646430978; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -18.700472818991617 11 -35.808201433501473 - 18 -4.0181375389538863 20 15.906836626290886 25 25.815943956457605 29 15.906836626290886 - 40 15.906836626290886; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 40 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 40 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 40 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 27 1 33 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 6.925456265951996 24 8.7983283713503706 - 27 6.3926030858134348 33 6.3635962352814666 40 6.9254562659520378; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 34.805307986888593 24 36.632382269376841 - 27 33.822785262465665 33 47.05685736241653 40 34.805307986888593; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 102.59116157729517 24 192.78853084142355 - 27 244.61438963345421 33 270.20666728035451 40 290.27880593926125; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -80.195825489861193 24 -301.53506754966133 - 27 -107.16030369744004 33 -119.97027355831113 40 -80.195825489861193; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1.4379585757962667 24 156.57861554381626 - 27 -1.7785995142158657 33 -12.212117601809471 40 1.4379585757962667; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -29.493568390973312 24 -201.27457036315781 - 27 -8.3728498348280613 33 9.7631065621530748 40 -29.493568390973312; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 27 1 33 1 40 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 27 1 33 1 40 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 27 1 33 1 40 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 125.1606853982252 20 125.1606853982252 - 29 125.1606853982252 40 125.1606853982252; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 77.825664227235052 20 77.825664227235052 - 29 77.825664227235052 40 77.825664227235052; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -175.25743303308352 20 -175.25743303308352 - 29 -175.25743303308352 40 -175.25743303308352; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -2.7793559208802852 24 -6.2589266759223765 - 29 -5.7256020995601595 35 -4.2532904743040874 40 -2.9210408011837785; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 31.512049030314767 24 33.797998948145974 - 29 44.58968899209637 35 30.741015514795059 40 31.512049030314763; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 112.52139196314549 24 192.78962588633638 - 29 261.49443100954397 35 282.49778173954013 40 302.03778197822874; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -104.8756268790394 24 -146.39991688279261 - 29 -156.49706152316367 35 -97.857221823782112 40 -116.96895307397615; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -38.321160312802796 24 -29.684032640488194 - 29 -18.220443250945642 35 -27.588374617224133 40 -38.321160312802768; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -5.1515784092334114 24 25.709605253119321 - 29 33.219492282605685 35 14.223026673819952 40 -5.1515784092334984; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 35 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 2.0464370519482591 24 1.9808213950622355 - 28 2.0468877521418802 35 1.9808213950622342 40 1.9808213950622366; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 35.290216119765219 24 36.083543817722116 - 28 39.774127200765285 35 35.682105273888197 40 35.797750324022346; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 135.58394463251807 24 218.91422477429876 - 28 272.7450196331414 35 312.76108124915578 40 327.73280893196056; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 56.307325565710279 24 56.307325565710279 - 28 56.307325565710279 35 61.551998289871989 40 56.307325565710279; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 11.49524675155142 24 11.49524675155142 - 28 11.49524675155142 35 11.49524675155142 40 11.49524675155142; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 -20.965676744725002 24 -20.965676744725002 - 28 -20.965676744725002 35 -20.965676744725002 40 -20.965676744725002; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 35 1 40 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 35 1 40 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 35 1 40 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.21285352564148119 40 -0.21285352564148119; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.15078676416754505 40 0.15078676416754505; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.15149042747921673 40 0.15149042747921673; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 19 1 20 1 26 1 29 - 1 40 1 42 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.90991990467137285 13 0.90991990467137285 - 17 0.90991990467137285 19 3.2165938865377592 20 3.2165938865377592 26 3.2165938865377592 - 29 3.2165938865377592 40 3.2165938865377592 42 3.2165938865377592 48 3.2165938865377592; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.6840963091226424 13 1.6840963091226424 - 17 1.6840963091226424 19 1.0198173250982352 20 1.0198173250982352 26 1.0198173250982352 - 29 1.0198173250982352 40 1.0198173250982352 42 1.0198173250982352 48 1.0198173250982352; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.8509277672757398 13 2.8509277672757398 - 17 2.8509277672757398 19 5.5089484635562949 20 5.5089484635562949 26 5.5089484635562949 - 29 5.5089484635562949 40 5.5089484635562949 42 5.5089484635562949 48 5.5089484635562949; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -81.50691442197396 13 -31.261146897838977 - 17 -76.052449399988134 19 14.028238821473778 20 -70.437175366272854 26 -54.179056524598487 - 29 -70.437175366272854 40 -70.437175366272854 42 -55.664830857165363 48 -37.750911612187679; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 30.964642776910992 13 16.829153229070521 - 17 17.998418905573541 19 61.793759660292352 20 7.7450184891197837 26 25.772656551088751 - 29 7.7450184891197837 40 7.7450184891197837 42 8.3717076859878041 48 21.674975974628239; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.8358968951012837 13 6.4562833550431655 - 17 -20.729425848392836 19 20.568981510619366 20 -8.0995301610500423 26 -13.075226896918867 - 29 -8.0995301610500423 40 -8.0995301610500423 42 -3.6057329631056776 48 -6.3849825779711411; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 19 1 20 1 26 1 29 - 1 40 1 42 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 19 1 20 1 26 1 29 - 1 40 1 42 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 17 1 19 1 20 1 26 1 29 - 1 40 1 42 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 3 3 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 3 3 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 1 27 1 35 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 0 27 0 35 0 40 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 2.3128351505039433 27 2.3128351505039433 - 35 2.3128351505039433 40 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 0.23421866920666501 27 0.23421866920666501 - 35 0.23421866920666501 40 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 21.70499742554771 27 25.167480403945813 - 35 18.582420375475547 40 21.70499742554771; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 27.293662652073252 27 1.8347558617044366 - 35 30.126299270770989 40 27.293662652073252; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 12.887946883084584 27 13.462079635152172 - 35 7.3368803554432276 40 12.887946883084584; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 1 27 1 35 1 40 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 1 27 1 35 1 40 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 20 1 27 1 35 1 40 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 40 1 48 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 40 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 40 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 40 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 40 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 40 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 40 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.27427147149852044 11 0.27427147153653575 - 12 0.27427147153797948 13 0.27427147153980314 14 0.27427147154217391 15 0.2742714715453653 - 16 0.27427147154983328 17 0.27427147155621612 18 0.27427147156259896 19 0.27427147156259896 - 20 0.27427147156259896 24 0.27427147156259896 29 0.27427147156259896 40 0.27427147156259896 - 48 0.27427147156259896; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -1.1074984126668126 11 -1.1074984146392313 - 12 -1.1074984147141391 13 -1.1074984148087597 14 -1.1074984149317662 15 -1.1074984150973519 - 16 -1.107498415329172 17 -1.1074984156603436 18 -1.1074984159915151 19 -1.1074984159915151 - 20 -1.1074984159915151 24 -1.1074984159915151 29 -1.1074984159915151 40 -1.1074984159915151 - 48 -1.1074984159915151; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -1.642626684874722 11 -1.6426266835385228 - 12 -1.6426266834877772 13 -1.6426266834236773 14 -1.6426266833403476 15 -1.6426266832281728 - 16 -1.642626683071128 17 -1.6426266828467784 18 -1.6426266826224289 19 -1.6426266826224289 - 20 -1.6426266826224289 24 -1.6426266826224289 29 -1.6426266826224289 40 -1.6426266826224289 - 48 -1.6426266826224289; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 40 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 40 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -37.815214478634331 11 -125.74912876606732 - 12 -125.51192920989145 13 -100.00216573212361 14 -59.835637123346231 15 -36.233993668944173 - 16 -35.413141578212446 17 -49.792207316432325 18 -114.59155902616467 19 -86.44861012607744 - 20 -18.911188309049191 24 -42.937392967796441 29 -18.911188309049191 40 -18.911188309049191 - 48 -83.651838089100195; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 40 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 40 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 40 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 40 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 40 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 40 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 40 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.2742786288673521 10 -0.27427863453231033 - 17 -0.27427863453231033 18 -0.27427863453231033 19 -0.27427863453231033 20 - -0.27427863453231033 24 -0.27427863453231033 29 -0.27427863453231033 40 -0.27427863453231033 - 48 -0.27427863453231033; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.1075115373407667 10 -1.1075115557303763 - 17 -1.1075115557303763 18 -1.1075115557303763 19 -1.1075115557303763 20 -1.1075115557303763 - 24 -1.1075115557303763 29 -1.1075115557303763 40 -1.1075115557303763 48 -1.1075115557303763; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.6426166407301896 10 -1.6426166273853338 - 17 -1.6426166273853338 18 -1.6426166273853338 19 -1.6426166273853338 20 -1.6426166273853338 - 24 -1.6426166273853338 29 -1.6426166273853338 40 -1.6426166273853338 48 -1.6426166273853338; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 40 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 40 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 108.86198107485642 10 108.86198107485642 - 17 73.338597776745388 18 26.403355291791605 19 54.852317270957315 20 17.797350596899509 - 24 34.98949021968803 29 17.797350596899509 40 17.797350596899509 48 61.879441874128936; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.14201183279855 20 1.0099431818894913 - 28 1 29 1.0099431818894913 40 1.0099431818894913 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1.0110080399545431 28 1 - 29 1.0110080399545431 40 1.0110080399545431 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 29 0 40 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 11 1 18 1 20 1 27 1 34 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -28.073881032405502 6 -46.403838232154726 - 11 -57.268694860493916 18 -64.448733245059486 20 -85.021389942138228 27 -96.759313977435809 - 34 -81.70071573151256 48 -92.276866801256645; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -61.199228718418333 6 -52.589856193268211 - 11 -48.400115258246736 18 -43.995383780771014 20 -56.304528730735143 27 -41.2276998033512 - 34 -55.139126251391993 48 -76.844287356428978; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -81.184232108591999 6 -75.778137454888423 - 11 -62.491121494028498 18 -64.875827156229477 20 -23.876400721722792 27 -34.093153518684247 - 34 -33.172769882599198 48 -6.4131326743179056; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 19 1 22 1 29 1 34 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -117.99254693569441 13 -123.98803296810649 - 19 -131.56223464759714 22 -143.68624235845436 29 -118.25457552859019 34 -118.19943411562497 - 48 -137.79238049393118; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 27.075624429458429 13 25.391307459182691 - 19 20.623216711056333 22 37.500675079600633 29 12.160180912642328 34 24.003088726248219 - 48 55.642180590844198; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -35.130967703309707 13 -76.878252144223026 - 19 -53.588570440441174 22 -49.075623471088711 29 -63.575828601904099 34 -35.895713294177334 - 48 -20.939120123829618; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.90858890976581275 20 -0.90858890976581275 - 40 -0.90858890976581275; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.2382713968077237 20 6.2382713968077237 - 40 6.2382713968077237; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.55501859990651525 20 -0.55501859990651525 - 40 -0.55501859990651525; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -22.350064437213423 20 -22.350064437213423 - 40 -22.350064437213423; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -10.303773027856268 20 -10.303773027856268 - 40 -10.303773027856268; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 8.8115085199100047 20 8.8115085199100047 - 40 8.8115085199100047; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 0.99999999999999978 24 0.99999999999999978 - 29 0.99999999999999978 35 0.99999999999999978 40 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 29 1 35 1 40 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 1 24 1 28 1 33 1 40 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 0.99999999999999989 24 0.99999999999999989 - 28 0.99999999999999989 33 0.99999999999999989 40 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 20 0.99999999999999978 24 0.99999999999999978 - 28 0.99999999999999978 33 0.99999999999999978 40 0.99999999999999978; -createNode animCurveTU -n "IMP_locator5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_camera_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator14_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 90 40 90; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.25 40 1.25; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.25 40 1.25; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.25 40 1.25; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_lelbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_lelbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_relbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.1057240879120851; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5956396785200369; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3817563473270154; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41001647724799928; -createNode animCurveTL -n "IMP_Lmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1693934765127816; -createNode animCurveTL -n "IMP_Lmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5729514457211735; -createNode animCurveTA -n "IMP_Lmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_pointConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_orientConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_cam_connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0046539604129529621; -createNode animCurveTL -n "IMP_cam_connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4094890802521576; -createNode animCurveTL -n "IMP_cam_connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0367577756137232; -createNode animCurveTA -n "IMP_cam_connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.11875208173462; -createNode animCurveTA -n "IMP_cam_connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085761516203950224; -createNode animCurveTA -n "IMP_cam_connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1776791248832486e-005; -createNode animCurveTU -n "IMP_cam_connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_eyes_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.034284369950123843; -createNode animCurveTL -n "IMP_eyes_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9944975057013083; -createNode animCurveTL -n "IMP_eyes_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.9109443986143884; -createNode animCurveTA -n "IMP_eyes_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -147.00752219093516; -createNode animCurveTA -n "IMP_eyes_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_eyes_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 180; -createNode animCurveTU -n "IMP_eyes_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_eyes_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator13_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.0032893248995669033; -createNode animCurveTL -n "IMP_locator13_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.42074550807650996; -createNode animCurveTL -n "IMP_locator13_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -88.322777837915837; -createNode animCurveTA -n "IMP_locator13_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 179.72494022541443; -createNode animCurveTA -n "IMP_locator13_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085757562239429132; -createNode animCurveTA -n "IMP_locator13_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -179.99989705255965; -createNode animCurveTU -n "IMP_locator13_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0000000000000002; -createNode animCurveTU -n "IMP_locator13_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 87.843121583379272; -createNode animCurveTU -n "IMP_pCube1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_pCube1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.04673741311718338; -createNode animCurveTL -n "IMP_pCube1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.018550086981591107; -createNode animCurveTL -n "IMP_pCube1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.59134881205267886; -createNode animCurveTA -n "IMP_pCube1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_pCube1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.81452695663524144; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 13.663320674475715 40 13.663320674475715; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.7758528420198658 40 6.7758528420198658; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.784757077400341 40 -12.784757077400341; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.2695897469829736 40 3.2695897469829736; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.9162979482121409 40 -6.9162979482121409; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.2353930143209828 40 6.2353930143209828; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.58855436141337392 40 0.58855436141337392; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.10942982456140288 40 -0.10942982456140288; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 13.663320674475715 40 13.663320674475715; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.7758528420198658 40 6.7758528420198658; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.1064832569487142 40 -2.1064832569487142; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.36693656610454173 40 0.36693656610454173; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.728045273286209 40 12.728045273286209; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.2353930143209828 40 6.2353930143209828; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.58855436141337392 40 0.58855436141337392; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.10942982456140288 40 -0.10942982456140288; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.5258192723085173 20 5.5258192723085173 - 40 5.5258192723085173; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.1525507362789047 20 1.1525507362789047 - 40 1.1525507362789047; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.1924108426844384 20 1.1924108426844384 - 40 1.1924108426844384; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.3533140211779946 20 6.3533140211779946 - 40 6.3533140211779946; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.74525677667777757 20 0.74525677667777757 - 40 0.74525677667777757; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.8072476834435935 20 1.8072476834435935 - 40 1.8072476834435935; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 9.022004834100839 20 9.022004834100839 - 40 9.022004834100839; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.9550621233059426 20 1.9550621233059426 - 40 1.9550621233059426; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.88597689344963537 20 -0.88597689344963537 - 40 -0.88597689344963537; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.9684923358091311 20 -3.9684923358091311 - 40 -3.9684923358091311; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.2916645882841449 20 2.2916645882841449 - 40 2.2916645882841449; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.7296155549506897 20 4.7296155549506897 - 40 4.7296155549506897; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.1608864069345106 20 2.1608864069345106 - 40 2.1608864069345106; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.0054669522092379 20 -3.0054669522092379 - 40 -3.0054669522092379; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 28.836234092176063 20 11.07349067527878 - 40 61.221005816918222; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 3.5988200593703294 20 -53.841918861092552 - 40 -54.58547961358898; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 52.351071907336284 20 -25.947600690391031 - 40 -26.289528192330923; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 12.412879749935719 20 12.412879749935719 - 40 12.412879749935719; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.7286993982861674 20 -6.7286993982861674 - 40 -6.7286993982861674; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.868763862603668 20 -3.868763862603668 - 40 -3.868763862603668; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -34.36059369489287 20 42.922644402952855 - 40 8.2008866242010114; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -8.556853256702178 20 8.5989866823062808 - 40 1.6429396614658915; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -23.206907965932974 20 27.627511712669737 - 40 5.2785678612290523; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 12.890532588149956 20 12.890532588149956 - 40 12.890532588149956; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.69008032694306476 20 -0.69008032694306476 - 40 -0.69008032694306476; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.645694319339265 20 4.645694319339265 - 40 4.645694319339265; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -5.4675296479599407 20 -5.4675296479599407 - 40 -5.4675296479599407; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.0844803122567583 20 2.0844803122567583 - 40 2.0844803122567583; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.0869908056348607 20 -3.0869908056348607 - 40 -3.0869908056348607; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 26.659954467743521 20 35.929156953403414 - 40 -49.514654456880642; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -49.492801424012306 20 58.495495793078319 - 40 38.868184542311127; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -100.40231940259616 20 35.62217186926501 - 40 -49.363344064729375; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.41287000000041 20 -12.41287000000041 - 40 -12.41287000000041; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.7285999999993047 20 -6.7285999999993047 - 40 -6.7285999999993047; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.8687599999999316 20 -3.8687599999999316 - 40 -3.8687599999999316; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 33.257666229421972 20 74.138445451041335 - 40 32.60369206298445; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 -1.1463794921978937e-014 - 40 -5.041406482635607e-015; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -9.5092015178261011 20 -21.198042374621632 - 40 -9.3222138893735309; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.890500000000031 20 -12.890500000000031 - 40 -12.890500000000031; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.6900999999992341 20 -0.6900999999992341 - 40 -0.6900999999992341; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.6456900000000347 20 4.6456900000000347 - 40 4.6456900000000347; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -4.0846345617354372 20 -4.0846345617354372 - 40 -4.0846345617354372; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.282468147773308 20 4.282468147773308 - 40 4.282468147773308; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 7.7712681071056613 20 7.7712681071056613 - 40 7.7712681071056613; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.4264261331675518 20 4.4264261331675518 - 40 4.4264261331675518; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.3937238431314825 20 4.3937238431314825 - 40 4.3937238431314825; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 7.7712681071056613 20 7.7712681071056613 - 40 7.7712681071056613; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 40 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 40 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.0180767416209342 40 -0.0180767416209342; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.350740136846035 40 4.350740136846035; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.679538405939565 40 2.679538405939565; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 9.2053053109380052 40 9.2053053109380052; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.55189552941641418 40 -0.55189552941641418; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0646191166984784 40 1.0646191166984784; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.6380577235397413 40 -3.6380577235397413; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.9996743942435486 40 -5.9996743942435486; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.7995714837697929 40 -2.7995714837697929; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 11.586085933787016 40 -18.863262919690143; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 23.165861309280317 40 15.715481841842799; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 73.16163459057924 40 49.572207625383122; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 19.149140381761772 40 19.149140381761772; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.3756686479080088 40 0.3756686479080088; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.21075234496274775 40 0.21075234496274775; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 89.830862630651069 40 118.73879230959092; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.1568819853431291 40 1.5291712197973963; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.8855564166933343 40 10.423159905043939; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 20.742856452934195 40 20.742856452934195; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.84893801560717619 40 -0.84893801560717619; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.16812918533366403 40 -0.16812918533366403; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9175729778873523 40 5.9175729778873523; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.85605761867933861 40 0.85605761867933861; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.5874050102942485 40 1.5874050102942485; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.9900427762468107 40 2.9900427762468107; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.91245575548367119 40 0.91245575548367119; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.39837671684541476 40 0.39837671684541476; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.169754565364844 40 5.169754565364844; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.0564808409517294 40 -1.0564808409517294; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.42012489059707847 40 -0.42012489059707847; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.46895946313800008 40 0.46895946313800008; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.744537024733662 40 3.744537024733662; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.043574269372096713 40 0.043574269372096713; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1287329396630019 40 4.1287329396630019; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.85810195764911135 40 0.85810195764911135; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.32542761684201271 40 -0.32542761684201271; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.8784880075680586 40 3.8784880075680586; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.9996743942435486 40 -5.9996743942435486; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.7995714837697929 40 -2.7995714837697929; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -76.090633252486683 40 -79.144267849266839; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 19.791362663024994 40 -35.206669963347245; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 54.744021489634264 40 20.460632145881572; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 18.980231639280721 40 18.980231639280721; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.663797374263001 40 1.663797374263001; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.41525250862709329 40 -0.41525250862709329; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 113.88179442110163 40 85.909266009805634; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.88642296005711507 40 -0.66869288686441264; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -16.683497590890667 40 -12.585567691443064; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 20.799371406295553 40 20.799371406295553; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.32904719010364564 40 0.32904719010364564; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.16941601589852961 40 0.16941601589852961; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.1142991392184163 40 6.1142991392184163; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.13638708324248117 40 -0.13638708324248117; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0994349581901075 40 1.0994349581901075; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.5124344559409741 40 2.5124344559409741; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.5859239079718024 40 1.5859239079718024; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.3423521551430217 40 0.3423521551430217; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6684103441767562 40 4.6684103441767562; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.21264207246076725 40 -0.21264207246076725; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.3825986145063745 40 -0.3825986145063745; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.4623854590403933 40 -0.4623854590403933; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.8711962578925494 40 3.8711962578925494; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.1098661950250604 40 -0.1098661950250604; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.9497075072661634 40 4.9497075072661634; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.748040561262465 40 1.748040561262465; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.35737371225579673 40 -0.35737371225579673; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 99.194475901955684 20 99.194475901955684 - 29 99.194475901955684 40 99.194475901955684; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 69.492034696563493 20 69.492034696563493 - 29 69.492034696563493 40 69.492034696563493; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 52.003739368178465 20 52.003739368178465 - 29 52.003739368178465 40 52.003739368178465; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 29 1 40 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 0 29 0 40 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 217.7239621497128 20 217.7239621497128 - 29 217.7239621497128 40 217.7239621497128; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 40 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 40 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.7373203203190113; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4972392481870522; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6496305501990709; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 62.667511380374542; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -13.204130585379209; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 40.323400206122145; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_Lwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint8_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint7_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint9_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_Rwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 25.574347872336627; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -select -ne :time1; - setAttr ".o" 20; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933572 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643403 -66.654599961471263 -11.653334128372219 ; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_locator5_visibility.o" "IMP_locator5.v"; -connectAttr "IMP_locator5_scaleX.o" "IMP_locator5.sx"; -connectAttr "IMP_locator5_scaleY.o" "IMP_locator5.sy"; -connectAttr "IMP_locator5_scaleZ.o" "IMP_locator5.sz"; -connectAttr "IMP_locator5_pointConstraint1_nodeState.o" "IMP_locator5_pointConstraint1.nds" - ; -connectAttr "IMP_locator5_pointConstraint1_RhandW0.o" "IMP_locator5_pointConstraint1.w0" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetX.o" "IMP_locator5_pointConstraint1.ox" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetY.o" "IMP_locator5_pointConstraint1.oy" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetZ.o" "IMP_locator5_pointConstraint1.oz" - ; -connectAttr "IMP_locator5_orientConstraint1_nodeState.o" "IMP_locator5_orientConstraint1.nds" - ; -connectAttr "IMP_locator5_orientConstraint1_RhandW0.o" "IMP_locator5_orientConstraint1.w0" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetX.o" "IMP_locator5_orientConstraint1.ox" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetY.o" "IMP_locator5_orientConstraint1.oy" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetZ.o" "IMP_locator5_orientConstraint1.oz" - ; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_locator6_visibility.o" "IMP_locator6.v"; -connectAttr "IMP_locator6_scaleX.o" "IMP_locator6.sx"; -connectAttr "IMP_locator6_scaleY.o" "IMP_locator6.sy"; -connectAttr "IMP_locator6_scaleZ.o" "IMP_locator6.sz"; -connectAttr "IMP_locator6_pointConstraint1_nodeState.o" "IMP_locator6_pointConstraint1.nds" - ; -connectAttr "IMP_locator6_pointConstraint1_LhandW0.o" "IMP_locator6_pointConstraint1.w0" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetX.o" "IMP_locator6_pointConstraint1.ox" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetY.o" "IMP_locator6_pointConstraint1.oy" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetZ.o" "IMP_locator6_pointConstraint1.oz" - ; -connectAttr "IMP_locator6_orientConstraint1_nodeState.o" "IMP_locator6_orientConstraint1.nds" - ; -connectAttr "IMP_locator6_orientConstraint1_LhandW0.o" "IMP_locator6_orientConstraint1.w0" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetX.o" "IMP_locator6_orientConstraint1.ox" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetY.o" "IMP_locator6_orientConstraint1.oy" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetZ.o" "IMP_locator6_orientConstraint1.oz" - ; -connectAttr "IMP_Lmissile_visibility.o" "IMP_Lmissile.v"; -connectAttr "IMP_Lmissile_translateX.o" "IMP_Lmissile.tx"; -connectAttr "IMP_Lmissile_translateY.o" "IMP_Lmissile.ty"; -connectAttr "IMP_Lmissile_translateZ.o" "IMP_Lmissile.tz"; -connectAttr "IMP_Lmissile_rotateX.o" "IMP_Lmissile.rx"; -connectAttr "IMP_Lmissile_rotateY.o" "IMP_Lmissile.ry"; -connectAttr "IMP_Lmissile_rotateZ.o" "IMP_Lmissile.rz"; -connectAttr "IMP_Lmissile_scaleX.o" "IMP_Lmissile.sx"; -connectAttr "IMP_Lmissile_scaleY.o" "IMP_Lmissile.sy"; -connectAttr "IMP_Lmissile_scaleZ.o" "IMP_Lmissile.sz"; -connectAttr "IMP_camera_visibility.o" "IMP_camera.v"; -connectAttr "IMP_camera_scaleX.o" "IMP_camera.sx"; -connectAttr "IMP_camera_scaleY.o" "IMP_camera.sy"; -connectAttr "IMP_camera_scaleZ.o" "IMP_camera.sz"; -connectAttr "IMP_camera_pointConstraint1_nodeState.o" "IMP_camera_pointConstraint1.nds" - ; -connectAttr "IMP_camera_pointConstraint1_eyesW0.o" "IMP_camera_pointConstraint1.w0" - ; -connectAttr "IMP_camera_pointConstraint1_offsetX.o" "IMP_camera_pointConstraint1.ox" - ; -connectAttr "IMP_camera_pointConstraint1_offsetY.o" "IMP_camera_pointConstraint1.oy" - ; -connectAttr "IMP_camera_pointConstraint1_offsetZ.o" "IMP_camera_pointConstraint1.oz" - ; -connectAttr "IMP_camera_orientConstraint1_nodeState.o" "IMP_camera_orientConstraint1.nds" - ; -connectAttr "IMP_camera_orientConstraint1_eyesW0.o" "IMP_camera_orientConstraint1.w0" - ; -connectAttr "IMP_camera_orientConstraint1_offsetX.o" "IMP_camera_orientConstraint1.ox" - ; -connectAttr "IMP_camera_orientConstraint1_offsetY.o" "IMP_camera_orientConstraint1.oy" - ; -connectAttr "IMP_camera_orientConstraint1_offsetZ.o" "IMP_camera_orientConstraint1.oz" - ; -connectAttr "IMP_locator14_visibility.o" "IMP_locator14.v"; -connectAttr "IMP_locator14_scaleX.o" "IMP_locator14.sx"; -connectAttr "IMP_locator14_scaleY.o" "IMP_locator14.sy"; -connectAttr "IMP_locator14_scaleZ.o" "IMP_locator14.sz"; -connectAttr "IMP_locator14_pointConstraint1_nodeState.o" "IMP_locator14_pointConstraint1.nds" - ; -connectAttr "IMP_locator14_pointConstraint1_HeadW0.o" "IMP_locator14_pointConstraint1.w0" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetX.o" "IMP_locator14_pointConstraint1.ox" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetY.o" "IMP_locator14_pointConstraint1.oy" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetZ.o" "IMP_locator14_pointConstraint1.oz" - ; -connectAttr "IMP_locator14_orientConstraint1_nodeState.o" "IMP_locator14_orientConstraint1.nds" - ; -connectAttr "IMP_locator14_orientConstraint1_HeadW0.o" "IMP_locator14_orientConstraint1.w0" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetX.o" "IMP_locator14_orientConstraint1.ox" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetY.o" "IMP_locator14_orientConstraint1.oy" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetZ.o" "IMP_locator14_orientConstraint1.oz" - ; -connectAttr "IMP_cam_connector_visibility.o" "IMP_cam_connector.v"; -connectAttr "IMP_cam_connector_translateX.o" "IMP_cam_connector.tx"; -connectAttr "IMP_cam_connector_translateY.o" "IMP_cam_connector.ty"; -connectAttr "IMP_cam_connector_translateZ.o" "IMP_cam_connector.tz"; -connectAttr "IMP_cam_connector_rotateX.o" "IMP_cam_connector.rx"; -connectAttr "IMP_cam_connector_rotateY.o" "IMP_cam_connector.ry"; -connectAttr "IMP_cam_connector_rotateZ.o" "IMP_cam_connector.rz"; -connectAttr "IMP_cam_connector_scaleX.o" "IMP_cam_connector.sx"; -connectAttr "IMP_cam_connector_scaleY.o" "IMP_cam_connector.sy"; -connectAttr "IMP_cam_connector_scaleZ.o" "IMP_cam_connector.sz"; -connectAttr "IMP_eyes_translateX.o" "IMP_eyes.tx"; -connectAttr "IMP_eyes_translateY.o" "IMP_eyes.ty"; -connectAttr "IMP_eyes_translateZ.o" "IMP_eyes.tz"; -connectAttr "IMP_eyes_rotateX.o" "IMP_eyes.rx"; -connectAttr "IMP_eyes_rotateY.o" "IMP_eyes.ry"; -connectAttr "IMP_eyes_rotateZ.o" "IMP_eyes.rz"; -connectAttr "IMP_eyes_visibility.o" "IMP_eyes.v"; -connectAttr "IMP_eyes_scaleX.o" "IMP_eyes.sx"; -connectAttr "IMP_eyes_scaleY.o" "IMP_eyes.sy"; -connectAttr "IMP_eyes_scaleZ.o" "IMP_eyes.sz"; -connectAttr "IMP_locator13_visibility.o" "IMP_locator13.v"; -connectAttr "IMP_locator13_translateX.o" "IMP_locator13.tx"; -connectAttr "IMP_locator13_translateY.o" "IMP_locator13.ty"; -connectAttr "IMP_locator13_translateZ.o" "IMP_locator13.tz"; -connectAttr "IMP_locator13_rotateX.o" "IMP_locator13.rx"; -connectAttr "IMP_locator13_rotateY.o" "IMP_locator13.ry"; -connectAttr "IMP_locator13_rotateZ.o" "IMP_locator13.rz"; -connectAttr "IMP_locator13_scaleX.o" "IMP_locator13.sx"; -connectAttr "IMP_locator13_scaleY.o" "IMP_locator13.sy"; -connectAttr "IMP_locator13_scaleZ.o" "IMP_locator13.sz"; -connectAttr "IMP_pCube1_visibility.o" "IMP_pCube1.v"; -connectAttr "IMP_pCube1_translateX.o" "IMP_pCube1.tx"; -connectAttr "IMP_pCube1_translateY.o" "IMP_pCube1.ty"; -connectAttr "IMP_pCube1_translateZ.o" "IMP_pCube1.tz"; -connectAttr "IMP_pCube1_rotateX.o" "IMP_pCube1.rx"; -connectAttr "IMP_pCube1_rotateY.o" "IMP_pCube1.ry"; -connectAttr "IMP_pCube1_rotateZ.o" "IMP_pCube1.rz"; -connectAttr "IMP_pCube1_scaleX.o" "IMP_pCube1.sx"; -connectAttr "IMP_pCube1_scaleY.o" "IMP_pCube1.sy"; -connectAttr "IMP_pCube1_scaleZ.o" "IMP_pCube1.sz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Rwing_thing_visibility.o" "IMP_Rwing_thing.v"; -connectAttr "IMP_Rwing_thing_scaleX.o" "IMP_Rwing_thing.sx"; -connectAttr "IMP_Rwing_thing_scaleY.o" "IMP_Rwing_thing.sy"; -connectAttr "IMP_Rwing_thing_scaleZ.o" "IMP_Rwing_thing.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Lwing_thing_visibility.o" "IMP_Lwing_thing.v"; -connectAttr "IMP_Lwing_thing_scaleX.o" "IMP_Lwing_thing.sx"; -connectAttr "IMP_Lwing_thing_scaleY.o" "IMP_Lwing_thing.sy"; -connectAttr "IMP_Lwing_thing_scaleZ.o" "IMP_Lwing_thing.sz"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Lwing_pointConstraint1_nodeState.o" "IMP_Lwing_pointConstraint1.nds" - ; -connectAttr "IMP_Lwing_pointConstraint1_Lwing_nullW0.o" "IMP_Lwing_pointConstraint1.w0" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetX.o" "IMP_Lwing_pointConstraint1.ox" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetY.o" "IMP_Lwing_pointConstraint1.oy" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetZ.o" "IMP_Lwing_pointConstraint1.oz" - ; -connectAttr "IMP_joint8_scaleX.o" "IMP_joint8.sx"; -connectAttr "IMP_joint8_scaleY.o" "IMP_joint8.sy"; -connectAttr "IMP_joint8_scaleZ.o" "IMP_joint8.sz"; -connectAttr "IMP_joint8_visibility.o" "IMP_joint8.v"; -connectAttr "IMP_joint7_visibility.o" "IMP_joint7.v"; -connectAttr "IMP_joint7_scaleX.o" "IMP_joint7.sx"; -connectAttr "IMP_joint7_scaleY.o" "IMP_joint7.sy"; -connectAttr "IMP_joint7_scaleZ.o" "IMP_joint7.sz"; -connectAttr "IMP_joint6_scaleX.o" "IMP_joint6.sx"; -connectAttr "IMP_joint6_scaleY.o" "IMP_joint6.sy"; -connectAttr "IMP_joint6_scaleZ.o" "IMP_joint6.sz"; -connectAttr "IMP_joint6_visibility.o" "IMP_joint6.v"; -connectAttr "IMP_joint9_visibility.o" "IMP_joint9.v"; -connectAttr "IMP_joint9_scaleX.o" "IMP_joint9.sx"; -connectAttr "IMP_joint9_scaleY.o" "IMP_joint9.sy"; -connectAttr "IMP_joint9_scaleZ.o" "IMP_joint9.sz"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_joint5_visibility.o" "IMP_joint5.v"; -connectAttr "IMP_joint5_scaleX.o" "IMP_joint5.sx"; -connectAttr "IMP_joint5_scaleY.o" "IMP_joint5.sy"; -connectAttr "IMP_joint5_scaleZ.o" "IMP_joint5.sz"; -connectAttr "IMP_Rwing4_scaleX.o" "IMP_Rwing4.sx"; -connectAttr "IMP_Rwing4_scaleY.o" "IMP_Rwing4.sy"; -connectAttr "IMP_Rwing4_scaleZ.o" "IMP_Rwing4.sz"; -connectAttr "IMP_Rwing4_visibility.o" "IMP_Rwing4.v"; -connectAttr "IMP_Rwing1_visibility.o" "IMP_Rwing1.v"; -connectAttr "IMP_Rwing1_scaleX.o" "IMP_Rwing1.sx"; -connectAttr "IMP_Rwing1_scaleY.o" "IMP_Rwing1.sy"; -connectAttr "IMP_Rwing1_scaleZ.o" "IMP_Rwing1.sz"; -connectAttr "IMP_Rwing_pointConstraint1_nodeState.o" "IMP_Rwing_pointConstraint1.nds" - ; -connectAttr "IMP_Rwing_pointConstraint1_Rwing_nullW0.o" "IMP_Rwing_pointConstraint1.w0" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetX.o" "IMP_Rwing_pointConstraint1.ox" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetY.o" "IMP_Rwing_pointConstraint1.oy" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetZ.o" "IMP_Rwing_pointConstraint1.oz" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_lelbow_visibility.o" "IMP_lelbow.v"; -connectAttr "IMP_lelbow_scaleX.o" "IMP_lelbow.sx"; -connectAttr "IMP_lelbow_scaleY.o" "IMP_lelbow.sy"; -connectAttr "IMP_lelbow_scaleZ.o" "IMP_lelbow.sz"; -connectAttr "IMP_locator3_pointConstraint1_nodeState.o" "IMP_locator3_pointConstraint1.nds" - ; -connectAttr "IMP_locator3_pointConstraint1_LloarmW0.o" "IMP_locator3_pointConstraint1.w0" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetX.o" "IMP_locator3_pointConstraint1.ox" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetY.o" "IMP_locator3_pointConstraint1.oy" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetZ.o" "IMP_locator3_pointConstraint1.oz" - ; -connectAttr "IMP_locator3_orientConstraint1_nodeState.o" "IMP_locator3_orientConstraint1.nds" - ; -connectAttr "IMP_locator3_orientConstraint1_LloarmW0.o" "IMP_locator3_orientConstraint1.w0" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetX.o" "IMP_locator3_orientConstraint1.ox" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetY.o" "IMP_locator3_orientConstraint1.oy" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetZ.o" "IMP_locator3_orientConstraint1.oz" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_relbow_visibility.o" "IMP_relbow.v"; -connectAttr "IMP_relbow_scaleX.o" "IMP_relbow.sx"; -connectAttr "IMP_relbow_scaleY.o" "IMP_relbow.sy"; -connectAttr "IMP_relbow_scaleZ.o" "IMP_relbow.sz"; -connectAttr "IMP_locator4_pointConstraint1_nodeState.o" "IMP_locator4_pointConstraint1.nds" - ; -connectAttr "IMP_locator4_pointConstraint1_RloarmW0.o" "IMP_locator4_pointConstraint1.w0" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetX.o" "IMP_locator4_pointConstraint1.ox" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetY.o" "IMP_locator4_pointConstraint1.oy" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetZ.o" "IMP_locator4_pointConstraint1.oz" - ; -connectAttr "IMP_locator4_orientConstraint1_nodeState.o" "IMP_locator4_orientConstraint1.nds" - ; -connectAttr "IMP_locator4_orientConstraint1_RloarmW0.o" "IMP_locator4_orientConstraint1.w0" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetX.o" "IMP_locator4_orientConstraint1.ox" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetY.o" "IMP_locator4_orientConstraint1.oy" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetZ.o" "IMP_locator4_orientConstraint1.oz" - ; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of jump_loop.ma diff --git a/base/models/monsters/imp/animation/cycles/jump_loop2.ma b/base/models/monsters/imp/animation/cycles/jump_loop2.ma deleted file mode 100644 index 1ef56066b..000000000 --- a/base/models/monsters/imp/animation/cycles/jump_loop2.ma +++ /dev/null @@ -1,8787 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:20 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: jump_loop2.ma -//Last modified: Sat, Mar 22, 2003 02:42:46 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Unlimited 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 605.15213440286334 53.833967769892041 7.2718052457910858 ; - setAttr ".r" -type "double3" -5.1301089067096974 -1714.199999999692 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 271.08733878669375; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 339.21072765353517 61.535235649362093 20.712041475033917 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 283.84778885232589 28.807279623574583 251.64906643421713 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 382.26842571335123; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 503.1108425748202 36.715032929366295 -23.867183619064008 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 223.86211087954965; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "group2"; - setAttr ".t" -type "double3" 297.75049857774576 -2.8421709430404007e-014 - 115.34478773732499 ; - setAttr ".rp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; - setAttr ".sp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode transform -n "pointLight2" -p "group2"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 20 -max 29 -ast 20 -aet 29 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.08568 20 -1.08568; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537988160630093 20 4.1537988160630093; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185075120832098 20 4.6185075120832098; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8119691574396866 20 -5.8119691574396866; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9186219656239931 20 5.9186219656239931; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.1258655568218376 20 -4.1258655568218376; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.085679155728795 20 1.085679155728795; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537911794025533 20 4.1537911794025533; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185070801020824 20 4.6185070801020824; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3244262317670241 20 -6.3244262317670241; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0332012531196431 20 1.0332012531196431; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.463963295533194 20 8.463963295533194; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 20 1 28 1 29 1 36 1 39 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.71946295727715 20 13.71946295727715 - 28 13.71946295727715 29 13.71946295727715 36 13.71946295727715 39 13.71946295727715 - 48 13.71946295727715; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 68.596496127541187 20 68.596496127541187 - 28 68.596496127541187 29 68.596496127541187 36 68.596496127541187 39 68.596496127541187 - 48 68.596496127541187; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -60.802874383230787 20 -60.802874383230787 - 28 -60.802874383230787 29 -60.802874383230787 36 -60.802874383230787 39 -60.802874383230787 - 48 -60.802874383230787; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -157.43468421330525 20 -157.43468421330525 - 28 -157.43468421330525 29 -157.43468421330525 36 -157.43468421330525 39 -157.43468421330525 - 48 -157.43468421330525; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459183 20 15.445123296459183 - 28 15.445123296459183 29 15.445123296459183 36 15.445123296459183 39 15.445123296459183 - 48 15.445123296459183; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 36 15.445123296459185 39 15.445123296459185 - 48 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459181 20 15.445123296459181 - 28 15.445123296459181 29 15.445123296459181 36 15.445123296459181 39 15.445123296459181 - 48 15.445123296459181; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 20 1 28 1 29 1 36 1 39 1 48 - 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.010024364806417531 20 0.21060231619815561 - 28 0.20000000000000001 29 0.21060231619815561 36 0.20000000000000001 39 0.096209918545383938 - 48 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.42673163973887457 20 1.0386541206168749 - 28 1 29 1.0386541206168749 36 1 39 0 48 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1 28 1 29 1 31 1 32 1 36 - 1 39 1 48 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.5294371750177831 20 -2.5294371750177831 - 28 -2.5294371750177831 29 -2.5294371750177831 31 -2.5294371750177831 32 -2.5294371750177831 - 36 -2.5294371750177831 39 -2.5294371750177831 48 -2.5294371750177831; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 13.481673551673362 20 13.481673551673362 - 28 13.481673551673362 29 13.481673551673362 31 13.481673551673362 32 13.481673551673362 - 36 13.481673551673362 39 13.481673551673362 48 13.481673551673362; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -0.26635088939205875 20 -0.26635088939205875 - 28 -0.26635088939205875 29 -0.26635088939205875 31 -0.26635088939205875 32 - -0.26635088939205875 36 -0.26635088939205875 39 -0.26635088939205875 48 -0.26635088939205875; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 73.167297059293915 20 73.167297059293915 - 28 73.167297059293915 29 73.167297059293915 31 73.167297059293915 32 73.167297059293915 - 36 73.167297059293915 39 73.167297059293915 48 73.167297059293915; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 61.241182877125034 20 61.241182877125034 - 28 61.241182877125034 29 61.241182877125034 31 61.241182877125034 32 61.241182877125034 - 36 61.241182877125034 39 61.241182877125034 48 61.241182877125034; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 177.69376467901077 20 177.69376467901077 - 28 177.69376467901077 29 177.69376467901077 31 177.69376467901077 32 177.69376467901077 - 36 177.69376467901077 39 177.69376467901077 48 177.69376467901077; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1 28 1 29 1 31 1 32 1 36 - 1 39 1 48 1; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0.53328935673265621 28 0.5 - 29 0.53328935673265621 31 0.54367346977328057 32 0.54064000626006248 36 0 - 39 0.62187499874627028 48 0.19999999999999996; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0 28 0 29 0 31 0 32 0 36 - 0 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 1.0599738906558223 28 1 - 29 1.0599738906558223 31 1.0653061208314818 32 0 36 1 39 1 48 1; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 19 1 20 1 24 1 26 1 29 - 1 30 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 142.98348776985753 11 142.98348776985753 - 19 142.98348776985753 20 191.26337083735385 24 323.16554587969301 26 370.7488378067593 - 29 424.66764999887118 30 420.62465938310265 31 427.05957900171768 32 425.30704005425184 - 36 428.11110237019716 37 432.46487722460995 39 452.48527341107649 42 467.68382734480741 - 48 463.64501189855395; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 29.138462584867199 11 29.138462584867199 - 19 27.007636541590745 20 50.99433076673629 24 64.122704384201199 26 67.673821000368392 - 29 50.99433076673629 30 35.823339310631809 31 33.823372152340816 32 28.03999362570373 - 36 32.771848783861358 37 31.592042718943524 39 39.094608524655982 42 50.000621409275169 - 48 64.878916548913807; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -64.436916064427393 11 -64.436916064427393 - 19 -64.436916064427393 20 -28.039483942373991 24 -22.809421473582191 26 -27.315202675304697 - 29 -28.039483942373991 30 -73.413769831276639 31 -61.599737051475088 32 -61.599737051475088 - 36 -61.599737051475088 37 -61.404340838912852 39 -61.599737051475088 42 -66.875434832292612 - 48 -72.305486080561622; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 219.80154311026268 11 219.80154311026268 - 19 219.80154311026268 20 358.04876736035584 24 372.9737147923201 26 365.36849059365238 - 29 358.04876736035584 30 402.3692513842521 31 399.75421244244444 32 361.75246976057394 - 36 388.54315471056964 37 382.12979672988405 39 446.2181411264944 42 470.82609984934618 - 48 441.51022981784752; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 103.06211582598448 11 103.06211582598448 - 19 103.06211582598448 20 155.91713557661092 24 154.99028448406145 26 154.87320782015533 - 29 155.91713557661092 30 160.53188760921961 31 128.89442661327502 32 128.8944266132749 - 36 130.20957118662795 37 126.422682041705 39 149.08574357438997 42 133.83971002200158 - 48 132.94446310792156; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 179.66289643582957 11 179.66289643582957 - 19 179.66289643582957 20 418.4296026462676 24 433.04458652607644 26 428.61629242164224 - 29 418.4296026462676 30 424.0923332662079 31 371.32760212837917 32 371.32760212837917 - 36 316.59454777258998 37 319.37663179388846 39 335.03872044309094 42 367.06275467923081 - 48 439.67161200383958; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 24 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 115.77674460548414 11 115.77674460548414 - 18 115.77674460548414 19 128.23278335184611 20 186.67237970682669 24 317.37616622813266 - 29 422.34271983107715 30 423.70984279183483 31 443.99727667219565 36 443.99727667219565 - 37 443.99727667219565 38 443.38906601627184 39 443.99727667219565 42 456.16149037302819 - 43 460.00331537229431 48 451.97121129722473; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 29.57010509969825 11 29.57010509969825 - 18 29.57010509969825 19 29.27089625396021 20 67.467475647037872 24 60.160080806453195 - 29 67.02301038508196 30 35.768974660229517 31 28.598876396236033 36 28.598876396236033 - 37 29.891609618591474 38 32.477481014791223 39 35.885190922239445 42 47.511691840001383 - 43 53.969285662101555 48 68.087166186099452; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 5.5906769424741611 11 5.5906769424741611 - 18 5.5906769424741611 19 7.7790374995743576 20 23.176181226346223 24 17.543464066542786 - 29 23.173230830419207 30 17.688799523426937 31 17.688799523426937 36 17.688799523426937 - 37 18.393926735620809 38 16.901407469018011 39 18.158884331556195 42 17.688799523426937 - 43 16.932203967017472 48 18.833156565013823; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -178.9145192530496 11 -178.9145192530496 - 18 -178.9145192530496 19 -167.69587374559055 20 -294.84643525493948 24 -343.93712456946542 - 29 -294.84643525493948 30 -295.55702963991496 31 -323.43616169739801 36 -323.43616169739801 - 37 -301.98736295612144 38 -294.1473764072087 39 -284.1852919748419 42 -215.34826646492581 - 43 -201.47174946737618 48 -256.50049062084815; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 77.792981530281054 11 77.792981530281054 - 18 77.792981530281054 19 77.792981530281097 20 56.583233323599366 24 35.558533015590569 - 29 56.583233323599366 30 56.539878395975578 31 67.318721800853339 36 67.318721800853339 - 37 64.350871231601133 38 67.126204716457593 39 67.31872180085341 42 38.522706263852164 - 43 35.653912925478181 48 18.052275906821958; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 146.44536767645329 11 146.44536767645329 - 18 146.44536767645329 19 146.44536767645334 20 97.316003029379416 24 108.00241227863057 - 29 97.316003029379416 30 92.774179834952406 31 39.044332496204468 36 39.044332496204468 - 37 42.18224322723831 38 39.690533059175472 39 39.044332496204518 42 60.637340161233091 - 43 65.527995150390169 48 23.269369027924608; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 20 0 25 0 29 0 30 - 0; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 11 5.6268319407172029 - 18 5.6268319407172029 20 5.6268319407172029 25 5.6268319407172029 29 5.6268319407172029 - 30 5.6268319407172029; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 11 -2.1098668596606802 - 18 -2.1098668596606802 20 -2.1098668596606802 25 -2.1098668596606802 29 -2.1098668596606802 - 30 -2.1098668596606802; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 360.76739391711288 11 336.00205489946853 - 18 342.74743969676229 20 337.91989796733282 25 336.93676059136885 29 337.91989796733282 - 30 375.1012001423897; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.39334696132271052 11 22.934613158314267 - 18 3.3751297566513738 20 -4.7482216885987958 25 -5.4065782212421292 29 -4.7482216885987958 - 30 1.1508514452864969; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -18.700472818991617 11 -35.808201433501473 - 18 -4.0181375389538863 20 8.3047565270522217 25 15.795646702355084 29 8.3047565270522217 - 30 16.328915349246685; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 7.1689522478599494 13 7.1689522478599494 - 16 7.1689522478599503 19 7.1689522478599503 20 6.925456265951996 24 8.7983283713503688 - 26 11.018796760141813 29 6.9254562659520378 30 6.9254562659520369 34 6.9254562659520369 - 38 7.554986848268765; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 14.562786750258176 13 14.562786750258176 - 16 14.562786750258176 19 13.842211007852075 20 20.923245467494844 24 22.750319749983092 - 26 18.178738536249831 29 20.923245467494844 30 13.359586698238232 34 13.673824607627459 - 38 14.11106435922871; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 96.133649094344804 13 96.133649094344804 - 16 108.69386808893657 19 108.69386808893657 20 119.35821919539188 24 227.16912977936141 - 26 261.36084706164974 29 307.0458635573579 30 333.39863420942874 34 333.39863420942874 - 38 377.18147202625158; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -174.49049195404214 13 -174.49049195404214 - 16 -174.49049195404214 19 -174.49049195404214 20 -80.195825489861193 24 -301.53506754966133 - 26 -100.27785478110128 29 -80.195825489861193 30 10.11833837859974 34 10.11833837859974 - 38 6.0578085460824589; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 129.78625356110399 13 129.78625356110399 - 16 129.78625356110399 19 129.78625356110399 20 1.4379585757962667 24 156.57861554381626 - 26 32.210181397685318 29 1.4379585757962667 30 22.148402438321622 34 22.148402438321622 - 38 14.559598429561929; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -169.93906815090079 13 -169.93906815090079 - 16 -169.93906815090079 19 -169.93906815090079 20 -29.493568390973312 24 -201.27457036315781 - 26 -29.967697144210206 29 -29.493568390973312 30 8.7946878310934409 34 8.7946878310934409 - 38 8.2507937920490004; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 125.1606853982252 20 125.1606853982252 - 29 125.1606853982252; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 77.825664227235052 20 77.825664227235052 - 29 77.825664227235052; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -175.25743303308352 20 -175.25743303308352 - 29 -175.25743303308352; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; - setAttr -s 9 ".kot[3:8]" 5 9 5 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -7.3924057183505028 7 -7.3924057183505019 - 19 -7.3924057183505019 20 -6.9176833889325122 24 -6.2589266759223765 29 -6.916667322061806 - 30 -6.3308105672263544 34 -6.3308105672263544 38 -7.1642625370327009; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.840283259770729 7 9.4070003601017547 - 19 9.4070003356835699 20 11.196614583528255 24 16.336583444843768 29 10.625810794831406 - 30 9.8084023440544854 34 10.14635638156529 38 10.992193194026985; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 76.997633470219824 7 99.667297021434308 - 19 99.667297021434308 20 121.48715069975222 24 219.36892594278427 29 311.00354071483548 - 30 333.23005140887722 34 333.23005140887722 38 377.1632664084907; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -18.39795914825002 7 21.526450659699222 - 19 21.526450659699222 20 -40.037064876295929 24 -146.39991688279261 29 -40.037064876295929 - 30 15.958661750368087 34 15.958661750368087 38 12.355198312075999; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -48.06590236816033 7 -38.053954061890678 - 19 -38.053954061890678 20 -38.321160312802654 24 -29.684032640488194 29 -38.321160312802654 - 30 -38.059156299065826 34 -38.059156299065826 38 -35.152508962264037; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 7.7650564355670078 7 -10.667864335873874 - 19 -10.667864335873874 20 -5.1515784092334673 24 25.709605253119321 29 -5.1515784092334673 - 30 -11.009931379047687 34 -11.009931379047687 38 -11.865112406666784; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 9 1 13 1 18 1 20 1 24 1 28 - 1 29 1 30 1 33 1 37 1 42 1 48 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 2.5125681904581358 9 1.9808213950621905 - 13 1.9808213950621907 18 9.2715722022641724 20 2.0464370519482591 24 1.9808213950622344 - 28 1.9808213950622338 29 1.9808213950622362 30 1.9808213950622389 33 1.9808213950622422 - 37 1.9808213950622449 42 1.9808213950622469 48 1.9808213950622469; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 49.057951687626066 9 46.233318687395005 - 13 43.306536510238651 18 43.306536510238651 20 35.290216119765219 24 36.66720358350176 - 28 35.312644657012214 29 35.289789669868796 30 42.450288337009852 33 43.630641520076964 - 37 60.430686497730626 42 54.094786172201999 48 61.311043210496877; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 96.110338887997557 9 101.4151315840935 - 13 107.81746759662305 18 107.81746759662305 20 135.58394463251807 24 244.33339068178299 - 28 310.95588426834991 29 324.1770843528858 30 333.64740089743867 33 347.87539237621274 - 37 360.25559275384734 42 369.39210044166862 48 369.39210044166862; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 22.565311747406891 9 42.315017092753621 - 13 36.358132000694155 18 36.358132000694155 20 0.49705284723442805 24 0.49705284723442805 - 28 0.49705284723442805 29 0.49705284723442805 30 0.49705284723442805 33 0.49705284723442805 - 37 0.49705284723442805 42 -42.6591147393315 48 -42.6591147393315; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 7.9513867036587919e-016 9 0 13 - 0 18 0 20 11.49524675155142 24 11.49524675155142 28 11.49524675155142 29 - 11.49524675155142 30 11.49524675155142 33 11.49524675155142 37 11.49524675155142 - 42 11.495246751551425 48 11.495246751551425; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 7.4260738755503892 9 7.426073875550375 - 13 7.4260738755503644 18 7.4260738755503644 20 -20.965676744725002 24 -20.965676744725002 - 28 -20.965676744725002 29 -20.965676744725002 30 -20.965676744725002 33 -20.965676744725002 - 37 -20.965676744725002 42 -20.965676744725013 48 -20.965676744725013; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 9 1 13 1 18 1 20 1 24 1 28 - 1 29 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 9 1 13 1 18 1 20 1 24 1 28 - 1 29 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 9 1 13 1 18 1 20 1 24 1 28 - 1 29 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21285352564148119; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15078676416754505; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15149042747921673; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.90991990467137285 13 0.90991990467137285 - 17 0.90991990467137285 19 3.2165938865377592 20 3.2165938865377592 25 3.2165938865377592 - 29 3.2165938865377592 30 3.2165938865377592 36 3.2165938865377592 42 3.2165938865377592 - 48 3.2165938865377592; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.6840963091226424 13 1.6840963091226424 - 17 1.6840963091226424 19 1.0198173250982352 20 1.0198173250982352 25 1.0198173250982352 - 29 1.0198173250982352 30 1.0198173250982352 36 1.0198173250982352 42 1.0198173250982352 - 48 1.0198173250982352; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.8509277672757398 13 2.8509277672757398 - 17 2.8509277672757398 19 5.5089484635562949 20 5.5089484635562949 25 5.5089484635562949 - 29 5.5089484635562949 30 5.5089484635562949 36 5.5089484635562949 42 5.5089484635562949 - 48 5.5089484635562949; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -81.50691442197396 13 -31.261146897838977 - 17 -76.052449399988134 19 14.028238821473778 20 12.673536893584014 25 -10.92851419478561 - 29 12.673536893584014 30 -84.048401441518692 36 -100.98950409530727 42 -55.664830857165363 - 48 -37.750911612187679; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 30.964642776910992 13 16.829153229070521 - 17 17.998418905573541 19 61.793759660292352 20 0.86649866220487337 25 3.760929659062147 - 29 0.86649866220487337 30 -3.8527038109155853 36 2.9181746341270869 42 8.3717076859878041 - 48 21.674975974628239; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.8358968951012837 13 6.4562833550431655 - 17 -20.729425848392836 19 20.568981510619366 20 -24.976998968181309 25 -26.877955074762507 - 29 -24.976998968181309 30 -3.3299002212729572 36 -35.030428448148584 42 -3.6057329631056776 - 48 -6.3849825779711411; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 10 0 17 0 19 0 20 0 22 0 30 - 0 35 0 48 0; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.3128351505039433 10 2.3128351505039433 - 17 2.3128351505039433 19 2.3128351505039433 20 2.3128351505039433 22 2.3128351505039433 - 30 2.3128351505039433 35 2.3128351505039433 48 2.3128351505039433; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.23421866920666501 10 0.23421866920666501 - 17 0.23421866920666501 19 0.23421866920666501 20 0.23421866920666501 22 0.23421866920666501 - 30 0.23421866920666501 35 0.23421866920666501 48 0.23421866920666501; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.671711834718816 10 -3.671711834718816 - 17 -0.38903580510386404 19 24.430204060920861 20 26.154517719026376 22 20.858840660148381 - 30 27.159710134283735 35 33.513181175101714 48 16.877903135718185; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -30.925240358666347 10 -30.925240358666347 - 17 -8.0093455226114028 19 -36.190660550952373 20 20.225914021857086 22 12.125593470464233 - 30 21.141076518420324 35 21.151855214980227 48 -2.7299381262472755; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 24.795614393044964 10 24.795614393044964 - 17 28.310029710143734 19 11.117279450806294 20 13.30559106872983 22 1.7686655262962976 - 30 15.451645632735099 35 28.619674064500245 48 0.26452410412025396; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 24 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0.27427147149852044 11 0.27427147153653575 - 12 0.27427147153797948 13 0.27427147153980314 14 0.27427147154217391 15 0.2742714715453653 - 16 0.27427147154983328 17 0.27427147155621612 18 0.27427147156259896 19 0.27427147156259896 - 20 0.27427147156259896 24 0.27427147156259896 29 0.27427147156259896 32 0.27427147156259896 - 38 0.27427147156259896 48 0.27427147156259896; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -1.1074984126668126 11 -1.1074984146392313 - 12 -1.1074984147141391 13 -1.1074984148087597 14 -1.1074984149317662 15 -1.1074984150973519 - 16 -1.107498415329172 17 -1.1074984156603436 18 -1.1074984159915151 19 -1.1074984159915151 - 20 -1.1074984159915151 24 -1.1074984159915151 29 -1.1074984159915151 32 -1.1074984159915151 - 38 -1.1074984159915151 48 -1.1074984159915151; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -1.642626684874722 11 -1.6426266835385228 - 12 -1.6426266834877772 13 -1.6426266834236773 14 -1.6426266833403476 15 -1.6426266832281728 - 16 -1.642626683071128 17 -1.6426266828467784 18 -1.6426266826224289 19 -1.6426266826224289 - 20 -1.6426266826224289 24 -1.6426266826224289 29 -1.6426266826224289 32 -1.6426266826224289 - 38 -1.6426266826224289 48 -1.6426266826224289; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 24 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -37.815214478634331 11 -125.74912876606732 - 12 -125.51192920989145 13 -100.00216573212361 14 -59.835637123346231 15 -36.233993668944173 - 16 -35.413141578212446 17 -49.792207316432325 18 -114.59155902616467 19 -86.44861012607744 - 20 -18.911188309049191 24 -42.937392967796441 29 -18.911188309049191 32 -57.295779513082323 - 38 -59.587610693605619 48 -83.651838089100195; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.2742786288673521 10 -0.27427863453231033 - 17 -0.27427863453231033 18 -0.27427863453231033 19 -0.27427863453231033 20 - -0.27427863453231033 24 -0.27427863453231033 29 -0.27427863453231033 35 -0.27427863453231033 - 48 -0.27427863453231033; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.1075115373407667 10 -1.1075115557303763 - 17 -1.1075115557303763 18 -1.1075115557303763 19 -1.1075115557303763 20 -1.1075115557303763 - 24 -1.1075115557303763 29 -1.1075115557303763 35 -1.1075115557303763 48 -1.1075115557303763; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.6426166407301896 10 -1.6426166273853338 - 17 -1.6426166273853338 18 -1.6426166273853338 19 -1.6426166273853338 20 -1.6426166273853338 - 24 -1.6426166273853338 29 -1.6426166273853338 35 -1.6426166273853338 48 -1.6426166273853338; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 108.86198107485642 10 108.86198107485642 - 17 73.338597776745388 18 26.403355291791605 19 54.852317270957315 20 17.797350596899509 - 24 34.98949021968803 29 17.797350596899509 35 29.793805346802827 48 61.879441874128936; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.14201183279855 20 1.0099431818894913 - 28 1 29 1.0099431818894913 36 1 39 0 48 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1.0110080399545431 28 1 - 29 1.0110080399545431 31 1.0367346951942145 32 1 36 1 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0 28 0 29 0 31 0 32 0 36 - 0 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 11 1 18 1 20 1 27 1 34 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -28.073881032405502 6 -46.403838232154726 - 11 -57.268694860493916 18 -64.448733245059486 20 -85.021389942138228 27 -96.759313977435809 - 34 -81.70071573151256 48 -92.276866801256645; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -61.199228718418333 6 -52.589856193268211 - 11 -48.400115258246736 18 -43.995383780771014 20 -56.304528730735143 27 -41.2276998033512 - 34 -55.139126251391993 48 -76.844287356428978; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -81.184232108591999 6 -75.778137454888423 - 11 -62.491121494028498 18 -64.875827156229477 20 -23.876400721722792 27 -34.093153518684247 - 34 -33.172769882599198 48 -6.4131326743179056; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 19 1 22 1 29 1 34 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -117.99254693569441 13 -123.98803296810649 - 19 -131.56223464759714 22 -143.68624235845436 29 -118.25457552859019 34 -118.19943411562497 - 48 -137.79238049393118; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 27.075624429458429 13 25.391307459182691 - 19 20.623216711056333 22 37.500675079600633 29 12.160180912642328 34 24.003088726248219 - 48 55.642180590844198; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -35.130967703309707 13 -76.878252144223026 - 19 -53.588570440441174 22 -49.075623471088711 29 -63.575828601904099 34 -35.895713294177334 - 48 -20.939120123829618; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.90858890976581275 20 -0.90858890976581275; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.2382713968077237 20 6.2382713968077237; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.55501859990651525 20 -0.55501859990651525; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -22.350064437213423 20 -22.350064437213423; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -10.303773027856268 20 -10.303773027856268; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.8115085199100047 20 8.8115085199100047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 24 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0.99999999999999978 11 0.99999999999999978 - 18 0.99999999999999978 19 0.99999999999999978 20 0.99999999999999978 24 0.99999999999999978 - 29 0.99999999999999978 30 0.99999999999999978 31 0.99999999999999978 36 0.99999999999999978 - 37 0.99999999999999978 38 0.99999999999999978 39 0.99999999999999978 42 0.99999999999999978 - 43 0.99999999999999978 48 0.99999999999999978; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 24 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 19 1 20 1 24 1 26 1 29 - 1 30 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.99999999999999989 11 0.99999999999999989 - 19 0.99999999999999989 20 0.99999999999999989 24 0.99999999999999989 26 0.99999999999999989 - 29 0.99999999999999989 30 0.99999999999999989 31 0.99999999999999989 32 0.99999999999999989 - 36 0.99999999999999989 37 0.99999999999999989 39 0.99999999999999989 42 0.99999999999999989 - 48 0.99999999999999989; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978 20 0.99999999999999978 24 0.99999999999999978 26 0.99999999999999978 - 29 0.99999999999999978 30 0.99999999999999978 31 0.99999999999999978 32 0.99999999999999978 - 36 0.99999999999999978 37 0.99999999999999978 39 0.99999999999999978 42 0.99999999999999978 - 48 0.99999999999999978; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_locator5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_camera_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator14_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_Rwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_lelbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_lelbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_relbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.1057240879120851; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5956396785200369; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3817563473270154; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41001647724799928; -createNode animCurveTL -n "IMP_Lmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1693934765127816; -createNode animCurveTL -n "IMP_Lmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5729514457211735; -createNode animCurveTA -n "IMP_Lmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_pointConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_orientConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_cam_connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0046539604129529621; -createNode animCurveTL -n "IMP_cam_connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4094890802521576; -createNode animCurveTL -n "IMP_cam_connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0367577756137232; -createNode animCurveTA -n "IMP_cam_connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.11875208173462; -createNode animCurveTA -n "IMP_cam_connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085761516203950224; -createNode animCurveTA -n "IMP_cam_connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1776791248832486e-005; -createNode animCurveTU -n "IMP_cam_connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_eyes_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.034284369950123843; -createNode animCurveTL -n "IMP_eyes_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9944975057013083; -createNode animCurveTL -n "IMP_eyes_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.9109443986143884; -createNode animCurveTA -n "IMP_eyes_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -147.00752219093516; -createNode animCurveTA -n "IMP_eyes_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_eyes_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 180; -createNode animCurveTU -n "IMP_eyes_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_eyes_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator13_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.0032893248995669033; -createNode animCurveTL -n "IMP_locator13_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.42074550807650996; -createNode animCurveTL -n "IMP_locator13_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -88.322777837915837; -createNode animCurveTA -n "IMP_locator13_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 179.72494022541443; -createNode animCurveTA -n "IMP_locator13_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085757562239429132; -createNode animCurveTA -n "IMP_locator13_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -179.99989705255965; -createNode animCurveTU -n "IMP_locator13_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0000000000000002; -createNode animCurveTU -n "IMP_locator13_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 87.843121583379272; -createNode animCurveTU -n "IMP_pCube1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_pCube1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.04673741311718338; -createNode animCurveTL -n "IMP_pCube1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.018550086981591107; -createNode animCurveTL -n "IMP_pCube1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.59134881205267886; -createNode animCurveTA -n "IMP_pCube1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_pCube1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.81452695663524144; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.5258192723085173 20 5.5258192723085173; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.1525507362789047 20 1.1525507362789047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.1924108426844384 20 1.1924108426844384; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.3533140211779946 20 6.3533140211779946; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.74525677667777757 20 0.74525677667777757; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.8072476834435935 20 1.8072476834435935; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 9.022004834100839 20 9.022004834100839; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.9550621233059426 20 1.9550621233059426; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.88597689344963537 20 -0.88597689344963537; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.9684923358091311 20 -3.9684923358091311; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.2916645882841449 20 2.2916645882841449; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.7296155549506897 20 4.7296155549506897; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.1608864069345106 20 2.1608864069345106; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.0054669522092379 20 -3.0054669522092379; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 28.836234092176063 20 11.07349067527878; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.5988200593703294 20 -53.841918861092552; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 52.351071907336284 20 -25.947600690391031; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.412879749935719 20 12.412879749935719; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.7286993982861674 20 -6.7286993982861674; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.868763862603668 20 -3.868763862603668; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -34.36059369489287 20 42.922644402952855; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -8.556853256702178 20 8.5989866823062808; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -23.206907965932974 20 27.627511712669737; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.890532588149956 20 12.890532588149956; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.69008032694306476 20 -0.69008032694306476; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.645694319339265 20 4.645694319339265; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.4675296479599407 20 -5.4675296479599407; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.0844803122567583 20 2.0844803122567583; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.0869908056348607 20 -3.0869908056348607; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 26.659954467743521 20 35.929156953403414; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -49.492801424012306 20 58.495495793078319; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -100.40231940259616 20 35.62217186926501; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.41287000000041 20 -12.41287000000041; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.7285999999993047 20 -6.7285999999993047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.8687599999999316 20 -3.8687599999999316; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 33.257666229421972 20 74.138445451041335; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 -1.1463794921978937e-014; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.5092015178261011 20 -21.198042374621632; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.890500000000031 20 -12.890500000000031; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.6900999999992341 20 -0.6900999999992341; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6456900000000347 20 4.6456900000000347; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.0846345617354372 20 -4.0846345617354372; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.282468147773308 20 4.282468147773308; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.7712681071056613 20 7.7712681071056613; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.4264261331675518 20 4.4264261331675518; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.3937238431314825 20 4.3937238431314825; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.7712681071056613 20 7.7712681071056613; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 9.2053053109380052; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.55189552941641418; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0646191166984784; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 11.586085933787016; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 23.165861309280317; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 73.16163459057924; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 89.830862630651069; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1568819853431291; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.8855564166933343; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -76.090633252486683; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.791362663024994; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 54.744021489634264; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 113.88179442110163; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.88642296005711507; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -16.683497590890667; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 99.194475901955684 20 99.194475901955684 - 29 99.194475901955684; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 69.492034696563493 20 69.492034696563493 - 29 69.492034696563493; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 52.003739368178465 20 52.003739368178465 - 29 52.003739368178465; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 217.7239621497128 20 217.7239621497128 - 29 217.7239621497128; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.7373203203190113; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4972392481870522; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6496305501990709; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 62.667511380374542; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -13.204130585379209; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 40.323400206122145; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_Lwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint8_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint7_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint9_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_Rwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -select -ne :time1; - setAttr ".o" 21; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933713 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Waist; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643403 -66.654599961471263 -11.653334128372219 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; -select -ne IMP_RHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_locator5_visibility.o" "IMP_locator5.v"; -connectAttr "IMP_locator5_scaleX.o" "IMP_locator5.sx"; -connectAttr "IMP_locator5_scaleY.o" "IMP_locator5.sy"; -connectAttr "IMP_locator5_scaleZ.o" "IMP_locator5.sz"; -connectAttr "IMP_locator5_pointConstraint1_nodeState.o" "IMP_locator5_pointConstraint1.nds" - ; -connectAttr "IMP_locator5_pointConstraint1_RhandW0.o" "IMP_locator5_pointConstraint1.w0" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetX.o" "IMP_locator5_pointConstraint1.ox" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetY.o" "IMP_locator5_pointConstraint1.oy" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetZ.o" "IMP_locator5_pointConstraint1.oz" - ; -connectAttr "IMP_locator5_orientConstraint1_nodeState.o" "IMP_locator5_orientConstraint1.nds" - ; -connectAttr "IMP_locator5_orientConstraint1_RhandW0.o" "IMP_locator5_orientConstraint1.w0" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetX.o" "IMP_locator5_orientConstraint1.ox" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetY.o" "IMP_locator5_orientConstraint1.oy" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetZ.o" "IMP_locator5_orientConstraint1.oz" - ; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_locator6_visibility.o" "IMP_locator6.v"; -connectAttr "IMP_locator6_scaleX.o" "IMP_locator6.sx"; -connectAttr "IMP_locator6_scaleY.o" "IMP_locator6.sy"; -connectAttr "IMP_locator6_scaleZ.o" "IMP_locator6.sz"; -connectAttr "IMP_locator6_pointConstraint1_nodeState.o" "IMP_locator6_pointConstraint1.nds" - ; -connectAttr "IMP_locator6_pointConstraint1_LhandW0.o" "IMP_locator6_pointConstraint1.w0" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetX.o" "IMP_locator6_pointConstraint1.ox" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetY.o" "IMP_locator6_pointConstraint1.oy" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetZ.o" "IMP_locator6_pointConstraint1.oz" - ; -connectAttr "IMP_locator6_orientConstraint1_nodeState.o" "IMP_locator6_orientConstraint1.nds" - ; -connectAttr "IMP_locator6_orientConstraint1_LhandW0.o" "IMP_locator6_orientConstraint1.w0" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetX.o" "IMP_locator6_orientConstraint1.ox" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetY.o" "IMP_locator6_orientConstraint1.oy" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetZ.o" "IMP_locator6_orientConstraint1.oz" - ; -connectAttr "IMP_Lmissile_visibility.o" "IMP_Lmissile.v"; -connectAttr "IMP_Lmissile_translateX.o" "IMP_Lmissile.tx"; -connectAttr "IMP_Lmissile_translateY.o" "IMP_Lmissile.ty"; -connectAttr "IMP_Lmissile_translateZ.o" "IMP_Lmissile.tz"; -connectAttr "IMP_Lmissile_rotateX.o" "IMP_Lmissile.rx"; -connectAttr "IMP_Lmissile_rotateY.o" "IMP_Lmissile.ry"; -connectAttr "IMP_Lmissile_rotateZ.o" "IMP_Lmissile.rz"; -connectAttr "IMP_Lmissile_scaleX.o" "IMP_Lmissile.sx"; -connectAttr "IMP_Lmissile_scaleY.o" "IMP_Lmissile.sy"; -connectAttr "IMP_Lmissile_scaleZ.o" "IMP_Lmissile.sz"; -connectAttr "IMP_camera_visibility.o" "IMP_camera.v"; -connectAttr "IMP_camera_scaleX.o" "IMP_camera.sx"; -connectAttr "IMP_camera_scaleY.o" "IMP_camera.sy"; -connectAttr "IMP_camera_scaleZ.o" "IMP_camera.sz"; -connectAttr "IMP_camera_pointConstraint1_nodeState.o" "IMP_camera_pointConstraint1.nds" - ; -connectAttr "IMP_camera_pointConstraint1_eyesW0.o" "IMP_camera_pointConstraint1.w0" - ; -connectAttr "IMP_camera_pointConstraint1_offsetX.o" "IMP_camera_pointConstraint1.ox" - ; -connectAttr "IMP_camera_pointConstraint1_offsetY.o" "IMP_camera_pointConstraint1.oy" - ; -connectAttr "IMP_camera_pointConstraint1_offsetZ.o" "IMP_camera_pointConstraint1.oz" - ; -connectAttr "IMP_camera_orientConstraint1_nodeState.o" "IMP_camera_orientConstraint1.nds" - ; -connectAttr "IMP_camera_orientConstraint1_eyesW0.o" "IMP_camera_orientConstraint1.w0" - ; -connectAttr "IMP_camera_orientConstraint1_offsetX.o" "IMP_camera_orientConstraint1.ox" - ; -connectAttr "IMP_camera_orientConstraint1_offsetY.o" "IMP_camera_orientConstraint1.oy" - ; -connectAttr "IMP_camera_orientConstraint1_offsetZ.o" "IMP_camera_orientConstraint1.oz" - ; -connectAttr "IMP_locator14_visibility.o" "IMP_locator14.v"; -connectAttr "IMP_locator14_scaleX.o" "IMP_locator14.sx"; -connectAttr "IMP_locator14_scaleY.o" "IMP_locator14.sy"; -connectAttr "IMP_locator14_scaleZ.o" "IMP_locator14.sz"; -connectAttr "IMP_locator14_pointConstraint1_nodeState.o" "IMP_locator14_pointConstraint1.nds" - ; -connectAttr "IMP_locator14_pointConstraint1_HeadW0.o" "IMP_locator14_pointConstraint1.w0" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetX.o" "IMP_locator14_pointConstraint1.ox" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetY.o" "IMP_locator14_pointConstraint1.oy" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetZ.o" "IMP_locator14_pointConstraint1.oz" - ; -connectAttr "IMP_locator14_orientConstraint1_nodeState.o" "IMP_locator14_orientConstraint1.nds" - ; -connectAttr "IMP_locator14_orientConstraint1_HeadW0.o" "IMP_locator14_orientConstraint1.w0" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetX.o" "IMP_locator14_orientConstraint1.ox" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetY.o" "IMP_locator14_orientConstraint1.oy" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetZ.o" "IMP_locator14_orientConstraint1.oz" - ; -connectAttr "IMP_cam_connector_visibility.o" "IMP_cam_connector.v"; -connectAttr "IMP_cam_connector_translateX.o" "IMP_cam_connector.tx"; -connectAttr "IMP_cam_connector_translateY.o" "IMP_cam_connector.ty"; -connectAttr "IMP_cam_connector_translateZ.o" "IMP_cam_connector.tz"; -connectAttr "IMP_cam_connector_rotateX.o" "IMP_cam_connector.rx"; -connectAttr "IMP_cam_connector_rotateY.o" "IMP_cam_connector.ry"; -connectAttr "IMP_cam_connector_rotateZ.o" "IMP_cam_connector.rz"; -connectAttr "IMP_cam_connector_scaleX.o" "IMP_cam_connector.sx"; -connectAttr "IMP_cam_connector_scaleY.o" "IMP_cam_connector.sy"; -connectAttr "IMP_cam_connector_scaleZ.o" "IMP_cam_connector.sz"; -connectAttr "IMP_eyes_translateX.o" "IMP_eyes.tx"; -connectAttr "IMP_eyes_translateY.o" "IMP_eyes.ty"; -connectAttr "IMP_eyes_translateZ.o" "IMP_eyes.tz"; -connectAttr "IMP_eyes_rotateX.o" "IMP_eyes.rx"; -connectAttr "IMP_eyes_rotateY.o" "IMP_eyes.ry"; -connectAttr "IMP_eyes_rotateZ.o" "IMP_eyes.rz"; -connectAttr "IMP_eyes_visibility.o" "IMP_eyes.v"; -connectAttr "IMP_eyes_scaleX.o" "IMP_eyes.sx"; -connectAttr "IMP_eyes_scaleY.o" "IMP_eyes.sy"; -connectAttr "IMP_eyes_scaleZ.o" "IMP_eyes.sz"; -connectAttr "IMP_locator13_visibility.o" "IMP_locator13.v"; -connectAttr "IMP_locator13_translateX.o" "IMP_locator13.tx"; -connectAttr "IMP_locator13_translateY.o" "IMP_locator13.ty"; -connectAttr "IMP_locator13_translateZ.o" "IMP_locator13.tz"; -connectAttr "IMP_locator13_rotateX.o" "IMP_locator13.rx"; -connectAttr "IMP_locator13_rotateY.o" "IMP_locator13.ry"; -connectAttr "IMP_locator13_rotateZ.o" "IMP_locator13.rz"; -connectAttr "IMP_locator13_scaleX.o" "IMP_locator13.sx"; -connectAttr "IMP_locator13_scaleY.o" "IMP_locator13.sy"; -connectAttr "IMP_locator13_scaleZ.o" "IMP_locator13.sz"; -connectAttr "IMP_pCube1_visibility.o" "IMP_pCube1.v"; -connectAttr "IMP_pCube1_translateX.o" "IMP_pCube1.tx"; -connectAttr "IMP_pCube1_translateY.o" "IMP_pCube1.ty"; -connectAttr "IMP_pCube1_translateZ.o" "IMP_pCube1.tz"; -connectAttr "IMP_pCube1_rotateX.o" "IMP_pCube1.rx"; -connectAttr "IMP_pCube1_rotateY.o" "IMP_pCube1.ry"; -connectAttr "IMP_pCube1_rotateZ.o" "IMP_pCube1.rz"; -connectAttr "IMP_pCube1_scaleX.o" "IMP_pCube1.sx"; -connectAttr "IMP_pCube1_scaleY.o" "IMP_pCube1.sy"; -connectAttr "IMP_pCube1_scaleZ.o" "IMP_pCube1.sz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_Rwing_thing_visibility.o" "IMP_Rwing_thing.v"; -connectAttr "IMP_Rwing_thing_scaleX.o" "IMP_Rwing_thing.sx"; -connectAttr "IMP_Rwing_thing_scaleY.o" "IMP_Rwing_thing.sy"; -connectAttr "IMP_Rwing_thing_scaleZ.o" "IMP_Rwing_thing.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Lwing_thing_visibility.o" "IMP_Lwing_thing.v"; -connectAttr "IMP_Lwing_thing_scaleX.o" "IMP_Lwing_thing.sx"; -connectAttr "IMP_Lwing_thing_scaleY.o" "IMP_Lwing_thing.sy"; -connectAttr "IMP_Lwing_thing_scaleZ.o" "IMP_Lwing_thing.sz"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Lwing_pointConstraint1_nodeState.o" "IMP_Lwing_pointConstraint1.nds" - ; -connectAttr "IMP_Lwing_pointConstraint1_Lwing_nullW0.o" "IMP_Lwing_pointConstraint1.w0" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetX.o" "IMP_Lwing_pointConstraint1.ox" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetY.o" "IMP_Lwing_pointConstraint1.oy" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetZ.o" "IMP_Lwing_pointConstraint1.oz" - ; -connectAttr "IMP_joint8_scaleX.o" "IMP_joint8.sx"; -connectAttr "IMP_joint8_scaleY.o" "IMP_joint8.sy"; -connectAttr "IMP_joint8_scaleZ.o" "IMP_joint8.sz"; -connectAttr "IMP_joint8_visibility.o" "IMP_joint8.v"; -connectAttr "IMP_joint7_visibility.o" "IMP_joint7.v"; -connectAttr "IMP_joint7_scaleX.o" "IMP_joint7.sx"; -connectAttr "IMP_joint7_scaleY.o" "IMP_joint7.sy"; -connectAttr "IMP_joint7_scaleZ.o" "IMP_joint7.sz"; -connectAttr "IMP_joint6_scaleX.o" "IMP_joint6.sx"; -connectAttr "IMP_joint6_scaleY.o" "IMP_joint6.sy"; -connectAttr "IMP_joint6_scaleZ.o" "IMP_joint6.sz"; -connectAttr "IMP_joint6_visibility.o" "IMP_joint6.v"; -connectAttr "IMP_joint9_visibility.o" "IMP_joint9.v"; -connectAttr "IMP_joint9_scaleX.o" "IMP_joint9.sx"; -connectAttr "IMP_joint9_scaleY.o" "IMP_joint9.sy"; -connectAttr "IMP_joint9_scaleZ.o" "IMP_joint9.sz"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_joint5_visibility.o" "IMP_joint5.v"; -connectAttr "IMP_joint5_scaleX.o" "IMP_joint5.sx"; -connectAttr "IMP_joint5_scaleY.o" "IMP_joint5.sy"; -connectAttr "IMP_joint5_scaleZ.o" "IMP_joint5.sz"; -connectAttr "IMP_Rwing4_scaleX.o" "IMP_Rwing4.sx"; -connectAttr "IMP_Rwing4_scaleY.o" "IMP_Rwing4.sy"; -connectAttr "IMP_Rwing4_scaleZ.o" "IMP_Rwing4.sz"; -connectAttr "IMP_Rwing4_visibility.o" "IMP_Rwing4.v"; -connectAttr "IMP_Rwing1_visibility.o" "IMP_Rwing1.v"; -connectAttr "IMP_Rwing1_scaleX.o" "IMP_Rwing1.sx"; -connectAttr "IMP_Rwing1_scaleY.o" "IMP_Rwing1.sy"; -connectAttr "IMP_Rwing1_scaleZ.o" "IMP_Rwing1.sz"; -connectAttr "IMP_Rwing_pointConstraint1_nodeState.o" "IMP_Rwing_pointConstraint1.nds" - ; -connectAttr "IMP_Rwing_pointConstraint1_Rwing_nullW0.o" "IMP_Rwing_pointConstraint1.w0" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetX.o" "IMP_Rwing_pointConstraint1.ox" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetY.o" "IMP_Rwing_pointConstraint1.oy" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetZ.o" "IMP_Rwing_pointConstraint1.oz" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_lelbow_visibility.o" "IMP_lelbow.v"; -connectAttr "IMP_lelbow_scaleX.o" "IMP_lelbow.sx"; -connectAttr "IMP_lelbow_scaleY.o" "IMP_lelbow.sy"; -connectAttr "IMP_lelbow_scaleZ.o" "IMP_lelbow.sz"; -connectAttr "IMP_locator3_pointConstraint1_nodeState.o" "IMP_locator3_pointConstraint1.nds" - ; -connectAttr "IMP_locator3_pointConstraint1_LloarmW0.o" "IMP_locator3_pointConstraint1.w0" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetX.o" "IMP_locator3_pointConstraint1.ox" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetY.o" "IMP_locator3_pointConstraint1.oy" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetZ.o" "IMP_locator3_pointConstraint1.oz" - ; -connectAttr "IMP_locator3_orientConstraint1_nodeState.o" "IMP_locator3_orientConstraint1.nds" - ; -connectAttr "IMP_locator3_orientConstraint1_LloarmW0.o" "IMP_locator3_orientConstraint1.w0" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetX.o" "IMP_locator3_orientConstraint1.ox" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetY.o" "IMP_locator3_orientConstraint1.oy" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetZ.o" "IMP_locator3_orientConstraint1.oz" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_relbow_visibility.o" "IMP_relbow.v"; -connectAttr "IMP_relbow_scaleX.o" "IMP_relbow.sx"; -connectAttr "IMP_relbow_scaleY.o" "IMP_relbow.sy"; -connectAttr "IMP_relbow_scaleZ.o" "IMP_relbow.sz"; -connectAttr "IMP_locator4_pointConstraint1_nodeState.o" "IMP_locator4_pointConstraint1.nds" - ; -connectAttr "IMP_locator4_pointConstraint1_RloarmW0.o" "IMP_locator4_pointConstraint1.w0" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetX.o" "IMP_locator4_pointConstraint1.ox" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetY.o" "IMP_locator4_pointConstraint1.oy" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetZ.o" "IMP_locator4_pointConstraint1.oz" - ; -connectAttr "IMP_locator4_orientConstraint1_nodeState.o" "IMP_locator4_orientConstraint1.nds" - ; -connectAttr "IMP_locator4_orientConstraint1_RloarmW0.o" "IMP_locator4_orientConstraint1.w0" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetX.o" "IMP_locator4_orientConstraint1.ox" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetY.o" "IMP_locator4_orientConstraint1.oy" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetZ.o" "IMP_locator4_orientConstraint1.oz" - ; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of jump_loop2.ma diff --git a/base/models/monsters/imp/animation/cycles/jump_loop3.ma b/base/models/monsters/imp/animation/cycles/jump_loop3.ma deleted file mode 100644 index b0c41e992..000000000 --- a/base/models/monsters/imp/animation/cycles/jump_loop3.ma +++ /dev/null @@ -1,8781 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:21 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: jump_loop3.ma -//Last modified: Sat, Mar 22, 2003 02:45:52 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Unlimited 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 592.96635388432878 45.341057206473785 -97.029682527524244 ; - setAttr ".r" -type "double3" -3.3301089067029777 -1691.7999999996794 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 271.08733878669375; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 339.21072765353517 61.535235649362093 20.712041475033917 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 283.84778885232589 28.807279623574583 251.64906643421713 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 382.26842571335123; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 503.1108425748202 36.715032929366295 -23.867183619064008 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 223.86211087954965; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "group2"; - setAttr ".t" -type "double3" 297.75049857774576 -2.8421709430404007e-014 - 115.34478773732499 ; - setAttr ".rp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; - setAttr ".sp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode transform -n "pointLight2" -p "group2"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 20 -max 29 -ast 20 -aet 29 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.08568 20 -1.08568; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537988160630093 20 4.1537988160630093; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185075120832098 20 4.6185075120832098; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8119691574396866 20 -5.8119691574396866; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9186219656239931 20 5.9186219656239931; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.1258655568218376 20 -4.1258655568218376; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.085679155728795 20 1.085679155728795; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537911794025533 20 4.1537911794025533; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185070801020824 20 4.6185070801020824; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3244262317670241 20 -6.3244262317670241; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0332012531196431 20 1.0332012531196431; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.463963295533194 20 8.463963295533194; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 20 1 28 1 29 1 36 1 39 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.71946295727715 20 13.71946295727715 - 28 13.71946295727715 29 13.71946295727715 36 13.71946295727715 39 13.71946295727715 - 48 13.71946295727715; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 68.596496127541187 20 68.596496127541187 - 28 68.596496127541187 29 68.596496127541187 36 68.596496127541187 39 68.596496127541187 - 48 68.596496127541187; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -60.802874383230787 20 -60.802874383230787 - 28 -60.802874383230787 29 -60.802874383230787 36 -60.802874383230787 39 -60.802874383230787 - 48 -60.802874383230787; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -157.43468421330525 20 -157.43468421330525 - 28 -157.43468421330525 29 -157.43468421330525 36 -157.43468421330525 39 -157.43468421330525 - 48 -157.43468421330525; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459183 20 15.445123296459183 - 28 15.445123296459183 29 15.445123296459183 36 15.445123296459183 39 15.445123296459183 - 48 15.445123296459183; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 36 15.445123296459185 39 15.445123296459185 - 48 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459181 20 15.445123296459181 - 28 15.445123296459181 29 15.445123296459181 36 15.445123296459181 39 15.445123296459181 - 48 15.445123296459181; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 20 1 28 1 29 1 36 1 39 1 48 - 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.010024364806417531 20 0.21060231619815561 - 28 0.20000000000000001 29 0.21060231619815561 36 0.20000000000000001 39 0.096209918545383938 - 48 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.42673163973887457 20 1.0386541206168749 - 28 1 29 1.0386541206168749 36 1 39 0 48 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1 28 1 29 1 31 1 32 1 36 - 1 39 1 48 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.5294371750177831 20 -2.5294371750177831 - 28 -2.5294371750177831 29 -2.5294371750177831 31 -2.5294371750177831 32 -2.5294371750177831 - 36 -2.5294371750177831 39 -2.5294371750177831 48 -2.5294371750177831; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 13.481673551673362 20 13.481673551673362 - 28 13.481673551673362 29 13.481673551673362 31 13.481673551673362 32 13.481673551673362 - 36 13.481673551673362 39 13.481673551673362 48 13.481673551673362; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -0.26635088939205875 20 -0.26635088939205875 - 28 -0.26635088939205875 29 -0.26635088939205875 31 -0.26635088939205875 32 - -0.26635088939205875 36 -0.26635088939205875 39 -0.26635088939205875 48 -0.26635088939205875; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 73.167297059293915 20 73.167297059293915 - 28 73.167297059293915 29 73.167297059293915 31 73.167297059293915 32 73.167297059293915 - 36 73.167297059293915 39 73.167297059293915 48 73.167297059293915; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 61.241182877125034 20 61.241182877125034 - 28 61.241182877125034 29 61.241182877125034 31 61.241182877125034 32 61.241182877125034 - 36 61.241182877125034 39 61.241182877125034 48 61.241182877125034; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 177.69376467901077 20 177.69376467901077 - 28 177.69376467901077 29 177.69376467901077 31 177.69376467901077 32 177.69376467901077 - 36 177.69376467901077 39 177.69376467901077 48 177.69376467901077; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 29 15.445123296459185 31 15.445123296459185 32 15.445123296459185 - 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1 28 1 29 1 31 1 32 1 36 - 1 39 1 48 1; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0.53328935673265621 28 0.5 - 29 0.53328935673265621 31 0.54367346977328057 32 0.54064000626006248 36 0 - 39 0.62187499874627028 48 0.19999999999999996; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0 28 0 29 0 31 0 32 0 36 - 0 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 1.0599738906558223 28 1 - 29 1.0599738906558223 31 1.0653061208314818 32 0 36 1 39 1 48 1; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 11 1 19 1 20 1 24 1 29 1 30 - 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 142.98348776985753 11 142.98348776985753 - 19 142.98348776985753 20 191.26337083735379 24 323.16554587969301 29 424.66764999887118 - 30 420.62465938310265 31 427.05957900171768 32 425.30704005425184 36 428.11110237019716 - 37 432.46487722460995 39 452.48527341107649 42 467.68382734480741 48 463.64501189855395; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 29.138462584867199 11 29.138462584867199 - 19 27.007636541590745 20 56.345616285769353 24 55.560647553748304 29 51.707835502607367 - 30 35.823339310631809 31 33.823372152340816 32 28.03999362570373 36 32.771848783861358 - 37 31.592042718943524 39 39.094608524655982 42 50.000621409275169 48 64.878916548913807; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -64.436916064427393 11 -64.436916064427393 - 19 -64.436916064427393 20 -20.904436583663255 24 -22.274292921678885 29 -21.974693687469838 - 30 -73.413769831276639 31 -61.599737051475088 32 -61.599737051475088 36 -61.599737051475088 - 37 -61.404340838912852 39 -61.599737051475088 42 -66.875434832292612 48 -72.305486080561622; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 219.80154311026268 11 219.80154311026268 - 19 219.80154311026268 20 358.04876736035584 24 372.9737147923201 29 358.04876736035584 - 30 402.3692513842521 31 399.75421244244444 32 361.75246976057394 36 388.54315471056964 - 37 382.12979672988405 39 446.2181411264944 42 470.82609984934618 48 441.51022981784752; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 103.06211582598448 11 103.06211582598448 - 19 103.06211582598448 20 155.91713557661092 24 154.99028448406145 29 155.91713557661092 - 30 160.53188760921961 31 128.89442661327502 32 128.8944266132749 36 130.20957118662795 - 37 126.422682041705 39 149.08574357438997 42 133.83971002200158 48 132.94446310792156; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 179.66289643582957 11 179.66289643582957 - 19 179.66289643582957 20 418.4296026462676 24 433.04458652607644 29 418.4296026462676 - 30 424.0923332662079 31 371.32760212837917 32 371.32760212837917 36 316.59454777258998 - 37 319.37663179388846 39 335.03872044309094 42 367.06275467923081 48 439.67161200383958; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 25 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 115.77674460548414 11 115.77674460548414 - 18 115.77674460548414 19 128.23278335184611 20 186.67237970682669 25 317.37616622813266 - 29 422.34271983107715 30 423.70984279183483 31 443.99727667219565 36 443.99727667219565 - 37 443.99727667219565 38 443.38906601627184 39 443.99727667219565 42 456.16149037302819 - 43 460.00331537229431 48 451.97121129722473; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 29.57010509969825 11 29.57010509969825 - 18 29.57010509969825 19 29.27089625396021 20 84.413213123975879 25 84.062489458134195 - 29 84.503876413923294 30 35.768974660229517 31 28.598876396236033 36 28.598876396236033 - 37 29.891609618591474 38 32.477481014791223 39 35.885190922239445 42 47.511691840001383 - 43 53.969285662101555 48 68.087166186099452; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 5.5906769424741611 11 5.5906769424741611 - 18 5.5906769424741611 19 7.7790374995743576 20 14.257372027957803 25 22.002868665737008 - 29 18.357073863289454 30 17.688799523426937 31 17.688799523426937 36 17.688799523426937 - 37 18.393926735620809 38 16.901407469018011 39 18.158884331556195 42 17.688799523426937 - 43 16.932203967017472 48 18.833156565013823; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -178.9145192530496 11 -178.9145192530496 - 18 -178.9145192530496 19 -167.69587374559055 20 -348.54680731482705 25 -315.47994301629564 - 29 -313.30399091479285 30 -295.55702963991496 31 -323.43616169739801 36 -323.43616169739801 - 37 -301.98736295612144 38 -294.1473764072087 39 -284.1852919748419 42 -215.34826646492581 - 43 -201.47174946737618 48 -256.50049062084815; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 77.792981530281054 11 77.792981530281054 - 18 77.792981530281054 19 77.792981530281097 20 46.172650614682254 25 32.649838923909805 - 29 43.020497035122034 30 56.539878395975578 31 67.318721800853339 36 67.318721800853339 - 37 64.350871231601133 38 67.126204716457593 39 67.31872180085341 42 38.522706263852164 - 43 35.653912925478181 48 18.052275906821958; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 146.44536767645329 11 146.44536767645329 - 18 146.44536767645329 19 146.44536767645334 20 89.699429941144373 25 92.41220787778019 - 29 105.93622613769033 30 92.774179834952406 31 39.044332496204468 36 39.044332496204468 - 37 42.18224322723831 38 39.690533059175472 39 39.044332496204518 42 60.637340161233091 - 43 65.527995150390169 48 23.269369027924608; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 20 0 25 0 29 0 30 - 0; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 11 5.6268319407172029 - 18 5.6268319407172029 20 5.6268319407172029 25 5.6268319407172029 29 5.6268319407172029 - 30 5.6268319407172029; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 11 -2.1098668596606802 - 18 -2.1098668596606802 20 -2.1098668596606802 25 -2.1098668596606802 29 -2.1098668596606802 - 30 -2.1098668596606802; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 360.76739391711288 11 336.00205489946853 - 18 342.74743969676229 20 338.37368336073973 25 325.09636024467915 29 338.37368336073973 - 30 375.1012001423897; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.39334696132271052 11 22.934613158314267 - 18 3.3751297566513738 20 -21.338021142239622 25 -29.820366813239424 29 -21.338021142239622 - 30 1.1508514452864969; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -18.700472818991617 11 -35.808201433501473 - 18 -4.0181375389538863 20 20.661903200550853 25 26.05196766405594 29 20.661903200550853 - 30 16.328915349246685; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 20 1 25 1 29 1 30 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 3 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 3 3 9 9 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 7.1689522478599494 13 7.1689522478599494 - 16 7.1689522478599503 19 7.1689522478599503 20 6.925456265951996 24 8.7983283713503688 - 26 11.018796760141813 29 6.9254562659520378 30 6.9254562659520369 34 6.9254562659520369 - 38 7.554986848268765; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 14.562786750258176 13 14.562786750258176 - 16 14.562786750258176 19 13.842211007852075 20 20.923245467494844 24 22.750319749983092 - 26 18.178738536249831 29 20.923245467494844 30 13.359586698238232 34 13.673824607627459 - 38 14.11106435922871; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 96.133649094344804 13 96.133649094344804 - 16 108.69386808893657 19 108.69386808893657 20 119.35821919539188 24 227.16912977936141 - 26 261.36084706164974 29 307.0458635573579 30 333.39863420942874 34 333.39863420942874 - 38 377.18147202625158; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -174.49049195404214 13 -174.49049195404214 - 16 -174.49049195404214 19 -174.49049195404214 20 -80.195825489861193 24 -301.53506754966133 - 26 -100.27785478110128 29 -80.195825489861193 30 10.11833837859974 34 10.11833837859974 - 38 6.0578085460824589; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 129.78625356110399 13 129.78625356110399 - 16 129.78625356110399 19 129.78625356110399 20 1.4379585757962667 24 156.57861554381626 - 26 32.210181397685318 29 1.4379585757962667 30 22.148402438321622 34 22.148402438321622 - 38 14.559598429561929; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -169.93906815090079 13 -169.93906815090079 - 16 -169.93906815090079 19 -169.93906815090079 20 -29.493568390973312 24 -201.27457036315781 - 26 -29.967697144210206 29 -29.493568390973312 30 8.7946878310934409 34 8.7946878310934409 - 38 8.2507937920490004; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 16 1 19 1 20 1 24 1 26 - 1 29 1 30 1 34 1 38 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 9 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 125.1606853982252 20 125.1606853982252 - 29 125.1606853982252; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 77.825664227235052 20 77.825664227235052 - 29 77.825664227235052; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -175.25743303308352 20 -175.25743303308352 - 29 -175.25743303308352; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; - setAttr -s 9 ".kot[3:8]" 5 9 5 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -7.3924057183505028 7 -7.3924057183505019 - 19 -7.3924057183505019 20 -6.9176833889325122 24 -6.2589266759223765 29 -6.916667322061806 - 30 -6.3308105672263544 34 -6.3308105672263544 38 -7.1642625370327009; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 15.840283259770729 7 9.4070003601017547 - 19 9.4070003356835699 20 11.196614583528255 24 16.336583444843768 29 10.625810794831406 - 30 9.8084023440544854 34 10.14635638156529 38 10.992193194026985; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 76.997633470219824 7 99.667297021434308 - 19 99.667297021434308 20 121.48715069975222 24 219.36892594278427 29 311.00354071483548 - 30 333.23005140887722 34 333.23005140887722 38 377.1632664084907; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -18.39795914825002 7 21.526450659699222 - 19 21.526450659699222 20 -40.037064876295929 24 -146.39991688279261 29 -40.037064876295929 - 30 15.958661750368087 34 15.958661750368087 38 12.355198312075999; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -48.06590236816033 7 -38.053954061890678 - 19 -38.053954061890678 20 -38.321160312802654 24 -29.684032640488194 29 -38.321160312802654 - 30 -38.059156299065826 34 -38.059156299065826 38 -35.152508962264037; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 7.7650564355670078 7 -10.667864335873874 - 19 -10.667864335873874 20 -5.1515784092334673 24 25.709605253119321 29 -5.1515784092334673 - 30 -11.009931379047687 34 -11.009931379047687 38 -11.865112406666784; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 19 1 20 1 24 1 29 1 30 - 1 34 1 38 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 20 1 24 1 29 - 1 30 1 33 1 37 1 42 1 48 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 2.5125681904581358 9 1.9808213950621905 - 13 1.9808213950621907 18 9.2715722022641724 20 1.0475304217287646 24 -0.15969281255098805 - 29 1.4100176063653691 30 1.9808213950622389 33 1.9808213950622422 37 1.9808213950622449 - 42 1.9808213950622469 48 1.9808213950622469; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 49.057951687626066 9 46.233318687395005 - 13 43.306536510238651 18 43.306536510238651 20 37.71613222172688 24 39.806624421334483 - 29 37.573004824656252 30 42.450288337009852 33 43.630641520076964 37 60.430686497730626 - 42 54.094786172201999 48 61.311043210496877; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 96.110338887997557 9 101.4151315840935 - 13 107.81746759662305 18 107.81746759662305 20 135.58394463251807 24 244.33339068178299 - 29 324.1770843528858 30 333.64740089743867 33 347.87539237621274 37 360.25559275384734 - 42 369.39210044166862 48 369.39210044166862; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 22.565311747406891 9 42.315017092753621 - 13 36.358132000694155 18 36.358132000694155 20 0.49705284723442805 24 11.965536004890978 - 29 -1.622671583472751 30 0.49705284723442805 33 0.49705284723442805 37 0.49705284723442805 - 42 -42.6591147393315 48 -42.6591147393315; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.9513867036587919e-016 9 0 13 - 0 18 0 20 11.49524675155142 24 24.982008394583602 29 13.305580484287841 30 - 11.49524675155142 33 11.49524675155142 37 11.49524675155142 42 11.495246751551425 - 48 11.495246751551425; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.4260738755503892 9 7.426073875550375 - 13 7.4260738755503644 18 7.4260738755503644 20 -20.965676744725002 24 -5.5453476021864274 - 29 -18.757615244261551 30 -20.965676744725002 33 -20.965676744725002 37 -20.965676744725002 - 42 -20.965676744725013 48 -20.965676744725013; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 20 1 24 1 29 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 20 1 24 1 29 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 20 1 24 1 29 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21285352564148119; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15078676416754505; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15149042747921673; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.90991990467137285 13 0.90991990467137285 - 17 0.90991990467137285 19 3.2165938865377592 20 3.2165938865377592 25 3.2165938865377592 - 29 3.2165938865377592 30 3.2165938865377592 36 3.2165938865377592 42 3.2165938865377592 - 48 3.2165938865377592; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.6840963091226424 13 1.6840963091226424 - 17 1.6840963091226424 19 1.0198173250982352 20 1.0198173250982352 25 1.0198173250982352 - 29 1.0198173250982352 30 1.0198173250982352 36 1.0198173250982352 42 1.0198173250982352 - 48 1.0198173250982352; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.8509277672757398 13 2.8509277672757398 - 17 2.8509277672757398 19 5.5089484635562949 20 5.5089484635562949 25 5.5089484635562949 - 29 5.5089484635562949 30 5.5089484635562949 36 5.5089484635562949 42 5.5089484635562949 - 48 5.5089484635562949; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -81.50691442197396 13 -31.261146897838977 - 17 -76.052449399988134 19 14.028238821473778 20 18.829906193345121 25 1.6570391603464214 - 29 18.829906193345121 30 -84.048401441518692 36 -100.98950409530727 42 -55.664830857165363 - 48 -37.750911612187679; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 30.964642776910992 13 16.829153229070521 - 17 17.998418905573541 19 61.793759660292352 20 14.934689214991996 25 19.405840797638781 - 29 14.934689214991996 30 -3.8527038109155853 36 2.9181746341270869 42 8.3717076859878041 - 48 21.674975974628239; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.8358968951012837 13 6.4562833550431655 - 17 -20.729425848392836 19 20.568981510619366 20 -15.202923748813964 25 -16.492097408750883 - 29 -15.202923748813964 30 -3.3299002212729572 36 -35.030428448148584 42 -3.6057329631056776 - 48 -6.3849825779711411; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 13 1 17 1 19 1 20 1 25 1 29 - 1 30 1 36 1 42 1 48 1; - setAttr -s 11 ".kit[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 3 9 9 9 9 - 9 9 9 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 10 0 17 0 19 0 20 0 22 0 30 - 0 35 0 48 0; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.3128351505039433 10 2.3128351505039433 - 17 2.3128351505039433 19 2.3128351505039433 20 2.3128351505039433 22 2.3128351505039433 - 30 2.3128351505039433 35 2.3128351505039433 48 2.3128351505039433; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.23421866920666501 10 0.23421866920666501 - 17 0.23421866920666501 19 0.23421866920666501 20 0.23421866920666501 22 0.23421866920666501 - 30 0.23421866920666501 35 0.23421866920666501 48 0.23421866920666501; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.671711834718816 10 -3.671711834718816 - 17 -0.38903580510386404 19 24.430204060920861 20 26.154517719026376 22 20.858840660148381 - 30 27.159710134283735 35 33.513181175101714 48 16.877903135718185; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -30.925240358666347 10 -30.925240358666347 - 17 -8.0093455226114028 19 -36.190660550952373 20 20.225914021857086 22 12.125593470464233 - 30 21.141076518420324 35 21.151855214980227 48 -2.7299381262472755; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 24.795614393044964 10 24.795614393044964 - 17 28.310029710143734 19 11.117279450806294 20 13.30559106872983 22 1.7686655262962976 - 30 15.451645632735099 35 28.619674064500245 48 0.26452410412025396; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 17 1 19 1 20 1 22 1 30 - 1 35 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 25 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 25 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 25 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 25 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 25 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 25 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 25 1 29 1 32 1 38 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0.27427147149852044 11 0.27427147153653575 - 12 0.27427147153797948 13 0.27427147153980314 14 0.27427147154217391 15 0.2742714715453653 - 16 0.27427147154983328 17 0.27427147155621612 18 0.27427147156259896 19 0.27427147156259896 - 20 0.27427148236273546 25 0.27427147156259896 29 0.27427148236273546 32 0.27427147156259896 - 38 0.27427147156259896 48 0.27427147156259896; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -1.1074984126668126 11 -1.1074984146392313 - 12 -1.1074984147141391 13 -1.1074984148087597 14 -1.1074984149317662 15 -1.1074984150973519 - 16 -1.107498415329172 17 -1.1074984156603436 18 -1.1074984159915151 19 -1.1074984159915151 - 20 -1.1074984087483377 25 -1.1074984159915151 29 -1.1074984087483377 32 -1.1074984159915151 - 38 -1.1074984159915151 48 -1.1074984159915151; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -1.642626684874722 11 -1.6426266835385228 - 12 -1.6426266834877772 13 -1.6426266834236773 14 -1.6426266833403476 15 -1.6426266832281728 - 16 -1.642626683071128 17 -1.6426266828467784 18 -1.6426266826224289 19 -1.6426266826224289 - 20 -1.6426266857026413 25 -1.6426266826224289 29 -1.6426266857026413 32 -1.6426266826224289 - 38 -1.6426266826224289 48 -1.6426266826224289; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 25 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 25 0 29 0 32 0 38 0 48 0; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -37.815214478634331 11 -125.74912876606732 - 12 -125.51192920989145 13 -100.00216573212361 14 -59.835637123346231 15 -36.233993668944173 - 16 -35.413141578212446 17 -49.792207316432325 18 -114.59155902616467 19 -86.44861012607744 - 20 2.8612079059220927 25 8.6288085939776487 29 2.8612079059220927 32 -57.295779513082323 - 38 -59.587610693605619 48 -83.651838089100195; - setAttr -s 16 ".kit[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 29 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.2742786288673521 10 -0.27427863453231033 - 17 -0.27427863453231033 18 -0.27427863453231033 19 -0.27427863453231033 20 - -0.27427863453231033 24 -0.27427863453231033 29 -0.27427863453231033 35 -0.27427863453231033 - 48 -0.27427863453231033; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.1075115373407667 10 -1.1075115557303763 - 17 -1.1075115557303763 18 -1.1075115557303763 19 -1.1075115557303763 20 -1.1075115557303763 - 24 -1.1075115557303763 29 -1.1075115557303763 35 -1.1075115557303763 48 -1.1075115557303763; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.6426166407301896 10 -1.6426166273853338 - 17 -1.6426166273853338 18 -1.6426166273853338 19 -1.6426166273853338 20 -1.6426166273853338 - 24 -1.6426166273853338 29 -1.6426166273853338 35 -1.6426166273853338 48 -1.6426166273853338; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 29 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 108.86198107485642 10 108.86198107485642 - 17 73.338597776745388 18 26.403355291791605 19 54.852317270957315 20 17.797350596899509 - 24 34.98949021968803 29 17.797350596899509 35 29.793805346802827 48 61.879441874128936; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.14201183279855 20 1.0099431818894913 - 28 1 29 1.0099431818894913 36 1 39 0 48 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 20 0 28 0 29 0 36 0 39 0 48 - 0; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 20 1.0110080399545431 28 1 - 29 1.0110080399545431 31 1.0367346951942145 32 1 36 1 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 20 0 28 0 29 0 31 0 32 0 36 - 0 39 0 48 0; - setAttr -s 9 ".kit[1:8]" 9 9 9 3 3 3 3 - 9; - setAttr -s 9 ".kot[1:8]" 9 9 9 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 11 1 18 1 20 1 27 1 34 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -28.073881032405502 6 -46.403838232154726 - 11 -57.268694860493916 18 -64.448733245059486 20 -85.021389942138228 27 -96.759313977435809 - 34 -81.70071573151256 48 -92.276866801256645; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -61.199228718418333 6 -52.589856193268211 - 11 -48.400115258246736 18 -43.995383780771014 20 -56.304528730735143 27 -41.2276998033512 - 34 -55.139126251391993 48 -76.844287356428978; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -81.184232108591999 6 -75.778137454888423 - 11 -62.491121494028498 18 -64.875827156229477 20 -23.876400721722792 27 -34.093153518684247 - 34 -33.172769882599198 48 -6.4131326743179056; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 19 1 22 1 29 1 34 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -117.99254693569441 13 -123.98803296810649 - 19 -131.56223464759714 22 -143.68624235845436 29 -118.25457552859019 34 -118.19943411562497 - 48 -137.79238049393118; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 27.075624429458429 13 25.391307459182691 - 19 20.623216711056333 22 37.500675079600633 29 12.160180912642328 34 24.003088726248219 - 48 55.642180590844198; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -35.130967703309707 13 -76.878252144223026 - 19 -53.588570440441174 22 -49.075623471088711 29 -63.575828601904099 34 -35.895713294177334 - 48 -20.939120123829618; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.90858890976581275 20 -0.90858890976581275; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.2382713968077237 20 6.2382713968077237; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.55501859990651525 20 -0.55501859990651525; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -22.350064437213423 20 -22.350064437213423; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -10.303773027856268 20 -10.303773027856268; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.8115085199100047 20 8.8115085199100047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 25 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0.99999999999999978 11 0.99999999999999978 - 18 0.99999999999999978 19 0.99999999999999978 20 0.99999999999999978 25 0.99999999999999978 - 29 0.99999999999999978 30 0.99999999999999978 31 0.99999999999999978 36 0.99999999999999978 - 37 0.99999999999999978 38 0.99999999999999978 39 0.99999999999999978 42 0.99999999999999978 - 43 0.99999999999999978 48 0.99999999999999978; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 11 1 18 1 19 1 20 1 25 1 29 - 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 16 ".kit[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; - setAttr -s 16 ".kot[0:15]" 3 3 3 9 9 9 9 - 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 11 1 19 1 20 1 24 1 29 1 30 - 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0.99999999999999989 11 0.99999999999999989 - 19 0.99999999999999989 20 0.99999999999999989 24 0.99999999999999989 29 0.99999999999999989 - 30 0.99999999999999989 31 0.99999999999999989 32 0.99999999999999989 36 0.99999999999999989 - 37 0.99999999999999989 39 0.99999999999999989 42 0.99999999999999989 48 0.99999999999999989; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978 20 0.99999999999999978 24 0.99999999999999978 29 0.99999999999999978 - 30 0.99999999999999978 31 0.99999999999999978 32 0.99999999999999978 36 0.99999999999999978 - 37 0.99999999999999978 39 0.99999999999999978 42 0.99999999999999978 48 0.99999999999999978; - setAttr -s 14 ".kit[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; - setAttr -s 14 ".kot[3:13]" 9 9 9 9 9 3 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_locator5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_camera_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator14_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_Rwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_lelbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_lelbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_relbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.1057240879120851; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5956396785200369; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3817563473270154; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41001647724799928; -createNode animCurveTL -n "IMP_Lmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1693934765127816; -createNode animCurveTL -n "IMP_Lmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5729514457211735; -createNode animCurveTA -n "IMP_Lmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_pointConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_orientConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_cam_connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0046539604129529621; -createNode animCurveTL -n "IMP_cam_connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4094890802521576; -createNode animCurveTL -n "IMP_cam_connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0367577756137232; -createNode animCurveTA -n "IMP_cam_connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.11875208173462; -createNode animCurveTA -n "IMP_cam_connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085761516203950224; -createNode animCurveTA -n "IMP_cam_connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1776791248832486e-005; -createNode animCurveTU -n "IMP_cam_connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_eyes_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.034284369950123843; -createNode animCurveTL -n "IMP_eyes_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9944975057013083; -createNode animCurveTL -n "IMP_eyes_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.9109443986143884; -createNode animCurveTA -n "IMP_eyes_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -147.00752219093516; -createNode animCurveTA -n "IMP_eyes_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_eyes_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 180; -createNode animCurveTU -n "IMP_eyes_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_eyes_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator13_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.0032893248995669033; -createNode animCurveTL -n "IMP_locator13_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.42074550807650996; -createNode animCurveTL -n "IMP_locator13_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -88.322777837915837; -createNode animCurveTA -n "IMP_locator13_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 179.72494022541443; -createNode animCurveTA -n "IMP_locator13_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085757562239429132; -createNode animCurveTA -n "IMP_locator13_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -179.99989705255965; -createNode animCurveTU -n "IMP_locator13_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0000000000000002; -createNode animCurveTU -n "IMP_locator13_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 87.843121583379272; -createNode animCurveTU -n "IMP_pCube1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_pCube1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.04673741311718338; -createNode animCurveTL -n "IMP_pCube1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.018550086981591107; -createNode animCurveTL -n "IMP_pCube1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.59134881205267886; -createNode animCurveTA -n "IMP_pCube1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_pCube1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.81452695663524144; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.5258192723085173 20 5.5258192723085173; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.1525507362789047 20 1.1525507362789047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.1924108426844384 20 1.1924108426844384; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.3533140211779946 20 6.3533140211779946; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.74525677667777757 20 0.74525677667777757; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.8072476834435935 20 1.8072476834435935; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 9.022004834100839 20 9.022004834100839; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.9550621233059426 20 1.9550621233059426; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.88597689344963537 20 -0.88597689344963537; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.9684923358091311 20 -3.9684923358091311; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.2916645882841449 20 2.2916645882841449; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.7296155549506897 20 4.7296155549506897; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.1608864069345106 20 2.1608864069345106; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.0054669522092379 20 -3.0054669522092379; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 28.836234092176063 20 11.07349067527878; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.5988200593703294 20 -53.841918861092552; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 52.351071907336284 20 -25.947600690391031; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.412879749935719 20 12.412879749935719; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.7286993982861674 20 -6.7286993982861674; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.868763862603668 20 -3.868763862603668; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -34.36059369489287 20 42.922644402952855; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -8.556853256702178 20 8.5989866823062808; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -23.206907965932974 20 27.627511712669737; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 12.890532588149956 20 12.890532588149956; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.69008032694306476 20 -0.69008032694306476; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.645694319339265 20 4.645694319339265; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.4675296479599407 20 -5.4675296479599407; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.0844803122567583 20 2.0844803122567583; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.0869908056348607 20 -3.0869908056348607; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 26.659954467743521 20 35.929156953403414; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -49.492801424012306 20 58.495495793078319; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -100.40231940259616 20 35.62217186926501; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.41287000000041 20 -12.41287000000041; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.7285999999993047 20 -6.7285999999993047; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.8687599999999316 20 -3.8687599999999316; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 33.257666229421972 20 74.138445451041335; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 -1.1463794921978937e-014; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.5092015178261011 20 -21.198042374621632; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.890500000000031 20 -12.890500000000031; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.6900999999992341 20 -0.6900999999992341; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6456900000000347 20 4.6456900000000347; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.0846345617354372 20 -4.0846345617354372; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.282468147773308 20 4.282468147773308; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.7712681071056613 20 7.7712681071056613; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.4264261331675518 20 4.4264261331675518; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.3937238431314825 20 4.3937238431314825; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.7712681071056613 20 7.7712681071056613; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 20 0; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 20 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 9.2053053109380052; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.55189552941641418; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0646191166984784; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 11.586085933787016; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 23.165861309280317; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 73.16163459057924; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 89.830862630651069; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1568819853431291; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.8855564166933343; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -76.090633252486683; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.791362663024994; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 54.744021489634264; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 113.88179442110163; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.88642296005711507; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -16.683497590890667; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 99.194475901955684 20 99.194475901955684 - 29 99.194475901955684; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 69.492034696563493 20 69.492034696563493 - 29 69.492034696563493; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 52.003739368178465 20 52.003739368178465 - 29 52.003739368178465; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 29 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 29 0; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 217.7239621497128 20 217.7239621497128 - 29 217.7239621497128; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.7373203203190113; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4972392481870522; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6496305501990709; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 62.667511380374542; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -13.204130585379209; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 40.323400206122145; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_Lwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint8_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint7_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint9_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_Rwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -select -ne :time1; - setAttr ".o" 28; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933713 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Waist; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643403 -66.654599961471263 -11.653334128372219 ; -select -ne IMP_Rhand_IK; -select -ne IMP_RIK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; -select -ne IMP_RHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_locator5_visibility.o" "IMP_locator5.v"; -connectAttr "IMP_locator5_scaleX.o" "IMP_locator5.sx"; -connectAttr "IMP_locator5_scaleY.o" "IMP_locator5.sy"; -connectAttr "IMP_locator5_scaleZ.o" "IMP_locator5.sz"; -connectAttr "IMP_locator5_pointConstraint1_nodeState.o" "IMP_locator5_pointConstraint1.nds" - ; -connectAttr "IMP_locator5_pointConstraint1_RhandW0.o" "IMP_locator5_pointConstraint1.w0" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetX.o" "IMP_locator5_pointConstraint1.ox" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetY.o" "IMP_locator5_pointConstraint1.oy" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetZ.o" "IMP_locator5_pointConstraint1.oz" - ; -connectAttr "IMP_locator5_orientConstraint1_nodeState.o" "IMP_locator5_orientConstraint1.nds" - ; -connectAttr "IMP_locator5_orientConstraint1_RhandW0.o" "IMP_locator5_orientConstraint1.w0" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetX.o" "IMP_locator5_orientConstraint1.ox" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetY.o" "IMP_locator5_orientConstraint1.oy" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetZ.o" "IMP_locator5_orientConstraint1.oz" - ; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_locator6_visibility.o" "IMP_locator6.v"; -connectAttr "IMP_locator6_scaleX.o" "IMP_locator6.sx"; -connectAttr "IMP_locator6_scaleY.o" "IMP_locator6.sy"; -connectAttr "IMP_locator6_scaleZ.o" "IMP_locator6.sz"; -connectAttr "IMP_locator6_pointConstraint1_nodeState.o" "IMP_locator6_pointConstraint1.nds" - ; -connectAttr "IMP_locator6_pointConstraint1_LhandW0.o" "IMP_locator6_pointConstraint1.w0" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetX.o" "IMP_locator6_pointConstraint1.ox" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetY.o" "IMP_locator6_pointConstraint1.oy" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetZ.o" "IMP_locator6_pointConstraint1.oz" - ; -connectAttr "IMP_locator6_orientConstraint1_nodeState.o" "IMP_locator6_orientConstraint1.nds" - ; -connectAttr "IMP_locator6_orientConstraint1_LhandW0.o" "IMP_locator6_orientConstraint1.w0" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetX.o" "IMP_locator6_orientConstraint1.ox" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetY.o" "IMP_locator6_orientConstraint1.oy" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetZ.o" "IMP_locator6_orientConstraint1.oz" - ; -connectAttr "IMP_Lmissile_visibility.o" "IMP_Lmissile.v"; -connectAttr "IMP_Lmissile_translateX.o" "IMP_Lmissile.tx"; -connectAttr "IMP_Lmissile_translateY.o" "IMP_Lmissile.ty"; -connectAttr "IMP_Lmissile_translateZ.o" "IMP_Lmissile.tz"; -connectAttr "IMP_Lmissile_rotateX.o" "IMP_Lmissile.rx"; -connectAttr "IMP_Lmissile_rotateY.o" "IMP_Lmissile.ry"; -connectAttr "IMP_Lmissile_rotateZ.o" "IMP_Lmissile.rz"; -connectAttr "IMP_Lmissile_scaleX.o" "IMP_Lmissile.sx"; -connectAttr "IMP_Lmissile_scaleY.o" "IMP_Lmissile.sy"; -connectAttr "IMP_Lmissile_scaleZ.o" "IMP_Lmissile.sz"; -connectAttr "IMP_camera_visibility.o" "IMP_camera.v"; -connectAttr "IMP_camera_scaleX.o" "IMP_camera.sx"; -connectAttr "IMP_camera_scaleY.o" "IMP_camera.sy"; -connectAttr "IMP_camera_scaleZ.o" "IMP_camera.sz"; -connectAttr "IMP_camera_pointConstraint1_nodeState.o" "IMP_camera_pointConstraint1.nds" - ; -connectAttr "IMP_camera_pointConstraint1_eyesW0.o" "IMP_camera_pointConstraint1.w0" - ; -connectAttr "IMP_camera_pointConstraint1_offsetX.o" "IMP_camera_pointConstraint1.ox" - ; -connectAttr "IMP_camera_pointConstraint1_offsetY.o" "IMP_camera_pointConstraint1.oy" - ; -connectAttr "IMP_camera_pointConstraint1_offsetZ.o" "IMP_camera_pointConstraint1.oz" - ; -connectAttr "IMP_camera_orientConstraint1_nodeState.o" "IMP_camera_orientConstraint1.nds" - ; -connectAttr "IMP_camera_orientConstraint1_eyesW0.o" "IMP_camera_orientConstraint1.w0" - ; -connectAttr "IMP_camera_orientConstraint1_offsetX.o" "IMP_camera_orientConstraint1.ox" - ; -connectAttr "IMP_camera_orientConstraint1_offsetY.o" "IMP_camera_orientConstraint1.oy" - ; -connectAttr "IMP_camera_orientConstraint1_offsetZ.o" "IMP_camera_orientConstraint1.oz" - ; -connectAttr "IMP_locator14_visibility.o" "IMP_locator14.v"; -connectAttr "IMP_locator14_scaleX.o" "IMP_locator14.sx"; -connectAttr "IMP_locator14_scaleY.o" "IMP_locator14.sy"; -connectAttr "IMP_locator14_scaleZ.o" "IMP_locator14.sz"; -connectAttr "IMP_locator14_pointConstraint1_nodeState.o" "IMP_locator14_pointConstraint1.nds" - ; -connectAttr "IMP_locator14_pointConstraint1_HeadW0.o" "IMP_locator14_pointConstraint1.w0" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetX.o" "IMP_locator14_pointConstraint1.ox" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetY.o" "IMP_locator14_pointConstraint1.oy" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetZ.o" "IMP_locator14_pointConstraint1.oz" - ; -connectAttr "IMP_locator14_orientConstraint1_nodeState.o" "IMP_locator14_orientConstraint1.nds" - ; -connectAttr "IMP_locator14_orientConstraint1_HeadW0.o" "IMP_locator14_orientConstraint1.w0" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetX.o" "IMP_locator14_orientConstraint1.ox" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetY.o" "IMP_locator14_orientConstraint1.oy" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetZ.o" "IMP_locator14_orientConstraint1.oz" - ; -connectAttr "IMP_cam_connector_visibility.o" "IMP_cam_connector.v"; -connectAttr "IMP_cam_connector_translateX.o" "IMP_cam_connector.tx"; -connectAttr "IMP_cam_connector_translateY.o" "IMP_cam_connector.ty"; -connectAttr "IMP_cam_connector_translateZ.o" "IMP_cam_connector.tz"; -connectAttr "IMP_cam_connector_rotateX.o" "IMP_cam_connector.rx"; -connectAttr "IMP_cam_connector_rotateY.o" "IMP_cam_connector.ry"; -connectAttr "IMP_cam_connector_rotateZ.o" "IMP_cam_connector.rz"; -connectAttr "IMP_cam_connector_scaleX.o" "IMP_cam_connector.sx"; -connectAttr "IMP_cam_connector_scaleY.o" "IMP_cam_connector.sy"; -connectAttr "IMP_cam_connector_scaleZ.o" "IMP_cam_connector.sz"; -connectAttr "IMP_eyes_translateX.o" "IMP_eyes.tx"; -connectAttr "IMP_eyes_translateY.o" "IMP_eyes.ty"; -connectAttr "IMP_eyes_translateZ.o" "IMP_eyes.tz"; -connectAttr "IMP_eyes_rotateX.o" "IMP_eyes.rx"; -connectAttr "IMP_eyes_rotateY.o" "IMP_eyes.ry"; -connectAttr "IMP_eyes_rotateZ.o" "IMP_eyes.rz"; -connectAttr "IMP_eyes_visibility.o" "IMP_eyes.v"; -connectAttr "IMP_eyes_scaleX.o" "IMP_eyes.sx"; -connectAttr "IMP_eyes_scaleY.o" "IMP_eyes.sy"; -connectAttr "IMP_eyes_scaleZ.o" "IMP_eyes.sz"; -connectAttr "IMP_locator13_visibility.o" "IMP_locator13.v"; -connectAttr "IMP_locator13_translateX.o" "IMP_locator13.tx"; -connectAttr "IMP_locator13_translateY.o" "IMP_locator13.ty"; -connectAttr "IMP_locator13_translateZ.o" "IMP_locator13.tz"; -connectAttr "IMP_locator13_rotateX.o" "IMP_locator13.rx"; -connectAttr "IMP_locator13_rotateY.o" "IMP_locator13.ry"; -connectAttr "IMP_locator13_rotateZ.o" "IMP_locator13.rz"; -connectAttr "IMP_locator13_scaleX.o" "IMP_locator13.sx"; -connectAttr "IMP_locator13_scaleY.o" "IMP_locator13.sy"; -connectAttr "IMP_locator13_scaleZ.o" "IMP_locator13.sz"; -connectAttr "IMP_pCube1_visibility.o" "IMP_pCube1.v"; -connectAttr "IMP_pCube1_translateX.o" "IMP_pCube1.tx"; -connectAttr "IMP_pCube1_translateY.o" "IMP_pCube1.ty"; -connectAttr "IMP_pCube1_translateZ.o" "IMP_pCube1.tz"; -connectAttr "IMP_pCube1_rotateX.o" "IMP_pCube1.rx"; -connectAttr "IMP_pCube1_rotateY.o" "IMP_pCube1.ry"; -connectAttr "IMP_pCube1_rotateZ.o" "IMP_pCube1.rz"; -connectAttr "IMP_pCube1_scaleX.o" "IMP_pCube1.sx"; -connectAttr "IMP_pCube1_scaleY.o" "IMP_pCube1.sy"; -connectAttr "IMP_pCube1_scaleZ.o" "IMP_pCube1.sz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_Rwing_thing_visibility.o" "IMP_Rwing_thing.v"; -connectAttr "IMP_Rwing_thing_scaleX.o" "IMP_Rwing_thing.sx"; -connectAttr "IMP_Rwing_thing_scaleY.o" "IMP_Rwing_thing.sy"; -connectAttr "IMP_Rwing_thing_scaleZ.o" "IMP_Rwing_thing.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Lwing_thing_visibility.o" "IMP_Lwing_thing.v"; -connectAttr "IMP_Lwing_thing_scaleX.o" "IMP_Lwing_thing.sx"; -connectAttr "IMP_Lwing_thing_scaleY.o" "IMP_Lwing_thing.sy"; -connectAttr "IMP_Lwing_thing_scaleZ.o" "IMP_Lwing_thing.sz"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Lwing_pointConstraint1_nodeState.o" "IMP_Lwing_pointConstraint1.nds" - ; -connectAttr "IMP_Lwing_pointConstraint1_Lwing_nullW0.o" "IMP_Lwing_pointConstraint1.w0" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetX.o" "IMP_Lwing_pointConstraint1.ox" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetY.o" "IMP_Lwing_pointConstraint1.oy" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetZ.o" "IMP_Lwing_pointConstraint1.oz" - ; -connectAttr "IMP_joint8_scaleX.o" "IMP_joint8.sx"; -connectAttr "IMP_joint8_scaleY.o" "IMP_joint8.sy"; -connectAttr "IMP_joint8_scaleZ.o" "IMP_joint8.sz"; -connectAttr "IMP_joint8_visibility.o" "IMP_joint8.v"; -connectAttr "IMP_joint7_visibility.o" "IMP_joint7.v"; -connectAttr "IMP_joint7_scaleX.o" "IMP_joint7.sx"; -connectAttr "IMP_joint7_scaleY.o" "IMP_joint7.sy"; -connectAttr "IMP_joint7_scaleZ.o" "IMP_joint7.sz"; -connectAttr "IMP_joint6_scaleX.o" "IMP_joint6.sx"; -connectAttr "IMP_joint6_scaleY.o" "IMP_joint6.sy"; -connectAttr "IMP_joint6_scaleZ.o" "IMP_joint6.sz"; -connectAttr "IMP_joint6_visibility.o" "IMP_joint6.v"; -connectAttr "IMP_joint9_visibility.o" "IMP_joint9.v"; -connectAttr "IMP_joint9_scaleX.o" "IMP_joint9.sx"; -connectAttr "IMP_joint9_scaleY.o" "IMP_joint9.sy"; -connectAttr "IMP_joint9_scaleZ.o" "IMP_joint9.sz"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_joint5_visibility.o" "IMP_joint5.v"; -connectAttr "IMP_joint5_scaleX.o" "IMP_joint5.sx"; -connectAttr "IMP_joint5_scaleY.o" "IMP_joint5.sy"; -connectAttr "IMP_joint5_scaleZ.o" "IMP_joint5.sz"; -connectAttr "IMP_Rwing4_scaleX.o" "IMP_Rwing4.sx"; -connectAttr "IMP_Rwing4_scaleY.o" "IMP_Rwing4.sy"; -connectAttr "IMP_Rwing4_scaleZ.o" "IMP_Rwing4.sz"; -connectAttr "IMP_Rwing4_visibility.o" "IMP_Rwing4.v"; -connectAttr "IMP_Rwing1_visibility.o" "IMP_Rwing1.v"; -connectAttr "IMP_Rwing1_scaleX.o" "IMP_Rwing1.sx"; -connectAttr "IMP_Rwing1_scaleY.o" "IMP_Rwing1.sy"; -connectAttr "IMP_Rwing1_scaleZ.o" "IMP_Rwing1.sz"; -connectAttr "IMP_Rwing_pointConstraint1_nodeState.o" "IMP_Rwing_pointConstraint1.nds" - ; -connectAttr "IMP_Rwing_pointConstraint1_Rwing_nullW0.o" "IMP_Rwing_pointConstraint1.w0" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetX.o" "IMP_Rwing_pointConstraint1.ox" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetY.o" "IMP_Rwing_pointConstraint1.oy" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetZ.o" "IMP_Rwing_pointConstraint1.oz" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_lelbow_visibility.o" "IMP_lelbow.v"; -connectAttr "IMP_lelbow_scaleX.o" "IMP_lelbow.sx"; -connectAttr "IMP_lelbow_scaleY.o" "IMP_lelbow.sy"; -connectAttr "IMP_lelbow_scaleZ.o" "IMP_lelbow.sz"; -connectAttr "IMP_locator3_pointConstraint1_nodeState.o" "IMP_locator3_pointConstraint1.nds" - ; -connectAttr "IMP_locator3_pointConstraint1_LloarmW0.o" "IMP_locator3_pointConstraint1.w0" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetX.o" "IMP_locator3_pointConstraint1.ox" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetY.o" "IMP_locator3_pointConstraint1.oy" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetZ.o" "IMP_locator3_pointConstraint1.oz" - ; -connectAttr "IMP_locator3_orientConstraint1_nodeState.o" "IMP_locator3_orientConstraint1.nds" - ; -connectAttr "IMP_locator3_orientConstraint1_LloarmW0.o" "IMP_locator3_orientConstraint1.w0" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetX.o" "IMP_locator3_orientConstraint1.ox" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetY.o" "IMP_locator3_orientConstraint1.oy" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetZ.o" "IMP_locator3_orientConstraint1.oz" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_relbow_visibility.o" "IMP_relbow.v"; -connectAttr "IMP_relbow_scaleX.o" "IMP_relbow.sx"; -connectAttr "IMP_relbow_scaleY.o" "IMP_relbow.sy"; -connectAttr "IMP_relbow_scaleZ.o" "IMP_relbow.sz"; -connectAttr "IMP_locator4_pointConstraint1_nodeState.o" "IMP_locator4_pointConstraint1.nds" - ; -connectAttr "IMP_locator4_pointConstraint1_RloarmW0.o" "IMP_locator4_pointConstraint1.w0" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetX.o" "IMP_locator4_pointConstraint1.ox" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetY.o" "IMP_locator4_pointConstraint1.oy" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetZ.o" "IMP_locator4_pointConstraint1.oz" - ; -connectAttr "IMP_locator4_orientConstraint1_nodeState.o" "IMP_locator4_orientConstraint1.nds" - ; -connectAttr "IMP_locator4_orientConstraint1_RloarmW0.o" "IMP_locator4_orientConstraint1.w0" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetX.o" "IMP_locator4_orientConstraint1.ox" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetY.o" "IMP_locator4_orientConstraint1.oy" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetZ.o" "IMP_locator4_orientConstraint1.oz" - ; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of jump_loop3.ma diff --git a/base/models/monsters/imp/animation/cycles/offwall.ma b/base/models/monsters/imp/animation/cycles/offwall.ma deleted file mode 100644 index 5c820042d..000000000 --- a/base/models/monsters/imp/animation/cycles/offwall.ma +++ /dev/null @@ -1,4847 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:26 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: offwall.ma -//Last modified: Tue, Apr 15, 2003 03:41:01 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 658.55033052240378 94.015818237528208 -188.91452936663802 ; - setAttr ".r" -type "double3" -1.5383527298023965 -248.59999999980516 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 734.68726213374407; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -23.262569697143597 146.09679771260525 74.762208946438633 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 14.412631977731875 662.17872283905001 133.4709355293644 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 59.1558257954932; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 30.371090381265201 37.007057017818994 815.07576647140127 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 293.34644748111657; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 747.50996588819953 57.023274860181282 51.157800715479638 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 986.42513474783084; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; - setAttr ".sp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; -createNode transform -n "pCube1"; - setAttr ".t" -type "double3" -5.6843418860808015e-014 149.26512503118903 - 202.61946759552882 ; - setAttr ".s" -type "double3" 109.54793614784964 333.64250028549338 109.54793614784964 ; -createNode mesh -n "pCubeShape1" -p "pCube1"; - setAttr -k off ".v"; - setAttr ".vir" yes; - setAttr ".vif" yes; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 8 ".vt[0:7]" -0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 - 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5; - setAttr -s 12 ".ed[0:11]" 0 1 0 2 3 - 0 4 5 0 6 7 0 0 2 0 1 - 3 0 2 4 0 3 5 0 4 6 0 - 5 7 0 6 0 0 7 1 0; - setAttr -s 6 ".fc[0:5]" -type "polyFaces" - f 4 0 5 -2 -5 - mu 0 4 0 1 3 2 - f 4 1 7 -3 -7 - mu 0 4 2 3 5 4 - f 4 2 9 -4 -9 - mu 0 4 4 5 7 6 - f 4 3 11 -1 -11 - mu 0 4 6 7 9 8 - f 4 -12 -10 -8 -6 - mu 0 4 1 10 11 3 - f 4 10 4 6 8 - mu 0 4 12 0 2 13 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 5 -size 12 -divisions 5 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".a" -type "string" ( - "playbackOptions -min 175 -max 550 -animationStartTime 175 -animationEndTime 550;"); -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 1 19 1 34 1 47 1 64 1 84 1 101 - 1 122 1 159 1 175 1 180 1 210 1 225 1 231 1 240 1 252 1 257 1 267 1 273 1 - 274 1 275 1 284 1 293 1 300 1 316 1 322 1 328 1 340 1 350 1 354 1 358 1 360 - 1 366 1 372 1 375 1 380 1 390 1; - setAttr -s 37 ".kot[0:36]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 -1.8737271154983264 19 -1.6613386989836982 - 34 -2.2826111391682247 47 -2.0126705916148353 64 -2.1398804519899386 84 -2.2788239281064477 - 101 -2.0569674839374414 122 -2.1398804519899102 159 -2.5741253126735444 175 - -1.8372203886484151 180 -1.598585186146418 210 -0.68476440307362074 225 -2.5610286432535347 - 231 -2.4532873633736756 240 -2.4532873633736756 252 -2.4532873633736756 257 - -2.4532873633736756 267 -2.4532873633736898 273 9.9686910221251708 274 10.356877844221749 - 275 10.356877844221749 284 10.356877844221749 293 28.343241194306493 300 - 26.549510598535683 316 25.229739954750627 322 3.0449695070249874 328 -9.407716971226499 - 340 -9.407716971226499 350 -10.138891185552517 354 -11.760639078078606 358 - -11.625938013748339 360 -11.322832502070817 366 -9.4685913734431395 372 -3.9705624303266589 - 375 -4.3252739750438636 380 -4.3252739750438636 390 -1.3102258449477446; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 45.289646234384705 19 43.45975447080491 - 34 44.008756581408399 47 45.211076293792118 64 45.372393621703651 84 44.849000100838595 - 101 44.681740460443386 122 46.149662836907325 159 47.245227879055243 175 - 42.933023176517956 180 43.761847822199741 210 37.691305575430782 225 28.883185839773944 - 231 150.90934151452461 240 187.71347479205821 252 224.21105195170423 257 - 242.40613443462377 267 237.61832519402316 273 227.48306248528252 274 227.16633552580294 - 275 227.16633552580294 284 227.16633552580294 293 213.38881662000136 300 - 193.65778006652243 316 185.41103708504988 322 171.6444289482842 328 156.72315665026287 - 340 156.72315665026287 350 156.08598436427036 354 153.63785004884301 358 - 153.52524824111248 360 152.66541927720232 366 144.36138966008002 372 47.704769397333173 - 375 25.113700439862086 380 26.086659789732629 390 40.131681099801071; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 -6.0211322505970015 19 -2.3856432977300397 - 34 -1.1293052870147777 47 1.8664744253246628 64 -0.019257512535769905 84 - -4.1111759504230436 101 -3.9909459832736434 122 -0.62532176989005794 159 - -1.8412922095612823 175 -1.2162693023524245 180 -0.94874875499471756 210 - 0.52665327172160337 225 4.0946461538302543 231 48.630202722564846 240 59.312502922828671 - 252 45.905229680509763 257 54.244642485181217 267 138.30975242533893 273 - 135.61768862616933 274 135.53356162812224 275 135.53356162812224 284 135.53356162812224 - 293 138.30975242533893 300 138.30975242533893 316 138.51961429876974 322 - 138.51961429876974 328 138.51961429876974 340 138.51961429876974 350 134.99353404822867 - 354 137.04803757403079 358 138.91144584358642 360 134.32063909449116 366 - 83.759861750372593 372 43.425745226706034 375 26.265817586632004 380 23.640935728429788 - 390 7.8724268641583777; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 31.313957318447539 19 34.749154858433194 - 34 36.711290435546232 47 40.504604138109976 64 44.920249942548615 84 44.963957980195794 - 101 46.976982620334901 122 51.919926485990992 159 46.15823010264635 175 46.902810848060049 - 180 43.892329927473945 210 -3.2487095644533492 225 -49.688709564452843 231 - -16.568709564453226 240 -16.568709564453226 252 -16.568709564453226 257 -16.568709564453226 - 267 -53.487452381656269 273 -82.976830421155611 274 -83.313373479756478 275 - -83.313373479756478 284 -83.313373479756478 293 -89.937730570777035 300 -99.819684344252849 - 316 -105.15996210054494 322 -108.0081119091647 328 -107.92299230550628 340 - -68.323721831942279 350 -68.373525931449336 354 -65.65592094012645 358 -66.754416528595584 - 360 -70.48476472436397 366 -128.6387205425425 372 -220.94828986870402 375 - -244.43901553826518 380 -194.83323949256427 390 -225.39274289281965; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 0 19 0 34 0 47 0 64 0 84 0 101 - 0 122 0 159 0 175 0 180 0 210 0 225 0 231 0 240 0 252 0 257 0 267 -2.8851627384779546 - 273 5.3025632790835537 274 5.5584297156941762 275 5.5584297156941762 284 - 5.5584297156941762 293 16.626621937207151 300 17.962907783462498 316 9.8532116456232774 - 322 0.59078860467235605 328 1.8738176336199384 340 -4.4793202770328389 350 - -6.1264824695506253 354 -8.3232126530100032 358 -14.998240960772259 360 -11.295016530677211 - 366 -4.197142078508266 372 -4.1971420785082678 375 -4.1971420785082705 380 - -4.1971420785082705 390 -4.1971420785082669; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 0 19 0 34 0 47 0 64 0 84 0 101 - 0 122 0 159 0 175 0 180 0 210 0 225 0 231 0 240 0 252 0 257 0 267 -38.622960847799121 - 273 -79.449016605290439 274 -80.724830857820947 275 -80.724830857820947 284 - -80.724830857820947 293 -137.33547028998819 300 -170.99903295406995 316 -195.26080954929273 - 322 -225.72004624753629 328 -221.76393561555477 340 -206.02898314232931 350 - -203.9717067981496 354 -203.7968530428534 358 -191.7154956858632 360 -190.11177893386431 - 366 -186.97326752357426 372 -186.97326752357444 375 -186.9732675235739 380 - -186.97326752357395 390 -186.9732675235737; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 1 19 1 34 1 47 1 64 1 84 1 101 - 1 122 1 159 1 175 1 180 1 210 1 225 1 231 1 240 1 252 1 257 1 267 1 273 1 - 274 1 275 1 284 1 293 1 300 1 316 1 322 1 328 1 340 1 350 1 354 1 358 1 360 - 1 366 1 372 1 375 1 380 1 390 1; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 1 19 1 34 1 47 1 64 1 84 1 101 - 1 122 1 159 1 175 1 180 1 210 1 225 1 231 1 240 1 252 1 257 1 267 1 273 1 - 274 1 275 1 284 1 293 1 300 1 316 1 322 1 328 1 340 1 350 1 354 1 358 1 360 - 1 366 1 372 1 375 1 380 1 390 1; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 37 ".ktv[0:36]" 1 1 19 1 34 1 47 1 64 1 84 1 101 - 1 122 1 159 1 175 1 180 1 210 1 225 1 231 1 240 1 252 1 257 1 267 1 273 1 - 274 1 275 1 284 1 293 1 300 1 316 1 322 1 328 1 340 1 350 1 354 1 358 1 360 - 1 366 1 372 1 375 1 380 1 390 1; - setAttr -s 37 ".kit[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; - setAttr -s 37 ".kot[19:36]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 1 228 1 265 1 267 1 273 1 274 - 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 373 1 - 379 1 390 1; - setAttr -s 20 ".kot[0:19]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 -8.5876080790523481 228 -8.5876080790523481 - 265 -8.5876080790523481 267 0.85335813357585877 273 -27.425370027547462 274 - -27.425370027547462 275 -27.425370027547462 283 -27.425370027547462 289 -27.425370027547462 - 290 -27.425370027547462 291 -27.425370027547462 292 -27.425370027547462 293 - -11.308757780772696 323 -11.465436589224687 350 -25.116892904472309 362 -25.116892904472309 - 370 0.72153011527480948 373 141.48615780020356 379 90.7278269093581 390 114.70487876162238; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 76.951251548613897 228 76.951251548613897 - 265 76.951251548613897 267 -8.0409468231916215 273 -3.991044883850996 274 - -3.991044883850996 275 -3.991044883850996 283 -3.991044883850996 289 -3.991044883850996 - 290 -3.991044883850996 291 -3.991044883850996 292 -3.991044883850996 293 - -6.4884533366523538 323 -8.3750525926228292 350 -35.385279265504266 362 -35.385279265504266 - 370 -66.036279772745772 373 -38.410664367711405 379 -33.991174624367638 390 - -67.47897379878458; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 -24.478761456972119 228 -24.478761456972119 - 265 -24.478761456972119 267 -67.371332345763037 273 -135.71766358851912 274 - -135.71766358851912 275 -135.71766358851912 283 -135.71766358851912 289 -135.71766358851912 - 290 -135.71766358851912 291 -135.71766358851912 292 -135.71766358851912 293 - 153.66859132384255 323 60.405827874392706 350 -17.970931916691971 362 -17.970931916691971 - 370 19.364807489241855 373 -67.013610191752861 379 -50.592736835079265 390 - -80.108063609287441; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 1 228 1 265 1 267 1 273 1 274 - 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 373 1 - 379 1 390 1; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 1 228 1 265 1 267 1 273 1 274 - 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 373 1 - 379 1 390 1; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 1 228 1 265 1 267 1 273 1 274 - 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 373 1 - 379 1 390 1; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 227 1 228 1 229 0 265 0 267 1 273 - 1 274 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 - 373 1 379 1 390 1; - setAttr -s 21 ".kot[0:20]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 0 228 0 265 0 267 0 273 0 274 - 0 275 0 283 0 289 0 290 0 291 0 292 0 293 0 323 0 350 0 362 0 370 0 373 0 - 379 0 390 0; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 0 228 0 265 0 267 0 273 0 274 - 0 275 0 283 0 289 0 290 0 291 0 292 0 293 0 323 0 350 0 362 0 370 0 373 0 - 379 0 390 0; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 1 228 1 265 1 267 1 273 1 274 - 1 275 1 283 1 289 1 290 1 291 1 292 1 293 1 323 1 350 1 362 1 370 1 373 1 - 379 1 390 1; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 0 228 0 265 0 267 0 273 0 274 - 0 275 0 283 0 289 0 290 0 291 0 292 0 293 0 323 0 350 0 362 0 370 0 373 0 - 379 0 390 0; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 0 228 0 265 0 267 0 273 0 274 - 0 275 0 283 0 289 0 290 0 291 0 292 0 293 0 323 0 350 0 362 0 370 0 373 0 - 379 0 390 0; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 20 ".ktv[0:19]" 227 0 228 0 265 0 267 0 273 0 274 - 0 275 0 283 0 289 0 290 0 291 0 292 0 293 0 323 0 350 0 362 0 370 0 373 0 - 379 0 390 0; - setAttr -s 20 ".kit[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; - setAttr -s 20 ".kot[5:19]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 1 229 1 267 1 268 1 269 1 270 - 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 350 1 - 362 1 371 1 375 1 390 1; - setAttr -s 22 ".kot[0:21]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 144.83137175429587 229 144.83137175429587 - 267 21.616532115679878 268 21.616532115679878 269 21.616532115679878 270 - 21.616532115679878 271 21.616532115679878 272 21.616532115679878 273 21.616532115679878 - 274 21.616532115679878 275 21.616532115679878 283 21.616532115679878 289 - -143.29144294663561 290 -143.29144294663561 291 -143.29144294663561 308 -143.29144294663561 - 316 -155.66193405299751 350 -162.31777414782641 362 -162.31777414782641 371 - 56.990718223772802 375 67.263703595818129 390 83.167214994321085; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 79.157162121524962 229 79.157162121524962 - 267 165.49918311869115 268 165.49918311869115 269 165.49918311869115 270 - 165.49918311869115 271 165.49918311869115 272 165.49918311869115 273 165.49918311869115 - 274 165.49918311869115 275 165.49918311869115 283 165.49918311869115 289 - 4.2533828847040986 290 4.2533828847040986 291 4.2533828847040986 308 4.2533828847040986 - 316 1.4130585723237974 350 -9.8834230289994771 362 -9.8834230289994771 371 - -31.962502572129765 375 -52.205102831734813 390 -82.977005048295894; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 172.09602594563279 229 172.09602594563279 - 267 70.944131901868772 268 70.944131901868772 269 70.944131901868772 270 - 70.944131901868772 271 70.944131901868772 272 70.944131901868772 273 70.944131901868772 - 274 70.944131901868772 275 70.944131901868772 283 70.944131901868772 289 - 136.3918425046943 290 136.3918425046943 291 136.3918425046943 308 136.3918425046943 - 316 59.386991251683099 350 54.514904675632295 362 54.514904675632295 371 - -49.58219201140988 375 -80.433861189468445 390 -89.516431033069338; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 1 229 1 267 1 268 1 269 1 270 - 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 350 1 - 362 1 371 1 375 1 390 1; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 1 229 1 267 1 268 1 269 1 270 - 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 350 1 - 362 1 371 1 375 1 390 1; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 1 229 1 267 1 268 1 269 1 270 - 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 350 1 - 362 1 371 1 375 1 390 1; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 228 1 229 0 265 0 267 1 268 1 269 - 1 270 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 - 350 1 362 1 371 1 375 1 390 1; - setAttr -s 23 ".kot[0:22]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 0 229 0 267 0 268 0 269 0 270 - 0 271 0 272 0 273 0 274 0 275 0 283 0 289 0 290 0 291 0 308 0 316 0 350 0 - 362 0 371 0 375 0 390 0; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 0 229 0 267 0 268 0 269 0 270 - 0 271 0 272 0 273 0 274 0 275 0 283 0 289 0 290 0 291 0 308 0 316 0 350 0 - 362 0 371 0 375 0 390 0; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 1 229 1 267 1 268 1 269 1 270 - 1 271 1 272 1 273 1 274 1 275 1 283 1 289 1 290 1 291 1 308 1 316 1 350 1 - 362 1 371 1 375 1 390 1; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 0 229 0 267 0 268 0 269 0 270 - 0 271 0 272 0 273 0 274 0 275 0 283 0 289 0 290 0 291 0 308 0 316 0 350 0 - 362 0 371 0 375 0 390 0; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 0 229 0 267 0 268 0 269 0 270 - 0 271 0 272 0 273 0 274 0 275 0 283 0 289 0 290 0 291 0 308 0 316 0 350 0 - 362 0 371 0 375 0 390 0; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 228 0 229 0 267 0 268 0 269 0 270 - 0 271 0 272 0 273 0 274 0 275 0 283 0 289 0 290 0 291 0 308 0 316 0 350 0 - 362 0 371 0 375 0 390 0; - setAttr -s 22 ".kit[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; - setAttr -s 22 ".kot[9:21]" 3 3 3 9 9 9 9 - 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 1 226 1 227 1 228 1 265 1 266 - 1 267 1 273 1 274 1 275 1 283 1 293 1 294 1 296 1 301 1 317 1 323 1 333 1 - 341 1 365 1 370 1 373 1; - setAttr -s 22 ".kot[0:21]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 -15.123893378995502 226 -15.123893378995502 - 227 -15.123893378995502 228 -9.0791887346121083 265 -7.3996203628665906 266 - -7.3996203628666191 267 -14.279021244547348 273 -5.1838804863995378 274 -4.8996573266347667 - 275 -4.8996573266347667 283 -4.8996573266347667 293 15.630452913464424 294 - 15.630452913464424 296 22.797753839688447 301 41.283658717927871 317 41.283658717927871 - 323 21.217193980762932 333 21.217193980762932 341 8.8759783341877991 365 - 8.8759783341877991 370 11.233156514493402 373 6.2181095165947227; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 0.77211996138749939 226 0.77211996138749939 - 227 23.097256987622373 228 47.936342295853962 265 13.77637077652351 266 205.27162949317182 - 267 205.27162949317182 273 230.97693312444881 274 231.78022390721856 275 - 231.78022390721856 283 231.78022390721856 293 238.83498472188091 294 238.83498472188091 - 296 233.15559115166002 301 214.96963337114005 317 214.96963337114005 323 - 170.9304344523616 333 170.9304344523616 341 160.94207353928769 365 160.94207353928769 - 370 69.136854376532398 373 -0.06975207951241913; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 -4.579364761070849 226 -4.579364761070849 - 227 -0.72546676870285154 228 10.985841470814959 265 0.99388558827314633 266 - 137.27150597409187 267 137.5520292119991 273 137.5520292119991 274 137.5520292119991 - 275 137.5520292119991 283 137.5520292119991 293 140.73302872632877 294 140.73302872632877 - 296 140.73302872632877 301 142.53527049283878 317 142.53527049283878 323 - 141.71567170555295 333 141.71567170555295 341 139.49166518283735 365 139.49166518283735 - 370 77.391735597921624 373 19.111626280712272; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 0 226 0 227 -55.573804587543236 - 228 -55.159808228151697 265 -55.159808228151697 266 -55.159808228151697 267 - -61.545914512614615 273 -61.545914512614615 274 -61.545914512614615 275 -61.545914512614615 - 283 -61.545914512614615 293 -64.062013012848809 294 -64.062013012848809 296 - -64.062013012848809 301 -160.8860305442243 317 -160.8860305442243 323 -52.364204103699528 - 333 -52.364204103699528 341 -47.334177748461983 365 -47.334177748461983 370 - 18.685801781848685 373 184.13581419708555; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 -8.1254375044848945 226 -8.1254375044848945 - 227 -8.1254375044849034 228 -8.1254375044849159 265 -8.1254375044849159 266 - -8.1254375044849159 267 -22.459944033325801 273 -22.459944033325801 274 -22.459944033325801 - 275 -22.459944033325801 283 -22.459944033325801 293 -28.522551800439185 294 - -28.522551800439185 296 -28.522551800439185 301 -99.005792853071071 317 -99.005792853071071 - 323 -63.745983700258115 333 -63.745983700258115 341 -30.224991155757944 365 - -30.224991155757944 370 -11.350316966915798 373 -11.350316966915766; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 0 226 0 227 8.0320201176309027e-016 - 228 -8.0320201176308987e-016 265 -8.0320201176308987e-016 266 -8.0320201176308987e-016 - 267 23.704430146789104 273 23.704430146789104 274 23.704430146789104 275 - 23.704430146789104 283 23.704430146789104 293 130.78863126133913 294 130.78863126133913 - 296 130.78863126133913 301 316.85219592828133 317 316.85219592828133 323 - 244.8843962332962 333 244.8843962332962 341 217.63989858300866 365 217.63989858300866 - 370 184.57875107934515 373 184.57875107934305; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 1 226 1 227 1 228 1 265 1 266 - 1 267 1 273 1 274 1 275 1 283 1 293 1 294 1 296 1 301 1 317 1 323 1 333 1 - 341 1 365 1 370 1 373 1; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 1 226 1 227 1 228 1 265 1 266 - 1 267 1 273 1 274 1 275 1 283 1 293 1 294 1 296 1 301 1 317 1 323 1 333 1 - 341 1 365 1 370 1 373 1; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 175 1 226 1 227 1 228 1 265 1 266 - 1 267 1 273 1 274 1 275 1 283 1 293 1 294 1 296 1 301 1 317 1 323 1 333 1 - 341 1 365 1 370 1 373 1; - setAttr -s 22 ".kit[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; - setAttr -s 22 ".kot[4:21]" 9 9 9 9 3 3 3 - 9 9 9 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 1 227 1 228 1 265 1 266 1 267 - 1 270 1 272 1 274 1 275 1 283 1 291 1 309 1 316 1 323 1 331 1 350 1 362 1 - 369 1 373 1 387 1 390 1; - setAttr -s 22 ".kot[0:21]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 4.3871280445984766 227 4.3871280445984766 - 228 2.707559672852959 265 4.3871280445984766 266 4.3871280445984482 267 4.3871280445984482 - 270 4.3871280445984482 272 -3.9700409894306095 274 -4.5792336923478043 275 - -4.5792336923478043 283 -4.5792336923478043 291 -0.90148035365796453 309 - -0.90148035365796453 316 17.303820859812632 323 17.303820859812632 331 -8.3844736229173602 - 350 -8.3844736229173602 362 -8.3844736229173602 369 -2.7547842075509656 373 - -16.495191933515667 387 -16.495191933515667 390 -16.495191933515667; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 1.6648666211645171 227 23.990003647399391 - 228 48.829088955630979 265 14.669117436300528 266 206.16437615294882 267 - 196.17554842963295 270 196.17554842963295 272 187.26308988857255 274 189.41572080152315 - 275 189.41572080152315 283 189.41572080152315 291 216.44805387530357 309 - 216.44805387530357 316 208.9153516065596 323 208.9153516065596 331 177.61865215834331 - 350 177.61865215834331 362 177.61865215834331 369 113.17326150302826 373 - 0.99346846446849923 387 0.99346846446849923 390 8.1561436181880147; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 -8.2514949399869195 227 -4.3975969476189221 - 228 7.3137112918988887 265 -2.6782445906429242 266 133.5993757951758 267 - 139.19034231159245 270 139.19034231159245 272 139.19034231159245 274 139.24116008935454 - 275 139.24116008935454 283 139.24116008935454 291 139.66024768586121 309 - 139.66024768586121 316 141.54453920092178 323 141.54453920092178 331 141.54286347980323 - 350 141.54286347980323 362 141.54286347980323 369 85.855668646633589 373 - 30.927422016795276 387 30.927422016795276 390 21.009871803952876; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 0 227 -55.573804587543258 228 - -55.159808228151761 265 -55.159808228151761 266 -55.159808228151761 267 -37.06930371327536 - 270 -37.06930371327536 272 -37.06930371327536 274 -39.521180083344248 275 - -39.521180083344248 283 -39.521180083344248 291 -59.741484657790053 309 -59.741484657790053 - 316 -21.273574484401578 323 -21.273574484401578 331 -87.521307747581858 350 - -87.521307747581858 362 -87.521307747581858 369 -4.4744016157092537 373 184.6368060838486 - 387 184.6368060838486 390 152.37183134268415; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 18.296137987022 227 18.296137987022018 - 228 18.296137987022 265 18.296137987022 266 18.296137987022 267 -0.23858382514771123 - 270 -0.23858382514771123 272 -0.23858382514771123 274 0.22386133590240365 - 275 0.22386133590240365 283 0.22386133590240365 291 4.0375862983218544 309 - 4.0375862983218544 316 79.532383494430391 323 79.532383494430391 331 82.583531280463575 - 350 82.583531280463575 362 82.583531280463575 369 20.912199614131278 373 - 13.129447800812493 387 13.129447800812493 390 13.129447800812487; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 0 227 -1.6749517809334143e-015 - 228 1.6749517809334143e-015 265 1.6749517809334143e-015 266 1.6749517809334143e-015 - 267 15.115251311429674 270 15.115251311429674 272 15.115251311429674 274 - 27.441956250003088 275 27.441956250003088 283 27.441956250003088 291 129.09868332230459 - 309 129.09868332230459 316 180.42106283374238 323 180.42106283374238 331 - 150.10915495042997 350 150.10915495042997 362 150.10915495042997 369 213.02246013652058 - 373 181.03896715644348 387 181.03896715644348 390 181.03896715644314; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 1 227 1 228 1 265 1 266 1 267 - 1 270 1 272 1 274 1 275 1 283 1 291 1 309 1 316 1 323 1 331 1 350 1 362 1 - 369 1 373 1 387 1 390 1; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 1 227 1 228 1 265 1 266 1 267 - 1 270 1 272 1 274 1 275 1 283 1 291 1 309 1 316 1 323 1 331 1 350 1 362 1 - 369 1 373 1 387 1 390 1; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 22 ".ktv[0:21]" 226 1 227 1 228 1 265 1 266 1 267 - 1 270 1 272 1 274 1 275 1 283 1 291 1 309 1 316 1 323 1 331 1 350 1 362 1 - 369 1 373 1 387 1 390 1; - setAttr -s 22 ".kit[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; - setAttr -s 22 ".kot[3:21]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3 3 3 9 3 3 9; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -3.6380577235397413 236 -3.6380577235397413 - 245 -3.6380577235397413 254 -3.6380577235397413 261 -3.6380577235397413 265 - -3.6380577235397413 266 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -5.9996743942435486 236 -5.9996743942435486 - 245 -5.9996743942435486 254 -5.9996743942435486 261 -5.9996743942435486 265 - -5.9996743942435486 266 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -2.7995714837697929 236 -2.7995714837697929 - 245 -2.7995714837697929 254 -2.7995714837697929 261 -2.7995714837697929 265 - -2.7995714837697929 266 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 26.9398870232313 236 18.63877926461285 - 245 -9.6168555357449641 254 -5.8967974572229487 261 30.127395637554674 265 - 30.430208959156598 266 30.127395637554674; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 17.338473339133191 236 10.49719443565219 - 245 22.940890099394323 254 27.409045766891701 261 11.392516471131566 265 - 11.304528863486553 266 11.392516471131566; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -6.5102200089042581 236 33.96472436225794 - 245 23.939238429974701 254 -25.988825717638758 261 -35.587876600779062 265 - -36.041416556237699 266 -35.587876600779062; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 3.8784880075680586 236 3.8784880075680586 - 245 3.8784880075680586 254 3.8784880075680586 261 3.8784880075680586 265 - 3.8784880075680586 266 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -5.9996743942435486 236 -5.9996743942435486 - 245 -5.9996743942435486 254 -5.9996743942435486 261 -5.9996743942435486 265 - -5.9996743942435486 266 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -2.7995714837697929 236 -2.7995714837697929 - 245 -2.7995714837697929 254 -2.7995714837697929 261 -2.7995714837697929 265 - -2.7995714837697929 266 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 3.7039287588755494 236 2.5126892064215616 - 245 -29.134921115470323 254 -28.919398587674639 261 8.8473770679548558 265 - 9.1367660148803118 266 8.8473770679548558; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -15.99016035269621 236 -23.499215891424843 - 245 -21.738925805446296 254 -15.816302952323923 261 -21.081643271636448 265 - -21.076635404756832 266 -21.081643271636448; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 -38.505461646388937 236 5.9315385960210136 - 245 18.1164674218724 254 -33.075709868196157 261 -69.934138196499575 265 - -70.604999945949501 266 -69.934138196499575; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 228 1 236 1 245 1 254 1 261 1 265 - 1 266 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 167 1 200 1 227 1 230 1 240 - 1 250 1 261 1 280 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 167 0 200 0 227 0 230 0 240 - 0 250 0 261 0 280 0; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.3128351505039433 167 2.3128351505039433 - 200 2.3128351505039433 227 2.3128351505039433 230 2.3128351505039433 240 - 2.3128351505039433 250 2.3128351505039433 261 2.3128351505039433 280 2.3128351505039433; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.23421866920666501 167 0.23421866920666501 - 200 0.23421866920666501 227 0.23421866920666501 230 0.23421866920666501 240 - 0.23421866920666501 250 0.23421866920666501 261 0.23421866920666501 280 0.23421866920666501; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -26.438317290203379 167 -40.813407571272059 - 200 -1.9583172902029919 227 115.04168270980961 230 -0.04572360202242106 240 - -12.398317290191384 250 -39.123801757269518 261 -2.4038017572692931 280 64.556198242732492; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 167 0 200 0 227 0 230 0 240 - 0 250 0 261 0 280 0; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 167 0 200 0 227 0 230 0 240 - 0 250 0 261 0 280 0; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 167 1 200 1 227 1 230 1 240 - 1 250 1 261 1 280 1; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 167 1 200 1 227 1 230 1 240 - 1 250 1 261 1 280 1; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 167 1 200 1 227 1 230 1 240 - 1 250 1 261 1 280 1; - setAttr -s 9 ".kit[3:8]" 3 9 9 3 3 3; - setAttr -s 9 ".kot[3:8]" 3 9 9 3 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 1 224 1 251 1 282 1 363 1 371 - 1 383 1 390 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 4.3664174709540751 224 3.3867545965885748 - 251 3.3867545965885748 282 3.3867545965885748 363 3.3867545965885748 371 - 3.3867545965885748 383 3.3867545965885748 390 3.3867545965885748; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 3.1099268747715612 224 2.1192573708760349 - 251 2.1192573708760349 282 2.1192573708760349 363 2.1192573708760349 371 - 2.1192573708760349 383 2.1192573708760349 390 2.1192573708760349; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 -3.7072105122059682 224 -3.0821078932592165 - 251 -3.0821078932592165 282 -3.0821078932592165 363 -3.0821078932592165 371 - -3.0821078932592165 383 -3.0821078932592165 390 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 13.223374574125849 224 56.425247953281428 - 251 -40.285557284590823 282 69.812514574714825 363 69.812514574714825 371 - 179.76484847599897 383 40.244880278278401 390 19.603597361558105; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 2.7101115029085507 224 -5.0907920613585329 - 251 43.286939505461781 282 -35.833316284227401 363 -35.833316284227401 371 - -56.303413580721134 383 3.7032192308766367 390 11.128610609649872; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 -22.047547046636712 224 -14.936691436575893 - 251 -29.696359038007625 282 -39.408894905149559 363 -39.408894905149559 371 - -161.31818442170544 383 -21.848362443808487 390 -15.867240586588608; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 1 224 1 251 1 282 1 363 1 371 - 1 383 1 390 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 1 224 1 251 1 282 1 363 1 371 - 1 383 1 390 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 180 1 224 1 251 1 282 1 363 1 371 - 1 383 1 390 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 12.412879749935719 224 12.412879749935719 - 251 12.412879749935719 282 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 -6.7286993982861674 224 -6.7286993982861674 - 251 -6.7286993982861674 282 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 -3.868763862603668 224 -3.868763862603668 - 251 -3.868763862603668 282 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 21.467257209710247 224 87.9236846802591 - 251 -16.6149916392839 282 52.08859604091267; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 0 224 0 251 0 282 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 0 224 0 251 0 282 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 1 224 1 251 1 282 1 360 1 370 - 1 373 1 381 1 390 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 -3.3867499999998705 224 -3.3867499999998705 - 251 -3.3867499999998705 282 -3.3867499999998705 360 -3.3867499999998705 370 - -3.3867499999998705 373 -3.3867499999998705 381 -3.3867499999998705 390 -3.3867499999998705; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 2.1192000000001707 224 2.1192000000001707 - 251 2.1192000000001707 282 2.1192000000001707 360 2.1192000000001707 370 - 2.1192000000001707 373 2.1192000000001707 381 2.1192000000001707 390 2.1192000000001707; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 -3.0821100000000254 224 -3.0821100000000254 - 251 -3.0821100000000254 282 -3.0821100000000254 360 -3.0821100000000254 370 - -3.0821100000000254 373 -3.0821100000000254 381 -3.0821100000000254 390 -3.0821100000000254; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 2.7053222475354395 224 -29.529006016926616 - 251 -61.302428034391362 282 -30.749430312853328 360 -53.143912206542765 370 - -5.4194588815699349 373 -71.33577735955005 381 33.050758712797453 390 7.0709311574472533; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 -21.49884193898183 224 18.495913006499109 - 251 -80.124812583583434 282 18.504015209371598 360 48.527652996893153 370 - 52.937630020481322 373 48.264047960372864 381 -25.731811521758253 390 9.2484939398885455; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 -18.211019312871041 224 -58.888065425498034 - 251 86.452838995552867 282 -59.977118344026948 360 -122.79781162479932 370 - -35.889813444990651 373 -90.01051104191491 381 16.476992987139667 390 4.5724227027533049; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 1 224 1 251 1 282 1 360 1 370 - 1 373 1 381 1 390 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 1 224 1 251 1 282 1 360 1 370 - 1 373 1 381 1 390 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 180 1 224 1 251 1 282 1 360 1 370 - 1 373 1 381 1 390 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 -12.41287000000041 224 -12.41287000000041 - 251 -12.41287000000041 282 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 -6.7285999999993047 224 -6.7285999999993047 - 251 -6.7285999999993047 282 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 -3.8687599999999316 224 -3.8687599999999316 - 251 -3.8687599999999316 282 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 17.852875042495878 224 74.792194986875913 - 251 13.745243843081065 282 80.548452422810087; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 0 224 0 251 0 282 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 0 224 0 251 0 282 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 180 1 224 1 251 1 282 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 1 224 1 251 1 266 1 267 1 275 - 1 282 1 320 1 352 1 353 1 361 1 362 1 367 1 375 1 390 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 -2.5294371750177831 224 -2.5294371750177831 - 251 -2.5294371750177831 266 -2.5294371750177831 267 -2.5294371750177831 275 - -2.5294371750177831 282 -2.5294371750177831 320 -2.5294371750177831 352 -2.5294371750177831 - 353 -2.5294371750177831 361 -2.5294371750177831 362 -2.5294371750177831 367 - -2.5294371750177831 375 -2.5294371750177831 390 -2.5294371750177831; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 13.481673551673362 224 13.481673551673362 - 251 13.481673551673362 266 13.481673551673362 267 13.481673551673362 275 - 13.481673551673362 282 13.481673551673362 320 13.481673551673362 352 13.481673551673362 - 353 13.481673551673362 361 13.481673551673362 362 13.481673551673362 367 - 13.481673551673362 375 13.481673551673362 390 13.481673551673362; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 -0.26635088939205875 224 -0.26635088939205875 - 251 -0.26635088939205875 266 -0.26635088939205875 267 -0.26635088939205875 - 275 -0.26635088939205875 282 -0.26635088939205875 320 -0.26635088939205875 - 352 -0.26635088939205875 353 -0.26635088939205875 361 -0.26635088939205875 - 362 -0.26635088939205875 367 -0.26635088939205875 375 -0.26635088939205875 - 390 -0.26635088939205875; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 99.74050296058293 224 99.74050296058293 - 251 99.74050296058293 266 -53.595327832536782 267 99.74050296058293 275 99.74050296058293 - 282 99.74050296058293 320 99.74050296058293 352 99.74050296058293 353 100.53778874050573 - 361 100.53778874050573 362 100.53778874050573 367 100.53778874050573 375 - 100.53778874050573 390 100.53778874050573; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 61.241182877125077 224 61.241182877125077 - 251 61.241182877125077 266 77.278830035522148 267 61.241182877125077 275 - 61.241182877125077 282 61.241182877125077 320 61.241182877125077 352 61.241182877125077 - 353 61.240561613471911 361 61.240561613471911 362 61.240561613471911 367 - 61.240561613471911 375 61.240561613471911 390 61.240561613471911; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 177.69376467901074 224 177.69376467901074 - 251 177.69376467901074 266 101.09515590485606 267 177.69376467901074 275 - 177.69376467901074 282 177.69376467901074 320 177.69376467901074 352 177.69376467901074 - 353 178.40523122443901 361 178.40523122443901 362 178.40523122443901 367 - 178.40523122443901 375 178.40523122443901 390 178.40523122443901; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 15.445123296459185 224 15.445123296459185 - 251 15.445123296459185 266 15.445123296459185 267 15.445123296459185 275 - 15.445123296459185 282 15.445123296459185 320 15.445123296459185 352 15.445123296459185 - 353 15.445123296459185 361 15.445123296459185 362 15.445123296459185 367 - 15.445123296459185 375 15.445123296459185 390 15.445123296459185; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 15.445123296459185 224 15.445123296459185 - 251 15.445123296459185 266 15.445123296459185 267 15.445123296459185 275 - 15.445123296459185 282 15.445123296459185 320 15.445123296459185 352 15.445123296459185 - 353 15.445123296459185 361 15.445123296459185 362 15.445123296459185 367 - 15.445123296459185 375 15.445123296459185 390 15.445123296459185; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 15.445123296459185 224 15.445123296459185 - 251 15.445123296459185 266 15.445123296459185 267 15.445123296459185 275 - 15.445123296459185 282 15.445123296459185 320 15.445123296459185 352 15.445123296459185 - 353 15.445123296459185 361 15.445123296459185 362 15.445123296459185 367 - 15.445123296459185 375 15.445123296459185 390 15.445123296459185; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 0 224 0 251 0 266 0 267 1 275 - 1 282 1 320 1 352 1.1305345477259587 353 1.1372238282435581 361 1 362 0 367 - 0 375 0 390 0; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 0.19999999999999996 224 1 251 - 1 266 0.32835181545914927 267 0 275 0 282 0 320 0 352 0 353 0 361 0 362 0 - 367 0 375 0 390 0; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 0 224 0 251 0 266 -0.028351815459149405 - 267 0 275 0 282 0 320 0 352 0 353 0 361 0 362 0 367 0 375 0 390 0; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 180 0 224 0 251 0 266 -0.028351815459149405 - 267 0 275 0 282 0 320 0 352 0 353 0 361 0 362 0 367 1 375 0.5 390 0; - setAttr -s 15 ".kit[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; - setAttr -s 15 ".kot[3:14]" 3 3 9 9 9 9 9 - 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 1 224 1 251 1 267 1 268 1 271 - 1 282 1 297 1 303 1 351 1 352 1 361 1 362 1 367 1 374 1 390 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 -7.5406347832540632e-013 224 - -7.5406347832540632e-013 251 -7.5406347832540632e-013 267 -7.5406347832540632e-013 - 268 -7.5406347832540632e-013 271 -7.5406347832540632e-013 282 -7.5406347832540632e-013 - 297 -7.5406347832540632e-013 303 -7.5406347832540632e-013 351 -7.5406347832540632e-013 - 352 -7.5406347832540632e-013 361 -7.5406347832540632e-013 362 -7.5406347832540632e-013 - 367 -7.5406347832540632e-013 374 -7.5406347832540632e-013 390 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 13.71946295727715 224 13.71946295727715 - 251 13.71946295727715 267 13.71946295727715 268 13.71946295727715 271 13.71946295727715 - 282 13.71946295727715 297 13.71946295727715 303 13.71946295727715 351 13.71946295727715 - 352 13.71946295727715 361 13.71946295727715 362 13.71946295727715 367 13.71946295727715 - 374 13.71946295727715 390 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 -3.0908609005564358e-013 224 - -3.0908609005564358e-013 251 -3.0908609005564358e-013 267 -3.0908609005564358e-013 - 268 -3.0908609005564358e-013 271 -3.0908609005564358e-013 282 -3.0908609005564358e-013 - 297 -3.0908609005564358e-013 303 -3.0908609005564358e-013 351 -3.0908609005564358e-013 - 352 -3.0908609005564358e-013 361 -3.0908609005564358e-013 362 -3.0908609005564358e-013 - 367 -3.0908609005564358e-013 374 -3.0908609005564358e-013 390 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 241.6757745667974 224 241.6757745667974 - 251 241.6757745667974 267 127.34067835981325 268 128.74753279516449 271 242.54442712327184 - 282 242.54442712327184 297 242.50769921422767 303 242.49770852767782 351 - 242.54442712327184 352 243.55186006665591 361 243.55186006665591 362 243.55186006665591 - 367 243.55186006665591 374 243.55186006665591 390 243.55186006665591; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 -65.376464450943217 224 -65.376464450943217 - 251 -65.376464450943217 267 -116.59698609748621 268 -118.52262569594082 271 - -128.72467062152424 282 -128.72467062152424 297 -128.71907489158892 303 -128.71755274699422 - 351 -128.72467062152424 352 -128.87815942510051 361 -128.87815942510051 362 - -128.87815942510051 367 -128.87815942510051 374 -128.87815942510051 390 -128.87815942510051; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 -290.17658859952701 224 -290.17658859952701 - 251 -290.17658859952701 267 -290.82992808309154 268 -292.98011571020351 271 - -343.99225868392136 282 -343.99225868392136 297 -343.96980717545631 303 -343.96369993970507 - 351 -343.99225868392136 352 -344.60809521307561 361 -344.60809521307561 362 - -344.60809521307561 367 -344.60809521307561 374 -344.60809521307561 390 -344.60809521307561; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 15.445123296459183 224 15.445123296459183 - 251 15.445123296459183 267 15.445123296459183 268 15.445123296459183 271 - 15.445123296459183 282 15.445123296459183 297 15.445123296459183 303 15.445123296459183 - 351 15.445123296459183 352 15.445123296459183 361 15.445123296459183 362 - 15.445123296459183 367 15.445123296459183 374 15.445123296459183 390 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 15.445123296459185 224 15.445123296459185 - 251 15.445123296459185 267 15.445123296459185 268 15.445123296459185 271 - 15.445123296459185 282 15.445123296459185 297 15.445123296459185 303 15.445123296459185 - 351 15.445123296459185 352 15.445123296459185 361 15.445123296459185 362 - 15.445123296459185 367 15.445123296459185 374 15.445123296459185 390 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 15.445123296459181 224 15.445123296459181 - 251 15.445123296459181 267 15.445123296459181 268 15.445123296459181 271 - 15.445123296459181 282 15.445123296459181 297 15.445123296459181 303 15.445123296459181 - 351 15.445123296459181 352 15.445123296459181 361 15.445123296459181 362 - 15.445123296459181 367 15.445123296459181 374 15.445123296459181 390 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 0 224 0 251 0 267 0 268 1 271 - 1 282 1 297 1.0288415320951623 303 1.0361973308115018 351 1.1225005163094903 - 352 1.1277490830822055 361 1 362 0 367 0 374 0 390 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 0.099999999999999978 224 1 - 251 1 267 1 268 0.95989964068038924 271 0 282 0 297 0 303 0 351 0 352 0 361 - 0 362 0 367 0 374 0 390 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 1 224 1 251 1 267 1 268 1 271 - 1 282 1 297 1 303 0 351 0 352 0 361 0 362 1 367 0 374 0 390 1; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 180 0 224 0 251 0 267 0 268 0.040100359319610791 - 271 1 282 1 297 1 303 0 351 0 352 0 361 0 362 1 367 1 374 0 390 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 1 267 1 282 1 290 1 293 1 300 - 1 315 1 320 1 324 1 335 1 346 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 12.959798477174113 267 16.473340651878491 - 282 16.473340651878491 290 33.286531319679881 293 33.286531319679881 300 - 12.84239318141201 315 12.84239318141201 320 -22.303185349146077 324 -22.303185349146077 - 335 -40.234480278206043 346 -40.234480278206043; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 227.76847559769891 267 225.79321472848241 - 282 225.79321472848241 290 191.4457152377328 293 191.4457152377328 300 159.40978507444268 - 315 159.40978507444268 320 151.50046016655531 324 151.50046016655531 335 - 119.51170531123591 346 119.51170531123591; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 137.73646400152586 267 144.4607056280467 - 282 144.4607056280467 290 143.55401305796258 293 143.55401305796258 300 143.55401305796258 - 315 143.55401305796258 320 143.65130979906056 324 143.65130979906056 335 - 142.33802638301404 346 142.33802638301404; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 33.892693033620276 267 -73.647033844340214 - 282 -73.647033844340214 290 -65.653374570654577 293 -65.653374570654577 300 - -47.224427734725154 315 -47.224427734725154 320 -47.36452304368747 324 -47.36452304368747 - 335 -44.49231287264314 346 -44.49231287264314; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 54.671688625550239 267 -9.0018530611648284 - 282 -9.0018530611648284 290 0.074562255402407018 293 0.074562255402407018 - 300 1.5481985508636535 315 1.5481985508636535 320 2.2482082478435772 324 - 2.2482082478435772 335 3.9983080502120738 346 3.9983080502120738; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 39.468648652835569 267 -88.402862859534252 - 282 -88.402862859534252 290 -135.3074302281361 293 -135.3074302281361 300 - -207.00116094664901 315 -207.00116094664901 320 -195.72976803137328 324 -195.72976803137328 - 335 -189.34834938513126 346 -189.34834938513126; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 1 267 1 282 1 290 1 293 1 300 - 1 315 1 320 1 324 1 335 1 346 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 0.99999999999999989 267 0.99999999999999989 - 282 0.99999999999999989 290 0.99999999999999989 293 0.99999999999999989 300 - 0.99999999999999989 315 0.99999999999999989 320 0.99999999999999989 324 0.99999999999999989 - 335 0.99999999999999989 346 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 266 0.99999999999999978 267 0.99999999999999978 - 282 0.99999999999999978 290 0.99999999999999978 293 0.99999999999999978 300 - 0.99999999999999978 315 0.99999999999999978 320 0.99999999999999978 324 0.99999999999999978 - 335 0.99999999999999978 346 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 1 268 1 270 1 277 1 289 1 303 - 1 317 1 326 1 352 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 -5.2154452967521969 268 -3.407783310269541 - 270 -3.407783310269541 277 34.03962204655717 289 34.03962204655717 303 41.708229050552198 - 317 41.708229050552198 326 -8.5247937980440724 352 -8.5247937980440724; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 263.4309699104258 268 262.69960457310611 - 270 262.69960457310611 277 247.82293657159823 289 247.82293657159823 303 - 155.2152591635566 317 155.2152591635566 326 119.82000983541387 352 119.82000983541387; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 145.43262890317143 268 144.660987309658 - 270 144.660987309658 277 144.85286352780403 289 144.85286352780403 303 145.04909644713825 - 317 145.04909644713825 326 144.78792171830889 352 144.78792171830889; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 9.4749040322149245 268 -72.179319613452051 - 270 -72.179319613452051 277 -81.553296657763639 289 -81.553296657763639 303 - -69.714007975742106 317 -69.714007975742106 326 -59.38956563879654 352 -59.38956563879654; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 -58.854902956455234 268 -14.335453509830552 - 270 -14.335453509830552 277 21.081314190176677 289 21.081314190176677 303 - 15.084879447471897 317 15.084879447471897 326 7.990273856634686 352 7.990273856634686; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 -8.3632933901642268 268 -49.01008334661114 - 270 -49.01008334661114 277 -64.709396930942248 289 -64.709396930942248 303 - -198.85998064089878 317 -198.85998064089878 326 -196.97513457308119 352 -196.97513457308119; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 1 268 1 270 1 277 1 289 1 303 - 1 317 1 326 1 352 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 0.99999999999999978 268 0.99999999999999978 - 270 0.99999999999999978 277 0.99999999999999978 289 0.99999999999999978 303 - 0.99999999999999978 317 0.99999999999999978 326 0.99999999999999978 352 0.99999999999999978; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 267 1 268 1 270 1 277 1 289 1 303 - 1 317 1 326 1 352 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 3 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 9 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 1 289 1 303 1 321 1 332 1 339 - 1 345 1 350 1 356 1 360 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 0 321 0 332 0 339 - 0 345 0 350 0 356 0 360 0; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 0 321 0 332 0 339 - 0 345 0 350 0 356 0 360 0; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 0 321 0 332 0 339 - 0 345 0 350 0 356 0 360 0; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 1 289 1 303 1 321 1 332 1 339 - 1 345 1 350 1 356 1 360 1; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 1 289 1 303 1 321 1 332 1 339 - 1 345 1 350 1 356 1 360 1; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 1 289 1 303 1 321 1 332 1 339 - 1 345 1 350 1 356 1 360 1; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 -1.4552022914442899 289 -1.4552022914442899 - 303 0.40482154021187799 321 -1.4552022914442899 332 -1.4552022914442899 339 - -0.54053867779965592 345 -1.4552022914442899 350 -1.4552022914442899 356 - -1.4552022914442899 360 -1.4552022914442899; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 -0.45214165675022822 289 -0.45214165675022822 - 303 0.62726587996320216 321 -0.45214165675022822 332 -0.45214165675022822 - 339 -0.49698220922304426 345 -0.45214165675022822 350 -0.45214165675022822 - 356 -0.45214165675022822 360 -0.45214165675022822; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 -1.2953587198947258 289 -1.2953587198947258 - 303 -1.8554398498510623 321 -1.2953587198947258 332 -1.2953587198947258 339 - -1.8603297077451715 345 -1.2953587198947258 350 -1.2953587198947258 356 -1.2953587198947258 - 360 -1.2953587198947258; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 0 321 0 332 0 339 - 0 345 0 350 0 356 0 360 0; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 0 321 0 332 0 339 - 0 345 0 350 0 356 0 360 0; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 289 0 303 88.235500450146773 - 321 103.13240312354817 332 146.67719555349075 339 121.91458615590747 345 - 147.82311114375239 350 153.67395055040285 356 135.58987523775133 360 169.59550735872367; - setAttr -s 10 ".kit[1:9]" 3 9 9 9 9 9 9 - 9 9; - setAttr -s 10 ".kot[1:9]" 3 9 9 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_ikHandle1_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 0 410 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_ikHandle1_pointConstraint1_joint9W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; -createNode animCurveTU -n "IMP_ikHandle1_pointConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 0 410 0; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_ikHandle1_pointConstraint1_joint9W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1 290 1 300 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 0 300 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 0 300 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 0 300 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1 290 1 300 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1 290 1 300 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1 290 1 300 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 -0.5607352104765746 290 -0.54089375976485077 - 300 -0.54089375976485077; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1.1840605010113316 290 1.1669750652682638 - 300 1.1669750652682638; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 1.5111508044123045 290 1.4925190104283761 - 300 1.4925190104283761; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 0 300 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 0 300 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 282 0 290 63.025357464390559 300 - 63.025357464390559; -createNode animCurveTU -n "IMP_lelbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_lelbow_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; -createNode animCurveTU -n "IMP_lelbow_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; -createNode animCurveTU -n "IMP_lelbow_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 403 1 410 1; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 1 81 1 87 1 108 1 112 1 116 - 1 121 1 127 1 191 1 198 1 203 1 208 1 212 1 214 1 217 1 219 1 222 1 223 1 - 225 1 227 1 230 1 235 1 240 1 242 1 244 1 246 1 248 1 250 1 253 1 255 1 258 - 1 262 1 275 1 297 1 324 1 349 1 357 1 362 1 365 1 369 1 373 1 376 1 379 1 - 382 1 385 1 389 1 396 1 403 1 408 1 416 1 429 1 452 1 473 1; - setAttr -s 53 ".kot[0:52]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 -0.12017666558909808 81 -0.12017666558909808 - 87 -0.12017666558909808 108 -0.12017666558909808 112 -0.12017666558909808 - 116 -0.12017666558909808 121 -0.12017666558909808 127 -0.12017666558909808 - 191 -0.12017666558909808 198 -0.12017666558909808 203 -0.12017666558909808 - 208 -0.12017666558909808 212 -0.12017666558909808 214 -0.12017666558909808 - 217 -0.12017666558909808 219 -0.12017666558909808 222 -0.12017666558909808 - 223 -0.12017666558909808 225 -0.12017666558909808 227 -0.12017666558909808 - 230 -0.12017666558909808 235 -0.12017666558909808 240 -0.12017666558909808 - 242 -0.12017666558909808 244 -0.12017666558909808 246 -0.12017666558909808 - 248 -0.12017666558909808 250 -0.12017666558909808 253 -0.12017666558909808 - 255 -0.12017666558909808 258 -0.12017666558909808 262 -0.12017666558909808 - 275 -0.12017666558909808 297 -0.12017666558909808 324 -0.12017666558909808 - 349 -0.12017666558909808 357 -0.12017666558909808 362 -0.12017666558909808 - 365 -0.12017666558909808 369 -0.12017666558909808 373 -0.12017666558909808 - 376 -0.12017666558909808 379 -0.12017666558909808 382 -0.12017666558909808 - 385 -0.12017666558909808 389 -0.12017666558909808 396 -0.12017666558909808 - 403 -0.12017666558909808 408 -0.12017666558909808 416 -0.12017666558909808 - 429 -0.12017666558909808 452 -0.12017666558909808 473 -0.12017666558909808; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 -0.724592717525262 81 -0.724592717525262 - 87 -0.724592717525262 108 -0.724592717525262 112 -0.724592717525262 116 -0.724592717525262 - 121 -0.724592717525262 127 -0.724592717525262 191 -0.724592717525262 198 - -0.724592717525262 203 -0.724592717525262 208 -0.724592717525262 212 -0.724592717525262 - 214 -0.724592717525262 217 -0.724592717525262 219 -0.724592717525262 222 - -0.724592717525262 223 -0.724592717525262 225 -0.724592717525262 227 -0.724592717525262 - 230 -0.724592717525262 235 -0.724592717525262 240 -0.724592717525262 242 - -0.724592717525262 244 -0.724592717525262 246 -0.724592717525262 248 -0.724592717525262 - 250 -0.724592717525262 253 -0.724592717525262 255 -0.724592717525262 258 - -0.724592717525262 262 -0.724592717525262 275 -0.724592717525262 297 -0.724592717525262 - 324 -0.724592717525262 349 -0.724592717525262 357 -0.724592717525262 362 - -0.724592717525262 365 -0.724592717525262 369 -0.724592717525262 373 -0.724592717525262 - 376 -0.724592717525262 379 -0.724592717525262 382 -0.724592717525262 385 - -0.724592717525262 389 -0.724592717525262 396 -0.724592717525262 403 -0.724592717525262 - 408 -0.724592717525262 416 -0.724592717525262 429 -0.724592717525262 452 - -0.724592717525262 473 -0.724592717525262; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 -0.21268105951286304 81 -0.21268105951286304 - 87 -0.21268105951286304 108 -0.21268105951286304 112 -0.21268105951286304 - 116 -0.21268105951286304 121 -0.21268105951286304 127 -0.21268105951286304 - 191 -0.21268105951286304 198 -0.21268105951286304 203 -0.21268105951286304 - 208 -0.21268105951286304 212 -0.21268105951286304 214 -0.21268105951286304 - 217 -0.21268105951286304 219 -0.21268105951286304 222 -0.21268105951286304 - 223 -0.21268105951286304 225 -0.21268105951286304 227 -0.21268105951286304 - 230 -0.21268105951286304 235 -0.21268105951286304 240 -0.21268105951286304 - 242 -0.21268105951286304 244 -0.21268105951286304 246 -0.21268105951286304 - 248 -0.21268105951286304 250 -0.21268105951286304 253 -0.21268105951286304 - 255 -0.21268105951286304 258 -0.21268105951286304 262 -0.21268105951286304 - 275 -0.21268105951286304 297 -0.21268105951286304 324 -0.21268105951286304 - 349 -0.21268105951286304 357 -0.21268105951286304 362 -0.21268105951286304 - 365 -0.21268105951286304 369 -0.21268105951286304 373 -0.21268105951286304 - 376 -0.21268105951286304 379 -0.21268105951286304 382 -0.21268105951286304 - 385 -0.21268105951286304 389 -0.21268105951286304 396 -0.21268105951286304 - 403 -0.21268105951286304 408 -0.21268105951286304 416 -0.21268105951286304 - 429 -0.21268105951286304 452 -0.21268105951286304 473 -0.21268105951286304; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 143.97979303987 81 130.87048694627813 - 87 143.97979303987 108 142.06986700034375 112 130.87048694627813 116 142.06986700034375 - 121 130.87048694627813 127 142.06986700034375 191 143.97979303987 198 155.0094007102669 - 203 59.17945379148636 208 155.0094007102669 212 59.17945379148636 214 155.0094007102669 - 217 59.17945379148636 219 155.0094007102669 222 59.17945379148636 223 155.0094007102669 - 225 59.17945379148636 227 155.0094007102669 230 59.17945379148636 235 32.99207118671859 - 240 105.37175826478149 242 45.74301936580315 244 105.37175826478149 246 45.74301936580315 - 248 105.37175826478149 250 45.74301936580315 253 105.37175826478149 255 45.74301936580315 - 258 105.37175826478149 262 21.255674522450533 275 -50.254266097338657 297 - -128.52442079951481 324 28.01722958494263 349 -28.547583321439657 357 63.050857504129979 - 362 150.96466302098312 365 46.474706047365473 369 150.96466302098312 373 - 46.474706047365473 376 150.96466302098312 379 46.474706047365473 382 150.96466302098312 - 385 46.474706047365473 389 150.96466302098312 396 57.993104387599303 403 - -148.86660714619958 408 -165.14851885205101 416 -134.04944500662211 429 -121.34714837580458 - 452 -124.96896050332234 473 -122.4108206827307; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 -25.119237776405349 81 -3.5948417717987606 - 87 -25.119237776405349 108 -9.5180691332242997 112 -3.5948417717987606 116 - -9.5180691332242997 121 -3.5948417717987606 127 -9.5180691332242997 191 -25.119237776405349 - 198 4.4500584381840369 203 11.092263147254242 208 4.4500584381840369 212 - 11.092263147254242 214 4.4500584381840369 217 11.092263147254242 219 4.4500584381840369 - 222 11.092263147254242 223 4.4500584381840369 225 11.092263147254242 227 - 4.4500584381840369 230 11.092263147254242 235 -53.170063210257261 240 1.329033652289753 - 242 -22.145332292356379 244 1.329033652289753 246 -22.145332292356379 248 - 1.329033652289753 250 -22.145332292356379 253 1.329033652289753 255 -22.145332292356379 - 258 1.329033652289753 262 -46.085947030019398 275 -11.285658889841576 297 - 48.411398229437644 324 28.412139979988989 349 -51.727412870003896 357 9.5119028628492259 - 362 38.556451648109295 365 14.273437318026236 369 38.556451648109295 373 - 14.273437318026236 376 38.556451648109295 379 14.273437318026236 382 38.556451648109295 - 385 14.273437318026236 389 38.556451648109295 396 133.56820358782903 403 - 232.1104442464007 408 215.86425967507847 416 221.0315502484475 429 222.53553291667396 - 452 198.19231922636658 473 215.79178849802108; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 -10.758168812157226 81 36.14228853993837 - 87 -10.758168812157226 108 -23.750612388697569 112 36.14228853993837 116 - -23.750612388697569 121 36.14228853993837 127 -23.750612388697569 191 -10.758168812157226 - 198 56.048903159483451 203 10.159970037792675 208 56.048903159483451 212 - 10.159970037792675 214 56.048903159483451 217 10.159970037792675 219 56.048903159483451 - 222 10.159970037792675 223 56.048903159483451 225 10.159970037792675 227 - 56.048903159483451 230 10.159970037792675 235 67.662616920613928 240 118.22554564532281 - 242 43.178884144943339 244 118.22554564532281 246 43.178884144943339 248 - 118.22554564532281 250 43.178884144943339 253 118.22554564532281 255 43.178884144943339 - 258 118.22554564532281 262 84.642103093737035 275 120.02618087728655 297 - 94.424998753881269 324 200.45158413977165 349 219.36601224521394 357 54.989366469786432 - 362 94.268217651276373 365 34.024056189749686 369 94.268217651276373 373 - 34.024056189749686 376 94.268217651276373 379 34.024056189749686 382 94.268217651276373 - 385 34.024056189749686 389 94.268217651276373 396 -56.184637770203075 403 - -121.22160051202962 408 -94.784285102598517 416 -129.68412323829099 429 -137.07529045089885 - 452 -146.27424262609586 473 -135.64702995670638; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 0.99999999999999989 81 0.99999999999999989 - 87 0.99999999999999989 108 0.99999999999999989 112 0.99999999999999989 116 - 0.99999999999999989 121 0.99999999999999989 127 0.99999999999999989 191 0.99999999999999989 - 198 0.99999999999999989 203 0.99999999999999989 208 0.99999999999999989 212 - 0.99999999999999989 214 0.99999999999999989 217 0.99999999999999989 219 0.99999999999999989 - 222 0.99999999999999989 223 0.99999999999999989 225 0.99999999999999989 227 - 0.99999999999999989 230 0.99999999999999989 235 0.99999999999999989 240 0.99999999999999989 - 242 0.99999999999999989 244 0.99999999999999989 246 0.99999999999999989 248 - 0.99999999999999989 250 0.99999999999999989 253 0.99999999999999989 255 0.99999999999999989 - 258 0.99999999999999989 262 0.99999999999999989 275 0.99999999999999989 297 - 0.99999999999999989 324 0.99999999999999989 349 0.99999999999999989 357 0.99999999999999989 - 362 0.99999999999999989 365 0.99999999999999989 369 0.99999999999999989 373 - 0.99999999999999989 376 0.99999999999999989 379 0.99999999999999989 382 0.99999999999999989 - 385 0.99999999999999989 389 0.99999999999999989 396 0.99999999999999989 403 - 0.99999999999999989 408 0.99999999999999989 416 0.99999999999999989 429 0.99999999999999989 - 452 0.99999999999999989 473 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 0.99999999999999989 81 0.99999999999999989 - 87 0.99999999999999989 108 0.99999999999999989 112 0.99999999999999989 116 - 0.99999999999999989 121 0.99999999999999989 127 0.99999999999999989 191 0.99999999999999989 - 198 0.99999999999999989 203 0.99999999999999989 208 0.99999999999999989 212 - 0.99999999999999989 214 0.99999999999999989 217 0.99999999999999989 219 0.99999999999999989 - 222 0.99999999999999989 223 0.99999999999999989 225 0.99999999999999989 227 - 0.99999999999999989 230 0.99999999999999989 235 0.99999999999999989 240 0.99999999999999989 - 242 0.99999999999999989 244 0.99999999999999989 246 0.99999999999999989 248 - 0.99999999999999989 250 0.99999999999999989 253 0.99999999999999989 255 0.99999999999999989 - 258 0.99999999999999989 262 0.99999999999999989 275 0.99999999999999989 297 - 0.99999999999999989 324 0.99999999999999989 349 0.99999999999999989 357 0.99999999999999989 - 362 0.99999999999999989 365 0.99999999999999989 369 0.99999999999999989 373 - 0.99999999999999989 376 0.99999999999999989 379 0.99999999999999989 382 0.99999999999999989 - 385 0.99999999999999989 389 0.99999999999999989 396 0.99999999999999989 403 - 0.99999999999999989 408 0.99999999999999989 416 0.99999999999999989 429 0.99999999999999989 - 452 0.99999999999999989 473 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 1 81 1 87 1 108 1 112 1 116 - 1 121 1 127 1 191 1 198 1 203 1 208 1 212 1 214 1 217 1 219 1 222 1 223 1 - 225 1 227 1 230 1 235 1 240 1 242 1 244 1 246 1 248 1 250 1 253 1 255 1 258 - 1 262 1 275 1 297 1 324 1 349 1 357 1 362 1 365 1 369 1 373 1 376 1 379 1 - 382 1 385 1 389 1 396 1 403 1 408 1 416 1 429 1 452 1 473 1; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 53 ".ktv[0:52]" 76 1 81 0 87 1 108 1.1520829770510697 - 112 0 116 1.1520829770510697 121 0 127 1.1520829770510697 191 1 198 0 203 - 0 208 0 212 0 214 0 217 0 219 0 222 0 223 0 225 0 227 0 230 0 235 1 240 0 - 242 0 244 0 246 0 248 0 250 0 253 0 255 0 258 0 262 1 275 1 297 1 324 1 349 - 0 357 0 362 0 365 0 369 0 373 0 376 0 379 0 382 0 385 0 389 0 396 1 403 1 - 408 1 416 1 429 1 452 1 473 1; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 1 81 1 87 1 108 1 112 1 116 - 1 121 1 127 1 191 1 198 1 203 1 208 1 212 1 214 1 217 1 219 1 222 1 223 1 - 225 1 227 1 230 1 232 1 235 1 240 1 242 1 244 1 246 1 248 1 250 1 253 1 255 - 1 258 1 262 1 275 1 297 1 324 1 349 1 357 1 362 1 365 1 369 1 373 1 376 1 - 379 1 382 1 385 1 389 1 396 1 403 1 408 1 416 1 429 1 452 1 473 1; - setAttr -s 54 ".kot[0:53]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 -0.24500268074642695 81 -0.24500268074642695 - 87 -0.24500268074642695 108 -0.24500268074642695 112 -0.24500268074642695 - 116 -0.24500268074642695 121 -0.24500268074642695 127 -0.24500268074642695 - 191 -0.24500268074642695 198 -0.24500268074642695 203 -0.24500268074642695 - 208 -0.24500268074642695 212 -0.24500268074642695 214 -0.24500268074642695 - 217 -0.24500268074642695 219 -0.24500268074642695 222 -0.24500268074642695 - 223 -0.24500268074642695 225 -0.24500268074642695 227 -0.24500268074642695 - 230 -0.24500268074642695 232 -0.24500268074642695 235 -0.24500268074642695 - 240 -0.24500268074642695 242 -0.24500268074642695 244 -0.24500268074642695 - 246 -0.24500268074642695 248 -0.24500268074642695 250 -0.24500268074642695 - 253 -0.24500268074642695 255 -0.24500268074642695 258 -0.24500268074642695 - 262 -0.24500268074642695 275 -0.24500268074642695 297 -0.24500268074642695 - 324 -0.24500268074642695 349 -0.24500268074642695 357 -0.24500268074642695 - 362 -0.24500268074642695 365 -0.24500268074642695 369 -0.24500268074642695 - 373 -0.24500268074642695 376 -0.24500268074642695 379 -0.24500268074642695 - 382 -0.24500268074642695 385 -0.24500268074642695 389 -0.24500268074642695 - 396 -0.24500268074642695 403 -0.24500268074642695 408 -0.24500268074642695 - 416 -0.24500268074642695 429 -0.24500268074642695 452 -0.24500268074642695 - 473 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 1.2065238412698649 81 1.2065238412698649 - 87 1.2065238412698649 108 1.2065238412698649 112 1.2065238412698649 116 1.2065238412698649 - 121 1.2065238412698649 127 1.2065238412698649 191 1.2065238412698649 198 - 1.2065238412698649 203 1.2065238412698649 208 1.2065238412698649 212 1.2065238412698649 - 214 1.2065238412698649 217 1.2065238412698649 219 1.2065238412698649 222 - 1.2065238412698649 223 1.2065238412698649 225 1.2065238412698649 227 1.2065238412698649 - 230 1.2065238412698649 232 1.2065238412698649 235 1.2065238412698649 240 - 1.2065238412698649 242 1.2065238412698649 244 1.2065238412698649 246 1.2065238412698649 - 248 1.2065238412698649 250 1.2065238412698649 253 1.2065238412698649 255 - 1.2065238412698649 258 1.2065238412698649 262 1.2065238412698649 275 1.2065238412698649 - 297 1.2065238412698649 324 1.2065238412698649 349 1.2065238412698649 357 - 1.2065238412698649 362 1.2065238412698649 365 1.2065238412698649 369 1.2065238412698649 - 373 1.2065238412698649 376 1.2065238412698649 379 1.2065238412698649 382 - 1.2065238412698649 385 1.2065238412698649 389 1.2065238412698649 396 1.2065238412698649 - 403 1.2065238412698649 408 1.2065238412698649 416 1.2065238412698649 429 - 1.2065238412698649 452 1.2065238412698649 473 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 -0.38309524546711837 81 -0.38309524546711837 - 87 -0.38309524546711837 108 -0.38309524546711837 112 -0.38309524546711837 - 116 -0.38309524546711837 121 -0.38309524546711837 127 -0.38309524546711837 - 191 -0.38309524546711837 198 -0.38309524546711837 203 -0.38309524546711837 - 208 -0.38309524546711837 212 -0.38309524546711837 214 -0.38309524546711837 - 217 -0.38309524546711837 219 -0.38309524546711837 222 -0.38309524546711837 - 223 -0.38309524546711837 225 -0.38309524546711837 227 -0.38309524546711837 - 230 -0.38309524546711837 232 -0.38309524546711837 235 -0.38309524546711837 - 240 -0.38309524546711837 242 -0.38309524546711837 244 -0.38309524546711837 - 246 -0.38309524546711837 248 -0.38309524546711837 250 -0.38309524546711837 - 253 -0.38309524546711837 255 -0.38309524546711837 258 -0.38309524546711837 - 262 -0.38309524546711837 275 -0.38309524546711837 297 -0.38309524546711837 - 324 -0.38309524546711837 349 -0.38309524546711837 357 -0.38309524546711837 - 362 -0.38309524546711837 365 -0.38309524546711837 369 -0.38309524546711837 - 373 -0.38309524546711837 376 -0.38309524546711837 379 -0.38309524546711837 - 382 -0.38309524546711837 385 -0.38309524546711837 389 -0.38309524546711837 - 396 -0.38309524546711837 403 -0.38309524546711837 408 -0.38309524546711837 - 416 -0.38309524546711837 429 -0.38309524546711837 452 -0.38309524546711837 - 473 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 -14.614862034248505 81 -38.03931458561614 - 87 -14.614862034248505 108 21.948338118828786 112 -38.03931458561614 116 - 21.948338118828786 121 -38.03931458561614 127 21.948338118828786 191 -14.614862034248505 - 198 -32.946655926864146 203 -150.76878765469937 208 -22.722896469317906 212 - -150.76878765469937 214 -22.722896469317906 217 -150.76878765469937 219 -22.722896469317906 - 222 -150.76878765469937 223 -22.722896469317906 225 -150.76878765469937 227 - -22.722896469317906 230 -150.76878765469937 232 -347.40493105798396 235 -326.4695473498324 - 240 -375.00105539757362 242 -423.24212142607155 244 -375.00105539757362 246 - -423.24212142607155 248 -375.00105539757362 250 -423.24212142607155 253 -375.00105539757362 - 255 -423.24212142607155 258 -375.00105539757362 262 -369.37801764194273 275 - -446.21573848046637 297 -448.85175954881021 324 -554.82214881196796 349 -546.5822001131462 - 357 -622.80169577035224 362 -411.36824977053112 365 -604.65179655391353 369 - -411.36824977053112 373 -604.65179655391353 376 -411.36824977053112 379 -604.65179655391353 - 382 -411.36824977053112 385 -604.65179655391353 389 -411.36824977053112 396 - -324.49700079416908 403 -297.82684011801598 408 -292.8915147267013 416 -302.13752018355405 - 429 -308.19870123977523 452 -303.40930699642439 473 -304.52903223095734; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 33.316404488343842 81 39.905226810146928 - 87 33.316404488343842 108 35.196269918576242 112 39.905226810146928 116 35.196269918576242 - 121 39.905226810146928 127 35.196269918576242 191 33.316404488343842 198 - -7.7972035397988231 203 44.692229476182632 208 3.5959844187000023 212 44.692229476182632 - 214 3.5959844187000023 217 44.692229476182632 219 3.5959844187000023 222 - 44.692229476182632 223 3.5959844187000023 225 44.692229476182632 227 3.5959844187000023 - 230 44.692229476182632 232 47.63461313759997 235 51.307261911764442 240 44.672882942132347 - 242 80.694791990944935 244 44.672882942132347 246 80.694791990944935 248 - 44.672882942132347 250 80.694791990944935 253 44.672882942132347 255 80.694791990944935 - 258 44.672882942132347 262 51.742099727642639 275 27.174253623193373 297 - -33.419570946323695 324 -29.542742843834958 349 -20.150544507411997 357 43.452654452531803 - 362 27.483001352687658 365 71.275488182830571 369 27.483001352687658 373 - 71.275488182830571 376 27.483001352687658 379 71.275488182830571 382 27.483001352687658 - 385 71.275488182830571 389 27.483001352687658 396 1.0823842426082846 403 - 33.208234614541126 408 28.734749864137815 416 39.048439817559455 429 50.832909173166115 - 452 29.424878934447349 473 60.405460083704867; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 -119.57538852061882 81 -155.63657326478847 - 87 -119.57538852061882 108 -80.559013862157059 112 -155.63657326478847 116 - -80.559013862157059 121 -155.63657326478847 127 -80.559013862157059 191 -119.57538852061882 - 198 -205.71056485981228 203 -251.42823372287296 208 -206.25864330649821 212 - -251.42823372287296 214 -206.25864330649821 217 -251.42823372287296 219 -206.25864330649821 - 222 -251.42823372287296 223 -206.25864330649821 225 -251.42823372287296 227 - -206.25864330649821 230 -251.42823372287296 232 -454.8772828003909 235 -409.56400500491952 - 240 -546.04257078496244 242 -504.67475978789537 244 -546.04257078496244 246 - -504.67475978789537 248 -546.04257078496244 250 -504.67475978789537 253 -546.04257078496244 - 255 -504.67475978789537 258 -546.04257078496244 262 -448.02014778203261 275 - -511.48664008709278 297 -500.72719140215702 324 -432.3059191154004 349 -318.00252722705164 - 357 -375.73265839675395 362 -217.84588188499393 365 -332.20841930231239 369 - -217.84588188499393 373 -332.20841930231239 376 -217.84588188499393 379 -332.20841930231239 - 382 -217.84588188499393 385 -332.20841930231239 389 -217.84588188499393 396 - -177.03605538327324 403 -28.175617508559188 408 -33.262905721451958 416 -38.867151018230494 - 429 -43.438093435596457 452 -50.362097227639325 473 -50.542363056820705; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 1.0000000000000007 81 1.0000000000000007 - 87 1.0000000000000007 108 1.0000000000000007 112 1.0000000000000007 116 1.0000000000000007 - 121 1.0000000000000007 127 1.0000000000000007 191 1.0000000000000007 198 - 1.0000000000000007 203 1.0000000000000007 208 1.0000000000000007 212 1.0000000000000007 - 214 1.0000000000000007 217 1.0000000000000007 219 1.0000000000000007 222 - 1.0000000000000007 223 1.0000000000000007 225 1.0000000000000007 227 1.0000000000000007 - 230 1.0000000000000007 232 1.0000000000000007 235 1.0000000000000007 240 - 1.0000000000000007 242 1.0000000000000007 244 1.0000000000000007 246 1.0000000000000007 - 248 1.0000000000000007 250 1.0000000000000007 253 1.0000000000000007 255 - 1.0000000000000007 258 1.0000000000000007 262 1.0000000000000007 275 1.0000000000000007 - 297 1.0000000000000007 324 1.0000000000000007 349 1.0000000000000007 357 - 1.0000000000000007 362 1.0000000000000007 365 1.0000000000000007 369 1.0000000000000007 - 373 1.0000000000000007 376 1.0000000000000007 379 1.0000000000000007 382 - 1.0000000000000007 385 1.0000000000000007 389 1.0000000000000007 396 1.0000000000000007 - 403 1.0000000000000007 408 1.0000000000000007 416 1.0000000000000007 429 - 1.0000000000000007 452 1.0000000000000007 473 1.0000000000000007; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 1.0000000000000004 81 1.0000000000000004 - 87 1.0000000000000004 108 1.0000000000000004 112 1.0000000000000004 116 1.0000000000000004 - 121 1.0000000000000004 127 1.0000000000000004 191 1.0000000000000004 198 - 1.0000000000000004 203 1.0000000000000004 208 1.0000000000000004 212 1.0000000000000004 - 214 1.0000000000000004 217 1.0000000000000004 219 1.0000000000000004 222 - 1.0000000000000004 223 1.0000000000000004 225 1.0000000000000004 227 1.0000000000000004 - 230 1.0000000000000004 232 1.0000000000000004 235 1.0000000000000004 240 - 1.0000000000000004 242 1.0000000000000004 244 1.0000000000000004 246 1.0000000000000004 - 248 1.0000000000000004 250 1.0000000000000004 253 1.0000000000000004 255 - 1.0000000000000004 258 1.0000000000000004 262 1.0000000000000004 275 1.0000000000000004 - 297 1.0000000000000004 324 1.0000000000000004 349 1.0000000000000004 357 - 1.0000000000000004 362 1.0000000000000004 365 1.0000000000000004 369 1.0000000000000004 - 373 1.0000000000000004 376 1.0000000000000004 379 1.0000000000000004 382 - 1.0000000000000004 385 1.0000000000000004 389 1.0000000000000004 396 1.0000000000000004 - 403 1.0000000000000004 408 1.0000000000000004 416 1.0000000000000004 429 - 1.0000000000000004 452 1.0000000000000004 473 1.0000000000000004; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 1.0000000000000002 81 1.0000000000000002 - 87 1.0000000000000002 108 1.0000000000000002 112 1.0000000000000002 116 1.0000000000000002 - 121 1.0000000000000002 127 1.0000000000000002 191 1.0000000000000002 198 - 1.0000000000000002 203 1.0000000000000002 208 1.0000000000000002 212 1.0000000000000002 - 214 1.0000000000000002 217 1.0000000000000002 219 1.0000000000000002 222 - 1.0000000000000002 223 1.0000000000000002 225 1.0000000000000002 227 1.0000000000000002 - 230 1.0000000000000002 232 1.0000000000000002 235 1.0000000000000002 240 - 1.0000000000000002 242 1.0000000000000002 244 1.0000000000000002 246 1.0000000000000002 - 248 1.0000000000000002 250 1.0000000000000002 253 1.0000000000000002 255 - 1.0000000000000002 258 1.0000000000000002 262 1.0000000000000002 275 1.0000000000000002 - 297 1.0000000000000002 324 1.0000000000000002 349 1.0000000000000002 357 - 1.0000000000000002 362 1.0000000000000002 365 1.0000000000000002 369 1.0000000000000002 - 373 1.0000000000000002 376 1.0000000000000002 379 1.0000000000000002 382 - 1.0000000000000002 385 1.0000000000000002 389 1.0000000000000002 396 1.0000000000000002 - 403 1.0000000000000002 408 1.0000000000000002 416 1.0000000000000002 429 - 1.0000000000000002 452 1.0000000000000002 473 1.0000000000000002; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 54 ".ktv[0:53]" 76 0 81 0.49756833412212709 87 - 0 108 -0.083104905248358493 112 0.49756833412212709 116 -0.083104905248358493 - 121 0.49756833412212709 127 -0.083104905248358493 191 0 198 0.74137779233561285 - 203 1 208 0.74137779233561285 212 1 214 0.74137779233561285 217 1 219 0.74137779233561285 - 222 1 223 0.74137779233561285 225 1 227 0.74137779233561285 230 1 232 0.67727580269795373 - 235 0 240 1 242 1 244 1 246 1 248 1 250 1 253 1 255 1 258 1 262 0 275 0 297 - 0 324 0 349 1 357 1 362 1 365 1 369 1 373 1 376 1 379 1 382 1 385 1 389 1 - 396 0 403 0 408 0 416 0 429 0 452 0 473 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 1 282 1 320 1 352 1 353 1 361 - 1 362 1 367 0 375 0 390 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 275 0 282 0 320 0 352 0 353 0 361 - 0 362 0 367 0 375 0 390 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 297 0 303 1 351 1 352 1 361 1 362 - 0 367 0 374 0 390 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 297 0 303 0 351 0 352 0 361 0 362 - 0 367 0 374 0 390 0; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 275 -max 390 -ast 275 -aet 390 "; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 1 373 1 390 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 -1.3102258449477446 373 -1.3102258449477446 - 390 -1.3102258449477446; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 112.26953576829938 373 0 390 - 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 27.841316625318409 373 27.841316625318409 - 390 7.8724268641583777; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 0 373 0 390 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 0 373 0 390 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 0 373 0 390 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 1 373 1 390 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 1 373 1 390 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 369 1 373 1 390 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 1 373 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 -6.3038863769067355 373 -6.3038863769067355; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 -44.570279979342686 373 -0.43759559521969749; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 -36.343470271195734 373 -36.343470271195734; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 0 373 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 0 373 0; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 0 373 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 1.25 373 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 1.25 373 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 363 1.25 373 1.25; -select -ne :time1; - setAttr ".o" 381; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 3 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" yes; -select -ne IMP_pCube2; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049348399 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607581 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Rupleg; - setAttr ".ra" -type "double3" 139.70607085520152 -3.1805546814635176e-015 - 90 ; - setAttr ".jo" -type "double3" 167.10526971660403 49.095322549761697 -9.9739354817997672 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lupleg; - setAttr ".ra" -type "double3" 143.98655038061756 0 90 ; - setAttr ".jo" -type "double3" 167.62253938683563 53.343417781490345 -9.9846365949429643 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_lelbow_visibility.o" "IMP_lelbow.v"; -connectAttr "IMP_lelbow_scaleX.o" "IMP_lelbow.sx"; -connectAttr "IMP_lelbow_scaleY.o" "IMP_lelbow.sy"; -connectAttr "IMP_lelbow_scaleZ.o" "IMP_lelbow.sz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pCubeShape1.iog" ":initialShadingGroup.dsm" -na; -// End of offwall.ma diff --git a/base/models/monsters/imp/animation/cycles/on4_idle.ma b/base/models/monsters/imp/animation/cycles/on4_idle.ma deleted file mode 100644 index 5b3e9e5a9..000000000 --- a/base/models/monsters/imp/animation/cycles/on4_idle.ma +++ /dev/null @@ -1,3541 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:23 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: on4_idle.ma -//Last modified: Thu, Nov 13, 2003 04:35:18 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 143.62079492121666 38.680898872494978 -53.413122162758157 ; - setAttr ".r" -type "double3" -13.530108915234779 -2751.8000000002335 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 82.434211523260203; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 73.393312726190914 19.804469755084217 -18.716187810005199 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 76.66589438746432 21.396720735023585 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 60.115549445093862; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 93.879148187933041; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 164 -ast 1 -aet 164 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 23 0 35 0 56 0 79 0 91 0 112 - 0 131 0 143 0 164 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.3128351505039433 23 2.3128351505039433 - 35 2.3128351505039433 56 2.3128351505039433 79 2.3128351505039433 91 2.3128351505039433 - 112 2.3128351505039433 131 2.3128351505039433 143 2.3128351505039433 164 - 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.23421866920666501 23 0.23421866920666501 - 35 0.23421866920666501 56 0.23421866920666501 79 0.23421866920666501 91 0.23421866920666501 - 112 0.23421866920666501 131 0.23421866920666501 143 0.23421866920666501 164 - 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 7 23 -1.6400000000002868 35 -3.4400000000003419 - 56 7 79 -1.6400000000002868 91 -3.4400000000003419 112 7 131 -1.6400000000002868 - 143 -3.4400000000003419 164 7; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.903356467361473 23 -26.90335646736148 - 35 -26.903356467361476 56 -26.903356467361473 79 -26.90335646736148 91 -26.903356467361476 - 112 -26.903356467361473 131 -26.90335646736148 143 -26.903356467361476 164 - -26.903356467361473; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.011069830747704 23 15.011069830747717 - 35 15.011069830747713 56 15.011069830747704 79 15.011069830747717 91 15.011069830747713 - 112 15.011069830747704 131 15.011069830747717 143 15.011069830747713 164 - 15.011069830747704; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 28 1 58 1 80 1 115 1 143 1 - 164 1; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.7811807856021344 28 5.7811807856021344 - 58 5.7811807856021344 80 5.7811807856021353 115 5.7811807856021344 143 5.7811807856021344 - 164 5.7811807856021344; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 25.889387873057544 28 26.523131958326466 - 58 25.889387873057544 80 26.269634324218906 115 25.239360085597689 143 26.267290117781048 - 164 25.889387873057544; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 53.227781741534002 28 52.340540022157505 - 58 53.227781741534002 80 53.861525826802932 115 52.989394209459462 143 54.147946281375177 - 164 53.227781741534002; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 77.619347049814735 28 77.619347049814735 - 58 77.619347049814735 80 77.619347049814735 115 77.619347049814735 143 77.619347049814735 - 164 77.619347049814735; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 28 0 58 0 80 0 115 0 143 0 - 164 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.4260738755503866 28 7.4260738755503866 - 58 7.4260738755503866 80 7.4260738755503866 115 7.4260738755503866 143 7.4260738755503866 - 164 7.4260738755503866; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 28 1 58 1 80 1 115 1 143 1 - 164 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 28 1 58 1 80 1 115 1 143 1 - 164 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 28 1 58 1 80 1 115 1 143 1 - 164 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 19 1 44 1 74 1 96.332 1 109 - 1 123 1 135 1 147 1 164 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 19 0 44 0 74 0 96.332 0 109 - 0 123 0 135 0 147 0 164 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.6268319407172029 19 5.6268319407172029 - 44 5.6268319407172029 74 5.6268319407172029 96.332 5.6268319407172029 109 - 5.6268319407172029 123 5.6268319407172029 135 5.6268319407172029 147 5.6268319407172029 - 164 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -2.1098668596606802 19 -2.1098668596606802 - 44 -2.1098668596606802 74 -2.1098668596606802 96.332 -2.1098668596606802 - 109 -2.1098668596606802 123 -2.1098668596606802 135 -2.1098668596606802 147 - -2.1098668596606802 164 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 345.27271965780443 19 348.321155490499 - 44 348.321155490499 74 343.95139401286002 96.332 343.95139401286002 109 350.59074107043182 - 123 350.59074107043182 135 347.97524631186201 147 347.97524631186201 164 - 345.27271965780443; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.3179419976279476 19 -6.7990161161606126 - 44 -6.7990161161606126 74 10.547631010639803 96.332 10.547631010639803 109 - 4.3538922741238197 123 4.3538922741238197 135 11.006160829153359 147 11.006160829153359 - 164 1.3179419976279476; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -15.879152782861023 19 -7.1745394132635436 - 44 -7.1745394132635436 74 -41.391733920712802 96.332 -41.391733920712802 - 109 -23.863415136797379 123 -23.863415136797379 135 -21.618577640925643 147 - -21.618577640925643 164 -15.879152782861023; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 19 1 44 1 74 1 96.332 1 109 - 1 123 1 135 1 147 1 164 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 19 1 44 1 74 1 96.332 1 109 - 1 123 1 135 1 147 1 164 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 19 1 44 1 74 1 96.332 1 109 - 1 123 1 135 1 147 1 164 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 6 1 23 1 43 1 51 1 57 1 80 - 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -89.357473964112842 6 -90.941579558584522 - 23 -82.257348464485574 43 -95.050384163510145 51 -82.990588992012249 57 -120.65264219499377 - 80 -82.957980049975419 98 -73.820064112840726 105 -78.644026037743103 113 - -78.644026037743103 118 -64.274484016113846 127 -64.274484016113846 134 -64.274484016113846 - 140 -84.180544414861316 156 -84.180544414861316 164 -89.357473964112842; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 27.285995176624525 6 14.668459582008078 - 23 22.37690584153086 43 23.829597105165679 51 30.02199866780364 57 45.542042537996807 - 80 48.967747359056773 98 33.908278455971143 105 -9.7374870200871069 113 -9.7374870200871069 - 118 26.681693201652777 127 26.681693201652777 134 26.681693201652777 140 - 44.461343173014235 156 44.461343173014235 164 27.285995176624525; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -11.640194316301965 6 13.1215384591156 - 23 1.2894479229110605 43 7.424878868956613 51 -8.9131779640642392 57 -47.327765180398039 - 80 -28.204628199279032 98 -9.71638229745645 105 -3.118173088460757 113 -3.118173088460757 - 118 20.535020731775216 127 20.535020731775216 134 20.535020731775216 140 - -33.512066589889507 156 -33.512066589889507 164 -11.640194316301965; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 6 1 23 1 43 1 51 1 57 1 80 - 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 6 1 23 1 43 1 51 1 57 1 80 - 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 6 1 23 1 43 1 51 1 57 1 80 - 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 16 ".kit[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; - setAttr -s 16 ".kot[0:15]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 105 1.1434256346412039 113 1.1434256346412039; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 105 2.4747586019443117 113 2.4747586019443117; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 105 3.4085747911787618 113 3.4085747911787618; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.739160914831501; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -76.726154744596627; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -173.86213662459591; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 141.20709981379272; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 64.064019952206479; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 252.95011708695623; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.098430367493391069; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2938531700865199; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.5219249117522764; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -95.110993991716654; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0581001958067302; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.97887915067413922; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.386441338106027; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 135.72390740166219; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 68.064626042993012; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 176.22610035782074; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -66.065354836318264; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.775852580156471; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -91.471856426984459; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 217.7239621497128; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -61.864687108561675; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829776; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121454; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -102.79322267388413; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 53.022108389175763; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.34185235662672303; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 104.02743330242008; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 67.988981015108081; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 37.800067484309146; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.8361212914297057; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5855994671500682; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.25463676619339848; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 21.877026181853708; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.8835109760916842; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.6668705341433823; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 82.174334819999999; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.4169468409999997; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.590676942; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -156.6082625; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.351754810000003; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 168.3677892; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 66.534727176917499 164 66.534727176917499; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 164 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.2264759820026532 164 -7.2264759820026532; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 164 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 164 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 164 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 164 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 164 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 164 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".t" -type "double3" -7.392405718350501 4.230030542675058 36.754381567957459 ; - setAttr ".r" -type "double3" -7.4815773627500066 -50.847426602078386 -16.248026693665089 ; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933783 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".t" -type "double3" 7.1689522478599548 0 37.961325025704973 ; - setAttr ".r" -type "double3" -174.49049195404214 129.78625356110399 -169.93906815090079 ; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 44.896641906037516 -6.9422266998600851e-015 - -12.83707679345506 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; - setAttr ".v" yes; - setAttr ".t" -type "double3" 89.060937550000006 6.4996370350000001 -18.214943030000001 ; - setAttr ".r" -type "double3" 47.63135552 79.9108418 3.4514964969999999 ; - setAttr ".s" -type "double3" 1 1 1 ; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FLAT"; -select -ne IMP_RHAND_ROT; - setAttr -k on ".Flat"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of on4_idle.ma diff --git a/base/models/monsters/imp/animation/cycles/on4_melee1.ma b/base/models/monsters/imp/animation/cycles/on4_melee1.ma deleted file mode 100644 index 56361874d..000000000 --- a/base/models/monsters/imp/animation/cycles/on4_melee1.ma +++ /dev/null @@ -1,4852 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:24 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: on4_melee1.ma -//Last modified: Thu, Nov 13, 2003 05:15:16 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 188.36374514524167 29.336963941449422 34.957948589908561 ; - setAttr ".r" -type "double3" -3.9301089187174805 -2449.0000000007158 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 109.58910353117189; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 73.393312726190914 19.804469755084217 -18.716187810005199 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 76.66589438746432 21.396720735023585 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 79.219103619322951; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 18.681463597477045 -5.4655275657049325 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 89.323072030664264; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 22 -ast 1 -aet 22 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.08568 22 -1.08568; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537988160630093 22 4.1537988160630093; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185075120832098 22 4.6185075120832098; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8119691574396866 22 -5.8119691574396866; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9186219656239931 22 5.9186219656239931; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.1258655568218376 22 -4.1258655568218376; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.085679155728795 22 1.085679155728795; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537911794025533 22 4.1537911794025533; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185070801020824 22 4.6185070801020824; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3244262317670241 22 -6.3244262317670241; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0332012531196431 22 1.0332012531196431; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.463963295533194 22 8.463963295533194; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 22 1; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 20 0 22 0; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.3128351505039433 20 2.3128351505039433 - 22 2.3128351505039433; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.23421866920666501 20 0.23421866920666501 - 22 0.23421866920666501; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 7 20 -1.6400000000002868 22 7; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 0.99182963371276855 1; - setAttr -s 3 ".kiy[1:2]" -0.12756963074207306 0; - setAttr -s 3 ".kox[1:2]" 0.99182963371276855 1; - setAttr -s 3 ".koy[1:2]" -0.12756957113742828 0; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -26.903356467361473 20 -26.90335646736148 - 22 -26.903356467361473; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.011069830747704 20 15.011069830747717 - 22 15.011069830747704; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 22 1; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 22 1; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20 1 22 1; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9.712 1 12.568 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 5 5 5 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 5.7811807856021344 5 5.7811807856021344 - 9.712 2.8507602504419642 12.568 10.948348138606914 22 5.7811807856021344; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 25.889387873057544 5 26.36950248027216 - 9.712 30.212892148693967 12.568 31.567547827585148 22 25.889387873057544; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 53.227781741534002 5 51.031854031468363 - 9.712 51.057211899049314 12.568 52.129031712193637 22 53.227781741534002; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 77.619347049814735 5 83.426502523177476 - 9.712 87.964378195603032 12.568 88.124026039010673 22 77.619347049814735; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 -16.147189699425542 9.712 - -4.5002264694654297 12.568 22.852158072889264 22 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 7.4260738755503866 5 9.1324908831387912 - 9.712 -18.764848656244311 12.568 6.5269946612670546 22 7.4260738755503866; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9.712 1 12.568 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9.712 1 12.568 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 9.712 1 12.568 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 16 1 22 1; - setAttr -s 4 ".kit[1:3]" 9 9 1; - setAttr -s 4 ".kot[1:3]" 5 5 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6 0 16 0 22 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.6268319407172029 6 5.6268319407172029 - 16 5.6268319407172029 22 5.6268319407172029; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.1098668596606802 6 -2.1098668596606802 - 16 -2.1098668596606802 22 -2.1098668596606802; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 345.27271965780443 6 362.84110163073296 - 16 326.38578674792439 22 345.27271965780443; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.3179419976279476 6 14.300573821540183 - 16 13.464052920493558 22 1.3179419976279476; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -15.879152782861023 6 -17.927870184702993 - 16 -9.099122169600216 22 -15.879152782861023; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 16 1 22 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 16 1 22 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6 1 16 1 22 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 1; - setAttr -s 4 ".kot[0:3]" 3 9 9 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 4 1 11.144 1 20 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 5 5 5 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -89.357473964112842 4 -122.87977582374819 - 11.144 -94.208853744351899 20 -104.24643880396567 22 -89.357473964112842; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 27.285995176624525 4 28.29504540194392 - 11.144 19.625494165357832 20 27.30369299997675 22 27.285995176624525; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -11.640194316301965 4 -13.35074612575438 - 11.144 -16.828279599761938 20 -17.896269604230742 22 -11.640194316301965; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 4 1 11.144 1 20 1 22 1; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 4 1 11.144 1 20 1 22 1; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 4 1 11.144 1 20 1 22 1; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.1434256346412039 4 1.1434256346412039 - 11.144 1.1434256346412039 20 1.1434256346412039 22 1.1434256346412039; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.4747586019443117 4 2.4747586019443117 - 11.144 2.4747586019443117 20 2.4747586019443117 22 2.4747586019443117; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 3.4085747911787618 4 3.4085747911787618 - 11.144 3.4085747911787618 20 3.4085747911787618 22 3.4085747911787618; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 9 1 11 1 15 1 20 1 22 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 1 1; - setAttr -s 7 ".kot[0:6]" 3 5 5 5 5 5 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.5406347832540632e-013 7 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 11 -7.5406347832540632e-013 15 -7.5406347832540632e-013 - 20 -7.5406347832540632e-013 22 -7.5406347832540632e-013; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.71946295727715 7 13.71946295727715 - 9 13.71946295727715 11 13.71946295727715 15 13.71946295727715 20 13.71946295727715 - 22 13.71946295727715; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0908609005564358e-013 7 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 11 -3.0908609005564358e-013 15 -3.0908609005564358e-013 - 20 -3.0908609005564358e-013 22 -3.0908609005564358e-013; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 77.739160914831501 7 77.739160914831501 - 9 77.739160914831501 11 77.739160914831501 15 77.739160914831501 20 77.739160914831501 - 22 77.739160914831501; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -76.726154744596627 7 -76.726154744596627 - 9 -76.726154744596627 11 -76.726154744596627 15 -76.726154744596627 20 -76.726154744596627 - 22 -76.726154744596627; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -173.86213662459591 7 -173.86213662459591 - 9 -173.86213662459591 11 -173.86213662459591 15 -173.86213662459591 20 -173.86213662459591 - 22 -173.86213662459591; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459183 7 15.445123296459183 - 9 15.445123296459183 11 15.445123296459183 15 15.445123296459183 20 15.445123296459183 - 22 15.445123296459183; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 7 15.445123296459185 - 9 15.445123296459185 11 15.445123296459185 15 15.445123296459185 20 15.445123296459185 - 22 15.445123296459185; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459181 7 15.445123296459181 - 9 15.445123296459181 11 15.445123296459181 15 15.445123296459181 20 15.445123296459181 - 22 15.445123296459181; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 9 1 11 1 15 1 20 1 22 1; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 9 1 11 0 15 0 20 0 22 0; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 9 0 11 0 15 0 20 0 22 0; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 9 0 11 1 15 1 20 0 22 0; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.5 7 1 9 0 11 0 15 0 20 1 22 - 0.5; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 9 0 11 0 15 0 20 0 22 0; - setAttr -s 7 ".kit[5:6]" 1 1; - setAttr -s 7 ".kot[6]" 1; - setAttr -s 7 ".kix[5:6]" 1 1; - setAttr -s 7 ".kiy[5:6]" 0 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.5294371750177831 22 -2.5294371750177831; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 13.481673551673362 22 13.481673551673362; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.26635088939205875 22 -0.26635088939205875; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 141.20709981379272 22 141.20709981379272; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 64.064019952206479 22 64.064019952206479; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 252.95011708695623 22 252.95011708695623; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 22 15.445123296459185; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 22 15.445123296459185; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 15.445123296459185 22 15.445123296459185; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5 22 0.5; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 9 1 10.432 1 13 1 19 1 - 22 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 1; - setAttr -s 7 ".kot[0:6]" 3 5 5 5 5 5 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 5 0 9 0 10.432 0 13 0 19 0 - 22 0; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 5 0 9 0 10.432 0 13 0 19 0 - 22 0; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 5 0 9 0 10.432 0 13 0 19 0 - 22 0; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 9 1 10.432 1 13 1 19 1 - 22 1; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 9 1 10.432 1 13 1 19 1 - 22 1; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 5 1 9 1 10.432 1 13 1 19 1 - 22 1; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.098430367493391069 5 0.098430367493391069 - 9 0.098430367493391069 10.432 0.098430367493391069 13 0.098430367493391069 - 19 0.098430367493391069 22 0.098430367493391069; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.2938531700865199 5 1.2938531700865199 - 9 1.2938531700865199 10.432 1.2938531700865199 13 1.2938531700865199 19 1.2938531700865199 - 22 1.2938531700865199; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.5219249117522764 5 -1.5219249117522764 - 9 -1.5219249117522764 10.432 -1.5219249117522764 13 -1.5219249117522764 19 - -1.5219249117522764 22 -1.5219249117522764; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 5 0 9 0 10.432 0 13 0 19 0 - 22 0; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 5 0 9 0 10.432 0 13 0 19 0 - 22 0; - setAttr -s 7 ".kit[4:6]" 9 9 1; - setAttr -s 7 ".kot[4:6]" 9 9 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -82.505922498838544 5 -60.733526283867263 - 9 -1.1459155902616476 11 94.932337128486438 12 106.2172137653391 13 -199.38931270552652 - 19 -17.188733853924635 22 -82.505922498838544; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[7]" 1; - setAttr -s 8 ".koy[7]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0581001958067302 22 1.0581001958067302; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.97887915067413922 22 0.97887915067413922; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.386441338106027 22 -1.386441338106027; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 135.72390740166219 22 135.72390740166219; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 68.064626042993012 22 68.064626042993012; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 176.22610035782074 22 176.22610035782074; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -66.065354836318264 22 -66.065354836318264; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 28.775852580156471 22 28.775852580156471; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -91.471856426984459 22 -91.471856426984459; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 217.7239621497128 22 217.7239621497128; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.7758528420198658 22 6.7758528420198658; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.9388939039072284e-018 22 -6.9388939039072284e-018; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.5120444723942321e-016 22 -9.5120444723942321e-016; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -61.864687108561675 22 -61.864687108561675; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.2695897469829776 22 3.2695897469829776; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.9162979482121454 22 -6.9162979482121454; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -102.79322267388413 22 -102.79322267388413; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 53.022108389175763 22 53.022108389175763; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.34185235662672303 22 -0.34185235662672303; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 22 0.52893863520222695; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 22 0.52893863520222695; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.52893863520222695 22 0.52893863520222695; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 104.02743330242008 22 104.02743330242008; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 67.988981015108081 22 67.988981015108081; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 37.800067484309146 22 37.800067484309146; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 22 0.5814880999021691; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 22 0.5814880999021691; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.5814880999021691 22 0.5814880999021691; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.8361212914297057 22 -0.8361212914297057; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.5855994671500682 22 7.5855994671500682; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.25463676619339848 22 -0.25463676619339848; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 21.877026181853708 22 21.877026181853708; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.8835109760916842 22 -6.8835109760916842; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.6668705341433823 22 -4.6668705341433823; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 82.174334819999999 7 82.174334823634609 - 12 121.58166618891791 15 103.3064205237564 17 98.688742524231287 20 82.174334823634609 - 22 82.174334819999999; - setAttr -s 7 ".kit[0:6]" 3 3 9 1 1 1 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 1 1 1 1; - setAttr -s 7 ".kix[3:6]" 0.0084583600983023643 0.083333410322666168 - 1 1; - setAttr -s 7 ".kiy[3:6]" -0.99996423721313477 -10.989851951599121 - 7.5806347012985498e-005 0; - setAttr -s 7 ".kox[3:6]" 0.0084583666175603867 0.12500002980232239 - 1 1; - setAttr -s 7 ".koy[3:6]" -0.99996423721313477 -16.48480224609375 - 0 0; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.4169468409999997 7 3.8609192673090504 - 10 29.11113486865278 12 35.478124351197692 15 25.264958084311548 20 3.8609192673090504 - 22 5.4169468409999997; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.590676942 7 19.986680375422775 - 10 18.207828752064469 12 -18.626533320362164 15 -37.990722336995191 20 5.5906769424741469 - 22 5.590676942; - setAttr -s 7 ".kit[0:6]" 3 1 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 1 9 9 9 3 1; - setAttr -s 7 ".kix[1:6]" 0.022163737565279007 0.0053953109309077263 - 0.0037070687394589186 0.013763011433184147 1 1; - setAttr -s 7 ".kiy[1:6]" 0.99975436925888062 -0.9999854564666748 - -0.99999314546585083 0.9999052882194519 0 0; - setAttr -s 7 ".kox[1:6]" 0.022163739427924156 0.0053953109309077263 - 0.0037070687394589186 0.013763011433184147 1 1; - setAttr -s 7 ".koy[1:6]" 0.99975436925888062 -0.9999854564666748 - -0.99999314546585083 0.9999052882194519 0 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 10 1 12 1 15 1 20 1 22 - 1; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 1; - setAttr -s 7 ".kot[0:6]" 3 5 5 5 5 5 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -156.6082625 7 -156.60826252478512 - 10 -313.69115680231681 15 -165.73171487502498 20 -156.60826252478512 22 -156.6082625; - setAttr -s 6 ".kit[2:5]" 9 9 3 1; - setAttr -s 6 ".kot[2:5]" 9 9 3 1; - setAttr -s 6 ".kix[5]" 1; - setAttr -s 6 ".kiy[5]" 0; - setAttr -s 6 ".kox[5]" 1; - setAttr -s 6 ".koy[5]" 0; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 77.351754810000003 7 77.351754812025419 - 10 36.385400305072324 12 38.340348890105304 15 3.7705823780907686 20 77.351754812025419 - 22 77.351754810000003; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 168.3677892 7 168.36778920107275 - 10 78.004393828658991 12 123.34434030749674 15 114.46018653617976 20 168.36778920107275 - 22 168.3677892; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 10 1 12 1 15 1 20 1 22 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 0.99999999999999978 10 0.99999999999999978 - 12 0.99999999999999978 15 0.99999999999999978 20 0.99999999999999978 22 1; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 10 1 12 1 15 1 20 1 22 - 1; - setAttr -s 7 ".kit[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kot[0:6]" 3 3 9 9 9 3 1; - setAttr -s 7 ".kix[6]" 1; - setAttr -s 7 ".kiy[6]" 0; - setAttr -s 7 ".kox[6]" 1; - setAttr -s 7 ".koy[6]" 0; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 29.159999999997844 12.568 - 22.590616467275972 17 36.853872605888235 22 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 12.568 0 17 0 22 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 12.568 0 17 0 22 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 12.568 1 17 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 5 5 5 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 5 0 12.568 0 17 0 22 0; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.74525677667777757 5 0.74525677667777757 - 12.568 0.74525677667777757 17 0.74525677667777757 22 0.74525677667777757; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.8072476834435935 5 1.8072476834435935 - 12.568 1.8072476834435935 17 1.8072476834435935 22 1.8072476834435935; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 12.568 1 17 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 12.568 1 17 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 5 1 12.568 1 17 1 22 1; - setAttr -s 5 ".kit[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kot[0:4]" 3 9 9 9 1; - setAttr -s 5 ".kix[4]" 1; - setAttr -s 5 ".kiy[4]" 0; - setAttr -s 5 ".kox[4]" 1; - setAttr -s 5 ".koy[4]" 0; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 89.060937550000006 22 89.060937550000006; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 6.4996370350000001 22 6.4996370350000001; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -18.214943030000001 22 -18.214943030000001; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 47.63135552 22 47.63135552; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 79.9108418 22 79.9108418; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.4514964969999999 22 3.4514964969999999; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 66.534727176917499 22 66.534727176917499; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.2264759820026532 22 -7.2264759820026532; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 22 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 22 1; -select -ne :time1; - setAttr ".o" 22; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".t" -type "double3" -7.392405718350501 4.230030542675058 36.754381567957459 ; - setAttr ".r" -type "double3" -7.4815773627500066 -50.847426602078386 -16.248026693665089 ; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933783 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".t" -type "double3" 7.1689522478599548 0 37.961325025704973 ; - setAttr ".r" -type "double3" -174.49049195404214 129.78625356110399 -169.93906815090079 ; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 44.896641906037516 -6.9422266998600851e-015 - -12.83707679345506 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; - setAttr ".v" yes; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of on4_melee1.ma diff --git a/base/models/monsters/imp/animation/cycles/on4_melee2.ma b/base/models/monsters/imp/animation/cycles/on4_melee2.ma deleted file mode 100644 index a2e8e9fd3..000000000 --- a/base/models/monsters/imp/animation/cycles/on4_melee2.ma +++ /dev/null @@ -1,4167 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:24 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: on4_melee2.ma -//Last modified: Thu, Nov 13, 2003 05:00:15 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 260.62037628490174 61.240846090575353 82.213679392195161 ; - setAttr ".r" -type "double3" -12.93010891556472 -2460.5999999989508 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 158.56303403430746; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 73.393312726190914 19.804469755084217 -18.716187810005199 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 88.303401920342438 31.095322358856478 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 161.88493699298937; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 18.681463597477045 -5.4655275657049325 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 89.323072030664264; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 28 -ast 1 -aet 28 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 22.248000000000001 1 35 1 56 - 1 79 1 91 1 112 1 131 1 143 1 164 1; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 22.248000000000001 0 35 0 56 - 0 79 0 91 0 112 0 131 0 143 0 164 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.3128351505039433 22.248000000000001 - 2.3128351505039433 35 2.3128351505039433 56 2.3128351505039433 79 2.3128351505039433 - 91 2.3128351505039433 112 2.3128351505039433 131 2.3128351505039433 143 2.3128351505039433 - 164 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.23421866920666501 22.248000000000001 - 0.23421866920666501 35 0.23421866920666501 56 0.23421866920666501 79 0.23421866920666501 - 91 0.23421866920666501 112 0.23421866920666501 131 0.23421866920666501 143 - 0.23421866920666501 164 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 7 22.248000000000001 -1.6400000000002868 - 35 -3.4400000000003419 56 7 79 -1.6400000000002868 91 -3.4400000000003419 - 112 7 131 -1.6400000000002868 143 -3.4400000000003419 164 7; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.903356467361473 22.248000000000001 - -26.90335646736148 35 -26.903356467361476 56 -26.903356467361473 79 -26.90335646736148 - 91 -26.903356467361476 112 -26.903356467361473 131 -26.90335646736148 143 - -26.903356467361476 164 -26.903356467361473; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.011069830747704 22.248000000000001 - 15.011069830747717 35 15.011069830747713 56 15.011069830747704 79 15.011069830747717 - 91 15.011069830747713 112 15.011069830747704 131 15.011069830747717 143 15.011069830747713 - 164 15.011069830747704; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 22.248000000000001 1 35 1 56 - 1 79 1 91 1 112 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 22.248000000000001 1 35 1 56 - 1 79 1 91 1 112 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 22.248000000000001 1 35 1 56 - 1 79 1 91 1 112 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 10 1 18 1 23.752 1 26 1 - 28 1 58 1 80 1 115 1 143 1 164 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 9 9 9 9 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 5.7811807856021344 5 9.6918148664645436 - 10 -5.6654689082215342 18 8.0445999984719858 23.752 5.7811807856021442 26 - 5.7811807856021433 28 5.7811807856021487 58 5.7811807856021344 80 5.7811807856021353 - 115 5.7811807856021344 143 5.7811807856021344 164 5.7811807856021344; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 25.889387873057544 5 31.943949866429968 - 10 37.346740964233277 18 40.845411299225653 23.752 25.337722884924979 26 - 26.523131958326466 28 26.523131958326466 58 25.889387873057544 80 26.269634324218906 - 115 25.239360085597689 143 26.267290117781048 164 25.889387873057544; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 53.227781741534002 5 60.151012145537237 - 10 70.668531462746913 18 93.921771808323726 23.752 101.45688453519716 26 - 108.08877747484603 28 130.03857143193906 58 53.227781741534002 80 53.861525826802932 - 115 52.989394209459462 143 54.147946281375177 164 53.227781741534002; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 77.619347049814735 5 51.111912895881503 - 10 63.20562099413106 18 79.418833178988464 23.752 77.619347049814735 26 77.619347049814735 - 28 77.619347049814735 58 77.619347049814735 80 77.619347049814735 115 77.619347049814735 - 143 77.619347049814735 164 77.619347049814735; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 5 -9.3969159361361072 10 39.278246410500174 - 18 -27.116488234837163 23.752 0 26 0 28 0 58 0 80 0 115 0 143 0 164 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.4260738755503866 5 -13.945802716585503 - 10 34.215106826579586 18 -24.608135385601731 23.752 7.4260738755503866 26 - 7.4260738755503866 28 7.4260738755503866 58 7.4260738755503866 80 7.4260738755503866 - 115 7.4260738755503866 143 7.4260738755503866 164 7.4260738755503866; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 10 1 18 1 23.752 1 26 1 - 28 1 58 1 80 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 10 1 18 1 23.752 1 26 1 - 28 1 58 1 80 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 5 1 10 1 18 1 23.752 1 26 1 - 28 1 58 1 80 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 23.752 1 44 1 74 1 - 96.332 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 8 0 19 0 23.752 0 44 0 74 0 - 96.332 0 109 0 123 0 135 0 147 0 164 0; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 5.6268319407172029 8 5.6268319407172029 - 19 5.6268319407172029 23.752 5.6268319407172029 44 5.6268319407172029 74 - 5.6268319407172029 96.332 5.6268319407172029 109 5.6268319407172029 123 5.6268319407172029 - 135 5.6268319407172029 147 5.6268319407172029 164 5.6268319407172029; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -2.1098668596606802 8 -2.1098668596606802 - 19 -2.1098668596606802 23.752 -2.1098668596606802 44 -2.1098668596606802 - 74 -2.1098668596606802 96.332 -2.1098668596606802 109 -2.1098668596606802 - 123 -2.1098668596606802 135 -2.1098668596606802 147 -2.1098668596606802 164 - -2.1098668596606802; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 345.27271965780443 8 362.84110163073296 - 19 326.38578674792439 23.752 350.30353008021302 44 348.321155490499 74 343.95139401286002 - 96.332 343.95139401286002 109 350.59074107043182 123 350.59074107043182 135 - 347.97524631186201 147 347.97524631186201 164 345.27271965780443; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1.3179419976279476 8 14.300573821540183 - 19 13.464052920493558 23.752 9.0151637326740381 44 -6.7990161161606126 74 - 10.547631010639803 96.332 10.547631010639803 109 4.3538922741238197 123 4.3538922741238197 - 135 11.006160829153359 147 11.006160829153359 164 1.3179419976279476; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -15.879152782861023 8 -17.927870184702993 - 19 -9.099122169600216 23.752 -14.536444735081535 44 -7.1745394132635436 74 - -41.391733920712802 96.332 -41.391733920712802 109 -23.863415136797379 123 - -23.863415136797379 135 -21.618577640925643 147 -21.618577640925643 164 -15.879152782861023; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 23.752 1 44 1 74 1 - 96.332 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 23.752 1 44 1 74 1 - 96.332 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 23.752 1 44 1 74 1 - 96.332 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 6 1 11 1 14 1 18 1 22.248000000000001 - 1 23.752 1 28 1 43 1 51 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 - 1 156 1 164 1; - setAttr -s 21 ".kot[0:20]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 -89.357473964112842 6 -99.775604634623889 - 11 -99.18126743549837 14 -130.19486190056222 18 -116.92370213300117 22.248000000000001 - -131.85429311135462 23.752 -107.67350147859567 28 -118.8319677549016 43 -95.050384163510145 - 51 -82.990588992012249 57 -120.65264219499377 80 -82.957980049975419 98 -73.820064112840726 - 105 -78.644026037743103 113 -78.644026037743103 118 -64.274484016113846 127 - -64.274484016113846 134 -64.274484016113846 140 -84.180544414861316 156 -84.180544414861316 - 164 -89.357473964112842; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 27.285995176624525 6 34.733878023900154 - 11 -14.575242104011895 14 -5.3154883573066103 18 48.293154836553988 22.248000000000001 - 33.922415972086796 23.752 20.952333016226916 28 29.906551092127671 43 23.829597105165679 - 51 30.02199866780364 57 45.542042537996807 80 48.967747359056773 98 33.908278455971143 - 105 -9.7374870200871069 113 -9.7374870200871069 118 26.681693201652777 127 - 26.681693201652777 134 26.681693201652777 140 44.461343173014235 156 44.461343173014235 - 164 27.285995176624525; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 -11.640194316301965 6 -1.3261187274608208 - 11 9.9133465556065801 14 -7.0186154978527062 18 -37.294982859548924 22.248000000000001 - -13.338925649285748 23.752 2.4219045705494211 28 -11.475507869257086 43 7.424878868956613 - 51 -8.9131779640642392 57 -47.327765180398039 80 -28.204628199279032 98 -9.71638229745645 - 105 -3.118173088460757 113 -3.118173088460757 118 20.535020731775216 127 - 20.535020731775216 134 20.535020731775216 140 -33.512066589889507 156 -33.512066589889507 - 164 -11.640194316301965; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 6 1 11 1 14 1 18 1 22.248000000000001 - 1 23.752 1 28 1 43 1 51 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 - 1 156 1 164 1; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 6 1 11 1 14 1 18 1 22.248000000000001 - 1 23.752 1 28 1 43 1 51 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 - 1 156 1 164 1; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 21 ".ktv[0:20]" 1 1 6 1 11 1 14 1 18 1 22.248000000000001 - 1 23.752 1 28 1 43 1 51 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 - 1 156 1 164 1; - setAttr -s 21 ".kit[20]" 3; - setAttr -s 21 ".kot[20]" 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.1434256346412039 6 1.1434256346412039 - 11 1.1434256346412039 14 1.1434256346412039 18 1.1434256346412039 22.248000000000001 - 1.1434256346412039 23.752 1.1434256346412039 28 1.1434256346412039 105 1.1434256346412039 - 113 1.1434256346412039; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.4747586019443117 6 2.4747586019443117 - 11 2.4747586019443117 14 2.4747586019443117 18 2.4747586019443117 22.248000000000001 - 2.4747586019443117 23.752 2.4747586019443117 28 2.4747586019443117 105 2.4747586019443117 - 113 2.4747586019443117; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.4085747911787618 6 3.4085747911787618 - 11 3.4085747911787618 14 3.4085747911787618 18 3.4085747911787618 22.248000000000001 - 3.4085747911787618 23.752 3.4085747911787618 28 3.4085747911787618 105 3.4085747911787618 - 113 3.4085747911787618; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 5 1 6 1 14 1 19 1 23 1 - 25.248000000000001 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 5 0 6 0 14 -7.5406347832540632e-013 19 -7.5406347832540632e-013 23 -7.5406347832540632e-013 - 25.248000000000001 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 5 13.71946295727715 6 13.71946295727715 14 13.71946295727715 19 13.71946295727715 - 23 13.71946295727715 25.248000000000001 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 5 0 6 0 14 -3.0908609005564358e-013 19 -3.0908609005564358e-013 23 -3.0908609005564358e-013 - 25.248000000000001 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 77.739160914831501 3 77.739160914831501 - 5 77.739160914831501 6 77.739160914831501 14 77.739160914831501 19 77.739160914831501 - 23 77.739160914831501 25.248000000000001 77.739160914831501; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -76.726154744596627 3 -76.726154744596627 - 5 -76.726154744596627 6 -76.726154744596627 14 -76.726154744596627 19 -76.726154744596627 - 23 -76.726154744596627 25.248000000000001 -76.726154744596627; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -173.86213662459591 3 -173.86213662459591 - 5 -173.86213662459591 6 -173.86213662459591 14 -173.86213662459591 19 -173.86213662459591 - 23 -173.86213662459591 25.248000000000001 -173.86213662459591; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 5 15.445123296459183 6 15.445123296459183 14 15.445123296459183 19 15.445123296459183 - 23 15.445123296459183 25.248000000000001 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 5 15.445123296459185 6 15.445123296459185 14 15.445123296459185 19 15.445123296459185 - 23 15.445123296459185 25.248000000000001 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 5 15.445123296459181 6 15.445123296459181 14 15.445123296459181 19 15.445123296459181 - 23 15.445123296459181 25.248000000000001 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 5 1 6 1 14 1 19 1 23 1 - 25.248000000000001 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 5 0 6 0 14 0 19 0 23 0 - 25.248000000000001 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 1 5 1 6 0 14 1 19 0 23 0 - 25.248000000000001 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 5 0 6 1 14 0 19 0 23 0 - 25.248000000000001 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5 3 0 5 0 6 0 14 0 19 0 23 - 0 25.248000000000001 1; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 5 0 6 0 14 0 19 0 23 0 - 25.248000000000001 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 6 1 11 1 13 1 20 1 23 1 - 25.248000000000001 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.5294371750177831 3 -2.5294371750177831 - 6 -2.5294371750177831 11 -2.5294371750177831 13 -2.5294371750177831 20 -2.5294371750177831 - 23 -2.5294371750177831 25.248000000000001 -2.5294371750177831; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.481673551673362 3 13.481673551673362 - 6 13.481673551673362 11 13.481673551673362 13 13.481673551673362 20 13.481673551673362 - 23 13.481673551673362 25.248000000000001 13.481673551673362; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.26635088939205875 3 -0.26635088939205875 - 6 -0.26635088939205875 11 -0.26635088939205875 13 -0.26635088939205875 20 - -0.26635088939205875 23 -0.26635088939205875 25.248000000000001 -0.26635088939205875; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 141.20709981379272 3 141.20709981379272 - 6 141.20709981379272 11 141.20709981379272 13 141.20709981379272 20 141.20709981379272 - 23 141.20709981379272 25.248000000000001 141.20709981379272; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 64.064019952206479 3 64.064019952206479 - 6 64.064019952206479 11 64.064019952206479 13 64.064019952206479 20 64.064019952206479 - 23 64.064019952206479 25.248000000000001 64.064019952206479; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 252.95011708695623 3 252.95011708695623 - 6 252.95011708695623 11 252.95011708695623 13 252.95011708695623 20 252.95011708695623 - 23 252.95011708695623 25.248000000000001 252.95011708695623; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 6 15.445123296459185 11 15.445123296459185 13 15.445123296459185 20 15.445123296459185 - 23 15.445123296459185 25.248000000000001 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 6 15.445123296459185 11 15.445123296459185 13 15.445123296459185 20 15.445123296459185 - 23 15.445123296459185 25.248000000000001 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 6 15.445123296459185 11 15.445123296459185 13 15.445123296459185 20 15.445123296459185 - 23 15.445123296459185 25.248000000000001 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 6 1 11 1 13 1 20 1 23 1 - 25.248000000000001 1; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 6 0 11 0 13 0 20 0 23 0 - 25.248000000000001 0; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 6 1 11 0 13 0 20 0 23 1 - 25.248000000000001 0; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 6 0 11 0 13 1 20 0 23 0 - 25.248000000000001 0; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.5 6 0 11 0 13 0 20 0 23 0 25.248000000000001 - 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 6 0 11 0 13 0 20 0 23 0 - 25.248000000000001 0; - setAttr -s 8 ".kit[0:7]" 3 3 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 3 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 7 1 12 1 15 1 25.248000000000001 - 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 4 0 7 0 12 0 15 0 25.248000000000001 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 4 0 7 0 12 0 15 0 25.248000000000001 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 4 0 7 0 12 0 15 0 25.248000000000001 - 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 7 1 12 1 15 1 25.248000000000001 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 7 1 12 1 15 1 25.248000000000001 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 7 1 12 1 15 1 25.248000000000001 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.098430367493391069 4 0.098430367493391069 - 7 0.098430367493391069 12 0.098430367493391069 15 0.098430367493391069 25.248000000000001 - 0.098430367493391069; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.2938531700865199 4 1.2938531700865199 - 7 1.2938531700865199 12 1.2938531700865199 15 1.2938531700865199 25.248000000000001 - 1.2938531700865199; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -1.5219249117522764 4 -1.5219249117522764 - 7 -1.5219249117522764 12 -1.5219249117522764 15 -1.5219249117522764 25.248000000000001 - -1.5219249117522764; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 4 0 7 0 12 0 15 0 25.248000000000001 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 4 0 7 0 12 0 15 0 25.248000000000001 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -95.110993991716654 4 -2.2918311805232823 - 7 77.92226013779198 12 200.53522829578816 15 297.9380534680281 25.248000000000001 - 347.21242384927888; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 7 1 11 1 13 1 17 1 18 1 19 - 1 20 1 20.752 1 23.752 1 28 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 0 11 0 13 0 17 0 18 0 19 - 0 20 0 20.752 0 23.752 0 28 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 0 11 0 13 0 17 0 18 0 19 - 0 20 0 20.752 0 23.752 0 28 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 0 11 0 13 0 17 0 18 0 19 - 0 20 0 20.752 0 23.752 0 28 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 7 1 11 1 13 1 17 1 18 1 19 - 1 20 1 20.752 1 23.752 1 28 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 7 1 11 1 13 1 17 1 18 1 19 - 1 20 1 20.752 1 23.752 1 28 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 7 1 11 1 13 1 17 1 18 1 19 - 1 20 1 20.752 1 23.752 1 28 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.0581001958067302 7 1.0581001958067302 - 11 1.0581001958067302 13 1.0581001958067302 17 1.0581001958067302 18 1.0581001958067302 - 19 1.0581001958067302 20 1.0581001958067302 20.752 1.0581001958067302 23.752 - 1.0581001958067302 28 1.0581001958067302; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.97887915067413922 7 0.97887915067413922 - 11 0.97887915067413922 13 0.97887915067413922 17 0.97887915067413922 18 0.97887915067413922 - 19 0.97887915067413922 20 0.97887915067413922 20.752 0.97887915067413922 - 23.752 0.97887915067413922 28 0.97887915067413922; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -1.386441338106027 7 -1.386441338106027 - 11 -1.386441338106027 13 -1.386441338106027 17 -1.386441338106027 18 -1.386441338106027 - 19 -1.386441338106027 20 -1.386441338106027 20.752 -1.386441338106027 23.752 - -1.386441338106027 28 -1.386441338106027; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 0 11 0 13 0 17 0 18 0 19 - 0 20 0 20.752 0 23.752 0 28 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 0 11 0 13 0 17 0 18 0 19 - 0 20 0 20.752 0 23.752 0 28 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 7 -45.836623610465864 11 55.003948332559027 - 13 -40.107045659157635 17 -186.78424121264842 18 -309.93642319601867 19 -327.58952616755977 - 20 -365.94860689031759 20.752 -8.0214091318315308 23.752 -28.974001907645491 - 28 -2.2918311805232952; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 135.72390740166219; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 68.064626042993012; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 176.22610035782074; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -66.065354836318264; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.775852580156471; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -91.471856426984459; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 217.7239621497128; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -11.616248861770167; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829762; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121658; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -102.79322267388413; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 53.022108389175763; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.34185235662672303; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 104.02743330242008; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 67.988981015108081; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 37.800067484309146; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.8361212914297057; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5855994671500682; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.25463676619339848; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 21.877026181853708; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.8835109760916842; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.6668705341433823; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 82.174334819999999 6 106.25408310706433 - 8 143.62904456955377 11 123.40557909351786 16 134.3533940131303 20 148.80076870227609 - 22.248000000000001 160.99386424179738 26 183.46490295708932; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.0047459891065955162 0.012145761400461197 - 0.035913199186325073 0.014764966443181038 0.0097716329619288445 0.0072118774987757206 - 0.0069569372572004795; - setAttr -s 8 ".kiy[1:7]" 0.99998873472213745 0.99992620944976807 - -0.99935489892959595 0.99989098310470581 0.99995225667953491 0.99997401237487793 - 0.99997580051422119; - setAttr -s 8 ".kox[1:7]" 0.0047459891065955162 0.012145761400461197 - 0.035913199186325073 0.014764966443181038 0.0097716329619288445 0.0072118774987757206 - 0.0069569372572004795; - setAttr -s 8 ".koy[1:7]" 0.99998873472213745 0.99992620944976807 - -0.99935489892959595 0.99989098310470581 0.99995225667953491 0.99997401237487793 - 0.99997580051422119; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.4169468409999997 6 61.397320984706695 - 8 56.349297971780722 11 45.763662094187836 16 36.297093882181791 20 25.444335436652093 - 22.248000000000001 16.943770112340914 26 3.8609192673090504; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.0057264557108283043 0.013324765488505363 - 0.016620980575680733 0.018452193588018417 0.013450391590595245 0.011582190170884132 - 0.01194863673299551; - setAttr -s 8 ".kiy[1:7]" 0.99998360872268677 -0.99991124868392944 - -0.99986183643341064 -0.99982976913452148 -0.99990952014923096 -0.99993294477462769 - -0.99992859363555908; - setAttr -s 8 ".kox[1:7]" 0.0057264566421508789 0.013324765488505363 - 0.016620980575680733 0.018452193588018417 0.013450391590595245 0.011582190170884132 - 0.01194863673299551; - setAttr -s 8 ".koy[1:7]" 0.99998360872268677 -0.99991124868392944 - -0.99986183643341064 -0.99982976913452148 -0.99990952014923096 -0.99993294477462769 - -0.99992859363555908; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.590676942 6 25.316152341346353 - 8 -11.680775584895853 11 -40.661405777668548 16 12.444374312235873 20 13.59140337041131 - 22.248000000000001 8.4544442243166316 26 5.5906769424741469; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.016884803771972656 0.003157623577862978 - 0.013815521262586117 0.0069119189865887165 0.065109148621559143 0.031231917440891266 - 0.054508954286575317; - setAttr -s 8 ".kiy[1:7]" -0.99985742568969727 -0.99999499320983887 - 0.9999045729637146 0.99997609853744507 -0.99787813425064087 -0.99951213598251343 - -0.99851328134536743; - setAttr -s 8 ".kox[1:7]" 0.016884803771972656 0.003157623577862978 - 0.013815521262586117 0.0069119189865887165 0.065109148621559143 0.031231917440891266 - 0.054508954286575317; - setAttr -s 8 ".koy[1:7]" -0.99985742568969727 -0.99999499320983887 - 0.9999045729637146 0.99997609853744507 -0.99787813425064087 -0.99951213598251343 - -0.99851328134536743; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 8 1 11 1 16 1 20 1 22.248000000000001 - 1 26 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -156.6082625 6 -279.03303568836861 - 8 -220.30882368802673 11 -121.7482465754717 16 -170.48147038346218 20 -240.88538199108339 - 22.248000000000001 -257.64108756453294 26 -156.60826252478512; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.25375416874885559 0.075674153864383698 - 0.35790508985519409 0.17748290300369263 0.1686820387840271 0.16755950450897217 - 0.088310383260250092; - setAttr -s 8 ".kiy[1:7]" -0.96726876497268677 0.99713259935379028 - 0.9337579607963562 -0.98412388563156128 -0.98567050695419312 0.98586195707321167 - 0.9960930347442627; - setAttr -s 8 ".kox[1:7]" 0.25375425815582275 0.075674153864383698 - 0.35790508985519409 0.17748290300369263 0.1686820387840271 0.16755950450897217 - 0.088310383260250092; - setAttr -s 8 ".koy[1:7]" -0.96726870536804199 0.99713259935379028 - 0.9337579607963562 -0.98412388563156128 -0.98567050695419312 0.98586195707321167 - 0.9960930347442627; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 77.351754810000003 6 51.286427736306159 - 8 8.1515039508134315 11 -8.2129000938786216 16 -1.9689069460429205 20 79.158370425486424 - 22.248000000000001 72.724435868701264 26 77.351754812025419; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.23474349081516266 0.19669848680496216 - 0.88360816240310669 0.23880048096179962 0.19582997262477875 0.99213981628417969 - 0.88844978809356689; - setAttr -s 8 ".kiy[1:7]" -0.97205734252929688 -0.98046404123306274 - -0.46822705864906311 0.97106868028640747 0.98063784837722778 -0.1251341849565506 - 0.45897385478019714; - setAttr -s 8 ".kox[1:7]" 0.23474352061748505 0.19669848680496216 - 0.88360816240310669 0.23880048096179962 0.19582997262477875 0.99213981628417969 - 0.88844978809356689; - setAttr -s 8 ".koy[1:7]" -0.97205734252929688 -0.98046404123306274 - -0.46822705864906311 0.97106868028640747 0.98063784837722778 -0.1251341849565506 - 0.45897385478019714; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 168.3677892 6 104.68781338254634 - 8 170.98962285557164 11 111.76472035956324 16 74.145248960151733 20 73.049633792735676 - 22.248000000000001 93.232407756779068 26 168.36778920107275; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 0.9879152774810791 0.86018550395965576 - 0.19348257780075073 0.48525521159172058 0.61575061082839966 0.14860649406909943 - 0.11837649345397949; - setAttr -s 8 ".kiy[1:7]" 0.15499496459960938 0.50998127460479736 - -0.98110371828079224 -0.87437254190444946 0.7879410982131958 0.98889642953872681 - 0.99296879768371582; - setAttr -s 8 ".kox[1:7]" 0.98791539669036865 0.86018550395965576 - 0.19348257780075073 0.48525521159172058 0.61575061082839966 0.14860649406909943 - 0.11837649345397949; - setAttr -s 8 ".koy[1:7]" 0.15499418973922729 0.50998127460479736 - -0.98110371828079224 -0.87437254190444946 0.7879410982131958 0.98889642953872681 - 0.99296879768371582; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 8 1 11 1 16 1 20 1 22.248000000000001 - 1 26 1; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".kiy[1:7]" 0 0 0 0 0 0 0; - setAttr -s 8 ".kox[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".koy[1:7]" 0 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 0.99999999999999978 8 0.99999999999999978 - 11 0.99999999999999978 16 0.99999999999999978 20 0.99999999999999978 22.248000000000001 - 0.99999999999999978 26 0.99999999999999978; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".kiy[1:7]" 0 0 0 0 0 0 0; - setAttr -s 8 ".kox[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".koy[1:7]" 0 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 8 1 11 1 16 1 20 1 22.248000000000001 - 1 26 1; - setAttr -s 8 ".kit[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 1 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".kiy[1:7]" 0 0 0 0 0 0 0; - setAttr -s 8 ".kox[1:7]" 1 1 1 1 1 1 1; - setAttr -s 8 ".koy[1:7]" 0 0 0 0 0 0 0; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 29.159999999997844 16 22.590616467275972 - 20 36.853872605888235 23.752 1.2138726058909635; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 23.752 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 23.752 0; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 23.752 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 23.752 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.74525677667777757 7 0.74525677667777757 - 16 0.74525677667777757 20 0.74525677667777757 23.752 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.8072476834435935 7 1.8072476834435935 - 16 1.8072476834435935 20 1.8072476834435935 23.752 1.8072476834435935; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 23.752 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 23.752 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 23.752 1; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 89.060937550000006 3.04 89.060937550000006 - 7 87.737039250992353 11 96.101105575169754 13 142.40935689544878 16 148.26027644375552 - 18 155.45569127925432 22.248000000000001 168.07053049522614 25.248000000000001 - 163.82747917683471; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.0045726504176855087 0.0039941519498825073 - 0.015966689214110374 0.013140208087861538 0.036050088703632355 0.029447168111801147; - setAttr -s 9 ".kiy[2:8]" 2.8950926207471639e-005 0.99998956918716431 - 0.9999920129776001 0.99987250566482544 0.99991369247436523 0.99935001134872437 - -0.99956631660461426; - setAttr -s 9 ".kox[2:8]" 1 0.0045726504176855087 0.0039941519498825073 - 0.015966689214110374 0.013140208087861538 0.036050088703632355 0.029447168111801147; - setAttr -s 9 ".koy[2:8]" 0 0.99998956918716431 0.9999920129776001 - 0.99987250566482544 0.99991369247436523 0.99935001134872437 -0.99956631660461426; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 6.4996370350000001 3.04 6.4996370350000001 - 7 36.694679308673678 11 79.35597265781476 13 68.209317284874388 16 50.08933739790794 - 18 39.426103611030896 22.248000000000001 25.287551015007168 25.248000000000001 - 3.7982393257906111; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.0079325716942548752 0.0071182786487042904 - 0.0072378255426883698 0.010495977476239204 0.0084762070327997208 0.0058167497627437115; - setAttr -s 9 ".kiy[2:8]" 0 0.99996852874755859 -0.99997466802597046 - -0.9999738335609436 -0.99994492530822754 -0.99996405839920044 -0.99998307228088379; - setAttr -s 9 ".kox[2:8]" 1 0.0079325716942548752 0.0071182786487042904 - 0.0072378255426883698 0.010495977476239204 0.0084762070327997208 0.0058167497627437115; - setAttr -s 9 ".koy[2:8]" 0 0.99996852874755859 -0.99997466802597046 - -0.9999738335609436 -0.99994492530822754 -0.99996405839920044 -0.99998307228088379; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -18.214943030000001 3.04 -18.214943030000001 - 7 -24.681284073904788 11 -29.320534138059152 13 -11.664695184569453 16 17.649998039919868 - 18 5.5026469182520934 22.248000000000001 -19.89532699299404 25.248000000000001 - -18.214943034405117; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.019202718511223793 0.0044353613629937172 - 0.01213455107063055 0.0069336746819317341 0.012732133269309998 0.07418283075094223; - setAttr -s 9 ".kiy[2:8]" 0 0.99981558322906494 0.99999016523361206 - 0.99992638826370239 -0.99997597932815552 -0.99991893768310547 0.99724465608596802; - setAttr -s 9 ".kox[2:8]" 1 0.019202718511223793 0.0044353613629937172 - 0.01213455107063055 0.0069336746819317341 0.012732133269309998 0.07418283075094223; - setAttr -s 9 ".koy[2:8]" 0 0.99981558322906494 0.99999016523361206 - 0.99992638826370239 -0.99997597932815552 -0.99991893768310547 0.99724465608596802; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.04 1 7 1 11 1 13 1 16 1 18 - 1 22.248000000000001 1 25.248000000000001 1; - setAttr -s 9 ".kit[0:8]" 3 3 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 5 5 5 5 5 - 5 5; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 47.63135552 3.04 47.63135552 - 7 72.193940716242977 11 -23.249304833007958 13 83.111114254504429 16 228.71808680169207 - 18 227.98213759744283 22.248000000000001 154.41308554935048 25.248000000000001 - 47.631355515172437; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.79533290863037109 0.04732060432434082 - 0.082116544246673584 0.19681389629840851 0.095504060387611389 0.066920816898345947; - setAttr -s 9 ".kiy[2:8]" 0 0.60617291927337646 0.99887973070144653 - 0.99662274122238159 -0.98044085502624512 -0.99542903900146484 -0.99775826930999756; - setAttr -s 9 ".kox[2:8]" 1 0.79533290863037109 0.04732060432434082 - 0.082116544246673584 0.19681389629840851 0.095504060387611389 0.066920816898345947; - setAttr -s 9 ".koy[2:8]" 0 0.60617291927337646 0.99887973070144653 - 0.99662274122238159 -0.98044085502624512 -0.99542903900146484 -0.99775826930999756; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 79.9108418 3.04 79.9108418 7 - 126.25105989748279 11 187.48753506443182 13 156.29724550296677 16 197.39894235381789 - 18 189.31664610074043 22.248000000000001 142.00000838297527 25.248000000000001 - 79.910841797573624; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.43033117055892944 0.76935410499572754 - 0.33997067809104919 0.25998815894126892 0.15621557831764221 0.11459002643823624; - setAttr -s 9 ".kiy[2:8]" 0 0.90267109870910645 0.63882255554199219 - 0.94043600559234619 -0.96561181545257568 -0.98772299289703369 -0.99341285228729248; - setAttr -s 9 ".kox[2:8]" 1 0.43033117055892944 0.76935410499572754 - 0.33997067809104919 0.25998815894126892 0.15621557831764221 0.11459002643823624; - setAttr -s 9 ".koy[2:8]" 0 0.90267109870910645 0.63882255554199219 - 0.94043600559234619 -0.96561181545257568 -0.98772299289703369 -0.99341285228729248; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.4514964969999999 3.04 3.4514964969999999 - 7 -20.241286567637317 11 35.970185730983673 13 88.707259867513883 16 75.153263148153883 - 18 75.109640172485172 22.248000000000001 70.753838552636154 25.248000000000001 - 3.4514964971630411; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 0.13035261631011963 0.29141488671302795 - 0.65971523523330688 0.95914995670318604 0.2347242683172226 0.10581749677658081; - setAttr -s 9 ".kiy[2:8]" 0 0.99146771430969238 0.9565967321395874 - -0.75151568651199341 -0.28289806842803955 -0.97206199169158936 -0.99438554048538208; - setAttr -s 9 ".kox[2:8]" 1 0.13035261631011963 0.29141488671302795 - 0.65971523523330688 0.95914995670318604 0.2347242683172226 0.10581749677658081; - setAttr -s 9 ".koy[2:8]" 0 0.99146771430969238 0.9565967321395874 - -0.75151568651199341 -0.28289806842803955 -0.97206199169158936 -0.99438554048538208; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.04 1 7 1 11 1 13 1 16 1 18 - 1 22.248000000000001 1 25.248000000000001 1; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".kiy[2:8]" 0 0 0 0 0 0 0; - setAttr -s 9 ".kox[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".koy[2:8]" 0 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.04 1 7 0.99999999999999989 - 11 0.99999999999999989 13 0.99999999999999989 16 0.99999999999999989 18 0.99999999999999989 - 22.248000000000001 0.99999999999999989 25.248000000000001 0.99999999999999989; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".kiy[2:8]" 0 0 0 0 0 0 0; - setAttr -s 9 ".kox[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".koy[2:8]" 0 0 0 0 0 0 0; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.04 1 7 0.99999999999999978 - 11 0.99999999999999978 13 0.99999999999999978 16 0.99999999999999978 18 0.99999999999999978 - 22.248000000000001 0.99999999999999978 25.248000000000001 0.99999999999999978; - setAttr -s 9 ".kit[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 1 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".kiy[2:8]" 0 0 0 0 0 0 0; - setAttr -s 9 ".kox[2:8]" 1 1 1 1 1 1 1; - setAttr -s 9 ".koy[2:8]" 0 0 0 0 0 0 0; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -7.6830847237629127 4 -7.6830847237629127 - 8 -7.3924057183504974 11 -7.6830847237629092 18 -7.6830847237629092 22.248000000000001 - -7.3924057183504965; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.067222986630498513 4 0.067222986630498513 - 8 4.230030542675058 11 0.067222986630498513 18 0.067222986630498513 22.248000000000001 - 4.230030542675058; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 37.987561360779395 4 37.987561360779395 - 8 70.574104964785704 11 73.778849248683926 18 73.778849248683926 22.248000000000001 - 95.920792735427909; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 8 1 11 1 18 1 22.248000000000001 - 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.793904686753875 4 13.793904686753875 - 8 -7.4815773627500066 11 13.793904686753875 18 13.793904686753875 22.248000000000001 - -7.4815773627500066; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -50.847426602078492 4 -50.847426602078492 - 8 -50.847426602078386 11 -50.847426602078492 18 -50.847426602078492 22.248000000000001 - -50.847426602078386; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -16.248026693665114 4 -16.248026693665114 - 8 -16.248026693665089 11 -16.248026693665114 18 -16.248026693665114 22.248000000000001 - -16.248026693665089; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 8 1 11 1 18 1 22.248000000000001 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 8 1 11 1 18 1 22.248000000000001 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4 1 8 1 11 1 18 1 22.248000000000001 - 1; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 7.1689522478599548 17 7.1689522478599699; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 0 17 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 37.961325025704973 17 109.36656543099986; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 1 17 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 -174.49049195404214 17 -174.49049195404214; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 129.78625356110399 17 129.78625356110399; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 -169.93906815090079 17 -169.93906815090079; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 1 17 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 1 17 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 8 1 17 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933783 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 44.896641906037516 -6.9422266998600851e-015 - -12.83707679345506 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FLAT"; -select -ne IMP_RHAND_ROT; - setAttr -k on ".Flat"; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of on4_melee2.ma diff --git a/base/models/monsters/imp/animation/cycles/on4_sight.ma b/base/models/monsters/imp/animation/cycles/on4_sight.ma deleted file mode 100644 index 9fc725d38..000000000 --- a/base/models/monsters/imp/animation/cycles/on4_sight.ma +++ /dev/null @@ -1,3636 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: on4_sight.ma -//Last modified: Thu, Nov 13, 2003 05:02:28 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 174.86133861353869 44.35425159446244 -4.576195465824668 ; - setAttr ".r" -type "double3" -14.130108896989553 -2426.6000000004979 2.5444437451708134e-014 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 98.382958845157575; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 73.393312726190914 19.804469755084217 -18.716187810005199 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 76.66589438746432 21.396720735023585 109.80627035458363 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 79.219103619322951; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 18.681463597477045 -5.4655275657049325 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 89.323072030664264; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 25 -ast 1 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 23 0 35 0 56 0 79 0 91 0 112 - 0 131 0 143 0 164 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.3128351505039433 23 2.3128351505039433 - 35 2.3128351505039433 56 2.3128351505039433 79 2.3128351505039433 91 2.3128351505039433 - 112 2.3128351505039433 131 2.3128351505039433 143 2.3128351505039433 164 - 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.23421866920666501 23 0.23421866920666501 - 35 0.23421866920666501 56 0.23421866920666501 79 0.23421866920666501 91 0.23421866920666501 - 112 0.23421866920666501 131 0.23421866920666501 143 0.23421866920666501 164 - 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 7 23 -1.6400000000002868 35 -3.4400000000003419 - 56 7 79 -1.6400000000002868 91 -3.4400000000003419 112 7 131 -1.6400000000002868 - 143 -3.4400000000003419 164 7; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.903356467361473 23 -26.90335646736148 - 35 -26.903356467361476 56 -26.903356467361473 79 -26.90335646736148 91 -26.903356467361476 - 112 -26.903356467361473 131 -26.90335646736148 143 -26.903356467361476 164 - -26.903356467361473; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 15.011069830747704 23 15.011069830747717 - 35 15.011069830747713 56 15.011069830747704 79 15.011069830747717 91 15.011069830747713 - 112 15.011069830747704 131 15.011069830747717 143 15.011069830747713 164 - 15.011069830747704; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 23 1 35 1 56 1 79 1 91 1 112 - 1 131 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 18 1 25 1 28 1 58 1 80 - 1 115 1 143 1 164 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 9 9 9 - 9 9 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.7811807856021344 10 5.7811807856021344 - 18 5.7811807856021344 25 5.7811807856021344 28 5.7811807856021344 58 5.7811807856021344 - 80 5.7811807856021353 115 5.7811807856021344 143 5.7811807856021344 164 5.7811807856021344; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 25.889387873057544 10 26.36950248027216 - 18 28.26376559941939 25 25.337722884924979 28 26.523131958326466 58 25.889387873057544 - 80 26.269634324218906 115 25.239360085597689 143 26.267290117781048 164 25.889387873057544; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 53.227781741534002 10 51.031854031468363 - 18 48.022609521050235 25 53.08853424352462 28 52.340540022157505 58 53.227781741534002 - 80 53.861525826802932 115 52.989394209459462 143 54.147946281375177 164 53.227781741534002; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 77.619347049814735 10 83.686299289909144 - 18 88.270816095701633 25 77.619347049814735 28 77.619347049814735 58 77.619347049814735 - 80 77.619347049814735 115 77.619347049814735 143 77.619347049814735 164 77.619347049814735; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 -0.78924035798623293 18 - -1.3800637347773068 25 0 28 0 58 0 80 0 115 0 143 0 164 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 7.4260738755503866 10 7.384248472544038 - 18 7.297417848456627 25 7.4260738755503866 28 7.4260738755503866 58 7.4260738755503866 - 80 7.4260738755503866 115 7.4260738755503866 143 7.4260738755503866 164 7.4260738755503866; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 18 1 25 1 28 1 58 1 80 - 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 18 1 25 1 28 1 58 1 80 - 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 18 1 25 1 28 1 58 1 80 - 1 115 1 143 1 164 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 25 1 44 1 74 1 96.332 - 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 8 0 19 0 25 0 44 0 74 0 96.332 - 0 109 0 123 0 135 0 147 0 164 0; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 5.6268319407172029 8 5.6268319407172029 - 19 5.6268319407172029 25 5.6268319407172029 44 5.6268319407172029 74 5.6268319407172029 - 96.332 5.6268319407172029 109 5.6268319407172029 123 5.6268319407172029 135 - 5.6268319407172029 147 5.6268319407172029 164 5.6268319407172029; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -2.1098668596606802 8 -2.1098668596606802 - 19 -2.1098668596606802 25 -2.1098668596606802 44 -2.1098668596606802 74 -2.1098668596606802 - 96.332 -2.1098668596606802 109 -2.1098668596606802 123 -2.1098668596606802 - 135 -2.1098668596606802 147 -2.1098668596606802 164 -2.1098668596606802; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 345.27271965780443 8 362.84110163073296 - 19 326.38578674792439 25 350.30353008021302 44 348.321155490499 74 343.95139401286002 - 96.332 343.95139401286002 109 350.59074107043182 123 350.59074107043182 135 - 347.97524631186201 147 347.97524631186201 164 345.27271965780443; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1.3179419976279476 8 14.300573821540183 - 19 13.464052920493558 25 9.0151637326740381 44 -6.7990161161606126 74 10.547631010639803 - 96.332 10.547631010639803 109 4.3538922741238197 123 4.3538922741238197 135 - 11.006160829153359 147 11.006160829153359 164 1.3179419976279476; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -15.879152782861023 8 -17.927870184702993 - 19 -9.099122169600216 25 -14.536444735081535 44 -7.1745394132635436 74 -41.391733920712802 - 96.332 -41.391733920712802 109 -23.863415136797379 123 -23.863415136797379 - 135 -21.618577640925643 147 -21.618577640925643 164 -15.879152782861023; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 25 1 44 1 74 1 96.332 - 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 25 1 44 1 74 1 96.332 - 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8 1 19 1 25 1 44 1 74 1 96.332 - 1 109 1 123 1 135 1 147 1 164 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 9 3 3 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6 1 14 1 23 1 25 1 43 1 51 - 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 18 ".kot[0:17]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -89.357473964112842 6 -122.87977582374819 - 14 -94.208853744351899 23 -104.24643880396567 25 -89.357473964112842 43 -95.050384163510145 - 51 -82.990588992012249 57 -120.65264219499377 80 -82.957980049975419 98 -73.820064112840726 - 105 -78.644026037743103 113 -78.644026037743103 118 -64.274484016113846 127 - -64.274484016113846 134 -64.274484016113846 140 -84.180544414861316 156 -84.180544414861316 - 164 -89.357473964112842; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 27.285995176624525 6 28.29504540194392 - 14 19.625494165357832 23 27.30369299997675 25 27.285995176624525 43 23.829597105165679 - 51 30.02199866780364 57 45.542042537996807 80 48.967747359056773 98 33.908278455971143 - 105 -9.7374870200871069 113 -9.7374870200871069 118 26.681693201652777 127 - 26.681693201652777 134 26.681693201652777 140 44.461343173014235 156 44.461343173014235 - 164 27.285995176624525; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -11.640194316301965 6 -13.35074612575438 - 14 -16.828279599761938 23 -17.896269604230742 25 -11.640194316301965 43 7.424878868956613 - 51 -8.9131779640642392 57 -47.327765180398039 80 -28.204628199279032 98 -9.71638229745645 - 105 -3.118173088460757 113 -3.118173088460757 118 20.535020731775216 127 - 20.535020731775216 134 20.535020731775216 140 -33.512066589889507 156 -33.512066589889507 - 164 -11.640194316301965; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6 1 14 1 23 1 25 1 43 1 51 - 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6 1 14 1 23 1 25 1 43 1 51 - 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6 1 14 1 23 1 25 1 43 1 51 - 1 57 1 80 1 98 1 105 1 113 1 118 1 127 1 134 1 140 1 156 1 164 1; - setAttr -s 18 ".kit[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; - setAttr -s 18 ".kot[0:17]" 3 3 3 3 3 9 9 - 9 9 9 9 9 9 9 9 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.1434256346412039 6 1.1434256346412039 - 14 1.1434256346412039 23 1.1434256346412039 25 1.1434256346412039 105 1.1434256346412039 - 113 1.1434256346412039; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4747586019443117 6 2.4747586019443117 - 14 2.4747586019443117 23 2.4747586019443117 25 2.4747586019443117 105 2.4747586019443117 - 113 2.4747586019443117; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 3.4085747911787618 6 3.4085747911787618 - 14 3.4085747911787618 23 3.4085747911787618 25 3.4085747911787618 105 3.4085747911787618 - 113 3.4085747911787618; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.739160914831501; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -76.726154744596627; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -173.86213662459591; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 141.20709981379272; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 64.064019952206479; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 252.95011708695623; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.098430367493391069; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2938531700865199; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.5219249117522764; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -95.110993991716654; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0581001958067302; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.97887915067413922; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.386441338106027; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 135.72390740166219; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 68.064626042993012; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 176.22610035782074; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -66.065354836318264; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.775852580156471; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -91.471856426984459; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 217.7239621497128; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -61.864687108561675; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829776; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121454; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -102.79322267388413; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 53.022108389175763; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.34185235662672303; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 104.02743330242008; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 67.988981015108081; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 37.800067484309146; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.8361212914297057; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5855994671500682; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.25463676619339848; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 21.877026181853708; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.8835109760916842; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.6668705341433823; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 82.174334819999999; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.4169468409999997; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.590676942; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -156.6082625; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.351754810000003; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 168.3677892; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 29.159999999997844 16 22.590616467275972 - 20 36.853872605888235 25 1.2138726058909635; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 25 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 25 0; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 25 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 7 0 16 0 20 0 25 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.74525677667777757 7 0.74525677667777757 - 16 0.74525677667777757 20 0.74525677667777757 25 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.8072476834435935 7 1.8072476834435935 - 16 1.8072476834435935 20 1.8072476834435935 25 1.8072476834435935; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 25 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 25 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 7 1 16 1 20 1 25 1; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 66.534727176917499 25 66.534727176917499; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 25 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.2264759820026532 25 -7.2264759820026532; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 25 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 25 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 25 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 25 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 25 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 25 1; -select -ne :time1; - setAttr ".o" 9; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".t" -type "double3" -7.392405718350501 4.230030542675058 36.754381567957459 ; - setAttr ".r" -type "double3" -7.4815773627500066 -50.847426602078386 -16.248026693665089 ; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933783 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".t" -type "double3" 7.1689522478599548 0 37.961325025704973 ; - setAttr ".r" -type "double3" -174.49049195404214 129.78625356110399 -169.93906815090079 ; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body2; - setAttr ".t" -type "double3" -1.056829330869963 -1.2375278839290837 6.4760897421942092 ; -select -ne IMP_Shoulders; - setAttr ".t" -type "double3" 0 5.5258192723085173 1.1525507362789047 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 77.838685046101745 -1.2035951346650277e-014 - -22.256033748127585 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Lhand_GOAL; - setAttr ".v" yes; - setAttr ".t" -type "double3" 89.060937550000006 6.4996370350000001 -18.214943030000001 ; - setAttr ".r" -type "double3" 47.63135552 79.9108418 3.4514964969999999 ; - setAttr ".s" -type "double3" 1 1 1 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of on4_sight.ma diff --git a/base/models/monsters/imp/animation/cycles/outofhole.ma b/base/models/monsters/imp/animation/cycles/outofhole.ma deleted file mode 100644 index 16daa3d8d..000000000 --- a/base/models/monsters/imp/animation/cycles/outofhole.ma +++ /dev/null @@ -1,5245 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:26 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: outofhole.ma -//Last modified: Mon, Mar 17, 2003 01:54:21 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" -40.22152852647293 56.803115187619447 290.59465687225946 ; - setAttr ".r" -type "double3" -6.930108917406665 -1082.1999999993272 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 267.02341770080176; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -37.712599235383777 18.434444180036223 6.8306302889271855 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" -27.764643353708173 102.42230559510008 24.779370914096514 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 319.4449271267178; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" -24.034116864733175 25.090247390676655 115.38120683615807 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 234.05119771530428; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 117.1942551390236 -28.246595584868139 3.2987860274769076 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 416.98517263294673; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "group2"; - setAttr ".rp" -type "double3" -32 -8 64 ; - setAttr ".sp" -type "double3" -32 -8 64 ; -createNode transform -n "polySurface1" -p "group2"; -createNode mesh -n "polySurfaceShape1" -p "polySurface1"; - setAttr -k off ".v"; - setAttr -s 2 ".iog[0].og"; - setAttr ".iog[0].og[0].gcl" -type "componentList" 0; - setAttr ".iog[0].og[1].gcl" -type "componentList" 1 "f[0:47]"; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 96 ".uvst[0].uvsp[0:95]" -type "float2" -13 7 -9 - 7 -9 8 -13 8 -9 -6 -9 -5 -13 -5 -13 -6 9 1 9 0.75 13 0.75 13 1 -7 1 -7 0.75 - -6 0.75 -6 1 -13 1 -13 0.75 -9 0.75 -9 1 6 1 6 0.75 7 0.75 7 1 -13 8 -7 8 - -7 10 -13 10 -7 -8 -7 -6 -13 -6 -13 -8 7 1 7 0.75 13 0.75 13 1 -9 1 -9 0.75 - -7 0.75 -7 1 -13 1 -13 0.75 -7 0.75 -7 1 7 1 7 0.75 9 0.75 9 1 -8 7 -7 7 - -7 8 -8 8 -7 -6 -7 -5 -8 -5 -8 -6 7 1 7 0.75 8 0.75 8 1 -7 1 -7 0.75 -6 0.75 - -6 1 -8 1 -8 0.75 -7 0.75 -7 1 6 1 6 0.75 7 0.75 7 1 -13 5 -7 5 -7 7 -13 - 7 -7 -5 -7 -3 -13 -3 -13 -5 7 1 7 0.75 13 0.75 13 1 -6 1 -6 0.75 -4 0.75 - -4 1 -13 1 -13 0.75 -7 0.75 -7 1 4 1 4 0.75 6 0.75 6 1; - setAttr ".cuvs" -type "string" "map1"; - setAttr -s 96 ".vt[0:95]" -64 -16 256 -64 -16 0 0 -16 0 0 - -16 256 0 0 0 -64 0 0 -64 0 256 0 0 256 -64 0 0 -64 -16 0 -64 -16 256 -64 - 0 256 0 0 0 0 -16 0 -64 -16 0 -64 0 0 0 0 256 0 -16 256 0 -16 0 0 0 0 -64 - 0 256 -64 -16 256 0 -16 256 0 0 256 0 -16 256 0 -16 -128 128 -16 -128 128 - -16 256 128 0 -128 0 0 -128 0 0 256 128 0 256 0 0 -128 0 -16 -128 0 -16 256 - 0 0 256 128 0 -128 128 -16 -128 0 -16 -128 0 0 -128 128 0 256 128 -16 256 - 128 -16 -128 128 0 -128 0 0 256 0 -16 256 128 -16 256 128 0 256 -64 -16 -64 - -64 -16 -128 0 -16 -128 0 -16 -64 0 0 -128 -64 0 -128 -64 0 -64 0 0 -64 -64 - 0 -128 -64 -16 -128 -64 -16 -64 -64 0 -64 0 0 -128 0 -16 -128 -64 -16 -128 - -64 0 -128 0 0 -64 0 -16 -64 0 -16 -128 0 0 -128 -64 0 -64 -64 -16 -64 0 - -16 -64 0 0 -64 -192 -16 256 -192 -16 -128 -64 -16 -128 -64 -16 256 -64 0 - -128 -192 0 -128 -192 0 256 -64 0 256 -192 0 -128 -192 -16 -128 -192 -16 - 256 -192 0 256 -64 0 -128 -64 -16 -128 -192 -16 -128 -192 0 -128 -64 0 256 - -64 -16 256 -64 -16 -128 -64 0 -128 -192 0 256 -192 -16 256 -64 -16 256 -64 - 0 256; - setAttr -s 120 ".ed[0:119]" 0 1 0 1 2 - 0 2 0 0 3 0 0 2 3 0 4 - 5 0 5 6 0 6 4 0 7 4 0 - 6 7 0 8 9 0 9 10 0 10 8 - 0 11 8 0 10 11 0 12 13 0 13 - 14 0 14 12 0 15 12 0 14 15 0 - 16 17 0 17 18 0 18 16 0 19 16 - 0 18 19 0 20 21 0 21 22 0 22 - 20 0 23 20 0 22 23 0 24 25 0 - 25 26 0 26 24 0 27 24 0 26 27 - 0 28 29 0 29 30 0 30 28 0 31 - 28 0 30 31 0 32 33 0 33 34 0 - 34 32 0 35 32 0 34 35 0 36 37 - 0 37 38 0 38 36 0 39 36 0 38 - 39 0 40 41 0 41 42 0 42 40 0 - 43 40 0 42 43 0 44 45 0 45 46 - 0 46 44 0 47 44 0 46 47 0 48 - 49 0 49 50 0 50 48 0 51 48 0 - 50 51 0 52 53 0 53 54 0 54 52 - 0 55 52 0 54 55 0 56 57 0 57 - 58 0 58 56 0 59 56 0 58 59 0 - 60 61 0 61 62 0 62 60 0 63 60 - 0 62 63 0 64 65 0 65 66 0 66 - 64 0 67 64 0 66 67 0 68 69 0 - 69 70 0 70 68 0 71 68 0 70 71 - 0 72 73 0 73 74 0 74 72 0 75 - 72 0 74 75 0 76 77 0 77 78 0 - 78 76 0 79 76 0 78 79 0 80 81 - 0 81 82 0 82 80 0 83 80 0 82 - 83 0 84 85 0 85 86 0 86 84 0 - 87 84 0 86 87 0 88 89 0 89 90 - 0 90 88 0 91 88 0 90 91 0 92 - 93 0 93 94 0 94 92 0 95 92 0 - 94 95 0; - setAttr -s 144 ".n[0:143]" -type "float3" 0 0 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 - -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 - 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 - 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 0 -1 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 - 1 0 0 1 0 0 1 0 0 1 0 0 1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 0 - 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 -1 0 - 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0; - setAttr -s 48 ".fc[0:47]" -type "polyFaces" - f 3 0 1 2 - mu 0 3 0 1 2 - f 3 3 -3 4 - mu 0 3 3 0 2 - f 3 5 6 7 - mu 0 3 4 5 6 - f 3 8 -8 9 - mu 0 3 7 4 6 - f 3 10 11 12 - mu 0 3 8 9 10 - f 3 13 -13 14 - mu 0 3 11 8 10 - f 3 15 16 17 - mu 0 3 12 13 14 - f 3 18 -18 19 - mu 0 3 15 12 14 - f 3 20 21 22 - mu 0 3 16 17 18 - f 3 23 -23 24 - mu 0 3 19 16 18 - f 3 25 26 27 - mu 0 3 20 21 22 - f 3 28 -28 29 - mu 0 3 23 20 22 - f 3 30 31 32 - mu 0 3 24 25 26 - f 3 33 -33 34 - mu 0 3 27 24 26 - f 3 35 36 37 - mu 0 3 28 29 30 - f 3 38 -38 39 - mu 0 3 31 28 30 - f 3 40 41 42 - mu 0 3 32 33 34 - f 3 43 -43 44 - mu 0 3 35 32 34 - f 3 45 46 47 - mu 0 3 36 37 38 - f 3 48 -48 49 - mu 0 3 39 36 38 - f 3 50 51 52 - mu 0 3 40 41 42 - f 3 53 -53 54 - mu 0 3 43 40 42 - f 3 55 56 57 - mu 0 3 44 45 46 - f 3 58 -58 59 - mu 0 3 47 44 46 - f 3 60 61 62 - mu 0 3 48 49 50 - f 3 63 -63 64 - mu 0 3 51 48 50 - f 3 65 66 67 - mu 0 3 52 53 54 - f 3 68 -68 69 - mu 0 3 55 52 54 - f 3 70 71 72 - mu 0 3 56 57 58 - f 3 73 -73 74 - mu 0 3 59 56 58 - f 3 75 76 77 - mu 0 3 60 61 62 - f 3 78 -78 79 - mu 0 3 63 60 62 - f 3 80 81 82 - mu 0 3 64 65 66 - f 3 83 -83 84 - mu 0 3 67 64 66 - f 3 85 86 87 - mu 0 3 68 69 70 - f 3 88 -88 89 - mu 0 3 71 68 70 - f 3 90 91 92 - mu 0 3 72 73 74 - f 3 93 -93 94 - mu 0 3 75 72 74 - f 3 95 96 97 - mu 0 3 76 77 78 - f 3 98 -98 99 - mu 0 3 79 76 78 - f 3 100 101 102 - mu 0 3 80 81 82 - f 3 103 -103 104 - mu 0 3 83 80 82 - f 3 105 106 107 - mu 0 3 84 85 86 - f 3 108 -108 109 - mu 0 3 87 84 86 - f 3 110 111 112 - mu 0 3 88 89 90 - f 3 113 -113 114 - mu 0 3 91 88 90 - f 3 115 116 117 - mu 0 3 92 93 94 - f 3 118 -118 119 - mu 0 3 95 92 94 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 35 1 46 1 52 1 58 1 67 1 72 - 1 125 1 155 1 200 1 245 1 290 1 320 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 9 9 9 - 9 9 9 9 9 1; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 35 0 46 0 52 0 58 0 67 0 72 - 0 125 0 155 0 200 0 245 0 290 0 320 0; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 5.6268319407172029 35 5.6268319407172029 - 46 5.6268319407172029 52 5.6268319407172029 58 5.6268319407172029 67 5.6268319407172029 - 72 5.6268319407172029 125 5.6268319407172029 155 5.6268319407172029 200 5.6268319407172029 - 245 5.6268319407172029 290 5.6268319407172029 320 5.6268319407172029; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -2.1098668596606802 35 -2.1098668596606802 - 46 -2.1098668596606802 52 -2.1098668596606802 58 -2.1098668596606802 67 -2.1098668596606802 - 72 -2.1098668596606802 125 -2.1098668596606802 155 -2.1098668596606802 200 - -2.1098668596606802 245 -2.1098668596606802 290 -2.1098668596606802 320 -2.1098668596606802; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 380.4969630522524 35 370.97986512582639 - 46 370.23577437821262 52 391.94901782435005 58 376.92501851620631 67 371.05657280048524 - 72 371.05657280048524 125 370.97986512582639 155 380.4969630522524 200 370.97986512582639 - 245 380.4969630522524 290 370.97986512582639 320 380.4969630522524; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 9 3 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 9 3 1 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -0.44667534838539324 35 -0.4466753483853948 - 46 -0.4466753483853948 52 -12.94779197190141 58 -4.3826494962827018 67 7.7406771966086136 - 72 7.7406771966086136 125 -0.4466753483853948 155 -0.44667534838539324 200 - -0.4466753483853948 245 -0.44667534838539324 290 -0.4466753483853948 320 - -0.44667534838539324; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -14.64190619217311 35 -14.641906192173119 - 46 -14.641906192173119 52 -19.833888812944295 58 -21.615674713378485 67 -14.970643750053718 - 72 -14.970643750053718 125 -14.641906192173119 155 -14.64190619217311 200 - -14.641906192173119 245 -14.64190619217311 290 -14.641906192173119 320 -14.64190619217311; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 35 1 46 1 52 1 58 1 67 1 72 - 1 125 1 155 1 200 1 245 1 290 1 320 1; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 35 1 46 1 52 1 58 1 67 1 72 - 1 125 1 155 1 200 1 245 1 290 1 320 1; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 35 1 46 1 52 1 58 1 67 1 72 - 1 125 1 155 1 200 1 245 1 290 1 320 1; - setAttr -s 13 ".kit[12]" 1; - setAttr -s 13 ".kot[9:12]" 1 9 9 9; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[9:12]" 1 1 1 1; - setAttr -s 13 ".koy[9:12]" 0 0 0 0; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 36 1 125 1 156 1 201 1 245 - 1 290 1 321 1; - setAttr -s 8 ".kit[0:7]" 9 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.8522027930141798 36 5.6263356976128209 - 125 5.7077300798754731 156 4.2728422839461313 201 5.7092843065061274 245 - 4.8522027930141798 290 5.3747990747980294 321 4.8522027930141798; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.1192573708759381 36 2.1968799275302229 - 125 2.2161219770055927 156 2.1300473608914325 201 2.1870065245139054 245 - 2.1192573708759381 290 2.2088441001574304 321 2.1192573708759381; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0821078932592165 36 -3.0171620595005368 - 125 -3.0367046551861128 156 -2.993739050872108 201 -3.0247639118124328 245 - -3.0821078932592165 290 -3.0182846824251 321 -3.0821078932592165; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -17.481282422130235 36 -17.481282422130235 - 125 -17.481282422130235 156 -17.481282422130235 201 -17.481282422130235 245 - -17.481282422130235 290 -17.481282422130235 321 -17.481282422130235; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 30.702824881409519 36 30.702824881409519 - 125 30.702824881409519 156 30.702824881409519 201 30.702824881409519 245 - 30.702824881409519 290 30.702824881409519 321 30.702824881409519; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.797032566082748 36 -30.797032566082748 - 125 -30.797032566082748 156 -30.797032566082748 201 -30.797032566082748 245 - -30.797032566082748 290 -30.797032566082748 321 -30.797032566082748; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 36 1 125 1 156 1 201 1 245 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 36 1 125 1 156 1 201 1 245 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 36 1 125 1 156 1 201 1 245 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 34 1 125 1 156 1 199 1 240 - 1 290 1 321 1; - setAttr -s 8 ".kit[0:7]" 9 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -5.0348979650608028 34 -6.1662787952208804 - 125 -6.332052802545526 156 -5.0348979650608028 199 -5.9989817443231157 240 - -5.0348979650608028 290 -6.1651054738667508 321 -5.0348979650608028; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.1192000000002627 34 2.0633398577805862 - 125 2.0151003404222902 156 2.1192000000002627 199 2.0685615589513167 240 - 2.1192000000002627 290 2.0279963425986116 321 2.1192000000002627; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0821100000000254 34 -3.1088246861360456 - 125 -3.096744066089737 156 -3.0821100000000254 199 -3.1023554395515527 240 - -3.0821100000000254 290 -3.0935877675684584 321 -3.0821100000000254; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 9 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 34 1 125 1 156 1 199 1 240 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 34 1 125 1 156 1 199 1 240 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 34 1 125 1 156 1 199 1 240 - 1 290 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 20 1 25 1 30 1 36 1 41 1 48 - 1 54 1 59 1 68 1 72 1 105 1 136 1 156 1 185 1 225 1 270 1 321 1; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 9 9 3 9 9 9 1; - setAttr -s 18 ".kot[0:17]" 3 5 5 5 5 5 5 - 5 5 5 5 5 5 3 5 5 5 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 0 20 0 25 0 30 0 36 0 41 0 48 - 0 54 0 59 0 68 0 72 0 105 0 136 0 156 0 185 0 225 0 270 0 321 0; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 2.6456615572060826 20 2.6456615572060826 - 25 2.6456615572060826 30 2.6456615572060826 36 2.6456615572060826 41 2.6456615572060826 - 48 2.6456615572060826 54 2.6456615572060826 59 2.6456615572060826 68 2.6456615572060826 - 72 2.6456615572060826 105 2.6456615572060826 136 2.6456615572060826 156 2.6456615572060826 - 185 2.6456615572060826 225 2.6456615572060826 270 2.6456615572060826 321 - 2.6456615572060826; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1.9935618776130362 20 1.9935618776130362 - 25 1.9935618776130362 30 1.9935618776130362 36 1.9935618776130362 41 1.9935618776130362 - 48 1.9935618776130362 54 1.9935618776130362 59 1.9935618776130362 68 1.9935618776130362 - 72 1.9935618776130362 105 1.9935618776130362 136 1.9935618776130362 156 1.9935618776130362 - 185 1.9935618776130362 225 1.9935618776130362 270 1.9935618776130362 321 - 1.9935618776130362; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -9.2446596468972171 20 3.4832624144605182 - 25 17.935864224752269 30 -41.517932052650266 36 -56.304011779539323 41 -67.440855384402724 - 48 -106.28548098668018 54 -40.529597193899811 59 -40.829859091361449 68 -17.785099615049436 - 72 -9.2626735647337934 105 3.8822115545531957 136 -6.2957739870043987 156 - -9.2446596468972171 185 3.4832624144605182 225 -13.064746825930683 270 -8.3197602871798271 - 321 -9.2446596468972171; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 0.99978089332580566 1 1 1; - setAttr -s 18 ".koy[14:17]" 0.020931452512741089 0 0 0; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 5.4602836565267197 20 5.4602836565267285 - 25 26.120030363444279 30 9.4653685182960494 36 21.769002971056299 41 -7.1015468209301558 - 48 10.17425012890541 54 21.180517441425668 59 3.0256475464771411 68 -11.065461090339863 - 72 -9.9229329922836538 105 26.709277681532512 136 5.4602836565267321 156 - 5.4602836565267197 185 5.4602836565267285 225 -23.049736335314446 270 -21.160045816227957 - 321 5.4602836565267197; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -15.091352590275809 20 -15.0913525902758 - 25 -22.072160219041216 30 -32.291897362502148 36 -11.684221328775717 41 -25.615238243086118 - 48 -44.165507687022874 54 -26.408054801006667 59 -14.710362920033205 68 -16.688843288509048 - 72 -19.462613006807242 105 -13.676163644138256 136 -15.091352590275802 156 - -15.091352590275809 185 -15.0913525902758 225 -25.207145492133286 270 -23.318199416559274 - 321 -15.091352590275809; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 20 1 25 1 30 1 36 1 41 1 48 - 1 54 1 59 1 68 1 72 1 105 1 136 1 156 1 185 1 225 1 270 1 321 1; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 20 1 25 1 30 1 36 1 41 1 48 - 1 54 1 59 1 68 1 72 1 105 1 136 1 156 1 185 1 225 1 270 1 321 1; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 20 1 25 1 30 1 36 1 41 1 48 - 1 54 1 59 1 68 1 72 1 105 1 136 1 156 1 185 1 225 1 270 1 321 1; - setAttr -s 18 ".kit[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 9 3 3 1; - setAttr -s 18 ".kot[0:17]" 3 9 9 9 9 9 9 - 9 9 9 9 3 9 3 1 3 3 3; - setAttr -s 18 ".kix[17]" 1; - setAttr -s 18 ".kiy[17]" 0; - setAttr -s 18 ".kox[14:17]" 1 1 1 1; - setAttr -s 18 ".koy[14:17]" 0 0 0 0; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 24 1 28 1 35 1 44 1 53 1 113 - 1 156 1 189 1 218 1 245 1 278 1 321 1; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 5 5 5 5 5 5 - 3 5 5 5 5 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 24 0 28 0 35 0 44 0 53 0 113 - 0 156 0 189 0 218 0 245 0 278 0 321 0; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.74525677667777757 24 0.74525677667777757 - 28 0.74525677667777757 35 0.74525677667777757 44 0.74525677667777757 53 0.74525677667777757 - 113 0.74525677667777757 156 0.74525677667777757 189 0.74525677667777757 218 - 0.74525677667777757 245 0.74525677667777757 278 0.74525677667777757 321 0.74525677667777757; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1.8072476834435935 24 1.8072476834435935 - 28 1.8072476834435935 35 1.8072476834435935 44 1.8072476834435935 53 1.8072476834435935 - 113 1.8072476834435935 156 1.8072476834435935 189 1.8072476834435935 218 - 1.8072476834435935 245 1.8072476834435935 278 1.8072476834435935 321 1.8072476834435935; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -5.2846953468686371 24 1.9368023994867858 - 28 24.84629198209587 35 39.708647808790204 44 -1.3097052378237242 53 -4.773336916696497 - 113 2.9452411150471089 156 -5.2846953468686371 189 1.9368023994867858 218 - -4.773336916696497 245 -4.773336916696497 278 2.9452411150471089 321 -5.2846953468686371; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 0.99999153614044189 0.99874275922775269 - 0.99855130910873413 0.99999600648880005 1; - setAttr -s 13 ".koy[8:12]" 0.0041191442869603634 -0.050128623843193054 - 0.053807776421308517 -0.0028183746617287397 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 24 0 28 0 35 0 44 0 53 0 113 - 0 156 0 189 0 218 0 245 0 278 0 321 0; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 24 0 28 0 35 0 44 0 53 0 113 - 0 156 0 189 0 218 0 245 0 278 0 321 0; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 24 1 28 1 35 1 44 1 53 1 113 - 1 156 1 189 1 218 1 245 1 278 1 321 1; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 24 1 28 1 35 1 44 1 53 1 113 - 1 156 1 189 1 218 1 245 1 278 1 321 1; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 24 1 28 1 35 1 44 1 53 1 113 - 1 156 1 189 1 218 1 245 1 278 1 321 1; - setAttr -s 13 ".kit[0:12]" 3 9 9 9 9 9 9 - 3 9 9 9 9 1; - setAttr -s 13 ".kot[0:12]" 3 9 9 9 9 9 9 - 3 1 9 9 9 3; - setAttr -s 13 ".kix[12]" 1; - setAttr -s 13 ".kiy[12]" 0; - setAttr -s 13 ".kox[8:12]" 1 1 1 1 1; - setAttr -s 13 ".koy[8:12]" 0 0 0 0 0; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 44 1 94 1 131 1 156 1 209 1 - 259 1 296 1 321 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -12.41287000000041 44 -12.41287000000041 - 94 -12.41287000000041 131 -12.41287000000041 156 -12.41287000000041 209 -12.41287000000041 - 259 -12.41287000000041 296 -12.41287000000041 321 -12.41287000000041; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.7285999999993047 44 -6.7285999999993047 - 94 -6.7285999999993047 131 -6.7285999999993047 156 -6.7285999999993047 209 - -6.7285999999993047 259 -6.7285999999993047 296 -6.7285999999993047 321 -6.7285999999993047; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.8687599999999316 44 -3.8687599999999316 - 94 -3.8687599999999316 131 -3.8687599999999316 156 -3.8687599999999316 209 - -3.8687599999999316 259 -3.8687599999999316 296 -3.8687599999999316 321 -3.8687599999999316; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 8.5757406876636644 44 17.575740687663522 - 94 6.4870119110025382 131 13.327011911002414 156 8.5757406876636644 209 17.575740687663522 - 259 6.4870119110025382 296 13.327011911002414 321 8.5757406876636644; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 3 9 9 - 9 1; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 3 1 9 - 9 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 0.99995577335357666 0.99979084730148315 - 0.9999004602432251 1; - setAttr -s 9 ".koy[5:8]" -0.0094073759391903877 -0.02045208215713501 - 0.014110283926129341 0; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 44 0 94 0 131 0 156 0 209 0 - 259 0 296 0 321 0; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 44 0 94 0 131 0 156 0 209 0 - 259 0 296 0 321 0; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 44 1 94 1 131 1 156 1 209 1 - 259 1 296 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 44 1 94 1 131 1 156 1 209 1 - 259 1 296 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 44 1 94 1 131 1 156 1 209 1 - 259 1 296 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 49.111805173615501 34 51.190846457835931 - 125 51.862187489241293 156 49.111805173615501 199 51.190846457835931 240 - 48.532274277619457 290 51.862187489241293 321 49.111805173615501; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 0.99931013584136963; - setAttr -s 8 ".kiy[7]" -0.03713814914226532; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -36.514345314725674 34 -32.919913206550518 - 125 -31.581067417553413 156 -36.514345314725674 199 -32.919913206550518 240 - -37.39496101549193 290 -31.581067417553413 321 -36.514345314725674; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 0.99778562784194946; - setAttr -s 8 ".kiy[7]" -0.066511951386928558; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -10.891726707689953 34 -14.539579744065646 - 125 -15.797541811386251 156 -10.891726707689953 199 -14.539579744065646 240 - -9.9277851245267712 290 -15.797541811386251 321 -10.891726707689953; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kix[7]" 0.99781012535095215; - setAttr -s 8 ".kiy[7]" 0.066143319010734558; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 50 1 92 1 125 1 156 1 215 1 - 257 1 290 1 321 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 12.412879749935719 50 12.412879749935719 - 92 12.412879749935719 125 12.412879749935719 156 12.412879749935719 215 12.412879749935719 - 257 12.412879749935719 290 12.412879749935719 321 12.412879749935719; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.7286993982861674 50 -6.7286993982861674 - 92 -6.7286993982861674 125 -6.7286993982861674 156 -6.7286993982861674 215 - -6.7286993982861674 257 -6.7286993982861674 290 -6.7286993982861674 321 -6.7286993982861674; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.868763862603668 50 -3.868763862603668 - 92 -3.868763862603668 125 -3.868763862603668 156 -3.868763862603668 215 -3.868763862603668 - 257 -3.868763862603668 290 -3.868763862603668 321 -3.868763862603668; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 19.580561221118923 50 26.060561221119134 - 92 11.300561221118764 125 21.38056122111913 156 19.580561221118923 215 26.060561221119134 - 257 11.300561221118764 290 21.38056122111913 321 19.580561221118923; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 3 9 9 - 9 1; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 3 1 9 - 9 3; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 0.99927449226379395 0.99965858459472656 - 0.99853479862213135 1; - setAttr -s 9 ".koy[5:8]" -0.038085736334323883 -0.02612912654876709 - 0.054113071411848068 0; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 50 0 92 0 125 0 156 0 215 0 - 257 0 290 0 321 0; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 50 0 92 0 125 0 156 0 215 0 - 257 0 290 0 321 0; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 50 1 92 1 125 1 156 1 215 1 - 257 1 290 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 50 1 92 1 125 1 156 1 215 1 - 257 1 290 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 50 1 92 1 125 1 156 1 215 1 - 257 1 290 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 72 -ast 1 -aet 72 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 37 1 120 1 156 1 202 1 245 - 1 285 1 321 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 5 5 3 5 5 5 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.4264261331675518 37 5.8137795257559475 - 120 5.8137795257559475 156 4.4264261331675518 202 5.8137795257559475 245 - 4.4264261331675518 285 5.8137795257559475 321 4.4264261331675518; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.3937238431314825 37 4.6602991197236454 - 120 4.6602991197236454 156 4.3937238431314825 202 4.6602991197236454 245 - 4.3937238431314825 285 4.6602991197236454 321 4.3937238431314825; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.7712681071056613 37 7.7844874121673691 - 120 7.7844874121673691 156 7.7712681071056613 202 7.7844874121673691 245 - 7.7712681071056613 285 7.7844874121673691 321 7.7712681071056613; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 37 -2.6718525581737946 120 - -2.6718525581737946 156 0 202 -2.6718525581737946 245 0 285 -2.6718525581737946 - 321 0; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 37 10.944524996277053 120 10.944524996277053 - 156 0 202 10.944524996277053 245 0 285 10.944524996277053 321 0; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 37 0.90809814617374629 120 - 0.90809814617374629 156 0 202 0.90809814617374629 245 0 285 0.90809814617374629 - 321 0; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 37 1 120 1 156 1 202 1 245 - 1 285 1 321 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 37 1 120 1 156 1 202 1 245 - 1 285 1 321 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 37 1 120 1 156 1 202 1 245 - 1 285 1 321 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 41 1 120 1 156 1 206 1 240 - 1 285 1 321 1; - setAttr -s 8 ".kit[0:7]" 9 9 9 9 9 9 9 - 1; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -4.0846345617354372 41 -4.769570789566667 - 120 -4.769570789566667 156 -4.0846345617354372 206 -4.769570789566667 240 - -4.0846345617354372 285 -4.769570789566667 321 -4.0846345617354372; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.282468147773308 41 4.4352392314085174 - 120 4.4352392314085174 156 4.282468147773308 206 4.4352392314085174 240 4.282468147773308 - 285 4.4352392314085174 321 4.282468147773308; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.7712681071056613 41 7.6330797418271441 - 120 7.6330797418271441 156 7.7712681071056613 206 7.6330797418271441 240 - 7.7712681071056613 285 7.6330797418271441 321 7.7712681071056613; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 41 0 120 0 156 0 206 0 240 - 0 285 0 321 0; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kot[4:7]" 1 9 9 9; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 41 -6.8555441350667934 120 - -6.8555441350667934 156 0 206 -6.8555441350667934 240 0 285 -6.8555441350667934 - 321 0; - setAttr -s 8 ".kit[0:7]" 3 9 9 3 9 9 9 - 1; - setAttr -s 8 ".kot[0:7]" 3 9 9 3 1 9 9 - 3; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 41 0 120 0 156 0 206 0 240 - 0 285 0 321 0; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kot[4:7]" 1 9 9 9; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 41 1 120 1 156 1 206 1 240 - 1 285 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kot[4:7]" 1 9 9 9; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 41 1 120 1 156 1 206 1 240 - 1 285 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kot[4:7]" 1 9 9 9; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 41 1 120 1 156 1 206 1 240 - 1 285 1 321 1; - setAttr -s 8 ".kit[7]" 1; - setAttr -s 8 ".kot[4:7]" 1 9 9 9; - setAttr -s 8 ".kix[7]" 1; - setAttr -s 8 ".kiy[7]" 0; - setAttr -s 8 ".kox[4:7]" 1 1 1 1; - setAttr -s 8 ".koy[4:7]" 0 0 0 0; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 69 1 96 1 119 1 156 1 226 1 - 261 1 284 1 321 1; - setAttr -s 9 ".kit[0:8]" 9 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 69 0 96 0 119 0 156 0 226 0 - 261 0 284 0 321 0; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.7384771804188404 69 5.7384771804188404 - 96 5.7384771804188404 119 5.7384771804188404 156 5.7384771804188404 226 5.7384771804188404 - 261 5.7384771804188404 284 5.7384771804188404 321 5.7384771804188404; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.0494561358638701 69 2.0494561358638701 - 96 2.0494561358638701 119 2.0494561358638701 156 2.0494561358638701 226 2.0494561358638701 - 261 2.0494561358638701 284 2.0494561358638701 321 2.0494561358638701; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -15.409205020920503 69 -15.409205020920503 - 96 -15.409205020920503 119 -15.409205020920503 156 -15.409205020920503 226 - -15.409205020920503 261 -15.409205020920503 284 -15.409205020920503 321 -15.409205020920503; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 69 7.7133668323055993 96 7.7133668323055993 - 119 0 156 0 226 7.7133668323055993 261 7.7133668323055993 284 0 321 0; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 1 9 - 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 0.99942213296890259 0.99845200777053833 - 0.99855327606201172 1; - setAttr -s 9 ".koy[5:8]" 0.033990535885095596 -0.055620104074478149 - -0.053771551698446274 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 27.72702953106549 69 19.576116982883828 - 96 19.576116982883828 119 27.72702953106549 156 27.72702953106549 226 19.576116982883828 - 261 19.576116982883828 284 27.72702953106549 321 27.72702953106549; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 9 1; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 1 9 - 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 0.9993547797203064 0.9982718825340271 - 0.99838489294052124 1; - setAttr -s 9 ".koy[5:8]" -0.035916250199079514 0.058764584362506866 - 0.056812196969985962 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 69 1 96 1 119 1 156 1 226 1 - 261 1 284 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 69 1 96 1 119 1 156 1 226 1 - 261 1 284 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 69 1 96 1 119 1 156 1 226 1 - 261 1 284 1 321 1; - setAttr -s 9 ".kit[8]" 1; - setAttr -s 9 ".kot[5:8]" 1 9 9 9; - setAttr -s 9 ".kix[8]" 1; - setAttr -s 9 ".kiy[8]" 0; - setAttr -s 9 ".kox[5:8]" 1 1 1 1; - setAttr -s 9 ".koy[5:8]" 0 0 0 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 24 1 30 1 36 1 44 1 50 1 68 - 1 90 1 133 1 156 1 209 1 255 1 298 1 321 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 9 9 9 - 9 9 9 9 9 9 1; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 24 0 30 0 36 0 44 0 50 0 68 - 0 90 0 133 0 156 0 209 0 255 0 298 0 321 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 2.3128351505039433 24 2.3128351505039433 - 30 2.3128351505039433 36 2.3128351505039433 44 2.3128351505039433 50 2.3128351505039433 - 68 2.3128351505039433 90 2.3128351505039433 133 2.3128351505039433 156 2.3128351505039433 - 209 2.3128351505039433 255 2.3128351505039433 298 2.3128351505039433 321 - 2.3128351505039433; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0.23421866920666501 24 0.23421866920666501 - 30 0.23421866920666501 36 0.23421866920666501 44 0.23421866920666501 50 0.23421866920666501 - 68 0.23421866920666501 90 0.23421866920666501 133 0.23421866920666501 156 - 0.23421866920666501 209 0.23421866920666501 255 0.23421866920666501 298 0.23421866920666501 - 321 0.23421866920666501; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 12.660431799163181 24 7.9008319537560396 - 30 39.016433997086388 36 28.694212709616185 44 15.291251200423016 50 8.9442305058293439 - 68 6.7808786336124385 90 12.660431799163181 133 12.660431799163181 156 12.660431799163181 - 209 12.660431799163181 255 12.660431799163181 298 12.660431799163181 321 - 12.660431799163181; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 24 5.2555723290627778 30 -16.76234163202998 - 36 5.9002787555909437 44 -12.291857078170608 50 -21.77453965207193 68 -0.71481869324333414 - 90 0 133 0 156 0 209 0 255 0 298 0 321 0; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 2.4125540166489063 24 21.85241390361492 - 30 9.6480288102595519 36 1.2816103111795829 44 12.840572615061761 50 20.88672709754373 - 68 6.623082524097196 90 6.6291762441279065 133 2.7190922877940427 156 2.4125540166489063 - 209 8.1736799826346633 255 6.6291762441279065 298 2.7190922877940427 321 - 2.4125540166489063; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 0.99998444318771362; - setAttr -s 14 ".kiy[13]" -0.0055826283060014248; - setAttr -s 14 ".kox[10:13]" 0.99980312585830688 0.99967062473297119 - 0.99964213371276855 0.99998444318771362; - setAttr -s 14 ".koy[10:13]" 0.019841650500893593 -0.025663593783974648 - -0.02675185538828373 -0.0055826273746788502; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 24 1 30 1 36 1 44 1 50 1 68 - 1 90 1 133 1 156 1 209 1 255 1 298 1 321 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 24 1 30 1 36 1 44 1 50 1 68 - 1 90 1 133 1 156 1 209 1 255 1 298 1 321 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 24 1 30 1 36 1 44 1 50 1 68 - 1 90 1 133 1 156 1 209 1 255 1 298 1 321 1; - setAttr -s 14 ".kit[13]" 1; - setAttr -s 14 ".kot[10:13]" 1 9 9 9; - setAttr -s 14 ".kix[13]" 1; - setAttr -s 14 ".kiy[13]" 0; - setAttr -s 14 ".kox[10:13]" 1 1 1 1; - setAttr -s 14 ".koy[10:13]" 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 165 1 247 1 321 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.83371697884823759 165 -1.8373931045955381 - 247 -0.83680153259810386 321 0.83371697884823759; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.1086667563431649 165 0.23948600528621516 - 247 0.10906879739455771 321 -0.1086667563431649; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.4408920985006262e-016 165 0 - 247 0 321 4.4408920985006262e-016; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 165 0 247 0 321 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 165 0 247 0 321 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 165 0 247 0 321 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 165 1 247 1 321 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 165 1 247 1 321 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 165 1 247 1 321 1; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -71.101691513482606; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 32.578198345223548; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -95.56444850608456; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -118.97547160373531; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 30.32938199865233; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -92.904446145666853; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 138 0.5814880999021691; -createNode shadingEngine -n "m0"; - setAttr ".ihi" 0; - setAttr ".ro" yes; -createNode materialInfo -n "materialInfo1"; -createNode groupId -n "groupId2"; - setAttr ".ihi" 0; -createNode groupId -n "groupId3"; - setAttr ".ihi" 0; -createNode phong -n "m1"; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 46 1 50 1 54 1 57 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505294 26 -7.3924057183505063 - 40 -7.3924057183505179 46 -17.124037188805239 50 -16.184614532343865 54 -7.9820098837994706 - 57 -12.308575661360603; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -27.902018787772242 26 -47.074063250566127 - 40 -29.80970146242662 46 5.1356286277218492 50 2.8054700201938267 54 11.173984803659732 - 57 -0.95282201487227469; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 46.295679079339266 26 -25.87325148866584 - 40 -39.021431616519877 46 -45.657947847845755 50 -21.608400808547838 54 -5.9505266473776777 - 57 1.1907019295482839; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.3462904043098467 26 5.3462904043098467 - 40 5.3462904043098467 46 -137.21822615023987 50 -80.705944887551524 54 -116.160898422058 - 57 6.9309101890804268; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -29.54838557779286 26 -29.54838557779286 - 40 -29.54838557779286 46 -29.548385577792871 50 -29.548385577792871 54 -16.960873563865537 - 57 -18.912749782057567; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -5.3030645628451412 26 -5.3030645628451412 - 40 -5.3030645628451412 46 -5.3030645628451367 50 -5.303064562845174 54 72.349909585786875 - 57 -1.5040355914857426; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 46 1 50 1 54 1 57 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 46 1 50 1 54 1 57 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 46 1 50 1 54 1 57 - 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 45 1 47 1 50 1 54 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599272 26 5.3429412887409509 - 40 8.5556322169264583 45 -4.7788909586105337 47 -1.7748788012054757 50 8.1032305447016562 - 54 9.1932009727674107; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -27.902018787772242 26 -42.852518238477863 - 40 -40.852281268102097 45 -20.686997481942612 47 -9.9883124012267306 50 2.5976522199061218 - 54 -0.49216656971902861; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 45.90915342386289 26 -25.673127079494183 - 40 -27.317807907262615 45 -44.522593778644499 47 -47.27011802752687 50 -30.330982737658747 - 54 5.5794890277464173; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 10.109326515514191 26 -23.24603559211992 - 40 -13.384540695570882 45 -53.133341354984331 47 -71.007549998059076 50 -98.902536707040028 - 54 -1.4789471918415964; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 63.314403926397745 26 63.314403926397731 - 40 63.31440392639783 45 16.935807680510099 47 4.4107688039341699 50 -11.069622315077353 - 54 15.370162747101846; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.590164763476968 26 11.590164763476965 - 40 11.590164763476992 45 -4.4588010166110381 47 -2.5352028272593254 50 4.9287722085422265 - 54 4.0000679704473141; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 45 1 47 1 50 1 54 - 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 45 1 47 1 50 1 54 - 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 26 1 40 1 45 1 47 1 50 1 54 - 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 23 1 26 1 30 1 40 1 45 - 1 50 1 54 1 62 1 72 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.9808213950621805 20 7.5901231261283657 - 23 3.8245446048056144 26 -2.9152499389882958 30 1.9808213950621762 40 -1.3415510043916097 - 45 -6.2245712386292213 50 7.3062062638027694 54 2.7549392158158841 62 1.7904716055565564 - 72 1.7904716055565564; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -16.871363683421645 20 -16.561674063569097 - 23 -7.736402725099242 26 -7.7310790668519216 30 -0.83184804796066203 40 -2.8844808810772773 - 45 8.633756225781676 50 16.299833302973529 54 25.467509833446083 62 35.237749496336392 - 72 35.237749496336392; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 8.6912861200334959 20 -8.9553845291185947 - 23 -12.09115101226536 26 -13.800121710317084 30 -16.428984694400057 40 -19.440837046780839 - 45 -14.207080204197558 50 6.0426191373004778 54 12.594694744576117 62 10.07097725157794 - 72 10.07097725157794; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -129.41813740830423 20 -87.838301964495599 - 23 -67.046132246893237 26 -40.81638422910531 30 -16.147080465426196 40 4.8987086542291358 - 45 39.877958276445469 50 72.650979543572888 54 50.224044665964207 62 0 72 - 0; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 20 0 23 -7.5078282714114604 - 26 -14.165713734989462 30 -3.9756933518293969e-016 40 -5.4029422326095462 - 45 3.896988822633721 50 0 54 -0.37411094882090579 62 0 72 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 7.4260738755503786 20 7.4260738755503768 - 23 -0.95871801076974605 26 -8.3942881632552986 30 7.4260738755503786 40 0.95667291234623963 - 45 8.5807631194443879 50 7.4260738755503786 54 7.3152237069473838 62 7.4260738755503946 - 72 7.4260738755503946; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 23 1 26 1 30 1 40 1 45 - 1 50 1 54 1 62 1 72 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 23 1 26 1 30 1 40 1 45 - 1 50 1 54 1 62 1 72 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 23 1 26 1 30 1 40 1 45 - 1 50 1 54 1 62 1 72 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 1 18 1 23 1 28 1 38 1 47 1 51 - 1 68 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 0 28 0 38 0 47 0 51 - 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 0 28 0 38 0 47 0 51 - 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 0 28 0 38 0 47 0 51 - 0 68 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 1 18 1 23 1 28 1 38 1 47 1 51 - 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 1 18 1 23 1 28 1 38 1 47 1 51 - 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 1 18 1 23 1 28 1 38 1 47 1 51 - 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 -0.33009531459353392 18 -0.33009531459353392 - 23 -0.33009531459353392 28 -0.33009531459353392 38 -0.33009531459353392 47 - -0.33009531459353392 51 -0.33009531459353392 68 -0.33009531459353392; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 -0.93351630712508826 18 -0.93351630712508826 - 23 -0.93351630712508826 28 -0.93351630712508826 38 -0.93351630712508826 47 - -0.93351630712508826 51 -0.93351630712508826 68 -0.93351630712508826; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 -1.7376951365574447 18 -1.7376951365574447 - 23 -1.7376951365574447 28 -1.7376951365574447 38 -1.7376951365574447 47 -1.7376951365574447 - 51 -1.7376951365574447 68 -1.7376951365574447; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 0 28 0 38 0 47 0 51 - 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 0 28 0 38 0 47 0 51 - 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -1 0 18 0 23 -46.982539200727508 - 28 -16.042818263663051 38 -51.566201561774093 47 -87.089584859885136 51 -104.27831871380982 - 68 -6.8754935415698846; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 1.0639533528779415; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 -1.1085122182869189; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 -1.2803139946157169; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" -1 0; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 1 18 1 23 1 26 1 29 1 47 1 49 - 1 50 1 52 1 54 1 56 1 65 1 72 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -46.030907265180566 18 -46.030907265180566 - 23 -56.809579932284471 26 -57.297490192239245 29 -57.297490192239245 47 -57.297490192239245 - 49 -54.478426871701316 50 -53.693005245948697 52 -53.693005245948697 54 -51.559506484848633 - 56 -50.709920286684167 65 -54.737159338818216 72 -51.907036029080558; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -22.126802863647807 18 -22.126802863647807 - 23 17.788958299516473 26 5.0081812307644142 29 5.0081812307644142 47 5.0081812307644142 - 49 4.8464156051788123 50 5.128861690075162 52 5.128861690075162 54 8.3166573553889229 - 56 16.099436289737923 65 41.415106847927291 72 44.95276098509936; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -1.1827709997086959 18 -1.1827709997086959 - 23 -5.1424975699431261 26 14.71891654229975 29 14.71891654229975 47 14.71891654229975 - 49 18.895681332636812 50 23.521979404252434 52 23.521979404252434 54 32.854927690893284 - 56 41.597826807996569 65 37.848979477025665 72 37.848979477025665; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -99.950111501411854 18 -99.950111501411854 - 23 -24.214302904288388 26 21.005720373583245 29 33.402182600940229 47 33.402182600940229 - 49 32.835137449414781 50 22.999705602974753 52 22.999705602974753 54 51.432939585689311 - 56 97.462339464099628 65 38.797130601922305 72 23.468857978210018; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 40.530583229589944 18 40.530583229589944 - 23 40.530583229589929 26 -20.504948567453471 29 -17.05735557596331 47 -17.05735557596331 - 49 -53.364028044481195 50 -81.713333811970941 52 -81.713333811970941 54 -68.126276746626814 - 56 -43.404372232592415 65 -63.670752398935349 72 -28.989805790169729; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 6.9000238083301229 18 6.9000238083301229 - 23 6.9000238083301904 26 19.448825171691837 29 2.309275077873906 47 2.309275077873906 - 49 5.2942869645653534 50 15.701893455528165 52 15.701893455528165 54 -0.45419778171477304 - 56 3.7306285444745666 65 60.012603908651812 72 36.832365798494777; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 1 18 1 23 1 26 1 29 1 47 1 49 - 1 50 1 52 1 54 1 56 1 65 1 72 1; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 0.99999999999999978 18 0.99999999999999978 - 23 0.99999999999999978 26 0.99999999999999978 29 0.99999999999999978 47 0.99999999999999978 - 49 0.99999999999999978 50 0.99999999999999978 52 0.99999999999999978 54 0.99999999999999978 - 56 0.99999999999999978 65 0.99999999999999978 72 0.99999999999999978; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 1 18 1 23 1 26 1 29 1 47 1 49 - 1 50 1 52 1 54 1 56 1 65 1 72 1; - setAttr -s 13 ".kit[3:12]" 3 3 3 3 3 3 9 - 9 9 9; - setAttr -s 13 ".kot[3:12]" 3 3 3 3 3 3 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 1 24 1 26 1 28 1 32 1 41 1 44 - 1 47 1 53 1 54 1 56 1 65 1 72 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -4.0804971630949147 24 -4.0804971630949147 - 26 -6.5270086120398751 28 -10.987157668793664 32 -16.497216089676257 41 -16.497216089676257 - 44 -14.055869714249567 47 -17.092775061148252 53 -17.092775061148252 54 -15.627244783609179 - 56 -10.41220942979416 65 -8.7947412930784434 72 -8.7947412930784434; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -20.561841326754191 24 -20.561841326754191 - 26 -0.64284411788714202 28 12.251993747582624 32 3.9351186646142811 41 3.9351186646142811 - 44 14.399441001041108 47 4.3586214044016103 53 4.3586214044016103 54 8.6142723804766632 - 56 26.348521145651077 65 46.086204278603823 72 46.086204278603823; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -6.2199016597829484 24 -6.2199016597829484 - 26 -7.9965198625322671 28 14.408515340808744 32 14.332718831072164 41 14.332718831072164 - 44 38.471704278780649 47 61.696251145087309 53 61.696251145087309 54 58.356074564387548 - 56 42.80925976852248 65 28.375781252042298 72 28.375781252042298; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 -37.192348213066076 24 -37.192348213066076 - 26 -27.666718121914442 28 -37.840598117127001 32 35.17979891560951 41 35.17979891560951 - 44 -23.953757848192488 47 43.858928316163706 53 43.858928316163706 54 68.240813213482411 - 56 54.663281061291443 65 49.23226103144578 72 44.61114431683459; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 54.671688625550289 24 54.671688625550289 - 26 24.718313295698689 28 2.6080987359799876 32 28.887487078832468 41 28.887487078832468 - 44 3.7034151195247698 47 26.094625790471238 53 26.094625790471238 54 5.8789259489603554 - 56 59.025529103624265 65 36.81654216389655 72 29.721056185700206; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 39.468648652835761 24 39.468648652835761 - 26 -9.4978900365605554 28 -22.161493378755853 32 -6.2610576615839779 41 -6.2610576615839779 - 44 -62.179261503908606 47 1.2400574619674247 53 1.2400574619674247 54 -5.7901397219079804 - 56 -44.089863311556087 65 -28.192011993544774 72 -18.235602453736533; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 1 24 1 26 1 28 1 32 1 41 1 44 - 1 47 1 53 1 54 1 56 1 65 1 72 1; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 0.99999999999999989 24 0.99999999999999989 - 26 0.99999999999999989 28 0.99999999999999989 32 0.99999999999999989 41 0.99999999999999989 - 44 0.99999999999999989 47 0.99999999999999989 53 0.99999999999999989 54 0.99999999999999989 - 56 0.99999999999999989 65 0.99999999999999989 72 0.99999999999999989; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" -1 0.99999999999999978 24 0.99999999999999978 - 26 0.99999999999999978 28 0.99999999999999978 32 0.99999999999999978 41 0.99999999999999978 - 44 0.99999999999999978 47 0.99999999999999978 53 0.99999999999999978 54 0.99999999999999978 - 56 0.99999999999999978 65 0.99999999999999978 72 0.99999999999999978; - setAttr -s 13 ".kit[4:12]" 3 3 3 3 3 3 9 - 9 9; - setAttr -s 13 ".kot[4:12]" 3 3 3 3 3 3 9 - 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 1 28 1 52 1 56 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 -7.5406347832540632e-013 28 - -7.5406347832540632e-013 52 -7.5406347832540632e-013 56 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 13.71946295727715 28 13.71946295727715 - 52 13.71946295727715 56 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 -3.0908609005564358e-013 28 - -3.0908609005564358e-013 52 -3.0908609005564358e-013 56 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 68.596496127541187 28 68.596496127541187 - 52 68.596496127541187 56 68.596496127541187; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 -60.802874383230787 28 -60.802874383230787 - 52 -60.802874383230787 56 -60.802874383230787; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 -157.43468421330525 28 -157.43468421330525 - 52 -157.43468421330525 56 -157.43468421330525; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 15.445123296459183 28 15.445123296459183 - 52 15.445123296459183 56 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 15.445123296459185 28 15.445123296459185 - 52 15.445123296459185 56 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 15.445123296459181 28 15.445123296459181 - 52 15.445123296459181 56 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 1 28 1 52 1 56 1; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 0 28 0 52 0 56 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 0 28 0 52 0 56 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 0 28 0 52 0 56 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 0 28 1 52 1 56 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 25 0 28 0 52 0 56 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 1 32 1 41 1 44 1 46 1 47 1 53 - 1 54 1 59 1 72 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 -2.5294371750177831 32 -2.5294371750177831 - 41 -2.5294371750177831 44 -2.5294371750177831 46 -2.5294371750177831 47 -2.5294371750177831 - 53 -2.5294371750177831 54 -2.5294371750177831 59 -2.5294371750177831 72 -2.5294371750177831; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 13.481673551673362 32 13.481673551673362 - 41 13.481673551673362 44 13.481673551673362 46 13.481673551673362 47 13.481673551673362 - 53 13.481673551673362 54 13.481673551673362 59 13.481673551673362 72 13.481673551673362; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 -0.26635088939205875 32 -0.26635088939205875 - 41 -0.26635088939205875 44 -0.26635088939205875 46 -0.26635088939205875 47 - -0.26635088939205875 53 -0.26635088939205875 54 -0.26635088939205875 59 -0.26635088939205875 - 72 -0.26635088939205875; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 141.20709981379272 32 141.20709981379272 - 41 141.20709981379272 44 141.20709981379272 46 141.20709981379272 47 141.20709981379272 - 53 141.20709981379272 54 141.20709981379272 59 141.20709981379272 72 141.20709981379272; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 64.064019952206479 32 64.064019952206479 - 41 64.064019952206479 44 64.064019952206479 46 64.064019952206479 47 64.064019952206479 - 53 64.064019952206479 54 64.064019952206479 59 64.064019952206479 72 64.064019952206479; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 252.95011708695623 32 252.95011708695623 - 41 252.95011708695623 44 252.95011708695623 46 252.95011708695623 47 252.95011708695623 - 53 252.95011708695623 54 252.95011708695623 59 252.95011708695623 72 252.95011708695623; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 15.445123296459185 32 15.445123296459185 - 41 15.445123296459185 44 15.445123296459185 46 15.445123296459185 47 15.445123296459185 - 53 15.445123296459185 54 15.445123296459185 59 15.445123296459185 72 15.445123296459185; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 15.445123296459185 32 15.445123296459185 - 41 15.445123296459185 44 15.445123296459185 46 15.445123296459185 47 15.445123296459185 - 53 15.445123296459185 54 15.445123296459185 59 15.445123296459185 72 15.445123296459185; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 15.445123296459185 32 15.445123296459185 - 41 15.445123296459185 44 15.445123296459185 46 15.445123296459185 47 15.445123296459185 - 53 15.445123296459185 54 15.445123296459185 59 15.445123296459185 72 15.445123296459185; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 1 32 1 41 1 44 1 46 1 47 1 53 - 1 54 1 59 1 72 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 0 32 0 41 0 44 0 46 0 47 0 53 - 0 54 0 59 0 72 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 0 32 0 41 0 44 0 46 0 47 0 53 - 0 54 0 59 0 72 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 0 32 0 41 0 44 0 46 0 47 0 53 - 0 54 0 59 0 72 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 0 32 1 41 1.0374999990712024 - 44 0 46 0 47 1 53 1 54 0.7 59 0 72 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 29 0 32 0 41 0 44 0 46 0 47 0 53 - 0 54 0.40000000000000002 59 0.2833819241982507 72 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 3 9 3; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 3 9 3; -select -ne :time1; - setAttr ".o" 72; -select -ne :renderPartition; - setAttr -s 13 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 13 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 3 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".t" -type "double3" -31.859694719102226 0 15.380674188071323 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049337152 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rring_lo; - setAttr ".jo" -type "double3" 177.08304195105549 -12.748596609828455 129.8945470875733 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_origin; - setAttr ".t" -type "double3" -31.859694719102226 0 12.031251180646866 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FLAT"; -select -ne IMP_RHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "groupId3.id" "polySurfaceShape1.iog.og[1].gid"; -connectAttr "m0.mwc" "polySurfaceShape1.iog.og[1].gco"; -connectAttr "groupId2.id" "polySurfaceShape1.ciog.cog[0].cgid"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[2].llnk"; -connectAttr "m0.msg" "lightLinker1.lnk[2].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "m1.oc" "m0.ss"; -connectAttr "groupId3.msg" "m0.gn" -na; -connectAttr "polySurfaceShape1.iog.og[1]" "m0.dsm" -na; -connectAttr "m0.msg" "materialInfo1.sg"; -connectAttr "m0.pa" ":renderPartition.st" -na; -connectAttr "m1.msg" ":defaultShaderList1.s" -na; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "polySurfaceShape1.ciog.cog[0]" ":initialShadingGroup.dsm" -na - ; -connectAttr "groupId2.msg" ":initialShadingGroup.gn" -na; -// End of outofhole.ma diff --git a/base/models/monsters/imp/animation/cycles/pain3.ma b/base/models/monsters/imp/animation/cycles/pain3.ma deleted file mode 100644 index 251e4d6e8..000000000 --- a/base/models/monsters/imp/animation/cycles/pain3.ma +++ /dev/null @@ -1,3796 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:18 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain3.ma -//Last modified: Mon, Mar 15, 2004 09:09:51 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 17.702050259139185 31.842936243058137 259.06476191198834 ; - setAttr ".r" -type "double3" 4.4698910864526882 -359.00000000000443 6.2129671272200827e-018 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 272.13145619611009; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 22.57111845060059 55.161154620979616 4.855171589784562 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 34.105831591195802 115.73742012124887 7.6304956654842391 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 164.67624707525044; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 38.073089812497805 54.534898150352312 107.86157254419315 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.464393079493448; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 103.07551681128726 30.048199460830929 -10.456343212331282 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 123.45552071539539; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -29.548385579999998 25 -29.548385579999998 - 29 -38.367703938541368 33 -38.367703938541368; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 5.3462904040000003 25 5.3462904040000003 - 29 -22.261750778216175 33 0 53 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.3030645630000004 25 -5.3030645630000004 - 29 0 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.392405718 25 -7.392405718 - 29 -8.5228661809757718 33 -8.5228661809757842; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 25 0 29 8.6414253885234693 - 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.3620493590000002 25 -7.3620493590000002 - 29 29.058010331813129 33 55.894887262743886; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 63.314403930000005 25 63.314403930000005 41 36.237070617308525 - 49 36.237070617308518 53 36.237070617308518; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 10.10932652 25 10.10932652 41 0 49 -19.289764981099978 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 11.59016476 - 25 11.59016476 41 0 49 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 7.1689522480000001 25 7.1689522480000001 41 9.6873596619451892 - 49 9.6873596619451749 53 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 25 0 41 0 49 6.5824344037117717 53 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 -7.748575014 25 -7.748575014 41 19.750878638974889 - 49 56.871344609681749 53 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 44.282519935230724 25 41.235789590000003 29 42.252989606287457 - 33 39.474641024093501 41 35.507697111286575 49 41.757587197385924 53 38.975399081339425 - 61 36.922520121156822; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 -13.543165533959179 25 -2.4191866630000001 29 - 35.34397057886077 33 46.128707057474401 41 48.210536281058985 49 64.065722338788731 - 53 76.398879176777299 61 80.803578047487491; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 1.7610456982876939 25 1.980821395 29 1.9932938451333648 - 33 0.5224520839187321 41 -0.96093906669208984 49 -4.8012869768196573 53 0.51611782181851806 - 61 0.81152919952064195; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kix[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".kiy[9:10]" 0.98337632417678833 0; - setAttr -s 11 ".kox[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".koy[9:10]" 0.98337632417678833 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 0.4494172494 25 0.4494172494 28.2 6.6566912693983946 - 32.200000000000003 6.1330193887268454 40.200000000000003 0.24039650864424209 - 53 -4.1657930308134645; - setAttr -s 9 ".kit[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kix[6:8]" 0.061753064393997192 0.083855703473091125 - 1; - setAttr -s 9 ".kiy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; - setAttr -s 9 ".kox[6:8]" 0.061753060668706894 0.083855703473091125 - 1; - setAttr -s 9 ".koy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 -0.058577090280000001 25 -0.058577090280000001 28.2 - -0.86763382127902322 32.200000000000003 -0.42972806484138226 40.200000000000003 - -0.031333305538134112 53 0.54296989172209287; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 0 25 0 28.2 5.0790319675705673 32.200000000000003 - 6.7230875260072231 40.200000000000003 0 53 -7.4542171015494922; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 40.200000000000003 - 2.3128351505039433 53 2.3128351505039433; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 40.200000000000003 0.23421866920666501 53 0.23421866920666501; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581426 20.2 7.824737866480139 28.2 -0.56667192682884493 40.200000000000003 - 0.57720421748491901 53 8.7951795972581372; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 -24.30811116038322 20.2 -5.0226759171895878 28.2 13.000667896194788 40.200000000000003 - 12.790622953496632 53 13.892774724407374; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325647 - 20.2 22.77669484325164 28.2 -13.027357639203586 40.200000000000003 -8.1143097424545108 - 53 26.888910802325626; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 373.5000544583113 19.4 398.33832420130017 25.800000000000001 405.49797585237241 - 32.200000000000003 388.93797585237292 40.200000000000003 400.28864310407283 - 53 389.49637174592857; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -16.781272320372167 19.4 -14.641906192173103 25.800000000000001 -14.641906192173103 - 32.200000000000003 -14.641906192173099 40.200000000000003 -14.641906192173103 - 53 -14.641906192173099; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -13.03948754198662 19.4 -0.44667534838541073 25.800000000000001 -0.4466753483854129 - 32.200000000000003 -0.44667534838541123 40.200000000000003 -0.44667534838541301 - 53 -0.44667534838541167; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 32.200000000000003 5.6268319407172029 40.200000000000003 5.6268319407172029 - 53 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 32.200000000000003 -2.1098668596606802 40.200000000000003 -2.1098668596606802 - 53 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.600000000000001 5.7384771804188404 47 5.7384771804188404 53 5.7384771804188404; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.600000000000001 2.0494561358638701 47 2.0494561358638701 53 2.0494561358638701; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.600000000000001 0 47 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.600000000000001 16.052055400530755 47 30.358488909126763 53 37.874152024707215; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.600000000000001 11.52461344822842 47 -2.1187003779812748 53 -14.364226384227051; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.600000000000001 -25.97088988767895 47 -26.687875434482198 53 -36.863333637497242; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 4.2330399930741924 15 -11.340398697750635 18 - -24.598006495389306 25 -14.840217421411868 32.200000000000003 -15.091352590275802 - 40.200000000000003 -24.981217127315897 53 -16.777720747043478; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 50.780790677232417 15 31.281930439752845 18 48.15826652499068 - 25 16.509687863537451 32.200000000000003 5.460283656526733 40.200000000000003 - 3.555911204482308 53 5.3449549069799076; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 40.298833138656228 15 14.363880496065407 18 -33.408635312787865 - 25 -17.89538038991634 32.200000000000003 -19.683531133663919 40.200000000000003 - -11.295059140243522 53 -16.48879266455566; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 15 2.6456615572060826 18 2.6456615572060826 - 25 2.6456615572060826 32.200000000000003 2.6456615572060826 40.200000000000003 - 2.6456615572060826 53 2.6456615572060826; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 15 1.9935618776130362 18 1.9935618776130362 - 25 1.9935618776130362 32.200000000000003 1.9935618776130362 40.200000000000003 - 1.9935618776130362 53 1.9935618776130362; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 11.4 0 13 0 15 0 18 0 - 25 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 13 12.412879749935719 - 20 12.412879749935719 25 12.412879749935719 34.6 12.412879749935719 40.200000000000003 - 12.412879749935719 53 12.412879749935719; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 13 -6.7286993982861674 - 20 -6.7286993982861674 25 -6.7286993982861674 34.6 -6.7286993982861674 40.200000000000003 - -6.7286993982861674 53 -6.7286993982861674; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 13 -3.868763862603668 - 20 -3.868763862603668 25 -3.868763862603668 34.6 -3.868763862603668 40.200000000000003 - -3.868763862603668 53 -3.868763862603668; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 80.239686562403847 13 49.536191119687935 - 20 92.401590058023146 25 103.41622835125608 34.6 94.762662499017765 40.200000000000003 - 87.603010847945214 53 105.11870283856432; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.8978517871634404 13 0.21742569259672134 - 20 0.098912473866345871 25 0 34.6 0 40.200000000000003 0 53 0.21742569259672076; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.92545182592768849 13 0.034116996666525408 - 20 0.015520688835634049 25 0 34.6 0 40.200000000000003 0 53 0.034116996666525033; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 25 -12.41287000000041 27.4 -12.41287000000041 40.200000000000003 - -12.41287000000041 53 -12.41287000000041; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 25 -6.7285999999993047 27.4 -6.7285999999993047 40.200000000000003 - -6.7285999999993047 53 -6.7285999999993047; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 25 -3.8687599999999316 27.4 -3.8687599999999316 40.200000000000003 - -3.8687599999999316 53 -3.8687599999999316; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.099612817676174 10.6 82.316033184538099 - 13 56.675828465321835 25 92.144105348206509 27.4 63.019898856647714 40.200000000000003 - 82.099898856647854 53 81.577924579716537; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 25 -ast 13 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 25 0 29 0 33 0 41 0 49 0 53 - 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 25 0 29 0 33 0 41 0 49 0 53 - 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 3.09040954 25 3.09040954 29 - 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.3867545965885748 25 4.0594933981443528; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192573708760349 25 2.2039448112088227; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821078932592165 25 -3.1435795472686916; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.11911525643685131 25 5.8468963861459979; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -12.432261590875594 25 -28.368765378774526; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -30.651383093952994 25 -28.052185257064387; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.9298872857263043 25 -4.3029039238518836; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.7882691209681596 25 2.0038703496478467; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -5.1146352835171411 25 -2.9983962363577357; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.528644656404655 25 42.346733523013434; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -14.243020355514393 25 -6.9184562357428412; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.779588332864435 25 -1.2143143388545381; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 25 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 25 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 25 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -82.976046413383102 25 -82.082942762890042; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.144874087538099 25 -41.262114869043131; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.205809805073454 25 -27.695327781842096; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 25 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 25 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -2.5294371750177831 25 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.481673551673362 25 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.26635088939205875 25 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 240.76698806505698 25 239.50132211939308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 76.182851789542724 25 78.903278192407754; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 374.83445880576221 25 345.83232963291096; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -18.647768363316043 25 -32.458460557687573; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 36.3191443147117 25 25.207071114325792; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 107.88509288000579 25 81.364043115468817; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 23.914756983415913 25 25.521603815854018; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.717907199956898 25 -49.929606980787931; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -41.055955789443395 25 -60.904739916227172; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -118.97547159999999 25 -118.97547159999999; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.329382000000003 25 30.329382000000003; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -92.904446149999998 25 -92.904446149999998; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -71.101691509999995 25 -71.101691509999995; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 32.578198350000001 25 32.578198350000001; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -95.564448510000005 25 -95.564448510000005; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -select -ne :time1; - setAttr ".o" 13; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Body2; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lloleg; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_LIK; -select -ne IMP_RIK; -select -ne IMP_Rwing3; - setAttr ".r" -type "double3" 33.805899850653965 26.272866888105089 92.702463214576383 ; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr -av ".rz"; -select -ne IMP_Rwing4; - setAttr ".r" -type "double3" 108.20197775459526 -16.834522544392435 81.977625287425354 ; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr -av ".rz"; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pain3.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_chest.ma b/base/models/monsters/imp/animation/cycles/pain_chest.ma deleted file mode 100644 index c51cb8f37..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_chest.ma +++ /dev/null @@ -1,3789 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:17 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_chest.ma -//Last modified: Mon, Mar 15, 2004 09:04:20 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 136.17954940791105 116.63392760133064 134.37936155899513 ; - setAttr ".r" -type "double3" -23.730108910345447 -319.79999999999359 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 193.13681176587454; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 22.621395057547673 72.090731966247304 -1.5964668190306734 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 34.105831591195802 115.73742012124887 7.6304956654842391 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 164.67624707525044; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 38.073089812497805 54.534898150352312 107.86157254419315 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.464393079493448; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 103.07551681128726 30.048199460830929 -10.456343212331282 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 123.45552071539539; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -29.548385579999998 25 -29.548385579999998 - 29 -38.367703938541368 33 -38.367703938541368; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 5.3462904040000003 25 5.3462904040000003 - 29 -22.261750778216175 33 0 53 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.3030645630000004 25 -5.3030645630000004 - 29 0 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.392405718 25 -7.392405718 - 29 -8.5228661809757718 33 -8.5228661809757842; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 25 0 29 8.6414253885234693 - 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.3620493590000002 25 -7.3620493590000002 - 29 29.058010331813129 33 55.894887262743886; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 63.314403930000005 25 63.314403930000005 41 36.237070617308525 - 49 36.237070617308518 53 36.237070617308518; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 10.10932652 25 10.10932652 41 0 49 -19.289764981099978 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 11.59016476 - 25 11.59016476 41 0 49 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 7.1689522480000001 25 7.1689522480000001 41 9.6873596619451892 - 49 9.6873596619451749 53 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 25 0 41 0 49 6.5824344037117717 53 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 -7.748575014 25 -7.748575014 41 19.750878638974889 - 49 56.871344609681749 53 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 42.587516741806581 19 43.953987309620217 25 41.235789590000003 - 29 42.252989606287457 33 39.474641024093501 41 35.507697111286575 49 41.757587197385924 - 53 38.975399081339425 61 36.922520121156822; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 -6.4235737777912316 19 -9.9012425657988388 25 - -2.4191866630000001 29 35.34397057886077 33 46.128707057474401 41 48.210536281058985 - 49 64.065722338788731 53 76.398879176777299 61 80.803578047487491; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 2.5741423197638151 19 4.2998164017139082 25 - 1.980821395 29 1.9932938451333648 33 0.5224520839187321 41 -0.96093906669208984 - 49 -4.8012869768196573 53 0.51611782181851806 61 0.81152919952064195; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 1 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 1 3; - setAttr -s 12 ".kix[10:11]" 0.18157932162284851 1; - setAttr -s 12 ".kiy[10:11]" 0.98337632417678833 0; - setAttr -s 12 ".kox[10:11]" 0.18157932162284851 1; - setAttr -s 12 ".koy[10:11]" 0.98337632417678833 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8.2 1 12.2 1 13 1 19 1 25 1 - 29 1 33 1 41 1 49 1 53 1 61 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8.2 1 12.2 1 13 1 19 1 25 1 - 29 1 33 1 41 1 49 1 53 1 61 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8.2 1 12.2 1 13 1 19 1 25 1 - 29 1 33 1 41 1 49 1 53 1 61 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 8.2 1 12.2 1 13 1 19 1 25 1 - 29 1 33 1 41 1 49 1 53 1 61 1; - setAttr -s 12 ".kit[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; - setAttr -s 12 ".kot[0:11]" 9 9 9 3 9 3 9 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 0.4494172494 25 0.4494172494 28.2 6.6566912693983946 - 32.200000000000003 6.1330193887268454 40.200000000000003 0.24039650864424209 - 53 -4.1657930308134645; - setAttr -s 9 ".kit[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kix[6:8]" 0.061753064393997192 0.083855703473091125 - 1; - setAttr -s 9 ".kiy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; - setAttr -s 9 ".kox[6:8]" 0.061753060668706894 0.083855703473091125 - 1; - setAttr -s 9 ".koy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 -0.058577090280000001 25 -0.058577090280000001 28.2 - -0.86763382127902322 32.200000000000003 -0.42972806484138226 40.200000000000003 - -0.031333305538134112 53 0.54296989172209287; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 0 25 0 28.2 5.0790319675705673 32.200000000000003 - 6.7230875260072231 40.200000000000003 0 53 -7.4542171015494922; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 40.200000000000003 - 2.3128351505039433 53 2.3128351505039433; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 40.200000000000003 0.23421866920666501 53 0.23421866920666501; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581426 20.2 7.824737866480139 28.2 -0.56667192682884493 40.200000000000003 - 0.57720421748491901 53 8.7951795972581372; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 -24.30811116038322 20.2 -5.0226759171895878 28.2 13.000667896194788 40.200000000000003 - 12.790622953496632 53 13.892774724407374; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325647 - 20.2 22.77669484325164 28.2 -13.027357639203586 40.200000000000003 -8.1143097424545108 - 53 26.888910802325626; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 368.43949989086099 19.4 398.33832420130017 25.800000000000001 405.49797585237241 - 32.200000000000003 388.93797585237292 40.200000000000003 400.28864310407283 - 53 389.49637174592857; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -13.812492743297291 19.4 -14.641906192173103 25.800000000000001 -14.641906192173103 - 32.200000000000003 -14.641906192173099 40.200000000000003 -14.641906192173103 - 53 -14.641906192173099; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 6.1114145780702858 19.4 -0.44667534838541073 25.800000000000001 -0.4466753483854129 - 32.200000000000003 -0.44667534838541123 40.200000000000003 -0.44667534838541301 - 53 -0.44667534838541167; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 32.200000000000003 5.6268319407172029 40.200000000000003 5.6268319407172029 - 53 5.6268319407172029; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 32.200000000000003 -2.1098668596606802 40.200000000000003 -2.1098668596606802 - 53 -2.1098668596606802; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.600000000000001 5.7384771804188404 47 5.7384771804188404 53 5.7384771804188404; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.600000000000001 2.0494561358638701 47 2.0494561358638701 53 2.0494561358638701; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.600000000000001 0 47 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.600000000000001 16.052055400530755 47 30.358488909126763 53 37.874152024707215; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.600000000000001 11.52461344822842 47 -2.1187003779812748 53 -14.364226384227051; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.600000000000001 -25.97088988767895 47 -26.687875434482198 53 -36.863333637497242; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 6.6 1 11.4 1 13 1 18 1 25 1 - 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 6.6 1 11.4 1 13 1 18 1 25 1 - 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 6.6 1 11.4 1 13 1 18 1 25 1 - 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -33.477607178884384 18 -44.665229992089117 25 - -14.840217421411868 32.200000000000003 -15.091352590275802 40.200000000000003 - -24.981217127315897 53 -16.777720747043478; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 8.8200946856803952 18 22.016749744658348 25 16.509687863537451 - 32.200000000000003 5.460283656526733 40.200000000000003 3.555911204482308 - 53 5.3449549069799076; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 29.527236381391724 18 -21.693219535296443 25 - -17.89538038991634 32.200000000000003 -19.683531133663919 40.200000000000003 - -11.295059140243522 53 -16.48879266455566; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 18 2.6456615572060826 25 2.6456615572060826 - 32.200000000000003 2.6456615572060826 40.200000000000003 2.6456615572060826 - 53 2.6456615572060826; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 18 1.9935618776130362 25 1.9935618776130362 - 32.200000000000003 1.9935618776130362 40.200000000000003 1.9935618776130362 - 53 1.9935618776130362; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 6.6 0 11.4 0 13 0 18 0 25 0 - 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[5:8]" 3 9 9 3; - setAttr -s 9 ".kot[5:8]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 6.6 1 11.4 1 13 1 18 1 25 1 - 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 13 12.412879749935719 - 20 12.412879749935719 25 12.412879749935719 34.6 12.412879749935719 40.200000000000003 - 12.412879749935719 53 12.412879749935719; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 13 -6.7286993982861674 - 20 -6.7286993982861674 25 -6.7286993982861674 34.6 -6.7286993982861674 40.200000000000003 - -6.7286993982861674 53 -6.7286993982861674; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 13 -3.868763862603668 - 20 -3.868763862603668 25 -3.868763862603668 34.6 -3.868763862603668 40.200000000000003 - -3.868763862603668 53 -3.868763862603668; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 80.239686562403847 13 63.99454265112773 - 20 92.401590058023146 25 103.41622835125608 34.6 94.762662499017765 40.200000000000003 - 87.603010847945214 53 105.11870283856432; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.8978517871634404 13 0.21742569259672134 - 20 0.098912473866345871 25 0 34.6 0 40.200000000000003 0 53 0.21742569259672076; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.92545182592768849 13 0.034116996666525387 - 20 0.015520688835634049 25 0 34.6 0 40.200000000000003 0 53 0.034116996666525033; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 25 -12.41287000000041 27.4 -12.41287000000041 40.200000000000003 - -12.41287000000041 53 -12.41287000000041; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 25 -6.7285999999993047 27.4 -6.7285999999993047 40.200000000000003 - -6.7285999999993047 53 -6.7285999999993047; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 25 -3.8687599999999316 27.4 -3.8687599999999316 40.200000000000003 - -3.8687599999999316 53 -3.8687599999999316; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.099612817676174 10.6 82.316033184538099 - 13 91.384037731060346 25 92.144105348206509 27.4 63.019898856647714 40.200000000000003 - 82.099898856647854 53 81.577924579716537; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 25 -ast 13 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 0 19 0 25 0 29 0 33 0 41 0 49 - 0 53 0 61 0; - setAttr -s 9 ".kit[1:8]" 9 3 9 3 3 3 3 - 3; - setAttr -s 9 ".kot[1:8]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 0 19 0 25 0 29 0 33 0 41 0 49 - 0 53 0 61 0; - setAttr -s 9 ".kit[1:8]" 9 3 9 3 3 3 3 - 3; - setAttr -s 9 ".kot[1:8]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 13 3.09040954 19 3.09040954 25 - 3.09040954 29 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 9 ".kit[1:8]" 9 3 9 3 3 3 3 - 3; - setAttr -s 9 ".kot[1:8]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.3867545965885748 25 4.0594933981443528; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192573708760349 25 2.2039448112088227; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821078932592165 25 -3.1435795472686916; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 21.248702102211979 25 5.8468963861459979; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 42.003958653676925 25 -28.368765378774526; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.8872598631391213 25 -28.052185257064387; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.9298872857263043 25 -4.3029039238518836; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.7882691209681596 25 2.0038703496478467; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -5.1146352835171411 25 -2.9983962363577357; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 18.943859741875197 25 42.346733523013434; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -5.4453635470246784 25 -6.9184562357428412; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 14.542605826866481 25 -1.2143143388545381; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 25 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 25 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 25 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -82.976046413383102 25 -82.082942762890042; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.144874087538099 25 -41.262114869043131; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.205809805073454 25 -27.695327781842096; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 25 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 25 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -2.5294371750177831 25 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.481673551673362 25 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.26635088939205875 25 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 240.76698806505698 25 239.50132211939308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 76.182851789542724 25 78.903278192407754; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 374.83445880576221 25 345.83232963291096; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -18.647768363316043 25 -32.458460557687573; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 36.3191443147117 25 25.207071114325792; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 107.88509288000579 25 81.364043115468817; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 23.914756983415913 25 25.521603815854018; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.717907199956898 25 -49.929606980787931; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -41.055955789443395 25 -60.904739916227172; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -71.101691509999995 25 -71.101691509999995; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 32.578198350000001 25 32.578198350000001; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -95.564448510000005 25 -95.564448510000005; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -118.97547159999999 25 -118.97547159999999; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.329382000000003 25 30.329382000000003; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -92.904446149999998 25 -92.904446149999998; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -select -ne :time1; - setAttr ".o" 13; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lloleg; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pain_chest.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_chest_on4.ma b/base/models/monsters/imp/animation/cycles/pain_chest_on4.ma deleted file mode 100644 index e870f19e6..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_chest_on4.ma +++ /dev/null @@ -1,4010 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:20 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_chest_on4.ma -//Last modified: Thu, Nov 07, 2002 02:56:38 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 83.429713910231115 34.947721337405838 199.47826475455869 ; - setAttr ".r" -type "double3" -5.7301089156246832 -2153.799999999942 9.9977103475920019e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 206.74841567216831; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 60.284816736133564 1.3769642459752021 -3.2182643071980692 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 101.55584547386937 -3.3428797739735074 119.73801778504512 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.31162123314752; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.366533543047794; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 2 -max 19 -ast 2 -aet 19 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 4 -7.5406347832540632e-013 5 -7.5406347832540632e-013 6 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 10 -7.5406347832540632e-013 11 -7.5406347832540632e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 4 13.71946295727715 5 13.71946295727715 6 13.71946295727715 9 13.71946295727715 - 10 13.71946295727715 11 13.71946295727715; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 4 -3.0908609005564358e-013 5 -3.0908609005564358e-013 6 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 10 -3.0908609005564358e-013 11 -3.0908609005564358e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 68.596496127541187 2 68.596496127541187 - 3 68.596496127541187 4 68.596496127541187 5 68.596496127541187 6 68.596496127541187 - 9 68.596496127541187 10 68.596496127541187 11 68.596496127541187; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -60.802874383230787 2 -60.802874383230787 - 3 -60.802874383230787 4 -60.802874383230787 5 -60.802874383230787 6 -60.802874383230787 - 9 -60.802874383230787 10 -60.802874383230787 11 -60.802874383230787; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -157.43468421330525 2 -157.43468421330525 - 3 -157.43468421330525 4 -157.43468421330525 5 -157.43468421330525 6 -157.43468421330525 - 9 -157.43468421330525 10 -157.43468421330525 11 -157.43468421330525; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 4 15.445123296459183 5 15.445123296459183 6 15.445123296459183 9 15.445123296459183 - 10 15.445123296459183 11 15.445123296459183; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 4 15.445123296459185 5 15.445123296459185 6 15.445123296459185 9 15.445123296459185 - 10 15.445123296459185 11 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 4 15.445123296459181 5 15.445123296459181 6 15.445123296459181 9 15.445123296459181 - 10 15.445123296459181 11 15.445123296459181; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 1 10 0 11 - 0.40000000000000002; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 3 -2.5294371750177831 - 9 -2.5294371750177831 12 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 - 19 -2.5294371750177831; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 3 13.481673551673362 - 9 13.481673551673362 12 13.481673551673362 14 13.481673551673362 17 13.481673551673362 - 19 13.481673551673362; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 3 -0.26635088939205875 - 9 -0.26635088939205875 12 -0.26635088939205875 14 -0.26635088939205875 17 - -0.26635088939205875 19 -0.26635088939205875; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 73.167297059293915 3 73.167297059293915 - 9 73.167297059293915 12 73.167297059293915 14 73.167297059293915 17 73.167297059293915 - 19 73.167297059293915; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 61.241182877125034 3 61.241182877125034 - 9 61.241182877125034 12 61.241182877125034 14 61.241182877125034 17 61.241182877125034 - 19 61.241182877125034; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 177.69376467901077 3 177.69376467901077 - 9 177.69376467901077 12 177.69376467901077 14 177.69376467901077 17 177.69376467901077 - 19 177.69376467901077; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0.5 17 0 19 - 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 0 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 1 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 59.56190462579648 2 87.086512400040135 - 3 87.086512400040135 9 87.086512400040135 10 87.086512400040135 11 89.803156191128494 - 12 90.914510469301021 13 95.359927581991059 14 106.84392178977366 16 114.45709035559202 - 19 167.43505300763536; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 6.1155384277619564 2 3.3966049353215197 - 3 3.3966049353215197 9 3.3966049353215197 10 4.3844754048082084 11 7.5950544306398937 - 12 8.2124734740690712 13 9.6942791782990856 14 11.670020117272431 16 13.774088242950418 - 19 3.1848718158837808; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -18.214943034405117 2 -18.214943034405117 - 3 -18.214943034405117 9 -18.214943034405117 10 -18.214943034405117 11 -18.214943034405117 - 12 -18.214943034405117 13 -18.214943034405117 14 -18.214943034405117 16 -18.214943034405117 - 19 -18.214943034405117; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 64.752151263719625 2 45.636324587558242 - 3 45.636324587558242 9 45.636324587558242 10 51.259142132888385 11 82.633703945066614 - 12 91.925517875523141 13 45.636324587558242 14 45.636324587558242 16 -52.350191482226066 - 19 219.80154311026268; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 54.671688625550246 2 79.910841797573497 - 3 79.910841797573497 9 79.910841797573497 10 79.910841797573482 11 79.91084179757361 - 12 79.91084179757344 13 79.910841797573497 14 79.910841797573497 16 24.766301215716588 - 19 103.06211582598448; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.46864865283559 2 3.4514964971631841 - 3 3.4514964971631841 9 3.4514964971631841 10 3.4514964971631956 11 3.4514964971632005 - 12 3.4514964971635234 13 3.4514964971631841 14 3.4514964971631841 16 -98.530493758286156 - 19 179.66289643582957; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999989 2 0.99999999999999989 - 3 0.99999999999999989 9 0.99999999999999989 10 0.99999999999999989 11 0.99999999999999989 - 12 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 16 0.99999999999999989 - 19 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 9 0.99999999999999978 10 0.99999999999999978 11 0.99999999999999978 - 12 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 16 0.99999999999999978 - 19 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.426477445851056 2 47.90393294415022 - 3 47.90393294415022 4 49.571857445849837 5 54.416924328220652 6 76.91378422815221 - 7 90.926137136631965 8 104.90238781324805 9 119.6320759386512 11 133.30969811775907 - 19 133.30969811775907; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.382959769989033 2 4.26699651607976 - 3 4.26699651607976 4 7.5234205432075498 5 8.9484432415242807 6 7.203638148018376 - 7 13.455232162483156 8 13.222439041068554 9 8.429209504871201 11 3.616514330714832 - 19 3.616514330714832; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.5906769424741469 2 5.5906769424741469 - 3 5.5906769424741469 4 5.5906769424741469 5 4.8437019572729909 6 4.7903818813050094 - 7 5.5906769424741469 8 5.5906769424741469 9 5.5906769424741469 11 5.5906769424741469 - 19 5.5906769424741469; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -213.67554625381291 2 -155.58505834761613 - 3 -155.58505834761613 4 -122.73251224871834 5 -177.7142343101996 6 -225.74849598730907 - 7 -182.20184218742966 8 -167.35620527064438 9 -185.9452684786005 11 -178.9145192530496 - 19 -178.9145192530496; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 76.0624067087263 2 77.351754812025391 - 3 77.351754812025391 4 77.351754812025504 5 78.853863033891884 6 68.745530314090416 - 7 42.231539530725335 8 52.060566701540544 9 40.693717484916455 11 77.792981530281054 - 19 77.792981530281054; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 125.96337513298413 2 168.36778920107272 - 3 168.36778920107272 4 168.3677892010729 5 89.977469223902958 6 -37.34389052151419 - 7 50.997059015191702 8 69.291367951665947 9 111.25790401441596 11 146.44536767645329 - 19 146.44536767645329; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 4 0.99999999999999978 5 0.99999999999999978 6 0.99999999999999978 - 7 0.99999999999999978 8 0.99999999999999978 9 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 2 0 3 0 5 0 9 0 13 0 17 0 19 - 0 21.392 0; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.6268319407172029 2 5.6268319407172029 - 3 5.6268319407172029 5 5.6268319407172029 9 5.6268319407172029 13 5.6268319407172029 - 17 5.6268319407172029 19 5.6268319407172029 21.392 5.6268319407172029; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1098668596606802 2 -2.1098668596606802 - 3 -2.1098668596606802 5 -2.1098668596606802 9 -2.1098668596606802 13 -2.1098668596606802 - 17 -2.1098668596606802 19 -2.1098668596606802 21.392 -2.1098668596606802; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.624 363.04706215082535 2 360.73763009723075 - 3 365.13931823930221 5 373.76063026300602 9 361.64068150857611 13 378.57221183734987 - 17 362.51014995549542 19 360.73763009723075 20.58 370.59077456904788; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1.3 1.0164485751876862 2 -0.44667534838539391 - 3 -0.86706792719803072 5 -0.44667534838539302 9 -0.44667534838539519 13 -0.44667534838539386 - 17 2.6709700285893727 19 -0.44667534838539391 21.392 -0.44667534838539391; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.92800000000000005 -14.898177256474998 - 2 -14.641906192173112 3 -9.9942319205333412 5 -14.641906192173147 9 -14.64190619217317 - 13 -14.64190619217317 17 -15.478432696593305 19 -14.641906192173112 20.428 - -10.003399928309316; - setAttr -s 9 ".kit[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".kiy[0:8]" -0.098345361649990082 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; - setAttr -s 9 ".kox[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".koy[0:8]" -0.098345354199409485 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599494 8 7.1689522478599494 - 11 7.168952247859953 12 6.3450935941379685 13 6.0198451340742674 15 7.1689522478599494 - 17 7.1689522478599494; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 11 7.9126523868203575 12 - 11.673695323026516 13 10.182893175810886 15 0.0996086992316223 17 0.0996086992316223; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.672655709095594 8 18.672655709095594 - 11 33.796945933310276 12 39.374766587856087 13 50.519161987064884 15 79.36659147624809 - 17 79.36659147624809; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -174.49049195404214 8 -174.49049195404214 - 11 -197.94003856162612 12 -209.04261896981978 13 -197.47915486936469 15 -174.49049195404214 - 17 -174.49049195404214; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 129.78625356110399 8 129.78625356110399 - 11 129.78625356110399 12 129.78625356110393 13 129.78625356110396 15 129.78625356110399 - 17 129.78625356110399; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -169.93906815090079 8 -169.93906815090079 - 11 -169.93906815090077 12 -169.93906815090071 13 -169.93906815090074 15 -169.93906815090079 - 17 -169.93906815090079; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 2 -7.3924057183505063 - 4 -7.3924057183505063 7 -7.3924057183505072 16 -7.3924057183505072 19 -7.8056900478444984 - 20 -7.3924057183505019; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 2 3.8239532939043315 4 4.0648047266548115 - 7 0 16 0 19 4.5955098521668347 20 8.7811622696593155; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 2 0.20742917859232701 - 4 13.300708001810973 7 41.567423254461779 16 41.567423254461779 19 64.205822324463625 - 20 81.566657370801593; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.229299623311356 2 -4.0235235023419671 - 4 11.229299623311356 7 11.229299623311356 16 11.229299623311356 19 -11.325478474133927 - 20 -23.884488550391008; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -47.425170065295866 2 -50.847426602078393 - 4 -47.425170065295866 7 -47.425170065295866 16 -47.425170065295866 19 -48.639053402913603 - 20 -48.184556498320411; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -15.059620758260801 2 -16.248026693665089 - 4 -15.059620758260801 7 -15.059620758260801 16 -15.059620758260801 19 -11.299337016217571 - 20 11.991848508498084; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; - setAttr -s 8 ".kot[1:7]" 5 5 5 9 9 5 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9808213950621774 2 1.9808213950621774 - 4 1.9808213950621782 8 1.9808213950621798 12 1.980821395062182 16 1.9808213950621867 - 19 1.9808213950621898 20 1.9808213950621909; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 18.41992256503119 2 17.5648042732577 - 4 19.662864340591319 8 22.465004485504792 12 16.444893931989601 16 22.519284760552775 - 19 17.522230344830156 20 17.859988542372403; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.39740898729022 2 26.732721558892088 - 4 29.466153273510063 8 45.33754183681927 12 67.170375289917047 16 83.777913253213256 - 19 96.110338887997557 20 100.30869317838135; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 67.201049905350132 2 92.493672305884772 - 4 89.380629992441925 8 80.647224957363562 12 67.201049905350132 16 67.201049905350132 - 19 67.201049905350132 20 67.201049905350132; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 -7.9513867036587959e-016 - 4 0 8 7.9513867036587909e-016 12 0 16 0 19 0 20 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.426073875550391 2 7.4260738755503892 - 4 7.4260738755503768 8 7.4260738755503892 12 7.426073875550391 16 7.426073875550391 - 19 7.426073875550391 20 7.426073875550391; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.3610577639827144 2 -0.21285352564148119 - 5.7960000000000003 3.5485029363551686 9.2360000000000007 1.3924894832037882 - 14 -3.8248141218513645 19 -0.21285352564148119 21 2.8197115728311255; - setAttr -s 7 ".kit[5:6]" 1 9; - setAttr -s 7 ".kot[5:6]" 1 9; - setAttr -s 7 ".kix[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".kiy[5:6]" 0.99956315755844116 0.999622642993927; - setAttr -s 7 ".kox[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".koy[5:6]" 0.99956315755844116 0.999622642993927; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.27858988479459218 2 0.15078676416754505 - 3 0.041071720760699121 5 -0.12734812175584798 11 0.01615418026612319 14 0.50054018883462204 - 19 0.15078676416754505 21 0.01581159374970395; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.039992513696998876 2 0.15149042747921673 - 3 0.38885909572774768 5 0.81318111183904007 11 0.47178511368290149 14 -0.68058277559896596 - 19 0.15149042747921673 21 0.6807047568788458; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 0.90991990467137285 6 0.757413731437375 - 11 0.52631001515514408 14 0.17989662655130284 16 0.11086142298673962 19 0.90991990467137285; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1.6840963091226424 6 1.9921588651806885 - 11 2.376954893450355 14 2.6063840737414372 16 2.5942005418897831 19 1.6840963091226424; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 2.8509277672757398 6 2.6074946383461919 - 11 2.2942978244046901 14 2.0606653100128796 16 2.0534195118150946 19 2.8509277672757398; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -82.189303625215842 6 -104.37729528867425 - 11 -92.006962071167038 14 -104.30491760011213 16 -98.611645848609228 19 -82.189303625215842; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 32.936642853707767 6 -8.8441659435333211 - 11 -23.718949300073728 14 -13.739625821068813 16 0.073490689192853564 19 - 32.936642853707767; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -9.2450492652573306 6 -11.190509011262176 - 11 -15.571971397215279 14 -18.399796932359234 16 -15.14081226122182 19 -9.2450492652573306; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; - setAttr -s 7 ".kot[1:6]" 5 5 5 5 5 9; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0 2 0 7 0 11 0 15 0 19 0 - 21.972000000000001 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 2.3128351505039433 2 2.3128351505039433 - 7 2.3128351505039433 11 2.3128351505039433 15 2.3128351505039433 19 2.3128351505039433 - 21.972000000000001 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0.23421866920666501 2 0.23421866920666501 - 7 0.23421866920666501 11 0.23421866920666501 15 0.23421866920666501 19 0.23421866920666501 - 21.972000000000001 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 18.015821706774922 2 7 7 - 17.885785658953552 11 7 15 17.865328849758896 19 7 21.972000000000001 17.767020748470053; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 -20.871491789318089 2 -26.903356467361473 - 7 6.6740813894110849 11 26 15 -2.3802552171770213 19 -26.903356467361473 - 21.972000000000001 -13.498742838462716; - setAttr -s 7 ".kit[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kot[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kix[2:6]" 0.31150621175765991 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".kiy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; - setAttr -s 7 ".kox[2:6]" 0.3115062415599823 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".koy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -1.3720000000000001 7.6978127730792556 - 2 15.011069830747704 7 0.81964143355547092 11 5.6889805773011233 15 1.2715285190009615 - 19 15.011069830747704 21.972000000000001 16.516055040920126; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0.27427147149852044 5 0.27427147149852044 - 8 0.27427147149852044 11 0.27427147149852044 19 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.1074984126668126 5 -1.1074984126668126 - 8 -1.1074984126668126 11 -1.1074984126668126 19 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.642626684874722 5 -1.642626684874722 - 8 -1.642626684874722 11 -1.642626684874722 19 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -72.192682186483722 5 -112.43723771647277 - 8 -140.9476176021825 11 -76.320044575450154 19 -72.192682186483722; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -0.2742786288673521 8 -0.2742786288673521 - 12 -0.2742786288673521 16 -0.2742786288673521 19 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.1075115373407667 8 -1.1075115373407667 - 12 -1.1075115373407667 16 -1.1075115373407667 19 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.6426166407301896 8 -1.6426166407301896 - 12 -1.6426166407301896 16 -1.6426166407301896 19 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 57.295779513082337 8 46.221739108863801 - 12 83.651838089100195 16 124.90479933851947 19 57.295779513082337; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 1 4 1 5 1 6 0 9 0 10 0 11 1; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 0 4 0.60000000000000009 5 1 6 - 0.30000000000000004 9 0.046875 10 0 11 0; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 1 9 1 12 1 14 0 17 0 19 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 0 9 0 12 1 14 0 17 0 19 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 8 1 12 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -66.817792973155349 8 -117.76998860514637 - 12 -58.717593899130961 19 -66.817792973155349; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -49.477141044160646 8 -45.114889989798428 - 12 -58.488201638849723 19 -49.477141044160646; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -52.341476887309149 8 -22.64196747141678 - 12 -76.449769012401859 19 -52.341476887309149; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 10 1 14 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -168.75212351198743 10 -142.34379908236403 - 14 -91.772226065525047 19 -168.75212351198743; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 44.488737867426309 10 11.646024816259962 - 14 57.8461210256567 19 44.488737867426309; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -70.747288710930945 10 -54.074322568995257 - 14 -28.519478878489718 19 -70.747288710930945; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.90858890976581275 7 -3.7621162796982501 - 14 0.3657111927859622 16 -0.5854119341237376 19 -0.90858890976581275; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 6.2382713968077237 7 5.3887456806949574 - 14 6.0204513845034606 16 5.8835786026344072 19 6.2382713968077237; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.55501859990651525 7 1.684897371141969 - 14 -0.55708239243809732 16 2.3929863357066576 19 -0.55501859990651525; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -22.350064437213423 7 -13.094561677764091 - 14 -16.423765740015508 16 -18.438399824774098 19 -22.350064437213423; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -10.303773027856268 7 6.151404343053847 - 14 8.9343731574279008 16 7.5138197933918374 19 -10.303773027856268; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 8.8115085199100047 7 22.517921127381236 - 14 29.420970529265055 16 16.267284651382163 19 8.8115085199100047; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 6.7758528420198658 16 6.7758528420198658 - 19 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9388939039072284e-018 16 - -6.9388939039072284e-018 19 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -9.5120444723942321e-016 16 - -9.5120444723942321e-016 19 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -12.784757077400341 16 -91.730384948739413 - 19 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 3.2695897469829736 16 3.2695897469829762 - 19 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9162979482121409 16 -6.9162979482121507 - 19 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0.74525677667777757 6 0.74525677667777757 - 11 0.74525677667777757 15 0.74525677667777757 19 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1.8072476834435935 6 1.8072476834435935 - 11 1.8072476834435935 15 1.8072476834435935 19 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 13.355267980117441 11 0 15 - 7.2929987411270378 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -select -ne :time1; - setAttr ".o" 3; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 88.083131913957033 -1.3620017983976201e-014 - -25.185178235689889 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; - setAttr ".r" -type "double3" -66.065354836318264 28.775852580156471 -91.471856426984459 ; - setAttr ".twi" 217.7239621497128; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_place2dTexture1.mv" "IMP_file1.mv"; -connectAttr "IMP_place2dTexture1.vt1" "IMP_file1.vt1"; -connectAttr "IMP_place2dTexture1.vt2" "IMP_file1.vt2"; -connectAttr "IMP_place2dTexture1.vt3" "IMP_file1.vt3"; -connectAttr "IMP_place2dTexture1.vc1" "IMP_file1.vc1"; -connectAttr "IMP_leg_place2dTexture1.mv" "IMP_leg_file1.mv"; -connectAttr "IMP_leg_place2dTexture1.vt1" "IMP_leg_file1.vt1"; -connectAttr "IMP_leg_place2dTexture1.vt2" "IMP_leg_file1.vt2"; -connectAttr "IMP_leg_place2dTexture1.vt3" "IMP_leg_file1.vt3"; -connectAttr "IMP_leg_place2dTexture1.vc1" "IMP_leg_file1.vc1"; -connectAttr "IMP_place2dTexture2.mv" "IMP_file2.mv"; -connectAttr "IMP_place2dTexture2.vt1" "IMP_file2.vt1"; -connectAttr "IMP_place2dTexture2.vt2" "IMP_file2.vt2"; -connectAttr "IMP_place2dTexture2.vt3" "IMP_file2.vt3"; -connectAttr "IMP_place2dTexture2.vc1" "IMP_file2.vc1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.mv" "IMP_ZOMBIE1_file1.mv"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt1" "IMP_ZOMBIE1_file1.vt1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt2" "IMP_ZOMBIE1_file1.vt2"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt3" "IMP_ZOMBIE1_file1.vt3"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vc1" "IMP_ZOMBIE1_file1.vc1"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of pain_chest_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_head.ma b/base/models/monsters/imp/animation/cycles/pain_head.ma deleted file mode 100644 index 619844a20..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_head.ma +++ /dev/null @@ -1,3788 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:17 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_head.ma -//Last modified: Mon, Mar 15, 2004 09:04:41 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 214.89453902526654 95.374490343106459 32.704068263075953 ; - setAttr ".r" -type "double3" -15.930108913467674 -280.20000000000039 8.9803183372081466e-015 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 209.80631590139211; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 22.57111845060059 55.161154620979616 4.855171589784562 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 34.105831591195802 115.73742012124887 7.6304956654842391 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 164.67624707525044; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 38.073089812497805 54.534898150352312 107.86157254419315 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.464393079493448; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 103.07551681128726 30.048199460830929 -10.456343212331282 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 123.45552071539539; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -29.548385579999998 25 -29.548385579999998 - 29 -38.367703938541368 33 -38.367703938541368; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 5.3462904040000003 25 5.3462904040000003 - 29 -22.261750778216175 33 0 53 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.3030645630000004 25 -5.3030645630000004 - 29 0 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.392405718 25 -7.392405718 - 29 -8.5228661809757718 33 -8.5228661809757842; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 25 0 29 8.6414253885234693 - 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.3620493590000002 25 -7.3620493590000002 - 29 29.058010331813129 33 55.894887262743886; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 63.314403930000005 25 63.314403930000005 41 36.237070617308525 - 49 36.237070617308518 53 36.237070617308518; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 10.10932652 25 10.10932652 41 0 49 -19.289764981099978 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 11.59016476 - 25 11.59016476 41 0 49 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 7.1689522480000001 25 7.1689522480000001 41 9.6873596619451892 - 49 9.6873596619451749 53 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 25 0 41 0 49 6.5824344037117717 53 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 -7.748575014 25 -7.748575014 41 19.750878638974889 - 49 56.871344609681749 53 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 42.810891982955745 25 41.235789590000003 29 42.252989606287457 - 33 39.474641024093501 41 35.507697111286575 49 41.757587197385924 53 38.975399081339425 - 61 36.922520121156822; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 -6.7783195950424124 25 -2.4191866630000001 29 - 35.34397057886077 33 46.128707057474401 41 48.210536281058985 49 64.065722338788731 - 53 76.398879176777299 61 80.803578047487491; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 2.4966961154840899 25 1.980821395 29 1.9932938451333648 - 33 0.5224520839187321 41 -0.96093906669208984 49 -4.8012869768196573 53 0.51611782181851806 - 61 0.81152919952064195; - setAttr -s 11 ".kit[4:10]" 3 9 3 3 3 1 3; - setAttr -s 11 ".kot[4:10]" 3 9 3 3 3 1 3; - setAttr -s 11 ".kix[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".kiy[9:10]" 0.98337632417678833 0; - setAttr -s 11 ".kox[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".koy[9:10]" 0.98337632417678833 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 9 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 0.4494172494 25 0.4494172494 28.2 6.6566912693983946 - 32.200000000000003 6.1330193887268454 40.200000000000003 0.24039650864424209 - 53 -4.1657930308134645; - setAttr -s 9 ".kit[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kix[6:8]" 0.061753064393997192 0.083855703473091125 - 1; - setAttr -s 9 ".kiy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; - setAttr -s 9 ".kox[6:8]" 0.061753060668706894 0.083855703473091125 - 1; - setAttr -s 9 ".koy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 -0.058577090280000001 25 -0.058577090280000001 28.2 - -0.86763382127902322 32.200000000000003 -0.42972806484138226 40.200000000000003 - -0.031333305538134112 53 0.54296989172209287; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 0 25 0 28.2 5.0790319675705673 32.200000000000003 - 6.7230875260072231 40.200000000000003 0 53 -7.4542171015494922; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 40.200000000000003 - 2.3128351505039433 53 2.3128351505039433; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 40.200000000000003 0.23421866920666501 53 0.23421866920666501; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581426 20.2 7.824737866480139 28.2 -0.56667192682884493 40.200000000000003 - 0.57720421748491901 53 8.7951795972581372; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 -24.30811116038322 20.2 -5.0226759171895878 28.2 13.000667896194788 40.200000000000003 - 12.790622953496632 53 13.892774724407374; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325647 - 20.2 22.77669484325164 28.2 -13.027357639203586 40.200000000000003 -8.1143097424545108 - 53 26.888910802325626; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857 19.4 398.33832420130017 25.800000000000001 405.49797585237241 - 32.200000000000003 388.93797585237292 40.200000000000003 400.28864310407283 - 53 389.49637174592857; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099 19.4 -14.641906192173103 25.800000000000001 -14.641906192173103 - 32.200000000000003 -14.641906192173099 40.200000000000003 -14.641906192173103 - 53 -14.641906192173099; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167 19.4 -0.44667534838541073 25.800000000000001 -0.4466753483854129 - 32.200000000000003 -0.44667534838541123 40.200000000000003 -0.44667534838541301 - 53 -0.44667534838541167; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 32.200000000000003 5.6268319407172029 40.200000000000003 5.6268319407172029 - 53 5.6268319407172029; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 32.200000000000003 -2.1098668596606802 40.200000000000003 -2.1098668596606802 - 53 -2.1098668596606802; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 9 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 9 9 9 9 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.600000000000001 5.7384771804188404 47 5.7384771804188404 53 5.7384771804188404; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.600000000000001 2.0494561358638701 47 2.0494561358638701 53 2.0494561358638701; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.600000000000001 0 47 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.600000000000001 16.052055400530755 47 30.358488909126763 53 37.874152024707215; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.600000000000001 11.52461344822842 47 -2.1187003779812748 53 -14.364226384227051; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.600000000000001 -25.97088988767895 47 -26.687875434482198 53 -36.863333637497242; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 11.4 1 13 1 25 1 32.200000000000003 - 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 11.4 1 13 1 25 1 32.200000000000003 - 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 11.4 1 13 1 25 1 32.200000000000003 - 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -8.5828185196333049 25 -14.840217421411868 32.200000000000003 - -15.091352590275802 40.200000000000003 -24.981217127315897 53 -16.777720747043478; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 22.698539612789109 25 16.509687863537451 32.200000000000003 - 5.460283656526733 40.200000000000003 3.555911204482308 53 5.3449549069799076; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -31.832189282578572 25 -17.89538038991634 32.200000000000003 - -19.683531133663919 40.200000000000003 -11.295059140243522 53 -16.48879266455566; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 25 2.6456615572060826 32.200000000000003 - 2.6456615572060826 40.200000000000003 2.6456615572060826 53 2.6456615572060826; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 25 1.9935618776130362 32.200000000000003 - 1.9935618776130362 40.200000000000003 1.9935618776130362 53 1.9935618776130362; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 11.4 0 13 0 25 0 32.200000000000003 - 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 11.4 1 13 1 25 1 32.200000000000003 - 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 12.412879749935719 13 12.412879749935719 - 25 12.412879749935719 34.6 12.412879749935719 40.200000000000003 12.412879749935719 - 53 12.412879749935719; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7286993982861674 13 -6.7286993982861674 - 25 -6.7286993982861674 34.6 -6.7286993982861674 40.200000000000003 -6.7286993982861674 - 53 -6.7286993982861674; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.868763862603668 13 -3.868763862603668 - 25 -3.868763862603668 34.6 -3.868763862603668 40.200000000000003 -3.868763862603668 - 53 -3.868763862603668; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 80.239686562403847 13 50.689203411885629 - 25 103.41622835125608 34.6 94.762662499017765 40.200000000000003 87.603010847945214 - 53 105.11870283856432; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.8978517871634404 13 0.21742569259672087 - 25 0 34.6 0 40.200000000000003 0 53 0.21742569259672076; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.92545182592768849 13 0.034116996666525151 - 25 0 34.6 0 40.200000000000003 0 53 0.034116996666525033; - setAttr -s 6 ".kit[1:5]" 3 9 9 9 3; - setAttr -s 6 ".kot[1:5]" 3 9 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 25 -12.41287000000041 27.4 -12.41287000000041 40.200000000000003 - -12.41287000000041 53 -12.41287000000041; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 25 -6.7285999999993047 27.4 -6.7285999999993047 40.200000000000003 - -6.7285999999993047 53 -6.7285999999993047; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 25 -3.8687599999999316 27.4 -3.8687599999999316 40.200000000000003 - -3.8687599999999316 53 -3.8687599999999316; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.099612817676174 10.6 82.316033184538099 - 13 16.616014164358148 25 92.144105348206509 27.4 63.019898856647714 40.200000000000003 - 82.099898856647854 53 81.577924579716537; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 25 -ast 13 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 25 0 29 0 33 0 41 0 49 0 53 - 0 61 0; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 25 0 29 0 33 0 41 0 49 0 53 - 0 61 0; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 3.09040954 25 3.09040954 29 - 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.3867545965885748 25 4.0594933981443528; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192573708760349 25 2.2039448112088227; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821078932592165 25 -3.1435795472686916; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -22.544413261769744 25 5.8468963861459979; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 6.4088981628514183 25 -28.368765378774526; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -11.822514651798571 25 -28.052185257064387; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.3867499999998705 25 -4.3029039238518836; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192000000001707 25 2.0038703496478467; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821100000000254 25 -2.9983962363577357; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 17.910482139718681 25 42.346733523013434; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -14.515639402999367 25 -6.9184562357428412; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 11.938427127869016 25 -1.2143143388545381; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 25 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 25 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 25 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -82.976046413383102 25 -82.082942762890042; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.144874087538099 25 -41.262114869043131; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.205809805073454 25 -27.695327781842096; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 25 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 25 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -2.5294371750177831 25 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.481673551673362 25 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.26635088939205875 25 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 240.76698806505698 25 239.50132211939308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 76.182851789542724 25 78.903278192407754; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 374.83445880576221 25 345.83232963291096; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -18.647768363316043 25 -32.458460557687573; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 36.3191443147117 25 25.207071114325792; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 107.88509288000579 25 81.364043115468817; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 23.914756983415913 25 25.521603815854018; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.717907199956898 25 -49.929606980787931; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -41.055955789443395 25 -60.904739916227172; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -118.97547159999999 25 -118.97547159999999; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.329382000000003 25 30.329382000000003; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -92.904446149999998 25 -92.904446149999998; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -71.101691509999995 25 -71.101691509999995; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 32.578198350000001 25 32.578198350000001; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -95.564448510000005 25 -95.564448510000005; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -select -ne :time1; - setAttr ".o" 13; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lloleg; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rwing3; - setAttr ".r" -type "double3" 33.805899850653965 26.272866888105089 92.702463214576383 ; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr -av ".rz"; -select -ne IMP_Rwing4; - setAttr ".r" -type "double3" 108.20197775459526 -16.834522544392435 81.977625287425354 ; - setAttr -av ".rx"; - setAttr -av ".ry"; - setAttr -av ".rz"; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pain_head.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_head_on4.ma b/base/models/monsters/imp/animation/cycles/pain_head_on4.ma deleted file mode 100644 index a047f221e..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_head_on4.ma +++ /dev/null @@ -1,4019 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:22 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_head_on4.ma -//Last modified: Thu, Nov 07, 2002 02:47:12 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 245.68986760427191 17.15049376524609 23.777670855812993 ; - setAttr ".r" -type "double3" 6.8698910840245553 -2080.1999999996096 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 159.57083740814585; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 89.768508610957127 36.23757999745456 -4.2770096802075024 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 101.55584547386937 -3.3428797739735074 119.73801778504512 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.31162123314752; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.366533543047794; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 2 -max 19 -ast 2 -aet 19 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 4 -7.5406347832540632e-013 5 -7.5406347832540632e-013 6 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 10 -7.5406347832540632e-013 11 -7.5406347832540632e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 4 13.71946295727715 5 13.71946295727715 6 13.71946295727715 9 13.71946295727715 - 10 13.71946295727715 11 13.71946295727715; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 4 -3.0908609005564358e-013 5 -3.0908609005564358e-013 6 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 10 -3.0908609005564358e-013 11 -3.0908609005564358e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 68.596496127541187 2 68.596496127541187 - 3 68.596496127541187 4 68.596496127541187 5 68.596496127541187 6 68.596496127541187 - 9 68.596496127541187 10 68.596496127541187 11 68.596496127541187; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -60.802874383230787 2 -60.802874383230787 - 3 -60.802874383230787 4 -60.802874383230787 5 -60.802874383230787 6 -60.802874383230787 - 9 -60.802874383230787 10 -60.802874383230787 11 -60.802874383230787; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -157.43468421330525 2 -157.43468421330525 - 3 -157.43468421330525 4 -157.43468421330525 5 -157.43468421330525 6 -157.43468421330525 - 9 -157.43468421330525 10 -157.43468421330525 11 -157.43468421330525; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 4 15.445123296459183 5 15.445123296459183 6 15.445123296459183 9 15.445123296459183 - 10 15.445123296459183 11 15.445123296459183; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 4 15.445123296459185 5 15.445123296459185 6 15.445123296459185 9 15.445123296459185 - 10 15.445123296459185 11 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 4 15.445123296459181 5 15.445123296459181 6 15.445123296459181 9 15.445123296459181 - 10 15.445123296459181 11 15.445123296459181; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 1 10 0 11 - 0.40000000000000002; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 3 -2.5294371750177831 - 9 -2.5294371750177831 12 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 - 19 -2.5294371750177831; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 3 13.481673551673362 - 9 13.481673551673362 12 13.481673551673362 14 13.481673551673362 17 13.481673551673362 - 19 13.481673551673362; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 3 -0.26635088939205875 - 9 -0.26635088939205875 12 -0.26635088939205875 14 -0.26635088939205875 17 - -0.26635088939205875 19 -0.26635088939205875; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 73.167297059293915 3 73.167297059293915 - 9 73.167297059293915 12 73.167297059293915 14 73.167297059293915 17 73.167297059293915 - 19 73.167297059293915; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 61.241182877125034 3 61.241182877125034 - 9 61.241182877125034 12 61.241182877125034 14 61.241182877125034 17 61.241182877125034 - 19 61.241182877125034; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 177.69376467901077 3 177.69376467901077 - 9 177.69376467901077 12 177.69376467901077 14 177.69376467901077 17 177.69376467901077 - 19 177.69376467901077; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0.5 17 0 19 - 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 0 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 1 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 59.56190462579648 2 87.086512400040135 - 3 87.086512400040135 9 87.086512400040135 10 87.086512400040135 11 89.803156191128494 - 12 90.914510469301021 13 95.359927581991059 14 106.84392178977366 16 114.45709035559202 - 19 167.43505300763536; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 6.1155384277619564 2 3.3966049353215197 - 3 3.3966049353215197 9 3.3966049353215197 10 4.3844754048082084 11 7.5950544306398937 - 12 8.2124734740690712 13 9.6942791782990856 14 11.670020117272431 16 13.774088242950418 - 19 3.1848718158837808; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -18.214943034405117 2 -18.214943034405117 - 3 -18.214943034405117 9 -18.214943034405117 10 -18.214943034405117 11 -18.214943034405117 - 12 -18.214943034405117 13 -18.214943034405117 14 -18.214943034405117 16 -18.214943034405117 - 19 -18.214943034405117; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 64.752151263719625 2 45.636324587558242 - 3 45.636324587558242 9 45.636324587558242 10 51.259142132888385 11 82.633703945066614 - 12 91.925517875523141 13 45.636324587558242 14 45.636324587558242 16 -52.350191482226066 - 19 219.80154311026268; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 54.671688625550246 2 79.910841797573497 - 3 79.910841797573497 9 79.910841797573497 10 79.910841797573482 11 79.91084179757361 - 12 79.91084179757344 13 79.910841797573497 14 79.910841797573497 16 24.766301215716588 - 19 103.06211582598448; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.46864865283559 2 3.4514964971631841 - 3 3.4514964971631841 9 3.4514964971631841 10 3.4514964971631956 11 3.4514964971632005 - 12 3.4514964971635234 13 3.4514964971631841 14 3.4514964971631841 16 -98.530493758286156 - 19 179.66289643582957; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999989 2 0.99999999999999989 - 3 0.99999999999999989 9 0.99999999999999989 10 0.99999999999999989 11 0.99999999999999989 - 12 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 16 0.99999999999999989 - 19 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 9 0.99999999999999978 10 0.99999999999999978 11 0.99999999999999978 - 12 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 16 0.99999999999999978 - 19 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.426477445851056 2 47.90393294415022 - 3 47.90393294415022 4 49.571857445849837 5 54.416924328220652 6 76.91378422815221 - 7 90.926137136631965 8 104.90238781324805 9 119.6320759386512 11 133.30969811775907 - 19 133.30969811775907; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.382959769989033 2 4.26699651607976 - 3 4.26699651607976 4 7.5234205432075498 5 8.9484432415242807 6 7.203638148018376 - 7 13.455232162483156 8 13.222439041068554 9 8.429209504871201 11 3.616514330714832 - 19 3.616514330714832; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.5906769424741469 2 5.5906769424741469 - 3 5.5906769424741469 4 5.5906769424741469 5 4.8437019572729909 6 4.7903818813050094 - 7 5.5906769424741469 8 5.5906769424741469 9 5.5906769424741469 11 5.5906769424741469 - 19 5.5906769424741469; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -213.67554625381291 2 -155.58505834761613 - 3 -155.58505834761613 4 -122.73251224871834 5 -177.7142343101996 6 -225.74849598730907 - 7 -182.20184218742966 8 -167.35620527064438 9 -185.9452684786005 11 -178.9145192530496 - 19 -178.9145192530496; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 76.0624067087263 2 77.351754812025391 - 3 77.351754812025391 4 77.351754812025504 5 78.853863033891884 6 68.745530314090416 - 7 42.231539530725335 8 52.060566701540544 9 40.693717484916455 11 77.792981530281054 - 19 77.792981530281054; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 125.96337513298413 2 168.36778920107272 - 3 168.36778920107272 4 168.3677892010729 5 89.977469223902958 6 -37.34389052151419 - 7 50.997059015191702 8 69.291367951665947 9 111.25790401441596 11 146.44536767645329 - 19 146.44536767645329; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 4 0.99999999999999978 5 0.99999999999999978 6 0.99999999999999978 - 7 0.99999999999999978 8 0.99999999999999978 9 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 2 0 3 0 5 0 9 0 13 0 17 0 19 - 0 21.392 0; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.6268319407172029 2 5.6268319407172029 - 3 5.6268319407172029 5 5.6268319407172029 9 5.6268319407172029 13 5.6268319407172029 - 17 5.6268319407172029 19 5.6268319407172029 21.392 5.6268319407172029; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1098668596606802 2 -2.1098668596606802 - 3 -2.1098668596606802 5 -2.1098668596606802 9 -2.1098668596606802 13 -2.1098668596606802 - 17 -2.1098668596606802 19 -2.1098668596606802 21.392 -2.1098668596606802; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.624 363.04706215082535 2 342.13999836944492 - 3 343.18215574923147 5 335.3429872572521 9 361.64068150857611 13 378.57221183734987 - 17 362.51014995549542 19 360.73763009723075 20.58 370.59077456904788; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1.3 1.0164485751876862 2 -0.44667534838539552 - 3 -0.86706792719803427 5 -0.44667534838539286 9 -0.44667534838539519 13 -0.44667534838539386 - 17 2.6709700285893727 19 -0.44667534838539391 21.392 -0.44667534838539391; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.92800000000000005 -14.898177256474998 - 2 -14.641906192173094 3 -9.9942319205333483 5 -14.641906192173154 9 -14.64190619217317 - 13 -14.64190619217317 17 -15.478432696593305 19 -14.641906192173112 20.428 - -10.003399928309316; - setAttr -s 9 ".kit[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".kiy[0:8]" -0.098345361649990082 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; - setAttr -s 9 ".kox[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".koy[0:8]" -0.098345354199409485 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599494 8 7.1689522478599494 - 11 7.168952247859953 12 6.3450935941379685 13 6.0198451340742674 15 7.1689522478599494 - 17 7.1689522478599494; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 11 7.9126523868203575 12 - 11.673695323026516 13 10.182893175810886 15 0.0996086992316223 17 0.0996086992316223; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.672655709095594 8 18.672655709095594 - 11 33.796945933310276 12 39.374766587856087 13 50.519161987064884 15 79.36659147624809 - 17 79.36659147624809; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -174.49049195404214 8 -174.49049195404214 - 11 -197.94003856162612 12 -209.04261896981978 13 -197.47915486936469 15 -174.49049195404214 - 17 -174.49049195404214; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 129.78625356110399 8 129.78625356110399 - 11 129.78625356110399 12 129.78625356110393 13 129.78625356110396 15 129.78625356110399 - 17 129.78625356110399; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -169.93906815090079 8 -169.93906815090079 - 11 -169.93906815090077 12 -169.93906815090071 13 -169.93906815090074 15 -169.93906815090079 - 17 -169.93906815090079; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 2 -7.3924057183505063 - 4 -7.3924057183505063 7 -7.3924057183505072 16 -7.3924057183505072 19 -7.8056900478444984 - 20 -7.3924057183505019; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 2 3.8239532939043315 4 4.0648047266548115 - 7 0 16 0 19 4.5955098521668347 20 8.7811622696593155; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 2 0.20742917859232701 - 4 13.300708001810973 7 41.567423254461779 16 41.567423254461779 19 64.205822324463625 - 20 81.566657370801593; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.229299623311356 2 -4.0235235023419671 - 4 11.229299623311356 7 11.229299623311356 16 11.229299623311356 19 -11.325478474133927 - 20 -23.884488550391008; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -47.425170065295866 2 -50.847426602078393 - 4 -47.425170065295866 7 -47.425170065295866 16 -47.425170065295866 19 -48.639053402913603 - 20 -48.184556498320411; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -15.059620758260801 2 -16.248026693665089 - 4 -15.059620758260801 7 -15.059620758260801 16 -15.059620758260801 19 -11.299337016217571 - 20 11.991848508498084; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; - setAttr -s 8 ".kot[1:7]" 5 5 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9808213950621774 2 2.2713148145891573 - 4 2.2013945633919945 8 1.9808213950621805 12 1.980821395062182 16 1.9808213950621867 - 19 1.9808213950621898 20 1.9808213950621909; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 18.41992256503119 2 16.19303949088323 - 4 18.393082895031409 8 22.465004485504792 12 16.444893931989601 16 22.519284760552775 - 19 17.522230344830156 20 17.859988542372403; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.39740898729022 2 34.250172753837418 - 4 39.184293756209037 8 52.050851690712953 12 67.170375289917047 16 83.777913253213256 - 19 96.110338887997557 20 100.30869317838135; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 67.201049905350132 2 61.499715108539476 - 4 62.209110964312558 8 67.201049905350132 12 67.201049905350132 16 67.201049905350132 - 19 67.201049905350132 20 67.201049905350132; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 4 3.975693351829396e-016 - 8 0 12 0 16 0 19 0 20 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.426073875550391 2 7.4260738755503892 - 4 7.4260738755503892 8 7.426073875550391 12 7.426073875550391 16 7.426073875550391 - 19 7.426073875550391 20 7.426073875550391; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.3610577639827144 2 -0.21285352564148119 - 5.7960000000000003 3.5485029363551686 9.2360000000000007 1.3924894832037882 - 14 -3.8248141218513645 19 -0.21285352564148119 21 2.8197115728311255; - setAttr -s 7 ".kit[5:6]" 1 9; - setAttr -s 7 ".kot[5:6]" 1 9; - setAttr -s 7 ".kix[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".kiy[5:6]" 0.99956315755844116 0.999622642993927; - setAttr -s 7 ".kox[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".koy[5:6]" 0.99956315755844116 0.999622642993927; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.27858988479459218 2 0.15078676416754505 - 3 0.041071720760699121 5 -0.12734812175584798 11 0.01615418026612319 14 0.50054018883462204 - 19 0.15078676416754505 21 0.01581159374970395; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.039992513696998876 2 0.15149042747921673 - 3 0.38885909572774768 5 0.81318111183904007 11 0.47178511368290149 14 -0.68058277559896596 - 19 0.15149042747921673 21 0.6807047568788458; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 0.90991990467137285 6 0.757413731437375 - 11 0.52631001515514408 14 0.17989662655130284 16 0.11086142298673962 19 0.90991990467137285; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1.6840963091226424 6 1.9921588651806885 - 11 2.376954893450355 14 2.6063840737414372 16 2.5942005418897831 19 1.6840963091226424; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 2.8509277672757398 6 2.6074946383461919 - 11 2.2942978244046901 14 2.0606653100128796 16 2.0534195118150946 19 2.8509277672757398; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -82.189303625215842 6 -128.33525880719549 - 11 -92.006962071167038 14 -104.30491760011213 16 -98.611645848609228 19 -82.189303625215842; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 32.936642853707767 6 15.938368647014006 - 11 -23.718949300073728 14 -13.739625821068813 16 0.073490689192853564 19 - 32.936642853707767; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -9.2450492652573306 6 -7.4045268902071761 - 11 -15.571971397215279 14 -18.399796932359234 16 -15.14081226122182 19 -9.2450492652573306; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; - setAttr -s 7 ".kot[1:6]" 5 5 5 5 5 9; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0 2 0 7 0 11 0 15 0 19 0 - 21.972000000000001 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 2.3128351505039433 2 2.3128351505039433 - 7 2.3128351505039433 11 2.3128351505039433 15 2.3128351505039433 19 2.3128351505039433 - 21.972000000000001 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0.23421866920666501 2 0.23421866920666501 - 7 0.23421866920666501 11 0.23421866920666501 15 0.23421866920666501 19 0.23421866920666501 - 21.972000000000001 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 18.015821706774922 2 7 7 - 17.885785658953552 11 7 15 17.865328849758896 19 7 21.972000000000001 17.767020748470053; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 -20.871491789318089 2 -26.903356467361473 - 7 6.6740813894110849 11 26 15 -2.3802552171770213 19 -26.903356467361473 - 21.972000000000001 -13.498742838462716; - setAttr -s 7 ".kit[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kot[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kix[2:6]" 0.31150621175765991 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".kiy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; - setAttr -s 7 ".kox[2:6]" 0.3115062415599823 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".koy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -1.3720000000000001 7.6978127730792556 - 2 15.011069830747704 7 0.81964143355547092 11 5.6889805773011233 15 1.2715285190009615 - 19 15.011069830747704 21.972000000000001 16.516055040920126; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0.27427147149852044 5 0.27427147149852044 - 8 0.27427147149852044 11 0.27427147149852044 19 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.1074984126668126 5 -1.1074984126668126 - 8 -1.1074984126668126 11 -1.1074984126668126 19 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.642626684874722 5 -1.642626684874722 - 8 -1.642626684874722 11 -1.642626684874722 19 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -72.192682186483722 5 -112.43723771647277 - 8 -140.9476176021825 11 -76.320044575450154 19 -72.192682186483722; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -0.2742786288673521 8 -0.2742786288673521 - 12 -0.2742786288673521 16 -0.2742786288673521 19 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.1075115373407667 8 -1.1075115373407667 - 12 -1.1075115373407667 16 -1.1075115373407667 19 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.6426166407301896 8 -1.6426166407301896 - 12 -1.6426166407301896 16 -1.6426166407301896 19 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 57.295779513082337 8 46.221739108863801 - 12 83.651838089100195 16 124.90479933851947 19 57.295779513082337; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 1 4 1 5 1 6 0 9 0 10 0 11 1; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 0 4 0.60000000000000009 5 1 6 - 0.30000000000000004 9 0.046875 10 0 11 0; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 1 9 1 12 1 14 0 17 0 19 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 0 9 0 12 1 14 0 17 0 19 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 8 1 12 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -66.817792973155349 8 -117.76998860514637 - 12 -58.717593899130961 19 -66.817792973155349; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -49.477141044160646 8 -45.114889989798428 - 12 -58.488201638849723 19 -49.477141044160646; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -52.341476887309149 8 -22.64196747141678 - 12 -76.449769012401859 19 -52.341476887309149; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 10 1 14 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -168.75212351198743 10 -142.34379908236403 - 14 -91.772226065525047 19 -168.75212351198743; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 44.488737867426309 10 11.646024816259962 - 14 57.8461210256567 19 44.488737867426309; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -70.747288710930945 10 -54.074322568995257 - 14 -28.519478878489718 19 -70.747288710930945; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.4652805254022965 7 -2.2959283785819204 - 14 0.3657111927859622 16 -0.5854119341237376 19 -0.90858890976581275; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 7.1549044207944554 7 9.5726348221023336 - 14 6.0204513845034606 16 5.8835786026344072 19 6.2382713968077237; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -2.3114637506173104 7 -3.3847373373767704 - 14 -0.55708239243809732 16 2.3929863357066576 19 -0.55501859990651525; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -36.223797113372278 7 -13.094561677764091 - 14 -16.423765740015508 16 -18.438399824774098 19 -22.350064437213423; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -10.303773027856327 7 6.151404343053847 - 14 8.9343731574279008 16 7.5138197933918374 19 -10.303773027856268; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 8.8115085199100385 7 22.517921127381236 - 14 29.420970529265055 16 16.267284651382163 19 8.8115085199100047; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 6.7758528420198658 16 6.7758528420198658 - 19 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9388939039072284e-018 16 - -6.9388939039072284e-018 19 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -9.5120444723942321e-016 16 - -9.5120444723942321e-016 19 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -12.784757077400341 16 -91.730384948739413 - 19 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 3.2695897469829736 16 3.2695897469829762 - 19 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9162979482121409 16 -6.9162979482121507 - 19 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0.74525677667777757 6 0.74525677667777757 - 11 0.74525677667777757 15 0.74525677667777757 19 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1.8072476834435935 6 1.8072476834435935 - 11 1.8072476834435935 15 1.8072476834435935 19 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 13.355267980117441 11 0 15 - 7.2929987411270378 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -select -ne :time1; - setAttr ".o" 18; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Neck; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 39.949705779916087 -6.1772975069565881e-015 - -11.422623590557539 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; - setAttr ".r" -type "double3" -66.065354836318264 28.775852580156471 -91.471856426984459 ; - setAttr ".twi" 217.7239621497128; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_place2dTexture1.mv" "IMP_file1.mv"; -connectAttr "IMP_place2dTexture1.vt1" "IMP_file1.vt1"; -connectAttr "IMP_place2dTexture1.vt2" "IMP_file1.vt2"; -connectAttr "IMP_place2dTexture1.vt3" "IMP_file1.vt3"; -connectAttr "IMP_place2dTexture1.vc1" "IMP_file1.vc1"; -connectAttr "IMP_leg_place2dTexture1.mv" "IMP_leg_file1.mv"; -connectAttr "IMP_leg_place2dTexture1.vt1" "IMP_leg_file1.vt1"; -connectAttr "IMP_leg_place2dTexture1.vt2" "IMP_leg_file1.vt2"; -connectAttr "IMP_leg_place2dTexture1.vt3" "IMP_leg_file1.vt3"; -connectAttr "IMP_leg_place2dTexture1.vc1" "IMP_leg_file1.vc1"; -connectAttr "IMP_place2dTexture2.mv" "IMP_file2.mv"; -connectAttr "IMP_place2dTexture2.vt1" "IMP_file2.vt1"; -connectAttr "IMP_place2dTexture2.vt2" "IMP_file2.vt2"; -connectAttr "IMP_place2dTexture2.vt3" "IMP_file2.vt3"; -connectAttr "IMP_place2dTexture2.vc1" "IMP_file2.vc1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.mv" "IMP_ZOMBIE1_file1.mv"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt1" "IMP_ZOMBIE1_file1.vt1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt2" "IMP_ZOMBIE1_file1.vt2"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt3" "IMP_ZOMBIE1_file1.vt3"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vc1" "IMP_ZOMBIE1_file1.vc1"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of pain_head_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_luparm.ma b/base/models/monsters/imp/animation/cycles/pain_luparm.ma deleted file mode 100644 index e893b4d6b..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_luparm.ma +++ /dev/null @@ -1,3783 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:18 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_luparm.ma -//Last modified: Mon, Mar 15, 2004 09:04:58 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 310.56902975408008 19.245527335182775 12.455586786649235 ; - setAttr ".r" -type "double3" 6.2698910864453623 -632.99999999997283 1.5192971093946156e-014 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 304.85102710415231; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 22.57111845060059 55.161154620979616 4.855171589784562 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 34.105831591195802 115.73742012124887 7.6304956654842391 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 164.67624707525044; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 38.073089812497805 54.534898150352312 107.86157254419315 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.464393079493448; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 103.07551681128726 30.048199460830929 -10.456343212331282 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 123.45552071539539; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -29.548385579999998 25 -29.548385579999998 - 29 -38.367703938541368 33 -38.367703938541368; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 5.3462904040000003 25 5.3462904040000003 - 29 -22.261750778216175 33 0 53 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.3030645630000004 25 -5.3030645630000004 - 29 0 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.392405718 25 -7.392405718 - 29 -8.5228661809757718 33 -8.5228661809757842; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 25 0 29 8.6414253885234693 - 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.3620493590000002 25 -7.3620493590000002 - 29 29.058010331813129 33 55.894887262743886; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 63.314403930000005 25 63.314403930000005 41 36.237070617308525 - 49 36.237070617308518 53 36.237070617308518; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 10.10932652 25 10.10932652 41 0 49 -19.289764981099978 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 11.59016476 - 25 11.59016476 41 0 49 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 7.1689522480000001 25 7.1689522480000001 41 9.6873596619451892 - 49 9.6873596619451749 53 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 25 0 41 0 49 6.5824344037117717 53 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 -7.748575014 25 -7.748575014 41 19.750878638974889 - 49 56.871344609681749 53 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 44.78293200785356 25 41.235789590000003 29 42.252989606287457 - 33 39.474641024093501 41 35.507697111286575 49 41.757587197385924 53 38.975399081339425 - 61 36.922520121156822; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 -8.825745186370666 25 -2.4191866630000001 29 35.34397057886077 - 33 46.128707057474401 41 48.210536281058985 49 64.065722338788731 53 76.398879176777299 - 61 80.803578047487491; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 1.8688025629239517 25 1.980821395 29 1.9932938451333648 - 33 0.5224520839187321 41 -0.96093906669208984 49 -4.8012869768196573 53 0.51611782181851806 - 61 0.81152919952064195; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kix[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".kiy[9:10]" 0.98337632417678833 0; - setAttr -s 11 ".kox[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".koy[9:10]" 0.98337632417678833 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 0.4494172494 25 0.4494172494 28.2 6.6566912693983946 - 32.200000000000003 6.1330193887268454 40.200000000000003 0.24039650864424209 - 53 -4.1657930308134645; - setAttr -s 9 ".kit[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kix[6:8]" 0.061753064393997192 0.083855703473091125 - 1; - setAttr -s 9 ".kiy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; - setAttr -s 9 ".kox[6:8]" 0.061753060668706894 0.083855703473091125 - 1; - setAttr -s 9 ".koy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 -0.058577090280000001 25 -0.058577090280000001 28.2 - -0.86763382127902322 32.200000000000003 -0.42972806484138226 40.200000000000003 - -0.031333305538134112 53 0.54296989172209287; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 0 25 0 28.2 5.0790319675705673 32.200000000000003 - 6.7230875260072231 40.200000000000003 0 53 -7.4542171015494922; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 40.200000000000003 - 2.3128351505039433 53 2.3128351505039433; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 40.200000000000003 0.23421866920666501 53 0.23421866920666501; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581426 20.2 7.824737866480139 28.2 -0.56667192682884493 40.200000000000003 - 0.57720421748491901 53 8.7951795972581372; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 -24.30811116038322 20.2 -5.0226759171895878 28.2 13.000667896194788 40.200000000000003 - 12.790622953496632 53 13.892774724407374; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325647 - 20.2 22.77669484325164 28.2 -13.027357639203586 40.200000000000003 -8.1143097424545108 - 53 26.888910802325626; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 343.1695050242169 19.4 398.33832420130017 25.800000000000001 405.49797585237241 - 32.200000000000003 388.93797585237292 40.200000000000003 400.28864310407283 - 53 389.49637174592857; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -9.7440880834617651 19.4 -14.641906192173103 25.800000000000001 -14.641906192173103 - 32.200000000000003 -14.641906192173099 40.200000000000003 -14.641906192173103 - 53 -14.641906192173099; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 2.1752330352387825 19.4 -0.44667534838541073 25.800000000000001 -0.4466753483854129 - 32.200000000000003 -0.44667534838541123 40.200000000000003 -0.44667534838541301 - 53 -0.44667534838541167; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 32.200000000000003 5.6268319407172029 40.200000000000003 5.6268319407172029 - 53 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 32.200000000000003 -2.1098668596606802 40.200000000000003 -2.1098668596606802 - 53 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.600000000000001 5.7384771804188404 47 5.7384771804188404 53 5.7384771804188404; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.600000000000001 2.0494561358638701 47 2.0494561358638701 53 2.0494561358638701; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.600000000000001 0 47 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.600000000000001 16.052055400530755 47 30.358488909126763 53 37.874152024707215; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.600000000000001 11.52461344822842 47 -2.1187003779812748 53 -14.364226384227051; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.600000000000001 -25.97088988767895 47 -26.687875434482198 53 -36.863333637497242; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 4.2330399930741924 15 -11.340398697750635 18 - -24.598006495389306 25 -14.840217421411868 32.200000000000003 -15.091352590275802 - 40.200000000000003 -24.981217127315897 53 -16.777720747043478; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 50.780790677232417 15 31.281930439752845 18 48.15826652499068 - 25 16.509687863537451 32.200000000000003 5.460283656526733 40.200000000000003 - 3.555911204482308 53 5.3449549069799076; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 40.298833138656228 15 14.363880496065407 18 -33.408635312787865 - 25 -17.89538038991634 32.200000000000003 -19.683531133663919 40.200000000000003 - -11.295059140243522 53 -16.48879266455566; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 15 2.6456615572060826 18 2.6456615572060826 - 25 2.6456615572060826 32.200000000000003 2.6456615572060826 40.200000000000003 - 2.6456615572060826 53 2.6456615572060826; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 15 1.9935618776130362 18 1.9935618776130362 - 25 1.9935618776130362 32.200000000000003 1.9935618776130362 40.200000000000003 - 1.9935618776130362 53 1.9935618776130362; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 11.4 0 13 0 15 0 18 0 - 25 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 13 12.412879749935719 - 20 12.412879749935719 25 12.412879749935719 34.6 12.412879749935719 40.200000000000003 - 12.412879749935719 53 12.412879749935719; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 13 -6.7286993982861674 - 20 -6.7286993982861674 25 -6.7286993982861674 34.6 -6.7286993982861674 40.200000000000003 - -6.7286993982861674 53 -6.7286993982861674; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 13 -3.868763862603668 - 20 -3.868763862603668 25 -3.868763862603668 34.6 -3.868763862603668 40.200000000000003 - -3.868763862603668 53 -3.868763862603668; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 80.239686562403847 13 -10.549773912168689 - 20 92.401590058023146 25 103.41622835125608 34.6 94.762662499017765 40.200000000000003 - 87.603010847945214 53 105.11870283856432; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.8978517871634404 13 0.21742569259672162 - 20 0.098912473866345871 25 0 34.6 0 40.200000000000003 0 53 0.21742569259672076; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.92545182592768849 13 0.034116996666525491 - 20 0.015520688835634049 25 0 34.6 0 40.200000000000003 0 53 0.034116996666525033; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 25 -12.41287000000041 27.4 -12.41287000000041 40.200000000000003 - -12.41287000000041 53 -12.41287000000041; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 25 -6.7285999999993047 27.4 -6.7285999999993047 40.200000000000003 - -6.7285999999993047 53 -6.7285999999993047; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 25 -3.8687599999999316 27.4 -3.8687599999999316 40.200000000000003 - -3.8687599999999316 53 -3.8687599999999316; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.099612817676174 10.6 82.316033184538099 - 13 56.675828465321835 25 92.144105348206509 27.4 63.019898856647714 40.200000000000003 - 82.099898856647854 53 81.577924579716537; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 25 -ast 13 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 -6.5976010060140409 25 0 29 - 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 27.91216014618217 25 0 29 0 - 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 -14.130286704716584 25 3.09040954 - 29 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.3867545965885748 25 4.0594933981443528; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192573708760349 25 2.2039448112088227; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821078932592165 25 -3.1435795472686916; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.176544157041736 25 5.8468963861459979; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -11.554061359738578 25 -28.368765378774526; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -8.1144849336106368 25 -28.052185257064387; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.9298872857263043 25 -4.3029039238518836; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.7882691209681596 25 2.0038703496478467; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -5.1146352835171411 25 -2.9983962363577357; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -12.077870952939543 25 42.346733523013434; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.555097654470636 25 -6.9184562357428412; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.60874214957099237 25 -1.2143143388545381; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 25 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 25 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 25 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -82.976046413383102 25 -82.082942762890042; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.144874087538099 25 -41.262114869043131; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.205809805073454 25 -27.695327781842096; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 25 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 25 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -2.5294371750177831 25 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.481673551673362 25 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.26635088939205875 25 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 240.76698806505698 25 239.50132211939308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 76.182851789542724 25 78.903278192407754; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 374.83445880576221 25 345.83232963291096; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -18.647768363316043 25 -32.458460557687573; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 36.3191443147117 25 25.207071114325792; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 107.88509288000579 25 81.364043115468817; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 23.914756983415913 25 25.521603815854018; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.717907199956898 25 -49.929606980787931; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -41.055955789443395 25 -60.904739916227172; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -118.97547159999999 25 -118.97547159999999; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.329382000000003 25 30.329382000000003; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -92.904446149999998 25 -92.904446149999998; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -71.101691509999995 25 -71.101691509999995; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 32.578198350000001 25 32.578198350000001; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -95.564448510000005 25 -95.564448510000005; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -select -ne :time1; - setAttr ".o" 13; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lloleg; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pain_luparm.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_luparm_on4.ma b/base/models/monsters/imp/animation/cycles/pain_luparm_on4.ma deleted file mode 100644 index 08ab7d70e..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_luparm_on4.ma +++ /dev/null @@ -1,3999 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:20 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_luparm_on4.ma -//Last modified: Thu, Nov 07, 2002 02:50:04 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 229.41915847402083 9.5560810503418292 -3.39379748733655 ; - setAttr ".r" -type "double3" 3.2698910844838487 -2072.5999999996866 -8.764178719842211e-015 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 157.53469790667066; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 71.489854880680866 5.0477038073337184 -6.4965647914197646 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 101.55584547386937 -3.3428797739735074 119.73801778504512 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.31162123314752; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.366533543047794; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 2 -max 19 -ast 2 -aet 19 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 4 -7.5406347832540632e-013 5 -7.5406347832540632e-013 6 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 10 -7.5406347832540632e-013 11 -7.5406347832540632e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 4 13.71946295727715 5 13.71946295727715 6 13.71946295727715 9 13.71946295727715 - 10 13.71946295727715 11 13.71946295727715; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 4 -3.0908609005564358e-013 5 -3.0908609005564358e-013 6 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 10 -3.0908609005564358e-013 11 -3.0908609005564358e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 68.596496127541187 2 68.596496127541187 - 3 68.596496127541187 4 68.596496127541187 5 68.596496127541187 6 68.596496127541187 - 9 68.596496127541187 10 68.596496127541187 11 68.596496127541187; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -60.802874383230787 2 -60.802874383230787 - 3 -60.802874383230787 4 -60.802874383230787 5 -60.802874383230787 6 -60.802874383230787 - 9 -60.802874383230787 10 -60.802874383230787 11 -60.802874383230787; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -157.43468421330525 2 -157.43468421330525 - 3 -157.43468421330525 4 -157.43468421330525 5 -157.43468421330525 6 -157.43468421330525 - 9 -157.43468421330525 10 -157.43468421330525 11 -157.43468421330525; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 4 15.445123296459183 5 15.445123296459183 6 15.445123296459183 9 15.445123296459183 - 10 15.445123296459183 11 15.445123296459183; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 4 15.445123296459185 5 15.445123296459185 6 15.445123296459185 9 15.445123296459185 - 10 15.445123296459185 11 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 4 15.445123296459181 5 15.445123296459181 6 15.445123296459181 9 15.445123296459181 - 10 15.445123296459181 11 15.445123296459181; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 1 10 0 11 - 0.40000000000000002; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 3 -2.5294371750177831 - 9 -2.5294371750177831 12 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 - 19 -2.5294371750177831; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 3 13.481673551673362 - 9 13.481673551673362 12 13.481673551673362 14 13.481673551673362 17 13.481673551673362 - 19 13.481673551673362; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 3 -0.26635088939205875 - 9 -0.26635088939205875 12 -0.26635088939205875 14 -0.26635088939205875 17 - -0.26635088939205875 19 -0.26635088939205875; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 73.167297059293915 3 73.167297059293915 - 9 73.167297059293915 12 73.167297059293915 14 73.167297059293915 17 73.167297059293915 - 19 73.167297059293915; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 61.241182877125034 3 61.241182877125034 - 9 61.241182877125034 12 61.241182877125034 14 61.241182877125034 17 61.241182877125034 - 19 61.241182877125034; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 177.69376467901077 3 177.69376467901077 - 9 177.69376467901077 12 177.69376467901077 14 177.69376467901077 17 177.69376467901077 - 19 177.69376467901077; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0.5 17 0 19 - 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 0 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 1 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 59.56190462579648 2 87.086512400040135 - 3 87.086512400040135 9 87.086512400040135 10 87.086512400040135 11 89.803156191128494 - 12 90.914510469301021 13 95.359927581991059 14 106.84392178977366 16 114.45709035559202 - 19 167.43505300763536; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 6.1155384277619564 2 3.3966049353215197 - 3 3.3966049353215197 9 3.3966049353215197 10 4.3844754048082084 11 7.5950544306398937 - 12 8.2124734740690712 13 9.6942791782990856 14 11.670020117272431 16 13.774088242950418 - 19 3.1848718158837808; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -18.214943034405117 2 -18.214943034405117 - 3 -18.214943034405117 9 -18.214943034405117 10 -18.214943034405117 11 -18.214943034405117 - 12 -18.214943034405117 13 -18.214943034405117 14 -18.214943034405117 16 -18.214943034405117 - 19 -18.214943034405117; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 64.752151263719625 2 45.636324587558242 - 3 45.636324587558242 9 45.636324587558242 10 51.259142132888385 11 82.633703945066614 - 12 91.925517875523141 13 45.636324587558242 14 45.636324587558242 16 -52.350191482226066 - 19 219.80154311026268; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 54.671688625550246 2 79.910841797573497 - 3 79.910841797573497 9 79.910841797573497 10 79.910841797573482 11 79.91084179757361 - 12 79.91084179757344 13 79.910841797573497 14 79.910841797573497 16 24.766301215716588 - 19 103.06211582598448; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.46864865283559 2 3.4514964971631841 - 3 3.4514964971631841 9 3.4514964971631841 10 3.4514964971631956 11 3.4514964971632005 - 12 3.4514964971635234 13 3.4514964971631841 14 3.4514964971631841 16 -98.530493758286156 - 19 179.66289643582957; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999989 2 0.99999999999999989 - 3 0.99999999999999989 9 0.99999999999999989 10 0.99999999999999989 11 0.99999999999999989 - 12 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 16 0.99999999999999989 - 19 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 9 0.99999999999999978 10 0.99999999999999978 11 0.99999999999999978 - 12 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 16 0.99999999999999978 - 19 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.426477445851056 2 47.90393294415022 - 3 47.90393294415022 4 49.571857445849837 5 54.416924328220652 6 76.91378422815221 - 7 90.926137136631965 8 104.90238781324805 9 119.6320759386512 11 133.30969811775907 - 19 133.30969811775907; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.382959769989033 2 4.26699651607976 - 3 4.26699651607976 4 7.5234205432075498 5 8.9484432415242807 6 7.203638148018376 - 7 13.455232162483156 8 13.222439041068554 9 8.429209504871201 11 3.616514330714832 - 19 3.616514330714832; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.5906769424741469 2 5.5906769424741469 - 3 5.5906769424741469 4 5.5906769424741469 5 4.8437019572729909 6 4.7903818813050094 - 7 5.5906769424741469 8 5.5906769424741469 9 5.5906769424741469 11 5.5906769424741469 - 19 5.5906769424741469; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -213.67554625381291 2 -155.58505834761613 - 3 -155.58505834761613 4 -122.73251224871834 5 -177.7142343101996 6 -225.74849598730907 - 7 -182.20184218742966 8 -167.35620527064438 9 -185.9452684786005 11 -178.9145192530496 - 19 -178.9145192530496; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 76.0624067087263 2 77.351754812025391 - 3 77.351754812025391 4 77.351754812025504 5 78.853863033891884 6 68.745530314090416 - 7 42.231539530725335 8 52.060566701540544 9 40.693717484916455 11 77.792981530281054 - 19 77.792981530281054; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 125.96337513298413 2 168.36778920107272 - 3 168.36778920107272 4 168.3677892010729 5 89.977469223902958 6 -37.34389052151419 - 7 50.997059015191702 8 69.291367951665947 9 111.25790401441596 11 146.44536767645329 - 19 146.44536767645329; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 4 0.99999999999999978 5 0.99999999999999978 6 0.99999999999999978 - 7 0.99999999999999978 8 0.99999999999999978 9 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 5 1 9 1 13 1 17 1 19 1 - 21.392 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 2.2108130780280457 5 0 9 - 0 13 0 17 0 19 0 21.392 0; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 2 7.6119659250630507 - 5 5.6268319407172029 9 5.6268319407172029 13 5.6268319407172029 17 5.6268319407172029 - 19 5.6268319407172029 21.392 5.6268319407172029; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 2 -2.0102170666694961 - 5 -2.1098668596606802 9 -2.1098668596606802 13 -2.1098668596606802 17 -2.1098668596606802 - 19 -2.1098668596606802 21.392 -2.1098668596606802; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -0.624 363.04706215082535 2 361.24644087209703 - 5 373.76063026300602 9 361.64068150857611 13 378.57221183734987 17 362.51014995549542 - 19 360.73763009723075 20.58 370.59077456904788; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1.3 1.0164485751876862 2 -2.7819088339027283 - 5 -0.44667534838539302 9 -0.44667534838539519 13 -0.44667534838539386 17 - 2.6709700285893727 19 -0.44667534838539391 21.392 -0.44667534838539391; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" -0.92800000000000005 -14.898177256474998 - 2 -24.791905049441631 5 -14.641906192173147 9 -14.64190619217317 13 -14.64190619217317 - 17 -15.478432696593305 19 -14.641906192173112 20.428 -10.003399928309316; - setAttr -s 8 ".kit[0:7]" 1 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 1 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kix[0:7]" 0.99515235424041748 0.99983608722686768 - 0.85469967126846313 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 8 ".kiy[0:7]" -0.098345361649990082 0.018105426803231239 - 0.51912277936935425 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; - setAttr -s 8 ".kox[0:7]" 0.99515235424041748 0.99983608722686768 - 0.85469967126846313 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 8 ".koy[0:7]" -0.098345354199409485 0.018105426803231239 - 0.51912277936935425 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 5 1 9 1 13 1 17 1 19 1 - 21.392 1; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 5 1 9 1 13 1 17 1 19 1 - 21.392 1; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 5 1 9 1 13 1 17 1 19 1 - 21.392 1; - setAttr -s 8 ".kit[2:7]" 3 3 3 9 9 3; - setAttr -s 8 ".kot[2:7]" 3 3 3 9 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599494 8 7.1689522478599494 - 11 7.168952247859953 12 6.3450935941379685 13 6.0198451340742674 15 7.1689522478599494 - 17 7.1689522478599494; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 11 7.9126523868203575 12 - 11.673695323026516 13 10.182893175810886 15 0.0996086992316223 17 0.0996086992316223; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.672655709095594 8 18.672655709095594 - 11 33.796945933310276 12 39.374766587856087 13 50.519161987064884 15 79.36659147624809 - 17 79.36659147624809; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -174.49049195404214 8 -174.49049195404214 - 11 -197.94003856162612 12 -209.04261896981978 13 -197.47915486936469 15 -174.49049195404214 - 17 -174.49049195404214; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 129.78625356110399 8 129.78625356110399 - 11 129.78625356110399 12 129.78625356110393 13 129.78625356110396 15 129.78625356110399 - 17 129.78625356110399; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -169.93906815090079 8 -169.93906815090079 - 11 -169.93906815090077 12 -169.93906815090071 13 -169.93906815090074 15 -169.93906815090079 - 17 -169.93906815090079; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 2 -7.3924057183505063 - 4 -7.3924057183505063 7 -7.3924057183505072 16 -7.3924057183505072 19 -7.8056900478444984 - 20 -7.3924057183505019; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 2 3.8239532939043315 4 4.0648047266548115 - 7 0 16 0 19 4.5955098521668347 20 8.7811622696593155; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 2 0.20742917859232701 - 4 13.300708001810973 7 41.567423254461779 16 41.567423254461779 19 64.205822324463625 - 20 81.566657370801593; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.229299623311356 2 -4.0235235023419671 - 4 11.229299623311356 7 11.229299623311356 16 11.229299623311356 19 -11.325478474133927 - 20 -23.884488550391008; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -47.425170065295866 2 -50.847426602078393 - 4 -47.425170065295866 7 -47.425170065295866 16 -47.425170065295866 19 -48.639053402913603 - 20 -48.184556498320411; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -15.059620758260801 2 -16.248026693665089 - 4 -15.059620758260801 7 -15.059620758260801 16 -15.059620758260801 19 -11.299337016217571 - 20 11.991848508498084; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; - setAttr -s 8 ".kot[1:7]" 5 5 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9808213950621774 2 1.9808213950621776 - 4 1.9808213950621785 8 1.9808213950621805 12 1.980821395062182 16 1.9808213950621867 - 19 1.9808213950621898 20 1.9808213950621909; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 18.41992256503119 2 17.5648042732577 - 4 19.662864340591319 8 22.465004485504792 12 16.444893931989601 16 22.519284760552775 - 19 17.522230344830156 20 17.859988542372403; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.39740898729022 2 31.096571683529532 - 4 36.8657521678211 8 52.050851690712953 12 67.170375289917047 16 83.777913253213256 - 19 96.110338887997557 20 100.30869317838135; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 67.201049905350132 2 72.412729339164329 - 4 72.24368546320558 8 67.201049905350132 12 67.201049905350132 16 67.201049905350132 - 19 67.201049905350132 20 67.201049905350132; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 34.001171535446794 4 30.348192492267696 - 8 0 12 0 16 0 19 0 20 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.426073875550391 2 11.895378756359257 - 4 13.413087657808239 8 7.426073875550391 12 7.426073875550391 16 7.426073875550391 - 19 7.426073875550391 20 7.426073875550391; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.3610577639827144 2 -0.21285352564148119 - 5.7960000000000003 3.5485029363551686 9.2360000000000007 1.3924894832037882 - 14 -3.8248141218513645 19 -0.21285352564148119 21 2.8197115728311255; - setAttr -s 7 ".kit[5:6]" 1 9; - setAttr -s 7 ".kot[5:6]" 1 9; - setAttr -s 7 ".kix[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".kiy[5:6]" 0.99956315755844116 0.999622642993927; - setAttr -s 7 ".kox[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".koy[5:6]" 0.99956315755844116 0.999622642993927; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.27858988479459218 2 0.15078676416754505 - 3 0.041071720760699121 5 -0.12734812175584798 11 0.01615418026612319 14 0.50054018883462204 - 19 0.15078676416754505 21 0.01581159374970395; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.039992513696998876 2 0.15149042747921673 - 3 0.38885909572774768 5 0.81318111183904007 11 0.47178511368290149 14 -0.68058277559896596 - 19 0.15149042747921673 21 0.6807047568788458; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 0.90991990467137285 6 0.757413731437375 - 11 0.52631001515514408 14 0.17989662655130284 16 0.11086142298673962 19 0.90991990467137285; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1.6840963091226424 6 1.9921588651806885 - 11 2.376954893450355 14 2.6063840737414372 16 2.5942005418897831 19 1.6840963091226424; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 2.8509277672757398 6 2.6074946383461919 - 11 2.2942978244046901 14 2.0606653100128796 16 2.0534195118150946 19 2.8509277672757398; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -82.189303625215842 6 -104.37729528867425 - 11 -92.006962071167038 14 -104.30491760011213 16 -98.611645848609228 19 -82.189303625215842; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 32.936642853707767 6 -8.8441659435333211 - 11 -23.718949300073728 14 -13.739625821068813 16 0.073490689192853564 19 - 32.936642853707767; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -9.2450492652573306 6 -11.190509011262176 - 11 -15.571971397215279 14 -18.399796932359234 16 -15.14081226122182 19 -9.2450492652573306; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; - setAttr -s 7 ".kot[1:6]" 5 5 5 5 5 9; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0 2 0 7 0 11 0 15 0 19 0 - 21.972000000000001 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 2.3128351505039433 2 2.3128351505039433 - 7 2.3128351505039433 11 2.3128351505039433 15 2.3128351505039433 19 2.3128351505039433 - 21.972000000000001 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0.23421866920666501 2 0.23421866920666501 - 7 0.23421866920666501 11 0.23421866920666501 15 0.23421866920666501 19 0.23421866920666501 - 21.972000000000001 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 18.015821706774922 2 7 7 - 17.885785658953552 11 7 15 17.865328849758896 19 7 21.972000000000001 17.767020748470053; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 -20.871491789318089 2 -26.903356467361473 - 7 6.6740813894110849 11 26 15 -2.3802552171770213 19 -26.903356467361473 - 21.972000000000001 -13.498742838462716; - setAttr -s 7 ".kit[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kot[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kix[2:6]" 0.31150621175765991 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".kiy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; - setAttr -s 7 ".kox[2:6]" 0.3115062415599823 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".koy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -1.3720000000000001 7.6978127730792556 - 2 15.011069830747704 7 0.81964143355547092 11 5.6889805773011233 15 1.2715285190009615 - 19 15.011069830747704 21.972000000000001 16.516055040920126; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0.27427147149852044 5 0.27427147149852044 - 8 0.27427147149852044 11 0.27427147149852044 19 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.1074984126668126 5 -1.1074984126668126 - 8 -1.1074984126668126 11 -1.1074984126668126 19 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.642626684874722 5 -1.642626684874722 - 8 -1.642626684874722 11 -1.642626684874722 19 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -72.192682186483722 5 -112.43723771647277 - 8 -140.9476176021825 11 -76.320044575450154 19 -72.192682186483722; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -0.2742786288673521 8 -0.2742786288673521 - 12 -0.2742786288673521 16 -0.2742786288673521 19 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.1075115373407667 8 -1.1075115373407667 - 12 -1.1075115373407667 16 -1.1075115373407667 19 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.6426166407301896 8 -1.6426166407301896 - 12 -1.6426166407301896 16 -1.6426166407301896 19 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 57.295779513082337 8 46.221739108863801 - 12 83.651838089100195 16 124.90479933851947 19 57.295779513082337; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 1 4 1 5 1 6 0 9 0 10 0 11 1; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 0 4 0.60000000000000009 5 1 6 - 0.30000000000000004 9 0.046875 10 0 11 0; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 1 9 1 12 1 14 0 17 0 19 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 0 9 0 12 1 14 0 17 0 19 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 8 1 12 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -66.817792973155349 8 -117.76998860514637 - 12 -58.717593899130961 19 -66.817792973155349; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -49.477141044160646 8 -45.114889989798428 - 12 -58.488201638849723 19 -49.477141044160646; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -52.341476887309149 8 -22.64196747141678 - 12 -76.449769012401859 19 -52.341476887309149; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 10 1 14 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -168.75212351198743 10 -142.34379908236403 - 14 -91.772226065525047 19 -168.75212351198743; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 44.488737867426309 10 11.646024816259962 - 14 57.8461210256567 19 44.488737867426309; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -70.747288710930945 10 -54.074322568995257 - 14 -28.519478878489718 19 -70.747288710930945; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.90858890976581275 7 -3.7621162796982501 - 14 0.3657111927859622 16 -0.5854119341237376 19 -0.90858890976581275; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 6.2382713968077237 7 5.3887456806949574 - 14 6.0204513845034606 16 5.8835786026344072 19 6.2382713968077237; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.55501859990651525 7 1.684897371141969 - 14 -0.55708239243809732 16 2.3929863357066576 19 -0.55501859990651525; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -22.350064437213423 7 -13.094561677764091 - 14 -16.423765740015508 16 -18.438399824774098 19 -22.350064437213423; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -10.303773027856268 7 6.151404343053847 - 14 8.9343731574279008 16 7.5138197933918374 19 -10.303773027856268; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 8.8115085199100047 7 22.517921127381236 - 14 29.420970529265055 16 16.267284651382163 19 8.8115085199100047; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 6.7758528420198658 16 6.7758528420198658 - 19 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9388939039072284e-018 16 - -6.9388939039072284e-018 19 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -9.5120444723942321e-016 16 - -9.5120444723942321e-016 19 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -12.784757077400341 16 -91.730384948739413 - 19 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 3.2695897469829736 16 3.2695897469829762 - 19 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9162979482121409 16 -6.9162979482121507 - 19 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0.74525677667777757 6 0.74525677667777757 - 11 0.74525677667777757 15 0.74525677667777757 19 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1.8072476834435935 6 1.8072476834435935 - 11 1.8072476834435935 15 1.8072476834435935 19 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 13.355267980117441 11 0 15 - 7.2929987411270378 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -select -ne :time1; - setAttr ".o" 10; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" -18.614506811257503 0.84764906658249273 5.7933053667332839 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; - setAttr ".r" -type "double3" -66.065354836318264 28.775852580156471 -91.471856426984459 ; - setAttr ".twi" 217.7239621497128; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_place2dTexture1.mv" "IMP_file1.mv"; -connectAttr "IMP_place2dTexture1.vt1" "IMP_file1.vt1"; -connectAttr "IMP_place2dTexture1.vt2" "IMP_file1.vt2"; -connectAttr "IMP_place2dTexture1.vt3" "IMP_file1.vt3"; -connectAttr "IMP_place2dTexture1.vc1" "IMP_file1.vc1"; -connectAttr "IMP_leg_place2dTexture1.mv" "IMP_leg_file1.mv"; -connectAttr "IMP_leg_place2dTexture1.vt1" "IMP_leg_file1.vt1"; -connectAttr "IMP_leg_place2dTexture1.vt2" "IMP_leg_file1.vt2"; -connectAttr "IMP_leg_place2dTexture1.vt3" "IMP_leg_file1.vt3"; -connectAttr "IMP_leg_place2dTexture1.vc1" "IMP_leg_file1.vc1"; -connectAttr "IMP_place2dTexture2.mv" "IMP_file2.mv"; -connectAttr "IMP_place2dTexture2.vt1" "IMP_file2.vt1"; -connectAttr "IMP_place2dTexture2.vt2" "IMP_file2.vt2"; -connectAttr "IMP_place2dTexture2.vt3" "IMP_file2.vt3"; -connectAttr "IMP_place2dTexture2.vc1" "IMP_file2.vc1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.mv" "IMP_ZOMBIE1_file1.mv"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt1" "IMP_ZOMBIE1_file1.vt1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt2" "IMP_ZOMBIE1_file1.vt2"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt3" "IMP_ZOMBIE1_file1.vt3"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vc1" "IMP_ZOMBIE1_file1.vc1"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of pain_luparm_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_ruparm.ma b/base/models/monsters/imp/animation/cycles/pain_ruparm.ma deleted file mode 100644 index 7281ac74d..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_ruparm.ma +++ /dev/null @@ -1,3785 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:25 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_ruparm.ma -//Last modified: Mon, Mar 15, 2004 09:05:17 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 241.02463342233725 77.444609546045385 113.12055624675455 ; - setAttr ".r" -type "double3" -10.530108913547632 -296.19999999999283 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 260.85304481259561; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 22.57111845060059 55.161154620979616 4.855171589784562 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 34.105831591195802 115.73742012124887 7.6304956654842391 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 164.67624707525044; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 38.073089812497805 54.534898150352312 107.86157254419315 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.464393079493448; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 103.07551681128726 30.048199460830929 -10.456343212331282 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 123.45552071539539; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -29.548385579999998 25 -29.548385579999998 - 29 -38.367703938541368 33 -38.367703938541368; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 5.3462904040000003 25 5.3462904040000003 - 29 -22.261750778216175 33 0 53 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.3030645630000004 25 -5.3030645630000004 - 29 0 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.392405718 25 -7.392405718 - 29 -8.5228661809757718 33 -8.5228661809757842; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 25 0 29 8.6414253885234693 - 33 0; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -7.3620493590000002 25 -7.3620493590000002 - 29 29.058010331813129 33 55.894887262743886; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 25 1 29 1 33 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 63.314403930000005 25 63.314403930000005 41 36.237070617308525 - 49 36.237070617308518 53 36.237070617308518; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 10.10932652 25 10.10932652 41 0 49 -19.289764981099978 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 11.59016476 - 25 11.59016476 41 0 49 0 53 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 7.1689522480000001 25 7.1689522480000001 41 9.6873596619451892 - 49 9.6873596619451749 53 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 25 0 41 0 49 6.5824344037117717 53 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 -7.748575014 25 -7.748575014 41 19.750878638974889 - 49 56.871344609681749 53 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 25 1 41 1 - 49 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 43.400594811358097 25 41.235789590000003 29 42.252989606287457 - 33 39.474641024093501 41 35.507697111286575 49 41.757587197385924 53 38.975399081339425 - 61 36.922520121156822; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 -9.6005467365588046 25 -2.4191866630000001 29 - 35.34397057886077 33 46.128707057474401 41 48.210536281058985 49 64.065722338788731 - 53 76.398879176777299 61 80.803578047487491; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 3.4240648103304925 25 1.980821395 29 1.9932938451333648 - 33 0.5224520839187321 41 -0.96093906669208984 49 -4.8012869768196573 53 0.51611782181851806 - 61 0.81152919952064195; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 1 3; - setAttr -s 11 ".kix[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".kiy[9:10]" 0.98337632417678833 0; - setAttr -s 11 ".kox[9:10]" 0.18157932162284851 1; - setAttr -s 11 ".koy[9:10]" 0.98337632417678833 0; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8.2 1 12.2 1 13 1 25 1 29 1 - 33 1 41 1 49 1 53 1 61 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 9 3 - 3 3 3 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 0.4494172494 25 0.4494172494 28.2 6.6566912693983946 - 32.200000000000003 6.1330193887268454 40.200000000000003 0.24039650864424209 - 53 -4.1657930308134645; - setAttr -s 9 ".kit[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 1 9 3; - setAttr -s 9 ".kix[6:8]" 0.061753064393997192 0.083855703473091125 - 1; - setAttr -s 9 ".kiy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; - setAttr -s 9 ".kox[6:8]" 0.061753060668706894 0.083855703473091125 - 1; - setAttr -s 9 ".koy[6:8]" -0.99809145927429199 -0.99647790193557739 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 -0.058577090280000001 25 -0.058577090280000001 28.2 - -0.86763382127902322 32.200000000000003 -0.42972806484138226 40.200000000000003 - -0.031333305538134112 53 0.54296989172209287; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 25 0 28.2 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 0 25 0 28.2 5.0790319675705673 32.200000000000003 - 6.7230875260072231 40.200000000000003 0 53 -7.4542171015494922; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 25 1 28.2 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 9 ".kit[3:8]" 3 3 9 9 9 3; - setAttr -s 9 ".kot[3:8]" 3 3 9 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 40.200000000000003 - 2.3128351505039433 53 2.3128351505039433; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 40.200000000000003 0.23421866920666501 53 0.23421866920666501; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581426 20.2 7.824737866480139 28.2 -0.56667192682884493 40.200000000000003 - 0.57720421748491901 53 8.7951795972581372; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 -24.30811116038322 20.2 -5.0226759171895878 28.2 13.000667896194788 40.200000000000003 - 12.790622953496632 53 13.892774724407374; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325647 - 20.2 22.77669484325164 28.2 -13.027357639203586 40.200000000000003 -8.1143097424545108 - 53 26.888910802325626; - setAttr -s 7 ".kit[2:6]" 3 3 9 9 3; - setAttr -s 7 ".kot[2:6]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 373.5000544583113 19.4 398.33832420130017 25.800000000000001 405.49797585237241 - 32.200000000000003 388.93797585237292 40.200000000000003 400.28864310407283 - 53 389.49637174592857; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -16.781272320372167 19.4 -14.641906192173103 25.800000000000001 -14.641906192173103 - 32.200000000000003 -14.641906192173099 40.200000000000003 -14.641906192173103 - 53 -14.641906192173099; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -13.03948754198662 19.4 -0.44667534838541073 25.800000000000001 -0.4466753483854129 - 32.200000000000003 -0.44667534838541123 40.200000000000003 -0.44667534838541301 - 53 -0.44667534838541167; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 32.200000000000003 5.6268319407172029 40.200000000000003 5.6268319407172029 - 53 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 32.200000000000003 -2.1098668596606802 40.200000000000003 -2.1098668596606802 - 53 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.600000000000001 5.7384771804188404 47 5.7384771804188404 53 5.7384771804188404; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.600000000000001 2.0494561358638701 47 2.0494561358638701 53 2.0494561358638701; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.600000000000001 0 47 0 53 0; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.600000000000001 16.052055400530755 47 30.358488909126763 53 37.874152024707215; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.600000000000001 11.52461344822842 47 -2.1187003779812748 53 -14.364226384227051; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.600000000000001 -25.97088988767895 47 -26.687875434482198 53 -36.863333637497242; - setAttr -s 8 ".kit[2:7]" 3 9 3 9 3 3; - setAttr -s 8 ".kot[2:7]" 3 9 3 9 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.600000000000001 1 47 1 53 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 9.2581582796388115 15 -11.340398697750635 18 - -24.598006495389306 25 -14.840217421411868 32.200000000000003 -15.091352590275802 - 40.200000000000003 -24.981217127315897 53 -16.777720747043478; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 13.28388939133403 15 31.281930439752845 18 48.15826652499068 - 25 16.509687863537451 32.200000000000003 5.460283656526733 40.200000000000003 - 3.555911204482308 53 5.3449549069799076; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 26.279213255443945 15 14.363880496065407 18 -33.408635312787865 - 25 -17.89538038991634 32.200000000000003 -19.683531133663919 40.200000000000003 - -11.295059140243522 53 -16.48879266455566; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 15 2.6456615572060826 18 2.6456615572060826 - 25 2.6456615572060826 32.200000000000003 2.6456615572060826 40.200000000000003 - 2.6456615572060826 53 2.6456615572060826; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 15 1.9935618776130362 18 1.9935618776130362 - 25 1.9935618776130362 32.200000000000003 1.9935618776130362 40.200000000000003 - 1.9935618776130362 53 1.9935618776130362; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 11.4 0 13 0 15 0 18 0 - 25 0 32.200000000000003 0 40.200000000000003 0 53 0; - setAttr -s 10 ".kit[6:9]" 3 9 9 3; - setAttr -s 10 ".kot[6:9]" 3 9 9 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 15 1 18 1 - 25 1 32.200000000000003 1 40.200000000000003 1 53 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 13 12.412879749935719 - 20 12.412879749935719 25 12.412879749935719 34.6 12.412879749935719 40.200000000000003 - 12.412879749935719 53 12.412879749935719; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 13 -6.7286993982861674 - 20 -6.7286993982861674 25 -6.7286993982861674 34.6 -6.7286993982861674 40.200000000000003 - -6.7286993982861674 53 -6.7286993982861674; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 13 -3.868763862603668 - 20 -3.868763862603668 25 -3.868763862603668 34.6 -3.868763862603668 40.200000000000003 - -3.868763862603668 53 -3.868763862603668; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 80.239686562403847 13 73.398012792547533 - 20 92.401590058023146 25 103.41622835125608 34.6 94.762662499017765 40.200000000000003 - 87.603010847945214 53 105.11870283856432; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.8978517871634404 13 0.21742569259672129 - 20 0.098912473866345871 25 0 34.6 0 40.200000000000003 0 53 0.21742569259672076; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.92545182592768849 13 0.034116996666525318 - 20 0.015520688835634049 25 0 34.6 0 40.200000000000003 0 53 0.034116996666525033; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 20 1 25 1 34.6 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 25 -12.41287000000041 27.4 -12.41287000000041 40.200000000000003 - -12.41287000000041 53 -12.41287000000041; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 25 -6.7285999999993047 27.4 -6.7285999999993047 40.200000000000003 - -6.7285999999993047 53 -6.7285999999993047; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 25 -3.8687599999999316 27.4 -3.8687599999999316 40.200000000000003 - -3.8687599999999316 53 -3.8687599999999316; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 58.099612817676174 10.6 82.316033184538099 - 13 -13.178840025327611 25 92.144105348206509 27.4 63.019898856647714 40.200000000000003 - 82.099898856647854 53 81.577924579716537; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10.6 0 13 0 25 0 27.4 0 40.200000000000003 - 0 53 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10.6 1 13 1 25 1 27.4 1 40.200000000000003 - 1 53 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 13 -max 25 -ast 13 -aet 25 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0.84249900256869781 25 0 29 - 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 -23.041086893268535 25 0 29 - 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 11.645753960453801 25 3.09040954 - 29 0 33 0 41 0 49 0 53 0 61 0; - setAttr -s 8 ".kit[2:7]" 9 3 3 3 3 3; - setAttr -s 8 ".kot[2:7]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 3.3867545965885748 25 4.0594933981443528; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.1192573708760349 25 2.2039448112088227; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0821078932592165 25 -3.1435795472686916; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 6.6922618023400222 25 5.8468963861459979; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 16.358135010133395 25 -28.368765378774526; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.2600025551719725 25 -28.052185257064387; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.9298872857263043 25 -4.3029039238518836; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.7882691209681596 25 2.0038703496478467; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -5.1146352835171411 25 -2.9983962363577357; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 47.075908035354132 25 42.346733523013434; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -1.1479639137932736 25 -6.9184562357428412; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 12.487385448540254 25 -1.2143143388545381; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -7.5406347832540632e-013 25 - -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.71946295727715 25 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -3.0908609005564358e-013 25 - -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -82.976046413383102 25 -82.082942762890042; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -32.144874087538099 25 -41.262114869043131; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -26.205809805073454 25 -27.695327781842096; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459183 25 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459181 25 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -2.5294371750177831 25 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 13.481673551673362 25 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.26635088939205875 25 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 240.76698806505698 25 239.50132211939308; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 76.182851789542724 25 78.903278192407754; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 374.83445880576221 25 345.83232963291096; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.445123296459185 25 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -18.647768363316043 25 -32.458460557687573; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 36.3191443147117 25 25.207071114325792; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 107.88509288000579 25 81.364043115468817; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.52893863520222695 25 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 23.914756983415913 25 25.521603815854018; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -58.717907199956898 25 -49.929606980787931; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -41.055955789443395 25 -60.904739916227172; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0.5814880999021691 25 0.5814880999021691; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -118.97547159999999 25 -118.97547159999999; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 30.329382000000003 25 30.329382000000003; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -92.904446149999998 25 -92.904446149999998; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -71.101691509999995 25 -71.101691509999995; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 32.578198350000001 25 32.578198350000001; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -95.564448510000005 25 -95.564448510000005; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 25 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 25 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 13 1; -select -ne :time1; - setAttr ".o" 13; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Lloleg; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pain_ruparm.ma diff --git a/base/models/monsters/imp/animation/cycles/pain_ruparm_on4.ma b/base/models/monsters/imp/animation/cycles/pain_ruparm_on4.ma deleted file mode 100644 index 456c3ca9b..000000000 --- a/base/models/monsters/imp/animation/cycles/pain_ruparm_on4.ma +++ /dev/null @@ -1,4015 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:25 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pain_ruparm_on4.ma -//Last modified: Thu, Nov 07, 2002 02:51:50 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 236.64041988314204 25.494178431566176 19.367495358001314 ; - setAttr ".r" -type "double3" -3.9301089156430788 -2079.3999999999014 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 166.88044346809713; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 74.327570721028252 4.0422369888750822 -6.0043706496266012 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 101.55584547386937 -3.3428797739735074 119.73801778504512 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.31162123314752; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.366533543047794; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 2 -max 19 -ast 2 -aet 19 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 4 -7.5406347832540632e-013 5 -7.5406347832540632e-013 6 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 10 -7.5406347832540632e-013 11 -7.5406347832540632e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 4 13.71946295727715 5 13.71946295727715 6 13.71946295727715 9 13.71946295727715 - 10 13.71946295727715 11 13.71946295727715; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 4 -3.0908609005564358e-013 5 -3.0908609005564358e-013 6 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 10 -3.0908609005564358e-013 11 -3.0908609005564358e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 68.596496127541187 2 68.596496127541187 - 3 68.596496127541187 4 68.596496127541187 5 68.596496127541187 6 68.596496127541187 - 9 68.596496127541187 10 68.596496127541187 11 68.596496127541187; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -60.802874383230787 2 -60.802874383230787 - 3 -60.802874383230787 4 -60.802874383230787 5 -60.802874383230787 6 -60.802874383230787 - 9 -60.802874383230787 10 -60.802874383230787 11 -60.802874383230787; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -157.43468421330525 2 -157.43468421330525 - 3 -157.43468421330525 4 -157.43468421330525 5 -157.43468421330525 6 -157.43468421330525 - 9 -157.43468421330525 10 -157.43468421330525 11 -157.43468421330525; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 4 15.445123296459183 5 15.445123296459183 6 15.445123296459183 9 15.445123296459183 - 10 15.445123296459183 11 15.445123296459183; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 4 15.445123296459185 5 15.445123296459185 6 15.445123296459185 9 15.445123296459185 - 10 15.445123296459185 11 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 4 15.445123296459181 5 15.445123296459181 6 15.445123296459181 9 15.445123296459181 - 10 15.445123296459181 11 15.445123296459181; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 1 10 0 11 - 0.40000000000000002; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 3 -2.5294371750177831 - 9 -2.5294371750177831 12 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 - 19 -2.5294371750177831; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 3 13.481673551673362 - 9 13.481673551673362 12 13.481673551673362 14 13.481673551673362 17 13.481673551673362 - 19 13.481673551673362; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 3 -0.26635088939205875 - 9 -0.26635088939205875 12 -0.26635088939205875 14 -0.26635088939205875 17 - -0.26635088939205875 19 -0.26635088939205875; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 73.167297059293915 3 73.167297059293915 - 9 73.167297059293915 12 73.167297059293915 14 73.167297059293915 17 73.167297059293915 - 19 73.167297059293915; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 61.241182877125034 3 61.241182877125034 - 9 61.241182877125034 12 61.241182877125034 14 61.241182877125034 17 61.241182877125034 - 19 61.241182877125034; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 177.69376467901077 3 177.69376467901077 - 9 177.69376467901077 12 177.69376467901077 14 177.69376467901077 17 177.69376467901077 - 19 177.69376467901077; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0.5 17 0 19 - 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 0 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 1 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 59.56190462579648 2 87.086512400040135 - 3 87.086512400040135 9 87.086512400040135 10 87.086512400040135 11 89.803156191128494 - 12 90.914510469301021 13 95.359927581991059 14 106.84392178977366 16 114.45709035559202 - 19 167.43505300763536; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 6.1155384277619564 2 3.3966049353215197 - 3 3.3966049353215197 9 3.3966049353215197 10 4.3844754048082084 11 7.5950544306398937 - 12 8.2124734740690712 13 9.6942791782990856 14 11.670020117272431 16 13.774088242950418 - 19 3.1848718158837808; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -18.214943034405117 2 -18.214943034405117 - 3 -18.214943034405117 9 -18.214943034405117 10 -18.214943034405117 11 -18.214943034405117 - 12 -18.214943034405117 13 -18.214943034405117 14 -18.214943034405117 16 -18.214943034405117 - 19 -18.214943034405117; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 64.752151263719625 2 45.636324587558242 - 3 45.636324587558242 9 45.636324587558242 10 51.259142132888385 11 82.633703945066614 - 12 91.925517875523141 13 45.636324587558242 14 45.636324587558242 16 -52.350191482226066 - 19 219.80154311026268; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 54.671688625550246 2 79.910841797573497 - 3 79.910841797573497 9 79.910841797573497 10 79.910841797573482 11 79.91084179757361 - 12 79.91084179757344 13 79.910841797573497 14 79.910841797573497 16 24.766301215716588 - 19 103.06211582598448; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.46864865283559 2 3.4514964971631841 - 3 3.4514964971631841 9 3.4514964971631841 10 3.4514964971631956 11 3.4514964971632005 - 12 3.4514964971635234 13 3.4514964971631841 14 3.4514964971631841 16 -98.530493758286156 - 19 179.66289643582957; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999989 2 0.99999999999999989 - 3 0.99999999999999989 9 0.99999999999999989 10 0.99999999999999989 11 0.99999999999999989 - 12 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 16 0.99999999999999989 - 19 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 9 0.99999999999999978 10 0.99999999999999978 11 0.99999999999999978 - 12 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 16 0.99999999999999978 - 19 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 5 1 6 1 7 1 8 1 9 1 11 - 1 19 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 39.426477445851056 2 47.90393294415022 - 5 65.264654188123274 6 76.91378422815221 7 90.926137136631965 8 104.90238781324805 - 9 119.6320759386512 11 133.30969811775907 19 133.30969811775907; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.382959769989033 2 4.26699651607976 - 5 14.069361696561202 6 7.203638148018376 7 13.455232162483156 8 13.222439041068554 - 9 8.429209504871201 11 3.616514330714832 19 3.616514330714832; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.5906769424741469 2 31.879969900450337 - 5 15.006801376612026 6 4.7903818813050094 7 5.5906769424741469 8 5.5906769424741469 - 9 5.5906769424741469 11 5.5906769424741469 19 5.5906769424741469; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -213.67554625381291 2 -155.58505834761613 - 5 -126.84719698017133 6 -225.74849598730907 7 -182.20184218742966 8 -167.35620527064438 - 9 -185.9452684786005 11 -178.9145192530496 19 -178.9145192530496; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 76.0624067087263 2 77.351754812025391 - 5 57.177570021199571 6 68.745530314090416 7 42.231539530725335 8 52.060566701540544 - 9 40.693717484916455 11 77.792981530281054 19 77.792981530281054; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 125.96337513298413 2 168.36778920107272 - 5 95.955174720716059 6 -37.34389052151419 7 50.997059015191702 8 69.291367951665947 - 9 111.25790401441596 11 146.44536767645329 19 146.44536767645329; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 5 1 6 1 7 1 8 1 9 1 11 - 1 19 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.99999999999999978 2 0.99999999999999978 - 5 0.99999999999999978 6 0.99999999999999978 7 0.99999999999999978 8 0.99999999999999978 - 9 0.99999999999999978 11 0.99999999999999978 19 0.99999999999999978; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 5 1 6 1 7 1 8 1 9 1 11 - 1 19 1; - setAttr -s 9 ".kit[0:8]" 3 9 9 9 9 9 9 - 3 3; - setAttr -s 9 ".kot[0:8]" 3 9 9 9 9 9 9 - 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 2 0 3 0 5 0 9 0 13 0 17 0 19 - 0 21.392 0; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.6268319407172029 2 5.6268319407172029 - 3 5.6268319407172029 5 5.6268319407172029 9 5.6268319407172029 13 5.6268319407172029 - 17 5.6268319407172029 19 5.6268319407172029 21.392 5.6268319407172029; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1098668596606802 2 -2.1098668596606802 - 3 -2.1098668596606802 5 -2.1098668596606802 9 -2.1098668596606802 13 -2.1098668596606802 - 17 -2.1098668596606802 19 -2.1098668596606802 21.392 -2.1098668596606802; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.624 363.04706215082535 2 375.52844244347591 - 3 389.51907119217475 5 380.50213101284243 9 361.64068150857611 13 378.57221183734987 - 17 362.51014995549542 19 360.73763009723075 20.58 370.59077456904788; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1.3 1.0164485751876862 2 3.3709897186224871 - 3 -4.5214096952936202 5 -3.2932180536752576 9 -0.44667534838539519 13 -0.44667534838539386 - 17 2.6709700285893727 19 -0.44667534838539391 21.392 -0.44667534838539391; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.92800000000000005 -14.898177256474998 - 2 -1.8970204435832103 3 0.96948855192219086 5 2.8189137154980668 9 -14.64190619217317 - 13 -14.64190619217317 17 -15.478432696593305 19 -14.641906192173112 20.428 - -10.003399928309316; - setAttr -s 9 ".kit[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[0:8]" 0.99515235424041748 0.50877201557159424 - 0.83519691228866577 0.67607080936431885 0.73804324865341187 0.99904215335845947 - 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".kiy[0:8]" -0.098345361649990082 0.86090129613876343 - 0.54995101690292358 -0.73683667182922363 -0.67475336790084839 -0.043758470565080643 - 0 0.55604952573776245 0.80578088760375977; - setAttr -s 9 ".kox[0:8]" 0.99515235424041748 0.50877201557159424 - 0.83519691228866577 0.67607080936431885 0.73804324865341187 0.99904215335845947 - 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".koy[0:8]" -0.098345354199409485 0.86090129613876343 - 0.54995101690292358 -0.73683667182922363 -0.67475336790084839 -0.043758470565080643 - 0 0.55604952573776245 0.80578088760375977; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[4:8]" 3 3 9 9 3; - setAttr -s 9 ".kot[4:8]" 3 3 9 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599494 8 7.1689522478599494 - 11 7.168952247859953 12 6.3450935941379685 13 6.0198451340742674 15 7.1689522478599494 - 17 7.1689522478599494; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 11 7.9126523868203575 12 - 11.673695323026516 13 10.182893175810886 15 0.0996086992316223 17 0.0996086992316223; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.672655709095594 8 18.672655709095594 - 11 33.796945933310276 12 39.374766587856087 13 50.519161987064884 15 79.36659147624809 - 17 79.36659147624809; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -174.49049195404214 8 -174.49049195404214 - 11 -197.94003856162612 12 -209.04261896981978 13 -197.47915486936469 15 -174.49049195404214 - 17 -174.49049195404214; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 129.78625356110399 8 129.78625356110399 - 11 129.78625356110399 12 129.78625356110393 13 129.78625356110396 15 129.78625356110399 - 17 129.78625356110399; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -169.93906815090079 8 -169.93906815090079 - 11 -169.93906815090077 12 -169.93906815090071 13 -169.93906815090074 15 -169.93906815090079 - 17 -169.93906815090079; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 2 -7.3924057183505063 - 4 -7.3924057183505063 7 -7.3924057183505072 16 -7.3924057183505072 19 -7.8056900478444984 - 20 -7.3924057183505019; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 2 3.8239532939043315 4 4.0648047266548115 - 7 0 16 0 19 4.5955098521668347 20 8.7811622696593155; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 2 0.20742917859232701 - 4 13.300708001810973 7 41.567423254461779 16 41.567423254461779 19 64.205822324463625 - 20 81.566657370801593; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.229299623311356 2 -4.0235235023419671 - 4 11.229299623311356 7 11.229299623311356 16 11.229299623311356 19 -11.325478474133927 - 20 -23.884488550391008; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -47.425170065295866 2 -50.847426602078393 - 4 -47.425170065295866 7 -47.425170065295866 16 -47.425170065295866 19 -48.639053402913603 - 20 -48.184556498320411; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -15.059620758260801 2 -16.248026693665089 - 4 -15.059620758260801 7 -15.059620758260801 16 -15.059620758260801 19 -11.299337016217571 - 20 11.991848508498084; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; - setAttr -s 8 ".kot[1:7]" 5 5 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9808213950621774 2 1.9808213950621776 - 4 1.9808213950621785 8 1.9808213950621805 12 1.980821395062182 16 1.9808213950621867 - 19 1.9808213950621898 20 1.9808213950621909; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 18.41992256503119 2 17.5648042732577 - 4 19.662864340591319 8 22.465004485504792 12 16.444893931989601 16 22.519284760552775 - 19 17.522230344830156 20 17.859988542372403; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.39740898729022 2 31.096571683529532 - 4 36.8657521678211 8 52.050851690712953 12 67.170375289917047 16 83.777913253213256 - 19 96.110338887997557 20 100.30869317838135; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 67.201049905350132 2 73.127573997605538 - 4 59.548287678704689 8 67.201049905350132 12 67.201049905350132 16 67.201049905350132 - 19 67.201049905350132 20 67.201049905350132; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 -12.20531815264818 4 -18.389573434446515 - 8 0 12 0 16 0 19 0 20 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.426073875550391 2 12.856973257781958 - 4 10.19397623384255 8 7.426073875550391 12 7.426073875550391 16 7.426073875550391 - 19 7.426073875550391 20 7.426073875550391; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.3610577639827144 2 -0.21285352564148119 - 5.7960000000000003 3.5485029363551686 9.2360000000000007 1.3924894832037882 - 14 -3.8248141218513645 19 -0.21285352564148119 21 2.8197115728311255; - setAttr -s 7 ".kit[5:6]" 1 9; - setAttr -s 7 ".kot[5:6]" 1 9; - setAttr -s 7 ".kix[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".kiy[5:6]" 0.99956315755844116 0.999622642993927; - setAttr -s 7 ".kox[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".koy[5:6]" 0.99956315755844116 0.999622642993927; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.27858988479459218 2 0.15078676416754505 - 3 0.041071720760699121 5 -0.12734812175584798 11 0.01615418026612319 14 0.50054018883462204 - 19 0.15078676416754505 21 0.01581159374970395; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.039992513696998876 2 0.15149042747921673 - 3 0.38885909572774768 5 0.81318111183904007 11 0.47178511368290149 14 -0.68058277559896596 - 19 0.15149042747921673 21 0.6807047568788458; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 0.90991990467137285 6 0.757413731437375 - 11 0.52631001515514408 14 0.17989662655130284 16 0.11086142298673962 19 0.90991990467137285; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1.6840963091226424 6 1.9921588651806885 - 11 2.376954893450355 14 2.6063840737414372 16 2.5942005418897831 19 1.6840963091226424; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 2.8509277672757398 6 2.6074946383461919 - 11 2.2942978244046901 14 2.0606653100128796 16 2.0534195118150946 19 2.8509277672757398; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -82.189303625215842 6 -104.37729528867425 - 11 -92.006962071167038 14 -104.30491760011213 16 -98.611645848609228 19 -82.189303625215842; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 32.936642853707767 6 -8.8441659435333211 - 11 -23.718949300073728 14 -13.739625821068813 16 0.073490689192853564 19 - 32.936642853707767; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -9.2450492652573306 6 -11.190509011262176 - 11 -15.571971397215279 14 -18.399796932359234 16 -15.14081226122182 19 -9.2450492652573306; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; - setAttr -s 7 ".kot[1:6]" 5 5 5 5 5 9; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0 2 0 7 0 11 0 15 0 19 0 - 21.972000000000001 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 2.3128351505039433 2 2.3128351505039433 - 7 2.3128351505039433 11 2.3128351505039433 15 2.3128351505039433 19 2.3128351505039433 - 21.972000000000001 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0.23421866920666501 2 0.23421866920666501 - 7 0.23421866920666501 11 0.23421866920666501 15 0.23421866920666501 19 0.23421866920666501 - 21.972000000000001 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 18.015821706774922 2 7 7 - 17.885785658953552 11 7 15 17.865328849758896 19 7 21.972000000000001 17.767020748470053; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 -20.871491789318089 2 -26.903356467361473 - 7 6.6740813894110849 11 26 15 -2.3802552171770213 19 -26.903356467361473 - 21.972000000000001 -13.498742838462716; - setAttr -s 7 ".kit[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kot[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kix[2:6]" 0.31150621175765991 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".kiy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; - setAttr -s 7 ".kox[2:6]" 0.3115062415599823 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".koy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -1.3720000000000001 7.6978127730792556 - 2 15.011069830747704 7 0.81964143355547092 11 5.6889805773011233 15 1.2715285190009615 - 19 15.011069830747704 21.972000000000001 16.516055040920126; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0.27427147149852044 5 0.27427147149852044 - 8 0.27427147149852044 11 0.27427147149852044 19 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.1074984126668126 5 -1.1074984126668126 - 8 -1.1074984126668126 11 -1.1074984126668126 19 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.642626684874722 5 -1.642626684874722 - 8 -1.642626684874722 11 -1.642626684874722 19 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -72.192682186483722 5 -112.43723771647277 - 8 -140.9476176021825 11 -76.320044575450154 19 -72.192682186483722; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -0.2742786288673521 8 -0.2742786288673521 - 12 -0.2742786288673521 16 -0.2742786288673521 19 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.1075115373407667 8 -1.1075115373407667 - 12 -1.1075115373407667 16 -1.1075115373407667 19 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.6426166407301896 8 -1.6426166407301896 - 12 -1.6426166407301896 16 -1.6426166407301896 19 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 57.295779513082337 8 46.221739108863801 - 12 83.651838089100195 16 124.90479933851947 19 57.295779513082337; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 1 4 1 5 1 6 0 9 0 10 0 11 1; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 0 4 0.60000000000000009 5 1 6 - 0.30000000000000004 9 0.046875 10 0 11 0; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 1 9 1 12 1 14 0 17 0 19 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 0 9 0 12 1 14 0 17 0 19 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 8 1 12 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -66.817792973155349 8 -117.76998860514637 - 12 -58.717593899130961 19 -66.817792973155349; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -49.477141044160646 8 -45.114889989798428 - 12 -58.488201638849723 19 -49.477141044160646; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -52.341476887309149 8 -22.64196747141678 - 12 -76.449769012401859 19 -52.341476887309149; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 10 1 14 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -168.75212351198743 10 -142.34379908236403 - 14 -91.772226065525047 19 -168.75212351198743; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 44.488737867426309 10 11.646024816259962 - 14 57.8461210256567 19 44.488737867426309; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -70.747288710930945 10 -54.074322568995257 - 14 -28.519478878489718 19 -70.747288710930945; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.90858890976581275 7 -3.7621162796982501 - 14 0.3657111927859622 16 -0.5854119341237376 19 -0.90858890976581275; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 6.2382713968077237 7 5.3887456806949574 - 14 6.0204513845034606 16 5.8835786026344072 19 6.2382713968077237; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.55501859990651525 7 1.684897371141969 - 14 -0.55708239243809732 16 2.3929863357066576 19 -0.55501859990651525; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -22.350064437213423 7 -13.094561677764091 - 14 -16.423765740015508 16 -18.438399824774098 19 -22.350064437213423; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -10.303773027856268 7 6.151404343053847 - 14 8.9343731574279008 16 7.5138197933918374 19 -10.303773027856268; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 8.8115085199100047 7 22.517921127381236 - 14 29.420970529265055 16 16.267284651382163 19 8.8115085199100047; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 6.7758528420198658 16 6.7758528420198658 - 19 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9388939039072284e-018 16 - -6.9388939039072284e-018 19 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -9.5120444723942321e-016 16 - -9.5120444723942321e-016 19 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -12.784757077400341 16 -91.730384948739413 - 19 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 3.2695897469829736 16 3.2695897469829762 - 19 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9162979482121409 16 -6.9162979482121507 - 19 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0.74525677667777757 6 0.74525677667777757 - 11 0.74525677667777757 15 0.74525677667777757 19 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1.8072476834435935 6 1.8072476834435935 - 11 1.8072476834435935 15 1.8072476834435935 19 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 13.355267980117441 11 0 15 - 7.2929987411270378 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -select -ne :time1; - setAttr ".o" 15; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 56.887248082175496 -8.7962964656502608e-015 - -16.265492054563058 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; - setAttr ".r" -type "double3" -66.065354836318264 28.775852580156471 -91.471856426984459 ; - setAttr ".twi" 217.7239621497128; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_place2dTexture1.mv" "IMP_file1.mv"; -connectAttr "IMP_place2dTexture1.vt1" "IMP_file1.vt1"; -connectAttr "IMP_place2dTexture1.vt2" "IMP_file1.vt2"; -connectAttr "IMP_place2dTexture1.vt3" "IMP_file1.vt3"; -connectAttr "IMP_place2dTexture1.vc1" "IMP_file1.vc1"; -connectAttr "IMP_leg_place2dTexture1.mv" "IMP_leg_file1.mv"; -connectAttr "IMP_leg_place2dTexture1.vt1" "IMP_leg_file1.vt1"; -connectAttr "IMP_leg_place2dTexture1.vt2" "IMP_leg_file1.vt2"; -connectAttr "IMP_leg_place2dTexture1.vt3" "IMP_leg_file1.vt3"; -connectAttr "IMP_leg_place2dTexture1.vc1" "IMP_leg_file1.vc1"; -connectAttr "IMP_place2dTexture2.mv" "IMP_file2.mv"; -connectAttr "IMP_place2dTexture2.vt1" "IMP_file2.vt1"; -connectAttr "IMP_place2dTexture2.vt2" "IMP_file2.vt2"; -connectAttr "IMP_place2dTexture2.vt3" "IMP_file2.vt3"; -connectAttr "IMP_place2dTexture2.vc1" "IMP_file2.vc1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.mv" "IMP_ZOMBIE1_file1.mv"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt1" "IMP_ZOMBIE1_file1.vt1"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt2" "IMP_ZOMBIE1_file1.vt2"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vt3" "IMP_ZOMBIE1_file1.vt3"; -connectAttr "IMP_ZOMBIE1_place2dTexture1.vc1" "IMP_ZOMBIE1_file1.vc1"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of pain_ruparm_on4.ma diff --git a/base/models/monsters/imp/animation/cycles/range1.ma b/base/models/monsters/imp/animation/cycles/range1.ma deleted file mode 100644 index adb9f0797..000000000 --- a/base/models/monsters/imp/animation/cycles/range1.ma +++ /dev/null @@ -1,3938 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:21 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: range1.ma -//Last modified: Thu, May 09, 2002 02:43:42 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 213.43128985575231 153.72606589318832 168.40544170188159 ; - setAttr ".r" -type "double3" -24.930108912366684 -1388.5999999998182 -2.5490132216631201e-015 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 222.31470662531549; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 48.009446329610896 73.293644119483716 42.595205044249596 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 147.42200685729316; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 59.610932956686291 34.976017359279254 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 202.0596881513782; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 99.999999999999986 32.737409329949301 -4.7113895455624615 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 262.90780108329994; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 21 1 29 1 32.200000000000003 - 1 33.616 1; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 21 1 29 1 32.200000000000003 - 1 33.616 1; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 21 1 29 1 32.200000000000003 - 1 33.616 1; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 -38.367703938541368 21 -38.367703938541368 - 29 -38.367703938541368 32.200000000000003 -38.36770393854141 33.616 -38.36770393854141; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 13 0 21 0 29 -22.261750778216175 - 32.200000000000003 9.6638522443422588 33.616 0 48.200000000000003 0; - setAttr -s 6 ".kit[2:5]" 9 3 3 3; - setAttr -s 6 ".kot[2:5]" 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 0 21 0 29 0 32.200000000000003 - 0 33.616 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 -8.52286618097577 21 -8.52286618097577 - 29 -8.5228661809757718 32.200000000000003 -8.5228661809757842 33.616 -8.5228661809757842; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 0 21 0 29 8.6414253885234693 - 32.200000000000003 0 33.616 0; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 -4.579364761070849 21 -4.579364761070849 - 29 29.058010331813129 32.200000000000003 55.894887262743886 33.616 55.894887262743886; - setAttr -s 5 ".kit[2:4]" 9 3 3; - setAttr -s 5 ".kot[2:4]" 9 3 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 21 1 29 1 32.200000000000003 - 1 33.616 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 15 1 37.36 - 1 45 1 48.200000000000003 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 15 1 37.36 - 1 45 1 48.200000000000003 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 15 1 37.36 - 1 45 1 48.200000000000003 1; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 36.23707061730854 15 36.23707061730854 37.36 36.237070617308525 - 45 36.237070617308518 48.200000000000003 36.23707061730854; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 14.439669496646856 15 0 37.36 0.37406996600235581 45 -19.289764981099978 - 48.200000000000003 14.439669496646856; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 12.2 0 13 0 15 0 37.36 - 0 45 0 48.200000000000003 0; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 9.6873596619451892 15 9.6873596619451892 37.36 - 9.6873596619451892 45 9.6873596619451749 48.200000000000003 9.6873596619451749; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 15 0 37.36 0 45 6.5824344037117717 48.200000000000003 0; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 3 9 3; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 3 9 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 26.486563744388956 15 26.486563744388956 37.36 - 26.486563744388956 45 56.871344609681749 48.200000000000003 87.942743472173689; - setAttr -s 8 ".kit[3:7]" 3 3 3 9 3; - setAttr -s 8 ".kot[3:7]" 3 3 3 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 12.2 1 13 1 15 1 37.36 - 1 45 1 48.200000000000003 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 40.648686302336252 8.2 43.454363644344404 - 12.2 41.286340243701709 13 40.946343146808175 21 39.022517460717204 29 44.205709090509586 - 32.200000000000003 44.072979267366563 34 41.162424230526909 37.36 37.460416595508704 - 41 38.968831226805413 45 44.15245041935723 48.200000000000003 40.928118565561554 - 61 38.875239605378951; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 14.373557394032371 21 17.766738474032827 29 35.34397057886077 - 32.200000000000003 40.693841374169345 34 41.781432257732639 37.36 54.635065841240319 - 41 64.005434973554088 45 69.592519060653558 48.200000000000003 76.398879176777299 - 61 80.803578047487491; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 0.65147019540262718 21 3.4389526704134474 - 29 1.9932938451333648 32.200000000000003 0.52245208391873188 34 -0.16284641805594532 - 37.36 -0.96093906669208939 41 -2.8692155288485908 45 -4.8012869768196564 - 48.200000000000003 0.51611782181851806 61 0.81152919952064195; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 21 1 29 1 - 32.200000000000003 1 34 1 37.36 1 41 1 45 1 48.200000000000003 1 61 1; - setAttr -s 13 ".kot[5:12]" 5 5 5 5 5 5 9 - 9; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 21 1 29 1 - 32.200000000000003 1 34 1 37.36 1 41 1 45 1 48.200000000000003 1 61 1; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 21 1 29 1 - 32.200000000000003 1 34 1 37.36 1 41 1 45 1 48.200000000000003 1 61 1; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 12.2 1 13 1 21 1 29 1 - 32.200000000000003 1 34 1 37.36 1 41 1 45 1 48.200000000000003 1 61 1; - setAttr -s 13 ".kit[5:12]" 3 9 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 9 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 -4.1657930308134645 20.2 -1.6735805890538134 28.2 - 6.6566912693983946 31.56 6.1330193887268454 36.864 0.24039650864424209 48.200000000000003 - -4.1657930308134645; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287 20.2 0.21813466524646566 28.2 - -0.86763382127902322 31.56 -0.42972806484138226 36.864 -0.031333305538134112 - 48.200000000000003 0.54296989172209287; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 -7.4542171015494922 20.2 0 28.2 5.0790319675705673 - 31.56 6.7230875260072231 36.864 0 48.200000000000003 -7.4542171015494922; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 36.864 - 2.3128351505039433 48.200000000000003 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 36.864 0.23421866920666501 48.200000000000003 0.23421866920666501; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 0 13 0 20.2 0 28.2 0 36.864 - 0 48.200000000000003 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581372 20.2 7.8247378664801399 28.2 -0.56667192682884493 36.864 - 0.57720421748491901 48.200000000000003 8.7951795972581372; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.660431799163181 8.2 13.751352433260992 - 13 13.892774724407374 20.2 13.751352433260992 28.2 13.000667896194788 36.864 - 12.790622953496632 48.200000000000003 13.892774724407374; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8.2 22.776694843251629 13 26.888910802325626 - 20.2 22.776694843251629 28.2 -13.027357639203586 36.864 -8.1143097424545108 - 48.200000000000003 26.888910802325626; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857 19.4 398.36837297080183 25.800000000000001 405.87328549495959 - 31.56 379.83372596750263 33.8 353.57391219228805 36.864 386.50793879591424 - 39.4 409.82129011423473 42.6 411.22237565094844 48.200000000000003 389.49637174592857; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099 19.4 -12.600779850050984 25.800000000000001 -20.832460906370112 - 31.56 -21.817439286719896 33.8 8.3242847484057965 36.864 10.617569482988788 - 39.4 16.213333110155673 42.6 8.0699656443412024 48.200000000000003 -14.641906192173099; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167 19.4 2.1331084602003276 25.800000000000001 -6.4884256527418813 - 31.56 -13.151834079049511 33.8 -24.88323729372328 36.864 -20.63225115983429 - 39.4 8.390824613411958 42.6 18.506365469201853 48.200000000000003 -0.44667534838541167; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 31.56 5.6268319407172029 33.8 5.6268319407172029 36.864 5.6268319407172029 - 39.4 5.6268319407172029 42.6 5.6268319407172029 48.200000000000003 5.6268319407172029; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 31.56 -2.1098668596606802 33.8 -2.1098668596606802 36.864 -2.1098668596606802 - 39.4 -2.1098668596606802 42.6 -2.1098668596606802 48.200000000000003 -2.1098668596606802; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 31.56 0 33.8 0 36.864 0 39.4 0 42.6 0 48.200000000000003 0; - setAttr -s 11 ".kit[3:10]" 3 3 3 9 3 9 3 - 9; - setAttr -s 11 ".kot[3:10]" 3 3 3 9 3 9 3 - 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1; - setAttr -s 11 ".kot[3:10]" 5 5 5 5 5 5 5 - 9; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.280000000000001 5.7384771804188404 43.4 5.7384771804188404 48.200000000000003 - 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.280000000000001 2.0494561358638701 43.4 2.0494561358638701 48.200000000000003 - 2.0494561358638701; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.280000000000001 0 43.4 0 48.200000000000003 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.280000000000001 16.052055400530755 43.4 30.358488909126763 48.200000000000003 - 37.874152024707215; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.280000000000001 11.52461344822842 43.4 -2.1187003779812748 48.200000000000003 - -14.364226384227051; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.280000000000001 -25.97088988767895 43.4 -26.687875434482198 48.200000000000003 - -36.863333637497242; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -8.7397788191085439 21 -8.7397788191085439 29 - -14.46559177801103 33 -14.46559177801103 35.492 -5.551383374574181 41.8 -39.825254035125468 - 48.200000000000003 -8.7397788191085439; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 7.3330119448673576 21 7.3330119448673576 29 27.409635153347722 - 33 27.409635153347722 35.492 10.151298835483475 41.8 -13.161176261445801 - 48.200000000000003 7.3330119448673576; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -16.154270916852411 21 -16.154270916852411 29 - -7.2330610293733786 33 -7.2330610293733786 35.492 -23.366089781757765 41.8 - -23.114348107291107 48.200000000000003 -16.154270916852411; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 21 2.6456615572060826 29 2.6456615572060826 - 33 2.6456615572060826 35.492 2.6456615572060826 41.8 2.6456615572060826 48.200000000000003 - 2.6456615572060826; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 21 1.9935618776130362 29 1.9935618776130362 - 33 1.9935618776130362 35.492 1.9935618776130362 41.8 1.9935618776130362 48.200000000000003 - 1.9935618776130362; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 11.4 0 13 0 21 0 29 0 - 33 0 35.492 0 41.8 0 48.200000000000003 0; - setAttr -s 10 ".kit[0:9]" 9 9 9 3 3 3 3 - 3 3 3; - setAttr -s 10 ".kot[0:9]" 9 9 9 3 3 3 3 - 3 3 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1; - setAttr -s 10 ".kot[3:9]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 12.412879749935719 13 12.412879749935719 - 16 12.412879749935719 25 12.412879749935719 30.600000000000001 12.412879749935719 - 34.876 12.412879749935719 41.8 12.412879749935719 48.200000000000003 12.412879749935719; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7286993982861674 13 -6.7286993982861674 - 16 -6.7286993982861674 25 -6.7286993982861674 30.600000000000001 -6.7286993982861674 - 34.876 -6.7286993982861674 41.8 -6.7286993982861674 48.200000000000003 -6.7286993982861674; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.868763862603668 13 -3.868763862603668 - 16 -3.868763862603668 25 -3.868763862603668 30.600000000000001 -3.868763862603668 - 34.876 -3.868763862603668 41.8 -3.868763862603668 48.200000000000003 -3.868763862603668; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 80.239686562403847 13 80.239686562403847 - 16 54.077927468358183 25 55.762517552242812 30.600000000000001 55.762517552242812 - 34.876 110.97588549878063 41.8 19.895885498785315 48.200000000000003 80.239686562403847; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.8978517871634404 13 5.8978517871634404 - 16 5.8978517871634288 25 5.8978517871634368 30.600000000000001 5.8978517871634368 - 34.876 5.8978517871634333 41.8 5.8978517871634288 48.200000000000003 5.8978517871634404; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.92545182592768849 13 0.92545182592768849 - 16 0.92545182592768971 25 0.92545182592768871 30.600000000000001 0.92545182592768871 - 34.876 0.92545182592769071 41.8 0.92545182592769171 48.200000000000003 0.92545182592768849; - setAttr -s 8 ".kit[0:7]" 9 3 9 3 3 3 3 - 3; - setAttr -s 8 ".kot[0:7]" 9 3 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1; - setAttr -s 8 ".kot[1:7]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 16 -12.41287000000041 25 -12.41287000000041 33.616 - -12.41287000000041 37.348 -12.41287000000041 44.200000000000003 -12.41287000000041 - 48.200000000000003 -12.41287000000041; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 16 -6.7285999999993047 25 -6.7285999999993047 33.616 - -6.7285999999993047 37.348 -6.7285999999993047 44.200000000000003 -6.7285999999993047 - 48.200000000000003 -6.7285999999993047; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 16 -3.8687599999999316 25 -3.8687599999999316 33.616 - -3.8687599999999316 37.348 -3.8687599999999316 44.200000000000003 -3.8687599999999316 - 48.200000000000003 -3.8687599999999316; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 58.099612817676174 10.6 82.316033184538099 - 13 82.316033184538099 16 64.08197397813943 25 97.683090386840206 33.616 53.821890365126315 - 37.348 -10.072402928647007 44.200000000000003 45.282566297638787 48.200000000000003 - 82.316033184538099; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 10.6 0 13 0 16 0 25 0 33.616 - 0 37.348 0 44.200000000000003 0 48.200000000000003 0; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 10.6 0 13 0 16 0 25 0 33.616 - 0 37.348 0 44.200000000000003 0 48.200000000000003 0; - setAttr -s 9 ".kit[0:8]" 9 9 3 9 3 3 3 - 3 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 9 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1; - setAttr -s 9 ".kot[2:8]" 5 5 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 16 -max 48 -ast 16 -aet 48 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 21 0 29 -14.694793212242772 - 32.200000000000003 -22.317950345874792 34 -19.074728949341196 37.36 -11.713338680642 - 41 4.2476420800354884 45 0 48.200000000000003 0 61 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 9 9; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 21 0 29 -1.987846675914698e-016 - 32.200000000000003 -12.461609460487022 34 2.9737603694704617 37.36 32.154520226133918 - 41 19.906095238845598 45 0 48.200000000000003 0 61 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 9 9; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 21 0 29 -10.800000000000438 - 32.200000000000003 -11.176041601674743 34 -7.9659487865846152 37.36 -2.4417633521739086 - 41 -1.5116373460888639 45 0 48.200000000000003 0 61 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 9 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 1 21 1 30.600000000000001 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 6.7758528420198658 21 6.7758528420198658 - 30.600000000000001 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 -6.9388939039072284e-018 21 - -6.9388939039072284e-018 30.600000000000001 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 -9.5120444723942321e-016 21 - -9.5120444723942321e-016 30.600000000000001 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 -12.784757077400341 21 -37.624757077399877 - 30.600000000000001 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 3.2695897469829736 21 3.2695897469829753 - 30.600000000000001 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 -6.9162979482121409 21 -6.9162979482121507 - 30.600000000000001 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 1 21 1 30.600000000000001 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 1 21 1 30.600000000000001 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 15 1 21 1 30.600000000000001 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 1 38.6 1 44.200000000000003 - 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 6.7758528420198658 38.6 6.7758528420198658 - 44.200000000000003 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 -6.9388939039072284e-018 38.6 - -6.9388939039072284e-018 44.200000000000003 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 -9.5120444723942321e-016 38.6 - -9.5120444723942321e-016 44.200000000000003 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 -2.1064832569487142 38.6 -26.31570375597023 - 44.200000000000003 0; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 0.36693656610454173 38.6 0.36693656610454845 - 44.200000000000003 0.36693656610454845; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 12.728045273286209 38.6 12.728045273286213 - 44.200000000000003 12.728045273286213; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 1 38.6 1 44.200000000000003 - 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 1 38.6 1 44.200000000000003 - 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 33.8 1 38.6 1 44.200000000000003 - 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 48.200000000000003 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -5.8807954640291324 16 8.5156304394485858 - 26 -3.3842862675489864 32.200000000000003 59.43985759115133 34.876 67.718224866084512 - 35.492 49.782078750379959 36.112 2.9566598552920471 37.36 -14.325185707358159 - 42 -21.775397049639 48.200000000000003 -5.8807954640291324; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.4977373448908193 16 -41.436655454713687 - 26 24.158999191717797 32.200000000000003 -6.4530174823216635 34.876 -162.88377979146023 - 35.492 -104.91854193010487 36.112 -70.19765518443279 37.36 -90.249964522452984 - 42 -73.633745821089818 48.200000000000003 -3.4977373448908193; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 22.979007009556593 16 16.360110645449957 - 26 27.448763083984442 32.200000000000003 -22.019983593182211 34.876 -100.60191722424253 - 35.492 -55.224743769963553 36.112 -25.723945146099769 37.36 -33.011917662712847 - 42 7.8337284132215155 48.200000000000003 22.979007009556593; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.0821100000000254 16 -3.0821100000000254 - 26 -3.0821100000000254 32.200000000000003 -3.0821100000000254 34.876 -3.0821100000000254 - 35.492 -3.0821100000000254 36.112 -3.0821100000000254 37.36 -3.0821100000000254 - 42 -3.0821100000000254 48.200000000000003 -3.0821100000000254; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 2.1192000000001707 16 2.1192000000001707 - 26 2.1192000000001707 32.200000000000003 2.1192000000001707 34.876 2.1192000000001707 - 35.492 2.1192000000001707 36.112 2.1192000000001707 37.36 2.1192000000001707 - 42 2.1192000000001707 48.200000000000003 2.1192000000001707; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.3867499999998705 16 -3.3867499999998705 - 26 -3.3867499999998705 32.200000000000003 -3.3867499999998705 34.876 -3.3867499999998705 - 35.492 -3.3867499999998705 36.112 -3.3867499999998705 37.36 -3.3867499999998705 - 42 -3.3867499999998705 48.200000000000003 -3.3867499999998705; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 48.200000000000003 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 48.200000000000003 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 48.200000000000003 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 3; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 1 16 1 27 1 31.4 1 35.492 1 - 40.200000000000003 1 48.200000000000003 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 3.3867545965885748 16 3.3867545965885748 - 27 3.3867545965885748 31.4 3.3867545965885748 35.492 3.3867545965885748 40.200000000000003 - 3.3867545965885748 48.200000000000003 3.3867545965885748; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 2.1192573708760349 16 2.1192573708760349 - 27 2.1192573708760349 31.4 2.1192573708760349 35.492 2.1192573708760349 40.200000000000003 - 2.1192573708760349 48.200000000000003 2.1192573708760349; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 -3.0821078932592165 16 -3.0821078932592165 - 27 -3.0821078932592165 31.4 -3.0821078932592165 35.492 -3.0821078932592165 - 40.200000000000003 -3.0821078932592165 48.200000000000003 -3.0821078932592165; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 0 16 75.312657822261826 27 59.720924156132824 - 31.4 59.720924156132824 35.492 -20.164660612627923 40.200000000000003 6.6887517907386203 - 48.200000000000003 8.6707069395922574; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 0 16 11.771191120276887 27 0 - 31.4 0 35.492 -39.979903022931879 40.200000000000003 -41.519786912787602 - 48.200000000000003 -29.177569194225612; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 -6.7129388973255946 16 14.730782984337566 - 27 -6.7129388973256088 31.4 -6.7129388973256088 35.492 -19.399360970102574 - 40.200000000000003 -48.392671971163551 48.200000000000003 -24.635006331828023; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 1 16 1 27 1 31.4 1 35.492 1 - 40.200000000000003 1 48.200000000000003 1; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 1 16 1 27 1 31.4 1 35.492 1 - 40.200000000000003 1 48.200000000000003 1; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 13 1 16 1 27 1 31.4 1 35.492 1 - 40.200000000000003 1 48.200000000000003 1; - setAttr -s 7 ".kit[1:6]" 9 3 3 3 9 9; - setAttr -s 7 ".kot[1:6]" 9 3 3 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1 29 1 35 1 40 1 48 1 53 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 -2.5294371750177831 29 -2.5294371750177831 - 35 -2.5294371750177831 40 -2.5294371750177831 48 -2.5294371750177831 53 -2.5294371750177831; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 13.481673551673362 29 13.481673551673362 - 35 13.481673551673362 40 13.481673551673362 48 13.481673551673362 53 13.481673551673362; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 -0.26635088939205875 29 -0.26635088939205875 - 35 -0.26635088939205875 40 -0.26635088939205875 48 -0.26635088939205875 53 - -0.26635088939205875; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 97.855881494193042 29 141.20709981379272 - 35 152.96344280164271 40 184.89719599566124 48 103.08313836415496 53 123.88225034018718; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 148.48318103992199 29 64.064019952206479 - 35 139.72900819152471 40 155.90140465165601 48 120.9730461925711 53 126.91688172103902; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 185.52482540053091 29 252.95011708695623 - 35 248.32318073773087 40 261.12614011805363 48 249.82792170870755 53 245.70418815060009; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 48 15.445123296459185 53 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 48 15.445123296459185 53 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 48 15.445123296459185 53 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 0 35 0 40 0 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 1 35 1 40 0.19999999999999996 - 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 0 35 0 40 0 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 0 35 0 40 0 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 0 35 0 40 0 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 29 0 35 0 40 0 48 0 53 0; - setAttr -s 6 ".kit[0:5]" 9 3 3 3 3 3; - setAttr -s 6 ".kot[0:5]" 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 1 25 1 26 1 27 1 28 1 29 1 34 - 1 36 1 39 1 44 1 48 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -7.5406347832540632e-013 25 - -7.5406347832540632e-013 26 -7.5406347832540632e-013 27 -7.5406347832540632e-013 - 28 -7.5406347832540632e-013 29 -7.5406347832540632e-013 34 -7.5406347832540632e-013 - 36 -7.5406347832540632e-013 39 -7.5406347832540632e-013 44 -7.5406347832540632e-013 - 48 -7.5406347832540632e-013; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 13.71946295727715 25 13.71946295727715 - 26 13.71946295727715 27 13.71946295727715 28 13.71946295727715 29 13.71946295727715 - 34 13.71946295727715 36 13.71946295727715 39 13.71946295727715 44 13.71946295727715 - 48 13.71946295727715; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -3.0908609005564358e-013 25 - -3.0908609005564358e-013 26 -3.0908609005564358e-013 27 -3.0908609005564358e-013 - 28 -3.0908609005564358e-013 29 -3.0908609005564358e-013 34 -3.0908609005564358e-013 - 36 -3.0908609005564358e-013 39 -3.0908609005564358e-013 44 -3.0908609005564358e-013 - 48 -3.0908609005564358e-013; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 260.01204204600725 25 371.81698241758346 - 26 341.72938901265888 27 316.91500938239909 28 -56.429127733094752 29 -63.128460417457674 - 34 77.739160914831501 36 253.58951914813761 39 71.559257816680997 44 -0.52444715856921864 - 48 13.60685205589594; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -38.320908201910434 25 -54.351726169543703 - 26 -46.10431805179325 27 -56.310082641832359 28 -52.674300990047442 29 -70.10134924460381 - 34 -76.726154744596627 36 -51.959710397762237 39 -46.571202148179758 44 -56.835484376724843 - 48 -78.127995506301787; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -322.65738741293052 25 -421.93598632875813 - 26 -425.06390674275218 27 -383.14789382944997 28 -36.446894902195744 29 -6.8807221056785242 - 34 -173.86213662459591 36 -365.60209280718618 39 -116.68772684506173 44 -63.927976809723475 - 48 -119.06977740209733; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459183 25 15.445123296459183 - 26 15.445123296459183 27 15.445123296459183 28 15.445123296459183 29 15.445123296459183 - 34 15.445123296459183 36 15.445123296459183 39 15.445123296459183 44 15.445123296459183 - 48 15.445123296459183; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459185 25 15.445123296459185 - 26 15.445123296459185 27 15.445123296459185 28 15.445123296459185 29 15.445123296459185 - 34 15.445123296459185 36 15.445123296459185 39 15.445123296459185 44 15.445123296459185 - 48 15.445123296459185; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459181 25 15.445123296459181 - 26 15.445123296459181 27 15.445123296459181 28 15.445123296459181 29 15.445123296459181 - 34 15.445123296459181 36 15.445123296459181 39 15.445123296459181 44 15.445123296459181 - 48 15.445123296459181; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 48 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0.70000000000000007 25 0.70000000000000007 - 26 0.70000000000000007 27 0.70000000000000007 28 0.70000000000000007 29 0.70000000000000007 - 34 0.70000000000000007 36 0 39 0.158203125 44 0.5 48 0.5; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 48 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 1 39 0.68359375 44 0 48 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 48 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 48 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 3; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 3; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -1.4752837996356043 22 -1.3864483331337971 - 29 -1.865128947678026 35 -1.196221183104005; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -3.4429152318518517 22 -3.5176571193192414 - 29 -3.8281732756743612 35 -4.3171539839663167; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 4.6597910865832972 22 3.50938048508575 - 29 3.6017971266837443 35 6.7011525574960222; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -26.447332316722964 22 -26.447332316722964 - 29 -26.447332316722964 35 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -67.357715796337814 22 -67.357715796337814 - 29 -67.357715796337814 35 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 24.545813639883598 22 24.545813639883598 - 29 24.545813639883598 35 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -select -ne :time1; - setAttr ".o" 19; -select -ne :renderPartition; - setAttr -s 11 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 11 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_Rwing_meshShape3Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig5; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape5Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rmissile; - setAttr ".jo" -type "double3" 10.172609088116555 69.500974497559 0.32021133972216492 ; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".v" yes; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".s" -type "double3" 1 1 1 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of range1.ma diff --git a/base/models/monsters/imp/animation/cycles/range2.ma b/base/models/monsters/imp/animation/cycles/range2.ma deleted file mode 100644 index d36c09526..000000000 --- a/base/models/monsters/imp/animation/cycles/range2.ma +++ /dev/null @@ -1,2306 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:21 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: range2.ma -//Last modified: Mon, Mar 17, 2003 11:05:51 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -5.4257462930913078 67.68991687259151 263.76182240538532 ; - setAttr ".r" -type "double3" -5.138352729597246 5.4000000000002153 9.9835406865268895e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 238.64078118110282; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -5.456954712996982 62.631918016406615 3.9457092847660675 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" -1.433759302487335 40.592721706092917 180.39467984956417 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 196.7224762557926; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 151.59740109751749 36.570642988351061 85.991235134745722 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 296.45546053762138; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 5.157268050779404 64.595370499164162 73.888125873898332 ; - setAttr ".sp" -type "double3" 5.157268050779404 64.595370499164162 73.888125873898332 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -4.8432018369461876 7 -4.8432018369461876 - 15 -4.8432018369461876 18 -4.8432018369461876 22 -4.8432018369461876 31 -4.8432018369461876 - 35 -4.8432018369461876; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.6706592090743859 7 2.6706592090743859 - 15 2.6706592090743859 18 2.6706592090743859 22 2.6706592090743859 31 2.6706592090743859 - 35 2.6706592090743859; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.8591231689033729 7 -2.8591231689033729 - 15 -2.8591231689033729 18 -2.8591231689033729 22 -2.8591231689033729 31 -2.8591231689033729 - 35 -2.8591231689033729; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.153193350797192 7 19.366665065772043 - 15 2.9513556865618322 18 49.389038537638172 22 26.6012451039323 31 36.28829725017296 - 35 38.654028644190106; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -68.199964176618579 7 -39.007790280771871 - 15 -14.204902125422128 18 -26.742656469169866 22 -39.561371151422748 31 -59.513949725540215 - 35 -52.624543789318707; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -17.348716601005805 7 20.39562875406293 - 15 -13.114511910458351 18 -93.834467382733592 22 -93.026189466042482 31 -67.923590668854629 - 35 -34.552109224820512; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.41287000000041 7 -12.41287000000041 - 15 -12.41287000000041 18 -12.41287000000041 28 -12.41287000000041 35 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7285999999993047 7 -6.7285999999993047 - 15 -6.7285999999993047 18 -6.7285999999993047 28 -6.7285999999993047 35 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8687599999999316 7 -3.8687599999999316 - 15 -3.8687599999999316 18 -3.8687599999999316 28 -3.8687599999999316 35 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 68.341863881747486 7 107.50790256458413 - 15 107.50790256458413 18 -29.563777677169 28 8.7628874276478896 35 55.901074574063429; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 3.3867545965885748 7 3.3867545965885748 - 15 3.3867545965885748 18 3.3867545965885748 22 3.3867545965885748 31 3.3867545965885748 - 35 3.3867545965885748; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.1192573708760349 7 2.1192573708760349 - 15 2.1192573708760349 18 2.1192573708760349 22 2.1192573708760349 31 2.1192573708760349 - 35 2.1192573708760349; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821078932592165 7 -3.0821078932592165 - 15 -3.0821078932592165 18 -3.0821078932592165 22 -3.0821078932592165 31 -3.0821078932592165 - 35 -3.0821078932592165; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 67.92474321130986 15 32.847729424280139 - 18 75.626129379022643 22 61.38936549601533 31 11.704011283183505 35 -40.972043253708904; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 43.89702540380781 7 25.702288985807424 - 15 37.585931050197537 18 59.085447479434151 22 29.02663458264017 31 60.875634605755025 - 35 40.982540837486624; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.1263873323303013 7 30.8527991373888 - 15 2.5005120654728477 18 25.420312609661735 22 14.942255526856952 31 -6.8759201153211693 - 35 -41.173243464098263; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 22 1 31 1 35 - 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 12.412879749935719 7 12.412879749935719 - 15 12.412879749935719 18 12.412879749935719 28 12.412879749935719 35 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7286993982861674 7 -6.7286993982861674 - 15 -6.7286993982861674 18 -6.7286993982861674 28 -6.7286993982861674 35 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.868763862603668 7 -3.868763862603668 - 15 -3.868763862603668 18 -3.868763862603668 28 -3.868763862603668 35 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 76.7810959838569 7 92.333317131983691 - 15 105.5502438083217 18 8.2386877555233582 28 59.38605602640331 35 78.378154483425135; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 1.9839573990326234; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 -0.89539737695748534; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 15 1 19 1 25 1 30 1 35 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 15 -1.1368683772161604e-014 - 19 5.3732720049169256 25 -5.6201782407884391 30 -0.0086437501176720166 35 - -1.303339470580636; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 39.956938881757473 8 29.717722158047295 - 15 28.135297755292093 19 41.731713063582347 25 38.917770744314566 30 36.248406861267092 - 35 35.802533988227843; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -9.102319805357757 8 5.9772539150154387 - 15 11.655365007254714 19 26.692696228859521 25 57.456419917827091 30 64.186743569694571 - 35 69.124079119838598; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 25.578234395771194 8 -18.701765604228807 - 15 8.8890870999044704 19 4.5262551966084441 25 32.289087099904471 30 34.458058444473686 - 35 32.289087099904471; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 15 0 19 0 25 0 30 0 35 - 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 15 0 19 0 25 0 30 0 35 - 0; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 15 1 19 1 25 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 15 1 19 1 25 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 15 1 19 1 25 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 23 1 30 1 35 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 15 0 18 0 23 0 30 0 35 - 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 7 5.6268319407172029 - 15 5.6268319407172029 18 5.6268319407172029 23 5.6268319407172029 30 5.6268319407172029 - 35 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 7 -2.1098668596606802 - 15 -2.1098668596606802 18 -2.1098668596606802 23 -2.1098668596606802 30 -2.1098668596606802 - 35 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 68.386896347780706 15 62.215446759285875 - 18 -41.882401229247932 23 -51.903128904596819 30 -14.619586337406801 35 -14.559935631107107; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 20.572061275655237 15 22.253596212904135 - 18 -15.489422602730667 23 -9.3906844336292661 30 6.7981241501420255 35 2.0818118868195024; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 40.623953640200867 15 23.796379207643891 - 18 -9.2160897457227815 23 9.2219179310380923 30 15.454597744550211 35 8.7902366827900842; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 23 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 23 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 23 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.7384771804188404 7 5.7384771804188404 - 15 5.7384771804188404 18 5.7384771804188404 28 5.7384771804188404 35 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 2.0494561358638701 7 2.0494561358638701 - 15 2.0494561358638701 18 2.0494561358638701 28 2.0494561358638701 35 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 24 1 30 1 35 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7 0 15 0 18 0 24 0 30 0 35 - 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.6456615572060826 7 2.6456615572060826 - 15 2.6456615572060826 18 2.6456615572060826 24 2.6456615572060826 30 2.6456615572060826 - 35 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.9935618776130362 7 1.9935618776130362 - 15 1.9935618776130362 18 1.9935618776130362 24 1.9935618776130362 30 1.9935618776130362 - 35 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -14.976401943903339 7 -62.022298258605268 - 15 0 18 33.170073113221548 24 -40.046068762160552 30 -45.459538806370681 - 35 -41.001542663337609; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.9450961262645556 7 -20.787862919385955 - 15 0 18 14.886886108179089 24 44.230987354572058 30 -14.036851211981002 35 - -7.0574107745566534; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -10.487566896628159 7 -9.2454901388145938 - 15 0 18 22.7124261720143 24 -13.665207623987754 30 3.1333038682472991 35 - -2.46052783471958; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 24 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 24 1 30 1 35 - 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7 1 15 1 18 1 24 1 30 1 35 - 1; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 5 -size 12 -divisions 5 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 35 -ast 1 -aet 35 "; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -7.5406347832540632e-013 7 -7.5406347832540632e-013 - 15 -7.5406347832540632e-013 18 -7.5406347832540632e-013 28 -7.5406347832540632e-013 - 35 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.71946295727715 7 13.71946295727715 - 15 13.71946295727715 18 13.71946295727715 28 13.71946295727715 35 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.0908609005564358e-013 7 -3.0908609005564358e-013 - 15 -3.0908609005564358e-013 18 -3.0908609005564358e-013 28 -3.0908609005564358e-013 - 35 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 77.739160914831501 7 -48.32331881351444 - 15 115.55012539823768 18 40.319837049238032 28 77.739160914831501 35 261.91239950065847; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -76.726154744596627 7 -41.131317558950172 - 15 -59.093342360358207 18 -41.220589552059231 28 -76.726154744596627 35 -67.598995297218778; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -173.86213662459591 7 0.033490047665410541 - 15 -167.62311447021816 18 -172.3476096028605 28 -173.86213662459591 35 -338.28561031790707; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459183 7 15.445123296459183 - 15 15.445123296459183 18 15.445123296459183 28 15.445123296459183 35 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 7 15.445123296459185 - 15 15.445123296459185 18 15.445123296459185 28 15.445123296459185 35 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459181 7 15.445123296459181 - 15 15.445123296459181 18 15.445123296459181 28 15.445123296459181 35 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 1 15 1 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 1 35 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 1 28 0 35 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 7 1 15 1 18 1 28 1 35 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.5294371750177831 7 -2.5294371750177831 - 15 -2.5294371750177831 18 -2.5294371750177831 28 -2.5294371750177831 35 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.481673551673362 7 13.481673551673362 - 15 13.481673551673362 18 13.481673551673362 28 13.481673551673362 35 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.26635088939205875 7 -0.26635088939205875 - 15 -0.26635088939205875 18 -0.26635088939205875 28 -0.26635088939205875 35 - -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 178.94205136167187 7 27.744241775064992 - 15 -64.279894211431426 18 190.31347224676995 28 64.540364479304387 35 65.910858257957386; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 67.368426950553314 7 68.989964869117813 - 15 49.286692098962675 18 68.669373974321047 28 56.625614027032313 35 53.583363911750702; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 213.59829072099083 7 93.139107033993611 - 15 34.04610635206523 18 343.57990239354734 28 203.78301631379659 35 181.53360810780703; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 7 15.445123296459185 - 15 15.445123296459185 18 15.445123296459185 28 15.445123296459185 35 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 7 15.445123296459185 - 15 15.445123296459185 18 15.445123296459185 28 15.445123296459185 35 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 7 15.445123296459185 - 15 15.445123296459185 18 15.445123296459185 28 15.445123296459185 35 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 1 15 1 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 1 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 1 28 0 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 7 0 15 0 18 0 28 0 35 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 19 1 22 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -7.3924057183505179 17 -7.3924057183505179 - 19 -7.3924057183505179 22 -7.3924057183505179; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.12533659468619246 17 0.12533659468619246 - 19 5.1439296388539031 22 0.12533659468619246; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -11.472787814522771 17 -11.472787814522771 - 19 9.9393048438657203 22 50.986434200109386; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.5224481147703117 17 2.5224481147703117 - 19 -19.132214932909505 22 2.5224481147703117; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.350375071499506 17 -3.350375071499506 - 19 -3.3503750714995073 22 -3.350375071499506; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -10.882927420172908 17 -10.882927420172908 - 19 -10.88292742017291 22 -10.882927420172908; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 19 1 22 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 19 1 22 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 17 1 19 1 22 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 19 1 23 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 7.1689522478599388 19 7.1689522478599388 - 23 7.1689522478599272 28 7.1689522478599388; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.50142173061260698 19 0.50142173061260698 - 23 17.163419853741008 28 0.50142173061260698; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.4072513127240764 19 5.4072513127240764 - 23 33.053136466741584 28 64.887792098640531; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.026563187903942138 19 -0.026563187903942138 - 23 -92.098736454101427 28 -0.026563187903942138; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.4307631628322328 19 3.4307631628322328 - 23 3.4307631628322297 28 3.4307631628322328; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 8.201702819722124 19 8.201702819722124 - 23 8.2017028197221293 28 8.201702819722124; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 19 1 23 1 28 1; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 19 1 23 1 28 1; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 19 1 23 1 28 1; - setAttr -s 4 ".kit[2:3]" 9 9; - setAttr -s 4 ".kot[2:3]" 9 9; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -79.609386010084833 9 -35.322957837804083 - 19 -48.795825705973677 35 -66.785451404696758; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 31.191835517701879 9 70.167228408751043 - 19 54.781627452796251 35 63.416473323894252; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -93.167368530284719 9 -61.169691850008505 - 19 -77.722025944280162 35 -85.13620094129746; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 19 0 35 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 19 0 35 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 19 1 35 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 19 0 35 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 19 0 35 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 9 0 19 0 35 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -108.63847514149069 9 -123.19672997108036 - 35 -123.19672997108036; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -14.31981200687156 9 26.520505468777699 - 35 26.520505468777699; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -87.62267613298549 9 -94.77996700627007 - 35 -94.77996700627007; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9 0 35 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9 0 35 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9 1 35 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9 0 35 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9 0 35 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9 0 35 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 8 1 17 1 21 1 24 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8 0 17 0 21 0 24 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.3128351505039433 8 2.3128351505039433 - 17 2.3128351505039433 21 2.3128351505039433 24 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.23421866920666501 8 0.23421866920666501 - 17 0.23421866920666501 21 0.23421866920666501 24 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8 -30.267416143437202 17 -3.6274161434372494 - 21 26.612583856562729 24 4.4851273593851984; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8 0 17 0 21 0 24 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8 0 17 0 21 0 24 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 8 1 17 1 21 1 24 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 8 1 17 1 21 1 24 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 8 1 17 1 21 1 24 1; -select -ne :time1; - setAttr ".o" 35; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_locator5" "group1"; -parent -s -nc -r "IMP_locator6" "group1"; -parent -s -nc -r "IMP_camera" "group1"; -parent -s -nc -r "IMP_locator14" "group1"; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537529 ; -select -ne IMP_Body; -select -ne IMP_Waist; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607581 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_LIK; -select -ne IMP_RIK; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of range2.ma diff --git a/base/models/monsters/imp/animation/cycles/range3.ma b/base/models/monsters/imp/animation/cycles/range3.ma deleted file mode 100644 index c3e25db8d..000000000 --- a/base/models/monsters/imp/animation/cycles/range3.ma +++ /dev/null @@ -1,2392 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:21 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: range3.ma -//Last modified: Mon, Mar 17, 2003 11:20:59 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -25.932189129146018 109.41336143303829 413.11523525431966 ; - setAttr ".r" -type "double3" -12.330108913833849 -6.2000000000034978 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 340.57645555405406; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 9.9588427967380166 36.135886248172234 61.151065751222788 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" -4.1053557775439913 50.242371261150723 338.09105009204751 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 167.2986862966404; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 167.18863567775352 27.712750368689377 178.80852812000643 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 362.24902807380221; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 5.157268050779404 64.595370499164162 73.888125873898332 ; - setAttr ".sp" -type "double3" 5.157268050779404 64.595370499164162 73.888125873898332 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 10 1 16 1 27 1 37 1 40 1 41 - 1 42 1 43 1 46 1 51 1 60 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -4.5461158161673003 10 -4.4933483193977217 - 16 -4.5461158161673003 27 -5.41334735724155 37 -5.2595949271584583 40 -4.8800117733543695 - 41 -4.7529623691648313 42 -4.6320567565188879 43 -4.5461158161673003 46 -4.5461158161673003 - 51 -4.656044489751535 60 -4.1683424838388445; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 2.1192000000002555 10 3.8141713261863757 - 16 2.1192000000002555 27 0.72030802088967583 37 0.95537396439510991 40 4.6111670631227106 - 41 4.1436059401405219 42 3.0249593319467492 43 2.1192000000002555 46 2.1192000000002555 - 51 2.704539938379003 60 2.5704603351258366; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -3.0821100000000254 10 -3.5904080289050797 - 16 -3.0821100000000254 27 -5.0614333637160369 37 -4.8520892635189545 40 -3.6475312738637622 - 41 -3.3907725293617039 42 -3.2047559497145541 43 -3.0821100000000254 46 -3.0821100000000254 - 51 -2.2602320802024654 60 -3.4535814248545851; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 16.724490460414607 10 13.336858360938237 - 16 34.882031465850432 27 41.838979608369065 37 65.940500123600359 40 43.108202288163632 - 41 -6.9257160015764576 42 -24.921042395604157 43 -80.299678259600853 46 -28.989855533476558 - 51 56.672723355907614 60 21.641970755221617; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -18.497178696094011 10 -30.898518557166973 - 16 -7.519253860443663 27 -16.221835552962613 37 -48.422713141277995 40 6.6633286779219096 - 41 57.313352519816789 42 59.782139328996521 43 70.221641551134311 46 -52.562393556788727 - 51 -75.055028313483646 60 -19.827043878388338; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -34.969129181092967 10 -37.557026247389928 - 16 13.958120845404386 27 18.899775392059002 37 -24.409800875234609 40 43.837614971036764 - 41 8.472577976070836 42 6.773172842391558 43 -45.539997755948072 46 -48.651530557765312 - 51 -179.92498834088192 60 -12.533957575183134; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 10 1 16 1 27 1 37 1 40 1 41 - 1 42 1 43 1 46 1 51 1 60 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 10 1 16 1 27 1 37 1 40 1 41 - 1 42 1 43 1 46 1 51 1 60 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 10 1 16 1 27 1 37 1 40 1 41 - 1 42 1 43 1 46 1 51 1 60 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 26 1 34 1 40 1 45 - 1 50 1 60 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 4.4752032871275116 10 4.4752032871275116 - 16 4.4752032871275116 26 4.4752032871275116 34 4.4752032871275116 40 4.4752032871275116 - 45 4.4752032871275116 50 4.4752032871275116 60 4.4752032871275116; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.1192573708760327 10 2.1192573708760327 - 16 2.1192573708760327 26 2.1192573708760327 34 2.1192573708760327 40 2.1192573708760327 - 45 2.1192573708760327 50 2.1192573708760327 60 2.1192573708760327; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.0821078932592156 10 -3.0821078932592156 - 16 -3.0821078932592156 26 -3.0821078932592156 34 -3.0821078932592156 40 -3.0821078932592156 - 45 -3.0821078932592156 50 -3.0821078932592156 60 -3.0821078932592156; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -14.579305876479085 10 78.700389747152826 - 16 15.168287101660164 26 -14.30684874897492 34 38.900811519314146 40 64.673327797995512 - 45 3.2620306712583647 50 -54.657203625118399 60 16.34486350958267; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.8651387359010507 10 21.777472921728254 - 16 28.125907496362796 26 18.197363334042187 34 38.930441611065461 40 1.1365267785133553 - 45 -0.86948751140416558 50 -0.72387986224588829 60 15.911320352957109; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -22.94523010110164 10 26.664871956413482 - 16 13.435092026772498 26 5.3603842791450065 34 36.362825147785379 40 58.871004710791382 - 45 -35.904686167387062 50 -39.273142156728582 60 -18.683662046647623; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 26 1 34 1 40 1 45 - 1 50 1 60 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 26 1 34 1 40 1 45 - 1 50 1 60 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 26 1 34 1 40 1 45 - 1 50 1 60 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 33 1 43 1 50 1 60 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 10 12.412879749935719 - 16 12.412879749935719 33 12.412879749935719 43 12.412879749935719 50 12.412879749935719 - 60 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 10 -6.7286993982861674 - 16 -6.7286993982861674 33 -6.7286993982861674 43 -6.7286993982861674 50 -6.7286993982861674 - 60 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 10 -3.868763862603668 - 16 -3.868763862603668 33 -3.868763862603668 43 -3.868763862603668 50 -3.868763862603668 - 60 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 78.531161924125755 10 72.48399089739722 - 16 80.81633315544309 33 43.307744666889086 43 90.805921474006098 50 24.565921474003904 - 60 63.891128891913766; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 16 0 33 0 43 0 50 0 60 - 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0 16 0 33 0 43 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 33 1 43 1 50 1 60 - 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 33 1 43 1 50 1 60 - 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 33 1 43 1 50 1 60 - 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 34 1 40 1 46 1 54 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -12.41287000000041 10 -12.41287000000041 - 16 -12.41287000000041 34 -12.41287000000041 40 -12.41287000000041 46 -12.41287000000041 - 54 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7285999999993047 10 -6.7285999999993047 - 16 -6.7285999999993047 34 -6.7285999999993047 40 -6.7285999999993047 46 -6.7285999999993047 - 54 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.8687599999999316 10 -3.8687599999999316 - 16 -3.8687599999999316 34 -3.8687599999999316 40 -3.8687599999999316 46 -3.8687599999999316 - 54 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 70.812045989226689 10 95.516162415670834 - 16 16.24134325040837 34 -13.374499019095841 40 42.397923004327204 46 -7.3442157091552112 - 54 54.977040666493515; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 6.9288435376111241 16 6.9288435376111188 - 34 6.928843537611109 40 6.9288435376111126 46 6.9288435376111108 54 6.9288435376111162; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 10 0.33872407100041041 16 0.33872407100040797 - 34 0.33872407100040547 40 0.33872407100040497 46 0.33872407100040358 54 0.33872407100040147; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 34 1 40 1 46 1 54 - 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 34 1 40 1 46 1 54 - 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 10 1 16 1 34 1 40 1 46 1 54 - 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 16 1 20 1 23 1 28 1 34 - 1 39 1 44 1 55 1 60 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 0 16 0 20 0 23 0 28 0 34 - 0 39 0 44 0 55 0 60 0; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.6456615572060826 10 2.6456615572060826 - 16 2.6456615572060826 20 2.6456615572060826 23 2.6456615572060826 28 2.6456615572060826 - 34 2.6456615572060826 39 2.6456615572060826 44 2.6456615572060826 55 2.6456615572060826 - 60 2.6456615572060826; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.9935618776130362 10 1.9935618776130362 - 16 1.9935618776130362 20 1.9935618776130362 23 1.9935618776130362 28 1.9935618776130362 - 34 1.9935618776130362 39 1.9935618776130362 44 1.9935618776130362 55 1.9935618776130362 - 60 1.9935618776130362; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -11.319304921837727 10 -36.549084349752782 - 16 -33.382296689166438 20 -34.933718006683236 23 -39.242061761129861 28 -35.854883388258173 - 34 -6.095815865250076 39 -14.128890211635834 44 -58.853571554765999 55 -35.404404920858447 - 60 -49.512309461986924; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 8.7357061754666496 10 -32.178099669829749 - 16 25.481588026003369 20 27.095361950429687 23 30.33134215275971 28 51.513669763580687 - 34 41.785317948022282 39 35.713194262856312 44 -45.654188056722248 55 -35.563682866630998 - 60 -1.0448181643759979; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 12.353868759547961 10 11.836394244317464 - 16 -2.2995515454835997 20 -8.816365998057023 23 -32.514475108096356 28 -6.9614415857705563 - 34 -5.0496252397352004 39 19.883617843221217 44 1.0023089695028693 55 11.258572944891277 - 60 6.0898747601390877; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 16 1 20 1 23 1 28 1 34 - 1 39 1 44 1 55 1 60 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 16 1 20 1 23 1 28 1 34 - 1 39 1 44 1 55 1 60 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 16 1 20 1 23 1 28 1 34 - 1 39 1 44 1 55 1 60 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 27 1 34 1 40 1 46 - 1 53 1 60 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 10 0 16 0 27 0 34 0 40 0 46 - 0 53 0 60 0; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.6268319407172029 10 5.6268319407172029 - 16 5.6268319407172029 27 5.6268319407172029 34 5.6268319407172029 40 5.6268319407172029 - 46 5.6268319407172029 53 5.6268319407172029 60 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1098668596606802 10 -2.1098668596606802 - 16 -2.1098668596606802 27 -2.1098668596606802 34 -2.1098668596606802 40 -2.1098668596606802 - 46 -2.1098668596606802 53 -2.1098668596606802 60 -2.1098668596606802; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 17.567813902989808 10 23.223495474484967 - 16 22.256444217454277 27 20.474166650584689 34 -15.355401608008929 40 14.763592887934298 - 46 47.004069222466136 53 49.960194848477727 60 22.223336447702419; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.4207084349782937 10 28.228330473052615 - 16 -16.168126445799196 27 -39.346433565102302 34 -53.306346310514208 40 -35.704813860019385 - 46 47.765897555579741 53 59.817110427867213 60 12.477521259066462; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.4106830101791599 10 -5.233426088120007 - 16 3.8448012887874894 27 7.0210039455255515 34 26.413857638033118 40 -8.5691081208372264 - 46 25.321670844939494 53 1.1554258400191104 60 0.18912683018068174; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 27 1 34 1 40 1 46 - 1 53 1 60 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 27 1 34 1 40 1 46 - 1 53 1 60 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 10 1 16 1 27 1 34 1 40 1 46 - 1 53 1 60 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 1 14 1 26 1 34 1 40 1 44 1 48 - 1 60 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 -7.5406347832540632e-013 14 - -7.5406347832540632e-013 26 -7.5406347832540632e-013 34 -7.5406347832540632e-013 - 40 -7.5406347832540632e-013 44 -7.5406347832540632e-013 48 -7.5406347832540632e-013 - 60 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 13.71946295727715 14 13.71946295727715 - 26 13.71946295727715 34 13.71946295727715 40 13.71946295727715 44 13.71946295727715 - 48 13.71946295727715 60 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 -3.0908609005564358e-013 14 - -3.0908609005564358e-013 26 -3.0908609005564358e-013 34 -3.0908609005564358e-013 - 40 -3.0908609005564358e-013 44 -3.0908609005564358e-013 48 -3.0908609005564358e-013 - 60 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 77.739160914831501 14 153.15122207917597 - 26 128.19922390322839 34 102.95125670867301 40 102.95125670867301 44 92.047813191246007 - 48 126.4286043347746 60 105.61965936398866; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 -76.726154744596627 14 -150.67593500212973 - 26 -171.83852957467144 34 -175.37757551345405 40 -175.37757551345405 44 -123.70065130882152 - 48 -137.27620024961033 60 -118.23881637471186; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 -173.86213662459591 14 -193.54013691199052 - 26 -197.67510513965038 34 -197.6888739994036 40 -197.6888739994036 44 -246.38393858255313 - 48 -179.50535984360792 60 -220.69119092180586; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 15.445123296459183 14 15.445123296459183 - 26 15.445123296459183 34 15.445123296459183 40 15.445123296459183 44 15.445123296459183 - 48 15.445123296459183 60 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 15.445123296459185 14 15.445123296459185 - 26 15.445123296459185 34 15.445123296459185 40 15.445123296459185 44 15.445123296459185 - 48 15.445123296459185 60 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 15.445123296459181 14 15.445123296459181 - 26 15.445123296459181 34 15.445123296459181 40 15.445123296459181 44 15.445123296459181 - 48 15.445123296459181 60 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 0 16 0 26 0 34 0 40 0 44 0 48 - 0 60 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 1 16 0 26 0.51769547413252759 - 34 0.40000000000000002 40 0.5 44 0 48 0 60 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 0 16 0 26 0 34 0 40 0 44 0 48 - 1 60 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 0 16 0 26 0 34 0 40 0 44 0 48 - 0 60 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 0 16 0 26 0 34 0 40 0 44 0 48 - 0 60 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 10 0 16 0 26 0 34 0 40 0 44 0 48 - 0 60 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 60 -ast 1 -aet 60 "; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8 1 13 1 18 1 29 1 37 1 40 - 1 43 1 48 1 52 1 60 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.49806644921906407 8 4.8216980507318405 - 13 -0.62458865000033981 18 -1.5451891440417713 29 2.8140831241902178 37 4.1884643706570728 - 40 3.9868227772879914 43 1.457521088926172 48 -0.64490400770853573 52 -0.92204620587603092 - 60 -0.37244949094401536; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 40.71684346646505 8 33.90789452921009 - 13 36.443630400296925 18 38.849854846976129 29 41.608295219873568 37 26.69750051518022 - 40 23.917506382545785 43 33.206375781131655 48 39.760295920402875 52 34.537837264238156 - 60 28.774352317450269; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -5.3187662547460119 8 7.2014935634414901 - 13 20.142547896892935 18 34.205766854686324 29 59.975328221567615 37 76.385859615360033 - 40 88.389586935502933 43 127.80867538412184 48 176.42592111918427 52 190.68941266982117 - 60 208.1049805870137; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 13 0 18 0 29 0 37 7.9918322623669242 - 40 -3.8237946376536245 43 -6.1515521501918444 48 -3.8237946376536245 52 5.230327429632573 - 60 26.583043734830337; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 6.9164550408607237 13 3.8699212314522611 - 18 0 29 0 37 -11.319895538116445 40 -7.4039377140267328 43 -6.9867546636939633 - 48 -7.4039377140267328 52 -7.4475647005450503 60 -7.4039377140267417; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 8 0 13 0 18 0 29 0 37 -11.250012057136495 - 40 5.633502662545685 43 7.4321725421386393 48 5.633502662545685 52 5.4454064657203967 - 60 5.6335026625456868; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8 1 13 1 18 1 29 1 37 1 40 - 1 43 1 48 1 52 1 60 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8 1 13 1 18 1 29 1 37 1 40 - 1 43 1 48 1 52 1 60 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 8 1 13 1 18 1 29 1 37 1 40 - 1 43 1 48 1 52 1 60 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 13 1 18 1 28 1 39 1 44 - 1 48 1 49 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 7.1689522478599503 7 7.1689522478599503 - 13 7.1689522478599503 18 7.1689522478599503 28 7.1689522478599503 39 7.1689522478599503 - 44 7.1689522478599272 48 7.1689522478599041 49 7.1689522478599503; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.23162624533316611 7 0.23162624533316611 - 13 8.1310715722954381 18 0.23162624533316611 28 0.23162624533316611 39 0.23162624533316611 - 44 13.578795182581178 48 7.5537907422003032 49 0.23162624533316611; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -22.470299720523364 7 -22.470299720523364 - 13 13.411926510423898 18 49.980531825518682 28 49.980531825518682 39 49.980531825518682 - 44 121.31912027151309 48 197.96301995945169 49 199.32268986266999; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.42372271318040872 7 0.42372271318040872 - 13 -24.671630418479694 18 0.42372271318040872 28 0.42372271318040872 39 0.42372271318040872 - 44 -36.696847123266657 48 -7.6391832068166696 49 0.42372271318040872; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 37.158780844606625 7 37.158780844606625 - 13 42.691489509033985 18 37.158780844606625 28 37.158780844606625 39 37.158780844606625 - 44 31.254400997257669 48 37.090413940163032 49 37.158780844606625; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.2404998971825694 7 2.2404998971825694 - 13 -0.47148970053346378 18 2.2404998971825694 28 2.2404998971825694 39 2.2404998971825694 - 44 -23.255273262402696 48 -3.4570717091495511 49 2.2404998971825694; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 13 1 18 1 28 1 39 1 44 - 1 48 1 49 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 13 1 18 1 28 1 39 1 44 - 1 48 1 49 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 13 1 18 1 28 1 39 1 44 - 1 48 1 49 1; - setAttr -s 9 ".kit[2:8]" 9 3 3 3 9 9 9; - setAttr -s 9 ".kot[2:8]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 27 1 33 1 35 1 37 1 43 - 1 46 1 50 1 53 1 57 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -7.3924057183505063 20 -7.3924057183505063 - 27 -7.3924057183505294 33 -7.3924057183505294 35 -7.3924057183505294 37 -7.3924057183505294 - 43 -7.3924057183505294 46 -7.3924057183505472 50 -7.3924057183505756 53 -7.3924057183505987 - 57 -7.3924057183506218; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.21364198155914232 20 0.21364198155914232 - 27 6.7069892155530564 33 3.8932054141556862 35 0.86297670495852508 37 0.86297670495852508 - 43 0.86297670495852508 46 8.9224664681274675 50 22.392612265542081 53 16.54885404195511 - 57 0.8629767049585314; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 12.111817859148234 20 12.111817859148234 - 27 55.184354511307845 33 89.815539759275367 35 92.845768468472514 37 92.845768468472514 - 43 92.845768468472514 46 123.68578101362124 50 166.66166181904458 53 186.03833382356976 - 57 217.71765471985688; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 4.3781541716515164 20 4.3781541716515164 - 27 -14.427127959464933 33 -14.427127959464933 35 3.8660535604441244 37 3.8660535604441244 - 43 3.8660535604441244 46 -17.033632236101582 50 -68.54397592171631 53 -68.54397592171631 - 57 -2.0443255247949765; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -24.213948650779095 20 -24.213948650779095 - 27 -25.480481469893611 33 -25.480481469893611 35 -24.282211840074865 37 -24.282211840074865 - 43 -24.282211840074865 46 -21.586844919479983 50 -14.943717641249897 53 -14.943717641249897 - 57 -24.932898941512288; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -8.177110698286512 20 -8.177110698286512 - 27 0.26841907386403141 33 0.26841907386403141 35 -7.9535314489879418 37 -7.9535314489879418 - 43 -7.9535314489879418 46 0.66988755142155909 50 21.923569201760955 53 21.923569201760955 - 57 -5.3383494470301711; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 27 1 33 1 35 1 37 1 43 - 1 46 1 50 1 53 1 57 1; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 27 1 33 1 35 1 37 1 43 - 1 46 1 50 1 53 1 57 1; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 20 1 27 1 33 1 35 1 37 1 43 - 1 46 1 50 1 53 1 57 1; - setAttr -s 11 ".kit[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; - setAttr -s 11 ".kot[0:10]" 3 3 9 9 9 3 3 - 9 9 9 9; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -119.34380057881232; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 23.887904365859594; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -89.762654827794037; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -77.738257575292849; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.142928565555039; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -94.881448308156521; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 21 1 25 1 35 1 37 1 41 - 1 46 1 51 1 57 1 60 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 -5.5644749482043405 21 1.1401714823404647 - 25 5.1928075004019663 35 3.426953026012904 37 2.4313862601444631 41 -3.6614659419467253 - 46 0.16140354439451826 51 8.6796590471887693 57 1.0125581773395047 60 0.1934609054398039; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 1.0977079619312291 21 -2.1776597996588754 - 25 -0.94074130266283729 35 -2.8414546503021239 37 -2.7256999436893974 41 - 1.8063097087901456 46 2.8971032854842971 51 -0.63515765963504744 57 -1.414115402488676 - 60 3.1453133125090034; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 -0.61457317739239847 21 - -0.64638284517118583 25 -0.63546473000367742 35 -0.57957973984701272 37 -0.45341992545263188 - 41 0.70114395636148807 46 0.29915519806214602 51 -0.68097166988669422 57 - 0.6905770623859766 60 -1.4719057529298571; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 1.1909874465778965 21 0.15527566844734925 - 25 -9.8816164222338543 35 -1.6081655957999033 37 0 41 -42.251622103350847 - 46 16.669933027235647 51 0 57 -21.604458102761356 60 -13.798096935874128; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 0.11308212636258869 21 -17.293893291036625 - 25 -23.669291161430184 35 8.7457119877435741 37 0 41 -12.153090288152635 - 46 9.1195035215177729 51 18.686727302439905 57 1.7638024088387279 60 -4.4520220519158542; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 10 -10.847358601187052 21 10.136346027416648 - 25 3.229461388906282 35 0.0015387559627626638 37 0 41 4.7862880613782099 - 46 -4.5156563154704115 51 -16.373080136357373 57 -15.612548740774837 60 -6.2005368456291139; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 21 1 25 1 35 1 37 1 41 - 1 46 1 51 1 57 1 60 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 21 1 25 1 35 1 37 1 41 - 1 46 1 51 1 57 1 60 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 10 1 21 1 25 1 35 1 37 1 41 - 1 46 1 51 1 57 1 60 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11 1 18 1 33 1 41 1 50 1 60 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 11 -2.5294371750177831 - 18 -2.5294371750177831 33 -2.5294371750177831 41 -2.5294371750177831 50 -2.5294371750177831 - 60 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 11 13.481673551673362 - 18 13.481673551673362 33 13.481673551673362 41 13.481673551673362 50 13.481673551673362 - 60 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 11 -0.26635088939205875 - 18 -0.26635088939205875 33 -0.26635088939205875 41 -0.26635088939205875 50 - -0.26635088939205875 60 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 141.20709981379272 11 107.33597915339269 - 18 190.21666799468537 33 186.79500963170889 41 186.79500963170889 50 328.44887174103451 - 60 135.12427068118569; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 64.064019952206479 11 71.679478852876827 - 18 115.50900194654945 33 112.74314872781807 41 112.74314872781807 50 134.65306043174292 - 60 109.23306907637736; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 252.95011708695623 11 182.61634471570321 - 18 290.06407641123837 33 298.66301832375785 41 298.66301832375785 50 430.32802257786182 - 60 246.2597931317809; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 11 15.445123296459185 - 18 15.445123296459185 33 15.445123296459185 41 15.445123296459185 50 15.445123296459185 - 60 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 11 15.445123296459185 - 18 15.445123296459185 33 15.445123296459185 41 15.445123296459185 50 15.445123296459185 - 60 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 11 15.445123296459185 - 18 15.445123296459185 33 15.445123296459185 41 15.445123296459185 50 15.445123296459185 - 60 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11 0 18 0 33 0 41 0 50 0 60 - 0; -select -ne :time1; - setAttr ".o" 60; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_locator5" "group1"; -parent -s -nc -r "IMP_locator6" "group1"; -parent -s -nc -r "IMP_camera" "group1"; -parent -s -nc -r "IMP_locator14" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049339262 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".t" -type "double3" 6.7758528420198658 -6.9388939039072284e-018 - -9.5120444723942321e-016 ; - setAttr ".r" -type "double3" -2.1064832569487142 0.36693656610454173 12.728045273286209 ; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_LHAND_ROT; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of range3.ma diff --git a/base/models/monsters/imp/animation/cycles/run.ma b/base/models/monsters/imp/animation/cycles/run.ma deleted file mode 100644 index 4ee823249..000000000 --- a/base/models/monsters/imp/animation/cycles/run.ma +++ /dev/null @@ -1,4821 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:23 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 3.0 scene -//Name: run.ma -//Last modified: Tue, Nov 06, 2001 05:49:13 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "3.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 136.74852511551751 37.29780802957346 280.21325396097694 ; - setAttr ".r" -type "double3" -0.3301089136371827 -363.799999999943 1.5564270698223716e-018 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".coi" 287.31308636809371; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 158.80961284654845 30.157612899892705 -5.2062095915323745 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 167.75293043163455 174.15590065431593 9.0877035561647581 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".coi" 100; - setAttr ".ow" 63.930448299237334; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 152.28185045031884 42.263141095333964 134.80508471921718 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".coi" 100; - setAttr ".ow" 392.09498338349943; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 318.21296363098907 69.280395002060672 0.37011244166337143 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 10000; - setAttr ".coi" 100; - setAttr ".ow" 258.89308388508232; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436975629 31.127794189756983 -3.7027086850713236 ; - setAttr ".sp" -type "double3" -0.44516282436975629 31.127794189756983 -3.7027086850713236 ; -createNode transform -n "group2"; - setAttr ".t" -type "double3" 97.167256100580829 0 0 ; - setAttr ".rp" -type "double3" 58.34183406829834 30.132447689771652 0.25323009490966797 ; - setAttr ".sp" -type "double3" 58.34183406829834 30.132447689771652 0.25323009490966797 ; -createNode transform -n "group3"; - setAttr ".t" -type "double3" 94.481191252075632 0 0 ; - setAttr ".rp" -type "double3" 84.818626403808594 35.816556453704834 0.25323009490966797 ; - setAttr ".sp" -type "double3" 84.818626403808594 35.816556453704834 0.25323009490966797 ; -createNode transform -n "group4"; - setAttr ".rp" -type "double3" 102.00495529174805 31.051433742046356 0.25323009490966797 ; - setAttr ".sp" -type "double3" 102.00495529174805 31.051433742046356 0.25323009490966797 ; -createNode transform -n "group5"; - setAttr ".t" -type "double3" 101.23721415018795 0 0 ; - setAttr ".rp" -type "double3" 125.33818817138672 28.336967915296555 2.0487651824951172 ; - setAttr ".sp" -type "double3" 125.33818817138672 28.336967915296555 2.0487651824951172 ; -createNode transform -n "group6"; - setAttr ".rp" -type "double3" 225.46916961669922 28.209134921431541 5.6890664100646973 ; - setAttr ".sp" -type "double3" 225.46916961669922 28.209134921431541 5.6890664100646973 ; -createNode transform -n "group7"; - setAttr ".rp" -type "double3" 259.14519500732422 30.132447689771652 0.25323009490966797 ; - setAttr ".sp" -type "double3" 259.14519500732422 30.132447689771652 0.25323009490966797 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.24500268074642695 4 -0.24500268074642695 - 7 -0.24500268074642695 14 -0.24500268074642695 17 -0.24500268074642695 20 - -0.24500268074642695 27 -0.24500268074642695 30 -0.24500268074642695; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.2065238412698649 4 1.2065238412698649 - 7 1.2065238412698649 14 1.2065238412698649 17 1.2065238412698649 20 1.2065238412698649 - 27 1.2065238412698649 30 1.2065238412698649; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.38309524546711837 4 -0.38309524546711837 - 7 -0.38309524546711837 14 -0.38309524546711837 17 -0.38309524546711837 20 - -0.38309524546711837 27 -0.38309524546711837 30 -0.38309524546711837; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 74.769256900725878 4 74.769256900725878 - 7 74.769256900725878 14 74.769256900725878 17 74.769256900725878 20 74.769256900725878 - 27 74.769256900725878 30 74.769256900725878; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 50.164573696692479 4 50.164573696692479 - 7 50.164573696692479 14 50.164573696692479 17 50.164573696692479 20 50.164573696692479 - 27 50.164573696692479 30 50.164573696692479; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -17.69972805884121 4 -17.69972805884121 - 7 -17.69972805884121 14 -17.69972805884121 17 -17.69972805884121 20 -17.69972805884121 - 27 -17.69972805884121 30 -17.69972805884121; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.0000000000000007 4 1.0000000000000007 - 7 1.0000000000000007 14 1.0000000000000007 17 1.0000000000000007 20 1.0000000000000007 - 27 1.0000000000000007 30 1.0000000000000007; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.0000000000000004 4 1.0000000000000004 - 7 1.0000000000000004 14 1.0000000000000004 17 1.0000000000000004 20 1.0000000000000004 - 27 1.0000000000000004 30 1.0000000000000004; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.0000000000000002 4 1.0000000000000002 - 7 1.0000000000000002 14 1.0000000000000002 17 1.0000000000000002 20 1.0000000000000002 - 27 1.0000000000000002 30 1.0000000000000002; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.12017666558909808 4 -0.12017666558909808 - 7 -0.12017666558909808 14 -0.12017666558909808 17 -0.12017666558909808 20 - -0.12017666558909808 27 -0.12017666558909808 30 -0.12017666558909808; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.724592717525262 4 -0.724592717525262 - 7 -0.724592717525262 14 -0.724592717525262 17 -0.724592717525262 20 -0.724592717525262 - 27 -0.724592717525262 30 -0.724592717525262; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.21268105951286304 4 -0.21268105951286304 - 7 -0.21268105951286304 14 -0.21268105951286304 17 -0.21268105951286304 20 - -0.21268105951286304 27 -0.21268105951286304 30 -0.21268105951286304; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 26.16299544171568 4 26.16299544171568 - 7 26.16299544171568 14 26.16299544171568 17 26.16299544171568 20 26.16299544171568 - 27 26.16299544171568 30 26.16299544171568; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -27.702126700627552 4 -27.702126700627552 - 7 -27.702126700627552 14 -27.702126700627552 17 -27.702126700627552 20 -27.702126700627552 - 27 -27.702126700627552 30 -27.702126700627552; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 68.590533289339191 4 68.590533289339191 - 7 68.590533289339191 14 68.590533289339191 17 68.590533289339191 20 68.590533289339191 - 27 68.590533289339191 30 68.590533289339191; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.99999999999999989 4 0.99999999999999989 - 7 0.99999999999999989 14 0.99999999999999989 17 0.99999999999999989 20 0.99999999999999989 - 27 0.99999999999999989 30 0.99999999999999989; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.99999999999999989 4 0.99999999999999989 - 7 0.99999999999999989 14 0.99999999999999989 17 0.99999999999999989 20 0.99999999999999989 - 27 0.99999999999999989 30 0.99999999999999989; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rhand_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 26.60888886703863; -createNode animCurveTA -n "IMP_Rhand_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.1090718009889402; -createNode animCurveTA -n "IMP_Rhand_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.5476660078217872; -createNode animCurveTA -n "IMP_Lhand_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureMaxSize 1024\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperShadeEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"HyperShade\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild hyperShadePanel1VisorEd;\n" - + ";\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperShadeEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"HyperShade\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -openFolder 1 -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" hyperShadePanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild hyperShadePanel1VisorEd;\n" - + ";\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild visorPanel1VisorEd;\n" - + ";\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"VisorEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"Visor\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "visor -reset visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Animation\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Character Clips & Poses\" -parent \"Animation\" -type command -cmd \"currentCharacters\" $editorName;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Character Clips & Poses\" -type command -cmd \"getCharacterPoses\" $editorName;\n" - + "visor -addFolder -name \"Unused Clips & Poses\" -parent \"Animation\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Clips\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryClips\" $editorName;\n" - + "visor -addFolder -name \"Poses\" -parent \"Animation/Unused Clips & Poses\" -type command -cmd \"getLibraryPoses\" $editorName;\n" - + "visor -addFolder -name \"Rendering\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Rendering\" -type command -cmd \"ls -type camera -type imagePlane\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Rendering\" -type command -cmd \"ls -type light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultShaderList\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Rendering\" -type command -cmd \"ls -type opticalFX -type shaderGlow\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Rendering\" -openFolder 1 -type connectedNodes -cmd \"ls -type defaultTextureList\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Rendering\" -type connectedNodes -cmd \"ls -type defaultRenderUtilityList\" $editorName;\n" - + "visor -addFolder -name \"Create\" -parent \"\" -openDirectories 1 visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Cameras\" -parent \"Create\" -type defaultNodes -cmd \"cameraCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Lights\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes light\" $editorName;\n" - + "visor -addFolder -name \"Materials\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/surface\\\"\" $editorName;\n" - + "visor -addFolder -name \"Volume\" -parent \"Create/Materials\" -type defaultNodes -cmd \"listNodeTypes \\\"shader/volume\\\"\" $editorName;\n" - + "visor -addFolder -name \"Post Process\" -parent \"Create\" -type defaultNodes -cmd \"postProcessCreateFolder()\" $editorName;\n" - + "visor -addFolder -name \"Textures\" -parent \"Create\" -type defaultNodes -cmd \"listNodeTypes texture\" $editorName;\n" - + "visor -addFolder -name \"Utilities\" -parent \"Create\" visorPanel1VisorEd;\n" - + "visor -addFolder -name \"Color\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/color\\\"\" $editorName;\n" - + "visor -addFolder -name \"General\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/general\\\"\" $editorName;\n" - + "visor -addFolder -name \"Particle\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/particle\\\"\" $editorName;\n" - + "visor -addFolder -name \"Switch\" -parent \"Create/Utilities\" -type defaultNodes -cmd \"listNodeTypes \\\"utility/switch\\\"\" $editorName;\n" - + "visor -addFolder -name \"Project\" -parent \"\" -openDirectories 1 -type directoryCommand -cmd \"currentProjectParentDir()\" $editorName;\n" - + "visor -addFolder -name \"Brushes\" -parent \"\" -type shelfItems -cmd \"C:/AW/Maya3.0/brushes\" $editorName;\n" - + "visor -rebuild visorPanel1VisorEd;\n" - + ";\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"Texture View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"Texture View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Texture View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureMaxSize 1024\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -textureMaxSize 1024\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "\tgrid -spacing 8cm -size 400cm -divisions 2 -style 2;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".a" -type "string" ( - "playbackOptions -min 4 -max 30 -animationStartTime 4 -animationEndTime 30;"); -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 4 5.6268319407172029 - 7 5.6268319407172029 14 5.6268319407172029 17 5.6268319407172029 20 5.6268319407172029 - 27 5.6268319407172029 30 5.6268319407172029; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 4 -2.1098668596606802 - 7 -2.1098668596606802 14 -2.1098668596606802 17 -2.1098668596606802 20 -2.1098668596606802 - 27 -2.1098668596606802 30 -2.1098668596606802; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 8.2765886173671639 4 8.2765886173671639 - 7 8.2765886173671639 14 8.2765886173671639 17 8.2765886173671639 20 8.2765886173671639 - 27 8.2765886173671639 30 8.2765886173671639; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 16.108724860940846 4 16.108724860940846 - 7 16.108724860940846 14 16.108724860940846 17 16.108724860940846 20 16.108724860940846 - 27 16.108724860940846 30 16.108724860940846; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.0033818239742485 4 3.0033818239742485 - 7 3.0033818239742485 14 3.0033818239742485 17 3.0033818239742485 20 3.0033818239742485 - 27 3.0033818239742485 30 3.0033818239742485; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.3867499999998705 4 -3.3867499999998705 - 7 -3.3867499999998705 14 -3.3867499999998705 17 -3.3867499999998705 20 -3.3867499999998705 - 27 -3.3867499999998705 30 -3.3867499999998705; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.1192000000001707 4 2.1192000000001707 - 7 2.1192000000001707 14 2.1192000000001707 17 2.1192000000001707 20 2.1192000000001707 - 27 2.1192000000001707 30 2.1192000000001707; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0821100000000254 4 -3.0821100000000254 - 7 -3.0821100000000254 14 -3.0821100000000254 17 -3.0821100000000254 20 -3.0821100000000254 - 27 -3.0821100000000254 30 -3.0821100000000254; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -44.035596296615644 4 -44.035596296615644 - 7 -44.035596296615644 14 -7.9001015586318184 17 -7.9001015586318184 20 -7.9001015586318184 - 27 -44.035596296615644 30 -44.035596296615644; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.360639871191168 4 28.360639871191168 - 7 28.360639871191168 14 -59.779472635747851 17 -59.779472635747851 20 -59.779472635747851 - 27 28.360639871191168 30 28.360639871191168; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -68.390332360578824 4 -68.390332360578824 - 7 -68.390332360578824 14 40.224698886106651 17 40.224698886106651 20 40.224698886106651 - 27 -68.390332360578824 30 -68.390332360578824; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.6456615572060826 4 2.6456615572060826 - 7 2.6456615572060826 14 2.6456615572060826 17 2.6456615572060826 20 2.6456615572060826 - 27 2.6456615572060826 30 2.6456615572060826; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9935618776130362 4 1.9935618776130362 - 7 1.9935618776130362 14 1.9935618776130362 17 1.9935618776130362 20 1.9935618776130362 - 27 1.9935618776130362 30 1.9935618776130362; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.550679091825927 4 -2.550679091825927 - 7 -2.550679091825927 14 -7.0518935036137904 17 -7.0518935036137904 20 -7.0518935036137904 - 27 -2.550679091825927 30 -2.550679091825927; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.983004235142092 4 -14.983004235142092 - 7 -14.983004235142092 14 21.909669650262209 17 21.909669650262209 20 21.909669650262209 - 27 -14.983004235142092 30 -14.983004235142092; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -17.42885184086596 4 -17.42885184086596 - 7 -17.42885184086596 14 -10.388215651363215 17 -10.388215651363215 20 -10.388215651363215 - 27 -17.42885184086596 30 -17.42885184086596; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6929913889239794 4 5.6929913889239794 - 7 5.6929913889239794 14 5.6929913889239794 17 5.6929913889239794 20 5.6929913889239794 - 27 5.6929913889239794 30 5.6929913889239794; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.1192573708758888 4 2.1192573708758888 - 7 2.1192573708758888 14 2.1192573708758888 17 2.1192573708758888 20 2.1192573708758888 - 27 2.1192573708758888 30 2.1192573708758888; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0821078932592156 4 -3.0821078932592156 - 7 -3.0821078932592156 14 -3.0821078932592156 17 -3.0821078932592156 20 -3.0821078932592156 - 27 -3.0821078932592156 30 -3.0821078932592156; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -45.643415771272259 4 -45.643415771272259 - 7 -45.643415771272259 14 72.057069547164545 17 72.057069547164545 20 72.057069547164545 - 27 -45.643415771272259 30 -45.643415771272259; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 66.209153054111951 4 66.209153054111951 - 7 66.209153054111951 14 -30.523862569932106 17 -30.523862569932106 20 -30.523862569932106 - 27 66.209153054111951 30 66.209153054111951; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -56.106161234812348 4 -56.106161234812348 - 7 -56.106161234812348 14 -40.545586556275715 17 -40.545586556275715 20 -40.545586556275715 - 27 -56.106161234812348 30 -56.106161234812348; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 23 1 27 1 30 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.93440374929457759 4 -0.93440374929457293 - 7 -0.9344037492945676 10 -0.93440374929456382 14 -0.9344037492945545 17 -0.93440374929455117 - 20 -0.93440374929454595 23 -0.93440374929454084 27 -0.93440374929453385 30 - -0.93440374929452974; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 36.570004361109405 4 41.870036512050177 - 7 37.011673707021139 10 32.1533109019921 14 36.570004361109412 17 41.870036512050177 - 20 37.011673707021139 23 32.1533109019921 27 36.570004361109405 30 41.870036512050177; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 59.381821719479213 4 79.256942285507094 - 7 100.45707088927014 10 115.47382865026898 14 156.54907782005995 17 176.08064241160113 - 20 198.06160730670362 23 217.20248558759377 27 260.18518248191822 30 276.53743706965781; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.2415997349859555 4 5.2415997349859555 - 7 5.2415997349859555 10 5.2415997349859555 14 9.2527564173197288 17 9.2527564173197288 - 20 9.2527564173197288 27 5.2415997349859555 30 5.2415997349859555; - setAttr -s 9 ".kit[7:8]" 3 3; - setAttr -s 9 ".kot[7:8]" 3 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.87909605399529678 4 0.87909605399529678 - 7 0.87909605399529678 10 0.87909605399529678 14 -33.843488579138629 17 -33.843488579138629 - 20 -33.843488579138629 27 0.87909605399529678 30 0.87909605399529678; - setAttr -s 9 ".kit[7:8]" 3 3; - setAttr -s 9 ".kot[7:8]" 3 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 8.6737210421414037 4 8.6737210421414037 - 7 8.6737210421414037 10 8.6737210421414037 14 -11.814037175631583 17 -11.814037175631583 - 20 -11.814037175631583 27 8.6737210421414037 30 8.6737210421414037; - setAttr -s 9 ".kit[7:8]" 3 3; - setAttr -s 9 ".kot[7:8]" 3 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 23 1 27 1 30 1; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 23 1 27 1 30 1; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 23 1 27 1 30 1; - setAttr -s 10 ".kit[8:9]" 3 3; - setAttr -s 10 ".kot[8:9]" 3 3; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.0180767416209342 4 -0.0180767416209342 - 7 -0.0180767416209342 14 -0.0180767416209342 17 -0.0180767416209342 20 -0.0180767416209342 - 27 -0.0180767416209342 30 -0.0180767416209342; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 4.350740136846035 4 4.350740136846035 - 7 4.350740136846035 14 4.350740136846035 17 4.350740136846035 20 4.350740136846035 - 27 4.350740136846035 30 4.350740136846035; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.679538405939565 4 2.679538405939565 - 7 2.679538405939565 14 2.679538405939565 17 2.679538405939565 20 2.679538405939565 - 27 2.679538405939565 30 2.679538405939565; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -26.74942150947361 4 -26.74942150947361 - 7 -26.74942150947361 14 -26.74942150947361 17 -26.74942150947361 20 -26.74942150947361 - 27 -26.74942150947361 30 -26.74942150947361; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -1.987846675914699e-016 4 -1.987846675914699e-016 - 7 -1.987846675914699e-016 14 -1.987846675914699e-016 17 -1.987846675914699e-016 - 20 -1.987846675914699e-016 27 -1.987846675914699e-016 30 -1.987846675914699e-016; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.8192025374841858 4 -7.8192025374841858 - 7 -7.8192025374841858 14 -7.8192025374841858 17 -7.8192025374841858 20 -7.8192025374841858 - 27 -7.8192025374841858 30 -7.8192025374841858; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 8 1 13 1 14 1 17 1 - 20 1 23 1 27 1 30 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 3.1478515992155343 4 3.1478515992155436 - 7 3.1478515992155436 8 3.147851599215544 13 3.147851599215544 14 3.147851599215544 - 17 3.1478515992155511 20 3.1478515992155547 23 3.1478515992155622 27 3.1478515992155773 - 30 3.1478515992155853; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 14.076363666894219 4 12.751355629159017 - 7 0.82628328954228003 8 0.82628328954228003 13 0.82628328954228003 14 9.8059006399461648 - 17 20.559718542553703 20 24.251372029726319 23 19.183570818575703 27 14.076363666894219 - 30 12.751355629159017; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 61.361628145551578 4 113.47861096313582 - 7 124.40577392273553 8 121.67284690304743 13 121.67284690304743 14 122.84410134005667 - 17 141.58871745135664 20 175.16013285980097 23 205.89353980194954 27 262.16498890799062 - 30 310.75910574728653; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -31.137525322475135 4 43.53625249152887 - 7 43.53625249152887 8 -0.8550498098012862 13 -0.8550498098012862 14 -42.216024165141327 - 17 -79.270964543377175 20 -128.86322314889259 23 -95.925126403792177 27 -31.137525322475135 - 30 43.53625249152887; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 18.296137987022039 4 18.296137987022036 - 7 18.296137987022036 8 18.296137987022057 13 18.296137987022057 14 18.296137987022117 - 17 18.296137987022036 20 18.296137987022064 23 18.296137987022053 27 18.296137987022039 - 30 18.296137987022036; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 4 8.3747589046670757e-016 7 - 0 8 5.2342243154169186e-017 13 5.2342243154169186e-017 14 -2.5124276714001233e-015 - 17 1.6749517809334147e-015 20 0 23 0 27 0 30 8.3747589046670757e-016; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 8 1 13 1 14 1 17 1 - 20 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 8 1 13 1 14 1 17 1 - 20 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 8 1 13 1 14 1 17 1 - 20 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; - setAttr -s 11 ".kot[0:10]" 9 9 3 3 3 3 3 - 9 9 3 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 21 1 23 1 27 1 30 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -4.4322715971404367 4 -4.4322715971404332 - 7 -4.432271597140427 10 -4.432271597140427 14 -4.432271597140419 17 -4.4322715971403994 - 20 -4.4322715971403941 21 -4.4322715971404039 23 -4.4322715971404039 27 -4.4322715971403932 - 30 -4.4322715971403941; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 10.300377747421932 4 20.458772703391737 - 7 24.433796816597308 10 19.575434011568262 14 14.27540186062749 17 12.650409789997049 - 20 1.3991262220830052 21 0.62587526571696905 23 0.62587526571696905 27 10.300377747421932 - 30 20.458772703391737; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 25.821225815232442 4 46.138015727172075 - 7 78.821547324640164 10 103.9967000416088 14 158.32202958875166 17 207.77112803444192 - 20 220.93375234842333 21 222.46720014274393 23 222.46720014274393 27 226.62458657767149 - 30 243.41851051132272; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -46.22599066299675 4 -79.820300249324575 - 7 -131.44052093839491 10 -94.661852890676116 14 -30.998173262766496 17 38.211329721891154 - 20 39.858576121946541 21 -1.9298200005985919 23 -1.9298200005985919 27 -46.22599066299675 - 30 -79.820300249324575; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -8.1254375044848981 4 -8.1254375044849123 - 7 -8.1254375044849176 10 -8.1254375044849159 14 -8.1254375044849159 17 -8.1254375044849176 - 20 -8.1254375044849159 21 -8.125437504484923 23 -8.125437504484923 27 -8.1254375044848981 - 30 -8.1254375044849123; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 4 8.0320201176309007e-016 7 - 0 10 0 14 4.0160100588154513e-016 17 0 20 0 21 0 23 0 27 0 30 8.0320201176309007e-016; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 21 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 21 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 4 1 7 1 10 1 14 1 17 1 20 1 - 21 1 23 1 27 1 30 1; - setAttr -s 11 ".kit[5:10]" 3 9 3 3 3 3; - setAttr -s 11 ".kot[5:10]" 3 9 3 3 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 4 -7.5406347832540632e-013 - 7 -7.5406347832540632e-013 14 -7.5406347832540632e-013 17 -7.5406347832540632e-013 - 20 -7.5406347832540632e-013 27 -7.5406347832540632e-013 30 -7.5406347832540632e-013; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 4 13.71946295727715 - 7 13.71946295727715 14 13.71946295727715 17 13.71946295727715 20 13.71946295727715 - 27 13.71946295727715 30 13.71946295727715; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 4 -3.0908609005564358e-013 - 7 -3.0908609005564358e-013 14 -3.0908609005564358e-013 17 -3.0908609005564358e-013 - 20 -3.0908609005564358e-013 27 -3.0908609005564358e-013 30 -3.0908609005564358e-013; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -56.613147182359185 4 -56.613147182359185 - 7 -56.613147182359185 14 -56.613147182359185 17 -56.613147182359185 20 -56.613147182359185 - 27 -56.613147182359185 30 -56.613147182359185; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -54.936564629393459 4 -54.936564629393459 - 7 -54.936564629393459 14 -54.936564629393459 17 -54.936564629393459 20 -54.936564629393459 - 27 -54.936564629393459 30 -54.936564629393459; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -17.454668883693078 4 -17.454668883693078 - 7 -17.454668883693078 14 -17.454668883693078 17 -17.454668883693078 20 -17.454668883693078 - 27 -17.454668883693078 30 -17.454668883693078; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 4 15.445123296459183 - 7 15.445123296459183 14 15.445123296459183 17 15.445123296459183 20 15.445123296459183 - 27 15.445123296459183 30 15.445123296459183; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 4 15.445123296459185 - 7 15.445123296459185 14 15.445123296459185 17 15.445123296459185 20 15.445123296459185 - 27 15.445123296459185 30 15.445123296459185; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 4 15.445123296459181 - 7 15.445123296459181 14 15.445123296459181 17 15.445123296459181 20 15.445123296459181 - 27 15.445123296459181 30 15.445123296459181; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.5294371750177831 4 -2.5294371750177831 - 7 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 20 -2.5294371750177831 - 27 -2.5294371750177831 30 -2.5294371750177831; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.481673551673362 4 13.481673551673362 - 7 13.481673551673362 14 13.481673551673362 17 13.481673551673362 20 13.481673551673362 - 27 13.481673551673362 30 13.481673551673362; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.26635088939205875 4 -0.26635088939205875 - 7 -0.26635088939205875 14 -0.26635088939205875 17 -0.26635088939205875 20 - -0.26635088939205875 27 -0.26635088939205875 30 -0.26635088939205875; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 255.49947050255454 4 255.49947050255454 - 7 255.49947050255454 14 255.49947050255454 17 255.49947050255454 20 255.49947050255454 - 27 255.49947050255454 30 255.49947050255454; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 77.994350484299176 4 77.994350484299176 - 7 77.994350484299176 14 77.994350484299176 17 77.994350484299176 20 77.994350484299176 - 27 77.994350484299176 30 77.994350484299176; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 341.29462909356693 4 341.29462909356693 - 7 341.29462909356693 14 341.29462909356693 17 341.29462909356693 20 341.29462909356693 - 27 341.29462909356693 30 341.29462909356693; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 4 15.445123296459185 - 7 15.445123296459185 14 15.445123296459185 17 15.445123296459185 20 15.445123296459185 - 27 15.445123296459185 30 15.445123296459185; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 4 15.445123296459185 - 7 15.445123296459185 14 15.445123296459185 17 15.445123296459185 20 15.445123296459185 - 27 15.445123296459185 30 15.445123296459185; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 4 15.445123296459185 - 7 15.445123296459185 14 15.445123296459185 17 15.445123296459185 20 15.445123296459185 - 27 15.445123296459185 30 15.445123296459185; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 57.599360313663027 4 57.599360313663027 - 7 57.599360313663027 14 57.599360313663027 17 57.599360313663027 20 57.599360313663027 - 27 57.599360313663027 30 57.599360313663027; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 117.54758325826437 4 117.54758325826437 - 7 117.54758325826437 14 117.54758325826437 17 117.54758325826437 20 117.54758325826437 - 27 117.54758325826437 30 117.54758325826437; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 72.698104511620812 4 72.698104511620812 - 7 72.698104511620812 14 72.698104511620812 17 72.698104511620812 20 72.698104511620812 - 27 72.698104511620812 30 72.698104511620812; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -87.111658359157133 4 -87.111658359157133 - 7 -87.111658359157133 14 -87.111658359157133 17 -87.111658359157133 20 -87.111658359157133 - 27 -87.111658359157133 30 -87.111658359157133; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -23.754136702713122 4 -23.754136702713122 - 7 -23.754136702713122 14 -23.754136702713122 17 -23.754136702713122 20 -23.754136702713122 - 27 -23.754136702713122 30 -23.754136702713122; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -85.189443779084158 4 -85.189443779084158 - 7 -85.189443779084158 14 -85.189443779084158 17 -85.189443779084158 20 -85.189443779084158 - 27 -85.189443779084158 30 -85.189443779084158; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 6.7758528420198658 4 6.7758528420198658 - 7 6.7758528420198658 14 6.7758528420198658 17 6.7758528420198658 20 6.7758528420198658 - 23 6.7758528420198658 27 6.7758528420198658 30 6.7758528420198658; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.9388939039072284e-018 4 -6.9388939039072284e-018 - 7 -6.9388939039072284e-018 14 -6.9388939039072284e-018 17 -6.9388939039072284e-018 - 20 -6.9388939039072284e-018 23 -6.9388939039072284e-018 27 -6.9388939039072284e-018 - 30 -6.9388939039072284e-018; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -9.5120444723942321e-016 4 -9.5120444723942321e-016 - 7 -9.5120444723942321e-016 14 -9.5120444723942321e-016 17 -9.5120444723942321e-016 - 20 -9.5120444723942321e-016 23 -9.5120444723942321e-016 27 -9.5120444723942321e-016 - 30 -9.5120444723942321e-016; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -12.784757077400341 4 -12.784757077400341 - 7 -12.784757077400341 14 -12.784757077400341 17 -12.784757077400341 20 -12.784757077400341 - 23 -12.784757077400341 27 -12.784757077400341 30 -12.784757077400341; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.2695897469829736 4 3.2695897469829736 - 7 3.2695897469829736 14 3.2695897469829736 17 3.2695897469829736 20 3.2695897469829736 - 23 3.2695897469829736 27 3.2695897469829736 30 3.2695897469829736; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.9162979482121409 4 -6.9162979482121409 - 7 -6.9162979482121409 14 -6.9162979482121409 17 -6.9162979482121409 20 -6.9162979482121409 - 23 -6.9162979482121409 27 -6.9162979482121409 30 -6.9162979482121409; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 6.7758528420198658 4 6.7758528420198658 - 7 6.7758528420198658 14 6.7758528420198658 17 6.7758528420198658 20 6.7758528420198658 - 23 6.7758528420198658 27 6.7758528420198658 30 6.7758528420198658; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -4.0609141336791277e-018 4 -4.0609141336791277e-018 - 7 -4.0609141336791277e-018 14 -4.0609141336791277e-018 17 -4.0609141336791277e-018 - 20 -4.0609141336791277e-018 23 -4.0609141336791277e-018 27 -4.0609141336791277e-018 - 30 -4.0609141336791277e-018; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.5668232391302755e-016 4 -5.5668232391302755e-016 - 7 -5.5668232391302755e-016 14 -5.5668232391302755e-016 17 -5.5668232391302755e-016 - 20 -5.5668232391302755e-016 23 -5.5668232391302755e-016 27 -5.5668232391302755e-016 - 30 -5.5668232391302755e-016; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1064832569487142 4 -2.1064832569487142 - 7 -2.1064832569487142 14 -2.1064832569487142 17 -2.1064832569487142 20 -2.1064832569487142 - 23 -2.1064832569487142 27 -2.1064832569487142 30 -2.1064832569487142; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.36693656610454173 4 0.36693656610454173 - 7 0.36693656610454173 14 0.36693656610454173 17 0.36693656610454173 20 0.36693656610454173 - 23 0.36693656610454173 27 0.36693656610454173 30 0.36693656610454173; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 12.728045273286209 4 12.728045273286209 - 7 12.728045273286209 14 12.728045273286209 17 12.728045273286209 20 12.728045273286209 - 23 12.728045273286209 27 12.728045273286209 30 12.728045273286209; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 7 1 14 1 17 1 20 1 23 1 - 27 1 30 1; - setAttr -s 9 ".kit[4:8]" 3 9 9 3 3; - setAttr -s 9 ".kot[4:8]" 3 9 9 3 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.3128351505039433 4 2.3128351505039433 - 7 2.3128351505039433 14 2.3128351505039433 17 2.3128351505039433 20 2.3128351505039433 - 27 2.3128351505039433 30 2.3128351505039433; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.23421866920666501 4 0.23421866920666501 - 7 0.23421866920666501 14 0.23421866920666501 17 0.23421866920666501 20 0.23421866920666501 - 27 0.23421866920666501 30 0.23421866920666501; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 26.040680922301711 4 26.040680922301711 - 7 26.040680922301711 14 26.040680922301711 17 26.040680922301711 20 26.040680922301711 - 27 26.040680922301711 30 26.040680922301711; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.7384771804188404 4 5.7384771804188404 - 7 5.7384771804188404 14 5.7384771804188404 17 5.7384771804188404 20 5.7384771804188404 - 27 5.7384771804188404 30 5.7384771804188404; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.0494561358638701 4 2.0494561358638701 - 7 2.0494561358638701 14 2.0494561358638701 17 2.0494561358638701 20 2.0494561358638701 - 27 2.0494561358638701 30 2.0494561358638701; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -31.751920304050358 4 -31.751920304050358 - 7 -31.751920304050358 14 -31.751920304050358 17 -31.751920304050358 20 -31.751920304050358 - 27 -31.751920304050358 30 -31.751920304050358; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.74525677667777757 4 0.74525677667777757 - 7 0.74525677667777757 14 0.74525677667777757 17 0.74525677667777757 20 0.74525677667777757 - 27 0.74525677667777757 30 0.74525677667777757; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.8072476834435935 4 1.8072476834435935 - 7 1.8072476834435935 14 1.8072476834435935 17 1.8072476834435935 20 1.8072476834435935 - 27 1.8072476834435935 30 1.8072476834435935; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 12.412879749935719 4 12.412879749935719 - 7 12.412879749935719 14 12.412879749935719 17 12.412879749935719 20 12.412879749935719 - 27 12.412879749935719 30 12.412879749935719; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7286993982861674 4 -6.7286993982861674 - 7 -6.7286993982861674 14 -6.7286993982861674 17 -6.7286993982861674 20 -6.7286993982861674 - 27 -6.7286993982861674 30 -6.7286993982861674; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.868763862603668 4 -3.868763862603668 - 7 -3.868763862603668 14 -3.868763862603668 17 -3.868763862603668 20 -3.868763862603668 - 27 -3.868763862603668 30 -3.868763862603668; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 20.797088797044175 4 20.797088797044175 - 7 20.797088797044175 14 83.337946405767994 17 83.337946405767994 20 83.337946405767994 - 27 20.797088797044175 30 20.797088797044175; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -12.41287000000041 4 -12.41287000000041 - 7 -12.41287000000041 14 -12.41287000000041 17 -12.41287000000041 20 -12.41287000000041 - 27 -12.41287000000041 30 -12.41287000000041; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7285999999993047 4 -6.7285999999993047 - 7 -6.7285999999993047 14 -6.7285999999993047 17 -6.7285999999993047 20 -6.7285999999993047 - 27 -6.7285999999993047 30 -6.7285999999993047; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.8687599999999316 4 -3.8687599999999316 - 7 -3.8687599999999316 14 -3.8687599999999316 17 -3.8687599999999316 20 -3.8687599999999316 - 27 -3.8687599999999316 30 -3.8687599999999316; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 69.406632037547368 4 69.406632037547368 - 7 69.406632037547368 14 27.932389340869854 17 27.932389340869854 20 27.932389340869854 - 27 69.406632037547368 30 69.406632037547368; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.78994179518057983 4 0.78994179518057983 - 7 0.78994178826928274 14 0.78994178881405241 17 0.78994178881405241 20 0.29554191732040602 - 27 0.78994179518057983 30 0.7899417877303162; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.21983840563198737 4 -0.21983840563198737 - 7 -0.2198384080722863 14 -0.21983840787993583 17 -0.21983840787993583 20 - -1.0451457028442617 27 -0.21983840563198737 30 -0.21983840826258552; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -1.8241883224152418 4 -1.8241883224152418 - 7 -1.8241883251140121 14 -1.8241883249012882 17 -1.8241883249012882 20 -1.67938245642047 - 27 -1.8241883224152418 30 -1.8241883253244631; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 4 1 7 1 14 1 17 1 20 1 27 1 - 30 1; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.3636353889235085 4 0.3636353889235085 - 7 0.363635388934687 14 0.36363538856905847 17 0.36363538856905847 20 -0.50749592851722125 - 27 0.3636353889235085 30 0.36363539030931985; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.85721784142318669 4 -0.85721784142318669 - 7 -0.85721784142755253 14 -0.85721784128576495 17 -0.85721784128576495 20 - 0.96614162869413645 27 -0.85721784142318669 30 -0.8572178419605867; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -1.7700132418341845 4 -1.7700132418341845 - 7 -1.770013241829774 14 -1.7700132419735544 17 -1.7700132419735544 20 -1.6760126001444056 - 27 -1.7700132418341845 30 -1.7700132412892235; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 4 0 7 0 14 0 17 0 20 0 27 0 - 30 0; - setAttr -s 8 ".kit[6:7]" 3 3; - setAttr -s 8 ".kot[6:7]" 3 3; -createNode animCurveTU -n "group4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "group4_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 96.433281980424312; -createNode animCurveTL -n "group4_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTL -n "group4_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "group4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "group4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "group4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTU -n "group4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "group4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "group4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 1; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 1; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 30 1; -select -ne :time1; - setAttr ".o" 14; -select -ne :renderPartition; - setAttr -s 8 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 8 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 3 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 3 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 3 ".sol"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_LHAND_ROT; - setAttr -k on ".FIST"; -select -ne IMP_RHAND_ROT; -select -ne IMP_Rwing_meshShape3Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape2Orig5; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Rwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape1Orig3; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape3Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape5Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape2Orig4; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_Lwing_meshShape4Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 6 ".uvst[0].uvsp[0:5]" -type "float2" 0.0053039999 - 0.672656 0.065654002 0.72388399 0.192425 0.47426999 0.0063800002 0.361103 - 0.0053039999 0.672656 0.192425 0.47426999; -select -ne IMP_ALL; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049349098 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455941 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Body2; - setAttr ".t" -type "double3" 2.7120579650005574 -0.40824693196578749 0.079241712248960913 ; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "group4_visibility.o" "group4.v"; -connectAttr "group4_translateX.o" "group4.tx"; -connectAttr "group4_translateY.o" "group4.ty"; -connectAttr "group4_translateZ.o" "group4.tz"; -connectAttr "group4_rotateX.o" "group4.rx"; -connectAttr "group4_rotateY.o" "group4.ry"; -connectAttr "group4_rotateZ.o" "group4.rz"; -connectAttr "group4_scaleX.o" "group4.sx"; -connectAttr "group4_scaleY.o" "group4.sy"; -connectAttr "group4_scaleZ.o" "group4.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of run.ma diff --git a/base/models/monsters/imp/animation/cycles/scurry2.ma b/base/models/monsters/imp/animation/cycles/scurry2.ma deleted file mode 100644 index b11d3ab1f..000000000 --- a/base/models/monsters/imp/animation/cycles/scurry2.ma +++ /dev/null @@ -1,3968 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:24 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.0 scene -//Name: scurry2.ma -//Last modified: Sun, May 19, 2002 03:52:20 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models/monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.0"; -currentUnit -l centimeter -a degree -t film; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" -158.44878221441809 59.060735500589473 23.110431220824523 ; - setAttr ".r" -type "double3" -8.1301089156291795 -2244.5999999999658 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 262.00740951943499; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 99.774204502848789 22.007262598785083 -1.2988276743474743 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 101.55584547386937 -3.3428797739735074 119.73801778504512 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 239.31162123314752; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 212.13842597111801 20.36001797120765 -3.4272829690320656 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.366533543047794; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -73.663635402316629 15.943982779194229 -32.240070706815317 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "pointLight2"; - setAttr ".t" -type "double3" 246.36976393965614 118.25846578140836 131.002452665389 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 2 -max 19 -ast 2 -aet 19 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -7.5406347832540632e-013 3 -7.5406347832540632e-013 - 4 -7.5406347832540632e-013 5 -7.5406347832540632e-013 6 -7.5406347832540632e-013 - 9 -7.5406347832540632e-013 10 -7.5406347832540632e-013 11 -7.5406347832540632e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.71946295727715 3 13.71946295727715 - 4 13.71946295727715 5 13.71946295727715 6 13.71946295727715 9 13.71946295727715 - 10 13.71946295727715 11 13.71946295727715; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.0908609005564358e-013 3 -3.0908609005564358e-013 - 4 -3.0908609005564358e-013 5 -3.0908609005564358e-013 6 -3.0908609005564358e-013 - 9 -3.0908609005564358e-013 10 -3.0908609005564358e-013 11 -3.0908609005564358e-013; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 68.596496127541187 2 68.596496127541187 - 3 68.596496127541187 4 68.596496127541187 5 68.596496127541187 6 68.596496127541187 - 9 68.596496127541187 10 68.596496127541187 11 68.596496127541187; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -60.802874383230787 2 -60.802874383230787 - 3 -60.802874383230787 4 -60.802874383230787 5 -60.802874383230787 6 -60.802874383230787 - 9 -60.802874383230787 10 -60.802874383230787 11 -60.802874383230787; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -157.43468421330525 2 -157.43468421330525 - 3 -157.43468421330525 4 -157.43468421330525 5 -157.43468421330525 6 -157.43468421330525 - 9 -157.43468421330525 10 -157.43468421330525 11 -157.43468421330525; - setAttr -s 9 ".kit[0:8]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459183 3 15.445123296459183 - 4 15.445123296459183 5 15.445123296459183 6 15.445123296459183 9 15.445123296459183 - 10 15.445123296459183 11 15.445123296459183; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 3 15.445123296459185 - 4 15.445123296459185 5 15.445123296459185 6 15.445123296459185 9 15.445123296459185 - 10 15.445123296459185 11 15.445123296459185; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459181 3 15.445123296459181 - 4 15.445123296459181 5 15.445123296459181 6 15.445123296459181 9 15.445123296459181 - 10 15.445123296459181 11 15.445123296459181; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 3 1 4 1 5 1 6 1 9 1 10 1 11 - 1; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 0 10 0 11 - 0; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 4 0 5 0 6 0 9 1 10 0 11 - 0.40000000000000002; - setAttr -s 8 ".kit[0:7]" 9 3 3 3 3 3 3 - 9; - setAttr -s 8 ".kot[0:7]" 9 3 3 3 3 3 3 - 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.5294371750177831 3 -2.5294371750177831 - 9 -2.5294371750177831 12 -2.5294371750177831 14 -2.5294371750177831 17 -2.5294371750177831 - 19 -2.5294371750177831; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 13.481673551673362 3 13.481673551673362 - 9 13.481673551673362 12 13.481673551673362 14 13.481673551673362 17 13.481673551673362 - 19 13.481673551673362; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.26635088939205875 3 -0.26635088939205875 - 9 -0.26635088939205875 12 -0.26635088939205875 14 -0.26635088939205875 17 - -0.26635088939205875 19 -0.26635088939205875; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 73.167297059293915 3 73.167297059293915 - 9 73.167297059293915 12 73.167297059293915 14 73.167297059293915 17 73.167297059293915 - 19 73.167297059293915; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 61.241182877125034 3 61.241182877125034 - 9 61.241182877125034 12 61.241182877125034 14 61.241182877125034 17 61.241182877125034 - 19 61.241182877125034; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 177.69376467901077 3 177.69376467901077 - 9 177.69376467901077 12 177.69376467901077 14 177.69376467901077 17 177.69376467901077 - 19 177.69376467901077; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 15.445123296459185 3 15.445123296459185 - 9 15.445123296459185 12 15.445123296459185 14 15.445123296459185 17 15.445123296459185 - 19 15.445123296459185; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 3 1 9 1 12 1 14 1 17 1 19 1; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0.5 17 0 19 - 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 0 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 9 0 12 0 14 0 17 1 19 0; - setAttr -s 7 ".kit[0:6]" 9 3 3 3 3 3 3; - setAttr -s 7 ".kot[0:6]" 9 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 59.56190462579648 2 87.086512400040135 - 3 87.086512400040135 9 87.086512400040135 10 87.086512400040135 11 89.803156191128494 - 12 90.914510469301021 13 95.359927581991059 14 106.84392178977366 16 114.45709035559202 - 19 167.43505300763536; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 6.1155384277619564 2 3.3966049353215197 - 3 3.3966049353215197 9 3.3966049353215197 10 4.3844754048082084 11 7.5950544306398937 - 12 8.2124734740690712 13 9.6942791782990856 14 11.670020117272431 16 13.774088242950418 - 19 3.1848718158837808; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -18.214943034405117 2 -18.214943034405117 - 3 -18.214943034405117 9 -18.214943034405117 10 -18.214943034405117 11 -18.214943034405117 - 12 -18.214943034405117 13 -18.214943034405117 14 -18.214943034405117 16 -18.214943034405117 - 19 -18.214943034405117; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 64.752151263719625 2 45.636324587558242 - 3 45.636324587558242 9 45.636324587558242 10 51.259142132888385 11 82.6337039450666 - 12 91.925517875523141 13 45.636324587558242 14 45.636324587558242 16 -52.350191482226066 - 19 219.80154311026268; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 54.671688625550246 2 79.910841797573497 - 3 79.910841797573497 9 79.910841797573497 10 79.910841797573482 11 79.91084179757361 - 12 79.91084179757344 13 79.910841797573497 14 79.910841797573497 16 24.766301215716588 - 19 103.06211582598448; - setAttr -s 11 ".kit[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; - setAttr -s 11 ".kot[0:10]" 9 3 3 3 3 3 3 - 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.46864865283559 2 3.4514964971631841 - 3 3.4514964971631841 9 3.4514964971631841 10 3.4514964971631956 11 3.4514964971632001 - 12 3.4514964971635234 13 3.4514964971631841 14 3.4514964971631841 16 -98.530493758286156 - 19 179.66289643582957; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 9 1 10 1 11 1 12 1 - 13 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999989 2 0.99999999999999989 - 3 0.99999999999999989 9 0.99999999999999989 10 0.99999999999999989 11 0.99999999999999989 - 12 0.99999999999999989 13 0.99999999999999989 14 0.99999999999999989 16 0.99999999999999989 - 19 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 9 0.99999999999999978 10 0.99999999999999978 11 0.99999999999999978 - 12 0.99999999999999978 13 0.99999999999999978 14 0.99999999999999978 16 0.99999999999999978 - 19 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 39.426477445851056 2 47.90393294415022 - 3 47.90393294415022 4 49.571857445849837 5 54.416924328220652 6 76.91378422815221 - 7 90.926137136631965 8 104.90238781324805 9 119.6320759386512 11 133.30969811775907 - 19 133.30969811775907; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.382959769989033 2 4.26699651607976 - 3 4.26699651607976 4 7.5234205432075498 5 8.9484432415242807 6 7.203638148018376 - 7 13.455232162483156 8 13.222439041068554 9 8.429209504871201 11 3.616514330714832 - 19 3.616514330714832; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 5.5906769424741469 2 5.5906769424741469 - 3 5.5906769424741469 4 5.5906769424741469 5 4.8437019572729909 6 4.7903818813050094 - 7 5.5906769424741469 8 5.5906769424741469 9 5.5906769424741469 11 5.5906769424741469 - 19 5.5906769424741469; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -213.67554625381291 2 -155.58505834761613 - 3 -155.58505834761613 4 -122.73251224871834 5 -177.7142343101996 6 -225.74849598730907 - 7 -182.20184218742966 8 -167.35620527064438 9 -185.9452684786005 11 -178.9145192530496 - 19 -178.9145192530496; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 76.0624067087263 2 77.351754812025391 - 3 77.351754812025391 4 77.351754812025504 5 78.853863033891884 6 68.745530314090416 - 7 42.231539530725335 8 52.060566701540544 9 40.693717484916455 11 77.792981530281054 - 19 77.792981530281054; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 125.96337513298413 2 168.36778920107272 - 3 168.36778920107272 4 168.36778920107287 5 89.977469223902943 6 -37.34389052151419 - 7 50.997059015191702 8 69.291367951665947 9 111.25790401441596 11 146.44536767645329 - 19 146.44536767645329; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0.99999999999999978 2 0.99999999999999978 - 3 0.99999999999999978 4 0.99999999999999978 5 0.99999999999999978 6 0.99999999999999978 - 7 0.99999999999999978 8 0.99999999999999978 9 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 - 9 1 11 1 19 1; - setAttr -s 11 ".kit[5:10]" 9 9 9 9 3 3; - setAttr -s 11 ".kot[5:10]" 9 9 9 9 3 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 2 0 3 0 5 0 9 0 13 0 17 0 19 - 0 21.392 0; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.6268319407172029 2 5.6268319407172029 - 3 5.6268319407172029 5 5.6268319407172029 9 5.6268319407172029 13 5.6268319407172029 - 17 5.6268319407172029 19 5.6268319407172029 21.392 5.6268319407172029; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.1098668596606802 2 -2.1098668596606802 - 3 -2.1098668596606802 5 -2.1098668596606802 9 -2.1098668596606802 13 -2.1098668596606802 - 17 -2.1098668596606802 19 -2.1098668596606802 21.392 -2.1098668596606802; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.624 363.04706215082535 2 360.73763009723075 - 3 365.13931823930221 5 373.76063026300602 9 361.64068150857611 13 378.57221183734987 - 17 362.51014995549542 19 360.73763009723075 20.58 370.59077456904788; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1.3 1.0164485751876862 2 -0.44667534838539391 - 3 -0.86706792719803072 5 -0.44667534838539302 9 -0.44667534838539519 13 -0.44667534838539386 - 17 2.6709700285893727 19 -0.44667534838539391 21.392 -0.44667534838539391; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" -0.92800000000000005 -14.898177256474998 - 2 -14.641906192173112 3 -9.9942319205333412 5 -14.641906192173147 9 -14.64190619217317 - 13 -14.64190619217317 17 -15.478432696593305 19 -14.641906192173112 20.428 - -10.003399928309316; - setAttr -s 9 ".kit[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 1 9 9 9 9 9 9 - 9 9; - setAttr -s 9 ".kix[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".kiy[0:8]" -0.098345361649990082 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; - setAttr -s 9 ".kox[0:8]" 0.99515235424041748 0.8861432671546936 - 1 0.95118248462677002 1 0.99904215335845947 1 0.83114916086196899 0.59221374988555908; - setAttr -s 9 ".koy[0:8]" -0.098345354199409485 0.4634113609790802 - 0 -0.30862909555435181 0 -0.043758470565080643 0 0.55604952573776245 0.80578088760375977; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 2 1 3 1 5 1 9 1 13 1 17 1 19 - 1 21.392 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 9 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 9 - 9 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 7.1689522478599494 8 7.1689522478599494 - 11 7.168952247859953 12 6.3450935941379685 13 6.0198451340742674 15 7.1689522478599494 - 17 7.1689522478599494; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 8 0 11 7.9126523868203575 12 - 11.673695323026516 13 10.182893175810886 15 0.0996086992316223 17 0.0996086992316223; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.672655709095594 8 18.672655709095594 - 11 33.796945933310276 12 39.374766587856087 13 50.519161987064884 15 79.36659147624809 - 17 79.36659147624809; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -174.49049195404214 8 -174.49049195404214 - 11 -197.94003856162612 12 -209.04261896981978 13 -197.47915486936469 15 -174.49049195404214 - 17 -174.49049195404214; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 129.78625356110399 8 129.78625356110399 - 11 129.78625356110399 12 129.78625356110393 13 129.78625356110396 15 129.78625356110399 - 17 129.78625356110399; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -169.93906815090079 8 -169.93906815090079 - 11 -169.93906815090077 12 -169.93906815090071 13 -169.93906815090074 15 -169.93906815090079 - 17 -169.93906815090079; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 8 1 11 1 12 1 13 1 15 1 17 - 1; - setAttr -s 7 ".kit[1:6]" 3 9 9 9 3 3; - setAttr -s 7 ".kot[1:6]" 3 9 9 9 3 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3924057183505063 2 -7.3924057183505063 - 4 -7.3924057183505063 7 -7.3924057183505072 16 -7.3924057183505072 19 -7.8056900478444984 - 20 -7.3924057183505019; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 2 3.8239532939043315 4 4.0648047266548115 - 7 0 16 0 19 4.5955098521668347 20 8.7811622696593155; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -7.3620493586843594 2 0.20742917859232701 - 4 13.300708001810973 7 41.567423254461779 16 41.567423254461779 19 64.205822324463625 - 20 81.566657370801593; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 11.229299623311356 2 -4.0235235023419671 - 4 11.229299623311356 7 11.229299623311356 16 11.229299623311356 19 -11.325478474133927 - 20 -23.884488550391008; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -47.425170065295866 2 -50.847426602078393 - 4 -47.425170065295866 7 -47.425170065295866 16 -47.425170065295866 19 -48.639053402913603 - 20 -48.184556498320411; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -15.059620758260801 2 -16.248026693665089 - 4 -15.059620758260801 7 -15.059620758260801 16 -15.059620758260801 19 -11.299337016217571 - 20 11.991848508498084; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 2 1 4 1 7 1 16 1 19 1 20 1; - setAttr -s 7 ".kit[3:6]" 3 3 9 3; - setAttr -s 7 ".kot[3:6]" 3 3 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1.9808213950621774 2 1.9808213950621776 - 4 1.9808213950621785 8 1.9808213950621805 12 1.980821395062182 16 1.9808213950621867 - 19 1.9808213950621898 20 1.9808213950621909; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 18.41992256503119 2 17.5648042732577 - 4 19.662864340591319 8 22.465004485504792 12 16.444893931989601 16 22.519284760552775 - 19 17.522230344830156 20 17.859988542372403; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 28.39740898729022 2 31.096571683529532 - 4 36.8657521678211 8 52.050851690712953 12 67.170375289917047 16 83.777913253213256 - 19 96.110338887997557 20 100.30869317838135; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 67.201049905350132 2 67.201049905350132 - 4 67.201049905350132 8 67.201049905350132 12 67.201049905350132 16 67.201049905350132 - 19 67.201049905350132 20 67.201049905350132; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 4 0 8 0 12 0 16 0 19 0 - 20 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 7.426073875550391 2 7.426073875550391 - 4 7.426073875550391 8 7.426073875550391 12 7.426073875550391 16 7.426073875550391 - 19 7.426073875550391 20 7.426073875550391; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 4 1 8 1 12 1 16 1 19 1 - 20 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; - setAttr -s 8 ".kot[1:7]" 5 9 9 9 9 5 9; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -1.3610577639827144 2 -0.21285352564148119 - 5.7960000000000003 3.5485029363551686 9.2360000000000007 1.3924894832037882 - 14 -3.8248141218513645 19 -0.21285352564148119 21 2.8197115728311255; - setAttr -s 7 ".kit[5:6]" 1 9; - setAttr -s 7 ".kot[5:6]" 1 9; - setAttr -s 7 ".kix[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".kiy[5:6]" 0.99956315755844116 0.999622642993927; - setAttr -s 7 ".kox[5:6]" 0.029554074630141258 0.027469120919704437; - setAttr -s 7 ".koy[5:6]" 0.99956315755844116 0.999622642993927; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.27858988479459218 2 0.15078676416754505 - 3 0.041071720760699121 5 -0.12734812175584798 11 0.01615418026612319 14 0.50054018883462204 - 19 0.15078676416754505 21 0.01581159374970395; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.039992513696998876 2 0.15149042747921673 - 3 0.38885909572774768 5 0.81318111183904007 11 0.47178511368290149 14 -0.68058277559896596 - 19 0.15149042747921673 21 0.6807047568788458; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 2 0 3 0 5 0 11 0 14 0 19 0 - 21 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 2 1 3 1 5 1 11 1 14 1 19 1 - 21 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 0.90991990467137285 6 0.757413731437375 - 11 0.52631001515514408 14 0.17989662655130284 16 0.11086142298673962 19 0.90991990467137285; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1.6840963091226424 6 1.9921588651806885 - 11 2.376954893450355 14 2.6063840737414372 16 2.5942005418897831 19 1.6840963091226424; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 2.8509277672757398 6 2.6074946383461919 - 11 2.2942978244046901 14 2.0606653100128796 16 2.0534195118150946 19 2.8509277672757398; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -82.189303625215842 6 -104.37729528867425 - 11 -92.006962071167038 14 -104.30491760011213 16 -98.611645848609228 19 -82.189303625215842; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 32.936642853707767 6 -8.8441659435333211 - 11 -23.718949300073728 14 -13.739625821068813 16 0.073490689192853564 19 - 32.936642853707767; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 -9.2450492652573306 6 -11.190509011262176 - 11 -15.571971397215279 14 -18.399796932359234 16 -15.14081226122182 19 -9.2450492652573306; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 2 1 6 1 11 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; - setAttr -s 7 ".kot[1:6]" 5 5 5 5 5 9; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0 2 0 7 0 11 0 15 0 19 0 - 21.972000000000001 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 2.3128351505039433 2 2.3128351505039433 - 7 2.3128351505039433 11 2.3128351505039433 15 2.3128351505039433 19 2.3128351505039433 - 21.972000000000001 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 0.23421866920666501 2 0.23421866920666501 - 7 0.23421866920666501 11 0.23421866920666501 15 0.23421866920666501 19 0.23421866920666501 - 21.972000000000001 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 18.015821706774922 2 7 7 - 17.885785658953552 11 7 15 17.865328849758896 19 7 21.972000000000001 17.767020748470053; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 -20.871491789318089 2 -26.903356467361473 - 7 6.6740813894110849 11 26 15 -2.3802552171770213 19 -26.903356467361473 - 21.972000000000001 -13.498742838462716; - setAttr -s 7 ".kit[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kot[2:6]" 1 9 1 9 9; - setAttr -s 7 ".kix[2:6]" 0.31150621175765991 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".kiy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; - setAttr -s 7 ".kox[2:6]" 0.3115062415599823 0.90359807014465332 - 0.28040501475334167 0.83153796195983887 0.46781390905380249; - setAttr -s 7 ".koy[2:6]" 0.95024412870407104 -0.42838135361671448 - -0.95988178253173828 -0.55546796321868896 0.88382697105407715; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -1.3720000000000001 7.6978127730792556 - 2 15.011069830747704 7 0.81964143355547092 11 5.6889805773011233 15 1.2715285190009615 - 19 15.011069830747704 21.972000000000001 16.516055040920126; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" -0.636 1 2 1 7 1 11 1 15 1 19 1 - 21.972000000000001 1; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 5 1 8 1 11 1 19 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0.27427147149852044 5 0.27427147149852044 - 8 0.27427147149852044 11 0.27427147149852044 19 0.27427147149852044; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.1074984126668126 5 -1.1074984126668126 - 8 -1.1074984126668126 11 -1.1074984126668126 19 -1.1074984126668126; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -1.642626684874722 5 -1.642626684874722 - 8 -1.642626684874722 11 -1.642626684874722 19 -1.642626684874722; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 0 5 0 8 0 11 0 19 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -72.192682186483722 5 -112.43723771647277 - 8 -140.9476176021825 11 -76.320044575450154 19 -72.192682186483722; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 8 1 12 1 16 1 19 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -0.2742786288673521 8 -0.2742786288673521 - 12 -0.2742786288673521 16 -0.2742786288673521 19 -0.2742786288673521; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.1075115373407667 8 -1.1075115373407667 - 12 -1.1075115373407667 16 -1.1075115373407667 19 -1.1075115373407667; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 -1.6426166407301896 8 -1.6426166407301896 - 12 -1.6426166407301896 16 -1.6426166407301896 19 -1.6426166407301896; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 8 0 12 0 16 0 19 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 57.295779513082337 8 46.221739108863801 - 12 83.651838089100195 16 124.90479933851947 19 57.295779513082337; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 1 4 1 5 1 6 0 9 0 10 0 11 1; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 3 0 4 0.60000000000000009 5 1 6 - 0.30000000000000004 9 0.046875 10 0 11 0; - setAttr -s 7 ".kit[6]" 9; - setAttr -s 7 ".kot[6]" 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 1 9 1 12 1 14 0 17 0 19 1; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 3 0 9 0 12 1 14 0 17 0 19 0; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 8 1 12 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -66.817792973155349 8 -117.76998860514637 - 12 -58.717593899130961 19 -66.817792973155349; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -49.477141044160646 8 -45.114889989798428 - 12 -58.488201638849723 19 -49.477141044160646; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -52.341476887309149 8 -22.64196747141678 - 12 -76.449769012401859 19 -52.341476887309149; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.5814880999021691 8 0.5814880999021691 - 12 0.5814880999021691 19 0.5814880999021691; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 1 10 1 14 1 19 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -168.75212351198743 10 -142.34379908236403 - 14 -91.772226065525047 19 -168.75212351198743; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 44.488737867426309 10 11.646024816259962 - 14 57.8461210256567 19 44.488737867426309; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 -70.747288710930945 10 -54.074322568995257 - 14 -28.519478878489718 19 -70.747288710930945; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 2 0.52893863520222695 10 0.52893863520222695 - 14 0.52893863520222695 19 0.52893863520222695; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.90858890976581275 7 -3.7621162796982501 - 14 0.3657111927859622 16 -0.5854119341237376 19 -0.90858890976581275; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 6.2382713968077237 7 5.3887456806949574 - 14 6.0204513845034606 16 5.8835786026344072 19 6.2382713968077237; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -0.55501859990651525 7 1.684897371141969 - 14 -0.55708239243809732 16 2.3929863357066576 19 -0.55501859990651525; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -22.350064437213423 7 -13.094561677764091 - 14 -16.423765740015508 16 -18.438399824774098 19 -22.350064437213423; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 -10.303773027856268 7 6.151404343053847 - 14 8.9343731574279008 16 7.5138197933918374 19 -10.303773027856268; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 8.8115085199100047 7 22.517921127381236 - 14 29.420970529265055 16 16.267284651382163 19 8.8115085199100047; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 3 1 7 1 14 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 6.7758528420198658 16 6.7758528420198658 - 19 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9388939039072284e-018 16 - -6.9388939039072284e-018 19 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -9.5120444723942321e-016 16 - -9.5120444723942321e-016 19 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -12.784757077400341 16 -91.730384948739413 - 19 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 3.2695897469829736 16 3.2695897469829762 - 19 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 -6.9162979482121409 16 -6.9162979482121507 - 19 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 11 1 16 1 19 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0.74525677667777757 6 0.74525677667777757 - 11 0.74525677667777757 15 0.74525677667777757 19 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1.8072476834435935 6 1.8072476834435935 - 11 1.8072476834435935 15 1.8072476834435935 19 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 13.355267980117441 11 0 15 - 7.2929987411270378 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 0 6 0 11 0 15 0 19 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 2 1 6 1 11 1 15 1 19 1; -select -ne :time1; - setAttr ".o" 6; -select -ne :renderPartition; - setAttr -s 11 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 11 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :hyperGraphLayout; - setAttr ".cch" no; - setAttr ".ihi" 2; - setAttr ".nds" 0; - setAttr ".img" -type "string" ""; - setAttr ".ims" 1; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002751997 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".t" -type "double3" 4.7296155549506897 2.1608864069345106 -3.0054669522092379 ; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".t" -type "double3" 12.412879749935719 -6.7286993982861674 -3.868763862603668 ; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".t" -type "double3" -5.4675296479599407 2.0844803122567583 -3.0869908056348607 ; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".t" -type "double3" -12.41287000000041 -6.7285999999993047 -3.8687599999999316 ; - setAttr ".r" -type "double3" 71.709623779134716 -1.1088233856739415e-014 - -20.50358129699524 ; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_RIK; - setAttr ".r" -type "double3" -66.065354836318264 28.775852580156471 -91.471856426984459 ; - setAttr ".twi" 217.7239621497128; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Rwing_null; - setAttr ".t" -type "double3" -0.24500268074642695 1.2065238412698649 -0.38309524546711837 ; - setAttr ".r" -type "double3" -14.614862034248505 33.316404488343842 -119.57538852061882 ; - setAttr ".s" -type "double3" 0.33812841032783514 0.33812841032783514 0.33812841032783514 ; -select -ne IMP_Lwing_null; - setAttr ".t" -type "double3" -3.7373203203190113 -2.4972392481870522 3.6496305501990709 ; - setAttr ".r" -type "double3" 62.667511380374542 -13.204130585379209 40.323400206122145 ; - setAttr ".s" -type "double3" 0.2797760798095944 0.2797760798095944 0.27977607980959479 ; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing3; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rwing4; - setAttr ".s" -type "double3" 0.5814880999021691 0.5814880999021691 0.5814880999021691 ; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of scurry2.ma diff --git a/base/models/monsters/imp/animation/cycles/scurry_leap2.ma b/base/models/monsters/imp/animation/cycles/scurry_leap2.ma deleted file mode 100644 index da7720562..000000000 --- a/base/models/monsters/imp/animation/cycles/scurry_leap2.ma +++ /dev/null @@ -1,8243 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:24 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: scurry_leap2.ma -//Last modified: Mon, Mar 17, 2003 11:53:25 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 720.26757732003796 90.341300754902989 336.50441696121419 ; - setAttr ".r" -type "double3" -11.730108906695333 -1736.59999999974 -1.7758180503070084e-015 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 584.70972522043064; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 173.57325666100638 3.3805620558039777 -17.517110055926459 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 79.72306854705441 168.32465943840063 14.032308451754792 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 250.03182692930133; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 426.38591646366035 24.207613699686657 215.31705294060819 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 336.45985012315282; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 503.1108425748202 37.205902318164846 12.342629946130748 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 244.44410022721146; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode transform -n "pointLight1"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape1" -p "pointLight1"; - setAttr -k off ".v"; - setAttr ".in" 0.5; -createNode transform -n "group2"; - setAttr ".t" -type "double3" 297.75049857774576 -2.8421709430404007e-014 - 115.34478773732499 ; - setAttr ".rp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; - setAttr ".sp" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode transform -n "pointLight2" -p "group2"; - setAttr ".t" -type "double3" -51.380734638089606 118.25846578140839 15.657664928064008 ; -createNode pointLight -n "pointLightShape2" -p "pointLight2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"all\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"all\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 48 -ast 1 -aet 48 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185075120832098; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8119691574396866; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9186219656239931; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1258655568218376; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6185070801020824; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.3244262317670241; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0332012531196431; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.463963295533194; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 36 1 39 1 48 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 36 0 39 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 13.71946295727715 20 13.71946295727715 - 28 13.71946295727715 36 13.71946295727715 39 13.71946295727715 48 13.71946295727715; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 36 0 39 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 68.596496127541187 20 68.596496127541187 - 28 68.596496127541187 36 68.596496127541187 39 68.596496127541187 48 68.596496127541187; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -60.802874383230787 20 -60.802874383230787 - 28 -60.802874383230787 36 -60.802874383230787 39 -60.802874383230787 48 -60.802874383230787; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -157.43468421330525 20 -157.43468421330525 - 28 -157.43468421330525 36 -157.43468421330525 39 -157.43468421330525 48 -157.43468421330525; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459183 20 15.445123296459183 - 28 15.445123296459183 36 15.445123296459183 39 15.445123296459183 48 15.445123296459183; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 36 15.445123296459185 39 15.445123296459185 48 15.445123296459185; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 15.445123296459181 20 15.445123296459181 - 28 15.445123296459181 36 15.445123296459181 39 15.445123296459181 48 15.445123296459181; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 28 1 36 1 39 1 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.010024364806417531 20 0 28 - 0.20000000000000001 36 0.20000000000000001 39 0.096209918545383938 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 36 0 39 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.42673163973887457 20 0.40000000000000002 - 28 1 36 1 39 0 48 1; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 28 1 31 1 32 1 36 1 39 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.5294371750177831 20 -2.5294371750177831 - 28 -2.5294371750177831 31 -2.5294371750177831 32 -2.5294371750177831 36 -2.5294371750177831 - 39 -2.5294371750177831 48 -2.5294371750177831; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 13.481673551673362 20 13.481673551673362 - 28 13.481673551673362 31 13.481673551673362 32 13.481673551673362 36 13.481673551673362 - 39 13.481673551673362 48 13.481673551673362; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.26635088939205875 20 -0.26635088939205875 - 28 -0.26635088939205875 31 -0.26635088939205875 32 -0.26635088939205875 36 - -0.26635088939205875 39 -0.26635088939205875 48 -0.26635088939205875; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 73.167297059293915 20 73.167297059293915 - 28 73.167297059293915 31 73.167297059293915 32 73.167297059293915 36 73.167297059293915 - 39 73.167297059293915 48 73.167297059293915; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 61.241182877125034 20 61.241182877125034 - 28 61.241182877125034 31 61.241182877125034 32 61.241182877125034 36 61.241182877125034 - 39 61.241182877125034 48 61.241182877125034; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 177.69376467901077 20 177.69376467901077 - 28 177.69376467901077 31 177.69376467901077 32 177.69376467901077 36 177.69376467901077 - 39 177.69376467901077 48 177.69376467901077; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 31 15.445123296459185 32 15.445123296459185 36 15.445123296459185 - 39 15.445123296459185 48 15.445123296459185; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 31 15.445123296459185 32 15.445123296459185 36 15.445123296459185 - 39 15.445123296459185 48 15.445123296459185; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 15.445123296459185 20 15.445123296459185 - 28 15.445123296459185 31 15.445123296459185 32 15.445123296459185 36 15.445123296459185 - 39 15.445123296459185 48 15.445123296459185; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 28 1 31 1 32 1 36 1 39 - 1 48 1; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 28 0.5 31 0.54367346977328057 - 32 0.54064000626006248 36 0 39 0.62187499874627028 48 0.19999999999999996; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 28 0 31 0 32 0 36 0 39 - 0 48 0; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 28 1 31 1.0653061208314818 - 32 0 36 1 39 1 48 1; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 19 1 20 1 21 1 24 1 28 - 1 30 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 168.17683573869542 11 168.17683573869542 - 19 168.17683573869542 20 174.45875310346568 21 204.61233919052719 24 312.63720843599691 - 28 421.00009276477823 30 445.81800735194054 31 452.25292697055562 32 450.50038802308978 - 36 453.30445033903504 37 457.65822519344783 39 477.67862137991438 42 492.8771753136453 - 48 488.83835986739177; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 3.1848718158837808 11 3.1848718158837808 - 19 3.1848718158837808 20 15.40856811014881 21 38.08937776192316 24 71.388929535583443 - 28 59.719225939125216 30 19.422814800215999 31 7.8697813833574006 32 2.0864028567203126 - 36 6.8182580148779373 37 5.6384519499601051 39 13.141017755672562 42 24.047030640291752 - 48 38.925325779930411; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -18.214943034405117 11 -18.214943034405117 - 19 -18.214943034405117 20 -17.697410863169523 21 -18.214943034405117 24 -33.656396560950455 - 28 -38.499368838504409 30 -27.191796801254359 31 -15.377764021452805 32 -15.377764021452805 - 36 -15.377764021452805 37 -15.182367808890572 39 -15.377764021452805 42 -20.653461802270328 - 48 -26.083513050539345; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 219.80154311026268 11 219.80154311026268 - 19 219.80154311026268 20 296.42872753988729 21 252.67500881186177 24 414.48525500682922 - 28 326.88313129670559 30 402.3692513842521 31 399.75421244244444 32 361.75246976057394 - 36 388.54315471056964 37 382.12979672988405 39 446.2181411264944 42 470.82609984934618 - 48 441.51022981784752; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 103.06211582598448 11 103.06211582598448 - 19 103.06211582598448 20 103.06211582598425 21 76.748267997145021 24 138.28353981948115 - 28 146.51207909713125 30 160.53188760921961 31 128.89442661327502 32 128.8944266132749 - 36 130.20957118662795 37 126.422682041705 39 149.08574357438997 42 133.83971002200158 - 48 132.94446310792156; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 179.66289643582957 11 179.66289643582957 - 19 179.66289643582957 20 179.66289643582925 21 122.61921513781505 24 346.06828034955765 - 28 401.27383014999248 30 424.0923332662079 31 371.32760212837917 32 371.32760212837917 - 36 316.59454777258998 37 319.37663179388846 39 335.03872044309094 42 367.06275467923081 - 48 439.67161200383958; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 11 1 18 1 19 1 20 1 21 1 24 - 1 28 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 17 ".kot[0:16]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 140.97009257432202 11 140.97009257432202 - 18 140.97009257432202 19 153.42613132068399 20 176.71205382657112 21 205.9493946777971 - 24 342.56951419697054 28 414.82270228531723 30 448.90319076067277 31 469.19062464103354 - 36 469.19062464103354 37 469.19062464103354 38 468.58241398510978 39 469.19062464103354 - 42 481.35483834186607 43 485.19666334113225 48 477.16455926606267; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 3.616514330714832 11 3.616514330714832 - 18 3.616514330714832 19 7.3536469131173607 20 22.168814062164397 21 34.459460434475012 - 24 67.061325771298158 28 56.573827155279034 30 19.322678700267659 31 2.6452856272526155 - 36 2.6452856272526155 37 3.9380188496080599 38 6.5238902458078059 39 9.9316001532560243 - 42 21.558101071017969 43 28.015694893118134 48 42.133575417116042; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 5.5906769424741469 11 5.5906769424741469 - 18 5.5906769424741469 19 7.7790374995743417 20 13.012836068189541 21 13.175726632309505 - 24 21.942257454491596 28 28.102174266597292 30 17.688799523426916 31 17.688799523426916 - 36 17.688799523426916 37 18.393926735620784 38 16.901407469017983 39 18.158884331556173 - 42 17.688799523426916 43 16.93220396701745 48 18.833156565013795; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 -178.9145192530496 11 -178.9145192530496 - 18 -178.9145192530496 19 -167.69587374559055 20 -72.558494637865309 21 -72.558494637865309 - 24 -256.85303375760401 28 -295.55702963991496 30 -295.55702963991496 31 -323.43616169739801 - 36 -323.43616169739801 37 -301.98736295612144 38 -294.1473764072087 39 -284.1852919748419 - 42 -215.34826646492581 43 -201.47174946737618 48 -256.50049062084815; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 77.792981530281054 11 77.792981530281054 - 18 77.792981530281054 19 77.792981530281097 20 77.792981530281082 21 77.792981530281082 - 24 33.941676065657482 28 56.539878395975578 30 56.539878395975578 31 67.318721800853339 - 36 67.318721800853339 37 64.350871231601133 38 67.126204716457593 39 67.31872180085341 - 42 38.522706263852164 43 35.653912925478181 48 18.052275906821958; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 146.44536767645329 11 146.44536767645329 - 18 146.44536767645329 19 146.44536767645334 20 146.44536767645306 21 146.44536767645306 - 24 91.230110731846636 28 92.774179834952406 30 92.774179834952406 31 39.044332496204468 - 36 39.044332496204468 37 42.18224322723831 38 39.690533059175472 39 39.044332496204518 - 42 60.637340161233091 43 65.527995150390169 48 23.269369027924608; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11 1 18 1 25 1 28 1 30 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 11 0 18 0 25 0 28 0 30 0; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.6268319407172029 11 5.6268319407172029 - 18 5.6268319407172029 25 5.6268319407172029 28 5.6268319407172029 30 5.6268319407172029; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.1098668596606802 11 -2.1098668596606802 - 18 -2.1098668596606802 25 -2.1098668596606802 28 -2.1098668596606802 30 -2.1098668596606802; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 360.76739391711288 11 336.00205489946853 - 18 342.74743969676229 25 317.57893234324393 28 321.18672728105173 30 375.1012001423897; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.39334696132271052 11 22.934613158314267 - 18 3.3751297566513738 25 -4.8433113423463121 28 1.1508514452864951 30 1.1508514452864969; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -18.700472818991617 11 -35.808201433501473 - 18 -4.0181375389538863 25 24.770489890383015 28 16.328915349246696 30 16.328915349246685; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11 1 18 1 25 1 28 1 30 1; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11 1 18 1 25 1 28 1 30 1; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11 1 18 1 25 1 28 1 30 1; - setAttr -s 6 ".kit[3:5]" 9 9 9; - setAttr -s 6 ".kot[3:5]" 9 9 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 13 1 16 1 19 1 20 1 21 1 24 - 1 28 1 29 1 30 1 34 1 38 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.1689522478599494 13 7.1689522478599494 - 16 7.1689522478599503 19 7.1689522478599503 20 7.1689522478599521 21 7.1689522478599521 - 24 7.168952247859977 28 7.1689522478599788 29 6.9254562659520369 30 6.9254562659520369 - 34 6.9254562659520369 38 7.554986848268765; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0.0996086992316223 13 0.0996086992316223 - 16 0.0996086992316223 19 0.0996086992316223 20 13.885214912807996 21 18.398798644770412 - 24 40.607487748057665 28 26.84137245585238 29 18.206727723569827 30 -0.78935344339909386 - 34 -0.78935344339909386 38 -0.35211369179784302; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 79.36659147624809 13 79.36659147624809 - 16 91.926810470839854 19 91.926810470839854 20 101.91146766498335 21 123.17418455494628 - 24 210.4020721612647 28 276.74211772328857 29 298.55012155462475 30 316.63157659133202 - 34 316.63157659133202 38 360.41441440815493; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -174.49049195404214 13 -174.49049195404214 - 16 -174.49049195404214 19 -174.49049195404214 20 -301.53506754966133 21 -301.53506754966133 - 24 -301.53506754966133 28 -301.53506754966133 29 -80.195825489861193 30 10.11833837859974 - 34 10.11833837859974 38 6.0578085460824589; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 129.78625356110399 13 129.78625356110399 - 16 129.78625356110399 19 129.78625356110399 20 156.57861554381626 21 156.57861554381626 - 24 156.57861554381626 28 156.57861554381626 29 1.4379585757962667 30 22.148402438321622 - 34 22.148402438321622 38 14.559598429561929; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -169.93906815090079 13 -169.93906815090079 - 16 -169.93906815090079 19 -169.93906815090079 20 -201.27457036315781 21 -201.27457036315781 - 24 -201.27457036315781 28 -201.27457036315781 29 -29.493568390973312 30 8.7946878310934409 - 34 8.7946878310934409 38 8.2507937920490004; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 13 1 16 1 19 1 20 1 21 1 24 - 1 28 1 29 1 30 1 34 1 38 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 13 1 16 1 19 1 20 1 21 1 24 - 1 28 1 29 1 30 1 34 1 38 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 13 1 16 1 19 1 20 1 21 1 24 - 1 28 1 29 1 30 1 34 1 38 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 125.1606853982252; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 77.825664227235052; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -175.25743303308352; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 7 1 19 1 20 1 21 1 24 1 28 - 1 30 1 34 1 38 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -7.3924057183505028 7 -7.3924057183505019 - 19 -7.3924057183505019 20 -7.3924057183505001 21 -7.3924057183505001 24 -7.3924057183504752 - 28 -7.3924057183504734 30 -6.3308105672263544 34 -6.3308105672263544 38 -7.1642625370327009; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 4.9564581926526348 7 -1.4768247070163421 - 19 -1.4768247070163421 20 15.984943163513709 21 20.498526895476129 24 56.954837136122279 - 28 30.658960459157367 30 -0.73746868555280376 34 -0.73746868555280376 38 - 0.10836812690888847; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 68.031874733613122 7 90.701538284827592 - 19 90.701538284827592 20 101.91158269795564 21 123.17429958791857 24 211.6974254794514 - 28 283.31583816613124 30 324.26429267227053 34 324.26429267227053 38 368.19750767188401; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -18.39795914825002 7 21.526450659699222 - 19 21.526450659699222 20 -109.5626727624874 21 -109.5626727624874 24 -146.39991688279261 - 28 -109.5626727624874 30 15.958661750368087 34 15.958661750368087 38 12.355198312075999; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -48.06590236816033 7 -38.053954061890678 - 19 -38.053954061890678 20 -37.885237316356623 21 -37.885237316356623 24 -29.684032640488194 - 28 -37.885237316356623 30 -38.059156299065826 34 -38.059156299065826 38 -35.152508962264037; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 7.7650564355670078 7 -10.667864335873874 - 19 -10.667864335873874 20 3.766736197967794 21 3.766736197967794 24 25.709605253119321 - 28 3.766736197967794 30 -11.009931379047687 34 -11.009931379047687 38 -11.865112406666784; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 7 1 19 1 20 1 21 1 24 1 28 - 1 30 1 34 1 38 1; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 7 1 19 1 20 1 21 1 24 1 28 - 1 30 1 34 1 38 1; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 7 1 19 1 20 1 21 1 24 1 28 - 1 30 1 34 1 38 1; - setAttr -s 10 ".kit[3:9]" 9 9 9 9 3 3 3; - setAttr -s 10 ".kot[3:9]" 9 9 9 9 3 3 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 21 1 24 1 28 - 1 30 1 33 1 37 1 42 1 48 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 2.5125681904581358 9 1.9808213950621905 - 13 1.9808213950621907 18 9.2715722022641724 21 1.9808213950622011 24 1.9808213950622344 - 28 1.9808213950622338 30 1.9808213950622389 33 1.9808213950622422 37 1.9808213950622449 - 42 1.9808213950622469 48 1.9808213950622469; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 20.712711117205764 9 17.888078116974704 - 13 14.961295939818349 18 14.961295939818349 21 38.362758162965797 24 51.2994247846391 - 28 27.223956596613224 30 27.223956596613224 33 15.285400949656662 37 32.085445927310325 - 42 25.749545601781694 48 32.965802640076575; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 96.110338887997557 9 101.4151315840935 - 13 107.81746759662305 18 107.81746759662305 21 157.10550307546458 24 244.33339068178299 - 28 310.95588426834991 30 333.64740089743867 33 347.87539237621274 37 360.25559275384734 - 42 369.39210044166862 48 369.39210044166862; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 78.375584465882739 9 98.125289811229464 - 13 92.168404719170013 18 92.168404719170013 21 56.307325565710279 24 56.307325565710279 - 28 56.307325565710279 30 56.307325565710279 33 56.307325565710279 37 56.307325565710279 - 42 13.151157979144362 48 13.151157979144362; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.9513867036587919e-016 9 0 13 - 0 18 0 21 11.49524675155142 24 11.49524675155142 28 11.49524675155142 30 - 11.49524675155142 33 11.49524675155142 37 11.49524675155142 42 11.495246751551425 - 48 11.495246751551425; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 7.4260738755503892 9 7.426073875550375 - 13 7.4260738755503644 18 7.4260738755503644 21 -20.965676744725002 24 -20.965676744725002 - 28 -20.965676744725002 30 -20.965676744725002 33 -20.965676744725002 37 -20.965676744725002 - 42 -20.965676744725013 48 -20.965676744725013; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 21 1 24 1 28 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 21 1 24 1 28 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 9 1 13 1 18 1 21 1 24 1 28 - 1 30 1 33 1 37 1 42 1 48 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21285352564148119; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15078676416754505; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.15149042747921673; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 17 1 19 1 28 1 30 1 36 - 1 42 1 48 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.90991990467137285 13 0.90991990467137285 - 17 0.90991990467137285 19 3.2165938865377592 28 3.2165938865377592 30 3.2165938865377592 - 36 3.2165938865377592 42 3.2165938865377592 48 3.2165938865377592; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.6840963091226424 13 1.6840963091226424 - 17 1.6840963091226424 19 1.0198173250982352 28 1.0198173250982352 30 1.0198173250982352 - 36 1.0198173250982352 42 1.0198173250982352 48 1.0198173250982352; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.8509277672757398 13 2.8509277672757398 - 17 2.8509277672757398 19 5.5089484635562949 28 5.5089484635562949 30 5.5089484635562949 - 36 5.5089484635562949 42 5.5089484635562949 48 5.5089484635562949; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -81.50691442197396 13 -31.261146897838977 - 17 -76.052449399988134 19 14.028238821473778 28 -32.812965905662523 30 -84.048401441518692 - 36 -100.98950409530727 42 -55.664830857165363 48 -37.750911612187679; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 30.964642776910992 13 16.829153229070521 - 17 17.998418905573541 19 61.793759660292352 28 18.346128357839692 30 -3.8527038109155853 - 36 2.9181746341270869 42 8.3717076859878041 48 21.674975974628239; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.8358968951012837 13 6.4562833550431655 - 17 -20.729425848392836 19 20.568981510619366 28 9.5251459779590153 30 -3.3299002212729572 - 36 -35.030428448148584 42 -3.6057329631056776 48 -6.3849825779711411; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 17 1 19 1 28 1 30 1 36 - 1 42 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 17 1 19 1 28 1 30 1 36 - 1 42 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 17 1 19 1 28 1 30 1 36 - 1 42 1 48 1; - setAttr -s 9 ".kit[0:8]" 3 3 3 9 9 9 9 - 9 9; - setAttr -s 9 ".kot[0:8]" 3 3 3 9 9 9 9 - 9 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 17 1 19 1 22 1 30 1 35 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10 0 17 0 19 0 22 0 30 0 35 - 0 48 0; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.3128351505039433 10 2.3128351505039433 - 17 2.3128351505039433 19 2.3128351505039433 22 2.3128351505039433 30 2.3128351505039433 - 35 2.3128351505039433 48 2.3128351505039433; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.23421866920666501 10 0.23421866920666501 - 17 0.23421866920666501 19 0.23421866920666501 22 0.23421866920666501 30 0.23421866920666501 - 35 0.23421866920666501 48 0.23421866920666501; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.671711834718816 10 -3.671711834718816 - 17 -0.38903580510386404 19 24.430204060920861 22 20.858840660148381 30 27.159710134283735 - 35 33.513181175101714 48 16.877903135718185; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -30.925240358666347 10 -30.925240358666347 - 17 -8.0093455226114028 19 -36.190660550952373 22 12.125593470464233 30 21.141076518420324 - 35 21.151855214980227 48 -2.7299381262472755; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 24.795614393044964 10 24.795614393044964 - 17 28.310029710143734 19 11.117279450806294 22 1.7686655262962976 30 15.451645632735099 - 35 28.619674064500245 48 0.26452410412025396; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 17 1 19 1 22 1 30 1 35 - 1 48 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 17 1 19 1 22 1 30 1 35 - 1 48 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10 1 17 1 19 1 22 1 30 1 35 - 1 48 1; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 28 1 32 1 38 1 48 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 28 0 32 0 38 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 28 0 32 0 38 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 28 0 32 0 38 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 28 1 32 1 38 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 28 1 32 1 38 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 12 1 13 1 14 1 15 1 16 - 1 17 1 18 1 19 1 20 1 28 1 32 1 38 1 48 1; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.27427147149852044 11 0.27427147153653575 - 12 0.27427147153797948 13 0.27427147153980314 14 0.27427147154217391 15 0.2742714715453653 - 16 0.27427147154983328 17 0.27427147155621612 18 0.27427147156259896 19 0.27427147156259896 - 20 0.27427147156259896 28 0.27427147156259896 32 0.27427147156259896 38 0.27427147156259896 - 48 0.27427147156259896; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -1.1074984126668126 11 -1.1074984146392313 - 12 -1.1074984147141391 13 -1.1074984148087597 14 -1.1074984149317662 15 -1.1074984150973519 - 16 -1.107498415329172 17 -1.1074984156603436 18 -1.1074984159915151 19 -1.1074984159915151 - 20 -1.1074984159915151 28 -1.1074984159915151 32 -1.1074984159915151 38 -1.1074984159915151 - 48 -1.1074984159915151; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -1.642626684874722 11 -1.6426266835385228 - 12 -1.6426266834877772 13 -1.6426266834236773 14 -1.6426266833403476 15 -1.6426266832281728 - 16 -1.642626683071128 17 -1.6426266828467784 18 -1.6426266826224289 19 -1.6426266826224289 - 20 -1.6426266826224289 28 -1.6426266826224289 32 -1.6426266826224289 38 -1.6426266826224289 - 48 -1.6426266826224289; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 28 0 32 0 38 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 11 0 12 0 13 0 14 0 15 0 16 - 0 17 0 18 0 19 0 20 0 28 0 32 0 38 0 48 0; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -37.815214478634331 11 -125.74912876606732 - 12 -125.51192920989145 13 -100.00216573212361 14 -59.835637123346231 15 -36.233993668944173 - 16 -35.413141578212446 17 -49.792207316432325 18 -114.59155902616467 19 -86.44861012607744 - 20 -95.110993991716668 28 -14.896902673401405 32 -57.295779513082323 38 -59.587610693605619 - 48 -83.651838089100195; - setAttr -s 15 ".kit[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; - setAttr -s 15 ".kot[0:14]" 3 3 3 3 3 3 3 - 9 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 28 1 35 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 28 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 28 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 28 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 28 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 28 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10 1 17 1 18 1 19 1 20 1 24 - 1 28 1 35 1 48 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.2742786288673521 10 -0.27427863453231033 - 17 -0.27427863453231033 18 -0.27427863453231033 19 -0.27427863453231033 20 - -0.27427863453231033 24 -0.27427863453231033 28 -0.27427863453231033 35 -0.27427863453231033 - 48 -0.27427863453231033; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.1075115373407667 10 -1.1075115557303763 - 17 -1.1075115557303763 18 -1.1075115557303763 19 -1.1075115557303763 20 -1.1075115557303763 - 24 -1.1075115557303763 28 -1.1075115557303763 35 -1.1075115557303763 48 -1.1075115557303763; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.6426166407301896 10 -1.6426166273853338 - 17 -1.6426166273853338 18 -1.6426166273853338 19 -1.6426166273853338 20 -1.6426166273853338 - 24 -1.6426166273853338 28 -1.6426166273853338 35 -1.6426166273853338 48 -1.6426166273853338; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 28 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10 0 17 0 18 0 19 0 20 0 24 - 0 28 0 35 0 48 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 108.86198107485642 10 108.86198107485642 - 17 73.338597776745388 18 26.403355291791605 19 54.852317270957315 20 93.965078401455045 - 24 92.285269732770345 28 21.772396214971302 35 29.793805346802827 48 61.879441874128936; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.14201183279855 20 1 28 1 36 - 1 39 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 28 0 36 0 39 0 48 0; - setAttr -s 6 ".kit[0:5]" 3 9 9 9 9 9; - setAttr -s 6 ".kot[0:5]" 3 9 9 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 20 1 28 1 31 1.0367346951942145 - 32 1 36 1 39 0 48 0; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 20 0 28 0 31 0 32 0 36 0 39 - 0 48 0; - setAttr -s 8 ".kit[1:7]" 9 9 3 3 3 3 9; - setAttr -s 8 ".kot[1:7]" 9 9 3 3 3 3 9; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6 1 11 1 18 1 20 1 27 1 34 - 1 48 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -28.073881032405502 6 -46.403838232154726 - 11 -57.268694860493916 18 -64.448733245059486 20 -85.021389942138228 27 -96.759313977435809 - 34 -81.70071573151256 48 -92.276866801256645; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -61.199228718418333 6 -52.589856193268211 - 11 -48.400115258246736 18 -43.995383780771014 20 -56.304528730735143 27 -41.2276998033512 - 34 -55.139126251391993 48 -76.844287356428978; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -81.184232108591999 6 -75.778137454888423 - 11 -62.491121494028498 18 -64.875827156229477 20 -23.876400721722792 27 -34.093153518684247 - 34 -33.172769882599198 48 -6.4131326743179056; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.5814880999021691 6 0.5814880999021691 - 11 0.5814880999021691 18 0.5814880999021691 20 0.5814880999021691 27 0.5814880999021691 - 34 0.5814880999021691 48 0.5814880999021691; - setAttr -s 8 ".kit[0:7]" 3 9 9 9 9 9 9 - 9; - setAttr -s 8 ".kot[0:7]" 3 9 9 9 9 9 9 - 9; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 13 1 19 1 22 1 29 1 34 1 48 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -117.99254693569441 13 -123.98803296810649 - 19 -131.56223464759714 22 -143.68624235845436 29 -118.25457552859019 34 -118.19943411562497 - 48 -137.79238049393118; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 27.075624429458429 13 25.391307459182691 - 19 20.623216711056333 22 37.500675079600633 29 12.160180912642328 34 24.003088726248219 - 48 55.642180590844198; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -35.130967703309707 13 -76.878252144223026 - 19 -53.588570440441174 22 -49.075623471088711 29 -63.575828601904099 34 -35.895713294177334 - 48 -20.939120123829618; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.52893863520222695 13 0.52893863520222695 - 19 0.52893863520222695 22 0.52893863520222695 29 0.52893863520222695 34 0.52893863520222695 - 48 0.52893863520222695; - setAttr -s 7 ".kit[0:6]" 3 9 9 9 9 9 9; - setAttr -s 7 ".kot[0:6]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.90858890976581275; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2382713968077237; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.55501859990651525; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -22.350064437213423; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -10.303773027856268; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.8115085199100047; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 11 1 18 1 19 1 20 1 21 1 24 - 1 28 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 0.99999999999999978 11 0.99999999999999978 - 18 0.99999999999999978 19 0.99999999999999978 20 0.99999999999999978 21 0.99999999999999978 - 24 0.99999999999999978 28 0.99999999999999978 30 0.99999999999999978 31 0.99999999999999978 - 36 0.99999999999999978 37 0.99999999999999978 38 0.99999999999999978 39 0.99999999999999978 - 42 0.99999999999999978 43 0.99999999999999978 48 0.99999999999999978; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 17 ".ktv[0:16]" 1 1 11 1 18 1 19 1 20 1 21 1 24 - 1 28 1 30 1 31 1 36 1 37 1 38 1 39 1 42 1 43 1 48 1; - setAttr -s 17 ".kit[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; - setAttr -s 17 ".kot[0:16]" 3 3 3 9 9 9 9 - 9 9 3 9 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 11 1 19 1 20 1 21 1 24 1 28 - 1 30 1 31 1 32 1 36 1 37 1 39 1 42 1 48 1; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.99999999999999989 11 0.99999999999999989 - 19 0.99999999999999989 20 0.99999999999999989 21 0.99999999999999989 24 0.99999999999999989 - 28 0.99999999999999989 30 0.99999999999999989 31 0.99999999999999989 32 0.99999999999999989 - 36 0.99999999999999989 37 0.99999999999999989 39 0.99999999999999989 42 0.99999999999999989 - 48 0.99999999999999989; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0.99999999999999978 11 0.99999999999999978 - 19 0.99999999999999978 20 0.99999999999999978 21 0.99999999999999978 24 0.99999999999999978 - 28 0.99999999999999978 30 0.99999999999999978 31 0.99999999999999978 32 0.99999999999999978 - 36 0.99999999999999978 37 0.99999999999999978 39 0.99999999999999978 42 0.99999999999999978 - 48 0.99999999999999978; - setAttr -s 15 ".kit[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; - setAttr -s 15 ".kot[3:14]" 9 9 9 9 9 9 3 - 3 3 3 3 3; -createNode animCurveTU -n "IMP_locator5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_camera_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_locator14_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.25; -createNode animCurveTU -n "IMP_Rwing_thing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing_thing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_thing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_lelbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_lelbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_lelbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_relbow_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_relbow_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator5_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_pointConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator5_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator5_orientConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.1057240879120851; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.5956396785200369; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3817563473270154; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator6_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_pointConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator6_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator6_orientConstraint1_LhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lmissile_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41001647724799928; -createNode animCurveTL -n "IMP_Lmissile_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1693934765127816; -createNode animCurveTL -n "IMP_Lmissile_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.5729514457211735; -createNode animCurveTA -n "IMP_Lmissile_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lmissile_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lmissile_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lmissile_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_camera_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_pointConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_camera_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_camera_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_camera_orientConstraint1_eyesW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator14_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_pointConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator14_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator14_orientConstraint1_HeadW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_cam_connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0046539604129529621; -createNode animCurveTL -n "IMP_cam_connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.4094890802521576; -createNode animCurveTL -n "IMP_cam_connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0367577756137232; -createNode animCurveTA -n "IMP_cam_connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.11875208173462; -createNode animCurveTA -n "IMP_cam_connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085761516203950224; -createNode animCurveTA -n "IMP_cam_connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1776791248832486e-005; -createNode animCurveTU -n "IMP_cam_connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_cam_connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_eyes_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.034284369950123843; -createNode animCurveTL -n "IMP_eyes_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9944975057013083; -createNode animCurveTL -n "IMP_eyes_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.9109443986143884; -createNode animCurveTA -n "IMP_eyes_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -147.00752219093516; -createNode animCurveTA -n "IMP_eyes_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_eyes_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 180; -createNode animCurveTU -n "IMP_eyes_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_eyes_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_eyes_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator13_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.0032893248995669033; -createNode animCurveTL -n "IMP_locator13_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.42074550807650996; -createNode animCurveTL -n "IMP_locator13_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -88.322777837915837; -createNode animCurveTA -n "IMP_locator13_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 179.72494022541443; -createNode animCurveTA -n "IMP_locator13_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0085757562239429132; -createNode animCurveTA -n "IMP_locator13_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -179.99989705255965; -createNode animCurveTU -n "IMP_locator13_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator13_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0000000000000002; -createNode animCurveTU -n "IMP_locator13_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 87.843121583379272; -createNode animCurveTU -n "IMP_pCube1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_pCube1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.04673741311718338; -createNode animCurveTL -n "IMP_pCube1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.018550086981591107; -createNode animCurveTL -n "IMP_pCube1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.59134881205267886; -createNode animCurveTA -n "IMP_pCube1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_pCube1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_pCube1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99999999999999989; -createNode animCurveTU -n "IMP_pCube1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.81452695663524144; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.10942982456140288; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.3533140211779946; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 9.022004834100839; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.9550621233059426; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.88597689344963537; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.2916645882841449; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.7296155549506897; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.1608864069345106; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0054669522092379; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 28.836234092176063; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.5988200593703294; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 52.351071907336284; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -34.36059369489287; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -8.556853256702178; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -23.206907965932974; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.4675296479599407; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.0844803122567583; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.0869908056348607; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 26.659954467743521; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -49.492801424012306; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -100.40231940259616; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.257666229421972; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -9.5092015178261011; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 9.2053053109380052; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.55189552941641418; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0646191166984784; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 11.586085933787016; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 23.165861309280317; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 73.16163459057924; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21075234496274775; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 89.830862630651069; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1568819853431291; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.8855564166933343; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.39837671684541476; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.42012489059707847; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.043574269372096713; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.32542761684201271; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.7995714837697929; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -76.090633252486683; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.791362663024994; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 54.744021489634264; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.41525250862709329; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 113.88179442110163; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.88642296005711507; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -16.683497590890667; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.3423521551430217; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.3825986145063745; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.1098661950250604; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.35737371225579673; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 99.194475901955684; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 69.492034696563493; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 52.003739368178465; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 217.7239621497128; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.7373203203190113; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -2.4972392481870522; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6496305501990709; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 62.667511380374542; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -13.204130585379209; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 40.323400206122145; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Lwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Lwing_pointConstraint1_Lwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_joint8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint8_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint8_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint7_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint7_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint6_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint6_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint9_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_joint9_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_joint5_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_joint5_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rwing1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_Rwing_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_Rwing_pointConstraint1_Rwing_nullW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator3_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_pointConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator3_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator3_orientConstraint1_LloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_locator4_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_pointConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_locator4_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_locator4_orientConstraint1_RloarmW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -select -ne :time1; - setAttr ".o" 3; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".l"; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :defaultLightSet; - setAttr -s 2 ".dsm"; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933713 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643403 -66.654599961471263 -11.653334128372219 ; -select -ne IMP_Rhand_IK; -select -ne IMP_Lhand_IK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Rhand_GOAL; -select -ne IMP_Lhand_GOAL; -select -ne IMP_LHAND_ROT; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_locator5_visibility.o" "IMP_locator5.v"; -connectAttr "IMP_locator5_scaleX.o" "IMP_locator5.sx"; -connectAttr "IMP_locator5_scaleY.o" "IMP_locator5.sy"; -connectAttr "IMP_locator5_scaleZ.o" "IMP_locator5.sz"; -connectAttr "IMP_locator5_pointConstraint1_nodeState.o" "IMP_locator5_pointConstraint1.nds" - ; -connectAttr "IMP_locator5_pointConstraint1_RhandW0.o" "IMP_locator5_pointConstraint1.w0" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetX.o" "IMP_locator5_pointConstraint1.ox" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetY.o" "IMP_locator5_pointConstraint1.oy" - ; -connectAttr "IMP_locator5_pointConstraint1_offsetZ.o" "IMP_locator5_pointConstraint1.oz" - ; -connectAttr "IMP_locator5_orientConstraint1_nodeState.o" "IMP_locator5_orientConstraint1.nds" - ; -connectAttr "IMP_locator5_orientConstraint1_RhandW0.o" "IMP_locator5_orientConstraint1.w0" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetX.o" "IMP_locator5_orientConstraint1.ox" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetY.o" "IMP_locator5_orientConstraint1.oy" - ; -connectAttr "IMP_locator5_orientConstraint1_offsetZ.o" "IMP_locator5_orientConstraint1.oz" - ; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_locator6_visibility.o" "IMP_locator6.v"; -connectAttr "IMP_locator6_scaleX.o" "IMP_locator6.sx"; -connectAttr "IMP_locator6_scaleY.o" "IMP_locator6.sy"; -connectAttr "IMP_locator6_scaleZ.o" "IMP_locator6.sz"; -connectAttr "IMP_locator6_pointConstraint1_nodeState.o" "IMP_locator6_pointConstraint1.nds" - ; -connectAttr "IMP_locator6_pointConstraint1_LhandW0.o" "IMP_locator6_pointConstraint1.w0" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetX.o" "IMP_locator6_pointConstraint1.ox" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetY.o" "IMP_locator6_pointConstraint1.oy" - ; -connectAttr "IMP_locator6_pointConstraint1_offsetZ.o" "IMP_locator6_pointConstraint1.oz" - ; -connectAttr "IMP_locator6_orientConstraint1_nodeState.o" "IMP_locator6_orientConstraint1.nds" - ; -connectAttr "IMP_locator6_orientConstraint1_LhandW0.o" "IMP_locator6_orientConstraint1.w0" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetX.o" "IMP_locator6_orientConstraint1.ox" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetY.o" "IMP_locator6_orientConstraint1.oy" - ; -connectAttr "IMP_locator6_orientConstraint1_offsetZ.o" "IMP_locator6_orientConstraint1.oz" - ; -connectAttr "IMP_Lmissile_visibility.o" "IMP_Lmissile.v"; -connectAttr "IMP_Lmissile_translateX.o" "IMP_Lmissile.tx"; -connectAttr "IMP_Lmissile_translateY.o" "IMP_Lmissile.ty"; -connectAttr "IMP_Lmissile_translateZ.o" "IMP_Lmissile.tz"; -connectAttr "IMP_Lmissile_rotateX.o" "IMP_Lmissile.rx"; -connectAttr "IMP_Lmissile_rotateY.o" "IMP_Lmissile.ry"; -connectAttr "IMP_Lmissile_rotateZ.o" "IMP_Lmissile.rz"; -connectAttr "IMP_Lmissile_scaleX.o" "IMP_Lmissile.sx"; -connectAttr "IMP_Lmissile_scaleY.o" "IMP_Lmissile.sy"; -connectAttr "IMP_Lmissile_scaleZ.o" "IMP_Lmissile.sz"; -connectAttr "IMP_camera_visibility.o" "IMP_camera.v"; -connectAttr "IMP_camera_scaleX.o" "IMP_camera.sx"; -connectAttr "IMP_camera_scaleY.o" "IMP_camera.sy"; -connectAttr "IMP_camera_scaleZ.o" "IMP_camera.sz"; -connectAttr "IMP_camera_pointConstraint1_nodeState.o" "IMP_camera_pointConstraint1.nds" - ; -connectAttr "IMP_camera_pointConstraint1_eyesW0.o" "IMP_camera_pointConstraint1.w0" - ; -connectAttr "IMP_camera_pointConstraint1_offsetX.o" "IMP_camera_pointConstraint1.ox" - ; -connectAttr "IMP_camera_pointConstraint1_offsetY.o" "IMP_camera_pointConstraint1.oy" - ; -connectAttr "IMP_camera_pointConstraint1_offsetZ.o" "IMP_camera_pointConstraint1.oz" - ; -connectAttr "IMP_camera_orientConstraint1_nodeState.o" "IMP_camera_orientConstraint1.nds" - ; -connectAttr "IMP_camera_orientConstraint1_eyesW0.o" "IMP_camera_orientConstraint1.w0" - ; -connectAttr "IMP_camera_orientConstraint1_offsetX.o" "IMP_camera_orientConstraint1.ox" - ; -connectAttr "IMP_camera_orientConstraint1_offsetY.o" "IMP_camera_orientConstraint1.oy" - ; -connectAttr "IMP_camera_orientConstraint1_offsetZ.o" "IMP_camera_orientConstraint1.oz" - ; -connectAttr "IMP_locator14_visibility.o" "IMP_locator14.v"; -connectAttr "IMP_locator14_scaleX.o" "IMP_locator14.sx"; -connectAttr "IMP_locator14_scaleY.o" "IMP_locator14.sy"; -connectAttr "IMP_locator14_scaleZ.o" "IMP_locator14.sz"; -connectAttr "IMP_locator14_pointConstraint1_nodeState.o" "IMP_locator14_pointConstraint1.nds" - ; -connectAttr "IMP_locator14_pointConstraint1_HeadW0.o" "IMP_locator14_pointConstraint1.w0" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetX.o" "IMP_locator14_pointConstraint1.ox" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetY.o" "IMP_locator14_pointConstraint1.oy" - ; -connectAttr "IMP_locator14_pointConstraint1_offsetZ.o" "IMP_locator14_pointConstraint1.oz" - ; -connectAttr "IMP_locator14_orientConstraint1_nodeState.o" "IMP_locator14_orientConstraint1.nds" - ; -connectAttr "IMP_locator14_orientConstraint1_HeadW0.o" "IMP_locator14_orientConstraint1.w0" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetX.o" "IMP_locator14_orientConstraint1.ox" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetY.o" "IMP_locator14_orientConstraint1.oy" - ; -connectAttr "IMP_locator14_orientConstraint1_offsetZ.o" "IMP_locator14_orientConstraint1.oz" - ; -connectAttr "IMP_cam_connector_visibility.o" "IMP_cam_connector.v"; -connectAttr "IMP_cam_connector_translateX.o" "IMP_cam_connector.tx"; -connectAttr "IMP_cam_connector_translateY.o" "IMP_cam_connector.ty"; -connectAttr "IMP_cam_connector_translateZ.o" "IMP_cam_connector.tz"; -connectAttr "IMP_cam_connector_rotateX.o" "IMP_cam_connector.rx"; -connectAttr "IMP_cam_connector_rotateY.o" "IMP_cam_connector.ry"; -connectAttr "IMP_cam_connector_rotateZ.o" "IMP_cam_connector.rz"; -connectAttr "IMP_cam_connector_scaleX.o" "IMP_cam_connector.sx"; -connectAttr "IMP_cam_connector_scaleY.o" "IMP_cam_connector.sy"; -connectAttr "IMP_cam_connector_scaleZ.o" "IMP_cam_connector.sz"; -connectAttr "IMP_eyes_translateX.o" "IMP_eyes.tx"; -connectAttr "IMP_eyes_translateY.o" "IMP_eyes.ty"; -connectAttr "IMP_eyes_translateZ.o" "IMP_eyes.tz"; -connectAttr "IMP_eyes_rotateX.o" "IMP_eyes.rx"; -connectAttr "IMP_eyes_rotateY.o" "IMP_eyes.ry"; -connectAttr "IMP_eyes_rotateZ.o" "IMP_eyes.rz"; -connectAttr "IMP_eyes_visibility.o" "IMP_eyes.v"; -connectAttr "IMP_eyes_scaleX.o" "IMP_eyes.sx"; -connectAttr "IMP_eyes_scaleY.o" "IMP_eyes.sy"; -connectAttr "IMP_eyes_scaleZ.o" "IMP_eyes.sz"; -connectAttr "IMP_locator13_visibility.o" "IMP_locator13.v"; -connectAttr "IMP_locator13_translateX.o" "IMP_locator13.tx"; -connectAttr "IMP_locator13_translateY.o" "IMP_locator13.ty"; -connectAttr "IMP_locator13_translateZ.o" "IMP_locator13.tz"; -connectAttr "IMP_locator13_rotateX.o" "IMP_locator13.rx"; -connectAttr "IMP_locator13_rotateY.o" "IMP_locator13.ry"; -connectAttr "IMP_locator13_rotateZ.o" "IMP_locator13.rz"; -connectAttr "IMP_locator13_scaleX.o" "IMP_locator13.sx"; -connectAttr "IMP_locator13_scaleY.o" "IMP_locator13.sy"; -connectAttr "IMP_locator13_scaleZ.o" "IMP_locator13.sz"; -connectAttr "IMP_pCube1_visibility.o" "IMP_pCube1.v"; -connectAttr "IMP_pCube1_translateX.o" "IMP_pCube1.tx"; -connectAttr "IMP_pCube1_translateY.o" "IMP_pCube1.ty"; -connectAttr "IMP_pCube1_translateZ.o" "IMP_pCube1.tz"; -connectAttr "IMP_pCube1_rotateX.o" "IMP_pCube1.rx"; -connectAttr "IMP_pCube1_rotateY.o" "IMP_pCube1.ry"; -connectAttr "IMP_pCube1_rotateZ.o" "IMP_pCube1.rz"; -connectAttr "IMP_pCube1_scaleX.o" "IMP_pCube1.sx"; -connectAttr "IMP_pCube1_scaleY.o" "IMP_pCube1.sy"; -connectAttr "IMP_pCube1_scaleZ.o" "IMP_pCube1.sz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_Rwing_thing_visibility.o" "IMP_Rwing_thing.v"; -connectAttr "IMP_Rwing_thing_scaleX.o" "IMP_Rwing_thing.sx"; -connectAttr "IMP_Rwing_thing_scaleY.o" "IMP_Rwing_thing.sy"; -connectAttr "IMP_Rwing_thing_scaleZ.o" "IMP_Rwing_thing.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Lwing_thing_visibility.o" "IMP_Lwing_thing.v"; -connectAttr "IMP_Lwing_thing_scaleX.o" "IMP_Lwing_thing.sx"; -connectAttr "IMP_Lwing_thing_scaleY.o" "IMP_Lwing_thing.sy"; -connectAttr "IMP_Lwing_thing_scaleZ.o" "IMP_Lwing_thing.sz"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Lwing_pointConstraint1_nodeState.o" "IMP_Lwing_pointConstraint1.nds" - ; -connectAttr "IMP_Lwing_pointConstraint1_Lwing_nullW0.o" "IMP_Lwing_pointConstraint1.w0" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetX.o" "IMP_Lwing_pointConstraint1.ox" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetY.o" "IMP_Lwing_pointConstraint1.oy" - ; -connectAttr "IMP_Lwing_pointConstraint1_offsetZ.o" "IMP_Lwing_pointConstraint1.oz" - ; -connectAttr "IMP_joint8_scaleX.o" "IMP_joint8.sx"; -connectAttr "IMP_joint8_scaleY.o" "IMP_joint8.sy"; -connectAttr "IMP_joint8_scaleZ.o" "IMP_joint8.sz"; -connectAttr "IMP_joint8_visibility.o" "IMP_joint8.v"; -connectAttr "IMP_joint7_visibility.o" "IMP_joint7.v"; -connectAttr "IMP_joint7_scaleX.o" "IMP_joint7.sx"; -connectAttr "IMP_joint7_scaleY.o" "IMP_joint7.sy"; -connectAttr "IMP_joint7_scaleZ.o" "IMP_joint7.sz"; -connectAttr "IMP_joint6_scaleX.o" "IMP_joint6.sx"; -connectAttr "IMP_joint6_scaleY.o" "IMP_joint6.sy"; -connectAttr "IMP_joint6_scaleZ.o" "IMP_joint6.sz"; -connectAttr "IMP_joint6_visibility.o" "IMP_joint6.v"; -connectAttr "IMP_joint9_visibility.o" "IMP_joint9.v"; -connectAttr "IMP_joint9_scaleX.o" "IMP_joint9.sx"; -connectAttr "IMP_joint9_scaleY.o" "IMP_joint9.sy"; -connectAttr "IMP_joint9_scaleZ.o" "IMP_joint9.sz"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Rwing3_scaleX.o" "IMP_Rwing3.sx"; -connectAttr "IMP_Rwing3_scaleY.o" "IMP_Rwing3.sy"; -connectAttr "IMP_Rwing3_scaleZ.o" "IMP_Rwing3.sz"; -connectAttr "IMP_Rwing3_visibility.o" "IMP_Rwing3.v"; -connectAttr "IMP_joint5_visibility.o" "IMP_joint5.v"; -connectAttr "IMP_joint5_scaleX.o" "IMP_joint5.sx"; -connectAttr "IMP_joint5_scaleY.o" "IMP_joint5.sy"; -connectAttr "IMP_joint5_scaleZ.o" "IMP_joint5.sz"; -connectAttr "IMP_Rwing4_scaleX.o" "IMP_Rwing4.sx"; -connectAttr "IMP_Rwing4_scaleY.o" "IMP_Rwing4.sy"; -connectAttr "IMP_Rwing4_scaleZ.o" "IMP_Rwing4.sz"; -connectAttr "IMP_Rwing4_visibility.o" "IMP_Rwing4.v"; -connectAttr "IMP_Rwing1_visibility.o" "IMP_Rwing1.v"; -connectAttr "IMP_Rwing1_scaleX.o" "IMP_Rwing1.sx"; -connectAttr "IMP_Rwing1_scaleY.o" "IMP_Rwing1.sy"; -connectAttr "IMP_Rwing1_scaleZ.o" "IMP_Rwing1.sz"; -connectAttr "IMP_Rwing_pointConstraint1_nodeState.o" "IMP_Rwing_pointConstraint1.nds" - ; -connectAttr "IMP_Rwing_pointConstraint1_Rwing_nullW0.o" "IMP_Rwing_pointConstraint1.w0" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetX.o" "IMP_Rwing_pointConstraint1.ox" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetY.o" "IMP_Rwing_pointConstraint1.oy" - ; -connectAttr "IMP_Rwing_pointConstraint1_offsetZ.o" "IMP_Rwing_pointConstraint1.oz" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_lelbow_visibility.o" "IMP_lelbow.v"; -connectAttr "IMP_lelbow_scaleX.o" "IMP_lelbow.sx"; -connectAttr "IMP_lelbow_scaleY.o" "IMP_lelbow.sy"; -connectAttr "IMP_lelbow_scaleZ.o" "IMP_lelbow.sz"; -connectAttr "IMP_locator3_pointConstraint1_nodeState.o" "IMP_locator3_pointConstraint1.nds" - ; -connectAttr "IMP_locator3_pointConstraint1_LloarmW0.o" "IMP_locator3_pointConstraint1.w0" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetX.o" "IMP_locator3_pointConstraint1.ox" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetY.o" "IMP_locator3_pointConstraint1.oy" - ; -connectAttr "IMP_locator3_pointConstraint1_offsetZ.o" "IMP_locator3_pointConstraint1.oz" - ; -connectAttr "IMP_locator3_orientConstraint1_nodeState.o" "IMP_locator3_orientConstraint1.nds" - ; -connectAttr "IMP_locator3_orientConstraint1_LloarmW0.o" "IMP_locator3_orientConstraint1.w0" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetX.o" "IMP_locator3_orientConstraint1.ox" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetY.o" "IMP_locator3_orientConstraint1.oy" - ; -connectAttr "IMP_locator3_orientConstraint1_offsetZ.o" "IMP_locator3_orientConstraint1.oz" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_relbow_visibility.o" "IMP_relbow.v"; -connectAttr "IMP_relbow_scaleX.o" "IMP_relbow.sx"; -connectAttr "IMP_relbow_scaleY.o" "IMP_relbow.sy"; -connectAttr "IMP_relbow_scaleZ.o" "IMP_relbow.sz"; -connectAttr "IMP_locator4_pointConstraint1_nodeState.o" "IMP_locator4_pointConstraint1.nds" - ; -connectAttr "IMP_locator4_pointConstraint1_RloarmW0.o" "IMP_locator4_pointConstraint1.w0" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetX.o" "IMP_locator4_pointConstraint1.ox" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetY.o" "IMP_locator4_pointConstraint1.oy" - ; -connectAttr "IMP_locator4_pointConstraint1_offsetZ.o" "IMP_locator4_pointConstraint1.oz" - ; -connectAttr "IMP_locator4_orientConstraint1_nodeState.o" "IMP_locator4_orientConstraint1.nds" - ; -connectAttr "IMP_locator4_orientConstraint1_RloarmW0.o" "IMP_locator4_orientConstraint1.w0" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetX.o" "IMP_locator4_orientConstraint1.ox" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetY.o" "IMP_locator4_orientConstraint1.oy" - ; -connectAttr "IMP_locator4_orientConstraint1_offsetZ.o" "IMP_locator4_orientConstraint1.oz" - ; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -connectAttr "pointLightShape1.ltd" ":lightList1.l" -na; -connectAttr "pointLightShape2.ltd" ":lightList1.l" -na; -connectAttr "pointLight1.iog" ":defaultLightSet.dsm" -na; -connectAttr "pointLight2.iog" ":defaultLightSet.dsm" -na; -// End of scurry_leap2.ma diff --git a/base/models/monsters/imp/animation/cycles/sight.ma b/base/models/monsters/imp/animation/cycles/sight.ma deleted file mode 100644 index 2cd79c27a..000000000 --- a/base/models/monsters/imp/animation/cycles/sight.ma +++ /dev/null @@ -1,4179 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:17 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: sight.ma -//Last modified: Mon, Mar 15, 2004 09:05:42 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 13.538119084953905 64.823157116752441 257.16405997401887 ; - setAttr ".r" -type "double3" -5.1301089135277183 2.5999999999994947 -9.9494756703951373e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 273.37253712114347; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 1.2994289005574777 49.453306911683555 10.571225793121133 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" -3.3927874941258063 44.132460232398266 114.40646173572298 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 106.57157150542142; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 104.86085128619987 42.365131842652389 10.045758476009869 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 182.69883031017056; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; - setAttr ".sp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -125.22193586838614 20 -118.97547159999999 - 49 -125.22193586838614 65 -118.97547159999999 68 -125.22193586838614; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 8.6146645406138322 20 30.329382000000003 - 49 8.6146645406138322 65 30.329382000000003 68 8.6146645406138322; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -81.606402433660108 20 -92.904446149999998 - 49 -81.606402433660108 65 -92.904446149999998 68 -81.606402433660108; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -89.263548368337112 20 -71.101691509999995 - 49 -89.263548368337112 65 -71.101691509999995 68 -89.263548368337112; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 5.567698967347587 20 32.578198350000001 - 49 5.567698967347587 65 32.578198350000001 68 5.567698967347587; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -104.19557958825375 20 -95.564448510000005 - 49 -104.19557958825375 65 -95.564448510000005 68 -104.19557958825375; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 49 1 65 1 68 1; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 0 49 0 65 0 68 0; - setAttr -s 5 ".kit[1:4]" 3 9 3 9; - setAttr -s 5 ".kot[1:4]" 3 9 3 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 65 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -16.21787434118799 20 -7.392405718 - 65 -7.392405718 68 -16.21787434118799; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.77211996138749939 20 0 65 0 - 68 0.77211996138749939; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -4.579364761070849 20 -7.3620493590000002 - 65 -7.3620493590000002 68 -4.579364761070849; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 5.3462904040000003 65 5.3462904040000003 - 68 0; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -8.1254375044848945 20 -29.548385579999998 - 65 -29.548385579999998 68 -8.1254375044848945; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20 -5.3030645630000004 65 -5.3030645630000004 - 68 0; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 65 1 68 1; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 65 1 68 1; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20 1 65 1 68 1; - setAttr -s 4 ".kit[0:3]" 9 3 3 9; - setAttr -s 4 ".kot[0:3]" 9 3 3 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.7758528420198658 30 6.7758528420198658 - 49 6.7758528420198658 68 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9388939039072284e-018 30 -6.9388939039072284e-018 - 49 0 68 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -9.5120444723942321e-016 30 -9.5120444723942321e-016 - 49 0 68 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -12.784757077400341 30 -12.784757077400341 - 49 -12.784757077400341 68 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.2695897469829736 30 3.2695897469829736 - 49 3.2695897469829736 68 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9162979482121409 30 -6.9162979482121409 - 49 -6.9162979482121409 68 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 65 1 68 1 72 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.758090709918321 20 7.1689522480000001 - 65 7.1689522480000001 68 12.758090709918321 72 5.8482392980113111; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.6648666211645171 20 0 65 0 - 68 1.6648666211645171 72 11.185560383958709; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -8.2514949399869195 20 -7.748575014 - 65 -7.748575014 68 -8.2514949399869195 72 23.265284412710983; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 10.10932652 65 10.10932652 - 68 0 72 -25.871497169061271; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 18.296137987022 20 63.314403930000005 - 65 63.314403930000005 68 18.296137987022 72 18.296137987021996; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 20 11.59016476 65 11.59016476 - 68 0 72 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 65 1 68 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 65 1 68 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 20 1 65 1 68 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 3; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.7758528420198658 30 6.7758528420198658 - 49 6.7758528420198658 68 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9388939039072284e-018 30 -6.9388939039072284e-018 - 49 0 68 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -9.5120444723942321e-016 30 -9.5120444723942321e-016 - 49 0 68 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.1064832569487142 30 -2.1064832569487142 - 49 -2.1064832569487142 68 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.36693656610454173 30 0.36693656610454173 - 49 0.36693656610454173 68 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.728045273286209 30 12.728045273286209 - 49 12.728045273286209 68 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 20 1 30 1 37 1 49 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.4992483681888071 13 0 20 1.980821395 - 30 1.974938028170959 37 0.78324272857221566 49 1.4019959624554719 65 1.980821395 - 68 -3.1375833875031756 72 -6.6302543635927753; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 38.296982945425135 13 42.080319990702506 - 20 41.235789590000003 30 41.660246213666603 37 39.397005865429264 49 39.121601482230204 - 65 41.235789590000003 68 39.970234670070724 72 40.641750406486153; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.9739425354301807 13 -2.0017954694714746 - 20 -2.4191866630000001 30 -1.5768455902068759 37 -5.8201855992453853 49 -7.7856149610102738 - 65 -2.4191866630000001 68 -7.1140041361149606 72 19.556314098060291; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.55644336951292817 13 0.55644336951292817 - 20 0 30 0.55644336951292817 37 44.112788513580988 49 44.112788513580988 65 - 0 68 14.488305710603974 72 40.494473772929702; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 6.2969131118352886 13 6.2969131118352886 - 20 0 30 6.2969131118352886 37 6.2969131118352939 49 6.2969131118352939 65 - 0 68 6.2969131118352921 72 6.2969131118352939; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.060261194923271 13 5.060261194923271 - 20 3.09040954 30 5.060261194923271 37 5.0602611949232728 49 5.0602611949232728 - 65 3.09040954 68 5.0602611949232719 72 5.0602611949232701; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 20 1 30 1 37 1 49 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 20 1 30 1 37 1 49 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 20 1 30 1 37 1 49 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[0:8]" 9 9 3 3 3 3 3 - 9 3; - setAttr -s 9 ".kot[0:8]" 9 9 3 3 3 3 3 - 9 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 30 1 49 1 65 1 68 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0.4494172494 30 0 49 0 65 - 0.4494172494 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 -0.058577090280000001 30 - 0 49 0 65 -0.058577090280000001 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 30 0 49 0 65 0 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 30 0 49 0 65 0 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 30 0 49 0 65 0 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 20 0 30 0 49 0 65 0 68 0; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 30 1 49 1 65 1 68 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 30 1 49 1 65 1 68 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 20 1 30 1 49 1 65 1 68 1; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 30 1 37 1 49 1 58 1 68 1 72 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 30 0 37 0 49 0 58 0 68 0 72 - 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 30 2.3128351505039433 - 37 2.3128351505039433 49 2.3128351505039433 58 2.3128351505039433 68 2.3128351505039433 - 72 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 30 0.23421866920666501 - 37 0.23421866920666501 49 0.23421866920666501 58 0.23421866920666501 68 0.23421866920666501 - 72 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 30 0 37 -17.141297204275059 - 49 5.3035021064144265 58 16.08626461041349 68 11.913770184118828 72 -1.314232773616012; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 30 0 37 0 49 0 58 0 68 0 72 - 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 30 0 37 0 49 0 58 0 68 0 72 - 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 30 1 37 1 49 1 58 1 68 1 72 - 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 30 1 37 1 49 1 58 1 68 1 72 - 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 30 1 37 1 49 1 58 1 68 1 72 - 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 30 1 37 1 49 1 58 1 68 - 1 72 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8 0 30 0 37 0 49 0 58 0 68 - 0 72 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 8 5.6268319407172029 - 30 5.6268319407172029 37 5.6268319407172029 49 5.6268319407172029 58 5.6268319407172029 - 68 5.6268319407172029 72 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 8 -2.1098668596606802 - 30 -2.1098668596606802 37 -2.1098668596606802 49 -2.1098668596606802 58 -2.1098668596606802 - 68 -2.1098668596606802 72 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.4119425478832621 8 -19.272650002129094 - 30 -19.671845271147479 37 3.1223777499579128 49 -0.30366309659256324 58 -2.3317707784075354 - 68 9.4119425478832621 72 -17.638912642294702; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.8819931310225972 8 11.160355259495649 - 30 6.2156627158197422 37 12.862713338850638 49 -11.330548525072736 58 3.0474696548407598 - 68 3.8819931310225972 72 23.29906932962308; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -5.7213769427135075 8 -5.7000527654561859 - 30 -15.19062649640299 37 -9.6855981986908475 49 1.6311015885912843 58 1.7284196208570557 - 68 -5.7213769427135075 72 -13.948397192348018; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 30 1 37 1 49 1 58 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 30 1 37 1 49 1 58 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8 1 30 1 37 1 49 1 58 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.7384771804188404 30 5.7384771804188404 - 49 5.7384771804188404 68 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.0494561358638701 30 2.0494561358638701 - 49 2.0494561358638701 68 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 8 1 13 1 15 1 19 1 27 1 - 30 1 33 1 37 1 49 1 53 1 61 1 68 1 72 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 0 6 0 8 0 13 0 15 0 19 0 27 0 - 30 0 33 0 37 0 49 0 53 0 61 0 68 0 72 0; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 2.6456615572060826 6 2.6456615572060826 - 8 2.6456615572060826 13 2.6456615572060826 15 2.6456615572060826 19 2.6456615572060826 - 27 2.6456615572060826 30 2.6456615572060826 33 2.6456615572060826 37 2.6456615572060826 - 49 2.6456615572060826 53 2.6456615572060826 61 2.6456615572060826 68 2.6456615572060826 - 72 2.6456615572060826; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1.9935618776130362 6 1.9935618776130362 - 8 1.9935618776130362 13 1.9935618776130362 15 1.9935618776130362 19 1.9935618776130362 - 27 1.9935618776130362 30 1.9935618776130362 33 1.9935618776130362 37 1.9935618776130362 - 49 1.9935618776130362 53 1.9935618776130362 61 1.9935618776130362 68 1.9935618776130362 - 72 1.9935618776130362; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -17.460363846642768 6 -20.678138434240765 - 8 -13.647074566714469 13 -4.6424437116352379 15 -0.32021527976762992 19 7.5728952920654553 - 27 -3.3721199222698415 30 -3.3721199222698415 33 -8.1259270466375 37 -55.753285691539659 - 49 -61.981690635772658 53 -77.630484697886416 61 -66.944551782216209 68 -17.460363846642768 - 72 -29.237879655452048; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -5.7962630210791115 6 -8.0634433288000018 - 8 -7.9310585985358752 13 -4.8323287439474187 15 -5.6523792081990631 19 -8.298716698377735 - 27 -18.61358322935018 30 -18.61358322935018 33 -3.5840270081743055 37 -0.56575935076619877 - 49 -22.706955140559792 53 -19.619340820278161 61 8.4699108941543688 68 -5.7962630210791115 - 72 -25.237041595994583; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 6.6414265814238034 6 -1.5366656520054842 - 8 6.2516574625368309 13 5.2692574676113662 15 -19.313986433738943 19 -7.2165571489038571 - 27 14.181440951070751 30 14.181440951070751 33 7.5833949322652927 37 10.878229969953455 - 49 -13.476487678639403 53 -12.138888481798636 61 -3.0482303883022888 68 6.6414265814238034 - 72 -13.195505960341031; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 8 1 13 1 15 1 19 1 27 1 - 30 1 33 1 37 1 49 1 53 1 61 1 68 1 72 1; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 8 1 13 1 15 1 19 1 27 1 - 30 1 33 1 37 1 49 1 53 1 61 1 68 1 72 1; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 8 1 13 1 15 1 19 1 27 1 - 30 1 33 1 37 1 49 1 53 1 61 1 68 1 72 1; - setAttr -s 15 ".kit[14]" 3; - setAttr -s 15 ".kot[14]" 3; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 30 1 37 1 49 1 58 1 68 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 30 0 37 0 49 0 58 0 68 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.74525677667777757 30 0.74525677667777757 - 37 0.74525677667777757 49 0.74525677667777757 58 0.74525677667777757 68 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.8072476834435935 30 1.8072476834435935 - 37 1.8072476834435935 49 1.8072476834435935 58 1.8072476834435935 68 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8161377226329614 30 -3.8161377226329614 - 37 33.604514516045661 49 33.604514516045661 58 33.604514516045661 68 -3.8161377226329614; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 30 0 37 0 49 0 58 0 68 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 30 0 37 0 49 0 58 0 68 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 30 1 37 1 49 1 58 1 68 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 30 1 37 1 49 1 58 1 68 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 30 1 37 1 49 1 58 1 68 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6 1 19 1 37 1 49 1 58 1 72 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 4.8088785785432249 6 4.8088785785432249 - 19 4.8088785785432249 37 4.8088785785432249 49 4.8088785785432249 58 4.8088785785432249 - 72 4.8088785785432249; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.1192573708759417 6 2.1192573708759417 - 19 2.1192573708759417 37 2.1192573708759417 49 2.1192573708759417 58 2.1192573708759417 - 72 2.1192573708759417; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821078932592161 6 -3.0821078932592161 - 19 -3.0821078932592161 37 -3.0821078932592161 49 -3.0821078932592161 58 -3.0821078932592161 - 72 -3.0821078932592161; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -12.427061868902332 6 -11.919620528529935 - 19 4.1849439241982447 30 4.1849439241982447 37 -31.374569670256559 49 -25.30843142256029 - 58 10.816843173369225 65 -4.5817938397042637 72 -44.349491166563986; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 18.355136182766611 6 36.848488493160268 - 19 28.48057963545498 30 28.48057963545498 37 42.119218428813006 49 25.396652550296359 - 58 28.51468070731762 65 26.658400951807923 72 23.333749626109348; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -29.925918142194192 6 -29.19021614747578 - 19 14.730956410834692 30 14.730956410834692 37 -39.591688320473089 49 -28.81302514430838 - 58 -23.590959622970207 65 -28.520910922575261 72 -26.605868620425959; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6 1 19 1 37 1 49 1 58 1 72 - 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6 1 19 1 37 1 49 1 58 1 72 - 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6 1 19 1 37 1 49 1 58 1 72 - 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 12.412879749935719 13 12.412879749935719 - 30 12.412879749935719 37 12.412879749935719 49 12.412879749935719 68 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7286993982861674 13 -6.7286993982861674 - 30 -6.7286993982861674 37 -6.7286993982861674 49 -6.7286993982861674 68 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.868763862603668 13 -3.868763862603668 - 30 -3.868763862603668 37 -3.868763862603668 49 -3.868763862603668 68 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 53.630905100806274 13 94.022956559219736 - 19 80.705542659749995 30 80.705542659749995 37 12.30846027300135 49 12.30846027300135 - 68 53.630905100806274; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 13 0 19 -6.888411515133873 - 30 -6.888411515133873 37 0 49 0 68 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 13 0 19 -9.7103727997758771 - 30 -9.7103727997758771 37 0 49 0 68 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 19 1 37 1 49 1 58 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.3932492040642028 13 -5.3932492040642028 - 19 -5.3932492040642028 37 -5.3932492040642028 49 -5.3932492040642028 58 -5.3932492040642028 - 65 -5.3932492040642028 68 -5.3932492040642028 72 -5.3932492040642028; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.1192000000003004 13 2.1192000000003004 - 19 2.1192000000003004 37 2.1192000000003004 49 2.1192000000003004 58 2.1192000000003004 - 65 2.1192000000003004 68 2.1192000000003004 72 2.1192000000003004; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.0821100000000272 13 -3.0821100000000272 - 19 -3.0821100000000272 37 -3.0821100000000272 49 -3.0821100000000272 58 -3.0821100000000272 - 65 -3.0821100000000272 68 -3.0821100000000272 72 -3.0821100000000272; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 47.897771024785186 13 37.644003394830598 - 19 1.9984963154227247 30 1.9984963154227247 37 56.95212985769335 49 41.698744042302785 - 58 22.338324296500808 65 31.962861877202858 68 47.897771024785186 72 -2.617353045691353; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -48.751706532137327 13 -44.423366031221406 - 19 -34.736357457638789 30 -34.736357457638789 37 -56.989558608194088 49 -46.648273923095957 - 58 -46.648273923095942 65 -31.342810215007134 68 -48.751706532137327 72 -5.9392503669031784; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.369283509291309 13 -1.8020574325262639 - 19 9.6786312897271092 30 9.6786312897271092 37 -42.337773340010131 49 -23.080304259132767 - 58 -23.08030425913276 65 -18.2085977172752 68 -10.369283509291309 72 -36.464846512098269; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 19 1 37 1 49 1 58 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 19 1 37 1 49 1 58 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 19 1 37 1 49 1 58 1 65 - 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.41287000000041 13 -12.41287000000041 - 30 -12.41287000000041 37 -12.41287000000041 49 -12.41287000000041 68 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7285999999993047 13 -6.7285999999993047 - 30 -6.7285999999993047 37 -6.7285999999993047 49 -6.7285999999993047 68 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8687599999999316 13 -3.8687599999999316 - 30 -3.8687599999999316 37 -3.8687599999999316 49 -3.8687599999999316 68 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 66.649287652014095 13 89.637953608802889 - 19 72.389328651827441 30 75.679925282090593 37 2.2130851399409881 49 2.2130851399409881 - 68 66.649287652014095; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 13 0 19 -3.6766424755279101 - 30 1.6604723665843502 37 0 49 0 68 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 13 0 19 -1.0589911124422209 - 30 -4.0214942467213399 37 0 49 0 68 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 13 1 30 1 37 1 49 1 68 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 30 1 68 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.0180767416209342 30 -0.0180767416209342 - 68 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.350740136846035 30 4.350740136846035 - 68 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.679538405939565 30 2.679538405939565 - 68 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 40 -63.90346873963567 - 68 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 40 0 68 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 40 0 68 0; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 30 1 68 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 30 1 68 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 30 1 68 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 37 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.5294371750177831 37 -2.5294371750177831 - 49 -2.5294371750177831 68 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 13.481673551673362 37 13.481673551673362 - 49 13.481673551673362 68 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.26635088939205875 37 -0.26635088939205875 - 49 -0.26635088939205875 68 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 34.731179446332078 19 383.55322504794935 - 30 383.55322504794935 37 -19.70034142316899 49 -33.342461218964765 65 -0.90465784012028105 - 68 34.731179446332078; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 80.262128312658689 19 80.455918362257933 - 30 80.455918362257933 37 68.079716356409364 49 60.328817780487206 65 79.127370116906235 - 68 80.262128312658689; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 161.64280519855993 19 459.38173981860081 - 30 459.38173981860081 37 68.698650924264754 49 59.657311668621517 65 101.82242611341948 - 68 161.64280519855993; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 37 15.445123296459185 - 49 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 37 15.445123296459185 - 49 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 37 15.445123296459185 - 49 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 37 0 49 0 68 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 37 0 49 0 68 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 19 0 32 0.13147433136474931 - 34 0 65 0.37999999999999989 68 1; - setAttr -s 6 ".kit[3:5]" 3 9 9; - setAttr -s 6 ".kot[3:5]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 33 0 37 0.59426043818956764 - 56 0.60680157084534347 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 37 1 68 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -7.5406347832540632e-013 36 0 - 68 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.71946295727715 37 13.71946295727715 - 68 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.0908609005564358e-013 36 0 - 68 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 83.451920652031347 19 129.94799202045385 - 37 109.83304985802269 52 150.20187293547716 65 -20.721417223369137 68 83.451920652031347; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -83.268958049108775 19 -115.71371456304053 - 37 -137.01549747165305 52 -107.32789410973774 65 -76.010271987183614 68 -83.268958049108775; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -217.30282869676228 19 -220.21374018682576 - 37 -210.70510868639386 52 -241.59478808439451 65 -68.13488408174311 68 -217.30282869676228; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459183 37 15.445123296459183 - 68 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 37 15.445123296459185 - 68 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459181 37 15.445123296459181 - 68 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 36 0 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 19 0 36 0 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 19 0.34494887368928995 34 1 - 36 0.36670594003338086 65 0.37999999999999989 68 1; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 19 0 34 0 37 0.5 56 0.48101066942509846 - 68 0; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 0.9325680136680603; - setAttr -s 6 ".kiy[5]" -0.36099430918693542; - setAttr -s 6 ".kox[5]" 0.93256807327270508; - setAttr -s 6 ".koy[5]" -0.36099410057067871; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.24500268074642695 30 -0.24500268074642695 - 49 -0.24500268074642695 68 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.2065238412698649 30 1.2065238412698649 - 49 1.2065238412698649 68 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.38309524546711837 30 -0.38309524546711837 - 49 -0.38309524546711837 68 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -14.614862034248505 30 -14.614862034248505 - 49 -14.614862034248505 68 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 33.316404488343842 30 33.316404488343842 - 49 33.316404488343842 68 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -119.57538852061882 30 -119.57538852061882 - 49 -119.57538852061882 68 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000007 30 1.0000000000000007 - 49 1.0000000000000007 68 1.0000000000000007; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000004 30 1.0000000000000004 - 49 1.0000000000000004 68 1.0000000000000004; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000002 30 1.0000000000000002 - 49 1.0000000000000002 68 1.0000000000000002; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.12017666558909808 30 -0.12017666558909808 - 49 -0.12017666558909808 68 -0.12017666558909808; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.724592717525262 30 -0.724592717525262 - 49 -0.724592717525262 68 -0.724592717525262; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.21268105951286304 30 -0.21268105951286304 - 49 -0.21268105951286304 68 -0.21268105951286304; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 143.97979303987 30 143.97979303987 - 49 143.97979303987 68 143.97979303987; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -25.119237776405349 30 -25.119237776405349 - 49 -25.119237776405349 68 -25.119237776405349; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -10.758168812157226 30 -10.758168812157226 - 49 -10.758168812157226 68 -10.758168812157226; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 30 0.99999999999999989 - 49 0.99999999999999989 68 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 30 0.99999999999999989 - 49 0.99999999999999989 68 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.27427863724837187 30 0.077981293515704403 - 49 -0.74999975068806757 68 -0.15174782359914046; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.1075115639039561 30 -1.1351282283403885 - 49 -0.069091982949667785 68 -1.0222432259776459; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.6426166214208928 30 -1.6448108776046009 - 49 -1.8517679259567221 68 -1.7123058678214413; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 30 1 49 1 68 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.27427146386087553 30 -0.96028872540452515 - 49 -1.2426402281997371 68 -0.68393793124877111; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.1074983884594769 30 -1.0206120681764821 - 49 -0.19156158567963411 68 -0.75098205981507427; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.6426267024711592 30 -1.4269535977576329 - 49 -1.5793638928377538 68 -1.7228624007839568; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 30 0 49 0 68 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 512 -size 1024 -divisions 5 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 20 -max 65 -ast 20 -aet 65 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 19 0 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 19 0 36 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 37 0 49 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 37 0 49 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; -select -ne :time1; - setAttr ".o" 20; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of sight.ma diff --git a/base/models/monsters/imp/animation/cycles/sight2.ma b/base/models/monsters/imp/animation/cycles/sight2.ma deleted file mode 100644 index abddddb4a..000000000 --- a/base/models/monsters/imp/animation/cycles/sight2.ma +++ /dev/null @@ -1,4545 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:25 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: sight2.ma -//Last modified: Mon, Mar 15, 2004 09:06:00 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" -27.583803752031031 33.78771152298863 223.03048284598583 ; - setAttr ".r" -type "double3" 1.4698910858926806 -1087.3999999990776 2.505677727803358e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 230.17454125173415; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" -6.9316948918523984 59.305906725678959 -4.7946797848537992 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.844702467344078; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" -3.0051187796762622 2.9717154282831739 104.70346136378367 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 20.791840715546915; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 127.37922344524941 44.832784054704177 27.672610790863892 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 188.82368487405671; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.130097827167887 0.19251035509265524 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; - setAttr ".ihi" 0; - setAttr -s 2 ".lnk"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 3 1 18.344000000000001 1 46 - 1 46.82 1 55 1; - setAttr -s 6 ".kbd[2:5]" yes no yes no; - setAttr -s 6 ".kot[0:5]" 5 5 9 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.980821395062172 3 1.980821395 - 8.952 1.9806539227154296 18.344000000000001 1.614375984502191 46 1.980821395 - 46.82 1.614375984502191 55 2.2470678227489294; - setAttr -s 7 ".kbd[2:6]" yes yes no yes no; - setAttr -s 7 ".kit[1:6]" 3 9 9 3 9 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 3 9 9; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 41.235789592866901 3 41.235789590000003 - 12 43.540135467411694 16 36.62435582003841 46 41.235789590000003 46.82 36.62435582003841 - 55 37.395082118257179; - setAttr -s 7 ".kbd[2:6]" yes yes no yes no; - setAttr -s 7 ".kit[1:6]" 3 9 1 3 1 9; - setAttr -s 7 ".kot[1:6]" 3 9 1 3 1 9; - setAttr -s 7 ".kix[3:6]" 0.11448873579502106 1 0.22030675411224365 - 0.40444174408912659; - setAttr -s 7 ".kiy[3:6]" -0.99342453479766846 0 0.97543066740036011 - 0.91456377506256104; - setAttr -s 7 ".kox[3:6]" 0.11448875814676285 1 0.22030675411224365 - 0.40444174408912659; - setAttr -s 7 ".koy[3:6]" -0.99342453479766846 0 0.97543066740036011 - 0.91456377506256104; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.4191866633612995 3 -2.4191866630000001 - 8.952 -3.4812776908126235 46 -2.4191866630000001 46.82 -3.7834579892918132 - 55 13.218930809907427; - setAttr -s 6 ".kbd[2:5]" yes no yes no; - setAttr -s 6 ".kit[0:5]" 9 3 1 3 1 9; - setAttr -s 6 ".kot[0:5]" 9 3 1 3 1 9; - setAttr -s 6 ".kix[2:5]" 0.21315400302410126 1 0.18930709362030029 - 0.020042182877659798; - setAttr -s 6 ".kiy[2:5]" -0.97701859474182129 0 0.98191791772842407 - 0.99979913234710693; - setAttr -s 6 ".kox[2:5]" 0.21315400302410126 1 0.1893070787191391 - 0.020042182877659798; - setAttr -s 6 ".koy[2:5]" -0.97701859474182129 0 0.98191791772842407 - 0.99979913234710693; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 3 0 8.952 -10.364773128378729 - 14.324 -10.364773128378729 18.344000000000001 0 46 0 46.82 0 55 19.337616025271206; - setAttr -s 8 ".kbd[2:7]" yes yes yes no yes no; - setAttr -s 8 ".kit[1:7]" 3 9 9 9 3 9 9; - setAttr -s 8 ".kot[1:7]" 3 9 9 9 3 9 9; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 3 0 8.952 -0.51158511214046132 - 18.344000000000001 0 46 0 46.82 0 55 0; - setAttr -s 7 ".kbd[2:6]" yes yes no yes no; - setAttr -s 7 ".kit[1:6]" 3 9 9 3 9 9; - setAttr -s 7 ".kot[1:6]" 3 9 9 3 9 9; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.8412363057509031 3 3.09040954 - 8.952 -2.7948366733285739 18.344000000000001 -2.8412363057509031 46 3.09040954 - 55 1.3079116377382698; - setAttr -s 6 ".kbd[2:5]" yes yes no no; - setAttr -s 6 ".kit[1:5]" 3 9 9 3 9; - setAttr -s 6 ".kot[1:5]" 3 9 9 3 9; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 3 1 18.344000000000001 1 46 - 1 46.82 1 55 1; - setAttr -s 6 ".kbd[2:5]" yes no yes no; - setAttr -s 6 ".kit[1:5]" 3 9 3 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 3 9 9; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 3 1 18.344000000000001 1 46 - 1 46.82 1 55 1; - setAttr -s 6 ".kbd[2:5]" yes no yes no; - setAttr -s 6 ".kit[1:5]" 3 9 3 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 3 9 9; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 3 1 18.344000000000001 1 46 - 1 46.82 1 55 1; - setAttr -s 6 ".kbd[2:5]" yes no yes no; - setAttr -s 6 ".kit[1:5]" 3 9 3 9 9; - setAttr -s 6 ".kot[1:5]" 3 9 3 9 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11.636 1 18.348 1 23.708 1 - 43.544 1 55 1; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 11.636 0 18.348 0 23.708 0 - 43.544 0 55 0; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.6268319407172029 11.636 5.6268319407172029 - 18.348 5.6268319407172029 23.708 5.6268319407172029 43.544 5.6268319407172029 - 55 5.6268319407172029; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.1098668596606802 11.636 -2.1098668596606802 - 18.348 -2.1098668596606802 23.708 -2.1098668596606802 43.544 -2.1098668596606802 - 55 -2.1098668596606802; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 380.4969630522524 11.636 338.02553738474546 - 15.66 373.43691457359012 23.708 387.27199112906698 43.544 374.44212415848034 - 55 355.46455151232618; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -0.44667534838539324 11.636 3.7706144987003345 - 18.348 3.6333181081234063 23.708 -3.6843561568413965 43.544 -5.5012137249646909 - 55 -1.4612990720034928; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -9.1348552853601976 11.636 2.8637351545978875 - 18.348 2.293828544484779 23.708 -3.5581258335640205 43.544 -4.1534391115893898 - 55 -4.6098070966010036; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11.636 1 18.348 1 23.708 1 - 43.544 1 55 1; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11.636 1 18.348 1 23.708 1 - 43.544 1 55 1; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 11.636 1 18.348 1 23.708 1 - 43.544 1 55 1; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.608 1 12.972 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.8522027930141798 7.608 4.9763348848950901 - 12.972 5.1881310493394723 55 4.8522027930141798; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.1192573708759381 7.608 2.1317041360426563 - 12.972 2.1529410048601614 55 2.1192573708759381; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.0821078932592165 7.608 -3.07169383865011 - 12.972 -3.0539252129628651 55 -3.0821078932592165; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -17.481282422130235 6.2160000000000002 - 0.0014845681789677028 10.452 -14.244562552885601 18.236 9.3272290760684893 - 55 -32.313057939695923; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 30.702824881409519 6.2160000000000002 - 61.700561852333998 10.452 41.115767258540409 18.236 12.254587369315917 55 - 26.914041181906828; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -30.797032566082748 6.2160000000000002 - -29.329994389635857 10.452 -38.019715699149835 18.236 -47.643076444688184 - 55 -45.412031805890074; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.608 1 12.972 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.608 1 12.972 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.608 1 12.972 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.0348979650608028 55 -5.0394018283595567; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 0.96090155839920044; - setAttr -s 2 ".kiy[1]" 0.27689012885093689; - setAttr -s 2 ".kox[1]" 0.96089744567871094; - setAttr -s 2 ".koy[1]" 0.27690455317497253; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.1192000000002627 55 2.1196899971770544; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 0.99999934434890747; - setAttr -s 2 ".kiy[1]" -0.0011602294398471713; - setAttr -s 2 ".kox[1]" 0.99999934434890747; - setAttr -s 2 ".koy[1]" -0.001154148718342185; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -3.0821100000000254 55 -3.082500815800266; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 0.9999161958694458; - setAttr -s 2 ".kiy[1]" 0.01294776052236557; - setAttr -s 2 ".kox[1]" 0.99991613626480103; - setAttr -s 2 ".koy[1]" 0.012950824573636055; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.608 1 11.636 1 19.692 1 25.056000000000001 - 1 40.272 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 7.608 0 11.636 0 19.692 0 25.056000000000001 - 0 40.272 0 55 0; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.6456615572060826 7.608 2.6456615572060826 - 11.636 2.6456615572060826 19.692 2.6456615572060826 25.056000000000001 2.6456615572060826 - 40.272 2.6456615572060826 55 2.6456615572060826; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.9935618776130362 7.608 1.9935618776130362 - 11.636 1.9935618776130362 19.692 1.9935618776130362 25.056000000000001 1.9935618776130362 - 40.272 1.9935618776130362 55 1.9935618776130362; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -9.2446596468972171 7.608 13.747977555208793 - 11.636 13.965885558818478 19.692 -58.961763495270503 25.056000000000001 -60.697561427788884 - 55 2.3189401777838894; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 5.4602836565267197 7.608 6.3029289969003397 - 11.636 6.1232278821290302 19.692 20.680650595553359 25.056000000000001 5.7262743630377919 - 55 3.5867652321794989; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -30.070531056806921 7.608 -39.740312684781117 - 11.636 -26.917441537482969 19.692 -20.589837840749855 25.056000000000001 - -22.139117039167985 40.272 -13.074602990615206 55 -23.383894748085673; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.608 1 11.636 1 19.692 1 25.056000000000001 - 1 40.272 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.608 1 11.636 1 19.692 1 25.056000000000001 - 1 40.272 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.608 1 11.636 1 19.692 1 25.056000000000001 - 1 40.272 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11.636 1 16.992 1 22.364000000000001 - 1 40.272 1 48.452 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11.636 0 16.992 0 22.364000000000001 - 0 40.272 0 48.452 0 55 0; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.74525677667777757 11.636 0.74525677667777757 - 16.992 0.74525677667777757 22.364000000000001 0.74525677667777757 40.272 - 0.74525677667777757 48.452 0.74525677667777757 55 0.74525677667777757; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.8072476834435935 11.636 1.8072476834435935 - 16.992 1.8072476834435935 22.364000000000001 1.8072476834435935 40.272 1.8072476834435935 - 48.452 1.8072476834435935 55 1.8072476834435935; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -5.2846953468686371 11.636 -2.2209257425247575 - 16.992 29.049649739459184 22.364000000000001 43.277306460408866 40.272 24.124721048275823 - 48.452 -5.8947304930716964 55 -8.176501274828464; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11.636 0 16.992 0 22.364000000000001 - 0 40.272 0 48.452 0 55 0; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 11.636 0 16.992 0 22.364000000000001 - 0 40.272 0 48.452 0 55 0; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11.636 1 16.992 1 22.364000000000001 - 1 40.272 1 48.452 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11.636 1 16.992 1 22.364000000000001 - 1 40.272 1 48.452 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 11.636 1 16.992 1 22.364000000000001 - 1 40.272 1 48.452 1 55 1; - setAttr -s 7 ".kbd[1:6]" yes yes yes yes yes no; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10.292 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.41287000000041 10.292 -12.41287000000041 - 55 -12.41287000000041; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.7285999999993047 10.292 -6.7285999999993047 - 55 -6.7285999999993047; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.8687599999999316 10.292 -3.8687599999999316 - 55 -3.8687599999999316; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 8.5757406876636644 10.292 79.786575754112874 - 14.788 79.786575754112874 19.384 54.648994945673039 45.808 39.222726678682477 - 55 -1.9703415328539626; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 0.95564764738082886; - setAttr -s 6 ".kiy[5]" 0.29451239109039307; - setAttr -s 6 ".kox[5]" 0.95564770698547363; - setAttr -s 6 ".koy[5]" 0.2945123016834259; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10.292 2.2048955355629136 14.788 - 2.2048955355629136 19.384 1.5610738595831426 45.808 17.752775166719342 55 - 0; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 1; - setAttr -s 6 ".kiy[5]" 0; - setAttr -s 6 ".kox[5]" 1; - setAttr -s 6 ".koy[5]" 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10.292 33.720091837144814 14.788 - 33.720091837144814 19.384 23.873944951628197 45.808 -0.41568347094639946 - 55 0; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 1; - setAttr -s 6 ".kiy[5]" 0; - setAttr -s 6 ".kox[5]" 1; - setAttr -s 6 ".koy[5]" 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10.292 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10.292 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10.292 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[2]" 1; - setAttr -s 3 ".kot[2]" 1; - setAttr -s 3 ".kix[2]" 1; - setAttr -s 3 ".kiy[2]" 0; - setAttr -s 3 ".kox[2]" 1; - setAttr -s 3 ".koy[2]" 0; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 49.111805173615501 8.336 31.977250543080615 - 18.236 39.597139866968838 55 48.53310063223288; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 0.99998170137405396; - setAttr -s 4 ".kiy[3]" -0.0060524786822497845; - setAttr -s 4 ".kox[3]" 0.99998170137405396; - setAttr -s 4 ".koy[3]" -0.00605048518627882; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -36.514345314725674 8.336 -24.681548860334939 - 18.236 0.31462045837323505 55 -37.40583503775288; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 0.99999839067459106; - setAttr -s 4 ".kiy[3]" -0.0018030918436124921; - setAttr -s 4 ".kox[3]" 0.99999839067459106; - setAttr -s 4 ".koy[3]" -0.0018023141892626882; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -10.891726707689953 8.336 -20.923070313388816 - 18.236 -11.406515017732458 55 -10.23450562925086; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 0.98737305402755737; - setAttr -s 4 ".kiy[3]" 0.15841226279735565; - setAttr -s 4 ".kox[3]" 0.98737305402755737; - setAttr -s 4 ".koy[3]" 0.15841236710548401; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.952 1 14.788 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.412879749935719 8.952 12.412879749935719 - 14.788 12.412879749935719 55 12.412879749935719; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.7286993982861674 8.952 -6.7286993982861674 - 14.788 -6.7286993982861674 55 -6.7286993982861674; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -3.868763862603668 8.952 -3.868763862603668 - 14.788 -3.868763862603668 55 -3.868763862603668; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 19.580561221118923 8.952 79.829486727524269 - 14.788 79.829486727524269 20.532 70.518429452914006 45.808 47.570309277923911 - 55 3.8817931390284506; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 0.96369034051895142; - setAttr -s 6 ".kiy[5]" 0.26702243089675903; - setAttr -s 6 ".kox[5]" 0.96369034051895142; - setAttr -s 6 ".koy[5]" 0.26702228188514709; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.952 -11.04517248249685 14.788 - -11.04517248249685 20.532 -10.251743550898951 45.808 -5.1764847361533999 - 55 0; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 1; - setAttr -s 6 ".kiy[5]" 0; - setAttr -s 6 ".kox[5]" 1; - setAttr -s 6 ".koy[5]" 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.952 5.5731579237573357 14.788 - 5.5731579237573357 20.532 19.015912864268277 45.808 28.193335556788593 55 - 0; - setAttr -s 6 ".kbd[1:5]" yes yes yes yes no; - setAttr -s 6 ".kit[5]" 1; - setAttr -s 6 ".kot[5]" 1; - setAttr -s 6 ".kix[5]" 1; - setAttr -s 6 ".kiy[5]" 0; - setAttr -s 6 ".kox[5]" 1; - setAttr -s 6 ".koy[5]" 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.952 1 14.788 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.952 1 14.788 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.952 1 14.788 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 0\n" - + " -nurbsSurfaces 0\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 0\n" - + " -planes 0\n" - + " -lights 0\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 0\n" - + " -ikHandles 0\n" - + " -deformers 0\n" - + " -dynamics 0\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 0\n" - + " -handles 1\n" - + " -pivots 0\n" - + " -textures 0\n" - + " -strokes 0\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 0\n" - + " -nurbsSurfaces 0\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 0\n" - + " -planes 0\n" - + " -lights 0\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 0\n" - + " -ikHandles 0\n" - + " -deformers 0\n" - + " -dynamics 0\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 0\n" - + " -handles 1\n" - + " -pivots 0\n" - + " -textures 0\n" - + " -strokes 0\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 0\n" - + " -nurbsSurfaces 0\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 0\n" - + " -planes 0\n" - + " -lights 0\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 0\n" - + " -ikHandles 0\n" - + " -deformers 0\n" - + " -dynamics 0\n" - + " -fluids 0\n" - + " -locators 0\n" - + " -dimensions 0\n" - + " -handles 1\n" - + " -pivots 0\n" - + " -textures 0\n" - + " -strokes 0\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 0\n" - + " -nurbsSurfaces 0\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 0\n" - + " -planes 0\n" - + " -lights 0\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 0\n" - + " -ikHandles 0\n" - + " -deformers 0\n" - + " -dynamics 0\n" - + " -fluids 0\n" - + " -locators 0\n" - + " -dimensions 0\n" - + " -handles 1\n" - + " -pivots 0\n" - + " -textures 0\n" - + " -strokes 0\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 0\\n -nurbsSurfaces 0\\n -polymeshes 1\\n -subdivSurfaces 0\\n -planes 0\\n -lights 0\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 0\\n -ikHandles 0\\n -deformers 0\\n -dynamics 0\\n -fluids 0\\n -locators 0\\n -dimensions 0\\n -handles 1\\n -pivots 0\\n -textures 0\\n -strokes 0\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 0\\n -nurbsSurfaces 0\\n -polymeshes 1\\n -subdivSurfaces 0\\n -planes 0\\n -lights 0\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 0\\n -ikHandles 0\\n -deformers 0\\n -dynamics 0\\n -fluids 0\\n -locators 0\\n -dimensions 0\\n -handles 1\\n -pivots 0\\n -textures 0\\n -strokes 0\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 3 -max 46 -ast 3 -aet 46 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 45.184 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[1:2]" 1 9; - setAttr -s 3 ".kot[1:2]" 5 5; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.4264261331675518 45.184 5.8137795257559475 - 55 5.6875851059539269; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.81786155700683594; - setAttr -s 3 ".kiy[1:2]" 0 -0.57541507482528687; - setAttr -s 3 ".kox[1:2]" 1 0.81786102056503296; - setAttr -s 3 ".koy[1:2]" 0 -0.57541584968566895; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.3937238431314825 45.184 4.6602991197236454 - 55 4.6360512874533484; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99098563194274902; - setAttr -s 3 ".kiy[1:2]" 0 -0.13396798074245453; - setAttr -s 3 ".kox[1:2]" 1 0.99098563194274902; - setAttr -s 3 ".koy[1:2]" 0 -0.13396833837032318; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 7.7712681071056613 45.184 7.7844874121673691 - 55 7.7832849769829666; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99997752904891968; - setAttr -s 3 ".kiy[1:2]" 0 -0.0067047001793980598; - setAttr -s 3 ".kox[1:2]" 1 0.99997752904891968; - setAttr -s 3 ".koy[1:2]" 0 -0.0067041139118373394; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 45.184 -2.6718525581737946 - 55 -2.4288193950471157; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99972051382064819; - setAttr -s 3 ".kiy[1:2]" 0 0.023641971871256828; - setAttr -s 3 ".kox[1:2]" 1 0.99972051382064819; - setAttr -s 3 ".koy[1:2]" 0 0.023641960695385933; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 45.184 10.944524996277053 55 - 9.9490050449133296; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99534088373184204; - setAttr -s 3 ".kiy[1:2]" 0 -0.096418708562850952; - setAttr -s 3 ".kox[1:2]" 1 0.99534088373184204; - setAttr -s 3 ".koy[1:2]" 0 -0.096418678760528564; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 45.184 0.90809814617374629 - 55 0.82549704447039274; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99996769428253174; - setAttr -s 3 ".kiy[1:2]" 0 -0.0080373194068670273; - setAttr -s 3 ".kox[1:2]" 1 0.99996769428253174; - setAttr -s 3 ".koy[1:2]" 0 -0.0080373194068670273; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 45.184 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 45.184 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 45.184 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 50.092 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 9; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -4.0846345617354372 50.092 -4.769570789566667 - 55 -4.7433611394888588; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.9575268030166626; - setAttr -s 3 ".kiy[1:2]" 0 0.28834423422813416; - setAttr -s 3 ".kox[1:2]" 1 0.95752739906311035; - setAttr -s 3 ".koy[1:2]" 0 0.28834220767021179; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.282468147773308 50.092 4.4352392314085174 - 55 4.4293933198018776; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99775224924087524; - setAttr -s 3 ".kiy[1:2]" 0 -0.067011035978794098; - setAttr -s 3 ".kox[1:2]" 1 0.99775201082229614; - setAttr -s 3 ".koy[1:2]" 0 -0.067014433443546295; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 7.7712681071056613 50.092 7.6330797418271441 - 55 7.6383676336798532; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.99815976619720459; - setAttr -s 3 ".kiy[1:2]" 0 0.060638811439275742; - setAttr -s 3 ".kox[1:2]" 1 0.99815952777862549; - setAttr -s 3 ".koy[1:2]" 0 0.060642607510089874; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 50.092 0 55 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 1; - setAttr -s 3 ".kot[0:2]" 9 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 50.092 -6.8555441350667934 - 55 -6.5932110804377366; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 3 1 1; - setAttr -s 3 ".kot[0:2]" 3 1 1; - setAttr -s 3 ".kix[1:2]" 1 0.9986191987991333; - setAttr -s 3 ".kiy[1:2]" 0 0.052532311528921127; - setAttr -s 3 ".kox[1:2]" 1 0.9986191987991333; - setAttr -s 3 ".koy[1:2]" 0 0.052532263100147247; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 50.092 0 55 0; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 1; - setAttr -s 3 ".kot[0:2]" 9 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 50.092 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 1; - setAttr -s 3 ".kot[0:2]" 9 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 50.092 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 1; - setAttr -s 3 ".kot[0:2]" 9 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 50.092 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kit[0:2]" 9 1 1; - setAttr -s 3 ".kot[0:2]" 9 1 1; - setAttr -s 3 ".kix[1:2]" 1 1; - setAttr -s 3 ".kiy[1:2]" 0 0; - setAttr -s 3 ".kox[1:2]" 1 1; - setAttr -s 3 ".koy[1:2]" 0 0; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.7384771804188404 55 5.7384771804188404; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.0494561358638701 55 2.0494561358638701; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -15.409205020920503 55 -15.409205020920503; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 5.6617615262233931; - setAttr -s 2 ".kix[0:1]" 1 0.99768441915512085; - setAttr -s 2 ".kiy[0:1]" 0 0.068013660609722137; - setAttr -s 2 ".kox[0:1]" 1 0.99768435955047607; - setAttr -s 2 ".koy[0:1]" 0 0.068013705313205719; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 27.72702953106549 55 21.744100922033642; - setAttr -s 2 ".kix[0:1]" 1 0.99741530418395996; - setAttr -s 2 ".kiy[0:1]" 0 -0.071852400898933411; - setAttr -s 2 ".kox[0:1]" 1 0.99741530418395996; - setAttr -s 2 ".koy[0:1]" 0 -0.071852393448352814; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 1; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; - setAttr -s 2 ".kox[0:1]" 1 1; - setAttr -s 2 ".koy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.3128351505039433 55 2.3128351505039433; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.23421866920666501 55 0.23421866920666501; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.660431799163181 11.636 12.660431799163193 - 18.344000000000001 28.058005418095856 55 12.660431799163181; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 11.636 0 18.344000000000001 - 0.69879773133918499 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[3]" 1; - setAttr -s 4 ".kot[3]" 1; - setAttr -s 4 ".kix[3]" 1; - setAttr -s 4 ".kiy[3]" 0; - setAttr -s 4 ".kox[3]" 1; - setAttr -s 4 ".koy[3]" 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.21529931220431 11.636 1.2295313269626582 - 18.344000000000001 0.30556707462957666 55 1.37983350423336; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[1]" 1; - setAttr -s 2 ".kot[1]" 1; - setAttr -s 2 ".kix[1]" 1; - setAttr -s 2 ".kiy[1]" 0; - setAttr -s 2 ".kox[1]" 1; - setAttr -s 2 ".koy[1]" 0; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 5; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3 1 46 1 55 1; - setAttr -s 4 ".kit[0:3]" 1 9 9 9; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.83371697884823759 3 0.4494172494 - 46 0.4494172494 55 0.018122242582603421; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 0.86093151569366455; - setAttr -s 4 ".kiy[0:3]" 0 0 0 -0.50872087478637695; - setAttr -s 4 ".kox[0:3]" 1 1 1 0.86093145608901978; - setAttr -s 4 ".koy[0:3]" 0 0 0 -0.50872093439102173; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.1086667563431649 3 -0.058577090280000001 - 46 -0.058577090280000001 55 -0.0023620549528063084; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 0.9970473051071167; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0.076790012419223785; - setAttr -s 4 ".kox[0:3]" 1 1 1 0.9970473051071167; - setAttr -s 4 ".koy[0:3]" 0 0 0 0.076790027320384979; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 3 0 46 0 55 0; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 3 0 46 0 55 0; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 3 0 46 0 55 0; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 3 0 46 0 55 0; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3 1 46 1 55 1; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3 1 46 1 55 1; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3 1 46 1 55 1; - setAttr -s 4 ".kit[0:3]" 1 3 3 1; - setAttr -s 4 ".kot[0:3]" 1 3 3 1; - setAttr -s 4 ".kix[0:3]" 1 1 1 1; - setAttr -s 4 ".kiy[0:3]" 0 0 0 0; - setAttr -s 4 ".kox[0:3]" 1 1 1 1; - setAttr -s 4 ".koy[0:3]" 0 0 0 0; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -1.08568 55 -1.08568; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537988160630093 55 4.1537988160630093; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185075120832098 55 4.6185075120832098; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -5.8119691574396866 55 -5.8119691574396866; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 5.9186219656239931 55 5.9186219656239931; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.1258655568218376 55 -4.1258655568218376; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.085679155728795 55 1.085679155728795; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.1537911794025533 55 4.1537911794025533; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.6185070801020824 55 4.6185070801020824; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -6.3244262317670241 55 -6.3244262317670241; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.0332012531196431 55 1.0332012531196431; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.463963295533194 55 8.463963295533194; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 7.1689522480000001 46 7.1689522480000001; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 0 46 0; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 -7.748575014 46 -7.748575014; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 10.10932652 46 10.10932652; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 63.314403930000005 46 63.314403930000005; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 11.59016476 46 11.59016476; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 -7.392405718 46 -7.392405718; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 0 46 0; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 -7.3620493590000002 46 -7.3620493590000002; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 5.3462904040000003 46 5.3462904040000003; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 -29.548385579999998 46 -29.548385579999998; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 -5.3030645630000004 46 -5.3030645630000004; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -71.101691513482606 55 -71.101691513482606; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 32.578198345223548 55 32.578198345223548; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -95.56444850608456 55 -95.56444850608456; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -118.97547160373531 55 -118.97547160373531; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 30.32938199865233 55 30.32938199865233; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -92.904446145666853 55 -92.904446145666853; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kot[0:1]" 5 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 55 1; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; - setAttr -s 2 ".kit[0:1]" 1 9; - setAttr -s 2 ".kix[0:1]" 1 1; - setAttr -s 2 ".kiy[0:1]" 0 0; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 1; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 55.093539413074161; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 -43.06669930639881; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 45.347904894038919; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 1; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 -31.985789116916926; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 -63.633495633976999; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 -40.765251761238815; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 55 0.5814880999021691; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 11.636 1 18.344000000000001 - 1 55 1; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.5294371750177831 11.636 -2.5294371750177831 - 18.344000000000001 -2.5294371750177831 55 -2.5294371750177831; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 13.481673551673362 11.636 13.481673551673362 - 18.344000000000001 13.481673551673362 55 13.481673551673362; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.26635088939205875 11.636 -0.26635088939205875 - 18.344000000000001 -0.26635088939205875 55 -0.26635088939205875; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 141.20709981379272 11.636 366.06015233979912 - 18.344000000000001 290.54453882797736 55 323.37327933639068; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 64.064019952206479 11.636 60.452875067120452 - 18.344000000000001 59.801098563240878 55 80.510595246148824; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 252.95011708695623 11.636 450.11090965480804 - 18.344000000000001 376.96858778026393 55 424.18783977739457; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 11.636 15.445123296459185 - 18.344000000000001 15.445123296459185 55 15.445123296459185; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 11.636 15.445123296459185 - 18.344000000000001 15.445123296459185 55 15.445123296459185; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 11.636 15.445123296459185 - 18.344000000000001 15.445123296459185 55 15.445123296459185; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8.952 0 12.972 0 18.344000000000001 - 0 55 0; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 12.972 0.80000000000000004 - 18.344000000000001 0 55 0.45393508498681923; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[2:3]" 3 9; - setAttr -s 4 ".kot[2:3]" 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8.952 0 12.972 0 18.344000000000001 - 0 55 0; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 12.972 0 18.344000000000001 - 0.30659229892737039 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[1:3]" 3 9 9; - setAttr -s 4 ".kot[1:3]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8.952 0 12.972 0 18.344000000000001 - 0 55 0; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 8.952 0 12.972 0 18.344000000000001 - 0 55 0; - setAttr -s 5 ".kbd[1:4]" yes yes yes no; - setAttr -s 5 ".kit[3:4]" 3 9; - setAttr -s 5 ".kot[3:4]" 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 16.992 1 55 1; - setAttr -s 3 ".kbd[1:2]" yes no; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.71946295727715 16.992 13.71946295727715 - 55 13.71946295727715; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 55 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 68.596496127541187 16.992 26.883916547895073 - 55 -50.985109126157433; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -60.802874383230787 16.992 -58.709675487321149 - 55 -67.713423201478207; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -157.43468421330525 16.992 -87.533850060282305 - 55 -33.544491604786437; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459183 16.992 15.445123296459183 - 55 15.445123296459183; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 16.992 15.445123296459185 - 55 15.445123296459185; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459181 16.992 15.445123296459181 - 55 15.445123296459181; - setAttr -s 3 ".kbd[1:2]" yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 11.636 0 18.344000000000001 - 0 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 12.972 0.80000000000000004 - 18.344000000000001 0 55 0.45393508498681923; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[2:3]" 3 9; - setAttr -s 4 ".kot[2:3]" 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 11.636 0 18.344000000000001 - 0 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 12.972 0 18.344000000000001 - 0.30659229892737039 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; - setAttr -s 4 ".kit[1:3]" 3 9 9; - setAttr -s 4 ".kot[1:3]" 3 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 11.636 0 18.344000000000001 - 0 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 11.636 0 18.344000000000001 - 0 55 0; - setAttr -s 4 ".kbd[1:3]" yes yes no; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 3 1 46 1; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 3 1; -select -ne :time1; - setAttr ".o" 3; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Rhand_GOAL" "group1"; -parent -s -nc -r "IMP_Lhand_GOAL" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049338562 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lshldr; - setAttr ".ra" -type "double3" -90.90398877138675 -8.0808711689142498 89.883202428956693 ; - setAttr ".jo" -type "double3" 164.75873697870293 89.0723577156771 82.838695884636735 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Rshldr; - setAttr ".ra" -type "double3" 44.301357164874034 192.09383512215641 43.348288914766634 ; - setAttr ".jo" -type "double3" 41.116473914608129 201.73952513262623 40.048560793896556 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611652 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_Rhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne IMP_Hips; - setAttr ".t" -type "double3" -0.0180767416209342 4.350740136846035 2.679538405939565 ; - setAttr ".r" -type "double3" 0 0 0 ; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_LIK; -select -ne IMP_RIK; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_Lwing; - setAttr ".ssc" yes; -select -ne IMP_Rwing; - setAttr ".ssc" yes; -select -ne IMP_Lhand_GOAL; - setAttr ".t" -type "double3" 29.775846152470962 57.582470209590937 -1.0893063224582775 ; - setAttr ".r" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; - setAttr ".s" -type "double3" 1 0.99999999999999989 0.99999999999999978 ; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "P:/Doom/base/models/monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of sight2.ma diff --git a/base/models/monsters/imp/animation/cycles/slash1.ma b/base/models/monsters/imp/animation/cycles/slash1.ma deleted file mode 100644 index 70c050371..000000000 --- a/base/models/monsters/imp/animation/cycles/slash1.ma +++ /dev/null @@ -1,4674 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:25 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: slash1.ma -//Last modified: Tue, Jan 21, 2003 06:55:43 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 833.17893635863379 -62.958664620464361 -48.650389080770204 ; - setAttr ".r" -type "double3" 9.2698910856730272 -984.59999999998502 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 597.28836114981823; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 246.3070297740347 33.255654340474216 6.8253394288779106 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 119.53135691131881; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 220.73398190977039 27.478851418490692 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 142.21720599998613; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 502.30005776407745 36 -4.2986908380167517 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 209.91082357055421; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 43 1 45.252000000000002 1 58.752000000000002 1 64.376000000000005 - 1 73 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 43 1 45.252000000000002 1 58.752000000000002 1 64.376000000000005 - 1 73 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 43 1 45.252000000000002 1 58.752000000000002 1 64.376000000000005 - 1 73 1; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 -38.367703938541368 20.18 -38.367703938541368 - 25 -38.367703938541368 36 -38.367703938541368 37 -38.367703938541368 38 -38.367703938541418 - 42 -38.367703938541425 43 -38.36770393854141 45.252000000000002 -38.36770393854141 - 58.752000000000002 -38.36770393854141 64.376000000000005 -38.36770393854141 - 73 -38.36770393854141; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 0 20.18 0 25 0 36 0 37 0 38 - -106.5776725621525 42 -65.464724689752856 43 -4.5087060753243948 45.252000000000002 - -4.5087060753243948 58.752000000000002 -4.5087060753243948 64.376000000000005 - -4.5087060753243948 73 -4.5087060753243948; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 0 20.18 0 25 0 36 0 37 0 38 - -4.056605094900921e-015 42 0 43 -2.5353781843130746e-016 45.252000000000002 - -2.5353781843130746e-016 58.752000000000002 0 64.376000000000005 0 73 0; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 -8.52286618097577 20.18 -8.52286618097577 - 25 -8.5228661809757682 36 -8.5228661809757682 37 -8.5228661809757682 38 -8.5228661809757682 - 42 -8.5228661809757469 43 -8.5228661809757362 45.252000000000002 -8.5228661809757362 - 58.752000000000002 -8.5228661809757362 64.376000000000005 -8.5228661809757309 - 73 -8.5228661809757309; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 0 20.18 0 25 0 36 0 37 0 38 - 15.856399981493698 42 26.231575278026614 43 1.1173925191969412 45.252000000000002 - 1.1173925191969412 58.752000000000002 1.1173925191969412 64.376000000000005 - 1.1173925191969412 73 1.1173925191969412; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 -4.579364761070849 20.18 -4.579364761070849 - 25 18.100304531459912 36 18.100304531459912 37 18.100304531459912 38 37.284590928822638 - 42 121.06902539893741 43 203.17308441818832 45.252000000000002 203.17308441818832 - 58.752000000000002 203.17308441818832 64.376000000000005 223.47963978432884 - 73 223.47963978432884; - setAttr -s 12 ".kit[4:11]" 9 9 9 3 3 3 3 - 3; - setAttr -s 12 ".kot[4:11]" 9 9 9 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 43 1 45.252000000000002 1 58.752000000000002 1 64.376000000000005 - 1 73 1; - setAttr -s 12 ".kot[0:11]" 5 5 5 5 5 5 5 - 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 43 1 45.252000000000002 1 48.624000000000002 1 53.128 1 - 62.124000000000002 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 43 1 45.252000000000002 1 48.624000000000002 1 53.128 1 - 62.124000000000002 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 43 1 45.252000000000002 1 48.624000000000002 1 53.128 1 - 62.124000000000002 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 36.23707061730854 14.800000000000001 36.23707061730854 - 37 36.23707061730854 38 36.23707061730854 42 36.23707061730854 43 36.23707061730854 - 45.252000000000002 36.23707061730854 48.624000000000002 36.23707061730854 - 53.128 36.23707061730854 62.124000000000002 36.23707061730854 73 36.23707061730854; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 14.439669496646856 14.800000000000001 0 37 0 38 -94.950298577729043 - 42 -61.214627600253856 43 1.3309014920097999 45.252000000000002 1.3309014920097999 - 48.624000000000002 1.3309014920097999 53.128 1.3309014920097999 62.124000000000002 - 1.3309014920097999 73 1.3309014920097999; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 0 12.2 0 13 0 14.800000000000001 - 0 37 0 38 0 42 0 43 1.2322717886371888e-016 45.252000000000002 1.2322717886371888e-016 - 48.624000000000002 0 53.128 0 62.124000000000002 1.2322717886371888e-016 - 73 1.2322717886371888e-016; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 9.6873596619451892 14.800000000000001 9.6873596619451892 - 37 9.6873596619451892 38 9.6873596619451909 42 9.6873596619452016 43 9.6873596619452123 - 45.252000000000002 9.6873596619452123 48.624000000000002 9.6873596619452123 - 53.128 9.6873596619452194 62.124000000000002 9.6873596619452194 73 9.6873596619452194; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 14.800000000000001 0 37 0 38 15.451973974847458 42 26.633340511302404 - 43 -0.14993282020596688 45.252000000000002 -0.14993282020596688 48.624000000000002 - -0.14993282020596688 53.128 -0.14993282020596688 62.124000000000002 -0.14993282020596688 - 73 -0.14993282020596688; - setAttr -s 14 ".kit[1:13]" 9 3 3 3 3 3 3 - 3 3 3 3 3 3; - setAttr -s 14 ".kot[1:13]" 9 3 3 3 3 3 3 - 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 26.486563744388956 14.800000000000001 26.486563744388956 - 37 26.486563744388956 38 39.09212146071188 42 135.30388003020795 43 193.81103051165826 - 45.252000000000002 193.81103051165826 48.624000000000002 193.81103051165826 - 53.128 236.50094804274906 62.124000000000002 236.50094804274906 73 236.50094804274906; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 43 1 45.252000000000002 1 48.624000000000002 1 53.128 1 - 62.124000000000002 1 73 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 38.993623662586046 20.18 37.069797976495074 28 - 25.985749074130414 35 20.728138454973941 40 49.406014559463785 43 37.610815773490515 - 45.252000000000002 37.610815773490515 50.876 37.300586130982779 55.368000000000002 - 27.100211381404904 59.872 31.715337600982302 63.244 34.894123517527945 67.748000000000005 - 39.791808485242719 73 39.791808485242719; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 14.373557394032371 20.18 17.766738474032827 28 - 28.168692059328908 35 30.558515068036385 40 105.8379398423222 43 203.1600181136379 - 45.252000000000002 203.1600181136379 50.876 221.79599095164204 55.368000000000002 - 227.74620955556244 59.872 228.8999911104568 63.244 233.62275875789607 67.748000000000005 - 240.89931928135803 73 240.89931928135803; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 0.65147019540262718 20.18 3.4389526704134474 - 28 3.4389526704134483 35 3.4389526704134483 40 3.4389526704134648 43 2.1550846074433267 - 45.252000000000002 2.1550846074433267 50.876 -1.2817025244496318 55.368000000000002 - 3.4389526704134887 59.872 3.4389526704134887 63.244 7.955158822769393 67.748000000000005 - 3.4389526704134905 73 3.4389526704134905; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 45.252000000000002 1 50.876 1 55.368000000000002 1 59.872 - 1 63.244 1 67.748000000000005 1 73 1; - setAttr -s 16 ".kot[5:15]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 45.252000000000002 1 50.876 1 55.368000000000002 1 59.872 - 1 63.244 1 67.748000000000005 1 73 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 45.252000000000002 1 50.876 1 55.368000000000002 1 59.872 - 1 63.244 1 67.748000000000005 1 73 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 45.252000000000002 1 50.876 1 55.368000000000002 1 59.872 - 1 63.244 1 67.748000000000005 1 73 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 3 - 3; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 3 - 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 73 - 1; - setAttr -s 6 ".kot[5]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 -4.1657930308134645 19.46 -1.6735805890538134 73 -1.6735805890538134; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287 19.46 0.21813466524646566 73 0.21813466524646566; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 73 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 73 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 73 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 -7.4542171015494922 19.46 0 73 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 73 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 73 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 73 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46.372 1 55.368000000000002 1 63.244 1 67.748000000000005 1 73 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46.372 1 55.368000000000002 1 63.244 1 67.748000000000005 1 73 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46.372 1 55.368000000000002 1 63.244 1 67.748000000000005 1 73 - 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 19.46 2.3128351505039433 24 2.3128351505039433 34 2.3128351505039433 - 40 2.3128351505039433 43 2.3128351505039433 46.372 2.3128351505039433 55.368000000000002 - 2.3128351505039433 63.244 2.3128351505039433 67.748000000000005 2.3128351505039433 - 73 2.3128351505039433; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 19.46 0.23421866920666501 24 0.23421866920666501 34 - 0.23421866920666501 40 0.23421866920666501 43 0.23421866920666501 46.372 - 0.23421866920666501 55.368000000000002 0.23421866920666501 63.244 0.23421866920666501 - 67.748000000000005 0.23421866920666501 73 0.23421866920666501; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 0 13 0 19.46 0 24 0 34 - 0 40 0 43 0 46.372 0 55.368000000000002 0 63.244 0 67.748000000000005 0 73 - 0; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581372 19.46 7.8247378664801399 24 -4.9687329344827127 34 - 28.583434985398817 40 -2.0830132220114304 43 20.253225946181054 46.372 8.9638927324932833 - 55.368000000000002 22.877076884835944 63.244 11.967706987968739 67.748000000000005 - 14.860798832736082 73 14.860798832736082; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 12.660431799163181 8.2 13.751352433260992 - 13 13.892774724407374 19.46 13.751352433260992 24 -8.6726939272339099 34 - 44.785835032594498 40 -44.116995890821372 43 5.0288927723012957 46.372 4.3119030022781359 - 55.368000000000002 7.7924052090692992 63.244 10.378568124469185 67.748000000000005 - 1.2668117475880938 73 1.2668117475880938; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 22.776694843251629 13 26.888910802325626 - 19.46 22.776694843251629 24 21.472297863750494 34 2.2079750683772614 40 31.930384700051565 - 43 20.723807121401762 46.372 21.261440092307385 55.368000000000002 13.557082065219102 - 63.244 32.173057052834672 67.748000000000005 14.956197574697519 73 14.956197574697519; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46.372 1 55.368000000000002 1 63.244 1 67.748000000000005 1 73 - 1; - setAttr -s 13 ".kot[4:12]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857 18.74 398.33832420130017 33 398.33832420130017 38 412.87438477691256 - 41 363.74139408925856 73 363.74139408925856; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099 18.74 -14.641906192173103 33 -14.641906192173103 38 - -14.641906192173103 41 -19.235073321416994 73 -19.235073321416994; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167 18.74 -0.44667534838541073 33 -0.44667534838541073 - 38 -0.44667534838541134 41 -6.1644555251967859 73 -6.1644555251967859; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 18.74 5.6268319407172029 33 5.6268319407172029 38 9.0210664288932136 - 41 5.6268319407172029 73 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 18.74 -2.1098668596606802 33 -2.1098668596606802 38 - 2.1840208462615793 41 -2.1098668596606802 73 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 6.6 0 13 0 18.74 0 33 0 38 - -0.027812113261208363 41 0 73 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 73 1; - setAttr -s 8 ".kot[4:7]" 5 5 5 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 73 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 73 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 73 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 20.9 5.7384771804188404 73 5.7384771804188404; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 20.9 2.0494561358638701 73 2.0494561358638701; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 9.8000000000000007 0 13 0 20.9 - 0 73 0; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 20.9 36.348615312237058 73 36.348615312237058; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 20.9 -12.486888359019849 73 -12.486888359019849; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 20.9 -36.216831783693365 73 -36.216831783693365; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 73 1; - setAttr -s 5 ".kot[4]" 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44.12 1 46.372 1 48.624000000000002 1 49.744 1 54.248 1 - 57.62 1 60.992 1 67.748000000000005 1 73 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44.12 1 46.372 1 48.624000000000002 1 49.744 1 54.248 1 - 57.62 1 60.992 1 67.748000000000005 1 73 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44.12 1 46.372 1 48.624000000000002 1 49.744 1 54.248 1 - 57.62 1 60.992 1 67.748000000000005 1 73 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -16.115585356027545 20.18 -10.142543541392451 - 25 -6.9280630876017737 34 -23.972862154377175 38 -15.130983324653501 41 -30.039509523571379 - 44.12 -35.978590618894593 46.372 -40.601884828844661 48.624000000000002 -5.8089708010832837 - 49.744 -15.63353436857974 54.248 -10.960925940079917 57.62 0.75210337741853828 - 60.992 -37.62205449358985 67.748000000000005 -23.766035573245222 73 -23.766035573245222; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 2.156870399342198 20.18 17.225876454101705 25 14.944575916344146 - 34 14.349795315487798 38 18.846730556029243 41 21.222331139965377 44.12 11.601196461359804 - 46.372 12.924031190326062 48.624000000000002 17.38635914348577 49.744 48.532089804961913 - 54.248 65.103011015596081 57.62 -1.0507515021622431 60.992 -10.200505454394669 - 67.748000000000005 16.713082101524591 73 16.713082101524591; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -19.144863004444691 20.18 -25.389628185944296 - 25 -4.1316061606907093 34 -67.203015108794645 38 -36.152530154079884 41 -12.042151395079298 - 44.12 -8.8954744207769192 46.372 8.8934263782584324 48.624000000000002 7.5170623891361279 - 49.744 -19.205731255459568 54.248 -4.1858965905874879 57.62 -30.972839455133265 - 60.992 -26.548110055998258 67.748000000000005 -5.6623198000214572 73 -5.6623198000214572; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 20.18 2.6456615572060826 25 - 2.6456615572060826 34 2.6456615572060826 38 2.6456615572060826 41 2.6456615572060826 - 44.12 2.6456615572060826 46.372 2.6456615572060826 48.624000000000002 2.6456615572060826 - 49.744 2.6456615572060826 54.248 2.6456615572060826 57.62 2.6456615572060826 - 60.992 2.6456615572060826 67.748000000000005 2.6456615572060826 73 2.6456615572060826; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 20.18 1.9935618776130362 25 - 1.9935618776130362 34 1.9935618776130362 38 1.9935618776130362 41 1.9935618776130362 - 44.12 1.9935618776130362 46.372 1.9935618776130362 48.624000000000002 1.9935618776130362 - 49.744 1.9935618776130362 54.248 1.9935618776130362 57.62 1.9935618776130362 - 60.992 1.9935618776130362 67.748000000000005 1.9935618776130362 73 1.9935618776130362; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 0 6.6 0 11.4 0 13 0 20.18 0 25 - 0 34 0 38 0 41 0 44.12 0 46.372 0 48.624000000000002 0 49.744 0 54.248 0 - 57.62 0 60.992 0 67.748000000000005 0 73 0; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44.12 1 46.372 1 48.624000000000002 1 49.744 1 54.248 1 - 57.62 1 60.992 1 67.748000000000005 1 73 1; - setAttr -s 18 ".kot[3:17]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46.372 - 1 49.756 1 55.380000000000003 1 73 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46.372 - 1 49.756 1 55.380000000000003 1 73 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46.372 - 1 49.756 1 55.380000000000003 1 73 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 12.412879749935719 13 12.412879749935719 - 24 12.412879749935719 33 12.412879749935719 38 12.412879749935719 43 12.412879749935719 - 46.372 12.412879749935719 49.756 12.412879749935719 55.380000000000003 12.412879749935719 - 73 12.412879749935719; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -6.7286993982861674 13 -6.7286993982861674 - 24 -6.7286993982861674 33 -6.7286993982861674 38 -6.7286993982861674 43 -6.7286993982861674 - 46.372 -6.7286993982861674 49.756 -6.7286993982861674 55.380000000000003 - -6.7286993982861674 73 -6.7286993982861674; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.868763862603668 13 -3.868763862603668 - 24 -3.868763862603668 33 -3.868763862603668 38 -3.868763862603668 43 -3.868763862603668 - 46.372 -3.868763862603668 49.756 -3.868763862603668 55.380000000000003 -3.868763862603668 - 73 -3.868763862603668; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 80.239686562403847 13 105.11870283856432 - 24 71.173362214431492 33 62.893362214431335 38 -15.586637785568827 43 13.465241265972063 - 46.372 13.465241265972063 49.756 -5.8165249333031408 55.380000000000003 52.14656032181734 - 73 52.14656032181734; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.8978517871634404 13 0.21742569259672076 - 24 0 33 0 38 0 43 0 46.372 0 49.756 -13.425591566540025 55.380000000000003 - 0 73 0; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.92545182592768849 13 0.034116996666525033 - 24 0 33 0 38 0 43 0 46.372 0 49.756 23.764941955195834 55.380000000000003 - 0 73 0; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46.372 - 1 49.756 1 55.380000000000003 1 73 1; - setAttr -s 10 ".kot[2:9]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 73 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 22 -12.41287000000041 35 -12.41287000000041 39 -12.41287000000041 - 43 -12.41287000000041 73 -12.41287000000041; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 22 -6.7285999999993047 35 -6.7285999999993047 39 -6.7285999999993047 - 43 -6.7285999999993047 73 -6.7285999999993047; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 22 -3.8687599999999316 35 -3.8687599999999316 39 -3.8687599999999316 - 43 -3.8687599999999316 73 -3.8687599999999316; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 58.099612817676174 10.6 82.316033184538099 - 13 81.577924579716537 22 58.537924579716176 35 104.14864772909701 39 15.22864772910598 - 43 35.198054152525124 73 35.198054152525124; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10.6 0 13 0 22 0 35 0 39 0 - 43 0 73 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10.6 0 13 0 22 0 35 0 39 0 - 43 0 73 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 73 1; - setAttr -s 8 ".kot[3:7]" 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 43 -max 68 -ast 43 -aet 68 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 72.732401021820706 - 43 -9.0898929668531654 45.252000000000002 -9.0898929668531654 50.876 56.479937212271295 - 55.368000000000002 37.377972102371409 59.872 25.010540855983066 63.244 23.643060542713936 - 67.748000000000005 21.536127911899268 73 21.536127911899268; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 0 43 - 17.292508165127312 45.252000000000002 17.292508165127312 50.876 -21.245593852346627 - 55.368000000000002 -42.77727538577502 59.872 47.544981192946956 63.244 32.739362874090922 - 67.748000000000005 9.9277435383719759 73 9.9277435383719759; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 0 43 - -5.1124843681511107 45.252000000000002 -5.1124843681511107 50.876 -31.477670460234876 - 55.368000000000002 -13.673261261011708 59.872 -16.477174933557826 63.244 - -13.511324998039733 67.748000000000005 -8.9417191714637081 73 -8.9417191714637081; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 9 3 3 - 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 1 24 1 34 1 38 1 41 1 43 1 47.504 - 1 49.744 1 50.876 1 53.128 1 56.5 1 58.752000000000002 1 62.124000000000002 - 1 67.748000000000005 1 73 1; - setAttr -s 15 ".kot[1:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 3.3867545965885748 24 3.3867545965885748 - 34 3.3867545965885748 38 3.3867545965885748 41 3.3867545965885748 43 3.3867545965885748 - 47.504 3.3867545965885748 49.744 3.3867545965885748 50.876 3.3867545965885748 - 53.128 3.3867545965885748 56.5 3.3867545965885748 58.752000000000002 3.3867545965885748 - 62.124000000000002 3.3867545965885748 67.748000000000005 3.3867545965885748 - 73 3.3867545965885748; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 2.1192573708760349 24 2.1192573708760349 - 34 2.1192573708760349 38 2.1192573708760349 41 2.1192573708760349 43 2.1192573708760349 - 47.504 2.1192573708760349 49.744 2.1192573708760349 50.876 2.1192573708760349 - 53.128 2.1192573708760349 56.5 2.1192573708760349 58.752000000000002 2.1192573708760349 - 62.124000000000002 2.1192573708760349 67.748000000000005 2.1192573708760349 - 73 2.1192573708760349; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 -3.0821078932592165 24 -3.0821078932592165 - 34 -3.0821078932592165 38 -3.0821078932592165 41 -3.0821078932592165 43 -3.0821078932592165 - 47.504 -3.0821078932592165 49.744 -3.0821078932592165 50.876 -3.0821078932592165 - 53.128 -3.0821078932592165 56.5 -3.0821078932592165 58.752000000000002 -3.0821078932592165 - 62.124000000000002 -3.0821078932592165 67.748000000000005 -3.0821078932592165 - 73 -3.0821078932592165; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 24 -22.140269864626553 34 - 14.54853681057746 38 43.948848359898776 41 62.842953086904046 43 65.98384066882619 - 47.504 -4.083938985942738 49.744 50.571853585444678 50.876 56.929345400996077 - 53.128 106.96251683427003 56.5 75.177900944064305 58.752000000000002 68.250949867080607 - 62.124000000000002 -27.887986816957284 67.748000000000005 17.941174035372224 - 73 17.941174035372224; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 24 -18.13526372185737 34 -39.861201900326897 - 38 -29.47383974389729 41 15.902019027919991 43 22.948191272809385 47.504 - -40.800614111584515 49.744 -55.554764813756108 50.876 -22.542528905767821 - 53.128 -5.1242488079717159 56.5 13.209794194943171 58.752000000000002 4.78298502778149 - 62.124000000000002 -4.8237149575449019 67.748000000000005 5.3092707506055987 - 73 5.3092707506055987; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 -6.7129388973255946 24 -20.318492745188728 - 34 -14.119904742119406 38 -50.034198784961902 41 50.14709560038655 43 61.367804147090176 - 47.504 63.638720242704046 49.744 24.819808842928108 50.876 24.830614146032957 - 53.128 49.569638782923263 56.5 46.815517050132868 58.752000000000002 46.478959441138564 - 62.124000000000002 -24.161341278461268 67.748000000000005 -19.195258198918136 - 73 -19.195258198918136; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 1 24 1 34 1 38 1 41 1 43 1 47.504 - 1 49.744 1 50.876 1 53.128 1 56.5 1 58.752000000000002 1 62.124000000000002 - 1 67.748000000000005 1 73 1; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 1 24 1 34 1 38 1 41 1 43 1 47.504 - 1 49.744 1 50.876 1 53.128 1 56.5 1 58.752000000000002 1 62.124000000000002 - 1 67.748000000000005 1 73 1; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 1 24 1 34 1 38 1 41 1 43 1 47.504 - 1 49.744 1 50.876 1 53.128 1 56.5 1 58.752000000000002 1 62.124000000000002 - 1 67.748000000000005 1 73 1; - setAttr -s 15 ".kit[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; - setAttr -s 15 ".kot[0:14]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46.372 - 1 49.744 1 55.368000000000002 1 57.62 1 58.752000000000002 1 59.872 1 61.004 - 1 67.748000000000005 1 73 1; - setAttr -s 14 ".kot[1:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.3867499999998705 19 -3.3867499999998705 - 33 -5.6477754078936684 38 -5.6477754078936684 43 -5.6477754078936684 46.372 - -5.6477754078936684 49.744 -5.6477754078936684 55.368000000000002 -5.6477754078936684 - 57.62 -5.6477754078936684 58.752000000000002 -5.6477754078936684 59.872 -5.6477754078936684 - 61.004 -5.6477754078936684 67.748000000000005 -5.6477754078936684 73 -5.6477754078936684; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 2.1192000000001707 19 2.1192000000001707 - 33 1.3040287561282207 38 1.3040287561282207 43 1.3040287561282207 46.372 - 1.3040287561282207 49.744 1.3040287561282207 55.368000000000002 1.3040287561282207 - 57.62 1.3040287561282207 58.752000000000002 1.3040287561282207 59.872 1.3040287561282207 - 61.004 1.3040287561282207 67.748000000000005 1.3040287561282207 73 1.3040287561282207; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.0821100000000254 19 -3.0821100000000254 - 33 -3.029058051753474 38 -3.029058051753474 43 -3.029058051753474 46.372 - -3.029058051753474 49.744 -3.029058051753474 55.368000000000002 -3.029058051753474 - 57.62 -3.029058051753474 58.752000000000002 -3.029058051753474 59.872 -3.029058051753474 - 61.004 -3.029058051753474 67.748000000000005 -3.029058051753474 73 -3.029058051753474; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 22.979007009556593 19 22.979007009556593 - 33 45.373139807618806 38 80.258782191899755 43 46.588159880279875 46.372 - 31.959061384122876 49.744 33.97070997010254 55.368000000000002 -61.314618405671105 - 57.62 -106.06866853581342 58.752000000000002 14.773175884512012 59.872 6.0622897612146494 - 61.004 27.959664913206936 67.748000000000005 33.379224710917185 73 33.379224710917185; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -5.8807954640291324 19 -5.8807954640291324 - 33 40.687338569936891 38 38.061810195815809 43 -29.737712592784046 46.372 - -24.261557449005764 49.744 -27.881817407484284 55.368000000000002 66.660532823980603 - 57.62 55.501732950163429 58.752000000000002 57.488437055901841 59.872 -7.2457258210734512 - 61.004 -67.195139032636746 67.748000000000005 -49.201950059885952 73 -49.201950059885952; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.4977373448908193 19 -3.4977373448908193 - 33 9.7790492183656959 38 29.532755321174395 43 -4.3550246040394294 46.372 - -69.412610236093386 49.744 -31.083585917003656 55.368000000000002 -32.845031356484071 - 57.62 -143.68598216744616 58.752000000000002 -44.63120379456273 59.872 -74.22092055678894 - 61.004 -124.71815120495674 67.748000000000005 -57.64175562055663 73 -57.64175562055663; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46.372 - 1 49.744 1 55.368000000000002 1 57.62 1 58.752000000000002 1 59.872 1 61.004 - 1 67.748000000000005 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46.372 - 1 49.744 1 55.368000000000002 1 57.62 1 58.752000000000002 1 59.872 1 61.004 - 1 67.748000000000005 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46.372 - 1 49.744 1 55.368000000000002 1 57.62 1 58.752000000000002 1 59.872 1 61.004 - 1 67.748000000000005 1 73 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 73 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 6.7758528420198658 - 20.18 6.7758528420198658 28 6.7758528420198658 36 6.7758528420198658 37 6.7758528420198658 - 38 6.7758528420198658 73 6.7758528420198658; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -6.9388939039072284e-018 - 20.18 -6.9388939039072284e-018 28 -6.9388939039072284e-018 36 -6.9388939039072284e-018 - 37 -6.9388939039072284e-018 38 -6.9388939039072284e-018 73 -6.9388939039072284e-018; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -9.5120444723942321e-016 - 20.18 -9.5120444723942321e-016 28 -9.5120444723942321e-016 36 -9.5120444723942321e-016 - 37 -9.5120444723942321e-016 38 -9.5120444723942321e-016 73 -9.5120444723942321e-016; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -12.784757077400341 - 20.18 -37.624757077399877 28 -13.708177176672606 36 -13.567741304451721 37 - -63.244847867618518 38 0 73 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 3.2695897469829736 - 20.18 3.2695897469829753 28 3.2695897469829736 36 3.2695897469829736 37 3.2695897469829793 - 38 3.2695897469829842 73 3.2695897469829842; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -6.9162979482121409 - 20.18 -6.9162979482121507 28 -6.9162979482121409 36 -6.9162979482121409 37 - -6.9162979482121472 38 -6.916297948212156 73 -6.916297948212156; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 73 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 73 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 73 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 1 23 1 36 1 40 1 43 1 48.624000000000002 - 1 54.248 1 57.632 1 58.752000000000002 1 63.256 1 65.508 1 68.88 1 73 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 -7.5406347832540632e-013 23 - -7.5406347832540632e-013 36 -7.5406347832540632e-013 40 -7.5406347832540632e-013 - 43 -7.5406347832540632e-013 48.624000000000002 -7.5406347832540632e-013 54.248 - -7.5406347832540632e-013 57.632 -7.5406347832540632e-013 58.752000000000002 - -7.5406347832540632e-013 63.256 -7.5406347832540632e-013 65.508 -7.5406347832540632e-013 - 68.88 -7.5406347832540632e-013 73 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 13.71946295727715 23 13.71946295727715 - 36 13.71946295727715 40 13.71946295727715 43 13.71946295727715 48.624000000000002 - 13.71946295727715 54.248 13.71946295727715 57.632 13.71946295727715 58.752000000000002 - 13.71946295727715 63.256 13.71946295727715 65.508 13.71946295727715 68.88 - 13.71946295727715 73 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 -3.0908609005564358e-013 23 - -3.0908609005564358e-013 36 -3.0908609005564358e-013 40 -3.0908609005564358e-013 - 43 -3.0908609005564358e-013 48.624000000000002 -3.0908609005564358e-013 54.248 - -3.0908609005564358e-013 57.632 -3.0908609005564358e-013 58.752000000000002 - -3.0908609005564358e-013 63.256 -3.0908609005564358e-013 65.508 -3.0908609005564358e-013 - 68.88 -3.0908609005564358e-013 73 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 295.48765045513591 23 295.48765045513591 - 36 295.48765045513591 40 213.88533605815715 43 370.91519141024645 48.624000000000002 - 398.39764562243226 54.248 281.33614296793479 57.632 225.15836113498781 58.752000000000002 - 268.30338242912825 63.256 357.43496433554446 65.508 349.61719632868903 68.88 - 295.48765045513591 73 295.48765045513591; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 -63.040996980451936 23 -63.040996980451936 - 36 -63.040996980451936 40 -15.936120622721644 43 -59.137062695894762 48.624000000000002 - -41.987062615171951 54.248 -48.02411967053439 57.632 -72.500797094272656 - 58.752000000000002 -69.125138419716905 63.256 -50.860803971704257 65.508 - -52.397947671024951 68.88 -63.040996980451936 73 -63.040996980451936; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 -405.45049633490953 23 -405.45049633490953 - 36 -405.45049633490953 40 -312.99889701280722 43 -488.32777674186815 48.624000000000002 - -458.15311271132873 54.248 -374.14230220947661 57.632 -306.9152143151191 - 58.752000000000002 -376.50653539592082 63.256 -416.70307790225212 65.508 - -415.28299902132557 68.88 -405.45049633490953 73 -405.45049633490953; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 15.445123296459183 23 15.445123296459183 - 36 15.445123296459183 40 15.445123296459183 43 15.445123296459183 48.624000000000002 - 15.445123296459183 54.248 15.445123296459183 57.632 15.445123296459183 58.752000000000002 - 15.445123296459183 63.256 15.445123296459183 65.508 15.445123296459183 68.88 - 15.445123296459183 73 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 15.445123296459185 23 15.445123296459185 - 36 15.445123296459185 40 15.445123296459185 43 15.445123296459185 48.624000000000002 - 15.445123296459185 54.248 15.445123296459185 57.632 15.445123296459185 58.752000000000002 - 15.445123296459185 63.256 15.445123296459185 65.508 15.445123296459185 68.88 - 15.445123296459185 73 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 15.445123296459181 23 15.445123296459181 - 36 15.445123296459181 40 15.445123296459181 43 15.445123296459181 48.624000000000002 - 15.445123296459181 54.248 15.445123296459181 57.632 15.445123296459181 58.752000000000002 - 15.445123296459181 63.256 15.445123296459181 65.508 15.445123296459181 68.88 - 15.445123296459181 73 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 23 0 36 0 40 0 43 0 48.624000000000002 - 0 54.248 0 57.632 0 58.752000000000002 0 63.256 0 65.508 0 68.88 0 73 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 23 1 36 0.81280641091087713 - 40 0 43 0 48.624000000000002 1 54.248 0.86851990984222383 57.632 0 58.752000000000002 - 0 63.256 0 65.508 0.5 68.88 0 73 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 23 0 36 0 40 0 43 0 48.624000000000002 - 0 54.248 0 57.632 0 58.752000000000002 0 63.256 0 65.508 0 68.88 0 73 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 23 0 36 0 40 0 43 0 48.624000000000002 - 0 54.248 0 57.632 1 58.752000000000002 0.98542274052478129 63.256 0 65.508 - 0 68.88 0 73 0; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 21 1 31 1 33 1 38 1 42 1 45.252000000000002 - 1 48.624000000000002 1 51.996000000000002 1 56.5 1 59.872 1 65.496 1 67.748000000000005 - 1 73 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -2.5294371750177831 21 -2.5294371750177831 - 31 -2.5294371750177831 33 -2.5294371750177831 38 -2.5294371750177831 42 -2.5294371750177831 - 45.252000000000002 -2.5294371750177831 48.624000000000002 -2.5294371750177831 - 51.996000000000002 -2.5294371750177831 56.5 -2.5294371750177831 59.872 -2.5294371750177831 - 65.496 -2.5294371750177831 67.748000000000005 -2.5294371750177831 73 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 13.481673551673362 21 13.481673551673362 - 31 13.481673551673362 33 13.481673551673362 38 13.481673551673362 42 13.481673551673362 - 45.252000000000002 13.481673551673362 48.624000000000002 13.481673551673362 - 51.996000000000002 13.481673551673362 56.5 13.481673551673362 59.872 13.481673551673362 - 65.496 13.481673551673362 67.748000000000005 13.481673551673362 73 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -0.26635088939205875 21 -0.26635088939205875 - 31 -0.26635088939205875 33 -0.26635088939205875 38 -0.26635088939205875 42 - -0.26635088939205875 45.252000000000002 -0.26635088939205875 48.624000000000002 - -0.26635088939205875 51.996000000000002 -0.26635088939205875 56.5 -0.26635088939205875 - 59.872 -0.26635088939205875 65.496 -0.26635088939205875 67.748000000000005 - -0.26635088939205875 73 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 2.5090696653770608 21 15.660322977726873 - 31 -59.152064220349949 33 -12.576992350425726 38 100.64125841157764 42 -59.74707945275015 - 45.252000000000002 2.5090696653770608 48.624000000000002 229.81257006268098 - 51.996000000000002 205.40557331358448 56.5 3.0001199156625389 59.872 1.7699337869651124 - 65.496 2.5090696653770608 67.748000000000005 38.344019863744009 73 38.344019863744009; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 57.72712587340903 21 46.71187586847725 - 31 78.864853271093551 33 62.263510007017452 38 51.115191882761081 42 103.16836677235398 - 45.252000000000002 57.72712587340903 48.624000000000002 71.479332000486821 - 51.996000000000002 66.578124695706904 56.5 21.84732767394534 59.872 40.81600952631031 - 65.496 57.72712587340903 67.748000000000005 74.099086231188735 73 74.099086231188735; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 114.81831393065704 21 111.56128358310468 - 31 83.4253918925113 33 123.49770013948103 38 187.37668404727597 42 99.332177522833007 - 45.252000000000002 114.81831393065704 48.624000000000002 338.70706758105109 - 51.996000000000002 359.66683128416048 56.5 97.32475108483716 59.872 113.85356831963652 - 65.496 114.81831393065704 67.748000000000005 149.44218936973084 73 149.44218936973084; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45.252000000000002 15.445123296459185 48.624000000000002 15.445123296459185 - 51.996000000000002 15.445123296459185 56.5 15.445123296459185 59.872 15.445123296459185 - 65.496 15.445123296459185 67.748000000000005 15.445123296459185 73 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45.252000000000002 15.445123296459185 48.624000000000002 15.445123296459185 - 51.996000000000002 15.445123296459185 56.5 15.445123296459185 59.872 15.445123296459185 - 65.496 15.445123296459185 67.748000000000005 15.445123296459185 73 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45.252000000000002 15.445123296459185 48.624000000000002 15.445123296459185 - 51.996000000000002 15.445123296459185 56.5 15.445123296459185 59.872 15.445123296459185 - 65.496 15.445123296459185 67.748000000000005 15.445123296459185 73 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 21 0 31 0 33 0 38 0 42 0 45.252000000000002 - 0 48.624000000000002 0 51.996000000000002 0 56.5 0 59.872 0 65.496 0 67.748000000000005 - 0 73 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 21 1 31 0.86060230006204896 - 33 0.84945048406701285 38 0 42 1 45.252000000000002 0.96802113702623904 48.624000000000002 - 0 51.996000000000002 0 56.5 0 59.872 1 65.496 0 67.748000000000005 0 73 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 21 0 31 0 33 0 38 0 42 0 45.252000000000002 - 0 48.624000000000002 0 51.996000000000002 0.3935860058309037 56.5 1 59.872 - 0 65.496 0 67.748000000000005 0 73 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 21 0 31 0 33 0 38 0 42 0 45.252000000000002 - 0 48.624000000000002 1 51.996000000000002 0.60641399416909625 56.5 0 59.872 - 0 65.496 0 67.748000000000005 0 73 0; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 73 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.0180767416209342 73 -0.0180767416209342; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 4.350740136846035 73 4.350740136846035; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.679538405939565 73 2.679538405939565; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 73 0; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 73 0; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.460139794067871 73 15.460139794067871; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 73 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 73 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 73 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20 1 25 1 43 1 45.252000000000002 - 1 48.624000000000002 1 54.248 1 57.62 1 62.124000000000002 1 67.748000000000005 - 1 73 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20 0 25 0 43 0 45.252000000000002 - 0 48.624000000000002 0 54.248 0 57.62 0 62.124000000000002 0 67.748000000000005 - 0 73 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0.74525677667777757 20 0.74525677667777757 - 25 0.74525677667777757 43 0.74525677667777757 45.252000000000002 0.74525677667777757 - 48.624000000000002 0.74525677667777757 54.248 0.74525677667777757 57.62 0.74525677667777757 - 62.124000000000002 0.74525677667777757 67.748000000000005 0.74525677667777757 - 73 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1.8072476834435935 20 1.8072476834435935 - 25 1.8072476834435935 43 1.8072476834435935 45.252000000000002 1.8072476834435935 - 48.624000000000002 1.8072476834435935 54.248 1.8072476834435935 57.62 1.8072476834435935 - 62.124000000000002 1.8072476834435935 67.748000000000005 1.8072476834435935 - 73 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -3.8161377226329614 20 23.97443434067613 - 25 -3.8037016770966843 43 21.903843468262686 45.252000000000002 4.4112070880310021 - 48.624000000000002 16.07480238918647 54.248 15.109332395359594 57.62 26.061052322842336 - 62.124000000000002 13.396972450271631 67.748000000000005 -2.9107248491535329 - 73 -2.9107248491535329; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20 0 25 0 43 -0.11856626249502177 - 45.252000000000002 3.709043918975985 48.624000000000002 8.3446223572303353 - 54.248 -4.3103980061846903 57.62 -0.31747878544030345 62.124000000000002 - -3.0374814655308411 67.748000000000005 -1.4620754001211411 73 -1.4620754001211411; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20 0 25 0 43 -9.5783340789965923 - 45.252000000000002 0.90154868664691201 48.624000000000002 8.7718521891731456 - 54.248 -8.5131513305800102 57.62 -18.111356086769547 62.124000000000002 13.313344906312897 - 67.748000000000005 2.5900267263694494 73 2.5900267263694494; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20 1 25 1 43 1 45.252000000000002 - 1 48.624000000000002 1 54.248 1 57.62 1 62.124000000000002 1 67.748000000000005 - 1 73 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20 1 25 1 43 1 45.252000000000002 - 1 48.624000000000002 1 54.248 1 57.62 1 62.124000000000002 1 67.748000000000005 - 1 73 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20 1 25 1 43 1 45.252000000000002 - 1 48.624000000000002 1 54.248 1 57.62 1 62.124000000000002 1 67.748000000000005 - 1 73 1; -createNode animCurveTU -n "IMP_Lwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 1 50 1 52 1 57 1 65 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Lwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 -108.31450682874039 50 -125.40834581998934 - 52 -100.20629798750925 57 -35.554748650199208 65 -39.250823904258596; -createNode animCurveTA -n "IMP_Lwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 68.065884696811835 50 56.047978936552163 - 52 24.444877027867999 57 72.366791430336889 65 60.183219200862425; -createNode animCurveTA -n "IMP_Lwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 51.239332246486676 50 -18.825791986767733 - 52 19.174023814476598 57 61.828020255316602 65 85.86021449300155; -createNode animCurveTU -n "IMP_Lwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.52893863520222695 50 0.52893863520222695 - 52 0.52893863520222695 57 0.52893863520222695 65 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.52893863520222695 50 0.52893863520222695 - 52 0.52893863520222695 57 0.52893863520222695 65 0.52893863520222695; -createNode animCurveTU -n "IMP_Lwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.52893863520222695 50 0.52893863520222695 - 52 0.52893863520222695 57 0.52893863520222695 65 0.52893863520222695; -createNode animCurveTU -n "IMP_Rwing_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 1 50 1 52 1 57 1 65 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTA -n "IMP_Rwing_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 -0.46348847946685173 50 -6.356486350804305 - 52 19.495321195258477 57 -37.577277765676968 65 -73.759134093643908; -createNode animCurveTA -n "IMP_Rwing_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 46.723472751832027 50 49.884388382294254 - 52 22.579042552072995 57 55.196507514702134 65 84.132592640798364; -createNode animCurveTA -n "IMP_Rwing_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 -2.8441284444406012 50 -46.078868840472666 - 52 -17.345933364724733 57 -79.39576248030248 65 -95.161871200032508; -createNode animCurveTU -n "IMP_Rwing_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.5814880999021691 50 0.5814880999021691 - 52 0.5814880999021691 57 0.5814880999021691 65 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.5814880999021691 50 0.5814880999021691 - 52 0.5814880999021691 57 0.5814880999021691 65 0.5814880999021691; -createNode animCurveTU -n "IMP_Rwing_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 45 0.5814880999021691 50 0.5814880999021691 - 52 0.5814880999021691 57 0.5814880999021691 65 0.5814880999021691; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 43 0 73 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 43 0 73 0; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -125.22193586838614; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 8.6146645406138322; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -81.606402433660108; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -89.263548368337112; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 5.567698967347587; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -104.19557958825375; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.36693656610454845; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 12.728045273286213; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.12017666558909808; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.724592717525262; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.21268105951286304; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 143.97979303987; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -25.119237776405349; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -10.758168812157226; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -1.0348054309679442; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.14210444943862929; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -1.7055744033867848; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -0.47885438515883816; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 -1.8523907672871756; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0.58253491147274805; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 73 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 1 47 1 51 1 53 1 57 1 60 1 68 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 0 47 0 51 0 53 0 57 0 60 0 68 - 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 -5.1202596191148562 47 -21.140850850527002 - 51 7.4771283577220622 53 18.842163162911888 57 14.734319257421593 60 -20.73006645997798 - 68 -6.3526127907619419; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 0 47 0 51 0 53 0 57 0 60 0 68 - 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 0 47 0 51 0 53 0 57 0 60 0 68 - 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 0 47 0 51 0 53 0 57 0 60 0 68 - 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 1 47 1 51 1 53 1 57 1 60 1 68 - 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 1 47 1 51 1 53 1 57 1 60 1 68 - 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 43 1 47 1 51 1 53 1 57 1 60 1 68 - 1; -select -ne :time1; - setAttr ".o" 59; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_origin; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Rwing_scaleX.o" "IMP_Rwing.sx"; -connectAttr "IMP_Rwing_scaleY.o" "IMP_Rwing.sy"; -connectAttr "IMP_Rwing_scaleZ.o" "IMP_Rwing.sz"; -connectAttr "IMP_Rwing_rotateX.o" "IMP_Rwing.rx"; -connectAttr "IMP_Rwing_rotateY.o" "IMP_Rwing.ry"; -connectAttr "IMP_Rwing_rotateZ.o" "IMP_Rwing.rz"; -connectAttr "IMP_Rwing_visibility.o" "IMP_Rwing.v"; -connectAttr "IMP_Lwing_scaleX.o" "IMP_Lwing.sx"; -connectAttr "IMP_Lwing_scaleY.o" "IMP_Lwing.sy"; -connectAttr "IMP_Lwing_scaleZ.o" "IMP_Lwing.sz"; -connectAttr "IMP_Lwing_rotateX.o" "IMP_Lwing.rx"; -connectAttr "IMP_Lwing_rotateY.o" "IMP_Lwing.ry"; -connectAttr "IMP_Lwing_rotateZ.o" "IMP_Lwing.rz"; -connectAttr "IMP_Lwing_visibility.o" "IMP_Lwing.v"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of slash1.ma diff --git a/base/models/monsters/imp/animation/cycles/slash2.ma b/base/models/monsters/imp/animation/cycles/slash2.ma deleted file mode 100644 index 654c6ac18..000000000 --- a/base/models/monsters/imp/animation/cycles/slash2.ma +++ /dev/null @@ -1,4433 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:25 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: slash2.ma -//Last modified: Tue, Jul 22, 2003 12:34:09 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 228.97377156190407 60.364557133650791 7.8549598240775538 ; - setAttr ".r" -type "double3" -4.5301089136283705 -268.20000000000539 2.5444437451708134e-014 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 175.82066999681791; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 5.758650619198864 44.3419131647142 -24.563915055871874 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 53.300142247510678; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 10.842253533442108 34.595016027307409 108.25600799593728 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 204.94988123890698; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 121.67533444799157 47.777980291697517 1.3773433912893087 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 181.09986171053757; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436975629 31.127794189756983 -8.0656466123174173 ; - setAttr ".sp" -type "double3" -0.44516282436975629 31.127794189756983 -8.0656466123174173 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 10 1 17 1 32 1 40 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.31943623179458119 10 -0.31943623179458119 - 17 -0.31943623179458119 32 -0.31943623179458119 40 -0.31943623179458119; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.60601403926667285 10 0.60601403926667285 - 17 0.60601403926667285 32 0.60601403926667285 40 0.60601403926667285; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.43535834755878011 10 -0.43535834755878011 - 17 -0.43535834755878011 32 -0.43535834755878011 40 -0.43535834755878011; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 33.628828049261436 10 33.628828049261436 - 17 33.628828049261436 32 33.628828049261436 40 103.84684319416141; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 52.823401811224393 10 52.823401811224393 - 17 52.823401811224393 32 52.823401811224393 40 -20.433460272357888; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -69.00481615483352 10 -69.00481615483352 - 17 -69.00481615483352 32 -69.00481615483352 40 -54.409165660469903; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.0000000000000007 10 1.0000000000000007 - 17 1.0000000000000007 32 1.0000000000000007 40 1.0000000000000007; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.0000000000000004 10 1.0000000000000004 - 17 1.0000000000000004 32 1.0000000000000004 40 1.0000000000000004; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.0000000000000002 10 1.0000000000000002 - 17 1.0000000000000002 32 1.0000000000000002 40 1.0000000000000002; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 10 1 17 1 40 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.12017702136323123 10 -0.12017702136323123 - 17 -0.12017702136323123 40 -0.12017702136323123; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.51178706078341452 10 -0.51178706078341452 - 17 -0.51178706078341452 40 -0.51178706078341452; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.31207209631066596 10 -0.31207209631066596 - 17 -0.31207209631066596 40 -0.31207209631066596; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 77.218311557265167 10 77.218311557265167 - 17 77.218311557265167 40 77.218311557265167; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -18.864800645565317 10 -18.864800645565317 - 17 -18.864800645565317 40 -18.864800645565317; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 42.706035682079857 10 42.706035682079857 - 17 42.706035682079857 40 42.706035682079857; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 10 0.99999999999999989 - 17 0.99999999999999989 40 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 10 0.99999999999999989 - 17 0.99999999999999989 40 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 10 1 17 1 40 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.4264261331675518 7.3600000000000003 - 4.4264261331675518 12.300000000000001 4.4264261331675518 32 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.3937238431314825 7.3600000000000003 - 4.3937238431314825 12.300000000000001 4.3937238431314825 32 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 7.7712681071056613 7.3600000000000003 - 7.7712681071056613 12.300000000000001 7.7712681071056613 32 7.7712681071056613; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -4.0846345617354372 7.3600000000000003 - -4.0846345617354372 12.300000000000001 -4.0846345617354372 32 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.282468147773308 7.3600000000000003 - 4.282468147773308 12.300000000000001 4.282468147773308 32 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 7.7712681071056613 7.3600000000000003 - 7.7712681071056613 12.300000000000001 7.7712681071056613 32 7.7712681071056613; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -12.890500000000031 6.968 -12.890500000000031 - 10.4 -12.890500000000031 28 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.6900999999992341 6.968 -0.6900999999992341 - 10.4 -0.6900999999992341 28 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 4.6456900000000347 6.968 4.6456900000000347 - 10.4 4.6456900000000347 28 4.6456900000000347; -createNode animCurveTA -n "IMP_Rhand_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 26.60888886703863 10 26.60888886703863 - 17 26.60888886703863 40 26.60888886703863; -createNode animCurveTA -n "IMP_Rhand_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 7.1090718009889402 10 7.1090718009889402 - 17 7.1090718009889402 40 7.1090718009889402; -createNode animCurveTA -n "IMP_Rhand_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.5476660078217872 10 3.5476660078217872 - 17 3.5476660078217872 40 3.5476660078217872; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 13.2 1 16.4 - 1 28 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.41287000000041 6.968 -12.41287000000041 - 10.4 -12.41287000000041 13.2 -12.41287000000041 16.4 -12.41287000000041 28 - -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7285999999993047 6.968 -6.7285999999993047 - 10.4 -6.7285999999993047 13.2 -6.7285999999993047 16.4 -6.7285999999993047 - 28 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8687599999999316 6.968 -3.8687599999999316 - 10.4 -3.8687599999999316 13.2 -3.8687599999999316 16.4 -3.8687599999999316 - 28 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 73.32840695755776 6.968 34.597832706806976 - 10.4 49.717832706807599 13.2 54.749268050199987 16.4 -3.0260567526605002 - 28 73.32840695755776; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 6.968 0 10.4 0 13.2 0 16.4 - 0 28 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 6.968 0 10.4 0 13.2 0 16.4 - 0 28 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 13.2 1 16.4 - 1 28 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 13.2 1 16.4 - 1 28 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 13.2 1 16.4 - 1 28 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 16.4 1 24 1 - 28 1 36 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -4.8931631916702223 6.968 -4.8931631916702223 - 10.4 -4.8931631916702223 16.4 -4.8931631916702223 24 -4.8931631916702223 - 28 -4.8931631916702223 36 -4.8931631916702223; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.119200000000268 6.968 2.119200000000268 - 10.4 2.119200000000268 16.4 2.119200000000268 24 2.119200000000268 28 2.119200000000268 - 36 2.119200000000268; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821100000000272 6.968 -3.0821100000000272 - 10.4 -3.0821100000000272 16.4 -3.0821100000000272 24 -3.0821100000000272 - 28 -3.0821100000000272 36 -3.0821100000000272; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 14.709655602780709 6.968 19.435029411446887 - 10.4 40.405905828411754 16.4 19.588884619228285 24 15.046396594134714 28 - 14.709655602780709 36 29.181954712100737; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -53.959949192035893 6.968 -21.074072265198154 - 10.4 -27.150983342120917 16.4 -40.471016572223292 24 -47.791482010053024 - 28 -53.959949192035893 36 -29.468655703669128; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 10.476954754024579 6.968 -40.018715255462382 - 10.4 -45.097957402963324 16.4 -27.633995633756868 24 49.208418543606989 28 - 10.476954754024579 36 -6.5709795590899356; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 16.4 1 24 1 - 28 1 36 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 16.4 1 24 1 - 28 1 36 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 16.4 1 24 1 - 28 1 36 1; - setAttr -s 7 ".kit[1:6]" 3 3 9 9 3 9; - setAttr -s 7 ".kot[1:6]" 3 3 9 9 3 9; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 12.4 1 28 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.890532588149956 6.968 12.890532588149956 - 10.4 12.890532588149956 12.4 12.890532588149956 28 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.69008032694306476 6.968 -0.69008032694306476 - 10.4 -0.69008032694306476 12.4 -0.69008032694306476 28 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 4.645694319339265 6.968 4.645694319339265 - 10.4 4.645694319339265 12.4 4.645694319339265 28 4.645694319339265; -createNode animCurveTA -n "IMP_Lhand_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 10 -30.993200126312015 17 -30.993200126312015 - 21 5.7467659029787752 40 0; -createNode animCurveTA -n "IMP_Lhand_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 10 -1.5902773407317584e-015 - 17 -1.5902773407317584e-015 21 -19.153911384585331 40 0; -createNode animCurveTA -n "IMP_Lhand_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 10 -59.784597119733576 17 -59.784597119733576 - 21 -95.109914296460943 40 0; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 12.4 1 28 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 12.4 1 28 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 12.4 1 28 1; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 23 1 28 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.412879749935719 6.968 12.412879749935719 - 10.4 12.412879749935719 12.4 12.412879749935719 16.4 12.412879749935719 23 - 12.412879749935719 28 12.412879749935719; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7286993982861674 6.968 -6.7286993982861674 - 10.4 -6.7286993982861674 12.4 -6.7286993982861674 16.4 -6.7286993982861674 - 23 -6.7286993982861674 28 -6.7286993982861674; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.868763862603668 6.968 -3.868763862603668 - 10.4 -3.868763862603668 12.4 -3.868763862603668 16.4 -3.868763862603668 23 - -3.868763862603668 28 -3.868763862603668; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 74.888959286143816 6.968 20.500449332430534 - 10.4 20.500449332430534 12.4 -6.2354813826853412 16.4 21.703310057340129 - 23 87.13417363917354 28 74.888959286143816; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 -50.563532815138402 10.4 - -50.563532815138402 12.4 0.61032398340457494 16.4 51.784180781947533 23 25.838238276050774 - 28 0; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 -16.107080368755717 10.4 - -16.107080368755717 12.4 -9.0855767893983135 16.4 -2.0640732100408887 23 - -0.23036807329765999 28 0; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 23 1 28 1; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 23 1 28 1; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 23 1 28 1; - setAttr -s 7 ".kit[4:6]" 9 9 3; - setAttr -s 7 ".kot[4:6]" 9 9 3; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 28 1 36 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 4.9784821666138681 6.968 4.9784821666138681 - 10.4 4.9784821666138681 12.4 4.9784821666138681 16.4 4.9784821666138681 28 - 4.9784821666138681 36 4.9784821666138681; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.1192573708759443 6.968 2.1192573708759443 - 10.4 2.1192573708759443 12.4 2.1192573708759443 16.4 2.1192573708759443 28 - 2.1192573708759443 36 2.1192573708759443; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -3.0821078932592161 6.968 -3.0821078932592161 - 10.4 -3.0821078932592161 12.4 -3.0821078932592161 16.4 -3.0821078932592161 - 28 -3.0821078932592161 36 -3.0821078932592161; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -8.6570982615599771e-016 6.968 - -32.966747079872121 10.4 -32.966747079872121 12.4 18.385712692895545 16.4 - 101.60854932291564 28 0 36 -0.0047669855528700913; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 23.294877190436519 6.968 23.294877190436519 - 10.4 23.294877190436519 12.4 29.800209116415594 16.4 -20.094424920343183 - 28 23.294877190436519 36 6.5276108860450481; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -22.025208130272862 6.968 -22.025208130272837 - 10.4 -22.025208130272837 12.4 4.2200958896381771 16.4 -30.815217477008382 - 28 -22.025208130272862 36 -33.75308806583417; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 28 1 36 1; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 28 1 36 1; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 28 1 36 1; - setAttr -s 7 ".kit[3:6]" 9 9 3 9; - setAttr -s 7 ".kot[3:6]" 9 9 3 9; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.74525677667777757 6.968 0.74525677667777757 - 10.4 0.74525677667777757 28 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.8072476834435935 6.968 1.8072476834435935 - 10.4 1.8072476834435935 28 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 24 1 28 1 30 1 33 1 36 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 0 10.4 0 12.4 0 16.4 - 0 24 0 28 0 30 0 33 0 36 0; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.968 2.6456615572060826 - 10.4 2.6456615572060826 12.4 2.6456615572060826 16.4 2.6456615572060826 24 - 2.6456615572060826 28 2.6456615572060826 30 2.6456615572060826 33 2.6456615572060826 - 36 2.6456615572060826; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.968 1.9935618776130362 - 10.4 1.9935618776130362 12.4 1.9935618776130362 16.4 1.9935618776130362 24 - 1.9935618776130362 28 1.9935618776130362 30 1.9935618776130362 33 1.9935618776130362 - 36 1.9935618776130362; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 3.4783155513485924 10.4 - -0.09657851034863181 12.4 1.033068756878724 16.4 -44.585914702747154 24 -51.097847798220513 - 28 -28.571053450148799 30 -51.748013488406485 33 -51.748013488406485 36 -37.365501522718546; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 -38.552795746403959 10.4 - -63.130993986213582 12.4 6.9931555689960305 16.4 23.890143984299847 24 3.5550824953832989 - 28 -15.172215763072439 30 -5.763286302391716 33 -5.763286302391716 36 -14.286023019057096; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 -11.900659750381106 10.4 - -2.8340140398937579 12.4 -11.40793439235436 16.4 -26.63984911912021 24 -7.9227599571284708 - 28 1.8026176014271429 30 7.7803125060915059 33 7.7803125060915059 36 -10.697215991693511; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 24 1 28 1 30 1 33 1 36 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 24 1 28 1 30 1 33 1 36 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 16.4 - 1 24 1 28 1 30 1 33 1 36 1; - setAttr -s 10 ".kit[0:9]" 3 9 9 9 9 9 9 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 3 9 9 9 9 9 9 - 9 9 9; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.7384771804188404 6.968 5.7384771804188404 - 10.4 5.7384771804188404 28 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.0494561358638701 6.968 2.0494561358638701 - 10.4 2.0494561358638701 28 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.5258192723085173 7.3600000000000003 - 5.5258192723085173 12.300000000000001 5.5258192723085173 32 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.1525507362789047 7.3600000000000003 - 1.1525507362789047 12.300000000000001 1.1525507362789047 32 1.1525507362789047; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 7.3600000000000003 0 12.300000000000001 - 0 32 0; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 20 1 - 28 1 36 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 0 10.4 0 13.2 0 20 0 - 28 0 36 0; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 5.6268319407172029 6.968 5.6268319407172029 - 10.4 5.6268319407172029 13.2 5.6268319407172029 20 5.6268319407172029 28 - 5.6268319407172029 36 5.6268319407172029; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1098668596606802 6.968 -2.1098668596606802 - 10.4 -2.1098668596606802 13.2 -2.1098668596606802 20 -2.1098668596606802 - 28 -2.1098668596606802 36 -2.1098668596606802; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 8.7058290712119923 10.4 - 4.5570158122354343 13.2 3.7584004604861434 20 5.9983976851997722 28 12.355203408163504 - 36 0; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 21.349850139386163 10.4 - 22.54725636188541 13.2 11.195317644779903 20 -7.9858282541455097 28 3.6849709854449091 - 36 0; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 -6.247674972399917 10.4 - -17.317154383170024 13.2 -25.757356403827732 20 6.7008824959581244 28 8.5442072715208415 - 36 0; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 20 1 - 28 1 36 1; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 20 1 - 28 1 36 1; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 20 1 - 28 1 36 1; - setAttr -s 7 ".kit[5:6]" 9 9; - setAttr -s 7 ".kot[5:6]" 9 9; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 16.4 1 28 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 6.968 0 10.4 0 16.4 0 28 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.3128351505039433 6.968 2.3128351505039433 - 10.4 2.3128351505039433 16.4 2.3128351505039433 28 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.23421866920666501 6.968 0.23421866920666501 - 10.4 0.23421866920666501 16.4 0.23421866920666501 28 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 5.5476722744402966 6.968 -0.17851958634135134 - 10.4 -1.968358597995892 16.4 15.898091796486007 28 5.5476722744402966; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 11.465170879460629 6.968 23.161410246680422 - 10.4 37.934458931289207 16.4 -14.119253355428109 28 11.465170879460629; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -5.7185964271191132 6.968 -7.5745938262471633 - 10.4 -11.059550023072394 16.4 28.752527450728124 28 -5.7185964271191132; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 16.4 1 28 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 16.4 1 28 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 6.968 1 10.4 1 16.4 1 28 1; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 14.800000000000001 - 1 19 1 25 1 28 1 32 1 36 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -2.6206888697473545 6.968 1.3908718849421143e-015 - 10.4 2.1477369068511565 12.4 -1.7935361464042296 14.800000000000001 -5.7172466500043271 - 19 0.95268298045776134 25 5.5177929186133117 28 2.2652878781431178e-015 32 - -0.28810669734665539 36 0.45826711591896391; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 44.007715033770502 6.968 45.305058519974509 - 10.4 42.179301268385053 12.4 42.070247228192649 14.800000000000001 46.148288172132446 - 19 42.537100941010962 25 43.244519967104992 28 42.488935944704316 32 40.91215203210097 - 36 41.370050872954565; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -2.679538405939565 6.968 3.5843916968058402 - 10.4 8.5978967691362165 12.4 13.040647611085967 14.800000000000001 15.910398537475354 - 19 26.956709793743542 25 33.204379170400401 28 36.891441800569851 32 40.339224448272503 - 36 45.130271158403126; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 -15.119999999999992 10.4 - -11.79650298766801 12.4 -8.7728794576676421 14.800000000000001 -1.8690363012711531 - 19 23.941792697709818 25 23.207500217070315 28 16.044077218497289 32 15.392856981716136 - 36 16.044077218497289; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -8.9912346900355296 6.968 5.6443297391071869 - 10.4 10.473225336876247 12.4 -1.8647795907738096 14.800000000000001 -17.284686628926693 - 19 -19.183372998525648 25 -8.3297171283498308 28 0 32 0.75724699772684312 - 36 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.968 -9.9876575159825064e-017 - 10.4 0.93596470501479778 12.4 1.0334955076068046 14.800000000000001 0.99817389296100234 - 19 0.95448957681403712 25 0.40498060464586744 28 0 32 -0.036816417959496348 - 36 0; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 14.800000000000001 - 1 19 1 25 1 28 1 32 1 36 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 14.800000000000001 - 1 19 1 25 1 28 1 32 1 36 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.968 1 10.4 1 12.4 1 14.800000000000001 - 1 19 1 25 1 28 1 32 1 36 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 14.800000000000001 - 1 17 1 18 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 6.083551512064922 6.968 6.083551512064922 - 10.4 6.083551512064922 13.2 6.083551512064922 14.800000000000001 6.083551512064922 - 17 6.0835515120649246 18 6.0835515120649246; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1.6648666211645171 6.968 1.6648666211645171 - 10.4 1.6648666211645171 13.2 1.6648666211645171 14.800000000000001 4.7834938486193472 - 17 0 18 0; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -8.2514949399869195 6.968 -8.2514949399869195 - 10.4 -8.2514949399869195 13.2 -8.2514949399869195 14.800000000000001 5.2992006552022177 - 17 30.621659161798782 18 31.714725195072955; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 0 10.4 0 13.2 0 14.800000000000001 - -11.569056279105665 17 0 18 0; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 18.296137987022 6.968 18.296137987022 - 10.4 18.296137987022 13.2 18.296137987022 14.800000000000001 18.296137987021996 - 17 18.296137987022 18 18.296137987022; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 6.968 0 10.4 0 13.2 0 14.800000000000001 - 0 17 0 18 0; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 14.800000000000001 - 1 17 1 18 1; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 14.800000000000001 - 1 17 1 18 1; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 6.968 1 10.4 1 13.2 1 14.800000000000001 - 1 17 1 18 1; - setAttr -s 7 ".kit[4:6]" 9 9 9; - setAttr -s 7 ".kot[4:6]" 9 9 9; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 13 1 16 1 21 1 32 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 6.7758528420198658 7.3600000000000003 - 6.7758528420198658 12.300000000000001 6.7758528420198658 13 6.7758528420198658 - 16 6.7758528420198658 21 6.7758528420198658 32 6.7758528420198658; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.9388939039072284e-018 7.3600000000000003 - -6.9388939039072284e-018 12.300000000000001 -6.9388939039072284e-018 13 -6.9132335015507743e-018 - 16 -6.4506042294685753e-018 21 -6.9132335015507743e-018 32 0; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -9.5120444723942321e-016 7.3600000000000003 - -9.5120444723942321e-016 12.300000000000001 -9.5120444723942321e-016 13 -9.4768684210272156e-016 - 16 -8.8426822998358626e-016 21 -9.4768684210272156e-016 32 0; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -2.1064832569487142 7.3600000000000003 - -2.1064832569487142 12.300000000000001 -2.1064832569487142 13 -2.1064832569487142 - 16 -36.315314818526481 21 -2.1064832569487142 32 -2.1064832569487142; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.36693656610454173 7.3600000000000003 - 0.36693656610454173 12.300000000000001 0.36693656610454173 13 0.36693656610454173 - 16 0.3669365661045409 21 0.36693656610454173 32 0.36693656610454173; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 12.728045273286209 7.3600000000000003 - 12.728045273286209 12.300000000000001 12.728045273286209 13 12.728045273286209 - 16 12.728045273286206 21 12.728045273286209 32 12.728045273286209; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 13 1 16 1 21 1 32 1; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 13 1 16 1 21 1 32 1; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 13 1 16 1 21 1 32 1; - setAttr -s 7 ".kit[3:6]" 9 9 9 3; - setAttr -s 7 ".kot[3:6]" 9 9 9 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 21 1 24 1 27 - 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -11.731277878283857 6.968 -11.731277878283857 - 10.4 -11.731277878283857 21 -11.731277878283857 24 -11.731277878283857 27 - -11.731277878283857; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.77211996138749939 6.968 5.5295316614501413 - 10.4 0.77211996138749939 21 0.77211996138749939 24 4.6403342456233601 27 - 0; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -4.579364761070849 6.968 14.042503893460001 - 10.4 16.489172767777923 21 16.489172767777923 24 18.807890752035945 27 38.586992718020369; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 6.968 -17.989322872624751 10.4 - 0 21 0 24 -15.734844212043885 27 0; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -8.1254375044848945 6.968 -8.1254375044848963 - 10.4 -8.1254375044848945 21 -8.1254375044848945 24 -8.1254375044849017 27 - -8.1254375044848945; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 6.968 4.0160100588154484e-016 - 10.4 0 21 0 24 0 27 0; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 21 1 24 1 27 - 1; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 21 1 24 1 27 - 1; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 6.968 1 10.4 1 21 1 24 1 27 - 1; - setAttr -s 6 ".kit[2:5]" 3 3 9 9; - setAttr -s 6 ".kot[2:5]" 3 3 9 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.7758528420198658 7.3600000000000003 - 6.7758528420198658 12.300000000000001 6.7758528420198658 32 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9388939039072284e-018 7.3600000000000003 - -6.9388939039072284e-018 12.300000000000001 -6.9388939039072284e-018 32 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -9.5120444723942321e-016 7.3600000000000003 - -9.5120444723942321e-016 12.300000000000001 -9.5120444723942321e-016 32 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -12.784757077400341 7.3600000000000003 - -12.784757077400341 12.300000000000001 -12.784757077400341 32 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.2695897469829736 7.3600000000000003 - 3.2695897469829736 12.300000000000001 3.2695897469829736 32 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9162979482121409 7.3600000000000003 - -6.9162979482121409 12.300000000000001 -6.9162979482121409 32 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 7.3600000000000003 1 12.300000000000001 - 1 32 1; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -125.22193586838614 6.968 -125.22193586838614 - 10.4 -125.22193586838614 28 -125.22193586838614; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 8.6146645406138322 6.968 8.6146645406138322 - 10.4 8.6146645406138322 28 8.6146645406138322; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -81.606402433660108 6.968 -81.606402433660108 - 10.4 -81.606402433660108 28 -81.606402433660108; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -89.263548368337112 6.968 -89.263548368337112 - 10.4 -89.263548368337112 28 -89.263548368337112; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.567698967347587 6.968 5.567698967347587 - 10.4 5.567698967347587 28 5.567698967347587; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -104.19557958825375 6.968 -104.19557958825375 - 10.4 -104.19557958825375 28 -104.19557958825375; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 6.968 1 10.4 1 28 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 6.968 0 10.4 0 28 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + " global int $gUseScenePanelConfig;\n" - + " int $useSceneConfig = $gUseScenePanelConfig;\n" - + " int $menusOkayInPanels = `optionVar -q allowMenusInPanels`; int $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + " int $nPanes = 0;\n" - + " string $editorName;\n" - + " string $panelName;\n" - + " string $itemFilterName;\n" - + " string $panelConfig;\n" - + " //\n" - + " // get current state of the UI\n" - + " //\n" - + " sceneUIReplacement -update $gMainPane;\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 0\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " outlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " outlinerPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " scriptedPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " blendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " blendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " devicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " devicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " scriptedPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + " panelConfiguration -edit -label \"Current Layout\"\n" - + " -defaultImage \"\"\n" - + " -image \"\"\n" - + " -sc false\n" - + " -configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + " -removeAllPanels\n" - + " -ap false\n" - + " \"Persp View\"\n" - + " \"modelPanel\"\n" - + " \"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 0\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " \"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 0\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " $configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + " }\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 6 -max 36 -ast 6 -aet 36 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.988 1 12.4 1 21 1 28 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -29.775800000000025 9.988 -29.775800000000025 - 12.4 -13.159705804145567 21 -13.159705804145567 28 -29.775800000000025; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 57.582500000000032 9.988 57.582500000000032 - 12.4 40.167811531488169 21 40.167811531488169 28 57.582500000000032; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -1.0893083480314791 9.988 -1.0893083480314791 - 12.4 15.143696204840495 21 15.143696204840495 28 -1.0893083480314791; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 104.76465739670967 9.988 193.92671198730929 - 12.4 167.97249473098717 21 56.489825828690655 28 104.76465739670967; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 56.880694911469462 9.988 11.428870651412508 - 12.4 15.122080985276625 21 9.8835849999533281 28 56.880694911469462; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 95.287512315538279 9.988 67.921463743814442 - 12.4 103.87385318318574 21 7.4094588932786554 28 95.287512315538279; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.988 1 12.4 1 21 1 28 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0.99999999999999978 9.988 0.99999999999999978 - 12.4 0.99999999999999978 21 0.99999999999999978 28 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.988 1 12.4 1 21 1 28 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4.532 1 8.48 1 11.6 1 14.800000000000001 - 1 28 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 29.775846152470962 4.532 19.641833440724263 - 8.48 -13.50242416118467 11.6 -13.50242416118467 14.800000000000001 -13.50242416118467 - 28 29.775846152470962; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 57.582470209590937 4.532 53.408043014847813 - 8.48 40.557019117514919 11.6 40.557019117514919 14.800000000000001 40.557019117514919 - 28 57.582470209590937; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -1.0893063224582775 4.532 -22.372279664530687 - 8.48 -2.5791135942523837 11.6 -2.5791135942523837 14.800000000000001 -2.5791135942523837 - 28 -1.0893063224582775; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 276.71789855035888 4.532 216.46441003843643 - 8.48 162.16734368429755 11.6 177.27415043926092 14.800000000000001 437.81823293323293 - 28 276.71789855035888; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 25.240608455912373 4.532 2.0558586998137796 - 8.48 -52.394829970363901 11.6 -61.835079378573042 14.800000000000001 -32.209318057570023 - 28 25.240608455912373; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 249.54962172920807 4.532 216.29233490133382 - 8.48 249.79162523117506 11.6 259.40824966368405 14.800000000000001 239.93745274205872 - 28 249.54962172920807; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 4.532 1 8.48 1 11.6 1 14.800000000000001 - 1 28 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.99999999999999989 4.532 0.99999999999999989 - 8.48 0.99999999999999989 11.6 0.99999999999999989 14.800000000000001 0.99999999999999989 - 28 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.99999999999999978 4.532 0.99999999999999978 - 8.48 0.99999999999999978 11.6 0.99999999999999978 14.800000000000001 0.99999999999999978 - 28 0.99999999999999978; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 5 1 6 1 10.232 1 12.4 1 13 - 1 14 1 16.4 1 21 1 25 1 28 1 33 1 36 1 40 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -2.5294371750177831 5 -2.5294371750177831 - 6 -2.5294371750177831 10.232 -2.5294371750177831 12.4 -2.5294371750177831 - 13 -2.5294371750177831 14 -2.5294371750177831 16.4 -2.5294371750177831 21 - -2.5294371750177831 25 -2.5294371750177831 28 -2.5294371750177831 33 -2.5294371750177831 - 36 -2.5294371750177831 40 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 13.481673551673362 5 13.481673551673362 - 6 13.481673551673362 10.232 13.481673551673362 12.4 13.481673551673362 13 - 13.481673551673362 14 13.481673551673362 16.4 13.481673551673362 21 13.481673551673362 - 25 13.481673551673362 28 13.481673551673362 33 13.481673551673362 36 13.481673551673362 - 40 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -0.26635088939205875 5 -0.26635088939205875 - 6 -0.26635088939205875 10.232 -0.26635088939205875 12.4 -0.26635088939205875 - 13 -0.26635088939205875 14 -0.26635088939205875 16.4 -0.26635088939205875 - 21 -0.26635088939205875 25 -0.26635088939205875 28 -0.26635088939205875 33 - -0.26635088939205875 36 -0.26635088939205875 40 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 7.4223676734694886 5 2.9431688913662311 - 6 -3.0714962490500808 10.232 2.9431688913662311 12.4 299.68980514861676 13 - 299.97392629960956 14 141.36322225774362 16.4 100.21931209117341 21 172.14601233752015 - 25 226.58634761534177 28 210.54698169130378 33 225.20384384561464 36 236.74867287849949 - 40 7.4223676734694886; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 103.24416525675046 5 85.6231564446052 - 6 85.659346261699994 10.232 85.6231564446052 12.4 55.37295920058218 13 19.644615297719866 - 14 157.64946105309642 16.4 164.9907128973193 21 131.94711404097504 25 124.02478663490713 - 28 102.21010213877064 33 111.98519188858759 36 106.76563159357174 40 103.24416525675046; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 78.336848898683712 5 83.46561831337894 - 6 77.399799945525629 10.232 83.46561831337894 12.4 396.39222267810015 13 - 377.36324792059759 14 193.18756356151806 16.4 183.29603434273693 21 213.4712785746606 - 25 274.41402626855489 28 264.66869183720922 33 320.17581880657843 36 321.29711043141424 - 40 78.336848898683712; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 15.445123296459185 5 15.445123296459185 - 6 15.445123296459185 10.232 15.445123296459185 12.4 15.445123296459185 13 - 15.445123296459185 14 15.445123296459185 16.4 15.445123296459185 21 15.445123296459185 - 25 15.445123296459185 28 15.445123296459185 33 15.445123296459185 36 15.445123296459185 - 40 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 15.445123296459185 5 15.445123296459185 - 6 15.445123296459185 10.232 15.445123296459185 12.4 15.445123296459185 13 - 15.445123296459185 14 15.445123296459185 16.4 15.445123296459185 21 15.445123296459185 - 25 15.445123296459185 28 15.445123296459185 33 15.445123296459185 36 15.445123296459185 - 40 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 15.445123296459185 5 15.445123296459185 - 6 15.445123296459185 10.232 15.445123296459185 12.4 15.445123296459185 13 - 15.445123296459185 14 15.445123296459185 16.4 15.445123296459185 21 15.445123296459185 - 25 15.445123296459185 28 15.445123296459185 33 15.445123296459185 36 15.445123296459185 - 40 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 5 0 6 0 10.232 0 12.4 0 13 - 0 14 0 16.4 0 21 0 25 0 28 0 33 0 36 0 40 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.5 5 0 6 0.76446448318353066 - 10.232 0.60000000000000009 12.4 0 13 -0.037320856001842505 14 0 16.4 0.0048349551823460403 - 21 0 25 0 28 0 33 0 36 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 5 0 6 0 10.232 0 12.4 0 13 - 0 14 0 16.4 0 21 0 25 0 28 0 33 0 36 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 5 1 6 1.0917615365713258 10.232 - 1 12.4 0 13 0.31640625 14 1 16.4 0.73612029931688228 21 0 25 0 28 0 33 0 - 36 0; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 10 0 17 0 32 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 6 0 10.232 0 12.4 0 13 0 14 0 16.4 - 0 21 0 25 0 28 0 33 0 36 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 6 0 10.232 0 12.4 0 13 0 14 0 16.4 - 0 21 0 25 0 28 0 33 0 36 0; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 1 13 1 16 1 20 1 28 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 13 0 16 0 20 0 28 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 -1.4190578225642019 13 -9.0977864665204677 - 16 15.828548054629838 20 8.1498194106735848 28 -0.11958066743315321; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 13 0 16 0 20 0 28 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 13 0 16 0 20 0 28 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 13 0 16 0 20 0 28 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 1 13 1 16 1 20 1 28 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 1 13 1 16 1 20 1 28 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 1 13 1 16 1 20 1 28 1; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 77.739160914831501 11 72.951145409272186 - 19 77.739160914831501 27 162.70249689785155 36 297.46227283960366; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 -76.726154744596627 11 -77.804739155309207 - 19 -76.726154744596627 27 -57.586674133646142 36 -67.066559724648442; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 -173.86213662459591 11 -170.23969963746543 - 19 -173.86213662459591 27 -238.14227840098636 36 -404.242826789106; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 1 11 1 19 1 27 1 36 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 -7.5406347832540632e-013 11 -7.5406347832540632e-013 - 19 -7.5406347832540632e-013 27 -7.5406347832540632e-013 36 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 13.71946295727715 11 13.71946295727715 - 19 13.71946295727715 27 13.71946295727715 36 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 -3.0908609005564358e-013 11 -3.0908609005564358e-013 - 19 -3.0908609005564358e-013 27 -3.0908609005564358e-013 36 -3.0908609005564358e-013; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 15.445123296459183 11 15.445123296459183 - 19 15.445123296459183 27 15.445123296459183 36 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 15.445123296459185 11 15.445123296459185 - 19 15.445123296459185 27 15.445123296459185 36 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 15.445123296459181 11 15.445123296459181 - 19 15.445123296459181 27 15.445123296459181 36 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0 19 0 27 0 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0.40000000000000002 19 0 - 27 0.5 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0 19 0 27 0 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0 19 0 27 0 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0 19 0 27 0 36 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 6 0 11 0 19 0 27 0 36 0; -select -ne :time1; - setAttr ".o" 36; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_LHAND_ROT; -select -ne IMP_RHAND_ROT; - setAttr -k on ".Fist"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049349098 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Lhand_orientConstraint1; - setAttr -k on ".nds" 0; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_Rhand_IK; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_file1; - setAttr ".ftn" -type "string" "W:/doom/base/models//monsters/imp/imp.tga"; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of slash2.ma diff --git a/base/models/monsters/imp/animation/cycles/slash3.ma b/base/models/monsters/imp/animation/cycles/slash3.ma deleted file mode 100644 index 97e0bebcf..000000000 --- a/base/models/monsters/imp/animation/cycles/slash3.ma +++ /dev/null @@ -1,4473 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:26 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: slash3.ma -//Last modified: Tue, Jul 22, 2003 12:36:54 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 492.57535669305162 30.698353598470256 -23.793243498386687 ; - setAttr ".r" -type "double3" 2.6698910856298439 -981.39999999992119 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 194.48592325204564; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 296.11268615722656 33.778549432754517 -6.2571811676025391 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 119.53135691131881; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 233.74687850632583 21.242200781938198 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 324.54022351279605; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 606.35967183241121 21.242200781938209 -7.2241166391904779 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 614.46483864905258; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 45 1 57 1 62 1 70 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 45 1 57 1 62 1 70 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 45 1 57 1 62 1 70 1; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -38.367703938541368 20.18 -38.367703938541368 - 25 -38.367703938541368 36 -38.367703938541368 37 -38.367703938541368 38 -38.367703938541418 - 42 -38.367703938541425 45 -38.36770393854141 57 -38.36770393854141 62 -38.36770393854141 - 70 -38.36770393854141; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20.18 0 25 0 36 0 37 0 38 - -106.5776725621525 42 -65.464724689752856 45 -4.5087060753243948 57 -4.5087060753243948 - 62 -4.5087060753243948 70 -4.5087060753243948; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20.18 0 25 0 36 0 37 0 38 - -4.056605094900921e-015 42 0 45 -2.5353781843130746e-016 57 0 62 0 70 -2.5353781843130746e-016; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -8.52286618097577 20.18 -8.52286618097577 - 25 -8.5228661809757682 36 -8.5228661809757682 37 -8.5228661809757682 38 -8.5228661809757682 - 42 -8.5228661809757469 45 -8.5228661809757362 57 -8.5228661809757362 62 -8.5228661809757309 - 70 -8.5228661809757309; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 0 20.18 0 25 0 36 0 37 0 38 - 15.856399981493698 42 26.231575278026614 45 1.1173925191969412 57 1.1173925191969412 - 62 1.1173925191969412 70 1.1173925191969412; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 -4.579364761070849 20.18 -4.579364761070849 - 25 18.100304531459912 36 18.100304531459912 37 18.100304531459912 38 37.284590928822638 - 42 121.06902539893741 45 203.17308441818832 57 203.17308441818832 62 223.47963978432884 - 70 223.47963978432884; - setAttr -s 11 ".kit[4:10]" 9 9 9 3 3 3 3; - setAttr -s 11 ".kot[4:10]" 9 9 9 3 3 3 3; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 13 1 20.18 1 25 1 36 1 37 1 38 - 1 42 1 45 1 57 1 62 1 70 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 44 1 45 1 48 1 52 1 60 1 70 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 44 1 45 1 48 1 52 1 60 1 70 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 44 1 45 1 48 1 52 1 60 1 70 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 36.237070617308518 8.2 36.237070617308525 - 12.2 36.237070617308525 13 36.23707061730854 14.800000000000001 36.23707061730854 - 37 36.23707061730854 38 36.23707061730854 42 36.23707061730854 44 36.23707061730854 - 45 36.23707061730854 48 36.23707061730854 52 36.23707061730854 60 36.23707061730854 - 70 36.23707061730854; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 -16.225780481266991 12.2 - 0 13 14.439669496646856 14.800000000000001 0 37 0 38 -94.950298577729043 - 42 -61.214627600253856 44 13.631360692857506 45 1.3309014920097999 48 1.3309014920097999 - 52 1.3309014920097999 60 1.3309014920097999 70 1.3309014920097999; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 0 12.2 0 13 0 14.800000000000001 - 0 37 0 38 0 42 0 44 9.8581743090975106e-016 45 1.2322717886371888e-016 48 - 0 52 0 60 1.2322717886371888e-016 70 1.2322717886371888e-016; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 9.6873596619451892 8.2 9.6873596619451892 - 12.2 9.6873596619451892 13 9.6873596619451892 14.800000000000001 9.6873596619451892 - 37 9.6873596619451892 38 9.6873596619451909 42 9.6873596619452016 44 9.6873596619452123 - 45 9.6873596619452123 48 9.6873596619452123 52 9.6873596619452194 60 9.6873596619452194 - 70 9.6873596619452194; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 0 8.2 6.3204742269985701 12.2 - 0 13 0 14.800000000000001 0 37 0 38 15.451973974847458 42 26.633340511302404 - 44 -0.14993282020596688 45 -0.14993282020596688 48 -0.14993282020596688 52 - -0.14993282020596688 60 -0.14993282020596688 70 -0.14993282020596688; - setAttr -s 14 ".kit[1:13]" 9 3 3 3 3 3 3 - 3 3 3 3 3 3; - setAttr -s 14 ".kot[1:13]" 9 3 3 3 3 3 3 - 3 3 3 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -6.7799222993705621 8.2 5.9773130869645117 - 12.2 26.024397265491071 13 26.486563744388956 14.800000000000001 26.486563744388956 - 37 26.486563744388956 38 39.09212146071188 42 135.30388003020795 44 193.81103051165826 - 45 193.81103051165826 48 193.81103051165826 52 236.50094804274906 60 236.50094804274906 - 70 236.50094804274906; - setAttr -s 14 ".kit[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; - setAttr -s 14 ".kot[0:13]" 9 9 9 3 3 3 3 - 3 3 3 3 3 3 3; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8.2 1 12.2 1 13 1 14.800000000000001 - 1 37 1 38 1 42 1 44 1 45 1 48 1 52 1 60 1 70 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 38.695966818114123 8.2 41.501644160122275 - 12.2 39.333620759479579 13 38.993623662586046 20.18 37.069797976495074 28 - 25.985749074130414 35 20.728138454973941 40 49.406014559463785 43 46.964761181249308 - 46 20.469967794179276 50 37.300586130982779 54 27.100211381404904 58 31.715337600982302 - 61 34.894123517527945 65 37.560359659232915 72 39.183890827238983; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -2.4191866633612995 8.2 7.9108071867597083 - 12.2 13.904754235595359 13 14.373557394032371 20.18 17.766738474032827 28 - 28.168692059328908 35 30.558515068036385 40 105.8379398423222 43 157.86717777605494 - 46 203.77532889405444 50 221.79599095164204 54 227.74620955556244 58 228.8999911104568 - 61 233.62275875789607 65 240.26899557928877 72 241.1221258898961; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1.980821395062172 8.2 1.980821395062172 - 10.964 -0.39798246704975182 13 0.65147019540262718 20.18 3.4389526704134474 - 28 3.4389526704134483 35 3.4389526704134483 40 3.4389526704134648 43 3.4389526704134759 - 46 3.4389526704134852 50 -1.2817025244496318 54 3.4389526704134887 58 3.4389526704134887 - 61 7.955158822769393 65 6.9109033128671999 72 2.356874289686683; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 46 1 50 1 54 1 58 1 61 1 65 1 72 1; - setAttr -s 16 ".kot[5:15]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 46 1 50 1 54 1 58 1 61 1 65 1 72 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 46 1 50 1 54 1 58 1 61 1 65 1 72 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 8.2 1 12.2 1 13 1 20.18 1 28 - 1 35 1 40 1 43 1 46 1 50 1 54 1 58 1 61 1 65 1 72 1; - setAttr -s 16 ".kit[8:15]" 3 3 3 3 3 3 9 - 9; - setAttr -s 16 ".kot[8:15]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 70 - 1; - setAttr -s 6 ".kot[5]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 -4.1657930308134645 19.46 -1.6735805890538134 70 -1.6735805890538134; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287 19.46 0.21813466524646566 70 0.21813466524646566; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 70 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 70 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 0 12.2 0 13 0 19.46 0 70 - 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 -7.4542171015494922 19.46 0 70 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 70 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 70 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 8.2 1 12.2 1 13 1 19.46 1 70 - 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46 1 54 1 61 1 65 1 70 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46 1 54 1 61 1 65 1 70 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46 1 54 1 61 1 65 1 70 1; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 19.46 2.3128351505039433 24 2.3128351505039433 34 2.3128351505039433 - 40 2.3128351505039433 43 2.3128351505039433 46 2.3128351505039433 54 2.3128351505039433 - 61 2.3128351505039433 65 2.3128351505039433 70 2.3128351505039433; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 19.46 0.23421866920666501 24 0.23421866920666501 34 - 0.23421866920666501 40 0.23421866920666501 43 0.23421866920666501 46 0.23421866920666501 - 54 0.23421866920666501 61 0.23421866920666501 65 0.23421866920666501 70 0.23421866920666501; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 0 13 0 19.46 0 24 0 34 - 0 40 0 43 0 46 0 54 0 61 0 65 0 70 0; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581372 19.46 7.8247378664801399 24 -4.9687329344827127 34 - 28.583434985398817 40 -2.0830132220114304 43 20.253225946181054 46 8.9638927324932833 - 54 22.877076884835944 61 11.967706987968739 65 14.860798832736082 70 20.253225946181054; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 12.660431799163181 8.2 13.751352433260992 - 13 13.892774724407374 19.46 13.751352433260992 24 -8.6726939272339099 34 - 44.785835032594498 40 -44.116995890821372 43 5.0288927723012957 46 4.3119030022781359 - 54 7.7924052090692992 61 10.378568124469185 65 1.2668117475880938 70 5.0288927723012957; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 8.2 22.776694843251629 13 26.888910802325626 - 19.46 22.776694843251629 24 21.472297863750494 34 2.2079750683772614 40 31.930384700051565 - 43 20.723807121401762 46 21.261440092307385 54 13.557082065219102 61 32.173057052834672 - 65 14.956197574697519 70 20.723807121401762; - setAttr -s 13 ".kit[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; - setAttr -s 13 ".kot[0:12]" 9 9 9 9 3 9 3 - 9 3 3 3 3 3; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 8.2 1 13 1 19.46 1 24 1 34 - 1 40 1 43 1 46 1 54 1 61 1 65 1 70 1; - setAttr -s 13 ".kot[4:12]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 60 1 64 1 72 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 60 1 64 1 72 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 60 1 64 1 72 1; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857 18.74 398.33832420130017 33 398.33832420130017 38 412.87438477691256 - 41 363.74139408925856 60 360.27258127478137 64 368.82129737150024 72 363.74139408925856; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099 18.74 -14.641906192173103 33 -14.641906192173103 38 - -14.641906192173103 41 -19.235073321416994 60 -19.559353105802064 64 -28.743064617944807 - 72 -19.235073321416994; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167 18.74 -0.44667534838541073 33 -0.44667534838541073 - 38 -0.44667534838541134 41 -6.1644555251967859 60 -6.568133527595494 64 9.2606141207053074 - 72 -6.1644555251967859; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 18.74 5.6268319407172029 33 5.6268319407172029 38 9.0210664288932136 - 41 5.6268319407172029 60 5.3871973681743865 64 5.4715487377094583 72 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 18.74 -2.1098668596606802 33 -2.1098668596606802 38 - 2.1840208462615793 41 -2.1098668596606802 60 -2.4130173976637117 64 -2.3063084082866445 - 72 -2.1098668596606802; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 13 0 18.74 0 33 0 38 - -0.027812113261208363 41 0 60 0.0019635485287625926 64 0.0012723794466381602 - 72 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 13 1 18.74 1 33 1 38 - 1 41 1 60 1 64 1 72 1; - setAttr -s 10 ".kot[4:9]" 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 70 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 70 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 70 1; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 20.9 5.7384771804188404 70 5.7384771804188404; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 20.9 2.0494561358638701 70 2.0494561358638701; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 9.8000000000000007 0 13 0 20.9 - 0 70 0; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 20.9 36.348615312237058 70 36.348615312237058; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 20.9 -12.486888359019849 70 -12.486888359019849; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 20.9 -36.216831783693365 70 -36.216831783693365; - setAttr -s 5 ".kit[4]" 3; - setAttr -s 5 ".kot[4]" 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9.8000000000000007 1 13 1 20.9 - 1 70 1; - setAttr -s 5 ".kot[4]" 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44 1 46 1 48 1 49 1 53 1 56 1 59 1 65 1 72 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44 1 46 1 48 1 49 1 53 1 56 1 59 1 65 1 72 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44 1 46 1 48 1 49 1 53 1 56 1 59 1 65 1 72 1; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -16.115585356027545 20.18 -10.142543541392451 - 25 -6.9280630876017737 34 -23.972862154377175 38 -15.130983324653501 41 -30.039509523571379 - 44 -35.978590618894593 46 -40.601884828844661 48 -5.8089708010832837 49 -15.63353436857974 - 53 -10.960925940079917 56 0.75210337741853828 59 -37.62205449358985 65 -23.766035573245222 - 72 -9.345428642953399; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 2.156870399342198 20.18 17.225876454101705 25 14.944575916344146 - 34 14.349795315487798 38 18.846730556029243 41 21.222331139965377 44 11.601196461359804 - 46 12.924031190326062 48 17.38635914348577 49 48.532089804961913 53 65.103011015596081 - 56 -1.0507515021622431 59 -10.200505454394669 65 16.713082101524591 72 17.56695725730507; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -19.144863004444691 20.18 -25.389628185944296 - 25 -4.1316061606907093 34 -67.203015108794645 38 -36.152530154079884 41 -12.042151395079298 - 44 -8.8954744207769192 46 8.8934263782584324 48 7.5170623891361279 49 -19.205731255459568 - 53 -4.1858965905874879 56 -30.972839455133265 59 -26.548110055998258 65 -5.6623198000214572 - 72 -1.3917358326436629; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 20.18 2.6456615572060826 25 - 2.6456615572060826 34 2.6456615572060826 38 2.6456615572060826 41 2.6456615572060826 - 44 2.6456615572060826 46 2.6456615572060826 48 2.6456615572060826 49 2.6456615572060826 - 53 2.6456615572060826 56 2.6456615572060826 59 2.6456615572060826 65 2.6456615572060826 - 72 2.6456615572060826; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 20.18 1.9935618776130362 25 - 1.9935618776130362 34 1.9935618776130362 38 1.9935618776130362 41 1.9935618776130362 - 44 1.9935618776130362 46 1.9935618776130362 48 1.9935618776130362 49 1.9935618776130362 - 53 1.9935618776130362 56 1.9935618776130362 59 1.9935618776130362 65 1.9935618776130362 - 72 1.9935618776130362; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 0 6.6 0 11.4 0 13 0 20.18 0 25 - 0 34 0 38 0 41 0 44 0 46 0 48 0 49 0 53 0 56 0 59 0 65 0 72 0; - setAttr -s 18 ".kit[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; - setAttr -s 18 ".kot[0:17]" 9 9 9 3 9 9 9 - 9 3 3 3 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 18 ".ktv[0:17]" 1 1 6.6 1 11.4 1 13 1 20.18 1 25 - 1 34 1 38 1 41 1 44 1 46 1 48 1 49 1 53 1 56 1 59 1 65 1 72 1; - setAttr -s 18 ".kot[3:17]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46 - 1 49 1 54 1 70 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46 - 1 49 1 54 1 70 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46 - 1 49 1 54 1 70 1; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 12.412879749935719 13 12.412879749935719 - 24 12.412879749935719 33 12.412879749935719 38 12.412879749935719 43 12.412879749935719 - 46 12.412879749935719 49 12.412879749935719 54 12.412879749935719 70 12.412879749935719; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -6.7286993982861674 13 -6.7286993982861674 - 24 -6.7286993982861674 33 -6.7286993982861674 38 -6.7286993982861674 43 -6.7286993982861674 - 46 -6.7286993982861674 49 -6.7286993982861674 54 -6.7286993982861674 70 -6.7286993982861674; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.868763862603668 13 -3.868763862603668 - 24 -3.868763862603668 33 -3.868763862603668 38 -3.868763862603668 43 -3.868763862603668 - 46 -3.868763862603668 49 -3.868763862603668 54 -3.868763862603668 70 -3.868763862603668; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 80.239686562403847 13 105.11870283856432 - 24 71.173362214431492 33 62.893362214431335 38 -15.586637785568827 43 13.465241265972063 - 46 13.465241265972063 49 -5.8165249333031408 54 52.14656032181734 70 52.14656032181734; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 5.8978517871634404 13 0.21742569259672076 - 24 0 33 0 38 0 43 0 46 0 49 -13.425591566540025 54 0 70 0; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.92545182592768849 13 0.034116996666525033 - 24 0 33 0 38 0 43 0 46 0 49 23.764941955195834 54 0 70 0; - setAttr -s 10 ".kit[6:9]" 3 3 3 3; - setAttr -s 10 ".kot[6:9]" 3 3 3 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 13 1 24 1 33 1 38 1 43 1 46 - 1 49 1 54 1 70 1; - setAttr -s 10 ".kot[2:9]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 70 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 70 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 70 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 22 -12.41287000000041 35 -12.41287000000041 39 -12.41287000000041 - 43 -12.41287000000041 70 -12.41287000000041; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 22 -6.7285999999993047 35 -6.7285999999993047 39 -6.7285999999993047 - 43 -6.7285999999993047 70 -6.7285999999993047; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 22 -3.8687599999999316 35 -3.8687599999999316 39 -3.8687599999999316 - 43 -3.8687599999999316 70 -3.8687599999999316; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 58.099612817676174 10.6 82.316033184538099 - 13 81.577924579716537 22 58.537924579716176 35 104.14864772909701 39 15.22864772910598 - 43 35.198054152525124 70 35.198054152525124; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10.6 0 13 0 22 0 35 0 39 0 - 43 0 70 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 10.6 0 13 0 22 0 35 0 39 0 - 43 0 70 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 10.6 1 13 1 22 1 35 1 39 1 - 43 1 70 1; - setAttr -s 8 ".kot[3:7]" 5 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + " global int $gUseScenePanelConfig;\n" - + " int $useSceneConfig = $gUseScenePanelConfig;\n" - + " int $menusOkayInPanels = `optionVar -q allowMenusInPanels`; int $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + " int $nPanes = 0;\n" - + " string $editorName;\n" - + " string $panelName;\n" - + " string $itemFilterName;\n" - + " string $panelConfig;\n" - + " //\n" - + " // get current state of the UI\n" - + " //\n" - + " sceneUIReplacement -update $gMainPane;\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " modelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " outlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " outlinerPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " scriptedPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + " $editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.365\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + " $editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.365\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " scriptedPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " blendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " blendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " devicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " devicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " scriptedPanel -e -to $panelName;\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " $panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + " if (\"\" == $panelName) {\n" - + " if ($useSceneConfig) {\n" - + " $panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + " }\n" - + " } else {\n" - + " $label = `panel -q -label $panelName`;\n" - + " scriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + " if (!$useSceneConfig) {\n" - + " panel -e -l $label $panelName;\n" - + " }\n" - + " }\n" - + " if ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + " panelConfiguration -edit -label \"Current Layout\"\n" - + " -defaultImage \"\"\n" - + " -image \"\"\n" - + " -sc false\n" - + " -configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + " -removeAllPanels\n" - + " -ap false\n" - + " \"Persp View\"\n" - + " \"modelPanel\"\n" - + " \"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " \"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + " $configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + " }\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 52 -max 72 -ast 52 -aet 72 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 72.732401021820706 - 43 16.828197670709326 46 -18.161224690000036 50 56.479937212271295 54 37.377972102371409 - 58 25.010540855983066 61 23.643060542713936 65 21.536127911899268 72 21.220711872664051; - setAttr -s 13 ".kit[5:12]" 3 3 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 0 43 - 14.180322108739537 46 18.38177328486303 50 -21.245593852346627 54 -42.77727538577502 - 58 47.544981192946956 61 32.739362874090922 65 9.9277435383719759 72 2.5927201647250082; - setAttr -s 13 ".kit[5:12]" 3 3 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 13 0 20.18 0 28 0 35 0 40 0 43 - -5.6408198933274267 46 -4.9275669343393993 50 -31.477670460234876 54 -13.673261261011708 - 58 -16.477174933557826 61 -13.511324998039733 65 -8.9417191714637081 72 -11.827739429776924; - setAttr -s 13 ".kit[5:12]" 3 3 3 3 3 3 9 - 9; - setAttr -s 13 ".kot[5:12]" 3 3 3 3 3 3 9 - 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 1 24 1 34 1 38 1 41 1 43 1 47 - 1 49 1 50 1 52 1 55 1 57 1 60 1 65 1 67 1 72 1; - setAttr -s 16 ".kot[1:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 3.3867545965885748 24 3.3867545965885748 - 34 3.3867545965885748 38 3.3867545965885748 41 3.3867545965885748 43 3.3867545965885748 - 47 3.3867545965885748 49 3.3867545965885748 50 3.3867545965885748 52 3.3867545965885748 - 55 3.3867545965885748 57 3.3867545965885748 60 3.3867545965885748 65 3.3867545965885748 - 67 3.3867545965885748 72 3.3867545965885748; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 2.1192573708760349 24 2.1192573708760349 - 34 2.1192573708760349 38 2.1192573708760349 41 2.1192573708760349 43 2.1192573708760349 - 47 2.1192573708760349 49 2.1192573708760349 50 2.1192573708760349 52 2.1192573708760349 - 55 2.1192573708760349 57 2.1192573708760349 60 2.1192573708760349 65 2.1192573708760349 - 67 2.1192573708760349 72 2.1192573708760349; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 -3.0821078932592165 24 -3.0821078932592165 - 34 -3.0821078932592165 38 -3.0821078932592165 41 -3.0821078932592165 43 -3.0821078932592165 - 47 -3.0821078932592165 49 -3.0821078932592165 50 -3.0821078932592165 52 -3.0821078932592165 - 55 -3.0821078932592165 57 -3.0821078932592165 60 -3.0821078932592165 65 -3.0821078932592165 - 67 -3.0821078932592165 72 -3.0821078932592165; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 0 24 -22.140269864626553 34 - 14.54853681057746 38 43.948848359898776 41 62.842953086904046 43 44.473770737274208 - 47 -4.083938985942738 49 50.571853585444678 50 56.929345400996077 52 106.96251683427003 - 55 75.177900944064305 57 68.250949867080607 60 -27.887986816957284 65 17.941174035372224 - 67 14.494190474588063 72 3.5348146561750906; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 0 24 -18.13526372185737 34 -39.861201900326897 - 38 -29.47383974389729 41 15.902019027919991 43 6.8939126220827287 47 -40.800614111584515 - 49 -55.554764813756108 50 -22.542528905767821 52 -5.1242488079717159 55 13.209794194943171 - 57 4.78298502778149 60 -4.8237149575449019 65 5.3092707506055987 67 17.232993525223481 - 72 24.712628280184436; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 -6.7129388973255946 24 -20.318492745188728 - 34 -14.119904742119406 38 -50.034198784961902 41 50.14709560038655 43 67.765650379274618 - 47 63.638720242704046 49 24.819808842928108 50 24.830614146032957 52 49.569638782923263 - 55 46.815517050132868 57 46.478959441138564 60 -24.161341278461268 65 -19.195258198918136 - 67 -3.8196375149841191 72 -19.76897500372317; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 1 24 1 34 1 38 1 41 1 43 1 47 - 1 49 1 50 1 52 1 55 1 57 1 60 1 65 1 67 1 72 1; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 1 24 1 34 1 38 1 41 1 43 1 47 - 1 49 1 50 1 52 1 55 1 57 1 60 1 65 1 67 1 72 1; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 13 1 24 1 34 1 38 1 41 1 43 1 47 - 1 49 1 50 1 52 1 55 1 57 1 60 1 65 1 67 1 72 1; - setAttr -s 16 ".kit[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; - setAttr -s 16 ".kot[0:15]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 3 9 9; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46 1 49 - 1 54 1 56 1 57 1 58 1 59 1 65 1 72 1; - setAttr -s 14 ".kot[1:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.3867499999998705 19 -3.3867499999998705 - 33 -5.6477754078936684 38 -5.6477754078936684 43 -5.6477754078936684 46 -5.6477754078936684 - 49 -5.6477754078936684 54 -5.6477754078936684 56 -5.6477754078936684 57 -5.6477754078936684 - 58 -5.6477754078936684 59 -5.6477754078936684 65 -5.6477754078936684 72 -5.6477754078936684; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 2.1192000000001707 19 2.1192000000001707 - 33 1.3040287561282207 38 1.3040287561282207 43 1.3040287561282207 46 1.3040287561282207 - 49 1.3040287561282207 54 1.3040287561282207 56 1.3040287561282207 57 1.3040287561282207 - 58 1.3040287561282207 59 1.3040287561282207 65 1.3040287561282207 72 1.3040287561282207; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.0821100000000254 19 -3.0821100000000254 - 33 -3.029058051753474 38 -3.029058051753474 43 -3.029058051753474 46 -3.029058051753474 - 49 -3.029058051753474 54 -3.029058051753474 56 -3.029058051753474 57 -3.029058051753474 - 58 -3.029058051753474 59 -3.029058051753474 65 -3.029058051753474 72 -3.029058051753474; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 22.979007009556593 19 22.979007009556593 - 33 45.373139807618806 38 80.258782191899755 43 -24.186993692941517 46 31.959061384122876 - 49 33.97070997010254 54 -61.314618405671105 56 -106.06866853581342 57 14.773175884512012 - 58 6.0622897612146494 59 27.959664913206936 65 33.379224710917185 72 32.451956273129419; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -5.8807954640291324 19 -5.8807954640291324 - 33 40.687338569936891 38 38.061810195815809 43 20.327789765356176 46 -24.261557449005764 - 49 -27.881817407484284 54 66.660532823980603 56 55.501732950163429 57 57.488437055901841 - 58 -7.2457258210734512 59 -67.195139032636746 65 -49.201950059885952 72 -13.357523350556376; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.4977373448908193 19 -3.4977373448908193 - 33 9.7790492183656959 38 29.532755321174395 43 -9.5757966271076889 46 -69.412610236093386 - 49 -31.083585917003656 54 -32.845031356484071 56 -143.68598216744616 57 -44.63120379456273 - 58 -74.22092055678894 59 -124.71815120495674 65 -57.64175562055663 72 -41.725060680171673; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46 1 49 - 1 54 1 56 1 57 1 58 1 59 1 65 1 72 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46 1 49 - 1 54 1 56 1 57 1 58 1 59 1 65 1 72 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 19 1 33 1 38 1 43 1 46 1 49 - 1 54 1 56 1 57 1 58 1 59 1 65 1 72 1; - setAttr -s 14 ".kit[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; - setAttr -s 14 ".kot[0:13]" 9 9 9 9 3 3 3 - 3 3 3 3 3 3 9; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 70 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 6.7758528420198658 - 20.18 6.7758528420198658 28 6.7758528420198658 36 6.7758528420198658 37 6.7758528420198658 - 38 6.7758528420198658 70 6.7758528420198658; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -6.9388939039072284e-018 - 20.18 -6.9388939039072284e-018 28 -6.9388939039072284e-018 36 -6.9388939039072284e-018 - 37 -6.9388939039072284e-018 38 -6.9388939039072284e-018 70 -6.9388939039072284e-018; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -9.5120444723942321e-016 - 20.18 -9.5120444723942321e-016 28 -9.5120444723942321e-016 36 -9.5120444723942321e-016 - 37 -9.5120444723942321e-016 38 -9.5120444723942321e-016 70 -9.5120444723942321e-016; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -12.784757077400341 - 20.18 -37.624757077399877 28 -13.708177176672606 36 -13.567741304451721 37 - -63.244847867618518 38 0 70 0; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 3.2695897469829736 - 20.18 3.2695897469829753 28 3.2695897469829736 36 3.2695897469829736 37 3.2695897469829793 - 38 3.2695897469829842 70 3.2695897469829842; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 -6.9162979482121409 - 20.18 -6.9162979482121507 28 -6.9162979482121409 36 -6.9162979482121409 37 - -6.9162979482121472 38 -6.916297948212156 70 -6.916297948212156; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 70 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 70 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 14.800000000000001 1 20.18 1 28 - 1 36 1 37 1 38 1 70 1; - setAttr -s 7 ".kit[6]" 3; - setAttr -s 7 ".kot[6]" 3; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 1 23 1 36 1 40 1 44 1 48 1 53 - 1 56 1 57 1 61 1 63 1 66 1 69 1 72 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -7.5406347832540632e-013 23 - -7.5406347832540632e-013 36 -7.5406347832540632e-013 40 -7.5406347832540632e-013 - 44 -7.5406347832540632e-013 48 -7.5406347832540632e-013 53 -7.5406347832540632e-013 - 56 -7.5406347832540632e-013 57 -7.5406347832540632e-013 61 -7.5406347832540632e-013 - 63 -7.5406347832540632e-013 66 -7.5406347832540632e-013 69 0 72 -7.5406347832540632e-013; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 13.71946295727715 23 13.71946295727715 - 36 13.71946295727715 40 13.71946295727715 44 13.71946295727715 48 13.71946295727715 - 53 13.71946295727715 56 13.71946295727715 57 13.71946295727715 61 13.71946295727715 - 63 13.71946295727715 66 13.71946295727715 69 13.71946295727715 72 13.71946295727715; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -3.0908609005564358e-013 23 - -3.0908609005564358e-013 36 -3.0908609005564358e-013 40 -3.0908609005564358e-013 - 44 -3.0908609005564358e-013 48 -3.0908609005564358e-013 53 -3.0908609005564358e-013 - 56 -3.0908609005564358e-013 57 -3.0908609005564358e-013 61 -3.0908609005564358e-013 - 63 -3.0908609005564358e-013 66 -3.0908609005564358e-013 69 0 72 -3.0908609005564358e-013; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 295.48765045513591 23 295.48765045513591 - 36 295.48765045513591 40 213.88533605815715 44 327.97459542708128 48 398.39764562243226 - 53 281.33614296793479 56 225.15836113498781 57 268.30338242912825 61 357.43496433554446 - 63 349.61719632868903 66 295.48765045513591 69 281.43157355010277 72 293.14298422427868; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -63.040996980451936 23 -63.040996980451936 - 36 -63.040996980451936 40 -15.936120622721644 44 -71.110555075689462 48 -41.987062615171951 - 53 -48.02411967053439 56 -72.500797094272656 57 -69.125138419716905 61 -50.860803971704257 - 63 -52.397947671024951 66 -63.040996980451936 69 -67.347192760145859 72 -72.359723737647542; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 -405.45049633490953 23 -405.45049633490953 - 36 -405.45049633490953 40 -312.99889701280722 44 -481.30058336485945 48 -458.15311271132873 - 53 -374.14230220947661 56 -306.9152143151191 57 -376.50653539592082 61 -416.70307790225212 - 63 -415.28299902132557 66 -405.45049633490953 69 -376.01225983971062 72 -392.63024836950899; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459183 23 15.445123296459183 - 36 15.445123296459183 40 15.445123296459183 44 15.445123296459183 48 15.445123296459183 - 53 15.445123296459183 56 15.445123296459183 57 15.445123296459183 61 15.445123296459183 - 63 15.445123296459183 66 15.445123296459183 69 15.445123296459183 72 15.445123296459183; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459185 23 15.445123296459185 - 36 15.445123296459185 40 15.445123296459185 44 15.445123296459185 48 15.445123296459185 - 53 15.445123296459185 56 15.445123296459185 57 15.445123296459185 61 15.445123296459185 - 63 15.445123296459185 66 15.445123296459185 69 15.445123296459185 72 15.445123296459185; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 15.445123296459181 23 15.445123296459181 - 36 15.445123296459181 40 15.445123296459181 44 15.445123296459181 48 15.445123296459181 - 53 15.445123296459181 56 15.445123296459181 57 15.445123296459181 61 15.445123296459181 - 63 15.445123296459181 66 15.445123296459181 69 15.445123296459181 72 15.445123296459181; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 23 0 36 0 40 0 44 0 48 0 53 - 0 56 0 57 0 61 0 63 0 66 0 69 0 72 0; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 23 1 36 0.81280641091087713 - 40 0 44 0 48 1 53 0.86851990984222383 56 0 57 0 61 0 63 0.5 66 0 69 0 72 - 0; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 23 0 36 0 40 0 44 0 48 0 53 - 0 56 0 57 0 61 0 63 0 66 0 69 0 72 0; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 13 0 23 0 36 0 40 0 44 0 48 0 53 - 0 56 1 57 0.98542274052478129 61 0 63 0 66 0 69 0 72 0; - setAttr -s 14 ".kit[12:13]" 9 9; - setAttr -s 14 ".kot[12:13]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 1 21 1 31 1 33 1 38 1 42 1 45 - 1 48 1 51 1 55 1 58 1 63 1 65 1 69 1 72 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 -2.5294371750177831 21 -2.5294371750177831 - 31 -2.5294371750177831 33 -2.5294371750177831 38 -2.5294371750177831 42 -2.5294371750177831 - 45 -2.5294371750177831 48 -2.5294371750177831 51 -2.5294371750177831 55 -2.5294371750177831 - 58 -2.5294371750177831 63 -2.5294371750177831 65 -2.5294371750177831 69 -2.5294371750177831 - 72 -2.5294371750177831; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 13.481673551673362 21 13.481673551673362 - 31 13.481673551673362 33 13.481673551673362 38 13.481673551673362 42 13.481673551673362 - 45 13.481673551673362 48 13.481673551673362 51 13.481673551673362 55 13.481673551673362 - 58 13.481673551673362 63 13.481673551673362 65 13.481673551673362 69 13.481673551673362 - 72 13.481673551673362; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 -0.26635088939205875 21 -0.26635088939205875 - 31 -0.26635088939205875 33 -0.26635088939205875 38 -0.26635088939205875 42 - -0.26635088939205875 45 -0.26635088939205875 48 -0.26635088939205875 51 -0.26635088939205875 - 55 -0.26635088939205875 58 -0.26635088939205875 63 -0.26635088939205875 65 - -0.26635088939205875 69 -0.26635088939205875 72 -0.26635088939205875; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 2.5090696653770608 21 15.660322977726873 - 31 -59.152064220349949 33 -12.576992350425726 38 100.64125841157764 42 -59.74707945275015 - 45 2.5090696653770608 48 229.81257006268098 51 205.40557331358448 55 3.0001199156625389 - 58 1.7699337869651124 63 2.5090696653770608 65 38.344019863744009 69 16.714287246285636 - 72 38.344019863744009; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 57.72712587340903 21 46.71187586847725 - 31 78.864853271093551 33 62.263510007017452 38 51.115191882761081 42 103.16836677235398 - 45 57.72712587340903 48 71.479332000486821 51 66.578124695706904 55 21.84732767394534 - 58 40.81600952631031 63 57.72712587340903 65 74.099086231188735 69 81.61478912564283 - 72 74.099086231188735; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 114.81831393065704 21 111.56128358310468 - 31 83.4253918925113 33 123.49770013948103 38 187.37668404727597 42 99.332177522833007 - 45 114.81831393065704 48 338.70706758105109 51 359.66683128416048 55 97.32475108483716 - 58 113.85356831963652 63 114.81831393065704 65 149.44218936973084 69 133.35986307602087 - 72 149.44218936973084; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45 15.445123296459185 48 15.445123296459185 51 15.445123296459185 55 15.445123296459185 - 58 15.445123296459185 63 15.445123296459185 65 15.445123296459185 69 15.445123296459185 - 72 15.445123296459185; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45 15.445123296459185 48 15.445123296459185 51 15.445123296459185 55 15.445123296459185 - 58 15.445123296459185 63 15.445123296459185 65 15.445123296459185 69 15.445123296459185 - 72 15.445123296459185; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 15.445123296459185 21 15.445123296459185 - 31 15.445123296459185 33 15.445123296459185 38 15.445123296459185 42 15.445123296459185 - 45 15.445123296459185 48 15.445123296459185 51 15.445123296459185 55 15.445123296459185 - 58 15.445123296459185 63 15.445123296459185 65 15.445123296459185 69 15.445123296459185 - 72 15.445123296459185; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 21 0 31 0 33 0 38 0 42 0 45 - 0 48 0 51 0 55 0 58 0 63 0 65 0 69 0 72 0; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 21 1 31 0.86060230006204896 - 33 0.84945048406701285 38 0 42 1 45 0.96802113702623904 48 0 51 0 55 0 58 - 1 63 0 65 0 69 0 72 0; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 21 0 31 0 33 0 38 0 42 0 45 - 0 48 0 51 0.3935860058309037 55 1 58 0 63 0 65 0 69 0 72 0; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 13 0 21 0 31 0 33 0 38 0 42 0 45 - 0 48 1 51 0.60641399416909625 55 0 58 0 63 0 65 0 69 0 72 0; - setAttr -s 15 ".kit[13:14]" 9 9; - setAttr -s 15 ".kot[13:14]" 9 9; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 70 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 -0.0180767416209342 70 -0.0180767416209342; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 4.350740136846035 70 4.350740136846035; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 2.679538405939565 70 2.679538405939565; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 70 0; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 0 70 0; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 15.460139794067871 70 15.460139794067871; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 70 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 70 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 13 1 70 1; - setAttr -s 2 ".kit[1]" 3; - setAttr -s 2 ".kot[1]" 3; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -125.22193586838614; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 8.6146645406138322; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -81.606402433660108; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -89.263548368337112; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 5.567698967347587; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -104.19557958825375; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -9.5120444723942321e-016; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.36693656610454845; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 12.728045273286213; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 20 1 25 1 45 1 48 1 53 1 56 - 1 60 1 65 1 70 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 20 0 25 0 45 0 48 0 53 0 56 - 0 60 0 65 0 70 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0.74525677667777757 20 0.74525677667777757 - 25 0.74525677667777757 45 0.74525677667777757 48 0.74525677667777757 53 0.74525677667777757 - 56 0.74525677667777757 60 0.74525677667777757 65 0.74525677667777757 70 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1.8072476834435935 20 1.8072476834435935 - 25 1.8072476834435935 45 1.8072476834435935 48 1.8072476834435935 53 1.8072476834435935 - 56 1.8072476834435935 60 1.8072476834435935 65 1.8072476834435935 70 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.8161377226329614 20 23.97443434067613 - 25 -3.8037016770966843 45 -3.8088876274986432 48 16.07480238918647 53 15.109332395359594 - 56 26.061052322842336 60 13.396972450271631 65 -2.9107248491535329 70 -3.8161377226329614; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 20 0 25 0 45 0 48 8.3446223572303353 - 53 -4.3103980061846903 56 -0.31747878544030345 60 -3.0374814655308411 65 - -1.4620754001211411 70 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 0 20 0 25 0 45 0 48 8.7718521891731456 - 53 -8.5131513305800102 56 -18.111356086769547 60 13.313344906312897 65 2.5900267263694494 - 70 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 20 1 25 1 45 1 48 1 53 1 56 - 1 60 1 65 1 70 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 20 1 25 1 45 1 48 1 53 1 56 - 1 60 1 65 1 70 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 20 1 25 1 45 1 48 1 53 1 56 - 1 60 1 65 1 70 1; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.33812841032783514; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.12017666558909808; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.724592717525262; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.21268105951286304; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 143.97979303987; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -25.119237776405349; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -10.758168812157226; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.2797760798095944; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.27977607980959479; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.089288315816329011; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -1.3478882421479896; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -1.4748643609966379; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -0.21593819942915299; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 -1.9219320910538564; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0.50945827248643527; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 70 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 69 0 72 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 69 0 72 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 69 0 72 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 69 0 72 0; -select -ne :time1; - setAttr ".o" 57; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_LHAND_ROT; -select -ne IMP_RHAND_ROT; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_ALL; - setAttr ".r" -type "double3" 0 90 0 ; - setAttr ".s" -type "double3" 1.25 1.25 1.25 ; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479692 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.155057227455956 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Body; -select -ne IMP_Chest; -select -ne IMP_Head; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_effector4; - setAttr ".v" yes; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_effector3; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne |group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1 - ; - setAttr ".v" yes; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of slash3.ma diff --git a/base/models/monsters/imp/animation/cycles/teleportin.ma b/base/models/monsters/imp/animation/cycles/teleportin.ma deleted file mode 100644 index 31e4bc76b..000000000 --- a/base/models/monsters/imp/animation/cycles/teleportin.ma +++ /dev/null @@ -1,4198 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:17 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: teleportin.ma -//Last modified: Sat, May 29, 2004 06:57:33 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows 2000 (Build 2195)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 22.390672113731494 39.373514837820423 177.87475910151434 ; - setAttr ".r" -type "double3" -1.530108913527801 8.199999999999152 7.5314245805268063e-017 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 187.09196677513131; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 1.2994289005574777 49.453306911683555 10.571225793121133 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" -3.3927874941258063 44.014518843252489 114.40646173572298 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 329.23571818959681; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 104.86085128619987 42.365131842652389 10.045758476009869 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 182.69883031017056; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; - setAttr ".sp" -type "double3" 1.6908203087802036 38.036468565051095 -1.0893083480314765 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -125.22193586838614 15 -125.22193586838614 - 29.248000000000001 -125.22193586838614 68 -125.22193586838614; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 8.6146645406138322 15 8.6146645406138322 - 29.248000000000001 8.6146645406138322 68 8.6146645406138322; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -81.606402433660108 15 -81.606402433660108 - 29.248000000000001 -81.606402433660108 68 -81.606402433660108; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -89.263548368337112 15 -89.263548368337112 - 29.248000000000001 -89.263548368337112 68 -89.263548368337112; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.567698967347587 15 5.567698967347587 - 29.248000000000001 5.567698967347587 68 5.567698967347587; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -104.19557958825375 15 -104.19557958825375 - 29.248000000000001 -104.19557958825375 68 -104.19557958825375; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -16.21787434118799 15 -16.21787434118799 - 29.248000000000001 -16.21787434118799 68 -16.21787434118799; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.77211996138749939 15 0.77211996138749939 - 29.248000000000001 0.77211996138749939 68 0.77211996138749939; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -4.579364761070849 15 -4.579364761070849 - 29.248000000000001 -4.579364761070849 68 -4.579364761070849; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -8.1254375044848945 15 -8.1254375044848945 - 29.248000000000001 -8.1254375044848945 68 -8.1254375044848945; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.7758528420198658 15 6.7758528420198658 - 29.248000000000001 6.7758528420198658 68 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9388939039072284e-018 15 0 - 29.248000000000001 0 68 0; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -9.5120444723942321e-016 15 0 - 29.248000000000001 0 68 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -12.784757077400341 15 -12.784757077400341 - 29.248000000000001 -12.784757077400341 68 -12.784757077400341; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 3.2695897469829736 15 3.2695897469829736 - 29.248000000000001 3.2695897469829736 68 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9162979482121409 15 -6.9162979482121409 - 29.248000000000001 -6.9162979482121409 68 -6.9162979482121409; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 29.248000000000001 1 68 - 1 72 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.758090709918321 15 12.758090709918321 - 29.248000000000001 12.758090709918321 68 12.758090709918321 72 5.8482392980113111; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.6648666211645171 15 1.6648666211645171 - 29.248000000000001 1.6648666211645171 68 1.6648666211645171 72 11.185560383958709; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -8.2514949399869195 15 -8.2514949399869195 - 29.248000000000001 -8.2514949399869195 68 -8.2514949399869195 72 23.265284412710983; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 0 29.248000000000001 0 68 - 0 72 -25.871497169061271; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 18.296137987022 15 18.296137987022 - 29.248000000000001 18.296137987022 68 18.296137987022 72 18.296137987021996; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 0 29.248000000000001 0 68 - 0 72 0; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 29.248000000000001 1 68 - 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 29.248000000000001 1 68 - 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 29.248000000000001 1 68 - 1 72 1; - setAttr -s 5 ".kit[0:4]" 9 9 3 3 3; - setAttr -s 5 ".kot[0:4]" 9 9 3 3 3; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 6.7758528420198658 15 6.7758528420198658 - 29.248000000000001 6.7758528420198658 68 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -6.9388939039072284e-018 15 0 - 29.248000000000001 0 68 0; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -9.5120444723942321e-016 15 0 - 29.248000000000001 0 68 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.1064832569487142 15 -2.1064832569487142 - 29.248000000000001 -2.1064832569487142 68 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.36693656610454173 15 0.36693656610454173 - 29.248000000000001 0.36693656610454173 68 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 12.728045273286209 15 12.728045273286209 - 29.248000000000001 12.728045273286209 68 12.728045273286209; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 7.2240000000000002 - 1 15 1 20 1 29 1 40 1 68 1 72 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1.4992483681888071 3.336 0.85039738469675819 - 7.2240000000000002 0 15 0 20 -3.5394007894315376 29 -5.2885238856518164 40 - -4.754740194801002 68 -3.1375833875031756 72 -6.6302543635927753; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 136.94040788018989 3.336 43.965904408722096 - 7.2240000000000002 16.46867318519303 15 16.46867318519303 20 39.630677938540387 - 29 42.175979794167709 40 45.588186776516757 68 39.970234670070724 72 40.641750406486153; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -2.9739425354301807 3.336 -2.4048873014273817 - 7.2240000000000002 -1.6210105472851586 15 -1.6210105472851586 20 -8.7638947585759048 - 29 -7.719750307355369 40 -4.806682177977045 68 -7.1140041361149606 72 19.556314098060291; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.55644336951292817 3.336 -9.6561235235231493 - 7.2240000000000002 73.186688271287991 15 73.186688271287991 20 76.872788513580062 - 29 44.112788513580988 40 31.190403029326117 68 14.488305710603974 72 40.494473772929702; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 6.2969131118352886 3.336 7.6070477376342609 - 7.2240000000000002 6.2969131118353117 15 6.2969131118353117 20 6.2969131118353117 - 29 6.2969131118352939 40 6.2969131118352939 68 6.2969131118352921 72 6.2969131118352939; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.060261194923271 3.336 2.7074118456999363 - 7.2240000000000002 5.060261194923271 15 5.060261194923271 20 5.060261194923271 - 29 5.0602611949232728 40 5.0602611949232728 68 5.0602611949232719 72 5.0602611949232701; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 7.2240000000000002 - 1 15 1 20 1 29 1 40 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 7.2240000000000002 - 1 15 1 20 1 29 1 40 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 7.2240000000000002 - 1 15 1 20 1 29 1 40 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1 72 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0 72 0; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 2.3128351505039433 15 2.3128351505039433 - 20.416 2.3128351505039433 29.228000000000002 2.3128351505039433 35.848 2.3128351505039433 - 68 2.3128351505039433 72 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0.23421866920666501 15 0.23421866920666501 - 20.416 0.23421866920666501 29.228000000000002 0.23421866920666501 35.848 - 0.23421866920666501 68 0.23421866920666501 72 0.23421866920666501; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.416 -17.141297204275059 - 29.228000000000002 5.3035021064144265 35.848 16.08626461041349 68 11.913770184118828 - 72 -1.314232773616012; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0 72 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0 72 0; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1 72 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1 72 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1 72 1; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 15 1 20 1 29 1 36 1 40 1 68 - 1 72 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 15 0 20 0 29 0 36 0 40 0 68 - 0 72 0; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 5.6268319407172029 15 5.6268319407172029 - 20 5.6268319407172029 29 5.6268319407172029 36 5.6268319407172029 40 5.6268319407172029 - 68 5.6268319407172029 72 5.6268319407172029; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -2.1098668596606802 15 -2.1098668596606802 - 20 -2.1098668596606802 29 -2.1098668596606802 36 -2.1098668596606802 40 -2.1098668596606802 - 68 -2.1098668596606802 72 -2.1098668596606802; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 9.4119425478832621 15 -19.671845271147479 - 20 3.1223777499579128 29 -3.9519747036972719 36 -14.172772381287405 40 -5.073361759357911 - 68 9.4119425478832621 72 -17.638912642294702; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 3.8819931310225972 15 6.2156627158197422 - 20 12.862713338850638 29 -17.595970665073018 36 6.7972720801107922 40 -2.926066696665262 - 68 3.8819931310225972 72 23.29906932962308; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 -5.7213769427135075 15 -15.19062649640299 - 20 -9.6855981986908475 29 6.206659598004574 36 4.7318758517783293 40 7.0555237271740143 - 68 -5.7213769427135075 72 -13.948397192348018; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 15 1 20 1 29 1 36 1 40 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 15 1 20 1 29 1 36 1 40 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 15 1 20 1 29 1 36 1 40 1 68 - 1 72 1; - setAttr -s 8 ".kit[7]" 3; - setAttr -s 8 ".kot[7]" 3; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 5.7384771804188404 15 5.7384771804188404 - 29.248000000000001 5.7384771804188404 68 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.0494561358638701 15 2.0494561358638701 - 29.248000000000001 2.0494561358638701 68 2.0494561358638701; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 15 1 15.004 1 17.46 1 20.408000000000001 - 1 29.216000000000001 1 32.172 1 38.048 1 68 1 72 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 15 0 15.004 0 17.46 0 20.408000000000001 - 0 29.216000000000001 0 32.172 0 38.048 0 68 0 72 0; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 15 2.6456615572060826 - 15.004 2.6456615572060826 17.46 2.6456615572060826 20.408000000000001 2.6456615572060826 - 29.216000000000001 2.6456615572060826 32.172 2.6456615572060826 38.048 2.6456615572060826 - 68 2.6456615572060826 72 2.6456615572060826; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 15 1.9935618776130362 - 15.004 1.9935618776130362 17.46 1.9935618776130362 20.408000000000001 1.9935618776130362 - 29.216000000000001 1.9935618776130362 32.172 1.9935618776130362 38.048 1.9935618776130362 - 68 1.9935618776130362 72 1.9935618776130362; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -17.460363846642768 15 -3.3721199222698415 - 15.004 -3.3721199222698415 17.46 -8.1259270466375 20.408000000000001 -55.753285691539659 - 29.216000000000001 -61.981690635772658 32.172 -77.630484697886416 38.048 - -66.944551782216209 68 -17.460363846642768 72 -29.237879655452048; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -5.7962630210791115 15 -18.61358322935018 - 15.004 -18.61358322935018 17.46 -3.5840270081743055 20.408000000000001 -0.56575935076619877 - 29.216000000000001 -22.706955140559792 32.172 -19.619340820278161 38.048 - 8.4699108941543688 68 -5.7962630210791115 72 -25.237041595994583; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 6.6414265814238034 15 14.181440951070751 - 15.004 14.181440951070751 17.46 7.5833949322652927 20.408000000000001 10.878229969953455 - 29.216000000000001 -13.476487678639403 32.172 -12.138888481798636 38.048 - -3.0482303883022888 68 6.6414265814238034 72 -13.195505960341031; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 15 1 15.004 1 17.46 1 20.408000000000001 - 1 29.216000000000001 1 32.172 1 38.048 1 68 1 72 1; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 15 1 15.004 1 17.46 1 20.408000000000001 - 1 29.216000000000001 1 32.172 1 38.048 1 68 1 72 1; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 15 1 15.004 1 17.46 1 20.408000000000001 - 1 29.216000000000001 1 32.172 1 38.048 1 68 1 72 1; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0.74525677667777757 15 0.74525677667777757 - 20.416 0.74525677667777757 29.228000000000002 0.74525677667777757 35.848 - 0.74525677667777757 68 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.8072476834435935 15 1.8072476834435935 - 20.416 1.8072476834435935 29.228000000000002 1.8072476834435935 35.848 1.8072476834435935 - 68 1.8072476834435935; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8161377226329614 15 -3.8161377226329614 - 20.416 33.604514516045661 29.228000000000002 33.604514516045661 35.848 33.604514516045661 - 68 -3.8161377226329614; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 15 0 20.416 0 29.228000000000002 - 0 35.848 0 68 0; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 15 1 20.416 1 29.228000000000002 - 1 35.848 1 68 1; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.112 1 7.2240000000000002 - 1 15 1 20 1 29 1 36 1 40 1 72 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 4.8088785785432249 4.112 4.8088785785432249 - 7.2240000000000002 4.8088785785432249 15 4.8088785785432249 20 4.8088785785432249 - 29 4.8088785785432249 36 4.8088785785432249 40 4.8088785785432249 72 4.8088785785432249; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.1192573708759417 4.112 2.1192573708759417 - 7.2240000000000002 2.1192573708759417 15 2.1192573708759417 20 2.1192573708759417 - 29 2.1192573708759417 36 2.1192573708759417 40 2.1192573708759417 72 2.1192573708759417; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.0821078932592161 4.112 -3.0821078932592161 - 7.2240000000000002 -3.0821078932592161 15 -3.0821078932592161 20 -3.0821078932592161 - 29 -3.0821078932592161 36 -3.0821078932592161 40 -3.0821078932592161 72 -3.0821078932592161; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -12.427061868902332 4.112 -32.330638004323433 - 7.2240000000000002 17.881533420710575 15 18.200510443003346 20 -31.374569670256559 - 29 -9.5696897340168068 36 11.541539366558251 40 -5.8804207192356515 40.16 - -4.5817938397042637 72 -44.349491166563986; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 18.355136182766611 4.112 -29.571402311366267 - 7.2240000000000002 19.343663623497147 15 21.577108486009159 20 42.119218428813006 - 29 9.5594575188921382 36 20.3633786462435 40 19.840153297762072 40.16 26.658400951807923 - 72 23.333749626109348; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -29.925918142194192 4.112 96.16079356927915 - 7.2240000000000002 -4.9915353586612907 15 -7.7735701133787094 20 -39.591688320473089 - 29 -43.665853534367592 36 -27.779666503070004 40 -37.841731622871833 40.16 - -28.520910922575261 72 -26.605868620425959; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.112 1 7.2240000000000002 - 1 15 1 20 1 29 1 36 1 40 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.112 1 7.2240000000000002 - 1 15 1 20 1 29 1 36 1 40 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4.112 1 7.2240000000000002 - 1 15 1 20 1 29 1 36 1 40 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 12.412879749935719 15 12.412879749935719 - 20.416 12.412879749935719 29.248000000000001 12.412879749935719 68 12.412879749935719; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -6.7286993982861674 15 -6.7286993982861674 - 20.416 -6.7286993982861674 29.248000000000001 -6.7286993982861674 68 -6.7286993982861674; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.868763862603668 15 -3.868763862603668 - 20.416 -3.868763862603668 29.248000000000001 -3.868763862603668 68 -3.868763862603668; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 53.630905100806274 15 80.705542659749995 - 20.416 12.30846027300135 29.248000000000001 12.30846027300135 68 53.630905100806274; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 -6.888411515133873 20.416 - 0 29.248000000000001 0 68 0; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 -9.7103727997758771 20.416 - 0 29.248000000000001 0 68 0; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 6.4480000000000004 - 1 20.416 1 29.236000000000001 1 35.840000000000003 1 40.16 1 68 1 72 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.3932492040642028 3.336 -5.3932492040642028 - 6.4480000000000004 -5.3932492040642028 20.416 -5.3932492040642028 29.236000000000001 - -5.3932492040642028 35.840000000000003 -5.3932492040642028 40.16 -5.3932492040642028 - 68 -5.3932492040642028 72 -5.3932492040642028; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.1192000000003004 3.336 2.1192000000003004 - 6.4480000000000004 2.1192000000003004 20.416 2.1192000000003004 29.236000000000001 - 2.1192000000003004 35.840000000000003 2.1192000000003004 40.16 2.1192000000003004 - 68 2.1192000000003004 72 2.1192000000003004; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.0821100000000272 3.336 -3.0821100000000272 - 6.4480000000000004 -3.0821100000000272 20.416 -3.0821100000000272 29.236000000000001 - -3.0821100000000272 35.840000000000003 -3.0821100000000272 40.16 -3.0821100000000272 - 68 -3.0821100000000272 72 -3.0821100000000272; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 47.897771024785186 3.336 -29.2643540797771 - 6.4480000000000004 1.9984963154227247 15 1.9984963154227247 20.416 56.95212985769335 - 29.236000000000001 41.698744042302785 35.840000000000003 22.338324296500808 - 40.16 31.962861877202858 68 47.897771024785186 72 -2.617353045691353; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -48.751706532137327 3.336 50.941848589114784 - 6.4480000000000004 -34.736357457638789 15 -34.736357457638789 20.416 -56.989558608194088 - 29.236000000000001 -46.648273923095957 35.840000000000003 -46.648273923095942 - 40.16 -31.342810215007134 68 -48.751706532137327 72 -5.9392503669031784; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.369283509291309 3.336 32.572851772390301 - 6.4480000000000004 9.6786312897271092 15 9.6786312897271092 20.416 -42.337773340010131 - 29.236000000000001 -23.080304259132767 35.840000000000003 -23.08030425913276 - 40.16 -18.2085977172752 68 -10.369283509291309 72 -36.464846512098269; - setAttr -s 10 ".kit[9]" 3; - setAttr -s 10 ".kot[9]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 6.4480000000000004 - 1 20.416 1 29.236000000000001 1 35.840000000000003 1 40.16 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 6.4480000000000004 - 1 20.416 1 29.236000000000001 1 35.840000000000003 1 40.16 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 3.336 1 6.4480000000000004 - 1 20.416 1 29.236000000000001 1 35.840000000000003 1 40.16 1 68 1 72 1; - setAttr -s 9 ".kit[8]" 3; - setAttr -s 9 ".kot[8]" 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -12.41287000000041 15 -12.41287000000041 - 20.416 -12.41287000000041 29.248000000000001 -12.41287000000041 68 -12.41287000000041; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -6.7285999999993047 15 -6.7285999999993047 - 20.416 -6.7285999999993047 29.248000000000001 -6.7285999999993047 68 -6.7285999999993047; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -3.8687599999999316 15 -3.8687599999999316 - 20.416 -3.8687599999999316 29.248000000000001 -3.8687599999999316 68 -3.8687599999999316; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 66.649287652014095 15 75.679925282090593 - 20.416 2.2130851399409881 29.248000000000001 2.2130851399409881 68 66.649287652014095; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 1.6604723665843502 20.416 - 0 29.248000000000001 0 68 0; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 15 -4.0214942467213399 20.416 - 0 29.248000000000001 0 68 0; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 15 1 20.416 1 29.248000000000001 - 1 68 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15 1 68 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.0180767416209342 15 -0.0180767416209342 - 68 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 4.350740136846035 15 4.350740136846035 - 68 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.679538405939565 15 2.679538405939565 - 68 2.679538405939565; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 22.624 -63.90346873963567 - 68 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 22.624 0 68 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 22.624 0 68 0; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15 1 68 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15 1 68 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 15 1 68 1; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 20.416 1 29.248000000000001 - 1 68 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -2.5294371750177831 20.416 -2.5294371750177831 - 29.248000000000001 -2.5294371750177831 68 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 13.481673551673362 20.416 13.481673551673362 - 29.248000000000001 13.481673551673362 68 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.26635088939205875 20.416 -0.26635088939205875 - 29.248000000000001 -0.26635088939205875 68 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 34.731179446332078 15 383.55322504794935 - 20.416 -19.70034142316899 29.24 -33.342461218964765 40.16 -0.90465784012028105 - 68 34.731179446332078; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 80.262128312658689 15 80.455918362257933 - 20.416 68.079716356409364 29.24 60.328817780487206 40.16 79.127370116906235 - 68 80.262128312658689; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 161.64280519855993 15 459.38173981860081 - 20.416 68.698650924264754 29.24 59.657311668621517 40.16 101.82242611341948 - 68 161.64280519855993; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 20.416 15.445123296459185 - 29.248000000000001 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 20.416 15.445123296459185 - 29.248000000000001 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 15.445123296459185 20.416 15.445123296459185 - 29.248000000000001 15.445123296459185 68 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20.416 0 29.248000000000001 - 0 68 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 20.416 0 29.248000000000001 - 0 68 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 16.748000000000001 0.13147433136474931 - 18.208 0 40.16 0.37999999999999989 68 1; - setAttr -s 5 ".kit[2:4]" 3 9 9; - setAttr -s 5 ".kot[2:4]" 3 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 17.46 0 20.412 0.59426043818956764 - 34.376 0.60680157084534347 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 20.416 1 68 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -7.5406347832540632e-013 19.668 - 0 68 0; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 13.71946295727715 20.416 13.71946295727715 - 68 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.0908609005564358e-013 19.668 - 0 68 0; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 83.451920652031347 20.416 109.83304985802269 - 31.436 150.20187293547716 40.16 -20.721417223369137 68 83.451920652031347; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -83.268958049108775 20.416 -137.01549747165305 - 31.436 -107.32789410973774 40.16 -76.010271987183614 68 -83.268958049108775; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -217.30282869676228 20.416 -210.70510868639386 - 31.436 -241.59478808439451 40.16 -68.13488408174311 68 -217.30282869676228; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459183 20.416 15.445123296459183 - 68 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459185 20.416 15.445123296459185 - 68 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 15.445123296459181 20.416 15.445123296459181 - 68 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 19.668 0 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 19.668 0 68 0; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 18.208 1 19.668 0.36670594003338086 - 40.16 0.37999999999999989 68 1; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 0 18.208 0 20.416 0.5 34.376 - 0.48101066942509846 68 0; - setAttr -s 5 ".kit[4]" 1; - setAttr -s 5 ".kot[4]" 1; - setAttr -s 5 ".kix[4]" 0.9325680136680603; - setAttr -s 5 ".kiy[4]" -0.36099430918693542; - setAttr -s 5 ".kox[4]" 0.93256807327270508; - setAttr -s 5 ".koy[4]" -0.36099410057067871; -createNode animCurveTU -n "IMP_Rwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.24500268074642695 15 -0.24500268074642695 - 29.248000000000001 -0.24500268074642695 68 -0.24500268074642695; -createNode animCurveTL -n "IMP_Rwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.2065238412698649 15 1.2065238412698649 - 29.248000000000001 1.2065238412698649 68 1.2065238412698649; -createNode animCurveTL -n "IMP_Rwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.38309524546711837 15 -0.38309524546711837 - 29.248000000000001 -0.38309524546711837 68 -0.38309524546711837; -createNode animCurveTA -n "IMP_Rwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -14.614862034248505 15 -14.614862034248505 - 29.248000000000001 -14.614862034248505 68 -14.614862034248505; -createNode animCurveTA -n "IMP_Rwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 33.316404488343842 15 33.316404488343842 - 29.248000000000001 33.316404488343842 68 33.316404488343842; -createNode animCurveTA -n "IMP_Rwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -119.57538852061882 15 -119.57538852061882 - 29.248000000000001 -119.57538852061882 68 -119.57538852061882; -createNode animCurveTU -n "IMP_Rwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000007 15 1.0000000000000007 - 29.248000000000001 1.0000000000000007 68 1.0000000000000007; -createNode animCurveTU -n "IMP_Rwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000004 15 1.0000000000000004 - 29.248000000000001 1.0000000000000004 68 1.0000000000000004; -createNode animCurveTU -n "IMP_Rwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1.0000000000000002 15 1.0000000000000002 - 29.248000000000001 1.0000000000000002 68 1.0000000000000002; -createNode animCurveTU -n "IMP_Rwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Lwing_null_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Lwing_null_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.12017666558909808 15 -0.12017666558909808 - 29.248000000000001 -0.12017666558909808 68 -0.12017666558909808; -createNode animCurveTL -n "IMP_Lwing_null_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.724592717525262 15 -0.724592717525262 - 29.248000000000001 -0.724592717525262 68 -0.724592717525262; -createNode animCurveTL -n "IMP_Lwing_null_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.21268105951286304 15 -0.21268105951286304 - 29.248000000000001 -0.21268105951286304 68 -0.21268105951286304; -createNode animCurveTA -n "IMP_Lwing_null_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 143.97979303987 15 143.97979303987 - 29.248000000000001 143.97979303987 68 143.97979303987; -createNode animCurveTA -n "IMP_Lwing_null_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -25.119237776405349 15 -25.119237776405349 - 29.248000000000001 -25.119237776405349 68 -25.119237776405349; -createNode animCurveTA -n "IMP_Lwing_null_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -10.758168812157226 15 -10.758168812157226 - 29.248000000000001 -10.758168812157226 68 -10.758168812157226; -createNode animCurveTU -n "IMP_Lwing_null_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 15 0.99999999999999989 - 29.248000000000001 0.99999999999999989 68 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.99999999999999989 15 0.99999999999999989 - 29.248000000000001 0.99999999999999989 68 0.99999999999999989; -createNode animCurveTU -n "IMP_Lwing_null_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lwing_null_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -0.27427863724837187 15 0.077981293515704403 - 29.248000000000001 -0.74999975068806757 68 -0.15174782359914046; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.1075115639039561 15 -1.1351282283403885 - 29.248000000000001 -0.069091982949667785 68 -1.0222432259776459; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.6426166214208928 15 -1.6448108776046009 - 29.248000000000001 -1.8517679259567221 68 -1.7123058678214413; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 15 1 29.248000000000001 1 68 - 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0.27427146386087553 15 -0.96028872540452515 - 29.248000000000001 -1.2426402281997371 68 -0.68393793124877111; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.1074983884594769 15 -1.0206120681764821 - 29.248000000000001 -0.19156158567963411 68 -0.75098205981507427; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -1.6426267024711592 15 -1.4269535977576329 - 29.248000000000001 -1.5793638928377538 68 -1.7228624007839568; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 15 0 29.248000000000001 0 68 - 0; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 512 -size 1024 -divisions 5 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 40 -ast 1 -aet 40 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 19.668 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 19.668 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 20.416 0 29.248000000000001 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 20.416 0 29.248000000000001 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -3.3494230074244564; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_origin_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTL -n "IMP_origin_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -parent -s -nc -r "IMP_lelbow" "group1"; -parent -s -nc -r "IMP_relbow" "group1"; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.86585498 0.608989 - 0.904742 0.61987799 0.892663 0.58372599 0.86585498 0.608989 0.892663 0.58372599 - 0.88192099 0.50762999 0.84326202 0.52863598 0.86585498 0.608989 0.88192099 - 0.50762999 0.90890902 0.65339601 0.94025302 0.64341003 0.93670201 0.60081297 - 0.904742 0.61987799 0.90890902 0.65339601 0.93670201 0.60081297 0.93670201 - 0.60081297 0.94025302 0.64341003 0.96222198 0.59601402 0.892663 0.58372599 - 0.904742 0.61987799 0.93670201 0.60081297 0.892663 0.58372599 0.93670201 - 0.60081297 0.88192099 0.50762999 0.88192099 0.50762999 0.93670201 0.60081297 - 0.91139501 0.52158397 0.93670201 0.60081297 0.96222198 0.59601402 0.91139501 - 0.52158397 0.44557601 0.62202299 0.493588 0.62263501 0.47251999 0.59212297 - 0.46083799 0.64259601 0.493588 0.62263501 0.44557601 0.62202299 0.422638 - 0.66873902 0.46083799 0.64259601 0.44557601 0.62202299 0.47251999 0.59212297 - 0.50988603 0.60414898 0.471468 0.56798297 0.493588 0.62263501 0.50988603 - 0.60414898 0.47251999 0.59212297 0.422638 0.66873902 0.43200499 0.70468998 - 0.46083799 0.64259601 0.43200499 0.70468998 0.469937 0.66459 0.46083799 0.64259601 - 0.46083799 0.64259601 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 - 0.50244898 0.644642 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.50988603 0.60414898 0.55341202 0.63760501 0.55948597 0.61438298 0.493588 - 0.62263501 0.469937 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 - 0.727027 0.56032002 0.70486701 0.50244898 0.644642 0.578484 0.726412 0.56032002 - 0.70486701 0.476217 0.727027 0.56181002 0.765275 0.578484 0.726412 0.476217 - 0.727027 0.484781 0.85584599 0.50365102 0.81889403 0.47210601 0.79053301 - 0.47210601 0.79053301 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 - 0.79053301 0.56181002 0.765275 0.476217 0.727027 0.401124 0.82737499 0.484781 - 0.85584599 0.47210601 0.79053301 0.42608401 0.89203 0.484781 0.85584599 0.401124 - 0.82737499 0.401124 0.82737499 0.47210601 0.79053301 0.40665799 0.802068 - 0.40665799 0.802068 0.47210601 0.79053301 0.476217 0.727027 0.43095401 0.61518103 - 0.44557601 0.62202299 0.47251999 0.59212297 0.43095401 0.61518103 0.47251999 - 0.59212297 0.471468 0.56798297 0.37521201 0.59356803 0.471468 0.56798297 - 0.44446999 0.51254302 0.37521201 0.59356803 0.43095401 0.61518103 0.471468 - 0.56798297 0.43095401 0.61518103 0.422638 0.66873902 0.44557601 0.62202299 - 0.422638 0.66873902 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 - 0.66881698 0.422638 0.66873902 0.37521201 0.59356803 0.44672099 0.742163 - 0.476217 0.727027 0.43200499 0.70468998 0.43200499 0.70468998 0.476217 0.727027 - 0.469937 0.66459 0.39220601 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 - 0.37832099 0.73359799 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 - 0.69965303 0.37832099 0.73359799 0.43200499 0.70468998 0.41114399 0.69965303 - 0.43200499 0.70468998 0.422638 0.66873902 0.41114399 0.69965303 0.422638 - 0.66873902 0.402172 0.66881698 0.37832099 0.73359799 0.41114399 0.69965303 - 0.402172 0.66881698 0.55341202 0.63760501 0.58906102 0.696136 0.590801 0.64542502 - 0.56032002 0.70486701 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 - 0.70486701 0.55341202 0.63760501 0.50244898 0.644642 0.594082 0.62339002 - 0.55341202 0.63760501 0.590801 0.64542502 0.55341202 0.63760501 0.594082 - 0.62339002 0.55948597 0.61438298 0.471468 0.56798297 0.48631501 0.53582197 - 0.44446999 0.51254302 0.471468 0.56798297 0.52967697 0.561248 0.48631501 - 0.53582197 0.55948597 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 - 0.56466401 0.58405501 0.52967697 0.561248 0.50988603 0.60414898 0.56466401 - 0.58405501 0.55312598 0.548361 0.52967697 0.561248 0.55948597 0.61438298 - 0.594082 0.62339002 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 - 0.58405501 0.59298301 0.57251501 0.52967697 0.561248 0.55312598 0.548361 - 0.48631501 0.53582197 0.55312598 0.548361 0.59298301 0.57251501 0.55817002 - 0.495579 0.48631501 0.53582197 0.55312598 0.548361 0.55817002 0.495579 0.56466401 - 0.58405501 0.55948597 0.61438298 0.59298301 0.57251501 0.33425501 0.67281002 - 0.34469 0.60969198 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 - 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.33425501 0.67281002 0.402172 0.66881698 0.37521201 0.59356803 - 0.29069301 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 - 0.29069301 0.56685197 0.35016599 0.53974301 0.35016599 0.53974301 0.37521201 - 0.59356803 0.44446999 0.51254302 0.34469 0.60969198 0.37521201 0.59356803 - 0.35016599 0.53974301 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 - 0.52030098 0.66376501 0.50938398 0.62787598 0.58490998 0.70178902 0.52030098 - 0.611036 0.541574 0.62787598 0.58490998 0.66376501 0.50938398 0.91139501 - 0.52158397 0.94016802 0.552697 0.94404799 0.534742 0.91139501 0.52158397 - 0.94404799 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 - 0.52158397 0.91649199 0.412949 0.91649199 0.412949 0.94404799 0.534742 0.95096499 - 0.41022 0.94404799 0.534742 0.97447199 0.54772502 0.95096499 0.41022 0.97447199 - 0.54772502 0.99280602 0.52736998 0.95096499 0.41022 0.88192099 0.50762999 - 0.91139501 0.52158397 0.88974899 0.43314499 0.86741501 0.373849 0.88974899 - 0.43314499 0.91649199 0.412949 0.72172701 0.597004 0.73045999 0.53145701 - 0.70178902 0.52030098 0.361752 0.72452599; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.402172 0.66881698 - 0.33425501 0.67281002 0.361752 0.72452599 0.402172 0.66881698 0.66176099 - 0.61444402 0.72172701 0.597004 0.70178902 0.52030098 0.72172701 0.597004 - 0.76481098 0.59411001 0.73045999 0.53145701 0.33192599 0.74883097 0.361752 - 0.72452599 0.33425501 0.67281002 0.95096499 0.41022 0.99280602 0.52736998 - 0.99264401 0.396844 0.89975703 0.32890701 0.91649199 0.412949 0.95096499 - 0.41022 0.89975703 0.32890701 0.95096499 0.41022 0.99264401 0.396844 0.86741501 - 0.373849 0.91649199 0.412949 0.89975703 0.32890701 0.68089098 0.41862199 - 0.66376501 0.50938398 0.70178902 0.52030098 0.84326202 0.52863598 0.88192099 - 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 - 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 0.81960201 - 0.54509503 0.84326202 0.52863598 0.81960201 0.54509503 0.80370599 0.60544503 - 0.85311198 0.64641303 0.86585498 0.608989 0.84326202 0.52863598 0.90890902 - 0.65339601 0.86585498 0.608989 0.85311198 0.64641303 0.86585498 0.608989 - 0.90890902 0.65339601 0.904742 0.61987799 0.56233603 0.85706103 0.61128402 - 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 0.55527902 - 0.8071 0.56181002 0.765275 0.55527902 0.8071 0.61429799 0.75036502 0.57115501 - 0.92132199 0.63363802 0.89377397 0.60618597 0.86918902 0.57115501 0.92132199 - 0.60618597 0.86918902 0.56233603 0.85706103 0.14566401 0.93838102 0.16559599 - 0.995709 0.23810799 0.94020498 0.059299 0.99024302 0.16559599 0.995709 0.14566401 - 0.93838102 0.68109202 0.85573 0.66327202 0.82856899 0.61128402 0.83876997 - 0.17147 0.907399 0.14566401 0.93838102 0.23810799 0.94020498 0.063868999 - 0.91910303 0.059299 0.99024302 0.14566401 0.93838102 0.135956 0.83810002 - 0.12989099 0.871301 0.193271 0.88191301 0.052301999 0.89361697 0.063868999 - 0.91910303 0.072558001 0.88500297 0.60618597 0.86918902 0.68109202 0.85573 - 0.61128402 0.83876997 0.63363802 0.89377397 0.68109202 0.85573 0.60618597 - 0.86918902 0.052301999 0.89361697 0.0086899996 0.90104598 0.063868999 0.91910303 - 0.063868999 0.91910303 0.0086899996 0.90104598 0.059299 0.99024302 0.61128402 - 0.83876997 0.66305399 0.78664398 0.612091 0.80211103 0.66327202 0.82856899 - 0.66305399 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 - 0.78664398 0.64314198 0.77576202 0.64314198 0.77576202 0.68224001 0.752303 - 0.662714 0.74348199 0.66305399 0.78664398 0.68224001 0.752303 0.64314198 - 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.61429799 0.75036502 - 0.612091 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 - 0.77576202 0.662714 0.74348199 0.63186097 0.74417901 0.59559602 0.73881298 - 0.56181002 0.765275 0.61429799 0.75036502 0.59559602 0.73881298 0.61429799 - 0.75036502 0.596021 0.71545899 0.578484 0.726412 0.596021 0.71545899 0.58906102 - 0.696136 0.56032002 0.70486701 0.578484 0.726412 0.58906102 0.696136 0.578484 - 0.726412 0.59559602 0.73881298 0.596021 0.71545899 0.56181002 0.765275 0.59559602 - 0.73881298 0.578484 0.726412 0.038779002 0.81607199 0.0081359996 0.81497997 - 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 0.044146001 - 0.79082501 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 - 0.038779002 0.81607199 0.073301002 0.83981198 0.074841 0.80788898 0.12989099 - 0.871301 0.135956 0.83810002 0.073301002 0.83981198 0.063868999 0.91910303 - 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 0.063868999 - 0.91910303 0.17147 0.907399 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 - 0.862432 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 - 0.039615002 0.87295502 0.072558001 0.88500297 0.069305003 0.862432 0.052301999 - 0.89361697 0.072558001 0.88500297 0.039615002 0.87295502 0.029790999 0.85418802 - 0.039615002 0.87295502 0.073301002 0.83981198 0.073301002 0.83981198 0.039615002 - 0.87295502 0.069305003 0.862432 0.029790999 0.85418802 0.0086899996 0.90104598 - 0.039615002 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.039615002 - 0.87295502 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 - 0.83981198 0.135956 0.83810002 0.133753 0.80051601 0.17147 0.907399 0.063868999 - 0.91910303 0.14566401 0.93838102 0.60618597 0.86918902 0.61128402 0.83876997 - 0.56233603 0.85706103 0.193271 0.88191301 0.21379501 0.846349 0.209691 0.79815799 - 0.193271 0.88191301 0.225722 0.86254603 0.21379501 0.846349 0.21379501 0.846349 - 0.225722 0.86254603 0.237334 0.83964097 0.12989099 0.871301 0.17147 0.907399 - 0.193271 0.88191301 0.193271 0.88191301 0.17147 0.907399 0.23810799 0.94020498 - 0.115455 0.77456403 0.133753 0.80051601 0.134497 0.74599701 0.133753 0.80051601 - 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193271 0.88191301 - 0.209691 0.79815799 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 - 0.237334 0.83964097 0.225722 0.86254603 0.26639199 0.865004 0.81364501 0.66707098 - 0.85311198 0.64641303 0.84326202 0.52863598 0.193271 0.88191301 0.23810799 - 0.94020498 0.26639199 0.865004 0.81364501 0.66707098 0.84326202 0.52863598 - 0.80370599 0.60544503 0.237334 0.83964097 0.26639199 0.865004 0.32067001 - 0.79166698 0.237334 0.83964097 0.32067001 0.79166698 0.30680701 0.75846398 - 0.21379501 0.846349 0.237334 0.83964097 0.209691 0.79815799 0.133753 0.80051601 - 0.189914 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.193901 0.70055801 0.209691 0.79815799 - 0.235135 0.75121701 0.193901 0.70055801 0.193901 0.70055801 0.235135 0.75121701 - 0.23119999 0.70723599 0.209691 0.79815799 0.237334 0.83964097 0.235135 0.75121701 - 0.235135 0.75121701 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 - 0.30680701 0.75846398 0.23119999 0.70723599 0.80370599 0.60544503 0.81960201 - 0.54509503 0.76481098 0.59411001 0.30680701 0.75846398 0.32067001 0.79166698 - 0.33192599 0.74883097 0.30680701 0.75846398 0.33192599 0.74883097 0.33425501 - 0.67281002 0.193901 0.70055801 0.23119999 0.70723599 0.218197 0.66097301 - 0.218197 0.66097301 0.23119999 0.70723599 0.27809399 0.63370502 0.76481098 - 0.59411001 0.773857 0.53407699 0.73045999 0.53145701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.773857 0.53407699 0.81960201 0.54509503 0.82335901 - 0.49983799 0.773857 0.53407699 0.214571 0.58170599 0.29069301 0.56685197 - 0.241578 0.53054398 0.214571 0.58170599 0.27809399 0.63370502 0.29069301 - 0.56685197 0.218197 0.66097301 0.27809399 0.63370502 0.214571 0.58170599 - 0.191866 0.64202601 0.218197 0.66097301 0.214571 0.58170599 0.181797 0.58704501 - 0.214571 0.58170599 0.241578 0.53054398 0.227768 0.50040001 0.181797 0.58704501 - 0.241578 0.53054398 0.181797 0.58704501 0.191866 0.64202601 0.214571 0.58170599 - 0.193901 0.70055801 0.218197 0.66097301 0.191866 0.64202601 0.227768 0.50040001 - 0.35016599 0.53974301 0.34836701 0.49853599 0.227768 0.50040001 0.241578 - 0.53054398 0.35016599 0.53974301 0.302367 0.46158099 0.415775 0.44801801 - 0.33645499 0.40632701 0.302367 0.46158099 0.34836701 0.49853599 0.415775 - 0.44801801 0.49755499 0.488251 0.48631501 0.53582197 0.55817002 0.495579 - 0.44446999 0.51254302 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.55817002 0.495579 0.53173602 0.43147901 0.134497 0.74599701 0.16243599 - 0.73647797 0.137054 0.71443301 0.16243599 0.73647797 0.133753 0.80051601 - 0.193901 0.70055801 0.134497 0.74599701 0.133753 0.80051601 0.16243599 0.73647797 - 0.137054 0.71443301 0.16243599 0.73647797 0.155361 0.68448699 0.137054 0.71443301 - 0.155361 0.68448699 0.135434 0.64463699 0.038779002 0.81607199 0.029790999 - 0.85418802 0.073301002 0.83981198 0.17482001 0.65435803 0.193901 0.70055801 - 0.191866 0.64202601 0.16243599 0.73647797 0.193901 0.70055801 0.17482001 - 0.65435803 0.155361 0.68448699 0.16243599 0.73647797 0.17482001 0.65435803 - 0.17482001 0.65435803 0.191866 0.64202601 0.181797 0.58704501 0.17482001 - 0.65435803 0.152937 0.59559798 0.134919 0.61088699 0.152937 0.59559798 0.17482001 - 0.65435803 0.181797 0.58704501 0.227768 0.50040001 0.34836701 0.49853599 - 0.302367 0.46158099 0.152937 0.59559798 0.181797 0.58704501 0.17433301 0.53156102 - 0.17433301 0.53156102 0.181797 0.58704501 0.227768 0.50040001 0.302367 0.46158099 - 0.33645499 0.40632701 0.24266601 0.36897901 0.50244898 0.644642 0.55341202 - 0.63760501 0.493588 0.62263501 0.155361 0.68448699 0.17482001 0.65435803 - 0.135434 0.64463699 0.135434 0.64463699 0.17482001 0.65435803 0.134919 0.61088699 - 0.19817799 0.43839601 0.195015 0.48982099 0.235855 0.44651899 0.19817799 - 0.43839601 0.235855 0.44651899 0.216538 0.39981201 0.235855 0.44651899 0.302367 - 0.46158099 0.24266601 0.36897901 0.17433301 0.53156102 0.227768 0.50040001 - 0.195015 0.48982099 0.195015 0.48982099 0.227768 0.50040001 0.235855 0.44651899 - 0.216538 0.39981201 0.235855 0.44651899 0.24266601 0.36897901 0.202446 0.3633 - 0.216538 0.39981201 0.24266601 0.36897901 0.50988603 0.60414898 0.52967697 - 0.561248 0.471468 0.56798297 0.55527902 0.8071 0.612091 0.80211103 0.61429799 - 0.75036502 0.61128402 0.83876997 0.612091 0.80211103 0.55527902 0.8071 0.86997002 - 0.93731803 0.79334199 0.99322498 0.81753498 0.92918402 0.85467398 0.99159998 - 0.79334199 0.99322498 0.86997002 0.93731803 0.81753498 0.92918402 0.71710402 - 0.94957799 0.75108498 0.90098101 0.75108498 0.90098101 0.71710402 0.94957799 - 0.681234 0.89455098 0.81753498 0.92918402 0.79334199 0.99322498 0.71710402 - 0.94957799 0.71957898 0.86809897 0.681234 0.89455098 0.68843299 0.845505 - 0.848369 0.70362002 0.84964103 0.74003702 0.77899301 0.67823797 0.77644902 - 0.63733798 0.848369 0.70362002 0.77899301 0.67823797 0.82964599 0.80204397 - 0.79684901 0.86380398 0.78393102 0.81632203 0.77644902 0.63733798 0.77899301 - 0.67823797 0.72519898 0.67094803 0.77899301 0.67823797 0.74377102 0.72034299 - 0.72519898 0.67094803 0.74377102 0.72034299 0.71176398 0.71938401 0.72519898 - 0.67094803 0.75108498 0.90098101 0.681234 0.89455098 0.71957898 0.86809897 - 0.81753498 0.92918402 0.75108498 0.90098101 0.79684901 0.86380398 0.71957898 - 0.86809897 0.68843299 0.845505 0.718126 0.82873601 0.79684901 0.86380398 - 0.75108498 0.90098101 0.71957898 0.86809897 0.79684901 0.86380398 0.71957898 - 0.86809897 0.78393102 0.81632203 0.78393102 0.81632203 0.71957898 0.86809897 - 0.718126 0.82873601 0.75086302 0.78398401 0.718126 0.82873601 0.71901399 - 0.78532398 0.78393102 0.81632203 0.718126 0.82873601 0.75086302 0.78398401 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.27809399 0.63370502 0.50365102 0.81889403 - 0.55527902 0.8071 0.56181002 0.765275 0.50365102 0.81889403 0.484781 0.85584599 - 0.55527902 0.8071 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.78915399 0.74251801; - setAttr ".uvst[0].uvsp[750:999]" 0.86997002 0.93731803 0.81753498 - 0.92918402 0.82964599 0.80204397 0.81753498 0.92918402 0.79684901 0.86380398 - 0.82964599 0.80204397 0.86997002 0.93731803 0.82964599 0.80204397 0.84964103 - 0.74003702 0.074841 0.80788898 0.073301002 0.83981198 0.133753 0.80051601 - 0.074841 0.80788898 0.133753 0.80051601 0.115455 0.77456403 0.35912099 0.27489001 - 0.39272901 0.33256099 0.316248 0.291545 0.33604199 0.25541499 0.35912099 - 0.27489001 0.316248 0.291545 0.47097301 0.28257099 0.39272901 0.33256099 - 0.35912099 0.27489001 0.47097301 0.28257099 0.55185699 0.34580401 0.39272901 - 0.33256099 0.52854401 0.261291 0.55324697 0.28502101 0.47097301 0.28257099 - 0.55324697 0.28502101 0.55185699 0.34580401 0.47097301 0.28257099 0.31703201 - 0.24954499 0.33604199 0.25541499 0.316248 0.291545 0.31351399 0.202804 0.31703201 - 0.24954499 0.258811 0.22176901 0.31703201 0.24954499 0.316248 0.291545 0.255613 - 0.25320399 0.316248 0.291545 0.26878601 0.315254 0.255613 0.25320399 0.532996 - 0.217034 0.52854401 0.261291 0.400451 0.218311 0.53191298 0.15157899 0.400451 - 0.218311 0.35348001 0.188078 0.37215099 0.13412 0.53191298 0.15157899 0.35348001 - 0.188078 0.400451 0.218311 0.35912099 0.27489001 0.33604199 0.25541499 0.35348001 - 0.188078 0.400451 0.218311 0.33604199 0.25541499 0.35348001 0.188078 0.33604199 - 0.25541499 0.31703201 0.24954499 0.400451 0.218311 0.47097301 0.28257099 - 0.35912099 0.27489001 0.52854401 0.261291 0.47097301 0.28257099 0.400451 - 0.218311 0.32905 0.12617201 0.35348001 0.188078 0.31351399 0.202804 0.35348001 - 0.188078 0.31703201 0.24954499 0.31351399 0.202804 0.151114 0.233711 0.194934 - 0.29608399 0.128057 0.28853801 0.19205201 0.23548099 0.194934 0.29608399 - 0.151114 0.233711 0.26878601 0.315254 0.21787301 0.34819999 0.194934 0.29608399 - 0.32905 0.12617201 0.31351399 0.202804 0.271054 0.13361099 0.31335899 0.057027001 - 0.25301799 0.068204001 0.245719 0.014829 0.57874799 0.472913 0.591959 0.53098297 - 0.55444598 0.474244 0.60980803 0.47876301 0.639902 0.47827199 0.62550402 - 0.53194499 0.60980803 0.47876301 0.62550402 0.53194499 0.60595697 0.51647699 - 0.88900101 0.68397403 0.92526799 0.68932003 0.86200303 0.72877699 0.88900101 - 0.68397403 0.89971602 0.66068798 0.92526799 0.68932003 0.57874799 0.472913 - 0.60980803 0.47876301 0.591959 0.53098297 0.63387299 0.382061 0.58532703 - 0.345817 0.66333002 0.35212901 0.63387299 0.382061 0.610578 0.38000399 0.58532703 - 0.345817 0.610578 0.38000399 0.60697401 0.39847901 0.58532703 0.345817 0.60697401 - 0.39847901 0.57874799 0.472913 0.55444598 0.474244 0.591959 0.53098297 0.60980803 - 0.47876301 0.60595697 0.51647699 0.86512601 0.68251401 0.88900101 0.68397403 - 0.86200303 0.72877699 0.056297999 0.091900997 0.080518 0.123654 0.039241001 - 0.118589 0.039241001 0.118589 0.080518 0.123654 0.020680999 0.143217 0.070349 - 0.165839 0.069355004 0.21782801 0.041522998 0.25432399 0.60697401 0.39847901 - 0.61546803 0.418973 0.57874799 0.472913 0.61546803 0.418973 0.63182598 0.41617399 - 0.639902 0.47827199 0.63182598 0.41617399 0.64173597 0.390975 0.639902 0.47827199 - 0.036951002 0.29172301 0.128057 0.28853801 0.016138 0.325297 0.128057 0.28853801 - 0.048168998 0.35214001 0.016138 0.325297 0.070349 0.165839 0.041522998 0.25432399 - 0.027048999 0.208827 0.020680999 0.143217 0.070349 0.165839 0.027048999 0.208827 - 0.080518 0.123654 0.070349 0.165839 0.020680999 0.143217 0.194934 0.29608399 - 0.21787301 0.34819999 0.128057 0.28853801 0.271054 0.13361099 0.056297999 - 0.091900997 0.062045 0.057544 0.271054 0.13361099 0.080518 0.123654 0.056297999 - 0.091900997 0.61546803 0.418973 0.60697401 0.39847901 0.617971 0.407262 0.61546803 - 0.418973 0.617971 0.407262 0.63182598 0.41617399 0.64173597 0.390975 0.63387299 - 0.382061 0.66333002 0.35212901 0.97766298 0.79651397 0.94665498 0.81503397 - 0.86200303 0.72877699 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 - 0.72877699 0.92526799 0.68932003 0.93663901 0.729617 0.86200303 0.72877699 - 0.639902 0.47827199 0.665824 0.44352099 0.65543997 0.49157101 0.639902 0.47827199 - 0.64173597 0.390975 0.665824 0.44352099 0.665824 0.44352099 0.64173597 0.390975 - 0.66333002 0.35212901 0.58532703 0.345817 0.60697401 0.39847901 0.55444598 - 0.474244 0.37215099 0.13412 0.35348001 0.188078 0.32905 0.12617201 0.57477999 - 0.25117901 0.602754 0.257723 0.55324697 0.28502101 0.61704302 0.20689499 - 0.602754 0.257723 0.57477999 0.25117901 0.56468099 0.099036001 0.61118603 - 0.156872 0.53191298 0.15157899 0.602754 0.257723 0.64614099 0.22702 0.60898602 - 0.28752601 0.61704302 0.20689499 0.64614099 0.22702 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.255613 0.25320399 0.26878601 0.315254 0.194934 - 0.29608399 0.216565 0.237138 0.255613 0.25320399 0.194934 0.29608399 0.216565 - 0.237138 0.194934 0.29608399 0.19205201 0.23548099 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.42296299 0.00556 0.64614099 0.22702 0.627464 0.31886399 - 0.60898602 0.28752601 0.47337201 0.42365801 0.53173602 0.43147901 0.47644299 - 0.39616501 0.57477999 0.25117901 0.55324697 0.28502101 0.52854401 0.261291 - 0.60898602 0.28752601 0.627464 0.31886399 0.58940798 0.33751199 0.42296299 - 0.00556 0.475099 0.076341003 0.359846 0.051763002 0.53150898 0.049988002; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.42296299 0.00556 - 0.475099 0.076341003 0.53191298 0.15157899 0.37215099 0.13412 0.47644299 - 0.39616501 0.53173602 0.43147901 0.53674299 0.39848399 0.47644299 0.39616501 - 0.53674299 0.39848399 0.47946599 0.37119001 0.61118603 0.156872 0.61704302 - 0.20689499 0.53191298 0.15157899 0.271054 0.13361099 0.31351399 0.202804 - 0.22066 0.18181901 0.53191298 0.15157899 0.532996 0.217034 0.400451 0.218311 - 0.532996 0.217034 0.57477999 0.25117901 0.52854401 0.261291 0.53746098 0.37084499 - 0.54082298 0.34952399 0.48070699 0.35210899 0.56216699 0.060766999 0.56468099 - 0.099036001 0.529387 0.082309 0.56216699 0.060766999 0.529387 0.082309 0.53150898 - 0.049988002 0.53150898 0.049988002 0.529387 0.082309 0.475099 0.076341003 - 0.529387 0.082309 0.53191298 0.15157899 0.475099 0.076341003 0.56468099 0.099036001 - 0.53191298 0.15157899 0.529387 0.082309 0.563384 0.216162 0.57477999 0.25117901 - 0.532996 0.217034 0.61704302 0.20689499 0.57477999 0.25117901 0.563384 0.216162 - 0.61704302 0.20689499 0.563384 0.216162 0.53191298 0.15157899 0.563384 0.216162 - 0.532996 0.217034 0.53191298 0.15157899 0.47946599 0.37119001 0.53674299 - 0.39848399 0.53746098 0.37084499 0.47946599 0.37119001 0.53746098 0.37084499 - 0.48070699 0.35210899 0.475099 0.076341003 0.37215099 0.13412 0.359846 0.051763002 - 0.258811 0.22176901 0.31703201 0.24954499 0.255613 0.25320399 0.60980803 - 0.47876301 0.61546803 0.418973 0.639902 0.47827199 0.61546803 0.418973 0.60980803 - 0.47876301 0.57874799 0.472913 0.041522998 0.25432399 0.128057 0.28853801 - 0.036951002 0.29172301 0.151114 0.233711 0.128057 0.28853801 0.102847 0.22989 - 0.102847 0.22989 0.128057 0.28853801 0.041522998 0.25432399 0.069355004 0.21782801 - 0.102847 0.22989 0.041522998 0.25432399 0.107695 0.172719 0.102847 0.22989 - 0.069355004 0.21782801 0.070349 0.165839 0.107695 0.172719 0.069355004 0.21782801 - 0.080518 0.123654 0.107695 0.172719 0.070349 0.165839 0.155274 0.177471 0.151114 - 0.233711 0.107695 0.172719 0.107695 0.172719 0.151114 0.233711 0.102847 0.22989 - 0.155274 0.177471 0.107695 0.172719 0.080518 0.123654 0.271054 0.13361099 - 0.155274 0.177471 0.080518 0.123654 0.271054 0.13361099 0.22066 0.18181901 - 0.155274 0.177471 0.39272901 0.33256099 0.32999301 0.33045399 0.316248 0.291545 - 0.316248 0.291545 0.32999301 0.33045399 0.26878601 0.315254 0.42296299 0.00556 - 0.359846 0.051763002 0.36022699 0.003454 0.62550402 0.53194499 0.639902 0.47827199 - 0.65543997 0.49157101 0.0040460001 0.25350901 0.036951002 0.29172301 0.016138 - 0.325297 0.027048999 0.208827 0.041522998 0.25432399 0.0040460001 0.25350901 - 0.041522998 0.25432399 0.036951002 0.29172301 0.0040460001 0.25350901 0.056297999 - 0.091900997 0.039241001 0.118589 0.039096002 0.044592999 0.062045 0.057544 - 0.056297999 0.091900997 0.039096002 0.044592999 0.065323003 0.030218 0.062045 - 0.057544 0.039096002 0.044592999 0.048168998 0.35214001 0.023626 0.35801601 - 0.016138 0.325297 0.22066 0.18181901 0.193956 0.19936 0.155274 0.177471 0.155274 - 0.177471 0.193956 0.19936 0.151114 0.233711 0.193956 0.19936 0.19205201 0.23548099 - 0.151114 0.233711 0.193956 0.19936 0.216565 0.237138 0.19205201 0.23548099 - 0.22066 0.18181901 0.216565 0.237138 0.193956 0.19936 0.49755499 0.488251 - 0.53173602 0.43147901 0.47337201 0.42365801 0.415775 0.44801801 0.49755499 - 0.488251 0.47337201 0.42365801 0.63806599 0.14799 0.64614099 0.22702 0.61118603 - 0.156872 0.63874 0.094846003 0.63806599 0.14799 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.56216699 0.060766999 0.64656198 0.069087997 - 0.63874 0.094846003 0.56216699 0.060766999 0.602754 0.257723 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55324697 0.28502101 0.57625401 0.29346699 0.55185699 - 0.34580401 0.57625401 0.29346699 0.58940798 0.33751199 0.55185699 0.34580401 - 0.60898602 0.28752601 0.58940798 0.33751199 0.57625401 0.29346699 0.602754 - 0.257723 0.60898602 0.28752601 0.57625401 0.29346699 0.35016599 0.53974301 - 0.44446999 0.51254302 0.34836701 0.49853599 0.44446999 0.51254302 0.49755499 - 0.488251 0.415775 0.44801801 0.34836701 0.49853599 0.44446999 0.51254302 - 0.415775 0.44801801 0.235855 0.44651899 0.227768 0.50040001 0.302367 0.46158099 - 0.316118 0.025185 0.31335899 0.057027001 0.245719 0.014829 0.359846 0.051763002 - 0.31335899 0.057027001 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 - 0.316118 0.025185 0.32999301 0.33045399 0.28588501 0.35218599 0.26878601 - 0.315254 0.26878601 0.315254 0.28588501 0.35218599 0.21787301 0.34819999 - 0.359846 0.051763002 0.37215099 0.13412 0.32905 0.12617201 0.31976199 0.096646003 - 0.271054 0.13361099 0.25301799 0.068204001 0.31976199 0.096646003 0.32905 - 0.12617201 0.271054 0.13361099 0.359846 0.051763002 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.31976199 0.096646003 0.31335899 0.057027001 - 0.31335899 0.057027001 0.31976199 0.096646003 0.25301799 0.068204001 0.128057 - 0.28853801 0.21787301 0.34819999 0.11848 0.325919 0.128057 0.28853801 0.11848 - 0.325919 0.048168998 0.35214001 0.245719 0.014829 0.25301799 0.068204001 - 0.142845 0.034219 0.25301799 0.068204001 0.271054 0.13361099 0.062045 0.057544 - 0.142845 0.034219 0.062045 0.057544 0.065323003 0.030218 0.142845 0.034219 - 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.062045 0.057544 0.258811 0.22176901 - 0.255613 0.25320399 0.216565 0.237138 0.258811 0.22176901 0.216565 0.237138 - 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 0.22066 0.18181901 - 0.84087598 0.31692401 0.86741501 0.373849 0.89018202 0.239971 0.82062 0.34356001 - 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 0.227217 0.84087598 - 0.31692401 0.89018202 0.239971 0.82062 0.34356001 0.84087598 0.31692401 0.84594899 - 0.227217 0.84594899 0.227217 0.89018202 0.239971 0.89836198 0.137126 0.814367 - 0.424068 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.82062 - 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 0.43314499 0.86741501 - 0.373849 0.82335901 0.49983799 0.88974899 0.43314499 0.814367 0.424068 0.814367 - 0.424068 0.79613203 0.35278401 0.76275897 0.37884799 0.82062 0.34356001 0.814367 - 0.424068 0.86741501 0.373849 0.773857 0.53407699 0.82335901 0.49983799 0.814367 - 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.73045999 0.53145701 0.773857 - 0.53407699 0.814367 0.424068 0.779073 0.44323799 0.83935702 0.100765 0.84594899 - 0.227217 0.89836198 0.137126 0.79802299 0.211936 0.84594899 0.227217 0.83935702 - 0.100765 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.87032902 - 0.045508999 0.83935702 0.100765 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.83935702 0.100765 0.83545703 0.043729 0.818169 - 0.062284999 0.89018202 0.239971 0.966021 0.28052899 0.95396501 0.134362 0.89018202 - 0.239971 0.89975703 0.32890701 0.966021 0.28052899 0.89018202 0.239971 0.86741501 - 0.373849 0.89975703 0.32890701 0.79613203 0.35278401 0.79802299 0.211936 - 0.76275897 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 - 0.74679601 0.45871499 0.779073 0.44323799 0.76275897 0.37884799 0.74679601 - 0.45871499 0.76275897 0.37884799 0.733105 0.37849101 0.68089098 0.41862199 - 0.70178902 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 - 0.45871499 0.71095902 0.44087201 0.73045999 0.53145701 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.779073 0.44323799 0.74679601 - 0.45871499 0.71095902 0.44087201 0.74679601 0.45871499 0.733105 0.37849101 - 0.89836198 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 - 0.031078 0.89836198 0.137126 0.97778797 0.040635999 0.966021 0.28052899 0.89975703 - 0.32890701 0.99264401 0.396844 0.966021 0.28052899 0.99264401 0.396844 0.99426401 - 0.26670301 0.68089098 0.41862199 0.71095902 0.44087201 0.65865201 0.27080399 - 0.65865201 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 - 0.20985 0.65865201 0.27080399 0.70381802 0.225641 0.95396501 0.134362 0.966021 - 0.28052899 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 - 0.98321998 0.20574901 0.89836198 0.137126 0.89018202 0.239971 0.95396501 - 0.134362 0.66965002 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 - 0.006691 0.66965002 0.116933 0.70381802 0.225641 0.66478199 0.0078290002 - 0.66965002 0.116933 0.719881 0.006691 0.733105 0.37849101 0.73960102 0.22293501 - 0.70381802 0.225641 0.71095902 0.44087201 0.733105 0.37849101 0.70381802 - 0.225641 0.733105 0.37849101 0.76275897 0.37884799 0.73960102 0.22293501 - 0.76275897 0.37884799 0.79802299 0.211936 0.76523697 0.19111399 0.76275897 - 0.37884799 0.76523697 0.19111399 0.73960102 0.22293501 0.73960102 0.22293501 - 0.75811899 0.0040250001 0.719881 0.006691 0.79802299 0.211936 0.83935702 - 0.100765 0.818169 0.062284999 0.79802299 0.211936 0.818169 0.062284999 0.76523697 - 0.19111399 0.73960102 0.22293501 0.719881 0.006691 0.70381802 0.225641 0.76523697 - 0.19111399 0.75811899 0.0040250001 0.73960102 0.22293501 0.98507398 0.893085 - 0.94037199 0.870426 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 - 0.893085 0.95050299 0.82310897 0.90755701 0.964562 0.86997002 0.93731803 - 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 0.98405302 0.91405201 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.85467398 0.99159998 0.86997002 0.93731803 0.98405302 0.91405201 0.94037199 - 0.870426 0.98507398 0.893085 0.98405302 0.91405201 0.94326001 0.89290702 - 0.94037199 0.870426 0.94326001 0.89290702 0.909796 0.8951 0.94037199 0.870426 - 0.95050299 0.82310897 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 - 0.909796 0.8951 0.91257 0.81947201 0.91257 0.81947201 0.909796 0.8951 0.84964103 - 0.74003702 0.909796 0.8951 0.86997002 0.93731803 0.84964103 0.74003702 0.66562402 - 0.92713302 0.68109202 0.85573 0.63363802 0.89377397 0.818169 0.062284999 - 0.83545703 0.043729 0.804057 0.01567 0.818169 0.062284999 0.804057 0.01567 - 0.78658998 0.052133001 0.87032902 0.045508999 0.90803403 0.044094998 0.86865902 - 0.013712 0.86865902 0.013712 0.90803403 0.044094998 0.94019401 0.031078 0.83545703 - 0.043729 0.87032902 0.045508999 0.86865902 0.013712 0.83545703 0.043729 0.86865902 - 0.013712 0.804057 0.01567 0.78658998 0.052133001 0.804057 0.01567 0.75811899 - 0.0040250001 0.33735099 0.85548198 0.33477801 0.909235 0.32756099 0.89249802 - 0.33735099 0.85548198 0.34354001 0.86769497 0.33477801 0.909235 0.34659299 - 0.92080897 0.371288 0.86448097 0.35936901 0.91262299 0.359723 0.87225002 - 0.371288 0.86448097 0.34659299 0.92080897; - setAttr ".uvst[0].uvsp[1500:1749]" 0.359723 0.87225002 0.34659299 0.92080897 - 0.33477801 0.909235 0.34354001 0.86769497 0.359723 0.87225002 0.33477801 - 0.909235 0.44578099 0.93405002 0.45333701 0.95817798 0.48538801 0.95112503 - 0.48168799 0.91676801 0.44578099 0.93405002 0.48538801 0.95112503 0.42452699 - 0.94267398 0.43036199 0.96655297 0.45333701 0.95817798 0.44578099 0.93405002 - 0.42452699 0.94267398 0.45333701 0.95817798 0.352687 0.831747 0.34354001 - 0.86769497 0.33735099 0.85548198 0.34862399 0.80891901 0.352687 0.831747 - 0.33735099 0.85548198 0.368599 0.83635598 0.359723 0.87225002 0.34354001 - 0.86769497 0.352687 0.831747 0.368599 0.83635598 0.34354001 0.86769497 0.368599 - 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 0.359723 0.87225002 - 0.368599 0.83635598 0.371288 0.86448097 0.43036199 0.96655297 0.42452699 - 0.94267398 0.39850101 0.96660697 0.35968399 0.81033999 0.34862399 0.80891901 - 0.37021199 0.79415601 0.35968399 0.81033999 0.352687 0.831747 0.34862399 - 0.80891901 0.368599 0.83635598 0.352687 0.831747 0.35968399 0.81033999 0.37179601 - 0.81299299 0.368599 0.83635598 0.35968399 0.81033999 0.38256299 0.81765997 - 0.37179601 0.81299299 0.37021199 0.79415601 0.368599 0.83635598 0.37179601 - 0.81299299 0.38256299 0.81765997 0.37179601 0.81299299 0.35968399 0.81033999 - 0.37021199 0.79415601 0.308972 0.86521697 0.30324501 0.90815997 0.29274601 - 0.90635097 0.300255 0.86195898 0.308972 0.86521697 0.29274601 0.90635097 - 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 0.89249802 0.31726399 - 0.91030401 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 0.86521697 0.32226399 - 0.867616 0.30324501 0.90815997 0.46022999 0.96179903 0.46529901 0.98378903 - 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 0.96179903 0.49160999 - 0.97508597 0.43152601 0.97203702 0.43633199 0.99328399 0.46529901 0.98378903 - 0.46022999 0.96179903 0.43152601 0.97203702 0.46529901 0.98378903 0.307354 - 0.82550597 0.308972 0.86521697 0.300255 0.86195898 0.31612 0.82580698 0.308972 - 0.86521697 0.307354 0.82550597 0.329963 0.82830203 0.32226399 0.867616 0.308972 - 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.308972 0.86521697 0.32226399 - 0.867616 0.33719999 0.843934 0.33101901 0.87009001 0.32226399 0.867616 0.329963 - 0.82830203 0.33719999 0.843934 0.43152601 0.97203702 0.405705 0.98896497 - 0.43633199 0.99328399 0.329963 0.82830203 0.31612 0.82580698 0.32305399 0.80920303 - 0.33029699 0.81221998 0.329963 0.82830203 0.32305399 0.80920303 0.33029699 - 0.81221998 0.32305399 0.80920303 0.33178499 0.78945303 0.38630301 0.87709397 - 0.38328499 0.85446298 0.39264601 0.86977398 0.38630301 0.87709397 0.380456 - 0.87159598 0.38328499 0.85446298 0.376625 0.895226 0.380456 0.87159598 0.38630301 - 0.87709397 0.39264601 0.86977398 0.38328499 0.85446298 0.38593799 0.83733201 - 0.38863 0.90287602 0.38630301 0.87709397 0.39264601 0.86977398 0.40770999 - 0.866552 0.39264601 0.86977398 0.38593799 0.83733201 0.44178799 0.92605698 - 0.43939599 0.911412 0.42723399 0.92242002 0.38328499 0.85446298 0.37287301 - 0.875799 0.38593799 0.83733201 0.38863 0.90287602 0.39264601 0.86977398 0.40770999 - 0.866552 0.376625 0.895226 0.36011499 0.92878401 0.36799499 0.89132202 0.36799499 - 0.89132202 0.36011499 0.92878401 0.35936901 0.91262299 0.37287301 0.875799 - 0.380456 0.87159598 0.36799499 0.89132202 0.380456 0.87159598 0.376625 0.895226 - 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 0.875799 0.38328499 - 0.85446298 0.36011499 0.92878401 0.34659299 0.92080897 0.35936901 0.91262299 - 0.33477801 0.909235 0.31726399 0.91030401 0.32756099 0.89249802 0.40901801 - 0.89674503 0.40770999 0.866552 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 - 0.920587 0.381246 0.95752001 0.36011499 0.92878401 0.376625 0.895226 0.381246 - 0.95752001 0.376625 0.895226 0.38863 0.90287602 0.381246 0.95752001 0.376625 - 0.895226 0.38630301 0.87709397 0.38863 0.90287602 0.33891901 0.987975 0.36011499 - 0.92878401 0.381246 0.95752001 0.36011499 0.92878401 0.32005399 0.97494799 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.34659299 0.92080897 0.32005399 0.97494799 0.33477801 0.909235 - 0.31726399 0.91030401 0.300001 0.97013903 0.30324501 0.90815997 0.29274601 - 0.90635097 0.30324501 0.90815997 0.28796199 0.92390901 0.30324501 0.90815997 - 0.290243 0.940907 0.28796199 0.92390901 0.28796199 0.92390901 0.270601 0.92593902 - 0.27395099 0.912489 0.28796199 0.92390901 0.290243 0.940907 0.270601 0.92593902 - 0.27395099 0.912489 0.270601 0.92593902 0.258212 0.91232401 0.270601 0.92593902 - 0.25671601 0.927858 0.258212 0.91232401 0.30324501 0.90815997 0.300001 0.97013903 - 0.290243 0.940907 0.300001 0.97013903 0.283005 0.96905398 0.290243 0.940907 - 0.290243 0.940907 0.283005 0.96905398 0.270601 0.92593902 0.270601 0.92593902 - 0.283005 0.96905398 0.25671601 0.927858 0.35122901 1.000869 0.381246 0.95752001 - 0.369001 0.99685502 0.33891901 0.987975 0.381246 0.95752001 0.35122901 1.000869 - 0.283005 0.96905398 0.25706601 0.969437 0.25671601 0.927858 0.54497999 0.877047 - 0.53121799 0.86490297 0.53719902 0.90499997 0.54497999 0.877047 0.53719902 - 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 0.52387398 0.97127301 - 0.53666401 0.96573699 0.521644 0.96135998 0.52387398 0.97127301 0.54059702 - 0.94349098 0.55496401 0.97537702; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.54084498 - 0.98507202 0.55496401 0.97537702 0.54059702 0.94349098 0.53666401 0.96573699 - 0.27759501 0.89841598 0.258212 0.91232401 0.262528 0.89503402 0.27395099 - 0.912489 0.258212 0.91232401 0.27759501 0.89841598 0.291614 0.896658 0.27395099 - 0.912489 0.27759501 0.89841598 0.291614 0.896658 0.28940701 0.91069198 0.27395099 - 0.912489 0.52387398 0.97127301 0.51558298 0.98070103 0.52629602 0.99024498 - 0.53666401 0.96573699 0.52387398 0.97127301 0.52629602 0.99024498 0.54084498 - 0.98507202 0.52629602 0.99024498 0.52678698 0.99600202 0.53666401 0.96573699 - 0.52629602 0.99024498 0.54084498 0.98507202 0.27759501 0.89841598 0.262528 - 0.89503402 0.26901299 0.87969601 0.282882 0.883295 0.27759501 0.89841598 - 0.26901299 0.87969601 0.29319 0.88515502 0.27759501 0.89841598 0.282882 0.883295 - 0.29319 0.88515502 0.291614 0.896658 0.27759501 0.89841598 0.52629602 0.99024498 - 0.50723398 0.99519998 0.52678698 0.99600202 0.28712299 0.87004602 0.282882 - 0.883295 0.26901299 0.87969601 0.28712299 0.87004602 0.29319 0.88515502 0.282882 - 0.883295 0.51558298 0.98070103 0.50723398 0.99519998 0.52629602 0.99024498 - 0.28940701 0.91069198 0.28796199 0.92390901 0.27395099 0.912489 0.56407797 - 0.91909999 0.53719902 0.90499997 0.54059702 0.94349098 0.56407797 0.91909999 - 0.54059702 0.94349098 0.56377 0.96770799 0.56377 0.96770799 0.54059702 0.94349098 - 0.55496401 0.97537702 0.44178799 0.92605698 0.45468801 0.92364502 0.45547101 - 0.90422702 0.44178799 0.92605698 0.45547101 0.90422702 0.43939599 0.911412 - 0.40770999 0.866552 0.41640201 0.88049698 0.41693899 0.89492601 0.39948201 - 0.920587 0.38863 0.90287602 0.40770999 0.866552 0.39948201 0.920587 0.40770999 - 0.866552 0.40901801 0.89674503 0.41201699 0.92887998 0.40901801 0.89674503 - 0.41693899 0.89492601 0.39948201 0.920587 0.40901801 0.89674503 0.41201699 - 0.92887998 0.45547101 0.90422702 0.46091801 0.88338 0.44038501 0.90504903 - 0.381246 0.95752001 0.39948201 0.920587 0.41201699 0.92887998 0.381246 0.95752001 - 0.41201699 0.92887998 0.39207101 0.96583498 0.45547101 0.90422702 0.45468801 - 0.92364502 0.48168799 0.91676801 0.45547101 0.90422702 0.48168799 0.91676801 - 0.496647 0.874951 0.46091801 0.88338 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.49597099 0.91574198 0.496647 0.874951 0.48538801 - 0.95112503 0.49160999 0.97508597 0.50320703 0.95512199 0.49597099 0.91574198 - 0.48538801 0.95112503 0.50320703 0.95512199 0.48168799 0.91676801 0.48538801 - 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 0.51486897 0.97433299 - 0.521644 0.96135998 0.50320703 0.95512199 0.49160999 0.97508597 0.51486897 - 0.97433299 0.496647 0.874951 0.49597099 0.91574198 0.53719902 0.90499997 - 0.53719902 0.90499997 0.521644 0.96135998 0.54059702 0.94349098 0.49597099 - 0.91574198 0.50320703 0.95512199 0.53719902 0.90499997 0.53719902 0.90499997 - 0.50320703 0.95512199 0.521644 0.96135998 0.381246 0.95752001 0.39207101 - 0.96583498 0.369001 0.99685502 0.53121799 0.86490297 0.496647 0.874951 0.53719902 - 0.90499997 0.90803403 0.044094998 0.87032902 0.045508999 0.89836198 0.137126 - 0.90803403 0.044094998 0.89836198 0.137126 0.94019401 0.031078 0.76523697 - 0.19111399 0.78658998 0.052133001 0.75811899 0.0040250001 0.818169 0.062284999 - 0.78658998 0.052133001 0.76523697 0.19111399 0.32305399 0.80920303 0.31612 - 0.82580698 0.307354 0.82550597 0.33178499 0.78945303 0.32305399 0.80920303 - 0.307354 0.82550597 0.33719999 0.843934 0.33029699 0.81221998 0.33178499 - 0.78945303 0.329963 0.82830203 0.33029699 0.81221998 0.33719999 0.843934 - 0.78915399 0.74251801 0.74377102 0.72034299 0.77899301 0.67823797 0.84964103 - 0.74003702 0.78915399 0.74251801 0.77899301 0.67823797 0.84964103 0.74003702 - 0.82964599 0.80204397 0.78915399 0.74251801 0.694462 0.78577 0.69465202 0.75267702 - 0.71901399 0.78532398 0.718126 0.82873601 0.694462 0.78577 0.71901399 0.78532398 - 0.66842598 0.82617402 0.68843299 0.845505 0.694462 0.78577 0.718126 0.82873601 - 0.66842598 0.82617402 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 - 0.718126 0.82873601 0.32005399 0.97494799 0.300001 0.97013903 0.31726399 - 0.91030401 0.33477801 0.909235 0.32005399 0.97494799 0.31726399 0.91030401 - 0.39220601 0.76434302 0.38921699 0.788423 0.44672099 0.742163 0.38921699 - 0.788423 0.40665799 0.802068 0.44672099 0.742163 0.44672099 0.742163 0.40665799 - 0.802068 0.476217 0.727027 0.62646401 0.95210898 0.66562402 0.92713302 0.63363802 - 0.89377397 0.65396702 0.95580101 0.66562402 0.92713302 0.62646401 0.95210898 - 0.71901399 0.78532398 0.69465202 0.75267702 0.71984899 0.75139397 0.75086302 - 0.78398401 0.71901399 0.78532398 0.75477803 0.76254302 0.75477803 0.76254302 - 0.71901399 0.78532398 0.71984899 0.75139397 0.65045398 0.98993599 0.62603098 - 0.97777802 0.62701303 0.95989603 0.653786 0.972588 0.65045398 0.98993599 - 0.62701303 0.95989603 0.72957599 0.74754602 0.69725502 0.74743497 0.71176398 - 0.71938401 0.74377102 0.72034299 0.72957599 0.74754602 0.71176398 0.71938401 - 0.78915399 0.74251801 0.72957599 0.74754602 0.74377102 0.72034299 0.78915399 - 0.74251801 0.76598603 0.762146 0.72957599 0.74754602 0.97251898 0.99150902 - 0.95559901 0.985829 0.96395802 0.96951902 0.982153 0.97301102 0.97251898 - 0.99150902 0.96395802 0.96951902 0.64994597 0.70058 0.65568203 0.65436798 - 0.70140499 0.66365999 0.69391102 0.70558798 0.64994597 0.70058 0.70140499 - 0.66365999 0.60770202 0.71877599 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.69391102 0.70558798 0.658795 0.73315901 - 0.60770202 0.71877599 0.69391102 0.70558798 0.70140499 0.66365999 0.62879598 - 0.619084 0.68494898 0.62769097 0.70140499 0.66365999 0.65568203 0.65436798 - 0.62879598 0.619084 0.65568203 0.65436798 0.60452098 0.662067 0.62879598 - 0.619084 0.64994597 0.70058 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60770202 0.71877599 0.60452098 0.662067 0.904742 0.61987799 0.86585498 - 0.608989 0.892663 0.58372599 0.892663 0.58372599 0.86585498 0.608989 0.88192099 - 0.50762999 0.86585498 0.608989 0.84326202 0.52863598 0.88192099 0.50762999 - 0.94025302 0.64341003 0.90890902 0.65339601 0.93670201 0.60081297 0.90890902 - 0.65339601 0.904742 0.61987799 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.96222198 0.59601402 0.904742 0.61987799 0.892663 - 0.58372599 0.93670201 0.60081297 0.93670201 0.60081297 0.892663 0.58372599 - 0.88192099 0.50762999 0.93670201 0.60081297 0.88192099 0.50762999 0.91139501 - 0.52158397 0.96222198 0.59601402 0.93670201 0.60081297 0.91139501 0.52158397 - 0.493588 0.62263501 0.44557601 0.62202299 0.47251999 0.59212297 0.493588 - 0.62263501 0.46083799 0.64259601 0.44557601 0.62202299 0.46083799 0.64259601 - 0.422638 0.66873902 0.44557601 0.62202299 0.50988603 0.60414898 0.47251999 - 0.59212297 0.471468 0.56798297 0.50988603 0.60414898 0.493588 0.62263501 - 0.47251999 0.59212297 0.43200499 0.70468998 0.422638 0.66873902 0.46083799 - 0.64259601 0.469937 0.66459 0.43200499 0.70468998 0.46083799 0.64259601 0.469937 - 0.66459 0.46083799 0.64259601 0.50244898 0.644642 0.50244898 0.644642 0.46083799 - 0.64259601 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.50988603 0.60414898 0.55948597 0.61438298 0.55341202 0.63760501 0.493588 - 0.62263501 0.476217 0.727027 0.469937 0.66459 0.50244898 0.644642 0.56032002 - 0.70486701 0.476217 0.727027 0.50244898 0.644642 0.56032002 0.70486701 0.578484 - 0.726412 0.476217 0.727027 0.578484 0.726412 0.56181002 0.765275 0.476217 - 0.727027 0.50365102 0.81889403 0.484781 0.85584599 0.47210601 0.79053301 - 0.50365102 0.81889403 0.47210601 0.79053301 0.56181002 0.765275 0.56181002 - 0.765275 0.47210601 0.79053301 0.476217 0.727027 0.484781 0.85584599 0.401124 - 0.82737499 0.47210601 0.79053301 0.484781 0.85584599 0.42608401 0.89203 0.401124 - 0.82737499 0.47210601 0.79053301 0.401124 0.82737499 0.40665799 0.802068 - 0.47210601 0.79053301 0.40665799 0.802068 0.476217 0.727027 0.44557601 0.62202299 - 0.43095401 0.61518103 0.47251999 0.59212297 0.47251999 0.59212297 0.43095401 - 0.61518103 0.471468 0.56798297 0.471468 0.56798297 0.37521201 0.59356803 - 0.44446999 0.51254302 0.43095401 0.61518103 0.37521201 0.59356803 0.471468 - 0.56798297 0.422638 0.66873902 0.43095401 0.61518103 0.44557601 0.62202299 - 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 - 0.66873902 0.402172 0.66881698 0.37521201 0.59356803 0.476217 0.727027 0.44672099 - 0.742163 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.469937 - 0.66459 0.44672099 0.742163 0.39220601 0.76434302 0.43200499 0.70468998 0.39220601 - 0.76434302 0.37832099 0.73359799 0.43200499 0.70468998 0.37832099 0.73359799 - 0.41114399 0.69965303 0.43200499 0.70468998 0.43200499 0.70468998 0.41114399 - 0.69965303 0.422638 0.66873902 0.422638 0.66873902 0.41114399 0.69965303 - 0.402172 0.66881698 0.41114399 0.69965303 0.37832099 0.73359799 0.402172 - 0.66881698 0.58906102 0.696136 0.55341202 0.63760501 0.590801 0.64542502 - 0.58906102 0.696136 0.56032002 0.70486701 0.55341202 0.63760501 0.55341202 - 0.63760501 0.56032002 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 - 0.594082 0.62339002 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.48631501 0.53582197 0.471468 0.56798297 0.44446999 - 0.51254302 0.52967697 0.561248 0.471468 0.56798297 0.48631501 0.53582197 - 0.56466401 0.58405501 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 - 0.561248 0.56466401 0.58405501 0.50988603 0.60414898 0.55312598 0.548361 - 0.56466401 0.58405501 0.52967697 0.561248 0.594082 0.62339002 0.55948597 - 0.61438298 0.59298301 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 - 0.59298301 0.57251501 0.55312598 0.548361 0.52967697 0.561248 0.48631501 - 0.53582197 0.59298301 0.57251501 0.55312598 0.548361 0.55817002 0.495579 - 0.55312598 0.548361 0.48631501 0.53582197 0.55817002 0.495579 0.55948597 - 0.61438298 0.56466401 0.58405501 0.59298301 0.57251501 0.34469 0.60969198 - 0.33425501 0.67281002 0.29069301 0.56685197 0.33425501 0.67281002 0.27809399 - 0.63370502 0.29069301 0.56685197 0.37521201 0.59356803 0.33425501 0.67281002 - 0.34469 0.60969198 0.402172 0.66881698 0.33425501 0.67281002 0.37521201 0.59356803 - 0.34469 0.60969198 0.29069301 0.56685197 0.35016599 0.53974301 0.29069301 - 0.56685197 0.241578 0.53054398 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.44446999 0.51254302 0.37521201 0.59356803 0.34469 - 0.60969198 0.35016599 0.53974301 0.66176099 0.61444402 0.62787598 0.58490998 - 0.70178902 0.52030098 0.62787598 0.58490998 0.66376501 0.50938398 0.70178902 - 0.52030098 0.62787598 0.58490998 0.611036 0.541574 0.66376501 0.50938398 - 0.94016802 0.552697 0.91139501 0.52158397 0.94404799 0.534742 0.94404799 - 0.534742 0.91139501 0.52158397 0.91649199 0.412949 0.91139501 0.52158397 - 0.88974899 0.43314499 0.91649199 0.412949; - setAttr ".uvst[0].uvsp[2250:2499]" 0.94404799 0.534742 0.91649199 0.412949 - 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 0.534742 0.95096499 0.41022 - 0.99280602 0.52736998 0.97447199 0.54772502 0.95096499 0.41022 0.91139501 - 0.52158397 0.88192099 0.50762999 0.88974899 0.43314499 0.88974899 0.43314499 - 0.86741501 0.373849 0.91649199 0.412949 0.73045999 0.53145701 0.72172701 - 0.597004 0.70178902 0.52030098 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.402172 0.66881698 - 0.72172701 0.597004 0.66176099 0.61444402 0.70178902 0.52030098 0.76481098 - 0.59411001 0.72172701 0.597004 0.73045999 0.53145701 0.361752 0.72452599 - 0.33192599 0.74883097 0.33425501 0.67281002 0.99280602 0.52736998 0.95096499 - 0.41022 0.99264401 0.396844 0.91649199 0.412949 0.89975703 0.32890701 0.95096499 - 0.41022 0.95096499 0.41022 0.89975703 0.32890701 0.99264401 0.396844 0.91649199 - 0.412949 0.86741501 0.373849 0.89975703 0.32890701 0.66376501 0.50938398 - 0.68089098 0.41862199 0.70178902 0.52030098 0.88192099 0.50762999 0.84326202 - 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 0.49983799 - 0.88974899 0.43314499 0.82335901 0.49983799 0.84326202 0.52863598 0.81960201 - 0.54509503 0.81960201 0.54509503 0.84326202 0.52863598 0.80370599 0.60544503 - 0.86585498 0.608989 0.85311198 0.64641303 0.84326202 0.52863598 0.86585498 - 0.608989 0.90890902 0.65339601 0.85311198 0.64641303 0.90890902 0.65339601 - 0.86585498 0.608989 0.904742 0.61987799 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.55527902 - 0.8071 0.55527902 0.8071 0.56181002 0.765275 0.61429799 0.75036502 0.63363802 - 0.89377397 0.57115501 0.92132199 0.60618597 0.86918902 0.60618597 0.86918902 - 0.57115501 0.92132199 0.56233603 0.85706103 0.16559599 0.995709 0.14566401 - 0.93838102 0.23810799 0.94020498 0.16559599 0.995709 0.059299 0.99024302 - 0.14566401 0.93838102 0.66327202 0.82856899 0.68109202 0.85573 0.61128402 - 0.83876997 0.14566401 0.93838102 0.17147 0.907399 0.23810799 0.94020498 0.059299 - 0.99024302 0.063868999 0.91910303 0.14566401 0.93838102 0.12989099 0.871301 - 0.135956 0.83810002 0.193271 0.88191301 0.063868999 0.91910303 0.052301999 - 0.89361697 0.072558001 0.88500297 0.68109202 0.85573 0.60618597 0.86918902 - 0.61128402 0.83876997 0.68109202 0.85573 0.63363802 0.89377397 0.60618597 - 0.86918902 0.0086899996 0.90104598 0.052301999 0.89361697 0.063868999 0.91910303 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.059299 0.99024302 0.66305399 - 0.78664398 0.61128402 0.83876997 0.612091 0.80211103 0.66305399 0.78664398 - 0.66327202 0.82856899 0.61128402 0.83876997 0.66305399 0.78664398 0.612091 - 0.80211103 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 0.77576202 - 0.662714 0.74348199 0.68224001 0.752303 0.66305399 0.78664398 0.64314198 - 0.77576202 0.63186097 0.74417901 0.612091 0.80211103 0.61429799 0.75036502 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.63186097 0.74417901 0.56181002 0.765275 - 0.59559602 0.73881298 0.61429799 0.75036502 0.61429799 0.75036502 0.59559602 - 0.73881298 0.596021 0.71545899 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.58906102 0.696136 0.59559602 - 0.73881298 0.578484 0.726412 0.596021 0.71545899 0.59559602 0.73881298 0.56181002 - 0.765275 0.578484 0.726412 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.074841 0.80788898 0.135956 - 0.83810002 0.12989099 0.871301 0.073301002 0.83981198 0.12989099 0.871301 - 0.063868999 0.91910303 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.073301002 0.83981198 0.12989099 0.871301 0.069305003 - 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 0.862432 - 0.072558001 0.88500297 0.039615002 0.87295502 0.069305003 0.862432 0.072558001 - 0.88500297 0.052301999 0.89361697 0.039615002 0.87295502 0.039615002 0.87295502 - 0.029790999 0.85418802 0.073301002 0.83981198 0.039615002 0.87295502 0.073301002 - 0.83981198 0.069305003 0.862432 0.0086899996 0.90104598 0.029790999 0.85418802 - 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 0.135956 - 0.83810002 0.073301002 0.83981198 0.133753 0.80051601 0.063868999 0.91910303 - 0.17147 0.907399 0.14566401 0.93838102 0.61128402 0.83876997 0.60618597 0.86918902 - 0.56233603 0.85706103 0.21379501 0.846349 0.193271 0.88191301 0.209691 0.79815799 - 0.225722 0.86254603 0.193271 0.88191301 0.21379501 0.846349 0.225722 0.86254603 - 0.21379501 0.846349 0.237334 0.83964097 0.17147 0.907399 0.12989099 0.871301 - 0.193271 0.88191301 0.17147 0.907399 0.193271 0.88191301 0.23810799 0.94020498 - 0.133753 0.80051601 0.115455 0.77456403 0.134497 0.74599701 0.209691 0.79815799 - 0.133753 0.80051601 0.189914 0.76742601 0.193271 0.88191301 0.133753 0.80051601 - 0.209691 0.79815799 0.193271 0.88191301 0.225722 0.86254603 0.26639199 0.865004 - 0.225722 0.86254603 0.237334 0.83964097 0.26639199 0.865004 0.85311198 0.64641303 - 0.81364501 0.66707098 0.84326202 0.52863598 0.23810799 0.94020498; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.26639199 0.865004 - 0.84326202 0.52863598 0.81364501 0.66707098 0.80370599 0.60544503 0.26639199 - 0.865004 0.237334 0.83964097 0.32067001 0.79166698 0.32067001 0.79166698 - 0.237334 0.83964097 0.30680701 0.75846398 0.237334 0.83964097 0.21379501 - 0.846349 0.209691 0.79815799 0.189914 0.76742601 0.133753 0.80051601 0.193901 - 0.70055801 0.209691 0.79815799 0.189914 0.76742601 0.193901 0.70055801 0.235135 - 0.75121701 0.209691 0.79815799 0.193901 0.70055801 0.235135 0.75121701 0.193901 - 0.70055801 0.23119999 0.70723599 0.237334 0.83964097 0.209691 0.79815799 - 0.235135 0.75121701 0.237334 0.83964097 0.235135 0.75121701 0.30680701 0.75846398 - 0.30680701 0.75846398 0.235135 0.75121701 0.23119999 0.70723599 0.81960201 - 0.54509503 0.80370599 0.60544503 0.76481098 0.59411001 0.32067001 0.79166698 - 0.30680701 0.75846398 0.33192599 0.74883097 0.33192599 0.74883097 0.30680701 - 0.75846398 0.33425501 0.67281002 0.23119999 0.70723599 0.193901 0.70055801 - 0.218197 0.66097301 0.23119999 0.70723599 0.218197 0.66097301 0.27809399 - 0.63370502 0.773857 0.53407699 0.76481098 0.59411001 0.73045999 0.53145701 - 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 0.82335901 - 0.49983799 0.81960201 0.54509503 0.773857 0.53407699 0.29069301 0.56685197 - 0.214571 0.58170599 0.241578 0.53054398 0.27809399 0.63370502 0.214571 0.58170599 - 0.29069301 0.56685197 0.27809399 0.63370502 0.218197 0.66097301 0.214571 - 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.214571 0.58170599 0.214571 - 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 0.227768 - 0.50040001 0.241578 0.53054398 0.191866 0.64202601 0.181797 0.58704501 0.214571 - 0.58170599 0.218197 0.66097301 0.193901 0.70055801 0.191866 0.64202601 0.35016599 - 0.53974301 0.227768 0.50040001 0.34836701 0.49853599 0.241578 0.53054398 - 0.227768 0.50040001 0.35016599 0.53974301 0.415775 0.44801801 0.302367 0.46158099 - 0.33645499 0.40632701 0.34836701 0.49853599 0.302367 0.46158099 0.415775 - 0.44801801 0.48631501 0.53582197 0.49755499 0.488251 0.55817002 0.495579 - 0.48631501 0.53582197 0.44446999 0.51254302 0.49755499 0.488251 0.55817002 - 0.495579 0.49755499 0.488251 0.53173602 0.43147901 0.16243599 0.73647797 - 0.134497 0.74599701 0.137054 0.71443301 0.133753 0.80051601 0.16243599 0.73647797 - 0.193901 0.70055801 0.133753 0.80051601 0.134497 0.74599701 0.16243599 0.73647797 - 0.16243599 0.73647797 0.137054 0.71443301 0.155361 0.68448699 0.155361 0.68448699 - 0.137054 0.71443301 0.135434 0.64463699 0.029790999 0.85418802 0.038779002 - 0.81607199 0.073301002 0.83981198 0.193901 0.70055801 0.17482001 0.65435803 - 0.191866 0.64202601 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.17482001 0.65435803 - 0.191866 0.64202601 0.17482001 0.65435803 0.181797 0.58704501 0.152937 0.59559798 - 0.17482001 0.65435803 0.134919 0.61088699 0.17482001 0.65435803 0.152937 - 0.59559798 0.181797 0.58704501 0.34836701 0.49853599 0.227768 0.50040001 - 0.302367 0.46158099 0.181797 0.58704501 0.152937 0.59559798 0.17433301 0.53156102 - 0.181797 0.58704501 0.17433301 0.53156102 0.227768 0.50040001 0.33645499 - 0.40632701 0.302367 0.46158099 0.24266601 0.36897901 0.55341202 0.63760501 - 0.50244898 0.644642 0.493588 0.62263501 0.17482001 0.65435803 0.155361 0.68448699 - 0.135434 0.64463699 0.17482001 0.65435803 0.135434 0.64463699 0.134919 0.61088699 - 0.195015 0.48982099 0.19817799 0.43839601 0.235855 0.44651899 0.235855 0.44651899 - 0.19817799 0.43839601 0.216538 0.39981201 0.302367 0.46158099 0.235855 0.44651899 - 0.24266601 0.36897901 0.227768 0.50040001 0.17433301 0.53156102 0.195015 - 0.48982099 0.227768 0.50040001 0.195015 0.48982099 0.235855 0.44651899 0.235855 - 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.24266601 0.36897901 0.52967697 0.561248 0.50988603 0.60414898 - 0.471468 0.56798297 0.612091 0.80211103 0.55527902 0.8071 0.61429799 0.75036502 - 0.612091 0.80211103 0.61128402 0.83876997 0.55527902 0.8071 0.79334199 0.99322498 - 0.86997002 0.93731803 0.81753498 0.92918402 0.79334199 0.99322498 0.85467398 - 0.99159998 0.86997002 0.93731803 0.71710402 0.94957799 0.81753498 0.92918402 - 0.75108498 0.90098101 0.71710402 0.94957799 0.75108498 0.90098101 0.681234 - 0.89455098 0.79334199 0.99322498 0.81753498 0.92918402 0.71710402 0.94957799 - 0.681234 0.89455098 0.71957898 0.86809897 0.68843299 0.845505 0.84964103 - 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 0.70362002 - 0.77644902 0.63733798 0.77899301 0.67823797 0.79684901 0.86380398 0.82964599 - 0.80204397 0.78393102 0.81632203 0.77899301 0.67823797 0.77644902 0.63733798 - 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 0.72519898 - 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.72519898 0.67094803 - 0.681234 0.89455098 0.75108498 0.90098101 0.71957898 0.86809897 0.75108498 - 0.90098101 0.81753498 0.92918402 0.79684901 0.86380398 0.68843299 0.845505 - 0.71957898 0.86809897 0.718126 0.82873601 0.75108498 0.90098101 0.79684901 - 0.86380398 0.71957898 0.86809897 0.71957898 0.86809897 0.79684901 0.86380398 - 0.78393102 0.81632203 0.71957898 0.86809897 0.78393102 0.81632203 0.718126 - 0.82873601 0.718126 0.82873601 0.75086302 0.78398401 0.71901399 0.78532398 - 0.718126 0.82873601 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.75086302 0.78398401 0.30680701 - 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 0.67281002 - 0.30680701 0.75846398 0.27809399 0.63370502 0.55527902 0.8071 0.50365102 - 0.81889403 0.56181002 0.765275 0.484781 0.85584599 0.50365102 0.81889403 - 0.55527902 0.8071 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 - 0.74251801 0.75086302 0.78398401 0.78393102 0.81632203 0.78915399 0.74251801 - 0.81753498 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 - 0.86380398 0.81753498 0.92918402 0.82964599 0.80204397 0.82964599 0.80204397 - 0.86997002 0.93731803 0.84964103 0.74003702 0.073301002 0.83981198 0.074841 - 0.80788898 0.133753 0.80051601 0.133753 0.80051601 0.074841 0.80788898 0.115455 - 0.77456403 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 - 0.35912099 0.27489001 0.33604199 0.25541499 0.316248 0.291545 0.39272901 - 0.33256099 0.47097301 0.28257099 0.35912099 0.27489001 0.55185699 0.34580401 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55324697 0.28502101 0.52854401 - 0.261291 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 - 0.47097301 0.28257099 0.33604199 0.25541499 0.31703201 0.24954499 0.316248 - 0.291545 0.31703201 0.24954499 0.31351399 0.202804 0.258811 0.22176901 0.316248 - 0.291545 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 - 0.291545 0.255613 0.25320399 0.52854401 0.261291 0.532996 0.217034 0.400451 - 0.218311 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 - 0.15157899 0.37215099 0.13412 0.35348001 0.188078 0.35912099 0.27489001 0.400451 - 0.218311 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.33604199 - 0.25541499 0.33604199 0.25541499 0.35348001 0.188078 0.31703201 0.24954499 - 0.47097301 0.28257099 0.400451 0.218311 0.35912099 0.27489001 0.47097301 - 0.28257099 0.52854401 0.261291 0.400451 0.218311 0.35348001 0.188078 0.32905 - 0.12617201 0.31351399 0.202804 0.31703201 0.24954499 0.35348001 0.188078 - 0.31351399 0.202804 0.194934 0.29608399 0.151114 0.233711 0.128057 0.28853801 - 0.194934 0.29608399 0.19205201 0.23548099 0.151114 0.233711 0.21787301 0.34819999 - 0.26878601 0.315254 0.194934 0.29608399 0.31351399 0.202804 0.32905 0.12617201 - 0.271054 0.13361099 0.25301799 0.068204001 0.31335899 0.057027001 0.245719 - 0.014829 0.591959 0.53098297 0.57874799 0.472913 0.55444598 0.474244 0.639902 - 0.47827199 0.60980803 0.47876301 0.62550402 0.53194499 0.62550402 0.53194499 - 0.60980803 0.47876301 0.60595697 0.51647699 0.92526799 0.68932003 0.88900101 - 0.68397403 0.86200303 0.72877699 0.89971602 0.66068798 0.88900101 0.68397403 - 0.92526799 0.68932003 0.60980803 0.47876301 0.57874799 0.472913 0.591959 - 0.53098297 0.58532703 0.345817 0.63387299 0.382061 0.66333002 0.35212901 - 0.610578 0.38000399 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 - 0.610578 0.38000399 0.58532703 0.345817 0.57874799 0.472913 0.60697401 0.39847901 - 0.55444598 0.474244 0.60980803 0.47876301 0.591959 0.53098297 0.60595697 - 0.51647699 0.88900101 0.68397403 0.86512601 0.68251401 0.86200303 0.72877699 - 0.080518 0.123654 0.056297999 0.091900997 0.039241001 0.118589 0.080518 0.123654 - 0.039241001 0.118589 0.020680999 0.143217 0.069355004 0.21782801 0.070349 - 0.165839 0.041522998 0.25432399 0.61546803 0.418973 0.60697401 0.39847901 - 0.57874799 0.472913 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 - 0.64173597 0.390975 0.63182598 0.41617399 0.639902 0.47827199 0.128057 0.28853801 - 0.036951002 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 - 0.28853801 0.016138 0.325297 0.041522998 0.25432399 0.070349 0.165839 0.027048999 - 0.208827 0.070349 0.165839 0.020680999 0.143217 0.027048999 0.208827 0.070349 - 0.165839 0.080518 0.123654 0.020680999 0.143217 0.21787301 0.34819999 0.194934 - 0.29608399 0.128057 0.28853801 0.056297999 0.091900997 0.271054 0.13361099 - 0.062045 0.057544 0.080518 0.123654 0.271054 0.13361099 0.056297999 0.091900997 - 0.60697401 0.39847901 0.61546803 0.418973 0.617971 0.407262 0.617971 0.407262 - 0.61546803 0.418973 0.63182598 0.41617399 0.63387299 0.382061 0.64173597 - 0.390975 0.66333002 0.35212901 0.94665498 0.81503397 0.97766298 0.79651397 - 0.86200303 0.72877699 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 - 0.72877699 0.93663901 0.729617 0.92526799 0.68932003 0.86200303 0.72877699 - 0.665824 0.44352099 0.639902 0.47827199 0.65543997 0.49157101 0.64173597 - 0.390975 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.665824 - 0.44352099 0.66333002 0.35212901 0.60697401 0.39847901 0.58532703 0.345817 - 0.55444598 0.474244 0.35348001 0.188078 0.37215099 0.13412 0.32905 0.12617201 - 0.602754 0.257723 0.57477999 0.25117901 0.55324697 0.28502101 0.602754 0.257723 - 0.61704302 0.20689499 0.57477999 0.25117901 0.61118603 0.156872 0.56468099 - 0.099036001 0.53191298 0.15157899 0.64614099 0.22702 0.602754 0.257723 0.60898602 - 0.28752601 0.64614099 0.22702 0.61704302 0.20689499 0.602754 0.257723 0.61704302 - 0.20689499 0.64614099 0.22702 0.61118603 0.156872 0.61118603 0.156872 0.63874 - 0.094846003 0.56468099 0.099036001 0.26878601 0.315254 0.255613 0.25320399 - 0.194934 0.29608399 0.255613 0.25320399 0.216565 0.237138 0.194934 0.29608399 - 0.194934 0.29608399 0.216565 0.237138 0.19205201 0.23548099; - setAttr ".uvst[0].uvsp[3000:3249]" 0.53150898 0.049988002 0.57313102 - 0.0095039997 0.42296299 0.00556 0.627464 0.31886399 0.64614099 0.22702 0.60898602 - 0.28752601 0.53173602 0.43147901 0.47337201 0.42365801 0.47644299 0.39616501 - 0.55324697 0.28502101 0.57477999 0.25117901 0.52854401 0.261291 0.627464 - 0.31886399 0.60898602 0.28752601 0.58940798 0.33751199 0.475099 0.076341003 - 0.42296299 0.00556 0.359846 0.051763002 0.475099 0.076341003 0.53150898 0.049988002 - 0.42296299 0.00556 0.53191298 0.15157899 0.475099 0.076341003 0.37215099 - 0.13412 0.53173602 0.43147901 0.47644299 0.39616501 0.53674299 0.39848399 - 0.53674299 0.39848399 0.47644299 0.39616501 0.47946599 0.37119001 0.61704302 - 0.20689499 0.61118603 0.156872 0.53191298 0.15157899 0.31351399 0.202804 - 0.271054 0.13361099 0.22066 0.18181901 0.532996 0.217034 0.53191298 0.15157899 - 0.400451 0.218311 0.57477999 0.25117901 0.532996 0.217034 0.52854401 0.261291 - 0.54082298 0.34952399 0.53746098 0.37084499 0.48070699 0.35210899 0.56468099 - 0.099036001 0.56216699 0.060766999 0.529387 0.082309 0.529387 0.082309 0.56216699 - 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.475099 0.076341003 - 0.53191298 0.15157899 0.56468099 0.099036001 0.529387 0.082309 0.57477999 - 0.25117901 0.563384 0.216162 0.532996 0.217034 0.57477999 0.25117901 0.61704302 - 0.20689499 0.563384 0.216162 0.563384 0.216162 0.61704302 0.20689499 0.53191298 - 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53191298 0.15157899 0.53674299 - 0.39848399 0.47946599 0.37119001 0.53746098 0.37084499 0.53746098 0.37084499 - 0.47946599 0.37119001 0.48070699 0.35210899 0.37215099 0.13412 0.475099 0.076341003 - 0.359846 0.051763002 0.31703201 0.24954499 0.258811 0.22176901 0.255613 0.25320399 - 0.61546803 0.418973 0.60980803 0.47876301 0.639902 0.47827199 0.60980803 - 0.47876301 0.61546803 0.418973 0.57874799 0.472913 0.128057 0.28853801 0.041522998 - 0.25432399 0.036951002 0.29172301 0.128057 0.28853801 0.151114 0.233711 0.102847 - 0.22989 0.128057 0.28853801 0.102847 0.22989 0.041522998 0.25432399 0.102847 - 0.22989 0.069355004 0.21782801 0.041522998 0.25432399 0.102847 0.22989 0.107695 - 0.172719 0.069355004 0.21782801 0.107695 0.172719 0.070349 0.165839 0.069355004 - 0.21782801 0.107695 0.172719 0.080518 0.123654 0.070349 0.165839 0.151114 - 0.233711 0.155274 0.177471 0.107695 0.172719 0.151114 0.233711 0.107695 0.172719 - 0.102847 0.22989 0.107695 0.172719 0.155274 0.177471 0.080518 0.123654 0.155274 - 0.177471 0.271054 0.13361099 0.080518 0.123654 0.22066 0.18181901 0.271054 - 0.13361099 0.155274 0.177471 0.32999301 0.33045399 0.39272901 0.33256099 - 0.316248 0.291545 0.32999301 0.33045399 0.316248 0.291545 0.26878601 0.315254 - 0.359846 0.051763002 0.42296299 0.00556 0.36022699 0.003454 0.639902 0.47827199 - 0.62550402 0.53194499 0.65543997 0.49157101 0.036951002 0.29172301 0.0040460001 - 0.25350901 0.016138 0.325297 0.041522998 0.25432399 0.027048999 0.208827 - 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 0.25432399 0.0040460001 - 0.25350901 0.039241001 0.118589 0.056297999 0.091900997 0.039096002 0.044592999 - 0.056297999 0.091900997 0.062045 0.057544 0.039096002 0.044592999 0.062045 - 0.057544 0.065323003 0.030218 0.039096002 0.044592999 0.023626 0.35801601 - 0.048168998 0.35214001 0.016138 0.325297 0.193956 0.19936 0.22066 0.18181901 - 0.155274 0.177471 0.193956 0.19936 0.155274 0.177471 0.151114 0.233711 0.19205201 - 0.23548099 0.193956 0.19936 0.151114 0.233711 0.216565 0.237138 0.193956 - 0.19936 0.19205201 0.23548099 0.216565 0.237138 0.22066 0.18181901 0.193956 - 0.19936 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 0.42365801 0.49755499 - 0.488251 0.415775 0.44801801 0.47337201 0.42365801 0.64614099 0.22702 0.63806599 - 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 0.094846003 0.61118603 - 0.156872 0.56468099 0.099036001 0.63874 0.094846003 0.56216699 0.060766999 - 0.63874 0.094846003 0.64656198 0.069087997 0.56216699 0.060766999 0.57625401 - 0.29346699 0.602754 0.257723 0.55324697 0.28502101 0.57625401 0.29346699 - 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 0.33751199 0.57625401 - 0.29346699 0.55185699 0.34580401 0.58940798 0.33751199 0.60898602 0.28752601 - 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 0.257723 0.57625401 - 0.29346699 0.44446999 0.51254302 0.35016599 0.53974301 0.34836701 0.49853599 - 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 0.44446999 - 0.51254302 0.34836701 0.49853599 0.415775 0.44801801 0.227768 0.50040001 - 0.235855 0.44651899 0.302367 0.46158099 0.31335899 0.057027001 0.316118 0.025185 - 0.245719 0.014829 0.31335899 0.057027001 0.359846 0.051763002 0.316118 0.025185 - 0.359846 0.051763002 0.36022699 0.003454 0.316118 0.025185 0.28588501 0.35218599 - 0.32999301 0.33045399 0.26878601 0.315254 0.28588501 0.35218599 0.26878601 - 0.315254 0.21787301 0.34819999 0.37215099 0.13412 0.359846 0.051763002 0.32905 - 0.12617201 0.271054 0.13361099 0.31976199 0.096646003 0.25301799 0.068204001 - 0.32905 0.12617201 0.31976199 0.096646003 0.271054 0.13361099 0.32905 0.12617201 - 0.359846 0.051763002 0.31976199 0.096646003 0.31976199 0.096646003 0.359846 - 0.051763002 0.31335899 0.057027001 0.31976199 0.096646003; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.25301799 - 0.068204001 0.21787301 0.34819999 0.128057 0.28853801 0.11848 0.325919 0.11848 - 0.325919 0.128057 0.28853801 0.048168998 0.35214001 0.25301799 0.068204001 - 0.245719 0.014829 0.142845 0.034219 0.271054 0.13361099 0.25301799 0.068204001 - 0.062045 0.057544 0.062045 0.057544 0.142845 0.034219 0.065323003 0.030218 - 0.25301799 0.068204001 0.142845 0.034219 0.062045 0.057544 0.255613 0.25320399 - 0.258811 0.22176901 0.216565 0.237138 0.216565 0.237138 0.258811 0.22176901 - 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 0.22066 0.18181901 - 0.86741501 0.373849 0.84087598 0.31692401 0.89018202 0.239971 0.84594899 - 0.227217 0.82062 0.34356001 0.79613203 0.35278401 0.84087598 0.31692401 0.84594899 - 0.227217 0.89018202 0.239971 0.84087598 0.31692401 0.82062 0.34356001 0.84594899 - 0.227217 0.89018202 0.239971 0.84594899 0.227217 0.89836198 0.137126 0.82062 - 0.34356001 0.814367 0.424068 0.79613203 0.35278401 0.82062 0.34356001 0.84087598 - 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 0.814367 0.424068 0.86741501 - 0.373849 0.88974899 0.43314499 0.82335901 0.49983799 0.814367 0.424068 0.79613203 - 0.35278401 0.814367 0.424068 0.76275897 0.37884799 0.814367 0.424068 0.82062 - 0.34356001 0.86741501 0.373849 0.82335901 0.49983799 0.773857 0.53407699 - 0.814367 0.424068 0.779073 0.44323799 0.773857 0.53407699 0.73045999 0.53145701 - 0.814367 0.424068 0.773857 0.53407699 0.779073 0.44323799 0.84594899 0.227217 - 0.83935702 0.100765 0.89836198 0.137126 0.84594899 0.227217 0.79802299 0.211936 - 0.83935702 0.100765 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 - 0.83935702 0.100765 0.87032902 0.045508999 0.89836198 0.137126 0.87032902 - 0.045508999 0.83935702 0.100765 0.83545703 0.043729 0.83545703 0.043729 0.83935702 - 0.100765 0.818169 0.062284999 0.966021 0.28052899 0.89018202 0.239971 0.95396501 - 0.134362 0.89975703 0.32890701 0.89018202 0.239971 0.966021 0.28052899 0.86741501 - 0.373849 0.89018202 0.239971 0.89975703 0.32890701 0.79802299 0.211936 0.79613203 - 0.35278401 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 - 0.37884799 0.779073 0.44323799 0.74679601 0.45871499 0.76275897 0.37884799 - 0.76275897 0.37884799 0.74679601 0.45871499 0.733105 0.37849101 0.70178902 - 0.52030098 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 - 0.70178902 0.52030098 0.71095902 0.44087201 0.74679601 0.45871499 0.73045999 - 0.53145701 0.70178902 0.52030098 0.779073 0.44323799 0.73045999 0.53145701 - 0.74679601 0.45871499 0.74679601 0.45871499 0.71095902 0.44087201 0.733105 - 0.37849101 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 - 0.89836198 0.137126 0.94019401 0.031078 0.97778797 0.040635999 0.89975703 - 0.32890701 0.966021 0.28052899 0.99264401 0.396844 0.99264401 0.396844 0.966021 - 0.28052899 0.99426401 0.26670301 0.71095902 0.44087201 0.68089098 0.41862199 - 0.65865201 0.27080399 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 - 0.225641 0.65865201 0.27080399 0.64760703 0.20985 0.70381802 0.225641 0.966021 - 0.28052899 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 - 0.966021 0.28052899 0.98321998 0.20574901 0.89018202 0.239971 0.89836198 - 0.137126 0.95396501 0.134362 0.64760703 0.20985 0.66965002 0.116933 0.70381802 - 0.225641 0.66965002 0.116933 0.719881 0.006691 0.70381802 0.225641 0.66965002 - 0.116933 0.66478199 0.0078290002 0.719881 0.006691 0.73960102 0.22293501 - 0.733105 0.37849101 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 - 0.70381802 0.225641 0.76275897 0.37884799 0.733105 0.37849101 0.73960102 - 0.22293501 0.79802299 0.211936 0.76275897 0.37884799 0.76523697 0.19111399 - 0.76523697 0.19111399 0.76275897 0.37884799 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.73960102 0.22293501 0.719881 0.006691 0.83935702 0.100765 - 0.79802299 0.211936 0.818169 0.062284999 0.818169 0.062284999 0.79802299 - 0.211936 0.76523697 0.19111399 0.719881 0.006691 0.73960102 0.22293501 0.70381802 - 0.225641 0.75811899 0.0040250001 0.76523697 0.19111399 0.73960102 0.22293501 - 0.94037199 0.870426 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 - 0.893085 0.99505001 0.82360703 0.95050299 0.82310897 0.86997002 0.93731803 - 0.90755701 0.964562 0.909796 0.8951 0.94326001 0.89290702 0.90755701 0.964562 - 0.98405302 0.91405201 0.909796 0.8951 0.90755701 0.964562 0.94326001 0.89290702 - 0.85467398 0.99159998 0.90755701 0.964562 0.86997002 0.93731803 0.94037199 - 0.870426 0.98405302 0.91405201 0.98507398 0.893085 0.94326001 0.89290702 - 0.98405302 0.91405201 0.94037199 0.870426 0.909796 0.8951 0.94326001 0.89290702 - 0.94037199 0.870426 0.94037199 0.870426 0.95050299 0.82310897 0.91257 0.81947201 - 0.909796 0.8951 0.94037199 0.870426 0.91257 0.81947201 0.909796 0.8951 0.91257 - 0.81947201 0.84964103 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.84964103 - 0.74003702 0.68109202 0.85573 0.66562402 0.92713302 0.63363802 0.89377397 - 0.83545703 0.043729 0.818169 0.062284999 0.804057 0.01567 0.804057 0.01567 - 0.818169 0.062284999 0.78658998 0.052133001 0.90803403 0.044094998 0.87032902 - 0.045508999 0.86865902 0.013712 0.90803403 0.044094998 0.86865902 0.013712 - 0.94019401 0.031078 0.87032902 0.045508999 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.86865902 0.013712 0.86865902 0.013712 - 0.83545703 0.043729 0.804057 0.01567 0.804057 0.01567 0.78658998 0.052133001 - 0.75811899 0.0040250001 0.33477801 0.909235 0.33735099 0.85548198 0.32756099 - 0.89249802 0.34354001 0.86769497 0.33735099 0.85548198 0.33477801 0.909235 - 0.371288 0.86448097 0.34659299 0.92080897 0.35936901 0.91262299 0.371288 - 0.86448097 0.359723 0.87225002 0.34659299 0.92080897 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.33477801 0.909235 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.48538801 0.95112503 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.45333701 0.95817798 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.33735099 0.85548198 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.34354001 0.86769497 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.371288 0.86448097 0.42452699 0.94267398 0.43036199 0.96655297 - 0.39850101 0.96660697 0.34862399 0.80891901 0.35968399 0.81033999 0.37021199 - 0.79415601 0.352687 0.831747 0.35968399 0.81033999 0.34862399 0.80891901 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.35968399 0.81033999 0.37179601 0.81299299 0.38256299 - 0.81765997 0.37021199 0.79415601 0.37179601 0.81299299 0.368599 0.83635598 - 0.38256299 0.81765997 0.35968399 0.81033999 0.37179601 0.81299299 0.37021199 - 0.79415601 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.29274601 0.90635097 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.32756099 0.89249802 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.30324501 - 0.90815997 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.49160999 0.97508597 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.46529901 0.98378903 0.308972 0.86521697 0.307354 - 0.82550597 0.300255 0.86195898 0.308972 0.86521697 0.31612 0.82580698 0.307354 - 0.82550597 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 - 0.82830203 0.31612 0.82580698 0.308972 0.86521697 0.33719999 0.843934 0.32226399 - 0.867616 0.33101901 0.87009001 0.329963 0.82830203 0.32226399 0.867616 0.33719999 - 0.843934 0.405705 0.98896497 0.43152601 0.97203702 0.43633199 0.99328399 - 0.31612 0.82580698 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 - 0.33029699 0.81221998 0.32305399 0.80920303 0.32305399 0.80920303 0.33029699 - 0.81221998 0.33178499 0.78945303 0.38328499 0.85446298 0.38630301 0.87709397 - 0.39264601 0.86977398 0.380456 0.87159598 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.376625 0.895226 0.38630301 0.87709397 0.38328499 - 0.85446298 0.39264601 0.86977398 0.38593799 0.83733201 0.38630301 0.87709397 - 0.38863 0.90287602 0.39264601 0.86977398 0.39264601 0.86977398 0.40770999 - 0.866552 0.38593799 0.83733201 0.43939599 0.911412 0.44178799 0.92605698 - 0.42723399 0.92242002 0.37287301 0.875799 0.38328499 0.85446298 0.38593799 - 0.83733201 0.39264601 0.86977398 0.38863 0.90287602 0.40770999 0.866552 0.36011499 - 0.92878401 0.376625 0.895226 0.36799499 0.89132202 0.36011499 0.92878401 - 0.36799499 0.89132202 0.35936901 0.91262299 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.38328499 0.85446298 - 0.34659299 0.92080897 0.36011499 0.92878401 0.35936901 0.91262299 0.31726399 - 0.91030401 0.33477801 0.909235 0.32756099 0.89249802 0.40770999 0.866552 - 0.40901801 0.89674503 0.41693899 0.89492601 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.381246 0.95752001 0.38630301 0.87709397 - 0.376625 0.895226 0.38863 0.90287602 0.36011499 0.92878401 0.33891901 0.987975 - 0.381246 0.95752001 0.32005399 0.97494799 0.36011499 0.92878401 0.34659299 - 0.92080897 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 - 0.32005399 0.97494799 0.34659299 0.92080897 0.33477801 0.909235 0.300001 - 0.97013903 0.31726399 0.91030401 0.30324501 0.90815997 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.28796199 0.92390901 0.270601 0.92593902 0.28796199 0.92390901 - 0.27395099 0.912489 0.290243 0.940907 0.28796199 0.92390901 0.270601 0.92593902 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.258212 0.91232401 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.290243 0.940907 - 0.283005 0.96905398 0.290243 0.940907 0.270601 0.92593902 0.283005 0.96905398 - 0.270601 0.92593902 0.25671601 0.927858 0.381246 0.95752001 0.35122901 1.000869 - 0.369001 0.99685502; - setAttr ".uvst[0].uvsp[3750:3999]" 0.381246 0.95752001 0.33891901 0.987975 - 0.35122901 1.000869 0.25706601 0.969437 0.283005 0.96905398 0.25671601 0.927858 - 0.53121799 0.86490297 0.54497999 0.877047 0.53719902 0.90499997 0.53719902 - 0.90499997 0.54497999 0.877047 0.56407797 0.91909999 0.52387398 0.97127301 - 0.54059702 0.94349098 0.53666401 0.96573699 0.52387398 0.97127301 0.521644 - 0.96135998 0.54059702 0.94349098 0.53666401 0.96573699 0.55496401 0.97537702 - 0.54084498 0.98507202 0.54059702 0.94349098 0.55496401 0.97537702 0.53666401 - 0.96573699 0.258212 0.91232401 0.27759501 0.89841598 0.262528 0.89503402 - 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 0.27395099 - 0.912489 0.291614 0.896658 0.27759501 0.89841598 0.28940701 0.91069198 0.291614 - 0.896658 0.27395099 0.912489 0.51558298 0.98070103 0.52387398 0.97127301 - 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 0.52629602 - 0.99024498 0.52629602 0.99024498 0.54084498 0.98507202 0.52678698 0.99600202 - 0.52629602 0.99024498 0.53666401 0.96573699 0.54084498 0.98507202 0.262528 - 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 0.89841598 - 0.282882 0.883295 0.26901299 0.87969601 0.27759501 0.89841598 0.29319 0.88515502 - 0.282882 0.883295 0.291614 0.896658 0.29319 0.88515502 0.27759501 0.89841598 - 0.50723398 0.99519998 0.52629602 0.99024498 0.52678698 0.99600202 0.282882 - 0.883295 0.28712299 0.87004602 0.26901299 0.87969601 0.29319 0.88515502 0.28712299 - 0.87004602 0.282882 0.883295 0.50723398 0.99519998 0.51558298 0.98070103 - 0.52629602 0.99024498 0.28796199 0.92390901 0.28940701 0.91069198 0.27395099 - 0.912489 0.53719902 0.90499997 0.56407797 0.91909999 0.54059702 0.94349098 - 0.54059702 0.94349098 0.56407797 0.91909999 0.56377 0.96770799 0.54059702 - 0.94349098 0.56377 0.96770799 0.55496401 0.97537702 0.45468801 0.92364502 - 0.44178799 0.92605698 0.45547101 0.90422702 0.45547101 0.90422702 0.44178799 - 0.92605698 0.43939599 0.911412 0.41640201 0.88049698 0.40770999 0.866552 - 0.41693899 0.89492601 0.38863 0.90287602 0.39948201 0.920587 0.40770999 0.866552 - 0.40770999 0.866552 0.39948201 0.920587 0.40901801 0.89674503 0.40901801 - 0.89674503 0.41201699 0.92887998 0.41693899 0.89492601 0.40901801 0.89674503 - 0.39948201 0.920587 0.41201699 0.92887998 0.46091801 0.88338 0.45547101 0.90422702 - 0.44038501 0.90504903 0.39948201 0.920587 0.381246 0.95752001 0.41201699 - 0.92887998 0.41201699 0.92887998 0.381246 0.95752001 0.39207101 0.96583498 - 0.45468801 0.92364502 0.45547101 0.90422702 0.48168799 0.91676801 0.48168799 - 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 0.90422702 - 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 0.91676801 - 0.496647 0.874951 0.49160999 0.97508597 0.48538801 0.95112503 0.50320703 - 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.50320703 0.95512199 - 0.48538801 0.95112503 0.48168799 0.91676801 0.49597099 0.91574198 0.51486897 - 0.97433299 0.50320703 0.95512199 0.521644 0.96135998 0.49160999 0.97508597 - 0.50320703 0.95512199 0.51486897 0.97433299 0.49597099 0.91574198 0.496647 - 0.874951 0.53719902 0.90499997 0.521644 0.96135998 0.53719902 0.90499997 - 0.54059702 0.94349098 0.50320703 0.95512199 0.49597099 0.91574198 0.53719902 - 0.90499997 0.50320703 0.95512199 0.53719902 0.90499997 0.521644 0.96135998 - 0.39207101 0.96583498 0.381246 0.95752001 0.369001 0.99685502 0.496647 0.874951 - 0.53121799 0.86490297 0.53719902 0.90499997 0.87032902 0.045508999 0.90803403 - 0.044094998 0.89836198 0.137126 0.89836198 0.137126 0.90803403 0.044094998 - 0.94019401 0.031078 0.78658998 0.052133001 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.78658998 0.052133001 0.818169 0.062284999 0.76523697 0.19111399 - 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 0.80920303 - 0.33178499 0.78945303 0.307354 0.82550597 0.33029699 0.81221998 0.33719999 - 0.843934 0.33178499 0.78945303 0.33029699 0.81221998 0.329963 0.82830203 - 0.33719999 0.843934 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.77899301 0.67823797 - 0.82964599 0.80204397 0.84964103 0.74003702 0.78915399 0.74251801 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.71901399 0.78532398 0.68843299 0.845505 0.66842598 0.82617402 - 0.694462 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.694462 0.78577 - 0.66842598 0.82617402 0.68843299 0.845505 0.718126 0.82873601 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.31726399 0.91030401 0.38921699 0.788423 0.39220601 0.76434302 - 0.44672099 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.44672099 0.742163 - 0.40665799 0.802068 0.44672099 0.742163 0.476217 0.727027 0.66562402 0.92713302 - 0.62646401 0.95210898 0.63363802 0.89377397 0.66562402 0.92713302 0.65396702 - 0.95580101 0.62646401 0.95210898 0.69465202 0.75267702 0.71901399 0.78532398 - 0.71984899 0.75139397 0.71901399 0.78532398 0.75086302 0.78398401 0.75477803 - 0.76254302 0.71901399 0.78532398 0.75477803 0.76254302 0.71984899 0.75139397 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.62701303 0.95989603 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.71176398 0.71938401 0.72957599 0.74754602; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.74377102 - 0.72034299 0.76598603 0.762146 0.78915399 0.74251801 0.72957599 0.74754602 - 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 0.97251898 - 0.99150902 0.982153 0.97301102 0.96395802 0.96951902 0.65568203 0.65436798 - 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 0.70558798 - 0.70140499 0.66365999 0.64994597 0.70058 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.69391102 0.70558798 - 0.62879598 0.619084 0.70140499 0.66365999 0.68494898 0.62769097 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.62879598 0.619084 0.60452098 0.662067 0.64994597 - 0.70058 0.65568203 0.65436798 0.60770202 0.71877599 0.64994597 0.70058 0.60452098 - 0.662067; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.5614242504933854 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".ra" -type "double3" 6.5004949211009624 20.509769230607585 105.6937617003028 ; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_Lwing_null_SPREAD.o" "IMP_Lwing_null.SPREAD"; -connectAttr "IMP_Lwing_null_translateX.o" "IMP_Lwing_null.tx"; -connectAttr "IMP_Lwing_null_translateY.o" "IMP_Lwing_null.ty"; -connectAttr "IMP_Lwing_null_translateZ.o" "IMP_Lwing_null.tz"; -connectAttr "IMP_Lwing_null_rotateX.o" "IMP_Lwing_null.rx"; -connectAttr "IMP_Lwing_null_rotateY.o" "IMP_Lwing_null.ry"; -connectAttr "IMP_Lwing_null_rotateZ.o" "IMP_Lwing_null.rz"; -connectAttr "IMP_Lwing_null_visibility.o" "IMP_Lwing_null.v"; -connectAttr "IMP_Lwing_null_scaleX.o" "IMP_Lwing_null.sx"; -connectAttr "IMP_Lwing_null_scaleY.o" "IMP_Lwing_null.sy"; -connectAttr "IMP_Lwing_null_scaleZ.o" "IMP_Lwing_null.sz"; -connectAttr "IMP_Rwing_null_SPREAD.o" "IMP_Rwing_null.SPREAD"; -connectAttr "IMP_Rwing_null_translateX.o" "IMP_Rwing_null.tx"; -connectAttr "IMP_Rwing_null_translateY.o" "IMP_Rwing_null.ty"; -connectAttr "IMP_Rwing_null_translateZ.o" "IMP_Rwing_null.tz"; -connectAttr "IMP_Rwing_null_rotateX.o" "IMP_Rwing_null.rx"; -connectAttr "IMP_Rwing_null_rotateY.o" "IMP_Rwing_null.ry"; -connectAttr "IMP_Rwing_null_rotateZ.o" "IMP_Rwing_null.rz"; -connectAttr "IMP_Rwing_null_visibility.o" "IMP_Rwing_null.v"; -connectAttr "IMP_Rwing_null_scaleX.o" "IMP_Rwing_null.sx"; -connectAttr "IMP_Rwing_null_scaleY.o" "IMP_Rwing_null.sy"; -connectAttr "IMP_Rwing_null_scaleZ.o" "IMP_Rwing_null.sz"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_pointConstraint1_offsetX.o" "IMP_origin_pointConstraint1.ox" - ; -connectAttr "IMP_origin_pointConstraint1_offsetY.o" "IMP_origin_pointConstraint1.oy" - ; -connectAttr "IMP_origin_pointConstraint1_offsetZ.o" "IMP_origin_pointConstraint1.oz" - ; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of teleportin.ma diff --git a/base/models/monsters/imp/animation/cycles/turret_attack1.ma b/base/models/monsters/imp/animation/cycles/turret_attack1.ma deleted file mode 100644 index 9776a35e3..000000000 --- a/base/models/monsters/imp/animation/cycles/turret_attack1.ma +++ /dev/null @@ -1,6954 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:17 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: turret_attack1.ma -//Last modified: Thu, Jul 24, 2003 11:38:09 AM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 41.955191225556121 57.985718754622077 215.66399046814425 ; - setAttr ".r" -type "double3" -3.3301089123755538 -1436.5999999999865 -2.6136492345377836e-016 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 220.67195982928055; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 48.009446329610896 73.293644119483716 42.595205044249596 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 147.42200685729316; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 59.610932956686291 34.976017359279254 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 202.0596881513782; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 99.999999999999986 37.549632656672301 -15.619095752801243 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 169.87148343332197; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1 52 1; - setAttr -s 10 ".kot[9]" 5; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 -4.1657930308134645 20.2 -1.6735805890538134 28.2 - 6.6566912693983946 31.56 6.1330193887268454 36.864 0.24039650864424209 48.200000000000003 - -4.1657930308134645 52 -3.3997498455212511; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287 20.2 0.21813466524646566 28.2 - -0.86763382127902322 31.56 -0.42972806484138226 36.864 -0.031333305538134112 - 48.200000000000003 0.54296989172209287 52 0.44312374235124674; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0 52 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0 52 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 0 12.2 0 13 0 20.2 0 28.2 - 0 31.56 0 36.864 0 48.200000000000003 0 52 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 -7.4542171015494922 20.2 0 28.2 5.0790319675705673 - 31.56 6.7230875260072231 36.864 0 48.200000000000003 -7.4542171015494922 - 52 -4.2070399148698376; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 8.2 1 12.2 1 13 1 20.2 1 28.2 - 1 31.56 1 36.864 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1 52 1; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433 20.2 2.3128351505039433 28.2 2.3128351505039433 36.864 - 2.3128351505039433 48.200000000000003 2.3128351505039433 52 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501 20.2 0.23421866920666501 28.2 0.23421866920666501 - 36.864 0.23421866920666501 48.200000000000003 0.23421866920666501 52 0.23421866920666501; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 0 13 0 20.2 0 28.2 0 36.864 - 0 48.200000000000003 0 52 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581372 20.2 7.8247378664801399 28.2 -0.56667192682884493 36.864 - 0.57720421748491901 48.200000000000003 8.7951795972581372 52 8.879242733813113; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 12.660431799163181 8.2 13.751352433260992 - 13 13.892774724407374 20.2 13.751352433260992 28.2 13.000667896194788 36.864 - 12.790622953496632 48.200000000000003 13.892774724407374 52 13.882373375610742; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 0 8.2 22.776694843251629 13 26.888910802325626 - 20.2 22.776694843251629 28.2 -13.027357639203586 36.864 -8.1143097424545108 - 48.200000000000003 26.888910802325626 52 27.256913315606262; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 1 1 8.2 1 13 1 20.2 1 28.2 1 36.864 - 1 48.200000000000003 1 52 1; - setAttr -s 8 ".kot[7]" 5; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1 52 1; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1 52 1; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1 52 1; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857 19.4 398.36837297080183 25.800000000000001 405.87328549495959 - 31.56 379.83372596750263 33.8 353.57391219228805 36.864 386.50793879591424 - 39.4 409.82129011423473 42.6 411.22237565094844 48.200000000000003 389.49637174592857 - 52 394.46238408660975; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099 19.4 -12.600779850050984 25.800000000000001 -20.832460906370112 - 31.56 -21.817439286719896 33.8 8.3242847484057965 36.864 10.617569482988788 - 39.4 16.213333110155673 42.6 8.0699656443412024 48.200000000000003 -14.641906192173099 - 52 -13.581882154721427; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167 19.4 2.1331084602003276 25.800000000000001 -6.4884256527418813 - 31.56 -13.151834079049511 33.8 -24.88323729372328 36.864 -20.63225115983429 - 39.4 8.390824613411958 42.6 18.506365469201853 48.200000000000003 -0.44667534838541167 - 52 0.89309122543562958; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029 19.4 5.6268319407172029 25.800000000000001 5.6268319407172029 - 31.56 5.6268319407172029 33.8 5.6268319407172029 36.864 5.6268319407172029 - 39.4 5.6268319407172029 42.6 5.6268319407172029 48.200000000000003 5.6268319407172029 - 52 5.6268319407172029; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802 19.4 -2.1098668596606802 25.800000000000001 -2.1098668596606802 - 31.56 -2.1098668596606802 33.8 -2.1098668596606802 36.864 -2.1098668596606802 - 39.4 -2.1098668596606802 42.6 -2.1098668596606802 48.200000000000003 -2.1098668596606802 - 52 -2.1098668596606802; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 0 6.6 0 13 0 19.4 0 25.800000000000001 - 0 31.56 0 33.8 0 36.864 0 39.4 0 42.6 0 48.200000000000003 0 52 0; - setAttr -s 12 ".kit[3:11]" 3 3 3 9 3 9 3 - 9 9; - setAttr -s 12 ".kot[3:11]" 3 3 3 9 3 9 3 - 9 9; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 12 ".ktv[0:11]" 1 1 6.6 1 13 1 19.4 1 25.800000000000001 - 1 31.56 1 33.8 1 36.864 1 39.4 1 42.6 1 48.200000000000003 1 52 1; - setAttr -s 12 ".kot[3:11]" 5 5 5 5 5 5 5 - 9 5; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1 52 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1 52 1; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404 21.8 5.7384771804188404 26 5.7384771804188404 - 30.280000000000001 5.7384771804188404 43.4 5.7384771804188404 48.200000000000003 - 5.7384771804188404 52 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701 21.8 2.0494561358638701 26 2.0494561358638701 - 30.280000000000001 2.0494561358638701 43.4 2.0494561358638701 48.200000000000003 - 2.0494561358638701 52 2.0494561358638701; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 9.8000000000000007 0 13 0 21.8 - 0 26 0 30.280000000000001 0 43.4 0 48.200000000000003 0 52 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215 21.8 36.348615312237058 26 20.260322676635255 - 30.280000000000001 16.052055400530755 43.4 30.358488909126763 48.200000000000003 - 37.874152024707215 52 38.376451336692824; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051 21.8 -12.486888359019849 26 2.119722337647322 - 30.280000000000001 11.52461344822842 43.4 -2.1187003779812748 48.200000000000003 - -14.364226384227051 52 -14.713158398196649; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242 21.8 -36.216831783693365 26 -31.538953308315584 - 30.280000000000001 -25.97088988767895 43.4 -26.687875434482198 48.200000000000003 - -36.863333637497242 52 -36.965232595814633; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 9.8000000000000007 1 13 1 21.8 - 1 26 1 30.280000000000001 1 43.4 1 48.200000000000003 1 52 1; - setAttr -s 9 ".kot[8]" 5; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -8.7397788191085439 21 -8.7397788191085439 29 - -14.46559177801103 33 -14.46559177801103 35.492 -5.551383374574181 41.8 -39.825254035125468 - 48.200000000000003 -8.7397788191085439 52 -8.7397788191085439; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 7.3330119448673576 21 7.3330119448673576 29 27.409635153347722 - 33 27.409635153347722 35.492 10.151298835483475 41.8 -13.161176261445801 - 48.200000000000003 7.3330119448673576 52 7.3330119448673576; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -16.154270916852411 21 -16.154270916852411 29 - -7.2330610293733786 33 -7.2330610293733786 35.492 -23.366089781757765 41.8 - -23.114348107291107 48.200000000000003 -16.154270916852411 52 -16.154270916852411; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 21 2.6456615572060826 29 2.6456615572060826 - 33 2.6456615572060826 35.492 2.6456615572060826 41.8 2.6456615572060826 48.200000000000003 - 2.6456615572060826 52 2.6456615572060826; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 21 1.9935618776130362 29 1.9935618776130362 - 33 1.9935618776130362 35.492 1.9935618776130362 41.8 1.9935618776130362 48.200000000000003 - 1.9935618776130362 52 1.9935618776130362; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 0 6.6 0 11.4 0 13 0 21 0 29 0 - 33 0 35.492 0 41.8 0 48.200000000000003 0 52 0; - setAttr -s 11 ".kit[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; - setAttr -s 11 ".kot[0:10]" 9 9 9 3 3 3 3 - 3 3 3 9; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 1 1 6.6 1 11.4 1 13 1 21 1 29 1 - 33 1 35.492 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 11 ".kot[3:10]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 12.412879749935719 13 12.412879749935719 - 16 12.412879749935719 25 12.412879749935719 30.600000000000001 12.412879749935719 - 34.876 12.412879749935719 41.8 12.412879749935719 48.200000000000003 12.412879749935719 - 52 12.412879749935719; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -6.7286993982861674 13 -6.7286993982861674 - 16 -6.7286993982861674 25 -6.7286993982861674 30.600000000000001 -6.7286993982861674 - 34.876 -6.7286993982861674 41.8 -6.7286993982861674 48.200000000000003 -6.7286993982861674 - 52 -6.7286993982861674; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -3.868763862603668 13 -3.868763862603668 - 16 -3.868763862603668 25 -3.868763862603668 30.600000000000001 -3.868763862603668 - 34.876 -3.868763862603668 41.8 -3.868763862603668 48.200000000000003 -3.868763862603668 - 52 -3.868763862603668; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 80.239686562403847 13 80.239686562403847 - 16 54.077927468358183 25 55.762517552242812 30.600000000000001 55.762517552242812 - 34.876 110.97588549878063 41.8 19.895885498785315 48.200000000000003 80.239686562403847 - 52 54.077927468358183; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 5.8978517871634404 13 5.8978517871634404 - 16 5.8978517871634288 25 5.8978517871634368 30.600000000000001 5.8978517871634368 - 34.876 5.8978517871634333 41.8 5.8978517871634288 48.200000000000003 5.8978517871634404 - 52 5.8978517871634288; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.92545182592768849 13 0.92545182592768849 - 16 0.92545182592768971 25 0.92545182592768871 30.600000000000001 0.92545182592768871 - 34.876 0.92545182592769071 41.8 0.92545182592769171 48.200000000000003 0.92545182592768849 - 52 0.92545182592768971; - setAttr -s 9 ".kit[0:8]" 9 3 9 3 3 3 3 - 3 9; - setAttr -s 9 ".kot[0:8]" 9 3 9 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 13 1 16 1 25 1 30.600000000000001 - 1 34.876 1 41.8 1 48.200000000000003 1 52 1; - setAttr -s 9 ".kot[1:8]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1 52 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1 52 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1 52 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 16 -12.41287000000041 25 -12.41287000000041 33.616 - -12.41287000000041 37.348 -12.41287000000041 44.200000000000003 -12.41287000000041 - 48.200000000000003 -12.41287000000041 52 -12.41287000000041; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 16 -6.7285999999993047 25 -6.7285999999993047 33.616 - -6.7285999999993047 37.348 -6.7285999999993047 44.200000000000003 -6.7285999999993047 - 48.200000000000003 -6.7285999999993047 52 -6.7285999999993047; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 16 -3.8687599999999316 25 -3.8687599999999316 33.616 - -3.8687599999999316 37.348 -3.8687599999999316 44.200000000000003 -3.8687599999999316 - 48.200000000000003 -3.8687599999999316 52 -3.8687599999999316; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 58.099612817676174 10.6 82.316033184538099 - 13 82.316033184538099 16 64.08197397813943 25 97.683090386840206 33.616 53.821890365126315 - 37.348 -10.072402928647007 44.200000000000003 45.282566297638787 48.200000000000003 - 82.316033184538099 52 64.08197397813943; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10.6 0 13 0 16 0 25 0 33.616 - 0 37.348 0 44.200000000000003 0 48.200000000000003 0 52 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 10.6 0 13 0 16 0 25 0 33.616 - 0 37.348 0 44.200000000000003 0 48.200000000000003 0 52 0; - setAttr -s 10 ".kit[0:9]" 9 9 3 9 3 3 3 - 3 3 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 9 3 3 3 - 3 3 9; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 10.6 1 13 1 16 1 25 1 33.616 - 1 37.348 1 44.200000000000003 1 48.200000000000003 1 52 1; - setAttr -s 10 ".kot[2:9]" 5 5 5 5 5 5 5 - 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.365\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.365\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 16 -max 52 -ast 16 -aet 52 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 52 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -5.8807954640291324 16 8.5156304394485858 - 26 -3.3842862675489864 32.200000000000003 59.43985759115133 34.876 67.718224866084512 - 35.492 49.782078750379959 36.112 2.9566598552920471 37.36 -14.325185707358159 - 42 -21.775397049639 52 8.5156304394485858; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.4977373448908193 16 -41.436655454713687 - 26 24.158999191717797 32.200000000000003 -6.4530174823216635 34.876 -162.88377979146023 - 35.492 -104.91854193010487 36.112 -70.19765518443279 37.36 -90.249964522452984 - 42 -73.633745821089818 52 -41.436655454713687; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 22.979007009556593 16 16.360110645449957 - 26 27.448763083984442 32.200000000000003 -22.019983593182211 34.876 -100.60191722424253 - 35.492 -55.224743769963553 36.112 -25.723945146099769 37.36 -33.011917662712847 - 42 7.8337284132215155 52 16.360110645449957; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.0821100000000254 16 -3.0821100000000254 - 26 -3.0821100000000254 32.200000000000003 -3.0821100000000254 34.876 -3.0821100000000254 - 35.492 -3.0821100000000254 36.112 -3.0821100000000254 37.36 -3.0821100000000254 - 42 -3.0821100000000254 52 -3.0821100000000254; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 2.1192000000001707 16 2.1192000000001707 - 26 2.1192000000001707 32.200000000000003 2.1192000000001707 34.876 2.1192000000001707 - 35.492 2.1192000000001707 36.112 2.1192000000001707 37.36 2.1192000000001707 - 42 2.1192000000001707 52 2.1192000000001707; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 -3.3867499999998705 16 -3.3867499999998705 - 26 -3.3867499999998705 32.200000000000003 -3.3867499999998705 34.876 -3.3867499999998705 - 35.492 -3.3867499999998705 36.112 -3.3867499999998705 37.36 -3.3867499999998705 - 42 -3.3867499999998705 52 -3.3867499999998705; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 52 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 52 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 13 1 16 1 26 1 32.200000000000003 - 1 34.876 1 35.492 1 36.112 1 37.36 1 42 1 52 1; - setAttr -s 10 ".kit[1:9]" 9 3 3 3 3 3 3 - 3 9; - setAttr -s 10 ".kot[1:9]" 9 3 3 3 3 3 3 - 3 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 1 16 1 27 1 31 1 35 1 40 1 47 - 1 52 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 3.3867545965885748 16 3.3867545965885748 - 27 3.3867545965885748 31 3.3867545965885748 35 3.3867545965885748 40 3.3867545965885748 - 47 3.3867545965885748 52 3.3867545965885748; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 2.1192573708760349 16 2.1192573708760349 - 27 2.1192573708760349 31 2.1192573708760349 35 2.1192573708760349 40 2.1192573708760349 - 47 2.1192573708760349 52 2.1192573708760349; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 -3.0821078932592165 16 -3.0821078932592165 - 27 -3.0821078932592165 31 -3.0821078932592165 35 -3.0821078932592165 40 -3.0821078932592165 - 47 -3.0821078932592165 52 -3.0821078932592165; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 16 75.312657822261826 27 52.03641153059894 - 31 77.530595320103998 35 -29.908412796047013 40 6.6887517907386203 47 8.4502900525533118 - 52 75.312657822261826; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 0 16 11.771191120276887 27 -13.243269063885283 - 31 2.3533207651067061 35 -65.989413206281768 40 -41.519786912787602 47 15.261250420176914 - 52 11.771191120276887; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 -6.7129388973255946 16 14.730782984337566 - 27 -9.6664441727559041 31 20.260834327498888 35 -10.337452128101978 40 -48.392671971163551 - 47 -3.6433010564125698 52 14.730782984337566; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 1 16 1 27 1 31 1 35 1 40 1 47 - 1 52 1; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 1 16 1 27 1 31 1 35 1 40 1 47 - 1 52 1; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 13 1 16 1 27 1 31 1 35 1 40 1 47 - 1 52 1; - setAttr -s 8 ".kit[1:7]" 9 3 3 3 9 9 9; - setAttr -s 8 ".kot[1:7]" 9 3 3 3 9 9 9; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 29 1 35 1 40 1 52 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -2.5294371750177831 29 -2.5294371750177831 - 35 -2.5294371750177831 40 -2.5294371750177831 52 -2.5294371750177831; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 13.481673551673362 29 13.481673551673362 - 35 13.481673551673362 40 13.481673551673362 52 13.481673551673362; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -0.26635088939205875 29 -0.26635088939205875 - 35 -0.26635088939205875 40 -0.26635088939205875 52 -0.26635088939205875; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 97.855881494193042 29 141.20709981379272 - 35 152.96344280164271 40 184.89719599566124 52 97.855881494193042; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 148.48318103992199 29 64.064019952206479 - 35 139.72900819152471 40 155.90140465165601 52 148.48318103992199; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 185.52482540053091 29 252.95011708695623 - 35 248.32318073773087 40 261.12614011805363 52 185.52482540053091; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 52 15.445123296459185; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 52 15.445123296459185; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 15.445123296459185 29 15.445123296459185 - 35 15.445123296459185 40 15.445123296459185 52 15.445123296459185; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 0 35 0 40 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 1 35 1 40 0.19999999999999996 - 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 0 35 0 40 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 0 35 0 40 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 0 35 0 40 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 29 0 35 0 40 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 1 25 1 26 1 27 1 28 1 29 1 34 - 1 36 1 39 1 44 1 52 1; - setAttr -s 11 ".kot[0:10]" 5 5 5 5 5 5 5 - 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -7.5406347832540632e-013 25 - -7.5406347832540632e-013 26 -7.5406347832540632e-013 27 -7.5406347832540632e-013 - 28 -7.5406347832540632e-013 29 -7.5406347832540632e-013 34 -7.5406347832540632e-013 - 36 -7.5406347832540632e-013 39 -7.5406347832540632e-013 44 -7.5406347832540632e-013 - 52 -7.5406347832540632e-013; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 13.71946295727715 25 13.71946295727715 - 26 13.71946295727715 27 13.71946295727715 28 13.71946295727715 29 13.71946295727715 - 34 13.71946295727715 36 13.71946295727715 39 13.71946295727715 44 13.71946295727715 - 52 13.71946295727715; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -3.0908609005564358e-013 25 - -3.0908609005564358e-013 26 -3.0908609005564358e-013 27 -3.0908609005564358e-013 - 28 -3.0908609005564358e-013 29 -3.0908609005564358e-013 34 -3.0908609005564358e-013 - 36 -3.0908609005564358e-013 39 -3.0908609005564358e-013 44 -3.0908609005564358e-013 - 52 -3.0908609005564358e-013; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 260.01204204600725 25 371.81698241758346 - 26 341.72938901265888 27 316.91500938239909 28 -56.429127733094752 29 -63.128460417457674 - 34 77.739160914831501 36 253.58951914813761 39 71.559257816680997 44 -0.52444715856921864 - 52 260.01204204600725; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -38.320908201910434 25 -54.351726169543703 - 26 -46.10431805179325 27 -56.310082641832359 28 -52.674300990047442 29 -70.10134924460381 - 34 -76.726154744596627 36 -51.959710397762237 39 -46.571202148179758 44 -56.835484376724843 - 52 -38.320908201910434; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 -322.65738741293052 25 -421.93598632875813 - 26 -425.06390674275218 27 -383.14789382944997 28 -36.446894902195744 29 -6.8807221056785242 - 34 -173.86213662459591 36 -365.60209280718618 39 -116.68772684506173 44 -63.927976809723475 - 52 -322.65738741293052; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459183 25 15.445123296459183 - 26 15.445123296459183 27 15.445123296459183 28 15.445123296459183 29 15.445123296459183 - 34 15.445123296459183 36 15.445123296459183 39 15.445123296459183 44 15.445123296459183 - 52 15.445123296459183; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459185 25 15.445123296459185 - 26 15.445123296459185 27 15.445123296459185 28 15.445123296459185 29 15.445123296459185 - 34 15.445123296459185 36 15.445123296459185 39 15.445123296459185 44 15.445123296459185 - 52 15.445123296459185; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 15.445123296459181 25 15.445123296459181 - 26 15.445123296459181 27 15.445123296459181 28 15.445123296459181 29 15.445123296459181 - 34 15.445123296459181 36 15.445123296459181 39 15.445123296459181 44 15.445123296459181 - 52 15.445123296459181; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 52 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0.70000000000000007 25 0.70000000000000007 - 26 0.70000000000000007 27 0.70000000000000007 28 0.70000000000000007 29 0.70000000000000007 - 34 0.70000000000000007 36 0 39 0.158203125 44 0.5 52 0.70000000000000007; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 52 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 1 39 0.68359375 44 0 52 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 52 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 11 ".ktv[0:10]" 16 0 25 0 26 0 27 0 28 0 29 0 34 - 0 36 0 39 0 44 0 52 0; - setAttr -s 11 ".kit[6:10]" 3 3 3 3 9; - setAttr -s 11 ".kot[6:10]" 3 3 3 3 9; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -1.4752837996356043 22 -1.3864483331337971 - 29 -1.865128947678026 35 -1.196221183104005; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -3.4429152318518517 22 -3.5176571193192414 - 29 -3.8281732756743612 35 -4.3171539839663167; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 4.6597910865832972 22 3.50938048508575 - 29 3.6017971266837443 35 6.7011525574960222; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -26.447332316722964 22 -26.447332316722964 - 29 -26.447332316722964 35 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -67.357715796337814 22 -67.357715796337814 - 29 -67.357715796337814 35 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 24.545813639883598 22 24.545813639883598 - 29 24.545813639883598 35 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 22 1 29 1 35 1; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 -6.6987428689401023 52 -6.6987428689401023; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 -1.0063285154727897 52 -1.0063285154727897; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 3.9024574139229289 52 3.9024574139229289; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 17.856773962630957 52 17.856773962630957; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 -36.171253008403404 52 -36.171253008403404; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 -10.870404993254283 52 -10.870404993254283; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 9.6873596619451892 52 9.6873596619451892; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 0.098625839244114 52 0.098625839244114; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 14.651463035095317 52 14.651463035095317; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 4.9130999348608286 52 4.9130999348608286; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 35.947765167312816 52 35.947765167312816; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 8.3268568844740365 52 8.3268568844740365; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 16 1 52 1; - setAttr -s 2 ".kit[1]" 9; - setAttr -s 2 ".kot[1]" 9; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1.9225081589985762 25 1.9225081589985762 - 34 1.922508158998576 37 1.9225081589985795 43 1.9225081589985797 52 1.9225081589985762; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 35.652019839492347 25 32.495992983680701 - 34 39.89293092698928 37 38.165109730359134 43 39.695679248501058 52 35.652019839492347; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 13.461907599494868 25 7.741608923336269 - 34 1.9226844079335621 37 20.135685197861509 43 24.113498237859186 52 13.461907599494868; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1 25 1 34 1 37 1 43 1 52 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0.64576725303311566 25 0.64576725303311566 - 34 -14.418175126180156 37 -9.2797458328031528 43 0.64576725303311566 52 0.64576725303311566; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0 25 0 34 0.12335211885617081 - 37 0.081275739949692158 43 0 52 0; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 0.47460937865742331 25 0.47460937865742331 - 34 0.45829972899090571 37 0.46386307888792871 43 0.47460937865742331 52 0.47460937865742331; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1 25 1 34 1 37 1 43 1 52 1; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1 25 1 34 1 37 1 43 1 52 1; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 16 1 25 1 34 1 37 1 43 1 52 1; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -97.8430816148296 28 -104.65989170272563 - 48 -105.04669228748357 52 -97.8430816148296; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 2.1461068188508792 28 21.21605756681512 - 48 28.286885597002083 52 2.1461068188508792; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -85.383790866488482 28 -93.412541155030866 - 48 -72.619389877795342 52 -85.383790866488482; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 28 0 48 0 52 0; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 28 0 48 0 52 0; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 28 1 48 1 52 1; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 28 0 48 0 52 0; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 28 0 48 0 52 0; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 28 0 48 0 52 0; - setAttr -s 4 ".kit[3]" 9; - setAttr -s 4 ".kot[3]" 9; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -81.042166485265085 25 -70.39442373980151 - 36 -81.265284948031777 45 -68.679661051817945 52 -81.042166485265085; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 53.942839579097168 25 54.083841733575504 - 36 38.698922056984699 45 52.598761219558085 52 53.942839579097168; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 -93.582844077068899 25 -101.89044795554996 - 36 -100.7635681763023 45 -83.847793543476271 52 -93.582844077068899; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 25 0 36 0 45 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 25 0 36 0 45 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 1 25 1 36 1 45 1 52 1; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 25 0 36 0 45 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 25 0 36 0 45 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 16 0 25 0 36 0 45 0 52 0; - setAttr -s 5 ".kit[0:4]" 9 3 3 3 9; - setAttr -s 5 ".kot[0:4]" 9 3 3 3 9; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Chin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Chin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Chin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Face_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Face_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Face_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Hips_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Hips_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Hips_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Jaw_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Jaw_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Jaw_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -2.1064832569487142; -createNode animCurveTA -n "IMP_Lball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.36693656610454173; -createNode animCurveTA -n "IMP_Lball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 12.728045273286209; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 33.892693033620276; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 54.671688625550239; -createNode animCurveTA -n "IMP_Lhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 39.468648652835569; -createNode animCurveTA -n "IMP_Lhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 68.627482547296808; -createNode animCurveTA -n "IMP_Lloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.53417648123720507; -createNode animCurveTA -n "IMP_Lloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -10.053814532576119; -createNode animCurveTA -n "IMP_Lrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Ltoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -43.059580412880401; -createNode animCurveTA -n "IMP_Lupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 15.980315328783769; -createNode animCurveTA -n "IMP_Lupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 23.894233263106457; -createNode animCurveTA -n "IMP_Rankle_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rankle_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rankle_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rball_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -17.499757121316115; -createNode animCurveTA -n "IMP_Rball_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.2695897469829736; -createNode animCurveTA -n "IMP_Rball_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -6.9162979482121418; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 9.4749040322149245; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -58.854902956455234; -createNode animCurveTA -n "IMP_Rhand_GOAL_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -8.3632933901642268; -createNode animCurveTA -n "IMP_Rhand_IK_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_IK_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rloleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 69.169457744125054; -createNode animCurveTA -n "IMP_Rloleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.89079518170882233; -createNode animCurveTA -n "IMP_Rloleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.0718515372162871; -createNode animCurveTA -n "IMP_Rrib_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rrib_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rrib_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rshldr_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rshldr_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rshldr_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtip2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe1_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rtoe2_r_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rupleg_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -16.391343056341235; -createNode animCurveTA -n "IMP_Rupleg_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.97886024449907483; -createNode animCurveTA -n "IMP_Rupleg_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 16.978005640695013; -createNode animCurveTA -n "IMP_Shoulders_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Shoulders_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Shoulders_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector1_rotateZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_effector4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_Rtoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 13.663320674475715; -createNode animCurveTL -n "IMP_Rtoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Rtoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -2.4865668606186692e-016; -createNode animCurveTU -n "IMP_Rtoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.7758528420198658; -createNode animCurveTL -n "IMP_Rball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Rball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -9.5120444723942321e-016; -createNode animCurveTU -n "IMP_Rball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.2353930143209828; -createNode animCurveTL -n "IMP_Rankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.58855436141337392; -createNode animCurveTL -n "IMP_Rankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.10942982456140288; -createNode animCurveTU -n "IMP_Rankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 13.663320674475715; -createNode animCurveTL -n "IMP_Ltoe_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.4694469519536142e-018; -createNode animCurveTL -n "IMP_Ltoe_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -2.4865668606186692e-016; -createNode animCurveTU -n "IMP_Ltoe_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.7758528420198658; -createNode animCurveTL -n "IMP_Lball_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -6.9388939039072284e-018; -createNode animCurveTL -n "IMP_Lball_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -9.5120444723942321e-016; -createNode animCurveTU -n "IMP_Lball_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.2353930143209828; -createNode animCurveTL -n "IMP_Lankle_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.58855436141337392; -createNode animCurveTL -n "IMP_Lankle_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.10942982456140288; -createNode animCurveTU -n "IMP_Lankle_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Shoulders_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Shoulders_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Shoulders_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 5.5258192723085173; -createNode animCurveTL -n "IMP_Shoulders_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.1525507362789047; -createNode animCurveTU -n "IMP_Shoulders_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Shoulders_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Shoulders_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Face_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Face_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Face_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.1924108426844384; -createNode animCurveTL -n "IMP_Face_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.3533140211779946; -createNode animCurveTU -n "IMP_Face_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Face_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Face_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Jaw_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Jaw_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Jaw_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.74525677667777757; -createNode animCurveTL -n "IMP_Jaw_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.8072476834435935; -createNode animCurveTU -n "IMP_Jaw_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Jaw_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Jaw_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Chin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Chin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Chin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -3.9684923358091311; -createNode animCurveTL -n "IMP_Chin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 2.2916645882841449; -createNode animCurveTU -n "IMP_Chin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Chin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Chin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.085679155728795; -createNode animCurveTL -n "IMP_Lshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.1537911794025533; -createNode animCurveTL -n "IMP_Lshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.6185070801020824; -createNode animCurveTU -n "IMP_Lshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 12.890532588149956; -createNode animCurveTL -n "IMP_Lhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.69008032694306476; -createNode animCurveTL -n "IMP_Lhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.645694319339265; -createNode animCurveTU -n "IMP_Lhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_effector4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector4_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rshldr_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rshldr_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.08568; -createNode animCurveTL -n "IMP_Rshldr_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.1537988160630093; -createNode animCurveTL -n "IMP_Rshldr_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.6185075120832098; -createNode animCurveTU -n "IMP_Rshldr_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rshldr_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rshldr_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -12.890500000000031; -createNode animCurveTL -n "IMP_Rhand_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.6900999999992341; -createNode animCurveTL -n "IMP_Rhand_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.6456900000000347; -createNode animCurveTU -n "IMP_Rhand_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rthumb_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rpinky_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rring_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rring_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_lo_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_lo_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_lo_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_tip_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rindex_tip_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rindex_tip_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -4.0846345617354372; -createNode animCurveTL -n "IMP_Rrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.282468147773308; -createNode animCurveTL -n "IMP_Rrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 7.7712681071056613; -createNode animCurveTU -n "IMP_Rrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lrib_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lrib_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.4264261331675518; -createNode animCurveTL -n "IMP_Lrib_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.3937238431314825; -createNode animCurveTL -n "IMP_Lrib_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 7.7712681071056613; -createNode animCurveTU -n "IMP_Lrib_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lrib_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lrib_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Hips_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Hips_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.0180767416209342; -createNode animCurveTL -n "IMP_Hips_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.350740136846035; -createNode animCurveTL -n "IMP_Hips_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 2.679538405939565; -createNode animCurveTU -n "IMP_Hips_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Hips_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Hips_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -3.6380577235397413; -createNode animCurveTL -n "IMP_Rupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -5.9996743942435486; -createNode animCurveTL -n "IMP_Rupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -2.7995714837697929; -createNode animCurveTU -n "IMP_Rupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 19.149140381761772; -createNode animCurveTL -n "IMP_Rloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.3756686479080088; -createNode animCurveTL -n "IMP_Rloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.21075234496274775; -createNode animCurveTU -n "IMP_Rloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 20.742856452934195; -createNode animCurveTL -n "IMP_Rankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.84893801560717619; -createNode animCurveTL -n "IMP_Rankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.16812918533366403; -createNode animCurveTU -n "IMP_Rankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 5.9175729778873523; -createNode animCurveTL -n "IMP_Rball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.85605761867933861; -createNode animCurveTL -n "IMP_Rball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.5874050102942485; -createNode animCurveTU -n "IMP_Rball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 2.9900427762468107; -createNode animCurveTL -n "IMP_Rtoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.91245575548367119; -createNode animCurveTL -n "IMP_Rtoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.39837671684541476; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 5.169754565364844; -createNode animCurveTL -n "IMP_Rtip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.0564808409517294; -createNode animCurveTL -n "IMP_Rtip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.42012489059707847; -createNode animCurveTU -n "IMP_Rtip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.46895946313800008; -createNode animCurveTL -n "IMP_Rtoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.744537024733662; -createNode animCurveTL -n "IMP_Rtoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.043574269372096713; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rtip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.1287329396630019; -createNode animCurveTL -n "IMP_Rtip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.85810195764911135; -createNode animCurveTL -n "IMP_Rtip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.32542761684201271; -createNode animCurveTU -n "IMP_Rtip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rtip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lupleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lupleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.8784880075680586; -createNode animCurveTL -n "IMP_Lupleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -5.9996743942435486; -createNode animCurveTL -n "IMP_Lupleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -2.7995714837697929; -createNode animCurveTU -n "IMP_Lupleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lupleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lupleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lloleg_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lloleg_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 18.980231639280721; -createNode animCurveTL -n "IMP_Lloleg_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.663797374263001; -createNode animCurveTL -n "IMP_Lloleg_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.41525250862709329; -createNode animCurveTU -n "IMP_Lloleg_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lloleg_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lloleg_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lankle_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 20.799371406295553; -createNode animCurveTL -n "IMP_Lankle_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.32904719010364564; -createNode animCurveTL -n "IMP_Lankle_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.16941601589852961; -createNode animCurveTU -n "IMP_Lankle_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lankle_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lball_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 6.1142991392184163; -createNode animCurveTL -n "IMP_Lball_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.13638708324248117; -createNode animCurveTL -n "IMP_Lball_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.0994349581901075; -createNode animCurveTU -n "IMP_Lball_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lball_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 2.5124344559409741; -createNode animCurveTL -n "IMP_Ltoe1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.5859239079718024; -createNode animCurveTL -n "IMP_Ltoe1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.3423521551430217; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip1_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip1_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.6684103441767562; -createNode animCurveTL -n "IMP_Ltip1_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.21264207246076725; -createNode animCurveTL -n "IMP_Ltip1_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.3825986145063745; -createNode animCurveTU -n "IMP_Ltip1_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip1_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltoe2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.4623854590403933; -createNode animCurveTL -n "IMP_Ltoe2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 3.8711962578925494; -createNode animCurveTL -n "IMP_Ltoe2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.1098661950250604; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltoe2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip2_r_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Ltip2_r_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 4.9497075072661634; -createNode animCurveTL -n "IMP_Ltip2_r_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.748040561262465; -createNode animCurveTL -n "IMP_Ltip2_r_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.35737371225579673; -createNode animCurveTU -n "IMP_Ltip2_r_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Ltip2_r_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint4_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_joint4_orientConstraint1_joint7W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_nodeState1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_joint3_orientConstraint1_offsetZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_joint3_orientConstraint1_joint8W1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_effector1_scaleX1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_scaleY1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_scaleZ1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_effector1_hideDisplay1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Rhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -0.56289496886315527; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.38790618358257895; -createNode animCurveTU -n "IMP_Rhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.8795419779211335; -createNode animCurveTU -n "IMP_Rhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Rhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Rhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_IK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "IMP_Lhand_IK_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_IK_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.35285267709867663; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.6628726160188414; -createNode animCurveTU -n "IMP_Lhand_IK_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.0537312993167247; -createNode animCurveTU -n "IMP_Lhand_IK_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_IK_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTA -n "IMP_Lhand_IK_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_Lhand_IK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -29.775800000000025; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 57.582500000000032; -createNode animCurveTL -n "IMP_Rhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.0893083480314791; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.99999999999999978; -createNode animCurveTU -n "IMP_Rhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 29.775846152470962; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 57.582470209590937; -createNode animCurveTL -n "IMP_Lhand_GOAL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 -1.0893063224582775; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.99999999999999989; -createNode animCurveTU -n "IMP_Lhand_GOAL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0.99999999999999978; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_LIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_LIK_pointConstraint1_LankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_RIK_pointConstraint1_offsetZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_RIK_pointConstraint1_RankleW0"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 52 1.25; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 16.827384499368584; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -2.4031351987482168; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -select -ne :time1; - setAttr ".o" 16; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_Rmissile; - setAttr ".jo" -type "double3" 10.172609088116557 69.500974497559 0.3202113397221672 ; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Rtoe_scaleX.o" "IMP_Rtoe.sx"; -connectAttr "IMP_Rtoe_scaleY.o" "IMP_Rtoe.sy"; -connectAttr "IMP_Rtoe_scaleZ.o" "IMP_Rtoe.sz"; -connectAttr "IMP_Rtoe_rotateX.o" "IMP_Rtoe.rx"; -connectAttr "IMP_Rtoe_rotateY.o" "IMP_Rtoe.ry"; -connectAttr "IMP_Rtoe_rotateZ.o" "IMP_Rtoe.rz"; -connectAttr "IMP_Rtoe_visibility.o" "IMP_Rtoe.v"; -connectAttr "IMP_Rtoe_translateX.o" "IMP_Rtoe.tx"; -connectAttr "IMP_Rtoe_translateY.o" "IMP_Rtoe.ty"; -connectAttr "IMP_Rtoe_translateZ.o" "IMP_Rtoe.tz"; -connectAttr "IMP_Rball_scaleX.o" "IMP_Rball.sx"; -connectAttr "IMP_Rball_scaleY.o" "IMP_Rball.sy"; -connectAttr "IMP_Rball_scaleZ.o" "IMP_Rball.sz"; -connectAttr "IMP_Rball_rotateX.o" "IMP_Rball.rx"; -connectAttr "IMP_Rball_rotateZ.o" "IMP_Rball.rz"; -connectAttr "IMP_Rball_rotateY.o" "IMP_Rball.ry"; -connectAttr "IMP_Rball_translateX.o" "IMP_Rball.tx"; -connectAttr "IMP_Rball_translateY.o" "IMP_Rball.ty"; -connectAttr "IMP_Rball_translateZ.o" "IMP_Rball.tz"; -connectAttr "IMP_Rball_visibility.o" "IMP_Rball.v"; -connectAttr "IMP_Rankle_translateX.o" "IMP_Rankle.tx"; -connectAttr "IMP_Rankle_translateY.o" "IMP_Rankle.ty"; -connectAttr "IMP_Rankle_translateZ.o" "IMP_Rankle.tz"; -connectAttr "IMP_Rankle_rotateX.o" "IMP_Rankle.rx"; -connectAttr "IMP_Rankle_rotateY.o" "IMP_Rankle.ry"; -connectAttr "IMP_Rankle_rotateZ.o" "IMP_Rankle.rz"; -connectAttr "IMP_Rankle_visibility.o" "IMP_Rankle.v"; -connectAttr "IMP_Rankle_scaleX.o" "IMP_Rankle.sx"; -connectAttr "IMP_Rankle_scaleY.o" "IMP_Rankle.sy"; -connectAttr "IMP_Rankle_scaleZ.o" "IMP_Rankle.sz"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Ltoe_scaleX.o" "IMP_Ltoe.sx"; -connectAttr "IMP_Ltoe_scaleY.o" "IMP_Ltoe.sy"; -connectAttr "IMP_Ltoe_scaleZ.o" "IMP_Ltoe.sz"; -connectAttr "IMP_Ltoe_rotateX.o" "IMP_Ltoe.rx"; -connectAttr "IMP_Ltoe_rotateY.o" "IMP_Ltoe.ry"; -connectAttr "IMP_Ltoe_rotateZ.o" "IMP_Ltoe.rz"; -connectAttr "IMP_Ltoe_visibility.o" "IMP_Ltoe.v"; -connectAttr "IMP_Ltoe_translateX.o" "IMP_Ltoe.tx"; -connectAttr "IMP_Ltoe_translateY.o" "IMP_Ltoe.ty"; -connectAttr "IMP_Ltoe_translateZ.o" "IMP_Ltoe.tz"; -connectAttr "IMP_Lball_scaleX.o" "IMP_Lball.sx"; -connectAttr "IMP_Lball_scaleY.o" "IMP_Lball.sy"; -connectAttr "IMP_Lball_scaleZ.o" "IMP_Lball.sz"; -connectAttr "IMP_Lball_rotateX.o" "IMP_Lball.rx"; -connectAttr "IMP_Lball_rotateY.o" "IMP_Lball.ry"; -connectAttr "IMP_Lball_rotateZ.o" "IMP_Lball.rz"; -connectAttr "IMP_Lball_translateX.o" "IMP_Lball.tx"; -connectAttr "IMP_Lball_translateY.o" "IMP_Lball.ty"; -connectAttr "IMP_Lball_translateZ.o" "IMP_Lball.tz"; -connectAttr "IMP_Lball_visibility.o" "IMP_Lball.v"; -connectAttr "IMP_Lankle_translateX.o" "IMP_Lankle.tx"; -connectAttr "IMP_Lankle_translateY.o" "IMP_Lankle.ty"; -connectAttr "IMP_Lankle_translateZ.o" "IMP_Lankle.tz"; -connectAttr "IMP_Lankle_rotateX.o" "IMP_Lankle.rx"; -connectAttr "IMP_Lankle_rotateY.o" "IMP_Lankle.ry"; -connectAttr "IMP_Lankle_rotateZ.o" "IMP_Lankle.rz"; -connectAttr "IMP_Lankle_visibility.o" "IMP_Lankle.v"; -connectAttr "IMP_Lankle_scaleX.o" "IMP_Lankle.sx"; -connectAttr "IMP_Lankle_scaleY.o" "IMP_Lankle.sy"; -connectAttr "IMP_Lankle_scaleZ.o" "IMP_Lankle.sz"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Shoulders_scaleX.o" "IMP_Shoulders.sx"; -connectAttr "IMP_Shoulders_scaleY.o" "IMP_Shoulders.sy"; -connectAttr "IMP_Shoulders_scaleZ.o" "IMP_Shoulders.sz"; -connectAttr "IMP_Shoulders_rotateX.o" "IMP_Shoulders.rx"; -connectAttr "IMP_Shoulders_rotateY.o" "IMP_Shoulders.ry"; -connectAttr "IMP_Shoulders_rotateZ.o" "IMP_Shoulders.rz"; -connectAttr "IMP_Shoulders_visibility.o" "IMP_Shoulders.v"; -connectAttr "IMP_Shoulders_translateX.o" "IMP_Shoulders.tx"; -connectAttr "IMP_Shoulders_translateY.o" "IMP_Shoulders.ty"; -connectAttr "IMP_Shoulders_translateZ.o" "IMP_Shoulders.tz"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Face_rotateX.o" "IMP_Face.rx"; -connectAttr "IMP_Face_rotateY.o" "IMP_Face.ry"; -connectAttr "IMP_Face_rotateZ.o" "IMP_Face.rz"; -connectAttr "IMP_Face_visibility.o" "IMP_Face.v"; -connectAttr "IMP_Face_translateX.o" "IMP_Face.tx"; -connectAttr "IMP_Face_translateY.o" "IMP_Face.ty"; -connectAttr "IMP_Face_translateZ.o" "IMP_Face.tz"; -connectAttr "IMP_Face_scaleX.o" "IMP_Face.sx"; -connectAttr "IMP_Face_scaleY.o" "IMP_Face.sy"; -connectAttr "IMP_Face_scaleZ.o" "IMP_Face.sz"; -connectAttr "IMP_Jaw_scaleX.o" "IMP_Jaw.sx"; -connectAttr "IMP_Jaw_scaleY.o" "IMP_Jaw.sy"; -connectAttr "IMP_Jaw_scaleZ.o" "IMP_Jaw.sz"; -connectAttr "IMP_Jaw_rotateX.o" "IMP_Jaw.rx"; -connectAttr "IMP_Jaw_rotateY.o" "IMP_Jaw.ry"; -connectAttr "IMP_Jaw_rotateZ.o" "IMP_Jaw.rz"; -connectAttr "IMP_Jaw_visibility.o" "IMP_Jaw.v"; -connectAttr "IMP_Jaw_translateX.o" "IMP_Jaw.tx"; -connectAttr "IMP_Jaw_translateY.o" "IMP_Jaw.ty"; -connectAttr "IMP_Jaw_translateZ.o" "IMP_Jaw.tz"; -connectAttr "IMP_Chin_rotateX.o" "IMP_Chin.rx"; -connectAttr "IMP_Chin_rotateY.o" "IMP_Chin.ry"; -connectAttr "IMP_Chin_rotateZ.o" "IMP_Chin.rz"; -connectAttr "IMP_Chin_visibility.o" "IMP_Chin.v"; -connectAttr "IMP_Chin_translateX.o" "IMP_Chin.tx"; -connectAttr "IMP_Chin_translateY.o" "IMP_Chin.ty"; -connectAttr "IMP_Chin_translateZ.o" "IMP_Chin.tz"; -connectAttr "IMP_Chin_scaleX.o" "IMP_Chin.sx"; -connectAttr "IMP_Chin_scaleY.o" "IMP_Chin.sy"; -connectAttr "IMP_Chin_scaleZ.o" "IMP_Chin.sz"; -connectAttr "IMP_Lshldr_scaleX.o" "IMP_Lshldr.sx"; -connectAttr "IMP_Lshldr_scaleY.o" "IMP_Lshldr.sy"; -connectAttr "IMP_Lshldr_scaleZ.o" "IMP_Lshldr.sz"; -connectAttr "IMP_Lshldr_rotateX.o" "IMP_Lshldr.rx"; -connectAttr "IMP_Lshldr_rotateY.o" "IMP_Lshldr.ry"; -connectAttr "IMP_Lshldr_rotateZ.o" "IMP_Lshldr.rz"; -connectAttr "IMP_Lshldr_visibility.o" "IMP_Lshldr.v"; -connectAttr "IMP_Lshldr_translateX.o" "IMP_Lshldr.tx"; -connectAttr "IMP_Lshldr_translateY.o" "IMP_Lshldr.ty"; -connectAttr "IMP_Lshldr_translateZ.o" "IMP_Lshldr.tz"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Lhand_scaleX.o" "IMP_Lhand.sx"; -connectAttr "IMP_Lhand_scaleY.o" "IMP_Lhand.sy"; -connectAttr "IMP_Lhand_scaleZ.o" "IMP_Lhand.sz"; -connectAttr "IMP_Lhand_translateX.o" "IMP_Lhand.tx"; -connectAttr "IMP_Lhand_translateY.o" "IMP_Lhand.ty"; -connectAttr "IMP_Lhand_translateZ.o" "IMP_Lhand.tz"; -connectAttr "IMP_Lhand_visibility.o" "IMP_Lhand.v"; -connectAttr "IMP_Lthumb_lo_scaleX.o" "IMP_Lthumb_lo.sx"; -connectAttr "IMP_Lthumb_lo_scaleY.o" "IMP_Lthumb_lo.sy"; -connectAttr "IMP_Lthumb_lo_scaleZ.o" "IMP_Lthumb_lo.sz"; -connectAttr "IMP_Lthumb_lo_visibility.o" "IMP_Lthumb_lo.v"; -connectAttr "IMP_Lthumb_base_scaleX.o" "IMP_Lthumb_base.sx"; -connectAttr "IMP_Lthumb_base_scaleY.o" "IMP_Lthumb_base.sy"; -connectAttr "IMP_Lthumb_base_scaleZ.o" "IMP_Lthumb_base.sz"; -connectAttr "IMP_Lthumb_base_visibility.o" "IMP_Lthumb_base.v"; -connectAttr "IMP_Lthumb_mid_scaleX.o" "IMP_Lthumb_mid.sx"; -connectAttr "IMP_Lthumb_mid_scaleY.o" "IMP_Lthumb_mid.sy"; -connectAttr "IMP_Lthumb_mid_scaleZ.o" "IMP_Lthumb_mid.sz"; -connectAttr "IMP_Lthumb_mid_visibility.o" "IMP_Lthumb_mid.v"; -connectAttr "IMP_Lthumb_tip_visibility.o" "IMP_Lthumb_tip.v"; -connectAttr "IMP_Lthumb_tip_scaleX.o" "IMP_Lthumb_tip.sx"; -connectAttr "IMP_Lthumb_tip_scaleY.o" "IMP_Lthumb_tip.sy"; -connectAttr "IMP_Lthumb_tip_scaleZ.o" "IMP_Lthumb_tip.sz"; -connectAttr "IMP_Lpinky_base_scaleX.o" "IMP_Lpinky_base.sx"; -connectAttr "IMP_Lpinky_base_scaleY.o" "IMP_Lpinky_base.sy"; -connectAttr "IMP_Lpinky_base_scaleZ.o" "IMP_Lpinky_base.sz"; -connectAttr "IMP_Lpinky_base_visibility.o" "IMP_Lpinky_base.v"; -connectAttr "IMP_Lpinky_mid_scaleX.o" "IMP_Lpinky_mid.sx"; -connectAttr "IMP_Lpinky_mid_scaleY.o" "IMP_Lpinky_mid.sy"; -connectAttr "IMP_Lpinky_mid_scaleZ.o" "IMP_Lpinky_mid.sz"; -connectAttr "IMP_Lpinky_mid_visibility.o" "IMP_Lpinky_mid.v"; -connectAttr "IMP_Lpinky_tip_visibility.o" "IMP_Lpinky_tip.v"; -connectAttr "IMP_Lpinky_tip_scaleX.o" "IMP_Lpinky_tip.sx"; -connectAttr "IMP_Lpinky_tip_scaleY.o" "IMP_Lpinky_tip.sy"; -connectAttr "IMP_Lpinky_tip_scaleZ.o" "IMP_Lpinky_tip.sz"; -connectAttr "IMP_Lring_lo_scaleX.o" "IMP_Lring_lo.sx"; -connectAttr "IMP_Lring_lo_scaleY.o" "IMP_Lring_lo.sy"; -connectAttr "IMP_Lring_lo_scaleZ.o" "IMP_Lring_lo.sz"; -connectAttr "IMP_Lring_lo_visibility.o" "IMP_Lring_lo.v"; -connectAttr "IMP_Lring_base_scaleX.o" "IMP_Lring_base.sx"; -connectAttr "IMP_Lring_base_scaleY.o" "IMP_Lring_base.sy"; -connectAttr "IMP_Lring_base_scaleZ.o" "IMP_Lring_base.sz"; -connectAttr "IMP_Lring_base_visibility.o" "IMP_Lring_base.v"; -connectAttr "IMP_Lring_mid_scaleX.o" "IMP_Lring_mid.sx"; -connectAttr "IMP_Lring_mid_scaleY.o" "IMP_Lring_mid.sy"; -connectAttr "IMP_Lring_mid_scaleZ.o" "IMP_Lring_mid.sz"; -connectAttr "IMP_Lring_mid_visibility.o" "IMP_Lring_mid.v"; -connectAttr "IMP_Lring_tip_visibility.o" "IMP_Lring_tip.v"; -connectAttr "IMP_Lring_tip_scaleX.o" "IMP_Lring_tip.sx"; -connectAttr "IMP_Lring_tip_scaleY.o" "IMP_Lring_tip.sy"; -connectAttr "IMP_Lring_tip_scaleZ.o" "IMP_Lring_tip.sz"; -connectAttr "IMP_Lindex_lo_scaleX.o" "IMP_Lindex_lo.sx"; -connectAttr "IMP_Lindex_lo_scaleY.o" "IMP_Lindex_lo.sy"; -connectAttr "IMP_Lindex_lo_scaleZ.o" "IMP_Lindex_lo.sz"; -connectAttr "IMP_Lindex_lo_visibility.o" "IMP_Lindex_lo.v"; -connectAttr "IMP_Lindex_base_scaleX.o" "IMP_Lindex_base.sx"; -connectAttr "IMP_Lindex_base_scaleY.o" "IMP_Lindex_base.sy"; -connectAttr "IMP_Lindex_base_scaleZ.o" "IMP_Lindex_base.sz"; -connectAttr "IMP_Lindex_base_visibility.o" "IMP_Lindex_base.v"; -connectAttr "IMP_Lindex_mid_scaleX.o" "IMP_Lindex_mid.sx"; -connectAttr "IMP_Lindex_mid_scaleY.o" "IMP_Lindex_mid.sy"; -connectAttr "IMP_Lindex_mid_scaleZ.o" "IMP_Lindex_mid.sz"; -connectAttr "IMP_Lindex_mid_visibility.o" "IMP_Lindex_mid.v"; -connectAttr "IMP_Lindex_tip_visibility.o" "IMP_Lindex_tip.v"; -connectAttr "IMP_Lindex_tip_scaleX.o" "IMP_Lindex_tip.sx"; -connectAttr "IMP_Lindex_tip_scaleY.o" "IMP_Lindex_tip.sy"; -connectAttr "IMP_Lindex_tip_scaleZ.o" "IMP_Lindex_tip.sz"; -connectAttr "IMP_Lhand_orientConstraint1_nodeState.o" "IMP_Lhand_orientConstraint1.nds" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetX.o" "IMP_Lhand_orientConstraint1.ox" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetY.o" "IMP_Lhand_orientConstraint1.oy" - ; -connectAttr "IMP_Lhand_orientConstraint1_offsetZ.o" "IMP_Lhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector4_visibility.o" "IMP_effector4.v"; -connectAttr "IMP_effector4_rotateX.o" "IMP_effector4.rx"; -connectAttr "IMP_effector4_rotateY.o" "IMP_effector4.ry"; -connectAttr "IMP_effector4_rotateZ.o" "IMP_effector4.rz"; -connectAttr "IMP_effector4_scaleX.o" "IMP_effector4.sx"; -connectAttr "IMP_effector4_scaleY.o" "IMP_effector4.sy"; -connectAttr "IMP_effector4_scaleZ.o" "IMP_effector4.sz"; -connectAttr "IMP_effector4_hideDisplay.o" "IMP_effector4.hd"; -connectAttr "IMP_Rshldr_scaleX.o" "IMP_Rshldr.sx"; -connectAttr "IMP_Rshldr_scaleY.o" "IMP_Rshldr.sy"; -connectAttr "IMP_Rshldr_scaleZ.o" "IMP_Rshldr.sz"; -connectAttr "IMP_Rshldr_rotateX.o" "IMP_Rshldr.rx"; -connectAttr "IMP_Rshldr_rotateY.o" "IMP_Rshldr.ry"; -connectAttr "IMP_Rshldr_rotateZ.o" "IMP_Rshldr.rz"; -connectAttr "IMP_Rshldr_visibility.o" "IMP_Rshldr.v"; -connectAttr "IMP_Rshldr_translateX.o" "IMP_Rshldr.tx"; -connectAttr "IMP_Rshldr_translateY.o" "IMP_Rshldr.ty"; -connectAttr "IMP_Rshldr_translateZ.o" "IMP_Rshldr.tz"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_Rhand_scaleX.o" "IMP_Rhand.sx"; -connectAttr "IMP_Rhand_scaleY.o" "IMP_Rhand.sy"; -connectAttr "IMP_Rhand_scaleZ.o" "IMP_Rhand.sz"; -connectAttr "IMP_Rhand_translateX.o" "IMP_Rhand.tx"; -connectAttr "IMP_Rhand_translateY.o" "IMP_Rhand.ty"; -connectAttr "IMP_Rhand_translateZ.o" "IMP_Rhand.tz"; -connectAttr "IMP_Rhand_visibility.o" "IMP_Rhand.v"; -connectAttr "IMP_Rthumb_lo_scaleX.o" "IMP_Rthumb_lo.sx"; -connectAttr "IMP_Rthumb_lo_scaleY.o" "IMP_Rthumb_lo.sy"; -connectAttr "IMP_Rthumb_lo_scaleZ.o" "IMP_Rthumb_lo.sz"; -connectAttr "IMP_Rthumb_lo_visibility.o" "IMP_Rthumb_lo.v"; -connectAttr "IMP_Rthumb_base_scaleX.o" "IMP_Rthumb_base.sx"; -connectAttr "IMP_Rthumb_base_scaleY.o" "IMP_Rthumb_base.sy"; -connectAttr "IMP_Rthumb_base_scaleZ.o" "IMP_Rthumb_base.sz"; -connectAttr "IMP_Rthumb_base_visibility.o" "IMP_Rthumb_base.v"; -connectAttr "IMP_Rthumb_mid_scaleX.o" "IMP_Rthumb_mid.sx"; -connectAttr "IMP_Rthumb_mid_scaleY.o" "IMP_Rthumb_mid.sy"; -connectAttr "IMP_Rthumb_mid_scaleZ.o" "IMP_Rthumb_mid.sz"; -connectAttr "IMP_Rthumb_mid_visibility.o" "IMP_Rthumb_mid.v"; -connectAttr "IMP_Rthumb_tip_visibility.o" "IMP_Rthumb_tip.v"; -connectAttr "IMP_Rthumb_tip_scaleX.o" "IMP_Rthumb_tip.sx"; -connectAttr "IMP_Rthumb_tip_scaleY.o" "IMP_Rthumb_tip.sy"; -connectAttr "IMP_Rthumb_tip_scaleZ.o" "IMP_Rthumb_tip.sz"; -connectAttr "IMP_Rpinky_base_scaleX.o" "IMP_Rpinky_base.sx"; -connectAttr "IMP_Rpinky_base_scaleY.o" "IMP_Rpinky_base.sy"; -connectAttr "IMP_Rpinky_base_scaleZ.o" "IMP_Rpinky_base.sz"; -connectAttr "IMP_Rpinky_base_visibility.o" "IMP_Rpinky_base.v"; -connectAttr "IMP_Rpinky_mid_scaleX.o" "IMP_Rpinky_mid.sx"; -connectAttr "IMP_Rpinky_mid_scaleY.o" "IMP_Rpinky_mid.sy"; -connectAttr "IMP_Rpinky_mid_scaleZ.o" "IMP_Rpinky_mid.sz"; -connectAttr "IMP_Rpinky_mid_visibility.o" "IMP_Rpinky_mid.v"; -connectAttr "IMP_Rpinky_tip_visibility.o" "IMP_Rpinky_tip.v"; -connectAttr "IMP_Rpinky_tip_scaleX.o" "IMP_Rpinky_tip.sx"; -connectAttr "IMP_Rpinky_tip_scaleY.o" "IMP_Rpinky_tip.sy"; -connectAttr "IMP_Rpinky_tip_scaleZ.o" "IMP_Rpinky_tip.sz"; -connectAttr "IMP_Rring_lo_scaleX.o" "IMP_Rring_lo.sx"; -connectAttr "IMP_Rring_lo_scaleY.o" "IMP_Rring_lo.sy"; -connectAttr "IMP_Rring_lo_scaleZ.o" "IMP_Rring_lo.sz"; -connectAttr "IMP_Rring_lo_visibility.o" "IMP_Rring_lo.v"; -connectAttr "IMP_Rring_base_scaleX.o" "IMP_Rring_base.sx"; -connectAttr "IMP_Rring_base_scaleY.o" "IMP_Rring_base.sy"; -connectAttr "IMP_Rring_base_scaleZ.o" "IMP_Rring_base.sz"; -connectAttr "IMP_Rring_base_visibility.o" "IMP_Rring_base.v"; -connectAttr "IMP_Rring_mid_scaleX.o" "IMP_Rring_mid.sx"; -connectAttr "IMP_Rring_mid_scaleY.o" "IMP_Rring_mid.sy"; -connectAttr "IMP_Rring_mid_scaleZ.o" "IMP_Rring_mid.sz"; -connectAttr "IMP_Rring_mid_visibility.o" "IMP_Rring_mid.v"; -connectAttr "IMP_Rring_tip_visibility.o" "IMP_Rring_tip.v"; -connectAttr "IMP_Rring_tip_scaleX.o" "IMP_Rring_tip.sx"; -connectAttr "IMP_Rring_tip_scaleY.o" "IMP_Rring_tip.sy"; -connectAttr "IMP_Rring_tip_scaleZ.o" "IMP_Rring_tip.sz"; -connectAttr "IMP_Rindex_lo_scaleX.o" "IMP_Rindex_lo.sx"; -connectAttr "IMP_Rindex_lo_scaleY.o" "IMP_Rindex_lo.sy"; -connectAttr "IMP_Rindex_lo_scaleZ.o" "IMP_Rindex_lo.sz"; -connectAttr "IMP_Rindex_lo_visibility.o" "IMP_Rindex_lo.v"; -connectAttr "IMP_Rindex_base_scaleX.o" "IMP_Rindex_base.sx"; -connectAttr "IMP_Rindex_base_scaleY.o" "IMP_Rindex_base.sy"; -connectAttr "IMP_Rindex_base_scaleZ.o" "IMP_Rindex_base.sz"; -connectAttr "IMP_Rindex_base_visibility.o" "IMP_Rindex_base.v"; -connectAttr "IMP_Rindex_mid_scaleX.o" "IMP_Rindex_mid.sx"; -connectAttr "IMP_Rindex_mid_scaleY.o" "IMP_Rindex_mid.sy"; -connectAttr "IMP_Rindex_mid_scaleZ.o" "IMP_Rindex_mid.sz"; -connectAttr "IMP_Rindex_mid_visibility.o" "IMP_Rindex_mid.v"; -connectAttr "IMP_Rindex_tip_visibility.o" "IMP_Rindex_tip.v"; -connectAttr "IMP_Rindex_tip_scaleX.o" "IMP_Rindex_tip.sx"; -connectAttr "IMP_Rindex_tip_scaleY.o" "IMP_Rindex_tip.sy"; -connectAttr "IMP_Rindex_tip_scaleZ.o" "IMP_Rindex_tip.sz"; -connectAttr "IMP_Rhand_orientConstraint1_nodeState.o" "IMP_Rhand_orientConstraint1.nds" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetX.o" "IMP_Rhand_orientConstraint1.ox" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetY.o" "IMP_Rhand_orientConstraint1.oy" - ; -connectAttr "IMP_Rhand_orientConstraint1_offsetZ.o" "IMP_Rhand_orientConstraint1.oz" - ; -connectAttr "IMP_effector3_visibility.o" "IMP_effector3.v"; -connectAttr "IMP_effector3_rotateX.o" "IMP_effector3.rx"; -connectAttr "IMP_effector3_rotateY.o" "IMP_effector3.ry"; -connectAttr "IMP_effector3_rotateZ.o" "IMP_effector3.rz"; -connectAttr "IMP_effector3_scaleX.o" "IMP_effector3.sx"; -connectAttr "IMP_effector3_scaleY.o" "IMP_effector3.sy"; -connectAttr "IMP_effector3_scaleZ.o" "IMP_effector3.sz"; -connectAttr "IMP_effector3_hideDisplay.o" "IMP_effector3.hd"; -connectAttr "IMP_Rrib_rotateX.o" "IMP_Rrib.rx"; -connectAttr "IMP_Rrib_rotateY.o" "IMP_Rrib.ry"; -connectAttr "IMP_Rrib_rotateZ.o" "IMP_Rrib.rz"; -connectAttr "IMP_Rrib_visibility.o" "IMP_Rrib.v"; -connectAttr "IMP_Rrib_translateX.o" "IMP_Rrib.tx"; -connectAttr "IMP_Rrib_translateY.o" "IMP_Rrib.ty"; -connectAttr "IMP_Rrib_translateZ.o" "IMP_Rrib.tz"; -connectAttr "IMP_Rrib_scaleX.o" "IMP_Rrib.sx"; -connectAttr "IMP_Rrib_scaleY.o" "IMP_Rrib.sy"; -connectAttr "IMP_Rrib_scaleZ.o" "IMP_Rrib.sz"; -connectAttr "IMP_Lrib_rotateX.o" "IMP_Lrib.rx"; -connectAttr "IMP_Lrib_rotateY.o" "IMP_Lrib.ry"; -connectAttr "IMP_Lrib_rotateZ.o" "IMP_Lrib.rz"; -connectAttr "IMP_Lrib_visibility.o" "IMP_Lrib.v"; -connectAttr "IMP_Lrib_translateX.o" "IMP_Lrib.tx"; -connectAttr "IMP_Lrib_translateY.o" "IMP_Lrib.ty"; -connectAttr "IMP_Lrib_translateZ.o" "IMP_Lrib.tz"; -connectAttr "IMP_Lrib_scaleX.o" "IMP_Lrib.sx"; -connectAttr "IMP_Lrib_scaleY.o" "IMP_Lrib.sy"; -connectAttr "IMP_Lrib_scaleZ.o" "IMP_Lrib.sz"; -connectAttr "IMP_Hips_scaleX.o" "IMP_Hips.sx"; -connectAttr "IMP_Hips_scaleY.o" "IMP_Hips.sy"; -connectAttr "IMP_Hips_scaleZ.o" "IMP_Hips.sz"; -connectAttr "IMP_Hips_rotateX.o" "IMP_Hips.rx"; -connectAttr "IMP_Hips_rotateY.o" "IMP_Hips.ry"; -connectAttr "IMP_Hips_rotateZ.o" "IMP_Hips.rz"; -connectAttr "IMP_Hips_visibility.o" "IMP_Hips.v"; -connectAttr "IMP_Hips_translateX.o" "IMP_Hips.tx"; -connectAttr "IMP_Hips_translateY.o" "IMP_Hips.ty"; -connectAttr "IMP_Hips_translateZ.o" "IMP_Hips.tz"; -connectAttr "IMP_Rupleg_scaleX.o" "IMP_Rupleg.sx"; -connectAttr "IMP_Rupleg_scaleY.o" "IMP_Rupleg.sy"; -connectAttr "IMP_Rupleg_scaleZ.o" "IMP_Rupleg.sz"; -connectAttr "IMP_Rupleg_rotateX.o" "IMP_Rupleg.rx"; -connectAttr "IMP_Rupleg_rotateY.o" "IMP_Rupleg.ry"; -connectAttr "IMP_Rupleg_rotateZ.o" "IMP_Rupleg.rz"; -connectAttr "IMP_Rupleg_visibility.o" "IMP_Rupleg.v"; -connectAttr "IMP_Rupleg_translateX.o" "IMP_Rupleg.tx"; -connectAttr "IMP_Rupleg_translateY.o" "IMP_Rupleg.ty"; -connectAttr "IMP_Rupleg_translateZ.o" "IMP_Rupleg.tz"; -connectAttr "IMP_Rloleg_scaleX.o" "IMP_Rloleg.sx"; -connectAttr "IMP_Rloleg_scaleY.o" "IMP_Rloleg.sy"; -connectAttr "IMP_Rloleg_scaleZ.o" "IMP_Rloleg.sz"; -connectAttr "IMP_Rloleg_rotateX.o" "IMP_Rloleg.rx"; -connectAttr "IMP_Rloleg_rotateY.o" "IMP_Rloleg.ry"; -connectAttr "IMP_Rloleg_rotateZ.o" "IMP_Rloleg.rz"; -connectAttr "IMP_Rloleg_visibility.o" "IMP_Rloleg.v"; -connectAttr "IMP_Rloleg_translateX.o" "IMP_Rloleg.tx"; -connectAttr "IMP_Rloleg_translateY.o" "IMP_Rloleg.ty"; -connectAttr "IMP_Rloleg_translateZ.o" "IMP_Rloleg.tz"; -connectAttr "IMP_Rankle_r_scaleX.o" "IMP_Rankle_r.sx"; -connectAttr "IMP_Rankle_r_scaleY.o" "IMP_Rankle_r.sy"; -connectAttr "IMP_Rankle_r_scaleZ.o" "IMP_Rankle_r.sz"; -connectAttr "IMP_Rankle_r_translateX.o" "IMP_Rankle_r.tx"; -connectAttr "IMP_Rankle_r_translateY.o" "IMP_Rankle_r.ty"; -connectAttr "IMP_Rankle_r_translateZ.o" "IMP_Rankle_r.tz"; -connectAttr "IMP_Rankle_r_visibility.o" "IMP_Rankle_r.v"; -connectAttr "IMP_Rball_r_scaleX.o" "IMP_Rball_r.sx"; -connectAttr "IMP_Rball_r_scaleY.o" "IMP_Rball_r.sy"; -connectAttr "IMP_Rball_r_scaleZ.o" "IMP_Rball_r.sz"; -connectAttr "IMP_Rball_r_visibility.o" "IMP_Rball_r.v"; -connectAttr "IMP_Rball_r_translateX.o" "IMP_Rball_r.tx"; -connectAttr "IMP_Rball_r_translateY.o" "IMP_Rball_r.ty"; -connectAttr "IMP_Rball_r_translateZ.o" "IMP_Rball_r.tz"; -connectAttr "IMP_Rtoe1_r_scaleX.o" "IMP_Rtoe1_r.sx"; -connectAttr "IMP_Rtoe1_r_scaleY.o" "IMP_Rtoe1_r.sy"; -connectAttr "IMP_Rtoe1_r_scaleZ.o" "IMP_Rtoe1_r.sz"; -connectAttr "IMP_Rtoe1_r_rotateX.o" "IMP_Rtoe1_r.rx"; -connectAttr "IMP_Rtoe1_r_rotateY.o" "IMP_Rtoe1_r.ry"; -connectAttr "IMP_Rtoe1_r_rotateZ.o" "IMP_Rtoe1_r.rz"; -connectAttr "IMP_Rtoe1_r_visibility.o" "IMP_Rtoe1_r.v"; -connectAttr "IMP_Rtoe1_r_translateX.o" "IMP_Rtoe1_r.tx"; -connectAttr "IMP_Rtoe1_r_translateY.o" "IMP_Rtoe1_r.ty"; -connectAttr "IMP_Rtoe1_r_translateZ.o" "IMP_Rtoe1_r.tz"; -connectAttr "IMP_Rtip1_r_rotateX.o" "IMP_Rtip1_r.rx"; -connectAttr "IMP_Rtip1_r_rotateY.o" "IMP_Rtip1_r.ry"; -connectAttr "IMP_Rtip1_r_rotateZ.o" "IMP_Rtip1_r.rz"; -connectAttr "IMP_Rtip1_r_visibility.o" "IMP_Rtip1_r.v"; -connectAttr "IMP_Rtip1_r_translateX.o" "IMP_Rtip1_r.tx"; -connectAttr "IMP_Rtip1_r_translateY.o" "IMP_Rtip1_r.ty"; -connectAttr "IMP_Rtip1_r_translateZ.o" "IMP_Rtip1_r.tz"; -connectAttr "IMP_Rtip1_r_scaleX.o" "IMP_Rtip1_r.sx"; -connectAttr "IMP_Rtip1_r_scaleY.o" "IMP_Rtip1_r.sy"; -connectAttr "IMP_Rtip1_r_scaleZ.o" "IMP_Rtip1_r.sz"; -connectAttr "IMP_Rtoe2_r_scaleX.o" "IMP_Rtoe2_r.sx"; -connectAttr "IMP_Rtoe2_r_scaleY.o" "IMP_Rtoe2_r.sy"; -connectAttr "IMP_Rtoe2_r_scaleZ.o" "IMP_Rtoe2_r.sz"; -connectAttr "IMP_Rtoe2_r_rotateX.o" "IMP_Rtoe2_r.rx"; -connectAttr "IMP_Rtoe2_r_rotateY.o" "IMP_Rtoe2_r.ry"; -connectAttr "IMP_Rtoe2_r_rotateZ.o" "IMP_Rtoe2_r.rz"; -connectAttr "IMP_Rtoe2_r_visibility.o" "IMP_Rtoe2_r.v"; -connectAttr "IMP_Rtoe2_r_translateX.o" "IMP_Rtoe2_r.tx"; -connectAttr "IMP_Rtoe2_r_translateY.o" "IMP_Rtoe2_r.ty"; -connectAttr "IMP_Rtoe2_r_translateZ.o" "IMP_Rtoe2_r.tz"; -connectAttr "IMP_Rtip2_r_rotateX.o" "IMP_Rtip2_r.rx"; -connectAttr "IMP_Rtip2_r_rotateY.o" "IMP_Rtip2_r.ry"; -connectAttr "IMP_Rtip2_r_rotateZ.o" "IMP_Rtip2_r.rz"; -connectAttr "IMP_Rtip2_r_visibility.o" "IMP_Rtip2_r.v"; -connectAttr "IMP_Rtip2_r_translateX.o" "IMP_Rtip2_r.tx"; -connectAttr "IMP_Rtip2_r_translateY.o" "IMP_Rtip2_r.ty"; -connectAttr "IMP_Rtip2_r_translateZ.o" "IMP_Rtip2_r.tz"; -connectAttr "IMP_Rtip2_r_scaleX.o" "IMP_Rtip2_r.sx"; -connectAttr "IMP_Rtip2_r_scaleY.o" "IMP_Rtip2_r.sy"; -connectAttr "IMP_Rtip2_r_scaleZ.o" "IMP_Rtip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_Rball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W0.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_Rankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Rupleg|IMP_Rloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Lupleg_scaleX.o" "IMP_Lupleg.sx"; -connectAttr "IMP_Lupleg_scaleY.o" "IMP_Lupleg.sy"; -connectAttr "IMP_Lupleg_scaleZ.o" "IMP_Lupleg.sz"; -connectAttr "IMP_Lupleg_rotateX.o" "IMP_Lupleg.rx"; -connectAttr "IMP_Lupleg_rotateY.o" "IMP_Lupleg.ry"; -connectAttr "IMP_Lupleg_rotateZ.o" "IMP_Lupleg.rz"; -connectAttr "IMP_Lupleg_visibility.o" "IMP_Lupleg.v"; -connectAttr "IMP_Lupleg_translateX.o" "IMP_Lupleg.tx"; -connectAttr "IMP_Lupleg_translateY.o" "IMP_Lupleg.ty"; -connectAttr "IMP_Lupleg_translateZ.o" "IMP_Lupleg.tz"; -connectAttr "IMP_Lloleg_scaleX.o" "IMP_Lloleg.sx"; -connectAttr "IMP_Lloleg_scaleY.o" "IMP_Lloleg.sy"; -connectAttr "IMP_Lloleg_scaleZ.o" "IMP_Lloleg.sz"; -connectAttr "IMP_Lloleg_rotateX.o" "IMP_Lloleg.rx"; -connectAttr "IMP_Lloleg_rotateY.o" "IMP_Lloleg.ry"; -connectAttr "IMP_Lloleg_rotateZ.o" "IMP_Lloleg.rz"; -connectAttr "IMP_Lloleg_visibility.o" "IMP_Lloleg.v"; -connectAttr "IMP_Lloleg_translateX.o" "IMP_Lloleg.tx"; -connectAttr "IMP_Lloleg_translateY.o" "IMP_Lloleg.ty"; -connectAttr "IMP_Lloleg_translateZ.o" "IMP_Lloleg.tz"; -connectAttr "IMP_Lankle_r_scaleX.o" "IMP_Lankle_r.sx"; -connectAttr "IMP_Lankle_r_scaleY.o" "IMP_Lankle_r.sy"; -connectAttr "IMP_Lankle_r_scaleZ.o" "IMP_Lankle_r.sz"; -connectAttr "IMP_Lankle_r_translateX.o" "IMP_Lankle_r.tx"; -connectAttr "IMP_Lankle_r_translateY.o" "IMP_Lankle_r.ty"; -connectAttr "IMP_Lankle_r_translateZ.o" "IMP_Lankle_r.tz"; -connectAttr "IMP_Lankle_r_visibility.o" "IMP_Lankle_r.v"; -connectAttr "IMP_Lball_r_scaleX.o" "IMP_Lball_r.sx"; -connectAttr "IMP_Lball_r_scaleY.o" "IMP_Lball_r.sy"; -connectAttr "IMP_Lball_r_scaleZ.o" "IMP_Lball_r.sz"; -connectAttr "IMP_Lball_r_visibility.o" "IMP_Lball_r.v"; -connectAttr "IMP_Lball_r_translateX.o" "IMP_Lball_r.tx"; -connectAttr "IMP_Lball_r_translateY.o" "IMP_Lball_r.ty"; -connectAttr "IMP_Lball_r_translateZ.o" "IMP_Lball_r.tz"; -connectAttr "IMP_Ltoe1_r_scaleX.o" "IMP_Ltoe1_r.sx"; -connectAttr "IMP_Ltoe1_r_scaleY.o" "IMP_Ltoe1_r.sy"; -connectAttr "IMP_Ltoe1_r_scaleZ.o" "IMP_Ltoe1_r.sz"; -connectAttr "IMP_Ltoe1_r_rotateX.o" "IMP_Ltoe1_r.rx"; -connectAttr "IMP_Ltoe1_r_rotateY.o" "IMP_Ltoe1_r.ry"; -connectAttr "IMP_Ltoe1_r_rotateZ.o" "IMP_Ltoe1_r.rz"; -connectAttr "IMP_Ltoe1_r_visibility.o" "IMP_Ltoe1_r.v"; -connectAttr "IMP_Ltoe1_r_translateX.o" "IMP_Ltoe1_r.tx"; -connectAttr "IMP_Ltoe1_r_translateY.o" "IMP_Ltoe1_r.ty"; -connectAttr "IMP_Ltoe1_r_translateZ.o" "IMP_Ltoe1_r.tz"; -connectAttr "IMP_Ltip1_r_rotateX.o" "IMP_Ltip1_r.rx"; -connectAttr "IMP_Ltip1_r_rotateY.o" "IMP_Ltip1_r.ry"; -connectAttr "IMP_Ltip1_r_rotateZ.o" "IMP_Ltip1_r.rz"; -connectAttr "IMP_Ltip1_r_visibility.o" "IMP_Ltip1_r.v"; -connectAttr "IMP_Ltip1_r_translateX.o" "IMP_Ltip1_r.tx"; -connectAttr "IMP_Ltip1_r_translateY.o" "IMP_Ltip1_r.ty"; -connectAttr "IMP_Ltip1_r_translateZ.o" "IMP_Ltip1_r.tz"; -connectAttr "IMP_Ltip1_r_scaleX.o" "IMP_Ltip1_r.sx"; -connectAttr "IMP_Ltip1_r_scaleY.o" "IMP_Ltip1_r.sy"; -connectAttr "IMP_Ltip1_r_scaleZ.o" "IMP_Ltip1_r.sz"; -connectAttr "IMP_Ltoe2_r_scaleX.o" "IMP_Ltoe2_r.sx"; -connectAttr "IMP_Ltoe2_r_scaleY.o" "IMP_Ltoe2_r.sy"; -connectAttr "IMP_Ltoe2_r_scaleZ.o" "IMP_Ltoe2_r.sz"; -connectAttr "IMP_Ltoe2_r_rotateX.o" "IMP_Ltoe2_r.rx"; -connectAttr "IMP_Ltoe2_r_rotateY.o" "IMP_Ltoe2_r.ry"; -connectAttr "IMP_Ltoe2_r_rotateZ.o" "IMP_Ltoe2_r.rz"; -connectAttr "IMP_Ltoe2_r_visibility.o" "IMP_Ltoe2_r.v"; -connectAttr "IMP_Ltoe2_r_translateX.o" "IMP_Ltoe2_r.tx"; -connectAttr "IMP_Ltoe2_r_translateY.o" "IMP_Ltoe2_r.ty"; -connectAttr "IMP_Ltoe2_r_translateZ.o" "IMP_Ltoe2_r.tz"; -connectAttr "IMP_Ltip2_r_rotateX.o" "IMP_Ltip2_r.rx"; -connectAttr "IMP_Ltip2_r_rotateY.o" "IMP_Ltip2_r.ry"; -connectAttr "IMP_Ltip2_r_rotateZ.o" "IMP_Ltip2_r.rz"; -connectAttr "IMP_Ltip2_r_visibility.o" "IMP_Ltip2_r.v"; -connectAttr "IMP_Ltip2_r_translateX.o" "IMP_Ltip2_r.tx"; -connectAttr "IMP_Ltip2_r_translateY.o" "IMP_Ltip2_r.ty"; -connectAttr "IMP_Ltip2_r_translateZ.o" "IMP_Ltip2_r.tz"; -connectAttr "IMP_Ltip2_r_scaleX.o" "IMP_Ltip2_r.sx"; -connectAttr "IMP_Ltip2_r_scaleY.o" "IMP_Ltip2_r.sy"; -connectAttr "IMP_Ltip2_r_scaleZ.o" "IMP_Ltip2_r.sz"; -connectAttr "IMP_joint4_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.nds" - ; -connectAttr "IMP_joint4_orientConstraint1_joint7W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.w0" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.ox" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oy" - ; -connectAttr "IMP_joint4_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_Lball_r|IMP_joint4_orientConstraint1.oz" - ; -connectAttr "IMP_joint3_orientConstraint1_nodeState1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.nds" - ; -connectAttr "IMP_joint3_orientConstraint1_joint8W1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.w0" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.ox" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oy" - ; -connectAttr "IMP_joint3_orientConstraint1_offsetZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_Lankle_r|IMP_joint3_orientConstraint1.oz" - ; -connectAttr "IMP_effector1_visibility1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.v" - ; -connectAttr "IMP_effector1_rotateX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rx" - ; -connectAttr "IMP_effector1_rotateY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.ry" - ; -connectAttr "IMP_effector1_rotateZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.rz" - ; -connectAttr "IMP_effector1_scaleX1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sx" - ; -connectAttr "IMP_effector1_scaleY1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sy" - ; -connectAttr "IMP_effector1_scaleZ1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.sz" - ; -connectAttr "IMP_effector1_hideDisplay1.o" "|group1|IMP_ALL|IMP_Body|IMP_Body2|IMP_Hips|IMP_Lupleg|IMP_Lloleg|IMP_effector1.hd" - ; -connectAttr "IMP_Rhand_IK_rotateX.o" "IMP_Rhand_IK.rx"; -connectAttr "IMP_Rhand_IK_rotateY.o" "IMP_Rhand_IK.ry"; -connectAttr "IMP_Rhand_IK_rotateZ.o" "IMP_Rhand_IK.rz"; -connectAttr "IMP_Rhand_IK_visibility.o" "IMP_Rhand_IK.v"; -connectAttr "IMP_Rhand_IK_scaleX.o" "IMP_Rhand_IK.sx"; -connectAttr "IMP_Rhand_IK_scaleY.o" "IMP_Rhand_IK.sy"; -connectAttr "IMP_Rhand_IK_scaleZ.o" "IMP_Rhand_IK.sz"; -connectAttr "IMP_Rhand_IK_poleVectorX.o" "IMP_Rhand_IK.pvx"; -connectAttr "IMP_Rhand_IK_poleVectorY.o" "IMP_Rhand_IK.pvy"; -connectAttr "IMP_Rhand_IK_poleVectorZ.o" "IMP_Rhand_IK.pvz"; -connectAttr "IMP_Rhand_IK_offset.o" "IMP_Rhand_IK.off"; -connectAttr "IMP_Rhand_IK_roll.o" "IMP_Rhand_IK.rol"; -connectAttr "IMP_Rhand_IK_twist.o" "IMP_Rhand_IK.twi"; -connectAttr "IMP_Rhand_IK_pointConstraint1_nodeState.o" "IMP_Rhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_Rhand_GOALW0.o" "IMP_Rhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetX.o" "IMP_Rhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetY.o" "IMP_Rhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Rhand_IK_pointConstraint1_offsetZ.o" "IMP_Rhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Lhand_IK_rotateX.o" "IMP_Lhand_IK.rx"; -connectAttr "IMP_Lhand_IK_rotateY.o" "IMP_Lhand_IK.ry"; -connectAttr "IMP_Lhand_IK_rotateZ.o" "IMP_Lhand_IK.rz"; -connectAttr "IMP_Lhand_IK_visibility.o" "IMP_Lhand_IK.v"; -connectAttr "IMP_Lhand_IK_scaleX.o" "IMP_Lhand_IK.sx"; -connectAttr "IMP_Lhand_IK_scaleY.o" "IMP_Lhand_IK.sy"; -connectAttr "IMP_Lhand_IK_scaleZ.o" "IMP_Lhand_IK.sz"; -connectAttr "IMP_Lhand_IK_poleVectorX.o" "IMP_Lhand_IK.pvx"; -connectAttr "IMP_Lhand_IK_poleVectorY.o" "IMP_Lhand_IK.pvy"; -connectAttr "IMP_Lhand_IK_poleVectorZ.o" "IMP_Lhand_IK.pvz"; -connectAttr "IMP_Lhand_IK_offset.o" "IMP_Lhand_IK.off"; -connectAttr "IMP_Lhand_IK_roll.o" "IMP_Lhand_IK.rol"; -connectAttr "IMP_Lhand_IK_twist.o" "IMP_Lhand_IK.twi"; -connectAttr "IMP_Lhand_IK_pointConstraint1_nodeState.o" "IMP_Lhand_IK_pointConstraint1.nds" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_Lhand_GOALW0.o" "IMP_Lhand_IK_pointConstraint1.w0" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetX.o" "IMP_Lhand_IK_pointConstraint1.ox" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetY.o" "IMP_Lhand_IK_pointConstraint1.oy" - ; -connectAttr "IMP_Lhand_IK_pointConstraint1_offsetZ.o" "IMP_Lhand_IK_pointConstraint1.oz" - ; -connectAttr "IMP_Rhand_GOAL_rotateX.o" "IMP_Rhand_GOAL.rx"; -connectAttr "IMP_Rhand_GOAL_rotateY.o" "IMP_Rhand_GOAL.ry"; -connectAttr "IMP_Rhand_GOAL_rotateZ.o" "IMP_Rhand_GOAL.rz"; -connectAttr "IMP_Rhand_GOAL_translateX.o" "IMP_Rhand_GOAL.tx"; -connectAttr "IMP_Rhand_GOAL_translateY.o" "IMP_Rhand_GOAL.ty"; -connectAttr "IMP_Rhand_GOAL_translateZ.o" "IMP_Rhand_GOAL.tz"; -connectAttr "IMP_Rhand_GOAL_visibility.o" "IMP_Rhand_GOAL.v"; -connectAttr "IMP_Rhand_GOAL_scaleX.o" "IMP_Rhand_GOAL.sx"; -connectAttr "IMP_Rhand_GOAL_scaleY.o" "IMP_Rhand_GOAL.sy"; -connectAttr "IMP_Rhand_GOAL_scaleZ.o" "IMP_Rhand_GOAL.sz"; -connectAttr "IMP_Lhand_GOAL_rotateX.o" "IMP_Lhand_GOAL.rx"; -connectAttr "IMP_Lhand_GOAL_rotateY.o" "IMP_Lhand_GOAL.ry"; -connectAttr "IMP_Lhand_GOAL_rotateZ.o" "IMP_Lhand_GOAL.rz"; -connectAttr "IMP_Lhand_GOAL_translateX.o" "IMP_Lhand_GOAL.tx"; -connectAttr "IMP_Lhand_GOAL_translateY.o" "IMP_Lhand_GOAL.ty"; -connectAttr "IMP_Lhand_GOAL_translateZ.o" "IMP_Lhand_GOAL.tz"; -connectAttr "IMP_Lhand_GOAL_visibility.o" "IMP_Lhand_GOAL.v"; -connectAttr "IMP_Lhand_GOAL_scaleX.o" "IMP_Lhand_GOAL.sx"; -connectAttr "IMP_Lhand_GOAL_scaleY.o" "IMP_Lhand_GOAL.sy"; -connectAttr "IMP_Lhand_GOAL_scaleZ.o" "IMP_Lhand_GOAL.sz"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_LIK_pointConstraint1_nodeState.o" "IMP_LIK_pointConstraint1.nds" - ; -connectAttr "IMP_LIK_pointConstraint1_LankleW0.o" "IMP_LIK_pointConstraint1.w0" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetX.o" "IMP_LIK_pointConstraint1.ox" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetY.o" "IMP_LIK_pointConstraint1.oy" - ; -connectAttr "IMP_LIK_pointConstraint1_offsetZ.o" "IMP_LIK_pointConstraint1.oz" - ; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_RIK_pointConstraint1_nodeState.o" "IMP_RIK_pointConstraint1.nds" - ; -connectAttr "IMP_RIK_pointConstraint1_RankleW0.o" "IMP_RIK_pointConstraint1.w0" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetX.o" "IMP_RIK_pointConstraint1.ox" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetY.o" "IMP_RIK_pointConstraint1.oy" - ; -connectAttr "IMP_RIK_pointConstraint1_offsetZ.o" "IMP_RIK_pointConstraint1.oz" - ; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of turret_attack1.ma diff --git a/base/models/monsters/imp/animation/cycles/turret_idle.ma b/base/models/monsters/imp/animation/cycles/turret_idle.ma deleted file mode 100644 index 1c3788dee..000000000 --- a/base/models/monsters/imp/animation/cycles/turret_idle.ma +++ /dev/null @@ -1,3620 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:19 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: turret_idle.ma -//Last modified: Mon, Mar 15, 2004 08:21:55 PM -file -r -rpr "IMP" -rfn "IMPRN" "P:/Doom/base/models//monsters/imp/fred/IMP_SETUP.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 230.61814638947922 54.115398616019434 -1.4041515691882864 ; - setAttr ".r" -type "double3" -5.1301089123321155 -1352.9999999999063 7.5964855471413784e-015 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 202.68879302662407; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 48.009446329610896 73.293644119483716 42.595205044249596 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 61.323155760577478 115.73742012124887 0.31155135102866005 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 147.42200685729316; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 59.610932956686291 34.976017359279254 100 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 202.0596881513782; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 99.999999999999986 37.549632656672301 -15.619095752801243 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 169.87148343332197; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; - setAttr ".sp" -type "double3" -0.44516282436967813 31.035932025165941 -5.0433085935669322 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "IMPRN"; -createNode animCurveTU -n "IMP_Body2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.2 1 12.2 1 13 1; -createNode animCurveTL -n "IMP_Body2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 -5.4967884695878091 12.2 - -4.3988027625426138 13 -4.1657930308134645; -createNode animCurveTL -n "IMP_Body2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 0.71645197165077801 12.2 - 0.57334040222998173 13 0.54296989172209287; -createNode animCurveTL -n "IMP_Body2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 0 12.2 0 13 0; -createNode animCurveTA -n "IMP_Body2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 0 12.2 0 13 0; -createNode animCurveTA -n "IMP_Body2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 0 12.2 0 13 0; -createNode animCurveTA -n "IMP_Body2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 8.2 -10.396661074269078 12.2 - -8.1851317596830349 13 -7.4542171015494922; -createNode animCurveTU -n "IMP_Body2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.2 1 12.2 1 13 1; -createNode animCurveTU -n "IMP_Body2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.2 1 12.2 1 13 1; -createNode animCurveTU -n "IMP_Body2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 8.2 1 12.2 1 13 1; -createNode animCurveTU -n "IMP_Waist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8.2 1 13 1; -createNode animCurveTU -n "IMP_Waist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8.2 1 13 1; -createNode animCurveTU -n "IMP_Waist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8.2 1 13 1; -createNode animCurveTL -n "IMP_Waist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.3128351505039433 8.2 2.3128351505039433 - 13 2.3128351505039433; -createNode animCurveTL -n "IMP_Waist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.23421866920666501 8.2 0.23421866920666501 - 13 0.23421866920666501; -createNode animCurveTL -n "IMP_Waist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 8.2 0 13 0; -createNode animCurveTA -n "IMP_Waist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.4125540166489063 8.2 7.8247378664801399 - 13 8.7951795972581372; -createNode animCurveTA -n "IMP_Waist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 12.660431799163181 8.2 13.751352433260992 - 13 13.892774724407374; -createNode animCurveTA -n "IMP_Waist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 8.2 22.776694843251629 13 26.888910802325626; -createNode animCurveTU -n "IMP_Waist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 8.2 1 13 1; -createNode animCurveTU -n "IMP_Chest_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 6.6 1 13 1; -createNode animCurveTU -n "IMP_Chest_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 6.6 1 13 1; -createNode animCurveTU -n "IMP_Chest_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 6.6 1 13 1; -createNode animCurveTA -n "IMP_Chest_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 397.48811046169101 6.6 384.076758854052 - 13 389.49637174592857; -createNode animCurveTA -n "IMP_Chest_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -14.641906192173103 6.6 -14.641906192173096 - 13 -14.641906192173099; -createNode animCurveTA -n "IMP_Chest_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.44667534838541134 6.6 -0.44667534838541262 - 13 -0.44667534838541167; -createNode animCurveTL -n "IMP_Chest_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.6268319407172029 6.6 5.6268319407172029 - 13 5.6268319407172029; -createNode animCurveTL -n "IMP_Chest_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -2.1098668596606802 6.6 -2.1098668596606802 - 13 -2.1098668596606802; -createNode animCurveTL -n "IMP_Chest_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 6.6 0 13 0; -createNode animCurveTU -n "IMP_Chest_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 6.6 1 13 1; -createNode animCurveTU -n "IMP_Neck_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9.8000000000000007 1 13 1; -createNode animCurveTU -n "IMP_Neck_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9.8000000000000007 1 13 1; -createNode animCurveTU -n "IMP_Neck_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9.8000000000000007 1 13 1; -createNode animCurveTL -n "IMP_Neck_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.7384771804188404 9.8000000000000007 - 5.7384771804188404 13 5.7384771804188404; -createNode animCurveTL -n "IMP_Neck_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.0494561358638701 9.8000000000000007 - 2.0494561358638701 13 2.0494561358638701; -createNode animCurveTL -n "IMP_Neck_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 9.8000000000000007 0 13 0; -createNode animCurveTA -n "IMP_Neck_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 25.421275224154744 9.8000000000000007 - 36.348615312237058 13 37.874152024707215; -createNode animCurveTA -n "IMP_Neck_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 3.384380797852069 9.8000000000000007 - -12.486888359019849 13 -14.364226384227051; -createNode animCurveTA -n "IMP_Neck_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -30.586767920152276 9.8000000000000007 - -36.216831783693365 13 -36.863333637497242; -createNode animCurveTU -n "IMP_Neck_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 9.8000000000000007 1 13 1; -createNode animCurveTU -n "IMP_Head_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 16 1 27 1 - 33 1 39 1 47 1 52 1; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 16 1 27 1 - 33 1 39 1 47 1 52 1; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Head_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 16 1 27 1 - 33 1 39 1 47 1 52 1; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -26.189308995653338 6.6 -20.615640870158749 - 11.4 -15.091352590275797 13 -8.7397788191085439 16 -8.7397788191085439 27 - -13.386984648111072 33 -13.386984648111072 39 -7.4300613492731964 47 -8.7397788191085439 - 52 -8.7397788191085439; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5665765693897113 6.6 5.3542358202902411 - 11.4 5.460283656526725 13 7.3330119448673576 16 7.3330119448673576 27 9.1309964717567684 - 33 9.1309964717567684 39 4.1890579402584791 47 7.3330119448673576 52 7.3330119448673576; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTA -n "IMP_Head_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -10.120831904257262 6.6 -1.3642999981520949 - 11.4 -16.862715915252902 13 -16.154270916852411 16 -16.154270916852411 27 - -8.6238431128618682 33 -8.6238431128618682 39 -18.553074155080996 47 -16.154270916852411 - 52 -16.154270916852411; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.6456615572060826 6.6 2.6456615572060826 - 11.4 2.6456615572060826 13 2.6456615572060826 16 2.6456615572060826 27 2.6456615572060826 - 33 2.6456615572060826 39 2.6456615572060826 47 2.6456615572060826 52 2.6456615572060826; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1.9935618776130362 6.6 1.9935618776130362 - 11.4 1.9935618776130362 13 1.9935618776130362 16 1.9935618776130362 27 1.9935618776130362 - 33 1.9935618776130362 39 1.9935618776130362 47 1.9935618776130362 52 1.9935618776130362; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTL -n "IMP_Head_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0 6.6 0 11.4 0 13 0 16 0 27 0 - 33 0 39 0 47 0 52 0; - setAttr -s 10 ".kit[3:9]" 3 9 9 9 9 9 9; - setAttr -s 10 ".kot[3:9]" 3 9 9 9 9 9 9; -createNode animCurveTU -n "IMP_Head_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6.6 1 11.4 1 13 1 16 1 27 1 - 33 1 39 1 47 1 52 1; - setAttr -s 10 ".kot[3:9]" 5 5 5 5 5 5 5; -createNode animCurveTU -n "IMP_Lloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 13 1 16 1; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTU -n "IMP_Lloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 13 1 16 1; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTU -n "IMP_Lloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 13 1 16 1; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 12.412879749935719 13 12.412879749935719 - 16 12.412879749935719; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -6.7286993982861674 13 -6.7286993982861674 - 16 -6.7286993982861674; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTL -n "IMP_Lloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.868763862603668 13 -3.868763862603668 - 16 -3.868763862603668; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 80.239686562403847 13 80.239686562403847 - 16 54.077927468358183; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.8978517871634404 13 5.8978517871634404 - 16 5.8978517871634288; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTA -n "IMP_Lloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.92545182592768849 13 0.92545182592768849 - 16 0.92545182592768971; - setAttr -s 3 ".kit[1:2]" 3 9; - setAttr -s 3 ".kot[1:2]" 3 9; -createNode animCurveTU -n "IMP_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 13 1 16 1; - setAttr -s 3 ".kot[1:2]" 5 5; -createNode animCurveTU -n "IMP_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10.6 1 13 1 16 1 33 1 52 1; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10.6 1 13 1 16 1 33 1 52 1; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTU -n "IMP_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10.6 1 13 1 16 1 33 1 52 1; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.41287000000041 10.6 -12.41287000000041 - 13 -12.41287000000041 16 -12.41287000000041 33 -12.41287000000041 52 -12.41287000000041; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -6.7285999999993047 10.6 -6.7285999999993047 - 13 -6.7285999999993047 16 -6.7285999999993047 33 -6.7285999999993047 52 -6.7285999999993047; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTL -n "IMP_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.8687599999999316 10.6 -3.8687599999999316 - 13 -3.8687599999999316 16 -3.8687599999999316 33 -3.8687599999999316 52 -3.8687599999999316; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 58.099612817676174 10.6 82.316033184538099 - 13 82.316033184538099 16 64.08197397813943 33 55.854205132375412 52 64.08197397813943; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10.6 0 13 0 16 0 33 -3.8931075435917726 - 52 0; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTA -n "IMP_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 10.6 0 13 0 16 0 33 2.6364787994799905 - 52 0; - setAttr -s 6 ".kit[2:5]" 3 9 3 3; - setAttr -s 6 ".kot[2:5]" 3 9 3 3; -createNode animCurveTU -n "IMP_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 10.6 1 13 1 16 1 33 1 52 1; - setAttr -s 6 ".kot[2:5]" 5 5 5 5; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 0\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 1\n" - + " -showDeformers 1\n" - + " -showExpressions 1\n" - + " -showConstraints 1\n" - + " -showUnderworld 1\n" - + " -showInvisible 1\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 1\n" - + " -showDeformers 1\n" - + " -showExpressions 1\n" - + " -showConstraints 1\n" - + " -showUnderworld 1\n" - + " -showInvisible 1\n" - + " -transitionFrames 1\n" - + " -freeform 1\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 0\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "animationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 16 -max 52 -ast 16 -aet 52 "; - setAttr ".a" -type "string" ""; - setAttr ".st" 6; -createNode animCurveTU -n "IMP_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Ruparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -5.8807954640291324 16 8.5156304394485858 - 38 -6.5226954304651867 52 8.5156304394485858; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -3.4977373448908193 16 -41.436655454713687 - 38 -31.871418013889308 52 -41.436655454713687; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTA -n "IMP_Ruparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 22.979007009556593 16 16.360110645449957 - 38 10.871775215957863 52 16.360110645449957; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -3.0821100000000254 16 -3.0821100000000254 - 38 -5.5605251191758986 52 -3.0821100000000254; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 2.1192000000001707 16 2.1192000000001707 - 38 2.4447726192235173 52 2.1192000000001707; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTL -n "IMP_Ruparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -3.3867499999998705 16 -3.3867499999998705 - 38 -3.7847247223023714 52 -3.3867499999998705; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Ruparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 9; - setAttr -s 4 ".kot[0:3]" 3 9 9 9; -createNode animCurveTU -n "IMP_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_Luparm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 3.3867545965885748 16 3.3867545965885748 - 38 3.6273380960601238 52 3.3867545965885748; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Luparm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 2.1192573708760349 16 2.1192573708760349 - 38 3.1840952748737745 52 2.1192573708760349; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTL -n "IMP_Luparm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -3.0821078932592165 16 -3.0821078932592165 - 38 -3.6260434114653686 52 -3.0821078932592165; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 16 75.312657822261826 38 64.674867284673837 - 52 75.312657822261826; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 0 16 11.771191120276887 38 4.2143403133580959 - 52 11.771191120276887; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "IMP_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 -6.7129388973255946 16 14.730782984337566 - 38 14.346670463919063 52 14.730782984337566; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 13 1 16 1 38 1 52 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "IMP_LHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_LHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -2.5294371750177831; -createNode animCurveTL -n "IMP_LHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 13.481673551673362; -createNode animCurveTL -n "IMP_LHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -0.26635088939205875; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 97.855881494193042; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 148.48318103992199; -createNode animCurveTA -n "IMP_LHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 185.52482540053091; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 15.445123296459185; -createNode animCurveTU -n "IMP_LHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_LHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_RHAND_ROT_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 26 1 38 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "IMP_RHAND_ROT_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -7.5406347832540632e-013 26 - -7.5406347832540632e-013 38 -7.5406347832540632e-013 52 -7.5406347832540632e-013; -createNode animCurveTL -n "IMP_RHAND_ROT_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 13.71946295727715 26 13.71946295727715 - 38 13.71946295727715 52 13.71946295727715; -createNode animCurveTL -n "IMP_RHAND_ROT_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -3.0908609005564358e-013 26 - -3.0908609005564358e-013 38 -3.0908609005564358e-013 52 -3.0908609005564358e-013; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 260.01204204600725 26 267.95782566597035 - 38 274.18651268285799 52 260.01204204600725; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -38.320908201910434 26 -44.615662638752354 - 38 -46.770294375075956 52 -38.320908201910434; -createNode animCurveTA -n "IMP_RHAND_ROT_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 -322.65738741293052 26 -344.40785024388987 - 38 -359.71482733769528 52 -322.65738741293052; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 15.445123296459183 26 15.445123296459183 - 38 15.445123296459183 52 15.445123296459183; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 15.445123296459185 26 15.445123296459185 - 38 15.445123296459185 52 15.445123296459185; -createNode animCurveTU -n "IMP_RHAND_ROT_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 15.445123296459181 26 15.445123296459181 - 38 15.445123296459181 52 15.445123296459181; -createNode animCurveTU -n "IMP_RHAND_ROT_IK"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 26 0 38 0 52 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FIST"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0.70000000000000007 26 0.70000000000000007 - 38 0.70000000000000007 52 0.70000000000000007; -createNode animCurveTU -n "IMP_RHAND_ROT_NEUTRAL"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 26 0 38 0 52 0; -createNode animCurveTU -n "IMP_RHAND_ROT_SPREAD"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 26 0 38 0 52 0; -createNode animCurveTU -n "IMP_RHAND_ROT_FLAT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 26 0 38 0 52 0; -createNode animCurveTU -n "IMP_RHAND_ROT_PIVOT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 26 0 38 0 52 0; -createNode animCurveTU -n "IMP_Rmissile_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_Rmissile_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -1.4752837996356043; -createNode animCurveTL -n "IMP_Rmissile_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -3.4429152318518517; -createNode animCurveTL -n "IMP_Rmissile_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 4.6597910865832972; -createNode animCurveTA -n "IMP_Rmissile_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -26.447332316722964; -createNode animCurveTA -n "IMP_Rmissile_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -67.357715796337814; -createNode animCurveTA -n "IMP_Rmissile_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 24.545813639883598; -createNode animCurveTU -n "IMP_Rmissile_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Rmissile_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Rmissile_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTL -n "IMP_Rheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -6.6987428689401023; -createNode animCurveTL -n "IMP_Rheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -1.0063285154727897; -createNode animCurveTL -n "IMP_Rheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 3.9024574139229289; -createNode animCurveTU -n "IMP_Rheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Rheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 17.856773962630957; -createNode animCurveTA -n "IMP_Rheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -36.171253008403404; -createNode animCurveTA -n "IMP_Rheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -10.870404993254283; -createNode animCurveTU -n "IMP_Rheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Rheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Rheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTL -n "IMP_Lheel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 9.6873596619451892; -createNode animCurveTL -n "IMP_Lheel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0.098625839244114; -createNode animCurveTL -n "IMP_Lheel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 14.651463035095317; -createNode animCurveTU -n "IMP_Lheel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_Lheel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 4.9130999348608286; -createNode animCurveTA -n "IMP_Lheel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 35.947765167312816; -createNode animCurveTA -n "IMP_Lheel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 8.3268568844740365; -createNode animCurveTU -n "IMP_Lheel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Lheel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_Lheel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTL -n "IMP_Body_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1.9225081589985762 33 2.1568928123229139 - 44 1.9994727977102094 52 1.9225081589985762; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Body_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 35.652019839492347 33 35.665436407542778 - 44 35.826315836278539 52 35.652019839492347; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTL -n "IMP_Body_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 13.461907599494868 33 12.482060965090039 - 44 12.753457266829548 52 13.461907599494868; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 33 1 44 1 52 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "IMP_Body_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0.64576725303311566 33 -8.8710685572569332 - 44 -0.081081151691383815 52 0.64576725303311566; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0 33 -0.062604275251697108 44 - -0.14343447938809131 52 0; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_Body_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 0.47460937865742331 33 0.51311428136126047 - 44 0.49774443957308534 52 0.47460937865742331; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 33 1 44 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 33 1 44 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "IMP_Body_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 16 1 33 1 44 1 52 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "IMP_LIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 -97.8430816148296 36 -106.27988485531623 - 52 -97.8430816148296; -createNode animCurveTA -n "IMP_LIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 2.1461068188508792 36 26.539231153496413 - 52 2.1461068188508792; -createNode animCurveTA -n "IMP_LIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 -85.383790866488482 36 -73.676118255829095 - 52 -85.383790866488482; -createNode animCurveTU -n "IMP_LIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; -createNode animCurveTU -n "IMP_LIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; -createNode animCurveTU -n "IMP_LIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; -createNode animCurveTU -n "IMP_LIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_LIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 36 0 52 0; -createNode animCurveTU -n "IMP_LIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 36 0 52 0; -createNode animCurveTU -n "IMP_LIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 36 1 52 1; -createNode animCurveTU -n "IMP_LIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 36 0 52 0; -createNode animCurveTA -n "IMP_LIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 36 0 52 0; -createNode animCurveTA -n "IMP_LIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 36 0 52 0; -createNode animCurveTA -n "IMP_RIK_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 -81.042166485265085 34 -78.53075522190322 - 52 -81.042166485265085; -createNode animCurveTA -n "IMP_RIK_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 53.942839579097168 34 51.95495813660505 - 52 53.942839579097168; -createNode animCurveTA -n "IMP_RIK_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 -93.582844077068899 34 -90.69018765638441 - 52 -93.582844077068899; -createNode animCurveTU -n "IMP_RIK_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_RIK_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; -createNode animCurveTU -n "IMP_RIK_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; -createNode animCurveTU -n "IMP_RIK_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; -createNode animCurveTU -n "IMP_RIK_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "IMP_RIK_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 34 0 52 0; -createNode animCurveTU -n "IMP_RIK_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 34 0 52 0; -createNode animCurveTU -n "IMP_RIK_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 1 34 1 52 1; -createNode animCurveTU -n "IMP_RIK_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 34 0 52 0; -createNode animCurveTA -n "IMP_RIK_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 34 0 52 0; -createNode animCurveTA -n "IMP_RIK_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 16 0 34 0 52 0; -createNode animCurveTL -n "IMP_origin_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 16.827384499368584; -createNode animCurveTL -n "IMP_origin_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTL -n "IMP_origin_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 -2.4031351987482168; -createNode animCurveTU -n "IMP_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "IMP_origin_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTA -n "IMP_origin_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTA -n "IMP_origin_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 0; -createNode animCurveTU -n "IMP_origin_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_origin_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_origin_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 16 1; -createNode animCurveTU -n "IMP_ALL_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "IMP_ALL_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTL -n "IMP_ALL_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTL -n "IMP_ALL_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_ALL_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTA -n "IMP_ALL_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 90; -createNode animCurveTA -n "IMP_ALL_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 0; -createNode animCurveTU -n "IMP_ALL_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1.25; -createNode animCurveTU -n "IMP_ALL_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1.25; -createNode animCurveTU -n "IMP_ALL_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 20 1.25; -select -ne :time1; - setAttr ".o" 20; -select -ne :renderPartition; - setAttr -s 12 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 12 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 4 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 4 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr -s 2 ".dsm"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "IMP_polySurface1" "group1"; -parent -s -nc -r "IMP_ALL" "group1"; -parent -s -nc -r "IMP_Rwing" "group1"; -parent -s -nc -r "IMP_Lwing" "group1"; -parent -s -nc -r "IMP_curve1" "group1"; -parent -s -nc -r "IMP_Lwing_thing" "group1"; -parent -s -nc -r "IMP_curve2" "group1"; -parent -s -nc -r "IMP_Rwing_thing" "group1"; -parent -s -nc -r "IMP_origin" "group1"; -select -ne IMP_Rmissile; - setAttr ".jo" -type "double3" 10.172609088116557 69.500974497559 0.3202113397221672 ; -select -ne IMP_pCube1; - setAttr ".v" no; -select -ne IMP_pCube2; - setAttr ".v" no; -select -ne IMP_polySurface1; - setAttr ".v" yes; -select -ne IMP_polySurfaceShape1Orig; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 4038 ".uvst[0].uvsp"; - setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0.892663 0.58372599 - 0.904742 0.61987799 0.86585498 0.608989 0.88192099 0.50762999 0.892663 0.58372599 - 0.86585498 0.608989 0.88192099 0.50762999 0.86585498 0.608989 0.84326202 - 0.52863598 0.93670201 0.60081297 0.94025302 0.64341003 0.90890902 0.65339601 - 0.93670201 0.60081297 0.90890902 0.65339601 0.904742 0.61987799 0.96222198 - 0.59601402 0.94025302 0.64341003 0.93670201 0.60081297 0.93670201 0.60081297 - 0.904742 0.61987799 0.892663 0.58372599 0.88192099 0.50762999 0.93670201 - 0.60081297 0.892663 0.58372599 0.91139501 0.52158397 0.93670201 0.60081297 - 0.88192099 0.50762999 0.91139501 0.52158397 0.96222198 0.59601402 0.93670201 - 0.60081297 0.47251999 0.59212297 0.493588 0.62263501 0.44557601 0.62202299 - 0.44557601 0.62202299 0.493588 0.62263501 0.46083799 0.64259601 0.44557601 - 0.62202299 0.46083799 0.64259601 0.422638 0.66873902 0.471468 0.56798297 - 0.50988603 0.60414898 0.47251999 0.59212297 0.47251999 0.59212297 0.50988603 - 0.60414898 0.493588 0.62263501 0.46083799 0.64259601 0.43200499 0.70468998 - 0.422638 0.66873902 0.46083799 0.64259601 0.469937 0.66459 0.43200499 0.70468998 - 0.50244898 0.644642 0.469937 0.66459 0.46083799 0.64259601 0.493588 0.62263501 - 0.50244898 0.644642 0.46083799 0.64259601 0.50988603 0.60414898 0.55948597 - 0.61438298 0.493588 0.62263501 0.493588 0.62263501 0.55948597 0.61438298 - 0.55341202 0.63760501 0.50244898 0.644642 0.476217 0.727027 0.469937 0.66459 - 0.50244898 0.644642 0.56032002 0.70486701 0.476217 0.727027 0.476217 0.727027 - 0.56032002 0.70486701 0.578484 0.726412 0.476217 0.727027 0.578484 0.726412 - 0.56181002 0.765275 0.47210601 0.79053301 0.50365102 0.81889403 0.484781 - 0.85584599 0.56181002 0.765275 0.50365102 0.81889403 0.47210601 0.79053301 - 0.476217 0.727027 0.56181002 0.765275 0.47210601 0.79053301 0.47210601 0.79053301 - 0.484781 0.85584599 0.401124 0.82737499 0.401124 0.82737499 0.484781 0.85584599 - 0.42608401 0.89203 0.40665799 0.802068 0.47210601 0.79053301 0.401124 0.82737499 - 0.476217 0.727027 0.47210601 0.79053301 0.40665799 0.802068 0.47251999 0.59212297 - 0.44557601 0.62202299 0.43095401 0.61518103 0.471468 0.56798297 0.47251999 - 0.59212297 0.43095401 0.61518103 0.44446999 0.51254302 0.471468 0.56798297 - 0.37521201 0.59356803 0.471468 0.56798297 0.43095401 0.61518103 0.37521201 - 0.59356803 0.44557601 0.62202299 0.422638 0.66873902 0.43095401 0.61518103 - 0.37521201 0.59356803 0.43095401 0.61518103 0.422638 0.66873902 0.37521201 - 0.59356803 0.422638 0.66873902 0.402172 0.66881698 0.43200499 0.70468998 - 0.476217 0.727027 0.44672099 0.742163 0.469937 0.66459 0.476217 0.727027 - 0.43200499 0.70468998 0.43200499 0.70468998 0.44672099 0.742163 0.39220601 - 0.76434302 0.43200499 0.70468998 0.39220601 0.76434302 0.37832099 0.73359799 - 0.43200499 0.70468998 0.37832099 0.73359799 0.41114399 0.69965303 0.422638 - 0.66873902 0.43200499 0.70468998 0.41114399 0.69965303 0.402172 0.66881698 - 0.422638 0.66873902 0.41114399 0.69965303 0.402172 0.66881698 0.41114399 - 0.69965303 0.37832099 0.73359799 0.590801 0.64542502 0.58906102 0.696136 - 0.55341202 0.63760501 0.55341202 0.63760501 0.58906102 0.696136 0.56032002 - 0.70486701 0.50244898 0.644642 0.55341202 0.63760501 0.56032002 0.70486701 - 0.590801 0.64542502 0.55341202 0.63760501 0.594082 0.62339002 0.55948597 - 0.61438298 0.594082 0.62339002 0.55341202 0.63760501 0.44446999 0.51254302 - 0.48631501 0.53582197 0.471468 0.56798297 0.48631501 0.53582197 0.52967697 - 0.561248 0.471468 0.56798297 0.50988603 0.60414898 0.56466401 0.58405501 - 0.55948597 0.61438298 0.50988603 0.60414898 0.52967697 0.561248 0.56466401 - 0.58405501 0.52967697 0.561248 0.55312598 0.548361 0.56466401 0.58405501 - 0.59298301 0.57251501 0.594082 0.62339002 0.55948597 0.61438298 0.59298301 - 0.57251501 0.56466401 0.58405501 0.55312598 0.548361 0.48631501 0.53582197 - 0.55312598 0.548361 0.52967697 0.561248 0.55817002 0.495579 0.59298301 0.57251501 - 0.55312598 0.548361 0.55817002 0.495579 0.55312598 0.548361 0.48631501 0.53582197 - 0.59298301 0.57251501 0.55948597 0.61438298 0.56466401 0.58405501 0.29069301 - 0.56685197 0.34469 0.60969198 0.33425501 0.67281002 0.29069301 0.56685197 - 0.33425501 0.67281002 0.27809399 0.63370502 0.34469 0.60969198 0.37521201 - 0.59356803 0.33425501 0.67281002 0.37521201 0.59356803 0.402172 0.66881698 - 0.33425501 0.67281002 0.35016599 0.53974301 0.34469 0.60969198 0.29069301 - 0.56685197 0.35016599 0.53974301 0.29069301 0.56685197 0.241578 0.53054398 - 0.44446999 0.51254302 0.37521201 0.59356803 0.35016599 0.53974301 0.35016599 - 0.53974301 0.37521201 0.59356803 0.34469 0.60969198 0.70178902 0.52030098 - 0.66176099 0.61444402 0.62787598 0.58490998 0.70178902 0.52030098 0.62787598 - 0.58490998 0.66376501 0.50938398 0.66376501 0.50938398 0.62787598 0.58490998 - 0.611036 0.541574 0.94404799 0.534742 0.94016802 0.552697 0.91139501 0.52158397 - 0.91649199 0.412949 0.94404799 0.534742 0.91139501 0.52158397 0.91649199 - 0.412949 0.91139501 0.52158397 0.88974899 0.43314499 0.95096499 0.41022 0.94404799 - 0.534742 0.91649199 0.412949 0.95096499 0.41022 0.97447199 0.54772502 0.94404799 - 0.534742 0.95096499 0.41022 0.99280602 0.52736998 0.97447199 0.54772502 0.88974899 - 0.43314499 0.91139501 0.52158397 0.88192099 0.50762999 0.91649199 0.412949 - 0.88974899 0.43314499 0.86741501 0.373849 0.70178902 0.52030098 0.73045999 - 0.53145701 0.72172701 0.597004 0.402172 0.66881698; - setAttr ".uvst[0].uvsp[250:499]" 0.37832099 0.73359799 0.361752 0.72452599 - 0.402172 0.66881698 0.361752 0.72452599 0.33425501 0.67281002 0.70178902 - 0.52030098 0.72172701 0.597004 0.66176099 0.61444402 0.73045999 0.53145701 - 0.76481098 0.59411001 0.72172701 0.597004 0.33425501 0.67281002 0.361752 - 0.72452599 0.33192599 0.74883097 0.99264401 0.396844 0.99280602 0.52736998 - 0.95096499 0.41022 0.95096499 0.41022 0.91649199 0.412949 0.89975703 0.32890701 - 0.99264401 0.396844 0.95096499 0.41022 0.89975703 0.32890701 0.89975703 0.32890701 - 0.91649199 0.412949 0.86741501 0.373849 0.70178902 0.52030098 0.66376501 - 0.50938398 0.68089098 0.41862199 0.88974899 0.43314499 0.88192099 0.50762999 - 0.84326202 0.52863598 0.88974899 0.43314499 0.84326202 0.52863598 0.82335901 - 0.49983799 0.81960201 0.54509503 0.82335901 0.49983799 0.84326202 0.52863598 - 0.80370599 0.60544503 0.81960201 0.54509503 0.84326202 0.52863598 0.84326202 - 0.52863598 0.86585498 0.608989 0.85311198 0.64641303 0.85311198 0.64641303 - 0.86585498 0.608989 0.90890902 0.65339601 0.904742 0.61987799 0.90890902 - 0.65339601 0.86585498 0.608989 0.55527902 0.8071 0.61128402 0.83876997 0.56233603 - 0.85706103 0.55527902 0.8071 0.56233603 0.85706103 0.484781 0.85584599 0.61429799 - 0.75036502 0.55527902 0.8071 0.56181002 0.765275 0.60618597 0.86918902 0.63363802 - 0.89377397 0.57115501 0.92132199 0.56233603 0.85706103 0.60618597 0.86918902 - 0.57115501 0.92132199 0.23810799 0.94020498 0.16559599 0.995709 0.14566401 - 0.93838102 0.14566401 0.93838102 0.16559599 0.995709 0.059299 0.99024302 - 0.61128402 0.83876997 0.66327202 0.82856899 0.68109202 0.85573 0.23810799 - 0.94020498 0.14566401 0.93838102 0.17147 0.907399 0.14566401 0.93838102 0.059299 - 0.99024302 0.063868999 0.91910303 0.193271 0.88191301 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.052301999 - 0.89361697 0.61128402 0.83876997 0.68109202 0.85573 0.60618597 0.86918902 - 0.60618597 0.86918902 0.68109202 0.85573 0.63363802 0.89377397 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.052301999 0.89361697 0.059299 0.99024302 - 0.0086899996 0.90104598 0.063868999 0.91910303 0.612091 0.80211103 0.66305399 - 0.78664398 0.61128402 0.83876997 0.61128402 0.83876997 0.66305399 0.78664398 - 0.66327202 0.82856899 0.64314198 0.77576202 0.66305399 0.78664398 0.612091 - 0.80211103 0.662714 0.74348199 0.68224001 0.752303 0.64314198 0.77576202 - 0.64314198 0.77576202 0.68224001 0.752303 0.66305399 0.78664398 0.61429799 - 0.75036502 0.63186097 0.74417901 0.612091 0.80211103 0.63186097 0.74417901 - 0.64314198 0.77576202 0.612091 0.80211103 0.63186097 0.74417901 0.662714 - 0.74348199 0.64314198 0.77576202 0.61429799 0.75036502 0.56181002 0.765275 - 0.59559602 0.73881298 0.596021 0.71545899 0.61429799 0.75036502 0.59559602 - 0.73881298 0.58906102 0.696136 0.596021 0.71545899 0.578484 0.726412 0.58906102 - 0.696136 0.578484 0.726412 0.56032002 0.70486701 0.596021 0.71545899 0.59559602 - 0.73881298 0.578484 0.726412 0.578484 0.726412 0.59559602 0.73881298 0.56181002 - 0.765275 0.029790999 0.85418802 0.0081359996 0.81497997 0.038779002 0.81607199 - 0.044146001 0.79082501 0.038779002 0.81607199 0.0081359996 0.81497997 0.074841 - 0.80788898 0.038779002 0.81607199 0.044146001 0.79082501 0.074841 0.80788898 - 0.073301002 0.83981198 0.038779002 0.81607199 0.073301002 0.83981198 0.135956 - 0.83810002 0.12989099 0.871301 0.072558001 0.88500297 0.12989099 0.871301 - 0.063868999 0.91910303 0.17147 0.907399 0.063868999 0.91910303 0.12989099 - 0.871301 0.069305003 0.862432 0.073301002 0.83981198 0.12989099 0.871301 - 0.069305003 0.862432 0.12989099 0.871301 0.072558001 0.88500297 0.069305003 - 0.862432 0.072558001 0.88500297 0.039615002 0.87295502 0.039615002 0.87295502 - 0.072558001 0.88500297 0.052301999 0.89361697 0.073301002 0.83981198 0.039615002 - 0.87295502 0.029790999 0.85418802 0.069305003 0.862432 0.039615002 0.87295502 - 0.073301002 0.83981198 0.039615002 0.87295502 0.0086899996 0.90104598 0.029790999 - 0.85418802 0.039615002 0.87295502 0.052301999 0.89361697 0.0086899996 0.90104598 - 0.133753 0.80051601 0.193271 0.88191301 0.135956 0.83810002 0.133753 0.80051601 - 0.135956 0.83810002 0.073301002 0.83981198 0.14566401 0.93838102 0.063868999 - 0.91910303 0.17147 0.907399 0.56233603 0.85706103 0.61128402 0.83876997 0.60618597 - 0.86918902 0.209691 0.79815799 0.21379501 0.846349 0.193271 0.88191301 0.21379501 - 0.846349 0.225722 0.86254603 0.193271 0.88191301 0.237334 0.83964097 0.225722 - 0.86254603 0.21379501 0.846349 0.193271 0.88191301 0.17147 0.907399 0.12989099 - 0.871301 0.23810799 0.94020498 0.17147 0.907399 0.193271 0.88191301 0.134497 - 0.74599701 0.133753 0.80051601 0.115455 0.77456403 0.189914 0.76742601 0.209691 - 0.79815799 0.133753 0.80051601 0.209691 0.79815799 0.193271 0.88191301 0.133753 - 0.80051601 0.26639199 0.865004 0.193271 0.88191301 0.225722 0.86254603 0.26639199 - 0.865004 0.225722 0.86254603 0.237334 0.83964097 0.84326202 0.52863598 0.85311198 - 0.64641303 0.81364501 0.66707098 0.26639199 0.865004 0.23810799 0.94020498 - 0.193271 0.88191301 0.80370599 0.60544503 0.84326202 0.52863598 0.81364501 - 0.66707098 0.32067001 0.79166698 0.26639199 0.865004 0.237334 0.83964097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.237334 0.83964097 0.209691 - 0.79815799 0.237334 0.83964097 0.21379501 0.846349 0.193901 0.70055801 0.189914 - 0.76742601 0.133753 0.80051601 0.193901 0.70055801 0.209691 0.79815799; - setAttr ".uvst[0].uvsp[500:749]" 0.189914 0.76742601 0.193901 0.70055801 - 0.235135 0.75121701 0.209691 0.79815799 0.23119999 0.70723599 0.235135 0.75121701 - 0.193901 0.70055801 0.235135 0.75121701 0.237334 0.83964097 0.209691 0.79815799 - 0.30680701 0.75846398 0.237334 0.83964097 0.235135 0.75121701 0.23119999 - 0.70723599 0.30680701 0.75846398 0.235135 0.75121701 0.76481098 0.59411001 - 0.81960201 0.54509503 0.80370599 0.60544503 0.33192599 0.74883097 0.32067001 - 0.79166698 0.30680701 0.75846398 0.33425501 0.67281002 0.33192599 0.74883097 - 0.30680701 0.75846398 0.218197 0.66097301 0.23119999 0.70723599 0.193901 - 0.70055801 0.27809399 0.63370502 0.23119999 0.70723599 0.218197 0.66097301 - 0.73045999 0.53145701 0.773857 0.53407699 0.76481098 0.59411001 0.773857 - 0.53407699 0.81960201 0.54509503 0.76481098 0.59411001 0.773857 0.53407699 - 0.82335901 0.49983799 0.81960201 0.54509503 0.241578 0.53054398 0.29069301 - 0.56685197 0.214571 0.58170599 0.29069301 0.56685197 0.27809399 0.63370502 - 0.214571 0.58170599 0.214571 0.58170599 0.27809399 0.63370502 0.218197 0.66097301 - 0.214571 0.58170599 0.218197 0.66097301 0.191866 0.64202601 0.241578 0.53054398 - 0.214571 0.58170599 0.181797 0.58704501 0.241578 0.53054398 0.181797 0.58704501 - 0.227768 0.50040001 0.214571 0.58170599 0.191866 0.64202601 0.181797 0.58704501 - 0.191866 0.64202601 0.218197 0.66097301 0.193901 0.70055801 0.34836701 0.49853599 - 0.35016599 0.53974301 0.227768 0.50040001 0.35016599 0.53974301 0.241578 - 0.53054398 0.227768 0.50040001 0.33645499 0.40632701 0.415775 0.44801801 - 0.302367 0.46158099 0.415775 0.44801801 0.34836701 0.49853599 0.302367 0.46158099 - 0.55817002 0.495579 0.48631501 0.53582197 0.49755499 0.488251 0.49755499 - 0.488251 0.48631501 0.53582197 0.44446999 0.51254302 0.53173602 0.43147901 - 0.55817002 0.495579 0.49755499 0.488251 0.137054 0.71443301 0.16243599 0.73647797 - 0.134497 0.74599701 0.193901 0.70055801 0.133753 0.80051601 0.16243599 0.73647797 - 0.16243599 0.73647797 0.133753 0.80051601 0.134497 0.74599701 0.155361 0.68448699 - 0.16243599 0.73647797 0.137054 0.71443301 0.135434 0.64463699 0.155361 0.68448699 - 0.137054 0.71443301 0.073301002 0.83981198 0.029790999 0.85418802 0.038779002 - 0.81607199 0.191866 0.64202601 0.193901 0.70055801 0.17482001 0.65435803 - 0.17482001 0.65435803 0.193901 0.70055801 0.16243599 0.73647797 0.17482001 - 0.65435803 0.16243599 0.73647797 0.155361 0.68448699 0.181797 0.58704501 - 0.191866 0.64202601 0.17482001 0.65435803 0.134919 0.61088699 0.152937 0.59559798 - 0.17482001 0.65435803 0.181797 0.58704501 0.17482001 0.65435803 0.152937 - 0.59559798 0.302367 0.46158099 0.34836701 0.49853599 0.227768 0.50040001 - 0.17433301 0.53156102 0.181797 0.58704501 0.152937 0.59559798 0.227768 0.50040001 - 0.181797 0.58704501 0.17433301 0.53156102 0.24266601 0.36897901 0.33645499 - 0.40632701 0.302367 0.46158099 0.493588 0.62263501 0.55341202 0.63760501 - 0.50244898 0.644642 0.135434 0.64463699 0.17482001 0.65435803 0.155361 0.68448699 - 0.134919 0.61088699 0.17482001 0.65435803 0.135434 0.64463699 0.235855 0.44651899 - 0.195015 0.48982099 0.19817799 0.43839601 0.216538 0.39981201 0.235855 0.44651899 - 0.19817799 0.43839601 0.24266601 0.36897901 0.302367 0.46158099 0.235855 - 0.44651899 0.195015 0.48982099 0.227768 0.50040001 0.17433301 0.53156102 - 0.235855 0.44651899 0.227768 0.50040001 0.195015 0.48982099 0.24266601 0.36897901 - 0.235855 0.44651899 0.216538 0.39981201 0.24266601 0.36897901 0.216538 0.39981201 - 0.202446 0.3633 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 - 0.61429799 0.75036502 0.612091 0.80211103 0.55527902 0.8071 0.55527902 0.8071 - 0.612091 0.80211103 0.61128402 0.83876997 0.81753498 0.92918402 0.79334199 - 0.99322498 0.86997002 0.93731803 0.86997002 0.93731803 0.79334199 0.99322498 - 0.85467398 0.99159998 0.75108498 0.90098101 0.71710402 0.94957799 0.81753498 - 0.92918402 0.681234 0.89455098 0.71710402 0.94957799 0.75108498 0.90098101 - 0.71710402 0.94957799 0.79334199 0.99322498 0.81753498 0.92918402 0.68843299 - 0.845505 0.681234 0.89455098 0.71957898 0.86809897 0.77899301 0.67823797 - 0.84964103 0.74003702 0.848369 0.70362002 0.77899301 0.67823797 0.848369 - 0.70362002 0.77644902 0.63733798 0.78393102 0.81632203 0.79684901 0.86380398 - 0.82964599 0.80204397 0.72519898 0.67094803 0.77899301 0.67823797 0.77644902 - 0.63733798 0.72519898 0.67094803 0.74377102 0.72034299 0.77899301 0.67823797 - 0.72519898 0.67094803 0.71176398 0.71938401 0.74377102 0.72034299 0.71957898 - 0.86809897 0.681234 0.89455098 0.75108498 0.90098101 0.79684901 0.86380398 - 0.75108498 0.90098101 0.81753498 0.92918402 0.718126 0.82873601 0.68843299 - 0.845505 0.71957898 0.86809897 0.71957898 0.86809897 0.75108498 0.90098101 - 0.79684901 0.86380398 0.78393102 0.81632203 0.71957898 0.86809897 0.79684901 - 0.86380398 0.718126 0.82873601 0.71957898 0.86809897 0.78393102 0.81632203 - 0.71901399 0.78532398 0.718126 0.82873601 0.75086302 0.78398401 0.75086302 - 0.78398401 0.718126 0.82873601 0.78393102 0.81632203 0.27809399 0.63370502 - 0.30680701 0.75846398 0.23119999 0.70723599 0.27809399 0.63370502 0.33425501 - 0.67281002 0.30680701 0.75846398 0.56181002 0.765275 0.55527902 0.8071 0.50365102 - 0.81889403 0.55527902 0.8071 0.484781 0.85584599 0.50365102 0.81889403 0.78915399 - 0.74251801 0.78393102 0.81632203 0.82964599 0.80204397 0.78915399 0.74251801 - 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[750:999]" 0.82964599 0.80204397 0.81753498 - 0.92918402 0.86997002 0.93731803 0.82964599 0.80204397 0.79684901 0.86380398 - 0.81753498 0.92918402 0.84964103 0.74003702 0.82964599 0.80204397 0.86997002 - 0.93731803 0.133753 0.80051601 0.073301002 0.83981198 0.074841 0.80788898 - 0.115455 0.77456403 0.133753 0.80051601 0.074841 0.80788898 0.316248 0.291545 - 0.39272901 0.33256099 0.35912099 0.27489001 0.316248 0.291545 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35912099 0.27489001 0.39272901 0.33256099 - 0.47097301 0.28257099 0.39272901 0.33256099 0.55185699 0.34580401 0.47097301 - 0.28257099 0.47097301 0.28257099 0.55324697 0.28502101 0.52854401 0.261291 - 0.47097301 0.28257099 0.55185699 0.34580401 0.55324697 0.28502101 0.316248 - 0.291545 0.33604199 0.25541499 0.31703201 0.24954499 0.258811 0.22176901 - 0.31703201 0.24954499 0.31351399 0.202804 0.255613 0.25320399 0.316248 0.291545 - 0.31703201 0.24954499 0.255613 0.25320399 0.26878601 0.315254 0.316248 0.291545 - 0.400451 0.218311 0.52854401 0.261291 0.532996 0.217034 0.35348001 0.188078 - 0.400451 0.218311 0.53191298 0.15157899 0.35348001 0.188078 0.53191298 0.15157899 - 0.37215099 0.13412 0.33604199 0.25541499 0.35912099 0.27489001 0.400451 0.218311 - 0.33604199 0.25541499 0.400451 0.218311 0.35348001 0.188078 0.31703201 0.24954499 - 0.33604199 0.25541499 0.35348001 0.188078 0.35912099 0.27489001 0.47097301 - 0.28257099 0.400451 0.218311 0.400451 0.218311 0.47097301 0.28257099 0.52854401 - 0.261291 0.31351399 0.202804 0.35348001 0.188078 0.32905 0.12617201 0.31351399 - 0.202804 0.31703201 0.24954499 0.35348001 0.188078 0.128057 0.28853801 0.194934 - 0.29608399 0.151114 0.233711 0.151114 0.233711 0.194934 0.29608399 0.19205201 - 0.23548099 0.194934 0.29608399 0.21787301 0.34819999 0.26878601 0.315254 - 0.271054 0.13361099 0.31351399 0.202804 0.32905 0.12617201 0.245719 0.014829 - 0.25301799 0.068204001 0.31335899 0.057027001 0.55444598 0.474244 0.591959 - 0.53098297 0.57874799 0.472913 0.62550402 0.53194499 0.639902 0.47827199 - 0.60980803 0.47876301 0.60595697 0.51647699 0.62550402 0.53194499 0.60980803 - 0.47876301 0.86200303 0.72877699 0.92526799 0.68932003 0.88900101 0.68397403 - 0.92526799 0.68932003 0.89971602 0.66068798 0.88900101 0.68397403 0.591959 - 0.53098297 0.60980803 0.47876301 0.57874799 0.472913 0.66333002 0.35212901 - 0.58532703 0.345817 0.63387299 0.382061 0.58532703 0.345817 0.610578 0.38000399 - 0.63387299 0.382061 0.58532703 0.345817 0.60697401 0.39847901 0.610578 0.38000399 - 0.55444598 0.474244 0.57874799 0.472913 0.60697401 0.39847901 0.60595697 - 0.51647699 0.60980803 0.47876301 0.591959 0.53098297 0.86200303 0.72877699 - 0.88900101 0.68397403 0.86512601 0.68251401 0.039241001 0.118589 0.080518 - 0.123654 0.056297999 0.091900997 0.020680999 0.143217 0.080518 0.123654 0.039241001 - 0.118589 0.041522998 0.25432399 0.069355004 0.21782801 0.070349 0.165839 - 0.57874799 0.472913 0.61546803 0.418973 0.60697401 0.39847901 0.639902 0.47827199 - 0.63182598 0.41617399 0.61546803 0.418973 0.639902 0.47827199 0.64173597 - 0.390975 0.63182598 0.41617399 0.016138 0.325297 0.128057 0.28853801 0.036951002 - 0.29172301 0.016138 0.325297 0.048168998 0.35214001 0.128057 0.28853801 0.027048999 - 0.208827 0.041522998 0.25432399 0.070349 0.165839 0.027048999 0.208827 0.070349 - 0.165839 0.020680999 0.143217 0.020680999 0.143217 0.070349 0.165839 0.080518 - 0.123654 0.128057 0.28853801 0.21787301 0.34819999 0.194934 0.29608399 0.062045 - 0.057544 0.056297999 0.091900997 0.271054 0.13361099 0.056297999 0.091900997 - 0.080518 0.123654 0.271054 0.13361099 0.617971 0.407262 0.60697401 0.39847901 - 0.61546803 0.418973 0.63182598 0.41617399 0.617971 0.407262 0.61546803 0.418973 - 0.66333002 0.35212901 0.63387299 0.382061 0.64173597 0.390975 0.86200303 - 0.72877699 0.94665498 0.81503397 0.97766298 0.79651397 0.86200303 0.72877699 - 0.97766298 0.79651397 0.93663901 0.729617 0.86200303 0.72877699 0.93663901 - 0.729617 0.92526799 0.68932003 0.65543997 0.49157101 0.665824 0.44352099 - 0.639902 0.47827199 0.665824 0.44352099 0.64173597 0.390975 0.639902 0.47827199 - 0.66333002 0.35212901 0.64173597 0.390975 0.665824 0.44352099 0.55444598 - 0.474244 0.60697401 0.39847901 0.58532703 0.345817 0.32905 0.12617201 0.35348001 - 0.188078 0.37215099 0.13412 0.55324697 0.28502101 0.602754 0.257723 0.57477999 - 0.25117901 0.57477999 0.25117901 0.602754 0.257723 0.61704302 0.20689499 - 0.53191298 0.15157899 0.61118603 0.156872 0.56468099 0.099036001 0.60898602 - 0.28752601 0.64614099 0.22702 0.602754 0.257723 0.602754 0.257723 0.64614099 - 0.22702 0.61704302 0.20689499 0.61118603 0.156872 0.61704302 0.20689499 0.64614099 - 0.22702 0.56468099 0.099036001 0.61118603 0.156872 0.63874 0.094846003 0.194934 - 0.29608399 0.26878601 0.315254 0.255613 0.25320399 0.194934 0.29608399 0.255613 - 0.25320399 0.216565 0.237138 0.19205201 0.23548099 0.194934 0.29608399 0.216565 - 0.237138 0.42296299 0.00556 0.53150898 0.049988002 0.57313102 0.0095039997 - 0.60898602 0.28752601 0.627464 0.31886399 0.64614099 0.22702 0.47644299 0.39616501 - 0.53173602 0.43147901 0.47337201 0.42365801 0.52854401 0.261291 0.55324697 - 0.28502101 0.57477999 0.25117901 0.58940798 0.33751199 0.627464 0.31886399 - 0.60898602 0.28752601 0.359846 0.051763002 0.475099 0.076341003 0.42296299 - 0.00556 0.42296299 0.00556; - setAttr ".uvst[0].uvsp[1000:1249]" 0.475099 0.076341003 0.53150898 0.049988002 - 0.37215099 0.13412 0.53191298 0.15157899 0.475099 0.076341003 0.53674299 - 0.39848399 0.53173602 0.43147901 0.47644299 0.39616501 0.47946599 0.37119001 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53191298 0.15157899 0.61704302 - 0.20689499 0.61118603 0.156872 0.22066 0.18181901 0.31351399 0.202804 0.271054 - 0.13361099 0.400451 0.218311 0.532996 0.217034 0.53191298 0.15157899 0.52854401 - 0.261291 0.57477999 0.25117901 0.532996 0.217034 0.48070699 0.35210899 0.54082298 - 0.34952399 0.53746098 0.37084499 0.529387 0.082309 0.56468099 0.099036001 - 0.56216699 0.060766999 0.53150898 0.049988002 0.529387 0.082309 0.56216699 - 0.060766999 0.475099 0.076341003 0.529387 0.082309 0.53150898 0.049988002 - 0.475099 0.076341003 0.53191298 0.15157899 0.529387 0.082309 0.529387 0.082309 - 0.53191298 0.15157899 0.56468099 0.099036001 0.532996 0.217034 0.57477999 - 0.25117901 0.563384 0.216162 0.563384 0.216162 0.57477999 0.25117901 0.61704302 - 0.20689499 0.53191298 0.15157899 0.563384 0.216162 0.61704302 0.20689499 - 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 0.53746098 0.37084499 - 0.53674299 0.39848399 0.47946599 0.37119001 0.48070699 0.35210899 0.53746098 - 0.37084499 0.47946599 0.37119001 0.359846 0.051763002 0.37215099 0.13412 - 0.475099 0.076341003 0.255613 0.25320399 0.31703201 0.24954499 0.258811 0.22176901 - 0.639902 0.47827199 0.61546803 0.418973 0.60980803 0.47876301 0.57874799 - 0.472913 0.60980803 0.47876301 0.61546803 0.418973 0.036951002 0.29172301 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.151114 0.233711 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 - 0.041522998 0.25432399 0.102847 0.22989 0.069355004 0.21782801 0.069355004 - 0.21782801 0.102847 0.22989 0.107695 0.172719 0.069355004 0.21782801 0.107695 - 0.172719 0.070349 0.165839 0.070349 0.165839 0.107695 0.172719 0.080518 0.123654 - 0.107695 0.172719 0.151114 0.233711 0.155274 0.177471 0.102847 0.22989 0.151114 - 0.233711 0.107695 0.172719 0.080518 0.123654 0.107695 0.172719 0.155274 0.177471 - 0.080518 0.123654 0.155274 0.177471 0.271054 0.13361099 0.155274 0.177471 - 0.22066 0.18181901 0.271054 0.13361099 0.316248 0.291545 0.32999301 0.33045399 - 0.39272901 0.33256099 0.26878601 0.315254 0.32999301 0.33045399 0.316248 - 0.291545 0.36022699 0.003454 0.359846 0.051763002 0.42296299 0.00556 0.65543997 - 0.49157101 0.639902 0.47827199 0.62550402 0.53194499 0.016138 0.325297 0.036951002 - 0.29172301 0.0040460001 0.25350901 0.0040460001 0.25350901 0.041522998 0.25432399 - 0.027048999 0.208827 0.0040460001 0.25350901 0.036951002 0.29172301 0.041522998 - 0.25432399 0.039096002 0.044592999 0.039241001 0.118589 0.056297999 0.091900997 - 0.039096002 0.044592999 0.056297999 0.091900997 0.062045 0.057544 0.039096002 - 0.044592999 0.062045 0.057544 0.065323003 0.030218 0.016138 0.325297 0.023626 - 0.35801601 0.048168998 0.35214001 0.155274 0.177471 0.193956 0.19936 0.22066 - 0.18181901 0.151114 0.233711 0.193956 0.19936 0.155274 0.177471 0.151114 - 0.233711 0.19205201 0.23548099 0.193956 0.19936 0.19205201 0.23548099 0.216565 - 0.237138 0.193956 0.19936 0.193956 0.19936 0.216565 0.237138 0.22066 0.18181901 - 0.47337201 0.42365801 0.53173602 0.43147901 0.49755499 0.488251 0.47337201 - 0.42365801 0.49755499 0.488251 0.415775 0.44801801 0.61118603 0.156872 0.64614099 - 0.22702 0.63806599 0.14799 0.61118603 0.156872 0.63806599 0.14799 0.63874 - 0.094846003 0.56216699 0.060766999 0.56468099 0.099036001 0.63874 0.094846003 - 0.56216699 0.060766999 0.63874 0.094846003 0.64656198 0.069087997 0.55324697 - 0.28502101 0.57625401 0.29346699 0.602754 0.257723 0.55185699 0.34580401 - 0.57625401 0.29346699 0.55324697 0.28502101 0.55185699 0.34580401 0.58940798 - 0.33751199 0.57625401 0.29346699 0.57625401 0.29346699 0.58940798 0.33751199 - 0.60898602 0.28752601 0.57625401 0.29346699 0.60898602 0.28752601 0.602754 - 0.257723 0.34836701 0.49853599 0.44446999 0.51254302 0.35016599 0.53974301 - 0.415775 0.44801801 0.49755499 0.488251 0.44446999 0.51254302 0.415775 0.44801801 - 0.44446999 0.51254302 0.34836701 0.49853599 0.302367 0.46158099 0.227768 - 0.50040001 0.235855 0.44651899 0.245719 0.014829 0.31335899 0.057027001 0.316118 - 0.025185 0.316118 0.025185 0.31335899 0.057027001 0.359846 0.051763002 0.316118 - 0.025185 0.359846 0.051763002 0.36022699 0.003454 0.26878601 0.315254 0.28588501 - 0.35218599 0.32999301 0.33045399 0.21787301 0.34819999 0.28588501 0.35218599 - 0.26878601 0.315254 0.32905 0.12617201 0.37215099 0.13412 0.359846 0.051763002 - 0.25301799 0.068204001 0.271054 0.13361099 0.31976199 0.096646003 0.271054 - 0.13361099 0.32905 0.12617201 0.31976199 0.096646003 0.31976199 0.096646003 - 0.32905 0.12617201 0.359846 0.051763002 0.31335899 0.057027001 0.31976199 - 0.096646003 0.359846 0.051763002 0.25301799 0.068204001 0.31976199 0.096646003 - 0.31335899 0.057027001 0.11848 0.325919 0.21787301 0.34819999 0.128057 0.28853801 - 0.048168998 0.35214001 0.11848 0.325919 0.128057 0.28853801 0.142845 0.034219 - 0.25301799 0.068204001 0.245719 0.014829 0.062045 0.057544 0.271054 0.13361099 - 0.25301799 0.068204001 0.065323003 0.030218 0.062045 0.057544 0.142845 0.034219 - 0.062045 0.057544 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[1250:1499]" 0.142845 0.034219 0.216565 0.237138 - 0.255613 0.25320399 0.258811 0.22176901 0.22066 0.18181901 0.216565 0.237138 - 0.258811 0.22176901 0.22066 0.18181901 0.258811 0.22176901 0.31351399 0.202804 - 0.89018202 0.239971 0.86741501 0.373849 0.84087598 0.31692401 0.79613203 - 0.35278401 0.84594899 0.227217 0.82062 0.34356001 0.89018202 0.239971 0.84087598 - 0.31692401 0.84594899 0.227217 0.84594899 0.227217 0.84087598 0.31692401 - 0.82062 0.34356001 0.89836198 0.137126 0.89018202 0.239971 0.84594899 0.227217 - 0.79613203 0.35278401 0.82062 0.34356001 0.814367 0.424068 0.86741501 0.373849 - 0.82062 0.34356001 0.84087598 0.31692401 0.86741501 0.373849 0.88974899 0.43314499 - 0.814367 0.424068 0.814367 0.424068 0.88974899 0.43314499 0.82335901 0.49983799 - 0.76275897 0.37884799 0.79613203 0.35278401 0.814367 0.424068 0.86741501 - 0.373849 0.814367 0.424068 0.82062 0.34356001 0.814367 0.424068 0.82335901 - 0.49983799 0.773857 0.53407699 0.73045999 0.53145701 0.779073 0.44323799 - 0.773857 0.53407699 0.779073 0.44323799 0.814367 0.424068 0.773857 0.53407699 - 0.89836198 0.137126 0.84594899 0.227217 0.83935702 0.100765 0.83935702 0.100765 - 0.84594899 0.227217 0.79802299 0.211936 0.79613203 0.35278401 0.79802299 - 0.211936 0.84594899 0.227217 0.89836198 0.137126 0.83935702 0.100765 0.87032902 - 0.045508999 0.83545703 0.043729 0.87032902 0.045508999 0.83935702 0.100765 - 0.818169 0.062284999 0.83545703 0.043729 0.83935702 0.100765 0.95396501 0.134362 - 0.966021 0.28052899 0.89018202 0.239971 0.966021 0.28052899 0.89975703 0.32890701 - 0.89018202 0.239971 0.89975703 0.32890701 0.86741501 0.373849 0.89018202 - 0.239971 0.76275897 0.37884799 0.79802299 0.211936 0.79613203 0.35278401 - 0.76275897 0.37884799 0.814367 0.424068 0.779073 0.44323799 0.76275897 0.37884799 - 0.779073 0.44323799 0.74679601 0.45871499 0.733105 0.37849101 0.76275897 - 0.37884799 0.74679601 0.45871499 0.71095902 0.44087201 0.70178902 0.52030098 - 0.68089098 0.41862199 0.71095902 0.44087201 0.74679601 0.45871499 0.70178902 - 0.52030098 0.70178902 0.52030098 0.74679601 0.45871499 0.73045999 0.53145701 - 0.74679601 0.45871499 0.779073 0.44323799 0.73045999 0.53145701 0.733105 - 0.37849101 0.74679601 0.45871499 0.71095902 0.44087201 0.97778797 0.040635999 - 0.95396501 0.134362 0.89836198 0.137126 0.97778797 0.040635999 0.89836198 - 0.137126 0.94019401 0.031078 0.99264401 0.396844 0.89975703 0.32890701 0.966021 - 0.28052899 0.99426401 0.26670301 0.99264401 0.396844 0.966021 0.28052899 - 0.65865201 0.27080399 0.71095902 0.44087201 0.68089098 0.41862199 0.70381802 - 0.225641 0.71095902 0.44087201 0.65865201 0.27080399 0.70381802 0.225641 - 0.65865201 0.27080399 0.64760703 0.20985 0.98321998 0.20574901 0.966021 0.28052899 - 0.95396501 0.134362 0.98321998 0.20574901 0.99426401 0.26670301 0.966021 - 0.28052899 0.95396501 0.134362 0.89018202 0.239971 0.89836198 0.137126 0.70381802 - 0.225641 0.64760703 0.20985 0.66965002 0.116933 0.70381802 0.225641 0.66965002 - 0.116933 0.719881 0.006691 0.719881 0.006691 0.66965002 0.116933 0.66478199 - 0.0078290002 0.70381802 0.225641 0.73960102 0.22293501 0.733105 0.37849101 - 0.70381802 0.225641 0.733105 0.37849101 0.71095902 0.44087201 0.73960102 - 0.22293501 0.76275897 0.37884799 0.733105 0.37849101 0.76523697 0.19111399 - 0.79802299 0.211936 0.76275897 0.37884799 0.73960102 0.22293501 0.76523697 - 0.19111399 0.76275897 0.37884799 0.719881 0.006691 0.75811899 0.0040250001 - 0.73960102 0.22293501 0.818169 0.062284999 0.83935702 0.100765 0.79802299 - 0.211936 0.76523697 0.19111399 0.818169 0.062284999 0.79802299 0.211936 0.70381802 - 0.225641 0.719881 0.006691 0.73960102 0.22293501 0.73960102 0.22293501 0.75811899 - 0.0040250001 0.76523697 0.19111399 0.95050299 0.82310897 0.94037199 0.870426 - 0.98507398 0.893085 0.95050299 0.82310897 0.98507398 0.893085 0.99505001 - 0.82360703 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.98405302 - 0.91405201 0.94326001 0.89290702 0.90755701 0.964562 0.94326001 0.89290702 - 0.909796 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.85467398 0.99159998 - 0.90755701 0.964562 0.98507398 0.893085 0.94037199 0.870426 0.98405302 0.91405201 - 0.94037199 0.870426 0.94326001 0.89290702 0.98405302 0.91405201 0.94037199 - 0.870426 0.909796 0.8951 0.94326001 0.89290702 0.91257 0.81947201 0.94037199 - 0.870426 0.95050299 0.82310897 0.91257 0.81947201 0.909796 0.8951 0.94037199 - 0.870426 0.84964103 0.74003702 0.909796 0.8951 0.91257 0.81947201 0.84964103 - 0.74003702 0.86997002 0.93731803 0.909796 0.8951 0.63363802 0.89377397 0.68109202 - 0.85573 0.66562402 0.92713302 0.804057 0.01567 0.83545703 0.043729 0.818169 - 0.062284999 0.78658998 0.052133001 0.804057 0.01567 0.818169 0.062284999 - 0.86865902 0.013712 0.90803403 0.044094998 0.87032902 0.045508999 0.94019401 - 0.031078 0.90803403 0.044094998 0.86865902 0.013712 0.86865902 0.013712 0.87032902 - 0.045508999 0.83545703 0.043729 0.804057 0.01567 0.86865902 0.013712 0.83545703 - 0.043729 0.75811899 0.0040250001 0.804057 0.01567 0.78658998 0.052133001 - 0.32756099 0.89249802 0.33477801 0.909235 0.33735099 0.85548198 0.33477801 - 0.909235 0.34354001 0.86769497 0.33735099 0.85548198 0.35936901 0.91262299 - 0.371288 0.86448097 0.34659299 0.92080897 0.34659299 0.92080897 0.371288 - 0.86448097 0.359723 0.87225002; - setAttr ".uvst[0].uvsp[1500:1749]" 0.33477801 0.909235 0.34659299 0.92080897 - 0.359723 0.87225002 0.33477801 0.909235 0.359723 0.87225002 0.34354001 0.86769497 - 0.48538801 0.95112503 0.45333701 0.95817798 0.44578099 0.93405002 0.48538801 - 0.95112503 0.44578099 0.93405002 0.48168799 0.91676801 0.45333701 0.95817798 - 0.43036199 0.96655297 0.42452699 0.94267398 0.45333701 0.95817798 0.42452699 - 0.94267398 0.44578099 0.93405002 0.33735099 0.85548198 0.34354001 0.86769497 - 0.352687 0.831747 0.33735099 0.85548198 0.352687 0.831747 0.34862399 0.80891901 - 0.34354001 0.86769497 0.359723 0.87225002 0.368599 0.83635598 0.34354001 - 0.86769497 0.368599 0.83635598 0.352687 0.831747 0.371288 0.86448097 0.38256299 - 0.81765997 0.368599 0.83635598 0.371288 0.86448097 0.368599 0.83635598 0.359723 - 0.87225002 0.39850101 0.96660697 0.42452699 0.94267398 0.43036199 0.96655297 - 0.37021199 0.79415601 0.34862399 0.80891901 0.35968399 0.81033999 0.34862399 - 0.80891901 0.352687 0.831747 0.35968399 0.81033999 0.35968399 0.81033999 - 0.352687 0.831747 0.368599 0.83635598 0.35968399 0.81033999 0.368599 0.83635598 - 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 0.38256299 - 0.81765997 0.38256299 0.81765997 0.37179601 0.81299299 0.368599 0.83635598 - 0.37021199 0.79415601 0.35968399 0.81033999 0.37179601 0.81299299 0.29274601 - 0.90635097 0.30324501 0.90815997 0.308972 0.86521697 0.29274601 0.90635097 - 0.308972 0.86521697 0.300255 0.86195898 0.32756099 0.89249802 0.33101901 - 0.87009001 0.32226399 0.867616 0.32756099 0.89249802 0.32226399 0.867616 - 0.31726399 0.91030401 0.30324501 0.90815997 0.31726399 0.91030401 0.32226399 - 0.867616 0.30324501 0.90815997 0.32226399 0.867616 0.308972 0.86521697 0.49160999 - 0.97508597 0.46529901 0.98378903 0.46022999 0.96179903 0.49160999 0.97508597 - 0.46022999 0.96179903 0.48538801 0.95112503 0.46529901 0.98378903 0.43633199 - 0.99328399 0.43152601 0.97203702 0.46529901 0.98378903 0.43152601 0.97203702 - 0.46022999 0.96179903 0.300255 0.86195898 0.308972 0.86521697 0.307354 0.82550597 - 0.307354 0.82550597 0.308972 0.86521697 0.31612 0.82580698 0.308972 0.86521697 - 0.32226399 0.867616 0.329963 0.82830203 0.308972 0.86521697 0.329963 0.82830203 - 0.31612 0.82580698 0.33101901 0.87009001 0.33719999 0.843934 0.32226399 0.867616 - 0.33719999 0.843934 0.329963 0.82830203 0.32226399 0.867616 0.43633199 0.99328399 - 0.405705 0.98896497 0.43152601 0.97203702 0.32305399 0.80920303 0.31612 0.82580698 - 0.329963 0.82830203 0.32305399 0.80920303 0.329963 0.82830203 0.33029699 - 0.81221998 0.33178499 0.78945303 0.32305399 0.80920303 0.33029699 0.81221998 - 0.39264601 0.86977398 0.38328499 0.85446298 0.38630301 0.87709397 0.38328499 - 0.85446298 0.380456 0.87159598 0.38630301 0.87709397 0.38630301 0.87709397 - 0.380456 0.87159598 0.376625 0.895226 0.38593799 0.83733201 0.38328499 0.85446298 - 0.39264601 0.86977398 0.39264601 0.86977398 0.38630301 0.87709397 0.38863 - 0.90287602 0.38593799 0.83733201 0.39264601 0.86977398 0.40770999 0.866552 - 0.42723399 0.92242002 0.43939599 0.911412 0.44178799 0.92605698 0.38593799 - 0.83733201 0.37287301 0.875799 0.38328499 0.85446298 0.40770999 0.866552 - 0.39264601 0.86977398 0.38863 0.90287602 0.36799499 0.89132202 0.36011499 - 0.92878401 0.376625 0.895226 0.35936901 0.91262299 0.36011499 0.92878401 - 0.36799499 0.89132202 0.36799499 0.89132202 0.380456 0.87159598 0.37287301 - 0.875799 0.36799499 0.89132202 0.376625 0.895226 0.380456 0.87159598 0.38328499 - 0.85446298 0.37287301 0.875799 0.380456 0.87159598 0.35936901 0.91262299 - 0.34659299 0.92080897 0.36011499 0.92878401 0.32756099 0.89249802 0.31726399 - 0.91030401 0.33477801 0.909235 0.41693899 0.89492601 0.40770999 0.866552 - 0.40901801 0.89674503 0.381246 0.95752001 0.39948201 0.920587 0.38863 0.90287602 - 0.381246 0.95752001 0.376625 0.895226 0.36011499 0.92878401 0.381246 0.95752001 - 0.38863 0.90287602 0.376625 0.895226 0.38863 0.90287602 0.38630301 0.87709397 - 0.376625 0.895226 0.381246 0.95752001 0.36011499 0.92878401 0.33891901 0.987975 - 0.34659299 0.92080897 0.32005399 0.97494799 0.36011499 0.92878401 0.33891901 - 0.987975 0.36011499 0.92878401 0.32005399 0.97494799 0.33477801 0.909235 - 0.32005399 0.97494799 0.34659299 0.92080897 0.30324501 0.90815997 0.300001 - 0.97013903 0.31726399 0.91030401 0.28796199 0.92390901 0.30324501 0.90815997 - 0.29274601 0.90635097 0.28796199 0.92390901 0.290243 0.940907 0.30324501 - 0.90815997 0.27395099 0.912489 0.270601 0.92593902 0.28796199 0.92390901 - 0.270601 0.92593902 0.290243 0.940907 0.28796199 0.92390901 0.258212 0.91232401 - 0.270601 0.92593902 0.27395099 0.912489 0.258212 0.91232401 0.25671601 0.927858 - 0.270601 0.92593902 0.290243 0.940907 0.300001 0.97013903 0.30324501 0.90815997 - 0.290243 0.940907 0.283005 0.96905398 0.300001 0.97013903 0.270601 0.92593902 - 0.283005 0.96905398 0.290243 0.940907 0.25671601 0.927858 0.283005 0.96905398 - 0.270601 0.92593902 0.369001 0.99685502 0.381246 0.95752001 0.35122901 1.000869 - 0.35122901 1.000869 0.381246 0.95752001 0.33891901 0.987975 0.25671601 0.927858 - 0.25706601 0.969437 0.283005 0.96905398 0.53719902 0.90499997 0.53121799 - 0.86490297 0.54497999 0.877047 0.56407797 0.91909999 0.53719902 0.90499997 - 0.54497999 0.877047 0.53666401 0.96573699 0.52387398 0.97127301 0.54059702 - 0.94349098 0.54059702 0.94349098 0.52387398 0.97127301 0.521644 0.96135998 - 0.54084498 0.98507202; - setAttr ".uvst[0].uvsp[1750:1999]" 0.53666401 0.96573699 0.55496401 - 0.97537702 0.53666401 0.96573699 0.54059702 0.94349098 0.55496401 0.97537702 - 0.262528 0.89503402 0.258212 0.91232401 0.27759501 0.89841598 0.27759501 - 0.89841598 0.258212 0.91232401 0.27395099 0.912489 0.27759501 0.89841598 - 0.27395099 0.912489 0.291614 0.896658 0.27395099 0.912489 0.28940701 0.91069198 - 0.291614 0.896658 0.52629602 0.99024498 0.51558298 0.98070103 0.52387398 - 0.97127301 0.52629602 0.99024498 0.52387398 0.97127301 0.53666401 0.96573699 - 0.52678698 0.99600202 0.52629602 0.99024498 0.54084498 0.98507202 0.54084498 - 0.98507202 0.52629602 0.99024498 0.53666401 0.96573699 0.26901299 0.87969601 - 0.262528 0.89503402 0.27759501 0.89841598 0.26901299 0.87969601 0.27759501 - 0.89841598 0.282882 0.883295 0.282882 0.883295 0.27759501 0.89841598 0.29319 - 0.88515502 0.27759501 0.89841598 0.291614 0.896658 0.29319 0.88515502 0.52678698 - 0.99600202 0.50723398 0.99519998 0.52629602 0.99024498 0.26901299 0.87969601 - 0.282882 0.883295 0.28712299 0.87004602 0.282882 0.883295 0.29319 0.88515502 - 0.28712299 0.87004602 0.52629602 0.99024498 0.50723398 0.99519998 0.51558298 - 0.98070103 0.27395099 0.912489 0.28796199 0.92390901 0.28940701 0.91069198 - 0.54059702 0.94349098 0.53719902 0.90499997 0.56407797 0.91909999 0.56377 - 0.96770799 0.54059702 0.94349098 0.56407797 0.91909999 0.55496401 0.97537702 - 0.54059702 0.94349098 0.56377 0.96770799 0.45547101 0.90422702 0.45468801 - 0.92364502 0.44178799 0.92605698 0.43939599 0.911412 0.45547101 0.90422702 - 0.44178799 0.92605698 0.41693899 0.89492601 0.41640201 0.88049698 0.40770999 - 0.866552 0.40770999 0.866552 0.38863 0.90287602 0.39948201 0.920587 0.40901801 - 0.89674503 0.40770999 0.866552 0.39948201 0.920587 0.41693899 0.89492601 - 0.40901801 0.89674503 0.41201699 0.92887998 0.41201699 0.92887998 0.40901801 - 0.89674503 0.39948201 0.920587 0.44038501 0.90504903 0.46091801 0.88338 0.45547101 - 0.90422702 0.41201699 0.92887998 0.39948201 0.920587 0.381246 0.95752001 - 0.39207101 0.96583498 0.41201699 0.92887998 0.381246 0.95752001 0.48168799 - 0.91676801 0.45468801 0.92364502 0.45547101 0.90422702 0.496647 0.874951 - 0.48168799 0.91676801 0.45547101 0.90422702 0.496647 0.874951 0.45547101 - 0.90422702 0.46091801 0.88338 0.496647 0.874951 0.49597099 0.91574198 0.48168799 - 0.91676801 0.50320703 0.95512199 0.49160999 0.97508597 0.48538801 0.95112503 - 0.50320703 0.95512199 0.48538801 0.95112503 0.49597099 0.91574198 0.49597099 - 0.91574198 0.48538801 0.95112503 0.48168799 0.91676801 0.521644 0.96135998 - 0.51486897 0.97433299 0.50320703 0.95512199 0.51486897 0.97433299 0.49160999 - 0.97508597 0.50320703 0.95512199 0.53719902 0.90499997 0.49597099 0.91574198 - 0.496647 0.874951 0.54059702 0.94349098 0.521644 0.96135998 0.53719902 0.90499997 - 0.53719902 0.90499997 0.50320703 0.95512199 0.49597099 0.91574198 0.521644 - 0.96135998 0.50320703 0.95512199 0.53719902 0.90499997 0.369001 0.99685502 - 0.39207101 0.96583498 0.381246 0.95752001 0.53719902 0.90499997 0.496647 - 0.874951 0.53121799 0.86490297 0.89836198 0.137126 0.87032902 0.045508999 - 0.90803403 0.044094998 0.94019401 0.031078 0.89836198 0.137126 0.90803403 - 0.044094998 0.75811899 0.0040250001 0.78658998 0.052133001 0.76523697 0.19111399 - 0.76523697 0.19111399 0.78658998 0.052133001 0.818169 0.062284999 0.307354 - 0.82550597 0.31612 0.82580698 0.32305399 0.80920303 0.307354 0.82550597 0.32305399 - 0.80920303 0.33178499 0.78945303 0.33178499 0.78945303 0.33029699 0.81221998 - 0.33719999 0.843934 0.33719999 0.843934 0.33029699 0.81221998 0.329963 0.82830203 - 0.77899301 0.67823797 0.74377102 0.72034299 0.78915399 0.74251801 0.77899301 - 0.67823797 0.78915399 0.74251801 0.84964103 0.74003702 0.78915399 0.74251801 - 0.82964599 0.80204397 0.84964103 0.74003702 0.71901399 0.78532398 0.69465202 - 0.75267702 0.694462 0.78577 0.71901399 0.78532398 0.694462 0.78577 0.718126 - 0.82873601 0.694462 0.78577 0.68843299 0.845505 0.66842598 0.82617402 0.694462 - 0.78577 0.66842598 0.82617402 0.718126 0.82873601 0.718126 0.82873601 0.66842598 - 0.82617402 0.68843299 0.845505 0.31726399 0.91030401 0.300001 0.97013903 - 0.32005399 0.97494799 0.31726399 0.91030401 0.32005399 0.97494799 0.33477801 - 0.909235 0.44672099 0.742163 0.38921699 0.788423 0.39220601 0.76434302 0.44672099 - 0.742163 0.40665799 0.802068 0.38921699 0.788423 0.476217 0.727027 0.40665799 - 0.802068 0.44672099 0.742163 0.63363802 0.89377397 0.66562402 0.92713302 - 0.62646401 0.95210898 0.62646401 0.95210898 0.66562402 0.92713302 0.65396702 - 0.95580101 0.71984899 0.75139397 0.69465202 0.75267702 0.71901399 0.78532398 - 0.75477803 0.76254302 0.71901399 0.78532398 0.75086302 0.78398401 0.71984899 - 0.75139397 0.71901399 0.78532398 0.75477803 0.76254302 0.62701303 0.95989603 - 0.62603098 0.97777802 0.65045398 0.98993599 0.62701303 0.95989603 0.65045398 - 0.98993599 0.653786 0.972588 0.71176398 0.71938401 0.69725502 0.74743497 - 0.72957599 0.74754602 0.71176398 0.71938401 0.72957599 0.74754602 0.74377102 - 0.72034299 0.74377102 0.72034299 0.72957599 0.74754602 0.78915399 0.74251801 - 0.72957599 0.74754602 0.76598603 0.762146 0.78915399 0.74251801 0.96395802 - 0.96951902 0.95559901 0.985829 0.97251898 0.99150902 0.96395802 0.96951902 - 0.97251898 0.99150902 0.982153 0.97301102 0.70140499 0.66365999 0.65568203 - 0.65436798 0.64994597 0.70058 0.70140499 0.66365999 0.64994597 0.70058 0.69391102 - 0.70558798 0.69391102 0.70558798 0.64994597 0.70058; - setAttr ".uvst[0].uvsp[2000:2249]" 0.60770202 0.71877599 0.69391102 - 0.70558798 0.60770202 0.71877599 0.658795 0.73315901 0.68494898 0.62769097 - 0.62879598 0.619084 0.70140499 0.66365999 0.62879598 0.619084 0.65568203 - 0.65436798 0.70140499 0.66365999 0.62879598 0.619084 0.60452098 0.662067 - 0.65568203 0.65436798 0.65568203 0.65436798 0.60452098 0.662067 0.64994597 - 0.70058 0.60452098 0.662067 0.60770202 0.71877599 0.64994597 0.70058 0.892663 - 0.58372599 0.86585498 0.608989 0.904742 0.61987799 0.88192099 0.50762999 - 0.86585498 0.608989 0.892663 0.58372599 0.88192099 0.50762999 0.84326202 - 0.52863598 0.86585498 0.608989 0.93670201 0.60081297 0.90890902 0.65339601 - 0.94025302 0.64341003 0.93670201 0.60081297 0.904742 0.61987799 0.90890902 - 0.65339601 0.96222198 0.59601402 0.93670201 0.60081297 0.94025302 0.64341003 - 0.93670201 0.60081297 0.892663 0.58372599 0.904742 0.61987799 0.88192099 - 0.50762999 0.892663 0.58372599 0.93670201 0.60081297 0.91139501 0.52158397 - 0.88192099 0.50762999 0.93670201 0.60081297 0.91139501 0.52158397 0.93670201 - 0.60081297 0.96222198 0.59601402 0.47251999 0.59212297 0.44557601 0.62202299 - 0.493588 0.62263501 0.44557601 0.62202299 0.46083799 0.64259601 0.493588 - 0.62263501 0.44557601 0.62202299 0.422638 0.66873902 0.46083799 0.64259601 - 0.471468 0.56798297 0.47251999 0.59212297 0.50988603 0.60414898 0.47251999 - 0.59212297 0.493588 0.62263501 0.50988603 0.60414898 0.46083799 0.64259601 - 0.422638 0.66873902 0.43200499 0.70468998 0.46083799 0.64259601 0.43200499 - 0.70468998 0.469937 0.66459 0.50244898 0.644642 0.46083799 0.64259601 0.469937 - 0.66459 0.493588 0.62263501 0.46083799 0.64259601 0.50244898 0.644642 0.50988603 - 0.60414898 0.493588 0.62263501 0.55948597 0.61438298 0.493588 0.62263501 - 0.55341202 0.63760501 0.55948597 0.61438298 0.50244898 0.644642 0.469937 - 0.66459 0.476217 0.727027 0.50244898 0.644642 0.476217 0.727027 0.56032002 - 0.70486701 0.476217 0.727027 0.578484 0.726412 0.56032002 0.70486701 0.476217 - 0.727027 0.56181002 0.765275 0.578484 0.726412 0.47210601 0.79053301 0.484781 - 0.85584599 0.50365102 0.81889403 0.56181002 0.765275 0.47210601 0.79053301 - 0.50365102 0.81889403 0.476217 0.727027 0.47210601 0.79053301 0.56181002 - 0.765275 0.47210601 0.79053301 0.401124 0.82737499 0.484781 0.85584599 0.401124 - 0.82737499 0.42608401 0.89203 0.484781 0.85584599 0.40665799 0.802068 0.401124 - 0.82737499 0.47210601 0.79053301 0.476217 0.727027 0.40665799 0.802068 0.47210601 - 0.79053301 0.47251999 0.59212297 0.43095401 0.61518103 0.44557601 0.62202299 - 0.471468 0.56798297 0.43095401 0.61518103 0.47251999 0.59212297 0.44446999 - 0.51254302 0.37521201 0.59356803 0.471468 0.56798297 0.471468 0.56798297 - 0.37521201 0.59356803 0.43095401 0.61518103 0.44557601 0.62202299 0.43095401 - 0.61518103 0.422638 0.66873902 0.37521201 0.59356803 0.422638 0.66873902 - 0.43095401 0.61518103 0.37521201 0.59356803 0.402172 0.66881698 0.422638 - 0.66873902 0.43200499 0.70468998 0.44672099 0.742163 0.476217 0.727027 0.469937 - 0.66459 0.43200499 0.70468998 0.476217 0.727027 0.43200499 0.70468998 0.39220601 - 0.76434302 0.44672099 0.742163 0.43200499 0.70468998 0.37832099 0.73359799 - 0.39220601 0.76434302 0.43200499 0.70468998 0.41114399 0.69965303 0.37832099 - 0.73359799 0.422638 0.66873902 0.41114399 0.69965303 0.43200499 0.70468998 - 0.402172 0.66881698 0.41114399 0.69965303 0.422638 0.66873902 0.402172 0.66881698 - 0.37832099 0.73359799 0.41114399 0.69965303 0.590801 0.64542502 0.55341202 - 0.63760501 0.58906102 0.696136 0.55341202 0.63760501 0.56032002 0.70486701 - 0.58906102 0.696136 0.50244898 0.644642 0.56032002 0.70486701 0.55341202 - 0.63760501 0.590801 0.64542502 0.594082 0.62339002 0.55341202 0.63760501 - 0.55948597 0.61438298 0.55341202 0.63760501 0.594082 0.62339002 0.44446999 - 0.51254302 0.471468 0.56798297 0.48631501 0.53582197 0.48631501 0.53582197 - 0.471468 0.56798297 0.52967697 0.561248 0.50988603 0.60414898 0.55948597 - 0.61438298 0.56466401 0.58405501 0.50988603 0.60414898 0.56466401 0.58405501 - 0.52967697 0.561248 0.52967697 0.561248 0.56466401 0.58405501 0.55312598 - 0.548361 0.59298301 0.57251501 0.55948597 0.61438298 0.594082 0.62339002 - 0.59298301 0.57251501 0.55312598 0.548361 0.56466401 0.58405501 0.48631501 - 0.53582197 0.52967697 0.561248 0.55312598 0.548361 0.55817002 0.495579 0.55312598 - 0.548361 0.59298301 0.57251501 0.55817002 0.495579 0.48631501 0.53582197 - 0.55312598 0.548361 0.59298301 0.57251501 0.56466401 0.58405501 0.55948597 - 0.61438298 0.29069301 0.56685197 0.33425501 0.67281002 0.34469 0.60969198 - 0.29069301 0.56685197 0.27809399 0.63370502 0.33425501 0.67281002 0.34469 - 0.60969198 0.33425501 0.67281002 0.37521201 0.59356803 0.37521201 0.59356803 - 0.33425501 0.67281002 0.402172 0.66881698 0.35016599 0.53974301 0.29069301 - 0.56685197 0.34469 0.60969198 0.35016599 0.53974301 0.241578 0.53054398 0.29069301 - 0.56685197 0.44446999 0.51254302 0.35016599 0.53974301 0.37521201 0.59356803 - 0.35016599 0.53974301 0.34469 0.60969198 0.37521201 0.59356803 0.70178902 - 0.52030098 0.62787598 0.58490998 0.66176099 0.61444402 0.70178902 0.52030098 - 0.66376501 0.50938398 0.62787598 0.58490998 0.66376501 0.50938398 0.611036 - 0.541574 0.62787598 0.58490998 0.94404799 0.534742 0.91139501 0.52158397 - 0.94016802 0.552697 0.91649199 0.412949 0.91139501 0.52158397 0.94404799 - 0.534742 0.91649199 0.412949 0.88974899 0.43314499 0.91139501 0.52158397; - setAttr ".uvst[0].uvsp[2250:2499]" 0.95096499 0.41022 0.91649199 0.412949 - 0.94404799 0.534742 0.95096499 0.41022 0.94404799 0.534742 0.97447199 0.54772502 - 0.95096499 0.41022 0.97447199 0.54772502 0.99280602 0.52736998 0.88974899 - 0.43314499 0.88192099 0.50762999 0.91139501 0.52158397 0.91649199 0.412949 - 0.86741501 0.373849 0.88974899 0.43314499 0.70178902 0.52030098 0.72172701 - 0.597004 0.73045999 0.53145701 0.402172 0.66881698 0.361752 0.72452599 0.37832099 - 0.73359799 0.402172 0.66881698 0.33425501 0.67281002 0.361752 0.72452599 - 0.70178902 0.52030098 0.66176099 0.61444402 0.72172701 0.597004 0.73045999 - 0.53145701 0.72172701 0.597004 0.76481098 0.59411001 0.33425501 0.67281002 - 0.33192599 0.74883097 0.361752 0.72452599 0.99264401 0.396844 0.95096499 - 0.41022 0.99280602 0.52736998 0.95096499 0.41022 0.89975703 0.32890701 0.91649199 - 0.412949 0.99264401 0.396844 0.89975703 0.32890701 0.95096499 0.41022 0.89975703 - 0.32890701 0.86741501 0.373849 0.91649199 0.412949 0.70178902 0.52030098 - 0.68089098 0.41862199 0.66376501 0.50938398 0.88974899 0.43314499 0.84326202 - 0.52863598 0.88192099 0.50762999 0.88974899 0.43314499 0.82335901 0.49983799 - 0.84326202 0.52863598 0.81960201 0.54509503 0.84326202 0.52863598 0.82335901 - 0.49983799 0.80370599 0.60544503 0.84326202 0.52863598 0.81960201 0.54509503 - 0.84326202 0.52863598 0.85311198 0.64641303 0.86585498 0.608989 0.85311198 - 0.64641303 0.90890902 0.65339601 0.86585498 0.608989 0.904742 0.61987799 - 0.86585498 0.608989 0.90890902 0.65339601 0.55527902 0.8071 0.56233603 0.85706103 - 0.61128402 0.83876997 0.55527902 0.8071 0.484781 0.85584599 0.56233603 0.85706103 - 0.61429799 0.75036502 0.56181002 0.765275 0.55527902 0.8071 0.60618597 0.86918902 - 0.57115501 0.92132199 0.63363802 0.89377397 0.56233603 0.85706103 0.57115501 - 0.92132199 0.60618597 0.86918902 0.23810799 0.94020498 0.14566401 0.93838102 - 0.16559599 0.995709 0.14566401 0.93838102 0.059299 0.99024302 0.16559599 - 0.995709 0.61128402 0.83876997 0.68109202 0.85573 0.66327202 0.82856899 0.23810799 - 0.94020498 0.17147 0.907399 0.14566401 0.93838102 0.14566401 0.93838102 0.063868999 - 0.91910303 0.059299 0.99024302 0.193271 0.88191301 0.135956 0.83810002 0.12989099 - 0.871301 0.072558001 0.88500297 0.052301999 0.89361697 0.063868999 0.91910303 - 0.61128402 0.83876997 0.60618597 0.86918902 0.68109202 0.85573 0.60618597 - 0.86918902 0.63363802 0.89377397 0.68109202 0.85573 0.063868999 0.91910303 - 0.052301999 0.89361697 0.0086899996 0.90104598 0.059299 0.99024302 0.063868999 - 0.91910303 0.0086899996 0.90104598 0.612091 0.80211103 0.61128402 0.83876997 - 0.66305399 0.78664398 0.61128402 0.83876997 0.66327202 0.82856899 0.66305399 - 0.78664398 0.64314198 0.77576202 0.612091 0.80211103 0.66305399 0.78664398 - 0.662714 0.74348199 0.64314198 0.77576202 0.68224001 0.752303 0.64314198 - 0.77576202 0.66305399 0.78664398 0.68224001 0.752303 0.61429799 0.75036502 - 0.612091 0.80211103 0.63186097 0.74417901 0.63186097 0.74417901 0.612091 - 0.80211103 0.64314198 0.77576202 0.63186097 0.74417901 0.64314198 0.77576202 - 0.662714 0.74348199 0.61429799 0.75036502 0.59559602 0.73881298 0.56181002 - 0.765275 0.596021 0.71545899 0.59559602 0.73881298 0.61429799 0.75036502 - 0.58906102 0.696136 0.578484 0.726412 0.596021 0.71545899 0.58906102 0.696136 - 0.56032002 0.70486701 0.578484 0.726412 0.596021 0.71545899 0.578484 0.726412 - 0.59559602 0.73881298 0.578484 0.726412 0.56181002 0.765275 0.59559602 0.73881298 - 0.029790999 0.85418802 0.038779002 0.81607199 0.0081359996 0.81497997 0.044146001 - 0.79082501 0.0081359996 0.81497997 0.038779002 0.81607199 0.074841 0.80788898 - 0.044146001 0.79082501 0.038779002 0.81607199 0.074841 0.80788898 0.038779002 - 0.81607199 0.073301002 0.83981198 0.073301002 0.83981198 0.12989099 0.871301 - 0.135956 0.83810002 0.072558001 0.88500297 0.063868999 0.91910303 0.12989099 - 0.871301 0.17147 0.907399 0.12989099 0.871301 0.063868999 0.91910303 0.069305003 - 0.862432 0.12989099 0.871301 0.073301002 0.83981198 0.069305003 0.862432 - 0.072558001 0.88500297 0.12989099 0.871301 0.069305003 0.862432 0.039615002 - 0.87295502 0.072558001 0.88500297 0.039615002 0.87295502 0.052301999 0.89361697 - 0.072558001 0.88500297 0.073301002 0.83981198 0.029790999 0.85418802 0.039615002 - 0.87295502 0.069305003 0.862432 0.073301002 0.83981198 0.039615002 0.87295502 - 0.039615002 0.87295502 0.029790999 0.85418802 0.0086899996 0.90104598 0.039615002 - 0.87295502 0.0086899996 0.90104598 0.052301999 0.89361697 0.133753 0.80051601 - 0.135956 0.83810002 0.193271 0.88191301 0.133753 0.80051601 0.073301002 0.83981198 - 0.135956 0.83810002 0.14566401 0.93838102 0.17147 0.907399 0.063868999 0.91910303 - 0.56233603 0.85706103 0.60618597 0.86918902 0.61128402 0.83876997 0.209691 - 0.79815799 0.193271 0.88191301 0.21379501 0.846349 0.21379501 0.846349 0.193271 - 0.88191301 0.225722 0.86254603 0.237334 0.83964097 0.21379501 0.846349 0.225722 - 0.86254603 0.193271 0.88191301 0.12989099 0.871301 0.17147 0.907399 0.23810799 - 0.94020498 0.193271 0.88191301 0.17147 0.907399 0.134497 0.74599701 0.115455 - 0.77456403 0.133753 0.80051601 0.189914 0.76742601 0.133753 0.80051601 0.209691 - 0.79815799 0.209691 0.79815799 0.133753 0.80051601 0.193271 0.88191301 0.26639199 - 0.865004 0.225722 0.86254603 0.193271 0.88191301 0.26639199 0.865004 0.237334 - 0.83964097 0.225722 0.86254603 0.84326202 0.52863598 0.81364501 0.66707098 - 0.85311198 0.64641303 0.26639199 0.865004; - setAttr ".uvst[0].uvsp[2500:2749]" 0.193271 0.88191301 0.23810799 0.94020498 - 0.80370599 0.60544503 0.81364501 0.66707098 0.84326202 0.52863598 0.32067001 - 0.79166698 0.237334 0.83964097 0.26639199 0.865004 0.30680701 0.75846398 - 0.237334 0.83964097 0.32067001 0.79166698 0.209691 0.79815799 0.21379501 - 0.846349 0.237334 0.83964097 0.193901 0.70055801 0.133753 0.80051601 0.189914 - 0.76742601 0.193901 0.70055801 0.189914 0.76742601 0.209691 0.79815799 0.193901 - 0.70055801 0.209691 0.79815799 0.235135 0.75121701 0.23119999 0.70723599 - 0.193901 0.70055801 0.235135 0.75121701 0.235135 0.75121701 0.209691 0.79815799 - 0.237334 0.83964097 0.30680701 0.75846398 0.235135 0.75121701 0.237334 0.83964097 - 0.23119999 0.70723599 0.235135 0.75121701 0.30680701 0.75846398 0.76481098 - 0.59411001 0.80370599 0.60544503 0.81960201 0.54509503 0.33192599 0.74883097 - 0.30680701 0.75846398 0.32067001 0.79166698 0.33425501 0.67281002 0.30680701 - 0.75846398 0.33192599 0.74883097 0.218197 0.66097301 0.193901 0.70055801 - 0.23119999 0.70723599 0.27809399 0.63370502 0.218197 0.66097301 0.23119999 - 0.70723599 0.73045999 0.53145701 0.76481098 0.59411001 0.773857 0.53407699 - 0.773857 0.53407699 0.76481098 0.59411001 0.81960201 0.54509503 0.773857 - 0.53407699 0.81960201 0.54509503 0.82335901 0.49983799 0.241578 0.53054398 - 0.214571 0.58170599 0.29069301 0.56685197 0.29069301 0.56685197 0.214571 - 0.58170599 0.27809399 0.63370502 0.214571 0.58170599 0.218197 0.66097301 - 0.27809399 0.63370502 0.214571 0.58170599 0.191866 0.64202601 0.218197 0.66097301 - 0.241578 0.53054398 0.181797 0.58704501 0.214571 0.58170599 0.241578 0.53054398 - 0.227768 0.50040001 0.181797 0.58704501 0.214571 0.58170599 0.181797 0.58704501 - 0.191866 0.64202601 0.191866 0.64202601 0.193901 0.70055801 0.218197 0.66097301 - 0.34836701 0.49853599 0.227768 0.50040001 0.35016599 0.53974301 0.35016599 - 0.53974301 0.227768 0.50040001 0.241578 0.53054398 0.33645499 0.40632701 - 0.302367 0.46158099 0.415775 0.44801801 0.415775 0.44801801 0.302367 0.46158099 - 0.34836701 0.49853599 0.55817002 0.495579 0.49755499 0.488251 0.48631501 - 0.53582197 0.49755499 0.488251 0.44446999 0.51254302 0.48631501 0.53582197 - 0.53173602 0.43147901 0.49755499 0.488251 0.55817002 0.495579 0.137054 0.71443301 - 0.134497 0.74599701 0.16243599 0.73647797 0.193901 0.70055801 0.16243599 - 0.73647797 0.133753 0.80051601 0.16243599 0.73647797 0.134497 0.74599701 - 0.133753 0.80051601 0.155361 0.68448699 0.137054 0.71443301 0.16243599 0.73647797 - 0.135434 0.64463699 0.137054 0.71443301 0.155361 0.68448699 0.073301002 0.83981198 - 0.038779002 0.81607199 0.029790999 0.85418802 0.191866 0.64202601 0.17482001 - 0.65435803 0.193901 0.70055801 0.17482001 0.65435803 0.16243599 0.73647797 - 0.193901 0.70055801 0.17482001 0.65435803 0.155361 0.68448699 0.16243599 - 0.73647797 0.181797 0.58704501 0.17482001 0.65435803 0.191866 0.64202601 - 0.134919 0.61088699 0.17482001 0.65435803 0.152937 0.59559798 0.181797 0.58704501 - 0.152937 0.59559798 0.17482001 0.65435803 0.302367 0.46158099 0.227768 0.50040001 - 0.34836701 0.49853599 0.17433301 0.53156102 0.152937 0.59559798 0.181797 - 0.58704501 0.227768 0.50040001 0.17433301 0.53156102 0.181797 0.58704501 - 0.24266601 0.36897901 0.302367 0.46158099 0.33645499 0.40632701 0.493588 - 0.62263501 0.50244898 0.644642 0.55341202 0.63760501 0.135434 0.64463699 - 0.155361 0.68448699 0.17482001 0.65435803 0.134919 0.61088699 0.135434 0.64463699 - 0.17482001 0.65435803 0.235855 0.44651899 0.19817799 0.43839601 0.195015 - 0.48982099 0.216538 0.39981201 0.19817799 0.43839601 0.235855 0.44651899 - 0.24266601 0.36897901 0.235855 0.44651899 0.302367 0.46158099 0.195015 0.48982099 - 0.17433301 0.53156102 0.227768 0.50040001 0.235855 0.44651899 0.195015 0.48982099 - 0.227768 0.50040001 0.24266601 0.36897901 0.216538 0.39981201 0.235855 0.44651899 - 0.24266601 0.36897901 0.202446 0.3633 0.216538 0.39981201 0.471468 0.56798297 - 0.50988603 0.60414898 0.52967697 0.561248 0.61429799 0.75036502 0.55527902 - 0.8071 0.612091 0.80211103 0.55527902 0.8071 0.61128402 0.83876997 0.612091 - 0.80211103 0.81753498 0.92918402 0.86997002 0.93731803 0.79334199 0.99322498 - 0.86997002 0.93731803 0.85467398 0.99159998 0.79334199 0.99322498 0.75108498 - 0.90098101 0.81753498 0.92918402 0.71710402 0.94957799 0.681234 0.89455098 - 0.75108498 0.90098101 0.71710402 0.94957799 0.71710402 0.94957799 0.81753498 - 0.92918402 0.79334199 0.99322498 0.68843299 0.845505 0.71957898 0.86809897 - 0.681234 0.89455098 0.77899301 0.67823797 0.848369 0.70362002 0.84964103 - 0.74003702 0.77899301 0.67823797 0.77644902 0.63733798 0.848369 0.70362002 - 0.78393102 0.81632203 0.82964599 0.80204397 0.79684901 0.86380398 0.72519898 - 0.67094803 0.77644902 0.63733798 0.77899301 0.67823797 0.72519898 0.67094803 - 0.77899301 0.67823797 0.74377102 0.72034299 0.72519898 0.67094803 0.74377102 - 0.72034299 0.71176398 0.71938401 0.71957898 0.86809897 0.75108498 0.90098101 - 0.681234 0.89455098 0.79684901 0.86380398 0.81753498 0.92918402 0.75108498 - 0.90098101 0.718126 0.82873601 0.71957898 0.86809897 0.68843299 0.845505 - 0.71957898 0.86809897 0.79684901 0.86380398 0.75108498 0.90098101 0.78393102 - 0.81632203 0.79684901 0.86380398 0.71957898 0.86809897 0.718126 0.82873601 - 0.78393102 0.81632203 0.71957898 0.86809897 0.71901399 0.78532398 0.75086302 - 0.78398401 0.718126 0.82873601 0.75086302 0.78398401 0.78393102 0.81632203; - setAttr ".uvst[0].uvsp[2750:2999]" 0.718126 0.82873601 0.27809399 0.63370502 - 0.23119999 0.70723599 0.30680701 0.75846398 0.27809399 0.63370502 0.30680701 - 0.75846398 0.33425501 0.67281002 0.56181002 0.765275 0.50365102 0.81889403 - 0.55527902 0.8071 0.55527902 0.8071 0.50365102 0.81889403 0.484781 0.85584599 - 0.78915399 0.74251801 0.82964599 0.80204397 0.78393102 0.81632203 0.78915399 - 0.74251801 0.78393102 0.81632203 0.75086302 0.78398401 0.82964599 0.80204397 - 0.86997002 0.93731803 0.81753498 0.92918402 0.82964599 0.80204397 0.81753498 - 0.92918402 0.79684901 0.86380398 0.84964103 0.74003702 0.86997002 0.93731803 - 0.82964599 0.80204397 0.133753 0.80051601 0.074841 0.80788898 0.073301002 - 0.83981198 0.115455 0.77456403 0.074841 0.80788898 0.133753 0.80051601 0.316248 - 0.291545 0.35912099 0.27489001 0.39272901 0.33256099 0.316248 0.291545 0.33604199 - 0.25541499 0.35912099 0.27489001 0.35912099 0.27489001 0.47097301 0.28257099 - 0.39272901 0.33256099 0.39272901 0.33256099 0.47097301 0.28257099 0.55185699 - 0.34580401 0.47097301 0.28257099 0.52854401 0.261291 0.55324697 0.28502101 - 0.47097301 0.28257099 0.55324697 0.28502101 0.55185699 0.34580401 0.316248 - 0.291545 0.31703201 0.24954499 0.33604199 0.25541499 0.258811 0.22176901 - 0.31351399 0.202804 0.31703201 0.24954499 0.255613 0.25320399 0.31703201 - 0.24954499 0.316248 0.291545 0.255613 0.25320399 0.316248 0.291545 0.26878601 - 0.315254 0.400451 0.218311 0.532996 0.217034 0.52854401 0.261291 0.35348001 - 0.188078 0.53191298 0.15157899 0.400451 0.218311 0.35348001 0.188078 0.37215099 - 0.13412 0.53191298 0.15157899 0.33604199 0.25541499 0.400451 0.218311 0.35912099 - 0.27489001 0.33604199 0.25541499 0.35348001 0.188078 0.400451 0.218311 0.31703201 - 0.24954499 0.35348001 0.188078 0.33604199 0.25541499 0.35912099 0.27489001 - 0.400451 0.218311 0.47097301 0.28257099 0.400451 0.218311 0.52854401 0.261291 - 0.47097301 0.28257099 0.31351399 0.202804 0.32905 0.12617201 0.35348001 0.188078 - 0.31351399 0.202804 0.35348001 0.188078 0.31703201 0.24954499 0.128057 0.28853801 - 0.151114 0.233711 0.194934 0.29608399 0.151114 0.233711 0.19205201 0.23548099 - 0.194934 0.29608399 0.194934 0.29608399 0.26878601 0.315254 0.21787301 0.34819999 - 0.271054 0.13361099 0.32905 0.12617201 0.31351399 0.202804 0.245719 0.014829 - 0.31335899 0.057027001 0.25301799 0.068204001 0.55444598 0.474244 0.57874799 - 0.472913 0.591959 0.53098297 0.62550402 0.53194499 0.60980803 0.47876301 - 0.639902 0.47827199 0.60595697 0.51647699 0.60980803 0.47876301 0.62550402 - 0.53194499 0.86200303 0.72877699 0.88900101 0.68397403 0.92526799 0.68932003 - 0.92526799 0.68932003 0.88900101 0.68397403 0.89971602 0.66068798 0.591959 - 0.53098297 0.57874799 0.472913 0.60980803 0.47876301 0.66333002 0.35212901 - 0.63387299 0.382061 0.58532703 0.345817 0.58532703 0.345817 0.63387299 0.382061 - 0.610578 0.38000399 0.58532703 0.345817 0.610578 0.38000399 0.60697401 0.39847901 - 0.55444598 0.474244 0.60697401 0.39847901 0.57874799 0.472913 0.60595697 - 0.51647699 0.591959 0.53098297 0.60980803 0.47876301 0.86200303 0.72877699 - 0.86512601 0.68251401 0.88900101 0.68397403 0.039241001 0.118589 0.056297999 - 0.091900997 0.080518 0.123654 0.020680999 0.143217 0.039241001 0.118589 0.080518 - 0.123654 0.041522998 0.25432399 0.070349 0.165839 0.069355004 0.21782801 - 0.57874799 0.472913 0.60697401 0.39847901 0.61546803 0.418973 0.639902 0.47827199 - 0.61546803 0.418973 0.63182598 0.41617399 0.639902 0.47827199 0.63182598 - 0.41617399 0.64173597 0.390975 0.016138 0.325297 0.036951002 0.29172301 0.128057 - 0.28853801 0.016138 0.325297 0.128057 0.28853801 0.048168998 0.35214001 0.027048999 - 0.208827 0.070349 0.165839 0.041522998 0.25432399 0.027048999 0.208827 0.020680999 - 0.143217 0.070349 0.165839 0.020680999 0.143217 0.080518 0.123654 0.070349 - 0.165839 0.128057 0.28853801 0.194934 0.29608399 0.21787301 0.34819999 0.062045 - 0.057544 0.271054 0.13361099 0.056297999 0.091900997 0.056297999 0.091900997 - 0.271054 0.13361099 0.080518 0.123654 0.617971 0.407262 0.61546803 0.418973 - 0.60697401 0.39847901 0.63182598 0.41617399 0.61546803 0.418973 0.617971 - 0.407262 0.66333002 0.35212901 0.64173597 0.390975 0.63387299 0.382061 0.86200303 - 0.72877699 0.97766298 0.79651397 0.94665498 0.81503397 0.86200303 0.72877699 - 0.93663901 0.729617 0.97766298 0.79651397 0.86200303 0.72877699 0.92526799 - 0.68932003 0.93663901 0.729617 0.65543997 0.49157101 0.639902 0.47827199 - 0.665824 0.44352099 0.665824 0.44352099 0.639902 0.47827199 0.64173597 0.390975 - 0.66333002 0.35212901 0.665824 0.44352099 0.64173597 0.390975 0.55444598 - 0.474244 0.58532703 0.345817 0.60697401 0.39847901 0.32905 0.12617201 0.37215099 - 0.13412 0.35348001 0.188078 0.55324697 0.28502101 0.57477999 0.25117901 0.602754 - 0.257723 0.57477999 0.25117901 0.61704302 0.20689499 0.602754 0.257723 0.53191298 - 0.15157899 0.56468099 0.099036001 0.61118603 0.156872 0.60898602 0.28752601 - 0.602754 0.257723 0.64614099 0.22702 0.602754 0.257723 0.61704302 0.20689499 - 0.64614099 0.22702 0.61118603 0.156872 0.64614099 0.22702 0.61704302 0.20689499 - 0.56468099 0.099036001 0.63874 0.094846003 0.61118603 0.156872 0.194934 0.29608399 - 0.255613 0.25320399 0.26878601 0.315254 0.194934 0.29608399 0.216565 0.237138 - 0.255613 0.25320399 0.19205201 0.23548099 0.216565 0.237138 0.194934 0.29608399; - setAttr ".uvst[0].uvsp[3000:3249]" 0.42296299 0.00556 0.57313102 0.0095039997 - 0.53150898 0.049988002 0.60898602 0.28752601 0.64614099 0.22702 0.627464 - 0.31886399 0.47644299 0.39616501 0.47337201 0.42365801 0.53173602 0.43147901 - 0.52854401 0.261291 0.57477999 0.25117901 0.55324697 0.28502101 0.58940798 - 0.33751199 0.60898602 0.28752601 0.627464 0.31886399 0.359846 0.051763002 - 0.42296299 0.00556 0.475099 0.076341003 0.42296299 0.00556 0.53150898 0.049988002 - 0.475099 0.076341003 0.37215099 0.13412 0.475099 0.076341003 0.53191298 0.15157899 - 0.53674299 0.39848399 0.47644299 0.39616501 0.53173602 0.43147901 0.47946599 - 0.37119001 0.47644299 0.39616501 0.53674299 0.39848399 0.53191298 0.15157899 - 0.61118603 0.156872 0.61704302 0.20689499 0.22066 0.18181901 0.271054 0.13361099 - 0.31351399 0.202804 0.400451 0.218311 0.53191298 0.15157899 0.532996 0.217034 - 0.52854401 0.261291 0.532996 0.217034 0.57477999 0.25117901 0.48070699 0.35210899 - 0.53746098 0.37084499 0.54082298 0.34952399 0.529387 0.082309 0.56216699 - 0.060766999 0.56468099 0.099036001 0.53150898 0.049988002 0.56216699 0.060766999 - 0.529387 0.082309 0.475099 0.076341003 0.53150898 0.049988002 0.529387 0.082309 - 0.475099 0.076341003 0.529387 0.082309 0.53191298 0.15157899 0.529387 0.082309 - 0.56468099 0.099036001 0.53191298 0.15157899 0.532996 0.217034 0.563384 0.216162 - 0.57477999 0.25117901 0.563384 0.216162 0.61704302 0.20689499 0.57477999 - 0.25117901 0.53191298 0.15157899 0.61704302 0.20689499 0.563384 0.216162 - 0.53191298 0.15157899 0.563384 0.216162 0.532996 0.217034 0.53746098 0.37084499 - 0.47946599 0.37119001 0.53674299 0.39848399 0.48070699 0.35210899 0.47946599 - 0.37119001 0.53746098 0.37084499 0.359846 0.051763002 0.475099 0.076341003 - 0.37215099 0.13412 0.255613 0.25320399 0.258811 0.22176901 0.31703201 0.24954499 - 0.639902 0.47827199 0.60980803 0.47876301 0.61546803 0.418973 0.57874799 - 0.472913 0.61546803 0.418973 0.60980803 0.47876301 0.036951002 0.29172301 - 0.041522998 0.25432399 0.128057 0.28853801 0.102847 0.22989 0.151114 0.233711 - 0.128057 0.28853801 0.041522998 0.25432399 0.102847 0.22989 0.128057 0.28853801 - 0.041522998 0.25432399 0.069355004 0.21782801 0.102847 0.22989 0.069355004 - 0.21782801 0.107695 0.172719 0.102847 0.22989 0.069355004 0.21782801 0.070349 - 0.165839 0.107695 0.172719 0.070349 0.165839 0.080518 0.123654 0.107695 0.172719 - 0.107695 0.172719 0.155274 0.177471 0.151114 0.233711 0.102847 0.22989 0.107695 - 0.172719 0.151114 0.233711 0.080518 0.123654 0.155274 0.177471 0.107695 0.172719 - 0.080518 0.123654 0.271054 0.13361099 0.155274 0.177471 0.155274 0.177471 - 0.271054 0.13361099 0.22066 0.18181901 0.316248 0.291545 0.39272901 0.33256099 - 0.32999301 0.33045399 0.26878601 0.315254 0.316248 0.291545 0.32999301 0.33045399 - 0.36022699 0.003454 0.42296299 0.00556 0.359846 0.051763002 0.65543997 0.49157101 - 0.62550402 0.53194499 0.639902 0.47827199 0.016138 0.325297 0.0040460001 - 0.25350901 0.036951002 0.29172301 0.0040460001 0.25350901 0.027048999 0.208827 - 0.041522998 0.25432399 0.0040460001 0.25350901 0.041522998 0.25432399 0.036951002 - 0.29172301 0.039096002 0.044592999 0.056297999 0.091900997 0.039241001 0.118589 - 0.039096002 0.044592999 0.062045 0.057544 0.056297999 0.091900997 0.039096002 - 0.044592999 0.065323003 0.030218 0.062045 0.057544 0.016138 0.325297 0.048168998 - 0.35214001 0.023626 0.35801601 0.155274 0.177471 0.22066 0.18181901 0.193956 - 0.19936 0.151114 0.233711 0.155274 0.177471 0.193956 0.19936 0.151114 0.233711 - 0.193956 0.19936 0.19205201 0.23548099 0.19205201 0.23548099 0.193956 0.19936 - 0.216565 0.237138 0.193956 0.19936 0.22066 0.18181901 0.216565 0.237138 0.47337201 - 0.42365801 0.49755499 0.488251 0.53173602 0.43147901 0.47337201 0.42365801 - 0.415775 0.44801801 0.49755499 0.488251 0.61118603 0.156872 0.63806599 0.14799 - 0.64614099 0.22702 0.61118603 0.156872 0.63874 0.094846003 0.63806599 0.14799 - 0.56216699 0.060766999 0.63874 0.094846003 0.56468099 0.099036001 0.56216699 - 0.060766999 0.64656198 0.069087997 0.63874 0.094846003 0.55324697 0.28502101 - 0.602754 0.257723 0.57625401 0.29346699 0.55185699 0.34580401 0.55324697 - 0.28502101 0.57625401 0.29346699 0.55185699 0.34580401 0.57625401 0.29346699 - 0.58940798 0.33751199 0.57625401 0.29346699 0.60898602 0.28752601 0.58940798 - 0.33751199 0.57625401 0.29346699 0.602754 0.257723 0.60898602 0.28752601 - 0.34836701 0.49853599 0.35016599 0.53974301 0.44446999 0.51254302 0.415775 - 0.44801801 0.44446999 0.51254302 0.49755499 0.488251 0.415775 0.44801801 - 0.34836701 0.49853599 0.44446999 0.51254302 0.302367 0.46158099 0.235855 - 0.44651899 0.227768 0.50040001 0.245719 0.014829 0.316118 0.025185 0.31335899 - 0.057027001 0.316118 0.025185 0.359846 0.051763002 0.31335899 0.057027001 - 0.316118 0.025185 0.36022699 0.003454 0.359846 0.051763002 0.26878601 0.315254 - 0.32999301 0.33045399 0.28588501 0.35218599 0.21787301 0.34819999 0.26878601 - 0.315254 0.28588501 0.35218599 0.32905 0.12617201 0.359846 0.051763002 0.37215099 - 0.13412 0.25301799 0.068204001 0.31976199 0.096646003 0.271054 0.13361099 - 0.271054 0.13361099 0.31976199 0.096646003 0.32905 0.12617201 0.31976199 - 0.096646003 0.359846 0.051763002 0.32905 0.12617201 0.31335899 0.057027001 - 0.359846 0.051763002 0.31976199 0.096646003 0.25301799 0.068204001; - setAttr ".uvst[0].uvsp[3250:3499]" 0.31335899 0.057027001 0.31976199 - 0.096646003 0.11848 0.325919 0.128057 0.28853801 0.21787301 0.34819999 0.048168998 - 0.35214001 0.128057 0.28853801 0.11848 0.325919 0.142845 0.034219 0.245719 - 0.014829 0.25301799 0.068204001 0.062045 0.057544 0.25301799 0.068204001 - 0.271054 0.13361099 0.065323003 0.030218 0.142845 0.034219 0.062045 0.057544 - 0.062045 0.057544 0.142845 0.034219 0.25301799 0.068204001 0.216565 0.237138 - 0.258811 0.22176901 0.255613 0.25320399 0.22066 0.18181901 0.258811 0.22176901 - 0.216565 0.237138 0.22066 0.18181901 0.31351399 0.202804 0.258811 0.22176901 - 0.89018202 0.239971 0.84087598 0.31692401 0.86741501 0.373849 0.79613203 - 0.35278401 0.82062 0.34356001 0.84594899 0.227217 0.89018202 0.239971 0.84594899 - 0.227217 0.84087598 0.31692401 0.84594899 0.227217 0.82062 0.34356001 0.84087598 - 0.31692401 0.89836198 0.137126 0.84594899 0.227217 0.89018202 0.239971 0.79613203 - 0.35278401 0.814367 0.424068 0.82062 0.34356001 0.86741501 0.373849 0.84087598 - 0.31692401 0.82062 0.34356001 0.86741501 0.373849 0.814367 0.424068 0.88974899 - 0.43314499 0.814367 0.424068 0.82335901 0.49983799 0.88974899 0.43314499 - 0.76275897 0.37884799 0.814367 0.424068 0.79613203 0.35278401 0.86741501 - 0.373849 0.82062 0.34356001 0.814367 0.424068 0.814367 0.424068 0.773857 - 0.53407699 0.82335901 0.49983799 0.73045999 0.53145701 0.773857 0.53407699 - 0.779073 0.44323799 0.779073 0.44323799 0.773857 0.53407699 0.814367 0.424068 - 0.89836198 0.137126 0.83935702 0.100765 0.84594899 0.227217 0.83935702 0.100765 - 0.79802299 0.211936 0.84594899 0.227217 0.79613203 0.35278401 0.84594899 - 0.227217 0.79802299 0.211936 0.89836198 0.137126 0.87032902 0.045508999 0.83935702 - 0.100765 0.83545703 0.043729 0.83935702 0.100765 0.87032902 0.045508999 0.818169 - 0.062284999 0.83935702 0.100765 0.83545703 0.043729 0.95396501 0.134362 0.89018202 - 0.239971 0.966021 0.28052899 0.966021 0.28052899 0.89018202 0.239971 0.89975703 - 0.32890701 0.89975703 0.32890701 0.89018202 0.239971 0.86741501 0.373849 - 0.76275897 0.37884799 0.79613203 0.35278401 0.79802299 0.211936 0.76275897 - 0.37884799 0.779073 0.44323799 0.814367 0.424068 0.76275897 0.37884799 0.74679601 - 0.45871499 0.779073 0.44323799 0.733105 0.37849101 0.74679601 0.45871499 - 0.76275897 0.37884799 0.71095902 0.44087201 0.68089098 0.41862199 0.70178902 - 0.52030098 0.71095902 0.44087201 0.70178902 0.52030098 0.74679601 0.45871499 - 0.70178902 0.52030098 0.73045999 0.53145701 0.74679601 0.45871499 0.74679601 - 0.45871499 0.73045999 0.53145701 0.779073 0.44323799 0.733105 0.37849101 - 0.71095902 0.44087201 0.74679601 0.45871499 0.97778797 0.040635999 0.89836198 - 0.137126 0.95396501 0.134362 0.97778797 0.040635999 0.94019401 0.031078 0.89836198 - 0.137126 0.99264401 0.396844 0.966021 0.28052899 0.89975703 0.32890701 0.99426401 - 0.26670301 0.966021 0.28052899 0.99264401 0.396844 0.65865201 0.27080399 - 0.68089098 0.41862199 0.71095902 0.44087201 0.70381802 0.225641 0.65865201 - 0.27080399 0.71095902 0.44087201 0.70381802 0.225641 0.64760703 0.20985 0.65865201 - 0.27080399 0.98321998 0.20574901 0.95396501 0.134362 0.966021 0.28052899 - 0.98321998 0.20574901 0.966021 0.28052899 0.99426401 0.26670301 0.95396501 - 0.134362 0.89836198 0.137126 0.89018202 0.239971 0.70381802 0.225641 0.66965002 - 0.116933 0.64760703 0.20985 0.70381802 0.225641 0.719881 0.006691 0.66965002 - 0.116933 0.719881 0.006691 0.66478199 0.0078290002 0.66965002 0.116933 0.70381802 - 0.225641 0.733105 0.37849101 0.73960102 0.22293501 0.70381802 0.225641 0.71095902 - 0.44087201 0.733105 0.37849101 0.73960102 0.22293501 0.733105 0.37849101 - 0.76275897 0.37884799 0.76523697 0.19111399 0.76275897 0.37884799 0.79802299 - 0.211936 0.73960102 0.22293501 0.76275897 0.37884799 0.76523697 0.19111399 - 0.719881 0.006691 0.73960102 0.22293501 0.75811899 0.0040250001 0.818169 - 0.062284999 0.79802299 0.211936 0.83935702 0.100765 0.76523697 0.19111399 - 0.79802299 0.211936 0.818169 0.062284999 0.70381802 0.225641 0.73960102 0.22293501 - 0.719881 0.006691 0.73960102 0.22293501 0.76523697 0.19111399 0.75811899 - 0.0040250001 0.95050299 0.82310897 0.98507398 0.893085 0.94037199 0.870426 - 0.95050299 0.82310897 0.99505001 0.82360703 0.98507398 0.893085 0.909796 - 0.8951 0.90755701 0.964562 0.86997002 0.93731803 0.98405302 0.91405201 0.90755701 - 0.964562 0.94326001 0.89290702 0.94326001 0.89290702 0.90755701 0.964562 - 0.909796 0.8951 0.86997002 0.93731803 0.90755701 0.964562 0.85467398 0.99159998 - 0.98507398 0.893085 0.98405302 0.91405201 0.94037199 0.870426 0.94037199 - 0.870426 0.98405302 0.91405201 0.94326001 0.89290702 0.94037199 0.870426 - 0.94326001 0.89290702 0.909796 0.8951 0.91257 0.81947201 0.95050299 0.82310897 - 0.94037199 0.870426 0.91257 0.81947201 0.94037199 0.870426 0.909796 0.8951 - 0.84964103 0.74003702 0.91257 0.81947201 0.909796 0.8951 0.84964103 0.74003702 - 0.909796 0.8951 0.86997002 0.93731803 0.63363802 0.89377397 0.66562402 0.92713302 - 0.68109202 0.85573 0.804057 0.01567 0.818169 0.062284999 0.83545703 0.043729 - 0.78658998 0.052133001 0.818169 0.062284999 0.804057 0.01567 0.86865902 0.013712 - 0.87032902 0.045508999 0.90803403 0.044094998 0.94019401 0.031078 0.86865902 - 0.013712 0.90803403 0.044094998 0.86865902 0.013712 0.83545703 0.043729; - setAttr ".uvst[0].uvsp[3500:3749]" 0.87032902 0.045508999 0.804057 0.01567 - 0.83545703 0.043729 0.86865902 0.013712 0.75811899 0.0040250001 0.78658998 - 0.052133001 0.804057 0.01567 0.32756099 0.89249802 0.33735099 0.85548198 - 0.33477801 0.909235 0.33477801 0.909235 0.33735099 0.85548198 0.34354001 - 0.86769497 0.35936901 0.91262299 0.34659299 0.92080897 0.371288 0.86448097 - 0.34659299 0.92080897 0.359723 0.87225002 0.371288 0.86448097 0.33477801 - 0.909235 0.359723 0.87225002 0.34659299 0.92080897 0.33477801 0.909235 0.34354001 - 0.86769497 0.359723 0.87225002 0.48538801 0.95112503 0.44578099 0.93405002 - 0.45333701 0.95817798 0.48538801 0.95112503 0.48168799 0.91676801 0.44578099 - 0.93405002 0.45333701 0.95817798 0.42452699 0.94267398 0.43036199 0.96655297 - 0.45333701 0.95817798 0.44578099 0.93405002 0.42452699 0.94267398 0.33735099 - 0.85548198 0.352687 0.831747 0.34354001 0.86769497 0.33735099 0.85548198 - 0.34862399 0.80891901 0.352687 0.831747 0.34354001 0.86769497 0.368599 0.83635598 - 0.359723 0.87225002 0.34354001 0.86769497 0.352687 0.831747 0.368599 0.83635598 - 0.371288 0.86448097 0.368599 0.83635598 0.38256299 0.81765997 0.371288 0.86448097 - 0.359723 0.87225002 0.368599 0.83635598 0.39850101 0.96660697 0.43036199 - 0.96655297 0.42452699 0.94267398 0.37021199 0.79415601 0.35968399 0.81033999 - 0.34862399 0.80891901 0.34862399 0.80891901 0.35968399 0.81033999 0.352687 - 0.831747 0.35968399 0.81033999 0.368599 0.83635598 0.352687 0.831747 0.35968399 - 0.81033999 0.37179601 0.81299299 0.368599 0.83635598 0.37021199 0.79415601 - 0.38256299 0.81765997 0.37179601 0.81299299 0.38256299 0.81765997 0.368599 - 0.83635598 0.37179601 0.81299299 0.37021199 0.79415601 0.37179601 0.81299299 - 0.35968399 0.81033999 0.29274601 0.90635097 0.308972 0.86521697 0.30324501 - 0.90815997 0.29274601 0.90635097 0.300255 0.86195898 0.308972 0.86521697 - 0.32756099 0.89249802 0.32226399 0.867616 0.33101901 0.87009001 0.32756099 - 0.89249802 0.31726399 0.91030401 0.32226399 0.867616 0.30324501 0.90815997 - 0.32226399 0.867616 0.31726399 0.91030401 0.30324501 0.90815997 0.308972 - 0.86521697 0.32226399 0.867616 0.49160999 0.97508597 0.46022999 0.96179903 - 0.46529901 0.98378903 0.49160999 0.97508597 0.48538801 0.95112503 0.46022999 - 0.96179903 0.46529901 0.98378903 0.43152601 0.97203702 0.43633199 0.99328399 - 0.46529901 0.98378903 0.46022999 0.96179903 0.43152601 0.97203702 0.300255 - 0.86195898 0.307354 0.82550597 0.308972 0.86521697 0.307354 0.82550597 0.31612 - 0.82580698 0.308972 0.86521697 0.308972 0.86521697 0.329963 0.82830203 0.32226399 - 0.867616 0.308972 0.86521697 0.31612 0.82580698 0.329963 0.82830203 0.33101901 - 0.87009001 0.32226399 0.867616 0.33719999 0.843934 0.33719999 0.843934 0.32226399 - 0.867616 0.329963 0.82830203 0.43633199 0.99328399 0.43152601 0.97203702 - 0.405705 0.98896497 0.32305399 0.80920303 0.329963 0.82830203 0.31612 0.82580698 - 0.32305399 0.80920303 0.33029699 0.81221998 0.329963 0.82830203 0.33178499 - 0.78945303 0.33029699 0.81221998 0.32305399 0.80920303 0.39264601 0.86977398 - 0.38630301 0.87709397 0.38328499 0.85446298 0.38328499 0.85446298 0.38630301 - 0.87709397 0.380456 0.87159598 0.38630301 0.87709397 0.376625 0.895226 0.380456 - 0.87159598 0.38593799 0.83733201 0.39264601 0.86977398 0.38328499 0.85446298 - 0.39264601 0.86977398 0.38863 0.90287602 0.38630301 0.87709397 0.38593799 - 0.83733201 0.40770999 0.866552 0.39264601 0.86977398 0.42723399 0.92242002 - 0.44178799 0.92605698 0.43939599 0.911412 0.38593799 0.83733201 0.38328499 - 0.85446298 0.37287301 0.875799 0.40770999 0.866552 0.38863 0.90287602 0.39264601 - 0.86977398 0.36799499 0.89132202 0.376625 0.895226 0.36011499 0.92878401 - 0.35936901 0.91262299 0.36799499 0.89132202 0.36011499 0.92878401 0.36799499 - 0.89132202 0.37287301 0.875799 0.380456 0.87159598 0.36799499 0.89132202 - 0.380456 0.87159598 0.376625 0.895226 0.38328499 0.85446298 0.380456 0.87159598 - 0.37287301 0.875799 0.35936901 0.91262299 0.36011499 0.92878401 0.34659299 - 0.92080897 0.32756099 0.89249802 0.33477801 0.909235 0.31726399 0.91030401 - 0.41693899 0.89492601 0.40901801 0.89674503 0.40770999 0.866552 0.381246 - 0.95752001 0.38863 0.90287602 0.39948201 0.920587 0.381246 0.95752001 0.36011499 - 0.92878401 0.376625 0.895226 0.381246 0.95752001 0.376625 0.895226 0.38863 - 0.90287602 0.38863 0.90287602 0.376625 0.895226 0.38630301 0.87709397 0.381246 - 0.95752001 0.33891901 0.987975 0.36011499 0.92878401 0.34659299 0.92080897 - 0.36011499 0.92878401 0.32005399 0.97494799 0.33891901 0.987975 0.32005399 - 0.97494799 0.36011499 0.92878401 0.33477801 0.909235 0.34659299 0.92080897 - 0.32005399 0.97494799 0.30324501 0.90815997 0.31726399 0.91030401 0.300001 - 0.97013903 0.28796199 0.92390901 0.29274601 0.90635097 0.30324501 0.90815997 - 0.28796199 0.92390901 0.30324501 0.90815997 0.290243 0.940907 0.27395099 - 0.912489 0.28796199 0.92390901 0.270601 0.92593902 0.270601 0.92593902 0.28796199 - 0.92390901 0.290243 0.940907 0.258212 0.91232401 0.27395099 0.912489 0.270601 - 0.92593902 0.258212 0.91232401 0.270601 0.92593902 0.25671601 0.927858 0.290243 - 0.940907 0.30324501 0.90815997 0.300001 0.97013903 0.290243 0.940907 0.300001 - 0.97013903 0.283005 0.96905398 0.270601 0.92593902 0.290243 0.940907 0.283005 - 0.96905398 0.25671601 0.927858 0.270601 0.92593902 0.283005 0.96905398 0.369001 - 0.99685502 0.35122901 1.000869 0.381246 0.95752001; - setAttr ".uvst[0].uvsp[3750:3999]" 0.35122901 1.000869 0.33891901 0.987975 - 0.381246 0.95752001 0.25671601 0.927858 0.283005 0.96905398 0.25706601 0.969437 - 0.53719902 0.90499997 0.54497999 0.877047 0.53121799 0.86490297 0.56407797 - 0.91909999 0.54497999 0.877047 0.53719902 0.90499997 0.53666401 0.96573699 - 0.54059702 0.94349098 0.52387398 0.97127301 0.54059702 0.94349098 0.521644 - 0.96135998 0.52387398 0.97127301 0.54084498 0.98507202 0.55496401 0.97537702 - 0.53666401 0.96573699 0.53666401 0.96573699 0.55496401 0.97537702 0.54059702 - 0.94349098 0.262528 0.89503402 0.27759501 0.89841598 0.258212 0.91232401 - 0.27759501 0.89841598 0.27395099 0.912489 0.258212 0.91232401 0.27759501 - 0.89841598 0.291614 0.896658 0.27395099 0.912489 0.27395099 0.912489 0.291614 - 0.896658 0.28940701 0.91069198 0.52629602 0.99024498 0.52387398 0.97127301 - 0.51558298 0.98070103 0.52629602 0.99024498 0.53666401 0.96573699 0.52387398 - 0.97127301 0.52678698 0.99600202 0.54084498 0.98507202 0.52629602 0.99024498 - 0.54084498 0.98507202 0.53666401 0.96573699 0.52629602 0.99024498 0.26901299 - 0.87969601 0.27759501 0.89841598 0.262528 0.89503402 0.26901299 0.87969601 - 0.282882 0.883295 0.27759501 0.89841598 0.282882 0.883295 0.29319 0.88515502 - 0.27759501 0.89841598 0.27759501 0.89841598 0.29319 0.88515502 0.291614 0.896658 - 0.52678698 0.99600202 0.52629602 0.99024498 0.50723398 0.99519998 0.26901299 - 0.87969601 0.28712299 0.87004602 0.282882 0.883295 0.282882 0.883295 0.28712299 - 0.87004602 0.29319 0.88515502 0.52629602 0.99024498 0.51558298 0.98070103 - 0.50723398 0.99519998 0.27395099 0.912489 0.28940701 0.91069198 0.28796199 - 0.92390901 0.54059702 0.94349098 0.56407797 0.91909999 0.53719902 0.90499997 - 0.56377 0.96770799 0.56407797 0.91909999 0.54059702 0.94349098 0.55496401 - 0.97537702 0.56377 0.96770799 0.54059702 0.94349098 0.45547101 0.90422702 - 0.44178799 0.92605698 0.45468801 0.92364502 0.43939599 0.911412 0.44178799 - 0.92605698 0.45547101 0.90422702 0.41693899 0.89492601 0.40770999 0.866552 - 0.41640201 0.88049698 0.40770999 0.866552 0.39948201 0.920587 0.38863 0.90287602 - 0.40901801 0.89674503 0.39948201 0.920587 0.40770999 0.866552 0.41693899 - 0.89492601 0.41201699 0.92887998 0.40901801 0.89674503 0.41201699 0.92887998 - 0.39948201 0.920587 0.40901801 0.89674503 0.44038501 0.90504903 0.45547101 - 0.90422702 0.46091801 0.88338 0.41201699 0.92887998 0.381246 0.95752001 0.39948201 - 0.920587 0.39207101 0.96583498 0.381246 0.95752001 0.41201699 0.92887998 - 0.48168799 0.91676801 0.45547101 0.90422702 0.45468801 0.92364502 0.496647 - 0.874951 0.45547101 0.90422702 0.48168799 0.91676801 0.496647 0.874951 0.46091801 - 0.88338 0.45547101 0.90422702 0.496647 0.874951 0.48168799 0.91676801 0.49597099 - 0.91574198 0.50320703 0.95512199 0.48538801 0.95112503 0.49160999 0.97508597 - 0.50320703 0.95512199 0.49597099 0.91574198 0.48538801 0.95112503 0.49597099 - 0.91574198 0.48168799 0.91676801 0.48538801 0.95112503 0.521644 0.96135998 - 0.50320703 0.95512199 0.51486897 0.97433299 0.51486897 0.97433299 0.50320703 - 0.95512199 0.49160999 0.97508597 0.53719902 0.90499997 0.496647 0.874951 - 0.49597099 0.91574198 0.54059702 0.94349098 0.53719902 0.90499997 0.521644 - 0.96135998 0.53719902 0.90499997 0.49597099 0.91574198 0.50320703 0.95512199 - 0.521644 0.96135998 0.53719902 0.90499997 0.50320703 0.95512199 0.369001 - 0.99685502 0.381246 0.95752001 0.39207101 0.96583498 0.53719902 0.90499997 - 0.53121799 0.86490297 0.496647 0.874951 0.89836198 0.137126 0.90803403 0.044094998 - 0.87032902 0.045508999 0.94019401 0.031078 0.90803403 0.044094998 0.89836198 - 0.137126 0.75811899 0.0040250001 0.76523697 0.19111399 0.78658998 0.052133001 - 0.76523697 0.19111399 0.818169 0.062284999 0.78658998 0.052133001 0.307354 - 0.82550597 0.32305399 0.80920303 0.31612 0.82580698 0.307354 0.82550597 0.33178499 - 0.78945303 0.32305399 0.80920303 0.33178499 0.78945303 0.33719999 0.843934 - 0.33029699 0.81221998 0.33719999 0.843934 0.329963 0.82830203 0.33029699 - 0.81221998 0.77899301 0.67823797 0.78915399 0.74251801 0.74377102 0.72034299 - 0.77899301 0.67823797 0.84964103 0.74003702 0.78915399 0.74251801 0.78915399 - 0.74251801 0.84964103 0.74003702 0.82964599 0.80204397 0.71901399 0.78532398 - 0.694462 0.78577 0.69465202 0.75267702 0.71901399 0.78532398 0.718126 0.82873601 - 0.694462 0.78577 0.694462 0.78577 0.66842598 0.82617402 0.68843299 0.845505 - 0.694462 0.78577 0.718126 0.82873601 0.66842598 0.82617402 0.718126 0.82873601 - 0.68843299 0.845505 0.66842598 0.82617402 0.31726399 0.91030401 0.32005399 - 0.97494799 0.300001 0.97013903 0.31726399 0.91030401 0.33477801 0.909235 - 0.32005399 0.97494799 0.44672099 0.742163 0.39220601 0.76434302 0.38921699 - 0.788423 0.44672099 0.742163 0.38921699 0.788423 0.40665799 0.802068 0.476217 - 0.727027 0.44672099 0.742163 0.40665799 0.802068 0.63363802 0.89377397 0.62646401 - 0.95210898 0.66562402 0.92713302 0.62646401 0.95210898 0.65396702 0.95580101 - 0.66562402 0.92713302 0.71984899 0.75139397 0.71901399 0.78532398 0.69465202 - 0.75267702 0.75477803 0.76254302 0.75086302 0.78398401 0.71901399 0.78532398 - 0.71984899 0.75139397 0.75477803 0.76254302 0.71901399 0.78532398 0.62701303 - 0.95989603 0.65045398 0.98993599 0.62603098 0.97777802 0.62701303 0.95989603 - 0.653786 0.972588 0.65045398 0.98993599 0.71176398 0.71938401 0.72957599 - 0.74754602 0.69725502 0.74743497 0.71176398 0.71938401 0.74377102 0.72034299 - 0.72957599 0.74754602 0.74377102 0.72034299; - setAttr ".uvst[0].uvsp[4000:4037]" 0.78915399 0.74251801 0.72957599 - 0.74754602 0.72957599 0.74754602 0.78915399 0.74251801 0.76598603 0.762146 - 0.96395802 0.96951902 0.97251898 0.99150902 0.95559901 0.985829 0.96395802 - 0.96951902 0.982153 0.97301102 0.97251898 0.99150902 0.70140499 0.66365999 - 0.64994597 0.70058 0.65568203 0.65436798 0.70140499 0.66365999 0.69391102 - 0.70558798 0.64994597 0.70058 0.69391102 0.70558798 0.60770202 0.71877599 - 0.64994597 0.70058 0.69391102 0.70558798 0.658795 0.73315901 0.60770202 0.71877599 - 0.68494898 0.62769097 0.70140499 0.66365999 0.62879598 0.619084 0.62879598 - 0.619084 0.70140499 0.66365999 0.65568203 0.65436798 0.62879598 0.619084 - 0.65568203 0.65436798 0.60452098 0.662067 0.65568203 0.65436798 0.64994597 - 0.70058 0.60452098 0.662067 0.60452098 0.662067 0.64994597 0.70058 0.60770202 - 0.71877599; -select -ne IMP_ALL; -select -ne IMP_Rheel; - setAttr ".ra" -type "double3" 8.0771048182479674 91.626190194129521 8.4982430504044686 ; - setAttr ".jo" -type "double3" 0.56142425049352584 178.39242262433305 0.26792333555135794 ; -select -ne IMP_Rball; - setAttr ".t" -type "double3" 6.7758528420198658 -6.9388939039072284e-018 - -9.5120444723942321e-016 ; - setAttr ".r" -type "double3" -17.499757121316115 3.2695897469829736 -6.9162979482121418 ; - setAttr ".ra" -type "double3" 75.15505722745597 44.975001823209389 -104.89557108565613 ; - setAttr ".jo" -type "double3" 22.285837002752004 85.112297318923211 -159.67399459418885 ; -select -ne IMP_Lheel; - setAttr ".ra" -type "double3" 0 82.683543935018022 0 ; - setAttr ".jo" -type "double3" -179.84826270468696 -7.3164306857494816 179.98067635537532 ; -select -ne IMP_Lball; - setAttr ".t" -type "double3" 6.7758528420198658 -6.9388939039072284e-018 - -9.5120444723942321e-016 ; - setAttr ".r" -type "double3" -2.1064832569487142 0.36693656610454173 12.728045273286209 ; - setAttr ".ra" -type "double3" 77.404646653607244 36.382368691442373 -95.067813298800402 ; - setAttr ".jo" -type "double3" -30.525776215277158 81.020972351586465 148.95001766862941 ; -select -ne IMP_Luparm; - setAttr ".ra" -type "double3" -11.437238585050391 -11.941943939060382 117.24730045727162 ; - setAttr ".jo" -type "double3" -15.785781243419427 4.7861978473761679 -116.71102541645624 ; -select -ne IMP_Lloarm; - setAttr ".jo" -type "double3" 21.45687065981625 -0.84960941397895839 -104.67746165097874 ; -select -ne IMP_Lhand; - setAttr ".t" -type "double3" 12.890532588149956 -0.69008032694306476 4.645694319339265 ; - setAttr ".ra" -type "double3" 0 -61.314289729914059 -21.566133250925443 ; - setAttr ".jo" -type "double3" 33.892693033620276 54.671688625550239 39.468648652835569 ; -select -ne IMP_Ruparm; - setAttr ".ra" -type "double3" -107.04228045598703 -31.366818039908122 -96.774301453703899 ; - setAttr ".jo" -type "double3" -133.43908848583581 -68.657118565182259 -106.065755601448 ; -select -ne IMP_Rloarm; - setAttr ".ra" -type "double3" 23.420603912954633 -17.193363603305649 -100.41349077522109 ; - setAttr ".jo" -type "double3" 21.120834032786437 19.992889592632832 100.58808566452501 ; -select -ne IMP_Rhand; - setAttr ".t" -type "double3" -12.890500000000031 -0.6900999999992341 4.6456900000000347 ; - setAttr ".ra" -type "double3" 24.480452771218506 39.049361241549072 18.980653114611655 ; - setAttr ".jo" -type "double3" -13.981558378643408 -66.654599961471263 -11.65333412837221 ; -select -ne IMP_originShape; - setAttr ".uvst[0].uvsn" -type "string" "map1"; - setAttr -s 14 ".uvst[0].uvsp[0:13]" -type "float2" 0 0 1 0 - 0 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 2 0 2 1 -1 0 -1 1; -select -ne IMP_motionPath1; -select -ne IMP_motionPath2; -disconnectAttr "IMP_origin_pointConstraint1.ctx" "IMP_origin.tx"; -disconnectAttr "IMP_origin_pointConstraint1.ctz" "IMP_origin.tz"; -connectAttr "IMP_LHAND_ROT_IK.o" "IMP_LHAND_ROT.IK"; -connectAttr "IMP_LHAND_ROT_FIST.o" "IMP_LHAND_ROT.FIST"; -connectAttr "IMP_LHAND_ROT_NEUTRAL.o" "IMP_LHAND_ROT.NEUTRAL"; -connectAttr "IMP_LHAND_ROT_SPREAD.o" "IMP_LHAND_ROT.SPREAD"; -connectAttr "IMP_LHAND_ROT_FLAT.o" "IMP_LHAND_ROT.FLAT"; -connectAttr "IMP_LHAND_ROT_PIVOT.o" "IMP_LHAND_ROT.PIVOT"; -connectAttr "IMP_LHAND_ROT_rotateX.o" "IMP_LHAND_ROT.rx"; -connectAttr "IMP_LHAND_ROT_rotateY.o" "IMP_LHAND_ROT.ry"; -connectAttr "IMP_LHAND_ROT_rotateZ.o" "IMP_LHAND_ROT.rz"; -connectAttr "IMP_LHAND_ROT_visibility.o" "IMP_LHAND_ROT.v"; -connectAttr "IMP_LHAND_ROT_translateX.o" "IMP_LHAND_ROT.tx"; -connectAttr "IMP_LHAND_ROT_translateY.o" "IMP_LHAND_ROT.ty"; -connectAttr "IMP_LHAND_ROT_translateZ.o" "IMP_LHAND_ROT.tz"; -connectAttr "IMP_LHAND_ROT_scaleX.o" "IMP_LHAND_ROT.sx"; -connectAttr "IMP_LHAND_ROT_scaleY.o" "IMP_LHAND_ROT.sy"; -connectAttr "IMP_LHAND_ROT_scaleZ.o" "IMP_LHAND_ROT.sz"; -connectAttr "IMP_RHAND_ROT_IK.o" "IMP_RHAND_ROT.IK"; -connectAttr "IMP_RHAND_ROT_FIST.o" "IMP_RHAND_ROT.Fist"; -connectAttr "IMP_RHAND_ROT_NEUTRAL.o" "IMP_RHAND_ROT.NEUTRAL"; -connectAttr "IMP_RHAND_ROT_SPREAD.o" "IMP_RHAND_ROT.SPREAD"; -connectAttr "IMP_RHAND_ROT_FLAT.o" "IMP_RHAND_ROT.Flat"; -connectAttr "IMP_RHAND_ROT_PIVOT.o" "IMP_RHAND_ROT.PIVOT"; -connectAttr "IMP_RHAND_ROT_rotateX.o" "IMP_RHAND_ROT.rx"; -connectAttr "IMP_RHAND_ROT_rotateY.o" "IMP_RHAND_ROT.ry"; -connectAttr "IMP_RHAND_ROT_rotateZ.o" "IMP_RHAND_ROT.rz"; -connectAttr "IMP_RHAND_ROT_visibility.o" "IMP_RHAND_ROT.v"; -connectAttr "IMP_RHAND_ROT_translateX.o" "IMP_RHAND_ROT.tx"; -connectAttr "IMP_RHAND_ROT_translateY.o" "IMP_RHAND_ROT.ty"; -connectAttr "IMP_RHAND_ROT_translateZ.o" "IMP_RHAND_ROT.tz"; -connectAttr "IMP_RHAND_ROT_scaleX.o" "IMP_RHAND_ROT.sx"; -connectAttr "IMP_RHAND_ROT_scaleY.o" "IMP_RHAND_ROT.sy"; -connectAttr "IMP_RHAND_ROT_scaleZ.o" "IMP_RHAND_ROT.sz"; -connectAttr "IMP_Rmissile_rotateX.o" "IMP_Rmissile.rx"; -connectAttr "IMP_Rmissile_rotateY.o" "IMP_Rmissile.ry"; -connectAttr "IMP_Rmissile_rotateZ.o" "IMP_Rmissile.rz"; -connectAttr "IMP_Rmissile_translateX.o" "IMP_Rmissile.tx"; -connectAttr "IMP_Rmissile_translateY.o" "IMP_Rmissile.ty"; -connectAttr "IMP_Rmissile_translateZ.o" "IMP_Rmissile.tz"; -connectAttr "IMP_Rmissile_visibility.o" "IMP_Rmissile.v"; -connectAttr "IMP_Rmissile_scaleX.o" "IMP_Rmissile.sx"; -connectAttr "IMP_Rmissile_scaleY.o" "IMP_Rmissile.sy"; -connectAttr "IMP_Rmissile_scaleZ.o" "IMP_Rmissile.sz"; -connectAttr "IMP_ALL_rotateY.o" "IMP_ALL.ry"; -connectAttr "IMP_ALL_rotateX.o" "IMP_ALL.rx"; -connectAttr "IMP_ALL_rotateZ.o" "IMP_ALL.rz"; -connectAttr "IMP_ALL_visibility.o" "IMP_ALL.v"; -connectAttr "IMP_ALL_translateX.o" "IMP_ALL.tx"; -connectAttr "IMP_ALL_translateY.o" "IMP_ALL.ty"; -connectAttr "IMP_ALL_translateZ.o" "IMP_ALL.tz"; -connectAttr "IMP_ALL_scaleX.o" "IMP_ALL.sx"; -connectAttr "IMP_ALL_scaleY.o" "IMP_ALL.sy"; -connectAttr "IMP_ALL_scaleZ.o" "IMP_ALL.sz"; -connectAttr "IMP_Rheel_scaleX.o" "IMP_Rheel.sx"; -connectAttr "IMP_Rheel_scaleY.o" "IMP_Rheel.sy"; -connectAttr "IMP_Rheel_scaleZ.o" "IMP_Rheel.sz"; -connectAttr "IMP_Rheel_rotateY.o" "IMP_Rheel.ry"; -connectAttr "IMP_Rheel_rotateX.o" "IMP_Rheel.rx"; -connectAttr "IMP_Rheel_rotateZ.o" "IMP_Rheel.rz"; -connectAttr "IMP_Rheel_translateX.o" "IMP_Rheel.tx"; -connectAttr "IMP_Rheel_translateY.o" "IMP_Rheel.ty"; -connectAttr "IMP_Rheel_translateZ.o" "IMP_Rheel.tz"; -connectAttr "IMP_Rheel_visibility.o" "IMP_Rheel.v"; -connectAttr "IMP_Lheel_scaleX.o" "IMP_Lheel.sx"; -connectAttr "IMP_Lheel_scaleY.o" "IMP_Lheel.sy"; -connectAttr "IMP_Lheel_scaleZ.o" "IMP_Lheel.sz"; -connectAttr "IMP_Lheel_rotateY.o" "IMP_Lheel.ry"; -connectAttr "IMP_Lheel_rotateX.o" "IMP_Lheel.rx"; -connectAttr "IMP_Lheel_rotateZ.o" "IMP_Lheel.rz"; -connectAttr "IMP_Lheel_translateX.o" "IMP_Lheel.tx"; -connectAttr "IMP_Lheel_translateY.o" "IMP_Lheel.ty"; -connectAttr "IMP_Lheel_translateZ.o" "IMP_Lheel.tz"; -connectAttr "IMP_Lheel_visibility.o" "IMP_Lheel.v"; -connectAttr "IMP_Body_translateY.o" "IMP_Body.ty"; -connectAttr "IMP_Body_translateZ.o" "IMP_Body.tz"; -connectAttr "IMP_Body_translateX.o" "IMP_Body.tx"; -connectAttr "IMP_Body_visibility.o" "IMP_Body.v"; -connectAttr "IMP_Body_scaleX.o" "IMP_Body.sx"; -connectAttr "IMP_Body_scaleY.o" "IMP_Body.sy"; -connectAttr "IMP_Body_scaleZ.o" "IMP_Body.sz"; -connectAttr "IMP_Body_rotateX.o" "IMP_Body.rx"; -connectAttr "IMP_Body_rotateY.o" "IMP_Body.ry"; -connectAttr "IMP_Body_rotateZ.o" "IMP_Body.rz"; -connectAttr "IMP_Body2_visibility.o" "IMP_Body2.v"; -connectAttr "IMP_Body2_translateX.o" "IMP_Body2.tx"; -connectAttr "IMP_Body2_translateY.o" "IMP_Body2.ty"; -connectAttr "IMP_Body2_translateZ.o" "IMP_Body2.tz"; -connectAttr "IMP_Body2_rotateX.o" "IMP_Body2.rx"; -connectAttr "IMP_Body2_rotateY.o" "IMP_Body2.ry"; -connectAttr "IMP_Body2_rotateZ.o" "IMP_Body2.rz"; -connectAttr "IMP_Body2_scaleX.o" "IMP_Body2.sx"; -connectAttr "IMP_Body2_scaleY.o" "IMP_Body2.sy"; -connectAttr "IMP_Body2_scaleZ.o" "IMP_Body2.sz"; -connectAttr "IMP_Waist_scaleX.o" "IMP_Waist.sx"; -connectAttr "IMP_Waist_scaleY.o" "IMP_Waist.sy"; -connectAttr "IMP_Waist_scaleZ.o" "IMP_Waist.sz"; -connectAttr "IMP_Waist_translateY.o" "IMP_Waist.ty"; -connectAttr "IMP_Waist_translateZ.o" "IMP_Waist.tz"; -connectAttr "IMP_Waist_translateX.o" "IMP_Waist.tx"; -connectAttr "IMP_Waist_rotateZ.o" "IMP_Waist.rz"; -connectAttr "IMP_Waist_rotateX.o" "IMP_Waist.rx"; -connectAttr "IMP_Waist_rotateY.o" "IMP_Waist.ry"; -connectAttr "IMP_Waist_visibility.o" "IMP_Waist.v"; -connectAttr "IMP_Chest_scaleX.o" "IMP_Chest.sx"; -connectAttr "IMP_Chest_scaleY.o" "IMP_Chest.sy"; -connectAttr "IMP_Chest_scaleZ.o" "IMP_Chest.sz"; -connectAttr "IMP_Chest_rotateX.o" "IMP_Chest.rx"; -connectAttr "IMP_Chest_rotateZ.o" "IMP_Chest.rz"; -connectAttr "IMP_Chest_rotateY.o" "IMP_Chest.ry"; -connectAttr "IMP_Chest_translateY.o" "IMP_Chest.ty"; -connectAttr "IMP_Chest_translateZ.o" "IMP_Chest.tz"; -connectAttr "IMP_Chest_translateX.o" "IMP_Chest.tx"; -connectAttr "IMP_Chest_visibility.o" "IMP_Chest.v"; -connectAttr "IMP_Neck_scaleX.o" "IMP_Neck.sx"; -connectAttr "IMP_Neck_scaleY.o" "IMP_Neck.sy"; -connectAttr "IMP_Neck_scaleZ.o" "IMP_Neck.sz"; -connectAttr "IMP_Neck_translateY.o" "IMP_Neck.ty"; -connectAttr "IMP_Neck_translateZ.o" "IMP_Neck.tz"; -connectAttr "IMP_Neck_translateX.o" "IMP_Neck.tx"; -connectAttr "IMP_Neck_rotateZ.o" "IMP_Neck.rz"; -connectAttr "IMP_Neck_rotateY.o" "IMP_Neck.ry"; -connectAttr "IMP_Neck_rotateX.o" "IMP_Neck.rx"; -connectAttr "IMP_Neck_visibility.o" "IMP_Neck.v"; -connectAttr "IMP_Head_scaleX.o" "IMP_Head.sx"; -connectAttr "IMP_Head_scaleY.o" "IMP_Head.sy"; -connectAttr "IMP_Head_scaleZ.o" "IMP_Head.sz"; -connectAttr "IMP_Head_translateY.o" "IMP_Head.ty"; -connectAttr "IMP_Head_translateZ.o" "IMP_Head.tz"; -connectAttr "IMP_Head_translateX.o" "IMP_Head.tx"; -connectAttr "IMP_Head_rotateZ.o" "IMP_Head.rz"; -connectAttr "IMP_Head_rotateY.o" "IMP_Head.ry"; -connectAttr "IMP_Head_rotateX.o" "IMP_Head.rx"; -connectAttr "IMP_Head_visibility.o" "IMP_Head.v"; -connectAttr "IMP_Luparm_scaleX.o" "IMP_Luparm.sx"; -connectAttr "IMP_Luparm_scaleY.o" "IMP_Luparm.sy"; -connectAttr "IMP_Luparm_scaleZ.o" "IMP_Luparm.sz"; -connectAttr "IMP_Luparm_translateX.o" "IMP_Luparm.tx"; -connectAttr "IMP_Luparm_translateY.o" "IMP_Luparm.ty"; -connectAttr "IMP_Luparm_translateZ.o" "IMP_Luparm.tz"; -connectAttr "IMP_Luparm_rotateZ.o" "IMP_Luparm.rz"; -connectAttr "IMP_Luparm_rotateX.o" "IMP_Luparm.rx"; -connectAttr "IMP_Luparm_rotateY.o" "IMP_Luparm.ry"; -connectAttr "IMP_Luparm_visibility.o" "IMP_Luparm.v"; -connectAttr "IMP_Lloarm_scaleX.o" "IMP_Lloarm.sx"; -connectAttr "IMP_Lloarm_scaleY.o" "IMP_Lloarm.sy"; -connectAttr "IMP_Lloarm_scaleZ.o" "IMP_Lloarm.sz"; -connectAttr "IMP_Lloarm_translateX.o" "IMP_Lloarm.tx"; -connectAttr "IMP_Lloarm_translateY.o" "IMP_Lloarm.ty"; -connectAttr "IMP_Lloarm_translateZ.o" "IMP_Lloarm.tz"; -connectAttr "IMP_Lloarm_rotateX.o" "IMP_Lloarm.rx"; -connectAttr "IMP_Lloarm_rotateY.o" "IMP_Lloarm.ry"; -connectAttr "IMP_Lloarm_rotateZ.o" "IMP_Lloarm.rz"; -connectAttr "IMP_Lloarm_visibility.o" "IMP_Lloarm.v"; -connectAttr "IMP_Ruparm_scaleX.o" "IMP_Ruparm.sx"; -connectAttr "IMP_Ruparm_scaleY.o" "IMP_Ruparm.sy"; -connectAttr "IMP_Ruparm_scaleZ.o" "IMP_Ruparm.sz"; -connectAttr "IMP_Ruparm_translateX.o" "IMP_Ruparm.tx"; -connectAttr "IMP_Ruparm_translateY.o" "IMP_Ruparm.ty"; -connectAttr "IMP_Ruparm_translateZ.o" "IMP_Ruparm.tz"; -connectAttr "IMP_Ruparm_rotateX.o" "IMP_Ruparm.rx"; -connectAttr "IMP_Ruparm_rotateZ.o" "IMP_Ruparm.rz"; -connectAttr "IMP_Ruparm_rotateY.o" "IMP_Ruparm.ry"; -connectAttr "IMP_Ruparm_visibility.o" "IMP_Ruparm.v"; -connectAttr "IMP_Rloarm_scaleX.o" "IMP_Rloarm.sx"; -connectAttr "IMP_Rloarm_scaleY.o" "IMP_Rloarm.sy"; -connectAttr "IMP_Rloarm_scaleZ.o" "IMP_Rloarm.sz"; -connectAttr "IMP_Rloarm_translateX.o" "IMP_Rloarm.tx"; -connectAttr "IMP_Rloarm_translateY.o" "IMP_Rloarm.ty"; -connectAttr "IMP_Rloarm_translateZ.o" "IMP_Rloarm.tz"; -connectAttr "IMP_Rloarm_rotateX.o" "IMP_Rloarm.rx"; -connectAttr "IMP_Rloarm_rotateY.o" "IMP_Rloarm.ry"; -connectAttr "IMP_Rloarm_rotateZ.o" "IMP_Rloarm.rz"; -connectAttr "IMP_Rloarm_visibility.o" "IMP_Rloarm.v"; -connectAttr "IMP_LIK_twist.o" "IMP_LIK.twi"; -connectAttr "IMP_LIK_rotateY.o" "IMP_LIK.ry"; -connectAttr "IMP_LIK_rotateX.o" "IMP_LIK.rx"; -connectAttr "IMP_LIK_rotateZ.o" "IMP_LIK.rz"; -connectAttr "IMP_LIK_visibility.o" "IMP_LIK.v"; -connectAttr "IMP_LIK_scaleX.o" "IMP_LIK.sx"; -connectAttr "IMP_LIK_scaleY.o" "IMP_LIK.sy"; -connectAttr "IMP_LIK_scaleZ.o" "IMP_LIK.sz"; -connectAttr "IMP_LIK_solverEnable.o" "IMP_LIK.hse"; -connectAttr "IMP_LIK_poleVectorX.o" "IMP_LIK.pvx"; -connectAttr "IMP_LIK_poleVectorY.o" "IMP_LIK.pvy"; -connectAttr "IMP_LIK_poleVectorZ.o" "IMP_LIK.pvz"; -connectAttr "IMP_LIK_offset.o" "IMP_LIK.off"; -connectAttr "IMP_LIK_roll.o" "IMP_LIK.rol"; -connectAttr "IMP_RIK_rotateX.o" "IMP_RIK.rx"; -connectAttr "IMP_RIK_rotateY.o" "IMP_RIK.ry"; -connectAttr "IMP_RIK_rotateZ.o" "IMP_RIK.rz"; -connectAttr "IMP_RIK_visibility.o" "IMP_RIK.v"; -connectAttr "IMP_RIK_scaleX.o" "IMP_RIK.sx"; -connectAttr "IMP_RIK_scaleY.o" "IMP_RIK.sy"; -connectAttr "IMP_RIK_scaleZ.o" "IMP_RIK.sz"; -connectAttr "IMP_RIK_solverEnable.o" "IMP_RIK.hse"; -connectAttr "IMP_RIK_poleVectorX.o" "IMP_RIK.pvx"; -connectAttr "IMP_RIK_poleVectorY.o" "IMP_RIK.pvy"; -connectAttr "IMP_RIK_poleVectorZ.o" "IMP_RIK.pvz"; -connectAttr "IMP_RIK_offset.o" "IMP_RIK.off"; -connectAttr "IMP_RIK_roll.o" "IMP_RIK.rol"; -connectAttr "IMP_RIK_twist.o" "IMP_RIK.twi"; -connectAttr "IMP_origin_translateX.o" "IMP_origin.tx"; -connectAttr "IMP_origin_translateZ.o" "IMP_origin.tz"; -connectAttr "IMP_origin_translateY.o" "IMP_origin.ty"; -connectAttr "IMP_origin_visibility.o" "IMP_origin.v"; -connectAttr "IMP_origin_rotateX.o" "IMP_origin.rx"; -connectAttr "IMP_origin_rotateY.o" "IMP_origin.ry"; -connectAttr "IMP_origin_rotateZ.o" "IMP_origin.rz"; -connectAttr "IMP_origin_scaleX.o" "IMP_origin.sx"; -connectAttr "IMP_origin_scaleY.o" "IMP_origin.sy"; -connectAttr "IMP_origin_scaleZ.o" "IMP_origin.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of turret_idle.ma diff --git a/base/models/monsters/imp/fred/imp_setup.mb b/base/models/monsters/imp/fred/imp_setup.mb deleted file mode 100644 index 9aed940e3..000000000 Binary files a/base/models/monsters/imp/fred/imp_setup.mb and /dev/null differ diff --git a/base/models/monsters/imp/fred/imp_setup_ik.mb b/base/models/monsters/imp/fred/imp_setup_ik.mb deleted file mode 100644 index 770ac90a0..000000000 Binary files a/base/models/monsters/imp/fred/imp_setup_ik.mb and /dev/null differ diff --git a/base/models/weapons/machinegun/cycles/empty.ma b/base/models/weapons/machinegun/cycles/empty.ma deleted file mode 100644 index eeacb7d5a..000000000 --- a/base/models/weapons/machinegun/cycles/empty.ma +++ /dev/null @@ -1,1245 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: empty.ma -//Last modified: Tue, Mar 18, 2003 09:47:44 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -9.3637052639016947 -2.2222522912480782 -0.68781111403389339 ; - setAttr ".r" -type "double3" -11.130108913827698 260.59999999995989 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 21.853705220694888; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 9.908890708423435 -18.635357449706053 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 33.110969911671688; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 0 0 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 8 -ast 1 -aet 8 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 1 5 1 8 1 30 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 -36.757686530570041 5 -36.830298900946758 - 8 -36.757686530570041 30 -36.757686530570041; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 23.25274320068932 5 23.477466644718927 - 8 23.25274320068932 30 23.25274320068932; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 -78.68129553398353 5 -78.864387354189802 - 8 -78.68129553398353 30 -78.68129553398353; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 1 5 1 8 1 30 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 1 5 1 8 1 30 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 3 1 5 1 8 1 30 1; - setAttr -s 4 ".kit[2:3]" 9 3; - setAttr -s 4 ".kot[2:3]" 9 3; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 40 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 40 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 15 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 15 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -select -ne MGUN_locator7; - setAttr ".t" -type "double3" -4 11 -3 ; - setAttr ".r" -type "double3" 0 -29.205417093903414 0 ; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of empty.ma diff --git a/base/models/weapons/machinegun/cycles/fire1.ma b/base/models/weapons/machinegun/cycles/fire1.ma deleted file mode 100644 index 02df81a0f..000000000 --- a/base/models/weapons/machinegun/cycles/fire1.ma +++ /dev/null @@ -1,1676 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: fire1.ma -//Last modified: Tue, Mar 18, 2003 09:47:53 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -13.168785951699117 -2.4881401379737906 1.6525234113134852 ; - setAttr ".r" -type "double3" -2.1301089135560192 272.59999999995068 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 23.37900742541877; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 6.9259259259259274 100 2.9876543209876552 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.666666666666671; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 7.1155063688331204 -4.6961799197561591 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 45.768801672706658; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 -1.2200513915143922 -3.8819908765851059 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 83.662897360883647; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode pointConstraint -n "MGUN_locator8_pointConstraint1"; - setAttr -k on ".nds"; - setAttr -k off ".v"; - setAttr -k off ".tx"; - setAttr -k off ".ty"; - setAttr -k off ".tz"; - setAttr -k off ".rx"; - setAttr -k off ".ry"; - setAttr -k off ".rz"; - setAttr -k off ".sx"; - setAttr -k off ".sy"; - setAttr -k off ".sz"; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode transform -n "locator1"; -createNode locator -n "locatorShape1" -p "locator1"; - setAttr -k off ".v"; -createNode pointConstraint -n "locator1_pointConstraint1" -p "locator1"; - addAttr -ci true -sn "w0" -ln "MGUN_ExtW0" -bt "W000" -dv 1 -min 0 -at "double"; - setAttr -k on ".nds"; - setAttr -k off ".v"; - setAttr -k off ".tx"; - setAttr -k off ".ty"; - setAttr -k off ".tz"; - setAttr -k off ".rx"; - setAttr -k off ".ry"; - setAttr -k off ".rz"; - setAttr -k off ".sx"; - setAttr -k off ".sy"; - setAttr -k off ".sz"; - setAttr -k on ".w0"; -createNode orientConstraint -n "locator1_orientConstraint1" -p "locator1"; - addAttr -ci true -sn "w0" -ln "MGUN_ExtW0" -bt "W000" -dv 1 -min 0 -at "double"; - setAttr -k on ".nds"; - setAttr -k off ".v"; - setAttr -k off ".tx"; - setAttr -k off ".ty"; - setAttr -k off ".tz"; - setAttr -k off ".rx"; - setAttr -k off ".ry"; - setAttr -k off ".rz"; - setAttr -k off ".sx"; - setAttr -k off ".sy"; - setAttr -k off ".sz"; - setAttr -k on ".w0"; -createNode transform -n "locator2"; - setAttr ".t" -type "double3" 17.227624426968529 -5.2290123649222391 2.7392944515744202 ; -createNode locator -n "locatorShape2" -p "locator2"; - setAttr -k off ".v"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 4.004 -ast 1 -aet 4.004 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 3.5751692999544797 4 5.5895682500307444; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -21.881272138989363 4 -21.710493028270307; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.773903326022519 4 6.647843850981447; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 24.877835730398068 4 23.858970583210471; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -20.457073594014375 4 -12.978384796886047; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -2.2150193136421659 4 1.3183589787639254; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -37.043136527093303 2 -33.924101677981376 - 4 -37.043136527093303; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 24.119371109172484 2 28.604737919711852 - 4 24.119371109172484; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -79.391828382450555 2 -72.38004814782586 - 4 -79.391828382450555; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.6454304836991881; -createNode animCurveTL -n "MGUN_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.397540168639082; -createNode animCurveTL -n "MGUN_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.4127503099979837; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 62.860414737193942; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 43.94655411870697; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.175285457048407; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_joint3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966383081 4 0.045986124966383025; -createNode animCurveTL -n "MGUN_joint3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 10.606837109762385 4 0.11030631194291995; -createNode animCurveTL -n "MGUN_joint3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.7640488930259259 4 -0.63670003593960889; -createNode animCurveTA -n "MGUN_joint3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.0030757617605203986 4 0.0030757617605206896; -createNode animCurveTL -n "MGUN_joint1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 11.671854586161121 4 0.24257600657262612; -createNode animCurveTL -n "MGUN_joint1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.6705071718219031 4 0.36900809501673359; -createNode animCurveTA -n "MGUN_joint1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.0459861249664116 4 0.045986124966383178; -createNode animCurveTL -n "MGUN_joint2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -8.4801657072290944 4 -0.22981886370766613; -createNode animCurveTL -n "MGUN_joint2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.8734704774156512 4 0.44706418900463252; -createNode animCurveTA -n "MGUN_joint2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint4_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966411412 4 0.045986124966382824; -createNode animCurveTL -n "MGUN_joint4_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -11.422630579205043 4 -0.43689648867938491; -createNode animCurveTL -n "MGUN_joint4_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.3096409434716119 4 -0.71095561219968895; -createNode animCurveTA -n "MGUN_joint4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_locator8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 3 1 4 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "MGUN_locator8_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 16.082343940255758 2 16.421686306689175 - 3 16.803446468926765 4 18.118398138856243; -createNode animCurveTL -n "MGUN_locator8_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -5.3562657523347692 2 -5.101758977509709 - 3 -5.2290123649222391 4 -5.2290123649222391; -createNode animCurveTL -n "MGUN_locator8_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.7392944515744202 2 2.7392944515744202 - 3 2.7392944515744202 4 2.7392944515744202; -createNode animCurveTA -n "MGUN_locator8_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 3 0 4 0; -createNode animCurveTA -n "MGUN_locator8_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 3 0 4 0; -createNode animCurveTA -n "MGUN_locator8_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 3 0 4 0; -createNode animCurveTU -n "MGUN_locator8_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 3 1 4 1; -createNode animCurveTU -n "MGUN_locator8_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 3 1 4 1; -createNode animCurveTU -n "MGUN_locator8_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 3 1 4 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 40 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 40 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 15 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 15 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -select -ne MGUN_Bod; - setAttr ".t" -type "double3" -5.7384160023352093 1.4837587656993767 -0.12284385827254347 ; -select -ne MGUN_LHAND_GOAL_OFF; - setAttr ".t" -type "double3" 18.248571701804728 -20.558540398701673 2.6757355999372985 ; - setAttr ".r" -type "double3" 175.04694820912425 -25.021230763542317 -155.53426393850688 ; - setAttr ".s" -type "double3" 2.9044411307187503 2.9044411307187503 2.9044411307187503 ; -connectAttr "MGUN_joint1_translateX.o" "MGUN_joint1.tx"; -connectAttr "MGUN_joint1_translateY.o" "MGUN_joint1.ty"; -connectAttr "MGUN_joint1_translateZ.o" "MGUN_joint1.tz"; -connectAttr "MGUN_joint1_visibility.o" "MGUN_joint1.v"; -connectAttr "MGUN_joint1_rotateX.o" "MGUN_joint1.rx"; -connectAttr "MGUN_joint1_rotateY.o" "MGUN_joint1.ry"; -connectAttr "MGUN_joint1_rotateZ.o" "MGUN_joint1.rz"; -connectAttr "MGUN_joint1_scaleX.o" "MGUN_joint1.sx"; -connectAttr "MGUN_joint1_scaleY.o" "MGUN_joint1.sy"; -connectAttr "MGUN_joint1_scaleZ.o" "MGUN_joint1.sz"; -connectAttr "MGUN_joint2_translateX.o" "MGUN_joint2.tx"; -connectAttr "MGUN_joint2_translateY.o" "MGUN_joint2.ty"; -connectAttr "MGUN_joint2_translateZ.o" "MGUN_joint2.tz"; -connectAttr "MGUN_joint2_visibility.o" "MGUN_joint2.v"; -connectAttr "MGUN_joint2_rotateX.o" "MGUN_joint2.rx"; -connectAttr "MGUN_joint2_rotateY.o" "MGUN_joint2.ry"; -connectAttr "MGUN_joint2_rotateZ.o" "MGUN_joint2.rz"; -connectAttr "MGUN_joint2_scaleX.o" "MGUN_joint2.sx"; -connectAttr "MGUN_joint2_scaleY.o" "MGUN_joint2.sy"; -connectAttr "MGUN_joint2_scaleZ.o" "MGUN_joint2.sz"; -connectAttr "MGUN_joint3_translateY.o" "MGUN_joint3.ty"; -connectAttr "MGUN_joint3_translateZ.o" "MGUN_joint3.tz"; -connectAttr "MGUN_joint3_translateX.o" "MGUN_joint3.tx"; -connectAttr "MGUN_joint3_visibility.o" "MGUN_joint3.v"; -connectAttr "MGUN_joint3_rotateX.o" "MGUN_joint3.rx"; -connectAttr "MGUN_joint3_rotateY.o" "MGUN_joint3.ry"; -connectAttr "MGUN_joint3_rotateZ.o" "MGUN_joint3.rz"; -connectAttr "MGUN_joint3_scaleX.o" "MGUN_joint3.sx"; -connectAttr "MGUN_joint3_scaleY.o" "MGUN_joint3.sy"; -connectAttr "MGUN_joint3_scaleZ.o" "MGUN_joint3.sz"; -connectAttr "MGUN_joint4_translateY.o" "MGUN_joint4.ty"; -connectAttr "MGUN_joint4_translateZ.o" "MGUN_joint4.tz"; -connectAttr "MGUN_joint4_translateX.o" "MGUN_joint4.tx"; -connectAttr "MGUN_joint4_visibility.o" "MGUN_joint4.v"; -connectAttr "MGUN_joint4_rotateX.o" "MGUN_joint4.rx"; -connectAttr "MGUN_joint4_rotateY.o" "MGUN_joint4.ry"; -connectAttr "MGUN_joint4_rotateZ.o" "MGUN_joint4.rz"; -connectAttr "MGUN_joint4_scaleX.o" "MGUN_joint4.sx"; -connectAttr "MGUN_joint4_scaleY.o" "MGUN_joint4.sy"; -connectAttr "MGUN_joint4_scaleZ.o" "MGUN_joint4.sz"; -connectAttr "MGUN_Luparm_scaleX.o" "|group1|MGUN_locator7|MGUN_Luparm.sx" - ; -connectAttr "MGUN_Luparm_scaleY.o" "|group1|MGUN_locator7|MGUN_Luparm.sy" - ; -connectAttr "MGUN_Luparm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Luparm.sz" - ; -connectAttr "MGUN_Luparm_rotateX.o" "|group1|MGUN_locator7|MGUN_Luparm.rx" - ; -connectAttr "MGUN_Luparm_rotateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ry" - ; -connectAttr "MGUN_Luparm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.rz" - ; -connectAttr "MGUN_Luparm_translateX.o" "|group1|MGUN_locator7|MGUN_Luparm.tx" - ; -connectAttr "MGUN_Luparm_translateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.tz" - ; -connectAttr "MGUN_Luparm_translateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ty" - ; -connectAttr "MGUN_Luparm_visibility.o" "|group1|MGUN_locator7|MGUN_Luparm.v" - ; -connectAttr "MGUN_Rloarm_scaleX.o" "|group1|MGUN_locator7|MGUN_Rloarm.sx" - ; -connectAttr "MGUN_Rloarm_scaleY.o" "|group1|MGUN_locator7|MGUN_Rloarm.sy" - ; -connectAttr "MGUN_Rloarm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.sz" - ; -connectAttr "MGUN_Rloarm_rotateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.rx" - ; -connectAttr "MGUN_Rloarm_rotateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ry" - ; -connectAttr "MGUN_Rloarm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.rz" - ; -connectAttr "MGUN_Rloarm_translateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ty" - ; -connectAttr "MGUN_Rloarm_translateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.tx" - ; -connectAttr "MGUN_Rloarm_translateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.tz" - ; -connectAttr "MGUN_Rloarm_visibility.o" "|group1|MGUN_locator7|MGUN_Rloarm.v" - ; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr "locator1_pointConstraint1.ctx" "locator1.tx"; -connectAttr "locator1_pointConstraint1.cty" "locator1.ty"; -connectAttr "locator1_pointConstraint1.ctz" "locator1.tz"; -connectAttr "locator1_orientConstraint1.crx" "locator1.rx"; -connectAttr "locator1_orientConstraint1.cry" "locator1.ry"; -connectAttr "locator1_orientConstraint1.crz" "locator1.rz"; -connectAttr "locator1.pim" "locator1_pointConstraint1.cpim"; -connectAttr "locator1.rp" "locator1_pointConstraint1.crp"; -connectAttr "locator1.rpt" "locator1_pointConstraint1.crt"; -connectAttr "MGUN_Ext.t" "locator1_pointConstraint1.tg[0].tt"; -connectAttr "MGUN_Ext.rp" "locator1_pointConstraint1.tg[0].trp"; -connectAttr "MGUN_Ext.rpt" "locator1_pointConstraint1.tg[0].trt"; -connectAttr "MGUN_Ext.pm" "locator1_pointConstraint1.tg[0].tpm"; -connectAttr "locator1_pointConstraint1.w0" "locator1_pointConstraint1.tg[0].tw" - ; -connectAttr "locator1.ro" "locator1_orientConstraint1.cro"; -connectAttr "locator1.pim" "locator1_orientConstraint1.cpim"; -connectAttr "MGUN_Ext.r" "locator1_orientConstraint1.tg[0].tr"; -connectAttr "MGUN_Ext.ro" "locator1_orientConstraint1.tg[0].tro"; -connectAttr "MGUN_Ext.pm" "locator1_orientConstraint1.tg[0].tpm"; -connectAttr "MGUN_Ext.jo" "locator1_orientConstraint1.tg[0].tjo"; -connectAttr "locator1_orientConstraint1.w0" "locator1_orientConstraint1.tg[0].tw" - ; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of fire1.ma diff --git a/base/models/weapons/machinegun/cycles/fire2.ma b/base/models/weapons/machinegun/cycles/fire2.ma deleted file mode 100644 index 131a007b5..000000000 --- a/base/models/weapons/machinegun/cycles/fire2.ma +++ /dev/null @@ -1,1561 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: fire2.ma -//Last modified: Tue, Mar 18, 2003 09:48:02 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 48.55657198559738 -5.8922814650052739 -37.756445991293525 ; - setAttr ".r" -type "double3" 3.8698910864171099 141.80000000001019 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 52.393148804977386; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 10.388888888888889 100 -2.0370370370370363 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.666666666666671; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 9.9968092346807929 -7.9161166149004849 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 43.041214797784804; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 -12.937311324223494 1.3798468301195268 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 79.15971543234582; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 4.004 -ast 1 -aet 4.004 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.2019356114500193 4 5.5895682500307444; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -21.710493028270307 4 -21.710493028270307; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.4235377027335581 4 6.647843850981447; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 23.858970583210471 4 23.858970583210471; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.978384796886047 4 -12.978384796886047; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.3183589787639254 4 1.3183589787639254; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -37.831895252873686 2 -37.861167973794544 - 4 -37.043136527093303; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 26.307224381545861 2 25.735615431591235 - 4 24.119371109172484; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -81.242952009061852 2 -71.994733163055528 - 4 -79.391828382450555; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 2 1 4 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.45719176638888864; -createNode animCurveTL -n "MGUN_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.397540168639082; -createNode animCurveTL -n "MGUN_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.1089918048604277; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 64.44173526533929; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 44.061048311662518; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.253189311299412; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_joint1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.070703674570827532 4 0.0030757617605206896; -createNode animCurveTL -n "MGUN_joint1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.845752076924529 4 0.24257600657262612; -createNode animCurveTL -n "MGUN_joint1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 11.605970582134564 4 0.36900809501673359; -createNode animCurveTA -n "MGUN_joint1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.059530418011483857 4 0.045986124966383178; -createNode animCurveTL -n "MGUN_joint2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -11.455658667742219 4 -0.22981886370766613; -createNode animCurveTL -n "MGUN_joint2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 2.7668868133460265 4 0.44706418900463252; -createNode animCurveTA -n "MGUN_joint2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.053813907473742872 4 0.045986124966383025; -createNode animCurveTL -n "MGUN_joint3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 13.129464698328491 4 0.11030631194291995; -createNode animCurveTL -n "MGUN_joint3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -7.2291009970500948 4 -0.63670003593960889; -createNode animCurveTA -n "MGUN_joint3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint4_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.1103046117805077 4 0.045986124966382824; -createNode animCurveTL -n "MGUN_joint4_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -4.3741213708862254 4 -0.43689648867938491; -createNode animCurveTL -n "MGUN_joint4_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -9.5947393651247594 4 -0.71095561219968895; -createNode animCurveTA -n "MGUN_joint4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 40 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 40 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 15 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 15 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -connectAttr "MGUN_joint1_translateY.o" "MGUN_joint1.ty"; -connectAttr "MGUN_joint1_translateZ.o" "MGUN_joint1.tz"; -connectAttr "MGUN_joint1_translateX.o" "MGUN_joint1.tx"; -connectAttr "MGUN_joint1_visibility.o" "MGUN_joint1.v"; -connectAttr "MGUN_joint1_rotateX.o" "MGUN_joint1.rx"; -connectAttr "MGUN_joint1_rotateY.o" "MGUN_joint1.ry"; -connectAttr "MGUN_joint1_rotateZ.o" "MGUN_joint1.rz"; -connectAttr "MGUN_joint1_scaleX.o" "MGUN_joint1.sx"; -connectAttr "MGUN_joint1_scaleY.o" "MGUN_joint1.sy"; -connectAttr "MGUN_joint1_scaleZ.o" "MGUN_joint1.sz"; -connectAttr "MGUN_joint2_translateY.o" "MGUN_joint2.ty"; -connectAttr "MGUN_joint2_translateZ.o" "MGUN_joint2.tz"; -connectAttr "MGUN_joint2_translateX.o" "MGUN_joint2.tx"; -connectAttr "MGUN_joint2_visibility.o" "MGUN_joint2.v"; -connectAttr "MGUN_joint2_rotateX.o" "MGUN_joint2.rx"; -connectAttr "MGUN_joint2_rotateY.o" "MGUN_joint2.ry"; -connectAttr "MGUN_joint2_rotateZ.o" "MGUN_joint2.rz"; -connectAttr "MGUN_joint2_scaleX.o" "MGUN_joint2.sx"; -connectAttr "MGUN_joint2_scaleY.o" "MGUN_joint2.sy"; -connectAttr "MGUN_joint2_scaleZ.o" "MGUN_joint2.sz"; -connectAttr "MGUN_joint3_translateY.o" "MGUN_joint3.ty"; -connectAttr "MGUN_joint3_translateZ.o" "MGUN_joint3.tz"; -connectAttr "MGUN_joint3_translateX.o" "MGUN_joint3.tx"; -connectAttr "MGUN_joint3_visibility.o" "MGUN_joint3.v"; -connectAttr "MGUN_joint3_rotateX.o" "MGUN_joint3.rx"; -connectAttr "MGUN_joint3_rotateY.o" "MGUN_joint3.ry"; -connectAttr "MGUN_joint3_rotateZ.o" "MGUN_joint3.rz"; -connectAttr "MGUN_joint3_scaleX.o" "MGUN_joint3.sx"; -connectAttr "MGUN_joint3_scaleY.o" "MGUN_joint3.sy"; -connectAttr "MGUN_joint3_scaleZ.o" "MGUN_joint3.sz"; -connectAttr "MGUN_joint4_translateY.o" "MGUN_joint4.ty"; -connectAttr "MGUN_joint4_translateZ.o" "MGUN_joint4.tz"; -connectAttr "MGUN_joint4_translateX.o" "MGUN_joint4.tx"; -connectAttr "MGUN_joint4_visibility.o" "MGUN_joint4.v"; -connectAttr "MGUN_joint4_rotateX.o" "MGUN_joint4.rx"; -connectAttr "MGUN_joint4_rotateY.o" "MGUN_joint4.ry"; -connectAttr "MGUN_joint4_rotateZ.o" "MGUN_joint4.rz"; -connectAttr "MGUN_joint4_scaleX.o" "MGUN_joint4.sx"; -connectAttr "MGUN_joint4_scaleY.o" "MGUN_joint4.sy"; -connectAttr "MGUN_joint4_scaleZ.o" "MGUN_joint4.sz"; -connectAttr "MGUN_Luparm_scaleX.o" "|group1|MGUN_locator7|MGUN_Luparm.sx" - ; -connectAttr "MGUN_Luparm_scaleY.o" "|group1|MGUN_locator7|MGUN_Luparm.sy" - ; -connectAttr "MGUN_Luparm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Luparm.sz" - ; -connectAttr "MGUN_Luparm_rotateX.o" "|group1|MGUN_locator7|MGUN_Luparm.rx" - ; -connectAttr "MGUN_Luparm_rotateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ry" - ; -connectAttr "MGUN_Luparm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.rz" - ; -connectAttr "MGUN_Luparm_translateX.o" "|group1|MGUN_locator7|MGUN_Luparm.tx" - ; -connectAttr "MGUN_Luparm_translateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.tz" - ; -connectAttr "MGUN_Luparm_translateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ty" - ; -connectAttr "MGUN_Luparm_visibility.o" "|group1|MGUN_locator7|MGUN_Luparm.v" - ; -connectAttr "MGUN_Rloarm_scaleX.o" "|group1|MGUN_locator7|MGUN_Rloarm.sx" - ; -connectAttr "MGUN_Rloarm_scaleY.o" "|group1|MGUN_locator7|MGUN_Rloarm.sy" - ; -connectAttr "MGUN_Rloarm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.sz" - ; -connectAttr "MGUN_Rloarm_rotateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.rx" - ; -connectAttr "MGUN_Rloarm_rotateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ry" - ; -connectAttr "MGUN_Rloarm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.rz" - ; -connectAttr "MGUN_Rloarm_translateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ty" - ; -connectAttr "MGUN_Rloarm_translateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.tx" - ; -connectAttr "MGUN_Rloarm_translateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.tz" - ; -connectAttr "MGUN_Rloarm_visibility.o" "|group1|MGUN_locator7|MGUN_Rloarm.v" - ; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of fire2.ma diff --git a/base/models/weapons/machinegun/cycles/fire4.ma b/base/models/weapons/machinegun/cycles/fire4.ma deleted file mode 100644 index 7804fe0c9..000000000 --- a/base/models/weapons/machinegun/cycles/fire4.ma +++ /dev/null @@ -1,1573 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: fire4.ma -//Last modified: Tue, Mar 18, 2003 09:48:20 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -4.2404241604021351 -1.1462762343260406 -13.097207142027163 ; - setAttr ".r" -type "double3" -11.730108913557695 233.79999999997244 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 22.503023608347082; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 6.9259259259259274 100 2.9876543209876552 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.666666666666671; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 17.233540072825107 -5.9122880141337157 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 21.168914300270764; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100.22953762964947 -6.1167054649890513 2.8282526646157446 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 84.248085114204088; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 4.004 -ast 1 -aet 4.004 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 4.5574157893921452 4 5.1154134140104386; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -21.710493028270307 4 -21.710493028270307; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 7.2248224370480481 4 6.9128988668793641; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 23.858970583210471 4 23.858970583210471; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -12.978384796886047 4 -12.978384796886047; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.3183589787639254 4 1.3183589787639254; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -37.608163408585355 4 -37.043136527093303; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 22.319551010407952 4 24.119371109172484; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -80.85420450705162 4 -79.391828382450555; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.37809955776404236; -createNode animCurveTL -n "MGUN_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.397540168639082; -createNode animCurveTL -n "MGUN_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.7423962534162056; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 65.64383688415144; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 41.962368696912925; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 37.412640127621593; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_joint1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966383102 4 0.045986124966383102; -createNode animCurveTL -n "MGUN_joint1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 8.2294419703323385 4 0.3909692657448427; -createNode animCurveTL -n "MGUN_joint1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.27431353349647036 4 0.25178630067329033; -createNode animCurveTA -n "MGUN_joint1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966383102 4 0.045986124966383102; -createNode animCurveTL -n "MGUN_joint3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.017396468495705975 4 0.26962680416585272; -createNode animCurveTL -n "MGUN_joint3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -13.506024190761492 4 -0.55797549898230114; -createNode animCurveTA -n "MGUN_joint3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966383102 4 0.045986124966383102; -createNode animCurveTL -n "MGUN_joint2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1.8003262986714841 4 -0.095308675435210155; -createNode animCurveTL -n "MGUN_joint2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 10.061878174371918 4 0.21579730773632555; -createNode animCurveTA -n "MGUN_joint2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; - setAttr -s 2 ".kot[0:1]" 5 5; -createNode animCurveTL -n "MGUN_joint4_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0.045986124966397313 4 0.045986124966383102; -createNode animCurveTL -n "MGUN_joint4_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -10.844218457528665 4 -0.33035972280181802; -createNode animCurveTL -n "MGUN_joint4_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 -0.65854425425226548 4 -0.70970447922618174; -createNode animCurveTA -n "MGUN_joint4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTA -n "MGUN_joint4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 0 4 0; -createNode animCurveTU -n "MGUN_joint4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -createNode animCurveTU -n "MGUN_joint4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 2 ".ktv[0:1]" 1 1 4 1; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 40 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 40 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 15 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 15 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -connectAttr "MGUN_joint1_translateY.o" "MGUN_joint1.ty"; -connectAttr "MGUN_joint1_translateZ.o" "MGUN_joint1.tz"; -connectAttr "MGUN_joint1_translateX.o" "MGUN_joint1.tx"; -connectAttr "MGUN_joint1_visibility.o" "MGUN_joint1.v"; -connectAttr "MGUN_joint1_rotateX.o" "MGUN_joint1.rx"; -connectAttr "MGUN_joint1_rotateY.o" "MGUN_joint1.ry"; -connectAttr "MGUN_joint1_rotateZ.o" "MGUN_joint1.rz"; -connectAttr "MGUN_joint1_scaleX.o" "MGUN_joint1.sx"; -connectAttr "MGUN_joint1_scaleY.o" "MGUN_joint1.sy"; -connectAttr "MGUN_joint1_scaleZ.o" "MGUN_joint1.sz"; -connectAttr "MGUN_joint2_translateY.o" "MGUN_joint2.ty"; -connectAttr "MGUN_joint2_translateZ.o" "MGUN_joint2.tz"; -connectAttr "MGUN_joint2_translateX.o" "MGUN_joint2.tx"; -connectAttr "MGUN_joint2_visibility.o" "MGUN_joint2.v"; -connectAttr "MGUN_joint2_rotateX.o" "MGUN_joint2.rx"; -connectAttr "MGUN_joint2_rotateY.o" "MGUN_joint2.ry"; -connectAttr "MGUN_joint2_rotateZ.o" "MGUN_joint2.rz"; -connectAttr "MGUN_joint2_scaleX.o" "MGUN_joint2.sx"; -connectAttr "MGUN_joint2_scaleY.o" "MGUN_joint2.sy"; -connectAttr "MGUN_joint2_scaleZ.o" "MGUN_joint2.sz"; -connectAttr "MGUN_joint3_translateX.o" "MGUN_joint3.tx"; -connectAttr "MGUN_joint3_translateY.o" "MGUN_joint3.ty"; -connectAttr "MGUN_joint3_translateZ.o" "MGUN_joint3.tz"; -connectAttr "MGUN_joint3_visibility.o" "MGUN_joint3.v"; -connectAttr "MGUN_joint3_rotateX.o" "MGUN_joint3.rx"; -connectAttr "MGUN_joint3_rotateY.o" "MGUN_joint3.ry"; -connectAttr "MGUN_joint3_rotateZ.o" "MGUN_joint3.rz"; -connectAttr "MGUN_joint3_scaleX.o" "MGUN_joint3.sx"; -connectAttr "MGUN_joint3_scaleY.o" "MGUN_joint3.sy"; -connectAttr "MGUN_joint3_scaleZ.o" "MGUN_joint3.sz"; -connectAttr "MGUN_joint4_translateX.o" "MGUN_joint4.tx"; -connectAttr "MGUN_joint4_translateY.o" "MGUN_joint4.ty"; -connectAttr "MGUN_joint4_translateZ.o" "MGUN_joint4.tz"; -connectAttr "MGUN_joint4_visibility.o" "MGUN_joint4.v"; -connectAttr "MGUN_joint4_rotateX.o" "MGUN_joint4.rx"; -connectAttr "MGUN_joint4_rotateY.o" "MGUN_joint4.ry"; -connectAttr "MGUN_joint4_rotateZ.o" "MGUN_joint4.rz"; -connectAttr "MGUN_joint4_scaleX.o" "MGUN_joint4.sx"; -connectAttr "MGUN_joint4_scaleY.o" "MGUN_joint4.sy"; -connectAttr "MGUN_joint4_scaleZ.o" "MGUN_joint4.sz"; -connectAttr "MGUN_Luparm_scaleX.o" "|group1|MGUN_locator7|MGUN_Luparm.sx" - ; -connectAttr "MGUN_Luparm_scaleY.o" "|group1|MGUN_locator7|MGUN_Luparm.sy" - ; -connectAttr "MGUN_Luparm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Luparm.sz" - ; -connectAttr "MGUN_Luparm_rotateX.o" "|group1|MGUN_locator7|MGUN_Luparm.rx" - ; -connectAttr "MGUN_Luparm_rotateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ry" - ; -connectAttr "MGUN_Luparm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.rz" - ; -connectAttr "MGUN_Luparm_translateX.o" "|group1|MGUN_locator7|MGUN_Luparm.tx" - ; -connectAttr "MGUN_Luparm_translateZ.o" "|group1|MGUN_locator7|MGUN_Luparm.tz" - ; -connectAttr "MGUN_Luparm_translateY.o" "|group1|MGUN_locator7|MGUN_Luparm.ty" - ; -connectAttr "MGUN_Luparm_visibility.o" "|group1|MGUN_locator7|MGUN_Luparm.v" - ; -connectAttr "MGUN_Rloarm_scaleX.o" "|group1|MGUN_locator7|MGUN_Rloarm.sx" - ; -connectAttr "MGUN_Rloarm_scaleY.o" "|group1|MGUN_locator7|MGUN_Rloarm.sy" - ; -connectAttr "MGUN_Rloarm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.sz" - ; -connectAttr "MGUN_Rloarm_rotateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.rx" - ; -connectAttr "MGUN_Rloarm_rotateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ry" - ; -connectAttr "MGUN_Rloarm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.rz" - ; -connectAttr "MGUN_Rloarm_translateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ty" - ; -connectAttr "MGUN_Rloarm_translateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.tx" - ; -connectAttr "MGUN_Rloarm_translateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.tz" - ; -connectAttr "MGUN_Rloarm_visibility.o" "|group1|MGUN_locator7|MGUN_Rloarm.v" - ; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of fire4.ma diff --git a/base/models/weapons/machinegun/cycles/idle1.ma b/base/models/weapons/machinegun/cycles/idle1.ma deleted file mode 100644 index fbf681a3d..000000000 --- a/base/models/weapons/machinegun/cycles/idle1.ma +++ /dev/null @@ -1,1335 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: idle1.ma -//Last modified: Tue, Mar 18, 2003 09:48:29 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 8.17256483093783 -0.73804540872658375 -61.629541425325357 ; - setAttr ".r" -type "double3" -6.3301089138306432 183.79999999996627 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 66.061287348222592; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 9.908890708423435 -18.635357449706053 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 33.110969911671688; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 0 0 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.5895682500307444 26 5.4566254291701313 - 45 5.5895682500307444; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -21.710493028270307 26 -21.350205009277463 - 45 -21.710493028270307; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.647843850981447 26 6.7221595782921266 - 45 6.647843850981447; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 23.858970583210471 26 23.858970583210471 - 45 23.858970583210471; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.978384796886047 26 -12.978384796886047 - 45 -12.978384796886047; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.3183589787639254 26 1.3183589787639254 - 45 1.3183589787639254; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 14 1 33 1 45 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -37.043136527093303 14 -37.171028334538256 - 33 -36.776219495136843 45 -37.043136527093303; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 24.119371109172484 14 23.902180152856616 - 33 24.559367716302084 45 24.119371109172484; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -79.391828382450555 14 -79.706128346474401 - 33 -78.746841489642691 45 -79.391828382450555; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 14 1 33 1 45 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 14 1 33 1 45 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 14 1 33 1 45 1; - setAttr -s 4 ".kit[0:3]" 3 9 9 3; - setAttr -s 4 ".kot[0:3]" 3 9 9 3; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " -clipTime \"off\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232484\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 45 -ast 1 -aet 45 "; - setAttr ".st" 6; -select -ne :time1; - setAttr ".o" 1; -select -ne :renderPartition; - setAttr -s 40 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 40 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 15 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 15 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -select -ne MGUN_locator7; - setAttr ".t" -type "double3" -4 11 -3 ; - setAttr ".r" -type "double3" 0 -29.205417093903414 0 ; -connectAttr "MGUN_Rloarm_scaleX.o" "|group1|MGUN_locator7|MGUN_Rloarm.sx" - ; -connectAttr "MGUN_Rloarm_scaleY.o" "|group1|MGUN_locator7|MGUN_Rloarm.sy" - ; -connectAttr "MGUN_Rloarm_scaleZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.sz" - ; -connectAttr "MGUN_Rloarm_rotateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.rx" - ; -connectAttr "MGUN_Rloarm_rotateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ry" - ; -connectAttr "MGUN_Rloarm_rotateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.rz" - ; -connectAttr "MGUN_Rloarm_translateY.o" "|group1|MGUN_locator7|MGUN_Rloarm.ty" - ; -connectAttr "MGUN_Rloarm_translateX.o" "|group1|MGUN_locator7|MGUN_Rloarm.tx" - ; -connectAttr "MGUN_Rloarm_translateZ.o" "|group1|MGUN_locator7|MGUN_Rloarm.tz" - ; -connectAttr "MGUN_Rloarm_visibility.o" "|group1|MGUN_locator7|MGUN_Rloarm.v" - ; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of idle1.ma diff --git a/base/models/weapons/machinegun/cycles/pullup1.ma b/base/models/weapons/machinegun/cycles/pullup1.ma deleted file mode 100644 index f7fdd238d..000000000 --- a/base/models/weapons/machinegun/cycles/pullup1.ma +++ /dev/null @@ -1,7443 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: pullup1.ma -//Last modified: Tue, Jan 20, 2004 10:43:21 AM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0.91674366138346963 -1.8665829884681338 0.35040088355393961 ; - setAttr ".r" -type "double3" -0.33010891382989693 264.19999999996406 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 17.999987882312215; - setAttr ".fcp" 100000; - setAttr ".coi" 13.558603134110289; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 0 100 0 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 36.107290233837666; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 9.908890708423435 -18.635357449706053 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 43.495153047656757; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 72.18898307493248; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.5895682500307444 26 5.4566254291701313 - 45 5.5895682500307444; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -21.710493028270307 26 -21.350205009277463 - 45 -21.710493028270307; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.647843850981447 26 6.7221595782921266 - 45 6.647843850981447; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 23.858970583210471 26 23.858970583210471 - 45 23.858970583210471; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.978384796886047 26 -12.978384796886047 - 45 -12.978384796886047; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.3183589787639254 26 1.3183589787639254 - 45 1.3183589787639254; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 26 1 45 1; - setAttr -s 3 ".kit[1:2]" 9 3; - setAttr -s 3 ".kot[1:2]" 9 3; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 12 1 15 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -79.71813233923146 9 -56.615503843843733 - 12 -37.043136527093303 15 -37.043136527093303; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 7.1798979388855884 9 13.970245216417039 - 12 24.119371109172484 15 24.119371109172484; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -133.16990293317849 9 -99.860273402715791 - 12 -79.391828382450555 15 -79.391828382450555; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 12 1 15 1; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 12 1 15 1; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 9 1 12 1 15 1; - setAttr -s 4 ".kit[3]" 3; - setAttr -s 4 ".kot[3]" 3; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 15 -ast 1 -aet 15 "; - setAttr ".st" 6; -createNode animCurveTU -n "side_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "side_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 100; -createNode animCurveTL -n "side_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "side_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "side_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "side_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 89.999999999999986; -createNode animCurveTA -n "side_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "side_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "side_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "side_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_polySurface23_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_polySurface24_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_polySurface25_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_polySurface26_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_locator8_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator8_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_locator8_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_locator8_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator8_pointConstraint1_ExtW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator8_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_locator8_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_locator8_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_locator8_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator8_orientConstraint1_ExtW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ejectconnector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_ejectconnector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ejectconnector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ejectconnector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_meshes_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_meshes_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_meshes_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_meshes_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_meshes_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_meshes_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_meshes_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_meshes_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_meshes_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_meshes_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ruparmmesh_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_Luparmmesh_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_lelbow1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_lelbow1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_lelbow1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_lelbow1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_lelbow1_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_lelbow1_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_lelbow1_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_lelbow1_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_lelbow1_pointConstraint1_LwristW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_lelbow1_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_lelbow1_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_lelbow1_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_lelbow1_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_lelbow1_orientConstraint1_LwristW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_relbow1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_relbow1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_relbow1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_relbow1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99999999999999989; -createNode animCurveTU -n "MGUN_relbow1_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_relbow1_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_relbow1_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_relbow1_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_relbow1_pointConstraint1_RwristW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_relbow1_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_relbow1_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_relbow1_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_relbow1_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_relbow1_orientConstraint1_RwristW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_relbow2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_relbow2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.036277943796353185; -createNode animCurveTL -n "MGUN_relbow2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.060179754717886391; -createNode animCurveTL -n "MGUN_relbow2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.845995069778354; -createNode animCurveTA -n "MGUN_relbow2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.7663631185189397; -createNode animCurveTA -n "MGUN_relbow2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -6.1314410027132933; -createNode animCurveTA -n "MGUN_relbow2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 137.74794352100631; -createNode animCurveTU -n "MGUN_relbow2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.47955719524318668; -createNode animCurveTU -n "MGUN_relbow2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.47955719524318691; -createNode animCurveTU -n "MGUN_relbow2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.47955719524318691; -createNode animCurveTU -n "MGUN_group3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_group3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_group3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_group3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_group3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_group3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_group3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lloarm_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.13956670111441127; -createNode animCurveTL -n "MGUN_Lloarm_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -12.959117455432542; -createNode animCurveTL -n "MGUN_Lloarm_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.17873876116795584; -createNode animCurveTA -n "MGUN_Lloarm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.7296529428493148; -createNode animCurveTA -n "MGUN_Lloarm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.34000823712760941; -createNode animCurveTA -n "MGUN_Lloarm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.21212280099029795; -createNode animCurveTU -n "MGUN_Lloarm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lwrist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lwrist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.32372186610081854; -createNode animCurveTL -n "MGUN_Lwrist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.2570149160095667; -createNode animCurveTL -n "MGUN_Lwrist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.41267442901289719; -createNode animCurveTA -n "MGUN_Lwrist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 9.8910301442102426; -createNode animCurveTA -n "MGUN_Lwrist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -21.214467182591086; -createNode animCurveTA -n "MGUN_Lwrist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 14.021852821326179; -createNode animCurveTU -n "MGUN_Lwrist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lwrist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lwrist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.14159180612839606; -createNode animCurveTL -n "MGUN_Lhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.4524412205878612; -createNode animCurveTL -n "MGUN_Lhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4.6216072924443221; -createNode animCurveTU -n "MGUN_Lhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lthumb1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.10914856728805808; -createNode animCurveTL -n "MGUN_Lthumb1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.2751602490115874; -createNode animCurveTL -n "MGUN_Lthumb1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.043977474900984311; -createNode animCurveTA -n "MGUN_Lthumb1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lthumb1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 50.304429059414666; -createNode animCurveTA -n "MGUN_Lthumb1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Lthumb1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lthumb2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.10716000272675574; -createNode animCurveTL -n "MGUN_Lthumb2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.5044332321137617; -createNode animCurveTL -n "MGUN_Lthumb2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.095627985328331333; -createNode animCurveTA -n "MGUN_Lthumb2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 21.867232388874974; -createNode animCurveTA -n "MGUN_Lthumb2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.6320304877926561; -createNode animCurveTA -n "MGUN_Lthumb2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4.5322012242412715; -createNode animCurveTU -n "MGUN_Lthumb2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lthumb3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.0012174743149720572; -createNode animCurveTL -n "MGUN_Lthumb3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.1901634759753394; -createNode animCurveTL -n "MGUN_Lthumb3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.13288865115226967; -createNode animCurveTA -n "MGUN_Lthumb3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4.3633213422465662; -createNode animCurveTA -n "MGUN_Lthumb3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 19.474993242809933; -createNode animCurveTA -n "MGUN_Lthumb3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -7.9190056980029153; -createNode animCurveTU -n "MGUN_Lthumb3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lindex1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.43332347386308079; -createNode animCurveTL -n "MGUN_Lindex1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.7766053666013157; -createNode animCurveTL -n "MGUN_Lindex1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.977522558811267; -createNode animCurveTA -n "MGUN_Lindex1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.143580267832804; -createNode animCurveTA -n "MGUN_Lindex1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 50.071712497075531; -createNode animCurveTA -n "MGUN_Lindex1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 28.079959592936834; -createNode animCurveTU -n "MGUN_Lindex1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lindex2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.026337435720389778; -createNode animCurveTL -n "MGUN_Lindex2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.2033357122947774; -createNode animCurveTL -n "MGUN_Lindex2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.016939005373982362; -createNode animCurveTA -n "MGUN_Lindex2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -59.865508892148746; -createNode animCurveTA -n "MGUN_Lindex2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 35.761332771241115; -createNode animCurveTA -n "MGUN_Lindex2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 19.36955579273333; -createNode animCurveTU -n "MGUN_Lindex2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lindex3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.047142128204825544; -createNode animCurveTL -n "MGUN_Lindex3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.90750922827001435; -createNode animCurveTL -n "MGUN_Lindex3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.018470362040332939; -createNode animCurveTA -n "MGUN_Lindex3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.3817924597588638; -createNode animCurveTA -n "MGUN_Lindex3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.182699535523398; -createNode animCurveTA -n "MGUN_Lindex3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -13.629158212027662; -createNode animCurveTU -n "MGUN_Lindex3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.12929786122372844; -createNode animCurveTL -n "MGUN_Lmiddle1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.97449513235673757; -createNode animCurveTL -n "MGUN_Lmiddle1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.5290563280752414; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.7365202177784165; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 59.199473201738385; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 35.11968714747389; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.34987200341526942; -createNode animCurveTL -n "MGUN_Lmiddle2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.1638688304340805; -createNode animCurveTL -n "MGUN_Lmiddle2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.0059347417443372935; -createNode animCurveTA -n "MGUN_Lmiddle2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -64.509812703012244; -createNode animCurveTA -n "MGUN_Lmiddle2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 39.454167458324662; -createNode animCurveTA -n "MGUN_Lmiddle2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.524679226719375; -createNode animCurveTU -n "MGUN_Lmiddle2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.14250066551827384; -createNode animCurveTL -n "MGUN_Lmiddle3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.0737607585254823; -createNode animCurveTL -n "MGUN_Lmiddle3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.068473039088232324; -createNode animCurveTA -n "MGUN_Lmiddle3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 10.465179498482765; -createNode animCurveTA -n "MGUN_Lmiddle3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -26.959696334301707; -createNode animCurveTA -n "MGUN_Lmiddle3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -30.291073473869172; -createNode animCurveTU -n "MGUN_Lmiddle3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lring1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.42291936164487048; -createNode animCurveTL -n "MGUN_Lring1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.38529943542381484; -createNode animCurveTL -n "MGUN_Lring1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.5737744674322522; -createNode animCurveTA -n "MGUN_Lring1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -13.637412252907389; -createNode animCurveTA -n "MGUN_Lring1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 60.804887293381178; -createNode animCurveTA -n "MGUN_Lring1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 25.77249028945748; -createNode animCurveTU -n "MGUN_Lring1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lring2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.20979439067157463; -createNode animCurveTL -n "MGUN_Lring2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.013799034312115; -createNode animCurveTL -n "MGUN_Lring2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.028535504544426885; -createNode animCurveTA -n "MGUN_Lring2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -59.828954699514192; -createNode animCurveTA -n "MGUN_Lring2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 39.347121459496911; -createNode animCurveTA -n "MGUN_Lring2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 20.703834034896833; -createNode animCurveTU -n "MGUN_Lring2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lrring3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lrring3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.053767046384323905; -createNode animCurveTL -n "MGUN_Lrring3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.90219938083855244; -createNode animCurveTL -n "MGUN_Lrring3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.034043351522507662; -createNode animCurveTA -n "MGUN_Lrring3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 7.6124106742796798; -createNode animCurveTA -n "MGUN_Lrring3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -27.852477952066206; -createNode animCurveTA -n "MGUN_Lrring3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -20.46786065056288; -createNode animCurveTU -n "MGUN_Lrring3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lrring3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lrring3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.1824436775026228; -createNode animCurveTL -n "MGUN_Lpinky1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.22543995748073206; -createNode animCurveTL -n "MGUN_Lpinky1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.2856432959819659; -createNode animCurveTA -n "MGUN_Lpinky1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.9137418429085; -createNode animCurveTA -n "MGUN_Lpinky1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 62.090943841450247; -createNode animCurveTA -n "MGUN_Lpinky1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 23.144011103647046; -createNode animCurveTU -n "MGUN_Lpinky1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.11222397132676704; -createNode animCurveTL -n "MGUN_Lpinky2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.99157078517171993; -createNode animCurveTL -n "MGUN_Lpinky2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.025623709066893111; -createNode animCurveTA -n "MGUN_Lpinky2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -58.604431220675998; -createNode animCurveTA -n "MGUN_Lpinky2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 41.366821043660863; -createNode animCurveTA -n "MGUN_Lpinky2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.313067528325963; -createNode animCurveTU -n "MGUN_Lpinky2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.14687234024073881; -createNode animCurveTL -n "MGUN_Lpinky3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.68243627620263814; -createNode animCurveTL -n "MGUN_Lpinky3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.053010001991314955; -createNode animCurveTA -n "MGUN_Lpinky3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.523371164593958; -createNode animCurveTA -n "MGUN_Lpinky3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -28.474071475738981; -createNode animCurveTA -n "MGUN_Lpinky3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.8164680091303635; -createNode animCurveTU -n "MGUN_Lpinky3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand_orientConstraint3_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint3_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint3_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint3_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_effector3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_effector3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_effector3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector3_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_Luparm_pointConstraint2_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Luparm_pointConstraint2_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Luparm_pointConstraint2_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Luparm_pointConstraint2_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Luparm_pointConstraint2_locator11W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.2462785488356714; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 68.910183666687558; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 45.412890893971493; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rloarm_visibility1"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.13955918242152876; -createNode animCurveTL -n "MGUN_Rloarm_translateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 12.959147249723712; -createNode animCurveTL -n "MGUN_Rloarm_translateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.17873888855099107; -createNode animCurveTA -n "MGUN_Rloarm_rotateX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -18.478634810039789; -createNode animCurveTA -n "MGUN_Rloarm_rotateY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.85684624207355953; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.30153964634968816; -createNode animCurveTU -n "MGUN_Rloarm_scaleX1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ1"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rwrist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rwrist_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.32369628312252807; -createNode animCurveTL -n "MGUN_Rwrist_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.2570229018497336; -createNode animCurveTL -n "MGUN_Rwrist_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.41266994780323429; -createNode animCurveTA -n "MGUN_Rwrist_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 9.8910301442102426; -createNode animCurveTA -n "MGUN_Rwrist_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -21.214467182591086; -createNode animCurveTA -n "MGUN_Rwrist_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 14.021852821326179; -createNode animCurveTU -n "MGUN_Rwrist_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rwrist_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rwrist_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rhand_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.036277943796349632; -createNode animCurveTL -n "MGUN_Rhand_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.060179754717872957; -createNode animCurveTL -n "MGUN_Rhand_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.8459950697783487; -createNode animCurveTU -n "MGUN_Rhand_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.64620681537502023; -createNode animCurveTL -n "MGUN_Rthumb1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.99388952543193199; -createNode animCurveTL -n "MGUN_Rthumb1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.48428395905662924; -createNode animCurveTA -n "MGUN_Rthumb1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rthumb1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 50.304429059414666; -createNode animCurveTA -n "MGUN_Rthumb1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rthumb1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.10722807364154896; -createNode animCurveTL -n "MGUN_Rthumb2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.5043845588802078; -createNode animCurveTL -n "MGUN_Rthumb2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.095656228892401884; -createNode animCurveTA -n "MGUN_Rthumb2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 21.867232388874974; -createNode animCurveTA -n "MGUN_Rthumb2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.6320304877926561; -createNode animCurveTA -n "MGUN_Rthumb2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4.5322012242412715; -createNode animCurveTU -n "MGUN_Rthumb2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.0011903651940485815; -createNode animCurveTL -n "MGUN_Rthumb3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.1901831974686985; -createNode animCurveTL -n "MGUN_Rthumb3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.13289617599428638; -createNode animCurveTA -n "MGUN_Rthumb3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4.3633213422465662; -createNode animCurveTA -n "MGUN_Rthumb3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 19.474993242809933; -createNode animCurveTA -n "MGUN_Rthumb3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -7.9190056980029153; -createNode animCurveTU -n "MGUN_Rthumb3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.20250564689999706; -createNode animCurveTL -n "MGUN_Rindex1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.84625870343024445; -createNode animCurveTL -n "MGUN_Rindex1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.3841610121183949; -createNode animCurveTA -n "MGUN_Rindex1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.143580267832804; -createNode animCurveTA -n "MGUN_Rindex1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 50.071712497075531; -createNode animCurveTA -n "MGUN_Rindex1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 28.079959592936834; -createNode animCurveTU -n "MGUN_Rindex1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.026299781897019869; -createNode animCurveTL -n "MGUN_Rindex2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.2033401492406242; -createNode animCurveTL -n "MGUN_Rindex2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.016879845903456925; -createNode animCurveTA -n "MGUN_Rindex2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -59.865508892148746; -createNode animCurveTA -n "MGUN_Rindex2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 35.761332771241115; -createNode animCurveTA -n "MGUN_Rindex2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 19.36955579273333; -createNode animCurveTU -n "MGUN_Rindex2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.047171580751363962; -createNode animCurveTL -n "MGUN_Rindex3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.90754361657893412; -createNode animCurveTL -n "MGUN_Rindex3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.018369430481849136; -createNode animCurveTA -n "MGUN_Rindex3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.3817924597588638; -createNode animCurveTA -n "MGUN_Rindex3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.182699535523398; -createNode animCurveTA -n "MGUN_Rindex3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -13.629158212027662; -createNode animCurveTU -n "MGUN_Rindex3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.39997884468618139; -createNode animCurveTL -n "MGUN_Rmiddle1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.12113909295154457; -createNode animCurveTL -n "MGUN_Rmiddle1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.6394971133883862; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.7365202177784165; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 59.199473201738385; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 35.11968714747389; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.34996659009394904; -createNode animCurveTL -n "MGUN_Rmiddle2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.1638862061582265; -createNode animCurveTL -n "MGUN_Rmiddle2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.0058990959178562008; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -64.509812703012244; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 39.454167458324662; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.524679226719375; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.14255500229258544; -createNode animCurveTL -n "MGUN_Rmiddle3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0736792354681057; -createNode animCurveTL -n "MGUN_Rmiddle3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.068508544328491183; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 10.465179498482765; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -26.959696334301707; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -30.291073473869172; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rring1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.18401136578347632; -createNode animCurveTL -n "MGUN_Rring1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.88864370373640078; -createNode animCurveTL -n "MGUN_Rring1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.5036817365697139; -createNode animCurveTA -n "MGUN_Rring1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -13.637412252907389; -createNode animCurveTA -n "MGUN_Rring1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 60.804887293381178; -createNode animCurveTA -n "MGUN_Rring1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 25.77249028945748; -createNode animCurveTU -n "MGUN_Rring1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rring2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.20975021925272941; -createNode animCurveTL -n "MGUN_Rring2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0137524110593601; -createNode animCurveTL -n "MGUN_Rring2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.028503429526118396; -createNode animCurveTA -n "MGUN_Rring2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -59.828954699514192; -createNode animCurveTA -n "MGUN_Rring2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 39.347121459496911; -createNode animCurveTA -n "MGUN_Rring2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 20.703834034896833; -createNode animCurveTU -n "MGUN_Rring2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rring2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rrring3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rrring3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.053741705965343556; -createNode animCurveTL -n "MGUN_Rrring3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.90223981334459324; -createNode animCurveTL -n "MGUN_Rrring3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.034048580819781904; -createNode animCurveTA -n "MGUN_Rrring3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 7.6124106742796798; -createNode animCurveTA -n "MGUN_Rrring3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -27.852477952066206; -createNode animCurveTA -n "MGUN_Rrring3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -20.46786065056288; -createNode animCurveTU -n "MGUN_Rrring3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rrring3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rrring3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.2712478845905828; -createNode animCurveTL -n "MGUN_Rpinky1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.6800905578050163; -createNode animCurveTL -n "MGUN_Rpinky1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.0574260158963051; -createNode animCurveTA -n "MGUN_Rpinky1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.9137418429085; -createNode animCurveTA -n "MGUN_Rpinky1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 62.090943841450247; -createNode animCurveTA -n "MGUN_Rpinky1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 23.144011103647046; -createNode animCurveTU -n "MGUN_Rpinky1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.11218028540197622; -createNode animCurveTL -n "MGUN_Rpinky2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99160382885266696; -createNode animCurveTL -n "MGUN_Rpinky2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.025654221325943638; -createNode animCurveTA -n "MGUN_Rpinky2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -58.604431220675998; -createNode animCurveTA -n "MGUN_Rpinky2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 41.366821043660863; -createNode animCurveTA -n "MGUN_Rpinky2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.313067528325963; -createNode animCurveTU -n "MGUN_Rpinky2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky3_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.14683411705801674; -createNode animCurveTL -n "MGUN_Rpinky3_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.68245151272406979; -createNode animCurveTL -n "MGUN_Rpinky3_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.053025670655280521; -createNode animCurveTA -n "MGUN_Rpinky3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.523371164593958; -createNode animCurveTA -n "MGUN_Rpinky3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -28.474071475738981; -createNode animCurveTA -n "MGUN_Rpinky3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.8164680091303635; -createNode animCurveTU -n "MGUN_Rpinky3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rpinky3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand_orientConstraint2_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint2_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint2_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint2_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rhand_orientConstraint2_locator10W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_effector2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_effector2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector2_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_Ruparm_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Ruparm_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Ruparm_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Ruparm_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Ruparm_pointConstraint1_locator9W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ruparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Ruparm_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 162.70680990720004; -createNode animCurveTA -n "MGUN_Ruparm_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -48.71897871328224; -createNode animCurveTA -n "MGUN_Ruparm_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -20.272046550934654; -createNode animCurveTU -n "MGUN_Ruparm_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ruparm_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ruparm_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle3_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_ikHandle3_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle3_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle3_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle3_pointConstraint1_locator10W0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_ikHandle3_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.1927080055488182e-014; -createNode animCurveTA -n "MGUN_ikHandle3_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.9756933518293944e-015; -createNode animCurveTA -n "MGUN_ikHandle3_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -9.5416640443905456e-015; -createNode animCurveTU -n "MGUN_ikHandle3_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000004; -createNode animCurveTU -n "MGUN_ikHandle3_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000004; -createNode animCurveTU -n "MGUN_ikHandle3_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000002; -createNode animCurveTU -n "MGUN_ikHandle3_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_ikHandle3_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.078224471809798857; -createNode animCurveTU -n "MGUN_ikHandle3_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.094741256524000367; -createNode animCurveTU -n "MGUN_ikHandle3_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.1049742174170918; -createNode animCurveTU -n "MGUN_ikHandle3_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle3_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle3_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle4_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_ikHandle4_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle4_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle4_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_ikHandle4_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -118.17578552328128; -createNode animCurveTA -n "MGUN_ikHandle4_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -61.50391831071088; -createNode animCurveTA -n "MGUN_ikHandle4_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -148.26594570196698; -createNode animCurveTU -n "MGUN_ikHandle4_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle4_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle4_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle4_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle4_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle4_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle4_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_fx1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_fx2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_fx3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_fx4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_locator13_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator13_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_locator13_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_locator13_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator13_pointConstraint1_BodW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator13_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_locator13_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_locator13_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_locator13_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator13_orientConstraint1_BodW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_barrel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_barrel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 12.668980514700953; -createNode animCurveTL -n "MGUN_barrel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.5615950168103767; -createNode animCurveTL -n "MGUN_barrel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.705242917773897; -createNode animCurveTA -n "MGUN_barrel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_barrel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_barrel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_barrel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_barrel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_barrel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator13_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_locator13_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator13_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator13_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Gun2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.16132354913516858; -createNode animCurveTL -n "MGUN_Gun2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.05416238191776683; -createNode animCurveTL -n "MGUN_Gun2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.022183441315541959; -createNode animCurveTA -n "MGUN_Gun2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Gun2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Gun2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Gun2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Trig_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Trig_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.4821247509507298; -createNode animCurveTL -n "MGUN_Trig_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.010681267694348; -createNode animCurveTL -n "MGUN_Trig_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.39250887410369534; -createNode animCurveTA -n "MGUN_Trig_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Trig_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Trig_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Trig_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Trig_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Trig_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ext_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Ext_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.9266984917693435; -createNode animCurveTL -n "MGUN_Ext_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.6288191942702444; -createNode animCurveTL -n "MGUN_Ext_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.2443498069495047; -createNode animCurveTA -n "MGUN_Ext_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Ext_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -28.518133962388895; -createNode animCurveTA -n "MGUN_Ext_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Ext_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ext_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Ext_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Cli_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Cli_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.090296613812721; -createNode animCurveTL -n "MGUN_Cli_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.81101914312491763; -createNode animCurveTL -n "MGUN_Cli_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.061867831930466771; -createNode animCurveTA -n "MGUN_Cli_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Cli_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Cli_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Cli_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Cli_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Cli_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ToTop_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_ToTop_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.6701738797694734; -createNode animCurveTL -n "MGUN_ToTop_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3.0169059773160747; -createNode animCurveTL -n "MGUN_ToTop_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3.3881798259878253; -createNode animCurveTA -n "MGUN_ToTop_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 178.90993972715287; -createNode animCurveTA -n "MGUN_ToTop_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -35.136585827747794; -createNode animCurveTA -n "MGUN_ToTop_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -155.39348827926921; -createNode animCurveTU -n "MGUN_ToTop_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000004; -createNode animCurveTU -n "MGUN_ToTop_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99999999999999989; -createNode animCurveTU -n "MGUN_ToTop_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000002; -createNode animCurveTU -n "MGUN_Bod_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Bod_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.7384160023352093; -createNode animCurveTL -n "MGUN_Bod_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.4837587656993767; -createNode animCurveTL -n "MGUN_Bod_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.12284385827254347; -createNode animCurveTA -n "MGUN_Bod_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Bod_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Bod_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Bod_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Bod_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Bod_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 10.088378891733456; -createNode animCurveTL -n "MGUN_Connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.433273439350919; -createNode animCurveTL -n "MGUN_Connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.26979052810693338; -createNode animCurveTA -n "MGUN_Connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 184.55921161476257; -createNode animCurveTA -n "MGUN_Connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -29.104076635906718; -createNode animCurveTA -n "MGUN_Connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -156.52701371658429; -createNode animCurveTU -n "MGUN_Connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_guilight_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_guilight_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.203086144490312; -createNode animCurveTL -n "MGUN_guilight_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.1905144045116725; -createNode animCurveTL -n "MGUN_guilight_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.025163362666150487; -createNode animCurveTA -n "MGUN_guilight_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.44864236109062661; -createNode animCurveTA -n "MGUN_guilight_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -29.709107002120923; -createNode animCurveTA -n "MGUN_guilight_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.9683516885096406; -createNode animCurveTU -n "MGUN_guilight_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_guilight_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_guilight_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_flash_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_flash_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 14.403056995821359; -createNode animCurveTL -n "MGUN_flash_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.6019133872233553; -createNode animCurveTL -n "MGUN_flash_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.9425165276104304; -createNode animCurveTA -n "MGUN_flash_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.44864236109062661; -createNode animCurveTA -n "MGUN_flash_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -29.709107002120923; -createNode animCurveTA -n "MGUN_flash_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.9683516885096406; -createNode animCurveTU -n "MGUN_flash_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_flash_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_flash_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun1_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Gun1_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Gun1_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Gun1_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Gun1_pointConstraint1_Gun_ConstW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun1_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Gun1_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Gun1_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Gun1_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Gun1_orientConstraint1_Gun_ConstW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle2_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_ikHandle2_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle2_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_ikHandle2_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_pCube1_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_pCube1_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_pCube1_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_pCube1_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_pCube1_pointConstraint1_Hand_ConstW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lloarm1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.5843669248184606; -createNode animCurveTL -n "MGUN_Lloarm1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.4668580528710269; -createNode animCurveTL -n "MGUN_Lloarm1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.029944983560299319; -createNode animCurveTA -n "MGUN_Lloarm1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 15.398554121415428; -createNode animCurveTA -n "MGUN_Lloarm1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.2523918174358768; -createNode animCurveTA -n "MGUN_Lloarm1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.6806704463787199; -createNode animCurveTU -n "MGUN_Lloarm1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lloarm1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lhand1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.70478114446694362; -createNode animCurveTL -n "MGUN_Lhand1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.2509788706157714; -createNode animCurveTL -n "MGUN_Lhand1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.091389243282504598; -createNode animCurveTU -n "MGUN_Lhand1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Llothumb1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Llothumb1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.8908485888147197e-016; -createNode animCurveTL -n "MGUN_Llothumb1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.6111721441527558; -createNode animCurveTL -n "MGUN_Llothumb1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -6.9388939039072284e-018; -createNode animCurveTA -n "MGUN_Llothumb1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.5243924241537159; -createNode animCurveTA -n "MGUN_Llothumb1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 20.971053857540621; -createNode animCurveTA -n "MGUN_Llothumb1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 14.466112197356674; -createNode animCurveTU -n "MGUN_Llothumb1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Llothumb1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Llothumb1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_base1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lthumb_base1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.84569557368448001; -createNode animCurveTL -n "MGUN_Lthumb_base1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0102059331689646; -createNode animCurveTL -n "MGUN_Lthumb_base1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.2460211197800608; -createNode animCurveTA -n "MGUN_Lthumb_base1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -44.4088351846544; -createNode animCurveTA -n "MGUN_Lthumb_base1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.0455439935253663; -createNode animCurveTA -n "MGUN_Lthumb_base1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -9.2983408930814111; -createNode animCurveTU -n "MGUN_Lthumb_base1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_base1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_base1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_tip1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lthumb_tip1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.65785048735561602; -createNode animCurveTL -n "MGUN_Lthumb_tip1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.89301665211837233; -createNode animCurveTL -n "MGUN_Lthumb_tip1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.2240059051709255; -createNode animCurveTA -n "MGUN_Lthumb_tip1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -9.1273966542671694; -createNode animCurveTA -n "MGUN_Lthumb_tip1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.0630675741043039; -createNode animCurveTA -n "MGUN_Lthumb_tip1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -17.604069150125401; -createNode animCurveTU -n "MGUN_Lthumb_tip1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_tip1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lthumb_tip1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LT1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LT1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.55925029872683363; -createNode animCurveTL -n "MGUN_LT1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.96247656811253601; -createNode animCurveTL -n "MGUN_LT1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.02163351609884006; -createNode animCurveTA -n "MGUN_LT1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LT1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LT1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_LT1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LT1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LT1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_base1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lindex_base1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.39625406489899645; -createNode animCurveTL -n "MGUN_Lindex_base1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.3867477363767935; -createNode animCurveTL -n "MGUN_Lindex_base1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.950206629111412; -createNode animCurveTA -n "MGUN_Lindex_base1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lindex_base1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lindex_base1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 45.133024472761669; -createNode animCurveTU -n "MGUN_Lindex_base1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_base1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_base1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Linkdex_mid1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Linkdex_mid1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.65589229936799853; -createNode animCurveTL -n "MGUN_Linkdex_mid1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.95563043090752642; -createNode animCurveTL -n "MGUN_Linkdex_mid1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.026607907257882743; -createNode animCurveTA -n "MGUN_Linkdex_mid1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.5554401750069307; -createNode animCurveTA -n "MGUN_Linkdex_mid1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -6.0476935949915633; -createNode animCurveTA -n "MGUN_Linkdex_mid1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 50.828663395704197; -createNode animCurveTU -n "MGUN_Linkdex_mid1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Linkdex_mid1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Linkdex_mid1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_tip1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lindex_tip1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.46804217727388625; -createNode animCurveTL -n "MGUN_Lindex_tip1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.69018997488469236; -createNode animCurveTL -n "MGUN_Lindex_tip1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.013475025682114096; -createNode animCurveTA -n "MGUN_Lindex_tip1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lindex_tip1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lindex_tip1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -15.883592568351734; -createNode animCurveTU -n "MGUN_Lindex_tip1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_tip1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lindex_tip1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LI1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LI1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.61770409714098029; -createNode animCurveTL -n "MGUN_LI1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.69113574154321522; -createNode animCurveTL -n "MGUN_LI1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.0021453992795084391; -createNode animCurveTA -n "MGUN_LI1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LI1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LI1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_LI1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LI1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LI1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_base1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle_base1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.58143299157179507; -createNode animCurveTL -n "MGUN_Lmiddle_base1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.5849903848336484; -createNode animCurveTL -n "MGUN_Lmiddle_base1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3.4128414073494877; -createNode animCurveTA -n "MGUN_Lmiddle_base1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 10.244028408171902; -createNode animCurveTA -n "MGUN_Lmiddle_base1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -14.925042326130873; -createNode animCurveTA -n "MGUN_Lmiddle_base1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 59.875412505720249; -createNode animCurveTU -n "MGUN_Lmiddle_base1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_base1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_base1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_mid1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle_mid1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.64786317559594786; -createNode animCurveTL -n "MGUN_Lmiddle_mid1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.1566722400088016; -createNode animCurveTL -n "MGUN_Lmiddle_mid1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.037638525146715868; -createNode animCurveTA -n "MGUN_Lmiddle_mid1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.4728756756694907; -createNode animCurveTA -n "MGUN_Lmiddle_mid1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.8937353051836632; -createNode animCurveTA -n "MGUN_Lmiddle_mid1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 20.382046463429489; -createNode animCurveTU -n "MGUN_Lmiddle_mid1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_mid1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_mid1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_tip1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lmiddle_tip1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.4241372018849775; -createNode animCurveTL -n "MGUN_Lmiddle_tip1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.72525777140048575; -createNode animCurveTL -n "MGUN_Lmiddle_tip1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.0073811807745909957; -createNode animCurveTA -n "MGUN_Lmiddle_tip1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.084502128679647084; -createNode animCurveTA -n "MGUN_Lmiddle_tip1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.40684975751409264; -createNode animCurveTA -n "MGUN_Lmiddle_tip1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -51.670115761375698; -createNode animCurveTU -n "MGUN_Lmiddle_tip1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_tip1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lmiddle_tip1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LM1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LM1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.70731012500759682; -createNode animCurveTL -n "MGUN_LM1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0057919826032879; -createNode animCurveTL -n "MGUN_LM1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.017397413611068332; -createNode animCurveTA -n "MGUN_LM1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LM1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LM1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_LM1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LM1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LM1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_base1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky_base1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.6361565011204429; -createNode animCurveTL -n "MGUN_Lpinky_base1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.2376343738825733; -createNode animCurveTL -n "MGUN_Lpinky_base1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.9886264114509293; -createNode animCurveTA -n "MGUN_Lpinky_base1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 12.673904883747753; -createNode animCurveTA -n "MGUN_Lpinky_base1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.9080790012157016; -createNode animCurveTA -n "MGUN_Lpinky_base1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 15.162814766841485; -createNode animCurveTU -n "MGUN_Lpinky_base1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_base1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_base1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_mid1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky_mid1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.35616517659776342; -createNode animCurveTL -n "MGUN_Lpinky_mid1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.7248925706533399; -createNode animCurveTL -n "MGUN_Lpinky_mid1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.17507679160514406; -createNode animCurveTA -n "MGUN_Lpinky_mid1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -8.7874396783171989; -createNode animCurveTA -n "MGUN_Lpinky_mid1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.28885800697746; -createNode animCurveTA -n "MGUN_Lpinky_mid1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 27.206907108340452; -createNode animCurveTU -n "MGUN_Lpinky_mid1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_mid1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_mid1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_tip1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lpinky_tip1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.43327640087154745; -createNode animCurveTL -n "MGUN_Lpinky_tip1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.66313900324850228; -createNode animCurveTL -n "MGUN_Lpinky_tip1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.13766124231482524; -createNode animCurveTA -n "MGUN_Lpinky_tip1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lpinky_tip1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lpinky_tip1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -43.22127904117157; -createNode animCurveTU -n "MGUN_Lpinky_tip1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_tip1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lpinky_tip1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LP1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LP1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.52908619534301482; -createNode animCurveTL -n "MGUN_LP1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.60129947523247174; -createNode animCurveTL -n "MGUN_LP1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.14190935754551867; -createNode animCurveTA -n "MGUN_LP1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LP1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LP1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_LP1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LP1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LP1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_base1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lring_base1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0960266176063866; -createNode animCurveTL -n "MGUN_Lring_base1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.92767515759004915; -createNode animCurveTL -n "MGUN_Lring_base1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3.3860546815876655; -createNode animCurveTA -n "MGUN_Lring_base1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.5783022054368185; -createNode animCurveTA -n "MGUN_Lring_base1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.8010282664427946; -createNode animCurveTA -n "MGUN_Lring_base1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 51.028316808755143; -createNode animCurveTU -n "MGUN_Lring_base1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_base1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_base1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_mid1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lring_mid1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.56060733335278889; -createNode animCurveTL -n "MGUN_Lring_mid1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0508423175733979; -createNode animCurveTL -n "MGUN_Lring_mid1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.020798355657650949; -createNode animCurveTA -n "MGUN_Lring_mid1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lring_mid1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -22.220308610160757; -createNode animCurveTA -n "MGUN_Lring_mid1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 25.970189613902374; -createNode animCurveTU -n "MGUN_Lring_mid1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_mid1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_mid1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_tiip1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Lring_tiip1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.4279572606098147; -createNode animCurveTL -n "MGUN_Lring_tiip1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.76952015436871946; -createNode animCurveTL -n "MGUN_Lring_tiip1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.0073576783683653342; -createNode animCurveTA -n "MGUN_Lring_tiip1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.89202131442937549; -createNode animCurveTA -n "MGUN_Lring_tiip1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 17.159748139820071; -createNode animCurveTA -n "MGUN_Lring_tiip1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -50.829632973400699; -createNode animCurveTU -n "MGUN_Lring_tiip1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_tiip1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lring_tiip1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LR1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LR1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.71383458139311318; -createNode animCurveTL -n "MGUN_LR1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.88280437138944978; -createNode animCurveTL -n "MGUN_LR1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.027634441194869717; -createNode animCurveTA -n "MGUN_LR1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LR1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_LR1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_LR1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LR1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_LR1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Lhand_orientConstraint2_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint2_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint2_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Lhand_orientConstraint2_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator12_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator12_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.6099781764099258; -createNode animCurveTL -n "MGUN_locator12_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.05328910365139003; -createNode animCurveTL -n "MGUN_locator12_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.74441452563638755; -createNode animCurveTA -n "MGUN_locator12_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 15.680788712338803; -createNode animCurveTA -n "MGUN_locator12_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -47.51813011278341; -createNode animCurveTA -n "MGUN_locator12_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 30.85197096266624; -createNode animCurveTU -n "MGUN_locator12_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.6292426104807984; -createNode animCurveTU -n "MGUN_locator12_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.6292426104807989; -createNode animCurveTU -n "MGUN_locator12_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.6292426104807993; -createNode animCurveTU -n "MGUN_effector1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_effector1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_effector1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_effector1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_effector1_hideDisplay"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_locator11_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator11_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.6412044098427464; -createNode animCurveTL -n "MGUN_locator11_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.6404940201014764; -createNode animCurveTL -n "MGUN_locator11_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.3079669473746907; -createNode animCurveTA -n "MGUN_locator11_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.6843893727596475; -createNode animCurveTA -n "MGUN_locator11_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3.8301616494454134; -createNode animCurveTA -n "MGUN_locator11_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -179.15263870142536; -createNode animCurveTU -n "MGUN_locator11_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000002; -createNode animCurveTU -n "MGUN_locator11_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator11_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rhand1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.35899742808788115; -createNode animCurveTL -n "MGUN_Rhand1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 7.2852720089126581; -createNode animCurveTL -n "MGUN_Rhand1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rhand1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11a_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex11a_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.71177976781668506; -createNode animCurveTL -n "MGUN_Rindex11a_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 3.03054627590737; -createNode animCurveTL -n "MGUN_Rindex11a_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.029048475768120505; -createNode animCurveTA -n "MGUN_Rindex11a_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.8964471269322198; -createNode animCurveTA -n "MGUN_Rindex11a_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.32593908850176778; -createNode animCurveTA -n "MGUN_Rindex11a_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.001640065752628; -createNode animCurveTU -n "MGUN_Rindex11a_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11a_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11a_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex11_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.019663142258196046; -createNode animCurveTL -n "MGUN_Rindex11_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.3326987683783194; -createNode animCurveTL -n "MGUN_Rindex11_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.099122416121371543; -createNode animCurveTA -n "MGUN_Rindex11_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -66.514851199768302; -createNode animCurveTA -n "MGUN_Rindex11_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.5764868334373436; -createNode animCurveTA -n "MGUN_Rindex11_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -1.1829793720277602; -createNode animCurveTU -n "MGUN_Rindex11_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex11_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex21_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex21_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.0036189074961798877; -createNode animCurveTL -n "MGUN_Rindex21_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.79566015754876018; -createNode animCurveTL -n "MGUN_Rindex21_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.13699797440740269; -createNode animCurveTA -n "MGUN_Rindex21_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 52.952024582564967; -createNode animCurveTA -n "MGUN_Rindex21_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rindex21_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rindex21_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex21_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex21_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex31_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex31_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.017213943204127141; -createNode animCurveTL -n "MGUN_Rindex31_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.86389993795212727; -createNode animCurveTL -n "MGUN_Rindex31_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.035006750207567786; -createNode animCurveTA -n "MGUN_Rindex31_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rindex31_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rindex31_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rindex31_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex31_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rindex31_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb11_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb11_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.90763635715879143; -createNode animCurveTL -n "MGUN_Rthumb11_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.65376681357783784; -createNode animCurveTL -n "MGUN_Rthumb11_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.96806829679292483; -createNode animCurveTA -n "MGUN_Rthumb11_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -45.353676106284468; -createNode animCurveTA -n "MGUN_Rthumb11_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -29.678091936457527; -createNode animCurveTA -n "MGUN_Rthumb11_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.2082920477846049; -createNode animCurveTU -n "MGUN_Rthumb11_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb11_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb11_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb21_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb21_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.72610908572703259; -createNode animCurveTL -n "MGUN_Rthumb21_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.1770712597284088; -createNode animCurveTL -n "MGUN_Rthumb21_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.15205452190623614; -createNode animCurveTA -n "MGUN_Rthumb21_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.086563763860234; -createNode animCurveTA -n "MGUN_Rthumb21_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -11.622251840900596; -createNode animCurveTA -n "MGUN_Rthumb21_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 16.703200784620005; -createNode animCurveTU -n "MGUN_Rthumb21_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb21_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb21_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb31_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb31_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.34127860006749128; -createNode animCurveTL -n "MGUN_Rthumb31_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.92017605309139239; -createNode animCurveTL -n "MGUN_Rthumb31_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.066787604029035066; -createNode animCurveTA -n "MGUN_Rthumb31_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rthumb31_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rthumb31_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rthumb31_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb31_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb31_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb41_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb41_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.61868267562904211; -createNode animCurveTL -n "MGUN_Rthumb41_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.53882332525929511; -createNode animCurveTL -n "MGUN_Rthumb41_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.092484732001751682; -createNode animCurveTA -n "MGUN_Rthumb41_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rthumb41_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rthumb41_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rthumb41_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb41_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rthumb41_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings11_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rfings11_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.49511965294275512; -createNode animCurveTL -n "MGUN_Rfings11_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.2557819336236413; -createNode animCurveTL -n "MGUN_Rfings11_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.47110416452233655; -createNode animCurveTA -n "MGUN_Rfings11_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 25.372804622035076; -createNode animCurveTA -n "MGUN_Rfings11_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.9990469855459683; -createNode animCurveTA -n "MGUN_Rfings11_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 8.6911830172485871; -createNode animCurveTU -n "MGUN_Rfings11_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings11_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings11_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings21_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rfings21_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -7.3955709864469857e-032; -createNode animCurveTL -n "MGUN_Rfings21_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.3794246248043434; -createNode animCurveTL -n "MGUN_Rfings21_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -5.4879177129790981e-032; -createNode animCurveTA -n "MGUN_Rfings21_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -7.5831601936684994; -createNode animCurveTA -n "MGUN_Rfings21_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 6.0126542830104999; -createNode animCurveTA -n "MGUN_Rfings21_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 7.8010154954928419; -createNode animCurveTU -n "MGUN_Rfings21_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings21_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings21_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings31_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rfings31_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.7733391199176196e-032; -createNode animCurveTL -n "MGUN_Rfings31_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.82095460007098331; -createNode animCurveTL -n "MGUN_Rfings31_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.6653345369377348e-016; -createNode animCurveTA -n "MGUN_Rfings31_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -2.5756232903377194; -createNode animCurveTA -n "MGUN_Rfings31_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rfings31_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rfings31_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings31_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings31_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings41_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rfings41_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.0075621828761642069; -createNode animCurveTL -n "MGUN_Rfings41_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0719852852948357; -createNode animCurveTL -n "MGUN_Rfings41_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.2353457634733325; -createNode animCurveTA -n "MGUN_Rfings41_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rfings41_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rfings41_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rfings41_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings41_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rfings41_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Rhand_orientConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_Rhand_orientConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Rhand_orientConstraint1_Hand_ConstW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator10_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator10_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.71637758261489315; -createNode animCurveTL -n "MGUN_locator10_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.11956580904807776; -createNode animCurveTL -n "MGUN_locator10_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.86796116173448201; -createNode animCurveTA -n "MGUN_locator10_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 125.36832641526476; -createNode animCurveTA -n "MGUN_locator10_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -53.590974837310789; -createNode animCurveTA -n "MGUN_locator10_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 131.90976549698905; -createNode animCurveTU -n "MGUN_locator10_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.2697268321591695; -createNode animCurveTU -n "MGUN_locator10_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.2697268321591713; -createNode animCurveTU -n "MGUN_locator10_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.2697268321591704; -createNode animCurveTU -n "MGUN_locator9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator9_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 4.8412929072316899; -createNode animCurveTL -n "MGUN_locator9_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -14.577044978311854; -createNode animCurveTL -n "MGUN_locator9_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.48875764181286169; -createNode animCurveTA -n "MGUN_locator9_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -17.277009660855079; -createNode animCurveTA -n "MGUN_locator9_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 60.958631151455627; -createNode animCurveTA -n "MGUN_locator9_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 13.266713714376493; -createNode animCurveTU -n "MGUN_locator9_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator9_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator9_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.0000000000000002; -createNode animCurveTU -n "MGUN_Gun_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Gun_Const_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.5162399936433365; -createNode animCurveTL -n "MGUN_Gun_Const_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 5.0041930333989519; -createNode animCurveTL -n "MGUN_Gun_Const_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.98414601048815642; -createNode animCurveTA -n "MGUN_Gun_Const_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -13.866191376426826; -createNode animCurveTA -n "MGUN_Gun_Const_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 15.389092500252614; -createNode animCurveTA -n "MGUN_Gun_Const_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 57.052148581103815; -createNode animCurveTU -n "MGUN_Gun_Const_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99999999999999978; -createNode animCurveTU -n "MGUN_Gun_Const_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99999999999999989; -createNode animCurveTU -n "MGUN_Gun_Const_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.99999999999999978; -createNode animCurveTU -n "MGUN_Hand_Const_pointConstraint1_nodeState"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Hand_Const_pointConstraint1_offsetX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Hand_Const_pointConstraint1_offsetY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_Hand_Const_pointConstraint1_offsetZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_Hand_Const_pointConstraint1_RhandW0"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "group1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "group1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "group1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "group1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "group1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "group1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "group1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "group1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "group1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "group1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_Gun1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Gun1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_ikHandle2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_ikHandle2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_ikHandle2_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.2151686573512743; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -0.6851138899732141; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0.49185116311684374; -createNode animCurveTU -n "MGUN_ikHandle2_offset"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle2_roll"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_ikHandle2_twist"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -295.64622228750477; -createNode animCurveTU -n "MGUN_origin_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_origin_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_origin_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_origin_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_origin_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_origin_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_origin_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator7_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -4; -createNode animCurveTL -n "MGUN_locator7_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 11; -createNode animCurveTL -n "MGUN_locator7_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -3; -createNode animCurveTA -n "MGUN_locator7_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_locator7_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -29.205417093903414; -createNode animCurveTA -n "MGUN_locator7_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_locator7_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator7_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_locator7_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -createNode animCurveTU -n "MGUN_Luparm1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 11 1 15 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Luparm1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.6369692232633397 11 1.7053662306747834 - 15 1.7974548057714133; -createNode animCurveTL -n "MGUN_Luparm1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -17.266426032487498 11 -17.266426032487498 - 15 -17.266426032487498; -createNode animCurveTL -n "MGUN_Luparm1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.5071342460324888 11 -6.8455357985195207 - 15 -4.8486341053670774; -createNode animCurveTA -n "MGUN_Luparm1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 96.721166009171725 11 79.970330734044836 - 15 71.871655742392761; -createNode animCurveTA -n "MGUN_Luparm1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.7881473868798032 11 37.600027594716387 - 15 39.118688692300303; -createNode animCurveTA -n "MGUN_Luparm1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -87.277944797210935 11 27.579134098613466 - 15 18.69150874895815; -createNode animCurveTU -n "MGUN_Luparm1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 11 1 15 1; -createNode animCurveTU -n "MGUN_Luparm1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 11 1 15 1; -createNode animCurveTU -n "MGUN_Luparm1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 11 1 15 1; -createNode animCurveTU -n "MGUN_Rloarm1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10 1 15 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Rloarm1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.5895682500307444 10 5.5895682500307444 - 15 5.5895682500307444; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "MGUN_Rloarm1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -21.710493028270307 10 -21.710493028270307 - 15 -21.710493028270307; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTL -n "MGUN_Rloarm1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.647843850981447 10 6.647843850981447 - 15 6.647843850981447; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "MGUN_Rloarm1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 37.057239686974988 10 23.858970583210471 - 15 23.858970583210471; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "MGUN_Rloarm1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -60.874516085120419 10 -12.978384796886047 - 15 -12.978384796886047; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTA -n "MGUN_Rloarm1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 57.818310035105256 10 1.3183589787639254 - 15 1.3183589787639254; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "MGUN_Rloarm1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10 1 15 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "MGUN_Rloarm1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10 1 15 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "MGUN_Rloarm1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 10 1 15 1; - setAttr -s 3 ".kit[0:2]" 3 9 9; - setAttr -s 3 ".kot[0:2]" 3 9 9; -createNode animCurveTU -n "MGUN_group2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_group2_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_group2_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTL -n "MGUN_group2_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group2_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group2_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTA -n "MGUN_group2_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 0; -createNode animCurveTU -n "MGUN_group2_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.2269298281147605; -createNode animCurveTU -n "MGUN_group2_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.2269298281147605; -createNode animCurveTU -n "MGUN_group2_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1.2269298281147605; -createNode animCurveTU -n "MGUN_polySurface14_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 18.248571701804728; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -20.558540398701673; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.6757355999372985; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 175.04694820912425; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -25.021230763542317; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 -155.53426393850688; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.9044411307187503; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.9044411307187503; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 2.9044411307187503; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_CONNECT"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 15 1; -select -ne :time1; - setAttr ".o" 8; -select -ne :renderPartition; - setAttr -s 48 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 48 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 22 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 22 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -select -ne MGUN_locator7; -select -ne MGUN_Luparm1; - setAttr ".jo" -type "double3" -5.1813023882114697 57.718690249501776 -78.774352458193619 ; -select -ne MGUN_Rloarm1; - setAttr ".jo" -type "double3" -162.71850162818336 0 90 ; -select -ne MGUN_Hand_Const; -connectAttr "MGUN_polySurface23_visibility.o" "MGUN_polySurface23.v"; -connectAttr "MGUN_polySurface24_visibility.o" "MGUN_polySurface24.v"; -connectAttr "MGUN_polySurface25_visibility.o" "MGUN_polySurface25.v"; -connectAttr "MGUN_polySurface26_visibility.o" "MGUN_polySurface26.v"; -connectAttr "MGUN_ejectconnector_visibility.o" "MGUN_ejectconnector.v"; -connectAttr "MGUN_ejectconnector_scaleX.o" "MGUN_ejectconnector.sx"; -connectAttr "MGUN_ejectconnector_scaleY.o" "MGUN_ejectconnector.sy"; -connectAttr "MGUN_ejectconnector_scaleZ.o" "MGUN_ejectconnector.sz"; -connectAttr "MGUN_locator8_pointConstraint1_nodeState.o" "MGUN_locator8_pointConstraint1.nds" - ; -connectAttr "MGUN_locator8_pointConstraint1_ExtW0.o" "MGUN_locator8_pointConstraint1.w0" - ; -connectAttr "MGUN_locator8_pointConstraint1_offsetX.o" "MGUN_locator8_pointConstraint1.ox" - ; -connectAttr "MGUN_locator8_pointConstraint1_offsetY.o" "MGUN_locator8_pointConstraint1.oy" - ; -connectAttr "MGUN_locator8_pointConstraint1_offsetZ.o" "MGUN_locator8_pointConstraint1.oz" - ; -connectAttr "MGUN_locator8_orientConstraint1_nodeState.o" "MGUN_locator8_orientConstraint1.nds" - ; -connectAttr "MGUN_locator8_orientConstraint1_ExtW0.o" "MGUN_locator8_orientConstraint1.w0" - ; -connectAttr "MGUN_locator8_orientConstraint1_offsetX.o" "MGUN_locator8_orientConstraint1.ox" - ; -connectAttr "MGUN_locator8_orientConstraint1_offsetY.o" "MGUN_locator8_orientConstraint1.oy" - ; -connectAttr "MGUN_locator8_orientConstraint1_offsetZ.o" "MGUN_locator8_orientConstraint1.oz" - ; -connectAttr "MGUN_group3_visibility.o" "MGUN_group3.v"; -connectAttr "MGUN_group3_translateX.o" "MGUN_group3.tx"; -connectAttr "MGUN_group3_translateY.o" "MGUN_group3.ty"; -connectAttr "MGUN_group3_translateZ.o" "MGUN_group3.tz"; -connectAttr "MGUN_group3_rotateX.o" "MGUN_group3.rx"; -connectAttr "MGUN_group3_rotateY.o" "MGUN_group3.ry"; -connectAttr "MGUN_group3_rotateZ.o" "MGUN_group3.rz"; -connectAttr "MGUN_group3_scaleX.o" "MGUN_group3.sx"; -connectAttr "MGUN_group3_scaleY.o" "MGUN_group3.sy"; -connectAttr "MGUN_group3_scaleZ.o" "MGUN_group3.sz"; -connectAttr "MGUN_meshes_visibility.o" "MGUN_meshes.v"; -connectAttr "MGUN_meshes_translateX.o" "MGUN_meshes.tx"; -connectAttr "MGUN_meshes_translateY.o" "MGUN_meshes.ty"; -connectAttr "MGUN_meshes_translateZ.o" "MGUN_meshes.tz"; -connectAttr "MGUN_meshes_rotateX.o" "MGUN_meshes.rx"; -connectAttr "MGUN_meshes_rotateY.o" "MGUN_meshes.ry"; -connectAttr "MGUN_meshes_rotateZ.o" "MGUN_meshes.rz"; -connectAttr "MGUN_meshes_scaleX.o" "MGUN_meshes.sx"; -connectAttr "MGUN_meshes_scaleY.o" "MGUN_meshes.sy"; -connectAttr "MGUN_meshes_scaleZ.o" "MGUN_meshes.sz"; -connectAttr "MGUN_Ruparmmesh_visibility.o" "MGUN_Ruparmmesh.v"; -connectAttr "MGUN_Luparmmesh_visibility.o" "MGUN_Luparmmesh.v"; -connectAttr "MGUN_lelbow1_visibility.o" "MGUN_lelbow1.v"; -connectAttr "MGUN_lelbow1_scaleX.o" "MGUN_lelbow1.sx"; -connectAttr "MGUN_lelbow1_scaleY.o" "MGUN_lelbow1.sy"; -connectAttr "MGUN_lelbow1_scaleZ.o" "MGUN_lelbow1.sz"; -connectAttr "MGUN_lelbow1_pointConstraint1_nodeState.o" "MGUN_lelbow1_pointConstraint1.nds" - ; -connectAttr "MGUN_lelbow1_pointConstraint1_LwristW0.o" "MGUN_lelbow1_pointConstraint1.w0" - ; -connectAttr "MGUN_lelbow1_pointConstraint1_offsetX.o" "MGUN_lelbow1_pointConstraint1.ox" - ; -connectAttr "MGUN_lelbow1_pointConstraint1_offsetY.o" "MGUN_lelbow1_pointConstraint1.oy" - ; -connectAttr "MGUN_lelbow1_pointConstraint1_offsetZ.o" "MGUN_lelbow1_pointConstraint1.oz" - ; -connectAttr "MGUN_lelbow1_orientConstraint1_nodeState.o" "MGUN_lelbow1_orientConstraint1.nds" - ; -connectAttr "MGUN_lelbow1_orientConstraint1_LwristW0.o" "MGUN_lelbow1_orientConstraint1.w0" - ; -connectAttr "MGUN_lelbow1_orientConstraint1_offsetX.o" "MGUN_lelbow1_orientConstraint1.ox" - ; -connectAttr "MGUN_lelbow1_orientConstraint1_offsetY.o" "MGUN_lelbow1_orientConstraint1.oy" - ; -connectAttr "MGUN_lelbow1_orientConstraint1_offsetZ.o" "MGUN_lelbow1_orientConstraint1.oz" - ; -connectAttr "MGUN_relbow1_visibility.o" "MGUN_relbow1.v"; -connectAttr "MGUN_relbow1_scaleX.o" "MGUN_relbow1.sx"; -connectAttr "MGUN_relbow1_scaleY.o" "MGUN_relbow1.sy"; -connectAttr "MGUN_relbow1_scaleZ.o" "MGUN_relbow1.sz"; -connectAttr "MGUN_relbow1_pointConstraint1_nodeState.o" "MGUN_relbow1_pointConstraint1.nds" - ; -connectAttr "MGUN_relbow1_pointConstraint1_RwristW0.o" "MGUN_relbow1_pointConstraint1.w0" - ; -connectAttr "MGUN_relbow1_pointConstraint1_offsetX.o" "MGUN_relbow1_pointConstraint1.ox" - ; -connectAttr "MGUN_relbow1_pointConstraint1_offsetY.o" "MGUN_relbow1_pointConstraint1.oy" - ; -connectAttr "MGUN_relbow1_pointConstraint1_offsetZ.o" "MGUN_relbow1_pointConstraint1.oz" - ; -connectAttr "MGUN_relbow1_orientConstraint1_nodeState.o" "MGUN_relbow1_orientConstraint1.nds" - ; -connectAttr "MGUN_relbow1_orientConstraint1_RwristW0.o" "MGUN_relbow1_orientConstraint1.w0" - ; -connectAttr "MGUN_relbow1_orientConstraint1_offsetX.o" "MGUN_relbow1_orientConstraint1.ox" - ; -connectAttr "MGUN_relbow1_orientConstraint1_offsetY.o" "MGUN_relbow1_orientConstraint1.oy" - ; -connectAttr "MGUN_relbow1_orientConstraint1_offsetZ.o" "MGUN_relbow1_orientConstraint1.oz" - ; -connectAttr "MGUN_relbow2_visibility.o" "MGUN_relbow2.v"; -connectAttr "MGUN_relbow2_translateX.o" "MGUN_relbow2.tx"; -connectAttr "MGUN_relbow2_translateY.o" "MGUN_relbow2.ty"; -connectAttr "MGUN_relbow2_translateZ.o" "MGUN_relbow2.tz"; -connectAttr "MGUN_relbow2_rotateX.o" "MGUN_relbow2.rx"; -connectAttr "MGUN_relbow2_rotateY.o" "MGUN_relbow2.ry"; -connectAttr "MGUN_relbow2_rotateZ.o" "MGUN_relbow2.rz"; -connectAttr "MGUN_relbow2_scaleX.o" "MGUN_relbow2.sx"; -connectAttr "MGUN_relbow2_scaleY.o" "MGUN_relbow2.sy"; -connectAttr "MGUN_relbow2_scaleZ.o" "MGUN_relbow2.sz"; -connectAttr "MGUN_Luparm_scaleX.o" "MGUN_Luparm.sx"; -connectAttr "MGUN_Luparm_scaleY.o" "MGUN_Luparm.sy"; -connectAttr "MGUN_Luparm_scaleZ.o" "MGUN_Luparm.sz"; -connectAttr "MGUN_Luparm_visibility.o" "MGUN_Luparm.v"; -connectAttr "MGUN_Luparm_rotateX.o" "MGUN_Luparm.rx"; -connectAttr "MGUN_Luparm_rotateY.o" "MGUN_Luparm.ry"; -connectAttr "MGUN_Luparm_rotateZ.o" "MGUN_Luparm.rz"; -connectAttr "MGUN_Lloarm_scaleX.o" "MGUN_Lloarm.sx"; -connectAttr "MGUN_Lloarm_scaleY.o" "MGUN_Lloarm.sy"; -connectAttr "MGUN_Lloarm_scaleZ.o" "MGUN_Lloarm.sz"; -connectAttr "MGUN_Lloarm_visibility.o" "MGUN_Lloarm.v"; -connectAttr "MGUN_Lloarm_translateX.o" "MGUN_Lloarm.tx"; -connectAttr "MGUN_Lloarm_translateY.o" "MGUN_Lloarm.ty"; -connectAttr "MGUN_Lloarm_translateZ.o" "MGUN_Lloarm.tz"; -connectAttr "MGUN_Lloarm_rotateX.o" "MGUN_Lloarm.rx"; -connectAttr "MGUN_Lloarm_rotateY.o" "MGUN_Lloarm.ry"; -connectAttr "MGUN_Lloarm_rotateZ.o" "MGUN_Lloarm.rz"; -connectAttr "MGUN_Lwrist_translateX.o" "MGUN_Lwrist.tx"; -connectAttr "MGUN_Lwrist_translateY.o" "MGUN_Lwrist.ty"; -connectAttr "MGUN_Lwrist_translateZ.o" "MGUN_Lwrist.tz"; -connectAttr "MGUN_Lwrist_rotateX.o" "MGUN_Lwrist.rx"; -connectAttr "MGUN_Lwrist_rotateY.o" "MGUN_Lwrist.ry"; -connectAttr "MGUN_Lwrist_rotateZ.o" "MGUN_Lwrist.rz"; -connectAttr "MGUN_Lwrist_scaleX.o" "MGUN_Lwrist.sx"; -connectAttr "MGUN_Lwrist_scaleY.o" "MGUN_Lwrist.sy"; -connectAttr "MGUN_Lwrist_scaleZ.o" "MGUN_Lwrist.sz"; -connectAttr "MGUN_Lwrist_visibility.o" "MGUN_Lwrist.v"; -connectAttr "MGUN_Lhand_scaleX.o" "MGUN_Lhand.sx"; -connectAttr "MGUN_Lhand_scaleY.o" "MGUN_Lhand.sy"; -connectAttr "MGUN_Lhand_scaleZ.o" "MGUN_Lhand.sz"; -connectAttr "MGUN_Lhand_visibility.o" "MGUN_Lhand.v"; -connectAttr "MGUN_Lhand_translateX.o" "MGUN_Lhand.tx"; -connectAttr "MGUN_Lhand_translateY.o" "MGUN_Lhand.ty"; -connectAttr "MGUN_Lhand_translateZ.o" "MGUN_Lhand.tz"; -connectAttr "MGUN_Lthumb1_scaleX.o" "MGUN_Lthumb1.sx"; -connectAttr "MGUN_Lthumb1_scaleY.o" "MGUN_Lthumb1.sy"; -connectAttr "MGUN_Lthumb1_scaleZ.o" "MGUN_Lthumb1.sz"; -connectAttr "MGUN_Lthumb1_visibility.o" "MGUN_Lthumb1.v"; -connectAttr "MGUN_Lthumb1_translateX.o" "MGUN_Lthumb1.tx"; -connectAttr "MGUN_Lthumb1_translateY.o" "MGUN_Lthumb1.ty"; -connectAttr "MGUN_Lthumb1_translateZ.o" "MGUN_Lthumb1.tz"; -connectAttr "MGUN_Lthumb1_rotateX.o" "MGUN_Lthumb1.rx"; -connectAttr "MGUN_Lthumb1_rotateY.o" "MGUN_Lthumb1.ry"; -connectAttr "MGUN_Lthumb1_rotateZ.o" "MGUN_Lthumb1.rz"; -connectAttr "MGUN_Lthumb2_scaleX.o" "MGUN_Lthumb2.sx"; -connectAttr "MGUN_Lthumb2_scaleY.o" "MGUN_Lthumb2.sy"; -connectAttr "MGUN_Lthumb2_scaleZ.o" "MGUN_Lthumb2.sz"; -connectAttr "MGUN_Lthumb2_visibility.o" "MGUN_Lthumb2.v"; -connectAttr "MGUN_Lthumb2_translateX.o" "MGUN_Lthumb2.tx"; -connectAttr "MGUN_Lthumb2_translateY.o" "MGUN_Lthumb2.ty"; -connectAttr "MGUN_Lthumb2_translateZ.o" "MGUN_Lthumb2.tz"; -connectAttr "MGUN_Lthumb2_rotateX.o" "MGUN_Lthumb2.rx"; -connectAttr "MGUN_Lthumb2_rotateY.o" "MGUN_Lthumb2.ry"; -connectAttr "MGUN_Lthumb2_rotateZ.o" "MGUN_Lthumb2.rz"; -connectAttr "MGUN_Lthumb3_rotateY.o" "MGUN_Lthumb3.ry"; -connectAttr "MGUN_Lthumb3_rotateX.o" "MGUN_Lthumb3.rx"; -connectAttr "MGUN_Lthumb3_rotateZ.o" "MGUN_Lthumb3.rz"; -connectAttr "MGUN_Lthumb3_visibility.o" "MGUN_Lthumb3.v"; -connectAttr "MGUN_Lthumb3_translateX.o" "MGUN_Lthumb3.tx"; -connectAttr "MGUN_Lthumb3_translateY.o" "MGUN_Lthumb3.ty"; -connectAttr "MGUN_Lthumb3_translateZ.o" "MGUN_Lthumb3.tz"; -connectAttr "MGUN_Lthumb3_scaleX.o" "MGUN_Lthumb3.sx"; -connectAttr "MGUN_Lthumb3_scaleY.o" "MGUN_Lthumb3.sy"; -connectAttr "MGUN_Lthumb3_scaleZ.o" "MGUN_Lthumb3.sz"; -connectAttr "MGUN_Lindex1_scaleX.o" "MGUN_Lindex1.sx"; -connectAttr "MGUN_Lindex1_scaleY.o" "MGUN_Lindex1.sy"; -connectAttr "MGUN_Lindex1_scaleZ.o" "MGUN_Lindex1.sz"; -connectAttr "MGUN_Lindex1_visibility.o" "MGUN_Lindex1.v"; -connectAttr "MGUN_Lindex1_translateX.o" "MGUN_Lindex1.tx"; -connectAttr "MGUN_Lindex1_translateY.o" "MGUN_Lindex1.ty"; -connectAttr "MGUN_Lindex1_translateZ.o" "MGUN_Lindex1.tz"; -connectAttr "MGUN_Lindex1_rotateX.o" "MGUN_Lindex1.rx"; -connectAttr "MGUN_Lindex1_rotateY.o" "MGUN_Lindex1.ry"; -connectAttr "MGUN_Lindex1_rotateZ.o" "MGUN_Lindex1.rz"; -connectAttr "MGUN_Lindex2_scaleX.o" "MGUN_Lindex2.sx"; -connectAttr "MGUN_Lindex2_scaleY.o" "MGUN_Lindex2.sy"; -connectAttr "MGUN_Lindex2_scaleZ.o" "MGUN_Lindex2.sz"; -connectAttr "MGUN_Lindex2_visibility.o" "MGUN_Lindex2.v"; -connectAttr "MGUN_Lindex2_translateX.o" "MGUN_Lindex2.tx"; -connectAttr "MGUN_Lindex2_translateY.o" "MGUN_Lindex2.ty"; -connectAttr "MGUN_Lindex2_translateZ.o" "MGUN_Lindex2.tz"; -connectAttr "MGUN_Lindex2_rotateX.o" "MGUN_Lindex2.rx"; -connectAttr "MGUN_Lindex2_rotateY.o" "MGUN_Lindex2.ry"; -connectAttr "MGUN_Lindex2_rotateZ.o" "MGUN_Lindex2.rz"; -connectAttr "MGUN_Lindex3_visibility.o" "MGUN_Lindex3.v"; -connectAttr "MGUN_Lindex3_translateX.o" "MGUN_Lindex3.tx"; -connectAttr "MGUN_Lindex3_translateY.o" "MGUN_Lindex3.ty"; -connectAttr "MGUN_Lindex3_translateZ.o" "MGUN_Lindex3.tz"; -connectAttr "MGUN_Lindex3_rotateX.o" "MGUN_Lindex3.rx"; -connectAttr "MGUN_Lindex3_rotateY.o" "MGUN_Lindex3.ry"; -connectAttr "MGUN_Lindex3_rotateZ.o" "MGUN_Lindex3.rz"; -connectAttr "MGUN_Lindex3_scaleX.o" "MGUN_Lindex3.sx"; -connectAttr "MGUN_Lindex3_scaleY.o" "MGUN_Lindex3.sy"; -connectAttr "MGUN_Lindex3_scaleZ.o" "MGUN_Lindex3.sz"; -connectAttr "MGUN_Lmiddle1_scaleX.o" "MGUN_Lmiddle1.sx"; -connectAttr "MGUN_Lmiddle1_scaleY.o" "MGUN_Lmiddle1.sy"; -connectAttr "MGUN_Lmiddle1_scaleZ.o" "MGUN_Lmiddle1.sz"; -connectAttr "MGUN_Lmiddle1_visibility.o" "MGUN_Lmiddle1.v"; -connectAttr "MGUN_Lmiddle1_translateX.o" "MGUN_Lmiddle1.tx"; -connectAttr "MGUN_Lmiddle1_translateY.o" "MGUN_Lmiddle1.ty"; -connectAttr "MGUN_Lmiddle1_translateZ.o" "MGUN_Lmiddle1.tz"; -connectAttr "MGUN_Lmiddle1_rotateX.o" "MGUN_Lmiddle1.rx"; -connectAttr "MGUN_Lmiddle1_rotateY.o" "MGUN_Lmiddle1.ry"; -connectAttr "MGUN_Lmiddle1_rotateZ.o" "MGUN_Lmiddle1.rz"; -connectAttr "MGUN_Lmiddle2_scaleX.o" "MGUN_Lmiddle2.sx"; -connectAttr "MGUN_Lmiddle2_scaleY.o" "MGUN_Lmiddle2.sy"; -connectAttr "MGUN_Lmiddle2_scaleZ.o" "MGUN_Lmiddle2.sz"; -connectAttr "MGUN_Lmiddle2_visibility.o" "MGUN_Lmiddle2.v"; -connectAttr "MGUN_Lmiddle2_translateX.o" "MGUN_Lmiddle2.tx"; -connectAttr "MGUN_Lmiddle2_translateY.o" "MGUN_Lmiddle2.ty"; -connectAttr "MGUN_Lmiddle2_translateZ.o" "MGUN_Lmiddle2.tz"; -connectAttr "MGUN_Lmiddle2_rotateX.o" "MGUN_Lmiddle2.rx"; -connectAttr "MGUN_Lmiddle2_rotateY.o" "MGUN_Lmiddle2.ry"; -connectAttr "MGUN_Lmiddle2_rotateZ.o" "MGUN_Lmiddle2.rz"; -connectAttr "MGUN_Lmiddle3_visibility.o" "MGUN_Lmiddle3.v"; -connectAttr "MGUN_Lmiddle3_translateX.o" "MGUN_Lmiddle3.tx"; -connectAttr "MGUN_Lmiddle3_translateY.o" "MGUN_Lmiddle3.ty"; -connectAttr "MGUN_Lmiddle3_translateZ.o" "MGUN_Lmiddle3.tz"; -connectAttr "MGUN_Lmiddle3_rotateX.o" "MGUN_Lmiddle3.rx"; -connectAttr "MGUN_Lmiddle3_rotateY.o" "MGUN_Lmiddle3.ry"; -connectAttr "MGUN_Lmiddle3_rotateZ.o" "MGUN_Lmiddle3.rz"; -connectAttr "MGUN_Lmiddle3_scaleX.o" "MGUN_Lmiddle3.sx"; -connectAttr "MGUN_Lmiddle3_scaleY.o" "MGUN_Lmiddle3.sy"; -connectAttr "MGUN_Lmiddle3_scaleZ.o" "MGUN_Lmiddle3.sz"; -connectAttr "MGUN_Lring1_scaleX.o" "MGUN_Lring1.sx"; -connectAttr "MGUN_Lring1_scaleY.o" "MGUN_Lring1.sy"; -connectAttr "MGUN_Lring1_scaleZ.o" "MGUN_Lring1.sz"; -connectAttr "MGUN_Lring1_visibility.o" "MGUN_Lring1.v"; -connectAttr "MGUN_Lring1_translateX.o" "MGUN_Lring1.tx"; -connectAttr "MGUN_Lring1_translateY.o" "MGUN_Lring1.ty"; -connectAttr "MGUN_Lring1_translateZ.o" "MGUN_Lring1.tz"; -connectAttr "MGUN_Lring1_rotateX.o" "MGUN_Lring1.rx"; -connectAttr "MGUN_Lring1_rotateY.o" "MGUN_Lring1.ry"; -connectAttr "MGUN_Lring1_rotateZ.o" "MGUN_Lring1.rz"; -connectAttr "MGUN_Lring2_scaleX.o" "MGUN_Lring2.sx"; -connectAttr "MGUN_Lring2_scaleY.o" "MGUN_Lring2.sy"; -connectAttr "MGUN_Lring2_scaleZ.o" "MGUN_Lring2.sz"; -connectAttr "MGUN_Lring2_visibility.o" "MGUN_Lring2.v"; -connectAttr "MGUN_Lring2_translateX.o" "MGUN_Lring2.tx"; -connectAttr "MGUN_Lring2_translateY.o" "MGUN_Lring2.ty"; -connectAttr "MGUN_Lring2_translateZ.o" "MGUN_Lring2.tz"; -connectAttr "MGUN_Lring2_rotateX.o" "MGUN_Lring2.rx"; -connectAttr "MGUN_Lring2_rotateY.o" "MGUN_Lring2.ry"; -connectAttr "MGUN_Lring2_rotateZ.o" "MGUN_Lring2.rz"; -connectAttr "MGUN_Lrring3_visibility.o" "MGUN_Lrring3.v"; -connectAttr "MGUN_Lrring3_translateX.o" "MGUN_Lrring3.tx"; -connectAttr "MGUN_Lrring3_translateY.o" "MGUN_Lrring3.ty"; -connectAttr "MGUN_Lrring3_translateZ.o" "MGUN_Lrring3.tz"; -connectAttr "MGUN_Lrring3_rotateX.o" "MGUN_Lrring3.rx"; -connectAttr "MGUN_Lrring3_rotateY.o" "MGUN_Lrring3.ry"; -connectAttr "MGUN_Lrring3_rotateZ.o" "MGUN_Lrring3.rz"; -connectAttr "MGUN_Lrring3_scaleX.o" "MGUN_Lrring3.sx"; -connectAttr "MGUN_Lrring3_scaleY.o" "MGUN_Lrring3.sy"; -connectAttr "MGUN_Lrring3_scaleZ.o" "MGUN_Lrring3.sz"; -connectAttr "MGUN_Lpinky1_scaleX.o" "MGUN_Lpinky1.sx"; -connectAttr "MGUN_Lpinky1_scaleY.o" "MGUN_Lpinky1.sy"; -connectAttr "MGUN_Lpinky1_scaleZ.o" "MGUN_Lpinky1.sz"; -connectAttr "MGUN_Lpinky1_visibility.o" "MGUN_Lpinky1.v"; -connectAttr "MGUN_Lpinky1_translateX.o" "MGUN_Lpinky1.tx"; -connectAttr "MGUN_Lpinky1_translateY.o" "MGUN_Lpinky1.ty"; -connectAttr "MGUN_Lpinky1_translateZ.o" "MGUN_Lpinky1.tz"; -connectAttr "MGUN_Lpinky1_rotateX.o" "MGUN_Lpinky1.rx"; -connectAttr "MGUN_Lpinky1_rotateY.o" "MGUN_Lpinky1.ry"; -connectAttr "MGUN_Lpinky1_rotateZ.o" "MGUN_Lpinky1.rz"; -connectAttr "MGUN_Lpinky2_scaleX.o" "MGUN_Lpinky2.sx"; -connectAttr "MGUN_Lpinky2_scaleY.o" "MGUN_Lpinky2.sy"; -connectAttr "MGUN_Lpinky2_scaleZ.o" "MGUN_Lpinky2.sz"; -connectAttr "MGUN_Lpinky2_visibility.o" "MGUN_Lpinky2.v"; -connectAttr "MGUN_Lpinky2_translateX.o" "MGUN_Lpinky2.tx"; -connectAttr "MGUN_Lpinky2_translateY.o" "MGUN_Lpinky2.ty"; -connectAttr "MGUN_Lpinky2_translateZ.o" "MGUN_Lpinky2.tz"; -connectAttr "MGUN_Lpinky2_rotateX.o" "MGUN_Lpinky2.rx"; -connectAttr "MGUN_Lpinky2_rotateY.o" "MGUN_Lpinky2.ry"; -connectAttr "MGUN_Lpinky2_rotateZ.o" "MGUN_Lpinky2.rz"; -connectAttr "MGUN_Lpinky3_visibility.o" "MGUN_Lpinky3.v"; -connectAttr "MGUN_Lpinky3_translateX.o" "MGUN_Lpinky3.tx"; -connectAttr "MGUN_Lpinky3_translateY.o" "MGUN_Lpinky3.ty"; -connectAttr "MGUN_Lpinky3_translateZ.o" "MGUN_Lpinky3.tz"; -connectAttr "MGUN_Lpinky3_rotateX.o" "MGUN_Lpinky3.rx"; -connectAttr "MGUN_Lpinky3_rotateY.o" "MGUN_Lpinky3.ry"; -connectAttr "MGUN_Lpinky3_rotateZ.o" "MGUN_Lpinky3.rz"; -connectAttr "MGUN_Lpinky3_scaleX.o" "MGUN_Lpinky3.sx"; -connectAttr "MGUN_Lpinky3_scaleY.o" "MGUN_Lpinky3.sy"; -connectAttr "MGUN_Lpinky3_scaleZ.o" "MGUN_Lpinky3.sz"; -connectAttr "MGUN_Lhand_orientConstraint3_nodeState.o" "MGUN_Lhand_orientConstraint3.nds" - ; -connectAttr "MGUN_Lhand_orientConstraint3_offsetX.o" "MGUN_Lhand_orientConstraint3.ox" - ; -connectAttr "MGUN_Lhand_orientConstraint3_offsetY.o" "MGUN_Lhand_orientConstraint3.oy" - ; -connectAttr "MGUN_Lhand_orientConstraint3_offsetZ.o" "MGUN_Lhand_orientConstraint3.oz" - ; -connectAttr "MGUN_effector3_visibility.o" "MGUN_effector3.v"; -connectAttr "MGUN_effector3_rotateX.o" "MGUN_effector3.rx"; -connectAttr "MGUN_effector3_rotateY.o" "MGUN_effector3.ry"; -connectAttr "MGUN_effector3_rotateZ.o" "MGUN_effector3.rz"; -connectAttr "MGUN_effector3_scaleX.o" "MGUN_effector3.sx"; -connectAttr "MGUN_effector3_scaleY.o" "MGUN_effector3.sy"; -connectAttr "MGUN_effector3_scaleZ.o" "MGUN_effector3.sz"; -connectAttr "MGUN_effector3_hideDisplay.o" "MGUN_effector3.hd"; -connectAttr "MGUN_Luparm_pointConstraint2_nodeState.o" "MGUN_Luparm_pointConstraint2.nds" - ; -connectAttr "MGUN_Luparm_pointConstraint2_locator11W0.o" "MGUN_Luparm_pointConstraint2.w0" - ; -connectAttr "MGUN_Luparm_pointConstraint2_offsetX.o" "MGUN_Luparm_pointConstraint2.ox" - ; -connectAttr "MGUN_Luparm_pointConstraint2_offsetY.o" "MGUN_Luparm_pointConstraint2.oy" - ; -connectAttr "MGUN_Luparm_pointConstraint2_offsetZ.o" "MGUN_Luparm_pointConstraint2.oz" - ; -connectAttr "MGUN_Ruparm_scaleX.o" "MGUN_Ruparm.sx"; -connectAttr "MGUN_Ruparm_scaleY.o" "MGUN_Ruparm.sy"; -connectAttr "MGUN_Ruparm_scaleZ.o" "MGUN_Ruparm.sz"; -connectAttr "MGUN_Ruparm_visibility.o" "MGUN_Ruparm.v"; -connectAttr "MGUN_Ruparm_rotateX.o" "MGUN_Ruparm.rx"; -connectAttr "MGUN_Ruparm_rotateY.o" "MGUN_Ruparm.ry"; -connectAttr "MGUN_Ruparm_rotateZ.o" "MGUN_Ruparm.rz"; -connectAttr "MGUN_Rloarm_scaleX1.o" "MGUN_Rloarm.sx"; -connectAttr "MGUN_Rloarm_scaleY1.o" "MGUN_Rloarm.sy"; -connectAttr "MGUN_Rloarm_scaleZ1.o" "MGUN_Rloarm.sz"; -connectAttr "MGUN_Rloarm_visibility1.o" "MGUN_Rloarm.v"; -connectAttr "MGUN_Rloarm_translateX1.o" "MGUN_Rloarm.tx"; -connectAttr "MGUN_Rloarm_translateY1.o" "MGUN_Rloarm.ty"; -connectAttr "MGUN_Rloarm_translateZ1.o" "MGUN_Rloarm.tz"; -connectAttr "MGUN_Rloarm_rotateX1.o" "MGUN_Rloarm.rx"; -connectAttr "MGUN_Rloarm_rotateY1.o" "MGUN_Rloarm.ry"; -connectAttr "MGUN_Rloarm_rotateZ1.o" "MGUN_Rloarm.rz"; -connectAttr "MGUN_Rwrist_translateX.o" "MGUN_Rwrist.tx"; -connectAttr "MGUN_Rwrist_translateY.o" "MGUN_Rwrist.ty"; -connectAttr "MGUN_Rwrist_translateZ.o" "MGUN_Rwrist.tz"; -connectAttr "MGUN_Rwrist_rotateX.o" "MGUN_Rwrist.rx"; -connectAttr "MGUN_Rwrist_rotateY.o" "MGUN_Rwrist.ry"; -connectAttr "MGUN_Rwrist_rotateZ.o" "MGUN_Rwrist.rz"; -connectAttr "MGUN_Rwrist_scaleX.o" "MGUN_Rwrist.sx"; -connectAttr "MGUN_Rwrist_scaleY.o" "MGUN_Rwrist.sy"; -connectAttr "MGUN_Rwrist_scaleZ.o" "MGUN_Rwrist.sz"; -connectAttr "MGUN_Rwrist_visibility.o" "MGUN_Rwrist.v"; -connectAttr "MGUN_Rhand_scaleX.o" "MGUN_Rhand.sx"; -connectAttr "MGUN_Rhand_scaleY.o" "MGUN_Rhand.sy"; -connectAttr "MGUN_Rhand_scaleZ.o" "MGUN_Rhand.sz"; -connectAttr "MGUN_Rhand_visibility.o" "MGUN_Rhand.v"; -connectAttr "MGUN_Rhand_translateX.o" "MGUN_Rhand.tx"; -connectAttr "MGUN_Rhand_translateY.o" "MGUN_Rhand.ty"; -connectAttr "MGUN_Rhand_translateZ.o" "MGUN_Rhand.tz"; -connectAttr "MGUN_Rthumb1_scaleX.o" "MGUN_Rthumb1.sx"; -connectAttr "MGUN_Rthumb1_scaleY.o" "MGUN_Rthumb1.sy"; -connectAttr "MGUN_Rthumb1_scaleZ.o" "MGUN_Rthumb1.sz"; -connectAttr "MGUN_Rthumb1_visibility.o" "MGUN_Rthumb1.v"; -connectAttr "MGUN_Rthumb1_translateX.o" "MGUN_Rthumb1.tx"; -connectAttr "MGUN_Rthumb1_translateY.o" "MGUN_Rthumb1.ty"; -connectAttr "MGUN_Rthumb1_translateZ.o" "MGUN_Rthumb1.tz"; -connectAttr "MGUN_Rthumb1_rotateX.o" "MGUN_Rthumb1.rx"; -connectAttr "MGUN_Rthumb1_rotateY.o" "MGUN_Rthumb1.ry"; -connectAttr "MGUN_Rthumb1_rotateZ.o" "MGUN_Rthumb1.rz"; -connectAttr "MGUN_Rthumb2_scaleX.o" "MGUN_Rthumb2.sx"; -connectAttr "MGUN_Rthumb2_scaleY.o" "MGUN_Rthumb2.sy"; -connectAttr "MGUN_Rthumb2_scaleZ.o" "MGUN_Rthumb2.sz"; -connectAttr "MGUN_Rthumb2_visibility.o" "MGUN_Rthumb2.v"; -connectAttr "MGUN_Rthumb2_translateX.o" "MGUN_Rthumb2.tx"; -connectAttr "MGUN_Rthumb2_translateY.o" "MGUN_Rthumb2.ty"; -connectAttr "MGUN_Rthumb2_translateZ.o" "MGUN_Rthumb2.tz"; -connectAttr "MGUN_Rthumb2_rotateX.o" "MGUN_Rthumb2.rx"; -connectAttr "MGUN_Rthumb2_rotateY.o" "MGUN_Rthumb2.ry"; -connectAttr "MGUN_Rthumb2_rotateZ.o" "MGUN_Rthumb2.rz"; -connectAttr "MGUN_Rthumb3_visibility.o" "MGUN_Rthumb3.v"; -connectAttr "MGUN_Rthumb3_translateX.o" "MGUN_Rthumb3.tx"; -connectAttr "MGUN_Rthumb3_translateY.o" "MGUN_Rthumb3.ty"; -connectAttr "MGUN_Rthumb3_translateZ.o" "MGUN_Rthumb3.tz"; -connectAttr "MGUN_Rthumb3_rotateX.o" "MGUN_Rthumb3.rx"; -connectAttr "MGUN_Rthumb3_rotateY.o" "MGUN_Rthumb3.ry"; -connectAttr "MGUN_Rthumb3_rotateZ.o" "MGUN_Rthumb3.rz"; -connectAttr "MGUN_Rthumb3_scaleX.o" "MGUN_Rthumb3.sx"; -connectAttr "MGUN_Rthumb3_scaleY.o" "MGUN_Rthumb3.sy"; -connectAttr "MGUN_Rthumb3_scaleZ.o" "MGUN_Rthumb3.sz"; -connectAttr "MGUN_Rindex1_scaleX.o" "MGUN_Rindex1.sx"; -connectAttr "MGUN_Rindex1_scaleY.o" "MGUN_Rindex1.sy"; -connectAttr "MGUN_Rindex1_scaleZ.o" "MGUN_Rindex1.sz"; -connectAttr "MGUN_Rindex1_visibility.o" "MGUN_Rindex1.v"; -connectAttr "MGUN_Rindex1_translateX.o" "MGUN_Rindex1.tx"; -connectAttr "MGUN_Rindex1_translateY.o" "MGUN_Rindex1.ty"; -connectAttr "MGUN_Rindex1_translateZ.o" "MGUN_Rindex1.tz"; -connectAttr "MGUN_Rindex1_rotateX.o" "MGUN_Rindex1.rx"; -connectAttr "MGUN_Rindex1_rotateY.o" "MGUN_Rindex1.ry"; -connectAttr "MGUN_Rindex1_rotateZ.o" "MGUN_Rindex1.rz"; -connectAttr "MGUN_Rindex2_scaleX.o" "MGUN_Rindex2.sx"; -connectAttr "MGUN_Rindex2_scaleY.o" "MGUN_Rindex2.sy"; -connectAttr "MGUN_Rindex2_scaleZ.o" "MGUN_Rindex2.sz"; -connectAttr "MGUN_Rindex2_visibility.o" "MGUN_Rindex2.v"; -connectAttr "MGUN_Rindex2_translateX.o" "MGUN_Rindex2.tx"; -connectAttr "MGUN_Rindex2_translateY.o" "MGUN_Rindex2.ty"; -connectAttr "MGUN_Rindex2_translateZ.o" "MGUN_Rindex2.tz"; -connectAttr "MGUN_Rindex2_rotateX.o" "MGUN_Rindex2.rx"; -connectAttr "MGUN_Rindex2_rotateY.o" "MGUN_Rindex2.ry"; -connectAttr "MGUN_Rindex2_rotateZ.o" "MGUN_Rindex2.rz"; -connectAttr "MGUN_Rindex3_visibility.o" "MGUN_Rindex3.v"; -connectAttr "MGUN_Rindex3_translateX.o" "MGUN_Rindex3.tx"; -connectAttr "MGUN_Rindex3_translateY.o" "MGUN_Rindex3.ty"; -connectAttr "MGUN_Rindex3_translateZ.o" "MGUN_Rindex3.tz"; -connectAttr "MGUN_Rindex3_rotateX.o" "MGUN_Rindex3.rx"; -connectAttr "MGUN_Rindex3_rotateY.o" "MGUN_Rindex3.ry"; -connectAttr "MGUN_Rindex3_rotateZ.o" "MGUN_Rindex3.rz"; -connectAttr "MGUN_Rindex3_scaleX.o" "MGUN_Rindex3.sx"; -connectAttr "MGUN_Rindex3_scaleY.o" "MGUN_Rindex3.sy"; -connectAttr "MGUN_Rindex3_scaleZ.o" "MGUN_Rindex3.sz"; -connectAttr "MGUN_Rmiddle1_scaleX.o" "MGUN_Rmiddle1.sx"; -connectAttr "MGUN_Rmiddle1_scaleY.o" "MGUN_Rmiddle1.sy"; -connectAttr "MGUN_Rmiddle1_scaleZ.o" "MGUN_Rmiddle1.sz"; -connectAttr "MGUN_Rmiddle1_visibility.o" "MGUN_Rmiddle1.v"; -connectAttr "MGUN_Rmiddle1_translateX.o" "MGUN_Rmiddle1.tx"; -connectAttr "MGUN_Rmiddle1_translateY.o" "MGUN_Rmiddle1.ty"; -connectAttr "MGUN_Rmiddle1_translateZ.o" "MGUN_Rmiddle1.tz"; -connectAttr "MGUN_Rmiddle1_rotateX.o" "MGUN_Rmiddle1.rx"; -connectAttr "MGUN_Rmiddle1_rotateY.o" "MGUN_Rmiddle1.ry"; -connectAttr "MGUN_Rmiddle1_rotateZ.o" "MGUN_Rmiddle1.rz"; -connectAttr "MGUN_Rmiddle2_scaleX.o" "MGUN_Rmiddle2.sx"; -connectAttr "MGUN_Rmiddle2_scaleY.o" "MGUN_Rmiddle2.sy"; -connectAttr "MGUN_Rmiddle2_scaleZ.o" "MGUN_Rmiddle2.sz"; -connectAttr "MGUN_Rmiddle2_visibility.o" "MGUN_Rmiddle2.v"; -connectAttr "MGUN_Rmiddle2_translateX.o" "MGUN_Rmiddle2.tx"; -connectAttr "MGUN_Rmiddle2_translateY.o" "MGUN_Rmiddle2.ty"; -connectAttr "MGUN_Rmiddle2_translateZ.o" "MGUN_Rmiddle2.tz"; -connectAttr "MGUN_Rmiddle2_rotateX.o" "MGUN_Rmiddle2.rx"; -connectAttr "MGUN_Rmiddle2_rotateY.o" "MGUN_Rmiddle2.ry"; -connectAttr "MGUN_Rmiddle2_rotateZ.o" "MGUN_Rmiddle2.rz"; -connectAttr "MGUN_Rmiddle3_visibility.o" "MGUN_Rmiddle3.v"; -connectAttr "MGUN_Rmiddle3_translateX.o" "MGUN_Rmiddle3.tx"; -connectAttr "MGUN_Rmiddle3_translateY.o" "MGUN_Rmiddle3.ty"; -connectAttr "MGUN_Rmiddle3_translateZ.o" "MGUN_Rmiddle3.tz"; -connectAttr "MGUN_Rmiddle3_rotateX.o" "MGUN_Rmiddle3.rx"; -connectAttr "MGUN_Rmiddle3_rotateY.o" "MGUN_Rmiddle3.ry"; -connectAttr "MGUN_Rmiddle3_rotateZ.o" "MGUN_Rmiddle3.rz"; -connectAttr "MGUN_Rmiddle3_scaleX.o" "MGUN_Rmiddle3.sx"; -connectAttr "MGUN_Rmiddle3_scaleY.o" "MGUN_Rmiddle3.sy"; -connectAttr "MGUN_Rmiddle3_scaleZ.o" "MGUN_Rmiddle3.sz"; -connectAttr "MGUN_Rring1_scaleX.o" "MGUN_Rring1.sx"; -connectAttr "MGUN_Rring1_scaleY.o" "MGUN_Rring1.sy"; -connectAttr "MGUN_Rring1_scaleZ.o" "MGUN_Rring1.sz"; -connectAttr "MGUN_Rring1_visibility.o" "MGUN_Rring1.v"; -connectAttr "MGUN_Rring1_translateX.o" "MGUN_Rring1.tx"; -connectAttr "MGUN_Rring1_translateY.o" "MGUN_Rring1.ty"; -connectAttr "MGUN_Rring1_translateZ.o" "MGUN_Rring1.tz"; -connectAttr "MGUN_Rring1_rotateX.o" "MGUN_Rring1.rx"; -connectAttr "MGUN_Rring1_rotateY.o" "MGUN_Rring1.ry"; -connectAttr "MGUN_Rring1_rotateZ.o" "MGUN_Rring1.rz"; -connectAttr "MGUN_Rring2_scaleX.o" "MGUN_Rring2.sx"; -connectAttr "MGUN_Rring2_scaleY.o" "MGUN_Rring2.sy"; -connectAttr "MGUN_Rring2_scaleZ.o" "MGUN_Rring2.sz"; -connectAttr "MGUN_Rring2_visibility.o" "MGUN_Rring2.v"; -connectAttr "MGUN_Rring2_translateX.o" "MGUN_Rring2.tx"; -connectAttr "MGUN_Rring2_translateY.o" "MGUN_Rring2.ty"; -connectAttr "MGUN_Rring2_translateZ.o" "MGUN_Rring2.tz"; -connectAttr "MGUN_Rring2_rotateX.o" "MGUN_Rring2.rx"; -connectAttr "MGUN_Rring2_rotateY.o" "MGUN_Rring2.ry"; -connectAttr "MGUN_Rring2_rotateZ.o" "MGUN_Rring2.rz"; -connectAttr "MGUN_Rrring3_visibility.o" "MGUN_Rrring3.v"; -connectAttr "MGUN_Rrring3_translateX.o" "MGUN_Rrring3.tx"; -connectAttr "MGUN_Rrring3_translateY.o" "MGUN_Rrring3.ty"; -connectAttr "MGUN_Rrring3_translateZ.o" "MGUN_Rrring3.tz"; -connectAttr "MGUN_Rrring3_rotateX.o" "MGUN_Rrring3.rx"; -connectAttr "MGUN_Rrring3_rotateY.o" "MGUN_Rrring3.ry"; -connectAttr "MGUN_Rrring3_rotateZ.o" "MGUN_Rrring3.rz"; -connectAttr "MGUN_Rrring3_scaleX.o" "MGUN_Rrring3.sx"; -connectAttr "MGUN_Rrring3_scaleY.o" "MGUN_Rrring3.sy"; -connectAttr "MGUN_Rrring3_scaleZ.o" "MGUN_Rrring3.sz"; -connectAttr "MGUN_Rpinky1_scaleX.o" "MGUN_Rpinky1.sx"; -connectAttr "MGUN_Rpinky1_scaleY.o" "MGUN_Rpinky1.sy"; -connectAttr "MGUN_Rpinky1_scaleZ.o" "MGUN_Rpinky1.sz"; -connectAttr "MGUN_Rpinky1_visibility.o" "MGUN_Rpinky1.v"; -connectAttr "MGUN_Rpinky1_translateX.o" "MGUN_Rpinky1.tx"; -connectAttr "MGUN_Rpinky1_translateY.o" "MGUN_Rpinky1.ty"; -connectAttr "MGUN_Rpinky1_translateZ.o" "MGUN_Rpinky1.tz"; -connectAttr "MGUN_Rpinky1_rotateX.o" "MGUN_Rpinky1.rx"; -connectAttr "MGUN_Rpinky1_rotateY.o" "MGUN_Rpinky1.ry"; -connectAttr "MGUN_Rpinky1_rotateZ.o" "MGUN_Rpinky1.rz"; -connectAttr "MGUN_Rpinky2_scaleX.o" "MGUN_Rpinky2.sx"; -connectAttr "MGUN_Rpinky2_scaleY.o" "MGUN_Rpinky2.sy"; -connectAttr "MGUN_Rpinky2_scaleZ.o" "MGUN_Rpinky2.sz"; -connectAttr "MGUN_Rpinky2_visibility.o" "MGUN_Rpinky2.v"; -connectAttr "MGUN_Rpinky2_translateX.o" "MGUN_Rpinky2.tx"; -connectAttr "MGUN_Rpinky2_translateY.o" "MGUN_Rpinky2.ty"; -connectAttr "MGUN_Rpinky2_translateZ.o" "MGUN_Rpinky2.tz"; -connectAttr "MGUN_Rpinky2_rotateX.o" "MGUN_Rpinky2.rx"; -connectAttr "MGUN_Rpinky2_rotateY.o" "MGUN_Rpinky2.ry"; -connectAttr "MGUN_Rpinky2_rotateZ.o" "MGUN_Rpinky2.rz"; -connectAttr "MGUN_Rpinky3_visibility.o" "MGUN_Rpinky3.v"; -connectAttr "MGUN_Rpinky3_translateX.o" "MGUN_Rpinky3.tx"; -connectAttr "MGUN_Rpinky3_translateY.o" "MGUN_Rpinky3.ty"; -connectAttr "MGUN_Rpinky3_translateZ.o" "MGUN_Rpinky3.tz"; -connectAttr "MGUN_Rpinky3_rotateX.o" "MGUN_Rpinky3.rx"; -connectAttr "MGUN_Rpinky3_rotateY.o" "MGUN_Rpinky3.ry"; -connectAttr "MGUN_Rpinky3_rotateZ.o" "MGUN_Rpinky3.rz"; -connectAttr "MGUN_Rpinky3_scaleX.o" "MGUN_Rpinky3.sx"; -connectAttr "MGUN_Rpinky3_scaleY.o" "MGUN_Rpinky3.sy"; -connectAttr "MGUN_Rpinky3_scaleZ.o" "MGUN_Rpinky3.sz"; -connectAttr "MGUN_Rhand_orientConstraint2_nodeState.o" "MGUN_Rhand_orientConstraint2.nds" - ; -connectAttr "MGUN_Rhand_orientConstraint2_locator10W0.o" "MGUN_Rhand_orientConstraint2.w0" - ; -connectAttr "MGUN_Rhand_orientConstraint2_offsetX.o" "MGUN_Rhand_orientConstraint2.ox" - ; -connectAttr "MGUN_Rhand_orientConstraint2_offsetY.o" "MGUN_Rhand_orientConstraint2.oy" - ; -connectAttr "MGUN_Rhand_orientConstraint2_offsetZ.o" "MGUN_Rhand_orientConstraint2.oz" - ; -connectAttr "MGUN_effector2_visibility.o" "MGUN_effector2.v"; -connectAttr "MGUN_effector2_rotateX.o" "MGUN_effector2.rx"; -connectAttr "MGUN_effector2_rotateY.o" "MGUN_effector2.ry"; -connectAttr "MGUN_effector2_rotateZ.o" "MGUN_effector2.rz"; -connectAttr "MGUN_effector2_scaleX.o" "MGUN_effector2.sx"; -connectAttr "MGUN_effector2_scaleY.o" "MGUN_effector2.sy"; -connectAttr "MGUN_effector2_scaleZ.o" "MGUN_effector2.sz"; -connectAttr "MGUN_effector2_hideDisplay.o" "MGUN_effector2.hd"; -connectAttr "MGUN_Ruparm_pointConstraint1_nodeState.o" "MGUN_Ruparm_pointConstraint1.nds" - ; -connectAttr "MGUN_Ruparm_pointConstraint1_locator9W0.o" "MGUN_Ruparm_pointConstraint1.w0" - ; -connectAttr "MGUN_Ruparm_pointConstraint1_offsetX.o" "MGUN_Ruparm_pointConstraint1.ox" - ; -connectAttr "MGUN_Ruparm_pointConstraint1_offsetY.o" "MGUN_Ruparm_pointConstraint1.oy" - ; -connectAttr "MGUN_Ruparm_pointConstraint1_offsetZ.o" "MGUN_Ruparm_pointConstraint1.oz" - ; -connectAttr "MGUN_ikHandle3_visibility.o" "MGUN_ikHandle3.v"; -connectAttr "MGUN_ikHandle3_rotateX.o" "MGUN_ikHandle3.rx"; -connectAttr "MGUN_ikHandle3_rotateY.o" "MGUN_ikHandle3.ry"; -connectAttr "MGUN_ikHandle3_rotateZ.o" "MGUN_ikHandle3.rz"; -connectAttr "MGUN_ikHandle3_scaleX.o" "MGUN_ikHandle3.sx"; -connectAttr "MGUN_ikHandle3_scaleY.o" "MGUN_ikHandle3.sy"; -connectAttr "MGUN_ikHandle3_scaleZ.o" "MGUN_ikHandle3.sz"; -connectAttr "MGUN_ikHandle3_solverEnable.o" "MGUN_ikHandle3.hse"; -connectAttr "MGUN_ikHandle3_poleVectorX.o" "MGUN_ikHandle3.pvx"; -connectAttr "MGUN_ikHandle3_poleVectorY.o" "MGUN_ikHandle3.pvy"; -connectAttr "MGUN_ikHandle3_poleVectorZ.o" "MGUN_ikHandle3.pvz"; -connectAttr "MGUN_ikHandle3_offset.o" "MGUN_ikHandle3.off"; -connectAttr "MGUN_ikHandle3_roll.o" "MGUN_ikHandle3.rol"; -connectAttr "MGUN_ikHandle3_twist.o" "MGUN_ikHandle3.twi"; -connectAttr "MGUN_ikHandle3_pointConstraint1_nodeState.o" "MGUN_ikHandle3_pointConstraint1.nds" - ; -connectAttr "MGUN_ikHandle3_pointConstraint1_locator10W0.o" "MGUN_ikHandle3_pointConstraint1.w0" - ; -connectAttr "MGUN_ikHandle3_pointConstraint1_offsetX.o" "MGUN_ikHandle3_pointConstraint1.ox" - ; -connectAttr "MGUN_ikHandle3_pointConstraint1_offsetY.o" "MGUN_ikHandle3_pointConstraint1.oy" - ; -connectAttr "MGUN_ikHandle3_pointConstraint1_offsetZ.o" "MGUN_ikHandle3_pointConstraint1.oz" - ; -connectAttr "MGUN_ikHandle4_visibility.o" "MGUN_ikHandle4.v"; -connectAttr "MGUN_ikHandle4_rotateX.o" "MGUN_ikHandle4.rx"; -connectAttr "MGUN_ikHandle4_rotateY.o" "MGUN_ikHandle4.ry"; -connectAttr "MGUN_ikHandle4_rotateZ.o" "MGUN_ikHandle4.rz"; -connectAttr "MGUN_ikHandle4_scaleX.o" "MGUN_ikHandle4.sx"; -connectAttr "MGUN_ikHandle4_scaleY.o" "MGUN_ikHandle4.sy"; -connectAttr "MGUN_ikHandle4_scaleZ.o" "MGUN_ikHandle4.sz"; -connectAttr "MGUN_ikHandle4_solverEnable.o" "MGUN_ikHandle4.hse"; -connectAttr "MGUN_ikHandle4_poleVectorX.o" "MGUN_ikHandle4.pvx"; -connectAttr "MGUN_ikHandle4_poleVectorY.o" "MGUN_ikHandle4.pvy"; -connectAttr "MGUN_ikHandle4_poleVectorZ.o" "MGUN_ikHandle4.pvz"; -connectAttr "MGUN_ikHandle4_offset.o" "MGUN_ikHandle4.off"; -connectAttr "MGUN_ikHandle4_roll.o" "MGUN_ikHandle4.rol"; -connectAttr "MGUN_ikHandle4_twist.o" "MGUN_ikHandle4.twi"; -connectAttr "MGUN_ikHandle4_pointConstraint1_nodeState.o" "MGUN_ikHandle4_pointConstraint1.nds" - ; -connectAttr "MGUN_ikHandle4_pointConstraint1_offsetX.o" "MGUN_ikHandle4_pointConstraint1.ox" - ; -connectAttr "MGUN_ikHandle4_pointConstraint1_offsetY.o" "MGUN_ikHandle4_pointConstraint1.oy" - ; -connectAttr "MGUN_ikHandle4_pointConstraint1_offsetZ.o" "MGUN_ikHandle4_pointConstraint1.oz" - ; -connectAttr "MGUN_fx1_visibility.o" "MGUN_fx1.v"; -connectAttr "MGUN_fx2_visibility.o" "MGUN_fx2.v"; -connectAttr "MGUN_fx3_visibility.o" "MGUN_fx3.v"; -connectAttr "MGUN_fx4_visibility.o" "MGUN_fx4.v"; -connectAttr "MGUN_locator13_visibility.o" "MGUN_locator13.v"; -connectAttr "MGUN_locator13_scaleX.o" "MGUN_locator13.sx"; -connectAttr "MGUN_locator13_scaleY.o" "MGUN_locator13.sy"; -connectAttr "MGUN_locator13_scaleZ.o" "MGUN_locator13.sz"; -connectAttr "MGUN_locator13_pointConstraint1_nodeState.o" "MGUN_locator13_pointConstraint1.nds" - ; -connectAttr "MGUN_locator13_pointConstraint1_BodW0.o" "MGUN_locator13_pointConstraint1.w0" - ; -connectAttr "MGUN_locator13_pointConstraint1_offsetX.o" "MGUN_locator13_pointConstraint1.ox" - ; -connectAttr "MGUN_locator13_pointConstraint1_offsetY.o" "MGUN_locator13_pointConstraint1.oy" - ; -connectAttr "MGUN_locator13_pointConstraint1_offsetZ.o" "MGUN_locator13_pointConstraint1.oz" - ; -connectAttr "MGUN_locator13_orientConstraint1_nodeState.o" "MGUN_locator13_orientConstraint1.nds" - ; -connectAttr "MGUN_locator13_orientConstraint1_BodW0.o" "MGUN_locator13_orientConstraint1.w0" - ; -connectAttr "MGUN_locator13_orientConstraint1_offsetX.o" "MGUN_locator13_orientConstraint1.ox" - ; -connectAttr "MGUN_locator13_orientConstraint1_offsetY.o" "MGUN_locator13_orientConstraint1.oy" - ; -connectAttr "MGUN_locator13_orientConstraint1_offsetZ.o" "MGUN_locator13_orientConstraint1.oz" - ; -connectAttr "MGUN_barrel_visibility.o" "MGUN_barrel.v"; -connectAttr "MGUN_barrel_translateX.o" "MGUN_barrel.tx"; -connectAttr "MGUN_barrel_translateY.o" "MGUN_barrel.ty"; -connectAttr "MGUN_barrel_translateZ.o" "MGUN_barrel.tz"; -connectAttr "MGUN_barrel_rotateX.o" "MGUN_barrel.rx"; -connectAttr "MGUN_barrel_rotateY.o" "MGUN_barrel.ry"; -connectAttr "MGUN_barrel_rotateZ.o" "MGUN_barrel.rz"; -connectAttr "MGUN_barrel_scaleX.o" "MGUN_barrel.sx"; -connectAttr "MGUN_barrel_scaleY.o" "MGUN_barrel.sy"; -connectAttr "MGUN_barrel_scaleZ.o" "MGUN_barrel.sz"; -connectAttr "MGUN_Gun1_visibility.o" "MGUN_Gun1.v"; -connectAttr "MGUN_Gun1_scaleX.o" "MGUN_Gun1.sx"; -connectAttr "MGUN_Gun1_scaleY.o" "MGUN_Gun1.sy"; -connectAttr "MGUN_Gun1_scaleZ.o" "MGUN_Gun1.sz"; -connectAttr "MGUN_Gun2_visibility.o" "MGUN_Gun2.v"; -connectAttr "MGUN_Gun2_translateX.o" "MGUN_Gun2.tx"; -connectAttr "MGUN_Gun2_translateY.o" "MGUN_Gun2.ty"; -connectAttr "MGUN_Gun2_translateZ.o" "MGUN_Gun2.tz"; -connectAttr "MGUN_Gun2_rotateX.o" "MGUN_Gun2.rx"; -connectAttr "MGUN_Gun2_rotateY.o" "MGUN_Gun2.ry"; -connectAttr "MGUN_Gun2_rotateZ.o" "MGUN_Gun2.rz"; -connectAttr "MGUN_Gun2_scaleX.o" "MGUN_Gun2.sx"; -connectAttr "MGUN_Gun2_scaleY.o" "MGUN_Gun2.sy"; -connectAttr "MGUN_Gun2_scaleZ.o" "MGUN_Gun2.sz"; -connectAttr "MGUN_Trig_visibility.o" "MGUN_Trig.v"; -connectAttr "MGUN_Trig_translateX.o" "MGUN_Trig.tx"; -connectAttr "MGUN_Trig_translateY.o" "MGUN_Trig.ty"; -connectAttr "MGUN_Trig_translateZ.o" "MGUN_Trig.tz"; -connectAttr "MGUN_Trig_rotateX.o" "MGUN_Trig.rx"; -connectAttr "MGUN_Trig_rotateY.o" "MGUN_Trig.ry"; -connectAttr "MGUN_Trig_rotateZ.o" "MGUN_Trig.rz"; -connectAttr "MGUN_Trig_scaleX.o" "MGUN_Trig.sx"; -connectAttr "MGUN_Trig_scaleY.o" "MGUN_Trig.sy"; -connectAttr "MGUN_Trig_scaleZ.o" "MGUN_Trig.sz"; -connectAttr "MGUN_Ext_scaleX.o" "MGUN_Ext.sx"; -connectAttr "MGUN_Ext_scaleY.o" "MGUN_Ext.sy"; -connectAttr "MGUN_Ext_scaleZ.o" "MGUN_Ext.sz"; -connectAttr "MGUN_Ext_translateX.o" "MGUN_Ext.tx"; -connectAttr "MGUN_Ext_translateY.o" "MGUN_Ext.ty"; -connectAttr "MGUN_Ext_translateZ.o" "MGUN_Ext.tz"; -connectAttr "MGUN_Ext_rotateX.o" "MGUN_Ext.rx"; -connectAttr "MGUN_Ext_rotateY.o" "MGUN_Ext.ry"; -connectAttr "MGUN_Ext_rotateZ.o" "MGUN_Ext.rz"; -connectAttr "MGUN_Ext_visibility.o" "MGUN_Ext.v"; -connectAttr "MGUN_Cli_visibility.o" "MGUN_Cli.v"; -connectAttr "MGUN_Cli_translateX.o" "MGUN_Cli.tx"; -connectAttr "MGUN_Cli_translateY.o" "MGUN_Cli.ty"; -connectAttr "MGUN_Cli_translateZ.o" "MGUN_Cli.tz"; -connectAttr "MGUN_Cli_rotateX.o" "MGUN_Cli.rx"; -connectAttr "MGUN_Cli_rotateY.o" "MGUN_Cli.ry"; -connectAttr "MGUN_Cli_rotateZ.o" "MGUN_Cli.rz"; -connectAttr "MGUN_Cli_scaleX.o" "MGUN_Cli.sx"; -connectAttr "MGUN_Cli_scaleY.o" "MGUN_Cli.sy"; -connectAttr "MGUN_Cli_scaleZ.o" "MGUN_Cli.sz"; -connectAttr "MGUN_ToTop_rotateX.o" "MGUN_ToTop.rx"; -connectAttr "MGUN_ToTop_rotateY.o" "MGUN_ToTop.ry"; -connectAttr "MGUN_ToTop_rotateZ.o" "MGUN_ToTop.rz"; -connectAttr "MGUN_ToTop_translateX.o" "MGUN_ToTop.tx"; -connectAttr "MGUN_ToTop_translateY.o" "MGUN_ToTop.ty"; -connectAttr "MGUN_ToTop_translateZ.o" "MGUN_ToTop.tz"; -connectAttr "MGUN_ToTop_visibility.o" "MGUN_ToTop.v"; -connectAttr "MGUN_ToTop_scaleX.o" "MGUN_ToTop.sx"; -connectAttr "MGUN_ToTop_scaleY.o" "MGUN_ToTop.sy"; -connectAttr "MGUN_ToTop_scaleZ.o" "MGUN_ToTop.sz"; -connectAttr "MGUN_Bod_translateX.o" "MGUN_Bod.tx"; -connectAttr "MGUN_Bod_translateY.o" "MGUN_Bod.ty"; -connectAttr "MGUN_Bod_translateZ.o" "MGUN_Bod.tz"; -connectAttr "MGUN_Bod_rotateX.o" "MGUN_Bod.rx"; -connectAttr "MGUN_Bod_rotateY.o" "MGUN_Bod.ry"; -connectAttr "MGUN_Bod_rotateZ.o" "MGUN_Bod.rz"; -connectAttr "MGUN_Bod_visibility.o" "MGUN_Bod.v"; -connectAttr "MGUN_Bod_scaleX.o" "MGUN_Bod.sx"; -connectAttr "MGUN_Bod_scaleY.o" "MGUN_Bod.sy"; -connectAttr "MGUN_Bod_scaleZ.o" "MGUN_Bod.sz"; -connectAttr "MGUN_Connector_translateX.o" "MGUN_Connector.tx"; -connectAttr "MGUN_Connector_translateY.o" "MGUN_Connector.ty"; -connectAttr "MGUN_Connector_translateZ.o" "MGUN_Connector.tz"; -connectAttr "MGUN_Connector_rotateX.o" "MGUN_Connector.rx"; -connectAttr "MGUN_Connector_rotateY.o" "MGUN_Connector.ry"; -connectAttr "MGUN_Connector_rotateZ.o" "MGUN_Connector.rz"; -connectAttr "MGUN_Connector_visibility.o" "MGUN_Connector.v"; -connectAttr "MGUN_Connector_scaleX.o" "MGUN_Connector.sx"; -connectAttr "MGUN_Connector_scaleY.o" "MGUN_Connector.sy"; -connectAttr "MGUN_Connector_scaleZ.o" "MGUN_Connector.sz"; -connectAttr "MGUN_guilight_visibility.o" "MGUN_guilight.v"; -connectAttr "MGUN_guilight_translateX.o" "MGUN_guilight.tx"; -connectAttr "MGUN_guilight_translateY.o" "MGUN_guilight.ty"; -connectAttr "MGUN_guilight_translateZ.o" "MGUN_guilight.tz"; -connectAttr "MGUN_guilight_rotateX.o" "MGUN_guilight.rx"; -connectAttr "MGUN_guilight_rotateY.o" "MGUN_guilight.ry"; -connectAttr "MGUN_guilight_rotateZ.o" "MGUN_guilight.rz"; -connectAttr "MGUN_guilight_scaleX.o" "MGUN_guilight.sx"; -connectAttr "MGUN_guilight_scaleY.o" "MGUN_guilight.sy"; -connectAttr "MGUN_guilight_scaleZ.o" "MGUN_guilight.sz"; -connectAttr "MGUN_flash_visibility.o" "MGUN_flash.v"; -connectAttr "MGUN_flash_translateX.o" "MGUN_flash.tx"; -connectAttr "MGUN_flash_translateY.o" "MGUN_flash.ty"; -connectAttr "MGUN_flash_translateZ.o" "MGUN_flash.tz"; -connectAttr "MGUN_flash_rotateX.o" "MGUN_flash.rx"; -connectAttr "MGUN_flash_rotateY.o" "MGUN_flash.ry"; -connectAttr "MGUN_flash_rotateZ.o" "MGUN_flash.rz"; -connectAttr "MGUN_flash_scaleX.o" "MGUN_flash.sx"; -connectAttr "MGUN_flash_scaleY.o" "MGUN_flash.sy"; -connectAttr "MGUN_flash_scaleZ.o" "MGUN_flash.sz"; -connectAttr "MGUN_Gun1_pointConstraint1_nodeState.o" "MGUN_Gun1_pointConstraint1.nds" - ; -connectAttr "MGUN_Gun1_pointConstraint1_Gun_ConstW0.o" "MGUN_Gun1_pointConstraint1.w0" - ; -connectAttr "MGUN_Gun1_pointConstraint1_offsetX.o" "MGUN_Gun1_pointConstraint1.ox" - ; -connectAttr "MGUN_Gun1_pointConstraint1_offsetY.o" "MGUN_Gun1_pointConstraint1.oy" - ; -connectAttr "MGUN_Gun1_pointConstraint1_offsetZ.o" "MGUN_Gun1_pointConstraint1.oz" - ; -connectAttr "MGUN_Gun1_orientConstraint1_nodeState.o" "MGUN_Gun1_orientConstraint1.nds" - ; -connectAttr "MGUN_Gun1_orientConstraint1_Gun_ConstW0.o" "MGUN_Gun1_orientConstraint1.w0" - ; -connectAttr "MGUN_Gun1_orientConstraint1_offsetX.o" "MGUN_Gun1_orientConstraint1.ox" - ; -connectAttr "MGUN_Gun1_orientConstraint1_offsetY.o" "MGUN_Gun1_orientConstraint1.oy" - ; -connectAttr "MGUN_Gun1_orientConstraint1_offsetZ.o" "MGUN_Gun1_orientConstraint1.oz" - ; -connectAttr "MGUN_ikHandle2_visibility.o" "MGUN_ikHandle2.v"; -connectAttr "MGUN_ikHandle2_rotateX.o" "MGUN_ikHandle2.rx"; -connectAttr "MGUN_ikHandle2_rotateY.o" "MGUN_ikHandle2.ry"; -connectAttr "MGUN_ikHandle2_rotateZ.o" "MGUN_ikHandle2.rz"; -connectAttr "MGUN_ikHandle2_scaleX.o" "MGUN_ikHandle2.sx"; -connectAttr "MGUN_ikHandle2_scaleY.o" "MGUN_ikHandle2.sy"; -connectAttr "MGUN_ikHandle2_scaleZ.o" "MGUN_ikHandle2.sz"; -connectAttr "MGUN_ikHandle2_solverEnable.o" "MGUN_ikHandle2.hse"; -connectAttr "MGUN_ikHandle2_poleVectorX.o" "MGUN_ikHandle2.pvx"; -connectAttr "MGUN_ikHandle2_poleVectorY.o" "MGUN_ikHandle2.pvy"; -connectAttr "MGUN_ikHandle2_poleVectorZ.o" "MGUN_ikHandle2.pvz"; -connectAttr "MGUN_ikHandle2_offset.o" "MGUN_ikHandle2.off"; -connectAttr "MGUN_ikHandle2_roll.o" "MGUN_ikHandle2.rol"; -connectAttr "MGUN_ikHandle2_twist.o" "MGUN_ikHandle2.twi"; -connectAttr "MGUN_ikHandle2_pointConstraint1_nodeState.o" "MGUN_ikHandle2_pointConstraint1.nds" - ; -connectAttr "MGUN_ikHandle2_pointConstraint1_offsetX.o" "MGUN_ikHandle2_pointConstraint1.ox" - ; -connectAttr "MGUN_ikHandle2_pointConstraint1_offsetY.o" "MGUN_ikHandle2_pointConstraint1.oy" - ; -connectAttr "MGUN_ikHandle2_pointConstraint1_offsetZ.o" "MGUN_ikHandle2_pointConstraint1.oz" - ; -connectAttr "MGUN_origin_visibility.o" "MGUN_origin.v"; -connectAttr "MGUN_origin_rotateX.o" "MGUN_origin.rx"; -connectAttr "MGUN_origin_rotateY.o" "MGUN_origin.ry"; -connectAttr "MGUN_origin_rotateZ.o" "MGUN_origin.rz"; -connectAttr "MGUN_origin_scaleX.o" "MGUN_origin.sx"; -connectAttr "MGUN_origin_scaleY.o" "MGUN_origin.sy"; -connectAttr "MGUN_origin_scaleZ.o" "MGUN_origin.sz"; -connectAttr "MGUN_pCube1_pointConstraint1_nodeState.o" "MGUN_pCube1_pointConstraint1.nds" - ; -connectAttr "MGUN_pCube1_pointConstraint1_Hand_ConstW0.o" "MGUN_pCube1_pointConstraint1.w0" - ; -connectAttr "MGUN_pCube1_pointConstraint1_offsetX.o" "MGUN_pCube1_pointConstraint1.ox" - ; -connectAttr "MGUN_pCube1_pointConstraint1_offsetY.o" "MGUN_pCube1_pointConstraint1.oy" - ; -connectAttr "MGUN_pCube1_pointConstraint1_offsetZ.o" "MGUN_pCube1_pointConstraint1.oz" - ; -connectAttr "MGUN_locator7_translateX.o" "MGUN_locator7.tx"; -connectAttr "MGUN_locator7_translateY.o" "MGUN_locator7.ty"; -connectAttr "MGUN_locator7_translateZ.o" "MGUN_locator7.tz"; -connectAttr "MGUN_locator7_rotateX.o" "MGUN_locator7.rx"; -connectAttr "MGUN_locator7_rotateY.o" "MGUN_locator7.ry"; -connectAttr "MGUN_locator7_rotateZ.o" "MGUN_locator7.rz"; -connectAttr "MGUN_locator7_visibility.o" "MGUN_locator7.v"; -connectAttr "MGUN_locator7_scaleX.o" "MGUN_locator7.sx"; -connectAttr "MGUN_locator7_scaleY.o" "MGUN_locator7.sy"; -connectAttr "MGUN_locator7_scaleZ.o" "MGUN_locator7.sz"; -connectAttr "MGUN_Luparm1_scaleX.o" "MGUN_Luparm1.sx"; -connectAttr "MGUN_Luparm1_scaleY.o" "MGUN_Luparm1.sy"; -connectAttr "MGUN_Luparm1_scaleZ.o" "MGUN_Luparm1.sz"; -connectAttr "MGUN_Luparm1_visibility.o" "MGUN_Luparm1.v"; -connectAttr "MGUN_Luparm1_translateX.o" "MGUN_Luparm1.tx"; -connectAttr "MGUN_Luparm1_translateY.o" "MGUN_Luparm1.ty"; -connectAttr "MGUN_Luparm1_translateZ.o" "MGUN_Luparm1.tz"; -connectAttr "MGUN_Luparm1_rotateX.o" "MGUN_Luparm1.rx"; -connectAttr "MGUN_Luparm1_rotateY.o" "MGUN_Luparm1.ry"; -connectAttr "MGUN_Luparm1_rotateZ.o" "MGUN_Luparm1.rz"; -connectAttr "MGUN_Lloarm1_scaleX.o" "MGUN_Lloarm1.sx"; -connectAttr "MGUN_Lloarm1_scaleY.o" "MGUN_Lloarm1.sy"; -connectAttr "MGUN_Lloarm1_scaleZ.o" "MGUN_Lloarm1.sz"; -connectAttr "MGUN_Lloarm1_visibility.o" "MGUN_Lloarm1.v"; -connectAttr "MGUN_Lloarm1_translateX.o" "MGUN_Lloarm1.tx"; -connectAttr "MGUN_Lloarm1_translateY.o" "MGUN_Lloarm1.ty"; -connectAttr "MGUN_Lloarm1_translateZ.o" "MGUN_Lloarm1.tz"; -connectAttr "MGUN_Lloarm1_rotateX.o" "MGUN_Lloarm1.rx"; -connectAttr "MGUN_Lloarm1_rotateY.o" "MGUN_Lloarm1.ry"; -connectAttr "MGUN_Lloarm1_rotateZ.o" "MGUN_Lloarm1.rz"; -connectAttr "MGUN_Lhand1_scaleX.o" "MGUN_Lhand1.sx"; -connectAttr "MGUN_Lhand1_scaleY.o" "MGUN_Lhand1.sy"; -connectAttr "MGUN_Lhand1_scaleZ.o" "MGUN_Lhand1.sz"; -connectAttr "MGUN_Lhand1_translateX.o" "MGUN_Lhand1.tx"; -connectAttr "MGUN_Lhand1_translateY.o" "MGUN_Lhand1.ty"; -connectAttr "MGUN_Lhand1_translateZ.o" "MGUN_Lhand1.tz"; -connectAttr "MGUN_Lhand1_visibility.o" "MGUN_Lhand1.v"; -connectAttr "MGUN_Llothumb1_scaleX.o" "MGUN_Llothumb1.sx"; -connectAttr "MGUN_Llothumb1_scaleY.o" "MGUN_Llothumb1.sy"; -connectAttr "MGUN_Llothumb1_scaleZ.o" "MGUN_Llothumb1.sz"; -connectAttr "MGUN_Llothumb1_visibility.o" "MGUN_Llothumb1.v"; -connectAttr "MGUN_Llothumb1_translateX.o" "MGUN_Llothumb1.tx"; -connectAttr "MGUN_Llothumb1_translateY.o" "MGUN_Llothumb1.ty"; -connectAttr "MGUN_Llothumb1_translateZ.o" "MGUN_Llothumb1.tz"; -connectAttr "MGUN_Llothumb1_rotateX.o" "MGUN_Llothumb1.rx"; -connectAttr "MGUN_Llothumb1_rotateY.o" "MGUN_Llothumb1.ry"; -connectAttr "MGUN_Llothumb1_rotateZ.o" "MGUN_Llothumb1.rz"; -connectAttr "MGUN_Lthumb_base1_scaleX.o" "MGUN_Lthumb_base1.sx"; -connectAttr "MGUN_Lthumb_base1_scaleY.o" "MGUN_Lthumb_base1.sy"; -connectAttr "MGUN_Lthumb_base1_scaleZ.o" "MGUN_Lthumb_base1.sz"; -connectAttr "MGUN_Lthumb_base1_visibility.o" "MGUN_Lthumb_base1.v"; -connectAttr "MGUN_Lthumb_base1_translateX.o" "MGUN_Lthumb_base1.tx"; -connectAttr "MGUN_Lthumb_base1_translateY.o" "MGUN_Lthumb_base1.ty"; -connectAttr "MGUN_Lthumb_base1_translateZ.o" "MGUN_Lthumb_base1.tz"; -connectAttr "MGUN_Lthumb_base1_rotateX.o" "MGUN_Lthumb_base1.rx"; -connectAttr "MGUN_Lthumb_base1_rotateY.o" "MGUN_Lthumb_base1.ry"; -connectAttr "MGUN_Lthumb_base1_rotateZ.o" "MGUN_Lthumb_base1.rz"; -connectAttr "MGUN_Lthumb_tip1_scaleX.o" "MGUN_Lthumb_tip1.sx"; -connectAttr "MGUN_Lthumb_tip1_scaleY.o" "MGUN_Lthumb_tip1.sy"; -connectAttr "MGUN_Lthumb_tip1_scaleZ.o" "MGUN_Lthumb_tip1.sz"; -connectAttr "MGUN_Lthumb_tip1_visibility.o" "MGUN_Lthumb_tip1.v"; -connectAttr "MGUN_Lthumb_tip1_translateX.o" "MGUN_Lthumb_tip1.tx"; -connectAttr "MGUN_Lthumb_tip1_translateY.o" "MGUN_Lthumb_tip1.ty"; -connectAttr "MGUN_Lthumb_tip1_translateZ.o" "MGUN_Lthumb_tip1.tz"; -connectAttr "MGUN_Lthumb_tip1_rotateX.o" "MGUN_Lthumb_tip1.rx"; -connectAttr "MGUN_Lthumb_tip1_rotateY.o" "MGUN_Lthumb_tip1.ry"; -connectAttr "MGUN_Lthumb_tip1_rotateZ.o" "MGUN_Lthumb_tip1.rz"; -connectAttr "MGUN_LT1_visibility.o" "MGUN_LT1.v"; -connectAttr "MGUN_LT1_translateX.o" "MGUN_LT1.tx"; -connectAttr "MGUN_LT1_translateY.o" "MGUN_LT1.ty"; -connectAttr "MGUN_LT1_translateZ.o" "MGUN_LT1.tz"; -connectAttr "MGUN_LT1_rotateX.o" "MGUN_LT1.rx"; -connectAttr "MGUN_LT1_rotateY.o" "MGUN_LT1.ry"; -connectAttr "MGUN_LT1_rotateZ.o" "MGUN_LT1.rz"; -connectAttr "MGUN_LT1_scaleX.o" "MGUN_LT1.sx"; -connectAttr "MGUN_LT1_scaleY.o" "MGUN_LT1.sy"; -connectAttr "MGUN_LT1_scaleZ.o" "MGUN_LT1.sz"; -connectAttr "MGUN_Lindex_base1_scaleX.o" "MGUN_Lindex_base1.sx"; -connectAttr "MGUN_Lindex_base1_scaleY.o" "MGUN_Lindex_base1.sy"; -connectAttr "MGUN_Lindex_base1_scaleZ.o" "MGUN_Lindex_base1.sz"; -connectAttr "MGUN_Lindex_base1_visibility.o" "MGUN_Lindex_base1.v"; -connectAttr "MGUN_Lindex_base1_translateX.o" "MGUN_Lindex_base1.tx"; -connectAttr "MGUN_Lindex_base1_translateY.o" "MGUN_Lindex_base1.ty"; -connectAttr "MGUN_Lindex_base1_translateZ.o" "MGUN_Lindex_base1.tz"; -connectAttr "MGUN_Lindex_base1_rotateX.o" "MGUN_Lindex_base1.rx"; -connectAttr "MGUN_Lindex_base1_rotateY.o" "MGUN_Lindex_base1.ry"; -connectAttr "MGUN_Lindex_base1_rotateZ.o" "MGUN_Lindex_base1.rz"; -connectAttr "MGUN_Linkdex_mid1_scaleX.o" "MGUN_Linkdex_mid1.sx"; -connectAttr "MGUN_Linkdex_mid1_scaleY.o" "MGUN_Linkdex_mid1.sy"; -connectAttr "MGUN_Linkdex_mid1_scaleZ.o" "MGUN_Linkdex_mid1.sz"; -connectAttr "MGUN_Linkdex_mid1_visibility.o" "MGUN_Linkdex_mid1.v"; -connectAttr "MGUN_Linkdex_mid1_translateX.o" "MGUN_Linkdex_mid1.tx"; -connectAttr "MGUN_Linkdex_mid1_translateY.o" "MGUN_Linkdex_mid1.ty"; -connectAttr "MGUN_Linkdex_mid1_translateZ.o" "MGUN_Linkdex_mid1.tz"; -connectAttr "MGUN_Linkdex_mid1_rotateX.o" "MGUN_Linkdex_mid1.rx"; -connectAttr "MGUN_Linkdex_mid1_rotateY.o" "MGUN_Linkdex_mid1.ry"; -connectAttr "MGUN_Linkdex_mid1_rotateZ.o" "MGUN_Linkdex_mid1.rz"; -connectAttr "MGUN_Lindex_tip1_scaleX.o" "MGUN_Lindex_tip1.sx"; -connectAttr "MGUN_Lindex_tip1_scaleY.o" "MGUN_Lindex_tip1.sy"; -connectAttr "MGUN_Lindex_tip1_scaleZ.o" "MGUN_Lindex_tip1.sz"; -connectAttr "MGUN_Lindex_tip1_visibility.o" "MGUN_Lindex_tip1.v"; -connectAttr "MGUN_Lindex_tip1_translateX.o" "MGUN_Lindex_tip1.tx"; -connectAttr "MGUN_Lindex_tip1_translateY.o" "MGUN_Lindex_tip1.ty"; -connectAttr "MGUN_Lindex_tip1_translateZ.o" "MGUN_Lindex_tip1.tz"; -connectAttr "MGUN_Lindex_tip1_rotateX.o" "MGUN_Lindex_tip1.rx"; -connectAttr "MGUN_Lindex_tip1_rotateY.o" "MGUN_Lindex_tip1.ry"; -connectAttr "MGUN_Lindex_tip1_rotateZ.o" "MGUN_Lindex_tip1.rz"; -connectAttr "MGUN_LI1_visibility.o" "MGUN_LI1.v"; -connectAttr "MGUN_LI1_translateX.o" "MGUN_LI1.tx"; -connectAttr "MGUN_LI1_translateY.o" "MGUN_LI1.ty"; -connectAttr "MGUN_LI1_translateZ.o" "MGUN_LI1.tz"; -connectAttr "MGUN_LI1_rotateX.o" "MGUN_LI1.rx"; -connectAttr "MGUN_LI1_rotateY.o" "MGUN_LI1.ry"; -connectAttr "MGUN_LI1_rotateZ.o" "MGUN_LI1.rz"; -connectAttr "MGUN_LI1_scaleX.o" "MGUN_LI1.sx"; -connectAttr "MGUN_LI1_scaleY.o" "MGUN_LI1.sy"; -connectAttr "MGUN_LI1_scaleZ.o" "MGUN_LI1.sz"; -connectAttr "MGUN_Lmiddle_base1_scaleX.o" "MGUN_Lmiddle_base1.sx"; -connectAttr "MGUN_Lmiddle_base1_scaleY.o" "MGUN_Lmiddle_base1.sy"; -connectAttr "MGUN_Lmiddle_base1_scaleZ.o" "MGUN_Lmiddle_base1.sz"; -connectAttr "MGUN_Lmiddle_base1_visibility.o" "MGUN_Lmiddle_base1.v"; -connectAttr "MGUN_Lmiddle_base1_translateX.o" "MGUN_Lmiddle_base1.tx"; -connectAttr "MGUN_Lmiddle_base1_translateY.o" "MGUN_Lmiddle_base1.ty"; -connectAttr "MGUN_Lmiddle_base1_translateZ.o" "MGUN_Lmiddle_base1.tz"; -connectAttr "MGUN_Lmiddle_base1_rotateX.o" "MGUN_Lmiddle_base1.rx"; -connectAttr "MGUN_Lmiddle_base1_rotateY.o" "MGUN_Lmiddle_base1.ry"; -connectAttr "MGUN_Lmiddle_base1_rotateZ.o" "MGUN_Lmiddle_base1.rz"; -connectAttr "MGUN_Lmiddle_mid1_scaleX.o" "MGUN_Lmiddle_mid1.sx"; -connectAttr "MGUN_Lmiddle_mid1_scaleY.o" "MGUN_Lmiddle_mid1.sy"; -connectAttr "MGUN_Lmiddle_mid1_scaleZ.o" "MGUN_Lmiddle_mid1.sz"; -connectAttr "MGUN_Lmiddle_mid1_visibility.o" "MGUN_Lmiddle_mid1.v"; -connectAttr "MGUN_Lmiddle_mid1_translateX.o" "MGUN_Lmiddle_mid1.tx"; -connectAttr "MGUN_Lmiddle_mid1_translateY.o" "MGUN_Lmiddle_mid1.ty"; -connectAttr "MGUN_Lmiddle_mid1_translateZ.o" "MGUN_Lmiddle_mid1.tz"; -connectAttr "MGUN_Lmiddle_mid1_rotateX.o" "MGUN_Lmiddle_mid1.rx"; -connectAttr "MGUN_Lmiddle_mid1_rotateY.o" "MGUN_Lmiddle_mid1.ry"; -connectAttr "MGUN_Lmiddle_mid1_rotateZ.o" "MGUN_Lmiddle_mid1.rz"; -connectAttr "MGUN_Lmiddle_tip1_scaleX.o" "MGUN_Lmiddle_tip1.sx"; -connectAttr "MGUN_Lmiddle_tip1_scaleY.o" "MGUN_Lmiddle_tip1.sy"; -connectAttr "MGUN_Lmiddle_tip1_scaleZ.o" "MGUN_Lmiddle_tip1.sz"; -connectAttr "MGUN_Lmiddle_tip1_visibility.o" "MGUN_Lmiddle_tip1.v"; -connectAttr "MGUN_Lmiddle_tip1_translateX.o" "MGUN_Lmiddle_tip1.tx"; -connectAttr "MGUN_Lmiddle_tip1_translateY.o" "MGUN_Lmiddle_tip1.ty"; -connectAttr "MGUN_Lmiddle_tip1_translateZ.o" "MGUN_Lmiddle_tip1.tz"; -connectAttr "MGUN_Lmiddle_tip1_rotateX.o" "MGUN_Lmiddle_tip1.rx"; -connectAttr "MGUN_Lmiddle_tip1_rotateY.o" "MGUN_Lmiddle_tip1.ry"; -connectAttr "MGUN_Lmiddle_tip1_rotateZ.o" "MGUN_Lmiddle_tip1.rz"; -connectAttr "MGUN_LM1_visibility.o" "MGUN_LM1.v"; -connectAttr "MGUN_LM1_translateX.o" "MGUN_LM1.tx"; -connectAttr "MGUN_LM1_translateY.o" "MGUN_LM1.ty"; -connectAttr "MGUN_LM1_translateZ.o" "MGUN_LM1.tz"; -connectAttr "MGUN_LM1_rotateX.o" "MGUN_LM1.rx"; -connectAttr "MGUN_LM1_rotateY.o" "MGUN_LM1.ry"; -connectAttr "MGUN_LM1_rotateZ.o" "MGUN_LM1.rz"; -connectAttr "MGUN_LM1_scaleX.o" "MGUN_LM1.sx"; -connectAttr "MGUN_LM1_scaleY.o" "MGUN_LM1.sy"; -connectAttr "MGUN_LM1_scaleZ.o" "MGUN_LM1.sz"; -connectAttr "MGUN_Lpinky_base1_scaleX.o" "MGUN_Lpinky_base1.sx"; -connectAttr "MGUN_Lpinky_base1_scaleY.o" "MGUN_Lpinky_base1.sy"; -connectAttr "MGUN_Lpinky_base1_scaleZ.o" "MGUN_Lpinky_base1.sz"; -connectAttr "MGUN_Lpinky_base1_visibility.o" "MGUN_Lpinky_base1.v"; -connectAttr "MGUN_Lpinky_base1_translateX.o" "MGUN_Lpinky_base1.tx"; -connectAttr "MGUN_Lpinky_base1_translateY.o" "MGUN_Lpinky_base1.ty"; -connectAttr "MGUN_Lpinky_base1_translateZ.o" "MGUN_Lpinky_base1.tz"; -connectAttr "MGUN_Lpinky_base1_rotateX.o" "MGUN_Lpinky_base1.rx"; -connectAttr "MGUN_Lpinky_base1_rotateY.o" "MGUN_Lpinky_base1.ry"; -connectAttr "MGUN_Lpinky_base1_rotateZ.o" "MGUN_Lpinky_base1.rz"; -connectAttr "MGUN_Lpinky_mid1_scaleX.o" "MGUN_Lpinky_mid1.sx"; -connectAttr "MGUN_Lpinky_mid1_scaleY.o" "MGUN_Lpinky_mid1.sy"; -connectAttr "MGUN_Lpinky_mid1_scaleZ.o" "MGUN_Lpinky_mid1.sz"; -connectAttr "MGUN_Lpinky_mid1_visibility.o" "MGUN_Lpinky_mid1.v"; -connectAttr "MGUN_Lpinky_mid1_translateX.o" "MGUN_Lpinky_mid1.tx"; -connectAttr "MGUN_Lpinky_mid1_translateY.o" "MGUN_Lpinky_mid1.ty"; -connectAttr "MGUN_Lpinky_mid1_translateZ.o" "MGUN_Lpinky_mid1.tz"; -connectAttr "MGUN_Lpinky_mid1_rotateX.o" "MGUN_Lpinky_mid1.rx"; -connectAttr "MGUN_Lpinky_mid1_rotateY.o" "MGUN_Lpinky_mid1.ry"; -connectAttr "MGUN_Lpinky_mid1_rotateZ.o" "MGUN_Lpinky_mid1.rz"; -connectAttr "MGUN_Lpinky_tip1_scaleX.o" "MGUN_Lpinky_tip1.sx"; -connectAttr "MGUN_Lpinky_tip1_scaleY.o" "MGUN_Lpinky_tip1.sy"; -connectAttr "MGUN_Lpinky_tip1_scaleZ.o" "MGUN_Lpinky_tip1.sz"; -connectAttr "MGUN_Lpinky_tip1_visibility.o" "MGUN_Lpinky_tip1.v"; -connectAttr "MGUN_Lpinky_tip1_translateX.o" "MGUN_Lpinky_tip1.tx"; -connectAttr "MGUN_Lpinky_tip1_translateY.o" "MGUN_Lpinky_tip1.ty"; -connectAttr "MGUN_Lpinky_tip1_translateZ.o" "MGUN_Lpinky_tip1.tz"; -connectAttr "MGUN_Lpinky_tip1_rotateX.o" "MGUN_Lpinky_tip1.rx"; -connectAttr "MGUN_Lpinky_tip1_rotateY.o" "MGUN_Lpinky_tip1.ry"; -connectAttr "MGUN_Lpinky_tip1_rotateZ.o" "MGUN_Lpinky_tip1.rz"; -connectAttr "MGUN_LP1_visibility.o" "MGUN_LP1.v"; -connectAttr "MGUN_LP1_translateX.o" "MGUN_LP1.tx"; -connectAttr "MGUN_LP1_translateY.o" "MGUN_LP1.ty"; -connectAttr "MGUN_LP1_translateZ.o" "MGUN_LP1.tz"; -connectAttr "MGUN_LP1_rotateX.o" "MGUN_LP1.rx"; -connectAttr "MGUN_LP1_rotateY.o" "MGUN_LP1.ry"; -connectAttr "MGUN_LP1_rotateZ.o" "MGUN_LP1.rz"; -connectAttr "MGUN_LP1_scaleX.o" "MGUN_LP1.sx"; -connectAttr "MGUN_LP1_scaleY.o" "MGUN_LP1.sy"; -connectAttr "MGUN_LP1_scaleZ.o" "MGUN_LP1.sz"; -connectAttr "MGUN_Lring_base1_scaleX.o" "MGUN_Lring_base1.sx"; -connectAttr "MGUN_Lring_base1_scaleY.o" "MGUN_Lring_base1.sy"; -connectAttr "MGUN_Lring_base1_scaleZ.o" "MGUN_Lring_base1.sz"; -connectAttr "MGUN_Lring_base1_visibility.o" "MGUN_Lring_base1.v"; -connectAttr "MGUN_Lring_base1_translateX.o" "MGUN_Lring_base1.tx"; -connectAttr "MGUN_Lring_base1_translateY.o" "MGUN_Lring_base1.ty"; -connectAttr "MGUN_Lring_base1_translateZ.o" "MGUN_Lring_base1.tz"; -connectAttr "MGUN_Lring_base1_rotateX.o" "MGUN_Lring_base1.rx"; -connectAttr "MGUN_Lring_base1_rotateY.o" "MGUN_Lring_base1.ry"; -connectAttr "MGUN_Lring_base1_rotateZ.o" "MGUN_Lring_base1.rz"; -connectAttr "MGUN_Lring_mid1_scaleX.o" "MGUN_Lring_mid1.sx"; -connectAttr "MGUN_Lring_mid1_scaleY.o" "MGUN_Lring_mid1.sy"; -connectAttr "MGUN_Lring_mid1_scaleZ.o" "MGUN_Lring_mid1.sz"; -connectAttr "MGUN_Lring_mid1_visibility.o" "MGUN_Lring_mid1.v"; -connectAttr "MGUN_Lring_mid1_translateX.o" "MGUN_Lring_mid1.tx"; -connectAttr "MGUN_Lring_mid1_translateY.o" "MGUN_Lring_mid1.ty"; -connectAttr "MGUN_Lring_mid1_translateZ.o" "MGUN_Lring_mid1.tz"; -connectAttr "MGUN_Lring_mid1_rotateX.o" "MGUN_Lring_mid1.rx"; -connectAttr "MGUN_Lring_mid1_rotateY.o" "MGUN_Lring_mid1.ry"; -connectAttr "MGUN_Lring_mid1_rotateZ.o" "MGUN_Lring_mid1.rz"; -connectAttr "MGUN_Lring_tiip1_scaleX.o" "MGUN_Lring_tiip1.sx"; -connectAttr "MGUN_Lring_tiip1_scaleY.o" "MGUN_Lring_tiip1.sy"; -connectAttr "MGUN_Lring_tiip1_scaleZ.o" "MGUN_Lring_tiip1.sz"; -connectAttr "MGUN_Lring_tiip1_visibility.o" "MGUN_Lring_tiip1.v"; -connectAttr "MGUN_Lring_tiip1_translateX.o" "MGUN_Lring_tiip1.tx"; -connectAttr "MGUN_Lring_tiip1_translateY.o" "MGUN_Lring_tiip1.ty"; -connectAttr "MGUN_Lring_tiip1_translateZ.o" "MGUN_Lring_tiip1.tz"; -connectAttr "MGUN_Lring_tiip1_rotateX.o" "MGUN_Lring_tiip1.rx"; -connectAttr "MGUN_Lring_tiip1_rotateY.o" "MGUN_Lring_tiip1.ry"; -connectAttr "MGUN_Lring_tiip1_rotateZ.o" "MGUN_Lring_tiip1.rz"; -connectAttr "MGUN_LR1_visibility.o" "MGUN_LR1.v"; -connectAttr "MGUN_LR1_translateX.o" "MGUN_LR1.tx"; -connectAttr "MGUN_LR1_translateY.o" "MGUN_LR1.ty"; -connectAttr "MGUN_LR1_translateZ.o" "MGUN_LR1.tz"; -connectAttr "MGUN_LR1_rotateX.o" "MGUN_LR1.rx"; -connectAttr "MGUN_LR1_rotateY.o" "MGUN_LR1.ry"; -connectAttr "MGUN_LR1_rotateZ.o" "MGUN_LR1.rz"; -connectAttr "MGUN_LR1_scaleX.o" "MGUN_LR1.sx"; -connectAttr "MGUN_LR1_scaleY.o" "MGUN_LR1.sy"; -connectAttr "MGUN_LR1_scaleZ.o" "MGUN_LR1.sz"; -connectAttr "MGUN_Lhand_orientConstraint2_nodeState.o" "MGUN_Lhand_orientConstraint2.nds" - ; -connectAttr "MGUN_Lhand_orientConstraint2_offsetX.o" "MGUN_Lhand_orientConstraint2.ox" - ; -connectAttr "MGUN_Lhand_orientConstraint2_offsetY.o" "MGUN_Lhand_orientConstraint2.oy" - ; -connectAttr "MGUN_Lhand_orientConstraint2_offsetZ.o" "MGUN_Lhand_orientConstraint2.oz" - ; -connectAttr "MGUN_locator12_rotateX.o" "MGUN_locator12.rx"; -connectAttr "MGUN_locator12_rotateY.o" "MGUN_locator12.ry"; -connectAttr "MGUN_locator12_rotateZ.o" "MGUN_locator12.rz"; -connectAttr "MGUN_locator12_translateX.o" "MGUN_locator12.tx"; -connectAttr "MGUN_locator12_translateY.o" "MGUN_locator12.ty"; -connectAttr "MGUN_locator12_translateZ.o" "MGUN_locator12.tz"; -connectAttr "MGUN_locator12_visibility.o" "MGUN_locator12.v"; -connectAttr "MGUN_locator12_scaleX.o" "MGUN_locator12.sx"; -connectAttr "MGUN_locator12_scaleY.o" "MGUN_locator12.sy"; -connectAttr "MGUN_locator12_scaleZ.o" "MGUN_locator12.sz"; -connectAttr "MGUN_effector1_visibility.o" "MGUN_effector1.v"; -connectAttr "MGUN_effector1_rotateX.o" "MGUN_effector1.rx"; -connectAttr "MGUN_effector1_rotateY.o" "MGUN_effector1.ry"; -connectAttr "MGUN_effector1_rotateZ.o" "MGUN_effector1.rz"; -connectAttr "MGUN_effector1_scaleX.o" "MGUN_effector1.sx"; -connectAttr "MGUN_effector1_scaleY.o" "MGUN_effector1.sy"; -connectAttr "MGUN_effector1_scaleZ.o" "MGUN_effector1.sz"; -connectAttr "MGUN_effector1_hideDisplay.o" "MGUN_effector1.hd"; -connectAttr "MGUN_locator11_translateX.o" "MGUN_locator11.tx"; -connectAttr "MGUN_locator11_translateY.o" "MGUN_locator11.ty"; -connectAttr "MGUN_locator11_translateZ.o" "MGUN_locator11.tz"; -connectAttr "MGUN_locator11_visibility.o" "MGUN_locator11.v"; -connectAttr "MGUN_locator11_rotateX.o" "MGUN_locator11.rx"; -connectAttr "MGUN_locator11_rotateY.o" "MGUN_locator11.ry"; -connectAttr "MGUN_locator11_rotateZ.o" "MGUN_locator11.rz"; -connectAttr "MGUN_locator11_scaleX.o" "MGUN_locator11.sx"; -connectAttr "MGUN_locator11_scaleY.o" "MGUN_locator11.sy"; -connectAttr "MGUN_locator11_scaleZ.o" "MGUN_locator11.sz"; -connectAttr "MGUN_Rloarm1_scaleX.o" "MGUN_Rloarm1.sx"; -connectAttr "MGUN_Rloarm1_scaleY.o" "MGUN_Rloarm1.sy"; -connectAttr "MGUN_Rloarm1_scaleZ.o" "MGUN_Rloarm1.sz"; -connectAttr "MGUN_Rloarm1_visibility.o" "MGUN_Rloarm1.v"; -connectAttr "MGUN_Rloarm1_translateX.o" "MGUN_Rloarm1.tx"; -connectAttr "MGUN_Rloarm1_translateY.o" "MGUN_Rloarm1.ty"; -connectAttr "MGUN_Rloarm1_translateZ.o" "MGUN_Rloarm1.tz"; -connectAttr "MGUN_Rloarm1_rotateX.o" "MGUN_Rloarm1.rx"; -connectAttr "MGUN_Rloarm1_rotateY.o" "MGUN_Rloarm1.ry"; -connectAttr "MGUN_Rloarm1_rotateZ.o" "MGUN_Rloarm1.rz"; -connectAttr "MGUN_Rhand1_scaleX.o" "MGUN_Rhand1.sx"; -connectAttr "MGUN_Rhand1_scaleY.o" "MGUN_Rhand1.sy"; -connectAttr "MGUN_Rhand1_scaleZ.o" "MGUN_Rhand1.sz"; -connectAttr "MGUN_Rhand1_translateX.o" "MGUN_Rhand1.tx"; -connectAttr "MGUN_Rhand1_translateY.o" "MGUN_Rhand1.ty"; -connectAttr "MGUN_Rhand1_translateZ.o" "MGUN_Rhand1.tz"; -connectAttr "MGUN_Rhand1_visibility.o" "MGUN_Rhand1.v"; -connectAttr "MGUN_Rindex11a_scaleX.o" "MGUN_Rindex11a.sx"; -connectAttr "MGUN_Rindex11a_scaleY.o" "MGUN_Rindex11a.sy"; -connectAttr "MGUN_Rindex11a_scaleZ.o" "MGUN_Rindex11a.sz"; -connectAttr "MGUN_Rindex11a_visibility.o" "MGUN_Rindex11a.v"; -connectAttr "MGUN_Rindex11a_translateX.o" "MGUN_Rindex11a.tx"; -connectAttr "MGUN_Rindex11a_translateY.o" "MGUN_Rindex11a.ty"; -connectAttr "MGUN_Rindex11a_translateZ.o" "MGUN_Rindex11a.tz"; -connectAttr "MGUN_Rindex11a_rotateX.o" "MGUN_Rindex11a.rx"; -connectAttr "MGUN_Rindex11a_rotateY.o" "MGUN_Rindex11a.ry"; -connectAttr "MGUN_Rindex11a_rotateZ.o" "MGUN_Rindex11a.rz"; -connectAttr "MGUN_Rindex11_scaleX.o" "MGUN_Rindex11.sx"; -connectAttr "MGUN_Rindex11_scaleY.o" "MGUN_Rindex11.sy"; -connectAttr "MGUN_Rindex11_scaleZ.o" "MGUN_Rindex11.sz"; -connectAttr "MGUN_Rindex11_visibility.o" "MGUN_Rindex11.v"; -connectAttr "MGUN_Rindex11_translateX.o" "MGUN_Rindex11.tx"; -connectAttr "MGUN_Rindex11_translateY.o" "MGUN_Rindex11.ty"; -connectAttr "MGUN_Rindex11_translateZ.o" "MGUN_Rindex11.tz"; -connectAttr "MGUN_Rindex11_rotateX.o" "MGUN_Rindex11.rx"; -connectAttr "MGUN_Rindex11_rotateY.o" "MGUN_Rindex11.ry"; -connectAttr "MGUN_Rindex11_rotateZ.o" "MGUN_Rindex11.rz"; -connectAttr "MGUN_Rindex21_scaleX.o" "MGUN_Rindex21.sx"; -connectAttr "MGUN_Rindex21_scaleY.o" "MGUN_Rindex21.sy"; -connectAttr "MGUN_Rindex21_scaleZ.o" "MGUN_Rindex21.sz"; -connectAttr "MGUN_Rindex21_visibility.o" "MGUN_Rindex21.v"; -connectAttr "MGUN_Rindex21_translateX.o" "MGUN_Rindex21.tx"; -connectAttr "MGUN_Rindex21_translateY.o" "MGUN_Rindex21.ty"; -connectAttr "MGUN_Rindex21_translateZ.o" "MGUN_Rindex21.tz"; -connectAttr "MGUN_Rindex21_rotateX.o" "MGUN_Rindex21.rx"; -connectAttr "MGUN_Rindex21_rotateY.o" "MGUN_Rindex21.ry"; -connectAttr "MGUN_Rindex21_rotateZ.o" "MGUN_Rindex21.rz"; -connectAttr "MGUN_Rindex31_visibility.o" "MGUN_Rindex31.v"; -connectAttr "MGUN_Rindex31_translateX.o" "MGUN_Rindex31.tx"; -connectAttr "MGUN_Rindex31_translateY.o" "MGUN_Rindex31.ty"; -connectAttr "MGUN_Rindex31_translateZ.o" "MGUN_Rindex31.tz"; -connectAttr "MGUN_Rindex31_rotateX.o" "MGUN_Rindex31.rx"; -connectAttr "MGUN_Rindex31_rotateY.o" "MGUN_Rindex31.ry"; -connectAttr "MGUN_Rindex31_rotateZ.o" "MGUN_Rindex31.rz"; -connectAttr "MGUN_Rindex31_scaleX.o" "MGUN_Rindex31.sx"; -connectAttr "MGUN_Rindex31_scaleY.o" "MGUN_Rindex31.sy"; -connectAttr "MGUN_Rindex31_scaleZ.o" "MGUN_Rindex31.sz"; -connectAttr "MGUN_Rthumb11_scaleX.o" "MGUN_Rthumb11.sx"; -connectAttr "MGUN_Rthumb11_scaleY.o" "MGUN_Rthumb11.sy"; -connectAttr "MGUN_Rthumb11_scaleZ.o" "MGUN_Rthumb11.sz"; -connectAttr "MGUN_Rthumb11_visibility.o" "MGUN_Rthumb11.v"; -connectAttr "MGUN_Rthumb11_translateX.o" "MGUN_Rthumb11.tx"; -connectAttr "MGUN_Rthumb11_translateY.o" "MGUN_Rthumb11.ty"; -connectAttr "MGUN_Rthumb11_translateZ.o" "MGUN_Rthumb11.tz"; -connectAttr "MGUN_Rthumb11_rotateX.o" "MGUN_Rthumb11.rx"; -connectAttr "MGUN_Rthumb11_rotateY.o" "MGUN_Rthumb11.ry"; -connectAttr "MGUN_Rthumb11_rotateZ.o" "MGUN_Rthumb11.rz"; -connectAttr "MGUN_Rthumb21_scaleX.o" "MGUN_Rthumb21.sx"; -connectAttr "MGUN_Rthumb21_scaleY.o" "MGUN_Rthumb21.sy"; -connectAttr "MGUN_Rthumb21_scaleZ.o" "MGUN_Rthumb21.sz"; -connectAttr "MGUN_Rthumb21_visibility.o" "MGUN_Rthumb21.v"; -connectAttr "MGUN_Rthumb21_translateX.o" "MGUN_Rthumb21.tx"; -connectAttr "MGUN_Rthumb21_translateY.o" "MGUN_Rthumb21.ty"; -connectAttr "MGUN_Rthumb21_translateZ.o" "MGUN_Rthumb21.tz"; -connectAttr "MGUN_Rthumb21_rotateX.o" "MGUN_Rthumb21.rx"; -connectAttr "MGUN_Rthumb21_rotateY.o" "MGUN_Rthumb21.ry"; -connectAttr "MGUN_Rthumb21_rotateZ.o" "MGUN_Rthumb21.rz"; -connectAttr "MGUN_Rthumb31_scaleX.o" "MGUN_Rthumb31.sx"; -connectAttr "MGUN_Rthumb31_scaleY.o" "MGUN_Rthumb31.sy"; -connectAttr "MGUN_Rthumb31_scaleZ.o" "MGUN_Rthumb31.sz"; -connectAttr "MGUN_Rthumb31_visibility.o" "MGUN_Rthumb31.v"; -connectAttr "MGUN_Rthumb31_translateX.o" "MGUN_Rthumb31.tx"; -connectAttr "MGUN_Rthumb31_translateY.o" "MGUN_Rthumb31.ty"; -connectAttr "MGUN_Rthumb31_translateZ.o" "MGUN_Rthumb31.tz"; -connectAttr "MGUN_Rthumb31_rotateX.o" "MGUN_Rthumb31.rx"; -connectAttr "MGUN_Rthumb31_rotateY.o" "MGUN_Rthumb31.ry"; -connectAttr "MGUN_Rthumb31_rotateZ.o" "MGUN_Rthumb31.rz"; -connectAttr "MGUN_Rthumb41_visibility.o" "MGUN_Rthumb41.v"; -connectAttr "MGUN_Rthumb41_translateX.o" "MGUN_Rthumb41.tx"; -connectAttr "MGUN_Rthumb41_translateY.o" "MGUN_Rthumb41.ty"; -connectAttr "MGUN_Rthumb41_translateZ.o" "MGUN_Rthumb41.tz"; -connectAttr "MGUN_Rthumb41_rotateX.o" "MGUN_Rthumb41.rx"; -connectAttr "MGUN_Rthumb41_rotateY.o" "MGUN_Rthumb41.ry"; -connectAttr "MGUN_Rthumb41_rotateZ.o" "MGUN_Rthumb41.rz"; -connectAttr "MGUN_Rthumb41_scaleX.o" "MGUN_Rthumb41.sx"; -connectAttr "MGUN_Rthumb41_scaleY.o" "MGUN_Rthumb41.sy"; -connectAttr "MGUN_Rthumb41_scaleZ.o" "MGUN_Rthumb41.sz"; -connectAttr "MGUN_Rfings11_scaleX.o" "MGUN_Rfings11.sx"; -connectAttr "MGUN_Rfings11_scaleY.o" "MGUN_Rfings11.sy"; -connectAttr "MGUN_Rfings11_scaleZ.o" "MGUN_Rfings11.sz"; -connectAttr "MGUN_Rfings11_visibility.o" "MGUN_Rfings11.v"; -connectAttr "MGUN_Rfings11_translateX.o" "MGUN_Rfings11.tx"; -connectAttr "MGUN_Rfings11_translateY.o" "MGUN_Rfings11.ty"; -connectAttr "MGUN_Rfings11_translateZ.o" "MGUN_Rfings11.tz"; -connectAttr "MGUN_Rfings11_rotateX.o" "MGUN_Rfings11.rx"; -connectAttr "MGUN_Rfings11_rotateY.o" "MGUN_Rfings11.ry"; -connectAttr "MGUN_Rfings11_rotateZ.o" "MGUN_Rfings11.rz"; -connectAttr "MGUN_Rfings21_scaleX.o" "MGUN_Rfings21.sx"; -connectAttr "MGUN_Rfings21_scaleY.o" "MGUN_Rfings21.sy"; -connectAttr "MGUN_Rfings21_scaleZ.o" "MGUN_Rfings21.sz"; -connectAttr "MGUN_Rfings21_visibility.o" "MGUN_Rfings21.v"; -connectAttr "MGUN_Rfings21_translateX.o" "MGUN_Rfings21.tx"; -connectAttr "MGUN_Rfings21_translateY.o" "MGUN_Rfings21.ty"; -connectAttr "MGUN_Rfings21_translateZ.o" "MGUN_Rfings21.tz"; -connectAttr "MGUN_Rfings21_rotateX.o" "MGUN_Rfings21.rx"; -connectAttr "MGUN_Rfings21_rotateY.o" "MGUN_Rfings21.ry"; -connectAttr "MGUN_Rfings21_rotateZ.o" "MGUN_Rfings21.rz"; -connectAttr "MGUN_Rfings31_scaleX.o" "MGUN_Rfings31.sx"; -connectAttr "MGUN_Rfings31_scaleY.o" "MGUN_Rfings31.sy"; -connectAttr "MGUN_Rfings31_scaleZ.o" "MGUN_Rfings31.sz"; -connectAttr "MGUN_Rfings31_visibility.o" "MGUN_Rfings31.v"; -connectAttr "MGUN_Rfings31_translateX.o" "MGUN_Rfings31.tx"; -connectAttr "MGUN_Rfings31_translateY.o" "MGUN_Rfings31.ty"; -connectAttr "MGUN_Rfings31_translateZ.o" "MGUN_Rfings31.tz"; -connectAttr "MGUN_Rfings31_rotateX.o" "MGUN_Rfings31.rx"; -connectAttr "MGUN_Rfings31_rotateY.o" "MGUN_Rfings31.ry"; -connectAttr "MGUN_Rfings31_rotateZ.o" "MGUN_Rfings31.rz"; -connectAttr "MGUN_Rfings41_visibility.o" "MGUN_Rfings41.v"; -connectAttr "MGUN_Rfings41_translateX.o" "MGUN_Rfings41.tx"; -connectAttr "MGUN_Rfings41_translateY.o" "MGUN_Rfings41.ty"; -connectAttr "MGUN_Rfings41_translateZ.o" "MGUN_Rfings41.tz"; -connectAttr "MGUN_Rfings41_rotateX.o" "MGUN_Rfings41.rx"; -connectAttr "MGUN_Rfings41_rotateY.o" "MGUN_Rfings41.ry"; -connectAttr "MGUN_Rfings41_rotateZ.o" "MGUN_Rfings41.rz"; -connectAttr "MGUN_Rfings41_scaleX.o" "MGUN_Rfings41.sx"; -connectAttr "MGUN_Rfings41_scaleY.o" "MGUN_Rfings41.sy"; -connectAttr "MGUN_Rfings41_scaleZ.o" "MGUN_Rfings41.sz"; -connectAttr "MGUN_Rhand_orientConstraint1_nodeState.o" "MGUN_Rhand_orientConstraint1.nds" - ; -connectAttr "MGUN_Rhand_orientConstraint1_Hand_ConstW0.o" "MGUN_Rhand_orientConstraint1.w0" - ; -connectAttr "MGUN_Rhand_orientConstraint1_offsetX.o" "MGUN_Rhand_orientConstraint1.ox" - ; -connectAttr "MGUN_Rhand_orientConstraint1_offsetY.o" "MGUN_Rhand_orientConstraint1.oy" - ; -connectAttr "MGUN_Rhand_orientConstraint1_offsetZ.o" "MGUN_Rhand_orientConstraint1.oz" - ; -connectAttr "MGUN_locator10_rotateX.o" "MGUN_locator10.rx"; -connectAttr "MGUN_locator10_rotateY.o" "MGUN_locator10.ry"; -connectAttr "MGUN_locator10_rotateZ.o" "MGUN_locator10.rz"; -connectAttr "MGUN_locator10_translateX.o" "MGUN_locator10.tx"; -connectAttr "MGUN_locator10_translateY.o" "MGUN_locator10.ty"; -connectAttr "MGUN_locator10_translateZ.o" "MGUN_locator10.tz"; -connectAttr "MGUN_locator10_visibility.o" "MGUN_locator10.v"; -connectAttr "MGUN_locator10_scaleX.o" "MGUN_locator10.sx"; -connectAttr "MGUN_locator10_scaleY.o" "MGUN_locator10.sy"; -connectAttr "MGUN_locator10_scaleZ.o" "MGUN_locator10.sz"; -connectAttr "MGUN_locator9_translateX.o" "MGUN_locator9.tx"; -connectAttr "MGUN_locator9_translateY.o" "MGUN_locator9.ty"; -connectAttr "MGUN_locator9_translateZ.o" "MGUN_locator9.tz"; -connectAttr "MGUN_locator9_visibility.o" "MGUN_locator9.v"; -connectAttr "MGUN_locator9_rotateX.o" "MGUN_locator9.rx"; -connectAttr "MGUN_locator9_rotateY.o" "MGUN_locator9.ry"; -connectAttr "MGUN_locator9_rotateZ.o" "MGUN_locator9.rz"; -connectAttr "MGUN_locator9_scaleX.o" "MGUN_locator9.sx"; -connectAttr "MGUN_locator9_scaleY.o" "MGUN_locator9.sy"; -connectAttr "MGUN_locator9_scaleZ.o" "MGUN_locator9.sz"; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr "MGUN_Gun_Const_translateX.o" "MGUN_Gun_Const.tx"; -connectAttr "MGUN_Gun_Const_translateY.o" "MGUN_Gun_Const.ty"; -connectAttr "MGUN_Gun_Const_translateZ.o" "MGUN_Gun_Const.tz"; -connectAttr "MGUN_Gun_Const_rotateX.o" "MGUN_Gun_Const.rx"; -connectAttr "MGUN_Gun_Const_rotateY.o" "MGUN_Gun_Const.ry"; -connectAttr "MGUN_Gun_Const_rotateZ.o" "MGUN_Gun_Const.rz"; -connectAttr "MGUN_Gun_Const_visibility.o" "MGUN_Gun_Const.v"; -connectAttr "MGUN_Gun_Const_scaleX.o" "MGUN_Gun_Const.sx"; -connectAttr "MGUN_Gun_Const_scaleY.o" "MGUN_Gun_Const.sy"; -connectAttr "MGUN_Gun_Const_scaleZ.o" "MGUN_Gun_Const.sz"; -connectAttr "MGUN_Hand_Const_pointConstraint1_nodeState.o" "MGUN_Hand_Const_pointConstraint1.nds" - ; -connectAttr "MGUN_Hand_Const_pointConstraint1_RhandW0.o" "MGUN_Hand_Const_pointConstraint1.w0" - ; -connectAttr "MGUN_Hand_Const_pointConstraint1_offsetX.o" "MGUN_Hand_Const_pointConstraint1.ox" - ; -connectAttr "MGUN_Hand_Const_pointConstraint1_offsetY.o" "MGUN_Hand_Const_pointConstraint1.oy" - ; -connectAttr "MGUN_Hand_Const_pointConstraint1_offsetZ.o" "MGUN_Hand_Const_pointConstraint1.oz" - ; -connectAttr "MGUN_group2_visibility.o" "MGUN_group2.v"; -connectAttr "MGUN_group2_translateX.o" "MGUN_group2.tx"; -connectAttr "MGUN_group2_translateY.o" "MGUN_group2.ty"; -connectAttr "MGUN_group2_translateZ.o" "MGUN_group2.tz"; -connectAttr "MGUN_group2_rotateX.o" "MGUN_group2.rx"; -connectAttr "MGUN_group2_rotateY.o" "MGUN_group2.ry"; -connectAttr "MGUN_group2_rotateZ.o" "MGUN_group2.rz"; -connectAttr "MGUN_group2_scaleX.o" "MGUN_group2.sx"; -connectAttr "MGUN_group2_scaleY.o" "MGUN_group2.sy"; -connectAttr "MGUN_group2_scaleZ.o" "MGUN_group2.sz"; -connectAttr "MGUN_polySurface14_visibility.o" "MGUN_polySurface14.v"; -connectAttr "MGUN_LHAND_GOAL_OFF_CONNECT.o" "MGUN_LHAND_GOAL_OFF.CONNECT" - ; -connectAttr "MGUN_LHAND_GOAL_OFF_translateX.o" "MGUN_LHAND_GOAL_OFF.tx"; -connectAttr "MGUN_LHAND_GOAL_OFF_translateY.o" "MGUN_LHAND_GOAL_OFF.ty"; -connectAttr "MGUN_LHAND_GOAL_OFF_translateZ.o" "MGUN_LHAND_GOAL_OFF.tz"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateX.o" "MGUN_LHAND_GOAL_OFF.rx"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateY.o" "MGUN_LHAND_GOAL_OFF.ry"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateZ.o" "MGUN_LHAND_GOAL_OFF.rz"; -connectAttr "MGUN_LHAND_GOAL_OFF_visibility.o" "MGUN_LHAND_GOAL_OFF.v"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleX.o" "MGUN_LHAND_GOAL_OFF.sx"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleY.o" "MGUN_LHAND_GOAL_OFF.sy"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleZ.o" "MGUN_LHAND_GOAL_OFF.sz"; -connectAttr "side_visibility.o" ":side.v"; -connectAttr "side_translateX.o" ":side.tx"; -connectAttr "side_translateY.o" ":side.ty"; -connectAttr "side_translateZ.o" ":side.tz"; -connectAttr "side_rotateX.o" ":side.rx"; -connectAttr "side_rotateY.o" ":side.ry"; -connectAttr "side_rotateZ.o" ":side.rz"; -connectAttr "side_scaleX.o" ":side.sx"; -connectAttr "side_scaleY.o" ":side.sy"; -connectAttr "side_scaleZ.o" ":side.sz"; -connectAttr "group1_visibility.o" "group1.v"; -connectAttr "group1_translateX.o" "group1.tx"; -connectAttr "group1_translateY.o" "group1.ty"; -connectAttr "group1_translateZ.o" "group1.tz"; -connectAttr "group1_rotateX.o" "group1.rx"; -connectAttr "group1_rotateY.o" "group1.ry"; -connectAttr "group1_rotateZ.o" "group1.rz"; -connectAttr "group1_scaleX.o" "group1.sx"; -connectAttr "group1_scaleY.o" "group1.sy"; -connectAttr "group1_scaleZ.o" "group1.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of pullup1.ma diff --git a/base/models/weapons/machinegun/cycles/putaway.ma b/base/models/weapons/machinegun/cycles/putaway.ma deleted file mode 100644 index 765476bd9..000000000 --- a/base/models/weapons/machinegun/cycles/putaway.ma +++ /dev/null @@ -1,1594 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:27 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: putaway.ma -//Last modified: Mon, Jan 19, 2004 10:58:45 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".v" no; - setAttr ".t" -type "double3" -3.3701950804684326 -3.0346064183513324 2.5404995247810724 ; - setAttr ".r" -type "double3" -30.930108913546494 271.79999999997932 -1.0125685513008293e-013 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v" no; - setAttr ".fl" 34.999999999999993; - setAttr ".fcp" 100000; - setAttr ".coi" 18.102515646369714; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".v" no; - setAttr ".t" -type "double3" 6.7961511042850251 100 -2.4628881879303037 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 60.215517241379345; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".v" no; - setAttr ".t" -type "double3" 13.178794635641133 -8.8175496818041061 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 109.04632652175749; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".v" no; - setAttr ".t" -type "double3" 100 0 0 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v" no; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 30; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "group1"; - setAttr ".rp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; - setAttr ".sp" -type "double3" 11.486778009373046 -14.669913764246656 4.0016839576759402 ; -createNode transform -n "persp1"; - setAttr ".t" -type "double3" 2.184944949433385 59.393403368610507 1.9299169736467008 ; - setAttr ".r" -type "double3" -87.93010891356802 -82.600000000001273 -7.4083775361419622e-014 ; -createNode camera -n "perspShape2" -p "persp1"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fl" 34.999999999999993; - setAttr ".coi" 85.152329937421754; - setAttr ".imn" -type "string" "persp1"; - setAttr ".den" -type "string" "persp1_depth"; - setAttr ".man" -type "string" "persp1_mask"; - setAttr ".tp" -type "double3" 10.801480261993932 -17.139646926120147 4.5024412021349809 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 0\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 1\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 1\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"quad\\\" -ps 1 50 50 -ps 2 50 50 -ps 3 50 50 -ps 4 50 50 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Top View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Top View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Top View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera top` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera persp` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Side View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Side View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Side View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera side` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Front View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Front View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Front View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -cam `findStartUpCamera front` \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"wireframe\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 0\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 1\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 6 -ast 1 -aet 6 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 14 1 18 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 5.1154134140104386 14 -0.09514544572216628 - 18 -0.09514544572216628; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -21.710493028270307 14 -21.710493028270307 - 18 -21.710493028270307; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 6.9128988668793641 14 1.0671561892387926 - 18 1.0671561892387926; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 23.858970583210471 14 49.522719062792603 - 18 49.522719062792603; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -12.978384796886047 14 -22.751164930908381 - 18 -22.751164930908381; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.3183589787639254 14 32.408148234511351 - 18 32.408148234511351; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 14 1 18 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 14 1 18 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 14 1 18 1; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3.2200000000000002 1 4.136 - 1 6.228 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -37.043136527093303 3.2200000000000002 - -42.568923346174067 4.136 -49.074494278618531 6.228 -49.844784252116106; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 24.119371109172484 3.2200000000000002 - 23.338933364493951 4.136 11.417476832303331 6.228 12.843583657705642; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -79.391828382450555 3.2200000000000002 - -107.90936097435528 4.136 -177.56557022728197 6.228 -161.08207240028887; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3.2200000000000002 1 4.136 - 1 6.228 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3.2200000000000002 1 4.136 - 1 6.228 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 3.2200000000000002 1 4.136 - 1 6.228 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 12 1 18 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1.2595865557226966 12 -2.8131382815901533 - 18 -3.0099427452828196; -createNode animCurveTL -n "MGUN_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -19.397540168639082 12 -20.394628667008789 - 18 -20.394628667008789; -createNode animCurveTL -n "MGUN_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3.1673856936136509 12 -10.453051168206356 - 18 -10.805113127472199; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 60.877876903291245 12 96.732921192653592 - 18 100.4470178987855; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 44.176165852300457 12 16.91078284851125 - 18 10.479344524987145; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 10.826657154260396 12 -32.6674008711502 - 18 -62.712033822140413; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 12 1 18 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 12 1 18 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 12 1 18 1; -createNode animCurveTU -n "MGUN_ikHandle2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.104 1 4.136 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTA -n "MGUN_ikHandle2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.104 0 4.136 0; -createNode animCurveTA -n "MGUN_ikHandle2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.104 0 4.136 0; -createNode animCurveTA -n "MGUN_ikHandle2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.104 0 4.136 0; -createNode animCurveTU -n "MGUN_ikHandle2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.104 1 4.136 1; -createNode animCurveTU -n "MGUN_ikHandle2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.104 1 4.136 1; -createNode animCurveTU -n "MGUN_ikHandle2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.104 1 4.136 1; -createNode animCurveTU -n "MGUN_ikHandle2_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.104 1 4.136 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.215168658192533 4.104 0.215168658192533 - 4.136 0.215168658192533; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -0.68511389263983957 4.104 -0.68511389263983957 - 4.136 -0.68511389263983957; -createNode animCurveTU -n "MGUN_ikHandle2_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0.49185115903440002 4.104 0.49185115903440002 - 4.136 0.49185115903440002; -createNode animCurveTU -n "MGUN_ikHandle2_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.104 0 4.136 0; -createNode animCurveTA -n "MGUN_ikHandle2_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.104 0 4.136 0; -createNode animCurveTA -n "MGUN_ikHandle2_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -295.64622228750477 4.104 -263.56058576017864 - 4.136 -234.91269600363751; -createNode animCurveTU -n "MGUN_locator8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 5 1 6 1 7 1 9 1 11 1 15 - 1 18 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_locator8_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 17.853467334841042 4 17.972290420494222 - 5 17.7508041888367 6 17.214813053302823 7 16.661583768639183 9 15.080928669600212 - 11 12.902505432625277 15 8.6644820443285759 18 6.8425280643131714; -createNode animCurveTL -n "MGUN_locator8_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -5.2290123649222391 4 -10.536443524097541 - 5 -12.295975776449803 6 -13.92964467532394 7 -15.482131735042646 9 -18.695628738949125 - 11 -21.221719522835219 15 -24.161490678995335 18 -25.428936925962574; -createNode animCurveTL -n "MGUN_locator8_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 2.7392944515744202 4 2.7392944515744202 - 5 2.7392944515744202 6 2.7392944515744202 7 2.7392944515744202 9 2.7392944515744202 - 11 2.7392944515744202 15 2.7392944515744202 18 2.7392944515744202; -createNode animCurveTA -n "MGUN_locator8_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 0 5 0 6 0 7 0 9 0 11 0 15 - 0 18 0; -createNode animCurveTA -n "MGUN_locator8_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 0 5 0 6 0 7 0 9 0 11 0 15 - 0 18 0; -createNode animCurveTA -n "MGUN_locator8_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0 4 -18.140406121763508 5 -21.518893148341458 - 6 -26.066856453350237 7 -32.434005080362532 9 -50.625858300397638 11 -57.823189941161132 - 15 -78.386994629056815 18 -78.386994629056815; -createNode animCurveTU -n "MGUN_locator8_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 5 1 6 1 7 1 9 1 11 1 15 - 1 18 1; -createNode animCurveTU -n "MGUN_locator8_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 5 1 6 1 7 1 9 1 11 1 15 - 1 18 1; -createNode animCurveTU -n "MGUN_locator8_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 4 1 5 1 6 1 7 1 9 1 11 1 15 - 1 18 1; -createNode animCurveTU -n "MGUN_barrel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 1.552 1 4.136 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_barrel_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 17.853467334841042 1.552 6.9298767996489534 - 4.136 6.9298767996489534; -createNode animCurveTL -n "MGUN_barrel_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -5.2290123649222391 1.552 -26.235917240291645 - 4.136 -26.235917240291645; -createNode animCurveTL -n "MGUN_barrel_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 2.7392944515744202 1.552 -14.390982005024874 - 4.136 -14.390982005024874; -createNode animCurveTA -n "MGUN_barrel_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 1.552 0 4.136 0; -createNode animCurveTA -n "MGUN_barrel_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 1.552 0 4.136 0; -createNode animCurveTA -n "MGUN_barrel_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 1.552 0 4.136 0; -createNode animCurveTU -n "MGUN_barrel_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 1.552 1 4.136 1; -createNode animCurveTU -n "MGUN_barrel_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 1.552 1 4.136 1; -createNode animCurveTU -n "MGUN_barrel_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 1.552 1 4.136 1; -createNode animCurveTU -n "MGUN_locator7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.136 1 6.228 1; - setAttr -s 3 ".kot[0:2]" 5 5 5; -createNode animCurveTL -n "MGUN_locator7_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -4 4.136 -7.7054576973412718 - 6.228 -7.7054576973412718; -createNode animCurveTL -n "MGUN_locator7_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 11 4.136 2.2657068562670002 6.228 - 2.2657068562670002; -createNode animCurveTL -n "MGUN_locator7_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -3 4.136 -3 6.228 -3; -createNode animCurveTA -n "MGUN_locator7_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.136 0 6.228 0; -createNode animCurveTA -n "MGUN_locator7_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 -29.205417093903414 4.136 -29.205417093903414 - 6.228 -29.205417093903414; -createNode animCurveTA -n "MGUN_locator7_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 0 4.136 0 6.228 0; -createNode animCurveTU -n "MGUN_locator7_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.136 1 6.228 1; -createNode animCurveTU -n "MGUN_locator7_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.136 1 6.228 1; -createNode animCurveTU -n "MGUN_locator7_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 3 ".ktv[0:2]" 1 1 4.136 1 6.228 1; -select -ne :time1; - setAttr ".o" 2; -select -ne :renderPartition; - setAttr -s 48 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 48 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 22 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 22 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -parent -s -nc -r "MGUN_Gun1" "group1"; -parent -s -nc -r "MGUN_ikHandle2" "group1"; -parent -s -nc -r "MGUN_origin" "group1"; -parent -s -nc -r "MGUN_locator7" "group1"; -parent -s -nc -r "MGUN_group2" "group1"; -parent -s -nc -r "MGUN_LHAND_GOAL_OFF" "group1"; -connectAttr "MGUN_barrel_visibility.o" "MGUN_barrel.v"; -connectAttr "MGUN_barrel_translateX.o" "MGUN_barrel.tx"; -connectAttr "MGUN_barrel_translateY.o" "MGUN_barrel.ty"; -connectAttr "MGUN_barrel_translateZ.o" "MGUN_barrel.tz"; -connectAttr "MGUN_barrel_rotateX.o" "MGUN_barrel.rx"; -connectAttr "MGUN_barrel_rotateY.o" "MGUN_barrel.ry"; -connectAttr "MGUN_barrel_rotateZ.o" "MGUN_barrel.rz"; -connectAttr "MGUN_barrel_scaleX.o" "MGUN_barrel.sx"; -connectAttr "MGUN_barrel_scaleY.o" "MGUN_barrel.sy"; -connectAttr "MGUN_barrel_scaleZ.o" "MGUN_barrel.sz"; -connectAttr "MGUN_ikHandle2_visibility.o" "MGUN_ikHandle2.v"; -connectAttr "MGUN_ikHandle2_rotateX.o" "MGUN_ikHandle2.rx"; -connectAttr "MGUN_ikHandle2_rotateY.o" "MGUN_ikHandle2.ry"; -connectAttr "MGUN_ikHandle2_rotateZ.o" "MGUN_ikHandle2.rz"; -connectAttr "MGUN_ikHandle2_scaleX.o" "MGUN_ikHandle2.sx"; -connectAttr "MGUN_ikHandle2_scaleY.o" "MGUN_ikHandle2.sy"; -connectAttr "MGUN_ikHandle2_scaleZ.o" "MGUN_ikHandle2.sz"; -connectAttr "MGUN_ikHandle2_solverEnable.o" "MGUN_ikHandle2.hse"; -connectAttr "MGUN_ikHandle2_poleVectorX.o" "MGUN_ikHandle2.pvx"; -connectAttr "MGUN_ikHandle2_poleVectorY.o" "MGUN_ikHandle2.pvy"; -connectAttr "MGUN_ikHandle2_poleVectorZ.o" "MGUN_ikHandle2.pvz"; -connectAttr "MGUN_ikHandle2_offset.o" "MGUN_ikHandle2.off"; -connectAttr "MGUN_ikHandle2_roll.o" "MGUN_ikHandle2.rol"; -connectAttr "MGUN_ikHandle2_twist.o" "MGUN_ikHandle2.twi"; -connectAttr "MGUN_locator7_visibility.o" "MGUN_locator7.v"; -connectAttr "MGUN_locator7_translateX.o" "MGUN_locator7.tx"; -connectAttr "MGUN_locator7_translateY.o" "MGUN_locator7.ty"; -connectAttr "MGUN_locator7_translateZ.o" "MGUN_locator7.tz"; -connectAttr "MGUN_locator7_rotateX.o" "MGUN_locator7.rx"; -connectAttr "MGUN_locator7_rotateY.o" "MGUN_locator7.ry"; -connectAttr "MGUN_locator7_rotateZ.o" "MGUN_locator7.rz"; -connectAttr "MGUN_locator7_scaleX.o" "MGUN_locator7.sx"; -connectAttr "MGUN_locator7_scaleY.o" "MGUN_locator7.sy"; -connectAttr "MGUN_locator7_scaleZ.o" "MGUN_locator7.sz"; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of putaway.ma diff --git a/base/models/weapons/machinegun/cycles/reload1.ma b/base/models/weapons/machinegun/cycles/reload1.ma deleted file mode 100644 index b055d077b..000000000 --- a/base/models/weapons/machinegun/cycles/reload1.ma +++ /dev/null @@ -1,4122 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:28 sparhawk - * Initial revision - * - ***************************************************************************/ - -//Maya ASCII 4.5 scene -//Name: reload1.ma -//Last modified: Mon, Jan 19, 2004 03:16:49 PM -file -r -rpr "MGUN" -rfn "MGUNRN" "P:/Doom/base/models//weapons/machinegun/fred/setup1.mb"; -requires maya "4.5"; -currentUnit -l centimeter -a degree -t film; -fileInfo "application" "maya"; -fileInfo "product" "Maya Complete 4.5"; -fileInfo "version" "4.5"; -fileInfo "cutIdentifier" "200208160001"; -fileInfo "osv" "Microsoft Windows XP Professional Service Pack 1 (Build 2600)\n"; -createNode transform -s -n "persp"; - setAttr ".t" -type "double3" 2.1228346899041561 -0.37960962279220445 -1.2661964059358235 ; - setAttr ".r" -type "double3" -10.530108913648457 266.20000000005223 0 ; -createNode camera -s -n "perspShape" -p "persp"; - setAttr -k off ".v"; - setAttr ".fl" 17.999987882312215; - setAttr ".fcp" 100000; - setAttr ".coi" 9.7619643138363266; - setAttr ".imn" -type "string" "persp"; - setAttr ".den" -type "string" "persp_depth"; - setAttr ".man" -type "string" "persp_mask"; - setAttr ".tp" -type "double3" 11.54789130328736 -1.1785431846986802 2.5898471407854826 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -s -n "top"; - setAttr ".t" -type "double3" 12.086495460819293 100 3.702780271224428 ; - setAttr ".r" -type "double3" -89.999999999999986 0 0 ; -createNode camera -s -n "topShape" -p "top"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 51.71166430753464; - setAttr ".imn" -type "string" "top"; - setAttr ".den" -type "string" "top_depth"; - setAttr ".man" -type "string" "top_mask"; - setAttr ".hc" -type "string" "viewSet -t %camera"; - setAttr ".o" yes; -createNode transform -s -n "front"; - setAttr ".t" -type "double3" 8.1972570459934566 -7.3037643220981252 102.68062202911365 ; -createNode camera -s -n "frontShape" -p "front"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 76.055335105216088; - setAttr ".imn" -type "string" "front"; - setAttr ".den" -type "string" "front_depth"; - setAttr ".man" -type "string" "front_mask"; - setAttr ".hc" -type "string" "viewSet -f %camera"; - setAttr ".o" yes; -createNode transform -s -n "side"; - setAttr ".t" -type "double3" 100 -8.4029823724459547 0.79808365262352066 ; - setAttr ".r" -type "double3" 0 89.999999999999986 0 ; -createNode camera -s -n "sideShape" -p "side"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fcp" 100000; - setAttr ".coi" 100; - setAttr ".ow" 56.76094695621218; - setAttr ".imn" -type "string" "side"; - setAttr ".den" -type "string" "side_depth"; - setAttr ".man" -type "string" "side_mask"; - setAttr ".hc" -type "string" "viewSet -s %camera"; - setAttr ".o" yes; -createNode transform -n "persp1"; - setAttr ".t" -type "double3" 0.2881477838971962 -0.92376001484664716 -0.76948499820717098 ; - setAttr ".r" -type "double3" 2.0698910864099149 -92.999999999990266 0 ; -createNode camera -n "perspShape2" -p "persp1"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fl" 17.999987882312215; - setAttr ".coi" 3.3772936283432382; - setAttr ".imn" -type "string" "persp1"; - setAttr ".den" -type "string" "persp1_depth"; - setAttr ".man" -type "string" "persp1_mask"; - setAttr ".tp" -type "double3" 8.8014802619939321 -6.302417405740858 4.1009811986739688 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode transform -n "persp2"; - setAttr ".t" -type "double3" -6.7227596799464688 0.33401141165756454 -3.6615437550382781 ; - setAttr ".r" -type "double3" -5.7383527295509476 259.40000000000447 0 ; -createNode camera -n "perspShape3" -p "persp2"; - setAttr -k off ".v"; - setAttr ".rnd" no; - setAttr ".fl" 34.999999999999993; - setAttr ".coi" 24.31491973646915; - setAttr ".imn" -type "string" "persp2"; - setAttr ".den" -type "string" "persp2_depth"; - setAttr ".man" -type "string" "persp2_mask"; - setAttr ".tp" -type "double3" 6.3933024329045471 -7.2637683120982235 0.11317560362396772 ; - setAttr ".hc" -type "string" "viewSet -p %camera"; -createNode renderLayer -s -n "globalRender"; -createNode lightLinker -n "lightLinker1"; -createNode displayLayerManager -n "layerManager"; -createNode displayLayer -n "defaultLayer"; -createNode renderLayerManager -n "renderLayerManager"; -createNode renderLayer -n "defaultRenderLayer"; -createNode reference -n "MGUNRN"; -createNode script -n "uiConfigurationScriptNode"; - setAttr ".b" -type "string" ( - "// Maya Mel UI Configuration File.\n" - + "//\n" - + "// This script is machine generated. Edit at your own risk.\n" - + "//\n" - + "//\n" - + "global string $gMainPane;\n" - + "if (`paneLayout -exists $gMainPane`) {\n" - + "\tglobal int $gUseScenePanelConfig;\n" - + "\tint $useSceneConfig = $gUseScenePanelConfig;\n" - + "\tint $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\tint $nVisPanes = `paneLayout -q -nvp $gMainPane`;\n" - + "\tint $nPanes = 0;\n" - + "\tstring $editorName;\n" - + "\tstring $panelName;\n" - + "\tstring $itemFilterName;\n" - + "\tstring $panelConfig;\n" - + "\t//\n" - + "\t// get current state of the UI\n" - + "\t//\n" - + "\tsceneUIReplacement -update $gMainPane;\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Top View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Top View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Top View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"top\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Side View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Side View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Side View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"side\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Front View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Front View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Front View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"front\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"wireframe\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 1\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"modelPanel\" \"Persp View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `modelPanel -unParent -l \"Persp View\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp2\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tmodelPanel -edit -l \"Persp View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " modelEditor -e \n" - + " -camera \"persp2\" \n" - + " -useInteractiveMode 0\n" - + " -displayLights \"default\" \n" - + " -displayAppearance \"smoothShaded\" \n" - + " -activeOnly 0\n" - + " -wireframeOnShaded 0\n" - + " -bufferMode \"double\" \n" - + " -twoSidedLighting 1\n" - + " -backfaceCulling 0\n" - + " -xray 0\n" - + " -displayTextures 1\n" - + " -smoothWireframe 0\n" - + " -textureAnisotropic 0\n" - + " -textureHilight 1\n" - + " -textureSampling 2\n" - + " -textureDisplay \"modulate\" \n" - + " -textureMaxSize 1024\n" - + " -fogging 0\n" - + " -fogSource \"fragment\" \n" - + " -fogMode \"linear\" \n" - + " -fogStart 0\n" - + " -fogEnd 100\n" - + " -fogDensity 0.1\n" - + " -fogColor 0.5 0.5 0.5 1 \n" - + " -sortTransparent 1\n" - + " -nurbsCurves 1\n" - + " -nurbsSurfaces 1\n" - + " -polymeshes 1\n" - + " -subdivSurfaces 1\n" - + " -planes 1\n" - + " -lights 1\n" - + " -cameras 0\n" - + " -controlVertices 1\n" - + " -hulls 1\n" - + " -grid 1\n" - + " -joints 1\n" - + " -ikHandles 1\n" - + " -deformers 1\n" - + " -dynamics 1\n" - + " -fluids 1\n" - + " -locators 1\n" - + " -dimensions 1\n" - + " -handles 1\n" - + " -pivots 1\n" - + " -textures 1\n" - + " -strokes 1\n" - + " -shadows 0\n" - + " $editorName;\n" - + "modelEditor -e -viewSelected 0 $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"outlinerPanel\" \"Outliner\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `outlinerPanel -unParent -l \"Outliner\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\toutlinerPanel -edit -l \"Outliner\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t$editorName = $panelName;\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"worldList\" \n" - + " -selectionConnection \"modelList\" \n" - + " -showShapes 0\n" - + " -showAttributes 0\n" - + " -showConnected 0\n" - + " -showAnimCurvesOnly 0\n" - + " -autoExpand 0\n" - + " -showDagOnly 1\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 0\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 0\n" - + " -highlightActive 1\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"defaultSetFilter\" \n" - + " -showSetMembers 1\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\toutlinerPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"graphEditor\" \"Graph Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"graphEditor\" -l \"Graph Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Graph Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"graphEditorList\" \n" - + " -selectionConnection \"graphEditor1FromOutliner\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 1\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 1\n" - + " -showCompounds 0\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 1\n" - + " -doNotSelectNewObjects 0\n" - + " -dropIsParent 1\n" - + " -transmitFilters 1\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"GraphEd\");\n" - + " animCurveEditor -e \n" - + " -mainListConnection \"graphEditor1FromOutliner\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 1\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"none\" \n" - + " -snapValue \"none\" \n" - + " -showResults \"off\" \n" - + " -showBufferCurves \"off\" \n" - + " -smoothness \"fine\" \n" - + " -resultSamples 1\n" - + " -resultScreenSamples 0\n" - + " -resultUpdate \"delayed\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dopeSheetPanel\" \"Dope Sheet\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dopeSheetPanel\" -l \"Dope Sheet\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dope Sheet\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"OutlineEd\");\n" - + " outlinerEditor -e \n" - + " -mainListConnection \"animationList\" \n" - + " -selectionConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -highlightConnection \"keyframeList\" \n" - + " -showShapes 1\n" - + " -showAttributes 1\n" - + " -showConnected 1\n" - + " -showAnimCurvesOnly 1\n" - + " -autoExpand 0\n" - + " -showDagOnly 0\n" - + " -ignoreDagHierarchy 0\n" - + " -expandConnections 1\n" - + " -showUnitlessCurves 0\n" - + " -showCompounds 1\n" - + " -showLeafs 1\n" - + " -showNumericAttrsOnly 1\n" - + " -highlightActive 0\n" - + " -autoSelectNewObjects 0\n" - + " -doNotSelectNewObjects 1\n" - + " -dropIsParent 1\n" - + " -transmitFilters 0\n" - + " -setFilter \"0\" \n" - + " -showSetMembers 0\n" - + " -allowMultiSelection 1\n" - + " -alwaysToggleSelect 0\n" - + " -directSelect 0\n" - + " -displayMode \"DAG\" \n" - + " -expandObjects 0\n" - + " -setsIgnoreFilters 1\n" - + " -editAttrName 0\n" - + " -showAttrValues 0\n" - + " -highlightSecondary 0\n" - + " -showUVAttrsOnly 0\n" - + " -showTextureNodesOnly 0\n" - + " -sortOrder \"none\" \n" - + " -longNames 0\n" - + " -niceNames 1\n" - + " $editorName;\n" - + "\t\t\t$editorName = ($panelName+\"DopeSheetEd\");\n" - + " dopeSheetEditor -e \n" - + " -mainListConnection \"dopeSheetPanel1FromOutliner\" \n" - + " -highlightConnection \"dopeSheetPanel1OutlinerSelection\" \n" - + " -displayKeys 1\n" - + " -displayTangents 0\n" - + " -displayActiveKeys 0\n" - + " -displayActiveKeyTangents 0\n" - + " -displayInfinities 0\n" - + " -autoFit 0\n" - + " -snapTime \"integer\" \n" - + " -snapValue \"none\" \n" - + " -outliner \"dopeSheetPanel1OutlineEd\" \n" - + " -showSummary 1\n" - + " -showScene 0\n" - + " -hierarchyBelow 0\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"clipEditorPanel\" \"Trax Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"clipEditorPanel\" -l \"Trax Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Trax Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"ClipEditor\");\n" - + " clipEditor -e \n" - + " -characterOutline \"clipEditorPanel1OutlineEditor\" \n" - + " -menuContext \"track\" \n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperGraphPanel\" \"Hypergraph\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperGraphPanel\" -l \"Hypergraph\" -mbv $menusOkayInPanels `;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232655\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypergraph\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\t\t$editorName = ($panelName+\"HyperGraphEd\");\n" - + " hyperGraph -e \n" - + " -orientation \"horiz\" \n" - + " -zoom 0.232655\n" - + " -animateTransition 0\n" - + " -showShapes 0\n" - + " -showDeformers 0\n" - + " -showExpressions 0\n" - + " -showConstraints 0\n" - + " -showUnderworld 0\n" - + " -showInvisible 0\n" - + " -transitionFrames 5\n" - + " -freeform 0\n" - + " -imageEnabled 0\n" - + " -graphType \"DAG\" \n" - + " -updateSelection 1\n" - + " -updateNodeAdded 1\n" - + " $editorName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + "\t\tscriptedPanel -e -to $panelName;\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"hyperShadePanel\" \"Hypershade\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"hyperShadePanel\" -l \"Hypershade\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Hypershade\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"visorPanel\" \"Visor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"visorPanel\" -l \"Visor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Visor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"polyTexturePlacementPanel\" \"UV Texture Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"polyTexturePlacementPanel\" -l \"UV Texture Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"UV Texture Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"multiListerPanel\" \"Multilister\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"multiListerPanel\" -l \"Multilister\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Multilister\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"renderWindowPanel\" \"Render View\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"renderWindowPanel\" -l \"Render View\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Render View\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"blendShapePanel\" \"Blend Shape\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tblendShapePanel -unParent -l \"Blend Shape\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tblendShapePanel -edit -l \"Blend Shape\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynRelEdPanel\" \"Dynamic Relationships\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynRelEdPanel\" -l \"Dynamic Relationships\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Dynamic Relationships\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextPanel \"devicePanel\" \"Devices\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\tdevicePanel -unParent -l \"Devices\" -mbv $menusOkayInPanels ;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tdevicePanel -edit -l \"Devices\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"relationshipPanel\" \"Relationship Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"relationshipPanel\" -l \"Relationship Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Relationship Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"referenceEditorPanel\" \"Reference Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"referenceEditorPanel\" -l \"Reference Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Reference Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"componentEditorPanel\" \"Component Editor\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"componentEditorPanel\" -l \"Component Editor\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Component Editor\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\t$panelName = `sceneUIReplacement -getNextScriptedPanel \"dynPaintScriptedPanelType\" \"Paint Effects\"`;\n" - + "\tif (\"\" == $panelName) {\n" - + "\t\tif ($useSceneConfig) {\n" - + "\t\t\t$panelName = `scriptedPanel -unParent -type \"dynPaintScriptedPanelType\" -l \"Paint Effects\" -mbv $menusOkayInPanels `;\n" - + "\t\t}\n" - + "\t} else {\n" - + "\t\t$label = `panel -q -label $panelName`;\n" - + "\t\tscriptedPanel -edit -l \"Paint Effects\" -mbv $menusOkayInPanels $panelName;\n" - + "\t\tif (!$useSceneConfig) {\n" - + "\t\t\tpanel -e -l $label $panelName;\n" - + "\t\t}\n" - + "\t}\n" - + "\tif ($useSceneConfig) {\n" - + " string $configName = `getPanel -cwl \"Current Layout\"`;\n" - + " if (\"\" != $configName) {\n" - + "\t\t\tpanelConfiguration -edit -label \"Current Layout\"\n" - + "\t\t\t\t-defaultImage \"\"\n" - + "\t\t\t\t-image \"\"\n" - + "\t\t\t\t-sc false\n" - + "\t\t\t\t-configString \"global string $gMainPane; paneLayout -e -cn \\\"single\\\" -ps 1 100 100 $gMainPane;\"\n" - + "\t\t\t\t-removeAllPanels\n" - + "\t\t\t\t-ap false\n" - + "\t\t\t\t\t\"Persp View\"\n" - + "\t\t\t\t\t\"modelPanel\"\n" - + "\t\t\t\t\t\"$panelName = `modelPanel -unParent -l \\\"Persp View\\\" -mbv $menusOkayInPanels `;\\n$editorName = $panelName;\\nmodelEditor -e \\n -camera \\\"persp2\\\" \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t\t\"modelPanel -edit -l \\\"Persp View\\\" -mbv $menusOkayInPanels $panelName;\\n$editorName = $panelName;\\nmodelEditor -e \\n -camera \\\"persp2\\\" \\n -useInteractiveMode 0\\n -displayLights \\\"default\\\" \\n -displayAppearance \\\"smoothShaded\\\" \\n -activeOnly 0\\n -wireframeOnShaded 0\\n -bufferMode \\\"double\\\" \\n -twoSidedLighting 1\\n -backfaceCulling 0\\n -xray 0\\n -displayTextures 1\\n -smoothWireframe 0\\n -textureAnisotropic 0\\n -textureHilight 1\\n -textureSampling 2\\n -textureDisplay \\\"modulate\\\" \\n -textureMaxSize 1024\\n -fogging 0\\n -fogSource \\\"fragment\\\" \\n -fogMode \\\"linear\\\" \\n -fogStart 0\\n -fogEnd 100\\n -fogDensity 0.1\\n -fogColor 0.5 0.5 0.5 1 \\n -sortTransparent 1\\n -nurbsCurves 1\\n -nurbsSurfaces 1\\n -polymeshes 1\\n -subdivSurfaces 1\\n -planes 1\\n -lights 1\\n -cameras 0\\n -controlVertices 1\\n -hulls 1\\n -grid 1\\n -joints 1\\n -ikHandles 1\\n -deformers 1\\n -dynamics 1\\n -fluids 1\\n -locators 1\\n -dimensions 1\\n -handles 1\\n -pivots 1\\n -textures 1\\n -strokes 1\\n -shadows 0\\n $editorName;\\nmodelEditor -e -viewSelected 0 $editorName\"\n" - + "\t\t\t\t$configName;\n" - + " setNamedPanelLayout \"Current Layout\";\n" - + " }\n" - + " panelHistory -e -clear mainPanelHistory;\n" - + " setFocus `paneLayout -q -p1 $gMainPane`;\n" - + " sceneUIReplacement -deleteRemaining;\n" - + " sceneUIReplacement -clear;\n" - + "\t}\n" - + "grid -spacing 8 -size 400 -divisions 2 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\n" - + "}\n"); - setAttr ".st" 3; -createNode script -n "sceneConfigurationScriptNode"; - setAttr ".b" -type "string" "playbackOptions -min 1 -max 60 -ast 1 -aet 60 "; - setAttr ".st" 6; -createNode animCurveTU -n "MGUN_Rloarm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 12 1 20 1 23 1 35 1 52 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Rloarm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 4.5574157893921452 12 14.016575258137484 - 20 16.079150038692706 23 16.65876360262633 35 17.33053453692613 52 4.5574157893921452; -createNode animCurveTL -n "MGUN_Rloarm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -21.710493028270307 12 -23.260331009672019 - 20 -25.252979842902793 23 -23.837791963854585 35 -24.920871704030997 52 -21.710493028270307; -createNode animCurveTL -n "MGUN_Rloarm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 7.2248224370480481 12 2.792795871015417 - 20 1.6398058565314413 23 1.7369856980933895 35 3.1184023055732819 52 7.2248224370480481; -createNode animCurveTA -n "MGUN_Rloarm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 23.858970583210471 12 11.330105009920073 - 20 6.985699928423136 23 6.3699375129522213 35 6.985699928423136 52 23.858970583210471; -createNode animCurveTA -n "MGUN_Rloarm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -12.978384796886047 12 10.816101749424362 - 20 14.000103089115454 23 14.670575305104764 35 14.000103089115454 52 -12.978384796886047; -createNode animCurveTA -n "MGUN_Rloarm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1.3183589787639254 12 -47.646264651233622 - 20 -67.660557605692816 23 -70.365999815169474 35 -67.660557605692816 52 1.3183589787639254; -createNode animCurveTU -n "MGUN_Rloarm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 12 1 20 1 23 1 35 1 52 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 12 1 20 1 23 1 35 1 52 1; -createNode animCurveTU -n "MGUN_Rloarm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 12 1 20 1 23 1 35 1 52 1; -createNode animCurveTU -n "MGUN_Hand_Const_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8 1 12 1 15 1 20 1 24 1 31 - 1 36 1 40 1 44 1 47 1 49 1 52 1 60 1; - setAttr -s 14 ".kot[0:13]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5; -createNode animCurveTA -n "MGUN_Hand_Const_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -37.608163408585355 8 -64.821384981017658 - 12 -63.463781860339047 15 -44.757390418505452 20 -19.704651590275891 24 -24.375228193909113 - 31 -15.383888286047913 36 -6.8834053889431992 40 -15.574701038712893 44 -23.102630397103507 - 47 -20.303433915064289 49 -26.156687756313794 52 -37.608163408585355 60 -37.608163408585355; -createNode animCurveTA -n "MGUN_Hand_Const_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 22.319551010407952 8 32.69489905815459 - 12 32.706564518001898 15 57.164039079001412 20 52.996936541228656 24 53.050202117678623 - 31 50.546762934422659 36 38.343689279080571 40 18.909799741962644 44 23.629383951447029 - 47 26.362640386964948 49 26.073757922349117 52 22.319551010407952 60 22.319551010407952; -createNode animCurveTA -n "MGUN_Hand_Const_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 -80.85420450705162 8 -81.195011962967101 - 12 -78.121597160486957 15 -60.13574261669801 20 -14.978743206546778 24 -20.061591516801002 - 31 -34.348670516524464 36 -20.440640630986735 40 -10.822403917528604 44 -27.13150041011049 - 47 -55.228800244051087 49 -81.04227693203039 52 -80.85420450705162 60 -80.85420450705162; -createNode animCurveTU -n "MGUN_Hand_Const_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8 1 12 1 15 1 20 1 24 1 31 - 1 36 1 40 1 44 1 47 1 49 1 52 1 60 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8 1 12 1 15 1 20 1 24 1 31 - 1 36 1 40 1 44 1 47 1 49 1 52 1 60 1; -createNode animCurveTU -n "MGUN_Hand_Const_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 14 ".ktv[0:13]" 1 1 8 1 12 1 15 1 20 1 24 1 31 - 1 36 1 40 1 44 1 47 1 49 1 52 1 60 1; -createNode animCurveTU -n "MGUN_Luparm_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 12 1 25 1 41 1 44 1 52 1 60 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Luparm_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -0.37809955776404236 12 1.7459654711594861 - 25 -2.4329618510351017 41 -6.3370567113598533 44 -2.8760706044466753 52 -4.1922251727147977 - 60 -0.76865428638383371; -createNode animCurveTL -n "MGUN_Luparm_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -19.397540168639082 12 -20.947378150040798 - 25 -28.246190500320857 41 -26.656725442511778 44 -26.468966031050876 52 -19.397540168639082 - 60 -19.397540168639082; -createNode animCurveTL -n "MGUN_Luparm_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 -6.7423962534162056 12 -3.1182497663530828 - 25 -0.066952419548223577 41 -5.8046121843621812 44 -7.5248856298196776 52 - -6.173742055629635 60 -7.6408325817031519; -createNode animCurveTA -n "MGUN_Luparm_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 70.326658910521701 12 16.041939771890728 - 25 19.508369894880815 41 20.779123634841163 44 31.821575100583946 52 59.565588664864769 - 60 70.032641814667315; -createNode animCurveTA -n "MGUN_Luparm_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 42.086533313608697 12 61.380627451536668 - 25 54.433830026479605 41 127.49943513572663 44 126.18695176503374 52 52.078481091066884 - 60 41.351515250971673; -createNode animCurveTA -n "MGUN_Luparm_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 37.372696357515984 12 24.60252746625185 - 25 -3.6021063619379428 41 14.430812186083235 44 40.241862909634847 52 32.918734327901021 - 60 44.258915076132375; -createNode animCurveTU -n "MGUN_Luparm_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 12 1 25 1 41 1 44 1 52 1 60 - 1; -createNode animCurveTU -n "MGUN_Luparm_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 12 1 25 1 41 1 44 1 52 1 60 - 1; -createNode animCurveTU -n "MGUN_Luparm_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 1 1 12 1 25 1 41 1 44 1 52 1 60 - 1; -createNode animCurveTU -n "MGUN_Ext_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 16 1 18 1 46 1 49 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Ext_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 2.9266984917693435 16 2.9266984917693435 - 18 2.9266984917693435 46 2.9266984917693435 49 2.9266984917693435; -createNode animCurveTL -n "MGUN_Ext_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 3.6288191942702444 16 3.6288191942702444 - 18 3.6288191942702444 46 3.6288191942702444 49 3.6288191942702444; -createNode animCurveTL -n "MGUN_Ext_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 2.2443498069495047 16 2.2443498069495047 - 18 2.2443498069495047 46 2.2443498069495047 49 2.2443498069495047; -createNode animCurveTA -n "MGUN_Ext_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 0 16 9.7999208463873302 18 14.451877741908055 - 46 9.7999208463873302 49 0; -createNode animCurveTA -n "MGUN_Ext_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 -28.518133962388895 16 -26.915223649200353 - 18 -24.854557102760651 46 -26.915223649200353 49 -28.518133962388895; -createNode animCurveTA -n "MGUN_Ext_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 0 16 -20.885646746993839 18 - -31.515017869484382 46 -20.885646746993839 49 0; -createNode animCurveTU -n "MGUN_Ext_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 16 1 18 1 46 1 49 1; -createNode animCurveTU -n "MGUN_Ext_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 16 1 18 1 46 1 49 1; -createNode animCurveTU -n "MGUN_Ext_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 13 1 16 1 18 1 46 1 49 1; -createNode animCurveTU -n "MGUN_Cli_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 1 20 1 22 1 39 1 41 1 46 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Cli_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 -5.090296613812721 20 -12.251287456403215 - 22 -22.47589625219744 39 -22.560677097863678 41 -13.993528209092069 46 -5.090296613812721; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "MGUN_Cli_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 0.81101914312491763 20 -0.29170918481534075 - 22 -2.8957803599708063 39 -3.6410154775252979 41 -0.76975279919813222 46 - 0.81101914312491763; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTL -n "MGUN_Cli_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 -0.061867831930466771 20 -0.22427229528175899 - 22 -1.4396604390177081 39 0.54834378996618094 41 -0.32163202252991185 46 - -0.061867831930466771; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "MGUN_Cli_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 0 20 0 22 0 39 0 41 0 46 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "MGUN_Cli_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 0 20 0 22 0 39 0 41 0 46 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTA -n "MGUN_Cli_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 0 20 0 22 9.9275789368945713 - 39 9.9275789368945713 41 7.5373382214766158 46 0; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "MGUN_Cli_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 1 20 1 22 1 39 1 41 1 46 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "MGUN_Cli_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 1 20 1 22 1 39 1 41 1 46 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "MGUN_Cli_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 17 1 20 1 22 1 39 1 41 1 46 1; - setAttr -s 6 ".kit[5]" 3; - setAttr -s 6 ".kot[5]" 3; -createNode animCurveTU -n "MGUN_Connector_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Connector_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 10.088378891733456; -createNode animCurveTL -n "MGUN_Connector_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 -1.433273439350919; -createNode animCurveTL -n "MGUN_Connector_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 -0.26979052810693338; -createNode animCurveTA -n "MGUN_Connector_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 184.55921161476257; -createNode animCurveTA -n "MGUN_Connector_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 -29.104076635906718; -createNode animCurveTA -n "MGUN_Connector_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 -156.52701371658429; -createNode animCurveTU -n "MGUN_Connector_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 1; -createNode animCurveTU -n "MGUN_Connector_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 1; -createNode animCurveTU -n "MGUN_Connector_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr ".ktv[0]" 5 1; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 1 5 1 8 1 9 1 10 1 11 1 17 1 - 18 1 20 1 21 1 25 1 29 1 34 1 39 1 42 1 44 1 47 1 48 1 50 1 53 1 56 1 57 - 1 58 1 59 1 60 1; - setAttr -s 25 ".kot[0:24]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 18.248571701804728 5 16.393202036777154 - 8 10.896929322099259 9 11.652773926581535 10 12.067138166110071 11 12.35979042314478 - 17 12.35979042314478 18 10.975064122116146 20 8.9305104423232322 21 5.4919526825456293 - 25 8.1699404378262628 29 11.317878710880855 34 11.317878710880855 39 -1.3102815662615486 - 42 0.4546507574550207 44 3.3175995700507421 47 5.508290301347345 48 6.2459470382495219 - 50 7.5624934362873617 53 8.4607682088652822 56 10.193206802637775 57 11.705378936737384 - 58 13.307223347256281 59 12.936389054204033 60 18.248571701804728; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 -20.558540398701673 5 -10.830774916549961 - 8 -6.4177569046168532 9 -1.2733411072655121 10 -1.2275618161569126 11 -1.4387255304999726 - 17 -1.4387255304999726 18 -2.308009701741522 20 -3.7107197512028405 21 -8.5174255192853856 - 25 -11.170760760555268 29 -15.714458847487768 34 -15.714458847487768 39 -14.577159768870235 - 42 -9.8381088357805915 44 -5.7474883999357695 47 -2.2946160966747349 48 -1.846984294158392 - 50 -2.3378462452816855 53 -7.8640009703728886 56 -10.269221537238881 57 -10.668203644034195 - 58 -11.052086398427697 59 -10.740890953295292 60 -20.558540398701673; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTL -n "MGUN_LHAND_GOAL_OFF_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 2.6757355999372985 5 -3.2717325429345441 - 8 -3.9943255232009678 9 0.92744026468344321 10 1.8008290834669549 11 2.2756669736186756 - 17 2.2756669736186756 18 1.4906996510564263 20 0.32068625909967974 21 -1.8530259004064129 - 25 -0.75514042127458036 29 0.91891197267370561 34 0.91891197267370561 39 - -1.1086838419825762 42 -2.2039295622617305 44 -1.5394419658261409 47 0.20869838329936086 - 48 -0.42889500414830262 50 -2.3962042344192316 53 -2.524123160489069 56 -1.8954200453121386 - 57 -0.7115869295912749 58 -1.0118138579757383 59 -0.69435399342952042 60 - 2.6757355999372985; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 175.04694820912425 5 122.15309731402773 - 8 115.69186784352652 9 101.91972198970069 10 131.17840975465114 11 157.92775532370973 - 17 157.92775532370973 18 192.88525355662927 20 243.68817087832142 21 276.35612022014493 - 25 215.32855295798072 29 124.60687855882377 34 124.60687855882377 39 129.32627999765396 - 42 132.83751467427066 44 138.48977456908005 47 146.7308123045479 48 112.75993288498833 - 50 159.58899685389966 53 229.03398250272622 56 300.28018056134795 57 268.47714967918949 - 58 218.13832203478967 59 173.37813423336138 60 175.04694820912425; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 -25.021230763542317 5 -53.514473282087316 - 8 -40.146145083775096 9 -77.894488601787018 10 -83.435987851452339 11 -80.435734324974973 - 17 -80.435734324974973 18 -76.548287863135243 20 -70.485276746920121 21 -65.048980927320997 - 25 -49.419878157976136 29 -82.487367186205816 34 -82.487367186205816 39 -47.803542871332425 - 42 -21.998777371463898 44 -9.0458115823371745 47 -48.913558606468257 48 -35.94482190682389 - 50 -65.698944058354613 53 -79.315171717463855 56 -81.983685471989432 57 -73.67464264834399 - 58 -59.011263519263416 59 -42.773940036613169 60 -25.021230763542317; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTA -n "MGUN_LHAND_GOAL_OFF_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 -155.53426393850688 5 -118.51855563090983 - 8 -59.221067138803157 9 -27.12981075824446 10 -53.497743198925328 11 -77.684616723155997 - 17 -77.684616723155997 18 -109.06501717360489 20 -155.02865710036821 21 -185.92066717828862 - 25 -150.61298197031007 29 -46.042673650943719 34 -46.042673650943719 39 -15.038418341762773 - 42 8.0287474560305743 44 25.35414948378725 47 -51.167354264737398 48 -36.304692142151509 - 50 -65.301623391608857 53 -158.98209938307366 56 -297.66440886724786 57 -266.11512182299242 - 58 -211.69853828643798 59 -161.53932569862337 60 -155.53426393850688; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 2.9044411307187503 5 2.9044411307187503 - 8 2.9044411307187503 9 2.9044411307187503 10 2.9044411307187503 11 2.9044411307187503 - 17 2.9044411307187503 18 2.9044411307187503 20 2.9044411307187503 21 2.9044411307187503 - 25 2.9044411307187503 29 2.9044411307187503 34 2.9044411307187503 39 2.9044411307187503 - 42 2.9044411307187503 44 2.9044411307187503 47 2.9044411307187503 48 2.9044411307187503 - 50 2.9044411307187503 53 2.9044411307187503 56 2.9044411307187503 57 2.9044411307187503 - 58 2.9044411307187503 59 2.9044411307187503 60 2.9044411307187503; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 2.9044411307187503 5 2.9044411307187503 - 8 2.9044411307187503 9 2.9044411307187503 10 2.9044411307187503 11 2.9044411307187503 - 17 2.9044411307187503 18 2.9044411307187503 20 2.9044411307187503 21 2.9044411307187503 - 25 2.9044411307187503 29 2.9044411307187503 34 2.9044411307187503 39 2.9044411307187503 - 42 2.9044411307187503 44 2.9044411307187503 47 2.9044411307187503 48 2.9044411307187503 - 50 2.9044411307187503 53 2.9044411307187503 56 2.9044411307187503 57 2.9044411307187503 - 58 2.9044411307187503 59 2.9044411307187503 60 2.9044411307187503; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 2.9044411307187503 5 2.9044411307187503 - 8 2.9044411307187503 9 2.9044411307187503 10 2.9044411307187503 11 2.9044411307187503 - 17 2.9044411307187503 18 2.9044411307187503 20 2.9044411307187503 21 2.9044411307187503 - 25 2.9044411307187503 29 2.9044411307187503 34 2.9044411307187503 39 2.9044411307187503 - 42 2.9044411307187503 44 2.9044411307187503 47 2.9044411307187503 48 2.9044411307187503 - 50 2.9044411307187503 53 2.9044411307187503 56 2.9044411307187503 57 2.9044411307187503 - 58 2.9044411307187503 59 2.9044411307187503 60 2.9044411307187503; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTU -n "MGUN_LHAND_GOAL_OFF_CONNECT"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 4 1 5 0 8 0 9 2 10 2 11 2 17 2 - 18 2 20 2 21 0 25 0 29 0 34 0 39 0 42 0 44 0 47 0 48 -0.014233074583605461 - 50 -0.056304666437258177 53 -0.12244898212704429 56 -0.18148687651619516 - 57 -0.19100259091530022 58 -0.17962760396905306 59 0 60 1; - setAttr -s 25 ".kit[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; - setAttr -s 25 ".kot[0:24]" 3 9 9 9 9 9 9 - 9 9 9 9 3 3 9 9 9 9 9 9 9 9 9 - 9 9 3; -createNode animCurveTU -n "MGUN_Lindex_base_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 17 1 22 1 44 1 48 1 51 - 1 55 1 60 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_Lindex_base_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0.39625406489899645 9 0.39625406489899645 - 17 0.39625406489899645 22 0.39625406489899645 44 0.39625406489899645 48 0.39625406489899645 - 51 0.39625406489899645 55 0.39625406489899645 60 0.39625406489899645; -createNode animCurveTL -n "MGUN_Lindex_base_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 2.3867477363767935 9 2.3867477363767935 - 17 2.3867477363767935 22 2.3867477363767935 44 2.3867477363767935 48 2.3867477363767935 - 51 2.3867477363767935 55 2.3867477363767935 60 2.3867477363767935; -createNode animCurveTL -n "MGUN_Lindex_base_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -2.950206629111412 9 -2.950206629111412 - 17 -2.950206629111412 22 -2.950206629111412 44 -2.950206629111412 48 -2.950206629111412 - 51 -2.950206629111412 55 -2.950206629111412 60 -2.950206629111412; -createNode animCurveTA -n "MGUN_Lindex_base_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0 9 0 17 0 22 0 44 0 48 0 51 - 0 55 0 60 0; -createNode animCurveTA -n "MGUN_Lindex_base_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0 9 0 17 0 22 0 44 0 48 0 51 - 0 55 0 60 0; -createNode animCurveTA -n "MGUN_Lindex_base_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 45.133024472761669 9 -10.496959597689308 - 17 15.702957127863865 22 8.0898718677090447 44 8.0898718677090447 48 46.724815327965302 - 51 65.255604675593091 55 -2.6534115479790072 60 45.133024472761669; -createNode animCurveTU -n "MGUN_Lindex_base_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 17 1 22 1 44 1 48 1 51 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Lindex_base_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 17 1 22 1 44 1 48 1 51 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Lindex_base_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 17 1 22 1 44 1 48 1 51 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Linkdex_mid_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 12 1 17 1 22 1 25 1 44 - 1 55 1 60 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_Linkdex_mid_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -0.65589229936799853 9 -0.65589229936799853 - 12 -0.65589229936799853 17 -0.65589229936799853 22 -0.65589229936799853 25 - -0.65589229936799853 44 -0.65589229936799853 55 -0.65589229936799853 60 -0.65589229936799853; -createNode animCurveTL -n "MGUN_Linkdex_mid_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0.95563043090752642 9 0.95563043090752642 - 12 0.95563043090752642 17 0.95563043090752642 22 0.95563043090752642 25 0.95563043090752642 - 44 0.95563043090752642 55 0.95563043090752642 60 0.95563043090752642; -createNode animCurveTL -n "MGUN_Linkdex_mid_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -0.026607907257882743 9 -0.026607907257882743 - 12 -0.026607907257882743 17 -0.026607907257882743 22 -0.026607907257882743 - 25 -0.026607907257882743 44 -0.026607907257882743 55 -0.026607907257882743 - 60 -0.026607907257882743; -createNode animCurveTA -n "MGUN_Linkdex_mid_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -1.5554401750069307 9 1.6805605072177257 - 12 1.6805605072177257 17 -0.27233220751066395 22 2.3957823720544944 25 0.35102270537686875 - 44 0.35102270537686875 55 1.9203855801333809 60 -1.5554401750069307; -createNode animCurveTA -n "MGUN_Linkdex_mid_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -6.0476935949915633 9 -6.0142412143301396 - 12 -6.0142412143301396 17 -6.2378785038946054 22 -5.7675496535679356 25 -6.2339609774000353 - 44 -6.2339609774000353 55 -5.9422514226766809 60 -6.0476935949915633; -createNode animCurveTA -n "MGUN_Linkdex_mid_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 50.828663395704197 9 20.732420710916237 - 12 20.732420710916237 17 38.880737306028927 22 13.772286132874681 25 33.146748330796818 - 44 33.146748330796818 55 18.430057596772791 60 50.828663395704197; -createNode animCurveTU -n "MGUN_Linkdex_mid_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 12 1 17 1 22 1 25 1 44 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Linkdex_mid_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 12 1 17 1 22 1 25 1 44 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Linkdex_mid_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 9 1 12 1 17 1 22 1 25 1 44 - 1 55 1 60 1; -createNode animCurveTU -n "MGUN_Gun2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 1 13 1 14 1 45 1 47 1 48 1 50 - 1 55 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "MGUN_Gun2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 -0.16132354913516858 13 -0.16132354913516858 - 14 -0.16132354913516858 45 -0.16132354913516858 47 -0.16132354913516858 48 - -0.16132354913516858 50 -0.16132354913516858 55 -0.16132354913516858; -createNode animCurveTL -n "MGUN_Gun2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 -0.05416238191776683 13 -0.05416238191776683 - 14 -0.05416238191776683 45 -0.05416238191776683 47 -0.05416238191776683 48 - -0.05416238191776683 50 -0.05416238191776683 55 -0.05416238191776683; -createNode animCurveTL -n "MGUN_Gun2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 -0.022183441315541959 13 -0.022183441315541959 - 14 -0.022183441315541959 45 -0.022183441315541959 47 -0.022183441315541959 - 48 -0.022183441315541959 50 -0.022183441315541959 55 -0.022183441315541959; -createNode animCurveTA -n "MGUN_Gun2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 0 13 7.963472749188881 14 0 - 45 0 47 -1.0185284469223708 48 0 50 5.079334404149467 55 0; -createNode animCurveTA -n "MGUN_Gun2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 0 13 -0.37211949859904458 14 - 0 45 0 47 3.4347042456394914 48 0 50 2.9586806676707926 55 0; -createNode animCurveTA -n "MGUN_Gun2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 0 13 2.658144230839639 14 0 - 45 0 47 -6.3219575334722737 48 0 50 -0.41175121937862558 55 0; -createNode animCurveTU -n "MGUN_Gun2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 1 13 1 14 1 45 1 47 1 48 1 50 - 1 55 1; -createNode animCurveTU -n "MGUN_Gun2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 1 13 1 14 1 45 1 47 1 48 1 50 - 1 55 1; -createNode animCurveTU -n "MGUN_Gun2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 11 1 13 1 14 1 45 1 47 1 48 1 50 - 1 55 1; -createNode animCurveTU -n "MGUN_locator7_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 17 1 24 1 40 1 50 1 60 1; - setAttr -s 6 ".kot[0:5]" 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_locator7_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -2.1947366122839007 17 7.9028306481625794 - 24 7.9000013315106923 40 6.7181766715182718 50 -0.92655430788114401 60 -2.1947366122839007; -createNode animCurveTL -n "MGUN_locator7_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 10.560095940452598 17 11.370677755904762 - 24 11.596071858550872 40 13.369490170126843 50 10.560095940452598 60 10.560095940452598; -createNode animCurveTL -n "MGUN_locator7_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -3.598167567107895 17 -4.0153751612140258 - 24 -3.598167567107895 40 -5.9363786908504768 50 -4.5889349924225487 60 -3.598167567107895; -createNode animCurveTA -n "MGUN_locator7_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 17 0 24 0 40 0 50 0 60 0; -createNode animCurveTA -n "MGUN_locator7_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 -29.205417093903414 17 -29.205417093903414 - 24 -29.205417093903414 40 -29.205417093903414 50 -29.205417093903414 60 -29.205417093903414; -createNode animCurveTA -n "MGUN_locator7_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 0 17 0 24 0 40 0 50 0 60 0; -createNode animCurveTU -n "MGUN_locator7_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 17 1 24 1 40 1 50 1 60 1; -createNode animCurveTU -n "MGUN_locator7_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 17 1 24 1 40 1 50 1 60 1; -createNode animCurveTU -n "MGUN_locator7_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 6 ".ktv[0:5]" 1 1 17 1 24 1 40 1 50 1 60 1; -createNode animCurveTU -n "MGUN_locator8_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 59 1 60 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "MGUN_locator8_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 17.853467334841042 2 -25.071436062830855 - 59 -25.071436062830855 60 17.853467334841042; -createNode animCurveTL -n "MGUN_locator8_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 -5.2290123649222391 2 -22.501466508305754 - 59 -22.501466508305754 60 -5.2290123649222391; -createNode animCurveTL -n "MGUN_locator8_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 2.7392944515744202 2 2.2069024635974057 - 59 2.2069024635974057 60 2.7392944515744202; -createNode animCurveTA -n "MGUN_locator8_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 59 0 60 0; -createNode animCurveTA -n "MGUN_locator8_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 59 0 60 0; -createNode animCurveTA -n "MGUN_locator8_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 0 2 0 59 0 60 0; -createNode animCurveTU -n "MGUN_locator8_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 59 1 60 1; -createNode animCurveTU -n "MGUN_locator8_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 59 1 60 1; -createNode animCurveTU -n "MGUN_locator8_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 1 1 2 1 59 1 60 1; -createNode animCurveTU -n "MGUN_locator11_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 1 9 1 13 1 15 1 17 1 18 1 20 - 1 21 1 22 1 24 1 29 1 34 1 39 1 41 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 - 1 52 1 53 1 60 1; - setAttr -s 25 ".kot[0:24]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "MGUN_locator11_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 -0.6412044098427464 9 -6.1449440308172294 - 13 -0.68550166095143938 15 -0.84024228234501352 17 -6.8494242664466043 18 - -9.3322728772795234 20 -15.695258779244879 21 -0.52475540847197955 22 1.6032254780838957 - 24 1.4584929763523804 29 11.303089521674728 34 6.4528276335922081 39 4.9929947447091285 - 41 -2.4190659418012759 44 -2.2252646577928998 45 -14.368574805129816 46 -11.626833777934651 - 47 -5.344525642505868 48 0.23289135284488977 49 5.6172163544557101 50 6.2245002820910189 - 51 6.5669251366412302 52 2.5437331287944964 53 -0.008584120126517096 60 0.16709843403574687; -createNode animCurveTL -n "MGUN_locator11_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 -5.6404940201014764 9 -4.0648930010107316 - 13 -9.7356153927323899 15 -9.5644900305245937 17 -15.009053591173505 18 -12.736851844204622 - 20 -12.088429127692727 21 3.1223033008074674 22 -0.70875380912936348 24 -3.2367904382400265 - 29 2.9548560344854282 34 6.9022123526941321 39 17.03910326914437 41 4.3022015144229035 - 44 0.54263204080144101 45 -1.6204973833561858 46 -6.3406940211584066 47 -7.759614899042715 - 48 -7.8480518562161281 49 -8.7625800361354287 50 -7.0961325843864076 51 -6.4095961367116541 - 52 -4.9337204409802506 53 1.9557392103152131 60 -6.7016063978412239; -createNode animCurveTL -n "MGUN_locator11_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 -2.3079669473746907 9 9.0749743840402672 - 13 12.658996166874893 15 11.721344046177904 17 10.735483934714351 18 13.951654385557411 - 20 10.199836030888497 21 -27.311470350222269 22 -28.420451745936074 24 -26.899554194992749 - 29 -24.885620227121311 34 -20.254173443077622 39 -17.030760887938957 41 -19.063505741725422 - 44 -17.449610162389675 45 -9.4939992427447777 46 6.1808733757021157 47 10.508178262522442 - 48 12.21541234625983 49 4.4359835395353668 50 4.6265112678419218 51 5.6230009281081355 - 52 8.3962903757599161 53 10.290010092828966 60 -2.5491118783598581; -createNode animCurveTA -n "MGUN_locator11_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 6.6843893727596484 9 6.6843893727596484 - 13 6.6843893727596484 15 6.6843893727596484 17 6.6843893727596484 18 6.6843893727596484 - 20 6.6843893727596484 21 6.6843893727596484 22 6.6843893727596484 24 6.6843893727596484 - 29 6.6843893727596484 34 6.6843893727596484 39 6.6843893727596484 41 6.6843893727596484 - 44 6.6843893727596484 45 6.6843893727596484 46 6.6843893727596484 47 6.6843893727596484 - 48 6.6843893727596484 49 6.6843893727596484 50 6.6843893727596484 51 6.6843893727596484 - 52 6.6843893727596484 53 6.6843893727596484 60 6.6843893727596484; -createNode animCurveTA -n "MGUN_locator11_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 -3.8301616494454134 9 -3.8301616494454134 - 13 -3.8301616494454134 15 -3.8301616494454134 17 -3.8301616494454134 18 -3.8301616494454134 - 20 -3.8301616494454134 21 -3.8301616494454134 22 -3.8301616494454134 24 -3.8301616494454134 - 29 -3.8301616494454134 34 -3.8301616494454134 39 -3.8301616494454134 41 -3.8301616494454134 - 44 -3.8301616494454134 45 -3.8301616494454134 46 -3.8301616494454134 47 -3.8301616494454134 - 48 -3.8301616494454134 49 -3.8301616494454134 50 -3.8301616494454134 51 -3.8301616494454134 - 52 -3.8301616494454134 53 -3.8301616494454134 60 -3.8301616494454134; -createNode animCurveTA -n "MGUN_locator11_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 -179.15263870142536 9 -179.15263870142536 - 13 -179.15263870142536 15 -179.15263870142536 17 -179.15263870142536 18 -179.15263870142536 - 20 -179.15263870142536 21 -179.15263870142536 22 -179.15263870142536 24 -179.15263870142536 - 29 -179.15263870142536 34 -179.15263870142536 39 -179.15263870142536 41 -179.15263870142536 - 44 -179.15263870142536 45 -179.15263870142536 46 -179.15263870142536 47 -179.15263870142536 - 48 -179.15263870142536 49 -179.15263870142536 50 -179.15263870142536 51 -179.15263870142536 - 52 -179.15263870142536 53 -179.15263870142536 60 -179.15263870142536; -createNode animCurveTU -n "MGUN_locator11_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 1.0000000000000002 9 1.0000000000000002 - 13 1.0000000000000002 15 1.0000000000000002 17 1.0000000000000002 18 1.0000000000000002 - 20 1.0000000000000002 21 1.0000000000000002 22 1.0000000000000002 24 1.0000000000000002 - 29 1.0000000000000002 34 1.0000000000000002 39 1.0000000000000002 41 1.0000000000000002 - 44 1.0000000000000002 45 1.0000000000000002 46 1.0000000000000002 47 1.0000000000000002 - 48 1.0000000000000002 49 1.0000000000000002 50 1.0000000000000002 51 1.0000000000000002 - 52 1.0000000000000002 53 1.0000000000000002 60 1.0000000000000002; -createNode animCurveTU -n "MGUN_locator11_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 1 9 1 13 1 15 1 17 1 18 1 20 - 1 21 1 22 1 24 1 29 1 34 1 39 1 41 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 - 1 52 1 53 1 60 1; -createNode animCurveTU -n "MGUN_locator11_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 25 ".ktv[0:24]" 1 1 9 1 13 1 15 1 17 1 18 1 20 - 1 21 1 22 1 24 1 29 1 34 1 39 1 41 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 - 1 52 1 53 1 60 1; -createNode animCurveTU -n "MGUN_locator12_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 1 7 1 24 1 29 1 40 1 42 1 44 - 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 - 1 60 1; - setAttr -s 23 ".kot[0:22]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 - 5; -createNode animCurveTL -n "MGUN_locator12_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 -0.6099781764099258 7 -0.14466311958752329 - 24 -3.165424957837077 29 -8.6809377942761259 40 0.5806925247342658 42 0.73808154862980946 - 44 0.69236702267264627 45 1.5249710714895819 46 1.7171856467804041 47 0.90825317351652068 - 48 2.9201396882369961 49 3.321199573629972 50 2.4028791401006915 51 1.2087244755372111 - 52 0.21235270020383848 53 -0.79763590302947474 54 -3.0040342727921159 55 - -3.185490524251287 56 -3.0246613903808073 57 -3.1773474795713832 58 -1.3151299609425582 - 59 -1.1891977769959863 60 -0.41046663315488341; -createNode animCurveTL -n "MGUN_locator12_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 -0.05328910365139003 7 -2.4508048708664583 - 24 -0.89210831132374724 29 -2.5720064653971413 40 -7.2526135521890165 42 - -4.1146682308778093 44 -2.0167585538095656 45 -3.6287082367579515 46 -4.7723504383011557 - 47 -4.4621084914054308 48 -2.9452256705972313 49 -2.0521201737851533 50 -1.4430594826115224 - 51 -0.7364120339936423 52 0.56776238975219173 53 2.0960014742645736 54 2.5701958288621598 - 55 1.1858446214093348 56 -0.36065956235629421 57 -0.85938323685344864 58 - -1.5963130604308529 59 -1.9509542583121375 60 -0.11674933478873453; -createNode animCurveTL -n "MGUN_locator12_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 -0.74441452563638755 7 -0.49153926030766093 - 24 -0.034577859205132622 29 0.43868727274229036 40 1.9169422721999556 42 - 3.0975382342960649 44 3.3702887685404117 45 3.0849608285410546 46 1.3811249667791738 - 47 0.22990590686251156 48 0.067434739277598008 49 1.9348514858520076 50 1.8944469813227407 - 51 -0.56821777764781745 52 -2.816950763548979 53 -4.5583501409359632 54 -3.0606391803759418 - 55 -2.6204224763708508 56 -2.5239311537959601 57 -3.0885724227556932 58 -2.5915656433791812 - 59 -3.1173435840831081 60 -0.81169803179249556; -createNode animCurveTA -n "MGUN_locator12_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 15.680788712338803 7 31.293240707843932 - 24 42.02726922029084 29 4.3938651238415991 40 57.829784536583993 42 54.120672854657116 - 44 44.173510101410194 45 31.091828719226349 46 48.808280061572283 47 56.358605819649163 - 48 76.172384879485818 49 64.640060178267916 50 65.542405006895393 51 91.898436875000186 - 52 -108.52158900128296 53 -166.02946291815067 54 -250.03504553766095 55 -70.874745380438441 - 56 -66.373555225757329 57 67.094910788401975 58 30.194820037489336 59 7.4364757780718431 - 60 29.884183050556061; -createNode animCurveTA -n "MGUN_locator12_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 -47.51813011278341 7 -44.215403630172567 - 24 -14.944136244022689 29 -62.395585794862292 40 -25.279796194742715 42 -27.236769567937202 - 44 -32.485016400740207 45 -36.17699881194622 46 -29.863061865872307 47 -38.383508063083056 - 48 -51.028717227548277 49 -58.931089993609767 50 -65.199539356917157 51 -83.279496358870119 - 52 -80.855063494238664 53 -73.70994228037317 54 -51.966318351858924 55 -146.73871614573122 - 56 -131.73405056553705 57 -60.578901157442246 58 -31.742863644731823 59 -29.798222400503469 - 60 -48.177043398311852; -createNode animCurveTA -n "MGUN_locator12_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 30.85197096266624 7 43.590855306731108 - 24 -41.223258760254971 29 8.4122360770802356 40 -15.603349718305372 42 -11.515281485272752 - 44 -0.55182581118682394 45 13.043209283521723 46 2.6278375728349705 47 -10.752566218763789 - 48 15.31139625447304 49 10.863476249807693 50 -16.386569118726051 51 -61.126090799759289 - 52 121.23884597528573 53 177.83367887769535 54 286.15845296838609 55 136.26380966714788 - 56 121.77785892651431 57 -36.880595318724566 58 1.5078399402630194 59 21.914190061661138 - 60 9.9809420802661588; -createNode animCurveTU -n "MGUN_locator12_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 2.6292426104807984 7 2.6292426104807984 - 24 2.6292426104807984 29 2.6292426104807984 40 2.6292426104807984 42 2.6292426104807984 - 44 2.6292426104807984 45 2.6292426104807984 46 2.6292426104807984 47 2.6292426104807984 - 48 2.6292426104807984 49 2.6292426104807984 50 2.6292426104807984 51 2.6292426104807984 - 52 2.6292426104807984 53 2.6292426104807984 54 2.6292426104807984 55 2.6292426104807984 - 56 2.6292426104807984 57 2.6292426104807984 58 2.6292426104807984 59 2.6292426104807984 - 60 2.6292426104807984; -createNode animCurveTU -n "MGUN_locator12_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 2.6292426104807989 7 2.6292426104807989 - 24 2.6292426104807989 29 2.6292426104807989 40 2.6292426104807989 42 2.6292426104807989 - 44 2.6292426104807989 45 2.6292426104807989 46 2.6292426104807989 47 2.6292426104807989 - 48 2.6292426104807989 49 2.6292426104807989 50 2.6292426104807989 51 2.6292426104807989 - 52 2.6292426104807989 53 2.6292426104807989 54 2.6292426104807989 55 2.6292426104807989 - 56 2.6292426104807989 57 2.6292426104807989 58 2.6292426104807989 59 2.6292426104807989 - 60 2.6292426104807989; -createNode animCurveTU -n "MGUN_locator12_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 23 ".ktv[0:22]" 1 2.6292426104807993 7 2.6292426104807993 - 24 2.6292426104807993 29 2.6292426104807993 40 2.6292426104807993 42 2.6292426104807993 - 44 2.6292426104807993 45 2.6292426104807993 46 2.6292426104807993 47 2.6292426104807993 - 48 2.6292426104807993 49 2.6292426104807993 50 2.6292426104807993 51 2.6292426104807993 - 52 2.6292426104807993 53 2.6292426104807993 54 2.6292426104807993 55 2.6292426104807993 - 56 2.6292426104807993 57 2.6292426104807993 58 2.6292426104807993 59 2.6292426104807993 - 60 2.6292426104807993; -createNode animCurveTU -n "MGUN_ikHandle4_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 10 1 31 1 41 1 44 1 46 1 47 - 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 57 1 60 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTA -n "MGUN_ikHandle4_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -132.43694405602443 10 -144.8752937872913 - 31 -150.59661268773405 41 -97.070773564099866 44 -91.950597448850644 46 -99.127905065558281 - 47 -81.049961612248865 48 -100.09884432778178 49 -87.125262635782448 50 -101.86627100468378 - 51 -104.00853323530089 52 -108.01342168306411 53 53.076018869331392 54 46.074691001695726 - 57 69.484253394983384 60 55.297363566418248; -createNode animCurveTA -n "MGUN_ikHandle4_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -43.038094235400557 10 -37.789738920678218 - 31 -14.915902449280919 41 16.150894011292088 44 -1.2009804453820758 46 -21.264505184145339 - 47 -10.149488590602159 48 -9.5527142229263529 49 -1.7136364937239053 50 -3.5612873126659754 - 51 0.4386935681651542 52 -12.473792279750704 53 148.95030116917968 54 160.95952708475164 - 57 225.86295007057274 60 236.98044687702682; -createNode animCurveTA -n "MGUN_ikHandle4_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -133.638678091201 10 -64.30771368744719 - 31 -77.472695886096673 41 -102.53935317496175 44 -77.615005763284486 46 -48.176188423167261 - 47 -63.978041244482029 48 -63.316716082769567 49 -93.74518870277285 50 -87.778243010480708 - 51 -98.681699285826781 52 -72.500414396944095 53 64.272322712445742 54 53.154386920174545 - 57 20.305104301358281 60 29.67753254632558; -createNode animCurveTU -n "MGUN_ikHandle4_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1.0000000000000002 10 1.0000000000000002 - 31 1.0000000000000002 41 1.0000000000000002 44 1.0000000000000002 46 1.0000000000000002 - 47 1.0000000000000002 48 1.0000000000000002 49 1.0000000000000002 50 1.0000000000000002 - 51 1.0000000000000002 52 1.0000000000000002 53 1.0000000000000002 54 1.0000000000000002 - 57 1.0000000000000002 60 1.0000000000000002; -createNode animCurveTU -n "MGUN_ikHandle4_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0.99999999999999989 10 0.99999999999999989 - 31 0.99999999999999989 41 0.99999999999999989 44 0.99999999999999989 46 0.99999999999999989 - 47 0.99999999999999989 48 0.99999999999999989 49 0.99999999999999989 50 0.99999999999999989 - 51 0.99999999999999989 52 0.99999999999999989 53 0.99999999999999989 54 0.99999999999999989 - 57 0.99999999999999989 60 0.99999999999999989; -createNode animCurveTU -n "MGUN_ikHandle4_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 10 1 31 1 41 1 44 1 46 1 47 - 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 57 1 60 1; -createNode animCurveTU -n "MGUN_ikHandle4_solverEnable"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 1 10 1 31 1 41 1 44 1 46 1 47 - 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 57 1 60 1; - setAttr -s 16 ".kot[0:15]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5 5; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -0.14640672097487539 10 -0.14640672097487539 - 31 -0.14640672097487539 41 -0.14640672097487539 44 -0.14640672097487539 46 - -0.14640672097487539 47 -0.14640672097487539 48 -0.14640672097487539 49 -0.14640672097487539 - 50 -0.14640672097487539 51 -0.14640672097487539 52 -0.14640672097487539 53 - -0.14640672097487539 54 -0.14640672097487539 57 -0.14640672097487539 60 -0.14640672097487539; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -0.023475842477980131 10 -0.023475842477980131 - 31 -0.023475842477980131 41 -0.023475842477980131 44 -0.023475842477980131 - 46 -0.023475842477980131 47 -0.023475842477980131 48 -0.023475842477980131 - 49 -0.023475842477980131 50 -0.023475842477980131 51 -0.023475842477980131 - 52 -0.023475842477980131 53 -0.023475842477980131 54 -0.023475842477980131 - 57 -0.023475842477980131 60 -0.023475842477980131; -createNode animCurveTU -n "MGUN_ikHandle4_poleVectorZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 -0.064253535881958021 10 -0.064253535881958021 - 31 -0.064253535881958021 41 -0.064253535881958021 44 -0.064253535881958021 - 46 -0.064253535881958021 47 -0.064253535881958021 48 -0.064253535881958021 - 49 -0.064253535881958021 50 -0.064253535881958021 51 -0.064253535881958021 - 52 -0.064253535881958021 53 -0.064253535881958021 54 -0.064253535881958021 - 57 -0.064253535881958021 60 -0.064253535881958021; -createNode animCurveTU -n "MGUN_ikHandle4_offset"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 10 0 31 0 41 0 44 0 46 0 47 - 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 57 0 60 0; -createNode animCurveTA -n "MGUN_ikHandle4_roll"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 10 0 31 0 41 0 44 0 46 0 47 - 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 57 0 60 0; -createNode animCurveTA -n "MGUN_ikHandle4_twist"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 16 ".ktv[0:15]" 1 0 10 0 31 0 41 0 44 0 46 0 47 - 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 57 0 60 0; -createNode animCurveTU -n "MGUN_Lwrist_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 1 41 1 44 1 48 1; - setAttr -s 4 ".kot[0:3]" 5 5 5 5; -createNode animCurveTL -n "MGUN_Lwrist_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 -0.32372186610081854 41 -0.32372186610081854 - 44 -0.32372186610081854 48 -0.32372186610081854; -createNode animCurveTL -n "MGUN_Lwrist_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 -5.2570149160095667 41 -5.2570149160095667 - 44 -5.2570149160095667 48 -5.2570149160095667; -createNode animCurveTL -n "MGUN_Lwrist_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 -0.41267442901289719 41 -0.41267442901289719 - 44 -0.41267442901289719 48 -0.41267442901289719; -createNode animCurveTA -n "MGUN_Lwrist_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 9.8910301442102426 41 23.242688066463046 - 44 20.335828464149312 48 9.8910301442102426; -createNode animCurveTA -n "MGUN_Lwrist_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 -21.21446718259109 41 1.8240848800926632 - 44 -11.643714086436241 48 -21.21446718259109; -createNode animCurveTA -n "MGUN_Lwrist_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 14.021852821326179 41 -54.489190103910779 - 44 -21.679646725854379 48 14.021852821326179; -createNode animCurveTU -n "MGUN_Lwrist_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 1 41 1 44 1 48 1; -createNode animCurveTU -n "MGUN_Lwrist_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 1 41 1 44 1 48 1; -createNode animCurveTU -n "MGUN_Lwrist_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 4 ".ktv[0:3]" 37 1 41 1 44 1 48 1; -createNode animCurveTU -n "MGUN_locator9_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 34 1 50 1 60 1; - setAttr -s 5 ".kot[0:4]" 5 5 5 5 5; -createNode animCurveTL -n "MGUN_locator9_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 4.8412929072316899 9 -3.3893030369127763 - 34 -5.1412332839725652 50 4.4953504051901856 60 3.5540378596370967; -createNode animCurveTL -n "MGUN_locator9_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -14.577044978311854 9 -5.8264345533806612 - 34 -10.300397577148273 50 -12.508440861802727 60 -13.147422257720235; -createNode animCurveTL -n "MGUN_locator9_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -0.48875764181286169 9 -0.96753781800540628 - 34 5.3192414519453548 50 5.5153593701297243 60 2.3047962596451463; -createNode animCurveTA -n "MGUN_locator9_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 -17.277009660855079 9 -17.277009660855079 - 34 -17.277009660855079 50 -17.277009660855079 60 -17.277009660855079; -createNode animCurveTA -n "MGUN_locator9_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 60.958631151455627 9 60.958631151455627 - 34 60.958631151455627 50 60.958631151455627 60 60.958631151455627; -createNode animCurveTA -n "MGUN_locator9_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 13.266713714376493 9 13.266713714376493 - 34 13.266713714376493 50 13.266713714376493 60 13.266713714376493; -createNode animCurveTU -n "MGUN_locator9_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 34 1 50 1 60 1; -createNode animCurveTU -n "MGUN_locator9_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1 9 1 34 1 50 1 60 1; -createNode animCurveTU -n "MGUN_locator9_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 5 ".ktv[0:4]" 1 1.0000000000000002 9 1.0000000000000002 - 34 1.0000000000000002 50 1.0000000000000002 60 1.0000000000000002; -createNode animCurveTU -n "MGUN_Lindex1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6 1 8 1 10 1 11 1 15 1 20 1 - 25 1 46 1 48 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "MGUN_Lindex1_translateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.43332347386308079 6 -0.43332347386308079 - 8 -0.43332347386308079 10 -0.43332347386308079 11 -0.43332347386308079 15 - -0.43332347386308079 20 -0.43332347386308079 25 -0.43332347386308079 46 -0.43332347386308079 - 48 -0.43332347386308079; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTL -n "MGUN_Lindex1_translateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -1.7766053666013157 6 -1.7766053666013157 - 8 -1.7766053666013157 10 -1.7766053666013157 11 -1.7766053666013157 15 -1.7766053666013157 - 20 -1.7766053666013157 25 -1.7766053666013157 46 -1.7766053666013157 48 -1.7766053666013157; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTL -n "MGUN_Lindex1_translateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 2.977522558811267 6 2.977522558811267 - 8 2.977522558811267 10 2.977522558811267 11 2.977522558811267 15 2.977522558811267 - 20 2.977522558811267 25 2.977522558811267 46 2.977522558811267 48 2.977522558811267; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTA -n "MGUN_Lindex1_rotateX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 4.143580267832804 6 -22.295947921394298 - 8 -8.090933518785894 10 -6.3059439915529047 11 21.089296168039354 15 26.991613477355305 - 20 16.852421423309647 25 -36.433793815116921 46 -36.433793815116921 48 11.906808190654191; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTA -n "MGUN_Lindex1_rotateY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 50.071712497075531 6 46.221061437250206 - 8 49.715246739561316 10 48.601179445829501 11 46.677392788674133 15 44.077107525550147 - 20 48.019646661395591 25 37.281486251141153 46 37.281486251141153 48 49.138961812956786; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTA -n "MGUN_Lindex1_rotateZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 28.079959592936834 6 -6.9100058538303069 - 8 12.126844408346495 10 14.176220521556983 11 50.611481363821952 15 58.894943536692274 - 20 44.853475372712317 25 -27.945225892209852 46 -27.945225892209852 48 38.261697369602722; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTU -n "MGUN_Lindex1_scaleX"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6 1 8 1 10 1 11 1 15 1 20 1 - 25 1 46 1 48 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTU -n "MGUN_Lindex1_scaleY"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6 1 8 1 10 1 11 1 15 1 20 1 - 25 1 46 1 48 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTU -n "MGUN_Lindex1_scaleZ"; - setAttr ".tan" 3; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 6 1 8 1 10 1 11 1 15 1 20 1 - 25 1 46 1 48 1; - setAttr -s 10 ".kit[0:9]" 9 9 3 3 3 3 3 - 9 9 9; - setAttr -s 10 ".kot[0:9]" 9 9 3 3 3 3 3 - 9 9 9; -createNode animCurveTU -n "MGUN_Lmiddle1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 9 1 11 1 13 1 17 1 20 1 - 45 1 49 1 52 1 53 1 54 1 55 1 56 1 58 1; - setAttr -s 15 ".kot[0:14]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Lmiddle1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -0.12929786122372844 6 -0.12929786122372844 - 9 -0.12929786122372844 11 -0.12929786122372844 13 -0.12929786122372844 17 - -0.12929786122372844 20 -0.12929786122372844 45 -0.12929786122372844 49 -0.12929786122372844 - 52 -0.12929786122372844 53 -0.12929786122372844 54 -0.12929786122372844 55 - -0.12929786122372844 56 -0.12929786122372844 58 -0.12929786122372844; -createNode animCurveTL -n "MGUN_Lmiddle1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 -0.97449513235673757 6 -0.97449513235673757 - 9 -0.97449513235673757 11 -0.97449513235673757 13 -0.97449513235673757 17 - -0.97449513235673757 20 -0.97449513235673757 45 -0.97449513235673757 49 -0.97449513235673757 - 52 -0.97449513235673757 53 -0.97449513235673757 54 -0.97449513235673757 55 - -0.97449513235673757 56 -0.97449513235673757 58 -0.97449513235673757; -createNode animCurveTL -n "MGUN_Lmiddle1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 3.5290563280752414 6 3.5290563280752414 - 9 3.5290563280752414 11 3.5290563280752414 13 3.5290563280752414 17 3.5290563280752414 - 20 3.5290563280752414 45 3.5290563280752414 49 3.5290563280752414 52 3.5290563280752414 - 53 3.5290563280752414 54 3.5290563280752414 55 3.5290563280752414 56 3.5290563280752414 - 58 3.5290563280752414; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1.7365202177784167 6 -14.038434000466443 - 9 6.900620468985883 11 21.151590155833308 13 -3.0846028247617627 17 11.472508236035946 - 20 12.424945281392139 45 14.8747845661269 49 19.21582354664109 52 10.314873413644586 - 53 -22.828660602257173 54 -25.762857365617126 55 -18.472301366242242 56 -45.497953662338048 - 58 -45.142723500193533; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 59.199473201738385 6 58.158415993410038 - 9 58.96575999482161 11 56.814819350347427 13 59.165618214675362 17 58.516699868365485 - 20 58.392964676467436 45 58.024156942086734 49 57.179180239148316 52 58.652779403918331 - 53 50.166934586999929 54 55.367910053414903 55 53.731377950333851 56 43.097667336954572 - 58 43.479022530431578; -createNode animCurveTA -n "MGUN_Lmiddle1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 35.11968714747389 6 16.697234160839233 - 9 41.137617167617954 11 57.904252550803477 13 29.507100282437868 17 46.484816413790512 - 20 47.602390847600113 45 50.484468043316951 49 55.624657186818581 52 45.128356325353991 - 53 4.509863296367004 54 2.7047269907857712 55 11.25302510384015 56 -23.021581824098142 - 58 -22.503509341083518; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 9 1 11 1 13 1 17 1 20 1 - 45 1 49 1 52 1 53 1 54 1 55 1 56 1 58 1; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 9 1 11 1 13 1 17 1 20 1 - 45 1 49 1 52 1 53 1 54 1 55 1 56 1 58 1; -createNode animCurveTU -n "MGUN_Lmiddle1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 15 ".ktv[0:14]" 1 1 6 1 9 1 11 1 13 1 17 1 20 1 - 45 1 49 1 52 1 53 1 54 1 55 1 56 1 58 1; -createNode animCurveTU -n "MGUN_Lring1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 15 1 19 1 46 1 51 1 - 53 1 57 1 60 1; - setAttr -s 10 ".kot[0:9]" 5 5 5 5 5 5 5 - 5 5 5; -createNode animCurveTL -n "MGUN_Lring1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 0.42291936164487048 5 0.42291936164487048 - 8 0.42291936164487048 15 0.42291936164487048 19 0.42291936164487048 46 0.42291936164487048 - 51 0.42291936164487048 53 0.42291936164487048 57 0.42291936164487048 60 0.42291936164487048; -createNode animCurveTL -n "MGUN_Lring1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -0.38529943542381484 5 -0.38529943542381484 - 8 -0.38529943542381484 15 -0.38529943542381484 19 -0.38529943542381484 46 - -0.38529943542381484 51 -0.38529943542381484 53 -0.38529943542381484 57 -0.38529943542381484 - 60 -0.38529943542381484; -createNode animCurveTL -n "MGUN_Lring1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 3.5737744674322522 5 3.5737744674322522 - 8 3.5737744674322522 15 3.5737744674322522 19 3.5737744674322522 46 3.5737744674322522 - 51 3.5737744674322522 53 3.5737744674322522 57 3.5737744674322522 60 3.5737744674322522; -createNode animCurveTA -n "MGUN_Lring1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 -13.637412252907389 5 -22.149521832095495 - 8 6.241330411945043 15 52.81092937687653 19 14.959763169631922 46 36.741967353464538 - 51 31.18456927634724 53 -32.34277225085355 57 -43.144374125648412 60 -30.237533810218284; -createNode animCurveTA -n "MGUN_Lring1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 60.804887293381178 5 59.216022703672799 - 8 61.519500066301561 15 38.34932108542754 19 60.615827709852489 46 53.732754698873038 - 51 56.351367726866755 53 55.869674087841112 57 49.481972523397857 60 56.723196133706288; -createNode animCurveTA -n "MGUN_Lring1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 25.77249028945748 5 15.951534591771885 - 8 48.396755763461307 15 106.09496330641223 19 58.352329028557307 46 84.100734004165474 - 51 77.324248298321379 53 3.8892123067760247 57 -9.6498479118882585 60 6.4195947020087711; -createNode animCurveTU -n "MGUN_Lring1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 15 1 19 1 46 1 51 1 - 53 1 57 1 60 1; -createNode animCurveTU -n "MGUN_Lring1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 15 1 19 1 46 1 51 1 - 53 1 57 1 60 1; -createNode animCurveTU -n "MGUN_Lring1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 10 ".ktv[0:9]" 1 1 5 1 8 1 15 1 19 1 46 1 51 1 - 53 1 57 1 60 1; -createNode animCurveTU -n "MGUN_Lring2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 8 1 11 1 17 1 21 1 46 1 49 - 1 52 1 54 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_Lring2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0.20979439067157463 8 0.20979439067157463 - 11 0.20979439067157463 17 0.20979439067157463 21 0.20979439067157463 46 0.20979439067157463 - 49 0.20979439067157463 52 0.20979439067157463 54 0.20979439067157463; -createNode animCurveTL -n "MGUN_Lring2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -1.013799034312115 8 -1.013799034312115 - 11 -1.013799034312115 17 -1.013799034312115 21 -1.013799034312115 46 -1.013799034312115 - 49 -1.013799034312115 52 -1.013799034312115 54 -1.013799034312115; -createNode animCurveTL -n "MGUN_Lring2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 0.028535504544426885 8 0.028535504544426885 - 11 0.028535504544426885 17 0.028535504544426885 21 0.028535504544426885 46 - 0.028535504544426885 49 0.028535504544426885 52 0.028535504544426885 54 0.028535504544426885; -createNode animCurveTA -n "MGUN_Lring2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 -59.828954699514192 8 -65.83948747865071 - 11 -36.20509104972124 17 -58.351816083251862 21 -66.245456834821383 46 -66.997814286886069 - 49 -67.108952942833639 52 -67.04899618171892 54 -65.595128355457291; -createNode animCurveTA -n "MGUN_Lring2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 39.347121459496911 8 18.272051618215276 - 11 61.205973183796992 17 42.207242730478171 21 15.238005980549289 46 -5.955639132134281 - 49 2.3347698394103662 52 4.6558541310384589 54 19.839986686782929; -createNode animCurveTA -n "MGUN_Lring2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 20.703834034896836 8 8.4769694584618254 - 11 50.598863785366724 17 22.964629603412739 21 7.0692828013123723 46 -2.0510461125884478 - 49 1.4565056609048999 52 2.4397117191921427 54 9.2253271801091117; -createNode animCurveTU -n "MGUN_Lring2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 8 1 11 1 17 1 21 1 46 1 49 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lring2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 8 1 11 1 17 1 21 1 46 1 49 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lring2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 5 1 8 1 11 1 17 1 21 1 46 1 49 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lthumb1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 8 1 13 1 15 1 17 1 19 1 - 25 1 43 1 46 1 49 1 50 1 52 1; - setAttr -s 13 ".kot[0:12]" 5 5 5 5 5 5 5 - 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Lthumb1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.10914856728805808 4 0.10914856728805808 - 8 0.10914856728805808 13 0.10914856728805808 15 0.10914856728805808 17 0.10914856728805808 - 19 0.10914856728805808 25 0.10914856728805808 43 0.10914856728805808 46 0.10914856728805808 - 49 0.10914856728805808 50 0.10914856728805808 52 0.10914856728805808; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTL -n "MGUN_Lthumb1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 -1.2751602490115874 4 -1.2751602490115874 - 8 -1.2751602490115874 13 -1.2751602490115874 15 -1.2751602490115874 17 -1.2751602490115874 - 19 -1.2751602490115874 25 -1.2751602490115874 43 -1.2751602490115874 46 -1.2751602490115874 - 49 -1.2751602490115874 50 -1.2751602490115874 52 -1.2751602490115874; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTL -n "MGUN_Lthumb1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0.043977474900984311 4 0.043977474900984311 - 8 0.043977474900984311 13 0.043977474900984311 15 0.043977474900984311 17 - 0.043977474900984311 19 0.043977474900984311 25 0.043977474900984311 43 0.043977474900984311 - 46 0.043977474900984311 49 0.043977474900984311 50 0.043977474900984311 52 - 0.043977474900984311; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTA -n "MGUN_Lthumb1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 4 32.399999999999984 8 -13.210686945295569 - 13 -52.447548637072359 15 -7.9791596557850033 17 -15.483392179018713 19 0.7845047762955808 - 25 -4.1062175340206677 43 -42.713989623810896 46 -44.957511071649783 49 -45.66804808190652 - 50 -45.97897399040825 52 -27.156963111441293; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTA -n "MGUN_Lthumb1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 50.304429059414666 4 50.304429059414687 - 8 32.52812067081986 13 49.078139235531395 15 65.71146700888356 17 65.049631177593341 - 19 63.580414996613804 25 63.047903778213083 43 56.596052828690219 46 50.169326940935264 - 49 31.243506204878283 50 26.268662401891298 52 43.242488711366221; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTA -n "MGUN_Lthumb1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 0 4 -2.4898333743169426e-015 - 8 -17.506169212526068 13 -59.352966150481805 15 3.4137980531298675 17 -5.1185514756274486 - 19 37.41688345677111 25 31.556020685890132 43 -23.073811841393653 46 -48.762516707030862 - 49 -64.265472740450377 50 -56.742829449705781 52 -6.4531530398943948; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTU -n "MGUN_Lthumb1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 8 1 13 1 15 1 17 1 19 1 - 25 1 43 1 46 1 49 1 50 1 52 1; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTU -n "MGUN_Lthumb1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 8 1 13 1 15 1 17 1 19 1 - 25 1 43 1 46 1 49 1 50 1 52 1; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTU -n "MGUN_Lthumb1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 13 ".ktv[0:12]" 1 1 4 1 8 1 13 1 15 1 17 1 19 1 - 25 1 43 1 46 1 49 1 50 1 52 1; - setAttr -s 13 ".kit[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; - setAttr -s 13 ".kot[2:12]" 3 3 3 9 3 3 9 - 9 9 9 9; -createNode animCurveTU -n "MGUN_Lindex2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 12 1 17 1 22 1 45 1 48 - 1 52 1 54 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_Lindex2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.026337435720389778 7 0.026337435720389778 - 12 0.026337435720389778 17 0.026337435720389778 22 0.026337435720389778 45 - 0.026337435720389778 48 0.026337435720389778 52 0.026337435720389778 54 0.026337435720389778; -createNode animCurveTL -n "MGUN_Lindex2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -1.2033357122947774 7 -1.2033357122947774 - 12 -1.2033357122947774 17 -1.2033357122947774 22 -1.2033357122947774 45 -1.2033357122947774 - 48 -1.2033357122947774 52 -1.2033357122947774 54 -1.2033357122947774; -createNode animCurveTL -n "MGUN_Lindex2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 0.016939005373982362 7 0.016939005373982362 - 12 0.016939005373982362 17 0.016939005373982362 22 0.016939005373982362 45 - 0.016939005373982362 48 0.016939005373982362 52 0.016939005373982362 54 0.016939005373982362; -createNode animCurveTA -n "MGUN_Lindex2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 -59.865508892148746 7 -64.046440520766097 - 12 -61.398336974132192 17 -64.937855989368728 22 -62.310920757235124 45 -62.310920757235124 - 48 -59.670568178885183 52 -60.571674093472538 54 -58.706575687458425; -createNode animCurveTA -n "MGUN_Lindex2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 35.761332771241115 7 21.432966913826821 - 12 31.681862739767634 17 15.90836555338957 22 28.753551268902982 45 28.753551268902982 - 48 36.221889239282838 52 33.991040193617678 54 38.344778446913132; -createNode animCurveTA -n "MGUN_Lindex2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 19.36955579273333 7 10.71551839169617 - 12 16.610607488786144 17 7.9346843044547386 22 14.798065161275632 45 14.798065161275632 - 48 19.701272310601986 52 18.134759652116021 54 21.292319368904767; -createNode animCurveTU -n "MGUN_Lindex2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 12 1 17 1 22 1 45 1 48 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lindex2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 12 1 17 1 22 1 45 1 48 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lindex2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 1 1 7 1 12 1 17 1 22 1 45 1 48 - 1 52 1 54 1; -createNode animCurveTU -n "MGUN_Lindex3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 1 11 1 14 1 18 1 22 1 40 1 46 - 1 48 1 52 1; - setAttr -s 9 ".kot[0:8]" 5 5 5 5 5 5 5 - 5 5; -createNode animCurveTL -n "MGUN_Lindex3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 -0.047142128204825544 11 -0.047142128204825544 - 14 -0.047142128204825544 18 -0.047142128204825544 22 -0.047142128204825544 - 40 -0.047142128204825544 46 -0.047142128204825544 48 -0.047142128204825544 - 52 -0.047142128204825544; -createNode animCurveTL -n "MGUN_Lindex3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 -0.90750922827001435 11 -0.90750922827001435 - 14 -0.90750922827001435 18 -0.90750922827001435 22 -0.90750922827001435 40 - -0.90750922827001435 46 -0.90750922827001435 48 -0.90750922827001435 52 -0.90750922827001435; -createNode animCurveTL -n "MGUN_Lindex3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 -0.018470362040332939 11 -0.018470362040332939 - 14 -0.018470362040332939 18 -0.018470362040332939 22 -0.018470362040332939 - 40 -0.018470362040332939 46 -0.018470362040332939 48 -0.018470362040332939 - 52 -0.018470362040332939; -createNode animCurveTA -n "MGUN_Lindex3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 1.3817924597588638 11 13.933972878578507 - 14 -4.3288625090244084 18 11.914215770968292 22 3.1992478777103992 40 3.1992478777103992 - 46 16.771760196062356 48 6.8191635877520786 52 7.989304115494738; -createNode animCurveTA -n "MGUN_Lindex3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 -25.182699535523398 11 -21.232087335755207 - 14 -24.867775102107316 18 -22.390294745330568 22 -25.027534714210979 40 -25.027534714210979 - 46 -19.110988989757161 48 -24.336916399467025 52 -23.99803654503522; -createNode animCurveTA -n "MGUN_Lindex3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 -13.629158212027662 11 -44.799382598087611 - 14 -0.18030330225475025 18 -39.367127776053998 22 -17.911139026493579 40 - -17.911139026493579 46 -53.015028536083818 48 -26.566058592292233 52 -29.423700543587678; -createNode animCurveTU -n "MGUN_Lindex3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 1 11 1 14 1 18 1 22 1 40 1 46 - 1 48 1 52 1; -createNode animCurveTU -n "MGUN_Lindex3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 1 11 1 14 1 18 1 22 1 40 1 46 - 1 48 1 52 1; -createNode animCurveTU -n "MGUN_Lindex3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 9 ".ktv[0:8]" 9 1 11 1 14 1 18 1 22 1 40 1 46 - 1 48 1 52 1; -createNode animCurveTU -n "MGUN_Lpinky1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 1 7 1 20 1 40 1 45 1 53 1 55 - 1; - setAttr -s 7 ".kot[0:6]" 5 5 5 5 5 5 5; -createNode animCurveTL -n "MGUN_Lpinky1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 1.1824436775026228 7 1.1824436775026228 - 20 1.1824436775026228 40 1.1824436775026228 45 1.1824436775026228 53 1.1824436775026228 - 55 1.1824436775026228; -createNode animCurveTL -n "MGUN_Lpinky1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 0.22543995748073206 7 0.22543995748073206 - 20 0.22543995748073206 40 0.22543995748073206 45 0.22543995748073206 53 0.22543995748073206 - 55 0.22543995748073206; -createNode animCurveTL -n "MGUN_Lpinky1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 3.2856432959819659 7 3.2856432959819659 - 20 3.2856432959819659 40 3.2856432959819659 45 3.2856432959819659 53 3.2856432959819659 - 55 3.2856432959819659; -createNode animCurveTA -n "MGUN_Lpinky1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 -25.9137418429085 7 53.693966196672129 - 20 64.470812861997217 40 64.470812861997217 45 -21.694220675813845 53 -61.349838296975918 - 55 -11.763300094504826; -createNode animCurveTA -n "MGUN_Lpinky1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 62.090943841450247 7 44.680251221849041 - 20 12.344624000990047 40 12.344624000990047 45 63.057273296182302 53 28.587891411652329 - 55 64.53002235659342; -createNode animCurveTA -n "MGUN_Lpinky1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 23.144011103647046 7 114.62465746250081 - 20 136.11674499523266 40 136.11674499523266 45 27.89707913264246 53 -23.402024872572582 - 55 38.958151668359442; -createNode animCurveTU -n "MGUN_Lpinky1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 1 7 1 20 1 40 1 45 1 53 1 55 - 1; -createNode animCurveTU -n "MGUN_Lpinky1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 1 7 1 20 1 40 1 45 1 53 1 55 - 1; -createNode animCurveTU -n "MGUN_Lpinky1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 7 ".ktv[0:6]" 4 1 7 1 20 1 40 1 45 1 53 1 55 - 1; -createNode animCurveTU -n "MGUN_locator10_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_locator10_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.3622342504804135; -createNode animCurveTL -n "MGUN_locator10_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.56944496179341286; -createNode animCurveTL -n "MGUN_locator10_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0912052221015249; -createNode animCurveTA -n "MGUN_locator10_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 118.09249262938081; -createNode animCurveTA -n "MGUN_locator10_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -44.86078128627743; -createNode animCurveTA -n "MGUN_locator10_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 132.49240857398249; -createNode animCurveTU -n "MGUN_locator10_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.2697268321591695; -createNode animCurveTU -n "MGUN_locator10_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.2697268321591713; -createNode animCurveTU -n "MGUN_locator10_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 5.2697268321591704; -createNode animCurveTU -n "MGUN_Rthumb1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.73002257428498396; -createNode animCurveTL -n "MGUN_Rthumb1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.99479550068687961; -createNode animCurveTL -n "MGUN_Rthumb1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.61877722880805675; -createNode animCurveTA -n "MGUN_Rthumb1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -6.2892421243705741; -createNode animCurveTA -n "MGUN_Rthumb1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 39.374160340086505; -createNode animCurveTA -n "MGUN_Rthumb1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 11.188921640234602; -createNode animCurveTU -n "MGUN_Rthumb1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.0011903651940485815; -createNode animCurveTL -n "MGUN_Rthumb3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1901831974686985; -createNode animCurveTL -n "MGUN_Rthumb3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.13289617599428638; -createNode animCurveTA -n "MGUN_Rthumb3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -4.1555141795791375; -createNode animCurveTA -n "MGUN_Rthumb3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -8.1724967783416851; -createNode animCurveTA -n "MGUN_Rthumb3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -5.8700508696813012; -createNode animCurveTU -n "MGUN_Rthumb3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.22566437600543834; -createNode animCurveTL -n "MGUN_Rindex1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.90623968522803611; -createNode animCurveTL -n "MGUN_Rindex1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.3915952354027477; -createNode animCurveTA -n "MGUN_Rindex1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -43.662436345161844; -createNode animCurveTA -n "MGUN_Rindex1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 33.40502825343426; -createNode animCurveTA -n "MGUN_Rindex1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -34.025322869532438; -createNode animCurveTU -n "MGUN_Rindex1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.026299781897019869; -createNode animCurveTL -n "MGUN_Rindex2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2033401492406242; -createNode animCurveTL -n "MGUN_Rindex2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.016879845903456925; -createNode animCurveTA -n "MGUN_Rindex2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -62.901115459539874; -createNode animCurveTA -n "MGUN_Rindex2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 49.666824753193545; -createNode animCurveTA -n "MGUN_Rindex2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 11.353218222348337; -createNode animCurveTU -n "MGUN_Rindex2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.48961408126658096; -createNode animCurveTL -n "MGUN_Rmiddle1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.14527035191089369; -createNode animCurveTL -n "MGUN_Rmiddle1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.6416829612192703; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 96.871771103443351; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 47.709931189611979; -createNode animCurveTA -n "MGUN_Rmiddle1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 139.99565910917332; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.34996659009394904; -createNode animCurveTL -n "MGUN_Rmiddle2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.1638862061582265; -createNode animCurveTL -n "MGUN_Rmiddle2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.0058990959178562008; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -64.027300339479325; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 40.645192805017352; -createNode animCurveTA -n "MGUN_Rmiddle2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 19.274513826590528; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rmiddle3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.14255500229258544; -createNode animCurveTL -n "MGUN_Rmiddle3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0736792354681057; -createNode animCurveTL -n "MGUN_Rmiddle3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.068508544328491183; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 24.218431917458261; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -16.036528925541123; -createNode animCurveTA -n "MGUN_Rmiddle3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -66.567575078325333; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rmiddle3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rring1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.18401136578347632; -createNode animCurveTL -n "MGUN_Rring1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.88864370373640078; -createNode animCurveTL -n "MGUN_Rring1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.5036817365697139; -createNode animCurveTA -n "MGUN_Rring1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 79.676548600210253; -createNode animCurveTA -n "MGUN_Rring1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 41.191388199916062; -createNode animCurveTA -n "MGUN_Rring1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 103.00787951800865; -createNode animCurveTU -n "MGUN_Rring1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky1_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky1_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.2712478845905828; -createNode animCurveTL -n "MGUN_Rpinky1_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.6800905578050163; -createNode animCurveTL -n "MGUN_Rpinky1_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.0574260158963051; -createNode animCurveTA -n "MGUN_Rpinky1_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -11.120782321634302; -createNode animCurveTA -n "MGUN_Rpinky1_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 71.62898640743677; -createNode animCurveTA -n "MGUN_Rpinky1_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -7.1137263137415472; -createNode animCurveTU -n "MGUN_Rpinky1_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky1_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky1_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.11218028540197622; -createNode animCurveTL -n "MGUN_Rpinky2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.99160382885266696; -createNode animCurveTL -n "MGUN_Rpinky2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.025654221325943638; -createNode animCurveTA -n "MGUN_Rpinky2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -40.218336032115488; -createNode animCurveTA -n "MGUN_Rpinky2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 59.202228613205293; -createNode animCurveTA -n "MGUN_Rpinky2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 41.796555669940332; -createNode animCurveTU -n "MGUN_Rpinky2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rindex3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.047171580751363962; -createNode animCurveTL -n "MGUN_Rindex3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.90754361657893412; -createNode animCurveTL -n "MGUN_Rindex3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.018369430481849136; -createNode animCurveTA -n "MGUN_Rindex3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 8.762551225346904; -createNode animCurveTA -n "MGUN_Rindex3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -19.331810868690113; -createNode animCurveTA -n "MGUN_Rindex3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -20.812992026202238; -createNode animCurveTU -n "MGUN_Rindex3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rindex3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rring2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.20975021925272941; -createNode animCurveTL -n "MGUN_Rring2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.0137524110593601; -createNode animCurveTL -n "MGUN_Rring2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.028503429526118396; -createNode animCurveTA -n "MGUN_Rring2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -59.828954699514192; -createNode animCurveTA -n "MGUN_Rring2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 39.347121459496911; -createNode animCurveTA -n "MGUN_Rring2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 20.703834034896836; -createNode animCurveTU -n "MGUN_Rring2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rring2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rrring3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rrring3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.053741705965343556; -createNode animCurveTL -n "MGUN_Rrring3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.90223981334459324; -createNode animCurveTL -n "MGUN_Rrring3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.034048580819781904; -createNode animCurveTA -n "MGUN_Rrring3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 7.6124106742796798; -createNode animCurveTA -n "MGUN_Rrring3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -27.852477952066206; -createNode animCurveTA -n "MGUN_Rrring3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -20.46786065056288; -createNode animCurveTU -n "MGUN_Rrring3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rrring3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rrring3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky3_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rpinky3_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.14683411705801674; -createNode animCurveTL -n "MGUN_Rpinky3_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.68245151272406979; -createNode animCurveTL -n "MGUN_Rpinky3_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.053025670655280521; -createNode animCurveTA -n "MGUN_Rpinky3_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 6.523371164593958; -createNode animCurveTA -n "MGUN_Rpinky3_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -28.474071475738981; -createNode animCurveTA -n "MGUN_Rpinky3_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -1.8164680091303635; -createNode animCurveTU -n "MGUN_Rpinky3_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky3_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rpinky3_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb2_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTL -n "MGUN_Rthumb2_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0.21273393895870849; -createNode animCurveTL -n "MGUN_Rthumb2_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.2162025924277884; -createNode animCurveTL -n "MGUN_Rthumb2_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -0.089693919575826161; -createNode animCurveTA -n "MGUN_Rthumb2_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 21.853509170555224; -createNode animCurveTA -n "MGUN_Rthumb2_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1.8150032070874769; -createNode animCurveTA -n "MGUN_Rthumb2_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 -13.106809766073738; -createNode animCurveTU -n "MGUN_Rthumb2_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb2_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_Rthumb2_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTL -n "MGUN_ToTop_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 -6.7134381190228343 9 -4.2013464829743512 - 10 -6.1539441034936626 11 -6.7134381190228343 15 -6.7134381190228343 17 -7.6758687812270585 - 18 -8.611929728998156 19 -10.483202563144483; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTL -n "MGUN_ToTop_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 0.23108615156333684 9 1.5885969224314254 - 10 2.0578273270492531 11 0.23108615156333684 15 0.23108615156333684 17 0.5042262483107216 - 18 -0.14032462412821534 19 -0.69138519692191225; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTL -n "MGUN_ToTop_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 -3.9620629493658104 9 -5.6990684770324558 - 10 -4.9490019678495019 11 -3.9620629493658104 15 -3.9620629493658104 17 -4.3096458130168402 - 18 -5.4730121558404967 19 -6.0959163900295543; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTU -n "MGUN_ToTop_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 1 9 1 10 1 11 1 15 1 17 1 18 - 1 19 1; - setAttr -s 8 ".kot[0:7]" 5 5 5 5 5 5 5 - 5; -createNode animCurveTA -n "MGUN_ToTop_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 182.73495869708836 9 199.39193463417487 - 10 185.34396265939424 11 182.73495869708836 15 182.73495869708836 17 174.30769740280417 - 18 157.64257962903929 19 137.41989802260656; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTA -n "MGUN_ToTop_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 -33.286512630671034 9 -33.286512630671034 - 10 -22.476636816591185 11 -33.286512630671034 15 -33.286512630671034 17 -30.327450658659476 - 18 -48.231045415418897 19 -71.672672664175025; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTA -n "MGUN_ToTop_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 -97.926324564900781 9 -97.926324564900781 - 10 -95.999088499842813 11 -97.926324564900781 15 -97.926324564900781 17 -99.766797737804723 - 18 -96.144179522117142 19 -91.223603428321894; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTU -n "MGUN_ToTop_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 1.0000000000000004 9 1.0000000000000004 - 10 1.0000000000000004 11 1.0000000000000004 15 1.0000000000000004 17 1.0000000000000004 - 18 1.0000000000000004 19 1.0000000000000004; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTU -n "MGUN_ToTop_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 0.99999999999999989 9 0.99999999999999989 - 10 0.99999999999999989 11 0.99999999999999989 15 0.99999999999999989 17 0.99999999999999989 - 18 0.99999999999999989 19 0.99999999999999989; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTU -n "MGUN_ToTop_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr -s 8 ".ktv[0:7]" 8 1.0000000000000002 9 1.0000000000000002 - 10 1.0000000000000002 11 1.0000000000000002 15 1.0000000000000002 17 1.0000000000000002 - 18 1.0000000000000002 19 1.0000000000000002; - setAttr -s 8 ".kit[3:7]" 3 3 9 9 9; - setAttr -s 8 ".kot[3:7]" 3 3 9 9 9; -createNode animCurveTL -n "MGUN_barrel_translateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 12.907611084068815; -createNode animCurveTL -n "MGUN_barrel_translateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 3.574315939383617; -createNode animCurveTL -n "MGUN_barrel_translateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 4.7969255142583327; -createNode animCurveTU -n "MGUN_barrel_visibility"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; - setAttr ".kot[0]" 5; -createNode animCurveTA -n "MGUN_barrel_rotateX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "MGUN_barrel_rotateY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTA -n "MGUN_barrel_rotateZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 0; -createNode animCurveTU -n "MGUN_barrel_scaleX"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_barrel_scaleY"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -createNode animCurveTU -n "MGUN_barrel_scaleZ"; - setAttr ".tan" 9; - setAttr ".wgt" no; - setAttr ".ktv[0]" 1 1; -select -ne :time1; - setAttr ".o" 42; -select -ne :renderPartition; - setAttr -s 48 ".st"; -select -ne :renderGlobalsList1; -select -ne :defaultShaderList1; - setAttr -s 48 ".s"; -select -ne :postProcessList1; - setAttr -s 2 ".p"; -select -ne :defaultRenderUtilityList1; - setAttr -s 22 ".u"; -select -ne :lightList1; - setAttr -s 2 ".ln"; -select -ne :defaultTextureList1; - setAttr -s 22 ".tx"; -select -ne :initialShadingGroup; - setAttr -k on ".nds"; - setAttr ".ro" yes; -select -ne :initialParticleSE; - setAttr ".ro" yes; -select -ne :ikSystem; - setAttr -s 2 ".sol"; -select -ne MGUN_Cli; - setAttr ".ra" -type "double3" 0 0 16.070108112509264 ; - setAttr ".jo" -type "double3" 0 0 -16.070108112509295 ; -select -ne MGUN_guilight; - setAttr ".t" -type "double3" 4.203086144490312 5.1905144045116725 0.025163362666150487 ; - setAttr ".r" -type "double3" -0.44864236109062661 -29.709107002120923 5.9683516885096406 ; -select -ne MGUN_Gun1_pointConstraint1; - setAttr ".r" -type "double3" 0 0 0 ; - setAttr -k off ".rx"; - setAttr -k off ".ry"; - setAttr -k off ".rz"; -select -ne MGUN_ikHandle2; - setAttr ".twi" -295.64622228750477; -select -ne MGUN_Lloarm1; - setAttr ".v" yes; -select -ne MGUN_effector1; - setAttr ".v" yes; -select -ne MGUN_Rloarm1; - setAttr ".t" -type "double3" 5.5895682500307444 -21.710493028270307 6.647843850981447 ; - setAttr ".r" -type "double3" 23.858970583210471 -12.978384796886047 1.3183589787639254 ; - setAttr ".jo" -type "double3" -162.71850162818336 0 90 ; -select -ne MGUN_Rhand1; - setAttr ".v" yes; -select -ne MGUN_Rthumb11; - setAttr ".t" -type "double3" -0.90763635715879143 0.65376681357783784 -0.96806829679292483 ; - setAttr ".r" -type "double3" -45.353676106284468 -29.678091936457527 8.2082920477846049 ; - setAttr ".ra" -type "double3" -8.8021710090297951 9.5794721429543923 -24.033102922457708 ; - setAttr ".jo" -type "double3" -29.354027924151232 3.2925937281261737 25.569296434707272 ; -select -ne MGUN_Lwrist; - setAttr ".ra" -type "double3" 17.29933035209088 -0.85701431765945668 48.708574703586685 ; - setAttr ".jo" -type "double3" 49.854470040682372 -29.764242167548215 -154.32270774917538 ; -select -ne MGUN_Lthumb1; - setAttr ".jo" -type "double3" -16.009013308736321 -21.551321014099699 7.0509990708146049 ; -select -ne MGUN_Lthumb2; - setAttr ".t" -type "double3" -0.10716000272675574 -1.5044332321137617 0.095627985328331333 ; - setAttr ".r" -type "double3" 21.867232388874974 -1.6320304877926561 -4.5322012242412724 ; - setAttr ".jo" -type "double3" 13.772439478172686 179.99999856373717 0 ; -select -ne MGUN_Lindex1; - setAttr ".jo" -type "double3" -56.165624924208203 -21.551321014099699 7.0509990708146164 ; -select -ne MGUN_Lindex2; - setAttr ".jo" -type "double3" 65.917967098563139 0 0 ; -select -ne MGUN_Lindex3; - setAttr ".jo" -type "double3" 179.99999999999994 -30.963756532073706 90.000000000000156 ; -select -ne MGUN_Lmiddle1; - setAttr ".jo" -type "double3" -56.165624924208203 -21.551321014099699 7.0509990708146164 ; -select -ne MGUN_Lring1; - setAttr ".jo" -type "double3" -56.165624924208203 -21.551321014099699 7.0509990708146164 ; -select -ne MGUN_Lring2; - setAttr ".jo" -type "double3" 65.917967098563139 0 0 ; -select -ne MGUN_Lpinky1; - setAttr ".jo" -type "double3" -56.165624924208203 -21.551321014099699 7.0509990708146164 ; -select -ne MGUN_effector3; - setAttr ".v" yes; -select -ne MGUN_Rwrist; - setAttr ".t" -type "double3" 0.32369628312252807 5.2570229018497336 0.41266994780323429 ; - setAttr ".r" -type "double3" 9.8910301442102426 -21.21446718259109 14.021852821326179 ; - setAttr ".jo" -type "double3" 49.854470040682401 -29.764242167548222 -154.32270774917538 ; -select -ne MGUN_Rhand; - setAttr ".jo" -type "double3" 5.1224988002658076 -2.9298764982412617 131.59753300962348 ; -select -ne MGUN_Rthumb1; - setAttr ".jo" -type "double3" 142.31332490621023 20.278138957014853 -43.208611970576932 ; -select -ne MGUN_Rthumb2; - setAttr ".jo" -type "double3" -166.22756052182729 0 179.99999965807427 ; -select -ne MGUN_Rthumb3; - setAttr ".jo" -type "double3" 0 70.497551526525655 89.999999114888197 ; -select -ne MGUN_Rindex1; - setAttr ".jo" -type "double3" 102.15671329073835 20.278138957014832 -43.208611970576932 ; -select -ne MGUN_Rindex2; - setAttr ".jo" -type "double3" 65.917967098563139 0 0 ; -select -ne MGUN_Rindex3; - setAttr ".jo" -type "double3" 179.99999999999991 -30.963756532073706 90.000000000000099 ; -select -ne MGUN_Rmiddle1; - setAttr ".jo" -type "double3" 102.15671329073835 20.278138957014825 -43.208611970576932 ; -select -ne MGUN_Rmiddle2; - setAttr ".jo" -type "double3" 65.91796709856321 0 0 ; -select -ne MGUN_Rmiddle3; - setAttr ".jo" -type "double3" -179.99999991744673 -30.96375663953037 89.999999973141669 ; -select -ne MGUN_Rring1; - setAttr ".jo" -type "double3" 102.15671329073835 20.278138957014828 -43.208611970576932 ; -select -ne MGUN_Rpinky1; - setAttr ".jo" -type "double3" 102.15671329073835 20.278138957014825 -43.208611970576932 ; -select -ne MGUN_Rpinky2; - setAttr ".jo" -type "double3" 65.917967098563182 0 0 ; -select -ne MGUN_effector2; - setAttr ".v" yes; -select -ne MGUN_ikHandle4; -select -ne MGUN_barrel; - setAttr ".jo" -type "double3" -0.44864236109062566 -29.709107002120909 - 5.9683516885096344 ; -connectAttr "MGUN_Gun2_rotateX.o" "MGUN_Gun2.rx"; -connectAttr "MGUN_Gun2_rotateY.o" "MGUN_Gun2.ry"; -connectAttr "MGUN_Gun2_rotateZ.o" "MGUN_Gun2.rz"; -connectAttr "MGUN_Gun2_translateX.o" "MGUN_Gun2.tx"; -connectAttr "MGUN_Gun2_translateY.o" "MGUN_Gun2.ty"; -connectAttr "MGUN_Gun2_translateZ.o" "MGUN_Gun2.tz"; -connectAttr "MGUN_Gun2_visibility.o" "MGUN_Gun2.v"; -connectAttr "MGUN_Gun2_scaleX.o" "MGUN_Gun2.sx"; -connectAttr "MGUN_Gun2_scaleY.o" "MGUN_Gun2.sy"; -connectAttr "MGUN_Gun2_scaleZ.o" "MGUN_Gun2.sz"; -connectAttr "MGUN_Ext_scaleX.o" "MGUN_Ext.sx"; -connectAttr "MGUN_Ext_scaleY.o" "MGUN_Ext.sy"; -connectAttr "MGUN_Ext_scaleZ.o" "MGUN_Ext.sz"; -connectAttr "MGUN_Ext_translateX.o" "MGUN_Ext.tx"; -connectAttr "MGUN_Ext_translateY.o" "MGUN_Ext.ty"; -connectAttr "MGUN_Ext_translateZ.o" "MGUN_Ext.tz"; -connectAttr "MGUN_Ext_rotateX.o" "MGUN_Ext.rx"; -connectAttr "MGUN_Ext_rotateY.o" "MGUN_Ext.ry"; -connectAttr "MGUN_Ext_rotateZ.o" "MGUN_Ext.rz"; -connectAttr "MGUN_Ext_visibility.o" "MGUN_Ext.v"; -connectAttr "MGUN_Cli_translateX.o" "MGUN_Cli.tx"; -connectAttr "MGUN_Cli_translateY.o" "MGUN_Cli.ty"; -connectAttr "MGUN_Cli_translateZ.o" "MGUN_Cli.tz"; -connectAttr "MGUN_Cli_visibility.o" "MGUN_Cli.v"; -connectAttr "MGUN_Cli_rotateX.o" "MGUN_Cli.rx"; -connectAttr "MGUN_Cli_rotateY.o" "MGUN_Cli.ry"; -connectAttr "MGUN_Cli_rotateZ.o" "MGUN_Cli.rz"; -connectAttr "MGUN_Cli_scaleX.o" "MGUN_Cli.sx"; -connectAttr "MGUN_Cli_scaleY.o" "MGUN_Cli.sy"; -connectAttr "MGUN_Cli_scaleZ.o" "MGUN_Cli.sz"; -connectAttr "MGUN_ToTop_rotateX.o" "MGUN_ToTop.rx"; -connectAttr "MGUN_ToTop_rotateY.o" "MGUN_ToTop.ry"; -connectAttr "MGUN_ToTop_rotateZ.o" "MGUN_ToTop.rz"; -connectAttr "MGUN_ToTop_translateX.o" "MGUN_ToTop.tx"; -connectAttr "MGUN_ToTop_translateY.o" "MGUN_ToTop.ty"; -connectAttr "MGUN_ToTop_translateZ.o" "MGUN_ToTop.tz"; -connectAttr "MGUN_ToTop_scaleX.o" "MGUN_ToTop.sx"; -connectAttr "MGUN_ToTop_scaleY.o" "MGUN_ToTop.sy"; -connectAttr "MGUN_ToTop_scaleZ.o" "MGUN_ToTop.sz"; -connectAttr "MGUN_ToTop_visibility.o" "MGUN_ToTop.v"; -connectAttr "MGUN_Connector_translateX.o" "MGUN_Connector.tx"; -connectAttr "MGUN_Connector_translateY.o" "MGUN_Connector.ty"; -connectAttr "MGUN_Connector_translateZ.o" "MGUN_Connector.tz"; -connectAttr "MGUN_Connector_rotateX.o" "MGUN_Connector.rx"; -connectAttr "MGUN_Connector_rotateY.o" "MGUN_Connector.ry"; -connectAttr "MGUN_Connector_rotateZ.o" "MGUN_Connector.rz"; -connectAttr "MGUN_Connector_visibility.o" "MGUN_Connector.v"; -connectAttr "MGUN_Connector_scaleX.o" "MGUN_Connector.sx"; -connectAttr "MGUN_Connector_scaleY.o" "MGUN_Connector.sy"; -connectAttr "MGUN_Connector_scaleZ.o" "MGUN_Connector.sz"; -connectAttr "MGUN_locator7_rotateY.o" "MGUN_locator7.ry"; -connectAttr "MGUN_locator7_rotateX.o" "MGUN_locator7.rx"; -connectAttr "MGUN_locator7_rotateZ.o" "MGUN_locator7.rz"; -connectAttr "MGUN_locator7_translateX.o" "MGUN_locator7.tx"; -connectAttr "MGUN_locator7_translateZ.o" "MGUN_locator7.tz"; -connectAttr "MGUN_locator7_translateY.o" "MGUN_locator7.ty"; -connectAttr "MGUN_locator7_visibility.o" "MGUN_locator7.v"; -connectAttr "MGUN_locator7_scaleX.o" "MGUN_locator7.sx"; -connectAttr "MGUN_locator7_scaleY.o" "MGUN_locator7.sy"; -connectAttr "MGUN_locator7_scaleZ.o" "MGUN_locator7.sz"; -connectAttr "MGUN_locator12_rotateX.o" "MGUN_locator12.rx"; -connectAttr "MGUN_locator12_rotateY.o" "MGUN_locator12.ry"; -connectAttr "MGUN_locator12_rotateZ.o" "MGUN_locator12.rz"; -connectAttr "MGUN_locator12_translateX.o" "MGUN_locator12.tx"; -connectAttr "MGUN_locator12_translateY.o" "MGUN_locator12.ty"; -connectAttr "MGUN_locator12_translateZ.o" "MGUN_locator12.tz"; -connectAttr "MGUN_locator12_scaleX.o" "MGUN_locator12.sx"; -connectAttr "MGUN_locator12_scaleY.o" "MGUN_locator12.sy"; -connectAttr "MGUN_locator12_scaleZ.o" "MGUN_locator12.sz"; -connectAttr "MGUN_locator12_visibility.o" "MGUN_locator12.v"; -connectAttr "MGUN_locator11_translateX.o" "MGUN_locator11.tx"; -connectAttr "MGUN_locator11_translateY.o" "MGUN_locator11.ty"; -connectAttr "MGUN_locator11_translateZ.o" "MGUN_locator11.tz"; -connectAttr "MGUN_locator11_scaleX.o" "MGUN_locator11.sx"; -connectAttr "MGUN_locator11_scaleY.o" "MGUN_locator11.sy"; -connectAttr "MGUN_locator11_scaleZ.o" "MGUN_locator11.sz"; -connectAttr "MGUN_locator11_rotateX.o" "MGUN_locator11.rx"; -connectAttr "MGUN_locator11_rotateY.o" "MGUN_locator11.ry"; -connectAttr "MGUN_locator11_rotateZ.o" "MGUN_locator11.rz"; -connectAttr "MGUN_locator11_visibility.o" "MGUN_locator11.v"; -connectAttr "MGUN_locator10_rotateX.o" "MGUN_locator10.rx"; -connectAttr "MGUN_locator10_rotateY.o" "MGUN_locator10.ry"; -connectAttr "MGUN_locator10_rotateZ.o" "MGUN_locator10.rz"; -connectAttr "MGUN_locator10_translateX.o" "MGUN_locator10.tx"; -connectAttr "MGUN_locator10_translateY.o" "MGUN_locator10.ty"; -connectAttr "MGUN_locator10_translateZ.o" "MGUN_locator10.tz"; -connectAttr "MGUN_locator10_scaleX.o" "MGUN_locator10.sx"; -connectAttr "MGUN_locator10_scaleY.o" "MGUN_locator10.sy"; -connectAttr "MGUN_locator10_scaleZ.o" "MGUN_locator10.sz"; -connectAttr "MGUN_locator10_visibility.o" "MGUN_locator10.v"; -connectAttr "MGUN_locator9_translateX.o" "MGUN_locator9.tx"; -connectAttr "MGUN_locator9_translateY.o" "MGUN_locator9.ty"; -connectAttr "MGUN_locator9_translateZ.o" "MGUN_locator9.tz"; -connectAttr "MGUN_locator9_visibility.o" "MGUN_locator9.v"; -connectAttr "MGUN_locator9_rotateX.o" "MGUN_locator9.rx"; -connectAttr "MGUN_locator9_rotateY.o" "MGUN_locator9.ry"; -connectAttr "MGUN_locator9_rotateZ.o" "MGUN_locator9.rz"; -connectAttr "MGUN_locator9_scaleX.o" "MGUN_locator9.sx"; -connectAttr "MGUN_locator9_scaleY.o" "MGUN_locator9.sy"; -connectAttr "MGUN_locator9_scaleZ.o" "MGUN_locator9.sz"; -connectAttr "MGUN_Hand_Const_rotateX.o" "MGUN_Hand_Const.rx"; -connectAttr "MGUN_Hand_Const_rotateY.o" "MGUN_Hand_Const.ry"; -connectAttr "MGUN_Hand_Const_rotateZ.o" "MGUN_Hand_Const.rz"; -connectAttr "MGUN_Hand_Const_visibility.o" "MGUN_Hand_Const.v"; -connectAttr "MGUN_Hand_Const_scaleX.o" "MGUN_Hand_Const.sx"; -connectAttr "MGUN_Hand_Const_scaleY.o" "MGUN_Hand_Const.sy"; -connectAttr "MGUN_Hand_Const_scaleZ.o" "MGUN_Hand_Const.sz"; -connectAttr "MGUN_LHAND_GOAL_OFF_CONNECT.o" "MGUN_LHAND_GOAL_OFF.CONNECT" - ; -connectAttr "MGUN_LHAND_GOAL_OFF_translateX.o" "MGUN_LHAND_GOAL_OFF.tx"; -connectAttr "MGUN_LHAND_GOAL_OFF_translateY.o" "MGUN_LHAND_GOAL_OFF.ty"; -connectAttr "MGUN_LHAND_GOAL_OFF_translateZ.o" "MGUN_LHAND_GOAL_OFF.tz"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateX.o" "MGUN_LHAND_GOAL_OFF.rx"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateY.o" "MGUN_LHAND_GOAL_OFF.ry"; -connectAttr "MGUN_LHAND_GOAL_OFF_rotateZ.o" "MGUN_LHAND_GOAL_OFF.rz"; -connectAttr "MGUN_LHAND_GOAL_OFF_visibility.o" "MGUN_LHAND_GOAL_OFF.v"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleX.o" "MGUN_LHAND_GOAL_OFF.sx"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleY.o" "MGUN_LHAND_GOAL_OFF.sy"; -connectAttr "MGUN_LHAND_GOAL_OFF_scaleZ.o" "MGUN_LHAND_GOAL_OFF.sz"; -connectAttr "MGUN_Lwrist_translateX.o" "MGUN_Lwrist.tx"; -connectAttr "MGUN_Lwrist_translateY.o" "MGUN_Lwrist.ty"; -connectAttr "MGUN_Lwrist_translateZ.o" "MGUN_Lwrist.tz"; -connectAttr "MGUN_Lwrist_rotateX.o" "MGUN_Lwrist.rx"; -connectAttr "MGUN_Lwrist_rotateY.o" "MGUN_Lwrist.ry"; -connectAttr "MGUN_Lwrist_rotateZ.o" "MGUN_Lwrist.rz"; -connectAttr "MGUN_Lwrist_scaleX.o" "MGUN_Lwrist.sx"; -connectAttr "MGUN_Lwrist_scaleY.o" "MGUN_Lwrist.sy"; -connectAttr "MGUN_Lwrist_scaleZ.o" "MGUN_Lwrist.sz"; -connectAttr "MGUN_Lwrist_visibility.o" "MGUN_Lwrist.v"; -connectAttr "MGUN_Lthumb1_scaleX.o" "MGUN_Lthumb1.sx"; -connectAttr "MGUN_Lthumb1_scaleY.o" "MGUN_Lthumb1.sy"; -connectAttr "MGUN_Lthumb1_scaleZ.o" "MGUN_Lthumb1.sz"; -connectAttr "MGUN_Lthumb1_rotateX.o" "MGUN_Lthumb1.rx"; -connectAttr "MGUN_Lthumb1_rotateZ.o" "MGUN_Lthumb1.rz"; -connectAttr "MGUN_Lthumb1_rotateY.o" "MGUN_Lthumb1.ry"; -connectAttr "MGUN_Lthumb1_translateX.o" "MGUN_Lthumb1.tx"; -connectAttr "MGUN_Lthumb1_translateY.o" "MGUN_Lthumb1.ty"; -connectAttr "MGUN_Lthumb1_translateZ.o" "MGUN_Lthumb1.tz"; -connectAttr "MGUN_Lthumb1_visibility.o" "MGUN_Lthumb1.v"; -connectAttr "MGUN_Lindex1_scaleX.o" "MGUN_Lindex1.sx"; -connectAttr "MGUN_Lindex1_scaleY.o" "MGUN_Lindex1.sy"; -connectAttr "MGUN_Lindex1_scaleZ.o" "MGUN_Lindex1.sz"; -connectAttr "MGUN_Lindex1_rotateX.o" "MGUN_Lindex1.rx"; -connectAttr "MGUN_Lindex1_rotateY.o" "MGUN_Lindex1.ry"; -connectAttr "MGUN_Lindex1_rotateZ.o" "MGUN_Lindex1.rz"; -connectAttr "MGUN_Lindex1_translateX.o" "MGUN_Lindex1.tx"; -connectAttr "MGUN_Lindex1_translateY.o" "MGUN_Lindex1.ty"; -connectAttr "MGUN_Lindex1_translateZ.o" "MGUN_Lindex1.tz"; -connectAttr "MGUN_Lindex1_visibility.o" "MGUN_Lindex1.v"; -connectAttr "MGUN_Lindex2_scaleX.o" "MGUN_Lindex2.sx"; -connectAttr "MGUN_Lindex2_scaleY.o" "MGUN_Lindex2.sy"; -connectAttr "MGUN_Lindex2_scaleZ.o" "MGUN_Lindex2.sz"; -connectAttr "MGUN_Lindex2_rotateX.o" "MGUN_Lindex2.rx"; -connectAttr "MGUN_Lindex2_rotateY.o" "MGUN_Lindex2.ry"; -connectAttr "MGUN_Lindex2_rotateZ.o" "MGUN_Lindex2.rz"; -connectAttr "MGUN_Lindex2_translateX.o" "MGUN_Lindex2.tx"; -connectAttr "MGUN_Lindex2_translateY.o" "MGUN_Lindex2.ty"; -connectAttr "MGUN_Lindex2_translateZ.o" "MGUN_Lindex2.tz"; -connectAttr "MGUN_Lindex2_visibility.o" "MGUN_Lindex2.v"; -connectAttr "MGUN_Lindex3_visibility.o" "MGUN_Lindex3.v"; -connectAttr "MGUN_Lindex3_translateX.o" "MGUN_Lindex3.tx"; -connectAttr "MGUN_Lindex3_translateY.o" "MGUN_Lindex3.ty"; -connectAttr "MGUN_Lindex3_translateZ.o" "MGUN_Lindex3.tz"; -connectAttr "MGUN_Lindex3_rotateX.o" "MGUN_Lindex3.rx"; -connectAttr "MGUN_Lindex3_rotateY.o" "MGUN_Lindex3.ry"; -connectAttr "MGUN_Lindex3_rotateZ.o" "MGUN_Lindex3.rz"; -connectAttr "MGUN_Lindex3_scaleX.o" "MGUN_Lindex3.sx"; -connectAttr "MGUN_Lindex3_scaleY.o" "MGUN_Lindex3.sy"; -connectAttr "MGUN_Lindex3_scaleZ.o" "MGUN_Lindex3.sz"; -connectAttr "MGUN_Lmiddle1_scaleX.o" "MGUN_Lmiddle1.sx"; -connectAttr "MGUN_Lmiddle1_scaleY.o" "MGUN_Lmiddle1.sy"; -connectAttr "MGUN_Lmiddle1_scaleZ.o" "MGUN_Lmiddle1.sz"; -connectAttr "MGUN_Lmiddle1_rotateX.o" "MGUN_Lmiddle1.rx"; -connectAttr "MGUN_Lmiddle1_rotateY.o" "MGUN_Lmiddle1.ry"; -connectAttr "MGUN_Lmiddle1_rotateZ.o" "MGUN_Lmiddle1.rz"; -connectAttr "MGUN_Lmiddle1_translateX.o" "MGUN_Lmiddle1.tx"; -connectAttr "MGUN_Lmiddle1_translateY.o" "MGUN_Lmiddle1.ty"; -connectAttr "MGUN_Lmiddle1_translateZ.o" "MGUN_Lmiddle1.tz"; -connectAttr "MGUN_Lmiddle1_visibility.o" "MGUN_Lmiddle1.v"; -connectAttr "MGUN_Lring1_scaleX.o" "MGUN_Lring1.sx"; -connectAttr "MGUN_Lring1_scaleY.o" "MGUN_Lring1.sy"; -connectAttr "MGUN_Lring1_scaleZ.o" "MGUN_Lring1.sz"; -connectAttr "MGUN_Lring1_rotateX.o" "MGUN_Lring1.rx"; -connectAttr "MGUN_Lring1_rotateY.o" "MGUN_Lring1.ry"; -connectAttr "MGUN_Lring1_rotateZ.o" "MGUN_Lring1.rz"; -connectAttr "MGUN_Lring1_translateX.o" "MGUN_Lring1.tx"; -connectAttr "MGUN_Lring1_translateY.o" "MGUN_Lring1.ty"; -connectAttr "MGUN_Lring1_translateZ.o" "MGUN_Lring1.tz"; -connectAttr "MGUN_Lring1_visibility.o" "MGUN_Lring1.v"; -connectAttr "MGUN_Lring2_scaleX.o" "MGUN_Lring2.sx"; -connectAttr "MGUN_Lring2_scaleY.o" "MGUN_Lring2.sy"; -connectAttr "MGUN_Lring2_scaleZ.o" "MGUN_Lring2.sz"; -connectAttr "MGUN_Lring2_rotateX.o" "MGUN_Lring2.rx"; -connectAttr "MGUN_Lring2_rotateY.o" "MGUN_Lring2.ry"; -connectAttr "MGUN_Lring2_rotateZ.o" "MGUN_Lring2.rz"; -connectAttr "MGUN_Lring2_translateX.o" "MGUN_Lring2.tx"; -connectAttr "MGUN_Lring2_translateY.o" "MGUN_Lring2.ty"; -connectAttr "MGUN_Lring2_translateZ.o" "MGUN_Lring2.tz"; -connectAttr "MGUN_Lring2_visibility.o" "MGUN_Lring2.v"; -connectAttr "MGUN_Lpinky1_scaleX.o" "MGUN_Lpinky1.sx"; -connectAttr "MGUN_Lpinky1_scaleY.o" "MGUN_Lpinky1.sy"; -connectAttr "MGUN_Lpinky1_scaleZ.o" "MGUN_Lpinky1.sz"; -connectAttr "MGUN_Lpinky1_rotateX.o" "MGUN_Lpinky1.rx"; -connectAttr "MGUN_Lpinky1_rotateY.o" "MGUN_Lpinky1.ry"; -connectAttr "MGUN_Lpinky1_rotateZ.o" "MGUN_Lpinky1.rz"; -connectAttr "MGUN_Lpinky1_translateX.o" "MGUN_Lpinky1.tx"; -connectAttr "MGUN_Lpinky1_translateY.o" "MGUN_Lpinky1.ty"; -connectAttr "MGUN_Lpinky1_translateZ.o" "MGUN_Lpinky1.tz"; -connectAttr "MGUN_Lpinky1_visibility.o" "MGUN_Lpinky1.v"; -connectAttr "MGUN_Rthumb1_scaleX.o" "MGUN_Rthumb1.sx"; -connectAttr "MGUN_Rthumb1_scaleY.o" "MGUN_Rthumb1.sy"; -connectAttr "MGUN_Rthumb1_scaleZ.o" "MGUN_Rthumb1.sz"; -connectAttr "MGUN_Rthumb1_rotateY.o" "MGUN_Rthumb1.ry"; -connectAttr "MGUN_Rthumb1_rotateX.o" "MGUN_Rthumb1.rx"; -connectAttr "MGUN_Rthumb1_rotateZ.o" "MGUN_Rthumb1.rz"; -connectAttr "MGUN_Rthumb1_translateX.o" "MGUN_Rthumb1.tx"; -connectAttr "MGUN_Rthumb1_translateY.o" "MGUN_Rthumb1.ty"; -connectAttr "MGUN_Rthumb1_translateZ.o" "MGUN_Rthumb1.tz"; -connectAttr "MGUN_Rthumb1_visibility.o" "MGUN_Rthumb1.v"; -connectAttr "MGUN_Rthumb2_scaleX.o" "MGUN_Rthumb2.sx"; -connectAttr "MGUN_Rthumb2_scaleY.o" "MGUN_Rthumb2.sy"; -connectAttr "MGUN_Rthumb2_scaleZ.o" "MGUN_Rthumb2.sz"; -connectAttr "MGUN_Rthumb2_rotateX.o" "MGUN_Rthumb2.rx"; -connectAttr "MGUN_Rthumb2_rotateZ.o" "MGUN_Rthumb2.rz"; -connectAttr "MGUN_Rthumb2_rotateY.o" "MGUN_Rthumb2.ry"; -connectAttr "MGUN_Rthumb2_translateX.o" "MGUN_Rthumb2.tx"; -connectAttr "MGUN_Rthumb2_translateY.o" "MGUN_Rthumb2.ty"; -connectAttr "MGUN_Rthumb2_translateZ.o" "MGUN_Rthumb2.tz"; -connectAttr "MGUN_Rthumb2_visibility.o" "MGUN_Rthumb2.v"; -connectAttr "MGUN_Rthumb3_rotateX.o" "MGUN_Rthumb3.rx"; -connectAttr "MGUN_Rthumb3_rotateY.o" "MGUN_Rthumb3.ry"; -connectAttr "MGUN_Rthumb3_rotateZ.o" "MGUN_Rthumb3.rz"; -connectAttr "MGUN_Rthumb3_translateX.o" "MGUN_Rthumb3.tx"; -connectAttr "MGUN_Rthumb3_translateY.o" "MGUN_Rthumb3.ty"; -connectAttr "MGUN_Rthumb3_translateZ.o" "MGUN_Rthumb3.tz"; -connectAttr "MGUN_Rthumb3_visibility.o" "MGUN_Rthumb3.v"; -connectAttr "MGUN_Rthumb3_scaleX.o" "MGUN_Rthumb3.sx"; -connectAttr "MGUN_Rthumb3_scaleY.o" "MGUN_Rthumb3.sy"; -connectAttr "MGUN_Rthumb3_scaleZ.o" "MGUN_Rthumb3.sz"; -connectAttr "MGUN_Rindex1_scaleX.o" "MGUN_Rindex1.sx"; -connectAttr "MGUN_Rindex1_scaleY.o" "MGUN_Rindex1.sy"; -connectAttr "MGUN_Rindex1_scaleZ.o" "MGUN_Rindex1.sz"; -connectAttr "MGUN_Rindex1_rotateX.o" "MGUN_Rindex1.rx"; -connectAttr "MGUN_Rindex1_rotateZ.o" "MGUN_Rindex1.rz"; -connectAttr "MGUN_Rindex1_rotateY.o" "MGUN_Rindex1.ry"; -connectAttr "MGUN_Rindex1_translateX.o" "MGUN_Rindex1.tx"; -connectAttr "MGUN_Rindex1_translateY.o" "MGUN_Rindex1.ty"; -connectAttr "MGUN_Rindex1_translateZ.o" "MGUN_Rindex1.tz"; -connectAttr "MGUN_Rindex1_visibility.o" "MGUN_Rindex1.v"; -connectAttr "MGUN_Rindex2_scaleX.o" "MGUN_Rindex2.sx"; -connectAttr "MGUN_Rindex2_scaleY.o" "MGUN_Rindex2.sy"; -connectAttr "MGUN_Rindex2_scaleZ.o" "MGUN_Rindex2.sz"; -connectAttr "MGUN_Rindex2_rotateX.o" "MGUN_Rindex2.rx"; -connectAttr "MGUN_Rindex2_rotateZ.o" "MGUN_Rindex2.rz"; -connectAttr "MGUN_Rindex2_rotateY.o" "MGUN_Rindex2.ry"; -connectAttr "MGUN_Rindex2_translateX.o" "MGUN_Rindex2.tx"; -connectAttr "MGUN_Rindex2_translateY.o" "MGUN_Rindex2.ty"; -connectAttr "MGUN_Rindex2_translateZ.o" "MGUN_Rindex2.tz"; -connectAttr "MGUN_Rindex2_visibility.o" "MGUN_Rindex2.v"; -connectAttr "MGUN_Rindex3_rotateX.o" "MGUN_Rindex3.rx"; -connectAttr "MGUN_Rindex3_rotateY.o" "MGUN_Rindex3.ry"; -connectAttr "MGUN_Rindex3_rotateZ.o" "MGUN_Rindex3.rz"; -connectAttr "MGUN_Rindex3_translateX.o" "MGUN_Rindex3.tx"; -connectAttr "MGUN_Rindex3_translateY.o" "MGUN_Rindex3.ty"; -connectAttr "MGUN_Rindex3_translateZ.o" "MGUN_Rindex3.tz"; -connectAttr "MGUN_Rindex3_visibility.o" "MGUN_Rindex3.v"; -connectAttr "MGUN_Rindex3_scaleX.o" "MGUN_Rindex3.sx"; -connectAttr "MGUN_Rindex3_scaleY.o" "MGUN_Rindex3.sy"; -connectAttr "MGUN_Rindex3_scaleZ.o" "MGUN_Rindex3.sz"; -connectAttr "MGUN_Rmiddle1_scaleX.o" "MGUN_Rmiddle1.sx"; -connectAttr "MGUN_Rmiddle1_scaleY.o" "MGUN_Rmiddle1.sy"; -connectAttr "MGUN_Rmiddle1_scaleZ.o" "MGUN_Rmiddle1.sz"; -connectAttr "MGUN_Rmiddle1_rotateY.o" "MGUN_Rmiddle1.ry"; -connectAttr "MGUN_Rmiddle1_rotateZ.o" "MGUN_Rmiddle1.rz"; -connectAttr "MGUN_Rmiddle1_rotateX.o" "MGUN_Rmiddle1.rx"; -connectAttr "MGUN_Rmiddle1_translateX.o" "MGUN_Rmiddle1.tx"; -connectAttr "MGUN_Rmiddle1_translateY.o" "MGUN_Rmiddle1.ty"; -connectAttr "MGUN_Rmiddle1_translateZ.o" "MGUN_Rmiddle1.tz"; -connectAttr "MGUN_Rmiddle1_visibility.o" "MGUN_Rmiddle1.v"; -connectAttr "MGUN_Rmiddle2_scaleX.o" "MGUN_Rmiddle2.sx"; -connectAttr "MGUN_Rmiddle2_scaleY.o" "MGUN_Rmiddle2.sy"; -connectAttr "MGUN_Rmiddle2_scaleZ.o" "MGUN_Rmiddle2.sz"; -connectAttr "MGUN_Rmiddle2_rotateX.o" "MGUN_Rmiddle2.rx"; -connectAttr "MGUN_Rmiddle2_rotateY.o" "MGUN_Rmiddle2.ry"; -connectAttr "MGUN_Rmiddle2_rotateZ.o" "MGUN_Rmiddle2.rz"; -connectAttr "MGUN_Rmiddle2_translateX.o" "MGUN_Rmiddle2.tx"; -connectAttr "MGUN_Rmiddle2_translateY.o" "MGUN_Rmiddle2.ty"; -connectAttr "MGUN_Rmiddle2_translateZ.o" "MGUN_Rmiddle2.tz"; -connectAttr "MGUN_Rmiddle2_visibility.o" "MGUN_Rmiddle2.v"; -connectAttr "MGUN_Rmiddle3_rotateX.o" "MGUN_Rmiddle3.rx"; -connectAttr "MGUN_Rmiddle3_rotateY.o" "MGUN_Rmiddle3.ry"; -connectAttr "MGUN_Rmiddle3_rotateZ.o" "MGUN_Rmiddle3.rz"; -connectAttr "MGUN_Rmiddle3_translateX.o" "MGUN_Rmiddle3.tx"; -connectAttr "MGUN_Rmiddle3_translateY.o" "MGUN_Rmiddle3.ty"; -connectAttr "MGUN_Rmiddle3_translateZ.o" "MGUN_Rmiddle3.tz"; -connectAttr "MGUN_Rmiddle3_visibility.o" "MGUN_Rmiddle3.v"; -connectAttr "MGUN_Rmiddle3_scaleX.o" "MGUN_Rmiddle3.sx"; -connectAttr "MGUN_Rmiddle3_scaleY.o" "MGUN_Rmiddle3.sy"; -connectAttr "MGUN_Rmiddle3_scaleZ.o" "MGUN_Rmiddle3.sz"; -connectAttr "MGUN_Rring1_scaleX.o" "MGUN_Rring1.sx"; -connectAttr "MGUN_Rring1_scaleY.o" "MGUN_Rring1.sy"; -connectAttr "MGUN_Rring1_scaleZ.o" "MGUN_Rring1.sz"; -connectAttr "MGUN_Rring1_rotateX.o" "MGUN_Rring1.rx"; -connectAttr "MGUN_Rring1_rotateY.o" "MGUN_Rring1.ry"; -connectAttr "MGUN_Rring1_rotateZ.o" "MGUN_Rring1.rz"; -connectAttr "MGUN_Rring1_translateX.o" "MGUN_Rring1.tx"; -connectAttr "MGUN_Rring1_translateY.o" "MGUN_Rring1.ty"; -connectAttr "MGUN_Rring1_translateZ.o" "MGUN_Rring1.tz"; -connectAttr "MGUN_Rring1_visibility.o" "MGUN_Rring1.v"; -connectAttr "MGUN_Rring2_scaleX.o" "MGUN_Rring2.sx"; -connectAttr "MGUN_Rring2_scaleY.o" "MGUN_Rring2.sy"; -connectAttr "MGUN_Rring2_scaleZ.o" "MGUN_Rring2.sz"; -connectAttr "MGUN_Rring2_visibility.o" "MGUN_Rring2.v"; -connectAttr "MGUN_Rring2_translateX.o" "MGUN_Rring2.tx"; -connectAttr "MGUN_Rring2_translateY.o" "MGUN_Rring2.ty"; -connectAttr "MGUN_Rring2_translateZ.o" "MGUN_Rring2.tz"; -connectAttr "MGUN_Rring2_rotateX.o" "MGUN_Rring2.rx"; -connectAttr "MGUN_Rring2_rotateY.o" "MGUN_Rring2.ry"; -connectAttr "MGUN_Rring2_rotateZ.o" "MGUN_Rring2.rz"; -connectAttr "MGUN_Rrring3_visibility.o" "MGUN_Rrring3.v"; -connectAttr "MGUN_Rrring3_translateX.o" "MGUN_Rrring3.tx"; -connectAttr "MGUN_Rrring3_translateY.o" "MGUN_Rrring3.ty"; -connectAttr "MGUN_Rrring3_translateZ.o" "MGUN_Rrring3.tz"; -connectAttr "MGUN_Rrring3_rotateX.o" "MGUN_Rrring3.rx"; -connectAttr "MGUN_Rrring3_rotateY.o" "MGUN_Rrring3.ry"; -connectAttr "MGUN_Rrring3_rotateZ.o" "MGUN_Rrring3.rz"; -connectAttr "MGUN_Rrring3_scaleX.o" "MGUN_Rrring3.sx"; -connectAttr "MGUN_Rrring3_scaleY.o" "MGUN_Rrring3.sy"; -connectAttr "MGUN_Rrring3_scaleZ.o" "MGUN_Rrring3.sz"; -connectAttr "MGUN_Rpinky1_scaleX.o" "MGUN_Rpinky1.sx"; -connectAttr "MGUN_Rpinky1_scaleY.o" "MGUN_Rpinky1.sy"; -connectAttr "MGUN_Rpinky1_scaleZ.o" "MGUN_Rpinky1.sz"; -connectAttr "MGUN_Rpinky1_rotateX.o" "MGUN_Rpinky1.rx"; -connectAttr "MGUN_Rpinky1_rotateZ.o" "MGUN_Rpinky1.rz"; -connectAttr "MGUN_Rpinky1_rotateY.o" "MGUN_Rpinky1.ry"; -connectAttr "MGUN_Rpinky1_translateX.o" "MGUN_Rpinky1.tx"; -connectAttr "MGUN_Rpinky1_translateY.o" "MGUN_Rpinky1.ty"; -connectAttr "MGUN_Rpinky1_translateZ.o" "MGUN_Rpinky1.tz"; -connectAttr "MGUN_Rpinky1_visibility.o" "MGUN_Rpinky1.v"; -connectAttr "MGUN_Rpinky2_scaleX.o" "MGUN_Rpinky2.sx"; -connectAttr "MGUN_Rpinky2_scaleY.o" "MGUN_Rpinky2.sy"; -connectAttr "MGUN_Rpinky2_scaleZ.o" "MGUN_Rpinky2.sz"; -connectAttr "MGUN_Rpinky2_rotateX.o" "MGUN_Rpinky2.rx"; -connectAttr "MGUN_Rpinky2_rotateY.o" "MGUN_Rpinky2.ry"; -connectAttr "MGUN_Rpinky2_rotateZ.o" "MGUN_Rpinky2.rz"; -connectAttr "MGUN_Rpinky2_translateX.o" "MGUN_Rpinky2.tx"; -connectAttr "MGUN_Rpinky2_translateY.o" "MGUN_Rpinky2.ty"; -connectAttr "MGUN_Rpinky2_translateZ.o" "MGUN_Rpinky2.tz"; -connectAttr "MGUN_Rpinky2_visibility.o" "MGUN_Rpinky2.v"; -connectAttr "MGUN_Rpinky3_visibility.o" "MGUN_Rpinky3.v"; -connectAttr "MGUN_Rpinky3_translateX.o" "MGUN_Rpinky3.tx"; -connectAttr "MGUN_Rpinky3_translateY.o" "MGUN_Rpinky3.ty"; -connectAttr "MGUN_Rpinky3_translateZ.o" "MGUN_Rpinky3.tz"; -connectAttr "MGUN_Rpinky3_rotateX.o" "MGUN_Rpinky3.rx"; -connectAttr "MGUN_Rpinky3_rotateY.o" "MGUN_Rpinky3.ry"; -connectAttr "MGUN_Rpinky3_rotateZ.o" "MGUN_Rpinky3.rz"; -connectAttr "MGUN_Rpinky3_scaleX.o" "MGUN_Rpinky3.sx"; -connectAttr "MGUN_Rpinky3_scaleY.o" "MGUN_Rpinky3.sy"; -connectAttr "MGUN_Rpinky3_scaleZ.o" "MGUN_Rpinky3.sz"; -connectAttr "MGUN_ikHandle4_twist.o" "MGUN_ikHandle4.twi"; -connectAttr "MGUN_ikHandle4_scaleX.o" "MGUN_ikHandle4.sx"; -connectAttr "MGUN_ikHandle4_scaleY.o" "MGUN_ikHandle4.sy"; -connectAttr "MGUN_ikHandle4_scaleZ.o" "MGUN_ikHandle4.sz"; -connectAttr "MGUN_ikHandle4_rotateX.o" "MGUN_ikHandle4.rx"; -connectAttr "MGUN_ikHandle4_rotateY.o" "MGUN_ikHandle4.ry"; -connectAttr "MGUN_ikHandle4_rotateZ.o" "MGUN_ikHandle4.rz"; -connectAttr "MGUN_ikHandle4_visibility.o" "MGUN_ikHandle4.v"; -connectAttr "MGUN_ikHandle4_solverEnable.o" "MGUN_ikHandle4.hse"; -connectAttr "MGUN_ikHandle4_poleVectorX.o" "MGUN_ikHandle4.pvx"; -connectAttr "MGUN_ikHandle4_poleVectorY.o" "MGUN_ikHandle4.pvy"; -connectAttr "MGUN_ikHandle4_poleVectorZ.o" "MGUN_ikHandle4.pvz"; -connectAttr "MGUN_ikHandle4_offset.o" "MGUN_ikHandle4.off"; -connectAttr "MGUN_ikHandle4_roll.o" "MGUN_ikHandle4.rol"; -connectAttr "MGUN_barrel_translateX.o" "MGUN_barrel.tx"; -connectAttr "MGUN_barrel_translateY.o" "MGUN_barrel.ty"; -connectAttr "MGUN_barrel_translateZ.o" "MGUN_barrel.tz"; -connectAttr "MGUN_barrel_visibility.o" "MGUN_barrel.v"; -connectAttr "MGUN_barrel_rotateX.o" "MGUN_barrel.rx"; -connectAttr "MGUN_barrel_rotateY.o" "MGUN_barrel.ry"; -connectAttr "MGUN_barrel_rotateZ.o" "MGUN_barrel.rz"; -connectAttr "MGUN_barrel_scaleX.o" "MGUN_barrel.sx"; -connectAttr "MGUN_barrel_scaleY.o" "MGUN_barrel.sy"; -connectAttr "MGUN_barrel_scaleZ.o" "MGUN_barrel.sz"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[0].llnk"; -connectAttr ":initialShadingGroup.msg" "lightLinker1.lnk[0].olnk"; -connectAttr ":defaultLightSet.msg" "lightLinker1.lnk[1].llnk"; -connectAttr ":initialParticleSE.msg" "lightLinker1.lnk[1].olnk"; -connectAttr "layerManager.dli[0]" "defaultLayer.id"; -connectAttr "renderLayerManager.rlmi[0]" "defaultRenderLayer.rlid"; -connectAttr "lightLinker1.msg" ":lightList1.ln" -na; -// End of reload1.ma diff --git a/base/models/weapons/machinegun/fred/setup1.mb b/base/models/weapons/machinegun/fred/setup1.mb deleted file mode 100644 index 1456ee2ff..000000000 Binary files a/base/models/weapons/machinegun/fred/setup1.mb and /dev/null differ diff --git a/cm/CollisionModel.h b/cm/CollisionModel.h new file mode 100644 index 000000000..71ea24588 --- /dev/null +++ b/cm/CollisionModel.h @@ -0,0 +1,139 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __COLLISIONMODELMANAGER_H__ +#define __COLLISIONMODELMANAGER_H__ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + + Short translations are the least expensive. Retrieving contact points is + about as cheap as a short translation. Position tests are more expensive + and rotations are most expensive. + + There is no position test at the start of a translation or rotation. In other + words if a translation with start != end or a rotation with angle != 0 starts + in solid, this goes unnoticed and the collision result is undefined. + + A translation with start == end or a rotation with angle == 0 performs + a position test and fills in the trace_t structure accordingly. + +=============================================================================== +*/ + +// contact type +typedef enum { + CONTACT_NONE, // no contact + CONTACT_EDGE, // trace model edge hits model edge + CONTACT_MODELVERTEX, // model vertex hits trace model polygon + CONTACT_TRMVERTEX // trace model vertex hits model polygon +} contactType_t; + +// contact info +struct contactInfo_t { + contactType_t type; // contact type + idVec3 point; // point of contact + idVec3 normal; // contact plane normal + float dist; // contact plane distance + int contents; // contents at other side of surface + const idMaterial * material; // surface material + int modelFeature; // contact feature on model + int trmFeature; // contact feature on trace model + int entityNum; // entity the contact surface is a part of + int id; // id of clip model the contact surface is part of +}; + +// trace result +typedef struct trace_s { + float fraction; // fraction of movement completed, 1.0 = didn't hit anything + idVec3 endpos; // final position of trace model + idMat3 endAxis; // final axis of trace model + contactInfo_t c; // contact information, only valid if fraction < 1.0 +} trace_t; + +typedef int cmHandle_t; + +#define CM_CLIP_EPSILON 0.25f // always stay this distance away from any model +#define CM_BOX_EPSILON 1.0f // should always be larger than clip epsilon +#define CM_MAX_TRACE_DIST 4096.0f // maximum distance a trace model may be traced, point traces are unlimited + +class idCollisionModelManager { +public: + virtual ~idCollisionModelManager( void ) {} + + // Loads collision models from a map file. + virtual void LoadMap( const idMapFile *mapFile ) = 0; + // Frees all the collision models. + virtual void FreeMap( void ) = 0; + + // Gets the clip handle for a model. + virtual cmHandle_t LoadModel( const char *modelName, const bool precache ) = 0; + // Sets up a trace model for collision with other trace models. + virtual cmHandle_t SetupTrmModel( const idTraceModel &trm, const idMaterial *material ) = 0; + // Creates a trace model from a collision model, returns true if succesfull. + virtual bool TrmFromModel( const char *modelName, idTraceModel &trm ) = 0; + + // Gets the name of a model. + virtual const char * GetModelName( cmHandle_t model ) const = 0; + // Gets the bounds of a model. + virtual bool GetModelBounds( cmHandle_t model, idBounds &bounds ) const = 0; + // Gets all contents flags of brushes and polygons of a model ored together. + virtual bool GetModelContents( cmHandle_t model, int &contents ) const = 0; + // Gets a vertex of a model. + virtual bool GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const = 0; + // Gets an edge of a model. + virtual bool GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const = 0; + // Gets a polygon of a model. + virtual bool GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const = 0; + + // Translates a trace model and reports the first collision if any. + virtual void Translation( trace_t *results, const idVec3 &start, const idVec3 &end, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; + // Rotates a trace model and reports the first collision if any. + virtual void Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; + // Returns the contents touched by the trace model or 0 if the trace model is in free space. + virtual int Contents( const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; + // Stores all contact points of the trace model with the model, returns the number of contacts. + virtual int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; + + // Tests collision detection. + virtual void DebugOutput( const idVec3 &origin ) = 0; + // Draws a model. + virtual void DrawModel( cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis, + const idVec3 &viewOrigin, const float radius ) = 0; + // Prints model information, use -1 handle for accumulated model info. + virtual void ModelInfo( cmHandle_t model ) = 0; + // Lists all loaded models. + virtual void ListModels( void ) = 0; + // Writes a collision model file for the given map entity. + virtual bool WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ) = 0; +}; + +extern idCollisionModelManager * collisionModelManager; + +#endif /* !__COLLISIONMODELMANAGER_H__ */ diff --git a/cm/CollisionModel_contacts.cpp b/cm/CollisionModel_contacts.cpp new file mode 100644 index 000000000..36b650990 --- /dev/null +++ b/cm/CollisionModel_contacts.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +/* +=============================================================================== + +Retrieving contacts + +=============================================================================== +*/ + +/* +================== +idCollisionModelManagerLocal::Contacts +================== +*/ +int idCollisionModelManagerLocal::Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ) { + trace_t results; + idVec3 end; + + // same as Translation but instead of storing the first collision we store all collisions as contacts + idCollisionModelManagerLocal::getContacts = true; + idCollisionModelManagerLocal::contacts = contacts; + idCollisionModelManagerLocal::maxContacts = maxContacts; + idCollisionModelManagerLocal::numContacts = 0; + end = start + dir.SubVec3(0) * depth; + idCollisionModelManagerLocal::Translation( &results, start, end, trm, trmAxis, contentMask, model, origin, modelAxis ); + if ( dir.SubVec3(1).LengthSqr() != 0.0f ) { + // FIXME: rotational contacts + } + idCollisionModelManagerLocal::getContacts = false; + idCollisionModelManagerLocal::maxContacts = 0; + + return idCollisionModelManagerLocal::numContacts; +} diff --git a/cm/CollisionModel_contents.cpp b/cm/CollisionModel_contents.cpp new file mode 100644 index 000000000..68c76eba8 --- /dev/null +++ b/cm/CollisionModel_contents.cpp @@ -0,0 +1,632 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +/* +=============================================================================== + +Contents test + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::TestTrmVertsInBrush + + returns true if any of the trm vertices is inside the brush +================ +*/ +bool idCollisionModelManagerLocal::TestTrmVertsInBrush( cm_traceWork_t *tw, cm_brush_t *b ) { + int i, j, numVerts, bestPlane; + float d, bestd; + idVec3 *p; + + if ( b->checkcount == idCollisionModelManagerLocal::checkCount ) { + return false; + } + b->checkcount = idCollisionModelManagerLocal::checkCount; + + if ( !(b->contents & tw->contents) ) { + return false; + } + + // if the brush bounds don't intersect the trace bounds + if ( !b->bounds.IntersectsBounds( tw->bounds ) ) { + return false; + } + + if ( tw->pointTrace ) { + numVerts = 1; + } + else { + numVerts = tw->numVerts; + } + + for ( j = 0; j < numVerts; j++ ) { + p = &tw->vertices[j].p; + + // see if the point is inside the brush + bestPlane = 0; + bestd = -idMath::INFINITY; + for ( i = 0; i < b->numPlanes; i++ ) { + d = b->planes[i].Distance( *p ); + if ( d >= 0.0f ) { + break; + } + if ( d > bestd ) { + bestd = d; + bestPlane = i; + } + } + if ( i >= b->numPlanes ) { + tw->trace.fraction = 0.0f; + tw->trace.c.type = CONTACT_TRMVERTEX; + tw->trace.c.normal = b->planes[bestPlane].Normal(); + tw->trace.c.dist = b->planes[bestPlane].Dist(); + tw->trace.c.contents = b->contents; + tw->trace.c.material = b->material; + tw->trace.c.point = *p; + tw->trace.c.modelFeature = 0; + tw->trace.c.trmFeature = j; + return true; + } + } + return false; +} + +/* +================ +CM_SetTrmEdgeSidedness +================ +*/ +#define CM_SetTrmEdgeSidedness( edge, bpl, epl, bitNum ) { \ + if ( !(edge->sideSet & (1<side = (edge->side & ~(1<sideSet |= (1 << bitNum); \ + } \ +} + +/* +================ +CM_SetTrmPolygonSidedness +================ +*/ +#define CM_SetTrmPolygonSidedness( v, plane, bitNum ) { \ + if ( !((v)->sideSet & (1<p ); \ + /* cannot use float sign bit because it is undetermined when fl == 0.0f */ \ + if ( fl < 0.0f ) { \ + (v)->side |= (1 << bitNum); \ + } \ + else { \ + (v)->side &= ~(1 << bitNum); \ + } \ + (v)->sideSet |= (1 << bitNum); \ + } \ +} + +/* +================ +idCollisionModelManagerLocal::TestTrmInPolygon + + returns true if the trm intersects the polygon +================ +*/ +bool idCollisionModelManagerLocal::TestTrmInPolygon( cm_traceWork_t *tw, cm_polygon_t *p ) { + int i, j, k, edgeNum, flip, trmEdgeNum, bitNum, bestPlane; + int sides[MAX_TRACEMODEL_VERTS]; + float d, bestd; + cm_trmEdge_t *trmEdge; + cm_edge_t *edge; + cm_vertex_t *v, *v1, *v2; + + // if already checked this polygon + if ( p->checkcount == idCollisionModelManagerLocal::checkCount ) { + return false; + } + p->checkcount = idCollisionModelManagerLocal::checkCount; + + // if this polygon does not have the right contents behind it + if ( !(p->contents & tw->contents) ) { + return false; + } + + // if the polygon bounds don't intersect the trace bounds + if ( !p->bounds.IntersectsBounds( tw->bounds ) ) { + return false; + } + + // bounds should cross polygon plane + switch( tw->bounds.PlaneSide( p->plane ) ) { + case PLANESIDE_CROSS: + break; + case PLANESIDE_FRONT: + if ( tw->model->isConvex ) { + tw->quickExit = true; + return true; + } + default: + return false; + } + + // if the trace model is convex + if ( tw->isConvex ) { + // test if any polygon vertices are inside the trm + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = tw->model->edges + abs(edgeNum); + // if this edge is already tested + if ( edge->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + + for ( j = 0; j < 2; j++ ) { + v = &tw->model->vertices[edge->vertexNum[j]]; + // if this vertex is already tested + if ( v->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + + bestPlane = 0; + bestd = -idMath::INFINITY; + for ( k = 0; k < tw->numPolys; k++ ) { + d = tw->polys[k].plane.Distance( v->p ); + if ( d >= 0.0f ) { + break; + } + if ( d > bestd ) { + bestd = d; + bestPlane = k; + } + } + if ( k >= tw->numPolys ) { + tw->trace.fraction = 0.0f; + tw->trace.c.type = CONTACT_MODELVERTEX; + tw->trace.c.normal = -tw->polys[bestPlane].plane.Normal(); + tw->trace.c.dist = -tw->polys[bestPlane].plane.Dist(); + tw->trace.c.contents = p->contents; + tw->trace.c.material = p->material; + tw->trace.c.point = v->p; + tw->trace.c.modelFeature = edge->vertexNum[j]; + tw->trace.c.trmFeature = 0; + return true; + } + } + } + } + + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = tw->model->edges + abs(edgeNum); + // reset sidedness cache if this is the first time we encounter this edge + if ( edge->checkcount != idCollisionModelManagerLocal::checkCount ) { + edge->sideSet = 0; + } + // pluecker coordinate for edge + tw->polygonEdgePlueckerCache[i].FromLine( tw->model->vertices[edge->vertexNum[0]].p, + tw->model->vertices[edge->vertexNum[1]].p ); + v = &tw->model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]]; + // reset sidedness cache if this is the first time we encounter this vertex + if ( v->checkcount != idCollisionModelManagerLocal::checkCount ) { + v->sideSet = 0; + } + v->checkcount = idCollisionModelManagerLocal::checkCount; + } + + // get side of polygon for each trm vertex + for ( i = 0; i < tw->numVerts; i++ ) { + d = p->plane.Distance( tw->vertices[i].p ); + sides[i] = d < 0.0f ? -1 : 1; + } + + // test if any trm edges go through the polygon + for ( i = 1; i <= tw->numEdges; i++ ) { + // if the trm edge does not cross the polygon plane + if ( sides[tw->edges[i].vertexNum[0]] == sides[tw->edges[i].vertexNum[1]] ) { + continue; + } + // check from which side to which side the trm edge goes + flip = INTSIGNBITSET( sides[tw->edges[i].vertexNum[0]] ); + // test if trm edge goes through the polygon between the polygon edges + for ( j = 0; j < p->numEdges; j++ ) { + edgeNum = p->edges[j]; + edge = tw->model->edges + abs(edgeNum); +#if 1 + CM_SetTrmEdgeSidedness( edge, tw->edges[i].pl, tw->polygonEdgePlueckerCache[j], i ); + if ( INTSIGNBITSET(edgeNum) ^ ((edge->side >> i) & 1) ^ flip ) { + break; + } +#else + d = tw->edges[i].pl.PermutedInnerProduct( tw->polygonEdgePlueckerCache[j] ); + if ( flip ) { + d = -d; + } + if ( edgeNum > 0 ) { + if ( d <= 0.0f ) { + break; + } + } + else { + if ( d >= 0.0f ) { + break; + } + } +#endif + } + if ( j >= p->numEdges ) { + tw->trace.fraction = 0.0f; + tw->trace.c.type = CONTACT_EDGE; + tw->trace.c.normal = p->plane.Normal(); + tw->trace.c.dist = p->plane.Dist(); + tw->trace.c.contents = p->contents; + tw->trace.c.material = p->material; + tw->trace.c.point = tw->vertices[tw->edges[i].vertexNum[ !flip ]].p; + tw->trace.c.modelFeature = *reinterpret_cast(&p); + tw->trace.c.trmFeature = i; + return true; + } + } + + // test if any polygon edges go through the trm polygons + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = tw->model->edges + abs(edgeNum); + if ( edge->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + edge->checkcount = idCollisionModelManagerLocal::checkCount; + + for ( j = 0; j < tw->numPolys; j++ ) { +#if 1 + v1 = tw->model->vertices + edge->vertexNum[0]; + CM_SetTrmPolygonSidedness( v1, tw->polys[j].plane, j ); + v2 = tw->model->vertices + edge->vertexNum[1]; + CM_SetTrmPolygonSidedness( v2, tw->polys[j].plane, j ); + // if the polygon edge does not cross the trm polygon plane + if ( !(((v1->side ^ v2->side) >> j) & 1) ) { + continue; + } + flip = (v1->side >> j) & 1; +#else + float d1, d2; + + v1 = tw->model->vertices + edge->vertexNum[0]; + d1 = tw->polys[j].plane.Distance( v1->p ); + v2 = tw->model->vertices + edge->vertexNum[1]; + d2 = tw->polys[j].plane.Distance( v2->p ); + // if the polygon edge does not cross the trm polygon plane + if ( (d1 >= 0.0f && d2 >= 0.0f) || (d1 <= 0.0f && d2 <= 0.0f) ) { + continue; + } + flip = false; + if ( d1 < 0.0f ) { + flip = true; + } +#endif + // test if polygon edge goes through the trm polygon between the trm polygon edges + for ( k = 0; k < tw->polys[j].numEdges; k++ ) { + trmEdgeNum = tw->polys[j].edges[k]; + trmEdge = tw->edges + abs(trmEdgeNum); +#if 1 + bitNum = abs(trmEdgeNum); + CM_SetTrmEdgeSidedness( edge, trmEdge->pl, tw->polygonEdgePlueckerCache[i], bitNum ); + if ( INTSIGNBITSET(trmEdgeNum) ^ ((edge->side >> bitNum) & 1) ^ flip ) { + break; + } +#else + d = trmEdge->pl.PermutedInnerProduct( tw->polygonEdgePlueckerCache[i] ); + if ( flip ) { + d = -d; + } + if ( trmEdgeNum > 0 ) { + if ( d <= 0.0f ) { + break; + } + } + else { + if ( d >= 0.0f ) { + break; + } + } +#endif + } + if ( k >= tw->polys[j].numEdges ) { + tw->trace.fraction = 0.0f; + tw->trace.c.type = CONTACT_EDGE; + tw->trace.c.normal = -tw->polys[j].plane.Normal(); + tw->trace.c.dist = -tw->polys[j].plane.Dist(); + tw->trace.c.contents = p->contents; + tw->trace.c.material = p->material; + tw->trace.c.point = tw->model->vertices[edge->vertexNum[ !flip ]].p; + tw->trace.c.modelFeature = edgeNum; + tw->trace.c.trmFeature = j; + return true; + } + } + } + return false; +} + +/* +================ +idCollisionModelManagerLocal::PointNode +================ +*/ +cm_node_t *idCollisionModelManagerLocal::PointNode( const idVec3 &p, cm_model_t *model ) { + cm_node_t *node; + + node = model->node; + while ( node->planeType != -1 ) { + if (p[node->planeType] > node->planeDist) { + node = node->children[0]; + } + else { + node = node->children[1]; + } + + assert( node != NULL ); + } + return node; +} + +/* +================ +idCollisionModelManagerLocal::PointContents +================ +*/ +int idCollisionModelManagerLocal::PointContents( const idVec3 p, cmHandle_t model ) { + int i; + float d; + cm_node_t *node; + cm_brushRef_t *bref; + cm_brush_t *b; + idPlane *plane; + + node = idCollisionModelManagerLocal::PointNode( p, idCollisionModelManagerLocal::models[model] ); + for ( bref = node->brushes; bref; bref = bref->next ) { + b = bref->b; + // test if the point is within the brush bounds + for ( i = 0; i < 3; i++ ) { + if ( p[i] < b->bounds[0][i] ) { + break; + } + if ( p[i] > b->bounds[1][i] ) { + break; + } + } + if ( i < 3 ) { + continue; + } + // test if the point is inside the brush + plane = b->planes; + for ( i = 0; i < b->numPlanes; i++, plane++ ) { + d = plane->Distance( p ); + if ( d >= 0 ) { + break; + } + } + if ( i >= b->numPlanes ) { + return b->contents; + } + } + return 0; +} + +/* +================== +idCollisionModelManagerLocal::TransformedPointContents +================== +*/ +int idCollisionModelManagerLocal::TransformedPointContents( const idVec3 &p, cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ) { + idVec3 p_l; + + // subtract origin offset + p_l = p - origin; + if ( modelAxis.IsRotated() ) { + p_l *= modelAxis; + } + return idCollisionModelManagerLocal::PointContents( p_l, model ); +} + + +/* +================== +idCollisionModelManagerLocal::ContentsTrm +================== +*/ +int idCollisionModelManagerLocal::ContentsTrm( trace_t *results, const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + int i; + bool model_rotated, trm_rotated; + idMat3 invModelAxis, tmpAxis; + idVec3 dir; + ALIGN16( cm_traceWork_t tw ); + + // fast point case + if ( !trm || ( trm->bounds[1][0] - trm->bounds[0][0] <= 0.0f && + trm->bounds[1][1] - trm->bounds[0][1] <= 0.0f && + trm->bounds[1][2] - trm->bounds[0][2] <= 0.0f ) ) { + + results->c.contents = idCollisionModelManagerLocal::TransformedPointContents( start, model, modelOrigin, modelAxis ); + results->fraction = ( results->c.contents == 0 ); + results->endpos = start; + results->endAxis = trmAxis; + + return results->c.contents; + } + + idCollisionModelManagerLocal::checkCount++; + + tw.trace.fraction = 1.0f; + tw.trace.c.contents = 0; + tw.trace.c.type = CONTACT_NONE; + tw.contents = contentMask; + tw.isConvex = true; + tw.rotation = false; + tw.positionTest = true; + tw.pointTrace = false; + tw.quickExit = false; + tw.numContacts = 0; + tw.model = idCollisionModelManagerLocal::models[model]; + tw.start = start - modelOrigin; + tw.end = tw.start; + + model_rotated = modelAxis.IsRotated(); + if ( model_rotated ) { + invModelAxis = modelAxis.Transpose(); + } + + // setup trm structure + idCollisionModelManagerLocal::SetupTrm( &tw, trm ); + + trm_rotated = trmAxis.IsRotated(); + + // calculate vertex positions + if ( trm_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + // rotate trm around the start position + tw.vertices[i].p *= trmAxis; + } + } + for ( i = 0; i < tw.numVerts; i++ ) { + // set trm at start position + tw.vertices[i].p += tw.start; + } + if ( model_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + // rotate trm around model instead of rotating the model + tw.vertices[i].p *= invModelAxis; + } + } + + // add offset to start point + if ( trm_rotated ) { + dir = trm->offset * trmAxis; + tw.start += dir; + tw.end += dir; + } else { + tw.start += trm->offset; + tw.end += trm->offset; + } + if ( model_rotated ) { + // rotate trace instead of model + tw.start *= invModelAxis; + tw.end *= invModelAxis; + } + + + // setup trm vertices + tw.size.Clear(); + for ( i = 0; i < tw.numVerts; i++ ) { + // get axial trm size after rotations + tw.size.AddPoint( tw.vertices[i].p - tw.start ); + } + + // setup trm edges + for ( i = 1; i <= tw.numEdges; i++ ) { + // edge start, end and pluecker coordinate + tw.edges[i].start = tw.vertices[tw.edges[i].vertexNum[0]].p; + tw.edges[i].end = tw.vertices[tw.edges[i].vertexNum[1]].p; + tw.edges[i].pl.FromLine( tw.edges[i].start, tw.edges[i].end ); + } + + // setup trm polygons + if ( trm_rotated & model_rotated ) { + tmpAxis = trmAxis * invModelAxis; + for ( i = 0; i < tw.numPolys; i++ ) { + tw.polys[i].plane *= tmpAxis; + } + } else if ( trm_rotated ) { + for ( i = 0; i < tw.numPolys; i++ ) { + tw.polys[i].plane *= trmAxis; + } + } else if ( model_rotated ) { + for ( i = 0; i < tw.numPolys; i++ ) { + tw.polys[i].plane *= invModelAxis; + } + } + for ( i = 0; i < tw.numPolys; i++ ) { + tw.polys[i].plane.FitThroughPoint( tw.edges[abs(tw.polys[i].edges[0])].start ); + } + + // bounds for full trace, a little bit larger for epsilons + for ( i = 0; i < 3; i++ ) { + if ( tw.start[i] < tw.end[i] ) { + tw.bounds[0][i] = tw.start[i] + tw.size[0][i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.end[i] + tw.size[1][i] + CM_BOX_EPSILON; + } else { + tw.bounds[0][i] = tw.end[i] + tw.size[0][i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.start[i] + tw.size[1][i] + CM_BOX_EPSILON; + } + if ( idMath::Fabs(tw.size[0][i]) > idMath::Fabs(tw.size[1][i]) ) { + tw.extents[i] = idMath::Fabs( tw.size[0][i] ) + CM_BOX_EPSILON; + } else { + tw.extents[i] = idMath::Fabs( tw.size[1][i] ) + CM_BOX_EPSILON; + } + } + + // trace through the model + idCollisionModelManagerLocal::TraceThroughModel( &tw ); + + *results = tw.trace; + results->fraction = ( results->c.contents == 0 ); + results->endpos = start; + results->endAxis = trmAxis; + + return results->c.contents; +} + +/* +================== +idCollisionModelManagerLocal::Contents +================== +*/ +int idCollisionModelManagerLocal::Contents( const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + trace_t results; + + if ( model < 0 || model > idCollisionModelManagerLocal::maxModels || model > MAX_SUBMODELS ) { + common->Printf("idCollisionModelManagerLocal::Contents: invalid model handle\n"); + return 0; + } + if ( !idCollisionModelManagerLocal::models || !idCollisionModelManagerLocal::models[model] ) { + common->Printf("idCollisionModelManagerLocal::Contents: invalid model\n"); + return 0; + } + + return ContentsTrm( &results, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); +} diff --git a/cm/CollisionModel_debug.cpp b/cm/CollisionModel_debug.cpp new file mode 100644 index 000000000..8349699c7 --- /dev/null +++ b/cm/CollisionModel_debug.cpp @@ -0,0 +1,479 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + + +/* +=============================================================================== + +Visualisation code + +=============================================================================== +*/ + +const char *cm_contentsNameByIndex[] = { + "none", // 0 + "solid", // 1 + "opaque", // 2 + "water", // 3 + "playerclip", // 4 + "monsterclip", // 5 + "moveableclip", // 6 + "ikclip", // 7 + "blood", // 8 + "body", // 9 + "corpse", // 10 + "trigger", // 11 + "aas_solid", // 12 + "aas_obstacle", // 13 + "flashlight_trigger", // 14 + NULL +}; + +int cm_contentsFlagByIndex[] = { + -1, // 0 + CONTENTS_SOLID, // 1 + CONTENTS_OPAQUE, // 2 + CONTENTS_WATER, // 3 + CONTENTS_PLAYERCLIP, // 4 + CONTENTS_MONSTERCLIP, // 5 + CONTENTS_MOVEABLECLIP, // 6 + CONTENTS_IKCLIP, // 7 + CONTENTS_BLOOD, // 8 + CONTENTS_BODY, // 9 + CONTENTS_CORPSE, // 10 + CONTENTS_TRIGGER, // 11 + CONTENTS_AAS_SOLID, // 12 + CONTENTS_AAS_OBSTACLE, // 13 + CONTENTS_FLASHLIGHT_TRIGGER, // 14 + 0 +}; + +idCVar cm_drawMask( "cm_drawMask", "none", CVAR_GAME, "collision mask", cm_contentsNameByIndex, idCmdSystem::ArgCompletion_String ); +idCVar cm_drawColor( "cm_drawColor", "1 0 0 .5", CVAR_GAME, "color used to draw the collision models" ); +idCVar cm_drawFilled( "cm_drawFilled", "0", CVAR_GAME | CVAR_BOOL, "draw filled polygons" ); +idCVar cm_drawInternal( "cm_drawInternal", "1", CVAR_GAME | CVAR_BOOL, "draw internal edges green" ); +idCVar cm_drawNormals( "cm_drawNormals", "0", CVAR_GAME | CVAR_BOOL, "draw polygon and edge normals" ); +idCVar cm_backFaceCull( "cm_backFaceCull", "0", CVAR_GAME | CVAR_BOOL, "cull back facing polygons" ); +idCVar cm_debugCollision( "cm_debugCollision", "0", CVAR_GAME | CVAR_BOOL, "debug the collision detection" ); + +static idVec4 cm_color; + +/* +================ +idCollisionModelManagerLocal::ContentsFromString +================ +*/ +int idCollisionModelManagerLocal::ContentsFromString( const char *string ) const { + int i, contents = 0; + idLexer src( string, idStr::Length( string ), "ContentsFromString" ); + idToken token; + + while( src.ReadToken( &token ) ) { + if ( token == "," ) { + continue; + } + for ( i = 1; cm_contentsNameByIndex[i] != NULL; i++ ) { + if ( token.Icmp( cm_contentsNameByIndex[i] ) == 0 ) { + contents |= cm_contentsFlagByIndex[i]; + break; + } + } + } + + return contents; +} + +/* +================ +idCollisionModelManagerLocal::StringFromContents +================ +*/ +const char *idCollisionModelManagerLocal::StringFromContents( const int contents ) const { + int i, length = 0; + static char contentsString[MAX_STRING_CHARS]; + + contentsString[0] = '\0'; + + for ( i = 1; cm_contentsFlagByIndex[i] != 0; i++ ) { + if ( contents & cm_contentsFlagByIndex[i] ) { + if ( length != 0 ) { + length += idStr::snPrintf( contentsString + length, sizeof( contentsString ) - length, "," ); + } + length += idStr::snPrintf( contentsString + length, sizeof( contentsString ) - length, cm_contentsNameByIndex[i] ); + } + } + + return contentsString; +} + +/* +================ +idCollisionModelManagerLocal::DrawEdge +================ +*/ +void idCollisionModelManagerLocal::DrawEdge( cm_model_t *model, int edgeNum, const idVec3 &origin, const idMat3 &axis ) { + int side; + cm_edge_t *edge; + idVec3 start, end, mid; + bool isRotated; + + isRotated = axis.IsRotated(); + + edge = model->edges + abs(edgeNum); + side = edgeNum < 0; + + start = model->vertices[edge->vertexNum[side]].p; + end = model->vertices[edge->vertexNum[!side]].p; + if ( isRotated ) { + start *= axis; + end *= axis; + } + start += origin; + end += origin; + + if ( edge->internal ) { + if ( cm_drawInternal.GetBool() ) { + session->rw->DebugArrow( colorGreen, start, end, 1 ); + } + } else { + if ( edge->numUsers > 2 ) { + session->rw->DebugArrow( colorBlue, start, end, 1 ); + } else { + session->rw->DebugArrow( cm_color, start, end, 1 ); + } + } + + if ( cm_drawNormals.GetBool() ) { + mid = (start + end) * 0.5f; + if ( isRotated ) { + end = mid + 5 * (axis * edge->normal); + } else { + end = mid + 5 * edge->normal; + } + session->rw->DebugArrow( colorCyan, mid, end, 1 ); + } +} + +/* +================ +idCollisionModelManagerLocal::DrawPolygon +================ +*/ +void idCollisionModelManagerLocal::DrawPolygon( cm_model_t *model, cm_polygon_t *p, const idVec3 &origin, const idMat3 &axis, const idVec3 &viewOrigin ) { + int i, edgeNum; + cm_edge_t *edge; + idVec3 center, end, dir; + + if ( cm_backFaceCull.GetBool() ) { + edgeNum = p->edges[0]; + edge = model->edges + abs(edgeNum); + dir = model->vertices[edge->vertexNum[0]].p - viewOrigin; + if ( dir * p->plane.Normal() > 0.0f ) { + return; + } + } + + if ( cm_drawNormals.GetBool() ) { + center = vec3_origin; + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = model->edges + abs(edgeNum); + center += model->vertices[edge->vertexNum[edgeNum < 0]].p; + } + center *= (1.0f / p->numEdges); + if ( axis.IsRotated() ) { + center = center * axis + origin; + end = center + 5 * (axis * p->plane.Normal()); + } else { + center += origin; + end = center + 5 * p->plane.Normal(); + } + session->rw->DebugArrow( colorMagenta, center, end, 1 ); + } + + if ( cm_drawFilled.GetBool() ) { + idFixedWinding winding; + for ( i = p->numEdges - 1; i >= 0; i-- ) { + edgeNum = p->edges[i]; + edge = model->edges + abs(edgeNum); + winding += origin + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p * axis; + } + session->rw->DebugPolygon( cm_color, winding ); + } else { + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = model->edges + abs(edgeNum); + if ( edge->checkcount == checkCount ) { + continue; + } + edge->checkcount = checkCount; + DrawEdge( model, edgeNum, origin, axis ); + } + } +} + +/* +================ +idCollisionModelManagerLocal::DrawNodePolygons +================ +*/ +void idCollisionModelManagerLocal::DrawNodePolygons( cm_model_t *model, cm_node_t *node, + const idVec3 &origin, const idMat3 &axis, + const idVec3 &viewOrigin, const float radius ) { + int i; + cm_polygon_t *p; + cm_polygonRef_t *pref; + + while (1) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + if ( radius ) { + // polygon bounds should overlap with trace bounds + for ( i = 0; i < 3; i++ ) { + if ( p->bounds[0][i] > viewOrigin[i] + radius ) { + break; + } + if ( p->bounds[1][i] < viewOrigin[i] - radius ) { + break; + } + } + if ( i < 3 ) { + continue; + } + } + if ( p->checkcount == checkCount ) { + continue; + } + if ( !( p->contents & cm_contentsFlagByIndex[cm_drawMask.GetInteger()] ) ) { + continue; + } + + DrawPolygon( model, p, origin, axis, viewOrigin ); + p->checkcount = checkCount; + } + if ( node->planeType == -1 ) { + break; + } + if ( radius && viewOrigin[node->planeType] > node->planeDist + radius ) { + node = node->children[0]; + } else if ( radius && viewOrigin[node->planeType] < node->planeDist - radius ) { + node = node->children[1]; + } else { + DrawNodePolygons( model, node->children[1], origin, axis, viewOrigin, radius ); + node = node->children[0]; + } + } +} + +/* +================ +idCollisionModelManagerLocal::DrawModel +================ +*/ +void idCollisionModelManagerLocal::DrawModel( cmHandle_t handle, const idVec3 &modelOrigin, const idMat3 &modelAxis, + const idVec3 &viewOrigin, const float radius ) { + + cm_model_t *model; + idVec3 viewPos; + + if ( handle < 0 && handle >= numModels ) { + return; + } + + if ( cm_drawColor.IsModified() ) { + sscanf( cm_drawColor.GetString(), "%f %f %f %f", &cm_color.x, &cm_color.y, &cm_color.z, &cm_color.w ); + cm_drawColor.ClearModified(); + } + + model = models[ handle ]; + viewPos = (viewOrigin - modelOrigin) * modelAxis.Transpose(); + checkCount++; + DrawNodePolygons( model, model->node, modelOrigin, modelAxis, viewPos, radius ); +} + +/* +=============================================================================== + +Speed test code + +=============================================================================== +*/ + +static idCVar cm_testCollision( "cm_testCollision", "0", CVAR_GAME | CVAR_BOOL, "" ); +static idCVar cm_testRotation( "cm_testRotation", "1", CVAR_GAME | CVAR_BOOL, "" ); +static idCVar cm_testModel( "cm_testModel", "0", CVAR_GAME | CVAR_INTEGER, "" ); +static idCVar cm_testTimes( "cm_testTimes", "1000", CVAR_GAME | CVAR_INTEGER, "" ); +static idCVar cm_testRandomMany( "cm_testRandomMany", "0", CVAR_GAME | CVAR_BOOL, "" ); +static idCVar cm_testOrigin( "cm_testOrigin", "0 0 0", CVAR_GAME, "" ); +static idCVar cm_testReset( "cm_testReset", "0", CVAR_GAME | CVAR_BOOL, "" ); +static idCVar cm_testBox( "cm_testBox", "-16 -16 0 16 16 64", CVAR_GAME, "" ); +static idCVar cm_testBoxRotation( "cm_testBoxRotation", "0 0 0", CVAR_GAME, "" ); +static idCVar cm_testWalk( "cm_testWalk", "1", CVAR_GAME | CVAR_BOOL, "" ); +static idCVar cm_testLength( "cm_testLength", "1024", CVAR_GAME | CVAR_FLOAT, "" ); +static idCVar cm_testRadius( "cm_testRadius", "64", CVAR_GAME | CVAR_FLOAT, "" ); +static idCVar cm_testAngle( "cm_testAngle", "60", CVAR_GAME | CVAR_FLOAT, "" ); + +static int total_translation; +static int min_translation = 999999; +static int max_translation = -999999; +static int num_translation = 0; +static int total_rotation; +static int min_rotation = 999999; +static int max_rotation = -999999; +static int num_rotation = 0; +static idVec3 start; +static idVec3 *testend; + +#include "../sys/sys_public.h" + +void idCollisionModelManagerLocal::DebugOutput( const idVec3 &origin ) { + int i, k, t; + char buf[128]; + idVec3 end; + idAngles boxAngles; + idMat3 modelAxis, boxAxis; + idBounds bounds; + trace_t trace; + + if ( !cm_testCollision.GetBool() ) { + return; + } + + testend = (idVec3 *) Mem_Alloc( cm_testTimes.GetInteger() * sizeof(idVec3) ); + + if ( cm_testReset.GetBool() || ( cm_testWalk.GetBool() && !start.Compare( start ) ) ) { + total_translation = total_rotation = 0; + min_translation = min_rotation = 999999; + max_translation = max_rotation = -999999; + num_translation = num_rotation = 0; + cm_testReset.SetBool( false ); + } + + if ( cm_testWalk.GetBool() ) { + start = origin; + cm_testOrigin.SetString( va( "%1.2f %1.2f %1.2f", start[0], start[1], start[2] ) ); + } else { + sscanf( cm_testOrigin.GetString(), "%f %f %f", &start[0], &start[1], &start[2] ); + } + + sscanf( cm_testBox.GetString(), "%f %f %f %f %f %f", &bounds[0][0], &bounds[0][1], &bounds[0][2], + &bounds[1][0], &bounds[1][1], &bounds[1][2] ); + sscanf( cm_testBoxRotation.GetString(), "%f %f %f", &boxAngles[0], &boxAngles[1], &boxAngles[2] ); + boxAxis = boxAngles.ToMat3(); + modelAxis.Identity(); + + idTraceModel itm( bounds ); + idRandom random( 0 ); + idTimer timer; + + if ( cm_testRandomMany.GetBool() ) { + // if many traces in one random direction + for ( i = 0; i < 3; i++ ) { + testend[0][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat(); + } + for ( k = 1; k < cm_testTimes.GetInteger(); k++ ) { + testend[k] = testend[0]; + } + } else { + // many traces each in a different random direction + for ( k = 0; k < cm_testTimes.GetInteger(); k++ ) { + for ( i = 0; i < 3; i++ ) { + testend[k][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat(); + } + } + } + + // translational collision detection + timer.Clear(); + timer.Start(); + for ( i = 0; i < cm_testTimes.GetInteger(); i++ ) { + Translation( &trace, start, testend[i], &itm, boxAxis, CONTENTS_SOLID|CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis ); + } + timer.Stop(); + t = timer.Milliseconds(); + if ( t < min_translation ) min_translation = t; + if ( t > max_translation ) max_translation = t; + num_translation++; + total_translation += t; + if ( cm_testTimes.GetInteger() > 9999 ) { + sprintf( buf, "%3dK", (int ) ( cm_testTimes.GetInteger() / 1000 ) ); + } else { + sprintf( buf, "%4d", cm_testTimes.GetInteger() ); + } + common->Printf("%s translations: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_translation, max_translation, (float) total_translation / num_translation ); + + if ( cm_testRandomMany.GetBool() ) { + // if many traces in one random direction + for ( i = 0; i < 3; i++ ) { + testend[0][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat(); + } + for ( k = 1; k < cm_testTimes.GetInteger(); k++ ) { + testend[k] = testend[0]; + } + } else { + // many traces each in a different random direction + for ( k = 0; k < cm_testTimes.GetInteger(); k++ ) { + for ( i = 0; i < 3; i++ ) { + testend[k][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat(); + } + } + } + + if ( cm_testRotation.GetBool() ) { + // rotational collision detection + idVec3 vec( random.CRandomFloat(), random.CRandomFloat(), random.RandomFloat() ); + vec.Normalize(); + idRotation rotation( vec3_origin, vec, cm_testAngle.GetFloat() ); + + timer.Clear(); + timer.Start(); + for ( i = 0; i < cm_testTimes.GetInteger(); i++ ) { + rotation.SetOrigin( testend[i] ); + Rotation( &trace, start, rotation, &itm, boxAxis, CONTENTS_SOLID|CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis ); + } + timer.Stop(); + t = timer.Milliseconds(); + if ( t < min_rotation ) min_rotation = t; + if ( t > max_rotation ) max_rotation = t; + num_rotation++; + total_rotation += t; + if ( cm_testTimes.GetInteger() > 9999 ) { + sprintf( buf, "%3dK", (int ) ( cm_testTimes.GetInteger() / 1000 ) ); + } else { + sprintf( buf, "%4d", cm_testTimes.GetInteger() ); + } + common->Printf("%s rotation: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_rotation, max_rotation, (float) total_rotation / num_rotation ); + } + + Mem_Free( testend ); + testend = NULL; +} diff --git a/cm/CollisionModel_files.cpp b/cm/CollisionModel_files.cpp new file mode 100644 index 000000000..f094dc847 --- /dev/null +++ b/cm/CollisionModel_files.cpp @@ -0,0 +1,607 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +#define CM_FILE_EXT "cm" +#define CM_FILEID "CM" +#define CM_FILEVERSION "1.00" + + +/* +=============================================================================== + +Writing of collision model file + +=============================================================================== +*/ + +void CM_GetNodeBounds( idBounds *bounds, cm_node_t *node ); +int CM_GetNodeContents( cm_node_t *node ); + + +/* +================ +idCollisionModelManagerLocal::WriteNodes +================ +*/ +void idCollisionModelManagerLocal::WriteNodes( idFile *fp, cm_node_t *node ) { + fp->WriteFloatString( "\t( %d %f )\n", node->planeType, node->planeDist ); + if ( node->planeType != -1 ) { + WriteNodes( fp, node->children[0] ); + WriteNodes( fp, node->children[1] ); + } +} + +/* +================ +idCollisionModelManagerLocal::CountPolygonMemory +================ +*/ +int idCollisionModelManagerLocal::CountPolygonMemory( cm_node_t *node ) const { + cm_polygonRef_t *pref; + cm_polygon_t *p; + int memory; + + memory = 0; + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + + memory += sizeof( cm_polygon_t ) + ( p->numEdges - 1 ) * sizeof( p->edges[0] ); + } + if ( node->planeType != -1 ) { + memory += CountPolygonMemory( node->children[0] ); + memory += CountPolygonMemory( node->children[1] ); + } + return memory; +} + +/* +================ +idCollisionModelManagerLocal::WritePolygons +================ +*/ +void idCollisionModelManagerLocal::WritePolygons( idFile *fp, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + int i; + + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + fp->WriteFloatString( "\t%d (", p->numEdges ); + for ( i = 0; i < p->numEdges; i++ ) { + fp->WriteFloatString( " %d", p->edges[i] ); + } + fp->WriteFloatString( " ) ( %f %f %f ) %f", p->plane.Normal()[0], p->plane.Normal()[1], p->plane.Normal()[2], p->plane.Dist() ); + fp->WriteFloatString( " ( %f %f %f )", p->bounds[0][0], p->bounds[0][1], p->bounds[0][2] ); + fp->WriteFloatString( " ( %f %f %f )", p->bounds[1][0], p->bounds[1][1], p->bounds[1][2] ); + fp->WriteFloatString( " \"%s\"\n", p->material->GetName() ); + } + if ( node->planeType != -1 ) { + WritePolygons( fp, node->children[0] ); + WritePolygons( fp, node->children[1] ); + } +} + +/* +================ +idCollisionModelManagerLocal::CountBrushMemory +================ +*/ +int idCollisionModelManagerLocal::CountBrushMemory( cm_node_t *node ) const { + cm_brushRef_t *bref; + cm_brush_t *b; + int memory; + + memory = 0; + for ( bref = node->brushes; bref; bref = bref->next ) { + b = bref->b; + if ( b->checkcount == checkCount ) { + continue; + } + b->checkcount = checkCount; + + memory += sizeof( cm_brush_t ) + ( b->numPlanes - 1 ) * sizeof( b->planes[0] ); + } + if ( node->planeType != -1 ) { + memory += CountBrushMemory( node->children[0] ); + memory += CountBrushMemory( node->children[1] ); + } + return memory; +} + +/* +================ +idCollisionModelManagerLocal::WriteBrushes +================ +*/ +void idCollisionModelManagerLocal::WriteBrushes( idFile *fp, cm_node_t *node ) { + cm_brushRef_t *bref; + cm_brush_t *b; + int i; + + for ( bref = node->brushes; bref; bref = bref->next ) { + b = bref->b; + if ( b->checkcount == checkCount ) { + continue; + } + b->checkcount = checkCount; + fp->WriteFloatString( "\t%d {\n", b->numPlanes ); + for ( i = 0; i < b->numPlanes; i++ ) { + fp->WriteFloatString( "\t\t( %f %f %f ) %f\n", b->planes[i].Normal()[0], b->planes[i].Normal()[1], b->planes[i].Normal()[2], b->planes[i].Dist() ); + } + fp->WriteFloatString( "\t} ( %f %f %f )", b->bounds[0][0], b->bounds[0][1], b->bounds[0][2] ); + fp->WriteFloatString( " ( %f %f %f ) \"%s\"\n", b->bounds[1][0], b->bounds[1][1], b->bounds[1][2], StringFromContents( b->contents ) ); + } + if ( node->planeType != -1 ) { + WriteBrushes( fp, node->children[0] ); + WriteBrushes( fp, node->children[1] ); + } +} + +/* +================ +idCollisionModelManagerLocal::WriteCollisionModel +================ +*/ +void idCollisionModelManagerLocal::WriteCollisionModel( idFile *fp, cm_model_t *model ) { + int i, polygonMemory, brushMemory; + + fp->WriteFloatString( "collisionModel \"%s\" {\n", model->name.c_str() ); + // vertices + fp->WriteFloatString( "\tvertices { /* numVertices = */ %d\n", model->numVertices ); + for ( i = 0; i < model->numVertices; i++ ) { + fp->WriteFloatString( "\t/* %d */ ( %f %f %f )\n", i, model->vertices[i].p[0], model->vertices[i].p[1], model->vertices[i].p[2] ); + } + fp->WriteFloatString( "\t}\n" ); + // edges + fp->WriteFloatString( "\tedges { /* numEdges = */ %d\n", model->numEdges ); + for ( i = 0; i < model->numEdges; i++ ) { + fp->WriteFloatString( "\t/* %d */ ( %d %d ) %d %d\n", i, model->edges[i].vertexNum[0], model->edges[i].vertexNum[1], model->edges[i].internal, model->edges[i].numUsers ); + } + fp->WriteFloatString( "\t}\n" ); + // nodes + fp->WriteFloatString( "\tnodes {\n" ); + WriteNodes( fp, model->node ); + fp->WriteFloatString( "\t}\n" ); + // polygons + checkCount++; + polygonMemory = CountPolygonMemory( model->node ); + fp->WriteFloatString( "\tpolygons /* polygonMemory = */ %d {\n", polygonMemory ); + checkCount++; + WritePolygons( fp, model->node ); + fp->WriteFloatString( "\t}\n" ); + // brushes + checkCount++; + brushMemory = CountBrushMemory( model->node ); + fp->WriteFloatString( "\tbrushes /* brushMemory = */ %d {\n", brushMemory ); + checkCount++; + WriteBrushes( fp, model->node ); + fp->WriteFloatString( "\t}\n" ); + // closing brace + fp->WriteFloatString( "}\n" ); +} + +/* +================ +idCollisionModelManagerLocal::WriteCollisionModelsToFile +================ +*/ +void idCollisionModelManagerLocal::WriteCollisionModelsToFile( const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC ) { + int i; + idFile *fp; + idStr name; + + name = filename; + name.SetFileExtension( CM_FILE_EXT ); + + common->Printf( "writing %s\n", name.c_str() ); + // _D3XP was saving to fs_cdpath + fp = fileSystem->OpenFileWrite( name, "fs_devpath" ); + if ( !fp ) { + common->Warning( "idCollisionModelManagerLocal::WriteCollisionModelsToFile: Error opening file %s\n", name.c_str() ); + return; + } + + // write file id and version + fp->WriteFloatString( "%s \"%s\"\n\n", CM_FILEID, CM_FILEVERSION ); + // write the map file crc + fp->WriteFloatString( "%u\n\n", mapFileCRC ); + + // write the collision models + for ( i = firstModel; i < lastModel; i++ ) { + WriteCollisionModel( fp, models[ i ] ); + } + + fileSystem->CloseFile( fp ); +} + +/* +================ +idCollisionModelManagerLocal::WriteCollisionModelForMapEntity +================ +*/ +bool idCollisionModelManagerLocal::WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel ) { + idFile *fp; + idStr name; + cm_model_t *model; + + SetupHash(); + model = CollisionModelForMapEntity( mapEnt ); + model->name = filename; + + name = filename; + name.SetFileExtension( CM_FILE_EXT ); + + common->Printf( "writing %s\n", name.c_str() ); + fp = fileSystem->OpenFileWrite( name, "fs_devpath" ); + if ( !fp ) { + common->Printf( "idCollisionModelManagerLocal::WriteCollisionModelForMapEntity: Error opening file %s\n", name.c_str() ); + FreeModel( model ); + return false; + } + + // write file id and version + fp->WriteFloatString( "%s \"%s\"\n\n", CM_FILEID, CM_FILEVERSION ); + // write the map file crc + fp->WriteFloatString( "%u\n\n", 0 ); + + // write the collision model + WriteCollisionModel( fp, model ); + + fileSystem->CloseFile( fp ); + + if ( testTraceModel ) { + idTraceModel trm; + TrmFromModel( model, trm ); + } + + FreeModel( model ); + + return true; +} + + +/* +=============================================================================== + +Loading of collision model file + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::ParseVertices +================ +*/ +void idCollisionModelManagerLocal::ParseVertices( idLexer *src, cm_model_t *model ) { + int i; + + src->ExpectTokenString( "{" ); + model->numVertices = src->ParseInt(); + model->maxVertices = model->numVertices; + model->vertices = (cm_vertex_t *) Mem_Alloc( model->maxVertices * sizeof( cm_vertex_t ) ); + for ( i = 0; i < model->numVertices; i++ ) { + src->Parse1DMatrix( 3, model->vertices[i].p.ToFloatPtr() ); + model->vertices[i].side = 0; + model->vertices[i].sideSet = 0; + model->vertices[i].checkcount = 0; + } + src->ExpectTokenString( "}" ); +} + +/* +================ +idCollisionModelManagerLocal::ParseEdges +================ +*/ +void idCollisionModelManagerLocal::ParseEdges( idLexer *src, cm_model_t *model ) { + int i; + + src->ExpectTokenString( "{" ); + model->numEdges = src->ParseInt(); + model->maxEdges = model->numEdges; + model->edges = (cm_edge_t *) Mem_Alloc( model->maxEdges * sizeof( cm_edge_t ) ); + for ( i = 0; i < model->numEdges; i++ ) { + src->ExpectTokenString( "(" ); + model->edges[i].vertexNum[0] = src->ParseInt(); + model->edges[i].vertexNum[1] = src->ParseInt(); + src->ExpectTokenString( ")" ); + model->edges[i].side = 0; + model->edges[i].sideSet = 0; + model->edges[i].internal = src->ParseInt(); + model->edges[i].numUsers = src->ParseInt(); + model->edges[i].normal = vec3_origin; + model->edges[i].checkcount = 0; + model->numInternalEdges += model->edges[i].internal; + } + src->ExpectTokenString( "}" ); +} + +/* +================ +idCollisionModelManagerLocal::ParseNodes +================ +*/ +cm_node_t *idCollisionModelManagerLocal::ParseNodes( idLexer *src, cm_model_t *model, cm_node_t *parent ) { + cm_node_t *node; + + model->numNodes++; + node = AllocNode( model, model->numNodes < NODE_BLOCK_SIZE_SMALL ? NODE_BLOCK_SIZE_SMALL : NODE_BLOCK_SIZE_LARGE ); + node->brushes = NULL; + node->polygons = NULL; + node->parent = parent; + src->ExpectTokenString( "(" ); + node->planeType = src->ParseInt(); + node->planeDist = src->ParseFloat(); + src->ExpectTokenString( ")" ); + if ( node->planeType != -1 ) { + node->children[0] = ParseNodes( src, model, node ); + node->children[1] = ParseNodes( src, model, node ); + } + return node; +} + +/* +================ +idCollisionModelManagerLocal::ParsePolygons +================ +*/ +void idCollisionModelManagerLocal::ParsePolygons( idLexer *src, cm_model_t *model ) { + cm_polygon_t *p; + int i, numEdges; + idVec3 normal; + idToken token; + + if ( src->CheckTokenType( TT_NUMBER, 0, &token ) ) { + model->polygonBlock = (cm_polygonBlock_t *) Mem_Alloc( sizeof( cm_polygonBlock_t ) + token.GetIntValue() ); + model->polygonBlock->bytesRemaining = token.GetIntValue(); + model->polygonBlock->next = ( (byte *) model->polygonBlock ) + sizeof( cm_polygonBlock_t ); + } + + src->ExpectTokenString( "{" ); + while ( !src->CheckTokenString( "}" ) ) { + // parse polygon + numEdges = src->ParseInt(); + p = AllocPolygon( model, numEdges ); + p->numEdges = numEdges; + src->ExpectTokenString( "(" ); + for ( i = 0; i < p->numEdges; i++ ) { + p->edges[i] = src->ParseInt(); + } + src->ExpectTokenString( ")" ); + src->Parse1DMatrix( 3, normal.ToFloatPtr() ); + p->plane.SetNormal( normal ); + p->plane.SetDist( src->ParseFloat() ); + src->Parse1DMatrix( 3, p->bounds[0].ToFloatPtr() ); + src->Parse1DMatrix( 3, p->bounds[1].ToFloatPtr() ); + src->ExpectTokenType( TT_STRING, 0, &token ); + // get material + p->material = declManager->FindMaterial( token ); + p->contents = p->material->GetContentFlags(); + p->checkcount = 0; + // filter polygon into tree + R_FilterPolygonIntoTree( model, model->node, NULL, p ); + } +} + +/* +================ +idCollisionModelManagerLocal::ParseBrushes +================ +*/ +void idCollisionModelManagerLocal::ParseBrushes( idLexer *src, cm_model_t *model ) { + cm_brush_t *b; + int i, numPlanes; + idVec3 normal; + idToken token; + + if ( src->CheckTokenType( TT_NUMBER, 0, &token ) ) { + model->brushBlock = (cm_brushBlock_t *) Mem_Alloc( sizeof( cm_brushBlock_t ) + token.GetIntValue() ); + model->brushBlock->bytesRemaining = token.GetIntValue(); + model->brushBlock->next = ( (byte *) model->brushBlock ) + sizeof( cm_brushBlock_t ); + } + + src->ExpectTokenString( "{" ); + while ( !src->CheckTokenString( "}" ) ) { + // parse brush + numPlanes = src->ParseInt(); + b = AllocBrush( model, numPlanes ); + b->numPlanes = numPlanes; + src->ExpectTokenString( "{" ); + for ( i = 0; i < b->numPlanes; i++ ) { + src->Parse1DMatrix( 3, normal.ToFloatPtr() ); + b->planes[i].SetNormal( normal ); + b->planes[i].SetDist( src->ParseFloat() ); + } + src->ExpectTokenString( "}" ); + src->Parse1DMatrix( 3, b->bounds[0].ToFloatPtr() ); + src->Parse1DMatrix( 3, b->bounds[1].ToFloatPtr() ); + src->ReadToken( &token ); + if ( token.type == TT_NUMBER ) { + b->contents = token.GetIntValue(); // old .cm files use a single integer + } else { + b->contents = ContentsFromString( token ); + } + b->checkcount = 0; + b->primitiveNum = 0; + // filter brush into tree + R_FilterBrushIntoTree( model, model->node, NULL, b ); + } +} + +/* +================ +idCollisionModelManagerLocal::ParseCollisionModel +================ +*/ +bool idCollisionModelManagerLocal::ParseCollisionModel( idLexer *src ) { + cm_model_t *model; + idToken token; + + if ( numModels >= MAX_SUBMODELS ) { + common->Error( "LoadModel: no free slots" ); + return false; + } + model = AllocModel(); + models[numModels ] = model; + numModels++; + // parse the file + src->ExpectTokenType( TT_STRING, 0, &token ); + model->name = token; + src->ExpectTokenString( "{" ); + while ( !src->CheckTokenString( "}" ) ) { + + src->ReadToken( &token ); + + if ( token == "vertices" ) { + ParseVertices( src, model ); + continue; + } + + if ( token == "edges" ) { + ParseEdges( src, model ); + continue; + } + + if ( token == "nodes" ) { + src->ExpectTokenString( "{" ); + model->node = ParseNodes( src, model, NULL ); + src->ExpectTokenString( "}" ); + continue; + } + + if ( token == "polygons" ) { + ParsePolygons( src, model ); + continue; + } + + if ( token == "brushes" ) { + ParseBrushes( src, model ); + continue; + } + + src->Error( "ParseCollisionModel: bad token \"%s\"", token.c_str() ); + } + // calculate edge normals + checkCount++; + CalculateEdgeNormals( model, model->node ); + // get model bounds from brush and polygon bounds + CM_GetNodeBounds( &model->bounds, model->node ); + // get model contents + model->contents = CM_GetNodeContents( model->node ); + // total memory used by this model + model->usedMemory = model->numVertices * sizeof(cm_vertex_t) + + model->numEdges * sizeof(cm_edge_t) + + model->polygonMemory + + model->brushMemory + + model->numNodes * sizeof(cm_node_t) + + model->numPolygonRefs * sizeof(cm_polygonRef_t) + + model->numBrushRefs * sizeof(cm_brushRef_t); + + return true; +} + +/* +================ +idCollisionModelManagerLocal::LoadCollisionModelFile +================ +*/ +bool idCollisionModelManagerLocal::LoadCollisionModelFile( const char *name, unsigned int mapFileCRC ) { + idStr fileName; + idToken token; + idLexer *src; + unsigned int crc; + + // load it + fileName = name; + fileName.SetFileExtension( CM_FILE_EXT ); + src = new idLexer( fileName ); + src->SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_NODOLLARPRECOMPILE ); + if ( !src->IsLoaded() ) { + delete src; + return false; + } + + if ( !src->ExpectTokenString( CM_FILEID ) ) { + common->Warning( "%s is not an CM file.", fileName.c_str() ); + delete src; + return false; + } + + if ( !src->ReadToken( &token ) || token != CM_FILEVERSION ) { + common->Warning( "%s has version %s instead of %s", fileName.c_str(), token.c_str(), CM_FILEVERSION ); + delete src; + return false; + } + + if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) { + common->Warning( "%s has no map file CRC", fileName.c_str() ); + delete src; + return false; + } + + crc = token.GetUnsignedLongValue(); + if ( mapFileCRC && crc != mapFileCRC ) { + common->Printf( "%s is out of date\n", fileName.c_str() ); + delete src; + return false; + } + + // parse the file + while ( 1 ) { + if ( !src->ReadToken( &token ) ) { + break; + } + + if ( token == "collisionModel" ) { + if ( !ParseCollisionModel( src ) ) { + delete src; + return false; + } + continue; + } + + src->Error( "idCollisionModelManagerLocal::LoadCollisionModelFile: bad token \"%s\"", token.c_str() ); + } + + delete src; + + return true; +} diff --git a/cm/CollisionModel_load.cpp b/cm/CollisionModel_load.cpp new file mode 100644 index 000000000..17e541912 --- /dev/null +++ b/cm/CollisionModel_load.cpp @@ -0,0 +1,3684 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + + It is more important to minimize the number of collision polygons + than it is to minimize the number of edges used for collision + detection (total edges - internal edges). + + Stitching the world tends to minimize the number of edges used + for collision detection (more internal edges). However stitching + also results in more collision polygons which usually makes a + stitched world slower. + + In an average map over 30% of all edges is internal. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + + +idCollisionModelManagerLocal collisionModelManagerLocal; +idCollisionModelManager * collisionModelManager = &collisionModelManagerLocal; + +cm_windingList_t * cm_windingList; +cm_windingList_t * cm_outList; +cm_windingList_t * cm_tmpList; + +idHashIndex * cm_vertexHash; +idHashIndex * cm_edgeHash; + +idBounds cm_modelBounds; +int cm_vertexShift; + + +/* +=============================================================================== + +Proc BSP tree for data pruning + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::ParseProcNodes +================ +*/ +void idCollisionModelManagerLocal::ParseProcNodes( idLexer *src ) { + int i; + + src->ExpectTokenString( "{" ); + + numProcNodes = src->ParseInt(); + if ( numProcNodes < 0 ) { + src->Error( "ParseProcNodes: bad numProcNodes" ); + } + procNodes = (cm_procNode_t *)Mem_ClearedAlloc( numProcNodes * sizeof( cm_procNode_t ) ); + + for ( i = 0; i < numProcNodes; i++ ) { + cm_procNode_t *node; + + node = &procNodes[i]; + + src->Parse1DMatrix( 4, node->plane.ToFloatPtr() ); + node->children[0] = src->ParseInt(); + node->children[1] = src->ParseInt(); + } + + src->ExpectTokenString( "}" ); +} + +/* +================ +idCollisionModelManagerLocal::LoadProcBSP + + FIXME: if the nodes would be at the start of the .proc file it would speed things up considerably +================ +*/ +void idCollisionModelManagerLocal::LoadProcBSP( const char *name ) { + idStr filename; + idToken token; + idLexer *src; + + // load it + filename = name; + filename.SetFileExtension( PROC_FILE_EXT ); + src = new idLexer( filename, LEXFL_NOSTRINGCONCAT | LEXFL_NODOLLARPRECOMPILE ); + if ( !src->IsLoaded() ) { + common->Warning( "idCollisionModelManagerLocal::LoadProcBSP: couldn't load %s", filename.c_str() ); + delete src; + return; + } + + if ( !src->ReadToken( &token ) || token.Icmp( PROC_FILE_ID ) ) { + common->Warning( "idCollisionModelManagerLocal::LoadProcBSP: bad id '%s' instead of '%s'", token.c_str(), PROC_FILE_ID ); + delete src; + return; + } + + // parse the file + while ( 1 ) { + if ( !src->ReadToken( &token ) ) { + break; + } + + if ( token == "model" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "shadowModel" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "interAreaPortals" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "nodes" ) { + ParseProcNodes( src ); + break; + } + + src->Error( "idCollisionModelManagerLocal::LoadProcBSP: bad token \"%s\"", token.c_str() ); + } + + delete src; +} + +/* +=============================================================================== + +Free map + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::Clear +================ +*/ +void idCollisionModelManagerLocal::Clear( void ) { + mapName.Clear(); + mapFileTime = 0; + loaded = 0; + checkCount = 0; + maxModels = 0; + numModels = 0; + models = NULL; + memset( trmPolygons, 0, sizeof( trmPolygons ) ); + trmBrushes[0] = NULL; + trmMaterial = NULL; + numProcNodes = 0; + procNodes = NULL; + getContacts = false; + contacts = NULL; + maxContacts = 0; + numContacts = 0; +} + +/* +================ +idCollisionModelManagerLocal::RemovePolygonReferences_r +================ +*/ +void idCollisionModelManagerLocal::RemovePolygonReferences_r( cm_node_t *node, cm_polygon_t *p ) { + cm_polygonRef_t *pref; + + while( node ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + if ( pref->p == p ) { + pref->p = NULL; + // cannot return here because we can have links down the tree due to polygon merging + //return; + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( p->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( p->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + RemovePolygonReferences_r( node->children[1], p ); + node = node->children[0]; + } + } +} + +/* +================ +idCollisionModelManagerLocal::RemoveBrushReferences_r +================ +*/ +void idCollisionModelManagerLocal::RemoveBrushReferences_r( cm_node_t *node, cm_brush_t *b ) { + cm_brushRef_t *bref; + + while( node ) { + for ( bref = node->brushes; bref; bref = bref->next ) { + if ( bref->b == b ) { + bref->b = NULL; + return; + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( b->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( b->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + RemoveBrushReferences_r( node->children[1], b ); + node = node->children[0]; + } + } +} + +/* +================ +idCollisionModelManagerLocal::FreeNode +================ +*/ +void idCollisionModelManagerLocal::FreeNode( cm_node_t *node ) { + // don't free the node here + // the nodes are allocated in blocks which are freed when the model is freed +} + +/* +================ +idCollisionModelManagerLocal::FreePolygonReference +================ +*/ +void idCollisionModelManagerLocal::FreePolygonReference( cm_polygonRef_t *pref ) { + // don't free the polygon reference here + // the polygon references are allocated in blocks which are freed when the model is freed +} + +/* +================ +idCollisionModelManagerLocal::FreeBrushReference +================ +*/ +void idCollisionModelManagerLocal::FreeBrushReference( cm_brushRef_t *bref ) { + // don't free the brush reference here + // the brush references are allocated in blocks which are freed when the model is freed +} + +/* +================ +idCollisionModelManagerLocal::FreePolygon +================ +*/ +void idCollisionModelManagerLocal::FreePolygon( cm_model_t *model, cm_polygon_t *poly ) { + model->numPolygons--; + model->polygonMemory -= sizeof( cm_polygon_t ) + ( poly->numEdges - 1 ) * sizeof( poly->edges[0] ); + if ( model->polygonBlock == NULL ) { + Mem_Free( poly ); + } +} + +/* +================ +idCollisionModelManagerLocal::FreeBrush +================ +*/ +void idCollisionModelManagerLocal::FreeBrush( cm_model_t *model, cm_brush_t *brush ) { + model->numBrushes--; + model->brushMemory -= sizeof( cm_brush_t ) + ( brush->numPlanes - 1 ) * sizeof( brush->planes[0] ); + if ( model->brushBlock == NULL ) { + Mem_Free( brush ); + } +} + +/* +================ +idCollisionModelManagerLocal::FreeTree_r +================ +*/ +void idCollisionModelManagerLocal::FreeTree_r( cm_model_t *model, cm_node_t *headNode, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + cm_brushRef_t *bref; + cm_brush_t *b; + + // free all polygons at this node + for ( pref = node->polygons; pref; pref = node->polygons ) { + p = pref->p; + if ( p ) { + // remove all other references to this polygon + RemovePolygonReferences_r( headNode, p ); + FreePolygon( model, p ); + } + node->polygons = pref->next; + FreePolygonReference( pref ); + } + // free all brushes at this node + for ( bref = node->brushes; bref; bref = node->brushes ) { + b = bref->b; + if ( b ) { + // remove all other references to this brush + RemoveBrushReferences_r( headNode, b ); + FreeBrush( model, b ); + } + node->brushes = bref->next; + FreeBrushReference( bref ); + } + // recurse down the tree + if ( node->planeType != -1 ) { + FreeTree_r( model, headNode, node->children[0] ); + node->children[0] = NULL; + FreeTree_r( model, headNode, node->children[1] ); + node->children[1] = NULL; + } + FreeNode( node ); +} + +/* +================ +idCollisionModelManagerLocal::FreeModel +================ +*/ +void idCollisionModelManagerLocal::FreeModel( cm_model_t *model ) { + cm_polygonRefBlock_t *polygonRefBlock, *nextPolygonRefBlock; + cm_brushRefBlock_t *brushRefBlock, *nextBrushRefBlock; + cm_nodeBlock_t *nodeBlock, *nextNodeBlock; + + // free the tree structure + if ( model->node ) { + FreeTree_r( model, model->node, model->node ); + } + // free blocks with polygon references + for ( polygonRefBlock = model->polygonRefBlocks; polygonRefBlock; polygonRefBlock = nextPolygonRefBlock ) { + nextPolygonRefBlock = polygonRefBlock->next; + Mem_Free( polygonRefBlock ); + } + // free blocks with brush references + for ( brushRefBlock = model->brushRefBlocks; brushRefBlock; brushRefBlock = nextBrushRefBlock ) { + nextBrushRefBlock = brushRefBlock->next; + Mem_Free( brushRefBlock ); + } + // free blocks with nodes + for ( nodeBlock = model->nodeBlocks; nodeBlock; nodeBlock = nextNodeBlock ) { + nextNodeBlock = nodeBlock->next; + Mem_Free( nodeBlock ); + } + // free block allocated polygons + Mem_Free( model->polygonBlock ); + // free block allocated brushes + Mem_Free( model->brushBlock ); + // free edges + Mem_Free( model->edges ); + // free vertices + Mem_Free( model->vertices ); + // free the model + delete model; +} + +/* +================ +idCollisionModelManagerLocal::FreeMap +================ +*/ +void idCollisionModelManagerLocal::FreeMap( void ) { + int i; + + if ( !loaded ) { + Clear(); + return; + } + + for ( i = 0; i < maxModels; i++ ) { + if ( !models[i] ) { + continue; + } + FreeModel( models[i] ); + } + + FreeTrmModelStructure(); + + Mem_Free( models ); + + Clear(); + + ShutdownHash(); +} + +/* +================ +idCollisionModelManagerLocal::FreeTrmModelStructure +================ +*/ +void idCollisionModelManagerLocal::FreeTrmModelStructure( void ) { + int i; + + assert( models ); + if ( !models[MAX_SUBMODELS] ) { + return; + } + + for ( i = 0; i < MAX_TRACEMODEL_POLYS; i++ ) { + FreePolygon( models[MAX_SUBMODELS], trmPolygons[i]->p ); + } + FreeBrush( models[MAX_SUBMODELS], trmBrushes[0]->b ); + + models[MAX_SUBMODELS]->node->polygons = NULL; + models[MAX_SUBMODELS]->node->brushes = NULL; + FreeModel( models[MAX_SUBMODELS] ); +} + + +/* +=============================================================================== + +Edge normals + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::CalculateEdgeNormals +================ +*/ +#define SHARP_EDGE_DOT -0.7f + +void idCollisionModelManagerLocal::CalculateEdgeNormals( cm_model_t *model, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + cm_edge_t *edge; + float dot, s; + int i, edgeNum; + idVec3 dir; + + while( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // if we checked this polygon already + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = model->edges + abs( edgeNum ); + if ( edge->normal[0] == 0.0f && edge->normal[1] == 0.0f && edge->normal[2] == 0.0f ) { + // if the edge is only used by this polygon + if ( edge->numUsers == 1 ) { + dir = model->vertices[ edge->vertexNum[edgeNum < 0]].p - model->vertices[ edge->vertexNum[edgeNum > 0]].p; + edge->normal = p->plane.Normal().Cross( dir ); + edge->normal.Normalize(); + } else { + // the edge is used by more than one polygon + edge->normal = p->plane.Normal(); + } + } else { + dot = edge->normal * p->plane.Normal(); + // if the two planes make a very sharp edge + if ( dot < SHARP_EDGE_DOT ) { + // max length normal pointing outside both polygons + dir = model->vertices[ edge->vertexNum[edgeNum > 0]].p - model->vertices[ edge->vertexNum[edgeNum < 0]].p; + edge->normal = edge->normal.Cross( dir ) + p->plane.Normal().Cross( -dir ); + edge->normal *= ( 0.5f / ( 0.5f + 0.5f * SHARP_EDGE_DOT ) ) / edge->normal.Length(); + model->numSharpEdges++; + } else { + s = 0.5f / ( 0.5f + 0.5f * dot ); + edge->normal = s * ( edge->normal + p->plane.Normal() ); + } + } + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + CalculateEdgeNormals( model, node->children[1] ); + node = node->children[0]; + } +} + +/* +=============================================================================== + +Trace model to general collision model + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::AllocModel +================ +*/ +cm_model_t *idCollisionModelManagerLocal::AllocModel( void ) { + cm_model_t *model; + + model = new cm_model_t; + model->contents = 0; + model->isConvex = false; + model->maxVertices = 0; + model->numVertices = 0; + model->vertices = NULL; + model->maxEdges = 0; + model->numEdges = 0; + model->edges= NULL; + model->node = NULL; + model->nodeBlocks = NULL; + model->polygonRefBlocks = NULL; + model->brushRefBlocks = NULL; + model->polygonBlock = NULL; + model->brushBlock = NULL; + model->numPolygons = model->polygonMemory = + model->numBrushes = model->brushMemory = + model->numNodes = model->numBrushRefs = + model->numPolygonRefs = model->numInternalEdges = + model->numSharpEdges = model->numRemovedPolys = + model->numMergedPolys = model->usedMemory = 0; + + return model; +} + +/* +================ +idCollisionModelManagerLocal::AllocNode +================ +*/ +cm_node_t *idCollisionModelManagerLocal::AllocNode( cm_model_t *model, int blockSize ) { + int i; + cm_node_t *node; + cm_nodeBlock_t *nodeBlock; + + if ( !model->nodeBlocks || !model->nodeBlocks->nextNode ) { + nodeBlock = (cm_nodeBlock_t *) Mem_ClearedAlloc( sizeof( cm_nodeBlock_t ) + blockSize * sizeof(cm_node_t) ); + nodeBlock->nextNode = (cm_node_t *) ( ( (byte *) nodeBlock ) + sizeof( cm_nodeBlock_t ) ); + nodeBlock->next = model->nodeBlocks; + model->nodeBlocks = nodeBlock; + node = nodeBlock->nextNode; + for ( i = 0; i < blockSize - 1; i++ ) { + node->parent = node + 1; + node = node->parent; + } + node->parent = NULL; + } + + node = model->nodeBlocks->nextNode; + model->nodeBlocks->nextNode = node->parent; + node->parent = NULL; + + return node; +} + +/* +================ +idCollisionModelManagerLocal::AllocPolygonReference +================ +*/ +cm_polygonRef_t *idCollisionModelManagerLocal::AllocPolygonReference( cm_model_t *model, int blockSize ) { + int i; + cm_polygonRef_t *pref; + cm_polygonRefBlock_t *prefBlock; + + if ( !model->polygonRefBlocks || !model->polygonRefBlocks->nextRef ) { + prefBlock = (cm_polygonRefBlock_t *) Mem_Alloc( sizeof( cm_polygonRefBlock_t ) + blockSize * sizeof(cm_polygonRef_t) ); + prefBlock->nextRef = (cm_polygonRef_t *) ( ( (byte *) prefBlock ) + sizeof( cm_polygonRefBlock_t ) ); + prefBlock->next = model->polygonRefBlocks; + model->polygonRefBlocks = prefBlock; + pref = prefBlock->nextRef; + for ( i = 0; i < blockSize - 1; i++ ) { + pref->next = pref + 1; + pref = pref->next; + } + pref->next = NULL; + } + + pref = model->polygonRefBlocks->nextRef; + model->polygonRefBlocks->nextRef = pref->next; + + return pref; +} + +/* +================ +idCollisionModelManagerLocal::AllocBrushReference +================ +*/ +cm_brushRef_t *idCollisionModelManagerLocal::AllocBrushReference( cm_model_t *model, int blockSize ) { + int i; + cm_brushRef_t *bref; + cm_brushRefBlock_t *brefBlock; + + if ( !model->brushRefBlocks || !model->brushRefBlocks->nextRef ) { + brefBlock = (cm_brushRefBlock_t *) Mem_Alloc( sizeof(cm_brushRefBlock_t) + blockSize * sizeof(cm_brushRef_t) ); + brefBlock->nextRef = (cm_brushRef_t *) ( ( (byte *) brefBlock ) + sizeof(cm_brushRefBlock_t) ); + brefBlock->next = model->brushRefBlocks; + model->brushRefBlocks = brefBlock; + bref = brefBlock->nextRef; + for ( i = 0; i < blockSize - 1; i++ ) { + bref->next = bref + 1; + bref = bref->next; + } + bref->next = NULL; + } + + bref = model->brushRefBlocks->nextRef; + model->brushRefBlocks->nextRef = bref->next; + + return bref; +} + +/* +================ +idCollisionModelManagerLocal::AllocPolygon +================ +*/ +cm_polygon_t *idCollisionModelManagerLocal::AllocPolygon( cm_model_t *model, int numEdges ) { + cm_polygon_t *poly; + int size; + + size = sizeof( cm_polygon_t ) + ( numEdges - 1 ) * sizeof( poly->edges[0] ); + model->numPolygons++; + model->polygonMemory += size; + if ( model->polygonBlock && model->polygonBlock->bytesRemaining >= size ) { + poly = (cm_polygon_t *) model->polygonBlock->next; + model->polygonBlock->next += size; + model->polygonBlock->bytesRemaining -= size; + } else { + poly = (cm_polygon_t *) Mem_Alloc( size ); + } + return poly; +} + +/* +================ +idCollisionModelManagerLocal::AllocBrush +================ +*/ +cm_brush_t *idCollisionModelManagerLocal::AllocBrush( cm_model_t *model, int numPlanes ) { + cm_brush_t *brush; + int size; + + size = sizeof( cm_brush_t ) + ( numPlanes - 1 ) * sizeof( brush->planes[0] ); + model->numBrushes++; + model->brushMemory += size; + if ( model->brushBlock && model->brushBlock->bytesRemaining >= size ) { + brush = (cm_brush_t *) model->brushBlock->next; + model->brushBlock->next += size; + model->brushBlock->bytesRemaining -= size; + } else { + brush = (cm_brush_t *) Mem_Alloc( size ); + } + return brush; +} + +/* +================ +idCollisionModelManagerLocal::AddPolygonToNode +================ +*/ +void idCollisionModelManagerLocal::AddPolygonToNode( cm_model_t *model, cm_node_t *node, cm_polygon_t *p ) { + cm_polygonRef_t *pref; + + pref = AllocPolygonReference( model, model->numPolygonRefs < REFERENCE_BLOCK_SIZE_SMALL ? REFERENCE_BLOCK_SIZE_SMALL : REFERENCE_BLOCK_SIZE_LARGE ); + pref->p = p; + pref->next = node->polygons; + node->polygons = pref; + model->numPolygonRefs++; +} + +/* +================ +idCollisionModelManagerLocal::AddBrushToNode +================ +*/ +void idCollisionModelManagerLocal::AddBrushToNode( cm_model_t *model, cm_node_t *node, cm_brush_t *b ) { + cm_brushRef_t *bref; + + bref = AllocBrushReference( model, model->numBrushRefs < REFERENCE_BLOCK_SIZE_SMALL ? REFERENCE_BLOCK_SIZE_SMALL : REFERENCE_BLOCK_SIZE_LARGE ); + bref->b = b; + bref->next = node->brushes; + node->brushes = bref; + model->numBrushRefs++; +} + +/* +================ +idCollisionModelManagerLocal::SetupTrmModelStructure +================ +*/ +void idCollisionModelManagerLocal::SetupTrmModelStructure( void ) { + int i; + cm_node_t *node; + cm_model_t *model; + + // setup model + model = AllocModel(); + + assert( models ); + models[MAX_SUBMODELS] = model; + // create node to hold the collision data + node = (cm_node_t *) AllocNode( model, 1 ); + node->planeType = -1; + model->node = node; + // allocate vertex and edge arrays + model->numVertices = 0; + model->maxVertices = MAX_TRACEMODEL_VERTS; + model->vertices = (cm_vertex_t *) Mem_ClearedAlloc( model->maxVertices * sizeof(cm_vertex_t) ); + model->numEdges = 0; + model->maxEdges = MAX_TRACEMODEL_EDGES+1; + model->edges = (cm_edge_t *) Mem_ClearedAlloc( model->maxEdges * sizeof(cm_edge_t) ); + // create a material for the trace model polygons + trmMaterial = declManager->FindMaterial( "_tracemodel", false ); + if ( !trmMaterial ) { + common->FatalError( "_tracemodel material not found" ); + } + + // allocate polygons + for ( i = 0; i < MAX_TRACEMODEL_POLYS; i++ ) { + trmPolygons[i] = AllocPolygonReference( model, MAX_TRACEMODEL_POLYS ); + trmPolygons[i]->p = AllocPolygon( model, MAX_TRACEMODEL_POLYEDGES ); + trmPolygons[i]->p->bounds.Clear(); + trmPolygons[i]->p->plane.Zero(); + trmPolygons[i]->p->checkcount = 0; + trmPolygons[i]->p->contents = -1; // all contents + trmPolygons[i]->p->material = trmMaterial; + trmPolygons[i]->p->numEdges = 0; + } + // allocate brush for position test + trmBrushes[0] = AllocBrushReference( model, 1 ); + trmBrushes[0]->b = AllocBrush( model, MAX_TRACEMODEL_POLYS ); + trmBrushes[0]->b->primitiveNum = 0; + trmBrushes[0]->b->bounds.Clear(); + trmBrushes[0]->b->checkcount = 0; + trmBrushes[0]->b->contents = -1; // all contents + trmBrushes[0]->b->numPlanes = 0; +} + +/* +================ +idCollisionModelManagerLocal::SetupTrmModel + +Trace models (item boxes, etc) are converted to collision models on the fly, using the last model slot +as a reusable temporary buffer +================ +*/ +cmHandle_t idCollisionModelManagerLocal::SetupTrmModel( const idTraceModel &trm, const idMaterial *material ) { + int i, j; + cm_vertex_t *vertex; + cm_edge_t *edge; + cm_polygon_t *poly; + cm_model_t *model; + const traceModelVert_t *trmVert; + const traceModelEdge_t *trmEdge; + const traceModelPoly_t *trmPoly; + + assert( models ); + + if ( material == NULL ) { + material = trmMaterial; + } + + model = models[MAX_SUBMODELS]; + model->node->brushes = NULL; + model->node->polygons = NULL; + // if not a valid trace model + if ( trm.type == TRM_INVALID || !trm.numPolys ) { + return TRACE_MODEL_HANDLE; + } + // vertices + model->numVertices = trm.numVerts; + vertex = model->vertices; + trmVert = trm.verts; + for ( i = 0; i < trm.numVerts; i++, vertex++, trmVert++ ) { + vertex->p = *trmVert; + vertex->sideSet = 0; + } + // edges + model->numEdges = trm.numEdges; + edge = model->edges + 1; + trmEdge = trm.edges + 1; + for ( i = 0; i < trm.numEdges; i++, edge++, trmEdge++ ) { + edge->vertexNum[0] = trmEdge->v[0]; + edge->vertexNum[1] = trmEdge->v[1]; + edge->normal = trmEdge->normal; + edge->internal = false; + edge->sideSet = 0; + } + // polygons + model->numPolygons = trm.numPolys; + trmPoly = trm.polys; + for ( i = 0; i < trm.numPolys; i++, trmPoly++ ) { + poly = trmPolygons[i]->p; + poly->numEdges = trmPoly->numEdges; + for ( j = 0; j < trmPoly->numEdges; j++ ) { + poly->edges[j] = trmPoly->edges[j]; + } + poly->plane.SetNormal( trmPoly->normal ); + poly->plane.SetDist( trmPoly->dist ); + poly->bounds = trmPoly->bounds; + poly->material = material; + // link polygon at node + trmPolygons[i]->next = model->node->polygons; + model->node->polygons = trmPolygons[i]; + } + // if the trace model is convex + if ( trm.isConvex ) { + // setup brush for position test + trmBrushes[0]->b->numPlanes = trm.numPolys; + for ( i = 0; i < trm.numPolys; i++ ) { + trmBrushes[0]->b->planes[i] = trmPolygons[i]->p->plane; + } + trmBrushes[0]->b->bounds = trm.bounds; + // link brush at node + trmBrushes[0]->next = model->node->brushes; + model->node->brushes = trmBrushes[0]; + } + // model bounds + model->bounds = trm.bounds; + // convex + model->isConvex = trm.isConvex; + + return TRACE_MODEL_HANDLE; +} + +/* +=============================================================================== + +Optimisation, removal of polygons contained within brushes or solid + +=============================================================================== +*/ + +/* +============ +idCollisionModelManagerLocal::R_ChoppedAwayByProcBSP +============ +*/ +int idCollisionModelManagerLocal::R_ChoppedAwayByProcBSP( int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius ) { + int res; + idFixedWinding back; + cm_procNode_t *node; + float dist; + + do { + node = procNodes + nodeNum; + dist = node->plane.Normal() * origin + node->plane[3]; + if ( dist > radius ) { + res = SIDE_FRONT; + } + else if ( dist < -radius ) { + res = SIDE_BACK; + } + else { + res = w->Split( &back, node->plane, CHOP_EPSILON ); + } + if ( res == SIDE_FRONT ) { + nodeNum = node->children[0]; + } + else if ( res == SIDE_BACK ) { + nodeNum = node->children[1]; + } + else if ( res == SIDE_ON ) { + // continue with the side the winding faces + if ( node->plane.Normal() * normal > 0.0f ) { + nodeNum = node->children[0]; + } + else { + nodeNum = node->children[1]; + } + } + else { + // if either node is not solid + if ( node->children[0] < 0 || node->children[1] < 0 ) { + return false; + } + // only recurse if the node is not solid + if ( node->children[1] > 0 ) { + if ( !R_ChoppedAwayByProcBSP( node->children[1], &back, normal, origin, radius ) ) { + return false; + } + } + nodeNum = node->children[0]; + } + } while ( nodeNum > 0 ); + if ( nodeNum < 0 ) { + return false; + } + return true; +} + +/* +============ +idCollisionModelManagerLocal::ChoppedAwayByProcBSP +============ +*/ +int idCollisionModelManagerLocal::ChoppedAwayByProcBSP( const idFixedWinding &w, const idPlane &plane, int contents ) { + idFixedWinding neww; + idBounds bounds; + float radius; + idVec3 origin; + + // if the .proc file has no BSP tree + if ( procNodes == NULL ) { + return false; + } + // don't chop if the polygon is not solid + if ( !(contents & CONTENTS_SOLID) ) { + return false; + } + // make a local copy of the winding + neww = w; + neww.GetBounds( bounds ); + origin = (bounds[1] - bounds[0]) * 0.5f; + radius = origin.Length() + CHOP_EPSILON; + origin = bounds[0] + origin; + // + return R_ChoppedAwayByProcBSP( 0, &neww, plane.Normal(), origin, radius ); +} + +/* +============= +idCollisionModelManagerLocal::ChopWindingWithBrush + + returns the least number of winding fragments outside the brush +============= +*/ +void idCollisionModelManagerLocal::ChopWindingListWithBrush( cm_windingList_t *list, cm_brush_t *b ) { + int i, k, res, startPlane, planeNum, bestNumWindings; + idFixedWinding back, front; + idPlane plane; + bool chopped; + int sidedness[MAX_POINTS_ON_WINDING]; + float dist; + + if ( b->numPlanes > MAX_POINTS_ON_WINDING ) { + return; + } + + // get sidedness for the list of windings + for ( i = 0; i < b->numPlanes; i++ ) { + plane = -b->planes[i]; + + dist = plane.Distance( list->origin ); + if ( dist > list->radius ) { + sidedness[i] = SIDE_FRONT; + } + else if ( dist < -list->radius ) { + sidedness[i] = SIDE_BACK; + } + else { + sidedness[i] = list->bounds.PlaneSide( plane ); + if ( sidedness[i] == PLANESIDE_FRONT ) { + sidedness[i] = SIDE_FRONT; + } + else if ( sidedness[i] == PLANESIDE_BACK ) { + sidedness[i] = SIDE_BACK; + } + else { + sidedness[i] = SIDE_CROSS; + } + } + } + + cm_outList->numWindings = 0; + for ( k = 0; k < list->numWindings; k++ ) { + // + startPlane = 0; + bestNumWindings = 1 + b->numPlanes; + chopped = false; + do { + front = list->w[k]; + cm_tmpList->numWindings = 0; + for ( planeNum = startPlane, i = 0; i < b->numPlanes; i++, planeNum++ ) { + + if ( planeNum >= b->numPlanes ) { + planeNum = 0; + } + + res = sidedness[planeNum]; + + if ( res == SIDE_CROSS ) { + plane = -b->planes[planeNum]; + res = front.Split( &back, plane, CHOP_EPSILON ); + } + + // NOTE: disabling this can create gaps at places where Z-fighting occurs + // Z-fighting should not occur but what if there is a decal brush side + // with exactly the same size as another brush side ? + // only leave windings on a brush if the winding plane and brush side plane face the same direction + if ( res == SIDE_ON && list->primitiveNum >= 0 && (list->normal * b->planes[planeNum].Normal()) > 0 ) { + // return because all windings in the list will be on this brush side plane + return; + } + + if ( res == SIDE_BACK ) { + if ( cm_outList->numWindings >= MAX_WINDING_LIST ) { + common->Warning( "idCollisionModelManagerLocal::ChopWindingWithBrush: primitive %d more than %d windings", list->primitiveNum, MAX_WINDING_LIST ); + return; + } + // winding and brush didn't intersect, store the original winding + cm_outList->w[cm_outList->numWindings] = list->w[k]; + cm_outList->numWindings++; + chopped = false; + break; + } + + if ( res == SIDE_CROSS ) { + if ( cm_tmpList->numWindings >= MAX_WINDING_LIST ) { + common->Warning( "idCollisionModelManagerLocal::ChopWindingWithBrush: primitive %d more than %d windings", list->primitiveNum, MAX_WINDING_LIST ); + return; + } + // store the front winding in the temporary list + cm_tmpList->w[cm_tmpList->numWindings] = back; + cm_tmpList->numWindings++; + chopped = true; + } + + // if already found a start plane which generates less fragments + if ( cm_tmpList->numWindings >= bestNumWindings ) { + break; + } + } + + // find the best start plane to get the least number of fragments outside the brush + if ( cm_tmpList->numWindings < bestNumWindings ) { + bestNumWindings = cm_tmpList->numWindings; + // store windings from temporary list in the out list + for ( i = 0; i < cm_tmpList->numWindings; i++ ) { + if ( cm_outList->numWindings + i >= MAX_WINDING_LIST ) { + common->Warning( "idCollisionModelManagerLocal::ChopWindingWithBrush: primitive %d more than %d windings", list->primitiveNum, MAX_WINDING_LIST ); + return; + } + cm_outList->w[cm_outList->numWindings+i] = cm_tmpList->w[i]; + } + // if only one winding left then we can't do any better + if ( bestNumWindings == 1 ) { + break; + } + } + + // try the next start plane + startPlane++; + + } while ( chopped && startPlane < b->numPlanes ); + // + if ( chopped ) { + cm_outList->numWindings += bestNumWindings; + } + } + for ( k = 0; k < cm_outList->numWindings; k++ ) { + list->w[k] = cm_outList->w[k]; + } + list->numWindings = cm_outList->numWindings; +} + +/* +============ +idCollisionModelManagerLocal::R_ChopWindingListWithTreeBrushes +============ +*/ +void idCollisionModelManagerLocal::R_ChopWindingListWithTreeBrushes( cm_windingList_t *list, cm_node_t *node ) { + int i; + cm_brushRef_t *bref; + cm_brush_t *b; + + while( 1 ) { + for ( bref = node->brushes; bref; bref = bref->next ) { + b = bref->b; + // if we checked this brush already + if ( b->checkcount == checkCount ) { + continue; + } + b->checkcount = checkCount; + // if the windings in the list originate from this brush + if ( b->primitiveNum == list->primitiveNum ) { + continue; + } + // if brush has a different contents + if ( b->contents != list->contents ) { + continue; + } + // brush bounds and winding list bounds should overlap + for ( i = 0; i < 3; i++ ) { + if ( list->bounds[0][i] > b->bounds[1][i] ) { + break; + } + if ( list->bounds[1][i] < b->bounds[0][i] ) { + break; + } + } + if ( i < 3 ) { + continue; + } + // chop windings in the list with brush + ChopWindingListWithBrush( list, b ); + // if all windings are chopped away we're done + if ( !list->numWindings ) { + return; + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( list->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( list->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + R_ChopWindingListWithTreeBrushes( list, node->children[1] ); + if ( !list->numWindings ) { + return; + } + node = node->children[0]; + } + } +} + +/* +============ +idCollisionModelManagerLocal::WindingOutsideBrushes + + Returns one winding which is not fully contained in brushes. + We always favor less polygons over a stitched world. + If the winding is partly contained and the contained pieces can be chopped off + without creating multiple winding fragments then the chopped winding is returned. +============ +*/ +idFixedWinding *idCollisionModelManagerLocal::WindingOutsideBrushes( idFixedWinding *w, const idPlane &plane, int contents, int primitiveNum, cm_node_t *headNode ) { + int i, windingLeft; + + cm_windingList->bounds.Clear(); + for ( i = 0; i < w->GetNumPoints(); i++ ) { + cm_windingList->bounds.AddPoint( (*w)[i].ToVec3() ); + } + + cm_windingList->origin = (cm_windingList->bounds[1] - cm_windingList->bounds[0]) * 0.5; + cm_windingList->radius = cm_windingList->origin.Length() + CHOP_EPSILON; + cm_windingList->origin = cm_windingList->bounds[0] + cm_windingList->origin; + cm_windingList->bounds[0] -= idVec3( CHOP_EPSILON, CHOP_EPSILON, CHOP_EPSILON ); + cm_windingList->bounds[1] += idVec3( CHOP_EPSILON, CHOP_EPSILON, CHOP_EPSILON ); + + cm_windingList->w[0] = *w; + cm_windingList->numWindings = 1; + cm_windingList->normal = plane.Normal(); + cm_windingList->contents = contents; + cm_windingList->primitiveNum = primitiveNum; + // + checkCount++; + R_ChopWindingListWithTreeBrushes( cm_windingList, headNode ); + // + if ( !cm_windingList->numWindings ) { + return NULL; + } + if ( cm_windingList->numWindings == 1 ) { + return &cm_windingList->w[0]; + } + // if not the world model + if ( numModels != 0 ) { + return w; + } + // check if winding fragments would be chopped away by the proc BSP tree + windingLeft = -1; + for ( i = 0; i < cm_windingList->numWindings; i++ ) { + if ( !ChoppedAwayByProcBSP( cm_windingList->w[i], plane, contents ) ) { + if ( windingLeft >= 0 ) { + return w; + } + windingLeft = i; + } + } + if ( windingLeft >= 0 ) { + return &cm_windingList->w[windingLeft]; + } + return NULL; +} + +/* +=============================================================================== + +Merging polygons + +=============================================================================== +*/ + +/* +============= +idCollisionModelManagerLocal::ReplacePolygons + + does not allow for a node to have multiple references to the same polygon +============= +*/ +void idCollisionModelManagerLocal::ReplacePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *p1, cm_polygon_t *p2, cm_polygon_t *newp ) { + cm_polygonRef_t *pref, *lastpref, *nextpref; + cm_polygon_t *p; + bool linked; + + while( 1 ) { + linked = false; + lastpref = NULL; + for ( pref = node->polygons; pref; pref = nextpref ) { + nextpref = pref->next; + // + p = pref->p; + // if this polygon reference should change + if ( p == p1 || p == p2 ) { + // if the new polygon is already linked at this node + if ( linked ) { + if ( lastpref ) { + lastpref->next = nextpref; + } + else { + node->polygons = nextpref; + } + FreePolygonReference( pref ); + model->numPolygonRefs--; + } + else { + pref->p = newp; + linked = true; + lastpref = pref; + } + } + else { + lastpref = pref; + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( p1->bounds[0][node->planeType] > node->planeDist && p2->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( p1->bounds[1][node->planeType] < node->planeDist && p2->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + ReplacePolygons( model, node->children[1], p1, p2, newp ); + node = node->children[0]; + } + } +} + +/* +============= +idCollisionModelManagerLocal::TryMergePolygons +============= +*/ +#define CONTINUOUS_EPSILON 0.005f +#define NORMAL_EPSILON 0.01f + +cm_polygon_t *idCollisionModelManagerLocal::TryMergePolygons( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ) { + int i, j, nexti, prevj; + int p1BeforeShare, p1AfterShare, p2BeforeShare, p2AfterShare; + int newEdges[CM_MAX_POLYGON_EDGES], newNumEdges; + int edgeNum, edgeNum1, edgeNum2, newEdgeNum1, newEdgeNum2; + cm_edge_t *edge; + cm_polygon_t *newp; + idVec3 delta, normal; + float dot; + bool keep1, keep2; + + if ( p1->material != p2->material ) { + return NULL; + } + if ( idMath::Fabs( p1->plane.Dist() - p2->plane.Dist() ) > NORMAL_EPSILON ) { + return NULL; + } + for ( i = 0; i < 3; i++ ) { + if ( idMath::Fabs( p1->plane.Normal()[i] - p2->plane.Normal()[i] ) > NORMAL_EPSILON ) { + return NULL; + } + if ( p1->bounds[0][i] > p2->bounds[1][i] ) { + return NULL; + } + if ( p1->bounds[1][i] < p2->bounds[0][i] ) { + return NULL; + } + } + // this allows for merging polygons with multiple shared edges + // polygons with multiple shared edges probably never occur tho ;) + p1BeforeShare = p1AfterShare = p2BeforeShare = p2AfterShare = -1; + for ( i = 0; i < p1->numEdges; i++ ) { + nexti = (i+1)%p1->numEdges; + for ( j = 0; j < p2->numEdges; j++ ) { + prevj = (j+p2->numEdges-1)%p2->numEdges; + // + if ( abs(p1->edges[i]) != abs(p2->edges[j]) ) { + // if the next edge of p1 and the previous edge of p2 are the same + if ( abs(p1->edges[nexti]) == abs(p2->edges[prevj]) ) { + // if both polygons don't use the edge in the same direction + if ( p1->edges[nexti] != p2->edges[prevj] ) { + p1BeforeShare = i; + p2AfterShare = j; + } + break; + } + } + // if both polygons don't use the edge in the same direction + else if ( p1->edges[i] != p2->edges[j] ) { + // if the next edge of p1 and the previous edge of p2 are not the same + if ( abs(p1->edges[nexti]) != abs(p2->edges[prevj]) ) { + p1AfterShare = nexti; + p2BeforeShare = prevj; + break; + } + } + } + } + if ( p1BeforeShare < 0 || p1AfterShare < 0 || p2BeforeShare < 0 || p2AfterShare < 0 ) { + return NULL; + } + + // check if the new polygon would still be convex + edgeNum = p1->edges[p1BeforeShare]; + edge = model->edges + abs(edgeNum); + delta = model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p - + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + normal = p1->plane.Normal().Cross( delta ); + normal.Normalize(); + + edgeNum = p2->edges[p2AfterShare]; + edge = model->edges + abs(edgeNum); + delta = model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p - + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + + dot = delta * normal; + if (dot < -CONTINUOUS_EPSILON) + return NULL; // not a convex polygon + keep1 = (bool)(dot > CONTINUOUS_EPSILON); + + edgeNum = p2->edges[p2BeforeShare]; + edge = model->edges + abs(edgeNum); + delta = model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p - + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + normal = p1->plane.Normal().Cross( delta ); + normal.Normalize(); + + edgeNum = p1->edges[p1AfterShare]; + edge = model->edges + abs(edgeNum); + delta = model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p - + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + + dot = delta * normal; + if (dot < -CONTINUOUS_EPSILON) + return NULL; // not a convex polygon + keep2 = (bool)(dot > CONTINUOUS_EPSILON); + + newEdgeNum1 = newEdgeNum2 = 0; + // get new edges if we need to replace colinear ones + if ( !keep1 ) { + edgeNum1 = p1->edges[p1BeforeShare]; + edgeNum2 = p2->edges[p2AfterShare]; + GetEdge( model, model->vertices[model->edges[abs(edgeNum1)].vertexNum[INTSIGNBITSET(edgeNum1)]].p, + model->vertices[model->edges[abs(edgeNum2)].vertexNum[INTSIGNBITNOTSET(edgeNum2)]].p, + &newEdgeNum1, -1 ); + if ( newEdgeNum1 == 0 ) { + keep1 = true; + } + } + if ( !keep2 ) { + edgeNum1 = p2->edges[p2BeforeShare]; + edgeNum2 = p1->edges[p1AfterShare]; + GetEdge( model, model->vertices[model->edges[abs(edgeNum1)].vertexNum[INTSIGNBITSET(edgeNum1)]].p, + model->vertices[model->edges[abs(edgeNum2)].vertexNum[INTSIGNBITNOTSET(edgeNum2)]].p, + &newEdgeNum2, -1 ); + if ( newEdgeNum2 == 0 ) { + keep2 = true; + } + } + // set edges for new polygon + newNumEdges = 0; + if ( !keep2 ) { + newEdges[newNumEdges++] = newEdgeNum2; + } + if ( p1AfterShare < p1BeforeShare ) { + for ( i = p1AfterShare + (!keep2); i <= p1BeforeShare - (!keep1); i++ ) { + newEdges[newNumEdges++] = p1->edges[i]; + } + } + else { + for ( i = p1AfterShare + (!keep2); i < p1->numEdges; i++ ) { + newEdges[newNumEdges++] = p1->edges[i]; + } + for ( i = 0; i <= p1BeforeShare - (!keep1); i++ ) { + newEdges[newNumEdges++] = p1->edges[i]; + } + } + if ( !keep1 ) { + newEdges[newNumEdges++] = newEdgeNum1; + } + if ( p2AfterShare < p2BeforeShare ) { + for ( i = p2AfterShare + (!keep1); i <= p2BeforeShare - (!keep2); i++ ) { + newEdges[newNumEdges++] = p2->edges[i]; + } + } + else { + for ( i = p2AfterShare + (!keep1); i < p2->numEdges; i++ ) { + newEdges[newNumEdges++] = p2->edges[i]; + } + for ( i = 0; i <= p2BeforeShare - (!keep2); i++ ) { + newEdges[newNumEdges++] = p2->edges[i]; + } + } + + newp = AllocPolygon( model, newNumEdges ); + memcpy( newp, p1, sizeof(cm_polygon_t) ); + memcpy( newp->edges, newEdges, newNumEdges * sizeof(int) ); + newp->numEdges = newNumEdges; + newp->checkcount = 0; + // increase usage count for the edges of this polygon + for ( i = 0; i < newp->numEdges; i++ ) { + if ( !keep1 && newp->edges[i] == newEdgeNum1 ) { + continue; + } + if ( !keep2 && newp->edges[i] == newEdgeNum2 ) { + continue; + } + model->edges[abs(newp->edges[i])].numUsers++; + } + // create new bounds from the merged polygons + newp->bounds = p1->bounds + p2->bounds; + + return newp; +} + +/* +============= +idCollisionModelManagerLocal::MergePolygonWithTreePolygons +============= +*/ +bool idCollisionModelManagerLocal::MergePolygonWithTreePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ) { + int i; + cm_polygonRef_t *pref; + cm_polygon_t *p, *newp; + + while( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // + if ( p == polygon ) { + continue; + } + // + newp = TryMergePolygons( model, polygon, p ); + // if polygons were merged + if ( newp ) { + model->numMergedPolys++; + // replace links to the merged polygons with links to the new polygon + ReplacePolygons( model, model->node, polygon, p, newp ); + // decrease usage count for edges of both merged polygons + for ( i = 0; i < polygon->numEdges; i++ ) { + model->edges[abs(polygon->edges[i])].numUsers--; + } + for ( i = 0; i < p->numEdges; i++ ) { + model->edges[abs(p->edges[i])].numUsers--; + } + // free merged polygons + FreePolygon( model, polygon ); + FreePolygon( model, p ); + + return true; + } + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( polygon->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( polygon->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + if ( MergePolygonWithTreePolygons( model, node->children[1], polygon ) ) { + return true; + } + node = node->children[0]; + } + } + return false; +} + +/* +============= +idCollisionModelManagerLocal::MergeTreePolygons + + try to merge any two polygons with the same surface flags and the same contents +============= +*/ +void idCollisionModelManagerLocal::MergeTreePolygons( cm_model_t *model, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + bool merge; + + while( 1 ) { + do { + merge = false; + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // if we checked this polygon already + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + // try to merge this polygon with other polygons in the tree + if ( MergePolygonWithTreePolygons( model, model->node, p ) ) { + merge = true; + break; + } + } + } while (merge); + // if leaf node + if ( node->planeType == -1 ) { + break; + } + MergeTreePolygons( model, node->children[1] ); + node = node->children[0]; + } +} + +/* +=============================================================================== + +Find internal edges + +=============================================================================== +*/ + +/* + + if (two polygons have the same contents) + if (the normals of the two polygon planes face towards each other) + if (an edge is shared between the polygons) + if (the edge is not shared in the same direction) + then this is an internal edge + else + if (this edge is on the plane of the other polygon) + if (this edge if fully inside the winding of the other polygon) + then this edge is an internal edge + +*/ + +/* +============= +idCollisionModelManagerLocal::PointInsidePolygon +============= +*/ +bool idCollisionModelManagerLocal::PointInsidePolygon( cm_model_t *model, cm_polygon_t *p, idVec3 &v ) { + int i, edgeNum; + idVec3 *v1, *v2, dir1, dir2, vec; + cm_edge_t *edge; + + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = model->edges + abs(edgeNum); + // + v1 = &model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + v2 = &model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p; + dir1 = (*v2) - (*v1); + vec = v - (*v1); + dir2 = dir1.Cross( p->plane.Normal() ); + if ( vec * dir2 > VERTEX_EPSILON ) { + return false; + } + } + return true; +} + +/* +============= +idCollisionModelManagerLocal::FindInternalEdgesOnPolygon +============= +*/ +void idCollisionModelManagerLocal::FindInternalEdgesOnPolygon( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ) { + int i, j, k, edgeNum; + cm_edge_t *edge; + idVec3 *v1, *v2, dir1, dir2; + float d; + + // bounds of polygons should overlap or touch + for ( i = 0; i < 3; i++ ) { + if ( p1->bounds[0][i] > p2->bounds[1][i] ) { + return; + } + if ( p1->bounds[1][i] < p2->bounds[0][i] ) { + return; + } + } + // + // FIXME: doubled geometry causes problems + // + for ( i = 0; i < p1->numEdges; i++ ) { + edgeNum = p1->edges[i]; + edge = model->edges + abs(edgeNum); + // if already an internal edge + if ( edge->internal ) { + continue; + } + // + v1 = &model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + v2 = &model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p; + // if either of the two vertices is outside the bounds of the other polygon + for ( k = 0; k < 3; k++ ) { + d = p2->bounds[1][k] + VERTEX_EPSILON; + if ( (*v1)[k] > d || (*v2)[k] > d ) { + break; + } + d = p2->bounds[0][k] - VERTEX_EPSILON; + if ( (*v1)[k] < d || (*v2)[k] < d ) { + break; + } + } + if ( k < 3 ) { + continue; + } + // + k = abs(edgeNum); + for ( j = 0; j < p2->numEdges; j++ ) { + if ( k == abs(p2->edges[j]) ) { + break; + } + } + // if the edge is shared between the two polygons + if ( j < p2->numEdges ) { + // if the edge is used by more than 2 polygons + if ( edge->numUsers > 2 ) { + // could still be internal but we'd have to test all polygons using the edge + continue; + } + // if the edge goes in the same direction for both polygons + if ( edgeNum == p2->edges[j] ) { + // the polygons can lay ontop of each other or one can obscure the other + continue; + } + } + // the edge was not shared + else { + // both vertices should be on the plane of the other polygon + d = p2->plane.Distance( *v1 ); + if ( idMath::Fabs(d) > VERTEX_EPSILON ) { + continue; + } + d = p2->plane.Distance( *v2 ); + if ( idMath::Fabs(d) > VERTEX_EPSILON ) { + continue; + } + } + // the two polygon plane normals should face towards each other + dir1 = (*v2) - (*v1); + dir2 = p1->plane.Normal().Cross( dir1 ); + if ( p2->plane.Normal() * dir2 < 0 ) { + //continue; + break; + } + // if the edge was not shared + if ( j >= p2->numEdges ) { + // both vertices of the edge should be inside the winding of the other polygon + if ( !PointInsidePolygon( model, p2, *v1 ) ) { + continue; + } + if ( !PointInsidePolygon( model, p2, *v2 ) ) { + continue; + } + } + // we got another internal edge + edge->internal = true; + model->numInternalEdges++; + } +} + +/* +============= +idCollisionModelManagerLocal::FindInternalPolygonEdges +============= +*/ +void idCollisionModelManagerLocal::FindInternalPolygonEdges( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + + if ( polygon->material->GetCullType() == CT_TWO_SIDED || polygon->material->ShouldCreateBackSides() ) { + return; + } + + while( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // + // FIXME: use some sort of additional checkcount because currently + // polygons can be checked multiple times + // + // if the polygons don't have the same contents + if ( p->contents != polygon->contents ) { + continue; + } + if ( p == polygon ) { + continue; + } + FindInternalEdgesOnPolygon( model, polygon, p ); + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + if ( polygon->bounds[0][node->planeType] > node->planeDist ) { + node = node->children[0]; + } + else if ( polygon->bounds[1][node->planeType] < node->planeDist ) { + node = node->children[1]; + } + else { + FindInternalPolygonEdges( model, node->children[1], polygon ); + node = node->children[0]; + } + } +} + +/* +============= +idCollisionModelManagerLocal::FindContainedEdges +============= +*/ +void idCollisionModelManagerLocal::FindContainedEdges( cm_model_t *model, cm_polygon_t *p ) { + int i, edgeNum; + cm_edge_t *edge; + idFixedWinding w; + + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + edge = model->edges + abs(edgeNum); + if ( edge->internal ) { + continue; + } + w.Clear(); + w += model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p; + w += model->vertices[edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]].p; + if ( ChoppedAwayByProcBSP( w, p->plane, p->contents ) ) { + edge->internal = true; + } + } +} + +/* +============= +idCollisionModelManagerLocal::FindInternalEdges +============= +*/ +void idCollisionModelManagerLocal::FindInternalEdges( cm_model_t *model, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + + while( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // if we checked this polygon already + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + + FindInternalPolygonEdges( model, model->node, p ); + + //FindContainedEdges( model, p ); + } + // if leaf node + if ( node->planeType == -1 ) { + break; + } + FindInternalEdges( model, node->children[1] ); + node = node->children[0]; + } +} + +/* +=============================================================================== + +Spatial subdivision + +=============================================================================== +*/ + +/* +================ +CM_FindSplitter +================ +*/ +static int CM_FindSplitter( const cm_node_t *node, const idBounds &bounds, int *planeType, float *planeDist ) { + int i, j, type, axis[3], polyCount; + float dist, t, bestt, size[3]; + cm_brushRef_t *bref; + cm_polygonRef_t *pref; + const cm_node_t *n; + bool forceSplit = false; + + for ( i = 0; i < 3; i++ ) { + size[i] = bounds[1][i] - bounds[0][i]; + axis[i] = i; + } + // sort on largest axis + for ( i = 0; i < 2; i++ ) { + if ( size[i] < size[i+1] ) { + t = size[i]; + size[i] = size[i+1]; + size[i+1] = t; + j = axis[i]; + axis[i] = axis[i+1]; + axis[i+1] = j; + i = -1; + } + } + // if the node is too small for further splits + if ( size[0] < MIN_NODE_SIZE ) { + polyCount = 0; + for ( pref = node->polygons; pref; pref = pref->next) { + polyCount++; + } + if ( polyCount > MAX_NODE_POLYGONS ) { + forceSplit = true; + } + } + // find an axial aligned splitter + for ( i = 0; i < 3; i++ ) { + // start with the largest axis first + type = axis[i]; + bestt = size[i]; + // if the node is small anough in this axis direction + if ( !forceSplit && bestt < MIN_NODE_SIZE ) { + break; + } + // find an axial splitter from the brush bounding boxes + // also try brushes from parent nodes + for ( n = node; n; n = n->parent ) { + for ( bref = n->brushes; bref; bref = bref->next) { + for ( j = 0; j < 2; j++ ) { + dist = bref->b->bounds[j][type]; + // if the splitter is already used or outside node bounds + if ( dist >= bounds[1][type] || dist <= bounds[0][type] ) { + continue; + } + // find the most centered splitter + t = abs((bounds[1][type] - dist) - (dist - bounds[0][type])); + if ( t < bestt ) { + bestt = t; + *planeType = type; + *planeDist = dist; + } + } + } + } + // find an axial splitter from the polygon bounding boxes + // also try brushes from parent nodes + for ( n = node; n; n = n->parent ) { + for ( pref = n->polygons; pref; pref = pref->next) { + for ( j = 0; j < 2; j++ ) { + dist = pref->p->bounds[j][type]; + // if the splitter is already used or outside node bounds + if ( dist >= bounds[1][type] || dist <= bounds[0][type] ) { + continue; + } + // find the most centered splitter + t = abs((bounds[1][type] - dist) - (dist - bounds[0][type])); + if ( t < bestt ) { + bestt = t; + *planeType = type; + *planeDist = dist; + } + } + } + } + // if we found a splitter on the largest axis + if ( bestt < size[i] ) { + // if forced split due to lots of polygons + if ( forceSplit ) { + return true; + } + // don't create splitters real close to the bounds + if ( bounds[1][type] - *planeDist > (MIN_NODE_SIZE*0.5f) && + *planeDist - bounds[0][type] > (MIN_NODE_SIZE*0.5f) ) { + return true; + } + } + } + return false; +} + +/* +================ +CM_R_InsideAllChildren +================ +*/ +static int CM_R_InsideAllChildren( cm_node_t *node, const idBounds &bounds ) { + assert(node != NULL); + if ( node->planeType != -1 ) { + if ( bounds[0][node->planeType] >= node->planeDist ) { + return false; + } + if ( bounds[1][node->planeType] <= node->planeDist ) { + return false; + } + if ( !CM_R_InsideAllChildren( node->children[0], bounds ) ) { + return false; + } + if ( !CM_R_InsideAllChildren( node->children[1], bounds ) ) { + return false; + } + } + return true; +} + +/* +================ +idCollisionModelManagerLocal::R_FilterPolygonIntoTree +================ +*/ +void idCollisionModelManagerLocal::R_FilterPolygonIntoTree( cm_model_t *model, cm_node_t *node, cm_polygonRef_t *pref, cm_polygon_t *p ) { + assert(node != NULL); + while ( node->planeType != -1 ) { + if ( CM_R_InsideAllChildren( node, p->bounds ) ) { + break; + } + if ( p->bounds[0][node->planeType] >= node->planeDist ) { + node = node->children[0]; + } + else if ( p->bounds[1][node->planeType] <= node->planeDist ) { + node = node->children[1]; + } + else { + R_FilterPolygonIntoTree( model, node->children[1], NULL, p ); + node = node->children[0]; + } + } + if ( pref ) { + pref->next = node->polygons; + node->polygons = pref; + } + else { + AddPolygonToNode( model, node, p ); + } +} + +/* +================ +idCollisionModelManagerLocal::R_FilterBrushIntoTree +================ +*/ +void idCollisionModelManagerLocal::R_FilterBrushIntoTree( cm_model_t *model, cm_node_t *node, cm_brushRef_t *pref, cm_brush_t *b ) { + assert(node != NULL); + while ( node->planeType != -1 ) { + if ( CM_R_InsideAllChildren( node, b->bounds ) ) { + break; + } + if ( b->bounds[0][node->planeType] >= node->planeDist ) { + node = node->children[0]; + } + else if ( b->bounds[1][node->planeType] <= node->planeDist ) { + node = node->children[1]; + } + else { + R_FilterBrushIntoTree( model, node->children[1], NULL, b ); + node = node->children[0]; + } + } + if ( pref ) { + pref->next = node->brushes; + node->brushes = pref; + } + else { + AddBrushToNode( model, node, b ); + } +} + +/* +================ +idCollisionModelManagerLocal::R_CreateAxialBSPTree + + a brush or polygon is linked in the node closest to the root where + the brush or polygon is inside all children +================ +*/ +cm_node_t *idCollisionModelManagerLocal::R_CreateAxialBSPTree( cm_model_t *model, cm_node_t *node, const idBounds &bounds ) { + int planeType; + float planeDist; + cm_polygonRef_t *pref, *nextpref, *prevpref; + cm_brushRef_t *bref, *nextbref, *prevbref; + cm_node_t *frontNode, *backNode, *n; + idBounds frontBounds, backBounds; + + if ( !CM_FindSplitter( node, bounds, &planeType, &planeDist ) ) { + node->planeType = -1; + return node; + } + // create two child nodes + frontNode = AllocNode( model, NODE_BLOCK_SIZE_LARGE ); + memset( frontNode, 0, sizeof(cm_node_t) ); + frontNode->parent = node; + frontNode->planeType = -1; + // + backNode = AllocNode( model, NODE_BLOCK_SIZE_LARGE ); + memset( backNode, 0, sizeof(cm_node_t) ); + backNode->parent = node; + backNode->planeType = -1; + // + model->numNodes += 2; + // set front node bounds + frontBounds = bounds; + frontBounds[0][planeType] = planeDist; + // set back node bounds + backBounds = bounds; + backBounds[1][planeType] = planeDist; + // + node->planeType = planeType; + node->planeDist = planeDist; + node->children[0] = frontNode; + node->children[1] = backNode; + // filter polygons and brushes down the tree if necesary + for ( n = node; n; n = n->parent ) { + prevpref = NULL; + for ( pref = n->polygons; pref; pref = nextpref) { + nextpref = pref->next; + // if polygon is not inside all children + if ( !CM_R_InsideAllChildren( n, pref->p->bounds ) ) { + // filter polygon down the tree + R_FilterPolygonIntoTree( model, n, pref, pref->p ); + if ( prevpref ) { + prevpref->next = nextpref; + } + else { + n->polygons = nextpref; + } + } + else { + prevpref = pref; + } + } + prevbref = NULL; + for ( bref = n->brushes; bref; bref = nextbref) { + nextbref = bref->next; + // if brush is not inside all children + if ( !CM_R_InsideAllChildren( n, bref->b->bounds ) ) { + // filter brush down the tree + R_FilterBrushIntoTree( model, n, bref, bref->b ); + if ( prevbref ) { + prevbref->next = nextbref; + } + else { + n->brushes = nextbref; + } + } + else { + prevbref = bref; + } + } + } + R_CreateAxialBSPTree( model, frontNode, frontBounds ); + R_CreateAxialBSPTree( model, backNode, backBounds ); + return node; +} + +/* +int cm_numSavedPolygonLinks; +int cm_numSavedBrushLinks; + +int CM_R_CountChildren( cm_node_t *node ) { + if ( node->planeType == -1 ) { + return 0; + } + return 2 + CM_R_CountChildren(node->children[0]) + CM_R_CountChildren(node->children[1]); +} + +void CM_R_TestOptimisation( cm_node_t *node ) { + int polyCount, brushCount, numChildren; + cm_polygonRef_t *pref; + cm_brushRef_t *bref; + + if ( node->planeType == -1 ) { + return; + } + polyCount = 0; + for ( pref = node->polygons; pref; pref = pref->next) { + polyCount++; + } + brushCount = 0; + for ( bref = node->brushes; bref; bref = bref->next) { + brushCount++; + } + if ( polyCount || brushCount ) { + numChildren = CM_R_CountChildren( node ); + cm_numSavedPolygonLinks += (numChildren - 1) * polyCount; + cm_numSavedBrushLinks += (numChildren - 1) * brushCount; + } + CM_R_TestOptimisation( node->children[0] ); + CM_R_TestOptimisation( node->children[1] ); +} +*/ + +/* +================ +idCollisionModelManagerLocal::CreateAxialBSPTree +================ +*/ +cm_node_t *idCollisionModelManagerLocal::CreateAxialBSPTree( cm_model_t *model, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_brushRef_t *bref; + idBounds bounds; + + // get head node bounds + bounds.Clear(); + for ( pref = node->polygons; pref; pref = pref->next) { + bounds += pref->p->bounds; + } + for ( bref = node->brushes; bref; bref = bref->next) { + bounds += bref->b->bounds; + } + + // create axial BSP tree from head node + node = R_CreateAxialBSPTree( model, node, bounds ); + + return node; +} + +/* +=============================================================================== + +Raw polygon and brush data + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::SetupHash +================ +*/ +void idCollisionModelManagerLocal::SetupHash( void ) { + if ( !cm_vertexHash ) { + cm_vertexHash = new idHashIndex( VERTEX_HASH_SIZE, 1024 ); + } + if ( !cm_edgeHash ) { + cm_edgeHash = new idHashIndex( EDGE_HASH_SIZE, 1024 ); + } + // init variables used during loading and optimization + if ( !cm_windingList ) { + cm_windingList = new cm_windingList_t; + } + if ( !cm_outList ) { + cm_outList = new cm_windingList_t; + } + if ( !cm_tmpList ) { + cm_tmpList = new cm_windingList_t; + } +} + +/* +================ +idCollisionModelManagerLocal::ShutdownHash +================ +*/ +void idCollisionModelManagerLocal::ShutdownHash( void ) { + delete cm_vertexHash; + cm_vertexHash = NULL; + delete cm_edgeHash; + cm_edgeHash = NULL; + delete cm_tmpList; + cm_tmpList = NULL; + delete cm_outList; + cm_outList = NULL; + delete cm_windingList; + cm_windingList = NULL; +} + +/* +================ +idCollisionModelManagerLocal::ClearHash +================ +*/ +void idCollisionModelManagerLocal::ClearHash( idBounds &bounds ) { + int i; + float f, max; + + cm_vertexHash->Clear(); + cm_edgeHash->Clear(); + + cm_modelBounds = bounds; + max = bounds[1].x - bounds[0].x; + f = bounds[1].y - bounds[0].y; + if ( f > max ) { + max = f; + } + cm_vertexShift = (float) max / VERTEX_HASH_BOXSIZE; + for ( i = 0; (1<> cm_vertexShift) & (VERTEX_HASH_BOXSIZE-1); + y = (((int)(vec[1] - cm_modelBounds[0].y + 0.5 )) >> cm_vertexShift) & (VERTEX_HASH_BOXSIZE-1); + + assert (x >= 0 && x < VERTEX_HASH_BOXSIZE && y >= 0 && y < VERTEX_HASH_BOXSIZE); + + return y * VERTEX_HASH_BOXSIZE + x; + */ + int x, y, z; + + x = (((int) (vec[0] - cm_modelBounds[0].x + 0.5)) + 2) >> 2; + y = (((int) (vec[1] - cm_modelBounds[0].y + 0.5)) + 2) >> 2; + z = (((int) (vec[2] - cm_modelBounds[0].z + 0.5)) + 2) >> 2; + return (x + y * VERTEX_HASH_BOXSIZE + z) & (VERTEX_HASH_SIZE-1); +} + +/* +================ +idCollisionModelManagerLocal::GetVertex +================ +*/ +int idCollisionModelManagerLocal::GetVertex( cm_model_t *model, const idVec3 &v, int *vertexNum ) { + int i, hashKey, vn; + idVec3 vert, *p; + + for (i = 0; i < 3; i++) { + if ( idMath::Fabs(v[i] - idMath::Rint(v[i])) < INTEGRAL_EPSILON ) + vert[i] = idMath::Rint(v[i]); + else + vert[i] = v[i]; + } + + hashKey = HashVec( vert ); + + for (vn = cm_vertexHash->First( hashKey ); vn >= 0; vn = cm_vertexHash->Next( vn ) ) { + p = &model->vertices[vn].p; + // first compare z-axis because hash is based on x-y plane + if (idMath::Fabs(vert[2] - (*p)[2]) < VERTEX_EPSILON && + idMath::Fabs(vert[0] - (*p)[0]) < VERTEX_EPSILON && + idMath::Fabs(vert[1] - (*p)[1]) < VERTEX_EPSILON ) + { + *vertexNum = vn; + return true; + } + } + + if ( model->numVertices >= model->maxVertices ) { + cm_vertex_t *oldVertices; + + // resize vertex array + model->maxVertices = (float) model->maxVertices * 1.5f + 1; + oldVertices = model->vertices; + model->vertices = (cm_vertex_t *) Mem_ClearedAlloc( model->maxVertices * sizeof(cm_vertex_t) ); + memcpy( model->vertices, oldVertices, model->numVertices * sizeof(cm_vertex_t) ); + Mem_Free( oldVertices ); + + cm_vertexHash->ResizeIndex( model->maxVertices ); + } + model->vertices[model->numVertices].p = vert; + model->vertices[model->numVertices].checkcount = 0; + *vertexNum = model->numVertices; + // add vertice to hash + cm_vertexHash->Add( hashKey, model->numVertices ); + // + model->numVertices++; + return false; +} + +/* +================ +idCollisionModelManagerLocal::GetEdge +================ +*/ +int idCollisionModelManagerLocal::GetEdge( cm_model_t *model, const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num ) { + int v2num, hashKey, e; + int found, *vertexNum; + + // the first edge is a dummy + if ( model->numEdges == 0 ) { + model->numEdges = 1; + } + + if ( v1num != -1 ) { + found = 1; + } + else { + found = GetVertex( model, v1, &v1num ); + } + found &= GetVertex( model, v2, &v2num ); + // if both vertices are the same or snapped onto each other + if ( v1num == v2num ) { + *edgeNum = 0; + return true; + } + hashKey = cm_edgeHash->GenerateKey( v1num, v2num ); + // if both vertices where already stored + if (found) { + for (e = cm_edgeHash->First( hashKey ); e >= 0; e = cm_edgeHash->Next( e ) ) + { + // NOTE: only allow at most two users that use the edge in opposite direction + if ( model->edges[e].numUsers != 1 ) { + continue; + } + + vertexNum = model->edges[e].vertexNum; + if ( vertexNum[0] == v2num ) { + if ( vertexNum[1] == v1num ) { + // negative for a reversed edge + *edgeNum = -e; + break; + } + } + /* + else if ( vertexNum[0] == v1num ) { + if ( vertexNum[1] == v2num ) { + *edgeNum = e; + break; + } + } + */ + } + // if edge found in hash + if ( e >= 0 ) { + model->edges[e].numUsers++; + return true; + } + } + if ( model->numEdges >= model->maxEdges ) { + cm_edge_t *oldEdges; + + // resize edge array + model->maxEdges = (float) model->maxEdges * 1.5f + 1; + oldEdges = model->edges; + model->edges = (cm_edge_t *) Mem_ClearedAlloc( model->maxEdges * sizeof(cm_edge_t) ); + memcpy( model->edges, oldEdges, model->numEdges * sizeof(cm_edge_t) ); + Mem_Free( oldEdges ); + + cm_edgeHash->ResizeIndex( model->maxEdges ); + } + // setup edge + model->edges[model->numEdges].vertexNum[0] = v1num; + model->edges[model->numEdges].vertexNum[1] = v2num; + model->edges[model->numEdges].internal = false; + model->edges[model->numEdges].checkcount = 0; + model->edges[model->numEdges].numUsers = 1; // used by one polygon atm + model->edges[model->numEdges].normal.Zero(); + // + *edgeNum = model->numEdges; + // add edge to hash + cm_edgeHash->Add( hashKey, model->numEdges ); + + model->numEdges++; + + return false; +} + +/* +================ +idCollisionModelManagerLocal::CreatePolygon +================ +*/ +void idCollisionModelManagerLocal::CreatePolygon( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ) { + int i, j, edgeNum, v1num; + int numPolyEdges, polyEdges[MAX_POINTS_ON_WINDING]; + idBounds bounds; + cm_polygon_t *p; + + // turn the winding into a sequence of edges + numPolyEdges = 0; + v1num = -1; // first vertex unknown + for ( i = 0, j = 1; i < w->GetNumPoints(); i++, j++ ) { + if ( j >= w->GetNumPoints() ) { + j = 0; + } + GetEdge( model, (*w)[i].ToVec3(), (*w)[j].ToVec3(), &polyEdges[numPolyEdges], v1num ); + if ( polyEdges[numPolyEdges] ) { + // last vertex of this edge is the first vertex of the next edge + v1num = model->edges[ abs(polyEdges[numPolyEdges]) ].vertexNum[ INTSIGNBITNOTSET(polyEdges[numPolyEdges]) ]; + // this edge is valid so keep it + numPolyEdges++; + } + } + // should have at least 3 edges + if ( numPolyEdges < 3 ) { + return; + } + // the polygon is invalid if some edge is found twice + for ( i = 0; i < numPolyEdges; i++ ) { + for ( j = i+1; j < numPolyEdges; j++ ) { + if ( abs(polyEdges[i]) == abs(polyEdges[j]) ) { + return; + } + } + } + // don't overflow max edges + if ( numPolyEdges > CM_MAX_POLYGON_EDGES ) { + common->Warning( "idCollisionModelManagerLocal::CreatePolygon: polygon has more than %d edges", numPolyEdges ); + numPolyEdges = CM_MAX_POLYGON_EDGES; + } + + w->GetBounds( bounds ); + + p = AllocPolygon( model, numPolyEdges ); + p->numEdges = numPolyEdges; + p->contents = material->GetContentFlags(); + p->material = material; + p->checkcount = 0; + p->plane = plane; + p->bounds = bounds; + for ( i = 0; i < numPolyEdges; i++ ) { + edgeNum = polyEdges[i]; + p->edges[i] = edgeNum; + } + R_FilterPolygonIntoTree( model, model->node, NULL, p ); +} + +/* +================ +idCollisionModelManagerLocal::PolygonFromWinding + + NOTE: for patches primitiveNum < 0 and abs(primitiveNum) is the real number +================ +*/ +void idCollisionModelManagerLocal::PolygonFromWinding( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ) { + int contents; + + contents = material->GetContentFlags(); + + // if this polygon is part of the world model + if ( numModels == 0 ) { + // if the polygon is fully chopped away by the proc bsp tree + if ( ChoppedAwayByProcBSP( *w, plane, contents ) ) { + model->numRemovedPolys++; + return; + } + } + + // get one winding that is not or only partly contained in brushes + w = WindingOutsideBrushes( w, plane, contents, primitiveNum, model->node ); + + // if the polygon is fully contained within a brush + if ( !w ) { + model->numRemovedPolys++; + return; + } + + if ( w->IsHuge() ) { + common->Warning( "idCollisionModelManagerLocal::PolygonFromWinding: model %s primitive %d is degenerate", model->name.c_str(), abs(primitiveNum) ); + return; + } + + CreatePolygon( model, w, plane, material, primitiveNum ); + + if ( material->GetCullType() == CT_TWO_SIDED || material->ShouldCreateBackSides() ) { + w->ReverseSelf(); + CreatePolygon( model, w, -plane, material, primitiveNum ); + } +} + +/* +================= +idCollisionModelManagerLocal::CreatePatchPolygons +================= +*/ +void idCollisionModelManagerLocal::CreatePatchPolygons( cm_model_t *model, idSurface_Patch &mesh, const idMaterial *material, int primitiveNum ) { + int i, j; + float dot; + int v1, v2, v3, v4; + idFixedWinding w; + idPlane plane; + idVec3 d1, d2; + + for ( i = 0; i < mesh.GetWidth() - 1; i++ ) { + for ( j = 0; j < mesh.GetHeight() - 1; j++ ) { + + v1 = j * mesh.GetWidth() + i; + v2 = v1 + 1; + v3 = v1 + mesh.GetWidth() + 1; + v4 = v1 + mesh.GetWidth(); + + d1 = mesh[v2].xyz - mesh[v1].xyz; + d2 = mesh[v3].xyz - mesh[v1].xyz; + plane.SetNormal( d1.Cross(d2) ); + if ( plane.Normalize() != 0.0f ) { + plane.FitThroughPoint( mesh[v1].xyz ); + dot = plane.Distance( mesh[v4].xyz ); + // if we can turn it into a quad + if ( idMath::Fabs(dot) < 0.1f ) { + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v2].xyz; + w += mesh[v3].xyz; + w += mesh[v4].xyz; + + PolygonFromWinding( model, &w, plane, material, -primitiveNum ); + continue; + } + else { + // create one of the triangles + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v2].xyz; + w += mesh[v3].xyz; + + PolygonFromWinding( model, &w, plane, material, -primitiveNum ); + } + } + // create the other triangle + d1 = mesh[v3].xyz - mesh[v1].xyz; + d2 = mesh[v4].xyz - mesh[v1].xyz; + plane.SetNormal( d1.Cross(d2) ); + if ( plane.Normalize() != 0.0f ) { + plane.FitThroughPoint( mesh[v1].xyz ); + + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v3].xyz; + w += mesh[v4].xyz; + + PolygonFromWinding( model, &w, plane, material, -primitiveNum ); + } + } + } +} + +/* +================= +CM_EstimateVertsAndEdges +================= +*/ +static void CM_EstimateVertsAndEdges( const idMapEntity *mapEnt, int *numVerts, int *numEdges ) { + int j, width, height; + + *numVerts = *numEdges = 0; + for ( j = 0; j < mapEnt->GetNumPrimitives(); j++ ) { + const idMapPrimitive *mapPrim; + mapPrim = mapEnt->GetPrimitive(j); + if ( mapPrim->GetType() == idMapPrimitive::TYPE_PATCH ) { + // assume maximum tesselation without adding verts + width = static_cast(mapPrim)->GetWidth(); + height = static_cast(mapPrim)->GetHeight(); + *numVerts += width * height; + *numEdges += (width-1) * height + width * (height-1) + (width-1) * (height-1); + continue; + } + if ( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) { + // assume cylinder with a polygon with (numSides - 2) edges ontop and on the bottom + *numVerts += (static_cast(mapPrim)->GetNumSides() - 2) * 2; + *numEdges += (static_cast(mapPrim)->GetNumSides() - 2) * 3; + continue; + } + } +} + +/* +================= +idCollisionModelManagerLocal::ConverPatch +================= +*/ +void idCollisionModelManagerLocal::ConvertPatch( cm_model_t *model, const idMapPatch *patch, int primitiveNum ) { + const idMaterial *material; + idSurface_Patch *cp; + + material = declManager->FindMaterial( patch->GetMaterial() ); + if ( !( material->GetContentFlags() & CONTENTS_REMOVE_UTIL ) ) { + return; + } + + // copy the patch + cp = new idSurface_Patch( *patch ); + + // if the patch has an explicit number of subdivisions use it to avoid cracks + if ( patch->GetExplicitlySubdivided() ) { + cp->SubdivideExplicit( patch->GetHorzSubdivisions(), patch->GetVertSubdivisions(), false, true ); + } else { + cp->Subdivide( DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_LENGTH_CD, false ); + } + + // create collision polygons for the patch + CreatePatchPolygons( model, *cp, material, primitiveNum ); + + delete cp; +} + +/* +================ +idCollisionModelManagerLocal::ConvertBrushSides +================ +*/ +void idCollisionModelManagerLocal::ConvertBrushSides( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ) { + int i, j; + idMapBrushSide *mapSide; + idFixedWinding w; + idPlane *planes; + const idMaterial *material; + + // fix degenerate planes + planes = (idPlane *) _alloca16( mapBrush->GetNumSides() * sizeof( planes[0] ) ); + for ( i = 0; i < mapBrush->GetNumSides(); i++ ) { + planes[i] = mapBrush->GetSide(i)->GetPlane(); + planes[i].FixDegeneracies( DEGENERATE_DIST_EPSILON ); + } + + // create a collision polygon for each brush side + for ( i = 0; i < mapBrush->GetNumSides(); i++ ) { + mapSide = mapBrush->GetSide(i); + material = declManager->FindMaterial( mapSide->GetMaterial() ); + if ( !( material->GetContentFlags() & CONTENTS_REMOVE_UTIL ) ) { + continue; + } + w.BaseForPlane( -planes[i] ); + for ( j = 0; j < mapBrush->GetNumSides() && w.GetNumPoints(); j++ ) { + if ( i == j ) { + continue; + } + w.ClipInPlace( -planes[j], 0 ); + } + + if ( w.GetNumPoints() ) { + PolygonFromWinding( model, &w, planes[i], material, primitiveNum ); + } + } +} + +/* +================ +idCollisionModelManagerLocal::ConvertBrush +================ +*/ +void idCollisionModelManagerLocal::ConvertBrush( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ) { + int i, j, contents; + idBounds bounds; + idMapBrushSide *mapSide; + cm_brush_t *brush; + idPlane *planes; + idFixedWinding w; + const idMaterial *material = NULL; + + contents = 0; + bounds.Clear(); + + // fix degenerate planes + planes = (idPlane *) _alloca16( mapBrush->GetNumSides() * sizeof( planes[0] ) ); + for ( i = 0; i < mapBrush->GetNumSides(); i++ ) { + planes[i] = mapBrush->GetSide(i)->GetPlane(); + planes[i].FixDegeneracies( DEGENERATE_DIST_EPSILON ); + } + + // we are only getting the bounds for the brush so there's no need + // to create a winding for the last brush side + for ( i = 0; i < mapBrush->GetNumSides() - 1; i++ ) { + mapSide = mapBrush->GetSide(i); + material = declManager->FindMaterial( mapSide->GetMaterial() ); + contents |= ( material->GetContentFlags() & CONTENTS_REMOVE_UTIL ); + w.BaseForPlane( -planes[i] ); + for ( j = 0; j < mapBrush->GetNumSides() && w.GetNumPoints(); j++ ) { + if ( i == j ) { + continue; + } + w.ClipInPlace( -planes[j], 0 ); + } + + for ( j = 0; j < w.GetNumPoints(); j++ ) { + bounds.AddPoint( w[j].ToVec3() ); + } + } + if ( !contents ) { + return; + } + // create brush for position test + brush = AllocBrush( model, mapBrush->GetNumSides() ); + brush->checkcount = 0; + brush->contents = contents; + brush->material = material; + brush->primitiveNum = primitiveNum; + brush->bounds = bounds; + brush->numPlanes = mapBrush->GetNumSides(); + for (i = 0; i < mapBrush->GetNumSides(); i++) { + brush->planes[i] = planes[i]; + } + AddBrushToNode( model, model->node, brush ); +} + +/* +================ +CM_CountNodeBrushes +================ +*/ +static int CM_CountNodeBrushes( const cm_node_t *node ) { + int count; + cm_brushRef_t *bref; + + count = 0; + for ( bref = node->brushes; bref; bref = bref->next ) { + count++; + } + return count; +} + +/* +================ +CM_R_GetModelBounds +================ +*/ +static void CM_R_GetNodeBounds( idBounds *bounds, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_brushRef_t *bref; + + while ( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + bounds->AddPoint( pref->p->bounds[0] ); + bounds->AddPoint( pref->p->bounds[1] ); + } + for ( bref = node->brushes; bref; bref = bref->next ) { + bounds->AddPoint( bref->b->bounds[0] ); + bounds->AddPoint( bref->b->bounds[1] ); + } + if ( node->planeType == -1 ) { + break; + } + CM_R_GetNodeBounds( bounds, node->children[1] ); + node = node->children[0]; + } +} + +/* +================ +CM_GetNodeBounds +================ +*/ +void CM_GetNodeBounds( idBounds *bounds, cm_node_t *node ) { + bounds->Clear(); + CM_R_GetNodeBounds( bounds, node ); + if ( bounds->IsCleared() ) { + bounds->Zero(); + } +} + +/* +================ +CM_GetNodeContents +================ +*/ +int CM_GetNodeContents( cm_node_t *node ) { + int contents; + cm_polygonRef_t *pref; + cm_brushRef_t *bref; + + contents = 0; + while ( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + contents |= pref->p->contents; + } + for ( bref = node->brushes; bref; bref = bref->next ) { + contents |= bref->b->contents; + } + if ( node->planeType == -1 ) { + break; + } + contents |= CM_GetNodeContents( node->children[1] ); + node = node->children[0]; + } + return contents; +} + +/* +================== +idCollisionModelManagerLocal::RemapEdges +================== +*/ +void idCollisionModelManagerLocal::RemapEdges( cm_node_t *node, int *edgeRemap ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + int i; + + while ( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + // if we checked this polygon already + if ( p->checkcount == checkCount ) { + continue; + } + p->checkcount = checkCount; + for ( i = 0; i < p->numEdges; i++ ) { + if ( p->edges[i] < 0 ) { + p->edges[i] = -edgeRemap[ abs(p->edges[i]) ]; + } + else { + p->edges[i] = edgeRemap[ p->edges[i] ]; + } + } + } + if ( node->planeType == -1 ) { + break; + } + + RemapEdges( node->children[1], edgeRemap ); + node = node->children[0]; + } +} + +/* +================== +idCollisionModelManagerLocal::OptimizeArrays + + due to polygon merging and polygon removal the vertex and edge array + can have a lot of unused entries. +================== +*/ +void idCollisionModelManagerLocal::OptimizeArrays( cm_model_t *model ) { + int i, newNumVertices, newNumEdges, *v; + int *remap; + cm_edge_t *oldEdges; + cm_vertex_t *oldVertices; + + remap = (int *) Mem_ClearedAlloc( Max( model->numVertices, model->numEdges ) * sizeof( int ) ); + // get all used vertices + for ( i = 0; i < model->numEdges; i++ ) { + remap[ model->edges[i].vertexNum[0] ] = true; + remap[ model->edges[i].vertexNum[1] ] = true; + } + // create remap index and move vertices + newNumVertices = 0; + for ( i = 0; i < model->numVertices; i++ ) { + if ( remap[ i ] ) { + remap[ i ] = newNumVertices; + model->vertices[ newNumVertices ] = model->vertices[ i ]; + newNumVertices++; + } + } + model->numVertices = newNumVertices; + // change edge vertex indexes + for ( i = 1; i < model->numEdges; i++ ) { + v = model->edges[i].vertexNum; + v[0] = remap[ v[0] ]; + v[1] = remap[ v[1] ]; + } + + // create remap index and move edges + newNumEdges = 1; + for ( i = 1; i < model->numEdges; i++ ) { + // if the edge is used + if ( model->edges[ i ].numUsers ) { + remap[ i ] = newNumEdges; + model->edges[ newNumEdges ] = model->edges[ i ]; + newNumEdges++; + } + } + // change polygon edge indexes + checkCount++; + RemapEdges( model->node, remap ); + model->numEdges = newNumEdges; + + Mem_Free( remap ); + + // realloc vertices + oldVertices = model->vertices; + if ( oldVertices ) { + model->vertices = (cm_vertex_t *) Mem_ClearedAlloc( model->numVertices * sizeof(cm_vertex_t) ); + memcpy( model->vertices, oldVertices, model->numVertices * sizeof(cm_vertex_t) ); + Mem_Free( oldVertices ); + } + + // realloc edges + oldEdges = model->edges; + if ( oldEdges ) { + model->edges = (cm_edge_t *) Mem_ClearedAlloc( model->numEdges * sizeof(cm_edge_t) ); + memcpy( model->edges, oldEdges, model->numEdges * sizeof(cm_edge_t) ); + Mem_Free( oldEdges ); + } +} + +/* +================ +idCollisionModelManagerLocal::FinishModel +================ +*/ +void idCollisionModelManagerLocal::FinishModel( cm_model_t *model ) { + // try to merge polygons + checkCount++; + MergeTreePolygons( model, model->node ); + // find internal edges (no mesh can ever collide with internal edges) + checkCount++; + FindInternalEdges( model, model->node ); + // calculate edge normals + checkCount++; + CalculateEdgeNormals( model, model->node ); + + //common->Printf( "%s vertex hash spread is %d\n", model->name.c_str(), cm_vertexHash->GetSpread() ); + //common->Printf( "%s edge hash spread is %d\n", model->name.c_str(), cm_edgeHash->GetSpread() ); + + // remove all unused vertices and edges + OptimizeArrays( model ); + // get model bounds from brush and polygon bounds + CM_GetNodeBounds( &model->bounds, model->node ); + // get model contents + model->contents = CM_GetNodeContents( model->node ); + // total memory used by this model + model->usedMemory = model->numVertices * sizeof(cm_vertex_t) + + model->numEdges * sizeof(cm_edge_t) + + model->polygonMemory + + model->brushMemory + + model->numNodes * sizeof(cm_node_t) + + model->numPolygonRefs * sizeof(cm_polygonRef_t) + + model->numBrushRefs * sizeof(cm_brushRef_t); +} + +/* +================ +idCollisionModelManagerLocal::LoadRenderModel +================ +*/ +cm_model_t *idCollisionModelManagerLocal::LoadRenderModel( const char *fileName ) { + int i, j; + idRenderModel *renderModel; + const modelSurface_t *surf; + idFixedWinding w; + cm_node_t *node; + cm_model_t *model; + idPlane plane; + idBounds bounds; + bool collisionSurface; + idStr extension; + + // only load ASE and LWO models + idStr( fileName ).ExtractFileExtension( extension ); + if ( ( extension.Icmp( "ase" ) != 0 ) && ( extension.Icmp( "lwo" ) != 0 ) && ( extension.Icmp( "ma" ) != 0 ) ) { + return NULL; + } + + if ( !renderModelManager->CheckModel( fileName ) ) { + return NULL; + } + + renderModel = renderModelManager->FindModel( fileName ); + + model = AllocModel(); + model->name = fileName; + node = AllocNode( model, NODE_BLOCK_SIZE_SMALL ); + node->planeType = -1; + model->node = node; + + model->maxVertices = 0; + model->numVertices = 0; + model->maxEdges = 0; + model->numEdges = 0; + + bounds = renderModel->Bounds( NULL ); + + collisionSurface = false; + for ( i = 0; i < renderModel->NumSurfaces(); i++ ) { + surf = renderModel->Surface( i ); + if ( surf->shader->GetSurfaceFlags() & SURF_COLLISION ) { + collisionSurface = true; + } + } + + for ( i = 0; i < renderModel->NumSurfaces(); i++ ) { + surf = renderModel->Surface( i ); + // if this surface has no contents + if ( ! ( surf->shader->GetContentFlags() & CONTENTS_REMOVE_UTIL ) ) { + continue; + } + // if the model has a collision surface and this surface is not a collision surface + if ( collisionSurface && !( surf->shader->GetSurfaceFlags() & SURF_COLLISION ) ) { + continue; + } + // get max verts and edges + model->maxVertices += surf->geometry->numVerts; + model->maxEdges += surf->geometry->numIndexes; + } + + model->vertices = (cm_vertex_t *) Mem_ClearedAlloc( model->maxVertices * sizeof(cm_vertex_t) ); + model->edges = (cm_edge_t *) Mem_ClearedAlloc( model->maxEdges * sizeof(cm_edge_t) ); + + // setup hash to speed up finding shared vertices and edges + SetupHash(); + + cm_vertexHash->ResizeIndex( model->maxVertices ); + cm_edgeHash->ResizeIndex( model->maxEdges ); + + ClearHash( bounds ); + + for ( i = 0; i < renderModel->NumSurfaces(); i++ ) { + surf = renderModel->Surface( i ); + // if this surface has no contents + if ( ! ( surf->shader->GetContentFlags() & CONTENTS_REMOVE_UTIL ) ) { + continue; + } + // if the model has a collision surface and this surface is not a collision surface + if ( collisionSurface && !( surf->shader->GetSurfaceFlags() & SURF_COLLISION ) ) { + continue; + } + + for ( j = 0; j < surf->geometry->numIndexes; j += 3 ) { + w.Clear(); + w += surf->geometry->verts[ surf->geometry->indexes[ j + 2 ] ].xyz; + w += surf->geometry->verts[ surf->geometry->indexes[ j + 1 ] ].xyz; + w += surf->geometry->verts[ surf->geometry->indexes[ j + 0 ] ].xyz; + w.GetPlane( plane ); + plane = -plane; + PolygonFromWinding( model, &w, plane, surf->shader, 1 ); + } + } + + // create a BSP tree for the model + model->node = CreateAxialBSPTree( model, model->node ); + + model->isConvex = false; + + FinishModel( model ); + + // shutdown the hash + ShutdownHash(); + + common->Printf( "loaded collision model %s\n", model->name.c_str() ); + + return model; +} + +/* +================ +idCollisionModelManagerLocal::CollisionModelForMapEntity +================ +*/ +cm_model_t *idCollisionModelManagerLocal::CollisionModelForMapEntity( const idMapEntity *mapEnt ) { + cm_model_t *model; + idBounds bounds; + const char *name; + int i, brushCount; + + // if the entity has no primitives + if ( mapEnt->GetNumPrimitives() < 1 ) { + return NULL; + } + + // get a name for the collision model + mapEnt->epairs.GetString( "model", "", &name ); + if ( !name[0] ) { + mapEnt->epairs.GetString( "name", "", &name ); + if ( !name[0] ) { + if ( !numModels ) { + // first model is always the world + name = "worldMap"; + } + else { + name = "unnamed inline model"; + } + } + } + + model = AllocModel(); + model->node = AllocNode( model, NODE_BLOCK_SIZE_SMALL ); + + CM_EstimateVertsAndEdges( mapEnt, &model->maxVertices, &model->maxEdges ); + model->numVertices = 0; + model->numEdges = 0; + model->vertices = (cm_vertex_t *) Mem_ClearedAlloc( model->maxVertices * sizeof(cm_vertex_t) ); + model->edges = (cm_edge_t *) Mem_ClearedAlloc( model->maxEdges * sizeof(cm_edge_t) ); + + cm_vertexHash->ResizeIndex( model->maxVertices ); + cm_edgeHash->ResizeIndex( model->maxEdges ); + + model->name = name; + model->isConvex = false; + + // convert brushes + for ( i = 0; i < mapEnt->GetNumPrimitives(); i++ ) { + idMapPrimitive *mapPrim; + + mapPrim = mapEnt->GetPrimitive(i); + if ( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) { + ConvertBrush( model, static_cast(mapPrim), i ); + continue; + } + } + + // create an axial bsp tree for the model if it has more than just a bunch brushes + brushCount = CM_CountNodeBrushes( model->node ); + if ( brushCount > 4 ) { + model->node = CreateAxialBSPTree( model, model->node ); + } else { + model->node->planeType = -1; + } + + // get bounds for hash + if ( brushCount ) { + CM_GetNodeBounds( &bounds, model->node ); + } else { + bounds[0].Set( -256, -256, -256 ); + bounds[1].Set( 256, 256, 256 ); + } + + // different models do not share edges and vertices with each other, so clear the hash + ClearHash( bounds ); + + // create polygons from patches and brushes + for ( i = 0; i < mapEnt->GetNumPrimitives(); i++ ) { + idMapPrimitive *mapPrim; + + mapPrim = mapEnt->GetPrimitive(i); + if ( mapPrim->GetType() == idMapPrimitive::TYPE_PATCH ) { + ConvertPatch( model, static_cast(mapPrim), i ); + continue; + } + if ( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) { + ConvertBrushSides( model, static_cast(mapPrim), i ); + continue; + } + } + + FinishModel( model ); + + return model; +} + +/* +================ +idCollisionModelManagerLocal::FindModel +================ +*/ +cmHandle_t idCollisionModelManagerLocal::FindModel( const char *name ) { + int i; + + // check if this model is already loaded + for ( i = 0; i < numModels; i++ ) { + if ( !models[i]->name.Icmp( name ) ) { + break; + } + } + // if the model is already loaded + if ( i < numModels ) { + return i; + } + return -1; +} + +/* +================== +idCollisionModelManagerLocal::PrintModelInfo +================== +*/ +void idCollisionModelManagerLocal::PrintModelInfo( const cm_model_t *model ) { + common->Printf( "%6i vertices (%i KB)\n", model->numVertices, (model->numVertices * sizeof(cm_vertex_t))>>10 ); + common->Printf( "%6i edges (%i KB)\n", model->numEdges, (model->numEdges * sizeof(cm_edge_t))>>10 ); + common->Printf( "%6i polygons (%i KB)\n", model->numPolygons, model->polygonMemory>>10 ); + common->Printf( "%6i brushes (%i KB)\n", model->numBrushes, model->brushMemory>>10 ); + common->Printf( "%6i nodes (%i KB)\n", model->numNodes, (model->numNodes * sizeof(cm_node_t))>>10 ); + common->Printf( "%6i polygon refs (%i KB)\n", model->numPolygonRefs, (model->numPolygonRefs * sizeof(cm_polygonRef_t))>>10 ); + common->Printf( "%6i brush refs (%i KB)\n", model->numBrushRefs, (model->numBrushRefs * sizeof(cm_brushRef_t))>>10 ); + common->Printf( "%6i internal edges\n", model->numInternalEdges ); + common->Printf( "%6i sharp edges\n", model->numSharpEdges ); + common->Printf( "%6i contained polygons removed\n", model->numRemovedPolys ); + common->Printf( "%6i polygons merged\n", model->numMergedPolys ); + common->Printf( "%6i KB total memory used\n", model->usedMemory>>10 ); +} + +/* +================ +idCollisionModelManagerLocal::AccumulateModelInfo +================ +*/ +void idCollisionModelManagerLocal::AccumulateModelInfo( cm_model_t *model ) { + int i; + + memset( model, 0, sizeof( *model ) ); + // accumulate statistics of all loaded models + for ( i = 0; i < numModels; i++ ) { + model->numVertices += models[i]->numVertices; + model->numEdges += models[i]->numEdges; + model->numPolygons += models[i]->numPolygons; + model->polygonMemory += models[i]->polygonMemory; + model->numBrushes += models[i]->numBrushes; + model->brushMemory += models[i]->brushMemory; + model->numNodes += models[i]->numNodes; + model->numBrushRefs += models[i]->numBrushRefs; + model->numPolygonRefs += models[i]->numPolygonRefs; + model->numInternalEdges += models[i]->numInternalEdges; + model->numSharpEdges += models[i]->numSharpEdges; + model->numRemovedPolys += models[i]->numRemovedPolys; + model->numMergedPolys += models[i]->numMergedPolys; + model->usedMemory += models[i]->usedMemory; + } +} + +/* +================ +idCollisionModelManagerLocal::ModelInfo +================ +*/ +void idCollisionModelManagerLocal::ModelInfo( cmHandle_t model ) { + cm_model_t modelInfo; + + if ( model == -1 ) { + AccumulateModelInfo( &modelInfo ); + PrintModelInfo( &modelInfo ); + return; + } + if ( model < 0 || model > MAX_SUBMODELS || model > maxModels ) { + common->Printf( "idCollisionModelManagerLocal::ModelInfo: invalid model handle\n" ); + return; + } + if ( !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::ModelInfo: invalid model\n" ); + return; + } + + PrintModelInfo( models[model] ); +} + +/* +================ +idCollisionModelManagerLocal::ListModels +================ +*/ +void idCollisionModelManagerLocal::ListModels( void ) { + int i, totalMemory; + + totalMemory = 0; + for ( i = 0; i < numModels; i++ ) { + common->Printf( "%4d: %5d KB %s\n", i, (models[i]->usedMemory>>10), models[i]->name.c_str() ); + totalMemory += models[i]->usedMemory; + } + common->Printf( "%4d KB in %d models\n", (totalMemory>>10), numModels ); +} + +/* +================ +idCollisionModelManagerLocal::BuildModels +================ +*/ +void idCollisionModelManagerLocal::BuildModels( const idMapFile *mapFile ) { + int i; + const idMapEntity *mapEnt; + + idTimer timer; + timer.Start(); + + if ( !LoadCollisionModelFile( mapFile->GetName(), mapFile->GetGeometryCRC() ) ) { + + if ( !mapFile->GetNumEntities() ) { + return; + } + + // load the .proc file bsp for data optimisation + LoadProcBSP( mapFile->GetName() ); + + // convert brushes and patches to collision data + for ( i = 0; i < mapFile->GetNumEntities(); i++ ) { + mapEnt = mapFile->GetEntity(i); + + if ( numModels >= MAX_SUBMODELS ) { + common->Error( "idCollisionModelManagerLocal::BuildModels: more than %d collision models", MAX_SUBMODELS ); + break; + } + models[numModels] = CollisionModelForMapEntity( mapEnt ); + if ( models[ numModels] ) { + numModels++; + } + } + + // free the proc bsp which is only used for data optimization + Mem_Free( procNodes ); + procNodes = NULL; + + // write the collision models to a file + WriteCollisionModelsToFile( mapFile->GetName(), 0, numModels, mapFile->GetGeometryCRC() ); + } + + timer.Stop(); + + // print statistics on collision data + cm_model_t model; + AccumulateModelInfo( &model ); + common->Printf( "collision data:\n" ); + common->Printf( "%6i models\n", numModels ); + PrintModelInfo( &model ); + common->Printf( "%.0f msec to load collision data.\n", timer.Milliseconds() ); +} + + +/* +================ +idCollisionModelManagerLocal::LoadMap +================ +*/ +void idCollisionModelManagerLocal::LoadMap( const idMapFile *mapFile ) { + + if ( mapFile == NULL ) { + common->Error( "idCollisionModelManagerLocal::LoadMap: NULL mapFile" ); + } + + // check whether we can keep the current collision map based on the mapName and mapFileTime + if ( loaded ) { + if ( mapName.Icmp( mapFile->GetName() ) == 0 ) { + if ( mapFile->GetFileTime() == mapFileTime ) { + common->DPrintf( "Using loaded version\n" ); + return; + } + common->DPrintf( "Reloading modified map\n" ); + } + FreeMap(); + } + + // clear the collision map + Clear(); + + // models + maxModels = MAX_SUBMODELS; + numModels = 0; + models = (cm_model_t **) Mem_ClearedAlloc( (maxModels+1) * sizeof(cm_model_t *) ); + + // setup hash to speed up finding shared vertices and edges + SetupHash(); + + // setup trace model structure + SetupTrmModelStructure(); + + // build collision models + BuildModels( mapFile ); + + // save name and time stamp + mapName = mapFile->GetName(); + mapFileTime = mapFile->GetFileTime(); + loaded = true; + + // shutdown the hash + ShutdownHash(); +} + +/* +=================== +idCollisionModelManagerLocal::GetModelName +=================== +*/ +const char *idCollisionModelManagerLocal::GetModelName( cmHandle_t model ) const { + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelBounds: invalid model handle\n" ); + return ""; + } + return models[model]->name.c_str(); +} + +/* +=================== +idCollisionModelManagerLocal::GetModelBounds +=================== +*/ +bool idCollisionModelManagerLocal::GetModelBounds( cmHandle_t model, idBounds &bounds ) const { + + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelBounds: invalid model handle\n" ); + return false; + } + + bounds = models[model]->bounds; + return true; +} + +/* +=================== +idCollisionModelManagerLocal::GetModelContents +=================== +*/ +bool idCollisionModelManagerLocal::GetModelContents( cmHandle_t model, int &contents ) const { + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelContents: invalid model handle\n" ); + return false; + } + + contents = models[model]->contents; + + return true; +} + +/* +=================== +idCollisionModelManagerLocal::GetModelVertex +=================== +*/ +bool idCollisionModelManagerLocal::GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const { + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelVertex: invalid model handle\n" ); + return false; + } + + if ( vertexNum < 0 || vertexNum >= models[model]->numVertices ) { + common->Printf( "idCollisionModelManagerLocal::GetModelVertex: invalid vertex number\n" ); + return false; + } + + vertex = models[model]->vertices[vertexNum].p; + + return true; +} + +/* +=================== +idCollisionModelManagerLocal::GetModelEdge +=================== +*/ +bool idCollisionModelManagerLocal::GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const { + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelEdge: invalid model handle\n" ); + return false; + } + + edgeNum = abs( edgeNum ); + if ( edgeNum >= models[model]->numEdges ) { + common->Printf( "idCollisionModelManagerLocal::GetModelEdge: invalid edge number\n" ); + return false; + } + + start = models[model]->vertices[models[model]->edges[edgeNum].vertexNum[0]].p; + end = models[model]->vertices[models[model]->edges[edgeNum].vertexNum[1]].p; + + return true; +} + +/* +=================== +idCollisionModelManagerLocal::GetModelPolygon +=================== +*/ +bool idCollisionModelManagerLocal::GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const { + int i, edgeNum; + cm_polygon_t *poly; + + if ( model < 0 || model > MAX_SUBMODELS || model >= numModels || !models[model] ) { + common->Printf( "idCollisionModelManagerLocal::GetModelPolygon: invalid model handle\n" ); + return false; + } + + poly = *reinterpret_cast(&polygonNum); + winding.Clear(); + for ( i = 0; i < poly->numEdges; i++ ) { + edgeNum = poly->edges[i]; + winding += models[model]->vertices[ models[model]->edges[abs(edgeNum)].vertexNum[INTSIGNBITSET(edgeNum)] ].p; + } + + return true; +} + +/* +================== +idCollisionModelManagerLocal::LoadModel +================== +*/ +cmHandle_t idCollisionModelManagerLocal::LoadModel( const char *modelName, const bool precache ) { + int handle; + + handle = FindModel( modelName ); + if ( handle >= 0 ) { + return handle; + } + + if ( numModels >= MAX_SUBMODELS ) { + common->Error( "idCollisionModelManagerLocal::LoadModel: no free slots\n" ); + return 0; + } + + // try to load a .cm file + if ( LoadCollisionModelFile( modelName, 0 ) ) { + handle = FindModel( modelName ); + if ( handle >= 0 ) { + return handle; + } else { + common->Warning( "idCollisionModelManagerLocal::LoadModel: collision file for '%s' contains different model", modelName ); + } + } + + // if only precaching .cm files do not waste memory converting render models + if ( precache ) { + return 0; + } + + // try to load a .ASE or .LWO model and convert it to a collision model + models[numModels] = LoadRenderModel( modelName ); + if ( models[numModels] != NULL ) { + numModels++; + return ( numModels - 1 ); + } + + return 0; +} + +/* +================== +idCollisionModelManagerLocal::TrmFromModel_r +================== +*/ +bool idCollisionModelManagerLocal::TrmFromModel_r( idTraceModel &trm, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_polygon_t *p; + int i; + + while ( 1 ) { + for ( pref = node->polygons; pref; pref = pref->next ) { + p = pref->p; + + if ( p->checkcount == checkCount ) { + continue; + } + + p->checkcount = checkCount; + + if ( trm.numPolys >= MAX_TRACEMODEL_POLYS ) { + return false; + } + // copy polygon properties + trm.polys[ trm.numPolys ].bounds = p->bounds; + trm.polys[ trm.numPolys ].normal = p->plane.Normal(); + trm.polys[ trm.numPolys ].dist = p->plane.Dist(); + trm.polys[ trm.numPolys ].numEdges = p->numEdges; + // copy edge index + for ( i = 0; i < p->numEdges; i++ ) { + trm.polys[ trm.numPolys ].edges[ i ] = p->edges[ i ]; + } + trm.numPolys++; + } + if ( node->planeType == -1 ) { + break; + } + if ( !TrmFromModel_r( trm, node->children[1] ) ) { + return false; + } + node = node->children[0]; + } + return true; +} + +/* +================== +idCollisionModelManagerLocal::TrmFromModel + + NOTE: polygon merging can merge colinear edges and as such might cause dangling edges. +================== +*/ +bool idCollisionModelManagerLocal::TrmFromModel( const cm_model_t *model, idTraceModel &trm ) { + int i, j, numEdgeUsers[MAX_TRACEMODEL_EDGES+1]; + + // if the model has too many vertices to fit in a trace model + if ( model->numVertices > MAX_TRACEMODEL_VERTS ) { + common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s has too many vertices.\n", model->name.c_str() ); + PrintModelInfo( model ); + return false; + } + + // plus one because the collision model accounts for the first unused edge + if ( model->numEdges > MAX_TRACEMODEL_EDGES+1 ) { + common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s has too many edges.\n", model->name.c_str() ); + PrintModelInfo( model ); + return false; + } + + trm.type = TRM_CUSTOM; + trm.numVerts = 0; + trm.numEdges = 1; + trm.numPolys = 0; + trm.bounds.Clear(); + + // copy polygons + checkCount++; + if ( !TrmFromModel_r( trm, model->node ) ) { + common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s has too many polygons.\n", model->name.c_str() ); + PrintModelInfo( model ); + return false; + } + + // copy vertices + for ( i = 0; i < model->numVertices; i++ ) { + trm.verts[ i ] = model->vertices[ i ].p; + trm.bounds.AddPoint( trm.verts[ i ] ); + } + trm.numVerts = model->numVertices; + + // copy edges + for ( i = 0; i < model->numEdges; i++ ) { + trm.edges[ i ].v[0] = model->edges[ i ].vertexNum[0]; + trm.edges[ i ].v[1] = model->edges[ i ].vertexNum[1]; + } + // minus one because the collision model accounts for the first unused edge + trm.numEdges = model->numEdges - 1; + + // each edge should be used exactly twice + memset( numEdgeUsers, 0, sizeof(numEdgeUsers) ); + for ( i = 0; i < trm.numPolys; i++ ) { + for ( j = 0; j < trm.polys[i].numEdges; j++ ) { + numEdgeUsers[ abs( trm.polys[i].edges[j] ) ]++; + } + } + for ( i = 1; i <= trm.numEdges; i++ ) { + if ( numEdgeUsers[i] != 2 ) { + common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s has dangling edges, the model has to be an enclosed hull.\n", model->name.c_str() ); + PrintModelInfo( model ); + return false; + } + } + + // assume convex + trm.isConvex = true; + // check if really convex + for ( i = 0; i < trm.numPolys; i++ ) { + // to be convex no vertices should be in front of any polygon plane + for ( j = 0; j < trm.numVerts; j++ ) { + if ( trm.polys[ i ].normal * trm.verts[ j ] - trm.polys[ i ].dist > 0.01f ) { + trm.isConvex = false; + break; + } + } + if ( j < trm.numVerts ) { + break; + } + } + + // offset to center of model + trm.offset = trm.bounds.GetCenter(); + + trm.GenerateEdgeNormals(); + + return true; +} + +/* +================== +idCollisionModelManagerLocal::TrmFromModel +================== +*/ +bool idCollisionModelManagerLocal::TrmFromModel( const char *modelName, idTraceModel &trm ) { + cmHandle_t handle; + + handle = LoadModel( modelName, false ); + if ( !handle ) { + common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s not found.\n", modelName ); + return false; + } + + return TrmFromModel( models[ handle ], trm ); +} diff --git a/cm/CollisionModel_local.h b/cm/CollisionModel_local.h new file mode 100644 index 000000000..564c9cc65 --- /dev/null +++ b/cm/CollisionModel_local.h @@ -0,0 +1,518 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "CollisionModel.h" + +#define MIN_NODE_SIZE 64.0f +#define MAX_NODE_POLYGONS 128 +#define CM_MAX_POLYGON_EDGES 64 +#define CIRCLE_APPROXIMATION_LENGTH 64.0f + +#define MAX_SUBMODELS 2048 +#define TRACE_MODEL_HANDLE MAX_SUBMODELS + +#define VERTEX_HASH_BOXSIZE (1<<6) // must be power of 2 +#define VERTEX_HASH_SIZE (VERTEX_HASH_BOXSIZE*VERTEX_HASH_BOXSIZE) +#define EDGE_HASH_SIZE (1<<14) + +#define NODE_BLOCK_SIZE_SMALL 8 +#define NODE_BLOCK_SIZE_LARGE 256 +#define REFERENCE_BLOCK_SIZE_SMALL 8 +#define REFERENCE_BLOCK_SIZE_LARGE 256 + +#define MAX_WINDING_LIST 128 // quite a few are generated at times +#define INTEGRAL_EPSILON 0.01f +#define VERTEX_EPSILON 0.1f +#define CHOP_EPSILON 0.1f + + +typedef struct cm_windingList_s { + int numWindings; // number of windings + idFixedWinding w[MAX_WINDING_LIST]; // windings + idVec3 normal; // normal for all windings + idBounds bounds; // bounds of all windings in list + idVec3 origin; // origin for radius + float radius; // radius relative to origin for all windings + int contents; // winding surface contents + int primitiveNum; // number of primitive the windings came from +} cm_windingList_t; + +/* +=============================================================================== + +Collision model + +=============================================================================== +*/ + +typedef struct cm_vertex_s { + idVec3 p; // vertex point + int checkcount; // for multi-check avoidance + unsigned long side; // each bit tells at which side this vertex passes one of the trace model edges + unsigned long sideSet; // each bit tells if sidedness for the trace model edge has been calculated yet +} cm_vertex_t; + +typedef struct cm_edge_s { + int checkcount; // for multi-check avoidance + unsigned short internal; // a trace model can never collide with internal edges + unsigned short numUsers; // number of polygons using this edge + unsigned long side; // each bit tells at which side of this edge one of the trace model vertices passes + unsigned long sideSet; // each bit tells if sidedness for the trace model vertex has been calculated yet + int vertexNum[2]; // start and end point of edge + idVec3 normal; // edge normal +} cm_edge_t; + +typedef struct cm_polygonBlock_s { + int bytesRemaining; + byte * next; +} cm_polygonBlock_t; + +typedef struct cm_polygon_s { + idBounds bounds; // polygon bounds + int checkcount; // for multi-check avoidance + int contents; // contents behind polygon + const idMaterial * material; // material + idPlane plane; // polygon plane + int numEdges; // number of edges + int edges[1]; // variable sized, indexes into cm_edge_t list +} cm_polygon_t; + +typedef struct cm_polygonRef_s { + cm_polygon_t * p; // pointer to polygon + struct cm_polygonRef_s *next; // next polygon in chain +} cm_polygonRef_t; + +typedef struct cm_polygonRefBlock_s { + cm_polygonRef_t * nextRef; // next polygon reference in block + struct cm_polygonRefBlock_s *next; // next block with polygon references +} cm_polygonRefBlock_t; + +typedef struct cm_brushBlock_s { + int bytesRemaining; + byte * next; +} cm_brushBlock_t; + +typedef struct cm_brush_s { + int checkcount; // for multi-check avoidance + idBounds bounds; // brush bounds + int contents; // contents of brush + const idMaterial * material; // material + int primitiveNum; // number of brush primitive + int numPlanes; // number of bounding planes + idPlane planes[1]; // variable sized +} cm_brush_t; + +typedef struct cm_brushRef_s { + cm_brush_t * b; // pointer to brush + struct cm_brushRef_s * next; // next brush in chain +} cm_brushRef_t; + +typedef struct cm_brushRefBlock_s { + cm_brushRef_t * nextRef; // next brush reference in block + struct cm_brushRefBlock_s *next; // next block with brush references +} cm_brushRefBlock_t; + +typedef struct cm_node_s { + int planeType; // node axial plane type + float planeDist; // node plane distance + cm_polygonRef_t * polygons; // polygons in node + cm_brushRef_t * brushes; // brushes in node + struct cm_node_s * parent; // parent of this node + struct cm_node_s * children[2]; // node children +} cm_node_t; + +typedef struct cm_nodeBlock_s { + cm_node_t * nextNode; // next node in block + struct cm_nodeBlock_s *next; // next block with nodes +} cm_nodeBlock_t; + +typedef struct cm_model_s { + idStr name; // model name + idBounds bounds; // model bounds + int contents; // all contents of the model ored together + bool isConvex; // set if model is convex + // model geometry + int maxVertices; // size of vertex array + int numVertices; // number of vertices + cm_vertex_t * vertices; // array with all vertices used by the model + int maxEdges; // size of edge array + int numEdges; // number of edges + cm_edge_t * edges; // array with all edges used by the model + cm_node_t * node; // first node of spatial subdivision + // blocks with allocated memory + cm_nodeBlock_t * nodeBlocks; // list with blocks of nodes + cm_polygonRefBlock_t * polygonRefBlocks; // list with blocks of polygon references + cm_brushRefBlock_t * brushRefBlocks; // list with blocks of brush references + cm_polygonBlock_t * polygonBlock; // memory block with all polygons + cm_brushBlock_t * brushBlock; // memory block with all brushes + // statistics + int numPolygons; + int polygonMemory; + int numBrushes; + int brushMemory; + int numNodes; + int numBrushRefs; + int numPolygonRefs; + int numInternalEdges; + int numSharpEdges; + int numRemovedPolys; + int numMergedPolys; + int usedMemory; +} cm_model_t; + +/* +=============================================================================== + +Data used during collision detection calculations + +=============================================================================== +*/ + +typedef struct cm_trmVertex_s { + int used; // true if this vertex is used for collision detection + idVec3 p; // vertex position + idVec3 endp; // end point of vertex after movement + int polygonSide; // side of polygon this vertex is on (rotational collision) + idPluecker pl; // pluecker coordinate for vertex movement + idVec3 rotationOrigin; // rotation origin for this vertex + idBounds rotationBounds; // rotation bounds for this vertex +} cm_trmVertex_t; + +typedef struct cm_trmEdge_s { + int used; // true when vertex is used for collision detection + idVec3 start; // start of edge + idVec3 end; // end of edge + int vertexNum[2]; // indexes into cm_traceWork_t->vertices + idPluecker pl; // pluecker coordinate for edge + idVec3 cross; // (z,-y,x) of cross product between edge dir and movement dir + idBounds rotationBounds; // rotation bounds for this edge + idPluecker plzaxis; // pluecker coordinate for rotation about the z-axis + unsigned short bitNum; // vertex bit number +} cm_trmEdge_t; + +typedef struct cm_trmPolygon_s { + int used; + idPlane plane; // polygon plane + int numEdges; // number of edges + int edges[MAX_TRACEMODEL_POLYEDGES]; // index into cm_traceWork_t->edges + idBounds rotationBounds; // rotation bounds for this polygon +} cm_trmPolygon_t; + +typedef struct cm_traceWork_s { + int numVerts; + cm_trmVertex_t vertices[MAX_TRACEMODEL_VERTS]; // trm vertices + int numEdges; + cm_trmEdge_t edges[MAX_TRACEMODEL_EDGES+1]; // trm edges + int numPolys; + cm_trmPolygon_t polys[MAX_TRACEMODEL_POLYS]; // trm polygons + cm_model_t *model; // model colliding with + idVec3 start; // start of trace + idVec3 end; // end of trace + idVec3 dir; // trace direction + idBounds bounds; // bounds of full trace + idBounds size; // bounds of transformed trm relative to start + idVec3 extents; // largest of abs(size[0]) and abs(size[1]) for BSP trace + int contents; // ignore polygons that do not have any of these contents flags + trace_t trace; // collision detection result + + bool rotation; // true if calculating rotational collision + bool pointTrace; // true if only tracing a point + bool positionTest; // true if not tracing but doing a position test + bool isConvex; // true if the trace model is convex + bool axisIntersectsTrm; // true if the rotation axis intersects the trace model + bool getContacts; // true if retrieving contacts + bool quickExit; // set to quickly stop the collision detection calculations + + idVec3 origin; // origin of rotation in model space + idVec3 axis; // rotation axis in model space + idMat3 matrix; // rotates axis of rotation to the z-axis + float angle; // angle for rotational collision + float maxTan; // max tangent of half the positive angle used instead of fraction + float radius; // rotation radius of trm start + idRotation modelVertexRotation; // inverse rotation for model vertices + + contactInfo_t *contacts; // array with contacts + int maxContacts; // max size of contact array + int numContacts; // number of contacts found + + idPlane heartPlane1; // polygons should be near anough the trace heart planes + float maxDistFromHeartPlane1; + idPlane heartPlane2; + float maxDistFromHeartPlane2; + idPluecker polygonEdgePlueckerCache[CM_MAX_POLYGON_EDGES]; + idPluecker polygonVertexPlueckerCache[CM_MAX_POLYGON_EDGES]; + idVec3 polygonRotationOriginCache[CM_MAX_POLYGON_EDGES]; +} cm_traceWork_t; + +/* +=============================================================================== + +Collision Map + +=============================================================================== +*/ + +typedef struct cm_procNode_s { + idPlane plane; + int children[2]; // negative numbers are (-1 - areaNumber), 0 = solid +} cm_procNode_t; + +class idCollisionModelManagerLocal : public idCollisionModelManager { +public: + // load collision models from a map file + void LoadMap( const idMapFile *mapFile ); + // frees all the collision models + void FreeMap( void ); + + // get clip handle for model + cmHandle_t LoadModel( const char *modelName, const bool precache ); + // sets up a trace model for collision with other trace models + cmHandle_t SetupTrmModel( const idTraceModel &trm, const idMaterial *material ); + // create trace model from a collision model, returns true if succesfull + bool TrmFromModel( const char *modelName, idTraceModel &trm ); + + // name of the model + const char * GetModelName( cmHandle_t model ) const; + // bounds of the model + bool GetModelBounds( cmHandle_t model, idBounds &bounds ) const; + // all contents flags of brushes and polygons ored together + bool GetModelContents( cmHandle_t model, int &contents ) const; + // get the vertex of a model + bool GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const; + // get the edge of a model + bool GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const; + // get the polygon of a model + bool GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const; + + // translates a trm and reports the first collision if any + void Translation( trace_t *results, const idVec3 &start, const idVec3 &end, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + // rotates a trm and reports the first collision if any + void Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + // returns the contents the trm is stuck in or 0 if the trm is in free space + int Contents( const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + // stores all contact points of the trm with the model, returns the number of contacts + int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + // test collision detection + void DebugOutput( const idVec3 &origin ); + // draw a model + void DrawModel( cmHandle_t model, const idVec3 &origin, const idMat3 &axis, + const idVec3 &viewOrigin, const float radius ); + // print model information, use -1 handle for accumulated model info + void ModelInfo( cmHandle_t model ); + // list all loaded models + void ListModels( void ); + // write a collision model file for the map entity + bool WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ); + +private: // CollisionMap_translate.cpp + int TranslateEdgeThroughEdge( idVec3 &cross, idPluecker &l1, idPluecker &l2, float *fraction ); + void TranslateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ); + void TranslateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int bitNum ); + void TranslatePointThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v ); + void TranslateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, cm_vertex_t *v, idVec3 &endp, idPluecker &pl ); + bool TranslateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); + void SetupTranslationHeartPlanes( cm_traceWork_t *tw ); + void SetupTrm( cm_traceWork_t *tw, const idTraceModel *trm ); + +private: // CollisionMap_rotate.cpp + int CollisionBetweenEdgeBounds( cm_traceWork_t *tw, const idVec3 &va, const idVec3 &vb, + const idVec3 &vc, const idVec3 &vd, float tanHalfAngle, + idVec3 &collisionPoint, idVec3 &collisionNormal ); + int RotateEdgeThroughEdge( cm_traceWork_t *tw, const idPluecker &pl1, + const idVec3 &vc, const idVec3 &vd, + const float minTan, float &tanHalfAngle ); + int EdgeFurthestFromEdge( cm_traceWork_t *tw, const idPluecker &pl1, + const idVec3 &vc, const idVec3 &vd, + float &tanHalfAngle, float &dir ); + void RotateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ); + int RotatePointThroughPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, + const float angle, const float minTan, float &tanHalfAngle ); + int PointFurthestFromPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, + const float angle, float &tanHalfAngle, float &dir ); + int RotatePointThroughEpsilonPlane( const cm_traceWork_t *tw, const idVec3 &point, const idVec3 &endPoint, + const idPlane &plane, const float angle, const idVec3 &origin, + float &tanHalfAngle, idVec3 &collisionPoint, idVec3 &endDir ); + void RotateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int vertexNum); + void RotateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, + cm_vertex_t *v, idVec3 &rotationOrigin ); + bool RotateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); + void BoundsForRotation( const idVec3 &origin, const idVec3 &axis, const idVec3 &start, const idVec3 &end, idBounds &bounds ); + void Rotation180( trace_t *results, const idVec3 &rorg, const idVec3 &axis, + const float startAngle, const float endAngle, const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ); + +private: // CollisionMap_contents.cpp + bool TestTrmVertsInBrush( cm_traceWork_t *tw, cm_brush_t *b ); + bool TestTrmInPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); + cm_node_t * PointNode( const idVec3 &p, cm_model_t *model ); + int PointContents( const idVec3 p, cmHandle_t model ); + int TransformedPointContents( const idVec3 &p, cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ); + int ContentsTrm( trace_t *results, const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + +private: // CollisionMap_trace.cpp + void TraceTrmThroughNode( cm_traceWork_t *tw, cm_node_t *node ); + void TraceThroughAxialBSPTree_r( cm_traceWork_t *tw, cm_node_t *node, float p1f, float p2f, idVec3 &p1, idVec3 &p2); + void TraceThroughModel( cm_traceWork_t *tw ); + void RecurseProcBSP_r( trace_t *results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3 &p1, const idVec3 &p2 ); + +private: // CollisionMap_load.cpp + void Clear( void ); + void FreeTrmModelStructure( void ); + // model deallocation + void RemovePolygonReferences_r( cm_node_t *node, cm_polygon_t *p ); + void RemoveBrushReferences_r( cm_node_t *node, cm_brush_t *b ); + void FreeNode( cm_node_t *node ); + void FreePolygonReference( cm_polygonRef_t *pref ); + void FreeBrushReference( cm_brushRef_t *bref ); + void FreePolygon( cm_model_t *model, cm_polygon_t *poly ); + void FreeBrush( cm_model_t *model, cm_brush_t *brush ); + void FreeTree_r( cm_model_t *model, cm_node_t *headNode, cm_node_t *node ); + void FreeModel( cm_model_t *model ); + // merging polygons + void ReplacePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *p1, cm_polygon_t *p2, cm_polygon_t *newp ); + cm_polygon_t * TryMergePolygons( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ); + bool MergePolygonWithTreePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ); + void MergeTreePolygons( cm_model_t *model, cm_node_t *node ); + // finding internal edges + bool PointInsidePolygon( cm_model_t *model, cm_polygon_t *p, idVec3 &v ); + void FindInternalEdgesOnPolygon( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ); + void FindInternalPolygonEdges( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ); + void FindInternalEdges( cm_model_t *model, cm_node_t *node ); + void FindContainedEdges( cm_model_t *model, cm_polygon_t *p ); + // loading of proc BSP tree + void ParseProcNodes( idLexer *src ); + void LoadProcBSP( const char *name ); + // removal of contained polygons + int R_ChoppedAwayByProcBSP( int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius ); + int ChoppedAwayByProcBSP( const idFixedWinding &w, const idPlane &plane, int contents ); + void ChopWindingListWithBrush( cm_windingList_t *list, cm_brush_t *b ); + void R_ChopWindingListWithTreeBrushes( cm_windingList_t *list, cm_node_t *node ); + idFixedWinding *WindingOutsideBrushes( idFixedWinding *w, const idPlane &plane, int contents, int patch, cm_node_t *headNode ); + // creation of axial BSP tree + cm_model_t * AllocModel( void ); + cm_node_t * AllocNode( cm_model_t *model, int blockSize ); + cm_polygonRef_t*AllocPolygonReference( cm_model_t *model, int blockSize ); + cm_brushRef_t * AllocBrushReference( cm_model_t *model, int blockSize ); + cm_polygon_t * AllocPolygon( cm_model_t *model, int numEdges ); + cm_brush_t * AllocBrush( cm_model_t *model, int numPlanes ); + void AddPolygonToNode( cm_model_t *model, cm_node_t *node, cm_polygon_t *p ); + void AddBrushToNode( cm_model_t *model, cm_node_t *node, cm_brush_t *b ); + void SetupTrmModelStructure( void ); + void R_FilterPolygonIntoTree( cm_model_t *model, cm_node_t *node, cm_polygonRef_t *pref, cm_polygon_t *p ); + void R_FilterBrushIntoTree( cm_model_t *model, cm_node_t *node, cm_brushRef_t *pref, cm_brush_t *b ); + cm_node_t * R_CreateAxialBSPTree( cm_model_t *model, cm_node_t *node, const idBounds &bounds ); + cm_node_t * CreateAxialBSPTree( cm_model_t *model, cm_node_t *node ); + // creation of raw polygons + void SetupHash(void); + void ShutdownHash(void); + void ClearHash( idBounds &bounds ); + int HashVec(const idVec3 &vec); + int GetVertex( cm_model_t *model, const idVec3 &v, int *vertexNum ); + int GetEdge( cm_model_t *model, const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num ); + void CreatePolygon( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ); + void PolygonFromWinding( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ); + void CalculateEdgeNormals( cm_model_t *model, cm_node_t *node ); + void CreatePatchPolygons( cm_model_t *model, idSurface_Patch &mesh, const idMaterial *material, int primitiveNum ); + void ConvertPatch( cm_model_t *model, const idMapPatch *patch, int primitiveNum ); + void ConvertBrushSides( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ); + void ConvertBrush( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ); + void PrintModelInfo( const cm_model_t *model ); + void AccumulateModelInfo( cm_model_t *model ); + void RemapEdges( cm_node_t *node, int *edgeRemap ); + void OptimizeArrays( cm_model_t *model ); + void FinishModel( cm_model_t *model ); + void BuildModels( const idMapFile *mapFile ); + cmHandle_t FindModel( const char *name ); + cm_model_t * CollisionModelForMapEntity( const idMapEntity *mapEnt ); // brush/patch model from .map + cm_model_t * LoadRenderModel( const char *fileName ); // ASE/LWO models + bool TrmFromModel_r( idTraceModel &trm, cm_node_t *node ); + bool TrmFromModel( const cm_model_t *model, idTraceModel &trm ); + +private: // CollisionMap_files.cpp + // writing + void WriteNodes( idFile *fp, cm_node_t *node ); + int CountPolygonMemory( cm_node_t *node ) const; + void WritePolygons( idFile *fp, cm_node_t *node ); + int CountBrushMemory( cm_node_t *node ) const; + void WriteBrushes( idFile *fp, cm_node_t *node ); + void WriteCollisionModel( idFile *fp, cm_model_t *model ); + void WriteCollisionModelsToFile( const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC ); + // loading + cm_node_t * ParseNodes( idLexer *src, cm_model_t *model, cm_node_t *parent ); + void ParseVertices( idLexer *src, cm_model_t *model ); + void ParseEdges( idLexer *src, cm_model_t *model ); + void ParsePolygons( idLexer *src, cm_model_t *model ); + void ParseBrushes( idLexer *src, cm_model_t *model ); + bool ParseCollisionModel( idLexer *src ); + bool LoadCollisionModelFile( const char *name, unsigned int mapFileCRC ); + +private: // CollisionMap_debug + int ContentsFromString( const char *string ) const; + const char * StringFromContents( const int contents ) const; + void DrawEdge( cm_model_t *model, int edgeNum, const idVec3 &origin, const idMat3 &axis ); + void DrawPolygon( cm_model_t *model, cm_polygon_t *p, const idVec3 &origin, const idMat3 &axis, + const idVec3 &viewOrigin ); + void DrawNodePolygons( cm_model_t *model, cm_node_t *node, const idVec3 &origin, const idMat3 &axis, + const idVec3 &viewOrigin, const float radius ); + +private: // collision map data + idStr mapName; + ID_TIME_T mapFileTime; + int loaded; + // for multi-check avoidance + int checkCount; + // models + int maxModels; + int numModels; + cm_model_t ** models; + // polygons and brush for trm model + cm_polygonRef_t*trmPolygons[MAX_TRACEMODEL_POLYS]; + cm_brushRef_t * trmBrushes[1]; + const idMaterial *trmMaterial; + // for data pruning + int numProcNodes; + cm_procNode_t * procNodes; + // for retrieving contact points + bool getContacts; + contactInfo_t * contacts; + int maxContacts; + int numContacts; +}; + +// for debugging +extern idCVar cm_debugCollision; diff --git a/cm/CollisionModel_rotate.cpp b/cm/CollisionModel_rotate.cpp new file mode 100644 index 000000000..1a5ca0b87 --- /dev/null +++ b/cm/CollisionModel_rotate.cpp @@ -0,0 +1,1685 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +/* +=============================================================================== + +Collision detection for rotational motion + +=============================================================================== +*/ + +// epsilon for round-off errors in epsilon calculations +#define CM_PL_RANGE_EPSILON 1e-4f +// if the collision point is this close to the rotation axis it is not considered a collision +#define ROTATION_AXIS_EPSILON (CM_CLIP_EPSILON*0.25f) + + +/* +================ +CM_RotatePoint + + rotates a point about an arbitrary axis using the tangent of half the rotation angle +================ +*/ +void CM_RotatePoint( idVec3 &point, const idVec3 &origin, const idVec3 &axis, const float tanHalfAngle ) { + double d, t, s, c; + idVec3 proj, v1, v2; + + point -= origin; + proj = axis * ( point * axis ); + v1 = point - proj; + v2 = axis.Cross( v1 ); + + // r = tan( a / 2 ); + // sin(a) = 2*r/(1+r*r); + // cos(a) = (1-r*r)/(1+r*r); + t = tanHalfAngle * tanHalfAngle; + d = 1.0f / ( 1.0f + t ); + s = 2.0f * tanHalfAngle * d; + c = ( 1.0f - t ) * d; + + point = v1 * c - v2 * s + proj + origin; +} + +/* +================ +CM_RotateEdge + + rotates an edge about an arbitrary axis using the tangent of half the rotation angle +================ +*/ +void CM_RotateEdge( idVec3 &start, idVec3 &end, const idVec3 &origin, const idVec3 &axis, const float tanHalfAngle ) { + double d, t, s, c; + idVec3 proj, v1, v2; + + // r = tan( a / 2 ); + // sin(a) = 2*r/(1+r*r); + // cos(a) = (1-r*r)/(1+r*r); + t = tanHalfAngle * tanHalfAngle; + d = 1.0f / ( 1.0f + t ); + s = 2.0f * tanHalfAngle * d; + c = ( 1.0f - t ) * d; + + start -= origin; + proj = axis * ( start * axis ); + v1 = start - proj; + v2 = axis.Cross( v1 ); + start = v1 * c - v2 * s + proj + origin; + + end -= origin; + proj = axis * ( end * axis ); + v1 = end - proj; + v2 = axis.Cross( v1 ); + end = v1 * c - v2 * s + proj + origin; +} + +/* +================ +idCollisionModelManagerLocal::CollisionBetweenEdgeBounds + + verifies if the collision of two edges occurs between the edge bounds + also calculates the collision point and collision plane normal if the collision occurs between the bounds +================ +*/ +int idCollisionModelManagerLocal::CollisionBetweenEdgeBounds( cm_traceWork_t *tw, const idVec3 &va, const idVec3 &vb, + const idVec3 &vc, const idVec3 &vd, float tanHalfAngle, + idVec3 &collisionPoint, idVec3 &collisionNormal ) { + float d1, d2, d; + idVec3 at, bt, dir, dir1, dir2; + idPluecker pl1, pl2; + + at = va; + bt = vb; + if ( tanHalfAngle != 0.0f ) { + CM_RotateEdge( at, bt, tw->origin, tw->axis, tanHalfAngle ); + } + + dir1 = (at - tw->origin).Cross( tw->axis ); + dir2 = (bt - tw->origin).Cross( tw->axis ); + if ( dir1 * dir1 > dir2 * dir2 ) { + dir = dir1; + } + else { + dir = dir2; + } + if ( tw->angle < 0.0f ) { + dir = -dir; + } + + pl1.FromLine( at, bt ); + pl2.FromRay( vc, dir ); + d1 = pl1.PermutedInnerProduct( pl2 ); + pl2.FromRay( vd, dir ); + d2 = pl1.PermutedInnerProduct( pl2 ); + if ( ( d1 > 0.0f && d2 > 0.0f ) || ( d1 < 0.0f && d2 < 0.0f ) ) { + return false; + } + + pl1.FromLine( vc, vd ); + pl2.FromRay( at, dir ); + d1 = pl1.PermutedInnerProduct( pl2 ); + pl2.FromRay( bt, dir ); + d2 = pl1.PermutedInnerProduct( pl2 ); + if ( ( d1 > 0.0f && d2 > 0.0f ) || ( d1 < 0.0f && d2 < 0.0f ) ) { + return false; + } + + // collision point on the edge at-bt + dir1 = (vd - vc).Cross( dir ); + d = dir1 * vc; + d1 = dir1 * at - d; + d2 = dir1 * bt - d; + if ( d1 == d2 ) { + return false; + } + collisionPoint = at + ( d1 / (d1 - d2) ) * ( bt - at ); + + // normal is cross product of the rotated edge va-vb and the edge vc-vd + collisionNormal.Cross( bt-at, vd-vc ); + + return true; +} + +/* +================ +idCollisionModelManagerLocal::RotateEdgeThroughEdge + + calculates the tangent of half the rotation angle at which the edges collide +================ +*/ +int idCollisionModelManagerLocal::RotateEdgeThroughEdge( cm_traceWork_t *tw, const idPluecker &pl1, + const idVec3 &vc, const idVec3 &vd, + const float minTan, float &tanHalfAngle ) { + double v0, v1, v2, a, b, c, d, sqrtd, q, frac1, frac2; + idVec3 ct, dt; + idPluecker pl2; + + /* + + a = start of line being rotated + b = end of line being rotated + pl1 = pluecker coordinate for line (a - b) + pl2 = pluecker coordinate for edge we might collide with (c - d) + t = rotation angle around the z-axis + solve pluecker inner product for t of rotating line a-b and line l2 + + // start point of rotated line during rotation + an[0] = a[0] * cos(t) + a[1] * sin(t) + an[1] = a[0] * -sin(t) + a[1] * cos(t) + an[2] = a[2]; + // end point of rotated line during rotation + bn[0] = b[0] * cos(t) + b[1] * sin(t) + bn[1] = b[0] * -sin(t) + b[1] * cos(t) + bn[2] = b[2]; + + pl1[0] = a[0] * b[1] - b[0] * a[1]; + pl1[1] = a[0] * b[2] - b[0] * a[2]; + pl1[2] = a[0] - b[0]; + pl1[3] = a[1] * b[2] - b[1] * a[2]; + pl1[4] = a[2] - b[2]; + pl1[5] = b[1] - a[1]; + + v[0] = (a[0] * cos(t) + a[1] * sin(t)) * (b[0] * -sin(t) + b[1] * cos(t)) - (b[0] * cos(t) + b[1] * sin(t)) * (a[0] * -sin(t) + a[1] * cos(t)); + v[1] = (a[0] * cos(t) + a[1] * sin(t)) * b[2] - (b[0] * cos(t) + b[1] * sin(t)) * a[2]; + v[2] = (a[0] * cos(t) + a[1] * sin(t)) - (b[0] * cos(t) + b[1] * sin(t)); + v[3] = (a[0] * -sin(t) + a[1] * cos(t)) * b[2] - (b[0] * -sin(t) + b[1] * cos(t)) * a[2]; + v[4] = a[2] - b[2]; + v[5] = (b[0] * -sin(t) + b[1] * cos(t)) - (a[0] * -sin(t) + a[1] * cos(t)); + + pl2[0] * v[4] + pl2[1] * v[5] + pl2[2] * v[3] + pl2[4] * v[0] + pl2[5] * v[1] + pl2[3] * v[2] = 0; + + v[0] = (a[0] * cos(t) + a[1] * sin(t)) * (b[0] * -sin(t) + b[1] * cos(t)) - (b[0] * cos(t) + b[1] * sin(t)) * (a[0] * -sin(t) + a[1] * cos(t)); + v[0] = (a[1] * b[1] - a[0] * b[0]) * cos(t) * sin(t) + (a[0] * b[1] + a[1] * b[0] * cos(t)^2) - (a[1] * b[0]) - ((b[1] * a[1] - b[0] * a[0]) * cos(t) * sin(t) + (b[0] * a[1] + b[1] * a[0]) * cos(t)^2 - (b[1] * a[0])) + v[0] = - (a[1] * b[0]) - ( - (b[1] * a[0])) + v[0] = (b[1] * a[0]) - (a[1] * b[0]) + + v[0] = (a[0]*b[1]) - (a[1]*b[0]); + v[1] = (a[0]*b[2] - b[0]*a[2]) * cos(t) + (a[1]*b[2] - b[1]*a[2]) * sin(t); + v[2] = (a[0]-b[0]) * cos(t) + (a[1]-b[1]) * sin(t); + v[3] = (b[0]*a[2] - a[0]*b[2]) * sin(t) + (a[1]*b[2] - b[1]*a[2]) * cos(t); + v[4] = a[2] - b[2]; + v[5] = (a[0]-b[0]) * sin(t) + (b[1]-a[1]) * cos(t); + + v[0] = (a[0]*b[1]) - (a[1]*b[0]); + v[1] = (a[0]*b[2] - b[0]*a[2]) * cos(t) + (a[1]*b[2] - b[1]*a[2]) * sin(t); + v[2] = (a[0]-b[0]) * cos(t) - (b[1]-a[1]) * sin(t); + v[3] = (a[0]*b[2] - b[0]*a[2]) * -sin(t) + (a[1]*b[2] - b[1]*a[2]) * cos(t); + v[4] = a[2] - b[2]; + v[5] = (a[0]-b[0]) * sin(t) + (b[1]-a[1]) * cos(t); + + v[0] = pl1[0]; + v[1] = pl1[1] * cos(t) + pl1[3] * sin(t); + v[2] = pl1[2] * cos(t) - pl1[5] * sin(t); + v[3] = pl1[3] * cos(t) - pl1[1] * sin(t); + v[4] = pl1[4]; + v[5] = pl1[5] * cos(t) + pl1[2] * sin(t); + + pl2[0] * v[4] + pl2[1] * v[5] + pl2[2] * v[3] + pl2[4] * v[0] + pl2[5] * v[1] + pl2[3] * v[2] = 0; + + 0 = pl2[0] * pl1[4] + + pl2[1] * (pl1[5] * cos(t) + pl1[2] * sin(t)) + + pl2[2] * (pl1[3] * cos(t) - pl1[1] * sin(t)) + + pl2[4] * pl1[0] + + pl2[5] * (pl1[1] * cos(t) + pl1[3] * sin(t)) + + pl2[3] * (pl1[2] * cos(t) - pl1[5] * sin(t)); + + v2 * cos(t) + v1 * sin(t) + v0 = 0; + + // rotation about the z-axis + v0 = pl2[0] * pl1[4] + pl2[4] * pl1[0]; + v1 = pl2[1] * pl1[2] - pl2[2] * pl1[1] + pl2[5] * pl1[3] - pl2[3] * pl1[5]; + v2 = pl2[1] * pl1[5] + pl2[2] * pl1[3] + pl2[5] * pl1[1] + pl2[3] * pl1[2]; + + // rotation about the x-axis + //v0 = pl2[3] * pl1[2] + pl2[2] * pl1[3]; + //v1 = -pl2[5] * pl1[0] + pl2[4] * pl1[1] - pl2[1] * pl1[4] + pl2[0] * pl1[5]; + //v2 = pl2[4] * pl1[0] + pl2[5] * pl1[1] + pl2[0] * pl1[4] + pl2[1] * pl1[5]; + + r = tan(t / 2); + sin(t) = 2*r/(1+r*r); + cos(t) = (1-r*r)/(1+r*r); + + v1 * 2 * r / (1 + r*r) + v2 * (1 - r*r) / (1 + r*r) + v0 = 0 + (v1 * 2 * r + v2 * (1 - r*r)) / (1 + r*r) = -v0 + (v1 * 2 * r + v2 - v2 * r*r) / (1 + r*r) = -v0 + v1 * 2 * r + v2 - v2 * r*r = -v0 * (1 + r*r) + v1 * 2 * r + v2 - v2 * r*r = -v0 + -v0 * r*r + (v0 - v2) * r * r + (2 * v1) * r + (v0 + v2) = 0; + + MrE gives Pluecker a banana.. good monkey + + */ + + tanHalfAngle = tw->maxTan; + + // transform rotation axis to z-axis + ct = (vc - tw->origin) * tw->matrix; + dt = (vd - tw->origin) * tw->matrix; + + pl2.FromLine( ct, dt ); + + v0 = pl2[0] * pl1[4] + pl2[4] * pl1[0]; + v1 = pl2[1] * pl1[2] - pl2[2] * pl1[1] + pl2[5] * pl1[3] - pl2[3] * pl1[5]; + v2 = pl2[1] * pl1[5] + pl2[2] * pl1[3] + pl2[5] * pl1[1] + pl2[3] * pl1[2]; + + a = v0 - v2; + b = v1; + c = v0 + v2; + if ( a == 0.0f ) { + if ( b == 0.0f ) { + return false; + } + frac1 = -c / ( 2.0f * b ); + frac2 = 1e10; // = tan( idMath::HALF_PI ) + } + else { + d = b * b - c * a; + if ( d <= 0.0f ) { + return false; + } + sqrtd = sqrt( d ); + if ( b > 0.0f ) { + q = - b + sqrtd; + } + else { + q = - b - sqrtd; + } + frac1 = q / a; + frac2 = c / q; + } + + if ( tw->angle < 0.0f ) { + frac1 = -frac1; + frac2 = -frac2; + } + + // get smallest tangent for which a collision occurs + if ( frac1 >= minTan && frac1 < tanHalfAngle ) { + tanHalfAngle = frac1; + } + if ( frac2 >= minTan && frac2 < tanHalfAngle ) { + tanHalfAngle = frac2; + } + + if ( tw->angle < 0.0f ) { + tanHalfAngle = -tanHalfAngle; + } + + return true; +} + +/* +================ +idCollisionModelManagerLocal::EdgeFurthestFromEdge + + calculates the direction of motion at the initial position, where dir < 0 means the edges move towards each other + if the edges move away from each other the tangent of half the rotation angle at which + the edges are furthest apart is also calculated +================ +*/ +int idCollisionModelManagerLocal::EdgeFurthestFromEdge( cm_traceWork_t *tw, const idPluecker &pl1, + const idVec3 &vc, const idVec3 &vd, + float &tanHalfAngle, float &dir ) { + double v0, v1, v2, a, b, c, d, sqrtd, q, frac1, frac2; + idVec3 ct, dt; + idPluecker pl2; + + /* + + v2 * cos(t) + v1 * sin(t) + v0 = 0; + + // rotation about the z-axis + v0 = pl2[0] * pl1[4] + pl2[4] * pl1[0]; + v1 = pl2[1] * pl1[2] - pl2[2] * pl1[1] + pl2[5] * pl1[3] - pl2[3] * pl1[5]; + v2 = pl2[1] * pl1[5] + pl2[2] * pl1[3] + pl2[5] * pl1[1] + pl2[3] * pl1[2]; + + derivative: + v1 * cos(t) - v2 * sin(t) = 0; + + r = tan(t / 2); + sin(t) = 2*r/(1+r*r); + cos(t) = (1-r*r)/(1+r*r); + + -v2 * 2 * r / (1 + r*r) + v1 * (1 - r*r)/(1+r*r); + -v2 * 2 * r + v1 * (1 - r*r) / (1 + r*r) = 0; + -v2 * 2 * r + v1 * (1 - r*r) = 0; + (-v1) * r * r + (-2 * v2) * r + (v1) = 0; + + */ + + tanHalfAngle = 0.0f; + + // transform rotation axis to z-axis + ct = (vc - tw->origin) * tw->matrix; + dt = (vd - tw->origin) * tw->matrix; + + pl2.FromLine( ct, dt ); + + v0 = pl2[0] * pl1[4] + pl2[4] * pl1[0]; + v1 = pl2[1] * pl1[2] - pl2[2] * pl1[1] + pl2[5] * pl1[3] - pl2[3] * pl1[5]; + v2 = pl2[1] * pl1[5] + pl2[2] * pl1[3] + pl2[5] * pl1[1] + pl2[3] * pl1[2]; + + // get the direction of motion at the initial position + c = v0 + v2; + if ( tw->angle > 0.0f ) { + if ( c > 0.0f ) { + dir = v1; + } + else { + dir = -v1; + } + } + else { + if ( c > 0.0f ) { + dir = -v1; + } + else { + dir = v1; + } + } + // negative direction means the edges move towards each other at the initial position + if ( dir <= 0.0f ) { + return true; + } + + a = -v1; + b = -v2; + c = v1; + if ( a == 0.0f ) { + if ( b == 0.0f ) { + return false; + } + frac1 = -c / ( 2.0f * b ); + frac2 = 1e10; // = tan( idMath::HALF_PI ) + } + else { + d = b * b - c * a; + if ( d <= 0.0f ) { + return false; + } + sqrtd = sqrt( d ); + if ( b > 0.0f ) { + q = - b + sqrtd; + } + else { + q = - b - sqrtd; + } + frac1 = q / a; + frac2 = c / q; + } + + if ( tw->angle < 0.0f ) { + frac1 = -frac1; + frac2 = -frac2; + } + + if ( frac1 < 0.0f && frac2 < 0.0f ) { + return false; + } + + if ( frac1 > frac2 ) { + tanHalfAngle = frac1; + } + else { + tanHalfAngle = frac2; + } + + if ( tw->angle < 0.0f ) { + tanHalfAngle = -tanHalfAngle; + } + + return true; +} + +/* +================ +idCollisionModelManagerLocal::RotateTrmEdgeThroughPolygon +================ +*/ +void idCollisionModelManagerLocal::RotateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ) { + int i, j, edgeNum; + float f1, f2, startTan, dir, tanHalfAngle; + cm_edge_t *edge; + cm_vertex_t *v1, *v2; + idVec3 collisionPoint, collisionNormal, origin, epsDir; + idPluecker epsPl; + idBounds bounds; + + // if the trm is convex and the rotation axis intersects the trm + if ( tw->isConvex && tw->axisIntersectsTrm ) { + // if both points are behind the polygon the edge cannot collide within a 180 degrees rotation + if ( tw->vertices[trmEdge->vertexNum[0]].polygonSide & tw->vertices[trmEdge->vertexNum[1]].polygonSide ) { + return; + } + } + + // if the trace model edge rotation bounds do not intersect the polygon bounds + if ( !trmEdge->rotationBounds.IntersectsBounds( poly->bounds ) ) { + return; + } + + // edge rotation bounds should cross polygon plane + if ( trmEdge->rotationBounds.PlaneSide( poly->plane ) != SIDE_CROSS ) { + return; + } + + // check edges for a collision + for ( i = 0; i < poly->numEdges; i++ ) { + edgeNum = poly->edges[i]; + edge = tw->model->edges + abs(edgeNum); + + // if this edge is already checked + if ( edge->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + + // can never collide with internal edges + if ( edge->internal ) { + continue; + } + + v1 = tw->model->vertices + edge->vertexNum[INTSIGNBITSET(edgeNum)]; + v2 = tw->model->vertices + edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]; + + // edge bounds + for ( j = 0; j < 3; j++ ) { + if ( v1->p[j] > v2->p[j] ) { + bounds[0][j] = v2->p[j]; + bounds[1][j] = v1->p[j]; + } + else { + bounds[0][j] = v1->p[j]; + bounds[1][j] = v2->p[j]; + } + } + + // if the trace model edge rotation bounds do not intersect the polygon edge bounds + if ( !trmEdge->rotationBounds.IntersectsBounds( bounds ) ) { + continue; + } + + f1 = trmEdge->pl.PermutedInnerProduct( tw->polygonEdgePlueckerCache[i] ); + + // pluecker coordinate for epsilon expanded edge + epsDir = edge->normal * (CM_CLIP_EPSILON+CM_PL_RANGE_EPSILON); + epsPl.FromLine( tw->model->vertices[edge->vertexNum[0]].p + epsDir, + tw->model->vertices[edge->vertexNum[1]].p + epsDir ); + + f2 = trmEdge->pl.PermutedInnerProduct( epsPl ); + + // if the rotating edge is inbetween the polygon edge and the epsilon expanded edge + if ( ( f1 < 0.0f && f2 > 0.0f ) || ( f1 > 0.0f && f2 < 0.0f ) ) { + + if ( !EdgeFurthestFromEdge( tw, trmEdge->plzaxis, v1->p, v2->p, startTan, dir ) ) { + continue; + } + + if ( dir <= 0.0f ) { + // moving towards the polygon edge so stop immediately + tanHalfAngle = 0.0f; + } + else if ( idMath::Fabs( startTan ) >= tw->maxTan ) { + // never going to get beyond the start tangent during the current rotation + continue; + } + else { + // collide with the epsilon expanded edge + if ( !RotateEdgeThroughEdge(tw, trmEdge->plzaxis, v1->p + epsDir, v2->p + epsDir, idMath::Fabs( startTan ), tanHalfAngle ) ) { + tanHalfAngle = startTan; + } + } + } + else { + // collide with the epsilon expanded edge + epsDir = edge->normal * CM_CLIP_EPSILON; + if ( !RotateEdgeThroughEdge(tw, trmEdge->plzaxis, v1->p + epsDir, v2->p + epsDir, 0.0f, tanHalfAngle ) ) { + continue; + } + } + + if ( idMath::Fabs( tanHalfAngle ) >= tw->maxTan ) { + continue; + } + + // check if the collision is between the edge bounds + if ( !CollisionBetweenEdgeBounds( tw, trmEdge->start, trmEdge->end, v1->p, v2->p, + tanHalfAngle, collisionPoint, collisionNormal ) ) { + continue; + } + + // allow rotation if the rotation axis goes through the collisionPoint + origin = tw->origin + tw->axis * ( tw->axis * ( collisionPoint - tw->origin ) ); + if ( ( collisionPoint - origin ).LengthSqr() < ROTATION_AXIS_EPSILON * ROTATION_AXIS_EPSILON ) { + continue; + } + + // fill in trace structure + tw->maxTan = idMath::Fabs( tanHalfAngle ); + tw->trace.c.normal = collisionNormal; + tw->trace.c.normal.Normalize(); + tw->trace.c.dist = tw->trace.c.normal * v1->p; + // make sure the collision plane faces the trace model + if ( (tw->trace.c.normal * trmEdge->start) - tw->trace.c.dist < 0 ) { + tw->trace.c.normal = -tw->trace.c.normal; + tw->trace.c.dist = -tw->trace.c.dist; + } + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_EDGE; + tw->trace.c.modelFeature = edgeNum; + tw->trace.c.trmFeature = trmEdge - tw->edges; + tw->trace.c.point = collisionPoint; + // if no collision can be closer + if ( tw->maxTan == 0.0f ) { + break; + } + } +} + +/* +================ +idCollisionModelManagerLocal::RotatePointThroughPlane + + calculates the tangent of half the rotation angle at which the point collides with the plane +================ +*/ +int idCollisionModelManagerLocal::RotatePointThroughPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, + const float angle, const float minTan, float &tanHalfAngle ) { + double v0, v1, v2, a, b, c, d, sqrtd, q, frac1, frac2; + idVec3 p, normal; + + /* + + p[0] = point[0] * cos(t) + point[1] * sin(t) + p[1] = point[0] * -sin(t) + point[1] * cos(t) + p[2] = point[2]; + + normal[0] * (p[0] * cos(t) + p[1] * sin(t)) + + normal[1] * (p[0] * -sin(t) + p[1] * cos(t)) + + normal[2] * p[2] + dist = 0 + + normal[0] * p[0] * cos(t) + normal[0] * p[1] * sin(t) + + -normal[1] * p[0] * sin(t) + normal[1] * p[1] * cos(t) + + normal[2] * p[2] + dist = 0 + + v2 * cos(t) + v1 * sin(t) + v0 + + // rotation about the z-axis + v0 = normal[2] * p[2] + dist + v1 = normal[0] * p[1] - normal[1] * p[0] + v2 = normal[0] * p[0] + normal[1] * p[1] + + r = tan(t / 2); + sin(t) = 2*r/(1+r*r); + cos(t) = (1-r*r)/(1+r*r); + + v1 * 2 * r / (1 + r*r) + v2 * (1 - r*r) / (1 + r*r) + v0 = 0 + (v1 * 2 * r + v2 * (1 - r*r)) / (1 + r*r) = -v0 + (v1 * 2 * r + v2 - v2 * r*r) / (1 + r*r) = -v0 + v1 * 2 * r + v2 - v2 * r*r = -v0 * (1 + r*r) + v1 * 2 * r + v2 - v2 * r*r = -v0 + -v0 * r*r + (v0 - v2) * r * r + (2 * v1) * r + (v0 + v2) = 0; + + */ + + tanHalfAngle = tw->maxTan; + + // transform rotation axis to z-axis + p = (point - tw->origin) * tw->matrix; + d = plane[3] + plane.Normal() * tw->origin; + normal = plane.Normal() * tw->matrix; + + v0 = normal[2] * p[2] + d; + v1 = normal[0] * p[1] - normal[1] * p[0]; + v2 = normal[0] * p[0] + normal[1] * p[1]; + + a = v0 - v2; + b = v1; + c = v0 + v2; + if ( a == 0.0f ) { + if ( b == 0.0f ) { + return false; + } + frac1 = -c / ( 2.0f * b ); + frac2 = 1e10; // = tan( idMath::HALF_PI ) + } + else { + d = b * b - c * a; + if ( d <= 0.0f ) { + return false; + } + sqrtd = sqrt( d ); + if ( b > 0.0f ) { + q = - b + sqrtd; + } + else { + q = - b - sqrtd; + } + frac1 = q / a; + frac2 = c / q; + } + + if ( angle < 0.0f ) { + frac1 = -frac1; + frac2 = -frac2; + } + + // get smallest tangent for which a collision occurs + if ( frac1 >= minTan && frac1 < tanHalfAngle ) { + tanHalfAngle = frac1; + } + if ( frac2 >= minTan && frac2 < tanHalfAngle ) { + tanHalfAngle = frac2; + } + + if ( angle < 0.0f ) { + tanHalfAngle = -tanHalfAngle; + } + + return true; +} + +/* +================ +idCollisionModelManagerLocal::PointFurthestFromPlane + + calculates the direction of motion at the initial position, where dir < 0 means the point moves towards the plane + if the point moves away from the plane the tangent of half the rotation angle at which + the point is furthest away from the plane is also calculated +================ +*/ +int idCollisionModelManagerLocal::PointFurthestFromPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, + const float angle, float &tanHalfAngle, float &dir ) { + + double v1, v2, a, b, c, d, sqrtd, q, frac1, frac2; + idVec3 p, normal; + + /* + + v2 * cos(t) + v1 * sin(t) + v0 = 0; + + // rotation about the z-axis + v0 = normal[2] * p[2] + dist + v1 = normal[0] * p[1] - normal[1] * p[0] + v2 = normal[0] * p[0] + normal[1] * p[1] + + derivative: + v1 * cos(t) - v2 * sin(t) = 0; + + r = tan(t / 2); + sin(t) = 2*r/(1+r*r); + cos(t) = (1-r*r)/(1+r*r); + + -v2 * 2 * r / (1 + r*r) + v1 * (1 - r*r)/(1+r*r); + -v2 * 2 * r + v1 * (1 - r*r) / (1 + r*r) = 0; + -v2 * 2 * r + v1 * (1 - r*r) = 0; + (-v1) * r * r + (-2 * v2) * r + (v1) = 0; + + */ + + tanHalfAngle = 0.0f; + + // transform rotation axis to z-axis + p = (point - tw->origin) * tw->matrix; + normal = plane.Normal() * tw->matrix; + + v1 = normal[0] * p[1] - normal[1] * p[0]; + v2 = normal[0] * p[0] + normal[1] * p[1]; + + // the point will always start at the front of the plane, therefore v0 + v2 > 0 is always true + if ( angle < 0.0f ) { + dir = -v1; + } + else { + dir = v1; + } + // negative direction means the point moves towards the plane at the initial position + if ( dir <= 0.0f ) { + return true; + } + + a = -v1; + b = -v2; + c = v1; + if ( a == 0.0f ) { + if ( b == 0.0f ) { + return false; + } + frac1 = -c / ( 2.0f * b ); + frac2 = 1e10; // = tan( idMath::HALF_PI ) + } + else { + d = b * b - c * a; + if ( d <= 0.0f ) { + return false; + } + sqrtd = sqrt( d ); + if ( b > 0.0f ) { + q = - b + sqrtd; + } + else { + q = - b - sqrtd; + } + frac1 = q / a; + frac2 = c / q; + } + + if ( angle < 0.0f ) { + frac1 = -frac1; + frac2 = -frac2; + } + + if ( frac1 < 0.0f && frac2 < 0.0f ) { + return false; + } + + if ( frac1 > frac2 ) { + tanHalfAngle = frac1; + } + else { + tanHalfAngle = frac2; + } + + if ( angle < 0.0f ) { + tanHalfAngle = -tanHalfAngle; + } + + return true; +} + +/* +================ +idCollisionModelManagerLocal::RotatePointThroughEpsilonPlane +================ +*/ +int idCollisionModelManagerLocal::RotatePointThroughEpsilonPlane( const cm_traceWork_t *tw, const idVec3 &point, const idVec3 &endPoint, + const idPlane &plane, const float angle, const idVec3 &origin, + float &tanHalfAngle, idVec3 &collisionPoint, idVec3 &endDir ) { + float d, dir, startTan; + idVec3 vec, startDir; + idPlane epsPlane; + + // epsilon expanded plane + epsPlane = plane; + epsPlane.SetDist( epsPlane.Dist() + CM_CLIP_EPSILON ); + + // if the rotation sphere at the rotation origin is too far away from the polygon plane + d = epsPlane.Distance( origin ); + vec = point - origin; + if ( d * d > vec * vec ) { + return false; + } + + // calculate direction of motion at vertex start position + startDir = ( point - origin ).Cross( tw->axis ); + if ( angle < 0.0f ) { + startDir = -startDir; + } + // if moving away from plane at start position + if ( startDir * epsPlane.Normal() >= 0.0f ) { + // if end position is outside epsilon range + d = epsPlane.Distance( endPoint ); + if ( d >= 0.0f ) { + return false; // no collision + } + // calculate direction of motion at vertex end position + endDir = ( endPoint - origin ).Cross( tw->axis ); + if ( angle < 0.0f ) { + endDir = -endDir; + } + // if also moving away from plane at end position + if ( endDir * epsPlane.Normal() > 0.0f ) { + return false; // no collision + } + } + + // if the start position is in the epsilon range + d = epsPlane.Distance( point ); + if ( d <= CM_PL_RANGE_EPSILON ) { + + // calculate tangent of half the rotation for which the vertex is furthest away from the plane + if ( !PointFurthestFromPlane( tw, point, plane, angle, startTan, dir ) ) { + return false; + } + + if ( dir <= 0.0f ) { + // moving towards the polygon plane so stop immediately + tanHalfAngle = 0.0f; + } + else if ( idMath::Fabs( startTan ) >= tw->maxTan ) { + // never going to get beyond the start tangent during the current rotation + return false; + } + else { + // calculate collision with epsilon expanded plane + if ( !RotatePointThroughPlane( tw, point, epsPlane, angle, idMath::Fabs( startTan ), tanHalfAngle ) ) { + tanHalfAngle = startTan; + } + } + } + else { + // calculate collision with epsilon expanded plane + if ( !RotatePointThroughPlane( tw, point, epsPlane, angle, 0.0f, tanHalfAngle ) ) { + return false; + } + } + + // calculate collision point + collisionPoint = point; + if ( tanHalfAngle != 0.0f ) { + CM_RotatePoint( collisionPoint, tw->origin, tw->axis, tanHalfAngle ); + } + // calculate direction of motion at collision point + endDir = ( collisionPoint - origin ).Cross( tw->axis ); + if ( angle < 0.0f ) { + endDir = -endDir; + } + return true; +} + +/* +================ +idCollisionModelManagerLocal::RotateTrmVertexThroughPolygon +================ +*/ +void idCollisionModelManagerLocal::RotateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int vertexNum ) { + int i; + float tanHalfAngle; + idVec3 endDir, collisionPoint; + idPluecker pl; + + // if the trm vertex is behind the polygon plane it cannot collide with the polygon within a 180 degrees rotation + if ( tw->isConvex && tw->axisIntersectsTrm && v->polygonSide ) { + return; + } + + // if the trace model vertex rotation bounds do not intersect the polygon bounds + if ( !v->rotationBounds.IntersectsBounds( poly->bounds ) ) { + return; + } + + // vertex rotation bounds should cross polygon plane + if ( v->rotationBounds.PlaneSide( poly->plane ) != SIDE_CROSS ) { + return; + } + + // rotate the vertex through the epsilon plane + if ( !RotatePointThroughEpsilonPlane( tw, v->p, v->endp, poly->plane, tw->angle, v->rotationOrigin, + tanHalfAngle, collisionPoint, endDir ) ) { + return; + } + + if ( idMath::Fabs( tanHalfAngle ) < tw->maxTan ) { + // verify if 'collisionPoint' moving along 'endDir' moves between polygon edges + pl.FromRay( collisionPoint, endDir ); + for ( i = 0; i < poly->numEdges; i++ ) { + if ( poly->edges[i] < 0 ) { + if ( pl.PermutedInnerProduct( tw->polygonEdgePlueckerCache[i] ) > 0.0f ) { + return; + } + } + else { + if ( pl.PermutedInnerProduct( tw->polygonEdgePlueckerCache[i] ) < 0.0f ) { + return; + } + } + } + tw->maxTan = idMath::Fabs( tanHalfAngle ); + // collision plane is the polygon plane + tw->trace.c.normal = poly->plane.Normal(); + tw->trace.c.dist = poly->plane.Dist(); + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_TRMVERTEX; + tw->trace.c.modelFeature = *reinterpret_cast(&poly); + tw->trace.c.trmFeature = v - tw->vertices; + tw->trace.c.point = collisionPoint; + } +} + +/* +================ +idCollisionModelManagerLocal::RotateVertexThroughTrmPolygon +================ +*/ +void idCollisionModelManagerLocal::RotateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, cm_vertex_t *v, idVec3 &rotationOrigin ) { + int i, edgeNum; + float tanHalfAngle; + idVec3 dir, endp, endDir, collisionPoint; + idPluecker pl; + cm_trmEdge_t *edge; + + // if the polygon vertex is behind the trm plane it cannot collide with the trm polygon within a 180 degrees rotation + if ( tw->isConvex && tw->axisIntersectsTrm && trmpoly->plane.Distance( v->p ) < 0.0f ) { + return; + } + + // if the model vertex is outside the trm polygon rotation bounds + if ( !trmpoly->rotationBounds.ContainsPoint( v->p ) ) { + return; + } + + // if the rotation axis goes through the polygon vertex + dir = v->p - rotationOrigin; + if ( dir * dir < ROTATION_AXIS_EPSILON * ROTATION_AXIS_EPSILON ) { + return; + } + + // calculate vertex end position + endp = v->p; + tw->modelVertexRotation.RotatePoint( endp ); + + // rotate the vertex through the epsilon plane + if ( !RotatePointThroughEpsilonPlane( tw, v->p, endp, trmpoly->plane, -tw->angle, rotationOrigin, + tanHalfAngle, collisionPoint, endDir ) ) { + return; + } + + if ( idMath::Fabs( tanHalfAngle ) < tw->maxTan ) { + // verify if 'collisionPoint' moving along 'endDir' moves between polygon edges + pl.FromRay( collisionPoint, endDir ); + for ( i = 0; i < trmpoly->numEdges; i++ ) { + edgeNum = trmpoly->edges[i]; + edge = tw->edges + abs(edgeNum); + if ( edgeNum < 0 ) { + if ( pl.PermutedInnerProduct( edge->pl ) > 0.0f ) { + return; + } + } + else { + if ( pl.PermutedInnerProduct( edge->pl ) < 0.0f ) { + return; + } + } + } + tw->maxTan = idMath::Fabs( tanHalfAngle ); + // collision plane is the flipped trm polygon plane + tw->trace.c.normal = -trmpoly->plane.Normal(); + tw->trace.c.dist = tw->trace.c.normal * v->p; + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_MODELVERTEX; + tw->trace.c.modelFeature = v - tw->model->vertices; + tw->trace.c.trmFeature = trmpoly - tw->polys; + tw->trace.c.point = v->p; + } +} + +/* +================ +idCollisionModelManagerLocal::RotateTrmThroughPolygon + + returns true if the polygon blocks the complete rotation +================ +*/ +bool idCollisionModelManagerLocal::RotateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ) { + int i, j, k, edgeNum; + float d; + cm_trmVertex_t *bv; + cm_trmEdge_t *be; + cm_trmPolygon_t *bp; + cm_vertex_t *v; + cm_edge_t *e; + idVec3 *rotationOrigin; + + // if already checked this polygon + if ( p->checkcount == idCollisionModelManagerLocal::checkCount ) { + return false; + } + p->checkcount = idCollisionModelManagerLocal::checkCount; + + // if this polygon does not have the right contents behind it + if ( !(p->contents & tw->contents) ) { + return false; + } + + // if the the trace bounds do not intersect the polygon bounds + if ( !tw->bounds.IntersectsBounds( p->bounds ) ) { + return false; + } + + // back face culling + if ( tw->isConvex ) { + // if the center of the convex trm is behind the polygon plane + if ( p->plane.Distance( tw->start ) < 0.0f ) { + // if the rotation axis intersects the trace model + if ( tw->axisIntersectsTrm ) { + return false; + } + else { + // if the direction of motion at the start and end position of the + // center of the trm both go towards or away from the polygon plane + // or if the intersections of the rotation axis with the expanded heart planes + // are both in front of the polygon plane + } + } + } + + // if the polygon is too far from the first heart plane + d = p->bounds.PlaneDistance( tw->heartPlane1 ); + if ( idMath::Fabs(d) > tw->maxDistFromHeartPlane1 ) { + return false; + } + + // rotation bounds should cross polygon plane + switch( tw->bounds.PlaneSide( p->plane ) ) { + case PLANESIDE_CROSS: + break; + case PLANESIDE_FRONT: + if ( tw->model->isConvex ) { + tw->quickExit = true; + return true; + } + default: + return false; + } + + for ( i = 0; i < tw->numVerts; i++ ) { + bv = tw->vertices + i; + // calculate polygon side this vertex is on + d = p->plane.Distance( bv->p ); + bv->polygonSide = FLOATSIGNBITSET( d ); + } + + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + e = tw->model->edges + abs(edgeNum); + v = tw->model->vertices + e->vertexNum[INTSIGNBITSET(edgeNum)]; + + // pluecker coordinate for edge + tw->polygonEdgePlueckerCache[i].FromLine( tw->model->vertices[e->vertexNum[0]].p, + tw->model->vertices[e->vertexNum[1]].p ); + + // calculate rotation origin projected into rotation plane through the vertex + tw->polygonRotationOriginCache[i] = tw->origin + tw->axis * ( tw->axis * ( v->p - tw->origin ) ); + } + // copy first to last so we can easily cycle through + tw->polygonRotationOriginCache[p->numEdges] = tw->polygonRotationOriginCache[0]; + + // fast point rotation + if ( tw->pointTrace ) { + RotateTrmVertexThroughPolygon( tw, p, &tw->vertices[0], 0 ); + } + else { + // rotate trm vertices through polygon + for ( i = 0; i < tw->numVerts; i++ ) { + bv = tw->vertices + i; + if ( bv->used ) { + RotateTrmVertexThroughPolygon( tw, p, bv, i ); + } + } + + // rotate trm edges through polygon + for ( i = 1; i <= tw->numEdges; i++ ) { + be = tw->edges + i; + if ( be->used ) { + RotateTrmEdgeThroughPolygon( tw, p, be ); + } + } + + // rotate all polygon vertices through the trm + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + e = tw->model->edges + abs(edgeNum); + + if ( e->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + // set edge check count + e->checkcount = idCollisionModelManagerLocal::checkCount; + // can never collide with internal edges + if ( e->internal ) { + continue; + } + // got to check both vertices because we skip internal edges + for ( k = 0; k < 2; k++ ) { + + v = tw->model->vertices + e->vertexNum[k ^ INTSIGNBITSET(edgeNum)]; + + // if this vertex is already checked + if ( v->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + // set vertex check count + v->checkcount = idCollisionModelManagerLocal::checkCount; + + // if the vertex is outside the trm rotation bounds + if ( !tw->bounds.ContainsPoint( v->p ) ) { + continue; + } + + rotationOrigin = &tw->polygonRotationOriginCache[i+k]; + + for ( j = 0; j < tw->numPolys; j++ ) { + bp = tw->polys + j; + if ( bp->used ) { + RotateVertexThroughTrmPolygon( tw, bp, p, v, *rotationOrigin ); + } + } + } + } + } + + return ( tw->maxTan == 0.0f ); +} + +/* +================ +idCollisionModelManagerLocal::BoundsForRotation + + only for rotations < 180 degrees +================ +*/ +void idCollisionModelManagerLocal::BoundsForRotation( const idVec3 &origin, const idVec3 &axis, const idVec3 &start, const idVec3 &end, idBounds &bounds ) { + int i; + float radiusSqr; + idVec3 v1, v2; + + radiusSqr = ( start - origin ).LengthSqr(); + v1 = ( start - origin ).Cross( axis ); + v2 = ( end - origin ).Cross( axis ); + + for ( i = 0; i < 3; i++ ) { + // if the derivative changes sign along this axis during the rotation from start to end + if ( ( v1[i] > 0.0f && v2[i] < 0.0f ) || ( v1[i] < 0.0f && v2[i] > 0.0f ) ) { + if ( ( 0.5f * (start[i] + end[i]) - origin[i] ) > 0.0f ) { + bounds[0][i] = Min( start[i], end[i] ); + bounds[1][i] = origin[i] + idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); + } + else { + bounds[0][i] = origin[i] - idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); + bounds[1][i] = Max( start[i], end[i] ); + } + } + else if ( start[i] > end[i] ) { + bounds[0][i] = end[i]; + bounds[1][i] = start[i]; + } + else { + bounds[0][i] = start[i]; + bounds[1][i] = end[i]; + } + // expand for epsilons + bounds[0][i] -= CM_BOX_EPSILON; + bounds[1][i] += CM_BOX_EPSILON; + } +} + +/* +================ +idCollisionModelManagerLocal::Rotation180 +================ +*/ +void idCollisionModelManagerLocal::Rotation180( trace_t *results, const idVec3 &rorg, const idVec3 &axis, + const float startAngle, const float endAngle, const idVec3 &start, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + int i, j, edgeNum; + float d, maxErr, initialTan; + bool model_rotated, trm_rotated; + idVec3 dir, dir1, dir2, tmp, vr, vup, org, at, bt; + idMat3 invModelAxis, endAxis, tmpAxis; + idRotation startRotation, endRotation; + idPluecker plaxis; + cm_trmPolygon_t *poly; + cm_trmEdge_t *edge; + cm_trmVertex_t *vert; + ALIGN16( static cm_traceWork_t tw ); + + if ( model < 0 || model > MAX_SUBMODELS || model > idCollisionModelManagerLocal::maxModels ) { + common->Printf("idCollisionModelManagerLocal::Rotation180: invalid model handle\n"); + return; + } + if ( !idCollisionModelManagerLocal::models[model] ) { + common->Printf("idCollisionModelManagerLocal::Rotation180: invalid model\n"); + return; + } + + idCollisionModelManagerLocal::checkCount++; + + tw.trace.fraction = 1.0f; + tw.trace.c.contents = 0; + tw.trace.c.type = CONTACT_NONE; + tw.contents = contentMask; + tw.isConvex = true; + tw.rotation = true; + tw.positionTest = false; + tw.axisIntersectsTrm = false; + tw.quickExit = false; + tw.angle = endAngle - startAngle; + assert( tw.angle > -180.0f && tw.angle < 180.0f ); + tw.maxTan = initialTan = idMath::Fabs( tan( ( idMath::PI / 360.0f ) * tw.angle ) ); + tw.model = idCollisionModelManagerLocal::models[model]; + tw.start = start - modelOrigin; + // rotation axis, axis is assumed to be normalized + tw.axis = axis; + assert( tw.axis[0] * tw.axis[0] + tw.axis[1] * tw.axis[1] + tw.axis[2] * tw.axis[2] > 0.99f ); + // rotation origin projected into rotation plane through tw.start + tw.origin = rorg - modelOrigin; + d = (tw.axis * tw.origin) - ( tw.axis * tw.start ); + tw.origin = tw.origin - d * tw.axis; + // radius of rotation + tw.radius = ( tw.start - tw.origin ).Length(); + // maximum error of the circle approximation traced through the axial BSP tree + d = tw.radius * tw.radius - (CIRCLE_APPROXIMATION_LENGTH*CIRCLE_APPROXIMATION_LENGTH*0.25f); + if ( d > 0.0f ) { + maxErr = tw.radius - idMath::Sqrt( d ); + } else { + maxErr = tw.radius; + } + + model_rotated = modelAxis.IsRotated(); + if ( model_rotated ) { + invModelAxis = modelAxis.Transpose(); + tw.axis *= invModelAxis; + tw.origin *= invModelAxis; + } + + startRotation.Set( tw.origin, tw.axis, startAngle ); + endRotation.Set( tw.origin, tw.axis, endAngle ); + + // create matrix which rotates the rotation axis to the z-axis + tw.axis.NormalVectors( vr, vup ); + tw.matrix[0][0] = vr[0]; + tw.matrix[1][0] = vr[1]; + tw.matrix[2][0] = vr[2]; + tw.matrix[0][1] = -vup[0]; + tw.matrix[1][1] = -vup[1]; + tw.matrix[2][1] = -vup[2]; + tw.matrix[0][2] = tw.axis[0]; + tw.matrix[1][2] = tw.axis[1]; + tw.matrix[2][2] = tw.axis[2]; + + // if optimized point trace + if ( !trm || ( trm->bounds[1][0] - trm->bounds[0][0] <= 0.0f && + trm->bounds[1][1] - trm->bounds[0][1] <= 0.0f && + trm->bounds[1][2] - trm->bounds[0][2] <= 0.0f ) ) { + + if ( model_rotated ) { + // rotate trace instead of model + tw.start *= invModelAxis; + } + tw.end = tw.start; + // if we start at a specific angle + if ( startAngle != 0.0f ) { + startRotation.RotatePoint( tw.start ); + } + // calculate end position of rotation + endRotation.RotatePoint( tw.end ); + + // calculate rotation origin projected into rotation plane through the vertex + tw.numVerts = 1; + tw.vertices[0].p = tw.start; + tw.vertices[0].endp = tw.end; + tw.vertices[0].used = true; + tw.vertices[0].rotationOrigin = tw.origin + tw.axis * ( tw.axis * ( tw.vertices[0].p - tw.origin ) ); + BoundsForRotation( tw.vertices[0].rotationOrigin, tw.axis, tw.start, tw.end, tw.vertices[0].rotationBounds ); + // rotation bounds + tw.bounds = tw.vertices[0].rotationBounds; + tw.numEdges = tw.numPolys = 0; + + // collision with single point + tw.pointTrace = true; + + // extents is set to maximum error of the circle approximation traced through the axial BSP tree + tw.extents[0] = tw.extents[1] = tw.extents[2] = maxErr + CM_BOX_EPSILON; + + // setup rotation heart plane + tw.heartPlane1.SetNormal( tw.axis ); + tw.heartPlane1.FitThroughPoint( tw.start ); + tw.maxDistFromHeartPlane1 = CM_BOX_EPSILON; + + // trace through the model + idCollisionModelManagerLocal::TraceThroughModel( &tw ); + + // store results + *results = tw.trace; + results->endpos = start; + if ( tw.maxTan == initialTan ) { + results->fraction = 1.0f; + } else { + results->fraction = idMath::Fabs( atan( tw.maxTan ) * ( 2.0f * 180.0f / idMath::PI ) / tw.angle ); + } + assert( results->fraction <= 1.0f ); + endRotation.Set( rorg, axis, startAngle + (endAngle-startAngle) * results->fraction ); + endRotation.RotatePoint( results->endpos ); + results->endAxis.Identity(); + + if ( results->fraction < 1.0f ) { + // rotate trace plane normal if there was a collision with a rotated model + if ( model_rotated ) { + results->c.normal *= modelAxis; + results->c.point *= modelAxis; + } + results->c.point += modelOrigin; + results->c.dist += modelOrigin * results->c.normal; + } + return; + } + + tw.pointTrace = false; + + // setup trm structure + idCollisionModelManagerLocal::SetupTrm( &tw, trm ); + + trm_rotated = trmAxis.IsRotated(); + + // calculate vertex positions + if ( trm_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + // rotate trm around the start position + tw.vertices[i].p *= trmAxis; + } + } + for ( i = 0; i < tw.numVerts; i++ ) { + // set trm at start position + tw.vertices[i].p += tw.start; + } + if ( model_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + tw.vertices[i].p *= invModelAxis; + } + } + for ( i = 0; i < tw.numVerts; i++ ) { + tw.vertices[i].endp = tw.vertices[i].p; + } + // if we start at a specific angle + if ( startAngle != 0.0f ) { + for ( i = 0; i < tw.numVerts; i++ ) { + startRotation.RotatePoint( tw.vertices[i].p ); + } + } + for ( i = 0; i < tw.numVerts; i++ ) { + // end position of vertex + endRotation.RotatePoint( tw.vertices[i].endp ); + } + + // add offset to start point + if ( trm_rotated ) { + tw.start += trm->offset * trmAxis; + } else { + tw.start += trm->offset; + } + // if the model is rotated + if ( model_rotated ) { + // rotate trace instead of model + tw.start *= invModelAxis; + } + tw.end = tw.start; + // if we start at a specific angle + if ( startAngle != 0.0f ) { + startRotation.RotatePoint( tw.start ); + } + // calculate end position of rotation + endRotation.RotatePoint( tw.end ); + + // setup trm vertices + for ( vert = tw.vertices, i = 0; i < tw.numVerts; i++, vert++ ) { + // calculate rotation origin projected into rotation plane through the vertex + vert->rotationOrigin = tw.origin + tw.axis * ( tw.axis * ( vert->p - tw.origin ) ); + // calculate rotation bounds for this vertex + BoundsForRotation( vert->rotationOrigin, tw.axis, vert->p, vert->endp, vert->rotationBounds ); + // if the rotation axis goes through the vertex then the vertex is not used + d = ( vert->p - vert->rotationOrigin ).LengthSqr(); + if ( d > ROTATION_AXIS_EPSILON * ROTATION_AXIS_EPSILON ) { + vert->used = true; + } + } + + // setup trm edges + for ( edge = tw.edges + 1, i = 1; i <= tw.numEdges; i++, edge++ ) { + // if the rotation axis goes through both the edge vertices then the edge is not used + if ( tw.vertices[edge->vertexNum[0]].used | tw.vertices[edge->vertexNum[1]].used ) { + edge->used = true; + } + // edge start, end and pluecker coordinate + edge->start = tw.vertices[edge->vertexNum[0]].p; + edge->end = tw.vertices[edge->vertexNum[1]].p; + edge->pl.FromLine( edge->start, edge->end ); + // pluecker coordinate for edge being rotated about the z-axis + at = ( edge->start - tw.origin ) * tw.matrix; + bt = ( edge->end - tw.origin ) * tw.matrix; + edge->plzaxis.FromLine( at, bt ); + // get edge rotation bounds from the rotation bounds of both vertices + edge->rotationBounds = tw.vertices[edge->vertexNum[0]].rotationBounds; + edge->rotationBounds.AddBounds( tw.vertices[edge->vertexNum[1]].rotationBounds ); + // used to calculate if the rotation axis intersects the trm + edge->bitNum = 0; + } + + tw.bounds.Clear(); + + // rotate trm polygon planes + if ( trm_rotated & model_rotated ) { + tmpAxis = trmAxis * invModelAxis; + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= tmpAxis; + } + } else if ( trm_rotated ) { + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= trmAxis; + } + } else if ( model_rotated ) { + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= invModelAxis; + } + } + + // setup trm polygons + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->used = true; + // set trm polygon plane distance + poly->plane.FitThroughPoint( tw.edges[abs(poly->edges[0])].start ); + // get polygon bounds from edge bounds + poly->rotationBounds.Clear(); + for ( j = 0; j < poly->numEdges; j++ ) { + // add edge rotation bounds to polygon rotation bounds + edge = &tw.edges[abs( poly->edges[j] )]; + poly->rotationBounds.AddBounds( edge->rotationBounds ); + } + // get trace bounds from polygon bounds + tw.bounds.AddBounds( poly->rotationBounds ); + } + + // extents including the maximum error of the circle approximation traced through the axial BSP tree + for ( i = 0; i < 3; i++ ) { + tw.size[0][i] = tw.bounds[0][i] - tw.start[i]; + tw.size[1][i] = tw.bounds[1][i] - tw.start[i]; + if ( idMath::Fabs( tw.size[0][i] ) > idMath::Fabs( tw.size[1][i] ) ) { + tw.extents[i] = idMath::Fabs( tw.size[0][i] ) + maxErr + CM_BOX_EPSILON; + } else { + tw.extents[i] = idMath::Fabs( tw.size[1][i] ) + maxErr + CM_BOX_EPSILON; + } + } + + // for back-face culling + if ( tw.isConvex ) { + if ( tw.start == tw.origin ) { + tw.axisIntersectsTrm = true; + } else { + // determine if the rotation axis intersects the trm + plaxis.FromRay( tw.origin, tw.axis ); + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + // back face cull polygons + if ( poly->plane.Normal() * tw.axis > 0.0f ) { + continue; + } + // test if the axis goes between the polygon edges + for ( j = 0; j < poly->numEdges; j++ ) { + edgeNum = poly->edges[j]; + edge = tw.edges + abs(edgeNum); + if ( !(edge->bitNum & 2) ) { + d = plaxis.PermutedInnerProduct( edge->pl ); + edge->bitNum = FLOATSIGNBITSET( d ) | 2; + } + if ( ( edge->bitNum ^ INTSIGNBITSET( edgeNum ) ) & 1 ) { + break; + } + } + if ( j >= poly->numEdges ) { + tw.axisIntersectsTrm = true; + break; + } + } + } + } + + // setup rotation heart plane + tw.heartPlane1.SetNormal( tw.axis ); + tw.heartPlane1.FitThroughPoint( tw.start ); + tw.maxDistFromHeartPlane1 = 0.0f; + for ( i = 0; i < tw.numVerts; i++ ) { + d = idMath::Fabs( tw.heartPlane1.Distance( tw.vertices[i].p ) ); + if ( d > tw.maxDistFromHeartPlane1 ) { + tw.maxDistFromHeartPlane1 = d; + } + } + tw.maxDistFromHeartPlane1 += CM_BOX_EPSILON; + + // inverse rotation to rotate model vertices towards trace model + tw.modelVertexRotation.Set( tw.origin, tw.axis, -tw.angle ); + + // trace through the model + idCollisionModelManagerLocal::TraceThroughModel( &tw ); + + // store results + *results = tw.trace; + results->endpos = start; + if ( tw.maxTan == initialTan ) { + results->fraction = 1.0f; + } else { + results->fraction = idMath::Fabs( atan( tw.maxTan ) * ( 2.0f * 180.0f / idMath::PI ) / tw.angle ); + } + assert( results->fraction <= 1.0f ); + endRotation.Set( rorg, axis, startAngle + (endAngle-startAngle) * results->fraction ); + endRotation.RotatePoint( results->endpos ); + results->endAxis = trmAxis * endRotation.ToMat3(); + + if ( results->fraction < 1.0f ) { + // rotate trace plane normal if there was a collision with a rotated model + if ( model_rotated ) { + results->c.normal *= modelAxis; + results->c.point *= modelAxis; + } + results->c.point += modelOrigin; + results->c.dist += modelOrigin * results->c.normal; + } +} + +/* +================ +idCollisionModelManagerLocal::Rotation +================ +*/ +#ifdef _DEBUG +static int entered = 0; +#endif + +void idCollisionModelManagerLocal::Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + idVec3 tmp; + float maxa, stepa, a, lasta; + + assert( ((byte *)&start) < ((byte *)results) || ((byte *)&start) > (((byte *)results) + sizeof( trace_t )) ); + assert( ((byte *)&trmAxis) < ((byte *)results) || ((byte *)&trmAxis) > (((byte *)results) + sizeof( trace_t )) ); + + memset( results, 0, sizeof( *results ) ); + + // if special position test + if ( rotation.GetAngle() == 0.0f ) { + idCollisionModelManagerLocal::ContentsTrm( results, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + return; + } + +#ifdef _DEBUG + bool startsolid = false; + // test whether or not stuck to begin with + if ( cm_debugCollision.GetBool() ) { + if ( !entered ) { + entered = 1; + // if already messed up to begin with + if ( idCollisionModelManagerLocal::Contents( start, trm, trmAxis, -1, model, modelOrigin, modelAxis ) & contentMask ) { + startsolid = true; + } + entered = 0; + } + } +#endif + + if ( rotation.GetAngle() >= 180.0f || rotation.GetAngle() <= -180.0f) { + if ( rotation.GetAngle() >= 360.0f ) { + maxa = 360.0f; + stepa = 120.0f; // three steps strictly < 180 degrees + } else if ( rotation.GetAngle() <= -360.0f ) { + maxa = -360.0f; + stepa = -120.0f; // three steps strictly < 180 degrees + } else { + maxa = rotation.GetAngle(); + stepa = rotation.GetAngle() * 0.5f; // two steps strictly < 180 degrees + } + for ( lasta = 0.0f, a = stepa; fabs( a ) < fabs( maxa ) + 1.0f; lasta = a, a += stepa ) { + // partial rotation + idCollisionModelManagerLocal::Rotation180( results, rotation.GetOrigin(), rotation.GetVec(), lasta, a, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + // if there is a collision + if ( results->fraction < 1.0f ) { + // fraction of total rotation + results->fraction = (lasta + stepa * results->fraction) / rotation.GetAngle(); + return; + } + } + results->fraction = 1.0f; + return; + } + + idCollisionModelManagerLocal::Rotation180( results, rotation.GetOrigin(), rotation.GetVec(), 0.0f, rotation.GetAngle(), start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + +#ifdef _DEBUG + // test for missed collisions + if ( cm_debugCollision.GetBool() ) { + if ( !entered ) { + entered = 1; + // if the trm is stuck in the model + if ( idCollisionModelManagerLocal::Contents( results->endpos, trm, results->endAxis, -1, model, modelOrigin, modelAxis ) & contentMask ) { + trace_t tr; + + // test where the trm is stuck in the model + idCollisionModelManagerLocal::Contents( results->endpos, trm, results->endAxis, -1, model, modelOrigin, modelAxis ); + // re-run collision detection to find out where it failed + idCollisionModelManagerLocal::Rotation( &tr, start, rotation, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + } + entered = 0; + } + } +#endif +} diff --git a/cm/CollisionModel_trace.cpp b/cm/CollisionModel_trace.cpp new file mode 100644 index 000000000..0fa47d854 --- /dev/null +++ b/cm/CollisionModel_trace.cpp @@ -0,0 +1,247 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +/* +=============================================================================== + +Trace through the spatial subdivision + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::TraceTrmThroughNode +================ +*/ +void idCollisionModelManagerLocal::TraceTrmThroughNode( cm_traceWork_t *tw, cm_node_t *node ) { + cm_polygonRef_t *pref; + cm_brushRef_t *bref; + + // position test + if ( tw->positionTest ) { + // if already stuck in solid + if ( tw->trace.fraction == 0.0f ) { + return; + } + // test if any of the trm vertices is inside a brush + for ( bref = node->brushes; bref; bref = bref->next ) { + if ( idCollisionModelManagerLocal::TestTrmVertsInBrush( tw, bref->b ) ) { + return; + } + } + // if just testing a point we're done + if ( tw->pointTrace ) { + return; + } + // test if the trm is stuck in any polygons + for ( pref = node->polygons; pref; pref = pref->next ) { + if ( idCollisionModelManagerLocal::TestTrmInPolygon( tw, pref->p ) ) { + return; + } + } + } + else if ( tw->rotation ) { + // rotate through all polygons in this leaf + for ( pref = node->polygons; pref; pref = pref->next ) { + if ( idCollisionModelManagerLocal::RotateTrmThroughPolygon( tw, pref->p ) ) { + return; + } + } + } + else { + // trace through all polygons in this leaf + for ( pref = node->polygons; pref; pref = pref->next ) { + if ( idCollisionModelManagerLocal::TranslateTrmThroughPolygon( tw, pref->p ) ) { + return; + } + } + } +} + +/* +================ +idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r +================ +*/ +//#define NO_SPATIAL_SUBDIVISION + +void idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( cm_traceWork_t *tw, cm_node_t *node, float p1f, float p2f, idVec3 &p1, idVec3 &p2) { + float t1, t2, offset; + float frac, frac2; + float idist; + idVec3 mid; + int side; + float midf; + + if ( !node ) { + return; + } + + if ( tw->quickExit ) { + return; // stop immediately + } + + if ( tw->trace.fraction <= p1f ) { + return; // already hit something nearer + } + + // if we need to test this node for collisions + if ( node->polygons || (tw->positionTest && node->brushes) ) { + // trace through node with collision data + idCollisionModelManagerLocal::TraceTrmThroughNode( tw, node ); + } + // if already stuck in solid + if ( tw->positionTest && tw->trace.fraction == 0.0f ) { + return; + } + // if this is a leaf node + if ( node->planeType == -1 ) { + return; + } +#ifdef NO_SPATIAL_SUBDIVISION + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[0], p1f, p2f, p1, p2 ); + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[1], p1f, p2f, p1, p2 ); + return; +#endif + // distance from plane for trace start and end + t1 = p1[node->planeType] - node->planeDist; + t2 = p2[node->planeType] - node->planeDist; + // adjust the plane distance appropriately for mins/maxs + offset = tw->extents[node->planeType]; + // see which sides we need to consider + if ( t1 >= offset && t2 >= offset ) { + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[0], p1f, p2f, p1, p2 ); + return; + } + + if ( t1 < -offset && t2 < -offset ) { + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[1], p1f, p2f, p1, p2 ); + return; + } + + if ( t1 < t2 ) { + idist = 1.0f / (t1-t2); + side = 1; + frac2 = (t1 + offset) * idist; + frac = (t1 - offset) * idist; + } else if (t1 > t2) { + idist = 1.0f / (t1-t2); + side = 0; + frac2 = (t1 - offset) * idist; + frac = (t1 + offset) * idist; + } else { + side = 0; + frac = 1.0f; + frac2 = 0.0f; + } + + // move up to the node + if ( frac < 0.0f ) { + frac = 0.0f; + } + else if ( frac > 1.0f ) { + frac = 1.0f; + } + + midf = p1f + (p2f - p1f)*frac; + + mid[0] = p1[0] + frac*(p2[0] - p1[0]); + mid[1] = p1[1] + frac*(p2[1] - p1[1]); + mid[2] = p1[2] + frac*(p2[2] - p1[2]); + + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[side], p1f, midf, p1, mid ); + + + // go past the node + if ( frac2 < 0.0f ) { + frac2 = 0.0f; + } + else if ( frac2 > 1.0f ) { + frac2 = 1.0f; + } + + midf = p1f + (p2f - p1f)*frac2; + + mid[0] = p1[0] + frac2*(p2[0] - p1[0]); + mid[1] = p1[1] + frac2*(p2[1] - p1[1]); + mid[2] = p1[2] + frac2*(p2[2] - p1[2]); + + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, node->children[side^1], midf, p2f, mid, p2 ); +} + +/* +================ +idCollisionModelManagerLocal::TraceThroughModel +================ +*/ +void idCollisionModelManagerLocal::TraceThroughModel( cm_traceWork_t *tw ) { + float d; + int i, numSteps; + idVec3 start, end; + idRotation rot; + + if ( !tw->rotation ) { + // trace through spatial subdivision and then through leafs + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, tw->model->node, 0, 1, tw->start, tw->end ); + } + else { + // approximate the rotation with a series of straight line movements + // total length covered along circle + d = tw->radius * DEG2RAD( tw->angle ); + // if more than one step + if ( d > CIRCLE_APPROXIMATION_LENGTH ) { + // number of steps for the approximation + numSteps = (int) (CIRCLE_APPROXIMATION_LENGTH / d); + // start of approximation + start = tw->start; + // trace circle approximation steps through the BSP tree + for ( i = 0; i < numSteps; i++ ) { + // calculate next point on approximated circle + rot.Set( tw->origin, tw->axis, tw->angle * ((float) (i+1) / numSteps) ); + end = start * rot; + // trace through spatial subdivision and then through leafs + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, tw->model->node, 0, 1, start, end ); + // no need to continue if something was hit already + if ( tw->trace.fraction < 1.0f ) { + return; + } + start = end; + } + } + else { + start = tw->start; + } + // last step of the approximation + idCollisionModelManagerLocal::TraceThroughAxialBSPTree_r( tw, tw->model->node, 0, 1, start, tw->end ); + } +} diff --git a/cm/CollisionModel_translate.cpp b/cm/CollisionModel_translate.cpp new file mode 100644 index 000000000..823077ede --- /dev/null +++ b/cm/CollisionModel_translate.cpp @@ -0,0 +1,1111 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Trace model vs. polygonal model collision detection. + +=============================================================================== +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "CollisionModel_local.h" + +/* +=============================================================================== + +Collision detection for translational motion + +=============================================================================== +*/ + +/* +================ +idCollisionModelManagerLocal::TranslateEdgeThroughEdge + + calculates fraction of the translation completed at which the edges collide +================ +*/ +ID_INLINE int idCollisionModelManagerLocal::TranslateEdgeThroughEdge( idVec3 &cross, idPluecker &l1, idPluecker &l2, float *fraction ) { + + float d, t; + + /* + + a = start of line + b = end of line + dir = movement direction + l1 = pluecker coordinate for line + l2 = pluecker coordinate for edge we might collide with + a+dir = start of line after movement + b+dir = end of line after movement + t = scale factor + solve pluecker inner product for t of line (a+t*dir : b+t*dir) and line l2 + + v[0] = (a[0]+t*dir[0]) * (b[1]+t*dir[1]) - (b[0]+t*dir[0]) * (a[1]+t*dir[1]); + v[1] = (a[0]+t*dir[0]) * (b[2]+t*dir[2]) - (b[0]+t*dir[0]) * (a[2]+t*dir[2]); + v[2] = (a[0]+t*dir[0]) - (b[0]+t*dir[0]); + v[3] = (a[1]+t*dir[1]) * (b[2]+t*dir[2]) - (b[1]+t*dir[1]) * (a[2]+t*dir[2]); + v[4] = (a[2]+t*dir[2]) - (b[2]+t*dir[2]); + v[5] = (b[1]+t*dir[1]) - (a[1]+t*dir[1]); + + l2[0] * v[4] + l2[1] * v[5] + l2[2] * v[3] + l2[4] * v[0] + l2[5] * v[1] + l2[3] * v[2] = 0; + + solve t + + v[0] = (a[0]+t*dir[0]) * (b[1]+t*dir[1]) - (b[0]+t*dir[0]) * (a[1]+t*dir[1]); + v[0] = (a[0]*b[1]) + a[0]*t*dir[1] + b[1]*t*dir[0] + (t*t*dir[0]*dir[1]) - + ((b[0]*a[1]) + b[0]*t*dir[1] + a[1]*t*dir[0] + (t*t*dir[0]*dir[1])); + v[0] = a[0]*b[1] + a[0]*t*dir[1] + b[1]*t*dir[0] - b[0]*a[1] - b[0]*t*dir[1] - a[1]*t*dir[0]; + + v[1] = (a[0]+t*dir[0]) * (b[2]+t*dir[2]) - (b[0]+t*dir[0]) * (a[2]+t*dir[2]); + v[1] = (a[0]*b[2]) + a[0]*t*dir[2] + b[2]*t*dir[0] + (t*t*dir[0]*dir[2]) - + ((b[0]*a[2]) + b[0]*t*dir[2] + a[2]*t*dir[0] + (t*t*dir[0]*dir[2])); + v[1] = a[0]*b[2] + a[0]*t*dir[2] + b[2]*t*dir[0] - b[0]*a[2] - b[0]*t*dir[2] - a[2]*t*dir[0]; + + v[2] = (a[0]+t*dir[0]) - (b[0]+t*dir[0]); + v[2] = a[0] - b[0]; + + v[3] = (a[1]+t*dir[1]) * (b[2]+t*dir[2]) - (b[1]+t*dir[1]) * (a[2]+t*dir[2]); + v[3] = (a[1]*b[2]) + a[1]*t*dir[2] + b[2]*t*dir[1] + (t*t*dir[1]*dir[2]) - + ((b[1]*a[2]) + b[1]*t*dir[2] + a[2]*t*dir[1] + (t*t*dir[1]*dir[2])); + v[3] = a[1]*b[2] + a[1]*t*dir[2] + b[2]*t*dir[1] - b[1]*a[2] - b[1]*t*dir[2] - a[2]*t*dir[1]; + + v[4] = (a[2]+t*dir[2]) - (b[2]+t*dir[2]); + v[4] = a[2] - b[2]; + + v[5] = (b[1]+t*dir[1]) - (a[1]+t*dir[1]); + v[5] = b[1] - a[1]; + + + v[0] = a[0]*b[1] + a[0]*t*dir[1] + b[1]*t*dir[0] - b[0]*a[1] - b[0]*t*dir[1] - a[1]*t*dir[0]; + v[1] = a[0]*b[2] + a[0]*t*dir[2] + b[2]*t*dir[0] - b[0]*a[2] - b[0]*t*dir[2] - a[2]*t*dir[0]; + v[2] = a[0] - b[0]; + v[3] = a[1]*b[2] + a[1]*t*dir[2] + b[2]*t*dir[1] - b[1]*a[2] - b[1]*t*dir[2] - a[2]*t*dir[1]; + v[4] = a[2] - b[2]; + v[5] = b[1] - a[1]; + + v[0] = (a[0]*dir[1] + b[1]*dir[0] - b[0]*dir[1] - a[1]*dir[0]) * t + a[0]*b[1] - b[0]*a[1]; + v[1] = (a[0]*dir[2] + b[2]*dir[0] - b[0]*dir[2] - a[2]*dir[0]) * t + a[0]*b[2] - b[0]*a[2]; + v[2] = a[0] - b[0]; + v[3] = (a[1]*dir[2] + b[2]*dir[1] - b[1]*dir[2] - a[2]*dir[1]) * t + a[1]*b[2] - b[1]*a[2]; + v[4] = a[2] - b[2]; + v[5] = b[1] - a[1]; + + l2[4] * (a[0]*dir[1] + b[1]*dir[0] - b[0]*dir[1] - a[1]*dir[0]) * t + l2[4] * (a[0]*b[1] - b[0]*a[1]) + + l2[5] * (a[0]*dir[2] + b[2]*dir[0] - b[0]*dir[2] - a[2]*dir[0]) * t + l2[5] * (a[0]*b[2] - b[0]*a[2]) + + l2[3] * (a[0] - b[0]) + + l2[2] * (a[1]*dir[2] + b[2]*dir[1] - b[1]*dir[2] - a[2]*dir[1]) * t + l2[2] * (a[1]*b[2] - b[1]*a[2]) + + l2[0] * (a[2] - b[2]) + + l2[1] * (b[1] - a[1]) = 0 + + t = (- l2[4] * (a[0]*b[1] - b[0]*a[1]) - + l2[5] * (a[0]*b[2] - b[0]*a[2]) - + l2[3] * (a[0] - b[0]) - + l2[2] * (a[1]*b[2] - b[1]*a[2]) - + l2[0] * (a[2] - b[2]) - + l2[1] * (b[1] - a[1])) / + (l2[4] * (a[0]*dir[1] + b[1]*dir[0] - b[0]*dir[1] - a[1]*dir[0]) + + l2[5] * (a[0]*dir[2] + b[2]*dir[0] - b[0]*dir[2] - a[2]*dir[0]) + + l2[2] * (a[1]*dir[2] + b[2]*dir[1] - b[1]*dir[2] - a[2]*dir[1])); + + d = l2[4] * (a[0]*dir[1] + b[1]*dir[0] - b[0]*dir[1] - a[1]*dir[0]) + + l2[5] * (a[0]*dir[2] + b[2]*dir[0] - b[0]*dir[2] - a[2]*dir[0]) + + l2[2] * (a[1]*dir[2] + b[2]*dir[1] - b[1]*dir[2] - a[2]*dir[1]); + + t = - ( l2[4] * (a[0]*b[1] - b[0]*a[1]) + + l2[5] * (a[0]*b[2] - b[0]*a[2]) + + l2[3] * (a[0] - b[0]) + + l2[2] * (a[1]*b[2] - b[1]*a[2]) + + l2[0] * (a[2] - b[2]) + + l2[1] * (b[1] - a[1])); + t /= d; + + MrE pats Pluecker on the head.. good monkey + + edgeDir = a - b; + d = l2[4] * (edgeDir[0]*dir[1] - edgeDir[1]*dir[0]) + + l2[5] * (edgeDir[0]*dir[2] - edgeDir[2]*dir[0]) + + l2[2] * (edgeDir[1]*dir[2] - edgeDir[2]*dir[1]); + */ + + d = l2[4] * cross[0] + l2[5] * cross[1] + l2[2] * cross[2]; + + if ( d == 0.0f ) { + *fraction = 1.0f; + // no collision ever + return false; + } + + t = -l1.PermutedInnerProduct( l2 ); + // if the lines cross each other to begin with + if ( t == 0.0f ) { + *fraction = 0.0f; + return true; + } + // fraction of movement at the time the lines cross each other + *fraction = t / d; + return true; +} + +/* +================ +CM_AddContact +================ +*/ +ID_INLINE void CM_AddContact( cm_traceWork_t *tw ) { + + if ( tw->numContacts >= tw->maxContacts ) { + return; + } + // copy contact information from trace_t + tw->contacts[tw->numContacts] = tw->trace.c; + tw->numContacts++; + // set fraction back to 1 to find all other contacts + tw->trace.fraction = 1.0f; +} + +/* +================ +CM_SetVertexSidedness + + stores for the given model vertex at which side of one of the trm edges it passes +================ +*/ +ID_INLINE void CM_SetVertexSidedness( cm_vertex_t *v, const idPluecker &vpl, const idPluecker &epl, const int bitNum ) { + if ( !(v->sideSet & (1<side = (v->side & ~(1<sideSet |= (1 << bitNum); + } +} + +/* +================ +CM_SetEdgeSidedness + + stores for the given model edge at which side one of the trm vertices +================ +*/ +ID_INLINE void CM_SetEdgeSidedness( cm_edge_t *edge, const idPluecker &vpl, const idPluecker &epl, const int bitNum ) { + if ( !(edge->sideSet & (1<side = (edge->side & ~(1<sideSet |= (1 << bitNum); + } +} + +/* +================ +idCollisionModelManagerLocal::TranslateTrmEdgeThroughPolygon +================ +*/ +void idCollisionModelManagerLocal::TranslateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ) { + int i, edgeNum; + float f1, f2, dist, d1, d2; + idVec3 start, end, normal; + cm_edge_t *edge; + cm_vertex_t *v1, *v2; + idPluecker *pl, epsPl; + + // check edges for a collision + for ( i = 0; i < poly->numEdges; i++) { + edgeNum = poly->edges[i]; + edge = tw->model->edges + abs(edgeNum); + // if this edge is already checked + if ( edge->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + // can never collide with internal edges + if ( edge->internal ) { + continue; + } + pl = &tw->polygonEdgePlueckerCache[i]; + // get the sides at which the trm edge vertices pass the polygon edge + CM_SetEdgeSidedness( edge, *pl, tw->vertices[trmEdge->vertexNum[0]].pl, trmEdge->vertexNum[0] ); + CM_SetEdgeSidedness( edge, *pl, tw->vertices[trmEdge->vertexNum[1]].pl, trmEdge->vertexNum[1] ); + // if the trm edge start and end vertex do not pass the polygon edge at different sides + if ( !(((edge->side >> trmEdge->vertexNum[0]) ^ (edge->side >> trmEdge->vertexNum[1])) & 1) ) { + continue; + } + // get the sides at which the polygon edge vertices pass the trm edge + v1 = tw->model->vertices + edge->vertexNum[INTSIGNBITSET(edgeNum)]; + CM_SetVertexSidedness( v1, tw->polygonVertexPlueckerCache[i], trmEdge->pl, trmEdge->bitNum ); + v2 = tw->model->vertices + edge->vertexNum[INTSIGNBITNOTSET(edgeNum)]; + CM_SetVertexSidedness( v2, tw->polygonVertexPlueckerCache[i+1], trmEdge->pl, trmEdge->bitNum ); + // if the polygon edge start and end vertex do not pass the trm edge at different sides + if ( !((v1->side ^ v2->side) & (1<bitNum)) ) { + continue; + } + // if there is no possible collision between the trm edge and the polygon edge + if ( !idCollisionModelManagerLocal::TranslateEdgeThroughEdge( trmEdge->cross, trmEdge->pl, *pl, &f1 ) ) { + continue; + } + // if moving away from edge + if ( f1 < 0.0f ) { + continue; + } + + // pluecker coordinate for epsilon expanded edge + epsPl.FromLine( tw->model->vertices[edge->vertexNum[0]].p + edge->normal * CM_CLIP_EPSILON, + tw->model->vertices[edge->vertexNum[1]].p + edge->normal * CM_CLIP_EPSILON ); + // calculate collision fraction with epsilon expanded edge + if ( !idCollisionModelManagerLocal::TranslateEdgeThroughEdge( trmEdge->cross, trmEdge->pl, epsPl, &f2 ) ) { + continue; + } + // if no collision with epsilon edge or moving away from edge + if ( f2 > 1.0f || f1 < f2 ) { + continue; + } + + if ( f2 < 0.0f ) { + f2 = 0.0f; + } + + if ( f2 < tw->trace.fraction ) { + tw->trace.fraction = f2; + // create plane with normal vector orthogonal to both the polygon edge and the trm edge + start = tw->model->vertices[edge->vertexNum[0]].p; + end = tw->model->vertices[edge->vertexNum[1]].p; + tw->trace.c.normal = ( end - start ).Cross( trmEdge->end - trmEdge->start ); + // FIXME: do this normalize when we know the first collision + tw->trace.c.normal.Normalize(); + tw->trace.c.dist = tw->trace.c.normal * start; + // make sure the collision plane faces the trace model + if ( tw->trace.c.normal * trmEdge->start - tw->trace.c.dist < 0.0f ) { + tw->trace.c.normal = -tw->trace.c.normal; + tw->trace.c.dist = -tw->trace.c.dist; + } + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_EDGE; + tw->trace.c.modelFeature = edgeNum; + tw->trace.c.trmFeature = trmEdge - tw->edges; + // calculate collision point + normal[0] = trmEdge->cross[2]; + normal[1] = -trmEdge->cross[1]; + normal[2] = trmEdge->cross[0]; + dist = normal * trmEdge->start; + d1 = normal * start - dist; + d2 = normal * end - dist; + f1 = d1 / ( d1 - d2 ); + //assert( f1 >= 0.0f && f1 <= 1.0f ); + tw->trace.c.point = start + f1 * ( end - start ); + // if retrieving contacts + if ( tw->getContacts ) { + CM_AddContact( tw ); + } + } + } +} + +/* +================ +CM_TranslationPlaneFraction +================ +*/ + +#if 0 + +float CM_TranslationPlaneFraction( idPlane &plane, idVec3 &start, idVec3 &end ) { + float d1, d2; + + d2 = plane.Distance( end ); + // if the end point is closer to the plane than an epsilon we still take it for a collision + if ( d2 >= CM_CLIP_EPSILON ) { + return 1.0f; + } + d1 = plane.Distance( start ); + + // if completely behind the polygon + if ( d1 <= 0.0f ) { + return 1.0f; + } + // leaves polygon + if ( d1 <= d2 ) { + return 1.0f; + } + return (d1-CM_CLIP_EPSILON) / (d1-d2); +} + +#else + +float CM_TranslationPlaneFraction( idPlane &plane, idVec3 &start, idVec3 &end ) { + float d1, d2, d2eps; + + d2 = plane.Distance( end ); + // if the end point is closer to the plane than an epsilon we still take it for a collision + // if ( d2 >= CM_CLIP_EPSILON ) { + d2eps = d2 - CM_CLIP_EPSILON; + if ( FLOATSIGNBITNOTSET(d2eps) ) { + return 1.0f; + } + d1 = plane.Distance( start ); + + // if completely behind the polygon + if ( FLOATSIGNBITSET(d1) ) { + return 1.0f; + } + // if going towards the front of the plane and + // the start and end point are not at equal distance from the plane + // if ( d1 > d2 ) + d2 = d1 - d2; + if ( d2 <= 0.0f ) { + return 1.0f; + } + return (d1-CM_CLIP_EPSILON) / d2; +} + +#endif + +/* +================ +idCollisionModelManagerLocal::TranslateTrmVertexThroughPolygon +================ +*/ +void idCollisionModelManagerLocal::TranslateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int bitNum ) { + int i, edgeNum; + float f; + cm_edge_t *edge; + + f = CM_TranslationPlaneFraction( poly->plane, v->p, v->endp ); + if ( f < tw->trace.fraction ) { + + for ( i = 0; i < poly->numEdges; i++ ) { + edgeNum = poly->edges[i]; + edge = tw->model->edges + abs(edgeNum); + CM_SetEdgeSidedness( edge, tw->polygonEdgePlueckerCache[i], v->pl, bitNum ); + if ( INTSIGNBITSET(edgeNum) ^ ((edge->side >> bitNum) & 1) ) { + return; + } + } + if ( f < 0.0f ) { + f = 0.0f; + } + tw->trace.fraction = f; + // collision plane is the polygon plane + tw->trace.c.normal = poly->plane.Normal(); + tw->trace.c.dist = poly->plane.Dist(); + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_TRMVERTEX; + tw->trace.c.modelFeature = *reinterpret_cast(&poly); + tw->trace.c.trmFeature = v - tw->vertices; + tw->trace.c.point = v->p + tw->trace.fraction * ( v->endp - v->p ); + // if retrieving contacts + if ( tw->getContacts ) { + CM_AddContact( tw ); + // no need to store the trm vertex more than once as a contact + v->used = false; + } + } +} + +/* +================ +idCollisionModelManagerLocal::TranslatePointThroughPolygon +================ +*/ +void idCollisionModelManagerLocal::TranslatePointThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v ) { + int i, edgeNum; + float f; + cm_edge_t *edge; + idPluecker pl; + + f = CM_TranslationPlaneFraction( poly->plane, v->p, v->endp ); + if ( f < tw->trace.fraction ) { + + for ( i = 0; i < poly->numEdges; i++ ) { + edgeNum = poly->edges[i]; + edge = tw->model->edges + abs(edgeNum); + // if we didn't yet calculate the sidedness for this edge + if ( edge->checkcount != idCollisionModelManagerLocal::checkCount ) { + float fl; + edge->checkcount = idCollisionModelManagerLocal::checkCount; + pl.FromLine(tw->model->vertices[edge->vertexNum[0]].p, tw->model->vertices[edge->vertexNum[1]].p); + fl = v->pl.PermutedInnerProduct( pl ); + edge->side = FLOATSIGNBITSET(fl); + } + // if the point passes the edge at the wrong side + //if ( (edgeNum > 0) == edge->side ) { + if ( INTSIGNBITSET(edgeNum) ^ edge->side ) { + return; + } + } + if ( f < 0.0f ) { + f = 0.0f; + } + tw->trace.fraction = f; + // collision plane is the polygon plane + tw->trace.c.normal = poly->plane.Normal(); + tw->trace.c.dist = poly->plane.Dist(); + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_TRMVERTEX; + tw->trace.c.modelFeature = *reinterpret_cast(&poly); + tw->trace.c.trmFeature = v - tw->vertices; + tw->trace.c.point = v->p + tw->trace.fraction * ( v->endp - v->p ); + // if retrieving contacts + if ( tw->getContacts ) { + CM_AddContact( tw ); + // no need to store the trm vertex more than once as a contact + v->used = false; + } + } +} + +/* +================ +idCollisionModelManagerLocal::TranslateVertexThroughTrmPolygon +================ +*/ +void idCollisionModelManagerLocal::TranslateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, cm_vertex_t *v, idVec3 &endp, idPluecker &pl ) { + int i, edgeNum; + float f; + cm_trmEdge_t *edge; + + f = CM_TranslationPlaneFraction( trmpoly->plane, v->p, endp ); + if ( f < tw->trace.fraction ) { + + for ( i = 0; i < trmpoly->numEdges; i++ ) { + edgeNum = trmpoly->edges[i]; + edge = tw->edges + abs(edgeNum); + + CM_SetVertexSidedness( v, pl, edge->pl, edge->bitNum ); + if ( INTSIGNBITSET(edgeNum) ^ ((v->side >> edge->bitNum) & 1) ) { + return; + } + } + if ( f < 0.0f ) { + f = 0.0f; + } + tw->trace.fraction = f; + // collision plane is the inverse trm polygon plane + tw->trace.c.normal = -trmpoly->plane.Normal(); + tw->trace.c.dist = -trmpoly->plane.Dist(); + tw->trace.c.contents = poly->contents; + tw->trace.c.material = poly->material; + tw->trace.c.type = CONTACT_MODELVERTEX; + tw->trace.c.modelFeature = v - tw->model->vertices; + tw->trace.c.trmFeature = trmpoly - tw->polys; + tw->trace.c.point = v->p + tw->trace.fraction * ( endp - v->p ); + // if retrieving contacts + if ( tw->getContacts ) { + CM_AddContact( tw ); + } + } +} + +/* +================ +idCollisionModelManagerLocal::TranslateTrmThroughPolygon + + returns true if the polygon blocks the complete translation +================ +*/ +bool idCollisionModelManagerLocal::TranslateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ) { + int i, j, k, edgeNum; + float fraction, d; + idVec3 endp; + idPluecker *pl; + cm_trmVertex_t *bv; + cm_trmEdge_t *be; + cm_trmPolygon_t *bp; + cm_vertex_t *v; + cm_edge_t *e; + + // if already checked this polygon + if ( p->checkcount == idCollisionModelManagerLocal::checkCount ) { + return false; + } + p->checkcount = idCollisionModelManagerLocal::checkCount; + + // if this polygon does not have the right contents behind it + if ( !(p->contents & tw->contents) ) { + return false; + } + + // if the the trace bounds do not intersect the polygon bounds + if ( !tw->bounds.IntersectsBounds( p->bounds ) ) { + return false; + } + + // only collide with the polygon if approaching at the front + if ( ( p->plane.Normal() * tw->dir ) > 0.0f ) { + return false; + } + + // if the polygon is too far from the first heart plane + d = p->bounds.PlaneDistance( tw->heartPlane1 ); + if ( idMath::Fabs(d) > tw->maxDistFromHeartPlane1 ) { + return false; + } + + // if the polygon is too far from the second heart plane + d = p->bounds.PlaneDistance( tw->heartPlane2 ); + if ( idMath::Fabs(d) > tw->maxDistFromHeartPlane2 ) { + return false; + } + fraction = tw->trace.fraction; + + // fast point trace + if ( tw->pointTrace ) { + idCollisionModelManagerLocal::TranslatePointThroughPolygon( tw, p, &tw->vertices[0] ); + } + else { + + // trace bounds should cross polygon plane + switch ( tw->bounds.PlaneSide( p->plane ) ) { + case PLANESIDE_CROSS: + break; + case PLANESIDE_FRONT: + if ( tw->model->isConvex ) { + tw->quickExit = true; + return true; + } + default: + return false; + } + + // calculate pluecker coordinates for the polygon edges and polygon vertices + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + e = tw->model->edges + abs(edgeNum); + // reset sidedness cache if this is the first time we encounter this edge during this trace + if ( e->checkcount != idCollisionModelManagerLocal::checkCount ) { + e->sideSet = 0; + } + // pluecker coordinate for edge + tw->polygonEdgePlueckerCache[i].FromLine( tw->model->vertices[e->vertexNum[0]].p, + tw->model->vertices[e->vertexNum[1]].p ); + + v = &tw->model->vertices[e->vertexNum[INTSIGNBITSET(edgeNum)]]; + // reset sidedness cache if this is the first time we encounter this vertex during this trace + if ( v->checkcount != idCollisionModelManagerLocal::checkCount ) { + v->sideSet = 0; + } + // pluecker coordinate for vertex movement vector + tw->polygonVertexPlueckerCache[i].FromRay( v->p, -tw->dir ); + } + // copy first to last so we can easily cycle through for the edges + tw->polygonVertexPlueckerCache[p->numEdges] = tw->polygonVertexPlueckerCache[0]; + + // trace trm vertices through polygon + for ( i = 0; i < tw->numVerts; i++ ) { + bv = tw->vertices + i; + if ( bv->used ) { + idCollisionModelManagerLocal::TranslateTrmVertexThroughPolygon( tw, p, bv, i ); + } + } + + // trace trm edges through polygon + for ( i = 1; i <= tw->numEdges; i++ ) { + be = tw->edges + i; + if ( be->used ) { + idCollisionModelManagerLocal::TranslateTrmEdgeThroughPolygon( tw, p, be); + } + } + + // trace all polygon vertices through the trm + for ( i = 0; i < p->numEdges; i++ ) { + edgeNum = p->edges[i]; + e = tw->model->edges + abs(edgeNum); + + if ( e->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + // set edge check count + e->checkcount = idCollisionModelManagerLocal::checkCount; + // can never collide with internal edges + if ( e->internal ) { + continue; + } + // got to check both vertices because we skip internal edges + for ( k = 0; k < 2; k++ ) { + + v = tw->model->vertices + e->vertexNum[k ^ INTSIGNBITSET(edgeNum)]; + // if this vertex is already checked + if ( v->checkcount == idCollisionModelManagerLocal::checkCount ) { + continue; + } + // set vertex check count + v->checkcount = idCollisionModelManagerLocal::checkCount; + + // if the vertex is outside the trace bounds + if ( !tw->bounds.ContainsPoint( v->p ) ) { + continue; + } + + // vertex end point after movement + endp = v->p - tw->dir; + // pluecker coordinate for vertex movement vector + pl = &tw->polygonVertexPlueckerCache[i+k]; + + for ( j = 0; j < tw->numPolys; j++ ) { + bp = tw->polys + j; + if ( bp->used ) { + idCollisionModelManagerLocal::TranslateVertexThroughTrmPolygon( tw, bp, p, v, endp, *pl ); + } + } + } + } + } + + // if there was a collision with this polygon and we are not retrieving contacts + if ( tw->trace.fraction < fraction && !tw->getContacts ) { + fraction = tw->trace.fraction; + endp = tw->start + fraction * tw->dir; + // decrease bounds + for ( i = 0; i < 3; i++ ) { + if ( tw->start[i] < endp[i] ) { + tw->bounds[0][i] = tw->start[i] + tw->size[0][i] - CM_BOX_EPSILON; + tw->bounds[1][i] = endp[i] + tw->size[1][i] + CM_BOX_EPSILON; + } + else { + tw->bounds[0][i] = endp[i] + tw->size[0][i] - CM_BOX_EPSILON; + tw->bounds[1][i] = tw->start[i] + tw->size[1][i] + CM_BOX_EPSILON; + } + } + } + + return ( tw->trace.fraction == 0.0f ); +} + +/* +================ +idCollisionModelManagerLocal::SetupTrm +================ +*/ +void idCollisionModelManagerLocal::SetupTrm( cm_traceWork_t *tw, const idTraceModel *trm ) { + int i, j; + + // vertices + tw->numVerts = trm->numVerts; + for ( i = 0; i < trm->numVerts; i++ ) { + tw->vertices[i].p = trm->verts[i]; + tw->vertices[i].used = false; + } + // edges + tw->numEdges = trm->numEdges; + for ( i = 1; i <= trm->numEdges; i++ ) { + tw->edges[i].vertexNum[0] = trm->edges[i].v[0]; + tw->edges[i].vertexNum[1] = trm->edges[i].v[1]; + tw->edges[i].used = false; + } + // polygons + tw->numPolys = trm->numPolys; + for ( i = 0; i < trm->numPolys; i++ ) { + tw->polys[i].numEdges = trm->polys[i].numEdges; + for ( j = 0; j < trm->polys[i].numEdges; j++ ) { + tw->polys[i].edges[j] = trm->polys[i].edges[j]; + } + tw->polys[i].plane.SetNormal( trm->polys[i].normal ); + tw->polys[i].used = false; + } + // is the trace model convex or not + tw->isConvex = trm->isConvex; +} + +/* +================ +idCollisionModelManagerLocal::SetupTranslationHeartPlanes +================ +*/ +void idCollisionModelManagerLocal::SetupTranslationHeartPlanes( cm_traceWork_t *tw ) { + idVec3 dir, normal1, normal2; + + // calculate trace heart planes + dir = tw->dir; + dir.Normalize(); + dir.NormalVectors( normal1, normal2 ); + tw->heartPlane1.SetNormal( normal1 ); + tw->heartPlane1.FitThroughPoint( tw->start ); + tw->heartPlane2.SetNormal( normal2 ); + tw->heartPlane2.FitThroughPoint( tw->start ); +} + +/* +================ +idCollisionModelManagerLocal::Translation +================ +*/ +#ifdef _DEBUG +static int entered = 0; +#endif + +void idCollisionModelManagerLocal::Translation( trace_t *results, const idVec3 &start, const idVec3 &end, + const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + + int i, j; + float dist; + bool model_rotated, trm_rotated; + idVec3 dir1, dir2, dir; + idMat3 invModelAxis, tmpAxis; + cm_trmPolygon_t *poly; + cm_trmEdge_t *edge; + cm_trmVertex_t *vert; + ALIGN16( static cm_traceWork_t tw ); + + assert( ((byte *)&start) < ((byte *)results) || ((byte *)&start) >= (((byte *)results) + sizeof( trace_t )) ); + assert( ((byte *)&end) < ((byte *)results) || ((byte *)&end) >= (((byte *)results) + sizeof( trace_t )) ); + assert( ((byte *)&trmAxis) < ((byte *)results) || ((byte *)&trmAxis) >= (((byte *)results) + sizeof( trace_t )) ); + + memset( results, 0, sizeof( *results ) ); + + if ( model < 0 || model > MAX_SUBMODELS || model > idCollisionModelManagerLocal::maxModels ) { + common->Printf("idCollisionModelManagerLocal::Translation: invalid model handle\n"); + return; + } + if ( !idCollisionModelManagerLocal::models[model] ) { + common->Printf("idCollisionModelManagerLocal::Translation: invalid model\n"); + return; + } + + // if case special position test + if ( start[0] == end[0] && start[1] == end[1] && start[2] == end[2] ) { + idCollisionModelManagerLocal::ContentsTrm( results, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + return; + } + +#ifdef _DEBUG + bool startsolid = false; + // test whether or not stuck to begin with + if ( cm_debugCollision.GetBool() ) { + if ( !entered && !idCollisionModelManagerLocal::getContacts ) { + entered = 1; + // if already messed up to begin with + if ( idCollisionModelManagerLocal::Contents( start, trm, trmAxis, -1, model, modelOrigin, modelAxis ) & contentMask ) { + startsolid = true; + } + entered = 0; + } + } +#endif + + idCollisionModelManagerLocal::checkCount++; + + tw.trace.fraction = 1.0f; + tw.trace.c.contents = 0; + tw.trace.c.type = CONTACT_NONE; + tw.contents = contentMask; + tw.isConvex = true; + tw.rotation = false; + tw.positionTest = false; + tw.quickExit = false; + tw.getContacts = idCollisionModelManagerLocal::getContacts; + tw.contacts = idCollisionModelManagerLocal::contacts; + tw.maxContacts = idCollisionModelManagerLocal::maxContacts; + tw.numContacts = 0; + tw.model = idCollisionModelManagerLocal::models[model]; + tw.start = start - modelOrigin; + tw.end = end - modelOrigin; + tw.dir = end - start; + + model_rotated = modelAxis.IsRotated(); + if ( model_rotated ) { + invModelAxis = modelAxis.Transpose(); + } + + // if optimized point trace + if ( !trm || ( trm->bounds[1][0] - trm->bounds[0][0] <= 0.0f && + trm->bounds[1][1] - trm->bounds[0][1] <= 0.0f && + trm->bounds[1][2] - trm->bounds[0][2] <= 0.0f ) ) { + + if ( model_rotated ) { + // rotate trace instead of model + tw.start *= invModelAxis; + tw.end *= invModelAxis; + tw.dir *= invModelAxis; + } + + // trace bounds + for ( i = 0; i < 3; i++ ) { + if ( tw.start[i] < tw.end[i] ) { + tw.bounds[0][i] = tw.start[i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.end[i] + CM_BOX_EPSILON; + } + else { + tw.bounds[0][i] = tw.end[i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.start[i] + CM_BOX_EPSILON; + } + } + tw.extents[0] = tw.extents[1] = tw.extents[2] = CM_BOX_EPSILON; + tw.size.Zero(); + + // setup trace heart planes + idCollisionModelManagerLocal::SetupTranslationHeartPlanes( &tw ); + tw.maxDistFromHeartPlane1 = CM_BOX_EPSILON; + tw.maxDistFromHeartPlane2 = CM_BOX_EPSILON; + // collision with single point + tw.numVerts = 1; + tw.vertices[0].p = tw.start; + tw.vertices[0].endp = tw.vertices[0].p + tw.dir; + tw.vertices[0].pl.FromRay( tw.vertices[0].p, tw.dir ); + tw.numEdges = tw.numPolys = 0; + tw.pointTrace = true; + // trace through the model + idCollisionModelManagerLocal::TraceThroughModel( &tw ); + // store results + *results = tw.trace; + results->endpos = start + results->fraction * (end - start); + results->endAxis = mat3_identity; + + if ( results->fraction < 1.0f ) { + // rotate trace plane normal if there was a collision with a rotated model + if ( model_rotated ) { + results->c.normal *= modelAxis; + results->c.point *= modelAxis; + } + results->c.point += modelOrigin; + results->c.dist += modelOrigin * results->c.normal; + } + idCollisionModelManagerLocal::numContacts = tw.numContacts; + return; + } + + // the trace fraction is too inaccurate to describe translations over huge distances + if ( tw.dir.LengthSqr() > Square( CM_MAX_TRACE_DIST ) ) { + results->fraction = 0.0f; + results->endpos = start; + results->endAxis = trmAxis; + results->c.normal = vec3_origin; + results->c.material = NULL; + results->c.point = start; + if ( session->rw ) { + session->rw->DebugArrow( colorRed, start, end, 1 ); + } + common->Printf( "idCollisionModelManagerLocal::Translation: huge translation\n" ); + return; + } + + tw.pointTrace = false; + tw.size.Clear(); + + // setup trm structure + idCollisionModelManagerLocal::SetupTrm( &tw, trm ); + + trm_rotated = trmAxis.IsRotated(); + + // calculate vertex positions + if ( trm_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + // rotate trm around the start position + tw.vertices[i].p *= trmAxis; + } + } + for ( i = 0; i < tw.numVerts; i++ ) { + // set trm at start position + tw.vertices[i].p += tw.start; + } + if ( model_rotated ) { + for ( i = 0; i < tw.numVerts; i++ ) { + // rotate trm around model instead of rotating the model + tw.vertices[i].p *= invModelAxis; + } + } + + // add offset to start point + if ( trm_rotated ) { + dir = trm->offset * trmAxis; + tw.start += dir; + tw.end += dir; + } else { + tw.start += trm->offset; + tw.end += trm->offset; + } + if ( model_rotated ) { + // rotate trace instead of model + tw.start *= invModelAxis; + tw.end *= invModelAxis; + tw.dir *= invModelAxis; + } + + // rotate trm polygon planes + if ( trm_rotated & model_rotated ) { + tmpAxis = trmAxis * invModelAxis; + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= tmpAxis; + } + } else if ( trm_rotated ) { + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= trmAxis; + } + } else if ( model_rotated ) { + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + poly->plane *= invModelAxis; + } + } + + // setup trm polygons + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + // if the trm poly plane is facing in the movement direction + dist = poly->plane.Normal() * tw.dir; + if ( dist > 0.0f || ( !trm->isConvex && dist == 0.0f ) ) { + // this trm poly and it's edges and vertices need to be used for collision + poly->used = true; + for ( j = 0; j < poly->numEdges; j++ ) { + edge = &tw.edges[abs( poly->edges[j] )]; + edge->used = true; + tw.vertices[edge->vertexNum[0]].used = true; + tw.vertices[edge->vertexNum[1]].used = true; + } + } + } + + // setup trm vertices + for ( vert = tw.vertices, i = 0; i < tw.numVerts; i++, vert++ ) { + if ( !vert->used ) { + continue; + } + // get axial trm size after rotations + tw.size.AddPoint( vert->p - tw.start ); + // calculate the end position of each vertex for a full trace + vert->endp = vert->p + tw.dir; + // pluecker coordinate for vertex movement line + vert->pl.FromRay( vert->p, tw.dir ); + } + + // setup trm edges + for ( edge = tw.edges + 1, i = 1; i <= tw.numEdges; i++, edge++ ) { + if ( !edge->used ) { + continue; + } + // edge start, end and pluecker coordinate + edge->start = tw.vertices[edge->vertexNum[0]].p; + edge->end = tw.vertices[edge->vertexNum[1]].p; + edge->pl.FromLine( edge->start, edge->end ); + // calculate normal of plane through movement plane created by the edge + dir = edge->start - edge->end; + edge->cross[0] = dir[0] * tw.dir[1] - dir[1] * tw.dir[0]; + edge->cross[1] = dir[0] * tw.dir[2] - dir[2] * tw.dir[0]; + edge->cross[2] = dir[1] * tw.dir[2] - dir[2] * tw.dir[1]; + // bit for vertex sidedness bit cache + edge->bitNum = i; + } + + // set trm plane distances + for ( poly = tw.polys, i = 0; i < tw.numPolys; i++, poly++ ) { + if ( poly->used ) { + poly->plane.FitThroughPoint( tw.edges[abs(poly->edges[0])].start ); + } + } + + // bounds for full trace, a little bit larger for epsilons + for ( i = 0; i < 3; i++ ) { + if ( tw.start[i] < tw.end[i] ) { + tw.bounds[0][i] = tw.start[i] + tw.size[0][i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.end[i] + tw.size[1][i] + CM_BOX_EPSILON; + } else { + tw.bounds[0][i] = tw.end[i] + tw.size[0][i] - CM_BOX_EPSILON; + tw.bounds[1][i] = tw.start[i] + tw.size[1][i] + CM_BOX_EPSILON; + } + if ( idMath::Fabs( tw.size[0][i] ) > idMath::Fabs( tw.size[1][i] ) ) { + tw.extents[i] = idMath::Fabs( tw.size[0][i] ) + CM_BOX_EPSILON; + } else { + tw.extents[i] = idMath::Fabs( tw.size[1][i] ) + CM_BOX_EPSILON; + } + } + + // setup trace heart planes + idCollisionModelManagerLocal::SetupTranslationHeartPlanes( &tw ); + tw.maxDistFromHeartPlane1 = 0; + tw.maxDistFromHeartPlane2 = 0; + // calculate maximum trm vertex distance from both heart planes + for ( vert = tw.vertices, i = 0; i < tw.numVerts; i++, vert++ ) { + if ( !vert->used ) { + continue; + } + dist = idMath::Fabs( tw.heartPlane1.Distance( vert->p ) ); + if ( dist > tw.maxDistFromHeartPlane1 ) { + tw.maxDistFromHeartPlane1 = dist; + } + dist = idMath::Fabs( tw.heartPlane2.Distance( vert->p ) ); + if ( dist > tw.maxDistFromHeartPlane2 ) { + tw.maxDistFromHeartPlane2 = dist; + } + } + // for epsilons + tw.maxDistFromHeartPlane1 += CM_BOX_EPSILON; + tw.maxDistFromHeartPlane2 += CM_BOX_EPSILON; + + // trace through the model + idCollisionModelManagerLocal::TraceThroughModel( &tw ); + + // if we're getting contacts + if ( tw.getContacts ) { + // move all contacts to world space + if ( model_rotated ) { + for ( i = 0; i < tw.numContacts; i++ ) { + tw.contacts[i].normal *= modelAxis; + tw.contacts[i].point *= modelAxis; + } + } + if ( modelOrigin != vec3_origin ) { + for ( i = 0; i < tw.numContacts; i++ ) { + tw.contacts[i].point += modelOrigin; + tw.contacts[i].dist += modelOrigin * tw.contacts[i].normal; + } + } + idCollisionModelManagerLocal::numContacts = tw.numContacts; + } else { + // store results + *results = tw.trace; + results->endpos = start + results->fraction * ( end - start ); + results->endAxis = trmAxis; + + if ( results->fraction < 1.0f ) { + // if the fraction is tiny the actual movement could end up zero + if ( results->fraction > 0.0f && results->endpos.Compare( start ) ) { + results->fraction = 0.0f; + } + // rotate trace plane normal if there was a collision with a rotated model + if ( model_rotated ) { + results->c.normal *= modelAxis; + results->c.point *= modelAxis; + } + results->c.point += modelOrigin; + results->c.dist += modelOrigin * results->c.normal; + } + } + +#ifdef _DEBUG + // test for missed collisions + if ( cm_debugCollision.GetBool() ) { + if ( !entered && !idCollisionModelManagerLocal::getContacts ) { + entered = 1; + // if the trm is stuck in the model + if ( idCollisionModelManagerLocal::Contents( results->endpos, trm, trmAxis, -1, model, modelOrigin, modelAxis ) & contentMask ) { + trace_t tr; + + // test where the trm is stuck in the model + idCollisionModelManagerLocal::Contents( results->endpos, trm, trmAxis, -1, model, modelOrigin, modelAxis ); + // re-run collision detection to find out where it failed + idCollisionModelManagerLocal::Translation( &tr, start, end, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); + } + entered = 0; + } + } +#endif +} diff --git a/cm/collisionmodel.h b/cm/collisionmodel.h deleted file mode 100644 index 71589a85a..000000000 --- a/cm/collisionmodel.h +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:03 sparhawk - * Initial revision - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __COLLISIONMODELMANAGER_H__ -#define __COLLISIONMODELMANAGER_H__ - -/* -=============================================================================== - - Trace model vs. polygonal model collision detection. - - Short translations are the least expensive. Retrieving contact points is - about as cheap as a short translation. Position tests are more expensive - and rotations are most expensive. - - There is no position test at the start of a translation or rotation. In other - words if a translation with start != end or a rotation with angle != 0 starts - in solid, this goes unnoticed and the collision result is undefined. - - A translation with start == end or a rotation with angle == 0 performs - a position test and fills in the trace_t structure accordingly. - -=============================================================================== -*/ - -// contact type -typedef enum { - CONTACT_NONE, // no contact - CONTACT_EDGE, // trace model edge hits model edge - CONTACT_MODELVERTEX, // model vertex hits trace model polygon - CONTACT_TRMVERTEX // trace model vertex hits model polygon -} contactType_t; - -// contact info -struct contactInfo_t { - contactType_t type; // contact type - idVec3 point; // point of contact - idVec3 normal; // contact plane normal - float dist; // contact plane distance - int contents; // contents at other side of surface - const idMaterial * material; // surface material - int modelFeature; // contact feature on model - int trmFeature; // contact feature on trace model - int entityNum; // entity the contact surface is a part of - int id; // id of clip model the contact surface is part of -}; - -// trace result -typedef struct trace_s { - float fraction; // fraction of movement completed, 1.0 = didn't hit anything - idVec3 endpos; // final position of trace model - idMat3 endAxis; // final axis of trace model - contactInfo_t c; // contact information, only valid if fraction < 1.0 -} trace_t; - -typedef int cmHandle_t; - -#define CM_CLIP_EPSILON 0.25f // always stay this distance away from any model -#define CM_BOX_EPSILON 1.0f // should always be larger than clip epsilon -#define CM_MAX_TRACE_DIST 4096.0f // maximum distance a trace model may be traced, point traces are unlimited - -class idCollisionModelManager { -public: - virtual ~idCollisionModelManager( void ) {} - - // Loads collision models from a map file. - virtual void LoadMap( const idMapFile *mapFile ) = 0; - // Frees all the collision models. - virtual void FreeMap( void ) = 0; - - // Gets the clip handle for a model. - virtual cmHandle_t LoadModel( const char *modelName, const bool precache ) = 0; - // Sets up a trace model for collision with other trace models. - virtual cmHandle_t SetupTrmModel( const idTraceModel &trm, const idMaterial *material ) = 0; - // Creates a trace model from a collision model, returns true if succesfull. - virtual bool TrmFromModel( const char *modelName, idTraceModel &trm ) = 0; - - // Gets the name of a model. - virtual const char * GetModelName( cmHandle_t model ) const = 0; - // Gets the bounds of a model. - virtual bool GetModelBounds( cmHandle_t model, idBounds &bounds ) const = 0; - // Gets all contents flags of brushes and polygons of a model ored together. - virtual bool GetModelContents( cmHandle_t model, int &contents ) const = 0; - // Gets a vertex of a model. - virtual bool GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const = 0; - // Gets an edge of a model. - virtual bool GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const = 0; - // Gets a polygon of a model. - virtual bool GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const = 0; - - // Translates a trace model and reports the first collision if any. - virtual void Translation( trace_t *results, const idVec3 &start, const idVec3 &end, - const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; - // Rotates a trace model and reports the first collision if any. - virtual void Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation, - const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; - // Returns the contents touched by the trace model or 0 if the trace model is in free space. - virtual int Contents( const idVec3 &start, - const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; - // Stores all contact points of the trace model with the model, returns the number of contacts. - virtual int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, - const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) = 0; - - // Tests collision detection. - virtual void DebugOutput( const idVec3 &origin ) = 0; - // Draws a model. - virtual void DrawModel( cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis, - const idVec3 &viewOrigin, const float radius ) = 0; - // Prints model information, use -1 handle for accumulated model info. - virtual void ModelInfo( cmHandle_t model ) = 0; - // Lists all loaded models. - virtual void ListModels( void ) = 0; - // Writes a collision model file for the given map entity. - virtual bool WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ) = 0; -}; - -extern idCollisionModelManager * collisionModelManager; - -#endif /* !__COLLISIONMODELMANAGER_H__ */ diff --git a/d3game.sln b/d3game.sln deleted file mode 100644 index 3731d1cc7..000000000 --- a/d3game.sln +++ /dev/null @@ -1,44 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Game", "d3game.vcproj", "{49BEC5C6-B964-417A-851E-808886B57430}" - ProjectSection(ProjectDependencies) = postProject - {49BEC5C6-B964-417A-851E-808886B57400} = {49BEC5C6-B964-417A-851E-808886B57400} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idLib", "idlib.vcproj", "{49BEC5C6-B964-417A-851E-808886B57400}" -EndProject -Project("{8BC9CEB9-8B4A-11D0-8D11-00A0C91BC942}") = "DOOM3.exe", "..\DOOM3.exe", "{795A9372-D4FF-4DB2-A5A6-993988F23D9E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug with inlines and memory log|Win32 = Debug with inlines and memory log|Win32 - Debug with inlines|Win32 = Debug with inlines|Win32 - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.Build.0 = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.Build.0 = Release|Win32 - {795A9372-D4FF-4DB2-A5A6-993988F23D9E}.Debug with inlines and memory log|Win32.ActiveCfg = Debug - {795A9372-D4FF-4DB2-A5A6-993988F23D9E}.Debug with inlines|Win32.ActiveCfg = Debug - {795A9372-D4FF-4DB2-A5A6-993988F23D9E}.Debug|Win32.ActiveCfg = Debug - {795A9372-D4FF-4DB2-A5A6-993988F23D9E}.Release|Win32.ActiveCfg = Debug - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/d3game.vcproj b/d3game.vcproj deleted file mode 100644 index 264e13fa9..000000000 --- a/d3game.vcproj +++ /dev/null @@ -1,2797 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/darkmod_src.cfg b/darkmod_src.cfg deleted file mode 100644 index 1d303c15b..000000000 --- a/darkmod_src.cfg +++ /dev/null @@ -1,946 +0,0 @@ -# Doxyfile 1.2.16 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = The Dark Mod - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = Alpha - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = DarkmodDoc - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Korean, -# Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovene, -# Spanish, Swedish and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these class will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of -# the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. - -STRIP_FROM_PATH = - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower case letters. If set to YES upper case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are adviced to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = YES - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. - -INHERIT_DOCS = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consist of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp -# *.h++ *.idl *.odl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = *.cod - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories -# that are symbolic links (a Unix filesystem feature) are excluded from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse. - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = YES - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = YES - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the Html help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, -# or Internet explorer 4.0+). Note that for large projects the tree generation -# can take a very long time. In such cases it is better to disable this feature. -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = YES - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_XML = NO - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line and do not end with a semicolon. Such function macros are typically -# used for boiler-plate code, and will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = YES - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superceded by the HAVE_DOT option below. This is only a fallback. It is -# recommended to install and use dot, since it yield more powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermedate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = /usr/local/bin/ - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = diff --git a/debug.sh b/debug.sh deleted file mode 100755 index 81c30c051..000000000 --- a/debug.sh +++ /dev/null @@ -1 +0,0 @@ -gdb attach `ps -C doom.x86 -o pid= ` diff --git a/dmlauncher/D3ProcessChecker.cpp b/dmlauncher/D3ProcessChecker.cpp index 7b08d3d62..417970bf4 100644 --- a/dmlauncher/D3ProcessChecker.cpp +++ b/dmlauncher/D3ProcessChecker.cpp @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision: 4852 $ - * $Date: 2011-05-17 08:04:03 +0200 (Di, 17 Mai 2011) $ - * $Author: greebo $ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "D3ProcessChecker.h" diff --git a/dmlauncher/D3ProcessChecker.h b/dmlauncher/D3ProcessChecker.h index 0ccaeb330..70662140a 100644 --- a/dmlauncher/D3ProcessChecker.h +++ b/dmlauncher/D3ProcessChecker.h @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision: 4852 $ - * $Date: 2011-05-17 08:04:03 +0200 (Di, 17 Mai 2011) $ - * $Author: greebo $ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef D3PROCESSCHECKER_H_ #define D3PROCESSCHECKER_H_ diff --git a/dmlauncher/Launcher.cpp b/dmlauncher/Launcher.cpp index 4f53eeab0..f1e9d073c 100644 --- a/dmlauncher/Launcher.cpp +++ b/dmlauncher/Launcher.cpp @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Launcher.h" diff --git a/dmlauncher/Launcher.h b/dmlauncher/Launcher.h index ce41fb1d5..9a7292969 100644 --- a/dmlauncher/Launcher.h +++ b/dmlauncher/Launcher.h @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _LAUNCHER_H_ #define _LAUNCHER_H_ diff --git a/dmlauncher/SConscript.tdmlauncher b/dmlauncher/SConscript.tdmlauncher index caa5fe651..28edbc708 100644 --- a/dmlauncher/SConscript.tdmlauncher +++ b/dmlauncher/SConscript.tdmlauncher @@ -4,15 +4,24 @@ # Adapted from id's game sconscript # Author: greebo -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#*************************************************************************** +#***************************************************************************** +# The Dark Mod GPL Source Code +# +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. +# +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +# ***************************************************************************** import sys, os, string diff --git a/dmlauncher/SConstruct b/dmlauncher/SConstruct index df681031b..28fee3c7a 100644 --- a/dmlauncher/SConstruct +++ b/dmlauncher/SConstruct @@ -4,15 +4,24 @@ # Adapted from id's game sconscript # Author: greebo -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#*************************************************************************** +#***************************************************************************** +# The Dark Mod GPL Source Code +# +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. +# +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +# ***************************************************************************** import sys, os, time, commands, re, pickle, StringIO, commands, pdb, string import SCons diff --git a/dmlauncher/TraceLog.cpp b/dmlauncher/TraceLog.cpp index 4cd8f45a7..782555481 100644 --- a/dmlauncher/TraceLog.cpp +++ b/dmlauncher/TraceLog.cpp @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "TraceLog.h" diff --git a/dmlauncher/TraceLog.h b/dmlauncher/TraceLog.h index a3597dc8a..44fcde563 100644 --- a/dmlauncher/TraceLog.h +++ b/dmlauncher/TraceLog.h @@ -1,13 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - *************************************************************************/ - +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _TRACELOG_H_ #define _TRACELOG_H_ diff --git a/dmlauncher/dmlauncher.cpp b/dmlauncher/dmlauncher.cpp index 10cbece85..487a2bddb 100644 --- a/dmlauncher/dmlauncher.cpp +++ b/dmlauncher/dmlauncher.cpp @@ -1,12 +1,21 @@ -/************************************************************************* - * - * PROJECT: The Dark Mod - Launcher - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - *************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* Darkmod Launcher. Launches doom3. Builds command-line args diff --git a/dmlauncher/dmlauncher.sln b/dmlauncher/dmlauncher.sln deleted file mode 100644 index ffab37d80..000000000 --- a/dmlauncher/dmlauncher.sln +++ /dev/null @@ -1,19 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dmlauncher", "dmlauncher.vcproj", "{7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Debug|Win32.ActiveCfg = Debug|Win32 - {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Debug|Win32.Build.0 = Debug|Win32 - {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Release|Win32.ActiveCfg = Release|Win32 - {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/dmlauncher/dmlauncher.vcproj b/dmlauncher/dmlauncher.vcproj deleted file mode 100644 index fe4b3e750..000000000 --- a/dmlauncher/dmlauncher.vcproj +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dmlauncher/libs/libboost_filesystem-gcc43-1_34_1.a b/dmlauncher/libs/libboost_filesystem-gcc43-1_34_1.a deleted file mode 100644 index 796f5c7eb..000000000 Binary files a/dmlauncher/libs/libboost_filesystem-gcc43-1_34_1.a and /dev/null differ diff --git a/dmlauncher/tdmlauncher.sln b/dmlauncher/tdmlauncher.sln new file mode 100644 index 000000000..7a8d354ef --- /dev/null +++ b/dmlauncher/tdmlauncher.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdmlauncher", "tdmlauncher.vcxproj", "{7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Debug|Win32.Build.0 = Debug|Win32 + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Release|Win32.ActiveCfg = Release|Win32 + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dmlauncher/tdmlauncher.vcxproj b/dmlauncher/tdmlauncher.vcxproj new file mode 100644 index 000000000..18d363be2 --- /dev/null +++ b/dmlauncher/tdmlauncher.vcxproj @@ -0,0 +1,124 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D} + Win32Proj + + + + Application + Static + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\darkmod\ + Debug\ + true + false + ..\..\darkmod\ + Release\ + false + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\include;..\win32\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + Psapi.lib;%(AdditionalDependencies) + $(OutDir)tdmlauncher.exe + ..\lib;..\win32\lib;%(AdditionalLibraryDirectories) + true + $(OutDir)dmlauncher.pdb + Windows + mainCRTStartup + false + + + MachineX86 + + + + + ..\include;..\win32\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + Psapi.lib;%(AdditionalDependencies) + $(OutDir)tdmlauncher.exe + ..\lib;..\win32\lib;%(AdditionalLibraryDirectories) + false + Windows + true + true + mainCRTStartup + false + + + MachineX86 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmlauncher/tdmlauncher.vcxproj.filters b/dmlauncher/tdmlauncher.vcxproj.filters new file mode 100644 index 000000000..a4dc8fef4 --- /dev/null +++ b/dmlauncher/tdmlauncher.vcxproj.filters @@ -0,0 +1,43 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/doom.sln b/doom.sln new file mode 100644 index 000000000..dc1d9587e --- /dev/null +++ b/doom.sln @@ -0,0 +1,104 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libs", "libs", "{347D107C-D787-4408-A60D-86FA45997F9B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "exes", "exes", "{003B01AB-152D-45C8-BF45-E5A035042D7F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dlls", "dlls", "{1E2B3940-65F8-4D8F-9EEE-85E94EBBC6DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Game", "game.vcxproj", "{49BEC5C6-B964-417A-851E-808886B57430}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idLib", "idlib.vcxproj", "{49BEC5C6-B964-417A-851E-808886B57400}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TypeInfo", "typeinfo.vcxproj", "{6EA6406F-3E65-47D9-8246-D6660A81606F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DoomDLL", "doomdll.vcxproj", "{49BEC5C6-B964-417A-851E-808886B57420}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MayaImport", "MayaImport.vcxproj", "{49BEC5C6-B964-417A-851E-808886B574F1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug with inlines and memory log|Win32 = Debug with inlines and memory log|Win32 + Debug with inlines|Win32 = Debug with inlines|Win32 + Debug|Win32 = Debug|Win32 + Dedicated Debug with inlines|Win32 = Dedicated Debug with inlines|Win32 + Dedicated Debug|Win32 = Dedicated Debug|Win32 + Dedicated Release|Win32 = Dedicated Release|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.ActiveCfg = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.Build.0 = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Debug with inlines|Win32.ActiveCfg = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Debug with inlines|Win32.Build.0 = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Debug|Win32.ActiveCfg = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Debug|Win32.Build.0 = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Release|Win32.ActiveCfg = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Dedicated Release|Win32.Build.0 = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.ActiveCfg = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.Build.0 = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.ActiveCfg = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.Build.0 = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Debug with inlines|Win32.ActiveCfg = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Debug with inlines|Win32.Build.0 = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Debug|Win32.ActiveCfg = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Debug|Win32.Build.0 = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Release|Win32.ActiveCfg = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Dedicated Release|Win32.Build.0 = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.ActiveCfg = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.Build.0 = Release|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug|Win32.ActiveCfg = Debug|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Debug|Win32.Build.0 = Debug|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Debug with inlines|Win32.ActiveCfg = Dedicated Debug with inlines|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Debug with inlines|Win32.Build.0 = Dedicated Debug with inlines|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Debug|Win32.ActiveCfg = Dedicated Debug|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Debug|Win32.Build.0 = Dedicated Debug|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Release|Win32.ActiveCfg = Dedicated Release|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Dedicated Release|Win32.Build.0 = Dedicated Release|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Release|Win32.ActiveCfg = Release|Win32 + {6EA6406F-3E65-47D9-8246-D6660A81606F}.Release|Win32.Build.0 = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug|Win32.ActiveCfg = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Debug|Win32.Build.0 = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Debug with inlines|Win32.ActiveCfg = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Debug with inlines|Win32.Build.0 = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Debug|Win32.ActiveCfg = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Debug|Win32.Build.0 = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Release|Win32.ActiveCfg = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Dedicated Release|Win32.Build.0 = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Release|Win32.ActiveCfg = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B57420}.Release|Win32.Build.0 = Release|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Dedicated Debug with inlines|Win32.ActiveCfg = Dedicated Debug with inlines|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Dedicated Debug|Win32.ActiveCfg = Dedicated Debug|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Dedicated Release|Win32.ActiveCfg = Dedicated Release|Win32 + {49BEC5C6-B964-417A-851E-808886B574F1}.Release|Win32.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {49BEC5C6-B964-417A-851E-808886B57400} = {347D107C-D787-4408-A60D-86FA45997F9B} + {6EA6406F-3E65-47D9-8246-D6660A81606F} = {003B01AB-152D-45C8-BF45-E5A035042D7F} + {49BEC5C6-B964-417A-851E-808886B57420} = {003B01AB-152D-45C8-BF45-E5A035042D7F} + {49BEC5C6-B964-417A-851E-808886B57430} = {1E2B3940-65F8-4D8F-9EEE-85E94EBBC6DF} + {49BEC5C6-B964-417A-851E-808886B574F1} = {1E2B3940-65F8-4D8F-9EEE-85E94EBBC6DF} + EndGlobalSection +EndGlobal diff --git a/doomdll.vcxproj b/doomdll.vcxproj new file mode 100644 index 000000000..db932ec07 --- /dev/null +++ b/doomdll.vcxproj @@ -0,0 +1,2514 @@ + + + + + Debug with inlines and memory log + Win32 + + + Debug with inlines + Win32 + + + Debug + Win32 + + + Dedicated Debug with inlines + Win32 + + + Dedicated Debug + Win32 + + + Dedicated Release + Win32 + + + Release + Win32 + + + + DoomDLL + {49BEC5C6-B964-417A-851E-808886B57420} + DoomDLL + + + + + + + Win32Proj + + + + Application + false + MultiByte + false + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + false + + + Application + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) + + + + true + true + true + + + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + + + + + {49bec5c6-b964-417a-851e-808886b57400} + false + + + {6ea6406f-3e65-47d9-8246-d6660a81606f} + false + + + + + + \ No newline at end of file diff --git a/doomdll.vcxproj.filters b/doomdll.vcxproj.filters new file mode 100644 index 000000000..6b449cbaf --- /dev/null +++ b/doomdll.vcxproj.filters @@ -0,0 +1,2544 @@ + + + + + {0b350a6a-58d3-441e-bdcf-1115ff7edc1d} + + + {f5d345cb-9f26-4da2-9ef1-335e871dcce5} + + + {78d0b2e7-608c-46f4-8945-a3fbf061ccae} + + + {19b363f5-76a7-4256-b7f0-7a6ec012d09d} + + + {7fdc46b4-13a1-46c2-9be6-af8a85990431} + + + {2b6b512d-2388-41b9-8880-402e156ec20b} + + + {63e32bc7-65cb-4ee2-8b8f-2d546502dbf4} + + + {40269b4b-9ecd-432f-a25a-a802a60ad93d} + + + {ce6b537e-d981-4a37-9907-5460db169903} + + + {cae44ca7-f71e-479d-b9a2-f7a9b8676924} + + + {4bd5585c-21a4-4c0b-a27c-d41a167f5f43} + + + {9a23ae4a-a963-4984-a90b-6902bf5665c5} + + + {8672dd57-2df1-454a-be5e-1ea2d6647cef} + + + {c4397186-0c42-4057-82b4-17dea14c173f} + + + {900f9550-2a58-4b22-82a9-298f01f6ac51} + + + {af0039d7-487e-4e9c-859d-c7b4c194b985} + + + {de4b7a7a-3038-4cac-a5d1-95b015b026ec} + + + {1041a97c-8f17-4731-a48e-a94cf40753fe} + + + {082fe765-698a-408b-ae96-04db4f62a5dc} + + + {e51aaa76-0800-450c-9cf5-63484392d7a3} + + + {83ad091e-339c-4f64-ad0d-e0776c4fe142} + + + {07d88fa0-f779-44b7-87b1-2c0d8214aa3f} + + + {6984ce76-c3bf-4003-97cf-64b50f951fe8} + + + {4533a5c7-30f7-4306-9a19-f4a7d8e453b5} + + + {c53bab3f-79ce-44fe-916e-04c51a7d93a9} + + + {bdc52484-8a48-4b82-b396-9228f0304808} + + + {6b6929e6-0646-465b-9c53-e0b8535bf175} + + + {33958bbe-2c45-4c6c-bf13-2bdea604a1f1} + + + {44a955ea-0e6e-4cd1-aeb0-5e355aabe9bc} + + + {e245eb22-9902-436d-b292-1bd362aee648} + + + {527cec37-a4ca-4466-9d91-f925361a7aea} + + + {06cc72d4-f944-4821-8693-667ae16daaee} + + + {60417518-1848-4aa4-87d8-b8d81c6c1ac4} + + + {1116e2f3-d474-4b47-b913-d95b022f80b2} + + + {b3166d25-0562-49da-bc8d-961006fe1785} + + + + + CM + + + CM + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Sound + + + Sound + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc\books + + + Sound\vorbissrc\books + + + Sound\vorbissrc\books + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbissrc\modes + + + Sound\vorbis + + + Sound\vorbis + + + Sound\vorbis + + + Sound\ogg + + + Sound\ogg + + + Sys + + + Sys + + + Sys + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Tools\Compilers + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\DMap + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + + + CM + + + CM + + + CM + + + CM + + + CM + + + CM + + + CM + + + CM + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Framework\Async + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Renderer\JPeg-6 + + + Sound + + + Sound + + + Sound + + + Sound + + + Sound + + + Sound + + + Sound + + + Sound + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\vorbissrc + + + Sound\oggsrc + + + Sound\oggsrc + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys + + + Sys\RC + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\AAS + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\DMap + + + Tools\Compilers\RenderBump + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Compilers\RoqVQ + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Decl + + + Tools\Decl + + + Tools\Decl + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\Sound + + + Tools\Sound + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\Particle + + + Tools\PDA + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Script + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + Ui + + + + + Sound + + + Sound\vorbissrc + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Sys\RC\res + + + Tools\ComAfx + + + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + Sys\RC + + + + + Tools + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\AF + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\ComAfx + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Common\PropTree + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Debugger + + + Tools\Decl + + + Tools\Decl + + + Tools\Decl + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\GuiEd + + + Tools\Sound + + + Tools\Sound + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\MaterialEditor + + + Tools\Particle + + + Tools\PDA + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Radiant + + + Tools\Script + + + \ No newline at end of file diff --git a/doomdll.vcxproj.user b/doomdll.vcxproj.user new file mode 100644 index 000000000..c820a96ad --- /dev/null +++ b/doomdll.vcxproj.user @@ -0,0 +1,38 @@ + + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath c:\games\doom3 +set fs_game darkmod + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + + $(OutDir)DOOM3.exe + WindowsLocalDebugger + +set fs_basepath "C:\Program Files (x86)\Steam\steamapps\common\doom 3" +set com_allowConsole 1 +set si_pure 0 + + \ No newline at end of file diff --git a/eula.development kit.rtf b/eula.development kit.rtf deleted file mode 100644 index 2d3f1c5a0..000000000 --- a/eula.development kit.rtf +++ /dev/null @@ -1,241 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:03 sparhawk - * Initial revision - * - ***************************************************************************/ - -{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f11\froman\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} -{\f35\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f176\froman\fcharset128\fprq1{\*\panose 00000000000000000000}@MS Mincho;}{\f177\froman\fcharset238\fprq2 Times New Roman CE;}{\f178\froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f180\froman\fcharset161\fprq2 Times New Roman Greek;}{\f181\froman\fcharset162\fprq2 Times New Roman Tur;}{\f182\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f183\froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f184\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f185\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f197\fmodern\fcharset238\fprq1 Courier New CE;}{\f198\fmodern\fcharset204\fprq1 Courier New Cyr;} -{\f200\fmodern\fcharset161\fprq1 Courier New Greek;}{\f201\fmodern\fcharset162\fprq1 Courier New Tur;}{\f202\fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f203\fmodern\fcharset178\fprq1 Courier New (Arabic);} -{\f204\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f205\fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f527\fswiss\fcharset238\fprq2 Tahoma CE;}{\f528\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f530\fswiss\fcharset161\fprq2 Tahoma Greek;} -{\f531\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f532\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f533\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f534\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f535\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} -{\f536\fswiss\fcharset222\fprq2 Tahoma (Thai);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; -\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ -\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 -\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 Plain Text;}{\s16\qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 -Body Text;}{\s17\qj \fi-720\li1440\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 Body Text Indent;}{\s18\ql \li0\ri0\widctlpar -\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext18 header;}{\s19\ql \li0\ri0\widctlpar -\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext19 footer;}{\s20\qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 -\b\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext20 Body Text 2;}{\s21\qc \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \b\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext21 Title;} -{\*\cs22 \additive \sbasedon10 \styrsid15538956 page number;}{\s23\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f35\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext23 \ssemihidden \styrsid13987891 -Balloon Text;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid812838912\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat11\levelspace0\levelindent0{\leveltext\leveltemplateid-1723273448 -\'02\'00.;}{\levelnumbers\'01;}\fbias0 \fi-720\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;} -\fi-360\li1800\jclisttab\tx1800\lin1800 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\fi-180\li2520\jclisttab\tx2520\lin2520 } -{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\fi-360\li3240\jclisttab\tx3240\lin3240 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 -\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\fi-360\li3960\jclisttab\tx3960\lin3960 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1 -\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\fi-180\li4680\jclisttab\tx4680\lin4680 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext -\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5400\jclisttab\tx5400\lin5400 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713 -\'02\'07.;}{\levelnumbers\'01;}\fi-360\li6120\jclisttab\tx6120\lin6120 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\fi-180\li6840 -\jclisttab\tx6840\lin6840 }{\listname ;}\listid316225388}}{\*\listoverridetable{\listoverride\listid316225388\listoverridecount0\ls1}}{\*\rsidtbl \rsid336730\rsid399436\rsid406316\rsid1539794\rsid2190517\rsid2254137\rsid2570230\rsid2782285\rsid3172333 -\rsid3356405\rsid3429659\rsid3546842\rsid3755724\rsid3945188\rsid4068369\rsid4078708\rsid4159818\rsid4535378\rsid4726574\rsid4997456\rsid5117373\rsid5252406\rsid5596352\rsid5930124\rsid6098781\rsid6099282\rsid6122216\rsid6166940\rsid6186163\rsid6249450 -\rsid6301700\rsid6442038\rsid6447482\rsid6624163\rsid7106940\rsid7149160\rsid7157100\rsid7174890\rsid7412454\rsid7473120\rsid7496172\rsid7895822\rsid8142905\rsid8270881\rsid8324675\rsid8465115\rsid9243334\rsid9253099\rsid9575298\rsid9858980\rsid9924168 -\rsid10099548\rsid10159481\rsid11282962\rsid11304168\rsid11344957\rsid11825741\rsid12009836\rsid12089053\rsid12479790\rsid12525691\rsid12655544\rsid12855299\rsid12916664\rsid12926986\rsid12929118\rsid13008411\rsid13064352\rsid13180332\rsid13649385 -\rsid13792965\rsid13987891\rsid14513105\rsid15161735\rsid15538956\rsid15677057\rsid15740827\rsid16546257}{\*\generator Microsoft Word 11.0.5604;}{\info{\title LIMITED USE SOFTWARE LICENSE AGREEMENT}{\author Internal Machine}{\operator raduffy} -{\creatim\yr2004\mo10\dy15\hr14\min25}{\revtim\yr2004\mo10\dy15\hr14\min25}{\printim\yr2004\mo9\dy27\hr16\min17}{\version2}{\edmins0}{\nofpages5}{\nofwords2375}{\nofchars13538}{\*\company Mpath Interactive}{\nofcharsws15882}{\vern24689}}{\*\userprops -{\propname _AdHocReviewCycleID}\proptype3{\staticval -1564658940}{\propname _EmailSubject}\proptype30{\staticval SDK Doom 3 EULA}{\propname _AuthorEmail}\proptype30{\staticval wcloud@hhdulaw.com}{\propname _AuthorEmailDisplayName}\proptype30{\staticval D. - Wade Cloud}{\propname _PreviousAdHocReviewCycleID}\proptype3{\staticval 1130798080}{\propname _ReviewingToolsShownOnce}\proptype30{\staticval }}\margl1440\margr1440\margb1080 -\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 -\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\nolnhtadjtbl\nojkernpunct\rsidroot6442038 \fet0{\*\ftnsep \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 { -\insrsid12525691 \chftnsep -\par }}{\*\ftnsepc \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid12525691 \chftnsepc -\par }}{\*\aftnsep \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid12525691 \chftnsep -\par }}{\*\aftnsepc \pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid12525691 \chftnsepc -\par }}\sectd \psz1\linex0\footery1080\endnhere\sectdefaultcl\sectrsid15538956\sftnbj {\footer \pard\plain \s19\ql \li0\ri0\widctlpar\tqr\tx9360\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid15538956 -\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid8270881 -\par -\par }{\i\ul\insrsid8270881\charrsid9970214 DOOM 3}{\ul\insrsid8270881 Software Development Kit }{\ul\insrsid8270881\charrsid6166940 Limited}{\ul\insrsid8270881 Use License Agreement}{\insrsid8270881 \tab Page }{\field{\*\fldinst {\cs22\insrsid8270881 PAGE -}}{\fldrslt {\cs22\lang1024\langfe1024\noproof\insrsid12525691 1}}}{\cs22\insrsid8270881 -\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} -{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 -\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \s21\qc \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6447482 -\b\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\i\fs22\insrsid6447482\charrsid11212988 DOOM 3}{\fs22\insrsid12655544 SOFTWARE DEVELOPMENT KIT}{\fs22\insrsid6447482 -\par }{\fs22\insrsid6447482\charrsid6166940 LIMITED}{\fs22\insrsid6447482\charrsid15538956 USE LICENSE AGREEMENT -\par }\pard\plain \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par }\pard \qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 {\fs22\insrsid11344957\charrsid15538956 This}{\fs22\insrsid399436 }{\i\fs22\insrsid399436 DOOM 3}{\fs22\insrsid11344957\charrsid15538956 }{ -\fs22\insrsid7106940 Software Development Kit Limited Use }{\fs22\insrsid11344957\charrsid15538956 License Agreement (this "Agreement") is a legal agreement }{\fs22\insrsid16546257 among}{\fs22\insrsid11344957\charrsid15538956 - you, the end-user, and Id Software, Inc. ("Id Software")}{\fs22\insrsid5252406 . }{\b\fs22\insrsid5252406 BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THIS SOFTWARE}{\b\fs22\insrsid12655544 DEVELOPMENT KIT (THE "SOFTWARE")}{\b\fs22\insrsid5252406 - FOR THE GAME PROGRAM ENTITLED }{\b\i\fs22\insrsid5252406 DOOM\~3}{\b\fs22\insrsid5252406 , BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU ARE A -GREEING TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU ACKNOWLEDGE AND UNDERSTAND THAT IN ORDER TO OPERATE THE SOFTWARE, YOU MUST HAVE THE FULL VERSION OF THE ID}{\b\fs22\insrsid8142905 SOFTWARE}{\b\fs22\insrsid5252406 GAME ENTITLED }{ -\b\i\fs22\insrsid5252406 DOOM}{\b\i\fs22\insrsid8142905 \~}{\b\i\fs22\insrsid5252406 3}{\b\fs22\insrsid5252406 INSTALLED ON YOUR COMPUTER.}{\fs22\insrsid11344957\charrsid15538956 -\par -\par }\pard\plain \s15\qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f0\fs22\insrsid11344957\charrsid15538956 1.\tab Grant of License}{ -\b\f0\fs22\insrsid11344957\charrsid7157100 .}{\f0\fs22\insrsid11344957\charrsid15538956 - Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software only in executable or object code form. The term -"Software" includes all elements of the Software, including, without limitation, data files and screen displays. You are not receiving any ownership or proprietary right, title}{\f0\fs22\insrsid6122216 ,}{\f0\fs22\insrsid11344957\charrsid15538956 - or interest in or to the Softwar}{\f0\fs22\insrsid7157100 e or the copyrights, trademarks}{\f0\fs22\insrsid6122216 ,}{\f0\fs22\insrsid11344957\charrsid15538956 or other rights related thereto. For purposes}{\f0\fs22\insrsid5930124 - of the first sentence of this S}{\f0\fs22\insrsid11344957\charrsid15538956 -ection, "use" means loading the Software into RAM and/or onto computer hard drive, as well as installation of the Software on a hard disk or other storage device, and means the uses permitted in }{\f0\fs22\insrsid5930124 S}{ -\f0\fs22\insrsid11344957\charrsid15538956 ections 2}{\f0\fs22\insrsid7157100 and }{\f0\fs22\insrsid5930124 5}{\f0\fs22\insrsid6166940 herein}{\f0\fs22\insrsid11344957\charrsid15538956 below. You agree that the Software will not be downloaded, shipp}{ -\f0\fs22\insrsid7157100 ed, transferred, exported or re\_}{\f0\fs22\insrsid11344957\charrsid15538956 exported into an}{\f0\fs22\insrsid6122216 y country in violation of the United }{\f0\fs22\insrsid11344957\charrsid15538956 S}{\f0\fs22\insrsid6122216 -tates}{\f0\fs22\insrsid11344957\charrsid15538956 Export Administration Act (or any other law governing such matters) by you or anyone at your direction}{\f0\fs22\insrsid7157100 ,}{\f0\fs22\insrsid11344957\charrsid15538956 - and that you will not utilize and will not authorize anyone to utilize }{\f0\fs22\insrsid7157100 the Software }{\f0\fs22\insrsid11344957\charrsid15538956 in any other manner in violation of any applicable law. The Software shall not be downloa}{ -\f0\fs22\insrsid6186163 ded or otherwise exported or re\_}{\f0\fs22\insrsid11344957\charrsid15538956 exported into (or to a national or resident}{\f0\fs22\insrsid6122216 of) any country to which the United }{\f0\fs22\insrsid11344957\charrsid15538956 S}{ -\f0\fs22\insrsid6122216 tates}{\f0\fs22\insrsid11344957\charrsid15538956 has embargoed goods}{\f0\fs22\insrsid6122216 ,}{\f0\fs22\insrsid11344957\charrsid15538956 or to anyone or into any country who/}{\f0\fs22\insrsid6186163 that}{ -\f0\fs22\insrsid11344957\charrsid15538956 are prohibited, by applicable law, from receiving such property.}{\fs22\loch\af0\hich\af0\dbch\af11\insrsid11344957\charrsid15538956 \hich\af0\dbch\af11\loch\f0 }{\f0\fs22\insrsid11344957\charrsid15538956 -In exercising your limited rights hereunder, you shall comply, at all times, with all applicable laws, regulations, ordinances}{\f0\fs22\insrsid6122216 ,}{\f0\fs22\insrsid11344957\charrsid15538956 - and statutes. Id Software reserves all rights not granted in this Agreement, including, without limitation, all rights to Id Software's trademarks.}{\fs22\loch\af0\hich\af0\dbch\af11\insrsid11344957\charrsid15538956 -\par -\par }\pard\plain \s16\qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\fs22\insrsid11344957\charrsid15538956 2.\tab Permitted New Creations}{ -\b\fs22\insrsid11344957\charrsid6186163 .}{\fs22\insrsid11344957\charrsid15538956 Subjec -t to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to }{\fs22\insrsid7473120 use}{\fs22\insrsid11344957\charrsid15538956 - the Software}{\fs22\insrsid7473120 to create for the software game }{\i\fs22\insrsid7473120 DOOM 3}{\fs22\insrsid11344957\charrsid15538956 your own modifications (the "New Creations") }{\fs22\insrsid4068369 that }{ -\fs22\insrsid11344957\charrsid15538956 shall operate only with}{\fs22\insrsid7473120 }{\i\fs22\insrsid7473120 DOOM 3}{\fs22\insrsid11344957\charrsid15538956 (but not any demo, test}{\fs22\insrsid9575298 ,}{\fs22\insrsid11344957\charrsid15538956 - or other version of}{\fs22\insrsid7473120 }{\i\fs22\insrsid7473120 DOOM 3}{\fs22\insrsid11344957\charrsid15538956 -). You may include within the New Creations certain textures and other images (the "Software Images") from the Software. You shall not create any New Creations }{\fs22\insrsid4068369 that}{\fs22\insrsid9575298 infringe against any third-}{ -\fs22\insrsid11344957\charrsid15538956 party right or }{\fs22\insrsid4068369 that}{\fs22\insrsid11344957\charrsid15538956 are libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. }{\fs22\insrsid9575298 }{ -\fs22\insrsid11344957\charrsid15538956 You agree that the New Creations will not be downloaded, shipped, transferred, exported}{\fs22\insrsid9575298 ,}{\fs22\insrsid11344957\charrsid15538956 or re}{\fs22\insrsid4068369 \_}{ -\fs22\insrsid11344957\charrsid15538956 exported into an}{\fs22\insrsid9575298 y country in violation of the United }{\fs22\insrsid11344957\charrsid15538956 S}{\fs22\insrsid9575298 tates}{\fs22\insrsid11344957\charrsid15538956 - Export Administration Act (or any other law governing such matters) by you or anyone at your direction}{\fs22\insrsid4068369 ,}{\fs22\insrsid11344957\charrsid15538956 and that you will not utilize and will not authorize anyone}{\fs22\insrsid4068369 - to utilize}{\fs22\insrsid11344957\charrsid15538956 }{\fs22\insrsid4068369\charrsid15538956 the New Creations }{\fs22\insrsid11344957\charrsid15538956 in any other manner in v}{\fs22\insrsid4068369 iolation of any applicable law. }{ -\fs22\insrsid11344957\charrsid15538956 The New Creations shall not be downloa}{\fs22\insrsid4068369 ded or otherwise exported or re\_}{\fs22\insrsid11344957\charrsid15538956 exported into (or to a national or resident}{\fs22\insrsid9575298 - of) any country to which the United }{\fs22\insrsid11344957\charrsid15538956 S}{\fs22\insrsid9575298 tates}{\fs22\insrsid11344957\charrsid15538956 has embargoed goods or to anyone or into any country who/}{\fs22\insrsid4068369 that}{ -\fs22\insrsid11344957\charrsid15538956 are prohibited, by applicable law, from receiving such property. You shall not rent, sell, lease, lend, offer on a pay-per-play basis}{\fs22\insrsid9575298 ,}{\fs22\insrsid11344957\charrsid15538956 - or otherwise commercially exploit or commercially distribute the New Creations. You are permitted to distribute, without any cost or charge, the New Creations }{\fs22\insrsid9575298 only }{\fs22\insrsid11344957\charrsid15538956 -to other end-users so long as such distribution is n}{\fs22\insrsid4068369 ot infringing against any third-}{\fs22\insrsid9575298 party right and }{\fs22\insrsid9575298\charrsid15538956 otherwise }{\fs22\insrsid11344957\charrsid15538956 -is not illegal or unlawful. As noted below, in the event you commit any breach of this Agreement, your license and this Agreement automatically }{\fs22\insrsid4068369 shall }{\fs22\insrsid11344957\charrsid15538956 terminate, without notice. -\par }\pard\plain \qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par }{\b\fs22\insrsid11344957\charrsid15538956 3.\tab Prohibitions with Regard to the Software}{\b\fs22\insrsid11344957\charrsid3172333 .}{\fs22\insrsid11344957\charrsid15538956 }{\fs22\insrsid12479790 }{\fs22\insrsid11344957\charrsid15538956 -You, whether directly or indirectly, shall }{\b\fs22\insrsid11344957\charrsid15538956 not}{\fs22\insrsid11344957\charrsid15538956 do any of the following acts: -\par -\par }\pard \qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 {\fs22\insrsid11344957\charrsid15538956 a.\tab rent the Software; -\par -\par b.\tab sell the Software; -\par -\par c.\tab lease or lend the Software; -\par -\par d.\tab offer the Software on a pay-per-play basis; -\par -\par }\pard\plain \s17\qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 e.\tab distribute the Software -}{\fs22\insrsid3356405 (except as permitted under Section 5 hereinbelow)}{\fs22\insrsid11344957\charrsid15538956 ; -\par }\pard\plain \qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par }\pard\plain \s17\qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 f.\tab -in any other manner and through any medium whatsoever commercially exploit the Software or use the Software for any commercial purpose; -\par }\pard\plain \qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par }\pard\plain \s17\qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 g.\tab -disassemble, reverse engineer, decompile, modify (except as permitted }{\fs22\insrsid8324675 under}{\fs22\insrsid11344957\charrsid15538956 }{\fs22\insrsid5930124 S}{\fs22\insrsid11344957\charrsid15538956 ection}{\fs22\insrsid3172333 \~}{ -\fs22\insrsid11344957\charrsid15538956 2 hereinabove) or alter the Software; -\par }\pard\plain \qj \fi-720\li1840\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1840\itap0\culi720\pararsid12525691 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par h.\tab translate the Software; -\par -\par i.\tab reproduce or copy the Software (e}{\fs22\insrsid4159818 xcept as permitted }{\fs22\insrsid8324675 under}{\fs22\insrsid4159818 }{\fs22\insrsid5930124 S}{\fs22\insrsid4159818 ection }{\fs22\insrsid4726574 5}{\fs22\insrsid12479790 herein}{ -\fs22\insrsid11344957\charrsid15538956 below); -\par -\par j.\tab publicly display the Software; -\par -\par }{\fs22\insrsid3172333 k.\tab }{\fs22\insrsid11344957\charrsid15538956 prepare or develop derivative w}{\fs22\insrsid6166940 orks based upon the Software;}{\fs22\insrsid11344957\charrsid15538956 -\par -\par }{\fs22\insrsid3172333 l.\tab }{\fs22\insrsid11344957\charrsid15538956 remove or alter any notices or other markings or legends, such as trademark or copyright notices, affixed on or within the Software}{\fs22\insrsid6166940 ; or}{\fs22\insrsid11344957 - -\par }{\fs22\insrsid6166940 -\par m.\tab remove, alter, modify, disable, or reduce any of the anti-piracy measures contained in the Software}{\fs22\insrsid12089053 or in }{\i\fs22\insrsid12089053 DOOM 3}{\fs22\insrsid7496172 ,}{\fs22\insrsid11282962 - including, without limitation, measures relating to multiplayer play}{\fs22\insrsid6166940 .}{\fs22\insrsid6166940\charrsid15538956 -\par }\pard \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\fs22\insrsid11344957\charrsid15538956 -\par }\pard \qj \fi720\li0\ri0\widctlpar\faauto\rin0\lin0\itap0\pararsid13064352 {\b\fs22\insrsid6098781\charrsid7174890 4.\tab Prohibition against Cheat Programs.}{\fs22\insrsid6098781\charrsid7174890 }{\fs22\insrsid11282962\charrsid7174890 Any attempt - by you, either directly or indirectly, to circumvent or bypass any element of the Software to gain any advantage in multiplayer play of the Software is a material breach of this Agreement. }{\fs22\insrsid6098781\charrsid7174890 It is a }{ -\fs22\insrsid11282962\charrsid7174890 material }{\fs22\insrsid6098781\charrsid7174890 breach of this Agreement for you, whether directly or indirectly, to create, develop, copy, reproduce, distribute, or otherwise make any use of any software program }{ -\fs22\insrsid15161735\charrsid7174890 or any}{\fs22\insrsid7174890 modification to the Software ("}{\fs22\insrsid15161735\charrsid7174890 Cheat Program}{\fs22\insrsid7174890 "}{\fs22\insrsid15161735\charrsid7174890 ) itself }{ -\fs22\insrsid6098781\charrsid7174890 that enables or allows the user thereof to obtain an advantage }{\fs22\insrsid13649385\charrsid7174890 or otherwise exploit another Software player or user }{\fs22\insrsid6098781\charrsid7174890 -when playing the Software against other }{\fs22\insrsid13649385\charrsid7174890 players or }{\fs22\insrsid6098781\charrsid7174890 users on a local area network, any other network, or on the Internet. }{\fs22\insrsid15161735\charrsid7174890 H}{ -\fs22\insrsid6098781\charrsid7174890 acking into the executable of the Software}{\fs22\insrsid15161735\charrsid7174890 , modification of the Software,}{\fs22\insrsid6098781\charrsid7174890 or }{\fs22\insrsid15161735\charrsid7174890 any}{ -\fs22\insrsid6098781\charrsid7174890 other use of the Software in connection with the creation, development,}{\fs22\insrsid15161735\charrsid7174890 or use of }{\fs22\insrsid6098781\charrsid7174890 any such unauthorized }{ -\fs22\insrsid15161735\charrsid7174890 Cheat Program}{\fs22\insrsid6098781\charrsid7174890 is a material breach of this Agreement.}{\fs22\insrsid11282962\charrsid7174890 }{\fs22\insrsid15161735\charrsid7174890 -Cheat Programs include, but are not limited to,}{\b\fs22\insrsid15161735\charrsid7174890 }{\fs22\insrsid15161735\charrsid7174890 programs that allow Software players or users to see through walls or other }{\fs22\insrsid7174890 level geometry;}{ -\fs22\insrsid15161735\charrsid7174890 programs that allow Software players or users to change their rate of speed outside the a}{\fs22\insrsid7174890 llowable limits of the Software;}{\fs22\insrsid15161735\charrsid7174890 - programs that crash either and/or other Software players, users, PC clients}{\fs22\insrsid7174890 , or network servers;}{\fs22\insrsid15161735\charrsid7174890 programs that automatically target other Software}{\fs22\insrsid7174890 }{ -\fs22\insrsid15161735\charrsid7174890 players or users (commonly referred to as }{\fs22\insrsid7174890 "}{\fs22\insrsid15161735\charrsid7174890 aimbots}{\fs22\insrsid7174890 "}{\fs22\insrsid15161735\charrsid7174890 ) }{\fs22\insrsid7174890 that }{ -\fs22\insrsid15161735\charrsid7174890 automatically simulate }{\fs22\insrsid15740827\charrsid7174890 Software }{\fs22\insrsid15161735\charrsid7174890 player }{\fs22\insrsid15740827\charrsid7174890 or user }{\fs22\insrsid15161735\charrsid7174890 -input for the purpose of gaining an advantage over other }{\fs22\insrsid15740827\charrsid7174890 Software }{\fs22\insrsid15161735\charrsid7174890 players}{\fs22\insrsid15740827\charrsid7174890 or users}{\fs22\insrsid7174890 ;}{ -\fs22\insrsid15161735\charrsid7174890 or any other program or modification that functions in a similar capacity or allows }{\fs22\insrsid15740827\charrsid7174890 any }{\fs22\insrsid15161735\charrsid7174890 prohibited conduct. -\par -\par }\pard \qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 {\fs22\insrsid11282962 In the event you breach this }{\fs22\insrsid5930124 S}{\fs22\insrsid11282962 -ection or otherwise breach this Agreement, your license and this Agreement automatically shall terminate, without notice, and you shall have no right to play the Software against other players or make any other use of the Software.}{ -\fs22\insrsid6098781\charrsid6098781 -\par }{\b\fs22\insrsid6098781 -\par 5}{\b\fs22\insrsid11344957\charrsid15538956 .\tab }{\b\fs22\insrsid8324675 Permitted Distribution and Copying.}{\fs22\insrsid8324675 - So long as this Agreement accompanies each copy you make of the Software, and so long as you comply fully at all times with t -his Agreement, Id Software grants to you the non-exclusive and limited right to copy the Software and to distribute such copies of the Software free of charge for non-commercial purposes that shall include the free-of-charge distribution of copies of the -Software as mounted on the covers of magazines; provided, however, you shall }{\b\fs22\insrsid8324675 not }{\fs22\insrsid8324675 -copy or distribute the Software in any infringing manner or in any manner that violates any law or third-party right, and you shall }{\b\fs22\insrsid8324675 not}{\fs22\insrsid8324675 distribute the Software together with an -y material that infringes against any third-party right or that is libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. Subject to the terms and conditions of this Agreement, you also may: (i) download one (1) copy of the -Software or copy the Software from the CD ROM on which you received your copy of the Software onto your computer RAM; (ii) copy the Software from your computer RAM onto your computer hard drive; and (iii)\~ -make one (1) "backup" or archival copy of the Softwa -re on one (1) hard disk. In exercising your limited rights hereunder, you shall comply at all times with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement. }{ -\b\fs22\insrsid8324675 You shall not distribute -the Software commercially unless you first enter into a separate contract with Id Software, on terms and conditions determined in Id Software's sole discretion, and only upon your receipt of a written agreement executed by an authorized officer of Id Soft -ware.}{\fs22\insrsid11344957\charrsid15538956 -\par -\par }{\b\fs22\insrsid6098781 6}{\b\fs22\insrsid11344957\charrsid15538956 .\tab Intellectual Property Rights}{\b\fs22\insrsid11344957\charrsid6249450 .}{\fs22\insrsid11344957\charrsid15538956 The Software and all copyrights, trademarks}{ -\fs22\insrsid11304168 ,}{\fs22\insrsid11344957\charrsid15538956 and all other conceivable intellectual property rights related to the Software are owned by Id Software and are protected by United States copyright laws, international treaty provisions}{ -\fs22\insrsid11304168 ,}{\fs22\insrsid11344957\charrsid15538956 and all applicable law, such as the Lanham Act. You must treat the Software like any other copyrighted material, as required by 17 U.S.C. \'a7}{\fs22\insrsid6249450 }{ -\fs22\insrsid11344957\charrsid15538956 101 }{\i\fs22\insrsid11344957\charrsid6249450 et seq.}{\fs22\insrsid11344957\charrsid15538956 and other applicable law. You agree to use your best efforts to see that any user of }{\fs22\insrsid10159481 -the Software licensed hereunder}{\fs22\insrsid11344957\charrsid15538956 }{\fs22\insrsid13180332 or }{\fs22\insrsid11344957\charrsid15538956 -the New Creations complies with this Agreement. You agree that you are receiving a copy of the Software by limited license only and not by sale and that the "first sale" doctrine of 17}{\fs22\insrsid6249450 \~}{\fs22\insrsid11344957\charrsid15538956 -U.S.C. \'a7}{\fs22\insrsid6249450 }{\fs22\insrsid11344957\charrsid15538956 109 does not apply to your receipt or use of the Software. }{\fs22\insrsid11304168 }{\fs22\insrsid11344957\charrsid15538956 This }{\fs22\insrsid5930124 S}{ -\fs22\insrsid11344957\charrsid15538956 ection shall survive the cancellation or termination of this Agreement. -\par -\par }{\b\fs22\insrsid6098781 7}{\b\fs22\insrsid11344957\charrsid15538956 .\tab NO ID SOFTWARE WARRANTIES}{\b\fs22\insrsid11344957\charrsid15677057 .}{\fs22\insrsid11344957\charrsid15538956 }{\b\fs22\insrsid11344957\charrsid15538956 -ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE}{\b\fs22\insrsid11304168 ,}{\b\fs22\insrsid11344957\charrsid15538956 - AND ANY WARRANTY OF NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE SOFTWARE IMAGES}{\b\fs22\insrsid11304168 ,}{\b\fs22\insrsid11344957\charrsid15538956 AND OTHERW}{\b\fs22\insrsid15677057 ISE. THE SOFTWARE IS PROVIDED "}{ -\b\fs22\insrsid11344957\charrsid15538956 AS IS}{\b\fs22\insrsid15677057 "}{\b\fs22\insrsid11344957\charrsid15538956 AND WITHOUT WARRANTY. ID SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE}{\b\fs22\insrsid11304168 - WILL BE UNINTERRUPTED OR ERROR-}{\b\fs22\insrsid11344957\charrsid15538956 FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD -NOT BE RELIED UPON.}{\fs22\insrsid11344957\charrsid15538956 This }{\fs22\insrsid5930124 S}{\fs22\insrsid11344957\charrsid15538956 ection shall survive the cancellation or}{\fs22\insrsid11304168 termination of this Agreement.}{ -\fs22\insrsid11344957\charrsid15538956 -\par -\par }{\b\fs22\insrsid10159481 8}{\b\fs22\insrsid11344957\charrsid15538956 .\tab Governing Law, Venue, Indemnity}{\b\fs22\insrsid6099282 ,}{\b\fs22\insrsid11344957\charrsid15538956 and Liability Limitation}{\b\fs22\insrsid11344957\charrsid15677057 .}{ -\fs22\insrsid11344957\charrsid15538956 This Agreement shall be construed in accordance with and governed by the applicable laws of the State of Texas}{\fs22\insrsid6166940 (but excluding conflicts of laws principles)}{ -\fs22\insrsid11344957\charrsid15538956 and applicable United States federal law. Except as set forth below, exclusive venue for all litigation regarding this Agreement shall be in Dallas County, Texas}{\fs22\insrsid3755724 ,}{ -\fs22\insrsid11344957\charrsid15538956 and you agree to submit to the jurisdiction of the federal and state courts in Dallas County, Texas}{\fs22\insrsid3755724 ,}{\fs22\insrsid11344957\charrsid15538956 for any such litigation. }{\fs22\insrsid3755724 } -{\fs22\insrsid11344957\charrsid15538956 You hereby agree to indemnify, defend and hold harmless Id Software and Id Software's officers, employees, directors, agents, licensees (excluding you), sub-licensees (excluding you), successors}{ -\fs22\insrsid6099282 ,}{\fs22\insrsid11344957\charrsid15538956 and assigns from and against all losses, lawsuits, damages, causes of action}{\fs22\insrsid6099282 ,}{\fs22\insrsid11344957\charrsid15538956 - and claims relating to and/or arising from the New Creations or the distribution or other use of the New Creations or relating to and/or arising from your breach of this Agreement. You agree that your unauthorized use of the Software Images}{ -\fs22\insrsid10159481 }{\fs22\insrsid11344957\charrsid15538956 or the Software, or any part thereof, immediately and irreparably }{\fs22\insrsid3755724 may }{\fs22\insrsid11344957\charrsid15538956 -damage Id Software such that Id Software could not be adequately compensated solely by a monetary award, and in such event, at Id Software's option, that Id Software shall be entitled to an injunctive order, in addition to all other available remedies}{ -\fs22\insrsid3755724 ,}{\fs22\insrsid11344957\charrsid15538956 including a monetary award, to prohibit such unauthorized use without the necessity of Id Software posting bond or other security. }{\b\fs22\insrsid11344957\charrsid15538956 -IN ANY CASE, ID SOFTWA}{\b\fs22\insrsid10159481 RE}{\b\fs22\insrsid6099282 AND ID SOFTWARE}{\b\fs22\insrsid10159481 '}{\b\fs22\insrsid11344957\charrsid15538956 -S OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB}{\b\fs22\insrsid3755724 -LICENSEES (EXCLUD}{\b\fs22\insrsid11344957\charrsid15538956 ING YOU), SUCCESSORS}{\b\fs22\insrsid6099282 ,}{ -\b\fs22\insrsid11344957\charrsid15538956 AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR PUNITIVE DAMAGES}{\b\fs22\insrsid6099282 ,}{ -\b\fs22\insrsid11344957\charrsid15538956 OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLI}{\b\fs22\insrsid3755724 GENCE, STRICT PRODUCT LIABILITY}{\b\fs22\insrsid6099282 ,}{ -\b\fs22\insrsid11344957\charrsid15538956 OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE OR }{\b\fs22\insrsid9253099 ITS }{\b\fs22\insrsid11344957\charrsid15538956 -RESPECTIVE AGENT(S) HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY.}{\fs22\insrsid11344957\charrsid15538956 Some jurisdictions do not allow the exclusion - or limitation of incidental or consequential damages, so the above limitation or exclusi}{\fs22\insrsid5930124 on may not apply to you. This S}{\fs22\insrsid11344957\charrsid15538956 -ection shall survive the cancellation or termination of this Agreement. -\par -\par }{\b\fs22\insrsid10159481 9}{\b\fs22\insrsid3429659 .\tab United }{\b\fs22\insrsid11344957\charrsid15538956 S}{\b\fs22\insrsid3429659 tates}{\b\fs22\insrsid11344957\charrsid15538956 Government Restricted Rights}{\b\fs22\insrsid11344957\charrsid7895822 .} -{\fs22\insrsid11344957\charrsid15538956 To the extent applicable, the United States Government shall have }{\fs22\insrsid7895822 only }{\fs22\insrsid11344957\charrsid15538956 -those rights to use the Software as expressly stated and expressly limited and restricted in this Agreement, as provided in 48 C.F.R. \'a7\'a7 227.7201 through 227.7204, inclusive. -\par -\par }\pard\plain \s16\qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\fs22\insrsid11344957\charrsid15538956 1}{\b\fs22\insrsid10159481 0}{ -\b\fs22\insrsid11344957\charrsid15538956 .\tab General Provisions}{\b\fs22\insrsid11344957\charrsid7895822 .}{\fs22\insrsid11344957\charrsid15538956 - Neither this Agreement nor any part or portion hereof shall be assigned or sublicensed by you. Id Software may assign its }{\fs22\insrsid10159481 r}{\fs22\insrsid11344957\charrsid15538956 ights under this Agreement in }{\fs22\insrsid10159481 its}{ -\fs22\insrsid11344957\charrsid15538956 sole discretion. Should any provision of this Agreement be held to be void, invalid, unenforceable}{\fs22\insrsid2190517 ,}{\fs22\insrsid11344957\charrsid15538956 - or illegal by a court of competent jurisdiction, the validity and enforceability of the other provisions shall not be affected thereby. If any provision is determined to be unenforceable by a court of competent jurisdiction, you agree to a modificati -on of such provision to provide for enforcement of the provision's intent, to the extent permitted by applicable law. Failure of Id Software to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or -of the right to enforce such provision. }{\b\fs22\insrsid11344957\charrsid15538956 IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH}{\b\fs22\insrsid2190517 ,}{\b\fs22\insrsid11344957\charrsid15538956 OR }{\b\fs22\insrsid7895822 YOUR }{ -\b\fs22\insrsid11344957\charrsid15538956 BREACH OF ANY TERM OR PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT AUTOMATICALLY }{\b\fs22\insrsid7895822 SHALL }{\b\fs22\insrsid11344957\charrsid15538956 -TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE MAY PURSUE ALL }{\b\fs22\insrsid6166940 RELIEF AND REMEDIES AGAINST YOU}{\b\fs22\insrsid11344957\charrsid15538956 }{\b\fs22\insrsid7895822 THAT}{\b\fs22\insrsid11344957\charrsid15538956 - ARE AVAILABLE UNDER APPLICABLE LAW AND/OR THIS AGREEMENT.}{\fs22\insrsid11344957\charrsid15538956 Immediately upon termination of this Agreement, any and all rights you are granted hereunder shall terminate, you shall have no right to use the Software} -{\fs22\insrsid10159481 }{\fs22\insrsid11344957\charrsid15538956 or the New Creations, in any manner, you immediately }{\fs22\insrsid7895822 shall }{\fs22\insrsid11344957\charrsid15538956 destroy all copies of the Software}{\fs22\insrsid10159481 }{ -\fs22\insrsid11344957\charrsid15538956 and the New Creations in your possession, custody}{\fs22\insrsid2190517 ,}{\fs22\insrsid11344957\charrsid15538956 - or control, and all rights granted hereunder shall revert, without notice, to and be vested in Id Software. -\par }\pard\plain \qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid11344957\charrsid15538956 -\par }\pard\plain \s20\qj \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13064352 \b\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\fs22\insrsid9858980 -YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS AGREEMENT, AND YOU UNDERSTAND THAT, BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR - COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN, SEPARATE AGREEMENTS, IF ANY, BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLU -S -IVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO RELATING TO THE SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, BETWEEN ID AND YOU RELATING -TO THE SUBJECT MATTER OF THIS AGREEMENT.}{\b0\fs22\insrsid7895822 -\par }{\b0\fs22\insrsid7895822\charrsid7895822 -\par }} \ No newline at end of file diff --git a/framework/BuildDefines.h b/framework/BuildDefines.h new file mode 100644 index 000000000..1bd579569 --- /dev/null +++ b/framework/BuildDefines.h @@ -0,0 +1,126 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Preprocessor settings for compiling different versions. + +=============================================================================== +*/ + +// memory debugging +//#define ID_REDIRECT_NEWDELETE +//#define ID_DEBUG_MEMORY +//#define ID_DEBUG_UNINITIALIZED_MEMORY + +// if enabled, the console won't toggle upon ~, unless you start the binary with +set com_allowConsole 1 +// Ctrl+Alt+~ will always toggle the console no matter what +#ifndef ID_CONSOLE_LOCK + #if defined(_WIN32) || defined(MACOS_X) + #ifdef _DEBUG + #define ID_CONSOLE_LOCK 0 + #else + #define ID_CONSOLE_LOCK 1 + #endif + #else + #define ID_CONSOLE_LOCK 0 + #endif +#endif + +// useful for network debugging, turns off 'LAN' checks, all IPs are classified 'internet' +#ifndef ID_NOLANADDRESS + #define ID_NOLANADDRESS 0 +#endif + +// let .dds be loaded from FS without altering pure state. only for developement. +#ifndef ID_PURE_ALLOWDDS + #define ID_PURE_ALLOWDDS 0 +#endif + +// build an exe with no CVAR_CHEAT controls +#ifndef ID_ALLOW_CHEATS + #define ID_ALLOW_CHEATS 0 +#endif + +#ifndef ID_ENABLE_CURL + #define ID_ENABLE_CURL 1 +#endif + +// fake a pure client. useful to connect an all-debug client to a server +#ifndef ID_FAKE_PURE + #define ID_FAKE_PURE 0 +#endif + +// verify checksums in clientinfo traffic +// NOTE: this makes the network protocol incompatible +#ifndef ID_CLIENTINFO_TAGS + #define ID_CLIENTINFO_TAGS 0 +#endif + +// for win32 this is defined in preprocessor settings so that MFC can be +// compiled out. +//#define ID_DEDICATED + +// if this is defined, the executable positively won't work with any paks other +// than the demo pak, even if productid is present. +//#define ID_DEMO_BUILD + +// don't define ID_ALLOW_TOOLS when we don't want tool code in the executable. +#if defined( _WIN32 ) && !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD ) + #define ID_ALLOW_TOOLS +#endif + +// don't do backtraces in release builds. +// atm, we have no useful way to reconstruct the trace, so let's leave it off +#define ID_BT_STUB +#ifndef ID_BT_STUB + #if defined( __linux__ ) + #if defined( _DEBUG ) + #define ID_BT_STUB + #endif + #else + #define ID_BT_STUB + #endif +#endif + +#ifndef ID_ENFORCE_KEY +# if !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD ) +# define ID_ENFORCE_KEY 1 +# else +# define ID_ENFORCE_KEY 0 +# endif +#endif + +#ifndef ID_OPENAL +# if ( defined(_WIN32) || defined(MACOS_X) ) && !defined( ID_DEDICATED ) +# define ID_OPENAL 1 +# else +# define ID_OPENAL 0 +# endif +#endif + +#ifndef ID_ALLOW_D3XP +# if defined( MACOS_X ) +# define ID_ALLOW_D3XP 0 +# else +# define ID_ALLOW_D3XP 1 +# endif +#endif + diff --git a/framework/BuildVersion.h b/framework/BuildVersion.h new file mode 100644 index 000000000..09a9179ed --- /dev/null +++ b/framework/BuildVersion.h @@ -0,0 +1,19 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +const int BUILD_NUMBER = 1304; diff --git a/framework/CVarSystem.cpp b/framework/CVarSystem.cpp new file mode 100644 index 000000000..69cd6acfd --- /dev/null +++ b/framework/CVarSystem.cpp @@ -0,0 +1,1248 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +idCVar * idCVar::staticVars = NULL; + +/* +=============================================================================== + + idInternalCVar + +=============================================================================== +*/ + +class idInternalCVar : public idCVar { + friend class idCVarSystemLocal; +public: + idInternalCVar( void ); + idInternalCVar( const char *newName, const char *newValue, int newFlags ); + idInternalCVar( const idCVar *cvar ); + virtual ~idInternalCVar( void ); + + const char ** CopyValueStrings( const char **strings ); + void Update( const idCVar *cvar ); + void UpdateValue( void ); + void UpdateCheat( void ); + void Set( const char *newValue, bool force, bool fromServer ); + void Reset( void ); + +private: + idStr nameString; // name + idStr resetString; // resetting will change to this value + idStr valueString; // value + idStr descriptionString; // description + + virtual void InternalSetString( const char *newValue ); + virtual void InternalServerSetString( const char *newValue ); + virtual void InternalSetBool( const bool newValue ); + virtual void InternalSetInteger( const int newValue ); + virtual void InternalSetFloat( const float newValue ); +}; + +/* +============ +idInternalCVar::idInternalCVar +============ +*/ +idInternalCVar::idInternalCVar( void ) { +} + +/* +============ +idInternalCVar::idInternalCVar +============ +*/ +idInternalCVar::idInternalCVar( const char *newName, const char *newValue, int newFlags ) { + nameString = newName; + name = nameString.c_str(); + valueString = newValue; + value = valueString.c_str(); + resetString = newValue; + descriptionString = ""; + description = descriptionString.c_str(); + flags = ( newFlags & ~CVAR_STATIC ) | CVAR_MODIFIED; + valueMin = 1; + valueMax = -1; + valueStrings = NULL; + valueCompletion = 0; + UpdateValue(); + UpdateCheat(); + internalVar = this; +} + +/* +============ +idInternalCVar::idInternalCVar +============ +*/ +idInternalCVar::idInternalCVar( const idCVar *cvar ) { + nameString = cvar->GetName(); + name = nameString.c_str(); + valueString = cvar->GetString(); + value = valueString.c_str(); + resetString = cvar->GetString(); + descriptionString = cvar->GetDescription(); + description = descriptionString.c_str(); + flags = cvar->GetFlags() | CVAR_MODIFIED; + valueMin = cvar->GetMinValue(); + valueMax = cvar->GetMaxValue(); + valueStrings = CopyValueStrings( cvar->GetValueStrings() ); + valueCompletion = cvar->GetValueCompletion(); + UpdateValue(); + UpdateCheat(); + internalVar = this; +} + +/* +============ +idInternalCVar::~idInternalCVar +============ +*/ +idInternalCVar::~idInternalCVar( void ) { + Mem_Free( valueStrings ); + valueStrings = NULL; +} + + +/* +============ +idInternalCVar::CopyValueStrings +============ +*/ +const char **idInternalCVar::CopyValueStrings( const char **strings ) { + int i, totalLength; + const char **ptr; + char *str; + + if ( !strings ) { + return NULL; + } + + totalLength = 0; + for ( i = 0; strings[i] != NULL; i++ ) { + totalLength += idStr::Length( strings[i] ) + 1; + } + + ptr = (const char **) Mem_Alloc( ( i + 1 ) * sizeof( char * ) + totalLength ); + str = (char *) (((byte *)ptr) + ( i + 1 ) * sizeof( char * ) ); + + for ( i = 0; strings[i] != NULL; i++ ) { + ptr[i] = str; + strcpy( str, strings[i] ); + str += idStr::Length( strings[i] ) + 1; + } + ptr[i] = NULL; + + return ptr; +} + +/* +============ +idInternalCVar::Update +============ +*/ +void idInternalCVar::Update( const idCVar *cvar ) { + + // if this is a statically declared variable + if ( cvar->GetFlags() & CVAR_STATIC ) { + + if ( flags & CVAR_STATIC ) { + + // the code has more than one static declaration of the same variable, make sure they have the same properties + if ( resetString.Icmp( cvar->GetString() ) != 0 ) { + common->Warning( "CVar '%s' declared multiple times with different initial value", nameString.c_str() ); + } + if ( ( flags & (CVAR_BOOL|CVAR_INTEGER|CVAR_FLOAT) ) != ( cvar->GetFlags() & (CVAR_BOOL|CVAR_INTEGER|CVAR_FLOAT) ) ) { + common->Warning( "CVar '%s' declared multiple times with different type", nameString.c_str() ); + } + if ( valueMin != cvar->GetMinValue() || valueMax != cvar->GetMaxValue() ) { + common->Warning( "CVar '%s' declared multiple times with different minimum/maximum", nameString.c_str() ); + } + + } + + // the code is now specifying a variable that the user already set a value for, take the new value as the reset value + resetString = cvar->GetString(); + descriptionString = cvar->GetDescription(); + description = descriptionString.c_str(); + valueMin = cvar->GetMinValue(); + valueMax = cvar->GetMaxValue(); + Mem_Free( valueStrings ); + valueStrings = CopyValueStrings( cvar->GetValueStrings() ); + valueCompletion = cvar->GetValueCompletion(); + UpdateValue(); + cvarSystem->SetModifiedFlags( cvar->GetFlags() ); + } + + flags |= cvar->GetFlags(); + + UpdateCheat(); + + // only allow one non-empty reset string without a warning + if ( resetString.Length() == 0 ) { + resetString = cvar->GetString(); + } else if ( cvar->GetString()[0] && resetString.Cmp( cvar->GetString() ) != 0 ) { + common->Warning( "cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", nameString.c_str(), resetString.c_str(), cvar->GetString() ); + } +} + +/* +============ +idInternalCVar::UpdateValue +============ +*/ +void idInternalCVar::UpdateValue( void ) { + bool clamped = false; + + if ( flags & CVAR_BOOL ) { + integerValue = ( atoi( value ) != 0 ); + floatValue = integerValue; + if ( idStr::Icmp( value, "0" ) != 0 && idStr::Icmp( value, "1" ) != 0 ) { + valueString = idStr( (bool)( integerValue != 0 ) ); + value = valueString.c_str(); + } + } else if ( flags & CVAR_INTEGER ) { + integerValue = (int)atoi( value ); + if ( valueMin < valueMax ) { + if ( integerValue < valueMin ) { + integerValue = (int)valueMin; + clamped = true; + } else if ( integerValue > valueMax ) { + integerValue = (int)valueMax; + clamped = true; + } + } + if ( clamped || !idStr::IsNumeric( value ) || idStr::FindChar( value, '.' ) ) { + valueString = idStr( integerValue ); + value = valueString.c_str(); + } + floatValue = (float)integerValue; + } else if ( flags & CVAR_FLOAT ) { + floatValue = (float)atof( value ); + if ( valueMin < valueMax ) { + if ( floatValue < valueMin ) { + floatValue = valueMin; + clamped = true; + } else if ( floatValue > valueMax ) { + floatValue = valueMax; + clamped = true; + } + } + if ( clamped || !idStr::IsNumeric( value ) ) { + valueString = idStr( floatValue ); + value = valueString.c_str(); + } + integerValue = (int)floatValue; + } else { + if ( valueStrings && valueStrings[0] ) { + integerValue = 0; + for ( int i = 0; valueStrings[i]; i++ ) { + if ( valueString.Icmp( valueStrings[i] ) == 0 ) { + integerValue = i; + break; + } + } + valueString = valueStrings[integerValue]; + value = valueString.c_str(); + floatValue = (float)integerValue; + } else if ( valueString.Length() < 32 ) { + floatValue = (float)atof( value ); + integerValue = (int)floatValue; + } else { + floatValue = 0.0f; + integerValue = 0; + } + } +} + +/* +============ +idInternalCVar::UpdateCheat +============ +*/ +void idInternalCVar::UpdateCheat( void ) { + // all variables are considered cheats except for a few types + if ( flags & ( CVAR_NOCHEAT | CVAR_INIT | CVAR_ROM | CVAR_ARCHIVE | CVAR_USERINFO | CVAR_SERVERINFO | CVAR_NETWORKSYNC ) ) { + flags &= ~CVAR_CHEAT; + } else { + flags |= CVAR_CHEAT; + } +} + +/* +============ +idInternalCVar::Set +============ +*/ +void idInternalCVar::Set( const char *newValue, bool force, bool fromServer ) { + if ( session && session->IsMultiplayer() && !fromServer ) { +#ifndef ID_TYPEINFO + if ( ( flags & CVAR_NETWORKSYNC ) && idAsyncNetwork::client.IsActive() ) { + common->Printf( "%s is a synced over the network and cannot be changed on a multiplayer client.\n", nameString.c_str() ); +#if ID_ALLOW_CHEATS + common->Printf( "ID_ALLOW_CHEATS override!\n" ); +#else + return; +#endif + } +#endif + if ( ( flags & CVAR_CHEAT ) && !cvarSystem->GetCVarBool( "net_allowCheats" ) ) { + common->Printf( "%s cannot be changed in multiplayer.\n", nameString.c_str() ); +#if ID_ALLOW_CHEATS + common->Printf( "ID_ALLOW_CHEATS override!\n" ); +#else + return; +#endif + } + } + + if ( !newValue ) { + newValue = resetString.c_str(); + } + + if ( !force ) { + if ( flags & CVAR_ROM ) { + common->Printf( "%s is read only.\n", nameString.c_str() ); + return; + } + + if ( flags & CVAR_INIT ) { + common->Printf( "%s is write protected.\n", nameString.c_str() ); + return; + } + } + + if ( valueString.Icmp( newValue ) == 0 ) { + return; + } + + valueString = newValue; + value = valueString.c_str(); + UpdateValue(); + + SetModified(); + cvarSystem->SetModifiedFlags( flags ); +} + +/* +============ +idInternalCVar::Reset +============ +*/ +void idInternalCVar::Reset( void ) { + valueString = resetString; + value = valueString.c_str(); + UpdateValue(); +} + +/* +============ +idInternalCVar::InternalSetString +============ +*/ +void idInternalCVar::InternalSetString( const char *newValue ) { + Set( newValue, true, false ); +} + +/* +=============== +idInternalCVar::InternalServerSetString +=============== +*/ +void idInternalCVar::InternalServerSetString( const char *newValue ) { + Set( newValue, true, true ); +} + +/* +============ +idInternalCVar::InternalSetBool +============ +*/ +void idInternalCVar::InternalSetBool( const bool newValue ) { + Set( idStr( newValue ), true, false ); +} + +/* +============ +idInternalCVar::InternalSetInteger +============ +*/ +void idInternalCVar::InternalSetInteger( const int newValue ) { + Set( idStr( newValue ), true, false ); +} + +/* +============ +idInternalCVar::InternalSetFloat +============ +*/ +void idInternalCVar::InternalSetFloat( const float newValue ) { + Set( idStr( newValue ), true, false ); +} + + +/* +=============================================================================== + + idCVarSystemLocal + +=============================================================================== +*/ + +class idCVarSystemLocal : public idCVarSystem { +public: + idCVarSystemLocal( void ); + + virtual ~idCVarSystemLocal( void ) {} + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual bool IsInitialized( void ) const; + + virtual void Register( idCVar *cvar ); + + virtual idCVar * Find( const char *name ); + + virtual void SetCVarString( const char *name, const char *value, int flags = 0 ); + virtual void SetCVarBool( const char *name, const bool value, int flags = 0 ); + virtual void SetCVarInteger( const char *name, const int value, int flags = 0 ); + virtual void SetCVarFloat( const char *name, const float value, int flags = 0 ); + + virtual const char * GetCVarString( const char *name ) const; + virtual bool GetCVarBool( const char *name ) const; + virtual int GetCVarInteger( const char *name ) const; + virtual float GetCVarFloat( const char *name ) const; + + virtual bool Command( const idCmdArgs &args ); + + virtual void CommandCompletion( void(*callback)( const char *s ) ); + virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ); + + virtual void SetModifiedFlags( int flags ); + virtual int GetModifiedFlags( void ) const; + virtual void ClearModifiedFlags( int flags ); + + virtual void ResetFlaggedVariables( int flags ); + virtual void RemoveFlaggedAutoCompletion( int flags ); + virtual void WriteFlaggedVariables( int flags, const char *setCmd, idFile *f ) const; + + virtual const idDict * MoveCVarsToDict( int flags ) const; + virtual void SetCVarsFromDict( const idDict &dict ); + + void RegisterInternal( idCVar *cvar ); + idInternalCVar * FindInternal( const char *name ) const; + void SetInternal( const char *name, const char *value, int flags ); + +private: + bool initialized; + idList cvars; + idHashIndex cvarHash; + int modifiedFlags; + // use a static dictionary to MoveCVarsToDict can be used from game + static idDict moveCVarsToDict; + + +private: + static void Toggle_f( const idCmdArgs &args ); + static void Set_f( const idCmdArgs &args ); + static void SetS_f( const idCmdArgs &args ); + static void SetU_f( const idCmdArgs &args ); + static void SetT_f( const idCmdArgs &args ); + static void SetA_f( const idCmdArgs &args ); + static void Reset_f( const idCmdArgs &args ); + static void ListByFlags( const idCmdArgs &args, cvarFlags_t flags ); + static void List_f( const idCmdArgs &args ); + static void Restart_f( const idCmdArgs &args ); +}; + +idCVarSystemLocal localCVarSystem; +idCVarSystem * cvarSystem = &localCVarSystem; + +idDict idCVarSystemLocal::moveCVarsToDict; + +#define NUM_COLUMNS 77 // 78 - 1 +#define NUM_NAME_CHARS 33 +#define NUM_DESCRIPTION_CHARS ( NUM_COLUMNS - NUM_NAME_CHARS ) +#define FORMAT_STRING "%-32s " + +const char *CreateColumn( const char *text, int columnWidth, const char *indent, idStr &string ) { + int i, lastLine; + + string.Clear(); + for ( lastLine = i = 0; text[i] != '\0'; i++ ) { + if ( i - lastLine >= columnWidth || text[i] == '\n' ) { + while( i > 0 && text[i] > ' ' && text[i] != '/' && text[i] != ',' && text[i] != '\\' ) { + i--; + } + while( lastLine < i ) { + string.Append( text[lastLine++] ); + } + string.Append( indent ); + lastLine++; + } + } + while( lastLine < i ) { + string.Append( text[lastLine++] ); + } + return string.c_str(); +} + +/* +============ +idCVarSystemLocal::FindInternal +============ +*/ +idInternalCVar *idCVarSystemLocal::FindInternal( const char *name ) const { + int hash = cvarHash.GenerateKey( name, false ); + for ( int i = cvarHash.First( hash ); i != -1; i = cvarHash.Next( i ) ) { + if ( cvars[i]->nameString.Icmp( name ) == 0 ) { + return cvars[i]; + } + } + return NULL; +} + +/* +============ +idCVarSystemLocal::SetInternal +============ +*/ +void idCVarSystemLocal::SetInternal( const char *name, const char *value, int flags ) { + int hash; + idInternalCVar *internal; + + internal = FindInternal( name ); + + if ( internal ) { + internal->InternalSetString( value ); + internal->flags |= flags & ~CVAR_STATIC; + internal->UpdateCheat(); + } else { + internal = new idInternalCVar( name, value, flags ); + hash = cvarHash.GenerateKey( internal->nameString.c_str(), false ); + cvarHash.Add( hash, cvars.Append( internal ) ); + } +} + +/* +============ +idCVarSystemLocal::idCVarSystemLocal +============ +*/ +idCVarSystemLocal::idCVarSystemLocal( void ) { + initialized = false; + modifiedFlags = 0; +} + +/* +============ +idCVarSystemLocal::Init +============ +*/ +void idCVarSystemLocal::Init( void ) { + + modifiedFlags = 0; + + cmdSystem->AddCommand( "toggle", Toggle_f, CMD_FL_SYSTEM, "toggles a cvar" ); + cmdSystem->AddCommand( "set", Set_f, CMD_FL_SYSTEM, "sets a cvar" ); + cmdSystem->AddCommand( "sets", SetS_f, CMD_FL_SYSTEM, "sets a cvar and flags it as server info" ); + cmdSystem->AddCommand( "setu", SetU_f, CMD_FL_SYSTEM, "sets a cvar and flags it as user info" ); + cmdSystem->AddCommand( "sett", SetT_f, CMD_FL_SYSTEM, "sets a cvar and flags it as tool" ); + cmdSystem->AddCommand( "seta", SetA_f, CMD_FL_SYSTEM, "sets a cvar and flags it as archive" ); + cmdSystem->AddCommand( "reset", Reset_f, CMD_FL_SYSTEM, "resets a cvar" ); + cmdSystem->AddCommand( "listCvars", List_f, CMD_FL_SYSTEM, "lists cvars" ); + cmdSystem->AddCommand( "cvar_restart", Restart_f, CMD_FL_SYSTEM, "restart the cvar system" ); + + initialized = true; +} + +/* +============ +idCVarSystemLocal::Shutdown +============ +*/ +void idCVarSystemLocal::Shutdown( void ) { + cvars.DeleteContents( true ); + cvarHash.Free(); + moveCVarsToDict.Clear(); + initialized = false; +} + +/* +============ +idCVarSystemLocal::IsInitialized +============ +*/ +bool idCVarSystemLocal::IsInitialized( void ) const { + return initialized; +} + +/* +============ +idCVarSystemLocal::Register +============ +*/ +void idCVarSystemLocal::Register( idCVar *cvar ) { + int hash; + idInternalCVar *internal; + + cvar->SetInternalVar( cvar ); + + internal = FindInternal( cvar->GetName() ); + + if ( internal ) { + internal->Update( cvar ); + } else { + internal = new idInternalCVar( cvar ); + hash = cvarHash.GenerateKey( internal->nameString.c_str(), false ); + cvarHash.Add( hash, cvars.Append( internal ) ); + } + + cvar->SetInternalVar( internal ); +} + +/* +============ +idCVarSystemLocal::Find +============ +*/ +idCVar *idCVarSystemLocal::Find( const char *name ) { + return FindInternal( name ); +} + +/* +============ +idCVarSystemLocal::SetCVarString +============ +*/ +void idCVarSystemLocal::SetCVarString( const char *name, const char *value, int flags ) { + SetInternal( name, value, flags ); +} + +/* +============ +idCVarSystemLocal::SetCVarBool +============ +*/ +void idCVarSystemLocal::SetCVarBool( const char *name, const bool value, int flags ) { + SetInternal( name, idStr( value ), flags ); +} + +/* +============ +idCVarSystemLocal::SetCVarInteger +============ +*/ +void idCVarSystemLocal::SetCVarInteger( const char *name, const int value, int flags ) { + SetInternal( name, idStr( value ), flags ); +} + +/* +============ +idCVarSystemLocal::SetCVarFloat +============ +*/ +void idCVarSystemLocal::SetCVarFloat( const char *name, const float value, int flags ) { + SetInternal( name, idStr( value ), flags ); +} + +/* +============ +idCVarSystemLocal::GetCVarString +============ +*/ +const char *idCVarSystemLocal::GetCVarString( const char *name ) const { + idInternalCVar *internal = FindInternal( name ); + if ( internal ) { + return internal->GetString(); + } + return ""; +} + +/* +============ +idCVarSystemLocal::GetCVarBool +============ +*/ +bool idCVarSystemLocal::GetCVarBool( const char *name ) const { + idInternalCVar *internal = FindInternal( name ); + if ( internal ) { + return internal->GetBool(); + } + return false; +} + +/* +============ +idCVarSystemLocal::GetCVarInteger +============ +*/ +int idCVarSystemLocal::GetCVarInteger( const char *name ) const { + idInternalCVar *internal = FindInternal( name ); + if ( internal ) { + return internal->GetInteger(); + } + return 0; +} + +/* +============ +idCVarSystemLocal::GetCVarFloat +============ +*/ +float idCVarSystemLocal::GetCVarFloat( const char *name ) const { + idInternalCVar *internal = FindInternal( name ); + if ( internal ) { + return internal->GetFloat(); + } + return 0.0f; +} + +/* +============ +idCVarSystemLocal::Command +============ +*/ +bool idCVarSystemLocal::Command( const idCmdArgs &args ) { + idInternalCVar *internal; + + internal = FindInternal( args.Argv( 0 ) ); + + if ( internal == NULL ) { + return false; + } + + if ( args.Argc() == 1 ) { + // print the variable + common->Printf( "\"%s\" is:\"%s\"" S_COLOR_WHITE " default:\"%s\"\n", + internal->nameString.c_str(), internal->valueString.c_str(), internal->resetString.c_str() ); + if ( idStr::Length( internal->GetDescription() ) > 0 ) { + common->Printf( S_COLOR_WHITE "%s\n", internal->GetDescription() ); + } + } else { + // set the value + internal->Set( args.Args(), false, false ); + } + return true; +} + +/* +============ +idCVarSystemLocal::CommandCompletion +============ +*/ +void idCVarSystemLocal::CommandCompletion( void(*callback)( const char *s ) ) { + for( int i = 0; i < cvars.Num(); i++ ) { + callback( cvars[i]->GetName() ); + } +} + +/* +============ +idCVarSystemLocal::ArgCompletion +============ +*/ +void idCVarSystemLocal::ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) { + idCmdArgs args; + + args.TokenizeString( cmdString, false ); + + for( int i = 0; i < cvars.Num(); i++ ) { + if ( !cvars[i]->valueCompletion ) { + continue; + } + if ( idStr::Icmp( args.Argv( 0 ), cvars[i]->nameString.c_str() ) == 0 ) { + cvars[i]->valueCompletion( args, callback ); + break; + } + } +} + +/* +============ +idCVarSystemLocal::SetModifiedFlags +============ +*/ +void idCVarSystemLocal::SetModifiedFlags( int flags ) { + modifiedFlags |= flags; +} + +/* +============ +idCVarSystemLocal::GetModifiedFlags +============ +*/ +int idCVarSystemLocal::GetModifiedFlags( void ) const { + return modifiedFlags; +} + +/* +============ +idCVarSystemLocal::ClearModifiedFlags +============ +*/ +void idCVarSystemLocal::ClearModifiedFlags( int flags ) { + modifiedFlags &= ~flags; +} + +/* +============ +idCVarSystemLocal::ResetFlaggedVariables +============ +*/ +void idCVarSystemLocal::ResetFlaggedVariables( int flags ) { + for( int i = 0; i < cvars.Num(); i++ ) { + idInternalCVar *cvar = cvars[i]; + if ( cvar->GetFlags() & flags ) { + cvar->Set( NULL, true, true ); + } + } +} + +/* +============ +idCVarSystemLocal::RemoveFlaggedAutoCompletion +============ +*/ +void idCVarSystemLocal::RemoveFlaggedAutoCompletion( int flags ) { + for( int i = 0; i < cvars.Num(); i++ ) { + idInternalCVar *cvar = cvars[i]; + if ( cvar->GetFlags() & flags ) { + cvar->valueCompletion = NULL; + } + } +} + +/* +============ +idCVarSystemLocal::WriteFlaggedVariables + +Appends lines containing "set variable value" for all variables +with the "flags" flag set to true. +============ +*/ +void idCVarSystemLocal::WriteFlaggedVariables( int flags, const char *setCmd, idFile *f ) const { + for( int i = 0; i < cvars.Num(); i++ ) { + idInternalCVar *cvar = cvars[i]; + if ( cvar->GetFlags() & flags ) { + f->Printf( "%s %s \"%s\"\n", setCmd, cvar->GetName(), cvar->GetString() ); + } + } +} + +/* +============ +idCVarSystemLocal::MoveCVarsToDict +============ +*/ +const idDict* idCVarSystemLocal::MoveCVarsToDict( int flags ) const { + moveCVarsToDict.Clear(); + for( int i = 0; i < cvars.Num(); i++ ) { + idCVar *cvar = cvars[i]; + if ( cvar->GetFlags() & flags ) { + moveCVarsToDict.Set( cvar->GetName(), cvar->GetString() ); + } + } + return &moveCVarsToDict; +} + +/* +============ +idCVarSystemLocal::SetCVarsFromDict +============ +*/ +void idCVarSystemLocal::SetCVarsFromDict( const idDict &dict ) { + idInternalCVar *internal; + + for( int i = 0; i < dict.GetNumKeyVals(); i++ ) { + const idKeyValue *kv = dict.GetKeyVal( i ); + internal = FindInternal( kv->GetKey() ); + if ( internal ) { + internal->InternalServerSetString( kv->GetValue() ); + } + } +} + +/* +============ +idCVarSystemLocal::Toggle_f +============ +*/ +void idCVarSystemLocal::Toggle_f( const idCmdArgs &args ) { + int argc, i; + float current, set; + const char *text; + + argc = args.Argc(); + if ( argc < 2 ) { + common->Printf ("usage:\n" + " toggle - toggles between 0 and 1\n" + " toggle - toggles between 0 and \n" + " toggle [string 1] [string 2]...[string n] - cycles through all strings\n"); + return; + } + + idInternalCVar *cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + + if ( cvar == NULL ) { + common->Warning( "Toggle_f: cvar \"%s\" not found", args.Argv( 1 ) ); + return; + } + + if ( argc > 3 ) { + // cycle through multiple values + text = cvar->GetString(); + for( i = 2; i < argc; i++ ) { + if ( !idStr::Icmp( text, args.Argv( i ) ) ) { + // point to next value + i++; + break; + } + } + if ( i >= argc ) { + i = 2; + } + + common->Printf( "set %s = %s\n", args.Argv(1), args.Argv( i ) ); + cvar->Set( va("%s", args.Argv( i ) ), false, false ); + } else { + // toggle between 0 and 1 + current = cvar->GetFloat(); + if ( argc == 3 ) { + set = atof( args.Argv( 2 ) ); + } else { + set = 1.0f; + } + if ( current == 0.0f ) { + current = set; + } else { + current = 0.0f; + } + common->Printf( "set %s = %f\n", args.Argv(1), current ); + cvar->Set( idStr( current ), false, false ); + } +} + +/* +============ +idCVarSystemLocal::Set_f +============ +*/ +void idCVarSystemLocal::Set_f( const idCmdArgs &args ) { + const char *str; + + str = args.Args( 2, args.Argc() - 1 ); + localCVarSystem.SetCVarString( args.Argv(1), str ); +} + +/* +============ +idCVarSystemLocal::SetS_f +============ +*/ +void idCVarSystemLocal::SetS_f( const idCmdArgs &args ) { + idInternalCVar *cvar; + + Set_f( args ); + cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + cvar->flags |= CVAR_SERVERINFO | CVAR_ARCHIVE; +} + +/* +============ +idCVarSystemLocal::SetU_f +============ +*/ +void idCVarSystemLocal::SetU_f( const idCmdArgs &args ) { + idInternalCVar *cvar; + + Set_f( args ); + cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + cvar->flags |= CVAR_USERINFO | CVAR_ARCHIVE; +} + +/* +============ +idCVarSystemLocal::SetT_f +============ +*/ +void idCVarSystemLocal::SetT_f( const idCmdArgs &args ) { + idInternalCVar *cvar; + + Set_f( args ); + cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + cvar->flags |= CVAR_TOOL; +} + +/* +============ +idCVarSystemLocal::SetA_f +============ +*/ +void idCVarSystemLocal::SetA_f( const idCmdArgs &args ) { + idInternalCVar *cvar; + + Set_f( args ); + cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + + // FIXME: enable this for ship, so mods can store extra data + // but during development we don't want obsolete cvars to continue + // to be saved +// cvar->flags |= CVAR_ARCHIVE; +} + +/* +============ +idCVarSystemLocal::Reset_f +============ +*/ +void idCVarSystemLocal::Reset_f( const idCmdArgs &args ) { + idInternalCVar *cvar; + + if ( args.Argc() != 2 ) { + common->Printf ("usage: reset \n"); + return; + } + cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + + cvar->Reset(); +} + +/* +============ +idCVarSystemLocal::ListByFlags +============ +*/ +// NOTE: the const wonkyness is required to make msvc happy +template<> +ID_INLINE int idListSortCompare( const idInternalCVar * const *a, const idInternalCVar * const *b ) { + return idStr::Icmp( (*a)->GetName(), (*b)->GetName() ); +} + +void idCVarSystemLocal::ListByFlags( const idCmdArgs &args, cvarFlags_t flags ) { + int i, argNum; + idStr match, indent, string; + const idInternalCVar *cvar; + idListcvarList; + + enum { + SHOW_VALUE, + SHOW_DESCRIPTION, + SHOW_TYPE, + SHOW_FLAGS + } show; + + argNum = 1; + show = SHOW_VALUE; + + if ( idStr::Icmp( args.Argv( argNum ), "-" ) == 0 || idStr::Icmp( args.Argv( argNum ), "/" ) == 0 ) { + if ( idStr::Icmp( args.Argv( argNum + 1 ), "help" ) == 0 || idStr::Icmp( args.Argv( argNum + 1 ), "?" ) == 0 ) { + argNum = 3; + show = SHOW_DESCRIPTION; + } else if ( idStr::Icmp( args.Argv( argNum + 1 ), "type" ) == 0 || idStr::Icmp( args.Argv( argNum + 1 ), "range" ) == 0 ) { + argNum = 3; + show = SHOW_TYPE; + } else if ( idStr::Icmp( args.Argv( argNum + 1 ), "flags" ) == 0 ) { + argNum = 3; + show = SHOW_FLAGS; + } + } + + if ( args.Argc() > argNum ) { + match = args.Args( argNum, -1 ); + match.Replace( " ", "" ); + } else { + match = ""; + } + + for ( i = 0; i < localCVarSystem.cvars.Num(); i++ ) { + cvar = localCVarSystem.cvars[i]; + + if ( !( cvar->GetFlags() & flags ) ) { + continue; + } + + if ( match.Length() && !cvar->nameString.Filter( match, false ) ) { + continue; + } + + cvarList.Append( cvar ); + } + + cvarList.Sort(); + + switch( show ) { + case SHOW_VALUE: { + for ( i = 0; i < cvarList.Num(); i++ ) { + cvar = cvarList[i]; + common->Printf( FORMAT_STRING S_COLOR_WHITE "\"%s\"\n", cvar->nameString.c_str(), cvar->valueString.c_str() ); + } + break; + } + case SHOW_DESCRIPTION: { + indent.Fill( ' ', NUM_NAME_CHARS ); + indent.Insert( "\n", 0 ); + + for ( i = 0; i < cvarList.Num(); i++ ) { + cvar = cvarList[i]; + common->Printf( FORMAT_STRING S_COLOR_WHITE "%s\n", cvar->nameString.c_str(), CreateColumn( cvar->GetDescription(), NUM_DESCRIPTION_CHARS, indent, string ) ); + } + break; + } + case SHOW_TYPE: { + for ( i = 0; i < cvarList.Num(); i++ ) { + cvar = cvarList[i]; + if ( cvar->GetFlags() & CVAR_BOOL ) { + common->Printf( FORMAT_STRING S_COLOR_CYAN "bool\n", cvar->GetName() ); + } else if ( cvar->GetFlags() & CVAR_INTEGER ) { + if ( cvar->GetMinValue() < cvar->GetMaxValue() ) { + common->Printf( FORMAT_STRING S_COLOR_GREEN "int " S_COLOR_WHITE "[%d, %d]\n", cvar->GetName(), (int) cvar->GetMinValue(), (int) cvar->GetMaxValue() ); + } else { + common->Printf( FORMAT_STRING S_COLOR_GREEN "int\n", cvar->GetName() ); + } + } else if ( cvar->GetFlags() & CVAR_FLOAT ) { + if ( cvar->GetMinValue() < cvar->GetMaxValue() ) { + common->Printf( FORMAT_STRING S_COLOR_RED "float " S_COLOR_WHITE "[%s, %s]\n", cvar->GetName(), idStr( cvar->GetMinValue() ).c_str(), idStr( cvar->GetMaxValue() ).c_str() ); + } else { + common->Printf( FORMAT_STRING S_COLOR_RED "float\n", cvar->GetName() ); + } + } else if ( cvar->GetValueStrings() ) { + common->Printf( FORMAT_STRING S_COLOR_WHITE "string " S_COLOR_WHITE "[", cvar->GetName() ); + for ( int j = 0; cvar->GetValueStrings()[j] != NULL; j++ ) { + if ( j ) { + common->Printf( S_COLOR_WHITE ", %s", cvar->GetValueStrings()[j] ); + } else { + common->Printf( S_COLOR_WHITE "%s", cvar->GetValueStrings()[j] ); + } + } + common->Printf( S_COLOR_WHITE "]\n" ); + } else { + common->Printf( FORMAT_STRING S_COLOR_WHITE "string\n", cvar->GetName() ); + } + } + break; + } + case SHOW_FLAGS: { + for ( i = 0; i < cvarList.Num(); i++ ) { + cvar = cvarList[i]; + common->Printf( FORMAT_STRING, cvar->GetName() ); + string = ""; + if ( cvar->GetFlags() & CVAR_BOOL ) { + string += S_COLOR_CYAN "B "; + } else if ( cvar->GetFlags() & CVAR_INTEGER ) { + string += S_COLOR_GREEN "I "; + } else if ( cvar->GetFlags() & CVAR_FLOAT ) { + string += S_COLOR_RED "F "; + } else { + string += S_COLOR_WHITE "S "; + } + if ( cvar->GetFlags() & CVAR_SYSTEM ) { + string += S_COLOR_WHITE "SYS "; + } else if ( cvar->GetFlags() & CVAR_RENDERER ) { + string += S_COLOR_WHITE "RNDR "; + } else if ( cvar->GetFlags() & CVAR_SOUND ) { + string += S_COLOR_WHITE "SND "; + } else if ( cvar->GetFlags() & CVAR_GUI ) { + string += S_COLOR_WHITE "GUI "; + } else if ( cvar->GetFlags() & CVAR_GAME ) { + string += S_COLOR_WHITE "GAME "; + } else if ( cvar->GetFlags() & CVAR_TOOL ) { + string += S_COLOR_WHITE "TOOL "; + } else { + string += S_COLOR_WHITE " "; + } + string += ( cvar->GetFlags() & CVAR_USERINFO ) ? "UI " : " "; + string += ( cvar->GetFlags() & CVAR_SERVERINFO ) ? "SI " : " "; + string += ( cvar->GetFlags() & CVAR_STATIC ) ? "ST " : " "; + string += ( cvar->GetFlags() & CVAR_CHEAT ) ? "CH " : " "; + string += ( cvar->GetFlags() & CVAR_INIT ) ? "IN " : " "; + string += ( cvar->GetFlags() & CVAR_ROM ) ? "RO " : " "; + string += ( cvar->GetFlags() & CVAR_ARCHIVE ) ? "AR " : " "; + string += ( cvar->GetFlags() & CVAR_MODIFIED ) ? "MO " : " "; + string += "\n"; + common->Printf( string ); + } + break; + } + } + + common->Printf( "\n%i cvars listed\n\n", cvarList.Num() ); + common->Printf( "listCvar [search string] = list cvar values\n" + "listCvar -help [search string] = list cvar descriptions\n" + "listCvar -type [search string] = list cvar types\n" + "listCvar -flags [search string] = list cvar flags\n" ); +} + +/* +============ +idCVarSystemLocal::List_f +============ +*/ +void idCVarSystemLocal::List_f( const idCmdArgs &args ) { + ListByFlags( args, CVAR_ALL ); +} + +/* +============ +idCVarSystemLocal::Restart_f +============ +*/ +void idCVarSystemLocal::Restart_f( const idCmdArgs &args ) { + int i, hash; + idInternalCVar *cvar; + + for ( i = 0; i < localCVarSystem.cvars.Num(); i++ ) { + cvar = localCVarSystem.cvars[i]; + + // don't mess with rom values + if ( cvar->flags & ( CVAR_ROM | CVAR_INIT ) ) { + continue; + } + + // throw out any variables the user created + if ( !( cvar->flags & CVAR_STATIC ) ) { + hash = localCVarSystem.cvarHash.GenerateKey( cvar->nameString, false ); + delete cvar; + localCVarSystem.cvars.RemoveIndex( i ); + localCVarSystem.cvarHash.RemoveIndex( hash, i ); + i--; + continue; + } + + cvar->Reset(); + } +} diff --git a/framework/CVarSystem.h b/framework/CVarSystem.h new file mode 100644 index 000000000..d6823e143 --- /dev/null +++ b/framework/CVarSystem.h @@ -0,0 +1,300 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CVARSYSTEM_H__ +#define __CVARSYSTEM_H__ + +/* +=============================================================================== + + Console Variables (CVars) are used to hold scalar or string variables + that can be changed or displayed at the console as well as accessed + directly in code. + + CVars are mostly used to hold settings that can be changed from the + console or saved to and loaded from configuration files. CVars are also + occasionally used to communicate information between different modules + of the program. + + CVars are restricted from having the same names as console commands to + keep the console interface from being ambiguous. + + CVars can be accessed from the console in three ways: + cvarName prints the current value + cvarName X sets the value to X if the variable exists + set cvarName X as above, but creates the CVar if not present + + CVars may be declared in the global namespace, in classes and in functions. + However declarations in classes and functions should always be static to + save space and time. Making CVars static does not change their + functionality due to their global nature. + + CVars should be contructed only through one of the constructors with name, + value, flags and description. The name, value and description parameters + to the constructor have to be static strings, do not use va() or the like + functions returning a string. + + CVars may be declared multiple times using the same name string. However, + they will all reference the same value and changing the value of one CVar + changes the value of all CVars with the same name. + + CVars should always be declared with the correct type flag: CVAR_BOOL, + CVAR_INTEGER or CVAR_FLOAT. If no such flag is specified the CVar + defaults to type string. If the CVAR_BOOL flag is used there is no need + to specify an argument auto-completion function because the CVar gets + one assigned automatically. + + CVars are automatically range checked based on their type and any min/max + or valid string set specified in the constructor. + + CVars are always considered cheats except when CVAR_NOCHEAT, CVAR_INIT, + CVAR_ROM, CVAR_ARCHIVE, CVAR_USERINFO, CVAR_SERVERINFO, CVAR_NETWORKSYNC + is set. + +=============================================================================== +*/ + +typedef enum { + CVAR_ALL = -1, // all flags + CVAR_BOOL = BIT(0), // variable is a boolean + CVAR_INTEGER = BIT(1), // variable is an integer + CVAR_FLOAT = BIT(2), // variable is a float + CVAR_SYSTEM = BIT(3), // system variable + CVAR_RENDERER = BIT(4), // renderer variable + CVAR_SOUND = BIT(5), // sound variable + CVAR_GUI = BIT(6), // gui variable + CVAR_GAME = BIT(7), // game variable + CVAR_TOOL = BIT(8), // tool variable + CVAR_USERINFO = BIT(9), // sent to servers, available to menu + CVAR_SERVERINFO = BIT(10), // sent from servers, available to menu + CVAR_NETWORKSYNC = BIT(11), // cvar is synced from the server to clients + CVAR_STATIC = BIT(12), // statically declared, not user created + CVAR_CHEAT = BIT(13), // variable is considered a cheat + CVAR_NOCHEAT = BIT(14), // variable is not considered a cheat + CVAR_INIT = BIT(15), // can only be set from the command-line + CVAR_ROM = BIT(16), // display only, cannot be set by user at all + CVAR_ARCHIVE = BIT(17), // set to cause it to be saved to a config file + CVAR_MODIFIED = BIT(18) // set when the variable is modified +} cvarFlags_t; + + +/* +=============================================================================== + + idCVar + +=============================================================================== +*/ + +class idCVar { +public: + // Never use the default constructor. + idCVar( void ) { assert( typeid( this ) != typeid( idCVar ) ); } + + // Always use one of the following constructors. + idCVar( const char *name, const char *value, int flags, const char *description, + argCompletion_t valueCompletion = NULL ); + idCVar( const char *name, const char *value, int flags, const char *description, + float valueMin, float valueMax, argCompletion_t valueCompletion = NULL ); + idCVar( const char *name, const char *value, int flags, const char *description, + const char **valueStrings, argCompletion_t valueCompletion = NULL ); + + virtual ~idCVar( void ) {} + + const char * GetName( void ) const { return internalVar->name; } + int GetFlags( void ) const { return internalVar->flags; } + const char * GetDescription( void ) const { return internalVar->description; } + float GetMinValue( void ) const { return internalVar->valueMin; } + float GetMaxValue( void ) const { return internalVar->valueMax; } + const char ** GetValueStrings( void ) const { return valueStrings; } + argCompletion_t GetValueCompletion( void ) const { return valueCompletion; } + + bool IsModified( void ) const { return ( internalVar->flags & CVAR_MODIFIED ) != 0; } + void SetModified( void ) { internalVar->flags |= CVAR_MODIFIED; } + void ClearModified( void ) { internalVar->flags &= ~CVAR_MODIFIED; } + + const char * GetString( void ) const { return internalVar->value; } + bool GetBool( void ) const { return ( internalVar->integerValue != 0 ); } + int GetInteger( void ) const { return internalVar->integerValue; } + float GetFloat( void ) const { return internalVar->floatValue; } + + void SetString( const char *value ) { internalVar->InternalSetString( value ); } + void SetBool( const bool value ) { internalVar->InternalSetBool( value ); } + void SetInteger( const int value ) { internalVar->InternalSetInteger( value ); } + void SetFloat( const float value ) { internalVar->InternalSetFloat( value ); } + + void SetInternalVar( idCVar *cvar ) { internalVar = cvar; } + + static void RegisterStaticVars( void ); + +protected: + const char * name; // name + const char * value; // value + const char * description; // description + int flags; // CVAR_? flags + float valueMin; // minimum value + float valueMax; // maximum value + const char ** valueStrings; // valid value strings + argCompletion_t valueCompletion; // value auto-completion function + int integerValue; // atoi( string ) + float floatValue; // atof( value ) + idCVar * internalVar; // internal cvar + idCVar * next; // next statically declared cvar + +private: + void Init( const char *name, const char *value, int flags, const char *description, + float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion ); + + virtual void InternalSetString( const char *newValue ) {} + virtual void InternalSetBool( const bool newValue ) {} + virtual void InternalSetInteger( const int newValue ) {} + virtual void InternalSetFloat( const float newValue ) {} + + static idCVar * staticVars; +}; + +ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, + argCompletion_t valueCompletion ) { + if ( !valueCompletion && ( flags & CVAR_BOOL ) ) { + valueCompletion = idCmdSystem::ArgCompletion_Boolean; + } + Init( name, value, flags, description, 1, -1, NULL, valueCompletion ); +} + +ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, + float valueMin, float valueMax, argCompletion_t valueCompletion ) { + Init( name, value, flags, description, valueMin, valueMax, NULL, valueCompletion ); +} + +ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, + const char **valueStrings, argCompletion_t valueCompletion ) { + Init( name, value, flags, description, 1, -1, valueStrings, valueCompletion ); +} + + +/* +=============================================================================== + + idCVarSystem + +=============================================================================== +*/ + +class idCVarSystem { +public: + virtual ~idCVarSystem( void ) {} + + virtual void Init( void ) = 0; + virtual void Shutdown( void ) = 0; + virtual bool IsInitialized( void ) const = 0; + + // Registers a CVar. + virtual void Register( idCVar *cvar ) = 0; + + // Finds the CVar with the given name. + // Returns NULL if there is no CVar with the given name. + virtual idCVar * Find( const char *name ) = 0; + + // Sets the value of a CVar by name. + virtual void SetCVarString( const char *name, const char *value, int flags = 0 ) = 0; + virtual void SetCVarBool( const char *name, const bool value, int flags = 0 ) = 0; + virtual void SetCVarInteger( const char *name, const int value, int flags = 0 ) = 0; + virtual void SetCVarFloat( const char *name, const float value, int flags = 0 ) = 0; + + // Gets the value of a CVar by name. + virtual const char * GetCVarString( const char *name ) const = 0; + virtual bool GetCVarBool( const char *name ) const = 0; + virtual int GetCVarInteger( const char *name ) const = 0; + virtual float GetCVarFloat( const char *name ) const = 0; + + // Called by the command system when argv(0) doesn't match a known command. + // Returns true if argv(0) is a variable reference and prints or changes the CVar. + virtual bool Command( const idCmdArgs &args ) = 0; + + // Command and argument completion using callback for each valid string. + virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0; + virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0; + + // Sets/gets/clears modified flags that tell what kind of CVars have changed. + virtual void SetModifiedFlags( int flags ) = 0; + virtual int GetModifiedFlags( void ) const = 0; + virtual void ClearModifiedFlags( int flags ) = 0; + + // Resets variables with one of the given flags set. + virtual void ResetFlaggedVariables( int flags ) = 0; + + // Removes auto-completion from the flagged variables. + virtual void RemoveFlaggedAutoCompletion( int flags ) = 0; + + // Writes variables with one of the given flags set to the given file. + virtual void WriteFlaggedVariables( int flags, const char *setCmd, idFile *f ) const = 0; + + // Moves CVars to and from dictionaries. + virtual const idDict * MoveCVarsToDict( int flags ) const = 0; + virtual void SetCVarsFromDict( const idDict &dict ) = 0; +}; + +extern idCVarSystem * cvarSystem; + + +/* +=============================================================================== + + CVar Registration + + Each DLL using CVars has to declare a private copy of the static variable + idCVar::staticVars like this: idCVar * idCVar::staticVars = NULL; + Furthermore idCVar::RegisterStaticVars() has to be called after the + cvarSystem pointer is set when the DLL is first initialized. + +=============================================================================== +*/ + +ID_INLINE void idCVar::Init( const char *name, const char *value, int flags, const char *description, + float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion ) { + this->name = name; + this->value = value; + this->flags = flags; + this->description = description; + this->flags = flags | CVAR_STATIC; + this->valueMin = valueMin; + this->valueMax = valueMax; + this->valueStrings = valueStrings; + this->valueCompletion = valueCompletion; + this->integerValue = 0; + this->floatValue = 0.0f; + this->internalVar = this; + if ( staticVars != (idCVar *)0xFFFFFFFF ) { + this->next = staticVars; + staticVars = this; + } else { + cvarSystem->Register( this ); + } +} + +ID_INLINE void idCVar::RegisterStaticVars( void ) { + if ( staticVars != (idCVar *)0xFFFFFFFF ) { + for ( idCVar *cvar = staticVars; cvar; cvar = cvar->next ) { + cvarSystem->Register( cvar ); + } + staticVars = (idCVar *)0xFFFFFFFF; + } +} + +#endif /* !__CVARSYSTEM_H__ */ diff --git a/framework/CmdSystem.cpp b/framework/CmdSystem.cpp new file mode 100644 index 000000000..28d646965 --- /dev/null +++ b/framework/CmdSystem.cpp @@ -0,0 +1,774 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +/* +=============================================================================== + + idCmdSystemLocal + +=============================================================================== +*/ + +typedef struct commandDef_s { + struct commandDef_s * next; + char * name; + cmdFunction_t function; + argCompletion_t argCompletion; + int flags; + char * description; +} commandDef_t; + + +class idCmdSystemLocal : public idCmdSystem { +public: + virtual void Init( void ); + virtual void Shutdown( void ); + + virtual void AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion = NULL ); + virtual void RemoveCommand( const char *cmdName ); + virtual void RemoveFlaggedCommands( int flags ); + + virtual void CommandCompletion( void(*callback)( const char *s ) ); + virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ); + + virtual void BufferCommandText( cmdExecution_t exec, const char *text ); + virtual void ExecuteCommandBuffer( void ); + + virtual void ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ); + virtual void ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ); + + virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ); + + virtual void SetupReloadEngine( const idCmdArgs &args ); + virtual bool PostReloadEngine( void ); + + void SetWait( int numFrames ) { wait = numFrames; } + commandDef_t * GetCommands( void ) const { return commands; } + +private: + static const int MAX_CMD_BUFFER = 0x10000; + + commandDef_t * commands; + + int wait; + int textLength; + byte textBuf[MAX_CMD_BUFFER]; + + idStr completionString; + idStrList completionParms; + + // piggybacks on the text buffer, avoids tokenize again and screwing it up + idList tokenizedCmds; + + // a command stored to be executed after a reloadEngine and all associated commands have been processed + idCmdArgs postReload; + +private: + void ExecuteTokenizedString( const idCmdArgs &args ); + void ExecuteCommandText( const char *text ); + void InsertCommandText( const char *text ); + void AppendCommandText( const char *text ); + + static void ListByFlags( const idCmdArgs &args, cmdFlags_t flags ); + static void List_f( const idCmdArgs &args ); + static void SystemList_f( const idCmdArgs &args ); + static void RendererList_f( const idCmdArgs &args ); + static void SoundList_f( const idCmdArgs &args ); + static void GameList_f( const idCmdArgs &args ); + static void ToolList_f( const idCmdArgs &args ); + static void Exec_f( const idCmdArgs &args ); + static void Vstr_f( const idCmdArgs &args ); + static void Echo_f( const idCmdArgs &args ); + static void Parse_f( const idCmdArgs &args ); + static void Wait_f( const idCmdArgs &args ); + static void PrintMemInfo_f( const idCmdArgs &args ); +}; + +idCmdSystemLocal cmdSystemLocal; +idCmdSystem * cmdSystem = &cmdSystemLocal; + + +/* +============ +idCmdSystemLocal::ListByFlags +============ +*/ +// NOTE: the const wonkyness is required to make msvc happy +template<> +ID_INLINE int idListSortCompare( const commandDef_t * const *a, const commandDef_t * const *b ) { + return idStr::Icmp( (*a)->name, (*b)->name ); +} + +void idCmdSystemLocal::ListByFlags( const idCmdArgs &args, cmdFlags_t flags ) { + int i; + idStr match; + const commandDef_t *cmd; + idList cmdList; + + if ( args.Argc() > 1 ) { + match = args.Args( 1, -1 ); + match.Replace( " ", "" ); + } else { + match = ""; + } + + for ( cmd = cmdSystemLocal.GetCommands(); cmd; cmd = cmd->next ) { + if ( !( cmd->flags & flags ) ) { + continue; + } + if ( match.Length() && idStr( cmd->name ).Filter( match, false ) == 0 ) { + continue; + } + + cmdList.Append( cmd ); + } + + cmdList.Sort(); + + for ( i = 0; i < cmdList.Num(); i++ ) { + cmd = cmdList[i]; + + common->Printf( " %-21s %s\n", cmd->name, cmd->description ); + } + + common->Printf( "%i commands\n", cmdList.Num() ); +} + +/* +============ +idCmdSystemLocal::List_f +============ +*/ +void idCmdSystemLocal::List_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_ALL ); +} + +/* +============ +idCmdSystemLocal::SystemList_f +============ +*/ +void idCmdSystemLocal::SystemList_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_SYSTEM ); +} + +/* +============ +idCmdSystemLocal::RendererList_f +============ +*/ +void idCmdSystemLocal::RendererList_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_RENDERER ); +} + +/* +============ +idCmdSystemLocal::SoundList_f +============ +*/ +void idCmdSystemLocal::SoundList_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_SOUND ); +} + +/* +============ +idCmdSystemLocal::GameList_f +============ +*/ +void idCmdSystemLocal::GameList_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_GAME ); +} + +/* +============ +idCmdSystemLocal::ToolList_f +============ +*/ +void idCmdSystemLocal::ToolList_f( const idCmdArgs &args ) { + idCmdSystemLocal::ListByFlags( args, CMD_FL_TOOL ); +} + +/* +=============== +idCmdSystemLocal::Exec_f +=============== +*/ +void idCmdSystemLocal::Exec_f( const idCmdArgs &args ) { + char * f; + int len; + idStr filename; + + if ( args.Argc () != 2 ) { + common->Printf( "exec : execute a script file\n" ); + return; + } + + filename = args.Argv(1); + filename.DefaultFileExtension( ".cfg" ); + len = fileSystem->ReadFile( filename, reinterpret_cast(&f), NULL ); + if ( !f ) { + common->Printf( "couldn't exec %s\n", args.Argv(1) ); + return; + } + common->Printf( "execing %s\n", args.Argv(1) ); + + cmdSystemLocal.BufferCommandText( CMD_EXEC_INSERT, f ); + + fileSystem->FreeFile( f ); +} + +/* +=============== +idCmdSystemLocal::Vstr_f + +Inserts the current value of a cvar as command text +=============== +*/ +void idCmdSystemLocal::Vstr_f( const idCmdArgs &args ) { + const char *v; + + if ( args.Argc () != 2 ) { + common->Printf( "vstr : execute a variable command\n" ); + return; + } + + v = cvarSystem->GetCVarString( args.Argv( 1 ) ); + + cmdSystemLocal.BufferCommandText( CMD_EXEC_APPEND, va( "%s\n", v ) ); +} + +/* +=============== +idCmdSystemLocal::Echo_f + +Just prints the rest of the line to the console +=============== +*/ +void idCmdSystemLocal::Echo_f( const idCmdArgs &args ) { + int i; + + for ( i = 1; i < args.Argc(); i++ ) { + common->Printf( "%s ", args.Argv( i ) ); + } + common->Printf( "\n" ); +} + +/* +============ +idCmdSystemLocal::Wait_f + +Causes execution of the remainder of the command buffer to be delayed until next frame. +============ +*/ +void idCmdSystemLocal::Wait_f( const idCmdArgs &args ) { + if ( args.Argc() == 2 ) { + cmdSystemLocal.SetWait( atoi( args.Argv( 1 ) ) ); + } else { + cmdSystemLocal.SetWait( 1 ); + } +} + +/* +============ +idCmdSystemLocal::Parse_f + +This just prints out how the rest of the line was parsed, as a debugging tool. +============ +*/ +void idCmdSystemLocal::Parse_f( const idCmdArgs &args ) { + int i; + + for ( i = 0; i < args.Argc(); i++ ) { + common->Printf( "%i: %s\n", i, args.Argv(i) ); + } +} + +/* +============ +idCmdSystemLocal::Init +============ +*/ +void idCmdSystemLocal::Init( void ) { + + AddCommand( "listCmds", List_f, CMD_FL_SYSTEM, "lists commands" ); + AddCommand( "listSystemCmds", SystemList_f, CMD_FL_SYSTEM, "lists system commands" ); + AddCommand( "listRendererCmds", RendererList_f, CMD_FL_SYSTEM, "lists renderer commands" ); + AddCommand( "listSoundCmds", SoundList_f, CMD_FL_SYSTEM, "lists sound commands" ); + AddCommand( "listGameCmds", GameList_f, CMD_FL_SYSTEM, "lists game commands" ); + AddCommand( "listToolCmds", ToolList_f, CMD_FL_SYSTEM, "lists tool commands" ); + AddCommand( "exec", Exec_f, CMD_FL_SYSTEM, "executes a config file", ArgCompletion_ConfigName ); + AddCommand( "vstr", Vstr_f, CMD_FL_SYSTEM, "inserts the current value of a cvar as command text" ); + AddCommand( "echo", Echo_f, CMD_FL_SYSTEM, "prints text" ); + AddCommand( "parse", Parse_f, CMD_FL_SYSTEM, "prints tokenized string" ); + AddCommand( "wait", Wait_f, CMD_FL_SYSTEM, "delays remaining buffered commands one or more frames" ); + + completionString = "*"; + + textLength = 0; +} + +/* +============ +idCmdSystemLocal::Shutdown +============ +*/ +void idCmdSystemLocal::Shutdown( void ) { + commandDef_t *cmd; + + for ( cmd = commands; cmd; cmd = commands ) { + commands = commands->next; + Mem_Free( cmd->name ); + Mem_Free( cmd->description ); + delete cmd; + } + + completionString.Clear(); + completionParms.Clear(); + tokenizedCmds.Clear(); + postReload.Clear(); +} + +/* +============ +idCmdSystemLocal::AddCommand +============ +*/ +void idCmdSystemLocal::AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion ) { + commandDef_t *cmd; + + // fail if the command already exists + for ( cmd = commands; cmd; cmd = cmd->next ) { + if ( idStr::Cmp( cmdName, cmd->name ) == 0 ) { + if ( function != cmd->function ) { + common->Printf( "idCmdSystemLocal::AddCommand: %s already defined\n", cmdName ); + } + return; + } + } + + cmd = new commandDef_t; + cmd->name = Mem_CopyString( cmdName ); + cmd->function = function; + cmd->argCompletion = argCompletion; + cmd->flags = flags; + cmd->description = Mem_CopyString( description ); + cmd->next = commands; + commands = cmd; +} + +/* +============ +idCmdSystemLocal::RemoveCommand +============ +*/ +void idCmdSystemLocal::RemoveCommand( const char *cmdName ) { + commandDef_t *cmd, **last; + + for ( last = &commands, cmd = *last; cmd; cmd = *last ) { + if ( idStr::Cmp( cmdName, cmd->name ) == 0 ) { + *last = cmd->next; + Mem_Free( cmd->name ); + Mem_Free( cmd->description ); + delete cmd; + return; + } + last = &cmd->next; + } +} + +/* +============ +idCmdSystemLocal::RemoveFlaggedCommands +============ +*/ +void idCmdSystemLocal::RemoveFlaggedCommands( int flags ) { + commandDef_t *cmd, **last; + + for ( last = &commands, cmd = *last; cmd; cmd = *last ) { + if ( cmd->flags & flags ) { + *last = cmd->next; + Mem_Free( cmd->name ); + Mem_Free( cmd->description ); + delete cmd; + continue; + } + last = &cmd->next; + } +} + +/* +============ +idCmdSystemLocal::CommandCompletion +============ +*/ +void idCmdSystemLocal::CommandCompletion( void(*callback)( const char *s ) ) { + commandDef_t *cmd; + + for ( cmd = commands; cmd; cmd = cmd->next ) { + callback( cmd->name ); + } +} + +/* +============ +idCmdSystemLocal::ArgCompletion +============ +*/ +void idCmdSystemLocal::ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) { + commandDef_t *cmd; + idCmdArgs args; + + args.TokenizeString( cmdString, false ); + + for ( cmd = commands; cmd; cmd = cmd->next ) { + if ( !cmd->argCompletion ) { + continue; + } + if ( idStr::Icmp( args.Argv( 0 ), cmd->name ) == 0 ) { + cmd->argCompletion( args, callback ); + break; + } + } +} + +/* +============ +idCmdSystemLocal::ExecuteTokenizedString +============ +*/ +void idCmdSystemLocal::ExecuteTokenizedString( const idCmdArgs &args ) { + commandDef_t *cmd, **prev; + + // execute the command line + if ( !args.Argc() ) { + return; // no tokens + } + + // check registered command functions + for ( prev = &commands; *prev; prev = &cmd->next ) { + cmd = *prev; + if ( idStr::Icmp( args.Argv( 0 ), cmd->name ) == 0 ) { + // rearrange the links so that the command will be + // near the head of the list next time it is used + *prev = cmd->next; + cmd->next = commands; + commands = cmd; + + if ( ( cmd->flags & (CMD_FL_CHEAT|CMD_FL_TOOL) ) && session && session->IsMultiplayer() && !cvarSystem->GetCVarBool( "net_allowCheats" ) ) { + common->Printf( "Command '%s' not valid in multiplayer mode.\n", cmd->name ); + return; + } + // perform the action + if ( !cmd->function ) { + break; + } else { + cmd->function( args ); + } + return; + } + } + + // check cvars + if ( cvarSystem->Command( args ) ) { + return; + } + + common->Printf( "Unknown command '%s'\n", args.Argv( 0 ) ); +} + +/* +============ +idCmdSystemLocal::ExecuteCommandText + +Tokenizes, then executes. +============ +*/ +void idCmdSystemLocal::ExecuteCommandText( const char *text ) { + ExecuteTokenizedString( idCmdArgs( text, false ) ); +} + +/* +============ +idCmdSystemLocal::InsertCommandText + +Adds command text immediately after the current command +Adds a \n to the text +============ +*/ +void idCmdSystemLocal::InsertCommandText( const char *text ) { + int len; + int i; + + len = strlen( text ) + 1; + if ( len + textLength > (int)sizeof( textBuf ) ) { + common->Printf( "idCmdSystemLocal::InsertText: buffer overflow\n" ); + return; + } + + // move the existing command text + for ( i = textLength - 1; i >= 0; i-- ) { + textBuf[ i + len ] = textBuf[ i ]; + } + + // copy the new text in + memcpy( textBuf, text, len - 1 ); + + // add a \n + textBuf[ len - 1 ] = '\n'; + + textLength += len; +} + +/* +============ +idCmdSystemLocal::AppendCommandText + +Adds command text at the end of the buffer, does NOT add a final \n +============ +*/ +void idCmdSystemLocal::AppendCommandText( const char *text ) { + int l; + + l = strlen( text ); + + if ( textLength + l >= (int)sizeof( textBuf ) ) { + common->Printf( "idCmdSystemLocal::AppendText: buffer overflow\n" ); + return; + } + memcpy( textBuf + textLength, text, l ); + textLength += l; +} + +/* +============ +idCmdSystemLocal::BufferCommandText +============ +*/ +void idCmdSystemLocal::BufferCommandText( cmdExecution_t exec, const char *text ) { + switch( exec ) { + case CMD_EXEC_NOW: { + ExecuteCommandText( text ); + break; + } + case CMD_EXEC_INSERT: { + InsertCommandText( text ); + break; + } + case CMD_EXEC_APPEND: { + AppendCommandText( text ); + break; + } + default: { + common->FatalError( "idCmdSystemLocal::BufferCommandText: bad exec type" ); + } + } +} + +/* +============ +idCmdSystemLocal::BufferCommandArgs +============ +*/ +void idCmdSystemLocal::BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ) { + switch ( exec ) { + case CMD_EXEC_NOW: { + ExecuteTokenizedString( args ); + break; + } + case CMD_EXEC_APPEND: { + AppendCommandText( "_execTokenized\n" ); + tokenizedCmds.Append( args ); + break; + } + default: { + common->FatalError( "idCmdSystemLocal::BufferCommandArgs: bad exec type" ); + } + } +} + +/* +============ +idCmdSystemLocal::ExecuteCommandBuffer +============ +*/ +void idCmdSystemLocal::ExecuteCommandBuffer( void ) { + int i; + char * text; + int quotes; + idCmdArgs args; + + while( textLength ) { + + if ( wait ) { + // skip out while text still remains in buffer, leaving it for next frame + wait--; + break; + } + + // find a \n or ; line break + text = (char *)textBuf; + + quotes = 0; + for ( i = 0; i < textLength; i++ ) { + if ( text[i] == '"' ) { + quotes++; + } + if ( !( quotes & 1 ) && text[i] == ';' ) { + break; // don't break if inside a quoted string + } + if ( text[i] == '\n' || text[i] == '\r' ) { + break; + } + } + + text[i] = 0; + + if ( !idStr::Cmp( text, "_execTokenized" ) ) { + args = tokenizedCmds[ 0 ]; + tokenizedCmds.RemoveIndex( 0 ); + } else { + args.TokenizeString( text, false ); + } + + // delete the text from the command buffer and move remaining commands down + // this is necessary because commands (exec) can insert data at the + // beginning of the text buffer + + if ( i == textLength ) { + textLength = 0; + } else { + i++; + textLength -= i; + memmove( text, text+i, textLength ); + } + + // execute the command line that we have already tokenized + ExecuteTokenizedString( args ); + } +} + +/* +============ +idCmdSystemLocal::ArgCompletion_FolderExtension +============ +*/ +void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) { + int i; + idStr string; + const char *extension; + va_list argPtr; + + string = args.Argv( 0 ); + string += " "; + string += args.Argv( 1 ); + + if ( string.Icmp( completionString ) != 0 ) { + idStr parm, path; + idFileList *names; + + completionString = string; + completionParms.Clear(); + + parm = args.Argv( 1 ); + parm.ExtractFilePath( path ); + if ( stripFolder || path.Length() == 0 ) { + path = folder + path; + } + path.StripTrailing( '/' ); + + // list folders + names = fileSystem->ListFiles( path, "/", true, true ); + for ( i = 0; i < names->GetNumFiles(); i++ ) { + idStr name = names->GetFile( i ); + if ( stripFolder ) { + name.Strip( folder ); + } else { + name.Strip( "/" ); + } + name = args.Argv( 0 ) + ( " " + name ) + "/"; + completionParms.Append( name ); + } + fileSystem->FreeFileList( names ); + + // list files + va_start( argPtr, stripFolder ); + for ( extension = va_arg( argPtr, const char * ); extension; extension = va_arg( argPtr, const char * ) ) { + names = fileSystem->ListFiles( path, extension, true, true ); + for ( i = 0; i < names->GetNumFiles(); i++ ) { + idStr name = names->GetFile( i ); + if ( stripFolder ) { + name.Strip( folder ); + } else { + name.Strip( "/" ); + } + name = args.Argv( 0 ) + ( " " + name ); + completionParms.Append( name ); + } + fileSystem->FreeFileList( names ); + } + va_end( argPtr ); + } + for ( i = 0; i < completionParms.Num(); i++ ) { + callback( completionParms[i] ); + } +} + +/* +============ +idCmdSystemLocal::ArgCompletion_DeclName +============ +*/ +void idCmdSystemLocal::ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ) { + int i, num; + + if ( declManager == NULL ) { + return; + } + num = declManager->GetNumDecls( (declType_t)type ); + for ( i = 0; i < num; i++ ) { + callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( (declType_t)type, i , false )->GetName() ); + } +} + +/* +============ +idCmdSystemLocal::SetupReloadEngine +============ +*/ +void idCmdSystemLocal::SetupReloadEngine( const idCmdArgs &args ) { + BufferCommandText( CMD_EXEC_APPEND, "reloadEngine\n" ); + postReload = args; +} + +/* +============ +idCmdSystemLocal::PostReloadEngine +============ +*/ +bool idCmdSystemLocal::PostReloadEngine( void ) { + if ( !postReload.Argc() ) { + return false; + } + BufferCommandArgs( CMD_EXEC_APPEND, postReload ); + postReload.Clear(); + return true; +} diff --git a/framework/CmdSystem.h b/framework/CmdSystem.h new file mode 100644 index 000000000..a1b73628e --- /dev/null +++ b/framework/CmdSystem.h @@ -0,0 +1,179 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CMDSYSTEM_H__ +#define __CMDSYSTEM_H__ + +/* +=============================================================================== + + Console command execution and command text buffering. + + Any number of commands can be added in a frame from several different + sources. Most commands come from either key bindings or console line input, + but entire text files can be execed. + + Command execution takes a null terminated string, breaks it into tokens, + then searches for a command or variable that matches the first token. + +=============================================================================== +*/ + +// command flags +typedef enum { + CMD_FL_ALL = -1, + CMD_FL_CHEAT = BIT(0), // command is considered a cheat + CMD_FL_SYSTEM = BIT(1), // system command + CMD_FL_RENDERER = BIT(2), // renderer command + CMD_FL_SOUND = BIT(3), // sound command + CMD_FL_GAME = BIT(4), // game command + CMD_FL_TOOL = BIT(5) // tool command +} cmdFlags_t; + +// parameters for command buffer stuffing +typedef enum { + CMD_EXEC_NOW, // don't return until completed + CMD_EXEC_INSERT, // insert at current position, but don't run yet + CMD_EXEC_APPEND // add to end of the command buffer (normal case) +} cmdExecution_t; + +// command function +typedef void (*cmdFunction_t)( const idCmdArgs &args ); + +// argument completion function +typedef void (*argCompletion_t)( const idCmdArgs &args, void(*callback)( const char *s ) ); + + +class idCmdSystem { +public: + virtual ~idCmdSystem( void ) {} + + virtual void Init( void ) = 0; + virtual void Shutdown( void ) = 0; + + // Registers a command and the function to call for it. + virtual void AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion = NULL ) = 0; + // Removes a command. + virtual void RemoveCommand( const char *cmdName ) = 0; + // Remove all commands with one of the flags set. + virtual void RemoveFlaggedCommands( int flags ) = 0; + + // Command and argument completion using callback for each valid string. + virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0; + virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0; + + // Adds command text to the command buffer, does not add a final \n + virtual void BufferCommandText( cmdExecution_t exec, const char *text ) = 0; + // Pulls off \n \r or ; terminated lines of text from the command buffer and + // executes the commands. Stops when the buffer is empty. + // Normally called once per frame, but may be explicitly invoked. + virtual void ExecuteCommandBuffer( void ) = 0; + + // Base for path/file auto-completion. + virtual void ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) = 0; + // Base for decl name auto-completion. + virtual void ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ) = 0; + + // Adds to the command buffer in tokenized form ( CMD_EXEC_NOW or CMD_EXEC_APPEND only ) + virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ) = 0; + + // Setup a reloadEngine to happen on next command run, and give a command to execute after reload + virtual void SetupReloadEngine( const idCmdArgs &args ) = 0; + virtual bool PostReloadEngine( void ) = 0; + + // Default argument completion functions. + static void ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) ); + template + static void ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) ); + template + static void ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) ); + template + static void ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) ); +}; + +extern idCmdSystem * cmdSystem; + + +ID_INLINE void idCmdSystem::ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) ) { + callback( va( "%s 0", args.Argv( 0 ) ) ); + callback( va( "%s 1", args.Argv( 0 ) ) ); +} + +template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) ) { + for ( int i = min; i <= max; i++ ) { + callback( va( "%s %d", args.Argv( 0 ), i ) ); + } +} + +template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) ) { + for ( int i = 0; strings[i]; i++ ) { + callback( va( "%s %s", args.Argv( 0 ), strings[i] ) ); + } +} + +template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_DeclName( args, callback, type ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, "", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "maps/", true, ".map", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "sound/", false, ".wav", ".ogg", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", false, ".tga", ".dds", ".jpg", ".pcx", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "video/", false, ".roq", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, ".cfg", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "SaveGames/", true, ".save", NULL ); +} + +ID_INLINE void idCmdSystem::ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "demos/", true, ".demo", NULL ); +} + +#endif /* !__CMDSYSTEM_H__ */ diff --git a/framework/Common.cpp b/framework/Common.cpp new file mode 100644 index 000000000..a9e2536f4 --- /dev/null +++ b/framework/Common.cpp @@ -0,0 +1,3092 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "../renderer/Image.h" + +#define MAX_PRINT_MSG_SIZE 4096 +#define MAX_WARNING_LIST 256 + +typedef enum { + ERP_NONE, + ERP_FATAL, // exit the entire game with a popup window + ERP_DROP, // print to console and disconnect from game + ERP_DISCONNECT // don't kill server +} errorParm_t; + +#if defined( _DEBUG ) + #define BUILD_DEBUG "-debug" +#else + #define BUILD_DEBUG "" +#endif + +struct version_s { + version_s( void ) { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } + char string[256]; +} version; + +idCVar com_version( "si_version", version.string, CVAR_SYSTEM|CVAR_ROM|CVAR_SERVERINFO, "engine version" ); +idCVar com_skipRenderer( "com_skipRenderer", "0", CVAR_BOOL|CVAR_SYSTEM, "skip the renderer completely" ); +idCVar com_machineSpec( "com_machineSpec", "-1", CVAR_INTEGER | CVAR_ARCHIVE | CVAR_SYSTEM, "hardware classification, -1 = not detected, 0 = low quality, 1 = medium quality, 2 = high quality, 3 = ultra quality" ); +idCVar com_purgeAll( "com_purgeAll", "0", CVAR_BOOL | CVAR_ARCHIVE | CVAR_SYSTEM, "purge everything between level loads" ); +idCVar com_memoryMarker( "com_memoryMarker", "-1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_INIT, "used as a marker for memory stats" ); +idCVar com_preciseTic( "com_preciseTic", "1", CVAR_BOOL|CVAR_SYSTEM, "run one game tick every async thread update" ); +idCVar com_asyncInput( "com_asyncInput", "0", CVAR_BOOL|CVAR_SYSTEM, "sample input from the async thread" ); +#define ASYNCSOUND_INFO "0: mix sound inline, 1: memory mapped async mix, 2: callback mixing, 3: write async mix" +#if defined( MACOS_X ) +idCVar com_asyncSound( "com_asyncSound", "2", CVAR_INTEGER|CVAR_SYSTEM|CVAR_ROM, ASYNCSOUND_INFO ); +#elif defined( __linux__ ) +idCVar com_asyncSound( "com_asyncSound", "3", CVAR_INTEGER|CVAR_SYSTEM|CVAR_ROM, ASYNCSOUND_INFO ); +#else +idCVar com_asyncSound( "com_asyncSound", "1", CVAR_INTEGER|CVAR_SYSTEM, ASYNCSOUND_INFO, 0, 1 ); +#endif +idCVar com_forceGenericSIMD( "com_forceGenericSIMD", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "force generic platform independent SIMD" ); +idCVar com_developer( "developer", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "developer mode" ); +idCVar com_allowConsole( "com_allowConsole", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "allow toggling console with the tilde key" ); +idCVar com_speeds( "com_speeds", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show engine timings" ); +idCVar com_showFPS( "com_showFPS", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_ARCHIVE|CVAR_NOCHEAT, "show frames rendered per second" ); +idCVar com_showMemoryUsage( "com_showMemoryUsage", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show total and per frame memory usage" ); +idCVar com_showAsyncStats( "com_showAsyncStats", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show async network stats" ); +idCVar com_showSoundDecoders( "com_showSoundDecoders", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show sound decoders" ); +idCVar com_timestampPrints( "com_timestampPrints", "0", CVAR_SYSTEM, "print time with each console print, 1 = msec, 2 = sec", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar com_timescale( "timescale", "1", CVAR_SYSTEM | CVAR_FLOAT, "scales the time", 0.1f, 10.0f ); +idCVar com_logFile( "logFile", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "1 = buffer log, 2 = flush after each print", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar com_logFileName( "logFileName", "qconsole.log", CVAR_SYSTEM | CVAR_NOCHEAT, "name of log file, if empty, qconsole.log will be used" ); +idCVar com_makingBuild( "com_makingBuild", "0", CVAR_BOOL | CVAR_SYSTEM, "1 when making a build" ); +idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" ); +idCVar com_videoRam( "com_videoRam", "64", CVAR_INTEGER | CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "holds the last amount of detected video ram" ); + +idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." ); + +// com_speeds times +int time_gameFrame; +int time_gameDraw; +int time_frontend; // renderSystem frontend time +int time_backend; // renderSystem backend time + +int com_frameTime; // time for the current frame in milliseconds +int com_frameNumber; // variable frame number +volatile int com_ticNumber; // 60 hz tics +int com_editors; // currently opened editor(s) +bool com_editorActive; // true if an editor has focus + +#ifdef _WIN32 +HWND com_hwndMsg = NULL; +bool com_outputMsg = false; +unsigned int com_msgID = -1; +#endif + +#ifdef __DOOM_DLL__ +idGame * game = NULL; +idGameEdit * gameEdit = NULL; +#endif + +// writes si_version to the config file - in a kinda obfuscated way +//#define ID_WRITE_VERSION + +class idCommonLocal : public idCommon { +public: + idCommonLocal( void ); + + virtual void Init( int argc, const char **argv, const char *cmdline ); + virtual void Shutdown( void ); + virtual void Quit( void ); + virtual bool IsInitialized( void ) const; + virtual void Frame( void ); + virtual void GUIFrame( bool execCmd, bool network ); + virtual void Async( void ); + virtual void StartupVariable( const char *match, bool once ); + virtual void InitTool( const toolFlag_t tool, const idDict *dict ); + virtual void ActivateTool( bool active ); + virtual void WriteConfigToFile( const char *filename ); + virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ); + virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ); + virtual void EndRedirect( void ); + virtual void SetRefreshOnPrint( bool set ); + virtual void Printf( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual void VPrintf( const char *fmt, va_list arg ); + virtual void DPrintf( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual void Warning( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual void DWarning( const char *fmt, ...) id_attribute((format(printf,2,3))); + virtual void PrintWarnings( void ); + virtual void ClearWarnings( const char *reason ); + virtual void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual void FatalError( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual const idLangDict * GetLanguageDict( void ); + + virtual const char * KeysFromBinding( const char *bind ); + virtual const char * BindingFromKey( const char *key ); + + virtual int ButtonState( int key ); + virtual int KeyState( int key ); + + void InitGame( void ); + void ShutdownGame( bool reloading ); + + // localization + void InitLanguageDict( void ); + void LocalizeGui( const char *fileName, idLangDict &langDict ); + void LocalizeMapData( const char *fileName, idLangDict &langDict ); + void LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs ); + + void SetMachineSpec( void ); + +private: + void InitCommands( void ); + void InitRenderSystem( void ); + void InitSIMD( void ); + bool AddStartupCommands( void ); + void ParseCommandLine( int argc, const char **argv ); + void ClearCommandLine( void ); + bool SafeMode( void ); + void CheckToolMode( void ); + void CloseLogFile( void ); + void WriteConfiguration( void ); + void DumpWarnings( void ); + void SingleAsyncTic( void ); + void LoadGameDLL( void ); + void UnloadGameDLL( void ); + void PrintLoadingMessage( const char *msg ); + void FilterLangList( idStrList* list, idStr lang ); + + bool com_fullyInitialized; + bool com_refreshOnPrint; // update the screen every print for dmap + int com_errorEntered; // 0, ERP_DROP, etc + bool com_shuttingDown; + + idFile * logFile; + + char errorMessage[MAX_PRINT_MSG_SIZE]; + + char * rd_buffer; + int rd_buffersize; + void (*rd_flush)( const char *buffer ); + + idStr warningCaption; + idStrList warningList; + idStrList errorList; + + int gameDLL; + + idLangDict languageDict; + +#ifdef ID_WRITE_VERSION + idCompressor * config_compressor; +#endif +}; + +idCommonLocal commonLocal; +idCommon * common = &commonLocal; + + +/* +================== +idCommonLocal::idCommonLocal +================== +*/ +idCommonLocal::idCommonLocal( void ) { + com_fullyInitialized = false; + com_refreshOnPrint = false; + com_errorEntered = 0; + com_shuttingDown = false; + + logFile = NULL; + + strcpy( errorMessage, "" ); + + rd_buffer = NULL; + rd_buffersize = 0; + rd_flush = NULL; + + gameDLL = 0; + +#ifdef ID_WRITE_VERSION + config_compressor = NULL; +#endif +} + +/* +================== +idCommonLocal::BeginRedirect +================== +*/ +void idCommonLocal::BeginRedirect( char *buffer, int buffersize, void (*flush)( const char *) ) { + if ( !buffer || !buffersize || !flush ) { + return; + } + rd_buffer = buffer; + rd_buffersize = buffersize; + rd_flush = flush; + + *rd_buffer = 0; +} + +/* +================== +idCommonLocal::EndRedirect +================== +*/ +void idCommonLocal::EndRedirect( void ) { + if ( rd_flush && rd_buffer[ 0 ] ) { + rd_flush( rd_buffer ); + } + + rd_buffer = NULL; + rd_buffersize = 0; + rd_flush = NULL; +} + +#ifdef _WIN32 + +/* +================== +EnumWindowsProc +================== +*/ +BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) { + char buff[1024]; + + ::GetWindowText( hwnd, buff, sizeof( buff ) ); + if ( idStr::Icmpn( buff, EDITOR_WINDOWTEXT, strlen( EDITOR_WINDOWTEXT ) ) == 0 ) { + com_hwndMsg = hwnd; + return FALSE; + } + return TRUE; +} + +/* +================== +FindEditor +================== +*/ +bool FindEditor( void ) { + com_hwndMsg = NULL; + EnumWindows( EnumWindowsProc, 0 ); + return !( com_hwndMsg == NULL ); +} + +#endif + +/* +================== +idCommonLocal::CloseLogFile +================== +*/ +void idCommonLocal::CloseLogFile( void ) { + if ( logFile ) { + com_logFile.SetBool( false ); // make sure no further VPrintf attempts to open the log file again + fileSystem->CloseFile( logFile ); + logFile = NULL; + } +} + +/* +================== +idCommonLocal::SetRefreshOnPrint +================== +*/ +void idCommonLocal::SetRefreshOnPrint( bool set ) { + com_refreshOnPrint = set; +} + +/* +================== +idCommonLocal::VPrintf + +A raw string should NEVER be passed as fmt, because of "%f" type crashes. +================== +*/ +void idCommonLocal::VPrintf( const char *fmt, va_list args ) { + char msg[MAX_PRINT_MSG_SIZE]; + int timeLength; + static bool logFileFailed = false; + + // if the cvar system is not initialized + if ( !cvarSystem->IsInitialized() ) { + return; + } + + // optionally put a timestamp at the beginning of each print, + // so we can see how long different init sections are taking + if ( com_timestampPrints.GetInteger() ) { + int t = Sys_Milliseconds(); + if ( com_timestampPrints.GetInteger() == 1 ) { + t /= 1000; + } + sprintf( msg, "[%i]", t ); + timeLength = strlen( msg ); + } else { + timeLength = 0; + } + + // don't overflow + if ( idStr::vsnPrintf( msg+timeLength, MAX_PRINT_MSG_SIZE-timeLength-1, fmt, args ) < 0 ) { + msg[sizeof(msg)-2] = '\n'; msg[sizeof(msg)-1] = '\0'; // avoid output garbling + Sys_Printf( "idCommon::VPrintf: truncated to %d characters\n", strlen(msg)-1 ); + } + + if ( rd_buffer ) { + if ( (int)( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) ) { + rd_flush( rd_buffer ); + *rd_buffer = 0; + } + strcat( rd_buffer, msg ); + return; + } + + // echo to console buffer + console->Print( msg ); + + // remove any color codes + idStr::RemoveColors( msg ); + + // echo to dedicated console and early console + Sys_Printf( "%s", msg ); + + // print to script debugger server + // DebuggerServerPrint( msg ); + +#if 0 // !@# +#if defined(_DEBUG) && defined(WIN32) + if ( strlen( msg ) < 512 ) { + TRACE( msg ); + } +#endif +#endif + + // logFile + if ( com_logFile.GetInteger() && !logFileFailed && fileSystem->IsInitialized() ) { + static bool recursing; + + if ( !logFile && !recursing ) { + struct tm *newtime; + ID_TIME_T aclock; + const char *fileName = com_logFileName.GetString()[0] ? com_logFileName.GetString() : "qconsole.log"; + + // fileSystem->OpenFileWrite can cause recursive prints into here + recursing = true; + + logFile = fileSystem->OpenFileWrite( fileName ); + if ( !logFile ) { + logFileFailed = true; + FatalError( "failed to open log file '%s'\n", fileName ); + } + + recursing = false; + + if ( com_logFile.GetInteger() > 1 ) { + // force it to not buffer so we get valid + // data even if we are crashing + logFile->ForceFlush(); + } + + time( &aclock ); + newtime = localtime( &aclock ); + Printf( "log file '%s' opened on %s\n", fileName, asctime( newtime ) ); + } + if ( logFile ) { + logFile->Write( msg, strlen( msg ) ); + logFile->Flush(); // ForceFlush doesn't help a whole lot + } + } + + // don't trigger any updates if we are in the process of doing a fatal error + if ( com_errorEntered != ERP_FATAL ) { + // update the console if we are in a long-running command, like dmap + if ( com_refreshOnPrint ) { + session->UpdateScreen(); + } + + // let session redraw the animated loading screen if necessary + session->PacifierUpdate(); + } + +#ifdef _WIN32 + + if ( com_outputMsg ) { + if ( com_msgID == -1 ) { + com_msgID = ::RegisterWindowMessage( DMAP_MSGID ); + if ( !FindEditor() ) { + com_outputMsg = false; + } else { + Sys_ShowWindow( false ); + } + } + if ( com_hwndMsg ) { + ATOM atom = ::GlobalAddAtom( msg ); + ::PostMessage( com_hwndMsg, com_msgID, 0, static_cast(atom) ); + } + } + +#endif +} + +/* +================== +idCommonLocal::Printf + +Both client and server can use this, and it will output to the appropriate place. + +A raw string should NEVER be passed as fmt, because of "%f" type crashers. +================== +*/ +void idCommonLocal::Printf( const char *fmt, ... ) { + va_list argptr; + va_start( argptr, fmt ); + VPrintf( fmt, argptr ); + va_end( argptr ); +} + +/* +================== +idCommonLocal::DPrintf + +prints message that only shows up if the "developer" cvar is set +================== +*/ +void idCommonLocal::DPrintf( const char *fmt, ... ) { + va_list argptr; + char msg[MAX_PRINT_MSG_SIZE]; + + if ( !cvarSystem->IsInitialized() || !com_developer.GetBool() ) { + return; // don't confuse non-developers with techie stuff... + } + + va_start( argptr, fmt ); + idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr ); + va_end( argptr ); + msg[sizeof(msg)-1] = '\0'; + + // never refresh the screen, which could cause reentrency problems + bool temp = com_refreshOnPrint; + com_refreshOnPrint = false; + + Printf( S_COLOR_RED"%s", msg ); + + com_refreshOnPrint = temp; +} + +/* +================== +idCommonLocal::DWarning + +prints warning message in yellow that only shows up if the "developer" cvar is set +================== +*/ +void idCommonLocal::DWarning( const char *fmt, ... ) { + va_list argptr; + char msg[MAX_PRINT_MSG_SIZE]; + + if ( !com_developer.GetBool() ) { + return; // don't confuse non-developers with techie stuff... + } + + va_start( argptr, fmt ); + idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr ); + va_end( argptr ); + msg[sizeof(msg)-1] = '\0'; + + Printf( S_COLOR_YELLOW"WARNING: %s\n", msg ); +} + +/* +================== +idCommonLocal::Warning + +prints WARNING %s and adds the warning message to a queue to be printed later on +================== +*/ +void idCommonLocal::Warning( const char *fmt, ... ) { + va_list argptr; + char msg[MAX_PRINT_MSG_SIZE]; + + va_start( argptr, fmt ); + idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr ); + va_end( argptr ); + msg[sizeof(msg)-1] = 0; + + Printf( S_COLOR_YELLOW "WARNING: " S_COLOR_RED "%s\n", msg ); + + if ( warningList.Num() < MAX_WARNING_LIST ) { + warningList.AddUnique( msg ); + } +} + +/* +================== +idCommonLocal::PrintWarnings +================== +*/ +void idCommonLocal::PrintWarnings( void ) { + int i; + + if ( !warningList.Num() ) { + return; + } + + warningList.Sort(); + + Printf( "------------- Warnings ---------------\n" ); + Printf( "during %s...\n", warningCaption.c_str() ); + + for ( i = 0; i < warningList.Num(); i++ ) { + Printf( S_COLOR_YELLOW "WARNING: " S_COLOR_RED "%s\n", warningList[i].c_str() ); + } + if ( warningList.Num() ) { + if ( warningList.Num() >= MAX_WARNING_LIST ) { + Printf( "more than %d warnings\n", MAX_WARNING_LIST ); + } else { + Printf( "%d warnings\n", warningList.Num() ); + } + } +} + +/* +================== +idCommonLocal::ClearWarnings +================== +*/ +void idCommonLocal::ClearWarnings( const char *reason ) { + warningCaption = reason; + warningList.Clear(); +} + +/* +================== +idCommonLocal::DumpWarnings +================== +*/ +void idCommonLocal::DumpWarnings( void ) { + int i; + idFile *warningFile; + + if ( !warningList.Num() ) { + return; + } + + warningFile = fileSystem->OpenFileWrite( "warnings.txt", "fs_savepath" ); + if ( warningFile ) { + + warningFile->Printf( "------------- Warnings ---------------\n\n" ); + warningFile->Printf( "during %s...\n", warningCaption.c_str() ); + warningList.Sort(); + for ( i = 0; i < warningList.Num(); i++ ) { + warningList[i].RemoveColors(); + warningFile->Printf( "WARNING: %s\n", warningList[i].c_str() ); + } + if ( warningList.Num() >= MAX_WARNING_LIST ) { + warningFile->Printf( "\nmore than %d warnings!\n", MAX_WARNING_LIST ); + } else { + warningFile->Printf( "\n%d warnings.\n", warningList.Num() ); + } + + warningFile->Printf( "\n\n-------------- Errors ---------------\n\n" ); + errorList.Sort(); + for ( i = 0; i < errorList.Num(); i++ ) { + errorList[i].RemoveColors(); + warningFile->Printf( "ERROR: %s", errorList[i].c_str() ); + } + + warningFile->ForceFlush(); + + fileSystem->CloseFile( warningFile ); + +#if defined(_WIN32) && !defined(_DEBUG) + idStr osPath; + osPath = fileSystem->RelativePathToOSPath( "warnings.txt", "fs_savepath" ); + WinExec( va( "Notepad.exe %s", osPath.c_str() ), SW_SHOW ); +#endif + } +} + +/* +================== +idCommonLocal::Error +================== +*/ +void idCommonLocal::Error( const char *fmt, ... ) { + va_list argptr; + static int lastErrorTime; + static int errorCount; + int currentTime; + + int code = ERP_DROP; + + // always turn this off after an error + com_refreshOnPrint = false; + + // when we are running automated scripts, make sure we + // know if anything failed + if ( cvarSystem->GetCVarInteger( "fs_copyfiles" ) ) { + code = ERP_FATAL; + } + + // if we don't have GL running, make it a fatal error + if ( !renderSystem->IsOpenGLRunning() ) { + code = ERP_FATAL; + } + + // if we got a recursive error, make it fatal + if ( com_errorEntered ) { + // if we are recursively erroring while exiting + // from a fatal error, just kill the entire + // process immediately, which will prevent a + // full screen rendering window covering the + // error dialog + if ( com_errorEntered == ERP_FATAL ) { + Sys_Quit(); + } + code = ERP_FATAL; + } + + // if we are getting a solid stream of ERP_DROP, do an ERP_FATAL + currentTime = Sys_Milliseconds(); + if ( currentTime - lastErrorTime < 100 ) { + if ( ++errorCount > 3 ) { + code = ERP_FATAL; + } + } else { + errorCount = 0; + } + lastErrorTime = currentTime; + + com_errorEntered = code; + + va_start (argptr,fmt); + idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr ); + va_end (argptr); + errorMessage[sizeof(errorMessage)-1] = '\0'; + + // copy the error message to the clip board + Sys_SetClipboardData( errorMessage ); + + // add the message to the error list + errorList.AddUnique( errorMessage ); + + // Dont shut down the session for gui editor or debugger + if ( !( com_editors & ( EDITOR_GUI | EDITOR_DEBUGGER ) ) ) { + session->Stop(); + } + + if ( code == ERP_DISCONNECT ) { + com_errorEntered = 0; + throw idException( errorMessage ); + // The gui editor doesnt want thing to com_error so it handles exceptions instead + } else if( com_editors & ( EDITOR_GUI | EDITOR_DEBUGGER ) ) { + com_errorEntered = 0; + throw idException( errorMessage ); + } else if ( code == ERP_DROP ) { + Printf( "********************\nERROR: %s\n********************\n", errorMessage ); + com_errorEntered = 0; + throw idException( errorMessage ); + } else { + Printf( "********************\nERROR: %s\n********************\n", errorMessage ); + } + + if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" ); + } + + Shutdown(); + + Sys_Error( "%s", errorMessage ); +} + +/* +================== +idCommonLocal::FatalError + +Dump out of the game to a system dialog +================== +*/ +void idCommonLocal::FatalError( const char *fmt, ... ) { + va_list argptr; + + // if we got a recursive error, make it fatal + if ( com_errorEntered ) { + // if we are recursively erroring while exiting + // from a fatal error, just kill the entire + // process immediately, which will prevent a + // full screen rendering window covering the + // error dialog + + Sys_Printf( "FATAL: recursed fatal error:\n%s\n", errorMessage ); + + va_start( argptr, fmt ); + idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr ); + va_end( argptr ); + errorMessage[sizeof(errorMessage)-1] = '\0'; + + Sys_Printf( "%s\n", errorMessage ); + + // write the console to a log file? + Sys_Quit(); + } + com_errorEntered = ERP_FATAL; + + va_start( argptr, fmt ); + idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr ); + va_end( argptr ); + errorMessage[sizeof(errorMessage)-1] = '\0'; + + if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" ); + } + + Sys_SetFatalError( errorMessage ); + + Shutdown(); + + Sys_Error( "%s", errorMessage ); +} + +/* +================== +idCommonLocal::Quit +================== +*/ +void idCommonLocal::Quit( void ) { + +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_RADIANT ) { + RadiantInit(); + return; + } +#endif + + // don't try to shutdown if we are in a recursive error + if ( !com_errorEntered ) { + Shutdown(); + } + + Sys_Quit(); +} + + +/* +============================================================================ + +COMMAND LINE FUNCTIONS + ++ characters separate the commandLine string into multiple console +command lines. + +All of these are valid: + +doom +set test blah +map test +doom set test blah+map test +doom set test blah + map test + +============================================================================ +*/ + +#define MAX_CONSOLE_LINES 32 +int com_numConsoleLines; +idCmdArgs com_consoleLines[MAX_CONSOLE_LINES]; + +/* +================== +idCommonLocal::ParseCommandLine +================== +*/ +void idCommonLocal::ParseCommandLine( int argc, const char **argv ) { + int i, current_count; + + com_numConsoleLines = 0; + current_count = 0; + // API says no program path + for ( i = 0; i < argc; i++ ) { + if ( argv[ i ][ 0 ] == '+' ) { + com_numConsoleLines++; + com_consoleLines[ com_numConsoleLines-1 ].AppendArg( argv[ i ] + 1 ); + } else { + if ( !com_numConsoleLines ) { + com_numConsoleLines++; + } + com_consoleLines[ com_numConsoleLines-1 ].AppendArg( argv[ i ] ); + } + } +} + +/* +================== +idCommonLocal::ClearCommandLine +================== +*/ +void idCommonLocal::ClearCommandLine( void ) { + com_numConsoleLines = 0; +} + +/* +================== +idCommonLocal::SafeMode + +Check for "safe" on the command line, which will +skip loading of config file (DoomConfig.cfg) +================== +*/ +bool idCommonLocal::SafeMode( void ) { + int i; + + for ( i = 0 ; i < com_numConsoleLines ; i++ ) { + if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "safe" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "cvar_restart" ) ) { + com_consoleLines[ i ].Clear(); + return true; + } + } + return false; +} + +/* +================== +idCommonLocal::CheckToolMode + +Check for "renderbump", "dmap", or "editor" on the command line, +and force fullscreen off in those cases +================== +*/ +void idCommonLocal::CheckToolMode( void ) { + int i; + + for ( i = 0 ; i < com_numConsoleLines ; i++ ) { + if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "guieditor" ) ) { + com_editors |= EDITOR_GUI; + } + else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "debugger" ) ) { + com_editors |= EDITOR_DEBUGGER; + } + else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "editor" ) ) { + com_editors |= EDITOR_RADIANT; + } + // Nerve: Add support for the material editor + else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "materialEditor" ) ) { + com_editors |= EDITOR_MATERIAL; + } + + if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "renderbump" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "editor" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "guieditor" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "debugger" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "dmap" ) + || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "materialEditor" ) + ) { + cvarSystem->SetCVarBool( "r_fullscreen", false ); + return; + } + } +} + +/* +================== +idCommonLocal::StartupVariable + +Searches for command line parameters that are set commands. +If match is not NULL, only that cvar will be looked for. +That is necessary because cddir and basedir need to be set +before the filesystem is started, but all other sets should +be after execing the config and default. +================== +*/ +void idCommonLocal::StartupVariable( const char *match, bool once ) { + int i; + const char *s; + + i = 0; + while ( i < com_numConsoleLines ) { + if ( strcmp( com_consoleLines[ i ].Argv( 0 ), "set" ) ) { + i++; + continue; + } + + s = com_consoleLines[ i ].Argv(1); + + if ( !match || !idStr::Icmp( s, match ) ) { + cvarSystem->SetCVarString( s, com_consoleLines[ i ].Argv( 2 ) ); + if ( once ) { + // kill the line + int j = i + 1; + while ( j < com_numConsoleLines ) { + com_consoleLines[ j - 1 ] = com_consoleLines[ j ]; + j++; + } + com_numConsoleLines--; + continue; + } + } + i++; + } +} + +/* +================== +idCommonLocal::AddStartupCommands + +Adds command line parameters as script statements +Commands are separated by + signs + +Returns true if any late commands were added, which +will keep the demoloop from immediately starting +================== +*/ +bool idCommonLocal::AddStartupCommands( void ) { + int i; + bool added; + + added = false; + // quote every token, so args with semicolons can work + for ( i = 0; i < com_numConsoleLines; i++ ) { + if ( !com_consoleLines[i].Argc() ) { + continue; + } + + // set commands won't override menu startup + if ( idStr::Icmpn( com_consoleLines[i].Argv(0), "set", 3 ) ) { + added = true; + } + // directly as tokenized so nothing gets screwed + cmdSystem->BufferCommandArgs( CMD_EXEC_APPEND, com_consoleLines[i] ); + } + + return added; +} + +/* +================= +idCommonLocal::InitTool +================= +*/ +void idCommonLocal::InitTool( const toolFlag_t tool, const idDict *dict ) { +#ifdef ID_ALLOW_TOOLS + if ( tool & EDITOR_SOUND ) { + SoundEditorInit( dict ); + } else if ( tool & EDITOR_LIGHT ) { + LightEditorInit( dict ); + } else if ( tool & EDITOR_PARTICLE ) { + ParticleEditorInit( dict ); + } else if ( tool & EDITOR_AF ) { + AFEditorInit( dict ); + } +#endif +} + +/* +================== +idCommonLocal::ActivateTool + +Activates or Deactivates a tool +================== +*/ +void idCommonLocal::ActivateTool( bool active ) { + com_editorActive = active; + Sys_GrabMouseCursor( !active ); +} + +/* +================== +idCommonLocal::WriteFlaggedCVarsToFile +================== +*/ +void idCommonLocal::WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) { + idFile *f; + + f = fileSystem->OpenFileWrite( filename ); + if ( !f ) { + Printf( "Couldn't write %s.\n", filename ); + return; + } + cvarSystem->WriteFlaggedVariables( flags, setCmd, f ); + fileSystem->CloseFile( f ); +} + +/* +================== +idCommonLocal::WriteConfigToFile +================== +*/ +void idCommonLocal::WriteConfigToFile( const char *filename ) { + idFile *f; +#ifdef ID_WRITE_VERSION + ID_TIME_T t; + char *curtime; + idStr runtag; + idFile_Memory compressed( "compressed" ); + idBase64 out; +#endif + + f = fileSystem->OpenFileWrite( filename ); + if ( !f ) { + Printf ("Couldn't write %s.\n", filename ); + return; + } + +#ifdef ID_WRITE_VERSION + assert( config_compressor ); + t = time( NULL ); + curtime = ctime( &t ); + sprintf( runtag, "%s - %s", cvarSystem->GetCVarString( "si_version" ), curtime ); + config_compressor->Init( &compressed, true, 8 ); + config_compressor->Write( runtag.c_str(), runtag.Length() ); + config_compressor->FinishCompress( ); + out.Encode( (const byte *)compressed.GetDataPtr(), compressed.Length() ); + f->Printf( "// %s\n", out.c_str() ); +#endif + + idKeyInput::WriteBindings( f ); + cvarSystem->WriteFlaggedVariables( CVAR_ARCHIVE, "seta", f ); + fileSystem->CloseFile( f ); +} + +/* +=============== +idCommonLocal::WriteConfiguration + +Writes key bindings and archived cvars to config file if modified +=============== +*/ +void idCommonLocal::WriteConfiguration( void ) { + // if we are quiting without fully initializing, make sure + // we don't write out anything + if ( !com_fullyInitialized ) { + return; + } + + if ( !( cvarSystem->GetModifiedFlags() & CVAR_ARCHIVE ) ) { + return; + } + cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE ); + + // disable printing out the "Writing to:" message + bool developer = com_developer.GetBool(); + com_developer.SetBool( false ); + + WriteConfigToFile( CONFIG_FILE ); + session->WriteCDKey( ); + + // restore the developer cvar + com_developer.SetBool( developer ); +} + +/* +=============== +KeysFromBinding() +Returns the key bound to the command +=============== +*/ +const char* idCommonLocal::KeysFromBinding( const char *bind ) { + return idKeyInput::KeysFromBinding( bind ); +} + +/* +=============== +BindingFromKey() +Returns the binding bound to key +=============== +*/ +const char* idCommonLocal::BindingFromKey( const char *key ) { + return idKeyInput::BindingFromKey( key ); +} + +/* +=============== +ButtonState() +Returns the state of the button +=============== +*/ +int idCommonLocal::ButtonState( int key ) { + return usercmdGen->ButtonState(key); +} + +/* +=============== +ButtonState() +Returns the state of the key +=============== +*/ +int idCommonLocal::KeyState( int key ) { + return usercmdGen->KeyState(key); +} + +//============================================================================ + +#ifdef ID_ALLOW_TOOLS +/* +================== +Com_Editor_f + + we can start the editor dynamically, but we won't ever get back +================== +*/ +static void Com_Editor_f( const idCmdArgs &args ) { + RadiantInit(); +} + +/* +============= +Com_ScriptDebugger_f +============= +*/ +static void Com_ScriptDebugger_f( const idCmdArgs &args ) { + // Make sure it wasnt on the command line + if ( !( com_editors & EDITOR_DEBUGGER ) ) { + common->Printf( "Script debugger is currently disabled\n" ); + // DebuggerClientLaunch(); + } +} + +/* +============= +Com_EditGUIs_f +============= +*/ +static void Com_EditGUIs_f( const idCmdArgs &args ) { + GUIEditorInit(); +} + +/* +============= +Com_MaterialEditor_f +============= +*/ +static void Com_MaterialEditor_f( const idCmdArgs &args ) { + // Turn off sounds + soundSystem->SetMute( true ); + MaterialEditorInit(); +} +#endif // ID_ALLOW_TOOLS + +/* +============ +idCmdSystemLocal::PrintMemInfo_f + +This prints out memory debugging data +============ +*/ +static void PrintMemInfo_f( const idCmdArgs &args ) { + MemInfo_t mi; + + memset( &mi, 0, sizeof( mi ) ); + mi.filebase = session->GetCurrentMapName(); + + renderSystem->PrintMemInfo( &mi ); // textures and models + soundSystem->PrintMemInfo( &mi ); // sounds + + common->Printf( " Used image memory: %s bytes\n", idStr::FormatNumber( mi.imageAssetsTotal ).c_str() ); + mi.assetTotals += mi.imageAssetsTotal; + + common->Printf( " Used model memory: %s bytes\n", idStr::FormatNumber( mi.modelAssetsTotal ).c_str() ); + mi.assetTotals += mi.modelAssetsTotal; + + common->Printf( " Used sound memory: %s bytes\n", idStr::FormatNumber( mi.soundAssetsTotal ).c_str() ); + mi.assetTotals += mi.soundAssetsTotal; + + common->Printf( " Used asset memory: %s bytes\n", idStr::FormatNumber( mi.assetTotals ).c_str() ); + + // write overview file + idFile *f; + + f = fileSystem->OpenFileAppend( "maps/printmeminfo.txt" ); + if ( !f ) { + return; + } + + f->Printf( "total(%s ) image(%s ) model(%s ) sound(%s ): %s\n", idStr::FormatNumber( mi.assetTotals ).c_str(), idStr::FormatNumber( mi.imageAssetsTotal ).c_str(), + idStr::FormatNumber( mi.modelAssetsTotal ).c_str(), idStr::FormatNumber( mi.soundAssetsTotal ).c_str(), mi.filebase.c_str() ); + + fileSystem->CloseFile( f ); +} + +#ifdef ID_ALLOW_TOOLS +/* +================== +Com_EditLights_f +================== +*/ +static void Com_EditLights_f( const idCmdArgs &args ) { + LightEditorInit( NULL ); + cvarSystem->SetCVarInteger( "g_editEntityMode", 1 ); +} + +/* +================== +Com_EditSounds_f +================== +*/ +static void Com_EditSounds_f( const idCmdArgs &args ) { + SoundEditorInit( NULL ); + cvarSystem->SetCVarInteger( "g_editEntityMode", 2 ); +} + +/* +================== +Com_EditDecls_f +================== +*/ +static void Com_EditDecls_f( const idCmdArgs &args ) { + DeclBrowserInit( NULL ); +} + +/* +================== +Com_EditAFs_f +================== +*/ +static void Com_EditAFs_f( const idCmdArgs &args ) { + AFEditorInit( NULL ); +} + +/* +================== +Com_EditParticles_f +================== +*/ +static void Com_EditParticles_f( const idCmdArgs &args ) { + ParticleEditorInit( NULL ); +} + +/* +================== +Com_EditScripts_f +================== +*/ +static void Com_EditScripts_f( const idCmdArgs &args ) { + ScriptEditorInit( NULL ); +} + +/* +================== +Com_EditPDAs_f +================== +*/ +static void Com_EditPDAs_f( const idCmdArgs &args ) { + PDAEditorInit( NULL ); +} +#endif // ID_ALLOW_TOOLS + +/* +================== +Com_Error_f + +Just throw a fatal error to test error shutdown procedures. +================== +*/ +static void Com_Error_f( const idCmdArgs &args ) { + if ( !com_developer.GetBool() ) { + commonLocal.Printf( "error may only be used in developer mode\n" ); + return; + } + + if ( args.Argc() > 1 ) { + commonLocal.FatalError( "Testing fatal error" ); + } else { + commonLocal.Error( "Testing drop error" ); + } +} + +/* +================== +Com_Freeze_f + +Just freeze in place for a given number of seconds to test error recovery. +================== +*/ +static void Com_Freeze_f( const idCmdArgs &args ) { + float s; + int start, now; + + if ( args.Argc() != 2 ) { + commonLocal.Printf( "freeze \n" ); + return; + } + + if ( !com_developer.GetBool() ) { + commonLocal.Printf( "freeze may only be used in developer mode\n" ); + return; + } + + s = atof( args.Argv(1) ); + + start = eventLoop->Milliseconds(); + + while ( 1 ) { + now = eventLoop->Milliseconds(); + if ( ( now - start ) * 0.001f > s ) { + break; + } + } +} + +/* +================= +Com_Crash_f + +A way to force a bus error for development reasons +================= +*/ +static void Com_Crash_f( const idCmdArgs &args ) { + if ( !com_developer.GetBool() ) { + commonLocal.Printf( "crash may only be used in developer mode\n" ); + return; + } + + * ( int * ) 0 = 0x12345678; +} + +/* +================= +Com_Quit_f +================= +*/ +static void Com_Quit_f( const idCmdArgs &args ) { + commonLocal.Quit(); +} + +/* +=============== +Com_WriteConfig_f + +Write the config file to a specific name +=============== +*/ +void Com_WriteConfig_f( const idCmdArgs &args ) { + idStr filename; + + if ( args.Argc() != 2 ) { + commonLocal.Printf( "Usage: writeconfig \n" ); + return; + } + + filename = args.Argv(1); + filename.DefaultFileExtension( ".cfg" ); + commonLocal.Printf( "Writing %s.\n", filename.c_str() ); + commonLocal.WriteConfigToFile( filename ); +} + +/* +================= +Com_SetMachineSpecs_f +================= +*/ +void Com_SetMachineSpec_f( const idCmdArgs &args ) { + commonLocal.SetMachineSpec(); +} + +/* +================= +Com_ExecMachineSpecs_f +================= +*/ +#ifdef MACOS_X +void OSX_GetVideoCard( int& outVendorId, int& outDeviceId ); +bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture ); +#endif +void Com_ExecMachineSpec_f( const idCmdArgs &args ) { + if ( com_machineSpec.GetInteger() == 3 ) { + cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downsize", 0 , CVAR_ARCHIVE ); + cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 8, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useCompression", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_mode", 5, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE ); + } else if ( com_machineSpec.GetInteger() == 2 ) { + cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downsize", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 8, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_mode", 4, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE ); + } else if ( com_machineSpec.GetInteger() == 1 ) { + cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSize", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useNormalCompression", 2, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_mode", 3, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE ); + } else { + cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_anisotropy", 0, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBump", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_mode", 3 , CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_useNormalCompression", 2, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE ); + } + + if ( Sys_GetVideoRam() < 128 ) { + cvarSystem->SetCVarBool( "image_ignoreHighQuality", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBump", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE ); + } + + if ( Sys_GetSystemRam() < 512 ) { + cvarSystem->SetCVarBool( "image_ignoreHighQuality", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeLimit", 256, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE ); + cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "com_purgeAll", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "r_forceLoadImages", true, CVAR_ARCHIVE ); + } else { + cvarSystem->SetCVarBool( "com_purgeAll", false, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "r_forceLoadImages", false, CVAR_ARCHIVE ); + } + + bool oldCard = false; + bool nv10or20 = false; + renderSystem->GetCardCaps( oldCard, nv10or20 ); + if ( oldCard ) { + cvarSystem->SetCVarBool( "g_decals", false, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_projectileLights", false, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_doubleVision", false, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_muzzleFlash", false, CVAR_ARCHIVE ); + } else { + cvarSystem->SetCVarBool( "g_decals", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_projectileLights", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_doubleVision", true, CVAR_ARCHIVE ); + cvarSystem->SetCVarBool( "g_muzzleFlash", true, CVAR_ARCHIVE ); + } + if ( nv10or20 ) { + cvarSystem->SetCVarInteger( "image_useNormalCompression", 1, CVAR_ARCHIVE ); + } + +#if MACOS_X + // On low settings, G4 systems & 64MB FX5200/NV34 Systems should default shadows off + bool oldArch; + int vendorId, deviceId, cpuId; + OSX_GetVideoCard( vendorId, deviceId ); + OSX_GetCPUIdentification( cpuId, oldArch ); + bool isFX5200 = vendorId == 0x10DE && ( deviceId & 0x0FF0 ) == 0x0320; + if ( ( oldArch || ( isFX5200 && Sys_GetVideoRam() < 128 ) ) && com_machineSpec.GetInteger() == 0 ) { + cvarSystem->SetCVarBool( "r_shadows", false, CVAR_ARCHIVE ); + } else { + cvarSystem->SetCVarBool( "r_shadows", true, CVAR_ARCHIVE ); + } +#endif +} + +/* +================= +Com_ReloadEngine_f +================= +*/ +void Com_ReloadEngine_f( const idCmdArgs &args ) { + bool menu = false; + + if ( !commonLocal.IsInitialized() ) { + return; + } + + if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "menu" ) == 0 ) { + menu = true; + } + + common->Printf( "============= ReloadEngine start =============\n" ); + if ( !menu ) { + Sys_ShowConsole( 1, false ); + } + commonLocal.ShutdownGame( true ); + commonLocal.InitGame(); + if ( !menu && !idAsyncNetwork::serverDedicated.GetBool() ) { + Sys_ShowConsole( 0, false ); + } + common->Printf( "============= ReloadEngine end ===============\n" ); + + if ( !cmdSystem->PostReloadEngine() ) { + if ( menu ) { + session->StartMenu( ); + } + } +} + +/* +=============== +idCommonLocal::GetLanguageDict +=============== +*/ +const idLangDict *idCommonLocal::GetLanguageDict( void ) { + return &languageDict; +} + +/* +=============== +idCommonLocal::FilterLangList +=============== +*/ +void idCommonLocal::FilterLangList( idStrList* list, idStr lang ) { + + idStr temp; + for( int i = 0; i < list->Num(); i++ ) { + temp = (*list)[i]; + temp = temp.Right(temp.Length()-strlen("strings/")); + temp = temp.Left(lang.Length()); + if(idStr::Icmp(temp, lang) != 0) { + list->RemoveIndex(i); + i--; + } + } +} + +/* +=============== +idCommonLocal::InitLanguageDict +=============== +*/ +void idCommonLocal::InitLanguageDict( void ) { + idStr fileName; + languageDict.Clear(); + + //D3XP: Instead of just loading a single lang file for each language + //we are going to load all files that begin with the language name + //similar to the way pak files work. So you can place english001.lang + //to add new strings to the english language dictionary + idFileList* langFiles; + langFiles = fileSystem->ListFilesTree( "strings", ".lang", true ); + + idStrList langList = langFiles->GetList(); + + StartupVariable( "sys_lang", false ); // let it be set on the command line - this is needed because this init happens very early + idStr langName = cvarSystem->GetCVarString( "sys_lang" ); + + //Loop through the list and filter + idStrList currentLangList = langList; + FilterLangList(¤tLangList, langName); + + if ( currentLangList.Num() == 0 ) { + // reset cvar to default and try to load again + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reset sys_lang" ); + langName = cvarSystem->GetCVarString( "sys_lang" ); + currentLangList = langList; + FilterLangList(¤tLangList, langName); + } + + for( int i = 0; i < currentLangList.Num(); i++ ) { + //common->Printf("%s\n", currentLangList[i].c_str()); + languageDict.Load( currentLangList[i], false ); + } + + fileSystem->FreeFileList(langFiles); + + Sys_InitScanTable(); +} + +/* +=============== +idCommonLocal::LocalizeSpecificMapData +=============== +*/ +void idCommonLocal::LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs ) { + idStr out, ws, work; + + idMapFile map; + if ( map.Parse( fileName, false, false ) ) { + int count = map.GetNumEntities(); + for ( int i = 0; i < count; i++ ) { + idMapEntity *ent = map.GetEntity( i ); + if ( ent ) { + for ( int j = 0; j < replaceArgs.GetNumKeyVals(); j++ ) { + const idLangKeyValue *kv = replaceArgs.GetKeyVal( j ); + const char *temp = ent->epairs.GetString( kv->key ); + if ( temp && *temp ) { + idStr val = kv->value; + if ( val == temp ) { + ent->epairs.Set( kv->key, langDict.AddString( temp ) ); + } + } + } + } + } + map.Write( fileName, ".map" ); + } +} + +/* +=============== +idCommonLocal::LocalizeMapData +=============== +*/ +void idCommonLocal::LocalizeMapData( const char *fileName, idLangDict &langDict ) { + const char *buffer = NULL; + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + common->SetRefreshOnPrint( true ); + + if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) { + src.LoadMemory( buffer, strlen(buffer), fileName ); + if ( src.IsLoaded() ) { + common->Printf( "Processing %s\n", fileName ); + idStr mapFileName; + idToken token, token2; + idLangDict replaceArgs; + while ( src.ReadToken( &token ) ) { + mapFileName = token; + replaceArgs.Clear(); + src.ExpectTokenString( "{" ); + while ( src.ReadToken( &token) ) { + if ( token == "}" ) { + break; + } + if ( src.ReadToken( &token2 ) ) { + if ( token2 == "}" ) { + break; + } + replaceArgs.AddKeyVal( token, token2 ); + } + } + common->Printf( " localizing map %s...\n", mapFileName.c_str() ); + LocalizeSpecificMapData( mapFileName, langDict, replaceArgs ); + } + } + fileSystem->FreeFile( (void*)buffer ); + } + + common->SetRefreshOnPrint( false ); +} + +/* +=============== +idCommonLocal::LocalizeGui +=============== +*/ +void idCommonLocal::LocalizeGui( const char *fileName, idLangDict &langDict ) { + idStr out, ws, work; + const char *buffer = NULL; + out.Empty(); + int k; + char ch; + char slash = '\\'; + char tab = 't'; + char nl = 'n'; + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) { + src.LoadMemory( buffer, strlen(buffer), fileName ); + if ( src.IsLoaded() ) { + idFile *outFile = fileSystem->OpenFileWrite( fileName ); + common->Printf( "Processing %s\n", fileName ); + session->UpdateScreen(); + idToken token; + while( src.ReadToken( &token ) ) { + src.GetLastWhiteSpace( ws ); + out += ws; + if ( token.type == TT_STRING ) { + out += va( "\"%s\"", token.c_str() ); + } else { + out += token; + } + if ( out.Length() > 200000 ) { + outFile->Write( out.c_str(), out.Length() ); + out = ""; + } + work = token.Right( 6 ); + if ( token.Icmp( "text" ) == 0 || work.Icmp( "::text" ) == 0 || token.Icmp( "choices" ) == 0 ) { + if ( src.ReadToken( &token ) ) { + // see if already exists, if so save that id to this position in this file + // otherwise add this to the list and save the id to this position in this file + src.GetLastWhiteSpace( ws ); + out += ws; + token = langDict.AddString( token ); + out += "\""; + for ( k = 0; k < token.Length(); k++ ) { + ch = token[k]; + if ( ch == '\t' ) { + out += slash; + out += tab; + } else if ( ch == '\n' || ch == '\r' ) { + out += slash; + out += nl; + } else { + out += ch; + } + } + out += "\""; + } + } else if ( token.Icmp( "comment" ) == 0 ) { + if ( src.ReadToken( &token ) ) { + // need to write these out by hand to preserve any \n's + // see if already exists, if so save that id to this position in this file + // otherwise add this to the list and save the id to this position in this file + src.GetLastWhiteSpace( ws ); + out += ws; + out += "\""; + for ( k = 0; k < token.Length(); k++ ) { + ch = token[k]; + if ( ch == '\t' ) { + out += slash; + out += tab; + } else if ( ch == '\n' || ch == '\r' ) { + out += slash; + out += nl; + } else { + out += ch; + } + } + out += "\""; + } + } + } + outFile->Write( out.c_str(), out.Length() ); + fileSystem->CloseFile( outFile ); + } + fileSystem->FreeFile( (void*)buffer ); + } +} + +/* +================= +ReloadLanguage_f +================= +*/ +void Com_ReloadLanguage_f( const idCmdArgs &args ) { + commonLocal.InitLanguageDict(); +} + +typedef idHashTable ListHash; +void LoadMapLocalizeData(ListHash& listHash) { + + idStr fileName = "map_localize.cfg"; + const char *buffer = NULL; + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) { + src.LoadMemory( buffer, strlen(buffer), fileName ); + if ( src.IsLoaded() ) { + idStr classname; + idToken token; + + + + while ( src.ReadToken( &token ) ) { + classname = token; + src.ExpectTokenString( "{" ); + + idStrList list; + while ( src.ReadToken( &token) ) { + if ( token == "}" ) { + break; + } + list.Append(token); + } + + listHash.Set(classname, list); + } + } + fileSystem->FreeFile( (void*)buffer ); + } + +} + +void LoadGuiParmExcludeList(idStrList& list) { + + idStr fileName = "guiparm_exclude.cfg"; + const char *buffer = NULL; + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) { + src.LoadMemory( buffer, strlen(buffer), fileName ); + if ( src.IsLoaded() ) { + idStr classname; + idToken token; + + + + while ( src.ReadToken( &token ) ) { + list.Append(token); + } + } + fileSystem->FreeFile( (void*)buffer ); + } +} + +bool TestMapVal(idStr& str) { + //Already Localized? + if(str.Find("#str_") != -1) { + return false; + } + + return true; +} + +bool TestGuiParm(const char* parm, const char* value, idStrList& excludeList) { + + idStr testVal = value; + + //Already Localized? + if(testVal.Find("#str_") != -1) { + return false; + } + + //Numeric + if(testVal.IsNumeric()) { + return false; + } + + //Contains :: + if(testVal.Find("::") != -1) { + return false; + } + + //Contains / + if(testVal.Find("/") != -1) { + return false; + } + + if(excludeList.Find(testVal)) { + return false; + } + + return true; +} + +void GetFileList(const char* dir, const char* ext, idStrList& list) { + + //Recurse Subdirectories + idStrList dirList; + Sys_ListFiles(dir, "/", dirList); + for(int i = 0; i < dirList.Num(); i++) { + if(dirList[i] == "." || dirList[i] == "..") { + continue; + } + idStr fullName = va("%s/%s", dir, dirList[i].c_str()); + GetFileList(fullName, ext, list); + } + + idStrList fileList; + Sys_ListFiles(dir, ext, fileList); + for(int i = 0; i < fileList.Num(); i++) { + idStr fullName = va("%s/%s", dir, fileList[i].c_str()); + list.Append(fullName); + } +} + +int LocalizeMap(const char* mapName, idLangDict &langDict, ListHash& listHash, idStrList& excludeList, bool writeFile) { + + common->Printf("Localizing Map '%s'\n", mapName); + + int strCount = 0; + + idMapFile map; + if ( map.Parse(mapName, false, false ) ) { + int count = map.GetNumEntities(); + for ( int j = 0; j < count; j++ ) { + idMapEntity *ent = map.GetEntity( j ); + if ( ent ) { + + idStr classname = ent->epairs.GetString("classname"); + + //Hack: for info_location + bool hasLocation = false; + + idStrList* list; + listHash.Get(classname, &list); + if(list) { + + for(int k = 0; k < list->Num(); k++) { + + idStr val = ent->epairs.GetString((*list)[k], ""); + + if(val.Length() && classname == "info_location" && (*list)[k] == "location") { + hasLocation = true; + } + + if(val.Length() && TestMapVal(val)) { + + if(!hasLocation || (*list)[k] == "location") { + //Localize it!!! + strCount++; + ent->epairs.Set( (*list)[k], langDict.AddString( val ) ); + } + } + } + } + + listHash.Get("all", &list); + if(list) { + for(int k = 0; k < list->Num(); k++) { + idStr val = ent->epairs.GetString((*list)[k], ""); + if(val.Length() && TestMapVal(val)) { + //Localize it!!! + strCount++; + ent->epairs.Set( (*list)[k], langDict.AddString( val ) ); + } + } + } + + //Localize the gui_parms + const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm"); + while( kv ) { + if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) { + //Localize It! + strCount++; + ent->epairs.Set( kv->GetKey(), langDict.AddString( kv->GetValue() ) ); + } + kv = ent->epairs.MatchPrefix( "gui_parm", kv ); + } + } + } + if(writeFile && strCount > 0) { + //Before we write the map file lets make a backup of the original + idStr file = fileSystem->RelativePathToOSPath(mapName); + idStr bak = file.Left(file.Length() - 4); + bak.Append(".bak_loc"); + fileSystem->CopyFile( file, bak ); + + map.Write( mapName, ".map" ); + } + } + + common->Printf("Count: %d\n", strCount); + return strCount; +} + +/* +================= +LocalizeMaps_f +================= +*/ +void Com_LocalizeMaps_f( const idCmdArgs &args ) { + if ( args.Argc() < 2 ) { + common->Printf( "Usage: localizeMaps \n" ); + return; + } + + int strCount = 0; + + bool count = false; + bool dictUpdate = false; + bool write = false; + + if ( idStr::Icmp( args.Argv(1), "count" ) == 0 ) { + count = true; + } else if ( idStr::Icmp( args.Argv(1), "dictupdate" ) == 0 ) { + count = true; + dictUpdate = true; + } else if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) { + count = true; + dictUpdate = true; + write = true; + } else { + common->Printf( "Invalid Command\n" ); + common->Printf( "Usage: localizeMaps \n" ); + return; + + } + + idLangDict strTable; + idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger()); + if(strTable.Load( filename ) == false) { + //This is a new file so set the base index + strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000); + } + + common->SetRefreshOnPrint( true ); + + ListHash listHash; + LoadMapLocalizeData(listHash); + + idStrList excludeList; + LoadGuiParmExcludeList(excludeList); + + if(args.Argc() == 3) { + strCount += LocalizeMap(args.Argv(2), strTable, listHash, excludeList, write); + } else { + idStrList files; + GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files); + for ( int i = 0; i < files.Num(); i++ ) { + idStr file = fileSystem->OSPathToRelativePath(files[i]); + strCount += LocalizeMap(file, strTable, listHash, excludeList, write); + } + } + + if(count) { + common->Printf("Localize String Count: %d\n", strCount); + } + + common->SetRefreshOnPrint( false ); + + if(dictUpdate) { + strTable.Save( filename ); + } +} + +/* +================= +LocalizeGuis_f +================= +*/ +void Com_LocalizeGuis_f( const idCmdArgs &args ) { + + if ( args.Argc() != 2 ) { + common->Printf( "Usage: localizeGuis \n" ); + return; + } + + idLangDict strTable; + + idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger()); + if(strTable.Load( filename ) == false) { + //This is a new file so set the base index + strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000); + } + + idFileList *files; + if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) { + idStr game = cvarSystem->GetCVarString( "fs_game" ); + if(game.Length()) { + files = fileSystem->ListFilesTree( "guis", "*.gui", true, game ); + } else { + files = fileSystem->ListFilesTree( "guis", "*.gui", true ); + } + for ( int i = 0; i < files->GetNumFiles(); i++ ) { + commonLocal.LocalizeGui( files->GetFile( i ), strTable ); + } + fileSystem->FreeFileList( files ); + + if(game.Length()) { + files = fileSystem->ListFilesTree( "guis", "*.pd", true, game ); + } else { + files = fileSystem->ListFilesTree( "guis", "*.pd", true, "d3xp" ); + } + + for ( int i = 0; i < files->GetNumFiles(); i++ ) { + commonLocal.LocalizeGui( files->GetFile( i ), strTable ); + } + fileSystem->FreeFileList( files ); + + } else { + commonLocal.LocalizeGui( args.Argv(1), strTable ); + } + strTable.Save( filename ); +} + +void Com_LocalizeGuiParmsTest_f( const idCmdArgs &args ) { + + common->SetRefreshOnPrint( true ); + + idFile *localizeFile = fileSystem->OpenFileWrite( "gui_parm_localize.csv" ); + idFile *noLocalizeFile = fileSystem->OpenFileWrite( "gui_parm_nolocalize.csv" ); + + idStrList excludeList; + LoadGuiParmExcludeList(excludeList); + + idStrList files; + GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files); + + for ( int i = 0; i < files.Num(); i++ ) { + + common->Printf("Testing Map '%s'\n", files[i].c_str()); + idMapFile map; + + idStr file = fileSystem->OSPathToRelativePath(files[i]); + if ( map.Parse(file, false, false ) ) { + int count = map.GetNumEntities(); + for ( int j = 0; j < count; j++ ) { + idMapEntity *ent = map.GetEntity( j ); + if ( ent ) { + const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm"); + while( kv ) { + if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) { + idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str()); + localizeFile->Write( out.c_str(), out.Length() ); + } else { + idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str()); + noLocalizeFile->Write( out.c_str(), out.Length() ); + } + kv = ent->epairs.MatchPrefix( "gui_parm", kv ); + } + } + } + } + } + + fileSystem->CloseFile( localizeFile ); + fileSystem->CloseFile( noLocalizeFile ); + + common->SetRefreshOnPrint( false ); +} + + +void Com_LocalizeMapsTest_f( const idCmdArgs &args ) { + + ListHash listHash; + LoadMapLocalizeData(listHash); + + + common->SetRefreshOnPrint( true ); + + idFile *localizeFile = fileSystem->OpenFileWrite( "map_localize.csv" ); + + idStrList files; + GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files); + + for ( int i = 0; i < files.Num(); i++ ) { + + common->Printf("Testing Map '%s'\n", files[i].c_str()); + idMapFile map; + + idStr file = fileSystem->OSPathToRelativePath(files[i]); + if ( map.Parse(file, false, false ) ) { + int count = map.GetNumEntities(); + for ( int j = 0; j < count; j++ ) { + idMapEntity *ent = map.GetEntity( j ); + if ( ent ) { + + //Temp code to get a list of all entity key value pairs + /*idStr classname = ent->epairs.GetString("classname"); + if(classname == "worldspawn" || classname == "func_static" || classname == "light" || classname == "speaker" || classname.Left(8) == "trigger_") { + continue; + } + for( int i = 0; i < ent->epairs.GetNumKeyVals(); i++) { + const idKeyValue* kv = ent->epairs.GetKeyVal(i); + idStr out = va("%s,%s,%s,%s\r\n", classname.c_str(), kv->GetKey().c_str(), kv->GetValue().c_str(), file.c_str()); + localizeFile->Write( out.c_str(), out.Length() ); + }*/ + + idStr classname = ent->epairs.GetString("classname"); + + //Hack: for info_location + bool hasLocation = false; + + idStrList* list; + listHash.Get(classname, &list); + if(list) { + + for(int k = 0; k < list->Num(); k++) { + + idStr val = ent->epairs.GetString((*list)[k], ""); + + if(classname == "info_location" && (*list)[k] == "location") { + hasLocation = true; + } + + if(val.Length() && TestMapVal(val)) { + + if(!hasLocation || (*list)[k] == "location") { + idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str()); + localizeFile->Write( out.c_str(), out.Length() ); + } + } + } + } + + listHash.Get("all", &list); + if(list) { + for(int k = 0; k < list->Num(); k++) { + idStr val = ent->epairs.GetString((*list)[k], ""); + if(val.Length() && TestMapVal(val)) { + idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str()); + localizeFile->Write( out.c_str(), out.Length() ); + } + } + } + } + } + } + } + + fileSystem->CloseFile( localizeFile ); + + common->SetRefreshOnPrint( false ); +} + +/* +================= +Com_StartBuild_f +================= +*/ +void Com_StartBuild_f( const idCmdArgs &args ) { + globalImages->StartBuild(); +} + +/* +================= +Com_FinishBuild_f +================= +*/ +void Com_FinishBuild_f( const idCmdArgs &args ) { + if ( game ) { + game->CacheDictionaryMedia( NULL ); + } + globalImages->FinishBuild( ( args.Argc() > 1 ) ); +} + +/* +============== +Com_Help_f +============== +*/ +void Com_Help_f( const idCmdArgs &args ) { + common->Printf( "\nCommonly used commands:\n" ); + common->Printf( " spawnServer - start the server.\n" ); + common->Printf( " disconnect - shut down the server.\n" ); + common->Printf( " listCmds - list all console commands.\n" ); + common->Printf( " listCVars - list all console variables.\n" ); + common->Printf( " kick - kick a client by number.\n" ); + common->Printf( " gameKick - kick a client by name.\n" ); + common->Printf( " serverNextMap - immediately load next map.\n" ); + common->Printf( " serverMapRestart - restart the current map.\n" ); + common->Printf( " serverForceReady - force all players to ready status.\n" ); + common->Printf( "\nCommonly used variables:\n" ); + common->Printf( " si_name - server name (change requires a restart to see)\n" ); + common->Printf( " si_gametype - type of game.\n" ); + common->Printf( " si_fragLimit - max kills to win (or lives in Last Man Standing).\n" ); + common->Printf( " si_timeLimit - maximum time a game will last.\n" ); + common->Printf( " si_warmup - do pre-game warmup.\n" ); + common->Printf( " si_pure - pure server.\n" ); + common->Printf( " g_mapCycle - name of .scriptcfg file for cycling maps.\n" ); + common->Printf( "See mapcycle.scriptcfg for an example of a mapcyle script.\n\n" ); +} + +/* +================= +idCommonLocal::InitCommands +================= +*/ +void idCommonLocal::InitCommands( void ) { + cmdSystem->AddCommand( "error", Com_Error_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes an error" ); + cmdSystem->AddCommand( "crash", Com_Crash_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes a crash" ); + cmdSystem->AddCommand( "freeze", Com_Freeze_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "freezes the game for a number of seconds" ); + cmdSystem->AddCommand( "quit", Com_Quit_f, CMD_FL_SYSTEM, "quits the game" ); + cmdSystem->AddCommand( "exit", Com_Quit_f, CMD_FL_SYSTEM, "exits the game" ); + cmdSystem->AddCommand( "writeConfig", Com_WriteConfig_f, CMD_FL_SYSTEM, "writes a config file" ); + cmdSystem->AddCommand( "reloadEngine", Com_ReloadEngine_f, CMD_FL_SYSTEM, "reloads the engine down to including the file system" ); + cmdSystem->AddCommand( "setMachineSpec", Com_SetMachineSpec_f, CMD_FL_SYSTEM, "detects system capabilities and sets com_machineSpec to appropriate value" ); + cmdSystem->AddCommand( "execMachineSpec", Com_ExecMachineSpec_f, CMD_FL_SYSTEM, "execs the appropriate config files and sets cvars based on com_machineSpec" ); + +#if !defined( ID_DEMO_BUILD ) && !defined( ID_DEDICATED ) + // compilers + cmdSystem->AddCommand( "dmap", Dmap_f, CMD_FL_TOOL, "compiles a map", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "renderbump", RenderBump_f, CMD_FL_TOOL, "renders a bump map", idCmdSystem::ArgCompletion_ModelName ); + cmdSystem->AddCommand( "renderbumpFlat", RenderBumpFlat_f, CMD_FL_TOOL, "renders a flat bump map", idCmdSystem::ArgCompletion_ModelName ); + cmdSystem->AddCommand( "runAAS", RunAAS_f, CMD_FL_TOOL, "compiles an AAS file for a map", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "runAASDir", RunAASDir_f, CMD_FL_TOOL, "compiles AAS files for all maps in a folder", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "runReach", RunReach_f, CMD_FL_TOOL, "calculates reachability for an AAS file", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "roq", RoQFileEncode_f, CMD_FL_TOOL, "encodes a roq file" ); +#endif + +#ifdef ID_ALLOW_TOOLS + // editors + cmdSystem->AddCommand( "editor", Com_Editor_f, CMD_FL_TOOL, "launches the level editor Radiant" ); + cmdSystem->AddCommand( "editLights", Com_EditLights_f, CMD_FL_TOOL, "launches the in-game Light Editor" ); + cmdSystem->AddCommand( "editSounds", Com_EditSounds_f, CMD_FL_TOOL, "launches the in-game Sound Editor" ); + cmdSystem->AddCommand( "editDecls", Com_EditDecls_f, CMD_FL_TOOL, "launches the in-game Declaration Editor" ); + cmdSystem->AddCommand( "editAFs", Com_EditAFs_f, CMD_FL_TOOL, "launches the in-game Articulated Figure Editor" ); + cmdSystem->AddCommand( "editParticles", Com_EditParticles_f, CMD_FL_TOOL, "launches the in-game Particle Editor" ); + cmdSystem->AddCommand( "editScripts", Com_EditScripts_f, CMD_FL_TOOL, "launches the in-game Script Editor" ); + cmdSystem->AddCommand( "editGUIs", Com_EditGUIs_f, CMD_FL_TOOL, "launches the GUI Editor" ); + cmdSystem->AddCommand( "editPDAs", Com_EditPDAs_f, CMD_FL_TOOL, "launches the in-game PDA Editor" ); + cmdSystem->AddCommand( "debugger", Com_ScriptDebugger_f, CMD_FL_TOOL, "launches the Script Debugger" ); + + //BSM Nerve: Add support for the material editor + cmdSystem->AddCommand( "materialEditor", Com_MaterialEditor_f, CMD_FL_TOOL, "launches the Material Editor" ); +#endif + + cmdSystem->AddCommand( "printMemInfo", PrintMemInfo_f, CMD_FL_SYSTEM, "prints memory debugging data" ); + + // idLib commands + cmdSystem->AddCommand( "memoryDump", Mem_Dump_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a memory dump" ); + cmdSystem->AddCommand( "memoryDumpCompressed", Mem_DumpCompressed_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a compressed memory dump" ); + cmdSystem->AddCommand( "showStringMemory", idStr::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by strings" ); + cmdSystem->AddCommand( "showDictMemory", idDict::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by dictionaries" ); + cmdSystem->AddCommand( "listDictKeys", idDict::ListKeys_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all keys used by dictionaries" ); + cmdSystem->AddCommand( "listDictValues", idDict::ListValues_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all values used by dictionaries" ); + cmdSystem->AddCommand( "testSIMD", idSIMD::Test_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "test SIMD code" ); + + // localization + cmdSystem->AddCommand( "localizeGuis", Com_LocalizeGuis_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize guis" ); + cmdSystem->AddCommand( "localizeMaps", Com_LocalizeMaps_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize maps" ); + cmdSystem->AddCommand( "reloadLanguage", Com_ReloadLanguage_f, CMD_FL_SYSTEM, "reload language dict" ); + + //D3XP Localization + cmdSystem->AddCommand( "localizeGuiParmsTest", Com_LocalizeGuiParmsTest_f, CMD_FL_SYSTEM, "Create test files that show gui parms localized and ignored." ); + cmdSystem->AddCommand( "localizeMapsTest", Com_LocalizeMapsTest_f, CMD_FL_SYSTEM, "Create test files that shows which strings will be localized." ); + + // build helpers + cmdSystem->AddCommand( "startBuild", Com_StartBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "prepares to make a build" ); + cmdSystem->AddCommand( "finishBuild", Com_FinishBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "finishes the build process" ); + +#ifdef ID_DEDICATED + cmdSystem->AddCommand( "help", Com_Help_f, CMD_FL_SYSTEM, "shows help" ); +#endif +} + +/* +================= +idCommonLocal::InitRenderSystem +================= +*/ +void idCommonLocal::InitRenderSystem( void ) { + if ( com_skipRenderer.GetBool() ) { + return; + } + + renderSystem->InitOpenGL(); + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04343" ) ); +} + +/* +================= +idCommonLocal::PrintLoadingMessage +================= +*/ +void idCommonLocal::PrintLoadingMessage( const char *msg ) { + if ( !( msg && *msg ) ) { + return; + } + renderSystem->BeginFrame( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight() ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "splashScreen" ) ); + int len = strlen( msg ); + renderSystem->DrawSmallStringExt( ( 640 - len * SMALLCHAR_WIDTH ) / 2, 410, msg, idVec4( 0.0f, 0.81f, 0.94f, 1.0f ), true, declManager->FindMaterial( "textures/bigchars" ) ); + renderSystem->EndFrame( NULL, NULL ); +} + +/* +================= +idCommonLocal::InitSIMD +================= +*/ +void idCommonLocal::InitSIMD( void ) { + idSIMD::InitProcessor( "doom", com_forceGenericSIMD.GetBool() ); + com_forceGenericSIMD.ClearModified(); +} + +/* +================= +idCommonLocal::Frame +================= +*/ +void idCommonLocal::Frame( void ) { + try { + + // pump all the events + Sys_GenerateEvents(); + + // write config file if anything changed + WriteConfiguration(); + + // change SIMD implementation if required + if ( com_forceGenericSIMD.IsModified() ) { + InitSIMD(); + } + + eventLoop->RunEventLoop(); + + com_frameTime = com_ticNumber * USERCMD_MSEC; + + idAsyncNetwork::RunFrame(); + + if ( idAsyncNetwork::IsActive() ) { + if ( idAsyncNetwork::serverDedicated.GetInteger() != 1 ) { + session->GuiFrameEvents(); + session->UpdateScreen( false ); + } + } else { + session->Frame(); + + // normal, in-sequence screen update + session->UpdateScreen( false ); + } + + // report timing information + if ( com_speeds.GetBool() ) { + static int lastTime; + int nowTime = Sys_Milliseconds(); + int com_frameMsec = nowTime - lastTime; + lastTime = nowTime; + Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend ); + time_gameFrame = 0; + time_gameDraw = 0; + } + + com_frameNumber++; + + // set idLib frame number for frame based memory dumps + idLib::frameNumber = com_frameNumber; + + // the FPU stack better be empty at this point or some bad code or compiler bug left values on the stack + if ( !Sys_FPU_StackIsEmpty() ) { + Printf( Sys_FPU_GetState() ); + FatalError( "idCommon::Frame: the FPU stack is not empty at the end of the frame\n" ); + } + } + + catch( idException & ) { + return; // an ERP_DROP was thrown + } +} + +/* +================= +idCommonLocal::GUIFrame +================= +*/ +void idCommonLocal::GUIFrame( bool execCmd, bool network ) { + Sys_GenerateEvents(); + eventLoop->RunEventLoop( execCmd ); // and execute any commands + com_frameTime = com_ticNumber * USERCMD_MSEC; + if ( network ) { + idAsyncNetwork::RunFrame(); + } + session->Frame(); + session->UpdateScreen( false ); +} + +/* +================= +idCommonLocal::SingleAsyncTic + +The system will asyncronously call this function 60 times a second to +handle the time-critical functions that we don't want limited to +the frame rate: + +sound mixing +user input generation (conditioned by com_asyncInput) +packet server operation +packet client operation + +We are not using thread safe libraries, so any functionality put here must +be VERY VERY careful about what it calls. +================= +*/ + +typedef struct { + int milliseconds; // should always be incremeting by 60hz + int deltaMsec; // should always be 16 + int timeConsumed; // msec spent in Com_AsyncThread() + int clientPacketsReceived; + int serverPacketsReceived; + int mostRecentServerPacketSequence; +} asyncStats_t; + +static const int MAX_ASYNC_STATS = 1024; +asyncStats_t com_asyncStats[MAX_ASYNC_STATS]; // indexed by com_ticNumber +int prevAsyncMsec; +int lastTicMsec; + +void idCommonLocal::SingleAsyncTic( void ) { + // main thread code can prevent this from happening while modifying + // critical data structures + Sys_EnterCriticalSection(); + + asyncStats_t *stat = &com_asyncStats[com_ticNumber & (MAX_ASYNC_STATS-1)]; + memset( stat, 0, sizeof( *stat ) ); + stat->milliseconds = Sys_Milliseconds(); + stat->deltaMsec = stat->milliseconds - com_asyncStats[(com_ticNumber - 1) & (MAX_ASYNC_STATS-1)].milliseconds; + + if ( usercmdGen && com_asyncInput.GetBool() ) { + usercmdGen->UsercmdInterrupt(); + } + + switch ( com_asyncSound.GetInteger() ) { + case 1: + soundSystem->AsyncUpdate( stat->milliseconds ); + break; + case 3: + soundSystem->AsyncUpdateWrite( stat->milliseconds ); + break; + } + + // we update com_ticNumber after all the background tasks + // have completed their work for this tic + com_ticNumber++; + + stat->timeConsumed = Sys_Milliseconds() - stat->milliseconds; + + Sys_LeaveCriticalSection(); +} + +/* +================= +idCommonLocal::Async +================= +*/ +void idCommonLocal::Async( void ) { + if ( com_shuttingDown ) { + return; + } + + int msec = Sys_Milliseconds(); + if ( !lastTicMsec ) { + lastTicMsec = msec - USERCMD_MSEC; + } + + if ( !com_preciseTic.GetBool() ) { + // just run a single tic, even if the exact msec isn't precise + SingleAsyncTic(); + return; + } + + int ticMsec = USERCMD_MSEC; + + // the number of msec per tic can be varies with the timescale cvar + float timescale = com_timescale.GetFloat(); + if ( timescale != 1.0f ) { + ticMsec /= timescale; + if ( ticMsec < 1 ) { + ticMsec = 1; + } + } + + // don't skip too many + if ( timescale == 1.0f ) { + if ( lastTicMsec + 10 * USERCMD_MSEC < msec ) { + lastTicMsec = msec - 10*USERCMD_MSEC; + } + } + + while ( lastTicMsec + ticMsec <= msec ) { + SingleAsyncTic(); + lastTicMsec += ticMsec; + } +} + +/* +================= +idCommonLocal::LoadGameDLL +================= +*/ +void idCommonLocal::LoadGameDLL( void ) { +#ifdef __DOOM_DLL__ + char dllPath[ MAX_OSPATH ]; + + gameImport_t gameImport; + gameExport_t gameExport; + GetGameAPI_t GetGameAPI; + + fileSystem->FindDLL( "game", dllPath, true ); + + if ( !dllPath[ 0 ] ) { + common->FatalError( "couldn't find game dynamic library" ); + return; + } + common->DPrintf( "Loading game DLL: '%s'\n", dllPath ); + gameDLL = sys->DLL_Load( dllPath ); + if ( !gameDLL ) { + common->FatalError( "couldn't load game dynamic library" ); + return; + } + + GetGameAPI = (GetGameAPI_t) Sys_DLL_GetProcAddress( gameDLL, "GetGameAPI" ); + if ( !GetGameAPI ) { + Sys_DLL_Unload( gameDLL ); + gameDLL = NULL; + common->FatalError( "couldn't find game DLL API" ); + return; + } + + gameImport.version = GAME_API_VERSION; + gameImport.sys = ::sys; + gameImport.common = ::common; + gameImport.cmdSystem = ::cmdSystem; + gameImport.cvarSystem = ::cvarSystem; + gameImport.fileSystem = ::fileSystem; + gameImport.networkSystem = ::networkSystem; + gameImport.renderSystem = ::renderSystem; + gameImport.soundSystem = ::soundSystem; + gameImport.renderModelManager = ::renderModelManager; + gameImport.uiManager = ::uiManager; + gameImport.declManager = ::declManager; + gameImport.AASFileManager = ::AASFileManager; + gameImport.collisionModelManager = ::collisionModelManager; + + gameExport = *GetGameAPI( &gameImport ); + + if ( gameExport.version != GAME_API_VERSION ) { + Sys_DLL_Unload( gameDLL ); + gameDLL = NULL; + common->FatalError( "wrong game DLL API version" ); + return; + } + + game = gameExport.game; + gameEdit = gameExport.gameEdit; + +#endif + + // initialize the game object + if ( game != NULL ) { + game->Init(); + } +} + +/* +================= +idCommonLocal::UnloadGameDLL +================= +*/ +void idCommonLocal::UnloadGameDLL( void ) { + + // shut down the game object + if ( game != NULL ) { + game->Shutdown(); + } + +#ifdef __DOOM_DLL__ + + if ( gameDLL ) { + Sys_DLL_Unload( gameDLL ); + gameDLL = NULL; + } + game = NULL; + gameEdit = NULL; + +#endif +} + +/* +================= +idCommonLocal::IsInitialized +================= +*/ +bool idCommonLocal::IsInitialized( void ) const { + return com_fullyInitialized; +} + +/* +================= +idCommonLocal::SetMachineSpec +================= +*/ +void idCommonLocal::SetMachineSpec( void ) { + cpuid_t cpu = Sys_GetProcessorId(); + double ghz = Sys_ClockTicksPerSecond() * 0.000000001f; + int vidRam = Sys_GetVideoRam(); + int sysRam = Sys_GetSystemRam(); + bool oldCard = false; + bool nv10or20 = false; + + renderSystem->GetCardCaps( oldCard, nv10or20 ); + + Printf( "Detected\n \t%.2f GHz CPU\n\t%i MB of System memory\n\t%i MB of Video memory on %s\n\n", ghz, sysRam, vidRam, ( oldCard ) ? "a less than optimal video architecture" : "an optimal video architecture" ); + + if ( ghz >= 2.75f && vidRam >= 512 && sysRam >= 1024 && !oldCard ) { + Printf( "This system qualifies for Ultra quality!\n" ); + com_machineSpec.SetInteger( 3 ); + } else if ( ghz >= ( ( cpu & CPUID_AMD ) ? 1.9f : 2.19f ) && vidRam >= 256 && sysRam >= 512 && !oldCard ) { + Printf( "This system qualifies for High quality!\n" ); + com_machineSpec.SetInteger( 2 ); + } else if ( ghz >= ( ( cpu & CPUID_AMD ) ? 1.1f : 1.25f ) && vidRam >= 128 && sysRam >= 384 ) { + Printf( "This system qualifies for Medium quality.\n" ); + com_machineSpec.SetInteger( 1 ); + } else { + Printf( "This system qualifies for Low quality.\n" ); + com_machineSpec.SetInteger( 0 ); + } + com_videoRam.SetInteger( vidRam ); +} + +/* +================= +idCommonLocal::Init +================= +*/ +void idCommonLocal::Init( int argc, const char **argv, const char *cmdline ) { + try { + + // set interface pointers used by idLib + idLib::sys = sys; + idLib::common = common; + idLib::cvarSystem = cvarSystem; + idLib::fileSystem = fileSystem; + + // initialize idLib + idLib::Init(); + + // clear warning buffer + ClearWarnings( GAME_NAME " initialization" ); + + // parse command line options + idCmdArgs args; + if ( cmdline ) { + // tokenize if the OS doesn't do it for us + args.TokenizeString( cmdline, true ); + argv = args.GetArgs( &argc ); + } + ParseCommandLine( argc, argv ); + + // init console command system + cmdSystem->Init(); + + // init CVar system + cvarSystem->Init(); + + // start file logging right away, before early console or whatever + StartupVariable( "win_outputDebugString", false ); + + // register all static CVars + idCVar::RegisterStaticVars(); + + // print engine version + Printf( "%s\n", version.string ); + + // initialize key input/binding, done early so bind command exists + idKeyInput::Init(); + + // init the console so we can take prints + console->Init(); + + // get architecture info + Sys_Init(); + + // initialize networking + Sys_InitNetworking(); + + // override cvars from command line + StartupVariable( NULL, false ); + + if ( !idAsyncNetwork::serverDedicated.GetInteger() && Sys_AlreadyRunning() ) { + Sys_Quit(); + } + + // initialize processor specific SIMD implementation + InitSIMD(); + + // init commands + InitCommands(); + +#ifdef ID_WRITE_VERSION + config_compressor = idCompressor::AllocArithmetic(); +#endif + + // game specific initialization + InitGame(); + + // don't add startup commands if no CD key is present +#if ID_ENFORCE_KEY + if ( !session->CDKeysAreValid( false ) || !AddStartupCommands() ) { +#else + if ( !AddStartupCommands() ) { +#endif + // if the user didn't give any commands, run default action + session->StartMenu( true ); + } + + Printf( "--- Common Initialization Complete ---\n" ); + + // print all warnings queued during initialization + PrintWarnings(); + +#ifdef ID_DEDICATED + Printf( "\nType 'help' for dedicated server info.\n\n" ); +#endif + + // remove any prints from the notify lines + console->ClearNotifyLines(); + + ClearCommandLine(); + + com_fullyInitialized = true; + } + + catch( idException & ) { + Sys_Error( "Error during initialization" ); + } +} + + +/* +================= +idCommonLocal::Shutdown +================= +*/ +void idCommonLocal::Shutdown( void ) { + + com_shuttingDown = true; + + idAsyncNetwork::server.Kill(); + idAsyncNetwork::client.Shutdown(); + + // game specific shut down + ShutdownGame( false ); + + // shut down non-portable system services + Sys_Shutdown(); + + // shut down the console + console->Shutdown(); + + // shut down the key system + idKeyInput::Shutdown(); + + // shut down the cvar system + cvarSystem->Shutdown(); + + // shut down the console command system + cmdSystem->Shutdown(); + +#ifdef ID_WRITE_VERSION + delete config_compressor; + config_compressor = NULL; +#endif + + // free any buffered warning messages + ClearWarnings( GAME_NAME " shutdown" ); + warningCaption.Clear(); + errorList.Clear(); + + // free language dictionary + languageDict.Clear(); + + // enable leak test + Mem_EnableLeakTest( "doom" ); + + // shutdown idLib + idLib::ShutDown(); +} + +/* +================= +idCommonLocal::InitGame +================= +*/ +void idCommonLocal::InitGame( void ) { + // initialize the file system + fileSystem->Init(); + + // initialize the declaration manager + declManager->Init(); + + // force r_fullscreen 0 if running a tool + CheckToolMode(); + + idFile *file = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( CONFIG_SPEC, "fs_savepath" ) ); + bool sysDetect = ( file == NULL ); + if ( file ) { + fileSystem->CloseFile( file ); + } else { + file = fileSystem->OpenFileWrite( CONFIG_SPEC ); + fileSystem->CloseFile( file ); + } + + idCmdArgs args; + if ( sysDetect ) { + SetMachineSpec(); + Com_ExecMachineSpec_f( args ); + } + + // initialize the renderSystem data structures, but don't start OpenGL yet + renderSystem->Init(); + + // initialize string database right off so we can use it for loading messages + InitLanguageDict(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04344" ) ); + + // load the font, etc + console->LoadGraphics(); + + // init journalling, etc + eventLoop->Init(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04345" ) ); + + // exec the startup scripts + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec editor.cfg\n" ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec default.cfg\n" ); + + // skip the config file if "safe" is on the command line + if ( !SafeMode() ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec " CONFIG_FILE "\n" ); + } + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec autoexec.cfg\n" ); + + // reload the language dictionary now that we've loaded config files + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reloadLanguage\n" ); + + // run cfg execution + cmdSystem->ExecuteCommandBuffer(); + + // re-override anything from the config files with command line args + StartupVariable( NULL, false ); + + // if any archived cvars are modified after this, we will trigger a writing of the config file + cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE ); + + // cvars are initialized, but not the rendering system. Allow preference startup dialog + Sys_DoPreferences(); + + // init the user command input code + usercmdGen->Init(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04346" ) ); + + // start the sound system, but don't do any hardware operations yet + soundSystem->Init(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04347" ) ); + + // init async network + idAsyncNetwork::Init(); + +#ifdef ID_DEDICATED + idAsyncNetwork::server.InitPort(); + cvarSystem->SetCVarBool( "s_noSound", true ); +#else + if ( idAsyncNetwork::serverDedicated.GetInteger() == 1 ) { + idAsyncNetwork::server.InitPort(); + cvarSystem->SetCVarBool( "s_noSound", true ); + } else { + // init OpenGL, which will open a window and connect sound and input hardware + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04348" ) ); + InitRenderSystem(); + } +#endif + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04349" ) ); + + // initialize the user interfaces + uiManager->Init(); + + // startup the script debugger + // DebuggerServerInit(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04350" ) ); + + // load the game dll + LoadGameDLL(); + + PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04351" ) ); + + // init the session + session->Init(); + + // have to do this twice.. first one sets the correct r_mode for the renderer init + // this time around the backend is all setup correct.. a bit fugly but do not want + // to mess with all the gl init at this point.. an old vid card will never qualify for + if ( sysDetect ) { + SetMachineSpec(); + Com_ExecMachineSpec_f( args ); + cvarSystem->SetCVarInteger( "s_numberOfSpeakers", 6 ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" ); + cmdSystem->ExecuteCommandBuffer(); + } +} + +/* +================= +idCommonLocal::ShutdownGame +================= +*/ +void idCommonLocal::ShutdownGame( bool reloading ) { + + // kill sound first + idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); + if ( sw ) { + sw->StopAllSounds(); + } + soundSystem->ClearBuffer(); + + // shutdown the script debugger + // DebuggerServerShutdown(); + + idAsyncNetwork::client.Shutdown(); + + // shut down the session + session->Shutdown(); + + // shut down the user interfaces + uiManager->Shutdown(); + + // shut down the sound system + soundSystem->Shutdown(); + + // shut down async networking + idAsyncNetwork::Shutdown(); + + // shut down the user command input code + usercmdGen->Shutdown(); + + // shut down the event loop + eventLoop->Shutdown(); + + // shut down the renderSystem + renderSystem->Shutdown(); + + // shutdown the decl manager + declManager->Shutdown(); + + // unload the game dll + UnloadGameDLL(); + + // dump warnings to "warnings.txt" +#ifdef DEBUG + DumpWarnings(); +#endif + // only shut down the log file after all output is done + CloseLogFile(); + + // shut down the file system + fileSystem->Shutdown( reloading ); +} diff --git a/framework/Common.h b/framework/Common.h new file mode 100644 index 000000000..f167fb441 --- /dev/null +++ b/framework/Common.h @@ -0,0 +1,206 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +/* +============================================================== + + Common + +============================================================== +*/ + +typedef enum { + EDITOR_NONE = 0, + EDITOR_RADIANT = BIT(1), + EDITOR_GUI = BIT(2), + EDITOR_DEBUGGER = BIT(3), + EDITOR_SCRIPT = BIT(4), + EDITOR_LIGHT = BIT(5), + EDITOR_SOUND = BIT(6), + EDITOR_DECL = BIT(7), + EDITOR_AF = BIT(8), + EDITOR_PARTICLE = BIT(9), + EDITOR_PDA = BIT(10), + EDITOR_AAS = BIT(11), + EDITOR_MATERIAL = BIT(12) +} toolFlag_t; + +#define STRTABLE_ID "#str_" +#define STRTABLE_ID_LENGTH 5 + +extern idCVar com_version; +extern idCVar com_skipRenderer; +extern idCVar com_asyncInput; +extern idCVar com_asyncSound; +extern idCVar com_machineSpec; +extern idCVar com_purgeAll; +extern idCVar com_developer; +extern idCVar com_allowConsole; +extern idCVar com_speeds; +extern idCVar com_showFPS; +extern idCVar com_showMemoryUsage; +extern idCVar com_showAsyncStats; +extern idCVar com_showSoundDecoders; +extern idCVar com_makingBuild; +extern idCVar com_updateLoadSize; +extern idCVar com_videoRam; + +extern int time_gameFrame; // game logic time +extern int time_gameDraw; // game present time +extern int time_frontend; // renderer frontend time +extern int time_backend; // renderer backend time + +extern int com_frameTime; // time for the current frame in milliseconds +extern volatile int com_ticNumber; // 60 hz tics, incremented by async function +extern int com_editors; // current active editor(s) +extern bool com_editorActive; // true if an editor has focus + +#ifdef _WIN32 +const char DMAP_MSGID[] = "DMAPOutput"; +const char DMAP_DONE[] = "DMAPDone"; +extern HWND com_hwndMsg; +extern bool com_outputMsg; +#endif + +struct MemInfo_t { + idStr filebase; + + int total; + int assetTotals; + + // memory manager totals + int memoryManagerTotal; + + // subsystem totals + int gameSubsystemTotal; + int renderSubsystemTotal; + + // asset totals + int imageAssetsTotal; + int modelAssetsTotal; + int soundAssetsTotal; +}; + +class idCommon { +public: + virtual ~idCommon( void ) {} + + // Initialize everything. + // if the OS allows, pass argc/argv directly (without executable name) + // otherwise pass the command line in a single string (without executable name) + virtual void Init( int argc, const char **argv, const char *cmdline ) = 0; + + // Shuts down everything. + virtual void Shutdown( void ) = 0; + + // Shuts down everything. + virtual void Quit( void ) = 0; + + // Returns true if common initialization is complete. + virtual bool IsInitialized( void ) const = 0; + + // Called repeatedly as the foreground thread for rendering and game logic. + virtual void Frame( void ) = 0; + + // Called repeatedly by blocking function calls with GUI interactivity. + virtual void GUIFrame( bool execCmd, bool network ) = 0; + + // Called 60 times a second from a background thread for sound mixing, + // and input generation. Not called until idCommon::Init() has completed. + virtual void Async( void ) = 0; + + // Checks for and removes command line "+set var arg" constructs. + // If match is NULL, all set commands will be executed, otherwise + // only a set with the exact name. Only used during startup. + // set once to clear the cvar from +set for early init code + virtual void StartupVariable( const char *match, bool once ) = 0; + + // Initializes a tool with the given dictionary. + virtual void InitTool( const toolFlag_t tool, const idDict *dict ) = 0; + + // Activates or deactivates a tool. + virtual void ActivateTool( bool active ) = 0; + + // Writes the user's configuration to a file + virtual void WriteConfigToFile( const char *filename ) = 0; + + // Writes cvars with the given flags to a file. + virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) = 0; + + // Begins redirection of console output to the given buffer. + virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ) = 0; + + // Stops redirection of console output. + virtual void EndRedirect( void ) = 0; + + // Update the screen with every message printed. + virtual void SetRefreshOnPrint( bool set ) = 0; + + // Prints message to the console, which may cause a screen update if com_refreshOnPrint is set. + virtual void Printf( const char *fmt, ... )id_attribute((format(printf,2,3))) = 0; + + // Same as Printf, with a more usable API - Printf pipes to this. + virtual void VPrintf( const char *fmt, va_list arg ) = 0; + + // Prints message that only shows up if the "developer" cvar is set, + // and NEVER forces a screen update, which could cause reentrancy problems. + virtual void DPrintf( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + + // Prints WARNING %s message and adds the warning message to a queue for printing later on. + virtual void Warning( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + + // Prints WARNING %s message in yellow that only shows up if the "developer" cvar is set. + virtual void DWarning( const char *fmt, ...) id_attribute((format(printf,2,3))) = 0; + + // Prints all queued warnings. + virtual void PrintWarnings( void ) = 0; + + // Removes all queued warnings. + virtual void ClearWarnings( const char *reason ) = 0; + + // Issues a C++ throw. Normal errors just abort to the game loop, + // which is appropriate for media or dynamic logic errors. + virtual void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + + // Fatal errors quit all the way to a system dialog box, which is appropriate for + // static internal errors or cases where the system may be corrupted. + virtual void FatalError( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + + // Returns a pointer to the dictionary with language specific strings. + virtual const idLangDict * GetLanguageDict( void ) = 0; + + // Returns key bound to the command + virtual const char * KeysFromBinding( const char *bind ) = 0; + + // Returns the binding bound to the key + virtual const char * BindingFromKey( const char *key ) = 0; + + // Directly sample a button. + virtual int ButtonState( int key ) = 0; + + // Directly sample a keystate. + virtual int KeyState( int key ) = 0; +}; + +extern idCommon * common; + +#endif /* !__COMMON_H__ */ diff --git a/framework/Compressor.cpp b/framework/Compressor.cpp new file mode 100644 index 000000000..94aad4d68 --- /dev/null +++ b/framework/Compressor.cpp @@ -0,0 +1,2567 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + + +/* +================================================================================= + + idCompressor_None + +================================================================================= +*/ + +class idCompressor_None : public idCompressor { +public: + idCompressor_None( void ); + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + float GetCompressionRatio( void ) const; + + const char * GetName( void ); + const char * GetFullPath( void ); + int Read( void *outData, int outLength ); + int Write( const void *inData, int inLength ); + int Length( void ); + ID_TIME_T Timestamp( void ); + int Tell( void ); + void ForceFlush( void ); + void Flush( void ); + int Seek( long offset, fsOrigin_t origin ); + +protected: + idFile * file; + bool compress; +}; + +/* +================ +idCompressor_None::idCompressor_None +================ +*/ +idCompressor_None::idCompressor_None( void ) { + file = NULL; + compress = true; +} + +/* +================ +idCompressor_None::Init +================ +*/ +void idCompressor_None::Init( idFile *f, bool compress, int wordLength ) { + this->file = f; + this->compress = compress; +} + +/* +================ +idCompressor_None::FinishCompress +================ +*/ +void idCompressor_None::FinishCompress( void ) { +} + +/* +================ +idCompressor_None::GetCompressionRatio +================ +*/ +float idCompressor_None::GetCompressionRatio( void ) const { + return 0.0f; +} + +/* +================ +idCompressor_None::GetName +================ +*/ +const char *idCompressor_None::GetName( void ) { + if ( file ) { + return file->GetName(); + } else { + return ""; + } +} + +/* +================ +idCompressor_None::GetFullPath +================ +*/ +const char *idCompressor_None::GetFullPath( void ) { + if ( file ) { + return file->GetFullPath(); + } else { + return ""; + } +} + +/* +================ +idCompressor_None::Write +================ +*/ +int idCompressor_None::Write( const void *inData, int inLength ) { + if ( compress == false || inLength <= 0 ) { + return 0; + } + return file->Write( inData, inLength ); +} + +/* +================ +idCompressor_None::Read +================ +*/ +int idCompressor_None::Read( void *outData, int outLength ) { + if ( compress == true || outLength <= 0 ) { + return 0; + } + return file->Read( outData, outLength ); +} + +/* +================ +idCompressor_None::Length +================ +*/ +int idCompressor_None::Length( void ) { + if ( file ) { + return file->Length(); + } else { + return 0; + } +} + +/* +================ +idCompressor_None::Timestamp +================ +*/ +ID_TIME_T idCompressor_None::Timestamp( void ) { + if ( file ) { + return file->Timestamp(); + } else { + return 0; + } +} + +/* +================ +idCompressor_None::Tell +================ +*/ +int idCompressor_None::Tell( void ) { + if ( file ) { + return file->Tell(); + } else { + return 0; + } +} + +/* +================ +idCompressor_None::ForceFlush +================ +*/ +void idCompressor_None::ForceFlush( void ) { + if ( file ) { + file->ForceFlush(); + } +} + +/* +================ +idCompressor_None::Flush +================ +*/ +void idCompressor_None::Flush( void ) { + if ( file ) { + file->ForceFlush(); + } +} + +/* +================ +idCompressor_None::Seek +================ +*/ +int idCompressor_None::Seek( long offset, fsOrigin_t origin ) { + common->Error( "cannot seek on idCompressor" ); + return -1; +} + + +/* +================================================================================= + + idCompressor_BitStream + + Base class for bit stream compression. + +================================================================================= +*/ + +class idCompressor_BitStream : public idCompressor_None { +public: + idCompressor_BitStream( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + float GetCompressionRatio( void ) const; + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +protected: + byte buffer[65536]; + int wordLength; + + int readTotalBytes; + int readLength; + int readByte; + int readBit; + const byte * readData; + + int writeTotalBytes; + int writeLength; + int writeByte; + int writeBit; + byte * writeData; + +protected: + void InitCompress( const void *inData, const int inLength ); + void InitDecompress( void *outData, int outLength ); + void WriteBits( int value, int numBits ); + int ReadBits( int numBits ); + void UnreadBits( int numBits ); + int Compare( const byte *src1, int bitPtr1, const byte *src2, int bitPtr2, int maxBits ) const; +}; + +/* +================ +idCompressor_BitStream::Init +================ +*/ +void idCompressor_BitStream::Init( idFile *f, bool compress, int wordLength ) { + + assert( wordLength >= 1 && wordLength <= 32 ); + + this->file = f; + this->compress = compress; + this->wordLength = wordLength; + + readTotalBytes = 0; + readLength = 0; + readByte = 0; + readBit = 0; + readData = NULL; + + writeTotalBytes = 0; + writeLength = 0; + writeByte = 0; + writeBit = 0; + writeData = NULL; +} + +/* +================ +idCompressor_BitStream::InitCompress +================ +*/ +ID_INLINE void idCompressor_BitStream::InitCompress( const void *inData, const int inLength ) { + + readLength = inLength; + readByte = 0; + readBit = 0; + readData = (const byte *) inData; + + if ( !writeLength ) { + writeLength = sizeof( buffer ); + writeByte = 0; + writeBit = 0; + writeData = buffer; + } +} + +/* +================ +idCompressor_BitStream::InitDecompress +================ +*/ +ID_INLINE void idCompressor_BitStream::InitDecompress( void *outData, int outLength ) { + + if ( !readLength ) { + readLength = file->Read( buffer, sizeof( buffer ) ); + readByte = 0; + readBit = 0; + readData = buffer; + } + + writeLength = outLength; + writeByte = 0; + writeBit = 0; + writeData = (byte *) outData; +} + +/* +================ +idCompressor_BitStream::WriteBits +================ +*/ +void idCompressor_BitStream::WriteBits( int value, int numBits ) { + int put, fraction; + + // Short circuit for writing single bytes at a time + if ( writeBit == 0 && numBits == 8 && writeByte < writeLength ) { + writeByte++; + writeTotalBytes++; + writeData[writeByte - 1] = value; + return; + } + + + while( numBits ) { + if ( writeBit == 0 ) { + if ( writeByte >= writeLength ) { + if ( writeData == buffer ) { + file->Write( buffer, writeByte ); + writeByte = 0; + } else { + put = numBits; + writeBit = put & 7; + writeByte += ( put >> 3 ) + ( writeBit != 0 ); + writeTotalBytes += ( put >> 3 ) + ( writeBit != 0 ); + return; + } + } + writeData[writeByte] = 0; + writeByte++; + writeTotalBytes++; + } + put = 8 - writeBit; + if ( put > numBits ) { + put = numBits; + } + fraction = value & ( ( 1 << put ) - 1 ); + writeData[writeByte - 1] |= fraction << writeBit; + numBits -= put; + value >>= put; + writeBit = ( writeBit + put ) & 7; + } +} + +/* +================ +idCompressor_BitStream::ReadBits +================ +*/ +int idCompressor_BitStream::ReadBits( int numBits ) { + int value, valueBits, get, fraction; + + value = 0; + valueBits = 0; + + // Short circuit for reading single bytes at a time + if ( readBit == 0 && numBits == 8 && readByte < readLength ) { + readByte++; + readTotalBytes++; + return readData[readByte - 1]; + } + + while ( valueBits < numBits ) { + if ( readBit == 0 ) { + if ( readByte >= readLength ) { + if ( readData == buffer ) { + readLength = file->Read( buffer, sizeof( buffer ) ); + readByte = 0; + } else { + get = numBits - valueBits; + readBit = get & 7; + readByte += ( get >> 3 ) + ( readBit != 0 ); + readTotalBytes += ( get >> 3 ) + ( readBit != 0 ); + return value; + } + } + readByte++; + readTotalBytes++; + } + get = 8 - readBit; + if ( get > (numBits - valueBits) ) { + get = (numBits - valueBits); + } + fraction = readData[readByte - 1]; + fraction >>= readBit; + fraction &= ( 1 << get ) - 1; + value |= fraction << valueBits; + valueBits += get; + readBit = ( readBit + get ) & 7; + } + + return value; +} + +/* +================ +idCompressor_BitStream::UnreadBits +================ +*/ +void idCompressor_BitStream::UnreadBits( int numBits ) { + readByte -= ( numBits >> 3 ); + readTotalBytes -= ( numBits >> 3 ); + if ( readBit == 0 ) { + readBit = 8 - ( numBits & 7 ); + } else { + readBit -= numBits & 7; + if ( readBit <= 0 ) { + readByte--; + readTotalBytes--; + readBit = ( readBit + 8 ) & 7; + } + } + if ( readByte < 0 ) { + readByte = 0; + readBit = 0; + } +} + +/* +================ +idCompressor_BitStream::Compare +================ +*/ +int idCompressor_BitStream::Compare( const byte *src1, int bitPtr1, const byte *src2, int bitPtr2, int maxBits ) const { + int i; + + // If the two bit pointers are aligned then we can use a faster comparison + if ( ( bitPtr1 & 7 ) == (bitPtr2 & 7 ) && maxBits > 16 ) { + const byte *p1 = &src1[bitPtr1 >> 3]; + const byte *p2 = &src2[bitPtr2 >> 3]; + + int bits = 0; + + int bitsRemain = maxBits; + + // Compare the first couple bits (if any) + if ( bitPtr1 & 7 ) { + for ( i = (bitPtr1 & 7); i < 8; i++, bits++ ) { + if ( ( ( *p1 >> i ) ^ ( *p2 >> i ) ) & 1 ) { + return bits; + } + bitsRemain--; + } + p1++; + p2++; + } + + int remain = bitsRemain >> 3; + + // Compare the middle bytes as ints + while ( remain >= 4 && (*(const int *)p1 == *(const int *)p2) ) { + p1 += 4; + p2 += 4; + remain -= 4; + bits += 32; + } + + // Compare the remaining bytes + while ( remain > 0 && (*p1 == *p2) ) { + p1++; + p2++; + remain--; + bits += 8; + } + + // Compare the last couple of bits (if any) + int finalBits = 8; + if ( remain == 0 ) { + finalBits = ( bitsRemain & 7 ); + } + for ( i = 0; i < finalBits; i++, bits++ ) { + if ( ( ( *p1 >> i ) ^ ( *p2 >> i ) ) & 1 ) { + return bits; + } + } + + assert(bits == maxBits); + return bits; + } else { + for ( i = 0; i < maxBits; i++ ) { + if ( ( ( src1[bitPtr1 >> 3] >> ( bitPtr1 & 7 ) ) ^ ( src2[bitPtr2 >> 3] >> ( bitPtr2 & 7 ) ) ) & 1 ) { + break; + } + bitPtr1++; + bitPtr2++; + } + return i; +} +} + +/* +================ +idCompressor_BitStream::Write +================ +*/ +int idCompressor_BitStream::Write( const void *inData, int inLength ) { + int i; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + InitCompress( inData, inLength ); + + for ( i = 0; i < inLength; i++ ) { + WriteBits( ReadBits( 8 ), 8 ); + } + return i; +} + +/* +================ +idCompressor_BitStream::FinishCompress +================ +*/ +void idCompressor_BitStream::FinishCompress( void ) { + if ( compress == false ) { + return; + } + + if ( writeByte ) { + file->Write( buffer, writeByte ); + } + writeLength = 0; + writeByte = 0; + writeBit = 0; +} + +/* +================ +idCompressor_BitStream::Read +================ +*/ +int idCompressor_BitStream::Read( void *outData, int outLength ) { + int i; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + InitDecompress( outData, outLength ); + + for ( i = 0; i < outLength && readLength >= 0; i++ ) { + WriteBits( ReadBits( 8 ), 8 ); + } + return i; +} + +/* +================ +idCompressor_BitStream::GetCompressionRatio +================ +*/ +float idCompressor_BitStream::GetCompressionRatio( void ) const { + if ( compress ) { + return ( readTotalBytes - writeTotalBytes ) * 100.0f / readTotalBytes; + } else { + return ( writeTotalBytes - readTotalBytes ) * 100.0f / writeTotalBytes; + } +} + + +/* +================================================================================= + + idCompressor_RunLength + + The following algorithm implements run length compression with an arbitrary + word size. + +================================================================================= +*/ + +class idCompressor_RunLength : public idCompressor_BitStream { +public: + idCompressor_RunLength( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +private: + int runLengthCode; +}; + +/* +================ +idCompressor_RunLength::Init +================ +*/ +void idCompressor_RunLength::Init( idFile *f, bool compress, int wordLength ) { + idCompressor_BitStream::Init( f, compress, wordLength ); + runLengthCode = ( 1 << wordLength ) - 1; +} + +/* +================ +idCompressor_RunLength::Write +================ +*/ +int idCompressor_RunLength::Write( const void *inData, int inLength ) { + int bits, nextBits, count; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + InitCompress( inData, inLength ); + + while( readByte <= readLength ) { + count = 1; + bits = ReadBits( wordLength ); + for ( nextBits = ReadBits( wordLength ); nextBits == bits; nextBits = ReadBits( wordLength ) ) { + count++; + if ( count >= ( 1 << wordLength ) ) { + if ( count >= ( 1 << wordLength ) + 3 || bits == runLengthCode ) { + break; + } + } + } + if ( nextBits != bits ) { + UnreadBits( wordLength ); + } + if ( count > 3 || bits == runLengthCode ) { + WriteBits( runLengthCode, wordLength ); + WriteBits( bits, wordLength ); + if ( bits != runLengthCode ) { + count -= 3; + } + WriteBits( count - 1, wordLength ); + } else { + while( count-- ) { + WriteBits( bits, wordLength ); + } + } + } + + return inLength; +} + +/* +================ +idCompressor_RunLength::Read +================ +*/ +int idCompressor_RunLength::Read( void *outData, int outLength ) { + int bits, count; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + InitDecompress( outData, outLength ); + + while( writeByte <= writeLength && readLength >= 0 ) { + bits = ReadBits( wordLength ); + if ( bits == runLengthCode ) { + bits = ReadBits( wordLength ); + count = ReadBits( wordLength ) + 1; + if ( bits != runLengthCode ) { + count += 3; + } + while( count-- ) { + WriteBits( bits, wordLength ); + } + } else { + WriteBits( bits, wordLength ); + } + } + + return writeByte; +} + + +/* +================================================================================= + + idCompressor_RunLength_ZeroBased + + The following algorithm implements run length compression with an arbitrary + word size for data with a lot of zero bits. + +================================================================================= +*/ + +class idCompressor_RunLength_ZeroBased : public idCompressor_BitStream { +public: + idCompressor_RunLength_ZeroBased( void ) {} + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +private: +}; + +/* +================ +idCompressor_RunLength_ZeroBased::Write +================ +*/ +int idCompressor_RunLength_ZeroBased::Write( const void *inData, int inLength ) { + int bits, count; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + InitCompress( inData, inLength ); + + while( readByte <= readLength ) { + count = 0; + for ( bits = ReadBits( wordLength ); bits == 0 && count < ( 1 << wordLength ); bits = ReadBits( wordLength ) ) { + count++; + } + if ( count ) { + WriteBits( 0, wordLength ); + WriteBits( count - 1, wordLength ); + UnreadBits( wordLength ); + } else { + WriteBits( bits, wordLength ); + } + } + + return inLength; +} + +/* +================ +idCompressor_RunLength_ZeroBased::Read +================ +*/ +int idCompressor_RunLength_ZeroBased::Read( void *outData, int outLength ) { + int bits, count; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + InitDecompress( outData, outLength ); + + while( writeByte <= writeLength && readLength >= 0 ) { + bits = ReadBits( wordLength ); + if ( bits == 0 ) { + count = ReadBits( wordLength ) + 1; + while( count-- > 0 ) { + WriteBits( 0, wordLength ); + } + } else { + WriteBits( bits, wordLength ); + } + } + + return writeByte; +} + + +/* +================================================================================= + + idCompressor_Huffman + + The following algorithm is based on the adaptive Huffman algorithm described + in Sayood's Data Compression book. The ranks are not actually stored, but + implicitly defined by the location of a node within a doubly-linked list + +================================================================================= +*/ + +const int HMAX = 256; // Maximum symbol +const int NYT = HMAX; // NYT = Not Yet Transmitted +const int INTERNAL_NODE = HMAX + 1; // internal node + +typedef struct nodetype { + struct nodetype *left, *right, *parent; // tree structure + struct nodetype *next, *prev; // doubly-linked list + struct nodetype **head; // highest ranked node in block + int weight; + int symbol; +} huffmanNode_t; + +class idCompressor_Huffman : public idCompressor_None { +public: + idCompressor_Huffman( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + float GetCompressionRatio( void ) const; + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +private: + byte seq[65536]; + int bloc; + int blocMax; + int blocIn; + int blocNode; + int blocPtrs; + + int compressedSize; + int unCompressedSize; + + huffmanNode_t * tree; + huffmanNode_t * lhead; + huffmanNode_t * ltail; + huffmanNode_t * loc[HMAX+1]; + huffmanNode_t **freelist; + + huffmanNode_t nodeList[768]; + huffmanNode_t * nodePtrs[768]; + +private: + void AddRef( byte ch ); + int Receive( huffmanNode_t *node, int *ch ); + void Transmit( int ch, byte *fout ); + void PutBit( int bit, byte *fout, int *offset ); + int GetBit( byte *fout, int *offset ); + + void Add_bit( char bit, byte *fout ); + int Get_bit(); + huffmanNode_t **Get_ppnode(); + void Free_ppnode( huffmanNode_t **ppnode ); + void Swap( huffmanNode_t *node1, huffmanNode_t *node2 ); + void Swaplist( huffmanNode_t *node1, huffmanNode_t *node2 ); + void Increment( huffmanNode_t *node ); + void Send( huffmanNode_t *node, huffmanNode_t *child, byte *fout ); +}; + +/* +================ +idCompressor_Huffman::Init +================ +*/ +void idCompressor_Huffman::Init( idFile *f, bool compress, int wordLength ) { + int i; + + this->file = f; + this->compress = compress; + bloc = 0; + blocMax = 0; + blocIn = 0; + blocNode = 0; + blocPtrs = 0; + compressedSize = 0; + unCompressedSize = 0; + + tree = NULL; + lhead = NULL; + ltail = NULL; + for( i = 0; i < (HMAX+1); i++ ) { + loc[i] = NULL; + } + freelist = NULL; + + for( i = 0; i < 768; i++ ) { + memset( &nodeList[i], 0, sizeof(huffmanNode_t) ); + nodePtrs[i] = NULL; + } + + if ( compress ) { + // Add the NYT (not yet transmitted) node into the tree/list + tree = lhead = loc[NYT] = &nodeList[blocNode++]; + tree->symbol = NYT; + tree->weight = 0; + lhead->next = lhead->prev = NULL; + tree->parent = tree->left = tree->right = NULL; + loc[NYT] = tree; + } else { + // Initialize the tree & list with the NYT node + tree = lhead = ltail = loc[NYT] = &nodeList[blocNode++]; + tree->symbol = NYT; + tree->weight = 0; + lhead->next = lhead->prev = NULL; + tree->parent = tree->left = tree->right = NULL; + } +} + +/* +================ +idCompressor_Huffman::PutBit +================ +*/ +void idCompressor_Huffman::PutBit( int bit, byte *fout, int *offset) { + bloc = *offset; + if ( (bloc&7) == 0 ) { + fout[(bloc>>3)] = 0; + } + fout[(bloc>>3)] |= bit << (bloc&7); + bloc++; + *offset = bloc; +} + +/* +================ +idCompressor_Huffman::GetBit +================ +*/ +int idCompressor_Huffman::GetBit( byte *fin, int *offset) { + int t; + bloc = *offset; + t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1; + bloc++; + *offset = bloc; + return t; +} + +/* +================ +idCompressor_Huffman::Add_bit + + Add a bit to the output file (buffered) +================ +*/ +void idCompressor_Huffman::Add_bit( char bit, byte *fout ) { + if ( (bloc&7) == 0 ) { + fout[(bloc>>3)] = 0; + } + fout[(bloc>>3)] |= bit << (bloc&7); + bloc++; +} + +/* +================ +idCompressor_Huffman::Get_bit + + Get one bit from the input file (buffered) +================ +*/ +int idCompressor_Huffman::Get_bit() { + int t; + int wh = bloc >> 3; + int whb = wh>> 16; + if ( whb != blocIn ) { + blocMax += file->Read( seq, sizeof( seq ) ); + blocIn++; + } + wh &= 0xffff; + t = ( seq[wh] >> ( bloc & 7 ) ) & 0x1; + bloc++; + return t; +} + +/* +================ +idCompressor_Huffman::Get_ppnode +================ +*/ +huffmanNode_t **idCompressor_Huffman::Get_ppnode() { + huffmanNode_t **tppnode; + if ( !freelist ) { + return &nodePtrs[blocPtrs++]; + } else { + tppnode = freelist; + freelist = (huffmanNode_t **)*tppnode; + return tppnode; + } +} + +/* +================ +idCompressor_Huffman::Free_ppnode +================ +*/ +void idCompressor_Huffman::Free_ppnode( huffmanNode_t **ppnode ) { + *ppnode = (huffmanNode_t *)freelist; + freelist = ppnode; +} + +/* +================ +idCompressor_Huffman::Swap + + Swap the location of the given two nodes in the tree. +================ +*/ +void idCompressor_Huffman::Swap( huffmanNode_t *node1, huffmanNode_t *node2 ) { + huffmanNode_t *par1, *par2; + + par1 = node1->parent; + par2 = node2->parent; + + if ( par1 ) { + if ( par1->left == node1 ) { + par1->left = node2; + } else { + par1->right = node2; + } + } else { + tree = node2; + } + + if ( par2 ) { + if ( par2->left == node2 ) { + par2->left = node1; + } else { + par2->right = node1; + } + } else { + tree = node1; + } + + node1->parent = par2; + node2->parent = par1; +} + +/* +================ +idCompressor_Huffman::Swaplist + + Swap the given two nodes in the linked list (update ranks) +================ +*/ +void idCompressor_Huffman::Swaplist( huffmanNode_t *node1, huffmanNode_t *node2 ) { + huffmanNode_t *par1; + + par1 = node1->next; + node1->next = node2->next; + node2->next = par1; + + par1 = node1->prev; + node1->prev = node2->prev; + node2->prev = par1; + + if ( node1->next == node1 ) { + node1->next = node2; + } + if ( node2->next == node2 ) { + node2->next = node1; + } + if ( node1->next ) { + node1->next->prev = node1; + } + if ( node2->next ) { + node2->next->prev = node2; + } + if ( node1->prev ) { + node1->prev->next = node1; + } + if ( node2->prev ) { + node2->prev->next = node2; + } +} + +/* +================ +idCompressor_Huffman::Increment +================ +*/ +void idCompressor_Huffman::Increment( huffmanNode_t *node ) { + huffmanNode_t *lnode; + + if ( !node ) { + return; + } + + if ( node->next != NULL && node->next->weight == node->weight ) { + lnode = *node->head; + if ( lnode != node->parent ) { + Swap( lnode, node ); + } + Swaplist( lnode, node ); + } + if ( node->prev && node->prev->weight == node->weight ) { + *node->head = node->prev; + } else { + *node->head = NULL; + Free_ppnode( node->head ); + } + node->weight++; + if ( node->next && node->next->weight == node->weight ) { + node->head = node->next->head; + } else { + node->head = Get_ppnode(); + *node->head = node; + } + if ( node->parent ) { + Increment( node->parent ); + if ( node->prev == node->parent ) { + Swaplist( node, node->parent ); + if ( *node->head == node ) { + *node->head = node->parent; + } + } + } +} + +/* +================ +idCompressor_Huffman::AddRef +================ +*/ +void idCompressor_Huffman::AddRef( byte ch ) { + huffmanNode_t *tnode, *tnode2; + if ( loc[ch] == NULL ) { /* if this is the first transmission of this node */ + tnode = &nodeList[blocNode++]; + tnode2 = &nodeList[blocNode++]; + + tnode2->symbol = INTERNAL_NODE; + tnode2->weight = 1; + tnode2->next = lhead->next; + if ( lhead->next ) { + lhead->next->prev = tnode2; + if ( lhead->next->weight == 1 ) { + tnode2->head = lhead->next->head; + } else { + tnode2->head = Get_ppnode(); + *tnode2->head = tnode2; + } + } else { + tnode2->head = Get_ppnode(); + *tnode2->head = tnode2; + } + lhead->next = tnode2; + tnode2->prev = lhead; + + tnode->symbol = ch; + tnode->weight = 1; + tnode->next = lhead->next; + if ( lhead->next ) { + lhead->next->prev = tnode; + if ( lhead->next->weight == 1 ) { + tnode->head = lhead->next->head; + } else { + /* this should never happen */ + tnode->head = Get_ppnode(); + *tnode->head = tnode2; + } + } else { + /* this should never happen */ + tnode->head = Get_ppnode(); + *tnode->head = tnode; + } + lhead->next = tnode; + tnode->prev = lhead; + tnode->left = tnode->right = NULL; + + if ( lhead->parent ) { + if ( lhead->parent->left == lhead ) { /* lhead is guaranteed to by the NYT */ + lhead->parent->left = tnode2; + } else { + lhead->parent->right = tnode2; + } + } else { + tree = tnode2; + } + + tnode2->right = tnode; + tnode2->left = lhead; + + tnode2->parent = lhead->parent; + lhead->parent = tnode->parent = tnode2; + + loc[ch] = tnode; + + Increment( tnode2->parent ); + } else { + Increment( loc[ch] ); + } +} + +/* +================ +idCompressor_Huffman::Receive + + Get a symbol. +================ +*/ +int idCompressor_Huffman::Receive( huffmanNode_t *node, int *ch ) { + while ( node && node->symbol == INTERNAL_NODE ) { + if ( Get_bit() ) { + node = node->right; + } else { + node = node->left; + } + } + if ( !node ) { + return 0; + } + return (*ch = node->symbol); +} + +/* +================ +idCompressor_Huffman::Send + + Send the prefix code for this node. +================ +*/ +void idCompressor_Huffman::Send( huffmanNode_t *node, huffmanNode_t *child, byte *fout ) { + if ( node->parent ) { + Send( node->parent, node, fout ); + } + if ( child ) { + if ( node->right == child ) { + Add_bit( 1, fout ); + } else { + Add_bit( 0, fout ); + } + } +} + +/* +================ +idCompressor_Huffman::Transmit + + Send a symbol. +================ +*/ +void idCompressor_Huffman::Transmit( int ch, byte *fout ) { + int i; + if ( loc[ch] == NULL ) { + /* huffmanNode_t hasn't been transmitted, send a NYT, then the symbol */ + Transmit( NYT, fout ); + for ( i = 7; i >= 0; i-- ) { + Add_bit( (char)((ch >> i) & 0x1), fout ); + } + } else { + Send( loc[ch], NULL, fout ); + } +} + +/* +================ +idCompressor_Huffman::Write +================ +*/ +int idCompressor_Huffman::Write( const void *inData, int inLength ) { + int i, ch; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + for ( i = 0; i < inLength; i++ ) { + ch = ((const byte *)inData)[i]; + Transmit( ch, seq ); /* Transmit symbol */ + AddRef( (byte)ch ); /* Do update */ + int b = (bloc>>3); + if ( b > 32768 ) { + file->Write( seq, b ); + seq[0] = seq[b]; + bloc &= 7; + compressedSize += b; + } + } + + unCompressedSize += i; + return i; +} + +/* +================ +idCompressor_Huffman::FinishCompress +================ +*/ +void idCompressor_Huffman::FinishCompress( void ) { + + if ( compress == false ) { + return; + } + + bloc += 7; + int str = (bloc>>3); + if ( str ) { + file->Write( seq, str ); + compressedSize += str; + } +} + +/* +================ +idCompressor_Huffman::Read +================ +*/ +int idCompressor_Huffman::Read( void *outData, int outLength ) { + int i, j, ch; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + if ( bloc == 0 ) { + blocMax = file->Read( seq, sizeof( seq ) ); + blocIn = 0; + } + + for ( i = 0; i < outLength; i++ ) { + ch = 0; + // don't overflow reading from the file + if ( ( bloc >> 3 ) > blocMax ) { + break; + } + Receive( tree, &ch ); /* Get a character */ + if ( ch == NYT ) { /* We got a NYT, get the symbol associated with it */ + ch = 0; + for ( j = 0; j < 8; j++ ) { + ch = ( ch << 1 ) + Get_bit(); + } + } + + ((byte *)outData)[i] = ch; /* Write symbol */ + AddRef( (byte) ch ); /* Increment node */ + } + + compressedSize = bloc >> 3; + unCompressedSize += i; + return i; +} + +/* +================ +idCompressor_Huffman::GetCompressionRatio +================ +*/ +float idCompressor_Huffman::GetCompressionRatio( void ) const { + return ( unCompressedSize - compressedSize ) * 100.0f / unCompressedSize; +} + + +/* +================================================================================= + + idCompressor_Arithmetic + + The following algorithm is based on the Arithmetic Coding methods described + by Mark Nelson. The probability table is implicitly stored. + +================================================================================= +*/ + +const int AC_WORD_LENGTH = 8; +const int AC_NUM_BITS = 16; +const int AC_MSB_SHIFT = 15; +const int AC_MSB2_SHIFT = 14; +const int AC_MSB_MASK = 0x8000; +const int AC_MSB2_MASK = 0x4000; +const int AC_HIGH_INIT = 0xffff; +const int AC_LOW_INIT = 0x0000; + +class idCompressor_Arithmetic : public idCompressor_BitStream { +public: + idCompressor_Arithmetic( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +private: + typedef struct acProbs_s { + unsigned int low; + unsigned int high; + } acProbs_t; + + typedef struct acSymbol_s { + unsigned int low; + unsigned int high; + int position; + } acSymbol_t; + + acProbs_t probabilities[1<position; + + probabilities[ x ].high++; + + for( i = x + 1; i < (1< 0 ) { + mid = len >> 1; + if ( count >= probabilities[offset+mid].high ) { + offset += mid; + len -= mid; + res = 1; + } + else if ( count < probabilities[offset+mid].low ) { + len -= mid; + res = 0; + } else { + return offset+mid; + } + } + return offset+res; + +#else + + int j; + + for( j = 0; j < (1<= probabilities[ j ].low && count < probabilities[ j ].high ) { + return j; + } + } + + assert( false ); + + return 0; + +#endif +} + +/* +================ +idCompressor_Arithmetic::SymbolFromCount +================ +*/ +int idCompressor_Arithmetic::SymbolFromCount( unsigned int count, acSymbol_t* symbol ) { + int p = ProbabilityForCount( count ); + symbol->low = probabilities[ p ].low; + symbol->high = probabilities[ p ].high; + symbol->position = p; + return p; +} + +/* +================ +idCompressor_Arithmetic::RemoveSymbolFromStream +================ +*/ +void idCompressor_Arithmetic::RemoveSymbolFromStream( acSymbol_t* symbol ) { + long range; + + range = ( long )( high - low ) + 1; + high = low + ( unsigned short )( ( range * symbol->high ) / scale - 1 ); + low = low + ( unsigned short )( ( range * symbol->low ) / scale ); + + while( true ) { + + if ( ( high & AC_MSB_MASK ) == ( low & AC_MSB_MASK ) ) { + + } else if( ( low & AC_MSB2_MASK ) == AC_MSB2_MASK && ( high & AC_MSB2_MASK ) == 0 ) { + code ^= AC_MSB2_MASK; + low &= AC_MSB2_MASK - 1; + high |= AC_MSB2_MASK; + } else { + UpdateProbabilities( symbol ); + return; + } + + low <<= 1; + high <<= 1; + high |= 1; + code <<= 1; + code |= ReadBits( 1 ); + } +} + +/* +================ +idCompressor_Arithmetic::GetBit +================ +*/ +int idCompressor_Arithmetic::GetBit( void ) { + int getbit; + + if( symbolBit <= 0 ) { + // read a new symbol out + acSymbol_t symbol; + symbolBuffer = SymbolFromCount( GetCurrentCount(), &symbol ); + RemoveSymbolFromStream( &symbol ); + symbolBit = AC_WORD_LENGTH; + } + + getbit = ( symbolBuffer >> ( AC_WORD_LENGTH - symbolBit ) ) & 1; + symbolBit--; + + return getbit; +} + +/* +================ +idCompressor_Arithmetic::EncodeSymbol +================ +*/ +void idCompressor_Arithmetic::EncodeSymbol( acSymbol_t* symbol ) { + unsigned int range; + + // rescale high and low for the new symbol. + range = ( high - low ) + 1; + high = low + ( unsigned short )(( range * symbol->high ) / scale - 1 ); + low = low + ( unsigned short )(( range * symbol->low ) / scale ); + + while( true ) { + if ( ( high & AC_MSB_MASK ) == ( low & AC_MSB_MASK ) ) { + // the high digits of low and high have converged, and can be written to the stream + WriteBits( high >> AC_MSB_SHIFT, 1 ); + + while( underflowBits > 0 ) { + + WriteBits( ~high >> AC_MSB_SHIFT, 1 ); + + underflowBits--; + } + } else if ( ( low & AC_MSB2_MASK ) && !( high & AC_MSB2_MASK ) ) { + // underflow is in danger of happening, 2nd digits are converging but 1st digits don't match + underflowBits += 1; + low &= AC_MSB2_MASK - 1; + high |= AC_MSB2_MASK; + } else { + UpdateProbabilities( symbol ); + return; + } + + low <<= 1; + high <<= 1; + high |= 1; + } +} + +/* +================ +idCompressor_Arithmetic::CharToSymbol +================ +*/ +void idCompressor_Arithmetic::CharToSymbol( byte c, acSymbol_t* symbol ) { + symbol->low = probabilities[ c ].low; + symbol->high = probabilities[ c ].high; + symbol->position = c; +} + +/* +================ +idCompressor_Arithmetic::PutBit +================ +*/ +void idCompressor_Arithmetic::PutBit( int putbit ) { + symbolBuffer |= ( putbit & 1 ) << symbolBit; + symbolBit++; + + if( symbolBit >= AC_WORD_LENGTH ) { + acSymbol_t symbol; + + CharToSymbol( symbolBuffer, &symbol ); + EncodeSymbol( &symbol ); + + symbolBit = 0; + symbolBuffer = 0; + } +} + +/* +================ +idCompressor_Arithmetic::WriteOverflowBits +================ +*/ +void idCompressor_Arithmetic::WriteOverflowBits( void ) { + + WriteBits( low >> AC_MSB2_SHIFT, 1 ); + + underflowBits++; + while( underflowBits-- > 0 ) { + WriteBits( ~low >> AC_MSB2_SHIFT, 1 ); + } +} + +/* +================ +idCompressor_Arithmetic::Write +================ +*/ +int idCompressor_Arithmetic::Write( const void *inData, int inLength ) { + int i, j; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + InitCompress( inData, inLength ); + + for( i = 0; i < inLength; i++ ) { + if ( ( readTotalBytes & ( ( 1 << 14 ) - 1 ) ) == 0 ) { + if ( readTotalBytes ) { + WriteOverflowBits(); + WriteBits( 0, 15 ); + while( writeBit ) { + WriteBits( 0, 1 ); + } + WriteBits( 255, 8 ); + } + InitProbabilities(); + } + for ( j = 0; j < 8; j++ ) { + PutBit( ReadBits( 1 ) ); + } + } + + return inLength; +} + +/* +================ +idCompressor_Arithmetic::FinishCompress +================ +*/ +void idCompressor_Arithmetic::FinishCompress( void ) { + if ( compress == false ) { + return; + } + + WriteOverflowBits(); + + idCompressor_BitStream::FinishCompress(); +} + +/* +================ +idCompressor_Arithmetic::Read +================ +*/ +int idCompressor_Arithmetic::Read( void *outData, int outLength ) { + int i, j; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + InitDecompress( outData, outLength ); + + for( i = 0; i < outLength && readLength >= 0; i++ ) { + if ( ( writeTotalBytes & ( ( 1 << 14 ) - 1 ) ) == 0 ) { + if ( writeTotalBytes ) { + while( readBit ) { + ReadBits( 1 ); + } + while( ReadBits( 8 ) == 0 && readLength > 0 ) { + } + } + InitProbabilities(); + for ( j = 0; j < AC_NUM_BITS; j++ ) { + code <<= 1; + code |= ReadBits( 1 ); + } + } + for ( j = 0; j < 8; j++ ) { + WriteBits( GetBit(), 1 ); + } + } + + return i; +} + + +/* +================================================================================= + + idCompressor_LZSS + + In 1977 Abraham Lempel and Jacob Ziv presented a dictionary based scheme for + text compression called LZ77. For any new text LZ77 outputs an offset/length + pair to previously seen text and the next new byte after the previously seen + text. + + In 1982 James Storer and Thomas Szymanski presented a modification on the work + of Lempel and Ziv called LZSS. LZ77 always outputs an offset/length pair, even + if a match is only one byte long. An offset/length pair usually takes more than + a single byte to store and the compression is not optimal for small match sizes. + LZSS uses a bit flag which tells whether the following data is a literal (byte) + or an offset/length pair. + + The following algorithm is an implementation of LZSS with arbitrary word size. + +================================================================================= +*/ + +const int LZSS_BLOCK_SIZE = 65535; +const int LZSS_HASH_BITS = 10; +const int LZSS_HASH_SIZE = ( 1 << LZSS_HASH_BITS ); +const int LZSS_HASH_MASK = ( 1 << LZSS_HASH_BITS ) - 1; +const int LZSS_OFFSET_BITS = 11; +const int LZSS_LENGTH_BITS = 5; + +class idCompressor_LZSS : public idCompressor_BitStream { +public: + idCompressor_LZSS( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +protected: + int offsetBits; + int lengthBits; + int minMatchWords; + + byte block[LZSS_BLOCK_SIZE]; + int blockSize; + int blockIndex; + + int hashTable[LZSS_HASH_SIZE]; + int hashNext[LZSS_BLOCK_SIZE * 8]; + +protected: + bool FindMatch( int startWord, int startValue, int &wordOffset, int &numWords ); + void AddToHash( int index, int hash ); + int GetWordFromBlock( int wordOffset ) const; + virtual void CompressBlock( void ); + virtual void DecompressBlock( void ); +}; + +/* +================ +idCompressor_LZSS::Init +================ +*/ +void idCompressor_LZSS::Init( idFile *f, bool compress, int wordLength ) { + idCompressor_BitStream::Init( f, compress, wordLength ); + + offsetBits = LZSS_OFFSET_BITS; + lengthBits = LZSS_LENGTH_BITS; + + minMatchWords = ( offsetBits + lengthBits + wordLength ) / wordLength; + blockSize = 0; + blockIndex = 0; +} + +/* +================ +idCompressor_LZSS::FindMatch +================ +*/ +bool idCompressor_LZSS::FindMatch( int startWord, int startValue, int &wordOffset, int &numWords ) { + int i, n, hash, bottom, maxBits; + + wordOffset = startWord; + numWords = minMatchWords - 1; + + bottom = Max( 0, startWord - ( ( 1 << offsetBits ) - 1 ) ); + maxBits = ( blockSize << 3 ) - startWord * wordLength; + + hash = startValue & LZSS_HASH_MASK; + for ( i = hashTable[hash]; i >= bottom; i = hashNext[i] ) { + n = Compare( block, i * wordLength, block, startWord * wordLength, Min( maxBits, ( startWord - i ) * wordLength ) ); + if ( n > numWords * wordLength ) { + numWords = n / wordLength; + wordOffset = i; + if ( numWords > ( ( 1 << lengthBits ) - 1 + minMatchWords ) - 1 ) { + numWords = ( ( 1 << lengthBits ) - 1 + minMatchWords ) - 1; + break; + } + } + } + + return ( numWords >= minMatchWords ); +} + +/* +================ +idCompressor_LZSS::AddToHash +================ +*/ +void idCompressor_LZSS::AddToHash( int index, int hash ) { + hashNext[index] = hashTable[hash]; + hashTable[hash] = index; +} + +/* +================ +idCompressor_LZSS::GetWordFromBlock +================ +*/ +int idCompressor_LZSS::GetWordFromBlock( int wordOffset ) const { + int blockBit, blockByte, value, valueBits, get, fraction; + + blockBit = ( wordOffset * wordLength ) & 7; + blockByte = ( wordOffset * wordLength ) >> 3; + if ( blockBit != 0 ) { + blockByte++; + } + + value = 0; + valueBits = 0; + + while ( valueBits < wordLength ) { + if ( blockBit == 0 ) { + if ( blockByte >= LZSS_BLOCK_SIZE ) { + return value; + } + blockByte++; + } + get = 8 - blockBit; + if ( get > (wordLength - valueBits) ) { + get = (wordLength - valueBits); + } + fraction = block[blockByte - 1]; + fraction >>= blockBit; + fraction &= ( 1 << get ) - 1; + value |= fraction << valueBits; + valueBits += get; + blockBit = ( blockBit + get ) & 7; + } + + return value; +} + +/* +================ +idCompressor_LZSS::CompressBlock +================ +*/ +void idCompressor_LZSS::CompressBlock( void ) { + int i, startWord, startValue, wordOffset, numWords; + + InitCompress( block, blockSize ); + + memset( hashTable, -1, sizeof( hashTable ) ); + memset( hashNext, -1, sizeof( hashNext ) ); + + startWord = 0; + while( readByte < readLength ) { + startValue = ReadBits( wordLength ); + if ( FindMatch( startWord, startValue, wordOffset, numWords ) ) { + WriteBits( 1, 1 ); + WriteBits( startWord - wordOffset, offsetBits ); + WriteBits( numWords - minMatchWords, lengthBits ); + UnreadBits( wordLength ); + for ( i = 0; i < numWords; i++ ) { + startValue = ReadBits( wordLength ); + AddToHash( startWord, startValue & LZSS_HASH_MASK ); + startWord++; + } + } else { + WriteBits( 0, 1 ); + WriteBits( startValue, wordLength ); + AddToHash( startWord, startValue & LZSS_HASH_MASK ); + startWord++; + } + } + + blockSize = 0; +} + +/* +================ +idCompressor_LZSS::DecompressBlock +================ +*/ +void idCompressor_LZSS::DecompressBlock( void ) { + int i, offset, startWord, numWords; + + InitDecompress( block, LZSS_BLOCK_SIZE ); + + startWord = 0; + while( writeByte < writeLength && readLength >= 0 ) { + if ( ReadBits( 1 ) ) { + offset = startWord - ReadBits( offsetBits ); + numWords = ReadBits( lengthBits ) + minMatchWords; + for ( i = 0; i < numWords; i++ ) { + WriteBits( GetWordFromBlock( offset + i ), wordLength ); + startWord++; + } + } else { + WriteBits( ReadBits( wordLength ), wordLength ); + startWord++; + } + } + + blockSize = Min( writeByte, LZSS_BLOCK_SIZE ); +} + +/* +================ +idCompressor_LZSS::Write +================ +*/ +int idCompressor_LZSS::Write( const void *inData, int inLength ) { + int i, n; + + if ( compress == false || inLength <= 0 ) { + return 0; + } + + for ( n = i = 0; i < inLength; i += n ) { + n = LZSS_BLOCK_SIZE - blockSize; + if ( inLength - i >= n ) { + memcpy( block + blockSize, ((const byte *)inData) + i, n ); + blockSize = LZSS_BLOCK_SIZE; + CompressBlock(); + blockSize = 0; + } else { + memcpy( block + blockSize, ((const byte *)inData) + i, inLength - i ); + n = inLength - i; + blockSize += n; + } + } + + return inLength; +} + +/* +================ +idCompressor_LZSS::FinishCompress +================ +*/ +void idCompressor_LZSS::FinishCompress( void ) { + if ( compress == false ) { + return; + } + if ( blockSize ) { + CompressBlock(); + } + idCompressor_BitStream::FinishCompress(); +} + +/* +================ +idCompressor_LZSS::Read +================ +*/ +int idCompressor_LZSS::Read( void *outData, int outLength ) { + int i, n; + + if ( compress == true || outLength <= 0 ) { + return 0; + } + + if ( !blockSize ) { + DecompressBlock(); + } + + for ( n = i = 0; i < outLength; i += n ) { + if ( !blockSize ) { + return i; + } + n = blockSize - blockIndex; + if ( outLength - i >= n ) { + memcpy( ((byte *)outData) + i, block + blockIndex, n ); + DecompressBlock(); + blockIndex = 0; + } else { + memcpy( ((byte *)outData) + i, block + blockIndex, outLength - i ); + n = outLength - i; + blockIndex += n; + } + } + + return outLength; +} + +/* +================================================================================= + + idCompressor_LZSS_WordAligned + + Outputs word aligned compressed data. + +================================================================================= +*/ + +class idCompressor_LZSS_WordAligned : public idCompressor_LZSS { +public: + idCompressor_LZSS_WordAligned( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); +private: + virtual void CompressBlock( void ); + virtual void DecompressBlock( void ); +}; + +/* +================ +idCompressor_LZSS_WordAligned::Init +================ +*/ +void idCompressor_LZSS_WordAligned::Init( idFile *f, bool compress, int wordLength ) { + idCompressor_LZSS::Init( f, compress, wordLength ); + + offsetBits = 2 * wordLength; + lengthBits = wordLength; + + minMatchWords = ( offsetBits + lengthBits + wordLength ) / wordLength; + blockSize = 0; + blockIndex = 0; +} + +/* +================ +idCompressor_LZSS_WordAligned::CompressBlock +================ +*/ +void idCompressor_LZSS_WordAligned::CompressBlock( void ) { + int i, startWord, startValue, wordOffset, numWords; + + InitCompress( block, blockSize ); + + memset( hashTable, -1, sizeof( hashTable ) ); + memset( hashNext, -1, sizeof( hashNext ) ); + + startWord = 0; + while( readByte < readLength ) { + startValue = ReadBits( wordLength ); + if ( FindMatch( startWord, startValue, wordOffset, numWords ) ) { + WriteBits( numWords - ( minMatchWords - 1 ), lengthBits ); + WriteBits( startWord - wordOffset, offsetBits ); + UnreadBits( wordLength ); + for ( i = 0; i < numWords; i++ ) { + startValue = ReadBits( wordLength ); + AddToHash( startWord, startValue & LZSS_HASH_MASK ); + startWord++; + } + } else { + WriteBits( 0, lengthBits ); + WriteBits( startValue, wordLength ); + AddToHash( startWord, startValue & LZSS_HASH_MASK ); + startWord++; + } + } + + blockSize = 0; +} + +/* +================ +idCompressor_LZSS_WordAligned::DecompressBlock +================ +*/ +void idCompressor_LZSS_WordAligned::DecompressBlock( void ) { + int i, offset, startWord, numWords; + + InitDecompress( block, LZSS_BLOCK_SIZE ); + + startWord = 0; + while( writeByte < writeLength && readLength >= 0 ) { + numWords = ReadBits( lengthBits ); + if ( numWords ) { + numWords += ( minMatchWords - 1 ); + offset = startWord - ReadBits( offsetBits ); + for ( i = 0; i < numWords; i++ ) { + WriteBits( GetWordFromBlock( offset + i ), wordLength ); + startWord++; + } + } else { + WriteBits( ReadBits( wordLength ), wordLength ); + startWord++; + } + } + + blockSize = Min( writeByte, LZSS_BLOCK_SIZE ); +} + +/* +================================================================================= + + idCompressor_LZW + + http://www.unisys.com/about__unisys/lzw + http://www.dogma.net/markn/articles/lzw/lzw.htm + http://www.cs.cf.ac.uk/Dave/Multimedia/node214.html + http://www.cs.duke.edu/csed/curious/compression/lzw.html + http://oldwww.rasip.fer.hr/research/compress/algorithms/fund/lz/lzw.html + + This is the same compression scheme used by GIF with the exception that + the EOI and clear codes are not explicitly stored. Instead EOI happens + when the input stream runs dry and CC happens when the table gets to big. + + This is a derivation of LZ78, but the dictionary starts with all single + character values so only code words are output. It is similar in theory + to LZ77, but instead of using the previous X bytes as a lookup table, a table + is built as the stream is read. The compressor and decompressor use the + same formula, so the tables should be exactly alike. The only catch is the + decompressor is always one step behind the compressor and may get a code not + yet in the table. In this case, it is easy to determine what the next code + is going to be (it will be the previous string plus the first byte of the + previous string). + + The dictionary can be any size, but 12 bits seems to produce best results for + most sample data. The code size is variable. It starts with the minimum + number of bits required to store the dictionary and automatically increases + as the dictionary gets bigger (it starts at 9 bits and grows to 10 bits when + item 512 is added, 11 bits when 1024 is added, etc...) once the the dictionary + is filled (4096 items for a 12 bit dictionary), the whole thing is cleared and + the process starts over again. + + The compressor increases the bit size after it adds the item, while the + decompressor does before it adds the item. The difference is subtle, but + it's because decompressor being one step behind. Otherwise, the decompressor + would read 512 with only 9 bits. + + If "Hello" is in the dictionary, then "Hell", "Hel", "He" and "H" will be too. + We use this to our advantage by storing the index of the previous code, and + the value of the last character. This means when we traverse through the + dictionary, we get the characters in reverse. + + Dictionary entries 0-255 are always going to have the values 0-255 + +================================================================================= +*/ + +class idCompressor_LZW : public idCompressor_BitStream { +public: + idCompressor_LZW( void ) {} + + void Init( idFile *f, bool compress, int wordLength ); + void FinishCompress( void ); + + int Write( const void *inData, int inLength ); + int Read( void *outData, int outLength ); + +protected: + int AddToDict( int w, int k ); + int Lookup( int w, int k ); + + bool BumpBits(); + + int WriteChain( int code ); + void DecompressBlock(); + + static const int LZW_BLOCK_SIZE = 32767; + static const int LZW_START_BITS = 9; + static const int LZW_FIRST_CODE = (1 << (LZW_START_BITS-1)); + static const int LZW_DICT_BITS = 12; + static const int LZW_DICT_SIZE = 1 << LZW_DICT_BITS; + + // Dictionary data + struct { + int k; + int w; + } dictionary[LZW_DICT_SIZE]; + idHashIndex index; + + int nextCode; + int codeBits; + + // Block data + byte block[LZW_BLOCK_SIZE]; + int blockSize; + int blockIndex; + + // Used by the compressor + int w; + + // Used by the decompressor + int oldCode; +}; + +/* +================ +idCompressor_LZW::Init +================ +*/ +void idCompressor_LZW::Init( idFile *f, bool compress, int wordLength ) { + idCompressor_BitStream::Init( f, compress, wordLength ); + + for ( int i=0; i= n ) { + memcpy( ((byte *)outData) + i, block + blockIndex, n ); + DecompressBlock(); + blockIndex = 0; + } else { + memcpy( ((byte *)outData) + i, block + blockIndex, outLength - i ); + n = outLength - i; + blockIndex += n; + } + } + + return outLength; +} + +/* +================ +idCompressor_LZW::Lookup +================ +*/ +int idCompressor_LZW::Lookup( int w, int k ) { + int j; + + if ( w == -1 ) { + return k; + } else { + for ( j = index.First( w ^ k ); j >= 0 ; j = index.Next( j ) ) { + if ( dictionary[ j ].k == k && dictionary[ j ].w == w ) { + return j; + } + } + } + + return -1; +} + +/* +================ +idCompressor_LZW::AddToDict +================ +*/ +int idCompressor_LZW::AddToDict( int w, int k ) { + dictionary[ nextCode ].k = k; + dictionary[ nextCode ].w = w; + index.Add( w ^ k, nextCode ); + return nextCode++; +} + +/* +================ +idCompressor_LZW::BumpBits + +Possibly increments codeBits +Returns true if the dictionary was cleared +================ +*/ +bool idCompressor_LZW::BumpBits() { + if ( nextCode == ( 1 << codeBits ) ) { + codeBits ++; + if ( codeBits > LZW_DICT_BITS ) { + nextCode = LZW_FIRST_CODE; + codeBits = LZW_START_BITS; + index.Clear(); + return true; + } + } + return false; +} + +/* +================ +idCompressor_LZW::FinishCompress +================ +*/ +void idCompressor_LZW::FinishCompress( void ) { + WriteBits( w, codeBits ); + idCompressor_BitStream::FinishCompress(); +} + +/* +================ +idCompressor_LZW::Write +================ +*/ +int idCompressor_LZW::Write( const void *inData, int inLength ) { + int i; + + InitCompress( inData, inLength ); + + for ( i = 0; i < inLength; i++ ) { + int k = ReadBits( 8 ); + + int code = Lookup(w, k); + if ( code >= 0 ) { + w = code; + } else { + WriteBits( w, codeBits ); + if ( !BumpBits() ) { + AddToDict( w, k ); + } + w = k; + } + } + + return inLength; +} + + +/* +================ +idCompressor_LZW::WriteChain +The chain is stored backwards, so we have to write it to a buffer then output the buffer in reverse +================ +*/ +int idCompressor_LZW::WriteChain( int code ) { + byte chain[LZW_DICT_SIZE]; + int firstChar = 0; + int i = 0; + do { + assert( i < LZW_DICT_SIZE-1 && code >= 0 ); + chain[i++] = dictionary[code].k; + code = dictionary[code].w; + } while ( code >= 0 ); + firstChar = chain[--i]; + for ( ; i >= 0; i-- ) { + WriteBits( chain[i], 8 ); + } + return firstChar; +} + +/* +================ +idCompressor_LZW::DecompressBlock +================ +*/ +void idCompressor_LZW::DecompressBlock() { + int code, firstChar; + + InitDecompress( block, LZW_BLOCK_SIZE ); + + while( writeByte < writeLength - LZW_DICT_SIZE && readLength > 0 ) { + assert( codeBits <= LZW_DICT_BITS ); + + code = ReadBits( codeBits ); + if ( readLength == 0 ) { + break; + } + + if ( oldCode == -1 ) { + assert( code < 256 ); + WriteBits( code, 8 ); + oldCode = code; + firstChar = code; + continue; + } + + if ( code >= nextCode ) { + assert( code == nextCode ); + firstChar = WriteChain( oldCode ); + WriteBits( firstChar, 8 ); + } else { + firstChar = WriteChain( code ); + } + AddToDict( oldCode, firstChar ); + if ( BumpBits() ) { + oldCode = -1; + } else { + oldCode = code; + } + } + + blockSize = Min( writeByte, LZW_BLOCK_SIZE ); +} + +/* +================================================================================= + + idCompressor + +================================================================================= +*/ + +/* +================ +idCompressor::AllocNoCompression +================ +*/ +idCompressor * idCompressor::AllocNoCompression( void ) { + return new idCompressor_None(); +} + +/* +================ +idCompressor::AllocBitStream +================ +*/ +idCompressor * idCompressor::AllocBitStream( void ) { + return new idCompressor_BitStream(); +} + +/* +================ +idCompressor::AllocRunLength +================ +*/ +idCompressor * idCompressor::AllocRunLength( void ) { + return new idCompressor_RunLength(); +} + +/* +================ +idCompressor::AllocRunLength_ZeroBased +================ +*/ +idCompressor * idCompressor::AllocRunLength_ZeroBased( void ) { + return new idCompressor_RunLength_ZeroBased(); +} + +/* +================ +idCompressor::AllocHuffman +================ +*/ +idCompressor * idCompressor::AllocHuffman( void ) { + return new idCompressor_Huffman(); +} + +/* +================ +idCompressor::AllocArithmetic +================ +*/ +idCompressor * idCompressor::AllocArithmetic( void ) { + return new idCompressor_Arithmetic(); +} + +/* +================ +idCompressor::AllocLZSS +================ +*/ +idCompressor * idCompressor::AllocLZSS( void ) { + return new idCompressor_LZSS(); +} + +/* +================ +idCompressor::AllocLZSS_WordAligned +================ +*/ +idCompressor * idCompressor::AllocLZSS_WordAligned( void ) { + return new idCompressor_LZSS_WordAligned(); +} + +/* +================ +idCompressor::AllocLZW +================ +*/ +idCompressor * idCompressor::AllocLZW( void ) { + return new idCompressor_LZW(); +} diff --git a/framework/Compressor.h b/framework/Compressor.h new file mode 100644 index 000000000..2d203131e --- /dev/null +++ b/framework/Compressor.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __COMPRESSOR_H__ +#define __COMPRESSOR_H__ + +/* +=============================================================================== + + idCompressor is a layer ontop of idFile which provides lossless data + compression. The compressor can be used as a regular file and multiple + compressors can be stacked ontop of each other. + +=============================================================================== +*/ + +class idCompressor : public idFile { +public: + // compressor allocation + static idCompressor * AllocNoCompression( void ); + static idCompressor * AllocBitStream( void ); + static idCompressor * AllocRunLength( void ); + static idCompressor * AllocRunLength_ZeroBased( void ); + static idCompressor * AllocHuffman( void ); + static idCompressor * AllocArithmetic( void ); + static idCompressor * AllocLZSS( void ); + static idCompressor * AllocLZSS_WordAligned( void ); + static idCompressor * AllocLZW( void ); + + // initialization + virtual void Init( idFile *f, bool compress, int wordLength ) = 0; + virtual void FinishCompress( void ) = 0; + virtual float GetCompressionRatio( void ) const = 0; + + // common idFile interface + virtual const char * GetName( void ) = 0; + virtual const char * GetFullPath( void ) = 0; + virtual int Read( void *outData, int outLength ) = 0; + virtual int Write( const void *inData, int inLength ) = 0; + virtual int Length( void ) = 0; + virtual ID_TIME_T Timestamp( void ) = 0; + virtual int Tell( void ) = 0; + virtual void ForceFlush( void ) = 0; + virtual void Flush( void ) = 0; + virtual int Seek( long offset, fsOrigin_t origin ) = 0; +}; + +#endif /* !__COMPRESSOR_H__ */ diff --git a/framework/Console.cpp b/framework/Console.cpp new file mode 100644 index 000000000..9292d5b72 --- /dev/null +++ b/framework/Console.cpp @@ -0,0 +1,1177 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3))); +void SCR_DrawTextRightAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3))); + +#define LINE_WIDTH 78 +#define NUM_CON_TIMES 4 +#define CON_TEXTSIZE 0x30000 +#define TOTAL_LINES (CON_TEXTSIZE / LINE_WIDTH) +#define CONSOLE_FIRSTREPEAT 200 +#define CONSOLE_REPEAT 100 + +#define COMMAND_HISTORY 64 + +// the console will query the cvar and command systems for +// command completion information + +class idConsoleLocal : public idConsole { +public: + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void LoadGraphics( void ); + virtual bool ProcessEvent( const sysEvent_t *event, bool forceAccept ); + virtual bool Active( void ); + virtual void ClearNotifyLines( void ); + virtual void Close( void ); + virtual void Print( const char *text ); + virtual void Draw( bool forceFullScreen ); + + void Dump( const char *toFile ); + void Clear(); + + //============================ + + const idMaterial * charSetShader; + +private: + void KeyDownEvent( int key ); + + void Linefeed(); + + void PageUp(); + void PageDown(); + void Top(); + void Bottom(); + + void DrawInput(); + void DrawNotify(); + void DrawSolidConsole( float frac ); + + void Scroll(); + void SetDisplayFraction( float frac ); + void UpdateDisplayFraction( void ); + + //============================ + + bool keyCatching; + + short text[CON_TEXTSIZE]; + int current; // line where next message will be printed + int x; // offset in current line for next print + int display; // bottom of console displays this line + int lastKeyEvent; // time of last key event for scroll delay + int nextKeyEvent; // keyboard repeat rate + + float displayFrac; // approaches finalFrac at scr_conspeed + float finalFrac; // 0.0 to 1.0 lines of console to display + int fracTime; // time of last displayFrac update + + int vislines; // in scanlines + + int times[NUM_CON_TIMES]; // cls.realtime time the line was generated + // for transparent notify lines + idVec4 color; + + idEditField historyEditLines[COMMAND_HISTORY]; + + int nextHistoryLine;// the last line in the history buffer, not masked + int historyLine; // the line being displayed from history buffer + // will be <= nextHistoryLine + + idEditField consoleField; + + static idCVar con_speed; + static idCVar con_notifyTime; + static idCVar con_noPrint; + + const idMaterial * whiteShader; + const idMaterial * consoleShader; +}; + +static idConsoleLocal localConsole; +idConsole *console = &localConsole; + +idCVar idConsoleLocal::con_speed( "con_speed", "3", CVAR_SYSTEM, "speed at which the console moves up and down" ); +idCVar idConsoleLocal::con_notifyTime( "con_notifyTime", "3", CVAR_SYSTEM, "time messages are displayed onscreen when console is pulled up" ); +#ifdef DEBUG +idCVar idConsoleLocal::con_noPrint( "con_noPrint", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "print on the console but not onscreen when console is pulled up" ); +#else +idCVar idConsoleLocal::con_noPrint( "con_noPrint", "1", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "print on the console but not onscreen when console is pulled up" ); +#endif + + + +/* +============================================================================= + + Misc stats + +============================================================================= +*/ + +/* +================== +SCR_DrawTextLeftAlign +================== +*/ +void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) { + char string[MAX_STRING_CHARS]; + va_list argptr; + va_start( argptr, text ); + idStr::vsnPrintf( string, sizeof( string ), text, argptr ); + va_end( argptr ); + renderSystem->DrawSmallStringExt( 0, y + 2, string, colorWhite, true, localConsole.charSetShader ); + y += SMALLCHAR_HEIGHT + 4; +} + +/* +================== +SCR_DrawTextRightAlign +================== +*/ +void SCR_DrawTextRightAlign( float &y, const char *text, ... ) { + char string[MAX_STRING_CHARS]; + va_list argptr; + va_start( argptr, text ); + int i = idStr::vsnPrintf( string, sizeof( string ), text, argptr ); + va_end( argptr ); + renderSystem->DrawSmallStringExt( 635 - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true, localConsole.charSetShader ); + y += SMALLCHAR_HEIGHT + 4; +} + + + + +/* +================== +SCR_DrawFPS +================== +*/ +#define FPS_FRAMES 4 +float SCR_DrawFPS( float y ) { + char *s; + int w; + static int previousTimes[FPS_FRAMES]; + static int index; + int i, total; + int fps; + static int previous; + int t, frameTime; + + // don't use serverTime, because that will be drifting to + // correct for internet lag changes, timescales, timedemos, etc + t = Sys_Milliseconds(); + frameTime = t - previous; + previous = t; + + previousTimes[index % FPS_FRAMES] = frameTime; + index++; + if ( index > FPS_FRAMES ) { + // average multiple frames together to smooth changes out a bit + total = 0; + for ( i = 0 ; i < FPS_FRAMES ; i++ ) { + total += previousTimes[i]; + } + if ( !total ) { + total = 1; + } + fps = 10000 * FPS_FRAMES / total; + fps = (fps + 5)/10; + + s = va( "%ifps", fps ); + w = strlen( s ) * BIGCHAR_WIDTH; + + renderSystem->DrawBigStringExt( 635 - w, idMath::FtoiFast( y ) + 2, s, colorWhite, true, localConsole.charSetShader); + } + + return y + BIGCHAR_HEIGHT + 4; +} + +/* +================== +SCR_DrawMemoryUsage +================== +*/ +float SCR_DrawMemoryUsage( float y ) { + memoryStats_t allocs, frees; + + Mem_GetStats( allocs ); + SCR_DrawTextRightAlign( y, "total allocated memory: %4d, %4dkB", allocs.num, allocs.totalSize>>10 ); + + Mem_GetFrameStats( allocs, frees ); + SCR_DrawTextRightAlign( y, "frame alloc: %4d, %4dkB frame free: %4d, %4dkB", allocs.num, allocs.totalSize>>10, frees.num, frees.totalSize>>10 ); + + Mem_ClearFrameStats(); + + return y; +} + +/* +================== +SCR_DrawAsyncStats +================== +*/ +float SCR_DrawAsyncStats( float y ) { + int i, outgoingRate, incomingRate; + float outgoingCompression, incomingCompression; + + if ( idAsyncNetwork::server.IsActive() ) { + + SCR_DrawTextRightAlign( y, "server delay = %d msec", idAsyncNetwork::server.GetDelay() ); + SCR_DrawTextRightAlign( y, "total outgoing rate = %d KB/s", idAsyncNetwork::server.GetOutgoingRate() >> 10 ); + SCR_DrawTextRightAlign( y, "total incoming rate = %d KB/s", idAsyncNetwork::server.GetIncomingRate() >> 10 ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + + outgoingRate = idAsyncNetwork::server.GetClientOutgoingRate( i ); + incomingRate = idAsyncNetwork::server.GetClientIncomingRate( i ); + outgoingCompression = idAsyncNetwork::server.GetClientOutgoingCompression( i ); + incomingCompression = idAsyncNetwork::server.GetClientIncomingCompression( i ); + + if ( outgoingRate != -1 && incomingRate != -1 ) { + SCR_DrawTextRightAlign( y, "client %d: out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)", + i, outgoingRate, outgoingCompression, incomingRate, incomingCompression ); + } + } + + idStr msg; + idAsyncNetwork::server.GetAsyncStatsAvgMsg( msg ); + SCR_DrawTextRightAlign( y, msg.c_str() ); + + } else if ( idAsyncNetwork::client.IsActive() ) { + + outgoingRate = idAsyncNetwork::client.GetOutgoingRate(); + incomingRate = idAsyncNetwork::client.GetIncomingRate(); + outgoingCompression = idAsyncNetwork::client.GetOutgoingCompression(); + incomingCompression = idAsyncNetwork::client.GetIncomingCompression(); + + if ( outgoingRate != -1 && incomingRate != -1 ) { + SCR_DrawTextRightAlign( y, "out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)", + outgoingRate, outgoingCompression, incomingRate, incomingCompression ); + } + + SCR_DrawTextRightAlign( y, "packet loss = %d%%, client prediction = %d", + (int)idAsyncNetwork::client.GetIncomingPacketLoss(), idAsyncNetwork::client.GetPrediction() ); + + SCR_DrawTextRightAlign( y, "predicted frames: %d", idAsyncNetwork::client.GetPredictedFrames() ); + + } + + return y; +} + +/* +================== +SCR_DrawSoundDecoders +================== +*/ +float SCR_DrawSoundDecoders( float y ) { + int index, numActiveDecoders; + soundDecoderInfo_t decoderInfo; + + index = -1; + numActiveDecoders = 0; + while( ( index = soundSystem->GetSoundDecoderInfo( index, decoderInfo ) ) != -1 ) { + int localTime = decoderInfo.current44kHzTime - decoderInfo.start44kHzTime; + int sampleTime = decoderInfo.num44kHzSamples / decoderInfo.numChannels; + int percent; + if ( localTime > sampleTime ) { + if ( decoderInfo.looping ) { + percent = ( localTime % sampleTime ) * 100 / sampleTime; + } else { + percent = 100; + } + } else { + percent = localTime * 100 / sampleTime; + } + SCR_DrawTextLeftAlign( y, "%3d: %3d%% (%1.2f) %s: %s (%dkB)", numActiveDecoders, percent, decoderInfo.lastVolume, decoderInfo.format.c_str(), decoderInfo.name.c_str(), decoderInfo.numBytes >> 10 ); + numActiveDecoders++; + } + return y; +} + +//========================================================================= + +/* +============== +Con_Clear_f +============== +*/ +static void Con_Clear_f( const idCmdArgs &args ) { + localConsole.Clear(); +} + +/* +============== +Con_Dump_f +============== +*/ +static void Con_Dump_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Printf( "usage: conDump \n" ); + return; + } + + idStr fileName = args.Argv(1); + fileName.DefaultFileExtension(".txt"); + + common->Printf( "Dumped console text to %s.\n", fileName.c_str() ); + + localConsole.Dump( fileName.c_str() ); +} + +/* +============== +idConsoleLocal::Init +============== +*/ +void idConsoleLocal::Init( void ) { + int i; + + keyCatching = false; + + lastKeyEvent = -1; + nextKeyEvent = CONSOLE_FIRSTREPEAT; + + consoleField.Clear(); + + consoleField.SetWidthInChars( LINE_WIDTH ); + + for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) { + historyEditLines[i].Clear(); + historyEditLines[i].SetWidthInChars( LINE_WIDTH ); + } + + cmdSystem->AddCommand( "clear", Con_Clear_f, CMD_FL_SYSTEM, "clears the console" ); + cmdSystem->AddCommand( "conDump", Con_Dump_f, CMD_FL_SYSTEM, "dumps the console text to a file" ); +} + +/* +============== +idConsoleLocal::Shutdown +============== +*/ +void idConsoleLocal::Shutdown( void ) { + cmdSystem->RemoveCommand( "clear" ); + cmdSystem->RemoveCommand( "conDump" ); +} + +/* +============== +LoadGraphics + +Can't be combined with init, because init happens before +the renderSystem is initialized +============== +*/ +void idConsoleLocal::LoadGraphics() { + charSetShader = declManager->FindMaterial( "textures/bigchars" ); + whiteShader = declManager->FindMaterial( "_white" ); + consoleShader = declManager->FindMaterial( "console" ); +} + +/* +================ +idConsoleLocal::Active +================ +*/ +bool idConsoleLocal::Active( void ) { + return keyCatching; +} + +/* +================ +idConsoleLocal::ClearNotifyLines +================ +*/ +void idConsoleLocal::ClearNotifyLines() { + int i; + + for ( i = 0 ; i < NUM_CON_TIMES ; i++ ) { + times[i] = 0; + } +} + +/* +================ +idConsoleLocal::Close +================ +*/ +void idConsoleLocal::Close() { + keyCatching = false; + SetDisplayFraction( 0 ); + displayFrac = 0; // don't scroll to that point, go immediately + ClearNotifyLines(); +} + +/* +================ +idConsoleLocal::Clear +================ +*/ +void idConsoleLocal::Clear() { + int i; + + for ( i = 0 ; i < CON_TEXTSIZE ; i++ ) { + text[i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' '; + } + + Bottom(); // go to end +} + +/* +================ +idConsoleLocal::Dump + +Save the console contents out to a file +================ +*/ +void idConsoleLocal::Dump( const char *fileName ) { + int l, x, i; + short * line; + idFile *f; + char buffer[LINE_WIDTH + 3]; + + f = fileSystem->OpenFileWrite( fileName ); + if ( !f ) { + common->Warning( "couldn't open %s", fileName ); + return; + } + + // skip empty lines + l = current - TOTAL_LINES + 1; + if ( l < 0 ) { + l = 0; + } + for ( ; l <= current ; l++ ) + { + line = text + ( l % TOTAL_LINES ) * LINE_WIDTH; + for ( x = 0; x < LINE_WIDTH; x++ ) + if ( ( line[x] & 0xff ) > ' ' ) + break; + if ( x != LINE_WIDTH ) + break; + } + + // write the remaining lines + for ( ; l <= current; l++ ) { + line = text + ( l % TOTAL_LINES ) * LINE_WIDTH; + for( i = 0; i < LINE_WIDTH; i++ ) { + buffer[i] = line[i] & 0xff; + } + for ( x = LINE_WIDTH-1; x >= 0; x-- ) { + if ( buffer[x] <= ' ' ) { + buffer[x] = 0; + } else { + break; + } + } + buffer[x+1] = '\r'; + buffer[x+2] = '\n'; + buffer[x+3] = 0; + f->Write( buffer, strlen( buffer ) ); + } + + fileSystem->CloseFile( f ); +} + +/* +================ +idConsoleLocal::PageUp +================ +*/ +void idConsoleLocal::PageUp( void ) { + display -= 2; + if ( current - display >= TOTAL_LINES ) { + display = current - TOTAL_LINES + 1; + } +} + +/* +================ +idConsoleLocal::PageDown +================ +*/ +void idConsoleLocal::PageDown( void ) { + display += 2; + if ( display > current ) { + display = current; + } +} + +/* +================ +idConsoleLocal::Top +================ +*/ +void idConsoleLocal::Top( void ) { + display = 0; +} + +/* +================ +idConsoleLocal::Bottom +================ +*/ +void idConsoleLocal::Bottom( void ) { + display = current; +} + + +/* +============================================================================= + +CONSOLE LINE EDITING + +============================================================================== +*/ + +/* +==================== +KeyDownEvent + +Handles history and console scrollback +==================== +*/ +void idConsoleLocal::KeyDownEvent( int key ) { + + // Execute F key bindings + if ( key >= K_F1 && key <= K_F12 ) { + idKeyInput::ExecKeyBinding( key ); + return; + } + + // ctrl-L clears screen + if ( key == 'l' && idKeyInput::IsDown( K_CTRL ) ) { + Clear(); + return; + } + + // enter finishes the line + if ( key == K_ENTER || key == K_KP_ENTER ) { + + common->Printf ( "]%s\n", consoleField.GetBuffer() ); + + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, consoleField.GetBuffer() ); // valid command + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" ); + + // copy line to history buffer + historyEditLines[nextHistoryLine % COMMAND_HISTORY] = consoleField; + nextHistoryLine++; + historyLine = nextHistoryLine; + + consoleField.Clear(); + consoleField.SetWidthInChars( LINE_WIDTH ); + + session->UpdateScreen();// force an update, because the command + // may take some time + return; + } + + // command completion + + if ( key == K_TAB ) { + consoleField.AutoComplete(); + return; + } + + // command history (ctrl-p ctrl-n for unix style) + + if ( ( key == K_UPARROW ) || + ( ( tolower(key) == 'p' ) && idKeyInput::IsDown( K_CTRL ) ) ) { + if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) { + historyLine--; + } + consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; + return; + } + + if ( ( key == K_DOWNARROW ) || + ( ( tolower( key ) == 'n' ) && idKeyInput::IsDown( K_CTRL ) ) ) { + if ( historyLine == nextHistoryLine ) { + return; + } + historyLine++; + consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; + return; + } + + // console scrolling + if ( key == K_PGUP ) { + PageUp(); + lastKeyEvent = eventLoop->Milliseconds(); + nextKeyEvent = CONSOLE_FIRSTREPEAT; + return; + } + + if ( key == K_PGDN ) { + PageDown(); + lastKeyEvent = eventLoop->Milliseconds(); + nextKeyEvent = CONSOLE_FIRSTREPEAT; + return; + } + + if ( key == K_MWHEELUP ) { + PageUp(); + return; + } + + if ( key == K_MWHEELDOWN ) { + PageDown(); + return; + } + + // ctrl-home = top of console + if ( key == K_HOME && idKeyInput::IsDown( K_CTRL ) ) { + Top(); + return; + } + + // ctrl-end = bottom of console + if ( key == K_END && idKeyInput::IsDown( K_CTRL ) ) { + Bottom(); + return; + } + + // pass to the normal editline routine + consoleField.KeyDownEvent( key ); +} + +/* +============== +Scroll +deals with scrolling text because we don't have key repeat +============== +*/ +void idConsoleLocal::Scroll( ) { + if (lastKeyEvent == -1 || (lastKeyEvent+200) > eventLoop->Milliseconds()) { + return; + } + // console scrolling + if ( idKeyInput::IsDown( K_PGUP ) ) { + PageUp(); + nextKeyEvent = CONSOLE_REPEAT; + return; + } + + if ( idKeyInput::IsDown( K_PGDN ) ) { + PageDown(); + nextKeyEvent = CONSOLE_REPEAT; + return; + } +} + +/* +============== +SetDisplayFraction + +Causes the console to start opening the desired amount. +============== +*/ +void idConsoleLocal::SetDisplayFraction( float frac ) { + finalFrac = frac; + fracTime = com_frameTime; +} + +/* +============== +UpdateDisplayFraction + +Scrolls the console up or down based on conspeed +============== +*/ +void idConsoleLocal::UpdateDisplayFraction( void ) { + if ( con_speed.GetFloat() <= 0.1f ) { + fracTime = com_frameTime; + displayFrac = finalFrac; + return; + } + + // scroll towards the destination height + if ( finalFrac < displayFrac ) { + displayFrac -= con_speed.GetFloat() * ( com_frameTime - fracTime ) * 0.001f; + if ( finalFrac > displayFrac ) { + displayFrac = finalFrac; + } + fracTime = com_frameTime; + } else if ( finalFrac > displayFrac ) { + displayFrac += con_speed.GetFloat() * ( com_frameTime - fracTime ) * 0.001f; + if ( finalFrac < displayFrac ) { + displayFrac = finalFrac; + } + fracTime = com_frameTime; + } +} + +/* +============== +ProcessEvent +============== +*/ +bool idConsoleLocal::ProcessEvent( const sysEvent_t *event, bool forceAccept ) { + bool consoleKey; + consoleKey = event->evType == SE_KEY && ( event->evValue == Sys_GetConsoleKey( false ) || event->evValue == Sys_GetConsoleKey( true ) ); + +#if ID_CONSOLE_LOCK + // If the console's not already down, and we have it turned off, check for ctrl+alt + if ( !keyCatching && !com_allowConsole.GetBool() ) { + if ( !idKeyInput::IsDown( K_CTRL ) || !idKeyInput::IsDown( K_ALT ) ) { + consoleKey = false; + } + } +#endif + + // we always catch the console key event + if ( !forceAccept && consoleKey ) { + // ignore up events + if ( event->evValue2 == 0 ) { + return true; + } + + consoleField.ClearAutoComplete(); + + // a down event will toggle the destination lines + if ( keyCatching ) { + Close(); + Sys_GrabMouseCursor( true ); + cvarSystem->SetCVarBool( "ui_chat", false ); + } else { + consoleField.Clear(); + keyCatching = true; + if ( idKeyInput::IsDown( K_SHIFT ) ) { + // if the shift key is down, don't open the console as much + SetDisplayFraction( 0.2f ); + } else { + SetDisplayFraction( 0.5f ); + } + cvarSystem->SetCVarBool( "ui_chat", true ); + } + return true; + } + + // if we aren't key catching, dump all the other events + if ( !forceAccept && !keyCatching ) { + return false; + } + + // handle key and character events + if ( event->evType == SE_CHAR ) { + // never send the console key as a character + if ( event->evValue != Sys_GetConsoleKey( false ) && event->evValue != Sys_GetConsoleKey( true ) ) { + consoleField.CharEvent( event->evValue ); + } + return true; + } + + if ( event->evType == SE_KEY ) { + // ignore up key events + if ( event->evValue2 == 0 ) { + return true; + } + + KeyDownEvent( event->evValue ); + return true; + } + + // we don't handle things like mouse, joystick, and network packets + return false; +} + +/* +============================================================================== + +PRINTING + +============================================================================== +*/ + +/* +=============== +Linefeed +=============== +*/ +void idConsoleLocal::Linefeed() { + int i; + + // mark time for transparent overlay + if ( current >= 0 ) { + times[current % NUM_CON_TIMES] = com_frameTime; + } + + x = 0; + if ( display == current ) { + display++; + } + current++; + for ( i = 0; i < LINE_WIDTH; i++ ) { + text[(current%TOTAL_LINES)*LINE_WIDTH+i] = (idStr::ColorIndex(C_COLOR_CYAN)<<8) | ' '; + } +} + + +/* +================ +Print + +Handles cursor positioning, line wrapping, etc +================ +*/ +void idConsoleLocal::Print( const char *txt ) { + int y; + int c, l; + int color; + +#ifdef ID_ALLOW_TOOLS + RadiantPrint( txt ); + + if( com_editors & EDITOR_MATERIAL ) { + MaterialEditorPrintConsole(txt); + } +#endif + + color = idStr::ColorIndex( C_COLOR_CYAN ); + + while ( (c = *(const unsigned char*)txt) != 0 ) { + if ( idStr::IsColor( txt ) ) { + if ( *(txt+1) == C_COLOR_DEFAULT ) { + color = idStr::ColorIndex( C_COLOR_CYAN ); + } else { + color = idStr::ColorIndex( *(txt+1) ); + } + txt += 2; + continue; + } + + y = current % TOTAL_LINES; + + // if we are about to print a new word, check to see + // if we should wrap to the new line + if ( c > ' ' && ( x == 0 || text[y*LINE_WIDTH+x-1] <= ' ' ) ) { + // count word length + for (l=0 ; l< LINE_WIDTH ; l++) { + if ( txt[l] <= ' ') { + break; + } + } + + // word wrap + if (l != LINE_WIDTH && (x + l >= LINE_WIDTH) ) { + Linefeed(); + } + } + + txt++; + + switch( c ) { + case '\n': + Linefeed (); + break; + case '\t': + do { + text[y*LINE_WIDTH+x] = (color << 8) | ' '; + x++; + if ( x >= LINE_WIDTH ) { + Linefeed(); + x = 0; + } + } while ( x & 3 ); + break; + case '\r': + x = 0; + break; + default: // display character and advance + text[y*LINE_WIDTH+x] = (color << 8) | c; + x++; + if ( x >= LINE_WIDTH ) { + Linefeed(); + x = 0; + } + break; + } + } + + + // mark time for transparent overlay + if ( current >= 0 ) { + times[current % NUM_CON_TIMES] = com_frameTime; + } +} + + +/* +============================================================================== + +DRAWING + +============================================================================== +*/ + + +/* +================ +DrawInput + +Draw the editline after a ] prompt +================ +*/ +void idConsoleLocal::DrawInput() { + int y, autoCompleteLength; + + y = vislines - ( SMALLCHAR_HEIGHT * 2 ); + + if ( consoleField.GetAutoCompleteLength() != 0 ) { + autoCompleteLength = strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength(); + + if ( autoCompleteLength > 0 ) { + renderSystem->SetColor4( .8f, .2f, .2f, .45f ); + + renderSystem->DrawStretchPic( 2 * SMALLCHAR_WIDTH + consoleField.GetAutoCompleteLength() * SMALLCHAR_WIDTH, + y + 2, autoCompleteLength * SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT - 2, 0, 0, 0, 0, whiteShader ); + + } + } + + renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) ); + + renderSystem->DrawSmallChar( 1 * SMALLCHAR_WIDTH, y, ']', localConsole.charSetShader ); + + consoleField.Draw(2 * SMALLCHAR_WIDTH, y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, true, charSetShader ); +} + + +/* +================ +DrawNotify + +Draws the last few lines of output transparently over the game top +================ +*/ +void idConsoleLocal::DrawNotify() { + int x, v; + short *text_p; + int i; + int time; + int currentColor; + + if ( con_noPrint.GetBool() ) { + return; + } + + currentColor = idStr::ColorIndex( C_COLOR_WHITE ); + renderSystem->SetColor( idStr::ColorForIndex( currentColor ) ); + + v = 0; + for ( i = current-NUM_CON_TIMES+1; i <= current; i++ ) { + if ( i < 0 ) { + continue; + } + time = times[i % NUM_CON_TIMES]; + if ( time == 0 ) { + continue; + } + time = com_frameTime - time; + if ( time > con_notifyTime.GetFloat() * 1000 ) { + continue; + } + text_p = text + (i % TOTAL_LINES)*LINE_WIDTH; + + for ( x = 0; x < LINE_WIDTH; x++ ) { + if ( ( text_p[x] & 0xff ) == ' ' ) { + continue; + } + if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) { + currentColor = idStr::ColorIndex(text_p[x]>>8); + renderSystem->SetColor( idStr::ColorForIndex( currentColor ) ); + } + renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, v, text_p[x] & 0xff, localConsole.charSetShader ); + } + + v += SMALLCHAR_HEIGHT; + } + + renderSystem->SetColor( colorCyan ); +} + +/* +================ +DrawSolidConsole + +Draws the console with the solid background +================ +*/ +void idConsoleLocal::DrawSolidConsole( float frac ) { + int i, x; + float y; + int rows; + short *text_p; + int row; + int lines; + int currentColor; + + lines = idMath::FtoiFast( SCREEN_HEIGHT * frac ); + if ( lines <= 0 ) { + return; + } + + if ( lines > SCREEN_HEIGHT ) { + lines = SCREEN_HEIGHT; + } + + // draw the background + y = frac * SCREEN_HEIGHT - 2; + if ( y < 1.0f ) { + y = 0.0f; + } else { + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, y, 0, 1.0f - displayFrac, 1, 1, consoleShader ); + } + + renderSystem->SetColor( colorCyan ); + renderSystem->DrawStretchPic( 0, y, SCREEN_WIDTH, 2, 0, 0, 0, 0, whiteShader ); + renderSystem->SetColor( colorWhite ); + + // draw the version number + + renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) ); + + idStr version = va("%s.%i", ENGINE_VERSION, BUILD_NUMBER); + i = version.Length(); + + for ( x = 0; x < i; x++ ) { + renderSystem->DrawSmallChar( SCREEN_WIDTH - ( i - x ) * SMALLCHAR_WIDTH, + (lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), version[x], localConsole.charSetShader ); + + } + + + // draw the text + vislines = lines; + rows = (lines-SMALLCHAR_WIDTH)/SMALLCHAR_WIDTH; // rows of text to draw + + y = lines - (SMALLCHAR_HEIGHT*3); + + // draw from the bottom up + if ( display != current ) { + // draw arrows to show the buffer is backscrolled + renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) ); + for ( x = 0; x < LINE_WIDTH; x += 4 ) { + renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), '^', localConsole.charSetShader ); + } + y -= SMALLCHAR_HEIGHT; + rows--; + } + + row = display; + + if ( x == 0 ) { + row--; + } + + currentColor = idStr::ColorIndex( C_COLOR_WHITE ); + renderSystem->SetColor( idStr::ColorForIndex( currentColor ) ); + + for ( i = 0; i < rows; i++, y -= SMALLCHAR_HEIGHT, row-- ) { + if ( row < 0 ) { + break; + } + if ( current - row >= TOTAL_LINES ) { + // past scrollback wrap point + continue; + } + + text_p = text + (row % TOTAL_LINES)*LINE_WIDTH; + + for ( x = 0; x < LINE_WIDTH; x++ ) { + if ( ( text_p[x] & 0xff ) == ' ' ) { + continue; + } + + if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) { + currentColor = idStr::ColorIndex(text_p[x]>>8); + renderSystem->SetColor( idStr::ColorForIndex( currentColor ) ); + } + renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), text_p[x] & 0xff, localConsole.charSetShader ); + } + } + + // draw the input prompt, user text, and cursor if desired + DrawInput(); + + renderSystem->SetColor( colorCyan ); +} + + +/* +============== +Draw + +ForceFullScreen is used by the editor +============== +*/ +void idConsoleLocal::Draw( bool forceFullScreen ) { + float y = 0.0f; + + if ( !charSetShader ) { + return; + } + + if ( forceFullScreen ) { + // if we are forced full screen because of a disconnect, + // we want the console closed when we go back to a session state + Close(); + // we are however catching keyboard input + keyCatching = true; + } + + Scroll(); + + UpdateDisplayFraction(); + + if ( forceFullScreen ) { + DrawSolidConsole( 1.0f ); + } else if ( displayFrac ) { + DrawSolidConsole( displayFrac ); + } else { + // only draw the notify lines if the developer cvar is set, + // or we are a debug build + if ( !con_noPrint.GetBool() ) { + DrawNotify(); + } + } + + if ( com_showFPS.GetBool() ) { + y = SCR_DrawFPS( 0 ); + } + + if ( com_showMemoryUsage.GetBool() ) { + y = SCR_DrawMemoryUsage( y ); + } + + if ( com_showAsyncStats.GetBool() ) { + y = SCR_DrawAsyncStats( y ); + } + + if ( com_showSoundDecoders.GetBool() ) { + y = SCR_DrawSoundDecoders( y ); + } +} diff --git a/framework/Console.h b/framework/Console.h new file mode 100644 index 000000000..01596ed24 --- /dev/null +++ b/framework/Console.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CONSOLE_H__ +#define __CONSOLE_H__ + +/* +=============================================================================== + + The console is strictly for development and advanced users. It should + never be used to convey actual game information to the user, which should + always be done through a GUI. + + The force options are for the editor console display window, which + doesn't respond to pull up / pull down + +=============================================================================== +*/ + +class idConsole { +public: + virtual ~idConsole( void ) {} + + virtual void Init( void ) = 0; + virtual void Shutdown( void ) = 0; + + // can't be combined with Init, because Init happens before renderer is started + virtual void LoadGraphics() = 0; + + virtual bool ProcessEvent( const struct sysEvent_s *event, bool forceAccept ) = 0; + + // the system code can release the mouse pointer when the console is active + virtual bool Active( void ) = 0; + + // clear the timers on any recent prints that are displayed in the notify lines + virtual void ClearNotifyLines( void ) = 0; + + // some console commands, like timeDemo, will force the console closed before they start + virtual void Close( void ) = 0; + + virtual void Draw( bool forceFullScreen ) = 0; + virtual void Print( const char *text ) = 0; +}; + +extern idConsole * console; // statically initialized to an idConsoleLocal + +#endif /* !__CONSOLE_H__ */ diff --git a/framework/DeclAF.cpp b/framework/DeclAF.cpp new file mode 100644 index 000000000..11254655f --- /dev/null +++ b/framework/DeclAF.cpp @@ -0,0 +1,1736 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +/* +=============================================================================== + + idDeclAF + +=============================================================================== +*/ + +/* +================ +idAFVector::idAFVector +================ +*/ +idAFVector::idAFVector( void ) { + type = VEC_COORDS; + vec.Zero(); + negate = false; +} + +/* +================ +idAFVector::Parse +================ +*/ +bool idAFVector::Parse( idLexer &src ) { + idToken token; + + if ( !src.ReadToken( &token ) ) { + return false; + } + + if ( token == "-" ) { + negate = true; + if ( !src.ReadToken( &token ) ) { + return false; + } + } + else { + negate = false; + } + + if ( token == "(" ) { + type = idAFVector::VEC_COORDS; + vec.x = src.ParseFloat(); + src.ExpectTokenString( "," ); + vec.y = src.ParseFloat(); + src.ExpectTokenString( "," ); + vec.z = src.ParseFloat(); + src.ExpectTokenString( ")" ); + } + else if ( token == "joint" ) { + type = idAFVector::VEC_JOINT; + src.ExpectTokenString( "(" ); + src.ReadToken( &token ); + joint1 = token; + src.ExpectTokenString( ")" ); + } + else if ( token == "bonecenter" ) { + type = idAFVector::VEC_BONECENTER; + src.ExpectTokenString( "(" ); + src.ReadToken( &token ); + joint1 = token; + src.ExpectTokenString( "," ); + src.ReadToken( &token ); + joint2 = token; + src.ExpectTokenString( ")" ); + } + else if ( token == "bonedir" ) { + type = idAFVector::VEC_BONEDIR; + src.ExpectTokenString( "(" ); + src.ReadToken( &token ); + joint1 = token; + src.ExpectTokenString( "," ); + src.ReadToken( &token ); + joint2 = token; + src.ExpectTokenString( ")" ); + } + else { + src.Error( "unknown token %s in vector", token.c_str() ); + return false; + } + + return true; +} + +/* +================ +idAFVector::Finish +================ +*/ +bool idAFVector::Finish( const char *fileName, const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const { + idMat3 axis; + idVec3 start, end; + + switch( type ) { + case idAFVector::VEC_COORDS: { + break; + } + case idAFVector::VEC_JOINT: { + if ( !GetJointTransform( model, frame, joint1, vec, axis ) ) { + common->Warning( "invalid joint %s in joint() in '%s'", joint1.c_str(), fileName ); + vec.Zero(); + } + break; + } + case idAFVector::VEC_BONECENTER: { + if ( !GetJointTransform( model, frame, joint1, start, axis ) ) { + common->Warning( "invalid joint %s in bonecenter() in '%s'", joint1.c_str(), fileName ); + start.Zero(); + } + if ( !GetJointTransform( model, frame, joint2, end, axis ) ) { + common->Warning( "invalid joint %s in bonecenter() in '%s'", joint2.c_str(), fileName ); + end.Zero(); + } + vec = ( start + end ) * 0.5f; + break; + } + case idAFVector::VEC_BONEDIR: { + if ( !GetJointTransform( model, frame, joint1, start, axis ) ) { + common->Warning( "invalid joint %s in bonedir() in '%s'", joint1.c_str(), fileName ); + start.Zero(); + } + if ( !GetJointTransform( model, frame, joint2, end, axis ) ) { + common->Warning( "invalid joint %s in bonedir() in '%s'", joint2.c_str(), fileName ); + end.Zero(); + } + vec = ( end - start ); + break; + } + default: { + vec.Zero(); + break; + } + } + + if ( negate ) { + vec = -vec; + } + + return true; +} + +/* +================ +idAFVector::Write +================ +*/ +bool idAFVector::Write( idFile *f ) const { + + if ( negate ) { + f->WriteFloatString( "-" ); + } + switch( type ) { + case idAFVector::VEC_COORDS: { + f->WriteFloatString( "( %f, %f, %f )", vec.x, vec.y, vec.z ); + break; + } + case idAFVector::VEC_JOINT: { + f->WriteFloatString( "joint( \"%s\" )", joint1.c_str() ); + break; + } + case idAFVector::VEC_BONECENTER: { + f->WriteFloatString( "bonecenter( \"%s\", \"%s\" )", joint1.c_str(), joint2.c_str() ); + break; + } + case idAFVector::VEC_BONEDIR: { + f->WriteFloatString( "bonedir( \"%s\", \"%s\" )", joint1.c_str(), joint2.c_str() ); + break; + } + default: { + break; + } + } + return true; +} + +/* +================ +idAFVector::ToString +================ +*/ +const char *idAFVector::ToString( idStr &str, const int precision ) { + + switch( type ) { + case idAFVector::VEC_COORDS: { + char format[128]; + sprintf( format, "( %%.%df, %%.%df, %%.%df )", precision, precision, precision ); + sprintf( str, format, vec.x, vec.y, vec.z ); + break; + } + case idAFVector::VEC_JOINT: { + sprintf( str, "joint( \"%s\" )", joint1.c_str() ); + break; + } + case idAFVector::VEC_BONECENTER: { + sprintf( str, "bonecenter( \"%s\", \"%s\" )", joint1.c_str(), joint2.c_str() ); + break; + } + case idAFVector::VEC_BONEDIR: { + sprintf( str, "bonedir( \"%s\", \"%s\" )", joint1.c_str(), joint2.c_str() ); + break; + } + default: { + break; + } + } + if ( negate ) { + str = "-" + str; + } + return str.c_str(); +} + +/* +================ +idDeclAF_Body::SetDefault +================ +*/ +void idDeclAF_Body::SetDefault( const idDeclAF *file ) { + name = "noname"; + modelType = TRM_BOX; + v1.type = idAFVector::VEC_COORDS; + v1.ToVec3().x = v1.ToVec3().y = v1.ToVec3().z = -10.0f; + v2.type = idAFVector::VEC_COORDS; + v2.ToVec3().x = v2.ToVec3().y = v2.ToVec3().z = 10.0f; + numSides = 3; + origin.ToVec3().Zero(); + angles.Zero(); + density = 0.2f; + inertiaScale.Identity(); + linearFriction = file->defaultLinearFriction; + angularFriction = file->defaultAngularFriction; + contactFriction = file->defaultContactFriction; + contents = file->contents; + clipMask = file->clipMask; + selfCollision = file->selfCollision; + frictionDirection.ToVec3().Zero(); + contactMotorDirection.ToVec3().Zero(); + jointName = "origin"; + jointMod = DECLAF_JOINTMOD_AXIS; + containedJoints = "*origin"; +} + +/* +================ +idDeclAF_Constraint::SetDefault +================ +*/ +void idDeclAF_Constraint::SetDefault( const idDeclAF *file ) { + name = "noname"; + type = DECLAF_CONSTRAINT_UNIVERSALJOINT; + if ( file->bodies.Num() ) { + body1 = file->bodies[0]->name; + } + else { + body1 = "world"; + } + body2 = "world"; + friction = file->defaultConstraintFriction; + anchor.ToVec3().Zero(); + anchor2.ToVec3().Zero(); + axis.ToVec3().Set( 1.0f, 0.0f, 0.0f ); + shaft[0].ToVec3().Set( 0.0f, 0.0f, -1.0f ); + shaft[1].ToVec3().Set( 0.0f, 0.0f, 1.0f ); + limit = idDeclAF_Constraint::LIMIT_NONE; + limitAngles[0] = + limitAngles[1] = + limitAngles[2] = 0.0f; + limitAxis.ToVec3().Set( 0.0f, 0.0f, -1.0f ); +} + +/* +================ +idDeclAF::WriteBody +================ +*/ +bool idDeclAF::WriteBody( idFile *f, const idDeclAF_Body &body ) const { + idStr str; + + f->WriteFloatString( "\nbody \"%s\" {\n", body.name.c_str() ); + f->WriteFloatString( "\tjoint \"%s\"\n", body.jointName.c_str() ); + f->WriteFloatString( "\tmod %s\n", JointModToString( body.jointMod ) ); + switch( body.modelType ) { + case TRM_BOX: { + f->WriteFloatString( "\tmodel box( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( " )\n" ); + break; + } + case TRM_OCTAHEDRON: { + f->WriteFloatString( "\tmodel octahedron( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( " )\n" ); + break; + } + case TRM_DODECAHEDRON: { + f->WriteFloatString( "\tmodel dodecahedron( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( " )\n" ); + break; + } + case TRM_CYLINDER: { + f->WriteFloatString( "\tmodel cylinder( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( ", %d )\n", body.numSides ); + break; + } + case TRM_CONE: { + f->WriteFloatString( "\tmodel cone( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( ", %d )\n", body.numSides ); + break; + } + case TRM_BONE: { + f->WriteFloatString( "\tmodel bone( " ); + body.v1.Write( f ); + f->WriteFloatString( ", " ); + body.v2.Write( f ); + f->WriteFloatString( ", %f )\n", body.width ); + break; + } + default: + assert( 0 ); + break; + } + f->WriteFloatString( "\torigin " ); + body.origin.Write( f ); + f->WriteFloatString( "\n" ); + if ( body.angles != ang_zero ) { + f->WriteFloatString( "\tangles ( %f, %f, %f )\n", body.angles.pitch, body.angles.yaw, body.angles.roll ); + } + f->WriteFloatString( "\tdensity %f\n", body.density ); + if ( body.inertiaScale != mat3_identity ) { + const idMat3 &ic = body.inertiaScale; + f->WriteFloatString( "\tinertiaScale (%f %f %f %f %f %f %f %f %f)\n", + ic[0][0], ic[0][1], ic[0][2], + ic[1][0], ic[1][1], ic[1][2], + ic[2][0], ic[2][1], ic[2][2] ); + } + if ( body.linearFriction != -1 ) { + f->WriteFloatString( "\tfriction %f, %f, %f\n", body.linearFriction, body.angularFriction, body.contactFriction ); + } + f->WriteFloatString( "\tcontents %s\n", ContentsToString( body.contents, str ) ); + f->WriteFloatString( "\tclipMask %s\n", ContentsToString( body.clipMask, str ) ); + f->WriteFloatString( "\tselfCollision %d\n", body.selfCollision ); + if ( body.frictionDirection.ToVec3() != vec3_origin ) { + f->WriteFloatString( "\tfrictionDirection " ); + body.frictionDirection.Write( f ); + f->WriteFloatString( "\n" ); + } + if ( body.contactMotorDirection.ToVec3() != vec3_origin ) { + f->WriteFloatString( "\tcontactMotorDirection " ); + body.contactMotorDirection.Write( f ); + f->WriteFloatString( "\n" ); + } + f->WriteFloatString( "\tcontainedJoints \"%s\"\n", body.containedJoints.c_str() ); + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteFixed +================ +*/ +bool idDeclAF::WriteFixed( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nfixed \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteBallAndSocketJoint +================ +*/ +bool idDeclAF::WriteBallAndSocketJoint( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nballAndSocketJoint \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "\tanchor " ); + c.anchor.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tfriction %f\n", c.friction ); + if ( c.limit == idDeclAF_Constraint::LIMIT_CONE ) { + f->WriteFloatString( "\tconeLimit " ); + c.limitAxis.Write( f ); + f->WriteFloatString( ", %f, ", c.limitAngles[0] ); + c.shaft[0].Write( f ); + f->WriteFloatString( "\n" ); + } + else if ( c.limit == idDeclAF_Constraint::LIMIT_PYRAMID ) { + f->WriteFloatString( "\tpyramidLimit " ); + c.limitAxis.Write( f ); + f->WriteFloatString( ", %f, %f, %f, ", c.limitAngles[0], c.limitAngles[1], c.limitAngles[2] ); + c.shaft[0].Write( f ); + f->WriteFloatString( "\n" ); + } + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteUniversalJoint +================ +*/ +bool idDeclAF::WriteUniversalJoint( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nuniversalJoint \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "\tanchor " ); + c.anchor.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tshafts " ); + c.shaft[0].Write( f ); + f->WriteFloatString( ", " ); + c.shaft[1].Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tfriction %f\n", c.friction ); + if ( c.limit == idDeclAF_Constraint::LIMIT_CONE ) { + f->WriteFloatString( "\tconeLimit " ); + c.limitAxis.Write( f ); + f->WriteFloatString( ", %f\n", c.limitAngles[0] ); + } + else if ( c.limit == idDeclAF_Constraint::LIMIT_PYRAMID ) { + f->WriteFloatString( "\tpyramidLimit " ); + c.limitAxis.Write( f ); + f->WriteFloatString( ", %f, %f, %f\n", c.limitAngles[0], c.limitAngles[1], c.limitAngles[2] ); + } + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteHinge +================ +*/ +bool idDeclAF::WriteHinge( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nhinge \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "\tanchor " ); + c.anchor.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\taxis " ); + c.axis.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tfriction %f\n", c.friction ); + if ( c.limit == idDeclAF_Constraint::LIMIT_CONE ) { + f->WriteFloatString( "\tlimit " ); + f->WriteFloatString( "%f, %f, %f", c.limitAngles[0], c.limitAngles[1], c.limitAngles[2] ); + f->WriteFloatString( "\n" ); + } + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteSlider +================ +*/ +bool idDeclAF::WriteSlider( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nslider \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "\taxis " ); + c.axis.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tfriction %f\n", c.friction ); + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteSpring +================ +*/ +bool idDeclAF::WriteSpring( idFile *f, const idDeclAF_Constraint &c ) const { + f->WriteFloatString( "\nspring \"%s\" {\n", c.name.c_str() ); + f->WriteFloatString( "\tbody1 \"%s\"\n", c.body1.c_str() ); + f->WriteFloatString( "\tbody2 \"%s\"\n", c.body2.c_str() ); + f->WriteFloatString( "\tanchor1 " ); + c.anchor.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tanchor2 " ); + c.anchor2.Write( f ); + f->WriteFloatString( "\n" ); + f->WriteFloatString( "\tfriction %f\n", c.friction ); + f->WriteFloatString( "\tstretch %f\n", c.stretch ); + f->WriteFloatString( "\tcompress %f\n", c.compress ); + f->WriteFloatString( "\tdamping %f\n", c.damping ); + f->WriteFloatString( "\trestLength %f\n", c.restLength ); + f->WriteFloatString( "\tminLength %f\n", c.minLength ); + f->WriteFloatString( "\tmaxLength %f\n", c.maxLength ); + f->WriteFloatString( "}\n" ); + return true; +} + +/* +================ +idDeclAF::WriteConstraint +================ +*/ +bool idDeclAF::WriteConstraint( idFile *f, const idDeclAF_Constraint &c ) const { + switch( c.type ) { + case DECLAF_CONSTRAINT_FIXED: + return WriteFixed( f, c ); + case DECLAF_CONSTRAINT_BALLANDSOCKETJOINT: + return WriteBallAndSocketJoint( f, c ); + case DECLAF_CONSTRAINT_UNIVERSALJOINT: + return WriteUniversalJoint( f, c ); + case DECLAF_CONSTRAINT_HINGE: + return WriteHinge( f, c ); + case DECLAF_CONSTRAINT_SLIDER: + return WriteSlider( f, c ); + case DECLAF_CONSTRAINT_SPRING: + return WriteSpring( f, c ); + default: + break; + } + return false; +} + +/* +================ +idDeclAF::WriteSettings +================ +*/ +bool idDeclAF::WriteSettings( idFile *f ) const { + idStr str; + + f->WriteFloatString( "\nsettings {\n" ); + f->WriteFloatString( "\tmodel \"%s\"\n", model.c_str() ); + f->WriteFloatString( "\tskin \"%s\"\n", skin.c_str() ); + f->WriteFloatString( "\tfriction %f, %f, %f, %f\n", defaultLinearFriction, defaultAngularFriction, defaultContactFriction, defaultConstraintFriction ); + f->WriteFloatString( "\tsuspendSpeed %f, %f, %f, %f\n", suspendVelocity[0], suspendVelocity[1], suspendAcceleration[0], suspendAcceleration[1] ); + f->WriteFloatString( "\tnoMoveTime %f\n", noMoveTime ); + f->WriteFloatString( "\tnoMoveTranslation %f\n", noMoveTranslation ); + f->WriteFloatString( "\tnoMoveRotation %f\n", noMoveRotation ); + f->WriteFloatString( "\tminMoveTime %f\n", minMoveTime ); + f->WriteFloatString( "\tmaxMoveTime %f\n", maxMoveTime ); + f->WriteFloatString( "\ttotalMass %f\n", totalMass ); + f->WriteFloatString( "\tcontents %s\n", ContentsToString( contents, str ) ); + f->WriteFloatString( "\tclipMask %s\n", ContentsToString( clipMask, str ) ); + f->WriteFloatString( "\tselfCollision %d\n", selfCollision ); + f->WriteFloatString( "}\n" ); + return true; +} + + +/* +================ +idDeclAF::RebuildTextSource +================ +*/ +bool idDeclAF::RebuildTextSource( void ) { + int i; + idFile_Memory f; + + f.WriteFloatString("\n\n/*\n" + "\tGenerated by the Articulated Figure Editor.\n" + "\tDo not edit directly but launch the game and type 'editAFs' on the console.\n" + "*/\n" ); + + f.WriteFloatString( "\narticulatedFigure %s {\n", GetName() ); + + if ( !WriteSettings( &f ) ) { + return false; + } + + for ( i = 0; i < bodies.Num(); i++ ) { + if ( !WriteBody( &f, *bodies[i] ) ) { + return false; + } + } + + for ( i = 0; i < constraints.Num(); i++ ) { + if ( !WriteConstraint( &f, *constraints[i] ) ) { + return false; + } + } + + f.WriteFloatString( "\n}" ); + + SetText( f.GetDataPtr() ); + + return true; +} + +/* +================ +idDeclAF::Save +================ +*/ +bool idDeclAF::Save( void ) { + RebuildTextSource(); + ReplaceSourceFileText(); + modified = false; + return true; +} + +/* +================ +idDeclAF::ContentsFromString +================ +*/ +int idDeclAF::ContentsFromString( const char *str ) { + int c; + idToken token; + idLexer src( str, idStr::Length( str ), "idDeclAF::ContentsFromString" ); + + c = 0; + while( src.ReadToken( &token ) ) { + if ( token.Icmp( "none" ) == 0 ) { + c = 0; + } + else if ( token.Icmp( "solid" ) == 0 ) { + c |= CONTENTS_SOLID; + } + else if ( token.Icmp( "body" ) == 0 ) { + c |= CONTENTS_BODY; + } + else if ( token.Icmp( "corpse" ) == 0 ) { + c |= CONTENTS_CORPSE; + } + else if ( token.Icmp( "playerclip" ) == 0 ) { + c |= CONTENTS_PLAYERCLIP; + } + else if ( token.Icmp( "monsterclip" ) == 0 ) { + c |= CONTENTS_MONSTERCLIP; + } + else if ( token == "," ) { + continue; + } + else { + return c; + } + } + return c; +} + +/* +================ +idDeclAF::ContentsToString +================ +*/ +const char *idDeclAF::ContentsToString( const int contents, idStr &str ) { + str = ""; + if ( contents & CONTENTS_SOLID ) { + if ( str.Length() ) str += ", "; + str += "solid"; + } + if ( contents & CONTENTS_BODY ) { + if ( str.Length() ) str += ", "; + str += "body"; + } + if ( contents & CONTENTS_CORPSE ) { + if ( str.Length() ) str += ", "; + str += "corpse"; + } + if ( contents & CONTENTS_PLAYERCLIP ) { + if ( str.Length() ) str += ", "; + str += "playerclip"; + } + if ( contents & CONTENTS_MONSTERCLIP ) { + if ( str.Length() ) str += ", "; + str += "monsterclip"; + } + if ( str[0] == '\0' ) { + str = "none"; + } + return str.c_str(); +} + +/* +================ +idDeclAF::JointModFromString +================ +*/ +declAFJointMod_t idDeclAF::JointModFromString( const char *str ) { + if ( idStr::Icmp( str, "orientation" ) == 0 ) { + return DECLAF_JOINTMOD_AXIS; + } + if ( idStr::Icmp( str, "position" ) == 0 ) { + return DECLAF_JOINTMOD_ORIGIN; + } + if ( idStr::Icmp( str, "both" ) == 0 ) { + return DECLAF_JOINTMOD_BOTH; + } + return DECLAF_JOINTMOD_AXIS; +} + +/* +================ +idDeclAF::JointModToString +================ +*/ +const char * idDeclAF::JointModToString( declAFJointMod_t jointMod ) { + switch( jointMod ) { + case DECLAF_JOINTMOD_AXIS: { + return "orientation"; + } + case DECLAF_JOINTMOD_ORIGIN: { + return "position"; + } + case DECLAF_JOINTMOD_BOTH: { + return "both"; + } + } + return "orientation"; +} + +/* +================= +idDeclAF::Size +================= +*/ +size_t idDeclAF::Size( void ) const { + return sizeof( idDeclAF ); +} + +/* +================ +idDeclAF::ParseContents +================ +*/ +bool idDeclAF::ParseContents( idLexer &src, int &c ) const { + idToken token; + idStr str; + + while( src.ReadToken( &token ) ) { + str += token; + if ( !src.CheckTokenString( "," ) ) { + break; + } + str += ","; + } + c = ContentsFromString( str ); + return true; +} + +/* +================ +idDeclAF::ParseBody +================ +*/ +bool idDeclAF::ParseBody( idLexer &src ) { + bool hasJoint = false; + idToken token; + idAFVector angles; + idDeclAF_Body *body = new idDeclAF_Body; + + bodies.Alloc() = body; + + body->SetDefault( this ); + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + body->name = token; + if ( !body->name.Icmp( "origin" ) || !body->name.Icmp( "world" ) ) { + src.Error( "a body may not be named \"origin\" or \"world\"" ); + return false; + } + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "model" ) ) { + if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { + return false; + } + if ( !token.Icmp( "box" ) ) { + body->modelType = TRM_BOX; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "octahedron" ) ) { + body->modelType = TRM_OCTAHEDRON; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "dodecahedron" ) ) { + body->modelType = TRM_DODECAHEDRON; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "cylinder" ) ) { + body->modelType = TRM_CYLINDER; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + body->numSides = src.ParseInt(); + if ( !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "cone" ) ) { + body->modelType = TRM_CONE; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + body->numSides = src.ParseInt(); + if ( !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "bone" ) ) { + body->modelType = TRM_BONE; + if ( !src.ExpectTokenString( "(" ) || + !body->v1.Parse( src ) || + !src.ExpectTokenString( "," ) || + !body->v2.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + body->width = src.ParseFloat(); + if ( !src.ExpectTokenString( ")" ) ) { + return false; + } + } else if ( !token.Icmp( "custom" ) ) { + src.Error( "custom models not yet implemented" ); + return false; + } else { + src.Error( "unkown model type %s", token.c_str() ); + return false; + } + } else if ( !token.Icmp( "origin" ) ) { + if ( !body->origin.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "angles" ) ) { + if ( !angles.Parse( src ) ) { + return false; + } + body->angles = idAngles( angles.ToVec3().x, angles.ToVec3().y, angles.ToVec3().z ); + } else if ( !token.Icmp( "joint" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + body->jointName = token; + hasJoint = true; + } else if ( !token.Icmp( "mod" ) ) { + if ( !src.ExpectAnyToken( &token ) ) { + return false; + } + body->jointMod = JointModFromString( token.c_str() ); + } else if ( !token.Icmp( "density" ) ) { + body->density = src.ParseFloat(); + } else if ( !token.Icmp( "inertiaScale" ) ) { + src.Parse1DMatrix( 9, body->inertiaScale[0].ToFloatPtr() ); + } else if ( !token.Icmp( "friction" ) ) { + body->linearFriction = src.ParseFloat(); + src.ExpectTokenString( "," ); + body->angularFriction = src.ParseFloat(); + src.ExpectTokenString( "," ); + body->contactFriction = src.ParseFloat(); + } else if ( !token.Icmp( "contents" ) ) { + ParseContents( src, body->contents ); + } else if ( !token.Icmp( "clipMask" ) ) { + ParseContents( src, body->clipMask ); + } else if ( !token.Icmp( "selfCollision" ) ) { + body->selfCollision = src.ParseBool(); + } else if ( !token.Icmp( "containedjoints" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + body->containedJoints = token; + } else if ( !token.Icmp( "frictionDirection" ) ) { + if ( !body->frictionDirection.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "contactMotorDirection" ) ) { + if ( !body->contactMotorDirection.Parse( src ) ) { + return false; + } + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in body", token.c_str() ); + return false; + } + } + + if ( body->modelType == TRM_INVALID ) { + src.Error( "no model set for body" ); + return false; + } + + if ( !hasJoint ) { + src.Error( "no joint set for body" ); + return false; + } + + body->clipMask |= CONTENTS_MOVEABLECLIP; + + return true; +} + +/* +================ +idDeclAF::ParseFixed +================ +*/ +bool idDeclAF::ParseFixed( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_FIXED; + constraint->name = token; + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in ball and socket joint", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseBallAndSocketJoint +================ +*/ +bool idDeclAF::ParseBallAndSocketJoint( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_BALLANDSOCKETJOINT; + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + constraint->name = token; + constraint->friction = 0.5f; + constraint->anchor.ToVec3().Zero(); + constraint->shaft[0].ToVec3().Zero(); + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( !token.Icmp( "anchor" ) ) { + if ( !constraint->anchor.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "conelimit" ) ) { + if ( !constraint->limitAxis.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) || + !constraint->shaft[0].Parse( src ) ) { + return false; + } + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + } else if ( !token.Icmp( "pyramidlimit" ) ) { + if ( !constraint->limitAxis.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[1] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[2] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) || + !constraint->shaft[0].Parse( src ) ) { + return false; + } + constraint->limit = idDeclAF_Constraint::LIMIT_PYRAMID; + } else if ( !token.Icmp( "friction" ) ) { + constraint->friction = src.ParseFloat(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in ball and socket joint", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseUniversalJoint +================ +*/ +bool idDeclAF::ParseUniversalJoint( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_UNIVERSALJOINT; + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + constraint->name = token; + constraint->friction = 0.5f; + constraint->anchor.ToVec3().Zero(); + constraint->shaft[0].ToVec3().Zero(); + constraint->shaft[1].ToVec3().Zero(); + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( !token.Icmp( "anchor" ) ) { + if ( !constraint->anchor.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "shafts" ) ) { + if ( !constraint->shaft[0].Parse( src ) || + !src.ExpectTokenString( "," ) || + !constraint->shaft[1].Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "conelimit" ) ) { + if ( !constraint->limitAxis.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[0] = src.ParseFloat(); + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + } else if ( !token.Icmp( "pyramidlimit" ) ) { + if ( !constraint->limitAxis.Parse( src ) || + !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[1] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[2] = src.ParseFloat(); + constraint->limit = idDeclAF_Constraint::LIMIT_PYRAMID; + } else if ( !token.Icmp( "friction" ) ) { + constraint->friction = src.ParseFloat(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in universal joint", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseHinge +================ +*/ +bool idDeclAF::ParseHinge( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_HINGE; + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + constraint->name = token; + constraint->friction = 0.5f; + constraint->anchor.ToVec3().Zero(); + constraint->axis.ToVec3().Zero(); + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( !token.Icmp( "anchor" ) ) { + if ( !constraint->anchor.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "axis" ) ) { + if ( !constraint->axis.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "limit" ) ) { + constraint->limitAngles[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[1] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + constraint->limitAngles[2] = src.ParseFloat(); + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + } else if ( !token.Icmp( "friction" ) ) { + constraint->friction = src.ParseFloat(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in hinge", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseSlider +================ +*/ +bool idDeclAF::ParseSlider( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_SLIDER; + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + constraint->name = token; + constraint->friction = 0.5f; + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( !token.Icmp( "axis" ) ) { + if ( !constraint->axis.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "friction" ) ) { + constraint->friction = src.ParseFloat(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in slider", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseSpring +================ +*/ +bool idDeclAF::ParseSpring( idLexer &src ) { + idToken token; + idDeclAF_Constraint *constraint = new idDeclAF_Constraint; + + constraint->SetDefault( this ); + constraints.Alloc() = constraint; + + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) || + !src.ExpectTokenString( "{" ) ) { + return false; + } + + constraint->type = DECLAF_CONSTRAINT_SPRING; + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + constraint->name = token; + constraint->friction = 0.5f; + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "body1" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body1 = token; + } else if ( !token.Icmp( "body2" ) ) { + src.ExpectTokenType( TT_STRING, 0, &token ); + constraint->body2 = token; + } else if ( !token.Icmp( "anchor1" ) ) { + if ( !constraint->anchor.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "anchor2" ) ) { + if ( !constraint->anchor2.Parse( src ) ) { + return false; + } + } else if ( !token.Icmp( "friction" ) ) { + constraint->friction = src.ParseFloat(); + } else if ( !token.Icmp( "stretch" ) ) { + constraint->stretch = src.ParseFloat(); + } else if ( !token.Icmp( "compress" ) ) { + constraint->compress = src.ParseFloat(); + } else if ( !token.Icmp( "damping" ) ) { + constraint->damping = src.ParseFloat(); + } else if ( !token.Icmp( "restLength" ) ) { + constraint->restLength = src.ParseFloat(); + } else if ( !token.Icmp( "minLength" ) ) { + constraint->minLength = src.ParseFloat(); + } else if ( !token.Icmp( "maxLength" ) ) { + constraint->maxLength = src.ParseFloat(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in spring", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::ParseSettings +================ +*/ +bool idDeclAF::ParseSettings( idLexer &src ) { + idToken token; + + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "mesh" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + } else if ( !token.Icmp( "anim" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + } else if ( !token.Icmp( "model" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + model = token; + } else if ( !token.Icmp( "skin" ) ) { + if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { + return false; + } + skin = token; + } else if ( !token.Icmp( "friction" ) ) { + + defaultLinearFriction = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + defaultAngularFriction = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + defaultContactFriction = src.ParseFloat(); + if ( src.CheckTokenString( "," ) ) { + defaultConstraintFriction = src.ParseFloat(); + } + } else if ( !token.Icmp( "totalMass" ) ) { + totalMass = src.ParseFloat(); + } else if ( !token.Icmp( "suspendSpeed" ) ) { + + suspendVelocity[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + suspendVelocity[1] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + suspendAcceleration[0] = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + return false; + } + suspendAcceleration[1] = src.ParseFloat(); + } else if ( !token.Icmp( "noMoveTime" ) ) { + noMoveTime = src.ParseFloat(); + } else if ( !token.Icmp( "noMoveTranslation" ) ) { + noMoveTranslation = src.ParseFloat(); + } else if ( !token.Icmp( "noMoveRotation" ) ) { + noMoveRotation = src.ParseFloat(); + } else if ( !token.Icmp( "minMoveTime" ) ) { + minMoveTime = src.ParseFloat(); + } else if ( !token.Icmp( "maxMoveTime" ) ) { + maxMoveTime = src.ParseFloat(); + } else if ( !token.Icmp( "contents" ) ) { + ParseContents( src, contents ); + } else if ( !token.Icmp( "clipMask" ) ) { + ParseContents( src, clipMask ); + } else if ( !token.Icmp( "selfCollision" ) ) { + selfCollision = src.ParseBool(); + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown token %s in settings", token.c_str() ); + return false; + } + } + + return true; +} + +/* +================ +idDeclAF::Parse +================ +*/ +bool idDeclAF::Parse( const char *text, const int textLength ) { + int i, j; + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + while( src.ReadToken( &token ) ) { + + if ( !token.Icmp( "settings" ) ) { + if ( !ParseSettings( src ) ) { + return false; + } + } else if ( !token.Icmp( "body" ) ) { + if ( !ParseBody( src ) ) { + return false; + } + } else if ( !token.Icmp( "fixed" ) ) { + if ( !ParseFixed( src ) ) { + return false; + } + } else if ( !token.Icmp( "ballAndSocketJoint" ) ) { + if ( !ParseBallAndSocketJoint( src ) ) { + return false; + } + } else if ( !token.Icmp( "universalJoint" ) ) { + if ( !ParseUniversalJoint( src ) ) { + return false; + } + } else if ( !token.Icmp( "hinge" ) ) { + if ( !ParseHinge( src ) ) { + return false; + } + } else if ( !token.Icmp( "slider" ) ) { + if ( !ParseSlider( src ) ) { + return false; + } + } else if ( !token.Icmp( "spring" ) ) { + if ( !ParseSpring( src ) ) { + return false; + } + } else if ( token == "}" ) { + break; + } else { + src.Error( "unknown keyword %s", token.c_str() ); + return false; + } + } + + for ( i = 0; i < bodies.Num(); i++ ) { + // check for multiple bodies with the same name + for ( j = i+1; j < bodies.Num(); j++ ) { + if ( bodies[i]->name == bodies[j]->name ) { + src.Error( "two bodies with the same name \"%s\"", bodies[i]->name.c_str() ); + } + } + } + + for ( i = 0; i < constraints.Num(); i++ ) { + // check for multiple constraints with the same name + for ( j = i+1; j < constraints.Num(); j++ ) { + if ( constraints[i]->name == constraints[j]->name ) { + src.Error( "two constraints with the same name \"%s\"", constraints[i]->name.c_str() ); + } + } + // check if there are two valid bodies set + if ( constraints[i]->body1 == "" ) { + src.Error( "no valid body1 specified for constraint '%s'", constraints[i]->name.c_str() ); + } + if ( constraints[i]->body2 == "" ) { + src.Error( "no valid body2 specified for constraint '%s'", constraints[i]->name.c_str() ); + } + } + + // make sure the body which modifies the origin comes first + for ( i = 0; i < bodies.Num(); i++ ) { + if ( bodies[i]->jointName == "origin" ) { + if ( i != 0 ) { + idDeclAF_Body *b = bodies[0]; + bodies[0] = bodies[i]; + bodies[i] = b; + } + break; + } + } + + return true; +} + +/* +================ +idDeclAF::DefaultDefinition +================ +*/ +const char *idDeclAF::DefaultDefinition( void ) const { + return + "{\n" + "\t" "settings {\n" + "\t\t" "model \"\"\n" + "\t\t" "skin \"\"\n" + "\t\t" "friction 0.01, 0.01, 0.8, 0.5\n" + "\t\t" "suspendSpeed 20, 30, 40, 60\n" + "\t\t" "noMoveTime 1\n" + "\t\t" "noMoveTranslation 10\n" + "\t\t" "noMoveRotation 10\n" + "\t\t" "minMoveTime -1\n" + "\t\t" "maxMoveTime -1\n" + "\t\t" "totalMass -1\n" + "\t\t" "contents corpse\n" + "\t\t" "clipMask solid, corpse\n" + "\t\t" "selfCollision 1\n" + "\t" "}\n" + "\t" "body \"body\" {\n" + "\t\t" "joint \"origin\"\n" + "\t\t" "mod orientation\n" + "\t\t" "model box( ( -10, -10, -10 ), ( 10, 10, 10 ) )\n" + "\t\t" "origin ( 0, 0, 0 )\n" + "\t\t" "density 0.2\n" + "\t\t" "friction 0.01, 0.01, 0.8\n" + "\t\t" "contents corpse\n" + "\t\t" "clipMask solid, corpse\n" + "\t\t" "selfCollision 1\n" + "\t\t" "containedJoints \"*origin\"\n" + "\t" "}\n" + "}\n"; +} + +/* +================ +idDeclAF::FreeData +================ +*/ +void idDeclAF::FreeData( void ) { + modified = false; + defaultLinearFriction = 0.01f; + defaultAngularFriction = 0.01f; + defaultContactFriction = 0.8f; + defaultConstraintFriction = 0.5f; + totalMass = -1; + suspendVelocity.Set( 20.0f, 30.0f ); + suspendAcceleration.Set( 40.0f, 60.0f ); + noMoveTime = 1.0f; + noMoveTranslation = 10.0f; + noMoveRotation = 10.0f; + minMoveTime = -1.0f; + maxMoveTime = -1.0f; + selfCollision = true; + contents = CONTENTS_CORPSE; + clipMask = CONTENTS_SOLID | CONTENTS_CORPSE; + bodies.DeleteContents( true ); + constraints.DeleteContents( true ); +} + +/* +================ +idDeclAF::Finish +================ +*/ +void idDeclAF::Finish( const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const { + int i; + + const char *name = GetName(); + for ( i = 0; i < bodies.Num(); i++ ) { + idDeclAF_Body *body = bodies[i]; + body->v1.Finish( name, GetJointTransform, frame, model ); + body->v2.Finish( name, GetJointTransform, frame, model ); + body->origin.Finish( name, GetJointTransform, frame, model ); + body->frictionDirection.Finish( name, GetJointTransform, frame, model ); + body->contactMotorDirection.Finish( name, GetJointTransform, frame, model ); + } + for ( i = 0; i < constraints.Num(); i++ ) { + idDeclAF_Constraint *constraint = constraints[i]; + constraint->anchor.Finish( name, GetJointTransform, frame, model ); + constraint->anchor2.Finish( name, GetJointTransform, frame, model ); + constraint->shaft[0].Finish( name, GetJointTransform, frame, model ); + constraint->shaft[1].Finish( name, GetJointTransform, frame, model ); + constraint->axis.Finish( name, GetJointTransform, frame, model ); + constraint->limitAxis.Finish( name, GetJointTransform, frame, model ); + } +} + +/* +================ +idDeclAF::NewBody +================ +*/ +void idDeclAF::NewBody( const char *name ) { + idDeclAF_Body *body; + + body = new idDeclAF_Body(); + body->SetDefault( this ); + body->name = name; + bodies.Append( body ); +} + +/* +================ +idDeclAF::RenameBody + + rename the body with the given name and rename + all constraint body references +================ +*/ +void idDeclAF::RenameBody( const char *oldName, const char *newName ) { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + if ( bodies[i]->name.Icmp( oldName ) == 0 ) { + bodies[i]->name = newName; + break; + } + } + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->body1.Icmp( oldName ) == 0 ) { + constraints[i]->body1 = newName; + } else if ( constraints[i]->body2.Icmp( oldName ) == 0 ) { + constraints[i]->body2 = newName; + } + } +} + +/* +================ +idDeclAF::DeleteBody + + delete the body with the given name and delete + all constraints that reference the body +================ +*/ +void idDeclAF::DeleteBody( const char *name ) { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + if ( bodies[i]->name.Icmp( name ) == 0 ) { + delete bodies[i]; + bodies.RemoveIndex( i ); + break; + } + } + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->body1.Icmp( name ) == 0 || + constraints[i]->body2.Icmp( name ) == 0 ) { + delete constraints[i]; + constraints.RemoveIndex( i ); + i--; + } + } +} + +/* +================ +idDeclAF::NewConstraint +================ +*/ +void idDeclAF::NewConstraint( const char *name ) { + idDeclAF_Constraint *constraint; + + constraint = new idDeclAF_Constraint; + constraint->SetDefault( this ); + constraint->name = name; + constraints.Append( constraint ); +} + +/* +================ +idDeclAF::RenameConstraint +================ +*/ +void idDeclAF::RenameConstraint( const char *oldName, const char *newName ) { + int i; + + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->name.Icmp( oldName ) == 0 ) { + constraints[i]->name = newName; + return; + } + } +} + +/* +================ +idDeclAF::DeleteConstraint +================ +*/ +void idDeclAF::DeleteConstraint( const char *name ) { + int i; + + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->name.Icmp( name ) == 0 ) { + delete constraints[i]; + constraints.RemoveIndex( i ); + return; + } + } +} + +/* +================ +idDeclAF::idDeclAF +================ +*/ +idDeclAF::idDeclAF( void ) { + FreeData(); +} + +/* +================ +idDeclAF::~idDeclAF +================ +*/ +idDeclAF::~idDeclAF( void ) { + bodies.DeleteContents( true ); + constraints.DeleteContents( true ); +} diff --git a/framework/DeclAF.h b/framework/DeclAF.h new file mode 100644 index 000000000..e32f1f648 --- /dev/null +++ b/framework/DeclAF.h @@ -0,0 +1,207 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLAF_H__ +#define __DECLAF_H__ + +/* +=============================================================================== + + Articulated Figure + +=============================================================================== +*/ + +class idDeclAF; + +typedef enum { + DECLAF_CONSTRAINT_INVALID, + DECLAF_CONSTRAINT_FIXED, + DECLAF_CONSTRAINT_BALLANDSOCKETJOINT, + DECLAF_CONSTRAINT_UNIVERSALJOINT, + DECLAF_CONSTRAINT_HINGE, + DECLAF_CONSTRAINT_SLIDER, + DECLAF_CONSTRAINT_SPRING +} declAFConstraintType_t; + +typedef enum { + DECLAF_JOINTMOD_AXIS, + DECLAF_JOINTMOD_ORIGIN, + DECLAF_JOINTMOD_BOTH +} declAFJointMod_t; + +typedef bool (*getJointTransform_t)( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ); + +class idAFVector { +public: + enum { + VEC_COORDS = 0, + VEC_JOINT, + VEC_BONECENTER, + VEC_BONEDIR + } type; + idStr joint1; + idStr joint2; + +public: + idAFVector( void ); + + bool Parse( idLexer &src ); + bool Finish( const char *fileName, const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const; + bool Write( idFile *f ) const; + const char * ToString( idStr &str, const int precision = 8 ); + const idVec3 & ToVec3( void ) const { return vec; } + idVec3 & ToVec3( void ) { return vec; } + +private: + mutable idVec3 vec; + bool negate; +}; + +class idDeclAF_Body { +public: + idStr name; + idStr jointName; + declAFJointMod_t jointMod; + int modelType; + idAFVector v1, v2; + int numSides; + float width; + float density; + idAFVector origin; + idAngles angles; + int contents; + int clipMask; + bool selfCollision; + idMat3 inertiaScale; + float linearFriction; + float angularFriction; + float contactFriction; + idStr containedJoints; + idAFVector frictionDirection; + idAFVector contactMotorDirection; +public: + void SetDefault( const idDeclAF *file ); +}; + +class idDeclAF_Constraint { +public: + idStr name; + idStr body1; + idStr body2; + declAFConstraintType_t type; + float friction; + float stretch; + float compress; + float damping; + float restLength; + float minLength; + float maxLength; + idAFVector anchor; + idAFVector anchor2; + idAFVector shaft[2]; + idAFVector axis; + enum { + LIMIT_NONE = -1, + LIMIT_CONE, + LIMIT_PYRAMID + } limit; + idAFVector limitAxis; + float limitAngles[3]; + +public: + void SetDefault( const idDeclAF *file ); +}; + +class idDeclAF : public idDecl { + friend class idAFFileManager; +public: + idDeclAF( void ); + virtual ~idDeclAF( void ); + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + + virtual void Finish( const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const; + + bool Save( void ); + + void NewBody( const char *name ); + void RenameBody( const char *oldName, const char *newName ); + void DeleteBody( const char *name ); + + void NewConstraint( const char *name ); + void RenameConstraint( const char *oldName, const char *newName ); + void DeleteConstraint( const char *name ); + + static int ContentsFromString( const char *str ); + static const char * ContentsToString( const int contents, idStr &str ); + + static declAFJointMod_t JointModFromString( const char *str ); + static const char * JointModToString( declAFJointMod_t jointMod ); + +public: + bool modified; + idStr model; + idStr skin; + float defaultLinearFriction; + float defaultAngularFriction; + float defaultContactFriction; + float defaultConstraintFriction; + float totalMass; + idVec2 suspendVelocity; + idVec2 suspendAcceleration; + float noMoveTime; + float noMoveTranslation; + float noMoveRotation; + float minMoveTime; + float maxMoveTime; + int contents; + int clipMask; + bool selfCollision; + idList bodies; + idList constraints; + +private: + bool ParseContents( idLexer &src, int &c ) const; + bool ParseBody( idLexer &src ); + bool ParseFixed( idLexer &src ); + bool ParseBallAndSocketJoint( idLexer &src ); + bool ParseUniversalJoint( idLexer &src ); + bool ParseHinge( idLexer &src ); + bool ParseSlider( idLexer &src ); + bool ParseSpring( idLexer &src ); + bool ParseSettings( idLexer &src ); + + bool WriteBody( idFile *f, const idDeclAF_Body &body ) const; + bool WriteFixed( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteBallAndSocketJoint( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteUniversalJoint( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteHinge( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteSlider( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteSpring( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteConstraint( idFile *f, const idDeclAF_Constraint &c ) const; + bool WriteSettings( idFile *f ) const; + + bool RebuildTextSource( void ); +}; + +#endif /* !__DECLAF_H__ */ diff --git a/framework/DeclEntityDef.cpp b/framework/DeclEntityDef.cpp new file mode 100644 index 000000000..c7c3738d4 --- /dev/null +++ b/framework/DeclEntityDef.cpp @@ -0,0 +1,144 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + + +/* +================= +idDeclEntityDef::Size +================= +*/ +size_t idDeclEntityDef::Size( void ) const { + return sizeof( idDeclEntityDef ) + dict.Allocated(); +} + +/* +================ +idDeclEntityDef::FreeData +================ +*/ +void idDeclEntityDef::FreeData( void ) { + dict.Clear(); +} + +/* +================ +idDeclEntityDef::Parse +================ +*/ +bool idDeclEntityDef::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token, token2; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + while (1) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + if ( token.type != TT_STRING ) { + src.Warning( "Expected quoted string, but found '%s'", token.c_str() ); + MakeDefault(); + return false; + } + + if ( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + + if ( dict.FindKey( token ) ) { + src.Warning( "'%s' already defined", token.c_str() ); + } + dict.Set( token, token2 ); + } + + // we always automatically set a "classname" key to our name + dict.Set( "classname", GetName() ); + + // "inherit" keys will cause all values from another entityDef to be copied into this one + // if they don't conflict. We can't have circular recursions, because each entityDef will + // never be parsed mroe than once + + // find all of the dicts first, because copying inherited values will modify the dict + idList defList; + + while ( 1 ) { + const idKeyValue *kv; + kv = dict.MatchPrefix( "inherit", NULL ); + if ( !kv ) { + break; + } + + const idDeclEntityDef *copy = static_cast( declManager->FindType( DECL_ENTITYDEF, kv->GetValue(), false ) ); + if ( !copy ) { + src.Warning( "Unknown entityDef '%s' inherited by '%s'", kv->GetValue().c_str(), GetName() ); + } else { + defList.Append( copy ); + } + + // delete this key/value pair + dict.Delete( kv->GetKey() ); + } + + // now copy over the inherited key / value pairs + for ( int i = 0 ; i < defList.Num() ; i++ ) { + dict.SetDefaults( &defList[ i ]->dict ); + } + + // precache all referenced media + // do this as long as we arent in modview + if ( !( com_editors & (EDITOR_RADIANT|EDITOR_AAS) ) ) { + game->CacheDictionaryMedia( &dict ); + } + + return true; +} + +/* +================ +idDeclEntityDef::DefaultDefinition +================ +*/ +const char *idDeclEntityDef::DefaultDefinition( void ) const { + return + "{\n" + "\t" "\"DEFAULTED\"\t\"1\"\n" + "}"; +} + +/* +================ +idDeclEntityDef::Print + +Dumps all key/value pairs, including inherited ones +================ +*/ +void idDeclEntityDef::Print( void ) { + dict.Print(); +} diff --git a/framework/DeclEntityDef.h b/framework/DeclEntityDef.h new file mode 100644 index 000000000..f85371f77 --- /dev/null +++ b/framework/DeclEntityDef.h @@ -0,0 +1,42 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLENTITYDEF_H__ +#define __DECLENTITYDEF_H__ + +/* +=============================================================================== + + idDeclEntityDef + +=============================================================================== +*/ + +class idDeclEntityDef : public idDecl { +public: + idDict dict; + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition() const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ); +}; + +#endif /* !__DECLENTITYDEF_H__ */ diff --git a/framework/DeclFX.cpp b/framework/DeclFX.cpp new file mode 100644 index 000000000..08a440cb5 --- /dev/null +++ b/framework/DeclFX.cpp @@ -0,0 +1,464 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + + +/* +================= +idDeclFX::Size +================= +*/ +size_t idDeclFX::Size( void ) const { + return sizeof( idDeclFX ); +} + +/* +=============== +idDeclFX::Print +=============== +*/ +void idDeclFX::Print( void ) const { + const idDeclFX *list = this; + + common->Printf("%d events\n", list->events.Num() ); + for( int i = 0; i < list->events.Num(); i++ ) { + switch( list->events[i].type ) { + case FX_LIGHT: + common->Printf("FX_LIGHT %s\n", list->events[i].data.c_str()); + break; + case FX_PARTICLE: + common->Printf("FX_PARTICLE %s\n", list->events[i].data.c_str()); + break; + case FX_MODEL: + common->Printf("FX_MODEL %s\n", list->events[i].data.c_str()); + break; + case FX_SOUND: + common->Printf("FX_SOUND %s\n", list->events[i].data.c_str()); + break; + case FX_DECAL: + common->Printf("FX_DECAL %s\n", list->events[i].data.c_str()); + break; + case FX_SHAKE: + common->Printf("FX_SHAKE %s\n", list->events[i].data.c_str()); + break; + case FX_ATTACHLIGHT: + common->Printf("FX_ATTACHLIGHT %s\n", list->events[i].data.c_str()); + break; + case FX_ATTACHENTITY: + common->Printf("FX_ATTACHENTITY %s\n", list->events[i].data.c_str()); + break; + case FX_LAUNCH: + common->Printf("FX_LAUNCH %s\n", list->events[i].data.c_str()); + break; + case FX_SHOCKWAVE: + common->Printf("FX_SHOCKWAVE %s\n", list->events[i].data.c_str()); + break; + } + } +} + +/* +=============== +idDeclFX::List +=============== +*/ +void idDeclFX::List( void ) const { + common->Printf("%s, %d stages\n", GetName(), events.Num() ); +} + +/* +================ +idDeclFX::ParseSingleFXAction +================ +*/ +void idDeclFX::ParseSingleFXAction( idLexer &src, idFXSingleAction& FXAction ) { + idToken token; + + FXAction.type = -1; + FXAction.sibling = -1; + + FXAction.data = ""; + FXAction.name = ""; + FXAction.fire = ""; + + FXAction.delay = 0.0f; + FXAction.duration = 0.0f; + FXAction.restart = 0.0f; + FXAction.size = 0.0f; + FXAction.fadeInTime = 0.0f; + FXAction.fadeOutTime = 0.0f; + FXAction.shakeTime = 0.0f; + FXAction.shakeAmplitude = 0.0f; + FXAction.shakeDistance = 0.0f; + FXAction.shakeFalloff = false; + FXAction.shakeImpulse = 0.0f; + FXAction.shakeIgnoreMaster = false; + FXAction.lightRadius = 0.0f; + FXAction.rotate = 0.0f; + FXAction.random1 = 0.0f; + FXAction.random2 = 0.0f; + + FXAction.lightColor = vec3_origin; + FXAction.offset = vec3_origin; + FXAction.axis = mat3_identity; + + FXAction.bindParticles = false; + FXAction.explicitAxis = false; + FXAction.noshadows = false; + FXAction.particleTrackVelocity = false; + FXAction.trackOrigin = false; + FXAction.soundStarted = false; + + while (1) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + + if ( !token.Icmp( "shake" ) ) { + FXAction.type = FX_SHAKE; + FXAction.shakeTime = src.ParseFloat(); + src.ExpectTokenString(","); + FXAction.shakeAmplitude = src.ParseFloat(); + src.ExpectTokenString(","); + FXAction.shakeDistance = src.ParseFloat(); + src.ExpectTokenString(","); + FXAction.shakeFalloff = src.ParseBool(); + src.ExpectTokenString(","); + FXAction.shakeImpulse = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "noshadows" ) ) { + FXAction.noshadows = true; + continue; + } + + if ( !token.Icmp( "name" ) ) { + src.ReadToken( &token ); + FXAction.name = token; + continue; + } + + if ( !token.Icmp( "fire") ) { + src.ReadToken( &token ); + FXAction.fire = token; + continue; + } + + if ( !token.Icmp( "random" ) ) { + FXAction.random1 = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.random2 = src.ParseFloat(); + FXAction.delay = 0.0f; // check random + continue; + } + + if ( !token.Icmp( "delay" ) ) { + FXAction.delay = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "rotate" ) ) { + FXAction.rotate = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "duration" ) ) { + FXAction.duration = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "trackorigin" ) ) { + FXAction.trackOrigin = src.ParseBool(); + continue; + } + + if (!token.Icmp("restart")) { + FXAction.restart = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "fadeIn" ) ) { + FXAction.fadeInTime = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "fadeOut" ) ) { + FXAction.fadeOutTime = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "size" ) ) { + FXAction.size = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "offset" ) ) { + FXAction.offset.x = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.offset.y = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.offset.z = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "axis" ) ) { + idVec3 v; + v.x = src.ParseFloat(); + src.ExpectTokenString( "," ); + v.y = src.ParseFloat(); + src.ExpectTokenString( "," ); + v.z = src.ParseFloat(); + v.Normalize(); + FXAction.axis = v.ToMat3(); + FXAction.explicitAxis = true; + continue; + } + + if ( !token.Icmp( "angle" ) ) { + idAngles a; + a[0] = src.ParseFloat(); + src.ExpectTokenString( "," ); + a[1] = src.ParseFloat(); + src.ExpectTokenString( "," ); + a[2] = src.ParseFloat(); + FXAction.axis = a.ToMat3(); + FXAction.explicitAxis = true; + continue; + } + + if ( !token.Icmp( "uselight" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + for( int i = 0; i < events.Num(); i++ ) { + if ( events[i].name.Icmp( FXAction.data ) == 0 ) { + FXAction.sibling = i; + FXAction.lightColor = events[i].lightColor; + FXAction.lightRadius = events[i].lightRadius; + } + } + FXAction.type = FX_LIGHT; + + // precache the light material + declManager->FindMaterial( FXAction.data ); + continue; + } + + if ( !token.Icmp( "attachlight" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_ATTACHLIGHT; + + // precache it + declManager->FindMaterial( FXAction.data ); + continue; + } + + if ( !token.Icmp( "attachentity" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_ATTACHENTITY; + + // precache the model + renderModelManager->FindModel( FXAction.data ); + continue; + } + + if ( !token.Icmp( "launch" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_LAUNCH; + + // precache the entity def + declManager->FindType( DECL_ENTITYDEF, FXAction.data ); + continue; + } + + if ( !token.Icmp( "useModel" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + for( int i = 0; i < events.Num(); i++ ) { + if ( events[i].name.Icmp( FXAction.data ) == 0 ) { + FXAction.sibling = i; + } + } + FXAction.type = FX_MODEL; + + // precache the model + renderModelManager->FindModel( FXAction.data ); + continue; + } + + if ( !token.Icmp( "light" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + src.ExpectTokenString( "," ); + FXAction.lightColor[0] = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.lightColor[1] = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.lightColor[2] = src.ParseFloat(); + src.ExpectTokenString( "," ); + FXAction.lightRadius = src.ParseFloat(); + FXAction.type = FX_LIGHT; + + // precache the light material + declManager->FindMaterial( FXAction.data ); + continue; + } + + if ( !token.Icmp( "model" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_MODEL; + + // precache it + renderModelManager->FindModel( FXAction.data ); + continue; + } + + if ( !token.Icmp( "particle" ) ) { // FIXME: now the same as model + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_PARTICLE; + + // precache it + renderModelManager->FindModel( FXAction.data ); + continue; + } + + if ( !token.Icmp( "decal" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_DECAL; + + // precache it + declManager->FindMaterial( FXAction.data ); + continue; + } + + if ( !token.Icmp( "particleTrackVelocity" ) ) { + FXAction.particleTrackVelocity = true; + continue; + } + + if ( !token.Icmp( "sound" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_SOUND; + + // precache it + declManager->FindSound( FXAction.data ); + continue; + } + + if ( !token.Icmp( "ignoreMaster" ) ) { + FXAction.shakeIgnoreMaster = true; + continue; + } + + if ( !token.Icmp( "shockwave" ) ) { + src.ReadToken( &token ); + FXAction.data = token; + FXAction.type = FX_SHOCKWAVE; + + // precache the entity def + declManager->FindType( DECL_ENTITYDEF, FXAction.data ); + continue; + } + + src.Warning( "FX File: bad token" ); + continue; + } +} + +/* +================ +idDeclFX::Parse +================ +*/ +bool idDeclFX::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + // scan through, identifying each individual parameter + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "bindto" ) ) { + src.ReadToken( &token ); + joint = token; + continue; + } + + if ( !token.Icmp( "{" ) ) { + idFXSingleAction action; + ParseSingleFXAction( src, action ); + events.Append( action ); + continue; + } + } + + if ( src.HadError() ) { + src.Warning( "FX decl '%s' had a parse error", GetName() ); + return false; + } + return true; +} + +/* +=================== +idDeclFX::DefaultDefinition +=================== +*/ +const char *idDeclFX::DefaultDefinition( void ) const { + return + "{\n" + "\t" "{\n" + "\t\t" "duration\t5\n" + "\t\t" "model\t\t_default\n" + "\t" "}\n" + "}"; +} + +/* +=================== +idDeclFX::FreeData +=================== +*/ +void idDeclFX::FreeData( void ) { + events.Clear(); +} diff --git a/framework/DeclFX.h b/framework/DeclFX.h new file mode 100644 index 000000000..99fdfe806 --- /dev/null +++ b/framework/DeclFX.h @@ -0,0 +1,104 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLFX_H__ +#define __DECLFX_H__ + +/* +=============================================================================== + + idDeclFX + +=============================================================================== +*/ + +enum { + FX_LIGHT, + FX_PARTICLE, + FX_DECAL, + FX_MODEL, + FX_SOUND, + FX_SHAKE, + FX_ATTACHLIGHT, + FX_ATTACHENTITY, + FX_LAUNCH, + FX_SHOCKWAVE +}; + +// +// single fx structure +// +struct idFXSingleAction { + int type; + int sibling; + + idStr data; + idStr name; + idStr fire; + + float delay; + float duration; + float restart; + float size; + float fadeInTime; + float fadeOutTime; + float shakeTime; + float shakeAmplitude; + float shakeDistance; + float shakeImpulse; + float lightRadius; + float rotate; + float random1; + float random2; + + idVec3 lightColor; + idVec3 offset; + idMat3 axis; + + bool soundStarted; + bool shakeStarted; + bool shakeFalloff; + bool shakeIgnoreMaster; + bool bindParticles; + bool explicitAxis; + bool noshadows; + bool particleTrackVelocity; + bool trackOrigin; +}; + +// +// grouped fx structures +// +class idDeclFX : public idDecl { +public: + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + virtual void List( void ) const; + + idListevents; + idStr joint; + +private: + void ParseSingleFXAction( idLexer &src, idFXSingleAction& FXAction ); +}; + +#endif /* !__DECLFX_H__ */ diff --git a/framework/DeclManager.cpp b/framework/DeclManager.cpp new file mode 100644 index 000000000..4d388b925 --- /dev/null +++ b/framework/DeclManager.cpp @@ -0,0 +1,2221 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +/* + +GUIs and script remain separately parsed + +Following a parse, all referenced media (and other decls) will have been touched. + +sinTable and cosTable are required for the rotate material keyword to function + +A new FindType on a purged decl will cause it to be reloaded, but a stale pointer to a purged +decl will look like a defaulted decl. + +Moving a decl from one file to another will not be handled correctly by a reload, the material +will be defaulted. + +NULL or empty decl names will always return NULL + Should probably make a default decl for this + +Decls are initially created without a textSource +A parse without textSource set should always just call MakeDefault() +A parse that has an error should internally call MakeDefault() +A purge does nothing to a defaulted decl + +Should we have a "purged" media state separate from the "defaulted" media state? + +reloading over a decl name that was defaulted + +reloading over a decl name that was valid + +missing reload over a previously explicit definition + +*/ + +#define USE_COMPRESSED_DECLS +//#define GET_HUFFMAN_FREQUENCIES + +class idDeclType { +public: + idStr typeName; + declType_t type; + idDecl * (*allocator)( void ); +}; + +class idDeclFolder { +public: + idStr folder; + idStr extension; + declType_t defaultType; +}; + +class idDeclFile; + +class idDeclLocal : public idDeclBase { + friend class idDeclFile; + friend class idDeclManagerLocal; + +public: + idDeclLocal(); + virtual ~idDeclLocal() {}; + virtual const char * GetName( void ) const; + virtual declType_t GetType( void ) const; + virtual declState_t GetState( void ) const; + virtual bool IsImplicit( void ) const; + virtual bool IsValid( void ) const; + virtual void Invalidate( void ); + virtual void Reload( void ); + virtual void EnsureNotPurged( void ); + virtual int Index( void ) const; + virtual int GetLineNum( void ) const; + virtual const char * GetFileName( void ) const; + virtual size_t Size( void ) const; + virtual void GetText( char *text ) const; + virtual int GetTextLength( void ) const; + virtual void SetText( const char *text ); + virtual bool ReplaceSourceFileText( void ); + virtual bool SourceFileChanged( void ) const; + virtual void MakeDefault( void ); + virtual bool EverReferenced( void ) const; + +protected: + virtual bool SetDefaultText( void ); + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void List( void ) const; + virtual void Print( void ) const; + +protected: + void AllocateSelf( void ); + + // Parses the decl definition. + // After calling parse, a decl will be guaranteed usable. + void ParseLocal( void ); + + // Does a MakeDefualt, but flags the decl so that it + // will Parse() the next time the decl is found. + void Purge( void ); + + // Set textSource possible with compression. + void SetTextLocal( const char *text, const int length ); + +private: + idDecl * self; + + idStr name; // name of the decl + char * textSource; // decl text definition + int textLength; // length of textSource + int compressedLength; // compressed length + idDeclFile * sourceFile; // source file in which the decl was defined + int sourceTextOffset; // offset in source file to decl text + int sourceTextLength; // length of decl text in source file + int sourceLine; // this is where the actual declaration token starts + int checksum; // checksum of the decl text + declType_t type; // decl type + declState_t declState; // decl state + int index; // index in the per-type list + + bool parsedOutsideLevelLoad; // these decls will never be purged + bool everReferenced; // set to true if the decl was ever used + bool referencedThisLevel; // set to true when the decl is used for the current level + bool redefinedInReload; // used during file reloading to make sure a decl that has + // its source removed will be defaulted + idDeclLocal * nextInFile; // next decl in the decl file +}; + +class idDeclFile { +public: + idDeclFile(); + idDeclFile( const char *fileName, declType_t defaultType ); + + void Reload( bool force ); + int LoadAndParse(); + +public: + idStr fileName; + declType_t defaultType; + + ID_TIME_T timestamp; + int checksum; + int fileSize; + int numLines; + + idDeclLocal * decls; +}; + +class idDeclManagerLocal : public idDeclManager { + friend class idDeclLocal; + +public: + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void Reload( bool force ); + virtual void BeginLevelLoad(); + virtual void EndLevelLoad(); + virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ); + virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ); + virtual int GetChecksum( void ) const; + virtual int GetNumDeclTypes( void ) const; + virtual int GetNumDecls( declType_t type ); + virtual const char * GetDeclNameFromType( declType_t type ) const; + virtual declType_t GetDeclTypeFromName( const char *typeName ) const; + virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ); + virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ); + + virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ); + virtual void ReloadFile( const char* filename, bool force ); + + virtual void ListType( const idCmdArgs &args, declType_t type ); + virtual void PrintType( const idCmdArgs &args, declType_t type ); + + virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ); + + //BSM Added for the material editors rename capabilities + virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ); + + virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))); + virtual void WritePrecacheCommands( idFile *f ); + + virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ); + virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ); + virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ); + + virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ); + virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ); + virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ); + +public: + static void MakeNameCanonical( const char *name, char *result, int maxLength ); + idDeclLocal * FindTypeWithoutParsing( declType_t type, const char *name, bool makeDefault = true ); + + idDeclType * GetDeclType( int type ) const { return declTypes[type]; } + const idDeclFile * GetImplicitDeclFile( void ) const { return &implicitDecls; } + +private: + idList declTypes; + idList declFolders; + + idList loadedFiles; + idHashIndex hashTables[DECL_MAX_TYPES]; + idList linearLists[DECL_MAX_TYPES]; + idDeclFile implicitDecls; // this holds all the decls that were created because explicit + // text definitions were not found. Decls that became default + // because of a parse error are not in this list. + int checksum; // checksum of all loaded decl text + int indent; // for MediaPrint + bool insideLevelLoad; + + static idCVar decl_show; + +private: + static void ListDecls_f( const idCmdArgs &args ); + static void ReloadDecls_f( const idCmdArgs &args ); + static void TouchDecl_f( const idCmdArgs &args ); +}; + +idCVar idDeclManagerLocal::decl_show( "decl_show", "0", CVAR_SYSTEM, "set to 1 to print parses, 2 to also print references", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); + +idDeclManagerLocal declManagerLocal; +idDeclManager * declManager = &declManagerLocal; + +/* +==================================================================================== + + decl text huffman compression + +==================================================================================== +*/ + +const int MAX_HUFFMAN_SYMBOLS = 256; + +typedef struct huffmanNode_s { + int symbol; + int frequency; + struct huffmanNode_s * next; + struct huffmanNode_s * children[2]; +} huffmanNode_t; + +typedef struct huffmanCode_s { + unsigned long bits[8]; + int numBits; +} huffmanCode_t; + +// compression ratio = 64% +static int huffmanFrequencies[] = { + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00078fb6, 0x000352a7, 0x00000002, 0x00000001, 0x0002795e, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00049600, 0x000000dd, 0x00018732, 0x0000005a, 0x00000007, 0x00000092, 0x0000000a, 0x00000919, + 0x00002dcf, 0x00002dda, 0x00004dfc, 0x0000039a, 0x000058be, 0x00002d13, 0x00014d8c, 0x00023c60, + 0x0002ddb0, 0x0000d1fc, 0x000078c4, 0x00003ec7, 0x00003113, 0x00006b59, 0x00002499, 0x0000184a, + 0x0000250b, 0x00004e38, 0x000001ca, 0x00000011, 0x00000020, 0x000023da, 0x00000012, 0x00000091, + 0x0000000b, 0x00000b14, 0x0000035d, 0x0000137e, 0x000020c9, 0x00000e11, 0x000004b4, 0x00000737, + 0x000006b8, 0x00001110, 0x000006b3, 0x000000fe, 0x00000f02, 0x00000d73, 0x000005f6, 0x00000be4, + 0x00000d86, 0x0000014d, 0x00000d89, 0x0000129b, 0x00000db3, 0x0000015a, 0x00000167, 0x00000375, + 0x00000028, 0x00000112, 0x00000018, 0x00000678, 0x0000081a, 0x00000677, 0x00000003, 0x00018112, + 0x00000001, 0x000441ee, 0x000124b0, 0x0001fa3f, 0x00026125, 0x0005a411, 0x0000e50f, 0x00011820, + 0x00010f13, 0x0002e723, 0x00003518, 0x00005738, 0x0002cc26, 0x0002a9b7, 0x0002db81, 0x0003b5fa, + 0x000185d2, 0x00001299, 0x00030773, 0x0003920d, 0x000411cd, 0x00018751, 0x00005fbd, 0x000099b0, + 0x00009242, 0x00007cf2, 0x00002809, 0x00005a1d, 0x00000001, 0x00005a1d, 0x00000001, 0x00000001, + + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, +}; + +static huffmanCode_t huffmanCodes[MAX_HUFFMAN_SYMBOLS]; +static huffmanNode_t *huffmanTree = NULL; +static int totalUncompressedLength = 0; +static int totalCompressedLength = 0; +static int maxHuffmanBits = 0; + + +/* +================ +ClearHuffmanFrequencies +================ +*/ +void ClearHuffmanFrequencies( void ) { + int i; + + for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + huffmanFrequencies[i] = 1; + } +} + +/* +================ +InsertHuffmanNode +================ +*/ +huffmanNode_t *InsertHuffmanNode( huffmanNode_t *firstNode, huffmanNode_t *node ) { + huffmanNode_t *n, *lastNode; + + lastNode = NULL; + for ( n = firstNode; n; n = n->next ) { + if ( node->frequency <= n->frequency ) { + break; + } + lastNode = n; + } + if ( lastNode ) { + node->next = lastNode->next; + lastNode->next = node; + } else { + node->next = firstNode; + firstNode = node; + } + return firstNode; +} + +/* +================ +BuildHuffmanCode_r +================ +*/ +void BuildHuffmanCode_r( huffmanNode_t *node, huffmanCode_t code, huffmanCode_t codes[MAX_HUFFMAN_SYMBOLS] ) { + if ( node->symbol == -1 ) { + huffmanCode_t newCode = code; + assert( code.numBits < sizeof( codes[0].bits ) * 8 ); + newCode.numBits++; + if ( code.numBits > maxHuffmanBits ) { + maxHuffmanBits = newCode.numBits; + } + BuildHuffmanCode_r( node->children[0], newCode, codes ); + newCode.bits[code.numBits >> 5] |= 1 << ( code.numBits & 31 ); + BuildHuffmanCode_r( node->children[1], newCode, codes ); + } else { + assert( code.numBits <= sizeof( codes[0].bits ) * 8 ); + codes[node->symbol] = code; + } +} + +/* +================ +FreeHuffmanTree_r +================ +*/ +void FreeHuffmanTree_r( huffmanNode_t *node ) { + if ( node->symbol == -1 ) { + FreeHuffmanTree_r( node->children[0] ); + FreeHuffmanTree_r( node->children[1] ); + } + delete node; +} + +/* +================ +HuffmanHeight_r +================ +*/ +int HuffmanHeight_r( huffmanNode_t *node ) { + if ( node == NULL ) { + return -1; + } + int left = HuffmanHeight_r( node->children[0] ); + int right = HuffmanHeight_r( node->children[1] ); + if ( left > right ) { + return left + 1; + } + return right + 1; +} + +/* +================ +SetupHuffman +================ +*/ +void SetupHuffman( void ) { + int i, height; + huffmanNode_t *firstNode, *node; + huffmanCode_t code; + + firstNode = NULL; + for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + node = new huffmanNode_t; + node->symbol = i; + node->frequency = huffmanFrequencies[i]; + node->next = NULL; + node->children[0] = NULL; + node->children[1] = NULL; + firstNode = InsertHuffmanNode( firstNode, node ); + } + + for( i = 1; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + node = new huffmanNode_t; + node->symbol = -1; + node->frequency = firstNode->frequency + firstNode->next->frequency; + node->next = NULL; + node->children[0] = firstNode; + node->children[1] = firstNode->next; + firstNode = InsertHuffmanNode( firstNode->next->next, node ); + } + + maxHuffmanBits = 0; + memset( &code, 0, sizeof( code ) ); + BuildHuffmanCode_r( firstNode, code, huffmanCodes ); + + huffmanTree = firstNode; + + height = HuffmanHeight_r( firstNode ); + assert( maxHuffmanBits == height ); +} + +/* +================ +ShutdownHuffman +================ +*/ +void ShutdownHuffman( void ) { + if ( huffmanTree ) { + FreeHuffmanTree_r( huffmanTree ); + } +} + +/* +================ +HuffmanCompressText +================ +*/ +int HuffmanCompressText( const char *text, int textLength, byte *compressed, int maxCompressedSize ) { + int i, j; + idBitMsg msg; + + totalUncompressedLength += textLength; + + msg.Init( compressed, maxCompressedSize ); + msg.BeginWriting(); + for ( i = 0; i < textLength; i++ ) { + const huffmanCode_t &code = huffmanCodes[(unsigned char)text[i]]; + for ( j = 0; j < ( code.numBits >> 5 ); j++ ) { + msg.WriteBits( code.bits[j], 32 ); + } + if ( code.numBits & 31 ) { + msg.WriteBits( code.bits[j], code.numBits & 31 ); + } + } + + totalCompressedLength += msg.GetSize(); + + return msg.GetSize(); +} + +/* +================ +HuffmanDecompressText +================ +*/ +int HuffmanDecompressText( char *text, int textLength, const byte *compressed, int compressedSize ) { + int i, bit; + idBitMsg msg; + huffmanNode_t *node; + + msg.Init( compressed, compressedSize ); + msg.SetSize( compressedSize ); + msg.BeginReading(); + for ( i = 0; i < textLength; i++ ) { + node = huffmanTree; + do { + bit = msg.ReadBits( 1 ); + node = node->children[bit]; + } while( node->symbol == -1 ); + text[i] = node->symbol; + } + text[i] = '\0'; + return msg.GetReadCount(); +} + +/* +================ +ListHuffmanFrequencies_f +================ +*/ +void ListHuffmanFrequencies_f( const idCmdArgs &args ) { + int i; + float compression; + compression = !totalUncompressedLength ? 100 : 100 * totalCompressedLength / totalUncompressedLength; + common->Printf( "// compression ratio = %d%%\n", (int)compression ); + common->Printf( "static int huffmanFrequencies[] = {\n" ); + for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i += 8 ) { + common->Printf( "\t0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", + huffmanFrequencies[i+0], huffmanFrequencies[i+1], + huffmanFrequencies[i+2], huffmanFrequencies[i+3], + huffmanFrequencies[i+4], huffmanFrequencies[i+5], + huffmanFrequencies[i+6], huffmanFrequencies[i+7]); + } + common->Printf( "}\n" ); +} + +/* +==================================================================================== + + idDeclFile + +==================================================================================== +*/ + +/* +================ +idDeclFile::idDeclFile +================ +*/ +idDeclFile::idDeclFile( const char *fileName, declType_t defaultType ) { + this->fileName = fileName; + this->defaultType = defaultType; + this->timestamp = 0; + this->checksum = 0; + this->fileSize = 0; + this->numLines = 0; + this->decls = NULL; +} + +/* +================ +idDeclFile::idDeclFile +================ +*/ +idDeclFile::idDeclFile() { + this->fileName = ""; + this->defaultType = DECL_MAX_TYPES; + this->timestamp = 0; + this->checksum = 0; + this->fileSize = 0; + this->numLines = 0; + this->decls = NULL; +} + +/* +================ +idDeclFile::Reload + +ForceReload will cause it to reload even if the timestamp hasn't changed +================ +*/ +void idDeclFile::Reload( bool force ) { + // check for an unchanged timestamp + if ( !force && timestamp != 0 ) { + ID_TIME_T testTimeStamp; + fileSystem->ReadFile( fileName, NULL, &testTimeStamp ); + + if ( testTimeStamp == timestamp ) { + return; + } + } + + // parse the text + LoadAndParse(); +} + +/* +================ +idDeclFile::LoadAndParse + +This is used during both the initial load, and any reloads +================ +*/ +int c_savedMemory = 0; + +int idDeclFile::LoadAndParse() { + int i, numTypes; + idLexer src; + idToken token; + int startMarker; + char * buffer; + int length, size; + int sourceLine; + idStr name; + idDeclLocal *newDecl; + bool reparse; + + // load the text + common->DPrintf( "...loading '%s'\n", fileName.c_str() ); + length = fileSystem->ReadFile( fileName, (void **)&buffer, ×tamp ); + if ( length == -1 ) { + common->FatalError( "couldn't load %s", fileName.c_str() ); + return 0; + } + + if ( !src.LoadMemory( buffer, length, fileName ) ) { + common->Error( "Couldn't parse %s", fileName.c_str() ); + Mem_Free( buffer ); + return 0; + } + + // mark all the defs that were from the last reload of this file + for ( idDeclLocal *decl = decls; decl; decl = decl->nextInFile ) { + decl->redefinedInReload = false; + } + + src.SetFlags( DECL_LEXER_FLAGS ); + + checksum = MD5_BlockChecksum( buffer, length ); + + fileSize = length; + + // scan through, identifying each individual declaration + while( 1 ) { + + startMarker = src.GetFileOffset(); + sourceLine = src.GetLineNum(); + + // parse the decl type name + if ( !src.ReadToken( &token ) ) { + break; + } + + declType_t identifiedType = DECL_MAX_TYPES; + + // get the decl type from the type name + numTypes = declManagerLocal.GetNumDeclTypes(); + for ( i = 0; i < numTypes; i++ ) { + idDeclType *typeInfo = declManagerLocal.GetDeclType( i ); + if ( typeInfo && typeInfo->typeName.Icmp( token ) == 0 ) { + identifiedType = (declType_t) typeInfo->type; + break; + } + } + + if ( i >= numTypes ) { + + if ( token.Icmp( "{" ) == 0 ) { + + // if we ever see an open brace, we somehow missed the [type] prefix + src.Warning( "Missing decl name" ); + src.SkipBracedSection( false ); + continue; + + } else { + + if ( defaultType == DECL_MAX_TYPES ) { + src.Warning( "No type" ); + continue; + } + src.UnreadToken( &token ); + // use the default type + identifiedType = defaultType; + } + } + + // now parse the name + if ( !src.ReadToken( &token ) ) { + src.Warning( "Type without definition at end of file" ); + break; + } + + if ( !token.Icmp( "{" ) ) { + // if we ever see an open brace, we somehow missed the [type] prefix + src.Warning( "Missing decl name" ); + src.SkipBracedSection( false ); + continue; + } + + // FIXME: export decls are only used by the model exporter, they are skipped here for now + if ( identifiedType == DECL_MODELEXPORT ) { + src.SkipBracedSection(); + continue; + } + + name = token; + + // make sure there's a '{' + if ( !src.ReadToken( &token ) ) { + src.Warning( "Type without definition at end of file" ); + break; + } + if ( token != "{" ) { + src.Warning( "Expecting '{' but found '%s'", token.c_str() ); + continue; + } + src.UnreadToken( &token ); + + // now take everything until a matched closing brace + src.SkipBracedSection(); + size = src.GetFileOffset() - startMarker; + + // look it up, possibly getting a newly created default decl + reparse = false; + newDecl = declManagerLocal.FindTypeWithoutParsing( identifiedType, name, false ); + if ( newDecl ) { + // update the existing copy + if ( newDecl->sourceFile != this || newDecl->redefinedInReload ) { + src.Warning( "%s '%s' previously defined at %s:%i", declManagerLocal.GetDeclNameFromType( identifiedType ), + name.c_str(), newDecl->sourceFile->fileName.c_str(), newDecl->sourceLine ); + continue; + } + if ( newDecl->declState != DS_UNPARSED ) { + reparse = true; + } + } else { + // allow it to be created as a default, then add it to the per-file list + newDecl = declManagerLocal.FindTypeWithoutParsing( identifiedType, name, true ); + newDecl->nextInFile = this->decls; + this->decls = newDecl; + } + + newDecl->redefinedInReload = true; + + if ( newDecl->textSource ) { + Mem_Free( newDecl->textSource ); + newDecl->textSource = NULL; + } + + newDecl->SetTextLocal( buffer + startMarker, size ); + newDecl->sourceFile = this; + newDecl->sourceTextOffset = startMarker; + newDecl->sourceTextLength = size; + newDecl->sourceLine = sourceLine; + newDecl->declState = DS_UNPARSED; + + // if it is currently in use, reparse it immedaitely + if ( reparse ) { + newDecl->ParseLocal(); + } + } + + numLines = src.GetLineNum(); + + Mem_Free( buffer ); + + // any defs that weren't redefinedInReload should now be defaulted + for ( idDeclLocal *decl = decls ; decl ; decl = decl->nextInFile ) { + if ( decl->redefinedInReload == false ) { + decl->MakeDefault(); + decl->sourceTextOffset = decl->sourceFile->fileSize; + decl->sourceTextLength = 0; + decl->sourceLine = decl->sourceFile->numLines; + } + } + + return checksum; +} + +/* +==================================================================================== + + idDeclManagerLocal + +==================================================================================== +*/ + +const char *listDeclStrings[] = { "current", "all", "ever", NULL }; + +/* +=================== +idDeclManagerLocal::Init +=================== +*/ +void idDeclManagerLocal::Init( void ) { + + common->Printf( "----- Initializing Decls -----\n" ); + + checksum = 0; + +#ifdef USE_COMPRESSED_DECLS + SetupHuffman(); +#endif + +#ifdef GET_HUFFMAN_FREQUENCIES + ClearHuffmanFrequencies(); +#endif + + // decls used throughout the engine + RegisterDeclType( "table", DECL_TABLE, idDeclAllocator ); + RegisterDeclType( "material", DECL_MATERIAL, idDeclAllocator ); + RegisterDeclType( "skin", DECL_SKIN, idDeclAllocator ); + RegisterDeclType( "sound", DECL_SOUND, idDeclAllocator ); + + RegisterDeclType( "entityDef", DECL_ENTITYDEF, idDeclAllocator ); + RegisterDeclType( "mapDef", DECL_MAPDEF, idDeclAllocator ); + RegisterDeclType( "fx", DECL_FX, idDeclAllocator ); + RegisterDeclType( "particle", DECL_PARTICLE, idDeclAllocator ); + RegisterDeclType( "articulatedFigure", DECL_AF, idDeclAllocator ); + RegisterDeclType( "pda", DECL_PDA, idDeclAllocator ); + RegisterDeclType( "email", DECL_EMAIL, idDeclAllocator ); + RegisterDeclType( "video", DECL_VIDEO, idDeclAllocator ); + RegisterDeclType( "audio", DECL_AUDIO, idDeclAllocator ); + + RegisterDeclFolder( "materials", ".mtr", DECL_MATERIAL ); + RegisterDeclFolder( "skins", ".skin", DECL_SKIN ); + RegisterDeclFolder( "sound", ".sndshd", DECL_SOUND ); + + // add console commands + cmdSystem->AddCommand( "listDecls", ListDecls_f, CMD_FL_SYSTEM, "lists all decls" ); + + cmdSystem->AddCommand( "reloadDecls", ReloadDecls_f, CMD_FL_SYSTEM, "reloads decls" ); + cmdSystem->AddCommand( "touch", TouchDecl_f, CMD_FL_SYSTEM, "touches a decl" ); + + cmdSystem->AddCommand( "listTables", idListDecls_f, CMD_FL_SYSTEM, "lists tables", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listMaterials", idListDecls_f, CMD_FL_SYSTEM, "lists materials", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listSkins", idListDecls_f, CMD_FL_SYSTEM, "lists skins", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listSoundShaders", idListDecls_f, CMD_FL_SYSTEM, "lists sound shaders", idCmdSystem::ArgCompletion_String ); + + cmdSystem->AddCommand( "listEntityDefs", idListDecls_f, CMD_FL_SYSTEM, "lists entity defs", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listFX", idListDecls_f, CMD_FL_SYSTEM, "lists FX systems", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listParticles", idListDecls_f, CMD_FL_SYSTEM, "lists particle systems", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listAF", idListDecls_f, CMD_FL_SYSTEM, "lists articulated figures", idCmdSystem::ArgCompletion_String); + + cmdSystem->AddCommand( "listPDAs", idListDecls_f, CMD_FL_SYSTEM, "lists PDAs", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listEmails", idListDecls_f, CMD_FL_SYSTEM, "lists Emails", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listVideos", idListDecls_f, CMD_FL_SYSTEM, "lists Videos", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand( "listAudios", idListDecls_f, CMD_FL_SYSTEM, "lists Audios", idCmdSystem::ArgCompletion_String ); + + cmdSystem->AddCommand( "printTable", idPrintDecls_f, CMD_FL_SYSTEM, "prints a table", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printMaterial", idPrintDecls_f, CMD_FL_SYSTEM, "prints a material", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printSkin", idPrintDecls_f, CMD_FL_SYSTEM, "prints a skin", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printSoundShader", idPrintDecls_f, CMD_FL_SYSTEM, "prints a sound shader", idCmdSystem::ArgCompletion_Decl ); + + cmdSystem->AddCommand( "printEntityDef", idPrintDecls_f, CMD_FL_SYSTEM, "prints an entity def", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printFX", idPrintDecls_f, CMD_FL_SYSTEM, "prints an FX system", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printParticle", idPrintDecls_f, CMD_FL_SYSTEM, "prints a particle system", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printAF", idPrintDecls_f, CMD_FL_SYSTEM, "prints an articulated figure", idCmdSystem::ArgCompletion_Decl ); + + cmdSystem->AddCommand( "printPDA", idPrintDecls_f, CMD_FL_SYSTEM, "prints an PDA", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printEmail", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Email", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printVideo", idPrintDecls_f, CMD_FL_SYSTEM, "prints a Audio", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "printAudio", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Video", idCmdSystem::ArgCompletion_Decl ); + + cmdSystem->AddCommand( "listHuffmanFrequencies", ListHuffmanFrequencies_f, CMD_FL_SYSTEM, "lists decl text character frequencies" ); + + common->Printf( "------------------------------\n" ); +} + +/* +=================== +idDeclManagerLocal::Shutdown +=================== +*/ +void idDeclManagerLocal::Shutdown( void ) { + int i, j; + idDeclLocal *decl; + + // free decls + for ( i = 0; i < DECL_MAX_TYPES; i++ ) { + for ( j = 0; j < linearLists[i].Num(); j++ ) { + decl = linearLists[i][j]; + if ( decl->self != NULL ) { + decl->self->FreeData(); + delete decl->self; + } + if ( decl->textSource ) { + Mem_Free( decl->textSource ); + decl->textSource = NULL; + } + delete decl; + } + linearLists[i].Clear(); + hashTables[i].Free(); + } + + // free decl files + loadedFiles.DeleteContents( true ); + + // free the decl types and folders + declTypes.DeleteContents( true ); + declFolders.DeleteContents( true ); + +#ifdef USE_COMPRESSED_DECLS + ShutdownHuffman(); +#endif +} + +/* +=================== +idDeclManagerLocal::Reload +=================== +*/ +void idDeclManagerLocal::Reload( bool force ) { + for ( int i = 0; i < loadedFiles.Num(); i++ ) { + loadedFiles[i]->Reload( force ); + } +} + +/* +=================== +idDeclManagerLocal::BeginLevelLoad +=================== +*/ +void idDeclManagerLocal::BeginLevelLoad() { + insideLevelLoad = true; + + // clear all the referencedThisLevel flags and purge all the data + // so the next reference will cause a reparse + for ( int i = 0; i < DECL_MAX_TYPES; i++ ) { + int num = linearLists[i].Num(); + for ( int j = 0 ; j < num ; j++ ) { + idDeclLocal *decl = linearLists[i][j]; + decl->Purge(); + } + } +} + +/* +=================== +idDeclManagerLocal::EndLevelLoad +=================== +*/ +void idDeclManagerLocal::EndLevelLoad() { + insideLevelLoad = false; + + // we don't need to do anything here, but the image manager, model manager, + // and sound sample manager will need to free media that was not referenced +} + +/* +=================== +idDeclManagerLocal::RegisterDeclType +=================== +*/ +void idDeclManagerLocal::RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) { + idDeclType *declType; + + if ( type < declTypes.Num() && declTypes[(int)type] ) { + common->Warning( "idDeclManager::RegisterDeclType: type '%s' already exists", typeName ); + return; + } + + declType = new idDeclType; + declType->typeName = typeName; + declType->type = type; + declType->allocator = allocator; + + if ( (int)type + 1 > declTypes.Num() ) { + declTypes.AssureSize( (int)type + 1, NULL ); + } + declTypes[type] = declType; +} + +/* +=================== +idDeclManagerLocal::RegisterDeclFolder +=================== +*/ +void idDeclManagerLocal::RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) { + int i, j; + idStr fileName; + idDeclFolder *declFolder; + idFileList *fileList; + idDeclFile *df; + + // check whether this folder / extension combination already exists + for ( i = 0; i < declFolders.Num(); i++ ) { + if ( declFolders[i]->folder.Icmp( folder ) == 0 && declFolders[i]->extension.Icmp( extension ) == 0 ) { + break; + } + } + if ( i < declFolders.Num() ) { + declFolder = declFolders[i]; + } else { + declFolder = new idDeclFolder; + declFolder->folder = folder; + declFolder->extension = extension; + declFolder->defaultType = defaultType; + declFolders.Append( declFolder ); + } + + // scan for decl files + fileList = fileSystem->ListFiles( declFolder->folder, declFolder->extension, true ); + + // load and parse decl files + for ( i = 0; i < fileList->GetNumFiles(); i++ ) { + fileName = declFolder->folder + "/" + fileList->GetFile( i ); + + // check whether this file has already been loaded + for ( j = 0; j < loadedFiles.Num(); j++ ) { + if ( fileName.Icmp( loadedFiles[j]->fileName ) == 0 ) { + break; + } + } + if ( j < loadedFiles.Num() ) { + df = loadedFiles[j]; + } else { + df = new idDeclFile( fileName, defaultType ); + loadedFiles.Append( df ); + } + df->LoadAndParse(); + } + + fileSystem->FreeFileList( fileList ); +} + +/* +=================== +idDeclManagerLocal::GetChecksum +=================== +*/ +int idDeclManagerLocal::GetChecksum( void ) const { + int i, j, total, num; + int *checksumData; + + // get the total number of decls + total = 0; + for ( i = 0; i < DECL_MAX_TYPES; i++ ) { + total += linearLists[i].Num(); + } + + checksumData = (int *) _alloca16( total * 2 * sizeof( int ) ); + + total = 0; + for ( i = 0; i < DECL_MAX_TYPES; i++ ) { + declType_t type = (declType_t) i; + + // FIXME: not particularly pretty but PDAs and associated decls are localized and should not be checksummed + if ( type == DECL_PDA || type == DECL_VIDEO || type == DECL_AUDIO || type == DECL_EMAIL ) { + continue; + } + + num = linearLists[i].Num(); + for ( j = 0; j < num; j++ ) { + idDeclLocal *decl = linearLists[i][j]; + + if ( decl->sourceFile == &implicitDecls ) { + continue; + } + + checksumData[total*2+0] = total; + checksumData[total*2+1] = decl->checksum; + total++; + } + } + + LittleRevBytes( checksumData, sizeof(int), total * 2 ); + return MD5_BlockChecksum( checksumData, total * 2 * sizeof( int ) ); +} + +/* +=================== +idDeclManagerLocal::GetNumDeclTypes +=================== +*/ +int idDeclManagerLocal::GetNumDeclTypes( void ) const { + return declTypes.Num(); +} + +/* +=================== +idDeclManagerLocal::GetDeclNameFromType +=================== +*/ +const char * idDeclManagerLocal::GetDeclNameFromType( declType_t type ) const { + int typeIndex = (int)type; + + if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { + common->FatalError( "idDeclManager::GetDeclNameFromType: bad type: %i", typeIndex ); + } + return declTypes[typeIndex]->typeName; +} + +/* +=================== +idDeclManagerLocal::GetDeclTypeFromName +=================== +*/ +declType_t idDeclManagerLocal::GetDeclTypeFromName( const char *typeName ) const { + int i; + + for ( i = 0; i < declTypes.Num(); i++ ) { + if ( declTypes[i] && declTypes[i]->typeName.Icmp( typeName ) == 0 ) { + return (declType_t)declTypes[i]->type; + } + } + return DECL_MAX_TYPES; +} + +/* +================= +idDeclManagerLocal::FindType + +External users will always cause the decl to be parsed before returning +================= +*/ +const idDecl *idDeclManagerLocal::FindType( declType_t type, const char *name, bool makeDefault ) { + idDeclLocal *decl; + + if ( !name || !name[0] ) { + name = "_emptyName"; + //common->Warning( "idDeclManager::FindType: empty %s name", GetDeclType( (int)type )->typeName.c_str() ); + } + + decl = FindTypeWithoutParsing( type, name, makeDefault ); + if ( !decl ) { + return NULL; + } + + decl->AllocateSelf(); + + // if it hasn't been parsed yet, parse it now + if ( decl->declState == DS_UNPARSED ) { + decl->ParseLocal(); + } + + // mark it as referenced + decl->referencedThisLevel = true; + decl->everReferenced = true; + if ( insideLevelLoad ) { + decl->parsedOutsideLevelLoad = false; + } + + return decl->self; +} + +/* +=============== +idDeclManagerLocal::FindDeclWithoutParsing +=============== +*/ +const idDecl* idDeclManagerLocal::FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault) { + idDeclLocal* decl; + decl = FindTypeWithoutParsing(type, name, makeDefault); + if(decl) { + return decl->self; + } + return NULL; +} + +/* +=============== +idDeclManagerLocal::ReloadFile +=============== +*/ +void idDeclManagerLocal::ReloadFile( const char* filename, bool force ) { + for ( int i = 0; i < loadedFiles.Num(); i++ ) { + if(!loadedFiles[i]->fileName.Icmp(filename)) { + checksum ^= loadedFiles[i]->checksum; + loadedFiles[i]->Reload( force ); + checksum ^= loadedFiles[i]->checksum; + } + } +} + +/* +=================== +idDeclManagerLocal::GetNumDecls +=================== +*/ +int idDeclManagerLocal::GetNumDecls( declType_t type ) { + int typeIndex = (int)type; + + if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { + common->FatalError( "idDeclManager::GetNumDecls: bad type: %i", typeIndex ); + } + return linearLists[ typeIndex ].Num(); +} + +/* +=================== +idDeclManagerLocal::DeclByIndex +=================== +*/ +const idDecl *idDeclManagerLocal::DeclByIndex( declType_t type, int index, bool forceParse ) { + int typeIndex = (int)type; + + if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { + common->FatalError( "idDeclManager::DeclByIndex: bad type: %i", typeIndex ); + } + if ( index < 0 || index >= linearLists[ typeIndex ].Num() ) { + common->Error( "idDeclManager::DeclByIndex: out of range" ); + } + idDeclLocal *decl = linearLists[ typeIndex ][ index ]; + + decl->AllocateSelf(); + + if ( forceParse && decl->declState == DS_UNPARSED ) { + decl->ParseLocal(); + } + + return decl->self; +} + +/* +=================== +idDeclManagerLocal::ListType + +list* +Lists decls currently referenced + +list* ever +Lists decls that have been referenced at least once since app launched + +list* all +Lists every decl declared, even if it hasn't been referenced or parsed + +FIXME: alphabetized, wildcards? +=================== +*/ +void idDeclManagerLocal::ListType( const idCmdArgs &args, declType_t type ) { + bool all, ever; + + if ( !idStr::Icmp( args.Argv( 1 ), "all" ) ) { + all = true; + } else { + all = false; + } + if ( !idStr::Icmp( args.Argv( 1 ), "ever" ) ) { + ever = true; + } else { + ever = false; + } + + common->Printf( "--------------------\n" ); + int printed = 0; + int count = linearLists[ (int)type ].Num(); + for ( int i = 0 ; i < count ; i++ ) { + idDeclLocal *decl = linearLists[ (int)type ][ i ]; + + if ( !all && decl->declState == DS_UNPARSED ) { + continue; + } + + if ( !all && !ever && !decl->referencedThisLevel ) { + continue; + } + + if ( decl->referencedThisLevel ) { + common->Printf( "*" ); + } else if ( decl->everReferenced ) { + common->Printf( "." ); + } else { + common->Printf( " " ); + } + if ( decl->declState == DS_DEFAULTED ) { + common->Printf( "D" ); + } else { + common->Printf( " " ); + } + common->Printf( "%4i: ", decl->index ); + printed++; + if ( decl->declState == DS_UNPARSED ) { + // doesn't have any type specific data yet + common->Printf( "%s\n", decl->GetName() ); + } else { + decl->self->List(); + } + } + + common->Printf( "--------------------\n" ); + common->Printf( "%i of %i %s\n", printed, count, declTypes[type]->typeName.c_str() ); +} + +/* +=================== +idDeclManagerLocal::PrintType +=================== +*/ +void idDeclManagerLocal::PrintType( const idCmdArgs &args, declType_t type ) { + // individual decl types may use additional command parameters + if ( args.Argc() < 2 ) { + common->Printf( "USAGE: Print [type specific parms]\n" ); + return; + } + + // look it up, skipping the public path so it won't parse or reference + idDeclLocal *decl = FindTypeWithoutParsing( type, args.Argv( 1 ), false ); + if ( !decl ) { + common->Printf( "%s '%s' not found.\n", declTypes[ type ]->typeName.c_str(), args.Argv( 1 ) ); + return; + } + + // print information common to all decls + common->Printf( "%s %s:\n", declTypes[ type ]->typeName.c_str(), decl->name.c_str() ); + common->Printf( "source: %s:%i\n", decl->sourceFile->fileName.c_str(), decl->sourceLine ); + common->Printf( "----------\n" ); + if ( decl->textSource != NULL ) { + char *declText = (char *)_alloca( decl->textLength + 1 ); + decl->GetText( declText ); + common->Printf( "%s\n", declText ); + } else { + common->Printf( "NO SOURCE\n" ); + } + common->Printf( "----------\n" ); + switch( decl->declState ) { + case DS_UNPARSED: + common->Printf( "Unparsed.\n" ); + break; + case DS_DEFAULTED: + common->Printf( "\n" ); + break; + case DS_PARSED: + common->Printf( "Parsed.\n" ); + break; + } + + if ( decl->referencedThisLevel ) { + common->Printf( "Currently referenced this level.\n" ); + } else if ( decl->everReferenced ) { + common->Printf( "Referenced in a previous level.\n" ); + } else { + common->Printf( "Never referenced.\n" ); + } + + // allow type-specific data to be printed + if ( decl->self != NULL ) { + decl->self->Print(); + } +} + +/* +=================== +idDeclManagerLocal::CreateNewDecl +=================== +*/ +idDecl *idDeclManagerLocal::CreateNewDecl( declType_t type, const char *name, const char *_fileName ) { + int typeIndex = (int)type; + int i, hash; + + if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { + common->FatalError( "idDeclManager::CreateNewDecl: bad type: %i", typeIndex ); + } + + char canonicalName[MAX_STRING_CHARS]; + + MakeNameCanonical( name, canonicalName, sizeof( canonicalName ) ); + + idStr fileName = _fileName; + fileName.BackSlashesToSlashes(); + + // see if it already exists + hash = hashTables[typeIndex].GenerateKey( canonicalName, false ); + for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { + if ( linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) { + linearLists[typeIndex][i]->AllocateSelf(); + return linearLists[typeIndex][i]->self; + } + } + + idDeclFile *sourceFile; + + // find existing source file or create a new one + for ( i = 0; i < loadedFiles.Num(); i++ ) { + if ( loadedFiles[i]->fileName.Icmp( fileName ) == 0 ) { + break; + } + } + if ( i < loadedFiles.Num() ) { + sourceFile = loadedFiles[i]; + } else { + sourceFile = new idDeclFile( fileName, type ); + loadedFiles.Append( sourceFile ); + } + + idDeclLocal *decl = new idDeclLocal; + decl->name = canonicalName; + decl->type = type; + decl->declState = DS_UNPARSED; + decl->AllocateSelf(); + idStr header = declTypes[typeIndex]->typeName; + idStr defaultText = decl->self->DefaultDefinition(); + + + int size = header.Length() + 1 + idStr::Length( canonicalName ) + 1 + defaultText.Length(); + char *declText = ( char * ) _alloca( size + 1 ); + + memcpy( declText, header, header.Length() ); + declText[header.Length()] = ' '; + memcpy( declText + header.Length() + 1, canonicalName, idStr::Length( canonicalName ) ); + declText[header.Length() + 1 + idStr::Length( canonicalName )] = ' '; + memcpy( declText + header.Length() + 1 + idStr::Length( canonicalName ) + 1, defaultText, defaultText.Length() + 1 ); + + decl->SetTextLocal( declText, size ); + decl->sourceFile = sourceFile; + decl->sourceTextOffset = sourceFile->fileSize; + decl->sourceTextLength = 0; + decl->sourceLine = sourceFile->numLines; + + decl->ParseLocal(); + + // add this decl to the source file list + decl->nextInFile = sourceFile->decls; + sourceFile->decls = decl; + + // add it to the hash table and linear list + decl->index = linearLists[typeIndex].Num(); + hashTables[typeIndex].Add( hash, linearLists[typeIndex].Append( decl ) ); + + return decl->self; +} + +/* +=============== +idDeclManagerLocal::RenameDecl +=============== +*/ +bool idDeclManagerLocal::RenameDecl( declType_t type, const char* oldName, const char* newName ) { + + char canonicalOldName[MAX_STRING_CHARS]; + MakeNameCanonical( oldName, canonicalOldName, sizeof( canonicalOldName )); + + char canonicalNewName[MAX_STRING_CHARS]; + MakeNameCanonical( newName, canonicalNewName, sizeof( canonicalNewName ) ); + + idDeclLocal *decl = NULL; + + // make sure it already exists + int typeIndex = (int)type; + int i, hash; + hash = hashTables[typeIndex].GenerateKey( canonicalOldName, false ); + for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { + if ( linearLists[typeIndex][i]->name.Icmp( canonicalOldName ) == 0 ) { + decl = linearLists[typeIndex][i]; + break; + } + } + if(!decl) + return false; + + //if ( !hashTables[(int)type].Get( canonicalOldName, &declPtr ) ) + // return false; + + //decl = *declPtr; + + //Change the name + decl->name = canonicalNewName; + + + // add it to the hash table + //hashTables[(int)decl->type].Set( decl->name, decl ); + int newhash = hashTables[typeIndex].GenerateKey( canonicalNewName, false ); + hashTables[typeIndex].Add( newhash, decl->index ); + + //Remove the old hash item + hashTables[typeIndex].Remove(hash, decl->index); + + return true; +} + +/* +=================== +idDeclManagerLocal::MediaPrint + +This is just used to nicely indent media caching prints +=================== +*/ +void idDeclManagerLocal::MediaPrint( const char *fmt, ... ) { + if ( !decl_show.GetInteger() ) { + return; + } + for ( int i = 0 ; i < indent ; i++ ) { + common->Printf( " " ); + } + va_list argptr; + char buffer[1024]; + va_start (argptr,fmt); + idStr::vsnPrintf( buffer, sizeof(buffer), fmt, argptr ); + va_end (argptr); + buffer[sizeof(buffer)-1] = '\0'; + + common->Printf( "%s", buffer ); +} + +/* +=================== +idDeclManagerLocal::WritePrecacheCommands +=================== +*/ +void idDeclManagerLocal::WritePrecacheCommands( idFile *f ) { + for ( int i = 0; i < declTypes.Num(); i++ ) { + int num; + + if ( declTypes[i] == NULL ) { + continue; + } + + num = linearLists[i].Num(); + + for ( int j = 0 ; j < num ; j++ ) { + idDeclLocal *decl = linearLists[i][j]; + + if ( !decl->referencedThisLevel ) { + continue; + } + + char str[1024]; + sprintf( str, "touch %s %s\n", declTypes[i]->typeName.c_str(), decl->GetName() ); + common->Printf( "%s", str ); + f->Printf( "%s", str ); + } + } +} + +/********************************************************************/ + +const idMaterial *idDeclManagerLocal::FindMaterial( const char *name, bool makeDefault ) { + return static_cast( FindType( DECL_MATERIAL, name, makeDefault ) ); +} + +const idMaterial *idDeclManagerLocal::MaterialByIndex( int index, bool forceParse ) { + return static_cast( DeclByIndex( DECL_MATERIAL, index, forceParse ) ); +} + +/********************************************************************/ + +const idDeclSkin *idDeclManagerLocal::FindSkin( const char *name, bool makeDefault ) { + return static_cast( FindType( DECL_SKIN, name, makeDefault ) ); +} + +const idDeclSkin *idDeclManagerLocal::SkinByIndex( int index, bool forceParse ) { + return static_cast( DeclByIndex( DECL_SKIN, index, forceParse ) ); +} + +/********************************************************************/ + +const idSoundShader *idDeclManagerLocal::FindSound( const char *name, bool makeDefault ) { + return static_cast( FindType( DECL_SOUND, name, makeDefault ) ); +} + +const idSoundShader *idDeclManagerLocal::SoundByIndex( int index, bool forceParse ) { + return static_cast( DeclByIndex( DECL_SOUND, index, forceParse ) ); +} + +/* +=================== +idDeclManagerLocal::MakeNameCanonical +=================== +*/ +void idDeclManagerLocal::MakeNameCanonical( const char *name, char *result, int maxLength ) { + int i, lastDot; + + lastDot = -1; + for ( i = 0; i < maxLength && name[i] != '\0'; i++ ) { + int c = name[i]; + if ( c == '\\' ) { + result[i] = '/'; + } else if ( c == '.' ) { + lastDot = i; + result[i] = c; + } else { + result[i] = idStr::ToLower( c ); + } + } + if ( lastDot != -1 ) { + result[lastDot] = '\0'; + } else { + result[i] = '\0'; + } +} + +/* +================ +idDeclManagerLocal::ListDecls_f +================ +*/ +void idDeclManagerLocal::ListDecls_f( const idCmdArgs &args ) { + int i, j; + int totalDecls = 0; + int totalText = 0; + int totalStructs = 0; + + for ( i = 0; i < declManagerLocal.declTypes.Num(); i++ ) { + int size, num; + + if ( declManagerLocal.declTypes[i] == NULL ) { + continue; + } + + num = declManagerLocal.linearLists[i].Num(); + totalDecls += num; + + size = 0; + for ( j = 0; j < num; j++ ) { + size += declManagerLocal.linearLists[i][j]->Size(); + if ( declManagerLocal.linearLists[i][j]->self != NULL ) { + size += declManagerLocal.linearLists[i][j]->self->Size(); + } + } + totalStructs += size; + + common->Printf( "%4ik %4i %s\n", size >> 10, num, declManagerLocal.declTypes[i]->typeName.c_str() ); + } + + for ( i = 0 ; i < declManagerLocal.loadedFiles.Num() ; i++ ) { + idDeclFile *df = declManagerLocal.loadedFiles[i]; + totalText += df->fileSize; + } + + common->Printf( "%i total decls is %i decl files\n", totalDecls, declManagerLocal.loadedFiles.Num() ); + common->Printf( "%iKB in text, %iKB in structures\n", totalText >> 10, totalStructs >> 10 ); +} + +/* +=================== +idDeclManagerLocal::ReloadDecls_f + +Reload will not find any new files created in the directories, it +will only reload existing files. + +A reload will never cause anything to be purged. +=================== +*/ +void idDeclManagerLocal::ReloadDecls_f( const idCmdArgs &args ) { + bool force; + + if ( !idStr::Icmp( args.Argv( 1 ), "all" ) ) { + force = true; + common->Printf( "reloading all decl files:\n" ); + } else { + force = false; + common->Printf( "reloading changed decl files:\n" ); + } + + soundSystem->SetMute( true ); + + declManagerLocal.Reload( force ); + + soundSystem->SetMute( false ); +} + +/* +=================== +idDeclManagerLocal::TouchDecl_f +=================== +*/ +void idDeclManagerLocal::TouchDecl_f( const idCmdArgs &args ) { + int i; + + if ( args.Argc() != 3 ) { + common->Printf( "usage: touch \n" ); + common->Printf( "valid types: " ); + for ( int i = 0 ; i < declManagerLocal.declTypes.Num() ; i++ ) { + if ( declManagerLocal.declTypes[i] ) { + common->Printf( "%s ", declManagerLocal.declTypes[i]->typeName.c_str() ); + } + } + common->Printf( "\n" ); + return; + } + + for ( i = 0; i < declManagerLocal.declTypes.Num(); i++ ) { + if ( declManagerLocal.declTypes[i] && declManagerLocal.declTypes[i]->typeName.Icmp( args.Argv( 1 ) ) == 0 ) { + break; + } + } + if ( i >= declManagerLocal.declTypes.Num() ) { + common->Printf( "unknown decl type '%s'\n", args.Argv( 1 ) ); + return; + } + + const idDecl *decl = declManagerLocal.FindType( (declType_t)i, args.Argv( 2 ), false ); + if ( !decl ) { + common->Printf( "%s '%s' not found\n", declManagerLocal.declTypes[i]->typeName.c_str(), args.Argv( 2 ) ); + } +} + +/* +=================== +idDeclManagerLocal::FindTypeWithoutParsing + +This finds or creats the decl, but does not cause a parse. This is only used internally. +=================== +*/ +idDeclLocal *idDeclManagerLocal::FindTypeWithoutParsing( declType_t type, const char *name, bool makeDefault ) { + int typeIndex = (int)type; + int i, hash; + + if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { + common->FatalError( "idDeclManager::FindTypeWithoutParsing: bad type: %i", typeIndex ); + } + + char canonicalName[MAX_STRING_CHARS]; + + MakeNameCanonical( name, canonicalName, sizeof( canonicalName ) ); + + // see if it already exists + hash = hashTables[typeIndex].GenerateKey( canonicalName, false ); + for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { + if ( linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) { + // only print these when decl_show is set to 2, because it can be a lot of clutter + if ( decl_show.GetInteger() > 1 ) { + MediaPrint( "referencing %s %s\n", declTypes[ type ]->typeName.c_str(), name ); + } + return linearLists[typeIndex][i]; + } + } + + if ( !makeDefault ) { + return NULL; + } + + idDeclLocal *decl = new idDeclLocal; + decl->self = NULL; + decl->name = canonicalName; + decl->type = type; + decl->declState = DS_UNPARSED; + decl->textSource = NULL; + decl->textLength = 0; + decl->sourceFile = &implicitDecls; + decl->referencedThisLevel = false; + decl->everReferenced = false; + decl->parsedOutsideLevelLoad = !insideLevelLoad; + + // add it to the linear list and hash table + decl->index = linearLists[typeIndex].Num(); + hashTables[typeIndex].Add( hash, linearLists[typeIndex].Append( decl ) ); + + return decl; +} + + +/* +==================================================================================== + + idDeclLocal + +==================================================================================== +*/ + +/* +================= +idDeclLocal::idDeclLocal +================= +*/ +idDeclLocal::idDeclLocal( void ) { + name = "unnamed"; + textSource = NULL; + textLength = 0; + compressedLength = 0; + sourceFile = NULL; + sourceTextOffset = 0; + sourceTextLength = 0; + sourceLine = 0; + checksum = 0; + type = DECL_ENTITYDEF; + index = 0; + declState = DS_UNPARSED; + parsedOutsideLevelLoad = false; + referencedThisLevel = false; + everReferenced = false; + redefinedInReload = false; + nextInFile = NULL; +} + +/* +================= +idDeclLocal::GetName +================= +*/ +const char *idDeclLocal::GetName( void ) const { + return name.c_str(); +} + +/* +================= +idDeclLocal::GetType +================= +*/ +declType_t idDeclLocal::GetType( void ) const { + return type; +} + +/* +================= +idDeclLocal::GetState +================= +*/ +declState_t idDeclLocal::GetState( void ) const { + return declState; +} + +/* +================= +idDeclLocal::IsImplicit +================= +*/ +bool idDeclLocal::IsImplicit( void ) const { + return ( sourceFile == declManagerLocal.GetImplicitDeclFile() ); +} + +/* +================= +idDeclLocal::IsValid +================= +*/ +bool idDeclLocal::IsValid( void ) const { + return ( declState != DS_UNPARSED ); +} + +/* +================= +idDeclLocal::Invalidate +================= +*/ +void idDeclLocal::Invalidate( void ) { + declState = DS_UNPARSED; +} + +/* +================= +idDeclLocal::EnsureNotPurged +================= +*/ +void idDeclLocal::EnsureNotPurged( void ) { + if ( declState == DS_UNPARSED ) { + ParseLocal(); + } +} + +/* +================= +idDeclLocal::Index +================= +*/ +int idDeclLocal::Index( void ) const { + return index; +} + +/* +================= +idDeclLocal::GetLineNum +================= +*/ +int idDeclLocal::GetLineNum( void ) const { + return sourceLine; +} + +/* +================= +idDeclLocal::GetFileName +================= +*/ +const char *idDeclLocal::GetFileName( void ) const { + return ( sourceFile ) ? sourceFile->fileName.c_str() : "*invalid*"; +} + +/* +================= +idDeclLocal::Size +================= +*/ +size_t idDeclLocal::Size( void ) const { + return sizeof( idDecl ) + name.Allocated(); +} + +/* +================= +idDeclLocal::GetText +================= +*/ +void idDeclLocal::GetText( char *text ) const { +#ifdef USE_COMPRESSED_DECLS + HuffmanDecompressText( text, textLength, (byte *)textSource, compressedLength ); +#else + memcpy( text, textSource, textLength+1 ); +#endif +} + +/* +================= +idDeclLocal::GetTextLength +================= +*/ +int idDeclLocal::GetTextLength( void ) const { + return textLength; +} + +/* +================= +idDeclLocal::SetText +================= +*/ +void idDeclLocal::SetText( const char *text ) { + SetTextLocal( text, idStr::Length( text ) ); +} + +/* +================= +idDeclLocal::SetTextLocal +================= +*/ +void idDeclLocal::SetTextLocal( const char *text, const int length ) { + + Mem_Free( textSource ); + + checksum = MD5_BlockChecksum( text, length ); + +#ifdef GET_HUFFMAN_FREQUENCIES + for( int i = 0; i < length; i++ ) { + huffmanFrequencies[((const unsigned char *)text)[i]]++; + } +#endif + +#ifdef USE_COMPRESSED_DECLS + int maxBytesPerCode = ( maxHuffmanBits + 7 ) >> 3; + byte *compressed = (byte *)_alloca( length * maxBytesPerCode ); + compressedLength = HuffmanCompressText( text, length, compressed, length * maxBytesPerCode ); + textSource = (char *)Mem_Alloc( compressedLength ); + memcpy( textSource, compressed, compressedLength ); +#else + compressedLength = length; + textSource = (char *) Mem_Alloc( length + 1 ); + memcpy( textSource, text, length ); + textSource[length] = '\0'; +#endif + textLength = length; +} + +/* +================= +idDeclLocal::ReplaceSourceFileText +================= +*/ +bool idDeclLocal::ReplaceSourceFileText( void ) { + int oldFileLength, newFileLength; + char *buffer; + idFile *file; + + common->Printf( "Writing \'%s\' to \'%s\'...\n", GetName(), GetFileName() ); + + if ( sourceFile == &declManagerLocal.implicitDecls ) { + common->Warning( "Can't save implicit declaration %s.", GetName() ); + return false; + } + + // get length and allocate buffer to hold the file + oldFileLength = sourceFile->fileSize; + newFileLength = oldFileLength - sourceTextLength + textLength; + buffer = (char *) Mem_Alloc( Max( newFileLength, oldFileLength ) ); + + // read original file + if ( sourceFile->fileSize ) { + + file = fileSystem->OpenFileRead( GetFileName() ); + if ( !file ) { + Mem_Free( buffer ); + common->Warning( "Couldn't open %s for reading.", GetFileName() ); + return false; + } + + if ( file->Length() != sourceFile->fileSize || file->Timestamp() != sourceFile->timestamp ) { + Mem_Free( buffer ); + common->Warning( "The file %s has been modified outside of the engine.", GetFileName() ); + return false; + } + + file->Read( buffer, oldFileLength ); + fileSystem->CloseFile( file ); + + if ( MD5_BlockChecksum( buffer, oldFileLength ) != sourceFile->checksum ) { + Mem_Free( buffer ); + common->Warning( "The file %s has been modified outside of the engine.", GetFileName() ); + return false; + } + } + + // insert new text + char *declText = (char *) _alloca( textLength + 1 ); + GetText( declText ); + memmove( buffer + sourceTextOffset + textLength, buffer + sourceTextOffset + sourceTextLength, oldFileLength - sourceTextOffset - sourceTextLength ); + memcpy( buffer + sourceTextOffset, declText, textLength ); + + // write out new file + file = fileSystem->OpenFileWrite( GetFileName(), "fs_devpath" ); + if ( !file ) { + Mem_Free( buffer ); + common->Warning( "Couldn't open %s for writing.", GetFileName() ); + return false; + } + file->Write( buffer, newFileLength ); + fileSystem->CloseFile( file ); + + // set new file size, checksum and timestamp + sourceFile->fileSize = newFileLength; + sourceFile->checksum = MD5_BlockChecksum( buffer, newFileLength ); + fileSystem->ReadFile( GetFileName(), NULL, &sourceFile->timestamp ); + + // free buffer + Mem_Free( buffer ); + + // move all decls in the same file + for ( idDeclLocal *decl = sourceFile->decls; decl; decl = decl->nextInFile ) { + if (decl->sourceTextOffset > sourceTextOffset) { + decl->sourceTextOffset += textLength - sourceTextLength; + } + } + + // set new size of text in source file + sourceTextLength = textLength; + + return true; +} + +/* +================= +idDeclLocal::SourceFileChanged +================= +*/ +bool idDeclLocal::SourceFileChanged( void ) const { + int newLength; + ID_TIME_T newTimestamp; + + if ( sourceFile->fileSize <= 0 ) { + return false; + } + + newLength = fileSystem->ReadFile( GetFileName(), NULL, &newTimestamp ); + + if ( newLength != sourceFile->fileSize || newTimestamp != sourceFile->timestamp ) { + return true; + } + + return false; +} + +/* +================= +idDeclLocal::MakeDefault +================= +*/ +void idDeclLocal::MakeDefault() { + static int recursionLevel; + const char *defaultText; + + declManagerLocal.MediaPrint( "DEFAULTED\n" ); + declState = DS_DEFAULTED; + + AllocateSelf(); + + defaultText = self->DefaultDefinition(); + + // a parse error inside a DefaultDefinition() string could + // cause an infinite loop, but normal default definitions could + // still reference other default definitions, so we can't + // just dump out on the first recursion + if ( ++recursionLevel > 100 ) { + common->FatalError( "idDecl::MakeDefault: bad DefaultDefinition(): %s", defaultText ); + } + + // always free data before parsing + self->FreeData(); + + // parse + self->Parse( defaultText, strlen( defaultText ) ); + + // we could still eventually hit the recursion if we have enough Error() calls inside Parse... + --recursionLevel; +} + +/* +================= +idDeclLocal::SetDefaultText +================= +*/ +bool idDeclLocal::SetDefaultText( void ) { + return false; +} + +/* +================= +idDeclLocal::DefaultDefinition +================= +*/ +const char *idDeclLocal::DefaultDefinition() const { + return "{ }"; +} + +/* +================= +idDeclLocal::Parse +================= +*/ +bool idDeclLocal::Parse( const char *text, const int textLength ) { + idLexer src; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + src.SkipBracedSection( false ); + return true; +} + +/* +================= +idDeclLocal::FreeData +================= +*/ +void idDeclLocal::FreeData() { +} + +/* +================= +idDeclLocal::List +================= +*/ +void idDeclLocal::List() const { + common->Printf( "%s\n", GetName() ); +} + +/* +================= +idDeclLocal::Print +================= +*/ +void idDeclLocal::Print() const { +} + +/* +================= +idDeclLocal::Reload +================= +*/ +void idDeclLocal::Reload( void ) { + this->sourceFile->Reload( false ); +} + +/* +================= +idDeclLocal::AllocateSelf +================= +*/ +void idDeclLocal::AllocateSelf( void ) { + if ( self == NULL ) { + self = declManagerLocal.GetDeclType( (int)type )->allocator(); + self->base = this; + } +} + +/* +================= +idDeclLocal::ParseLocal +================= +*/ +void idDeclLocal::ParseLocal( void ) { + bool generatedDefaultText = false; + + AllocateSelf(); + + // always free data before parsing + self->FreeData(); + + declManagerLocal.MediaPrint( "parsing %s %s\n", declManagerLocal.declTypes[type]->typeName.c_str(), name.c_str() ); + + // if no text source try to generate default text + if ( textSource == NULL ) { + generatedDefaultText = self->SetDefaultText(); + } + + // indent for DEFAULTED or media file references + declManagerLocal.indent++; + + // no text immediately causes a MakeDefault() + if ( textSource == NULL ) { + MakeDefault(); + declManagerLocal.indent--; + return; + } + + declState = DS_PARSED; + + // parse + char *declText = (char *) _alloca( ( GetTextLength() + 1 ) * sizeof( char ) ); + GetText( declText ); + self->Parse( declText, GetTextLength() ); + + // free generated text + if ( generatedDefaultText ) { + Mem_Free( textSource ); + textSource = 0; + textLength = 0; + } + + declManagerLocal.indent--; +} + +/* +================= +idDeclLocal::Purge +================= +*/ +void idDeclLocal::Purge( void ) { + // never purge things that were referenced outside level load, + // like the console and menu graphics + if ( parsedOutsideLevelLoad ) { + return; + } + + referencedThisLevel = false; + MakeDefault(); + + // the next Find() for this will re-parse the real data + declState = DS_UNPARSED; +} + +/* +================= +idDeclLocal::EverReferenced +================= +*/ +bool idDeclLocal::EverReferenced( void ) const { + return everReferenced; +} diff --git a/framework/DeclManager.h b/framework/DeclManager.h new file mode 100644 index 000000000..5e95d519c --- /dev/null +++ b/framework/DeclManager.h @@ -0,0 +1,330 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLMANAGER_H__ +#define __DECLMANAGER_H__ + +/* +=============================================================================== + + Declaration Manager + + All "small text" data types, like materials, sound shaders, fx files, + entity defs, etc. are managed uniformly, allowing reloading, purging, + listing, printing, etc. All "large text" data types that never have more + than one declaration in a given file, like maps, models, AAS files, etc. + are not handled here. + + A decl will never, ever go away once it is created. The manager is + garranteed to always return the same decl pointer for a decl type/name + combination. The index of a decl in the per type list also stays the + same throughout the lifetime of the engine. Although the pointer to + a decl always stays the same, one should never maintain pointers to + data inside decls. The data stored in a decl is not garranteed to stay + the same for more than one engine frame. + + The decl indexes of explicitely defined decls are garrenteed to be + consistent based on the parsed decl files. However, the indexes of + implicit decls may be different based on the order in which levels + are loaded. + + The decl namespaces are separate for each type. Comments for decls go + above the text definition to keep them associated with the proper decl. + + During decl parsing, errors should never be issued, only warnings + followed by a call to MakeDefault(). + +=============================================================================== +*/ + +typedef enum { + DECL_TABLE = 0, + DECL_MATERIAL, + DECL_SKIN, + DECL_SOUND, + DECL_ENTITYDEF, + DECL_MODELDEF, + DECL_FX, + DECL_PARTICLE, + DECL_AF, + DECL_PDA, + DECL_VIDEO, + DECL_AUDIO, + DECL_EMAIL, + DECL_MODELEXPORT, + DECL_MAPDEF, + + // TDM specific DECLs + DECL_XDATA, // External data, for scripts + DECL_TDM_MATINFO, // Material information local to TDM. + DECL_TDM_MISSIONINFO, // Mission information + + DECL_MAX_TYPES = 32 +} declType_t; + +typedef enum { + DS_UNPARSED, + DS_DEFAULTED, // set if a parse failed due to an error, or the lack of any source + DS_PARSED +} declState_t; + +const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated + LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings + LEXFL_ALLOWPATHNAMES | // allow path seperators in names + LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals + LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated + LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring + + +class idDeclBase { +public: + virtual ~idDeclBase() {}; + virtual const char * GetName( void ) const = 0; + virtual declType_t GetType( void ) const = 0; + virtual declState_t GetState( void ) const = 0; + virtual bool IsImplicit( void ) const = 0; + virtual bool IsValid( void ) const = 0; + virtual void Invalidate( void ) = 0; + virtual void Reload( void ) = 0; + virtual void EnsureNotPurged( void ) = 0; + virtual int Index( void ) const = 0; + virtual int GetLineNum( void ) const = 0; + virtual const char * GetFileName( void ) const = 0; + virtual void GetText( char *text ) const = 0; + virtual int GetTextLength( void ) const = 0; + virtual void SetText( const char *text ) = 0; + virtual bool ReplaceSourceFileText( void ) = 0; + virtual bool SourceFileChanged( void ) const = 0; + virtual void MakeDefault( void ) = 0; + virtual bool EverReferenced( void ) const = 0; + virtual bool SetDefaultText( void ) = 0; + virtual const char * DefaultDefinition( void ) const = 0; + virtual bool Parse( const char *text, const int textLength ) = 0; + virtual void FreeData( void ) = 0; + virtual size_t Size( void ) const = 0; + virtual void List( void ) const = 0; + virtual void Print( void ) const = 0; +}; + + +class idDecl { +public: + // The constructor should initialize variables such that + // an immediate call to FreeData() does no harm. + idDecl( void ) { base = NULL; } + virtual ~idDecl( void ) {}; + + // Returns the name of the decl. + const char * GetName( void ) const { return base->GetName(); } + + // Returns the decl type. + declType_t GetType( void ) const { return base->GetType(); } + + // Returns the decl state which is usefull for finding out if a decl defaulted. + declState_t GetState( void ) const { return base->GetState(); } + + // Returns true if the decl was defaulted or the text was created with a call to SetDefaultText. + bool IsImplicit( void ) const { return base->IsImplicit(); } + + // The only way non-manager code can have an invalid decl is if the *ByIndex() + // call was used with forceParse = false to walk the lists to look at names + // without touching the media. + bool IsValid( void ) const { return base->IsValid(); } + + // Sets state back to unparsed. + // Used by decl editors to undo any changes to the decl. + void Invalidate( void ) { base->Invalidate(); } + + // if a pointer might possible be stale from a previous level, + // call this to have it re-parsed + void EnsureNotPurged( void ) { base->EnsureNotPurged(); } + + // Returns the index in the per-type list. + int Index( void ) const { return base->Index(); } + + // Returns the line number the decl starts. + int GetLineNum( void ) const { return base->GetLineNum(); } + + // Returns the name of the file in which the decl is defined. + const char * GetFileName( void ) const { return base->GetFileName(); } + + // Returns the decl text. + void GetText( char *text ) const { base->GetText( text ); } + + // Returns the length of the decl text. + int GetTextLength( void ) const { return base->GetTextLength(); } + + // Sets new decl text. + void SetText( const char *text ) { base->SetText( text ); } + + // Saves out new text for the decl. + // Used by decl editors to replace the decl text in the source file. + bool ReplaceSourceFileText( void ) { return base->ReplaceSourceFileText(); } + + // Returns true if the source file changed since it was loaded and parsed. + bool SourceFileChanged( void ) const { return base->SourceFileChanged(); } + + // Frees data and makes the decl a default. + void MakeDefault( void ) { base->MakeDefault(); } + + // Returns true if the decl was ever referenced. + bool EverReferenced( void ) const { return base->EverReferenced(); } + +public: + // Sets textSource to a default text if necessary. + // This may be overridden to provide a default definition based on the + // decl name. For instance materials may default to an implicit definition + // using a texture with the same name as the decl. + virtual bool SetDefaultText( void ) { return base->SetDefaultText(); } + + // Each declaration type must have a default string that it is guaranteed + // to parse acceptably. When a decl is not explicitly found, is purged, or + // has an error while parsing, MakeDefault() will do a FreeData(), then a + // Parse() with DefaultDefinition(). The defaultDefintion should start with + // an open brace and end with a close brace. + virtual const char * DefaultDefinition( void ) const { return base->DefaultDefinition(); } + + // The manager will have already parsed past the type, name and opening brace. + // All necessary media will be touched before return. + // The manager will have called FreeData() before issuing a Parse(). + // The subclass can call MakeDefault() internally at any point if + // there are parse errors. + virtual bool Parse( const char *text, const int textLength ) { return base->Parse( text, textLength ); } + + // Frees any pointers held by the subclass. This may be called before + // any Parse(), so the constructor must have set sane values. The decl will be + // invalid after issuing this call, but it will always be immediately followed + // by a Parse() + virtual void FreeData( void ) { base->FreeData(); } + + // Returns the size of the decl in memory. + virtual size_t Size( void ) const { return base->Size(); } + + // If this isn't overridden, it will just print the decl name. + // The manager will have printed 7 characters on the line already, + // containing the reference state and index number. + virtual void List( void ) const { base->List(); } + + // The print function will already have dumped the text source + // and common data, subclasses can override this to dump more + // explicit data. + virtual void Print( void ) const { base->Print(); } + +public: + idDeclBase * base; +}; + + +template< class type > +ID_INLINE idDecl *idDeclAllocator( void ) { + return new type; +} + + +class idMaterial; +class idDeclSkin; +class idSoundShader; + +class idDeclManager { +public: + virtual ~idDeclManager( void ) {} + + virtual void Init( void ) = 0; + virtual void Shutdown( void ) = 0; + virtual void Reload( bool force ) = 0; + + virtual void BeginLevelLoad() = 0; + virtual void EndLevelLoad() = 0; + + // Registers a new decl type. + virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) = 0; + + // Registers a new folder with decl files. + virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) = 0; + + // Returns a checksum for all loaded decl text. + virtual int GetChecksum( void ) const = 0; + + // Returns the number of decl types. + virtual int GetNumDeclTypes( void ) const = 0; + + // Returns the type name for a decl type. + virtual const char * GetDeclNameFromType( declType_t type ) const = 0; + + // Returns the decl type for a type name. + virtual declType_t GetDeclTypeFromName( const char *typeName ) const = 0; + + // If makeDefault is true, a default decl of appropriate type will be created + // if an explicit one isn't found. If makeDefault is false, NULL will be returned + // if the decl wasn't explcitly defined. + virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ) = 0; + + virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ) = 0; + + virtual void ReloadFile( const char* filename, bool force ) = 0; + + // Returns the number of decls of the given type. + virtual int GetNumDecls( declType_t type ) = 0; + + // The complete lists of decls can be walked to populate editor browsers. + // If forceParse is set false, you can get the decl to check name / filename / etc. + // without causing it to parse the source and load media. + virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ) = 0; + + // List and print decls. + virtual void ListType( const idCmdArgs &args, declType_t type ) = 0; + virtual void PrintType( const idCmdArgs &args, declType_t type ) = 0; + + // Creates a new default decl of the given type with the given name in + // the given file used by editors to create a new decls. + virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ) = 0; + + // BSM - Added for the material editors rename capabilities + virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ) = 0; + + // When media files are loaded, a reference line can be printed at a + // proper indentation if decl_show is set + virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + + virtual void WritePrecacheCommands( idFile *f ) = 0; + + // Convenience functions for specific types. + virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ) = 0; + virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ) = 0; + virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ) = 0; + + virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ) = 0; + virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ) = 0; + virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ) = 0; +}; + +extern idDeclManager * declManager; + + +template< declType_t type > +ID_INLINE void idListDecls_f( const idCmdArgs &args ) { + declManager->ListType( args, type ); +} + +template< declType_t type > +ID_INLINE void idPrintDecls_f( const idCmdArgs &args ) { + declManager->PrintType( args, type ); +} + +#endif /* !__DECLMANAGER_H__ */ diff --git a/framework/DeclPDA.cpp b/framework/DeclPDA.cpp new file mode 100644 index 000000000..4105ff076 --- /dev/null +++ b/framework/DeclPDA.cpp @@ -0,0 +1,659 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +/* +================= +idDeclPDA::Size +================= +*/ +size_t idDeclPDA::Size( void ) const { + return sizeof( idDeclPDA ); +} + +/* +=============== +idDeclPDA::Print +=============== +*/ +void idDeclPDA::Print( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +=============== +idDeclPDA::List +=============== +*/ +void idDeclPDA::List( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +================ +idDeclPDA::Parse +================ +*/ +bool idDeclPDA::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + // scan through, identifying each individual parameter + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "name") ) { + src.ReadToken( &token ); + pdaName = token; + continue; + } + + if ( !token.Icmp( "fullname") ) { + src.ReadToken( &token ); + fullName = token; + continue; + } + + if ( !token.Icmp( "icon") ) { + src.ReadToken( &token ); + icon = token; + continue; + } + + if ( !token.Icmp( "id") ) { + src.ReadToken( &token ); + id = token; + continue; + } + + if ( !token.Icmp( "post") ) { + src.ReadToken( &token ); + post = token; + continue; + } + + if ( !token.Icmp( "title") ) { + src.ReadToken( &token ); + title = token; + continue; + } + + if ( !token.Icmp( "security") ) { + src.ReadToken( &token ); + security = token; + continue; + } + + if ( !token.Icmp( "pda_email") ) { + src.ReadToken( &token ); + emails.Append( token ); + declManager->FindType(DECL_EMAIL, token); + continue; + } + + if ( !token.Icmp( "pda_audio") ) { + src.ReadToken( &token ); + audios.Append( token ); + declManager->FindType(DECL_AUDIO, token); + continue; + } + + if ( !token.Icmp( "pda_video") ) { + src.ReadToken( &token ); + videos.Append( token ); + declManager->FindType(DECL_VIDEO, token); + continue; + } + + } + + if ( src.HadError() ) { + src.Warning( "PDA decl '%s' had a parse error", GetName() ); + return false; + } + + originalVideos = videos.Num(); + originalEmails = emails.Num(); + return true; +} + +/* +=================== +idDeclPDA::DefaultDefinition +=================== +*/ +const char *idDeclPDA::DefaultDefinition( void ) const { + return + "{\n" + "\t" "name \"default pda\"\n" + "}"; +} + +/* +=================== +idDeclPDA::FreeData +=================== +*/ +void idDeclPDA::FreeData( void ) { + videos.Clear(); + audios.Clear(); + emails.Clear(); + originalEmails = 0; + originalVideos = 0; +} + +/* +================= +idDeclPDA::AddVideo +================= +*/ +void idDeclPDA::AddVideo( const char *name, bool unique ) const { + if ( unique && ( videos.Find( name ) != NULL ) ) { + return; + } + if ( declManager->FindType( DECL_VIDEO, name, false ) == NULL ) { + common->Printf( "Video %s not found\n", name ); + return; + } + videos.Append( name ); +} + +/* +================= +idDeclPDA::AddAudio +================= +*/ +void idDeclPDA::AddAudio( const char *name, bool unique ) const { + if ( unique && ( audios.Find( name ) != NULL ) ) { + return; + } + if ( declManager->FindType( DECL_AUDIO, name, false ) == NULL ) { + common->Printf( "Audio log %s not found\n", name ); + return; + } + audios.Append( name ); +} + +/* +================= +idDeclPDA::AddEmail +================= +*/ +void idDeclPDA::AddEmail( const char *name, bool unique ) const { + if ( unique && ( emails.Find( name ) != NULL ) ) { + return; + } + if ( declManager->FindType( DECL_EMAIL, name, false ) == NULL ) { + common->Printf( "Email %s not found\n", name ); + return; + } + emails.Append( name ); +} + +/* +================= +idDeclPDA::RemoveAddedEmailsAndVideos +================= +*/ +void idDeclPDA::RemoveAddedEmailsAndVideos() const { + int num = emails.Num(); + if ( originalEmails < num ) { + while ( num && num > originalEmails ) { + emails.RemoveIndex( --num ); + } + } + num = videos.Num(); + if ( originalVideos < num ) { + while ( num && num > originalVideos ) { + videos.RemoveIndex( --num ); + } + } +} + +/* +================= +idDeclPDA::SetSecurity +================= +*/ +void idDeclPDA::SetSecurity( const char *sec ) const { + security = sec; +} + +/* +================= +idDeclPDA::GetNumVideos +================= +*/ +const int idDeclPDA::GetNumVideos() const { + return videos.Num(); +} + +/* +================= +idDeclPDA::GetNumAudios +================= +*/ +const int idDeclPDA::GetNumAudios() const { + return audios.Num(); +} + +/* +================= +idDeclPDA::GetNumEmails +================= +*/ +const int idDeclPDA::GetNumEmails() const { + return emails.Num(); +} + +/* +================= +idDeclPDA::GetVideoByIndex +================= +*/ +const idDeclVideo* idDeclPDA::GetVideoByIndex( int index ) const { + if ( index >= 0 && index < videos.Num() ) { + return static_cast< const idDeclVideo* >( declManager->FindType( DECL_VIDEO, videos[index], false ) ); + } + return NULL; +} + +/* +================= +idDeclPDA::GetAudioByIndex +================= +*/ +const idDeclAudio* idDeclPDA::GetAudioByIndex( int index ) const { + if ( index >= 0 && index < audios.Num() ) { + return static_cast< const idDeclAudio* >( declManager->FindType( DECL_AUDIO, audios[index], false ) ); + } + return NULL; +} + +/* +================= +idDeclPDA::GetEmailByIndex +================= +*/ +const idDeclEmail* idDeclPDA::GetEmailByIndex( int index ) const { + if ( index >= 0 && index < emails.Num() ) { + return static_cast< const idDeclEmail* >( declManager->FindType( DECL_EMAIL, emails[index], false ) ); + } + return NULL; +} + +/* +================= +idDeclEmail::Size +================= +*/ +size_t idDeclEmail::Size( void ) const { + return sizeof( idDeclEmail ); +} + +/* +=============== +idDeclEmail::Print +=============== +*/ +void idDeclEmail::Print( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +=============== +idDeclEmail::List +=============== +*/ +void idDeclEmail::List( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +================ +idDeclEmail::Parse +================ +*/ +bool idDeclEmail::Parse( const char *_text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( _text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT | LEXFL_NOFATALERRORS ); + src.SkipUntilString( "{" ); + + text = ""; + // scan through, identifying each individual parameter + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "subject") ) { + src.ReadToken( &token ); + subject = token; + continue; + } + + if ( !token.Icmp( "to") ) { + src.ReadToken( &token ); + to = token; + continue; + } + + if ( !token.Icmp( "from") ) { + src.ReadToken( &token ); + from = token; + continue; + } + + if ( !token.Icmp( "date") ) { + src.ReadToken( &token ); + date = token; + continue; + } + + if ( !token.Icmp( "text") ) { + src.ReadToken( &token ); + if ( token != "{" ) { + src.Warning( "Email decl '%s' had a parse error", GetName() ); + return false; + } + while ( src.ReadToken( &token ) && token != "}" ) { + text += token; + } + continue; + } + + if ( !token.Icmp( "image") ) { + src.ReadToken( &token ); + image = token; + continue; + } + } + + if ( src.HadError() ) { + src.Warning( "Email decl '%s' had a parse error", GetName() ); + return false; + } + return true; +} + +/* +=================== +idDeclEmail::DefaultDefinition +=================== +*/ +const char *idDeclEmail::DefaultDefinition( void ) const { + return + "{\n" + "\t" "{\n" + "\t\t" "to\t5Mail recipient\n" + "\t\t" "subject\t5Nothing\n" + "\t\t" "from\t5No one\n" + "\t" "}\n" + "}"; +} + +/* +=================== +idDeclEmail::FreeData +=================== +*/ +void idDeclEmail::FreeData( void ) { +} + +/* +================= +idDeclVideo::Size +================= +*/ +size_t idDeclVideo::Size( void ) const { + return sizeof( idDeclVideo ); +} + +/* +=============== +idDeclVideo::Print +=============== +*/ +void idDeclVideo::Print( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +=============== +idDeclVideo::List +=============== +*/ +void idDeclVideo::List( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +================ +idDeclVideo::Parse +================ +*/ +bool idDeclVideo::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT | LEXFL_NOFATALERRORS ); + src.SkipUntilString( "{" ); + + // scan through, identifying each individual parameter + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "name") ) { + src.ReadToken( &token ); + videoName = token; + continue; + } + + if ( !token.Icmp( "preview") ) { + src.ReadToken( &token ); + preview = token; + continue; + } + + if ( !token.Icmp( "video") ) { + src.ReadToken( &token ); + video = token; + declManager->FindMaterial( video ); + continue; + } + + if ( !token.Icmp( "info") ) { + src.ReadToken( &token ); + info = token; + continue; + } + + if ( !token.Icmp( "audio") ) { + src.ReadToken( &token ); + audio = token; + declManager->FindSound(audio); + continue; + } + + } + + if ( src.HadError() ) { + src.Warning( "Video decl '%s' had a parse error", GetName() ); + return false; + } + return true; +} + +/* +=================== +idDeclVideo::DefaultDefinition +=================== +*/ +const char *idDeclVideo::DefaultDefinition( void ) const { + return + "{\n" + "\t" "{\n" + "\t\t" "name\t5Default Video\n" + "\t" "}\n" + "}"; +} + +/* +=================== +idDeclVideo::FreeData +=================== +*/ +void idDeclVideo::FreeData( void ) { +} + +/* +================= +idDeclAudio::Size +================= +*/ +size_t idDeclAudio::Size( void ) const { + return sizeof( idDeclAudio ); +} + +/* +=============== +idDeclAudio::Print +=============== +*/ +void idDeclAudio::Print( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +=============== +idDeclAudio::List +=============== +*/ +void idDeclAudio::List( void ) const { + common->Printf( "Implement me\n" ); +} + +/* +================ +idDeclAudio::Parse +================ +*/ +bool idDeclAudio::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT | LEXFL_NOFATALERRORS ); + src.SkipUntilString( "{" ); + + // scan through, identifying each individual parameter + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "name") ) { + src.ReadToken( &token ); + audioName = token; + continue; + } + + if ( !token.Icmp( "audio") ) { + src.ReadToken( &token ); + audio = token; + declManager->FindSound(audio); + continue; + } + + if ( !token.Icmp( "info") ) { + src.ReadToken( &token ); + info = token; + continue; + } + + if ( !token.Icmp( "preview") ) { + src.ReadToken( &token ); + preview = token; + continue; + } + + } + + if ( src.HadError() ) { + src.Warning( "Audio decl '%s' had a parse error", GetName() ); + return false; + } + return true; +} + +/* +=================== +idDeclAudio::DefaultDefinition +=================== +*/ +const char *idDeclAudio::DefaultDefinition( void ) const { + return + "{\n" + "\t" "{\n" + "\t\t" "name\t5Default Audio\n" + "\t" "}\n" + "}"; +} + +/* +=================== +idDeclAudio::FreeData +=================== +*/ +void idDeclAudio::FreeData( void ) { +} diff --git a/framework/DeclPDA.h b/framework/DeclPDA.h new file mode 100644 index 000000000..b27c959bb --- /dev/null +++ b/framework/DeclPDA.h @@ -0,0 +1,158 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLPDA_H__ +#define __DECLPDA_H__ + +/* +=============================================================================== + + idDeclPDA + +=============================================================================== +*/ + + +class idDeclEmail : public idDecl { +public: + idDeclEmail() {} + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + virtual void List( void ) const; + + const char * GetFrom() const { return from; } + const char * GetBody() const { return text; } + const char * GetSubject() const { return subject; } + const char * GetDate() const { return date; } + const char * GetTo() const { return to; } + const char * GetImage() const { return image; } + +private: + idStr text; + idStr subject; + idStr date; + idStr to; + idStr from; + idStr image; +}; + + +class idDeclVideo : public idDecl { +public: + idDeclVideo() {}; + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + virtual void List( void ) const; + + const char * GetRoq() const { return video; } + const char * GetWave() const { return audio; } + const char * GetVideoName() const { return videoName; } + const char * GetInfo() const { return info; } + const char * GetPreview() const { return preview; } + +private: + idStr preview; + idStr video; + idStr videoName; + idStr info; + idStr audio; +}; + + +class idDeclAudio : public idDecl { +public: + idDeclAudio() {}; + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + virtual void List( void ) const; + + const char * GetAudioName() const { return audioName; } + const char * GetWave() const { return audio; } + const char * GetInfo() const { return info; } + const char * GetPreview() const { return preview; } + +private: + idStr audio; + idStr audioName; + idStr info; + idStr preview; +}; + + +class idDeclPDA : public idDecl { +public: + idDeclPDA() { originalEmails = originalVideos = 0; }; + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + virtual void List( void ) const; + + virtual void AddVideo( const char *name, bool unique = true ) const; + virtual void AddAudio( const char *name, bool unique = true ) const; + virtual void AddEmail( const char *name, bool unique = true ) const; + virtual void RemoveAddedEmailsAndVideos() const; + + virtual const int GetNumVideos() const; + virtual const int GetNumAudios() const; + virtual const int GetNumEmails() const; + virtual const idDeclVideo *GetVideoByIndex( int index ) const; + virtual const idDeclAudio *GetAudioByIndex( int index ) const; + virtual const idDeclEmail *GetEmailByIndex( int index ) const; + + virtual void SetSecurity( const char *sec ) const; + + const char * GetPdaName() const { return pdaName; } + const char * GetSecurity() const {return security; } + const char * GetFullName() const { return fullName; } + const char * GetIcon() const { return icon; } + const char * GetPost() const { return post; } + const char * GetID() const { return id; } + const char * GetTitle() const { return title; } + +private: + mutable idStrList videos; + mutable idStrList audios; + mutable idStrList emails; + idStr pdaName; + idStr fullName; + idStr icon; + idStr id; + idStr post; + idStr title; + mutable idStr security; + mutable int originalEmails; + mutable int originalVideos; +}; + +#endif /* !__DECLPDA_H__ */ diff --git a/framework/DeclParticle.cpp b/framework/DeclParticle.cpp new file mode 100644 index 000000000..522bc006c --- /dev/null +++ b/framework/DeclParticle.cpp @@ -0,0 +1,1422 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +struct ParticleParmDesc { + const char *name; + int count; + const char *desc; +}; + +const ParticleParmDesc ParticleDistributionDesc[] = { + { "rect", 3, "" }, + { "cylinder", 4, "" }, + { "sphere", 3, "" } +}; + +const ParticleParmDesc ParticleDirectionDesc[] = { + { "cone", 1, "" }, + { "outward", 1, "" }, +}; + +const ParticleParmDesc ParticleOrientationDesc[] = { + { "view", 0, "" }, + { "aimed", 2, "" }, + { "x", 0, "" }, + { "y", 0, "" }, + { "z", 0, "" } +}; + +const ParticleParmDesc ParticleCustomDesc[] = { + { "standard", 0, "Standard" }, + { "helix", 5, "sizeX Y Z radialSpeed axialSpeed" }, + { "flies", 3, "radialSpeed axialSpeed size" }, + { "orbit", 2, "radius speed"}, + { "drip", 2, "something something" } +}; + +const int CustomParticleCount = sizeof( ParticleCustomDesc ) / sizeof( const ParticleParmDesc ); + +/* +================= +idDeclParticle::Size +================= +*/ +size_t idDeclParticle::Size( void ) const { + return sizeof( idDeclParticle ); +} + +/* +===================== +idDeclParticle::GetStageBounds +===================== +*/ +void idDeclParticle::GetStageBounds( idParticleStage *stage ) { + + stage->bounds.Clear(); + + // this isn't absolutely guaranteed, but it should be close + + particleGen_t g; + + renderEntity_t renderEntity; + memset( &renderEntity, 0, sizeof( renderEntity ) ); + renderEntity.axis = mat3_identity; + + renderView_t renderView; + memset( &renderView, 0, sizeof( renderView ) ); + renderView.viewaxis = mat3_identity; + + g.renderEnt = &renderEntity; + g.renderView = &renderView; + g.origin.Zero(); + g.axis = mat3_identity; + + idRandom steppingRandom; + steppingRandom.SetSeed( 0 ); + + // just step through a lot of possible particles as a representative sampling + for ( int i = 0 ; i < 1000 ; i++ ) { + g.random = g.originalRandom = steppingRandom; + + int maxMsec = stage->particleLife * 1000; + for ( int inCycleTime = 0 ; inCycleTime < maxMsec ; inCycleTime += 16 ) { + + // make sure we get the very last tic, which may make up an extreme edge + if ( inCycleTime + 16 > maxMsec ) { + inCycleTime = maxMsec - 1; + } + + g.frac = (float)inCycleTime / ( stage->particleLife * 1000 ); + g.age = inCycleTime * 0.001f; + + // if the particle doesn't get drawn because it is faded out or beyond a kill region, + // don't increment the verts + + idVec3 origin; + stage->ParticleOrigin( &g, origin ); + stage->bounds.AddPoint( origin ); + } + } + + // find the max size + float maxSize = 0; + + for ( float f = 0; f <= 1.0f; f += 1.0f / 64 ) { + float size = stage->size.Eval( f, steppingRandom ); + float aspect = stage->aspect.Eval( f, steppingRandom ); + if ( aspect > 1 ) { + size *= aspect; + } + if ( size > maxSize ) { + maxSize = size; + } + } + + maxSize += 8; // just for good measure + // users can specify a per-stage bounds expansion to handle odd cases + stage->bounds.ExpandSelf( maxSize + stage->boundsExpansion ); +} + +/* +================ +idDeclParticle::ParseParms + +Parses a variable length list of parms on one line +================ +*/ +void idDeclParticle::ParseParms( idLexer &src, float *parms, int maxParms ) { + idToken token; + + memset( parms, 0, maxParms * sizeof( *parms ) ); + int count = 0; + while( 1 ) { + if ( !src.ReadTokenOnLine( &token ) ) { + return; + } + if ( count == maxParms ) { + src.Error( "too many parms on line" ); + return; + } + token.StripQuotes(); + parms[count] = atof( token ); + count++; + } +} + +/* +================ +idDeclParticle::ParseParametric +================ +*/ +void idDeclParticle::ParseParametric( idLexer &src, idParticleParm *parm ) { + idToken token; + + parm->table = NULL; + parm->from = parm->to = 0.0f; + + if ( !src.ReadToken( &token ) ) { + src.Error( "not enough parameters" ); + return; + } + + if ( token.IsNumeric() ) { + // can have a to + 2nd parm + parm->from = parm->to = atof( token ); + if ( src.ReadToken( &token ) ) { + if ( !token.Icmp( "to" ) ) { + if ( !src.ReadToken( &token ) ) { + src.Error( "missing second parameter" ); + return; + } + parm->to = atof( token ); + } else { + src.UnreadToken( &token ); + } + } + } else { + // table + parm->table = static_cast( declManager->FindType( DECL_TABLE, token, false ) ); + } + +} + +/* +================ +idDeclParticle::ParseParticleStage +================ +*/ +idParticleStage *idDeclParticle::ParseParticleStage( idLexer &src ) { + idToken token; + + idParticleStage *stage = new idParticleStage; + stage->Default(); + + while (1) { + if ( src.HadError() ) { + break; + } + if ( !src.ReadToken( &token ) ) { + break; + } + if ( !token.Icmp( "}" ) ) { + break; + } + if ( !token.Icmp( "material" ) ) { + src.ReadToken( &token ); + stage->material = declManager->FindMaterial( token.c_str() ); + continue; + } + if ( !token.Icmp( "count" ) ) { + stage->totalParticles = src.ParseInt(); + continue; + } + if ( !token.Icmp( "time" ) ) { + stage->particleLife = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "cycles" ) ) { + stage->cycles = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "timeOffset" ) ) { + stage->timeOffset = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "deadTime" ) ) { + stage->deadTime = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "randomDistribution" ) ) { + stage->randomDistribution = src.ParseBool(); + continue; + } + if ( !token.Icmp( "bunching" ) ) { + stage->spawnBunching = src.ParseFloat(); + continue; + } + + if ( !token.Icmp( "distribution" ) ) { + src.ReadToken( &token ); + if ( !token.Icmp( "rect" ) ) { + stage->distributionType = PDIST_RECT; + } else if ( !token.Icmp( "cylinder" ) ) { + stage->distributionType = PDIST_CYLINDER; + } else if ( !token.Icmp( "sphere" ) ) { + stage->distributionType = PDIST_SPHERE; + } else { + src.Error( "bad distribution type: %s\n", token.c_str() ); + } + ParseParms( src, stage->distributionParms, sizeof( stage->distributionParms ) / sizeof( stage->distributionParms[0] ) ); + continue; + } + + if ( !token.Icmp( "direction" ) ) { + src.ReadToken( &token ); + if ( !token.Icmp( "cone" ) ) { + stage->directionType = PDIR_CONE; + } else if ( !token.Icmp( "outward" ) ) { + stage->directionType = PDIR_OUTWARD; + } else { + src.Error( "bad direction type: %s\n", token.c_str() ); + } + ParseParms( src, stage->directionParms, sizeof( stage->directionParms ) / sizeof( stage->directionParms[0] ) ); + continue; + } + + if ( !token.Icmp( "orientation" ) ) { + src.ReadToken( &token ); + if ( !token.Icmp( "view" ) ) { + stage->orientation = POR_VIEW; + } else if ( !token.Icmp( "aimed" ) ) { + stage->orientation = POR_AIMED; + } else if ( !token.Icmp( "x" ) ) { + stage->orientation = POR_X; + } else if ( !token.Icmp( "y" ) ) { + stage->orientation = POR_Y; + } else if ( !token.Icmp( "z" ) ) { + stage->orientation = POR_Z; + } else { + src.Error( "bad orientation type: %s\n", token.c_str() ); + } + ParseParms( src, stage->orientationParms, sizeof( stage->orientationParms ) / sizeof( stage->orientationParms[0] ) ); + continue; + } + + if ( !token.Icmp( "customPath" ) ) { + src.ReadToken( &token ); + if ( !token.Icmp( "standard" ) ) { + stage->customPathType = PPATH_STANDARD; + } else if ( !token.Icmp( "helix" ) ) { + stage->customPathType = PPATH_HELIX; + } else if ( !token.Icmp( "flies" ) ) { + stage->customPathType = PPATH_FLIES; + } else if ( !token.Icmp( "spherical" ) ) { + stage->customPathType = PPATH_ORBIT; + } else { + src.Error( "bad path type: %s\n", token.c_str() ); + } + ParseParms( src, stage->customPathParms, sizeof( stage->customPathParms ) / sizeof( stage->customPathParms[0] ) ); + continue; + } + + if ( !token.Icmp( "speed" ) ) { + ParseParametric( src, &stage->speed ); + continue; + } + if ( !token.Icmp( "rotation" ) ) { + ParseParametric( src, &stage->rotationSpeed ); + continue; + } + if ( !token.Icmp( "angle" ) ) { + stage->initialAngle = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "entityColor" ) ) { + stage->entityColor = src.ParseBool(); + continue; + } + if ( !token.Icmp( "size" ) ) { + ParseParametric( src, &stage->size ); + continue; + } + if ( !token.Icmp( "aspect" ) ) { + ParseParametric( src, &stage->aspect ); + continue; + } + if ( !token.Icmp( "fadeIn" ) ) { + stage->fadeInFraction = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "fadeOut" ) ) { + stage->fadeOutFraction = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "fadeIndex" ) ) { + stage->fadeIndexFraction = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "color" ) ) { + stage->color[0] = src.ParseFloat(); + stage->color[1] = src.ParseFloat(); + stage->color[2] = src.ParseFloat(); + stage->color[3] = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "fadeColor" ) ) { + stage->fadeColor[0] = src.ParseFloat(); + stage->fadeColor[1] = src.ParseFloat(); + stage->fadeColor[2] = src.ParseFloat(); + stage->fadeColor[3] = src.ParseFloat(); + continue; + } + if ( !token.Icmp("offset" ) ) { + stage->offset[0] = src.ParseFloat(); + stage->offset[1] = src.ParseFloat(); + stage->offset[2] = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "animationFrames" ) ) { + stage->animationFrames = src.ParseInt(); + continue; + } + if ( !token.Icmp( "animationRate" ) ) { + stage->animationRate = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "boundsExpansion" ) ) { + stage->boundsExpansion = src.ParseFloat(); + continue; + } + if ( !token.Icmp( "gravity" ) ) { + src.ReadToken( &token ); + if ( !token.Icmp( "world" ) ) { + stage->worldGravity = true; + } else { + src.UnreadToken( &token ); + } + stage->gravity = src.ParseFloat(); + continue; + } + + src.Error( "unknown token %s\n", token.c_str() ); + } + + // derive values + stage->cycleMsec = ( stage->particleLife + stage->deadTime ) * 1000; + + return stage; +} + +/* +================ +idDeclParticle::Parse +================ +*/ +bool idDeclParticle::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + depthHack = 0.0f; + + while (1) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + + if ( !token.Icmp( "{" ) ) { + idParticleStage *stage = ParseParticleStage( src ); + if ( !stage ) { + src.Warning( "Particle stage parse failed" ); + MakeDefault(); + return false; + } + stages.Append( stage ); + continue; + } + + if ( !token.Icmp( "depthHack" ) ) { + depthHack = src.ParseFloat(); + continue; + } + + src.Warning( "bad token %s", token.c_str() ); + MakeDefault(); + return false; + } + + // + // calculate the bounds + // + bounds.Clear(); + for( int i = 0; i < stages.Num(); i++ ) { + GetStageBounds( stages[i] ); + bounds.AddBounds( stages[i]->bounds ); + } + + if ( bounds.GetVolume() <= 0.1f ) { + bounds = idBounds( vec3_origin ).Expand( 8.0f ); + } + + return true; +} + +/* +================ +idDeclParticle::FreeData +================ +*/ +void idDeclParticle::FreeData( void ) { + stages.DeleteContents( true ); +} + +/* +================ +idDeclParticle::DefaultDefinition +================ +*/ +const char *idDeclParticle::DefaultDefinition( void ) const { + return + "{\n" + "\t" "{\n" + "\t\t" "material\t_default\n" + "\t\t" "count\t20\n" + "\t\t" "time\t\t1.0\n" + "\t" "}\n" + "}"; +} + +/* +================ +idDeclParticle::WriteParticleParm +================ +*/ +void idDeclParticle::WriteParticleParm( idFile *f, idParticleParm *parm, const char *name ) { + + f->WriteFloatString( "\t\t%s\t\t\t\t ", name ); + if ( parm->table ) { + f->WriteFloatString( "%s\n", parm->table->GetName() ); + } else { + f->WriteFloatString( "\"%.3f\" ", parm->from ); + if ( parm->from == parm->to ) { + f->WriteFloatString( "\n" ); + } else { + f->WriteFloatString( " to \"%.3f\"\n", parm->to ); + } + } +} + +/* +================ +idDeclParticle::WriteStage +================ +*/ +void idDeclParticle::WriteStage( idFile *f, idParticleStage *stage ) { + + int i; + + f->WriteFloatString( "\t{\n" ); + f->WriteFloatString( "\t\tcount\t\t\t\t%i\n", stage->totalParticles ); + f->WriteFloatString( "\t\tmaterial\t\t\t%s\n", stage->material->GetName() ); + if ( stage->animationFrames ) { + f->WriteFloatString( "\t\tanimationFrames \t%i\n", stage->animationFrames ); + } + if ( stage->animationRate ) { + f->WriteFloatString( "\t\tanimationRate \t\t%.3f\n", stage->animationRate ); + } + f->WriteFloatString( "\t\ttime\t\t\t\t%.3f\n", stage->particleLife ); + f->WriteFloatString( "\t\tcycles\t\t\t\t%.3f\n", stage->cycles ); + if ( stage->timeOffset ) { + f->WriteFloatString( "\t\ttimeOffset\t\t\t%.3f\n", stage->timeOffset ); + } + if ( stage->deadTime ) { + f->WriteFloatString( "\t\tdeadTime\t\t\t%.3f\n", stage->deadTime ); + } + f->WriteFloatString( "\t\tbunching\t\t\t%.3f\n", stage->spawnBunching ); + + f->WriteFloatString( "\t\tdistribution\t\t%s ", ParticleDistributionDesc[stage->distributionType].name ); + for ( i = 0; i < ParticleDistributionDesc[stage->distributionType].count; i++ ) { + f->WriteFloatString( "%.3f ", stage->distributionParms[i] ); + } + f->WriteFloatString( "\n" ); + + f->WriteFloatString( "\t\tdirection\t\t\t%s ", ParticleDirectionDesc[stage->directionType].name ); + for ( i = 0; i < ParticleDirectionDesc[stage->directionType].count; i++ ) { + f->WriteFloatString( "\"%.3f\" ", stage->directionParms[i] ); + } + f->WriteFloatString( "\n" ); + + f->WriteFloatString( "\t\torientation\t\t\t%s ", ParticleOrientationDesc[stage->orientation].name ); + for ( i = 0; i < ParticleOrientationDesc[stage->orientation].count; i++ ) { + f->WriteFloatString( "%.3f ", stage->orientationParms[i] ); + } + f->WriteFloatString( "\n" ); + + if ( stage->customPathType != PPATH_STANDARD ) { + f->WriteFloatString( "\t\tcustomPath %s ", ParticleCustomDesc[stage->customPathType].name ); + for ( i = 0; i < ParticleCustomDesc[stage->customPathType].count; i++ ) { + f->WriteFloatString( "%.3f ", stage->customPathParms[i] ); + } + f->WriteFloatString( "\n" ); + } + + if ( stage->entityColor ) { + f->WriteFloatString( "\t\tentityColor\t\t\t1\n" ); + } + + WriteParticleParm( f, &stage->speed, "speed" ); + WriteParticleParm( f, &stage->size, "size" ); + WriteParticleParm( f, &stage->aspect, "aspect" ); + + if ( stage->rotationSpeed.from ) { + WriteParticleParm( f, &stage->rotationSpeed, "rotation" ); + } + + if ( stage->initialAngle ) { + f->WriteFloatString( "\t\tangle\t\t\t\t%.3f\n", stage->initialAngle ); + } + + f->WriteFloatString( "\t\trandomDistribution\t\t\t\t%i\n", static_cast( stage->randomDistribution ) ); + f->WriteFloatString( "\t\tboundsExpansion\t\t\t\t%.3f\n", stage->boundsExpansion ); + + + f->WriteFloatString( "\t\tfadeIn\t\t\t\t%.3f\n", stage->fadeInFraction ); + f->WriteFloatString( "\t\tfadeOut\t\t\t\t%.3f\n", stage->fadeOutFraction ); + f->WriteFloatString( "\t\tfadeIndex\t\t\t\t%.3f\n", stage->fadeIndexFraction ); + + f->WriteFloatString( "\t\tcolor \t\t\t\t%.3f %.3f %.3f %.3f\n", stage->color.x, stage->color.y, stage->color.z, stage->color.w ); + f->WriteFloatString( "\t\tfadeColor \t\t\t%.3f %.3f %.3f %.3f\n", stage->fadeColor.x, stage->fadeColor.y, stage->fadeColor.z, stage->fadeColor.w ); + + f->WriteFloatString( "\t\toffset \t\t\t\t%.3f %.3f %.3f\n", stage->offset.x, stage->offset.y, stage->offset.z ); + f->WriteFloatString( "\t\tgravity \t\t\t" ); + if ( stage->worldGravity ) { + f->WriteFloatString( "world " ); + } + f->WriteFloatString( "%.3f\n", stage->gravity ); + f->WriteFloatString( "\t}\n" ); +} + +/* +================ +idDeclParticle::RebuildTextSource +================ +*/ +bool idDeclParticle::RebuildTextSource( void ) { + idFile_Memory f; + + f.WriteFloatString("\n\n/*\n" + "\tGenerated by the Particle Editor.\n" + "\tTo use the particle editor, launch the game and type 'editParticles' on the console.\n" + "*/\n" ); + + f.WriteFloatString( "particle %s {\n", GetName() ); + + if ( depthHack ) { + f.WriteFloatString( "\tdepthHack\t%f\n", depthHack ); + } + + for ( int i = 0; i < stages.Num(); i++ ) { + WriteStage( &f, stages[i] ); + } + + f.WriteFloatString( "}" ); + + SetText( f.GetDataPtr() ); + + return true; +} + +/* +================ +idDeclParticle::Save +================ +*/ +bool idDeclParticle::Save( const char *fileName ) { + RebuildTextSource(); + if ( fileName ) { + declManager->CreateNewDecl( DECL_PARTICLE, GetName(), fileName ); + } + ReplaceSourceFileText(); + return true; +} + +/* +==================================================================================== + +idParticleParm + +==================================================================================== +*/ + +float idParticleParm::Eval( float frac, idRandom &rand ) const { + if ( table ) { + return table->TableLookup( frac ); + } + return from + frac * ( to - from ); +} + +float idParticleParm::Integrate( float frac, idRandom &rand ) const { + if ( table ) { + common->Printf( "idParticleParm::Integrate: can't integrate tables\n" ); + return 0; + } + return ( from + frac * ( to - from ) * 0.5f ) * frac; +} + +/* +==================================================================================== + +idParticleStage + +==================================================================================== +*/ + +/* +================ +idParticleStage::idParticleStage +================ +*/ +idParticleStage::idParticleStage( void ) { + material = NULL; + totalParticles = 0; + cycles = 0.0f; + cycleMsec = 0; + spawnBunching = 0.0f; + particleLife = 0.0f; + timeOffset = 0.0f; + deadTime = 0.0f; + distributionType = PDIST_RECT; + distributionParms[0] = distributionParms[1] = distributionParms[2] = distributionParms[3] = 0.0f; + directionType = PDIR_CONE; + directionParms[0] = directionParms[1] = directionParms[2] = directionParms[3] = 0.0f; + // idParticleParm speed; + gravity = 0.0f; + worldGravity = false; + customPathType = PPATH_STANDARD; + customPathParms[0] = customPathParms[1] = customPathParms[2] = customPathParms[3] = 0.0f; + customPathParms[4] = customPathParms[5] = customPathParms[6] = customPathParms[7] = 0.0f; + offset.Zero(); + animationFrames = 0; + animationRate = 0.0f; + randomDistribution = true; + entityColor = false; + initialAngle = 0.0f; + // idParticleParm rotationSpeed; + orientation = POR_VIEW; + orientationParms[0] = orientationParms[1] = orientationParms[2] = orientationParms[3] = 0.0f; + // idParticleParm size + // idParticleParm aspect + color.Zero(); + fadeColor.Zero(); + fadeInFraction = 0.0f; + fadeOutFraction = 0.0f; + fadeIndexFraction = 0.0f; + hidden = false; + boundsExpansion = 0.0f; + bounds.Clear(); +} + +/* +================ +idParticleStage::Default + +Sets the stage to a default state +================ +*/ +void idParticleStage::Default() { + material = declManager->FindMaterial( "_default" ); + totalParticles = 100; + spawnBunching = 1.0f; + particleLife = 1.5f; + timeOffset = 0.0f; + deadTime = 0.0f; + distributionType = PDIST_RECT; + distributionParms[0] = 8.0f; + distributionParms[1] = 8.0f; + distributionParms[2] = 8.0f; + distributionParms[3] = 0.0f; + directionType = PDIR_CONE; + directionParms[0] = 90.0f; + directionParms[1] = 0.0f; + directionParms[2] = 0.0f; + directionParms[3] = 0.0f; + orientation = POR_VIEW; + orientationParms[0] = 0.0f; + orientationParms[1] = 0.0f; + orientationParms[2] = 0.0f; + orientationParms[3] = 0.0f; + speed.from = 150.0f; + speed.to = 150.0f; + speed.table = NULL; + gravity = 1.0f; + worldGravity = false; + customPathType = PPATH_STANDARD; + customPathParms[0] = 0.0f; + customPathParms[1] = 0.0f; + customPathParms[2] = 0.0f; + customPathParms[3] = 0.0f; + customPathParms[4] = 0.0f; + customPathParms[5] = 0.0f; + customPathParms[6] = 0.0f; + customPathParms[7] = 0.0f; + offset.Zero(); + animationFrames = 0; + animationRate = 0.0f; + initialAngle = 0.0f; + rotationSpeed.from = 0.0f; + rotationSpeed.to = 0.0f; + rotationSpeed.table = NULL; + size.from = 4.0f; + size.to = 4.0f; + size.table = NULL; + aspect.from = 1.0f; + aspect.to = 1.0f; + aspect.table = NULL; + color.x = 1.0f; + color.y = 1.0f; + color.z = 1.0f; + color.w = 1.0f; + fadeColor.x = 0.0f; + fadeColor.y = 0.0f; + fadeColor.z = 0.0f; + fadeColor.w = 0.0f; + fadeInFraction = 0.1f; + fadeOutFraction = 0.25f; + fadeIndexFraction = 0.0f; + boundsExpansion = 0.0f; + randomDistribution = true; + entityColor = false; + cycleMsec = ( particleLife + deadTime ) * 1000; +} + +/* +================ +idParticleStage::NumQuadsPerParticle + +includes trails and cross faded animations +================ +*/ +int idParticleStage::NumQuadsPerParticle() const { + int count = 1; + + if ( orientation == POR_AIMED ) { + int trails = idMath::Ftoi( orientationParms[0] ); + // each trail stage will add an extra quad + count *= ( 1 + trails ); + } + + // if we are doing strip-animation, we need to double the number and cross fade them + if ( animationFrames > 1 ) { + count *= 2; + } + + return count; +} + +/* +=============== +idParticleStage::ParticleOrigin +=============== +*/ +void idParticleStage::ParticleOrigin( particleGen_t *g, idVec3 &origin ) const { + if ( customPathType == PPATH_STANDARD ) { + // + // find intial origin distribution + // + float radiusSqr, angle1, angle2; + + switch( distributionType ) { + case PDIST_RECT: { // ( sizeX sizeY sizeZ ) + origin[0] = ( ( randomDistribution ) ? g->random.CRandomFloat() : 1.0f ) * distributionParms[0]; + origin[1] = ( ( randomDistribution ) ? g->random.CRandomFloat() : 1.0f ) * distributionParms[1]; + origin[2] = ( ( randomDistribution ) ? g->random.CRandomFloat() : 1.0f ) * distributionParms[2]; + break; + } + case PDIST_CYLINDER: { // ( sizeX sizeY sizeZ ringFraction ) + angle1 = ( ( randomDistribution ) ? g->random.CRandomFloat() : 1.0f ) * idMath::TWO_PI; + + idMath::SinCos16( angle1, origin[0], origin[1] ); + origin[2] = ( ( randomDistribution ) ? g->random.CRandomFloat() : 1.0f ); + + // reproject points that are inside the ringFraction to the outer band + if ( distributionParms[3] > 0.0f ) { + radiusSqr = origin[0] * origin[0] + origin[1] * origin[1]; + if ( radiusSqr < distributionParms[3] * distributionParms[3] ) { + // if we are inside the inner reject zone, rescale to put it out into the good zone + float f = sqrt( radiusSqr ) / distributionParms[3]; + float invf = 1.0f / f; + float newRadius = distributionParms[3] + f * ( 1.0f - distributionParms[3] ); + float rescale = invf * newRadius; + + origin[0] *= rescale; + origin[1] *= rescale; + } + } + origin[0] *= distributionParms[0]; + origin[1] *= distributionParms[1]; + origin[2] *= distributionParms[2]; + break; + } + case PDIST_SPHERE: { // ( sizeX sizeY sizeZ ringFraction ) + // iterating with rejection is the only way to get an even distribution over a sphere + if ( randomDistribution ) { + do { + origin[0] = g->random.CRandomFloat(); + origin[1] = g->random.CRandomFloat(); + origin[2] = g->random.CRandomFloat(); + radiusSqr = origin[0] * origin[0] + origin[1] * origin[1] + origin[2] * origin[2]; + } while( radiusSqr > 1.0f ); + } else { + origin.Set( 1.0f, 1.0f, 1.0f ); + radiusSqr = 3.0f; + } + + if ( distributionParms[3] > 0.0f ) { + // we could iterate until we got something that also satisfied ringFraction, + // but for narrow rings that could be a lot of work, so reproject inside points instead + if ( radiusSqr < distributionParms[3] * distributionParms[3] ) { + // if we are inside the inner reject zone, rescale to put it out into the good zone + float f = sqrt( radiusSqr ) / distributionParms[3]; + float invf = 1.0f / f; + float newRadius = distributionParms[3] + f * ( 1.0f - distributionParms[3] ); + float rescale = invf * newRadius; + + origin[0] *= rescale; + origin[1] *= rescale; + origin[2] *= rescale; + } + } + origin[0] *= distributionParms[0]; + origin[1] *= distributionParms[1]; + origin[2] *= distributionParms[2]; + break; + } + } + + // offset will effect all particle origin types + // add this before the velocity and gravity additions + origin += offset; + + // + // add the velocity over time + // + idVec3 dir; + + switch( directionType ) { + case PDIR_CONE: { + // angle is the full angle, so 360 degrees is any spherical direction + angle1 = g->random.CRandomFloat() * directionParms[0] * idMath::M_DEG2RAD; + angle2 = g->random.CRandomFloat() * idMath::PI; + + float s1, c1, s2, c2; + idMath::SinCos16( angle1, s1, c1 ); + idMath::SinCos16( angle2, s2, c2 ); + + dir[0] = s1 * c2; + dir[1] = s1 * s2; + dir[2] = c1; + break; + } + case PDIR_OUTWARD: { + dir = origin; + dir.Normalize(); + dir[2] += directionParms[0]; + break; + } + } + + // add speed + float iSpeed = speed.Integrate( g->frac, g->random ); + origin += dir * iSpeed * particleLife; + + } else { + // + // custom paths completely override both the origin and velocity calculations, but still + // use the standard gravity + // + float angle1, angle2, speed1, speed2; + switch( customPathType ) { + case PPATH_HELIX: { // ( sizeX sizeY sizeZ radialSpeed axialSpeed ) + speed1 = g->random.CRandomFloat(); + speed2 = g->random.CRandomFloat(); + angle1 = g->random.RandomFloat() * idMath::TWO_PI + customPathParms[3] * speed1 * g->age; + + float s1, c1; + idMath::SinCos16( angle1, s1, c1 ); + + origin[0] = c1 * customPathParms[0]; + origin[1] = s1 * customPathParms[1]; + origin[2] = g->random.RandomFloat() * customPathParms[2] + customPathParms[4] * speed2 * g->age; + break; + } + case PPATH_FLIES: { // ( radialSpeed axialSpeed size ) + speed1 = idMath::ClampFloat( 0.4f, 1.0f, g->random.CRandomFloat() ); + speed2 = idMath::ClampFloat( 0.4f, 1.0f, g->random.CRandomFloat() ); + angle1 = g->random.RandomFloat() * idMath::PI * 2 + customPathParms[0] * speed1 * g->age; + angle2 = g->random.RandomFloat() * idMath::PI * 2 + customPathParms[1] * speed1 * g->age; + + float s1, c1, s2, c2; + idMath::SinCos16( angle1, s1, c1 ); + idMath::SinCos16( angle2, s2, c2 ); + + origin[0] = c1 * c2; + origin[1] = s1 * c2; + origin[2] = -s2; + origin *= customPathParms[2]; + break; + } + case PPATH_ORBIT: { // ( radius speed axis ) + angle1 = g->random.RandomFloat() * idMath::TWO_PI + customPathParms[1] * g->age; + + float s1, c1; + idMath::SinCos16( angle1, s1, c1 ); + + origin[0] = c1 * customPathParms[0]; + origin[1] = s1 * customPathParms[0]; + origin.ProjectSelfOntoSphere( customPathParms[0] ); + break; + } + case PPATH_DRIP: { // ( speed ) + origin[0] = 0.0f; + origin[1] = 0.0f; + origin[2] = -( g->age * customPathParms[0] ); + break; + } + default: { + common->Error( "idParticleStage::ParticleOrigin: bad customPathType" ); + } + } + + origin += offset; + } + + // adjust for the per-particle smoke offset + origin *= g->axis; + origin += g->origin; + + // add gravity after adjusting for axis + if ( worldGravity ) { + idVec3 gra( 0, 0, -gravity ); + gra *= g->renderEnt->axis.Transpose(); + origin += gra * g->age * g->age; + } else { + origin[2] -= gravity * g->age * g->age; + } +} + +/* +================== +idParticleStage::ParticleVerts +================== +*/ +int idParticleStage::ParticleVerts( particleGen_t *g, idVec3 origin, idDrawVert *verts ) const { + float psize = size.Eval( g->frac, g->random ); + float paspect = aspect.Eval( g->frac, g->random ); + + float width = psize; + float height = psize * paspect; + + idVec3 left, up; + + if ( orientation == POR_AIMED ) { + // reset the values to an earlier time to get a previous origin + idRandom currentRandom = g->random; + float currentAge = g->age; + float currentFrac = g->frac; + idDrawVert *verts_p = verts; + idVec3 stepOrigin = origin; + idVec3 stepLeft; + int numTrails = idMath::Ftoi( orientationParms[0] ); + float trailTime = orientationParms[1]; + + if ( trailTime == 0 ) { + trailTime = 0.5f; + } + + float height = 1.0f / ( 1 + numTrails ); + float t = 0; + + for ( int i = 0 ; i <= numTrails ; i++ ) { + g->random = g->originalRandom; + g->age = currentAge - ( i + 1 ) * trailTime / ( numTrails + 1 ); // time to back up + g->frac = g->age / particleLife; + + idVec3 oldOrigin; + ParticleOrigin( g, oldOrigin ); + + up = stepOrigin - oldOrigin; // along the direction of travel + + idVec3 forwardDir; + g->renderEnt->axis.ProjectVector( g->renderView->viewaxis[0], forwardDir ); + + up -= ( up * forwardDir ) * forwardDir; + + up.Normalize(); + + + left = up.Cross( forwardDir ); + left *= psize; + + verts_p[0] = verts[0]; + verts_p[1] = verts[1]; + verts_p[2] = verts[2]; + verts_p[3] = verts[3]; + + if ( i == 0 ) { + verts_p[0].xyz = stepOrigin - left; + verts_p[1].xyz = stepOrigin + left; + } else { + verts_p[0].xyz = stepOrigin - stepLeft; + verts_p[1].xyz = stepOrigin + stepLeft; + } + verts_p[2].xyz = oldOrigin - left; + verts_p[3].xyz = oldOrigin + left; + + // modify texcoords + verts_p[0].st[0] = verts[0].st[0]; + verts_p[0].st[1] = t; + + verts_p[1].st[0] = verts[1].st[0]; + verts_p[1].st[1] = t; + + verts_p[2].st[0] = verts[2].st[0]; + verts_p[2].st[1] = t+height; + + verts_p[3].st[0] = verts[3].st[0]; + verts_p[3].st[1] = t+height; + + t += height; + + verts_p += 4; + + stepOrigin = oldOrigin; + stepLeft = left; + } + + g->random = currentRandom; + g->age = currentAge; + g->frac = currentFrac; + + return 4 * (numTrails+1); + } + + // + // constant rotation + // + float angle; + + angle = ( initialAngle ) ? initialAngle : 360 * g->random.RandomFloat(); + + float angleMove = rotationSpeed.Integrate( g->frac, g->random ) * particleLife; + // have hald the particles rotate each way + if ( g->index & 1 ) { + angle += angleMove; + } else { + angle -= angleMove; + } + + angle = angle / 180 * idMath::PI; + float c = idMath::Cos16( angle ); + float s = idMath::Sin16( angle ); + + if ( orientation == POR_Z ) { + // oriented in entity space + left[0] = s; + left[1] = c; + left[2] = 0; + up[0] = c; + up[1] = -s; + up[2] = 0; + } else if ( orientation == POR_X ) { + // oriented in entity space + left[0] = 0; + left[1] = c; + left[2] = s; + up[0] = 0; + up[1] = -s; + up[2] = c; + } else if ( orientation == POR_Y ) { + // oriented in entity space + left[0] = c; + left[1] = 0; + left[2] = s; + up[0] = -s; + up[1] = 0; + up[2] = c; + } else { + // oriented in viewer space + idVec3 entityLeft, entityUp; + + g->renderEnt->axis.ProjectVector( g->renderView->viewaxis[1], entityLeft ); + g->renderEnt->axis.ProjectVector( g->renderView->viewaxis[2], entityUp ); + + left = entityLeft * c + entityUp * s; + up = entityUp * c - entityLeft * s; + } + + left *= width; + up *= height; + + verts[0].xyz = origin - left + up; + verts[1].xyz = origin + left + up; + verts[2].xyz = origin - left - up; + verts[3].xyz = origin + left - up; + + return 4; +} + +/* +================== +idParticleStage::ParticleTexCoords +================== +*/ +void idParticleStage::ParticleTexCoords( particleGen_t *g, idDrawVert *verts ) const { + float s, width; + float t, height; + + if ( animationFrames > 1 ) { + width = 1.0f / animationFrames; + float floatFrame; + if ( animationRate ) { + // explicit, cycling animation + floatFrame = g->age * animationRate; + } else { + // single animation cycle over the life of the particle + floatFrame = g->frac * animationFrames; + } + int intFrame = (int)floatFrame; + g->animationFrameFrac = floatFrame - intFrame; + s = width * intFrame; + } else { + s = 0.0f; + width = 1.0f; + } + + t = 0.0f; + height = 1.0f; + + verts[0].st[0] = s; + verts[0].st[1] = t; + + verts[1].st[0] = s+width; + verts[1].st[1] = t; + + verts[2].st[0] = s; + verts[2].st[1] = t+height; + + verts[3].st[0] = s+width; + verts[3].st[1] = t+height; +} + +/* +================== +idParticleStage::ParticleColors +================== +*/ +void idParticleStage::ParticleColors( particleGen_t *g, idDrawVert *verts ) const { + float fadeFraction = 1.0f; + + // most particles fade in at the beginning and fade out at the end + if ( g->frac < fadeInFraction ) { + fadeFraction *= ( g->frac / fadeInFraction ); + } + if ( 1.0f - g->frac < fadeOutFraction ) { + fadeFraction *= ( ( 1.0f - g->frac ) / fadeOutFraction ); + } + + // individual gun smoke particles get more and more faded as the + // cycle goes on (note that totalParticles won't be correct for a surface-particle deform) + if ( fadeIndexFraction ) { + float indexFrac = ( totalParticles - g->index ) / (float)totalParticles; + if ( indexFrac < fadeIndexFraction ) { + fadeFraction *= indexFrac / fadeIndexFraction; + } + } + + for ( int i = 0 ; i < 4 ; i++ ) { + float fcolor = ( ( entityColor ) ? g->renderEnt->shaderParms[i] : color[i] ) * fadeFraction + fadeColor[i] * ( 1.0f - fadeFraction ); + int icolor = idMath::FtoiFast( fcolor * 255.0f ); + if ( icolor < 0 ) { + icolor = 0; + } else if ( icolor > 255 ) { + icolor = 255; + } + verts[0].color[i] = + verts[1].color[i] = + verts[2].color[i] = + verts[3].color[i] = icolor; + } +} + +/* +================ +idParticleStage::CreateParticle + +Returns 0 if no particle is created because it is completely faded out +Returns 4 if a normal quad is created +Returns 8 if two cross faded quads are created + +Vertex order is: + +0 1 +2 3 +================ +*/ +int idParticleStage::CreateParticle( particleGen_t *g, idDrawVert *verts ) const { + idVec3 origin; + + verts[0].Clear(); + verts[1].Clear(); + verts[2].Clear(); + verts[3].Clear(); + + ParticleColors( g, verts ); + + // if we are completely faded out, kill the particle + if ( verts[0].color[0] == 0 && verts[0].color[1] == 0 && verts[0].color[2] == 0 && verts[0].color[3] == 0 ) { + return 0; + } + + ParticleOrigin( g, origin ); + + ParticleTexCoords( g, verts ); + + int numVerts = ParticleVerts( g, origin, verts ); + + if ( animationFrames <= 1 ) { + return numVerts; + } + + // if we are doing strip-animation, we need to double the quad and cross fade it + float width = 1.0f / animationFrames; + float frac = g->animationFrameFrac; + float iFrac = 1.0f - frac; + for ( int i = 0 ; i < numVerts ; i++ ) { + verts[numVerts + i] = verts[i]; + + verts[numVerts + i].st[0] += width; + + verts[numVerts + i].color[0] *= frac; + verts[numVerts + i].color[1] *= frac; + verts[numVerts + i].color[2] *= frac; + verts[numVerts + i].color[3] *= frac; + + verts[i].color[0] *= iFrac; + verts[i].color[1] *= iFrac; + verts[i].color[2] *= iFrac; + verts[i].color[3] *= iFrac; + } + + return numVerts * 2; +} + +/* +================== +idParticleStage::GetCustomPathName +================== +*/ +const char* idParticleStage::GetCustomPathName() { + int index = ( customPathType < CustomParticleCount ) ? customPathType : 0; + return ParticleCustomDesc[index].name; +} + +/* +================== +idParticleStage::GetCustomPathDesc +================== +*/ +const char* idParticleStage::GetCustomPathDesc() { + int index = ( customPathType < CustomParticleCount ) ? customPathType : 0; + return ParticleCustomDesc[index].desc; +} + +/* +================== +idParticleStage::NumCustomPathParms +================== +*/ +int idParticleStage::NumCustomPathParms() { + int index = ( customPathType < CustomParticleCount ) ? customPathType : 0; + return ParticleCustomDesc[index].count; +} + +/* +================== +idParticleStage::SetCustomPathType +================== +*/ +void idParticleStage::SetCustomPathType( const char *p ) { + customPathType = PPATH_STANDARD; + for ( int i = 0; i < CustomParticleCount; i ++ ) { + if ( idStr::Icmp( p, ParticleCustomDesc[i].name ) == 0 ) { + customPathType = static_cast( i ); + break; + } + } +} + +/* +================== +idParticleStage::operator= +================== +*/ +void idParticleStage::operator=( const idParticleStage &src ) { + material = src.material; + totalParticles = src.totalParticles; + cycles = src.cycles; + cycleMsec = src.cycleMsec; + spawnBunching = src.spawnBunching; + particleLife = src.particleLife; + timeOffset = src.timeOffset; + deadTime = src.deadTime; + distributionType = src.distributionType; + distributionParms[0] = src.distributionParms[0]; + distributionParms[1] = src.distributionParms[1]; + distributionParms[2] = src.distributionParms[2]; + distributionParms[3] = src.distributionParms[3]; + directionType = src.directionType; + directionParms[0] = src.directionParms[0]; + directionParms[1] = src.directionParms[1]; + directionParms[2] = src.directionParms[2]; + directionParms[3] = src.directionParms[3]; + speed = src.speed; + gravity = src.gravity; + worldGravity = src.worldGravity; + randomDistribution = src.randomDistribution; + entityColor = src.entityColor; + customPathType = src.customPathType; + customPathParms[0] = src.customPathParms[0]; + customPathParms[1] = src.customPathParms[1]; + customPathParms[2] = src.customPathParms[2]; + customPathParms[3] = src.customPathParms[3]; + customPathParms[4] = src.customPathParms[4]; + customPathParms[5] = src.customPathParms[5]; + customPathParms[6] = src.customPathParms[6]; + customPathParms[7] = src.customPathParms[7]; + offset = src.offset; + animationFrames = src.animationFrames; + animationRate = src.animationRate; + initialAngle = src.initialAngle; + rotationSpeed = src.rotationSpeed; + orientation = src.orientation; + orientationParms[0] = src.orientationParms[0]; + orientationParms[1] = src.orientationParms[1]; + orientationParms[2] = src.orientationParms[2]; + orientationParms[3] = src.orientationParms[3]; + size = src.size; + aspect = src.aspect; + color = src.color; + fadeColor = src.fadeColor; + fadeInFraction = src.fadeInFraction; + fadeOutFraction = src.fadeOutFraction; + fadeIndexFraction = src.fadeIndexFraction; + hidden = src.hidden; + boundsExpansion = src.boundsExpansion; + bounds = src.bounds; +} diff --git a/framework/DeclParticle.h b/framework/DeclParticle.h new file mode 100644 index 000000000..da3cb6f38 --- /dev/null +++ b/framework/DeclParticle.h @@ -0,0 +1,209 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLPARTICLE_H__ +#define __DECLPARTICLE_H__ + +/* +=============================================================================== + + idDeclParticle + +=============================================================================== +*/ + +class idParticleParm { +public: + idParticleParm( void ) { table = NULL; from = to = 0.0f; } + + const idDeclTable * table; + float from; + float to; + + float Eval( float frac, idRandom &rand ) const; + float Integrate( float frac, idRandom &rand ) const; +}; + + +typedef enum { + PDIST_RECT, // ( sizeX sizeY sizeZ ) + PDIST_CYLINDER, // ( sizeX sizeY sizeZ ) + PDIST_SPHERE // ( sizeX sizeY sizeZ ringFraction ) + // a ringFraction of zero allows the entire sphere, 0.9 would only + // allow the outer 10% of the sphere +} prtDistribution_t; + +typedef enum { + PDIR_CONE, // parm0 is the solid cone angle + PDIR_OUTWARD // direction is relative to offset from origin, parm0 is an upward bias +} prtDirection_t; + +typedef enum { + PPATH_STANDARD, + PPATH_HELIX, // ( sizeX sizeY sizeZ radialSpeed climbSpeed ) + PPATH_FLIES, + PPATH_ORBIT, + PPATH_DRIP +} prtCustomPth_t; + +typedef enum { + POR_VIEW, + POR_AIMED, // angle and aspect are disregarded + POR_X, + POR_Y, + POR_Z +} prtOrientation_t; + +typedef struct renderEntity_s renderEntity_t; +typedef struct renderView_s renderView_t; + +typedef struct { + const renderEntity_t * renderEnt; // for shaderParms, etc + const renderView_t * renderView; + int index; // particle number in the system + float frac; // 0.0 to 1.0 + idRandom random; + idVec3 origin; // dynamic smoke particles can have individual origins and axis + idMat3 axis; + + + float age; // in seconds, calculated as fraction * stage->particleLife + idRandom originalRandom; // needed so aimed particles can reset the random for another origin calculation + float animationFrameFrac; // set by ParticleTexCoords, used to make the cross faded version +} particleGen_t; + + +// +// single particle stage +// +class idParticleStage { +public: + idParticleStage( void ); + virtual ~idParticleStage( void ) {} + + void Default(); + virtual int NumQuadsPerParticle() const; // includes trails and cross faded animations + // returns the number of verts created, which will range from 0 to 4*NumQuadsPerParticle() + virtual int CreateParticle( particleGen_t *g, idDrawVert *verts ) const; + + void ParticleOrigin( particleGen_t *g, idVec3 &origin ) const; + int ParticleVerts( particleGen_t *g, const idVec3 origin, idDrawVert *verts ) const; + void ParticleTexCoords( particleGen_t *g, idDrawVert *verts ) const; + void ParticleColors( particleGen_t *g, idDrawVert *verts ) const; + + const char * GetCustomPathName(); + const char * GetCustomPathDesc(); + int NumCustomPathParms(); + void SetCustomPathType( const char *p ); + void operator=( const idParticleStage &src ); + + + //------------------------------ + + const idMaterial * material; + + int totalParticles; // total number of particles, although some may be invisible at a given time + float cycles; // allows things to oneShot ( 1 cycle ) or run for a set number of cycles + // on a per stage basis + + int cycleMsec; // ( particleLife + deadTime ) in msec + + float spawnBunching; // 0.0 = all come out at first instant, 1.0 = evenly spaced over cycle time + float particleLife; // total seconds of life for each particle + float timeOffset; // time offset from system start for the first particle to spawn + float deadTime; // time after particleLife before respawning + + //------------------------------- // standard path parms + + prtDistribution_t distributionType; + float distributionParms[4]; + + prtDirection_t directionType; + float directionParms[4]; + + idParticleParm speed; + float gravity; // can be negative to float up + bool worldGravity; // apply gravity in world space + bool randomDistribution; // randomly orient the quad on emission ( defaults to true ) + bool entityColor; // force color from render entity ( fadeColor is still valid ) + + //------------------------------ // custom path will completely replace the standard path calculations + + prtCustomPth_t customPathType; // use custom C code routines for determining the origin + float customPathParms[8]; + + //-------------------------------- + + idVec3 offset; // offset from origin to spawn all particles, also applies to customPath + + int animationFrames; // if > 1, subdivide the texture S axis into frames and crossfade + float animationRate; // frames per second + + float initialAngle; // in degrees, random angle is used if zero ( default ) + idParticleParm rotationSpeed; // half the particles will have negative rotation speeds + + prtOrientation_t orientation; // view, aimed, or axis fixed + float orientationParms[4]; + + idParticleParm size; + idParticleParm aspect; // greater than 1 makes the T axis longer + + idVec4 color; + idVec4 fadeColor; // either 0 0 0 0 for additive, or 1 1 1 0 for blended materials + float fadeInFraction; // in 0.0 to 1.0 range + float fadeOutFraction; // in 0.0 to 1.0 range + float fadeIndexFraction; // in 0.0 to 1.0 range, causes later index smokes to be more faded + + bool hidden; // for editor use + //----------------------------------- + + float boundsExpansion; // user tweak to fix poorly calculated bounds + + idBounds bounds; // derived +}; + + +// +// group of particle stages +// +class idDeclParticle : public idDecl { +public: + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + + bool Save( const char *fileName = NULL ); + + idListstages; + idBounds bounds; + float depthHack; + +private: + bool RebuildTextSource( void ); + void GetStageBounds( idParticleStage *stage ); + idParticleStage * ParseParticleStage( idLexer &src ); + void ParseParms( idLexer &src, float *parms, int maxParms ); + void ParseParametric( idLexer &src, idParticleParm *parm ); + void WriteStage( idFile *f, idParticleStage *stage ); + void WriteParticleParm( idFile *f, idParticleParm *parm, const char *name ); +}; + +#endif /* !__DECLPARTICLE_H__ */ diff --git a/framework/DeclSkin.cpp b/framework/DeclSkin.cpp new file mode 100644 index 000000000..79d089c62 --- /dev/null +++ b/framework/DeclSkin.cpp @@ -0,0 +1,176 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + + +/* +================= +idDeclSkin::Size +================= +*/ +size_t idDeclSkin::Size( void ) const { + return sizeof( idDeclSkin ); +} + +/* +================ +idDeclSkin::FreeData +================ +*/ +void idDeclSkin::FreeData( void ) { + mappings.Clear(); +} + +/* +================ +idDeclSkin::Parse +================ +*/ +bool idDeclSkin::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token, token2; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + associatedModels.Clear(); + + while (1) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + if ( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + + if ( !token.Icmp( "model" ) ) { + associatedModels.Append( token2 ); + continue; + } + + skinMapping_t map; + + if ( !token.Icmp( "*" ) ) { + // wildcard + map.from = NULL; + } else { + map.from = declManager->FindMaterial( token ); + } + + map.to = declManager->FindMaterial( token2 ); + + mappings.Append( map ); + } + + return false; +} + +/* +================ +idDeclSkin::SetDefaultText +================ +*/ +bool idDeclSkin::SetDefaultText( void ) { + // if there exists a material with the same name + if ( declManager->FindType( DECL_MATERIAL, GetName(), false ) ) { + char generated[2048]; + + idStr::snPrintf( generated, sizeof( generated ), + "skin %s // IMPLICITLY GENERATED\n" + "{\n" + "_default %s\n" + "}\n", GetName(), GetName() ); + SetText( generated ); + return true; + } else { + return false; + } +} + +/* +================ +idDeclSkin::DefaultDefinition +================ +*/ +const char *idDeclSkin::DefaultDefinition( void ) const { + return + "{\n" + "\t" "\"*\"\t\"_default\"\n" + "}"; +} + +/* +================ +idDeclSkin::GetNumModelAssociations +================ +*/ +const int idDeclSkin::GetNumModelAssociations(void ) const { + return associatedModels.Num(); +} + +/* +================ +idDeclSkin::GetAssociatedModel +================ +*/ +const char *idDeclSkin::GetAssociatedModel( int index ) const { + if ( index >= 0 && index < associatedModels.Num() ) { + return associatedModels[ index ]; + } + return ""; +} + +/* +=============== +RemapShaderBySkin +=============== +*/ +const idMaterial *idDeclSkin::RemapShaderBySkin( const idMaterial *shader ) const { + int i; + + if ( !shader ) { + return NULL; + } + + // never remap surfaces that were originally nodraw, like collision hulls + if ( !shader->IsDrawn() ) { + return shader; + } + + for ( i = 0; i < mappings.Num() ; i++ ) { + const skinMapping_t *map = &mappings[i]; + + // NULL = wildcard match + if ( !map->from || map->from == shader ) { + return map->to; + } + } + + // didn't find a match or wildcard, so stay the same + return shader; +} diff --git a/framework/DeclSkin.h b/framework/DeclSkin.h new file mode 100644 index 000000000..1f1e3f635 --- /dev/null +++ b/framework/DeclSkin.h @@ -0,0 +1,55 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLSKIN_H__ +#define __DECLSKIN_H__ + +/* +=============================================================================== + + idDeclSkin + +=============================================================================== +*/ + +typedef struct { + const idMaterial * from; // 0 == any unmatched shader + const idMaterial * to; +} skinMapping_t; + +class idDeclSkin : public idDecl { +public: + virtual size_t Size( void ) const; + virtual bool SetDefaultText( void ); + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + + const idMaterial * RemapShaderBySkin( const idMaterial *shader ) const; + + // model associations are just for the preview dialog in the editor + const int GetNumModelAssociations() const; + const char * GetAssociatedModel( int index ) const; + +private: + idList mappings; + idStrList associatedModels; +}; + +#endif /* !__DECLSKIN_H__ */ diff --git a/framework/DeclTable.cpp b/framework/DeclTable.cpp new file mode 100644 index 000000000..ed50e7ddc --- /dev/null +++ b/framework/DeclTable.cpp @@ -0,0 +1,168 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + + +/* +================= +idDeclTable::TableLookup +================= +*/ +float idDeclTable::TableLookup( float index ) const { + int iIndex; + float iFrac; + + int domain = values.Num() - 1; + + if ( domain <= 1 ) { + return 1.0f; + } + + if ( clamp ) { + index *= (domain-1); + if ( index >= domain - 1 ) { + return values[domain - 1]; + } else if ( index <= 0 ) { + return values[0]; + } + iIndex = idMath::Ftoi( index ); + iFrac = index - iIndex; + } else { + index *= domain; + + if ( index < 0 ) { + index += domain * idMath::Ceil( -index / domain ); + } + + iIndex = idMath::FtoiFast( idMath::Floor( index ) ); + iFrac = index - iIndex; + iIndex = iIndex % domain; + } + + if ( !snap ) { + // we duplicated the 0 index at the end at creation time, so we + // don't need to worry about wrapping the filter + return values[iIndex] * ( 1.0f - iFrac ) + values[iIndex + 1] * iFrac; + } + + return values[iIndex]; +} + +/* +================= +idDeclTable::Size +================= +*/ +size_t idDeclTable::Size( void ) const { + return sizeof( idDeclTable ) + values.Allocated(); +} + +/* +================= +idDeclTable::FreeData +================= +*/ +void idDeclTable::FreeData( void ) { + snap = false; + clamp = false; + values.Clear(); +} + +/* +================= +idDeclTable::DefaultDefinition +================= +*/ +const char *idDeclTable::DefaultDefinition( void ) const { + return "{ { 0 } }"; +} + +/* +================= +idDeclTable::Parse +================= +*/ +bool idDeclTable::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + float v; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + snap = false; + clamp = false; + values.Clear(); + + while ( 1 ) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( token.Icmp( "snap" ) == 0 ) { + snap = true; + } else if ( token.Icmp( "clamp" ) == 0 ) { + clamp = true; + } else if ( token.Icmp( "{" ) == 0 ) { + + while ( 1 ) { + bool errorFlag; + + v = src.ParseFloat( &errorFlag ); + if ( errorFlag ) { + // we got something non-numeric + MakeDefault(); + return false; + } + + values.Append( v ); + + src.ReadToken( &token ); + if ( token == "}" ) { + break; + } + if ( token == "," ) { + continue; + } + src.Warning( "expected comma or brace" ); + MakeDefault(); + return false; + } + + } else { + src.Warning( "unknown token '%s'", token.c_str() ); + MakeDefault(); + return false; + } + } + + // copy the 0 element to the end, so lerping doesn't + // need to worry about the wrap case + float val = values[0]; // template bug requires this to not be in the Append()? + values.Append( val ); + + return true; +} diff --git a/framework/DeclTable.h b/framework/DeclTable.h new file mode 100644 index 000000000..1c6674c28 --- /dev/null +++ b/framework/DeclTable.h @@ -0,0 +1,47 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DECLTABLE_H__ +#define __DECLTABLE_H__ + +/* +=============================================================================== + + tables are used to map a floating point input value to a floating point + output value, with optional wrap / clamp and interpolation + +=============================================================================== +*/ + +class idDeclTable : public idDecl { +public: + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + + float TableLookup( float index ) const; + +private: + bool clamp; + bool snap; + idList values; +}; + +#endif /* !__DECLTABLE_H__ */ diff --git a/framework/DemoChecksum.h b/framework/DemoChecksum.h new file mode 100644 index 000000000..4a6508349 --- /dev/null +++ b/framework/DemoChecksum.h @@ -0,0 +1,30 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Pak file checksum for demo build. + +=============================================================================== +*/ + +// every time a new demo pk4 file is built, this checksum must be updated. +// the easiest way to get it is to just run the game and see what it spits out +#define DEMO_PAK_CHECKSUM 0xfe75bbef diff --git a/framework/DemoFile.cpp b/framework/DemoFile.cpp new file mode 100644 index 000000000..ee0965636 --- /dev/null +++ b/framework/DemoFile.cpp @@ -0,0 +1,319 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +idCVar idDemoFile::com_logDemos( "com_logDemos", "0", CVAR_SYSTEM | CVAR_BOOL, "Write demo.log with debug information in it" ); +idCVar idDemoFile::com_compressDemos( "com_compressDemos", "1", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE, "Compression scheme for demo files\n0: None (Fast, large files)\n1: LZW (Fast to compress, Fast to decompress, medium/small files)\n2: LZSS (Slow to compress, Fast to decompress, small files)\n3: Huffman (Fast to compress, Slow to decompress, medium files)\nSee also: The 'CompressDemo' command" ); +idCVar idDemoFile::com_preloadDemos( "com_preloadDemos", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_ARCHIVE, "Load the whole demo in to RAM before running it" ); + +#define DEMO_MAGIC GAME_NAME " RDEMO" + +/* +================ +idDemoFile::idDemoFile +================ +*/ +idDemoFile::idDemoFile() { + f = NULL; + fLog = NULL; + log = false; + fileImage = NULL; + compressor = NULL; + writing = false; +} + +/* +================ +idDemoFile::~idDemoFile +================ +*/ +idDemoFile::~idDemoFile() { + Close(); +} + +/* +================ +idDemoFile::AllocCompressor +================ +*/ +idCompressor *idDemoFile::AllocCompressor( int type ) { + switch ( type ) { + case 0: return idCompressor::AllocNoCompression(); + default: + case 1: return idCompressor::AllocLZW(); + case 2: return idCompressor::AllocLZSS(); + case 3: return idCompressor::AllocHuffman(); + } +} + +/* +================ +idDemoFile::OpenForReading +================ +*/ +bool idDemoFile::OpenForReading( const char *fileName ) { + static const int magicLen = sizeof(DEMO_MAGIC) / sizeof(DEMO_MAGIC[0]); + char magicBuffer[magicLen]; + int compression; + int fileLength; + + Close(); + + f = fileSystem->OpenFileRead( fileName ); + if ( !f ) { + return false; + } + + fileLength = f->Length(); + + if ( com_preloadDemos.GetBool() ) { + fileImage = (byte *)Mem_Alloc( fileLength ); + f->Read( fileImage, fileLength ); + fileSystem->CloseFile( f ); + f = new idFile_Memory( va( "preloaded(%s)", fileName ), (const char *)fileImage, fileLength ); + } + + if ( com_logDemos.GetBool() ) { + fLog = fileSystem->OpenFileWrite( "demoread.log" ); + } + + writing = false; + + f->Read(magicBuffer, magicLen); + if ( memcmp(magicBuffer, DEMO_MAGIC, magicLen) == 0 ) { + f->ReadInt( compression ); + } else { + // Ideally we would error out if the magic string isn't there, + // but for backwards compatibility we are going to assume it's just an uncompressed demo file + compression = 0; + f->Rewind(); + } + + compressor = AllocCompressor( compression ); + compressor->Init( f, false, 8 ); + + return true; +} + +/* +================ +idDemoFile::SetLog +================ +*/ +void idDemoFile::SetLog(bool b, const char *p) { + log = b; + if (p) { + logStr = p; + } +} + +/* +================ +idDemoFile::Log +================ +*/ +void idDemoFile::Log(const char *p) { + if ( fLog && p && *p ) { + fLog->Write( p, strlen(p) ); + } +} + +/* +================ +idDemoFile::OpenForWriting +================ +*/ +bool idDemoFile::OpenForWriting( const char *fileName ) { + Close(); + + f = fileSystem->OpenFileWrite( fileName ); + if ( f == NULL ) { + return false; + } + + if ( com_logDemos.GetBool() ) { + fLog = fileSystem->OpenFileWrite( "demowrite.log" ); + } + + writing = true; + + f->Write(DEMO_MAGIC, sizeof(DEMO_MAGIC)); + f->WriteInt( com_compressDemos.GetInteger() ); + f->Flush(); + + compressor = AllocCompressor( com_compressDemos.GetInteger() ); + compressor->Init( f, true, 8 ); + + return true; +} + +/* +================ +idDemoFile::Close +================ +*/ +void idDemoFile::Close() { + if ( writing && compressor ) { + compressor->FinishCompress(); + } + + if ( f ) { + fileSystem->CloseFile( f ); + f = NULL; + } + if ( fLog ) { + fileSystem->CloseFile( fLog ); + fLog = NULL; + } + if ( fileImage ) { + Mem_Free( fileImage ); + fileImage = NULL; + } + if ( compressor ) { + delete compressor; + compressor = NULL; + } + + demoStrings.DeleteContents( true ); +} + +/* +================ +idDemoFile::ReadHashString +================ +*/ +const char *idDemoFile::ReadHashString() { + int index; + + if ( log && fLog ) { + const char *text = va( "%s > Reading hash string\n", logStr.c_str() ); + fLog->Write( text, strlen( text ) ); + } + + ReadInt( index ); + + if ( index == -1 ) { + // read a new string for the table + idStr *str = new idStr; + + idStr data; + ReadString( data ); + *str = data; + + demoStrings.Append( str ); + + return *str; + } + + if ( index < -1 || index >= demoStrings.Num() ) { + Close(); + common->Error( "demo hash index out of range" ); + } + + return demoStrings[index]->c_str(); +} + +/* +================ +idDemoFile::WriteHashString +================ +*/ +void idDemoFile::WriteHashString( const char *str ) { + if ( log && fLog ) { + const char *text = va( "%s > Writing hash string\n", logStr.c_str() ); + fLog->Write( text, strlen( text ) ); + } + // see if it is already in the has table + for ( int i = 0 ; i < demoStrings.Num() ; i++ ) { + if ( !strcmp( demoStrings[i]->c_str(), str ) ) { + WriteInt( i ); + return; + } + } + + // add it to our table and the demo table + idStr *copy = new idStr( str ); +//common->Printf( "hash:%i = %s\n", demoStrings.Num(), str ); + demoStrings.Append( copy ); + int cmd = -1; + WriteInt( cmd ); + WriteString( str ); +} + +/* +================ +idDemoFile::ReadDict +================ +*/ +void idDemoFile::ReadDict( idDict &dict ) { + int i, c; + idStr key, val; + + dict.Clear(); + ReadInt( c ); + for ( i = 0; i < c; i++ ) { + key = ReadHashString(); + val = ReadHashString(); + dict.Set( key, val ); + } +} + +/* +================ +idDemoFile::WriteDict +================ +*/ +void idDemoFile::WriteDict( const idDict &dict ) { + int i, c; + + c = dict.GetNumKeyVals(); + WriteInt( c ); + for ( i = 0; i < c; i++ ) { + WriteHashString( dict.GetKeyVal( i )->GetKey() ); + WriteHashString( dict.GetKeyVal( i )->GetValue() ); + } +} + +/* + ================ + idDemoFile::Read + ================ + */ +int idDemoFile::Read( void *buffer, int len ) { + int read = compressor->Read( buffer, len ); + if ( read == 0 && len >= 4 ) { + *(demoSystem_t *)buffer = DS_FINISHED; + } + return read; +} + +/* + ================ + idDemoFile::Write + ================ + */ +int idDemoFile::Write( const void *buffer, int len ) { + return compressor->Write( buffer, len ); +} + + + + diff --git a/framework/DemoFile.h b/framework/DemoFile.h new file mode 100644 index 000000000..643bc0d20 --- /dev/null +++ b/framework/DemoFile.h @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DEMOFILE_H__ +#define __DEMOFILE_H__ + +/* +=============================================================================== + + Demo file + +=============================================================================== +*/ + +typedef enum { + DS_FINISHED, + DS_RENDER, + DS_SOUND, + DS_VERSION +} demoSystem_t; + +class idDemoFile : public idFile { +public: + idDemoFile(); + ~idDemoFile(); + + const char * GetName( void ) { return (f?f->GetName():""); } + const char * GetFullPath( void ) { return (f?f->GetFullPath():""); } + + void SetLog( bool b, const char *p ); + void Log( const char *p ); + bool OpenForReading( const char *fileName ); + bool OpenForWriting( const char *fileName ); + void Close(); + + const char * ReadHashString(); + void WriteHashString( const char *str ); + + void ReadDict( idDict &dict ); + void WriteDict( const idDict &dict ); + + int Read( void *buffer, int len ); + int Write( const void *buffer, int len ); + +private: + static idCompressor *AllocCompressor( int type ); + + bool writing; + byte * fileImage; + idFile * f; + idCompressor * compressor; + + idList demoStrings; + idFile * fLog; + bool log; + idStr logStr; + + static idCVar com_logDemos; + static idCVar com_compressDemos; + static idCVar com_preloadDemos; +}; + +#endif /* !__DEMOFILE_H__ */ diff --git a/framework/EditField.cpp b/framework/EditField.cpp new file mode 100644 index 000000000..d99cabefb --- /dev/null +++ b/framework/EditField.cpp @@ -0,0 +1,595 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static autoComplete_t globalAutoComplete; + +/* +=============== +FindMatches +=============== +*/ +static void FindMatches( const char *s ) { + int i; + + if ( idStr::Icmpn( s, globalAutoComplete.completionString, strlen( globalAutoComplete.completionString ) ) != 0 ) { + return; + } + globalAutoComplete.matchCount++; + if ( globalAutoComplete.matchCount == 1 ) { + idStr::Copynz( globalAutoComplete.currentMatch, s, sizeof( globalAutoComplete.currentMatch ) ); + return; + } + + // cut currentMatch to the amount common with s + for ( i = 0; s[i]; i++ ) { + if ( tolower( globalAutoComplete.currentMatch[i] ) != tolower( s[i] ) ) { + globalAutoComplete.currentMatch[i] = 0; + break; + } + } + globalAutoComplete.currentMatch[i] = 0; +} + +/* +=============== +FindIndexMatch +=============== +*/ +static void FindIndexMatch( const char *s ) { + + if ( idStr::Icmpn( s, globalAutoComplete.completionString, strlen( globalAutoComplete.completionString ) ) != 0 ) { + return; + } + + if( globalAutoComplete.findMatchIndex == globalAutoComplete.matchIndex ) { + idStr::Copynz( globalAutoComplete.currentMatch, s, sizeof( globalAutoComplete.currentMatch ) ); + } + + globalAutoComplete.findMatchIndex++; +} + +/* +=============== +PrintMatches +=============== +*/ +static void PrintMatches( const char *s ) { + if ( idStr::Icmpn( s, globalAutoComplete.currentMatch, strlen( globalAutoComplete.currentMatch ) ) == 0 ) { + common->Printf( " %s\n", s ); + } +} + +/* +=============== +PrintCvarMatches +=============== +*/ +static void PrintCvarMatches( const char *s ) { + if ( idStr::Icmpn( s, globalAutoComplete.currentMatch, strlen( globalAutoComplete.currentMatch ) ) == 0 ) { + common->Printf( " %s" S_COLOR_WHITE " = \"%s\"\n", s, cvarSystem->GetCVarString( s ) ); + } +} + +/* +=============== +idEditField::idEditField +=============== +*/ +idEditField::idEditField() { + widthInChars = 0; + Clear(); +} + +/* +=============== +idEditField::~idEditField +=============== +*/ +idEditField::~idEditField() { +} + +/* +=============== +idEditField::Clear +=============== +*/ +void idEditField::Clear( void ) { + buffer[0] = 0; + cursor = 0; + scroll = 0; + autoComplete.length = 0; + autoComplete.valid = false; +} + +/* +=============== +idEditField::SetWidthInChars +=============== +*/ +void idEditField::SetWidthInChars( int w ) { + assert( w <= MAX_EDIT_LINE ); + widthInChars = w; +} + +/* +=============== +idEditField::SetCursor +=============== +*/ +void idEditField::SetCursor( int c ) { + assert( c <= MAX_EDIT_LINE ); + cursor = c; +} + +/* +=============== +idEditField::GetCursor +=============== +*/ +int idEditField::GetCursor( void ) const { + return cursor; +} + +/* +=============== +idEditField::ClearAutoComplete +=============== +*/ +void idEditField::ClearAutoComplete( void ) { + if ( autoComplete.length > 0 && autoComplete.length <= (int) strlen( buffer ) ) { + buffer[autoComplete.length] = '\0'; + if ( cursor > autoComplete.length ) { + cursor = autoComplete.length; + } + } + autoComplete.length = 0; + autoComplete.valid = false; +} + +/* +=============== +idEditField::GetAutoCompleteLength +=============== +*/ +int idEditField::GetAutoCompleteLength( void ) const { + return autoComplete.length; +} + +/* +=============== +idEditField::AutoComplete +=============== +*/ +void idEditField::AutoComplete( void ) { + char completionArgString[MAX_EDIT_LINE]; + idCmdArgs args; + + if ( !autoComplete.valid ) { + args.TokenizeString( buffer, false ); + idStr::Copynz( autoComplete.completionString, args.Argv( 0 ), sizeof( autoComplete.completionString ) ); + idStr::Copynz( completionArgString, args.Args(), sizeof( completionArgString ) ); + autoComplete.matchCount = 0; + autoComplete.matchIndex = 0; + autoComplete.currentMatch[0] = 0; + + if ( strlen( autoComplete.completionString ) == 0 ) { + return; + } + + globalAutoComplete = autoComplete; + + cmdSystem->CommandCompletion( FindMatches ); + cvarSystem->CommandCompletion( FindMatches ); + + autoComplete = globalAutoComplete; + + if ( autoComplete.matchCount == 0 ) { + return; // no matches + } + + // when there's only one match or there's an argument + if ( autoComplete.matchCount == 1 || completionArgString[0] != '\0' ) { + + /// try completing arguments + idStr::Append( autoComplete.completionString, sizeof( autoComplete.completionString ), " " ); + idStr::Append( autoComplete.completionString, sizeof( autoComplete.completionString ), completionArgString ); + autoComplete.matchCount = 0; + + globalAutoComplete = autoComplete; + + cmdSystem->ArgCompletion( autoComplete.completionString, FindMatches ); + cvarSystem->ArgCompletion( autoComplete.completionString, FindMatches ); + + autoComplete = globalAutoComplete; + + idStr::snPrintf( buffer, sizeof( buffer ), "%s", autoComplete.currentMatch ); + + if ( autoComplete.matchCount == 0 ) { + // no argument matches + idStr::Append( buffer, sizeof( buffer ), " " ); + idStr::Append( buffer, sizeof( buffer ), completionArgString ); + SetCursor( strlen( buffer ) ); + return; + } + } else { + + // multiple matches, complete to shortest + idStr::snPrintf( buffer, sizeof( buffer ), "%s", autoComplete.currentMatch ); + if ( strlen( completionArgString ) ) { + idStr::Append( buffer, sizeof( buffer ), " " ); + idStr::Append( buffer, sizeof( buffer ), completionArgString ); + } + } + + autoComplete.length = strlen( buffer ); + autoComplete.valid = ( autoComplete.matchCount != 1 ); + SetCursor( autoComplete.length ); + + common->Printf( "]%s\n", buffer ); + + // run through again, printing matches + globalAutoComplete = autoComplete; + + cmdSystem->CommandCompletion( PrintMatches ); + cmdSystem->ArgCompletion( autoComplete.completionString, PrintMatches ); + cvarSystem->CommandCompletion( PrintCvarMatches ); + cvarSystem->ArgCompletion( autoComplete.completionString, PrintMatches ); + + } else if ( autoComplete.matchCount != 1 ) { + + // get the next match and show instead + autoComplete.matchIndex++; + if ( autoComplete.matchIndex == autoComplete.matchCount ) { + autoComplete.matchIndex = 0; + } + autoComplete.findMatchIndex = 0; + + globalAutoComplete = autoComplete; + + cmdSystem->CommandCompletion( FindIndexMatch ); + cmdSystem->ArgCompletion( autoComplete.completionString, FindIndexMatch ); + cvarSystem->CommandCompletion( FindIndexMatch ); + cvarSystem->ArgCompletion( autoComplete.completionString, FindIndexMatch ); + + autoComplete = globalAutoComplete; + + // and print it + idStr::snPrintf( buffer, sizeof( buffer ), autoComplete.currentMatch ); + if ( autoComplete.length > (int)strlen( buffer ) ) { + autoComplete.length = strlen( buffer ); + } + SetCursor( autoComplete.length ); + } +} + +/* +=============== +idEditField::CharEvent +=============== +*/ +void idEditField::CharEvent( int ch ) { + int len; + + if ( ch == 'v' - 'a' + 1 ) { // ctrl-v is paste + Paste(); + return; + } + + if ( ch == 'c' - 'a' + 1 ) { // ctrl-c clears the field + Clear(); + return; + } + + len = strlen( buffer ); + + if ( ch == 'h' - 'a' + 1 || ch == K_BACKSPACE ) { // ctrl-h is backspace + if ( cursor > 0 ) { + memmove( buffer + cursor - 1, buffer + cursor, len + 1 - cursor ); + cursor--; + if ( cursor < scroll ) { + scroll--; + } + } + return; + } + + if ( ch == 'a' - 'a' + 1 ) { // ctrl-a is home + cursor = 0; + scroll = 0; + return; + } + + if ( ch == 'e' - 'a' + 1 ) { // ctrl-e is end + cursor = len; + scroll = cursor - widthInChars; + return; + } + + // + // ignore any other non printable chars + // + if ( ch < 32 ) { + return; + } + + if ( idKeyInput::GetOverstrikeMode() ) { + if ( cursor == MAX_EDIT_LINE - 1 ) { + return; + } + buffer[cursor] = ch; + cursor++; + } else { // insert mode + if ( len == MAX_EDIT_LINE - 1 ) { + return; // all full + } + memmove( buffer + cursor + 1, buffer + cursor, len + 1 - cursor ); + buffer[cursor] = ch; + cursor++; + } + + + if ( cursor >= widthInChars ) { + scroll++; + } + + if ( cursor == len + 1 ) { + buffer[cursor] = 0; + } +} + +/* +=============== +idEditField::KeyDownEvent +=============== +*/ +void idEditField::KeyDownEvent( int key ) { + int len; + + // shift-insert is paste + if ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && idKeyInput::IsDown( K_SHIFT ) ) { + ClearAutoComplete(); + Paste(); + return; + } + + len = strlen( buffer ); + + if ( key == K_DEL ) { + if ( autoComplete.length ) { + ClearAutoComplete(); + } else if ( cursor < len ) { + memmove( buffer + cursor, buffer + cursor + 1, len - cursor ); + } + return; + } + + if ( key == K_RIGHTARROW ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + // skip to next word + while( ( cursor < len ) && ( buffer[ cursor ] != ' ' ) ) { + cursor++; + } + + while( ( cursor < len ) && ( buffer[ cursor ] == ' ' ) ) { + cursor++; + } + } else { + cursor++; + } + + if ( cursor > len ) { + cursor = len; + } + + if ( cursor >= scroll + widthInChars ) { + scroll = cursor - widthInChars + 1; + } + + if ( autoComplete.length > 0 ) { + autoComplete.length = cursor; + } + return; + } + + if ( key == K_LEFTARROW ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + // skip to previous word + while( ( cursor > 0 ) && ( buffer[ cursor - 1 ] == ' ' ) ) { + cursor--; + } + + while( ( cursor > 0 ) && ( buffer[ cursor - 1 ] != ' ' ) ) { + cursor--; + } + } else { + cursor--; + } + + if ( cursor < 0 ) { + cursor = 0; + } + if ( cursor < scroll ) { + scroll = cursor; + } + + if ( autoComplete.length ) { + autoComplete.length = cursor; + } + return; + } + + if ( key == K_HOME || ( tolower( key ) == 'a' && idKeyInput::IsDown( K_CTRL ) ) ) { + cursor = 0; + scroll = 0; + if ( autoComplete.length ) { + autoComplete.length = cursor; + autoComplete.valid = false; + } + return; + } + + if ( key == K_END || ( tolower( key ) == 'e' && idKeyInput::IsDown( K_CTRL ) ) ) { + cursor = len; + if ( cursor >= scroll + widthInChars ) { + scroll = cursor - widthInChars + 1; + } + if ( autoComplete.length ) { + autoComplete.length = cursor; + autoComplete.valid = false; + } + return; + } + + if ( key == K_INS ) { + idKeyInput::SetOverstrikeMode( !idKeyInput::GetOverstrikeMode() ); + return; + } + + // clear autocompletion buffer on normal key input + if ( key != K_CAPSLOCK && key != K_ALT && key != K_CTRL && key != K_SHIFT ) { + ClearAutoComplete(); + } +} + +/* +=============== +idEditField::Paste +=============== +*/ +void idEditField::Paste( void ) { + char *cbd; + int pasteLen, i; + + cbd = Sys_GetClipboardData(); + + if ( !cbd ) { + return; + } + + // send as if typed, so insert / overstrike works properly + pasteLen = strlen( cbd ); + for ( i = 0; i < pasteLen; i++ ) { + CharEvent( cbd[i] ); + } + + Mem_Free( cbd ); +} + +/* +=============== +idEditField::GetBuffer +=============== +*/ +char *idEditField::GetBuffer( void ) { + return buffer; +} + +/* +=============== +idEditField::SetBuffer +=============== +*/ +void idEditField::SetBuffer( const char *buf ) { + Clear(); + idStr::Copynz( buffer, buf, sizeof( buffer ) ); + SetCursor( strlen( buffer ) ); +} + +/* +=============== +idEditField::Draw +=============== +*/ +void idEditField::Draw( int x, int y, int width, bool showCursor, const idMaterial *shader ) { + int len; + int drawLen; + int prestep; + int cursorChar; + char str[MAX_EDIT_LINE]; + int size; + + size = SMALLCHAR_WIDTH; + + drawLen = widthInChars; + len = strlen( buffer ) + 1; + + // guarantee that cursor will be visible + if ( len <= drawLen ) { + prestep = 0; + } else { + if ( scroll + drawLen > len ) { + scroll = len - drawLen; + if ( scroll < 0 ) { + scroll = 0; + } + } + prestep = scroll; + + // Skip color code + if ( idStr::IsColor( buffer + prestep ) ) { + prestep += 2; + } + if ( prestep > 0 && idStr::IsColor( buffer + prestep - 1 ) ) { + prestep++; + } + } + + if ( prestep + drawLen > len ) { + drawLen = len - prestep; + } + + // extract characters from the field at + if ( drawLen >= MAX_EDIT_LINE ) { + common->Error( "drawLen >= MAX_EDIT_LINE" ); + } + + memcpy( str, buffer + prestep, drawLen ); + str[ drawLen ] = 0; + + // draw it + renderSystem->DrawSmallStringExt( x, y, str, colorWhite, false, shader ); + + // draw the cursor + if ( !showCursor ) { + return; + } + + if ( (int)( com_ticNumber >> 4 ) & 1 ) { + return; // off blink + } + + if ( idKeyInput::GetOverstrikeMode() ) { + cursorChar = 11; + } else { + cursorChar = 10; + } + + // Move the cursor back to account for color codes + for ( int i = 0; iDrawSmallChar( x + ( cursor - prestep ) * size, y, cursorChar, shader ); +} diff --git a/framework/EditField.h b/framework/EditField.h new file mode 100644 index 000000000..3b90b8192 --- /dev/null +++ b/framework/EditField.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __EDITFIELD_H__ +#define __EDITFIELD_H__ + +/* +=============================================================================== + + Edit field + +=============================================================================== +*/ + +const int MAX_EDIT_LINE = 256; + +typedef struct autoComplete_s { + bool valid; + int length; + char completionString[MAX_EDIT_LINE]; + char currentMatch[MAX_EDIT_LINE]; + int matchCount; + int matchIndex; + int findMatchIndex; +} autoComplete_t; + +class idEditField { +public: + idEditField(); + ~idEditField(); + + void Clear( void ); + void SetWidthInChars( int w ); + void SetCursor( int c ); + int GetCursor( void ) const; + void ClearAutoComplete( void ); + int GetAutoCompleteLength( void ) const; + void AutoComplete( void ); + void CharEvent( int c ); + void KeyDownEvent( int key ); + void Paste( void ); + char * GetBuffer( void ); + void Draw( int x, int y, int width, bool showCursor, const idMaterial *material ); + void SetBuffer( const char *buffer ); + +private: + int cursor; + int scroll; + int widthInChars; + char buffer[MAX_EDIT_LINE]; + autoComplete_t autoComplete; +}; + +#endif /* !__EDITFIELD_H__ */ diff --git a/framework/EventLoop.cpp b/framework/EventLoop.cpp new file mode 100644 index 000000000..04ff96bb8 --- /dev/null +++ b/framework/EventLoop.cpp @@ -0,0 +1,265 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +idCVar idEventLoop::com_journal( "com_journal", "0", CVAR_INIT|CVAR_SYSTEM, "1 = record journal, 2 = play back journal", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); + +idEventLoop eventLoopLocal; +idEventLoop *eventLoop = &eventLoopLocal; + + +/* +================= +idEventLoop::idEventLoop +================= +*/ +idEventLoop::idEventLoop( void ) { + com_journalFile = NULL; + com_journalDataFile = NULL; + initialTimeOffset = 0; +} + +/* +================= +idEventLoop::~idEventLoop +================= +*/ +idEventLoop::~idEventLoop( void ) { +} + +/* +================= +idEventLoop::GetRealEvent +================= +*/ +sysEvent_t idEventLoop::GetRealEvent( void ) { + int r; + sysEvent_t ev; + + // either get an event from the system or the journal file + if ( com_journal.GetInteger() == 2 ) { + r = com_journalFile->Read( &ev, sizeof(ev) ); + if ( r != sizeof(ev) ) { + common->FatalError( "Error reading from journal file" ); + } + if ( ev.evPtrLength ) { + ev.evPtr = Mem_ClearedAlloc( ev.evPtrLength ); + r = com_journalFile->Read( ev.evPtr, ev.evPtrLength ); + if ( r != ev.evPtrLength ) { + common->FatalError( "Error reading from journal file" ); + } + } + } else { + ev = Sys_GetEvent(); + + // write the journal value out if needed + if ( com_journal.GetInteger() == 1 ) { + r = com_journalFile->Write( &ev, sizeof(ev) ); + if ( r != sizeof(ev) ) { + common->FatalError( "Error writing to journal file" ); + } + if ( ev.evPtrLength ) { + r = com_journalFile->Write( ev.evPtr, ev.evPtrLength ); + if ( r != ev.evPtrLength ) { + common->FatalError( "Error writing to journal file" ); + } + } + } + } + + return ev; +} + +/* +================= +idEventLoop::PushEvent +================= +*/ +void idEventLoop::PushEvent( sysEvent_t *event ) { + sysEvent_t *ev; + static bool printedWarning; + + ev = &com_pushedEvents[ com_pushedEventsHead & (MAX_PUSHED_EVENTS-1) ]; + + if ( com_pushedEventsHead - com_pushedEventsTail >= MAX_PUSHED_EVENTS ) { + + // don't print the warning constantly, or it can give time for more... + if ( !printedWarning ) { + printedWarning = true; + common->Printf( "WARNING: Com_PushEvent overflow\n" ); + } + + if ( ev->evPtr ) { + Mem_Free( ev->evPtr ); + } + com_pushedEventsTail++; + } else { + printedWarning = false; + } + + *ev = *event; + com_pushedEventsHead++; +} + +/* +================= +idEventLoop::GetEvent +================= +*/ +sysEvent_t idEventLoop::GetEvent( void ) { + if ( com_pushedEventsHead > com_pushedEventsTail ) { + com_pushedEventsTail++; + return com_pushedEvents[ (com_pushedEventsTail-1) & (MAX_PUSHED_EVENTS-1) ]; + } + return GetRealEvent(); +} + +/* +================= +idEventLoop::ProcessEvent +================= +*/ +void idEventLoop::ProcessEvent( sysEvent_t ev ) { + // track key up / down states + if ( ev.evType == SE_KEY ) { + idKeyInput::PreliminaryKeyEvent( ev.evValue, ( ev.evValue2 != 0 ) ); + } + + if ( ev.evType == SE_CONSOLE ) { + // from a text console outside the game window + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, (char *)ev.evPtr ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" ); + } else { + session->ProcessEvent( &ev ); + } + + // free any block data + if ( ev.evPtr ) { + Mem_Free( ev.evPtr ); + } +} + +/* +=============== +idEventLoop::RunEventLoop +=============== +*/ +int idEventLoop::RunEventLoop( bool commandExecution ) { + sysEvent_t ev; + + while ( 1 ) { + + if ( commandExecution ) { + // execute any bound commands before processing another event + cmdSystem->ExecuteCommandBuffer(); + } + + ev = GetEvent(); + + // if no more events are available + if ( ev.evType == SE_NONE ) { + return 0; + } + ProcessEvent( ev ); + } + + return 0; // never reached +} + +/* +============= +idEventLoop::Init +============= +*/ +void idEventLoop::Init( void ) { + + initialTimeOffset = Sys_Milliseconds(); + + common->StartupVariable( "journal", false ); + + if ( com_journal.GetInteger() == 1 ) { + common->Printf( "Journaling events\n" ); + com_journalFile = fileSystem->OpenFileWrite( "journal.dat" ); + com_journalDataFile = fileSystem->OpenFileWrite( "journaldata.dat" ); + } else if ( com_journal.GetInteger() == 2 ) { + common->Printf( "Replaying journaled events\n" ); + com_journalFile = fileSystem->OpenFileRead( "journal.dat" ); + com_journalDataFile = fileSystem->OpenFileRead( "journaldata.dat" ); + } + + if ( !com_journalFile || !com_journalDataFile ) { + com_journal.SetInteger( 0 ); + com_journalFile = 0; + com_journalDataFile = 0; + common->Printf( "Couldn't open journal files\n" ); + } +} + +/* +============= +idEventLoop::Shutdown +============= +*/ +void idEventLoop::Shutdown( void ) { + if ( com_journalFile ) { + fileSystem->CloseFile( com_journalFile ); + com_journalFile = NULL; + } + if ( com_journalDataFile ) { + fileSystem->CloseFile( com_journalDataFile ); + com_journalDataFile = NULL; + } +} + +/* +================ +idEventLoop::Milliseconds + +Can be used for profiling, but will be journaled accurately +================ +*/ +int idEventLoop::Milliseconds( void ) { +#if 1 // FIXME! + return Sys_Milliseconds() - initialTimeOffset; +#else + sysEvent_t ev; + + // get events and push them until we get a null event with the current time + do { + + ev = Com_GetRealEvent(); + if ( ev.evType != SE_NONE ) { + Com_PushEvent( &ev ); + } + } while ( ev.evType != SE_NONE ); + + return ev.evTime; +#endif +} + +/* +================ +idEventLoop::JournalLevel +================ +*/ +int idEventLoop::JournalLevel( void ) const { + return com_journal.GetInteger(); +} diff --git a/framework/EventLoop.h b/framework/EventLoop.h new file mode 100644 index 000000000..28d67c83a --- /dev/null +++ b/framework/EventLoop.h @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __EVENTLOOP_H__ +#define __EVENTLOOP_H__ + +/* +=============================================================================== + + The event loop receives events from the system and dispatches them to + the various parts of the engine. The event loop also handles journaling. + The file system copies .cfg files to the journaled file. + +=============================================================================== +*/ + +const int MAX_PUSHED_EVENTS = 64; + +class idEventLoop { +public: + idEventLoop( void ); + ~idEventLoop( void ); + + void Init( void ); + + // Closes the journal file if needed. + void Shutdown( void ); + + // It is possible to get an event at the beginning of a frame that + // has a time stamp lower than the last event from the previous frame. + sysEvent_t GetEvent( void ); + + // Dispatches all pending events and returns the current time. + int RunEventLoop( bool commandExecution = true ); + + // Gets the current time in a way that will be journaled properly, + // as opposed to Sys_Milliseconds(), which always reads a real timer. + int Milliseconds( void ); + + // Returns the journal level, 1 = record, 2 = play back. + int JournalLevel( void ) const; + + // Journal file. + idFile * com_journalFile; + idFile * com_journalDataFile; + +private: + // all events will have this subtracted from their time + int initialTimeOffset; + + int com_pushedEventsHead, com_pushedEventsTail; + sysEvent_t com_pushedEvents[MAX_PUSHED_EVENTS]; + + static idCVar com_journal; + + sysEvent_t GetRealEvent( void ); + void ProcessEvent( sysEvent_t ev ); + void PushEvent( sysEvent_t *event ); +}; + +extern idEventLoop *eventLoop; + +#endif /* !__EVENTLOOP_H__ */ diff --git a/framework/File.cpp b/framework/File.cpp new file mode 100644 index 000000000..b91343c5f --- /dev/null +++ b/framework/File.cpp @@ -0,0 +1,1356 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Unzip.h" + +#define MAX_PRINT_MSG 4096 + +/* +================= +FS_WriteFloatString +================= +*/ +int FS_WriteFloatString( char *buf, const char *fmt, va_list argPtr ) { + long i; + unsigned long u; + double f; + char *str; + int index; + idStr tmp, format; + + index = 0; + + while( *fmt ) { + switch( *fmt ) { + case '%': + format = ""; + format += *fmt++; + while ( (*fmt >= '0' && *fmt <= '9') || + *fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') { + format += *fmt++; + } + format += *fmt; + switch( *fmt ) { + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + f = va_arg( argPtr, double ); + if ( format.Length() <= 2 ) { + // high precision floating point number without trailing zeros + sprintf( tmp, "%1.10f", f ); + tmp.StripTrailing( '0' ); + tmp.StripTrailing( '.' ); + index += sprintf( buf+index, "%s", tmp.c_str() ); + } + else { + index += sprintf( buf+index, format.c_str(), f ); + } + break; + case 'd': + case 'i': + i = va_arg( argPtr, long ); + index += sprintf( buf+index, format.c_str(), i ); + break; + case 'u': + u = va_arg( argPtr, unsigned long ); + index += sprintf( buf+index, format.c_str(), u ); + break; + case 'o': + u = va_arg( argPtr, unsigned long ); + index += sprintf( buf+index, format.c_str(), u ); + break; + case 'x': + u = va_arg( argPtr, unsigned long ); + index += sprintf( buf+index, format.c_str(), u ); + break; + case 'X': + u = va_arg( argPtr, unsigned long ); + index += sprintf( buf+index, format.c_str(), u ); + break; + case 'c': + i = va_arg( argPtr, long ); + index += sprintf( buf+index, format.c_str(), (char) i ); + break; + case 's': + str = va_arg( argPtr, char * ); + index += sprintf( buf+index, format.c_str(), str ); + break; + case '%': + index += sprintf( buf+index, format.c_str() ); + break; + default: + common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() ); + break; + } + fmt++; + break; + case '\\': + fmt++; + switch( *fmt ) { + case 't': + index += sprintf( buf+index, "\t" ); + break; + case 'v': + index += sprintf( buf+index, "\v" ); + break; + case 'n': + index += sprintf( buf+index, "\n" ); + break; + case '\\': + index += sprintf( buf+index, "\\" ); + break; + default: + common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt ); + break; + } + fmt++; + break; + default: + index += sprintf( buf+index, "%c", *fmt ); + fmt++; + break; + } + } + + return index; +} + +/* +================================================================================= + +idFile + +================================================================================= +*/ + +/* +================= +idFile::GetName +================= +*/ +const char *idFile::GetName( void ) { + return ""; +} + +/* +================= +idFile::GetFullPath +================= +*/ +const char *idFile::GetFullPath( void ) { + return ""; +} + +/* +================= +idFile::Read +================= +*/ +int idFile::Read( void *buffer, int len ) { + common->FatalError( "idFile::Read: cannot read from idFile" ); + return 0; +} + +/* +================= +idFile::Write +================= +*/ +int idFile::Write( const void *buffer, int len ) { + common->FatalError( "idFile::Write: cannot write to idFile" ); + return 0; +} + +/* +================= +idFile::Length +================= +*/ +int idFile::Length( void ) { + return 0; +} + +/* +================= +idFile::Timestamp +================= +*/ +ID_TIME_T idFile::Timestamp( void ) { + return 0; +} + +/* +================= +idFile::Tell +================= +*/ +int idFile::Tell( void ) { + return 0; +} + +/* +================= +idFile::ForceFlush +================= +*/ +void idFile::ForceFlush( void ) { +} + +/* +================= +idFile::Flush +================= +*/ +void idFile::Flush( void ) { +} + +/* +================= +idFile::Seek +================= +*/ +int idFile::Seek( long offset, fsOrigin_t origin ) { + return -1; +} + +/* +================= +idFile::Rewind +================= +*/ +void idFile::Rewind( void ) { + Seek( 0, FS_SEEK_SET ); +} + +/* +================= +idFile::Printf +================= +*/ +int idFile::Printf( const char *fmt, ... ) { + char buf[MAX_PRINT_MSG]; + int length; + va_list argptr; + + va_start( argptr, fmt ); + length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, argptr ); + va_end( argptr ); + + // so notepad formats the lines correctly + idStr work( buf ); + work.Replace( "\n", "\r\n" ); + + return Write( work.c_str(), work.Length() ); +} + +/* +================= +idFile::VPrintf +================= +*/ +int idFile::VPrintf( const char *fmt, va_list args ) { + char buf[MAX_PRINT_MSG]; + int length; + + length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, args ); + return Write( buf, length ); +} + +/* +================= +idFile::WriteFloatString +================= +*/ +int idFile::WriteFloatString( const char *fmt, ... ) { + char buf[MAX_PRINT_MSG]; + int len; + va_list argPtr; + + va_start( argPtr, fmt ); + len = FS_WriteFloatString( buf, fmt, argPtr ); + va_end( argPtr ); + + return Write( buf, len ); +} + +/* + ================= + idFile::ReadInt + ================= + */ +int idFile::ReadInt( int &value ) { + int result = Read( &value, sizeof( value ) ); + value = LittleLong(value); + return result; +} + +/* + ================= + idFile::ReadUnsignedInt + ================= + */ +int idFile::ReadUnsignedInt( unsigned int &value ) { + int result = Read( &value, sizeof( value ) ); + value = LittleLong(value); + return result; +} + +/* + ================= + idFile::ReadShort + ================= + */ +int idFile::ReadShort( short &value ) { + int result = Read( &value, sizeof( value ) ); + value = LittleShort(value); + return result; +} + +/* + ================= + idFile::ReadUnsignedShort + ================= + */ +int idFile::ReadUnsignedShort( unsigned short &value ) { + int result = Read( &value, sizeof( value ) ); + value = LittleShort(value); + return result; +} + +/* + ================= + idFile::ReadChar + ================= + */ +int idFile::ReadChar( char &value ) { + return Read( &value, sizeof( value ) ); +} + +/* + ================= + idFile::ReadUnsignedChar + ================= + */ +int idFile::ReadUnsignedChar( unsigned char &value ) { + return Read( &value, sizeof( value ) ); +} + +/* + ================= + idFile::ReadFloat + ================= + */ +int idFile::ReadFloat( float &value ) { + int result = Read( &value, sizeof( value ) ); + value = LittleFloat(value); + return result; +} + +/* + ================= + idFile::ReadBool + ================= + */ +int idFile::ReadBool( bool &value ) { + unsigned char c; + int result = ReadUnsignedChar( c ); + value = c ? true : false; + return result; +} + +/* + ================= + idFile::ReadString + ================= + */ +int idFile::ReadString( idStr &string ) { + int len; + int result = 0; + + ReadInt( len ); + if ( len >= 0 ) { + string.Fill( ' ', len ); + result = Read( &string[ 0 ], len ); + } + return result; +} + +/* + ================= + idFile::ReadVec2 + ================= + */ +int idFile::ReadVec2( idVec2 &vec ) { + int result = Read( &vec, sizeof( vec ) ); + LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) ); + return result; +} + +/* + ================= + idFile::ReadVec3 + ================= + */ +int idFile::ReadVec3( idVec3 &vec ) { + int result = Read( &vec, sizeof( vec ) ); + LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) ); + return result; +} + +/* + ================= + idFile::ReadVec4 + ================= + */ +int idFile::ReadVec4( idVec4 &vec ) { + int result = Read( &vec, sizeof( vec ) ); + LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) ); + return result; +} + +/* + ================= + idFile::ReadVec6 + ================= + */ +int idFile::ReadVec6( idVec6 &vec ) { + int result = Read( &vec, sizeof( vec ) ); + LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) ); + return result; +} + +/* + ================= + idFile::ReadMat3 + ================= + */ +int idFile::ReadMat3( idMat3 &mat ) { + int result = Read( &mat, sizeof( mat ) ); + LittleRevBytes( &mat, sizeof(float), sizeof(mat)/sizeof(float) ); + return result; +} + +/* + ================= + idFile::WriteInt + ================= + */ +int idFile::WriteInt( const int value ) { + int v = LittleLong(value); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteUnsignedInt + ================= + */ +int idFile::WriteUnsignedInt( const unsigned int value ) { + unsigned int v = LittleLong(value); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteShort + ================= + */ +int idFile::WriteShort( const short value ) { + short v = LittleShort(value); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteUnsignedShort + ================= + */ +int idFile::WriteUnsignedShort( const unsigned short value ) { + unsigned short v = LittleShort(value); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteChar + ================= + */ +int idFile::WriteChar( const char value ) { + return Write( &value, sizeof( value ) ); +} + +/* + ================= + idFile::WriteUnsignedChar + ================= + */ +int idFile::WriteUnsignedChar( const unsigned char value ) { + return Write( &value, sizeof( value ) ); +} + +/* + ================= + idFile::WriteFloat + ================= + */ +int idFile::WriteFloat( const float value ) { + float v = LittleFloat(value); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteBool + ================= + */ +int idFile::WriteBool( const bool value ) { + unsigned char c = value; + return WriteUnsignedChar( c ); +} + +/* + ================= + idFile::WriteString + ================= + */ +int idFile::WriteString( const char *value ) { + int len; + + len = strlen( value ); + WriteInt( len ); + return Write( value, len ); +} + +/* + ================= + idFile::WriteVec2 + ================= + */ +int idFile::WriteVec2( const idVec2 &vec ) { + idVec2 v = vec; + LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) ); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteVec3 + ================= + */ +int idFile::WriteVec3( const idVec3 &vec ) { + idVec3 v = vec; + LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) ); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteVec4 + ================= + */ +int idFile::WriteVec4( const idVec4 &vec ) { + idVec4 v = vec; + LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) ); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteVec6 + ================= + */ +int idFile::WriteVec6( const idVec6 &vec ) { + idVec6 v = vec; + LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) ); + return Write( &v, sizeof( v ) ); +} + +/* + ================= + idFile::WriteMat3 + ================= + */ +int idFile::WriteMat3( const idMat3 &mat ) { + idMat3 v = mat; + LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) ); + return Write( &v, sizeof( v ) ); +} + +/* +================================================================================= + +idFile_Memory + +================================================================================= +*/ + + +/* +================= +idFile_Memory::idFile_Memory +================= +*/ +idFile_Memory::idFile_Memory( void ) { + name = "*unknown*"; + maxSize = 0; + fileSize = 0; + allocated = 0; + granularity = 16384; + + mode = ( 1 << FS_WRITE ); + filePtr = NULL; + curPtr = NULL; +} + +/* +================= +idFile_Memory::idFile_Memory +================= +*/ +idFile_Memory::idFile_Memory( const char *name ) { + this->name = name; + maxSize = 0; + fileSize = 0; + allocated = 0; + granularity = 16384; + + mode = ( 1 << FS_WRITE ); + filePtr = NULL; + curPtr = NULL; +} + +/* +================= +idFile_Memory::idFile_Memory +================= +*/ +idFile_Memory::idFile_Memory( const char *name, char *data, int length ) { + this->name = name; + maxSize = length; + fileSize = 0; + allocated = length; + granularity = 16384; + + mode = ( 1 << FS_WRITE ); + filePtr = data; + curPtr = data; +} + +/* +================= +idFile_Memory::idFile_Memory +================= +*/ +idFile_Memory::idFile_Memory( const char *name, const char *data, int length ) { + this->name = name; + maxSize = 0; + fileSize = length; + allocated = 0; + granularity = 16384; + + mode = ( 1 << FS_READ ); + filePtr = const_cast(data); + curPtr = const_cast(data); +} + +/* +================= +idFile_Memory::~idFile_Memory +================= +*/ +idFile_Memory::~idFile_Memory( void ) { + if ( filePtr && allocated > 0 && maxSize == 0 ) { + Mem_Free( filePtr ); + } +} + +/* +================= +idFile_Memory::Read +================= +*/ +int idFile_Memory::Read( void *buffer, int len ) { + + if ( !( mode & ( 1 << FS_READ ) ) ) { + common->FatalError( "idFile_Memory::Read: %s not opened in read mode", name.c_str() ); + return 0; + } + + if ( curPtr + len > filePtr + fileSize ) { + len = filePtr + fileSize - curPtr; + } + memcpy( buffer, curPtr, len ); + curPtr += len; + return len; +} + +/* +================= +idFile_Memory::Write +================= +*/ +int idFile_Memory::Write( const void *buffer, int len ) { + + if ( !( mode & ( 1 << FS_WRITE ) ) ) { + common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() ); + return 0; + } + + int alloc = curPtr + len + 1 - filePtr - allocated; // need room for len+1 + if ( alloc > 0 ) { + if ( maxSize != 0 ) { + common->Error( "idFile_Memory::Write: exceeded maximum size %d", maxSize ); + return 0; + } + int extra = granularity * ( 1 + alloc / granularity ); + char *newPtr = (char *) Mem_Alloc( allocated + extra ); + if ( allocated ) { + memcpy( newPtr, filePtr, allocated ); + } + allocated += extra; + curPtr = newPtr + ( curPtr - filePtr ); + if ( filePtr ) { + Mem_Free( filePtr ); + } + filePtr = newPtr; + } + memcpy( curPtr, buffer, len ); + curPtr += len; + fileSize += len; + filePtr[ fileSize ] = 0; // len + 1 + return len; +} + +/* +================= +idFile_Memory::Length +================= +*/ +int idFile_Memory::Length( void ) { + return fileSize; +} + +/* +================= +idFile_Memory::Timestamp +================= +*/ +ID_TIME_T idFile_Memory::Timestamp( void ) { + return 0; +} + +/* +================= +idFile_Memory::Tell +================= +*/ +int idFile_Memory::Tell( void ) { + return ( curPtr - filePtr ); +} + +/* +================= +idFile_Memory::ForceFlush +================= +*/ +void idFile_Memory::ForceFlush( void ) { +} + +/* +================= +idFile_Memory::Flush +================= +*/ +void idFile_Memory::Flush( void ) { +} + +/* +================= +idFile_Memory::Seek + + returns zero on success and -1 on failure +================= +*/ +int idFile_Memory::Seek( long offset, fsOrigin_t origin ) { + + switch( origin ) { + case FS_SEEK_CUR: { + curPtr += offset; + break; + } + case FS_SEEK_END: { + curPtr = filePtr + fileSize - offset; + break; + } + case FS_SEEK_SET: { + curPtr = filePtr + offset; + break; + } + default: { + common->FatalError( "idFile_Memory::Seek: bad origin for %s\n", name.c_str() ); + return -1; + } + } + if ( curPtr < filePtr ) { + curPtr = filePtr; + return -1; + } + if ( curPtr > filePtr + fileSize ) { + curPtr = filePtr + fileSize; + return -1; + } + return 0; +} + +/* +================= +idFile_Memory::MakeReadOnly +================= +*/ +void idFile_Memory::MakeReadOnly( void ) { + mode = ( 1 << FS_READ ); + Rewind(); +} + +/* +================= +idFile_Memory::Clear +================= +*/ +void idFile_Memory::Clear( bool freeMemory ) { + fileSize = 0; + granularity = 16384; + if ( freeMemory ) { + allocated = 0; + Mem_Free( filePtr ); + filePtr = NULL; + curPtr = NULL; + } else { + curPtr = filePtr; + } +} + +/* +================= +idFile_Memory::SetData +================= +*/ +void idFile_Memory::SetData( const char *data, int length ) { + maxSize = 0; + fileSize = length; + allocated = 0; + granularity = 16384; + + mode = ( 1 << FS_READ ); + filePtr = const_cast(data); + curPtr = const_cast(data); +} + + +/* +================================================================================= + +idFile_BitMsg + +================================================================================= +*/ + +/* +================= +idFile_BitMsg::idFile_BitMsg +================= +*/ +idFile_BitMsg::idFile_BitMsg( idBitMsg &msg ) { + name = "*unknown*"; + mode = ( 1 << FS_WRITE ); + this->msg = &msg; +} + +/* +================= +idFile_BitMsg::idFile_BitMsg +================= +*/ +idFile_BitMsg::idFile_BitMsg( const idBitMsg &msg ) { + name = "*unknown*"; + mode = ( 1 << FS_READ ); + this->msg = const_cast(&msg); +} + +/* +================= +idFile_BitMsg::~idFile_BitMsg +================= +*/ +idFile_BitMsg::~idFile_BitMsg( void ) { +} + +/* +================= +idFile_BitMsg::Read +================= +*/ +int idFile_BitMsg::Read( void *buffer, int len ) { + + if ( !( mode & ( 1 << FS_READ ) ) ) { + common->FatalError( "idFile_BitMsg::Read: %s not opened in read mode", name.c_str() ); + return 0; + } + + return msg->ReadData( buffer, len ); +} + +/* +================= +idFile_BitMsg::Write +================= +*/ +int idFile_BitMsg::Write( const void *buffer, int len ) { + + if ( !( mode & ( 1 << FS_WRITE ) ) ) { + common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() ); + return 0; + } + + msg->WriteData( buffer, len ); + return len; +} + +/* +================= +idFile_BitMsg::Length +================= +*/ +int idFile_BitMsg::Length( void ) { + return msg->GetSize(); +} + +/* +================= +idFile_BitMsg::Timestamp +================= +*/ +ID_TIME_T idFile_BitMsg::Timestamp( void ) { + return 0; +} + +/* +================= +idFile_BitMsg::Tell +================= +*/ +int idFile_BitMsg::Tell( void ) { + if ( mode & FS_READ ) { + return msg->GetReadCount(); + } else { + return msg->GetSize(); + } +} + +/* +================= +idFile_BitMsg::ForceFlush +================= +*/ +void idFile_BitMsg::ForceFlush( void ) { +} + +/* +================= +idFile_BitMsg::Flush +================= +*/ +void idFile_BitMsg::Flush( void ) { +} + +/* +================= +idFile_BitMsg::Seek + + returns zero on success and -1 on failure +================= +*/ +int idFile_BitMsg::Seek( long offset, fsOrigin_t origin ) { + return -1; +} + + +/* +================================================================================= + +idFile_Permanent + +================================================================================= +*/ + +/* +================= +idFile_Permanent::idFile_Permanent +================= +*/ +idFile_Permanent::idFile_Permanent( void ) { + name = "invalid"; + o = NULL; + mode = 0; + fileSize = 0; + handleSync = false; +} + +/* +================= +idFile_Permanent::~idFile_Permanent +================= +*/ +idFile_Permanent::~idFile_Permanent( void ) { + if ( o ) { + fclose( o ); + } +} + +/* +================= +idFile_Permanent::Read + +Properly handles partial reads +================= +*/ +int idFile_Permanent::Read( void *buffer, int len ) { + int block, remaining; + int read; + byte * buf; + int tries; + + if ( !(mode & ( 1 << FS_READ ) ) ) { + common->FatalError( "idFile_Permanent::Read: %s not opened in read mode", name.c_str() ); + return 0; + } + + if ( !o ) { + return 0; + } + + buf = (byte *)buffer; + + remaining = len; + tries = 0; + while( remaining ) { + block = remaining; + read = fread( buf, 1, block, o ); + if ( read == 0 ) { + // we might have been trying to read from a CD, which + // sometimes returns a 0 read on windows + if ( !tries ) { + tries = 1; + } + else { + fileSystem->AddToReadCount( len - remaining ); + return len-remaining; + } + } + + if ( read == -1 ) { + common->FatalError( "idFile_Permanent::Read: -1 bytes read from %s", name.c_str() ); + } + + remaining -= read; + buf += read; + } + fileSystem->AddToReadCount( len ); + return len; +} + +/* +================= +idFile_Permanent::Write + +Properly handles partial writes +================= +*/ +int idFile_Permanent::Write( const void *buffer, int len ) { + int block, remaining; + int written; + byte * buf; + int tries; + + if ( !( mode & ( 1 << FS_WRITE ) ) ) { + common->FatalError( "idFile_Permanent::Write: %s not opened in write mode", name.c_str() ); + return 0; + } + + if ( !o ) { + return 0; + } + + buf = (byte *)buffer; + + remaining = len; + tries = 0; + while( remaining ) { + block = remaining; + written = fwrite( buf, 1, block, o ); + if ( written == 0 ) { + if ( !tries ) { + tries = 1; + } + else { + common->Printf( "idFile_Permanent::Write: 0 bytes written to %s\n", name.c_str() ); + return 0; + } + } + + if ( written == -1 ) { + common->Printf( "idFile_Permanent::Write: -1 bytes written to %s\n", name.c_str() ); + return 0; + } + + remaining -= written; + buf += written; + fileSize += written; + } + if ( handleSync ) { + fflush( o ); + } + return len; +} + +/* +================= +idFile_Permanent::ForceFlush +================= +*/ +void idFile_Permanent::ForceFlush( void ) { + setvbuf( o, NULL, _IONBF, 0 ); +} + +/* +================= +idFile_Permanent::Flush +================= +*/ +void idFile_Permanent::Flush( void ) { + fflush( o ); +} + +/* +================= +idFile_Permanent::Tell +================= +*/ +int idFile_Permanent::Tell( void ) { + return ftell( o ); +} + +/* +================ +idFile_Permanent::Length +================ +*/ +int idFile_Permanent::Length( void ) { + return fileSize; +} + +/* +================ +idFile_Permanent::Timestamp +================ +*/ +ID_TIME_T idFile_Permanent::Timestamp( void ) { + return Sys_FileTimeStamp( o ); +} + +/* +================= +idFile_Permanent::Seek + + returns zero on success and -1 on failure +================= +*/ +int idFile_Permanent::Seek( long offset, fsOrigin_t origin ) { + int _origin; + + switch( origin ) { + case FS_SEEK_CUR: { + _origin = SEEK_CUR; + break; + } + case FS_SEEK_END: { + _origin = SEEK_END; + break; + } + case FS_SEEK_SET: { + _origin = SEEK_SET; + break; + } + default: { + _origin = SEEK_CUR; + common->FatalError( "idFile_Permanent::Seek: bad origin for %s\n", name.c_str() ); + break; + } + } + + return fseek( o, offset, _origin ); +} + + +/* +================================================================================= + +idFile_InZip + +================================================================================= +*/ + +/* +================= +idFile_InZip::idFile_InZip +================= +*/ +idFile_InZip::idFile_InZip( void ) { + name = "invalid"; + zipFilePos = 0; + fileSize = 0; + memset( &z, 0, sizeof( z ) ); +} + +/* +================= +idFile_InZip::~idFile_InZip +================= +*/ +idFile_InZip::~idFile_InZip( void ) { + unzCloseCurrentFile( z ); + unzClose( z ); +} + +/* +================= +idFile_InZip::Read + +Properly handles partial reads +================= +*/ +int idFile_InZip::Read( void *buffer, int len ) { + int l = unzReadCurrentFile( z, buffer, len ); + fileSystem->AddToReadCount( l ); + return l; +} + +/* +================= +idFile_InZip::Write +================= +*/ +int idFile_InZip::Write( const void *buffer, int len ) { + common->FatalError( "idFile_InZip::Write: cannot write to the zipped file %s", name.c_str() ); + return 0; +} + +/* +================= +idFile_InZip::ForceFlush +================= +*/ +void idFile_InZip::ForceFlush( void ) { + common->FatalError( "idFile_InZip::ForceFlush: cannot flush the zipped file %s", name.c_str() ); +} + +/* +================= +idFile_InZip::Flush +================= +*/ +void idFile_InZip::Flush( void ) { + common->FatalError( "idFile_InZip::Flush: cannot flush the zipped file %s", name.c_str() ); +} + +/* +================= +idFile_InZip::Tell +================= +*/ +int idFile_InZip::Tell( void ) { + return unztell( z ); +} + +/* +================ +idFile_InZip::Length +================ +*/ +int idFile_InZip::Length( void ) { + return fileSize; +} + +/* +================ +idFile_InZip::Timestamp +================ +*/ +ID_TIME_T idFile_InZip::Timestamp( void ) { + return 0; +} + +/* +================= +idFile_InZip::Seek + + returns zero on success and -1 on failure +================= +*/ +#define ZIP_SEEK_BUF_SIZE (1<<15) + +int idFile_InZip::Seek( long offset, fsOrigin_t origin ) { + int res, i; + char *buf; + + switch( origin ) { + case FS_SEEK_END: { + offset = fileSize - offset; + } + case FS_SEEK_SET: { + // set the file position in the zip file (also sets the current file info) + unzSetCurrentFileInfoPosition( z, zipFilePos ); + unzOpenCurrentFile( z ); + if ( offset <= 0 ) { + return 0; + } + } + case FS_SEEK_CUR: { + buf = (char *) _alloca16( ZIP_SEEK_BUF_SIZE ); + for ( i = 0; i < ( offset - ZIP_SEEK_BUF_SIZE ); i += ZIP_SEEK_BUF_SIZE ) { + res = unzReadCurrentFile( z, buf, ZIP_SEEK_BUF_SIZE ); + if ( res < ZIP_SEEK_BUF_SIZE ) { + return -1; + } + } + res = i + unzReadCurrentFile( z, buf, offset - i ); + return ( res == offset ) ? 0 : -1; + } + default: { + common->FatalError( "idFile_InZip::Seek: bad origin for %s\n", name.c_str() ); + break; + } + } + return -1; +} diff --git a/framework/File.h b/framework/File.h new file mode 100644 index 000000000..91c6a9703 --- /dev/null +++ b/framework/File.h @@ -0,0 +1,234 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FILE_H__ +#define __FILE_H__ + +/* +============================================================== + + File Streams. + +============================================================== +*/ + +// mode parm for Seek +typedef enum { + FS_SEEK_CUR, + FS_SEEK_END, + FS_SEEK_SET +} fsOrigin_t; + +class idFileSystemLocal; + + +class idFile { +public: + virtual ~idFile( void ) {}; + // Get the name of the file. + virtual const char * GetName( void ); + // Get the full file path. + virtual const char * GetFullPath( void ); + // Read data from the file to the buffer. + virtual int Read( void *buffer, int len ); + // Write data from the buffer to the file. + virtual int Write( const void *buffer, int len ); + // Returns the length of the file. + virtual int Length( void ); + // Return a time value for reload operations. + virtual ID_TIME_T Timestamp( void ); + // Returns offset in file. + virtual int Tell( void ); + // Forces flush on files being writting to. + virtual void ForceFlush( void ); + // Causes any buffered data to be written to the file. + virtual void Flush( void ); + // Seek on a file. + virtual int Seek( long offset, fsOrigin_t origin ); + // Go back to the beginning of the file. + virtual void Rewind( void ); + // Like fprintf. + virtual int Printf( const char *fmt, ... ) id_attribute((format(printf,2,3))); + // Like fprintf but with argument pointer + virtual int VPrintf( const char *fmt, va_list arg ); + // Write a string with high precision floating point numbers to the file. + virtual int WriteFloatString( const char *fmt, ... ) id_attribute((format(printf,2,3))); + + // Endian portable alternatives to Read(...) + virtual int ReadInt( int &value ); + virtual int ReadUnsignedInt( unsigned int &value ); + virtual int ReadShort( short &value ); + virtual int ReadUnsignedShort( unsigned short &value ); + virtual int ReadChar( char &value ); + virtual int ReadUnsignedChar( unsigned char &value ); + virtual int ReadFloat( float &value ); + virtual int ReadBool( bool &value ); + virtual int ReadString( idStr &string ); + virtual int ReadVec2( idVec2 &vec ); + virtual int ReadVec3( idVec3 &vec ); + virtual int ReadVec4( idVec4 &vec ); + virtual int ReadVec6( idVec6 &vec ); + virtual int ReadMat3( idMat3 &mat ); + + // Endian portable alternatives to Write(...) + virtual int WriteInt( const int value ); + virtual int WriteUnsignedInt( const unsigned int value ); + virtual int WriteShort( const short value ); + virtual int WriteUnsignedShort( unsigned short value ); + virtual int WriteChar( const char value ); + virtual int WriteUnsignedChar( const unsigned char value ); + virtual int WriteFloat( const float value ); + virtual int WriteBool( const bool value ); + virtual int WriteString( const char *string ); + virtual int WriteVec2( const idVec2 &vec ); + virtual int WriteVec3( const idVec3 &vec ); + virtual int WriteVec4( const idVec4 &vec ); + virtual int WriteVec6( const idVec6 &vec ); + virtual int WriteMat3( const idMat3 &mat ); +}; + + +class idFile_Memory : public idFile { + friend class idFileSystemLocal; + +public: + idFile_Memory( void ); // file for writing without name + idFile_Memory( const char *name ); // file for writing + idFile_Memory( const char *name, char *data, int length ); // file for writing + idFile_Memory( const char *name, const char *data, int length ); // file for reading + virtual ~idFile_Memory( void ); + + virtual const char * GetName( void ) { return name.c_str(); } + virtual const char * GetFullPath( void ) { return name.c_str(); } + virtual int Read( void *buffer, int len ); + virtual int Write( const void *buffer, int len ); + virtual int Length( void ); + virtual ID_TIME_T Timestamp( void ); + virtual int Tell( void ); + virtual void ForceFlush( void ); + virtual void Flush( void ); + virtual int Seek( long offset, fsOrigin_t origin ); + + // changes memory file to read only + virtual void MakeReadOnly( void ); + // clear the file + virtual void Clear( bool freeMemory = true ); + // set data for reading + void SetData( const char *data, int length ); + // returns const pointer to the memory buffer + const char * GetDataPtr( void ) const { return filePtr; } + // set the file granularity + void SetGranularity( int g ) { assert( g > 0 ); granularity = g; } + +private: + idStr name; // name of the file + int mode; // open mode + int maxSize; // maximum size of file + int fileSize; // size of the file + int allocated; // allocated size + int granularity; // file granularity + char * filePtr; // buffer holding the file data + char * curPtr; // current read/write pointer +}; + + +class idFile_BitMsg : public idFile { + friend class idFileSystemLocal; + +public: + idFile_BitMsg( idBitMsg &msg ); + idFile_BitMsg( const idBitMsg &msg ); + virtual ~idFile_BitMsg( void ); + + virtual const char * GetName( void ) { return name.c_str(); } + virtual const char * GetFullPath( void ) { return name.c_str(); } + virtual int Read( void *buffer, int len ); + virtual int Write( const void *buffer, int len ); + virtual int Length( void ); + virtual ID_TIME_T Timestamp( void ); + virtual int Tell( void ); + virtual void ForceFlush( void ); + virtual void Flush( void ); + virtual int Seek( long offset, fsOrigin_t origin ); + +private: + idStr name; // name of the file + int mode; // open mode + idBitMsg * msg; +}; + + +class idFile_Permanent : public idFile { + friend class idFileSystemLocal; + +public: + idFile_Permanent( void ); + virtual ~idFile_Permanent( void ); + + virtual const char * GetName( void ) { return name.c_str(); } + virtual const char * GetFullPath( void ) { return fullPath.c_str(); } + virtual int Read( void *buffer, int len ); + virtual int Write( const void *buffer, int len ); + virtual int Length( void ); + virtual ID_TIME_T Timestamp( void ); + virtual int Tell( void ); + virtual void ForceFlush( void ); + virtual void Flush( void ); + virtual int Seek( long offset, fsOrigin_t origin ); + + // returns file pointer + FILE * GetFilePtr( void ) { return o; } + +private: + idStr name; // relative path of the file - relative path + idStr fullPath; // full file path - OS path + int mode; // open mode + int fileSize; // size of the file + FILE * o; // file handle + bool handleSync; // true if written data is immediately flushed +}; + + +class idFile_InZip : public idFile { + friend class idFileSystemLocal; + +public: + idFile_InZip( void ); + virtual ~idFile_InZip( void ); + + virtual const char * GetName( void ) { return name.c_str(); } + virtual const char * GetFullPath( void ) { return fullPath.c_str(); } + virtual int Read( void *buffer, int len ); + virtual int Write( const void *buffer, int len ); + virtual int Length( void ); + virtual ID_TIME_T Timestamp( void ); + virtual int Tell( void ); + virtual void ForceFlush( void ); + virtual void Flush( void ); + virtual int Seek( long offset, fsOrigin_t origin ); + +private: + idStr name; // name of the file in the pak + idStr fullPath; // full file path including pak file name + int zipFilePos; // zip file info position in pak + int fileSize; // size of the file + void * z; // unzip info +}; + +#endif /* !__FILE_H__ */ diff --git a/framework/FileSystem.cpp b/framework/FileSystem.cpp new file mode 100644 index 000000000..a333174ae --- /dev/null +++ b/framework/FileSystem.cpp @@ -0,0 +1,4208 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Unzip.h" + +#ifdef WIN32 + #include // for _read +#else + #if !__MACH__ && __MWERKS__ + #include + #include + #else + #include + #include + #endif + #include +#endif + +#if ID_ENABLE_CURL + #include "../include/curl/curl.h" +#endif + +/* +============================================================================= + +DOOM FILESYSTEM + +All of Doom's data access is through a hierarchical file system, but the contents of +the file system can be transparently merged from several sources. + +A "relativePath" is a reference to game file data, which must include a terminating zero. +"..", "\\", and ":" are explicitly illegal in qpaths to prevent any references +outside the Doom directory system. + +The "base path" is the path to the directory holding all the game directories and +usually the executable. It defaults to the current directory, but can be overridden +with "+set fs_basepath c:\doom" on the command line. The base path cannot be modified +at all after startup. + +The "save path" is the path to the directory where game files will be saved. It defaults +to the base path, but can be overridden with a "+set fs_savepath c:\doom" on the +command line. Any files that are created during the game (demos, screenshots, etc.) will +be created reletive to the save path. + +The "cd path" is the path to an alternate hierarchy that will be searched if a file +is not located in the base path. A user can do a partial install that copies some +data to a base path created on their hard drive and leave the rest on the cd. It defaults +to the current directory, but it can be overridden with "+set fs_cdpath g:\doom" on the +command line. + +The "dev path" is the path to an alternate hierarchy where the editors and tools used +during development (Radiant, AF editor, dmap, runAAS) will write files to. It defaults to +the cd path, but can be overridden with a "+set fs_devpath c:\doom" on the command line. + +If a user runs the game directly from a CD, the base path would be on the CD. This +should still function correctly, but all file writes will fail (harmlessly). + +The "base game" is the directory under the paths where data comes from by default, and +can be either "base" or "demo". + +The "current game" may be the same as the base game, or it may be the name of another +directory under the paths that should be searched for files before looking in the base +game. The game directory is set with "+set fs_game myaddon" on the command line. This is +the basis for addons. + +No other directories outside of the base game and current game will ever be referenced by +filesystem functions. + +To save disk space and speed up file loading, directory trees can be collapsed into zip +files. The files use a ".pk4" extension to prevent users from unzipping them accidentally, +but otherwise they are simply normal zip files. A game directory can have multiple zip +files of the form "pak0.pk4", "pak1.pk4", etc. Zip files are searched in decending order +from the highest number to the lowest, and will always take precedence over the filesystem. +This allows a pk4 distributed as a patch to override all existing data. + +Because we will have updated executables freely available online, there is no point to +trying to restrict demo / oem versions of the game with code changes. Demo / oem versions +should be exactly the same executables as release versions, but with different data that +automatically restricts where game media can come from to prevent add-ons from working. + +After the paths are initialized, Doom will look for the product.txt file. If not found +and verified, the game will run in restricted mode. In restricted mode, only files +contained in demo/pak0.pk4 will be available for loading, and only if the zip header is +verified to not have been modified. A single exception is made for DoomConfig.cfg. Files +can still be written out in restricted mode, so screenshots and demos are allowed. +Restricted mode can be tested by setting "+set fs_restrict 1" on the command line, even +if there is a valid product.txt under the basepath or cdpath. + +If the "fs_copyfiles" cvar is set to 1, then every time a file is sourced from the cd +path, it will be copied over to the save path. This is a development aid to help build +test releases and to copy working sets of files. + +If the "fs_copyfiles" cvar is set to 2, any file found in fs_cdpath that is newer than +it's fs_savepath version will be copied to fs_savepath (in addition to the fs_copyfiles 1 +behaviour). + +If the "fs_copyfiles" cvar is set to 3, files from both basepath and cdpath will be copied +over to the save path. This is useful when copying working sets of files mainly from base +path with an additional cd path (which can be a slower network drive for instance). + +If the "fs_copyfiles" cvar is set to 4, files that exist in the cd path but NOT the base path +will be copied to the save path + +NOTE: fs_copyfiles and case sensitivity. On fs_caseSensitiveOS 0 filesystems ( win32 ), the +copied files may change casing when copied over. + +The relative path "sound/newstuff/test.wav" would be searched for in the following places: + +for save path, dev path, base path, cd path: + for current game, base game: + search directory + search zip files + +downloaded files, to be written to save path + current game's directory + +The filesystem can be safely shutdown and reinitialized with different +basedir / cddir / game combinations, but all other subsystems that rely on it +(sound, video) must also be forced to restart. + + +"fs_caseSensitiveOS": +This cvar is set on operating systems that use case sensitive filesystems (Linux and OSX) +It is a common situation to have the media reference filenames, whereas the file on disc +only matches in a case-insensitive way. When "fs_caseSensitiveOS" is set, the filesystem +will always do a case insensitive search. +IMPORTANT: This only applies to files, and not to directories. There is no case-insensitive +matching of directories. All directory names should be lowercase, when "com_developer" is 1, +the filesystem will warn when it catches bad directory situations (regardless of the +"fs_caseSensitiveOS" setting) +When bad casing in directories happen and "fs_caseSensitiveOS" is set, BuildOSPath will +attempt to correct the situation by forcing the path to lowercase. This assumes the media +is stored all lowercase. + +"additional mod path search": +fs_game_base can be used to set an additional search path +in search order, fs_game, fs_game_base, BASEGAME +for instance to base a mod of D3 + D3XP assets, fs_game mymod, fs_game_base d3xp + +============================================================================= +*/ + + + +// define to fix special-cases for GetPackStatus so that files that shipped in +// the wrong place for Doom 3 don't break pure servers. +#define DOOM3_PURE_SPECIAL_CASES + +typedef bool (*pureExclusionFunc_t)( const struct pureExclusion_s &excl, int l, const idStr &name ); + +typedef struct pureExclusion_s { + int nameLen; + int extLen; + const char * name; + const char * ext; + pureExclusionFunc_t func; +} pureExclusion_t; + +bool excludeExtension( const pureExclusion_t &excl, int l, const idStr &name ) { + if ( l > excl.extLen && !idStr::Icmp( name.c_str() + l - excl.extLen, excl.ext ) ) { + return true; + } + return false; +} + +bool excludePathPrefixAndExtension( const pureExclusion_t &excl, int l, const idStr &name ) { + if ( l > excl.nameLen && !idStr::Icmp( name.c_str() + l - excl.extLen, excl.ext ) && !name.IcmpPrefixPath( excl.name ) ) { + return true; + } + return false; +} + +bool excludeFullName( const pureExclusion_t &excl, int l, const idStr &name ) { + if ( l == excl.nameLen && !name.Icmp( excl.name ) ) { + return true; + } + return false; +} + +static pureExclusion_t pureExclusions[] = { + { 0, 0, NULL, "/", excludeExtension }, + { 0, 0, NULL, "\\", excludeExtension }, + { 0, 0, NULL, ".pda", excludeExtension }, + { 0, 0, NULL, ".gui", excludeExtension }, + { 0, 0, NULL, ".pd", excludeExtension }, + { 0, 0, NULL, ".lang", excludeExtension }, + { 0, 0, "sound/VO", ".ogg", excludePathPrefixAndExtension }, + { 0, 0, "sound/VO", ".wav", excludePathPrefixAndExtension }, +#if defined DOOM3_PURE_SPECIAL_CASES + // add any special-case files or paths for pure servers here + { 0, 0, "sound/ed/marscity/vo_intro_cutscene.ogg", NULL, excludeFullName }, + { 0, 0, "sound/weapons/soulcube/energize_01.ogg", NULL, excludeFullName }, + { 0, 0, "sound/xian/creepy/vocal_fx", ".ogg", excludePathPrefixAndExtension }, + { 0, 0, "sound/xian/creepy/vocal_fx", ".wav", excludePathPrefixAndExtension }, + { 0, 0, "sound/feedback", ".ogg", excludePathPrefixAndExtension }, + { 0, 0, "sound/feedback", ".wav", excludePathPrefixAndExtension }, + { 0, 0, "guis/assets/mainmenu/chnote.tga", NULL, excludeFullName }, + { 0, 0, "sound/levels/alphalabs2/uac_better_place.ogg", NULL, excludeFullName }, + { 0, 0, "textures/bigchars.tga", NULL, excludeFullName }, + { 0, 0, "dds/textures/bigchars.dds", NULL, excludeFullName }, + { 0, 0, "fonts", ".tga", excludePathPrefixAndExtension }, + { 0, 0, "dds/fonts", ".dds", excludePathPrefixAndExtension }, + { 0, 0, "default.cfg", NULL, excludeFullName }, + // russian zpak001.pk4 + { 0, 0, "fonts", ".dat", excludePathPrefixAndExtension }, + { 0, 0, "guis/temp.guied", NULL, excludeFullName }, +#endif + { 0, 0, NULL, NULL, NULL } +}; + +// ensures that lengths for pure exclusions are correct +class idInitExclusions { +public: + idInitExclusions() { + for ( int i = 0; pureExclusions[i].func != NULL; i++ ) { + if ( pureExclusions[i].name ) { + pureExclusions[i].nameLen = idStr::Length( pureExclusions[i].name ); + } + if ( pureExclusions[i].ext ) { + pureExclusions[i].extLen = idStr::Length( pureExclusions[i].ext ); + } + } + } +}; + +static idInitExclusions initExclusions; + +#define MAX_ZIPPED_FILE_NAME 2048 +#define FILE_HASH_SIZE 1024 + +typedef struct fileInPack_s { + idStr name; // name of the file + unsigned long pos; // file info position in zip + struct fileInPack_s * next; // next file in the hash +} fileInPack_t; + +typedef enum { + BINARY_UNKNOWN = 0, + BINARY_YES, + BINARY_NO +} binaryStatus_t; + +typedef enum { + PURE_UNKNOWN = 0, // need to run the pak through GetPackStatus + PURE_NEUTRAL, // neutral regarding pureness. gets in the pure list if referenced + PURE_ALWAYS, // always referenced - for pak* named files, unless NEVER + PURE_NEVER // VO paks. may be referenced, won't be in the pure lists +} pureStatus_t; + +typedef struct { + idList depends; + idList mapDecls; +} addonInfo_t; + +typedef struct { + idStr pakFilename; // c:\doom\base\pak0.pk4 + unzFile handle; + int checksum; + int numfiles; + int length; + bool referenced; + binaryStatus_t binary; + bool addon; // this is an addon pack - addon_search tells if it's 'active' + bool addon_search; // is in the search list + addonInfo_t *addon_info; + pureStatus_t pureStatus; + bool isNew; // for downloaded paks + fileInPack_t *hashTable[FILE_HASH_SIZE]; + fileInPack_t *buildBuffer; +} pack_t; + +typedef struct { + idStr path; // c:\doom + idStr gamedir; // base +} directory_t; + +typedef struct searchpath_s { + pack_t * pack; // only one of pack / dir will be non NULL + directory_t * dir; + struct searchpath_s *next; +} searchpath_t; + +// search flags when opening a file +#define FSFLAG_SEARCH_DIRS ( 1 << 0 ) +#define FSFLAG_SEARCH_PAKS ( 1 << 1 ) +#define FSFLAG_PURE_NOREF ( 1 << 2 ) +#define FSFLAG_BINARY_ONLY ( 1 << 3 ) +#define FSFLAG_SEARCH_ADDONS ( 1 << 4 ) + +// 3 search path (fs_savepath fs_basepath fs_cdpath) +// + .jpg and .tga +#define MAX_CACHED_DIRS 6 + +// how many OSes to handle game paks for ( we don't have to know them precisely ) +#define MAX_GAME_OS 6 +#define BINARY_CONFIG "binary.conf" +#define ADDON_CONFIG "addon.conf" + +class idDEntry : public idStrList { +public: + idDEntry() {} + virtual ~idDEntry() {} + + bool Matches( const char *directory, const char *extension ) const; + void Init( const char *directory, const char *extension, const idStrList &list ); + void Clear( void ); + +private: + idStr directory; + idStr extension; +}; + +class idFileSystemLocal : public idFileSystem { +public: + idFileSystemLocal( void ); + + virtual void Init( void ); + virtual void StartBackgroundDownloadThread( void ); + virtual void Restart( void ); + virtual void Shutdown( bool reloading ); + virtual bool IsInitialized( void ) const; + virtual bool PerformingCopyFiles( void ) const; + virtual idModList * ListMods( void ); + virtual void FreeModList( idModList *modList ); + virtual idFileList * ListFiles( const char *relativePath, const char *extension, bool sort = false, bool fullRelativePath = false, const char* gamedir = NULL ); + virtual idFileList * ListFilesTree( const char *relativePath, const char *extension, bool sort = false, const char* gamedir = NULL ); + virtual void FreeFileList( idFileList *fileList ); + virtual const char * OSPathToRelativePath( const char *OSPath ); + virtual const char * RelativePathToOSPath( const char *relativePath, const char *basePath ); + virtual const char * BuildOSPath( const char *base, const char *game, const char *relativePath ); + virtual void CreateOSPath( const char *OSPath ); + virtual bool FileIsInPAK( const char *relativePath ); + virtual void UpdatePureServerChecksums( void ); + virtual bool UpdateGamePakChecksums( void ); + virtual fsPureReply_t SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum, int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum ); + virtual void GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int *gamePakChecksum ); + virtual void SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ); + virtual void ClearPureChecksums( void ); + virtual int GetOSMask( void ); + virtual int ReadFile( const char *relativePath, void **buffer, ID_TIME_T *timestamp ); + virtual void FreeFile( void *buffer ); + virtual int WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath = "fs_savepath" ); + virtual void RemoveFile( const char *relativePath ); + virtual idFile * OpenFileReadFlags( const char *relativePath, int searchFlags, pack_t **foundInPak = NULL, bool allowCopyFiles = true, const char* gamedir = NULL ); + virtual idFile * OpenFileRead( const char *relativePath, bool allowCopyFiles = true, const char* gamedir = NULL ); + virtual idFile * OpenFileWrite( const char *relativePath, const char *basePath = "fs_savepath" ); + virtual idFile * OpenFileAppend( const char *relativePath, bool sync = false, const char *basePath = "fs_basepath" ); + virtual idFile * OpenFileByMode( const char *relativePath, fsMode_t mode ); + virtual idFile * OpenExplicitFileRead( const char *OSPath ); + virtual idFile * OpenExplicitFileWrite( const char *OSPath ); + virtual void CloseFile( idFile *f ); + virtual void BackgroundDownload( backgroundDownload_t *bgl ); + virtual void ResetReadCount( void ) { readCount = 0; } + virtual void AddToReadCount( int c ) { readCount += c; } + virtual int GetReadCount( void ) { return readCount; } + virtual void FindDLL( const char *basename, char dllPath[ MAX_OSPATH ], bool updateChecksum ); + virtual void ClearDirCache( void ); + virtual bool HasD3XP( void ); + virtual bool RunningD3XP( void ); + virtual void CopyFile( const char *fromOSPath, const char *toOSPath ); + virtual int ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isBinary ); + virtual idFile * MakeTemporaryFile( void ); + virtual int AddZipFile( const char *path ); + virtual findFile_t FindFile( const char *path, bool scheduleAddons ); + virtual int GetNumMaps(); + virtual const idDict * GetMapDecl( int i ); + virtual void FindMapScreenshot( const char *path, char *buf, int len ); + virtual bool FilenameCompare( const char *s1, const char *s2 ) const; + + static void Dir_f( const idCmdArgs &args ); + static void DirTree_f( const idCmdArgs &args ); + static void Path_f( const idCmdArgs &args ); + static void TouchFile_f( const idCmdArgs &args ); + static void TouchFileList_f( const idCmdArgs &args ); + +private: + friend dword BackgroundDownloadThread( void *parms ); + + searchpath_t * searchPaths; + int readCount; // total bytes read + int loadCount; // total files read + int loadStack; // total files in memory + idStr gameFolder; // this will be a single name without separators + + searchpath_t *addonPaks; // not loaded up, but we saw them + + idDict mapDict; // for GetMapDecl + + static idCVar fs_debug; + static idCVar fs_restrict; + static idCVar fs_copyfiles; + static idCVar fs_basepath; + static idCVar fs_savepath; + static idCVar fs_cdpath; + static idCVar fs_devpath; + static idCVar fs_game; + static idCVar fs_game_base; + static idCVar fs_caseSensitiveOS; + static idCVar fs_searchAddons; + + backgroundDownload_t * backgroundDownloads; + backgroundDownload_t defaultBackgroundDownload; + xthreadInfo backgroundThread; + + idList serverPaks; + bool loadedFileFromDir; // set to true once a file was loaded from a directory - can't switch to pure anymore + idList restartChecksums; // used during a restart to set things in right order + idList addonChecksums; // list of checksums that should go to the search list directly ( for restarts ) + int restartGamePakChecksum; + int gameDLLChecksum; // the checksum of the last loaded game DLL + int gamePakChecksum; // the checksum of the pak holding the loaded game DLL + + int gamePakForOS[ MAX_GAME_OS ]; + + idDEntry dir_cache[ MAX_CACHED_DIRS ]; // fifo + int dir_cache_index; + int dir_cache_count; + + int d3xp; // 0: didn't check, -1: not installed, 1: installed + +private: + void ReplaceSeparators( idStr &path, char sep = PATHSEPERATOR_CHAR ); + long HashFileName( const char *fname ) const; + int ListOSFiles( const char *directory, const char *extension, idStrList &list ); + FILE * OpenOSFile( const char *name, const char *mode, idStr *caseSensitiveName = NULL ); + FILE * OpenOSFileCorrectName( idStr &path, const char *mode ); + int DirectFileLength( FILE *o ); + void CopyFile( idFile *src, const char *toOSPath ); + int AddUnique( const char *name, idStrList &list, idHashIndex &hashIndex ) const; + void GetExtensionList( const char *extension, idStrList &extensionList ) const; + int GetFileList( const char *relativePath, const idStrList &extensions, idStrList &list, idHashIndex &hashIndex, bool fullRelativePath, const char* gamedir = NULL ); + + int GetFileListTree( const char *relativePath, const idStrList &extensions, idStrList &list, idHashIndex &hashIndex, const char* gamedir = NULL ); + pack_t * LoadZipFile( const char *zipfile ); + void AddGameDirectory( const char *path, const char *dir ); + void SetupGameDirectories( const char *gameName ); + void Startup( void ); + void SetRestrictions( void ); + // some files can be obtained from directories without compromising si_pure + bool FileAllowedFromDir( const char *path ); + // searches all the paks, no pure check + pack_t * GetPackForChecksum( int checksum, bool searchAddons = false ); + // searches all the paks, no pure check + pack_t * FindPakForFileChecksum( const char *relativePath, int fileChecksum, bool bReference ); + idFile_InZip * ReadFileFromZip( pack_t *pak, fileInPack_t *pakFile, const char *relativePath ); + int GetFileChecksum( idFile *file ); + pureStatus_t GetPackStatus( pack_t *pak ); + addonInfo_t * ParseAddonDef( const char *buf, const int len ); + void FollowAddonDependencies( pack_t *pak ); + + static size_t CurlWriteFunction( void *ptr, size_t size, size_t nmemb, void *stream ); + // curl_progress_callback in curl.h + static int CurlProgressFunction( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow ); +}; + +idCVar idFileSystemLocal::fs_restrict( "fs_restrict", "", CVAR_SYSTEM | CVAR_INIT | CVAR_BOOL, "" ); +idCVar idFileSystemLocal::fs_debug( "fs_debug", "0", CVAR_SYSTEM | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar idFileSystemLocal::fs_copyfiles( "fs_copyfiles", "0", CVAR_SYSTEM | CVAR_INIT | CVAR_INTEGER, "", 0, 4, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar idFileSystemLocal::fs_basepath( "fs_basepath", "", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar idFileSystemLocal::fs_savepath( "fs_savepath", "", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar idFileSystemLocal::fs_cdpath( "fs_cdpath", "", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar idFileSystemLocal::fs_devpath( "fs_devpath", "", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar idFileSystemLocal::fs_game( "fs_game", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "mod path" ); +idCVar idFileSystemLocal::fs_game_base( "fs_game_base", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "alternate mod path, searched after the main fs_game path, before the basedir" ); +#ifdef WIN32 +idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +#else +idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "1", CVAR_SYSTEM | CVAR_BOOL, "" ); +#endif +idCVar idFileSystemLocal::fs_searchAddons( "fs_searchAddons", "0", CVAR_SYSTEM | CVAR_BOOL, "search all addon pk4s ( disables addon functionality )" ); + +idFileSystemLocal fileSystemLocal; +idFileSystem * fileSystem = &fileSystemLocal; + +/* +================ +idFileSystemLocal::idFileSystemLocal +================ +*/ +idFileSystemLocal::idFileSystemLocal( void ) { + searchPaths = NULL; + readCount = 0; + loadCount = 0; + loadStack = 0; + dir_cache_index = 0; + dir_cache_count = 0; + d3xp = 0; + loadedFileFromDir = false; + restartGamePakChecksum = 0; + memset( &backgroundThread, 0, sizeof( backgroundThread ) ); + addonPaks = NULL; +} + +/* +================ +idFileSystemLocal::HashFileName + +return a hash value for the filename +================ +*/ +long idFileSystemLocal::HashFileName( const char *fname ) const { + int i; + long hash; + char letter; + + hash = 0; + i = 0; + while( fname[i] != '\0' ) { + letter = idStr::ToLower( fname[i] ); + if ( letter == '.' ) { + break; // don't include extension + } + if ( letter == '\\' ) { + letter = '/'; // damn path names + } + hash += (long)(letter) * (i+119); + i++; + } + hash &= (FILE_HASH_SIZE-1); + return hash; +} + +/* +=========== +idFileSystemLocal::FilenameCompare + +Ignore case and separator char distinctions +=========== +*/ +bool idFileSystemLocal::FilenameCompare( const char *s1, const char *s2 ) const { + int c1, c2; + + do { + c1 = *s1++; + c2 = *s2++; + + if ( c1 >= 'a' && c1 <= 'z' ) { + c1 -= ('a' - 'A'); + } + if ( c2 >= 'a' && c2 <= 'z' ) { + c2 -= ('a' - 'A'); + } + + if ( c1 == '\\' || c1 == ':' ) { + c1 = '/'; + } + if ( c2 == '\\' || c2 == ':' ) { + c2 = '/'; + } + + if ( c1 != c2 ) { + return true; // strings not equal + } + } while( c1 ); + + return false; // strings are equal +} + +/* +================ +idFileSystemLocal::OpenOSFile +optional caseSensitiveName is set to case sensitive file name as found on disc (fs_caseSensitiveOS only) +================ +*/ +FILE *idFileSystemLocal::OpenOSFile( const char *fileName, const char *mode, idStr *caseSensitiveName ) { + int i; + FILE *fp; + idStr fpath, entry; + idStrList list; + +#ifndef __MWERKS__ +#ifndef WIN32 + // some systems will let you fopen a directory + struct stat buf; + if ( stat( fileName, &buf ) != -1 && !S_ISREG(buf.st_mode) ) { + return NULL; + } +#endif +#endif + fp = fopen( fileName, mode ); + if ( !fp && fs_caseSensitiveOS.GetBool() ) { + fpath = fileName; + fpath.StripFilename(); + fpath.StripTrailing( PATHSEPERATOR_CHAR ); + if ( ListOSFiles( fpath, NULL, list ) == -1 ) { + return NULL; + } + + for ( i = 0; i < list.Num(); i++ ) { + entry = fpath + PATHSEPERATOR_CHAR + list[i]; + if ( !entry.Icmp( fileName ) ) { + fp = fopen( entry, mode ); + if ( fp ) { + if ( caseSensitiveName ) { + *caseSensitiveName = entry; + caseSensitiveName->StripPath(); + } + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystemLocal::OpenFileRead: changed %s to %s\n", fileName, entry.c_str() ); + } + break; + } else { + // not supposed to happen if ListOSFiles is doing it's job correctly + common->Warning( "idFileSystemLocal::OpenFileRead: fs_caseSensitiveOS 1 could not open %s", entry.c_str() ); + } + } + } + } else if ( caseSensitiveName ) { + *caseSensitiveName = fileName; + caseSensitiveName->StripPath(); + } + return fp; +} + +/* +================ +idFileSystemLocal::OpenOSFileCorrectName +================ +*/ +FILE *idFileSystemLocal::OpenOSFileCorrectName( idStr &path, const char *mode ) { + idStr caseName; + FILE *f = OpenOSFile( path.c_str(), mode, &caseName ); + if ( f ) { + path.StripFilename(); + path += PATHSEPERATOR_STR; + path += caseName; + } + return f; +} + +/* +================ +idFileSystemLocal::DirectFileLength +================ +*/ +int idFileSystemLocal::DirectFileLength( FILE *o ) { + int pos; + int end; + + pos = ftell( o ); + fseek( o, 0, SEEK_END ); + end = ftell( o ); + fseek( o, pos, SEEK_SET ); + return end; +} + +/* +============ +idFileSystemLocal::CreateOSPath + +Creates any directories needed to store the given filename +============ +*/ +void idFileSystemLocal::CreateOSPath( const char *OSPath ) { + char *ofs; + + // make absolutely sure that it can't back up the path + // FIXME: what about c: ? + if ( strstr( OSPath, ".." ) || strstr( OSPath, "::" ) ) { +#ifdef _DEBUG + common->DPrintf( "refusing to create relative path \"%s\"\n", OSPath ); +#endif + return; + } + + idStr path( OSPath ); + for( ofs = &path[ 1 ]; *ofs ; ofs++ ) { + if ( *ofs == PATHSEPERATOR_CHAR ) { + // create the directory + *ofs = 0; + Sys_Mkdir( path ); + *ofs = PATHSEPERATOR_CHAR; + } + } +} + +/* +================= +idFileSystemLocal::CopyFile + +Copy a fully specified file from one place to another +================= +*/ +void idFileSystemLocal::CopyFile( const char *fromOSPath, const char *toOSPath ) { + FILE *f; + int len; + byte *buf; + + common->Printf( "copy %s to %s\n", fromOSPath, toOSPath ); + f = OpenOSFile( fromOSPath, "rb" ); + if ( !f ) { + return; + } + fseek( f, 0, SEEK_END ); + len = ftell( f ); + fseek( f, 0, SEEK_SET ); + + buf = (byte *)Mem_Alloc( len ); + if ( fread( buf, 1, len, f ) != (unsigned int)len ) { + common->FatalError( "short read in idFileSystemLocal::CopyFile()\n" ); + } + fclose( f ); + + CreateOSPath( toOSPath ); + f = OpenOSFile( toOSPath, "wb" ); + if ( !f ) { + common->Printf( "could not create destination file\n" ); + Mem_Free( buf ); + return; + } + if ( fwrite( buf, 1, len, f ) != (unsigned int)len ) { + common->FatalError( "short write in idFileSystemLocal::CopyFile()\n" ); + } + fclose( f ); + Mem_Free( buf ); +} + +/* +================= +idFileSystemLocal::CopyFile +================= +*/ +void idFileSystemLocal::CopyFile( idFile *src, const char *toOSPath ) { + FILE *f; + int len; + byte *buf; + + common->Printf( "copy %s to %s\n", src->GetName(), toOSPath ); + src->Seek( 0, FS_SEEK_END ); + len = src->Tell(); + src->Seek( 0, FS_SEEK_SET ); + + buf = (byte *)Mem_Alloc( len ); + if ( src->Read( buf, len ) != len ) { + common->FatalError( "Short read in idFileSystemLocal::CopyFile()\n" ); + } + + CreateOSPath( toOSPath ); + f = OpenOSFile( toOSPath, "wb" ); + if ( !f ) { + common->Printf( "could not create destination file\n" ); + Mem_Free( buf ); + return; + } + if ( fwrite( buf, 1, len, f ) != (unsigned int)len ) { + common->FatalError( "Short write in idFileSystemLocal::CopyFile()\n" ); + } + fclose( f ); + Mem_Free( buf ); +} + +/* +==================== +idFileSystemLocal::ReplaceSeparators + +Fix things up differently for win/unix/mac +==================== +*/ +void idFileSystemLocal::ReplaceSeparators( idStr &path, char sep ) { + char *s; + + for( s = &path[ 0 ]; *s ; s++ ) { + if ( *s == '/' || *s == '\\' ) { + *s = sep; + } + } +} + +/* +=================== +idFileSystemLocal::BuildOSPath +=================== +*/ +const char *idFileSystemLocal::BuildOSPath( const char *base, const char *game, const char *relativePath ) { + static char OSPath[MAX_STRING_CHARS]; + idStr newPath; + + if ( fs_caseSensitiveOS.GetBool() || com_developer.GetBool() ) { + // extract the path, make sure it's all lowercase + idStr testPath, fileName; + + sprintf( testPath, "%s/%s", game , relativePath ); + testPath.StripFilename(); + + if ( testPath.HasUpper() ) { + + common->Warning( "Non-portable: path contains uppercase characters: %s", testPath.c_str() ); + + // attempt a fixup on the fly + if ( fs_caseSensitiveOS.GetBool() ) { + testPath.ToLower(); + fileName = relativePath; + fileName.StripPath(); + sprintf( newPath, "%s/%s/%s", base, testPath.c_str(), fileName.c_str() ); + ReplaceSeparators( newPath ); + common->DPrintf( "Fixed up to %s\n", newPath.c_str() ); + idStr::Copynz( OSPath, newPath, sizeof( OSPath ) ); + return OSPath; + } + } + } + + idStr strBase = base; + strBase.StripTrailing( '/' ); + strBase.StripTrailing( '\\' ); + sprintf( newPath, "%s/%s/%s", strBase.c_str(), game, relativePath ); + ReplaceSeparators( newPath ); + idStr::Copynz( OSPath, newPath, sizeof( OSPath ) ); + return OSPath; +} + +/* +================ +idFileSystemLocal::OSPathToRelativePath + +takes a full OS path, as might be found in data from a media creation +program, and converts it to a relativePath by stripping off directories + +Returns false if the osPath tree doesn't match any of the existing +search paths. + +================ +*/ +const char *idFileSystemLocal::OSPathToRelativePath( const char *OSPath ) { + static char relativePath[MAX_STRING_CHARS]; + char *s, *base; + + // skip a drive letter? + + // search for anything with "base" in it + // Ase files from max may have the form of: + // "//Purgatory/purgatory/doom/base/models/mapobjects/bitch/hologirl.tga" + // which won't match any of our drive letter based search paths + bool ignoreWarning = false; +#ifdef ID_DEMO_BUILD + base = strstr( OSPath, BASE_GAMEDIR ); + idStr tempStr = OSPath; + tempStr.ToLower(); + if ( ( strstr( tempStr, "//" ) || strstr( tempStr, "w:" ) ) && strstr( tempStr, "/doom/base/") ) { + // will cause a warning but will load the file. ase models have + // hard coded doom/base/ in the material names + base = strstr( OSPath, "base" ); + ignoreWarning = true; + } +#else + // look for the first complete directory name + base = (char *)strstr( OSPath, BASE_GAMEDIR ); + while ( base ) { + char c1 = '\0', c2; + if ( base > OSPath ) { + c1 = *(base - 1); + } + c2 = *( base + strlen( BASE_GAMEDIR ) ); + if ( ( c1 == '/' || c1 == '\\' ) && ( c2 == '/' || c2 == '\\' ) ) { + break; + } + base = strstr( base + 1, BASE_GAMEDIR ); + } +#endif + // fs_game and fs_game_base support - look for first complete name with a mod path + // ( fs_game searched before fs_game_base ) + const char *fsgame = NULL; + int igame = 0; + for ( igame = 0; igame < 2; igame++ ) { + if ( igame == 0 ) { + fsgame = fs_game.GetString(); + } else if ( igame == 1 ) { + fsgame = fs_game_base.GetString(); + } + if ( base == NULL && fsgame && strlen( fsgame ) ) { + base = (char *)strstr( OSPath, fsgame ); + while ( base ) { + char c1 = '\0', c2; + if ( base > OSPath ) { + c1 = *(base - 1); + } + c2 = *( base + strlen( fsgame ) ); + if ( ( c1 == '/' || c1 == '\\' ) && ( c2 == '/' || c2 == '\\' ) ) { + break; + } + base = strstr( base + 1, fsgame ); + } + } + } + + if ( base ) { + s = strstr( base, "/" ); + if ( !s ) { + s = strstr( base, "\\" ); + } + if ( s ) { + strcpy( relativePath, s + 1 ); + if ( fs_debug.GetInteger() > 1 ) { + common->Printf( "idFileSystem::OSPathToRelativePath: %s becomes %s\n", OSPath, relativePath ); + } + return relativePath; + } + } + + if ( !ignoreWarning ) { + common->Warning( "idFileSystem::OSPathToRelativePath failed on %s", OSPath ); + } + strcpy( relativePath, "" ); + return relativePath; +} + +/* +===================== +idFileSystemLocal::RelativePathToOSPath + +Returns a fully qualified path that can be used with stdio libraries +===================== +*/ +const char *idFileSystemLocal::RelativePathToOSPath( const char *relativePath, const char *basePath ) { + const char *path = cvarSystem->GetCVarString( basePath ); + if ( !path[0] ) { + path = fs_savepath.GetString(); + } + return BuildOSPath( path, gameFolder, relativePath ); +} + +/* +================= +idFileSystemLocal::RemoveFile +================= +*/ +void idFileSystemLocal::RemoveFile( const char *relativePath ) { + idStr OSPath; + + if ( fs_devpath.GetString()[0] ) { + OSPath = BuildOSPath( fs_devpath.GetString(), gameFolder, relativePath ); + remove( OSPath ); + } + + OSPath = BuildOSPath( fs_savepath.GetString(), gameFolder, relativePath ); + remove( OSPath ); + + ClearDirCache(); +} + +/* +================ +idFileSystemLocal::FileIsInPAK +================ +*/ +bool idFileSystemLocal::FileIsInPAK( const char *relativePath ) { + searchpath_t *search; + pack_t *pak; + fileInPack_t *pakFile; + long hash; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( !relativePath ) { + common->FatalError( "idFileSystemLocal::FileIsInPAK: NULL 'relativePath' parameter passed\n" ); + } + + // qpaths are not supposed to have a leading slash + if ( relativePath[0] == '/' || relativePath[0] == '\\' ) { + relativePath++; + } + + // make absolutely sure that it can't back up the path. + // The searchpaths do guarantee that something will always + // be prepended, so we don't need to worry about "c:" or "//limbo" + if ( strstr( relativePath, ".." ) || strstr( relativePath, "::" ) ) { + return false; + } + + // + // search through the path, one element at a time + // + + hash = HashFileName( relativePath ); + + for ( search = searchPaths; search; search = search->next ) { + // is the element a pak file? + if ( search->pack && search->pack->hashTable[hash] ) { + + // disregard if it doesn't match one of the allowed pure pak files - or is a localization file + if ( serverPaks.Num() ) { + GetPackStatus( search->pack ); + if ( search->pack->pureStatus != PURE_NEVER && !serverPaks.Find( search->pack ) ) { + continue; // not on the pure server pak list + } + } + + // look through all the pak file elements + pak = search->pack; + pakFile = pak->hashTable[hash]; + do { + // case and separator insensitive comparisons + if ( !FilenameCompare( pakFile->name, relativePath ) ) { + return true; + } + pakFile = pakFile->next; + } while( pakFile != NULL ); + } + } + return false; +} + +/* +============ +idFileSystemLocal::ReadFile + +Filename are relative to the search path +a null buffer will just return the file length and time without loading +timestamp can be NULL if not required +============ +*/ +int idFileSystemLocal::ReadFile( const char *relativePath, void **buffer, ID_TIME_T *timestamp ) { + idFile * f; + byte * buf; + int len; + bool isConfig; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( !relativePath || !relativePath[0] ) { + common->FatalError( "idFileSystemLocal::ReadFile with empty name\n" ); + } + + if ( timestamp ) { + *timestamp = FILE_NOT_FOUND_TIMESTAMP; + } + + if ( buffer ) { + *buffer = NULL; + } + + buf = NULL; // quiet compiler warning + + // if this is a .cfg file and we are playing back a journal, read + // it from the journal file + if ( strstr( relativePath, ".cfg" ) == relativePath + strlen( relativePath ) - 4 ) { + isConfig = true; + if ( eventLoop && eventLoop->JournalLevel() == 2 ) { + int r; + + loadCount++; + loadStack++; + + common->DPrintf( "Loading %s from journal file.\n", relativePath ); + len = 0; + r = eventLoop->com_journalDataFile->Read( &len, sizeof( len ) ); + if ( r != sizeof( len ) ) { + *buffer = NULL; + return -1; + } + buf = (byte *)Mem_ClearedAlloc(len+1); + *buffer = buf; + r = eventLoop->com_journalDataFile->Read( buf, len ); + if ( r != len ) { + common->FatalError( "Read from journalDataFile failed" ); + } + + // guarantee that it will have a trailing 0 for string operations + buf[len] = 0; + + return len; + } + } else { + isConfig = false; + } + + // look for it in the filesystem or pack files + f = OpenFileRead( relativePath, ( buffer != NULL ) ); + if ( f == NULL ) { + if ( buffer ) { + *buffer = NULL; + } + return -1; + } + len = f->Length(); + + if ( timestamp ) { + *timestamp = f->Timestamp(); + } + + if ( !buffer ) { + CloseFile( f ); + return len; + } + + loadCount++; + loadStack++; + + buf = (byte *)Mem_ClearedAlloc(len+1); + *buffer = buf; + + f->Read( buf, len ); + + // guarantee that it will have a trailing 0 for string operations + buf[len] = 0; + CloseFile( f ); + + // if we are journalling and it is a config file, write it to the journal file + if ( isConfig && eventLoop && eventLoop->JournalLevel() == 1 ) { + common->DPrintf( "Writing %s to journal file.\n", relativePath ); + eventLoop->com_journalDataFile->Write( &len, sizeof( len ) ); + eventLoop->com_journalDataFile->Write( buf, len ); + eventLoop->com_journalDataFile->Flush(); + } + + return len; +} + +/* +============= +idFileSystemLocal::FreeFile +============= +*/ +void idFileSystemLocal::FreeFile( void *buffer ) { + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + if ( !buffer ) { + common->FatalError( "idFileSystemLocal::FreeFile( NULL )" ); + } + loadStack--; + + Mem_Free( buffer ); +} + +/* +============ +idFileSystemLocal::WriteFile + +Filenames are relative to the search path +============ +*/ +int idFileSystemLocal::WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath ) { + idFile *f; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( !relativePath || !buffer ) { + common->FatalError( "idFileSystemLocal::WriteFile: NULL parameter" ); + } + + f = idFileSystemLocal::OpenFileWrite( relativePath, basePath ); + if ( !f ) { + common->Printf( "Failed to open %s\n", relativePath ); + return -1; + } + + size = f->Write( buffer, size ); + + CloseFile( f ); + + return size; +} + +/* +================= +idFileSystemLocal::ParseAddonDef +================= +*/ +addonInfo_t *idFileSystemLocal::ParseAddonDef( const char *buf, const int len ) { + idLexer src; + idToken token, token2; + addonInfo_t *info; + + src.LoadMemory( buf, len, "" ); + src.SetFlags( DECL_LEXER_FLAGS ); + if ( !src.SkipUntilString( "addonDef" ) ) { + src.Warning( "ParseAddonDef: no addonDef" ); + return NULL; + } + if ( !src.ReadToken( &token ) ) { + src.Warning( "Expected {" ); + return NULL; + } + info = new addonInfo_t; + // read addonDef + while ( 1 ) { + if ( !src.ReadToken( &token ) ) { + delete info; + return NULL; + } + if ( !token.Icmp( "}" ) ) { + break; + } + if ( token.type != TT_STRING ) { + src.Warning( "Expected quoted string, but found '%s'", token.c_str() ); + delete info; + return NULL; + } + int checksum; + if ( sscanf( token.c_str(), "0x%x", &checksum ) != 1 && sscanf( token.c_str(), "%x", &checksum ) != 1 ) { + src.Warning( "Could not parse checksum '%s'", token.c_str() ); + delete info; + return NULL; + } + info->depends.Append( checksum ); + } + // read any number of mapDef entries + while ( 1 ) { + if ( !src.SkipUntilString( "mapDef" ) ) { + return info; + } + if ( !src.ReadToken( &token ) ) { + src.Warning( "Expected map path" ); + info->mapDecls.DeleteContents( true ); + delete info; + return NULL; + } + idDict *dict = new idDict; + dict->Set( "path", token.c_str() ); + if ( !src.ReadToken( &token ) ) { + src.Warning( "Expected {" ); + info->mapDecls.DeleteContents( true ); + delete dict; + delete info; + return NULL; + } + while ( 1 ) { + if ( !src.ReadToken( &token ) ) { + break; + } + if ( !token.Icmp( "}" ) ) { + break; + } + if ( token.type != TT_STRING ) { + src.Warning( "Expected quoted string, but found '%s'", token.c_str() ); + info->mapDecls.DeleteContents( true ); + delete dict; + delete info; + return NULL; + } + + if ( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + info->mapDecls.DeleteContents( true ); + delete dict; + delete info; + return NULL; + } + + if ( dict->FindKey( token ) ) { + src.Warning( "'%s' already defined", token.c_str() ); + } + dict->Set( token, token2 ); + } + info->mapDecls.Append( dict ); + } + assert( false ); + return NULL; +} + +/* +================= +idFileSystemLocal::LoadZipFile +================= +*/ +pack_t *idFileSystemLocal::LoadZipFile( const char *zipfile ) { + fileInPack_t * buildBuffer; + pack_t * pack; + unzFile uf; + int err; + unz_global_info gi; + char filename_inzip[MAX_ZIPPED_FILE_NAME]; + unz_file_info file_info; + int i; + long hash; + int fs_numHeaderLongs; + int * fs_headerLongs; + FILE *f; + int len; + int confHash; + fileInPack_t *pakFile; + + f = OpenOSFile( zipfile, "rb" ); + if ( !f ) { + return NULL; + } + fseek( f, 0, SEEK_END ); + len = ftell( f ); + fclose( f ); + + fs_numHeaderLongs = 0; + + uf = unzOpen( zipfile ); + err = unzGetGlobalInfo( uf, &gi ); + + if ( err != UNZ_OK ) { + return NULL; + } + + buildBuffer = new fileInPack_t[gi.number_entry]; + pack = new pack_t; + for( i = 0; i < FILE_HASH_SIZE; i++ ) { + pack->hashTable[i] = NULL; + } + + pack->pakFilename = zipfile; + pack->handle = uf; + pack->numfiles = gi.number_entry; + pack->buildBuffer = buildBuffer; + pack->referenced = false; + pack->binary = BINARY_UNKNOWN; + pack->addon = false; + pack->addon_search = false; + pack->addon_info = NULL; + pack->pureStatus = PURE_UNKNOWN; + pack->isNew = false; + + pack->length = len; + + unzGoToFirstFile(uf); + fs_headerLongs = (int *)Mem_ClearedAlloc( gi.number_entry * sizeof(int) ); + for ( i = 0; i < (int)gi.number_entry; i++ ) { + err = unzGetCurrentFileInfo( uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0 ); + if ( err != UNZ_OK ) { + break; + } + if ( file_info.uncompressed_size > 0 ) { + fs_headerLongs[fs_numHeaderLongs++] = LittleLong( file_info.crc ); + } + hash = HashFileName( filename_inzip ); + buildBuffer[i].name = filename_inzip; + buildBuffer[i].name.ToLower(); + buildBuffer[i].name.BackSlashesToSlashes(); + // store the file position in the zip + unzGetCurrentFileInfoPosition( uf, &buildBuffer[i].pos ); + // add the file to the hash + buildBuffer[i].next = pack->hashTable[hash]; + pack->hashTable[hash] = &buildBuffer[i]; + // go to the next file in the zip + unzGoToNextFile(uf); + } + + // check if this is an addon pak + pack->addon = false; + confHash = HashFileName( ADDON_CONFIG ); + for ( pakFile = pack->hashTable[confHash]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, ADDON_CONFIG ) ) { + pack->addon = true; + idFile_InZip *file = ReadFileFromZip( pack, pakFile, ADDON_CONFIG ); + // may be just an empty file if you don't bother about the mapDef + if ( file && file->Length() ) { + char *buf; + buf = new char[ file->Length() + 1 ]; + file->Read( (void *)buf, file->Length() ); + buf[ file->Length() ] = '\0'; + pack->addon_info = ParseAddonDef( buf, file->Length() ); + delete[] buf; + } + if ( file ) { + CloseFile( file ); + } + break; + } + } + + pack->checksum = MD4_BlockChecksum( fs_headerLongs, 4 * fs_numHeaderLongs ); + pack->checksum = LittleLong( pack->checksum ); + + Mem_Free( fs_headerLongs ); + + return pack; +} + +/* +=============== +idFileSystemLocal::AddZipFile +adds a downloaded pak file to the list so we can work out what we have and what we still need +the isNew flag is set to true, indicating that we cannot add this pak to the search lists without a restart +=============== +*/ +int idFileSystemLocal::AddZipFile( const char *path ) { + idStr fullpath = fs_savepath.GetString(); + pack_t *pak; + searchpath_t *search, *last; + + fullpath.AppendPath( path ); + pak = LoadZipFile( fullpath ); + if ( !pak ) { + common->Warning( "AddZipFile %s failed\n", path ); + return 0; + } + // insert the pak at the end of the search list - temporary until we restart + pak->isNew = true; + search = new searchpath_t; + search->dir = NULL; + search->pack = pak; + search->next = NULL; + last = searchPaths; + while ( last->next ) { + last = last->next; + } + last->next = search; + common->Printf( "Appended pk4 %s with checksum 0x%x\n", pak->pakFilename.c_str(), pak->checksum ); + return pak->checksum; +} + +/* +=============== +idFileSystemLocal::AddUnique +=============== +*/ +int idFileSystemLocal::AddUnique( const char *name, idStrList &list, idHashIndex &hashIndex ) const { + int i, hashKey; + + hashKey = hashIndex.GenerateKey( name ); + for ( i = hashIndex.First( hashKey ); i >= 0; i = hashIndex.Next( i ) ) { + if ( list[i].Icmp( name ) == 0 ) { + return i; + } + } + i = list.Append( name ); + hashIndex.Add( hashKey, i ); + return i; +} + +/* +=============== +idFileSystemLocal::GetExtensionList +=============== +*/ +void idFileSystemLocal::GetExtensionList( const char *extension, idStrList &extensionList ) const { + int s, e, l; + + l = idStr::Length( extension ); + s = 0; + while( 1 ) { + e = idStr::FindChar( extension, '|', s, l ); + if ( e != -1 ) { + extensionList.Append( idStr( extension, s, e ) ); + s = e + 1; + } else { + extensionList.Append( idStr( extension, s, l ) ); + break; + } + } +} + +/* +=============== +idFileSystemLocal::GetFileList + +Does not clear the list first so this can be used to progressively build a file list. +When 'sort' is true only the new files added to the list are sorted. +=============== +*/ +int idFileSystemLocal::GetFileList( const char *relativePath, const idStrList &extensions, idStrList &list, idHashIndex &hashIndex, bool fullRelativePath, const char* gamedir ) { + searchpath_t * search; + fileInPack_t * buildBuffer; + int i, j; + int pathLength; + int length; + const char * name; + pack_t * pak; + idStr work; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( !extensions.Num() ) { + return 0; + } + + if ( !relativePath ) { + return 0; + } + pathLength = strlen( relativePath ); + if ( pathLength ) { + pathLength++; // for the trailing '/' + } + + // search through the path, one element at a time, adding to list + for( search = searchPaths; search != NULL; search = search->next ) { + if ( search->dir ) { + if(gamedir && strlen(gamedir)) { + if(search->dir->gamedir != gamedir) { + continue; + } + } + + idStrList sysFiles; + idStr netpath; + + netpath = BuildOSPath( search->dir->path, search->dir->gamedir, relativePath ); + + for ( i = 0; i < extensions.Num(); i++ ) { + + // scan for files in the filesystem + ListOSFiles( netpath, extensions[i], sysFiles ); + + // if we are searching for directories, remove . and .. + if ( extensions[i][0] == '/' && extensions[i][1] == 0 ) { + sysFiles.Remove( "." ); + sysFiles.Remove( ".." ); + } + + for( j = 0; j < sysFiles.Num(); j++ ) { + // unique the match + if ( fullRelativePath ) { + work = relativePath; + work += "/"; + work += sysFiles[j]; + AddUnique( work, list, hashIndex ); + } + else { + AddUnique( sysFiles[j], list, hashIndex ); + } + } + } + } else if ( search->pack ) { + // look through all the pak file elements + + // exclude any extra packs if we have server paks to search + if ( serverPaks.Num() ) { + GetPackStatus( search->pack ); + if ( search->pack->pureStatus != PURE_NEVER && !serverPaks.Find( search->pack ) ) { + continue; // not on the pure server pak list + } + } + + pak = search->pack; + buildBuffer = pak->buildBuffer; + for( i = 0; i < pak->numfiles; i++ ) { + + length = buildBuffer[i].name.Length(); + + // if the name is not long anough to at least contain the path + if ( length <= pathLength ) { + continue; + } + + name = buildBuffer[i].name; + + + // check for a path match without the trailing '/' + if ( pathLength && idStr::Icmpn( name, relativePath, pathLength - 1 ) != 0 ) { + continue; + } + + // ensure we have a path, and not just a filename containing the path + if ( name[ pathLength ] == '\0' || name[pathLength - 1] != '/' ) { + continue; + } + + // make sure the file is not in a subdirectory + for ( j = pathLength; name[j+1] != '\0'; j++ ) { + if ( name[j] == '/' ) { + break; + } + } + if ( name[j+1] ) { + continue; + } + + // check for extension match + for ( j = 0; j < extensions.Num(); j++ ) { + if ( length >= extensions[j].Length() && extensions[j].Icmp( name + length - extensions[j].Length() ) == 0 ) { + break; + } + } + if ( j >= extensions.Num() ) { + continue; + } + + // unique the match + if ( fullRelativePath ) { + work = relativePath; + work += "/"; + work += name + pathLength; + work.StripTrailing( '/' ); + AddUnique( work, list, hashIndex ); + } else { + work = name + pathLength; + work.StripTrailing( '/' ); + AddUnique( work, list, hashIndex ); + } + } + } + } + + return list.Num(); +} + +/* +=============== +idFileSystemLocal::ListFiles +=============== +*/ +idFileList *idFileSystemLocal::ListFiles( const char *relativePath, const char *extension, bool sort, bool fullRelativePath, const char* gamedir ) { + idHashIndex hashIndex( 4096, 4096 ); + idStrList extensionList; + + idFileList *fileList = new idFileList; + fileList->basePath = relativePath; + + GetExtensionList( extension, extensionList ); + + GetFileList( relativePath, extensionList, fileList->list, hashIndex, fullRelativePath, gamedir ); + + if ( sort ) { + idStrListSortPaths( fileList->list ); + } + + return fileList; +} + +/* +=============== +idFileSystemLocal::GetFileListTree +=============== +*/ +int idFileSystemLocal::GetFileListTree( const char *relativePath, const idStrList &extensions, idStrList &list, idHashIndex &hashIndex, const char* gamedir ) { + int i; + idStrList slash, folders( 128 ); + idHashIndex folderHashIndex( 1024, 128 ); + + // recurse through the subdirectories + slash.Append( "/" ); + GetFileList( relativePath, slash, folders, folderHashIndex, true, gamedir ); + for ( i = 0; i < folders.Num(); i++ ) { + if ( folders[i][0] == '.' ) { + continue; + } + if ( folders[i].Icmp( relativePath ) == 0 ){ + continue; + } + GetFileListTree( folders[i], extensions, list, hashIndex, gamedir ); + } + + // list files in the current directory + GetFileList( relativePath, extensions, list, hashIndex, true, gamedir ); + + return list.Num(); +} + +/* +=============== +idFileSystemLocal::ListFilesTree +=============== +*/ +idFileList *idFileSystemLocal::ListFilesTree( const char *relativePath, const char *extension, bool sort, const char* gamedir ) { + idHashIndex hashIndex( 4096, 4096 ); + idStrList extensionList; + + idFileList *fileList = new idFileList(); + fileList->basePath = relativePath; + fileList->list.SetGranularity( 4096 ); + + GetExtensionList( extension, extensionList ); + + GetFileListTree( relativePath, extensionList, fileList->list, hashIndex, gamedir ); + + if ( sort ) { + idStrListSortPaths( fileList->list ); + } + + return fileList; +} + +/* +=============== +idFileSystemLocal::FreeFileList +=============== +*/ +void idFileSystemLocal::FreeFileList( idFileList *fileList ) { + delete fileList; +} + +/* +=============== +idFileSystemLocal::ListMods +=============== +*/ +idModList *idFileSystemLocal::ListMods( void ) { + int i; + const int MAX_DESCRIPTION = 256; + char desc[ MAX_DESCRIPTION ]; + + idStrList dirs; + idStrList pk4s; + + idModList *list = new idModList; + + const char *search[ 4 ]; + int isearch; + + search[0] = fs_savepath.GetString(); + search[1] = fs_devpath.GetString(); + search[2] = fs_basepath.GetString(); + search[3] = fs_cdpath.GetString(); + + for ( isearch = 0; isearch < 4; isearch++ ) { + + dirs.Clear(); + pk4s.Clear(); + + // scan for directories + ListOSFiles( search[ isearch ], "/", dirs ); + + dirs.Remove( "." ); + dirs.Remove( ".." ); + dirs.Remove( "base" ); + dirs.Remove( "pb" ); + + // see if there are any pk4 files in each directory + for( i = 0; i < dirs.Num(); i++ ) { + idStr gamepath = BuildOSPath( search[ isearch ], dirs[ i ], "" ); + ListOSFiles( gamepath, ".pk4", pk4s ); + if ( pk4s.Num() ) { + if ( !list->mods.Find( dirs[ i ] ) ) { + // D3 1.3 #31, only list d3xp if the pak is present + if ( dirs[ i ].Icmp( "d3xp" ) || HasD3XP() ) { + list->mods.Append( dirs[ i ] ); + } + } + } + } + } + + list->mods.Sort(); + + // read the descriptions for each mod - search all paths + for ( i = 0; i < list->mods.Num(); i++ ) { + + for ( isearch = 0; isearch < 4; isearch++ ) { + + idStr descfile = BuildOSPath( search[ isearch ], list->mods[ i ], "description.txt" ); + FILE *f = OpenOSFile( descfile, "r" ); + if ( f ) { + if ( fgets( desc, MAX_DESCRIPTION, f ) ) { + list->descriptions.Append( desc ); + fclose( f ); + break; + } else { + common->DWarning( "Error reading %s", descfile.c_str() ); + fclose( f ); + continue; + } + } + } + + if ( isearch == 4 ) { + list->descriptions.Append( list->mods[ i ] ); + } + } + + list->mods.Insert( "" ); + list->descriptions.Insert( "Doom 3" ); + + assert( list->mods.Num() == list->descriptions.Num() ); + + return list; +} + +/* +=============== +idFileSystemLocal::FreeModList +=============== +*/ +void idFileSystemLocal::FreeModList( idModList *modList ) { + delete modList; +} + +/* +=============== +idDEntry::Matches +=============== +*/ +bool idDEntry::Matches(const char *directory, const char *extension) const { + if ( !idDEntry::directory.Icmp( directory ) && !idDEntry::extension.Icmp( extension ) ) { + return true; + } + return false; +} + +/* +=============== +idDEntry::Init +=============== +*/ +void idDEntry::Init( const char *directory, const char *extension, const idStrList &list ) { + idDEntry::directory = directory; + idDEntry::extension = extension; + idStrList::operator=(list); +} + +/* +=============== +idDEntry::Clear +=============== +*/ +void idDEntry::Clear( void ) { + directory.Clear(); + extension.Clear(); + idStrList::Clear(); +} + +/* +=============== +idFileSystemLocal::ListOSFiles + + call to the OS for a listing of files in an OS directory + optionally, perform some caching of the entries +=============== +*/ +int idFileSystemLocal::ListOSFiles( const char *directory, const char *extension, idStrList &list ) { + int i, j, ret; + + if ( !extension ) { + extension = ""; + } + + if ( !fs_caseSensitiveOS.GetBool() ) { + return Sys_ListFiles( directory, extension, list ); + } + + // try in cache + i = dir_cache_index - 1; + while( i >= dir_cache_index - dir_cache_count ) { + j = (i+MAX_CACHED_DIRS) % MAX_CACHED_DIRS; + if ( dir_cache[j].Matches( directory, extension ) ) { + if ( fs_debug.GetInteger() ) { + //common->Printf( "idFileSystemLocal::ListOSFiles: cache hit: %s\n", directory ); + } + list = dir_cache[j]; + return list.Num(); + } + i--; + } + + if ( fs_debug.GetInteger() ) { + //common->Printf( "idFileSystemLocal::ListOSFiles: cache miss: %s\n", directory ); + } + + ret = Sys_ListFiles( directory, extension, list ); + + if ( ret == -1 ) { + return -1; + } + + // push a new entry + dir_cache[dir_cache_index].Init( directory, extension, list ); + dir_cache_index = (++dir_cache_index) % MAX_CACHED_DIRS; + if ( dir_cache_count < MAX_CACHED_DIRS ) { + dir_cache_count++; + } + + return ret; +} + +/* +================ +idFileSystemLocal::Dir_f +================ +*/ +void idFileSystemLocal::Dir_f( const idCmdArgs &args ) { + idStr relativePath; + idStr extension; + idFileList *fileList; + int i; + + if ( args.Argc() < 2 || args.Argc() > 3 ) { + common->Printf( "usage: dir [extension]\n" ); + return; + } + + if ( args.Argc() == 2 ) { + relativePath = args.Argv( 1 ); + extension = ""; + } + else { + relativePath = args.Argv( 1 ); + extension = args.Argv( 2 ); + if ( extension[0] != '.' ) { + common->Warning( "extension should have a leading dot" ); + } + } + relativePath.BackSlashesToSlashes(); + relativePath.StripTrailing( '/' ); + + common->Printf( "Listing of %s/*%s\n", relativePath.c_str(), extension.c_str() ); + common->Printf( "---------------\n" ); + + fileList = fileSystemLocal.ListFiles( relativePath, extension ); + + for ( i = 0; i < fileList->GetNumFiles(); i++ ) { + common->Printf( "%s\n", fileList->GetFile( i ) ); + } + common->Printf( "%d files\n", fileList->list.Num() ); + + fileSystemLocal.FreeFileList( fileList ); +} + +/* +================ +idFileSystemLocal::DirTree_f +================ +*/ +void idFileSystemLocal::DirTree_f( const idCmdArgs &args ) { + idStr relativePath; + idStr extension; + idFileList *fileList; + int i; + + if ( args.Argc() < 2 || args.Argc() > 3 ) { + common->Printf( "usage: dirtree [extension]\n" ); + return; + } + + if ( args.Argc() == 2 ) { + relativePath = args.Argv( 1 ); + extension = ""; + } + else { + relativePath = args.Argv( 1 ); + extension = args.Argv( 2 ); + if ( extension[0] != '.' ) { + common->Warning( "extension should have a leading dot" ); + } + } + relativePath.BackSlashesToSlashes(); + relativePath.StripTrailing( '/' ); + + common->Printf( "Listing of %s/*%s /s\n", relativePath.c_str(), extension.c_str() ); + common->Printf( "---------------\n" ); + + fileList = fileSystemLocal.ListFilesTree( relativePath, extension ); + + for ( i = 0; i < fileList->GetNumFiles(); i++ ) { + common->Printf( "%s\n", fileList->GetFile( i ) ); + } + common->Printf( "%d files\n", fileList->list.Num() ); + + fileSystemLocal.FreeFileList( fileList ); +} + +/* +============ +idFileSystemLocal::Path_f +============ +*/ +void idFileSystemLocal::Path_f( const idCmdArgs &args ) { + searchpath_t *sp; + int i; + idStr status; + + common->Printf( "Current search path:\n" ); + for ( sp = fileSystemLocal.searchPaths; sp; sp = sp->next ) { + if ( sp->pack ) { + if ( com_developer.GetBool() ) { + sprintf( status, "%s (%i files - 0x%x %s", sp->pack->pakFilename.c_str(), sp->pack->numfiles, sp->pack->checksum, sp->pack->referenced ? "referenced" : "not referenced" ); + if ( sp->pack->addon ) { + status += " - addon)\n"; + } else { + status += ")\n"; + } + common->Printf( status.c_str() ); + } else { + common->Printf( "%s (%i files)\n", sp->pack->pakFilename.c_str(), sp->pack->numfiles ); + } + if ( fileSystemLocal.serverPaks.Num() ) { + if ( fileSystemLocal.serverPaks.Find( sp->pack ) ) { + common->Printf( " on the pure list\n" ); + } else { + common->Printf( " not on the pure list\n" ); + } + } + } else { + common->Printf( "%s/%s\n", sp->dir->path.c_str(), sp->dir->gamedir.c_str() ); + } + } + common->Printf( "game DLL: 0x%x in pak: 0x%x\n", fileSystemLocal.gameDLLChecksum, fileSystemLocal.gamePakChecksum ); +#if ID_FAKE_PURE + common->Printf( "Note: ID_FAKE_PURE is enabled\n" ); +#endif + for( i = 0; i < MAX_GAME_OS; i++ ) { + if ( fileSystemLocal.gamePakForOS[ i ] ) { + common->Printf( "OS %d - pak 0x%x\n", i, fileSystemLocal.gamePakForOS[ i ] ); + } + } + // show addon packs that are *not* in the search lists + common->Printf( "Addon pk4s:\n" ); + for ( sp = fileSystemLocal.addonPaks; sp; sp = sp->next ) { + if ( com_developer.GetBool() ) { + common->Printf( "%s (%i files - 0x%x)\n", sp->pack->pakFilename.c_str(), sp->pack->numfiles, sp->pack->checksum ); + } else { + common->Printf( "%s (%i files)\n", sp->pack->pakFilename.c_str(), sp->pack->numfiles ); + } + } +} + +/* +============ +idFileSystemLocal::GetOSMask +============ +*/ +int idFileSystemLocal::GetOSMask( void ) { + int i, ret = 0; + for( i = 0; i < MAX_GAME_OS; i++ ) { + if ( fileSystemLocal.gamePakForOS[ i ] ) { + ret |= ( 1 << i ); + } + } + if ( !ret ) { + return -1; + } + return ret; +} + +/* +============ +idFileSystemLocal::TouchFile_f + +The only purpose of this function is to allow game script files to copy +arbitrary files furing an "fs_copyfiles 1" run. +============ +*/ +void idFileSystemLocal::TouchFile_f( const idCmdArgs &args ) { + idFile *f; + + if ( args.Argc() != 2 ) { + common->Printf( "Usage: touchFile \n" ); + return; + } + + f = fileSystemLocal.OpenFileRead( args.Argv( 1 ) ); + if ( f ) { + fileSystemLocal.CloseFile( f ); + } +} + +/* +============ +idFileSystemLocal::TouchFileList_f + +Takes a text file and touches every file in it, use one file per line. +============ +*/ +void idFileSystemLocal::TouchFileList_f( const idCmdArgs &args ) { + + if ( args.Argc() != 2 ) { + common->Printf( "Usage: touchFileList \n" ); + return; + } + + const char *buffer = NULL; + idParser src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + if ( fileSystem->ReadFile( args.Argv( 1 ), ( void** )&buffer, NULL ) && buffer ) { + src.LoadMemory( buffer, strlen( buffer ), args.Argv( 1 ) ); + if ( src.IsLoaded() ) { + idToken token; + while( src.ReadToken( &token ) ) { + common->Printf( "%s\n", token.c_str() ); + session->UpdateScreen(); + idFile *f = fileSystemLocal.OpenFileRead( token ); + if ( f ) { + fileSystemLocal.CloseFile( f ); + } + } + } + } + +} + + +/* +================ +idFileSystemLocal::AddGameDirectory + +Sets gameFolder, adds the directory to the head of the search paths, then loads any pk4 files. +================ +*/ +void idFileSystemLocal::AddGameDirectory( const char *path, const char *dir ) { + int i; + searchpath_t * search; + pack_t * pak; + idStr pakfile; + idStrList pakfiles; + + // check if the search path already exists + for ( search = searchPaths; search; search = search->next ) { + // if this element is a pak file + if ( !search->dir ) { + continue; + } + if ( search->dir->path.Cmp( path ) == 0 && search->dir->gamedir.Cmp( dir ) == 0 ) { + return; + } + } + + gameFolder = dir; + + // + // add the directory to the search path + // + search = new searchpath_t; + search->dir = new directory_t; + search->pack = NULL; + + search->dir->path = path; + search->dir->gamedir = dir; + search->next = searchPaths; + searchPaths = search; + + // find all pak files in this directory + pakfile = BuildOSPath( path, dir, "" ); + pakfile[ pakfile.Length() - 1 ] = 0; // strip the trailing slash + + ListOSFiles( pakfile, ".pk4", pakfiles ); + + // sort them so that later alphabetic matches override + // earlier ones. This makes pak1.pk4 override pak0.pk4 + pakfiles.Sort(); + + for ( i = 0; i < pakfiles.Num(); i++ ) { + pakfile = BuildOSPath( path, dir, pakfiles[i] ); + pak = LoadZipFile( pakfile ); + if ( !pak ) { + continue; + } + // insert the pak after the directory it comes from + search = new searchpath_t; + search->dir = NULL; + search->pack = pak; + search->next = searchPaths->next; + searchPaths->next = search; + common->Printf( "Loaded pk4 %s with checksum 0x%x\n", pakfile.c_str(), pak->checksum ); + } +} + +/* +================ +idFileSystemLocal::SetupGameDirectories + + Takes care of the correct search order. +================ +*/ +void idFileSystemLocal::SetupGameDirectories( const char *gameName ) { + // setup cdpath + if ( fs_cdpath.GetString()[0] ) { + AddGameDirectory( fs_cdpath.GetString(), gameName ); + } + + // setup basepath + if ( fs_basepath.GetString()[0] ) { + AddGameDirectory( fs_basepath.GetString(), gameName ); + } + + // setup devpath + if ( fs_devpath.GetString()[0] ) { + AddGameDirectory( fs_devpath.GetString(), gameName ); + } + + // setup savepath + if ( fs_savepath.GetString()[0] ) { + AddGameDirectory( fs_savepath.GetString(), gameName ); + } +} + +/* +=============== +idFileSystemLocal::FollowDependencies +=============== +*/ +void idFileSystemLocal::FollowAddonDependencies( pack_t *pak ) { + assert( pak ); + if ( !pak->addon_info || !pak->addon_info->depends.Num() ) { + return; + } + int i, num = pak->addon_info->depends.Num(); + for ( i = 0; i < num; i++ ) { + pack_t *deppak = GetPackForChecksum( pak->addon_info->depends[ i ], true ); + if ( deppak ) { + // make sure it hasn't been marked for search already + if ( !deppak->addon_search ) { + // must clean addonChecksums as we go + int addon_index = addonChecksums.FindIndex( deppak->checksum ); + if ( addon_index >= 0 ) { + addonChecksums.RemoveIndex( addon_index ); + } + deppak->addon_search = true; + common->Printf( "Addon pk4 %s 0x%x depends on pak %s 0x%x, will be searched\n", + pak->pakFilename.c_str(), pak->checksum, + deppak->pakFilename.c_str(), deppak->checksum ); + FollowAddonDependencies( deppak ); + } + } else { + common->Printf( "Addon pk4 %s 0x%x depends on unknown pak 0x%x\n", + pak->pakFilename.c_str(), pak->checksum, pak->addon_info->depends[ i ] ); + } + } +} + +/* +================ +idFileSystemLocal::Startup +================ +*/ +void idFileSystemLocal::Startup( void ) { + searchpath_t **search; + int i; + pack_t *pak; + int addon_index; + + common->Printf( "------ Initializing File System ------\n" ); + + if ( restartChecksums.Num() ) { + common->Printf( "restarting in pure mode with %d pak files\n", restartChecksums.Num() ); + } + if ( addonChecksums.Num() ) { + common->Printf( "restarting filesystem with %d addon pak file(s) to include\n", addonChecksums.Num() ); + } + + SetupGameDirectories( BASE_GAMEDIR ); + + // fs_game_base override + if ( fs_game_base.GetString()[0] && + idStr::Icmp( fs_game_base.GetString(), BASE_GAMEDIR ) ) { + SetupGameDirectories( fs_game_base.GetString() ); + } + + // fs_game override + if ( fs_game.GetString()[0] && + idStr::Icmp( fs_game.GetString(), BASE_GAMEDIR ) && + idStr::Icmp( fs_game.GetString(), fs_game_base.GetString() ) ) { + SetupGameDirectories( fs_game.GetString() ); + } + + // currently all addons are in the search list - deal with filtering out and dependencies now + // scan through and deal with dependencies + search = &searchPaths; + while ( *search ) { + if ( !( *search )->pack || !( *search )->pack->addon ) { + search = &( ( *search )->next ); + continue; + } + pak = ( *search )->pack; + if ( fs_searchAddons.GetBool() ) { + // when we have fs_searchAddons on we should never have addonChecksums + assert( !addonChecksums.Num() ); + pak->addon_search = true; + search = &( ( *search )->next ); + continue; + } + addon_index = addonChecksums.FindIndex( pak->checksum ); + if ( addon_index >= 0 ) { + assert( !pak->addon_search ); // any pak getting flagged as addon_search should also have been removed from addonChecksums already + pak->addon_search = true; + addonChecksums.RemoveIndex( addon_index ); + FollowAddonDependencies( pak ); + } + search = &( ( *search )->next ); + } + + // now scan to filter out addons not marked addon_search + search = &searchPaths; + while ( *search ) { + if ( !( *search )->pack || !( *search )->pack->addon ) { + search = &( ( *search )->next ); + continue; + } + assert( !( *search )->dir ); + pak = ( *search )->pack; + if ( pak->addon_search ) { + common->Printf( "Addon pk4 %s with checksum 0x%x is on the search list\n", + pak->pakFilename.c_str(), pak->checksum ); + search = &( ( *search )->next ); + } else { + // remove from search list, put in addons list + searchpath_t *paksearch = *search; + *search = ( *search )->next; + paksearch->next = addonPaks; + addonPaks = paksearch; + common->Printf( "Addon pk4 %s with checksum 0x%x is on addon list\n", + pak->pakFilename.c_str(), pak->checksum ); + } + } + + // all addon paks found and accounted for + assert( !addonChecksums.Num() ); + addonChecksums.Clear(); // just in case + + if ( restartChecksums.Num() ) { + search = &searchPaths; + while ( *search ) { + if ( !( *search )->pack ) { + search = &( ( *search )->next ); + continue; + } + if ( ( i = restartChecksums.FindIndex( ( *search )->pack->checksum ) ) != -1 ) { + if ( i == 0 ) { + // this pak is the next one in the pure search order + serverPaks.Append( ( *search )->pack ); + restartChecksums.RemoveIndex( 0 ); + if ( !restartChecksums.Num() ) { + break; // early out, we're done + } + search = &( ( *search )->next ); + continue; + } else { + // this pak will be on the pure list, but order is not right yet + searchpath_t *aux; + aux = ( *search )->next; + if ( !aux ) { + // last of the list can't be swapped back + if ( fs_debug.GetBool() ) { + common->Printf( "found pure checksum %x at index %d, but the end of search path is reached\n", ( *search )->pack->checksum, i ); + idStr checks; + checks.Clear(); + for ( i = 0; i < serverPaks.Num(); i++ ) { + checks += va( "%p ", serverPaks[ i ] ); + } + common->Printf( "%d pure paks - %s \n", serverPaks.Num(), checks.c_str() ); + checks.Clear(); + for ( i = 0; i < restartChecksums.Num(); i++ ) { + checks += va( "%x ", restartChecksums[ i ] ); + } + common->Printf( "%d paks left - %s\n", restartChecksums.Num(), checks.c_str() ); + } + common->FatalError( "Failed to restart with pure mode restrictions for server connect" ); + } + // put this search path at the end of the list + searchpath_t *search_end; + search_end = ( *search )->next; + while ( search_end->next ) { + search_end = search_end->next; + } + search_end->next = *search; + *search = ( *search )->next; + search_end->next->next = NULL; + continue; + } + } + // this pak is not on the pure list + search = &( ( *search )->next ); + } + // the list must be empty + if ( restartChecksums.Num() ) { + if ( fs_debug.GetBool() ) { + idStr checks; + checks.Clear(); + for ( i = 0; i < serverPaks.Num(); i++ ) { + checks += va( "%p ", serverPaks[ i ] ); + } + common->Printf( "%d pure paks - %s \n", serverPaks.Num(), checks.c_str() ); + checks.Clear(); + for ( i = 0; i < restartChecksums.Num(); i++ ) { + checks += va( "%x ", restartChecksums[ i ] ); + } + common->Printf( "%d paks left - %s\n", restartChecksums.Num(), checks.c_str() ); + } + common->FatalError( "Failed to restart with pure mode restrictions for server connect" ); + } + // also the game pak checksum + // we could check if the game pak is actually present, but we would not be restarting if there wasn't one @ first pure check + gamePakChecksum = restartGamePakChecksum; + } + + // add our commands + cmdSystem->AddCommand( "dir", Dir_f, CMD_FL_SYSTEM, "lists a folder", idCmdSystem::ArgCompletion_FileName ); + cmdSystem->AddCommand( "dirtree", DirTree_f, CMD_FL_SYSTEM, "lists a folder with subfolders" ); + cmdSystem->AddCommand( "path", Path_f, CMD_FL_SYSTEM, "lists search paths" ); + cmdSystem->AddCommand( "touchFile", TouchFile_f, CMD_FL_SYSTEM, "touches a file" ); + cmdSystem->AddCommand( "touchFileList", TouchFileList_f, CMD_FL_SYSTEM, "touches a list of files" ); + + // print the current search paths + Path_f( idCmdArgs() ); + + common->Printf( "file system initialized.\n" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +=================== +idFileSystemLocal::SetRestrictions + +Looks for product keys and restricts media add on ability +if the full version is not found +=================== +*/ +void idFileSystemLocal::SetRestrictions( void ) { +#ifdef ID_DEMO_BUILD + common->Printf( "\nRunning in restricted demo mode.\n\n" ); + // make sure that the pak file has the header checksum we expect + searchpath_t *search; + for ( search = searchPaths; search; search = search->next ) { + if ( search->pack ) { + // a tiny attempt to keep the checksum from being scannable from the exe + if ( ( search->pack->checksum ^ 0x84268436u ) != ( DEMO_PAK_CHECKSUM ^ 0x84268436u ) ) { + common->FatalError( "Corrupted %s: 0x%x", search->pack->pakFilename.c_str(), search->pack->checksum ); + } + } + } + cvarSystem->SetCVarBool( "fs_restrict", true ); +#endif +} + +/* +===================== +idFileSystemLocal::UpdatePureServerChecksums +===================== +*/ +void idFileSystemLocal::UpdatePureServerChecksums( void ) { + searchpath_t *search; + int i; + pureStatus_t status; + + serverPaks.Clear(); + for ( search = searchPaths; search; search = search->next ) { + // is the element a referenced pak file? + if ( !search->pack ) { + continue; + } + status = GetPackStatus( search->pack ); + if ( status == PURE_NEVER ) { + continue; + } + if ( status == PURE_NEUTRAL && !search->pack->referenced ) { + continue; + } + serverPaks.Append( search->pack ); + if ( serverPaks.Num() >= MAX_PURE_PAKS ) { + common->FatalError( "MAX_PURE_PAKS ( %d ) exceeded\n", MAX_PURE_PAKS ); + } + } + if ( fs_debug.GetBool() ) { + idStr checks; + for ( i = 0; i < serverPaks.Num(); i++ ) { + checks += va( "%x ", serverPaks[ i ]->checksum ); + } + common->Printf( "set pure list - %d paks ( %s)\n", serverPaks.Num(), checks.c_str() ); + } +} + +/* +===================== +idFileSystemLocal::UpdateGamePakChecksums +===================== +*/ +bool idFileSystemLocal::UpdateGamePakChecksums( void ) { + searchpath_t *search; + fileInPack_t *pakFile; + int confHash; + idFile *confFile; + char *buf; + idLexer *lexConf; + idToken token; + int id; + + confHash = HashFileName( BINARY_CONFIG ); + + memset( gamePakForOS, 0, sizeof( gamePakForOS ) ); + for ( search = searchPaths; search; search = search->next ) { + if ( !search->pack ) { + continue; + } + search->pack->binary = BINARY_NO; + for ( pakFile = search->pack->hashTable[confHash]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, BINARY_CONFIG ) ) { + search->pack->binary = BINARY_YES; + confFile = ReadFileFromZip( search->pack, pakFile, BINARY_CONFIG ); + buf = new char[ confFile->Length() + 1 ]; + confFile->Read( (void *)buf, confFile->Length() ); + buf[ confFile->Length() ] = '\0'; + lexConf = new idLexer( buf, confFile->Length(), confFile->GetFullPath() ); + while ( lexConf->ReadToken( &token ) ) { + if ( token.IsNumeric() ) { + id = atoi( token ); + if ( id < MAX_GAME_OS && !gamePakForOS[ id ] ) { + if ( fs_debug.GetBool() ) { + common->Printf( "Adding game pak checksum for OS %d: %s 0x%x\n", id, confFile->GetFullPath(), search->pack->checksum ); + } + gamePakForOS[ id ] = search->pack->checksum; + } + } + } + CloseFile( confFile ); + delete lexConf; + delete[] buf; + } + } + } + + // some sanity checks on the game code references + // make sure that at least the local OS got a pure reference + if ( !gamePakForOS[ BUILD_OS_ID ] ) { + common->Warning( "No game code pak reference found for the local OS" ); + return false; + } + + if ( !cvarSystem->GetCVarBool( "net_serverAllowServerMod" ) && + gamePakChecksum != gamePakForOS[ BUILD_OS_ID ] ) { + common->Warning( "The current game code doesn't match pak files (net_serverAllowServerMod is off)" ); + return false; + } + + return true; +} + +/* +===================== +idFileSystemLocal::GetPackForChecksum +===================== +*/ +pack_t* idFileSystemLocal::GetPackForChecksum( int checksum, bool searchAddons ) { + searchpath_t *search; + for ( search = searchPaths; search; search = search->next ) { + if ( !search->pack ) { + continue; + } + if ( search->pack->checksum == checksum ) { + return search->pack; + } + } + if ( searchAddons ) { + for ( search = addonPaks; search; search = search->next ) { + assert( search->pack && search->pack->addon ); + if ( search->pack->checksum == checksum ) { + return search->pack; + } + } + } + return NULL; +} + +/* +=============== +idFileSystemLocal::ValidateDownloadPakForChecksum +=============== +*/ +int idFileSystemLocal::ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isBinary ) { + int i; + idStrList testList; + idStr name; + idStr relativePath; + bool pakBinary; + pack_t *pak = GetPackForChecksum( checksum ); + + if ( !pak ) { + return 0; + } + + // validate this pak for a potential download + // ignore pak*.pk4 for download. those are reserved to distribution and cannot be downloaded + name = pak->pakFilename; + name.StripPath(); + if ( strstr( name.c_str(), "pak" ) == name.c_str() ) { + common->DPrintf( "%s is not a donwloadable pak\n", pak->pakFilename.c_str() ); + return 0; + } + // check the binary + // a pure server sets the binary flag when starting the game + assert( pak->binary != BINARY_UNKNOWN ); + pakBinary = ( pak->binary == BINARY_YES ) ? true : false; + if ( isBinary != pakBinary ) { + common->DPrintf( "%s binary flag mismatch\n", pak->pakFilename.c_str() ); + return 0; + } + + // extract a path that includes the fs_game: != OSPathToRelativePath + testList.Append( fs_savepath.GetString() ); + testList.Append( fs_devpath.GetString() ); + testList.Append( fs_basepath.GetString() ); + testList.Append( fs_cdpath.GetString() ); + for ( i = 0; i < testList.Num(); i ++ ) { + if ( testList[ i ].Length() && !testList[ i ].Icmpn( pak->pakFilename, testList[ i ].Length() ) ) { + relativePath = pak->pakFilename.c_str() + testList[ i ].Length() + 1; + break; + } + } + if ( i == testList.Num() ) { + common->Warning( "idFileSystem::ValidateDownloadPak: failed to extract relative path for %s", pak->pakFilename.c_str() ); + return 0; + } + idStr::Copynz( path, relativePath, MAX_STRING_CHARS ); + return pak->length; +} + +/* +===================== +idFileSystemLocal::ClearPureChecksums +===================== +*/ +void idFileSystemLocal::ClearPureChecksums( void ) { + common->DPrintf( "Cleared pure server lock\n" ); + serverPaks.Clear(); +} + +/* +===================== +idFileSystemLocal::SetPureServerChecksums +set the pure paks according to what the server asks +if that's not possible, identify why and build an answer +can be: + loadedFileFromDir - some files were loaded from directories instead of paks (a restart in pure pak-only is required) + missing/wrong checksums - some pak files would need to be installed/updated (downloaded for instance) + some pak files currently referenced are not referenced by the server + wrong order - if the pak order doesn't match, means some stuff could have been loaded from somewhere else +server referenced files are prepended to the list if possible ( that doesn't break pureness ) +DLL: + the checksum of the pak containing the DLL is maintained seperately, the server can send different replies by OS +===================== +*/ +fsPureReply_t idFileSystemLocal::SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int _gamePakChecksum, int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum ) { + pack_t *pack; + int i, j, imissing; + bool success = true; + bool canPrepend = true; + char dllName[MAX_OSPATH]; + int dllHash; + fileInPack_t * pakFile; + + sys->DLL_GetFileName( "game", dllName, MAX_OSPATH ); + dllHash = HashFileName( dllName ); + + imissing = 0; + missingChecksums[ 0 ] = 0; + assert( missingGamePakChecksum ); + *missingGamePakChecksum = 0; + + if ( pureChecksums[ 0 ] == 0 ) { + ClearPureChecksums(); + return PURE_OK; + } + + if ( !serverPaks.Num() ) { + // there was no pure lockdown yet - lock to what we already have + UpdatePureServerChecksums(); + } + i = 0; j = 0; + while ( pureChecksums[ i ] ) { + if ( j < serverPaks.Num() && serverPaks[ j ]->checksum == pureChecksums[ i ] ) { + canPrepend = false; // once you start matching into the list there is no prepending anymore + i++; j++; // the pak is matched, is in the right order, continue.. + } else { + pack = GetPackForChecksum( pureChecksums[ i ], true ); + if ( pack && pack->addon && !pack->addon_search ) { + // this is an addon pack, and it's not on our current search list + // setting success to false meaning that a restart including this addon is required + if ( fs_debug.GetBool() ) { + common->Printf( "pak %s checksumed 0x%x is on addon list. Restart required.\n", pack->pakFilename.c_str(), pack->checksum ); + } + success = false; + } + if ( pack && pack->isNew ) { + // that's a downloaded pack, we will need to restart + if ( fs_debug.GetBool() ) { + common->Printf( "pak %s checksumed 0x%x is a newly downloaded file. Restart required.\n", pack->pakFilename.c_str(), pack->checksum ); + } + success = false; + } + if ( pack ) { + if ( canPrepend ) { + // we still have a chance + if ( fs_debug.GetBool() ) { + common->Printf( "prepend pak %s checksumed 0x%x at index %d\n", pack->pakFilename.c_str(), pack->checksum, j ); + } + // NOTE: there is a light possibility this adds at the end of the list if UpdatePureServerChecksums didn't set anything + serverPaks.Insert( pack, j ); + i++; j++; // continue.. + } else { + success = false; + if ( fs_debug.GetBool() ) { + // verbose the situation + if ( serverPaks.Find( pack ) ) { + common->Printf( "pak %s checksumed 0x%x is in the pure list at wrong index. Current index is %d, found at %d\n", pack->pakFilename.c_str(), pack->checksum, j, serverPaks.FindIndex( pack ) ); + } else { + common->Printf( "pak %s checksumed 0x%x can't be added to pure list because of search order\n", pack->pakFilename.c_str(), pack->checksum ); + } + } + i++; // advance server checksums only + } + } else { + // didn't find a matching checksum + success = false; + missingChecksums[ imissing++ ] = pureChecksums[ i ]; + missingChecksums[ imissing ] = 0; + if ( fs_debug.GetBool() ) { + common->Printf( "checksum not found - 0x%x\n", pureChecksums[ i ] ); + } + i++; // advance the server checksums only + } + } + } + while ( j < serverPaks.Num() ) { + success = false; // just in case some extra pak files are referenced at the end of our local list + if ( fs_debug.GetBool() ) { + common->Printf( "pak %s checksumed 0x%x is an extra reference at the end of local pure list\n", serverPaks[ j ]->pakFilename.c_str(), serverPaks[ j ]->checksum ); + } + j++; + } + + // DLL checksuming + if ( !_gamePakChecksum ) { + // server doesn't have knowledge of code we can use ( OS issue ) + return PURE_NODLL; + } + assert( gameDLLChecksum ); +#if ID_FAKE_PURE + gamePakChecksum = _gamePakChecksum; +#endif + if ( _gamePakChecksum != gamePakChecksum ) { + // current DLL is wrong, search for a pak with the approriate checksum + // ( search all paks, the pure list is not relevant here ) + pack = GetPackForChecksum( _gamePakChecksum ); + if ( !pack ) { + if ( fs_debug.GetBool() ) { + common->Printf( "missing the game code pak ( 0x%x )\n", _gamePakChecksum ); + } + // if there are other paks missing they have also been marked above + *missingGamePakChecksum = _gamePakChecksum; + return PURE_MISSING; + } + // if assets paks are missing, don't try any of the DLL restart / NODLL + if ( imissing ) { + return PURE_MISSING; + } + // we have a matching pak + if ( fs_debug.GetBool() ) { + common->Printf( "server's game code pak candidate is '%s' ( 0x%x )\n", pack->pakFilename.c_str(), pack->checksum ); + } + // make sure there is a valid DLL for us + if ( pack->hashTable[ dllHash ] ) { + for ( pakFile = pack->hashTable[ dllHash ]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, dllName ) ) { + gamePakChecksum = _gamePakChecksum; // this will be used to extract the DLL in pure mode FindDLL + return PURE_RESTART; + } + } + } + common->Warning( "media is misconfigured. server claims pak '%s' ( 0x%x ) has media for us, but '%s' is not found\n", pack->pakFilename.c_str(), pack->checksum, dllName ); + return PURE_NODLL; + } + + // we reply to missing after DLL check so it can be part of the list + if ( imissing ) { + return PURE_MISSING; + } + + // one last check + if ( loadedFileFromDir ) { + success = false; + if ( fs_debug.GetBool() ) { + common->Printf( "SetPureServerChecksums: there are files loaded from dir\n" ); + } + } + return ( success ? PURE_OK : PURE_RESTART ); +} + +/* +===================== +idFileSystemLocal::GetPureServerChecksums +===================== +*/ +void idFileSystemLocal::GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int *_gamePakChecksum ) { + int i; + + for ( i = 0; i < serverPaks.Num(); i++ ) { + checksums[ i ] = serverPaks[ i ]->checksum; + } + checksums[ i ] = 0; + if ( _gamePakChecksum ) { + if ( OS >= 0 ) { + *_gamePakChecksum = gamePakForOS[ OS ]; + } else { + *_gamePakChecksum = gamePakChecksum; + } + } +} + +/* +===================== +idFileSystemLocal::SetRestartChecksums +===================== +*/ +void idFileSystemLocal::SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ) { + int i; + pack_t *pack; + + restartChecksums.Clear(); + i = 0; + while ( pureChecksums[ i ] ) { + pack = GetPackForChecksum( pureChecksums[ i ], true ); + if ( !pack ) { + common->FatalError( "SetRestartChecksums failed: no pak for checksum 0x%x\n", pureChecksums[i] ); + } + if ( pack->addon && addonChecksums.FindIndex( pack->checksum ) < 0 ) { + // can't mark it pure if we're not even gonna search it :-) + addonChecksums.Append( pack->checksum ); + } + restartChecksums.Append( pureChecksums[ i ] ); + i++; + } + restartGamePakChecksum = gamePakChecksum; +} + +/* +================ +idFileSystemLocal::Init + +Called only at inital startup, not when the filesystem +is resetting due to a game change +================ +*/ +void idFileSystemLocal::Init( void ) { + // allow command line parms to override our defaults + // we have to specially handle this, because normal command + // line variable sets don't happen until after the filesystem + // has already been initialized + common->StartupVariable( "fs_basepath", false ); + common->StartupVariable( "fs_savepath", false ); + common->StartupVariable( "fs_cdpath", false ); + common->StartupVariable( "fs_devpath", false ); + common->StartupVariable( "fs_game", false ); + common->StartupVariable( "fs_game_base", false ); + common->StartupVariable( "fs_copyfiles", false ); + common->StartupVariable( "fs_restrict", false ); + common->StartupVariable( "fs_searchAddons", false ); + +#if !ID_ALLOW_D3XP + if ( fs_game.GetString()[0] && !idStr::Icmp( fs_game.GetString(), "d3xp" ) ) { + fs_game.SetString( NULL ); + } + if ( fs_game_base.GetString()[0] && !idStr::Icmp( fs_game_base.GetString(), "d3xp" ) ) { + fs_game_base.SetString( NULL ); + } +#endif + + if ( fs_basepath.GetString()[0] == '\0' ) { + fs_basepath.SetString( Sys_DefaultBasePath() ); + } + if ( fs_savepath.GetString()[0] == '\0' ) { + fs_savepath.SetString( Sys_DefaultSavePath() ); + } + if ( fs_cdpath.GetString()[0] == '\0' ) { + fs_cdpath.SetString( Sys_DefaultCDPath() ); + } + + if ( fs_devpath.GetString()[0] == '\0' ) { +#ifdef WIN32 + fs_devpath.SetString( fs_cdpath.GetString()[0] ? fs_cdpath.GetString() : fs_basepath.GetString() ); +#else + fs_devpath.SetString( fs_savepath.GetString() ); +#endif + } + + // try to start up normally + Startup( ); + + // see if we are going to allow add-ons + SetRestrictions(); + + // spawn a thread to handle background file reads + StartBackgroundDownloadThread(); + + // if we can't find default.cfg, assume that the paths are + // busted and error out now, rather than getting an unreadable + // graphics screen when the font fails to load + // Dedicated servers can run with no outside files at all + if ( ReadFile( "default.cfg", NULL, NULL ) <= 0 ) { + common->FatalError( "Couldn't load default.cfg" ); + } +} + +/* +================ +idFileSystemLocal::Restart +================ +*/ +void idFileSystemLocal::Restart( void ) { + // free anything we currently have loaded + Shutdown( true ); + + Startup( ); + + // see if we are going to allow add-ons + SetRestrictions(); + + // if we can't find default.cfg, assume that the paths are + // busted and error out now, rather than getting an unreadable + // graphics screen when the font fails to load + if ( ReadFile( "default.cfg", NULL, NULL ) <= 0 ) { + common->FatalError( "Couldn't load default.cfg" ); + } +} + +/* +================ +idFileSystemLocal::Shutdown + +Frees all resources and closes all files +================ +*/ +void idFileSystemLocal::Shutdown( bool reloading ) { + searchpath_t *sp, *next, *loop; + + gameFolder.Clear(); + + serverPaks.Clear(); + if ( !reloading ) { + restartChecksums.Clear(); + addonChecksums.Clear(); + } + loadedFileFromDir = false; + gameDLLChecksum = 0; + gamePakChecksum = 0; + + ClearDirCache(); + + // free everything - loop through searchPaths and addonPaks + for ( loop = searchPaths; loop; loop == searchPaths ? loop = addonPaks : loop = NULL ) { + for ( sp = loop; sp; sp = next ) { + next = sp->next; + + if ( sp->pack ) { + unzClose( sp->pack->handle ); + delete [] sp->pack->buildBuffer; + if ( sp->pack->addon_info ) { + sp->pack->addon_info->mapDecls.DeleteContents( true ); + delete sp->pack->addon_info; + } + delete sp->pack; + } + if ( sp->dir ) { + delete sp->dir; + } + delete sp; + } + } + + // any FS_ calls will now be an error until reinitialized + searchPaths = NULL; + addonPaks = NULL; + + cmdSystem->RemoveCommand( "path" ); + cmdSystem->RemoveCommand( "dir" ); + cmdSystem->RemoveCommand( "dirtree" ); + cmdSystem->RemoveCommand( "touchFile" ); + + mapDict.Clear(); +} + +/* +================ +idFileSystemLocal::IsInitialized +================ +*/ +bool idFileSystemLocal::IsInitialized( void ) const { + return ( searchPaths != NULL ); +} + + +/* +================================================================================= + +Opening files + +================================================================================= +*/ + +/* +=========== +idFileSystemLocal::FileAllowedFromDir +=========== +*/ +bool idFileSystemLocal::FileAllowedFromDir( const char *path ) { + unsigned int l; + + l = strlen( path ); + + if ( !strcmp( path + l - 4, ".cfg" ) // for config files + || !strcmp( path + l - 4, ".dat" ) // for journal files + || !strcmp( path + l - 4, ".dll" ) // dynamic modules are handled a different way for pure + || !strcmp( path + l - 3, ".so" ) + || ( l > 6 && !strcmp( path + l - 6, ".dylib" ) ) + || ( l > 10 && !strcmp( path + l - 10, ".scriptcfg" ) ) // configuration script, such as map cycle +#if ID_PURE_ALLOWDDS + || !strcmp( path + l - 4, ".dds" ) +#endif + ) { + // note: cd and xp keys, as well as config.spec are opened through an explicit OS path and don't hit this + return true; + } + // savegames + if ( strstr( path, "savegames" ) == path && + ( !strcmp( path + l - 4, ".tga" ) || !strcmp( path + l -4, ".txt" ) || !strcmp( path + l - 5, ".save" ) ) ) { + return true; + } + // screen shots + if ( strstr( path, "screenshots" ) == path && !strcmp( path + l - 4, ".tga" ) ) { + return true; + } + // objective tgas + if ( strstr( path, "maps/game" ) == path && + !strcmp( path + l - 4, ".tga" ) ) { + return true; + } + // splash screens extracted from addons + if ( strstr( path, "guis/assets/splash/addon" ) == path && + !strcmp( path + l -4, ".tga" ) ) { + return true; + } + + return false; +} + +/* +=========== +idFileSystemLocal::GetPackStatus +=========== +*/ +pureStatus_t idFileSystemLocal::GetPackStatus( pack_t *pak ) { + int i, l, hashindex; + fileInPack_t *file; + bool abrt; + idStr name; + + if ( pak->pureStatus != PURE_UNKNOWN ) { + return pak->pureStatus; + } + + // check content for PURE_NEVER + i = 0; + file = pak->buildBuffer; + for ( hashindex = 0; hashindex < FILE_HASH_SIZE; hashindex++ ) { + abrt = false; + file = pak->hashTable[ hashindex ]; + while ( file ) { + abrt = true; + l = file->name.Length(); + for ( int j = 0; pureExclusions[j].func != NULL; j++ ) { + if ( pureExclusions[j].func( pureExclusions[j], l, file->name ) ) { + abrt = false; + break; + } + } + if ( abrt ) { + common->DPrintf( "pak '%s' candidate for pure: '%s'\n", pak->pakFilename.c_str(), file->name.c_str() ); + break; + } + file = file->next; + i++; + } + if ( abrt ) { + break; + } + } + if ( i == pak->numfiles ) { + pak->pureStatus = PURE_NEVER; + return PURE_NEVER; + } + + // check pak name for PURE_ALWAYS + pak->pakFilename.ExtractFileName( name ); + if ( !name.IcmpPrefixPath( "pak" ) ) { + pak->pureStatus = PURE_ALWAYS; + return PURE_ALWAYS; + } + + pak->pureStatus = PURE_NEUTRAL; + return PURE_NEUTRAL; +} + +/* +=========== +idFileSystemLocal::ReadFileFromZip +=========== +*/ +idFile_InZip * idFileSystemLocal::ReadFileFromZip( pack_t *pak, fileInPack_t *pakFile, const char *relativePath ) { + unz_s * zfi; + FILE * fp; + idFile_InZip *file = new idFile_InZip(); + + // open a new file on the pakfile + file->z = unzReOpen( pak->pakFilename, pak->handle ); + if ( file->z == NULL ) { + common->FatalError( "Couldn't reopen %s", pak->pakFilename.c_str() ); + } + file->name = relativePath; + file->fullPath = pak->pakFilename + "/" + relativePath; + zfi = (unz_s *)file->z; + // in case the file was new + fp = zfi->file; + // set the file position in the zip file (also sets the current file info) + unzSetCurrentFileInfoPosition( pak->handle, pakFile->pos ); + // copy the file info into the unzip structure + memcpy( zfi, pak->handle, sizeof(unz_s) ); + // we copy this back into the structure + zfi->file = fp; + // open the file in the zip + unzOpenCurrentFile( file->z ); + file->zipFilePos = pakFile->pos; + file->fileSize = zfi->cur_file_info.uncompressed_size; + return file; +} + +/* +=========== +idFileSystemLocal::OpenFileReadFlags + +Finds the file in the search path, following search flag recommendations +Returns filesize and an open FILE pointer. +Used for streaming data out of either a +separate file or a ZIP file. +=========== +*/ +idFile *idFileSystemLocal::OpenFileReadFlags( const char *relativePath, int searchFlags, pack_t **foundInPak, bool allowCopyFiles, const char* gamedir ) { + searchpath_t * search; + idStr netpath; + pack_t * pak; + fileInPack_t * pakFile; + directory_t * dir; + long hash; + FILE * fp; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( !relativePath ) { + common->FatalError( "idFileSystemLocal::OpenFileRead: NULL 'relativePath' parameter passed\n" ); + } + + if ( foundInPak ) { + *foundInPak = NULL; + } + + // qpaths are not supposed to have a leading slash + if ( relativePath[0] == '/' || relativePath[0] == '\\' ) { + relativePath++; + } + + // make absolutely sure that it can't back up the path. + // The searchpaths do guarantee that something will always + // be prepended, so we don't need to worry about "c:" or "//limbo" + if ( strstr( relativePath, ".." ) || strstr( relativePath, "::" ) ) { + return NULL; + } + + // edge case + if ( relativePath[0] == '\0' ) { + return NULL; + } + + // make sure the doomkey file is only readable by game at initialization + // any other time the key should only be accessed in memory using the provided functions + if( common->IsInitialized() && ( idStr::Icmp( relativePath, CDKEY_FILE ) == 0 || idStr::Icmp( relativePath, XPKEY_FILE ) == 0 ) ) { + return NULL; + } + + // + // search through the path, one element at a time + // + + hash = HashFileName( relativePath ); + + for ( search = searchPaths; search; search = search->next ) { + if ( search->dir && ( searchFlags & FSFLAG_SEARCH_DIRS ) ) { + // check a file in the directory tree + + // if we are running restricted, the only files we + // will allow to come from the directory are .cfg files + if ( fs_restrict.GetBool() || serverPaks.Num() ) { + if ( !FileAllowedFromDir( relativePath ) ) { + continue; + } + } + + dir = search->dir; + + if(gamedir && strlen(gamedir)) { + if(dir->gamedir != gamedir) { + continue; + } + } + + netpath = BuildOSPath( dir->path, dir->gamedir, relativePath ); + fp = OpenOSFileCorrectName( netpath, "rb" ); + if ( !fp ) { + continue; + } + + idFile_Permanent *file = new idFile_Permanent(); + file->o = fp; + file->name = relativePath; + file->fullPath = netpath; + file->mode = ( 1 << FS_READ ); + file->fileSize = DirectFileLength( file->o ); + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystem::OpenFileRead: %s (found in '%s/%s')\n", relativePath, dir->path.c_str(), dir->gamedir.c_str() ); + } + + if ( !loadedFileFromDir && !FileAllowedFromDir( relativePath ) ) { + if ( restartChecksums.Num() ) { + common->FatalError( "'%s' loaded from directory: Failed to restart with pure mode restrictions for server connect", relativePath ); + } + common->DPrintf( "filesystem: switching to pure mode will require a restart. '%s' loaded from directory.\n", relativePath ); + loadedFileFromDir = true; + } + + // if fs_copyfiles is set + if ( allowCopyFiles && fs_copyfiles.GetInteger() ) { + + idStr copypath; + idStr name; + copypath = BuildOSPath( fs_savepath.GetString(), dir->gamedir, relativePath ); + netpath.ExtractFileName( name ); + copypath.StripFilename( ); + copypath += PATHSEPERATOR_STR; + copypath += name; + + bool isFromCDPath = !dir->path.Cmp( fs_cdpath.GetString() ); + bool isFromSavePath = !dir->path.Cmp( fs_savepath.GetString() ); + bool isFromBasePath = !dir->path.Cmp( fs_basepath.GetString() ); + + switch ( fs_copyfiles.GetInteger() ) { + case 1: + // copy from cd path only + if ( isFromCDPath ) { + CopyFile( netpath, copypath ); + } + break; + case 2: + // from cd path + timestamps + if ( isFromCDPath ) { + CopyFile( netpath, copypath ); + } else if ( isFromSavePath || isFromBasePath ) { + idStr sourcepath; + sourcepath = BuildOSPath( fs_cdpath.GetString(), dir->gamedir, relativePath ); + FILE *f1 = OpenOSFile( sourcepath, "r" ); + if ( f1 ) { + ID_TIME_T t1 = Sys_FileTimeStamp( f1 ); + fclose( f1 ); + FILE *f2 = OpenOSFile( copypath, "r" ); + if ( f2 ) { + ID_TIME_T t2 = Sys_FileTimeStamp( f2 ); + fclose( f2 ); + if ( t1 > t2 ) { + CopyFile( sourcepath, copypath ); + } + } + } + } + break; + case 3: + if ( isFromCDPath || isFromBasePath ) { + CopyFile( netpath, copypath ); + } + break; + case 4: + if ( isFromCDPath && !isFromBasePath ) { + CopyFile( netpath, copypath ); + } + break; + } + } + + return file; + } else if ( search->pack && ( searchFlags & FSFLAG_SEARCH_PAKS ) ) { + + if ( !search->pack->hashTable[hash] ) { + continue; + } + + // disregard if it doesn't match one of the allowed pure pak files + if ( serverPaks.Num() ) { + GetPackStatus( search->pack ); + if ( search->pack->pureStatus != PURE_NEVER && !serverPaks.Find( search->pack ) ) { + continue; // not on the pure server pak list + } + } + + // look through all the pak file elements + pak = search->pack; + + if ( searchFlags & FSFLAG_BINARY_ONLY ) { + // make sure this pak is tagged as a binary file + if ( pak->binary == BINARY_UNKNOWN ) { + int confHash; + fileInPack_t *pakFile; + confHash = HashFileName( BINARY_CONFIG ); + pak->binary = BINARY_NO; + for ( pakFile = search->pack->hashTable[confHash]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, BINARY_CONFIG ) ) { + pak->binary = BINARY_YES; + break; + } + } + } + if ( pak->binary == BINARY_NO ) { + continue; // not a binary pak, skip + } + } + + for ( pakFile = pak->hashTable[hash]; pakFile; pakFile = pakFile->next ) { + // case and separator insensitive comparisons + if ( !FilenameCompare( pakFile->name, relativePath ) ) { + idFile_InZip *file = ReadFileFromZip( pak, pakFile, relativePath ); + + if ( foundInPak ) { + *foundInPak = pak; + } + + if ( !pak->referenced && !( searchFlags & FSFLAG_PURE_NOREF ) ) { + // mark this pak referenced + if ( fs_debug.GetInteger( ) ) { + common->Printf( "idFileSystem::OpenFileRead: %s -> adding %s to referenced paks\n", relativePath, pak->pakFilename.c_str() ); + } + pak->referenced = true; + } + + if ( fs_debug.GetInteger( ) ) { + common->Printf( "idFileSystem::OpenFileRead: %s (found in '%s')\n", relativePath, pak->pakFilename.c_str() ); + } + return file; + } + } + } + } + + if ( searchFlags & FSFLAG_SEARCH_ADDONS ) { + for ( search = addonPaks; search; search = search->next ) { + assert( search->pack ); + fileInPack_t *pakFile; + pak = search->pack; + for ( pakFile = pak->hashTable[hash]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, relativePath ) ) { + idFile_InZip *file = ReadFileFromZip( pak, pakFile, relativePath ); + if ( foundInPak ) { + *foundInPak = pak; + } + // we don't toggle pure on paks found in addons - they can't be used without a reloadEngine anyway + if ( fs_debug.GetInteger( ) ) { + common->Printf( "idFileSystem::OpenFileRead: %s (found in addon pk4 '%s')\n", relativePath, search->pack->pakFilename.c_str() ); + } + return file; + } + } + } + } + + if ( fs_debug.GetInteger( ) ) { + common->Printf( "Can't find %s\n", relativePath ); + } + + return NULL; +} + +/* +=========== +idFileSystemLocal::OpenFileRead +=========== +*/ +idFile *idFileSystemLocal::OpenFileRead( const char *relativePath, bool allowCopyFiles, const char* gamedir ) { + return OpenFileReadFlags( relativePath, FSFLAG_SEARCH_DIRS | FSFLAG_SEARCH_PAKS, NULL, allowCopyFiles, gamedir ); +} + +/* +=========== +idFileSystemLocal::OpenFileWrite +=========== +*/ +idFile *idFileSystemLocal::OpenFileWrite( const char *relativePath, const char *basePath ) { + const char *path; + idStr OSpath; + idFile_Permanent *f; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + path = cvarSystem->GetCVarString( basePath ); + if ( !path[0] ) { + path = fs_savepath.GetString(); + } + + OSpath = BuildOSPath( path, gameFolder, relativePath ); + + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystem::OpenFileWrite: %s\n", OSpath.c_str() ); + } + + // if the dir we are writing to is in our current list, it will be outdated + // so just flush everything + ClearDirCache(); + + common->DPrintf( "writing to: %s\n", OSpath.c_str() ); + CreateOSPath( OSpath ); + + f = new idFile_Permanent(); + f->o = OpenOSFile( OSpath, "wb" ); + if ( !f->o ) { + delete f; + return NULL; + } + f->name = relativePath; + f->fullPath = OSpath; + f->mode = ( 1 << FS_WRITE ); + f->handleSync = false; + f->fileSize = 0; + + return f; +} + +/* +=========== +idFileSystemLocal::OpenExplicitFileRead +=========== +*/ +idFile *idFileSystemLocal::OpenExplicitFileRead( const char *OSPath ) { + idFile_Permanent *f; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystem::OpenExplicitFileRead: %s\n", OSPath ); + } + + common->DPrintf( "idFileSystem::OpenExplicitFileRead - reading from: %s\n", OSPath ); + + f = new idFile_Permanent(); + f->o = OpenOSFile( OSPath, "rb" ); + if ( !f->o ) { + delete f; + return NULL; + } + f->name = OSPath; + f->fullPath = OSPath; + f->mode = ( 1 << FS_READ ); + f->handleSync = false; + f->fileSize = DirectFileLength( f->o ); + + return f; +} + +/* +=========== +idFileSystemLocal::OpenExplicitFileWrite +=========== +*/ +idFile *idFileSystemLocal::OpenExplicitFileWrite( const char *OSPath ) { + idFile_Permanent *f; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystem::OpenExplicitFileWrite: %s\n", OSPath ); + } + + common->DPrintf( "writing to: %s\n", OSPath ); + CreateOSPath( OSPath ); + + f = new idFile_Permanent(); + f->o = OpenOSFile( OSPath, "wb" ); + if ( !f->o ) { + delete f; + return NULL; + } + f->name = OSPath; + f->fullPath = OSPath; + f->mode = ( 1 << FS_WRITE ); + f->handleSync = false; + f->fileSize = 0; + + return f; +} + +/* +=========== +idFileSystemLocal::OpenFileAppend +=========== +*/ +idFile *idFileSystemLocal::OpenFileAppend( const char *relativePath, bool sync, const char *basePath ) { + const char *path; + idStr OSpath; + idFile_Permanent *f; + + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + + path = cvarSystem->GetCVarString( basePath ); + if ( !path[0] ) { + path = fs_savepath.GetString(); + } + + OSpath = BuildOSPath( path, gameFolder, relativePath ); + CreateOSPath( OSpath ); + + if ( fs_debug.GetInteger() ) { + common->Printf( "idFileSystem::OpenFileAppend: %s\n", OSpath.c_str() ); + } + + f = new idFile_Permanent(); + f->o = OpenOSFile( OSpath, "ab" ); + if ( !f->o ) { + delete f; + return NULL; + } + f->name = relativePath; + f->fullPath = OSpath; + f->mode = ( 1 << FS_WRITE ) + ( 1 << FS_APPEND ); + f->handleSync = sync; + f->fileSize = DirectFileLength( f->o ); + + return f; +} + +/* +================ +idFileSystemLocal::OpenFileByMode +================ +*/ +idFile *idFileSystemLocal::OpenFileByMode( const char *relativePath, fsMode_t mode ) { + if ( mode == FS_READ ) { + return OpenFileRead( relativePath ); + } + if ( mode == FS_WRITE ) { + return OpenFileWrite( relativePath ); + } + if ( mode == FS_APPEND ) { + return OpenFileAppend( relativePath, true ); + } + common->FatalError( "idFileSystemLocal::OpenFileByMode: bad mode" ); + return NULL; +} + +/* +============== +idFileSystemLocal::CloseFile +============== +*/ +void idFileSystemLocal::CloseFile( idFile *f ) { + if ( !searchPaths ) { + common->FatalError( "Filesystem call made without initialization\n" ); + } + delete f; +} + + +/* +================================================================================= + +back ground loading + +================================================================================= +*/ + +/* +================= +idFileSystemLocal::CurlWriteFunction +================= +*/ +size_t idFileSystemLocal::CurlWriteFunction( void *ptr, size_t size, size_t nmemb, void *stream ) { + backgroundDownload_t *bgl = (backgroundDownload_t *)stream; + if ( !bgl->f ) { + return size * nmemb; + } + #ifdef _WIN32 + return _write( static_cast(bgl->f)->GetFilePtr()->_file, ptr, size * nmemb ); + #else + return fwrite( ptr, size, nmemb, static_cast(bgl->f)->GetFilePtr() ); + #endif +} + +/* +================= +idFileSystemLocal::CurlProgressFunction +================= +*/ +int idFileSystemLocal::CurlProgressFunction( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow ) { + backgroundDownload_t *bgl = (backgroundDownload_t *)clientp; + if ( bgl->url.status == DL_ABORTING ) { + return 1; + } + bgl->url.dltotal = dltotal; + bgl->url.dlnow = dlnow; + return 0; +} + +/* +=================== +BackgroundDownload + +Reads part of a file from a background thread. +=================== +*/ +dword BackgroundDownloadThread( void *parms ) { + while( 1 ) { + Sys_EnterCriticalSection(); + backgroundDownload_t *bgl = fileSystemLocal.backgroundDownloads; + if ( !bgl ) { + Sys_LeaveCriticalSection(); + Sys_WaitForEvent(); + continue; + } + // remove this from the list + fileSystemLocal.backgroundDownloads = bgl->next; + Sys_LeaveCriticalSection(); + + bgl->next = NULL; + + if ( bgl->opcode == DLTYPE_FILE ) { + // use the low level read function, because fread may allocate memory + #if defined(WIN32) + _read( static_cast(bgl->f)->GetFilePtr()->_file, bgl->file.buffer, bgl->file.length ); + #else + fread( bgl->file.buffer, bgl->file.length, 1, static_cast(bgl->f)->GetFilePtr() ); + #endif + bgl->completed = true; + } else { +#if ID_ENABLE_CURL + // DLTYPE_URL + // use a local buffer for curl error since the size define is local + char error_buf[ CURL_ERROR_SIZE ]; + bgl->url.dlerror[ 0 ] = '\0'; + CURL *session = curl_easy_init(); + CURLcode ret; + if ( !session ) { + bgl->url.dlstatus = CURLE_FAILED_INIT; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_ERRORBUFFER, error_buf ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_URL, bgl->url.url.c_str() ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_FAILONERROR, 1 ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_WRITEFUNCTION, idFileSystemLocal::CurlWriteFunction ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_WRITEDATA, bgl ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_NOPROGRESS, 0 ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_PROGRESSFUNCTION, idFileSystemLocal::CurlProgressFunction ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + ret = curl_easy_setopt( session, CURLOPT_PROGRESSDATA, bgl ); + if ( ret ) { + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + bgl->url.dlnow = 0; + bgl->url.dltotal = 0; + bgl->url.status = DL_INPROGRESS; + ret = curl_easy_perform( session ); + if ( ret ) { + Sys_Printf( "curl_easy_perform failed: %s\n", error_buf ); + idStr::Copynz( bgl->url.dlerror, error_buf, MAX_STRING_CHARS ); + bgl->url.dlstatus = ret; + bgl->url.status = DL_FAILED; + bgl->completed = true; + continue; + } + bgl->url.status = DL_DONE; + bgl->completed = true; +#else + bgl->url.status = DL_FAILED; + bgl->completed = true; +#endif + } + } + return 0; +} + +/* +================= +idFileSystemLocal::StartBackgroundReadThread +================= +*/ +void idFileSystemLocal::StartBackgroundDownloadThread() { + if ( !backgroundThread.threadHandle ) { + Sys_CreateThread( (xthread_t)BackgroundDownloadThread, NULL, THREAD_NORMAL, backgroundThread, "backgroundDownload", g_threads, &g_thread_count ); + if ( !backgroundThread.threadHandle ) { + common->Warning( "idFileSystemLocal::StartBackgroundDownloadThread: failed" ); + } + } else { + common->Printf( "background thread already running\n" ); + } +} + +/* +================= +idFileSystemLocal::BackgroundDownload +================= +*/ +void idFileSystemLocal::BackgroundDownload( backgroundDownload_t *bgl ) { + if ( bgl->opcode == DLTYPE_FILE ) { + if ( dynamic_cast(bgl->f) ) { + // add the bgl to the background download list + Sys_EnterCriticalSection(); + bgl->next = backgroundDownloads; + backgroundDownloads = bgl; + Sys_TriggerEvent(); + Sys_LeaveCriticalSection(); + } else { + // read zipped file directly + bgl->f->Seek( bgl->file.position, FS_SEEK_SET ); + bgl->f->Read( bgl->file.buffer, bgl->file.length ); + bgl->completed = true; + } + } else { + Sys_EnterCriticalSection(); + bgl->next = backgroundDownloads; + backgroundDownloads = bgl; + Sys_TriggerEvent(); + Sys_LeaveCriticalSection(); + } +} + +/* +================= +idFileSystemLocal::PerformingCopyFiles +================= +*/ +bool idFileSystemLocal::PerformingCopyFiles( void ) const { + return fs_copyfiles.GetInteger() > 0; +} + +/* +================= +idFileSystemLocal::FindPakForFileChecksum +================= +*/ +pack_t *idFileSystemLocal::FindPakForFileChecksum( const char *relativePath, int findChecksum, bool bReference ) { + searchpath_t *search; + pack_t *pak; + fileInPack_t *pakFile; + int hash; + assert( !serverPaks.Num() ); + hash = HashFileName( relativePath ); + for ( search = searchPaths; search; search = search->next ) { + if ( search->pack && search->pack->hashTable[ hash ] ) { + pak = search->pack; + for ( pakFile = pak->hashTable[ hash ]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, relativePath ) ) { + idFile_InZip *file = ReadFileFromZip( pak, pakFile, relativePath ); + if ( findChecksum == GetFileChecksum( file ) ) { + if ( fs_debug.GetBool() ) { + common->Printf( "found '%s' with checksum 0x%x in pak '%s'\n", relativePath, findChecksum, pak->pakFilename.c_str() ); + } + if ( bReference ) { + pak->referenced = true; + // FIXME: use dependencies for pak references + } + CloseFile( file ); + return pak; + } else if ( fs_debug.GetBool() ) { + common->Printf( "'%s' in pak '%s' has != checksum %x\n", relativePath, pak->pakFilename.c_str(), GetFileChecksum( file ) ); + } + CloseFile( file ); + } + } + } + } + if ( fs_debug.GetBool() ) { + common->Printf( "no pak file found for '%s' checksumed %x\n", relativePath, findChecksum ); + } + return NULL; +} + +/* +================= +idFileSystemLocal::GetFileChecksum +================= +*/ +int idFileSystemLocal::GetFileChecksum( idFile *file ) { + int len, ret; + byte *buf; + + file->Seek( 0, FS_SEEK_END ); + len = file->Tell(); + file->Seek( 0, FS_SEEK_SET ); + buf = (byte *)Mem_Alloc( len ); + if ( file->Read( buf, len ) != len ) { + common->FatalError( "Short read in idFileSystemLocal::GetFileChecksum()\n" ); + } + ret = MD4_BlockChecksum( buf, len ); + Mem_Free( buf ); + return ret; +} + +/* +================= +idFileSystemLocal::FindDLL +================= +*/ +void idFileSystemLocal::FindDLL( const char *name, char _dllPath[ MAX_OSPATH ], bool updateChecksum ) { + idFile *dllFile = NULL; + char dllName[MAX_OSPATH]; + idStr dllPath; + int dllHash; + pack_t *inPak; + pack_t *pak; + fileInPack_t *pakFile; + + sys->DLL_GetFileName( name, dllName, MAX_OSPATH ); + dllHash = HashFileName( dllName ); + +#if ID_FAKE_PURE + if ( 1 ) { +#else + if ( !serverPaks.Num() ) { +#endif + // from executable directory first - this is handy for developement + dllPath = Sys_EXEPath( ); + dllPath.StripFilename( ); + dllPath.AppendPath( dllName ); + dllFile = OpenExplicitFileRead( dllPath ); + } + if ( !dllFile ) { + if ( !serverPaks.Num() ) { + // not running in pure mode, try to extract from a pak file first + dllFile = OpenFileReadFlags( dllName, FSFLAG_SEARCH_PAKS | FSFLAG_PURE_NOREF | FSFLAG_BINARY_ONLY, &inPak ); + if ( dllFile ) { + common->Printf( "found DLL in pak file: %s\n", dllFile->GetFullPath() ); + dllPath = RelativePathToOSPath( dllName, "fs_savepath" ); + CopyFile( dllFile, dllPath ); + CloseFile( dllFile ); + dllFile = OpenFileReadFlags( dllName, FSFLAG_SEARCH_DIRS ); + if ( !dllFile ) { + common->Error( "DLL extraction to fs_savepath failed\n" ); + } else if ( updateChecksum ) { + gameDLLChecksum = GetFileChecksum( dllFile ); + gamePakChecksum = inPak->checksum; + updateChecksum = false; // don't try again below + } + } else { + // didn't find a source in a pak file, try in the directory + dllFile = OpenFileReadFlags( dllName, FSFLAG_SEARCH_DIRS ); + if ( dllFile ) { + if ( updateChecksum ) { + gameDLLChecksum = GetFileChecksum( dllFile ); + // see if we can mark a pak file + pak = FindPakForFileChecksum( dllName, gameDLLChecksum, false ); + pak ? gamePakChecksum = pak->checksum : gamePakChecksum = 0; + updateChecksum = false; + } + } + } + } else { + // we are in pure mode. this path to be reached only for game DLL situations + // with a code pak checksum given by server + assert( gamePakChecksum ); + assert( updateChecksum ); + pak = GetPackForChecksum( gamePakChecksum ); + if ( !pak ) { + // not supposed to happen, bug in pure code? + common->Warning( "FindDLL in pure mode: game pak not found ( 0x%x )\n", gamePakChecksum ); + } else { + // extract and copy + for ( pakFile = pak->hashTable[dllHash]; pakFile; pakFile = pakFile->next ) { + if ( !FilenameCompare( pakFile->name, dllName ) ) { + dllFile = ReadFileFromZip( pak, pakFile, dllName ); + common->Printf( "found DLL in game pak file: %s\n", pak->pakFilename.c_str() ); + dllPath = RelativePathToOSPath( dllName, "fs_savepath" ); + CopyFile( dllFile, dllPath ); + CloseFile( dllFile ); + dllFile = OpenFileReadFlags( dllName, FSFLAG_SEARCH_DIRS ); + if ( !dllFile ) { + common->Error( "DLL extraction to fs_savepath failed\n" ); + } else { + gameDLLChecksum = GetFileChecksum( dllFile ); + updateChecksum = false; // don't try again below + } + } + } + } + } + } + if ( updateChecksum ) { + if ( dllFile ) { + gameDLLChecksum = GetFileChecksum( dllFile ); + } else { + gameDLLChecksum = 0; + } + gamePakChecksum = 0; + } + if ( dllFile ) { + dllPath = dllFile->GetFullPath( ); + CloseFile( dllFile ); + dllFile = NULL; + } else { + dllPath = ""; + } + idStr::snPrintf( _dllPath, MAX_OSPATH, dllPath.c_str() ); +} + +/* +================ +idFileSystemLocal::ClearDirCache +================ +*/ +void idFileSystemLocal::ClearDirCache( void ) { + int i; + + dir_cache_index = 0; + dir_cache_count = 0; + for( i = 0; i < MAX_CACHED_DIRS; i++ ) { + dir_cache[ i ].Clear(); + } +} + +/* +=============== +idFileSystemLocal::HasD3XP +=============== +*/ +bool idFileSystemLocal::HasD3XP( void ) { + int i; + idStrList dirs, pk4s; + idStr gamepath; + + if ( d3xp == -1 ) { + return false; + } else if ( d3xp == 1 ) { + return true; + } + +#if 0 + // check for a d3xp directory with a pk4 file + // copied over from ListMods - only looks in basepath + ListOSFiles( fs_basepath.GetString(), "/", dirs ); + for ( i = 0; i < dirs.Num(); i++ ) { + if ( dirs[i].Icmp( "d3xp" ) == 0 ) { + gamepath = BuildOSPath( fs_basepath.GetString(), dirs[ i ], "" ); + ListOSFiles( gamepath, ".pk4", pk4s ); + if ( pk4s.Num() ) { + d3xp = 1; + return true; + } + } + } +#elif ID_ALLOW_D3XP + // check for d3xp's d3xp/pak000.pk4 in any search path + // checking wether the pak is loaded by checksum wouldn't be enough: + // we may have a different fs_game right now but still need to reply that it's installed + const char *search[4]; + idFile *pakfile; + search[0] = fs_savepath.GetString(); + search[1] = fs_devpath.GetString(); + search[2] = fs_basepath.GetString(); + search[3] = fs_cdpath.GetString(); + for ( i = 0; i < 4; i++ ) { + pakfile = OpenExplicitFileRead( BuildOSPath( search[ i ], "d3xp", "pak000.pk4" ) ); + if ( pakfile ) { + CloseFile( pakfile ); + d3xp = 1; + return true; + } + } +#endif + +#if ID_ALLOW_D3XP + // if we didn't find a pk4 file then the user might have unpacked so look for default.cfg file + // that's the old way mostly used during developement. don't think it hurts to leave it there + ListOSFiles( fs_basepath.GetString(), "/", dirs ); + for ( i = 0; i < dirs.Num(); i++ ) { + if ( dirs[i].Icmp( "d3xp" ) == 0 ) { + + gamepath = BuildOSPath( fs_savepath.GetString(), dirs[ i ], "default.cfg" ); + idFile* cfg = OpenExplicitFileRead(gamepath); + if(cfg) { + CloseFile(cfg); + d3xp = 1; + return true; + } + } + } +#endif + d3xp = -1; + return false; +} + +/* +=============== +idFileSystemLocal::RunningD3XP +=============== +*/ +bool idFileSystemLocal::RunningD3XP( void ) { + // TODO: mark the checksum of the gold XP and check for it being referenced ( for double mod support ) + // a simple fs_game check should be enough for now.. + if ( !idStr::Icmp( fs_game.GetString(), "d3xp" ) || + !idStr::Icmp( fs_game_base.GetString(), "d3xp" ) ) { + return true; + } + return false; +} + +/* +=============== +idFileSystemLocal::MakeTemporaryFile +=============== +*/ +idFile * idFileSystemLocal::MakeTemporaryFile( void ) { + FILE *f = tmpfile(); + if ( !f ) { + common->Warning( "idFileSystem::MakeTemporaryFile failed: %s", strerror( errno ) ); + return NULL; + } + idFile_Permanent *file = new idFile_Permanent(); + file->o = f; + file->name = ""; + file->fullPath = ""; + file->mode = ( 1 << FS_READ ) + ( 1 << FS_WRITE ); + file->fileSize = 0; + return file; +} + +/* +=============== +idFileSystemLocal::FindFile +=============== +*/ + findFile_t idFileSystemLocal::FindFile( const char *path, bool scheduleAddons ) { + pack_t *pak; + idFile *f = OpenFileReadFlags( path, FSFLAG_SEARCH_DIRS | FSFLAG_SEARCH_PAKS | FSFLAG_SEARCH_ADDONS, &pak ); + if ( !f ) { + return FIND_NO; + } + if ( !pak ) { + // found in FS, not even in paks + return FIND_YES; + } + // marking addons for inclusion on reload - may need to do that even when already in the search path + if ( scheduleAddons && pak->addon && addonChecksums.FindIndex( pak->checksum ) < 0 ) { + addonChecksums.Append( pak->checksum ); + } + // an addon that's not on search list yet? that will require a restart + if ( pak->addon && !pak->addon_search ) { + delete f; + return FIND_ADDON; + } + delete f; + return FIND_YES; +} + +/* +=============== +idFileSystemLocal::GetNumMaps +account for actual decls and for addon maps +=============== +*/ +int idFileSystemLocal::GetNumMaps() { + int i; + searchpath_t *search = NULL; + int ret = declManager->GetNumDecls( DECL_MAPDEF ); + + // add to this all addon decls - coming from all addon packs ( searched or not ) + for ( i = 0; i < 2; i++ ) { + if ( i == 0 ) { + search = searchPaths; + } else if ( i == 1 ) { + search = addonPaks; + } + for ( ; search ; search = search->next ) { + if ( !search->pack || !search->pack->addon || !search->pack->addon_info ) { + continue; + } + ret += search->pack->addon_info->mapDecls.Num(); + } + } + return ret; +} + +/* +=============== +idFileSystemLocal::GetMapDecl +retrieve the decl dictionary, add a 'path' value +=============== +*/ +const idDict * idFileSystemLocal::GetMapDecl( int idecl ) { + int i; + const idDecl *mapDecl; + const idDeclEntityDef *mapDef; + int numdecls = declManager->GetNumDecls( DECL_MAPDEF ); + searchpath_t *search = NULL; + + if ( idecl < numdecls ) { + mapDecl = declManager->DeclByIndex( DECL_MAPDEF, idecl ); + mapDef = static_cast( mapDecl ); + if ( !mapDef ) { + common->Error( "idFileSystemLocal::GetMapDecl %d: not found\n", idecl ); + } + mapDict = mapDef->dict; + mapDict.Set( "path", mapDef->GetName() ); + return &mapDict; + } + idecl -= numdecls; + for ( i = 0; i < 2; i++ ) { + if ( i == 0 ) { + search = searchPaths; + } else if ( i == 1 ) { + search = addonPaks; + } + for ( ; search ; search = search->next ) { + if ( !search->pack || !search->pack->addon || !search->pack->addon_info ) { + continue; + } + // each addon may have a bunch of map decls + if ( idecl < search->pack->addon_info->mapDecls.Num() ) { + mapDict = *search->pack->addon_info->mapDecls[ idecl ]; + return &mapDict; + } + idecl -= search->pack->addon_info->mapDecls.Num(); + assert( idecl >= 0 ); + } + } + return NULL; +} + +/* +=============== +idFileSystemLocal::FindMapScreenshot +=============== +*/ +void idFileSystemLocal::FindMapScreenshot( const char *path, char *buf, int len ) { + idFile *file; + idStr mapname = path; + + mapname.StripPath(); + mapname.StripFileExtension(); + + idStr::snPrintf( buf, len, "guis/assets/splash/%s.tga", mapname.c_str() ); + if ( ReadFile( buf, NULL, NULL ) == -1 ) { + // try to extract from an addon + file = OpenFileReadFlags( buf, FSFLAG_SEARCH_ADDONS ); + if ( file ) { + // save it out to an addon splash directory + int dlen = file->Length(); + char *data = new char[ dlen ]; + file->Read( data, dlen ); + CloseFile( file ); + idStr::snPrintf( buf, len, "guis/assets/splash/addon/%s.tga", mapname.c_str() ); + WriteFile( buf, data, dlen ); + delete[] data; + } else { + idStr::Copynz( buf, "guis/assets/splash/pdtempa", len ); + } + } +} diff --git a/framework/FileSystem.h b/framework/FileSystem.h new file mode 100644 index 000000000..3ab8f0d9e --- /dev/null +++ b/framework/FileSystem.h @@ -0,0 +1,280 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FILESYSTEM_H__ +#define __FILESYSTEM_H__ + +/* +=============================================================================== + + File System + + No stdio calls should be used by any part of the game, because of all sorts + of directory and separator char issues. Throughout the game a forward slash + should be used as a separator. The file system takes care of the conversion + to an OS specific separator. The file system treats all file and directory + names as case insensitive. + + The following cvars store paths used by the file system: + + "fs_basepath" path to local install, read-only + "fs_savepath" path to config, save game, etc. files, read & write + "fs_cdpath" path to cd, read-only + "fs_devpath" path to files created during development, read & write + + The base path for file saving can be set to "fs_savepath" or "fs_devpath". + +=============================================================================== +*/ + +static const ID_TIME_T FILE_NOT_FOUND_TIMESTAMP = 0xFFFFFFFF; +static const int MAX_PURE_PAKS = 128; +static const int MAX_OSPATH = 256; + +// modes for OpenFileByMode. used as bit mask internally +typedef enum { + FS_READ = 0, + FS_WRITE = 1, + FS_APPEND = 2 +} fsMode_t; + +typedef enum { + PURE_OK, // we are good to connect as-is + PURE_RESTART, // restart required + PURE_MISSING, // pak files missing on the client + PURE_NODLL // no DLL could be extracted +} fsPureReply_t; + +typedef enum { + DLTYPE_URL, + DLTYPE_FILE +} dlType_t; + +typedef enum { + DL_WAIT, // waiting in the list for beginning of the download + DL_INPROGRESS, // in progress + DL_DONE, // download completed, success + DL_ABORTING, // this one can be set during a download, it will force the next progress callback to abort - then will go to DL_FAILED + DL_FAILED +} dlStatus_t; + +typedef enum { + FILE_EXEC, + FILE_OPEN +} dlMime_t; + +typedef enum { + FIND_NO, + FIND_YES, + FIND_ADDON +} findFile_t; + +typedef struct urlDownload_s { + idStr url; + char dlerror[ MAX_STRING_CHARS ]; + int dltotal; + int dlnow; + int dlstatus; + dlStatus_t status; +} urlDownload_t; + +typedef struct fileDownload_s { + int position; + int length; + void * buffer; +} fileDownload_t; + +typedef struct backgroundDownload_s { + struct backgroundDownload_s *next; // set by the fileSystem + dlType_t opcode; + idFile * f; + fileDownload_t file; + urlDownload_t url; + volatile bool completed; +} backgroundDownload_t; + +// file list for directory listings +class idFileList { + friend class idFileSystemLocal; +public: + const char * GetBasePath( void ) const { return basePath; } + int GetNumFiles( void ) const { return list.Num(); } + const char * GetFile( int index ) const { return list[index]; } + const idStrList & GetList( void ) const { return list; } + +private: + idStr basePath; + idStrList list; +}; + +// mod list +class idModList { + friend class idFileSystemLocal; +public: + int GetNumMods( void ) const { return mods.Num(); } + const char * GetMod( int index ) const { return mods[index]; } + const char * GetDescription( int index ) const { return descriptions[index]; } + +private: + idStrList mods; + idStrList descriptions; +}; + +class idFileSystem { +public: + virtual ~idFileSystem() {} + // Initializes the file system. + virtual void Init( void ) = 0; + // Restarts the file system. + virtual void Restart( void ) = 0; + // Shutdown the file system. + virtual void Shutdown( bool reloading ) = 0; + // Returns true if the file system is initialized. + virtual bool IsInitialized( void ) const = 0; + // Returns true if we are doing an fs_copyfiles. + virtual bool PerformingCopyFiles( void ) const = 0; + // Returns a list of mods found along with descriptions + // 'mods' contains the directory names to be passed to fs_game + // 'descriptions' contains a free form string to be used in the UI + virtual idModList * ListMods( void ) = 0; + // Frees the given mod list + virtual void FreeModList( idModList *modList ) = 0; + // Lists files with the given extension in the given directory. + // Directory should not have either a leading or trailing '/' + // The returned files will not include any directories or '/' unless fullRelativePath is set. + // The extension must include a leading dot and may not contain wildcards. + // If extension is "/", only subdirectories will be returned. + virtual idFileList * ListFiles( const char *relativePath, const char *extension, bool sort = false, bool fullRelativePath = false, const char* gamedir = NULL ) = 0; + // Lists files in the given directory and all subdirectories with the given extension. + // Directory should not have either a leading or trailing '/' + // The returned files include a full relative path. + // The extension must include a leading dot and may not contain wildcards. + virtual idFileList * ListFilesTree( const char *relativePath, const char *extension, bool sort = false, const char* gamedir = NULL ) = 0; + // Frees the given file list. + virtual void FreeFileList( idFileList *fileList ) = 0; + // Converts a relative path to a full OS path. + virtual const char * OSPathToRelativePath( const char *OSPath ) = 0; + // Converts a full OS path to a relative path. + virtual const char * RelativePathToOSPath( const char *relativePath, const char *basePath = "fs_devpath" ) = 0; + // Builds a full OS path from the given components. + virtual const char * BuildOSPath( const char *base, const char *game, const char *relativePath ) = 0; + // Creates the given OS path for as far as it doesn't exist already. + virtual void CreateOSPath( const char *OSPath ) = 0; + // Returns true if a file is in a pak file. + virtual bool FileIsInPAK( const char *relativePath ) = 0; + // Returns a space separated string containing the checksums of all referenced pak files. + // will call SetPureServerChecksums internally to restrict itself + virtual void UpdatePureServerChecksums( void ) = 0; + // setup the mapping of OS -> game pak checksum + virtual bool UpdateGamePakChecksums( void ) = 0; + // 0-terminated list of pak checksums + // if pureChecksums[ 0 ] == 0, all data sources will be allowed + // otherwise, only pak files that match one of the checksums will be checked for files + // with the sole exception of .cfg files. + // the function tries to configure pure mode from the paks already referenced and this new list + // it returns wether the switch was successfull, and sets the missing checksums + // the process is verbosive when fs_debug 1 + virtual fsPureReply_t SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum, int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum ) = 0; + // fills a 0-terminated list of pak checksums for a client + // if OS is -1, give the current game pak checksum. if >= 0, lookup the game pak table (server only) + virtual void GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int *gamePakChecksum ) = 0; + // before doing a restart, force the pure list and the search order + // if the given checksum list can't be completely processed and set, will error out + virtual void SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ) = 0; + // equivalent to calling SetPureServerChecksums with an empty list + virtual void ClearPureChecksums( void ) = 0; + // get a mask of supported OSes. if not pure, returns -1 + virtual int GetOSMask( void ) = 0; + // Reads a complete file. + // Returns the length of the file, or -1 on failure. + // A null buffer will just return the file length without loading. + // A null timestamp will be ignored. + // As a quick check for existance. -1 length == not present. + // A 0 byte will always be appended at the end, so string ops are safe. + // The buffer should be considered read-only, because it may be cached for other uses. + virtual int ReadFile( const char *relativePath, void **buffer, ID_TIME_T *timestamp = NULL ) = 0; + // Frees the memory allocated by ReadFile. + virtual void FreeFile( void *buffer ) = 0; + // Writes a complete file, will create any needed subdirectories. + // Returns the length of the file, or -1 on failure. + virtual int WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath = "fs_savepath" ) = 0; + // Removes the given file. + virtual void RemoveFile( const char *relativePath ) = 0; + // Opens a file for reading. + virtual idFile * OpenFileRead( const char *relativePath, bool allowCopyFiles = true, const char* gamedir = NULL ) = 0; + // Opens a file for writing, will create any needed subdirectories. + virtual idFile * OpenFileWrite( const char *relativePath, const char *basePath = "fs_savepath" ) = 0; + // Opens a file for writing at the end. + virtual idFile * OpenFileAppend( const char *filename, bool sync = false, const char *basePath = "fs_basepath" ) = 0; + // Opens a file for reading, writing, or appending depending on the value of mode. + virtual idFile * OpenFileByMode( const char *relativePath, fsMode_t mode ) = 0; + // Opens a file for reading from a full OS path. + virtual idFile * OpenExplicitFileRead( const char *OSPath ) = 0; + // Opens a file for writing to a full OS path. + virtual idFile * OpenExplicitFileWrite( const char *OSPath ) = 0; + // Closes a file. + virtual void CloseFile( idFile *f ) = 0; + // Returns immediately, performing the read from a background thread. + virtual void BackgroundDownload( backgroundDownload_t *bgl ) = 0; + // resets the bytes read counter + virtual void ResetReadCount( void ) = 0; + // retrieves the current read count + virtual int GetReadCount( void ) = 0; + // adds to the read count + virtual void AddToReadCount( int c ) = 0; + // look for a dynamic module + virtual void FindDLL( const char *basename, char dllPath[ MAX_OSPATH ], bool updateChecksum ) = 0; + // case sensitive filesystems use an internal directory cache + // the cache is cleared when calling OpenFileWrite and RemoveFile + // in some cases you may need to use this directly + virtual void ClearDirCache( void ) = 0; + + // is D3XP installed? even if not running it atm + virtual bool HasD3XP( void ) = 0; + // are we using D3XP content ( through a real d3xp run or through a double mod ) + virtual bool RunningD3XP( void ) = 0; + + // don't use for large copies - allocates a single memory block for the copy + virtual void CopyFile( const char *fromOSPath, const char *toOSPath ) = 0; + + // lookup a relative path, return the size or 0 if not found + virtual int ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isGamePak ) = 0; + + virtual idFile * MakeTemporaryFile( void ) = 0; + + // make downloaded pak files known so pure negociation works next time + virtual int AddZipFile( const char *path ) = 0; + + // look for a file in the loaded paks or the addon paks + // if the file is found in addons, FS's internal structures are ready for a reloadEngine + virtual findFile_t FindFile( const char *path, bool scheduleAddons = false ) = 0; + + // get map/addon decls and take into account addon paks that are not on the search list + // the decl 'name' is in the "path" entry of the dict + virtual int GetNumMaps() = 0; + virtual const idDict * GetMapDecl( int i ) = 0; + virtual void FindMapScreenshot( const char *path, char *buf, int len ) = 0; + + // ignore case and seperator char distinctions + virtual bool FilenameCompare( const char *s1, const char *s2 ) const = 0; +}; + +extern idFileSystem * fileSystem; + +#endif /* !__FILESYSTEM_H__ */ diff --git a/framework/KeyInput.cpp b/framework/KeyInput.cpp new file mode 100644 index 000000000..45572514c --- /dev/null +++ b/framework/KeyInput.cpp @@ -0,0 +1,776 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +typedef struct { + char *name; + int keynum; + char *strId; // localized string id +} keyname_t; + +// keys that can be set without a special name +static const char unnamedkeys[] = "*,-=./[\\]1234567890abcdefghijklmnopqrstuvwxyz"; + +#if MACOS_X +const char* OSX_GetLocalizedString( const char* ); +#endif + +// names not in this list can either be lowercase ascii, or '0xnn' hex sequences +keyname_t keynames[] = +{ + {"TAB", K_TAB, "#str_07018"}, + {"ENTER", K_ENTER, "#str_07019"}, + {"ESCAPE", K_ESCAPE, "#str_07020"}, + {"SPACE", K_SPACE, "#str_07021"}, + {"BACKSPACE", K_BACKSPACE, "#str_07022"}, + {"UPARROW", K_UPARROW, "#str_07023"}, + {"DOWNARROW", K_DOWNARROW, "#str_07024"}, + {"LEFTARROW", K_LEFTARROW, "#str_07025"}, + {"RIGHTARROW", K_RIGHTARROW, "#str_07026"}, + + {"ALT", K_ALT, "#str_07027"}, + {"RIGHTALT", K_RIGHT_ALT, "#str_07027"}, + {"CTRL", K_CTRL, "#str_07028"}, + {"SHIFT", K_SHIFT, "#str_07029"}, + + {"LWIN", K_LWIN, "#str_07030"}, + {"RWIN", K_RWIN, "#str_07031"}, + {"MENU", K_MENU, "#str_07032"}, + + {"COMMAND", K_COMMAND, "#str_07033"}, + + {"CAPSLOCK", K_CAPSLOCK, "#str_07034"}, + {"SCROLL", K_SCROLL, "#str_07035"}, + {"PRINTSCREEN", K_PRINT_SCR, "#str_07179"}, + + {"F1", K_F1, "#str_07036"}, + {"F2", K_F2, "#str_07037"}, + {"F3", K_F3, "#str_07038"}, + {"F4", K_F4, "#str_07039"}, + {"F5", K_F5, "#str_07040"}, + {"F6", K_F6, "#str_07041"}, + {"F7", K_F7, "#str_07042"}, + {"F8", K_F8, "#str_07043"}, + {"F9", K_F9, "#str_07044"}, + {"F10", K_F10, "#str_07045"}, + {"F11", K_F11, "#str_07046"}, + {"F12", K_F12, "#str_07047"}, + + {"INS", K_INS, "#str_07048"}, + {"DEL", K_DEL, "#str_07049"}, + {"PGDN", K_PGDN, "#str_07050"}, + {"PGUP", K_PGUP, "#str_07051"}, + {"HOME", K_HOME, "#str_07052"}, + {"END", K_END, "#str_07053"}, + + {"MOUSE1", K_MOUSE1, "#str_07054"}, + {"MOUSE2", K_MOUSE2, "#str_07055"}, + {"MOUSE3", K_MOUSE3, "#str_07056"}, + {"MOUSE4", K_MOUSE4, "#str_07057"}, + {"MOUSE5", K_MOUSE5, "#str_07058"}, + {"MOUSE6", K_MOUSE6, "#str_07059"}, + {"MOUSE7", K_MOUSE7, "#str_07060"}, + {"MOUSE8", K_MOUSE8, "#str_07061"}, + + {"MWHEELUP", K_MWHEELUP, "#str_07131"}, + {"MWHEELDOWN", K_MWHEELDOWN, "#str_07132"}, + + {"JOY1", K_JOY1, "#str_07062"}, + {"JOY2", K_JOY2, "#str_07063"}, + {"JOY3", K_JOY3, "#str_07064"}, + {"JOY4", K_JOY4, "#str_07065"}, + {"JOY5", K_JOY5, "#str_07066"}, + {"JOY6", K_JOY6, "#str_07067"}, + {"JOY7", K_JOY7, "#str_07068"}, + {"JOY8", K_JOY8, "#str_07069"}, + {"JOY9", K_JOY9, "#str_07070"}, + {"JOY10", K_JOY10, "#str_07071"}, + {"JOY11", K_JOY11, "#str_07072"}, + {"JOY12", K_JOY12, "#str_07073"}, + {"JOY13", K_JOY13, "#str_07074"}, + {"JOY14", K_JOY14, "#str_07075"}, + {"JOY15", K_JOY15, "#str_07076"}, + {"JOY16", K_JOY16, "#str_07077"}, + {"JOY17", K_JOY17, "#str_07078"}, + {"JOY18", K_JOY18, "#str_07079"}, + {"JOY19", K_JOY19, "#str_07080"}, + {"JOY20", K_JOY20, "#str_07081"}, + {"JOY21", K_JOY21, "#str_07082"}, + {"JOY22", K_JOY22, "#str_07083"}, + {"JOY23", K_JOY23, "#str_07084"}, + {"JOY24", K_JOY24, "#str_07085"}, + {"JOY25", K_JOY25, "#str_07086"}, + {"JOY26", K_JOY26, "#str_07087"}, + {"JOY27", K_JOY27, "#str_07088"}, + {"JOY28", K_JOY28, "#str_07089"}, + {"JOY29", K_JOY29, "#str_07090"}, + {"JOY30", K_JOY30, "#str_07091"}, + {"JOY31", K_JOY31, "#str_07092"}, + {"JOY32", K_JOY32, "#str_07093"}, + + {"AUX1", K_AUX1, "#str_07094"}, + {"AUX2", K_AUX2, "#str_07095"}, + {"AUX3", K_AUX3, "#str_07096"}, + {"AUX4", K_AUX4, "#str_07097"}, + {"AUX5", K_AUX5, "#str_07098"}, + {"AUX6", K_AUX6, "#str_07099"}, + {"AUX7", K_AUX7, "#str_07100"}, + {"AUX8", K_AUX8, "#str_07101"}, + {"AUX9", K_AUX9, "#str_07102"}, + {"AUX10", K_AUX10, "#str_07103"}, + {"AUX11", K_AUX11, "#str_07104"}, + {"AUX12", K_AUX12, "#str_07105"}, + {"AUX13", K_AUX13, "#str_07106"}, + {"AUX14", K_AUX14, "#str_07107"}, + {"AUX15", K_AUX15, "#str_07108"}, + {"AUX16", K_AUX16, "#str_07109"}, + + {"KP_HOME", K_KP_HOME, "#str_07110"}, + {"KP_UPARROW", K_KP_UPARROW, "#str_07111"}, + {"KP_PGUP", K_KP_PGUP, "#str_07112"}, + {"KP_LEFTARROW", K_KP_LEFTARROW, "#str_07113"}, + {"KP_5", K_KP_5, "#str_07114"}, + {"KP_RIGHTARROW", K_KP_RIGHTARROW, "#str_07115"}, + {"KP_END", K_KP_END, "#str_07116"}, + {"KP_DOWNARROW", K_KP_DOWNARROW, "#str_07117"}, + {"KP_PGDN", K_KP_PGDN, "#str_07118"}, + {"KP_ENTER", K_KP_ENTER, "#str_07119"}, + {"KP_INS", K_KP_INS, "#str_07120"}, + {"KP_DEL", K_KP_DEL, "#str_07121"}, + {"KP_SLASH", K_KP_SLASH, "#str_07122"}, + {"KP_MINUS", K_KP_MINUS, "#str_07123"}, + {"KP_PLUS", K_KP_PLUS, "#str_07124"}, + {"KP_NUMLOCK", K_KP_NUMLOCK, "#str_07125"}, + {"KP_STAR", K_KP_STAR, "#str_07126"}, + {"KP_EQUALS", K_KP_EQUALS, "#str_07127"}, + + {"PAUSE", K_PAUSE, "#str_07128"}, + + {"SEMICOLON", ';', "#str_07129"}, // because a raw semicolon separates commands + {"APOSTROPHE", '\'', "#str_07130"}, // because a raw apostrophe messes with parsing + + {NULL, 0, NULL} +}; + + + +static const int MAX_KEYS = 256; + +class idKey { +public: + idKey( void ) { down = false; repeats = 0; usercmdAction = 0; } + bool down; + int repeats; // if > 1, it is autorepeating + idStr binding; + int usercmdAction; // for testing by the asyncronous usercmd generation +}; + +bool key_overstrikeMode = false; +idKey * keys = NULL; + +#define ID_DOOM_LEGACY + +#ifdef ID_DOOM_LEGACY + +char * cheatCodes[] = { + "iddqd", // Invincibility + "idkfa", // All weapons, keys, ammo, and 200% armor + "idfa", // Reset ammunition + "idspispopd", // Walk through walls + "idclip", // Walk through walls + "idchoppers", // Chainsaw +/* + "idbeholds", // Berserker strength + "idbeholdv", // Temporary invincibility + "idbeholdi", // Temporary invisibility + "idbeholda", // Full automap + "idbeholdr", // Anti-radiation suit + "idbeholdl", // Light amplification visor + "idclev", // Level select + "iddt", // Toggle full map; full map and objects; normal map + "idmypos", // Display coordinates and heading + "idmus", // Change music to indicated level + "fhhall", // Kill all enemies in level + "fhshh", // Invisible to enemies until attack +*/ + NULL +}; +char lastKeys[32]; +int lastKeyIndex; + +#endif + +/* +=================== +idKeyInput::ArgCompletion_KeyName +=================== +*/ +void idKeyInput::ArgCompletion_KeyName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + keyname_t *kn; + int i; + + for( i = 0; i < sizeof( unnamedkeys ) - 1; i++ ) { + callback( va( "%s %c", args.Argv( 0 ), unnamedkeys[ i ] ) ); + } + + for ( kn = keynames; kn->name; kn++ ) { + callback( va( "%s %s", args.Argv( 0 ), kn->name ) ); + } +} + +/* +=================== +idKeyInput::GetOverstrikeMode +=================== +*/ +bool idKeyInput::GetOverstrikeMode( void ) { + return key_overstrikeMode; +} + +/* +=================== +idKeyInput::SetOverstrikeMode +=================== +*/ +void idKeyInput::SetOverstrikeMode( bool state ) { + key_overstrikeMode = state; +} + +/* +=================== +idKeyInput::IsDown +=================== +*/ +bool idKeyInput::IsDown( int keynum ) { + if ( keynum == -1 ) { + return false; + } + + return keys[keynum].down; +} + +/* +=================== +idKeyInput::StringToKeyNum + +Returns a key number to be used to index keys[] by looking at +the given string. Single ascii characters return themselves, while +the K_* names are matched up. + +0x11 will be interpreted as raw hex, which will allow new controlers +to be configured even if they don't have defined names. +=================== +*/ +int idKeyInput::StringToKeyNum( const char *str ) { + keyname_t *kn; + + if ( !str || !str[0] ) { + return -1; + } + if ( !str[1] ) { + return (unsigned char)(str[0]); + } + + // check for hex code + if ( str[0] == '0' && str[1] == 'x' && strlen( str ) == 4 ) { + int n1, n2; + + n1 = str[2]; + if ( n1 >= '0' && n1 <= '9' ) { + n1 -= '0'; + } else if ( n1 >= 'a' && n1 <= 'f' ) { + n1 = n1 - 'a' + 10; + } else { + n1 = 0; + } + + n2 = str[3]; + if ( n2 >= '0' && n2 <= '9' ) { + n2 -= '0'; + } else if ( n2 >= 'a' && n2 <= 'f' ) { + n2 = n2 - 'a' + 10; + } else { + n2 = 0; + } + + return n1 * 16 + n2; + } + + // scan for a text match + for ( kn = keynames; kn->name; kn++ ) { + if ( !idStr::Icmp( str, kn->name ) ) { + return kn->keynum; + } + } + + return -1; +} + +/* +=================== +idKeyInput::KeyNumToString + +Returns a string (either a single ascii char, a K_* name, or a 0x11 hex string) for the +given keynum. +=================== +*/ +const char *idKeyInput::KeyNumToString( int keynum, bool localized ) { + keyname_t *kn; + static char tinystr[5]; + int i, j; + + if ( keynum == -1 ) { + return ""; + } + + if ( keynum < 0 || keynum > 255 ) { + return ""; + } + + // check for printable ascii (don't use quote) + if ( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != '\'' ) { + tinystr[0] = Sys_MapCharForKey( keynum ); + tinystr[1] = 0; + return tinystr; + } + + // check for a key string + for ( kn = keynames; kn->name; kn++ ) { + if ( keynum == kn->keynum ) { + if ( !localized || kn->strId[0] != '#' ) { + return kn->name; + } else { +#if MACOS_X + + switch ( kn->keynum ) { + case K_ENTER: + case K_BACKSPACE: + case K_ALT: + case K_INS: + case K_PRINT_SCR: + return OSX_GetLocalizedString( kn->name ); + break; + default : + return common->GetLanguageDict()->GetString( kn->strId ); break; + } +#else + return common->GetLanguageDict()->GetString( kn->strId ); +#endif + } + } + } + + // check for European high-ASCII characters + if ( localized && keynum >= 161 && keynum <= 255 ) { + tinystr[0] = keynum; + tinystr[1] = 0; + return tinystr; + } + + // make a hex string + i = keynum >> 4; + j = keynum & 15; + + tinystr[0] = '0'; + tinystr[1] = 'x'; + tinystr[2] = i > 9 ? i - 10 + 'a' : i + '0'; + tinystr[3] = j > 9 ? j - 10 + 'a' : j + '0'; + tinystr[4] = 0; + + return tinystr; +} + +/* +=================== +idKeyInput::SetBinding +=================== +*/ +void idKeyInput::SetBinding( int keynum, const char *binding ) { + if ( keynum == -1 ) { + return; + } + + // Clear out all button states so we aren't stuck forever thinking this key is held down + usercmdGen->Clear(); + + // allocate memory for new binding + keys[keynum].binding = binding; + + // find the action for the async command generation + keys[keynum].usercmdAction = usercmdGen->CommandStringUsercmdData( binding ); + + // consider this like modifying an archived cvar, so the + // file write will be triggered at the next oportunity + cvarSystem->SetModifiedFlags( CVAR_ARCHIVE ); +} + + +/* +=================== +idKeyInput::GetBinding +=================== +*/ +const char *idKeyInput::GetBinding( int keynum ) { + if ( keynum == -1 ) { + return ""; + } + + return keys[ keynum ].binding; +} + +/* +=================== +idKeyInput::GetUsercmdAction +=================== +*/ +int idKeyInput::GetUsercmdAction( int keynum ) { + return keys[ keynum ].usercmdAction; +} + +/* +=================== +Key_Unbind_f +=================== +*/ +void Key_Unbind_f( const idCmdArgs &args ) { + int b; + + if ( args.Argc() != 2 ) { + common->Printf( "unbind : remove commands from a key\n" ); + return; + } + + b = idKeyInput::StringToKeyNum( args.Argv(1) ); + if ( b == -1 ) { + // If it wasn't a key, it could be a command + if ( !idKeyInput::UnbindBinding( args.Argv(1) ) ) { + common->Printf( "\"%s\" isn't a valid key\n", args.Argv(1) ); + } + } else { + idKeyInput::SetBinding( b, "" ); + } +} + +/* +=================== +Key_Unbindall_f +=================== +*/ +void Key_Unbindall_f( const idCmdArgs &args ) { + int i; + + for ( i = 0; i < MAX_KEYS; i++ ) { + idKeyInput::SetBinding( i, "" ); + } +} + +/* +=================== +Key_Bind_f +=================== +*/ +void Key_Bind_f( const idCmdArgs &args ) { + int i, c, b; + char cmd[MAX_STRING_CHARS]; + + c = args.Argc(); + + if ( c < 2 ) { + common->Printf( "bind [command] : attach a command to a key\n" ); + return; + } + b = idKeyInput::StringToKeyNum( args.Argv(1) ); + if ( b == -1 ) { + common->Printf( "\"%s\" isn't a valid key\n", args.Argv(1) ); + return; + } + + if ( c == 2 ) { + if ( keys[b].binding.Length() ) { + common->Printf( "\"%s\" = \"%s\"\n", args.Argv(1), keys[b].binding.c_str() ); + } + else { + common->Printf( "\"%s\" is not bound\n", args.Argv(1) ); + } + return; + } + + // copy the rest of the command line + cmd[0] = 0; // start out with a null string + for ( i = 2; i < c; i++ ) { + strcat( cmd, args.Argv( i ) ); + if ( i != (c-1) ) { + strcat( cmd, " " ); + } + } + + idKeyInput::SetBinding( b, cmd ); +} + +/* +============ +Key_BindUnBindTwo_f + +binds keynum to bindcommand and unbinds if there are already two binds on the key +============ +*/ +void Key_BindUnBindTwo_f( const idCmdArgs &args ) { + int c = args.Argc(); + if ( c < 3 ) { + common->Printf( "bindunbindtwo [command]\n" ); + return; + } + int key = atoi( args.Argv( 1 ) ); + idStr bind = args.Argv( 2 ); + if ( idKeyInput::NumBinds( bind ) >= 2 && !idKeyInput::KeyIsBoundTo( key, bind ) ) { + idKeyInput::UnbindBinding( bind ); + } + idKeyInput::SetBinding( key, bind ); +} + + + +/* +============ +idKeyInput::WriteBindings + +Writes lines containing "bind key value" +============ +*/ +void idKeyInput::WriteBindings( idFile *f ) { + int i; + + f->Printf( "unbindall\n" ); + + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].binding.Length() ) { + const char *name = KeyNumToString( i, false ); + + // handle the escape character nicely + if ( !strcmp( name, "\\" ) ) { + f->Printf( "bind \"\\\" \"%s\"\n", keys[i].binding.c_str() ); + } else { + f->Printf( "bind \"%s\" \"%s\"\n", KeyNumToString( i, false ), keys[i].binding.c_str() ); + } + } + } +} + +/* +============ +Key_ListBinds_f +============ +*/ +void Key_ListBinds_f( const idCmdArgs &args ) { + int i; + + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].binding.Length() ) { + common->Printf( "%s \"%s\"\n", idKeyInput::KeyNumToString( i, false ), keys[i].binding.c_str() ); + } + } +} + +/* +============ +idKeyInput::KeysFromBinding +returns the localized name of the key for the binding +============ +*/ +const char *idKeyInput::KeysFromBinding( const char *bind ) { + int i; + static char keyName[MAX_STRING_CHARS]; + + keyName[0] = '\0'; + if ( bind && *bind ) { + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].binding.Icmp( bind ) == 0 ) { + if ( keyName[0] != '\0' ) { + idStr::Append( keyName, sizeof( keyName ), common->GetLanguageDict()->GetString( "#str_07183" ) ); + } + idStr::Append( keyName, sizeof( keyName ), KeyNumToString( i, true ) ); + } + } + } + if ( keyName[0] == '\0' ) { + idStr::Copynz( keyName, common->GetLanguageDict()->GetString( "#str_07133" ), sizeof( keyName ) ); + } + idStr::ToLower( keyName ); + return keyName; +} + +/* +============ +idKeyInput::BindingFromKey +returns the binding for the localized name of the key +============ +*/ +const char *idKeyInput::BindingFromKey( const char *key ) { + const int keyNum = idKeyInput::StringToKeyNum( key ); + if ( keyNum<0 || keyNum >= MAX_KEYS ) { + return NULL; + } + return keys[keyNum].binding.c_str(); +} + +/* +============ +idKeyInput::UnbindBinding +============ +*/ +bool idKeyInput::UnbindBinding( const char *binding ) { + bool unbound = false; + int i; + + if ( binding && *binding ) { + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].binding.Icmp( binding ) == 0 ) { + SetBinding( i, "" ); + unbound = true; + } + } + } + return unbound; +} + +/* +============ +idKeyInput::NumBinds +============ +*/ +int idKeyInput::NumBinds( const char *binding ) { + int i, count = 0; + + if ( binding && *binding ) { + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].binding.Icmp( binding ) == 0 ) { + count++; + } + } + } + return count; +} + +/* +============ +idKeyInput::KeyIsBountTo +============ +*/ +bool idKeyInput::KeyIsBoundTo( int keynum, const char *binding ) { + if ( keynum >= 0 && keynum < MAX_KEYS ) { + return ( keys[keynum].binding.Icmp( binding ) == 0 ); + } + return false; +} + +/* +=================== +idKeyInput::PreliminaryKeyEvent + +Tracks global key up/down state +Called by the system for both key up and key down events +=================== +*/ +void idKeyInput::PreliminaryKeyEvent( int keynum, bool down ) { + keys[keynum].down = down; + +#ifdef ID_DOOM_LEGACY + if ( down ) { + lastKeys[ 0 + ( lastKeyIndex & 15 )] = keynum; + lastKeys[16 + ( lastKeyIndex & 15 )] = keynum; + lastKeyIndex = ( lastKeyIndex + 1 ) & 15; + for ( int i = 0; cheatCodes[i] != NULL; i++ ) { + int l = strlen( cheatCodes[i] ); + assert( l <= 16 ); + if ( idStr::Icmpn( lastKeys + 16 + ( lastKeyIndex & 15 ) - l, cheatCodes[i], l ) == 0 ) { + common->Printf( "your memory serves you well!\n" ); + break; + } + } + } +#endif +} + +/* +================= +idKeyInput::ExecKeyBinding +================= +*/ +bool idKeyInput::ExecKeyBinding( int keynum ) { + // commands that are used by the async thread + // don't add text + if ( keys[keynum].usercmdAction ) { + return false; + } + + // send the bound action + if ( keys[keynum].binding.Length() ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, keys[keynum].binding.c_str() ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" ); + } + return true; +} + +/* +=================== +idKeyInput::ClearStates +=================== +*/ +void idKeyInput::ClearStates( void ) { + int i; + + for ( i = 0; i < MAX_KEYS; i++ ) { + if ( keys[i].down ) { + PreliminaryKeyEvent( i, false ); + } + keys[i].down = false; + } + + // clear the usercommand states + usercmdGen->Clear(); +} + +/* +=================== +idKeyInput::Init +=================== +*/ +void idKeyInput::Init( void ) { + + keys = new idKey[MAX_KEYS]; + + // register our functions + cmdSystem->AddCommand( "bind", Key_Bind_f, CMD_FL_SYSTEM, "binds a command to a key", idKeyInput::ArgCompletion_KeyName ); + cmdSystem->AddCommand( "bindunbindtwo", Key_BindUnBindTwo_f, CMD_FL_SYSTEM, "binds a key but unbinds it first if there are more than two binds" ); + cmdSystem->AddCommand( "unbind", Key_Unbind_f, CMD_FL_SYSTEM, "unbinds any command from a key", idKeyInput::ArgCompletion_KeyName ); + cmdSystem->AddCommand( "unbindall", Key_Unbindall_f, CMD_FL_SYSTEM, "unbinds any commands from all keys" ); + cmdSystem->AddCommand( "listBinds", Key_ListBinds_f, CMD_FL_SYSTEM, "lists key bindings" ); +} + +/* +=================== +idKeyInput::Shutdown +=================== +*/ +void idKeyInput::Shutdown( void ) { + delete [] keys; + keys = NULL; +} diff --git a/framework/KeyInput.h b/framework/KeyInput.h new file mode 100644 index 000000000..e036df6bd --- /dev/null +++ b/framework/KeyInput.h @@ -0,0 +1,212 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __KEYINPUT_H__ +#define __KEYINPUT_H__ + +/* +=============================================================================== + + Key Input + +=============================================================================== +*/ + +// these are the key numbers that are used by the key system +// normal keys should be passed as lowercased ascii +// Some high ascii (> 127) characters that are mapped directly to keys on +// western european keyboards are inserted in this table so that those keys +// are bindable (otherwise they get bound as one of the special keys in this +// table) +typedef enum { + K_TAB = 9, + K_ENTER = 13, + K_ESCAPE = 27, + K_SPACE = 32, + + K_BACKSPACE = 127, + + K_COMMAND = 128, + K_CAPSLOCK, + K_SCROLL, + K_POWER, + K_PAUSE, + + K_UPARROW = 133, + K_DOWNARROW, + K_LEFTARROW, + K_RIGHTARROW, + + // The 3 windows keys + K_LWIN = 137, + K_RWIN, + K_MENU, + + K_ALT = 140, + K_CTRL, + K_SHIFT, + K_INS, + K_DEL, + K_PGDN, + K_PGUP, + K_HOME, + K_END, + + K_F1 = 149, + K_F2, + K_F3, + K_F4, + K_F5, + K_F6, + K_F7, + K_F8, + K_F9, + K_F10, + K_F11, + K_F12, + K_INVERTED_EXCLAMATION = 161, // upside down ! + K_F13, + K_F14, + K_F15, + + K_KP_HOME = 165, + K_KP_UPARROW, + K_KP_PGUP, + K_KP_LEFTARROW, + K_KP_5, + K_KP_RIGHTARROW, + K_KP_END, + K_KP_DOWNARROW, + K_KP_PGDN, + K_KP_ENTER, + K_KP_INS, + K_KP_DEL, + K_KP_SLASH, + K_SUPERSCRIPT_TWO = 178, // superscript 2 + K_KP_MINUS, + K_ACUTE_ACCENT = 180, // accute accent + K_KP_PLUS, + K_KP_NUMLOCK, + K_KP_STAR, + K_KP_EQUALS, + + K_MASCULINE_ORDINATOR = 186, + // K_MOUSE enums must be contiguous (no char codes in the middle) + K_MOUSE1 = 187, + K_MOUSE2, + K_MOUSE3, + K_MOUSE4, + K_MOUSE5, + K_MOUSE6, + K_MOUSE7, + K_MOUSE8, + + K_MWHEELDOWN = 195, + K_MWHEELUP, + + K_JOY1 = 197, + K_JOY2, + K_JOY3, + K_JOY4, + K_JOY5, + K_JOY6, + K_JOY7, + K_JOY8, + K_JOY9, + K_JOY10, + K_JOY11, + K_JOY12, + K_JOY13, + K_JOY14, + K_JOY15, + K_JOY16, + K_JOY17, + K_JOY18, + K_JOY19, + K_JOY20, + K_JOY21, + K_JOY22, + K_JOY23, + K_JOY24, + K_JOY25, + K_JOY26, + K_JOY27, + K_GRAVE_A = 224, // lowercase a with grave accent + K_JOY28, + K_JOY29, + K_JOY30, + K_JOY31, + K_JOY32, + + K_AUX1 = 230, + K_CEDILLA_C = 231, // lowercase c with Cedilla + K_GRAVE_E = 232, // lowercase e with grave accent + K_AUX2, + K_AUX3, + K_AUX4, + K_GRAVE_I = 236, // lowercase i with grave accent + K_AUX5, + K_AUX6, + K_AUX7, + K_AUX8, + K_TILDE_N = 241, // lowercase n with tilde + K_GRAVE_O = 242, // lowercase o with grave accent + K_AUX9, + K_AUX10, + K_AUX11, + K_AUX12, + K_AUX13, + K_AUX14, + K_GRAVE_U = 249, // lowercase u with grave accent + K_AUX15, + K_AUX16, + + K_PRINT_SCR = 252, // SysRq / PrintScr + K_RIGHT_ALT = 253, // used by some languages as "Alt-Gr" + K_LAST_KEY = 254 // this better be < 256! +} keyNum_t; + + +class idKeyInput { +public: + static void Init( void ); + static void Shutdown( void ); + + static void ArgCompletion_KeyName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void PreliminaryKeyEvent( int keyNum, bool down ); + static bool IsDown( int keyNum ); + static int GetUsercmdAction( int keyNum ); + static bool GetOverstrikeMode( void ); + static void SetOverstrikeMode( bool state ); + static void ClearStates( void ); + static int StringToKeyNum( const char *str ); + static const char * KeyNumToString( int keyNum, bool localized ); + + static void SetBinding( int keyNum, const char *binding ); + static const char * GetBinding( int keyNum ); + static bool UnbindBinding( const char *bind ); + static int NumBinds( const char *binding ); + static bool ExecKeyBinding( int keyNum ); + static const char * KeysFromBinding( const char *bind ); + static const char * BindingFromKey( const char *key ); + static bool KeyIsBoundTo( int keyNum, const char *binding ); + static void WriteBindings( idFile *f ); +}; + +#endif /* !__KEYINPUT_H__ */ diff --git a/framework/Licensee.h b/framework/Licensee.h new file mode 100644 index 000000000..8d486526e --- /dev/null +++ b/framework/Licensee.h @@ -0,0 +1,106 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Definitions for information that is related to a licensee's game name and location. + +=============================================================================== +*/ + +#define GAME_NAME "DOOM 3" // appears on window titles and errors + +#define ENGINE_VERSION "DOOM 1.3.1" // printed in console + +// paths +#define CD_BASEDIR "Doom" +#ifdef ID_DEMO_BUILD + #define BASE_GAMEDIR "demo" +#else + #define BASE_GAMEDIR "base" +#endif + +// filenames +#define CD_EXE "doom.exe" +#define CONFIG_FILE "DoomConfig.cfg" + +// base folder where the source code lives +#define SOURCE_CODE_BASE_FOLDER "neo" + + +// default idnet host address +#ifndef IDNET_HOST + #define IDNET_HOST "idnet.ua-corp.com" +#endif + +// default idnet master port +#ifndef IDNET_MASTER_PORT + #define IDNET_MASTER_PORT "27650" +#endif + +// default network server port +#ifndef PORT_SERVER + #define PORT_SERVER 27666 +#endif + +// broadcast scan this many ports after PORT_SERVER so a single machine can run multiple servers +#define NUM_SERVER_PORTS 4 + +// see ASYNC_PROTOCOL_VERSION +// use a different major for each game +#define ASYNC_PROTOCOL_MAJOR 1 + +// Savegame Version +// Update when you can no longer maintain compatibility with previous savegames +// NOTE: a seperate core savegame version and game savegame version could be useful +// 16: Doom v1.1 +// 17: Doom v1.2 / D3XP. Can still read old v16 with defaults for new data +#define SAVEGAME_VERSION 17 + +// <= Doom v1.1: 1. no DS_VERSION token ( default ) +// Doom v1.2: 2 +#define RENDERDEMO_VERSION 2 + +// editor info +#define EDITOR_DEFAULT_PROJECT "doom.qe4" +#define EDITOR_REGISTRY_KEY "DOOMRadiant" +#define EDITOR_WINDOWTEXT "DOOMEdit" + +// win32 info +#define WIN32_CONSOLE_CLASS "DOOM 3 WinConsole" +#define WIN32_WINDOW_CLASS_NAME "DOOM3" +#define WIN32_FAKE_WINDOW_CLASS_NAME "DOOM3_WGL_FAKE" + +// Linux info +#ifdef ID_DEMO_BUILD + #define LINUX_DEFAULT_PATH "/usr/local/games/doom3-demo" +#else + #define LINUX_DEFAULT_PATH "/usr/local/games/doom3" +#endif + +// CD Key file info +// goes into BASE_GAMEDIR whatever the fs_game is set to +// two distinct files for easier win32 installer job +#define CDKEY_FILE "doomkey" +#define XPKEY_FILE "xpkey" +#define CDKEY_TEXT "\n// Do not give this file to ANYONE.\n" \ + "// id Software or Zenimax will NEVER ask you to send this file to them.\n" + +#define CONFIG_SPEC "config.spec" diff --git a/framework/Session.cpp b/framework/Session.cpp new file mode 100644 index 000000000..09035d0f4 --- /dev/null +++ b/framework/Session.cpp @@ -0,0 +1,3315 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Session_local.h" + +idCVar idSessionLocal::com_showAngles( "com_showAngles", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar idSessionLocal::com_minTics( "com_minTics", "1", CVAR_SYSTEM, "" ); +idCVar idSessionLocal::com_showTics( "com_showTics", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar idSessionLocal::com_fixedTic( "com_fixedTic", "0", CVAR_SYSTEM | CVAR_INTEGER, "", 0, 10 ); +idCVar idSessionLocal::com_showDemo( "com_showDemo", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar idSessionLocal::com_skipGameDraw( "com_skipGameDraw", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar idSessionLocal::com_aviDemoSamples( "com_aviDemoSamples", "16", CVAR_SYSTEM, "" ); +idCVar idSessionLocal::com_aviDemoWidth( "com_aviDemoWidth", "256", CVAR_SYSTEM, "" ); +idCVar idSessionLocal::com_aviDemoHeight( "com_aviDemoHeight", "256", CVAR_SYSTEM, "" ); +idCVar idSessionLocal::com_aviDemoTics( "com_aviDemoTics", "2", CVAR_SYSTEM | CVAR_INTEGER, "", 1, 60 ); +idCVar idSessionLocal::com_wipeSeconds( "com_wipeSeconds", "1", CVAR_SYSTEM, "" ); +idCVar idSessionLocal::com_guid( "com_guid", "", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_ROM, "" ); + +idSessionLocal sessLocal; +idSession *session = &sessLocal; + +// these must be kept up to date with window Levelshot in guis/mainmenu.gui +const int PREVIEW_X = 211; +const int PREVIEW_Y = 31; +const int PREVIEW_WIDTH = 398; +const int PREVIEW_HEIGHT = 298; + +void RandomizeStack( void ) { + // attempt to force uninitialized stack memory bugs + int bytes = 4000000; + byte *buf = (byte *)_alloca( bytes ); + + int fill = rand()&255; + for ( int i = 0 ; i < bytes ; i++ ) { + buf[i] = fill; + } +} + +/* +================= +Session_RescanSI_f +================= +*/ +void Session_RescanSI_f( const idCmdArgs &args ) { + sessLocal.mapSpawnData.serverInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + if ( game && idAsyncNetwork::server.IsActive() ) { + game->SetServerInfo( sessLocal.mapSpawnData.serverInfo ); + } +} + +/* +================== +Session_Map_f + +Restart the server on a different map +================== +*/ +static void Session_Map_f( const idCmdArgs &args ) { + idStr map, string; + findFile_t ff; + idCmdArgs rl_args; + + map = args.Argv(1); + if ( !map.Length() ) { + return; + } + map.StripFileExtension(); + + // make sure the level exists before trying to change, so that + // a typo at the server console won't end the game + // handle addon packs through reloadEngine + sprintf( string, "maps/%s.map", map.c_str() ); + ff = fileSystem->FindFile( string, true ); + switch ( ff ) { + case FIND_NO: + common->Printf( "Can't find map %s\n", string.c_str() ); + return; + case FIND_ADDON: + common->Printf( "map %s is in an addon pak - reloading\n", string.c_str() ); + rl_args.AppendArg( "map" ); + rl_args.AppendArg( map ); + cmdSystem->SetupReloadEngine( rl_args ); + return; + default: + break; + } + + cvarSystem->SetCVarBool( "developer", false ); + sessLocal.StartNewGame( map, true ); +} + +/* +================== +Session_DevMap_f + +Restart the server on a different map in developer mode +================== +*/ +static void Session_DevMap_f( const idCmdArgs &args ) { + idStr map, string; + findFile_t ff; + idCmdArgs rl_args; + + map = args.Argv(1); + if ( !map.Length() ) { + return; + } + map.StripFileExtension(); + + // make sure the level exists before trying to change, so that + // a typo at the server console won't end the game + // handle addon packs through reloadEngine + sprintf( string, "maps/%s.map", map.c_str() ); + ff = fileSystem->FindFile( string, true ); + switch ( ff ) { + case FIND_NO: + common->Printf( "Can't find map %s\n", string.c_str() ); + return; + case FIND_ADDON: + common->Printf( "map %s is in an addon pak - reloading\n", string.c_str() ); + rl_args.AppendArg( "devmap" ); + rl_args.AppendArg( map ); + cmdSystem->SetupReloadEngine( rl_args ); + return; + default: + break; + } + + cvarSystem->SetCVarBool( "developer", true ); + sessLocal.StartNewGame( map, true ); +} + +/* +================== +Session_TestMap_f +================== +*/ +static void Session_TestMap_f( const idCmdArgs &args ) { + idStr map, string; + + map = args.Argv(1); + if ( !map.Length() ) { + return; + } + map.StripFileExtension(); + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + + sprintf( string, "dmap maps/%s.map", map.c_str() ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, string ); + + sprintf( string, "devmap %s", map.c_str() ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, string ); +} + +/* +================== +Sess_WritePrecache_f +================== +*/ +static void Sess_WritePrecache_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Printf( "USAGE: writePrecache \n" ); + return; + } + idStr str = args.Argv(1); + str.DefaultFileExtension( ".cfg" ); + idFile *f = fileSystem->OpenFileWrite( str ); + declManager->WritePrecacheCommands( f ); + renderModelManager->WritePrecacheCommands( f ); + uiManager->WritePrecacheCommands( f ); + + fileSystem->CloseFile( f ); +} + +/* +=============== +idSessionLocal::MaybeWaitOnCDKey +=============== +*/ +bool idSessionLocal::MaybeWaitOnCDKey( void ) { + if ( authEmitTimeout > 0 ) { + authWaitBox = true; + sessLocal.MessageBox( MSG_WAIT, common->GetLanguageDict()->GetString( "#str_07191" ), NULL, true, NULL, NULL, true ); + return true; + } + return false; +} + +/* +=================== +Session_PromptKey_f +=================== +*/ +static void Session_PromptKey_f( const idCmdArgs &args ) { + const char *retkey; + bool valid[ 2 ]; + static bool recursed = false; + + if ( recursed ) { + common->Warning( "promptKey recursed - aborted" ); + return; + } + recursed = true; + + do { + // in case we're already waiting for an auth to come back to us ( may happen exceptionally ) + if ( sessLocal.MaybeWaitOnCDKey() ) { + if ( sessLocal.CDKeysAreValid( true ) ) { + recursed = false; + return; + } + } + // the auth server may have replied and set an error message, otherwise use a default + const char *prompt_msg = sessLocal.GetAuthMsg(); + if ( prompt_msg[ 0 ] == '\0' ) { + prompt_msg = common->GetLanguageDict()->GetString( "#str_04308" ); + } + retkey = sessLocal.MessageBox( MSG_CDKEY, prompt_msg, common->GetLanguageDict()->GetString( "#str_04305" ), true, NULL, NULL, true ); + if ( retkey ) { + if ( sessLocal.CheckKey( retkey, false, valid ) ) { + // if all went right, then we may have sent an auth request to the master ( unless the prompt is used during a net connect ) + bool canExit = true; + if ( sessLocal.MaybeWaitOnCDKey() ) { + // wait on auth reply, and got denied, prompt again + if ( !sessLocal.CDKeysAreValid( true ) ) { + // server says key is invalid - MaybeWaitOnCDKey was interrupted by a CDKeysAuthReply call, which has set the right error message + // the invalid keys have also been cleared in the process + sessLocal.MessageBox( MSG_OK, sessLocal.GetAuthMsg(), common->GetLanguageDict()->GetString( "#str_04310" ), true, NULL, NULL, true ); + canExit = false; + } + } + if ( canExit ) { + // make sure that's saved on file + sessLocal.WriteCDKey(); + sessLocal.MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04307" ), common->GetLanguageDict()->GetString( "#str_04305" ), true, NULL, NULL, true ); + break; + } + } else { + // offline check sees key invalid + // build a message about keys being wrong. do not attempt to change the current key state though + // ( the keys may be valid, but user would have clicked on the dialog anyway, that kind of thing ) + idStr msg; + idAsyncNetwork::BuildInvalidKeyMsg( msg, valid ); + sessLocal.MessageBox( MSG_OK, msg, common->GetLanguageDict()->GetString( "#str_04310" ), true, NULL, NULL, true ); + } + } else if ( args.Argc() == 2 && idStr::Icmp( args.Argv(1), "force" ) == 0 ) { + // cancelled in force mode + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + cmdSystem->ExecuteCommandBuffer(); + } + } while ( retkey ); + recursed = false; +} + +/* +=============================================================================== + +SESSION LOCAL + +=============================================================================== +*/ + +/* +=============== +idSessionLocal::Clear +=============== +*/ +void idSessionLocal::Clear() { + + insideUpdateScreen = false; + insideExecuteMapChange = false; + + loadingSaveGame = false; + savegameFile = NULL; + savegameVersion = 0; + + currentMapName.Clear(); + aviDemoShortName.Clear(); + msgFireBack[ 0 ].Clear(); + msgFireBack[ 1 ].Clear(); + + timeHitch = 0; + + rw = NULL; + sw = NULL; + menuSoundWorld = NULL; + readDemo = NULL; + writeDemo = NULL; + renderdemoVersion = 0; + cmdDemoFile = NULL; + + syncNextGameFrame = false; + mapSpawned = false; + guiActive = NULL; + aviCaptureMode = false; + timeDemo = TD_NO; + waitingOnBind = false; + lastPacifierTime = 0; + + msgRunning = false; + guiMsgRestore = NULL; + msgIgnoreButtons = false; + + bytesNeededForMapLoad = 0; + +#if ID_CONSOLE_LOCK + emptyDrawCount = 0; +#endif + ClearWipe(); + + loadGameList.Clear(); + modsList.Clear(); + + authEmitTimeout = 0; + authWaitBox = false; + + authMsg.Clear(); +} + +/* +=============== +idSessionLocal::idSessionLocal +=============== +*/ +idSessionLocal::idSessionLocal() { + guiInGame = guiMainMenu = guiIntro \ + = guiRestartMenu = guiLoading = guiGameOver = guiActive \ + = guiTest = guiMsg = guiMsgRestore = guiTakeNotes = NULL; + + menuSoundWorld = NULL; + + Clear(); +} + +/* +=============== +idSessionLocal::~idSessionLocal +=============== +*/ +idSessionLocal::~idSessionLocal() { +} + +/* +=============== +idSessionLocal::Stop + +called on errors and game exits +=============== +*/ +void idSessionLocal::Stop() { + ClearWipe(); + + // clear mapSpawned and demo playing flags + UnloadMap(); + + // disconnect async client + idAsyncNetwork::client.DisconnectFromServer(); + + // kill async server + idAsyncNetwork::server.Kill(); + + if ( sw ) { + sw->StopAllSounds(); + } + + insideUpdateScreen = false; + insideExecuteMapChange = false; + + // drop all guis + SetGUI( NULL, NULL ); +} + +/* +=============== +idSessionLocal::Shutdown +=============== +*/ +void idSessionLocal::Shutdown() { + int i; + + if ( aviCaptureMode ) { + EndAVICapture(); + } + + Stop(); + + if ( rw ) { + delete rw; + rw = NULL; + } + + if ( sw ) { + delete sw; + sw = NULL; + } + + if ( menuSoundWorld ) { + delete menuSoundWorld; + menuSoundWorld = NULL; + } + + mapSpawnData.serverInfo.Clear(); + mapSpawnData.syncedCVars.Clear(); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + mapSpawnData.userInfo[i].Clear(); + mapSpawnData.persistentPlayerInfo[i].Clear(); + } + + if ( guiMainMenu_MapList != NULL ) { + guiMainMenu_MapList->Shutdown(); + uiManager->FreeListGUI( guiMainMenu_MapList ); + guiMainMenu_MapList = NULL; + } + + Clear(); +} + +/* +=============== +idSessionLocal::IsMultiplayer +=============== +*/ +bool idSessionLocal::IsMultiplayer() { + return idAsyncNetwork::IsActive(); +} + +/* +================ +idSessionLocal::StartWipe + +Draws and captures the current state, then starts a wipe with that image +================ +*/ +void idSessionLocal::StartWipe( const char *_wipeMaterial, bool hold ) { + console->Close(); + + // render the current screen into a texture for the wipe model + renderSystem->CropRenderSize( 640, 480, true ); + + Draw(); + + renderSystem->CaptureRenderToImage( "_scratch"); + renderSystem->UnCrop(); + + wipeMaterial = declManager->FindMaterial( _wipeMaterial, false ); + + wipeStartTic = com_ticNumber; + wipeStopTic = wipeStartTic + 1000.0f / USERCMD_MSEC * com_wipeSeconds.GetFloat(); + wipeHold = hold; +} + +/* +================ +idSessionLocal::CompleteWipe +================ +*/ +void idSessionLocal::CompleteWipe() { + if ( com_ticNumber == 0 ) { + // if the async thread hasn't started, we would hang here + wipeStopTic = 0; + UpdateScreen( true ); + return; + } + while ( com_ticNumber < wipeStopTic ) { +#if ID_CONSOLE_LOCK + emptyDrawCount = 0; +#endif + UpdateScreen( true ); + } +} + +/* +================ +idSessionLocal::ShowLoadingGui +================ +*/ +void idSessionLocal::ShowLoadingGui() { + if ( com_ticNumber == 0 ) { + return; + } + console->Close(); + + // introduced in D3XP code. don't think it actually fixes anything, but doesn't hurt either +#if 1 + // Try and prevent the while loop from being skipped over (long hitch on the main thread?) + int stop = Sys_Milliseconds() + 1000; + int force = 10; + while ( Sys_Milliseconds() < stop || force-- > 0 ) { + com_frameTime = com_ticNumber * USERCMD_MSEC; + session->Frame(); + session->UpdateScreen( false ); + } +#else + int stop = com_ticNumber + 1000.0f / USERCMD_MSEC * 1.0f; + while ( com_ticNumber < stop ) { + com_frameTime = com_ticNumber * USERCMD_MSEC; + session->Frame(); + session->UpdateScreen( false ); + } +#endif +} + + + +/* +================ +idSessionLocal::ClearWipe +================ +*/ +void idSessionLocal::ClearWipe( void ) { + wipeHold = false; + wipeStopTic = 0; + wipeStartTic = wipeStopTic + 1; +} + +/* +================ +Session_TestGUI_f +================ +*/ +static void Session_TestGUI_f( const idCmdArgs &args ) { + sessLocal.TestGUI( args.Argv(1) ); +} + +/* +================ +idSessionLocal::TestGUI +================ +*/ +void idSessionLocal::TestGUI( const char *guiName ) { + if ( guiName && *guiName ) { + guiTest = uiManager->FindGui( guiName, true, false, true ); + } else { + guiTest = NULL; + } +} + +/* +================ +FindUnusedFileName +================ +*/ +static idStr FindUnusedFileName( const char *format ) { + int i; + char filename[1024]; + + for ( i = 0 ; i < 999 ; i++ ) { + sprintf( filename, format, i ); + int len = fileSystem->ReadFile( filename, NULL, NULL ); + if ( len <= 0 ) { + return filename; // file doesn't exist + } + } + + return filename; +} + +/* +================ +Session_DemoShot_f +================ +*/ +static void Session_DemoShot_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + idStr filename = FindUnusedFileName( "demos/shot%03i.demo" ); + sessLocal.DemoShot( filename ); + } else { + sessLocal.DemoShot( va( "demos/shot_%s.demo", args.Argv(1) ) ); + } +} + +/* +================ +Session_RecordDemo_f +================ +*/ +static void Session_RecordDemo_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + idStr filename = FindUnusedFileName( "demos/demo%03i.demo" ); + sessLocal.StartRecordingRenderDemo( filename ); + } else { + sessLocal.StartRecordingRenderDemo( va( "demos/%s.demo", args.Argv(1) ) ); + } +} + +/* +================ +Session_CompressDemo_f +================ +*/ +static void Session_CompressDemo_f( const idCmdArgs &args ) { + if ( args.Argc() == 2 ) { + sessLocal.CompressDemoFile( "2", args.Argv(1) ); + } else if ( args.Argc() == 3 ) { + sessLocal.CompressDemoFile( args.Argv(2), args.Argv(1) ); + } else { + common->Printf("use: CompressDemo [scheme]\nscheme is the same as com_compressDemo, defaults to 2" ); + } +} + +/* +================ +Session_StopRecordingDemo_f +================ +*/ +static void Session_StopRecordingDemo_f( const idCmdArgs &args ) { + sessLocal.StopRecordingRenderDemo(); +} + +/* +================ +Session_PlayDemo_f +================ +*/ +static void Session_PlayDemo_f( const idCmdArgs &args ) { + if ( args.Argc() >= 2 ) { + sessLocal.StartPlayingRenderDemo( va( "demos/%s", args.Argv(1) ) ); + } +} + +/* +================ +Session_TimeDemo_f +================ +*/ +static void Session_TimeDemo_f( const idCmdArgs &args ) { + if ( args.Argc() >= 2 ) { + sessLocal.TimeRenderDemo( va( "demos/%s", args.Argv(1) ), ( args.Argc() > 2 ) ); + } +} + +/* +================ +Session_TimeDemoQuit_f +================ +*/ +static void Session_TimeDemoQuit_f( const idCmdArgs &args ) { + sessLocal.TimeRenderDemo( va( "demos/%s", args.Argv(1) ) ); + if ( sessLocal.timeDemo == TD_YES ) { + // this allows hardware vendors to automate some testing + sessLocal.timeDemo = TD_YES_THEN_QUIT; + } +} + +/* +================ +Session_AVIDemo_f +================ +*/ +static void Session_AVIDemo_f( const idCmdArgs &args ) { + sessLocal.AVIRenderDemo( va( "demos/%s", args.Argv(1) ) ); +} + +/* +================ +Session_AVIGame_f +================ +*/ +static void Session_AVIGame_f( const idCmdArgs &args ) { + sessLocal.AVIGame( args.Argv(1) ); +} + +/* +================ +Session_AVICmdDemo_f +================ +*/ +static void Session_AVICmdDemo_f( const idCmdArgs &args ) { + sessLocal.AVICmdDemo( args.Argv(1) ); +} + +/* +================ +Session_WriteCmdDemo_f +================ +*/ +static void Session_WriteCmdDemo_f( const idCmdArgs &args ) { + if ( args.Argc() == 1 ) { + idStr filename = FindUnusedFileName( "demos/cmdDemo%03i.cdemo" ); + sessLocal.WriteCmdDemo( filename ); + } else if ( args.Argc() == 2 ) { + sessLocal.WriteCmdDemo( va( "demos/%s.cdemo", args.Argv( 1 ) ) ); + } else { + common->Printf( "usage: writeCmdDemo [demoName]\n" ); + } +} + +/* +================ +Session_PlayCmdDemo_f +================ +*/ +static void Session_PlayCmdDemo_f( const idCmdArgs &args ) { + sessLocal.StartPlayingCmdDemo( args.Argv(1) ); +} + +/* +================ +Session_TimeCmdDemo_f +================ +*/ +static void Session_TimeCmdDemo_f( const idCmdArgs &args ) { + sessLocal.TimeCmdDemo( args.Argv(1) ); +} + +/* +================ +Session_Disconnect_f +================ +*/ +static void Session_Disconnect_f( const idCmdArgs &args ) { + sessLocal.Stop(); + sessLocal.StartMenu(); + if ( soundSystem ) { + soundSystem->SetMute( false ); + } +} + +#ifdef ID_DEMO_BUILD +/* +================ +Session_EndOfDemo_f +================ +*/ +static void Session_EndOfDemo_f( const idCmdArgs &args ) { + sessLocal.Stop(); + sessLocal.StartMenu(); + if ( soundSystem ) { + soundSystem->SetMute( false ); + } + if ( sessLocal.guiActive ) { + sessLocal.guiActive->HandleNamedEvent( "endOfDemo" ); + } +} +#endif + +/* +================ +Session_ExitCmdDemo_f +================ +*/ +static void Session_ExitCmdDemo_f( const idCmdArgs &args ) { + if ( !sessLocal.cmdDemoFile ) { + common->Printf( "not reading from a cmdDemo\n" ); + return; + } + fileSystem->CloseFile( sessLocal.cmdDemoFile ); + common->Printf( "Command demo exited at logIndex %i\n", sessLocal.logIndex ); + sessLocal.cmdDemoFile = NULL; +} + +/* +================ +idSessionLocal::StartRecordingRenderDemo +================ +*/ +void idSessionLocal::StartRecordingRenderDemo( const char *demoName ) { + if ( writeDemo ) { + // allow it to act like a toggle + StopRecordingRenderDemo(); + return; + } + + if ( !demoName[0] ) { + common->Printf( "idSessionLocal::StartRecordingRenderDemo: no name specified\n" ); + return; + } + + console->Close(); + + writeDemo = new idDemoFile; + if ( !writeDemo->OpenForWriting( demoName ) ) { + common->Printf( "error opening %s\n", demoName ); + delete writeDemo; + writeDemo = NULL; + return; + } + + common->Printf( "recording to %s\n", writeDemo->GetName() ); + + writeDemo->WriteInt( DS_VERSION ); + writeDemo->WriteInt( RENDERDEMO_VERSION ); + + // if we are in a map already, dump the current state + sw->StartWritingDemo( writeDemo ); + rw->StartWritingDemo( writeDemo ); +} + +/* +================ +idSessionLocal::StopRecordingRenderDemo +================ +*/ +void idSessionLocal::StopRecordingRenderDemo() { + if ( !writeDemo ) { + common->Printf( "idSessionLocal::StopRecordingRenderDemo: not recording\n" ); + return; + } + sw->StopWritingDemo(); + rw->StopWritingDemo(); + + writeDemo->Close(); + common->Printf( "stopped recording %s.\n", writeDemo->GetName() ); + delete writeDemo; + writeDemo = NULL; +} + +/* +================ +idSessionLocal::StopPlayingRenderDemo + +Reports timeDemo numbers and finishes any avi recording +================ +*/ +void idSessionLocal::StopPlayingRenderDemo() { + if ( !readDemo ) { + timeDemo = TD_NO; + return; + } + + // Record the stop time before doing anything that could be time consuming + int timeDemoStopTime = Sys_Milliseconds(); + + EndAVICapture(); + + readDemo->Close(); + + sw->StopAllSounds(); + soundSystem->SetPlayingSoundWorld( menuSoundWorld ); + + common->Printf( "stopped playing %s.\n", readDemo->GetName() ); + delete readDemo; + readDemo = NULL; + + if ( timeDemo ) { + // report the stats + float demoSeconds = ( timeDemoStopTime - timeDemoStartTime ) * 0.001f; + float demoFPS = numDemoFrames / demoSeconds; + idStr message = va( "%i frames rendered in %3.1f seconds = %3.1f fps\n", numDemoFrames, demoSeconds, demoFPS ); + + common->Printf( message ); + if ( timeDemo == TD_YES_THEN_QUIT ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + } else { + soundSystem->SetMute( true ); + MessageBox( MSG_OK, message, "Time Demo Results", true ); + soundSystem->SetMute( false ); + } + timeDemo = TD_NO; + } +} + +/* +================ +idSessionLocal::DemoShot + +A demoShot is a single frame demo +================ +*/ +void idSessionLocal::DemoShot( const char *demoName ) { + StartRecordingRenderDemo( demoName ); + + // force draw one frame + UpdateScreen(); + + StopRecordingRenderDemo(); +} + +/* +================ +idSessionLocal::StartPlayingRenderDemo +================ +*/ +void idSessionLocal::StartPlayingRenderDemo( idStr demoName ) { + if ( !demoName[0] ) { + common->Printf( "idSessionLocal::StartPlayingRenderDemo: no name specified\n" ); + return; + } + + // make sure localSound / GUI intro music shuts up + sw->StopAllSounds(); + sw->PlayShaderDirectly( "", 0 ); + menuSoundWorld->StopAllSounds(); + menuSoundWorld->PlayShaderDirectly( "", 0 ); + + // exit any current game + Stop(); + + // automatically put the console away + console->Close(); + + // bring up the loading screen manually, since demos won't + // call ExecuteMapChange() + guiLoading = uiManager->FindGui( "guis/map/loading.gui", true, false, true ); + guiLoading->SetStateString( "demo", common->GetLanguageDict()->GetString( "#str_02087" ) ); + readDemo = new idDemoFile; + demoName.DefaultFileExtension( ".demo" ); + if ( !readDemo->OpenForReading( demoName ) ) { + common->Printf( "couldn't open %s\n", demoName.c_str() ); + delete readDemo; + readDemo = NULL; + Stop(); + StartMenu(); + soundSystem->SetMute( false ); + return; + } + + insideExecuteMapChange = true; + UpdateScreen(); + insideExecuteMapChange = false; + guiLoading->SetStateString( "demo", "" ); + + // setup default render demo settings + // that's default for <= Doom3 v1.1 + renderdemoVersion = 1; + savegameVersion = 16; + + AdvanceRenderDemo( true ); + + numDemoFrames = 1; + + lastDemoTic = -1; + timeDemoStartTime = Sys_Milliseconds(); +} + +/* +================ +idSessionLocal::TimeRenderDemo +================ +*/ +void idSessionLocal::TimeRenderDemo( const char *demoName, bool twice ) { + idStr demo = demoName; + + // no sound in time demos + soundSystem->SetMute( true ); + + StartPlayingRenderDemo( demo ); + + if ( twice && readDemo ) { + // cycle through once to precache everything + guiLoading->SetStateString( "demo", common->GetLanguageDict()->GetString( "#str_04852" ) ); + guiLoading->StateChanged( com_frameTime ); + while ( readDemo ) { + insideExecuteMapChange = true; + UpdateScreen(); + insideExecuteMapChange = false; + AdvanceRenderDemo( true ); + } + guiLoading->SetStateString( "demo", "" ); + StartPlayingRenderDemo( demo ); + } + + + if ( !readDemo ) { + return; + } + + timeDemo = TD_YES; +} + + +/* +================ +idSessionLocal::BeginAVICapture +================ +*/ +void idSessionLocal::BeginAVICapture( const char *demoName ) { + idStr name = demoName; + name.ExtractFileBase( aviDemoShortName ); + aviCaptureMode = true; + aviDemoFrameCount = 0; + aviTicStart = 0; + sw->AVIOpen( va( "demos/%s/", aviDemoShortName.c_str() ), aviDemoShortName.c_str() ); +} + +/* +================ +idSessionLocal::EndAVICapture +================ +*/ +void idSessionLocal::EndAVICapture() { + if ( !aviCaptureMode ) { + return; + } + + sw->AVIClose(); + + // write a .roqParam file so the demo can be converted to a roq file + idFile *f = fileSystem->OpenFileWrite( va( "demos/%s/%s.roqParam", + aviDemoShortName.c_str(), aviDemoShortName.c_str() ) ); + f->Printf( "INPUT_DIR demos/%s\n", aviDemoShortName.c_str() ); + f->Printf( "FILENAME demos/%s/%s.RoQ\n", aviDemoShortName.c_str(), aviDemoShortName.c_str() ); + f->Printf( "\nINPUT\n" ); + f->Printf( "%s_*.tga [00000-%05i]\n", aviDemoShortName.c_str(), (int)( aviDemoFrameCount-1 ) ); + f->Printf( "END_INPUT\n" ); + delete f; + + common->Printf( "captured %i frames for %s.\n", ( int )aviDemoFrameCount, aviDemoShortName.c_str() ); + + aviCaptureMode = false; +} + + +/* +================ +idSessionLocal::AVIRenderDemo +================ +*/ +void idSessionLocal::AVIRenderDemo( const char *_demoName ) { + idStr demoName = _demoName; // copy off from va() buffer + + StartPlayingRenderDemo( demoName ); + if ( !readDemo ) { + return; + } + + BeginAVICapture( demoName.c_str() ) ; + + // I don't understand why I need to do this twice, something + // strange with the nvidia swapbuffers? + UpdateScreen(); +} + +/* +================ +idSessionLocal::AVICmdDemo +================ +*/ +void idSessionLocal::AVICmdDemo( const char *demoName ) { + StartPlayingCmdDemo( demoName ); + + BeginAVICapture( demoName ) ; +} + +/* +================ +idSessionLocal::AVIGame + +Start AVI recording the current game session +================ +*/ +void idSessionLocal::AVIGame( const char *demoName ) { + if ( aviCaptureMode ) { + EndAVICapture(); + return; + } + + if ( !mapSpawned ) { + common->Printf( "No map spawned.\n" ); + } + + if ( !demoName || !demoName[0] ) { + idStr filename = FindUnusedFileName( "demos/game%03i.game" ); + demoName = filename.c_str(); + + // write a one byte stub .game file just so the FindUnusedFileName works, + fileSystem->WriteFile( demoName, demoName, 1 ); + } + + BeginAVICapture( demoName ) ; +} + +/* +================ +idSessionLocal::CompressDemoFile +================ +*/ +void idSessionLocal::CompressDemoFile( const char *scheme, const char *demoName ) { + idStr fullDemoName = "demos/"; + fullDemoName += demoName; + fullDemoName.DefaultFileExtension( ".demo" ); + idStr compressedName = fullDemoName; + compressedName.StripFileExtension(); + compressedName.Append( "_compressed.demo" ); + + int savedCompression = cvarSystem->GetCVarInteger("com_compressDemos"); + bool savedPreload = cvarSystem->GetCVarBool("com_preloadDemos"); + cvarSystem->SetCVarBool( "com_preloadDemos", false ); + cvarSystem->SetCVarInteger("com_compressDemos", atoi(scheme) ); + + idDemoFile demoread, demowrite; + if ( !demoread.OpenForReading( fullDemoName ) ) { + common->Printf( "Could not open %s for reading\n", fullDemoName.c_str() ); + return; + } + if ( !demowrite.OpenForWriting( compressedName ) ) { + common->Printf( "Could not open %s for writing\n", compressedName.c_str() ); + demoread.Close(); + cvarSystem->SetCVarBool( "com_preloadDemos", savedPreload ); + cvarSystem->SetCVarInteger("com_compressDemos", savedCompression); + return; + } + common->SetRefreshOnPrint( true ); + common->Printf( "Compressing %s to %s...\n", fullDemoName.c_str(), compressedName.c_str() ); + + static const int bufferSize = 65535; + char buffer[bufferSize]; + int bytesRead; + while ( 0 != (bytesRead = demoread.Read( buffer, bufferSize ) ) ) { + demowrite.Write( buffer, bytesRead ); + common->Printf( "." ); + } + + demoread.Close(); + demowrite.Close(); + + cvarSystem->SetCVarBool( "com_preloadDemos", savedPreload ); + cvarSystem->SetCVarInteger("com_compressDemos", savedCompression); + + common->Printf( "Done\n" ); + common->SetRefreshOnPrint( false ); + +} + + +/* +=============== +idSessionLocal::StartNewGame +=============== +*/ +void idSessionLocal::StartNewGame( const char *mapName, bool devmap ) { +#ifdef ID_DEDICATED + common->Printf( "Dedicated servers cannot start singleplayer games.\n" ); + return; +#else +#if ID_ENFORCE_KEY + // strict check. don't let a game start without a definitive answer + if ( !CDKeysAreValid( true ) ) { + bool prompt = true; + if ( MaybeWaitOnCDKey() ) { + // check again, maybe we just needed more time + if ( CDKeysAreValid( true ) ) { + // can continue directly + prompt = false; + } + } + if ( prompt ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "promptKey force" ); + cmdSystem->ExecuteCommandBuffer(); + } + } +#endif + if ( idAsyncNetwork::server.IsActive() ) { + common->Printf("Server running, use si_map / serverMapRestart\n"); + return; + } + if ( idAsyncNetwork::client.IsActive() ) { + common->Printf("Client running, disconnect from server first\n"); + return; + } + + // clear the userInfo so the player starts out with the defaults + mapSpawnData.userInfo[0].Clear(); + mapSpawnData.persistentPlayerInfo[0].Clear(); + mapSpawnData.userInfo[0] = *cvarSystem->MoveCVarsToDict( CVAR_USERINFO ); + + mapSpawnData.serverInfo.Clear(); + mapSpawnData.serverInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + mapSpawnData.serverInfo.Set( "si_gameType", "singleplayer" ); + + // set the devmap key so any play testing items will be given at + // spawn time to set approximately the right weapons and ammo + if(devmap) { + mapSpawnData.serverInfo.Set( "devmap", "1" ); + } + + mapSpawnData.syncedCVars.Clear(); + mapSpawnData.syncedCVars = *cvarSystem->MoveCVarsToDict( CVAR_NETWORKSYNC ); + + MoveToNewMap( mapName ); +#endif +} + +/* +=============== +idSessionLocal::GetAutoSaveName +=============== +*/ +idStr idSessionLocal::GetAutoSaveName( const char *mapName ) const { + const idDecl *mapDecl = declManager->FindType( DECL_MAPDEF, mapName, false ); + const idDeclEntityDef *mapDef = static_cast( mapDecl ); + if ( mapDef ) { + mapName = common->GetLanguageDict()->GetString( mapDef->dict.GetString( "name", mapName ) ); + } + // Fixme: Localization + return va( "^3AutoSave:^0 %s", mapName ); +} + +/* +=============== +idSessionLocal::MoveToNewMap + +Leaves the existing userinfo and serverinfo +=============== +*/ +void idSessionLocal::MoveToNewMap( const char *mapName ) { + mapSpawnData.serverInfo.Set( "si_map", mapName ); + + ExecuteMapChange(); + + if ( !mapSpawnData.serverInfo.GetBool("devmap") ) { + // Autosave at the beginning of the level + SaveGame( GetAutoSaveName( mapName ), true ); + } + + SetGUI( NULL, NULL ); +} + +/* +============== +SaveCmdDemoFromFile +============== +*/ +void idSessionLocal::SaveCmdDemoToFile( idFile *file ) { + + mapSpawnData.serverInfo.WriteToFileHandle( file ); + + for ( int i = 0 ; i < MAX_ASYNC_CLIENTS ; i++ ) { + mapSpawnData.userInfo[i].WriteToFileHandle( file ); + mapSpawnData.persistentPlayerInfo[i].WriteToFileHandle( file ); + } + + file->Write( &mapSpawnData.mapSpawnUsercmd, sizeof( mapSpawnData.mapSpawnUsercmd ) ); + + if ( numClients < 1 ) { + numClients = 1; + } + file->Write( loggedUsercmds, numClients * logIndex * sizeof( loggedUsercmds[0] ) ); +} + +/* +============== +idSessionLocal::LoadCmdDemoFromFile +============== +*/ +void idSessionLocal::LoadCmdDemoFromFile( idFile *file ) { + + mapSpawnData.serverInfo.ReadFromFileHandle( file ); + + for ( int i = 0 ; i < MAX_ASYNC_CLIENTS ; i++ ) { + mapSpawnData.userInfo[i].ReadFromFileHandle( file ); + mapSpawnData.persistentPlayerInfo[i].ReadFromFileHandle( file ); + } + file->Read( &mapSpawnData.mapSpawnUsercmd, sizeof( mapSpawnData.mapSpawnUsercmd ) ); +} + +/* +============== +idSessionLocal::WriteCmdDemo + +Dumps the accumulated commands for the current level. +This should still work after disconnecting from a level +============== +*/ +void idSessionLocal::WriteCmdDemo( const char *demoName, bool save ) { + + if ( !demoName[0] ) { + common->Printf( "idSessionLocal::WriteCmdDemo: no name specified\n" ); + return; + } + + idStr statsName; + if (save) { + statsName = demoName; + statsName.StripFileExtension(); + statsName.DefaultFileExtension(".stats"); + } + + common->Printf( "writing save data to %s\n", demoName ); + + idFile *cmdDemoFile = fileSystem->OpenFileWrite( demoName ); + if ( !cmdDemoFile ) { + common->Printf( "Couldn't open for writing %s\n", demoName ); + return; + } + + if ( save ) { + cmdDemoFile->Write( &logIndex, sizeof( logIndex ) ); + } + + SaveCmdDemoToFile( cmdDemoFile ); + + if ( save ) { + idFile *statsFile = fileSystem->OpenFileWrite( statsName ); + if ( statsFile ) { + statsFile->Write( &statIndex, sizeof( statIndex ) ); + statsFile->Write( loggedStats, numClients * statIndex * sizeof( loggedStats[0] ) ); + fileSystem->CloseFile( statsFile ); + } + } + + fileSystem->CloseFile( cmdDemoFile ); +} + +/* +=============== +idSessionLocal::FinishCmdLoad +=============== +*/ +void idSessionLocal::FinishCmdLoad() { +} + +/* +=============== +idSessionLocal::StartPlayingCmdDemo +=============== +*/ +void idSessionLocal::StartPlayingCmdDemo(const char *demoName) { + // exit any current game + Stop(); + + idStr fullDemoName = "demos/"; + fullDemoName += demoName; + fullDemoName.DefaultFileExtension( ".cdemo" ); + cmdDemoFile = fileSystem->OpenFileRead(fullDemoName); + + if ( cmdDemoFile == NULL ) { + common->Printf( "Couldn't open %s\n", fullDemoName.c_str() ); + return; + } + + guiLoading = uiManager->FindGui( "guis/map/loading.gui", true, false, true ); + //cmdDemoFile->Read(&loadGameTime, sizeof(loadGameTime)); + + LoadCmdDemoFromFile(cmdDemoFile); + + // start the map + ExecuteMapChange(); + + cmdDemoFile = fileSystem->OpenFileRead(fullDemoName); + + // have to do this twice as the execmapchange clears the cmddemofile + LoadCmdDemoFromFile(cmdDemoFile); + + // run one frame to get the view angles correct + RunGameTic(); +} + +/* +=============== +idSessionLocal::TimeCmdDemo +=============== +*/ +void idSessionLocal::TimeCmdDemo( const char *demoName ) { + StartPlayingCmdDemo( demoName ); + ClearWipe(); + UpdateScreen(); + + int startTime = Sys_Milliseconds(); + int count = 0; + int minuteStart, minuteEnd; + float sec; + + // run all the frames in sequence + minuteStart = startTime; + + while( cmdDemoFile ) { + RunGameTic(); + count++; + + if ( count / 3600 != ( count - 1 ) / 3600 ) { + minuteEnd = Sys_Milliseconds(); + sec = ( minuteEnd - minuteStart ) / 1000.0; + minuteStart = minuteEnd; + common->Printf( "minute %i took %3.1f seconds\n", count / 3600, sec ); + UpdateScreen(); + } + } + + int endTime = Sys_Milliseconds(); + sec = ( endTime - startTime ) / 1000.0; + common->Printf( "%i seconds of game, replayed in %5.1f seconds\n", count / 60, sec ); +} + +/* +=============== +idSessionLocal::UnloadMap + +Performs cleanup that needs to happen between maps, or when a +game is exited. +Exits with mapSpawned = false +=============== +*/ +void idSessionLocal::UnloadMap() { + StopPlayingRenderDemo(); + + // end the current map in the game + if ( game ) { + game->MapShutdown(); + } + + if ( cmdDemoFile ) { + fileSystem->CloseFile( cmdDemoFile ); + cmdDemoFile = NULL; + } + + if ( writeDemo ) { + StopRecordingRenderDemo(); + } + + mapSpawned = false; +} + +/* +=============== +idSessionLocal::LoadLoadingGui +=============== +*/ +void idSessionLocal::LoadLoadingGui( const char *mapName ) { + // load / program a gui to stay up on the screen while loading + idStr stripped = mapName; + stripped.StripFileExtension(); + stripped.StripPath(); + + char guiMap[ MAX_STRING_CHARS ]; + strncpy( guiMap, va( "guis/map/%s.gui", stripped.c_str() ), MAX_STRING_CHARS ); + // give the gamecode a chance to override + game->GetMapLoadingGUI( guiMap ); + + if ( uiManager->CheckGui( guiMap ) ) { + guiLoading = uiManager->FindGui( guiMap, true, false, true ); + } else { + guiLoading = uiManager->FindGui( "guis/map/loading.gui", true, false, true ); + } + guiLoading->SetStateFloat( "map_loading", 0.0f ); +} + +/* +=============== +idSessionLocal::GetBytesNeededForMapLoad +=============== +*/ +int idSessionLocal::GetBytesNeededForMapLoad( const char *mapName ) { + const idDecl *mapDecl = declManager->FindType( DECL_MAPDEF, mapName, false ); + const idDeclEntityDef *mapDef = static_cast( mapDecl ); + if ( mapDef ) { + return mapDef->dict.GetInt( va("size%d", Max( 0, com_machineSpec.GetInteger() ) ) ); + } else { + if ( com_machineSpec.GetInteger() < 2 ) { + return 200 * 1024 * 1024; + } else { + return 400 * 1024 * 1024; + } + } +} + +/* +=============== +idSessionLocal::SetBytesNeededForMapLoad +=============== +*/ +void idSessionLocal::SetBytesNeededForMapLoad( const char *mapName, int bytesNeeded ) { + idDecl *mapDecl = const_cast(declManager->FindType( DECL_MAPDEF, mapName, false )); + idDeclEntityDef *mapDef = static_cast( mapDecl ); + + if ( com_updateLoadSize.GetBool() && mapDef ) { + // we assume that if com_updateLoadSize is true then the file is writable + + mapDef->dict.SetInt( va("size%d", com_machineSpec.GetInteger()), bytesNeeded ); + + idStr declText = "\nmapDef "; + declText += mapDef->GetName(); + declText += " {\n"; + for (int i=0; idict.GetNumKeyVals(); i++) { + const idKeyValue *kv = mapDef->dict.GetKeyVal( i ); + if ( kv && (kv->GetKey().Cmp("classname") != 0 ) ) { + declText += "\t\"" + kv->GetKey() + "\"\t\t\"" + kv->GetValue() + "\"\n"; + } + } + declText += "}"; + mapDef->SetText( declText ); + mapDef->ReplaceSourceFileText(); + } +} + +/* +=============== +idSessionLocal::ExecuteMapChange + +Performs the initialization of a game based on mapSpawnData, used for both single +player and multiplayer, but not for renderDemos, which don't +create a game at all. +Exits with mapSpawned = true +=============== +*/ +void idSessionLocal::ExecuteMapChange( bool noFadeWipe ) { + int i; + bool reloadingSameMap; + + // close console and remove any prints from the notify lines + console->Close(); + + if ( IsMultiplayer() ) { + // make sure the mp GUI isn't up, or when players get back in the + // map, mpGame's menu and the gui will be out of sync. + SetGUI( NULL, NULL ); + } + + // mute sound + soundSystem->SetMute( true ); + + // clear all menu sounds + menuSoundWorld->ClearAllSoundEmitters(); + + // unpause the game sound world + // NOTE: we UnPause again later down. not sure this is needed + if ( sw->IsPaused() ) { + sw->UnPause(); + } + + if ( !noFadeWipe ) { + // capture the current screen and start a wipe + StartWipe( "wipeMaterial", true ); + + // immediately complete the wipe to fade out the level transition + // run the wipe to completion + CompleteWipe(); + } + + // extract the map name from serverinfo + idStr mapString = mapSpawnData.serverInfo.GetString( "si_map" ); + + idStr fullMapName = "maps/"; + fullMapName += mapString; + fullMapName.StripFileExtension(); + + // shut down the existing game if it is running + UnloadMap(); + + // don't do the deferred caching if we are reloading the same map + if ( fullMapName == currentMapName ) { + reloadingSameMap = true; + } else { + reloadingSameMap = false; + currentMapName = fullMapName; + } + + // note which media we are going to need to load + if ( !reloadingSameMap ) { + declManager->BeginLevelLoad(); + renderSystem->BeginLevelLoad(); + soundSystem->BeginLevelLoad(); + } + + uiManager->BeginLevelLoad(); + uiManager->Reload( true ); + + // set the loading gui that we will wipe to + LoadLoadingGui( mapString ); + + // cause prints to force screen updates as a pacifier, + // and draw the loading gui instead of game draws + insideExecuteMapChange = true; + + // if this works out we will probably want all the sizes in a def file although this solution will + // work for new maps etc. after the first load. we can also drop the sizes into the default.cfg + fileSystem->ResetReadCount(); + if ( !reloadingSameMap ) { + bytesNeededForMapLoad = GetBytesNeededForMapLoad( mapString.c_str() ); + } else { + bytesNeededForMapLoad = 30 * 1024 * 1024; + } + + ClearWipe(); + + // let the loading gui spin for 1 second to animate out + ShowLoadingGui(); + + // note any warning prints that happen during the load process + common->ClearWarnings( mapString ); + + // release the mouse cursor + // before we do this potentially long operation + Sys_GrabMouseCursor( false ); + + // if net play, we get the number of clients during mapSpawnInfo processing + if ( !idAsyncNetwork::IsActive() ) { + numClients = 1; + } + + int start = Sys_Milliseconds(); + + common->Printf( "--------- Map Initialization ---------\n" ); + common->Printf( "Map: %s\n", mapString.c_str() ); + + // let the renderSystem load all the geometry + if ( !rw->InitFromMap( fullMapName ) ) { + common->Error( "couldn't load %s", fullMapName.c_str() ); + } + + // for the synchronous networking we needed to roll the angles over from + // level to level, but now we can just clear everything + usercmdGen->InitForNewMap(); + memset( &mapSpawnData.mapSpawnUsercmd, 0, sizeof( mapSpawnData.mapSpawnUsercmd ) ); + + // set the user info + for ( i = 0; i < numClients; i++ ) { + game->SetUserInfo( i, mapSpawnData.userInfo[i], idAsyncNetwork::client.IsActive(), false ); + game->SetPersistentPlayerInfo( i, mapSpawnData.persistentPlayerInfo[i] ); + } + + // load and spawn all other entities ( from a savegame possibly ) + if ( loadingSaveGame && savegameFile ) { + if ( game->InitFromSaveGame( fullMapName + ".map", rw, sw, savegameFile ) == false ) { + // If the loadgame failed, restart the map with the player persistent data + loadingSaveGame = false; + fileSystem->CloseFile( savegameFile ); + savegameFile = NULL; + + game->SetServerInfo( mapSpawnData.serverInfo ); + game->InitFromNewMap( fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), Sys_Milliseconds() ); + } + } else { + game->SetServerInfo( mapSpawnData.serverInfo ); + game->InitFromNewMap( fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), Sys_Milliseconds() ); + } + + if ( !idAsyncNetwork::IsActive() && !loadingSaveGame ) { + // spawn players + for ( i = 0; i < numClients; i++ ) { + game->SpawnPlayer( i ); + } + } + + // actually purge/load the media + if ( !reloadingSameMap ) { + renderSystem->EndLevelLoad(); + soundSystem->EndLevelLoad( mapString.c_str() ); + declManager->EndLevelLoad(); + SetBytesNeededForMapLoad( mapString.c_str(), fileSystem->GetReadCount() ); + } + uiManager->EndLevelLoad(); + + if ( !idAsyncNetwork::IsActive() && !loadingSaveGame ) { + // run a few frames to allow everything to settle + for ( i = 0; i < 10; i++ ) { + game->RunFrame( mapSpawnData.mapSpawnUsercmd ); + } + } + + common->Printf ("-----------------------------------\n"); + + int msec = Sys_Milliseconds() - start; + common->Printf( "%6d msec to load %s\n", msec, mapString.c_str() ); + + // let the renderSystem generate interactions now that everything is spawned + rw->GenerateAllInteractions(); + + common->PrintWarnings(); + + if ( guiLoading && bytesNeededForMapLoad ) { + float pct = guiLoading->State().GetFloat( "map_loading" ); + if ( pct < 0.0f ) { + pct = 0.0f; + } + while ( pct < 1.0f ) { + guiLoading->SetStateFloat( "map_loading", pct ); + guiLoading->StateChanged( com_frameTime ); + Sys_GenerateEvents(); + UpdateScreen(); + pct += 0.05f; + } + } + + // capture the current screen and start a wipe + StartWipe( "wipe2Material" ); + + usercmdGen->Clear(); + + // start saving commands for possible writeCmdDemo usage + logIndex = 0; + statIndex = 0; + lastSaveIndex = 0; + + // don't bother spinning over all the tics we spent loading + lastGameTic = latchedTicNumber = com_ticNumber; + + // remove any prints from the notify lines + console->ClearNotifyLines(); + + // stop drawing the laoding screen + insideExecuteMapChange = false; + + Sys_SetPhysicalWorkMemory( -1, -1 ); + + // set the game sound world for playback + soundSystem->SetPlayingSoundWorld( sw ); + + // when loading a save game the sound is paused + if ( sw->IsPaused() ) { + // unpause the game sound world + sw->UnPause(); + } + + // restart entity sound playback + soundSystem->SetMute( false ); + + // we are valid for game draws now + mapSpawned = true; + Sys_ClearEvents(); +} + +/* +=============== +LoadGame_f +=============== +*/ +void LoadGame_f( const idCmdArgs &args ) { + console->Close(); + if ( args.Argc() < 2 || idStr::Icmp(args.Argv(1), "quick" ) == 0 ) { + idStr saveName = common->GetLanguageDict()->GetString( "#str_07178" ); + sessLocal.LoadGame( saveName ); + } else { + sessLocal.LoadGame( args.Argv(1) ); + } +} + +/* +=============== +SaveGame_f +=============== +*/ +void SaveGame_f( const idCmdArgs &args ) { + if ( args.Argc() < 2 || idStr::Icmp( args.Argv(1), "quick" ) == 0 ) { + idStr saveName = common->GetLanguageDict()->GetString( "#str_07178" ); + if ( sessLocal.SaveGame( saveName ) ) { + common->Printf( "%s\n", saveName.c_str() ); + } + } else { + if ( sessLocal.SaveGame( args.Argv(1) ) ) { + common->Printf( "Saved %s\n", args.Argv(1) ); + } + } +} + +/* +=============== +TakeViewNotes_f +=============== +*/ +void TakeViewNotes_f( const idCmdArgs &args ) { + const char *p = ( args.Argc() > 1 ) ? args.Argv( 1 ) : ""; + sessLocal.TakeNotes( p ); +} + +/* +=============== +TakeViewNotes2_f +=============== +*/ +void TakeViewNotes2_f( const idCmdArgs &args ) { + const char *p = ( args.Argc() > 1 ) ? args.Argv( 1 ) : ""; + sessLocal.TakeNotes( p, true ); +} + +/* +=============== +idSessionLocal::TakeNotes +=============== +*/ +void idSessionLocal::TakeNotes( const char *p, bool extended ) { + if ( !mapSpawned ) { + common->Printf( "No map loaded!\n" ); + return; + } + + if ( extended ) { + guiTakeNotes = uiManager->FindGui( "guis/takeNotes2.gui", true, false, true ); + +#if 0 + const char *people[] = { + "Nobody", "Adam", "Brandon", "David", "PHook", "Jay", "Jake", + "PatJ", "Brett", "Ted", "Darin", "Brian", "Sean" + }; +#else + const char *people[] = { + "Tim", "Kenneth", "Robert", + "Matt", "Mal", "Jerry", "Steve", "Pat", + "Xian", "Ed", "Fred", "James", "Eric", "Andy", "Seneca", "Patrick", "Kevin", + "MrElusive", "Jim", "Brian", "John", "Adrian", "Nobody" + }; +#endif + const int numPeople = sizeof( people ) / sizeof( people[0] ); + + idListGUI * guiList_people = uiManager->AllocListGUI(); + guiList_people->Config( guiTakeNotes, "person" ); + for ( int i = 0; i < numPeople; i++ ) { + guiList_people->Push( people[i] ); + } + uiManager->FreeListGUI( guiList_people ); + + } else { + guiTakeNotes = uiManager->FindGui( "guis/takeNotes.gui", true, false, true ); + } + + SetGUI( guiTakeNotes, NULL ); + guiActive->SetStateString( "note", "" ); + guiActive->SetStateString( "notefile", p ); + guiActive->SetStateBool( "extended", extended ); + guiActive->Activate( true, com_frameTime ); +} + +/* +=============== +Session_Hitch_f +=============== +*/ +void Session_Hitch_f( const idCmdArgs &args ) { + idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); + if ( sw ) { + soundSystem->SetMute(true); + sw->Pause(); + Sys_EnterCriticalSection(); + } + if ( args.Argc() == 2 ) { + Sys_Sleep( atoi(args.Argv(1)) ); + } else { + Sys_Sleep( 100 ); + } + if ( sw ) { + Sys_LeaveCriticalSection(); + sw->UnPause(); + soundSystem->SetMute(false); + } +} + +/* +=============== +idSessionLocal::ScrubSaveGameFileName + +Turns a bad file name into a good one or your money back +=============== +*/ +void idSessionLocal::ScrubSaveGameFileName( idStr &saveFileName ) const { + int i; + idStr inFileName; + + inFileName = saveFileName; + inFileName.RemoveColors(); + inFileName.StripFileExtension(); + + saveFileName.Clear(); + + int len = inFileName.Length(); + for ( i = 0; i < len; i++ ) { + if ( strchr( "',.~!@#$%^&*()[]{}<>\\|/=?+;:-\'\"", inFileName[i] ) ) { + // random junk + saveFileName += '_'; + } else if ( (const unsigned char)inFileName[i] >= 128 ) { + // high ascii chars + saveFileName += '_'; + } else if ( inFileName[i] == ' ' ) { + saveFileName += '_'; + } else { + saveFileName += inFileName[i]; + } + } +} + +/* +=============== +idSessionLocal::SaveGame +=============== +*/ +bool idSessionLocal::SaveGame( const char *saveName, bool autosave ) { +#ifdef ID_DEDICATED + common->Printf( "Dedicated servers cannot save games.\n" ); + return false; +#else + int i; + idStr gameFile, previewFile, descriptionFile, mapName; + + if ( !mapSpawned ) { + common->Printf( "Not playing a game.\n" ); + return false; + } + + if ( IsMultiplayer() ) { + common->Printf( "Can't save during net play.\n" ); + return false; + } + + if ( game->GetPersistentPlayerInfo( 0 ).GetInt( "health" ) <= 0 ) { + MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04311" ), common->GetLanguageDict()->GetString ( "#str_04312" ), true ); + common->Printf( "You must be alive to save the game\n" ); + return false; + } + + if ( Sys_GetDriveFreeSpace( cvarSystem->GetCVarString( "fs_savepath" ) ) < 25 ) { + MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04313" ), common->GetLanguageDict()->GetString ( "#str_04314" ), true ); + common->Printf( "Not enough drive space to save the game\n" ); + return false; + } + + idSoundWorld *pauseWorld = soundSystem->GetPlayingSoundWorld(); + if ( pauseWorld ) { + pauseWorld->Pause(); + soundSystem->SetPlayingSoundWorld( NULL ); + } + + // setup up filenames and paths + gameFile = saveName; + ScrubSaveGameFileName( gameFile ); + + gameFile = "savegames/" + gameFile; + gameFile.SetFileExtension( ".save" ); + + previewFile = gameFile; + previewFile.SetFileExtension( ".tga" ); + + descriptionFile = gameFile; + descriptionFile.SetFileExtension( ".txt" ); + + // Open savegame file + idFile *fileOut = fileSystem->OpenFileWrite( gameFile ); + if ( fileOut == NULL ) { + common->Warning( "Failed to open save file '%s'\n", gameFile.c_str() ); + if ( pauseWorld ) { + soundSystem->SetPlayingSoundWorld( pauseWorld ); + pauseWorld->UnPause(); + } + return false; + } + + // Write SaveGame Header: + // Game Name / Version / Map Name / Persistant Player Info + + // game + const char *gamename = GAME_NAME; + fileOut->WriteString( gamename ); + + // version + fileOut->WriteInt( SAVEGAME_VERSION ); + + // map + mapName = mapSpawnData.serverInfo.GetString( "si_map" ); + fileOut->WriteString( mapName ); + + // persistent player info + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + mapSpawnData.persistentPlayerInfo[i] = game->GetPersistentPlayerInfo( i ); + mapSpawnData.persistentPlayerInfo[i].WriteToFileHandle( fileOut ); + } + + // let the game save its state + game->SaveGame( fileOut ); + + // close the sava game file + fileSystem->CloseFile( fileOut ); + + // Write screenshot + if ( !autosave ) { + renderSystem->CropRenderSize( 320, 240, false ); + game->Draw( 0 ); + renderSystem->CaptureRenderToFile( previewFile, true ); + renderSystem->UnCrop(); + } + + // Write description, which is just a text file with + // the unclean save name on line 1, map name on line 2, screenshot on line 3 + idFile *fileDesc = fileSystem->OpenFileWrite( descriptionFile ); + if ( fileDesc == NULL ) { + common->Warning( "Failed to open description file '%s'\n", descriptionFile.c_str() ); + if ( pauseWorld ) { + soundSystem->SetPlayingSoundWorld( pauseWorld ); + pauseWorld->UnPause(); + } + return false; + } + + idStr description = saveName; + description.Replace( "\\", "\\\\" ); + description.Replace( "\"", "\\\"" ); + + const idDeclEntityDef *mapDef = static_cast(declManager->FindType( DECL_MAPDEF, mapName, false )); + if ( mapDef ) { + mapName = common->GetLanguageDict()->GetString( mapDef->dict.GetString( "name", mapName ) ); + } + + fileDesc->Printf( "\"%s\"\n", description.c_str() ); + fileDesc->Printf( "\"%s\"\n", mapName.c_str()); + + if ( autosave ) { + idStr sshot = mapSpawnData.serverInfo.GetString( "si_map" ); + sshot.StripPath(); + sshot.StripFileExtension(); + fileDesc->Printf( "\"guis/assets/autosave/%s\"\n", sshot.c_str() ); + } else { + fileDesc->Printf( "\"\"\n" ); + } + + fileSystem->CloseFile( fileDesc ); + + if ( pauseWorld ) { + soundSystem->SetPlayingSoundWorld( pauseWorld ); + pauseWorld->UnPause(); + } + + syncNextGameFrame = true; + + + return true; +#endif +} + +/* +=============== +idSessionLocal::LoadGame +=============== +*/ +bool idSessionLocal::LoadGame( const char *saveName ) { +#ifdef ID_DEDICATED + common->Printf( "Dedicated servers cannot load games.\n" ); + return false; +#else + int i; + idStr in, loadFile, saveMap, gamename; + + if ( IsMultiplayer() ) { + common->Printf( "Can't load during net play.\n" ); + return false; + } + + //Hide the dialog box if it is up. + StopBox(); + + loadFile = saveName; + ScrubSaveGameFileName( loadFile ); + loadFile.SetFileExtension( ".save" ); + + in = "savegames/"; + in += loadFile; + + // Open savegame file + // only allow loads from the game directory because we don't want a base game to load + idStr game = cvarSystem->GetCVarString( "fs_game" ); + savegameFile = fileSystem->OpenFileRead( in, true, game.Length() ? game : NULL ); + + if ( savegameFile == NULL ) { + common->Warning( "Couldn't open savegame file %s", in.c_str() ); + return false; + } + + loadingSaveGame = true; + + // Read in save game header + // Game Name / Version / Map Name / Persistant Player Info + + // game + savegameFile->ReadString( gamename ); + + // if this isn't a savegame for the correct game, abort loadgame + if ( gamename != GAME_NAME ) { + common->Warning( "Attempted to load an invalid savegame: %s", in.c_str() ); + + loadingSaveGame = false; + fileSystem->CloseFile( savegameFile ); + savegameFile = NULL; + return false; + } + + // version + savegameFile->ReadInt( savegameVersion ); + + // map + savegameFile->ReadString( saveMap ); + + // persistent player info + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + mapSpawnData.persistentPlayerInfo[i].ReadFromFileHandle( savegameFile ); + } + + // check the version, if it doesn't match, cancel the loadgame, + // but still load the map with the persistant playerInfo from the header + // so that the player doesn't lose too much progress. + if ( savegameVersion != SAVEGAME_VERSION && + !( savegameVersion == 16 && SAVEGAME_VERSION == 17 ) ) { // handle savegame v16 in v17 + common->Warning( "Savegame Version mismatch: aborting loadgame and starting level with persistent data" ); + loadingSaveGame = false; + fileSystem->CloseFile( savegameFile ); + savegameFile = NULL; + } + + common->DPrintf( "loading a v%d savegame\n", savegameVersion ); + + if ( saveMap.Length() > 0 ) { + + // Start loading map + mapSpawnData.serverInfo.Clear(); + + mapSpawnData.serverInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + mapSpawnData.serverInfo.Set( "si_gameType", "singleplayer" ); + + mapSpawnData.serverInfo.Set( "si_map", saveMap ); + + mapSpawnData.syncedCVars.Clear(); + mapSpawnData.syncedCVars = *cvarSystem->MoveCVarsToDict( CVAR_NETWORKSYNC ); + + mapSpawnData.mapSpawnUsercmd[0] = usercmdGen->TicCmd( latchedTicNumber ); + // make sure no buttons are pressed + mapSpawnData.mapSpawnUsercmd[0].buttons = 0; + + ExecuteMapChange(); + + SetGUI( NULL, NULL ); + } + + if ( loadingSaveGame ) { + fileSystem->CloseFile( savegameFile ); + loadingSaveGame = false; + savegameFile = NULL; + } + + return true; +#endif +} + +/* +=============== +idSessionLocal::ProcessEvent +=============== +*/ +bool idSessionLocal::ProcessEvent( const sysEvent_t *event ) { + // hitting escape anywhere brings up the menu + if ( !guiActive && event->evType == SE_KEY && event->evValue2 == 1 && event->evValue == K_ESCAPE ) { + console->Close(); + if ( game ) { + idUserInterface *gui = NULL; + escReply_t op; + op = game->HandleESC( &gui ); + if ( op == ESC_IGNORE ) { + return true; + } else if ( op == ESC_GUI ) { + SetGUI( gui, NULL ); + return true; + } + } + StartMenu(); + return true; + } + + // let the pull-down console take it if desired + if ( console->ProcessEvent( event, false ) ) { + return true; + } + + // if we are testing a GUI, send all events to it + if ( guiTest ) { + // hitting escape exits the testgui + if ( event->evType == SE_KEY && event->evValue2 == 1 && event->evValue == K_ESCAPE ) { + guiTest = NULL; + return true; + } + + static const char *cmd; + cmd = guiTest->HandleEvent( event, com_frameTime ); + if ( cmd && cmd[0] ) { + common->Printf( "testGui event returned: '%s'\n", cmd ); + } + return true; + } + + // menus / etc + if ( guiActive ) { + MenuEvent( event ); + return true; + } + + // if we aren't in a game, force the console to take it + if ( !mapSpawned ) { + console->ProcessEvent( event, true ); + return true; + } + + // in game, exec bindings for all key downs + if ( event->evType == SE_KEY && event->evValue2 == 1 ) { + idKeyInput::ExecKeyBinding( event->evValue ); + return true; + } + + return false; +} + +/* +=============== +idSessionLocal::DrawWipeModel + +Draw the fade material over everything that has been drawn +=============== +*/ +void idSessionLocal::DrawWipeModel() { + int latchedTic = com_ticNumber; + + if ( wipeStartTic >= wipeStopTic ) { + return; + } + + if ( !wipeHold && latchedTic >= wipeStopTic ) { + return; + } + + float fade = ( float )( latchedTic - wipeStartTic ) / ( wipeStopTic - wipeStartTic ); + renderSystem->SetColor4( 1, 1, 1, fade ); + renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, wipeMaterial ); +} + +/* +=============== +idSessionLocal::AdvanceRenderDemo +=============== +*/ +void idSessionLocal::AdvanceRenderDemo( bool singleFrameOnly ) { + if ( lastDemoTic == -1 ) { + lastDemoTic = latchedTicNumber - 1; + } + + int skipFrames = 0; + + if ( !aviCaptureMode && !timeDemo && !singleFrameOnly ) { + skipFrames = ( (latchedTicNumber - lastDemoTic) / USERCMD_PER_DEMO_FRAME ) - 1; + // never skip too many frames, just let it go into slightly slow motion + if ( skipFrames > 4 ) { + skipFrames = 4; + } + lastDemoTic = latchedTicNumber - latchedTicNumber % USERCMD_PER_DEMO_FRAME; + } else { + // always advance a single frame with avidemo and timedemo + lastDemoTic = latchedTicNumber; + } + + while( skipFrames > -1 ) { + int ds = DS_FINISHED; + + readDemo->ReadInt( ds ); + if ( ds == DS_FINISHED ) { + if ( numDemoFrames != 1 ) { + // if the demo has a single frame (a demoShot), continuously replay + // the renderView that has already been read + Stop(); + StartMenu(); + } + break; + } + if ( ds == DS_RENDER ) { + if ( rw->ProcessDemoCommand( readDemo, ¤tDemoRenderView, &demoTimeOffset ) ) { + // a view is ready to render + skipFrames--; + numDemoFrames++; + } + continue; + } + if ( ds == DS_SOUND ) { + sw->ProcessDemoCommand( readDemo ); + continue; + } + // appears in v1.2, with savegame format 17 + if ( ds == DS_VERSION ) { + readDemo->ReadInt( renderdemoVersion ); + common->Printf( "reading a v%d render demo\n", renderdemoVersion ); + // set the savegameVersion to current for render demo paths that share the savegame paths + savegameVersion = SAVEGAME_VERSION; + continue; + } + common->Error( "Bad render demo token" ); + } + + if ( com_showDemo.GetBool() ) { + common->Printf( "frame:%i DemoTic:%i latched:%i skip:%i\n", numDemoFrames, lastDemoTic, latchedTicNumber, skipFrames ); + } + +} + +/* +=============== +idSessionLocal::DrawCmdGraph + +Graphs yaw angle for testing smoothness +=============== +*/ +static const int ANGLE_GRAPH_HEIGHT = 128; +static const int ANGLE_GRAPH_STRETCH = 3; +void idSessionLocal::DrawCmdGraph() { + if ( !com_showAngles.GetBool() ) { + return; + } + renderSystem->SetColor4( 0.1f, 0.1f, 0.1f, 1.0f ); + renderSystem->DrawStretchPic( 0, 480-ANGLE_GRAPH_HEIGHT, MAX_BUFFERED_USERCMD*ANGLE_GRAPH_STRETCH, ANGLE_GRAPH_HEIGHT, 0, 0, 1, 1, whiteMaterial ); + renderSystem->SetColor4( 0.9f, 0.9f, 0.9f, 1.0f ); + for ( int i = 0 ; i < MAX_BUFFERED_USERCMD-4 ; i++ ) { + usercmd_t cmd = usercmdGen->TicCmd( latchedTicNumber - (MAX_BUFFERED_USERCMD-4) + i ); + int h = cmd.angles[1]; + h >>= 8; + h &= (ANGLE_GRAPH_HEIGHT-1); + renderSystem->DrawStretchPic( i* ANGLE_GRAPH_STRETCH, 480-h, 1, h, 0, 0, 1, 1, whiteMaterial ); + } +} + +/* +=============== +idSessionLocal::PacifierUpdate +=============== +*/ +void idSessionLocal::PacifierUpdate() { + if ( !insideExecuteMapChange ) { + return; + } + + // never do pacifier screen updates while inside the + // drawing code, or we can have various recursive problems + if ( insideUpdateScreen ) { + return; + } + + int time = eventLoop->Milliseconds(); + + if ( time - lastPacifierTime < 100 ) { + return; + } + lastPacifierTime = time; + + if ( guiLoading && bytesNeededForMapLoad ) { + float n = fileSystem->GetReadCount(); + float pct = ( n / bytesNeededForMapLoad ); + // pct = idMath::ClampFloat( 0.0f, 100.0f, pct ); + guiLoading->SetStateFloat( "map_loading", pct ); + guiLoading->StateChanged( com_frameTime ); + } + + Sys_GenerateEvents(); + + UpdateScreen(); + + idAsyncNetwork::client.PacifierUpdate(); + idAsyncNetwork::server.PacifierUpdate(); +} + +/* +=============== +idSessionLocal::Draw +=============== +*/ +void idSessionLocal::Draw() { + bool fullConsole = false; + + if ( insideExecuteMapChange ) { + if ( guiLoading ) { + guiLoading->Redraw( com_frameTime ); + } + if ( guiActive == guiMsg ) { + guiMsg->Redraw( com_frameTime ); + } + } else if ( guiTest ) { + // if testing a gui, clear the screen and draw it + // clear the background, in case the tested gui is transparent + // NOTE that you can't use this for aviGame recording, it will tick at real com_frameTime between screenshots.. + renderSystem->SetColor( colorBlack ); + renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) ); + guiTest->Redraw( com_frameTime ); + } else if ( guiActive && !guiActive->State().GetBool( "gameDraw" ) ) { + + // draw the frozen gui in the background + if ( guiActive == guiMsg && guiMsgRestore ) { + guiMsgRestore->Redraw( com_frameTime ); + } + + // draw the menus full screen + if ( guiActive == guiTakeNotes && !com_skipGameDraw.GetBool() ) { + game->Draw( GetLocalClientNum() ); + } + + guiActive->Redraw( com_frameTime ); + } else if ( readDemo ) { + rw->RenderScene( ¤tDemoRenderView ); + renderSystem->DrawDemoPics(); + } else if ( mapSpawned ) { + bool gameDraw = false; + // normal drawing for both single and multi player + if ( !com_skipGameDraw.GetBool() && GetLocalClientNum() >= 0 ) { + // draw the game view + int start = Sys_Milliseconds(); + gameDraw = game->Draw( GetLocalClientNum() ); + int end = Sys_Milliseconds(); + time_gameDraw += ( end - start ); // note time used for com_speeds + } + if ( !gameDraw ) { + renderSystem->SetColor( colorBlack ); + renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) ); + } + + // save off the 2D drawing from the game + if ( writeDemo ) { + renderSystem->WriteDemoPics(); + } + } else { +#if ID_CONSOLE_LOCK + if ( com_allowConsole.GetBool() ) { + console->Draw( true ); + } else { + emptyDrawCount++; + if ( emptyDrawCount > 5 ) { + // it's best if you can avoid triggering the watchgod by doing the right thing somewhere else + assert( false ); + common->Warning( "idSession: triggering mainmenu watchdog" ); + emptyDrawCount = 0; + StartMenu(); + } + renderSystem->SetColor4( 0, 0, 0, 1 ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) ); + } +#else + // draw the console full screen - this should only ever happen in developer builds + console->Draw( true ); +#endif + fullConsole = true; + } + +#if ID_CONSOLE_LOCK + if ( !fullConsole && emptyDrawCount ) { + common->DPrintf( "idSession: %d empty frame draws\n", emptyDrawCount ); + emptyDrawCount = 0; + } + fullConsole = false; +#endif + + // draw the wipe material on top of this if it hasn't completed yet + DrawWipeModel(); + + // draw debug graphs + DrawCmdGraph(); + + // draw the half console / notify console on top of everything + if ( !fullConsole ) { + console->Draw( false ); + } +} + +/* +=============== +idSessionLocal::UpdateScreen +=============== +*/ +void idSessionLocal::UpdateScreen( bool outOfSequence ) { + +#ifdef _WIN32 + + if ( com_editors ) { + if ( !Sys_IsWindowVisible() ) { + return; + } + } +#endif + + if ( insideUpdateScreen ) { + return; +// common->FatalError( "idSessionLocal::UpdateScreen: recursively called" ); + } + + insideUpdateScreen = true; + + // if this is a long-operation update and we are in windowed mode, + // release the mouse capture back to the desktop + if ( outOfSequence ) { + Sys_GrabMouseCursor( false ); + } + + renderSystem->BeginFrame( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight() ); + + // draw everything + Draw(); + + if ( com_speeds.GetBool() ) { + renderSystem->EndFrame( &time_frontend, &time_backend ); + } else { + renderSystem->EndFrame( NULL, NULL ); + } + + insideUpdateScreen = false; +} + +/* +=============== +idSessionLocal::Frame +=============== +*/ +void idSessionLocal::Frame() { + + if ( com_asyncSound.GetInteger() == 0 ) { + soundSystem->AsyncUpdate( Sys_Milliseconds() ); + } + + // Editors that completely take over the game + if ( com_editorActive && ( com_editors & ( EDITOR_RADIANT | EDITOR_GUI ) ) ) { + return; + } + + // if the console is down, we don't need to hold + // the mouse cursor + if ( console->Active() || com_editorActive ) { + Sys_GrabMouseCursor( false ); + } else { + Sys_GrabMouseCursor( true ); + } + + // save the screenshot and audio from the last draw if needed + if ( aviCaptureMode ) { + idStr name; + + name = va("demos/%s/%s_%05i.tga", aviDemoShortName.c_str(), aviDemoShortName.c_str(), aviTicStart ); + + float ratio = 30.0f / ( 1000.0f / USERCMD_MSEC / com_aviDemoTics.GetInteger() ); + aviDemoFrameCount += ratio; + if ( aviTicStart + 1 != ( int )aviDemoFrameCount ) { + // skipped frames so write them out + int c = aviDemoFrameCount - aviTicStart; + while ( c-- ) { + renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL ); + name = va("demos/%s/%s_%05i.tga", aviDemoShortName.c_str(), aviDemoShortName.c_str(), ++aviTicStart ); + } + } + aviTicStart = aviDemoFrameCount; + + // remove any printed lines at the top before taking the screenshot + console->ClearNotifyLines(); + + // this will call Draw, possibly multiple times if com_aviDemoSamples is > 1 + renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL ); + } + + // at startup, we may be backwards + if ( latchedTicNumber > com_ticNumber ) { + latchedTicNumber = com_ticNumber; + } + + // se how many tics we should have before continuing + int minTic = latchedTicNumber + 1; + if ( com_minTics.GetInteger() > 1 ) { + minTic = lastGameTic + com_minTics.GetInteger(); + } + + if ( readDemo ) { + if ( !timeDemo && numDemoFrames != 1 ) { + minTic = lastDemoTic + USERCMD_PER_DEMO_FRAME; + } else { + // timedemos and demoshots will run as fast as they can, other demos + // will not run more than 30 hz + minTic = latchedTicNumber; + } + } else if ( writeDemo ) { + minTic = lastGameTic + USERCMD_PER_DEMO_FRAME; // demos are recorded at 30 hz + } + + // fixedTic lets us run a forced number of usercmd each frame without timing + if ( com_fixedTic.GetInteger() ) { + minTic = latchedTicNumber; + } + + // FIXME: deserves a cleanup and abstraction +#if defined( _WIN32 ) + // Spin in place if needed. The game should yield the cpu if + // it is running over 60 hz, because there is fundamentally + // nothing useful for it to do. + while( 1 ) { + latchedTicNumber = com_ticNumber; + if ( latchedTicNumber >= minTic ) { + break; + } + Sys_Sleep( 1 ); + } +#else + while( 1 ) { + latchedTicNumber = com_ticNumber; + if ( latchedTicNumber >= minTic ) { + break; + } + Sys_WaitForEvent( TRIGGER_EVENT_ONE ); + } +#endif + + if ( authEmitTimeout ) { + // waiting for a game auth + if ( Sys_Milliseconds() > authEmitTimeout ) { + // expired with no reply + // means that if a firewall is blocking the master, we will let through + common->DPrintf( "no reply from auth\n" ); + if ( authWaitBox ) { + // close the wait box + StopBox(); + authWaitBox = false; + } + if ( cdkey_state == CDKEY_CHECKING ) { + cdkey_state = CDKEY_OK; + } + if ( xpkey_state == CDKEY_CHECKING ) { + xpkey_state = CDKEY_OK; + } + // maintain this empty as it's set by auth denials + authMsg.Empty(); + authEmitTimeout = 0; + SetCDKeyGuiVars(); + } + } + + // send frame and mouse events to active guis + GuiFrameEvents(); + + // advance demos + if ( readDemo ) { + AdvanceRenderDemo( false ); + return; + } + + //------------ single player game tics -------------- + + if ( !mapSpawned || guiActive ) { + if ( !com_asyncInput.GetBool() ) { + // early exit, won't do RunGameTic .. but still need to update mouse position for GUIs + usercmdGen->GetDirectUsercmd(); + } + } + + if ( !mapSpawned ) { + return; + } + + if ( guiActive ) { + lastGameTic = latchedTicNumber; + return; + } + + // in message box / GUIFrame, idSessionLocal::Frame is used for GUI interactivity + // but we early exit to avoid running game frames + if ( idAsyncNetwork::IsActive() ) { + return; + } + + // check for user info changes + if ( cvarSystem->GetModifiedFlags() & CVAR_USERINFO ) { + mapSpawnData.userInfo[0] = *cvarSystem->MoveCVarsToDict( CVAR_USERINFO ); + game->SetUserInfo( 0, mapSpawnData.userInfo[0], false, false ); + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); + } + + // see how many usercmds we are going to run + int numCmdsToRun = latchedTicNumber - lastGameTic; + + // don't let a long onDemand sound load unsync everything + if ( timeHitch ) { + int skip = timeHitch / USERCMD_MSEC; + lastGameTic += skip; + numCmdsToRun -= skip; + timeHitch = 0; + } + + // don't get too far behind after a hitch + if ( numCmdsToRun > 10 ) { + lastGameTic = latchedTicNumber - 10; + } + + // never use more than USERCMD_PER_DEMO_FRAME, + // which makes it go into slow motion when recording + if ( writeDemo ) { + int fixedTic = USERCMD_PER_DEMO_FRAME; + // we should have waited long enough + if ( numCmdsToRun < fixedTic ) { + common->Error( "idSessionLocal::Frame: numCmdsToRun < fixedTic" ); + } + // we may need to dump older commands + lastGameTic = latchedTicNumber - fixedTic; + } else if ( com_fixedTic.GetInteger() > 0 ) { + // this may cause commands run in a previous frame to + // be run again if we are going at above the real time rate + lastGameTic = latchedTicNumber - com_fixedTic.GetInteger(); + } else if ( aviCaptureMode ) { + lastGameTic = latchedTicNumber - com_aviDemoTics.GetInteger(); + } + + // force only one game frame update this frame. the game code requests this after skipping cinematics + // so we come back immediately after the cinematic is done instead of a few frames later which can + // cause sounds played right after the cinematic to not play. + if ( syncNextGameFrame ) { + lastGameTic = latchedTicNumber - 1; + syncNextGameFrame = false; + } + + // create client commands, which will be sent directly + // to the game + if ( com_showTics.GetBool() ) { + common->Printf( "%i ", latchedTicNumber - lastGameTic ); + } + + int gameTicsToRun = latchedTicNumber - lastGameTic; + int i; + for ( i = 0 ; i < gameTicsToRun ; i++ ) { + RunGameTic(); + if ( !mapSpawned ) { + // exited game play + break; + } + if ( syncNextGameFrame ) { + // long game frame, so break out and continue executing as if there was no hitch + break; + } + } +} + +/* +================ +idSessionLocal::RunGameTic +================ +*/ +void idSessionLocal::RunGameTic() { + logCmd_t logCmd; + usercmd_t cmd; + + // if we are doing a command demo, read or write from the file + if ( cmdDemoFile ) { + if ( !cmdDemoFile->Read( &logCmd, sizeof( logCmd ) ) ) { + common->Printf( "Command demo completed at logIndex %i\n", logIndex ); + fileSystem->CloseFile( cmdDemoFile ); + cmdDemoFile = NULL; + if ( aviCaptureMode ) { + EndAVICapture(); + Shutdown(); + } + // we fall out of the demo to normal commands + // the impulse and chat character toggles may not be correct, and the view + // angle will definitely be wrong + } else { + cmd = logCmd.cmd; + cmd.ByteSwap(); + logCmd.consistencyHash = LittleLong( logCmd.consistencyHash ); + } + } + + // if we didn't get one from the file, get it locally + if ( !cmdDemoFile ) { + // get a locally created command + if ( com_asyncInput.GetBool() ) { + cmd = usercmdGen->TicCmd( lastGameTic ); + } else { + cmd = usercmdGen->GetDirectUsercmd(); + } + lastGameTic++; + } + + // run the game logic every player move + int start = Sys_Milliseconds(); + gameReturn_t ret = game->RunFrame( &cmd ); + + int end = Sys_Milliseconds(); + time_gameFrame += end - start; // note time used for com_speeds + + // check for constency failure from a recorded command + if ( cmdDemoFile ) { + if ( ret.consistencyHash != logCmd.consistencyHash ) { + common->Printf( "Consistency failure on logIndex %i\n", logIndex ); + Stop(); + return; + } + } + + // save the cmd for cmdDemo archiving + if ( logIndex < MAX_LOGGED_USERCMDS ) { + loggedUsercmds[logIndex].cmd = cmd; + // save the consistencyHash for demo playback verification + loggedUsercmds[logIndex].consistencyHash = ret.consistencyHash; + if (logIndex % 30 == 0 && statIndex < MAX_LOGGED_STATS) { + loggedStats[statIndex].health = ret.health; + loggedStats[statIndex].heartRate = ret.heartRate; + loggedStats[statIndex].stamina = ret.stamina; + loggedStats[statIndex].combat = ret.combat; + statIndex++; + } + logIndex++; + } + + syncNextGameFrame = ret.syncNextGameFrame; + + if ( ret.sessionCommand[0] ) { + idCmdArgs args; + + args.TokenizeString( ret.sessionCommand, false ); + + if ( !idStr::Icmp( args.Argv(0), "map" ) ) { + // get current player states + for ( int i = 0 ; i < numClients ; i++ ) { + mapSpawnData.persistentPlayerInfo[i] = game->GetPersistentPlayerInfo( i ); + } + // clear the devmap key on serverinfo, so player spawns + // won't get the map testing items + mapSpawnData.serverInfo.Delete( "devmap" ); + + // go to the next map + MoveToNewMap( args.Argv(1) ); + } else if ( !idStr::Icmp( args.Argv(0), "devmap" ) ) { + mapSpawnData.serverInfo.Set( "devmap", "1" ); + MoveToNewMap( args.Argv(1) ); + } else if ( !idStr::Icmp( args.Argv(0), "died" ) ) { + // restart on the same map + UnloadMap(); + SetGUI(guiRestartMenu, NULL); + } else if ( !idStr::Icmp( args.Argv(0), "disconnect" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_INSERT, "stoprecording ; disconnect" ); + } else if ( !idStr::Icmp( args.Argv(0), "endOfDemo" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "endOfDemo" ); + } + } +} + +/* +=============== +idSessionLocal::Init + +Called in an orderly fashion at system startup, +so commands, cvars, files, etc are all available +=============== +*/ +void idSessionLocal::Init() { + + common->Printf( "-------- Initializing Session --------\n" ); + + cmdSystem->AddCommand( "writePrecache", Sess_WritePrecache_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "writes precache commands" ); + +#ifndef ID_DEDICATED + cmdSystem->AddCommand( "map", Session_Map_f, CMD_FL_SYSTEM, "loads a map", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "devmap", Session_DevMap_f, CMD_FL_SYSTEM, "loads a map in developer mode", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "testmap", Session_TestMap_f, CMD_FL_SYSTEM, "tests a map", idCmdSystem::ArgCompletion_MapName ); + + cmdSystem->AddCommand( "writeCmdDemo", Session_WriteCmdDemo_f, CMD_FL_SYSTEM, "writes a command demo" ); + cmdSystem->AddCommand( "playCmdDemo", Session_PlayCmdDemo_f, CMD_FL_SYSTEM, "plays back a command demo" ); + cmdSystem->AddCommand( "timeCmdDemo", Session_TimeCmdDemo_f, CMD_FL_SYSTEM, "times a command demo" ); + cmdSystem->AddCommand( "exitCmdDemo", Session_ExitCmdDemo_f, CMD_FL_SYSTEM, "exits a command demo" ); + cmdSystem->AddCommand( "aviCmdDemo", Session_AVICmdDemo_f, CMD_FL_SYSTEM, "writes AVIs for a command demo" ); + cmdSystem->AddCommand( "aviGame", Session_AVIGame_f, CMD_FL_SYSTEM, "writes AVIs for the current game" ); + + cmdSystem->AddCommand( "recordDemo", Session_RecordDemo_f, CMD_FL_SYSTEM, "records a demo" ); + cmdSystem->AddCommand( "stopRecording", Session_StopRecordingDemo_f, CMD_FL_SYSTEM, "stops demo recording" ); + cmdSystem->AddCommand( "playDemo", Session_PlayDemo_f, CMD_FL_SYSTEM, "plays back a demo", idCmdSystem::ArgCompletion_DemoName ); + cmdSystem->AddCommand( "timeDemo", Session_TimeDemo_f, CMD_FL_SYSTEM, "times a demo", idCmdSystem::ArgCompletion_DemoName ); + cmdSystem->AddCommand( "timeDemoQuit", Session_TimeDemoQuit_f, CMD_FL_SYSTEM, "times a demo and quits", idCmdSystem::ArgCompletion_DemoName ); + cmdSystem->AddCommand( "aviDemo", Session_AVIDemo_f, CMD_FL_SYSTEM, "writes AVIs for a demo", idCmdSystem::ArgCompletion_DemoName ); + cmdSystem->AddCommand( "compressDemo", Session_CompressDemo_f, CMD_FL_SYSTEM, "compresses a demo file", idCmdSystem::ArgCompletion_DemoName ); +#endif + + cmdSystem->AddCommand( "disconnect", Session_Disconnect_f, CMD_FL_SYSTEM, "disconnects from a game" ); + +#ifdef ID_DEMO_BUILD + cmdSystem->AddCommand( "endOfDemo", Session_EndOfDemo_f, CMD_FL_SYSTEM, "ends the demo version of the game" ); +#endif + + cmdSystem->AddCommand( "demoShot", Session_DemoShot_f, CMD_FL_SYSTEM, "writes a screenshot for a demo" ); + cmdSystem->AddCommand( "testGUI", Session_TestGUI_f, CMD_FL_SYSTEM, "tests a gui" ); + +#ifndef ID_DEDICATED + cmdSystem->AddCommand( "saveGame", SaveGame_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "saves a game" ); + cmdSystem->AddCommand( "loadGame", LoadGame_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "loads a game", idCmdSystem::ArgCompletion_SaveGame ); +#endif + + cmdSystem->AddCommand( "takeViewNotes", TakeViewNotes_f, CMD_FL_SYSTEM, "take notes about the current map from the current view" ); + cmdSystem->AddCommand( "takeViewNotes2", TakeViewNotes2_f, CMD_FL_SYSTEM, "extended take view notes" ); + + cmdSystem->AddCommand( "rescanSI", Session_RescanSI_f, CMD_FL_SYSTEM, "internal - rescan serverinfo cvars and tell game" ); + + cmdSystem->AddCommand( "promptKey", Session_PromptKey_f, CMD_FL_SYSTEM, "prompt and sets the CD Key" ); + + cmdSystem->AddCommand( "hitch", Session_Hitch_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "hitches the game" ); + + // the same idRenderWorld will be used for all games + // and demos, insuring that level specific models + // will be freed + rw = renderSystem->AllocRenderWorld(); + sw = soundSystem->AllocSoundWorld( rw ); + + menuSoundWorld = soundSystem->AllocSoundWorld( rw ); + + // we have a single instance of the main menu +#ifndef ID_DEMO_BUILD + guiMainMenu = uiManager->FindGui( "guis/mainmenu.gui", true, false, true ); +#else + guiMainMenu = uiManager->FindGui( "guis/demo_mainmenu.gui", true, false, true ); +#endif + guiMainMenu_MapList = uiManager->AllocListGUI(); + guiMainMenu_MapList->Config( guiMainMenu, "mapList" ); + idAsyncNetwork::client.serverList.GUIConfig( guiMainMenu, "serverList" ); + guiRestartMenu = uiManager->FindGui( "guis/restart.gui", true, false, true ); + guiGameOver = uiManager->FindGui( "guis/gameover.gui", true, false, true ); + guiMsg = uiManager->FindGui( "guis/msg.gui", true, false, true ); + guiTakeNotes = uiManager->FindGui( "guis/takeNotes.gui", true, false, true ); + guiIntro = uiManager->FindGui( "guis/intro.gui", true, false, true ); + + whiteMaterial = declManager->FindMaterial( "_white" ); + + guiInGame = NULL; + guiTest = NULL; + + guiActive = NULL; + guiHandle = NULL; + + ReadCDKey(); + + common->Printf( "session initialized\n" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +=============== +idSessionLocal::GetLocalClientNum +=============== +*/ +int idSessionLocal::GetLocalClientNum() { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetLocalClientNum(); + } else if ( idAsyncNetwork::server.IsActive() ) { + if ( idAsyncNetwork::serverDedicated.GetInteger() == 0 ) { + return 0; + } else if ( idAsyncNetwork::server.IsClientInGame( idAsyncNetwork::serverDrawClient.GetInteger() ) ) { + return idAsyncNetwork::serverDrawClient.GetInteger(); + } else { + return -1; + } + } else { + return 0; + } +} + +/* +=============== +idSessionLocal::SetPlayingSoundWorld +=============== +*/ +void idSessionLocal::SetPlayingSoundWorld() { + if ( guiActive && ( guiActive == guiMainMenu || guiActive == guiIntro || guiActive == guiLoading || ( guiActive == guiMsg && !mapSpawned ) ) ) { + soundSystem->SetPlayingSoundWorld( menuSoundWorld ); + } else { + soundSystem->SetPlayingSoundWorld( sw ); + } +} + +/* +=============== +idSessionLocal::TimeHitch + +this is used by the sound system when an OnDemand sound is loaded, so the game action +doesn't advance and get things out of sync +=============== +*/ +void idSessionLocal::TimeHitch( int msec ) { + timeHitch += msec; +} + +/* +================= +idSessionLocal::ReadCDKey +================= +*/ +void idSessionLocal::ReadCDKey( void ) { + idStr filename; + idFile *f; + char buffer[32]; + + cdkey_state = CDKEY_UNKNOWN; + + filename = "../" BASE_GAMEDIR "/" CDKEY_FILE; + f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_savepath" ) ); + if ( !f ) { + common->Printf( "Couldn't read %s.\n", filename.c_str() ); + cdkey[ 0 ] = '\0'; + } else { + memset( buffer, 0, sizeof(buffer) ); + f->Read( buffer, CDKEY_BUF_LEN - 1 ); + fileSystem->CloseFile( f ); + idStr::Copynz( cdkey, buffer, CDKEY_BUF_LEN ); + } + + xpkey_state = CDKEY_UNKNOWN; + + filename = "../" BASE_GAMEDIR "/" XPKEY_FILE; + f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_savepath" ) ); + if ( !f ) { + common->Printf( "Couldn't read %s.\n", filename.c_str() ); + xpkey[ 0 ] = '\0'; + } else { + memset( buffer, 0, sizeof(buffer) ); + f->Read( buffer, CDKEY_BUF_LEN - 1 ); + fileSystem->CloseFile( f ); + idStr::Copynz( xpkey, buffer, CDKEY_BUF_LEN ); + } +} + +/* +================ +idSessionLocal::WriteCDKey +================ +*/ +void idSessionLocal::WriteCDKey( void ) { + idStr filename; + idFile *f; + const char *OSPath; + + filename = "../" BASE_GAMEDIR "/" CDKEY_FILE; + // OpenFileWrite advertises creating directories to the path if needed, but that won't work with a '..' in the path + // occasionally on windows, but mostly on Linux and OSX, the fs_savepath/base may not exist in full + OSPath = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_savepath" ), BASE_GAMEDIR, CDKEY_FILE ); + fileSystem->CreateOSPath( OSPath ); + f = fileSystem->OpenFileWrite( filename ); + if ( !f ) { + common->Printf( "Couldn't write %s.\n", filename.c_str() ); + return; + } + f->Printf( "%s%s", cdkey, CDKEY_TEXT ); + fileSystem->CloseFile( f ); + + filename = "../" BASE_GAMEDIR "/" XPKEY_FILE; + f = fileSystem->OpenFileWrite( filename ); + if ( !f ) { + common->Printf( "Couldn't write %s.\n", filename.c_str() ); + return; + } + f->Printf( "%s%s", xpkey, CDKEY_TEXT ); + fileSystem->CloseFile( f ); +} + +/* +=============== +idSessionLocal::ClearKey +=============== +*/ +void idSessionLocal::ClearCDKey( bool valid[ 2 ] ) { + if ( !valid[ 0 ] ) { + memset( cdkey, 0, CDKEY_BUF_LEN ); + cdkey_state = CDKEY_UNKNOWN; + } else if ( cdkey_state == CDKEY_CHECKING ) { + // if a key was in checking and not explicitely asked for clearing, put it back to ok + cdkey_state = CDKEY_OK; + } + if ( !valid[ 1 ] ) { + memset( xpkey, 0, CDKEY_BUF_LEN ); + xpkey_state = CDKEY_UNKNOWN; + } else if ( xpkey_state == CDKEY_CHECKING ) { + xpkey_state = CDKEY_OK; + } + WriteCDKey( ); +} + +/* +================ +idSessionLocal::GetCDKey +================ +*/ +const char *idSessionLocal::GetCDKey( bool xp ) { + if ( !xp ) { + return cdkey; + } + if ( xpkey_state == CDKEY_OK || xpkey_state == CDKEY_CHECKING ) { + return xpkey; + } + return NULL; +} + +// digits to letters table +#define CDKEY_DIGITS "TWSBJCGD7PA23RLH" + +/* +=============== +idSessionLocal::EmitGameAuth +we toggled some key state to CDKEY_CHECKING. send a standalone auth packet to validate +=============== +*/ +void idSessionLocal::EmitGameAuth( void ) { + // make sure the auth reply is empty, we use it to indicate an auth reply + authMsg.Empty(); + if ( idAsyncNetwork::client.SendAuthCheck( cdkey_state == CDKEY_CHECKING ? cdkey : NULL, xpkey_state == CDKEY_CHECKING ? xpkey : NULL ) ) { + authEmitTimeout = Sys_Milliseconds() + CDKEY_AUTH_TIMEOUT; + common->DPrintf( "authing with the master..\n" ); + } else { + // net is not available + common->DPrintf( "sendAuthCheck failed\n" ); + if ( cdkey_state == CDKEY_CHECKING ) { + cdkey_state = CDKEY_OK; + } + if ( xpkey_state == CDKEY_CHECKING ) { + xpkey_state = CDKEY_OK; + } + } +} + +/* +================ +idSessionLocal::CheckKey +the function will only modify keys to _OK or _CHECKING if the offline checks are passed +if the function returns false, the offline checks failed, and offline_valid holds which keys are bad +================ +*/ +bool idSessionLocal::CheckKey( const char *key, bool netConnect, bool offline_valid[ 2 ] ) { + char lkey[ 2 ][ CDKEY_BUF_LEN ]; + char l_chk[ 2 ][ 3 ]; + char s_chk[ 3 ]; + int imax,i_key; + unsigned int checksum, chk8; + bool edited_key[ 2 ]; + + // make sure have a right input string + assert( strlen( key ) == ( CDKEY_BUF_LEN - 1 ) * 2 + 4 + 3 + 4 ); + + edited_key[ 0 ] = ( key[0] == '1' ); + idStr::Copynz( lkey[0], key + 2, CDKEY_BUF_LEN ); + idStr::ToUpper( lkey[0] ); + idStr::Copynz( l_chk[0], key + CDKEY_BUF_LEN + 2, 3 ); + idStr::ToUpper( l_chk[0] ); + edited_key[ 1 ] = ( key[ CDKEY_BUF_LEN + 2 + 3 ] == '1' ); + idStr::Copynz( lkey[1], key + CDKEY_BUF_LEN + 7, CDKEY_BUF_LEN ); + idStr::ToUpper( lkey[1] ); + idStr::Copynz( l_chk[1], key + CDKEY_BUF_LEN * 2 + 7, 3 ); + idStr::ToUpper( l_chk[1] ); + + if ( fileSystem->HasD3XP() ) { + imax = 2; + } else { + imax = 1; + } + offline_valid[ 0 ] = offline_valid[ 1 ] = true; + for( i_key = 0; i_key < imax; i_key++ ) { + // check that the characters are from the valid set + int i; + for ( i = 0; i < CDKEY_BUF_LEN - 1; i++ ) { + if ( !strchr( CDKEY_DIGITS, lkey[i_key][i] ) ) { + offline_valid[ i_key ] = false; + continue; + } + } + + if ( edited_key[ i_key ] ) { + // verify the checksum for edited keys only + checksum = CRC32_BlockChecksum( lkey[i_key], CDKEY_BUF_LEN - 1 ); + chk8 = ( checksum & 0xff ) ^ ( ( ( checksum & 0xff00 ) >> 8 ) ^ ( ( ( checksum & 0xff0000 ) >> 16 ) ^ ( ( checksum & 0xff000000 ) >> 24 ) ) ); + idStr::snPrintf( s_chk, 3, "%02X", chk8 ); + if ( idStr::Icmp( l_chk[i_key], s_chk ) != 0 ) { + offline_valid[ i_key ] = false; + continue; + } + } + } + + if ( !offline_valid[ 0 ] || !offline_valid[1] ) { + return false; + } + + // offline checks passed, we'll return true and optionally emit key check requests + // the function should only modify the key states if the offline checks passed successfully + + // set the keys, don't send a game auth if we are net connecting + idStr::Copynz( cdkey, lkey[0], CDKEY_BUF_LEN ); + netConnect ? cdkey_state = CDKEY_OK : cdkey_state = CDKEY_CHECKING; + if ( fileSystem->HasD3XP() ) { + idStr::Copynz( xpkey, lkey[1], CDKEY_BUF_LEN ); + netConnect ? xpkey_state = CDKEY_OK : xpkey_state = CDKEY_CHECKING; + } else { + xpkey_state = CDKEY_NA; + } + if ( !netConnect ) { + EmitGameAuth(); + } + SetCDKeyGuiVars(); + + return true; +} + +/* +=============== +idSessionLocal::CDKeysAreValid +checking that the key is present and uses only valid characters +if d3xp is installed, check for a valid xpkey as well +emit an auth packet to the master if possible and needed +=============== +*/ +bool idSessionLocal::CDKeysAreValid( bool strict ) { + int i; + bool emitAuth = false; + + if ( cdkey_state == CDKEY_UNKNOWN ) { + if ( strlen( cdkey ) != CDKEY_BUF_LEN - 1 ) { + cdkey_state = CDKEY_INVALID; + } else { + for ( i = 0; i < CDKEY_BUF_LEN-1; i++ ) { + if ( !strchr( CDKEY_DIGITS, cdkey[i] ) ) { + cdkey_state = CDKEY_INVALID; + break; + } + } + } + if ( cdkey_state == CDKEY_UNKNOWN ) { + cdkey_state = CDKEY_CHECKING; + emitAuth = true; + } + } + if ( xpkey_state == CDKEY_UNKNOWN ) { + if ( fileSystem->HasD3XP() ) { + if ( strlen( xpkey ) != CDKEY_BUF_LEN -1 ) { + xpkey_state = CDKEY_INVALID; + } else { + for ( i = 0; i < CDKEY_BUF_LEN-1; i++ ) { + if ( !strchr( CDKEY_DIGITS, xpkey[i] ) ) { + xpkey_state = CDKEY_INVALID; + } + } + } + if ( xpkey_state == CDKEY_UNKNOWN ) { + xpkey_state = CDKEY_CHECKING; + emitAuth = true; + } + } else { + xpkey_state = CDKEY_NA; + } + } + if ( emitAuth ) { + EmitGameAuth(); + } + // make sure to keep the mainmenu gui up to date in case we made state changes + SetCDKeyGuiVars(); + if ( strict ) { + return cdkey_state == CDKEY_OK && ( xpkey_state == CDKEY_OK || xpkey_state == CDKEY_NA ); + } else { + return ( cdkey_state == CDKEY_OK || cdkey_state == CDKEY_CHECKING ) && ( xpkey_state == CDKEY_OK || xpkey_state == CDKEY_CHECKING || xpkey_state == CDKEY_NA ); + } +} + +/* +=============== +idSessionLocal::WaitingForGameAuth +=============== +*/ +bool idSessionLocal::WaitingForGameAuth( void ) { + return authEmitTimeout != 0; +} + +/* +=============== +idSessionLocal::CDKeysAuthReply +=============== +*/ +void idSessionLocal::CDKeysAuthReply( bool valid, const char *auth_msg ) { + assert( authEmitTimeout > 0 ); + if ( authWaitBox ) { + // close the wait box + StopBox(); + authWaitBox = false; + } + if ( !valid ) { + common->DPrintf( "auth key is invalid\n" ); + authMsg = auth_msg; + if ( cdkey_state == CDKEY_CHECKING ) { + cdkey_state = CDKEY_INVALID; + } + if ( xpkey_state == CDKEY_CHECKING ) { + xpkey_state = CDKEY_INVALID; + } + } else { + common->DPrintf( "client is authed in\n" ); + if ( cdkey_state == CDKEY_CHECKING ) { + cdkey_state = CDKEY_OK; + } + if ( xpkey_state == CDKEY_CHECKING ) { + xpkey_state = CDKEY_OK; + } + } + authEmitTimeout = 0; + SetCDKeyGuiVars(); +} + +/* +=============== +idSessionLocal::GetCurrentMapName +=============== +*/ +const char *idSessionLocal::GetCurrentMapName() { + return currentMapName.c_str(); +} + +/* +=============== +idSessionLocal::GetSaveGameVersion +=============== +*/ +int idSessionLocal::GetSaveGameVersion( void ) { + return savegameVersion; +} + +/* +=============== +idSessionLocal::GetAuthMsg +=============== +*/ +const char *idSessionLocal::GetAuthMsg( void ) { + return authMsg.c_str(); +} diff --git a/framework/Session.h b/framework/Session.h new file mode 100644 index 000000000..9a199c4a0 --- /dev/null +++ b/framework/Session.h @@ -0,0 +1,156 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SESSION_H__ +#define __SESSION_H__ + +/* +=============================================================================== + + The session is the glue that holds games together between levels. + +=============================================================================== +*/ + +// needed by the gui system for the load game menu +typedef struct { + short health; + short heartRate; + short stamina; + short combat; +} logStats_t; + +static const int MAX_LOGGED_STATS = 60 * 120; // log every half second + +typedef enum { + MSG_OK, + MSG_ABORT, + MSG_OKCANCEL, + MSG_YESNO, + MSG_PROMPT, + MSG_CDKEY, + MSG_INFO, + MSG_WAIT +} msgBoxType_t; + +typedef const char * (*HandleGuiCommand_t)( const char * ); + +class idSession { +public: + virtual ~idSession() {} + + // Called in an orderly fashion at system startup, + // so commands, cvars, files, etc are all available. + virtual void Init() = 0; + + // Shut down the session. + virtual void Shutdown() = 0; + + // Called on errors and game exits. + virtual void Stop() = 0; + + // Redraws the screen, handling games, guis, console, etc + // during normal once-a-frame updates, outOfSequence will be false, + // but when the screen is updated in a modal manner, as with utility + // output, the mouse cursor will be released if running windowed. + virtual void UpdateScreen( bool outOfSequence = true ) = 0; + + // Called when console prints happen, allowing the loading screen + // to redraw if enough time has passed. + virtual void PacifierUpdate() = 0; + + // Called every frame, possibly spinning in place if we are + // above maxFps, or we haven't advanced at least one demo frame. + // Returns the number of milliseconds since the last frame. + virtual void Frame() = 0; + + // Returns true if a multiplayer game is running. + // CVars and commands are checked differently in multiplayer mode. + virtual bool IsMultiplayer() = 0; + + // Processes the given event. + virtual bool ProcessEvent( const sysEvent_t *event ) = 0; + + // Activates the main menu + virtual void StartMenu( bool playIntro = false ) = 0; + + virtual void SetGUI( idUserInterface *gui, HandleGuiCommand_t handle ) = 0; + + // Updates gui and dispatched events to it + virtual void GuiFrameEvents() = 0; + + // fires up the optional GUI event, also returns them if you set wait to true + // if MSG_PROMPT and wait, returns the prompt string or NULL if aborted + // if MSG_CDKEY and want, returns the cd key or NULL if aborted + // network tells wether one should still run the network loop in a wait dialog + virtual const char *MessageBox( msgBoxType_t type, const char *message, const char *title = NULL, bool wait = false, const char *fire_yes = NULL, const char *fire_no = NULL, bool network = false ) = 0; + virtual void StopBox( void ) = 0; + // monitor this download in a progress box to either abort or completion + virtual void DownloadProgressBox( backgroundDownload_t *bgl, const char *title, int progress_start = 0, int progress_end = 100 ) = 0; + + virtual void SetPlayingSoundWorld() = 0; + + // this is used by the sound system when an OnDemand sound is loaded, so the game action + // doesn't advance and get things out of sync + virtual void TimeHitch( int msec ) = 0; + + // read and write the cd key data to files + // doesn't perform any validity checks + virtual void ReadCDKey( void ) = 0; + virtual void WriteCDKey( void ) = 0; + + // returns NULL for if xp is true and xp key is not valid or not present + virtual const char *GetCDKey( bool xp ) = 0; + + // check keys for validity when typed in by the user ( with checksum verification ) + // store the new set of keys if they are found valid + virtual bool CheckKey( const char *key, bool netConnect, bool offline_valid[ 2 ] ) = 0; + + // verify the current set of keys for validity + // strict -> keys in state CDKEY_CHECKING state are not ok + virtual bool CDKeysAreValid( bool strict ) = 0; + // wipe the key on file if the network check finds it invalid + virtual void ClearCDKey( bool valid[ 2 ] ) = 0; + + // configure gui variables for mainmenu.gui and cd key state + virtual void SetCDKeyGuiVars( void ) = 0; + + virtual bool WaitingForGameAuth( void ) = 0; + + // got reply from master about the keys. if !valid, auth_msg given + virtual void CDKeysAuthReply( bool valid, const char *auth_msg ) = 0; + + virtual const char *GetCurrentMapName( void ) = 0; + + virtual int GetSaveGameVersion( void ) = 0; + + // The render world and sound world used for this session. + idRenderWorld * rw; + idSoundWorld * sw; + + // The renderer and sound system will write changes to writeDemo. + // Demos can be recorded and played at the same time when splicing. + idDemoFile * readDemo; + idDemoFile * writeDemo; + int renderdemoVersion; +}; + +extern idSession * session; + +#endif /* !__SESSION_H__ */ diff --git a/framework/Session_local.h b/framework/Session_local.h new file mode 100644 index 000000000..07002d336 --- /dev/null +++ b/framework/Session_local.h @@ -0,0 +1,354 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SESSIONLOCAL_H__ +#define __SESSIONLOCAL_H__ + +/* + +IsConnectedToServer(); +IsGameLoaded(); +IsGuiActive(); +IsPlayingRenderDemo(); + +if connected to a server + if handshaking + if map loading + if in game +else if a game loaded + if in load game menu + if main menu up +else if playing render demo +else + if error dialog + full console + +*/ + +typedef struct { + usercmd_t cmd; + int consistencyHash; +} logCmd_t; + +struct fileTIME_T { + int index; + ID_TIME_T timeStamp; + + operator int() const { return timeStamp; } +}; + +typedef struct { + idDict serverInfo; + idDict syncedCVars; + idDict userInfo[MAX_ASYNC_CLIENTS]; + idDict persistentPlayerInfo[MAX_ASYNC_CLIENTS]; + usercmd_t mapSpawnUsercmd[MAX_ASYNC_CLIENTS]; // needed for tracking delta angles +} mapSpawnData_t; + +typedef enum { + TD_NO, + TD_YES, + TD_YES_THEN_QUIT +} timeDemo_t; + +const int USERCMD_PER_DEMO_FRAME = 2; +const int CONNECT_TRANSMIT_TIME = 1000; +const int MAX_LOGGED_USERCMDS = 60*60*60; // one hour of single player, 15 minutes of four player + +class idSessionLocal : public idSession { +public: + + idSessionLocal(); + virtual ~idSessionLocal(); + + virtual void Init(); + + virtual void Shutdown(); + + virtual void Stop(); + + virtual void UpdateScreen( bool outOfSequence = true ); + + virtual void PacifierUpdate(); + + virtual void Frame(); + + virtual bool IsMultiplayer(); + + virtual bool ProcessEvent( const sysEvent_t *event ); + + virtual void StartMenu( bool playIntro = false ); + virtual void ExitMenu(); + virtual void GuiFrameEvents(); + virtual void SetGUI( idUserInterface *gui, HandleGuiCommand_t handle ); + + virtual const char *MessageBox( msgBoxType_t type, const char *message, const char *title = NULL, bool wait = false, const char *fire_yes = NULL, const char *fire_no = NULL, bool network = false ); + virtual void StopBox( void ); + virtual void DownloadProgressBox( backgroundDownload_t *bgl, const char *title, int progress_start = 0, int progress_end = 100 ); + virtual void SetPlayingSoundWorld(); + + virtual void TimeHitch( int msec ); + + virtual void ReadCDKey( void ); + virtual void WriteCDKey( void ); + virtual const char *GetCDKey( bool xp ); + virtual bool CheckKey( const char *key, bool netConnect, bool offline_valid[ 2 ] ); + virtual bool CDKeysAreValid( bool strict ); + virtual void ClearCDKey( bool valid[ 2 ] ); + virtual void SetCDKeyGuiVars( void ); + virtual bool WaitingForGameAuth( void ); + virtual void CDKeysAuthReply( bool valid, const char *auth_msg ); + + virtual int GetSaveGameVersion( void ); + + virtual const char *GetCurrentMapName(); + + //===================================== + + int GetLocalClientNum(); + + void MoveToNewMap( const char *mapName ); + + // loads a map and starts a new game on it + void StartNewGame( const char *mapName, bool devmap = false ); + void PlayIntroGui(); + + void LoadSession( const char *name ); + void SaveSession( const char *name ); + + // called by Draw when the scene to scene wipe is still running + void DrawWipeModel(); + void StartWipe( const char *materialName, bool hold = false); + void CompleteWipe(); + void ClearWipe(); + + void ShowLoadingGui(); + + void ScrubSaveGameFileName( idStr &saveFileName ) const; + idStr GetAutoSaveName( const char *mapName ) const; + + bool LoadGame(const char *saveName); + bool SaveGame(const char *saveName, bool autosave = false); + + const char *GetAuthMsg( void ); + + //===================================== + + static idCVar com_showAngles; + static idCVar com_showTics; + static idCVar com_minTics; + static idCVar com_fixedTic; + static idCVar com_showDemo; + static idCVar com_skipGameDraw; + static idCVar com_aviDemoWidth; + static idCVar com_aviDemoHeight; + static idCVar com_aviDemoSamples; + static idCVar com_aviDemoTics; + static idCVar com_wipeSeconds; + static idCVar com_guid; + + static idCVar gui_configServerRate; + + int timeHitch; + + bool menuActive; + idSoundWorld * menuSoundWorld; // so the game soundWorld can be muted + + bool insideExecuteMapChange; // draw loading screen and update + // screen on prints + int bytesNeededForMapLoad; // + + // we don't want to redraw the loading screen for every single + // console print that happens + int lastPacifierTime; + + // this is the information required to be set before ExecuteMapChange() is called, + // which can be saved off at any time with the following commands so it can all be played back + mapSpawnData_t mapSpawnData; + idStr currentMapName; // for checking reload on same level + bool mapSpawned; // cleared on Stop() + + int numClients; // from serverInfo + + int logIndex; + logCmd_t loggedUsercmds[MAX_LOGGED_USERCMDS]; + int statIndex; + logStats_t loggedStats[MAX_LOGGED_STATS]; + int lastSaveIndex; + // each game tic, numClients usercmds will be added, until full + + bool insideUpdateScreen; // true while inside ::UpdateScreen() + + bool loadingSaveGame; // currently loading map from a SaveGame + idFile * savegameFile; // this is the savegame file to load from + int savegameVersion; + + idFile * cmdDemoFile; // if non-zero, we are reading commands from a file + + int latchedTicNumber; // set to com_ticNumber each frame + int lastGameTic; // while latchedTicNumber > lastGameTic, run game frames + int lastDemoTic; + bool syncNextGameFrame; + + + bool aviCaptureMode; // if true, screenshots will be taken and sound captured + idStr aviDemoShortName; // + float aviDemoFrameCount; + int aviTicStart; + + timeDemo_t timeDemo; + int timeDemoStartTime; + int numDemoFrames; // for timeDemo and demoShot + int demoTimeOffset; + renderView_t currentDemoRenderView; + // the next one will be read when + // com_frameTime + demoTimeOffset > currentDemoRenderView. + + // TODO: make this private (after sync networking removal and idnet tweaks) + idUserInterface * guiActive; + HandleGuiCommand_t guiHandle; + + idUserInterface * guiInGame; + idUserInterface * guiMainMenu; + idListGUI * guiMainMenu_MapList; // easy map list handling + idUserInterface * guiRestartMenu; + idUserInterface * guiLoading; + idUserInterface * guiIntro; + idUserInterface * guiGameOver; + idUserInterface * guiTest; + idUserInterface * guiTakeNotes; + + idUserInterface * guiMsg; + idUserInterface * guiMsgRestore; // store the calling GUI for restore + idStr msgFireBack[ 2 ]; + bool msgRunning; + int msgRetIndex; + bool msgIgnoreButtons; + + bool waitingOnBind; + + const idMaterial * whiteMaterial; + + const idMaterial * wipeMaterial; + int wipeStartTic; + int wipeStopTic; + bool wipeHold; + +#if ID_CONSOLE_LOCK + int emptyDrawCount; // watchdog to force the main menu to restart +#endif + + //===================================== + void Clear(); + + void DrawCmdGraph(); + void Draw(); + + void WriteCmdDemo( const char *name, bool save = false); + void StartPlayingCmdDemo( const char *demoName); + void TimeCmdDemo( const char *demoName); + void SaveCmdDemoToFile(idFile *file); + void LoadCmdDemoFromFile(idFile *file); + void StartRecordingRenderDemo( const char *name ); + void StopRecordingRenderDemo(); + void StartPlayingRenderDemo( idStr name ); + void StopPlayingRenderDemo(); + void CompressDemoFile( const char *scheme, const char *name ); + void TimeRenderDemo( const char *name, bool twice = false ); + void AVIRenderDemo( const char *name ); + void AVICmdDemo( const char *name ); + void AVIGame( const char *name ); + void BeginAVICapture( const char *name ); + void EndAVICapture(); + + void AdvanceRenderDemo( bool singleFrameOnly ); + void RunGameTic(); + + void FinishCmdLoad(); + void LoadLoadingGui(const char *mapName); + + void DemoShot( const char *name ); + + void TestGUI( const char *name ); + + int GetBytesNeededForMapLoad( const char *mapName ); + void SetBytesNeededForMapLoad( const char *mapName, int bytesNeeded ); + + void ExecuteMapChange( bool noFadeWipe = false ); + void UnloadMap(); + + // return true if we actually waiting on an auth reply + bool MaybeWaitOnCDKey( void ); + + //------------------ + // Session_menu.cpp + + idStrList loadGameList; + idStrList modsList; + + idUserInterface * GetActiveMenu(); + + void DispatchCommand( idUserInterface *gui, const char *menuCommand, bool doIngame = true ); + void MenuEvent( const sysEvent_t *event ); + bool HandleSaveGameMenuCommand( idCmdArgs &args, int &icmd ); + void HandleInGameCommands( const char *menuCommand ); + void HandleMainMenuCommands( const char *menuCommand ); + void HandleChatMenuCommands( const char *menuCommand ); + void HandleIntroMenuCommands( const char *menuCommand ); + void HandleRestartMenuCommands( const char *menuCommand ); + void HandleMsgCommands( const char *menuCommand ); + void HandleNoteCommands( const char *menuCommand ); + void GetSaveGameList( idStrList &fileList, idList &fileTimes ); + void TakeNotes( const char * p, bool extended = false ); + void UpdateMPLevelShot( void ); + + void SetSaveGameGuiVars( void ); + void SetMainMenuGuiVars( void ); + void SetModsMenuGuiVars( void ); + void SetMainMenuSkin( void ); + void SetPbMenuGuiVars( void ); + +private: + bool BoxDialogSanityCheck( void ); + void EmitGameAuth( void ); + + typedef enum { + CDKEY_UNKNOWN, // need to perform checks on the key + CDKEY_INVALID, // that key is wrong + CDKEY_OK, // valid + CDKEY_CHECKING, // sent a check request ( gameAuth only ) + CDKEY_NA // does not apply, xp key when xp is not present + } cdKeyState_t; + + static const int CDKEY_BUF_LEN = 17; + static const int CDKEY_AUTH_TIMEOUT = 5000; + + char cdkey[ CDKEY_BUF_LEN ]; + cdKeyState_t cdkey_state; + char xpkey[ CDKEY_BUF_LEN ]; + cdKeyState_t xpkey_state; + int authEmitTimeout; + bool authWaitBox; + + idStr authMsg; +}; + +extern idSessionLocal sessLocal; + +#endif /* !__SESSIONLOCAL_H__ */ diff --git a/framework/Session_menu.cpp b/framework/Session_menu.cpp new file mode 100644 index 000000000..3fa79945c --- /dev/null +++ b/framework/Session_menu.cpp @@ -0,0 +1,1645 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Session_local.h" + +idCVar idSessionLocal::gui_configServerRate( "gui_configServerRate", "0", CVAR_GUI | CVAR_ARCHIVE | CVAR_ROM | CVAR_INTEGER, "" ); + +// implements the setup for, and commands from, the main menu + +/* +============== +idSessionLocal::GetActiveMenu +============== +*/ +idUserInterface *idSessionLocal::GetActiveMenu( void ) { + return guiActive; +} + +/* +============== +idSessionLocal::StartMainMenu +============== +*/ +void idSessionLocal::StartMenu( bool playIntro ) { + if ( guiActive == guiMainMenu ) { + return; + } + + if ( readDemo ) { + // if we're playing a demo, esc kills it + UnloadMap(); + } + + // pause the game sound world + if ( sw != NULL && !sw->IsPaused() ) { + sw->Pause(); + } + + // start playing the menu sounds + soundSystem->SetPlayingSoundWorld( menuSoundWorld ); + + SetGUI( guiMainMenu, NULL ); + guiMainMenu->HandleNamedEvent( playIntro ? "playIntro" : "noIntro" ); + + + if(fileSystem->HasD3XP()) { + guiMainMenu->SetStateString("game_list", common->GetLanguageDict()->GetString( "#str_07202" )); + } else { + guiMainMenu->SetStateString("game_list", common->GetLanguageDict()->GetString( "#str_07212" )); + } + + console->Close(); + +} + +/* +================= +idSessionLocal::SetGUI +================= +*/ +void idSessionLocal::SetGUI( idUserInterface *gui, HandleGuiCommand_t handle ) { + const char *cmd; + + guiActive = gui; + guiHandle = handle; + if ( guiMsgRestore ) { + common->DPrintf( "idSessionLocal::SetGUI: cleared an active message box\n" ); + guiMsgRestore = NULL; + } + if ( !guiActive ) { + return; + } + + if ( guiActive == guiMainMenu ) { + SetSaveGameGuiVars(); + SetMainMenuGuiVars(); + } else if ( guiActive == guiRestartMenu ) { + SetSaveGameGuiVars(); + } + + sysEvent_t ev; + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_NONE; + + cmd = guiActive->HandleEvent( &ev, com_frameTime ); + guiActive->Activate( true, com_frameTime ); +} + +/* +=============== +idSessionLocal::ExitMenu +=============== +*/ +void idSessionLocal::ExitMenu( void ) { + guiActive = NULL; + + // go back to the game sounds + soundSystem->SetPlayingSoundWorld( sw ); + + // unpause the game sound world + if ( sw != NULL && sw->IsPaused() ) { + sw->UnPause(); + } +} + +/* +=============== +idListSaveGameCompare +=============== +*/ +ID_INLINE int idListSaveGameCompare( const fileTIME_T *a, const fileTIME_T *b ) { + return b->timeStamp - a->timeStamp; +} + +/* +=============== +idSessionLocal::GetSaveGameList +=============== +*/ +void idSessionLocal::GetSaveGameList( idStrList &fileList, idList &fileTimes ) { + int i; + idFileList *files; + + // NOTE: no fs_game_base for savegames + idStr game = cvarSystem->GetCVarString( "fs_game" ); + if( game.Length() ) { + files = fileSystem->ListFiles( "savegames", ".save", false, false, game ); + } else { + files = fileSystem->ListFiles( "savegames", ".save" ); + } + + fileList = files->GetList(); + fileSystem->FreeFileList( files ); + + for ( i = 0; i < fileList.Num(); i++ ) { + ID_TIME_T timeStamp; + + fileSystem->ReadFile( "savegames/" + fileList[i], NULL, &timeStamp ); + fileList[i].StripLeading( '/' ); + fileList[i].StripFileExtension(); + + fileTIME_T ft; + ft.index = i; + ft.timeStamp = timeStamp; + fileTimes.Append( ft ); + } + + fileTimes.Sort( idListSaveGameCompare ); +} + +/* +=============== +idSessionLocal::SetSaveGameGuiVars +=============== +*/ +void idSessionLocal::SetSaveGameGuiVars( void ) { + int i; + idStr name; + idStrList fileList; + idList fileTimes; + + loadGameList.Clear(); + fileList.Clear(); + fileTimes.Clear(); + + GetSaveGameList( fileList, fileTimes ); + + loadGameList.SetNum( fileList.Num() ); + for ( i = 0; i < fileList.Num(); i++ ) { + loadGameList[i] = fileList[fileTimes[i].index]; + + idLexer src(LEXFL_NOERRORS|LEXFL_NOSTRINGCONCAT); + if ( src.LoadFile( va("savegames/%s.txt", loadGameList[i].c_str()) ) ) { + idToken tok; + src.ReadToken( &tok ); + name = tok; + } else { + name = loadGameList[i]; + } + + name += "\t"; + + idStr date = Sys_TimeStampToStr( fileTimes[i].timeStamp ); + name += date; + + guiActive->SetStateString( va("loadgame_item_%i", i), name); + } + guiActive->DeleteStateVar( va("loadgame_item_%i", fileList.Num()) ); + + guiActive->SetStateString( "loadgame_sel_0", "-1" ); + guiActive->SetStateString( "loadgame_shot", "guis/assets/blankLevelShot" ); + +} + +/* +=============== +idSessionLocal::SetModsMenuGuiVars +=============== +*/ +void idSessionLocal::SetModsMenuGuiVars( void ) { + int i; + idModList *list = fileSystem->ListMods(); + + modsList.SetNum( list->GetNumMods() ); + + // Build the gui list + for ( i = 0; i < list->GetNumMods(); i++ ) { + guiActive->SetStateString( va("modsList_item_%i", i), list->GetDescription( i ) ); + modsList[i] = list->GetMod( i ); + } + guiActive->DeleteStateVar( va("modsList_item_%i", list->GetNumMods()) ); + guiActive->SetStateString( "modsList_sel_0", "-1" ); + + fileSystem->FreeModList( list ); +} + + +/* +=============== +idSessionLocal::SetMainMenuSkin +=============== +*/ +void idSessionLocal::SetMainMenuSkin( void ) { + // skins + idStr str = cvarSystem->GetCVarString( "mod_validSkins" ); + idStr uiSkin = cvarSystem->GetCVarString( "ui_skin" ); + idStr skin; + int skinId = 1; + int count = 1; + while ( str.Length() ) { + int n = str.Find( ";" ); + if ( n >= 0 ) { + skin = str.Left( n ); + str = str.Right( str.Length() - n - 1 ); + } else { + skin = str; + str = ""; + } + if ( skin.Icmp( uiSkin ) == 0 ) { + skinId = count; + } + count++; + } + + for ( int i = 0; i < count; i++ ) { + guiMainMenu->SetStateInt( va( "skin%i", i+1 ), 0 ); + } + guiMainMenu->SetStateInt( va( "skin%i", skinId ), 1 ); +} + +/* +=============== +idSessionLocal::SetPbMenuGuiVars +=============== +*/ +void idSessionLocal::SetPbMenuGuiVars( void ) { +} + +/* +=============== +idSessionLocal::SetMainMenuGuiVars +=============== +*/ +void idSessionLocal::SetMainMenuGuiVars( void ) { + + guiMainMenu->SetStateString( "serverlist_sel_0", "-1" ); + guiMainMenu->SetStateString( "serverlist_selid_0", "-1" ); + + guiMainMenu->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() ); + + // "inetGame" will hold a hand-typed inet address, which is not archived to a cvar + guiMainMenu->SetStateString( "inetGame", "" ); + + // key bind names + guiMainMenu->SetKeyBindingNames(); + + // flag for in-game menu + if ( mapSpawned ) { + guiMainMenu->SetStateString( "inGame", IsMultiplayer() ? "2" : "1" ); + } else { + guiMainMenu->SetStateString( "inGame", "0" ); + } + + SetCDKeyGuiVars( ); +#ifdef ID_DEMO_BUILD + guiMainMenu->SetStateString( "nightmare", "0" ); +#else + guiMainMenu->SetStateString( "nightmare", cvarSystem->GetCVarBool( "g_nightmare" ) ? "1" : "0" ); +#endif + guiMainMenu->SetStateString( "browser_levelshot", "guis/assets/splash/pdtempa" ); + + SetMainMenuSkin(); + // Mods Menu + SetModsMenuGuiVars(); + + guiMsg->SetStateString( "visible_hasxp", fileSystem->HasD3XP() ? "1" : "0" ); + +#if defined( __linux__ ) + guiMainMenu->SetStateString( "driver_prompt", "1" ); +#else + guiMainMenu->SetStateString( "driver_prompt", "0" ); +#endif + + SetPbMenuGuiVars(); +} + +/* +============== +idSessionLocal::HandleSaveGameMenuCommands +============== +*/ +bool idSessionLocal::HandleSaveGameMenuCommand( idCmdArgs &args, int &icmd ) { + + const char *cmd = args.Argv(icmd-1); + + if ( !idStr::Icmp( cmd, "loadGame" ) ) { + int choice = guiActive->State().GetInt("loadgame_sel_0"); + if ( choice >= 0 && choice < loadGameList.Num() ) { + sessLocal.LoadGame( loadGameList[choice] ); + } + return true; + } + + if ( !idStr::Icmp( cmd, "saveGame" ) ) { + const char *saveGameName = guiActive->State().GetString("saveGameName"); + if ( saveGameName && saveGameName[0] ) { + + // First see if the file already exists unless they pass '1' to authorize the overwrite + if ( icmd == args.Argc() || atoi(args.Argv( icmd++ )) == 0 ) { + idStr saveFileName = saveGameName; + sessLocal.ScrubSaveGameFileName( saveFileName ); + saveFileName = "savegames/" + saveFileName; + saveFileName.SetFileExtension(".save"); + + idStr game = cvarSystem->GetCVarString( "fs_game" ); + idFile *file; + if(game.Length()) { + file = fileSystem->OpenFileRead( saveFileName, true, game ); + } else { + file = fileSystem->OpenFileRead( saveFileName ); + } + + if ( file != NULL ) { + fileSystem->CloseFile( file ); + + // The file exists, see if it's an autosave + saveFileName.SetFileExtension(".txt"); + idLexer src(LEXFL_NOERRORS|LEXFL_NOSTRINGCONCAT); + if ( src.LoadFile( saveFileName ) ) { + idToken tok; + src.ReadToken( &tok ); // Name + src.ReadToken( &tok ); // Map + src.ReadToken( &tok ); // Screenshot + if ( !tok.IsEmpty() ) { + // NOTE: base/ gui doesn't handle that one + guiActive->HandleNamedEvent( "autosaveOverwriteError" ); + return true; + } + } + guiActive->HandleNamedEvent( "saveGameOverwrite" ); + return true; + } + } + + sessLocal.SaveGame( saveGameName ); + SetSaveGameGuiVars( ); + guiActive->StateChanged( com_frameTime ); + } + return true; + } + + if ( !idStr::Icmp( cmd, "deleteGame" ) ) { + int choice = guiActive->State().GetInt( "loadgame_sel_0" ); + if ( choice >= 0 && choice < loadGameList.Num() ) { + fileSystem->RemoveFile( va("savegames/%s.save", loadGameList[choice].c_str()) ); + fileSystem->RemoveFile( va("savegames/%s.tga", loadGameList[choice].c_str()) ); + fileSystem->RemoveFile( va("savegames/%s.txt", loadGameList[choice].c_str()) ); + SetSaveGameGuiVars( ); + guiActive->StateChanged( com_frameTime ); + } + return true; + } + + if ( !idStr::Icmp( cmd, "updateSaveGameInfo" ) ) { + int choice = guiActive->State().GetInt( "loadgame_sel_0" ); + if ( choice >= 0 && choice < loadGameList.Num() ) { + const idMaterial *material; + + idStr saveName, description, screenshot; + idLexer src(LEXFL_NOERRORS|LEXFL_NOSTRINGCONCAT); + if ( src.LoadFile( va("savegames/%s.txt", loadGameList[choice].c_str()) ) ) { + idToken tok; + + src.ReadToken( &tok ); + saveName = tok; + + src.ReadToken( &tok ); + description = tok; + + src.ReadToken( &tok ); + screenshot = tok; + + } else { + saveName = loadGameList[choice]; + description = loadGameList[choice]; + screenshot = ""; + } + if ( screenshot.Length() == 0 ) { + screenshot = va("savegames/%s.tga", loadGameList[choice].c_str()); + } + material = declManager->FindMaterial( screenshot ); + if ( material ) { + material->ReloadImages( false ); + } + guiActive->SetStateString( "loadgame_shot", screenshot ); + + saveName.RemoveColors(); + guiActive->SetStateString( "saveGameName", saveName ); + guiActive->SetStateString( "saveGameDescription", description ); + + ID_TIME_T timeStamp; + fileSystem->ReadFile( va("savegames/%s.save", loadGameList[choice].c_str()), NULL, &timeStamp ); + idStr date = Sys_TimeStampToStr(timeStamp); + int tab = date.Find( '\t' ); + idStr time = date.Right( date.Length() - tab - 1); + guiActive->SetStateString( "saveGameDate", date.Left( tab ) ); + guiActive->SetStateString( "saveGameTime", time ); + } + return true; + } + + return false; +} + +/* +============== +idSessionLocal::HandleRestartMenuCommands + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::HandleRestartMenuCommands( const char *menuCommand ) { + // execute the command from the menu + int icmd; + idCmdArgs args; + + args.TokenizeString( menuCommand, false ); + + for( icmd = 0; icmd < args.Argc(); ) { + const char *cmd = args.Argv( icmd++ ); + + if ( HandleSaveGameMenuCommand( args, icmd ) ) { + continue; + } + + if ( !idStr::Icmp( cmd, "restart" ) ) { + if ( !LoadGame( GetAutoSaveName( mapSpawnData.serverInfo.GetString("si_map") ) ) ) { + // If we can't load the autosave then just restart the map + MoveToNewMap( mapSpawnData.serverInfo.GetString("si_map") ); + } + continue; + } + + if ( !idStr::Icmp( cmd, "quit" ) ) { + ExitMenu(); + common->Quit(); + return; + } + + if ( !idStr::Icmp ( cmd, "exec" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, args.Argv( icmd++ ) ); + continue; + } + + if ( !idStr::Icmp( cmd, "play" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idStr snd = args.Argv(icmd++); + sw->PlayShaderDirectly(snd); + } + continue; + } + } +} + +/* +============== +idSessionLocal::HandleIntroMenuCommands + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::HandleIntroMenuCommands( const char *menuCommand ) { + // execute the command from the menu + int i; + idCmdArgs args; + + args.TokenizeString( menuCommand, false ); + + for( i = 0; i < args.Argc(); ) { + const char *cmd = args.Argv( i++ ); + + if ( !idStr::Icmp( cmd, "startGame" ) ) { + menuSoundWorld->ClearAllSoundEmitters(); + ExitMenu(); + continue; + } + + if ( !idStr::Icmp( cmd, "play" ) ) { + if ( args.Argc() - i >= 1 ) { + idStr snd = args.Argv(i++); + menuSoundWorld->PlayShaderDirectly(snd); + } + continue; + } + } +} + +/* +============== +idSessionLocal::UpdateMPLevelShot +============== +*/ +void idSessionLocal::UpdateMPLevelShot( void ) { + char screenshot[ MAX_STRING_CHARS ]; + fileSystem->FindMapScreenshot( cvarSystem->GetCVarString( "si_map" ), screenshot, MAX_STRING_CHARS ); + guiMainMenu->SetStateString( "current_levelshot", screenshot ); +} + +/* +============== +idSessionLocal::HandleMainMenuCommands + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::HandleMainMenuCommands( const char *menuCommand ) { + // execute the command from the menu + int icmd; + idCmdArgs args; + + args.TokenizeString( menuCommand, false ); + + for( icmd = 0; icmd < args.Argc(); ) { + const char *cmd = args.Argv( icmd++ ); + + if ( HandleSaveGameMenuCommand( args, icmd ) ) { + continue; + } + + // always let the game know the command is being run + if ( game ) { + game->HandleMainMenuCommands( cmd, guiActive ); + } + + if ( !idStr::Icmp( cmd, "startGame" ) ) { + cvarSystem->SetCVarInteger( "g_skill", guiMainMenu->State().GetInt( "skill" ) ); + if ( icmd < args.Argc() ) { + StartNewGame( args.Argv( icmd++ ) ); + } else { +#ifndef ID_DEMO_BUILD + StartNewGame( "game/mars_city1" ); +#else + StartNewGame( "game/demo_mars_city1" ); +#endif + } + // need to do this here to make sure com_frameTime is correct or the gui activates with a time that + // is "however long map load took" time in the past + common->GUIFrame( false, false ); + SetGUI( guiIntro, NULL ); + guiIntro->StateChanged( com_frameTime, true ); + // stop playing the game sounds + soundSystem->SetPlayingSoundWorld( menuSoundWorld ); + + continue; + } + + if ( !idStr::Icmp( cmd, "quit" ) ) { + ExitMenu(); + common->Quit(); + return; + } + + if ( !idStr::Icmp( cmd, "loadMod" ) ) { + int choice = guiActive->State().GetInt( "modsList_sel_0" ); + if ( choice >= 0 && choice < modsList.Num() ) { + cvarSystem->SetCVarString( "fs_game", modsList[ choice ] ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reloadEngine menu\n" ); + } + } + + if ( !idStr::Icmp( cmd, "UpdateServers" ) ) { + if ( guiActive->State().GetBool( "lanSet" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "LANScan" ); + } else { + idAsyncNetwork::GetNETServers(); + } + continue; + } + + if ( !idStr::Icmp( cmd, "RefreshServers" ) ) { + if ( guiActive->State().GetBool( "lanSet" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "LANScan" ); + } else { + idAsyncNetwork::client.serverList.NetScan( ); + } + continue; + } + + if ( !idStr::Icmp( cmd, "FilterServers" ) ) { + idAsyncNetwork::client.serverList.ApplyFilter( ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortServerName" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_SERVERNAME ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortGame" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_GAME ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortPlayers" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_PLAYERS ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortPing" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_PING ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortGameType" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_GAMETYPE ); + continue; + } + + if ( !idStr::Icmp( cmd, "sortMap" ) ) { + idAsyncNetwork::client.serverList.SetSorting( SORT_MAP ); + continue; + } + + if ( !idStr::Icmp( cmd, "serverList" ) ) { + idAsyncNetwork::client.serverList.GUIUpdateSelected(); + continue; + } + + if ( !idStr::Icmp( cmd, "LANConnect" ) ) { + int sel = guiActive->State().GetInt( "serverList_selid_0" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "Connect %d\n", sel ) ); + return; + } + + if ( !idStr::Icmp( cmd, "MAPScan" ) ) { + const char *gametype = cvarSystem->GetCVarString( "si_gameType" ); + if ( gametype == NULL || *gametype == 0 || idStr::Icmp( gametype, "singleplayer" ) == 0 ) { + gametype = "Deathmatch"; + } + + int i, num; + idStr si_map = cvarSystem->GetCVarString("si_map"); + const idDict *dict; + + guiMainMenu_MapList->Clear(); + guiMainMenu_MapList->SetSelection( 0 ); + num = fileSystem->GetNumMaps(); + for ( i = 0; i < num; i++ ) { + dict = fileSystem->GetMapDecl( i ); + if ( dict && dict->GetBool( gametype ) ) { + const char *mapName = dict->GetString( "name" ); + if ( mapName[ 0 ] == '\0' ) { + mapName = dict->GetString( "path" ); + } + mapName = common->GetLanguageDict()->GetString( mapName ); + guiMainMenu_MapList->Add( i, mapName ); + if ( !si_map.Icmp( dict->GetString( "path" ) ) ) { + guiMainMenu_MapList->SetSelection( guiMainMenu_MapList->Num() - 1 ); + } + } + } + i = guiMainMenu_MapList->GetSelection( NULL, 0 ); + if ( i >= 0 ) { + dict = fileSystem->GetMapDecl( i); + } else { + dict = NULL; + } + cvarSystem->SetCVarString( "si_map", ( dict ? dict->GetString( "path" ) : "" ) ); + + // set the current level shot + UpdateMPLevelShot(); + continue; + } + + if ( !idStr::Icmp( cmd, "click_mapList" ) ) { + int mapNum = guiMainMenu_MapList->GetSelection( NULL, 0 ); + const idDict *dict = fileSystem->GetMapDecl( mapNum ); + if ( dict ) { + cvarSystem->SetCVarString( "si_map", dict->GetString( "path" ) ); + } + UpdateMPLevelShot(); + continue; + } + + if ( !idStr::Icmp( cmd, "inetConnect" ) ) { + const char *s = guiMainMenu->State().GetString( "inetGame" ); + + if ( !s || s[0] == 0 ) { + // don't put the menu away if there isn't a valid selection + continue; + } + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "connect %s", s ) ); + return; + } + + if ( !idStr::Icmp( cmd, "startMultiplayer" ) ) { + int dedicated = guiActive->State().GetInt( "dedicated" ); + cvarSystem->SetCVarBool( "net_LANServer", guiActive->State().GetBool( "server_type" ) ); + if ( gui_configServerRate.GetInteger() > 0 ) { + // guess the best rate for upstream, number of internet clients + if ( gui_configServerRate.GetInteger() == 5 || cvarSystem->GetCVarBool( "net_LANServer" ) ) { + cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 25600 ); + } else { + // internet players + int n_clients = cvarSystem->GetCVarInteger( "si_maxPlayers" ); + if ( !dedicated ) { + n_clients--; + } + int maxclients = 0; + switch ( gui_configServerRate.GetInteger() ) { + case 1: + // 128 kbits + cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 8000 ); + maxclients = 2; + break; + case 2: + // 256 kbits + cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 9500 ); + maxclients = 3; + break; + case 3: + // 384 kbits + cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 10500 ); + maxclients = 4; + break; + case 4: + // 512 and above.. + cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 14000 ); + maxclients = 4; + break; + } + if ( n_clients > maxclients ) { + if ( MessageBox( MSG_OKCANCEL, va( common->GetLanguageDict()->GetString( "#str_04315" ), dedicated ? maxclients : Min( 8, maxclients + 1 ) ), common->GetLanguageDict()->GetString( "#str_04316" ), true, "OK" )[ 0 ] == '\0' ) { + continue; + } + cvarSystem->SetCVarInteger( "si_maxPlayers", dedicated ? maxclients : Min( 8, maxclients + 1 ) ); + } + } + } + + if ( !dedicated && !cvarSystem->GetCVarBool( "net_LANServer" ) && cvarSystem->GetCVarInteger("si_maxPlayers") > 4 ) { + // "Dedicated server mode is recommended for internet servers with more than 4 players. Continue in listen mode?" + if ( !MessageBox( MSG_YESNO, common->GetLanguageDict()->GetString ( "#str_00100625" ), common->GetLanguageDict()->GetString ( "#str_00100626" ), true, "yes" )[ 0 ] ) { + continue; + } + } + + if ( dedicated ) { + cvarSystem->SetCVarInteger( "net_serverDedicated", 1 ); + } else { + cvarSystem->SetCVarInteger( "net_serverDedicated", 0 ); + } + + + + ExitMenu(); + // may trigger a reloadEngine - APPEND + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "SpawnServer\n" ); + return; + } + + if ( !idStr::Icmp( cmd, "mpSkin")) { + idStr skin; + if ( args.Argc() - icmd >= 1 ) { + skin = args.Argv( icmd++ ); + cvarSystem->SetCVarString( "ui_skin", skin ); + SetMainMenuSkin(); + } + continue; + } + + if ( !idStr::Icmp( cmd, "close" ) ) { + // if we aren't in a game, the menu can't be closed + if ( mapSpawned ) { + ExitMenu(); + } + continue; + } + + if ( !idStr::Icmp( cmd, "resetdefaults" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "exec default.cfg" ); + guiMainMenu->SetKeyBindingNames(); + continue; + } + + + if ( !idStr::Icmp( cmd, "bind" ) ) { + if ( args.Argc() - icmd >= 2 ) { + int key = atoi( args.Argv( icmd++ ) ); + idStr bind = args.Argv( icmd++ ); + if ( idKeyInput::NumBinds( bind ) >= 2 && !idKeyInput::KeyIsBoundTo( key, bind ) ) { + idKeyInput::UnbindBinding( bind ); + } + idKeyInput::SetBinding( key, bind ); + guiMainMenu->SetKeyBindingNames(); + } + continue; + } + + if ( !idStr::Icmp( cmd, "play" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idStr snd = args.Argv( icmd++ ); + int channel = 1; + if ( snd.Length() == 1 ) { + channel = atoi( snd ); + snd = args.Argv( icmd++ ); + } + menuSoundWorld->PlayShaderDirectly( snd, channel ); + + } + continue; + } + + if ( !idStr::Icmp( cmd, "music" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idStr snd = args.Argv( icmd++ ); + menuSoundWorld->PlayShaderDirectly( snd, 2 ); + } + continue; + } + + // triggered from mainmenu or mpmain + if ( !idStr::Icmp( cmd, "sound" ) ) { + idStr vcmd; + if ( args.Argc() - icmd >= 1 ) { + vcmd = args.Argv( icmd++ ); + } + if ( !vcmd.Length() || !vcmd.Icmp( "speakers" ) ) { + int old = cvarSystem->GetCVarInteger( "s_numberOfSpeakers" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" ); + if ( old != cvarSystem->GetCVarInteger( "s_numberOfSpeakers" ) ) { +#ifdef _WIN32 + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04142" ), common->GetLanguageDict()->GetString( "#str_04141" ), true ); +#else + // a message that doesn't mention the windows control panel + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07230" ), common->GetLanguageDict()->GetString( "#str_04141" ), true ); +#endif + } + } + if ( !vcmd.Icmp( "eax" ) ) { + if ( cvarSystem->GetCVarBool( "s_useEAXReverb" ) ) { + int eax = soundSystem->IsEAXAvailable(); + switch ( eax ) { + case 2: + // OpenAL subsystem load failed + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07238" ), common->GetLanguageDict()->GetString( "#str_07231" ), true ); + break; + case 1: + // when you restart + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true ); + break; + case -1: + cvarSystem->SetCVarBool( "s_useEAXReverb", false ); + // disabled + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07233" ), common->GetLanguageDict()->GetString( "#str_07231" ), true ); + break; + case 0: + cvarSystem->SetCVarBool( "s_useEAXReverb", false ); + // not available + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07232" ), common->GetLanguageDict()->GetString( "#str_07231" ), true ); + break; + } + } else { + // also turn off OpenAL so we fully go back to legacy mixer + cvarSystem->SetCVarBool( "s_useOpenAL", false ); + // when you restart + MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true ); + } + } + if ( !vcmd.Icmp( "drivar" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" ); + } + continue; + } + + if ( !idStr::Icmp( cmd, "video" ) ) { + idStr vcmd; + if ( args.Argc() - icmd >= 1 ) { + vcmd = args.Argv( icmd++ ); + } + + int oldSpec = com_machineSpec.GetInteger(); + + if ( idStr::Icmp( vcmd, "low" ) == 0 ) { + com_machineSpec.SetInteger( 0 ); + } else if ( idStr::Icmp( vcmd, "medium" ) == 0 ) { + com_machineSpec.SetInteger( 1 ); + } else if ( idStr::Icmp( vcmd, "high" ) == 0 ) { + com_machineSpec.SetInteger( 2 ); + } else if ( idStr::Icmp( vcmd, "ultra" ) == 0 ) { + com_machineSpec.SetInteger( 3 ); + } else if ( idStr::Icmp( vcmd, "recommended" ) == 0 ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" ); + } + + if ( oldSpec != com_machineSpec.GetInteger() ) { + guiActive->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() ); + guiActive->StateChanged( com_frameTime ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "execMachineSpec\n" ); + } + + if ( idStr::Icmp( vcmd, "restart" ) == 0) { + guiActive->HandleNamedEvent( "cvar write render" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart\n" ); + } + + continue; + } + + if ( !idStr::Icmp( cmd, "clearBind" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idKeyInput::UnbindBinding( args.Argv( icmd++ ) ); + guiMainMenu->SetKeyBindingNames(); + } + continue; + } + + // FIXME: obsolete + if ( !idStr::Icmp( cmd, "chatdone" ) ) { + idStr temp = guiActive->State().GetString( "chattext" ); + temp += "\r"; + guiActive->SetStateString( "chattext", "" ); + continue; + } + + if ( !idStr::Icmp ( cmd, "exec" ) ) { + + //Backup the language so we can restore it after defaults. + idStr lang = cvarSystem->GetCVarString("sys_lang"); + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, args.Argv( icmd++ ) ); + if ( idStr::Icmp( "cvar_restart", args.Argv( icmd - 1 ) ) == 0 ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "exec default.cfg" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" ); + + //Make sure that any r_brightness changes take effect + float bright = cvarSystem->GetCVarFloat("r_brightness"); + cvarSystem->SetCVarFloat("r_brightness", 0.0f); + cvarSystem->SetCVarFloat("r_brightness", bright); + + //Force user info modified after a reset to defaults + cvarSystem->SetModifiedFlags(CVAR_USERINFO); + + guiActive->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() ); + + //Restore the language + cvarSystem->SetCVarString("sys_lang", lang); + + } + continue; + } + + if ( !idStr::Icmp ( cmd, "loadBinds" ) ) { + guiMainMenu->SetKeyBindingNames(); + continue; + } + + if ( !idStr::Icmp( cmd, "systemCvars" ) ) { + guiActive->HandleNamedEvent( "cvar read render" ); + guiActive->HandleNamedEvent( "cvar read sound" ); + continue; + } + + if ( !idStr::Icmp( cmd, "SetCDKey" ) ) { + // we can't do this from inside the HandleMainMenuCommands code, otherwise the message box stuff gets confused + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "promptKey\n" ); + continue; + } + + if ( !idStr::Icmp( cmd, "CheckUpdate" ) ) { + idAsyncNetwork::client.SendVersionCheck(); + continue; + } + + if ( !idStr::Icmp( cmd, "CheckUpdate2" ) ) { + idAsyncNetwork::client.SendVersionCheck( true ); + continue; + } + + if ( !idStr::Icmp( cmd, "checkKeys" ) ) { +#if ID_ENFORCE_KEY + // not a strict check so you silently auth in the background without bugging the user + if ( !session->CDKeysAreValid( false ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "promptKey force" ); + cmdSystem->ExecuteCommandBuffer(); + } +#endif + continue; + } + + // triggered from mainmenu or mpmain + if ( !idStr::Icmp( cmd, "punkbuster" ) ) { + idStr vcmd; + if ( args.Argc() - icmd >= 1 ) { + vcmd = args.Argv( icmd++ ); + } + // filtering PB based on enabled/disabled + idAsyncNetwork::client.serverList.ApplyFilter( ); + SetPbMenuGuiVars(); + continue; + } + } +} + +/* +============== +idSessionLocal::HandleChatMenuCommands + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::HandleChatMenuCommands( const char *menuCommand ) { + // execute the command from the menu + int i; + idCmdArgs args; + + args.TokenizeString( menuCommand, false ); + + for ( i = 0; i < args.Argc(); ) { + const char *cmd = args.Argv( i++ ); + + if ( idStr::Icmp( cmd, "chatactive" ) == 0 ) { + //chat.chatMode = CHAT_GLOBAL; + continue; + } + if ( idStr::Icmp( cmd, "chatabort" ) == 0 ) { + //chat.chatMode = CHAT_NONE; + continue; + } + if ( idStr::Icmp( cmd, "netready" ) == 0 ) { + bool b = cvarSystem->GetCVarBool( "ui_ready" ); + cvarSystem->SetCVarBool( "ui_ready", !b ); + continue; + } + if ( idStr::Icmp( cmd, "netstart" ) == 0 ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "netcommand start\n" ); + continue; + } + } +} + +/* +============== +idSessionLocal::HandleInGameCommands + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::HandleInGameCommands( const char *menuCommand ) { + // execute the command from the menu + idCmdArgs args; + + args.TokenizeString( menuCommand, false ); + + const char *cmd = args.Argv( 0 ); + if ( !idStr::Icmp( cmd, "close" ) ) { + if ( guiActive ) { + sysEvent_t ev; + ev.evType = SE_NONE; + const char *cmd; + cmd = guiActive->HandleEvent( &ev, com_frameTime ); + guiActive->Activate( false, com_frameTime ); + guiActive = NULL; + } + } +} + +/* +============== +idSessionLocal::DispatchCommand +============== +*/ +void idSessionLocal::DispatchCommand( idUserInterface *gui, const char *menuCommand, bool doIngame ) { + + if ( !gui ) { + gui = guiActive; + } + + if ( gui == guiMainMenu ) { + HandleMainMenuCommands( menuCommand ); + return; + } else if ( gui == guiIntro) { + HandleIntroMenuCommands( menuCommand ); + } else if ( gui == guiMsg ) { + HandleMsgCommands( menuCommand ); + } else if ( gui == guiTakeNotes ) { + HandleNoteCommands( menuCommand ); + } else if ( gui == guiRestartMenu ) { + HandleRestartMenuCommands( menuCommand ); + } else if ( game && guiActive && guiActive->State().GetBool( "gameDraw" ) ) { + const char *cmd = game->HandleGuiCommands( menuCommand ); + if ( !cmd ) { + guiActive = NULL; + } else if ( idStr::Icmp( cmd, "main" ) == 0 ) { + StartMenu(); + } else if ( strstr( cmd, "sound " ) == cmd ) { + // pipe the GUI sound commands not handled by the game to the main menu code + HandleMainMenuCommands( cmd ); + } + } else if ( guiHandle ) { + if ( (*guiHandle)( menuCommand ) ) { + return; + } + } else if ( !doIngame ) { + common->DPrintf( "idSessionLocal::DispatchCommand: no dispatch found for command '%s'\n", menuCommand ); + } + + if ( doIngame ) { + HandleInGameCommands( menuCommand ); + } +} + + +/* +============== +idSessionLocal::MenuEvent + +Executes any commands returned by the gui +============== +*/ +void idSessionLocal::MenuEvent( const sysEvent_t *event ) { + const char *menuCommand; + + if ( guiActive == NULL ) { + return; + } + + menuCommand = guiActive->HandleEvent( event, com_frameTime ); + + if ( !menuCommand || !menuCommand[0] ) { + // If the menu didn't handle the event, and it's a key down event for an F key, run the bind + if ( event->evType == SE_KEY && event->evValue2 == 1 && event->evValue >= K_F1 && event->evValue <= K_F12 ) { + idKeyInput::ExecKeyBinding( event->evValue ); + } + return; + } + + DispatchCommand( guiActive, menuCommand ); +} + +/* +================= +idSessionLocal::GuiFrameEvents +================= +*/ +void idSessionLocal::GuiFrameEvents() { + const char *cmd; + sysEvent_t ev; + idUserInterface *gui; + + // stop generating move and button commands when a local console or menu is active + // running here so SP, async networking and no game all go through it + if ( console->Active() || guiActive ) { + usercmdGen->InhibitUsercmd( INHIBIT_SESSION, true ); + } else { + usercmdGen->InhibitUsercmd( INHIBIT_SESSION, false ); + } + + if ( guiTest ) { + gui = guiTest; + } else if ( guiActive ) { + gui = guiActive; + } else { + return; + } + + memset( &ev, 0, sizeof( ev ) ); + + ev.evType = SE_NONE; + cmd = gui->HandleEvent( &ev, com_frameTime ); + if ( cmd && cmd[0] ) { + DispatchCommand( guiActive, cmd ); + } +} + +/* +================= +idSessionLocal::BoxDialogSanityCheck +================= +*/ +bool idSessionLocal::BoxDialogSanityCheck( void ) { + if ( !common->IsInitialized() ) { + common->DPrintf( "message box sanity check: !common->IsInitialized()\n" ); + return false; + } + if ( !guiMsg ) { + return false; + } + if ( guiMsgRestore ) { + common->DPrintf( "message box sanity check: recursed\n" ); + return false; + } + if ( cvarSystem->GetCVarInteger( "net_serverDedicated" ) ) { + common->DPrintf( "message box sanity check: not compatible with dedicated server\n" ); + return false; + } + return true; +} + +/* +================= +idSessionLocal::MessageBox +================= +*/ +const char* idSessionLocal::MessageBox( msgBoxType_t type, const char *message, const char *title, bool wait, const char *fire_yes, const char *fire_no, bool network ) { + + common->DPrintf( "MessageBox: %s - %s\n", title ? title : "", message ? message : "" ); + + if ( !BoxDialogSanityCheck() ) { + return NULL; + } + + guiMsg->SetStateString( "title", title ? title : "" ); + guiMsg->SetStateString( "message", message ? message : "" ); + if ( type == MSG_WAIT ) { + guiMsg->SetStateString( "visible_msgbox", "0" ); + guiMsg->SetStateString( "visible_waitbox", "1" ); + } else { + guiMsg->SetStateString( "visible_msgbox", "1" ); + guiMsg->SetStateString( "visible_waitbox", "0" ); + } + + guiMsg->SetStateString( "visible_entry", "0" ); + guiMsg->SetStateString( "visible_cdkey", "0" ); + switch ( type ) { + case MSG_INFO: + guiMsg->SetStateString( "mid", "" ); + guiMsg->SetStateString( "visible_mid", "0" ); + guiMsg->SetStateString( "visible_left", "0" ); + guiMsg->SetStateString( "visible_right", "0" ); + break; + case MSG_OK: + guiMsg->SetStateString( "mid", common->GetLanguageDict()->GetString( "#str_04339" ) ); + guiMsg->SetStateString( "visible_mid", "1" ); + guiMsg->SetStateString( "visible_left", "0" ); + guiMsg->SetStateString( "visible_right", "0" ); + break; + case MSG_ABORT: + guiMsg->SetStateString( "mid", common->GetLanguageDict()->GetString( "#str_04340" ) ); + guiMsg->SetStateString( "visible_mid", "1" ); + guiMsg->SetStateString( "visible_left", "0" ); + guiMsg->SetStateString( "visible_right", "0" ); + break; + case MSG_OKCANCEL: + guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) ); + guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) ); + guiMsg->SetStateString( "visible_mid", "0" ); + guiMsg->SetStateString( "visible_left", "1" ); + guiMsg->SetStateString( "visible_right", "1" ); + break; + case MSG_YESNO: + guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04341" ) ); + guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04342" ) ); + guiMsg->SetStateString( "visible_mid", "0" ); + guiMsg->SetStateString( "visible_left", "1" ); + guiMsg->SetStateString( "visible_right", "1" ); + break; + case MSG_PROMPT: + guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) ); + guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) ); + guiMsg->SetStateString( "visible_mid", "0" ); + guiMsg->SetStateString( "visible_left", "1" ); + guiMsg->SetStateString( "visible_right", "1" ); + guiMsg->SetStateString( "visible_entry", "1" ); + guiMsg->HandleNamedEvent( "Prompt" ); + break; + case MSG_CDKEY: + guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) ); + guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) ); + guiMsg->SetStateString( "visible_msgbox", "0" ); + guiMsg->SetStateString( "visible_cdkey", "1" ); + guiMsg->SetStateString( "visible_hasxp", fileSystem->HasD3XP() ? "1" : "0" ); + // the current cdkey / xpkey values may have bad/random data in them + // it's best to avoid printing them completely, unless the key is good + if ( cdkey_state == CDKEY_OK ) { + guiMsg->SetStateString( "str_cdkey", cdkey ); + guiMsg->SetStateString( "visible_cdchk", "0" ); + } else { + guiMsg->SetStateString( "str_cdkey", "" ); + guiMsg->SetStateString( "visible_cdchk", "1" ); + } + guiMsg->SetStateString( "str_cdchk", "" ); + if ( xpkey_state == CDKEY_OK ) { + guiMsg->SetStateString( "str_xpkey", xpkey ); + guiMsg->SetStateString( "visible_xpchk", "0" ); + } else { + guiMsg->SetStateString( "str_xpkey", "" ); + guiMsg->SetStateString( "visible_xpchk", "1" ); + } + guiMsg->SetStateString( "str_xpchk", "" ); + guiMsg->HandleNamedEvent( "CDKey" ); + break; + case MSG_WAIT: + break; + default: + common->Printf( "idSessionLocal::MessageBox: unknown msg box type\n" ); + } + msgFireBack[ 0 ] = fire_yes ? fire_yes : ""; + msgFireBack[ 1 ] = fire_no ? fire_no : ""; + guiMsgRestore = guiActive; + guiActive = guiMsg; + guiMsg->SetCursor( 325, 290 ); + guiActive->Activate( true, com_frameTime ); + msgRunning = true; + msgRetIndex = -1; + + if ( wait ) { + // play one frame ignoring events so we don't get confused by parasite button releases + msgIgnoreButtons = true; + common->GUIFrame( true, network ); + msgIgnoreButtons = false; + while ( msgRunning ) { + common->GUIFrame( true, network ); + } + if ( msgRetIndex < 0 ) { + // MSG_WAIT and other StopBox calls + return NULL; + } + if ( type == MSG_PROMPT ) { + if ( msgRetIndex == 0 ) { + guiMsg->State().GetString( "str_entry", "", msgFireBack[ 0 ] ); + return msgFireBack[ 0 ].c_str(); + } else { + return NULL; + } + } else if ( type == MSG_CDKEY ) { + if ( msgRetIndex == 0 ) { + // the visible_ values distinguish looking at a valid key, or editing it + sprintf( msgFireBack[ 0 ], "%1s;%16s;%2s;%1s;%16s;%2s", + guiMsg->State().GetString( "visible_cdchk" ), + guiMsg->State().GetString( "str_cdkey" ), + guiMsg->State().GetString( "str_cdchk" ), + guiMsg->State().GetString( "visible_xpchk" ), + guiMsg->State().GetString( "str_xpkey" ), + guiMsg->State().GetString( "str_xpchk" ) ); + return msgFireBack[ 0 ].c_str(); + } else { + return NULL; + } + } else { + return msgFireBack[ msgRetIndex ].c_str(); + } + } + return NULL; +} + +/* +================= +idSessionLocal::DownloadProgressBox +================= +*/ +void idSessionLocal::DownloadProgressBox( backgroundDownload_t *bgl, const char *title, int progress_start, int progress_end ) { + int dlnow = 0, dltotal = 0; + int startTime = Sys_Milliseconds(); + int lapsed; + idStr sNow, sTotal, sBW, sETA, sMsg; + + if ( !BoxDialogSanityCheck() ) { + return; + } + + guiMsg->SetStateString( "visible_msgbox", "1" ); + guiMsg->SetStateString( "visible_waitbox", "0" ); + + guiMsg->SetStateString( "visible_entry", "0" ); + guiMsg->SetStateString( "visible_cdkey", "0" ); + + guiMsg->SetStateString( "mid", "Cancel" ); + guiMsg->SetStateString( "visible_mid", "1" ); + guiMsg->SetStateString( "visible_left", "0" ); + guiMsg->SetStateString( "visible_right", "0" ); + + guiMsg->SetStateString( "title", title ); + guiMsg->SetStateString( "message", "Connecting.." ); + + guiMsgRestore = guiActive; + guiActive = guiMsg; + msgRunning = true; + + while ( 1 ) { + while ( msgRunning ) { + common->GUIFrame( true, false ); + if ( bgl->completed ) { + guiActive = guiMsgRestore; + guiMsgRestore = NULL; + return; + } else if ( bgl->url.dltotal != dltotal || bgl->url.dlnow != dlnow ) { + dltotal = bgl->url.dltotal; + dlnow = bgl->url.dlnow; + lapsed = Sys_Milliseconds() - startTime; + sNow.BestUnit( "%.2f", dlnow, MEASURE_SIZE ); + if ( lapsed > 2000 ) { + sBW.BestUnit( "%.1f", ( 1000.0f * dlnow ) / lapsed, MEASURE_BANDWIDTH ); + } else { + sBW = "-- KB/s"; + } + if ( dltotal ) { + sTotal.BestUnit( "%.2f", dltotal, MEASURE_SIZE ); + if ( lapsed < 2000 ) { + sprintf( sMsg, "%s / %s", sNow.c_str(), sTotal.c_str() ); + } else { + sprintf( sETA, "%.0f sec", ( (float)dltotal / (float)dlnow - 1.0f ) * lapsed / 1000 ); + sprintf( sMsg, "%s / %s ( %s - %s )", sNow.c_str(), sTotal.c_str(), sBW.c_str(), sETA.c_str() ); + } + } else { + if ( lapsed < 2000 ) { + sMsg = sNow; + } else { + sprintf( sMsg, "%s - %s", sNow.c_str(), sBW.c_str() ); + } + } + if ( dltotal ) { + guiMsg->SetStateString( "progress", va( "%d", progress_start + dlnow * ( progress_end - progress_start ) / dltotal ) ); + } else { + guiMsg->SetStateString( "progress", "0" ); + } + guiMsg->SetStateString( "message", sMsg.c_str() ); + } + } + // abort was used - tell the downloader and wait till final stop + bgl->url.status = DL_ABORTING; + guiMsg->SetStateString( "title", "Aborting.." ); + guiMsg->SetStateString( "visible_mid", "0" ); + // continue looping + guiMsgRestore = guiActive; + guiActive = guiMsg; + msgRunning = true; + } +} + +/* +================= +idSessionLocal::StopBox +================= +*/ +void idSessionLocal::StopBox() { + if ( guiActive == guiMsg ) { + HandleMsgCommands( "stop" ); + } +} + +/* +================= +idSessionLocal::HandleMsgCommands +================= +*/ +void idSessionLocal::HandleMsgCommands( const char *menuCommand ) { + assert( guiActive == guiMsg ); + // "stop" works even on first frame + if ( idStr::Icmp( menuCommand, "stop" ) == 0 ) { + // force hiding the current dialog + guiActive = guiMsgRestore; + guiMsgRestore = NULL; + msgRunning = false; + msgRetIndex = -1; + } + if ( msgIgnoreButtons ) { + common->DPrintf( "MessageBox HandleMsgCommands 1st frame ignore\n" ); + return; + } + if ( idStr::Icmp( menuCommand, "mid" ) == 0 || idStr::Icmp( menuCommand, "left" ) == 0 ) { + guiActive = guiMsgRestore; + guiMsgRestore = NULL; + msgRunning = false; + msgRetIndex = 0; + DispatchCommand( guiActive, msgFireBack[ 0 ].c_str() ); + } else if ( idStr::Icmp( menuCommand, "right" ) == 0 ) { + guiActive = guiMsgRestore; + guiMsgRestore = NULL; + msgRunning = false; + msgRetIndex = 1; + DispatchCommand( guiActive, msgFireBack[ 1 ].c_str() ); + } +} + +/* +================= +idSessionLocal::HandleNoteCommands +================= +*/ +#define NOTEDATFILE "C:/notenumber.dat" + +void idSessionLocal::HandleNoteCommands( const char *menuCommand ) { + guiActive = NULL; + + if ( idStr::Icmp( menuCommand, "note" ) == 0 && mapSpawned ) { + + idFile *file = NULL; + for ( int tries = 0; tries < 10; tries++ ) { + file = fileSystem->OpenExplicitFileRead( NOTEDATFILE ); + if ( file != NULL ) { + break; + } + Sys_Sleep( 500 ); + } + int noteNumber = 1000; + if ( file ) { + file->Read( ¬eNumber, 4 ); + fileSystem->CloseFile( file ); + } + + int i; + idStr str, noteNum, shotName, workName, fileName = "viewnotes/"; + idStrList fileList; + + const char *severity = NULL; + const char *p = guiTakeNotes->State().GetString( "notefile" ); + if ( p == NULL || *p == '\0' ) { + p = cvarSystem->GetCVarString( "ui_name" ); + } + + bool extended = guiTakeNotes->State().GetBool( "extended" ); + if ( extended ) { + if ( guiTakeNotes->State().GetInt( "severity" ) == 1 ) { + severity = "WishList_Viewnotes/"; + } else { + severity = "MustFix_Viewnotes/"; + } + fileName += severity; + + const idDecl *mapDecl = declManager->FindType(DECL_ENTITYDEF, mapSpawnData.serverInfo.GetString( "si_map" ), false ); + const idDeclEntityDef *mapInfo = static_cast(mapDecl); + + if ( mapInfo ) { + fileName += mapInfo->dict.GetString( "devname" ); + } else { + fileName += mapSpawnData.serverInfo.GetString( "si_map" ); + fileName.StripFileExtension(); + } + + int count = guiTakeNotes->State().GetInt( "person_numsel" ); + if ( count == 0 ) { + fileList.Append( fileName + "/Nobody" ); + } else { + for ( i = 0; i < count; i++ ) { + int person = guiTakeNotes->State().GetInt( va( "person_sel_%i", i ) ); + workName = fileName + "/"; + workName += guiTakeNotes->State().GetString( va( "person_item_%i", person ), "Nobody" ); + fileList.Append( workName ); + } + } + } else { + fileName += "maps/"; + fileName += mapSpawnData.serverInfo.GetString( "si_map" ); + fileName.StripFileExtension(); + fileList.Append( fileName ); + } + + bool bCon = cvarSystem->GetCVarBool( "con_noPrint" ); + cvarSystem->SetCVarBool( "con_noPrint", true ); + for ( i = 0; i < fileList.Num(); i++ ) { + workName = fileList[i]; + workName += "/"; + workName += p; + int workNote = noteNumber; + R_ScreenshotFilename( workNote, workName, shotName ); + + noteNum = shotName; + noteNum.StripPath(); + noteNum.StripFileExtension(); + + if ( severity && *severity ) { + workName = severity; + workName += "viewNotes"; + } + + sprintf( str, "recordViewNotes \"%s\" \"%s\" \"%s\"\n", workName.c_str(), noteNum.c_str(), guiTakeNotes->State().GetString( "note" ) ); + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, str ); + cmdSystem->ExecuteCommandBuffer(); + + UpdateScreen(); + renderSystem->TakeScreenshot( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight(), shotName, 1, NULL ); + } + noteNumber++; + + for ( int tries = 0; tries < 10; tries++ ) { + file = fileSystem->OpenExplicitFileWrite( "p:/viewnotes/notenumber.dat" ); + if ( file != NULL ) { + break; + } + Sys_Sleep( 500 ); + } + if ( file ) { + file->Write( ¬eNumber, 4 ); + fileSystem->CloseFile( file ); + } + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "closeViewNotes\n" ); + cvarSystem->SetCVarBool( "con_noPrint", bCon ); + } +} + +/* +=============== +idSessionLocal::SetCDKeyGuiVars +=============== +*/ +void idSessionLocal::SetCDKeyGuiVars( void ) { + if ( !guiMainMenu ) { + return; + } + guiMainMenu->SetStateString( "str_d3key_state", common->GetLanguageDict()->GetString( va( "#str_071%d", 86 + cdkey_state ) ) ); + guiMainMenu->SetStateString( "str_xpkey_state", common->GetLanguageDict()->GetString( va( "#str_071%d", 86 + xpkey_state ) ) ); +} diff --git a/framework/Unzip.cpp b/framework/Unzip.cpp new file mode 100644 index 000000000..4640cf23a --- /dev/null +++ b/framework/Unzip.cpp @@ -0,0 +1,4470 @@ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Unzip.h" + +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.3, July 9th, 1998 + + Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-1998 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +#define OF(args) args +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ +typedef Byte *voidp; + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#endif /* _ZCONF_H */ + +#define ZLIB_VERSION "1.1.3" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +const char * zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +int deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +int deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +int deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +int inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +int inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +int inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +int deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +int deflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +int deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +int deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +int deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +int inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +int inflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +int inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +int inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +int compress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +int compress2 OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +int uncompress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +gzFile gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +gzFile gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +int gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +int gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +int gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +int gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +int gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +char * gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +int gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +int gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +int gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +long gzseek OF((gzFile file, + long offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +int gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +long gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +int gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +int gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +const char * gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +uLong adler32 OF((uLong adler, const Byte *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +uLong crc32 OF((uLong crc, const Byte *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +int deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +int inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +int deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +int inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +const char * zError OF((int err)); +int inflateSyncPoint OF((z_streamp z)); +const uLong * get_crc_table OF((void)); + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#define zmemcpy memcpy +#define zmemcmp memcmp +#define zmemzero(dest, len) memset(dest, 0, len) + +/* Diagnostic functions */ +#ifdef _ZIP_DEBUG_ + int z_verbose = 0; +# define Assert(cond,msg) assert(cond); + //{if(!(cond)) Sys_Error(msg);} +# define Trace(x) {if (z_verbose>=0) Sys_Error x ;} +# define Tracev(x) {if (z_verbose>0) Sys_Error x ;} +# define Tracevv(x) {if (z_verbose>1) Sys_Error x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len)); +voidp zcalloc OF((voidp opaque, unsigned items, unsigned size)); +void zcfree OF((voidp opaque, voidp ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (65536) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (Mem_Alloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) Mem_Free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + +/* +static int unzlocal_getByte(FILE *fin,int *pi) +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} +*/ + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +static int unzlocal_getShort (FILE* fin, uLong *pX) +{ + short v; + + fread( &v, sizeof(v), 1, fin ); + + *pX = LittleShort( v); + return UNZ_OK; + +/* + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +*/ +} + +static int unzlocal_getLong (FILE *fin, uLong *pX) +{ + int v; + + fread( &v, sizeof(v), 1, fin ); + + *pX = LittleLong( v); + return UNZ_OK; + +/* + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +*/ +} + + +/* My own strcmpi / strcasecmp */ +static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity) +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +static uLong unzlocal_SearchCentralDir(FILE *fin) +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) + return 0; + + + uSizeFile = ftell( fin ); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) + break; + + if (fread(buf,(uInt)uReadSize,1,fin)!=1) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +extern unzFile unzReOpen (const char* path, unzFile file) +{ + unz_s *s; + FILE * fin; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + s=(unz_s*)ALLOC(sizeof(unz_s)); + memcpy(s, (unz_s*)file, sizeof(unz_s)); + + s->file = fin; + s->pfile_in_zip_read = NULL; + + return (unzFile)s; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile unzOpen (const char* path) +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + FILE * fin ; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + fclose(s->file); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +static int unzlocal_GetCurrentFileInfoInternal (unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int unzGetCurrentFileInfo ( unzFile file, unz_file_info *pfile_info, + char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int unzGoToNextFile (unzFile file) +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Get the position of the info of the current file in the zip. + return UNZ_OK if there is no problem +*/ +extern int unzGetCurrentFileInfoPosition (unzFile file, unsigned long *pos ) +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + *pos = s->pos_in_central_dir; + return UNZ_OK; +} + +/* + Set the position of the info of the current file in the zip. + return UNZ_OK if there is no problem +*/ +extern int unzSetCurrentFileInfoPosition (unzFile file, unsigned long pos ) +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return UNZ_OK; +} + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz_s* s; + int err; + + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the static header of the current zipfile + Check the coherency of the static header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in static header + (filename and size of extra field data) +*/ +static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, + uLong *poffset_local_extrafield, + uInt *psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int unzOpenCurrentFile (unzFile file) +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the static extra field */ + uInt size_local_extrafield; /* size of the static extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidp)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int unzReadCurrentFile (unzFile file, void *buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Byte*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed) + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Byte*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Byte *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern long unztell (unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (long)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int unzeof (unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the static-header version of the extra field (sometimes, there is + more info in the static-header version than in the central-header) + + if buf==NULL, it return the size of the static extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) +{ + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifdef DYNAMIC_CRC_TABLE + +static int crc_table_empty = 1; +static uLong crc_table[256]; +static void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +static const uLong crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLong * get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLong *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(uLong crc, const Byte *buf, uInt len) +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +static const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uInt *, /* 19 code lengths */ + uInt *, /* bits tree desired/actual depth */ + inflate_huft * *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uInt *, /* that many (total) code lengths */ + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + z_streamp)); /* for memory allocation */ + + +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uInt *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Byte *window; /* sliding window */ + Byte *end; /* one byte after sliding window */ + Byte *read; /* window read pointer */ + Byte *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load static pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +static /* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +#endif + + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); + Tracev(("inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev(("inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev(("inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev(("inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev(("inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev(("inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; +#ifdef MACOS_X // Optimization + if (t>64) { + zmemcpy(q, p, t); + } + else { + int t1; + for (t1=0; t1sub.left -= t) != 0) + break; + Tracev(("inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev(("inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + ZFREE(z, s->sub.trees.blens); + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev(("inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + ZFREE(z, s->sub.trees.blens); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev(("inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev(("inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev(("inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n) +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(inflate_blocks_statef *s) +{ + return s->mode == LENS; +} + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt n; + Byte *p; + Byte *q; + + /* static copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as as end of window */ +#ifdef MACOS_X // Optimization + if (n>64) { + zmemcpy(p, q, n); + } + else { + int t1; + for (t1=0; t1end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ +#ifdef MACOS_X // Optimization + if (n>64) { + zmemcpy(p, q, n); + } + else { + int t1; + for (t1=0; t1next_out = p; + s->read = q; + + /* done */ + return r; +} + +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +const char inflate_copyright[] = + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +static int huft_build OF(( + uInt *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uInt *, /* list of base values for non-simple codes */ + const uInt *, /* list of extra bits for non-simple codes */ + inflate_huft **, /* result: starting table */ + uInt *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uInt * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +static const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v) +//uInt *b; /* code lengths in bits (all assumed <= BMAX) */ +//uInt n; /* number of codes (assumed <= 288) */ +//uInt s; /* number of simple-valued codes (0..s-1) */ +//const uInt *d; /* list of base values for non-simple codes */ +//const uInt *e; /* list of extra bits for non-simple codes */ +//inflate_huft ** t; /* result: starting table */ +//uInt *m; /* maximum lookup bits, returns actual */ +//inflate_huft *hp; /* space for trees */ +//uInt *hn; /* hufts used in space */ +//uInt *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uInt *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uInt *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_MEM_ERROR; /* not enough memory */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z) +//uInt *c; /* 19 code lengths */ +//uInt *bb; /* bits tree desired/actual depth */ +//inflate_huft * *tb; /* bits tree result */ +//inflate_huft *hp; /* space for trees */ +//z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ + + if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z) +//uInt nl; /* number of literal/length codes */ +//uInt nd; /* number of distance codes */ +//uInt *c; /* that many (total) code lengths */ +//uInt *bl; /* literal desired/actual bit depth */ +//uInt *bd; /* distance desired/actual bit depth */ +//inflate_huft * *tl; /* literal/length tree result */ +//inflate_huft * *td; /* distance tree result */ +//inflate_huft *hp; /* space for trees */ +//z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +static uInt fixed_bl = 9; +static uInt fixed_bd = 5; +static inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +static inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; + +int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z) +//uInt *bl; /* literal desired/actual bit depth */ +//uInt *bd; /* distance desired/actual bit depth */ +//inflate_huft * *tl; /* literal/length tree result */ +//inflate_huft * *td; /* distance tree result */ +//z_streamp z; /* for memory allocation */ +{ + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z) +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Byte *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv(("inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} + +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z) +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev(("inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Byte *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv(("inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv(("inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv(("inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(inflate_codes_statef *c, z_streamp z) +{ + ZFREE(z, c); + Tracev(("inflate: codes free\n")); +} + +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#undef DO1 +#undef DO2 +#undef DO4 +#undef DO8 + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong adler32(uLong adler, const Byte *buf, uInt len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} + +/* @(#) $Id$ */ + +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); + +typedef enum { + imMETHOD, /* waiting for method byte */ + imFLAG, /* waiting for flag byte */ + imDICT4, /* four dictionary check bytes to go */ + imDICT3, /* three dictionary check bytes to go */ + imDICT2, /* two dictionary check bytes to go */ + imDICT1, /* one dictionary check byte to go */ + imDICT0, /* waiting for inflateSetDictionary */ + imBLOCKS, /* decompressing blocks */ + imCHECK4, /* four check bytes to go */ + imCHECK3, /* three check bytes to go */ + imCHECK2, /* two check bytes to go */ + imCHECK1, /* one check byte to go */ + imDONE, /* finished check, done */ + imBAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev(("inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev(("inflate: end\n")); + return Z_OK; +} + + + +int inflateInit2_(z_streamp z, int w, const char *version, int stream_size) +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc; + z->opaque = (voidp)0; + } + if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree; + if ((z->state = (struct internal_state *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev(("inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit_(z_streamp z, const char *version, int stream_size) +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z_streamp z, int f) +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case imMETHOD: + iNEEDBYTE + if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = imBAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = imBAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = imFLAG; + case imFLAG: + iNEEDBYTE + b = iNEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = imBLOCKS; + break; + } + z->state->mode = imDICT4; + case imDICT4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imDICT3; + case imDICT3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imDICT2; + case imDICT2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imDICT1; + case imDICT1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = imDICT0; + return Z_NEED_DICT; + case imDICT0: + z->state->mode = imBAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case imBLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = imDONE; + break; + } + z->state->mode = imCHECK4; + case imCHECK4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imCHECK3; + case imCHECK3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imCHECK2; + case imCHECK2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imCHECK1; + case imCHECK1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib check ok\n")); + z->state->mode = imDONE; + case imDONE: + return Z_STREAM_END; + case imBAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength) +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = imBLOCKS; + return Z_OK; +} + + +int inflateSync(z_streamp z) +{ + uInt n; /* number of bytes to look at */ + Byte *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != imBAD) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = imBLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int inflateSyncPoint(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); +} + +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidp)Mem_ClearedAlloc(items*size); +} + +void zcfree (voidp opaque, voidp ptr) +{ + Mem_Free(ptr); + if (opaque) return; /* make compiler happy */ +} diff --git a/framework/Unzip.h b/framework/Unzip.h new file mode 100644 index 000000000..670e79df3 --- /dev/null +++ b/framework/Unzip.h @@ -0,0 +1,337 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __UNZIP_H__ +#define __UNZIP_H__ + + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef void* unzFile; +#endif + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + unsigned int tm_sec; /* seconds after the minute - [0,59] */ + unsigned int tm_min; /* minutes after the hour - [0,59] */ + unsigned int tm_hour; /* hours since midnight - [0,23] */ + unsigned int tm_mday; /* day of the month - [1,31] */ + unsigned int tm_mon; /* months since January - [0,11] */ + unsigned int tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + unsigned long number_entry; /* total number of entries in the central dir on this disk */ + unsigned long size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + unsigned long version; /* version made by 2 unsigned chars */ + unsigned long version_needed; /* version needed to extract 2 unsigned chars */ + unsigned long flag; /* general purpose bit flag 2 unsigned chars */ + unsigned long compression_method; /* compression method 2 unsigned chars */ + unsigned long dosDate; /* last mod file date in Dos fmt 4 unsigned chars */ + unsigned long crc; /* crc-32 4 unsigned chars */ + unsigned long compressed_size; /* compressed size 4 unsigned chars */ + unsigned long uncompressed_size; /* uncompressed size 4 unsigned chars */ + unsigned long size_filename; /* filename length 2 unsigned chars */ + unsigned long size_file_extra; /* extra field length 2 unsigned chars */ + unsigned long size_file_comment; /* file comment length 2 unsigned chars */ + + unsigned long disk_num_start; /* disk number start 2 unsigned chars */ + unsigned long internal_fa; /* internal file attributes 2 unsigned chars */ + unsigned long external_fa; /* external file attributes 4 unsigned chars */ + + tm_unz tmu_date; +} unz_file_info; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + unsigned long offset_curfile;/* relative offset of static header 4 unsigned chars */ +} unz_file_info_internal; + +typedef void* (*alloc_func) (void* opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void* opaque, void* address); + +struct internal_state; + +typedef struct z_stream_s { + unsigned char *next_in; /* next input unsigned char */ + unsigned int avail_in; /* number of unsigned chars available at next_in */ + unsigned long total_in; /* total nb of input unsigned chars read so */ + + unsigned char *next_out; /* next output unsigned char should be put there */ + unsigned int avail_out; /* remaining free space at next_out */ + unsigned long total_out; /* total nb of unsigned chars output so */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + unsigned char* opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + unsigned long adler; /* adler32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream *z_streamp; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + unsigned long pos_in_zipfile; /* position in unsigned char on the zipfile, for fseek*/ + unsigned long stream_initialised; /* flag set if stream structure is initialised*/ + + unsigned long offset_local_extrafield;/* offset of the static extra field */ + unsigned int size_local_extrafield;/* size of the static extra field */ + unsigned long pos_local_extrafield; /* position in the static extra field in read*/ + + unsigned long crc32; /* crc32 of all data uncompressed */ + unsigned long crc32_wait; /* crc32 we must obtain after decompress all */ + unsigned long rest_read_compressed; /* number of unsigned char to be decompressed */ + unsigned long rest_read_uncompressed;/*number of unsigned char to be obtained after decomp*/ + FILE* file; /* io structore of the zipfile */ + unsigned long compression_method; /* compression method (0==store) */ + unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + FILE* file; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ + unsigned long num_file; /* number of the current file in the zipfile*/ + unsigned long pos_in_central_dir; /* pos of the current file in the central dir*/ + unsigned long current_file_ok; /* flag about the usability of the current file*/ + unsigned long central_pos; /* position of the beginning of the central dir*/ + + unsigned long size_central_dir; /* size of the central directory */ + unsigned long offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +#define UNZ_CASESENSITIVE 1 +#define UNZ_NOTCASESENSITIVE 2 +#define UNZ_OSDEFAULTCASE 0 + +extern int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity); + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + +extern unzFile unzOpen (const char *path); +extern unzFile unzReOpen (const char* path, unzFile file); + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int unzClose (unzFile file); + +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info); + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int unzGetGlobalComment (unzFile file, char *szComment, unsigned long uSizeBuf); + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of unsigned char copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int unzGoToFirstFile (unzFile file); + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int unzGoToNextFile (unzFile file); + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int unzGetCurrentFileInfoPosition (unzFile file, unsigned long *pos ); + +/* + Get the position of the info of the current file in the zip. + return UNZ_OK if there is no problem +*/ + +extern int unzSetCurrentFileInfoPosition (unzFile file, unsigned long pos ); + +/* + Set the position of the info of the current file in the zip. + return UNZ_OK if there is no problem +*/ + +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity); + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int unzGetCurrentFileInfo (unzFile file, unz_file_info *pfile_info, char *szFileName, unsigned long fileNameBufferSize, void *extraField, unsigned long extraFieldBufferSize, char *szComment, unsigned long commentBufferSize); + +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int unzOpenCurrentFile (unzFile file); + +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int unzCloseCurrentFile (unzFile file); + +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +extern int unzReadCurrentFile (unzFile file, void* buf, unsigned len); + +/* + Read unsigned chars from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of unsigned char copied if somes unsigned chars are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern long unztell(unzFile file); + +/* + Give the current position in uncompressed data +*/ + +extern int unzeof (unzFile file); + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int unzGetLocalExtrafield (unzFile file, void* buf, unsigned len); + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of unsigned chars copied in buf, or (if <0) + the error code +*/ + +#endif /* __UNZIP_H__ */ diff --git a/framework/UsercmdGen.cpp b/framework/UsercmdGen.cpp new file mode 100644 index 000000000..14eec1eda --- /dev/null +++ b/framework/UsercmdGen.cpp @@ -0,0 +1,1103 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Session_local.h" + +/* +================ +usercmd_t::ByteSwap +================ +*/ +void usercmd_t::ByteSwap( void ) { + angles[0] = LittleShort( angles[0] ); + angles[1] = LittleShort( angles[1] ); + angles[2] = LittleShort( angles[2] ); + sequence = LittleLong( sequence ); +} + +/* +================ +usercmd_t::operator== +================ +*/ +bool usercmd_t::operator==( const usercmd_t &rhs ) const { + return ( buttons == rhs.buttons && + forwardmove == rhs.forwardmove && + rightmove == rhs.rightmove && + upmove == rhs.upmove && + angles[0] == rhs.angles[0] && + angles[1] == rhs.angles[1] && + angles[2] == rhs.angles[2] && + impulse == rhs.impulse && + flags == rhs.flags && + mx == rhs.mx && + my == rhs.my ); +} + + +const int KEY_MOVESPEED = 127; + +/*typedef enum { + UB_NONE, + + UB_UP, + UB_DOWN, + UB_LEFT, + UB_RIGHT, + UB_FORWARD, + UB_BACK, + UB_LOOKUP, + UB_LOOKDOWN, + UB_STRAFE, + UB_MOVELEFT, + UB_MOVERIGHT, + + UB_BUTTON0, + UB_BUTTON1, + UB_BUTTON2, + UB_BUTTON3, + UB_BUTTON4, + UB_BUTTON5, + UB_BUTTON6, + UB_BUTTON7, + + UB_ATTACK, + UB_SPEED, + UB_ZOOM, + UB_SHOWSCORES, + UB_MLOOK, + + UB_IMPULSE0, + UB_IMPULSE1, + UB_IMPULSE2, + UB_IMPULSE3, + UB_IMPULSE4, + UB_IMPULSE5, + UB_IMPULSE6, + UB_IMPULSE7, + UB_IMPULSE8, + UB_IMPULSE9, + UB_IMPULSE10, + UB_IMPULSE11, + UB_IMPULSE12, + UB_IMPULSE13, + UB_IMPULSE14, + UB_IMPULSE15, + UB_IMPULSE16, + UB_IMPULSE17, + UB_IMPULSE18, + UB_IMPULSE19, + UB_IMPULSE20, + UB_IMPULSE21, + UB_IMPULSE22, + UB_IMPULSE23, + UB_IMPULSE24, + UB_IMPULSE25, + UB_IMPULSE26, + UB_IMPULSE27, + UB_IMPULSE28, + UB_IMPULSE29, + UB_IMPULSE30, + UB_IMPULSE31, + UB_IMPULSE32, + UB_IMPULSE33, + UB_IMPULSE34, + UB_IMPULSE35, + UB_IMPULSE36, + UB_IMPULSE37, + UB_IMPULSE38, + UB_IMPULSE39, + UB_IMPULSE40, + UB_IMPULSE41, + UB_IMPULSE42, + UB_IMPULSE43, + UB_IMPULSE44, + UB_IMPULSE45, + UB_IMPULSE46, + UB_IMPULSE47, + UB_IMPULSE48, + UB_IMPULSE49, + UB_IMPULSE50, + UB_IMPULSE51, + UB_IMPULSE52, + UB_IMPULSE53, + UB_IMPULSE54, + UB_IMPULSE55, + UB_IMPULSE56, + UB_IMPULSE57, + UB_IMPULSE58, + UB_IMPULSE59, + UB_IMPULSE60, + UB_IMPULSE61, + UB_IMPULSE62, + UB_IMPULSE63, + + UB_MAX_BUTTONS +} usercmdButton_t;*/ + +typedef struct { + const char *string; + UserCmdButton button; +} userCmdString_t; + +userCmdString_t userCmdStrings[] = { + { "_moveUp", UB_UP }, + { "_moveDown", UB_DOWN }, + { "_left", UB_LEFT }, + { "_right", UB_RIGHT }, + { "_forward", UB_FORWARD }, + { "_back", UB_BACK }, + { "_lookUp", UB_LOOKUP }, + { "_lookDown", UB_LOOKDOWN }, + { "_strafe", UB_STRAFE }, + { "_moveLeft", UB_MOVELEFT }, + { "_moveRight", UB_MOVERIGHT }, + + { "_attack", UB_ATTACK }, + { "_speed", UB_SPEED }, + { "_zoom", UB_ZOOM }, + { "_showScores", UB_SHOWSCORES }, + { "_mlook", UB_MLOOK }, + + { "_button0", UB_BUTTON0 }, + { "_button1", UB_BUTTON1 }, + { "_button2", UB_BUTTON2 }, + { "_button3", UB_BUTTON3 }, + { "_button4", UB_BUTTON4 }, + { "_button5", UB_BUTTON5 }, + { "_button6", UB_BUTTON6 }, + { "_button7", UB_BUTTON7 }, + + { "_impulse0", UB_IMPULSE0 }, + { "_impulse1", UB_IMPULSE1 }, + { "_impulse2", UB_IMPULSE2 }, + { "_impulse3", UB_IMPULSE3 }, + { "_impulse4", UB_IMPULSE4 }, + { "_impulse5", UB_IMPULSE5 }, + { "_impulse6", UB_IMPULSE6 }, + { "_impulse7", UB_IMPULSE7 }, + { "_impulse8", UB_IMPULSE8 }, + { "_impulse9", UB_IMPULSE9 }, + { "_impulse10", UB_IMPULSE10 }, + { "_impulse11", UB_IMPULSE11 }, + { "_impulse12", UB_IMPULSE12 }, + { "_impulse13", UB_IMPULSE13 }, + { "_impulse14", UB_IMPULSE14 }, + { "_impulse15", UB_IMPULSE15 }, + { "_impulse16", UB_IMPULSE16 }, + { "_impulse17", UB_IMPULSE17 }, + { "_impulse18", UB_IMPULSE18 }, + { "_impulse19", UB_IMPULSE19 }, + { "_impulse20", UB_IMPULSE20 }, + { "_impulse21", UB_IMPULSE21 }, + { "_impulse22", UB_IMPULSE22 }, + { "_impulse23", UB_IMPULSE23 }, + { "_impulse24", UB_IMPULSE24 }, + { "_impulse25", UB_IMPULSE25 }, + { "_impulse26", UB_IMPULSE26 }, + { "_impulse27", UB_IMPULSE27 }, + { "_impulse28", UB_IMPULSE28 }, + { "_impulse29", UB_IMPULSE29 }, + { "_impulse30", UB_IMPULSE30 }, + { "_impulse31", UB_IMPULSE31 }, + { "_impulse32", UB_IMPULSE32 }, + { "_impulse33", UB_IMPULSE33 }, + { "_impulse34", UB_IMPULSE34 }, + { "_impulse35", UB_IMPULSE35 }, + { "_impulse36", UB_IMPULSE36 }, + { "_impulse37", UB_IMPULSE37 }, + { "_impulse38", UB_IMPULSE38 }, + { "_impulse39", UB_IMPULSE39 }, + { "_impulse40", UB_IMPULSE40 }, + { "_impulse41", UB_IMPULSE41 }, + { "_impulse42", UB_IMPULSE42 }, + { "_impulse43", UB_IMPULSE43 }, + { "_impulse44", UB_IMPULSE44 }, + { "_impulse45", UB_IMPULSE45 }, + { "_impulse46", UB_IMPULSE46 }, + { "_impulse47", UB_IMPULSE47 }, + { "_impulse48", UB_IMPULSE48 }, + { "_impulse49", UB_IMPULSE49 }, + { "_impulse50", UB_IMPULSE50 }, + { "_impulse51", UB_IMPULSE51 }, + { "_impulse52", UB_IMPULSE52 }, + { "_impulse53", UB_IMPULSE53 }, + { "_impulse54", UB_IMPULSE54 }, + { "_impulse55", UB_IMPULSE55 }, + { "_impulse56", UB_IMPULSE56 }, + { "_impulse57", UB_IMPULSE57 }, + { "_impulse58", UB_IMPULSE58 }, + { "_impulse59", UB_IMPULSE59 }, + { "_impulse60", UB_IMPULSE60 }, + { "_impulse61", UB_IMPULSE61 }, + { "_impulse62", UB_IMPULSE62 }, + { "_impulse63", UB_IMPULSE63 }, + + { NULL, UB_NONE }, +}; + + class buttonState_t { + public: + int on; + bool held; + + buttonState_t() { Clear(); }; + void Clear( void ); + void SetKeyState( int keystate, bool toggle ); +}; + +/* +================ +buttonState_t::Clear +================ +*/ +void buttonState_t::Clear( void ) { + held = false; + on = 0; +} + +/* +================ +buttonState_t::SetKeyState +================ +*/ +void buttonState_t::SetKeyState( int keystate, bool toggle ) { + if ( !toggle ) { + held = false; + on = keystate; + } else if ( !keystate ) { + held = false; + } else if ( !held ) { + held = true; + on ^= 1; + } +} + + +const int NUM_USER_COMMANDS = sizeof(userCmdStrings) / sizeof(userCmdString_t); + +const int MAX_CHAT_BUFFER = 127; + +class idUsercmdGenLocal : public idUsercmdGen { +public: + idUsercmdGenLocal( void ); + + void Init( void ); + + void InitForNewMap( void ); + + void Shutdown( void ); + + void Clear( void ); + + void ClearAngles( void ); + + usercmd_t TicCmd( int ticNumber ); + + void InhibitUsercmd( inhibit_t subsystem, bool inhibit ); + + void UsercmdInterrupt( void ); + + int CommandStringUsercmdData( const char *cmdString ); + + int GetNumUserCommands( void ); + + const char * GetUserCommandName( int index ); + + void MouseState( int *x, int *y, int *button, bool *down ); + + int ButtonState( int key ); + int KeyState( int key ); + + usercmd_t GetDirectUsercmd( void ); + +private: + void MakeCurrent( void ); + void InitCurrent( void ); + + bool Inhibited( void ); + void AdjustAngles( void ); + void KeyMove( void ); + void JoystickMove( void ); + void MouseMove( void ); + void CmdButtons( void ); + + void Mouse( void ); + void Keyboard( void ); + void Joystick( void ); + + void Key( int keyNum, bool down ); + + idVec3 viewangles; + int flags; + int impulse; + + buttonState_t toggled_crouch; + buttonState_t toggled_run; + buttonState_t toggled_zoom; + + int buttonState[UB_MAX_BUTTONS]; + bool keyState[K_LAST_KEY]; + + int inhibitCommands; // true when in console or menu locally + int lastCommandTime; + + bool initialized; + + usercmd_t cmd; // the current cmd being built + usercmd_t buffered[MAX_BUFFERED_USERCMD]; + + int continuousMouseX, continuousMouseY; // for gui event generatioin, never zerod + int mouseButton; // for gui event generatioin + bool mouseDown; + + int mouseDx, mouseDy; // added to by mouse events + int joystickAxis[MAX_JOYSTICK_AXIS]; // set by joystick events + + static idCVar in_yawSpeed; + static idCVar in_pitchSpeed; + static idCVar in_angleSpeedKey; + static idCVar in_freeLook; + static idCVar in_alwaysRun; + static idCVar in_toggleRun; + static idCVar in_toggleCrouch; + static idCVar in_toggleZoom; + static idCVar sensitivity; + static idCVar m_pitch; + static idCVar m_yaw; + static idCVar m_strafeScale; + static idCVar m_smooth; + static idCVar m_strafeSmooth; + static idCVar m_showMouseRate; +}; + +idCVar idUsercmdGenLocal::in_yawSpeed( "in_yawspeed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "yaw change speed when holding down _left or _right button" ); +idCVar idUsercmdGenLocal::in_pitchSpeed( "in_pitchspeed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "pitch change speed when holding down look _lookUp or _lookDown button" ); +idCVar idUsercmdGenLocal::in_angleSpeedKey( "in_anglespeedkey", "1.5", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "angle change scale when holding down _speed button" ); +idCVar idUsercmdGenLocal::in_freeLook( "in_freeLook", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "look around with mouse (reverse _mlook button)" ); +idCVar idUsercmdGenLocal::in_alwaysRun( "in_alwaysRun", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "always run (reverse _speed button) - only in MP" ); +idCVar idUsercmdGenLocal::in_toggleRun( "in_toggleRun", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _speed button toggles run on/off - only in MP" ); +idCVar idUsercmdGenLocal::in_toggleCrouch( "in_toggleCrouch", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _movedown button toggles player crouching/standing" ); +idCVar idUsercmdGenLocal::in_toggleZoom( "in_toggleZoom", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _zoom button toggles zoom on/off" ); +idCVar idUsercmdGenLocal::sensitivity( "sensitivity", "5", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse view sensitivity" ); +idCVar idUsercmdGenLocal::m_pitch( "m_pitch", "0.022", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse pitch scale" ); +idCVar idUsercmdGenLocal::m_yaw( "m_yaw", "0.022", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse yaw scale" ); +idCVar idUsercmdGenLocal::m_strafeScale( "m_strafeScale", "6.25", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse strafe movement scale" ); +idCVar idUsercmdGenLocal::m_smooth( "m_smooth", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse viewing", 1, 8, idCmdSystem::ArgCompletion_Integer<1,8> ); +idCVar idUsercmdGenLocal::m_strafeSmooth( "m_strafeSmooth", "4", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse moving", 1, 8, idCmdSystem::ArgCompletion_Integer<1,8> ); +idCVar idUsercmdGenLocal::m_showMouseRate( "m_showMouseRate", "0", CVAR_SYSTEM | CVAR_BOOL, "shows mouse movement" ); + +static idUsercmdGenLocal localUsercmdGen; +idUsercmdGen *usercmdGen = &localUsercmdGen; + +/* +================ +idUsercmdGenLocal::idUsercmdGenLocal +================ +*/ +idUsercmdGenLocal::idUsercmdGenLocal( void ) { + lastCommandTime = 0; + initialized = false; + + flags = 0; + impulse = 0; + + toggled_crouch.Clear(); + toggled_run.Clear(); + toggled_zoom.Clear(); + toggled_run.on = in_alwaysRun.GetBool(); + + ClearAngles(); + Clear(); +} + +/* +================ +idUsercmdGenLocal::InhibitUsercmd +================ +*/ +void idUsercmdGenLocal::InhibitUsercmd( inhibit_t subsystem, bool inhibit ) { + if ( inhibit ) { + inhibitCommands |= 1 << subsystem; + } else { + inhibitCommands &= ( 0xffffffff ^ ( 1 << subsystem ) ); + } +} + +/* +=============== +idUsercmdGenLocal::ButtonState + +Returns (the fraction of the frame) that the key was down +=============== +*/ +int idUsercmdGenLocal::ButtonState( int key ) { + if ( key<0 || key>=UB_MAX_BUTTONS ) { + return -1; + } + return ( buttonState[key] > 0 ) ? 1 : 0; +} + +/* +=============== +idUsercmdGenLocal::KeyState + +Returns (the fraction of the frame) that the key was down +bk20060111 +=============== +*/ +int idUsercmdGenLocal::KeyState( int key ) { + if ( key<0 || key>=K_LAST_KEY ) { + return -1; + } + return ( keyState[key] ) ? 1 : 0; +} + + +//===================================================================== + + +/* +================ +idUsercmdGenLocal::GetNumUserCommands +================ +*/ +int idUsercmdGenLocal::GetNumUserCommands( void ) { + return NUM_USER_COMMANDS; +} + +/* +================ +idUsercmdGenLocal::GetNumUserCommands +================ +*/ +const char *idUsercmdGenLocal::GetUserCommandName( int index ) { + if (index >= 0 && index < NUM_USER_COMMANDS) { + return userCmdStrings[index].string; + } + return ""; +} + +/* +================ +idUsercmdGenLocal::Inhibited + +is user cmd generation inhibited +================ +*/ +bool idUsercmdGenLocal::Inhibited( void ) { + return ( inhibitCommands != 0); +} + +/* +================ +idUsercmdGenLocal::AdjustAngles + +Moves the local angle positions +================ +*/ +void idUsercmdGenLocal::AdjustAngles( void ) { + float speed; + + if ( toggled_run.on ^ ( in_alwaysRun.GetBool() && idAsyncNetwork::IsActive() ) ) { + speed = idMath::M_MS2SEC * USERCMD_MSEC * in_angleSpeedKey.GetFloat(); + } else { + speed = idMath::M_MS2SEC * USERCMD_MSEC; + } + + if ( !ButtonState( UB_STRAFE ) ) { + viewangles[YAW] -= speed * in_yawSpeed.GetFloat() * ButtonState( UB_RIGHT ); + viewangles[YAW] += speed * in_yawSpeed.GetFloat() * ButtonState( UB_LEFT ); + } + + viewangles[PITCH] -= speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKUP ); + viewangles[PITCH] += speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKDOWN ); +} + +/* +================ +idUsercmdGenLocal::KeyMove + +Sets the usercmd_t based on key states +================ +*/ +void idUsercmdGenLocal::KeyMove( void ) { + int forward, side, up; + + forward = 0; + side = 0; + up = 0; + if ( ButtonState( UB_STRAFE ) ) { + side += KEY_MOVESPEED * ButtonState( UB_RIGHT ); + side -= KEY_MOVESPEED * ButtonState( UB_LEFT ); + } + + side += KEY_MOVESPEED * ButtonState( UB_MOVERIGHT ); + side -= KEY_MOVESPEED * ButtonState( UB_MOVELEFT ); + + up -= KEY_MOVESPEED * toggled_crouch.on; + up += KEY_MOVESPEED * ButtonState( UB_UP ); + + forward += KEY_MOVESPEED * ButtonState( UB_FORWARD ); + forward -= KEY_MOVESPEED * ButtonState( UB_BACK ); + + cmd.forwardmove = idMath::ClampChar( forward ); + cmd.rightmove = idMath::ClampChar( side ); + cmd.upmove = idMath::ClampChar( up ); +} + +/* +================= +idUsercmdGenLocal::MouseMove +================= +*/ +void idUsercmdGenLocal::MouseMove( void ) { + float mx, my, strafeMx, strafeMy; + static int history[8][2]; + static int historyCounter; + int i; + + history[historyCounter&7][0] = mouseDx; + history[historyCounter&7][1] = mouseDy; + + // allow mouse movement to be smoothed together + int smooth = m_smooth.GetInteger(); + if ( smooth < 1 ) { + smooth = 1; + } + if ( smooth > 8 ) { + smooth = 8; + } + mx = 0; + my = 0; + for ( i = 0 ; i < smooth ; i++ ) { + mx += history[ ( historyCounter - i + 8 ) & 7 ][0]; + my += history[ ( historyCounter - i + 8 ) & 7 ][1]; + } + mx /= smooth; + my /= smooth; + + // use a larger smoothing for strafing + smooth = m_strafeSmooth.GetInteger(); + if ( smooth < 1 ) { + smooth = 1; + } + if ( smooth > 8 ) { + smooth = 8; + } + strafeMx = 0; + strafeMy = 0; + for ( i = 0 ; i < smooth ; i++ ) { + strafeMx += history[ ( historyCounter - i + 8 ) & 7 ][0]; + strafeMy += history[ ( historyCounter - i + 8 ) & 7 ][1]; + } + strafeMx /= smooth; + strafeMy /= smooth; + + historyCounter++; + + if ( idMath::Fabs( mx ) > 1000 || idMath::Fabs( my ) > 1000 ) { + Sys_DebugPrintf( "idUsercmdGenLocal::MouseMove: Ignoring ridiculous mouse delta.\n" ); + mx = my = 0; + } + + mx *= sensitivity.GetFloat(); + my *= sensitivity.GetFloat(); + + if ( m_showMouseRate.GetBool() ) { + Sys_DebugPrintf( "[%3i %3i = %5.1f %5.1f = %5.1f %5.1f] ", mouseDx, mouseDy, mx, my, strafeMx, strafeMy ); + } + + mouseDx = 0; + mouseDy = 0; + + if ( !strafeMx && !strafeMy ) { + return; + } + + if ( ButtonState( UB_STRAFE ) || !( cmd.buttons & BUTTON_MLOOK ) ) { + // add mouse X/Y movement to cmd + strafeMx *= m_strafeScale.GetFloat(); + strafeMy *= m_strafeScale.GetFloat(); + // clamp as a vector, instead of separate floats + float len = sqrt( strafeMx * strafeMx + strafeMy * strafeMy ); + if ( len > 127 ) { + strafeMx = strafeMx * 127 / len; + strafeMy = strafeMy * 127 / len; + } + } + + if ( !ButtonState( UB_STRAFE ) ) { + viewangles[YAW] -= m_yaw.GetFloat() * mx; + } else { + cmd.rightmove = idMath::ClampChar( (int)(cmd.rightmove + strafeMx) ); + } + + if ( !ButtonState( UB_STRAFE ) && ( cmd.buttons & BUTTON_MLOOK ) ) { + viewangles[PITCH] += m_pitch.GetFloat() * my; + } else { + cmd.forwardmove = idMath::ClampChar( (int)(cmd.forwardmove - strafeMy) ); + } +} + +/* +================= +idUsercmdGenLocal::JoystickMove +================= +*/ +void idUsercmdGenLocal::JoystickMove( void ) { + float anglespeed; + + if ( toggled_run.on ^ ( in_alwaysRun.GetBool() && idAsyncNetwork::IsActive() ) ) { + anglespeed = idMath::M_MS2SEC * USERCMD_MSEC * in_angleSpeedKey.GetFloat(); + } else { + anglespeed = idMath::M_MS2SEC * USERCMD_MSEC; + } + + if ( !ButtonState( UB_STRAFE ) ) { + viewangles[YAW] += anglespeed * in_yawSpeed.GetFloat() * joystickAxis[AXIS_SIDE]; + viewangles[PITCH] += anglespeed * in_pitchSpeed.GetFloat() * joystickAxis[AXIS_FORWARD]; + } else { + cmd.rightmove = idMath::ClampChar( cmd.rightmove + joystickAxis[AXIS_SIDE] ); + cmd.forwardmove = idMath::ClampChar( cmd.forwardmove + joystickAxis[AXIS_FORWARD] ); + } + + cmd.upmove = idMath::ClampChar( cmd.upmove + joystickAxis[AXIS_UP] ); +} + +/* +============== +idUsercmdGenLocal::CmdButtons +============== +*/ +void idUsercmdGenLocal::CmdButtons( void ) { + int i; + + cmd.buttons = 0; + + // figure button bits + for (i = 0 ; i <= 7 ; i++) { + if ( ButtonState( (UserCmdButton)( UB_BUTTON0 + i ) ) ) { + cmd.buttons |= 1 << i; + } + } + + // check the attack button + if ( ButtonState( UB_ATTACK ) ) { + cmd.buttons |= BUTTON_ATTACK; + } + + // check the run button + if ( toggled_run.on ^ ( in_alwaysRun.GetBool() && idAsyncNetwork::IsActive() ) ) { + cmd.buttons |= BUTTON_RUN; + } + + // check the zoom button + if ( toggled_zoom.on ) { + cmd.buttons |= BUTTON_ZOOM; + } + + // check the scoreboard button + if ( ButtonState( UB_SHOWSCORES ) || ButtonState( UB_IMPULSE19 ) ) { + // the button is toggled in SP mode as well but without effect + cmd.buttons |= BUTTON_SCORES; + } + + // check the mouse look button + if ( ButtonState( UB_MLOOK ) ^ in_freeLook.GetInteger() ) { + cmd.buttons |= BUTTON_MLOOK; + } +} + +/* +================ +idUsercmdGenLocal::InitCurrent + +inits the current command for this frame +================ +*/ +void idUsercmdGenLocal::InitCurrent( void ) { + memset( &cmd, 0, sizeof( cmd ) ); + cmd.flags = flags; + cmd.impulse = impulse; + cmd.buttons |= ( in_alwaysRun.GetBool() && idAsyncNetwork::IsActive() ) ? BUTTON_RUN : 0; + cmd.buttons |= in_freeLook.GetBool() ? BUTTON_MLOOK : 0; +} + +/* +================ +idUsercmdGenLocal::MakeCurrent + +creates the current command for this frame +================ +*/ +void idUsercmdGenLocal::MakeCurrent( void ) { + idVec3 oldAngles; + int i; + + oldAngles = viewangles; + + if ( !Inhibited() ) { + // update toggled key states + toggled_crouch.SetKeyState( ButtonState( UB_DOWN ), in_toggleCrouch.GetBool() ); + toggled_run.SetKeyState( ButtonState( UB_SPEED ), in_toggleRun.GetBool() && idAsyncNetwork::IsActive() ); + toggled_zoom.SetKeyState( ButtonState( UB_ZOOM ), in_toggleZoom.GetBool() ); + + // keyboard angle adjustment + AdjustAngles(); + + // set button bits + CmdButtons(); + + // get basic movement from keyboard + KeyMove(); + + // get basic movement from mouse + MouseMove(); + + // get basic movement from joystick + JoystickMove(); + + // check to make sure the angles haven't wrapped + if ( viewangles[PITCH] - oldAngles[PITCH] > 90 ) { + viewangles[PITCH] = oldAngles[PITCH] + 90; + } else if ( oldAngles[PITCH] - viewangles[PITCH] > 90 ) { + viewangles[PITCH] = oldAngles[PITCH] - 90; + } + } else { + mouseDx = 0; + mouseDy = 0; + } + + for ( i = 0; i < 3; i++ ) { + cmd.angles[i] = ANGLE2SHORT( viewangles[i] ); + } + + cmd.mx = continuousMouseX; + cmd.my = continuousMouseY; + + flags = cmd.flags; + impulse = cmd.impulse; + +} + +//===================================================================== + + +/* +================ +idUsercmdGenLocal::CommandStringUsercmdData + +Returns the button if the command string is used by the async usercmd generator. +================ +*/ +int idUsercmdGenLocal::CommandStringUsercmdData( const char *cmdString ) { + for ( userCmdString_t *ucs = userCmdStrings ; ucs->string ; ucs++ ) { + if ( idStr::Icmp( cmdString, ucs->string ) == 0 ) { + return ucs->button; + } + } + return UB_NONE; +} + +/* +================ +idUsercmdGenLocal::Init +================ +*/ +void idUsercmdGenLocal::Init( void ) { + initialized = true; +} + +/* +================ +idUsercmdGenLocal::InitForNewMap +================ +*/ +void idUsercmdGenLocal::InitForNewMap( void ) { + flags = 0; + impulse = 0; + + toggled_crouch.Clear(); + toggled_run.Clear(); + toggled_zoom.Clear(); + toggled_run.on = in_alwaysRun.GetBool(); + + Clear(); + ClearAngles(); +} + +/* +================ +idUsercmdGenLocal::Shutdown +================ +*/ +void idUsercmdGenLocal::Shutdown( void ) { + initialized = false; +} + +/* +================ +idUsercmdGenLocal::Clear +================ +*/ +void idUsercmdGenLocal::Clear( void ) { + // clears all key states + memset( buttonState, 0, sizeof( buttonState ) ); + memset( keyState, false, sizeof( keyState ) ); + + inhibitCommands = false; + + mouseDx = mouseDy = 0; + mouseButton = 0; + mouseDown = false; +} + +/* +================ +idUsercmdGenLocal::ClearAngles +================ +*/ +void idUsercmdGenLocal::ClearAngles( void ) { + viewangles.Zero(); +} + +/* +================ +idUsercmdGenLocal::TicCmd + +Returns a buffered usercmd +================ +*/ +usercmd_t idUsercmdGenLocal::TicCmd( int ticNumber ) { + + // the packetClient code can legally ask for com_ticNumber+1, because + // it is in the async code and com_ticNumber hasn't been updated yet, + // but all other code should never ask for anything > com_ticNumber + if ( ticNumber > com_ticNumber+1 ) { + common->Error( "idUsercmdGenLocal::TicCmd ticNumber > com_ticNumber" ); + } + + if ( ticNumber <= com_ticNumber - MAX_BUFFERED_USERCMD ) { + // this can happen when something in the game code hitches badly, allowing the + // async code to overflow the buffers + //common->Printf( "warning: idUsercmdGenLocal::TicCmd ticNumber <= com_ticNumber - MAX_BUFFERED_USERCMD\n" ); + } + + return buffered[ ticNumber & (MAX_BUFFERED_USERCMD-1) ]; +} + +//====================================================================== + + +/* +=================== +idUsercmdGenLocal::Key + +Handles async mouse/keyboard button actions +=================== +*/ +void idUsercmdGenLocal::Key( int keyNum, bool down ) { + + // Sanity check, sometimes we get double message :( + if ( keyState[ keyNum ] == down ) { + return; + } + keyState[ keyNum ] = down; + + int action = idKeyInput::GetUsercmdAction( keyNum ); + + if ( down ) { + + buttonState[ action ]++; + + if ( !Inhibited() ) { + if ( action >= UB_IMPULSE0 && action <= UB_IMPULSE61 ) { + cmd.impulse = action - UB_IMPULSE0; + cmd.flags ^= UCF_IMPULSE_SEQUENCE; + } + } + } else { + buttonState[ action ]--; + // we might have one held down across an app active transition + if ( buttonState[ action ] < 0 ) { + buttonState[ action ] = 0; + } + } +} + +/* +=================== +idUsercmdGenLocal::Mouse +=================== +*/ +void idUsercmdGenLocal::Mouse( void ) { + int i, numEvents; + + numEvents = Sys_PollMouseInputEvents(); + + if ( numEvents ) { + // + // Study each of the buffer elements and process them. + // + for( i = 0; i < numEvents; i++ ) { + int action, value; + if ( Sys_ReturnMouseInputEvent( i, action, value ) ) { + if ( action >= M_ACTION1 && action <= M_ACTION8 ) { + mouseButton = K_MOUSE1 + ( action - M_ACTION1 ); + mouseDown = ( value != 0 ); + Key( mouseButton, mouseDown ); + } else { + switch ( action ) { + case M_DELTAX: + mouseDx += value; + continuousMouseX += value; + break; + case M_DELTAY: + mouseDy += value; + continuousMouseY += value; + break; + case M_DELTAZ: + int key = value < 0 ? K_MWHEELDOWN : K_MWHEELUP; + value = abs( value ); + while( value-- > 0 ) { + Key( key, true ); + Key( key, false ); + mouseButton = key; + mouseDown = true; + } + break; + } + } + } + } + } + + Sys_EndMouseInputEvents(); +} + +/* +=============== +idUsercmdGenLocal::Keyboard +=============== +*/ +void idUsercmdGenLocal::Keyboard( void ) { + + int numEvents = Sys_PollKeyboardInputEvents(); + + if ( numEvents ) { + // + // Study each of the buffer elements and process them. + // + int key; + bool state; + for( int i = 0; i < numEvents; i++ ) { + if (Sys_ReturnKeyboardInputEvent( i, key, state )) { + Key ( key, state ); + } + } + } + + Sys_EndKeyboardInputEvents(); +} + +/* +=============== +idUsercmdGenLocal::Joystick +=============== +*/ +void idUsercmdGenLocal::Joystick( void ) { + memset( joystickAxis, 0, sizeof( joystickAxis ) ); +} + +/* +================ +idUsercmdGenLocal::UsercmdInterrupt + +Called asyncronously +================ +*/ +void idUsercmdGenLocal::UsercmdInterrupt( void ) { + // dedicated servers won't create usercmds + if ( !initialized ) { + return; + } + + // init the usercmd for com_ticNumber+1 + InitCurrent(); + + // process the system mouse events + Mouse(); + + // process the system keyboard events + Keyboard(); + + // process the system joystick events + Joystick(); + + // create the usercmd for com_ticNumber+1 + MakeCurrent(); + + // save a number for debugging cmdDemos and networking + cmd.sequence = com_ticNumber+1; + + buffered[(com_ticNumber+1) & (MAX_BUFFERED_USERCMD-1)] = cmd; +} + +/* +================ +idUsercmdGenLocal::MouseState +================ +*/ +void idUsercmdGenLocal::MouseState( int *x, int *y, int *button, bool *down ) { + *x = continuousMouseX; + *y = continuousMouseY; + *button = mouseButton; + *down = mouseDown; +} + +/* +================ +idUsercmdGenLocal::GetDirectUsercmd +================ +*/ +usercmd_t idUsercmdGenLocal::GetDirectUsercmd( void ) { + + // initialize current usercmd + InitCurrent(); + + // process the system mouse events + Mouse(); + + // process the system keyboard events + Keyboard(); + + // process the system joystick events + Joystick(); + + // create the usercmd + MakeCurrent(); + + cmd.duplicateCount = 0; + + return cmd; +} diff --git a/framework/UsercmdGen.h b/framework/UsercmdGen.h new file mode 100644 index 000000000..06e0b1893 --- /dev/null +++ b/framework/UsercmdGen.h @@ -0,0 +1,335 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __USERCMDGEN_H__ +#define __USERCMDGEN_H__ + +/* +=============================================================================== + + Samples a set of user commands from player input. + +=============================================================================== +*/ + +const int USERCMD_HZ = 60; // 60 frames per second +const int USERCMD_MSEC = 1000 / USERCMD_HZ; + +// ButtonState inputs; originally from UsercmdGen.cpp, left out of SDK by accident +// sourced from http://www.doom3world.org/phpbb2/viewtopic.php?f=26&t=18587&p=170143 +typedef enum { + UB_NONE, + + UB_UP, + UB_DOWN, + UB_LEFT, + UB_RIGHT, + UB_FORWARD, + UB_BACK, + UB_LOOKUP, + UB_LOOKDOWN, + UB_STRAFE, + UB_MOVELEFT, + UB_MOVERIGHT, + + UB_BUTTON0, + UB_BUTTON1, + UB_BUTTON2, + UB_BUTTON3, + UB_BUTTON4, + UB_BUTTON5, + UB_BUTTON6, + UB_BUTTON7, + + UB_ATTACK, + UB_SPEED, + UB_ZOOM, + UB_SHOWSCORES, + UB_MLOOK, + +#ifdef QUAKE4 + UB_INGAMESTATS, + UB_VOICECHAT, + UB_TOURNEY, +#endif//QUAKE4 + + UB_IMPULSE0, + UB_IMPULSE1, + UB_IMPULSE2, + UB_IMPULSE3, + UB_IMPULSE4, + UB_IMPULSE5, + UB_IMPULSE6, + UB_IMPULSE7, + UB_IMPULSE8, + UB_IMPULSE9, + UB_IMPULSE10, + UB_IMPULSE11, + UB_IMPULSE12, + UB_IMPULSE13, + UB_IMPULSE14, + UB_IMPULSE15, + UB_IMPULSE16, + UB_IMPULSE17, + UB_IMPULSE18, + UB_IMPULSE19, + UB_IMPULSE20, + UB_IMPULSE21, + UB_IMPULSE22, + UB_IMPULSE23, + UB_IMPULSE24, + UB_IMPULSE25, + UB_IMPULSE26, + UB_IMPULSE27, + UB_IMPULSE28, + UB_IMPULSE29, + UB_IMPULSE30, + UB_IMPULSE31, + UB_IMPULSE32, + UB_IMPULSE33, + UB_IMPULSE34, + UB_IMPULSE35, + UB_IMPULSE36, + UB_IMPULSE37, + UB_IMPULSE38, + UB_IMPULSE39, + UB_IMPULSE40, + UB_IMPULSE41, + UB_IMPULSE42, + UB_IMPULSE43, + UB_IMPULSE44, + UB_IMPULSE45, + UB_IMPULSE46, + UB_IMPULSE47, + UB_IMPULSE48, + UB_IMPULSE49, + UB_IMPULSE50, + UB_IMPULSE51, + UB_IMPULSE52, + UB_IMPULSE53, + UB_IMPULSE54, + UB_IMPULSE55, + UB_IMPULSE56, + UB_IMPULSE57, + UB_IMPULSE58, + UB_IMPULSE59, + UB_IMPULSE60, + UB_IMPULSE61, + UB_IMPULSE62, + UB_IMPULSE63, + + UB_MAX_BUTTONS +} UserCmdButton; + + +// usercmd_t->button bits +const int BUTTON_ATTACK = BIT(0); +const int BUTTON_RUN = BIT(1); +const int BUTTON_ZOOM = BIT(2); +const int BUTTON_SCORES = BIT(3); +const int BUTTON_MLOOK = BIT(4); +const int BUTTON_5 = BIT(5); +const int BUTTON_6 = BIT(6); +const int BUTTON_7 = BIT(7); + +// usercmd_t->impulse commands +enum { + IMPULSE_0, + IMPULSE_1, + IMPULSE_2, + IMPULSE_3, + IMPULSE_4, + IMPULSE_5, + IMPULSE_6, + IMPULSE_7, + IMPULSE_8, + IMPULSE_9, + IMPULSE_10, + IMPULSE_11, + IMPULSE_12, + IMPULSE_13, + IMPULSE_14, + IMPULSE_15, + IMPULSE_16, + IMPULSE_17, + IMPULSE_18, + IMPULSE_19, + IMPULSE_20, + IMPULSE_21, + IMPULSE_22, + IMPULSE_23, + IMPULSE_24, + IMPULSE_25, + IMPULSE_26, + IMPULSE_27, + IMPULSE_28, + IMPULSE_29, + IMPULSE_40 = 40, + IMPULSE_41, + IMPULSE_42, + IMPULSE_43, + IMPULSE_44, + IMPULSE_45, + IMPULSE_46, + IMPULSE_47, + IMPULSE_48, + IMPULSE_49, + IMPULSE_50, + IMPULSE_51, + IMPULSE_52, + IMPULSE_MAX +}; + +/* +const int IMPULSE_0 = 0; // weap 0 +const int IMPULSE_1 = 1; // weap 1 +const int IMPULSE_2 = 2; // weap 2 +const int IMPULSE_3 = 3; // weap 3 +const int IMPULSE_4 = 4; // weap 4 +const int IMPULSE_5 = 5; // weap 5 +const int IMPULSE_6 = 6; // weap 6 +const int IMPULSE_7 = 7; // weap 7 +const int IMPULSE_8 = 8; // weap 8 +const int IMPULSE_9 = 9; // weap 9 +const int IMPULSE_10 = 10; // weap 10 +const int IMPULSE_11 = 11; // weap 11 +const int IMPULSE_12 = 12; // weap 12 +const int IMPULSE_13 = 13; // weap reload +const int IMPULSE_14 = 14; // weap next +const int IMPULSE_15 = 15; // weap prev +const int IMPULSE_16 = 16; // +const int IMPULSE_17 = 17; // ready to play ( toggles ui_ready ) +const int IMPULSE_18 = 18; // center view +const int IMPULSE_19 = 19; // show PDA/INV/MAP +const int IMPULSE_20 = 20; // toggle team ( toggles ui_team ) +const int IMPULSE_21 = 21; // +const int IMPULSE_22 = 22; // spectate +const int IMPULSE_23 = 23; // +const int IMPULSE_24 = 24; // +const int IMPULSE_25 = 25; // +const int IMPULSE_26 = 26; // +const int IMPULSE_27 = 27; // +const int IMPULSE_28 = 28; // vote yes +const int IMPULSE_29 = 29; // vote no +const int IMPULSE_40 = 40; // use vehicle +const int IMPULSE_41 = 41; // TDM Use/Frob key +const int IMPULSE_42 = 42; // Inventory prev (unused) +const int IMPULSE_43 = 43; // Inventory next (unused) +const int IMPULSE_44 = 44; // Lean forward +const int IMPULSE_45 = 45; // Lean left +const int IMPULSE_46 = 46; // Lean right +const int IMPULSE_47 = 47; // Inventory prev item +const int IMPULSE_48 = 48; // Inventory next item +const int IMPULSE_49 = 49; // Inventory prev group +const int IMPULSE_50 = 50; // Inventory next group +const int IMPULSE_51 = 51; // Inventory use item +const int IMPULSE_52 = 52; // Inventory drop item +*/ + +// Darkmod: Added as a baseoffset for the impulse keys, when used with ButtonState. +// This function requires an int as input which defines the key that should be used, +// and it looks as if the first impulse starts with the number 25. +const int IMPULSE_BUTTON_BASE = 25; +#define KEY_FROM_IMPULSE(n) (n + IMPULSE_BUTTON_BASE) + +// usercmd_t->flags +const int UCF_IMPULSE_SEQUENCE = 0x0001; // toggled every time an impulse command is sent + +class usercmd_t { +public: + int gameFrame; // frame number + int gameTime; // game time + int duplicateCount; // duplication count for networking + byte buttons; // buttons + signed char forwardmove; // forward/backward movement + signed char rightmove; // left/right movement + signed char upmove; // up/down movement + short angles[3]; // view angles + short mx; // mouse delta x + short my; // mouse delta y + signed char impulse; // impulse command + byte flags; // additional flags + int sequence; // just for debugging + +public: + void ByteSwap(); // on big endian systems, byte swap the shorts and ints + bool operator==( const usercmd_t &rhs ) const; +}; + +typedef enum { + INHIBIT_SESSION = 0, + INHIBIT_ASYNC +} inhibit_t; + +const int MAX_BUFFERED_USERCMD = 64; + +class idUsercmdGen { +public: + virtual ~idUsercmdGen( void ) {} + + // Sets up all the cvars and console commands. + virtual void Init( void ) = 0; + + // Prepares for a new map. + virtual void InitForNewMap( void ) = 0; + + // Shut down. + virtual void Shutdown( void ) = 0; + + // Clears all key states and face straight. + virtual void Clear( void ) = 0; + + // Clears view angles. + virtual void ClearAngles( void ) = 0; + + // When the console is down or the menu is up, only emit default usercmd, so the player isn't moving around. + // Each subsystem (session and game) may want an inhibit will OR the requests. + virtual void InhibitUsercmd( inhibit_t subsystem, bool inhibit ) = 0; + + // Returns a buffered command for the given game tic. + virtual usercmd_t TicCmd( int ticNumber ) = 0; + + // Called async at regular intervals. + virtual void UsercmdInterrupt( void ) = 0; + + // Set a value that can safely be referenced by UsercmdInterrupt() for each key binding. + virtual int CommandStringUsercmdData( const char *cmdString ) = 0; + + // Returns the number of user commands. + virtual int GetNumUserCommands( void ) = 0; + + // Returns the name of a user command via index. + virtual const char *GetUserCommandName( int index ) = 0; + + // Continuously modified, never reset. For full screen guis. + virtual void MouseState( int *x, int *y, int *button, bool *down ) = 0; + + // Directly sample a button. + virtual int ButtonState( int key ) = 0; + + // Directly sample a keystate. + virtual int KeyState( int key ) = 0; + + // Directly sample a usercmd. + virtual usercmd_t GetDirectUsercmd( void ) = 0; +}; + +extern idUsercmdGen *usercmdGen; + +#endif /* !__USERCMDGEN_H__ */ diff --git a/framework/async/AsyncClient.cpp b/framework/async/AsyncClient.cpp new file mode 100644 index 000000000..f7b936dfb --- /dev/null +++ b/framework/async/AsyncClient.cpp @@ -0,0 +1,2325 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "AsyncNetwork.h" + +#include "../Session_local.h" + +const int SETUP_CONNECTION_RESEND_TIME = 1000; +const int EMPTY_RESEND_TIME = 500; +const int PREDICTION_FAST_ADJUST = 4; + + +/* +================== +idAsyncClient::idAsyncClient +================== +*/ +idAsyncClient::idAsyncClient( void ) { + guiNetMenu = NULL; + updateState = UPDATE_NONE; + Clear(); +} + +/* +================== +idAsyncClient::Clear +================== +*/ +void idAsyncClient::Clear( void ) { + active = false; + realTime = 0; + clientTime = 0; + clientId = 0; + clientDataChecksum = 0; + clientNum = 0; + clientState = CS_DISCONNECTED; + clientPrediction = 0; + clientPredictTime = 0; + serverId = 0; + serverChallenge = 0; + serverMessageSequence = 0; + lastConnectTime = -9999; + lastEmptyTime = -9999; + lastPacketTime = -9999; + lastSnapshotTime = -9999; + snapshotGameFrame = 0; + snapshotGameTime = 0; + snapshotSequence = 0; + gameInitId = GAME_INIT_ID_INVALID; + gameFrame = 0; + gameTimeResidual = 0; + gameTime = 0; + memset( userCmds, 0, sizeof( userCmds ) ); + backgroundDownload.completed = true; + lastRconTime = 0; + showUpdateMessage = false; + lastFrameDelta = 0; + + dlRequest = -1; + dlCount = -1; + memset( dlChecksums, 0, sizeof( int ) * MAX_PURE_PAKS ); + currentDlSize = 0; + totalDlSize = 0; +} + +/* +================== +idAsyncClient::Shutdown +================== +*/ +void idAsyncClient::Shutdown( void ) { + guiNetMenu = NULL; + updateMSG.Clear(); + updateURL.Clear(); + updateFile.Clear(); + updateFallback.Clear(); + backgroundDownload.url.url.Clear(); + dlList.Clear(); +} + +/* +================== +idAsyncClient::InitPort +================== +*/ +bool idAsyncClient::InitPort( void ) { + // if this is the first time we connect to a server, open the UDP port + if ( !clientPort.GetPort() ) { + if ( !clientPort.InitForPort( PORT_ANY ) ) { + common->Printf( "Couldn't open client network port.\n" ); + return false; + } + } + // maintain it valid between connects and ui manager reloads + guiNetMenu = uiManager->FindGui( "guis/netmenu.gui", true, false, true ); + + return true; +} + +/* +================== +idAsyncClient::ClosePort +================== +*/ +void idAsyncClient::ClosePort( void ) { + clientPort.Close(); +} + +/* +================== +idAsyncClient::ClearPendingPackets +================== +*/ +void idAsyncClient::ClearPendingPackets( void ) { + int size; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t from; + + while( clientPort.GetPacket( from, msgBuf, size, sizeof( msgBuf ) ) ) { + } +} + +/* +================== +idAsyncClient::HandleGuiCommandInternal +================== +*/ +const char* idAsyncClient::HandleGuiCommandInternal( const char *cmd ) { + if ( !idStr::Cmp( cmd, "abort" ) || !idStr::Cmp( cmd, "pure_abort" ) ) { + common->DPrintf( "connection aborted\n" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + return ""; + } else { + common->DWarning( "idAsyncClient::HandleGuiCommand: unknown cmd %s", cmd ); + } + return NULL; +} + +/* +================== +idAsyncClient::HandleGuiCommand +================== +*/ +const char* idAsyncClient::HandleGuiCommand( const char *cmd ) { + return idAsyncNetwork::client.HandleGuiCommandInternal( cmd ); +} + +/* +================== +idAsyncClient::ConnectToServer +================== +*/ +void idAsyncClient::ConnectToServer( const netadr_t adr ) { + // shutdown any current game. that includes network disconnect + session->Stop(); + + if ( !InitPort() ) { + return; + } + + if ( cvarSystem->GetCVarBool( "net_serverDedicated" ) ) { + common->Printf( "Can't connect to a server as dedicated\n" ); + return; + } + + // trash any currently pending packets + ClearPendingPackets(); + + serverAddress = adr; + + // clear the client state + Clear(); + + // get a pseudo random client id, but don't use the id which is reserved for connectionless packets + clientId = Sys_Milliseconds() & CONNECTIONLESS_MESSAGE_ID_MASK; + + // calculate a checksum on some of the essential data used + clientDataChecksum = declManager->GetChecksum(); + + // start challenging the server + clientState = CS_CHALLENGING; + + active = true; + + guiNetMenu = uiManager->FindGui( "guis/netmenu.gui", true, false, true ); + guiNetMenu->SetStateString( "status", va( common->GetLanguageDict()->GetString( "#str_06749" ), Sys_NetAdrToString( adr ) ) ); + session->SetGUI( guiNetMenu, HandleGuiCommand ); +} + +/* +================== +idAsyncClient::Reconnect +================== +*/ +void idAsyncClient::Reconnect( void ) { + ConnectToServer( serverAddress ); +} + +/* +================== +idAsyncClient::ConnectToServer +================== +*/ +void idAsyncClient::ConnectToServer( const char *address ) { + int serverNum; + netadr_t adr; + + if ( idStr::IsNumeric( address ) ) { + serverNum = atoi( address ); + if ( serverNum < 0 || serverNum >= serverList.Num() ) { + session->MessageBox( MSG_OK, va( common->GetLanguageDict()->GetString( "#str_06733" ), serverNum ), common->GetLanguageDict()->GetString( "#str_06735" ), true ); + return; + } + adr = serverList[ serverNum ].adr; + } else { + if ( !Sys_StringToNetAdr( address, &adr, true ) ) { + session->MessageBox( MSG_OK, va( common->GetLanguageDict()->GetString( "#str_06734" ), address ), common->GetLanguageDict()->GetString( "#str_06735" ), true ); + return; + } + } + if ( !adr.port ) { + adr.port = PORT_SERVER; + } + + common->Printf( "\"%s\" resolved to %s\n", address, Sys_NetAdrToString( adr ) ); + + ConnectToServer( adr ); +} + +/* +================== +idAsyncClient::DisconnectFromServer +================== +*/ +void idAsyncClient::DisconnectFromServer( void ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( clientState >= CS_CONNECTED ) { + // if we were actually connected, clear the pure list + fileSystem->ClearPureChecksums(); + + // send reliable disconnect to server + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( CLIENT_RELIABLE_MESSAGE_DISCONNECT ); + msg.WriteString( "disconnect" ); + + if ( !channel.SendReliableMessage( msg ) ) { + common->Error( "client->server reliable messages overflow\n" ); + } + + SendEmptyToServer( true ); + SendEmptyToServer( true ); + SendEmptyToServer( true ); + } + + if ( clientState != CS_PURERESTART ) { + channel.Shutdown(); + clientState = CS_DISCONNECTED; + } + + active = false; +} + +/* +================== +idAsyncClient::GetServerInfo +================== +*/ +void idAsyncClient::GetServerInfo( const netadr_t adr ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( !InitPort() ) { + return; + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "getInfo" ); + msg.WriteLong( serverList.GetChallenge() ); // challenge + + clientPort.SendPacket( adr, msg.GetData(), msg.GetSize() ); +} + +/* +================== +idAsyncClient::GetServerInfo +================== +*/ +void idAsyncClient::GetServerInfo( const char *address ) { + netadr_t adr; + + if ( address && *address != '\0' ) { + if ( !Sys_StringToNetAdr( address, &adr, true ) ) { + common->Printf( "Couldn't get server address for \"%s\"\n", address ); + return; + } + } else if ( active ) { + adr = serverAddress; + } else if ( idAsyncNetwork::server.IsActive() ) { + // used to be a Sys_StringToNetAdr( "localhost", &adr, true ); and send a packet over loopback + // but this breaks with net_ip ( typically, for multi-homed servers ) + idAsyncNetwork::server.PrintLocalServerInfo(); + return; + } else { + common->Printf( "no server found\n" ); + return; + } + + if ( !adr.port ) { + adr.port = PORT_SERVER; + } + + GetServerInfo( adr ); +} + +/* +================== +idAsyncClient::GetLANServers +================== +*/ +void idAsyncClient::GetLANServers( void ) { + int i; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t broadcastAddress; + + if ( !InitPort() ) { + return; + } + + idAsyncNetwork::LANServer.SetBool( true ); + + serverList.SetupLANScan(); + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "getInfo" ); + msg.WriteLong( serverList.GetChallenge() ); + + broadcastAddress.type = NA_BROADCAST; + for ( i = 0; i < MAX_SERVER_PORTS; i++ ) { + broadcastAddress.port = PORT_SERVER + i; + clientPort.SendPacket( broadcastAddress, msg.GetData(), msg.GetSize() ); + } +} + +/* +================== +idAsyncClient::GetNETServers +================== +*/ +void idAsyncClient::GetNETServers( void ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + idAsyncNetwork::LANServer.SetBool( false ); + + // NetScan only clears GUI and results, not the stored list + serverList.Clear( ); + serverList.NetScan( ); + serverList.StartServers( true ); + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "getServers" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); + msg.WriteString( cvarSystem->GetCVarString( "fs_game" ) ); + msg.WriteBits( cvarSystem->GetCVarInteger( "gui_filter_password" ), 2 ); + msg.WriteBits( cvarSystem->GetCVarInteger( "gui_filter_players" ), 2 ); + msg.WriteBits( cvarSystem->GetCVarInteger( "gui_filter_gameType" ), 2 ); + + netadr_t adr; + if ( idAsyncNetwork::GetMasterAddress( 0, adr ) ) { + clientPort.SendPacket( adr, msg.GetData(), msg.GetSize() ); + } +} + +/* +================== +idAsyncClient::ListServers +================== +*/ +void idAsyncClient::ListServers( void ) { + int i; + + for ( i = 0; i < serverList.Num(); i++ ) { + common->Printf( "%3d: %s %dms (%s)\n", i, serverList[i].serverInfo.GetString( "si_name" ), serverList[ i ].ping, Sys_NetAdrToString( serverList[i].adr ) ); + } +} + +/* +================== +idAsyncClient::ClearServers +================== +*/ +void idAsyncClient::ClearServers( void ) { + serverList.Clear(); +} + +/* +================== +idAsyncClient::RemoteConsole +================== +*/ +void idAsyncClient::RemoteConsole( const char *command ) { + netadr_t adr; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( !InitPort() ) { + return; + } + + if ( active ) { + adr = serverAddress; + } else { + Sys_StringToNetAdr( idAsyncNetwork::clientRemoteConsoleAddress.GetString(), &adr, true ); + } + + if ( !adr.port ) { + adr.port = PORT_SERVER; + } + + lastRconAddress = adr; + lastRconTime = realTime; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "rcon" ); + msg.WriteString( idAsyncNetwork::clientRemoteConsolePassword.GetString() ); + msg.WriteString( command ); + + clientPort.SendPacket( adr, msg.GetData(), msg.GetSize() ); +} + +/* +================== +idAsyncClient::GetPrediction +================== +*/ +int idAsyncClient::GetPrediction( void ) const { + if ( clientState < CS_CONNECTED ) { + return -1; + } else { + return clientPrediction; + } +} + +/* +================== +idAsyncClient::GetTimeSinceLastPacket +================== +*/ +int idAsyncClient::GetTimeSinceLastPacket( void ) const { + if ( clientState < CS_CONNECTED ) { + return -1; + } else { + return clientTime - lastPacketTime; + } +} + +/* +================== +idAsyncClient::GetOutgoingRate +================== +*/ +int idAsyncClient::GetOutgoingRate( void ) const { + if ( clientState < CS_CONNECTED ) { + return -1; + } else { + return channel.GetOutgoingRate(); + } +} + +/* +================== +idAsyncClient::GetIncomingRate +================== +*/ +int idAsyncClient::GetIncomingRate( void ) const { + if ( clientState < CS_CONNECTED ) { + return -1; + } else { + return channel.GetIncomingRate(); + } +} + +/* +================== +idAsyncClient::GetOutgoingCompression +================== +*/ +float idAsyncClient::GetOutgoingCompression( void ) const { + if ( clientState < CS_CONNECTED ) { + return 0.0f; + } else { + return channel.GetOutgoingCompression(); + } +} + +/* +================== +idAsyncClient::GetIncomingCompression +================== +*/ +float idAsyncClient::GetIncomingCompression( void ) const { + if ( clientState < CS_CONNECTED ) { + return 0.0f; + } else { + return channel.GetIncomingCompression(); + } +} + +/* +================== +idAsyncClient::GetIncomingPacketLoss +================== +*/ +float idAsyncClient::GetIncomingPacketLoss( void ) const { + if ( clientState < CS_CONNECTED ) { + return 0.0f; + } else { + return channel.GetIncomingPacketLoss(); + } +} + +/* +================== +idAsyncClient::DuplicateUsercmds +================== +*/ +void idAsyncClient::DuplicateUsercmds( int frame, int time ) { + int i, previousIndex, currentIndex; + + previousIndex = ( frame - 1 ) & ( MAX_USERCMD_BACKUP - 1 ); + currentIndex = frame & ( MAX_USERCMD_BACKUP - 1 ); + + // duplicate previous user commands if no new commands are available for a client + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + idAsyncNetwork::DuplicateUsercmd( userCmds[previousIndex][i], userCmds[currentIndex][i], frame, time ); + } +} + +/* +================== +idAsyncClient::SendUserInfoToServer +================== +*/ +void idAsyncClient::SendUserInfoToServer( void ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + idDict info; + + if ( clientState < CS_CONNECTED ) { + return; + } + + info = *cvarSystem->MoveCVarsToDict( CVAR_USERINFO ); + + // send reliable client info to server + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( CLIENT_RELIABLE_MESSAGE_CLIENTINFO ); + msg.WriteDeltaDict( info, &sessLocal.mapSpawnData.userInfo[ clientNum ] ); + + if ( !channel.SendReliableMessage( msg ) ) { + common->Error( "client->server reliable messages overflow\n" ); + } + + sessLocal.mapSpawnData.userInfo[clientNum] = info; +} + +/* +================== +idAsyncClient::SendEmptyToServer +================== +*/ +void idAsyncClient::SendEmptyToServer( bool force, bool mapLoad ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( lastEmptyTime > realTime ) { + lastEmptyTime = realTime; + } + + if ( !force && ( realTime - lastEmptyTime < EMPTY_RESEND_TIME ) ) { + return; + } + + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "sending empty to server, gameInitId = %d\n", mapLoad ? GAME_INIT_ID_MAP_LOAD : gameInitId ); + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( serverMessageSequence ); + msg.WriteLong( mapLoad ? GAME_INIT_ID_MAP_LOAD : gameInitId ); + msg.WriteLong( snapshotSequence ); + msg.WriteByte( CLIENT_UNRELIABLE_MESSAGE_EMPTY ); + + channel.SendMessage( clientPort, clientTime, msg ); + + while( channel.UnsentFragmentsLeft() ) { + channel.SendNextFragment( clientPort, clientTime ); + } + + lastEmptyTime = realTime; +} + +/* +================== +idAsyncClient::SendPingResponseToServer +================== +*/ +void idAsyncClient::SendPingResponseToServer( int time ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "sending ping response to server, gameInitId = %d\n", gameInitId ); + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( serverMessageSequence ); + msg.WriteLong( gameInitId ); + msg.WriteLong( snapshotSequence ); + msg.WriteByte( CLIENT_UNRELIABLE_MESSAGE_PINGRESPONSE ); + msg.WriteLong( time ); + + channel.SendMessage( clientPort, clientTime, msg ); + while( channel.UnsentFragmentsLeft() ) { + channel.SendNextFragment( clientPort, clientTime ); + } +} + +/* +================== +idAsyncClient::SendUsercmdsToServer +================== +*/ +void idAsyncClient::SendUsercmdsToServer( void ) { + int i, numUsercmds, index; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + usercmd_t * last; + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "sending usercmd to server: gameInitId = %d, gameFrame = %d, gameTime = %d\n", gameInitId, gameFrame, gameTime ); + } + + // generate user command for this client + index = gameFrame & ( MAX_USERCMD_BACKUP - 1 ); + userCmds[index][clientNum] = usercmdGen->GetDirectUsercmd(); + userCmds[index][clientNum].gameFrame = gameFrame; + userCmds[index][clientNum].gameTime = gameTime; + + // send the user commands to the server + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( serverMessageSequence ); + msg.WriteLong( gameInitId ); + msg.WriteLong( snapshotSequence ); + msg.WriteByte( CLIENT_UNRELIABLE_MESSAGE_USERCMD ); + msg.WriteShort( clientPrediction ); + + numUsercmds = idMath::ClampInt( 0, 10, idAsyncNetwork::clientUsercmdBackup.GetInteger() ) + 1; + + // write the user commands + msg.WriteLong( gameFrame ); + msg.WriteByte( numUsercmds ); + for ( last = NULL, i = gameFrame - numUsercmds + 1; i <= gameFrame; i++ ) { + index = i & ( MAX_USERCMD_BACKUP - 1 ); + idAsyncNetwork::WriteUserCmdDelta( msg, userCmds[index][clientNum], last ); + last = &userCmds[index][clientNum]; + } + + channel.SendMessage( clientPort, clientTime, msg ); + while( channel.UnsentFragmentsLeft() ) { + channel.SendNextFragment( clientPort, clientTime ); + } +} + +/* +================== +idAsyncClient::InitGame +================== +*/ +void idAsyncClient::InitGame( int serverGameInitId, int serverGameFrame, int serverGameTime, const idDict &serverSI ) { + gameInitId = serverGameInitId; + gameFrame = snapshotGameFrame = serverGameFrame; + gameTime = snapshotGameTime = serverGameTime; + gameTimeResidual = 0; + memset( userCmds, 0, sizeof( userCmds ) ); + + for ( int i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + sessLocal.mapSpawnData.userInfo[ i ].Clear(); + } + + sessLocal.mapSpawnData.serverInfo = serverSI; +} + +/* +================== +idAsyncClient::ProcessUnreliableServerMessage +================== +*/ +void idAsyncClient::ProcessUnreliableServerMessage( const idBitMsg &msg ) { + int i, j, index, id, numDuplicatedUsercmds, aheadOfServer, numUsercmds, delta; + int serverGameInitId, serverGameFrame, serverGameTime; + idDict serverSI; + usercmd_t *last; + bool pureWait; + + serverGameInitId = msg.ReadLong(); + + id = msg.ReadByte(); + switch( id ) { + case SERVER_UNRELIABLE_MESSAGE_EMPTY: { + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "received empty message from server\n" ); + } + break; + } + case SERVER_UNRELIABLE_MESSAGE_PING: { + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "received ping message from server\n" ); + } + SendPingResponseToServer( msg.ReadLong() ); + break; + } + case SERVER_UNRELIABLE_MESSAGE_GAMEINIT: { + serverGameFrame = msg.ReadLong(); + serverGameTime = msg.ReadLong(); + msg.ReadDeltaDict( serverSI, NULL ); + pureWait = serverSI.GetBool( "si_pure" ); + + InitGame( serverGameInitId, serverGameFrame, serverGameTime, serverSI ); + + channel.ResetRate(); + + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "received gameinit, gameInitId = %d, gameFrame = %d, gameTime = %d\n", gameInitId, gameFrame, gameTime ); + } + + // mute sound + soundSystem->SetMute( true ); + + // ensure chat icon goes away when the GUI is changed... + //cvarSystem->SetCVarBool( "ui_chat", false ); + + if ( pureWait ) { + guiNetMenu = uiManager->FindGui( "guis/netmenu.gui", true, false, true ); + session->SetGUI( guiNetMenu, HandleGuiCommand ); + session->MessageBox( MSG_ABORT, common->GetLanguageDict()->GetString ( "#str_04317" ), common->GetLanguageDict()->GetString ( "#str_04318" ), false, "pure_abort" ); + } else { + // load map + session->SetGUI( NULL, NULL ); + sessLocal.ExecuteMapChange(); + } + + break; + } + case SERVER_UNRELIABLE_MESSAGE_SNAPSHOT: { + // if the snapshot is from a different game + if ( serverGameInitId != gameInitId ) { + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "ignoring snapshot with != gameInitId\n" ); + } + break; + } + + snapshotSequence = msg.ReadLong(); + snapshotGameFrame = msg.ReadLong(); + snapshotGameTime = msg.ReadLong(); + numDuplicatedUsercmds = msg.ReadByte(); + aheadOfServer = msg.ReadShort(); + + // read the game snapshot + game->ClientReadSnapshot( clientNum, snapshotSequence, snapshotGameFrame, snapshotGameTime, numDuplicatedUsercmds, aheadOfServer, msg ); + + // read user commands of other clients from the snapshot + for ( last = NULL, i = msg.ReadByte(); i < MAX_ASYNC_CLIENTS; i = msg.ReadByte() ) { + numUsercmds = msg.ReadByte(); + if ( numUsercmds > MAX_USERCMD_RELAY ) { + common->Error( "snapshot %d contains too many user commands for client %d", snapshotSequence, i ); + break; + } + for ( j = 0; j < numUsercmds; j++ ) { + index = ( snapshotGameFrame + j ) & ( MAX_USERCMD_BACKUP - 1 ); + idAsyncNetwork::ReadUserCmdDelta( msg, userCmds[index][i], last ); + userCmds[index][i].gameFrame = snapshotGameFrame + j; + userCmds[index][i].duplicateCount = 0; + last = &userCmds[index][i]; + } + // clear all user commands after the ones just read from the snapshot + for ( j = numUsercmds; j < MAX_USERCMD_BACKUP; j++ ) { + index = ( snapshotGameFrame + j ) & ( MAX_USERCMD_BACKUP - 1 ); + userCmds[index][i].gameFrame = 0; + userCmds[index][i].gameTime = 0; + } + } + + // if this is the first snapshot after a game init was received + if ( clientState == CS_CONNECTED ) { + gameTimeResidual = 0; + clientState = CS_INGAME; + assert( !sessLocal.GetActiveMenu( ) ); + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "received first snapshot, gameInitId = %d, gameFrame %d gameTime %d\n", gameInitId, snapshotGameFrame, snapshotGameTime ); + } + } + + // if the snapshot is newer than the clients current game time + if ( gameTime < snapshotGameTime || gameTime > snapshotGameTime + idAsyncNetwork::clientMaxPrediction.GetInteger() ) { + gameFrame = snapshotGameFrame; + gameTime = snapshotGameTime; + gameTimeResidual = idMath::ClampInt( -idAsyncNetwork::clientMaxPrediction.GetInteger(), idAsyncNetwork::clientMaxPrediction.GetInteger(), gameTimeResidual ); + clientPredictTime = idMath::ClampInt( -idAsyncNetwork::clientMaxPrediction.GetInteger(), idAsyncNetwork::clientMaxPrediction.GetInteger(), clientPredictTime ); + } + + // adjust the client prediction time based on the snapshot time + clientPrediction -= ( 1 - ( INTSIGNBITSET( aheadOfServer - idAsyncNetwork::clientPrediction.GetInteger() ) << 1 ) ); + clientPrediction = idMath::ClampInt( idAsyncNetwork::clientPrediction.GetInteger(), idAsyncNetwork::clientMaxPrediction.GetInteger(), clientPrediction ); + delta = gameTime - ( snapshotGameTime + clientPrediction ); + clientPredictTime -= ( delta / PREDICTION_FAST_ADJUST ) + ( 1 - ( INTSIGNBITSET( delta ) << 1 ) ); + + lastSnapshotTime = clientTime; + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "received snapshot, gameInitId = %d, gameFrame = %d, gameTime = %d\n", gameInitId, gameFrame, gameTime ); + } + + if ( numDuplicatedUsercmds && ( idAsyncNetwork::verbose.GetInteger() == 2 ) ) { + common->Printf( "server duplicated %d user commands before snapshot %d\n", numDuplicatedUsercmds, snapshotGameFrame ); + } + break; + } + default: { + common->Printf( "unknown unreliable server message %d\n", id ); + break; + } + } +} + +/* +================== +idAsyncClient::ProcessReliableMessagePure +================== +*/ +void idAsyncClient::ProcessReliableMessagePure( const idBitMsg &msg ) { + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + int inChecksums[ MAX_PURE_PAKS ]; + int i; + int gamePakChecksum; + int serverGameInitId; + + session->SetGUI( NULL, NULL ); + + serverGameInitId = msg.ReadLong(); + + if ( serverGameInitId != gameInitId ) { + common->DPrintf( "ignoring pure server checksum from an outdated gameInitId (%d)\n", serverGameInitId ); + return; + } + + if ( !ValidatePureServerChecksums( serverAddress, msg ) ) { + + return; + } + + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "received new pure server info. ExecuteMapChange and report back\n" ); + } + + // it is now ok to load the next map with updated pure checksums + sessLocal.ExecuteMapChange( true ); + + // upon receiving our pure list, the server will send us SCS_INGAME and we'll start getting snapshots + fileSystem->GetPureServerChecksums( inChecksums, -1, &gamePakChecksum ); + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( CLIENT_RELIABLE_MESSAGE_PURE ); + + outMsg.WriteLong( gameInitId ); + + i = 0; + while ( inChecksums[ i ] ) { + outMsg.WriteLong( inChecksums[ i++ ] ); + } + outMsg.WriteLong( 0 ); + outMsg.WriteLong( gamePakChecksum ); + + if ( !channel.SendReliableMessage( outMsg ) ) { + common->Error( "client->server reliable messages overflow\n" ); + } +} + +/* +=============== +idAsyncClient::ReadLocalizedServerString +=============== +*/ +void idAsyncClient::ReadLocalizedServerString( const idBitMsg &msg, char *out, int maxLen ) { + msg.ReadString( out, maxLen ); + // look up localized string. if the message is not an #str_ format, we'll just get it back unchanged + idStr::snPrintf( out, maxLen - 1, "%s", common->GetLanguageDict()->GetString( out ) ); +} + +/* +================== +idAsyncClient::ProcessReliableServerMessages +================== +*/ +void idAsyncClient::ProcessReliableServerMessages( void ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + byte id; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + + while ( channel.GetReliableMessage( msg ) ) { + id = msg.ReadByte(); + switch( id ) { + case SERVER_RELIABLE_MESSAGE_CLIENTINFO: { + int clientNum; + clientNum = msg.ReadByte(); + + idDict &info = sessLocal.mapSpawnData.userInfo[ clientNum ]; + bool haveBase = ( msg.ReadBits( 1 ) != 0 ); + +#if ID_CLIENTINFO_TAGS + int checksum = info.Checksum(); + int srv_checksum = msg.ReadLong(); + if ( checksum != srv_checksum ) { + common->DPrintf( "SERVER_RELIABLE_MESSAGE_CLIENTINFO %d (haveBase: %s): != checksums srv: 0x%x local: 0x%x\n", clientNum, haveBase ? "true" : "false", checksum, srv_checksum ); + info.Print(); + } else { + common->DPrintf( "SERVER_RELIABLE_MESSAGE_CLIENTINFO %d (haveBase: %s): checksums ok 0x%x\n", clientNum, haveBase ? "true" : "false", checksum ); + } +#endif + + if ( haveBase ) { + msg.ReadDeltaDict( info, &info ); + } else { + msg.ReadDeltaDict( info, NULL ); + } + + // server forces us to a different userinfo + if ( clientNum == idAsyncClient::clientNum ) { + common->DPrintf( "local user info modified by server\n" ); + cvarSystem->SetCVarsFromDict( info ); + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); // don't emit back + } + game->SetUserInfo( clientNum, info, true, false ); + break; + } + case SERVER_RELIABLE_MESSAGE_SYNCEDCVARS: { + idDict &info = sessLocal.mapSpawnData.syncedCVars; + msg.ReadDeltaDict( info, &info ); + cvarSystem->SetCVarsFromDict( info ); + if ( !idAsyncNetwork::allowCheats.GetBool() ) { + cvarSystem->ResetFlaggedVariables( CVAR_CHEAT ); + } + break; + } + case SERVER_RELIABLE_MESSAGE_PRINT: { + char string[MAX_STRING_CHARS]; + msg.ReadString( string, MAX_STRING_CHARS ); + common->Printf( "%s\n", string ); + break; + } + case SERVER_RELIABLE_MESSAGE_DISCONNECT: { + int clientNum; + char string[MAX_STRING_CHARS]; + clientNum = msg.ReadLong( ); + ReadLocalizedServerString( msg, string, MAX_STRING_CHARS ); + if ( clientNum == idAsyncClient::clientNum ) { + session->Stop(); + session->MessageBox( MSG_OK, string, common->GetLanguageDict()->GetString ( "#str_04319" ), true ); + session->StartMenu(); + } else { + common->Printf( "client %d %s\n", clientNum, string ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "addChatLine \"%s^0 %s\"", sessLocal.mapSpawnData.userInfo[ clientNum ].GetString( "ui_name" ), string ) ); + sessLocal.mapSpawnData.userInfo[ clientNum ].Clear(); + } + break; + } + case SERVER_RELIABLE_MESSAGE_APPLYSNAPSHOT: { + int sequence; + sequence = msg.ReadLong(); + if ( !game->ClientApplySnapshot( clientNum, sequence ) ) { + session->Stop(); + common->Error( "couldn't apply snapshot %d", sequence ); + } + break; + } + case SERVER_RELIABLE_MESSAGE_PURE: { + ProcessReliableMessagePure( msg ); + break; + } + case SERVER_RELIABLE_MESSAGE_RELOAD: { + if ( idAsyncNetwork::verbose.GetBool() ) { + common->Printf( "got MESSAGE_RELOAD from server\n" ); + } + // simply reconnect, so that if the server restarts in pure mode we can get the right list and avoid spurious reloads + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reconnect\n" ); + break; + } + case SERVER_RELIABLE_MESSAGE_ENTERGAME: { + SendUserInfoToServer(); + game->SetUserInfo( clientNum, sessLocal.mapSpawnData.userInfo[ clientNum ], true, false ); + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); + break; + } + default: { + // pass reliable message on to game code + game->ClientProcessReliableMessage( clientNum, msg ); + break; + } + } + } +} + +/* +================== +idAsyncClient::ProcessChallengeResponseMessage +================== +*/ +void idAsyncClient::ProcessChallengeResponseMessage( const netadr_t from, const idBitMsg &msg ) { + char serverGame[ MAX_STRING_CHARS ], serverGameBase[ MAX_STRING_CHARS ]; + + if ( clientState != CS_CHALLENGING ) { + common->Printf( "Unwanted challenge response received.\n" ); + return; + } + + serverChallenge = msg.ReadLong(); + serverId = msg.ReadShort(); + msg.ReadString( serverGameBase, MAX_STRING_CHARS ); + msg.ReadString( serverGame, MAX_STRING_CHARS ); + + // the server is running a different game... we need to reload in the correct fs_game + // even pure pak checks would fail if we didn't, as there are files we may not even see atm + // NOTE: we could read the pure list from the server at the same time and set it up for the restart + // ( if the client can restart directly with the right pak order, then we avoid an extra reloadEngine later.. ) + if ( idStr::Icmp( cvarSystem->GetCVarString( "fs_game_base" ), serverGameBase ) || + idStr::Icmp( cvarSystem->GetCVarString( "fs_game" ), serverGame ) ) { + // bug #189 - if the server is running ROE and ROE is not locally installed, refuse to connect or we might crash + if ( !fileSystem->HasD3XP() && ( !idStr::Icmp( serverGameBase, "d3xp" ) || !idStr::Icmp( serverGame, "d3xp" ) ) ) { + common->Printf( "The server is running Doom3: Resurrection of Evil expansion pack. RoE is not installed on this client. Aborting the connection..\n" ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + return; + } + common->Printf( "The server is running a different mod (%s-%s). Restarting..\n", serverGameBase, serverGame ); + cvarSystem->SetCVarString( "fs_game_base", serverGameBase ); + cvarSystem->SetCVarString( "fs_game", serverGame ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadEngine" ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reconnect\n" ); + return; + } + + common->Printf( "received challenge response 0x%x from %s\n", serverChallenge, Sys_NetAdrToString( from ) ); + + // start sending connect packets instead of challenge request packets + clientState = CS_CONNECTING; + lastConnectTime = -9999; + + // take this address as the new server address. This allows + // a server proxy to hand off connections to multiple servers + serverAddress = from; +} + +/* +================== +idAsyncClient::ProcessConnectResponseMessage +================== +*/ +void idAsyncClient::ProcessConnectResponseMessage( const netadr_t from, const idBitMsg &msg ) { + int serverGameInitId, serverGameFrame, serverGameTime; + idDict serverSI; + + if ( clientState >= CS_CONNECTED ) { + common->Printf( "Duplicate connect received.\n" ); + return; + } + if ( clientState != CS_CONNECTING ) { + common->Printf( "Connect response packet while not connecting.\n" ); + return; + } + if ( !Sys_CompareNetAdrBase( from, serverAddress ) ) { + common->Printf( "Connect response from a different server.\n" ); + common->Printf( "%s should have been %s\n", Sys_NetAdrToString( from ), Sys_NetAdrToString( serverAddress ) ); + return; + } + + common->Printf( "received connect response from %s\n", Sys_NetAdrToString( from ) ); + + channel.Init( from, clientId ); + clientNum = msg.ReadLong(); + clientState = CS_CONNECTED; + lastPacketTime = -9999; + + serverGameInitId = msg.ReadLong(); + serverGameFrame = msg.ReadLong(); + serverGameTime = msg.ReadLong(); + msg.ReadDeltaDict( serverSI, NULL ); + + InitGame( serverGameInitId, serverGameFrame, serverGameTime, serverSI ); + + // load map + session->SetGUI( NULL, NULL ); + sessLocal.ExecuteMapChange(); + + clientPredictTime = clientPrediction = idMath::ClampInt( 0, idAsyncNetwork::clientMaxPrediction.GetInteger(), clientTime - lastConnectTime ); +} + +/* +================== +idAsyncClient::ProcessDisconnectMessage +================== +*/ +void idAsyncClient::ProcessDisconnectMessage( const netadr_t from, const idBitMsg &msg ) { + if ( clientState == CS_DISCONNECTED ) { + common->Printf( "Disconnect packet while not connected.\n" ); + return; + } + if ( !Sys_CompareNetAdrBase( from, serverAddress ) ) { + common->Printf( "Disconnect packet from unknown server.\n" ); + return; + } + session->Stop(); + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04320" ), NULL, true ); + session->StartMenu(); +} + +/* +================== +idAsyncClient::ProcessInfoResponseMessage +================== +*/ +void idAsyncClient::ProcessInfoResponseMessage( const netadr_t from, const idBitMsg &msg ) { + int i, protocol, index; + networkServer_t serverInfo; + bool verbose = false; + + if ( from.type == NA_LOOPBACK || cvarSystem->GetCVarBool( "developer" ) ) { + verbose = true; + } + + serverInfo.clients = 0; + serverInfo.adr = from; + serverInfo.challenge = msg.ReadLong(); // challenge + protocol = msg.ReadLong(); + if ( protocol != ASYNC_PROTOCOL_VERSION ) { + common->Printf( "server %s ignored - protocol %d.%d, expected %d.%d\n", Sys_NetAdrToString( serverInfo.adr ), protocol >> 16, protocol & 0xffff, ASYNC_PROTOCOL_MAJOR, ASYNC_PROTOCOL_MINOR ); + return; + } + msg.ReadDeltaDict( serverInfo.serverInfo, NULL ); + + if ( verbose ) { + common->Printf( "server IP = %s\n", Sys_NetAdrToString( serverInfo.adr ) ); + serverInfo.serverInfo.Print(); + } + for ( i = msg.ReadByte(); i < MAX_ASYNC_CLIENTS; i = msg.ReadByte() ) { + serverInfo.pings[ serverInfo.clients ] = msg.ReadShort(); + serverInfo.rate[ serverInfo.clients ] = msg.ReadLong(); + msg.ReadString( serverInfo.nickname[ serverInfo.clients ], MAX_NICKLEN ); + if ( verbose ) { + common->Printf( "client %2d: %s, ping = %d, rate = %d\n", i, serverInfo.nickname[ serverInfo.clients ], serverInfo.pings[ serverInfo.clients ], serverInfo.rate[ serverInfo.clients ] ); + } + serverInfo.clients++; + } + serverInfo.OSMask = msg.ReadLong(); + index = serverList.InfoResponse( serverInfo ); + + common->Printf( "%d: server %s - protocol %d.%d - %s\n", index, Sys_NetAdrToString( serverInfo.adr ), protocol >> 16, protocol & 0xffff, serverInfo.serverInfo.GetString( "si_name" ) ); +} + +/* +================== +idAsyncClient::ProcessPrintMessage +================== +*/ +void idAsyncClient::ProcessPrintMessage( const netadr_t from, const idBitMsg &msg ) { + char string[ MAX_STRING_CHARS ]; + int opcode; + int game_opcode = ALLOW_YES; + const char *retpass; + + opcode = msg.ReadLong(); + if ( opcode == SERVER_PRINT_GAMEDENY ) { + game_opcode = msg.ReadLong(); + } + ReadLocalizedServerString( msg, string, MAX_STRING_CHARS ); + common->Printf( "%s\n", string ); + guiNetMenu->SetStateString( "status", string ); + if ( opcode == SERVER_PRINT_GAMEDENY ) { + if ( game_opcode == ALLOW_BADPASS ) { + retpass = session->MessageBox( MSG_PROMPT, common->GetLanguageDict()->GetString ( "#str_04321" ), string, true, "passprompt_ok" ); + ClearPendingPackets(); + guiNetMenu->SetStateString( "status", common->GetLanguageDict()->GetString ( "#str_04322" )); + if ( retpass ) { + // #790 + cvarSystem->SetCVarString( "password", "" ); + cvarSystem->SetCVarString( "password", retpass ); + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + } + } else if ( game_opcode == ALLOW_NO ) { + session->MessageBox( MSG_OK, string, common->GetLanguageDict()->GetString ( "#str_04323" ), true ); + ClearPendingPackets(); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + } + // ALLOW_NOTYET just keeps running as usual. The GUI has an abort button + } else if ( opcode == SERVER_PRINT_BADCHALLENGE && clientState >= CS_CONNECTING ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reconnect" ); + } +} + +/* +================== +idAsyncClient::ProcessServersListMessage +================== +*/ +void idAsyncClient::ProcessServersListMessage( const netadr_t from, const idBitMsg &msg ) { + if ( !Sys_CompareNetAdrBase( idAsyncNetwork::GetMasterAddress(), from ) ) { + common->DPrintf( "received a server list from %s - not a valid master\n", Sys_NetAdrToString( from ) ); + return; + } + while ( msg.GetRemaingData() ) { + int a,b,c,d; + a = msg.ReadByte(); b = msg.ReadByte(); c = msg.ReadByte(); d = msg.ReadByte(); + serverList.AddServer( serverList.Num(), va( "%i.%i.%i.%i:%i", a, b, c, d, msg.ReadShort() ) ); + } +} + +/* +================== +idAsyncClient::ProcessAuthKeyMessage +================== +*/ +void idAsyncClient::ProcessAuthKeyMessage( const netadr_t from, const idBitMsg &msg ) { + authKeyMsg_t authMsg; + char read_string[ MAX_STRING_CHARS ]; + const char *retkey; + authBadKeyStatus_t authBadStatus; + int key_index; + bool valid[ 2 ]; + idStr auth_msg; + + if ( clientState != CS_CONNECTING && !session->WaitingForGameAuth() ) { + common->Printf( "clientState != CS_CONNECTING, not waiting for game auth, authKey ignored\n" ); + return; + } + + authMsg = (authKeyMsg_t)msg.ReadByte(); + if ( authMsg == AUTHKEY_BADKEY ) { + valid[ 0 ] = valid[ 1 ] = true; + key_index = 0; + authBadStatus = (authBadKeyStatus_t)msg.ReadByte(); + switch ( authBadStatus ) { + case AUTHKEY_BAD_INVALID: + valid[ 0 ] = ( msg.ReadByte() == 1 ); + valid[ 1 ] = ( msg.ReadByte() == 1 ); + idAsyncNetwork::BuildInvalidKeyMsg( auth_msg, valid ); + break; + case AUTHKEY_BAD_BANNED: + key_index = msg.ReadByte(); + auth_msg = common->GetLanguageDict()->GetString( va( "#str_0719%1d", 6 + key_index ) ); + auth_msg += "\n"; + auth_msg += common->GetLanguageDict()->GetString( "#str_04304" ); + valid[ key_index ] = false; + break; + case AUTHKEY_BAD_INUSE: + key_index = msg.ReadByte(); + auth_msg = common->GetLanguageDict()->GetString( va( "#str_0719%1d", 8 + key_index ) ); + auth_msg += "\n"; + auth_msg += common->GetLanguageDict()->GetString( "#str_04304" ); + valid[ key_index ] = false; + break; + case AUTHKEY_BAD_MSG: + // a general message explaining why this key is denied + // no specific use for this atm. let's not clear the keys either + msg.ReadString( read_string, MAX_STRING_CHARS ); + auth_msg = read_string; + break; + } + common->DPrintf( "auth deny: %s\n", auth_msg.c_str() ); + + // keys to be cleared. applies to both net connect and game auth + session->ClearCDKey( valid ); + + // get rid of the bad key - at least that's gonna annoy people who stole a fake key + if ( clientState == CS_CONNECTING ) { + while ( 1 ) { + // here we use the auth status message + retkey = session->MessageBox( MSG_CDKEY, auth_msg, common->GetLanguageDict()->GetString( "#str_04325" ), true ); + if ( retkey ) { + if ( session->CheckKey( retkey, true, valid ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reconnect" ); + } else { + // build a more precise message about the offline check failure + idAsyncNetwork::BuildInvalidKeyMsg( auth_msg, valid ); + session->MessageBox( MSG_OK, auth_msg.c_str(), common->GetLanguageDict()->GetString( "#str_04327" ), true ); + continue; + } + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + } + break; + } + } else { + // forward the auth status information to the session code + session->CDKeysAuthReply( false, auth_msg ); + } + } else { + msg.ReadString( read_string, MAX_STRING_CHARS ); + cvarSystem->SetCVarString( "com_guid", read_string ); + common->Printf( "guid set to %s\n", read_string ); + session->CDKeysAuthReply( true, NULL ); + } +} + +/* +================== +idAsyncClient::ProcessVersionMessage +================== +*/ +void idAsyncClient::ProcessVersionMessage( const netadr_t from, const idBitMsg &msg ) { + char string[ MAX_STRING_CHARS ]; + + if ( updateState != UPDATE_SENT ) { + common->Printf( "ProcessVersionMessage: version reply, != UPDATE_SENT\n" ); + return; + } + + common->Printf( "A new version is available\n" ); + msg.ReadString( string, MAX_STRING_CHARS ); + updateMSG = string; + updateDirectDownload = ( msg.ReadByte() != 0 ); + msg.ReadString( string, MAX_STRING_CHARS ); + updateURL = string; + updateMime = (dlMime_t)msg.ReadByte(); + msg.ReadString( string, MAX_STRING_CHARS ); + updateFallback = string; + updateState = UPDATE_READY; +} + +/* +================== +idAsyncClient::ValidatePureServerChecksums +================== +*/ +bool idAsyncClient::ValidatePureServerChecksums( const netadr_t from, const idBitMsg &msg ) { + int i, numChecksums, numMissingChecksums; + int inChecksums[ MAX_PURE_PAKS ]; + int inGamePakChecksum; + int missingChecksums[ MAX_PURE_PAKS ]; + int missingGamePakChecksum; + idBitMsg dlmsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + // read checksums + // pak checksums, in a 0-terminated list + numChecksums = 0; + do { + i = msg.ReadLong( ); + inChecksums[ numChecksums++ ] = i; + // just to make sure a broken message doesn't crash us + if ( numChecksums >= MAX_PURE_PAKS ) { + common->Warning( "MAX_PURE_PAKS ( %d ) exceeded in idAsyncClient::ProcessPureMessage\n", MAX_PURE_PAKS ); + return false; + } + } while ( i ); + inChecksums[ numChecksums ] = 0; + inGamePakChecksum = msg.ReadLong(); + + fsPureReply_t reply = fileSystem->SetPureServerChecksums( inChecksums, inGamePakChecksum, missingChecksums, &missingGamePakChecksum ); + switch ( reply ) { + case PURE_RESTART: + // need to restart the filesystem with a different pure configuration + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + // restart with the right FS configuration and get back to the server + clientState = CS_PURERESTART; + fileSystem->SetRestartChecksums( inChecksums, inGamePakChecksum ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadEngine" ); + return false; + case PURE_MISSING: { + + idStr checksums; + + i = 0; + while ( missingChecksums[ i ] ) { + checksums += va( "0x%x ", missingChecksums[ i++ ] ); + } + numMissingChecksums = i; + + if ( idAsyncNetwork::clientDownload.GetInteger() == 0 ) { + // never any downloads + idStr message = va( common->GetLanguageDict()->GetString( "#str_07210" ), Sys_NetAdrToString( from ) ); + + if ( numMissingChecksums > 0 ) { + message += va( common->GetLanguageDict()->GetString( "#str_06751" ), numMissingChecksums, checksums.c_str() ); + } + if ( missingGamePakChecksum ) { + message += va( common->GetLanguageDict()->GetString( "#str_06750" ), missingGamePakChecksum ); + } + + common->Printf( message ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + session->MessageBox( MSG_OK, message, common->GetLanguageDict()->GetString( "#str_06735" ), true ); + } else { + if ( clientState >= CS_CONNECTED ) { + // we are already connected, reconnect to negociate the paks in connectionless mode + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reconnect" ); + return false; + } + // ask the server to send back download info + common->DPrintf( "missing %d paks: %s\n", numMissingChecksums + ( missingGamePakChecksum ? 1 : 0 ), checksums.c_str() ); + if ( missingGamePakChecksum ) { + common->DPrintf( "game code pak: 0x%x\n", missingGamePakChecksum ); + } + // store the requested downloads + GetDownloadRequest( missingChecksums, numMissingChecksums, missingGamePakChecksum ); + // build the download request message + // NOTE: in a specific function? + dlmsg.Init( msgBuf, sizeof( msgBuf ) ); + dlmsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + dlmsg.WriteString( "downloadRequest" ); + dlmsg.WriteLong( serverChallenge ); + dlmsg.WriteShort( clientId ); + // used to make sure the server replies to the same download request + dlmsg.WriteLong( dlRequest ); + // special case the code pak - if we have a 0 checksum then we don't need to download it + dlmsg.WriteLong( missingGamePakChecksum ); + // 0-terminated list of missing paks + i = 0; + while ( missingChecksums[ i ] ) { + dlmsg.WriteLong( missingChecksums[ i++ ] ); + } + dlmsg.WriteLong( 0 ); + clientPort.SendPacket( from, dlmsg.GetData(), dlmsg.GetSize() ); + } + + return false; + } + case PURE_NODLL: + common->Printf( common->GetLanguageDict()->GetString( "#str_07211" ), Sys_NetAdrToString( from ) ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + return false; + default: + return true; + } + return true; +} + +/* +================== +idAsyncClient::ProcessPureMessage +================== +*/ +void idAsyncClient::ProcessPureMessage( const netadr_t from, const idBitMsg &msg ) { + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + int i; + int inChecksums[ MAX_PURE_PAKS ]; + int gamePakChecksum; + + if ( clientState != CS_CONNECTING ) { + common->Printf( "clientState != CS_CONNECTING, pure msg ignored\n" ); + return; + } + + if ( !ValidatePureServerChecksums( from, msg ) ) { + return; + } + + fileSystem->GetPureServerChecksums( inChecksums, -1, &gamePakChecksum ); + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "pureClient" ); + outMsg.WriteLong( serverChallenge ); + outMsg.WriteShort( clientId ); + i = 0; + while ( inChecksums[ i ] ) { + outMsg.WriteLong( inChecksums[ i++ ] ); + } + outMsg.WriteLong( 0 ); + outMsg.WriteLong( gamePakChecksum ); + clientPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); +} + +/* +================== +idAsyncClient::ConnectionlessMessage +================== +*/ +void idAsyncClient::ConnectionlessMessage( const netadr_t from, const idBitMsg &msg ) { + char string[MAX_STRING_CHARS*2]; // M. Quinn - Even Balance - PB packets can go beyond 1024 + + msg.ReadString( string, sizeof( string ) ); + + // info response from a server, are accepted from any source + if ( idStr::Icmp( string, "infoResponse" ) == 0 ) { + ProcessInfoResponseMessage( from, msg ); + return; + } + + // from master server: + if ( Sys_CompareNetAdrBase( from, idAsyncNetwork::GetMasterAddress( ) ) ) { + // server list + if ( idStr::Icmp( string, "servers" ) == 0 ) { + ProcessServersListMessage( from, msg ); + return; + } + + if ( idStr::Icmp( string, "authKey" ) == 0 ) { + ProcessAuthKeyMessage( from, msg ); + return; + } + + if ( idStr::Icmp( string, "newVersion" ) == 0 ) { + ProcessVersionMessage( from, msg ); + return; + } + } + + // ignore if not from the current/last server + if ( !Sys_CompareNetAdrBase( from, serverAddress ) && ( lastRconTime + 10000 < realTime || !Sys_CompareNetAdrBase( from, lastRconAddress ) ) ) { + common->DPrintf( "got message '%s' from bad source: %s\n", string, Sys_NetAdrToString( from ) ); + return; + } + + // challenge response from the server we are connecting to + if ( idStr::Icmp( string, "challengeResponse" ) == 0 ) { + ProcessChallengeResponseMessage( from, msg ); + return; + } + + // connect response from the server we are connecting to + if ( idStr::Icmp( string, "connectResponse" ) == 0 ) { + ProcessConnectResponseMessage( from, msg ); + return; + } + + // a disconnect message from the server, which will happen if the server + // dropped the connection but is still getting packets from this client + if ( idStr::Icmp( string, "disconnect" ) == 0 ) { + ProcessDisconnectMessage( from, msg ); + return; + } + + // print request from server + if ( idStr::Icmp( string, "print" ) == 0 ) { + ProcessPrintMessage( from, msg ); + return; + } + + // server pure list + if ( idStr::Icmp( string, "pureServer" ) == 0 ) { + ProcessPureMessage( from, msg ); + return; + } + + if ( idStr::Icmp( string, "downloadInfo" ) == 0 ) { + ProcessDownloadInfoMessage( from, msg ); + } + + if ( idStr::Icmp( string, "authrequired" ) == 0 ) { + // server telling us that he's expecting an auth mode connect, just in case we're trying to connect in LAN mode + if ( idAsyncNetwork::LANServer.GetBool() ) { + common->Warning( "server %s requests master authorization for this client. Turning off LAN mode\n", Sys_NetAdrToString( from ) ); + idAsyncNetwork::LANServer.SetBool( false ); + } + } + + common->DPrintf( "ignored message from %s: %s\n", Sys_NetAdrToString( from ), string ); +} + +/* +================= +idAsyncClient::ProcessMessage +================= +*/ +void idAsyncClient::ProcessMessage( const netadr_t from, idBitMsg &msg ) { + int id; + + id = msg.ReadShort(); + + // check for a connectionless packet + if ( id == CONNECTIONLESS_MESSAGE_ID ) { + ConnectionlessMessage( from, msg ); + return; + } + + if ( clientState < CS_CONNECTED ) { + return; // can't be a valid sequenced packet + } + + if ( msg.GetRemaingData() < 4 ) { + common->DPrintf( "%s: tiny packet\n", Sys_NetAdrToString( from ) ); + return; + } + + // is this a packet from the server + if ( !Sys_CompareNetAdrBase( from, channel.GetRemoteAddress() ) || id != serverId ) { + common->DPrintf( "%s: sequenced server packet without connection\n", Sys_NetAdrToString( from ) ); + return; + } + + if ( !channel.Process( from, clientTime, msg, serverMessageSequence ) ) { + return; // out of order, duplicated, fragment, etc. + } + + lastPacketTime = clientTime; + ProcessReliableServerMessages(); + ProcessUnreliableServerMessage( msg ); +} + +/* +================== +idAsyncClient::SetupConnection +================== +*/ +void idAsyncClient::SetupConnection( void ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( clientTime - lastConnectTime < SETUP_CONNECTION_RESEND_TIME ) { + return; + } + + if ( clientState == CS_CHALLENGING ) { + common->Printf( "sending challenge to %s\n", Sys_NetAdrToString( serverAddress ) ); + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "challenge" ); + msg.WriteLong( clientId ); + clientPort.SendPacket( serverAddress, msg.GetData(), msg.GetSize() ); + } else if ( clientState == CS_CONNECTING ) { + common->Printf( "sending connect to %s with challenge 0x%x\n", Sys_NetAdrToString( serverAddress ), serverChallenge ); + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "connect" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); +#if ID_FAKE_PURE + // fake win32 OS - might need to adapt depending on the case + msg.WriteShort( 0 ); +#else + msg.WriteShort( BUILD_OS_ID ); +#endif + msg.WriteLong( clientDataChecksum ); + msg.WriteLong( serverChallenge ); + msg.WriteShort( clientId ); + msg.WriteLong( cvarSystem->GetCVarInteger( "net_clientMaxRate" ) ); + msg.WriteString( cvarSystem->GetCVarString( "com_guid" ) ); + msg.WriteString( cvarSystem->GetCVarString( "password" ), -1, false ); + // do not make the protocol depend on PB + msg.WriteShort( 0 ); + clientPort.SendPacket( serverAddress, msg.GetData(), msg.GetSize() ); + + if ( idAsyncNetwork::LANServer.GetBool() ) { + common->Printf( "net_LANServer is set, connecting in LAN mode\n" ); + } else { + // emit a cd key authorization request + // modified at protocol 1.37 for XP key addition + msg.BeginWriting(); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "clAuth" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); + msg.WriteNetadr( serverAddress ); + // if we don't have a com_guid, this will request a direct reply from auth with it + msg.WriteByte( cvarSystem->GetCVarString( "com_guid" )[0] ? 1 : 0 ); + // send the main key, and flag an extra byte to add XP key + msg.WriteString( session->GetCDKey( false ) ); + const char *xpkey = session->GetCDKey( true ); + msg.WriteByte( xpkey ? 1 : 0 ); + if ( xpkey ) { + msg.WriteString( xpkey ); + } + clientPort.SendPacket( idAsyncNetwork::GetMasterAddress(), msg.GetData(), msg.GetSize() ); + } + } else { + return; + } + + lastConnectTime = clientTime; +} + +/* +================== +idAsyncClient::SendReliableGameMessage +================== +*/ +void idAsyncClient::SendReliableGameMessage( const idBitMsg &msg ) { + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( clientState < CS_INGAME ) { + return; + } + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( CLIENT_RELIABLE_MESSAGE_GAME ); + outMsg.WriteData( msg.GetData(), msg.GetSize() ); + if ( !channel.SendReliableMessage( outMsg ) ) { + common->Error( "client->server reliable messages overflow\n" ); + } +} + +/* +================== +idAsyncClient::Idle +================== +*/ +void idAsyncClient::Idle( void ) { + // also need to read mouse for the connecting guis + usercmdGen->GetDirectUsercmd(); + + SendEmptyToServer(); +} + +/* +================== +idAsyncClient::UpdateTime +================== +*/ +int idAsyncClient::UpdateTime( int clamp ) { + int time, msec; + + time = Sys_Milliseconds(); + msec = idMath::ClampInt( 0, clamp, time - realTime ); + realTime = time; + clientTime += msec; + return msec; +} + +/* +================== +idAsyncClient::RunFrame +================== +*/ +void idAsyncClient::RunFrame( void ) { + int msec, size; + bool newPacket; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t from; + + msec = UpdateTime( 100 ); + + if ( !clientPort.GetPort() ) { + return; + } + + // handle ongoing pk4 downloads and patch downloads + HandleDownloads(); + + gameTimeResidual += msec; + + // spin in place processing incoming packets until enough time lapsed to run a new game frame + do { + + do { + + // blocking read with game time residual timeout + newPacket = clientPort.GetPacketBlocking( from, msgBuf, size, sizeof( msgBuf ), USERCMD_MSEC - ( gameTimeResidual + clientPredictTime ) - 1 ); + if ( newPacket ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.SetSize( size ); + msg.BeginReading(); + ProcessMessage( from, msg ); + } + + msec = UpdateTime( 100 ); + gameTimeResidual += msec; + + } while( newPacket ); + + } while( gameTimeResidual + clientPredictTime < USERCMD_MSEC ); + + // update server list + serverList.RunFrame(); + + if ( clientState == CS_DISCONNECTED ) { + usercmdGen->GetDirectUsercmd(); + gameTimeResidual = USERCMD_MSEC - 1; + clientPredictTime = 0; + return; + } + + if ( clientState == CS_PURERESTART ) { + clientState = CS_DISCONNECTED; + Reconnect(); + gameTimeResidual = USERCMD_MSEC - 1; + clientPredictTime = 0; + return; + } + + // if not connected setup a connection + if ( clientState < CS_CONNECTED ) { + // also need to read mouse for the connecting guis + usercmdGen->GetDirectUsercmd(); + SetupConnection(); + gameTimeResidual = USERCMD_MSEC - 1; + clientPredictTime = 0; + return; + } + + if ( CheckTimeout() ) { + return; + } + + // if not yet in the game send empty messages to keep data flowing through the channel + if ( clientState < CS_INGAME ) { + Idle(); + gameTimeResidual = 0; + return; + } + + // check for user info changes + if ( cvarSystem->GetModifiedFlags() & CVAR_USERINFO ) { + game->ThrottleUserInfo( ); + SendUserInfoToServer( ); + game->SetUserInfo( clientNum, sessLocal.mapSpawnData.userInfo[ clientNum ], true, false ); + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); + } + + if ( gameTimeResidual + clientPredictTime >= USERCMD_MSEC ) { + lastFrameDelta = 0; + } + + // generate user commands for the predicted time + while ( gameTimeResidual + clientPredictTime >= USERCMD_MSEC ) { + + // send the user commands of this client to the server + SendUsercmdsToServer(); + + // update time + gameFrame++; + gameTime += USERCMD_MSEC; + gameTimeResidual -= USERCMD_MSEC; + + // run from the snapshot up to the local game frame + while ( snapshotGameFrame < gameFrame ) { + + lastFrameDelta++; + + // duplicate usercmds for clients if no new ones are available + DuplicateUsercmds( snapshotGameFrame, snapshotGameTime ); + + // indicate the last prediction frame before a render + bool lastPredictFrame = ( snapshotGameFrame + 1 >= gameFrame && gameTimeResidual + clientPredictTime < USERCMD_MSEC ); + + // run client prediction + gameReturn_t ret = game->ClientPrediction( clientNum, userCmds[ snapshotGameFrame & ( MAX_USERCMD_BACKUP - 1 ) ], lastPredictFrame ); + + idAsyncNetwork::ExecuteSessionCommand( ret.sessionCommand ); + + snapshotGameFrame++; + snapshotGameTime += USERCMD_MSEC; + } + } +} + +/* +================== +idAsyncClient::PacifierUpdate +================== +*/ +void idAsyncClient::PacifierUpdate( void ) { + if ( !IsActive() ) { + return; + } + realTime = Sys_Milliseconds(); + SendEmptyToServer( false, true ); +} + +/* +================== +idAsyncClient::SendVersionCheck +================== +*/ +void idAsyncClient::SendVersionCheck( bool fromMenu ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( updateState != UPDATE_NONE && !fromMenu ) { + common->DPrintf( "up-to-date check was already performed\n" ); + return; + } + + InitPort(); + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "versionCheck" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); + msg.WriteShort( BUILD_OS_ID ); + msg.WriteString( cvarSystem->GetCVarString( "si_version" ) ); + msg.WriteString( cvarSystem->GetCVarString( "com_guid" ) ); + clientPort.SendPacket( idAsyncNetwork::GetMasterAddress(), msg.GetData(), msg.GetSize() ); + + common->DPrintf( "sent a version check request\n" ); + + updateState = UPDATE_SENT; + updateSentTime = clientTime; + showUpdateMessage = fromMenu; +} + +/* +================== +idAsyncClient::SendVersionDLUpdate + +sending those packets is not strictly necessary. just a way to tell the update server +about what is going on. allows the update server to have a more precise view of the overall +network load for the updates +================== +*/ +void idAsyncClient::SendVersionDLUpdate( int state ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "versionDL" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); + msg.WriteShort( state ); + clientPort.SendPacket( idAsyncNetwork::GetMasterAddress(), msg.GetData(), msg.GetSize() ); +} + +/* +================== +idAsyncClient::HandleDownloads +================== +*/ +void idAsyncClient::HandleDownloads( void ) { + + if ( updateState == UPDATE_SENT && clientTime > updateSentTime + 2000 ) { + // timing out on no reply + updateState = UPDATE_DONE; + if ( showUpdateMessage ) { + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04839" ), common->GetLanguageDict()->GetString ( "#str_04837" ), true ); + showUpdateMessage = false; + } + common->DPrintf( "No update available\n" ); + } else if ( backgroundDownload.completed ) { + // only enter these if the download slot is free + if ( updateState == UPDATE_READY ) { + // + if ( session->MessageBox( MSG_YESNO, updateMSG, common->GetLanguageDict()->GetString ( "#str_04330" ), true, "yes" )[0] ) { + if ( !updateDirectDownload ) { + sys->OpenURL( updateURL, true ); + updateState = UPDATE_DONE; + } else { + + // we're just creating the file at toplevel inside fs_savepath + updateURL.ExtractFileName( updateFile ); + idFile_Permanent *f = static_cast< idFile_Permanent *>( fileSystem->OpenFileWrite( updateFile ) ); + dltotal = 0; + dlnow = 0; + + backgroundDownload.completed = false; + backgroundDownload.opcode = DLTYPE_URL; + backgroundDownload.f = f; + backgroundDownload.url.status = DL_WAIT; + backgroundDownload.url.dlnow = 0; + backgroundDownload.url.dltotal = 0; + backgroundDownload.url.url = updateURL; + fileSystem->BackgroundDownload( &backgroundDownload ); + + updateState = UPDATE_DLING; + SendVersionDLUpdate( 0 ); + session->DownloadProgressBox( &backgroundDownload, va( "Downloading %s\n", updateFile.c_str() ) ); + updateState = UPDATE_DONE; + if ( backgroundDownload.url.status == DL_DONE ) { + SendVersionDLUpdate( 1 ); + idStr fullPath = f->GetFullPath(); + fileSystem->CloseFile( f ); + if ( session->MessageBox( MSG_YESNO, common->GetLanguageDict()->GetString ( "#str_04331" ), common->GetLanguageDict()->GetString ( "#str_04332" ), true, "yes" )[0] ) { + if ( updateMime == FILE_EXEC ) { + sys->StartProcess( fullPath, true ); + } else { + sys->OpenURL( va( "file://%s", fullPath.c_str() ), true ); + } + } else { + session->MessageBox( MSG_OK, va( common->GetLanguageDict()->GetString ( "#str_04333" ), fullPath.c_str() ), common->GetLanguageDict()->GetString ( "#str_04334" ), true ); + } + } else { + if ( backgroundDownload.url.dlerror[ 0 ] ) { + common->Warning( "update download failed. curl error: %s", backgroundDownload.url.dlerror ); + } + SendVersionDLUpdate( 2 ); + idStr name = f->GetName(); + fileSystem->CloseFile( f ); + fileSystem->RemoveFile( name ); + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04335" ), common->GetLanguageDict()->GetString ( "#str_04336" ), true ); + if ( updateFallback.Length() ) { + sys->OpenURL( updateFallback.c_str(), true ); + } else { + common->Printf( "no fallback URL\n" ); + } + } + } + } else { + updateState = UPDATE_DONE; + } + } else if ( dlList.Num() ) { + + int numPaks = dlList.Num(); + int pakCount = 1; + int progress_start, progress_end; + currentDlSize = 0; + + do { + + if ( dlList[ 0 ].url[ 0 ] == '\0' ) { + // ignore empty files + dlList.RemoveIndex( 0 ); + continue; + } + common->Printf( "start download for %s\n", dlList[ 0 ].url.c_str() ); + + idFile_Permanent *f = static_cast< idFile_Permanent *>( fileSystem->MakeTemporaryFile( ) ); + if ( !f ) { + common->Warning( "could not create temporary file" ); + dlList.Clear(); + return; + } + + backgroundDownload.completed = false; + backgroundDownload.opcode = DLTYPE_URL; + backgroundDownload.f = f; + backgroundDownload.url.status = DL_WAIT; + backgroundDownload.url.dlnow = 0; + backgroundDownload.url.dltotal = dlList[ 0 ].size; + backgroundDownload.url.url = dlList[ 0 ].url; + fileSystem->BackgroundDownload( &backgroundDownload ); + idStr dltitle; + // "Downloading %s" + sprintf( dltitle, common->GetLanguageDict()->GetString( "#str_07213" ), dlList[ 0 ].filename.c_str() ); + if ( numPaks > 1 ) { + dltitle += va( " (%d/%d)", pakCount, numPaks ); + } + if ( totalDlSize ) { + progress_start = (int)( (float)currentDlSize * 100.0f / (float)totalDlSize ); + progress_end = (int)( (float)( currentDlSize + dlList[ 0 ].size ) * 100.0f / (float)totalDlSize ); + } else { + progress_start = 0; + progress_end = 100; + } + session->DownloadProgressBox( &backgroundDownload, dltitle, progress_start, progress_end ); + if ( backgroundDownload.url.status == DL_DONE ) { + idFile *saveas; + const int CHUNK_SIZE = 1024 * 1024; + byte *buf; + int remainlen; + int readlen; + int retlen; + int checksum; + + common->Printf( "file downloaded\n" ); + idStr finalPath = cvarSystem->GetCVarString( "fs_savepath" ); + finalPath.AppendPath( dlList[ 0 ].filename ); + fileSystem->CreateOSPath( finalPath ); + // do the final copy ourselves so we do by small chunks in case the file is big + saveas = fileSystem->OpenExplicitFileWrite( finalPath ); + buf = (byte*)Mem_Alloc( CHUNK_SIZE ); + f->Seek( 0, FS_SEEK_END ); + remainlen = f->Tell(); + f->Seek( 0, FS_SEEK_SET ); + while ( remainlen ) { + readlen = Min( remainlen, CHUNK_SIZE ); + retlen = f->Read( buf, readlen ); + if ( retlen != readlen ) { + common->FatalError( "short read %d of %d in idFileSystem::HandleDownload", retlen, readlen ); + } + retlen = saveas->Write( buf, readlen ); + if ( retlen != readlen ) { + common->FatalError( "short write %d of %d in idFileSystem::HandleDownload", retlen, readlen ); + } + remainlen -= readlen; + } + fileSystem->CloseFile( f ); + fileSystem->CloseFile( saveas ); + common->Printf( "saved as %s\n", finalPath.c_str() ); + Mem_Free( buf ); + + // add that file to our paks list + checksum = fileSystem->AddZipFile( dlList[ 0 ].filename ); + + // verify the checksum to be what the server says + if ( !checksum || checksum != dlList[ 0 ].checksum ) { + // "pak is corrupted ( checksum 0x%x, expected 0x%x )" + session->MessageBox( MSG_OK, va( common->GetLanguageDict()->GetString( "#str_07214" ) , checksum, dlList[0].checksum ), "Download failed", true ); + fileSystem->RemoveFile( dlList[ 0 ].filename ); + dlList.Clear(); + return; + } + + currentDlSize += dlList[ 0 ].size; + + } else { + common->Warning( "download failed: %s", dlList[ 0 ].url.c_str() ); + if ( backgroundDownload.url.dlerror[ 0 ] ) { + common->Warning( "curl error: %s", backgroundDownload.url.dlerror ); + } + // "The download failed or was cancelled" + // "Download failed" + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07215" ), common->GetLanguageDict()->GetString( "#str_07216" ), true ); + dlList.Clear(); + return; + } + + pakCount++; + dlList.RemoveIndex( 0 ); + } while ( dlList.Num() ); + + // all downloads successful - do the dew + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reconnect\n" ); + } + } +} + +/* +=============== +idAsyncClient::SendAuthCheck +=============== +*/ +bool idAsyncClient::SendAuthCheck( const char *cdkey, const char *xpkey ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + msg.WriteString( "gameAuth" ); + msg.WriteLong( ASYNC_PROTOCOL_VERSION ); + msg.WriteByte( cdkey ? 1 : 0 ); + msg.WriteString( cdkey ? cdkey : "" ); + msg.WriteByte( xpkey ? 1 : 0 ); + msg.WriteString( xpkey ? xpkey : "" ); + InitPort(); + clientPort.SendPacket( idAsyncNetwork::GetMasterAddress(), msg.GetData(), msg.GetSize() ); + return true; +} + +/* +=============== +idAsyncClient::CheckTimeout +=============== +*/ +bool idAsyncClient::CheckTimeout( void ) { + if ( lastPacketTime > 0 && ( lastPacketTime + idAsyncNetwork::clientServerTimeout.GetInteger()*1000 < clientTime ) ) { + session->StopBox(); + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04328" ), common->GetLanguageDict()->GetString ( "#str_04329" ), true ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + return true; + } + return false; +} + +/* +=============== +idAsyncClient::ProcessDownloadInfoMessage +=============== +*/ +void idAsyncClient::ProcessDownloadInfoMessage( const netadr_t from, const idBitMsg &msg ) { + char buf[ MAX_STRING_CHARS ]; + int srvDlRequest = msg.ReadLong(); + int infoType = msg.ReadByte(); + int pakDl; + int pakIndex; + + pakDlEntry_t entry; + bool gotAllFiles = true; + idStr sizeStr; + bool gotGame = false; + + if ( dlRequest == -1 || srvDlRequest != dlRequest ) { + common->Warning( "bad download id from server, ignored" ); + return; + } + // mark the dlRequest as dead now whatever how we process it + dlRequest = -1; + + if ( infoType == SERVER_DL_REDIRECT ) { + msg.ReadString( buf, MAX_STRING_CHARS ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + // "You are missing required pak files to connect to this server.\nThe server gave a web page though:\n%s\nDo you want to go there now?" + // "Missing required files" + if ( session->MessageBox( MSG_YESNO, va( common->GetLanguageDict()->GetString( "#str_07217" ), buf ), + common->GetLanguageDict()->GetString( "#str_07218" ), true, "yes" )[ 0 ] ) { + sys->OpenURL( buf, true ); + } + } else if ( infoType == SERVER_DL_LIST ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + if ( dlList.Num() ) { + common->Warning( "tried to process a download list while already busy downloading things" ); + return; + } + // read the URLs, check against what we requested, prompt for download + pakIndex = -1; + totalDlSize = 0; + do { + pakIndex++; + pakDl = msg.ReadByte(); + if ( pakDl == SERVER_PAK_YES ) { + if ( pakIndex == 0 ) { + gotGame = true; + } + msg.ReadString( buf, MAX_STRING_CHARS ); + entry.filename = buf; + msg.ReadString( buf, MAX_STRING_CHARS ); + entry.url = buf; + entry.size = msg.ReadLong(); + // checksums are not transmitted, we read them from the dl request we sent + entry.checksum = dlChecksums[ pakIndex ]; + totalDlSize += entry.size; + dlList.Append( entry ); + common->Printf( "download %s from %s ( 0x%x )\n", entry.filename.c_str(), entry.url.c_str(), entry.checksum ); + } else if ( pakDl == SERVER_PAK_NO ) { + msg.ReadString( buf, MAX_STRING_CHARS ); + entry.filename = buf; + entry.url = ""; + entry.size = 0; + entry.checksum = 0; + dlList.Append( entry ); + // first pak is game pak, only fail it if we actually requested it + if ( pakIndex != 0 || dlChecksums[ 0 ] != 0 ) { + common->Printf( "no download offered for %s ( 0x%x )\n", entry.filename.c_str(), dlChecksums[ pakIndex ] ); + gotAllFiles = false; + } + } else { + assert( pakDl == SERVER_PAK_END ); + } + } while ( pakDl != SERVER_PAK_END ); + if ( dlList.Num() < dlCount ) { + common->Printf( "%d files were ignored by the server\n", dlCount - dlList.Num() ); + gotAllFiles = false; + } + sizeStr.BestUnit( "%.2f", totalDlSize, MEASURE_SIZE ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + if ( totalDlSize == 0 ) { + // was no downloadable stuff for us + // "Can't connect to the pure server: no downloads offered" + // "Missing required files" + dlList.Clear(); + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07219" ), common->GetLanguageDict()->GetString( "#str_07218" ), true ); + return; + } + bool asked = false; + if ( gotGame ) { + asked = true; + // "You need to download game code to connect to this server. Are you sure? You should only answer yes if you trust the server administrators." + // "Missing game binaries" + if ( !session->MessageBox( MSG_YESNO, common->GetLanguageDict()->GetString( "#str_07220" ), common->GetLanguageDict()->GetString( "#str_07221" ), true, "yes" )[ 0 ] ) { + dlList.Clear(); + return; + } + } + if ( !gotAllFiles ) { + asked = true; + // "The server only offers to download some of the files required to connect ( %s ). Download anyway?" + // "Missing required files" + if ( !session->MessageBox( MSG_YESNO, va( common->GetLanguageDict()->GetString( "#str_07222" ), sizeStr.c_str() ), + common->GetLanguageDict()->GetString( "#str_07218" ), true, "yes" )[ 0 ] ) { + dlList.Clear(); + return; + } + } + if ( !asked && idAsyncNetwork::clientDownload.GetInteger() == 1 ) { + // "You need to download some files to connect to this server ( %s ), proceed?" + // "Missing required files" + if ( !session->MessageBox( MSG_YESNO, va( common->GetLanguageDict()->GetString( "#str_07224" ), sizeStr.c_str() ), + common->GetLanguageDict()->GetString( "#str_07218" ), true, "yes" )[ 0 ] ) { + dlList.Clear(); + return; + } + } + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + // "You are missing some files to connect to this server, and the server doesn't provide downloads." + // "Missing required files" + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07223" ), common->GetLanguageDict()->GetString( "#str_07218" ), true ); + } +} + +/* +=============== +idAsyncClient::GetDownloadRequest +=============== +*/ +int idAsyncClient::GetDownloadRequest( const int checksums[ MAX_PURE_PAKS ], int count, int gamePakChecksum ) { + assert( !checksums[ count ] ); // 0-terminated + if ( memcmp( dlChecksums + 1, checksums, sizeof( int ) * count ) || gamePakChecksum != dlChecksums[ 0 ] ) { + idRandom newreq; + + dlChecksums[ 0 ] = gamePakChecksum; + memcpy( dlChecksums + 1, checksums, sizeof( int ) * MAX_PURE_PAKS ); + + newreq.SetSeed( Sys_Milliseconds() ); + dlRequest = newreq.RandomInt(); + dlCount = count + ( gamePakChecksum ? 1 : 0 ); + return dlRequest; + } + // this is the same dlRequest, we haven't heard from the server. keep the same id + return dlRequest; +} diff --git a/framework/async/AsyncClient.h b/framework/async/AsyncClient.h new file mode 100644 index 000000000..a7b1d0f54 --- /dev/null +++ b/framework/async/AsyncClient.h @@ -0,0 +1,209 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __ASYNCCLIENT_H__ +#define __ASYNCCLIENT_H__ + +/* +=============================================================================== + + Network Client for asynchronous networking. + +=============================================================================== +*/ + +typedef enum { + CS_DISCONNECTED, + CS_PURERESTART, + CS_CHALLENGING, + CS_CONNECTING, + CS_CONNECTED, + CS_INGAME +} clientState_t; + +typedef enum { + AUTHKEY_BADKEY, + AUTHKEY_GUID +} authKeyMsg_t; + +typedef enum { + AUTHKEY_BAD_INVALID, + AUTHKEY_BAD_BANNED, + AUTHKEY_BAD_INUSE, + AUTHKEY_BAD_MSG +} authBadKeyStatus_t; + +typedef enum { + UPDATE_NONE, + UPDATE_SENT, + UPDATE_READY, + UPDATE_DLING, + UPDATE_DONE +} clientUpdateState_t; + +typedef struct { + idStr url; + idStr filename; + int size; + int checksum; +} pakDlEntry_t; + +class idAsyncClient { +public: + idAsyncClient(); + + void Shutdown( void ); + bool InitPort( void ); + void ClosePort( void ); + void ConnectToServer( const netadr_t adr ); + void ConnectToServer( const char *address ); + void Reconnect( void ); + void DisconnectFromServer( void ); + void GetServerInfo( const netadr_t adr ); + void GetServerInfo( const char *address ); + void GetLANServers( void ); + void GetNETServers( void ); + void ListServers( void ); + void ClearServers( void ); + void RemoteConsole( const char *command ); + bool IsPortInitialized() { return clientPort.GetPort() != 0; } + + bool IsActive( void ) const { return active; } + int GetLocalClientNum( void ) const { return clientNum; } + int GetPrediction( void ) const; + int GetTimeSinceLastPacket( void ) const; + int GetOutgoingRate( void ) const; + int GetIncomingRate( void ) const; + float GetOutgoingCompression( void ) const; + float GetIncomingCompression( void ) const; + float GetIncomingPacketLoss( void ) const; + int GetPredictedFrames( void ) const { return lastFrameDelta; } + + void RunFrame( void ); + void SendReliableGameMessage( const idBitMsg &msg ); + + void SendVersionCheck( bool fromMenu = false ); + // pass NULL for the keys you don't care to auth for + // returns false if internet link doesn't appear to be available + bool SendAuthCheck( const char *cdkey, const char *xpkey ); + + void PacifierUpdate( void ); + + idServerScan serverList; + +private: + bool active; // true if client is active + int realTime; // absolute time + + int clientTime; // client local time + idPort clientPort; // UDP port + int clientId; // client identification + int clientDataChecksum; // checksum of the data used by the client + int clientNum; // client number on server + clientState_t clientState; // client state + int clientPrediction; // how far the client predicts ahead + int clientPredictTime; // prediction time used to send user commands + + netadr_t serverAddress; // IP address of server + int serverId; // server identification + int serverChallenge; // challenge from server + int serverMessageSequence; // sequence number of last server message + + netadr_t lastRconAddress; // last rcon address we emitted to + int lastRconTime; // when last rcon emitted + + idMsgChannel channel; // message channel to server + int lastConnectTime; // last time a connect message was sent + int lastEmptyTime; // last time an empty message was sent + int lastPacketTime; // last time a packet was received from the server + int lastSnapshotTime; // last time a snapshot was received + + int snapshotSequence; // sequence number of the last received snapshot + int snapshotGameFrame; // game frame number of the last received snapshot + int snapshotGameTime; // game time of the last received snapshot + + int gameInitId; // game initialization identification + int gameFrame; // local game frame + int gameTime; // local game time + int gameTimeResidual; // left over time from previous frame + + usercmd_t userCmds[MAX_USERCMD_BACKUP][MAX_ASYNC_CLIENTS]; + + idUserInterface * guiNetMenu; + + clientUpdateState_t updateState; + int updateSentTime; + idStr updateMSG; + idStr updateURL; + bool updateDirectDownload; + idStr updateFile; + dlMime_t updateMime; + idStr updateFallback; + bool showUpdateMessage; + + backgroundDownload_t backgroundDownload; + int dltotal; + int dlnow; + + int lastFrameDelta; + + int dlRequest; // randomized number to keep track of the requests + int dlChecksums[ MAX_PURE_PAKS ]; // 0-terminated, first element is the game pak checksum or 0 + int dlCount; // total number of paks we request download for ( including the game pak ) + idListdlList; // list of paks to download, with url and name + int currentDlSize; + int totalDlSize; // for partial progress stuff + + void Clear( void ); + void ClearPendingPackets( void ); + void DuplicateUsercmds( int frame, int time ); + void SendUserInfoToServer( void ); + void SendEmptyToServer( bool force = false, bool mapLoad = false ); + void SendPingResponseToServer( int time ); + void SendUsercmdsToServer( void ); + void InitGame( int serverGameInitId, int serverGameFrame, int serverGameTime, const idDict &serverSI ); + void ProcessUnreliableServerMessage( const idBitMsg &msg ); + void ProcessReliableServerMessages( void ); + void ProcessChallengeResponseMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessConnectResponseMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessDisconnectMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessInfoResponseMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessPrintMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessServersListMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessAuthKeyMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessVersionMessage( const netadr_t from, const idBitMsg &msg ); + void ConnectionlessMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessMessage( const netadr_t from, idBitMsg &msg ); + void SetupConnection( void ); + void ProcessPureMessage( const netadr_t from, const idBitMsg &msg ); + bool ValidatePureServerChecksums( const netadr_t from, const idBitMsg &msg ); + void ProcessReliableMessagePure( const idBitMsg &msg ); + static const char* HandleGuiCommand( const char *cmd ); + const char* HandleGuiCommandInternal( const char *cmd ); + void SendVersionDLUpdate( int state ); + void HandleDownloads( void ); + void Idle( void ); + int UpdateTime( int clamp ); + void ReadLocalizedServerString( const idBitMsg &msg, char* out, int maxLen ); + bool CheckTimeout( void ); + void ProcessDownloadInfoMessage( const netadr_t from, const idBitMsg &msg ); + int GetDownloadRequest( const int checksums[ MAX_PURE_PAKS ], int count, int gamePakChecksum ); +}; + +#endif /* !__ASYNCCLIENT_H__ */ diff --git a/framework/async/AsyncNetwork.cpp b/framework/async/AsyncNetwork.cpp new file mode 100644 index 000000000..a58bb72b9 --- /dev/null +++ b/framework/async/AsyncNetwork.cpp @@ -0,0 +1,504 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "AsyncNetwork.h" + +idAsyncServer idAsyncNetwork::server; +idAsyncClient idAsyncNetwork::client; + +idCVar idAsyncNetwork::verbose( "net_verbose", "0", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "1 = verbose output, 2 = even more verbose output", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar idAsyncNetwork::allowCheats( "net_allowCheats", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NETWORKSYNC, "Allow cheats in network game" ); +#ifdef ID_DEDICATED +// dedicated executable can only have a value of 1 for net_serverDedicated +idCVar idAsyncNetwork::serverDedicated( "net_serverDedicated", "1", CVAR_SERVERINFO | CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT | CVAR_ROM, "" ); +#else +idCVar idAsyncNetwork::serverDedicated( "net_serverDedicated", "0", CVAR_SERVERINFO | CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "1 = text console dedicated server, 2 = graphical dedicated server", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +#endif +idCVar idAsyncNetwork::serverSnapshotDelay( "net_serverSnapshotDelay", "50", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "delay between snapshots in milliseconds" ); +idCVar idAsyncNetwork::serverMaxClientRate( "net_serverMaxClientRate", "16000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE | CVAR_NOCHEAT, "maximum rate to a client in bytes/sec" ); +idCVar idAsyncNetwork::clientMaxRate( "net_clientMaxRate", "16000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE | CVAR_NOCHEAT, "maximum rate requested by client from server in bytes/sec" ); +idCVar idAsyncNetwork::serverMaxUsercmdRelay( "net_serverMaxUsercmdRelay", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of usercmds from other clients the server relays to a client", 1, MAX_USERCMD_RELAY, idCmdSystem::ArgCompletion_Integer<1,MAX_USERCMD_RELAY> ); +idCVar idAsyncNetwork::serverZombieTimeout( "net_serverZombieTimeout", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "disconnected client timeout in seconds" ); +idCVar idAsyncNetwork::serverClientTimeout( "net_serverClientTimeout", "40", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "client time out in seconds" ); +idCVar idAsyncNetwork::clientServerTimeout( "net_clientServerTimeout", "40", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "server time out in seconds" ); +idCVar idAsyncNetwork::serverDrawClient( "net_serverDrawClient", "-1", CVAR_SYSTEM | CVAR_INTEGER, "number of client for which to draw view on server" ); +idCVar idAsyncNetwork::serverRemoteConsolePassword( "net_serverRemoteConsolePassword", "", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console password" ); +idCVar idAsyncNetwork::clientPrediction( "net_clientPrediction", "16", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "additional client side prediction in milliseconds" ); +idCVar idAsyncNetwork::clientMaxPrediction( "net_clientMaxPrediction", "1000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of milliseconds a client can predict ahead of server." ); +idCVar idAsyncNetwork::clientUsercmdBackup( "net_clientUsercmdBackup", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "number of usercmds to resend" ); +idCVar idAsyncNetwork::clientRemoteConsoleAddress( "net_clientRemoteConsoleAddress", "localhost", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console address" ); +idCVar idAsyncNetwork::clientRemoteConsolePassword( "net_clientRemoteConsolePassword", "", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console password" ); +idCVar idAsyncNetwork::master0( "net_master0", IDNET_HOST ":" IDNET_MASTER_PORT, CVAR_SYSTEM | CVAR_ROM, "idnet master server address" ); +idCVar idAsyncNetwork::master1( "net_master1", "", CVAR_SYSTEM | CVAR_ARCHIVE, "1st master server address" ); +idCVar idAsyncNetwork::master2( "net_master2", "", CVAR_SYSTEM | CVAR_ARCHIVE, "2nd master server address" ); +idCVar idAsyncNetwork::master3( "net_master3", "", CVAR_SYSTEM | CVAR_ARCHIVE, "3rd master server address" ); +idCVar idAsyncNetwork::master4( "net_master4", "", CVAR_SYSTEM | CVAR_ARCHIVE, "4th master server address" ); +idCVar idAsyncNetwork::LANServer( "net_LANServer", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NOCHEAT, "config LAN games only - affects clients and servers" ); +idCVar idAsyncNetwork::serverReloadEngine( "net_serverReloadEngine", "0", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "perform a full reload on next map restart (including flushing referenced pak files) - decreased if > 0" ); +idCVar idAsyncNetwork::serverAllowServerMod( "net_serverAllowServerMod", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NOCHEAT, "allow server-side mods" ); +idCVar idAsyncNetwork::idleServer( "si_idleServer", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_INIT | CVAR_SERVERINFO, "game clients are idle" ); +idCVar idAsyncNetwork::clientDownload( "net_clientDownload", "1", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE, "client pk4 downloads policy: 0 - never, 1 - ask, 2 - always (will still prompt for binary code)" ); + +int idAsyncNetwork::realTime; +master_t idAsyncNetwork::masters[ MAX_MASTER_SERVERS ]; + +/* +================== +idAsyncNetwork::idAsyncNetwork +================== +*/ +idAsyncNetwork::idAsyncNetwork( void ) { +} + +/* +================== +idAsyncNetwork::Init +================== +*/ +void idAsyncNetwork::Init( void ) { + + realTime = 0; + + memset( masters, 0, sizeof( masters ) ); + masters[0].var = &master0; + masters[1].var = &master1; + masters[2].var = &master2; + masters[3].var = &master3; + masters[4].var = &master4; + +#ifndef ID_DEMO_BUILD + cmdSystem->AddCommand( "spawnServer", SpawnServer_f, CMD_FL_SYSTEM, "spawns a server", idCmdSystem::ArgCompletion_MapName ); + cmdSystem->AddCommand( "nextMap", NextMap_f, CMD_FL_SYSTEM, "loads the next map on the server" ); + cmdSystem->AddCommand( "connect", Connect_f, CMD_FL_SYSTEM, "connects to a server" ); + cmdSystem->AddCommand( "reconnect", Reconnect_f, CMD_FL_SYSTEM, "reconnect to the last server we tried to connect to" ); + cmdSystem->AddCommand( "serverInfo", GetServerInfo_f, CMD_FL_SYSTEM, "shows server info" ); + cmdSystem->AddCommand( "LANScan", GetLANServers_f, CMD_FL_SYSTEM, "scans LAN for servers" ); + cmdSystem->AddCommand( "listServers", ListServers_f, CMD_FL_SYSTEM, "lists scanned servers" ); + cmdSystem->AddCommand( "rcon", RemoteConsole_f, CMD_FL_SYSTEM, "sends remote console command to server" ); + cmdSystem->AddCommand( "heartbeat", Heartbeat_f, CMD_FL_SYSTEM, "send a heartbeat to the the master servers" ); + cmdSystem->AddCommand( "kick", Kick_f, CMD_FL_SYSTEM, "kick a client by connection number" ); + cmdSystem->AddCommand( "checkNewVersion", CheckNewVersion_f, CMD_FL_SYSTEM, "check if a new version of the game is available" ); + cmdSystem->AddCommand( "updateUI", UpdateUI_f, CMD_FL_SYSTEM, "internal - cause a sync down of game-modified userinfo" ); +#endif +} + +/* +================== +idAsyncNetwork::GetMasterAddress +================== +*/ +netadr_t idAsyncNetwork::GetMasterAddress( void ) { + netadr_t ret; + GetMasterAddress( 0, ret ); + return masters[ 0 ].address; +} + +/* +================== +idAsyncNetwork::GetMasterAddress +================== +*/ +bool idAsyncNetwork::GetMasterAddress( int index, netadr_t &adr ) { + if ( !masters[ index ].var ) { + return false; + } + if ( masters[ index ].var->GetString()[0] == '\0' ) { + return false; + } + if ( !masters[ index ].resolved || masters[ index ].var->IsModified() ) { + masters[ index ].var->ClearModified(); + if ( !Sys_StringToNetAdr( masters[ index ].var->GetString(), &masters[ index ].address, true ) ) { + common->Printf( "Failed to resolve master%d: %s\n", index, masters[ index ].var->GetString() ); + memset( &masters[ index ].address, 0, sizeof( netadr_t ) ); + masters[ index ].resolved = true; + return false; + } + if ( masters[ index ].address.port == 0 ) { + masters[ index ].address.port = atoi( IDNET_MASTER_PORT ); + } + masters[ index ].resolved = true; + } + adr = masters[ index ].address; + return true; +} + +/* +================== +idAsyncNetwork::Shutdown +================== +*/ +void idAsyncNetwork::Shutdown( void ) { + client.serverList.Shutdown(); + client.DisconnectFromServer(); + client.ClearServers(); + client.ClosePort(); + server.Kill(); + server.ClosePort(); +} + +/* +================== +idAsyncNetwork::RunFrame +================== +*/ +void idAsyncNetwork::RunFrame( void ) { + if ( console->Active() ) { + Sys_GrabMouseCursor( false ); + usercmdGen->InhibitUsercmd( INHIBIT_ASYNC, true ); + } else { + Sys_GrabMouseCursor( true ); + usercmdGen->InhibitUsercmd( INHIBIT_ASYNC, false ); + } + client.RunFrame(); + server.RunFrame(); +} + +/* +================== +idAsyncNetwork::WriteUserCmdDelta +================== +*/ +void idAsyncNetwork::WriteUserCmdDelta( idBitMsg &msg, const usercmd_t &cmd, const usercmd_t *base ) { + if ( base ) { + msg.WriteDeltaLongCounter( base->gameTime, cmd.gameTime ); + msg.WriteDeltaByte( base->buttons, cmd.buttons ); + msg.WriteDeltaShort( base->mx, cmd.mx ); + msg.WriteDeltaShort( base->my, cmd.my ); + msg.WriteDeltaChar( base->forwardmove, cmd.forwardmove ); + msg.WriteDeltaChar( base->rightmove, cmd.rightmove ); + msg.WriteDeltaChar( base->upmove, cmd.upmove ); + msg.WriteDeltaShort( base->angles[0], cmd.angles[0] ); + msg.WriteDeltaShort( base->angles[1], cmd.angles[1] ); + msg.WriteDeltaShort( base->angles[2], cmd.angles[2] ); + return; + } + + msg.WriteLong( cmd.gameTime ); + msg.WriteByte( cmd.buttons ); + msg.WriteShort( cmd.mx ); + msg.WriteShort( cmd.my ); + msg.WriteChar( cmd.forwardmove ); + msg.WriteChar( cmd.rightmove ); + msg.WriteChar( cmd.upmove ); + msg.WriteShort( cmd.angles[0] ); + msg.WriteShort( cmd.angles[1] ); + msg.WriteShort( cmd.angles[2] ); +} + +/* +================== +idAsyncNetwork::ReadUserCmdDelta +================== +*/ +void idAsyncNetwork::ReadUserCmdDelta( const idBitMsg &msg, usercmd_t &cmd, const usercmd_t *base ) { + memset( &cmd, 0, sizeof( cmd ) ); + + if ( base ) { + cmd.gameTime = msg.ReadDeltaLongCounter( base->gameTime ); + cmd.buttons = msg.ReadDeltaByte( base->buttons ); + cmd.mx = msg.ReadDeltaShort( base->mx ); + cmd.my = msg.ReadDeltaShort( base->my ); + cmd.forwardmove = msg.ReadDeltaChar( base->forwardmove ); + cmd.rightmove = msg.ReadDeltaChar( base->rightmove ); + cmd.upmove = msg.ReadDeltaChar( base->upmove ); + cmd.angles[0] = msg.ReadDeltaShort( base->angles[0] ); + cmd.angles[1] = msg.ReadDeltaShort( base->angles[1] ); + cmd.angles[2] = msg.ReadDeltaShort( base->angles[2] ); + return; + } + + cmd.gameTime = msg.ReadLong(); + cmd.buttons = msg.ReadByte(); + cmd.mx = msg.ReadShort(); + cmd.my = msg.ReadShort(); + cmd.forwardmove = msg.ReadChar(); + cmd.rightmove = msg.ReadChar(); + cmd.upmove = msg.ReadChar(); + cmd.angles[0] = msg.ReadShort(); + cmd.angles[1] = msg.ReadShort(); + cmd.angles[2] = msg.ReadShort(); +} + +/* +================== +idAsyncNetwork::DuplicateUsercmd +================== +*/ +bool idAsyncNetwork::DuplicateUsercmd( const usercmd_t &previousUserCmd, usercmd_t ¤tUserCmd, int frame, int time ) { + + if ( currentUserCmd.gameTime <= previousUserCmd.gameTime ) { + + currentUserCmd = previousUserCmd; + currentUserCmd.gameFrame = frame; + currentUserCmd.gameTime = time; + currentUserCmd.duplicateCount++; + + if ( currentUserCmd.duplicateCount > MAX_USERCMD_DUPLICATION ) { + currentUserCmd.buttons &= ~BUTTON_ATTACK; + if ( abs( currentUserCmd.forwardmove ) > 2 ) currentUserCmd.forwardmove >>= 1; + if ( abs( currentUserCmd.rightmove ) > 2 ) currentUserCmd.rightmove >>= 1; + if ( abs( currentUserCmd.upmove ) > 2 ) currentUserCmd.upmove >>= 1; + } + + return true; + } + return false; +} + +/* +================== +idAsyncNetwork::UsercmdInputChanged +================== +*/ +bool idAsyncNetwork::UsercmdInputChanged( const usercmd_t &previousUserCmd, const usercmd_t ¤tUserCmd ) { + return previousUserCmd.buttons != currentUserCmd.buttons || + previousUserCmd.forwardmove != currentUserCmd.forwardmove || + previousUserCmd.rightmove != currentUserCmd.rightmove || + previousUserCmd.upmove != currentUserCmd.upmove || + previousUserCmd.angles[0] != currentUserCmd.angles[0] || + previousUserCmd.angles[1] != currentUserCmd.angles[1] || + previousUserCmd.angles[2] != currentUserCmd.angles[2]; +} + +/* +================== +idAsyncNetwork::SpawnServer_f +================== +*/ +void idAsyncNetwork::SpawnServer_f( const idCmdArgs &args ) { + + if(args.Argc() > 1) { + cvarSystem->SetCVarString("si_map", args.Argv(1)); + } + + // don't let a server spawn with singleplayer game type - it will crash + if ( idStr::Icmp( cvarSystem->GetCVarString( "si_gameType" ), "singleplayer" ) == 0 ) { + cvarSystem->SetCVarString( "si_gameType", "deathmatch" ); + } + com_asyncInput.SetBool( false ); + // make sure the current system state is compatible with net_serverDedicated + switch ( cvarSystem->GetCVarInteger( "net_serverDedicated" ) ) { + case 0: + case 2: + if ( !renderSystem->IsOpenGLRunning() ) { + common->Warning( "OpenGL is not running, net_serverDedicated == %d", cvarSystem->GetCVarInteger( "net_serverDedicated" ) ); + } + break; + case 1: + if ( renderSystem->IsOpenGLRunning() ) { + Sys_ShowConsole( 1, false ); + renderSystem->ShutdownOpenGL(); + } + soundSystem->SetMute( true ); + soundSystem->ShutdownHW(); + break; + } + // use serverMapRestart if we already have a running server + if ( server.IsActive() ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "serverMapRestart" ); + } else { + server.Spawn(); + } +} + +/* +================== +idAsyncNetwork::NextMap_f +================== +*/ +void idAsyncNetwork::NextMap_f( const idCmdArgs &args ) { + server.ExecuteMapChange(); +} + +/* +================== +idAsyncNetwork::Connect_f +================== +*/ +void idAsyncNetwork::Connect_f( const idCmdArgs &args ) { + if ( server.IsActive() ) { + common->Printf( "already running a server\n" ); + return; + } + if ( args.Argc() != 2 ) { + common->Printf( "USAGE: connect \n" ); + return; + } + com_asyncInput.SetBool( false ); + client.ConnectToServer( args.Argv( 1 ) ); +} + +/* +================== +idAsyncNetwork::Reconnect_f +================== +*/ +void idAsyncNetwork::Reconnect_f( const idCmdArgs &args ) { + client.Reconnect(); +} + +/* +================== +idAsyncNetwork::GetServerInfo_f +================== +*/ +void idAsyncNetwork::GetServerInfo_f( const idCmdArgs &args ) { + client.GetServerInfo( args.Argv( 1 ) ); +} + +/* +================== +idAsyncNetwork::GetLANServers_f +================== +*/ +void idAsyncNetwork::GetLANServers_f( const idCmdArgs &args ) { + client.GetLANServers(); +} + +/* +================== +idAsyncNetwork::ListServers_f +================== +*/ +void idAsyncNetwork::ListServers_f( const idCmdArgs &args ) { + client.ListServers(); +} + +/* +================== +idAsyncNetwork::RemoteConsole_f +================== +*/ +void idAsyncNetwork::RemoteConsole_f( const idCmdArgs &args ) { + client.RemoteConsole( args.Args() ); +} + +/* +================== +idAsyncNetwork::Heartbeat_f +================== +*/ +void idAsyncNetwork::Heartbeat_f( const idCmdArgs &args ) { + if ( !server.IsActive() ) { + common->Printf( "server is not running\n" ); + return; + } + server.MasterHeartbeat( true ); +} + +/* +================== +idAsyncNetwork::Kick_f +================== +*/ +void idAsyncNetwork::Kick_f( const idCmdArgs &args ) { + idStr clientId; + int iclient; + + if ( !server.IsActive() ) { + common->Printf( "server is not running\n" ); + return; + } + + clientId = args.Argv( 1 ); + if ( !clientId.IsNumeric() ) { + common->Printf( "usage: kick \n" ); + return; + } + iclient = atoi( clientId ); + + if ( server.GetLocalClientNum() == iclient ) { + common->Printf( "can't kick the host\n" ); + return; + } + + server.DropClient( iclient, "#str_07134" ); +} + +/* +================== +idAsyncNetwork::GetNETServers +================== +*/ +void idAsyncNetwork::GetNETServers( ) { + client.GetNETServers(); +} + +/* +================== +idAsyncNetwork::CheckNewVersion_f +================== +*/ +void idAsyncNetwork::CheckNewVersion_f( const idCmdArgs &args ) { + client.SendVersionCheck(); +} + +/* +================== +idAsyncNetwork::ExecuteSessionCommand +================== +*/ +void idAsyncNetwork::ExecuteSessionCommand( const char *sessCmd ) { + if ( sessCmd[ 0 ] ) { + if ( !idStr::Icmp( sessCmd, "game_startmenu" ) ) { + session->SetGUI( game->StartMenu(), NULL ); + } + } +} + +/* +================= +idAsyncNetwork::UpdateUI_f +================= +*/ +void idAsyncNetwork::UpdateUI_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Warning( "idAsyncNetwork::UpdateUI_f: wrong arguments\n" ); + return; + } + if ( !server.IsActive() ) { + common->Warning( "idAsyncNetwork::UpdateUI_f: server is not active\n" ); + return; + } + int clientNum = atoi( args.Args( 1 ) ); + server.UpdateUI( clientNum ); +} + +/* +=============== +idAsyncNetwork::BuildInvalidKeyMsg +=============== +*/ +void idAsyncNetwork::BuildInvalidKeyMsg( idStr &msg, bool valid[ 2 ] ) { + if ( !valid[ 0 ] ) { + msg += common->GetLanguageDict()->GetString( "#str_07194" ); + } + if ( fileSystem->HasD3XP() && !valid[ 1 ] ) { + if ( msg.Length() ) { + msg += "\n"; + } + msg += common->GetLanguageDict()->GetString( "#str_07195" ); + } + msg += "\n"; + msg += common->GetLanguageDict()->GetString( "#str_04304" ); +} + diff --git a/framework/async/AsyncNetwork.h b/framework/async/AsyncNetwork.h new file mode 100644 index 000000000..0ab4c462b --- /dev/null +++ b/framework/async/AsyncNetwork.h @@ -0,0 +1,210 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __ASYNCNETWORK_H__ +#define __ASYNCNETWORK_H__ + +/* +DOOM III gold: 33 +1.1 beta patch: 34 +1.1 patch: 35 +1.2 XP: 36-39 +1.3 patch: 40 +1.3.1: 41 +*/ +const int ASYNC_PROTOCOL_MINOR = 41; +const int ASYNC_PROTOCOL_VERSION = ( ASYNC_PROTOCOL_MAJOR << 16 ) + ASYNC_PROTOCOL_MINOR; +#define MAJOR_VERSION(v) ( v >> 16 ) + +const int MAX_ASYNC_CLIENTS = 32; + +const int MAX_USERCMD_BACKUP = 256; +const int MAX_USERCMD_DUPLICATION = 25; +const int MAX_USERCMD_RELAY = 10; + +// index 0 is hardcoded to be the idnet master +// which leaves 4 to user customization +const int MAX_MASTER_SERVERS = 5; + +const int MAX_NICKLEN = 32; + +// max number of servers that will be scanned for at a single IP address +const int MAX_SERVER_PORTS = 8; + +// special game init ids +const int GAME_INIT_ID_INVALID = -1; +const int GAME_INIT_ID_MAP_LOAD = -2; + + +#include "MsgChannel.h" +#include "AsyncServer.h" +#include "ServerScan.h" +#include "AsyncClient.h" + +/* +=============================================================================== + + Asynchronous Networking. + +=============================================================================== +*/ + + +// unreliable server -> client messages +enum { + SERVER_UNRELIABLE_MESSAGE_EMPTY = 0, + SERVER_UNRELIABLE_MESSAGE_PING, + SERVER_UNRELIABLE_MESSAGE_GAMEINIT, + SERVER_UNRELIABLE_MESSAGE_SNAPSHOT +}; + +// reliable server -> client messages +enum { + SERVER_RELIABLE_MESSAGE_PURE = 0, + SERVER_RELIABLE_MESSAGE_RELOAD, + SERVER_RELIABLE_MESSAGE_CLIENTINFO, + SERVER_RELIABLE_MESSAGE_SYNCEDCVARS, + SERVER_RELIABLE_MESSAGE_PRINT, + SERVER_RELIABLE_MESSAGE_DISCONNECT, + SERVER_RELIABLE_MESSAGE_APPLYSNAPSHOT, + SERVER_RELIABLE_MESSAGE_GAME, + SERVER_RELIABLE_MESSAGE_ENTERGAME +}; + +// unreliable client -> server messages +enum { + CLIENT_UNRELIABLE_MESSAGE_EMPTY = 0, + CLIENT_UNRELIABLE_MESSAGE_PINGRESPONSE, + CLIENT_UNRELIABLE_MESSAGE_USERCMD +}; + +// reliable client -> server messages +enum { + CLIENT_RELIABLE_MESSAGE_PURE = 0, + CLIENT_RELIABLE_MESSAGE_CLIENTINFO, + CLIENT_RELIABLE_MESSAGE_PRINT, + CLIENT_RELIABLE_MESSAGE_DISCONNECT, + CLIENT_RELIABLE_MESSAGE_GAME +}; + +// server print messages +enum { + SERVER_PRINT_MISC = 0, + SERVER_PRINT_BADPROTOCOL, + SERVER_PRINT_RCON, + SERVER_PRINT_GAMEDENY, + SERVER_PRINT_BADCHALLENGE +}; + +enum { + SERVER_DL_REDIRECT = 1, + SERVER_DL_LIST, + SERVER_DL_NONE +}; + +enum { + SERVER_PAK_NO = 0, + SERVER_PAK_YES, + SERVER_PAK_END +}; + +typedef struct master_s { + idCVar * var; + netadr_t address; + bool resolved; +} master_t; + + +class idAsyncNetwork { +public: + idAsyncNetwork(); + + static void Init( void ); + static void Shutdown( void ); + static bool IsActive( void ) { return ( server.IsActive() || client.IsActive() ); } + static void RunFrame( void ); + + static void WriteUserCmdDelta( idBitMsg &msg, const usercmd_t &cmd, const usercmd_t *base ); + static void ReadUserCmdDelta( const idBitMsg &msg, usercmd_t &cmd, const usercmd_t *base ); + + static bool DuplicateUsercmd( const usercmd_t &previousUserCmd, usercmd_t ¤tUserCmd, int frame, int time ); + static bool UsercmdInputChanged( const usercmd_t &previousUserCmd, const usercmd_t ¤tUserCmd ); + + // returns true if the corresponding master is set to something (and could be resolved) + static bool GetMasterAddress( int index, netadr_t &adr ); + // get the hardcoded idnet master, equivalent to GetMasterAddress( 0, .. ) + static netadr_t GetMasterAddress( void ); + + static void GetNETServers( ); + + static void ExecuteSessionCommand( const char *sessCmd ); + + static idAsyncServer server; + static idAsyncClient client; + + static idCVar verbose; // verbose output + static idCVar allowCheats; // allow cheats + static idCVar serverDedicated; // if set run a dedicated server + static idCVar serverSnapshotDelay; // number of milliseconds between snapshots + static idCVar serverMaxClientRate; // maximum outgoing rate to clients + static idCVar clientMaxRate; // maximum rate from server requested by client + static idCVar serverMaxUsercmdRelay; // maximum number of usercmds relayed to other clients + static idCVar serverZombieTimeout; // time out in seconds for zombie clients + static idCVar serverClientTimeout; // time out in seconds for connected clients + static idCVar clientServerTimeout; // time out in seconds for server + static idCVar serverDrawClient; // the server draws the view of this client + static idCVar serverRemoteConsolePassword; // remote console password + static idCVar clientPrediction; // how many additional milliseconds the clients runs ahead + static idCVar clientMaxPrediction; // max milliseconds into the future a client can run prediction + static idCVar clientUsercmdBackup; // how many usercmds the client sends from previous frames + static idCVar clientRemoteConsoleAddress; // remote console address + static idCVar clientRemoteConsolePassword; // remote console password + static idCVar master0; // idnet master server + static idCVar master1; // 1st master server + static idCVar master2; // 2nd master server + static idCVar master3; // 3rd master server + static idCVar master4; // 4th master server + static idCVar LANServer; // LAN mode + static idCVar serverReloadEngine; // reload engine on map change instead of growing the referenced paks + static idCVar serverAllowServerMod; // let a pure server start with a different game code than what is referenced in game code + static idCVar idleServer; // serverinfo reply, indicates all clients are idle + static idCVar clientDownload; // preferred download policy + + // same message used for offline check and network reply + static void BuildInvalidKeyMsg( idStr &msg, bool valid[ 2 ] ); + +private: + static int realTime; + static master_t masters[ MAX_MASTER_SERVERS]; // master1 etc. + + static void SpawnServer_f( const idCmdArgs &args ); + static void NextMap_f( const idCmdArgs &args ); + static void Connect_f( const idCmdArgs &args ); + static void Reconnect_f( const idCmdArgs &args ); + static void GetServerInfo_f( const idCmdArgs &args ); + static void GetLANServers_f( const idCmdArgs &args ); + static void ListServers_f( const idCmdArgs &args ); + static void RemoteConsole_f( const idCmdArgs &args ); + static void Heartbeat_f( const idCmdArgs &args ); + static void Kick_f( const idCmdArgs &args ); + static void CheckNewVersion_f( const idCmdArgs &args ); + static void UpdateUI_f( const idCmdArgs &args ); +}; + +#endif /* !__ASYNCNETWORK_H__ */ diff --git a/framework/async/AsyncServer.cpp b/framework/async/AsyncServer.cpp new file mode 100644 index 000000000..c86a801d2 --- /dev/null +++ b/framework/async/AsyncServer.cpp @@ -0,0 +1,2816 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "AsyncNetwork.h" + +#include "../Session_local.h" + +const int MIN_RECONNECT_TIME = 2000; +const int EMPTY_RESEND_TIME = 500; +const int PING_RESEND_TIME = 500; +const int NOINPUT_IDLE_TIME = 30000; + +const int HEARTBEAT_MSEC = 5*60*1000; + +// must be kept in sync with authReplyMsg_t +const char* authReplyMsg[] = { + // "Waiting for authorization", + "#str_07204", + // "Client unknown to auth", + "#str_07205", + // "Access denied - CD Key in use", + "#str_07206", + // "Auth custom message", // placeholder - we propagate a message from the master + "#str_07207", + // "Authorize Server - Waiting for client" + "#str_07208" +}; + +const char* authReplyStr[] = { + "AUTH_NONE", + "AUTH_OK", + "AUTH_WAIT", + "AUTH_DENY" +}; + +/* +================== +idAsyncServer::idAsyncServer +================== +*/ +idAsyncServer::idAsyncServer( void ) { + int i; + + active = false; + realTime = 0; + serverTime = 0; + serverId = 0; + serverDataChecksum = 0; + localClientNum = -1; + gameInitId = 0; + gameFrame = 0; + gameTime = 0; + gameTimeResidual = 0; + memset( challenges, 0, sizeof( challenges ) ); + memset( userCmds, 0, sizeof( userCmds ) ); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + ClearClient( i ); + } + serverReloadingEngine = false; + nextHeartbeatTime = 0; + nextAsyncStatsTime = 0; + noRconOutput = true; + lastAuthTime = 0; + + memset( stats_outrate, 0, sizeof( stats_outrate ) ); + stats_current = 0; + stats_average_sum = 0; + stats_max = 0; + stats_max_index = 0; +} + +/* +================== +idAsyncServer::InitPort +================== +*/ +bool idAsyncServer::InitPort( void ) { + int lastPort; + + // if this is the first time we have spawned a server, open the UDP port + if ( !serverPort.GetPort() ) { + if ( cvarSystem->GetCVarInteger( "net_port" ) != 0 ) { + if ( !serverPort.InitForPort( cvarSystem->GetCVarInteger( "net_port" ) ) ) { + common->Printf( "Unable to open server on port %d (net_port)\n", cvarSystem->GetCVarInteger( "net_port" ) ); + return false; + } + } else { + // scan for multiple ports, in case other servers are running on this IP already + for ( lastPort = 0; lastPort < NUM_SERVER_PORTS; lastPort++ ) { + if ( serverPort.InitForPort( PORT_SERVER + lastPort ) ) { + break; + } + } + if ( lastPort >= NUM_SERVER_PORTS ) { + common->Printf( "Unable to open server network port.\n" ); + return false; + } + } + } + + return true; +} + +/* +================== +idAsyncServer::ClosePort +================== +*/ +void idAsyncServer::ClosePort( void ) { + int i; + + serverPort.Close(); + for ( i = 0; i < MAX_CHALLENGES; i++ ) { + challenges[ i ].authReplyPrint.Clear(); + } +} + +/* +================== +idAsyncServer::Spawn +================== +*/ +void idAsyncServer::Spawn( void ) { + int i, size; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t from; + + // shutdown any current game + session->Stop(); + + if ( active ) { + return; + } + + if ( !InitPort() ) { + return; + } + + // trash any currently pending packets + while( serverPort.GetPacket( from, msgBuf, size, sizeof( msgBuf ) ) ) { + } + + // reset cheats cvars + if ( !idAsyncNetwork::allowCheats.GetBool() ) { + cvarSystem->ResetFlaggedVariables( CVAR_CHEAT ); + } + + memset( challenges, 0, sizeof( challenges ) ); + memset( userCmds, 0, sizeof( userCmds ) ); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + ClearClient( i ); + } + + common->Printf( "Server spawned on port %i.\n", serverPort.GetPort() ); + + // calculate a checksum on some of the essential data used + serverDataChecksum = declManager->GetChecksum(); + + // get a pseudo random server id, but don't use the id which is reserved for connectionless packets + serverId = Sys_Milliseconds() & CONNECTIONLESS_MESSAGE_ID_MASK; + + active = true; + + nextHeartbeatTime = 0; + nextAsyncStatsTime = 0; + + ExecuteMapChange(); +} + +/* +================== +idAsyncServer::Kill +================== +*/ +void idAsyncServer::Kill( void ) { + int i, j; + + if ( !active ) { + return; + } + + // drop all clients + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + DropClient( i, "#str_07135" ); + } + + // send some empty messages to the zombie clients to make sure they disconnect + for ( j = 0; j < 4; j++ ) { + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState == SCS_ZOMBIE ) { + if ( clients[i].channel.UnsentFragmentsLeft() ) { + clients[i].channel.SendNextFragment( serverPort, serverTime ); + } else { + SendEmptyToClient( i, true ); + } + } + } + Sys_Sleep( 10 ); + } + + // reset any pureness + fileSystem->ClearPureChecksums(); + + active = false; + + // shutdown any current game + session->Stop(); +} + +/* +================== +idAsyncServer::ExecuteMapChange +================== +*/ +void idAsyncServer::ExecuteMapChange( void ) { + int i; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + idStr mapName; + findFile_t ff; + bool addonReload = false; + char bestGameType[ MAX_STRING_CHARS ]; + + assert( active ); + + // reset any pureness + fileSystem->ClearPureChecksums(); + + // make sure the map/gametype combo is good + game->GetBestGameType( cvarSystem->GetCVarString("si_map"), cvarSystem->GetCVarString("si_gametype"), bestGameType ); + cvarSystem->SetCVarString("si_gametype", bestGameType ); + + // initialize map settings + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); + + sprintf( mapName, "maps/%s", sessLocal.mapSpawnData.serverInfo.GetString( "si_map" ) ); + mapName.SetFileExtension( ".map" ); + ff = fileSystem->FindFile( mapName, !serverReloadingEngine ); + switch( ff ) { + case FIND_NO: + common->Printf( "Can't find map %s\n", mapName.c_str() ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + return; + case FIND_ADDON: + // NOTE: we have no problem with addon dependencies here because if the map is in + // an addon pack that's already on search list, then all it's deps are assumed to be on search as well + common->Printf( "map %s is in an addon pak - reloading\n", mapName.c_str() ); + addonReload = true; + break; + default: + break; + } + + // if we are asked to do a full reload, the strategy is completely different + if ( !serverReloadingEngine && ( addonReload || idAsyncNetwork::serverReloadEngine.GetInteger() != 0 ) ) { + if ( idAsyncNetwork::serverReloadEngine.GetInteger() != 0 ) { + common->Printf( "net_serverReloadEngine enabled - doing a full reload\n" ); + } + // tell the clients to reconnect + // FIXME: shouldn't they wait for the new pure list, then reload? + // in a lot of cases this is going to trigger two reloadEngines for the clients + // one to restart, the other one to set paks right ( with addon for instance ) + // can fix by reconnecting without reloading and waiting for the server to tell.. + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[ i ].clientState >= SCS_PUREWAIT && i != localClientNum ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_RELOAD ); + SendReliableMessage( i, msg ); + clients[ i ].clientState = SCS_ZOMBIE; // so we don't bother sending a disconnect + } + } + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadEngine" ); + serverReloadingEngine = true; // don't get caught in endless loop + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "spawnServer\n" ); + // decrease feature + if ( idAsyncNetwork::serverReloadEngine.GetInteger() > 0 ) { + idAsyncNetwork::serverReloadEngine.SetInteger( idAsyncNetwork::serverReloadEngine.GetInteger() - 1 ); + } + return; + } + serverReloadingEngine = false; + + serverTime = 0; + + // initialize game id and time + gameInitId ^= Sys_Milliseconds(); // NOTE: make sure the gameInitId is always a positive number because negative numbers have special meaning + gameFrame = 0; + gameTime = 0; + gameTimeResidual = 0; + memset( userCmds, 0, sizeof( userCmds ) ); + + if ( idAsyncNetwork::serverDedicated.GetInteger() == 0 ) { + InitLocalClient( 0 ); + } else { + localClientNum = -1; + } + + // re-initialize all connected clients for the new map + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_PUREWAIT && i != localClientNum ) { + + InitClient( i, clients[i].clientId, clients[i].clientRate ); + + SendGameInitToClient( i ); + + if ( sessLocal.mapSpawnData.serverInfo.GetBool( "si_pure" ) ) { + clients[ i ].clientState = SCS_PUREWAIT; + } + } + } + + // setup the game pak checksums + // since this is not dependant on si_pure we catch anything bad before loading map + if ( sessLocal.mapSpawnData.serverInfo.GetInt( "si_pure" ) ) { + if ( !fileSystem->UpdateGamePakChecksums( ) ) { + session->MessageBox( MSG_OK, common->GetLanguageDict()->GetString ( "#str_04337" ), common->GetLanguageDict()->GetString ( "#str_04338" ), true ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + return; + } + } + + // load map + sessLocal.ExecuteMapChange(); + + if ( localClientNum >= 0 ) { + BeginLocalClient(); + } else { + game->SetLocalClient( -1 ); + } + + if ( sessLocal.mapSpawnData.serverInfo.GetInt( "si_pure" ) ) { + // lock down the pak list + fileSystem->UpdatePureServerChecksums( ); + // tell the clients so they can work out their pure lists + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[ i ].clientState == SCS_PUREWAIT ) { + if ( !SendReliablePureToClient( i ) ) { + clients[ i ].clientState = SCS_CONNECTED; + } + } + } + } + + // serverTime gets reset, force a heartbeat so timings restart + MasterHeartbeat( true ); +} + +/* +================== +idAsyncServer::GetPort +================== +*/ +int idAsyncServer::GetPort( void ) const { + return serverPort.GetPort(); +} + +/* +=============== +idAsyncServer::GetBoundAdr +=============== +*/ +netadr_t idAsyncServer::GetBoundAdr( void ) const { + return serverPort.GetAdr(); +} + +/* +================== +idAsyncServer::GetOutgoingRate +================== +*/ +int idAsyncServer::GetOutgoingRate( void ) const { + int i, rate; + + rate = 0; + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + const serverClient_t &client = clients[i]; + + if ( client.clientState >= SCS_CONNECTED ) { + rate += client.channel.GetOutgoingRate(); + } + } + return rate; +} + +/* +================== +idAsyncServer::GetIncomingRate +================== +*/ +int idAsyncServer::GetIncomingRate( void ) const { + int i, rate; + + rate = 0; + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + const serverClient_t &client = clients[i]; + + if ( client.clientState >= SCS_CONNECTED ) { + rate += client.channel.GetIncomingRate(); + } + } + return rate; +} + +/* +================== +idAsyncServer::IsClientInGame +================== +*/ +bool idAsyncServer::IsClientInGame( int clientNum ) const { + return ( clients[clientNum].clientState >= SCS_INGAME ); +} + +/* +================== +idAsyncServer::GetClientPing +================== +*/ +int idAsyncServer::GetClientPing( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 99999; + } else { + return client.clientPing; + } +} + +/* +================== +idAsyncServer::GetClientPrediction +================== +*/ +int idAsyncServer::GetClientPrediction( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 99999; + } else { + return client.clientPrediction; + } +} + +/* +================== +idAsyncServer::GetClientTimeSinceLastPacket +================== +*/ +int idAsyncServer::GetClientTimeSinceLastPacket( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 99999; + } else { + return serverTime - client.lastPacketTime; + } +} + +/* +================== +idAsyncServer::GetClientTimeSinceLastInput +================== +*/ +int idAsyncServer::GetClientTimeSinceLastInput( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 99999; + } else { + return serverTime - client.lastInputTime; + } +} + +/* +================== +idAsyncServer::GetClientOutgoingRate +================== +*/ +int idAsyncServer::GetClientOutgoingRate( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return -1; + } else { + return client.channel.GetOutgoingRate(); + } +} + +/* +================== +idAsyncServer::GetClientIncomingRate +================== +*/ +int idAsyncServer::GetClientIncomingRate( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return -1; + } else { + return client.channel.GetIncomingRate(); + } +} + +/* +================== +idAsyncServer::GetClientOutgoingCompression +================== +*/ +float idAsyncServer::GetClientOutgoingCompression( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 0.0f; + } else { + return client.channel.GetOutgoingCompression(); + } +} + +/* +================== +idAsyncServer::GetClientIncomingCompression +================== +*/ +float idAsyncServer::GetClientIncomingCompression( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 0.0f; + } else { + return client.channel.GetIncomingCompression(); + } +} + +/* +================== +idAsyncServer::GetClientIncomingPacketLoss +================== +*/ +float idAsyncServer::GetClientIncomingPacketLoss( int clientNum ) const { + const serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return 0.0f; + } else { + return client.channel.GetIncomingPacketLoss(); + } +} + +/* +================== +idAsyncServer::GetNumClients +================== +*/ +int idAsyncServer::GetNumClients( void ) const { + int ret = 0; + for ( int i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[ i ].clientState >= SCS_CONNECTED ) { + ret++; + } + } + return ret; +} + +/* +================== +idAsyncServer::GetNumIdleClients +================== +*/ +int idAsyncServer::GetNumIdleClients( void ) const { + int ret = 0; + for ( int i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[ i ].clientState >= SCS_CONNECTED ) { + if ( serverTime - clients[ i ].lastInputTime > NOINPUT_IDLE_TIME ) { + ret++; + } + } + } + return ret; +} + +/* +================== +idAsyncServer::DuplicateUsercmds +================== +*/ +void idAsyncServer::DuplicateUsercmds( int frame, int time ) { + int i, previousIndex, currentIndex; + + previousIndex = ( frame - 1 ) & ( MAX_USERCMD_BACKUP - 1 ); + currentIndex = frame & ( MAX_USERCMD_BACKUP - 1 ); + + // duplicate previous user commands if no new commands are available for a client + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState == SCS_FREE ) { + continue; + } + + if ( idAsyncNetwork::DuplicateUsercmd( userCmds[previousIndex][i], userCmds[currentIndex][i], frame, time ) ) { + clients[i].numDuplicatedUsercmds++; + } + } +} + +/* +================== +idAsyncServer::ClearClient +================== +*/ +void idAsyncServer::ClearClient( int clientNum ) { + serverClient_t &client = clients[clientNum]; + client.clientId = 0; + client.clientState = SCS_FREE; + client.clientPrediction = 0; + client.clientAheadTime = 0; + client.clientRate = 0; + client.clientPing = 0; + client.gameInitSequence = 0; + client.gameFrame = 0; + client.gameTime = 0; + client.channel.Shutdown(); + client.lastConnectTime = 0; + client.lastEmptyTime = 0; + client.lastPingTime = 0; + client.lastSnapshotTime = 0; + client.lastPacketTime = 0; + client.lastInputTime = 0; + client.snapshotSequence = 0; + client.acknowledgeSnapshotSequence = 0; + client.numDuplicatedUsercmds = 0; +} + +/* +================== +idAsyncServer::InitClient +================== +*/ +void idAsyncServer::InitClient( int clientNum, int clientId, int clientRate ) { + int i; + + // clear the user info + sessLocal.mapSpawnData.userInfo[ clientNum ].Clear(); // always start with a clean base + + // clear the server client + serverClient_t &client = clients[clientNum]; + client.clientId = clientId; + client.clientState = SCS_CONNECTED; + client.clientPrediction = 0; + client.clientAheadTime = 0; + client.gameInitSequence = -1; + client.gameFrame = 0; + client.gameTime = 0; + client.channel.ResetRate(); + client.clientRate = clientRate ? clientRate : idAsyncNetwork::serverMaxClientRate.GetInteger(); + client.channel.SetMaxOutgoingRate( Min( idAsyncNetwork::serverMaxClientRate.GetInteger(), client.clientRate ) ); + client.clientPing = 0; + client.lastConnectTime = serverTime; + client.lastEmptyTime = serverTime; + client.lastPingTime = serverTime; + client.lastSnapshotTime = serverTime; + client.lastPacketTime = serverTime; + client.lastInputTime = serverTime; + client.acknowledgeSnapshotSequence = 0; + client.numDuplicatedUsercmds = 0; + + // clear the user commands + for ( i = 0; i < MAX_USERCMD_BACKUP; i++ ) { + memset( &userCmds[i][clientNum], 0, sizeof( userCmds[i][clientNum] ) ); + } + + // let the game know a player connected + game->ServerClientConnect( clientNum, client.guid ); +} + +/* +================== +idAsyncServer::InitLocalClient +================== +*/ +void idAsyncServer::InitLocalClient( int clientNum ) { + netadr_t badAddress; + + localClientNum = clientNum; + InitClient( clientNum, 0, 0 ); + memset( &badAddress, 0, sizeof( badAddress ) ); + badAddress.type = NA_BAD; + clients[clientNum].channel.Init( badAddress, serverId ); + clients[clientNum].clientState = SCS_INGAME; + sessLocal.mapSpawnData.userInfo[clientNum] = *cvarSystem->MoveCVarsToDict( CVAR_USERINFO ); +} + +/* +================== +idAsyncServer::BeginLocalClient +================== +*/ +void idAsyncServer::BeginLocalClient( void ) { + game->SetLocalClient( localClientNum ); + game->SetUserInfo( localClientNum, sessLocal.mapSpawnData.userInfo[localClientNum], false, false ); + game->ServerClientBegin( localClientNum ); +} + +/* +================== +idAsyncServer::LocalClientInput +================== +*/ +void idAsyncServer::LocalClientInput( void ) { + int index; + + if ( localClientNum < 0 ) { + return; + } + + index = gameFrame & ( MAX_USERCMD_BACKUP - 1 ); + userCmds[index][localClientNum] = usercmdGen->GetDirectUsercmd(); + userCmds[index][localClientNum].gameFrame = gameFrame; + userCmds[index][localClientNum].gameTime = gameTime; + if ( idAsyncNetwork::UsercmdInputChanged( userCmds[( gameFrame - 1 ) & ( MAX_USERCMD_BACKUP - 1 )][localClientNum], userCmds[index][localClientNum] ) ) { + clients[localClientNum].lastInputTime = serverTime; + } + clients[localClientNum].gameFrame = gameFrame; + clients[localClientNum].gameTime = gameTime; + clients[localClientNum].lastPacketTime = serverTime; +} + +/* +================== +idAsyncServer::DropClient +================== +*/ +void idAsyncServer::DropClient( int clientNum, const char *reason ) { + int i; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + serverClient_t &client = clients[clientNum]; + + if ( client.clientState <= SCS_ZOMBIE ) { + return; + } + + if ( client.clientState >= SCS_PUREWAIT && clientNum != localClientNum ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_DISCONNECT ); + msg.WriteLong( clientNum ); + msg.WriteString( reason ); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + // clientNum so SCS_PUREWAIT client gets it's own disconnect msg + if ( i == clientNum || clients[i].clientState >= SCS_CONNECTED ) { + SendReliableMessage( i, msg ); + } + } + } + + reason = common->GetLanguageDict()->GetString( reason ); + common->Printf( "client %d %s\n", clientNum, reason ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "addChatLine \"%s^0 %s\"", sessLocal.mapSpawnData.userInfo[ clientNum ].GetString( "ui_name" ), reason ) ); + + // remove the player from the game + game->ServerClientDisconnect( clientNum ); + + client.clientState = SCS_ZOMBIE; +} + +/* +================== +idAsyncServer::SendReliableMessage +================== +*/ +void idAsyncServer::SendReliableMessage( int clientNum, const idBitMsg &msg ) { + if ( clientNum == localClientNum ) { + return; + } + if ( !clients[ clientNum ].channel.SendReliableMessage( msg ) ) { + clients[ clientNum ].channel.ClearReliableMessages(); + DropClient( clientNum, "#str_07136" ); + } +} + +/* +================== +idAsyncServer::CheckClientTimeouts +================== +*/ +void idAsyncServer::CheckClientTimeouts( void ) { + int i, zombieTimeout, clientTimeout; + + zombieTimeout = serverTime - idAsyncNetwork::serverZombieTimeout.GetInteger() * 1000; + clientTimeout = serverTime - idAsyncNetwork::serverClientTimeout.GetInteger() * 1000; + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + + if ( i == localClientNum ) { + continue; + } + + if ( client.lastPacketTime > serverTime ) { + client.lastPacketTime = serverTime; + continue; + } + + if ( client.clientState == SCS_ZOMBIE && client.lastPacketTime < zombieTimeout ) { + client.channel.Shutdown(); + client.clientState = SCS_FREE; + continue; + } + + if ( client.clientState >= SCS_PUREWAIT && client.lastPacketTime < clientTimeout ) { + DropClient( i, "#str_07137" ); + continue; + } + } +} + +/* +================== +idAsyncServer::SendPrintBroadcast +================== +*/ +void idAsyncServer::SendPrintBroadcast( const char *string ) { + int i; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_PRINT ); + msg.WriteString( string ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_CONNECTED ) { + SendReliableMessage( i, msg ); + } + } +} + +/* +================== +idAsyncServer::SendPrintToClient +================== +*/ +void idAsyncServer::SendPrintToClient( int clientNum, const char *string ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + serverClient_t &client = clients[clientNum]; + + if ( client.clientState < SCS_CONNECTED ) { + return; + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_PRINT ); + msg.WriteString( string ); + + SendReliableMessage( clientNum, msg ); +} + +/* +================== +idAsyncServer::SendUserInfoBroadcast +================== +*/ +void idAsyncServer::SendUserInfoBroadcast( int userInfoNum, const idDict &info, bool sendToAll ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + const idDict *gameInfo; + bool gameModifiedInfo; + + gameInfo = game->SetUserInfo( userInfoNum, info, false, true ); + if ( gameInfo ) { + gameModifiedInfo = true; + } else { + gameModifiedInfo = false; + gameInfo = &info; + } + + if ( userInfoNum == localClientNum ) { + common->DPrintf( "local user info modified by server\n" ); + cvarSystem->SetCVarsFromDict( *gameInfo ); + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); // don't emit back + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_CLIENTINFO ); + msg.WriteByte( userInfoNum ); + if ( gameModifiedInfo || sendToAll ) { + msg.WriteBits( 0, 1 ); + } else { + msg.WriteBits( 1, 1 ); + } + +#if ID_CLIENTINFO_TAGS + msg.WriteLong( sessLocal.mapSpawnData.userInfo[userInfoNum].Checksum() ); + common->DPrintf( "broadcast for client %d: 0x%x\n", userInfoNum, sessLocal.mapSpawnData.userInfo[userInfoNum].Checksum() ); + sessLocal.mapSpawnData.userInfo[userInfoNum].Print(); +#endif + + if ( gameModifiedInfo || sendToAll ) { + msg.WriteDeltaDict( *gameInfo, NULL ); + } else { + msg.WriteDeltaDict( *gameInfo, &sessLocal.mapSpawnData.userInfo[userInfoNum] ); + } + + for ( int i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_CONNECTED && ( sendToAll || i != userInfoNum || gameModifiedInfo ) ) { + SendReliableMessage( i, msg ); + } + } + + sessLocal.mapSpawnData.userInfo[userInfoNum] = *gameInfo; +} + +/* +================== +idAsyncServer::UpdateUI +if the game modifies userInfo, it will call this through command system +we then need to get the info from the game, and broadcast to clients +( using DeltaDict and our current mapSpawnData as a base ) +================== +*/ +void idAsyncServer::UpdateUI( int clientNum ) { + const idDict *info = game->GetUserInfo( clientNum ); + + if ( !info ) { + common->Warning( "idAsyncServer::UpdateUI: no info from game\n" ); + return; + } + + SendUserInfoBroadcast( clientNum, *info, true ); +} + +/* +================== +idAsyncServer::SendUserInfoToClient +================== +*/ +void idAsyncServer::SendUserInfoToClient( int clientNum, int userInfoNum, const idDict &info ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( clients[clientNum].clientState < SCS_CONNECTED ) { + return; + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_CLIENTINFO ); + msg.WriteByte( userInfoNum ); + msg.WriteBits( 0, 1 ); + +#if ID_CLIENTINFO_TAGS + msg.WriteLong( 0 ); + common->DPrintf( "user info %d to client %d: NULL base\n", userInfoNum, clientNum ); +#endif + + msg.WriteDeltaDict( info, NULL ); + + SendReliableMessage( clientNum, msg ); +} + +/* +================== +idAsyncServer::SendSyncedCvarsBroadcast +================== +*/ +void idAsyncServer::SendSyncedCvarsBroadcast( const idDict &cvars ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + int i; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_SYNCEDCVARS ); + msg.WriteDeltaDict( cvars, &sessLocal.mapSpawnData.syncedCVars ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_CONNECTED ) { + SendReliableMessage( i, msg ); + } + } + + sessLocal.mapSpawnData.syncedCVars = cvars; +} + +/* +================== +idAsyncServer::SendSyncedCvarsToClient +================== +*/ +void idAsyncServer::SendSyncedCvarsToClient( int clientNum, const idDict &cvars ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( clients[clientNum].clientState < SCS_CONNECTED ) { + return; + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_SYNCEDCVARS ); + msg.WriteDeltaDict( cvars, NULL ); + + SendReliableMessage( clientNum, msg ); +} + +/* +================== +idAsyncServer::SendApplySnapshotToClient +================== +*/ +void idAsyncServer::SendApplySnapshotToClient( int clientNum, int sequence ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_APPLYSNAPSHOT ); + msg.WriteLong( sequence ); + + SendReliableMessage( clientNum, msg ); +} + +/* +================== +idAsyncServer::SendEmptyToClient +================== +*/ +bool idAsyncServer::SendEmptyToClient( int clientNum, bool force ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + serverClient_t &client = clients[clientNum]; + + if ( client.lastEmptyTime > realTime ) { + client.lastEmptyTime = realTime; + } + + if ( !force && ( realTime - client.lastEmptyTime < EMPTY_RESEND_TIME ) ) { + return false; + } + + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "sending empty to client %d: gameInitId = %d, gameFrame = %d, gameTime = %d\n", clientNum, gameInitId, gameFrame, gameTime ); + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( gameInitId ); + msg.WriteByte( SERVER_UNRELIABLE_MESSAGE_EMPTY ); + + client.channel.SendMessage( serverPort, serverTime, msg ); + + client.lastEmptyTime = realTime; + + return true; +} + +/* +================== +idAsyncServer::SendPingToClient +================== +*/ +bool idAsyncServer::SendPingToClient( int clientNum ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + serverClient_t &client = clients[clientNum]; + + if ( client.lastPingTime > realTime ) { + client.lastPingTime = realTime; + } + + if ( realTime - client.lastPingTime < PING_RESEND_TIME ) { + return false; + } + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "pinging client %d: gameInitId = %d, gameFrame = %d, gameTime = %d\n", clientNum, gameInitId, gameFrame, gameTime ); + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( gameInitId ); + msg.WriteByte( SERVER_UNRELIABLE_MESSAGE_PING ); + msg.WriteLong( realTime ); + + client.channel.SendMessage( serverPort, serverTime, msg ); + + client.lastPingTime = realTime; + + return true; +} + +/* +================== +idAsyncServer::SendGameInitToClient +================== +*/ +void idAsyncServer::SendGameInitToClient( int clientNum ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "sending gameinit to client %d: gameInitId = %d, gameFrame = %d, gameTime = %d\n", clientNum, gameInitId, gameFrame, gameTime ); + } + + serverClient_t &client = clients[clientNum]; + + // clear the unsent fragments. might flood winsock but that's ok + while( client.channel.UnsentFragmentsLeft() ) { + client.channel.SendNextFragment( serverPort, serverTime ); + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( gameInitId ); + msg.WriteByte( SERVER_UNRELIABLE_MESSAGE_GAMEINIT ); + msg.WriteLong( gameFrame ); + msg.WriteLong( gameTime ); + msg.WriteDeltaDict( sessLocal.mapSpawnData.serverInfo, NULL ); + client.gameInitSequence = client.channel.SendMessage( serverPort, serverTime, msg ); +} + +/* +================== +idAsyncServer::SendSnapshotToClient +================== +*/ +bool idAsyncServer::SendSnapshotToClient( int clientNum ) { + int i, j, index, numUsercmds; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + usercmd_t * last; + byte clientInPVS[MAX_ASYNC_CLIENTS >> 3]; + + serverClient_t &client = clients[clientNum]; + + if ( serverTime - client.lastSnapshotTime < idAsyncNetwork::serverSnapshotDelay.GetInteger() ) { + return false; + } + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "sending snapshot to client %d: gameInitId = %d, gameFrame = %d, gameTime = %d\n", clientNum, gameInitId, gameFrame, gameTime ); + } + + // how far is the client ahead of the server minus the packet delay + client.clientAheadTime = client.gameTime - ( gameTime + gameTimeResidual ); + + // write the snapshot + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( gameInitId ); + msg.WriteByte( SERVER_UNRELIABLE_MESSAGE_SNAPSHOT ); + msg.WriteLong( client.snapshotSequence ); + msg.WriteLong( gameFrame ); + msg.WriteLong( gameTime ); + msg.WriteByte( idMath::ClampChar( client.numDuplicatedUsercmds ) ); + msg.WriteShort( idMath::ClampShort( client.clientAheadTime ) ); + + // write the game snapshot + game->ServerWriteSnapshot( clientNum, client.snapshotSequence, msg, clientInPVS, MAX_ASYNC_CLIENTS ); + + // write the latest user commands from the other clients in the PVS to the snapshot + for ( last = NULL, i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + + if ( client.clientState == SCS_FREE || i == clientNum ) { + continue; + } + + // if the client is not in the PVS + if ( !( clientInPVS[i >> 3] & ( 1 << ( i & 7 ) ) ) ) { + continue; + } + + int maxRelay = idMath::ClampInt( 1, MAX_USERCMD_RELAY, idAsyncNetwork::serverMaxUsercmdRelay.GetInteger() ); + + // Max( 1, to always send at least one cmd, which we know we have because we call DuplicateUsercmds in RunFrame + numUsercmds = Max( 1, Min( client.gameFrame, gameFrame + maxRelay ) - gameFrame ); + msg.WriteByte( i ); + msg.WriteByte( numUsercmds ); + for ( j = 0; j < numUsercmds; j++ ) { + index = ( gameFrame + j ) & ( MAX_USERCMD_BACKUP - 1 ); + idAsyncNetwork::WriteUserCmdDelta( msg, userCmds[index][i], last ); + last = &userCmds[index][i]; + } + } + msg.WriteByte( MAX_ASYNC_CLIENTS ); + + client.channel.SendMessage( serverPort, serverTime, msg ); + + client.lastSnapshotTime = serverTime; + client.snapshotSequence++; + client.numDuplicatedUsercmds = 0; + + return true; +} + +/* +================== +idAsyncServer::ProcessUnreliableClientMessage +================== +*/ +void idAsyncServer::ProcessUnreliableClientMessage( int clientNum, const idBitMsg &msg ) { + int i, id, acknowledgeSequence, clientGameInitId, clientGameFrame, numUsercmds, index; + usercmd_t *last; + + serverClient_t &client = clients[clientNum]; + + if ( client.clientState == SCS_ZOMBIE ) { + return; + } + + acknowledgeSequence = msg.ReadLong(); + clientGameInitId = msg.ReadLong(); + + // while loading a map the client may send empty messages to keep the connection alive + if ( clientGameInitId == GAME_INIT_ID_MAP_LOAD ) { + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "ignore unreliable msg from client %d, gameInitId == ID_MAP_LOAD\n", clientNum ); + } + return; + } + + // check if the client is in the right game + if ( clientGameInitId != gameInitId ) { + if ( acknowledgeSequence > client.gameInitSequence ) { + // the client is connected but not in the right game + client.clientState = SCS_CONNECTED; + + // send game init to client + SendGameInitToClient( clientNum ); + + if ( sessLocal.mapSpawnData.serverInfo.GetBool( "si_pure" ) ) { + client.clientState = SCS_PUREWAIT; + if ( !SendReliablePureToClient( clientNum ) ) { + client.clientState = SCS_CONNECTED; + } + } + } else if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "ignore unreliable msg from client %d, wrong gameInit, old sequence\n", clientNum ); + } + return; + } + + client.acknowledgeSnapshotSequence = msg.ReadLong(); + + if ( client.clientState == SCS_CONNECTED ) { + + // the client is in the right game + client.clientState = SCS_INGAME; + + // send the user info of other clients + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_CONNECTED && i != clientNum ) { + SendUserInfoToClient( clientNum, i, sessLocal.mapSpawnData.userInfo[i] ); + } + } + + // send synchronized cvars to client + SendSyncedCvarsToClient( clientNum, sessLocal.mapSpawnData.syncedCVars ); + + SendEnterGameToClient( clientNum ); + + // get the client running in the game + game->ServerClientBegin( clientNum ); + + // write any reliable messages to initialize the client game state + game->ServerWriteInitialReliableMessages( clientNum ); + } else if ( client.clientState == SCS_INGAME ) { + + // apply the last snapshot the client received + if ( game->ServerApplySnapshot( clientNum, client.acknowledgeSnapshotSequence ) ) { + SendApplySnapshotToClient( clientNum, client.acknowledgeSnapshotSequence ); + } + } + + // process the unreliable message + id = msg.ReadByte(); + switch( id ) { + case CLIENT_UNRELIABLE_MESSAGE_EMPTY: { + if ( idAsyncNetwork::verbose.GetInteger() ) { + common->Printf( "received empty message for client %d\n", clientNum ); + } + break; + } + case CLIENT_UNRELIABLE_MESSAGE_PINGRESPONSE: { + client.clientPing = realTime - msg.ReadLong(); + break; + } + case CLIENT_UNRELIABLE_MESSAGE_USERCMD: { + + client.clientPrediction = msg.ReadShort(); + + // read user commands + clientGameFrame = msg.ReadLong(); + numUsercmds = msg.ReadByte(); + for ( last = NULL, i = clientGameFrame - numUsercmds + 1; i <= clientGameFrame; i++ ) { + index = i & ( MAX_USERCMD_BACKUP - 1 ); + idAsyncNetwork::ReadUserCmdDelta( msg, userCmds[index][clientNum], last ); + userCmds[index][clientNum].gameFrame = i; + userCmds[index][clientNum].duplicateCount = 0; + if ( idAsyncNetwork::UsercmdInputChanged( userCmds[( i - 1 ) & ( MAX_USERCMD_BACKUP - 1 )][clientNum], userCmds[index][clientNum] ) ) { + client.lastInputTime = serverTime; + } + last = &userCmds[index][clientNum]; + } + + if ( last ) { + client.gameFrame = last->gameFrame; + client.gameTime = last->gameTime; + } + + if ( idAsyncNetwork::verbose.GetInteger() == 2 ) { + common->Printf( "received user command for client %d, gameInitId = %d, gameFrame, %d gameTime %d\n", clientNum, clientGameInitId, client.gameFrame, client.gameTime ); + } + break; + } + default: { + common->Printf( "unknown unreliable message %d from client %d\n", id, clientNum ); + break; + } + } +} + +/* +================== +idAsyncServer::ProcessReliableClientMessages +================== +*/ +void idAsyncServer::ProcessReliableClientMessages( int clientNum ) { + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + byte id; + + serverClient_t &client = clients[clientNum]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + + while ( client.channel.GetReliableMessage( msg ) ) { + id = msg.ReadByte(); + switch( id ) { + case CLIENT_RELIABLE_MESSAGE_CLIENTINFO: { + idDict info; + msg.ReadDeltaDict( info, &sessLocal.mapSpawnData.userInfo[clientNum] ); + SendUserInfoBroadcast( clientNum, info ); + break; + } + case CLIENT_RELIABLE_MESSAGE_PRINT: { + char string[MAX_STRING_CHARS]; + msg.ReadString( string, sizeof( string ) ); + common->Printf( "%s\n", string ); + break; + } + case CLIENT_RELIABLE_MESSAGE_DISCONNECT: { + DropClient( clientNum, "#str_07138" ); + break; + } + case CLIENT_RELIABLE_MESSAGE_PURE: { + // we get this message once the client has successfully updated it's pure list + ProcessReliablePure( clientNum, msg ); + break; + } + default: { + // pass reliable message on to game code + game->ServerProcessReliableMessage( clientNum, msg ); + break; + } + } + } +} + +/* +================== +idAsyncServer::ProcessAuthMessage +================== +*/ +void idAsyncServer::ProcessAuthMessage( const idBitMsg &msg ) { + netadr_t client_from; + char client_guid[ 12 ], string[ MAX_STRING_CHARS ]; + int i, clientId; + authReply_t reply; + authReplyMsg_t replyMsg = AUTH_REPLY_WAITING; + idStr replyPrintMsg; + + reply = (authReply_t)msg.ReadByte(); + if ( reply <= 0 || reply >= AUTH_MAXSTATES ) { + common->DPrintf( "auth: invalid reply %d\n", reply ); + return; + } + clientId = msg.ReadShort( ); + msg.ReadNetadr( &client_from ); + msg.ReadString( client_guid, sizeof( client_guid ) ); + if ( reply != AUTH_OK ) { + replyMsg = (authReplyMsg_t)msg.ReadByte(); + if ( replyMsg <= 0 || replyMsg >= AUTH_REPLY_MAXSTATES ) { + common->DPrintf( "auth: invalid reply msg %d\n", replyMsg ); + return; + } + if ( replyMsg == AUTH_REPLY_PRINT ) { + msg.ReadString( string, MAX_STRING_CHARS ); + replyPrintMsg = string; + } + } + + lastAuthTime = serverTime; + + // no message parsing below + + for ( i = 0; i < MAX_CHALLENGES; i++ ) { + if ( !challenges[i].connected && challenges[ i ].clientId == clientId ) { + // return if something is wrong + // break if we have found a valid auth + if ( !strlen( challenges[ i ].guid ) ) { + common->DPrintf( "auth: client %s has no guid yet\n", Sys_NetAdrToString( challenges[ i ].address ) ); + return; + } + if ( idStr::Cmp( challenges[ i ].guid, client_guid ) ) { + common->DPrintf( "auth: client %s %s not matched, auth server says guid %s\n", Sys_NetAdrToString( challenges[ i ].address ), challenges[i].guid, client_guid ); + return; + } + if ( !Sys_CompareNetAdrBase( client_from, challenges[i].address ) ) { + // let auth work when server and master don't see the same IP + common->DPrintf( "auth: matched guid '%s' for != IPs %s and %s\n", client_guid, Sys_NetAdrToString( client_from ), Sys_NetAdrToString( challenges[i].address ) ); + } + break; + } + } + if ( i >= MAX_CHALLENGES ) { + common->DPrintf( "auth: failed client lookup %s %s\n", Sys_NetAdrToString( client_from ), client_guid ); + return; + } + + if ( challenges[ i ].authState != CDK_WAIT ) { + common->DWarning( "auth: challenge 0x%x %s authState %d != CDK_WAIT", challenges[ i ].challenge, Sys_NetAdrToString( challenges[ i ].address ), challenges[ i ].authState ); + return; + } + + idStr::snPrintf( challenges[ i ].guid, 12, client_guid ); + if ( reply == AUTH_OK ) { + challenges[ i ].authState = CDK_OK; + common->Printf( "client %s %s is authed\n", Sys_NetAdrToString( client_from ), client_guid ); + } else { + const char *msg; + if ( replyMsg != AUTH_REPLY_PRINT ) { + msg = authReplyMsg[ replyMsg ]; + } else { + msg = replyPrintMsg.c_str(); + } + // maybe localize it + const char *l_msg = common->GetLanguageDict()->GetString( msg ); + common->DPrintf( "auth: client %s %s - %s %s\n", Sys_NetAdrToString( client_from ), client_guid, authReplyStr[ reply ], l_msg ); + challenges[ i ].authReply = reply; + challenges[ i ].authReplyMsg = replyMsg; + challenges[ i ].authReplyPrint = replyPrintMsg; + } +} + +/* +================== +idAsyncServer::ProcessChallengeMessage +================== +*/ +void idAsyncServer::ProcessChallengeMessage( const netadr_t from, const idBitMsg &msg ) { + int i, clientId, oldest, oldestTime; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + clientId = msg.ReadLong(); + + oldest = 0; + oldestTime = 0x7fffffff; + + // see if we already have a challenge for this ip + for ( i = 0; i < MAX_CHALLENGES; i++ ) { + if ( !challenges[i].connected && Sys_CompareNetAdrBase( from, challenges[i].address ) && clientId == challenges[i].clientId ) { + break; + } + if ( challenges[i].time < oldestTime ) { + oldestTime = challenges[i].time; + oldest = i; + } + } + + if ( i >= MAX_CHALLENGES ) { + // this is the first time this client has asked for a challenge + i = oldest; + challenges[i].address = from; + challenges[i].clientId = clientId; + challenges[i].challenge = ( (rand() << 16) ^ rand() ) ^ serverTime; + challenges[i].time = serverTime; + challenges[i].connected = false; + challenges[i].authState = CDK_WAIT; + challenges[i].authReply = AUTH_NONE; + challenges[i].authReplyMsg = AUTH_REPLY_WAITING; + challenges[i].authReplyPrint = ""; + challenges[i].guid[0] = '\0'; + } + challenges[i].pingTime = serverTime; + + common->Printf( "sending challenge 0x%x to %s\n", challenges[i].challenge, Sys_NetAdrToString( from ) ); + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "challengeResponse" ); + outMsg.WriteLong( challenges[i].challenge ); + outMsg.WriteShort( serverId ); + outMsg.WriteString( cvarSystem->GetCVarString( "fs_game_base" ) ); + outMsg.WriteString( cvarSystem->GetCVarString( "fs_game" ) ); + + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + + if ( Sys_IsLANAddress( from ) ) { + // no CD Key check for LAN clients + challenges[i].authState = CDK_OK; + } else { + if ( idAsyncNetwork::LANServer.GetBool() ) { + common->Printf( "net_LANServer is enabled. Client %s is not a LAN address, will be rejected\n", Sys_NetAdrToString( from ) ); + challenges[ i ].authState = CDK_ONLYLAN; + } else { + // emit a cd key confirmation request + outMsg.BeginWriting(); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "srvAuth" ); + outMsg.WriteLong( ASYNC_PROTOCOL_VERSION ); + outMsg.WriteNetadr( from ); + outMsg.WriteLong( -1 ); // this identifies "challenge" auth vs "connect" auth + // protocol 1.37 addition + outMsg.WriteByte( fileSystem->RunningD3XP() ); + serverPort.SendPacket( idAsyncNetwork::GetMasterAddress(), outMsg.GetData(), outMsg.GetSize() ); + } + } +} + +/* +================== +idAsyncServer::SendPureServerMessage +================== +*/ +bool idAsyncServer::SendPureServerMessage( const netadr_t to, int OS ) { + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + int serverChecksums[ MAX_PURE_PAKS ]; + int gamePakChecksum; + int i; + + fileSystem->GetPureServerChecksums( serverChecksums, OS, &gamePakChecksum ); + if ( !serverChecksums[ 0 ] ) { + // happens if you run fully expanded assets with si_pure 1 + common->Warning( "pure server has no pak files referenced" ); + return false; + } + common->DPrintf( "client %s: sending pure pak list\n", Sys_NetAdrToString( to ) ); + + // send our list of required paks + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "pureServer" ); + + i = 0; + while ( serverChecksums[ i ] ) { + outMsg.WriteLong( serverChecksums[ i++ ] ); + } + outMsg.WriteLong( 0 ); + + // write the pak checksum for game code + outMsg.WriteLong( gamePakChecksum ); + + serverPort.SendPacket( to, outMsg.GetData(), outMsg.GetSize() ); + return true; +} + +/* +================== +idAsyncServer::SendReliablePureToClient +================== +*/ +bool idAsyncServer::SendReliablePureToClient( int clientNum ) { + idBitMsg msg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + int serverChecksums[ MAX_PURE_PAKS ]; + int i; + int gamePakChecksum; + + fileSystem->GetPureServerChecksums( serverChecksums, clients[ clientNum ].OS, &gamePakChecksum ); + if ( !serverChecksums[ 0 ] ) { + // happens if you run fully expanded assets with si_pure 1 + common->Warning( "pure server has no pak files referenced" ); + return false; + } + + common->DPrintf( "client %d: sending pure pak list (reliable channel) @ gameInitId %d\n", clientNum, gameInitId ); + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_PURE ); + + msg.WriteLong( gameInitId ); + + i = 0; + while ( serverChecksums[ i ] ) { + msg.WriteLong( serverChecksums[ i++ ] ); + } + msg.WriteLong( 0 ); + msg.WriteLong( gamePakChecksum ); + + SendReliableMessage( clientNum, msg ); + + return true; +} + +/* +================== +idAsyncServer::ValidateChallenge +================== +*/ +int idAsyncServer::ValidateChallenge( const netadr_t from, int challenge, int clientId ) { + int i; + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + const serverClient_t &client = clients[i]; + + if ( client.clientState == SCS_FREE ) { + continue; + } + if ( Sys_CompareNetAdrBase( from, client.channel.GetRemoteAddress() ) && + ( clientId == client.clientId || from.port == client.channel.GetRemoteAddress().port ) ) { + if ( serverTime - client.lastConnectTime < MIN_RECONNECT_TIME ) { + common->Printf( "%s: reconnect rejected : too soon\n", Sys_NetAdrToString( from ) ); + return -1; + } + break; + } + } + + for ( i = 0; i < MAX_CHALLENGES; i++ ) { + if ( Sys_CompareNetAdrBase( from, challenges[i].address ) && from.port == challenges[i].address.port ) { + if ( challenge == challenges[i].challenge ) { + break; + } + } + } + if ( i == MAX_CHALLENGES ) { + PrintOOB( from, SERVER_PRINT_BADCHALLENGE, "#str_04840" ); + return -1; + } + return i; +} + +/* +================== +idAsyncServer::ProcessConnectMessage +================== +*/ +void idAsyncServer::ProcessConnectMessage( const netadr_t from, const idBitMsg &msg ) { + int clientNum, protocol, clientDataChecksum, challenge, clientId, ping, clientRate; + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + char guid[ 12 ]; + char password[ 17 ]; + int i, ichallenge, islot, OS, numClients; + + protocol = msg.ReadLong(); + OS = msg.ReadShort(); + + // check the protocol version + if ( protocol != ASYNC_PROTOCOL_VERSION ) { + // that's a msg back to a client, we don't know about it's localization, so send english + PrintOOB( from, SERVER_PRINT_BADPROTOCOL, va( "server uses protocol %d.%d\n", ASYNC_PROTOCOL_MAJOR, ASYNC_PROTOCOL_MINOR ) ); + return; + } + + clientDataChecksum = msg.ReadLong(); + challenge = msg.ReadLong(); + clientId = msg.ReadShort(); + clientRate = msg.ReadLong(); + + // check the client data - only for non pure servers + if ( !sessLocal.mapSpawnData.serverInfo.GetInt( "si_pure" ) && clientDataChecksum != serverDataChecksum ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04842" ); + return; + } + + if ( ( ichallenge = ValidateChallenge( from, challenge, clientId ) ) == -1 ) { + return; + } + challenges[ ichallenge ].OS = OS; + + msg.ReadString( guid, sizeof( guid ) ); + + switch ( challenges[ ichallenge ].authState ) { + case CDK_PUREWAIT: + SendPureServerMessage( from, OS ); + return; + case CDK_ONLYLAN: + common->DPrintf( "%s: not a lan client\n", Sys_NetAdrToString( from ) ); + PrintOOB( from, SERVER_PRINT_MISC, "#str_04843" ); + return; + case CDK_WAIT: + if ( challenges[ ichallenge ].authReply == AUTH_NONE && Min( serverTime - lastAuthTime, serverTime - challenges[ ichallenge ].time ) > AUTHORIZE_TIMEOUT ) { + common->DPrintf( "%s: Authorize server timed out\n", Sys_NetAdrToString( from ) ); + break; // will continue with the connecting process + } + const char *msg, *l_msg; + if ( challenges[ ichallenge ].authReplyMsg != AUTH_REPLY_PRINT ) { + msg = authReplyMsg[ challenges[ ichallenge ].authReplyMsg ]; + } else { + msg = challenges[ ichallenge ].authReplyPrint.c_str(); + } + l_msg = common->GetLanguageDict()->GetString( msg ); + + common->DPrintf( "%s: %s\n", Sys_NetAdrToString( from ), l_msg ); + + if ( challenges[ ichallenge ].authReplyMsg == AUTH_REPLY_UNKNOWN || challenges[ ichallenge ].authReplyMsg == AUTH_REPLY_WAITING ) { + // the client may be trying to connect to us in LAN mode, and the server disagrees + // let the client know so it would switch to authed connection + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "authrequired" ); + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + } + + PrintOOB( from, SERVER_PRINT_MISC, msg ); + + // update the guid in the challenges + idStr::snPrintf( challenges[ ichallenge ].guid, sizeof( challenges[ ichallenge ].guid ), guid ); + + // once auth replied denied, stop sending further requests + if ( challenges[ ichallenge ].authReply != AUTH_DENY ) { + // emit a cd key confirmation request + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "srvAuth" ); + outMsg.WriteLong( ASYNC_PROTOCOL_VERSION ); + outMsg.WriteNetadr( from ); + outMsg.WriteLong( clientId ); + outMsg.WriteString( guid ); + // protocol 1.37 addition + outMsg.WriteByte( fileSystem->RunningD3XP() ); + serverPort.SendPacket( idAsyncNetwork::GetMasterAddress(), outMsg.GetData(), outMsg.GetSize() ); + } + return; + default: + assert( challenges[ ichallenge ].authState == CDK_OK || challenges[ ichallenge ].authState == CDK_PUREOK ); + } + + numClients = 0; + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[ i ]; + if ( client.clientState >= SCS_PUREWAIT ) { + numClients++; + } + } + + // game may be passworded, client banned by IP or GUID + // if authState == CDK_PUREOK, the check was already performed once before entering pure checks + // but meanwhile, the max players may have been reached + msg.ReadString( password, sizeof( password ) ); + char reason[MAX_STRING_CHARS]; + allowReply_t reply = game->ServerAllowClient( numClients, Sys_NetAdrToString( from ), guid, password, reason ); + if ( reply != ALLOW_YES ) { + common->DPrintf( "game denied connection for %s\n", Sys_NetAdrToString( from ) ); + + // SERVER_PRINT_GAMEDENY passes the game opcode through. Don't use PrintOOB + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "print" ); + outMsg.WriteLong( SERVER_PRINT_GAMEDENY ); + outMsg.WriteLong( reply ); + outMsg.WriteString( reason ); + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + + return; + } + + // enter pure checks if necessary + if ( sessLocal.mapSpawnData.serverInfo.GetInt( "si_pure" ) && challenges[ ichallenge ].authState != CDK_PUREOK ) { + if ( SendPureServerMessage( from, OS ) ) { + challenges[ ichallenge ].authState = CDK_PUREWAIT; + return; + } + } + + // push back decl checksum here when running pure. just an additional safe check + if ( sessLocal.mapSpawnData.serverInfo.GetInt( "si_pure" ) && clientDataChecksum != serverDataChecksum ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04844" ); + return; + } + + ping = serverTime - challenges[ ichallenge ].pingTime; + common->Printf( "challenge from %s connecting with %d ping\n", Sys_NetAdrToString( from ), ping ); + challenges[ ichallenge ].connected = true; + + // find a slot for the client + for ( islot = 0; islot < 3; islot++ ) { + for ( clientNum = 0; clientNum < MAX_ASYNC_CLIENTS; clientNum++ ) { + serverClient_t &client = clients[ clientNum ]; + + if ( islot == 0 ) { + // if this slot uses the same IP and port + if ( Sys_CompareNetAdrBase( from, client.channel.GetRemoteAddress() ) && + ( clientId == client.clientId || from.port == client.channel.GetRemoteAddress().port ) ) { + break; + } + } else if ( islot == 1 ) { + // if this client is not connected and the slot uses the same IP + if ( client.clientState >= SCS_PUREWAIT ) { + continue; + } + if ( Sys_CompareNetAdrBase( from, client.channel.GetRemoteAddress() ) ) { + break; + } + } else if ( islot == 2 ) { + // if this slot is free + if ( client.clientState == SCS_FREE ) { + break; + } + } + } + + if ( clientNum < MAX_ASYNC_CLIENTS ) { + // initialize + clients[ clientNum ].channel.Init( from, serverId ); + clients[ clientNum ].OS = OS; + strncpy( clients[ clientNum ].guid, guid, 12 ); + clients[ clientNum ].guid[11] = 0; + break; + } + } + + // if no free spots available + if ( clientNum >= MAX_ASYNC_CLIENTS ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04845" ); + return; + } + + common->Printf( "sending connect response to %s\n", Sys_NetAdrToString( from ) ); + + // send connect response message + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "connectResponse" ); + outMsg.WriteLong( clientNum ); + outMsg.WriteLong( gameInitId ); + outMsg.WriteLong( gameFrame ); + outMsg.WriteLong( gameTime ); + outMsg.WriteDeltaDict( sessLocal.mapSpawnData.serverInfo, NULL ); + + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + + InitClient( clientNum, clientId, clientRate ); + + clients[clientNum].gameInitSequence = 1; + clients[clientNum].snapshotSequence = 1; + + // clear the challenge struct so a reconnect from this client IP starts clean + memset( &challenges[ ichallenge ], 0, sizeof( challenge_t ) ); +} + +/* +================== +idAsyncServer::VerifyChecksumMessage +================== +*/ +bool idAsyncServer::VerifyChecksumMessage( int clientNum, const netadr_t *from, const idBitMsg &msg, idStr &reply, int OS ) { + int i, numChecksums; + int checksums[ MAX_PURE_PAKS ]; + int gamePakChecksum; + int serverChecksums[ MAX_PURE_PAKS ]; + int serverGamePakChecksum; + + // pak checksums, in a 0-terminated list + numChecksums = 0; + do { + i = msg.ReadLong( ); + checksums[ numChecksums++ ] = i; + // just to make sure a broken client doesn't crash us + if ( numChecksums >= MAX_PURE_PAKS ) { + common->Warning( "MAX_PURE_PAKS ( %d ) exceeded in idAsyncServer::ProcessPureMessage\n", MAX_PURE_PAKS ); + sprintf( reply, "#str_07144" ); + return false; + } + } while ( i ); + numChecksums--; + + // code pak checksum + gamePakChecksum = msg.ReadLong( ); + + fileSystem->GetPureServerChecksums( serverChecksums, OS, &serverGamePakChecksum ); + assert( serverChecksums[ 0 ] ); + + // compare the lists + if ( serverGamePakChecksum != gamePakChecksum ) { + common->Printf( "client %s: invalid game code pak ( 0x%x )\n", from ? Sys_NetAdrToString( *from ) : va( "%d", clientNum ), gamePakChecksum ); + sprintf( reply, "#str_07145" ); + return false; + } + for ( i = 0; serverChecksums[ i ] != 0; i++ ) { + if ( checksums[ i ] != serverChecksums[ i ] ) { + common->DPrintf( "client %s: pak missing ( 0x%x )\n", from ? Sys_NetAdrToString( *from ) : va( "%d", clientNum ), serverChecksums[ i ] ); + sprintf( reply, "pak missing ( 0x%x )\n", serverChecksums[ i ] ); + return false; + } + } + if ( checksums[ i ] != 0 ) { + common->DPrintf( "client %s: extra pak file referenced ( 0x%x )\n", from ? Sys_NetAdrToString( *from ) : va( "%d", clientNum ), checksums[ i ] ); + sprintf( reply, "extra pak file referenced ( 0x%x )\n", checksums[ i ] ); + return false; + } + return true; +} + +/* +================== +idAsyncServer::ProcessPureMessage +================== +*/ +void idAsyncServer::ProcessPureMessage( const netadr_t from, const idBitMsg &msg ) { + int iclient, challenge, clientId; + idStr reply; + + challenge = msg.ReadLong(); + clientId = msg.ReadShort(); + + if ( ( iclient = ValidateChallenge( from, challenge, clientId ) ) == -1 ) { + return; + } + + if ( challenges[ iclient ].authState != CDK_PUREWAIT ) { + common->DPrintf( "client %s: got pure message, not in CDK_PUREWAIT\n", Sys_NetAdrToString( from ) ); + return; + } + + if ( !VerifyChecksumMessage( iclient, &from, msg, reply, challenges[ iclient ].OS ) ) { + PrintOOB( from, SERVER_PRINT_MISC, reply ); + return; + } + + common->DPrintf( "client %s: passed pure checks\n", Sys_NetAdrToString( from ) ); + challenges[ iclient ].authState = CDK_PUREOK; // next connect message will get the client through completely +} + +/* +================== +idAsyncServer::ProcessReliablePure +================== +*/ +void idAsyncServer::ProcessReliablePure( int clientNum, const idBitMsg &msg ) { + idStr reply; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + int clientGameInitId; + + clientGameInitId = msg.ReadLong(); + if ( clientGameInitId != gameInitId ) { + common->DPrintf( "client %d: ignoring reliable pure from an old gameInit (%d)\n", clientNum, clientGameInitId ); + return; + } + + if ( clients[ clientNum ].clientState != SCS_PUREWAIT ) { + // should not happen unless something is very wrong. still, don't let this crash us, just get rid of the client + common->DPrintf( "client %d: got reliable pure while != SCS_PUREWAIT, sending a reload\n", clientNum ); + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( SERVER_RELIABLE_MESSAGE_RELOAD ); + SendReliableMessage( clientNum, msg ); + // go back to SCS_CONNECTED to sleep on the client until it goes away for a reconnect + clients[ clientNum ].clientState = SCS_CONNECTED; + return; + } + + if ( !VerifyChecksumMessage( clientNum, NULL, msg, reply, clients[ clientNum ].OS ) ) { + DropClient( clientNum, reply ); + return; + } + common->DPrintf( "client %d: passed pure checks (reliable channel)\n", clientNum ); + clients[ clientNum ].clientState = SCS_CONNECTED; +} + +/* +================== +idAsyncServer::RemoteConsoleOutput +================== +*/ +void idAsyncServer::RemoteConsoleOutput( const char *string ) { + noRconOutput = false; + PrintOOB( rconAddress, SERVER_PRINT_RCON, string ); +} + +/* +================== +RConRedirect +================== +*/ +void RConRedirect( const char *string ) { + idAsyncNetwork::server.RemoteConsoleOutput( string ); +} + +/* +================== +idAsyncServer::ProcessRemoteConsoleMessage +================== +*/ +void idAsyncServer::ProcessRemoteConsoleMessage( const netadr_t from, const idBitMsg &msg ) { + idBitMsg outMsg; + byte msgBuf[952]; + char string[MAX_STRING_CHARS]; + + if ( idAsyncNetwork::serverRemoteConsolePassword.GetString()[0] == '\0' ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04846" ); + return; + } + + msg.ReadString( string, sizeof( string ) ); + + if ( idStr::Icmp( string, idAsyncNetwork::serverRemoteConsolePassword.GetString() ) != 0 ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04847" ); + return; + } + + msg.ReadString( string, sizeof( string ) ); + + common->Printf( "rcon from %s: %s\n", Sys_NetAdrToString( from ), string ); + + rconAddress = from; + noRconOutput = true; + common->BeginRedirect( (char *)msgBuf, sizeof( msgBuf ), RConRedirect ); + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, string ); + + common->EndRedirect(); + + if ( noRconOutput ) { + PrintOOB( rconAddress, SERVER_PRINT_RCON, "#str_04848" ); + } +} + +/* +================== +idAsyncServer::ProcessGetInfoMessage +================== +*/ +void idAsyncServer::ProcessGetInfoMessage( const netadr_t from, const idBitMsg &msg ) { + int i, challenge; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + if ( !IsActive() ) { + return; + } + + common->DPrintf( "Sending info response to %s\n", Sys_NetAdrToString( from ) ); + + challenge = msg.ReadLong(); + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "infoResponse" ); + outMsg.WriteLong( challenge ); + outMsg.WriteLong( ASYNC_PROTOCOL_VERSION ); + outMsg.WriteDeltaDict( sessLocal.mapSpawnData.serverInfo, NULL ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + + if ( client.clientState < SCS_CONNECTED ) { + continue; + } + + outMsg.WriteByte( i ); + outMsg.WriteShort( client.clientPing ); + outMsg.WriteLong( client.channel.GetMaxOutgoingRate() ); + outMsg.WriteString( sessLocal.mapSpawnData.userInfo[i].GetString( "ui_name", "Player" ) ); + } + outMsg.WriteByte( MAX_ASYNC_CLIENTS ); + outMsg.WriteLong( fileSystem->GetOSMask() ); + + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); +} + +/* +=============== +idAsyncServer::PrintLocalServerInfo +see (client) "getInfo" -> (server) "infoResponse" -> (client)ProcessGetInfoMessage +=============== +*/ +void idAsyncServer::PrintLocalServerInfo( void ) { + int i; + + common->Printf( "server '%s' IP = %s\nprotocol %d.%d OS mask 0x%x\n", + sessLocal.mapSpawnData.serverInfo.GetString( "si_name" ), + Sys_NetAdrToString( serverPort.GetAdr() ), + ASYNC_PROTOCOL_MAJOR, + ASYNC_PROTOCOL_MINOR, + fileSystem->GetOSMask() ); + sessLocal.mapSpawnData.serverInfo.Print(); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + if ( client.clientState < SCS_CONNECTED ) { + continue; + } + common->Printf( "client %2d: %s, ping = %d, rate = %d\n", i, + sessLocal.mapSpawnData.userInfo[i].GetString( "ui_name", "Player" ), + client.clientPing, client.channel.GetMaxOutgoingRate() ); + } +} + +/* +================== +idAsyncServer::ConnectionlessMessage +================== +*/ +bool idAsyncServer::ConnectionlessMessage( const netadr_t from, const idBitMsg &msg ) { + char string[MAX_STRING_CHARS*2]; // M. Quinn - Even Balance - PB Packets need more than 1024 + + msg.ReadString( string, sizeof( string ) ); + + // info request + if ( idStr::Icmp( string, "getInfo" ) == 0 ) { + ProcessGetInfoMessage( from, msg ); + return false; + } + + // remote console + if ( idStr::Icmp( string, "rcon" ) == 0 ) { + ProcessRemoteConsoleMessage( from, msg ); + return true; + } + + if ( !active ) { + PrintOOB( from, SERVER_PRINT_MISC, "#str_04849" ); + return false; + } + + // challenge from a client + if ( idStr::Icmp( string, "challenge" ) == 0 ) { + ProcessChallengeMessage( from, msg ); + return false; + } + + // connect from a client + if ( idStr::Icmp( string, "connect" ) == 0 ) { + ProcessConnectMessage( from, msg ); + return false; + } + + // pure mesasge from a client + if ( idStr::Icmp( string, "pureClient" ) == 0 ) { + ProcessPureMessage( from, msg ); + return false; + } + + // download request + if ( idStr::Icmp( string, "downloadRequest" ) == 0 ) { + ProcessDownloadRequestMessage( from, msg ); + } + + // auth server + if ( idStr::Icmp( string, "auth" ) == 0 ) { + if ( !Sys_CompareNetAdrBase( from, idAsyncNetwork::GetMasterAddress() ) ) { + common->Printf( "auth: bad source %s\n", Sys_NetAdrToString( from ) ); + return false; + } + if ( idAsyncNetwork::LANServer.GetBool() ) { + common->Printf( "auth message from master. net_LANServer is enabled, ignored.\n" ); + } + ProcessAuthMessage( msg ); + return false; + } + + return false; +} + +/* +================== +idAsyncServer::ProcessMessage +================== +*/ +bool idAsyncServer::ProcessMessage( const netadr_t from, idBitMsg &msg ) { + int i, id, sequence; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + id = msg.ReadShort(); + + // check for a connectionless message + if ( id == CONNECTIONLESS_MESSAGE_ID ) { + return ConnectionlessMessage( from, msg ); + } + + if ( msg.GetRemaingData() < 4 ) { + common->DPrintf( "%s: tiny packet\n", Sys_NetAdrToString( from ) ); + return false; + } + + // find out which client the message is from + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + + if ( client.clientState == SCS_FREE ) { + continue; + } + + // This does not compare the UDP port, because some address translating + // routers will change that at arbitrary times. + if ( !Sys_CompareNetAdrBase( from, client.channel.GetRemoteAddress() ) || id != client.clientId ) { + continue; + } + + // make sure it is a valid, in sequence packet + if ( !client.channel.Process( from, serverTime, msg, sequence ) ) { + return false; // out of order, duplicated, fragment, etc. + } + + // zombie clients still need to do the channel processing to make sure they don't + // need to retransmit the final reliable message, but they don't do any other processing + if ( client.clientState == SCS_ZOMBIE ) { + return false; + } + + client.lastPacketTime = serverTime; + + ProcessReliableClientMessages( i ); + ProcessUnreliableClientMessage( i, msg ); + + return false; + } + + // if we received a sequenced packet from an address we don't recognize, + // send an out of band disconnect packet to it + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "disconnect" ); + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + + return false; +} + +/* +================== +idAsyncServer::SendReliableGameMessage +================== +*/ +void idAsyncServer::SendReliableGameMessage( int clientNum, const idBitMsg &msg ) { + int i; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( SERVER_RELIABLE_MESSAGE_GAME ); + outMsg.WriteData( msg.GetData(), msg.GetSize() ); + + if ( clientNum >= 0 && clientNum < MAX_ASYNC_CLIENTS ) { + if ( clients[clientNum].clientState == SCS_INGAME ) { + SendReliableMessage( clientNum, outMsg ); + } + return; + } + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState != SCS_INGAME ) { + continue; + } + SendReliableMessage( i, outMsg ); + } +} + +/* +================== +idAsyncServer::LocalClientSendReliableMessageExcluding +================== +*/ +void idAsyncServer::SendReliableGameMessageExcluding( int clientNum, const idBitMsg &msg ) { + int i; + idBitMsg outMsg; + byte msgBuf[MAX_MESSAGE_SIZE]; + + assert( clientNum >= 0 && clientNum < MAX_ASYNC_CLIENTS ); + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( SERVER_RELIABLE_MESSAGE_GAME ); + outMsg.WriteData( msg.GetData(), msg.GetSize() ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( i == clientNum ) { + continue; + } + if ( clients[i].clientState != SCS_INGAME ) { + continue; + } + SendReliableMessage( i, outMsg ); + } +} + +/* +================== +idAsyncServer::LocalClientSendReliableMessage +================== +*/ +void idAsyncServer::LocalClientSendReliableMessage( const idBitMsg &msg ) { + if ( localClientNum < 0 ) { + common->Printf( "LocalClientSendReliableMessage: no local client\n" ); + return; + } + game->ServerProcessReliableMessage( localClientNum, msg ); +} + +/* +================== +idAsyncServer::ProcessConnectionLessMessages +================== +*/ +void idAsyncServer::ProcessConnectionLessMessages( void ) { + int size, id; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t from; + + if ( !serverPort.GetPort() ) { + return; + } + + while( serverPort.GetPacket( from, msgBuf, size, sizeof( msgBuf ) ) ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.SetSize( size ); + msg.BeginReading(); + id = msg.ReadShort(); + if ( id == CONNECTIONLESS_MESSAGE_ID ) { + ConnectionlessMessage( from, msg ); + } + } +} + +/* +================== +idAsyncServer::UpdateTime +================== +*/ +int idAsyncServer::UpdateTime( int clamp ) { + int time, msec; + + time = Sys_Milliseconds(); + msec = idMath::ClampInt( 0, clamp, time - realTime ); + realTime = time; + serverTime += msec; + return msec; +} + +/* +================== +idAsyncServer::RunFrame +================== +*/ +void idAsyncServer::RunFrame( void ) { + int i, msec, size; + bool newPacket; + idBitMsg msg; + byte msgBuf[MAX_MESSAGE_SIZE]; + netadr_t from; + int outgoingRate, incomingRate; + float outgoingCompression, incomingCompression; + + msec = UpdateTime( 100 ); + + if ( !serverPort.GetPort() ) { + return; + } + + if ( !active ) { + ProcessConnectionLessMessages(); + return; + } + + gameTimeResidual += msec; + + // spin in place processing incoming packets until enough time lapsed to run a new game frame + do { + + do { + + // blocking read with game time residual timeout + newPacket = serverPort.GetPacketBlocking( from, msgBuf, size, sizeof( msgBuf ), USERCMD_MSEC - gameTimeResidual - 1 ); + if ( newPacket ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.SetSize( size ); + msg.BeginReading(); + if ( ProcessMessage( from, msg ) ) { + return; // return because rcon was used + } + } + + msec = UpdateTime( 100 ); + gameTimeResidual += msec; + + } while( newPacket ); + + } while( gameTimeResidual < USERCMD_MSEC ); + + // send heart beat to master servers + MasterHeartbeat(); + + // check for clients that timed out + CheckClientTimeouts(); + + if ( idAsyncNetwork::idleServer.GetBool() == ( !GetNumClients() || GetNumIdleClients() != GetNumClients() ) ) { + idAsyncNetwork::idleServer.SetBool( !idAsyncNetwork::idleServer.GetBool() ); + // the need to propagate right away, only this + sessLocal.mapSpawnData.serverInfo.Set( "si_idleServer", idAsyncNetwork::idleServer.GetString() ); + game->SetServerInfo( sessLocal.mapSpawnData.serverInfo ); + } + + // make sure the time doesn't wrap + if ( serverTime > 0x70000000 ) { + ExecuteMapChange(); + return; + } + + // check for synchronized cvar changes + if ( cvarSystem->GetModifiedFlags() & CVAR_NETWORKSYNC ) { + idDict newCvars; + newCvars = *cvarSystem->MoveCVarsToDict( CVAR_NETWORKSYNC ); + SendSyncedCvarsBroadcast( newCvars ); + cvarSystem->ClearModifiedFlags( CVAR_NETWORKSYNC ); + } + + // check for user info changes of the local client + if ( cvarSystem->GetModifiedFlags() & CVAR_USERINFO ) { + if ( localClientNum >= 0 ) { + idDict newInfo; + game->ThrottleUserInfo( ); + newInfo = *cvarSystem->MoveCVarsToDict( CVAR_USERINFO ); + SendUserInfoBroadcast( localClientNum, newInfo ); + } + cvarSystem->ClearModifiedFlags( CVAR_USERINFO ); + } + + // advance the server game + while( gameTimeResidual >= USERCMD_MSEC ) { + + // sample input for the local client + LocalClientInput(); + + // duplicate usercmds for clients if no new ones are available + DuplicateUsercmds( gameFrame, gameTime ); + + // advance game + gameReturn_t ret = game->RunFrame( userCmds[gameFrame & ( MAX_USERCMD_BACKUP - 1 ) ] ); + + idAsyncNetwork::ExecuteSessionCommand( ret.sessionCommand ); + + // update time + gameFrame++; + gameTime += USERCMD_MSEC; + gameTimeResidual -= USERCMD_MSEC; + } + + // duplicate usercmds so there is always at least one available to send with snapshots + DuplicateUsercmds( gameFrame, gameTime ); + + // send snapshots to connected clients + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + serverClient_t &client = clients[i]; + + if ( client.clientState == SCS_FREE || i == localClientNum ) { + continue; + } + + // modify maximum rate if necesary + if ( idAsyncNetwork::serverMaxClientRate.IsModified() ) { + client.channel.SetMaxOutgoingRate( Min( client.clientRate, idAsyncNetwork::serverMaxClientRate.GetInteger() ) ); + } + + // if the channel is not yet ready to send new data + if ( !client.channel.ReadyToSend( serverTime ) ) { + continue; + } + + // send additional message fragments if the last message was too large to send at once + if ( client.channel.UnsentFragmentsLeft() ) { + client.channel.SendNextFragment( serverPort, serverTime ); + continue; + } + + if ( client.clientState == SCS_INGAME ) { + if ( !SendSnapshotToClient( i ) ) { + SendPingToClient( i ); + } + } else { + SendEmptyToClient( i ); + } + } + + if ( com_showAsyncStats.GetBool() ) { + + UpdateAsyncStatsAvg(); + + // dedicated will verbose to console + if ( idAsyncNetwork::serverDedicated.GetBool() && serverTime >= nextAsyncStatsTime ) { + common->Printf( "delay = %d msec, total outgoing rate = %d KB/s, total incoming rate = %d KB/s\n", GetDelay(), + GetOutgoingRate() >> 10, GetIncomingRate() >> 10 ); + + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + + outgoingRate = GetClientOutgoingRate( i ); + incomingRate = GetClientIncomingRate( i ); + outgoingCompression = GetClientOutgoingCompression( i ); + incomingCompression = GetClientIncomingCompression( i ); + + if ( outgoingRate != -1 && incomingRate != -1 ) { + common->Printf( "client %d: out rate = %d B/s (% -2.1f%%), in rate = %d B/s (% -2.1f%%)\n", + i, outgoingRate, outgoingCompression, incomingRate, incomingCompression ); + } + } + + idStr msg; + GetAsyncStatsAvgMsg( msg ); + common->Printf( va( "%s\n", msg.c_str() ) ); + + nextAsyncStatsTime = serverTime + 1000; + } + } + + idAsyncNetwork::serverMaxClientRate.ClearModified(); +} + +/* +================== +idAsyncServer::PacifierUpdate +================== +*/ +void idAsyncServer::PacifierUpdate( void ) { + int i; + + if ( !IsActive() ) { + return; + } + realTime = Sys_Milliseconds(); + ProcessConnectionLessMessages(); + for ( i = 0; i < MAX_ASYNC_CLIENTS; i++ ) { + if ( clients[i].clientState >= SCS_PUREWAIT ) { + if ( clients[i].channel.UnsentFragmentsLeft() ) { + clients[i].channel.SendNextFragment( serverPort, serverTime ); + } else { + SendEmptyToClient( i ); + } + } + } +} + +/* +================== +idAsyncServer::PrintOOB +================== +*/ +void idAsyncServer::PrintOOB( const netadr_t to, int opcode, const char *string ) { + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "print" ); + outMsg.WriteLong( opcode ); + outMsg.WriteString( string ); + serverPort.SendPacket( to, outMsg.GetData(), outMsg.GetSize() ); +} + +/* +================== +idAsyncServer::MasterHeartbeat +================== +*/ +void idAsyncServer::MasterHeartbeat( bool force ) { + if ( idAsyncNetwork::LANServer.GetBool() ) { + if ( force ) { + common->Printf( "net_LANServer is enabled. Not sending heartbeats\n" ); + } + return; + } + if ( force ) { + nextHeartbeatTime = 0; + } + // not yet + if ( serverTime < nextHeartbeatTime ) { + return; + } + nextHeartbeatTime = serverTime + HEARTBEAT_MSEC; + for ( int i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) { + netadr_t adr; + if ( idAsyncNetwork::GetMasterAddress( i, adr ) ) { + common->Printf( "Sending heartbeat to %s\n", Sys_NetAdrToString( adr ) ); + idBitMsg outMsg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "heartbeat" ); + serverPort.SendPacket( adr, outMsg.GetData(), outMsg.GetSize() ); + } + } +} + +/* +=============== +idAsyncServer::SendEnterGameToClient +=============== +*/ +void idAsyncServer::SendEnterGameToClient( int clientNum ) { + idBitMsg msg; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( SERVER_RELIABLE_MESSAGE_ENTERGAME ); + SendReliableMessage( clientNum, msg ); +} + +/* +=============== +idAsyncServer::UpdateAsyncStatsAvg +=============== +*/ +void idAsyncServer::UpdateAsyncStatsAvg( void ) { + stats_average_sum -= stats_outrate[ stats_current ]; + stats_outrate[ stats_current ] = idAsyncNetwork::server.GetOutgoingRate(); + if ( stats_outrate[ stats_current ] > stats_max ) { + stats_max = stats_outrate[ stats_current ]; + stats_max_index = stats_current; + } else if ( stats_current == stats_max_index ) { + // find the new max + int i; + stats_max = 0; + for ( i = 0; i < stats_numsamples ; i++ ) { + if ( stats_outrate[ i ] > stats_max ) { + stats_max = stats_outrate[ i ]; + stats_max_index = i; + } + } + } + stats_average_sum += stats_outrate[ stats_current ]; + stats_current++; stats_current %= stats_numsamples; +} + +/* +=============== +idAsyncServer::GetAsyncStatsAvgMsg +=============== +*/ +void idAsyncServer::GetAsyncStatsAvgMsg( idStr &msg ) { + sprintf( msg, "avrg out: %d B/s - max %d B/s ( over %d ms )", stats_average_sum / stats_numsamples, stats_max, idAsyncNetwork::serverSnapshotDelay.GetInteger() * stats_numsamples ); +} + +/* +=============== +idAsyncServer::ProcessDownloadRequestMessage +=============== +*/ +void idAsyncServer::ProcessDownloadRequestMessage( const netadr_t from, const idBitMsg &msg ) { + int challenge, clientId, iclient, numPaks, i; + int dlGamePak; + int dlPakChecksum; + int dlSize[ MAX_PURE_PAKS ]; // sizes + idStrList pakNames; // relative path + idStrList pakURLs; // game URLs + char pakbuf[ MAX_STRING_CHARS ]; + idStr paklist; + byte msgBuf[ MAX_MESSAGE_SIZE ]; + byte tmpBuf[ MAX_MESSAGE_SIZE ]; + idBitMsg outMsg, tmpMsg; + int dlRequest; + int voidSlots = 0; // to count and verbose the right number of paks requested for downloads + + challenge = msg.ReadLong(); + clientId = msg.ReadShort(); + dlRequest = msg.ReadLong(); + + if ( ( iclient = ValidateChallenge( from, challenge, clientId ) ) == -1 ) { + return; + } + + if ( challenges[ iclient ].authState != CDK_PUREWAIT ) { + common->DPrintf( "client %s: got download request message, not in CDK_PUREWAIT\n", Sys_NetAdrToString( from ) ); + return; + } + + // the first token of the pak names list passed to the game will be empty if no game pak is requested + dlGamePak = msg.ReadLong(); + if ( dlGamePak ) { + if ( !( dlSize[ 0 ] = fileSystem->ValidateDownloadPakForChecksum( dlGamePak, pakbuf, true ) ) ) { + common->Warning( "client requested unknown game pak 0x%x", dlGamePak ); + pakbuf[ 0 ] = '\0'; + voidSlots++; + } + } else { + pakbuf[ 0 ] = '\0'; + voidSlots++; + } + pakNames.Append( pakbuf ); + numPaks = 1; + + // read the checksums, build path names and pass that to the game code + dlPakChecksum = msg.ReadLong(); + while ( dlPakChecksum ) { + if ( !( dlSize[ numPaks ] = fileSystem->ValidateDownloadPakForChecksum( dlPakChecksum, pakbuf, false ) ) ) { + // we pass an empty token to the game so our list doesn't get offset + common->Warning( "client requested an unknown pak 0x%x", dlPakChecksum ); + pakbuf[ 0 ] = '\0'; + voidSlots++; + } + pakNames.Append( pakbuf ); + numPaks++; + dlPakChecksum = msg.ReadLong(); + } + + for ( i = 0; i < pakNames.Num(); i++ ) { + if ( i > 0 ) { + paklist += ";"; + } + paklist += pakNames[ i ].c_str(); + } + + // read the message and pass it to the game code + common->DPrintf( "got download request for %d paks - %s\n", numPaks - voidSlots, paklist.c_str() ); + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteShort( CONNECTIONLESS_MESSAGE_ID ); + outMsg.WriteString( "downloadInfo" ); + outMsg.WriteLong( dlRequest ); + if ( !game->DownloadRequest( Sys_NetAdrToString( from ), challenges[ iclient ].guid, paklist.c_str(), pakbuf ) ) { + common->DPrintf( "game: no downloads\n" ); + outMsg.WriteByte( SERVER_DL_NONE ); + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + return; + } + + char *token, *next; + int type = 0; + + token = pakbuf; + next = strchr( token, ';' ); + while ( token ) { + if ( next ) { + *next = '\0'; + } + + if ( type == 0 ) { + type = atoi( token ); + } else if ( type == SERVER_DL_REDIRECT ) { + common->DPrintf( "download request: redirect to URL %s\n", token ); + outMsg.WriteByte( SERVER_DL_REDIRECT ); + outMsg.WriteString( token ); + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + return; + } else if ( type == SERVER_DL_LIST ) { + pakURLs.Append( token ); + } else { + common->DPrintf( "wrong op type %d\n", type ); + next = token = NULL; + } + + if ( next ) { + token = next + 1; + next = strchr( token, ';' ); + } else { + token = NULL; + } + } + + if ( type == SERVER_DL_LIST ) { + int totalDlSize = 0; + int numActualPaks = 0; + + // put the answer packet together + outMsg.WriteByte( SERVER_DL_LIST ); + + tmpMsg.Init( tmpBuf, MAX_MESSAGE_SIZE ); + + for ( i = 0; i < pakURLs.Num(); i++ ) { + tmpMsg.BeginWriting(); + if ( !dlSize[ i ] || !pakURLs[ i ].Length() ) { + // still send the relative path so the client knows what it missed + tmpMsg.WriteByte( SERVER_PAK_NO ); + tmpMsg.WriteString( pakNames[ i ] ); + } else { + totalDlSize += dlSize[ i ]; + numActualPaks++; + tmpMsg.WriteByte( SERVER_PAK_YES ); + tmpMsg.WriteString( pakNames[ i ] ); + tmpMsg.WriteString( pakURLs[ i ] ); + tmpMsg.WriteLong( dlSize[ i ] ); + } + + // keep last 5 bytes for an 'end of message' - SERVER_PAK_END and the totalDlSize long + if ( outMsg.GetRemainingSpace() - tmpMsg.GetSize() > 5 ) { + outMsg.WriteData( tmpMsg.GetData(), tmpMsg.GetSize() ); + } else { + outMsg.WriteByte( SERVER_PAK_END ); + break; + } + } + if ( i == pakURLs.Num() ) { + // put a closure even if size not exceeded + outMsg.WriteByte( SERVER_PAK_END ); + } + common->DPrintf( "download request: download %d paks, %d bytes\n", numActualPaks, totalDlSize ); + + serverPort.SendPacket( from, outMsg.GetData(), outMsg.GetSize() ); + } +} diff --git a/framework/async/AsyncServer.h b/framework/async/AsyncServer.h new file mode 100644 index 000000000..2fb87c953 --- /dev/null +++ b/framework/async/AsyncServer.h @@ -0,0 +1,250 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __ASYNCSERVER_H__ +#define __ASYNCSERVER_H__ + +/* +=============================================================================== + + Network Server for asynchronous networking. + +=============================================================================== +*/ + +// MAX_CHALLENGES is made large to prevent a denial of service attack that could cycle +// all of them out before legitimate users connected +const int MAX_CHALLENGES = 1024; + +// if we don't hear from authorize server, assume it is down +const int AUTHORIZE_TIMEOUT = 5000; + +// states for the server's authorization process +typedef enum { + CDK_WAIT = 0, // we are waiting for a confirm/deny from auth + // this is subject to timeout if we don't hear from auth + // or a permanent wait if auth said so + CDK_OK, + CDK_ONLYLAN, + CDK_PUREWAIT, + CDK_PUREOK, + CDK_MAXSTATES +} authState_t; + +// states from the auth server, while the client is in CDK_WAIT +typedef enum { + AUTH_NONE = 0, // no reply yet + AUTH_OK, // this client is good + AUTH_WAIT, // wait - keep sending me srvAuth though + AUTH_DENY, // denied - don't send me anything about this client anymore + AUTH_MAXSTATES +} authReply_t; + +// message from auth to be forwarded back to the client +// some are locally hardcoded to save space, auth has the possibility to send a custom reply +typedef enum { + AUTH_REPLY_WAITING = 0, // waiting on an initial reply from auth + AUTH_REPLY_UNKNOWN, // client unknown to auth + AUTH_REPLY_DENIED, // access denied + AUTH_REPLY_PRINT, // custom message + AUTH_REPLY_SRVWAIT, // auth server replied and tells us he's working on it + AUTH_REPLY_MAXSTATES +} authReplyMsg_t; + +typedef struct challenge_s { + netadr_t address; // client address + int clientId; // client identification + int challenge; // challenge code + int time; // time the challenge was created + int pingTime; // time the challenge response was sent to client + bool connected; // true if the client is connected + authState_t authState; // local state regarding the client + authReply_t authReply; // cd key check replies + authReplyMsg_t authReplyMsg; // default auth messages + idStr authReplyPrint; // custom msg + char guid[12]; // guid + int OS; +} challenge_t; + +typedef enum { + SCS_FREE, // can be reused for a new connection + SCS_ZOMBIE, // client has been disconnected, but don't reuse connection for a couple seconds + SCS_PUREWAIT, // client needs to update it's pure checksums before we can go further + SCS_CONNECTED, // client is connected + SCS_INGAME // client is in the game +} serverClientState_t; + +typedef struct serverClient_s { + int OS; + int clientId; + serverClientState_t clientState; + int clientPrediction; + int clientAheadTime; + int clientRate; + int clientPing; + + int gameInitSequence; + int gameFrame; + int gameTime; + + idMsgChannel channel; + int lastConnectTime; + int lastEmptyTime; + int lastPingTime; + int lastSnapshotTime; + int lastPacketTime; + int lastInputTime; + int snapshotSequence; + int acknowledgeSnapshotSequence; + int numDuplicatedUsercmds; + + char guid[12]; // Even Balance - M. Quinn + +} serverClient_t; + + +class idAsyncServer { +public: + idAsyncServer(); + + bool InitPort( void ); + void ClosePort( void ); + void Spawn( void ); + void Kill( void ); + void ExecuteMapChange( void ); + + int GetPort( void ) const; + netadr_t GetBoundAdr( void ) const; + bool IsActive( void ) const { return active; } + int GetDelay( void ) const { return gameTimeResidual; } + int GetOutgoingRate( void ) const; + int GetIncomingRate( void ) const; + bool IsClientInGame( int clientNum ) const; + int GetClientPing( int clientNum ) const; + int GetClientPrediction( int clientNum ) const; + int GetClientTimeSinceLastPacket( int clientNum ) const; + int GetClientTimeSinceLastInput( int clientNum ) const; + int GetClientOutgoingRate( int clientNum ) const; + int GetClientIncomingRate( int clientNum ) const; + float GetClientOutgoingCompression( int clientNum ) const; + float GetClientIncomingCompression( int clientNum ) const; + float GetClientIncomingPacketLoss( int clientNum ) const; + int GetNumClients( void ) const; + int GetNumIdleClients( void ) const; + int GetLocalClientNum( void ) const { return localClientNum; } + + void RunFrame( void ); + void ProcessConnectionLessMessages( void ); + void RemoteConsoleOutput( const char *string ); + void SendReliableGameMessage( int clientNum, const idBitMsg &msg ); + void SendReliableGameMessageExcluding( int clientNum, const idBitMsg &msg ); + void LocalClientSendReliableMessage( const idBitMsg &msg ); + + void MasterHeartbeat( bool force = false ); + void DropClient( int clientNum, const char *reason ); + + void PacifierUpdate( void ); + + void UpdateUI( int clientNum ); + + void UpdateAsyncStatsAvg( void ); + void GetAsyncStatsAvgMsg( idStr &msg ); + + void PrintLocalServerInfo( void ); + +private: + bool active; // true if server is active + int realTime; // absolute time + + int serverTime; // local server time + idPort serverPort; // UDP port + int serverId; // server identification + int serverDataChecksum; // checksum of the data used by the server + int localClientNum; // local client on listen server + + challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting + serverClient_t clients[MAX_ASYNC_CLIENTS]; // clients + usercmd_t userCmds[MAX_USERCMD_BACKUP][MAX_ASYNC_CLIENTS]; + + int gameInitId; // game initialization identification + int gameFrame; // local game frame + int gameTime; // local game time + int gameTimeResidual; // left over time from previous frame + + netadr_t rconAddress; + + int nextHeartbeatTime; + int nextAsyncStatsTime; + + bool serverReloadingEngine; // flip-flop to not loop over when net_serverReloadEngine is on + + bool noRconOutput; // for default rcon response when command is silent + + int lastAuthTime; // global for auth server timeout + + // track the max outgoing rate over the last few secs to watch for spikes + // dependent on net_serverSnapshotDelay. 50ms, for a 3 seconds backlog -> 60 samples + static const int stats_numsamples = 60; + int stats_outrate[ stats_numsamples ]; + int stats_current; + int stats_average_sum; + int stats_max; + int stats_max_index; + + void PrintOOB( const netadr_t to, int opcode, const char *string ); + void DuplicateUsercmds( int frame, int time ); + void ClearClient( int clientNum ); + void InitClient( int clientNum, int clientId, int clientRate ); + void InitLocalClient( int clientNum ); + void BeginLocalClient( void ); + void LocalClientInput( void ); + void CheckClientTimeouts( void ); + void SendPrintBroadcast( const char *string ); + void SendPrintToClient( int clientNum, const char *string ); + void SendUserInfoBroadcast( int userInfoNum, const idDict &info, bool sendToAll = false ); + void SendUserInfoToClient( int clientNum, int userInfoNum, const idDict &info ); + void SendSyncedCvarsBroadcast( const idDict &cvars ); + void SendSyncedCvarsToClient( int clientNum, const idDict &cvars ); + void SendApplySnapshotToClient( int clientNum, int sequence ); + bool SendEmptyToClient( int clientNum, bool force = false ); + bool SendPingToClient( int clientNum ); + void SendGameInitToClient( int clientNum ); + bool SendSnapshotToClient( int clientNum ); + void ProcessUnreliableClientMessage( int clientNum, const idBitMsg &msg ); + void ProcessReliableClientMessages( int clientNum ); + void ProcessChallengeMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessConnectMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessRemoteConsoleMessage( const netadr_t from, const idBitMsg &msg ); + void ProcessGetInfoMessage( const netadr_t from, const idBitMsg &msg ); + bool ConnectionlessMessage( const netadr_t from, const idBitMsg &msg ); + bool ProcessMessage( const netadr_t from, idBitMsg &msg ); + void ProcessAuthMessage( const idBitMsg &msg ); + bool SendPureServerMessage( const netadr_t to, int OS ); // returns false if no pure paks on the list + void ProcessPureMessage( const netadr_t from, const idBitMsg &msg ); + int ValidateChallenge( const netadr_t from, int challenge, int clientId ); // returns -1 if validate failed + bool SendReliablePureToClient( int clientNum ); + void ProcessReliablePure( int clientNum, const idBitMsg &msg ); + bool VerifyChecksumMessage( int clientNum, const netadr_t *from, const idBitMsg &msg, idStr &reply, int OS ); // if from is NULL, clientNum is used for error messages + void SendReliableMessage( int clientNum, const idBitMsg &msg ); // checks for overflow and disconnects the faulty client + int UpdateTime( int clamp ); + void SendEnterGameToClient( int clientNum ); + void ProcessDownloadRequestMessage( const netadr_t from, const idBitMsg &msg ); +}; + +#endif /* !__ASYNCSERVER_H__ */ diff --git a/framework/async/MsgChannel.cpp b/framework/async/MsgChannel.cpp new file mode 100644 index 000000000..50dfe7be2 --- /dev/null +++ b/framework/async/MsgChannel.cpp @@ -0,0 +1,781 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MsgChannel.h" + +/* + +packet header +------------- +2 bytes id +4 bytes outgoing sequence. high bit will be set if this is a fragmented message. +2 bytes optional fragment start byte if fragment bit is set. +2 bytes optional fragment length if fragment bit is set. if < FRAGMENT_SIZE, this is the last fragment. + +If the id is -1, the packet should be handled as an out-of-band +message instead of as part of the message channel. + +All fragments will have the same sequence numbers. + +*/ + + +#define MAX_PACKETLEN 1400 // max size of a network packet +#define FRAGMENT_SIZE (MAX_PACKETLEN - 100) +#define FRAGMENT_BIT (1<<31) + +idCVar net_channelShowPackets( "net_channelShowPackets", "0", CVAR_SYSTEM | CVAR_BOOL, "show all packets" ); +idCVar net_channelShowDrop( "net_channelShowDrop", "0", CVAR_SYSTEM | CVAR_BOOL, "show dropped packets" ); + +/* +=============== +idMsgQueue::idMsgQueue +=============== +*/ +idMsgQueue::idMsgQueue( void ) { + Init( 0 ); +} + +/* +=============== +idMsgQueue::Init +=============== +*/ +void idMsgQueue::Init( int sequence ) { + first = last = sequence; + startIndex = endIndex = 0; +} + +/* +=============== +idMsgQueue::Add +=============== +*/ +bool idMsgQueue::Add( const byte *data, const int size ) { + if ( GetSpaceLeft() < size + 8 ) { + return false; + } + int sequence = last; + WriteShort( size ); + WriteLong( sequence ); + WriteData( data, size ); + last++; + return true; +} + +/* +=============== +idMsgQueue::Get +=============== +*/ +bool idMsgQueue::Get( byte *data, int &size ) { + if ( first == last ) { + size = 0; + return false; + } + int sequence; + size = ReadShort(); + sequence = ReadLong(); + ReadData( data, size ); + assert( sequence == first ); + first++; + return true; +} + +/* +=============== +idMsgQueue::GetTotalSize +=============== +*/ +int idMsgQueue::GetTotalSize( void ) const { + if ( startIndex <= endIndex ) { + return ( endIndex - startIndex ); + } else { + return ( sizeof( buffer ) - startIndex + endIndex ); + } +} + +/* +=============== +idMsgQueue::GetSpaceLeft +=============== +*/ +int idMsgQueue::GetSpaceLeft( void ) const { + if ( startIndex <= endIndex ) { + return sizeof( buffer ) - ( endIndex - startIndex ) - 1; + } else { + return ( startIndex - endIndex ) - 1; + } +} + +/* +=============== +idMsgQueue::CopyToBuffer +=============== +*/ +void idMsgQueue::CopyToBuffer( byte *buf ) const { + if ( startIndex <= endIndex ) { + memcpy( buf, buffer + startIndex, endIndex - startIndex ); + } else { + memcpy( buf, buffer + startIndex, sizeof( buffer ) - startIndex ); + memcpy( buf + sizeof( buffer ) - startIndex, buffer, endIndex ); + } +} + +/* +=============== +idMsgQueue::WriteByte +=============== +*/ +void idMsgQueue::WriteByte( byte b ) { + buffer[endIndex] = b; + endIndex = ( endIndex + 1 ) & ( MAX_MSG_QUEUE_SIZE - 1 ); +} + +/* +=============== +idMsgQueue::ReadByte +=============== +*/ +byte idMsgQueue::ReadByte( void ) { + byte b = buffer[startIndex]; + startIndex = ( startIndex + 1 ) & ( MAX_MSG_QUEUE_SIZE - 1 ); + return b; +} + +/* +=============== +idMsgQueue::WriteShort +=============== +*/ +void idMsgQueue::WriteShort( int s ) { + WriteByte( ( s >> 0 ) & 255 ); + WriteByte( ( s >> 8 ) & 255 ); +} + +/* +=============== +idMsgQueue::ReadShort +=============== +*/ +int idMsgQueue::ReadShort( void ) { + return ReadByte() | ( ReadByte() << 8 ); +} + +/* +=============== +idMsgQueue::WriteLong +=============== +*/ +void idMsgQueue::WriteLong( int l ) { + WriteByte( ( l >> 0 ) & 255 ); + WriteByte( ( l >> 8 ) & 255 ); + WriteByte( ( l >> 16 ) & 255 ); + WriteByte( ( l >> 24 ) & 255 ); +} + +/* +=============== +idMsgQueue::ReadLong +=============== +*/ +int idMsgQueue::ReadLong( void ) { + return ReadByte() | ( ReadByte() << 8 ) | ( ReadByte() << 16 ) | ( ReadByte() << 24 ); +} + +/* +=============== +idMsgQueue::WriteData +=============== +*/ +void idMsgQueue::WriteData( const byte *data, const int size ) { + for ( int i = 0; i < size; i++ ) { + WriteByte( data[i] ); + } +} + +/* +=============== +idMsgQueue::ReadData +=============== +*/ +void idMsgQueue::ReadData( byte *data, const int size ) { + if ( data ) { + for ( int i = 0; i < size; i++ ) { + data[i] = ReadByte(); + } + } else { + for ( int i = 0; i < size; i++ ) { + ReadByte(); + } + } +} + + +/* +=============== +idMsgChannel::idMsgChannel +=============== +*/ +idMsgChannel::idMsgChannel() { + id = -1; +} + +/* +============== +idMsgChannel::Init + + Opens a channel to a remote system. +============== +*/ +void idMsgChannel::Init( const netadr_t adr, const int id ) { + this->remoteAddress = adr; + this->id = id; + this->maxRate = 50000; + this->compressor = idCompressor::AllocRunLength_ZeroBased(); + + lastSendTime = 0; + lastDataBytes = 0; + outgoingRateTime = 0; + outgoingRateBytes = 0; + incomingRateTime = 0; + incomingRateBytes = 0; + incomingReceivedPackets = 0.0f; + incomingDroppedPackets = 0.0f; + incomingPacketLossTime = 0; + outgoingCompression = 0.0f; + incomingCompression = 0.0f; + outgoingSequence = 1; + incomingSequence = 0; + unsentFragments = false; + unsentFragmentStart = 0; + fragmentSequence = 0; + fragmentLength = 0; + reliableSend.Init( 1 ); + reliableReceive.Init( 0 ); +} + +/* +=============== +idMsgChannel::Shutdown +================ +*/ +void idMsgChannel::Shutdown( void ) { + delete compressor; + compressor = NULL; +} + +/* +================= +idMsgChannel::ResetRate +================= +*/ +void idMsgChannel::ResetRate( void ) { + lastSendTime = 0; + lastDataBytes = 0; + outgoingRateTime = 0; + outgoingRateBytes = 0; + incomingRateTime = 0; + incomingRateBytes = 0; +} + +/* +================= +idMsgChannel::ReadyToSend +================= +*/ +bool idMsgChannel::ReadyToSend( const int time ) const { + int deltaTime; + + if ( !maxRate ) { + return true; + } + deltaTime = time - lastSendTime; + if ( deltaTime > 1000 ) { + return true; + } + return ( ( lastDataBytes - ( deltaTime * maxRate ) / 1000 ) <= 0 ); +} + +/* +=============== +idMsgChannel::WriteMessageData +================ +*/ +void idMsgChannel::WriteMessageData( idBitMsg &out, const idBitMsg &msg ) { + idBitMsg tmp; + byte tmpBuf[MAX_MESSAGE_SIZE]; + + tmp.Init( tmpBuf, sizeof( tmpBuf ) ); + + // write acknowledgement of last received reliable message + tmp.WriteLong( reliableReceive.GetLast() ); + + // write reliable messages + reliableSend.CopyToBuffer( tmp.GetData() + tmp.GetSize() ); + tmp.SetSize( tmp.GetSize() + reliableSend.GetTotalSize() ); + tmp.WriteShort( 0 ); + + // write data + tmp.WriteData( msg.GetData(), msg.GetSize() ); + + // write message size + out.WriteShort( tmp.GetSize() ); + + // compress message + idFile_BitMsg file( out ); + compressor->Init( &file, true, 3 ); + compressor->Write( tmp.GetData(), tmp.GetSize() ); + compressor->FinishCompress(); + outgoingCompression = compressor->GetCompressionRatio(); +} + +/* +=============== +idMsgChannel::ReadMessageData +================ +*/ +bool idMsgChannel::ReadMessageData( idBitMsg &out, const idBitMsg &msg ) { + int reliableAcknowledge, reliableMessageSize, reliableSequence; + + // read message size + out.SetSize( msg.ReadShort() ); + + // decompress message + idFile_BitMsg file( msg ); + compressor->Init( &file, false, 3 ); + compressor->Read( out.GetData(), out.GetSize() ); + incomingCompression = compressor->GetCompressionRatio(); + out.BeginReading(); + + // read acknowledgement of sent reliable messages + reliableAcknowledge = out.ReadLong(); + + // remove acknowledged reliable messages + while( reliableSend.GetFirst() <= reliableAcknowledge ) { + if ( !reliableSend.Get( NULL, reliableMessageSize ) ) { + break; + } + } + + // read reliable messages + reliableMessageSize = out.ReadShort(); + while( reliableMessageSize != 0 ) { + if ( reliableMessageSize <= 0 || reliableMessageSize > out.GetSize() - out.GetReadCount() ) { + common->Printf( "%s: bad reliable message\n", Sys_NetAdrToString( remoteAddress ) ); + return false; + } + reliableSequence = out.ReadLong(); + if ( reliableSequence == reliableReceive.GetLast() + 1 ) { + reliableReceive.Add( out.GetData() + out.GetReadCount(), reliableMessageSize ); + } + out.ReadData( NULL, reliableMessageSize ); + reliableMessageSize = out.ReadShort(); + } + + return true; +} + +/* +================= +idMsgChannel::SendNextFragment + + Sends one fragment of the current message. +================= +*/ +void idMsgChannel::SendNextFragment( idPort &port, const int time ) { + idBitMsg msg; + byte msgBuf[MAX_PACKETLEN]; + int fragLength; + + if ( remoteAddress.type == NA_BAD ) { + return; + } + + if ( !unsentFragments ) { + return; + } + + // write the packet + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( id ); + msg.WriteLong( outgoingSequence | FRAGMENT_BIT ); + + fragLength = FRAGMENT_SIZE; + if ( unsentFragmentStart + fragLength > unsentMsg.GetSize() ) { + fragLength = unsentMsg.GetSize() - unsentFragmentStart; + } + + msg.WriteShort( unsentFragmentStart ); + msg.WriteShort( fragLength ); + msg.WriteData( unsentMsg.GetData() + unsentFragmentStart, fragLength ); + + // send the packet + port.SendPacket( remoteAddress, msg.GetData(), msg.GetSize() ); + + // update rate control variables + UpdateOutgoingRate( time, msg.GetSize() ); + + if ( net_channelShowPackets.GetBool() ) { + common->Printf( "%d send %4i : s = %i fragment = %i,%i\n", id, msg.GetSize(), outgoingSequence - 1, unsentFragmentStart, fragLength ); + } + + unsentFragmentStart += fragLength; + + // this exit condition is a little tricky, because a packet + // that is exactly the fragment length still needs to send + // a second packet of zero length so that the other side + // can tell there aren't more to follow + if ( unsentFragmentStart == unsentMsg.GetSize() && fragLength != FRAGMENT_SIZE ) { + outgoingSequence++; + unsentFragments = false; + } +} + +/* +=============== +idMsgChannel::SendMessage + + Sends a message to a connection, fragmenting if necessary + A 0 length will still generate a packet. +================ +*/ +int idMsgChannel::SendMessage( idPort &port, const int time, const idBitMsg &msg ) { + int totalLength; + + if ( remoteAddress.type == NA_BAD ) { + return -1; + } + + if ( unsentFragments ) { + common->Error( "idMsgChannel::SendMessage: called with unsent fragments left" ); + return -1; + } + + totalLength = 4 + reliableSend.GetTotalSize() + 4 + msg.GetSize(); + + if ( totalLength > MAX_MESSAGE_SIZE ) { + common->Printf( "idMsgChannel::SendMessage: message too large, length = %i\n", totalLength ); + return -1; + } + + unsentMsg.Init( unsentBuffer, sizeof( unsentBuffer ) ); + unsentMsg.BeginWriting(); + + // fragment large messages + if ( totalLength >= FRAGMENT_SIZE ) { + unsentFragments = true; + unsentFragmentStart = 0; + + // write out the message data + WriteMessageData( unsentMsg, msg ); + + // send the first fragment now + SendNextFragment( port, time ); + + return outgoingSequence; + } + + // write the header + unsentMsg.WriteShort( id ); + unsentMsg.WriteLong( outgoingSequence ); + + // write out the message data + WriteMessageData( unsentMsg, msg ); + + // send the packet + port.SendPacket( remoteAddress, unsentMsg.GetData(), unsentMsg.GetSize() ); + + // update rate control variables + UpdateOutgoingRate( time, unsentMsg.GetSize() ); + + if ( net_channelShowPackets.GetBool() ) { + common->Printf( "%d send %4i : s = %i ack = %i\n", id, unsentMsg.GetSize(), outgoingSequence - 1, incomingSequence ); + } + + outgoingSequence++; + + return ( outgoingSequence - 1 ); +} + +/* +================= +idMsgChannel::Process + + Returns false if the message should not be processed due to being out of order or a fragment. + + msg must be large enough to hold MAX_MESSAGE_SIZE, because if this is the final + fragment of a multi-part message, the entire thing will be copied out. +================= +*/ +bool idMsgChannel::Process( const netadr_t from, int time, idBitMsg &msg, int &sequence ) { + int fragStart, fragLength, dropped; + bool fragmented; + idBitMsg fragMsg; + + // the IP port can't be used to differentiate them, because + // some address translating routers periodically change UDP + // port assignments + if ( remoteAddress.port != from.port ) { + common->Printf( "idMsgChannel::Process: fixing up a translated port\n" ); + remoteAddress.port = from.port; + } + + // update incoming rate + UpdateIncomingRate( time, msg.GetSize() ); + + // get sequence numbers + sequence = msg.ReadLong(); + + // check for fragment information + if ( sequence & FRAGMENT_BIT ) { + sequence &= ~FRAGMENT_BIT; + fragmented = true; + } else { + fragmented = false; + } + + // read the fragment information + if ( fragmented ) { + fragStart = msg.ReadShort(); + fragLength = msg.ReadShort(); + } else { + fragStart = 0; // stop warning message + fragLength = 0; + } + + if ( net_channelShowPackets.GetBool() ) { + if ( fragmented ) { + common->Printf( "%d recv %4i : s = %i fragment = %i,%i\n", id, msg.GetSize(), sequence, fragStart, fragLength ); + } else { + common->Printf( "%d recv %4i : s = %i\n", id, msg.GetSize(), sequence ); + } + } + + // + // discard out of order or duplicated packets + // + if ( sequence <= incomingSequence ) { + if ( net_channelShowDrop.GetBool() || net_channelShowPackets.GetBool() ) { + common->Printf( "%s: out of order packet %i at %i\n", Sys_NetAdrToString( remoteAddress ), sequence, incomingSequence ); + } + return false; + } + + // + // dropped packets don't keep this message from being used + // + dropped = sequence - (incomingSequence+1); + if ( dropped > 0 ) { + if ( net_channelShowDrop.GetBool() || net_channelShowPackets.GetBool() ) { + common->Printf( "%s: dropped %i packets at %i\n", Sys_NetAdrToString( remoteAddress ), dropped, sequence ); + } + UpdatePacketLoss( time, 0, dropped ); + } + + // + // if the message is fragmented + // + if ( fragmented ) { + // make sure we have the correct sequence number + if ( sequence != fragmentSequence ) { + fragmentSequence = sequence; + fragmentLength = 0; + } + + // if we missed a fragment, dump the message + if ( fragStart != fragmentLength ) { + if ( net_channelShowDrop.GetBool() || net_channelShowPackets.GetBool() ) { + common->Printf( "%s: dropped a message fragment at seq %d\n", Sys_NetAdrToString( remoteAddress ), sequence ); + } + // we can still keep the part that we have so far, + // so we don't need to clear fragmentLength + UpdatePacketLoss( time, 0, 1 ); + return false; + } + + // copy the fragment to the fragment buffer + if ( fragLength < 0 || fragLength > msg.GetRemaingData() || fragmentLength + fragLength > sizeof( fragmentBuffer ) ) { + if ( net_channelShowDrop.GetBool() || net_channelShowPackets.GetBool() ) { + common->Printf( "%s: illegal fragment length\n", Sys_NetAdrToString( remoteAddress ) ); + } + UpdatePacketLoss( time, 0, 1 ); + return false; + } + + memcpy( fragmentBuffer + fragmentLength, msg.GetData() + msg.GetReadCount(), fragLength ); + + fragmentLength += fragLength; + + UpdatePacketLoss( time, 1, 0 ); + + // if this wasn't the last fragment, don't process anything + if ( fragLength == FRAGMENT_SIZE ) { + return false; + } + + } else { + memcpy( fragmentBuffer, msg.GetData() + msg.GetReadCount(), msg.GetRemaingData() ); + fragmentLength = msg.GetRemaingData(); + UpdatePacketLoss( time, 1, 0 ); + } + + fragMsg.Init( fragmentBuffer, fragmentLength ); + fragMsg.SetSize( fragmentLength ); + fragMsg.BeginReading(); + + incomingSequence = sequence; + + // read the message data + if ( !ReadMessageData( msg, fragMsg ) ) { + return false; + } + + return true; +} + +/* +================= +idMsgChannel::SendReliableMessage +================= +*/ +bool idMsgChannel::SendReliableMessage( const idBitMsg &msg ) { + bool result; + + assert( remoteAddress.type != NA_BAD ); + if ( remoteAddress.type == NA_BAD ) { + return false; + } + result = reliableSend.Add( msg.GetData(), msg.GetSize() ); + if ( !result ) { + common->Warning( "idMsgChannel::SendReliableMessage: overflowed" ); + return false; + } + return result; +} + +/* +================= +idMsgChannel::GetReliableMessage +================= +*/ +bool idMsgChannel::GetReliableMessage( idBitMsg &msg ) { + int size; + bool result; + + result = reliableReceive.Get( msg.GetData(), size ); + msg.SetSize( size ); + msg.BeginReading(); + return result; +} + +/* +=============== +idMsgChannel::ClearReliableMessages +================ +*/ +void idMsgChannel::ClearReliableMessages( void ) { + reliableSend.Init( 1 ); + reliableReceive.Init( 0 ); +} + +/* +================= +idMsgChannel::UpdateOutgoingRate +================= +*/ +void idMsgChannel::UpdateOutgoingRate( const int time, const int size ) { + // update the outgoing rate control variables + int deltaTime = time - lastSendTime; + if ( deltaTime > 1000 ) { + lastDataBytes = 0; + } else { + lastDataBytes -= ( deltaTime * maxRate ) / 1000; + if ( lastDataBytes < 0 ) { + lastDataBytes = 0; + } + } + lastDataBytes += size; + lastSendTime = time; + + // update outgoing rate variables + if ( time - outgoingRateTime > 1000 ) { + outgoingRateBytes -= outgoingRateBytes * ( time - outgoingRateTime - 1000 ) / 1000; + if ( outgoingRateBytes < 0 ) { + outgoingRateBytes = 0; + } + } + outgoingRateTime = time - 1000; + outgoingRateBytes += size; +} + +/* +================= +idMsgChannel::UpdateIncomingRate +================= +*/ +void idMsgChannel::UpdateIncomingRate( const int time, const int size ) { + // update incoming rate variables + if ( time - incomingRateTime > 1000 ) { + incomingRateBytes -= incomingRateBytes * ( time - incomingRateTime - 1000 ) / 1000; + if ( incomingRateBytes < 0 ) { + incomingRateBytes = 0; + } + } + incomingRateTime = time - 1000; + incomingRateBytes += size; +} + +/* +================= +idMsgChannel::UpdatePacketLoss +================= +*/ +void idMsgChannel::UpdatePacketLoss( const int time, const int numReceived, const int numDropped ) { + // update incoming packet loss variables + if ( time - incomingPacketLossTime > 5000 ) { + float scale = ( time - incomingPacketLossTime - 5000 ) * ( 1.0f / 5000.0f ); + incomingReceivedPackets -= incomingReceivedPackets * scale; + if ( incomingReceivedPackets < 0.0f ) { + incomingReceivedPackets = 0.0f; + } + incomingDroppedPackets -= incomingDroppedPackets * scale; + if ( incomingDroppedPackets < 0.0f ) { + incomingDroppedPackets = 0.0f; + } + } + incomingPacketLossTime = time - 5000; + incomingReceivedPackets += numReceived; + incomingDroppedPackets += numDropped; +} + +/* +================= +idMsgChannel::GetIncomingPacketLoss +================= +*/ +float idMsgChannel::GetIncomingPacketLoss( void ) const { + if ( incomingReceivedPackets == 0.0f && incomingDroppedPackets == 0.0f ) { + return 0.0f; + } + return incomingDroppedPackets * 100.0f / ( incomingReceivedPackets + incomingDroppedPackets ); +} diff --git a/framework/async/MsgChannel.h b/framework/async/MsgChannel.h new file mode 100644 index 000000000..956253ba1 --- /dev/null +++ b/framework/async/MsgChannel.h @@ -0,0 +1,192 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MSGCHANNEL_H__ +#define __MSGCHANNEL_H__ + + +/* +=============================================================================== + + Network channel. + + Handles message fragmentation and out of order / duplicate suppression. + Unreliable messages are not garrenteed to arrive but when they do, they + arrive in order and without duplicates. Reliable messages always arrive, + and they also arrive in order without duplicates. Reliable messages piggy + back on unreliable messages. As such an unreliable message stream is + required for the reliable messages to be delivered. + +=============================================================================== +*/ + +#define MAX_MESSAGE_SIZE 16384 // max length of a message, which may + // be fragmented into multiple packets +#define CONNECTIONLESS_MESSAGE_ID -1 // id for connectionless messages +#define CONNECTIONLESS_MESSAGE_ID_MASK 0x7FFF // value to mask away connectionless message id + +#define MAX_MSG_QUEUE_SIZE 16384 // must be a power of 2 + + +class idMsgQueue { +public: + idMsgQueue(); + + void Init( int sequence ); + + bool Add( const byte *data, const int size ); + bool Get( byte *data, int &size ); + int GetTotalSize( void ) const; + int GetSpaceLeft( void ) const; + int GetFirst( void ) const { return first; } + int GetLast( void ) const { return last; } + void CopyToBuffer( byte *buf ) const; + +private: + byte buffer[MAX_MSG_QUEUE_SIZE]; + int first; // sequence number of first message in queue + int last; // sequence number of last message in queue + int startIndex; // index pointing to the first byte of the first message + int endIndex; // index pointing to the first byte after the last message + + void WriteByte( byte b ); + byte ReadByte( void ); + void WriteShort( int s ); + int ReadShort( void ); + void WriteLong( int l ); + int ReadLong( void ); + void WriteData( const byte *data, const int size ); + void ReadData( byte *data, const int size ); +}; + + +class idMsgChannel { +public: + idMsgChannel(); + + void Init( const netadr_t adr, const int id ); + void Shutdown( void ); + void ResetRate( void ); + + // Sets the maximum outgoing rate. + void SetMaxOutgoingRate( int rate ) { maxRate = rate; } + + // Gets the maximum outgoing rate. + int GetMaxOutgoingRate( void ) { return maxRate; } + + // Returns the address of the entity at the other side of the channel. + netadr_t GetRemoteAddress( void ) const { return remoteAddress; } + + // Returns the average outgoing rate over the last second. + int GetOutgoingRate( void ) const { return outgoingRateBytes; } + + // Returns the average incoming rate over the last second. + int GetIncomingRate( void ) const { return incomingRateBytes; } + + // Returns the average outgoing compression ratio over the last second. + float GetOutgoingCompression( void ) const { return outgoingCompression; } + + // Returns the average incoming compression ratio over the last second. + float GetIncomingCompression( void ) const { return incomingCompression; } + + // Returns the average incoming packet loss over the last 5 seconds. + float GetIncomingPacketLoss( void ) const; + + // Returns true if the channel is ready to send new data based on the maximum rate. + bool ReadyToSend( const int time ) const; + + // Sends an unreliable message, in order and without duplicates. + int SendMessage( idPort &port, const int time, const idBitMsg &msg ); + + // Sends the next fragment if the last message was too large to send at once. + void SendNextFragment( idPort &port, const int time ); + + // Returns true if there are unsent fragments left. + bool UnsentFragmentsLeft( void ) const { return unsentFragments; } + + // Processes the incoming message. Returns true when a complete message + // is ready for further processing. In that case the read pointer of msg + // points to the first byte ready for reading, and sequence is set to + // the sequence number of the message. + bool Process( const netadr_t from, int time, idBitMsg &msg, int &sequence ); + + // Sends a reliable message, in order and without duplicates. + bool SendReliableMessage( const idBitMsg &msg ); + + // Returns true if a new reliable message is available and stores the message. + bool GetReliableMessage( idBitMsg &msg ); + + // Removes any pending outgoing or incoming reliable messages. + void ClearReliableMessages( void ); + +private: + netadr_t remoteAddress; // address of remote host + int id; // our identification used instead of port number + int maxRate; // maximum number of bytes that may go out per second + idCompressor * compressor; // compressor used for data compression + + // variables to control the outgoing rate + int lastSendTime; // last time data was sent out + int lastDataBytes; // bytes left to send at last send time + + // variables to keep track of the rate + int outgoingRateTime; + int outgoingRateBytes; + int incomingRateTime; + int incomingRateBytes; + + // variables to keep track of the compression ratio + float outgoingCompression; + float incomingCompression; + + // variables to keep track of the incoming packet loss + float incomingReceivedPackets; + float incomingDroppedPackets; + int incomingPacketLossTime; + + // sequencing variables + int outgoingSequence; + int incomingSequence; + + // outgoing fragment buffer + bool unsentFragments; + int unsentFragmentStart; + byte unsentBuffer[MAX_MESSAGE_SIZE]; + idBitMsg unsentMsg; + + // incoming fragment assembly buffer + int fragmentSequence; + int fragmentLength; + byte fragmentBuffer[MAX_MESSAGE_SIZE]; + + // reliable messages + idMsgQueue reliableSend; + idMsgQueue reliableReceive; + +private: + void WriteMessageData( idBitMsg &out, const idBitMsg &msg ); + bool ReadMessageData( idBitMsg &out, const idBitMsg &msg ); + + void UpdateOutgoingRate( const int time, const int size ); + void UpdateIncomingRate( const int time, const int size ); + + void UpdatePacketLoss( const int time, const int numReceived, const int numDropped ); +}; + +#endif /* !__MSGCHANNEL_H__ */ diff --git a/framework/async/NetworkSystem.cpp b/framework/async/NetworkSystem.cpp new file mode 100644 index 000000000..6eb185320 --- /dev/null +++ b/framework/async/NetworkSystem.cpp @@ -0,0 +1,206 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "NetworkSystem.h" + +idNetworkSystem networkSystemLocal; +idNetworkSystem * networkSystem = &networkSystemLocal; + + +/* +================== +idNetworkSystem::ServerSendReliableMessage +================== +*/ +void idNetworkSystem::ServerSendReliableMessage( int clientNum, const idBitMsg &msg ) { + if ( idAsyncNetwork::server.IsActive() ) { + idAsyncNetwork::server.SendReliableGameMessage( clientNum, msg ); + } +} + +/* +================== +idNetworkSystem::ServerSendReliableMessageExcluding +================== +*/ +void idNetworkSystem::ServerSendReliableMessageExcluding( int clientNum, const idBitMsg &msg ) { + if ( idAsyncNetwork::server.IsActive() ) { + idAsyncNetwork::server.SendReliableGameMessageExcluding( clientNum, msg ); + } +} + +/* +================== +idNetworkSystem::ServerGetClientPing +================== +*/ +int idNetworkSystem::ServerGetClientPing( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientPing( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientPrediction +================== +*/ +int idNetworkSystem::ServerGetClientPrediction( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientPrediction( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientTimeSinceLastPacket +================== +*/ +int idNetworkSystem::ServerGetClientTimeSinceLastPacket( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientTimeSinceLastPacket( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientTimeSinceLastInput +================== +*/ +int idNetworkSystem::ServerGetClientTimeSinceLastInput( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientTimeSinceLastInput( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientOutgoingRate +================== +*/ +int idNetworkSystem::ServerGetClientOutgoingRate( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientOutgoingRate( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientIncomingRate +================== +*/ +int idNetworkSystem::ServerGetClientIncomingRate( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientIncomingRate( clientNum ); + } + return 0; +} + +/* +================== +idNetworkSystem::ServerGetClientIncomingPacketLoss +================== +*/ +float idNetworkSystem::ServerGetClientIncomingPacketLoss( int clientNum ) { + if ( idAsyncNetwork::server.IsActive() ) { + return idAsyncNetwork::server.GetClientIncomingPacketLoss( clientNum ); + } + return 0.0f; +} + +/* +================== +idNetworkSystem::ClientSendReliableMessage +================== +*/ +void idNetworkSystem::ClientSendReliableMessage( const idBitMsg &msg ) { + if ( idAsyncNetwork::client.IsActive() ) { + idAsyncNetwork::client.SendReliableGameMessage( msg ); + } else if ( idAsyncNetwork::server.IsActive() ) { + idAsyncNetwork::server.LocalClientSendReliableMessage( msg ); + } +} + +/* +================== +idNetworkSystem::ClientGetPrediction +================== +*/ +int idNetworkSystem::ClientGetPrediction( void ) { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetPrediction(); + } + return 0; +} + +/* +================== +idNetworkSystem::ClientGetTimeSinceLastPacket +================== +*/ +int idNetworkSystem::ClientGetTimeSinceLastPacket( void ) { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetTimeSinceLastPacket(); + } + return 0; +} + +/* +================== +idNetworkSystem::ClientGetOutgoingRate +================== +*/ +int idNetworkSystem::ClientGetOutgoingRate( void ) { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetOutgoingRate(); + } + return 0; +} + +/* +================== +idNetworkSystem::ClientGetIncomingRate +================== +*/ +int idNetworkSystem::ClientGetIncomingRate( void ) { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetIncomingRate(); + } + return 0; +} + +/* +================== +idNetworkSystem::ClientGetIncomingPacketLoss +================== +*/ +float idNetworkSystem::ClientGetIncomingPacketLoss( void ) { + if ( idAsyncNetwork::client.IsActive() ) { + return idAsyncNetwork::client.GetIncomingPacketLoss(); + } + return 0.0f; +} diff --git a/framework/async/NetworkSystem.h b/framework/async/NetworkSystem.h new file mode 100644 index 000000000..92b77c1e0 --- /dev/null +++ b/framework/async/NetworkSystem.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __NETWORKSYSTEM_H__ +#define __NETWORKSYSTEM_H__ + + +/* +=============================================================================== + + Network System. + +=============================================================================== +*/ + +class idNetworkSystem { +public: + virtual ~idNetworkSystem( void ) {} + + virtual void ServerSendReliableMessage( int clientNum, const idBitMsg &msg ); + virtual void ServerSendReliableMessageExcluding( int clientNum, const idBitMsg &msg ); + virtual int ServerGetClientPing( int clientNum ); + virtual int ServerGetClientPrediction( int clientNum ); + virtual int ServerGetClientTimeSinceLastPacket( int clientNum ); + virtual int ServerGetClientTimeSinceLastInput( int clientNum ); + virtual int ServerGetClientOutgoingRate( int clientNum ); + virtual int ServerGetClientIncomingRate( int clientNum ); + virtual float ServerGetClientIncomingPacketLoss( int clientNum ); + + virtual void ClientSendReliableMessage( const idBitMsg &msg ); + virtual int ClientGetPrediction( void ); + virtual int ClientGetTimeSinceLastPacket( void ); + virtual int ClientGetOutgoingRate( void ); + virtual int ClientGetIncomingRate( void ); + virtual float ClientGetIncomingPacketLoss( void ); +}; + +extern idNetworkSystem * networkSystem; + +#endif /* !__NETWORKSYSTEM_H__ */ diff --git a/framework/async/ServerScan.cpp b/framework/async/ServerScan.cpp new file mode 100644 index 000000000..54117af4e --- /dev/null +++ b/framework/async/ServerScan.cpp @@ -0,0 +1,630 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +idCVar gui_filter_password( "gui_filter_password", "0", CVAR_GUI | CVAR_INTEGER | CVAR_ARCHIVE, "Password filter" ); +idCVar gui_filter_players( "gui_filter_players", "0", CVAR_GUI | CVAR_INTEGER | CVAR_ARCHIVE, "Players filter" ); +idCVar gui_filter_gameType( "gui_filter_gameType", "0", CVAR_GUI | CVAR_INTEGER | CVAR_ARCHIVE, "Gametype filter" ); +idCVar gui_filter_idle( "gui_filter_idle", "0", CVAR_GUI | CVAR_INTEGER | CVAR_ARCHIVE, "Idle servers filter" ); +idCVar gui_filter_game( "gui_filter_game", "0", CVAR_GUI | CVAR_INTEGER | CVAR_ARCHIVE, "Game filter" ); + +const char* l_gameTypes[] = { + "Deathmatch", + "Tourney", + "Team DM", + "Last Man", + "CTF", + NULL +}; + +static idServerScan *l_serverScan = NULL; + +/* +================ +idServerScan::idServerScan +================ +*/ +idServerScan::idServerScan( ) { + m_pGUI = NULL; + m_sort = SORT_PING; + m_sortAscending = true; + challenge = 0; + LocalClear(); +} + +/* +================ +idServerScan::LocalClear +================ +*/ +void idServerScan::LocalClear( ) { + scan_state = IDLE; + incoming_net = false; + lan_pingtime = -1; + net_info.Clear(); + net_servers.Clear(); + cur_info = 0; + if ( listGUI ) { + listGUI->Clear(); + } + incoming_useTimeout = false; + m_sortedServers.Clear(); +} + +/* +================ +idServerScan::Clear +================ +*/ +void idServerScan::Clear( ) { + LocalClear(); + idList::Clear(); +} + +/* +================ +idServerScan::Shutdown +================ +*/ +void idServerScan::Shutdown( ) { + m_pGUI = NULL; + if ( listGUI ) { + listGUI->Config( NULL, NULL ); + uiManager->FreeListGUI( listGUI ); + listGUI = NULL; + } + screenshot.Clear(); +} + +/* +================ +idServerScan::SetupLANScan +================ +*/ +void idServerScan::SetupLANScan( ) { + Clear(); + GUIUpdateSelected(); + scan_state = LAN_SCAN; + challenge++; + lan_pingtime = Sys_Milliseconds(); + common->DPrintf( "SetupLANScan with challenge %d\n", challenge ); +} + +/* +================ +idServerScan::InfoResponse +================ +*/ +int idServerScan::InfoResponse( networkServer_t &server ) { + if ( scan_state == IDLE ) { + return false; + } + + idStr serv = Sys_NetAdrToString( server.adr ); + + if ( server.challenge != challenge ) { + common->DPrintf( "idServerScan::InfoResponse - ignoring response from %s, wrong challenge %d.", serv.c_str(), server.challenge ); + return false; + } + + if ( scan_state == NET_SCAN ) { + const idKeyValue *info = net_info.FindKey( serv.c_str() ); + if ( !info ) { + common->DPrintf( "idServerScan::InfoResponse NET_SCAN: reply from unknown %s\n", serv.c_str() ); + return false; + } + int id = atoi( info->GetValue() ); + net_info.Delete( serv.c_str() ); + inServer_t iserv = net_servers[ id ]; + server.ping = Sys_Milliseconds() - iserv.time; + server.id = iserv.id; + } else { + server.ping = Sys_Milliseconds() - lan_pingtime; + server.id = 0; + + // check for duplicate servers + for ( int i = 0; i < Num() ; i++ ) { + if ( memcmp( &(*this)[ i ].adr, &server.adr, sizeof(netadr_t) ) == 0 ) { + common->DPrintf( "idServerScan::InfoResponse LAN_SCAN: duplicate server %s\n", serv.c_str() ); + return true; + } + } + } + + const char *si_map = server.serverInfo.GetString( "si_map" ); + const idDecl *mapDecl = declManager->FindType( DECL_MAPDEF, si_map, false ); + const idDeclEntityDef *mapDef = static_cast< const idDeclEntityDef * >( mapDecl ); + if ( mapDef ) { + const char *mapName = common->GetLanguageDict()->GetString( mapDef->dict.GetString( "name", si_map ) ); + server.serverInfo.Set( "si_mapName", mapName ); + } else { + server.serverInfo.Set( "si_mapName", si_map ); + } + + int index = Append( server ); + // for now, don't maintain sorting when adding new info response servers + m_sortedServers.Append( Num()-1 ); + if ( listGUI->IsConfigured( ) && !IsFiltered( server ) ) { + GUIAdd( Num()-1, server ); + } + if ( listGUI->GetSelection( NULL, 0 ) == ( Num()-1 ) ) { + GUIUpdateSelected(); + } + + return index; +} + +/* +================ +idServerScan::AddServer +================ +*/ +void idServerScan::AddServer( int id, const char *srv ) { + inServer_t s; + + incoming_net = true; + incoming_lastTime = Sys_Milliseconds() + INCOMING_TIMEOUT; + s.id = id; + + // using IPs, not hosts + if ( !Sys_StringToNetAdr( srv, &s.adr, false ) ) { + common->DPrintf( "idServerScan::AddServer: failed to parse server %s\n", srv ); + return; + } + if ( !s.adr.port ) { + s.adr.port = PORT_SERVER; + } + + net_servers.Append( s ); +} + +/* +================ +idServerScan::EndServers +================ +*/ +void idServerScan::EndServers( ) { + incoming_net = false; + l_serverScan = this; + m_sortedServers.Sort( idServerScan::Cmp ); + ApplyFilter(); +} + +/* +================ +idServerScan::StartServers +================ +*/ +void idServerScan::StartServers( bool timeout ) { + incoming_net = true; + incoming_useTimeout = timeout; + incoming_lastTime = Sys_Milliseconds() + REFRESH_START; +} + +/* +================ +idServerScan::EmitGetInfo +================ +*/ +void idServerScan::EmitGetInfo( netadr_t &serv ) { + idAsyncNetwork::client.GetServerInfo( serv ); +} + +/* +=============== +idServerScan::GetChallenge +=============== +*/ +int idServerScan::GetChallenge( ) { + return challenge; +} + +/* +================ +idServerScan::NetScan +================ +*/ +void idServerScan::NetScan( ) { + if ( !idAsyncNetwork::client.IsPortInitialized() ) { + // if the port isn't open, initialize it, but wait for a short + // time to let the OS do whatever magic things it needs to do... + idAsyncNetwork::client.InitPort(); + // start the scan one second from now... + scan_state = WAIT_ON_INIT; + endWaitTime = Sys_Milliseconds() + 1000; + return; + } + + // make sure the client port is open + idAsyncNetwork::client.InitPort(); + + scan_state = NET_SCAN; + challenge++; + + idList::Clear(); + m_sortedServers.Clear(); + cur_info = 0; + net_info.Clear(); + listGUI->Clear(); + GUIUpdateSelected(); + common->DPrintf( "NetScan with challenge %d\n", challenge ); + + while ( cur_info < Min( net_servers.Num(), MAX_PINGREQUESTS ) ) { + netadr_t serv = net_servers[ cur_info ].adr; + EmitGetInfo( serv ); + net_servers[ cur_info ].time = Sys_Milliseconds(); + net_info.SetInt( Sys_NetAdrToString( serv ), cur_info ); + cur_info++; + } +} + +/* +=============== +idServerScan::ServerScanFrame +=============== +*/ +void idServerScan::RunFrame( ) { + if ( scan_state == IDLE ) { + return; + } + + if ( scan_state == WAIT_ON_INIT ) { + if ( Sys_Milliseconds() >= endWaitTime ) { + scan_state = IDLE; + NetScan(); + } + return; + } + + int timeout_limit = Sys_Milliseconds() - REPLY_TIMEOUT; + + if ( scan_state == LAN_SCAN ) { + if ( timeout_limit > lan_pingtime ) { + common->Printf( "Scanned for servers on the LAN\n" ); + scan_state = IDLE; + } + return; + } + + // if scan_state == NET_SCAN + + // check for timeouts + int i = 0; + while ( i < net_info.GetNumKeyVals() ) { + if ( timeout_limit > net_servers[ atoi( net_info.GetKeyVal( i )->GetValue().c_str() ) ].time ) { + common->DPrintf( "timeout %s\n", net_info.GetKeyVal( i )->GetKey().c_str() ); + net_info.Delete( net_info.GetKeyVal( i )->GetKey().c_str() ); + } else { + i++; + } + } + + // possibly send more queries + while ( cur_info < net_servers.Num() && net_info.GetNumKeyVals() < MAX_PINGREQUESTS ) { + netadr_t serv = net_servers[ cur_info ].adr; + EmitGetInfo( serv ); + net_servers[ cur_info ].time = Sys_Milliseconds(); + net_info.SetInt( Sys_NetAdrToString( serv ), cur_info ); + cur_info++; + } + + // update state + if ( ( !incoming_net || ( incoming_useTimeout && Sys_Milliseconds() > incoming_lastTime ) ) && net_info.GetNumKeyVals() == 0 ) { + EndServers(); + // the list is complete, we are no longer waiting for any getInfo replies + common->Printf( "Scanned %d servers.\n", cur_info ); + scan_state = IDLE; + } +} + +/* +=============== +idServerScan::GetBestPing +=============== +*/ +bool idServerScan::GetBestPing( networkServer_t &serv ) { + int i, ic; + ic = Num(); + if ( !ic ) { + return false; + } + serv = (*this)[ 0 ]; + for ( i = 0 ; i < ic ; i++ ) { + if ( (*this)[ i ].ping < serv.ping ) { + serv = (*this)[ i ]; + } + } + return true; +} + +/* +================ +idServerScan::GUIConfig +================ +*/ +void idServerScan::GUIConfig( idUserInterface *pGUI, const char *name ) { + m_pGUI = pGUI; + if ( listGUI == NULL ) { + listGUI = uiManager->AllocListGUI(); + } + listGUI->Config( pGUI, name ); +} + +/* +================ +idServerScan::GUIUpdateSelected +================ +*/ +void idServerScan::GUIUpdateSelected( void ) { + char screenshot[ MAX_STRING_CHARS ]; + + if ( !m_pGUI ) { + return; + } + int i = listGUI->GetSelection( NULL, 0 ); + if ( i == -1 || i >= Num() ) { + m_pGUI->SetStateString( "server_name", "" ); + m_pGUI->SetStateString( "player1", "" ); + m_pGUI->SetStateString( "player2", "" ); + m_pGUI->SetStateString( "player3", "" ); + m_pGUI->SetStateString( "player4", "" ); + m_pGUI->SetStateString( "player5", "" ); + m_pGUI->SetStateString( "player6", "" ); + m_pGUI->SetStateString( "player7", "" ); + m_pGUI->SetStateString( "player8", "" ); + m_pGUI->SetStateString( "server_map", "" ); + m_pGUI->SetStateString( "browser_levelshot", "" ); + m_pGUI->SetStateString( "server_gameType", "" ); + m_pGUI->SetStateString( "server_IP", "" ); + m_pGUI->SetStateString( "server_passworded", "" ); + } else { + m_pGUI->SetStateString( "server_name", (*this)[ i ].serverInfo.GetString( "si_name" ) ); + for ( int j = 0; j < 8; j++ ) { + if ( (*this)[i].clients > j ) { + m_pGUI->SetStateString( va( "player%i", j + 1 ) , (*this)[ i ].nickname[ j ] ); + } else { + m_pGUI->SetStateString( va( "player%i", j + 1 ) , "" ); + } + } + m_pGUI->SetStateString( "server_map", (*this)[ i ].serverInfo.GetString( "si_mapName" ) ); + fileSystem->FindMapScreenshot( (*this)[ i ].serverInfo.GetString( "si_map" ), screenshot, MAX_STRING_CHARS ); + m_pGUI->SetStateString( "browser_levelshot", screenshot ); + m_pGUI->SetStateString( "server_gameType", (*this)[ i ].serverInfo.GetString( "si_gameType" ) ); + m_pGUI->SetStateString( "server_IP", Sys_NetAdrToString( (*this)[ i ].adr ) ); + if ( (*this)[ i ].serverInfo.GetBool( "si_usePass" ) ) { + m_pGUI->SetStateString( "server_passworded", "PASSWORD REQUIRED" ); + } else { + m_pGUI->SetStateString( "server_passworded", "" ); + } + } +} + +/* +================ +idServerScan::GUIAdd +================ +*/ +void idServerScan::GUIAdd( int id, const networkServer_t server ) { + idStr name = server.serverInfo.GetString( "si_name", GAME_NAME " Server" ); + bool d3xp = false; + bool mod = false; + + if ( !idStr::Icmp( server.serverInfo.GetString( "fs_game" ), "d3xp" ) || + !idStr::Icmp( server.serverInfo.GetString( "fs_game_base" ), "d3xp" ) ) { + d3xp = true; + } + if ( server.serverInfo.GetString( "fs_game" )[ 0 ] != '\0' ) { + mod = true; + } + + name += "\t"; + if ( server.serverInfo.GetString( "sv_punkbuster" )[ 0 ] == '1' ) { + name += "mtr_PB"; + } + + name += "\t"; + if ( d3xp ) { + // FIXME: even for a 'D3XP mod' + // could have a specific icon for this case + name += "mtr_doom3XPIcon"; + } else if ( mod ) { + name += "mtr_doom3Mod"; + } else { + name += "mtr_doom3Icon"; + } + name += "\t"; + name += va( "%i/%i\t", server.clients, server.serverInfo.GetInt( "si_maxPlayers" ) ); + name += ( server.ping > -1 ) ? va( "%i\t", server.ping ) : "na\t"; + name += server.serverInfo.GetString( "si_gametype" ); + name += "\t"; + name += server.serverInfo.GetString( "si_mapName" ); + name += "\t"; + listGUI->Add( id, name ); +} + +/* +================ +idServerScan::ApplyFilter +================ +*/ +void idServerScan::ApplyFilter( ) { + int i; + networkServer_t serv; + idStr s; + + listGUI->SetStateChanges( false ); + listGUI->Clear(); + for ( i = m_sortAscending ? 0 : m_sortedServers.Num() - 1; + m_sortAscending ? i < m_sortedServers.Num() : i >= 0; + m_sortAscending ? i++ : i-- ) { + serv = (*this)[ m_sortedServers[ i ] ]; + if ( !IsFiltered( serv ) ) { + GUIAdd( m_sortedServers[ i ], serv ); + } + } + GUIUpdateSelected(); + listGUI->SetStateChanges( true ); +} + +/* +================ +idServerScan::IsFiltered +================ +*/ +bool idServerScan::IsFiltered( const networkServer_t server ) { + int i; + const idKeyValue *keyval; + + // OS support filter +#if 0 + // filter out pure servers that won't provide checksumed game code for client OS + keyval = server.serverInfo.FindKey( "si_pure" ); + if ( keyval && !idStr::Cmp( keyval->GetValue(), "1" ) ) { + if ( ( server.OSMask & ( 1 << BUILD_OS_ID ) ) == 0 ) { + return true; + } + } +#else + if ( ( server.OSMask & ( 1 << BUILD_OS_ID ) ) == 0 ) { + return true; + } +#endif + // password filter + keyval = server.serverInfo.FindKey( "si_usePass" ); + if ( keyval && gui_filter_password.GetInteger() == 1 ) { + // show passworded only + if ( keyval->GetValue()[ 0 ] == '0' ) { + return true; + } + } else if ( keyval && gui_filter_password.GetInteger() == 2 ) { + // show no password only + if ( keyval->GetValue()[ 0 ] != '0' ) { + return true; + } + } + // players filter + keyval = server.serverInfo.FindKey( "si_maxPlayers" ); + if ( keyval ) { + if ( gui_filter_players.GetInteger() == 1 && server.clients == atoi( keyval->GetValue() ) ) { + return true; + } else if ( gui_filter_players.GetInteger() == 2 && ( !server.clients || server.clients == atoi( keyval->GetValue() ) ) ) { + return true; + } + } + // gametype filter + keyval = server.serverInfo.FindKey( "si_gameType" ); + if ( keyval && gui_filter_gameType.GetInteger() ) { + i = 0; + while ( l_gameTypes[ i ] ) { + if ( !keyval->GetValue().Icmp( l_gameTypes[ i ] ) ) { + break; + } + i++; + } + if ( l_gameTypes[ i ] && i != gui_filter_gameType.GetInteger() -1 ) { + return true; + } + } + // idle server filter + keyval = server.serverInfo.FindKey( "si_idleServer" ); + if ( keyval && !gui_filter_idle.GetInteger() ) { + if ( !keyval->GetValue().Icmp( "1" ) ) { + return true; + } + } + + // autofilter D3XP games if the user does not has the XP installed + if(!fileSystem->HasD3XP() && !idStr::Icmp(server.serverInfo.GetString( "fs_game" ), "d3xp")) { + return true; + } + + // filter based on the game doom or XP + if(gui_filter_game.GetInteger() == 1) { //Only Doom + if(idStr::Icmp(server.serverInfo.GetString("fs_game"), "")) { + return true; + } + } else if(gui_filter_game.GetInteger() == 2) { //Only D3XP + if(idStr::Icmp(server.serverInfo.GetString("fs_game"), "d3xp")) { + return true; + } + } + + return false; +} + +/* +================ +idServerScan::Cmp +================ +*/ + +int idServerScan::Cmp( const int *a, const int *b ) { + networkServer_t serv1, serv2; + idStr s1, s2; + int ret; + + serv1 = (*l_serverScan)[ *a ]; + serv2 = (*l_serverScan)[ *b ]; + switch ( l_serverScan->m_sort ) { + case SORT_PING: + ret = serv1.ping < serv2.ping ? -1 : ( serv1.ping > serv2.ping ? 1 : 0 ); + return ret; + case SORT_SERVERNAME: + serv1.serverInfo.GetString( "si_name", "", s1 ); + serv2.serverInfo.GetString( "si_name", "", s2 ); + return s1.IcmpNoColor( s2 ); + case SORT_PLAYERS: + ret = serv1.clients < serv2.clients ? -1 : ( serv1.clients > serv2.clients ? 1 : 0 ); + return ret; + case SORT_GAMETYPE: + serv1.serverInfo.GetString( "si_gameType", "", s1 ); + serv2.serverInfo.GetString( "si_gameType", "", s2 ); + return s1.Icmp( s2 ); + case SORT_MAP: + serv1.serverInfo.GetString( "si_mapName", "", s1 ); + serv2.serverInfo.GetString( "si_mapName", "", s2 ); + return s1.Icmp( s2 ); + case SORT_GAME: + serv1.serverInfo.GetString( "fs_game", "", s1 ); + serv2.serverInfo.GetString( "fs_game", "", s2 ); + return s1.Icmp( s2 ); + } + return 0; +} + +/* +================ +idServerScan::SetSorting +================ +*/ +void idServerScan::SetSorting( serverSort_t sort ) { + l_serverScan = this; + if ( sort == m_sort ) { + m_sortAscending = !m_sortAscending; + } else { + m_sort = sort; + m_sortAscending = true; // is the default for any new sort + m_sortedServers.Sort( idServerScan::Cmp ); + } + // trigger a redraw + ApplyFilter(); +} + diff --git a/framework/async/ServerScan.h b/framework/async/ServerScan.h new file mode 100644 index 000000000..f703960b4 --- /dev/null +++ b/framework/async/ServerScan.h @@ -0,0 +1,161 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SERVERSCAN_H__ +#define __SERVERSCAN_H__ + +/* +=============================================================================== + + Scan for servers, on the LAN or from a list + Update a listDef GUI through usage of idListGUI class + When updating large lists of servers, sends out getInfo in small batches to avoid congestion + +=============================================================================== +*/ + +// storage for incoming servers / server scan +typedef struct { + netadr_t adr; + int id; + int time; +} inServer_t; + +// the menu gui uses a hard-coded control type to display a list of network games +typedef struct { + netadr_t adr; + idDict serverInfo; + int ping; + int id; // idnet mode sends an id for each server in list + int clients; + char nickname[ MAX_NICKLEN ][ MAX_ASYNC_CLIENTS ]; + short pings[ MAX_ASYNC_CLIENTS ]; + int rate[ MAX_ASYNC_CLIENTS ]; + int OSMask; + int challenge; +} networkServer_t; + +typedef enum { + SORT_PING, + SORT_SERVERNAME, + SORT_PLAYERS, + SORT_GAMETYPE, + SORT_MAP, + SORT_GAME +} serverSort_t; + +class idServerScan : public idList { +public: + idServerScan( ); + + int InfoResponse( networkServer_t &server ); + + // add an internet server - ( store a numeric id along with it ) + void AddServer( int id, const char *srv ); + + // we are going to feed server entries to be pinged + // if timeout is true, use a timeout once we start AddServer to trigger EndServers and decide the scan is done + void StartServers( bool timeout ); + // we are done filling up the list of server entries + void EndServers( ); + + // scan the current list of servers - used for refreshes and while receiving a fresh list + void NetScan( ); + + // clear + void Clear( ); + + // called each game frame. Updates the scanner state, takes care of ongoing scans + void RunFrame( ); + + typedef enum { + IDLE = 0, + WAIT_ON_INIT, + LAN_SCAN, + NET_SCAN + } scan_state_t; + + scan_state_t GetState() { return scan_state; } + void SetState( scan_state_t ); + + bool GetBestPing( networkServer_t &serv ); + + // prepare for a LAN scan. idAsyncClient does the network job (UDP broadcast), we do the storage + void SetupLANScan( ); + + void GUIConfig( idUserInterface *pGUI, const char *name ); + // update the GUI fields with information about the currently selected server + void GUIUpdateSelected( void ); + + void Shutdown( ); + + void ApplyFilter( ); + + // there is an internal toggle, call twice with same sort to switch + void SetSorting( serverSort_t sort ); + + int GetChallenge( ); + +private: + static const int MAX_PINGREQUESTS = 32; // how many servers to query at once + static const int REPLY_TIMEOUT = 999; // how long should we wait for a reply from a game server + static const int INCOMING_TIMEOUT = 1500; // when we got an incoming server list, how long till we decide the list is done + static const int REFRESH_START = 10000; // how long to wait when sending the initial refresh request + + scan_state_t scan_state; + + bool incoming_net; // set to true while new servers are fed through AddServer + bool incoming_useTimeout; + int incoming_lastTime; + + int lan_pingtime; // holds the time of LAN scan + + // servers we're waiting for a reply from + // won't exceed MAX_PINGREQUESTS elements + // holds index of net_servers elements, indexed by 'from' string + idDict net_info; + + idList net_servers; + // where we are in net_servers list for getInfo emissions ( NET_SCAN only ) + // we may either be waiting on MAX_PINGREQUESTS, or for net_servers to grow some more ( through AddServer ) + int cur_info; + + idUserInterface *m_pGUI; + idListGUI * listGUI; + + serverSort_t m_sort; + bool m_sortAscending; + idList m_sortedServers; // use ascending for the walking order + + idStr screenshot; + int challenge; // challenge for current scan + + int endWaitTime; // when to stop waiting on a port init + +private: + void LocalClear( ); // we need to clear some internal data as well + + void EmitGetInfo( netadr_t &serv ); + void GUIAdd( int id, const networkServer_t server ); + bool IsFiltered( const networkServer_t server ); + + static int Cmp( const int *a, const int *b ); +}; + +#endif /* !__SERVERSCAN_H__ */ diff --git a/framework/async/networksystem.h b/framework/async/networksystem.h deleted file mode 100644 index e37b8d773..000000000 --- a/framework/async/networksystem.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:34 sparhawk - * Initial revision - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __NETWORKSYSTEM_H__ -#define __NETWORKSYSTEM_H__ - - -/* -=============================================================================== - - Network System. - -=============================================================================== -*/ - -class idNetworkSystem { -public: - virtual ~idNetworkSystem( void ) {} - - virtual void ServerSendReliableMessage( int clientNum, const idBitMsg &msg ); - virtual void ServerSendReliableMessageExcluding( int clientNum, const idBitMsg &msg ); - virtual int ServerGetClientPing( int clientNum ); - virtual int ServerGetClientPrediction( int clientNum ); - virtual int ServerGetClientTimeSinceLastPacket( int clientNum ); - virtual int ServerGetClientTimeSinceLastInput( int clientNum ); - virtual int ServerGetClientOutgoingRate( int clientNum ); - virtual int ServerGetClientIncomingRate( int clientNum ); - virtual float ServerGetClientIncomingPacketLoss( int clientNum ); - - virtual void ClientSendReliableMessage( const idBitMsg &msg ); - virtual int ClientGetPrediction( void ); - virtual int ClientGetTimeSinceLastPacket( void ); - virtual int ClientGetOutgoingRate( void ); - virtual int ClientGetIncomingRate( void ); - virtual float ClientGetIncomingPacketLoss( void ); -}; - -extern idNetworkSystem * networkSystem; - -#endif /* !__NETWORKSYSTEM_H__ */ diff --git a/framework/builddefines.h b/framework/builddefines.h deleted file mode 100644 index 011393bd0..000000000 --- a/framework/builddefines.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -/* -=============================================================================== - - Preprocessor settings for compiling different versions. - -=============================================================================== -*/ - -// memory debugging -//#define ID_REDIRECT_NEWDELETE -//#define ID_DEBUG_MEMORY -//#define ID_DEBUG_UNINITIALIZED_MEMORY - -// if enabled, the console won't toggle upon ~, unless you start the binary with +set com_allowConsole 1 -// Ctrl+Alt+~ will always toggle the console no matter what -#ifndef ID_CONSOLE_LOCK - #if defined(_WIN32) || defined(MACOS_X) - #ifdef _DEBUG - #define ID_CONSOLE_LOCK 0 - #else - #define ID_CONSOLE_LOCK 1 - #endif - #else - #define ID_CONSOLE_LOCK 0 - #endif -#endif - -// useful for network debugging, turns off 'LAN' checks, all IPs are classified 'internet' -#ifndef ID_NOLANADDRESS - #define ID_NOLANADDRESS 0 -#endif - -// let .dds be loaded from FS without altering pure state. only for developement. -#ifndef ID_PURE_ALLOWDDS - #define ID_PURE_ALLOWDDS 0 -#endif - -// build an exe with no CVAR_CHEAT controls -#ifndef ID_ALLOW_CHEATS - #define ID_ALLOW_CHEATS 0 -#endif - -#ifndef ID_ENABLE_CURL - #define ID_ENABLE_CURL 1 -#endif - -// fake a pure client. useful to connect an all-debug client to a server -#ifndef ID_FAKE_PURE - #define ID_FAKE_PURE 0 -#endif - -// verify checksums in clientinfo traffic -// NOTE: this makes the network protocol incompatible -#ifndef ID_CLIENTINFO_TAGS - #define ID_CLIENTINFO_TAGS 0 -#endif - -// for win32 this is defined in preprocessor settings so that MFC can be -// compiled out. -//#define ID_DEDICATED - -// if this is defined, the executable positively won't work with any paks other -// than the demo pak, even if productid is present. -//#define ID_DEMO_BUILD - -// don't define ID_ALLOW_TOOLS when we don't want tool code in the executable. -#if defined( _WIN32 ) && !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD ) - #define ID_ALLOW_TOOLS -#endif - -// don't do backtraces in release builds. -// atm, we have no useful way to reconstruct the trace, so let's leave it off -#define ID_BT_STUB -#ifndef ID_BT_STUB - #if defined( __linux__ ) - #if defined( _DEBUG ) - #define ID_BT_STUB - #endif - #else - #define ID_BT_STUB - #endif -#endif - -#ifndef ID_ENFORCE_KEY -# if !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD ) -# define ID_ENFORCE_KEY 1 -# else -# define ID_ENFORCE_KEY 0 -# endif -#endif - -#ifndef ID_OPENAL -# if defined( _WIN32 ) && !defined( ID_DEDICATED ) -# define ID_OPENAL 1 -# else -# define ID_OPENAL 0 -# endif -#endif - -#ifndef ID_ALLOW_D3XP -# if defined( MACOS_X ) -# define ID_ALLOW_D3XP 0 -# else -# define ID_ALLOW_D3XP 1 -# endif -#endif - diff --git a/framework/buildversion.h b/framework/buildversion.h deleted file mode 100644 index 4c7422459..000000000 --- a/framework/buildversion.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// This should never be hand edited, AlienBrain will update this when the -// release new doom .exe is executed from within the AlienBrain client -// There are no consequences for it not being updated, it just lets us -// track an exact build number that matches the source control history -const int BUILD_NUMBER = 1304; diff --git a/framework/cmdsystem.h b/framework/cmdsystem.h deleted file mode 100644 index f65edf05f..000000000 --- a/framework/cmdsystem.h +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CMDSYSTEM_H__ -#define __CMDSYSTEM_H__ - -/* -=============================================================================== - - Console command execution and command text buffering. - - Any number of commands can be added in a frame from several different - sources. Most commands come from either key bindings or console line input, - but entire text files can be execed. - - Command execution takes a null terminated string, breaks it into tokens, - then searches for a command or variable that matches the first token. - -=============================================================================== -*/ - -// command flags -typedef enum { - CMD_FL_ALL = -1, - CMD_FL_CHEAT = BIT(0), // command is considered a cheat - CMD_FL_SYSTEM = BIT(1), // system command - CMD_FL_RENDERER = BIT(2), // renderer command - CMD_FL_SOUND = BIT(3), // sound command - CMD_FL_GAME = BIT(4), // game command - CMD_FL_TOOL = BIT(5) // tool command -} cmdFlags_t; - -// parameters for command buffer stuffing -typedef enum { - CMD_EXEC_NOW, // don't return until completed - CMD_EXEC_INSERT, // insert at current position, but don't run yet - CMD_EXEC_APPEND // add to end of the command buffer (normal case) -} cmdExecution_t; - -// command function -typedef void (*cmdFunction_t)( const idCmdArgs &args ); - -// argument completion function -typedef void (*argCompletion_t)( const idCmdArgs &args, void(*callback)( const char *s ) ); - - -class idCmdSystem { -public: - virtual ~idCmdSystem( void ) {} - - virtual void Init( void ) = 0; - virtual void Shutdown( void ) = 0; - - // Registers a command and the function to call for it. - virtual void AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion = NULL ) = 0; - // Removes a command. - virtual void RemoveCommand( const char *cmdName ) = 0; - // Remove all commands with one of the flags set. - virtual void RemoveFlaggedCommands( int flags ) = 0; - - // Command and argument completion using callback for each valid string. - virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0; - virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0; - - // Adds command text to the command buffer, does not add a final \n - virtual void BufferCommandText( cmdExecution_t exec, const char *text ) = 0; - // Pulls off \n \r or ; terminated lines of text from the command buffer and - // executes the commands. Stops when the buffer is empty. - // Normally called once per frame, but may be explicitly invoked. - virtual void ExecuteCommandBuffer( void ) = 0; - - // Base for path/file auto-completion. - virtual void ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) = 0; - // Base for decl name auto-completion. - virtual void ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ) = 0; - - // Adds to the command buffer in tokenized form ( CMD_EXEC_NOW or CMD_EXEC_APPEND only ) - virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ) = 0; - - // Setup a reloadEngine to happen on next command run, and give a command to execute after reload - virtual void SetupReloadEngine( const idCmdArgs &args ) = 0; - virtual bool PostReloadEngine( void ) = 0; - - // Default argument completion functions. - static void ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) ); - template - static void ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) ); - template - static void ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) ); - template - static void ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) ); -}; - -extern idCmdSystem * cmdSystem; - - -ID_INLINE void idCmdSystem::ArgCompletion_Boolean( const idCmdArgs &args, void(*callback)( const char *s ) ) { - callback( va( "%s 0", args.Argv( 0 ) ) ); - callback( va( "%s 1", args.Argv( 0 ) ) ); -} - -template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Integer( const idCmdArgs &args, void(*callback)( const char *s ) ) { - for ( int i = min; i <= max; i++ ) { - callback( va( "%s %d", args.Argv( 0 ), i ) ); - } -} - -template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_String( const idCmdArgs &args, void(*callback)( const char *s ) ) { - for ( int i = 0; strings[i]; i++ ) { - callback( va( "%s %s", args.Argv( 0 ), strings[i] ) ); - } -} - -template ID_STATIC_TEMPLATE ID_INLINE void idCmdSystem::ArgCompletion_Decl( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_DeclName( args, callback, type ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_FileName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, "", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_MapName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "maps/", true, ".map", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "sound/", false, ".wav", ".ogg", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", false, ".tga", ".dds", ".jpg", ".pcx", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "video/", false, ".roq", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", true, ".cfg", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "SaveGames/", true, ".save", NULL ); -} - -ID_INLINE void idCmdSystem::ArgCompletion_DemoName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "demos/", true, ".demo", NULL ); -} - -#endif /* !__CMDSYSTEM_H__ */ diff --git a/framework/common.h b/framework/common.h deleted file mode 100644 index e68b93570..000000000 --- a/framework/common.h +++ /dev/null @@ -1,199 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __COMMON_H__ -#define __COMMON_H__ - -/* -============================================================== - - Common - -============================================================== -*/ - -typedef enum { - EDITOR_NONE = 0, - EDITOR_RADIANT = BIT(1), - EDITOR_GUI = BIT(2), - EDITOR_DEBUGGER = BIT(3), - EDITOR_SCRIPT = BIT(4), - EDITOR_LIGHT = BIT(5), - EDITOR_SOUND = BIT(6), - EDITOR_DECL = BIT(7), - EDITOR_AF = BIT(8), - EDITOR_PARTICLE = BIT(9), - EDITOR_PDA = BIT(10), - EDITOR_AAS = BIT(11), - EDITOR_MATERIAL = BIT(12) -} toolFlag_t; - -#define STRTABLE_ID "#str_" -#define STRTABLE_ID_LENGTH 5 - -extern idCVar com_version; -extern idCVar com_skipRenderer; -extern idCVar com_asyncInput; -extern idCVar com_asyncSound; -extern idCVar com_machineSpec; -extern idCVar com_purgeAll; -extern idCVar com_developer; -extern idCVar com_allowConsole; -extern idCVar com_speeds; -extern idCVar com_showFPS; -extern idCVar com_showMemoryUsage; -extern idCVar com_showAsyncStats; -extern idCVar com_showSoundDecoders; -extern idCVar com_makingBuild; -extern idCVar com_updateLoadSize; -extern idCVar com_videoRam; - -extern int time_gameFrame; // game logic time -extern int time_gameDraw; // game present time -extern int time_frontend; // renderer frontend time -extern int time_backend; // renderer backend time - -extern int com_frameTime; // time for the current frame in milliseconds -extern volatile int com_ticNumber; // 60 hz tics, incremented by async function -extern int com_editors; // current active editor(s) -extern bool com_editorActive; // true if an editor has focus - -#ifdef _WIN32 -const char DMAP_MSGID[] = "DMAPOutput"; -const char DMAP_DONE[] = "DMAPDone"; -extern HWND com_hwndMsg; -extern bool com_outputMsg; -#endif - -struct MemInfo_t { - idStr filebase; - - int total; - int assetTotals; - - // memory manager totals - int memoryManagerTotal; - - // subsystem totals - int gameSubsystemTotal; - int renderSubsystemTotal; - - // asset totals - int imageAssetsTotal; - int modelAssetsTotal; - int soundAssetsTotal; -}; - -class idCommon { -public: - virtual ~idCommon( void ) {} - - // Initialize everything. - // if the OS allows, pass argc/argv directly (without executable name) - // otherwise pass the command line in a single string (without executable name) - virtual void Init( int argc, const char **argv, const char *cmdline ) = 0; - - // Shuts down everything. - virtual void Shutdown( void ) = 0; - - // Shuts down everything. - virtual void Quit( void ) = 0; - - // Returns true if common initialization is complete. - virtual bool IsInitialized( void ) const = 0; - - // Called repeatedly as the foreground thread for rendering and game logic. - virtual void Frame( void ) = 0; - - // Called repeatedly by blocking function calls with GUI interactivity. - virtual void GUIFrame( bool execCmd, bool network ) = 0; - - // Called 60 times a second from a background thread for sound mixing, - // and input generation. Not called until idCommon::Init() has completed. - virtual void Async( void ) = 0; - - // Checks for and removes command line "+set var arg" constructs. - // If match is NULL, all set commands will be executed, otherwise - // only a set with the exact name. Only used during startup. - // set once to clear the cvar from +set for early init code - virtual void StartupVariable( const char *match, bool once ) = 0; - - // Initializes a tool with the given dictionary. - virtual void InitTool( const toolFlag_t tool, const idDict *dict ) = 0; - - // Activates or deactivates a tool. - virtual void ActivateTool( bool active ) = 0; - - // Writes the user's configuration to a file - virtual void WriteConfigToFile( const char *filename ) = 0; - - // Writes cvars with the given flags to a file. - virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) = 0; - - // Begins redirection of console output to the given buffer. - virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ) = 0; - - // Stops redirection of console output. - virtual void EndRedirect( void ) = 0; - - // Update the screen with every message printed. - virtual void SetRefreshOnPrint( bool set ) = 0; - - // Prints message to the console, which may cause a screen update if com_refreshOnPrint is set. - virtual void Printf( const char *fmt, ... )id_attribute((format(printf,2,3))) = 0; - - // Same as Printf, with a more usable API - Printf pipes to this. - virtual void VPrintf( const char *fmt, va_list arg ) = 0; - - // Prints message that only shows up if the "developer" cvar is set, - // and NEVER forces a screen update, which could cause reentrancy problems. - virtual void DPrintf( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; - - // Prints WARNING %s message and adds the warning message to a queue for printing later on. - virtual void Warning( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; - - // Prints WARNING %s message in yellow that only shows up if the "developer" cvar is set. - virtual void DWarning( const char *fmt, ...) id_attribute((format(printf,2,3))) = 0; - - // Prints all queued warnings. - virtual void PrintWarnings( void ) = 0; - - // Removes all queued warnings. - virtual void ClearWarnings( const char *reason ) = 0; - - // Issues a C++ throw. Normal errors just abort to the game loop, - // which is appropriate for media or dynamic logic errors. - virtual void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; - - // Fatal errors quit all the way to a system dialog box, which is appropriate for - // static internal errors or cases where the system may be corrupted. - virtual void FatalError( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; - - // Returns a pointer to the dictionary with language specific strings. - virtual const idLangDict * GetLanguageDict( void ) = 0; - - // Returns key bound to the command - virtual const char * KeysFromBinding( const char *bind ) = 0; - - // Returns the binding bound to the key - virtual const char * BindingFromKey( const char *key ) = 0; - - // Directly sample a button. - virtual int ButtonState( int key ) = 0; - - // Directly sample a keystate. - virtual int KeyState( int key ) = 0; -}; - -extern idCommon * common; - -#endif /* !__COMMON_H__ */ diff --git a/framework/cvarsystem.h b/framework/cvarsystem.h deleted file mode 100644 index 2011decb5..000000000 --- a/framework/cvarsystem.h +++ /dev/null @@ -1,299 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CVARSYSTEM_H__ -#define __CVARSYSTEM_H__ - -/* -=============================================================================== - - Console Variables (CVars) are used to hold scalar or string variables - that can be changed or displayed at the console as well as accessed - directly in code. - - CVars are mostly used to hold settings that can be changed from the - console or saved to and loaded from configuration files. CVars are also - occasionally used to communicate information between different modules - of the program. - - CVars are restricted from having the same names as console commands to - keep the console interface from being ambiguous. - - CVars can be accessed from the console in three ways: - cvarName prints the current value - cvarName X sets the value to X if the variable exists - set cvarName X as above, but creates the CVar if not present - - CVars may be declared in the global namespace, in classes and in functions. - However declarations in classes and functions should always be static to - save space and time. Making CVars static does not change their - functionality due to their global nature. - - CVars should be contructed only through one of the constructors with name, - value, flags and description. The name, value and description parameters - to the constructor have to be static strings, do not use va() or the like - functions returning a string. - - CVars may be declared multiple times using the same name string. However, - they will all reference the same value and changing the value of one CVar - changes the value of all CVars with the same name. - - CVars should always be declared with the correct type flag: CVAR_BOOL, - CVAR_INTEGER or CVAR_FLOAT. If no such flag is specified the CVar - defaults to type string. If the CVAR_BOOL flag is used there is no need - to specify an argument auto-completion function because the CVar gets - one assigned automatically. - - CVars are automatically range checked based on their type and any min/max - or valid string set specified in the constructor. - - CVars are always considered cheats except when CVAR_NOCHEAT, CVAR_INIT, - CVAR_ROM, CVAR_ARCHIVE, CVAR_USERINFO, CVAR_SERVERINFO, CVAR_NETWORKSYNC - is set. - -=============================================================================== -*/ - -#ifdef __linux__ -#include "cmdsystem.h" -#include -#include -#endif - -typedef enum { - CVAR_ALL = -1, // all flags - CVAR_BOOL = BIT(0), // variable is a boolean - CVAR_INTEGER = BIT(1), // variable is an integer - CVAR_FLOAT = BIT(2), // variable is a float - CVAR_SYSTEM = BIT(3), // system variable - CVAR_RENDERER = BIT(4), // renderer variable - CVAR_SOUND = BIT(5), // sound variable - CVAR_GUI = BIT(6), // gui variable - CVAR_GAME = BIT(7), // game variable - CVAR_TOOL = BIT(8), // tool variable - CVAR_USERINFO = BIT(9), // sent to servers, available to menu - CVAR_SERVERINFO = BIT(10), // sent from servers, available to menu - CVAR_NETWORKSYNC = BIT(11), // cvar is synced from the server to clients - CVAR_STATIC = BIT(12), // statically declared, not user created - CVAR_CHEAT = BIT(13), // variable is considered a cheat - CVAR_NOCHEAT = BIT(14), // variable is not considered a cheat - CVAR_INIT = BIT(15), // can only be set from the command-line - CVAR_ROM = BIT(16), // display only, cannot be set by user at all - CVAR_ARCHIVE = BIT(17), // set to cause it to be saved to a config file - CVAR_MODIFIED = BIT(18) // set when the variable is modified -} cvarFlags_t; - - -/* -=============================================================================== - - idCVar - -=============================================================================== -*/ - -class idCVar { -public: - // Never use the default constructor. - idCVar( void ) { assert( typeid( this ) != typeid( idCVar ) ); } - - // Always use one of the following constructors. - idCVar( const char *name, const char *value, int flags, const char *description, - argCompletion_t valueCompletion = NULL ); - idCVar( const char *name, const char *value, int flags, const char *description, - float valueMin, float valueMax, argCompletion_t valueCompletion = NULL ); - idCVar( const char *name, const char *value, int flags, const char *description, - const char **valueStrings, argCompletion_t valueCompletion = NULL ); - - virtual ~idCVar( void ) {} - - const char * GetName( void ) const { return internalVar->name; } - int GetFlags( void ) const { return internalVar->flags; } - const char * GetDescription( void ) const { return internalVar->description; } - float GetMinValue( void ) const { return internalVar->valueMin; } - float GetMaxValue( void ) const { return internalVar->valueMax; } - const char ** GetValueStrings( void ) const { return valueStrings; } - argCompletion_t GetValueCompletion( void ) const { return valueCompletion; } - - bool IsModified( void ) const { return ( internalVar->flags & CVAR_MODIFIED ) != 0; } - void SetModified( void ) { internalVar->flags |= CVAR_MODIFIED; } - void ClearModified( void ) { internalVar->flags &= ~CVAR_MODIFIED; } - - const char * GetString( void ) const { return internalVar->value; } - bool GetBool( void ) const { return ( internalVar->integerValue != 0 ); } - int GetInteger( void ) const { return internalVar->integerValue; } - float GetFloat( void ) const { return internalVar->floatValue; } - - void SetString( const char *value ) { internalVar->InternalSetString( value ); } - void SetBool( const bool value ) { internalVar->InternalSetBool( value ); } - void SetInteger( const int value ) { internalVar->InternalSetInteger( value ); } - void SetFloat( const float value ) { internalVar->InternalSetFloat( value ); } - - void SetInternalVar( idCVar *cvar ) { internalVar = cvar; } - - static void RegisterStaticVars( void ); - -protected: - const char * name; // name - const char * value; // value - const char * description; // description - int flags; // CVAR_? flags - float valueMin; // minimum value - float valueMax; // maximum value - const char ** valueStrings; // valid value strings - argCompletion_t valueCompletion; // value auto-completion function - int integerValue; // atoi( string ) - float floatValue; // atof( value ) - idCVar * internalVar; // internal cvar - idCVar * next; // next statically declared cvar - -private: - void Init( const char *name, const char *value, int flags, const char *description, - float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion ); - - virtual void InternalSetString( const char *newValue ) {} - virtual void InternalSetBool( const bool newValue ) {} - virtual void InternalSetInteger( const int newValue ) {} - virtual void InternalSetFloat( const float newValue ) {} - - static idCVar * staticVars; -}; - -ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, - argCompletion_t valueCompletion ) { - if ( !valueCompletion && ( flags & CVAR_BOOL ) ) { - valueCompletion = idCmdSystem::ArgCompletion_Boolean; - } - Init( name, value, flags, description, 1, -1, NULL, valueCompletion ); -} - -ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, - float valueMin, float valueMax, argCompletion_t valueCompletion ) { - Init( name, value, flags, description, valueMin, valueMax, NULL, valueCompletion ); -} - -ID_INLINE idCVar::idCVar( const char *name, const char *value, int flags, const char *description, - const char **valueStrings, argCompletion_t valueCompletion ) { - Init( name, value, flags, description, 1, -1, valueStrings, valueCompletion ); -} - - -/* -=============================================================================== - - idCVarSystem - -=============================================================================== -*/ - -class idCVarSystem { -public: - virtual ~idCVarSystem( void ) {} - - virtual void Init( void ) = 0; - virtual void Shutdown( void ) = 0; - virtual bool IsInitialized( void ) const = 0; - - // Registers a CVar. - virtual void Register( idCVar *cvar ) = 0; - - // Finds the CVar with the given name. - // Returns NULL if there is no CVar with the given name. - virtual idCVar * Find( const char *name ) = 0; - - // Sets the value of a CVar by name. - virtual void SetCVarString( const char *name, const char *value, int flags = 0 ) = 0; - virtual void SetCVarBool( const char *name, const bool value, int flags = 0 ) = 0; - virtual void SetCVarInteger( const char *name, const int value, int flags = 0 ) = 0; - virtual void SetCVarFloat( const char *name, const float value, int flags = 0 ) = 0; - - // Gets the value of a CVar by name. - virtual const char * GetCVarString( const char *name ) const = 0; - virtual bool GetCVarBool( const char *name ) const = 0; - virtual int GetCVarInteger( const char *name ) const = 0; - virtual float GetCVarFloat( const char *name ) const = 0; - - // Called by the command system when argv(0) doesn't match a known command. - // Returns true if argv(0) is a variable reference and prints or changes the CVar. - virtual bool Command( const idCmdArgs &args ) = 0; - - // Command and argument completion using callback for each valid string. - virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0; - virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0; - - // Sets/gets/clears modified flags that tell what kind of CVars have changed. - virtual void SetModifiedFlags( int flags ) = 0; - virtual int GetModifiedFlags( void ) const = 0; - virtual void ClearModifiedFlags( int flags ) = 0; - - // Resets variables with one of the given flags set. - virtual void ResetFlaggedVariables( int flags ) = 0; - - // Removes auto-completion from the flagged variables. - virtual void RemoveFlaggedAutoCompletion( int flags ) = 0; - - // Writes variables with one of the given flags set to the given file. - virtual void WriteFlaggedVariables( int flags, const char *setCmd, idFile *f ) const = 0; - - // Moves CVars to and from dictionaries. - virtual const idDict * MoveCVarsToDict( int flags ) const = 0; - virtual void SetCVarsFromDict( const idDict &dict ) = 0; -}; - -extern idCVarSystem * cvarSystem; - - -/* -=============================================================================== - - CVar Registration - - Each DLL using CVars has to declare a private copy of the static variable - idCVar::staticVars like this: idCVar * idCVar::staticVars = NULL; - Furthermore idCVar::RegisterStaticVars() has to be called after the - cvarSystem pointer is set when the DLL is first initialized. - -=============================================================================== -*/ - -ID_INLINE void idCVar::Init( const char *name, const char *value, int flags, const char *description, - float valueMin, float valueMax, const char **valueStrings, argCompletion_t valueCompletion ) { - this->name = name; - this->value = value; - this->flags = flags; - this->description = description; - this->flags = flags | CVAR_STATIC; - this->valueMin = valueMin; - this->valueMax = valueMax; - this->valueStrings = valueStrings; - this->valueCompletion = valueCompletion; - this->integerValue = 0; - this->floatValue = 0.0f; - this->internalVar = this; - if ( staticVars != (idCVar *)0xFFFFFFFF ) { - this->next = staticVars; - staticVars = this; - } else { - cvarSystem->Register( this ); - } -} - -ID_INLINE void idCVar::RegisterStaticVars( void ) { - if ( staticVars != (idCVar *)0xFFFFFFFF ) { - for ( idCVar *cvar = staticVars; cvar; cvar = cvar->next ) { - cvarSystem->Register( cvar ); - } - staticVars = (idCVar *)0xFFFFFFFF; - } -} - -#endif /* !__CVARSYSTEM_H__ */ diff --git a/framework/declaf.h b/framework/declaf.h deleted file mode 100644 index dc00f2396..000000000 --- a/framework/declaf.h +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLAF_H__ -#define __DECLAF_H__ - -/* -=============================================================================== - - Articulated Figure - -=============================================================================== -*/ - -class idDeclAF; - -typedef enum { - DECLAF_CONSTRAINT_INVALID, - DECLAF_CONSTRAINT_FIXED, - DECLAF_CONSTRAINT_BALLANDSOCKETJOINT, - DECLAF_CONSTRAINT_UNIVERSALJOINT, - DECLAF_CONSTRAINT_HINGE, - DECLAF_CONSTRAINT_SLIDER, - DECLAF_CONSTRAINT_SPRING -} declAFConstraintType_t; - -typedef enum { - DECLAF_JOINTMOD_AXIS, - DECLAF_JOINTMOD_ORIGIN, - DECLAF_JOINTMOD_BOTH -} declAFJointMod_t; - -typedef bool (*getJointTransform_t)( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ); - -class idAFVector { -public: - enum { - VEC_COORDS = 0, - VEC_JOINT, - VEC_BONECENTER, - VEC_BONEDIR - } type; - idStr joint1; - idStr joint2; - -public: - idAFVector( void ); - - bool Parse( idLexer &src ); - bool Finish( const char *fileName, const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const; - bool Write( idFile *f ) const; - const char * ToString( idStr &str, const int precision = 8 ); - const idVec3 & ToVec3( void ) const { return vec; } - idVec3 & ToVec3( void ) { return vec; } - -private: - mutable idVec3 vec; - bool negate; -}; - -class idDeclAF_Body { -public: - idStr name; - idStr jointName; - declAFJointMod_t jointMod; - int modelType; - idAFVector v1, v2; - int numSides; - float width; - float density; - idAFVector origin; - idAngles angles; - int contents; - int clipMask; - bool selfCollision; - idMat3 inertiaScale; - float linearFriction; - float angularFriction; - float contactFriction; - idStr containedJoints; - idAFVector frictionDirection; - idAFVector contactMotorDirection; -public: - void SetDefault( const idDeclAF *file ); -}; - -class idDeclAF_Constraint { -public: - idStr name; - idStr body1; - idStr body2; - declAFConstraintType_t type; - float friction; - float stretch; - float compress; - float damping; - float restLength; - float minLength; - float maxLength; - idAFVector anchor; - idAFVector anchor2; - idAFVector shaft[2]; - idAFVector axis; - enum { - LIMIT_NONE = -1, - LIMIT_CONE, - LIMIT_PYRAMID - } limit; - idAFVector limitAxis; - float limitAngles[3]; - -public: - void SetDefault( const idDeclAF *file ); -}; - -class idDeclAF : public idDecl { - friend class idAFFileManager; -public: - idDeclAF( void ); - virtual ~idDeclAF( void ); - - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - - virtual void Finish( const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model ) const; - - bool Save( void ); - - void NewBody( const char *name ); - void RenameBody( const char *oldName, const char *newName ); - void DeleteBody( const char *name ); - - void NewConstraint( const char *name ); - void RenameConstraint( const char *oldName, const char *newName ); - void DeleteConstraint( const char *name ); - - static int ContentsFromString( const char *str ); - static const char * ContentsToString( const int contents, idStr &str ); - - static declAFJointMod_t JointModFromString( const char *str ); - static const char * JointModToString( declAFJointMod_t jointMod ); - -public: - bool modified; - idStr model; - idStr skin; - float defaultLinearFriction; - float defaultAngularFriction; - float defaultContactFriction; - float defaultConstraintFriction; - float totalMass; - idVec2 suspendVelocity; - idVec2 suspendAcceleration; - float noMoveTime; - float noMoveTranslation; - float noMoveRotation; - float minMoveTime; - float maxMoveTime; - int contents; - int clipMask; - bool selfCollision; - idList bodies; - idList constraints; - -private: - bool ParseContents( idLexer &src, int &c ) const; - bool ParseBody( idLexer &src ); - bool ParseFixed( idLexer &src ); - bool ParseBallAndSocketJoint( idLexer &src ); - bool ParseUniversalJoint( idLexer &src ); - bool ParseHinge( idLexer &src ); - bool ParseSlider( idLexer &src ); - bool ParseSpring( idLexer &src ); - bool ParseSettings( idLexer &src ); - - bool WriteBody( idFile *f, const idDeclAF_Body &body ) const; - bool WriteFixed( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteBallAndSocketJoint( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteUniversalJoint( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteHinge( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteSlider( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteSpring( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteConstraint( idFile *f, const idDeclAF_Constraint &c ) const; - bool WriteSettings( idFile *f ) const; - - bool RebuildTextSource( void ); -}; - -#endif /* !__DECLAF_H__ */ diff --git a/framework/declentitydef.h b/framework/declentitydef.h deleted file mode 100644 index dba741d63..000000000 --- a/framework/declentitydef.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLENTITYDEF_H__ -#define __DECLENTITYDEF_H__ - -/* -=============================================================================== - - idDeclEntityDef - -=============================================================================== -*/ - -class idDeclEntityDef : public idDecl { -public: - idDict dict; - - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition() const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - virtual void Print( void ); -}; - -#endif /* !__DECLENTITYDEF_H__ */ diff --git a/framework/declfx.h b/framework/declfx.h deleted file mode 100644 index 129f7a894..000000000 --- a/framework/declfx.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLFX_H__ -#define __DECLFX_H__ - -/* -=============================================================================== - - idDeclFX - -=============================================================================== -*/ - -enum { - FX_LIGHT, - FX_PARTICLE, - FX_DECAL, - FX_MODEL, - FX_SOUND, - FX_SHAKE, - FX_ATTACHLIGHT, - FX_ATTACHENTITY, - FX_LAUNCH, - FX_SHOCKWAVE -}; - -// -// single fx structure -// -struct idFXSingleAction { - int type; - int sibling; - - idStr data; - idStr name; - idStr fire; - - float delay; - float duration; - float restart; - float size; - float fadeInTime; - float fadeOutTime; - float shakeTime; - float shakeAmplitude; - float shakeDistance; - float shakeImpulse; - float lightRadius; - float rotate; - float random1; - float random2; - - idVec3 lightColor; - idVec3 offset; - idMat3 axis; - - bool soundStarted; - bool shakeStarted; - bool shakeFalloff; - bool shakeIgnoreMaster; - bool bindParticles; - bool explicitAxis; - bool noshadows; - bool particleTrackVelocity; - bool trackOrigin; -}; - -// -// grouped fx structures -// -class idDeclFX : public idDecl { -public: - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - virtual void Print( void ) const; - virtual void List( void ) const; - - idListevents; - idStr joint; - -private: - void ParseSingleFXAction( idLexer &src, idFXSingleAction& FXAction ); -}; - -#endif /* !__DECLFX_H__ */ diff --git a/framework/declmanager.h b/framework/declmanager.h deleted file mode 100644 index 9e41c451c..000000000 --- a/framework/declmanager.h +++ /dev/null @@ -1,324 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLMANAGER_H__ -#define __DECLMANAGER_H__ - -/* -=============================================================================== - - Declaration Manager - - All "small text" data types, like materials, sound shaders, fx files, - entity defs, etc. are managed uniformly, allowing reloading, purging, - listing, printing, etc. All "large text" data types that never have more - than one declaration in a given file, like maps, models, AAS files, etc. - are not handled here. - - A decl will never, ever go away once it is created. The manager is - garranteed to always return the same decl pointer for a decl type/name - combination. The index of a decl in the per type list also stays the - same throughout the lifetime of the engine. Although the pointer to - a decl always stays the same, one should never maintain pointers to - data inside decls. The data stored in a decl is not garranteed to stay - the same for more than one engine frame. - - The decl indexes of explicitely defined decls are garrenteed to be - consistent based on the parsed decl files. However, the indexes of - implicit decls may be different based on the order in which levels - are loaded. - - The decl namespaces are separate for each type. Comments for decls go - above the text definition to keep them associated with the proper decl. - - During decl parsing, errors should never be issued, only warnings - followed by a call to MakeDefault(). - -=============================================================================== -*/ - -typedef enum { - DECL_TABLE = 0, - DECL_MATERIAL, - DECL_SKIN, - DECL_SOUND, - DECL_ENTITYDEF, - DECL_MODELDEF, - DECL_FX, - DECL_PARTICLE, - DECL_AF, - DECL_UNUSED, // tels: was DECL_PDA - DECL_VIDEO, - DECL_AUDIO, - DECL_UNUSED2, // tels: was DECL_EMAIL - DECL_MODELEXPORT, - DECL_MAPDEF, - - // TDM specific DECLs - DECL_XDATA, // External data, for scripts - DECL_TDM_MATINFO, // Material information local to TDM. - DECL_TDM_MISSIONINFO, // Mission information - // new decl types can be added here - - DECL_MAX_TYPES = 32 -} declType_t; - -typedef enum { - DS_UNPARSED, - DS_DEFAULTED, // set if a parse failed due to an error, or the lack of any source - DS_PARSED -} declState_t; - -const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated - LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings - LEXFL_ALLOWPATHNAMES | // allow path seperators in names - LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals - LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated - LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring - - -class idDeclBase { -public: - virtual ~idDeclBase() {}; - virtual const char * GetName( void ) const = 0; - virtual declType_t GetType( void ) const = 0; - virtual declState_t GetState( void ) const = 0; - virtual bool IsImplicit( void ) const = 0; - virtual bool IsValid( void ) const = 0; - virtual void Invalidate( void ) = 0; - virtual void Reload( void ) = 0; - virtual void EnsureNotPurged( void ) = 0; - virtual int Index( void ) const = 0; - virtual int GetLineNum( void ) const = 0; - virtual const char * GetFileName( void ) const = 0; - virtual void GetText( char *text ) const = 0; - virtual int GetTextLength( void ) const = 0; - virtual void SetText( const char *text ) = 0; - virtual bool ReplaceSourceFileText( void ) = 0; - virtual bool SourceFileChanged( void ) const = 0; - virtual void MakeDefault( void ) = 0; - virtual bool EverReferenced( void ) const = 0; - virtual bool SetDefaultText( void ) = 0; - virtual const char * DefaultDefinition( void ) const = 0; - virtual bool Parse( const char *text, const int textLength ) = 0; - virtual void FreeData( void ) = 0; - virtual size_t Size( void ) const = 0; - virtual void List( void ) const = 0; - virtual void Print( void ) const = 0; -}; - - -class idDecl { -public: - // The constructor should initialize variables such that - // an immediate call to FreeData() does no harm. - idDecl( void ) { base = NULL; } - virtual ~idDecl( void ) {}; - - // Returns the name of the decl. - const char * GetName( void ) const { return base->GetName(); } - - // Returns the decl type. - declType_t GetType( void ) const { return base->GetType(); } - - // Returns the decl state which is usefull for finding out if a decl defaulted. - declState_t GetState( void ) const { return base->GetState(); } - - // Returns true if the decl was defaulted or the text was created with a call to SetDefaultText. - bool IsImplicit( void ) const { return base->IsImplicit(); } - - // The only way non-manager code can have an invalid decl is if the *ByIndex() - // call was used with forceParse = false to walk the lists to look at names - // without touching the media. - bool IsValid( void ) const { return base->IsValid(); } - - // Sets state back to unparsed. - // Used by decl editors to undo any changes to the decl. - void Invalidate( void ) { base->Invalidate(); } - - // if a pointer might possible be stale from a previous level, - // call this to have it re-parsed - void EnsureNotPurged( void ) { base->EnsureNotPurged(); } - - // Returns the index in the per-type list. - int Index( void ) const { return base->Index(); } - - // Returns the line number the decl starts. - int GetLineNum( void ) const { return base->GetLineNum(); } - - // Returns the name of the file in which the decl is defined. - const char * GetFileName( void ) const { return base->GetFileName(); } - - // Returns the decl text. - void GetText( char *text ) const { base->GetText( text ); } - - // Returns the length of the decl text. - int GetTextLength( void ) const { return base->GetTextLength(); } - - // Sets new decl text. - void SetText( const char *text ) { base->SetText( text ); } - - // Saves out new text for the decl. - // Used by decl editors to replace the decl text in the source file. - bool ReplaceSourceFileText( void ) { return base->ReplaceSourceFileText(); } - - // Returns true if the source file changed since it was loaded and parsed. - bool SourceFileChanged( void ) const { return base->SourceFileChanged(); } - - // Frees data and makes the decl a default. - void MakeDefault( void ) { base->MakeDefault(); } - - // Returns true if the decl was ever referenced. - bool EverReferenced( void ) const { return base->EverReferenced(); } - -public: - // Sets textSource to a default text if necessary. - // This may be overridden to provide a default definition based on the - // decl name. For instance materials may default to an implicit definition - // using a texture with the same name as the decl. - virtual bool SetDefaultText( void ) { return base->SetDefaultText(); } - - // Each declaration type must have a default string that it is guaranteed - // to parse acceptably. When a decl is not explicitly found, is purged, or - // has an error while parsing, MakeDefault() will do a FreeData(), then a - // Parse() with DefaultDefinition(). The defaultDefintion should start with - // an open brace and end with a close brace. - virtual const char * DefaultDefinition( void ) const { return base->DefaultDefinition(); } - - // The manager will have already parsed past the type, name and opening brace. - // All necessary media will be touched before return. - // The manager will have called FreeData() before issuing a Parse(). - // The subclass can call MakeDefault() internally at any point if - // there are parse errors. - virtual bool Parse( const char *text, const int textLength ) { return base->Parse( text, textLength ); } - - // Frees any pointers held by the subclass. This may be called before - // any Parse(), so the constructor must have set sane values. The decl will be - // invalid after issuing this call, but it will always be immediately followed - // by a Parse() - virtual void FreeData( void ) { base->FreeData(); } - - // Returns the size of the decl in memory. - virtual size_t Size( void ) const { return base->Size(); } - - // If this isn't overridden, it will just print the decl name. - // The manager will have printed 7 characters on the line already, - // containing the reference state and index number. - virtual void List( void ) const { base->List(); } - - // The print function will already have dumped the text source - // and common data, subclasses can override this to dump more - // explicit data. - virtual void Print( void ) const { base->Print(); } - -public: - idDeclBase * base; -}; - - -template< class type > -ID_INLINE idDecl *idDeclAllocator( void ) { - return new type; -} - - -class idMaterial; -class idDeclSkin; -class idSoundShader; - -class idDeclManager { -public: - virtual ~idDeclManager( void ) {} - - virtual void Init( void ) = 0; - virtual void Shutdown( void ) = 0; - virtual void Reload( bool force ) = 0; - - virtual void BeginLevelLoad() = 0; - virtual void EndLevelLoad() = 0; - - // Registers a new decl type. - virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) = 0; - - // Registers a new folder with decl files. - virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) = 0; - - // Returns a checksum for all loaded decl text. - virtual int GetChecksum( void ) const = 0; - - // Returns the number of decl types. - virtual int GetNumDeclTypes( void ) const = 0; - - // Returns the type name for a decl type. - virtual const char * GetDeclNameFromType( declType_t type ) const = 0; - - // Returns the decl type for a type name. - virtual declType_t GetDeclTypeFromName( const char *typeName ) const = 0; - - // If makeDefault is true, a default decl of appropriate type will be created - // if an explicit one isn't found. If makeDefault is false, NULL will be returned - // if the decl wasn't explcitly defined. - virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ) = 0; - - virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ) = 0; - - virtual void ReloadFile( const char* filename, bool force ) = 0; - - // Returns the number of decls of the given type. - virtual int GetNumDecls( declType_t type ) = 0; - - // The complete lists of decls can be walked to populate editor browsers. - // If forceParse is set false, you can get the decl to check name / filename / etc. - // without causing it to parse the source and load media. - virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ) = 0; - - // List and print decls. - virtual void ListType( const idCmdArgs &args, declType_t type ) = 0; - virtual void PrintType( const idCmdArgs &args, declType_t type ) = 0; - - // Creates a new default decl of the given type with the given name in - // the given file used by editors to create a new decls. - virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ) = 0; - - // BSM - Added for the material editors rename capabilities - virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ) = 0; - - // When media files are loaded, a reference line can be printed at a - // proper indentation if decl_show is set - virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; - - virtual void WritePrecacheCommands( idFile *f ) = 0; - - // Convenience functions for specific types. - virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ) = 0; - virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ) = 0; - virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ) = 0; - - virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ) = 0; - virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ) = 0; - virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ) = 0; -}; - -extern idDeclManager * declManager; - - -template< declType_t type > -ID_INLINE void idListDecls_f( const idCmdArgs &args ) { - declManager->ListType( args, type ); -} - -template< declType_t type > -ID_INLINE void idPrintDecls_f( const idCmdArgs &args ) { - declManager->PrintType( args, type ); -} - -#endif /* !__DECLMANAGER_H__ */ diff --git a/framework/declparticle.h b/framework/declparticle.h deleted file mode 100644 index cbbf1ffa1..000000000 --- a/framework/declparticle.h +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLPARTICLE_H__ -#define __DECLPARTICLE_H__ - -/* -=============================================================================== - - idDeclParticle - -=============================================================================== -*/ - -class idParticleParm { -public: - idParticleParm( void ) { table = NULL; from = to = 0.0f; } - - const idDeclTable * table; - float from; - float to; - - float Eval( float frac, idRandom &rand ) const; - float Integrate( float frac, idRandom &rand ) const; -}; - - -typedef enum { - PDIST_RECT, // ( sizeX sizeY sizeZ ) - PDIST_CYLINDER, // ( sizeX sizeY sizeZ ) - PDIST_SPHERE // ( sizeX sizeY sizeZ ringFraction ) - // a ringFraction of zero allows the entire sphere, 0.9 would only - // allow the outer 10% of the sphere -} prtDistribution_t; - -typedef enum { - PDIR_CONE, // parm0 is the solid cone angle - PDIR_OUTWARD // direction is relative to offset from origin, parm0 is an upward bias -} prtDirection_t; - -typedef enum { - PPATH_STANDARD, - PPATH_HELIX, // ( sizeX sizeY sizeZ radialSpeed climbSpeed ) - PPATH_FLIES, - PPATH_ORBIT, - PPATH_DRIP -} prtCustomPth_t; - -typedef enum { - POR_VIEW, - POR_AIMED, // angle and aspect are disregarded - POR_X, - POR_Y, - POR_Z -} prtOrientation_t; - -typedef struct renderEntity_s renderEntity_t; -typedef struct renderView_s renderView_t; - -typedef struct { - const renderEntity_t * renderEnt; // for shaderParms, etc - const renderView_t * renderView; - int index; // particle number in the system - float frac; // 0.0 to 1.0 - idRandom random; - idVec3 origin; // dynamic smoke particles can have individual origins and axis - idMat3 axis; - - - float age; // in seconds, calculated as fraction * stage->particleLife - idRandom originalRandom; // needed so aimed particles can reset the random for another origin calculation - float animationFrameFrac; // set by ParticleTexCoords, used to make the cross faded version -} particleGen_t; - - -// -// single particle stage -// -class idParticleStage { -public: - idParticleStage( void ); - virtual ~idParticleStage( void ) {} - - void Default(); - virtual int NumQuadsPerParticle() const; // includes trails and cross faded animations - // returns the number of verts created, which will range from 0 to 4*NumQuadsPerParticle() - virtual int CreateParticle( particleGen_t *g, idDrawVert *verts ) const; - - void ParticleOrigin( particleGen_t *g, idVec3 &origin ) const; - int ParticleVerts( particleGen_t *g, const idVec3 origin, idDrawVert *verts ) const; - void ParticleTexCoords( particleGen_t *g, idDrawVert *verts ) const; - void ParticleColors( particleGen_t *g, idDrawVert *verts ) const; - - const char * GetCustomPathName(); - const char * GetCustomPathDesc(); - int NumCustomPathParms(); - void SetCustomPathType( const char *p ); - void operator=( const idParticleStage &src ); - - - //------------------------------ - - const idMaterial * material; - - int totalParticles; // total number of particles, although some may be invisible at a given time - float cycles; // allows things to oneShot ( 1 cycle ) or run for a set number of cycles - // on a per stage basis - - int cycleMsec; // ( particleLife + deadTime ) in msec - - float spawnBunching; // 0.0 = all come out at first instant, 1.0 = evenly spaced over cycle time - float particleLife; // total seconds of life for each particle - float timeOffset; // time offset from system start for the first particle to spawn - float deadTime; // time after particleLife before respawning - - //------------------------------- // standard path parms - - prtDistribution_t distributionType; - float distributionParms[4]; - - prtDirection_t directionType; - float directionParms[4]; - - idParticleParm speed; - float gravity; // can be negative to float up - bool worldGravity; // apply gravity in world space - bool randomDistribution; // randomly orient the quad on emission ( defaults to true ) - bool entityColor; // force color from render entity ( fadeColor is still valid ) - - //------------------------------ // custom path will completely replace the standard path calculations - - prtCustomPth_t customPathType; // use custom C code routines for determining the origin - float customPathParms[8]; - - //-------------------------------- - - idVec3 offset; // offset from origin to spawn all particles, also applies to customPath - - int animationFrames; // if > 1, subdivide the texture S axis into frames and crossfade - float animationRate; // frames per second - - float initialAngle; // in degrees, random angle is used if zero ( default ) - idParticleParm rotationSpeed; // half the particles will have negative rotation speeds - - prtOrientation_t orientation; // view, aimed, or axis fixed - float orientationParms[4]; - - idParticleParm size; - idParticleParm aspect; // greater than 1 makes the T axis longer - - idVec4 color; - idVec4 fadeColor; // either 0 0 0 0 for additive, or 1 1 1 0 for blended materials - float fadeInFraction; // in 0.0 to 1.0 range - float fadeOutFraction; // in 0.0 to 1.0 range - float fadeIndexFraction; // in 0.0 to 1.0 range, causes later index smokes to be more faded - - bool hidden; // for editor use - //----------------------------------- - - float boundsExpansion; // user tweak to fix poorly calculated bounds - - idBounds bounds; // derived -}; - - -// -// group of particle stages -// -class idDeclParticle : public idDecl { -public: - - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - - bool Save( const char *fileName = NULL ); - - idListstages; - idBounds bounds; - float depthHack; - -private: - bool RebuildTextSource( void ); - void GetStageBounds( idParticleStage *stage ); - idParticleStage * ParseParticleStage( idLexer &src ); - void ParseParms( idLexer &src, float *parms, int maxParms ); - void ParseParametric( idLexer &src, idParticleParm *parm ); - void WriteStage( idFile *f, idParticleStage *stage ); - void WriteParticleParm( idFile *f, idParticleParm *parm, const char *name ); -}; - -#endif /* !__DECLPARTICLE_H__ */ diff --git a/framework/declskin.h b/framework/declskin.h deleted file mode 100644 index 0bc603301..000000000 --- a/framework/declskin.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLSKIN_H__ -#define __DECLSKIN_H__ - -/* -=============================================================================== - - idDeclSkin - -=============================================================================== -*/ - -typedef struct { - const idMaterial * from; // 0 == any unmatched shader - const idMaterial * to; -} skinMapping_t; - -class idDeclSkin : public idDecl { -public: - virtual size_t Size( void ) const; - virtual bool SetDefaultText( void ); - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - - const idMaterial * RemapShaderBySkin( const idMaterial *shader ) const; - - // model associations are just for the preview dialog in the editor - const int GetNumModelAssociations() const; - const char * GetAssociatedModel( int index ) const; - -private: - idList mappings; - idStrList associatedModels; -}; - -#endif /* !__DECLSKIN_H__ */ diff --git a/framework/decltable.h b/framework/decltable.h deleted file mode 100644 index 6f821a841..000000000 --- a/framework/decltable.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DECLTABLE_H__ -#define __DECLTABLE_H__ - -/* -=============================================================================== - - tables are used to map a floating point input value to a floating point - output value, with optional wrap / clamp and interpolation - -=============================================================================== -*/ - -class idDeclTable : public idDecl { -public: - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - - float TableLookup( float index ) const; - -private: - bool clamp; - bool snap; - idList values; -}; - -#endif /* !__DECLTABLE_H__ */ diff --git a/framework/file.h b/framework/file.h deleted file mode 100644 index bd6b929e7..000000000 --- a/framework/file.h +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FILE_H__ -#define __FILE_H__ - -/* -============================================================== - - File Streams. - -============================================================== -*/ - -// mode parm for Seek -typedef enum { - FS_SEEK_CUR, - FS_SEEK_END, - FS_SEEK_SET -} fsOrigin_t; - -class idFileSystemLocal; - - -class idFile { -public: - virtual ~idFile( void ) {}; - // Get the name of the file. - virtual const char * GetName( void ); - // Get the full file path. - virtual const char * GetFullPath( void ); - // Read data from the file to the buffer. - virtual int Read( void *buffer, int len ); - // Write data from the buffer to the file. - virtual int Write( const void *buffer, int len ); - // Returns the length of the file. - virtual int Length( void ); - // Return a time value for reload operations. - virtual unsigned int Timestamp( void ); - // Returns offset in file. - virtual int Tell( void ); - // Forces flush on files being writting to. - virtual void ForceFlush( void ); - // Causes any buffered data to be written to the file. - virtual void Flush( void ); - // Seek on a file. - virtual int Seek( long offset, fsOrigin_t origin ); - // Go back to the beginning of the file. - virtual void Rewind( void ); - // Like fprintf. - virtual int Printf( const char *fmt, ... ) id_attribute((format(printf,2,3))); - // Like fprintf but with argument pointer - virtual int VPrintf( const char *fmt, va_list arg ); - // Write a string with high precision floating point numbers to the file. - virtual int WriteFloatString( const char *fmt, ... ) id_attribute((format(printf,2,3))); - - // Endian portable alternatives to Read(...) - virtual int ReadInt( int &value ); - virtual int ReadUnsignedInt( unsigned int &value ); - virtual int ReadShort( short &value ); - virtual int ReadUnsignedShort( unsigned short &value ); - virtual int ReadChar( char &value ); - virtual int ReadUnsignedChar( unsigned char &value ); - virtual int ReadFloat( float &value ); - virtual int ReadBool( bool &value ); - virtual int ReadString( idStr &string ); - virtual int ReadVec2( idVec2 &vec ); - virtual int ReadVec3( idVec3 &vec ); - virtual int ReadVec4( idVec4 &vec ); - virtual int ReadVec6( idVec6 &vec ); - virtual int ReadMat3( idMat3 &mat ); - - // Endian portable alternatives to Write(...) - virtual int WriteInt( const int value ); - virtual int WriteUnsignedInt( const unsigned int value ); - virtual int WriteShort( const short value ); - virtual int WriteUnsignedShort( unsigned short value ); - virtual int WriteChar( const char value ); - virtual int WriteUnsignedChar( const unsigned char value ); - virtual int WriteFloat( const float value ); - virtual int WriteBool( const bool value ); - virtual int WriteString( const char *string ); - virtual int WriteVec2( const idVec2 &vec ); - virtual int WriteVec3( const idVec3 &vec ); - virtual int WriteVec4( const idVec4 &vec ); - virtual int WriteVec6( const idVec6 &vec ); - virtual int WriteMat3( const idMat3 &mat ); -}; - - -class idFile_Memory : public idFile { - friend class idFileSystemLocal; - -public: - idFile_Memory( void ); // file for writing without name - idFile_Memory( const char *name ); // file for writing - idFile_Memory( const char *name, char *data, int length ); // file for writing - idFile_Memory( const char *name, const char *data, int length ); // file for reading - virtual ~idFile_Memory( void ); - - virtual const char * GetName( void ) { return name.c_str(); } - virtual const char * GetFullPath( void ) { return name.c_str(); } - virtual int Read( void *buffer, int len ); - virtual int Write( const void *buffer, int len ); - virtual int Length( void ); - virtual unsigned int Timestamp( void ); - virtual int Tell( void ); - virtual void ForceFlush( void ); - virtual void Flush( void ); - virtual int Seek( long offset, fsOrigin_t origin ); - - // changes memory file to read only - virtual void MakeReadOnly( void ); - // clear the file - virtual void Clear( bool freeMemory = true ); - // set data for reading - void SetData( const char *data, int length ); - // returns const pointer to the memory buffer - const char * GetDataPtr( void ) const { return filePtr; } - // set the file granularity - void SetGranularity( int g ) { assert( g > 0 ); granularity = g; } - -private: - idStr name; // name of the file - int mode; // open mode - int maxSize; // maximum size of file - int fileSize; // size of the file - int allocated; // allocated size - int granularity; // file granularity - char * filePtr; // buffer holding the file data - char * curPtr; // current read/write pointer -}; - - -class idFile_BitMsg : public idFile { - friend class idFileSystemLocal; - -public: - idFile_BitMsg( idBitMsg &msg ); - idFile_BitMsg( const idBitMsg &msg ); - virtual ~idFile_BitMsg( void ); - - virtual const char * GetName( void ) { return name.c_str(); } - virtual const char * GetFullPath( void ) { return name.c_str(); } - virtual int Read( void *buffer, int len ); - virtual int Write( const void *buffer, int len ); - virtual int Length( void ); - virtual unsigned int Timestamp( void ); - virtual int Tell( void ); - virtual void ForceFlush( void ); - virtual void Flush( void ); - virtual int Seek( long offset, fsOrigin_t origin ); - -private: - idStr name; // name of the file - int mode; // open mode - idBitMsg * msg; -}; - - -class idFile_Permanent : public idFile { - friend class idFileSystemLocal; - -public: - idFile_Permanent( void ); - virtual ~idFile_Permanent( void ); - - virtual const char * GetName( void ) { return name.c_str(); } - virtual const char * GetFullPath( void ) { return fullPath.c_str(); } - virtual int Read( void *buffer, int len ); - virtual int Write( const void *buffer, int len ); - virtual int Length( void ); - virtual unsigned int Timestamp( void ); - virtual int Tell( void ); - virtual void ForceFlush( void ); - virtual void Flush( void ); - virtual int Seek( long offset, fsOrigin_t origin ); - - // returns file pointer - FILE * GetFilePtr( void ) { return o; } - -private: - idStr name; // relative path of the file - relative path - idStr fullPath; // full file path - OS path - int mode; // open mode - int fileSize; // size of the file - FILE * o; // file handle - bool handleSync; // true if written data is immediately flushed -}; - - -class idFile_InZip : public idFile { - friend class idFileSystemLocal; - -public: - idFile_InZip( void ); - virtual ~idFile_InZip( void ); - - virtual const char * GetName( void ) { return name.c_str(); } - virtual const char * GetFullPath( void ) { return fullPath.c_str(); } - virtual int Read( void *buffer, int len ); - virtual int Write( const void *buffer, int len ); - virtual int Length( void ); - virtual unsigned int Timestamp( void ); - virtual int Tell( void ); - virtual void ForceFlush( void ); - virtual void Flush( void ); - virtual int Seek( long offset, fsOrigin_t origin ); - -private: - idStr name; // name of the file in the pak - idStr fullPath; // full file path including pak file name - int zipFilePos; // zip file info position in pak - int fileSize; // size of the file - void * z; // unzip info -}; - -#endif /* !__FILE_H__ */ diff --git a/framework/filesystem.h b/framework/filesystem.h deleted file mode 100644 index 2b11935a9..000000000 --- a/framework/filesystem.h +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FILESYSTEM_H__ -#define __FILESYSTEM_H__ - -/* -=============================================================================== - - File System - - No stdio calls should be used by any part of the game, because of all sorts - of directory and separator char issues. Throughout the game a forward slash - should be used as a separator. The file system takes care of the conversion - to an OS specific separator. The file system treats all file and directory - names as case insensitive. - - The following cvars store paths used by the file system: - - "fs_basepath" path to local install, read-only - "fs_savepath" path to config, save game, etc. files, read & write - "fs_cdpath" path to cd, read-only - "fs_devpath" path to files created during development, read & write - - The base path for file saving can be set to "fs_savepath" or "fs_devpath". - -=============================================================================== -*/ - -static const unsigned FILE_NOT_FOUND_TIMESTAMP = 0xFFFFFFFF; -static const int MAX_PURE_PAKS = 128; -static const int MAX_OSPATH = 256; - -// modes for OpenFileByMode. used as bit mask internally -typedef enum { - FS_READ = 0, - FS_WRITE = 1, - FS_APPEND = 2 -} fsMode_t; - -typedef enum { - PURE_OK, // we are good to connect as-is - PURE_RESTART, // restart required - PURE_MISSING, // pak files missing on the client - PURE_NODLL // no DLL could be extracted -} fsPureReply_t; - -typedef enum { - DLTYPE_URL, - DLTYPE_FILE -} dlType_t; - -typedef enum { - DL_WAIT, // waiting in the list for beginning of the download - DL_INPROGRESS, // in progress - DL_DONE, // download completed, success - DL_ABORTING, // this one can be set during a download, it will force the next progress callback to abort - then will go to DL_FAILED - DL_FAILED -} dlStatus_t; - -typedef enum { - FILE_EXEC, - FILE_OPEN -} dlMime_t; - -typedef enum { - FIND_NO, - FIND_YES, - FIND_ADDON -} findFile_t; - -typedef struct urlDownload_s { - idStr url; - char dlerror[ MAX_STRING_CHARS ]; - int dltotal; - int dlnow; - int dlstatus; - dlStatus_t status; -} urlDownload_t; - -typedef struct fileDownload_s { - int position; - int length; - void * buffer; -} fileDownload_t; - -typedef struct backgroundDownload_s { - struct backgroundDownload_s *next; // set by the fileSystem - dlType_t opcode; - idFile * f; - fileDownload_t file; - urlDownload_t url; - volatile bool completed; -} backgroundDownload_t; - -// file list for directory listings -class idFileList { - friend class idFileSystemLocal; -public: - const char * GetBasePath( void ) const { return basePath; } - int GetNumFiles( void ) const { return list.Num(); } - const char * GetFile( int index ) const { return list[index]; } - const idStrList & GetList( void ) const { return list; } - -private: - idStr basePath; - idStrList list; -}; - -// mod list -class idModList { - friend class idFileSystemLocal; -public: - int GetNumMods( void ) const { return mods.Num(); } - const char * GetMod( int index ) const { return mods[index]; } - const char * GetDescription( int index ) const { return descriptions[index]; } - -private: - idStrList mods; - idStrList descriptions; -}; - -class idFileSystem { -public: - virtual ~idFileSystem() {} - // Initializes the file system. - virtual void Init( void ) = 0; - // Restarts the file system. - virtual void Restart( void ) = 0; - // Shutdown the file system. - virtual void Shutdown( bool reloading ) = 0; - // Returns true if the file system is initialized. - virtual bool IsInitialized( void ) const = 0; - // Returns true if we are doing an fs_copyfiles. - virtual bool PerformingCopyFiles( void ) const = 0; - // Returns a list of mods found along with descriptions - // 'mods' contains the directory names to be passed to fs_game - // 'descriptions' contains a free form string to be used in the UI - virtual idModList * ListMods( void ) = 0; - // Frees the given mod list - virtual void FreeModList( idModList *modList ) = 0; - // Lists files with the given extension in the given directory. - // Directory should not have either a leading or trailing '/' - // The returned files will not include any directories or '/' unless fullRelativePath is set. - // The extension must include a leading dot and may not contain wildcards. - // If extension is "/", only subdirectories will be returned. - virtual idFileList * ListFiles( const char *relativePath, const char *extension, bool sort = false, bool fullRelativePath = false, const char* gamedir = NULL ) = 0; - // Lists files in the given directory and all subdirectories with the given extension. - // Directory should not have either a leading or trailing '/' - // The returned files include a full relative path. - // The extension must include a leading dot and may not contain wildcards. - virtual idFileList * ListFilesTree( const char *relativePath, const char *extension, bool sort = false, const char* gamedir = NULL ) = 0; - // Frees the given file list. - virtual void FreeFileList( idFileList *fileList ) = 0; - // Converts a relative path to a full OS path. - virtual const char * OSPathToRelativePath( const char *OSPath ) = 0; - // Converts a full OS path to a relative path. - virtual const char * RelativePathToOSPath( const char *relativePath, const char *basePath = "fs_devpath" ) = 0; - // Builds a full OS path from the given components. - virtual const char * BuildOSPath( const char *base, const char *game, const char *relativePath ) = 0; - // Creates the given OS path for as far as it doesn't exist already. - virtual void CreateOSPath( const char *OSPath ) = 0; - // Returns true if a file is in a pak file. - virtual bool FileIsInPAK( const char *relativePath ) = 0; - // Returns a space separated string containing the checksums of all referenced pak files. - // will call SetPureServerChecksums internally to restrict itself - virtual void UpdatePureServerChecksums( void ) = 0; - // setup the mapping of OS -> game pak checksum - virtual bool UpdateGamePakChecksums( void ) = 0; - // 0-terminated list of pak checksums - // if pureChecksums[ 0 ] == 0, all data sources will be allowed - // otherwise, only pak files that match one of the checksums will be checked for files - // with the sole exception of .cfg files. - // the function tries to configure pure mode from the paks already referenced and this new list - // it returns whether the switch was successfull, and sets the missing checksums - // the process is verbosive when fs_debug 1 - virtual fsPureReply_t SetPureServerChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum, int missingChecksums[ MAX_PURE_PAKS ], int *missingGamePakChecksum ) = 0; - // fills a 0-terminated list of pak checksums for a client - // if OS is -1, give the current game pak checksum. if >= 0, lookup the game pak table (server only) - virtual void GetPureServerChecksums( int checksums[ MAX_PURE_PAKS ], int OS, int *gamePakChecksum ) = 0; - // before doing a restart, force the pure list and the search order - // if the given checksum list can't be completely processed and set, will error out - virtual void SetRestartChecksums( const int pureChecksums[ MAX_PURE_PAKS ], int gamePakChecksum ) = 0; - // equivalent to calling SetPureServerChecksums with an empty list - virtual void ClearPureChecksums( void ) = 0; - // get a mask of supported OSes. if not pure, returns -1 - virtual int GetOSMask( void ) = 0; - // Reads a complete file. - // Returns the length of the file, or -1 on failure. - // A null buffer will just return the file length without loading. - // A null timestamp will be ignored. - // As a quick check for existance. -1 length == not present. - // A 0 byte will always be appended at the end, so string ops are safe. - // The buffer should be considered read-only, because it may be cached for other uses. - virtual int ReadFile( const char *relativePath, void **buffer, unsigned *timestamp = NULL ) = 0; - // Frees the memory allocated by ReadFile. - virtual void FreeFile( void *buffer ) = 0; - // Writes a complete file, will create any needed subdirectories. - // Returns the length of the file, or -1 on failure. - virtual int WriteFile( const char *relativePath, const void *buffer, int size, const char *basePath = "fs_savepath" ) = 0; - // Removes the given file. - virtual void RemoveFile( const char *relativePath ) = 0; - // Opens a file for reading. - virtual idFile * OpenFileRead( const char *relativePath, bool allowCopyFiles = true, const char* gamedir = NULL ) = 0; - // Opens a file for writing, will create any needed subdirectories. - virtual idFile * OpenFileWrite( const char *relativePath, const char *basePath = "fs_savepath" ) = 0; - // Opens a file for writing at the end. - virtual idFile * OpenFileAppend( const char *filename, bool sync = false, const char *basePath = "fs_basepath" ) = 0; - // Opens a file for reading, writing, or appending depending on the value of mode. - virtual idFile * OpenFileByMode( const char *relativePath, fsMode_t mode ) = 0; - // Opens a file for reading from a full OS path. - virtual idFile * OpenExplicitFileRead( const char *OSPath ) = 0; - // Opens a file for writing to a full OS path. - virtual idFile * OpenExplicitFileWrite( const char *OSPath ) = 0; - // Closes a file. - virtual void CloseFile( idFile *f ) = 0; - // Returns immediately, performing the read from a background thread. - virtual void BackgroundDownload( backgroundDownload_t *bgl ) = 0; - // resets the bytes read counter - virtual void ResetReadCount( void ) = 0; - // retrieves the current read count - virtual int GetReadCount( void ) = 0; - // adds to the read count - virtual void AddToReadCount( int c ) = 0; - // look for a dynamic module - virtual void FindDLL( const char *basename, char dllPath[ MAX_OSPATH ], bool updateChecksum ) = 0; - // case sensitive filesystems use an internal directory cache - // the cache is cleared when calling OpenFileWrite and RemoveFile - // in some cases you may need to use this directly - virtual void ClearDirCache( void ) = 0; - - // is D3XP installed? even if not running it atm - virtual bool HasD3XP( void ) = 0; - // are we using D3XP content ( through a real d3xp run or through a double mod ) - virtual bool RunningD3XP( void ) = 0; - - // don't use for large copies - allocates a single memory block for the copy - virtual void CopyFile( const char *fromOSPath, const char *toOSPath ) = 0; - - // lookup a relative path, return the size or 0 if not found - virtual int ValidateDownloadPakForChecksum( int checksum, char path[ MAX_STRING_CHARS ], bool isGamePak ) = 0; - - virtual idFile * MakeTemporaryFile( void ) = 0; - - // make downloaded pak files known so pure negociation works next time - virtual int AddZipFile( const char *path ) = 0; - - // look for a file in the loaded paks or the addon paks - // if the file is found in addons, FS's internal structures are ready for a reloadEngine - virtual findFile_t FindFile( const char *path, bool scheduleAddons = false ) = 0; - - // get map/addon decls and take into account addon paks that are not on the search list - // the decl 'name' is in the "path" entry of the dict - virtual int GetNumMaps() = 0; - virtual const idDict * GetMapDecl( int i ) = 0; - virtual void FindMapScreenshot( const char *path, char *buf, int len ) = 0; - - // ignore case and seperator char distinctions - virtual bool FilenameCompare( const char *s1, const char *s2 ) const = 0; -}; - -extern idFileSystem * fileSystem; - -#endif /* !__FILESYSTEM_H__ */ diff --git a/framework/licensee.h b/framework/licensee.h deleted file mode 100644 index 1300cb1a3..000000000 --- a/framework/licensee.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -/* -=============================================================================== - - Definitions for information that is related to a licensee's game name and location. - -=============================================================================== -*/ - -#define GAME_NAME "DOOM 3" // appears on window titles and errors - -#define ENGINE_VERSION "DOOM 1.3" // printed in console - -// paths -#define CD_BASEDIR "Doom" -#ifdef ID_DEMO_BUILD - #define BASE_GAMEDIR "demo" -#else - #define BASE_GAMEDIR "base" -#endif - -// filenames -#define CD_EXE "doom.exe" -#define CONFIG_FILE "DoomConfig.cfg" - -// base folder where the source code lives -#define SOURCE_CODE_BASE_FOLDER "neo" - - -// default idnet host address -#ifndef IDNET_HOST - #define IDNET_HOST "idnet.ua-corp.com" -#endif - -// default idnet master port -#ifndef IDNET_MASTER_PORT - #define IDNET_MASTER_PORT "27650" -#endif - -// default network server port -#ifndef PORT_SERVER - #define PORT_SERVER 27666 -#endif - -// broadcast scan this many ports after PORT_SERVER so a single machine can run multiple servers -#define NUM_SERVER_PORTS 4 - -// see ASYNC_PROTOCOL_VERSION -// use a different major for each game -#define ASYNC_PROTOCOL_MAJOR 1 - -// Savegame Version -// Update when you can no longer maintain compatibility with previous savegames -// NOTE: a seperate core savegame version and game savegame version could be useful -// 16: Doom v1.1 -// 17: Doom v1.2 / D3XP. Can still read old v16 with defaults for new data -#define SAVEGAME_VERSION 17 - -// <= Doom v1.1: 1. no DS_VERSION token ( default ) -// Doom v1.2: 2 -#define RENDERDEMO_VERSION 2 - -// editor info -#define EDITOR_DEFAULT_PROJECT "doom.qe4" -#define EDITOR_REGISTRY_KEY "DOOMRadiant" -#define EDITOR_WINDOWTEXT "DOOMEdit" - -// win32 info -#define WIN32_CONSOLE_CLASS "DOOM 3 WinConsole" -#define WIN32_WINDOW_CLASS_NAME "DOOM3" -#define WIN32_FAKE_WINDOW_CLASS_NAME "DOOM3_WGL_FAKE" - -// Linux info -#ifdef ID_DEMO_BUILD - #define LINUX_DEFAULT_PATH "/usr/local/games/doom3-demo" -#else - #define LINUX_DEFAULT_PATH "/usr/local/games/doom3" -#endif - -// CD Key file info -// goes into BASE_GAMEDIR whatever the fs_game is set to -// two distinct files for easier win32 installer job -#define CDKEY_FILE "doomkey" -#define XPKEY_FILE "xpkey" -#define CDKEY_TEXT "\n// Do not give this file to ANYONE.\n" \ - "// id Software and Activision will NOT ask you to send this file to them.\n" - -#define CONFIG_SPEC "config.spec" - diff --git a/framework/usercmdgen.h b/framework/usercmdgen.h deleted file mode 100644 index eff8a86de..000000000 --- a/framework/usercmdgen.h +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __USERCMDGEN_H__ -#define __USERCMDGEN_H__ - -/* -=============================================================================== - - Samples a set of user commands from player input. - -=============================================================================== -*/ - -const int USERCMD_HZ = 60; // 60 frames per second -const int USERCMD_MSEC = 1000 / USERCMD_HZ; - -// ButtonState inputs; originally from UsercmdGen.cpp, left out of SDK by accident -// sourced from http://www.doom3world.org/phpbb2/viewtopic.php?f=26&t=18587&p=170143 -typedef enum { - UB_NONE, - - UB_UP, - UB_DOWN, - UB_LEFT, - UB_RIGHT, - UB_FORWARD, - UB_BACK, - UB_LOOKUP, - UB_LOOKDOWN, - UB_STRAFE, - UB_MOVELEFT, - UB_MOVERIGHT, - - UB_BUTTON0, - UB_BUTTON1, - UB_BUTTON2, - UB_BUTTON3, - UB_BUTTON4, - UB_BUTTON5, - UB_BUTTON6, - UB_BUTTON7, - - UB_ATTACK, - UB_SPEED, - UB_ZOOM, - UB_SHOWSCORES, - UB_MLOOK, - -#ifdef QUAKE4 - UB_INGAMESTATS, - UB_VOICECHAT, - UB_TOURNEY, -#endif//QUAKE4 - - UB_IMPULSE0, - UB_IMPULSE1, - UB_IMPULSE2, - UB_IMPULSE3, - UB_IMPULSE4, - UB_IMPULSE5, - UB_IMPULSE6, - UB_IMPULSE7, - UB_IMPULSE8, - UB_IMPULSE9, - UB_IMPULSE10, - UB_IMPULSE11, - UB_IMPULSE12, - UB_IMPULSE13, - UB_IMPULSE14, - UB_IMPULSE15, - UB_IMPULSE16, - UB_IMPULSE17, - UB_IMPULSE18, - UB_IMPULSE19, - UB_IMPULSE20, - UB_IMPULSE21, - UB_IMPULSE22, - UB_IMPULSE23, - UB_IMPULSE24, - UB_IMPULSE25, - UB_IMPULSE26, - UB_IMPULSE27, - UB_IMPULSE28, - UB_IMPULSE29, - UB_IMPULSE30, - UB_IMPULSE31, - UB_IMPULSE32, - UB_IMPULSE33, - UB_IMPULSE34, - UB_IMPULSE35, - UB_IMPULSE36, - UB_IMPULSE37, - UB_IMPULSE38, - UB_IMPULSE39, - UB_IMPULSE40, - UB_IMPULSE41, - UB_IMPULSE42, - UB_IMPULSE43, - UB_IMPULSE44, - UB_IMPULSE45, - UB_IMPULSE46, - UB_IMPULSE47, - UB_IMPULSE48, - UB_IMPULSE49, - UB_IMPULSE50, - UB_IMPULSE51, - UB_IMPULSE52, - UB_IMPULSE53, - UB_IMPULSE54, - UB_IMPULSE55, - UB_IMPULSE56, - UB_IMPULSE57, - UB_IMPULSE58, - UB_IMPULSE59, - UB_IMPULSE60, - UB_IMPULSE61, - UB_IMPULSE62, - UB_IMPULSE63, - - UB_MAX_BUTTONS -} UserCmdButton; - - -// usercmd_t->button bits -const int BUTTON_ATTACK = BIT(0); -const int BUTTON_RUN = BIT(1); -const int BUTTON_ZOOM = BIT(2); -const int BUTTON_SCORES = BIT(3); -const int BUTTON_MLOOK = BIT(4); -const int BUTTON_5 = BIT(5); -const int BUTTON_6 = BIT(6); -const int BUTTON_7 = BIT(7); - -// usercmd_t->impulse commands -enum { - IMPULSE_0, - IMPULSE_1, - IMPULSE_2, - IMPULSE_3, - IMPULSE_4, - IMPULSE_5, - IMPULSE_6, - IMPULSE_7, - IMPULSE_8, - IMPULSE_9, - IMPULSE_10, - IMPULSE_11, - IMPULSE_12, - IMPULSE_13, - IMPULSE_14, - IMPULSE_15, - IMPULSE_16, - IMPULSE_17, - IMPULSE_18, - IMPULSE_19, - IMPULSE_20, - IMPULSE_21, - IMPULSE_22, - IMPULSE_23, - IMPULSE_24, - IMPULSE_25, - IMPULSE_26, - IMPULSE_27, - IMPULSE_28, - IMPULSE_29, - IMPULSE_40 = 40, - IMPULSE_41, - IMPULSE_42, - IMPULSE_43, - IMPULSE_44, - IMPULSE_45, - IMPULSE_46, - IMPULSE_47, - IMPULSE_48, - IMPULSE_49, - IMPULSE_50, - IMPULSE_51, - IMPULSE_52, - IMPULSE_MAX -}; - -/* -const int IMPULSE_0 = 0; // weap 0 -const int IMPULSE_1 = 1; // weap 1 -const int IMPULSE_2 = 2; // weap 2 -const int IMPULSE_3 = 3; // weap 3 -const int IMPULSE_4 = 4; // weap 4 -const int IMPULSE_5 = 5; // weap 5 -const int IMPULSE_6 = 6; // weap 6 -const int IMPULSE_7 = 7; // weap 7 -const int IMPULSE_8 = 8; // weap 8 -const int IMPULSE_9 = 9; // weap 9 -const int IMPULSE_10 = 10; // weap 10 -const int IMPULSE_11 = 11; // weap 11 -const int IMPULSE_12 = 12; // weap 12 -const int IMPULSE_13 = 13; // weap reload -const int IMPULSE_14 = 14; // weap next -const int IMPULSE_15 = 15; // weap prev -const int IMPULSE_16 = 16; // -const int IMPULSE_17 = 17; // ready to play ( toggles ui_ready ) -const int IMPULSE_18 = 18; // center view -const int IMPULSE_19 = 19; // show PDA/INV/MAP -const int IMPULSE_20 = 20; // toggle team ( toggles ui_team ) -const int IMPULSE_21 = 21; // -const int IMPULSE_22 = 22; // spectate -const int IMPULSE_23 = 23; // -const int IMPULSE_24 = 24; // -const int IMPULSE_25 = 25; // -const int IMPULSE_26 = 26; // -const int IMPULSE_27 = 27; // -const int IMPULSE_28 = 28; // vote yes -const int IMPULSE_29 = 29; // vote no -const int IMPULSE_40 = 40; // use vehicle -const int IMPULSE_41 = 41; // TDM Use/Frob key -const int IMPULSE_42 = 42; // Inventory prev (unused) -const int IMPULSE_43 = 43; // Inventory next (unused) -const int IMPULSE_44 = 44; // Lean forward -const int IMPULSE_45 = 45; // Lean left -const int IMPULSE_46 = 46; // Lean right -const int IMPULSE_47 = 47; // Inventory prev item -const int IMPULSE_48 = 48; // Inventory next item -const int IMPULSE_49 = 49; // Inventory prev group -const int IMPULSE_50 = 50; // Inventory next group -const int IMPULSE_51 = 51; // Inventory use item -const int IMPULSE_52 = 52; // Inventory drop item -*/ - -// Darkmod: Added as a baseoffset for the impulse keys, when used with ButtonState. -// This function requires an int as input which defines the key that should be used, -// and it looks as if the first impulse starts with the number 25. -const int IMPULSE_BUTTON_BASE = 25; -#define KEY_FROM_IMPULSE(n) (n + IMPULSE_BUTTON_BASE) - -// usercmd_t->flags -const int UCF_IMPULSE_SEQUENCE = 0x0001; // toggled every time an impulse command is sent - -class usercmd_t { -public: - int gameFrame; // frame number - int gameTime; // game time - int duplicateCount; // duplication count for networking - byte buttons; // buttons - signed char forwardmove; // forward/backward movement - signed char rightmove; // left/right movement - signed char upmove; // up/down movement - short angles[3]; // view angles - short mx; // mouse delta x - short my; // mouse delta y - signed char impulse; // impulse command - byte flags; // additional flags - int sequence; // just for debugging - -public: - void ByteSwap(); // on big endian systems, byte swap the shorts and ints - bool operator==( const usercmd_t &rhs ) const; -}; - -typedef enum { - INHIBIT_SESSION = 0, - INHIBIT_ASYNC -} inhibit_t; - -const int MAX_BUFFERED_USERCMD = 64; - -class idUsercmdGen { -public: - virtual ~idUsercmdGen( void ) {} - - // Sets up all the cvars and console commands. - virtual void Init( void ) = 0; - - // Prepares for a new map. - virtual void InitForNewMap( void ) = 0; - - // Shut down. - virtual void Shutdown( void ) = 0; - - // Clears all key states and face straight. - virtual void Clear( void ) = 0; - - // Clears view angles. - virtual void ClearAngles( void ) = 0; - - // When the console is down or the menu is up, only emit default usercmd, so the player isn't moving around. - // Each subsystem (session and game) may want an inhibit will OR the requests. - virtual void InhibitUsercmd( inhibit_t subsystem, bool inhibit ) = 0; - - // Returns a buffered command for the given game tic. - virtual usercmd_t TicCmd( int ticNumber ) = 0; - - // Called async at regular intervals. - virtual void UsercmdInterrupt( void ) = 0; - - // Set a value that can safely be referenced by UsercmdInterrupt() for each key binding. - virtual int CommandStringUsercmdData( const char *cmdString ) = 0; - - // Returns the number of user commands. - virtual int GetNumUserCommands( void ) = 0; - - // Returns the name of a user command via index. - virtual const char *GetUserCommandName( int index ) = 0; - - // Continuously modified, never reset. For full screen guis. - virtual void MouseState( int *x, int *y, int *button, bool *down ) = 0; - - // Directly sample a button. - virtual int ButtonState( int key ) = 0; - - // Directly sample a keystate. - virtual int KeyState( int key ) = 0; - - // Directly sample a usercmd. - virtual usercmd_t GetDirectUsercmd( void ) = 0; -}; - -extern idUsercmdGen *usercmdGen; - -#endif /* !__USERCMDGEN_H__ */ diff --git a/game.vcxproj b/game.vcxproj new file mode 100644 index 000000000..9eaf6bb50 --- /dev/null +++ b/game.vcxproj @@ -0,0 +1,700 @@ + + + + + Debug with inlines and memory log + Win32 + + + Debug with inlines + Win32 + + + Debug + Win32 + + + Dedicated Debug with inlines + Win32 + + + Dedicated Debug + Win32 + + + Dedicated Release + Win32 + + + Release + Win32 + + + + Game + {49BEC5C6-B964-417A-851E-808886B57430} + Game + + + + + + + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {49bec5c6-b964-417a-851e-808886b57400} + false + + + {6ea6406f-3e65-47d9-8246-d6660a81606f} + false + + + + + + + + + \ No newline at end of file diff --git a/game.vcxproj.filters b/game.vcxproj.filters new file mode 100644 index 000000000..8ed3ec9a3 --- /dev/null +++ b/game.vcxproj.filters @@ -0,0 +1,1238 @@ + + + + + {108fbdc3-00d4-4eba-8472-d04fcb45c4a1} + + + {e082d659-8d8e-49f5-ba1c-c12c9bb124d6} + + + {5c609656-a903-420e-9f5a-95dc0091f307} + + + {bf06073d-3e0f-4e0a-9acf-43c6e35a9af7} + + + {6dddfc49-4250-4d4d-8afc-d680ac207aaa} + + + {676b45b0-bae1-40ec-8817-7cd24459a7e7} + + + {196735aa-adbe-4993-b5a2-4cefa0c636d3} + + + {ad7de883-accf-42d3-900d-77cd24ee0486} + + + {794c4ee6-8dcb-48dc-9cd6-d55662e55374} + + + {1a59af1a-408f-40aa-8f50-e5694e59fd05} + + + {20350817-ee98-43f0-ba78-54231c8a55ff} + + + {96bec94a-1e7a-43e5-a9b9-df4a2ae4f76c} + + + {8d28a139-1856-4077-a734-36bbbb7b4cb9} + + + {6c33ed16-7d0d-497b-ae02-75d700056200} + + + {690e9078-025b-40a2-80b0-78b02000b24b} + + + {d93297dd-dff7-49a7-8b6f-605020816b18} + + + {c90266c6-9d15-4d7f-90fc-ef4110afd506} + + + {725808e1-e9e4-4915-b000-538e57816d78} + + + {a614826b-3fce-443f-a6e9-f7b14c71125e} + + + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\EAS + + + AI\EAS + + + AI\EAS + + + AI\Conversation + + + AI\Conversation + + + AI\Conversation + + + Http + + + Http + + + Inventory + + + Inventory + + + Inventory + + + Inventory + + + Missions + + + Missions + + + Missions + + + Missions + + + Missions + + + Missions + + + ZipLoader + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + sourcehook + + + Shop + + + Shop + + + Shop + + + randomizer + + + randomizer + + + randomizer + + + randomizer + + + randomizer + + + pugixml + + + pugixml + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Inventory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + Anim + + + Anim + + + Anim + + + Anim + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Script + + + Script + + + Script + + + Script + + + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\Tasks + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\States + + + AI\EAS + + + AI\EAS + + + AI\EAS + + + AI\EAS + + + AI\EAS + + + AI\Conversation + + + AI\Conversation + + + AI\Conversation + + + Http + + + Http + + + Inventory + + + Inventory + + + Inventory + + + Inventory + + + Inventory + + + Missions + + + Missions + + + Missions + + + Missions + + + Missions + + + Missions + + + ZipLoader + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + StimResponse + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + sourcehook + + + Shop + + + Shop + + + Shop + + + randomizer + + + randomizer + + + randomizer + + + pugixml + + + pugixml + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Objectives + + + Inventory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + AI + + + Anim + + + Anim + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + GameSys + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Physics + + + Script + + + Script + + + Script + + + Script + + + + + + \ No newline at end of file diff --git a/game/AF.cpp b/game/AF.cpp new file mode 100644 index 000000000..90c101906 --- /dev/null +++ b/game/AF.cpp @@ -0,0 +1,1402 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + + +/* +=============================================================================== + + Articulated figure controller. + +=============================================================================== +*/ +#define ARTICULATED_FIGURE_ANIM "af_pose" +#define POSE_BOUNDS_EXPANSION 5.0f + +/* +================ +idAF::idAF +================ +*/ +idAF::idAF( void ) { + self = NULL; + animator = NULL; + modifiedAnim = 0; + baseOrigin.Zero(); + baseAxis.Identity(); + poseTime = -1; + restStartTime = -1; + isLoaded = false; + isActive = false; + hasBindConstraints = false; +} + +/* +================ +idAF::~idAF +================ +*/ +idAF::~idAF( void ) { +} + +/* +================ +idAF::Save +================ +*/ +void idAF::Save( idSaveGame *savefile ) const { + savefile->WriteObject( self ); + savefile->WriteString( GetName() ); + savefile->WriteBool( hasBindConstraints ); + savefile->WriteVec3( baseOrigin ); + savefile->WriteMat3( baseAxis ); + savefile->WriteInt( poseTime ); + savefile->WriteInt( restStartTime ); + savefile->WriteBool( isLoaded ); + savefile->WriteBool( isActive ); + savefile->WriteStaticObject( physicsObj ); +} + +/* +================ +idAF::Restore +================ +*/ +void idAF::Restore( idRestoreGame *savefile ) { + savefile->ReadObject( reinterpret_cast( self ) ); + savefile->ReadString( name ); + savefile->ReadBool( hasBindConstraints ); + savefile->ReadVec3( baseOrigin ); + savefile->ReadMat3( baseAxis ); + savefile->ReadInt( poseTime ); + savefile->ReadInt( restStartTime ); + savefile->ReadBool( isLoaded ); + savefile->ReadBool( isActive ); + + animator = NULL; + modifiedAnim = 0; + + if ( self ) { + SetAnimator( self->GetAnimator() ); + Load( self, name ); + if ( hasBindConstraints ) { + AddBindConstraints(); + } + } + + savefile->ReadStaticObject( physicsObj ); + + if ( self ) { + if ( isActive ) { + // clear all animations + animator->ClearAllAnims( gameLocal.time, 0 ); + animator->ClearAllJoints(); + + // switch to articulated figure physics + self->RestorePhysics( &physicsObj ); + physicsObj.EnableClip(); + } + UpdateAnimation(); + } +} + +/* +================ +idAF::UpdateAnimation +================ +*/ +bool idAF::UpdateAnimation( void ) { + int i; + idVec3 origin, renderOrigin, bodyOrigin; + idMat3 axis, renderAxis, bodyAxis; + renderEntity_t *renderEntity; + + if ( !IsLoaded() ) { + return false; + } + + if ( !IsActive() ) { + return false; + } + + renderEntity = self->GetRenderEntity(); + if ( !renderEntity ) { + return false; + } + + if ( physicsObj.IsAtRest() ) { + if ( restStartTime == physicsObj.GetRestStartTime() ) { + return false; + } + restStartTime = physicsObj.GetRestStartTime(); + } + + // get the render position + origin = physicsObj.GetOrigin( 0 ); + axis = physicsObj.GetAxis( 0 ); + renderAxis = baseAxis.Transpose() * axis; + renderOrigin = origin - baseOrigin * renderAxis; + + // create an animation frame which reflects the current pose of the articulated figure + animator->InitAFPose(); + for ( i = 0; i < jointMods.Num(); i++ ) { + // check for the origin joint + if ( jointMods[i].jointHandle == 0 ) { + continue; + } + bodyOrigin = physicsObj.GetOrigin( jointMods[i].bodyId ); + bodyAxis = physicsObj.GetAxis( jointMods[i].bodyId ); + axis = jointMods[i].jointBodyAxis.Transpose() * ( bodyAxis * renderAxis.Transpose() ); + origin = ( bodyOrigin - jointMods[i].jointBodyOrigin * axis - renderOrigin ) * renderAxis.Transpose(); + + // TDM: Do not add AF jointmod if it has AF_JOINTMOD_NONE + // This is used for added bodies that we don't want to stretch the mesh + if( jointMods[i].jointMod != AF_JOINTMOD_NONE ) + animator->SetAFPoseJointMod( jointMods[i].jointHandle, jointMods[i].jointMod, axis, origin ); + } + animator->FinishAFPose( modifiedAnim, GetBounds().Expand( POSE_BOUNDS_EXPANSION ), gameLocal.time ); + animator->SetAFPoseBlendWeight( 1.0f ); + + return true; +} + +/* +================ +idAF::GetBounds + + returns bounds for the current pose +================ +*/ +idBounds idAF::GetBounds( void ) const { + int i; + idAFBody *body; + idVec3 origin, entityOrigin; + idMat3 axis, entityAxis; + idBounds bounds, b; + + bounds.Clear(); + + // get model base transform + origin = physicsObj.GetOrigin( 0 ); + axis = physicsObj.GetAxis( 0 ); + + entityAxis = baseAxis.Transpose() * axis; + entityOrigin = origin - baseOrigin * entityAxis; + + // get bounds relative to base + for ( i = 0; i < jointMods.Num(); i++ ) { + body = physicsObj.GetBody( jointMods[i].bodyId ); + origin = ( body->GetWorldOrigin() - entityOrigin ) * entityAxis.Transpose(); + axis = body->GetWorldAxis() * entityAxis.Transpose(); + b.FromTransformedBounds( body->GetClipModel()->GetBounds(), origin, axis ); + + bounds += b; + } + + return bounds; +} + +/* +================ +idAF::SetupPose + + Transforms the articulated figure to match the current animation pose of the given entity. +================ +*/ +void idAF::SetupPose( idEntity *ent, int time ) { + int i; + idAFBody *body; + idVec3 origin; + idMat3 axis; + idAnimator *animatorPtr; + renderEntity_t *renderEntity; + + if ( !IsLoaded() || !ent ) { + return; + } + + animatorPtr = ent->GetAnimator(); + if ( !animatorPtr ) { + return; + } + + renderEntity = ent->GetRenderEntity(); + if ( !renderEntity ) { + return; + } + + // if the animation is driven by the physics + if ( self->GetPhysics() == &physicsObj ) { + return; + } + + // if the pose was already updated this frame + if ( poseTime == time ) { + return; + } + poseTime = time; + + for ( i = 0; i < jointMods.Num(); i++ ) { + body = physicsObj.GetBody( jointMods[i].bodyId ); + animatorPtr->GetJointTransform( jointMods[i].jointHandle, time, origin, axis ); + body->SetWorldOrigin( renderEntity->origin + ( origin + jointMods[i].jointBodyOrigin * axis ) * renderEntity->axis ); + body->SetWorldAxis( jointMods[i].jointBodyAxis * axis * renderEntity->axis ); + } + + if ( isActive ) { + physicsObj.UpdateClipModels(); + } +} + +/* +================ +idAF::ChangePose + + Change the articulated figure to match the current animation pose of the given entity + and set the velocity relative to the previous pose. +================ +*/ +void idAF::ChangePose( idEntity *ent, int time ) { + int i; + float invDelta; + idAFBody *body; + idVec3 origin, lastOrigin; + idMat3 axis; + idAnimator *animatorPtr; + renderEntity_t *renderEntity; + +// if ( !IsLoaded() || !ent ) { + if ( !IsLoaded() || !ent || IsActive() ) { + return; + } + + animatorPtr = ent->GetAnimator(); + if ( !animatorPtr ) { + return; + } + + renderEntity = ent->GetRenderEntity(); + if ( !renderEntity ) { + return; + } + + // if the animation is driven by the physics + if ( self->GetPhysics() == &physicsObj ) { + return; + } + + // if the pose was already updated this frame + if ( poseTime == time ) { + return; + } + invDelta = 1.0f / MS2SEC( time - poseTime ); + poseTime = time; + + for ( i = 0; i < jointMods.Num(); i++ ) { + body = physicsObj.GetBody( jointMods[i].bodyId ); + animatorPtr->GetJointTransform( jointMods[i].jointHandle, time, origin, axis ); + lastOrigin = body->GetWorldOrigin(); + body->SetWorldOrigin( renderEntity->origin + ( origin + jointMods[i].jointBodyOrigin * axis ) * renderEntity->axis ); + body->SetWorldAxis( jointMods[i].jointBodyAxis * axis * renderEntity->axis ); + body->SetLinearVelocity( ( body->GetWorldOrigin() - lastOrigin ) * invDelta ); + } + + physicsObj.UpdateClipModels(); +} + +/* +================ +idAF::EntitiesTouchingAF +================ +*/ +int idAF::EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const { + int i, j, numClipModels; + idAFBody *body; + idClipModel *cm; + idClipModel *clipModels[ MAX_GENTITIES ]; + int numTouching; + + if ( !IsLoaded() ) { + return 0; + } + + numTouching = 0; + numClipModels = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), -1, clipModels, MAX_GENTITIES ); + + for ( i = 0; i < jointMods.Num(); i++ ) { + body = physicsObj.GetBody( jointMods[i].bodyId ); + + // ishtvan: don't test bodies with their clipmodels disabled + if( !body->GetClipMask() ) + continue; + + for ( j = 0; j < numClipModels; j++ ) { + cm = clipModels[j]; + + if ( !cm || cm->GetEntity() == self ) { + continue; + } + + if ( !cm->IsTraceModel() ) { + continue; + } + + if ( !body->GetClipModel()->GetAbsBounds().IntersectsBounds( cm->GetAbsBounds() ) ) { + continue; + } + + // ishtvan: Apply the body clipmask + if ( gameLocal.clip.ContentsModel( body->GetWorldOrigin(), body->GetClipModel(), body->GetWorldAxis(), body->GetClipMask(), cm->Handle(), cm->GetOrigin(), cm->GetAxis() ) ) { + touchList[ numTouching ].touchedByBody = body; + touchList[ numTouching ].touchedClipModel = cm; + touchList[ numTouching ].touchedEnt = cm->GetEntity(); + numTouching++; + clipModels[j] = NULL; + } + } + } + + return numTouching; +} + +/* +================ +idAF::BodyForClipModelId +================ +*/ +int idAF::BodyForClipModelId( int id ) const { + if ( id >= 0 ) { + return id; + } else { + id = CLIPMODEL_ID_TO_JOINT_HANDLE( id ); + if ( id < jointBody.Num() ) { + return jointBody[id]; + } else { + return 0; + } + } +} + +/* +================ +idAF::JointForBody +================ +*/ +jointHandle_t idAF::JointForBody( int body ) +{ + /* tels: if no jointBody[i] == body, this + will return -1 */ + jointHandle_t joint = (jointHandle_t)-1; + for( int i=0; i < jointBody.Num(); i++ ) + { + if( jointBody[i] == body ) + { + joint = (jointHandle_t) i; + break; + } + } + return joint; +} + +/* +================ +idAF::BodyForJoint +================ +*/ +int idAF::BodyForJoint( jointHandle_t joint ) +{ + if ( joint < jointBody.Num() ) + return jointBody[ joint ]; + else + return 0; +} + +/* +================ +idAF::GetPhysicsToVisualTransform +================ +*/ +void idAF::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const { + origin = - baseOrigin; + axis = baseAxis.Transpose(); +} + +/* +================ +idAF::GetImpactInfo +================ +*/ +void idAF::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { + SetupPose( self, gameLocal.time ); + physicsObj.GetImpactInfo( BodyForClipModelId( id ), point, info ); +} + +/* +================ +idAF::ApplyImpulse +================ +*/ +void idAF::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + SetupPose( self, gameLocal.time ); + physicsObj.ApplyImpulse( BodyForClipModelId( id ), point, impulse ); +} + +/* +================ +idAF::AddForce +================ +*/ +void idAF::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { + SetupPose( self, gameLocal.time ); + physicsObj.AddForce( BodyForClipModelId( id ), point, force ); +} + +/* +================ +idAF::AddBody + + Adds a body. +================ +*/ +void idAF::AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod ) { + int index; + jointHandle_t handle; + idVec3 origin; + idMat3 axis; + + handle = animator->GetJointHandle( jointName ); + if ( handle == INVALID_JOINT ) { + gameLocal.Error( "idAF for entity '%s' at (%s) modifies unknown joint '%s'", self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), jointName ); + } + + assert( handle < animator->NumJoints() ); + origin = joints[ handle ].ToVec3(); + axis = joints[ handle ].ToMat3(); + + index = jointMods.Num(); + jointMods.SetNum( index + 1, false ); + jointMods[index].bodyId = physicsObj.GetBodyId( body ); + jointMods[index].bodyName = body->GetName(); + jointMods[index].jointHandle = handle; + jointMods[index].jointMod = mod; + jointMods[index].jointBodyOrigin = ( body->GetWorldOrigin() - origin ) * axis.Transpose(); + jointMods[index].jointBodyAxis = body->GetWorldAxis() * axis.Transpose(); +} + +void idAF::AddBodyExtern +( + idAFEntity_Base *ent, idAFBody *bodyNew, + idAFBody *bodyExist, AFJointModType_t mod, + jointHandle_t joint +) +{ + int indexNew(0), indexExist(-1), matchID(0); + jointHandle_t tempJoint = INVALID_JOINT; + + idVec3 origin; + idMat3 axis; + + // if we are not given a joint, copy it from the existing body + if( joint != INVALID_JOINT ) + { + tempJoint = joint; + assert( tempJoint < animator->NumJoints() ); + } + else + { + matchID = physicsObj.GetBodyId( bodyExist ); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("idAF::AddBodyExtern: Existing body name is %s, id is %d\r", bodyExist->GetName().c_str(), matchID); + for( int i = 0; i < jointMods.Num(); i++ ) + { + if( jointMods[i].bodyId == matchID ) + { + tempJoint = jointMods[i].jointHandle; + if ( tempJoint == INVALID_JOINT ) + { + gameLocal.Error( "idAF for entity '%s' at (%s) modifies unknown joint %d", self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), (int) tempJoint ); + } + assert( tempJoint < animator->NumJoints() ); + break; + } + } + } + + if( tempJoint != INVALID_JOINT ) + { + ent->GetJointWorldTransform( tempJoint, gameLocal.time, origin, axis ); + + indexNew = jointMods.Num(); + jointMods.SetNum( indexNew + 1, false ); + jointMods[indexNew].bodyId = physicsObj.GetBodyId( bodyNew ); + jointMods[indexNew].bodyName = bodyNew->GetName(); + jointMods[indexNew].jointHandle = tempJoint; + jointMods[indexNew].jointMod = mod; + jointMods[indexNew].jointBodyOrigin = ( bodyNew->GetWorldOrigin() - origin ) * axis.Transpose(); + jointMods[indexNew].jointBodyAxis = bodyNew->GetWorldAxis() * axis.Transpose(); + } +} + +void idAF::DeleteBodyExtern( idAFEntity_Base *ent, const char *bodyName ) +{ + if( ent ) + { + for( int i = jointMods.Num() - 1; i >= 0; i-- ) + { + if( jointMods[i].bodyName == bodyName ) + { + //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Removed body %s from AF\r", bodyName ); + jointMods.RemoveIndex(i); + } + } + } + + // Refresh the bodyIDs in the list, since they will have changed + // When AF physics condenses the list when removing a body in the middle + for( int i = jointMods.Num() - 1; i >= 0; i-- ) + { + jointMods[i].bodyId = ent->GetAFPhysics()->GetBodyId( jointMods[i].bodyName ); + } +} + +/* +================ +idAF::SetBase + + Sets the base body. +================ +*/ +void idAF::SetBase( idAFBody *body, const idJointMat *joints ) { + physicsObj.ForceBodyId( body, 0 ); + baseOrigin = body->GetWorldOrigin(); + baseAxis = body->GetWorldAxis(); + AddBody( body, joints, animator->GetJointName( animator->GetFirstChild( "origin" ) ), AF_JOINTMOD_AXIS ); +} + +/* +================ +idAF::LoadBody +================ +*/ +bool idAF::LoadBody( const idDeclAF_Body *fb, const idJointMat *joints ) { + int id, i; + float length, mass; + idTraceModel trm; + idClipModel *clip; + idAFBody *body; + idMat3 axis, inertiaTensor; + idVec3 centerOfMass, origin; + idBounds bounds; + idList jointList; + + origin = fb->origin.ToVec3(); + axis = fb->angles.ToMat3(); + bounds[0] = fb->v1.ToVec3(); + bounds[1] = fb->v2.ToVec3(); + + switch( fb->modelType ) { + case TRM_BOX: { + trm.SetupBox( bounds ); + break; + } + case TRM_OCTAHEDRON: { + trm.SetupOctahedron( bounds ); + break; + } + case TRM_DODECAHEDRON: { + trm.SetupDodecahedron( bounds ); + break; + } + case TRM_CYLINDER: { + trm.SetupCylinder( bounds, fb->numSides ); + break; + } + case TRM_CONE: { + // place the apex at the origin + bounds[0].z -= bounds[1].z; + bounds[1].z = 0.0f; + trm.SetupCone( bounds, fb->numSides ); + break; + } + case TRM_BONE: { + // direction of bone + axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3(); + length = axis[2].Normalize(); + // axis of bone trace model + axis[2].NormalVectors( axis[0], axis[1] ); + axis[1] = -axis[1]; + // create bone trace model + trm.SetupBone( length, fb->width ); + break; + } + default: + assert( 0 ); + break; + } + trm.GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor ); + trm.Translate( -centerOfMass ); + origin += centerOfMass * axis; + + body = physicsObj.GetBody( fb->name ); + if ( body ) { + clip = body->GetClipModel(); + if ( !clip->IsEqual( trm ) ) { + clip = new idClipModel( trm ); + clip->SetContents( fb->contents ); + clip->Link( gameLocal.clip, self, 0, origin, axis ); + body->SetClipModel( clip ); + } + clip->SetContents( fb->contents ); + body->SetDensity( fb->density, fb->inertiaScale ); + body->SetWorldOrigin( origin ); + body->SetWorldAxis( axis ); + id = physicsObj.GetBodyId( body ); + } + else { + clip = new idClipModel( trm ); + clip->SetContents( fb->contents ); + clip->Link( gameLocal.clip, self, 0, origin, axis ); + body = new idAFBody( fb->name, clip, fb->density ); + if ( fb->inertiaScale != mat3_identity ) { + body->SetDensity( fb->density, fb->inertiaScale ); + } + id = physicsObj.AddBody( body ); + } + if ( fb->linearFriction != -1.0f ) { + body->SetFriction( fb->linearFriction, fb->angularFriction, fb->contactFriction ); + } + // TDM FIX: Remove MOVEABLE_CLIP flag that the parser seems to add in by default + body->SetClipMask( fb->clipMask & ~CONTENTS_MOVEABLECLIP ); + body->SetSelfCollision( fb->selfCollision ); + + if ( fb->jointName == "origin" ) { + SetBase( body, joints ); + } else { + AFJointModType_t mod; + if ( fb->jointMod == DECLAF_JOINTMOD_AXIS ) { + mod = AF_JOINTMOD_AXIS; + } else if ( fb->jointMod == DECLAF_JOINTMOD_ORIGIN ) { + mod = AF_JOINTMOD_ORIGIN; + } else if ( fb->jointMod == DECLAF_JOINTMOD_BOTH ) { + mod = AF_JOINTMOD_BOTH; + } else { + mod = AF_JOINTMOD_AXIS; + } + AddBody( body, joints, fb->jointName, mod ); + } + + if ( fb->frictionDirection.ToVec3() != vec3_origin ) { + body->SetFrictionDirection( fb->frictionDirection.ToVec3() ); + } + if ( fb->contactMotorDirection.ToVec3() != vec3_origin ) { + body->SetContactMotorDirection( fb->contactMotorDirection.ToVec3() ); + } + + // update table to find the nearest articulated figure body for a joint of the skeletal model + animator->GetJointList( fb->containedJoints, jointList ); + for( i = 0; i < jointList.Num(); i++ ) { + if ( jointBody[ jointList[ i ] ] != -1 ) { + gameLocal.Warning( "%s: joint '%s' is already contained by body '%s'", + name.c_str(), animator->GetJointName( (jointHandle_t)jointList[i] ), + physicsObj.GetBody( jointBody[ jointList[ i ] ] )->GetName().c_str() ); + } + jointBody[ jointList[ i ] ] = id; + } + + return true; +} + +/* +================ +idAF::LoadConstraint +================ +*/ +bool idAF::LoadConstraint( const idDeclAF_Constraint *fc ) { + idAFBody *body1, *body2; + idAngles angles; + idMat3 axis; + + body1 = physicsObj.GetBody( fc->body1 ); + body2 = physicsObj.GetBody( fc->body2 ); + + switch( fc->type ) { + case DECLAF_CONSTRAINT_FIXED: { + idAFConstraint_Fixed *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_Fixed( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + break; + } + case DECLAF_CONSTRAINT_BALLANDSOCKETJOINT: { + idAFConstraint_BallAndSocketJoint *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_BallAndSocketJoint( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + c->SetAnchor( fc->anchor.ToVec3() ); + c->SetFriction( fc->friction ); + switch( fc->limit ) { + case idDeclAF_Constraint::LIMIT_CONE: { + c->SetConeLimit( fc->limitAxis.ToVec3(), fc->limitAngles[0], fc->shaft[0].ToVec3() ); + break; + } + case idDeclAF_Constraint::LIMIT_PYRAMID: { + angles = fc->limitAxis.ToVec3().ToAngles(); + angles.roll = fc->limitAngles[2]; + axis = angles.ToMat3(); + c->SetPyramidLimit( axis[0], axis[1], fc->limitAngles[0], fc->limitAngles[1], fc->shaft[0].ToVec3() ); + break; + } + default: { + c->SetNoLimit(); + break; + } + } + break; + } + case DECLAF_CONSTRAINT_UNIVERSALJOINT: { + idAFConstraint_UniversalJoint *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_UniversalJoint( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + c->SetAnchor( fc->anchor.ToVec3() ); + c->SetShafts( fc->shaft[0].ToVec3(), fc->shaft[1].ToVec3() ); + c->SetFriction( fc->friction ); + switch( fc->limit ) { + case idDeclAF_Constraint::LIMIT_CONE: { + c->SetConeLimit( fc->limitAxis.ToVec3(), fc->limitAngles[0] ); + break; + } + case idDeclAF_Constraint::LIMIT_PYRAMID: { + angles = fc->limitAxis.ToVec3().ToAngles(); + angles.roll = fc->limitAngles[2]; + axis = angles.ToMat3(); + c->SetPyramidLimit( axis[0], axis[1], fc->limitAngles[0], fc->limitAngles[1] ); + break; + } + default: { + c->SetNoLimit(); + break; + } + } + break; + } + case DECLAF_CONSTRAINT_HINGE: { + idAFConstraint_Hinge *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_Hinge( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + c->SetAnchor( fc->anchor.ToVec3() ); + c->SetAxis( fc->axis.ToVec3() ); + c->SetFriction( fc->friction ); + switch( fc->limit ) { + case idDeclAF_Constraint::LIMIT_CONE: { + idVec3 left, up, axis, shaft; + fc->axis.ToVec3().OrthogonalBasis( left, up ); + axis = left * idRotation( vec3_origin, fc->axis.ToVec3(), fc->limitAngles[0] ); + shaft = left * idRotation( vec3_origin, fc->axis.ToVec3(), fc->limitAngles[2] ); + c->SetLimit( axis, fc->limitAngles[1], shaft ); + break; + } + default: { + c->SetNoLimit(); + break; + } + } + break; + } + case DECLAF_CONSTRAINT_SLIDER: { + idAFConstraint_Slider *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_Slider( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + c->SetAxis( fc->axis.ToVec3() ); + break; + } + case DECLAF_CONSTRAINT_SPRING: { + idAFConstraint_Spring *c; + c = static_cast(physicsObj.GetConstraint( fc->name )); + if ( c ) { + c->SetBody1( body1 ); + c->SetBody2( body2 ); + } + else { + c = new idAFConstraint_Spring( fc->name, body1, body2 ); + physicsObj.AddConstraint( c ); + } + c->SetAnchor( fc->anchor.ToVec3(), fc->anchor2.ToVec3() ); + c->SetSpring( fc->stretch, fc->compress, fc->damping, fc->restLength ); + c->SetLimit( fc->minLength, fc->maxLength ); + break; + } + default: break; + } + return true; +} + +/* +================ +GetJointTransform +================ +*/ +static bool GetJointTransform( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ) { + jointHandle_t joint; + + joint = reinterpret_cast(model)->GetJointHandle( jointName ); + if ( ( joint >= 0 ) && ( joint < reinterpret_cast(model)->NumJoints() ) ) { + origin = frame[ joint ].ToVec3(); + axis = frame[ joint ].ToMat3(); + return true; + } else { + return false; + } +} + +/* +================ +idAF::Load +================ +*/ +bool idAF::Load( idEntity *ent, const char *fileName ) { + int i, j; + const idDeclAF *file; + const idDeclModelDef *modelDef; + idRenderModel *model; + int numJoints; + idJointMat *joints; + + assert( ent ); + + self = ent; + physicsObj.SetSelf( self ); + + if ( animator == NULL ) { + gameLocal.Warning( "Couldn't load af '%s' for entity '%s' at (%s): NULL animator\n", name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + + name = fileName; + name.StripFileExtension(); + + file = static_cast( declManager->FindType( DECL_AF, name ) ); + if ( !file ) { + gameLocal.Warning( "Couldn't load af '%s' for entity '%s' at (%s)\n", name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + + if ( file->bodies.Num() == 0 || file->bodies[0]->jointName != "origin" ) { + gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no body which modifies the origin joint.", + name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + + modelDef = animator->ModelDef(); + if ( modelDef == NULL || modelDef->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no or defaulted modelDef '%s'", + name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), modelDef ? modelDef->GetName() : "" ); + return false; + } + + model = animator->ModelHandle(); + if ( model == NULL || model->IsDefaultModel() ) { + gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no or defaulted model '%s'", + name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), model ? model->Name() : "" ); + return false; + } + + // get the modified animation + modifiedAnim = animator->GetAnim( ARTICULATED_FIGURE_ANIM ); + if ( !modifiedAnim ) { + gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no modified animation '%s'", + name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), ARTICULATED_FIGURE_ANIM ); + return false; + } + + // create the animation frame used to setup the articulated figure + numJoints = animator->NumJoints(); + joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); + gameEdit->ANIM_CreateAnimFrame( model, animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset(), animator->RemoveOrigin() ); + + // set all vector positions from model joints + file->Finish( GetJointTransform, joints, animator ); + + // initialize articulated figure physics + physicsObj.SetGravity( gameLocal.GetGravity() ); + physicsObj.SetClipMask( file->clipMask ); + physicsObj.SetDefaultFriction( file->defaultLinearFriction, file->defaultAngularFriction, file->defaultContactFriction ); + physicsObj.SetSuspendSpeed( file->suspendVelocity, file->suspendAcceleration ); + physicsObj.SetSuspendTolerance( file->noMoveTime, file->noMoveTranslation, file->noMoveRotation ); + physicsObj.SetSuspendTime( file->minMoveTime, file->maxMoveTime ); + physicsObj.SetSelfCollision( file->selfCollision ); + + // clear the list with transforms from joints to bodies + jointMods.SetNum( 0, false ); + + // clear the joint to body conversion list + jointBody.AssureSize( animator->NumJoints() ); + for ( i = 0; i < jointBody.Num(); i++ ) { + jointBody[i] = -1; + } + + // delete any bodies in the physicsObj that are no longer in the idDeclAF + for ( i = 0; i < physicsObj.GetNumBodies(); i++ ) { + idAFBody *body = physicsObj.GetBody( i ); + for ( j = 0; j < file->bodies.Num(); j++ ) { + if ( file->bodies[j]->name.Icmp( body->GetName() ) == 0 ) { + break; + } + } + if ( j >= file->bodies.Num() ) { + physicsObj.DeleteBody( i ); + i--; + } + } + + // delete any constraints in the physicsObj that are no longer in the idDeclAF + for ( i = 0; i < physicsObj.GetNumConstraints(); i++ ) { + idAFConstraint *constraint = physicsObj.GetConstraint( i ); + for ( j = 0; j < file->constraints.Num(); j++ ) { + if ( file->constraints[j]->name.Icmp( constraint->GetName() ) == 0 && + file->constraints[j]->type == constraint->GetType() ) { + break; + } + } + if ( j >= file->constraints.Num() ) { + physicsObj.DeleteConstraint( i ); + i--; + } + } + + // load bodies from the file + for ( i = 0; i < file->bodies.Num(); i++ ) { + LoadBody( file->bodies[i], joints ); + } + + // load constraints from the file + for ( i = 0; i < file->constraints.Num(); i++ ) { + LoadConstraint( file->constraints[i] ); + } + + physicsObj.UpdateClipModels(); + + // check if each joint is contained by a body + for( i = 0; i < animator->NumJoints(); i++ ) { + if ( jointBody[i] == -1 ) { + gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) joint '%s' is not contained by a body", + name.c_str(), self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), animator->GetJointName( (jointHandle_t)i ) ); + } + } + +#ifdef MOD_WATERPHYSICS + // load how the body will be floated in liquid + bool isFixedDensity; + if( ent->spawnArgs.GetBool( "fixedDensityBuoyancy", "1", isFixedDensity ) ) + physicsObj.SetFixedDensityBuoyancy( isFixedDensity ); + +// load liquid density from file + float liquidDensity; + if( ent->spawnArgs.GetFloat( "liquidDensity", "", liquidDensity ) ) + physicsObj.SetLiquidDensity( liquidDensity ); +#endif // MOD_WATERPHYSICS + + physicsObj.SetMass( file->totalMass ); + physicsObj.SetChanged(); + physicsObj.BuildTrees(); + + // disable the articulated figure for collision detection until activated + physicsObj.DisableClip(); + + isLoaded = true; + + physicsObj.SetNumOrigBodies( physicsObj.GetNumBodies() ); + physicsObj.SetNumOrigConstraints( physicsObj.GetNumConstraints() ); + + return true; +} + +/* +================ +idAF::Start +================ +*/ +void idAF::Start( void ) { + if ( !IsLoaded() ) { + return; + } + // clear all animations + animator->ClearAllAnims( gameLocal.time, 0 ); + animator->ClearAllJoints(); + // switch to articulated figure physics + self->SetPhysics( &physicsObj ); + // start the articulated figure physics simulation + physicsObj.EnableClip(); + physicsObj.Activate(); + isActive = true; +} + +/* +================ +idAF::TestSolid +================ +*/ +bool idAF::TestSolid( void ) const { + int i; + idAFBody *body; + trace_t trace; + idStr str; + bool solid; + + if ( !IsLoaded() ) { + return false; + } + + if ( !af_testSolid.GetBool() ) { + return false; + } + + solid = false; + + for ( i = 0; i < physicsObj.GetNumBodies(); i++ ) { + body = physicsObj.GetBody( i ); + if ( gameLocal.clip.Translation( trace, body->GetWorldOrigin(), body->GetWorldOrigin(), body->GetClipModel(), body->GetWorldAxis(), body->GetClipMask(), self ) ) { + float depth = idMath::Fabs( trace.c.point * trace.c.normal - trace.c.dist ); + + body->SetWorldOrigin( body->GetWorldOrigin() + trace.c.normal * ( depth + 8.0f ) ); + + gameLocal.DWarning( "%s: body '%s' stuck in %d (normal = %.2f %.2f %.2f, depth = %.2f)", self->name.c_str(), + body->GetName().c_str(), trace.c.contents, trace.c.normal.x, trace.c.normal.y, trace.c.normal.z, depth ); + solid = true; + + } + } + return solid; +} + +/* +================ +idAF::StartFromCurrentPose +================ +*/ +void idAF::StartFromCurrentPose( int inheritVelocityTime ) { + + if ( !IsLoaded() ) { + return; + } + + // if the ragdoll should inherit velocity from the animation + if ( inheritVelocityTime > 0 ) { + + // make sure the ragdoll is at rest + physicsObj.PutToRest(); + + // set the pose for some time back + SetupPose( self, gameLocal.time - inheritVelocityTime ); + + // change the pose for the current time and set velocities + ChangePose( self, gameLocal.time ); + } + else { + // transform the articulated figure to reflect the current animation pose + SetupPose( self, gameLocal.time ); + } + + physicsObj.UpdateClipModels(); + + TestSolid(); + + Start(); + + UpdateAnimation(); + + // update the render entity origin and axis + self->UpdateModel(); + + // make sure the renderer gets the updated origin and axis + self->Present(); +} + +/* +================ +idAF::Stop +================ +*/ +void idAF::Stop( void ) { + // disable the articulated figure for collision detection + physicsObj.UnlinkClip(); + isActive = false; +} + +/* +================ +idAF::Rest +================ +*/ +void idAF::Rest( void ) { + physicsObj.PutToRest(); +} + +/* +================ +idAF::SetConstraintPosition + + Only moves constraints that bind the entity to another entity. +================ +*/ +void idAF::SetConstraintPosition( const char *name, const idVec3 &pos ) { + idAFConstraint *constraint; + + constraint = GetPhysics()->GetConstraint( name ); + + if ( !constraint ) { + gameLocal.Warning( "can't find a constraint with the name '%s'", name ); + return; + } + + if ( constraint->GetBody2() != NULL ) { + gameLocal.Warning( "constraint '%s' does not bind to another entity", name ); + return; + } + + switch( constraint->GetType() ) { + case CONSTRAINT_BALLANDSOCKETJOINT: { + idAFConstraint_BallAndSocketJoint *bs = static_cast(constraint); + bs->Translate( pos - bs->GetAnchor() ); + break; + } + case CONSTRAINT_UNIVERSALJOINT: { + idAFConstraint_UniversalJoint *uj = static_cast(constraint); + uj->Translate( pos - uj->GetAnchor() ); + break; + } + case CONSTRAINT_HINGE: { + idAFConstraint_Hinge *hinge = static_cast(constraint); + hinge->Translate( pos - hinge->GetAnchor() ); + break; + } + default: { + gameLocal.Warning( "cannot set the constraint position for '%s'", name ); + break; + } + } +} + +/* +================ +idAF::SaveState +================ +*/ +void idAF::SaveState( idDict &args ) const { + int i; + idAFBody *body; + idStr key, value; + + for ( i = 0; i < jointMods.Num(); i++ ) { + body = physicsObj.GetBody( jointMods[i].bodyId ); + + key = "body " + body->GetName(); + value = body->GetWorldOrigin().ToString( 8 ); + value += " "; + value += body->GetWorldAxis().ToAngles().ToString( 8 ); + args.Set( key, value ); + } +} + +/* +================ +idAF::LoadState +================ +*/ +void idAF::LoadState( const idDict &args ) { + const idKeyValue *kv; + idStr name; + idAFBody *body; + idVec3 origin; + idAngles angles; + + kv = args.MatchPrefix( "body ", NULL ); + while ( kv ) { + + name = kv->GetKey(); + name.Strip( "body " ); + body = physicsObj.GetBody( name ); + if ( body ) { + sscanf( kv->GetValue(), "%f %f %f %f %f %f", &origin.x, &origin.y, &origin.z, &angles.pitch, &angles.yaw, &angles.roll ); + body->SetWorldOrigin( origin ); + body->SetWorldAxis( angles.ToMat3() ); + } else { + gameLocal.Warning("Unknown body part %s in articulated figure %s", name.c_str(), this->name.c_str()); + } + + kv = args.MatchPrefix( "body ", kv ); + } + + physicsObj.UpdateClipModels(); +} + +/* +================ +idAF::AddBindConstraints +================ +*/ +void idAF::AddBindConstraints( void ) { + const idKeyValue *kv; + idStr name; + idAFBody *body; + idLexer lexer; + idToken type, bodyName, jointName; + idVec3 origin, renderOrigin; + idMat3 axis, renderAxis; + + if ( !IsLoaded() ) { + return; + } + + const idDict &args = self->spawnArgs; + + // get the render position + origin = physicsObj.GetOrigin( 0 ); + axis = physicsObj.GetAxis( 0 ); + renderAxis = baseAxis.Transpose() * axis; + renderOrigin = origin - baseOrigin * renderAxis; + + // parse all the bind constraints + for ( kv = args.MatchPrefix( "bindConstraint ", NULL ); kv; kv = args.MatchPrefix( "bindConstraint ", kv ) ) { + name = kv->GetKey(); + name.Strip( "bindConstraint " ); + + lexer.LoadMemory( kv->GetValue(), kv->GetValue().Length(), kv->GetKey() ); + lexer.ReadToken( &type ); + + lexer.ReadToken( &bodyName ); + body = physicsObj.GetBody( bodyName ); + if ( !body ) { + gameLocal.Warning( "idAF::AddBindConstraints: body '%s' not found on entity '%s'", bodyName.c_str(), self->name.c_str() ); + lexer.FreeSource(); + continue; + } + + if ( type.Icmp( "fixed" ) == 0 ) { + idAFConstraint_Fixed *c; + + c = new idAFConstraint_Fixed( name, body, NULL ); + physicsObj.AddConstraint( c ); + } + else if ( type.Icmp( "ballAndSocket" ) == 0 ) { + idAFConstraint_BallAndSocketJoint *c; + + c = new idAFConstraint_BallAndSocketJoint( name, body, NULL ); + physicsObj.AddConstraint( c ); + lexer.ReadToken( &jointName ); + + jointHandle_t joint = animator->GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) { + gameLocal.Warning( "idAF::AddBindConstraints: joint '%s' not found", jointName.c_str() ); + } + + animator->GetJointTransform( joint, gameLocal.time, origin, axis ); + c->SetAnchor( renderOrigin + origin * renderAxis ); + } + else if ( type.Icmp( "universal" ) == 0 ) { + idAFConstraint_UniversalJoint *c; + + c = new idAFConstraint_UniversalJoint( name, body, NULL ); + physicsObj.AddConstraint( c ); + lexer.ReadToken( &jointName ); + + jointHandle_t joint = animator->GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) { + gameLocal.Warning( "idAF::AddBindConstraints: joint '%s' not found", jointName.c_str() ); + } + animator->GetJointTransform( joint, gameLocal.time, origin, axis ); + c->SetAnchor( renderOrigin + origin * renderAxis ); + c->SetShafts( idVec3( 0, 0, 1 ), idVec3( 0, 0, -1 ) ); + } + else { + gameLocal.Warning( "idAF::AddBindConstraints: unknown constraint type '%s' on entity '%s'", type.c_str(), self->name.c_str() ); + } + + lexer.FreeSource(); + } + + hasBindConstraints = true; +} + +/* +================ +idAF::RemoveBindConstraints +================ +*/ +void idAF::RemoveBindConstraints( void ) { + const idKeyValue *kv; + + if ( !IsLoaded() ) { + return; + } + + const idDict &args = self->spawnArgs; + idStr name; + + kv = args.MatchPrefix( "bindConstraint ", NULL ); + while ( kv ) { + name = kv->GetKey(); + name.Strip( "bindConstraint " ); + + if ( physicsObj.GetConstraint( name ) ) { + physicsObj.DeleteConstraint( name ); + } + + kv = args.MatchPrefix( "bindConstraint ", kv ); + } + + hasBindConstraints = false; +} diff --git a/game/AF.h b/game/AF.h new file mode 100644 index 000000000..6f70693ff --- /dev/null +++ b/game/AF.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_AF_H__ +#define __GAME_AF_H__ + + +/* +=============================================================================== + + Articulated figure controller. + +=============================================================================== +*/ + +/* FORWRD DECLS */ +class idDeclAF_Body; +class idDeclAF_Constraint; + +typedef struct jointConversion_s { + int bodyId; // id of the body + idStr bodyName; // TDM: String name of body. Only used on add/remove for performance + jointHandle_t jointHandle; // handle of joint this body modifies + AFJointModType_t jointMod; // modify joint axis, origin or both + idVec3 jointBodyOrigin; // origin of body relative to joint + idMat3 jointBodyAxis; // axis of body relative to joint +} jointConversion_t; + +typedef struct afTouch_s { + idEntity * touchedEnt; + idClipModel * touchedClipModel; + idAFBody * touchedByBody; +} afTouch_t; + +class idAF { +public: + idAF( void ); + virtual ~idAF( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void SetAnimator( idAnimator *a ) { animator = a; } + bool Load( idEntity *ent, const char *fileName ); + bool IsLoaded( void ) const { return isLoaded && self != NULL; } + const char * GetName( void ) const { return name.c_str(); } + void SetupPose( idEntity *ent, int time ); + void ChangePose( idEntity *ent, int time ); + int EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const; + void Start( void ); + void StartFromCurrentPose( int inheritVelocityTime ); + void Stop( void ); + void Rest( void ); + bool IsActive( void ) const { return isActive; } + void SetConstraintPosition( const char *name, const idVec3 &pos ); + + idPhysics_AF * GetPhysics( void ) { return &physicsObj; } + const idPhysics_AF * GetPhysics( void ) const { return &physicsObj; } + idBounds GetBounds( void ) const; + bool UpdateAnimation( void ); + + void GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const; + void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); + void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); + int BodyForClipModelId( int id ) const; + /** + * Find the joint associated with the given body + **/ + jointHandle_t JointForBody( int body ); + int BodyForJoint( jointHandle_t joint ); + + void SaveState( idDict &args ) const; + void LoadState( const idDict &args ); + + void AddBindConstraints( void ); + void RemoveBindConstraints( void ); + + /** + * TDM: Allows adding a body not in the AF file, bodyNew. Must be referenced to an existing body in the AF file, bodyExist. + * Also needs the entity for which we are doing this. + **/ + void AddBodyExtern + ( idAFEntity_Base *ent, idAFBody *bodyNew, + idAFBody *bodyExist, AFJointModType_t mod, + jointHandle_t joint = INVALID_JOINT ); + + /** + * TDM: Delete an externally added body + * NOTE: Must remove the body on the AFPhysics object BEFORE calling this. + * Because this also refreshes the jointMod bodyID's based on the physics object. + **/ + void DeleteBodyExtern( idAFEntity_Base *ent, const char *bodyName ); + +protected: + idStr name; // name of the loaded .af file + idPhysics_AF physicsObj; // articulated figure physics + idEntity * self; // entity using the animated model + idAnimator * animator; // animator on entity + int modifiedAnim; // anim to modify + idVec3 baseOrigin; // offset of base body relative to skeletal model origin + idMat3 baseAxis; // axis of base body relative to skeletal model origin + idListjointMods; // list with transforms from skeletal model joints to articulated figure bodies + idList jointBody; // table to find the nearest articulated figure body for a joint of the skeletal model + int poseTime; // last time the articulated figure was transformed to reflect the current animation pose + int restStartTime; // time the articulated figure came to rest + bool isLoaded; // true when the articulated figure is properly loaded + bool isActive; // true if the articulated figure physics is active + bool hasBindConstraints; // true if the bind constraints have been added + +protected: + void SetBase( idAFBody *body, const idJointMat *joints ); + void AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod ); + + bool LoadBody( const idDeclAF_Body *fb, const idJointMat *joints ); + bool LoadConstraint( const idDeclAF_Constraint *fc ); + + bool TestSolid( void ) const; +}; + +#endif /* !__GAME_AF_H__ */ diff --git a/game/AFEntity.cpp b/game/AFEntity.cpp new file mode 100644 index 000000000..9ce61ec03 --- /dev/null +++ b/game/AFEntity.cpp @@ -0,0 +1,3662 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "StimResponse/StimResponseCollection.h" + +/* +=============================================================================== + + idMultiModelAF + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idMultiModelAF ) +END_CLASS + +/* +================ +idMultiModelAF::Spawn +================ +*/ +void idMultiModelAF::Spawn( void ) { + physicsObj.SetSelf( this ); +} + +/* +================ +idMultiModelAF::~idMultiModelAF +================ +*/ +idMultiModelAF::~idMultiModelAF( void ) { + int i; + + for ( i = 0; i < modelDefHandles.Num(); i++ ) { + if ( modelDefHandles[i] != -1 ) { + gameRenderWorld->FreeEntityDef( modelDefHandles[i] ); + modelDefHandles[i] = -1; + } + } +} + +/* +================ +idMultiModelAF::SetModelForId +================ +*/ +void idMultiModelAF::SetModelForId( int id, const idStr &modelName ) { + modelHandles.AssureSize( id+1, NULL ); + modelDefHandles.AssureSize( id+1, -1 ); + modelHandles[id] = renderModelManager->FindModel( modelName ); +} + +/* +================ +idMultiModelAF::Present +================ +*/ +void idMultiModelAF::Present( void ) +{ + int i; + + if( m_bFrobable ) + { + UpdateFrobState(); + UpdateFrobDisplay(); + } + + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) + { + return; + } + BecomeInactive( TH_UPDATEVISUALS ); + + for ( i = 0; i < modelHandles.Num(); i++ ) { + + if ( !modelHandles[i] ) { + continue; + } + + renderEntity.origin = physicsObj.GetOrigin( i ); + renderEntity.axis = physicsObj.GetAxis( i ); + renderEntity.hModel = modelHandles[i]; + renderEntity.bodyId = i; + + // add to refresh list + if ( modelDefHandles[i] == -1 ) { + modelDefHandles[i] = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandles[i], &renderEntity ); + } + } +} + +/* +================ +idMultiModelAF::Think +================ +*/ +void idMultiModelAF::Think( void ) { + RunPhysics(); + Present(); +} + +/* +====================== +idMultiModelAF::ParseAttachments +====================== +*/ +void idMultiModelAF::ParseAttachments( void ) +{ + return; +} + +/* +====================== +idMultiModelAF::ParseAttachmentsAF +====================== +*/ +void idMultiModelAF::ParseAttachmentsAF( void ) +{ + idEntity::ParseAttachments(); +} + + +/* +=============================================================================== + + idChain + +=============================================================================== +*/ + +CLASS_DECLARATION( idMultiModelAF, idChain ) +END_CLASS + +/* +================ +idChain::BuildChain + + builds a chain hanging down from the ceiling + the highest link is a child of the link below it etc. + this allows an object to be attached to multiple chains while keeping a single tree structure +================ +*/ +void idChain::BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld ) { + int i; + float halfLinkLength = linkLength * 0.5f; + idTraceModel trm; + idClipModel *clip; + idAFBody *body, *lastBody; + idAFConstraint_BallAndSocketJoint *bsj; + idAFConstraint_UniversalJoint *uj; + idVec3 org; + + // create a trace model + trm = idTraceModel( linkLength, linkWidth ); + trm.Translate( -trm.offset ); + + org = origin - idVec3( 0, 0, halfLinkLength ); + + lastBody = NULL; + for ( i = 0; i < numLinks; i++ ) { + + // add body + clip = new idClipModel( trm ); + clip->SetContents( CONTENTS_SOLID ); + clip->Link( gameLocal.clip, this, 0, org, mat3_identity ); + body = new idAFBody( name + idStr(i), clip, density ); + physicsObj.AddBody( body ); + + // visual model for body + SetModelForId( physicsObj.GetBodyId( body ), spawnArgs.GetString( "model" ) ); + + // add constraint + if ( bindToWorld ) { + if ( !lastBody ) { + uj = new idAFConstraint_UniversalJoint( name + idStr(i), body, lastBody ); + uj->SetShafts( idVec3( 0, 0, -1 ), idVec3( 0, 0, 1 ) ); + //uj->SetConeLimit( idVec3( 0, 0, -1 ), 30.0f ); + //uj->SetPyramidLimit( idVec3( 0, 0, -1 ), idVec3( 1, 0, 0 ), 90.0f, 30.0f ); + } + else { + uj = new idAFConstraint_UniversalJoint( name + idStr(i), lastBody, body ); + uj->SetShafts( idVec3( 0, 0, 1 ), idVec3( 0, 0, -1 ) ); + //uj->SetConeLimit( idVec3( 0, 0, 1 ), 30.0f ); + } + uj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) ); + uj->SetFriction( 0.9f ); + physicsObj.AddConstraint( uj ); + } + else { + if ( lastBody ) { + bsj = new idAFConstraint_BallAndSocketJoint( "joint" + idStr(i), lastBody, body ); + bsj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) ); + bsj->SetConeLimit( idVec3( 0, 0, 1 ), 60.0f, idVec3( 0, 0, 1 ) ); + physicsObj.AddConstraint( bsj ); + } + } + + org[2] -= linkLength; + + lastBody = body; + } +} + +/* +================ +idChain::Spawn +================ +*/ +void idChain::Spawn( void ) { + int numLinks; + float length, linkLength, linkWidth, density; + bool drop; + idVec3 origin; + + spawnArgs.GetBool( "drop", "0", drop ); + spawnArgs.GetInt( "links", "3", numLinks ); + spawnArgs.GetFloat( "length", idStr( numLinks * 32.0f ), length ); + spawnArgs.GetFloat( "width", "8", linkWidth ); + spawnArgs.GetFloat( "density", "0.2", density ); + linkLength = length / numLinks; + origin = GetPhysics()->GetOrigin(); + + // initialize physics + physicsObj.SetSelf( this ); + physicsObj.SetGravity( gameLocal.GetGravity() ); + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY ); + SetPhysics( &physicsObj ); + + BuildChain( "link", origin, linkLength, linkWidth, density, numLinks, !drop ); + + ParseAttachmentsAF(); +} + +/* +=============================================================================== + + idAFAttachment + +=============================================================================== +*/ + +CLASS_DECLARATION( idAnimatedEntity, idAFAttachment ) +END_CLASS + +/* +===================== +idAFAttachment::idAFAttachment +===================== +*/ +idAFAttachment::idAFAttachment( void ) { + body = NULL; + combatModel = NULL; + idleAnim = 0; + attachJoint = INVALID_JOINT; +} + +/* +===================== +idAFAttachment::~idAFAttachment +===================== +*/ +idAFAttachment::~idAFAttachment( void ) { + + StopSound( SND_CHANNEL_ANY, false ); + + delete combatModel; + combatModel = NULL; +} + +/* +===================== +idAFAttachment::Spawn +===================== +*/ +void idAFAttachment::Spawn( void ) { + idleAnim = animator.GetAnim( "idle" ); +} + +/* +===================== +idAFAttachment::SetBody +===================== +*/ +void idAFAttachment::SetBody( idEntity *bodyEnt, const char *model, jointHandle_t attachJoint ) +{ + bool bleed; + + body = bodyEnt; + this->attachJoint = attachJoint; + SetModel( model ); + fl.takedamage = true; + + bleed = body->spawnArgs.GetBool( "bleed" ); + spawnArgs.SetBool( "bleed", bleed ); + + // greebo: Add the body as frob peer + m_FrobPeers.AddUnique(bodyEnt->name); + + // ishtvan: Go through our bind children and copy the actor body info over to them + // might end up doing a few extra calls if GetTeamChildren is broken like we think, + // but that's okay, add extra check of direct bindmaster to prevent infinite recursion + idList children; + GetTeamChildren( &children ); + for( int i=0; i < children.Num(); i++ ) + { + if( !children[i]->IsType(idAFAttachment::Type) ) + continue; + if( !children[i]->IsBoundTo( this ) ) + continue; + else + { + CopyBodyTo( static_cast(children[i]) ); + } + } +} + +/* +===================== +idAFAttachment::ClearBody +===================== +*/ +void idAFAttachment::ClearBody( void ) { + body = NULL; + attachJoint = INVALID_JOINT; + Hide(); +} + +/* +===================== +idAFAttachment::GetBody +===================== +*/ +idEntity *idAFAttachment::GetBody( void ) const { + return body; +} + +/* +===================== +idAFAttachment::GetAttachJoint +===================== +*/ +jointHandle_t idAFAttachment::GetAttachJoint( void ) const +{ + return attachJoint; +} + +/** +* Return true if we can mantle this attachment, false otherwise. +**/ +bool idAFAttachment::IsMantleable() +{ + return (!body || body->IsMantleable()) && idEntity::IsMantleable(); +} + +/** +* idAFAttachment::BindNotify +**/ +void idAFAttachment::BindNotify( idEntity *ent ) +{ + // copy information over to a bound idAfAttachment + if( ent->IsType(idAFAttachment::Type) ) + { + CopyBodyTo( static_cast(ent) ); + } +} + +void idAFAttachment::UnbindNotify( idEntity *ent ) +{ + idEntity::UnbindNotify( ent ); + // remove ent from AF if it was dynamically added as an AF body + if( body && body->IsType(idAFEntity_Base::Type) ) + static_cast(body)->RemoveAddedEnt( ent ); +} + +void idAFAttachment::PostUnbind( void ) +{ + // no longer bound to an actor + body = NULL; + attachJoint = INVALID_JOINT; +} + +void idAFAttachment::DropOnRagdoll( void ) +{ + // some stuff copied from idAI::DropOnRagdoll + idEntity *ent = NULL; + int mask(0); + + // Drop TDM attachments + for( int i=0; ispawnArgs.GetBool( "drop_set_nonsolid" )) + { + int curContents = ent->GetPhysics()->GetContents(); + + // ishtvan: Also clear the CONTENTS_CORPSE flag (maybe this was a typo in original code?) + ent->GetPhysics()->SetContents(curContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE)); + + // also have to iterate thru stuff attached to this attachment + // ishtvan: left this commentd out because I'm not sure if GetTeamChildren is bugged or not + // don't want to accidentally set all attachments to the AI to nonsolid + /* + idList AttChildren; + ent->GetTeamChildren( &AttChildren ); + gameLocal.Printf("TEST: drop_set_nonsolid, Num team children = %d", AttChildren.Num() ); + for( int i=0; i < AttChildren.Num(); i++ ) + { + idPhysics *pChildPhys = AttChildren[i]->GetPhysics(); + if( pChildPhys == NULL ) + continue; + + int childContents = pChildPhys->GetContents(); + pChildPhys->SetContents( childContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); + } + */ + } + + bool bDrop = ent->spawnArgs.GetBool( "drop_when_ragdoll" ); + + if( !bDrop ) { + continue; + } + + bool bSetSolid = ent->spawnArgs.GetBool( "drop_add_contents_solid" ); + bool bSetCorpse = ent->spawnArgs.GetBool( "drop_add_contents_corpse" ); + bool bSetFrob = ent->spawnArgs.GetBool( "drop_set_frobable" ); + bool bExtinguish = ent->spawnArgs.GetBool("extinguish_on_drop", "0"); + + // Proceed with droppage + DetachInd( i ); + + if( bSetSolid ) + mask = CONTENTS_SOLID; + if( bSetCorpse ) + mask = mask | CONTENTS_CORPSE; + + if( mask ) + ent->GetPhysics()->SetContents( ent->GetPhysics()->GetContents() | mask ); + + if( bSetFrob ) + ent->m_bFrobable = true; + + // greebo: Check if we should extinguish the attachment, like torches + if ( bExtinguish ) + { + // Get the delay in milliseconds + int delay = SEC2MS(ent->spawnArgs.GetInt("extinguish_on_drop_delay", "3")); + if (delay < 0) { + delay = 0; + } + + // Schedule the extinguish event + ent->PostEventMS(&EV_ExtinguishLights, delay); + } + + ent->GetPhysics()->Activate(); + ent->m_droppedByAI = true; // grayman #1330 + } +} + +void idAFAttachment::CopyBodyTo( idAFAttachment *other ) +{ + if( body ) + { + idStr modelName = other->spawnArgs.GetString("model",""); + other->SetBody( body, modelName.c_str(), attachJoint ); + } +} + +/* +================ +idAFAttachment::Save + +archive object for savegame file +================ +*/ +void idAFAttachment::Save( idSaveGame *savefile ) const { + savefile->WriteObject( body ); + savefile->WriteInt( idleAnim ); + savefile->WriteJoint( attachJoint ); +} + +/* +================ +idAFAttachment::Restore + +unarchives object from save game file +================ +*/ +void idAFAttachment::Restore( idRestoreGame *savefile ) { + savefile->ReadObject( reinterpret_cast( body ) ); + savefile->ReadInt( idleAnim ); + savefile->ReadJoint( attachJoint ); + + SetCombatModel(); + LinkCombat(); +} + +/* +================ +idAFAttachment::Hide +================ +*/ +void idAFAttachment::Hide( void ) +{ + idEntity::Hide(); + + // ishtvan: Should hide any bind children of the head (copied from idActor) + idEntity *ent; + idEntity *next; + for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { + next = ent->GetNextTeamEntity(); + if ( ent->GetBindMaster() == this ) { + ent->Hide(); + if ( ent->IsType( idLight::Type ) ) { + static_cast( ent )->Off(); + } + } + } + + UnlinkCombat(); +} + +/* +================ +idAFAttachment::Show +================ +*/ +void idAFAttachment::Show( void ) +{ + idEntity::Show(); + + // ishtvan: Should show any bind children of the head (copied from idActor) + idEntity *ent; + idEntity *next; + + for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { + next = ent->GetNextTeamEntity(); + if ( ent->GetBindMaster() == this ) { + ent->Show(); + if ( ent->IsType( idLight::Type ) ) { + static_cast( ent )->On(); + } + } + } + LinkCombat(); +} + +/* +============ +idAFAttachment::Damage + +Pass damage to body at the bindjoint +============ +*/ +void idAFAttachment::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, trace_t *tr ) +{ + trace_t *pTrace = NULL; + + if( tr ) + { + trace_t TraceCopy = *tr; + + //TDM Fix: Propagate the trace. + // Also, some things like KO check the endpoint of the trace rather than the "location" for the joint hit + // So change this in the trace to the attach joint on the body we're attached to. + TraceCopy.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ); + pTrace = &TraceCopy; + } + + if ( body ) + { + body->Damage( inflictor, attacker, dir, damageDefName, damageScale, attachJoint, pTrace ); + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AF Attachment %s passed along damage to actor %s at attachjoint %d \r", name.c_str(), body->name.c_str(), (int) attachJoint ); + } +} + +/* +================ +idAFAttachment::AddDamageEffect +================ +*/ +void idAFAttachment::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { + if ( body ) { + trace_t c = collision; + c.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ); + body->AddDamageEffect( c, velocity, damageDefName ); + } +} + +/* +================ +idAFAttachment::GetImpactInfo +================ +*/ +void idAFAttachment::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { + if ( body ) { + body->GetImpactInfo( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, info ); + } else { + idEntity::GetImpactInfo( ent, id, point, info ); + } +} + +/* +================ +idAFAttachment::ApplyImpulse +================ +*/ +void idAFAttachment::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + if ( body ) { + body->ApplyImpulse( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, impulse ); + } else { + idEntity::ApplyImpulse( ent, id, point, impulse ); + } +} + +/* +================ +idAFAttachment::AddForce +================ +*/ +void idAFAttachment::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { + if ( body ) { + body->AddForce( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, force ); + } else { + idEntity::AddForce( ent, id, point, force ); + } +} + +/* +================ +idAFAttachment::PlayIdleAnim +================ +*/ +void idAFAttachment::PlayIdleAnim( int blendTime ) { + if ( idleAnim && ( idleAnim != animator.CurrentAnim( ANIMCHANNEL_ALL )->AnimNum() ) ) { + animator.CycleAnim( ANIMCHANNEL_ALL, idleAnim, gameLocal.time, blendTime ); + } +} + +/* +================ +idAfAttachment::Think +================ +*/ +void idAFAttachment::Think( void ) { + idAnimatedEntity::Think(); + if ( thinkFlags & TH_UPDATEPARTICLES ) { + UpdateDamageEffects(); + } +} + +/* +================ +idAFAttachment::SetCombatModel +================ +*/ +void idAFAttachment::SetCombatModel( void ) { + if ( combatModel ) { + combatModel->Unlink(); + combatModel->LoadModel( modelDefHandle ); + } else { + combatModel = new idClipModel( modelDefHandle ); + } + + if (m_StimResponseColl->HasResponse()) + { + combatModel->SetContents( combatModel->GetContents() | CONTENTS_RESPONSE ); + } + + combatModel->SetOwner( body ); +} + +/* +================ +idAFAttachment::GetCombatModel +================ +*/ +idClipModel *idAFAttachment::GetCombatModel( void ) const { + return combatModel; +} + +/* +================ +idAFAttachment::LinkCombat +================ +*/ +void idAFAttachment::LinkCombat( void ) { + if ( fl.hidden ) { + return; + } + + if ( combatModel ) { + combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); + } +} + +/* +================ +idAFAttachment::UnlinkCombat +================ +*/ +void idAFAttachment::UnlinkCombat( void ) { + if ( combatModel ) { + combatModel->Unlink(); + } +} + +idEntity* idAFAttachment::GetResponseEntity() +{ + return body; +} + +/* +=============================================================================== + + idAFEntity_Base + +=============================================================================== +*/ + +const idEventDef EV_SetConstraintPosition( "SetConstraintPosition", "sv" ); +const idEventDef EV_GetLinearVelocityB( "getLinearVelocityB", "d", 'v' ); +const idEventDef EV_GetAngularVelocityB( "getAngularVelocityB", "d", 'v' ); +const idEventDef EV_SetLinearVelocityB( "setLinearVelocityB", "vd" ); +const idEventDef EV_SetAngularVelocityB( "setAngularVelocityB", "vd" ); +const idEventDef EV_GetNumBodies( "getNumBodies", NULL, 'd' ); +const idEventDef EV_RestoreAddedEnts( "restoreAddedEnts", NULL ); + +CLASS_DECLARATION( idAnimatedEntity, idAFEntity_Base ) + EVENT( EV_SetConstraintPosition, idAFEntity_Base::Event_SetConstraintPosition ) + EVENT( EV_GetLinearVelocityB, idAFEntity_Base::Event_GetLinearVelocityB ) + EVENT( EV_GetAngularVelocityB, idAFEntity_Base::Event_GetAngularVelocityB ) + EVENT( EV_SetLinearVelocityB, idAFEntity_Base::Event_SetLinearVelocityB ) + EVENT( EV_SetAngularVelocityB, idAFEntity_Base::Event_SetAngularVelocityB ) + EVENT( EV_GetNumBodies, idAFEntity_Base::Event_GetNumBodies ) + EVENT( EV_RestoreAddedEnts, idAFEntity_Base::RestoreAddedEnts ) + +END_CLASS + +static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f; +static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f; + +/* +================ +idAFEntity_Base::idAFEntity_Base +================ +*/ +idAFEntity_Base::idAFEntity_Base( void ) +{ + combatModel = NULL; + combatModelContents = 0; + nextSoundTime = 0; + spawnOrigin.Zero(); + spawnAxis.Identity(); + m_bGroundWhenDragged = false; + m_GroundBodyMinNum = 0; + m_bDragAFDamping = false; + m_bCollideWithTeam = true; + m_bAFPushMoveables = false; + m_AddedEnts.Clear(); +} + +/* +================ +idAFEntity_Base::~idAFEntity_Base +================ +*/ +idAFEntity_Base::~idAFEntity_Base( void ) +{ + delete combatModel; + combatModel = NULL; + m_GroundBodyList.Clear(); + m_AddedEnts.Clear(); +} + +/* +================ +idAFEntity_Base::Save +================ +*/ +void idAFEntity_Base::Save( idSaveGame *savefile ) const +{ + savefile->WriteInt( combatModelContents ); + savefile->WriteClipModel( combatModel ); + savefile->WriteVec3( spawnOrigin ); + savefile->WriteMat3( spawnAxis ); + savefile->WriteInt( nextSoundTime ); + + savefile->WriteBool( m_bGroundWhenDragged ); + savefile->WriteInt( m_GroundBodyList.Num() ); + for( int i = 0; i < m_GroundBodyList.Num(); i++ ) + savefile->WriteInt( m_GroundBodyList[i] ); + savefile->WriteInt( m_GroundBodyMinNum ); + savefile->WriteBool( m_bDragAFDamping ); + savefile->WriteBool( m_bCollideWithTeam ); + savefile->WriteBool( m_bAFPushMoveables ); + + savefile->WriteInt( m_AddedEnts.Num() ); + for( int j = 0; j < m_AddedEnts.Num(); j++ ) + { + m_AddedEnts[j].ent.Save( savefile ); + savefile->WriteString( m_AddedEnts[j].bodyName ); + savefile->WriteString( m_AddedEnts[j].AddedToBody ); + savefile->WriteInt( m_AddedEnts[j].entContents ); + savefile->WriteInt( m_AddedEnts[j].entClipMask ); + // Check the body contents and clipmask just before saving, instead of putting in + // the variables bodyContents and bodyClipMask. These are only used on restoring. + // go to hell, const correctness! + idAFEntity_Base *thisNoConst = const_cast(this); + idAFBody *body = thisNoConst->GetAFPhysics()->GetBody( m_AddedEnts[j].bodyName.c_str() ); + savefile->WriteInt( body->GetClipModel()->GetContents() ); + savefile->WriteInt( body->GetClipMask() ); + } + + af.Save( savefile ); +} + +/* +================ +idAFEntity_Base::Restore +================ +*/ +void idAFEntity_Base::Restore( idRestoreGame *savefile ) +{ + savefile->ReadInt( combatModelContents ); + savefile->ReadClipModel( combatModel ); + savefile->ReadVec3( spawnOrigin ); + savefile->ReadMat3( spawnAxis ); + savefile->ReadInt( nextSoundTime ); + LinkCombat(); + + savefile->ReadBool( m_bGroundWhenDragged ); + + int GroundBodyListNum; + savefile->ReadInt( GroundBodyListNum ); + m_GroundBodyList.SetNum( GroundBodyListNum ); + for( int i = 0; i < GroundBodyListNum; i++ ) + savefile->ReadInt( m_GroundBodyList[i] ); + + savefile->ReadInt( m_GroundBodyMinNum ); + savefile->ReadBool( m_bDragAFDamping ); + savefile->ReadBool( m_bCollideWithTeam ); + savefile->ReadBool( m_bAFPushMoveables ); + + int AddedEntsNum; + savefile->ReadInt( AddedEntsNum ); + m_AddedEnts.SetNum( AddedEntsNum ); + for( int j = 0; j < AddedEntsNum; j++ ) + { + m_AddedEnts[j].ent.Restore( savefile ); + savefile->ReadString( m_AddedEnts[j].bodyName ); + savefile->ReadString( m_AddedEnts[j].AddedToBody ); + savefile->ReadInt( m_AddedEnts[j].entContents ); + savefile->ReadInt( m_AddedEnts[j].entClipMask ); + savefile->ReadInt( m_AddedEnts[j].bodyContents ); + savefile->ReadInt( m_AddedEnts[j].bodyClipMask ); + } + + af.Restore( savefile ); + if( m_bAFPushMoveables ) + { + af.SetupPose( this, gameLocal.time ); + af.GetPhysics()->EnableClip(); + } + + // Schedule any added entities for re-adding when they have spawned + PostEventMS( &EV_RestoreAddedEnts, 0 ); +} + +/* +================ +idAFEntity_Base::Spawn +================ +*/ +void idAFEntity_Base::Spawn( void ) +{ + spawnOrigin = GetPhysics()->GetOrigin(); + spawnAxis = GetPhysics()->GetAxis(); + nextSoundTime = 0; + m_bGroundWhenDragged = spawnArgs.GetBool( "ground_when_dragged", "0" ); + m_GroundBodyMinNum = spawnArgs.GetInt( "ground_min_number", "0" ); + m_bDragAFDamping = spawnArgs.GetBool( "drag_af_damping", "0" ); + m_bCollideWithTeam = spawnArgs.GetBool( "af_collide_with_team", "1" ); // true by default + m_bAFPushMoveables = spawnArgs.GetBool( "af_push_moveables", "0" ); +} + +/* +================ +idAFEntity_Base::LoadAF +================ +*/ +bool idAFEntity_Base::LoadAF( void ) +{ + idStr fileName; + + if ( !spawnArgs.GetString( "articulatedFigure", "*unknown*", fileName ) ) { + return false; + } + + af.SetAnimator( GetAnimator() ); + if ( !af.Load( this, fileName ) ) { + gameLocal.Error( "idAFEntity_Base::LoadAF: Couldn't load af file '%s' on entity '%s'", fileName.c_str(), name.c_str() ); + } + + af.Start(); + + af.GetPhysics()->Rotate( spawnAxis.ToRotation() ); + af.GetPhysics()->Translate( spawnOrigin ); + + LoadState( spawnArgs ); + + af.UpdateAnimation(); + animator.CreateFrame( gameLocal.time, true ); + UpdateVisuals(); + + SetUpGroundingVars(); + + if( m_bAFPushMoveables ) + { + af.SetupPose( this, gameLocal.time ); + af.GetPhysics()->EnableClip(); + } + + return true; +} + +/* +================ +idAFEntity_Base::Think +================ +*/ +void idAFEntity_Base::Think( void ) +{ + if( !IsHidden() ) + { + RunPhysics(); + UpdateAnimation(); + } + if ( thinkFlags & TH_UPDATEVISUALS ) + { + Present(); + LinkCombat(); + } + +// TDM: Anim/AF physics mods, generalized behavior that originally was just on AI + + // Update the AF bodies for the anim if we are set to do that + if ( m_bAFPushMoveables && af.IsLoaded() + && !IsType(idAI::Type) && !IsHidden() + && animator.FrameHasChanged( gameLocal.time ) ) + { + af.ChangePose( this, gameLocal.time ); + + // copied from idAI::PushWithAF + afTouch_t touchList[ MAX_GENTITIES ]; + idEntity *pushed_ents[ MAX_GENTITIES ]; + idEntity *ent; + idVec3 vel( vec3_origin ); + int num_pushed(0), i, j; + + int num = af.EntitiesTouchingAF( touchList ); + for( i = 0; i < num; i++ ) + { + // skip projectiles + if ( touchList[ i ].touchedEnt->IsType( idProjectile::Type ) ) + continue; + + // make sure we havent pushed this entity already. this avoids causing double damage + for( j = 0; j < num_pushed; j++ ) + { + if ( pushed_ents[ j ] == touchList[ i ].touchedEnt ) + break; + } + if ( j >= num_pushed ) + { + ent = touchList[ i ].touchedEnt; + pushed_ents[num_pushed++] = ent; + vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin(); + vel.Normalize(); + ent->ApplyImpulse( this, touchList[i].touchedClipModel->GetId(), ent->GetPhysics()->GetOrigin(), cv_ai_bumpobject_impulse.GetFloat() * vel ); + } + } + } +} + +/* +================ +idAFEntity_Base::BodyForClipModelId +================ +*/ +int idAFEntity_Base::BodyForClipModelId( int id ) const { + return af.BodyForClipModelId( id ); +} + +/* +================ +idAFEntity_Base::SaveState +================ +*/ +void idAFEntity_Base::SaveState( idDict &args ) const { + const idKeyValue *kv; + + // save the ragdoll pose + af.SaveState( args ); + + // save all the bind constraints + kv = spawnArgs.MatchPrefix( "bindConstraint ", NULL ); + while ( kv ) { + args.Set( kv->GetKey(), kv->GetValue() ); + kv = spawnArgs.MatchPrefix( "bindConstraint ", kv ); + } + + // save the bind if it exists + kv = spawnArgs.FindKey( "bind" ); + if ( kv ) { + args.Set( kv->GetKey(), kv->GetValue() ); + } + kv = spawnArgs.FindKey( "bindToJoint" ); + if ( kv ) { + args.Set( kv->GetKey(), kv->GetValue() ); + } + kv = spawnArgs.FindKey( "bindToBody" ); + if ( kv ) { + args.Set( kv->GetKey(), kv->GetValue() ); + } +} + +/* +================ +idAFEntity_Base::LoadState +================ +*/ +void idAFEntity_Base::LoadState( const idDict &args ) { + af.LoadState( args ); +} + +/* +================ +idAFEntity_Base::AddBindConstraints +================ +*/ +void idAFEntity_Base::AddBindConstraints( void ) { + af.AddBindConstraints(); +} + +/* +================ +idAFEntity_Base::RemoveBindConstraints +================ +*/ +void idAFEntity_Base::RemoveBindConstraints( void ) { + af.RemoveBindConstraints(); +} + +/* +================ +idAFEntity_Base::GetImpactInfo +================ +*/ +void idAFEntity_Base::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { + if ( af.IsActive() ) { + af.GetImpactInfo( ent, id, point, info ); + } else { + idEntity::GetImpactInfo( ent, id, point, info ); + } +} + +/* +================ +idAFEntity_Base::ApplyImpulse +================ +*/ +void idAFEntity_Base::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + if ( af.IsLoaded() ) { + af.ApplyImpulse( ent, id, point, impulse ); + } + if ( !af.IsActive() ) { + idEntity::ApplyImpulse( ent, id, point, impulse ); + } +} + +/* +================ +idAFEntity_Base::AddForce +================ +*/ +void idAFEntity_Base::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { + if ( af.IsLoaded() ) { + af.AddForce( ent, id, point, force ); + } + if ( !af.IsActive() ) { + idEntity::AddForce( ent, id, point, force ); + } +} + +/* +================ +idAFEntity_Base::Collide +================ +*/ +bool idAFEntity_Base::Collide( const trace_t &collision, const idVec3 &velocity ) { + float v, f; + + idEntity *e = gameLocal.entities[collision.c.entityNum]; + + if(e) + { + ProcCollisionStims( e, collision.c.id ); + if( e->IsType( idAI::Type ) ) + { + idAI *alertee = static_cast(e); + alertee->TactileAlert( this ); + } + } + + if ( af.IsActive() ) + { + v = -( velocity * collision.c.normal ); + if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) { + f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ); + if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) { + // don't set the volume unless there is a bounce sound as it overrides the entire channel + // which causes footsteps on ai's to not honor their shader parms + SetSoundVolume( f ); + } + nextSoundTime = gameLocal.time + 500; + } + } + + return false; +} + +/* +================ +idAFEntity_Base::GetPhysicsToVisualTransform +================ +*/ +bool idAFEntity_Base::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { + if ( af.IsActive() ) { + af.GetPhysicsToVisualTransform( origin, axis ); + return true; + } + return idEntity::GetPhysicsToVisualTransform( origin, axis ); +} + +/* +================ +idAFEntity_Base::UpdateAnimationControllers +================ +*/ +bool idAFEntity_Base::UpdateAnimationControllers( void ) { + if ( af.IsActive() ) { + if ( af.UpdateAnimation() ) { + return true; + } + } + return false; +} + +/* +================ +idAFEntity_Base::SetCombatModel +================ +*/ +void idAFEntity_Base::SetCombatModel( void ) { + if ( combatModel ) { + combatModel->Unlink(); + combatModel->LoadModel( modelDefHandle ); + } else { + combatModel = new idClipModel( modelDefHandle ); + } +} + +/* +================ +idAFEntity_Base::GetCombatModel +================ +*/ +idClipModel *idAFEntity_Base::GetCombatModel( void ) const { + return combatModel; +} + +/* +================ +idAFEntity_Base::SetCombatContents +================ +*/ +bool idAFEntity_Base::SetCombatContents( bool enable ) { + assert( combatModel ); + bool oldIsEnabled = (combatModel->GetContents() != 0); + if ( enable && combatModelContents ) { + assert( !combatModel->GetContents() ); + combatModel->SetContents( combatModelContents ); + combatModelContents = 0; + } else if ( !enable && combatModel->GetContents() ) { + assert( !combatModelContents ); + combatModelContents = combatModel->GetContents(); + combatModel->SetContents( 0 ); + } + return oldIsEnabled; +} + +/* +================ +idAFEntity_Base::LinkCombat +================ +*/ +void idAFEntity_Base::LinkCombat( void ) { + if ( fl.hidden ) { + return; + } + if ( combatModel ) { + combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); + } +} + +/* +================ +idAFEntity_Base::UnlinkCombat +================ +*/ +void idAFEntity_Base::UnlinkCombat( void ) { + if ( combatModel ) { + combatModel->Unlink(); + } +} + +/* +================ +idAFEntity_Base::FreeModelDef +================ +*/ +void idAFEntity_Base::FreeModelDef( void ) { + UnlinkCombat(); + idEntity::FreeModelDef(); +} + +/* +=============== +idAFEntity_Base::ShowEditingDialog +=============== +*/ +void idAFEntity_Base::ShowEditingDialog( void ) { + common->InitTool( EDITOR_AF, &spawnArgs ); +} + +/* +================ +idAFEntity_Base::DropAFs + + The entity should have the following key/value pairs set: + "def_dropAF" "af def" + "dropSkin" "skin name" + To drop multiple articulated figures the following key/value pairs can be used: + "def_dropAF*" "af def" + where * is an aribtrary string. +================ +*/ +void idAFEntity_Base::DropAFs( idEntity *ent, const char *type, idList *list ) { + const idKeyValue *kv; + const char *skinName; + idEntity *newEnt; + idAFEntity_Base *af; + idDict args; + const idDeclSkin *skin; + + // drop the articulated figures + kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), NULL ); + while ( kv ) { + + args.Set( "classname", kv->GetValue() ); + gameLocal.SpawnEntityDef( args, &newEnt ); + + if ( newEnt && newEnt->IsType( idAFEntity_Base::Type ) ) { + af = static_cast(newEnt); + af->GetPhysics()->SetOrigin( ent->GetPhysics()->GetOrigin() ); + af->GetPhysics()->SetAxis( ent->GetPhysics()->GetAxis() ); + af->af.SetupPose( ent, gameLocal.time ); + if ( list ) { + list->Append( af ); + } + } + + kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), kv ); + } + + // change the skin to hide all the dropped articulated figures + skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) ); + if ( skinName[0] ) { + skin = declManager->FindSkin( skinName ); + ent->SetSkin( skin ); + } +} + +/* +================ +idAFEntity_Base::Event_SetConstraintPosition +================ +*/ +void idAFEntity_Base::Event_SetConstraintPosition( const char *name, const idVec3 &pos ) { + af.SetConstraintPosition( name, pos ); +} + +void idAFEntity_Base::Event_SetLinearVelocityB( idVec3 &NewVelocity, int id ) +{ + GetPhysics()->SetLinearVelocity( NewVelocity, id ); +} + +void idAFEntity_Base::Event_SetAngularVelocityB( idVec3 &NewVelocity, int id ) +{ + GetPhysics()->SetAngularVelocity( NewVelocity, id ); +} + +void idAFEntity_Base::Event_GetLinearVelocityB( int id ) +{ + idThread::ReturnVector( GetPhysics()->GetLinearVelocity( id ) ); +} + +void idAFEntity_Base::Event_GetAngularVelocityB( int id ) +{ + idThread::ReturnVector( GetPhysics()->GetAngularVelocity( id ) ); +} + +void idAFEntity_Base::Event_GetNumBodies( void ) +{ + idThread::ReturnInt( static_cast( GetPhysics() )->GetNumBodies() ); +} + +void idAFEntity_Base::SetUpGroundingVars( void ) +{ + if( m_bGroundWhenDragged && af.IsLoaded() ) + { + idLexer src; + idToken token; + idStr tempStr = spawnArgs.GetString( "ground_critical_bodies", "" ); + + m_GroundBodyList.Clear(); + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Parsing critical ground bodies list %s\r", tempStr.c_str()); + if( tempStr.Length() ) + { + src.LoadMemory( tempStr.c_str(), tempStr.Length(), "" ); + src.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS | LEXFL_ALLOWPATHNAMES ); + + while( src.ReadToken( &token ) ) + m_GroundBodyList.Append( GetAFPhysics()->GetBodyId(token.c_str()) ); + + src.FreeSource(); + } + } +} + +bool idAFEntity_Base::CollidesWithTeam( void ) +{ + return m_bCollideWithTeam; +} + +void idAFEntity_Base::AddEntByJoint( idEntity *ent, jointHandle_t joint ) +{ + int bodID(0); + + if( af.IsLoaded() ) + { + bodID = BodyForClipModelId( JOINT_HANDLE_TO_CLIPMODEL_ID( joint ) ); + AddEntByBody( ent, bodID, joint ); + } +} + +void idAFEntity_Base::AddEntByBody( idEntity *ent, int bodID, jointHandle_t joint ) +{ + float EntMass(0.0), AFMass(0.0), MassOut(0.0), density(0.0); + idVec3 COM(vec3_zero), orig(vec3_zero); + idMat3 inertiaTensor, axis; + idClipModel *EntClip(NULL), *NewClip(NULL); + int newBodID(0); + SAddedEnt Entry; + idStr AddName; + + if( !af.IsLoaded() ) return; + + //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AddEntByBody: Called, ent %s, body %d\r", ent->name.c_str(), bodID ); + + + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Entity origin: %s \r", orig.ToString() ); + + EntClip = ent->GetPhysics()->GetClipModel(); + axis = EntClip->GetAxis(); + orig = EntClip->GetOrigin(); + + NewClip = new idClipModel(EntClip); + + // Propagate CONTENTS_CORPSE from AF to new clipmodel + if( GetAFPhysics()->GetContents() & CONTENTS_CORPSE ) + NewClip->SetContents( (NewClip->GetContents() & (~CONTENTS_SOLID)) | CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); + + // EntMass = ent->GetPhysics()->GetMass(); + // FIX: Large masses aren't working, the AFs are not quite that flexible that you can put on a huge mass + // Or it could be the occasional small negative elements in the inertia tensor. + // In any case for now, we set the masses to 1 so they only collide, don't pull on the AF + EntMass = 1.0f; + if ( EntMass <= 0.0f || FLOAT_IS_NAN( EntMass ) ) + { + EntMass = 1.0f; + } + AFMass = GetAFPhysics()->GetMass(); + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Retrieved masses. AF mass: %f , Ent mass: %f \r", AFMass, EntMass ); + + // Trick: Use a test density of 1.0 here, then divide the actual mass by output mass to get actual density + NewClip->GetMassProperties( 1.0f, MassOut, COM, inertiaTensor ); + + // AF bodies want to have their origin at the center of mass + NewClip->TranslateOrigin( -COM ); + orig += COM * axis; + + // DEBUG: +// idVec3 COMNew; +// NewClip->GetMassProperties( 1.0f, MassOut, COMNew, inertiaTensor ); +// DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("AF Bind: New Clip COM: %s \r", COMNew.ToString() ); +// DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("AF Bind: Modified origin: %s \r", orig.ToString() ); + + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Linking clipmodel copy... \r" ); + // FIXME: Do we really want to set id 0 here? Won't this conflict? + NewClip->Link( gameLocal.clip, this, 0, orig, axis ); + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Clipmodel linked.\r"); + + // Add the mass in the AF Structure + density = idMath::Fabs( EntMass / MassOut ); + GetAFPhysics()->SetMass( AFMass + EntMass ); + + AddName = ent->name + idStr(gameLocal.time); + + idAFBody *bodyExist = GetAFPhysics()->GetBody(bodID); + idAFBody *body = new idAFBody( AddName, NewClip, density ); + body->SetClipMask( bodyExist->GetClipMask() ); + body->SetSelfCollision( false ); + body->SetRerouteEnt( ent ); + body->SetWorldOrigin( orig ); + body->SetWorldAxis( axis ); + newBodID = GetAFPhysics()->AddBody( body ); + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Body added to physics_AF with id %d.\r", newBodID); + + // ishtvan: Don't add the constraint while animating, wait until full ragdoll mode + if( af.IsActive() ) + { + idAFConstraint_Fixed *cf = new idAFConstraint_Fixed( AddName, body, bodyExist ); + GetAFPhysics()->AddConstraint( cf ); + } + + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Constraint added between new body %s and original body %s.\r", body->GetName().c_str(), bodyExist->GetName().c_str()); + + // Now add body to AF object, for updating with idAF::ChangePos and the like + // We use AF_JOINTMOD_NONE since this new AF shouldn't actually stretch joints on the model when it moves + af.AddBodyExtern( this, body, bodyExist, AF_JOINTMOD_NONE, joint ); + + // Add to list + Entry.ent = ent; + Entry.AddedToBody = bodyExist->GetName(); + Entry.bodyName = AddName; + Entry.bodyContents = body->GetClipModel()->GetContents(); + Entry.bodyClipMask = body->GetClipMask(); + Entry.entContents = EntClip->GetContents(); + Entry.entClipMask = ent->GetPhysics()->GetClipMask(); + + m_AddedEnts.Append( Entry ); + + // Disable the entity's clipmodel + // leave CONTENTS_RESPONSE and CONTENTS_FROBABLE alone + int SetContents = 0; + if( (EntClip->GetContents() & CONTENTS_RESPONSE) != 0 ) + SetContents = CONTENTS_RESPONSE; + + if( (EntClip->GetContents() & CONTENTS_FROBABLE) != 0 + // Temporary fix: CONTENTS_FROBABLE is not currently set on all frobables + || ent->m_bFrobable ) + SetContents = SetContents | CONTENTS_FROBABLE; + + EntClip->SetContents( SetContents ); + ent->GetPhysics()->SetClipMask( 0 ); + + // Make sure the AF activates as soon as this is done + if( af.IsActive() ) + GetAFPhysics()->Activate(); + + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Done.\r"); +} + +/* +================ +idAFEntity_Base::RemoveAddedEnt +================ +*/ +void idAFEntity_Base::RemoveAddedEnt( idEntity *ent ) +{ + bool bRemoved = false; + idStr bodyName; + + for( int i=m_AddedEnts.Num() - 1; i >= 0; i-- ) + { + if(ent && (m_AddedEnts[i].ent.GetEntity() == ent)) + { + bodyName = m_AddedEnts[i].bodyName; + GetAFPhysics()->DeleteBody( bodyName.c_str() ); + af.DeleteBodyExtern( this, bodyName.c_str() ); + + ent->GetPhysics()->SetContents( m_AddedEnts[i].entContents ); + ent->GetPhysics()->SetClipMask( m_AddedEnts[i].entClipMask ); + m_AddedEnts.RemoveIndex(i); + // Added ent AF bodies have a mass of 1 for now + // GetAFPhysics()->SetMass( GetPhysics()->GetMass() - ent->GetPhysics()->GetMass() ); + GetAFPhysics()->SetMass( GetPhysics()->GetMass() - 1.0f ); + + bRemoved = true; + } + } + + if( bRemoved && IsActiveAF() ) + ActivatePhysics( this ); +} + +jointHandle_t idAFEntity_Base::JointForBody( int body ) +{ + return af.JointForBody( body ); +} + +int idAFEntity_Base::BodyForJoint( jointHandle_t joint ) +{ + return af.BodyForJoint( joint ); +} + +idAFBody *idAFEntity_Base::AFBodyForEnt( idEntity *ent ) +{ + idAFBody *returnBody = NULL; + for( int i=0; i < m_AddedEnts.Num(); i++ ) + { + if( m_AddedEnts[i].ent.GetEntity() == ent ) + { + idStr bodyName = m_AddedEnts[i].bodyName; + returnBody = GetAFPhysics()->GetBody( bodyName.c_str() ); + break; + } + } + + return returnBody; +} + +void idAFEntity_Base::RestoreAddedEnts( void ) +{ + // This must be called after all entities are loaded + int TempContents, TempClipMask, bodyID; + idEntity *ent; + idList OldAdded; + idStr temp; + + OldAdded = m_AddedEnts; + m_AddedEnts.Clear(); + + for(int i=0; iGetPhysics()->SetContents( TempContents ); + ent->GetPhysics()->SetClipMask( TempClipMask ); + + bodyID = GetAFPhysics()->GetBodyId( OldAdded[i].AddedToBody ); + + // Add the body again + AddEntByBody( ent, bodyID ); + + // restore the saved contents and clipmask of the AF body just added + idAFBody *body = AFBodyForEnt( ent ); + if( body ) + { + TempContents = OldAdded[i].bodyContents; + TempClipMask = OldAdded[i].bodyClipMask; + body->GetClipModel()->SetContents( TempContents ); + body->SetClipMask( TempClipMask ); + } + } +} + +void idAFEntity_Base::UpdateAddedEntConstraints( void ) +{ + for( int i=0; i < m_AddedEnts.Num(); i++ ) + { + idStr AddName = m_AddedEnts[i].bodyName; + idAFBody *body = GetAFPhysics()->GetBody( AddName.c_str() ); + idAFBody *bodyExist = GetAFPhysics()->GetBody( m_AddedEnts[i].AddedToBody ); + + // get the AF bodies in their most recent position (just before ragdoll start) + af.ChangePose( this, gameLocal.time ); + // add a constraint for the current position + idAFConstraint_Fixed *cf = new idAFConstraint_Fixed( AddName, body, bodyExist ); + GetAFPhysics()->AddConstraint( cf ); + } +} + +void idAFEntity_Base::UnbindNotify( idEntity *ent ) +{ + idEntity::UnbindNotify( ent ); + // remove ent from AF if it was dynamically added as an AF body + RemoveAddedEnt( ent ); +} + +void idAFEntity_Base::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, trace_t *tr ) +{ + idEntity *reroute = NULL; + idAFBody *StruckBody = NULL; + int bodID; + + if( tr ) + { + bodID = BodyForClipModelId( tr->c.id ); + StruckBody = GetAFPhysics()->GetBody( bodID ); + + if( StruckBody != NULL ) + reroute = StruckBody->GetRerouteEnt(); + } + + // check for reroute entity on the AF body and damage this instead + if( reroute != NULL ) + reroute->Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); + else + idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); +} + +/* +====================== +idAFEntity_Base::ParseAttachments +====================== +*/ +void idAFEntity_Base::ParseAttachments( void ) +{ + return; +} + +/* +====================== +idAFEntity_Base::ParseAttachmentsAF +====================== +*/ +void idAFEntity_Base::ParseAttachmentsAF( void ) +{ + // FIX: Preserve initial frame facing when posing the AF prior to attaching + // otherwise relationships between new AF bodies and AF bodies they're attached to + // get screwed up (since attached entities are attached when the AFEntity is still facing 0,0,0) + idMat3 tempAxis = renderEntity.axis; + idMat3 tempAxis2 = GetPhysics()->GetAxis(); + renderEntity.axis = mat3_identity; + SetAxis(mat3_identity); + + af.SetupPose(this, gameLocal.time); + idEntity::ParseAttachments(); + + renderEntity.axis = tempAxis; + SetAxis(tempAxis2); +} + +void idAFEntity_Base::ReAttachToPos + ( const char *AttName, const char *PosName ) +{ + int ind = GetAttachmentIndex( AttName ); + if (ind == -1 ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); + return; + } + + idEntity* ent = GetAttachment( ind ); + + if( !ent ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", AttName, name.c_str()); + return; + } + + // retain the AF body contents (don't want to accidentally re-enable them if clip disabled) + idAFBody *body = NULL; + int bodyContents = 0, bodyClipMask = 0; + bool bStoredAFBodyInfo = false; + if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL ) + { + bodyContents = body->GetClipModel()->GetContents(); + bodyClipMask = body->GetClipMask(); + bStoredAFBodyInfo = true; + } + + idEntity::ReAttachToPos( AttName, PosName ); + + // copy over the old AF body contents + if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL + && bStoredAFBodyInfo ) + { + body->GetClipModel()->SetContents( bodyContents ); + body->SetClipMask( bodyClipMask ); + } +} + +void idAFEntity_Base::ReAttachToCoords + ( const char *AttName, idStr jointName, + idVec3 offset, idAngles angles ) +{ + idEntity *ent(NULL); + CAttachInfo *attachment = GetAttachInfo( AttName ); + + if( !attachment ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); + return; + } + + ent = attachment->ent.GetEntity(); + if( !attachment->ent.IsValid() || !ent ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", name.c_str()); + return; + } + + // retain the AF body contents (don't want to accidentally re-enable them if clip disabled) + idAFBody *body = NULL; + int bodyContents = 0, bodyClipMask = 0; + bool bStoredAFBodyInfo = false; + if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL ) + { + bodyContents = body->GetClipModel()->GetContents(); + bodyClipMask = body->GetClipMask(); + bStoredAFBodyInfo = true; + } + + idAnimatedEntity::ReAttachToCoords( AttName, jointName, offset, angles ); + + // copy over the old AF body contents + if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL + && bStoredAFBodyInfo ) + { + body->GetClipModel()->SetContents( bodyContents ); + body->SetClipMask( bodyClipMask ); + } +} + +/* +=============================================================================== + +idAFEntity_Gibbable + +=============================================================================== +*/ + +const idEventDef EV_Gib( "gib", "s" ); +const idEventDef EV_Gibbed( "" ); + +CLASS_DECLARATION( idAFEntity_Base, idAFEntity_Gibbable ) + EVENT( EV_Gib, idAFEntity_Gibbable::Event_Gib ) + EVENT( EV_Gibbed, idAFEntity_Base::Event_Remove ) +END_CLASS + + +/* +================ +idAFEntity_Gibbable::idAFEntity_Gibbable +================ +*/ +idAFEntity_Gibbable::idAFEntity_Gibbable( void ) { + skeletonModel = NULL; + skeletonModelDefHandle = -1; + gibbed = false; +} + +/* +================ +idAFEntity_Gibbable::~idAFEntity_Gibbable +================ +*/ +idAFEntity_Gibbable::~idAFEntity_Gibbable() { + if ( skeletonModelDefHandle != -1 ) { + gameRenderWorld->FreeEntityDef( skeletonModelDefHandle ); + skeletonModelDefHandle = -1; + } +} + +/* +================ +idAFEntity_Gibbable::Save +================ +*/ +void idAFEntity_Gibbable::Save( idSaveGame *savefile ) const { + savefile->WriteBool( gibbed ); + savefile->WriteBool( combatModel != NULL ); +} + +/* +================ +idAFEntity_Gibbable::Restore +================ +*/ +void idAFEntity_Gibbable::Restore( idRestoreGame *savefile ) { + bool hasCombatModel; + + savefile->ReadBool( gibbed ); + savefile->ReadBool( hasCombatModel ); + + InitSkeletonModel(); + + if ( hasCombatModel ) { + SetCombatModel(); + LinkCombat(); + } +} + +/* +================ +idAFEntity_Gibbable::Spawn +================ +*/ +void idAFEntity_Gibbable::Spawn( void ) { + InitSkeletonModel(); + + gibbed = false; +} + +/* +================ +idAFEntity_Gibbable::InitSkeletonModel +================ +*/ +void idAFEntity_Gibbable::InitSkeletonModel( void ) { + const char *modelName; + const idDeclModelDef *modelDef; + + skeletonModel = NULL; + skeletonModelDefHandle = -1; + + modelName = spawnArgs.GetString( "model_gib" ); + + modelDef = NULL; + if ( modelName[0] != '\0' ) { + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelName, false ) ); + if ( modelDef ) { + skeletonModel = modelDef->ModelHandle(); + } else { + skeletonModel = renderModelManager->FindModel( modelName ); + } + if ( skeletonModel != NULL && renderEntity.hModel != NULL ) { + if ( skeletonModel->NumJoints() != renderEntity.hModel->NumJoints() ) { + gameLocal.Error( "gib model '%s' has different number of joints than model '%s'", + skeletonModel->Name(), renderEntity.hModel->Name() ); + } + } + } +} + +/* +================ +idAFEntity_Gibbable::Present +================ +*/ +void idAFEntity_Gibbable::Present( void ) { + renderEntity_t skeleton; + + if ( !gameLocal.isNewFrame ) { + return; + } + + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { + return; + } + + // update skeleton model + if ( gibbed && !IsHidden() && skeletonModel != NULL ) { + skeleton = renderEntity; + skeleton.hModel = skeletonModel; + // add to refresh list + if ( skeletonModelDefHandle == -1 ) { + skeletonModelDefHandle = gameRenderWorld->AddEntityDef( &skeleton ); + } else { + gameRenderWorld->UpdateEntityDef( skeletonModelDefHandle, &skeleton ); + } + } + + idEntity::Present(); +} + +/* +================ +idAFEntity_Gibbable::Damage +================ +*/ +void idAFEntity_Gibbable::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, trace_t *tr ) +{ + idAFEntity_Base::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); + + if ( !fl.takedamage ) + { + return; + } + + if ( health < -20 && spawnArgs.GetBool( "gib" ) ) { + Gib( dir, damageDefName ); + } +} + +/* +===================== +idAFEntity_Gibbable::SpawnGibs +===================== +*/ +void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefName ) { + int i; + bool gibNonSolid; + idVec3 entityCenter, velocity; + idList list; + + assert( !gameLocal.isClient ); + + const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) { + gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); + } + + // spawn gib articulated figures + idAFEntity_Base::DropAFs( this, "gib", &list ); + + // spawn gib items + idMoveableItem::DropItems( this, "gib", &list ); + + // blow out the gibs in the given direction away from the center of the entity + entityCenter = GetPhysics()->GetAbsBounds().GetCenter(); + gibNonSolid = damageDef->GetBool( "gibNonSolid" ); + for ( i = 0; i < list.Num(); i++ ) { + if ( gibNonSolid ) { + list[i]->GetPhysics()->SetContents( 0 ); + list[i]->GetPhysics()->SetClipMask( 0 ); + list[i]->GetPhysics()->UnlinkClip(); + list[i]->GetPhysics()->PutToRest(); + } else { + list[i]->GetPhysics()->SetContents( CONTENTS_CORPSE ); + list[i]->GetPhysics()->SetClipMask( CONTENTS_SOLID ); + velocity = list[i]->GetPhysics()->GetAbsBounds().GetCenter() - entityCenter; + velocity.NormalizeFast(); + velocity += ( i & 1 ) ? dir : -dir; + list[i]->GetPhysics()->SetLinearVelocity( velocity * 75.0f ); + } + list[i]->GetRenderEntity()->noShadow = true; + list[i]->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; + list[i]->PostEventSec( &EV_Remove, 4.0f ); + } +} + +/* +============ +idAFEntity_Gibbable::Gib +============ +*/ +void idAFEntity_Gibbable::Gib( const idVec3 &dir, const char *damageDefName ) { + // only gib once + if ( gibbed ) { + return; + } + + const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) { + gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); + } + + if ( damageDef->GetBool( "gibNonSolid" ) ) { + GetAFPhysics()->SetContents( 0 ); + GetAFPhysics()->SetClipMask( 0 ); + GetAFPhysics()->UnlinkClip(); + GetAFPhysics()->PutToRest(); + } else { + GetAFPhysics()->SetContents( CONTENTS_CORPSE ); + GetAFPhysics()->SetClipMask( CONTENTS_SOLID ); + } + + UnlinkCombat(); + + if ( g_bloodEffects.GetBool() ) { + if ( gameLocal.time > gameLocal.GetGibTime() ) { + gameLocal.SetGibTime( gameLocal.time + GIB_DELAY ); + SpawnGibs( dir, damageDefName ); + renderEntity.noShadow = true; + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; + StartSound( "snd_gibbed", SND_CHANNEL_ANY, 0, false, NULL ); + gibbed = true; + } + } else { + gibbed = true; + } + + + PostEventSec( &EV_Gibbed, 4.0f ); +} + +/* +============ +idAFEntity_Gibbable::Event_Gib +============ +*/ +void idAFEntity_Gibbable::Event_Gib( const char *damageDefName ) { + Gib( idVec3( 0, 0, 1 ), damageDefName ); +} + +/* +=============================================================================== + + idAFEntity_Generic + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Gibbable, idAFEntity_Generic ) + EVENT( EV_Activate, idAFEntity_Generic::Event_Activate ) +END_CLASS + +/* +================ +idAFEntity_Generic::idAFEntity_Generic +================ +*/ +idAFEntity_Generic::idAFEntity_Generic( void ) { + keepRunningPhysics = false; +} + +/* +================ +idAFEntity_Generic::~idAFEntity_Generic +================ +*/ +idAFEntity_Generic::~idAFEntity_Generic( void ) { +} + +/* +================ +idAFEntity_Generic::Save +================ +*/ +void idAFEntity_Generic::Save( idSaveGame *savefile ) const { + savefile->WriteBool( keepRunningPhysics ); +} + +/* +================ +idAFEntity_Generic::Restore +================ +*/ +void idAFEntity_Generic::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( keepRunningPhysics ); +} + +/* +================ +idAFEntity_Generic::Think +================ +*/ +void idAFEntity_Generic::Think( void ) { + idAFEntity_Base::Think(); + + if ( keepRunningPhysics && !IsHidden() ) + { + BecomeActive( TH_PHYSICS ); + } +} + +/* +================ +idAFEntity_Generic::Spawn +================ +*/ +void idAFEntity_Generic::Spawn( void ) { + if ( !LoadAF() ) { + gameLocal.Error( "Couldn't load af file on entity '%s'", name.c_str() ); + } + + SetCombatModel(); + + SetPhysics( af.GetPhysics() ); + + ParseAttachmentsAF(); + + af.GetPhysics()->PutToRest(); + if ( !spawnArgs.GetBool( "nodrop", "0" ) ) { + af.GetPhysics()->Activate(); + } + + fl.takedamage = true; +} + +/* +================ +idAFEntity_Generic::Event_Activate +================ +*/ +void idAFEntity_Generic::Event_Activate( idEntity *activator ) { + float delay; + idVec3 init_velocity, init_avelocity; + + Show(); + + af.GetPhysics()->EnableImpact(); + af.GetPhysics()->Activate(); + + spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); + spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); + + delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); + if ( delay == 0.0f ) { + af.GetPhysics()->SetLinearVelocity( init_velocity ); + } else { + PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); + } + + delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); + if ( delay == 0.0f ) { + af.GetPhysics()->SetAngularVelocity( init_avelocity ); + } else { + PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); + } + + // greebo: Reactivate the animation flag, just in case + // This hopefully helps rope arrows to not stick out straight in the air + BecomeActive(TH_ANIMATE); +} + + +/* +=============================================================================== + + idAFEntity_WithAttachedHead + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Gibbable, idAFEntity_WithAttachedHead ) + EVENT( EV_Gib, idAFEntity_WithAttachedHead::Event_Gib ) + EVENT( EV_Activate, idAFEntity_WithAttachedHead::Event_Activate ) +END_CLASS + +/* +================ +idAFEntity_WithAttachedHead::idAFEntity_WithAttachedHead +================ +*/ +idAFEntity_WithAttachedHead::idAFEntity_WithAttachedHead() { + head = NULL; +} + +/* +================ +idAFEntity_WithAttachedHead::~idAFEntity_WithAttachedHead +================ +*/ +idAFEntity_WithAttachedHead::~idAFEntity_WithAttachedHead() { + if ( head.GetEntity() ) { + head.GetEntity()->ClearBody(); + head.GetEntity()->PostEventMS( &EV_Remove, 0 ); + } +} + +/* +================ +idAFEntity_WithAttachedHead::Spawn +================ +*/ +void idAFEntity_WithAttachedHead::Spawn( void ) +{ + LoadAF(); + + SetCombatModel(); + + SetPhysics( af.GetPhysics() ); + + SetupHead(); + ParseAttachmentsAF(); + + af.GetPhysics()->PutToRest(); + if ( !spawnArgs.GetBool( "nodrop", "0" ) ) { + af.GetPhysics()->Activate(); + } + + fl.takedamage = true; + + if ( head.GetEntity() ) { + int anim = head.GetEntity()->GetAnimator()->GetAnim( "dead" ); + + if ( anim ) { + head.GetEntity()->GetAnimator()->SetFrame( ANIMCHANNEL_ALL, anim, 0, gameLocal.time, 0 ); + } + } +} + +/* +================ +idAFEntity_WithAttachedHead::Save +================ +*/ +void idAFEntity_WithAttachedHead::Save( idSaveGame *savefile ) const { + head.Save( savefile ); +} + +/* +================ +idAFEntity_WithAttachedHead::Restore +================ +*/ +void idAFEntity_WithAttachedHead::Restore( idRestoreGame *savefile ) { + head.Restore( savefile ); +} + +/* +================ +idAFEntity_WithAttachedHead::SetupHead +================ +*/ +void idAFEntity_WithAttachedHead::SetupHead() +{ + idStr headModelDefName = spawnArgs.GetString( "def_head", "" ); + + idVec3 modelOffset = spawnArgs.GetVector("offsetModel", "0 0 0"); + idVec3 HeadModelOffset = spawnArgs.GetVector("offsetHeadModel", "0 0 0"); + + if ( !headModelDefName.IsEmpty() ) + { + // We look if the head model is defined as a key to have a specific offset. + // If that is not the case, then we use the default value, if it exists, + // otherwise there is no offset at all. + if (spawnArgs.FindKey(headModelDefName) != NULL) + { + HeadModelOffset = spawnArgs.GetVector(headModelDefName, "0 0 0"); + } + + idStr jointName = spawnArgs.GetString( "head_joint" ); + jointHandle_t joint = animator.GetJointHandle( jointName.c_str() ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Joint '%s' not found for 'head_joint' on '%s'", jointName.c_str(), name.c_str() ); + } + + // Setup the default spawnargs for all heads + idDict args; + + const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); + + if (def == NULL) + { + gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); + + // Try to fallback on the default head entityDef + def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); + } + + if (def != NULL) + { + // Make a copy of the default spawnargs + args = def->dict; + } + else + { + gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); + } + + // Spawn the head entity + idEntity* ent = gameLocal.SpawnEntityType(idAFAttachment::Type, &args); + idAFAttachment* headEnt = static_cast(ent); + + // Retrieve the actual model from the head entityDef + idStr headModel = args.GetString("model"); + if (headModel.IsEmpty()) + { + gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); + } + + headEnt->SetName( va( "%s_head", name.c_str() ) ); + headEnt->SetBody( this, headModel, joint ); + headEnt->SetCombatModel(); + head = headEnt; + + idVec3 origin; + idMat3 axis; + animator.GetJointTransform( joint, gameLocal.time, origin, axis ); + origin = renderEntity.origin + ( origin + modelOffset + HeadModelOffset ) * renderEntity.axis; + headEnt->SetOrigin( origin ); + headEnt->SetAxis( renderEntity.axis ); + headEnt->BindToJoint( this, joint, true ); + + // greebo: Setup the frob-peer relationship between head and body + m_FrobPeers.AddUnique(headEnt->name); + } +} + +/* +================ +idAFEntity_WithAttachedHead::Think +================ +*/ +void idAFEntity_WithAttachedHead::Think( void ) { + idAFEntity_Base::Think(); +} + +/* +================ +idAFEntity_WithAttachedHead::LinkCombat +================ +*/ +void idAFEntity_WithAttachedHead::LinkCombat( void ) { + idAFAttachment *headEnt; + + if ( fl.hidden ) { + return; + } + + if ( combatModel ) { + combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); + } + headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->LinkCombat(); + } +} + +/* +================ +idAFEntity_WithAttachedHead::UnlinkCombat +================ +*/ +void idAFEntity_WithAttachedHead::UnlinkCombat( void ) { + idAFAttachment *headEnt; + + if ( combatModel ) { + combatModel->Unlink(); + } + headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->UnlinkCombat(); + } +} + +/* +================ +idAFEntity_WithAttachedHead::Hide +================ +*/ +void idAFEntity_WithAttachedHead::Hide( void ) { + idAFEntity_Base::Hide(); + if ( head.GetEntity() ) { + head.GetEntity()->Hide(); + } + UnlinkCombat(); +} + +/* +================ +idAFEntity_WithAttachedHead::Show +================ +*/ +void idAFEntity_WithAttachedHead::Show( void ) { + idAFEntity_Base::Show(); + if ( head.GetEntity() ) { + head.GetEntity()->Show(); + } + LinkCombat(); +} + +/* +================ +idAFEntity_WithAttachedHead::ProjectOverlay +================ +*/ +void idAFEntity_WithAttachedHead::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { + + idEntity::ProjectOverlay( origin, dir, size, material ); + + if ( head.GetEntity() ) { + head.GetEntity()->ProjectOverlay( origin, dir, size, material ); + } +} + +/* +============ +idAFEntity_WithAttachedHead::Gib +============ +*/ +void idAFEntity_WithAttachedHead::Gib( const idVec3 &dir, const char *damageDefName ) { + // only gib once + if ( gibbed ) { + return; + } + idAFEntity_Gibbable::Gib( dir, damageDefName ); + if ( head.GetEntity() ) { + head.GetEntity()->Hide(); + } +} + +/* +============ +idAFEntity_WithAttachedHead::Event_Gib +============ +*/ +void idAFEntity_WithAttachedHead::Event_Gib( const char *damageDefName ) { + Gib( idVec3( 0, 0, 1 ), damageDefName ); +} + +/* +================ +idAFEntity_WithAttachedHead::Event_Activate +================ +*/ +void idAFEntity_WithAttachedHead::Event_Activate( idEntity *activator ) { + float delay; + idVec3 init_velocity, init_avelocity; + + Show(); + + af.GetPhysics()->EnableImpact(); + af.GetPhysics()->Activate(); + + spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); + spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); + + delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); + if ( delay == 0.0f ) { + af.GetPhysics()->SetLinearVelocity( init_velocity ); + } else { + PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); + } + + delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); + if ( delay == 0.0f ) { + af.GetPhysics()->SetAngularVelocity( init_avelocity ); + } else { + PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); + } +} + + +/* +=============================================================================== + + idAFEntity_Vehicle + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Base, idAFEntity_Vehicle ) +END_CLASS + +/* +================ +idAFEntity_Vehicle::idAFEntity_Vehicle +================ +*/ +idAFEntity_Vehicle::idAFEntity_Vehicle( void ) { + player = NULL; + eyesJoint = INVALID_JOINT; + steeringWheelJoint = INVALID_JOINT; + wheelRadius = 0.0f; + steerAngle = 0.0f; + steerSpeed = 0.0f; + dustSmoke = NULL; +} + +/* +================ +idAFEntity_Vehicle::Spawn +================ +*/ +void idAFEntity_Vehicle::Spawn( void ) { + const char *eyesJointName = spawnArgs.GetString( "eyesJoint", "eyes" ); + const char *steeringWheelJointName = spawnArgs.GetString( "steeringWheelJoint", "steeringWheel" ); + + LoadAF(); + + SetCombatModel(); + + SetPhysics( af.GetPhysics() ); + + ParseAttachmentsAF(); + + fl.takedamage = true; + + if ( !eyesJointName[0] ) { + gameLocal.Error( "idAFEntity_Vehicle '%s' no eyes joint specified", name.c_str() ); + } + eyesJoint = animator.GetJointHandle( eyesJointName ); + if ( !steeringWheelJointName[0] ) { + gameLocal.Error( "idAFEntity_Vehicle '%s' no steering wheel joint specified", name.c_str() ); + } + steeringWheelJoint = animator.GetJointHandle( steeringWheelJointName ); + + spawnArgs.GetFloat( "wheelRadius", "20", wheelRadius ); + spawnArgs.GetFloat( "steerSpeed", "5", steerSpeed ); + + player = NULL; + steerAngle = 0.0f; + + const char *smokeName = spawnArgs.GetString( "smoke_vehicle_dust", "muzzlesmoke" ); + if ( *smokeName != '\0' ) { + dustSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + } +} + +/* +================ +idAFEntity_Vehicle::Use +================ +*/ +void idAFEntity_Vehicle::Use( idPlayer *other ) { + idVec3 origin; + idMat3 axis; + + if ( player ) { + if ( player == other ) { + other->Unbind(); + player = NULL; + + af.GetPhysics()->SetComeToRest( true ); + } + } + else { + player = other; + animator.GetJointTransform( eyesJoint, gameLocal.time, origin, axis ); + origin = renderEntity.origin + origin * renderEntity.axis; + player->GetPhysics()->SetOrigin( origin ); + player->BindToBody( this, 0, true ); + + af.GetPhysics()->SetComeToRest( false ); + af.GetPhysics()->Activate(); + } +} + +/* +================ +idAFEntity_Vehicle::GetSteerAngle +================ +*/ +float idAFEntity_Vehicle::GetSteerAngle( void ) { + float idealSteerAngle, angleDelta; + + idealSteerAngle = player->usercmd.rightmove * ( 30.0f / 128.0f ); + angleDelta = idealSteerAngle - steerAngle; + + if ( angleDelta > steerSpeed ) { + steerAngle += steerSpeed; + } else if ( angleDelta < -steerSpeed ) { + steerAngle -= steerSpeed; + } else { + steerAngle = idealSteerAngle; + } + + return steerAngle; +} + + +/* +=============================================================================== + + idAFEntity_VehicleSimple + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleSimple ) +END_CLASS + +/* +================ +idAFEntity_VehicleSimple::idAFEntity_VehicleSimple +================ +*/ +idAFEntity_VehicleSimple::idAFEntity_VehicleSimple( void ) { + int i; + for ( i = 0; i < 4; i++ ) { + suspension[i] = NULL; + } +} + +/* +================ +idAFEntity_VehicleSimple::~idAFEntity_VehicleSimple +================ +*/ +idAFEntity_VehicleSimple::~idAFEntity_VehicleSimple( void ) { + delete wheelModel; + wheelModel = NULL; +} + +/* +================ +idAFEntity_VehicleSimple::Spawn +================ +*/ +void idAFEntity_VehicleSimple::Spawn( void ) { + static const char *wheelJointKeys[] = { + "wheelJointFrontLeft", + "wheelJointFrontRight", + "wheelJointRearLeft", + "wheelJointRearRight" + }; + static idVec3 wheelPoly[4] = { idVec3( 2, 2, 0 ), idVec3( 2, -2, 0 ), idVec3( -2, -2, 0 ), idVec3( -2, 2, 0 ) }; + + int i; + idVec3 origin; + idMat3 axis; + idTraceModel trm; + + trm.SetupPolygon( wheelPoly, 4 ); + trm.Translate( idVec3( 0, 0, -wheelRadius ) ); + wheelModel = new idClipModel( trm ); + + for ( i = 0; i < 4; i++ ) { + const char *wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); + if ( !wheelJointName[0] ) { + gameLocal.Error( "idAFEntity_VehicleSimple '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); + } + wheelJoints[i] = animator.GetJointHandle( wheelJointName ); + if ( wheelJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idAFEntity_VehicleSimple '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); + } + + GetAnimator()->GetJointTransform( wheelJoints[i], 0, origin, axis ); + origin = renderEntity.origin + origin * renderEntity.axis; + + suspension[i] = new idAFConstraint_Suspension(); + suspension[i]->Setup( va( "suspension%d", i ), af.GetPhysics()->GetBody( 0 ), origin, af.GetPhysics()->GetAxis( 0 ), wheelModel ); + suspension[i]->SetSuspension( g_vehicleSuspensionUp.GetFloat(), + g_vehicleSuspensionDown.GetFloat(), + g_vehicleSuspensionKCompress.GetFloat(), + g_vehicleSuspensionDamping.GetFloat(), + g_vehicleTireFriction.GetFloat() ); + + af.GetPhysics()->AddConstraint( suspension[i] ); + } + + memset( wheelAngles, 0, sizeof( wheelAngles ) ); + BecomeActive( TH_THINK ); +} + +/* +================ +idAFEntity_VehicleSimple::Think +================ +*/ +void idAFEntity_VehicleSimple::Think( void ) { + int i; + float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; + idVec3 origin; + idMat3 axis; + idRotation wheelRotation, steerRotation; + + if ( thinkFlags & TH_THINK ) { + + if ( player ) { + // capture the input from a player + velocity = g_vehicleVelocity.GetFloat(); + if ( player->usercmd.forwardmove < 0 ) { + velocity = -velocity; + } + force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); + steerAngle = GetSteerAngle(); + } + + // update the wheel motor force and steering + for ( i = 0; i < 2; i++ ) { + + // front wheel drive + if ( velocity != 0.0f ) { + suspension[i]->EnableMotor( true ); + } else { + suspension[i]->EnableMotor( false ); + } + suspension[i]->SetMotorVelocity( velocity ); + suspension[i]->SetMotorForce( force ); + + // update the wheel steering + suspension[i]->SetSteerAngle( steerAngle ); + } + + // adjust wheel velocity for better steering because there are no differentials between the wheels + if ( steerAngle < 0.0f ) { + suspension[0]->SetMotorVelocity( velocity * 0.5f ); + } else if ( steerAngle > 0.0f ) { + suspension[1]->SetMotorVelocity( velocity * 0.5f ); + } + + // update suspension with latest cvar settings + for ( i = 0; i < 4; i++ ) { + suspension[i]->SetSuspension( g_vehicleSuspensionUp.GetFloat(), + g_vehicleSuspensionDown.GetFloat(), + g_vehicleSuspensionKCompress.GetFloat(), + g_vehicleSuspensionDamping.GetFloat(), + g_vehicleTireFriction.GetFloat() ); + } + + // run the physics + RunPhysics(); + + // move and rotate the wheels visually + for ( i = 0; i < 4; i++ ) { + idAFBody *body = af.GetPhysics()->GetBody( 0 ); + + origin = suspension[i]->GetWheelOrigin(); + velocity = body->GetPointVelocity( origin ) * body->GetWorldAxis()[0]; + wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; + + // additional rotation about the wheel axis + wheelRotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); + wheelRotation.SetVec( 0, -1, 0 ); + + if ( i < 2 ) { + // rotate the wheel for steering + steerRotation.SetAngle( steerAngle ); + steerRotation.SetVec( 0, 0, 1 ); + // set wheel rotation + animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() * steerRotation.ToMat3() ); + } else { + // set wheel rotation + animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() ); + } + + // set wheel position for suspension + origin = ( origin - renderEntity.origin ) * renderEntity.axis.Transpose(); + GetAnimator()->SetJointPos( wheelJoints[i], JOINTMOD_WORLD_OVERRIDE, origin ); + } +/* + // spawn dust particle effects + if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { + int numContacts; + idAFConstraint_Contact *contacts[2]; + for ( i = 0; i < 4; i++ ) { + numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); + for ( int j = 0; j < numContacts; j++ ) { + gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); + } + } + } +*/ + } + + UpdateAnimation(); + if ( thinkFlags & TH_UPDATEVISUALS ) { + Present(); + LinkCombat(); + } +} + + +/* +=============================================================================== + + idAFEntity_VehicleFourWheels + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleFourWheels ) +END_CLASS + + +/* +================ +idAFEntity_VehicleFourWheels::idAFEntity_VehicleFourWheels +================ +*/ +idAFEntity_VehicleFourWheels::idAFEntity_VehicleFourWheels( void ) { + int i; + + for ( i = 0; i < 4; i++ ) { + wheels[i] = NULL; + wheelJoints[i] = INVALID_JOINT; + wheelAngles[i] = 0.0f; + } + steering[0] = NULL; + steering[1] = NULL; +} + +/* +================ +idAFEntity_VehicleFourWheels::Spawn +================ +*/ +void idAFEntity_VehicleFourWheels::Spawn( void ) { + int i; + static const char *wheelBodyKeys[] = { + "wheelBodyFrontLeft", + "wheelBodyFrontRight", + "wheelBodyRearLeft", + "wheelBodyRearRight" + }; + static const char *wheelJointKeys[] = { + "wheelJointFrontLeft", + "wheelJointFrontRight", + "wheelJointRearLeft", + "wheelJointRearRight" + }; + static const char *steeringHingeKeys[] = { + "steeringHingeFrontLeft", + "steeringHingeFrontRight", + }; + + const char *wheelBodyName, *wheelJointName, *steeringHingeName; + + for ( i = 0; i < 4; i++ ) { + wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" ); + if ( !wheelBodyName[0] ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] ); + } + wheels[i] = af.GetPhysics()->GetBody( wheelBodyName ); + if ( !wheels[i] ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName ); + } + wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); + if ( !wheelJointName[0] ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); + } + wheelJoints[i] = animator.GetJointHandle( wheelJointName ); + if ( wheelJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); + } + } + + for ( i = 0; i < 2; i++ ) { + steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" ); + if ( !steeringHingeName[0] ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] ); + } + steering[i] = static_cast(af.GetPhysics()->GetConstraint( steeringHingeName )); + if ( !steering[i] ) { + gameLocal.Error( "idAFEntity_VehicleFourWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName ); + } + } + + memset( wheelAngles, 0, sizeof( wheelAngles ) ); + BecomeActive( TH_THINK ); +} + +/* +================ +idAFEntity_VehicleFourWheels::Think +================ +*/ +void idAFEntity_VehicleFourWheels::Think( void ) { + int i; + float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; + idVec3 origin; + idMat3 axis; + idRotation rotation; + + if ( thinkFlags & TH_THINK ) { + + if ( player ) { + // capture the input from a player + velocity = g_vehicleVelocity.GetFloat(); + if ( player->usercmd.forwardmove < 0 ) { + velocity = -velocity; + } + force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); + steerAngle = GetSteerAngle(); + } + + // update the wheel motor force + for ( i = 0; i < 2; i++ ) { + wheels[2+i]->SetContactMotorVelocity( velocity ); + wheels[2+i]->SetContactMotorForce( force ); + } + + // adjust wheel velocity for better steering because there are no differentials between the wheels + if ( steerAngle < 0.0f ) { + wheels[2]->SetContactMotorVelocity( velocity * 0.5f ); + } + else if ( steerAngle > 0.0f ) { + wheels[3]->SetContactMotorVelocity( velocity * 0.5f ); + } + + // update the wheel steering + steering[0]->SetSteerAngle( steerAngle ); + steering[1]->SetSteerAngle( steerAngle ); + for ( i = 0; i < 2; i++ ) { + steering[i]->SetSteerSpeed( 3.0f ); + } + + // update the steering wheel + animator.GetJointTransform( steeringWheelJoint, gameLocal.time, origin, axis ); + rotation.SetVec( axis[2] ); + rotation.SetAngle( -steerAngle ); + animator.SetJointAxis( steeringWheelJoint, JOINTMOD_WORLD, rotation.ToMat3() ); + + // run the physics + RunPhysics(); + + // rotate the wheels visually + for ( i = 0; i < 4; i++ ) { + if ( force == 0.0f ) { + velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0]; + } + wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; + // give the wheel joint an additional rotation about the wheel axis + rotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); + axis = af.GetPhysics()->GetAxis( 0 ); + rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] ); + animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, rotation.ToMat3() ); + } + + // spawn dust particle effects + if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { + int numContacts; + idAFConstraint_Contact *contacts[2]; + for ( i = 0; i < 4; i++ ) { + numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); + for ( int j = 0; j < numContacts; j++ ) { + gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); + } + } + } + } + + UpdateAnimation(); + if ( thinkFlags & TH_UPDATEVISUALS ) { + Present(); + LinkCombat(); + } +} + + +/* +=============================================================================== + + idAFEntity_VehicleSixWheels + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleSixWheels ) +END_CLASS + + /* +================ +idAFEntity_VehicleSixWheels::idAFEntity_VehicleSixWheels +================ +*/ +idAFEntity_VehicleSixWheels::idAFEntity_VehicleSixWheels( void ) { + int i; + + for ( i = 0; i < 6; i++ ) { + wheels[i] = NULL; + wheelJoints[i] = INVALID_JOINT; + wheelAngles[i] = 0.0f; + } + steering[0] = NULL; + steering[1] = NULL; + steering[2] = NULL; + steering[3] = NULL; +} + +/* +================ +idAFEntity_VehicleSixWheels::Spawn +================ +*/ +void idAFEntity_VehicleSixWheels::Spawn( void ) { + int i; + static const char *wheelBodyKeys[] = { + "wheelBodyFrontLeft", + "wheelBodyFrontRight", + "wheelBodyMiddleLeft", + "wheelBodyMiddleRight", + "wheelBodyRearLeft", + "wheelBodyRearRight" + }; + static const char *wheelJointKeys[] = { + "wheelJointFrontLeft", + "wheelJointFrontRight", + "wheelJointMiddleLeft", + "wheelJointMiddleRight", + "wheelJointRearLeft", + "wheelJointRearRight" + }; + static const char *steeringHingeKeys[] = { + "steeringHingeFrontLeft", + "steeringHingeFrontRight", + "steeringHingeRearLeft", + "steeringHingeRearRight" + }; + + const char *wheelBodyName, *wheelJointName, *steeringHingeName; + + for ( i = 0; i < 6; i++ ) { + wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" ); + if ( !wheelBodyName[0] ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] ); + } + wheels[i] = af.GetPhysics()->GetBody( wheelBodyName ); + if ( !wheels[i] ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName ); + } + wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); + if ( !wheelJointName[0] ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); + } + wheelJoints[i] = animator.GetJointHandle( wheelJointName ); + if ( wheelJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); + } + } + + for ( i = 0; i < 4; i++ ) { + steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" ); + if ( !steeringHingeName[0] ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] ); + } + steering[i] = static_cast(af.GetPhysics()->GetConstraint( steeringHingeName )); + if ( !steering[i] ) { + gameLocal.Error( "idAFEntity_VehicleSixWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName ); + } + } + + memset( wheelAngles, 0, sizeof( wheelAngles ) ); + BecomeActive( TH_THINK ); +} + +/* +================ +idAFEntity_VehicleSixWheels::Think +================ +*/ +void idAFEntity_VehicleSixWheels::Think( void ) { + int i; + float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; + idVec3 origin; + idMat3 axis; + idRotation rotation; + + if ( thinkFlags & TH_THINK ) { + + if ( player ) { + // capture the input from a player + velocity = g_vehicleVelocity.GetFloat(); + if ( player->usercmd.forwardmove < 0 ) { + velocity = -velocity; + } + force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); + steerAngle = GetSteerAngle(); + } + + // update the wheel motor force + for ( i = 0; i < 6; i++ ) { + wheels[i]->SetContactMotorVelocity( velocity ); + wheels[i]->SetContactMotorForce( force ); + } + + // adjust wheel velocity for better steering because there are no differentials between the wheels + if ( steerAngle < 0.0f ) { + for ( i = 0; i < 3; i++ ) { + wheels[(i<<1)]->SetContactMotorVelocity( velocity * 0.5f ); + } + } + else if ( steerAngle > 0.0f ) { + for ( i = 0; i < 3; i++ ) { + wheels[1+(i<<1)]->SetContactMotorVelocity( velocity * 0.5f ); + } + } + + // update the wheel steering + steering[0]->SetSteerAngle( steerAngle ); + steering[1]->SetSteerAngle( steerAngle ); + steering[2]->SetSteerAngle( -steerAngle ); + steering[3]->SetSteerAngle( -steerAngle ); + for ( i = 0; i < 4; i++ ) { + steering[i]->SetSteerSpeed( 3.0f ); + } + + // update the steering wheel + animator.GetJointTransform( steeringWheelJoint, gameLocal.time, origin, axis ); + rotation.SetVec( axis[2] ); + rotation.SetAngle( -steerAngle ); + animator.SetJointAxis( steeringWheelJoint, JOINTMOD_WORLD, rotation.ToMat3() ); + + // run the physics + RunPhysics(); + + // rotate the wheels visually + for ( i = 0; i < 6; i++ ) { + if ( force == 0.0f ) { + velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0]; + } + wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; + // give the wheel joint an additional rotation about the wheel axis + rotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); + axis = af.GetPhysics()->GetAxis( 0 ); + rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] ); + animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, rotation.ToMat3() ); + } + + // spawn dust particle effects + if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { + int numContacts; + idAFConstraint_Contact *contacts[2]; + for ( i = 0; i < 6; i++ ) { + numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); + for ( int j = 0; j < numContacts; j++ ) { + gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); + } + } + } + } + + UpdateAnimation(); + if ( thinkFlags & TH_UPDATEVISUALS ) { + Present(); + LinkCombat(); + } +} + + +/* +=============================================================================== + + idAFEntity_SteamPipe + +=============================================================================== +*/ + +CLASS_DECLARATION( idAFEntity_Base, idAFEntity_SteamPipe ) +END_CLASS + + +/* +================ +idAFEntity_SteamPipe::idAFEntity_SteamPipe +================ +*/ +idAFEntity_SteamPipe::idAFEntity_SteamPipe( void ) { + steamBody = 0; + steamForce = 0.0f; + steamUpForce = 0.0f; + steamModelDefHandle = -1; + memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) ); +} + +/* +================ +idAFEntity_SteamPipe::~idAFEntity_SteamPipe +================ +*/ +idAFEntity_SteamPipe::~idAFEntity_SteamPipe( void ) { + if ( steamModelDefHandle >= 0 ){ + gameRenderWorld->FreeEntityDef( steamModelDefHandle ); + } +} + +/* +================ +idAFEntity_SteamPipe::Save +================ +*/ +void idAFEntity_SteamPipe::Save( idSaveGame *savefile ) const { +} + +/* +================ +idAFEntity_SteamPipe::Restore +================ +*/ +void idAFEntity_SteamPipe::Restore( idRestoreGame *savefile ) { + Spawn(); +} + +/* +================ +idAFEntity_SteamPipe::Spawn +================ +*/ +void idAFEntity_SteamPipe::Spawn( void ) { + idVec3 steamDir; + const char *steamBodyName; + + LoadAF(); + + SetCombatModel(); + + SetPhysics( af.GetPhysics() ); + + ParseAttachmentsAF(); + + fl.takedamage = true; + + steamBodyName = spawnArgs.GetString( "steamBody", "" ); + steamForce = spawnArgs.GetFloat( "steamForce", "2000" ); + steamUpForce = spawnArgs.GetFloat( "steamUpForce", "10" ); + steamDir = af.GetPhysics()->GetAxis( steamBody )[2]; + steamBody = af.GetPhysics()->GetBodyId( steamBodyName ); + force.SetPosition( af.GetPhysics(), steamBody, af.GetPhysics()->GetOrigin( steamBody ) ); + force.SetForce( steamDir * -steamForce ); + + InitSteamRenderEntity(); + + BecomeActive( TH_THINK ); +} + +/* +================ +idAFEntity_SteamPipe::InitSteamRenderEntity +================ +*/ +void idAFEntity_SteamPipe::InitSteamRenderEntity( void ) { + const char *temp; + const idDeclModelDef *modelDef; + + memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) ); + steamRenderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; + steamRenderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f; + steamRenderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; + modelDef = NULL; + temp = spawnArgs.GetString ( "model_steam" ); + if ( *temp != '\0' ) { + if ( !strstr( temp, "." ) ) { + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, temp, false ) ); + if ( modelDef ) { + steamRenderEntity.hModel = modelDef->ModelHandle(); + } + } + + if ( !steamRenderEntity.hModel ) { + steamRenderEntity.hModel = renderModelManager->FindModel( temp ); + } + + if ( steamRenderEntity.hModel ) { + steamRenderEntity.bounds = steamRenderEntity.hModel->Bounds( &steamRenderEntity ); + } else { + steamRenderEntity.bounds.Zero(); + } + steamRenderEntity.origin = af.GetPhysics()->GetOrigin( steamBody ); + steamRenderEntity.axis = af.GetPhysics()->GetAxis( steamBody ); + steamModelDefHandle = gameRenderWorld->AddEntityDef( &steamRenderEntity ); + } +} + +/* +================ +idAFEntity_SteamPipe::Think +================ +*/ +void idAFEntity_SteamPipe::Think( void ) { + idVec3 steamDir; + + if ( thinkFlags & TH_THINK ) { + steamDir.x = gameLocal.random.CRandomFloat() * steamForce; + steamDir.y = gameLocal.random.CRandomFloat() * steamForce; + steamDir.z = steamUpForce; + force.SetForce( steamDir ); + force.Evaluate( gameLocal.time ); + //gameRenderWorld->DebugArrow( colorWhite, af.GetPhysics()->GetOrigin( steamBody ), af.GetPhysics()->GetOrigin( steamBody ) - 10.0f * steamDir, 4 ); + } + + if ( steamModelDefHandle >= 0 ){ + steamRenderEntity.origin = af.GetPhysics()->GetOrigin( steamBody ); + steamRenderEntity.axis = af.GetPhysics()->GetAxis( steamBody ); + gameRenderWorld->UpdateEntityDef( steamModelDefHandle, &steamRenderEntity ); + } + + idAFEntity_Base::Think(); +} + + +/* +=============================================================================== + + editor support routines + +=============================================================================== +*/ + + +/* +================ +idGameEdit::AF_SpawnEntity +================ +*/ +bool idGameEdit::AF_SpawnEntity( const char *fileName ) { + idDict args; + idPlayer *player; + idAFEntity_Generic *ent; + const idDeclAF *af; + idVec3 org; + float yaw; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk( false ) ) { + return false; + } + + af = static_cast( declManager->FindType( DECL_AF, fileName ) ); + if ( !af ) { + return false; + } + + yaw = player->viewAngles.yaw; + args.Set( "angle", va( "%f", yaw + 180 ) ); + org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); + args.Set( "origin", org.ToString() ); + args.Set( "spawnclass", "idAFEntity_Generic" ); + if ( af->model[0] ) { + args.Set( "model", af->model.c_str() ); + } else { + args.Set( "model", fileName ); + } + if ( af->skin[0] ) { + args.Set( "skin", af->skin.c_str() ); + } + args.Set( "articulatedFigure", fileName ); + args.Set( "nodrop", "1" ); + ent = static_cast(gameLocal.SpawnEntityType( idAFEntity_Generic::Type, &args)); + + // always update this entity + ent->BecomeActive( TH_THINK ); + ent->KeepRunningPhysics(); + ent->fl.forcePhysicsUpdate = true; + + player->dragEntity.SetSelected( ent ); + + return true; +} + +/* +================ +idGameEdit::AF_UpdateEntities +================ +*/ +void idGameEdit::AF_UpdateEntities( const char *fileName ) { + idEntity *ent; + idAFEntity_Base *af; + idStr name; + + name = fileName; + name.StripFileExtension(); + + // reload any idAFEntity_Generic which uses the given articulated figure file + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( idAFEntity_Base::Type ) ) { + af = static_cast(ent); + if ( name.Icmp( af->GetAFName() ) == 0 ) { + af->LoadAF(); + af->GetAFPhysics()->PutToRest(); + } + } + } +} + +/* +================ +idGameEdit::AF_UndoChanges +================ +*/ +void idGameEdit::AF_UndoChanges( void ) { + int i, c; + idEntity *ent; + idAFEntity_Base *af; + idDeclAF *decl; + + c = declManager->GetNumDecls( DECL_AF ); + for ( i = 0; i < c; i++ ) { + decl = static_cast( const_cast( declManager->DeclByIndex( DECL_AF, i, false ) ) ); + if ( !decl->modified ) { + continue; + } + + decl->Invalidate(); + declManager->FindType( DECL_AF, decl->GetName() ); + + // reload all AF entities using the file + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( idAFEntity_Base::Type ) ) { + af = static_cast(ent); + if ( idStr::Icmp( decl->GetName(), af->GetAFName() ) == 0 ) { + af->LoadAF(); + } + } + } + } +} + +/* +================ +GetJointTransform +================ +*/ +typedef struct { + renderEntity_t *ent; + const idMD5Joint *joints; +} jointTransformData_t; + +static bool GetJointTransform( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ) { + int i; + jointTransformData_t *data = reinterpret_cast(model); + + for ( i = 0; i < data->ent->numJoints; i++ ) { + if ( data->joints[i].name.Icmp( jointName ) == 0 ) { + break; + } + } + if ( i >= data->ent->numJoints ) { + return false; + } + origin = frame[i].ToVec3(); + axis = frame[i].ToMat3(); + return true; +} + +/* +================ +GetArgString +================ +*/ +static const char *GetArgString( const idDict &args, const idDict *defArgs, const char *key ) { + const char *s; + + s = args.GetString( key ); + if ( !s[0] && defArgs ) { + s = defArgs->GetString( key ); + } + return s; +} + +/* +================ +idGameEdit::AF_CreateMesh +================ +*/ +idRenderModel *idGameEdit::AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet ) { + int i(0), jointNum(0); + const idDeclAF *af(NULL); + const idDeclAF_Body *fb(NULL); + renderEntity_t ent; + idVec3 origin, *bodyOrigin(NULL), *newBodyOrigin(NULL), *modifiedOrigin(NULL); + idMat3 axis, *bodyAxis(NULL), *newBodyAxis(NULL), *modifiedAxis(NULL); + declAFJointMod_t *jointMod(NULL); + idAngles angles; + const idDict *defArgs(NULL); + const idKeyValue *arg(NULL); + idStr name; + jointTransformData_t data; + const char *classname(NULL), *afName(NULL), *modelName(NULL); + idRenderModel *md5(NULL); + const idDeclModelDef *modelDef(NULL); + const idMD5Anim *MD5anim(NULL); + const idMD5Joint *MD5joint(NULL); + const idMD5Joint *MD5joints(NULL); + int numMD5joints; + idJointMat *originalJoints(NULL); + int parentNum; + + poseIsSet = false; + meshOrigin.Zero(); + meshAxis.Identity(); + + classname = args.GetString( "classname" ); + defArgs = gameLocal.FindEntityDefDict( classname ); + + // get the articulated figure + afName = GetArgString( args, defArgs, "articulatedFigure" ); + af = static_cast( declManager->FindType( DECL_AF, afName ) ); + if ( !af ) { + return NULL; + } + + // get the md5 model + modelName = GetArgString( args, defArgs, "model" ); + modelDef = static_cast< const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, modelName, false ) ); + if ( !modelDef ) { + return NULL; + } + + // make sure model hasn't been purged + if ( modelDef->ModelHandle() && !modelDef->ModelHandle()->IsLoaded() ) { + modelDef->ModelHandle()->LoadModel(); + } + + // get the md5 + md5 = modelDef->ModelHandle(); + if ( !md5 || md5->IsDefaultModel() ) { + return NULL; + } + + // get the articulated figure pose anim + int animNum = modelDef->GetAnim( "af_pose" ); + if ( !animNum ) { + return NULL; + } + const idAnim *anim = modelDef->GetAnim( animNum ); + if ( !anim ) { + return NULL; + } + MD5anim = anim->MD5Anim( 0 ); + MD5joints = md5->GetJoints(); + numMD5joints = md5->NumJoints(); + + // setup a render entity + memset( &ent, 0, sizeof( ent ) ); + ent.customSkin = modelDef->GetSkin(); + ent.bounds.Clear(); + ent.numJoints = numMD5joints; + ent.joints = ( idJointMat * )_alloca16( ent.numJoints * sizeof( *ent.joints ) ); + + // create animation from of the af_pose + ANIM_CreateAnimFrame( md5, MD5anim, ent.numJoints, ent.joints, 1, modelDef->GetVisualOffset(), false ); + + // buffers to store the initial origin and axis for each body + bodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) ); + bodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) ); + newBodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) ); + newBodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) ); + + // finish the AF positions + data.ent = &ent; + data.joints = MD5joints; + af->Finish( GetJointTransform, ent.joints, &data ); + + // get the initial origin and axis for each AF body + for ( i = 0; i < af->bodies.Num(); i++ ) { + fb = af->bodies[i]; + + if ( fb->modelType == TRM_BONE ) { + // axis of bone trace model + axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3(); + axis[2].Normalize(); + axis[2].NormalVectors( axis[0], axis[1] ); + axis[1] = -axis[1]; + } else { + axis = fb->angles.ToMat3(); + } + + newBodyOrigin[i] = bodyOrigin[i] = fb->origin.ToVec3(); + newBodyAxis[i] = bodyAxis[i] = axis; + } + + // get any new body transforms stored in the key/value pairs + for ( arg = args.MatchPrefix( "body ", NULL ); arg; arg = args.MatchPrefix( "body ", arg ) ) { + name = arg->GetKey(); + name.Strip( "body " ); + for ( i = 0; i < af->bodies.Num(); i++ ) { + fb = af->bodies[i]; + if ( fb->name.Icmp( name ) == 0 ) { + break; + } + } + if ( i >= af->bodies.Num() ) { + continue; + } + sscanf( arg->GetValue(), "%f %f %f %f %f %f", &origin.x, &origin.y, &origin.z, &angles.pitch, &angles.yaw, &angles.roll ); + + if ( fb->jointName.Icmp( "origin" ) == 0 ) { + meshAxis = bodyAxis[i].Transpose() * angles.ToMat3(); + meshOrigin = origin - bodyOrigin[i] * meshAxis; + poseIsSet = true; + } else { + newBodyOrigin[i] = origin; + newBodyAxis[i] = angles.ToMat3(); + } + } + + // save the original joints + originalJoints = ( idJointMat * )_alloca16( numMD5joints * sizeof( originalJoints[0] ) ); + memcpy( originalJoints, ent.joints, numMD5joints * sizeof( originalJoints[0] ) ); + + // buffer to store the joint mods + jointMod = (declAFJointMod_t *) _alloca16( numMD5joints * sizeof( declAFJointMod_t ) ); + memset( jointMod, -1, numMD5joints * sizeof( declAFJointMod_t ) ); + modifiedOrigin = (idVec3 *) _alloca16( numMD5joints * sizeof( idVec3 ) ); + memset( modifiedOrigin, 0, numMD5joints * sizeof( idVec3 ) ); + modifiedAxis = (idMat3 *) _alloca16( numMD5joints * sizeof( idMat3 ) ); + memset( modifiedAxis, 0, numMD5joints * sizeof( idMat3 ) ); + + // get all the joint modifications + for ( i = 0; i < af->bodies.Num(); i++ ) { + fb = af->bodies[i]; + + if ( fb->jointName.Icmp( "origin" ) == 0 ) { + continue; + } + + for ( jointNum = 0; jointNum < numMD5joints; jointNum++ ) { + if ( MD5joints[jointNum].name.Icmp( fb->jointName ) == 0 ) { + break; + } + } + + if ( jointNum >= 0 && jointNum < ent.numJoints ) { + jointMod[ jointNum ] = fb->jointMod; + modifiedAxis[ jointNum ] = ( bodyAxis[i] * originalJoints[jointNum].ToMat3().Transpose() ).Transpose() * ( newBodyAxis[i] * meshAxis.Transpose() ); + // FIXME: calculate correct modifiedOrigin + modifiedOrigin[ jointNum ] = originalJoints[ jointNum ].ToVec3(); + } + } + + // apply joint modifications to the skeleton + MD5joint = MD5joints + 1; + for( i = 1; i < numMD5joints; i++, MD5joint++ ) { + + parentNum = MD5joint->parent - MD5joints; + idMat3 parentAxis = originalJoints[ parentNum ].ToMat3(); + idMat3 localm = originalJoints[i].ToMat3() * parentAxis.Transpose(); + idVec3 localt = ( originalJoints[i].ToVec3() - originalJoints[ parentNum ].ToVec3() ) * parentAxis.Transpose(); + + switch( jointMod[i] ) { + case DECLAF_JOINTMOD_ORIGIN: { + ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() ); + ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] ); + break; + } + case DECLAF_JOINTMOD_AXIS: { + ent.joints[ i ].SetRotation( modifiedAxis[ i ] ); + ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() ); + break; + } + case DECLAF_JOINTMOD_BOTH: { + ent.joints[ i ].SetRotation( modifiedAxis[ i ] ); + ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] ); + break; + } + default: { + ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() ); + ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() ); + break; + } + } + } + + // instantiate a mesh using the joint information from the render entity + return md5->InstantiateDynamicModel( &ent, NULL, NULL ); +} diff --git a/game/AFEntity.h b/game/AFEntity.h new file mode 100644 index 000000000..c924febc5 --- /dev/null +++ b/game/AFEntity.h @@ -0,0 +1,651 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_AFENTITY_H__ +#define __GAME_AFENTITY_H__ + + +/* +=============================================================================== + +idMultiModelAF + +Entity using multiple separate visual models animated with a single +articulated figure. Only used for debugging! + +=============================================================================== +*/ +const int GIB_DELAY = 200; // only gib this often to keep performace hits when blowing up several mobs + +class idMultiModelAF : public idEntity { +public: + CLASS_PROTOTYPE( idMultiModelAF ); + + void Spawn( void ); + virtual ~idMultiModelAF( void ); + + virtual void Think( void ); + virtual void Present( void ); + +protected: + /** + * Parsing attachments happens at a different time in the spawn routine for + * idAFEntities. To accomplish this, the function is overloaded to do + * nothing and a new function is called at the proper time. + **/ + virtual void ParseAttachments( void ); + + /** + * Same as idEntity::ParseAttachments, but called at a different point in spawn routine + **/ + virtual void ParseAttachmentsAF( void ); + +protected: + idPhysics_AF physicsObj; + + void SetModelForId( int id, const idStr &modelName ); + +private: + idList modelHandles; + idList modelDefHandles; +}; + + +/* +=============================================================================== + +idChain + +Chain hanging down from the ceiling. Only used for debugging! + +=============================================================================== +*/ + +class idChain : public idMultiModelAF { +public: + CLASS_PROTOTYPE( idChain ); + + void Spawn( void ); + +protected: + void BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld = true ); +}; + + +/* +=============================================================================== + +idAFAttachment + +=============================================================================== +*/ + +class idAFAttachment : public idAnimatedEntity { +public: + CLASS_PROTOTYPE( idAFAttachment ); + + idAFAttachment( void ); + virtual ~idAFAttachment( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void SetBody( idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint ); + void ClearBody( void ); + idEntity * GetBody( void ) const; + // ishtvan: Added this + jointHandle_t GetAttachJoint( void ) const; + + bool IsMantleable( void ); + + virtual void Think( void ); + + virtual void Hide( void ); + virtual void Show( void ); + + void PlayIdleAnim( int blendTime ); + + virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); + virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); + + virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, + const int location, trace_t *tr = NULL ); + virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); + + void SetCombatModel( void ); + idClipModel * GetCombatModel( void ) const; + virtual void LinkCombat( void ); + virtual void UnlinkCombat( void ); + + /** + * greebo: Virtual override of idEntity::GetResponseEntity(). This is used + * to relay stims to the "body" entity. + */ + virtual idEntity* GetResponseEntity(); + + /** + * Overload bind notify so that when another idAFAttachment is + * bound to us, we copy over our data on the actor we're bound to + **/ + virtual void BindNotify( idEntity *ent ); + + /** + * Also overload UnbindNotify to update the clipmodel physics on the AF we're attacehd to + **/ + virtual void UnbindNotify( idEntity *ent ); + + /** Also overload PostUnBind to clear the body information **/ + virtual void PostUnbind( void ); + + /** Use this to set up stuff attached to AI's heads when they go ragdoll **/ + virtual void DropOnRagdoll( void ); + +protected: + idEntity * body; + idClipModel * combatModel; // render model for hit detection of head + int idleAnim; + jointHandle_t attachJoint; + +protected: + /** + * Copy idActor bindmaster information to another idAFAttachment + **/ + void CopyBodyTo( idAFAttachment *other ); +}; + + +/* +=============================================================================== + +idAFEntity_Base + +=============================================================================== +*/ + +/** +* TDM: Used for dynamically adding ents with clipmodels to the AF +**/ +typedef struct SAddedEnt_s +{ + idEntityPtr ent; // associated entity + + // Must store string name because body ID's get reassigned when any are deleted + idStr bodyName; + // don't need to store constraint since they are deleted along with body + + idStr AddedToBody; // original body we added on to + + int entContents; // original entity clipmodel contents + int entClipMask; // original entity clipmask + int bodyContents; // AF body contents (for saving/restoring) + int bodyClipMask; // AF body clipmask (for saving/restoring) +} SAddedEnt; + + +class idAFEntity_Base : public idAnimatedEntity +{ +public: + CLASS_PROTOTYPE( idAFEntity_Base ); + + idAFEntity_Base( void ); + virtual ~idAFEntity_Base( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); + virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); + virtual bool UpdateAnimationControllers( void ); + virtual void FreeModelDef( void ); + + virtual bool LoadAF( void ); + bool IsActiveAF( void ) const { return af.IsActive(); } + const char * GetAFName( void ) const { return af.GetName(); } + idPhysics_AF * GetAFPhysics( void ) { return af.GetPhysics(); } + + virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, + const int location, trace_t *tr = NULL ); + void SetCombatModel( void ); + idClipModel * GetCombatModel( void ) const; + + // set contents of combatModel to 0 (if false) or restore proper contents (if true) + // returns the contents state before call (false = were disabled, true = were enabled) + bool SetCombatContents( bool enable ); + virtual void LinkCombat( void ); + virtual void UnlinkCombat( void ); + + int BodyForClipModelId( int id ) const; + + void SaveState( idDict &args ) const; + void LoadState( const idDict &args ); + + void AddBindConstraints( void ); + void RemoveBindConstraints( void ); + + /** + * Called when the given ent is about to be unbound/detached + * Updates m_AddedEnts if this ent's clipmodel was added to the AF + **/ + virtual void UnbindNotify( idEntity *ent ); + + /** + * Overloaded idAnimatedEntity::ReAttach methods to take into account AF body clipmask and contents + **/ + virtual void ReAttachToCoords( const char *AttName, idStr jointName, idVec3 offset, idAngles angles ); + virtual void ReAttachToPos( const char *AttName, const char *PosName ); + + /** + * TDM: Adds the clipmodel of the given entity to the AF structure + * Called during the binding process + * AddEntByBody is called by BindToBody, AddEntByJoint called by BindToJoint + * AddEntByBody takes an option joint argument to control the positin of the body with a joint + * If this is not specified, joint information is copied from the AF body we bind to + **/ + void AddEntByBody( idEntity *ent, int bodyID, jointHandle_t joint = INVALID_JOINT ); + void AddEntByJoint( idEntity *ent, jointHandle_t joint ); + + /** + * TDM: Remove a dynamically added ent from the AF of this AFEntity + * Called by UnBindNotify + **/ + void RemoveAddedEnt( idEntity *ent ); + + /** + * TDM: Get an AF body ID for a given joint, and vice versa + **/ + jointHandle_t JointForBody( int body ); + int BodyForJoint( jointHandle_t joint ); + + /** + * TDM: Get AF body for the given added entity + * returns NULL if added ent could not be found + **/ + idAFBody * AFBodyForEnt( idEntity *ent ); + + virtual void ShowEditingDialog( void ); + + static void DropAFs( idEntity *ent, const char *type, idList *list ); + + /** + * Return whether this entity should collide with its team when bound to a team + **/ + bool CollidesWithTeam( void ); + +public: + /** + * This AF should not be able to be picked up off the ground completely when dragged + **/ + bool m_bGroundWhenDragged; + + /** + * List of integer Id's of "critical" bodies to check for touching the ground + * when seeing if the AF is being lifted off the ground + **/ + idList m_GroundBodyList; + + /** + * Number of "critical" bodies that must be kept on the ground at all times + * If the number is below this, dragging the AF up will not be allowed + **/ + int m_GroundBodyMinNum; + + /** + * If set to true, this will use the "af" damping when being grabbed instead of the default damping + **/ + bool m_bDragAFDamping; + +protected: + idAF af; // articulated figure + idClipModel * combatModel; // render model for hit detection + int combatModelContents; + idVec3 spawnOrigin; // spawn origin + idMat3 spawnAxis; // rotation axis used when spawned + int nextSoundTime; // next time this can make a sound + + /** + * List of ents that have been dynamically added to the AF via binding + **/ + idList m_AddedEnts; + + /** + * Set to true if this entity should collide with team members when bound to them + **/ + bool m_bCollideWithTeam; + + /** + * Set to true if this animated AF should activate the AF body collision models + * and move them around to collide with the world when animating. + * NOTE: This MUST be set on AI in order for animation-based tactile alert + * to work properly. + **/ + bool m_bAFPushMoveables; + +protected: + /** + * Set up grounding vars, which apply when the AF might not be able to be + * lifted completely off the ground by the player + **/ + void SetUpGroundingVars( void ); + + void Event_SetConstraintPosition( const char *name, const idVec3 &pos ); + + /** + * GetNumBodies returns the number of bodies in the AF. + * If the AF physics pointer is NULL, it returns 0. + **/ + void Event_GetNumBodies( void ); + + /** + * Parsing attachments happens at a different time in the spawn routine for + * idAFEntities. To accomplish this, the function is overloaded to do + * nothing and a new function is called at the proper time. + **/ + virtual void ParseAttachments( void ); + + /** + * Same as idEntity::ParseAttachments, but called at a different point in spawn routine + **/ + virtual void ParseAttachmentsAF( void ); + + /** + * Restore attached entities that have been added to the AF after a save + **/ + virtual void RestoreAddedEnts( void ); + + /** + * Updates added ent constraints when going ragdoll, to resolve issue of ents bound to joints that can animate and move without the AF body moving + **/ + virtual void UpdateAddedEntConstraints( void ); + + /** + * Set the linear and angular velocities of a particular body given by ID argument + * If the ID is invalid, no velocity is set. + **/ + void Event_SetLinearVelocityB( idVec3 &NewVelocity, int id ); + void Event_SetAngularVelocityB( idVec3 &NewVelocity, int id ); + + /** + * Get the linear and angular velocities of a particular body given by int ID. + * If the body ID is invalid, returns (0,0,0) + **/ + void Event_GetLinearVelocityB( int id ); + void Event_GetAngularVelocityB( int id ); + +}; + +/* +=============================================================================== + +idAFEntity_Gibbable + +=============================================================================== +*/ + +extern const idEventDef EV_Gib; +extern const idEventDef EV_Gibbed; + +class idAFEntity_Gibbable : public idAFEntity_Base { +public: + CLASS_PROTOTYPE( idAFEntity_Gibbable ); + + idAFEntity_Gibbable( void ); + virtual ~idAFEntity_Gibbable( void ); + + void Spawn( void ); + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + virtual void Present( void ); + virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, + const float damageScale, const int location, trace_t *tr = NULL ); + virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName ); + +protected: + idRenderModel * skeletonModel; + int skeletonModelDefHandle; + bool gibbed; + + virtual void Gib( const idVec3 &dir, const char *damageDefName ); + void InitSkeletonModel( void ); + + void Event_Gib( const char *damageDefName ); +}; + +/* +=============================================================================== + + idAFEntity_Generic + +=============================================================================== +*/ + +class idAFEntity_Generic : public idAFEntity_Gibbable { +public: + CLASS_PROTOTYPE( idAFEntity_Generic ); + + idAFEntity_Generic( void ); + virtual ~idAFEntity_Generic( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + void KeepRunningPhysics( void ) { keepRunningPhysics = true; } + +private: + void Event_Activate( idEntity *activator ); + + bool keepRunningPhysics; +}; + + +/* +=============================================================================== + +idAFEntity_WithAttachedHead + +=============================================================================== +*/ + +class idAFEntity_WithAttachedHead : public idAFEntity_Gibbable { +public: + CLASS_PROTOTYPE( idAFEntity_WithAttachedHead ); + + idAFEntity_WithAttachedHead(); + virtual ~idAFEntity_WithAttachedHead(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void SetupHead( void ); + + virtual void Think( void ); + + virtual void Hide( void ); + virtual void Show( void ); + virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); + + virtual void LinkCombat( void ); + virtual void UnlinkCombat( void ); + +protected: + virtual void Gib( const idVec3 &dir, const char *damageDefName ); + +private: + idEntityPtr head; + + void Event_Gib( const char *damageDefName ); + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idAFEntity_Vehicle + +=============================================================================== +*/ + +class idAFEntity_Vehicle : public idAFEntity_Base { +public: + CLASS_PROTOTYPE( idAFEntity_Vehicle ); + + idAFEntity_Vehicle( void ); + + void Spawn( void ); + void Use( idPlayer *player ); + +protected: + idPlayer * player; + jointHandle_t eyesJoint; + jointHandle_t steeringWheelJoint; + float wheelRadius; + float steerAngle; + float steerSpeed; + const idDeclParticle * dustSmoke; + + float GetSteerAngle( void ); +}; + + +/* +=============================================================================== + +idAFEntity_VehicleSimple + +=============================================================================== +*/ + +class idAFEntity_VehicleSimple : public idAFEntity_Vehicle { +public: + CLASS_PROTOTYPE( idAFEntity_VehicleSimple ); + + idAFEntity_VehicleSimple( void ); + virtual ~idAFEntity_VehicleSimple( void ); + + void Spawn( void ); + virtual void Think( void ); + +protected: + idClipModel * wheelModel; + idAFConstraint_Suspension * suspension[4]; + jointHandle_t wheelJoints[4]; + float wheelAngles[4]; +}; + + +/* +=============================================================================== + +idAFEntity_VehicleFourWheels + +=============================================================================== +*/ + +class idAFEntity_VehicleFourWheels : public idAFEntity_Vehicle { +public: + CLASS_PROTOTYPE( idAFEntity_VehicleFourWheels ); + + idAFEntity_VehicleFourWheels( void ); + + void Spawn( void ); + virtual void Think( void ); + +protected: + idAFBody * wheels[4]; + idAFConstraint_Hinge * steering[2]; + jointHandle_t wheelJoints[4]; + float wheelAngles[4]; +}; + + +/* +=============================================================================== + +idAFEntity_VehicleSixWheels + +=============================================================================== +*/ + +class idAFEntity_VehicleSixWheels : public idAFEntity_Vehicle { +public: + CLASS_PROTOTYPE( idAFEntity_VehicleSixWheels ); + + idAFEntity_VehicleSixWheels( void ); + + void Spawn( void ); + virtual void Think( void ); + +private: + idAFBody * wheels[6]; + idAFConstraint_Hinge * steering[4]; + jointHandle_t wheelJoints[6]; + float wheelAngles[6]; +}; + + +/* +=============================================================================== + +idAFEntity_SteamPipe + +=============================================================================== +*/ + +class idAFEntity_SteamPipe : public idAFEntity_Base { +public: + CLASS_PROTOTYPE( idAFEntity_SteamPipe ); + + idAFEntity_SteamPipe( void ); + virtual ~idAFEntity_SteamPipe( void ); + + void Spawn( void ); + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + +private: + int steamBody; + float steamForce; + float steamUpForce; + idForce_Constant force; + renderEntity_t steamRenderEntity; + qhandle_t steamModelDefHandle; + + void InitSteamRenderEntity( void ); +}; + + +#endif /* !__GAME_AFENTITY_H__ */ diff --git a/DarkMod/AIComm_Message.cpp b/game/AIComm_Message.cpp similarity index 78% rename from DarkMod/AIComm_Message.cpp rename to game/AIComm_Message.cpp index 0b92d80d9..426f68c67 100644 --- a/DarkMod/AIComm_Message.cpp +++ b/game/AIComm_Message.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* * Implementation of the CAIComm_Message class. * diff --git a/DarkMod/AIComm_Message.h b/game/AIComm_Message.h similarity index 88% rename from DarkMod/AIComm_Message.h rename to game/AIComm_Message.h index efc1f2841..67c71ca2c 100644 --- a/DarkMod/AIComm_Message.h +++ b/game/AIComm_Message.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /******************************************************************************/ /* */ /* CommunicationStim */ diff --git a/DarkMod/AIVehicle.cpp b/game/AIVehicle.cpp similarity index 92% rename from DarkMod/AIVehicle.cpp rename to game/AIVehicle.cpp index 415c5bb52..761bfe75c 100644 --- a/DarkMod/AIVehicle.cpp +++ b/game/AIVehicle.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2007 The Dark Mod Authors // @@ -14,7 +24,7 @@ #pragma hdrstop #include "AIVehicle.h" -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" //=============================================================================== diff --git a/DarkMod/AIVehicle.h b/game/AIVehicle.h similarity index 82% rename from DarkMod/AIVehicle.h rename to game/AIVehicle.h index 5b7e03786..3faa6680a 100644 --- a/DarkMod/AIVehicle.h +++ b/game/AIVehicle.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2007 The Dark Mod Authors // diff --git a/DarkMod/AbsenceMarker.cpp b/game/AbsenceMarker.cpp similarity index 78% rename from DarkMod/AbsenceMarker.cpp rename to game/AbsenceMarker.cpp index d4d77055c..dbfdd29b7 100644 --- a/DarkMod/AbsenceMarker.cpp +++ b/game/AbsenceMarker.cpp @@ -1,15 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" -#include "../game/game_local.h" #pragma hdrstop + +#include "Game_local.h" #include "AbsenceMarker.h" CLASS_DECLARATION( idEntity, CAbsenceMarker ) diff --git a/game/AbsenceMarker.h b/game/AbsenceMarker.h new file mode 100644 index 000000000..363453872 --- /dev/null +++ b/game/AbsenceMarker.h @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef ABSENCEMARKER_H +#define ABSENCEMARKER_H + +#pragma hdrstop + +#include "Entity.h" + +/** +* The purpose of this entity subclass is to act as a marker for other entities that have +* been moved or destroyed. An instance of this class can be spawned when the other entity +* is removed, destroyed, moved or re-oriented in a noticeable fashion. If an instance +* of this class has a stim, it can signal entities to notice it, and then provide them +* with a copy of the missing entities spawn args so that a script will konw how to +* react to the absence. +* +* @author SophisticatedZombie +* @project The Dark Mod +* @copyright 2006 The Dark Mod team +* +*/ +class CAbsenceMarker : public idEntity +{ +public: + CLASS_PROTOTYPE( CAbsenceMarker ); + + int ownerTeam; + +protected: + + // Defines the spawnargs etc.. for this entity's script type + idStr referenced_entityDefName; + int referenced_entityDefNumber; + + // The name of the entity being referenced + idStr referenced_entityName; + + // The spawn args of the entity being referenced + idDict referenced_spawnArgs; + + +public: + + CAbsenceMarker(void); + + const idDict& GetRefSpawnargs() const; + + // Save and restore + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * Call this method to set the information about the entity + * which this references as "missing" from its normal location. + * + * @param absetEntity idEntityPtr indicating the entity who's + * absence we are marking. + */ + bool initAbsenceReference(idEntity* owner, idBounds& startBounds); +}; + + +// End of header wrapper +#endif diff --git a/game/Actor.cpp b/game/Actor.cpp new file mode 100644 index 000000000..d0c181c1f --- /dev/null +++ b/game/Actor.cpp @@ -0,0 +1,4980 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "Objectives/MissionData.h" +#include "TimerManager.h" +#include "MeleeWeapon.h" +#include "AbsenceMarker.h" + +// #include "logmgr.h" +/*********************************************************************** + + idAnimState + +***********************************************************************/ + +/* +===================== +idAnimState::idAnimState +===================== +*/ +idAnimState::idAnimState() { + self = NULL; + animator = NULL; + thread = NULL; + idleAnim = true; + disabled = true; + channel = ANIMCHANNEL_ALL; + animBlendFrames = 0; + lastAnimBlendFrames = 0; +} + +/* +===================== +idAnimState::~idAnimState +===================== +*/ +idAnimState::~idAnimState() { + delete thread; +} + +/* +===================== +idAnimState::Save +===================== +*/ +void idAnimState::Save( idSaveGame *savefile ) const { + + savefile->WriteObject( self ); + + // Save the entity owner of the animator + savefile->WriteObject( animator->GetEntity() ); + + savefile->WriteObject( thread ); + + savefile->WriteString( state ); + + savefile->WriteInt( animBlendFrames ); + savefile->WriteInt( lastAnimBlendFrames ); + savefile->WriteInt( channel ); + savefile->WriteBool( idleAnim ); + savefile->WriteBool( disabled ); +} + +/* +===================== +idAnimState::Restore +===================== +*/ +void idAnimState::Restore( idRestoreGame *savefile ) { + savefile->ReadObject( reinterpret_cast( self ) ); + + idEntity *animowner; + savefile->ReadObject( reinterpret_cast( animowner ) ); + if ( animowner ) { + animator = animowner->GetAnimator(); + } + + savefile->ReadObject( reinterpret_cast( thread ) ); + + savefile->ReadString( state ); + + savefile->ReadInt( animBlendFrames ); + savefile->ReadInt( lastAnimBlendFrames ); + savefile->ReadInt( channel ); + savefile->ReadBool( idleAnim ); + savefile->ReadBool( disabled ); +} + +/* +===================== +idAnimState::Init +===================== +*/ +void idAnimState::Init( idActor *owner, idAnimator *_animator, int animchannel ) { + assert( owner ); + assert( _animator ); + self = owner; + animator = _animator; + channel = animchannel; + + if ( !thread ) { + thread = new idThread(); + thread->ManualDelete(); + } + thread->EndThread(); + thread->ManualControl(); +} + +/* +===================== +idAnimState::Shutdown +===================== +*/ +void idAnimState::Shutdown( void ) { + delete thread; + thread = NULL; +} + +/* +===================== +idAnimState::SetState +===================== +*/ +void idAnimState::SetState( const char *statename, int blendFrames ) { + const function_t *func; + + func = self->scriptObject.GetFunction( statename ); + if ( !func ) { + assert( 0 ); + gameLocal.Error( "Can't find function '%s' in object '%s'", statename, self->scriptObject.GetTypeName() ); + } + + if (cv_ai_debug_anims.GetBool() && self != gameLocal.GetLocalPlayer()) + { + gameLocal.Printf("Frame %d: New animstate %s (%s)\n", gameLocal.framenum, statename, self->name.c_str()); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame %d: New animstate %s (%s)\r", gameLocal.framenum, statename, self->name.c_str()); + } + + state = statename; + disabled = false; + animBlendFrames = blendFrames; + lastAnimBlendFrames = blendFrames; + thread->CallFunction( self, func, true ); + + animBlendFrames = blendFrames; + lastAnimBlendFrames = blendFrames; + disabled = false; + idleAnim = false; + + if ( ai_debugScript.GetInteger() == self->entityNumber ) { + gameLocal.Printf( "%d: %s: Animstate: %s\n", gameLocal.time, self->name.c_str(), state.c_str() ); + } +} + +/* +===================== +idAnimState::SetFrame +===================== +*/ + +void idAnimState::SetFrame( int anim, int frame ) +{ + animator->SetFrame( channel, anim, frame, gameLocal.time, 0 ); +} + +/* +===================== +idAnimState::StopAnim +===================== +*/ +void idAnimState::StopAnim( int frames ) { + animBlendFrames = 0; + animator->Clear( channel, gameLocal.time, FRAME2MS( frames ) ); +} + +/* +===================== +idAnimState::PlayAnim +===================== +*/ +void idAnimState::PlayAnim( int anim ) { + if ( anim ) { + animator->PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + } + animBlendFrames = 0; +} + +/* +===================== +idAnimState::CycleAnim +===================== +*/ +void idAnimState::CycleAnim( int anim ) { + if ( anim ) { + animator->CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + } + animBlendFrames = 0; +} + +void idAnimState::PauseAnim( int channel, bool bPause) +{ + animator->CurrentAnim( channel )->Pause( bPause ); +} + +bool idAnimState::AnimIsPaused( int channel ) +{ + return animator->CurrentAnim( channel )->IsPaused(); +} + +/* +===================== +idAnimState::BecomeIdle +===================== +*/ +void idAnimState::BecomeIdle( void ) { + idleAnim = true; +} + +/* +===================== +idAnimState::Disabled +===================== +*/ +bool idAnimState::Disabled( void ) const { + return disabled; +} + +/* +===================== +idAnimState::AnimDone +===================== +*/ +bool idAnimState::AnimDone( int blendFrames ) const { + int animDoneTime; + + animDoneTime = animator->CurrentAnim( channel )->GetEndTime(); + if ( animDoneTime < 0 ) { + // playing a cycle + return false; + } else if ( animDoneTime - FRAME2MS( blendFrames ) <= gameLocal.time ) { + return true; + } else { + return false; + } +} + +/* +===================== +idAnimState::IsIdle +===================== +*/ +bool idAnimState::IsIdle( void ) const { + return disabled || idleAnim; +} + +/* +===================== +idAnimState::GetAnimFlags +===================== +*/ +animFlags_t idAnimState::GetAnimFlags( void ) const { + animFlags_t flags; + + memset( &flags, 0, sizeof( flags ) ); + if ( !disabled && !AnimDone( 0 ) ) { + flags = animator->GetAnimFlags( animator->CurrentAnim( channel )->AnimNum() ); + } + + return flags; +} + +idAnimator* idAnimState::GetAnimator() +{ + return animator; +} + +/* +===================== +idAnimState::Enable +===================== +*/ +void idAnimState::Enable( int blendFrames ) { + if ( disabled ) { + disabled = false; + animBlendFrames = blendFrames; + lastAnimBlendFrames = blendFrames; + if ( state.Length() ) { + SetState( state.c_str(), blendFrames ); + } + } +} + +/* +===================== +idAnimState::Disable +===================== +*/ +void idAnimState::Disable( void ) { + disabled = true; + idleAnim = false; +} + +/* +===================== +idAnimState::UpdateState +===================== +*/ +bool idAnimState::UpdateState( void ) { + if ( disabled ) { + return false; + } + + if ( ai_debugScript.GetInteger() == self->entityNumber ) { + thread->EnableDebugInfo(); + } else { + thread->DisableDebugInfo(); + } + + thread->Execute(); + + return true; +} + + +/* +===================== +idAnimState::FinishAction +===================== +*/ +void idAnimState::FinishAction(const idStr& actionname) +{ + if ( waitState == actionname ) { + SetWaitState( "" ); + } +} + +/* +===================== +idAnimState::SetWaitState +===================== +*/ +void idAnimState::SetWaitState( const char *_waitstate ) +{ + waitState = _waitstate; +} + +/* +===================== +idAnimState::WaitState +===================== +*/ +const char *idAnimState::WaitState( void ) const +{ + if ( waitState.Length() ) { + return waitState; + } else { + return NULL; + } +} + + + + + +/*********************************************************************** + + idActor + +***********************************************************************/ + +const char *idActor::MeleeTypeNames[ NUM_MELEE_TYPES ] = { + "Over", "LR", "RL", "Thrust", "General", "General" +}; + +const idEventDef AI_EnableEyeFocus( "enableEyeFocus" ); +const idEventDef AI_DisableEyeFocus( "disableEyeFocus" ); +const idEventDef EV_Footstep( "footstep" ); +const idEventDef EV_FootstepLeft( "leftFoot" ); +const idEventDef EV_FootstepRight( "rightFoot" ); +const idEventDef EV_EnableWalkIK( "EnableWalkIK" ); +const idEventDef EV_DisableWalkIK( "DisableWalkIK" ); +const idEventDef EV_EnableLegIK( "EnableLegIK", "d" ); +const idEventDef EV_DisableLegIK( "DisableLegIK", "d" ); +const idEventDef AI_StopAnim( "stopAnim", "dd" ); +// NOTE: Id defines playanim here, but it is also overloaded in a roundabout way +// by idWeapon (maybe due to limited polymorphism in scripting?) +const idEventDef AI_PlayAnim( "playAnim", "ds", 'd' ); +const idEventDef AI_PauseAnim( "pauseAnim", "dd" ); +const idEventDef AI_AnimIsPaused( "animIsPaused", "d", 'd' ); +const idEventDef AI_PlayCycle( "playCycle", "ds", 'd' ); +const idEventDef AI_IdleAnim( "idleAnim", "ds", 'd' ); +const idEventDef AI_SetSyncedAnimWeight( "setSyncedAnimWeight", "ddf" ); +const idEventDef AI_SyncAnimChannels("syncAnimChannels", "ddf"); +const idEventDef AI_SetBlendFrames( "setBlendFrames", "dd" ); +const idEventDef AI_GetBlendFrames( "getBlendFrames", "d", 'd' ); +const idEventDef AI_AnimState( "animState", "dsd" ); +const idEventDef AI_GetAnimState( "getAnimState", "d", 's' ); +const idEventDef AI_InAnimState( "inAnimState", "ds", 'd' ); +const idEventDef AI_FinishAction( "finishAction", "s" ); +const idEventDef AI_FinishChannelAction( "finishChannelAction", "ds" ); +const idEventDef AI_AnimDone( "animDone", "dd", 'd' ); +const idEventDef AI_OverrideAnim( "overrideAnim", "d" ); +const idEventDef AI_EnableAnim( "enableAnim", "dd" ); +const idEventDef AI_DisableAnimchannel( "disableAnimchannel", "d" ); +const idEventDef AI_PreventPain( "preventPain", "f" ); +const idEventDef AI_DisablePain( "disablePain" ); +const idEventDef AI_EnablePain( "enablePain" ); +const idEventDef AI_GetPainAnim( "getPainAnim", NULL, 's' ); +const idEventDef AI_SetAnimPrefix( "setAnimPrefix", "s" ); +const idEventDef AI_HasAnim( "hasAnim", "ds", 'f' ); +const idEventDef AI_CheckAnim( "checkAnim", "ds" ); +const idEventDef AI_ChooseAnim( "chooseAnim", "ds", 's' ); +const idEventDef AI_AnimLength( "animLength", "ds", 'f' ); +const idEventDef AI_AnimDistance( "animDistance", "ds", 'f' ); +const idEventDef AI_HasEnemies( "hasEnemies", NULL, 'd' ); +const idEventDef AI_NextEnemy( "nextEnemy", "E", 'e' ); +const idEventDef AI_ClosestEnemyToPoint( "closestEnemyToPoint", "v", 'e' ); +const idEventDef AI_SetNextState( "setNextState", "s" ); +const idEventDef AI_SetState( "setState", "s" ); +const idEventDef AI_GetState( "getState", NULL, 's' ); +const idEventDef AI_GetHead( "getHead", NULL, 'e' ); +const idEventDef AI_GetEyePos( "getEyePos", NULL, 'v' ); + +// greebo: Moved these from ai_events.cpp to here +const idEventDef AI_SetHealth( "setHealth", "f" ); +const idEventDef AI_GetHealth( "getHealth", NULL, 'f' ); + +// Attachment Related Events: +const idEventDef AI_Attach( "attach", "es" ); +const idEventDef AI_AttachToPos( "attachToPos", "ess" ); +const idEventDef AI_ReAttachToPos( "reAttachToPos", "ss" ); +const idEventDef AI_ReAttachToCoords( "reAttachToCoords", "ssvv" ); +const idEventDef AI_DropAttachment( "dropAttachment", "s" ); +const idEventDef AI_ShowAttachment( "showAttachment", "sd" ); +const idEventDef AI_DropAttachmentInd( "dropAttachmentInd", "d" ); +const idEventDef AI_ShowAttachmentInd( "showAttachmentInd", "dd" ); +const idEventDef AI_GetAttachment( "getAttachment", "s", 'e' ); +const idEventDef AI_GetAttachmentInd( "getAttachmentInd", "d", 'e' ); +const idEventDef AI_GetNumAttachments( "getNumAttachments", NULL, 'd' ); +// Weapon attachment related events +const idEventDef AI_GetNumRangedWeapons( "getNumRangedWeapons", NULL, 'd' ); +const idEventDef AI_GetNumMeleeWeapons( "getNumMeleeWeapons", NULL, 'd' ); + +// Getting/setting attack flags +const idEventDef AI_GetAttackFlag( "getAttackFlag", "d", 'd' ); +const idEventDef AI_SetAttackFlag( "setAttackFlag", "dd" ); + +// melee combat events +const idEventDef AI_MeleeAttackStarted( "meleeAttackStarted", "d" ); +const idEventDef AI_MeleeParryStarted( "meleeParryStarted", "d" ); +const idEventDef AI_MeleeActionHeld( "meleeActionHeld" ); +const idEventDef AI_MeleeActionReleased( "meleeActionReleased" ); +const idEventDef AI_MeleeActionFinished( "meleeActionFinished" ); +const idEventDef AI_GetMeleeActionState( "getMeleeActState", NULL, 'd' ); +const idEventDef AI_GetMeleeActionPhase( "getMeleeActPhase", NULL, 'd' ); +const idEventDef AI_GetMeleeActionType( "getMeleeActType", NULL, 'd' ); +const idEventDef AI_GetMeleeLastActTime( "getMeleeLastActTime", NULL, 'd' ); +const idEventDef AI_GetMeleeResult( "getMeleeResult", NULL, 'd' ); +const idEventDef AI_GetMeleeLastHitByType( "getMeleeLastHitByType", NULL, 'd' ); +const idEventDef AI_MeleeBestParry( "meleeBestParry", NULL, 'd' ); +const idEventDef AI_MeleeNameForNum( "meleeNameForNum", "d", 's' ); + +// greebo: anim replacement script events +const idEventDef AI_SetReplacementAnim( "setReplacementAnim", "ss"); +const idEventDef AI_LookupReplacementAnim( "lookupReplacementAnim", "s", 's'); +const idEventDef AI_RemoveReplacementAnim( "removeReplacementAnim", "s"); + +CLASS_DECLARATION( idAFEntity_Gibbable, idActor ) + EVENT( AI_EnableEyeFocus, idActor::Event_EnableEyeFocus ) + EVENT( AI_DisableEyeFocus, idActor::Event_DisableEyeFocus ) + EVENT( EV_Footstep, idActor::Event_Footstep ) + EVENT( EV_FootstepLeft, idActor::Event_Footstep ) + EVENT( EV_FootstepRight, idActor::Event_Footstep ) + EVENT( EV_EnableWalkIK, idActor::Event_EnableWalkIK ) + EVENT( EV_DisableWalkIK, idActor::Event_DisableWalkIK ) + EVENT( EV_EnableLegIK, idActor::Event_EnableLegIK ) + EVENT( EV_DisableLegIK, idActor::Event_DisableLegIK ) + EVENT( AI_PreventPain, idActor::Event_PreventPain ) + EVENT( AI_DisablePain, idActor::Event_DisablePain ) + EVENT( AI_EnablePain, idActor::Event_EnablePain ) + EVENT( AI_GetPainAnim, idActor::Event_GetPainAnim ) + EVENT( AI_SetAnimPrefix, idActor::Event_SetAnimPrefix ) + EVENT( AI_StopAnim, idActor::Event_StopAnim ) + EVENT( AI_PlayAnim, idActor::Event_PlayAnim ) + EVENT( AI_PauseAnim, idActor::Event_PauseAnim ) + EVENT( AI_AnimIsPaused, idActor::Event_AnimIsPaused ) + EVENT( AI_PlayCycle, idActor::Event_PlayCycle ) + EVENT( AI_IdleAnim, idActor::Event_IdleAnim ) + EVENT( AI_SetSyncedAnimWeight, idActor::Event_SetSyncedAnimWeight ) + EVENT( AI_SyncAnimChannels, idActor::Event_SyncAnimChannels) + EVENT( AI_SetBlendFrames, idActor::Event_SetBlendFrames ) + EVENT( AI_GetBlendFrames, idActor::Event_GetBlendFrames ) + EVENT( AI_AnimState, idActor::Event_AnimState ) + EVENT( AI_GetAnimState, idActor::Event_GetAnimState ) + EVENT( AI_InAnimState, idActor::Event_InAnimState ) + EVENT( AI_FinishAction, idActor::Event_FinishAction ) + EVENT( AI_FinishChannelAction, idActor::Event_FinishChannelAction ) + EVENT( AI_AnimDone, idActor::Event_AnimDone ) + EVENT( AI_OverrideAnim, idActor::Event_OverrideAnim ) + EVENT( AI_EnableAnim, idActor::Event_EnableAnim ) + EVENT( AI_DisableAnimchannel, idActor::Event_DisableAnimchannel ) + EVENT( AI_HasAnim, idActor::Event_HasAnim ) + EVENT( AI_CheckAnim, idActor::Event_CheckAnim ) + EVENT( AI_ChooseAnim, idActor::Event_ChooseAnim ) + EVENT( AI_AnimLength, idActor::Event_AnimLength ) + EVENT( AI_AnimDistance, idActor::Event_AnimDistance ) + EVENT( AI_HasEnemies, idActor::Event_HasEnemies ) + EVENT( AI_NextEnemy, idActor::Event_NextEnemy ) + EVENT( AI_ClosestEnemyToPoint, idActor::Event_ClosestEnemyToPoint ) + EVENT( AI_MeleeAttackStarted, idActor::Event_MeleeAttackStarted ) + EVENT( AI_MeleeParryStarted, idActor::Event_MeleeParryStarted ) + EVENT( AI_MeleeActionHeld, idActor::Event_MeleeActionHeld ) + EVENT( AI_MeleeActionReleased, idActor::Event_MeleeActionReleased ) + EVENT( AI_MeleeActionFinished, idActor::Event_MeleeActionFinished ) + EVENT( AI_GetMeleeActionState, idActor::Event_GetMeleeActionState ) + EVENT( AI_GetMeleeActionPhase, idActor::Event_GetMeleeActionPhase ) + EVENT( AI_GetMeleeActionType, idActor::Event_GetMeleeActionType ) + EVENT( AI_GetMeleeLastActTime, idActor::Event_GetMeleeLastActTime ) + EVENT( AI_GetMeleeResult, idActor::Event_GetMeleeResult ) + EVENT( AI_GetMeleeLastHitByType, idActor::Event_GetMeleeLastHitByType ) + EVENT( AI_MeleeBestParry, idActor::Event_MeleeBestParry ) + EVENT( AI_MeleeNameForNum, idActor::Event_MeleeNameForNum ) + EVENT( EV_StopSound, idActor::Event_StopSound ) + EVENT( AI_SetNextState, idActor::Event_SetNextState ) + EVENT( AI_SetState, idActor::Event_SetState ) + EVENT( AI_GetState, idActor::Event_GetState ) + EVENT( AI_GetHead, idActor::Event_GetHead ) + EVENT( AI_GetEyePos, idActor::Event_GetEyePos ) + EVENT( AI_SetHealth, idActor::Event_SetHealth ) + EVENT( AI_GetHealth, idActor::Event_GetHealth ) + + EVENT ( AI_Attach, idActor::Event_Attach ) + EVENT ( AI_AttachToPos, idActor::Event_AttachToPos ) + EVENT ( AI_ReAttachToPos, idActor::ReAttachToPos ) + EVENT ( AI_ReAttachToCoords, idActor::ReAttachToCoords ) + EVENT ( AI_DropAttachment, idActor::Detach ) + EVENT ( AI_ShowAttachment, idActor::ShowAttachment ) + EVENT ( AI_DropAttachmentInd, idActor::DetachInd ) + EVENT ( AI_ShowAttachmentInd, idActor::ShowAttachmentInd ) + EVENT ( AI_GetAttachment, idActor::Event_GetAttachment ) + EVENT ( AI_GetAttachmentInd, idActor::Event_GetAttachmentInd ) + EVENT ( AI_GetNumAttachments, idActor::Event_GetNumAttachments ) + EVENT ( AI_GetNumRangedWeapons, idActor::Event_GetNumRangedWeapons ) + EVENT ( AI_GetNumMeleeWeapons, idActor::Event_GetNumMeleeWeapons ) + + EVENT ( AI_SetReplacementAnim, idActor::Event_SetReplacementAnim ) + EVENT ( AI_LookupReplacementAnim, idActor::Event_LookupReplacementAnim ) + EVENT ( AI_RemoveReplacementAnim, idActor::Event_RemoveReplacementAnim ) + + EVENT ( AI_GetAttackFlag, idActor::Event_GetAttackFlag ) + EVENT ( AI_SetAttackFlag, idActor::Event_SetAttackFlag ) + +END_CLASS + +/* +===================== +idActor::idActor +===================== +*/ +idActor::idActor( void ) { + viewAxis.Identity(); + + scriptThread = NULL; // initialized by ConstructScriptObject, which is called by idEntity::Spawn + + use_combat_bbox = false; + head = NULL; + + m_AItype = 0; + m_Innocent = false; + rank = 0; + + greetingState = ECannotGreet; + + m_fovDotHoriz = 0.0f; + m_fovDotVert = 0.0f; + m_SneakAttackMult = 1.0f; + m_SneakAttackThresh = idMath::INFINITY; + eyeOffset.Zero(); + pain_debounce_time = 0; + pain_delay = 0; + pain_threshold = 0; + + melee_range_unarmed = 0.0f; + melee_range = 0.0f; + melee_range_vert = 0.0f; // grayman #2655 + m_MeleePredictedAttTime = 0.0f; + m_MeleePredictedAttTimeUnarmed = 0.0f; + m_MeleeDamageMult = 1.0f; + m_MeleeHoldTimeMin = 0; + m_MeleeHoldTimeMax = 0; + m_MeleeCurrentHoldTime = 0; + m_MeleeAttackRecoveryMin = 0; + m_MeleeAttackRecoveryMax = 0; + m_MeleeCurrentAttackRecovery = 0; + m_MeleeAttackLongRecoveryMin = 0; + m_MeleeAttackLongRecoveryMax = 0; + m_MeleeCurrentAttackLongRecovery = 0; + m_MeleeParryRecoveryMin = 0; + m_MeleeParryRecoveryMax = 0; + m_MeleeCurrentParryRecovery = 0; + m_MeleeRiposteRecoveryMin = 0; + m_MeleeRiposteRecoveryMax = 0; + m_MeleeCurrentRiposteRecovery = 0; + m_MeleePreParryDelayMin = 0; + m_MeleePreParryDelayMax = 0; + m_MeleeCurrentPreParryDelay = 0; + m_MeleeRepeatedPreParryDelayMin = 0; + m_MeleeRepeatedPreParryDelayMax = 0; + m_MeleeCurrentRepeatedPreParryDelay = 0; + m_MeleeNumRepAttacks = 0; + m_MeleeRepAttackTime = 0; + m_MeleePostParryDelayMin = 0; + m_MeleePostParryDelayMax = 0; + m_MeleeCurrentPostParryDelay = 0; + m_MeleeRepeatedPostParryDelayMin = 0; + m_MeleeRepeatedPostParryDelayMax = 0; + m_MeleeCurrentRepeatedPostParryDelay = 0; + + + state = NULL; + idealState = NULL; + + leftEyeJoint = INVALID_JOINT; + rightEyeJoint = INVALID_JOINT; + soundJoint = INVALID_JOINT; + + modelOffset.Zero(); + deltaViewAngles.Zero(); + + painTime = 0; + allowPain = false; + allowEyeFocus = false; + + waitState = ""; + + blink_anim = 0; + blink_time = 0; + blink_min = 0; + blink_max = 0; + + finalBoss = false; + + m_Attachments.SetGranularity( 1 ); + + enemyNode.SetOwner( this ); + enemyList.SetOwner( this ); + + INIT_TIMER_HANDLE(actorGetObstaclesTimer); + INIT_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer); + INIT_TIMER_HANDLE(actorGetWallEdgesTimer); + INIT_TIMER_HANDLE(actorSortWallEdgesTimer); + INIT_TIMER_HANDLE(actorBuildPathTreeTimer); + INIT_TIMER_HANDLE(actorPrunePathTreeTimer); + INIT_TIMER_HANDLE(actorFindOptimalPathTimer); + INIT_TIMER_HANDLE(actorRouteToGoalTimer); + INIT_TIMER_HANDLE(actorSubSampleWalkPathTimer); + INIT_TIMER_HANDLE(actorWalkPathValidTimer); + +} + +/* +===================== +idActor::~idActor +===================== +*/ +idActor::~idActor( void ) { + int i; + idEntity *ent; + + DeconstructScriptObject(); + scriptObject.Free(); + + StopSound( SND_CHANNEL_ANY, false ); + + delete combatModel; + combatModel = NULL; + + if ( head.GetEntity() ) { + head.GetEntity()->ClearBody(); + head.GetEntity()->PostEventMS( &EV_Remove, 0 ); + } + + // remove any attached entities + for( i = 0; i < m_Attachments.Num(); i++ ) { + ent = m_Attachments[ i ].ent.GetEntity(); + if ( ent ) { + ent->PostEventMS( &EV_SafeRemove, 0 ); + } + } + + ShutdownThreads(); +} + +/* +===================== +idActor::Spawn +===================== +*/ +void idActor::Spawn( void ) +{ + idStr jointName; + float fovDegHoriz, fovDegVert; + copyJoints_t copyJoint; + const idKeyValue *kv = NULL; + + animPrefix = ""; + state = NULL; + idealState = NULL; + + spawnArgs.GetFloat( "collision_damage_threshold_hard", "25", m_damage_thresh_hard ); // greebo: dealing 50+ hit points is considered "hard" + spawnArgs.GetFloat( "collision_damage_threshold_min", "5", m_damage_thresh_min ); // falling ~12 ft, g = 1066 + + spawnArgs.GetFloat( "collision_delta_scale", "1.0", m_delta_scale ); + spawnArgs.GetInt( "rank", "0", rank ); + spawnArgs.GetInt( "type", "0", m_AItype ); + spawnArgs.GetBool( "innocent", "0", m_Innocent ); + spawnArgs.GetVector("offsetModel", "0 0 0", modelOffset); + + spawnArgs.GetBool( "use_combat_bbox", "0", use_combat_bbox ); + + viewAxis = GetPhysics()->GetAxis(); + + spawnArgs.GetFloat( "fov", "150", fovDegHoriz ); + // If fov_vert is -1, it will be set the same as horizontal + spawnArgs.GetFloat( "fov_vert", "-1", fovDegVert ); + SetFOV( fovDegHoriz, fovDegVert ); + + pain_debounce_time = 0; + + pain_delay = SEC2MS( spawnArgs.GetFloat( "pain_delay" ) ); + pain_threshold = spawnArgs.GetInt( "pain_threshold" ); + + // load melee settings based on AI skill level + player difficulty + LoadMeleeSet(); + // adjust health based on multiplier that may be in melee set + health += spawnArgs.GetFloat("health_offset", "0.0"); + + melee_range_unarmed = spawnArgs.GetFloat( "melee_range","64"); + melee_range = melee_range_unarmed; + + // grayman #2655 - if "melee_range_vert" has a value, use that, + // otherwise set it to melee_range + + melee_range_vert = spawnArgs.GetFloat( "melee_range_vert","0"); + if (melee_range_vert == 0) + { + melee_range_vert = melee_range; + } + + m_MeleePredictedAttTimeUnarmed = 0.001f * spawnArgs.GetFloat("melee_predicted_attack_time"); + m_MeleePredictedAttTime = m_MeleePredictedAttTimeUnarmed; + m_MeleeDamageMult = spawnArgs.GetFloat("melee_damage_mod","1.0f"); + m_MeleeHoldTimeMin = spawnArgs.GetInt("melee_hold_time_min"); + m_MeleeHoldTimeMax = spawnArgs.GetInt("melee_hold_time_max"); + m_MeleeParryHoldMax = spawnArgs.GetInt("melee_parry_hold_max"); + m_MeleeParryHoldMin = spawnArgs.GetInt("melee_parry_hold_min"); + m_MeleeAttackRecoveryMin = spawnArgs.GetInt("melee_attack_recovery_min"); + m_MeleeAttackRecoveryMax = spawnArgs.GetInt("melee_attack_recovery_max"); + m_MeleeAttackLongRecoveryMin = spawnArgs.GetInt("melee_attack_long_recovery_min"); + m_MeleeAttackLongRecoveryMax = spawnArgs.GetInt("melee_attack_long_recovery_max"); + m_MeleeParryRecoveryMin = spawnArgs.GetInt("melee_parry_recovery_min"); + m_MeleeParryRecoveryMax = spawnArgs.GetInt("melee_parry_recovery_max"); + m_MeleeRiposteRecoveryMin = spawnArgs.GetInt("melee_riposte_recovery_min"); + m_MeleeRiposteRecoveryMax = spawnArgs.GetInt("melee_riposte_recovery_max"); + m_MeleePreParryDelayMin = spawnArgs.GetInt("melee_pre_parry_delay_min"); + m_MeleePreParryDelayMax = spawnArgs.GetInt("melee_pre_parry_delay_max"); + m_MeleeRepeatedPreParryDelayMin = spawnArgs.GetInt("melee_repeated_pre_parry_delay_min"); + m_MeleeRepeatedPreParryDelayMax = spawnArgs.GetInt("melee_repeated_pre_parry_delay_max"); + m_MeleePostParryDelayMin = spawnArgs.GetInt("melee_post_parry_delay_min"); + m_MeleePostParryDelayMax = spawnArgs.GetInt("melee_post_parry_delay_max"); + m_MeleeRepeatedPostParryDelayMin = spawnArgs.GetInt("melee_repeated_post_parry_delay_min"); + m_MeleeRepeatedPostParryDelayMax = spawnArgs.GetInt("melee_repeated_post_parry_delay_max"); + m_MeleeNumRepAttacks = spawnArgs.GetInt("melee_num_rep_attacks"); + m_MeleeRepAttackTime = spawnArgs.GetInt("melee_rep_attack_time"); + + LoadAF(); + + walkIK.Init( this, IK_ANIM, modelOffset ); + + // the animation used to be set to the IK_ANIM at this point, but that was fixed, resulting in + // attachments not binding correctly, so we're stuck setting the IK_ANIM before attaching things. + animator.ClearAllAnims( gameLocal.time, 0 ); + animator.SetFrame( ANIMCHANNEL_ALL, animator.GetAnim( IK_ANIM ), 0, 0, 0 ); + + SetupDamageGroups(); + ParseAttachmentsAF(); + SetupHead(); + + // clear the bind anim + animator.ClearAllAnims( gameLocal.time, 0 ); + + idEntity *headEnt = head.GetEntity(); + idAnimator *headAnimator; + if ( headEnt ) { + headAnimator = headEnt->GetAnimator(); + } else { + headAnimator = &animator; + } + + if ( headEnt ) { + // set up the list of joints to copy to the head + for( kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) { + if ( kv->GetValue() == "" ) { + // probably clearing out inherited key, so skip it + continue; + } + + jointName = kv->GetKey(); + if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) { + copyJoint.mod = JOINTMOD_WORLD_OVERRIDE; + } else { + jointName.StripLeadingOnce( "copy_joint " ); + copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE; + } + + copyJoint.from = animator.GetJointHandle( jointName ); + if ( copyJoint.from == INVALID_JOINT ) { + gameLocal.Warning( "Unknown copy_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); + continue; + } + + jointName = kv->GetValue(); + copyJoint.to = headAnimator->GetJointHandle( jointName ); + if ( copyJoint.to == INVALID_JOINT ) { + gameLocal.Warning( "Unknown copy_joint '%s' on head of entity %s", jointName.c_str(), name.c_str() ); + continue; + } + + copyJoints.Append( copyJoint ); + } + } + + greetingState = spawnArgs.GetBool("canGreet", "0") ? ENotGreetingAnybody : ECannotGreet; + + // set up blinking + blink_anim = headAnimator->GetAnim( "blink" ); + blink_time = 0; // it's ok to blink right away + blink_min = SEC2MS( spawnArgs.GetFloat( "blink_min", "0.5" ) ); + blink_max = SEC2MS( spawnArgs.GetFloat( "blink_max", "8" ) ); + + // set up the head anim if necessary + int headAnim = headAnimator->GetAnim( "def_head" ); + if ( headAnim ) { + if ( headEnt ) { + headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, 0 ); + } else { + headAnimator->CycleAnim( ANIMCHANNEL_HEAD, headAnim, gameLocal.time, 0 ); + } + } + + if ( spawnArgs.GetString( "sound_bone", "", jointName ) ) { + soundJoint = animator.GetJointHandle( jointName ); + if ( soundJoint == INVALID_JOINT ) { + gameLocal.Warning( "idAnimated '%s' at (%s): cannot find joint '%s' for sound playback", name.c_str(), GetPhysics()->GetOrigin().ToString(0), jointName.c_str() ); + } + } + + finalBoss = spawnArgs.GetBool( "finalBoss" ); + + canUseElevators = spawnArgs.GetBool("canOperateElevators", "0"); + + // greebo: Set up the melee flags for AI without weapons + if (spawnArgs.GetBool("unarmed_melee")) + { + SetAttackFlag(COMBAT_MELEE, true); + // add the general unarmed attack to possible melee attacks list + // this will be overridden if they get a weapon attached + // TODO: Add this back in if the weapon is later detached? + m_MeleeStatus.m_attacks.Append(MELEETYPE_UNBLOCKABLE); + } + + if (spawnArgs.GetBool("unarmed_ranged")) + { + SetAttackFlag(COMBAT_RANGED, true); + } + + lowHealthThreshold = spawnArgs.GetInt("low_health_threshold", "-1"); + lowHealthScript = spawnArgs.GetString("low_health_script"); + + LoadVocalSet(); + + // Load replacement animations from our own spawnargs + LoadReplacementAnims(spawnArgs); + + FinishSetup(); + + CREATE_TIMER(actorGetObstaclesTimer, name, "GetObstacles"); + CREATE_TIMER(actorGetPointOutsideObstaclesTimer, name, "GetPointOutsideObstacles"); + CREATE_TIMER(actorGetWallEdgesTimer, name, "GetWallEdges"); + CREATE_TIMER(actorSortWallEdgesTimer, name, "SortWallEdges"); + CREATE_TIMER(actorBuildPathTreeTimer, name, "BuildPathTree"); + CREATE_TIMER(actorPrunePathTreeTimer, name, "PrunePathTree"); + CREATE_TIMER(actorFindOptimalPathTimer, name, "FindOptimalPath"); + CREATE_TIMER(actorRouteToGoalTimer, name, "RouteToGoal"); + CREATE_TIMER(actorSubSampleWalkPathTimer, name, "SubSampleWalkPath"); + CREATE_TIMER(actorWalkPathValidTimer, name, "WalkPathValid"); + + m_pathRank = rank; // grayman #2345 - rank for path-finding + m_nextKickTime = 0; // grayman #2728 +} + +/* +================ +idActor::FinishSetup +================ +*/ +void idActor::FinishSetup( void ) { + const char *scriptObjectName; + + // setup script object + if ( spawnArgs.GetString( "scriptobject", NULL, &scriptObjectName ) ) { + if ( !scriptObject.SetType( scriptObjectName ) ) { + gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() ); + } + + ConstructScriptObject(); + } + + SetupBody(); +} + +/* +================ +idActor::SetupHead +================ +*/ +void idActor::SetupHead() +{ + if(gameLocal.isClient) + return; + + idStr headModelDefName = spawnArgs.GetString( "def_head", "" ); + + if (!headModelDefName.IsEmpty()) + { + // We look if the head model is defined as a key to have a specific offset. + // If that is not the case, then we use the default value, if it exists, + // otherwise there is no offset at all. + mHeadModelOffset = spawnArgs.GetVector(headModelDefName, "0 0 0"); + + // greebo: Regardless what happens, the offsetHeadModel vector always gets added to the offset + mHeadModelOffset += spawnArgs.GetVector("offsetHeadModel", "0 0 0"); + + idStr jointName = spawnArgs.GetString( "head_joint" ); + jointHandle_t joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Joint '%s' not found for 'head_joint' on '%s'", jointName.c_str(), name.c_str() ); + } + + // set the damage joint to be part of the head damage group (if possible) + jointHandle_t damageJoint = joint; + + for (int i = 0; i < damageGroups.Num(); i++ ) + { + if ( damageGroups[ i ] == "head" ) { + damageJoint = static_cast( i ); + break; + } + } + + // Setup the default spawnargs for all heads + idDict args; + + const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); + + if (def == NULL) + { + gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); + + // Try to fallback on the default head entityDef + def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); + } + + if (def != NULL) + { + // Make a copy of the default spawnargs + args = def->dict; + } + else + { + gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); + } + + // Copy any sounds in case we have frame commands on the head + for (const idKeyValue* kv = spawnArgs.MatchPrefix("snd_", NULL); kv != NULL; kv = spawnArgs.MatchPrefix("snd_", kv)) + { + args.Set(kv->GetKey(), kv->GetValue()); + } + + // Spawn the head entity + idEntity* ent = gameLocal.SpawnEntityType(idAFAttachment::Type, &args); + idAFAttachment* headEnt = static_cast(ent); + headEnt->SetName( name + "_head" ); + + // Retrieve the actual model from the head entityDef + idStr headModel = args.GetString("model"); + if (headModel.IsEmpty()) + { + gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); + } + headEnt->SetBody( this, headModel, damageJoint ); + headEnt->SetCombatModel(); + + // Store the head locally + head = headEnt; + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("SETBODY: Actor %s : damage joint %d for attached head is part of damage group %s\r", name.c_str(), (int) damageJoint, GetDamageGroup( damageJoint ) ); + + // Add the head as attachment + idVec3 origin; + idMat3 axis; + CAttachInfo& attach = m_Attachments.Alloc(); + + attach.channel = animator.GetChannelForJoint( joint ); + animator.GetJointTransform( joint, gameLocal.time, origin, axis ); + origin = renderEntity.origin + ( origin + modelOffset + mHeadModelOffset ) * renderEntity.axis; + attach.ent = headEnt; + attach.posName = jointName; // grayman #2603 + + headEnt->SetOrigin( origin ); + headEnt->SetAxis( renderEntity.axis ); + headEnt->BindToJoint( this, joint, true ); + + // greebo: Setup the frob-peer relationship between head and body + m_FrobPeers.AddUnique(headEnt->name); + } +} + +/* +================ +idActor::CopyJointsFromBodyToHead +================ +*/ +void idActor::CopyJointsFromBodyToHead( void ) { + idEntity *headEnt = head.GetEntity(); + idAnimator *headAnimator; + int i; + idMat3 mat; + idMat3 axis; + idVec3 pos; + + if ( !headEnt ) { + return; + } + + headAnimator = headEnt->GetAnimator(); + + // copy the animation from the body to the head + for( i = 0; i < copyJoints.Num(); i++ ) { + if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) { + mat = headEnt->GetPhysics()->GetAxis().Transpose(); + GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); + pos -= headEnt->GetPhysics()->GetOrigin(); + headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat ); + headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat ); + } else { + animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); + headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos ); + headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis ); + } + } +} + +/* +================ +idActor::Restart +================ +*/ +void idActor::Restart( void ) { + assert( !head.GetEntity() ); + SetupHead(); + FinishSetup(); +} + +/* +================ +idActor::Save + +archive object for savegame file +================ +*/ +void idActor::Save( idSaveGame *savefile ) const { + idActor *ent; + int i; + + savefile->WriteInt( rank ); + savefile->WriteInt( m_AItype ); + savefile->WriteBool( m_Innocent ); + savefile->WriteMat3( viewAxis ); + + savefile->WriteInt( enemyList.Num() ); + for ( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + savefile->WriteObject( ent ); + } + + savefile->WriteInt(static_cast(greetingState)); + + // melee stuff + m_MeleeStatus.Save( savefile ); + savefile->WriteFloat( melee_range_unarmed ); + savefile->WriteFloat( melee_range ); + savefile->WriteFloat( melee_range_vert ); // grayman #2655 + savefile->WriteFloat( m_MeleePredictedAttTimeUnarmed ); + savefile->WriteFloat( m_MeleePredictedAttTime ); + savefile->WriteFloat( m_MeleeDamageMult ); + savefile->WriteInt( m_MeleeHoldTimeMin ); + savefile->WriteInt( m_MeleeHoldTimeMax ); + savefile->WriteInt( m_MeleeCurrentHoldTime ); + savefile->WriteInt( m_MeleeAttackRecoveryMin ); + savefile->WriteInt( m_MeleeAttackRecoveryMax ); + savefile->WriteInt( m_MeleeCurrentAttackRecovery ); + savefile->WriteInt( m_MeleeAttackLongRecoveryMin ); + savefile->WriteInt( m_MeleeAttackLongRecoveryMax ); + savefile->WriteInt( m_MeleeCurrentAttackLongRecovery ); + savefile->WriteInt( m_MeleeParryRecoveryMin ); + savefile->WriteInt( m_MeleeParryRecoveryMax ); + savefile->WriteInt( m_MeleeCurrentParryRecovery ); + savefile->WriteInt( m_MeleeRiposteRecoveryMin ); + savefile->WriteInt( m_MeleeRiposteRecoveryMax ); + savefile->WriteInt( m_MeleeCurrentRiposteRecovery ); + savefile->WriteInt( m_MeleePreParryDelayMin ); + savefile->WriteInt( m_MeleePreParryDelayMax ); + savefile->WriteInt( m_MeleeCurrentPreParryDelay ); + savefile->WriteInt( m_MeleeRepeatedPreParryDelayMin ); + savefile->WriteInt( m_MeleeRepeatedPreParryDelayMax ); + savefile->WriteInt( m_MeleeCurrentRepeatedPreParryDelay ); + savefile->WriteInt( m_MeleeNumRepAttacks ); + savefile->WriteInt( m_MeleeRepAttackTime ); + savefile->WriteInt( m_MeleePostParryDelayMin ); + savefile->WriteInt( m_MeleePostParryDelayMax ); + savefile->WriteInt( m_MeleeCurrentPostParryDelay ); + savefile->WriteInt( m_MeleeRepeatedPostParryDelayMin ); + savefile->WriteInt( m_MeleeRepeatedPostParryDelayMax ); + savefile->WriteInt( m_MeleeCurrentRepeatedPostParryDelay ); + savefile->WriteInt( m_pathRank ); // grayman #2345 + savefile->WriteInt( m_nextKickTime ); // grayman #2728 + + savefile->WriteFloat( m_fovDotHoriz ); + savefile->WriteFloat( m_fovDotVert ); + savefile->WriteVec3( eyeOffset ); + savefile->WriteVec3( modelOffset ); + savefile->WriteVec3(mHeadModelOffset); + savefile->WriteAngles( deltaViewAngles ); + + savefile->WriteInt( pain_debounce_time ); + savefile->WriteInt( pain_delay ); + savefile->WriteInt( pain_threshold ); + + savefile->WriteInt( damageGroups.Num() ); + for( i = 0; i < damageGroups.Num(); i++ ) { + savefile->WriteString( damageGroups[ i ] ); + } + + savefile->WriteInt( damageScale.Num() ); + for( i = 0; i < damageScale.Num(); i++ ) { + savefile->WriteFloat( damageScale[ i ] ); + } + + savefile->WriteInt(lowHealthThreshold); + savefile->WriteString(lowHealthScript); + + savefile->WriteFloat( m_SneakAttackThresh ); + savefile->WriteFloat( m_SneakAttackMult ); + + savefile->WriteBool( use_combat_bbox ); + head.Save( savefile ); + + savefile->WriteInt( copyJoints.Num() ); + for( i = 0; i < copyJoints.Num(); i++ ) { + savefile->WriteInt( copyJoints[i].mod ); + savefile->WriteJoint( copyJoints[i].from ); + savefile->WriteJoint( copyJoints[i].to ); + } + + savefile->WriteJoint( leftEyeJoint ); + savefile->WriteJoint( rightEyeJoint ); + savefile->WriteJoint( soundJoint ); + + walkIK.Save( savefile ); + + savefile->WriteString( animPrefix ); + savefile->WriteString( painAnim ); + + savefile->WriteInt( blink_anim ); + savefile->WriteInt( blink_time ); + savefile->WriteInt( blink_min ); + savefile->WriteInt( blink_max ); + + // script variables + savefile->WriteObject( scriptThread ); + + savefile->WriteString( waitState ); + + headAnim.Save( savefile ); + torsoAnim.Save( savefile ); + legsAnim.Save( savefile ); + + savefile->WriteBool( allowPain ); + savefile->WriteBool( allowEyeFocus ); + + savefile->WriteInt( painTime ); + + savefile->WriteBool(canUseElevators); + + savefile->WriteBool( finalBoss ); + savefile->WriteFloat( m_damage_thresh_hard ); + savefile->WriteFloat( m_delta_scale ); + savefile->WriteFloat( m_damage_thresh_min ); + + idToken token; + + //FIXME: this is unneccesary + if ( state ) { + idLexer src( state->Name(), idStr::Length( state->Name() ), "idAI::Save" ); + + src.ReadTokenOnLine( &token ); + src.ExpectTokenString( "::" ); + src.ReadTokenOnLine( &token ); + + savefile->WriteString( token ); + } else { + savefile->WriteString( "" ); + } + + if ( idealState ) { + idLexer src( idealState->Name(), idStr::Length( idealState->Name() ), "idAI::Save" ); + + src.ReadTokenOnLine( &token ); + src.ExpectTokenString( "::" ); + src.ReadTokenOnLine( &token ); + + savefile->WriteString( token ); + } else { + savefile->WriteString( "" ); + } + + savefile->WriteFloat(m_stepvol_walk); + savefile->WriteFloat(m_stepvol_run); + savefile->WriteFloat(m_stepvol_creep); + + savefile->WriteFloat(m_stepvol_crouch_walk); + savefile->WriteFloat(m_stepvol_crouch_creep); + savefile->WriteFloat(m_stepvol_crouch_run); + + savefile->WriteDict(&m_replacementAnims); + + savefile->WriteInt(static_cast(m_AttackFlags.size())); + for (std::set::const_iterator i = m_AttackFlags.begin(); i != m_AttackFlags.end(); ++i) + { + savefile->WriteInt(static_cast(*i)); + } + + SAVE_TIMER_HANDLE(actorGetObstaclesTimer, savefile); + SAVE_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer, savefile); + SAVE_TIMER_HANDLE(actorGetWallEdgesTimer, savefile); + SAVE_TIMER_HANDLE(actorSortWallEdgesTimer, savefile); + SAVE_TIMER_HANDLE(actorBuildPathTreeTimer, savefile); + SAVE_TIMER_HANDLE(actorPrunePathTreeTimer, savefile); + SAVE_TIMER_HANDLE(actorFindOptimalPathTimer, savefile); + SAVE_TIMER_HANDLE(actorRouteToGoalTimer, savefile); + SAVE_TIMER_HANDLE(actorSubSampleWalkPathTimer, savefile); + SAVE_TIMER_HANDLE(actorWalkPathValidTimer, savefile); +} + +/* +================ +idActor::Restore + +unarchives object from save game file +================ +*/ +void idActor::Restore( idRestoreGame *savefile ) { + int i, num; + idActor *ent; + + savefile->ReadInt( rank ); + savefile->ReadInt( m_AItype ); + savefile->ReadBool( m_Innocent ); + savefile->ReadMat3( viewAxis ); + + savefile->ReadInt( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadObject( reinterpret_cast( ent ) ); + assert( ent ); + if ( ent ) { + ent->enemyNode.AddToEnd( enemyList ); + } + } + + savefile->ReadInt(i); + assert(i >= ECannotGreet && i < ENumAIGreetingStates); + greetingState = static_cast(i); + + // melee stuff + m_MeleeStatus.Restore( savefile ); + savefile->ReadFloat( melee_range_unarmed ); + savefile->ReadFloat( melee_range ); + savefile->ReadFloat( melee_range_vert ); // grayman #2655 + savefile->ReadFloat( m_MeleePredictedAttTimeUnarmed ); + savefile->ReadFloat( m_MeleePredictedAttTime ); + savefile->ReadFloat( m_MeleeDamageMult ); + savefile->ReadInt( m_MeleeHoldTimeMin ); + savefile->ReadInt( m_MeleeHoldTimeMax ); + savefile->ReadInt( m_MeleeCurrentHoldTime ); + savefile->ReadInt( m_MeleeAttackRecoveryMin ); + savefile->ReadInt( m_MeleeAttackRecoveryMax ); + savefile->ReadInt( m_MeleeCurrentAttackRecovery ); + savefile->ReadInt( m_MeleeAttackLongRecoveryMin ); + savefile->ReadInt( m_MeleeAttackLongRecoveryMax ); + savefile->ReadInt( m_MeleeCurrentAttackLongRecovery ); + savefile->ReadInt( m_MeleeParryRecoveryMin ); + savefile->ReadInt( m_MeleeParryRecoveryMax ); + savefile->ReadInt( m_MeleeCurrentParryRecovery ); + savefile->ReadInt( m_MeleeRiposteRecoveryMin ); + savefile->ReadInt( m_MeleeRiposteRecoveryMax ); + savefile->ReadInt( m_MeleeCurrentRiposteRecovery ); + savefile->ReadInt( m_MeleePreParryDelayMin ); + savefile->ReadInt( m_MeleePreParryDelayMax ); + savefile->ReadInt( m_MeleeCurrentPreParryDelay ); + savefile->ReadInt( m_MeleeRepeatedPreParryDelayMin ); + savefile->ReadInt( m_MeleeRepeatedPreParryDelayMax ); + savefile->ReadInt( m_MeleeCurrentRepeatedPreParryDelay ); + savefile->ReadInt( m_MeleeNumRepAttacks ); + savefile->ReadInt( m_MeleeRepAttackTime ); + savefile->ReadInt( m_MeleePostParryDelayMin ); + savefile->ReadInt( m_MeleePostParryDelayMax ); + savefile->ReadInt( m_MeleeCurrentPostParryDelay ); + savefile->ReadInt( m_MeleeRepeatedPostParryDelayMin ); + savefile->ReadInt( m_MeleeRepeatedPostParryDelayMax ); + savefile->ReadInt( m_MeleeCurrentRepeatedPostParryDelay ); + savefile->ReadInt( m_pathRank ); // grayman #2345 + savefile->ReadInt(m_nextKickTime); // grayman #2728 + + savefile->ReadFloat( m_fovDotHoriz ); + savefile->ReadFloat( m_fovDotVert ); + savefile->ReadVec3( eyeOffset ); + savefile->ReadVec3( modelOffset ); + savefile->ReadVec3(mHeadModelOffset); + savefile->ReadAngles( deltaViewAngles ); + + savefile->ReadInt( pain_debounce_time ); + savefile->ReadInt( pain_delay ); + savefile->ReadInt( pain_threshold ); + + savefile->ReadInt( num ); + damageGroups.SetGranularity( 1 ); + damageGroups.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadString( damageGroups[ i ] ); + } + + savefile->ReadInt( num ); + damageScale.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadFloat( damageScale[ i ] ); + } + + savefile->ReadInt(lowHealthThreshold); + savefile->ReadString(lowHealthScript); + + savefile->ReadFloat( m_SneakAttackThresh ); + savefile->ReadFloat( m_SneakAttackMult ); + + savefile->ReadBool( use_combat_bbox ); + head.Restore( savefile ); + + savefile->ReadInt( num ); + copyJoints.SetNum( num ); + for( i = 0; i < num; i++ ) { + int val; + savefile->ReadInt( val ); + copyJoints[i].mod = static_cast( val ); + savefile->ReadJoint( copyJoints[i].from ); + savefile->ReadJoint( copyJoints[i].to ); + } + + savefile->ReadJoint( leftEyeJoint ); + savefile->ReadJoint( rightEyeJoint ); + savefile->ReadJoint( soundJoint ); + + walkIK.Restore( savefile ); + + savefile->ReadString( animPrefix ); + savefile->ReadString( painAnim ); + + savefile->ReadInt( blink_anim ); + savefile->ReadInt( blink_time ); + savefile->ReadInt( blink_min ); + savefile->ReadInt( blink_max ); + + savefile->ReadObject( reinterpret_cast( scriptThread ) ); + + savefile->ReadString( waitState ); + + headAnim.Restore( savefile ); + torsoAnim.Restore( savefile ); + legsAnim.Restore( savefile ); + + savefile->ReadBool( allowPain ); + savefile->ReadBool( allowEyeFocus ); + + savefile->ReadInt( painTime ); + savefile->ReadBool(canUseElevators); + + savefile->ReadBool( finalBoss ); + savefile->ReadFloat( m_damage_thresh_hard ); + savefile->ReadFloat( m_delta_scale ); + savefile->ReadFloat( m_damage_thresh_min ); + + idStr statename; + + savefile->ReadString( statename ); + if ( statename.Length() > 0 ) { + state = GetScriptFunction( statename ); + } + + savefile->ReadString( statename ); + if ( statename.Length() > 0 ) { + idealState = GetScriptFunction( statename ); + } + + savefile->ReadFloat(m_stepvol_walk); + savefile->ReadFloat(m_stepvol_run); + savefile->ReadFloat(m_stepvol_creep); + + savefile->ReadFloat(m_stepvol_crouch_walk); + savefile->ReadFloat(m_stepvol_crouch_creep); + savefile->ReadFloat(m_stepvol_crouch_run); + + savefile->ReadDict(&m_replacementAnims); + + m_AttackFlags.clear(); + savefile->ReadInt(num); + for (int i = 0; i < num; i++) + { + int temp; + savefile->ReadInt(temp); + assert(static_cast(temp) >= COMBAT_NONE && static_cast(temp) <= COMBAT_RANGED); + m_AttackFlags.insert(temp); + } + + RESTORE_TIMER_HANDLE(actorGetObstaclesTimer, savefile); + RESTORE_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer, savefile); + RESTORE_TIMER_HANDLE(actorGetWallEdgesTimer, savefile); + RESTORE_TIMER_HANDLE(actorSortWallEdgesTimer, savefile); + RESTORE_TIMER_HANDLE(actorBuildPathTreeTimer, savefile); + RESTORE_TIMER_HANDLE(actorPrunePathTreeTimer, savefile); + RESTORE_TIMER_HANDLE(actorFindOptimalPathTimer, savefile); + RESTORE_TIMER_HANDLE(actorRouteToGoalTimer, savefile); + RESTORE_TIMER_HANDLE(actorSubSampleWalkPathTimer, savefile); + RESTORE_TIMER_HANDLE(actorWalkPathValidTimer, savefile); + +} + +/* +================ +idActor::Hide +================ +*/ +void idActor::Hide( void ) +{ + idAFEntity_Base::Hide(); + if ( head.GetEntity() ) + { + head.GetEntity()->Hide(); + } + UnlinkCombat(); +} + +/* +================ +idActor::Show +================ +*/ +void idActor::Show( void ) +{ + idAFEntity_Base::Show(); + if ( head.GetEntity() ) { + head.GetEntity()->Show(); + } + + LinkCombat(); +} + +/* +============== +idActor::GetDefaultSurfaceType +============== +*/ +int idActor::GetDefaultSurfaceType( void ) const { + return SURFTYPE_FLESH; +} + +/* +================ +idActor::ProjectOverlay +================ +*/ +void idActor::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { + idEntity *ent; + idEntity *next; + + idEntity::ProjectOverlay( origin, dir, size, material ); + + for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { + next = ent->GetNextTeamEntity(); + if ( ent->GetBindMaster() == this ) { + if ( ent->fl.takedamage && ent->spawnArgs.GetBool( "bleed" ) ) { + ent->ProjectOverlay( origin, dir, size, material ); + } + } + } +} + +/* +================ +idActor::LoadAF +================ +*/ +bool idActor::LoadAF( void ) +{ + bool bReturnVal = false; + idStr fileName; + + if ( !spawnArgs.GetString( "ragdoll", "*unknown*", fileName ) || !fileName.Length() ) + { + goto Quit; + } + af.SetAnimator( GetAnimator() ); + bReturnVal = af.Load( this, fileName ); + SetUpGroundingVars(); + + if( m_bAFPushMoveables ) + { + af.SetupPose( this, gameLocal.time ); + af.GetPhysics()->EnableClip(); + } + +Quit: + return bReturnVal; +} + +/* +===================== +idActor::SetupBody +===================== +*/ +void idActor::SetupBody( void ) { + const char *jointname; + + animator.ClearAllAnims( gameLocal.time, 0 ); + animator.ClearAllJoints(); + + idEntity *headEnt = head.GetEntity(); + if ( headEnt ) { + jointname = spawnArgs.GetString( "bone_leftEye" ); + leftEyeJoint = headEnt->GetAnimator()->GetJointHandle( jointname ); + + jointname = spawnArgs.GetString( "bone_rightEye" ); + rightEyeJoint = headEnt->GetAnimator()->GetJointHandle( jointname ); + + // set up the eye height. check if it's specified in the def. + if ( !spawnArgs.GetFloat( "eye_height", "0", eyeOffset.z ) ) { + // if not in the def, then try to base it off the idle animation + int anim = headEnt->GetAnimator()->GetAnim( "idle" ); + if ( anim && ( leftEyeJoint != INVALID_JOINT ) ) { + idVec3 pos; + idMat3 axis; + headEnt->GetAnimator()->PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, 0 ); + headEnt->GetAnimator()->GetJointTransform( leftEyeJoint, gameLocal.time, pos, axis ); + headEnt->GetAnimator()->ClearAllAnims( gameLocal.time, 0 ); + headEnt->GetAnimator()->ForceUpdate(); + pos += headEnt->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + eyeOffset = pos + modelOffset; + } else { + // just base it off the bounding box size + eyeOffset.z = GetPhysics()->GetBounds()[ 1 ].z - 6; + } + } + headAnim.Init( this, headEnt->GetAnimator(), ANIMCHANNEL_ALL ); + } else { + jointname = spawnArgs.GetString( "bone_leftEye" ); + leftEyeJoint = animator.GetJointHandle( jointname ); + + jointname = spawnArgs.GetString( "bone_rightEye" ); + rightEyeJoint = animator.GetJointHandle( jointname ); + + // set up the eye height. check if it's specified in the def. + if ( !spawnArgs.GetFloat( "eye_height", "0", eyeOffset.z ) ) { + // if not in the def, then try to base it off the idle animation + int anim = animator.GetAnim( "idle" ); + if ( anim && ( leftEyeJoint != INVALID_JOINT ) ) { + idVec3 pos; + idMat3 axis; + animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, 0 ); + animator.GetJointTransform( leftEyeJoint, gameLocal.time, pos, axis ); + animator.ClearAllAnims( gameLocal.time, 0 ); + animator.ForceUpdate(); + eyeOffset = pos + modelOffset; + } else { + // just base it off the bounding box size + eyeOffset.z = GetPhysics()->GetBounds()[ 1 ].z - 6; + } + } + headAnim.Init( this, &animator, ANIMCHANNEL_HEAD ); + } + + waitState = ""; + + torsoAnim.Init( this, &animator, ANIMCHANNEL_TORSO ); + legsAnim.Init( this, &animator, ANIMCHANNEL_LEGS ); +} + +/* +===================== +idActor::CheckBlink +===================== +*/ +void idActor::CheckBlink( void ) { + // check if it's time to blink + if ( !blink_anim || ( health <= 0 ) || !allowEyeFocus || ( blink_time > gameLocal.time ) ) { + return; + } + + idEntity *headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->GetAnimator()->PlayAnim( ANIMCHANNEL_EYELIDS, blink_anim, gameLocal.time, 1 ); + } else { + animator.PlayAnim( ANIMCHANNEL_EYELIDS, blink_anim, gameLocal.time, 1 ); + } + + // set the next blink time + blink_time = gameLocal.time + blink_min + gameLocal.random.RandomInt( blink_max - blink_min ); +} + +/* +================ +idActor::GetPhysicsToVisualTransform +================ +*/ +bool idActor::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { + if ( af.IsActive() ) { + af.GetPhysicsToVisualTransform( origin, axis ); + return true; + } + origin = modelOffset; + axis = viewAxis; + return true; +} + +/* +================ +idActor::GetPhysicsToSoundTransform +================ +*/ +bool idActor::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { + if ( soundJoint != INVALID_JOINT ) { + animator.GetJointTransform( soundJoint, gameLocal.time, origin, axis ); + origin += modelOffset; + axis = viewAxis; + } else { + origin = GetPhysics()->GetGravityNormal() * -eyeOffset.z; + axis.Identity(); + } + return true; +} + +/*********************************************************************** + + script state management + +***********************************************************************/ + +/* +================ +idActor::ShutdownThreads +================ +*/ +void idActor::ShutdownThreads( void ) { + headAnim.Shutdown(); + torsoAnim.Shutdown(); + legsAnim.Shutdown(); + + if ( scriptThread ) { + scriptThread->EndThread(); + scriptThread->PostEventMS( &EV_Remove, 0 ); + delete scriptThread; + scriptThread = NULL; + } +} + +/* +================ +idActor::ShouldConstructScriptObjectAtSpawn + +Called during idEntity::Spawn to see if it should construct the script object or not. +Overridden by subclasses that need to spawn the script object themselves. +================ +*/ +bool idActor::ShouldConstructScriptObjectAtSpawn( void ) const { + return false; +} + +/* +================ +idActor::ConstructScriptObject + +Called during idEntity::Spawn. Calls the constructor on the script object. +Can be overridden by subclasses when a thread doesn't need to be allocated. +================ +*/ +idThread *idActor::ConstructScriptObject( void ) { + const function_t *constructor; + + // make sure we have a scriptObject + if ( !scriptObject.HasObject() ) { + gameLocal.Error( "No scriptobject set on '%s'. Check the '%s' entityDef.", name.c_str(), GetEntityDefName() ); + } + + if ( !scriptThread ) { + // create script thread + scriptThread = new idThread(); + scriptThread->ManualDelete(); + scriptThread->ManualControl(); + scriptThread->SetThreadName( name.c_str() ); + } else { + scriptThread->EndThread(); + } + + // call script object's constructor + constructor = scriptObject.GetConstructor(); + if ( !constructor ) { + gameLocal.Error( "Missing constructor on '%s' for entity '%s'", scriptObject.GetTypeName(), name.c_str() ); + } + + // init the script object's data + scriptObject.ClearObject(); + + // just set the current function on the script. we'll execute in the subclasses. + scriptThread->CallFunction( this, constructor, true ); + + return scriptThread; +} + +/* +===================== +idActor::GetScriptFunction +===================== +*/ +const function_t *idActor::GetScriptFunction( const char *funcname ) { + const function_t *func; + + func = scriptObject.GetFunction( funcname ); + if ( !func ) { + scriptThread->Error( "Unknown function '%s' in '%s'", funcname, scriptObject.GetTypeName() ); + } + + return func; +} + +/* +===================== +idActor::SetState +===================== +*/ +void idActor::SetState( const function_t *newState ) { + if ( !newState ) { + gameLocal.Error( "idActor::SetState: Null state" ); + } + + if ( ai_debugScript.GetInteger() == entityNumber ) { + gameLocal.Printf( "%d: %s: State: %s\n", gameLocal.time, name.c_str(), newState->Name() ); + } + + state = newState; + idealState = state; + scriptThread->CallFunction( this, state, true ); +} + +/* +===================== +idActor::SetState +===================== +*/ +void idActor::SetState( const char *statename ) { + const function_t *newState; + + newState = GetScriptFunction( statename ); + SetState( newState ); +} + +/* +===================== +idActor::UpdateScript +===================== +*/ +void idActor::UpdateScript( void ) { + int i; + + if ( ai_debugScript.GetInteger() == entityNumber ) { + scriptThread->EnableDebugInfo(); + } else { + scriptThread->DisableDebugInfo(); + } + + // a series of state changes can happen in a single frame. + // this loop limits them in case we've entered an infinite loop. + for( i = 0; i < 20; i++ ) { + if ( idealState != state ) { + SetState( idealState ); + } + + // don't call script until it's done waiting + if ( scriptThread->IsWaiting() ) { + break; + } + + scriptThread->Execute(); + if ( idealState == state ) { + break; + } + } + + if ( i == 20 ) { + scriptThread->Warning( "idActor::UpdateScript: exited loop to prevent lockup" ); + } +} + +/*********************************************************************** + + vision + +***********************************************************************/ + +/* +===================== +idActor::setFov +===================== +*/ +void idActor::SetFOV( float fovHoriz, float fovVert ) +{ + m_fovDotHoriz = (float) cos( DEG2RAD( fovHoriz * 0.5f ) ); + + // if fovVert not specified (default val of -1), make same as horizontal + if( fovVert == -1 ) + m_fovDotVert = m_fovDotHoriz; + else + m_fovDotVert = (float) cos( DEG2RAD( fovVert * 0.5f) ); +} + +/* +===================== +idActor::SetEyeHeight +===================== +*/ +void idActor::SetEyeHeight( float height ) { + eyeOffset.z = height; +} + +/* +===================== +idActor::EyeHeight +===================== +*/ +float idActor::EyeHeight( void ) const { + return eyeOffset.z; +} + +/* +===================== +idActor::EyeOffset +===================== +*/ +idVec3 idActor::EyeOffset( void ) const { + return GetPhysics()->GetGravityNormal() * -eyeOffset.z; +} + +/* +===================== +idActor::GetEyePosition +===================== +*/ +idVec3 idActor::GetEyePosition( void ) const { + return GetPhysics()->GetOrigin() + ( GetPhysics()->GetGravityNormal() * -eyeOffset.z ); +} + +/* +===================== +idActor::GetViewPos +===================== +*/ +void idActor::GetViewPos( idVec3 &origin, idMat3 &axis ) const { + origin = GetEyePosition(); + axis = viewAxis; +} + +/* +===================== +idActor::CheckFOV +===================== +*/ +bool idActor::CheckFOV( const idVec3 &pos ) const +{ + //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("idActor::CheckFOV was called\r"); + + if ( m_fovDotHoriz == 1.0f ) { + return true; + } + + float dot; + idVec3 delta; + + delta = pos - GetEyePosition(); + + // get our gravity normal + const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); + + // infinite vertical vision, so project it onto our orientation plane + delta -= gravityDir * ( gravityDir * delta ); + + delta.Normalize(); + dot = viewAxis[ 0 ] * delta; + + return ( dot >= m_fovDotHoriz ); +} + +/* +===================== +idActor::CanSee +===================== +*/ +bool idActor::CanSee( idEntity *ent, bool useFov ) const +{ + // TDM: We need to be able to see lights that are off and hence hidden + /*if ( ent->IsHidden() ) + { + return false; + }*/ + + // The entity's origin + + // grayman #2861 - in the case of doors, use the 'closed origin' and not the 'origin' + + idVec3 origin; + if ( ent->IsType(CBinaryFrobMover::Type) ) + { + CBinaryFrobMover* door = static_cast(ent); + origin = door->GetClosedOrigin(); + } + else + { + origin = ent->GetPhysics()->GetOrigin(); + } + + const idVec3& entityOrigin = origin; + + // Check the field of view if specified + if (useFov && !CheckFOV(entityOrigin)) + { + // FOV check failed + return false; + } + + // This will hold the results of the traces + trace_t result; + + // eye position of the AI + idVec3 eye(GetEyePosition()); + + // angua: If the target entity is an idActor, + // use its eyeposition, the origin and the shoulders + if (ent->IsType(idActor::Type)) + { + idActor* actor = static_cast(ent); + idVec3 entityEyePos = actor->GetEyePosition(); + + if (!gameLocal.clip.TracePoint(result, eye, entityEyePos, MASK_OPAQUE, this) || + gameLocal.GetTraceEntity(result) == actor) + { + // Eye to eye trace succeeded + // gameRenderWorld->DebugArrow(colorGreen,eye, entityEyePos, 1, 32); + return true; + } + else if (!gameLocal.clip.TracePoint(result, eye, entityOrigin, MASK_OPAQUE, this) || + gameLocal.GetTraceEntity(result) == actor) + { + // Eye to origin trace succeeded + // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin, 1, 32); + return true; + } + else + { + idVec3 origin; + idMat3 viewaxis; + actor->GetViewPos(origin, viewaxis); + + const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); + idVec3 dir = (viewaxis[0] - gravityDir * ( gravityDir * viewaxis[0] )).Cross(gravityDir); + + float dist = 8; + + if (!gameLocal.clip.TracePoint(result, eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, MASK_OPAQUE, this) + || gameLocal.GetTraceEntity(result) == actor + || !gameLocal.clip.TracePoint(result, eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, MASK_OPAQUE, this) + || gameLocal.GetTraceEntity(result) == actor) + { + // Eye to shoulders traces succeeded + // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, 1, 32); + // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f - dir * dist, 1, 32); + return true; + } + } + } + // otherwise just use the origin (for general entities). + // Perform a trace from the eye position to the target entity + // TracePoint will return FALSE, when the trace.result is >= 1 + else + { + if (!gameLocal.clip.TracePoint(result, eye, entityOrigin, MASK_OPAQUE, this) || + gameLocal.GetTraceEntity(result) == ent) + { + // Trace succeeded or hit the target entity itself + return true; + } + + // grayman #2603 - We can't see the entity itself. If we're trying to see a light source, + // however, it might be embedded in a candle and/or a candle holder. + // So we have to look up the chain of bindmasters, and if we can see any of them, we'll take it + // that we can see the light source itself. + + if (ent->IsType(idLight::Type)) + { + idEntity* bindMaster = ent->GetBindMaster(); + while (bindMaster != NULL) // exit when bindMaster == NULL or we can see one of them + { + const idVec3& bindMasterOrigin = bindMaster->GetPhysics()->GetOrigin(); + + if (!gameLocal.clip.TracePoint(result, eye, bindMasterOrigin, MASK_OPAQUE, this) || + gameLocal.GetTraceEntity(result) == bindMaster) + { + // Trace succeeded or hit the target entity itself + return true; + } + bindMaster = bindMaster->GetBindMaster(); // go up the hierarchy + } + } + else if ( ent->IsType(CAbsenceMarker::Type) ) // grayman #2860 + { + // We're trying to see an absence marker and can't. Check for the case where the missing item + // was replaced by another item. For example, a lootable painting replaced by an empty frame. + // If a replacement item is present, is that what the trace hit? If so, the trace was successful. + + CAbsenceMarker* marker = static_cast(ent); + const idDict& refSpawnargs = marker->GetRefSpawnargs(); + idStr replacedByClass = refSpawnargs.GetString("replace"); + if ( !replacedByClass.IsEmpty() ) + { + idEntity* entHit = gameLocal.GetTraceEntity(result); // the trace hit this + if ( entHit != NULL ) + { + if ( idStr::Icmp( entHit->spawnArgs.GetString("classname"),replacedByClass ) == 0 ) + { + return true; // we hit the replacement item, which means a successful trace + } + } + } + } + } + + return false; +} + +/* +===================== +idActor::PointVisible +===================== +*/ +bool idActor::PointVisible( const idVec3 &point ) const { + trace_t results; + idVec3 start, end; + + start = GetEyePosition(); + end = point; + end[2] += 1.0f; + + gameLocal.clip.TracePoint( results, start, end, MASK_OPAQUE, this ); + return ( results.fraction >= 1.0f ); +} + +/* +===================== +idActor::GetAIAimTargets + +Returns positions for the AI to aim at. +===================== +*/ +void idActor::GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ) { + headPos = lastSightPos + EyeOffset(); + chestPos = ( headPos + lastSightPos + GetPhysics()->GetBounds().GetCenter() ) * 0.5f; +} + +/* +===================== +idActor::GetRenderView +===================== +*/ +renderView_t *idActor::GetRenderView() { + renderView_t *rv = idEntity::GetRenderView(); + rv->viewaxis = viewAxis; + rv->vieworg = GetEyePosition(); + return rv; +} + +/*********************************************************************** + + Model/Ragdoll + +***********************************************************************/ + +/* +================ +idActor::SetCombatModel +================ +*/ +void idActor::SetCombatModel( void ) { + idAFAttachment *headEnt; + + if ( !use_combat_bbox ) { + if ( combatModel ) { + combatModel->Unlink(); + combatModel->LoadModel( modelDefHandle ); + } else { + combatModel = new idClipModel( modelDefHandle ); + } + + headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->SetCombatModel(); + } + } +} + +/* +================ +idActor::GetCombatModel +================ +*/ +idClipModel *idActor::GetCombatModel( void ) const { + return combatModel; +} + +/* +================ +idActor::LinkCombat +================ +*/ +void idActor::LinkCombat( void ) { + idAFAttachment *headEnt; + + if ( fl.hidden || use_combat_bbox ) { + return; + } + + if ( combatModel ) { + combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); + } + headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->LinkCombat(); + } +} + +/* +================ +idActor::UnlinkCombat +================ +*/ +void idActor::UnlinkCombat( void ) { + idAFAttachment *headEnt; + + if ( combatModel != NULL ) { + combatModel->Unlink(); + } + headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->UnlinkCombat(); + } +} + +/* +================ +idActor::StartRagdoll +================ +*/ +bool idActor::StartRagdoll( void ) { + float slomoStart, slomoEnd; + float jointFrictionDent, jointFrictionDentStart, jointFrictionDentEnd; + float contactFrictionDent, contactFrictionDentStart, contactFrictionDentEnd; + + // if no AF loaded + if ( !af.IsLoaded() ) { + return false; + } + + // if the AF is already active + if ( af.IsActive() ) { + return true; + } + + // disable the monster bounding box + if (spawnArgs.GetBool("nonsolid_on_ragdoll", "1")) + { + GetPhysics()->DisableClip(); + } + + // ishtvan: Establish AF constraints for any AF bodies of bound entities + UpdateAddedEntConstraints(); + + // start using the AF + af.StartFromCurrentPose( spawnArgs.GetInt( "velocityTime", "0" ) ); + + slomoStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_slomoStart", "-1.6" ); + slomoEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_slomoEnd", "0.8" ); + + // do the first part of the death in slow motion + af.GetPhysics()->SetTimeScaleRamp( slomoStart, slomoEnd ); + + jointFrictionDent = spawnArgs.GetFloat( "ragdoll_jointFrictionDent", "0.1" ); + jointFrictionDentStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_jointFrictionStart", "0.2" ); + jointFrictionDentEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_jointFrictionEnd", "1.2" ); + + // set joint friction dent + af.GetPhysics()->SetJointFrictionDent( jointFrictionDent, jointFrictionDentStart, jointFrictionDentEnd ); + + contactFrictionDent = spawnArgs.GetFloat( "ragdoll_contactFrictionDent", "0.1" ); + contactFrictionDentStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_contactFrictionStart", "1.0" ); + contactFrictionDentEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_contactFrictionEnd", "2.0" ); + + // set contact friction dent + af.GetPhysics()->SetContactFrictionDent( contactFrictionDent, contactFrictionDentStart, contactFrictionDentEnd ); + + // drop any items the actor is holding + idMoveableItem::DropItems( this, "death", NULL ); + + // drop any articulated figures the actor is holding + idAFEntity_Base::DropAFs( this, "death", NULL ); + + RemoveAttachments(); + + return true; +} + +/* +================ +idActor::StopRagdoll +================ +*/ +void idActor::StopRagdoll( void ) { + if ( af.IsActive() ) { + af.Stop(); + } +} + +/* +================ +idActor::UpdateAnimationControllers +================ +*/ +bool idActor::UpdateAnimationControllers( void ) { + + if ( af.IsActive() ) { + return idAFEntity_Base::UpdateAnimationControllers(); + } else { + animator.ClearAFPose(); + } + + if ( walkIK.IsInitialized() ) { + walkIK.Evaluate(); + return true; + } + + return false; +} + +/* +================ +idActor::RemoveAttachments +================ +*/ +void idActor::RemoveAttachments( void ) +{ + int i; + idEntity *ent; + + // remove any attached entities + for( i = 0; i < m_Attachments.Num(); i++ ) { + ent = m_Attachments[ i ].ent.GetEntity(); + if ( ent && ent->spawnArgs.GetBool( "remove" ) ) { + ent->PostEventMS( &EV_SafeRemove, 0 ); + } + } +} + +/* +================ +idActor::Attach +================ +*/ +void idActor::Attach( idEntity *ent, const char *PosName, const char *AttName ) +{ + idAnimatedEntity::Attach( ent, PosName, AttName ); + + // If the ent we're attaching is an AFAttachment, call SetBody to set up damage propagation, physics propagation, etc. + // NOTE: We read ent->GetBindJoint here, assuming the bind went okay. + if( ent->IsType(idAFAttachment::Type) ) + { + // TODO: Is this line correct? Won't know until we test. + idStr modelName = ent->spawnArgs.GetString("model",""); + static_cast(ent)->SetBody( this, modelName.c_str(), ent->GetBindJoint() ); + } + + // check various spawnargs for special behaviors on attaching (not frobable, contents corpse, etc) + if( ent->spawnArgs.GetBool("on_attach_contents_corpse") ) + { + // clear solid contents, set corpse contents + int oldContents = ent->GetPhysics()->GetContents(); + ent->GetPhysics()->SetContents( (oldContents & ~CONTENTS_SOLID) | CONTENTS_CORPSE ); + } + if( ent->spawnArgs.GetBool("on_attach_nonsolid") ) + { + // clear solid and corpse contents + int oldContents = ent->GetPhysics()->GetContents(); + ent->GetPhysics()->SetContents( (oldContents & ~CONTENTS_SOLID) & ~CONTENTS_CORPSE ); + } + if( ent->spawnArgs.GetBool("on_attach_not_frobable") ) + ent->SetFrobable(false); + + + if( ent->IsType(CMeleeWeapon::Type) ) + { + static_cast(ent)->AttachedToActor( this ); + } +} + +/* +================ +idActor::BindNotify +================ +*/ +void idActor::BindNotify( idEntity *ent ) +{ + idAFEntity_Base::BindNotify(ent); + + // Override our animations based on the bound entity's replace_anim_* spawnargs + LoadReplacementAnims(ent->spawnArgs); +} + +/* +================ +idActor::UnbindNotify +================ +*/ +void idActor::UnbindNotify( idEntity *ent ) +{ + idAFEntity_Base::UnbindNotify(ent); + + // Remove animation overrides + const idKeyValue *KeyVal = ent->spawnArgs.MatchPrefix( "replace_anim_", NULL ); + while ( KeyVal ) + { + idStr key = KeyVal->GetKey(); + key.StripLeadingOnce("replace_anim_"); + + if (strcmp(m_replacementAnims.GetString( key ), KeyVal->GetValue().c_str()) == 0 ) + { + // This animation override is present, so remove it + //gameLocal.Warning( "idActor: Removing replacement animation %s", KeyVal->GetValue().c_str() ); + m_replacementAnims.Delete( key ); + } + + KeyVal = ent->spawnArgs.MatchPrefix( "replace_anim_", KeyVal ); + } + + // angua: remove from attachments + for (int i = 0; i < m_Attachments.Num(); i++) + { + idEntity* attachment = m_Attachments[i].ent.GetEntity(); + + if (attachment != NULL && attachment->name == ent->name) + { + m_Attachments[i].ent = NULL; + } + } +} + +/* +================ +idActor::Teleport +================ +*/ +void idActor::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { + + GetPhysics()->SetLinearVelocity( vec3_origin ); + if (destination == NULL) + { + GetPhysics()->SetOrigin( origin + idVec3( 0, 0, CM_CLIP_EPSILON ) ); + viewAxis = angles.ToMat3(); + } + else + { + GetPhysics()->SetOrigin( destination->GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); + viewAxis = destination->GetPhysics()->GetAxis(); + } + + UpdateVisuals(); + + if ( !IsHidden() ) { + // kill anything at the new position + gameLocal.KillBox( this ); + } +} + +/* +================ +idActor::GetDeltaViewAngles +================ +*/ +const idAngles &idActor::GetDeltaViewAngles( void ) const { + return deltaViewAngles; +} + +/* +================ +idActor::SetDeltaViewAngles +================ +*/ +void idActor::SetDeltaViewAngles( const idAngles &delta ) { + deltaViewAngles = delta; +} + +/* +================ +idActor::HasEnemies +================ +*/ +bool idActor::HasEnemies( void ) const { + idActor *ent; + + for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + if ( !ent->fl.hidden ) { + return true; + } + } + + return false; +} + +/* +================ +idActor::ClosestEnemyToPoint +================ +*/ +idActor *idActor::ClosestEnemyToPoint( const idVec3 &pos ) { + idActor *ent; + idActor *bestEnt; + float bestDistSquared; + float distSquared; + idVec3 delta; + + bestDistSquared = idMath::INFINITY; + bestEnt = NULL; + for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + if ( ent->fl.hidden ) { + continue; + } + delta = ent->GetPhysics()->GetOrigin() - pos; + distSquared = delta.LengthSqr(); + if ( distSquared < bestDistSquared ) { + bestEnt = ent; + bestDistSquared = distSquared; + } + } + + return bestEnt; +} + +/* +================ +idActor::EnemyWithMostHealth +================ +*/ +idActor *idActor::EnemyWithMostHealth() { + idActor *ent; + idActor *bestEnt; + + int most = -9999; + bestEnt = NULL; + for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + if ( !ent->fl.hidden && ( ent->health > most ) ) { + bestEnt = ent; + most = ent->health; + } + } + return bestEnt; +} + +/* +================ +idActor::ClosestAttackingEnemy +================ +*/ +idActor *idActor::ClosestAttackingEnemy( bool bUseFOV ) +{ + idActor *ent(NULL); + idActor *bestEnt(NULL); + float bestDistSquared(idMath::INFINITY); + float distSquared(0.0f); + idVec3 delta; + + for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) + { + if ( ent->fl.hidden ) + continue; + + CMeleeStatus *pStatus = &ent->m_MeleeStatus; + // TODO: Differentiate between phases of the action state, holding attack, etc? + if ( !(pStatus->m_ActionState == MELEEACTION_ATTACK) ) + continue; + + idVec3 entOrigin = ent->GetPhysics()->GetOrigin(); + delta = entOrigin - GetPhysics()->GetOrigin(); + distSquared = delta.LengthSqr(); + + // check FOV, using idActor version which only checks horizontal angle + if( bUseFOV && !idActor::CheckFOV( entOrigin) ) + { + continue; + } + + if ( distSquared < bestDistSquared ) + { + bestEnt = ent; + bestDistSquared = distSquared; + } + } + + return bestEnt; +} + +/* +================ +idActor::GetBestParry +================ +*/ +EMeleeType idActor::GetBestParry( void ) +{ + idActor *AttEnemy; + EMeleeType ParryType; + + if( m_MeleeStatus.m_bCanParryAll ) + ParryType = MELEETYPE_BLOCKALL; + else if( (AttEnemy = ClosestAttackingEnemy( true )) != NULL + && AttEnemy->m_MeleeStatus.m_ActionType != MELEETYPE_UNBLOCKABLE ) + { + ParryType = AttEnemy->m_MeleeStatus.m_ActionType; + } + else + ParryType = MELEETYPE_RL; + + return ParryType; +} + +/* +================ +idActor::OnLadder +================ +*/ +bool idActor::OnLadder( void ) const { + return false; +} + +CMultiStateMover* idActor::OnElevator(bool mustBeMoving) const +{ + return NULL; +} + +/* +============== +idActor::GetAASLocation +============== +*/ +void idActor::GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const { + idVec3 size; + idBounds bounds; + + GetFloorPos( 64.0f, pos ); + if ( !aas ) { + areaNum = 0; + return; + } + + size = aas->GetSettings()->boundingBoxes[0][1]; + bounds[0] = -size; + size.z = 32.0f; + bounds[1] = size; + + areaNum = aas->PointReachableAreaNum( pos, bounds, AREA_REACHABLE_WALK ); + if ( areaNum ) { + aas->PushPointIntoAreaNum( areaNum, pos ); + } +} + +/*********************************************************************** + + animation state + +***********************************************************************/ + +/* +===================== +idActor::SetAnimState +===================== +*/ +void idActor::SetAnimState( int channel, const char *statename, int blendFrames ) { + const function_t *func; + + // greebo: Try to lookup the script function of this animstate + func = scriptObject.GetFunction( statename ); + if ( !func ) { +// assert( 0 ); // greebo: don't just crash, a missing script function can happen... + gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); + } + + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.SetState( statename, blendFrames ); + allowEyeFocus = true; + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.SetState( statename, blendFrames ); + legsAnim.Enable( blendFrames ); + allowPain = true; + allowEyeFocus = true; + break; + + case ANIMCHANNEL_LEGS : + legsAnim.SetState( statename, blendFrames ); + torsoAnim.Enable( blendFrames ); + allowPain = true; + allowEyeFocus = true; + break; + + default: + gameLocal.Error( "idActor::SetAnimState: Unknown anim group" ); + break; + } +} + +/* +===================== +idActor::GetAnimState +===================== +*/ +const char *idActor::GetAnimState( int channel ) const { + switch( channel ) { + case ANIMCHANNEL_HEAD : + return headAnim.state; + break; + + case ANIMCHANNEL_TORSO : + return torsoAnim.state; + break; + + case ANIMCHANNEL_LEGS : + return legsAnim.state; + break; + + default: + gameLocal.Error( "idActor::GetAnimState: Unknown anim group" ); + return NULL; + break; + } +} + +/* +===================== +idActor::InAnimState +===================== +*/ +bool idActor::InAnimState( int channel, const char *statename ) const { + switch( channel ) { + case ANIMCHANNEL_HEAD : + if ( headAnim.state == statename ) { + return true; + } + break; + + case ANIMCHANNEL_TORSO : + if ( torsoAnim.state == statename ) { + return true; + } + break; + + case ANIMCHANNEL_LEGS : + if ( legsAnim.state == statename ) { + return true; + } + break; + + default: + gameLocal.Error( "idActor::InAnimState: Unknown anim group" ); + break; + } + + return false; +} + +/* +===================== +idActor::WaitState +===================== +*/ +const char *idActor::WaitState( void ) const { + if ( waitState.Length() ) { + return waitState; + } else { + return NULL; + } +} + + +const char *idActor::WaitState( int channel ) const +{ + switch( channel ) + { + case ANIMCHANNEL_HEAD : + return headAnim.WaitState(); + break; + + case ANIMCHANNEL_TORSO : + return torsoAnim.WaitState(); + break; + + case ANIMCHANNEL_LEGS : + return legsAnim.WaitState(); + break; + + default: + gameLocal.Error( "idActor::WaitState: Unknown anim group" ); + break; + } + + return NULL; +} + + + +/* +===================== +idActor::SetWaitState +===================== +*/ +void idActor::SetWaitState( const char *_waitstate ) { + waitState = _waitstate; +} + +void idActor::SetWaitState(int channel, const char *_waitstate) +{ + switch( channel ) + { + case ANIMCHANNEL_HEAD : + headAnim.SetWaitState(_waitstate); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.SetWaitState(_waitstate); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.SetWaitState(_waitstate); + break; + + default: + gameLocal.Error( "idActor::SetWaitState: Unknown anim group" ); + break; + } + +} + +/* +===================== +idActor::UpdateAnimState +===================== +*/ +void idActor::UpdateAnimState( void ) { + headAnim.UpdateState(); + torsoAnim.UpdateState(); + legsAnim.UpdateState(); +} + +/* +===================== +idActor::GetAnim +===================== +*/ +int idActor::GetAnim( int channel, const char *animname ) { + int anim; + const char *temp; + idAnimator *animatorPtr; + + if ( channel == ANIMCHANNEL_HEAD ) { + if ( !head.GetEntity() ) { + return 0; + } + animatorPtr = head.GetEntity()->GetAnimator(); + } else { + animatorPtr = &animator; + } + + if ( animPrefix.Length() ) + { + temp = va( "%s_%s", animPrefix.c_str(), animname ); + + const char* replacement = LookupReplacementAnim( temp ); + + if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer() && idStr::Cmp(replacement, temp) != 0) + { + gameLocal.Printf("Frame: %d - replacing %s with %s\n", gameLocal.framenum, animname, replacement); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - replacing %s with %s\r", gameLocal.framenum, animname, replacement); + } + + anim = animatorPtr->GetAnim( replacement ); + if (!anim) anim = animatorPtr->GetAnim( temp ); + if (anim) { + return anim; + } + } + + const char* replacement = LookupReplacementAnim( animname ); + + if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer() && idStr::Cmp(replacement, animname) != 0) + { + gameLocal.Printf("Frame: %d - replacing %s with %s\n", gameLocal.framenum, animname, replacement); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - replacing %s with %s\r", gameLocal.framenum, animname, replacement); + } + + anim = animatorPtr->GetAnim( replacement ); + if (!anim) anim = animatorPtr->GetAnim( animname ); + + return anim; +} + +idAnimator* idActor::GetAnimatorForChannel(int channel) +{ + switch (channel) + { + case ANIMCHANNEL_HEAD : + if (head.GetEntity() == NULL) + { + return headAnim.GetAnimator(); + } + return head.GetEntity()->GetAnimator(); + break; + + case ANIMCHANNEL_TORSO : + return torsoAnim.GetAnimator(); + break; + + case ANIMCHANNEL_LEGS : + return legsAnim.GetAnimator(); + break; + + default: + gameLocal.Error("GetAnimatorForChannel: Unknown anim group"); + break; + }; + + return NULL; +} + +/* +===================== +idActor::LookupReplacementAnim +(TDM) +===================== +*/ +const char* idActor::LookupReplacementAnim( const char *animname ) +{ + // Recursively lookup the animation to find its replacement animation + const char* replacement = animname; + int tries = 0; // Infinite loop prevention counter + + while ( m_replacementAnims.FindKey( replacement ) ) + { + replacement = m_replacementAnims.GetString( replacement ); + + // Avoid infinite loops + tries++; + if (tries > 500) + { + gameLocal.Warning("Infinite loop detected in replacements for animation '%s' applied to actor '%s'\n", + animname, this->name.c_str()); + break; + } + } + + return replacement; +} + +void idActor::LoadReplacementAnims(const idDict& spawnArgs) +{ + for (const idKeyValue* kv = spawnArgs.MatchPrefix("replace_anim_", NULL); + kv != NULL; kv = spawnArgs.MatchPrefix("replace_anim_", kv)) + { + idStr key = kv->GetKey(); + key.StripLeadingOnce("replace_anim_"); + + SetReplacementAnim(key, kv->GetValue()); + } +} + +void idActor::SetReplacementAnim(const idStr& animToReplace, const idStr& replacementAnim) +{ + m_replacementAnims.Set(animToReplace, replacementAnim); +} + +void idActor::RemoveReplacementAnim(const idStr& replacedAnim) +{ + m_replacementAnims.Delete(replacedAnim); +} + +void idActor::StopAnim(int channel, int frames) +{ + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.StopAnim( frames ); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.StopAnim( frames ); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.StopAnim( frames ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + +/* +=============== +idActor::SyncAnimChannels +=============== +*/ +void idActor::SyncAnimChannels( int channel, int syncToChannel, int blendFrames ) { + idAnimator *headAnimator; + idAFAttachment *headEnt; + int anim; + idAnimBlend *syncAnim; + int starttime; + int blendTime; + int cycle; + + blendTime = FRAME2MS( blendFrames ); + if ( channel == ANIMCHANNEL_HEAD ) { + headEnt = head.GetEntity(); + if ( headEnt ) { + headAnimator = headEnt->GetAnimator(); + syncAnim = animator.CurrentAnim( syncToChannel ); + if ( syncAnim ) { + anim = headAnimator->GetAnim( syncAnim->AnimFullName() ); + if ( !anim ) { + anim = headAnimator->GetAnim( syncAnim->AnimName() ); + } + if ( anim ) { + cycle = animator.CurrentAnim( syncToChannel )->GetCycleCount(); + starttime = animator.CurrentAnim( syncToChannel )->GetStartTime(); + headAnimator->PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, blendTime ); + headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); + headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->SetStartTime( starttime ); + } else { + headEnt->PlayIdleAnim( blendTime ); + } + } + } + } else if ( syncToChannel == ANIMCHANNEL_HEAD ) { + headEnt = head.GetEntity(); + if ( headEnt ) { + headAnimator = headEnt->GetAnimator(); + syncAnim = headAnimator->CurrentAnim( ANIMCHANNEL_ALL ); + if ( syncAnim ) { + anim = GetAnim( channel, syncAnim->AnimFullName() ); + if ( !anim ) { + anim = GetAnim( channel, syncAnim->AnimName() ); + } + if ( anim ) { + cycle = headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetCycleCount(); + starttime = headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime(); + animator.PlayAnim( channel, anim, gameLocal.time, blendTime ); + animator.CurrentAnim( channel )->SetCycleCount( cycle ); + animator.CurrentAnim( channel )->SetStartTime( starttime ); + } + } + } + } else { + animator.SyncAnimChannels( channel, syncToChannel, gameLocal.time, blendTime ); + } +} + +/*********************************************************************** + + Damage + +***********************************************************************/ + +/* +============ +idActor::Gib +============ +*/ +void idActor::Gib( const idVec3 &dir, const char *damageDefName ) { + // no gibbing in multiplayer - by self damage or by moving objects + if ( gameLocal.isMultiplayer ) { + return; + } + // only gib once + if ( gibbed ) { + return; + } + idAFEntity_Gibbable::Gib( dir, damageDefName ); + if ( head.GetEntity() ) { + head.GetEntity()->Hide(); + } + StopSound( SND_CHANNEL_VOICE, false ); +} + + +/* +============ +idActor::Damage + +this entity that is being damaged +inflictor entity that is causing the damage +attacker entity that caused the inflictor to damage targ + example: this=monster, inflictor=rocket, attacker=player + +dir direction of the attack for knockback in global space +point point at which the damage is being inflicted, used for headshots +damage amount of damage being inflicted + +collision trace info for the collision that caused the damage. Defaults to NULL. + +inflictor, attacker, dir, and point can be NULL for environmental effects + +Bleeding wounds and surface overlays are applied in the collision code that +calls Damage() +============ +*/ +void idActor::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision ) +{ + if (collision != NULL) + { + int bodID = BodyForClipModelId( collision->c.id ); + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Fun is trying to call getBody with bodyID %d\r", bodID ); + idAFBody* StruckBody = GetAFPhysics()->GetBody( bodID ); + + if( StruckBody != NULL ) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Struck body %s\r",StruckBody->GetName().c_str()); + idEntity* reroute = StruckBody->GetRerouteEnt(); + if (reroute != NULL) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Rerouting damage from the AF of entity %s to bound entity %s\r",name.c_str(), reroute->name.c_str()); + // TODO: Technically location is wrong here, it's a joint that's not on the reroute entity (not sure if it will matter) + reroute->Damage( inflictor, attacker, dir, damageDefName, damageScale, location, collision ); + return; + } + } + } + + if ( !fl.takedamage ) { + return; + } + + // grayman #2478 - why take more damage if you're already dead? + + if (health <= 0) + { + return; + } + + if ( !inflictor ) { + inflictor = gameLocal.world; + } + if ( !attacker ) { + attacker = gameLocal.world; + } + + // Try to find the damage entityDef + const idDict* damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) { + gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); + } + + // Get the damage amount + int damage = static_cast(damageDef->GetInt( "damage" ) * damageScale); + + damage = GetDamageForLocation( damage, location ); + + // apply stealth damage multiplier - only active for derived AI class + damage *= StealthDamageMult(); + + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Actor %s received damage %d at joint %d, corresponding to damage group %s\r", name.c_str(), damage, (int) location, GetDamageGroup(location) ); + + // inform the attacker that they hit someone + attacker->DamageFeedback( this, inflictor, damage ); + + // DarkMod: check for KO damage type and knockout AI if appropriate + bool bKO = damageDef->GetBool( "knockout" ); + bool bKOPowerBlow = damageDef->GetBool( "knockout_power" ); + + if( (bKO || bKOPowerBlow) && collision ) + { + if( TestKnockoutBlow( attacker, dir, collision, location, bKOPowerBlow ) ) + { + // For now, first KO blow does no health damage + damage = 0; + } + } + + if ( damage > 0 ) + { + // Apply the damage + health -= damage; + + if (lowHealthThreshold != -1 && health <= lowHealthThreshold) + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s's fell below health threshold %d, firing script %s\r", name.c_str(), lowHealthThreshold, lowHealthScript.c_str()); + + if (!lowHealthScript.IsEmpty()) + { + CallScriptFunctionArgs(lowHealthScript, true, 0, "e", this); + } + } + + if ( health <= 0 ) + { + if ( health < -999 ) + { + health = -999; + } + Killed( inflictor, attacker, damage, dir, location ); + if ( ( health < -20 ) && spawnArgs.GetBool( "gib" ) && damageDef->GetBool( "gib" ) ) + { + Gib( dir, damageDefName ); + } + } + else + { + Pain( inflictor, attacker, damage, dir, location, damageDef ); + + // FIX: if drowning, stop pain SFX and play drown SFX on voice channel + if ( damageDef->GetBool( "no_air" ) ) + { + StopSound( SND_CHANNEL_VOICE, false ); + SetSoundVolume(-10); // grayman #1488 - less volume underwater + StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); + } + } + } + // Ishtvan: Try commenting this out, it doesn't make sense to ignore nonzero "push" in the DmgDef just + // because the attack happens to hit armor and do no damage... + // Cleary Id was trying to fix something here, but I'm not sure what +/* + else + { + // Ishtvan: THIS IS WHAT'S CAUSING PLATE ARMOR HITS NOT TO MOVE AI... WHY DID ID DO THIS? + + // don't accumulate knockback + if ( af.IsLoaded() ) + { + // clear impacts + af.Rest(); + + // physics is turned off by calling af.Rest() + BecomeActive( TH_PHYSICS ); + } + } +*/ +} + +/* +===================== +idActor::ClearPain +===================== +*/ +void idActor::ClearPain( void ) { + pain_debounce_time = 0; +} + +/* +===================== +idActor::Pain +===================== +*/ +bool idActor::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ) { + if ( af.IsLoaded() && !IsKnockedOut() ) { + // clear impacts + af.Rest(); + + // physics is turned off by calling af.Rest() + BecomeActive( TH_PHYSICS ); + } + + if ( gameLocal.time < pain_debounce_time ) { + return false; + } + + // don't play pain sounds more than necessary + pain_debounce_time = gameLocal.time + pain_delay; + + if (damageDef != NULL && damageDef->FindKey("snd_damage") != NULL) + { + // The damage def defines a special damage sound, use that one + // Copy it into our own spawnargs for use with StartSound() routine + spawnArgs.Set("snd_damage_internal___", damageDef->GetString("snd_damage")); + + StartSound( "snd_damage_internal___", SND_CHANNEL_VOICE, 0, false, NULL ); + } + else + { + // Ordinary health-based pain sound + if ( health > 75 ) { + StartSound( "snd_pain_small", SND_CHANNEL_VOICE, 0, false, NULL ); + } else if ( health > 50 ) { + StartSound( "snd_pain_medium", SND_CHANNEL_VOICE, 0, false, NULL ); + } else if ( health > 25 ) { + StartSound( "snd_pain_large", SND_CHANNEL_VOICE, 0, false, NULL ); + } else { + StartSound( "snd_pain_huge", SND_CHANNEL_VOICE, 0, false, NULL ); + } + } + + if ( !allowPain || ( gameLocal.time < painTime ) ) { + // don't play a pain anim + return false; + } + + if ( pain_threshold && ( damage < pain_threshold ) ) { + return false; + } + + // set the pain anim + idStr damageGroup = GetDamageGroup( location ); + + painAnim = ""; + if ( animPrefix.Length() ) { + if ( damageGroup.Length() && ( damageGroup != "legs" ) ) { + sprintf( painAnim, "%s_pain_%s", animPrefix.c_str(), damageGroup.c_str() ); + if ( !animator.HasAnim( painAnim ) ) { + sprintf( painAnim, "pain_%s", damageGroup.c_str() ); + if ( !animator.HasAnim( painAnim ) ) { + painAnim = ""; + } + } + } + + if ( !painAnim.Length() ) { + sprintf( painAnim, "%s_pain", animPrefix.c_str() ); + if ( !animator.HasAnim( painAnim ) ) { + painAnim = ""; + } + } + } else if ( damageGroup.Length() && ( damageGroup != "legs" ) ) { + sprintf( painAnim, "pain_%s", damageGroup.c_str() ); + if ( !animator.HasAnim( painAnim ) ) { + sprintf( painAnim, "pain_%s", damageGroup.c_str() ); + if ( !animator.HasAnim( painAnim ) ) { + painAnim = ""; + } + } + } + + if ( !painAnim.Length() ) { + painAnim = "pain"; + } + + if ( g_debugDamage.GetBool() ) { + gameLocal.Printf( "Damage: joint: '%s', zone '%s', anim '%s'\n", animator.GetJointName( ( jointHandle_t )location ), + damageGroup.c_str(), painAnim.c_str() ); + } + + return true; +} + +void idActor::SetIsPushing(bool isPushing) +{ + // do nothing, is handled by the subclasses +} + +bool idActor::IsPushing() +{ + return false; +} + +/* +===================== +idActor::SpawnGibs +===================== +*/ +void idActor::SpawnGibs( const idVec3 &dir, const char *damageDefName ) { + idAFEntity_Gibbable::SpawnGibs( dir, damageDefName ); + RemoveAttachments(); +} + +/* +===================== +idActor::SetupDamageGroups + +FIXME: only store group names once and store an index for each joint +===================== +*/ +void idActor::SetupDamageGroups( void ) { + int i; + const idKeyValue *arg; + idStr groupname; + idList jointList; + int jointnum; + float scale; + + // create damage zones + damageGroups.SetNum( animator.NumJoints() ); + arg = spawnArgs.MatchPrefix( "damage_zone ", NULL ); + while ( arg ) { + groupname = arg->GetKey(); + groupname.Strip( "damage_zone " ); + animator.GetJointList( arg->GetValue(), jointList ); + for( i = 0; i < jointList.Num(); i++ ) { + jointnum = jointList[ i ]; + damageGroups[ jointnum ] = groupname; + } + jointList.Clear(); + arg = spawnArgs.MatchPrefix( "damage_zone ", arg ); + } + + // initilize the damage zones to normal damage + damageScale.SetNum( animator.NumJoints() ); + for( i = 0; i < damageScale.Num(); i++ ) { + damageScale[ i ] = 1.0f; + } + + // set the percentage on damage zones + arg = spawnArgs.MatchPrefix( "damage_scale ", NULL ); + while ( arg ) { + scale = atof( arg->GetValue() ); + groupname = arg->GetKey(); + groupname.Strip( "damage_scale " ); + for( i = 0; i < damageScale.Num(); i++ ) { + if ( damageGroups[ i ] == groupname ) { + damageScale[ i ] = scale; + } + } + arg = spawnArgs.MatchPrefix( "damage_scale ", arg ); + } +} + +/* +===================== +idActor::GetDamageForLocation +===================== +*/ +int idActor::GetDamageForLocation( int damage, int location ) { + if ( ( location < 0 ) || ( location >= damageScale.Num() ) ) { + return damage; + } + + return (int)ceil( damage * damageScale[ location ] ); +} + +/* +===================== +idActor::GetDamageGroup +===================== +*/ +const char *idActor::GetDamageGroup( int location ) { + if ( ( location < 0 ) || ( location >= damageGroups.Num() ) ) { + return ""; + } + + return damageGroups[ location ]; +} + +/* +===================== +idActor::PlayFootStepSound +===================== +*/ +void idActor::PlayFootStepSound( void ) +{ + // empty, override this in the subclasses +} + +void idActor::LinkScriptVariables() +{ + // Link the script variables to our script object + AI_DEAD.LinkTo(scriptObject, "AI_DEAD"); +} + +bool idActor::ReEvaluateArea(int areaNum) +{ + // Default implementation for actors: return positive + return true; +} + +void idActor::LoadVocalSet() +{ + // Try to look up the entityDef + idStr vocalSet = spawnArgs.GetString("def_vocal_set"); + + if (vocalSet.IsEmpty()) return; // nothing to do + + const idDeclEntityDef* def = gameLocal.FindEntityDef(vocalSet, false); + + if (def == NULL) + { + gameLocal.Warning("Could not find def_vocal_set %s!", vocalSet.c_str()); + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Could not find def_vocal_set %s!", vocalSet.c_str()); + return; + } + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copying vocal set %s to actor %s", vocalSet.c_str(), name.c_str()); + + int i = 0; + + // Copy all snd_* spawnargs over to this entity + for (const idKeyValue* kv = def->dict.MatchPrefix("snd_"); kv != NULL; kv = def->dict.MatchPrefix("snd_", kv), i++) + { + spawnArgs.Set(kv->GetKey(), kv->GetValue()); + } + + // Copy all sound prop "spr*" spawnargs over to this entity + for (const idKeyValue* kv = def->dict.MatchPrefix("spr"); kv != NULL; kv = def->dict.MatchPrefix("spr", kv), i++) + { + spawnArgs.Set(kv->GetKey(), kv->GetValue()); + } + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copied %d vocal set spawnargs to actor %s", i, name.c_str()); +} + +void idActor::LoadMeleeSet() +{ + idStr MeleeSet = spawnArgs.GetString("def_melee_set"); + if (MeleeSet.IsEmpty()) return; // nothing to do + + // tack on difficulty string + // if we do it this way, def will not be precached, but that's okay for just some numbers? + MeleeSet += va("_%s", cv_melee_difficulty.GetString()); + + const idDeclEntityDef* def = gameLocal.FindEntityDef(MeleeSet, false); + + if (def == NULL) + { + gameLocal.Warning("Could not find def_melee_set %s!", MeleeSet.c_str()); + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Could not find def_melee_set %s!", MeleeSet.c_str()); + return; + } + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copying melee set %s to actor %s", MeleeSet.c_str(), name.c_str()); + + // Copy ALL spawnargs from melee set over to this entity + spawnArgs.Copy( def->dict ); + + // re-cache the anim rates in case they changed + CacheAnimRates(); +} + +/*********************************************************************** + + Events + +***********************************************************************/ + +/* +===================== +idActor::Event_EnableEyeFocus +===================== +*/ +void idActor::Event_EnableEyeFocus( void ) { + allowEyeFocus = true; + blink_time = gameLocal.time + blink_min + gameLocal.random.RandomInt( blink_max - blink_min ); +} + +/* +===================== +idActor::Event_DisableEyeFocus +===================== +*/ +void idActor::Event_DisableEyeFocus( void ) { + allowEyeFocus = false; + + idEntity *headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->GetAnimator()->Clear( ANIMCHANNEL_EYELIDS, gameLocal.time, FRAME2MS( 2 ) ); + } else { + animator.Clear( ANIMCHANNEL_EYELIDS, gameLocal.time, FRAME2MS( 2 ) ); + } +} + +/* +=============== +idActor::Event_Footstep +=============== +*/ +void idActor::Event_Footstep( void ) { + PlayFootStepSound(); +} + +/* +===================== +idActor::Event_EnableWalkIK +===================== +*/ +void idActor::Event_EnableWalkIK( void ) { + walkIK.EnableAll(); +} + +/* +===================== +idActor::Event_DisableWalkIK +===================== +*/ +void idActor::Event_DisableWalkIK( void ) { + walkIK.DisableAll(); +} + +/* +===================== +idActor::Event_EnableLegIK +===================== +*/ +void idActor::Event_EnableLegIK( int num ) { + walkIK.EnableLeg( num ); +} + +/* +===================== +idActor::Event_DisableLegIK +===================== +*/ +void idActor::Event_DisableLegIK( int num ) { + walkIK.DisableLeg( num ); +} + +/* +===================== +idActor::Event_PreventPain +===================== +*/ +void idActor::Event_PreventPain( float duration ) { + painTime = gameLocal.time + SEC2MS( duration ); +} + +/* +=============== +idActor::Event_DisablePain +=============== +*/ +void idActor::Event_DisablePain( void ) { + allowPain = false; +} + +/* +=============== +idActor::Event_EnablePain +=============== +*/ +void idActor::Event_EnablePain( void ) { + allowPain = true; +} + +/* +===================== +idActor::Event_GetPainAnim +===================== +*/ +void idActor::Event_GetPainAnim( void ) { + if ( !painAnim.Length() ) { + idThread::ReturnString( "pain" ); + } else { + idThread::ReturnString( painAnim ); + } +} + +/* +===================== +idActor::Event_SetAnimPrefix +===================== +*/ +void idActor::Event_SetAnimPrefix( const char *prefix ) { + animPrefix = prefix; +} + +/* +=============== +idActor::Event_StopAnim +=============== +*/ +void idActor::Event_StopAnim( int channel, int frames ) { + StopAnim(channel, frames); +} + +/* +=============== +idActor::Event_PlayAnim +=============== +*/ +void idActor::Event_PlayAnim( int channel, const char *animname ) { + animFlags_t flags; + idEntity *headEnt; + int anim; + + if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer()) + { + gameLocal.Printf("Frame: %d - playing anim %s (%s)\n", gameLocal.framenum, animname, name.c_str()); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - playing anim %s (%s)\r", gameLocal.framenum, animname, name.c_str()); + } + + anim = GetAnim( channel, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { + gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); + } else { + //gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); + } +#endif + + idThread::ReturnInt( 0 ); + return; + } + + switch( channel ) { + case ANIMCHANNEL_HEAD : + headEnt = head.GetEntity(); + if ( headEnt ) { + headAnim.idleAnim = false; + headAnim.PlayAnim( anim ); + flags = headAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( torsoAnim.IsIdle() ) { + torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + if ( legsAnim.IsIdle() ) { + legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + } + } + } + } + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.idleAnim = false; + torsoAnim.PlayAnim( anim ); + flags = torsoAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( headAnim.IsIdle() ) { + headAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + if ( legsAnim.IsIdle() ) { + legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + } + break; + + case ANIMCHANNEL_LEGS : + legsAnim.idleAnim = false; + legsAnim.PlayAnim( anim ); + flags = legsAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( torsoAnim.IsIdle() ) { + torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + if ( headAnim.IsIdle() ) { + headAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + } + } + } + break; + + default : + gameLocal.Error( "Unknown anim group" ); + break; + } + idThread::ReturnInt( 1 ); +} + +/* +=============== +idActor::Event_PlayCycle +=============== +*/ +void idActor::Event_PlayCycle( int channel, const char *animname ) { + animFlags_t flags; + int anim; + + anim = GetAnim( channel, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { + gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); + } else { + gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); + } +#endif + + idThread::ReturnInt( false ); + return; + } + + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.idleAnim = false; + headAnim.CycleAnim( anim ); + flags = headAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( torsoAnim.IsIdle() && legsAnim.IsIdle() ) { + torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + } + } + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.idleAnim = false; + torsoAnim.CycleAnim( anim ); + flags = torsoAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( headAnim.IsIdle() ) { + headAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + if ( legsAnim.IsIdle() ) { + legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + } + break; + + case ANIMCHANNEL_LEGS : + legsAnim.idleAnim = false; + legsAnim.CycleAnim( anim ); + flags = legsAnim.GetAnimFlags(); + if ( !flags.prevent_idle_override ) { + if ( torsoAnim.IsIdle() ) { + torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + if ( headAnim.IsIdle() ) { + headAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + } + } + } + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } + + idThread::ReturnInt( true ); +} + +/* +=============== +idActor::Event_PauseAnim +=============== +*/ +void idActor::Event_PauseAnim( int channel, bool bPause ) +{ + animator.CurrentAnim( channel )->Pause( bPause ); +} + +/* +=============== +idActor::Event_AnimIsPaused +=============== +*/ +void idActor::Event_AnimIsPaused( int channel ) +{ + idThread::ReturnInt( animator.CurrentAnim( channel )->IsPaused() ); +} + +/* +=============== +idActor::Event_IdleAnim +=============== +*/ +void idActor::Event_IdleAnim( int channel, const char *animname ) { + int anim; + + anim = GetAnim( channel, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { + gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); + } else { + gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); + } +#endif + + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.BecomeIdle(); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.BecomeIdle(); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.BecomeIdle(); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } + + idThread::ReturnInt( false ); + return; + } + + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.BecomeIdle(); + if ( torsoAnim.GetAnimFlags().prevent_idle_override ) { + // don't sync to torso body if it doesn't override idle anims + headAnim.CycleAnim( anim ); + } else if ( torsoAnim.IsIdle() && legsAnim.IsIdle() ) { + // everything is idle, so play the anim on the head and copy it to the torso and legs + headAnim.CycleAnim( anim ); + torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); + } else if ( torsoAnim.IsIdle() ) { + // sync the head and torso to the legs + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, headAnim.animBlendFrames ); + torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, torsoAnim.animBlendFrames ); + } else { + // sync the head to the torso + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, headAnim.animBlendFrames ); + } + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.BecomeIdle(); + if ( legsAnim.GetAnimFlags().prevent_idle_override ) { + // don't sync to legs if legs anim doesn't override idle anims + torsoAnim.CycleAnim( anim ); + } else if ( legsAnim.IsIdle() ) { + // play the anim in both legs and torso + torsoAnim.CycleAnim( anim ); + legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } else { + // sync the anim to the legs + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, torsoAnim.animBlendFrames ); + } + + if ( headAnim.IsIdle() ) { + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + break; + + case ANIMCHANNEL_LEGS : + legsAnim.BecomeIdle(); + if ( torsoAnim.GetAnimFlags().prevent_idle_override ) { + // don't sync to torso if torso anim doesn't override idle anims + legsAnim.CycleAnim( anim ); + } else if ( torsoAnim.IsIdle() ) { + // play the anim in both legs and torso + legsAnim.CycleAnim( anim ); + torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + if ( headAnim.IsIdle() ) { + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + } + } else { + // sync the anim to the torso + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, legsAnim.animBlendFrames ); + } + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } + + idThread::ReturnInt( true ); +} + +/* +================ +idActor::Event_SetSyncedAnimWeight +================ +*/ +void idActor::Event_SetSyncedAnimWeight( int channel, int anim, float weight ) { + idEntity *headEnt; + + headEnt = head.GetEntity(); + switch( channel ) { + case ANIMCHANNEL_HEAD : + if ( headEnt ) { + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); + } else { + animator.CurrentAnim( ANIMCHANNEL_HEAD )->SetSyncedAnimWeight( anim, weight ); + } + if ( torsoAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); + if ( legsAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); + } + } + break; + + case ANIMCHANNEL_TORSO : + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); + if ( legsAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); + } + if ( headEnt && headAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); + } + break; + + case ANIMCHANNEL_LEGS : + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); + if ( torsoAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); + if ( headEnt && headAnim.IsIdle() ) { + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); + } + } + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } +} + +void idActor::Event_SyncAnimChannels(int fromChannel, int toChannel, float blendFrames) +{ + SyncAnimChannels(fromChannel, toChannel, static_cast(blendFrames)); +} + +/* +=============== +idActor::Event_OverrideAnim +=============== +*/ +void idActor::Event_OverrideAnim( int channel ) { + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.Disable(); + if ( !torsoAnim.IsIdle() ) { + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } else { + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + } + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.Disable(); + SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); + if ( headAnim.IsIdle() ) { + SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + } + break; + + case ANIMCHANNEL_LEGS : + legsAnim.Disable(); + SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + +/* +=============== +idActor::Event_EnableAnim +=============== +*/ +void idActor::Event_EnableAnim( int channel, int blendFrames ) { + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.Enable( blendFrames ); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.Enable( blendFrames ); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.Enable( blendFrames ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + + +/* +=============== +idActor::Event_DisableAnimchannel +=============== +*/ +void idActor::Event_DisableAnimchannel( int channel ) { + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.Disable(); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.Disable(); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.Disable(); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + +/* +=============== +idActor::Event_SetBlendFrames +=============== +*/ +void idActor::Event_SetBlendFrames( int channel, int blendFrames ) { + switch( channel ) { + case ANIMCHANNEL_HEAD : + headAnim.animBlendFrames = blendFrames; + headAnim.lastAnimBlendFrames = blendFrames; + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.animBlendFrames = blendFrames; + torsoAnim.lastAnimBlendFrames = blendFrames; + break; + + case ANIMCHANNEL_LEGS : + legsAnim.animBlendFrames = blendFrames; + legsAnim.lastAnimBlendFrames = blendFrames; + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + +/* +=============== +idActor::Event_GetBlendFrames +=============== +*/ +void idActor::Event_GetBlendFrames( int channel ) { + switch( channel ) { + case ANIMCHANNEL_HEAD : + idThread::ReturnInt( headAnim.animBlendFrames ); + break; + + case ANIMCHANNEL_TORSO : + idThread::ReturnInt( torsoAnim.animBlendFrames ); + break; + + case ANIMCHANNEL_LEGS : + idThread::ReturnInt( legsAnim.animBlendFrames ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + break; + } +} + +/* +=============== +idActor::Event_AnimState +=============== +*/ +void idActor::Event_AnimState( int channel, const char *statename, int blendFrames ) { + SetAnimState( channel, statename, blendFrames ); +} + +/* +=============== +idActor::Event_GetAnimState +=============== +*/ +void idActor::Event_GetAnimState( int channel ) { + const char *state; + + state = GetAnimState( channel ); + idThread::ReturnString( state ); +} + +/* +=============== +idActor::Event_InAnimState +=============== +*/ +void idActor::Event_InAnimState( int channel, const char *statename ) { + bool instate; + + instate = InAnimState( channel, statename ); + idThread::ReturnInt( instate ); +} + +/* +=============== +idActor::Event_FinishAction +=============== +*/ +void idActor::Event_FinishAction( const char *actionname ) { + if ( waitState == actionname ) { + SetWaitState( "" ); + } +} + +void idActor::Event_FinishChannelAction( int channel, const char *actionname) +{ + switch( channel ) + { + case ANIMCHANNEL_HEAD : + headAnim.FinishAction( actionname); + break; + + case ANIMCHANNEL_TORSO : + torsoAnim.FinishAction( actionname); + break; + + case ANIMCHANNEL_LEGS : + legsAnim.FinishAction( actionname ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } +} + +bool idActor::AnimDone( int channel, int blendFrames ) const +{ + bool result = false; + + switch( channel ) { + case ANIMCHANNEL_HEAD : + result = headAnim.AnimDone( blendFrames ); + break; + + case ANIMCHANNEL_TORSO : + result = torsoAnim.AnimDone( blendFrames ); + break; + + case ANIMCHANNEL_LEGS : + result = legsAnim.AnimDone( blendFrames ); + break; + + default: + gameLocal.Error( "Unknown anim group" ); + } + + return result; +} + +/* +=============== +idActor::Event_AnimDone +=============== +*/ +void idActor::Event_AnimDone( int channel, int blendFrames ) { + idThread::ReturnInt(AnimDone(channel, blendFrames)); +} + +/* +================ +idActor::Event_HasAnim +================ +*/ +void idActor::Event_HasAnim( int channel, const char *animname ) { + if ( GetAnim( channel, animname ) ) { + idThread::ReturnFloat( 1.0f ); + } else { + idThread::ReturnFloat( 0.0f ); + } +} + +/* +================ +idActor::Event_CheckAnim +================ +*/ +void idActor::Event_CheckAnim( int channel, const char *animname ) { + if ( !GetAnim( channel, animname ) ) { + if ( animPrefix.Length() ) { + gameLocal.Error( "Can't find anim '%s_%s' for '%s'", animPrefix.c_str(), animname, name.c_str() ); + } else { + gameLocal.Error( "Can't find anim '%s' for '%s'", animname, name.c_str() ); + } + } +} + +/* +================ +idActor::Event_ChooseAnim +================ +*/ +void idActor::Event_ChooseAnim( int channel, const char *animname ) { + int anim; + + anim = GetAnim( channel, animname ); + if ( anim ) { + if ( channel == ANIMCHANNEL_HEAD ) { + if ( head.GetEntity() ) { + idThread::ReturnString( head.GetEntity()->GetAnimator()->AnimFullName( anim ) ); + return; + } + } else { + idThread::ReturnString( animator.AnimFullName( anim ) ); + return; + } + } + + idThread::ReturnString( "" ); +} + +/* +================ +idActor::Event_AnimLength +================ +*/ +void idActor::Event_AnimLength( int channel, const char *animname ) { + int anim; + + anim = GetAnim( channel, animname ); + if ( anim ) { + if ( channel == ANIMCHANNEL_HEAD ) { + if ( head.GetEntity() ) { + idThread::ReturnFloat( MS2SEC( head.GetEntity()->GetAnimator()->AnimLength( anim ) ) ); + return; + } + } else { + idThread::ReturnFloat( MS2SEC( animator.AnimLength( anim ) ) ); + return; + } + } + + idThread::ReturnFloat( 0.0f ); +} + +/* +================ +idActor::Event_AnimDistance +================ +*/ +void idActor::Event_AnimDistance( int channel, const char *animname ) { + int anim; + + anim = GetAnim( channel, animname ); + if ( anim ) { + if ( channel == ANIMCHANNEL_HEAD ) { + if ( head.GetEntity() ) { + idThread::ReturnFloat( head.GetEntity()->GetAnimator()->TotalMovementDelta( anim ).Length() ); + return; + } + } else { + idThread::ReturnFloat( animator.TotalMovementDelta( anim ).Length() ); + return; + } + } + + idThread::ReturnFloat( 0.0f ); +} + +/* +================ +idActor::Event_HasEnemies +================ +*/ +void idActor::Event_HasEnemies( void ) { + bool hasEnemy; + + hasEnemy = HasEnemies(); + idThread::ReturnInt( hasEnemy ); +} + +/* +================ +idActor::Event_NextEnemy +================ +*/ +void idActor::Event_NextEnemy( idEntity *ent ) { + idActor *actor; + + if ( !ent || ( ent == this ) ) { + actor = enemyList.Next(); + } else { + if ( !ent->IsType( idActor::Type ) ) { + gameLocal.Error( "'%s' cannot be an enemy", ent->name.c_str() ); + } + + actor = static_cast( ent ); + if ( actor->enemyNode.ListHead() != &enemyList ) { + gameLocal.Error( "'%s' is not in '%s' enemy list", actor->name.c_str(), name.c_str() ); + } + } + + for( ; actor != NULL; actor = actor->enemyNode.Next() ) { + if ( !actor->fl.hidden ) { + idThread::ReturnEntity( actor ); + return; + } + } + + idThread::ReturnEntity( NULL ); +} + +/* +================ +idActor::Event_ClosestEnemyToPoint +================ +*/ +void idActor::Event_ClosestEnemyToPoint( const idVec3 &pos ) { + idActor *bestEnt = ClosestEnemyToPoint( pos ); + idThread::ReturnEntity( bestEnt ); +} + +/* +================ +idActor::Event_MeleeBestParry +================ +*/ +void idActor::Event_MeleeBestParry() +{ + idThread::ReturnInt( GetBestParry() ); +} + +/* +================ +idActor::Event_MeleeNameForNum +================ +*/ +void idActor::Event_MeleeNameForNum( int num ) +{ + if( num >= 0 && num < NUM_MELEE_TYPES ) + idThread::ReturnString( MeleeTypeNames[num] ); + else + { + gameLocal.Warning("Actor %s attempted to look up bad melee type number %d", name.c_str(), num ); + idThread::ReturnString( "" ); + } +} + +/* +================ +idActor::Event_StopSound +================ +*/ +void idActor::Event_StopSound( int channel, int netSync ) { + if ( channel == SND_CHANNEL_VOICE ) { + idEntity *headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->StopSound( channel, ( netSync != 0 ) ); + } + } + StopSound( channel, ( netSync != 0 ) ); +} + +/* +===================== +idActor::Event_SetNextState +===================== +*/ +void idActor::Event_SetNextState( const char *name ) { + idealState = GetScriptFunction( name ); + if ( idealState == state ) { + state = NULL; + } +} + +/* +===================== +idActor::Event_SetState +===================== +*/ +void idActor::Event_SetState( const char *name ) { + idealState = GetScriptFunction( name ); + if ( idealState == state ) { + state = NULL; + } + scriptThread->DoneProcessing(); +} + +/* +===================== +idActor::Event_GetState +===================== +*/ +void idActor::Event_GetState( void ) { + if ( state ) { + idThread::ReturnString( state->Name() ); + } else { + idThread::ReturnString( "" ); + } +} + +/* +===================== +idActor::Event_GetHead +===================== +*/ +void idActor::Event_GetHead( void ) { + idThread::ReturnEntity( head.GetEntity() ); +} + +/* +===================== +idActor::Event_GetEyePos +===================== +*/ +void idActor::Event_GetEyePos( void ) +{ + idThread::ReturnVector( GetEyePosition() ); +} + +/* +===================== +idActor::Event_SetHealth +===================== +*/ +void idActor::Event_SetHealth( float newHealth ) { + health = static_cast(newHealth); + fl.takedamage = true; + if ( health > 0 ) { + AI_DEAD = false; + } else { + AI_DEAD = true; + } +} + +/* +===================== +idActor::Event_GetHealth +===================== +*/ +void idActor::Event_GetHealth( void ) { + idThread::ReturnFloat( health ); +} + +/* +===================== +idActor::Event_Attach +===================== +*/ +void idActor::Event_Attach( idEntity *ent, const char *AttName ) +{ + Attach( ent, NULL, AttName ); +} + +/* +===================== +idActor::Event_AttachToPos +===================== +*/ +void idActor::Event_AttachToPos( idEntity *ent, const char *PosName, const char *AttName ) +{ + Attach( ent, PosName, AttName ); +} + +/* +===================== +idActor::Event_GetAttachment +===================== +*/ +void idActor::Event_GetAttachment( const char *AttName ) +{ + idEntity *ent = GetAttachment( AttName ); + idThread::ReturnEntity( ent ); +} + +/* +===================== +idActor::Event_GetAttachmentInd +===================== +*/ +void idActor::Event_GetAttachmentInd( int ind ) +{ + idEntity *ent = GetAttachment( ind ); + idThread::ReturnEntity( ent ); +} + +/* +===================== +idActor::Event_GetNumAttachments +===================== +*/ +void idActor::Event_GetNumAttachments( void ) +{ + idThread::ReturnInt( m_Attachments.Num() ); +} + +/* +===================== +idActor::Event_GetNumMeleeWeapons +===================== +*/ +void idActor::Event_GetNumMeleeWeapons() +{ + idThread::ReturnInt(GetNumMeleeWeapons()); +} + +/* +===================== +idActor::Event_GetNumRangedWeapons +===================== +*/ +void idActor::Event_GetNumRangedWeapons() +{ + idThread::ReturnInt(GetNumRangedWeapons()); +} + +int idActor::GetNumMeleeWeapons() +{ + int numMeleeWeapons(0); + + // greebo: Always return 1 if this type of actor doesn't need weapons to fight + if (spawnArgs.GetBool("unarmed_melee", "0")) { + return 1; + } + + for (int i = 0; i < m_Attachments.Num(); i++) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL || !m_Attachments[i].ent.IsValid()) + { + continue; + } + + if (ent->spawnArgs.GetBool("is_weapon_melee")) + { + numMeleeWeapons++; + } + } + + return numMeleeWeapons; +} + +int idActor::GetNumRangedWeapons() +{ + int numRangedWeapons(0); + + if (spawnArgs.GetBool("unarmed_ranged", "0")) { + return 1; + } + + for (int i = 0; i < m_Attachments.Num(); i++) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL || !m_Attachments[i].ent.IsValid()) + { + continue; + } + + if (ent->spawnArgs.GetBool("is_weapon_ranged")) + { + numRangedWeapons++; + } + } + + return numRangedWeapons; +} + +bool idActor::GetAttackFlag(ECombatType type) const +{ + return m_AttackFlags.find(static_cast(type)) != m_AttackFlags.end(); +} + +void idActor::SetAttackFlag(ECombatType type, bool enabled) +{ + if (enabled) + { + m_AttackFlags.insert(type); + } + else + { + m_AttackFlags.erase(type); + } +} + +/**************************************************************************************** + ===================== + idActor::CrashLand + handle collision(Falling) damage to AI/Players + Added by Richard Day + ===================== +****************************************************************************************/ +CrashLandResult idActor::CrashLand( const idPhysics_Actor& physicsObj, const idVec3 &savedOrigin, const idVec3 &savedVelocity ) +{ + CrashLandResult result; + result.damageDealt = 0; + result.hasLanded = false; + + if (GetPhysics() == NULL) return result; + + idPhysics& physics = *GetPhysics(); // shortcut + + // no falling damage if touching a nodamage surface + // We do this here since the sound wont be played otherwise + // as we do no damage if this is true. + for( int i = 0; i < physics.GetNumContacts(); i++ ) + { + const contactInfo_t &contact = physics.GetContact( i ); + if ( contact.material->GetSurfaceFlags() & SURF_NODAMAGE ) + { + StartSound( "snd_land_hard", SND_CHANNEL_ANY, 0, false, NULL ); + result.hasLanded = true; + return result; + } + } + + const idVec3& vGravNorm = physics.GetGravityNormal(); + const idVec3& curVelocity = physics.GetLinearVelocity(); + + // The current speed parallel to gravity + idVec3 curGravVelocity = (curVelocity*vGravNorm) * vGravNorm; + + // Get the vdelta (how much the velocity has changed in this frame) + idVec3 deltaVec = (savedVelocity - curVelocity); + + // greebo: Get the vertical portion of the velocity + idVec3 deltaVecVert = (deltaVec * vGravNorm) * vGravNorm; + // Get the horizontal portion by subtracting the vertical one from the velocity + idVec3 deltaVecHoriz = deltaVec - deltaVecVert; + + float deltaHoriz = deltaVecHoriz.LengthSqr(); + float deltaVert = deltaVec.LengthSqr() - deltaHoriz; + + // conversion factor to 10s of MJ/kg, horizontal and vertical weighted differently + double delta = cv_collision_damage_scale_vert.GetFloat() * deltaVert; + delta += cv_collision_damage_scale_horiz.GetFloat() * deltaHoriz; + + // damage scale per actor + delta *= m_delta_scale; + + // greebo: Check if we are still using actor physics, we might already be in ragdoll mode + if (physics.IsType(idPhysics_Actor::Type)) + { + waterLevel_t waterLevel = static_cast(physics).GetWaterLevel(); + + // reduce falling damage if there is standing water + switch (waterLevel) + { + case WATERLEVEL_NONE: + break; + case WATERLEVEL_FEET: delta *= 0.8f; // -20% for shallow water + break; + case WATERLEVEL_WAIST: delta *= 0.5f; // -50% for medium water + break; + case WATERLEVEL_HEAD: delta *= 0.25f; // -75% for deep water + break; + default: + break; + }; + } + + // We've been moving downwards with a certain velocity, set the flag + if (curGravVelocity.LengthFast() < 1 && deltaVecVert*vGravNorm > 100) + { + result.hasLanded = true; + } + + if (delta < 390000) + { + // Below this threshold, nothing happens + return result; + } + + // greebo: Now calibrate the damage using the sixth power of the velocity (=square^3) + // The damage has a linear relationship to the sixth power of vdelta + delta = delta*delta*delta; + int damage = static_cast(1.4E-16 * delta - 3); + + // gameRenderWorld->DrawText(idStr(damage), GetPhysics()->GetOrigin(), 0.15, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 16); + + // Check if the damage is above our threshold, ignore otherwise + if (damage >= m_damage_thresh_min) + { + //gameRenderWorld->DrawText(idStr(deltaVert), GetPhysics()->GetOrigin(), 0.15, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 50000); + + //gameRenderWorld->DrawText(idStr(damage), GetPhysics()->GetOrigin(), 0.15, colorRed, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 5000); + gameLocal.Printf("Damage dealt: %d\n", damage); + + pain_debounce_time = gameLocal.time + pain_delay + 1; // ignore pain since we'll play our landing anim + + // Update our return value + result.damageDealt = damage; + + if (damage > m_damage_thresh_hard) + { + // greebo: the damage_fall_hard entityDef has a damage value of 1, which is scaled by the calculated damage integer + StartSound("snd_damage_land_hard", SND_CHANNEL_VOICE, 0, false, NULL); + Damage(NULL, NULL, vGravNorm, "damage_fall_hard", damage, 0); + } + else + { + // We are below the "hard" threshold, just deal the "soft" damage + StartSound("snd_damage_land_soft", SND_CHANNEL_VOICE, 0, false, NULL); + Damage(NULL, NULL, vGravNorm, "damage_fall_soft", damage, 0); + } + } + + return result; +} + +void idActor::Event_MeleeAttackStarted( int num ) +{ + m_MeleeStatus.m_ActionResult = MELEERESULT_IN_PROGRESS; + m_MeleeStatus.m_ActionState = MELEEACTION_ATTACK; + m_MeleeStatus.m_ActionType = (EMeleeType) num; + m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; + m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; + + // randomize minimum times to events after this one + // TODO: Rewrite this so we only set the times we need according to the result? + float fRand = gameLocal.random.RandomFloat(); + m_MeleeCurrentHoldTime = m_MeleeHoldTimeMin + fRand*(m_MeleeHoldTimeMax - m_MeleeHoldTimeMin); + m_MeleeCurrentAttackRecovery = m_MeleeAttackRecoveryMin + fRand*(m_MeleeAttackRecoveryMax - m_MeleeAttackRecoveryMin); + m_MeleeCurrentAttackLongRecovery = m_MeleeAttackLongRecoveryMin + fRand*(m_MeleeAttackLongRecoveryMax - m_MeleeAttackLongRecoveryMin); + m_MeleeCurrentParryRecovery = m_MeleeParryRecoveryMin + fRand*(m_MeleeParryRecoveryMax - m_MeleeParryRecoveryMin); +} + +void idActor::Event_MeleeParryStarted( int num ) +{ + m_MeleeStatus.m_ActionResult = MELEERESULT_IN_PROGRESS; + m_MeleeStatus.m_ActionState = MELEEACTION_PARRY; + m_MeleeStatus.m_ActionType = (EMeleeType) num; + m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; + m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; + + // randomize minimum times to events after this one + // TODO: Rewrite this so we only set what we need based on result? + float fRand = gameLocal.random.RandomFloat(); + m_MeleeCurrentParryHold = m_MeleeParryHoldMin + fRand*(m_MeleeParryHoldMax - m_MeleeParryHoldMin); + m_MeleeCurrentAttackLongRecovery = m_MeleeAttackLongRecoveryMin + fRand*(m_MeleeAttackLongRecoveryMax - m_MeleeAttackLongRecoveryMin); + m_MeleeCurrentParryRecovery = m_MeleeParryRecoveryMin + fRand*(m_MeleeParryRecoveryMax - m_MeleeParryRecoveryMin); + m_MeleeCurrentRiposteRecovery = m_MeleeRiposteRecoveryMin + fRand*(m_MeleeRiposteRecoveryMax - m_MeleeRiposteRecoveryMin); + m_MeleeCurrentPreParryDelay = m_MeleePreParryDelayMin + fRand*(m_MeleePreParryDelayMax - m_MeleePreParryDelayMin); + m_MeleeCurrentRepeatedPreParryDelay = m_MeleeRepeatedPreParryDelayMin + fRand*(m_MeleeRepeatedPreParryDelayMax - m_MeleeRepeatedPreParryDelayMin); + m_MeleeCurrentPostParryDelay = m_MeleePostParryDelayMin + fRand*(m_MeleePostParryDelayMax - m_MeleePostParryDelayMin); + m_MeleeCurrentRepeatedPostParryDelay = m_MeleeRepeatedPostParryDelayMin + fRand*(m_MeleeRepeatedPostParryDelayMax - m_MeleeRepeatedPostParryDelayMin); +} + +void idActor::Event_MeleeActionHeld() +{ + m_MeleeStatus.m_ActionPhase = MELEEPHASE_HOLDING; + m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; +} + +void idActor::Event_MeleeActionReleased() +{ + // attacks go to executing phase, parries jump straight to recovering + // CMeleeWeapon handles toggling attacks from executing to recovering + if( m_MeleeStatus.m_ActionState == MELEEACTION_ATTACK ) + m_MeleeStatus.m_ActionPhase = MELEEPHASE_EXECUTING; + else + m_MeleeStatus.m_ActionPhase = MELEEPHASE_RECOVERING; + + + m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; +} + +void idActor::Event_MeleeActionFinished() +{ + m_MeleeStatus.m_ActionState = MELEEACTION_READY; + m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; + m_MeleeStatus.m_LastActTime = gameLocal.time; +} + +void idActor::Event_GetMeleeActionState() +{ + idThread::ReturnInt( m_MeleeStatus.m_ActionState ); +} + +void idActor::Event_GetMeleeActionPhase() +{ + idThread::ReturnInt( m_MeleeStatus.m_ActionPhase ); +} + +void idActor::Event_GetMeleeActionType() +{ + idThread::ReturnInt( m_MeleeStatus.m_ActionType ); +} + +void idActor::Event_GetMeleeLastActTime() +{ + idThread::ReturnInt( m_MeleeStatus.m_LastActTime ); +} + +void idActor::Event_GetMeleeResult() +{ + idThread::ReturnInt( m_MeleeStatus.m_ActionResult ); +} + +void idActor::Event_GetMeleeLastHitByType() +{ + idThread::ReturnInt( m_MeleeStatus.m_LastHitByType ); +} + +void idActor::Event_SetReplacementAnim(const char* animToReplace, const char* replacementAnim) +{ + SetReplacementAnim(animToReplace, replacementAnim); +} + +void idActor::Event_RemoveReplacementAnim(const char* animName) +{ + RemoveReplacementAnim(animName); +} + +void idActor::Event_LookupReplacementAnim(const char* animName) +{ + idThread::ReturnString(LookupReplacementAnim(animName)); +} + +void idActor::Event_GetAttackFlag(int combatType) +{ + if (combatType < COMBAT_NONE || combatType >= NUM_COMBAT_TYPES) + { + idThread::ReturnInt(0); + } + + idThread::ReturnInt(GetAttackFlag(static_cast(combatType)) ? 1 : 0); +} + +void idActor::Event_SetAttackFlag(int combatType, int enabled) +{ + if (combatType < COMBAT_NONE || combatType >= NUM_COMBAT_TYPES) + { + // do nothing + gameLocal.Warning("Script is trying to set invalid combatType %d", combatType); + return; + } + + SetAttackFlag(static_cast(combatType), enabled == 1); +} + +// ========== CMeleeStatus implementation ========= +CMeleeStatus::CMeleeStatus( void ) +{ + m_ActionState = MELEEACTION_READY; + m_ActionPhase = MELEEPHASE_PREPARING; + m_ActionType = MELEETYPE_OVER; + + m_PhaseChangeTime = 0; + m_LastActTime = 0; + + m_ActionResult = MELEERESULT_IN_PROGRESS; + + m_bWasHit = false; // NYI + m_LastHitByType = MELEETYPE_UNBLOCKABLE; + + m_bCanParry = false; + m_bCanParryAll = false; + m_attacks.Clear(); +} + +CMeleeStatus::~CMeleeStatus( void ) +{ + m_attacks.Clear(); +} + +void CMeleeStatus::Save( idSaveGame *savefile ) const +{ + savefile->WriteInt( m_ActionState ); + savefile->WriteInt( m_ActionPhase ); + savefile->WriteInt( m_ActionType ); + savefile->WriteInt( m_PhaseChangeTime ); + savefile->WriteInt( m_LastActTime ); + savefile->WriteInt( m_ActionResult ); + + savefile->WriteBool( m_bWasHit ); + savefile->WriteInt( m_LastHitByType ); + + savefile->WriteBool( m_bCanParry ); + savefile->WriteBool( m_bCanParryAll ); + + int num = m_attacks.Num(); + savefile->WriteInt( num ); + for( int i =0; i < num; i++ ) + { + savefile->WriteInt( m_attacks[i] ); + } +} + +void CMeleeStatus::Restore( idRestoreGame *savefile ) +{ + int i = 0; + savefile->ReadInt( i ); + m_ActionState = (EMeleeActState) i; + savefile->ReadInt( i ); + m_ActionPhase = (EMeleeActPhase) i; + savefile->ReadInt( i ); + m_ActionType = (EMeleeType) i; + savefile->ReadInt( m_PhaseChangeTime ); + savefile->ReadInt( m_LastActTime ); + savefile->ReadInt( i ); + m_ActionResult = (EMeleeResult) i; + + savefile->ReadBool( m_bWasHit ); + savefile->ReadInt( i ); + m_LastHitByType = (EMeleeType) i; + + savefile->ReadBool( m_bCanParry ); + savefile->ReadBool( m_bCanParryAll ); + + int num; + savefile->ReadInt( num ); + m_attacks.SetNum( num ); + for( int j =0; j < num; j++ ) + { + savefile->ReadInt( i ); + m_attacks[j] = (EMeleeType) i; + } +} diff --git a/game/Actor.h b/game/Actor.h new file mode 100644 index 000000000..e13896938 --- /dev/null +++ b/game/Actor.h @@ -0,0 +1,898 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_ACTOR_H__ +#define __GAME_ACTOR_H__ + +#include "MultiStateMoverPosition.h" +#include "ai/EAS/RouteInfo.h" +#include + +// greebo: Keep the values in scripts/tdm_defs.script in sync with these +enum ECombatType +{ + COMBAT_NONE, + COMBAT_MELEE, + COMBAT_RANGED, + NUM_COMBAT_TYPES +}; + +/** Melee Attack/Parry types **/ +typedef enum +{ + MELEETYPE_OVER, + MELEETYPE_LR, // slashing (attacker's) left to right + MELEETYPE_RL, // slashing (attacker's) right to left + MELEETYPE_THRUST, + MELEETYPE_UNBLOCKABLE, // unblockable attacks (e.g. animal claws) + MELEETYPE_BLOCKALL, // blocks all attacks except unblockable (e.g., shield) + NUM_MELEE_TYPES +} EMeleeType; + +/** Melee Overall Action States **/ +typedef enum +{ + MELEEACTION_READY, // ready to attack or parry + MELEEACTION_ATTACK, + MELEEACTION_PARRY +} EMeleeActState; + +/** Melee phases of each action (applies to both attack and parry) **/ +typedef enum +{ + MELEEPHASE_PREPARING, // Moving to backswing or parry position + MELEEPHASE_HOLDING, // holding a backswing or parry + MELEEPHASE_EXECUTING, // executing a threatening attack (doesn't apply to parries) + MELEEPHASE_RECOVERING // recovering the current attack/parry back to guard position +} EMeleeActPhase; + +/** Possible outcomes of a melee action (includes attacks and parries) **/ +enum EMeleeResult +{ + MELEERESULT_IN_PROGRESS, // no result yet, still in progress + MELEERESULT_AT_HIT, + MELEERESULT_AT_MISSED, + MELEERESULT_AT_PARRIED, + MELEERESULT_PAR_BLOCKED, // successfully parried the attack + MELEERESULT_PAR_FAILED, // got hit while parrying (TODO: Does not catch all cases, only catches parry type mismatch) + MELEERESULT_PAR_ABORTED, // gave up parrying + + NUM_MELEE_RESULTS +}; + +/** class for storing current melee combat status **/ +class CMeleeStatus +{ +public: + CMeleeStatus( void ); + virtual ~CMeleeStatus( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // clears the current action + void ClearAction( void ); + + EMeleeActState m_ActionState; // current action + EMeleeActPhase m_ActionPhase; // phase within that action + EMeleeType m_ActionType; // type of attack/parry + + // time the phase of our action last changed + int m_PhaseChangeTime; + // time that our most recent action ended + int m_LastActTime; + + // Result of most recent action + // Will be considered "in progress" until back in the "Ready" state + EMeleeResult m_ActionResult; + + // were we just hit by a melee attack? may take longer to perform next action + // NYI + bool m_bWasHit; + + /** What attack type were we last hit by? (used by trainers to give feedback) **/ + EMeleeType m_LastHitByType; + + // melee capabilities of weapon + bool m_bCanParry; + bool m_bCanParryAll; + idList m_attacks; // possible attacks with current weapon + +}; // CMeleeStatus + + +/* +=============================================================================== + + idActor + +=============================================================================== +*/ + +extern const idEventDef AI_EnableEyeFocus; +extern const idEventDef AI_DisableEyeFocus; +extern const idEventDef EV_Footstep; +extern const idEventDef EV_FootstepLeft; +extern const idEventDef EV_FootstepRight; +extern const idEventDef EV_EnableWalkIK; +extern const idEventDef EV_DisableWalkIK; +extern const idEventDef EV_EnableLegIK; +extern const idEventDef EV_DisableLegIK; +extern const idEventDef AI_SetAnimPrefix; +extern const idEventDef AI_PlayAnim; +extern const idEventDef AI_PauseAnim; +extern const idEventDef AI_AnimIsPaused; +extern const idEventDef AI_PlayCycle; +extern const idEventDef AI_AnimDone; +extern const idEventDef AI_SetBlendFrames; +extern const idEventDef AI_GetBlendFrames; + +extern const idEventDef AI_MeleeAttackStarted; +extern const idEventDef AI_MeleeParryStarted; +extern const idEventDef AI_MeleeActionHeld; +extern const idEventDef AI_MeleeActionReleased; +extern const idEventDef AI_MeleeActionFinished; +extern const idEventDef AI_GetMeleeActionState; +extern const idEventDef AI_GetMeleeActionPhase; +extern const idEventDef AI_GetMeleeActionType; +extern const idEventDef AI_GetMeleeLastActTime; +extern const idEventDef AI_GetMeleeResult; +extern const idEventDef AI_GetMeleeLastHitByType; +extern const idEventDef AI_MeleeBestParry; +extern const idEventDef AI_MeleeNameForNum; + +class idDeclParticle; + +class idAnimState { +public: + bool idleAnim; + idStr state; + int animBlendFrames; + int lastAnimBlendFrames; // allows override anims to blend based on the last transition time + +public: + idAnimState(); + ~idAnimState(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Init( idActor *owner, idAnimator *_animator, int animchannel ); + void Shutdown( void ); + void SetState( const char *name, int blendFrames ); + void SetFrame( int anim, int frame ); + void StopAnim( int frames ); + void PlayAnim( int anim ); + void PauseAnim( int channel, bool bPause ); + bool AnimIsPaused( int anim ); + void CycleAnim( int anim ); + void BecomeIdle( void ); + bool UpdateState( void ); + bool Disabled( void ) const; + void Enable( int blendFrames ); + void Disable( void ); + bool AnimDone( int blendFrames ) const; + bool IsIdle( void ) const; + animFlags_t GetAnimFlags( void ) const; + idAnimator* GetAnimator(); + void FinishAction(const idStr& actionname); + const char * WaitState( void ) const; + void SetWaitState( const char *_waitstate ); + + +private: + idStr waitState; + idActor * self; + idAnimator * animator; + idThread * thread; + int channel; + bool disabled; +}; + +typedef struct { + jointModTransform_t mod; + jointHandle_t from; + jointHandle_t to; +} copyJoints_t; + +struct CrashLandResult +{ + int damageDealt; // contains the damage done to the actor + bool hasLanded; // true if the actor hit the ground after a fall this frame +}; + +enum GreetingState +{ + ECannotGreet = 0, // actor is not able to greet (e.g. spiders) + ENotGreetingAnybody, // actor is currently not greeting anybody (free) + EWaitingForGreeting, // actor is receiving a greeting from somebody else + EGoingToGreet, // actor is about to greet somebody + EIsGreeting, // actor is currently playing its greeting sound + EAfterGreeting, // actor is in the small pause after greeting + ENumAIGreetingStates, // invalid state +}; + +#define TDM_HEAD_ENTITYDEF "atdm:ai_head_base" + +class idActor : public idAFEntity_Gibbable { +public: + CLASS_PROTOTYPE( idActor ); + + int rank; // monsters don't fight back if the attacker's rank is higher + /** + * TDM: Defines the type of the AI (human, beast, undead, bot, etc) + **/ + int m_AItype; + /** + * TDM: Whether this actor is considered a non-combatant + **/ + bool m_Innocent; + idMat3 viewAxis; // view axis of the actor + + idLinkList enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him + idLinkList enemyList; // list of characters that have targeted the player as their enemy + + // The greeting state this actor is currently in (to coordinate greeting barks in between actors) + GreetingState greetingState; + + /** + * TDM: Moved up from idAI + * These ranges are the best guess for the max range at which the AI can hit + * an enemy. melee_range_unarmed is the range with no weapon, read from + * the melee_range spawnarg on the AI. + * If the AI has no weapon, melee_range = melee_range_unarmed. + * melee_range includes the reach of the current weapon, updated when weapons are attached + **/ + float melee_range_unarmed; // potential + float melee_range; // includes reach of current weapon + /** + * grayman #2655 - some AI need a different vertical melee_range, i.e. the werebeast crawler + **/ + float melee_range_vert; + /** + * This should roughly correspond to the time it takes them to swing the weapon + * In seconds (read from spawnarg in milliseconds and converted) + * Currently it is used for AI predicting whether they will be able to hit + * their enemy in the future if they start our attack now + * It may be used for other things later + **/ + float m_MeleePredictedAttTime; + // and without a weapon (need to store in case they get disarmed somehow) + float m_MeleePredictedAttTimeUnarmed; + + + /** + * Stores what this actor is currently doing in melee combat + * ishtvan: Made public to avoid lots of gets/sets + **/ + CMeleeStatus m_MeleeStatus; + /** + * Number representing the ability of this actor to inflict melee damage + * multiplies the baseline melee damage set on the weapon by this amount + **/ + float m_MeleeDamageMult; + /** + * Melee timing: Time between the backswing and forward swing + * Actual number is random, between this min and max + * Number is in milliseconds + **/ + int m_MeleeHoldTimeMin; + int m_MeleeHoldTimeMax; + int m_MeleeCurrentHoldTime; + /** + * Melee timing: Max time that we will hold a parry, waiting for the attack + **/ + int m_MeleeParryHoldMin; + int m_MeleeParryHoldMax; + int m_MeleeCurrentParryHold; + /** + * Melee timing: Time between subsequent attacks (in milliseconds) + **/ + int m_MeleeAttackRecoveryMin; + int m_MeleeAttackRecoveryMax; + int m_MeleeCurrentAttackRecovery; + /** + * Melee timing: Time after being parried or getting hit that we can attack (longer than the normal time) + **/ + int m_MeleeAttackLongRecoveryMin; + int m_MeleeAttackLongRecoveryMax; + int m_MeleeCurrentAttackLongRecovery; + /** + * Melee timing: Time after last action that we can parry (fairly short) + * TODO: the name of this could be confusing, we're not recovering FROM a parry + **/ + int m_MeleeParryRecoveryMin; + int m_MeleeParryRecoveryMax; + int m_MeleeCurrentParryRecovery; + /** + * Melee timing: Time after a successful (or aborted) parry that we can attack + **/ + int m_MeleeRiposteRecoveryMin; + int m_MeleeRiposteRecoveryMax; + int m_MeleeCurrentRiposteRecovery; + /** + * Melee timing: Time delay between when we decide to parry and when the anim starts + * Acts as a human reaction time to an oncoming attack + **/ + int m_MeleePreParryDelayMin; + int m_MeleePreParryDelayMax; + int m_MeleeCurrentPreParryDelay; + /** + * Same as above, but use a shorter delay when responding to repeated attacks + * along the same direction + **/ + int m_MeleeRepeatedPreParryDelayMin; + int m_MeleeRepeatedPreParryDelayMax; + int m_MeleeCurrentRepeatedPreParryDelay; + /** + * Controls how many times the attack has to be repeated in a row + * in order to use the faster response time + **/ + int m_MeleeNumRepAttacks; + /** + * Time duration over which the same attacks in a row have to occur + * in order to be anticipated and use faster response + **/ + int m_MeleeRepAttackTime; + /** + * Melee timing: Time delay between when we decide to stop parrying and when the animation goes + * Acts as a human reaction time to the cessation of an attack + **/ + int m_MeleePostParryDelayMin; + int m_MeleePostParryDelayMax; + int m_MeleeCurrentPostParryDelay; + /** + * Same as above, but use a shorter delay when responding to repeated attacks + * along the same direction + **/ + int m_MeleeRepeatedPostParryDelayMin; + int m_MeleeRepeatedPostParryDelayMax; + int m_MeleeCurrentRepeatedPostParryDelay; + + /** + * Correspondence between melee type and string name suffix of the action + **/ + static const char * MeleeTypeNames[ NUM_MELEE_TYPES ]; + + /** + * grayman #2345 - rank for path-finding + **/ + int m_pathRank; + + /** + * grayman #2728 - next time this actor can be kicked by another actor + **/ + int m_nextKickTime; + +public: + idActor( void ); + virtual ~idActor( void ); + + void Spawn( void ); + virtual void Restart( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Hide( void ); + virtual void Show( void ); + virtual int GetDefaultSurfaceType( void ) const; + virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); + + virtual bool LoadAF( void ); + void SetupBody( void ); + + void CheckBlink( void ); + + virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); + virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); + + // script state management + void ShutdownThreads( void ); + virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; + virtual idThread * ConstructScriptObject( void ); + virtual void UpdateScript(); + const function_t *GetScriptFunction( const char *funcname ); + void SetState( const function_t *newState ); + void SetState( const char *statename ); + + // vision testing + void SetEyeHeight( float height ); + float EyeHeight( void ) const; + idVec3 EyeOffset( void ) const; + virtual idVec3 GetEyePosition( void ) const; + virtual void GetViewPos( idVec3 &origin, idMat3 &axis ) const; + /** + * Sets the actor's field of view (doesn't apply to players) + * Input is horizontal FOV, vertical FOV. + * If no vertical is provided, it is assumed the same as the vertical + * + * Sets the FOV dot products to those of the half-angles of the full fov + **/ + void SetFOV( float fovHoriz, float fovVert = -1 ); + virtual bool CheckFOV( const idVec3 &pos ) const; + + /** + * greebo: This method returns TRUE, if the given entity is visible by this actor. + * For actor entities, the eye position is taken into account, for ordinary entities, + * the origin is taken. + * First, the origin/eye position is checked against the FOV of this actor, and second, + * a trace is performed from eye (this) to origin/eye (other entity). If the trace is + * blocked, the entity is considered hidden and the method returns FALSE. + */ + virtual bool CanSee( idEntity *ent, bool useFOV ) const; + bool PointVisible( const idVec3 &point ) const; + virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ); + + // damage + void SetupDamageGroups( void ); + // DarkMod: Added trace reference to damage + virtual void Damage + ( + idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision = NULL + ); + + /** + * Return the stealth damage multiplier + * Only used by derived class idAI + **/ + virtual float StealthDamageMult( void ) { return 1.0; }; + + /** + * Melee callbacks so the melee system can let the actor know what happened + * And to keep the melee status up to date + **/ + void MeleeAttackMissed( void ); + void MeleeAttackHit( idEntity *ent ); + void MeleeAttackParried( idEntity *owner, idEntity *weapon = NULL ); + void MeleeParrySuccess( idEntity *other ); + + /**************************************************************************************** + ===================== + idActor::CrashLand + handle collision(Falling) damage to AI/Players + Added by Richard Day + ===================== + // greebo: Changed return type: the amount of damage points is contained in the struct + ****************************************************************************************/ + CrashLandResult CrashLand( const idPhysics_Actor& physicsObj, const idVec3 &oldOrigin, const idVec3 &oldVelocity ); + + int GetDamageForLocation( int damage, int location ); + const char * GetDamageGroup( int location ); + void ClearPain( void ); + virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ); + + // greebo: Sets the "player is pushing something heavy" state to the given bool. + virtual void SetIsPushing(bool isPushing); + // Returns whether the player is currently pushing something heavy + virtual bool IsPushing(); + + // model/combat model/ragdoll + void SetCombatModel( void ); + idClipModel * GetCombatModel( void ) const; + virtual void LinkCombat( void ); + virtual void UnlinkCombat( void ); + bool StartRagdoll( void ); + void StopRagdoll( void ); + virtual bool UpdateAnimationControllers( void ); + + // delta view angles to allow movers to rotate the view of the actor + const idAngles & GetDeltaViewAngles( void ) const; + void SetDeltaViewAngles( const idAngles &delta ); + + bool HasEnemies( void ) const; + idActor * ClosestEnemyToPoint( const idVec3 &pos ); + idActor * EnemyWithMostHealth(); + /** + * Get closest enemy who is in the process of launching a melee attack + **/ + idActor * ClosestAttackingEnemy( bool bUseFOV ); + /** + * Returns the enum of the best parry given the attacks at the time + * If no attacking enemy is found, returns default of "RL" + * See dActor::MeleeTypeNames for the list of melee attack/parry names + **/ + EMeleeType GetBestParry( void ); + + virtual bool OnLadder( void ) const; + // Returns the elevator entity if the actor is standing on an elevator + // angua: if mustBeMoving is true, the elevator is only returned when it is moving + virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; + + virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const; + + /** + * Called when the given ent is about to be bound/attached to this actor. + **/ + void BindNotify( idEntity *ent ); + + /** + * Called when the given ent is about to be unbound/detached from this actor. + **/ + virtual void UnbindNotify( idEntity *ent ); + + /** + * Attach an entity. Entity spawnArgs checked for attachments are: + * "origin", "angles", and "joint". + * AttName is the optional name of the attachment for indexing purposes (e.g., "melee_weapon") + * Ent is the entity being attached + * PosName is the optional position name to attach to. + **/ + virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); + + /** + * greebo: Returns the number of attached melee weapons. These are the entities + * with the according spawnarg "is_weapon_melee" etc. set to "1". + */ + int GetNumMeleeWeapons(); + int GetNumRangedWeapons(); + + ID_INLINE float GetMeleeRange() const + { + return melee_range; + } + + /** + * greebo: Returns TRUE whether combat is allowed for the given type. + * Even though an actor has a weapon attached, it might still be sheathed and + * combat is "disabled" therefore, which is represented by the AttackFlag. + */ + bool GetAttackFlag(ECombatType type) const; + void SetAttackFlag(ECombatType type, bool enabled); + + virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); + + virtual renderView_t * GetRenderView(); + + // animation state control + int GetAnim( int channel, const char *name ); + idAnimator* GetAnimatorForChannel(int channel); + + // greebo: Searches the given dictionary for animation replacement spawnargs and applies them to this actor + void LoadReplacementAnims(const idDict& spawnArgs); + + const char* LookupReplacementAnim( const char *name ); + + // greebo: Replaces the given animToReplace by the animation replacementAnim + void SetReplacementAnim(const idStr& animToReplace, const idStr& replacementAnim); + + // greebo: Removes any replacement for the given anim. + void RemoveReplacementAnim(const idStr& replacedAnim); + void StopAnim(int channel, int frames); + void UpdateAnimState( void ); + void SetAnimState( int channel, const char *name, int blendFrames ); + const char * GetAnimState( int channel ) const; + bool InAnimState( int channel, const char *name ) const; + const char * WaitState( void ) const; + const char * WaitState( int channel ) const; + void SetWaitState( const char *_waitstate ); + void SetWaitState( int channel, const char *_waitstate ); + bool AnimDone( int channel, int blendFrames ) const; + virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName ); + + /** + * Returns the modification to movement volume based on the movement type + * (crouch walk, creep, run, etc) + * Called in derived classes idPlayer and idAI. + **/ + virtual float GetMovementVolMod( void ) { return 0; }; + + virtual bool IsKnockedOut( void ) { return false; }; + + virtual bool CanUseElevators() const { return canUseElevators; } + + /** + * greebo: This gets called by the pathing routine to let the actor + * reconsider the "forbidden" status of the given area. After some time + * AI should be able to re-try opening locked doors otherwise the door's AAS area + * stays flagged as "forbidden" for all times. + * + * Note: This method is overriden by the AI class. + * + * @returns: TRUE if the area is now considered as "allowed", FALSE otherwise. + */ + virtual bool ReEvaluateArea(int areaNum); + +public: + // Moved from player/AI to here + idScriptBool AI_DEAD; + +protected: + + /* CrashLand variables Added by Richard Day */ + + float m_damage_thresh_min; // min damage. anything at or below this does 0 damage + float m_damage_thresh_hard; // any damage above this is considered "hard" + float m_delta_scale; ///< scale the damage based on this. delta is divide by this + + + friend class idAnimState; + + float m_fovDotHoriz; // cos( Horizontal fov [degrees] ) + float m_fovDotVert; // cos( Vertical fov [degrees] ) + idVec3 eyeOffset; // offset of eye relative to physics origin + idVec3 modelOffset; // offset of visual model relative to the physics origin + idVec3 mHeadModelOffset; // offset for the head + + idAngles deltaViewAngles; // delta angles relative to view input angles + + int pain_debounce_time; // next time the actor can show pain + int pain_delay; // time between playing pain sound + int pain_threshold; // how much damage monster can take at any one time before playing pain animation + + idStrList damageGroups; // body damage groups + idList damageScale; // damage scale per damage group + + // greebo: If not -1, the actor will fire a script when its health falls below this value + int lowHealthThreshold; + idStr lowHealthScript; + + /** + * Alertnum threshold above which sneak attacks won't work, + **/ + float m_SneakAttackThresh; + /** + * Damage multiplier applied for sneak attack damage + **/ + float m_SneakAttackMult; + + bool use_combat_bbox; // whether to use the bounding box for combat collision + idEntityPtr head; + idList copyJoints; // copied from the body animation to the head model + + // state variables + const function_t *state; + const function_t *idealState; + +protected: + + // joint handles + jointHandle_t leftEyeJoint; + jointHandle_t rightEyeJoint; + jointHandle_t soundJoint; + + idIK_Walk walkIK; + + idStr animPrefix; + idStr painAnim; + + // blinking + int blink_anim; + int blink_time; + int blink_min; + int blink_max; + + // script variables + idThread * scriptThread; + idStr waitState; + idAnimState headAnim; + idAnimState torsoAnim; + idAnimState legsAnim; + + bool allowPain; + bool allowEyeFocus; + bool finalBoss; + + int painTime; + + // greebo: Is set to TRUE if this actor can use elevators. + bool canUseElevators; + +// idList m_Attachments; + + // Maps animation names to the names of their replacements + idDict m_replacementAnims; + + /** + * This is the set of attack flags. If the corresponding enum value ECombatType + * is present in this set, the actor is ready for attacking with that attack type. + */ + std::set m_AttackFlags; + + /** + * Movement volume modifiers. Ones for the player are taken from + * cvars (for now), ones for AI are taken from spawnargs. + * Walking and not crouching is the default volume. + **/ + + float m_stepvol_walk; + float m_stepvol_run; + float m_stepvol_creep; + + float m_stepvol_crouch_walk; + float m_stepvol_crouch_creep; + float m_stepvol_crouch_run; + + virtual void Gib( const idVec3 &dir, const char *damageDefName ); + + // removes attachments with "remove" set for when character dies + void RemoveAttachments( void ); + + // copies animation from body to head joints + void CopyJointsFromBodyToHead( void ); + + /** + * Updates the volume offsets for various movement modes + * (eg walk, run, creep + crouch ). + * Used by derived classes idPlayer and idAI. + **/ + virtual void UpdateMoveVolumes( void ) {}; + + /** + * TestKnockoutBlow, only defined in derived classes + * Returns true if going from conscious to unconscious + **/ + virtual bool TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ) + { + return false; + }; + + /** + * greebo: Plays the footstep sound according to the current movement type. + * Note: AI and Player are overriding this method. + */ + virtual void PlayFootStepSound(); // empty default implementation + + // Links script variables (is overridden by idAI and idPlayer) + virtual void LinkScriptVariables(); + +private: + void SyncAnimChannels( int channel, int syncToChannel, int blendFrames ); + void FinishSetup( void ); + + /** + * greebo: This loads the vocal set (the snd_* spawnargs) into this entity's spawnargs. + */ + void LoadVocalSet(); + + /** + * ishtvan: Load a set of melee difficulty options + **/ + void LoadMeleeSet(); + + void SetupHead( void ); + +public: + void Event_EnableEyeFocus( void ); + void Event_DisableEyeFocus( void ); + void Event_Footstep( void ); + void Event_EnableWalkIK( void ); + void Event_DisableWalkIK( void ); + void Event_EnableLegIK( int num ); + void Event_DisableLegIK( int num ); + void Event_SetAnimPrefix( const char *name ); + void Event_LookAtEntity( idEntity *ent, float duration ); + void Event_PreventPain( float duration ); + void Event_DisablePain( void ); + void Event_EnablePain( void ); + void Event_GetPainAnim( void ); + void Event_StopAnim( int channel, int frames ); + void Event_PlayAnim( int channel, const char *name ); + void Event_PauseAnim( int channel, bool bPause ); + void Event_AnimIsPaused( int channel ); + void Event_PlayCycle( int channel, const char *name ); + void Event_IdleAnim( int channel, const char *name ); + void Event_SetSyncedAnimWeight( int channel, int anim, float weight ); + void Event_SyncAnimChannels(int fromChannel, int toChannel, float blendFrames); + void Event_OverrideAnim( int channel ); + void Event_EnableAnim( int channel, int blendFrames ); + void Event_DisableAnimchannel( int channel ); + void Event_SetBlendFrames( int channel, int blendFrames ); + void Event_GetBlendFrames( int channel ); + void Event_AnimState( int channel, const char *name, int blendFrames ); + void Event_GetAnimState( int channel ); + void Event_InAnimState( int channel, const char *name ); + void Event_FinishAction( const char *name ); + void Event_FinishChannelAction(int channel, const char *name ); + void Event_AnimDone( int channel, int blendFrames ); + void Event_HasAnim( int channel, const char *name ); + void Event_CheckAnim( int channel, const char *animname ); + void Event_ChooseAnim( int channel, const char *animname ); + void Event_AnimLength( int channel, const char *animname ); + void Event_AnimDistance( int channel, const char *animname ); + void Event_HasEnemies( void ); + void Event_NextEnemy( idEntity *ent ); + void Event_ClosestEnemyToPoint( const idVec3 &pos ); + void Event_StopSound( int channel, int netsync ); + void Event_SetNextState( const char *name ); + void Event_SetState( const char *name ); + void Event_GetState( void ); + void Event_GetHead( void ); + void Event_GetEyePos( void ); + + // greebo: Moved these from idAI to here + void Event_SetHealth( float newHealth ); + void Event_GetHealth( void ); + + /** + * Attaches the entity and gives it the given attachment name + **/ + void Event_Attach( idEntity *ent, const char *AttName ); + /** + * Attaches the entity to the named position PosName and gives it the attachment name AttName + **/ + void Event_AttachToPos( idEntity *ent, const char *PosName, const char *AttName ); + void Event_GetAttachment( const char *AttName ); + void Event_GetAttachmentInd( int ind ); + void Event_GetNumAttachments( void ); + + // Returns the number of ranged/melee weapons attached to the calling script + void Event_GetNumMeleeWeapons(); + void Event_GetNumRangedWeapons(); + /** + * Registers the start of a given melee attack/parry + * Intended to be called from a script that also starts the animation + **/ + void Event_MeleeAttackStarted( int AttType ); + void Event_MeleeParryStarted( int ParType ); + /** Called when the melee action reaches the "hold" point **/ + void Event_MeleeActionHeld( void ); + /** Called when the melee action is released from the hold point **/ + void Event_MeleeActionReleased( void ); + /** Called when the animation for the melee action has finished **/ + void Event_MeleeActionFinished( void ); + /** Get the current melee action state **/ + void Event_GetMeleeActionState( void ); + /** Get the current melee action phase **/ + void Event_GetMeleeActionPhase( void ); + /** Get the current melee action type **/ + void Event_GetMeleeActionType( void ); + /** Get the time at which the previous melee action finished **/ + void Event_GetMeleeLastActTime( void ); + /** Called by script to get result of last melee action **/ + void Event_GetMeleeResult( void ); + /** Get the type of the last melee attack we were hit with (defaults to MELEETYPE_UNBLOCKABLE if we were not hit) **/ + void Event_GetMeleeLastHitByType( void ); + + /** + * Returns the melee type integer of the optimal melee parry given current attackers + * If no attackers are found within the FOV, + * returns a default of MELEETYPE_RL (sabre parry #4) + **/ + void Event_MeleeBestParry(); + /** + * Convert a melee type integer to the corresponding string name + **/ + void Event_MeleeNameForNum( int num ); + + // Script interface for replacing anims with different ones + void Event_SetReplacementAnim(const char* animToReplace, const char* replacementAnim); + void Event_RemoveReplacementAnim(const char* animName); + void Event_LookupReplacementAnim(const char* animName); + + void Event_GetAttackFlag(int combatType); + void Event_SetAttackFlag(int combatType, int enabled); + +#ifdef TIMING_BUILD +public: + int actorGetObstaclesTimer; + int actorGetPointOutsideObstaclesTimer; + int actorGetWallEdgesTimer; + int actorSortWallEdgesTimer; + int actorBuildPathTreeTimer; + int actorPrunePathTreeTimer; + int actorFindOptimalPathTimer; + int actorRouteToGoalTimer; + int actorSubSampleWalkPathTimer; + int actorWalkPathValidTimer; +#endif +}; + +#endif /* !__GAME_ACTOR_H__ */ diff --git a/DarkMod/BinaryFrobMover.cpp b/game/BinaryFrobMover.cpp similarity index 97% rename from DarkMod/BinaryFrobMover.cpp rename to game/BinaryFrobMover.cpp index 21acdc1b3..a8d7af6e4 100644 --- a/DarkMod/BinaryFrobMover.cpp +++ b/game/BinaryFrobMover.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2004 Gerhard W. Gruber // @@ -15,11 +25,11 @@ static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" -#include "../game/ai/aas_local.h" +#include "Game_local.h" +#include "ai/AAS_local.h" #include "DarkModGlobals.h" #include "BinaryFrobMover.h" -#include "sndProp.h" +#include "SndProp.h" #include "StimResponse/StimResponse.h" //=============================================================================== @@ -1286,7 +1296,7 @@ void CBinaryFrobMover::FrobHeld(bool frobMaster, bool isFrobPeerAction, int hold m_bFineControlStarting = false; } - float dx = player->usercmd.mx - m_mousePosition.x; + //float dx = player->usercmd.mx - m_mousePosition.x; float dy = player->usercmd.my - m_mousePosition.y; m_mousePosition.x = player->usercmd.mx; m_mousePosition.y = player->usercmd.my; diff --git a/DarkMod/BinaryFrobMover.h b/game/BinaryFrobMover.h similarity index 95% rename from DarkMod/BinaryFrobMover.h rename to game/BinaryFrobMover.h index 28a67268b..3cbf08482 100644 --- a/DarkMod/BinaryFrobMover.h +++ b/game/BinaryFrobMover.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2004 Gerhard W. Gruber // diff --git a/DarkMod/BloodMarker.cpp b/game/BloodMarker.cpp similarity index 75% rename from DarkMod/BloodMarker.cpp rename to game/BloodMarker.cpp index 4ef5f8206..c7fd79d4b 100644 --- a/DarkMod/BloodMarker.cpp +++ b/game/BloodMarker.cpp @@ -1,15 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" -#include "../game/game_local.h" #pragma hdrstop + +#include "Game_local.h" #include "BloodMarker.h" #include "StimResponse/Stim.h" diff --git a/game/BloodMarker.h b/game/BloodMarker.h new file mode 100644 index 000000000..6d84d7b2d --- /dev/null +++ b/game/BloodMarker.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef BLOODMARKER_H +#define BLOODMARKER_H + +#pragma hdrstop + +#include "Entity.h" + +class CBloodMarker : public idEntity +{ +public: + CLASS_PROTOTYPE( CBloodMarker ); + +protected: + idStr _bloodSplat; + idStr _bloodSplatFading; + float _angle; + float _size; + + // True if this bloodsplat is in the process of disappearing + bool _isFading; + +public: + void Init(const idStr& splat, const idStr& splatFading, float size); + void Event_GenerateBloodSplat(); + + /** + * greebo: Overrides the OnStim method of the base class to check + * for water stims. + */ + void OnStim(const CStimPtr& stim, idEntity* stimSource); + + // Save and restore + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); +}; + +// End of header wrapper +#endif diff --git a/game/BrittleFracture.cpp b/game/BrittleFracture.cpp new file mode 100644 index 000000000..5e385f1d8 --- /dev/null +++ b/game/BrittleFracture.cpp @@ -0,0 +1,1390 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "SndProp.h" +#include "Objectives/MissionData.h" +#include "StimResponse/StimResponseCollection.h" + +const idEventDef EV_UpdateSoundLoss( "updateSoundLoss", NULL ); +const idEventDef EV_DampenSound( "dampenSound", "d" ); + +CLASS_DECLARATION( idEntity, idBrittleFracture ) + EVENT( EV_Activate, idBrittleFracture::Event_Activate ) + EVENT( EV_Touch, idBrittleFracture::Event_Touch ) + EVENT( EV_UpdateSoundLoss, idBrittleFracture::UpdateSoundLoss ) + EVENT( EV_DampenSound, idBrittleFracture::Event_DampenSound ) +END_CLASS + +const int SHARD_ALIVE_TIME = 5000; +const int SHARD_FADE_START = 2000; + +static const char *brittleFracture_SnapshotName = "_BrittleFracture_Snapshot_"; + +/* +================ +idBrittleFracture::idBrittleFracture +================ +*/ +idBrittleFracture::idBrittleFracture( void ) { + material = NULL; + decalMaterial = NULL; + decalSize = 0.0f; + maxShardArea = 0.0f; + maxShatterRadius = 0.0f; + minShatterRadius = 0.0f; + linearVelocityScale = 0.0f; + angularVelocityScale = 0.0f; + shardMass = 0.0f; + density = 0.0f; + friction = 0.0f; + bouncyness = 0.0f; + fxFracture.Clear(); + + bounds.Clear(); + disableFracture = false; + + lastRenderEntityUpdate = -1; + changed = false; + + fl.networkSync = true; + + m_AreaPortal = 0; + m_bSoundDamped = false; +} + +/* +================ +idBrittleFracture::~idBrittleFracture +================ +*/ +idBrittleFracture::~idBrittleFracture( void ) { + int i; + + for ( i = 0; i < shards.Num(); i++ ) { + shards[i]->decals.DeleteContents( true ); + delete shards[i]; + } + + // make sure the render entity is freed before the model is freed + FreeModelDef(); + renderModelManager->FreeModel( renderEntity.hModel ); +} + +/* +================ +idBrittleFracture::Save +================ +*/ +void idBrittleFracture::Save( idSaveGame *savefile ) const { + int i, j; + + savefile->WriteInt( health ); + entityFlags_s flags = fl; + + LittleBitField( &flags, sizeof( flags ) ); + + savefile->Write( &flags, sizeof( flags ) ); + + + // setttings + savefile->WriteMaterial( material ); + savefile->WriteMaterial( decalMaterial ); + savefile->WriteFloat( decalSize ); + savefile->WriteFloat( maxShardArea ); + savefile->WriteFloat( maxShatterRadius ); + savefile->WriteFloat( minShatterRadius ); + savefile->WriteFloat( linearVelocityScale ); + savefile->WriteFloat( angularVelocityScale ); + savefile->WriteFloat( shardMass ); + savefile->WriteFloat( density ); + savefile->WriteFloat( friction ); + savefile->WriteFloat( bouncyness ); + savefile->WriteString( fxFracture ); + + // state + savefile->WriteBounds( bounds ); + savefile->WriteBool( disableFracture ); + + savefile->WriteInt( lastRenderEntityUpdate ); + savefile->WriteBool( changed ); + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteInt( shards.Num() ); + for ( i = 0; i < shards.Num(); i++ ) { + savefile->WriteWinding( shards[i]->winding ); + + savefile->WriteInt( shards[i]->decals.Num() ); + for ( j = 0; j < shards[i]->decals.Num(); j++ ) { + savefile->WriteWinding( *shards[i]->decals[j] ); + } + + savefile->WriteInt( shards[i]->neighbours.Num() ); + for ( j = 0; j < shards[i]->neighbours.Num(); j++ ) { + int index = shards.FindIndex(shards[i]->neighbours[j]); + assert(index != -1); + savefile->WriteInt( index ); + } + + savefile->WriteInt( shards[i]->edgeHasNeighbour.Num() ); + for ( j = 0; j < shards[i]->edgeHasNeighbour.Num(); j++ ) { + savefile->WriteBool( shards[i]->edgeHasNeighbour[j] ); + } + + savefile->WriteInt( shards[i]->droppedTime ); + savefile->WriteInt( shards[i]->islandNum ); + savefile->WriteBool( shards[i]->atEdge ); + savefile->WriteStaticObject( shards[i]->physicsObj ); + } + + savefile->WriteInt( m_AreaPortal ); + savefile->WriteBool( m_bSoundDamped ); +} + +/* +================ +idBrittleFracture::Restore +================ +*/ +void idBrittleFracture::Restore( idRestoreGame *savefile ) { + int i, j , num; + + renderEntity.hModel = renderModelManager->AllocModel(); + renderEntity.hModel->InitEmpty( brittleFracture_SnapshotName ); + renderEntity.callback = idBrittleFracture::ModelCallback; + renderEntity.noShadow = true; + renderEntity.noSelfShadow = true; + renderEntity.noDynamicInteractions = false; + + savefile->ReadInt( health ); + savefile->Read( &fl, sizeof( fl ) ); + + // setttings + savefile->ReadMaterial( material ); + savefile->ReadMaterial( decalMaterial ); + savefile->ReadFloat( decalSize ); + savefile->ReadFloat( maxShardArea ); + savefile->ReadFloat( maxShatterRadius ); + savefile->ReadFloat( minShatterRadius ); + savefile->ReadFloat( linearVelocityScale ); + savefile->ReadFloat( angularVelocityScale ); + savefile->ReadFloat( shardMass ); + savefile->ReadFloat( density ); + savefile->ReadFloat( friction ); + savefile->ReadFloat( bouncyness ); + savefile->ReadString( fxFracture ); + + // state + savefile->ReadBounds(bounds); + savefile->ReadBool( disableFracture ); + + savefile->ReadInt( lastRenderEntityUpdate ); + savefile->ReadBool( changed ); + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadInt( num ); + shards.SetNum( num ); + for ( i = 0; i < num; i++ ) { + shards[i] = new shard_t; + } + + for ( i = 0; i < num; i++ ) { + savefile->ReadWinding( shards[i]->winding ); + + savefile->ReadInt( j ); + shards[i]->decals.SetNum( j ); + for ( j = 0; j < shards[i]->decals.Num(); j++ ) { + shards[i]->decals[j] = new idFixedWinding; + savefile->ReadWinding( *shards[i]->decals[j] ); + } + + savefile->ReadInt( j ); + shards[i]->neighbours.SetNum( j ); + for ( j = 0; j < shards[i]->neighbours.Num(); j++ ) { + int index; + savefile->ReadInt( index ); + assert(index != -1); + shards[i]->neighbours[j] = shards[index]; + } + + savefile->ReadInt( j ); + shards[i]->edgeHasNeighbour.SetNum( j ); + for ( j = 0; j < shards[i]->edgeHasNeighbour.Num(); j++ ) { + savefile->ReadBool( shards[i]->edgeHasNeighbour[j] ); + } + + savefile->ReadInt( shards[i]->droppedTime ); + savefile->ReadInt( shards[i]->islandNum ); + savefile->ReadBool( shards[i]->atEdge ); + savefile->ReadStaticObject( shards[i]->physicsObj ); + if ( shards[i]->droppedTime < 0 ) { + shards[i]->clipModel = physicsObj.GetClipModel( i ); + } else { + shards[i]->clipModel = shards[i]->physicsObj.GetClipModel(); + } + } + + savefile->ReadInt( m_AreaPortal ); + savefile->ReadBool( m_bSoundDamped ); + + UpdateSoundLoss(); +} + +/* +================ +idBrittleFracture::Spawn +================ +*/ +void idBrittleFracture::Spawn( void ) { + + // get shard properties + decalMaterial = declManager->FindMaterial( spawnArgs.GetString( "mtr_decal" ) ); + decalSize = spawnArgs.GetFloat( "decalSize", "40" ); + maxShardArea = spawnArgs.GetFloat( "maxShardArea", "200" ); + maxShardArea = idMath::ClampFloat( 100, 10000, maxShardArea ); + maxShatterRadius = spawnArgs.GetFloat( "maxShatterRadius", "40" ); + minShatterRadius = spawnArgs.GetFloat( "minShatterRadius", "10" ); + linearVelocityScale = spawnArgs.GetFloat( "linearVelocityScale", "0.1" ); + angularVelocityScale = spawnArgs.GetFloat( "angularVelocityScale", "40" ); + fxFracture = spawnArgs.GetString( "fx" ); + + // get rigid body properties + shardMass = spawnArgs.GetFloat( "shardMass", "20" ); + shardMass = idMath::ClampFloat( 0.001f, 1000.0f, shardMass ); + spawnArgs.GetFloat( "density", "0.1", density ); + density = idMath::ClampFloat( 0.001f, 1000.0f, density ); + spawnArgs.GetFloat( "friction", "0.4", friction ); + friction = idMath::ClampFloat( 0.0f, 1.0f, friction ); + spawnArgs.GetFloat( "bouncyness", "0.01", bouncyness ); + bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); + + disableFracture = spawnArgs.GetBool( "disableFracture", "0" ); + health = spawnArgs.GetInt( "health", "40" ); + fl.takedamage = true; + + // FIXME: set "bleed" so idProjectile calls AddDamageEffect + spawnArgs.SetBool( "bleed", 1 ); + + CreateFractures( renderEntity.hModel ); + + FindNeighbours(); + + renderEntity.hModel = renderModelManager->AllocModel(); + renderEntity.hModel->InitEmpty( brittleFracture_SnapshotName ); + renderEntity.callback = idBrittleFracture::ModelCallback; + renderEntity.noShadow = true; + renderEntity.noSelfShadow = true; + renderEntity.noDynamicInteractions = false; + + // Dark Mod: see if we are on a visportal + m_AreaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); + + //schedule updating the sound loss for after soundprop gameplay has initialized + PostEventMS( &EV_UpdateSoundLoss, 0 ); +} + +/* +================ +idBrittleFracture::AddShard +================ +*/ +void idBrittleFracture::AddShard( idClipModel *clipModel, idFixedWinding &w ) { + shard_t *shard = new shard_t; + shard->clipModel = clipModel; + shard->droppedTime = -1; + shard->winding = w; + shard->decals.Clear(); + shard->edgeHasNeighbour.AssureSize( w.GetNumPoints(), false ); + shard->neighbours.Clear(); + shard->atEdge = false; + shards.Append( shard ); +} + +/* +================ +idBrittleFracture::RemoveShard +================ +*/ +void idBrittleFracture::RemoveShard( int index ) { +// int i; // grayman - commented to stop compiler complaint + + delete shards[index]; + shards.RemoveIndex( index, false ); // Tels: false => don't bother to keep shards sorted + physicsObj.RemoveIndex( index, false ); + + // Tels: When we used RemoveIndex(), that might have moved some shards + // after index, so we needed to set the correct ID back to the climodel + // again. Now the RemoveIndex(index,false) routine will *only* move the + // last index back to "index", so this is the only (if it exists) shard + // that got moved, so we only need to update it's clipModel ID: + /*for ( i = index; i < shards.Num(); i++ ) { + shards[i]->clipModel->SetId( i ); + }*/ + // [0,1,2,3,4,5] (remove index == 2) => [ 0,1,5,3,4 ] + if (index < shards.Num()) + { + shards[index]->clipModel->SetId( index ); + } +} + +/* +================ +idBrittleFracture::UpdateRenderEntity +================ +*/ +bool idBrittleFracture::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const { + int i, j, k, n, msec, numTris, numDecalTris; + float fade; + dword packedColor; + srfTriangles_t *tris, *decalTris; + modelSurface_t surface; + idDrawVert *v; + idPlane plane; + idMat3 tangents; + + // this may be triggered by a model trace or other non-view related source, + // to which we should look like an empty model + if ( !renderView ) { + return false; + } + + // don't regenerate it if it is current + if ( lastRenderEntityUpdate == gameLocal.time || !changed ) { + return false; + } + + lastRenderEntityUpdate = gameLocal.time; + changed = false; + + numTris = 0; + numDecalTris = 0; + for ( i = 0; i < shards.Num(); i++ ) { + n = shards[i]->winding.GetNumPoints(); + if ( n > 2 ) { + numTris += n - 2; + } + for ( k = 0; k < shards[i]->decals.Num(); k++ ) { + n = shards[i]->decals[k]->GetNumPoints(); + if ( n > 2 ) { + numDecalTris += n - 2; + } + } + } + + // FIXME: re-use model surfaces + renderEntity->hModel->InitEmpty( brittleFracture_SnapshotName ); + + // allocate triangle surfaces for the fractures and decals + tris = renderEntity->hModel->AllocSurfaceTriangles( numTris * 3, material->ShouldCreateBackSides() ? numTris * 6 : numTris * 3 ); + decalTris = renderEntity->hModel->AllocSurfaceTriangles( numDecalTris * 3, decalMaterial->ShouldCreateBackSides() ? numDecalTris * 6 : numDecalTris * 3 ); + + for ( i = 0; i < shards.Num(); i++ ) { + const idVec3 &origin = shards[i]->clipModel->GetOrigin(); + const idMat3 &axis = shards[i]->clipModel->GetAxis(); + + fade = 1.0f; + if ( shards[i]->droppedTime >= 0 ) { + msec = gameLocal.time - shards[i]->droppedTime - SHARD_FADE_START; + if ( msec > 0 ) { + fade = 1.0f - (float) msec / ( SHARD_ALIVE_TIME - SHARD_FADE_START ); + } + } + packedColor = PackColor( idVec4( renderEntity->shaderParms[ SHADERPARM_RED ] * fade, + renderEntity->shaderParms[ SHADERPARM_GREEN ] * fade, + renderEntity->shaderParms[ SHADERPARM_BLUE ] * fade, + fade ) ); + + const idWinding &winding = shards[i]->winding; + + winding.GetPlane( plane ); + tangents = ( plane.Normal() * axis ).ToMat3(); + + for ( j = 2; j < winding.GetNumPoints(); j++ ) { + + v = &tris->verts[tris->numVerts++]; + v->Clear(); + v->xyz = origin + winding[0].ToVec3() * axis; + v->st[0] = winding[0].s; + v->st[1] = winding[0].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + v = &tris->verts[tris->numVerts++]; + v->Clear(); + v->xyz = origin + winding[j-1].ToVec3() * axis; + v->st[0] = winding[j-1].s; + v->st[1] = winding[j-1].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + v = &tris->verts[tris->numVerts++]; + v->Clear(); + v->xyz = origin + winding[j].ToVec3() * axis; + v->st[0] = winding[j].s; + v->st[1] = winding[j].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + tris->indexes[tris->numIndexes++] = tris->numVerts - 3; + tris->indexes[tris->numIndexes++] = tris->numVerts - 2; + tris->indexes[tris->numIndexes++] = tris->numVerts - 1; + + if ( material->ShouldCreateBackSides() ) { + + tris->indexes[tris->numIndexes++] = tris->numVerts - 2; + tris->indexes[tris->numIndexes++] = tris->numVerts - 3; + tris->indexes[tris->numIndexes++] = tris->numVerts - 1; + } + } + + for ( k = 0; k < shards[i]->decals.Num(); k++ ) { + const idWinding &decalWinding = *shards[i]->decals[k]; + + for ( j = 2; j < decalWinding.GetNumPoints(); j++ ) { + + v = &decalTris->verts[decalTris->numVerts++]; + v->Clear(); + v->xyz = origin + decalWinding[0].ToVec3() * axis; + v->st[0] = decalWinding[0].s; + v->st[1] = decalWinding[0].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + v = &decalTris->verts[decalTris->numVerts++]; + v->Clear(); + v->xyz = origin + decalWinding[j-1].ToVec3() * axis; + v->st[0] = decalWinding[j-1].s; + v->st[1] = decalWinding[j-1].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + v = &decalTris->verts[decalTris->numVerts++]; + v->Clear(); + v->xyz = origin + decalWinding[j].ToVec3() * axis; + v->st[0] = decalWinding[j].s; + v->st[1] = decalWinding[j].t; + v->normal = tangents[0]; + v->tangents[0] = tangents[1]; + v->tangents[1] = tangents[2]; + v->SetColor( packedColor ); + + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; + + if ( decalMaterial->ShouldCreateBackSides() ) { + + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; + decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; + } + } + } + } + + tris->tangentsCalculated = true; + decalTris->tangentsCalculated = true; + + SIMDProcessor->MinMax( tris->bounds[0], tris->bounds[1], tris->verts, tris->numVerts ); + SIMDProcessor->MinMax( decalTris->bounds[0], decalTris->bounds[1], decalTris->verts, decalTris->numVerts ); + + memset( &surface, 0, sizeof( surface ) ); + surface.shader = material; + surface.id = 0; + surface.geometry = tris; + renderEntity->hModel->AddSurface( surface ); + + memset( &surface, 0, sizeof( surface ) ); + surface.shader = decalMaterial; + surface.id = 1; + surface.geometry = decalTris; + renderEntity->hModel->AddSurface( surface ); + + return true; +} + +/* +================ +idBrittleFracture::ModelCallback +================ +*/ +bool idBrittleFracture::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) { + const idBrittleFracture *ent; + + ent = static_cast(gameLocal.entities[ renderEntity->entityNum ]); + if ( !ent ) { + gameLocal.Error( "idBrittleFracture::ModelCallback: callback with NULL game entity" ); + } + + return ent->UpdateRenderEntity( renderEntity, renderView ); +} + +/* +================ +idBrittleFracture::Present +================ +*/ +void idBrittleFracture::Present() +{ + if( m_bFrobable ) + { + UpdateFrobState(); + UpdateFrobDisplay(); + } + + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) + { + return; + } + BecomeInactive( TH_UPDATEVISUALS ); + + renderEntity.bounds = bounds; + renderEntity.origin.Zero(); + renderEntity.axis.Identity(); + + // force an update because the bounds/origin/axis may stay the same while the model changes + renderEntity.forceUpdate = true; + + // add to refresh list + if ( modelDefHandle == -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } + + changed = true; +} + +/* +================ +idBrittleFracture::Think +================ +*/ +void idBrittleFracture::Think( void ) { + int i, startTime, endTime, droppedTime; + shard_t *shard; + bool atRest = true, fading = false; + + // remove overdue shards + for ( i = 0; i < shards.Num(); i++ ) { + droppedTime = shards[i]->droppedTime; + if ( droppedTime != -1 ) { + if ( gameLocal.time - droppedTime > SHARD_ALIVE_TIME ) { + RemoveShard( i ); + i--; + } + fading = true; + } + } + + // remove the entity when nothing is visible + if ( !shards.Num() ) { + PostEventMS( &EV_Remove, 0 ); + return; + } + + if ( thinkFlags & TH_PHYSICS ) { + + startTime = gameLocal.previousTime; + endTime = gameLocal.time; + + // run physics on shards + for ( i = 0; i < shards.Num(); i++ ) { + shard = shards[i]; + + if ( shard->droppedTime == -1 ) { + continue; + } + + shard->physicsObj.Evaluate( endTime - startTime, endTime ); + + if ( !shard->physicsObj.IsAtRest() ) { + atRest = false; + } + } + + if ( atRest ) { + BecomeInactive( TH_PHYSICS ); + } else { + BecomeActive( TH_PHYSICS ); + } + } + + if ( !atRest || bounds.IsCleared() ) { + bounds.Clear(); + for ( i = 0; i < shards.Num(); i++ ) { + bounds.AddBounds( shards[i]->clipModel->GetAbsBounds() ); + } + } + + if ( fading ) { + BecomeActive( TH_UPDATEVISUALS | TH_THINK ); + } else { + BecomeInactive( TH_THINK ); + } + + RunPhysics(); + Present(); +} + +/* +================ +idBrittleFracture::ApplyImpulse +================ +*/ +void idBrittleFracture::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + + if ( id < 0 || id >= shards.Num() ) { + return; + } + + if ( shards[id]->droppedTime != -1 ) { + shards[id]->physicsObj.ApplyImpulse( 0, point, impulse ); + } else if ( health <= 0 && !disableFracture ) { + Shatter( point, impulse, gameLocal.time ); + } +} + +/* +================ +idBrittleFracture::AddForce +================ +*/ +void idBrittleFracture::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { + + if ( id < 0 || id >= shards.Num() ) { + return; + } + + if ( shards[id]->droppedTime != -1 ) { + shards[id]->physicsObj.AddForce( 0, point, force ); + } else if ( health <= 0 && !disableFracture ) { + Shatter( point, force, gameLocal.time ); + } +} + +/* +================ +idBrittleFracture::ProjectDecal +================ +*/ +void idBrittleFracture::ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName ) { + int i, j, bits, clipBits; + float a, c, s; + idVec2 st[MAX_POINTS_ON_WINDING]; + idVec3 origin; + idMat3 axis, axistemp; + idPlane textureAxis[2]; + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteFloat( point[0] ); + msg.WriteFloat( point[1] ); + msg.WriteFloat( point[2] ); + msg.WriteFloat( dir[0] ); + msg.WriteFloat( dir[1] ); + msg.WriteFloat( dir[2] ); + ServerSendEvent( EVENT_PROJECT_DECAL, &msg, true, -1 ); + } + + if ( time >= gameLocal.time ) { + // try to get the sound from the damage def + const idDeclEntityDef *damageDef = NULL; + const idSoundShader *sndShader = NULL; + if ( damageDefName ) { + damageDef = gameLocal.FindEntityDef( damageDefName, false ); + if ( damageDef ) { + sndShader = declManager->FindSound( damageDef->dict.GetString( "snd_shatter", "" ) ); + } + } + + if ( sndShader ) { + StartSoundShader( sndShader, SND_CHANNEL_ANY, 0, false, NULL ); + } else { + StartSound( "snd_bullethole", SND_CHANNEL_ANY, 0, false, NULL ); + } + } + + a = gameLocal.random.RandomFloat() * idMath::TWO_PI; + c = cos( a ); + s = -sin( a ); + + axis[2] = -dir; + axis[2].Normalize(); + axis[2].NormalVectors( axistemp[0], axistemp[1] ); + axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s; + axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c; + + textureAxis[0] = axis[0] * ( 1.0f / decalSize ); + textureAxis[0][3] = -( point * textureAxis[0].Normal() ) + 0.5f; + + textureAxis[1] = axis[1] * ( 1.0f / decalSize ); + textureAxis[1][3] = -( point * textureAxis[1].Normal() ) + 0.5f; + + for ( i = 0; i < shards.Num(); i++ ) { + idFixedWinding &winding = shards[i]->winding; + origin = shards[i]->clipModel->GetOrigin(); + axis = shards[i]->clipModel->GetAxis(); + float d0, d1; + + clipBits = -1; + for ( j = 0; j < winding.GetNumPoints(); j++ ) { + idVec3 p = origin + winding[j].ToVec3() * axis; + + st[j].x = d0 = textureAxis[0].Distance( p ); + st[j].y = d1 = textureAxis[1].Distance( p ); + + bits = FLOATSIGNBITSET( d0 ); + d0 = 1.0f - d0; + bits |= FLOATSIGNBITSET( d1 ) << 2; + d1 = 1.0f - d1; + bits |= FLOATSIGNBITSET( d0 ) << 1; + bits |= FLOATSIGNBITSET( d1 ) << 3; + + clipBits &= bits; + } + + if ( clipBits ) { + continue; + } + + idFixedWinding *decal = new idFixedWinding; + shards[i]->decals.Append( decal ); + + decal->SetNumPoints( winding.GetNumPoints() ); + for ( j = 0; j < winding.GetNumPoints(); j++ ) { + (*decal)[j].ToVec3() = winding[j].ToVec3(); + (*decal)[j].s = st[j].x; + (*decal)[j].t = st[j].y; + } + } + + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idBrittleFracture::DropShard +================ +*/ +void idBrittleFracture::DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time ) { + int i, j, clipModelId; + float dist, f; + idVec3 dir2, origin; + idMat3 axis; + shard_t *neighbour; + + // don't display decals on dropped shards + shard->decals.DeleteContents( true ); + + // remove neighbour pointers of neighbours pointing to this shard + for ( i = 0; i < shard->neighbours.Num(); i++ ) { + neighbour = shard->neighbours[i]; + for ( j = 0; j < neighbour->neighbours.Num(); j++ ) { + if ( neighbour->neighbours[j] == shard ) { + neighbour->neighbours.RemoveIndex( j ); + break; + } + } + } + + // remove neighbour pointers + shard->neighbours.Clear(); + + // remove the clip model from the static physics object + clipModelId = shard->clipModel->GetId(); + physicsObj.SetClipModel( NULL, 1.0f, clipModelId, false ); + + origin = shard->clipModel->GetOrigin(); + axis = shard->clipModel->GetAxis(); + + // set the dropped time for fading + shard->droppedTime = time; + + dir2 = origin - point; + dist = dir2.Normalize(); + f = dist > maxShatterRadius ? 1.0f : idMath::Sqrt( dist - minShatterRadius ) * ( 1.0f / idMath::Sqrt( maxShatterRadius - minShatterRadius ) ); + + // setup the physics + shard->physicsObj.SetSelf( this ); + shard->physicsObj.SetClipModel( shard->clipModel, density ); + shard->physicsObj.SetMass( shardMass ); + shard->physicsObj.SetOrigin( origin ); + shard->physicsObj.SetAxis( axis ); + shard->physicsObj.SetBouncyness( bouncyness ); + shard->physicsObj.SetFriction( 0.6f, 0.6f, friction ); + shard->physicsObj.SetGravity( gameLocal.GetGravity() ); + shard->physicsObj.SetContents( CONTENTS_RENDERMODEL ); + shard->physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); + shard->physicsObj.ApplyImpulse( 0, origin, impulse * linearVelocityScale * dir ); + shard->physicsObj.SetAngularVelocity( dir.Cross( dir2 ) * ( f * angularVelocityScale ) ); + + shard->clipModel->SetId( clipModelId ); + + BecomeActive( TH_PHYSICS ); +} + +/* +================ +idBrittleFracture::Shatter +================ +*/ +void idBrittleFracture::Shatter( const idVec3 &point, const idVec3 &impulse, const int time ) { + int i; + idVec3 dir; + shard_t *shard; + float m; + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteFloat( point[0] ); + msg.WriteFloat( point[1] ); + msg.WriteFloat( point[2] ); + msg.WriteFloat( impulse[0] ); + msg.WriteFloat( impulse[1] ); + msg.WriteFloat( impulse[2] ); + ServerSendEvent( EVENT_SHATTER, &msg, true, -1 ); + } + + if ( time > ( gameLocal.time - SHARD_ALIVE_TIME ) ) + { + if( m_bSoundDamped ) + StartSound( "snd_shatter_damped", SND_CHANNEL_ANY, 0, false, NULL ); + else + StartSound( "snd_shatter", SND_CHANNEL_ANY, 0, false, NULL ); + } + + if ( !IsBroken() ) { + Break(); + } + + if ( fxFracture.Length() ) { + idEntityFx::StartFx( fxFracture, &point, &GetPhysics()->GetAxis(), this, true ); + } + + dir = impulse; + m = dir.Normalize(); + + for ( i = 0; i < shards.Num(); i++ ) { + shard = shards[i]; + + if ( shard->droppedTime != -1 ) { + continue; + } + + if ( ( shard->clipModel->GetOrigin() - point ).LengthSqr() > Square( maxShatterRadius ) ) { + continue; + } + + DropShard( shard, point, dir, m, time ); + } + + DropFloatingIslands( point, impulse, time ); +} + +/* +================ +idBrittleFracture::DropFloatingIslands +================ +*/ +void idBrittleFracture::DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time ) { + int i, j, numIslands; + int queueStart, queueEnd; + shard_t *curShard, *nextShard, **queue; + bool touchesEdge; + idVec3 dir; + + dir = impulse; + dir.Normalize(); + + numIslands = 0; + queue = (shard_t **) _alloca16( shards.Num() * sizeof(shard_t **) ); + for ( i = 0; i < shards.Num(); i++ ) { + shards[i]->islandNum = 0; + } + + for ( i = 0; i < shards.Num(); i++ ) { + + if ( shards[i]->droppedTime != -1 ) { + continue; + } + + if ( shards[i]->islandNum ) { + continue; + } + + queueStart = 0; + queueEnd = 1; + queue[0] = shards[i]; + shards[i]->islandNum = numIslands+1; + touchesEdge = false; + + if ( shards[i]->atEdge ) { + touchesEdge = true; + } + + for ( curShard = queue[queueStart]; queueStart < queueEnd; curShard = queue[++queueStart] ) { + + for ( j = 0; j < curShard->neighbours.Num(); j++ ) { + + nextShard = curShard->neighbours[j]; + + if ( nextShard->droppedTime != -1 ) { + continue; + } + + if ( nextShard->islandNum ) { + continue; + } + + queue[queueEnd++] = nextShard; + nextShard->islandNum = numIslands+1; + + if ( nextShard->atEdge ) { + touchesEdge = true; + } + } + } + numIslands++; + + // if the island is not connected to the world at any edges + if ( !touchesEdge ) { + for ( j = 0; j < queueEnd; j++ ) { + DropShard( queue[j], point, dir, 0.0f, time ); + } + } + } +} + +/* +================ +idBrittleFracture::Break +================ +*/ +void idBrittleFracture::Break( void ) { + fl.takedamage = false; + physicsObj.SetContents( CONTENTS_RENDERMODEL ); + + // ishtvan: overwrite with custom contents if present + if( m_CustomContents != -1 ) + physicsObj.SetContents( m_CustomContents ); + + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_TRIGGER ); + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + UpdateSoundLoss(); +} + +/* +================ +idBrittleFracture::IsBroken +================ +*/ +bool idBrittleFracture::IsBroken( void ) const { + return ( fl.takedamage == false ); +} + +/* +================ +idBrittleFracture::Killed +================ +*/ +void idBrittleFracture::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) +{ + bool bPlayerResponsible(false); + + if ( !disableFracture ) { + ActivateTargets( this ); + Break(); + } + + if ( attacker && attacker->IsType( idPlayer::Type ) ) + bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); + else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) + bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); + + gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); +} + +/* +================ +idBrittleFracture::AddDamageEffect +================ +*/ +void idBrittleFracture::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { + if ( !disableFracture ) { + ProjectDecal( collision.c.point, collision.c.normal, gameLocal.time, damageDefName ); + } +} + +/* +================ +idBrittleFracture::Fracture_r +================ +*/ +void idBrittleFracture::Fracture_r( idFixedWinding &w ) { + int i, j, bestPlane; + float a, c, s, dist, bestDist; + idVec3 origin; + idPlane windingPlane, splitPlanes[2]; + idMat3 axis, axistemp; + idFixedWinding back; + idTraceModel trm; + idClipModel *clipModel; + + while( 1 ) { + origin = w.GetCenter(); + w.GetPlane( windingPlane ); + + if ( w.GetArea() < maxShardArea ) { + break; + } + + // randomly create a split plane + a = gameLocal.random.RandomFloat() * idMath::TWO_PI; + c = cos( a ); + s = -sin( a ); + axis[2] = windingPlane.Normal(); + axis[2].NormalVectors( axistemp[0], axistemp[1] ); + axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s; + axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c; + + // get the best split plane + bestDist = 0.0f; + bestPlane = 0; + for ( i = 0; i < 2; i++ ) { + splitPlanes[i].SetNormal( axis[i] ); + splitPlanes[i].FitThroughPoint( origin ); + for ( j = 0; j < w.GetNumPoints(); j++ ) { + dist = splitPlanes[i].Distance( w[j].ToVec3() ); + if ( dist > bestDist ) { + bestDist = dist; + bestPlane = i; + } + } + } + + // split the winding + if ( !w.Split( &back, splitPlanes[bestPlane] ) ) { + break; + } + + // recursively create shards for the back winding + Fracture_r( back ); + } + + // translate the winding to it's center + origin = w.GetCenter(); + for ( j = 0; j < w.GetNumPoints(); j++ ) { + w[j].ToVec3() -= origin; + } + w.RemoveEqualPoints(); + + trm.SetupPolygon( w ); + trm.Shrink( CM_CLIP_EPSILON ); + clipModel = new idClipModel( trm ); + + physicsObj.SetClipModel( clipModel, 1.0f, shards.Num() ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() + origin, shards.Num() ); + physicsObj.SetAxis( GetPhysics()->GetAxis(), shards.Num() ); + + AddShard( clipModel, w ); +} + +/* +================ +idBrittleFracture::CreateFractures +================ +*/ +void idBrittleFracture::CreateFractures( const idRenderModel *renderModel ) { + int i, j, k; + const modelSurface_t *surf; + const idDrawVert *v; + idFixedWinding w; + + if ( !renderModel ) { + return; + } + + physicsObj.SetSelf( this ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin(), 0 ); + physicsObj.SetAxis( GetPhysics()->GetAxis(), 0 ); + + for ( i = 0; i < 1 /*renderModel->NumSurfaces()*/; i++ ) { + surf = renderModel->Surface( i ); + material = surf->shader; + + for ( j = 0; j < surf->geometry->numIndexes; j += 3 ) { + w.Clear(); + for ( k = 0; k < 3; k++ ) { + v = &surf->geometry->verts[ surf->geometry->indexes[ j + 2 - k ] ]; + w.AddPoint( v->xyz ); + w[k].s = v->st[0]; + w[k].t = v->st[1]; + } + Fracture_r( w ); + } + } + + physicsObj.SetContents( material->GetContentFlags() ); + // ishtvan: overwrite with custom contents if present + if( m_CustomContents != -1 ) + physicsObj.SetContents( m_CustomContents ); + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + SetPhysics( &physicsObj ); +} + +/* +================ +idBrittleFracture::FindNeighbours +================ +*/ +void idBrittleFracture::FindNeighbours( void ) { + int i, j, k, l; + idVec3 p1, p2, dir; + idMat3 axis; + idPlane plane[4]; + + for ( i = 0; i < shards.Num(); i++ ) { + + shard_t *shard1 = shards[i]; + const idWinding &w1 = shard1->winding; + const idVec3 &origin1 = shard1->clipModel->GetOrigin(); + const idMat3 &axis1 = shard1->clipModel->GetAxis(); + + for ( k = 0; k < w1.GetNumPoints(); k++ ) { + + p1 = origin1 + w1[k].ToVec3() * axis1; + p2 = origin1 + w1[(k+1)%w1.GetNumPoints()].ToVec3() * axis1; + dir = p2 - p1; + dir.Normalize(); + axis = dir.ToMat3(); + + plane[0].SetNormal( dir ); + plane[0].FitThroughPoint( p1 ); + plane[1].SetNormal( -dir ); + plane[1].FitThroughPoint( p2 ); + plane[2].SetNormal( axis[1] ); + plane[2].FitThroughPoint( p1 ); + plane[3].SetNormal( axis[2] ); + plane[3].FitThroughPoint( p1 ); + + for ( j = 0; j < shards.Num(); j++ ) { + + if ( i == j ) { + continue; + } + + shard_t *shard2 = shards[j]; + + for ( l = 0; l < shard1->neighbours.Num(); l++ ) { + if ( shard1->neighbours[l] == shard2 ) { + break; + } + } + if ( l < shard1->neighbours.Num() ) { + continue; + } + + const idWinding &w2 = shard2->winding; + const idVec3 &origin2 = shard2->clipModel->GetOrigin(); + const idMat3 &axis2 = shard2->clipModel->GetAxis(); + + for ( l = w2.GetNumPoints()-1; l >= 0; l-- ) { + p1 = origin2 + w2[l].ToVec3() * axis2; + p2 = origin2 + w2[(l-1+w2.GetNumPoints())%w2.GetNumPoints()].ToVec3() * axis2; + if ( plane[0].Side( p2, 0.1f ) == SIDE_FRONT && plane[1].Side( p1, 0.1f ) == SIDE_FRONT ) { + if ( plane[2].Side( p1, 0.1f ) == SIDE_ON && plane[3].Side( p1, 0.1f ) == SIDE_ON ) { + if ( plane[2].Side( p2, 0.1f ) == SIDE_ON && plane[3].Side( p2, 0.1f ) == SIDE_ON ) { + shard1->neighbours.Append( shard2 ); + shard1->edgeHasNeighbour[k] = true; + shard2->neighbours.Append( shard1 ); + shard2->edgeHasNeighbour[(l-1+w2.GetNumPoints())%w2.GetNumPoints()] = true; + break; + } + } + } + } + } + } + + for ( k = 0; k < w1.GetNumPoints(); k++ ) { + if ( !shard1->edgeHasNeighbour[k] ) { + break; + } + } + if ( k < w1.GetNumPoints() ) { + shard1->atEdge = true; + } else { + shard1->atEdge = false; + } + } +} + +/* +================ +idBrittleFracture::Event_Activate +================ +*/ +void idBrittleFracture::Event_Activate( idEntity *activator ) { + disableFracture = false; + if ( health <= 0 ) { + Break(); + } +} + +/* +================ +idBrittleFracture::Event_Touch +================ +*/ +void idBrittleFracture::Event_Touch( idEntity *other, trace_t *trace ) { + idVec3 point, impulse; + + if ( !IsBroken() ) { + return; + } + + if ( trace->c.id < 0 || trace->c.id >= shards.Num() ) { + return; + } + + point = shards[trace->c.id]->clipModel->GetOrigin(); + impulse = other->GetPhysics()->GetLinearVelocity() * other->GetPhysics()->GetMass(); + + Shatter( point, impulse, gameLocal.time ); +} + +/* +================ +idBrittleFracture::Event_DampenSound +================ +*/ +void idBrittleFracture::Event_DampenSound( bool bDampen ) +{ + m_bSoundDamped = bDampen; +} + +/* +================ +idBrittleFracture::ClientPredictionThink +================ +*/ +void idBrittleFracture::ClientPredictionThink( void ) { + // only think forward because the state is not synced through snapshots + if ( !gameLocal.isNewFrame ) { + return; + } + + Think(); +} + +/* +================ +idBrittleFracture::ClientReceiveEvent +================ +*/ +bool idBrittleFracture::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + idVec3 point, dir; + + switch( event ) { + case EVENT_PROJECT_DECAL: { + point[0] = msg.ReadFloat(); + point[1] = msg.ReadFloat(); + point[2] = msg.ReadFloat(); + dir[0] = msg.ReadFloat(); + dir[1] = msg.ReadFloat(); + dir[2] = msg.ReadFloat(); + ProjectDecal( point, dir, time, NULL ); + return true; + } + case EVENT_SHATTER: { + point[0] = msg.ReadFloat(); + point[1] = msg.ReadFloat(); + point[2] = msg.ReadFloat(); + dir[0] = msg.ReadFloat(); + dir[1] = msg.ReadFloat(); + dir[2] = msg.ReadFloat(); + Shatter( point, dir, time ); + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +================ +idBrittleFracture::UpdateSoundLoss (Dark Mod ) +================ +*/ +void idBrittleFracture::UpdateSoundLoss( void ) +{ + float SetVal(0.0f); + + if ( !m_AreaPortal ) + goto Quit; + + if( IsBroken() ) + SetVal = spawnArgs.GetFloat( "loss_broken", "0.0"); + else + SetVal = spawnArgs.GetFloat( "loss_unbroken", "15.0"); + + gameLocal.m_sndProp->SetPortalLoss( m_AreaPortal, SetVal ); + +Quit: + return; +} + diff --git a/game/BrittleFracture.h b/game/BrittleFracture.h new file mode 100644 index 000000000..f75918eef --- /dev/null +++ b/game/BrittleFracture.h @@ -0,0 +1,140 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_BRITTLEFRACTURE_H__ +#define __GAME_BRITTLEFRACTURE_H__ + + +/* +=============================================================================== + +B-rep Brittle Fracture - Static entity using the boundary representation +of the render model which can fracture. + +=============================================================================== +*/ + +extern const idEventDef EV_UpdateSoundLoss; +extern const idEventDef EV_DampenSound; + +typedef struct shard_s { + idClipModel * clipModel; + idFixedWinding winding; + idList decals; + idList edgeHasNeighbour; + idList neighbours; + idPhysics_RigidBody physicsObj; + int droppedTime; + bool atEdge; + int islandNum; +} shard_t; + + +class idBrittleFracture : public idEntity { + +public: + CLASS_PROTOTYPE( idBrittleFracture ); + + idBrittleFracture( void ); + virtual ~idBrittleFracture( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + + virtual void Present( void ); + virtual void Think( void ); + virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); + virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + + void ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName ); + bool IsBroken( void ) const; + + enum { + EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS, + EVENT_SHATTER, + EVENT_MAXEVENTS + }; + + virtual void ClientPredictionThink( void ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + +private: + // setttings + const idMaterial * material; + const idMaterial * decalMaterial; + float decalSize; + float maxShardArea; + float maxShatterRadius; + float minShatterRadius; + float linearVelocityScale; + float angularVelocityScale; + float shardMass; + float density; + float friction; + float bouncyness; + idStr fxFracture; + + // state + idPhysics_StaticMulti physicsObj; + idList shards; + idBounds bounds; + bool disableFracture; + + /** TDM: Moss arrow dampens sound of shattering **/ + bool m_bSoundDamped; + + // for rendering + mutable int lastRenderEntityUpdate; + mutable bool changed; + + /** + * Contains the visportal handle that the breakable is touching, if portal is present + * If no portal is present, is set to 0. + **/ + qhandle_t m_AreaPortal; + + bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const; + static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); + + void AddShard( idClipModel *clipModel, idFixedWinding &w ); + void RemoveShard( int index ); + void DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time ); + void Shatter( const idVec3 &point, const idVec3 &impulse, const int time ); + void DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time ); + void Break( void ); + void Fracture_r( idFixedWinding &w ); + void CreateFractures( const idRenderModel *renderModel ); + void FindNeighbours( void ); + + void Event_Activate( idEntity *activator ); + void Event_Touch( idEntity *other, trace_t *trace ); + void Event_DampenSound( bool bDampen ); + + /** + * Update soundprop to set losses in associated portal, if portal is present + * Called on spawn and when it breaks + **/ + void UpdateSoundLoss( void ); +}; + +#endif /* !__GAME_BRITTLEFRACTURE_H__ */ diff --git a/game/ButtonStateTracker.cpp b/game/ButtonStateTracker.cpp new file mode 100644 index 000000000..850c4ae3a --- /dev/null +++ b/game/ButtonStateTracker.cpp @@ -0,0 +1,94 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "ButtonStateTracker.h" + +ButtonStateTracker::ButtonStateTracker(idPlayer* owner) : + _owner(owner), + _lastCheckTime(0) +{} + +void ButtonStateTracker::Update() +{ + int timeSinceLastCheck = gameLocal.time - _lastCheckTime; + + if (timeSinceLastCheck == 0) return; // no double-checking in the same frame + + //DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Updating button states\r"); + for (ButtonHoldTimeMap::iterator i = _buttons.begin(); i != _buttons.end(); /* in-loop increment */) + { + int impulse = i->first; + + if (common->ButtonState(KEY_FROM_IMPULSE(impulse))) + { + // Key is still held down, increase the hold time + i->second += timeSinceLastCheck; + + _owner->PerformKeyRepeat(impulse, i->second); + + // Increase the iterator + ++i; + } + else + { + int holdTime = i->second + timeSinceLastCheck; + + // Delete the impulse from the map, and increase the iterator immediately afterwards + _buttons.erase(i++); + + // Notify the player class about the keyrelease event + _owner->PerformKeyRelease(impulse, holdTime); + } + } + + // Remember the last time the buttons have been checked + _lastCheckTime = gameLocal.time; +} + +void ButtonStateTracker::StartTracking(int impulse) +{ + DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Impulse registered for tracking: %d\r", impulse); + // Initialise the given impulse with a hold time of zero + _buttons[impulse] = 0; + + if (_lastCheckTime == 0) + { + // Initialise the last check time, as it is 0 up to now + _lastCheckTime = gameLocal.time; + } +} + +bool ButtonStateTracker::ButtonIsHeld(int impulse) +{ + return (common->ButtonState(KEY_FROM_IMPULSE(impulse)) != 0); +} + +void ButtonStateTracker::StopTracking(int impulse) +{ + ButtonHoldTimeMap::iterator i = _buttons.find(impulse); + + if (i != _buttons.end()) + { + _buttons.erase(i); + } +} diff --git a/game/ButtonStateTracker.h b/game/ButtonStateTracker.h new file mode 100644 index 000000000..b173ab364 --- /dev/null +++ b/game/ButtonStateTracker.h @@ -0,0 +1,80 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_BUTTON_STATE_TRACKER_H__ +#define __GAME_BUTTON_STATE_TRACKER_H__ + +#include + +/** +* greebo: The ButtonStateTracker is a helper class keeping track +* of certain buttons. As soon as a tracked button is released, +* this calls the method PerformButtonRelease() on the idPlayer class. +* +* Use the StartTracking() method to register an impulse for tracking. +*/ + +// Forward declaration +class idPlayer; + +class ButtonStateTracker +{ + // The class that is going to be notified on button release + idPlayer* _owner; + + // ButtonTimeTable: maps buttons => hold time + typedef std::map ButtonHoldTimeMap; + + ButtonHoldTimeMap _buttons; + + int _lastCheckTime; + +public: + // Constructor, pass the owning, to-be-notified entity here + ButtonStateTracker(idPlayer* owner); + + /** + * greebo: Call this from the Think() method so that + * this class can update the state of the tracked buttons. + */ + void Update(); + + /** + * greebo: Register an impulse for tracking to consider it + * during the update() routine. Released buttons get + * automatically de-registered, so no stopTracking() call is needed. + */ + void StartTracking(int impulse); + + /** + * greebo: Returns TRUE if the given impulse button is currently + * held down by the user, FALSE otherwise. + */ + bool ButtonIsHeld(int impulse); + + /** + * greebo: De-register an impulse for tracking. Calling this method + * does not trigger a PerformKeyReleased() event on the player, + * so this is more or less a "cancellation". + */ + void StopTracking(int impulse); + +}; // class ButtonStateTracker + +#endif /* __GAME_BUTTON_STATE_TRACKER_H__ */ diff --git a/DarkMod/CImage.cpp b/game/CImage.cpp similarity index 88% rename from DarkMod/CImage.cpp rename to game/CImage.cpp index f43f4219e..9432a26d8 100644 --- a/DarkMod/CImage.cpp +++ b/game/CImage.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/CImage.h b/game/CImage.h similarity index 78% rename from DarkMod/CImage.h rename to game/CImage.h index 3e6c5a60d..1f82804f6 100644 --- a/DarkMod/CImage.h +++ b/game/CImage.h @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef DARKMODCIMAGE_H #define DARKMODCIMAGE_H #if defined(__linux__) || defined(MACOS_X) -#include "idlib/lib.h" -#include "sound/sound.h" +#include "../idlib/Lib.h" +#include "../sound/sound.h" #endif #include diff --git a/game/Camera.cpp b/game/Camera.cpp new file mode 100644 index 000000000..a599b383c --- /dev/null +++ b/game/Camera.cpp @@ -0,0 +1,712 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +=============================================================================== + + idCamera + + Base class for cameras + +=============================================================================== +*/ + +ABSTRACT_DECLARATION( idEntity, idCamera ) +END_CLASS + +/* +===================== +idCamera::Spawn +===================== +*/ +void idCamera::Spawn( void ) { +} + +/* +===================== +idCamera::GetRenderView +===================== +*/ +renderView_t *idCamera::GetRenderView() { + renderView_t *rv = idEntity::GetRenderView(); + GetViewParms( rv ); + return rv; +} + +/*********************************************************************** + + idCameraView + +***********************************************************************/ +const idEventDef EV_Camera_SetAttachments( "", NULL ); + +CLASS_DECLARATION( idCamera, idCameraView ) + EVENT( EV_Activate, idCameraView::Event_Activate ) + EVENT( EV_Camera_SetAttachments, idCameraView::Event_SetAttachments ) +END_CLASS + + +/* +=============== +idCameraView::idCameraView +================ +*/ +idCameraView::idCameraView() { + fov = 90.0f; + attachedTo = NULL; + attachedView = NULL; +} + +/* +=============== +idCameraView::Save +================ +*/ +void idCameraView::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( fov ); + savefile->WriteObject( attachedTo ); + savefile->WriteObject( attachedView ); +} + +/* +=============== +idCameraView::Restore +================ +*/ +void idCameraView::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( fov ); + savefile->ReadObject( reinterpret_cast( attachedTo ) ); + savefile->ReadObject( reinterpret_cast( attachedView ) ); +} + +/* +=============== +idCameraView::Event_SetAttachments +================ +*/ +void idCameraView::Event_SetAttachments( ) { + SetAttachment( &attachedTo, "attachedTo" ); + SetAttachment( &attachedView, "attachedView" ); +} + +/* +=============== +idCameraView::Event_Activate +================ +*/ +void idCameraView::Event_Activate( idEntity *activator ) { + if (spawnArgs.GetBool("trigger")) { + if (gameLocal.GetCamera() != this) { + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() ); + } + + gameLocal.SetCamera(this); + } else { + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); + } + gameLocal.SetCamera(NULL); + } + } +} + +/* +===================== +idCameraView::Stop +===================== +*/ +void idCameraView::Stop( void ) { + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); + } + gameLocal.SetCamera(NULL); + ActivateTargets( gameLocal.GetLocalPlayer() ); +} + + +/* +===================== +idCameraView::Spawn +===================== +*/ +void idCameraView::SetAttachment( idEntity **e, const char *p ) { + const char *cam = spawnArgs.GetString( p ); + if ( strlen ( cam ) ) { + *e = gameLocal.FindEntity( cam ); + } +} + + +/* +===================== +idCameraView::Spawn +===================== +*/ +void idCameraView::Spawn( void ) { + // if no target specified use ourself + const char *cam = spawnArgs.GetString("cameraTarget"); + if ( strlen ( cam ) == 0) { + spawnArgs.Set("cameraTarget", spawnArgs.GetString("name")); + } + fov = spawnArgs.GetFloat("fov", "90"); + + PostEventMS( &EV_Camera_SetAttachments, 0 ); + + UpdateChangeableSpawnArgs(NULL); +} + +/* +===================== +idCameraView::GetViewParms +===================== +*/ +void idCameraView::GetViewParms( renderView_t *view ) { + assert( view ); + + if (view == NULL) { + return; + } + + idVec3 dir; + idEntity *ent; + + if ( attachedTo ) { + ent = attachedTo; + } else { + ent = this; + } + + view->vieworg = ent->GetPhysics()->GetOrigin(); + if ( attachedView ) { + dir = attachedView->GetPhysics()->GetOrigin() - view->vieworg; + dir.Normalize(); + view->viewaxis = dir.ToMat3(); + } else { + view->viewaxis = ent->GetPhysics()->GetAxis(); + } + + gameLocal.CalcFov( fov, view->fov_x, view->fov_y ); +} + +/* +=============================================================================== + + idCameraAnim + +=============================================================================== +*/ + +const idEventDef EV_Camera_Start( "start", NULL ); +const idEventDef EV_Camera_Stop( "stop", NULL ); + +CLASS_DECLARATION( idCamera, idCameraAnim ) + EVENT( EV_Thread_SetCallback, idCameraAnim::Event_SetCallback ) + EVENT( EV_Camera_Stop, idCameraAnim::Event_Stop ) + EVENT( EV_Camera_Start, idCameraAnim::Event_Start ) + EVENT( EV_Activate, idCameraAnim::Event_Activate ) +END_CLASS + + +/* +===================== +idCameraAnim::idCameraAnim +===================== +*/ +idCameraAnim::idCameraAnim() { + threadNum = 0; + offset.Zero(); + frameRate = 0; + cycle = 1; + starttime = 0; + activator = NULL; + +} + +/* +===================== +idCameraAnim::~idCameraAnim +===================== +*/ +idCameraAnim::~idCameraAnim() { + if ( gameLocal.GetCamera() == this ) { + gameLocal.SetCamera( NULL ); + } +} + +/* +=============== +idCameraAnim::Save +================ +*/ +void idCameraAnim::Save( idSaveGame *savefile ) const { + savefile->WriteInt( threadNum ); + savefile->WriteVec3( offset ); + savefile->WriteInt( frameRate ); + savefile->WriteInt( starttime ); + savefile->WriteInt( cycle ); + activator.Save( savefile ); +} + +/* +=============== +idCameraAnim::Restore +================ +*/ +void idCameraAnim::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( threadNum ); + savefile->ReadVec3( offset ); + savefile->ReadInt( frameRate ); + savefile->ReadInt( starttime ); + savefile->ReadInt( cycle ); + activator.Restore( savefile ); + + LoadAnim(); +} + +/* +===================== +idCameraAnim::Spawn +===================== +*/ +void idCameraAnim::Spawn( void ) { + if ( spawnArgs.GetVector( "old_origin", "0 0 0", offset ) ) { + offset = GetPhysics()->GetOrigin() - offset; + } else { + offset.Zero(); + } + + // always think during cinematics + cinematic = true; + + LoadAnim(); +} + +/* +================ +idCameraAnim::Load +================ +*/ +void idCameraAnim::LoadAnim( void ) { + int version; + idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT ); + idToken token; + int numFrames; + int numCuts; + int i; + idStr filename; + const char *key; + + key = spawnArgs.GetString( "anim" ); + if ( !key ) { + gameLocal.Error( "Missing 'anim' key on '%s'", name.c_str() ); + } + + filename = spawnArgs.GetString( va( "anim %s", key ) ); + if ( !filename.Length() ) { + gameLocal.Error( "Missing 'anim %s' key on '%s'", key, name.c_str() ); + } + + filename.SetFileExtension( MD5_CAMERA_EXT ); + if ( !parser.LoadFile( filename ) ) { + gameLocal.Error( "Unable to load '%s' on '%s'", filename.c_str(), name.c_str() ); + } + + cameraCuts.Clear(); + cameraCuts.SetGranularity( 1 ); + camera.Clear(); + camera.SetGranularity( 1 ); + + parser.ExpectTokenString( MD5_VERSION_STRING ); + version = parser.ParseInt(); + if ( version != MD5_VERSION ) { + parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); + } + + // skip the commandline + parser.ExpectTokenString( "commandline" ); + parser.ReadToken( &token ); + + // parse num frames + parser.ExpectTokenString( "numFrames" ); + numFrames = parser.ParseInt(); + if ( numFrames <= 0 ) { + parser.Error( "Invalid number of frames: %d", numFrames ); + } + + // parse framerate + parser.ExpectTokenString( "frameRate" ); + frameRate = parser.ParseInt(); + if ( frameRate <= 0 ) { + parser.Error( "Invalid framerate: %d", frameRate ); + } + + // parse num cuts + parser.ExpectTokenString( "numCuts" ); + numCuts = parser.ParseInt(); + if ( ( numCuts < 0 ) || ( numCuts > numFrames ) ) { + parser.Error( "Invalid number of camera cuts: %d", numCuts ); + } + + // parse the camera cuts + parser.ExpectTokenString( "cuts" ); + parser.ExpectTokenString( "{" ); + cameraCuts.SetNum( numCuts ); + for( i = 0; i < numCuts; i++ ) { + cameraCuts[ i ] = parser.ParseInt(); + if ( ( cameraCuts[ i ] < 1 ) || ( cameraCuts[ i ] >= numFrames ) ) { + parser.Error( "Invalid camera cut" ); + } + } + parser.ExpectTokenString( "}" ); + + // parse the camera frames + parser.ExpectTokenString( "camera" ); + parser.ExpectTokenString( "{" ); + camera.SetNum( numFrames ); + for( i = 0; i < numFrames; i++ ) { + parser.Parse1DMatrix( 3, camera[ i ].t.ToFloatPtr() ); + parser.Parse1DMatrix( 3, camera[ i ].q.ToFloatPtr() ); + camera[ i ].fov = parser.ParseFloat(); + } + parser.ExpectTokenString( "}" ); + +#if 0 + if ( !gameLocal.GetLocalPlayer() ) { + return; + } + + idDebugGraph gGraph; + idDebugGraph tGraph; + idDebugGraph qGraph; + idDebugGraph dtGraph; + idDebugGraph dqGraph; + gGraph.SetNumSamples( numFrames ); + tGraph.SetNumSamples( numFrames ); + qGraph.SetNumSamples( numFrames ); + dtGraph.SetNumSamples( numFrames ); + dqGraph.SetNumSamples( numFrames ); + + gameLocal.Printf( "\n\ndelta vec:\n" ); + float diff_t, last_t, t; + float diff_q, last_q, q; + diff_t = last_t = 0.0f; + diff_q = last_q = 0.0f; + for( i = 1; i < numFrames; i++ ) { + t = ( camera[ i ].t - camera[ i - 1 ].t ).Length(); + q = ( camera[ i ].q.ToQuat() - camera[ i - 1 ].q.ToQuat() ).Length(); + diff_t = t - last_t; + diff_q = q - last_q; + gGraph.AddValue( ( i % 10 ) == 0 ); + tGraph.AddValue( t ); + qGraph.AddValue( q ); + dtGraph.AddValue( diff_t ); + dqGraph.AddValue( diff_q ); + + gameLocal.Printf( "%d: %.8f : %.8f, %.8f : %.8f\n", i, t, diff_t, q, diff_q ); + last_t = t; + last_q = q; + } + + gGraph.Draw( colorBlue, 300.0f ); + tGraph.Draw( colorOrange, 60.0f ); + dtGraph.Draw( colorYellow, 6000.0f ); + qGraph.Draw( colorGreen, 60.0f ); + dqGraph.Draw( colorCyan, 6000.0f ); +#endif +} + +/* +=============== +idCameraAnim::Start +================ +*/ +void idCameraAnim::Start( void ) { + cycle = spawnArgs.GetInt( "cycle" ); + if ( !cycle ) { + cycle = 1; + } + + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() ); + } + + starttime = gameLocal.time; + gameLocal.SetCamera( this ); + BecomeActive( TH_THINK ); + + // if the player has already created the renderview for this frame, have him update it again so that the camera starts this frame + if ( gameLocal.GetLocalPlayer()->GetRenderView()->time == gameLocal.time ) { + gameLocal.GetLocalPlayer()->CalculateRenderView(); + } +} + +/* +===================== +idCameraAnim::Stop +===================== +*/ +void idCameraAnim::Stop( void ) { + if ( gameLocal.GetCamera() == this ) { + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); + } + + BecomeInactive( TH_THINK ); + gameLocal.SetCamera( NULL ); + if ( threadNum ) { + idThread::ObjectMoveDone( threadNum, this ); + threadNum = 0; + } + ActivateTargets( activator.GetEntity() ); + } +} + +/* +===================== +idCameraAnim::Think +===================== +*/ +void idCameraAnim::Think( void ) { + int frame; + int frameTime; + + if ( thinkFlags & TH_THINK ) { + // check if we're done in the Think function when the cinematic is being skipped (idCameraAnim::GetViewParms isn't called when skipping cinematics). + if ( !gameLocal.skipCinematic ) { + return; + } + + if ( camera.Num() < 2 ) { + // 1 frame anims never end + return; + } + + if ( frameRate == USERCMD_HZ ) { + frameTime = gameLocal.time - starttime; + frame = frameTime / gameLocal.msec; + } else { + frameTime = ( gameLocal.time - starttime ) * frameRate; + frame = frameTime / 1000; + } + + if ( frame > camera.Num() + cameraCuts.Num() - 2 ) { + if ( cycle > 0 ) { + cycle--; + } + + if ( cycle != 0 ) { + // advance start time so that we loop + starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate; + } else { + Stop(); + } + } + } +} + +/* +===================== +idCameraAnim::GetViewParms +===================== +*/ +void idCameraAnim::GetViewParms( renderView_t *view ) { + int realFrame; + int frame; + int frameTime; + float lerp; + float invlerp; + cameraFrame_t *camFrame; + int i; + int cut; + idQuat q1, q2, q3; + + assert( view ); + if ( !view ) { + return; + } + + if ( camera.Num() == 0 ) { + // we most likely are in the middle of a restore + // FIXME: it would be better to fix it so this doesn't get called during a restore + return; + } + + if ( frameRate == USERCMD_HZ ) { + frameTime = gameLocal.time - starttime; + frame = frameTime / gameLocal.msec; + lerp = 0.0f; + } else { + frameTime = ( gameLocal.time - starttime ) * frameRate; + frame = frameTime / 1000; + lerp = ( frameTime % 1000 ) * 0.001f; + } + + // skip any frames where camera cuts occur + realFrame = frame; + cut = 0; + for( i = 0; i < cameraCuts.Num(); i++ ) { + if ( frame < cameraCuts[ i ] ) { + break; + } + frame++; + cut++; + } + + if ( g_debugCinematic.GetBool() ) { + int prevFrameTime = ( gameLocal.time - starttime - gameLocal.msec ) * frameRate; + int prevFrame = prevFrameTime / 1000; + int prevCut; + + prevCut = 0; + for( i = 0; i < cameraCuts.Num(); i++ ) { + if ( prevFrame < cameraCuts[ i ] ) { + break; + } + prevFrame++; + prevCut++; + } + + if ( prevCut != cut ) { + gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut ); + } + } + + // clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately, + // but since they're mainly used for static cams anyway, just stay on it infinitely. + if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) { + view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3(); + view->vieworg = camera[ 0 ].t + offset; + view->fov_x = camera[ 0 ].fov; + } else if ( frame > camera.Num() - 2 ) { + if ( cycle > 0 ) { + cycle--; + } + + if ( cycle != 0 ) { + // advance start time so that we loop + starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate; + GetViewParms( view ); + return; + } + + Stop(); + if ( gameLocal.GetCamera() != NULL ) { + // we activated another camera when we stopped, so get it's viewparms instead + gameLocal.GetCamera()->GetViewParms( view ); + return; + } else { + // just use our last frame + camFrame = &camera[ camera.Num() - 1 ]; + view->viewaxis = camFrame->q.ToQuat().ToMat3(); + view->vieworg = camFrame->t + offset; + view->fov_x = camFrame->fov; + } + } else if ( lerp == 0.0f ) { + camFrame = &camera[ frame ]; + view->viewaxis = camFrame[ 0 ].q.ToMat3(); + view->vieworg = camFrame[ 0 ].t + offset; + view->fov_x = camFrame[ 0 ].fov; + } else { + camFrame = &camera[ frame ]; + invlerp = 1.0f - lerp; + q1 = camFrame[ 0 ].q.ToQuat(); + q2 = camFrame[ 1 ].q.ToQuat(); + q3.Slerp( q1, q2, lerp ); + view->viewaxis = q3.ToMat3(); + view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset; + view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp; + } + + gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y ); + + // setup the pvs for this frame + UpdatePVSAreas( view->vieworg ); + +#if 0 + static int lastFrame = 0; + static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f ); + if ( gameLocal.time != lastFrame ) { + gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, gameLocal.msec ); + gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); + gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false ); + gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false ); + gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); + lastFrameVec = view->vieworg; + lastFrame = gameLocal.time; + } +#endif + + if ( g_showcamerainfo.GetBool() ) { + gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() ); + } +} + +/* +=============== +idCameraAnim::Event_Activate +================ +*/ +void idCameraAnim::Event_Activate( idEntity *_activator ) { + activator = _activator; + if ( thinkFlags & TH_THINK ) { + Stop(); + } else { + Start(); + } +} + +/* +=============== +idCameraAnim::Event_Start +================ +*/ +void idCameraAnim::Event_Start( void ) { + Start(); +} + +/* +=============== +idCameraAnim::Event_Stop +================ +*/ +void idCameraAnim::Event_Stop( void ) { + Stop(); +} + +/* +================ +idCameraAnim::Event_SetCallback +================ +*/ +void idCameraAnim::Event_SetCallback( void ) { + if ( ( gameLocal.GetCamera() == this ) && !threadNum ) { + threadNum = idThread::CurrentThreadNum(); + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} diff --git a/game/Camera.h b/game/Camera.h new file mode 100644 index 000000000..f5d0c740d --- /dev/null +++ b/game/Camera.h @@ -0,0 +1,123 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_CAMERA_H__ +#define __GAME_CAMERA_H__ + + +/* +=============================================================================== + +Camera providing an alternative view of the level. + +=============================================================================== +*/ + +class idCamera : public idEntity { +public: + ABSTRACT_PROTOTYPE( idCamera ); + + void Spawn( void ); + virtual void GetViewParms( renderView_t *view ) = 0; + virtual renderView_t * GetRenderView(); + virtual void Stop( void ){} ; +}; + +/* +=============================================================================== + +idCameraView + +=============================================================================== +*/ + +class idCameraView : public idCamera { +public: + CLASS_PROTOTYPE( idCameraView ); + idCameraView(); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void Spawn( ); + virtual void GetViewParms( renderView_t *view ); + virtual void Stop( void ); + +protected: + void Event_Activate( idEntity *activator ); + void Event_SetAttachments(); + void SetAttachment( idEntity **e, const char *p ); + float fov; + idEntity *attachedTo; + idEntity *attachedView; +}; + + + +/* +=============================================================================== + +A camera which follows a path defined by an animation. + +=============================================================================== +*/ + +typedef struct { + idCQuat q; + idVec3 t; + float fov; +} cameraFrame_t; + +class idCameraAnim : public idCamera { +public: + CLASS_PROTOTYPE( idCameraAnim ); + + idCameraAnim(); + ~idCameraAnim(); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void Spawn( void ); + virtual void GetViewParms( renderView_t *view ); + +private: + int threadNum; + idVec3 offset; + int frameRate; + int starttime; + int cycle; + idList cameraCuts; + idList camera; + idEntityPtr activator; + + void Start( void ); + void Stop( void ); + void Think( void ); + + void LoadAnim( void ); + void Event_Start( void ); + void Event_Stop( void ); + void Event_SetCallback( void ); + void Event_Activate( idEntity *activator ); +}; + +#endif /* !__GAME_CAMERA_H__ */ diff --git a/DarkMod/DarkModGlobals.cpp b/game/DarkModGlobals.cpp similarity index 97% rename from DarkMod/DarkModGlobals.cpp rename to game/DarkModGlobals.cpp index 7bc6b2539..643990a9a 100644 --- a/DarkMod/DarkModGlobals.cpp +++ b/game/DarkModGlobals.cpp @@ -5,14 +5,24 @@ /* */ /******************************************************************************/ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -22,11 +32,11 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "DarkModGlobals.h" -#include "sndPropLoader.h" -#include "sndProp.h" +#include "SndPropLoader.h" +#include "SndProp.h" #include "Relations.h" #include "ModMenu.h" -#include "../game/ai/ai.h" +#include "ai/AI.h" #include "sourcehook/sourcehook.h" #include "sourcehook/sourcehook_impl.h" #include "RevisionTracker.h" diff --git a/DarkMod/DarkModGlobals.h b/game/DarkModGlobals.h similarity index 92% rename from DarkMod/DarkModGlobals.h rename to game/DarkModGlobals.h index d04fa36cf..b0d9cb4db 100644 --- a/DarkMod/DarkModGlobals.h +++ b/game/DarkModGlobals.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /******************************************************************************/ /* */ /* DarkModGlobals (C) by Gerhard W. Gruber in Germany 2004 */ @@ -25,8 +35,8 @@ #define DARKMODGLOBALS_H #include -#include "../game/game_local.h" -#include "../DarkMod/CImage.h" +#include "Game_local.h" +#include "CImage.h" // greebo: Defines the darkmod release version #define TDM_VERSION_MAJOR 1 @@ -46,7 +56,7 @@ VersionCheckResult CompareVersion(int major, int minor, int toMajor, int toMinor /*! Darkmod LAS */ -#include "../DarkMod/darkModLAS.h" +#include "darkModLAS.h" #include class IniFile; diff --git a/DarkMod/DarkmodAASHidingSpotFinder.cpp b/game/DarkmodAASHidingSpotFinder.cpp similarity index 98% rename from DarkMod/DarkmodAASHidingSpotFinder.cpp rename to game/DarkmodAASHidingSpotFinder.cpp index b6a798635..53835c50e 100644 --- a/DarkMod/DarkmodAASHidingSpotFinder.cpp +++ b/game/DarkmodAASHidingSpotFinder.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/DarkmodAASHidingSpotFinder.h b/game/DarkmodAASHidingSpotFinder.h similarity index 94% rename from DarkMod/DarkmodAASHidingSpotFinder.h rename to game/DarkmodAASHidingSpotFinder.h index 13a1b444e..144dcad3e 100644 --- a/DarkMod/DarkmodAASHidingSpotFinder.h +++ b/game/DarkmodAASHidingSpotFinder.h @@ -1,21 +1,31 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once // Required includes -#include "../game/ai/aas.h" -#include "../game/pvs.h" -#include "../game/game_local.h" -#include "../game/entity.h" -#include "../DarkMod/PVSToAASMapping.h" -#include "../DarkMod/darkmodHidingSpotTree.h" +#include "../game/ai/AAS.h" +#include "../game/Pvs.h" +#include "../game/Game_local.h" +#include "../game/Entity.h" +#include "PVSToAASMapping.h" +#include "darkmodHidingSpotTree.h" /*! * This defines hiding spot characteristics as bit flags diff --git a/DarkMod/DifficultyManager.cpp b/game/DifficultyManager.cpp similarity index 90% rename from DarkMod/DifficultyManager.cpp rename to game/DifficultyManager.cpp index b9b71b38c..41a34eb1d 100644 --- a/DarkMod/DifficultyManager.cpp +++ b/game/DifficultyManager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/DifficultyManager.h b/game/DifficultyManager.h similarity index 81% rename from DarkMod/DifficultyManager.h rename to game/DifficultyManager.h index 71e25c49e..09e493e6d 100644 --- a/DarkMod/DifficultyManager.h +++ b/game/DifficultyManager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef DIFFICULTY_MANAGER_H #define DIFFICULTY_MANAGER_H diff --git a/DarkMod/DifficultySettings.cpp b/game/DifficultySettings.cpp similarity index 95% rename from DarkMod/DifficultySettings.cpp rename to game/DifficultySettings.cpp index f10c08129..a4a042cad 100644 --- a/DarkMod/DifficultySettings.cpp +++ b/game/DifficultySettings.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/DifficultySettings.h b/game/DifficultySettings.h similarity index 86% rename from DarkMod/DifficultySettings.h rename to game/DifficultySettings.h index d9ee8fcb2..dc376e04c 100644 --- a/DarkMod/DifficultySettings.h +++ b/game/DifficultySettings.h @@ -1,3 +1,22 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + #ifndef __DIFFICULTY_SETTINGS_H__ #define __DIFFICULTY_SETTINGS_H__ diff --git a/DarkMod/DownloadMenu.cpp b/game/DownloadMenu.cpp similarity index 96% rename from DarkMod/DownloadMenu.cpp rename to game/DownloadMenu.cpp index 09332e3b4..65180f58f 100644 --- a/DarkMod/DownloadMenu.cpp +++ b/game/DownloadMenu.cpp @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -// Copyright (C) 2004 Id Software, Inc. -// - +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -134,7 +141,7 @@ void CDownloadMenu::HandleCommands(const idStr& cmd, idUserInterface* gui) gameLocal.Printf("Connection Error.\n"); GuiMessage msg; - msg.title = gameLocal.m_I18N->Translate( "#str_02138" ); // "Mission Screenshot Download Failed" + msg.title = gameLocal.m_I18N->Translate( "#str_02002" ); // "Connection Error" msg.message = gameLocal.m_I18N->Translate( "#str_02139" ); // "Failed to download the screenshot file." msg.type = GuiMessage::MSG_OK; msg.okCmd = "close_msg_box"; @@ -210,7 +217,7 @@ void CDownloadMenu::HandleCommands(const idStr& cmd, idUserInterface* gui) gameLocal.m_I18N->Translate("#str_04353") : // Campaign gameLocal.m_I18N->Translate("#str_04352")); // Single Mission gui->SetStateString("av_mission_version", va("%d", mods[missionIndex]->version)); - gui->SetStateString("av_mission_size", va("%0.1f %s", mods[missionIndex]->sizeMB, gameLocal.m_I18N->Translate( "#str_02015" ))); // MB + gui->SetStateString("av_mission_size", va("%0.1f %s", mods[missionIndex]->sizeMB, gameLocal.m_I18N->Translate( "#str_02055" ))); // MB gui->SetStateBool("av_mission_details_visible", true); @@ -481,7 +488,7 @@ void CDownloadMenu::UpdateModDetails(idUserInterface* gui) gui->SetStateString("av_mission_author", mods[modIndex]->author); gui->SetStateString("av_mission_release_date", mods[modIndex]->releaseDate); gui->SetStateString("av_mission_version", va("%d", mods[modIndex]->version)); - gui->SetStateString("av_mission_size", va("%0.1f %s", mods[modIndex]->sizeMB, gameLocal.m_I18N->Translate( "#str_02015" ))); // MB + gui->SetStateString("av_mission_size", va("%0.1f %s", mods[modIndex]->sizeMB, gameLocal.m_I18N->Translate( "#str_02055" ))); // MB gui->SetStateString("av_mission_description", mods[modIndex]->description); } diff --git a/game/DownloadMenu.h b/game/DownloadMenu.h new file mode 100644 index 000000000..71a49bb58 --- /dev/null +++ b/game/DownloadMenu.h @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _DOWNLOAD_MENU_H_ +#define _DOWNLOAD_MENU_H_ + +#include +#include + +// Handles mainmenu that displays list of downloadable mods/PK4 files +class CDownloadMenu +{ +private: + // The index of the first displayed mod + int _availListTop; + int _selectedListTop; + + idList _selectedMods; + + /** + * greebo: Since mission l10n packs are stored separately, a mission + * transfer can consist of several downloads. + */ + struct MissionDownload + { + int missionDownloadId; // Download ID of the actual mission pack + int l10nPackDownloadId; // Download ID of the L10n Pack, is -1 by default + + MissionDownload() : + missionDownloadId(-1), + l10nPackDownloadId(-1) + {} + + MissionDownload(int missionDownloadId_, int l10nPackDownloadId_ = -1) : + missionDownloadId(missionDownloadId_), + l10nPackDownloadId(l10nPackDownloadId_) + {} + }; + + // A mapping "selected mod id" => download info + typedef std::map ActiveDownloads; + ActiveDownloads _downloads; + +public: + CDownloadMenu(); + + // handles main menu commands + void HandleCommands(const idStr& cmd, idUserInterface* gui); + + // updates the GUI variables + void UpdateGUI(idUserInterface* gui); + +private: + void StartDownload(idUserInterface* gui); + + void UpdateDownloadProgress(idUserInterface* gui); + + void ShowDownloadResult(idUserInterface* gui); + + void UpdateModDetails(idUserInterface* gui); + + void PerformScreenshotStep(idUserInterface* gui, int step); + + void UpdateNextScreenshotData(idUserInterface* gui, int nextScreenshotNum); + void UpdateScreenshotItemVisibility(idUserInterface* gui); + + idStr GetMissionDownloadProgressString(int modIndex); +}; +typedef boost::shared_ptr CDownloadMenuPtr; + +#endif /* _DOWNLOAD_MENU_H_ */ diff --git a/game/Emitter.cpp b/game/Emitter.cpp new file mode 100644 index 000000000..2c6de5327 --- /dev/null +++ b/game/Emitter.cpp @@ -0,0 +1,468 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* + Copyright (C) 2004 Id Software, Inc. + Copyright (C) 2011 The Dark Mod + +func_emitters - have one or more particle models + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Emitter.h" + +const idEventDef EV_EmitterAddModel( "emitterAddModel", "sv" ); +const idEventDef EV_EmitterGetNumModels( "emitterGetNumModels", NULL, 'f' ); + +CLASS_DECLARATION( idStaticEntity, idFuncEmitter ) + EVENT( EV_Activate, idFuncEmitter::Event_Activate ) + EVENT( EV_EmitterAddModel, idFuncEmitter::Event_EmitterAddModel ) + EVENT( EV_EmitterGetNumModels, idFuncEmitter::Event_EmitterGetNumModels ) +END_CLASS + +/* +=============== +idFuncEmitter::idFuncEmitter +=============== +*/ +idFuncEmitter::idFuncEmitter( void ) { + hidden = false; + m_LODHandle = 0; + + m_models.Clear(); +} + +/* +================ +idFuncEmitter::~idFuncEmitter +================ +*/ +idFuncEmitter::~idFuncEmitter( void ) { + + const int num = m_models.Num(); + for (int i = 0; i < num; i++ ) + { + if ( m_models[i].defHandle != -1 ) + { + gameRenderWorld->FreeEntityDef( m_models[i].defHandle ); + m_models[i].defHandle = -1; + } + } + m_models.Clear(); +} + +/* +================ +idFuncEmitter::SetModel for additional models +================ +*/ +void idFuncEmitter::SetModel( int id, const idStr &modelName, const idVec3 &offset ) { + + m_models.AssureSize( id+1 ); + m_models[id].defHandle = -1; + m_models[id].offset = offset; + m_models[id].flags = 0; + m_models[id].handle = renderModelManager->FindModel( modelName ); + if (spawnArgs.GetString("model") != modelName) + { + // differs + m_models[id].name = modelName; + } + else + { + // store "" to flag as "same as the original model" + m_models[id].name = ""; + } + + // need to call Present() the next time we Think(): + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idFuncEmitter::SetModel for LOD change +================ +*/ +void idFuncEmitter::SetModel( const char* modelName ) +{ + if ( modelDefHandle > 0 ) + { + gameRenderWorld->FreeEntityDef( modelDefHandle ); + } + modelDefHandle = -1; + spawnArgs.Set("model", modelName); + + idRenderModel * modelHandle = renderModelManager->FindModel( modelName ); + + // go through all other models and change them + const int num = m_models.Num(); + for (int i = 0; i < num; i++ ) { + if ( m_models[i].name.IsEmpty()) + { + // same as original model, so change it, too + if ( m_models[i].defHandle != -1 ) + { + gameRenderWorld->FreeEntityDef( m_models[0].defHandle ); + } + m_models[i].defHandle = -1; + m_models[i].handle = modelHandle; + } + // else: leave it alone + } + + // need to call Present() the next time we Think(): + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idFuncEmitter::Present +================ +*/ +void idFuncEmitter::Present( void ) +{ + if( m_bFrobable ) + { + UpdateFrobState(); + UpdateFrobDisplay(); + } + + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) + { + return; + } + BecomeInactive( TH_UPDATEVISUALS ); + + // present the first model + renderEntity.origin = GetPhysics()->GetOrigin(); + renderEntity.axis = GetPhysics()->GetAxis(); + renderEntity.hModel = renderModelManager->FindModel( spawnArgs.GetString("model") ); + + renderEntity.bodyId = 0; + // make each of them have a unique timeoffset, so they do not appear to be in sync + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time - gameLocal.random.RandomInt( 32767 ) ); + + if ( renderEntity.hModel ) { + renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); + // add to refresh list + if ( modelDefHandle == -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } + } + else { + // don't present the model if it is non-existant + renderEntity.bounds.Zero(); + } + // TODO: add to the bounds above the bounds of the other models + + // present additional models to the renderer + const int num = m_models.Num(); +// gameLocal.Printf("%s: Have %i models\n", GetName(), num + 1); + for (int i = 0; i < num; i++ ) { + + if ( !m_models[i].handle ) { + continue; + } + + if ( (m_models[i].flags & 1) != 0) + { + // is invisible, ignore it + continue; + } +// gameLocal.Printf("%s: Presenting model %i\n", GetName(), i); + renderEntity.origin = GetPhysics()->GetOrigin() + m_models[i].offset; + renderEntity.axis = GetPhysics()->GetAxis(); + renderEntity.hModel = m_models[i].handle; + renderEntity.bodyId = i + 1; + // make each of them have a unique timeoffset, so they do not appear to be in sync + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time - gameLocal.random.RandomInt( 32767 ) ); + + if ( renderEntity.hModel ) { + renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); + // add to refresh list + if ( m_models[i].defHandle == -1 ) { + m_models[i].defHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( m_models[i].defHandle, &renderEntity ); + } + } + else { + renderEntity.bounds.Zero(); + } + } +} + +/* +=============== +idFuncEmitter::Spawn +=============== +*/ +void idFuncEmitter::Spawn( void ) { + const idKeyValue *kv; + + if ( spawnArgs.GetBool( "start_off" ) ) { + hidden = true; + renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( 1 ); + UpdateVisuals(); + } else { + hidden = false; + } + + // check if we have additional models + kv = spawnArgs.MatchPrefix( "model", NULL ); + int model = 0; + while( kv ) + { + idStr suffix = kv->GetKey(); + idStr modelName = kv->GetValue(); + if ((suffix.Length() >= 9 && suffix.Cmpn("model_lod",9) == 0) || suffix == "model") + { + // ignore "model_lod_2" as well as "model" + kv = spawnArgs.MatchPrefix( "model", kv ); + continue; + } + suffix = suffix.Right( suffix.Length() - 5); // model_2 => "_2" + if (!spawnArgs.FindKey("offset" + suffix)) + { + gameLocal.Warning("FuncEmitter %s: 'offset%s' is undefined and will clash at origin.", GetName(), suffix.c_str() ); + } + idVec3 modelOffset = spawnArgs.GetVector( "offset" + suffix, "0,0,0" ); +// gameLocal.Printf( "FuncEmitter %s: Adding model %i ('%s') at offset %s (suffix %s).\n", GetName(), model, modelName.c_str(), modelOffset.ToString(), suffix.c_str() ); + SetModel( model++, modelName, modelOffset ); + kv = spawnArgs.MatchPrefix( "model", kv ); + } + if (model > 0) + { + gameLocal.Printf( "FuncEmitter %s: Added %i additional emitters.\n", GetName(), model ); + } +} + +/* +=============== +idFuncEmitter::Save +=============== +*/ +void idFuncEmitter::Save( idSaveGame *savefile ) const { + savefile->WriteBool( hidden ); + + const int num = m_models.Num(); + savefile->WriteInt( num ); + for (int i = 0; i < num; i++ ) { + savefile->WriteInt( m_models[i].defHandle ); + savefile->WriteVec3( m_models[i].offset ); + savefile->WriteString( m_models[i].name ); + savefile->WriteInt( m_models[i].flags ); + } +} + +/* +================ +idFuncEmitter::Think +================ +*/ +void idFuncEmitter::Think( void ) +{ + // will also do LOD thinking: + idEntity::Think(); + + // extra models? Do LOD thinking for them: + const int num = m_models.Num(); + // start with 1 +/* for (int i = 1; i < num; i++) + { + // TODO: + } +*/ + // did our model(s) change? + Present(); +} + +/* +=============== +idFuncEmitter::Restore +=============== +*/ +void idFuncEmitter::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( hidden ); + int num; + savefile->ReadInt( num ); + + idStr defaultModelName = spawnArgs.GetString("model"); + + m_models.Clear(); + m_models.SetNum(num); + for (int i = 0; i < num; i++ ) { + savefile->ReadInt( m_models[i].defHandle ); + savefile->ReadVec3( m_models[i].offset ); + savefile->ReadString( m_models[i].name ); + savefile->ReadInt( m_models[i].flags ); + + // find the modelHandle + idStr modelName = m_models[i].name; + if (modelName.IsEmpty()) + { + modelName = defaultModelName; + } + m_models[i].handle = renderModelManager->FindModel( modelName ); + } + BecomeActive( TH_UPDATEVISUALS ); +} + +/* + **************** Events **************************************** +*/ + +/* +================ +idFuncEmitter::Event_Activate +================ +*/ +void idFuncEmitter::Event_Activate( idEntity *activator ) { + if ( hidden || spawnArgs.GetBool( "cycleTrigger" ) ) { + renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = 0; + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + hidden = false; + } else { + renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time ); + hidden = true; + } + UpdateVisuals(); +} + +/* +================ +idFuncEmitter::Event_EmitterGetNumModels +================ +*/ +void idFuncEmitter::Event_EmitterGetNumModels( void ) const { + idThread::ReturnFloat( m_models.Num() + 1 ); +} + +/* +================ +idFuncEmitter::Event_EmitterAddModel +================ +*/ +void idFuncEmitter::Event_EmitterAddModel( idStr const &modelName, idVec3 const &modelOffset ) { + + SetModel( m_models.Num(), modelName, modelOffset ); +} + + + +/* +================ +idFuncEmitter::WriteToSnapshot +================ +*/ +void idFuncEmitter::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteBits( hidden ? 1 : 0, 1 ); + msg.WriteFloat( renderEntity.shaderParms[ SHADERPARM_PARTICLE_STOPTIME ] ); + msg.WriteFloat( renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] ); + // TODO: additinal models +} + +/* +================ +idFuncEmitter::ReadFromSnapshot +================ +*/ +void idFuncEmitter::ReadFromSnapshot( const idBitMsgDelta &msg ) { + hidden = msg.ReadBits( 1 ) != 0; + renderEntity.shaderParms[ SHADERPARM_PARTICLE_STOPTIME ] = msg.ReadFloat(); + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = msg.ReadFloat(); + // TODO: additinal models + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + + +/* +=============================================================================== + +idFuncSplat + +=============================================================================== +*/ + + +const idEventDef EV_Splat( "" ); +CLASS_DECLARATION( idFuncEmitter, idFuncSplat ) +EVENT( EV_Activate, idFuncSplat::Event_Activate ) +EVENT( EV_Splat, idFuncSplat::Event_Splat ) +END_CLASS + +/* +=============== +idFuncSplat::idFuncSplat +=============== +*/ +idFuncSplat::idFuncSplat( void ) { +} + +/* +=============== +idFuncSplat::Spawn +=============== +*/ +void idFuncSplat::Spawn( void ) { +} + +/* +================ +idFuncSplat::Event_Splat +================ +*/ +void idFuncSplat::Event_Splat( void ) { + const char *splat = NULL; + int count = spawnArgs.GetInt( "splatCount", "1" ); + for ( int i = 0; i < count; i++ ) { + splat = spawnArgs.RandomPrefix( "mtr_splat", gameLocal.random ); + if ( splat && *splat ) { + float size = spawnArgs.GetFloat( "splatSize", "128" ); + float dist = spawnArgs.GetFloat( "splatDistance", "128" ); + float angle = spawnArgs.GetFloat( "splatAngle", "0" ); + gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[2], dist, true, size, splat, angle ); + } + } + StartSound( "snd_splat", SND_CHANNEL_ANY, 0, false, NULL ); +} + +/* +================ +idFuncSplat::Event_Activate +================ +*/ +void idFuncSplat::Event_Activate( idEntity *activator ) { + idFuncEmitter::Event_Activate( activator ); + PostEventSec( &EV_Splat, spawnArgs.GetFloat( "splatDelay", "0.25" ) ); + StartSound( "snd_spurt", SND_CHANNEL_ANY, 0, false, NULL ); +} + + diff --git a/game/Emitter.h b/game/Emitter.h new file mode 100644 index 000000000..c1e2ddabc --- /dev/null +++ b/game/Emitter.h @@ -0,0 +1,106 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// Copyright (C) 2011 The Dark Mod + +#ifndef __GAME_TDM_EMITTER_H__ +#define __GAME_TDM_EMITTER_H__ + +#include "Misc.h" + +/* +=============================================================================== + +idFuncEmitter + +=============================================================================== +*/ + +/** Defines additional data for emitters with more than one particle */ +typedef struct { + int defHandle; + idVec3 offset; + idRenderModel * handle; + idStr name; // empty when this model equals the first model + int flags; // 0 => visible, 1 => hidden +} emitter_models_t; + +class idFuncEmitter : public idStaticEntity { +public: + CLASS_PROTOTYPE( idFuncEmitter ); + + idFuncEmitter( void ); + ~idFuncEmitter( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + void Event_Activate( idEntity *activator ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + virtual void Think( void ); + virtual void Present( void ); + + // switch to a new model + virtual void SetModel( const char *modelname ); + + // public events + void Event_EmitterGetNumModels( void ) const; + void Event_EmitterAddModel( idStr const &modelName, idVec3 const &modelOffset ); + +protected: + + // add an extra model + void SetModel( int id, const idStr &modelName, const idVec3 &offset ); + +private: + bool hidden; + + idList m_models; //! struct with data for additional models +}; + +/* +=============================================================================== + +idFuncSplat + +=============================================================================== +*/ + +class idFuncSplat : public idFuncEmitter { +public: + CLASS_PROTOTYPE( idFuncSplat ); + + idFuncSplat( void ); + + void Spawn( void ); + +private: + void Event_Activate( idEntity *activator ); + void Event_Splat(); +}; + + +#endif /* !__GAME_TDM_EMITTER_H__ */ + diff --git a/game/Entity.cpp b/game/Entity.cpp new file mode 100644 index 000000000..ddce9e8a7 --- /dev/null +++ b/game/Entity.cpp @@ -0,0 +1,12242 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#pragma warning(disable : 4533 4800) + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "declxdata.h" +#include "Objectives/MissionData.h" +#include "Objectives/ObjectiveLocation.h" +#include "Grabber.h" +#include "SndProp.h" +#include "StimResponse/StimResponseCollection.h" +#include "Inventory/Inventory.h" +#include "Inventory/Cursor.h" +#include "AbsenceMarker.h" +#include "Objectives/MissionData.h" + +/* +=============================================================================== + + idEntity + +=============================================================================== +*/ + +// TDM uses entity shaderparm 11 to control frob highlight state +#define FROB_SHADERPARM 11 + +// constant to disable LOD temp. Must be smaller than 1000 * (distcheckperiod + 2) +#define NOLOD -100000 + +// overridable events +const idEventDef EV_PostSpawn( "", NULL ); +const idEventDef EV_FindTargets( "", NULL ); +const idEventDef EV_Touch( "", "et" ); +const idEventDef EV_GetName( "getName", NULL, 's' ); +const idEventDef EV_SetName( "setName", "s" ); +const idEventDef EV_IsType ( "isType", "s" , 'd' ); +const idEventDef EV_Activate( "activate", "e" ); +const idEventDef EV_ActivateTargets( "activateTargets", "e" ); +const idEventDef EV_AddTarget( "addTarget", "e" ); +const idEventDef EV_RemoveTarget( "removeTarget", "e" ); +const idEventDef EV_NumTargets( "numTargets", NULL, 'f' ); +const idEventDef EV_GetTarget( "getTarget", "f", 'e' ); +const idEventDef EV_RandomTarget( "randomTarget", "s", 'e' ); +const idEventDef EV_Bind( "bind", "e" ); +const idEventDef EV_BindPosition( "bindPosition", "e" ); +const idEventDef EV_BindToJoint( "bindToJoint", "esf" ); +const idEventDef EV_BindToBody( "bindToBody", "edd" ); +const idEventDef EV_GetBindMaster( "getBindMaster", NULL, 'e' ); +const idEventDef EV_NumBindChildren( "numBindChildren", NULL, 'd' ); +const idEventDef EV_GetBindChild( "getBindChild", "d", 'e' ); +const idEventDef EV_Unbind( "unbind", NULL ); +const idEventDef EV_RemoveBinds( "removeBinds" ); +const idEventDef EV_SpawnBind( "", NULL ); +const idEventDef EV_SetOwner( "setOwner", "e" ); +const idEventDef EV_SetModel( "setModel", "s" ); +const idEventDef EV_SetSkin( "setSkin", "s" ); +const idEventDef EV_GetWorldOrigin( "getWorldOrigin", NULL, 'v' ); +const idEventDef EV_SetWorldOrigin( "setWorldOrigin", "v" ); +const idEventDef EV_GetOrigin( "getOrigin", NULL, 'v' ); +const idEventDef EV_SetOrigin( "setOrigin", "v" ); +const idEventDef EV_GetAngles( "getAngles", NULL, 'v' ); +const idEventDef EV_SetAngles( "setAngles", "v" ); +const idEventDef EV_GetLinearVelocity( "getLinearVelocity", NULL, 'v' ); +const idEventDef EV_SetLinearVelocity( "setLinearVelocity", "v" ); +const idEventDef EV_GetAngularVelocity( "getAngularVelocity", NULL, 'v' ); +const idEventDef EV_SetAngularVelocity( "setAngularVelocity", "v" ); +// greebo: Accessor events for the clipmask/contents flags +const idEventDef EV_SetContents( "setContents", "f" ); +const idEventDef EV_GetContents( "getContents", NULL, 'f' ); +const idEventDef EV_SetClipMask( "setClipMask", "d" ); +const idEventDef EV_GetClipMask( "getClipMask", NULL, 'd' ); + +const idEventDef EV_GetSize( "getSize", NULL, 'v' ); +const idEventDef EV_SetSize( "setSize", "vv" ); +const idEventDef EV_GetMins( "getMins", NULL, 'v' ); +const idEventDef EV_GetMaxs( "getMaxs", NULL, 'v' ); +const idEventDef EV_IsHidden( "isHidden", NULL, 'd' ); +const idEventDef EV_Hide( "hide", NULL ); +const idEventDef EV_Show( "show", NULL ); +const idEventDef EV_Touches( "touches", "E", 'd' ); +const idEventDef EV_ClearSignal( "clearSignal", "d" ); +const idEventDef EV_GetShaderParm( "getShaderParm", "d", 'f' ); +const idEventDef EV_SetShaderParm( "setShaderParm", "df" ); +const idEventDef EV_SetShaderParms( "setShaderParms", "ffff" ); +const idEventDef EV_SetColor( "setColor", "fff" ); +const idEventDef EV_GetColor( "getColor", NULL, 'v' ); +const idEventDef EV_CacheSoundShader( "cacheSoundShader", "s" ); +const idEventDef EV_StartSoundShader( "startSoundShader", "sd", 'f' ); +const idEventDef EV_StartSound( "startSound", "sdd", 'f' ); +const idEventDef EV_StopSound( "stopSound", "dd" ); +const idEventDef EV_FadeSound( "fadeSound", "dff" ); +const idEventDef EV_SetSoundVolume( "setSoundVolume", "f" ); +const idEventDef EV_GetNextKey( "getNextKey", "ss", 's' ); +const idEventDef EV_SetKey( "setKey", "ss" ); +const idEventDef EV_GetKey( "getKey", "s", 's' ); +const idEventDef EV_GetIntKey( "getIntKey", "s", 'f' ); +const idEventDef EV_GetFloatKey( "getFloatKey", "s", 'f' ); +const idEventDef EV_GetVectorKey( "getVectorKey", "s", 'v' ); +const idEventDef EV_GetEntityKey( "getEntityKey", "s", 'e' ); +const idEventDef EV_RemoveKey( "removeKey", "s" ); +const idEventDef EV_RestorePosition( "restorePosition" ); +const idEventDef EV_UpdateCameraTarget( "", NULL ); +const idEventDef EV_DistanceTo( "distanceTo", "E", 'f' ); +const idEventDef EV_DistanceToPoint( "distanceToPoint", "v", 'f' ); +const idEventDef EV_StartFx( "startFx", "s" ); +const idEventDef EV_HasFunction( "hasFunction", "s", 'd' ); +const idEventDef EV_CallFunction( "callFunction", "s" ); +const idEventDef EV_CallGlobalFunction( "callGlobalFunction", "sE" ); +const idEventDef EV_SetNeverDormant( "setNeverDormant", "d" ); + +// greebo: Extinguishes all lights (i.e. the entity plus all bound lights) +const idEventDef EV_ExtinguishLights("extinguishLights", NULL); + +const idEventDef EV_InPVS( "inPVS", NULL, 'd' ); +// greebo: Script event definition for dealing damage +const idEventDef EV_Damage("damage", "EEvsf"); +// greebo: Script event definition for healing +// Takes the name of the healing entity and the healing scale, returns an integer +const idEventDef EV_Heal("heal", "sf", 'd'); + +// tels: Teleport the entity to the position/orientation of the given entity +const idEventDef EV_TeleportTo("teleportTo", "e"); + +// ishtvan: Get/setd droppable on entity and associated inventory item +const idEventDef EV_IsDroppable( "isDroppable", NULL, 'd' ); +const idEventDef EV_SetDroppable( "setDroppable", "d" ); + +// tels: set noShadow on this entity to the given argument (true/false) +const idEventDef EV_NoShadows( "noShadows", "d" ); + +// tels: Find all lights in the player PVS, then returns their sum. +const idEventDef EV_GetLightInPVS("getLightInPVS", "ff", 'v'); + +const idEventDef EV_GetVinePlantLoc("getVinePlantLoc", NULL, 'v'); // grayman #2787 +const idEventDef EV_GetVinePlantNormal("getVinePlantNormal", NULL, 'v'); // grayman #2787 +const idEventDef EV_IsLight("isLight", NULL, 'd'); // grayman #2905 + +//=============================================================== +// TDM GUI interface +//=============================================================== +const idEventDef EV_SetGui( "setGui", "ds" ); +const idEventDef EV_GetGui( "getGui", "d", 's' ); +const idEventDef EV_SetGuiString( "setGuiString", "dss" ); +const idEventDef EV_GetGuiString( "getGuiString", "ds", 's' ); +const idEventDef EV_SetGuiFloat( "setGuiFloat", "dsf" ); +const idEventDef EV_GetGuiFloat( "getGuiFloat", "ds", 'f' ); +const idEventDef EV_SetGuiInt( "setGuiInt", "dsd" ); +const idEventDef EV_GetGuiInt( "getGuiInt", "ds", 'f' ); +const idEventDef EV_SetGuiStringFromKey( "setGuiStringFromKey", "dses" ); +const idEventDef EV_CallGui( "callGui", "ds" ); +const idEventDef EV_CreateOverlay( "createOverlay", "sd", 'd' ); +const idEventDef EV_DestroyOverlay( "destroyOverlay", "d" ); +const idEventDef EV_LoadExternalData( "loadExternalData", "ss", 'd' ); + + +//=============================================================== +// TDM Inventory +//=============================================================== +const idEventDef EV_GetLootAmount("getLootAmount", "d", 'd'); // returns the current value for the given group +const idEventDef EV_ChangeLootAmount("changeLootAmount", "dd", 'd'); // Changes the loot amount of the given group by the given amount, returns the new amount of that type +const idEventDef EV_AddInvItem("addInvItem", "e"); // Adds an entity to the inventory +const idEventDef EV_AddItemToInv("addItemToInv", "e"); // Adds this entity to the inventory of the given entity (reversed AddInvItem) +const idEventDef EV_ReplaceInvItem("replaceInvItem", "eE", 'd'); // olditem, newitem -> 1 if succeeded +const idEventDef EV_GetNextInvItem("getNextInvItem", "", 'e'); // switches to the next inventory item +const idEventDef EV_GetPrevInvItem("getPrevInvItem", "", 'e'); // switches to the previous inventory item +const idEventDef EV_ChangeInvItemCount("changeInvItemCount", "ssd"); // Changes the stack count (call with "inv_name", "inv_category" and amount) +const idEventDef EV_ChangeInvLightgemModifier("changeInvLightgemModifier", "ssd"); // Changes the lightgem modifier value of the given item. +const idEventDef EV_ChangeInvIcon("changeInvIcon", "sss"); // Changes the inventory icon of the given item. + +const idEventDef EV_SetCurInvCategory("setCurInvCategory", "s", 'd'); // category name -> 1 = success +const idEventDef EV_SetCurInvItem("setCurInvItem", "s", 'e'); // itemname -> entity +const idEventDef EV_GetCurInvCategory("getCurInvCategory", NULL, 's'); +const idEventDef EV_GetCurInvItemEntity("getCurInvItemEntity", NULL, 'e'); +const idEventDef EV_GetCurInvItemName("getCurInvItemName", NULL, 's'); +const idEventDef EV_GetCurInvItemId("getCurInvItemId", NULL, 's'); +const idEventDef EV_GetCurInvIcon("getCurInvIcon", NULL, 's'); + +// greebo: "Private" event which runs right after spawn time to check the inventory-related spawnargs. +const idEventDef EV_InitInventory("initInventory", "d"); + +// grayman #2478 - event which runs after spawn time to see if a mine is armed +const idEventDef EV_CheckMine("checkMine"); + +// The Dark Mod Stim/Response interface functions for scripting +// Normally I don't like names, which are "the other way around" +// but I think in this case it would be ok, because the interface +// for stims and responses are pretty much the same. +const idEventDef EV_StimAdd( "StimAdd", "df" ); +const idEventDef EV_StimRemove( "StimRemove", "d" ); +const idEventDef EV_StimEnable( "StimEnable", "dd" ); +const idEventDef EV_StimClearIgnoreList( "StimClearIgnoreList", "d" ); +const idEventDef EV_ResponseEnable( "ResponseEnable", "dd" ); +const idEventDef EV_ResponseAdd( "ResponseAdd", "d" ); +const idEventDef EV_ResponseRemove( "ResponseRemove", "d" ); +const idEventDef EV_ResponseIgnore( "ResponseIgnore", "de" ); +const idEventDef EV_ResponseAllow( "ResponseAllow", "de" ); +const idEventDef EV_ResponseSetAction( "ResponseSetAction", "ds" ); +const idEventDef EV_ResponseTrigger( "ResponseTrigger", "ed" ); +const idEventDef EV_GetResponseEntity( "GetResponseEntity", NULL, 'e' ); + +// StimType, Hours, minutes, seconds, miliseconds(?) +const idEventDef EV_TimerCreate( "CreateTimer", "ddddd" ); +const idEventDef EV_TimerStop( "StopTimer", "d" ); +const idEventDef EV_TimerStart( "StartTimer", "d" ); +const idEventDef EV_TimerRestart( "RestartTimer", "d" ); +const idEventDef EV_TimerReset( "ResetTimer", "d" ); +const idEventDef EV_TimerSetState( "SetTimerState", "dd" ); + +// soundprop event: Propagate sound directly from scripting +const idEventDef EV_TDM_PropSoundMod( "propSoundMod", "sf" ); +// I don't think scripting supports optional argument, so I must do this +const idEventDef EV_TDM_PropSound( "propSound", "s" ); + +// For detecting ranged enemies. Returns nonzero if this entity could +// potentially attack the given entity (first parameter) at range. +const idEventDef EV_TDM_RangedThreatTo( "rangedThreatTo", "e", 'f' ); + + +#ifdef MOD_WATERPHYSICS + +const idEventDef EV_GetMass( "getMass", "d" , 'f' ); + +const idEventDef EV_IsInLiquid( "isInLiquid", NULL, 'd' ); + +#endif // MOD_WATERPHYSICS + +const idEventDef EV_CopyBind( "copyBind", "e" ); +const idEventDef EV_IsFrobable( "isFrobable", NULL, 'd' ); +const idEventDef EV_SetFrobable( "setFrobable", "d" ); +const idEventDef EV_IsHilighted( "isHilighted", NULL, 'd' ); +const idEventDef EV_Frob("frob", NULL, 'd'); +const idEventDef EV_FrobHilight("frobHilight", "d" ); + +// greebo: Script event to check whether this entity can see a target entity +const idEventDef EV_CanSeeEntity("canSeeEntity", "ed", 'd'); + +const idEventDef EV_CanBeUsedBy("canBeUsedBy", "e", 'd'); + +const idEventDef EV_CheckAbsence("checkAbsence"); + +// greebo: TDM: Team accessor script events +const idEventDef EV_GetTeam("getTeam", NULL, 'd'); +const idEventDef EV_SetTeam("setTeam", "d"); + +const idEventDef EV_IsEnemy( "isEnemy", "E", 'd' ); +const idEventDef EV_IsFriend( "isFriend", "E", 'd' ); +const idEventDef EV_IsNeutral( "isNeutral", "E", 'd' ); + +const idEventDef EV_SetEntityRelation( "setEntityRelation", "Ed"); +const idEventDef EV_ChangeEntityRelation( "changeEntityRelation", "Ed"); + +ABSTRACT_DECLARATION( idClass, idEntity ) + EVENT( EV_Thread_SetRenderCallback, idEntity::Event_WaitForRender ) + + EVENT( EV_GetName, idEntity::Event_GetName ) + EVENT( EV_SetName, idEntity::Event_SetName ) + EVENT (EV_IsType, idEntity::Event_IsType ) + EVENT( EV_FindTargets, idEntity::Event_FindTargets ) + EVENT( EV_ActivateTargets, idEntity::Event_ActivateTargets ) + EVENT( EV_AddTarget, idEntity::Event_AddTarget) + EVENT( EV_RemoveTarget, idEntity::Event_RemoveTarget) + EVENT( EV_NumTargets, idEntity::Event_NumTargets ) + EVENT( EV_GetTarget, idEntity::Event_GetTarget ) + EVENT( EV_RandomTarget, idEntity::Event_RandomTarget ) + EVENT( EV_BindToJoint, idEntity::Event_BindToJoint ) + EVENT( EV_BindToBody, idEntity::Event_BindToBody ) + EVENT( EV_RemoveBinds, idEntity::Event_RemoveBinds ) + EVENT( EV_Bind, idEntity::Event_Bind ) + EVENT( EV_BindPosition, idEntity::Event_BindPosition ) + EVENT( EV_Unbind, idEntity::Event_Unbind ) + EVENT( EV_SpawnBind, idEntity::Event_SpawnBind ) + EVENT( EV_GetBindMaster, idEntity::Event_GetBindMaster ) + EVENT( EV_NumBindChildren, idEntity::Event_NumBindChildren ) + EVENT( EV_GetBindChild, idEntity::Event_GetBindChild ) + EVENT( EV_SetOwner, idEntity::Event_SetOwner ) + EVENT( EV_SetModel, idEntity::Event_SetModel ) + EVENT( EV_SetSkin, idEntity::Event_SetSkin ) + EVENT( EV_GetShaderParm, idEntity::Event_GetShaderParm ) + EVENT( EV_SetShaderParm, idEntity::Event_SetShaderParm ) + EVENT( EV_SetShaderParms, idEntity::Event_SetShaderParms ) + EVENT( EV_SetColor, idEntity::Event_SetColor ) + EVENT( EV_GetColor, idEntity::Event_GetColor ) + EVENT( EV_IsHidden, idEntity::Event_IsHidden ) + EVENT( EV_Hide, idEntity::Event_Hide ) + EVENT( EV_Show, idEntity::Event_Show ) + EVENT( EV_CacheSoundShader, idEntity::Event_CacheSoundShader ) + EVENT( EV_StartSoundShader, idEntity::Event_StartSoundShader ) + EVENT( EV_StartSound, idEntity::Event_StartSound ) + EVENT( EV_StopSound, idEntity::Event_StopSound ) + EVENT( EV_FadeSound, idEntity::Event_FadeSound ) + EVENT( EV_SetSoundVolume, idEntity::Event_SetSoundVolume ) + EVENT( EV_GetWorldOrigin, idEntity::Event_GetWorldOrigin ) + EVENT( EV_SetWorldOrigin, idEntity::Event_SetWorldOrigin ) + EVENT( EV_GetOrigin, idEntity::Event_GetOrigin ) + EVENT( EV_SetOrigin, idEntity::Event_SetOrigin ) + EVENT( EV_GetAngles, idEntity::Event_GetAngles ) + EVENT( EV_SetAngles, idEntity::Event_SetAngles ) + EVENT( EV_GetLinearVelocity, idEntity::Event_GetLinearVelocity ) + EVENT( EV_SetLinearVelocity, idEntity::Event_SetLinearVelocity ) + EVENT( EV_GetAngularVelocity, idEntity::Event_GetAngularVelocity ) + EVENT( EV_SetAngularVelocity, idEntity::Event_SetAngularVelocity ) + + EVENT( EV_SetContents, idEntity::Event_SetContents ) + EVENT( EV_GetContents, idEntity::Event_GetContents ) + EVENT( EV_SetClipMask, idEntity::Event_SetClipMask ) + EVENT( EV_GetClipMask, idEntity::Event_GetClipMask ) + + EVENT( EV_GetSize, idEntity::Event_GetSize ) + EVENT( EV_SetSize, idEntity::Event_SetSize ) + EVENT( EV_GetMins, idEntity::Event_GetMins) + EVENT( EV_GetMaxs, idEntity::Event_GetMaxs ) + EVENT( EV_Touches, idEntity::Event_Touches ) + EVENT( EV_GetNextKey, idEntity::Event_GetNextKey ) + EVENT( EV_SetKey, idEntity::Event_SetKey ) + EVENT( EV_GetKey, idEntity::Event_GetKey ) + EVENT( EV_GetIntKey, idEntity::Event_GetIntKey ) + EVENT( EV_GetFloatKey, idEntity::Event_GetFloatKey ) + EVENT( EV_GetVectorKey, idEntity::Event_GetVectorKey ) + EVENT( EV_GetEntityKey, idEntity::Event_GetEntityKey ) + EVENT( EV_RemoveKey, idEntity::Event_RemoveKey ) + EVENT( EV_RestorePosition, idEntity::Event_RestorePosition ) + EVENT( EV_UpdateCameraTarget, idEntity::Event_UpdateCameraTarget ) + EVENT( EV_DistanceTo, idEntity::Event_DistanceTo ) + EVENT( EV_DistanceToPoint, idEntity::Event_DistanceToPoint ) + EVENT( EV_StartFx, idEntity::Event_StartFx ) + EVENT( EV_Thread_WaitFrame, idEntity::Event_WaitFrame ) + EVENT( EV_Thread_Wait, idEntity::Event_Wait ) + EVENT( EV_HasFunction, idEntity::Event_HasFunction ) + EVENT( EV_CallFunction, idEntity::Event_CallFunction ) + EVENT( EV_CallGlobalFunction, idEntity::Event_CallGlobalFunction ) + EVENT( EV_SetNeverDormant, idEntity::Event_SetNeverDormant ) + + EVENT( EV_ExtinguishLights, idEntity::Event_ExtinguishLights ) + + EVENT( EV_InPVS, idEntity::Event_InPVS ) + EVENT( EV_Damage, idEntity::Event_Damage ) + EVENT( EV_Heal, idEntity::Event_Heal ) + EVENT( EV_TeleportTo, idEntity::Event_TeleportTo ) + EVENT( EV_IsDroppable, idEntity::Event_IsDroppable ) + EVENT( EV_SetDroppable, idEntity::Event_SetDroppable ) + EVENT( EV_GetLightInPVS, idEntity::Event_GetLightInPVS ) + + EVENT( EV_SetGui, idEntity::Event_SetGui ) + EVENT( EV_GetGui, idEntity::Event_GetGui ) + EVENT( EV_SetGuiString, idEntity::Event_SetGuiString ) + EVENT( EV_GetGuiString, idEntity::Event_GetGuiString ) + EVENT( EV_SetGuiFloat, idEntity::Event_SetGuiFloat ) + EVENT( EV_GetGuiFloat, idEntity::Event_GetGuiFloat ) + EVENT( EV_SetGuiInt, idEntity::Event_SetGuiInt ) + EVENT( EV_GetGuiInt, idEntity::Event_GetGuiInt ) + EVENT( EV_SetGuiStringFromKey, idEntity::Event_SetGuiStringFromKey ) + EVENT( EV_CallGui, idEntity::Event_CallGui ) + EVENT( EV_CreateOverlay, idEntity::Event_CreateOverlay ) + EVENT( EV_DestroyOverlay, idEntity::Event_DestroyOverlay ) + + EVENT( EV_LoadExternalData, idEntity::Event_LoadExternalData ) + + EVENT( EV_GetLootAmount, idEntity::Event_GetLootAmount ) + EVENT( EV_ChangeLootAmount, idEntity::Event_ChangeLootAmount ) + EVENT( EV_AddInvItem, idEntity::Event_AddInvItem ) + EVENT( EV_AddItemToInv, idEntity::Event_AddItemToInv ) + EVENT( EV_ReplaceInvItem, idEntity::Event_ReplaceInvItem ) + EVENT( EV_GetNextInvItem, idEntity::Event_GetNextInvItem ) + EVENT( EV_GetPrevInvItem, idEntity::Event_GetPrevInvItem ) + EVENT( EV_SetCurInvCategory, idEntity::Event_SetCurInvCategory ) + EVENT( EV_SetCurInvItem, idEntity::Event_SetCurInvItem ) + EVENT( EV_GetCurInvCategory, idEntity::Event_GetCurInvCategory ) + EVENT( EV_GetCurInvItemEntity, idEntity::Event_GetCurInvItemEntity ) + EVENT( EV_GetCurInvItemName, idEntity::Event_GetCurInvItemName ) + EVENT( EV_GetCurInvItemId, idEntity::Event_GetCurInvItemId ) + EVENT( EV_GetCurInvIcon, idEntity::Event_GetCurInvIcon ) + EVENT( EV_ChangeInvItemCount, idEntity::ChangeInventoryItemCount ) + EVENT( EV_ChangeInvLightgemModifier, idEntity::ChangeInventoryLightgemModifier ) + EVENT( EV_ChangeInvIcon, idEntity::ChangeInventoryIcon ) + EVENT( EV_InitInventory, idEntity::Event_InitInventory ) + + EVENT( EV_StimAdd, idEntity::Event_StimAdd) + EVENT( EV_StimRemove, idEntity::Event_StimRemove) + EVENT( EV_StimEnable, idEntity::Event_StimEnable) + EVENT( EV_StimClearIgnoreList, idEntity::Event_StimClearIgnoreList) + EVENT( EV_ResponseEnable, idEntity::Event_ResponseEnable) + EVENT( EV_ResponseAdd, idEntity::Event_ResponseAdd) + EVENT( EV_ResponseRemove, idEntity::Event_ResponseRemove) + EVENT( EV_ResponseIgnore, idEntity::Event_ResponseIgnore) + EVENT( EV_ResponseAllow, idEntity::Event_ResponseAllow) + EVENT( EV_ResponseSetAction, idEntity::Event_ResponseSetAction) + EVENT( EV_ResponseTrigger, idEntity::Event_ResponseTrigger) + EVENT( EV_GetResponseEntity, idEntity::Event_GetResponseEntity) + + EVENT( EV_TimerCreate, idEntity::Event_TimerCreate ) + EVENT( EV_TimerStop, idEntity::Event_TimerStop ) + EVENT( EV_TimerStart, idEntity::Event_TimerStart ) + EVENT( EV_TimerRestart, idEntity::Event_TimerRestart ) + EVENT( EV_TimerReset, idEntity::Event_TimerReset ) + EVENT( EV_TimerSetState, idEntity::Event_TimerSetState ) + + EVENT( EV_TDM_PropSound, idEntity::Event_PropSound ) + EVENT( EV_TDM_PropSoundMod, idEntity::Event_PropSoundMod ) + + EVENT( EV_TDM_RangedThreatTo, idEntity::Event_RangedThreatTo ) + +#ifdef MOD_WATERPHYSICS + + EVENT( EV_GetMass, idEntity::Event_GetMass ) + + EVENT( EV_IsInLiquid, idEntity::Event_IsInLiquid ) + +#endif // MOD_WATERPHYSICS + + EVENT( EV_CopyBind, idEntity::Event_CopyBind ) + EVENT( EV_IsFrobable, idEntity::Event_IsFrobable ) + EVENT( EV_SetFrobable, idEntity::Event_SetFrobable ) + EVENT( EV_IsHilighted, idEntity::Event_IsHilighted ) + EVENT( EV_Frob, idEntity::Event_Frob ) + EVENT( EV_FrobHilight, idEntity::Event_FrobHilight ) + EVENT( EV_CanSeeEntity, idEntity::Event_CanSeeEntity ) + EVENT( EV_CanBeUsedBy, idEntity::Event_CanBeUsedBy ) + + EVENT( EV_CheckAbsence, idEntity::Event_CheckAbsence ) + + EVENT (EV_GetTeam, idEntity::Event_GetTeam ) + EVENT (EV_SetTeam, idEntity::Event_SetTeam ) + + EVENT(EV_IsEnemy, idEntity::Event_IsEnemy ) + EVENT(EV_IsFriend, idEntity::Event_IsFriend ) + EVENT(EV_IsNeutral, idEntity::Event_IsNeutral ) + + EVENT(EV_SetEntityRelation, idEntity::Event_SetEntityRelation ) + EVENT(EV_ChangeEntityRelation, idEntity::Event_ChangeEntityRelation ) + + EVENT( EV_NoShadows, idEntity::Event_noShadows ) + + EVENT( EV_CheckMine, idEntity::Event_CheckMine ) // grayman #2478 + + EVENT( EV_GetVinePlantLoc, idEntity::Event_GetVinePlantLoc ) // grayman #2478 + EVENT( EV_GetVinePlantNormal, idEntity::Event_GetVinePlantNormal ) // grayman #2478 + EVENT( EV_IsLight, idEntity::Event_IsLight ) // grayman #2905 + +END_CLASS + +/* +================ +UpdateGuiParms +================ +*/ +void UpdateGuiParms( idUserInterface *gui, const idDict *args ) { + if ( gui == NULL || args == NULL ) { + return; + } + const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL ); + while( kv ) { + gui->SetStateString( kv->GetKey(), kv->GetValue() ); + kv = args->MatchPrefix( "gui_parm", kv ); + } + gui->SetStateBool( "noninteractive", args->GetBool( "gui_noninteractive" ) ) ; + gui->StateChanged( gameLocal.time ); +} + +/* +================ +AddRenderGui +================ +*/ +void AddRenderGui( const char *name, idUserInterface **gui, const idDict *args ) { + const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL ); + *gui = uiManager->FindGui( name, true, ( kv != NULL ) ); + UpdateGuiParms( *gui, args ); +} + +/* +================ +idGameEdit::ParseSpawnArgsToRenderEntity + +parse the static model parameters +this is the canonical renderEntity parm parsing, +which should be used by dmap and the editor +================ +*/ +void idGameEdit::ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity ) { + int i; + const char *temp; + idVec3 color; + float angle; + const idDeclModelDef *modelDef; + + memset( renderEntity, 0, sizeof( *renderEntity ) ); + + temp = args->GetString( "model" ); + + modelDef = NULL; + if ( temp[0] != '\0' ) { + if ( !strstr( temp, "." ) ) { + + // FIXME: temp hack to replace obsolete ips particles with prt particles + if ( !strstr( temp, ".ips" ) ) { + idStr str = temp; + str.Replace( ".ips", ".prt" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, str, false ) ); + } else { + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, temp, false ) ); + } + if ( modelDef ) { + renderEntity->hModel = modelDef->ModelHandle(); + } + } + + if ( !renderEntity->hModel ) { + renderEntity->hModel = renderModelManager->FindModel( temp ); + } + } + if ( renderEntity->hModel ) { + renderEntity->bounds = renderEntity->hModel->Bounds( renderEntity ); + } else { + renderEntity->bounds.Zero(); + } + + idStr rskin = args->GetString( "random_skin", "" ); + if ( !rskin.IsEmpty() ) { + // found list, select a random skin + temp = rskin.RandomPart(gameLocal.random.RandomFloat()).c_str(); + } + else { + // else just use the "skin" spawnarg + temp = args->GetString( "skin" ); + } + + if ( temp[0] != '\0' ) { + renderEntity->customSkin = declManager->FindSkin( temp ); + } else if ( modelDef ) { + renderEntity->customSkin = modelDef->GetDefaultSkin(); + } + + temp = args->GetString( "shader" ); + if ( temp[0] != '\0' ) { + renderEntity->customShader = declManager->FindMaterial( temp ); + } + + args->GetVector( "origin", "0 0 0", renderEntity->origin ); + + // get the rotation matrix in either full form, or single angle form + if ( !args->GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", renderEntity->axis ) ) { + angle = args->GetFloat( "angle" ); + if ( angle != 0.0f ) { + renderEntity->axis = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } else { + renderEntity->axis.Identity(); + } + } + + renderEntity->referenceSound = NULL; + + // get shader parms + args->GetVector( "_color", "1 1 1", color ); + renderEntity->shaderParms[ SHADERPARM_RED ] = color[0]; + renderEntity->shaderParms[ SHADERPARM_GREEN ] = color[1]; + renderEntity->shaderParms[ SHADERPARM_BLUE ] = color[2]; + renderEntity->shaderParms[ 3 ] = args->GetFloat( "shaderParm3", "1" ); + renderEntity->shaderParms[ 4 ] = args->GetFloat( "shaderParm4", "0" ); + renderEntity->shaderParms[ 5 ] = args->GetFloat( "shaderParm5", "0" ); + renderEntity->shaderParms[ 6 ] = args->GetFloat( "shaderParm6", "0" ); + renderEntity->shaderParms[ 7 ] = args->GetFloat( "shaderParm7", "0" ); + renderEntity->shaderParms[ 8 ] = args->GetFloat( "shaderParm8", "0" ); + renderEntity->shaderParms[ 9 ] = args->GetFloat( "shaderParm9", "0" ); + renderEntity->shaderParms[ 10 ] = args->GetFloat( "shaderParm10", "0" ); + renderEntity->shaderParms[ 11 ] = args->GetFloat( "shaderParm11", "0" ); + + // check noDynamicInteractions flag + renderEntity->noDynamicInteractions = args->GetBool( "noDynamicInteractions" ); + + // check noshadows flag + renderEntity->noShadow = args->GetBool( "noshadows" ); + + // check noselfshadows flag + renderEntity->noSelfShadow = args->GetBool( "noselfshadows" ); + + // init any guis, including entity-specific states + for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + temp = args->GetString( i == 0 ? "gui" : va( "gui%d", i + 1 ) ); + if ( temp[ 0 ] != '\0' ) { + AddRenderGui( temp, &renderEntity->gui[ i ], args ); + } + } +} + +/* +================ +idGameEdit::ParseSpawnArgsToRefSound + +parse the sound parameters +this is the canonical refSound parm parsing, +which should be used by dmap and the editor +================ +*/ +void idGameEdit::ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound ) { + const char *temp; + + memset( refSound, 0, sizeof( *refSound ) ); + + refSound->parms.minDistance = args->GetFloat( "s_mindistance" ); + refSound->parms.maxDistance = args->GetFloat( "s_maxdistance" ); + refSound->parms.volume = args->GetFloat( "s_volume" ); + refSound->parms.shakes = args->GetFloat( "s_shakes" ); + + args->GetVector( "origin", "0 0 0", refSound->origin ); + + refSound->referenceSound = NULL; + + // if a diversity is not specified, every sound start will make + // a random one. Specifying diversity is usefull to make multiple + // lights all share the same buzz sound offset, for instance. + refSound->diversity = args->GetFloat( "s_diversity", "-1" ); + refSound->waitfortrigger = args->GetBool( "s_waitfortrigger" ); + + if ( args->GetBool( "s_omni" ) ) { + refSound->parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL; + } + if ( args->GetBool( "s_looping" ) ) { + refSound->parms.soundShaderFlags |= SSF_LOOPING; + } + if ( args->GetBool( "s_occlusion" ) ) { + refSound->parms.soundShaderFlags |= SSF_NO_OCCLUSION; + } + if ( args->GetBool( "s_global" ) ) { + refSound->parms.soundShaderFlags |= SSF_GLOBAL; + } + if ( args->GetBool( "s_unclamped" ) ) { + refSound->parms.soundShaderFlags |= SSF_UNCLAMPED; + } + refSound->parms.soundClass = args->GetInt( "s_soundClass" ); + + temp = args->GetString( "s_shader" ); + if ( temp[0] != '\0' ) { + refSound->shader = declManager->FindSound( temp ); + } +} + +// ---------------------------------------------------------------- + +/* +=============== +idEntity::UpdateChangeableSpawnArgs + +Any key val pair that might change during the course of the game ( via a gui or whatever ) +should be initialize here so a gui or other trigger can change something and have it updated +properly. An optional source may be provided if the values reside in an outside dictionary and +first need copied over to spawnArgs +=============== +*/ +void idEntity::UpdateChangeableSpawnArgs( const idDict *source ) { + int i; + const char *target; + + if ( !source ) { + source = &spawnArgs; + } + cameraTarget = NULL; + target = source->GetString( "cameraTarget" ); + if ( target && target[0] ) { + // update the camera taget + PostEventMS( &EV_UpdateCameraTarget, 0 ); + } + + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + UpdateGuiParms( renderEntity.gui[ i ], source ); + } +} + +/* +================ +idEntity::idEntity +================ +*/ +idEntity::idEntity() +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX %s\r", this, __FUNCTION__); + + entityNumber = ENTITYNUM_NONE; + entityDefNumber = -1; + + spawnNode.SetOwner( this ); + activeNode.SetOwner( this ); + + snapshotNode.SetOwner( this ); + snapshotSequence = -1; + snapshotBits = 0; + + thinkFlags = 0; + dormantStart = 0; + cinematic = false; + renderView = NULL; + cameraTarget = NULL; + health = 0; + maxHealth = 0; + + m_droppedByAI = false; // grayman #1330 + + m_preHideContents = -1; // greebo: initialise this to invalid values + m_preHideClipMask = -1; + m_CustomContents = -1; + + physics = NULL; + bindMaster = NULL; + bindJoint = INVALID_JOINT; + bindBody = -1; + teamMaster = NULL; + teamChain = NULL; + signals = NULL; + + memset( PVSAreas, 0, sizeof( PVSAreas ) ); + numPVSAreas = -1; + + memset( &fl, 0, sizeof( fl ) ); + fl.neverDormant = true; // most entities never go dormant + + memset( &renderEntity, 0, sizeof( renderEntity ) ); + modelDefHandle = -1; + memset( &refSound, 0, sizeof( refSound ) ); + + memset( &m_renderTrigger, 0, sizeof( m_renderTrigger ) ); + m_renderTrigger.axis.Identity(); + m_renderTriggerHandle = -1; + m_renderWaitingThread = 0; + + mpGUIState = -1; + + m_SetInMotionByActor = NULL; + m_MovedByActor = NULL; + m_bFrobable = false; + m_bFrobSimple = false; + m_FrobDistance = 0; + m_FrobBias = 1.0f; + m_FrobBox = NULL; + m_FrobActionScript = ""; + m_bFrobbed = false; + m_bFrobHighlightState = false; + m_FrobChangeTime = 0; + m_FrobActionLock = false; + m_bAttachedAlertControlsSolidity = false; + m_bIsObjective = false; + m_bIsClimbableRope = false; + m_bIsMantleable = false; + m_bIsBroken = false; + + // We give all the entities a Stim/Response collection so that we wont have to worry + // about the pointer being available all the time. The memory footprint of that + // object is rather small, so this doesn't really hurt that + // much and makes the code easier to control. + m_StimResponseColl = new CStimResponseCollection; + + // Since we have a function to return inventories/etc, and many entities won't + // have anything to do with inventories, I figure I'd better wait until + // absolutely necessary to create these. + m_Inventory = CInventoryPtr(); + m_InventoryCursor = CInventoryCursorPtr(); + + m_LightQuotient = 0; + m_LightQuotientLastEvalTime = -1; + + // by default no LOD to save memory and time + m_LODHandle = 0; + m_DistCheckTimeStamp = 0; + + // grayman #597 - for hiding arrows when nocked to the bow + m_HideUntilTime = 0; +} + +/* +================ +idEntity::FixupLocalizedStrings +================ +*/ +void idEntity::FixupLocalizedStrings() +{ + // Tels: Transform here things like "inv_category" "Maps" back to "#str_02390" so that custom + // entities in FMs with hard-coded english inventory categories or names still work even with + // the new translation code. + + int c = 2; + const char* todo[2] = { "inv_category", "inv_name" }; + + for (int i = 0; i < c; i++) + { + idStr spName = spawnArgs.GetString( todo[i], ""); + if (!spName.IsEmpty()) + { + idStr strTemplate = gameLocal.m_I18N->TemplateFromEnglish( spName ); + // "Maps" resulted in "#str_02390"? + if (spName != strTemplate) + { + gameLocal.Printf("%s: Fixing %s from %s to %s.\n", GetName(), todo[i], spName.c_str(), strTemplate.c_str() ); + spawnArgs.Set( todo[i], strTemplate ); + } + } + } +} + +/* +================ +idEntity::ParseLODSpawnargs + +Tels: Look at dist_think_interval, lod_1_distance etc. and fill the m_LOD + data. The passed in dict is usually just this->spawnArgs, but can also + be from a completely different entity def so we can parse the spawnargs + without having to actually have the entity spawned. The fRandom + value is used to selectively hide some entities when hide_probability + is set, and should be between 0 and 1.0. +================ +*/ +lod_handle idEntity::ParseLODSpawnargs( const idDict* dict, const float fRandom) +{ + lod_data_t *m_LOD = NULL; + + int d = int(1000.0f * dict->GetFloat( "dist_check_period", "0" )); + + float fHideDistance = dict->GetFloat( "hide_distance", "0.0" ); + + m_DistCheckTimeStamp = 0; + // a quick check for LOD, to avoid looking at all lod_x_distance spawnargs: + if (d == 0 && fHideDistance < 0.1f) + { + // no LOD wanted + m_DistCheckTimeStamp = NOLOD; + return 0; + } + + // distance dependent LOD from this point on: + // allocate new memory + m_LOD = new lod_data_t; + + // if interval not set, use twice per second + m_LOD->DistCheckInterval = ((d == 0) ? 500 : d); + + m_SkinLODCur = 0; + m_ModelLODCur = 0; + m_LODLevel = 0; + + m_LOD->noshadowsLOD = dict->GetBool( "noshadows", "0" ) ? 1 : 0; // the default value for level 0 + + // if > 0, if the entity is closer than this, lod_bias will be at minimum 1.0 + m_LOD->fLODNormalDistance = dict->GetFloat( "lod_normal_distance", "500" ); + if (m_LOD->fLODNormalDistance < 0.0f) + { + m_LOD->fLODNormalDistance = 0.0f; + } + + idStr temp; + m_LOD->OffsetLOD[0] = idVec3(0,0,0); // assume there is no custom per-LOD model offset + m_LOD->DistLODSq[0] = 0; + + // setup level 0 (aka "The one and only original") + m_LOD->ModelLOD[0] = dict->GetString( "model", "" ); + + // For func_statics where name == model, use "" so they can share the same LOD data + // even tho they all have different "models". (Their model spawnarg is never used.) + if ( IsType( idStaticEntity::Type ) && m_LOD->ModelLOD[0] == GetName()) + { + m_LOD->ModelLOD[0] = ""; + } + + // use whatever was set as skin, that can differ from spawnArgs.GetString("skin") due to random_skin: + if ( renderEntity.customSkin ) + { + m_LOD->SkinLOD[0] = renderEntity.customSkin->GetName(); + } + else + { + m_LOD->SkinLOD[0] = ""; + } + + // start at 1, since 0 is "the original level" setup already above + for (int i = 1; i < LOD_LEVELS; i++) + { + // set to 0,0,0 as default in case someone tries to use it + m_LOD->OffsetLOD[i] = idVec3(0,0,0); + + if (i < LOD_LEVELS - 1) + { + // for i == LOD_LEVELS - 1, we use "hide_distance" + sprintf(temp, "lod_%i_distance", i); + m_LOD->DistLODSq[i] = dict->GetFloat( temp, "0.0" ); + } + + // Tels: Fix #2635: if the LOD distance here is < fHideDistance, use hide distance-1 so the + // entity gets really hidden. + if (fHideDistance > 1.0f && m_LOD->DistLODSq[i] > fHideDistance) + { + m_LOD->DistLODSq[i] = fHideDistance - 1.0f; + } + + if (i == LOD_LEVELS - 1) + { + // last distance is named differently so you don't need to know how many levels the code supports: + m_LOD->DistLODSq[i] = fHideDistance; + + // compute a random number and check it against the hide probability spawnarg + // do this only once at setup time, so the setting is stable during runtime + float fHideProbability = dict->GetFloat( "lod_hide_probability", "1.0" ); + if (fRandom > fHideProbability) + { + // disable hiding + m_LOD->DistLODSq[i] = -1.0f; // disable + continue; + } + + // do we have a lod_fadeout_range? + m_LOD->fLODFadeOutRange = dict->GetFloat( "lod_fadeout_range", "0.0" ); + + if (m_LOD->fLODFadeOutRange < 0) + { + gameLocal.Warning (" %s: lod_fadeout_range must be >= 0 but is %f. Ignoring it.\n", GetName(), m_LOD->fLODFadeOutRange); + m_LOD->fLODFadeOutRange = 0.0f; + } + else + { + // square for easier comparisation with deltaSq + m_LOD->fLODFadeOutRange *= m_LOD->fLODFadeOutRange; + } + + // do we have a lod_fadein_range? + m_LOD->fLODFadeInRange = dict->GetFloat( "lod_fadein_range", "0.0" ); + + if (m_LOD->fLODFadeInRange < 0) + { + gameLocal.Warning (" %s: lod_fadein_range must be >= 0 but is %f. Ignoring it.\n", GetName(), m_LOD->fLODFadeInRange); + m_LOD->fLODFadeInRange = 0.0f; + } + else if (m_LOD->fLODFadeInRange > 0 && m_LOD->fLODFadeInRange > m_LOD->DistLODSq[1]) + { + gameLocal.Warning (" %s: lod_fadein_range must be <= lod_1_distance (%f) 0 but is %f. Ignoring it.\n", GetName(), m_LOD->DistLODSq[1], m_LOD->fLODFadeInRange); + m_LOD->fLODFadeOutRange = 0.0f; + } + else + { + // square for easier comparisation with deltaSq + m_LOD->fLODFadeInRange *= m_LOD->fLODFadeInRange; + } + + //gameLocal.Printf (" %s: lod_fadeout_range %0.2f lod_fadein_range %0.2f.\n", GetName(), m_LOD->fLODFadeOutRange, m_LOD->fLODFadeInRange); + } + +// gameLocal.Printf (" %s: init LOD %i m_LOD->DistLODSq=%f\n", GetName(), i, m_LOD->DistLODSq[i]); + + if (i > 0 && m_LOD->DistLODSq[i] > 0 && (m_LOD->DistLODSq[i] * m_LOD->DistLODSq[i]) < m_LOD->DistLODSq[i-1]) + { + gameLocal.Warning (" %s: LOD %i m_DistLODSq %f < LOD %i m_DistLODSq=%f (this will not work!)\n", + GetName(), i, m_LOD->DistLODSq[i] * m_LOD->DistLODSq[i], i-1, m_LOD->DistLODSq[i-1]); + } + // -1 should stay -1 to signal "don't use this level" + if (m_LOD->DistLODSq[i] > 0) + { + m_LOD->DistLODSq[i] *= m_LOD->DistLODSq[i]; + + // the last level is "hide", so we don't need a model, skin, offset or noshadows there + if (i < LOD_LEVELS - 1) + { + // not the last level + sprintf(temp, "model_lod_%i", i); + m_LOD->ModelLOD[i] = dict->GetString( temp ); + if (m_LOD->ModelLOD[i].Length() == 0) { m_LOD->ModelLOD[i] = m_LOD->ModelLOD[0]; } + + sprintf(temp, "skin_lod_%i", i); + m_LOD->SkinLOD[i] = dict->GetString( temp ); + if (m_LOD->SkinLOD[i].Length() == 0) { m_LOD->SkinLOD[i] = m_LOD->SkinLOD[0]; } + + // set the right bit for noshadows + sprintf(temp, "noshadows_lod_%i", i ); + // 1, 2, 4, 8, 16 etc + m_LOD->noshadowsLOD |= (dict->GetBool( temp, "0" ) ? 1 : 0) << i; + +// // set the right bit for "standin". "standins" are models that always rotate in +// // XY to face the player, but unlike particles, don't tilt with the view +// sprintf(temp, "standin_lod_%i", i ); +// // 1, 2, 4, 8, 16 etc +// m_LOD->standinLOD |= (dict->GetBool( temp, "0" ) ? 1 : 0) << i; + + // setup the manual offset for this LOD stage (needed to align some models) + sprintf(temp, "offset_lod_%i", i); + m_LOD->OffsetLOD[i] = dict->GetVector( temp, "0,0,0" ); + } + // else hiding needs no offset + + //gameLocal.Printf (" noshadowsLOD 0x%08x model %s skin %s\n", m_noshadowsLOD, m_ModelLOD[i].c_str(), m_SkinLOD[i].c_str() ); + } + else + { + // initialize to empty in case someone tries to access them + m_LOD->SkinLOD[i] = ""; + m_LOD->ModelLOD[i] = ""; + m_LOD->OffsetLOD[i] = idVec3(0,0,0); + } + } + + m_LOD->bDistCheckXYOnly = dict->GetBool( "dist_check_xy", "0" ); + + // add some phase diversity to the checks so that they don't all run in one frame + // make sure they all run on the first frame though, by initializing m_TimeStamp to + // be at least one interval early. + // old code, only using half the interval: + m_DistCheckTimeStamp = gameLocal.time - (int) (m_LOD->DistCheckInterval * (1.0f + gameLocal.random.RandomFloat()) ); + + // register the data with the ModelGenerator and return the handle + lod_handle h = gameLocal.m_ModelGenerator->RegisterLODData( m_LOD ); + + // free memory + delete m_LOD; + + return h; +} + +/* +================ +idEntity::Spawn +================ +*/ +void idEntity::Spawn( void ) +{ + int i; + const char *temp; + idVec3 origin; + idMat3 axis; + const idKeyValue *networkSync; + const char *classname; + const char *scriptObjectName; + + gameLocal.RegisterEntity( this ); + + spawnArgs.GetString( "classname", NULL, &classname ); + const idDeclEntityDef *def = gameLocal.FindEntityDef( classname, false ); + if ( def ) { + entityDefNumber = def->Index(); + } + + // every object will have a unique name + temp = spawnArgs.GetString( "name", va( "%s_%s_%d", GetClassname(), spawnArgs.GetString( "classname" ), entityNumber)); + SetName(temp); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("this: %08lX Name: [%s]\r", this, temp); + + FixupLocalizedStrings(); + + // parse static models the same way the editor display does + gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &renderEntity ); + + renderEntity.entityNum = entityNumber; + + // go dormant within 5 frames so that when the map starts most monsters are dormant + dormantStart = gameLocal.time - DELAY_DORMANT_TIME + gameLocal.msec * 5; + + origin = renderEntity.origin; + axis = renderEntity.axis; + + // do the audio parsing the same way dmap and the editor do + gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound ); + + // only play SCHANNEL_PRIVATE when sndworld->PlaceListener() is called with this listenerId + // don't spatialize sounds from the same entity + refSound.listenerId = entityNumber + 1; + + cameraTarget = NULL; + temp = spawnArgs.GetString( "cameraTarget" ); + if ( temp && temp[0] ) { + // update the camera taget + PostEventMS( &EV_UpdateCameraTarget, 0 ); + } + + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + UpdateGuiParms( renderEntity.gui[ i ], &spawnArgs ); + + // Add the (potentially NULL) GUI as an external GUI to our overlaysys, + // so that the script functions to interact with GUIs can interact with it. + if ( m_overlays.createOverlay( 0, OVERLAYS_MIN_HANDLE + i ) >= OVERLAYS_MIN_HANDLE ) + m_overlays.setGui( OVERLAYS_MIN_HANDLE + i, renderEntity.gui[ i ] ); + else + gameLocal.Warning( "Unable to create overlay for renderentity GUI: %d\n", OVERLAYS_MIN_HANDLE + i ); + } + + fl.solidForTeam = spawnArgs.GetBool( "solidForTeam", "0" ); + fl.neverDormant = spawnArgs.GetBool( "neverDormant", "0" ); + fl.hidden = spawnArgs.GetBool( "hide", "0" ); + if ( fl.hidden ) { + // make sure we're hidden, since a spawn function might not set it up right + PostEventMS( &EV_Hide, 0 ); + } + cinematic = spawnArgs.GetBool( "cinematic", "0" ); + + networkSync = spawnArgs.FindKey( "networkSync" ); + if ( networkSync ) { + fl.networkSync = ( atoi( networkSync->GetValue() ) != 0 ); + } + +#if 0 + if ( !gameLocal.isClient ) { + // common->DPrintf( "NET: DBG %s - %s is synced: %s\n", spawnArgs.GetString( "classname", "" ), GetType()->classname, fl.networkSync ? "true" : "false" ); + if ( spawnArgs.GetString( "classname", "" )[ 0 ] == '\0' && !fl.networkSync ) { + common->DPrintf( "NET: WRN %s entity, no classname, and no networkSync?\n", GetType()->classname ); + } + } +#endif + + bool haveTargets = false; // grayman #2603 + // if we have targets, wait until all entities are spawned to get them + if ( spawnArgs.MatchPrefix( "target" ) || spawnArgs.MatchPrefix( "guiTarget" ) ) + { + haveTargets = true; + if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { + PostEventMS( &EV_FindTargets, 0 ); + } else { + // not during spawn, so it's ok to get the targets + FindTargets(); + } + } + + // if we're attaching relight positions, they have to be added as targets, + // so we have to wait until all entities are spawned to do that + + health = spawnArgs.GetInt( "health" ); + + InitDefaultPhysics( origin, axis ); + + // TDM: Set custom contents, and store it so it doesn't get overwritten + m_CustomContents = spawnArgs.GetInt("clipmodel_contents","-1"); + if( m_CustomContents != -1 ) + GetPhysics()->SetContents( m_CustomContents ); + + SetOrigin( origin ); + SetAxis( axis ); + + // load visual model and broken model + LoadModels(); + + if ( spawnArgs.GetString( "bind", "", &temp ) ) + { + PostEventMS( &EV_SpawnBind, 0 ); + } + + //TDM: Parse list of pre-defined attachment positions from spawnargs + ParseAttachPositions(); + + //TDM: Parse and spawn and attach any attachments + ParseAttachments(); + + // grayman #2603 - if we spawned relight positions, add them to the target list + + if (spawnArgs.MatchPrefix("relight_position")) + { + if (haveTargets) + { + if (gameLocal.GameState() != GAMESTATE_STARTUP) + { + // not during spawn, so it's ok to add targets from the relight positions now + FindRelights(); + } + } + else + { + targets.Clear(); + // it's ok to create targets from the relight positions now + FindRelights(); + } + } + + // auto-start a sound on the entity + if ( refSound.shader && !refSound.waitfortrigger ) { + StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); + } + + // setup script object + if ( ShouldConstructScriptObjectAtSpawn() && spawnArgs.GetString( "scriptobject", NULL, &scriptObjectName ) ) { + if ( !scriptObject.SetType( scriptObjectName ) ) { + gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() ); + } + + ConstructScriptObject(); + } + + m_StimResponseColl->InitFromSpawnargs(spawnArgs, this); + + // greebo: Post the inventory check event. If this entity should be added + // to someone's inventory, the event takes care of that. This must happen + // after the entity has fully spawned (including subclasses), otherwise + // the clipmodel and things like that are not initialised (>> crash). + + // grayman #2820 - don't queue EV_InitInventory if it's going to + // end up doing nothing. Queuing this for every entity causes a ton + // of event posting during frame 0 that can overrun the event queue limit + // in large maps w/lots of entities. + + int lootValue = spawnArgs.GetInt( "inv_loot_value", "0" ); + int lootType = spawnArgs.GetInt( "inv_loot_type", "0" ); + bool belongsInInventory = spawnArgs.GetBool( "inv_map_start", "0" ); + + // Only post EV_InitInventory if this is loot OR it belongs in someone's inventory. + // If extra work is added to EV_InitInventory, then that must be accounted for here, to make sure it has + // a chance of getting done. + + if ( belongsInInventory || ( ( lootType > LOOT_NONE ) && ( lootType < LOOT_COUNT ) && ( lootValue != 0 ) ) ) + { + PostEventMS( &EV_InitInventory, 0, 0 ); + } + + // grayman #2478 - If this is a mine or flashmine, it can be armed + // at spawn time. Post an event to replace the mine with its + // projectile counterpart, which handles arming/disarming. Wait a + // bit before replacing so the mine has time to settle. + + if ( idStr::Cmp(spawnArgs.GetString("toolclass"), "mine") == 0 ) + { + PostEventSec(&EV_CheckMine, 1.0f); + } + + LoadTDMSettings(); + + if (m_AbsenceNoticeability > 0) + { + PostEventMS(&EV_CheckAbsence, gameLocal.random.RandomFloat() * 5000); + } + m_StartBounds = GetPhysics()->GetAbsBounds(); + m_AbsenceStatus = false; + + // parse LOD spawnargs + m_LODHandle = ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ); + + if (m_LODHandle) + { + // Have to start thinking if we're distance dependent + BecomeActive( TH_THINK ); + } + + // init most recent voice and body sound data for AI - grayman #2341 + previousVoiceShader = NULL; // shader for the most recent voice request + previousVoiceIndex = 0; // index of most recent voice sound requested (1->N, where there are N sounds) + previousBodyShader = NULL; // shader for the most recent body sound request + previousBodyIndex = 0; // index of most recent body sound requested (1->N, where there are N sounds) +} + +/* +================ +idEntity::DisableLOD + +Tels: temp. disable LOD checks by setting the next check timestamp to negative. +================ +*/ +void idEntity::DisableLOD( const bool doTeam ) +{ + // negate check interval + if (m_LODHandle && m_DistCheckTimeStamp > NOLOD) + { +// gameLocal.Printf( "%s: Temporarily disabling LOD.\n", GetName() ); + m_DistCheckTimeStamp = NOLOD; + } + + if (!doTeam) { return; } + + /* also all the bound entities in our team */ + idEntity* NextEnt = this; + idEntity* bindM = GetBindMaster(); + if ( bindM ) { NextEnt = bindM; } + + while ( NextEnt != NULL ) + { + //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); + idEntity *ent = static_cast( NextEnt ); + if (ent) + { + ent->DisableLOD( false ); + } + /* get next Team member */ + NextEnt = NextEnt->GetNextTeamEntity(); + } +} + +/* +================ +idEntity::EnableLOD + +Tels: Enable LOD checks again (after DisableLOD) by setting the check interval to positive. +================ +*/ +void idEntity::EnableLOD( const bool doTeam ) +{ + // negate check interval + if (m_LODHandle && m_DistCheckTimeStamp <= NOLOD) + { +// gameLocal.Printf( "%s: Enabling LOD again.\n", GetName() ); + m_DistCheckTimeStamp = gameLocal.time; + } + + if (!doTeam) { return; } + + /* also all the bound entities in our team */ + idEntity* NextEnt = this; + idEntity* bindM = GetBindMaster(); + if ( bindM ) { NextEnt = bindM; } + + while ( NextEnt != NULL ) + { + //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); + idEntity *ent = static_cast( NextEnt ); + if (ent) + { + ent->EnableLOD( false ); + } + /* get next Team member */ + NextEnt = NextEnt->GetNextTeamEntity(); + } +} + +/* +================ +idEntity::StopLOD + +Tels: Permanently disable LOD checks, if doTeam is true, including on all of our attachements +================ +*/ +void idEntity::StopLOD( const bool doTeam ) +{ + //BecomeInactive( TH_THINK ); + // deregister our LOD struct + if (m_LODHandle) + { + // gameLocal.Printf( "%s: Stopping LOD.\n", GetName() ); + gameLocal.m_ModelGenerator->UnregisterLODData( m_LODHandle ); + m_LODHandle = 0; + } + + if (!doTeam) { return; } + + /* also all the bound entities in our team */ + idEntity* NextEnt = this; + + idEntity* bindM = GetBindMaster(); + if ( bindM ) { NextEnt = bindM; } + + while ( NextEnt != NULL ) + { + //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); + idEntity *ent = static_cast( NextEnt ); + if (ent) + { + ent->StopLOD( false ); + } + /* get next Team member */ + NextEnt = NextEnt->GetNextTeamEntity(); + } +} + +/* +================ +idEntity::LoadModels +================ +*/ +// tels: this routine loads all the visual and collision models +void idEntity::LoadModels() +{ + idStr model; + // we only use a brokenModel if we can find one automatically + bool needBroken = false; + + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Loading models for entity %d (%s)\r", entityNumber, name.c_str() ); + + // load the normal visual model + spawnArgs.GetString( "model", "", model ); + + if ( !model.IsEmpty() ) { + SetModel( model ); + } + + // was a brokenModel requested? + spawnArgs.GetString( "broken", "", brokenModel ); + + // see if we need to create a broken model name + if ( !brokenModel.IsEmpty() ) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Need broken model '%s' for entity %d (%s)\r", brokenModel.c_str(), entityNumber, name.c_str() ); + // spawnarg "broken" was set, so we need the broken model + needBroken = true; + } + // only check for an auto-broken model if the entity could be damaged + else if ( health || spawnArgs.FindKey( "max_force" ) ) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Looking for broken models for entity %d (%s) (health: %d)\r", entityNumber, name.c_str(), health ); + + int pos = model.Find("."); + + if ( pos < 0 ) + { + pos = model.Length(); + } + + if ( pos > 0 ) + { + model.Left( pos, brokenModel ); + } + + brokenModel += "_broken"; + + if ( pos > 0 ) + { + brokenModel += &model[ pos ]; + } + } + + // greebo: Only try to cache the model if it actually exists -> otherwise tons of false warnings get emitted + bool brokenModelFileExists = (fileSystem->FindFile(brokenModel) != FIND_NO); + + if (brokenModelFileExists) + { + // check brokenModel to exist, and make sure the brokenModel gets cached + if ( !renderModelManager->CheckModel( brokenModel ) ) + { + if ( needBroken ) { + gameLocal.Error( "Broken model '%s' not loadable for entity %d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); + } + else { + // couldn't find automatically generated "model_broken.lwo", so don't use brokenModel at all + brokenModel = ""; + } + } + } + else + { + // Broken model file does not exist + if ( needBroken ) { + gameLocal.Error( "Broken model '%s' required for entity %d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); + } + // set brokenModel to empty, so we later don't try to use it + brokenModel = ""; + } + + // can we be damaged? + if ( health || spawnArgs.FindKey( "max_force" ) || !brokenModel.IsEmpty() ) + { + fl.takedamage = true; + } + + if ( brokenModelFileExists && !brokenModel.IsEmpty() ) + { + if ( model.IsEmpty() ) + { + gameLocal.Error( "Breakable entity (broken model %s) without a model set on entity #%d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); + } + + // make sure the collision model for the brokenModel gets cached + idClipModel::CheckModel( brokenModel ); + + // since we can be damaged, setup some physics +/* +* Ishtvan: Commented out, this is handled separately and this call can interfere with other places contents are set +* + GetPhysics()->SetContents( !spawnArgs.GetBool( "solid" ) ? 0 : CONTENTS_SOLID ); + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) { + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + } +**/ + + } // end of loading of broken model(s) and their CM + + +} + +/* +================ +idEntity::~idEntity +================ +*/ +idEntity::~idEntity( void ) +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); + + // Tels: #2430 - If this entity is shouldered by the player, dequip it forcefully + if (gameLocal.m_Grabber->GetEquipped() == this) + { + if ( spawnArgs.GetBool("shoulderable") ) + { + gameLocal.Printf("Grabber: Forcefully unshouldering %s because it will be removed.\n", GetName() ); + gameLocal.m_Grabber->UnShoulderBody(this); + } + gameLocal.Printf("Grabber: Forcefully dequipping %s because it will be removed.\n", GetName() ); + gameLocal.m_Grabber->Forget(this); + } + + // Let each objective entity we're currently in know about our destruction + for (int i = 0; i < m_objLocations.Num(); ++i) + { + CObjectiveLocation* locationEnt = m_objLocations[i].GetEntity(); + + if (locationEnt == NULL) continue; // probably already deleted + + locationEnt->OnEntityDestroyed(this); + } + + gameLocal.RemoveResponse(this); + gameLocal.RemoveStim(this); + + if ( gameLocal.GameState() != GAMESTATE_SHUTDOWN && !gameLocal.isClient && fl.networkSync && entityNumber >= MAX_CLIENTS ) { + idBitMsg msg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteByte( GAME_RELIABLE_MESSAGE_DELETE_ENT ); + msg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); + networkSystem->ServerSendReliableMessage( -1, msg ); + } + + DeconstructScriptObject(); + scriptObject.Free(); + + if ( thinkFlags ) { + BecomeInactive( thinkFlags ); + } + activeNode.Remove(); + + Signal( SIG_REMOVED ); + + // we have to set back the default physics object before unbinding because the entity + // specific physics object might be an entity variable and as such could already be destroyed. + SetPhysics( NULL ); + + // remove any entities that are bound to me + RemoveBinds(); + + // unbind from master + Unbind(); + QuitTeam(); + + gameLocal.RemoveEntityFromHash( name.c_str(), this ); + + delete renderView; + renderView = NULL; + + delete signals; + signals = NULL; + + // free optional LOD data + if (m_LODHandle) + { + StopLOD( false ); + } + + FreeModelDef(); + FreeSoundEmitter( false ); + + if ( m_renderTriggerHandle != -1 ) { + gameRenderWorld->FreeEntityDef( m_renderTriggerHandle ); + } + + gameLocal.UnregisterEntity( this ); + gameLocal.RemoveStim(this); + gameLocal.RemoveResponse(this); + delete m_StimResponseColl; + + if( m_FrobBox ) + delete m_FrobBox; + + m_FrobPeers.Clear(); +} + +void idEntity::AddObjectsToSaveGame(idSaveGame* savefile) +{ + // empty default implementation +} + +/* +================ +idEntity::Save +================ +*/ +void idEntity::Save( idSaveGame *savefile ) const +{ + int i, j; + + savefile->WriteInt( entityNumber ); + savefile->WriteInt( entityDefNumber ); + + // spawnNode and activeNode are restored by gameLocal + + savefile->WriteInt( snapshotSequence ); + savefile->WriteInt( snapshotBits ); + + savefile->WriteDict( &spawnArgs ); + savefile->WriteString( name ); + scriptObject.Save( savefile ); + + savefile->WriteInt( thinkFlags ); + savefile->WriteInt( dormantStart ); + savefile->WriteBool( cinematic ); + + savefile->WriteObject( cameraTarget ); + + savefile->WriteInt( health ); + savefile->WriteInt( maxHealth ); + + savefile->WriteInt( m_preHideContents ); + savefile->WriteInt( m_preHideClipMask ); + savefile->WriteInt( m_CustomContents ); + + savefile->WriteInt( targets.Num() ); + for( i = 0; i < targets.Num(); i++ ) { + targets[ i ].Save( savefile ); + } + + entityFlags_s flags = fl; + + LittleBitField( &flags, sizeof( flags ) ); + + savefile->Write( &flags, sizeof( flags ) ); + + savefile->WriteInt(m_UsedByName.Num()); + for (i = 0; i < m_UsedByName.Num(); i++) + { + savefile->WriteString(m_UsedByName[i].c_str()); + } + savefile->WriteInt(m_UsedByInvName.Num()); + for (i = 0; i < m_UsedByInvName.Num(); i++) + { + savefile->WriteString(m_UsedByInvName[i].c_str()); + } + savefile->WriteInt(m_UsedByCategory.Num()); + for (i = 0; i < m_UsedByCategory.Num(); i++) + { + savefile->WriteString(m_UsedByCategory[i].c_str()); + } + savefile->WriteInt(m_UsedByClassname.Num()); + for (i = 0; i < m_UsedByClassname.Num(); i++) + { + savefile->WriteString(m_UsedByClassname[i].c_str()); + } + + savefile->WriteBool(m_bAttachedAlertControlsSolidity); + savefile->WriteBool(m_bIsObjective); + + savefile->WriteInt(m_objLocations.Num()); + for (i = 0; i < m_objLocations.Num(); ++i) + { + m_objLocations[i].Save(savefile); + } + + savefile->WriteBool(m_bFrobable); + savefile->WriteBool(m_bFrobSimple); + savefile->WriteInt(m_FrobDistance); + savefile->WriteFloat(m_FrobBias); + savefile->WriteClipModel(m_FrobBox); + + savefile->WriteBool(m_bIsClimbableRope); + + savefile->WriteInt(m_animRates.Num()); + for (i = 0; i < m_animRates.Num(); i++) + { + savefile->WriteFloat(m_animRates[i]); + } + + m_SetInMotionByActor.Save(savefile); + m_MovedByActor.Save(savefile); + + savefile->WriteBool(m_bFrobbed); + savefile->WriteBool(m_bFrobHighlightState); + savefile->WriteInt(m_FrobChangeTime); + + savefile->WriteString(m_FrobActionScript); + + savefile->WriteInt(m_FrobPeers.Num()); + for (i = 0; i < m_FrobPeers.Num(); i++) + { + savefile->WriteString(m_FrobPeers[i]); + } + + savefile->WriteString(m_MasterFrob); + savefile->WriteBool(m_FrobActionLock); + + savefile->WriteFloat(m_AbsenceNoticeability); + savefile->WriteBounds(m_StartBounds); + savefile->WriteBool(m_AbsenceStatus); + + m_AbsenceMarker.Save(savefile); + + savefile->WriteInt(team); + + savefile->WriteInt(m_EntityRelations.size()); + for (EntityRelationsMap::const_iterator i = m_EntityRelations.begin(); i != m_EntityRelations.end(); ++i) + { + savefile->WriteObject(i->first); + savefile->WriteInt(i->second); + } + + savefile->WriteBool( m_bIsMantleable ); + + savefile->WriteBool( m_bIsBroken ); + savefile->WriteString( brokenModel ); + + m_StimResponseColl->Save(savefile); + + savefile->WriteRenderEntity( renderEntity ); + savefile->WriteInt( modelDefHandle ); + savefile->WriteRefSound( refSound ); + + savefile->WriteRenderEntity( m_renderTrigger ); + savefile->WriteInt( m_renderTriggerHandle ); + savefile->WriteInt( m_renderWaitingThread ); + + m_overlays.Save( savefile ); + + savefile->WriteObject( bindMaster ); + savefile->WriteJoint( bindJoint ); + savefile->WriteInt( bindBody ); + savefile->WriteObject( teamMaster ); + savefile->WriteObject( teamChain ); + + savefile->WriteStaticObject( defaultPhysicsObj ); + + savefile->WriteInt( numPVSAreas ); + for( i = 0; i < MAX_PVS_AREAS; i++ ) { + savefile->WriteInt( PVSAreas[ i ] ); + } + + if ( !signals ) { + savefile->WriteBool( false ); + } else { + savefile->WriteBool( true ); + for( i = 0; i < NUM_SIGNALS; i++ ) { + savefile->WriteInt( signals->signal[ i ].Num() ); + for( j = 0; j < signals->signal[ i ].Num(); j++ ) { + savefile->WriteInt( signals->signal[ i ][ j ].threadnum ); + savefile->WriteString( signals->signal[ i ][ j ].function->Name() ); + } + } + } + + savefile->WriteInt( mpGUIState ); + + savefile->WriteBool(m_Inventory != NULL); + if (m_Inventory != NULL) { + m_Inventory->Save(savefile); + } + + savefile->WriteBool(m_InventoryCursor != NULL); + if (m_InventoryCursor != NULL) { + // Save the ID of the cursor + savefile->WriteInt(m_InventoryCursor->GetId()); + } + + savefile->WriteInt( m_Attachments.Num() ); + for( int i=0; i < m_Attachments.Num(); i++ ) + m_Attachments[i].Save( savefile ); + + savefile->WriteInt( m_AttNameMap.size() ); + for ( AttNameMap::const_iterator k = m_AttNameMap.begin(); + k != m_AttNameMap.end(); ++k ) + { + savefile->WriteString( k->first.c_str() ); + savefile->WriteInt( k->second ); + } + + savefile->WriteInt( m_AttachPositions.Num() ); + for ( i = 0; i < m_AttachPositions.Num(); i++ ) + { + m_AttachPositions[i].Save( savefile ); + } + + m_userManager.Save(savefile); + + savefile->WriteFloat(m_LightQuotient); + savefile->WriteInt(m_LightQuotientLastEvalTime); + + savefile->WriteBool(m_droppedByAI); // grayman #1330 + + savefile->WriteInt(m_LODHandle); + savefile->WriteInt(m_DistCheckTimeStamp); + savefile->WriteInt(m_LODLevel); + savefile->WriteInt(m_ModelLODCur); + savefile->WriteInt(m_SkinLODCur); + + // grayman #2341 - don't save previous voice and body shaders and indices, + // since they're irrelevant across saved games + + savefile->WriteSoundShader(NULL); // previousVoiceShader + savefile->WriteInt(0); // previousVoiceIndex + savefile->WriteSoundShader(NULL); // previousBodyShader + savefile->WriteInt(0); // previousBodyIndex + + // grayman #597 + + savefile->WriteInt(m_HideUntilTime); // arrow-hiding timer + + // grayman #2787 + savefile->WriteVec3( m_VinePlantLoc ); + savefile->WriteVec3( m_VinePlantNormal ); +} + +/* +================ +idEntity::Restore +================ +*/ +void idEntity::Restore( idRestoreGame *savefile ) +{ + int i, j; + int num; + idStr funcname; + + savefile->ReadInt( entityNumber ); + savefile->ReadInt( entityDefNumber ); + + // spawnNode and activeNode are restored by gameLocal + + savefile->ReadInt( snapshotSequence ); + savefile->ReadInt( snapshotBits ); + + savefile->ReadDict( &spawnArgs ); + savefile->ReadString( name ); + SetName( name ); + + scriptObject.Restore( savefile ); + + savefile->ReadInt( thinkFlags ); + savefile->ReadInt( dormantStart ); + savefile->ReadBool( cinematic ); + + savefile->ReadObject( reinterpret_cast( cameraTarget ) ); + + savefile->ReadInt( health ); + savefile->ReadInt( maxHealth ); + + savefile->ReadInt( m_preHideContents ); + savefile->ReadInt( m_preHideClipMask ); + savefile->ReadInt( m_CustomContents ); + + targets.Clear(); + savefile->ReadInt( num ); + targets.SetNum( num ); + for( i = 0; i < num; i++ ) { + targets[ i ].Restore( savefile ); + } + + savefile->Read( &fl, sizeof( fl ) ); + LittleBitField( &fl, sizeof( fl ) ); + + savefile->ReadInt(num); + m_UsedByName.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(m_UsedByName[i]); + } + savefile->ReadInt(num); + m_UsedByInvName.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(m_UsedByInvName[i]); + } + savefile->ReadInt(num); + m_UsedByCategory.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(m_UsedByCategory[i]); + } + savefile->ReadInt(num); + m_UsedByClassname.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(m_UsedByClassname[i]); + } + + savefile->ReadBool(m_bAttachedAlertControlsSolidity); + savefile->ReadBool(m_bIsObjective); + + savefile->ReadInt(num); + m_objLocations.SetNum(num); + for (i = 0; i < num; ++i) + { + m_objLocations[i].Restore(savefile); + } + + savefile->ReadBool(m_bFrobable); + savefile->ReadBool(m_bFrobSimple); + savefile->ReadInt(m_FrobDistance); + savefile->ReadFloat(m_FrobBias); + savefile->ReadClipModel(m_FrobBox); + + savefile->ReadBool(m_bIsClimbableRope); + + savefile->ReadInt(num); + m_animRates.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadFloat(m_animRates[i]); + } + + m_SetInMotionByActor.Restore(savefile); + m_MovedByActor.Restore(savefile); + + savefile->ReadBool(m_bFrobbed); + savefile->ReadBool(m_bFrobHighlightState); + savefile->ReadInt(m_FrobChangeTime); + + savefile->ReadString(m_FrobActionScript); + + savefile->ReadInt(num); + m_FrobPeers.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(m_FrobPeers[i]); + } + + savefile->ReadString(m_MasterFrob); + savefile->ReadBool(m_FrobActionLock); + + savefile->ReadFloat(m_AbsenceNoticeability); + savefile->ReadBounds(m_StartBounds); + savefile->ReadBool(m_AbsenceStatus); + + m_AbsenceMarker.Restore(savefile); + + savefile->ReadInt(team); + + savefile->ReadInt(num); + for (int i = 0; i < num; ++i) + { + idEntity* entity; + savefile->ReadObject(reinterpret_cast(entity)); + + int relation; + savefile->ReadInt(relation); + + m_EntityRelations[entity] = relation; + } + + + savefile->ReadBool(m_bIsMantleable); + + savefile->ReadBool( m_bIsBroken ); + savefile->ReadString( brokenModel ); + + m_StimResponseColl->Restore(savefile); + + savefile->ReadRenderEntity( renderEntity ); + savefile->ReadInt( modelDefHandle ); + savefile->ReadRefSound( refSound ); + + savefile->ReadRenderEntity( m_renderTrigger ); + savefile->ReadInt( m_renderTriggerHandle ); + savefile->ReadInt( m_renderWaitingThread ); + + m_overlays.Restore( savefile ); + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + // Add the (potentially NULL) GUI as an external GUI to our overlaysys, + // so that the script functions to interact with GUIs can interact with it. + // If the overlay isn't external, then the entity inheriting us must have + // messed with the overlays, and doesn't want us to set it. If it IS + // external, then they'll be resetting it anyways, so no harm done. + if ( m_overlays.isExternal( OVERLAYS_MIN_HANDLE + i ) ) + m_overlays.setGui( OVERLAYS_MIN_HANDLE + i, renderEntity.gui[ i ] ); + } + + savefile->ReadObject( reinterpret_cast( bindMaster ) ); + savefile->ReadJoint( bindJoint ); + savefile->ReadInt( bindBody ); + savefile->ReadObject( reinterpret_cast( teamMaster ) ); + savefile->ReadObject( reinterpret_cast( teamChain ) ); + + savefile->ReadStaticObject( defaultPhysicsObj ); + RestorePhysics( &defaultPhysicsObj ); + + savefile->ReadInt( numPVSAreas ); + for( i = 0; i < MAX_PVS_AREAS; i++ ) { + savefile->ReadInt( PVSAreas[ i ] ); + } + + bool readsignals; + savefile->ReadBool( readsignals ); + if ( readsignals ) { + signals = new signalList_t; + for( i = 0; i < NUM_SIGNALS; i++ ) { + savefile->ReadInt( num ); + signals->signal[ i ].SetNum( num ); + for( j = 0; j < num; j++ ) { + savefile->ReadInt( signals->signal[ i ][ j ].threadnum ); + savefile->ReadString( funcname ); + signals->signal[ i ][ j ].function = gameLocal.program.FindFunction( funcname ); + if ( !signals->signal[ i ][ j ].function ) { + savefile->Error( "Function '%s' not found", funcname.c_str() ); + } + } + } + } + + savefile->ReadInt( mpGUIState ); + + bool hasInventory; + savefile->ReadBool(hasInventory); + if (hasInventory) { + Inventory()->Restore(savefile); + } + + bool hasInventoryCursor; + savefile->ReadBool(hasInventoryCursor); + if (hasInventoryCursor) { + // Get the ID of the cursor + int cursorId; + savefile->ReadInt(cursorId); + m_InventoryCursor = Inventory()->GetCursor(cursorId); + } + + m_Attachments.Clear(); + savefile->ReadInt( num ); + m_Attachments.SetNum( num ); + for( int i=0; i < num; i++ ) + m_Attachments[i].Restore( savefile ); + + m_AttNameMap.clear(); + savefile->ReadInt( num ); + for ( int i = 0; i < num; i++ ) + { + idStr tempStr; + savefile->ReadString(tempStr); + + int tempIndex; + savefile->ReadInt(tempIndex); + + m_AttNameMap.insert(AttNameMap::value_type(tempStr.c_str(), tempIndex)); + } + + m_AttachPositions.Clear(); + savefile->ReadInt( num ); + for ( i = 0; i < num; i++ ) + { + SAttachPosition &attachPos = m_AttachPositions.Alloc(); + attachPos.Restore( savefile ); + } + + // restore must retrieve modelDefHandle from the renderer + if ( modelDefHandle != -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } + + // restore must retrieve m_renderTriggerHandle from the renderer + if ( m_renderTriggerHandle != -1 ) { + m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); + } + + m_userManager.Restore(savefile); + + savefile->ReadFloat(m_LightQuotient); + savefile->ReadInt(m_LightQuotientLastEvalTime); + + savefile->ReadBool(m_droppedByAI); // grayman #1330 + + savefile->ReadUnsignedInt(m_LODHandle); + savefile->ReadInt(m_DistCheckTimeStamp); + savefile->ReadInt(m_LODLevel); + savefile->ReadInt(m_ModelLODCur); + savefile->ReadInt(m_SkinLODCur); + + // grayman #2341 - restore previous voice and body shaders and indices + + savefile->ReadSoundShader((const idSoundShader *&)previousVoiceShader); + savefile->ReadInt(previousVoiceIndex); + savefile->ReadSoundShader((const idSoundShader *&)previousBodyShader); + savefile->ReadInt(previousBodyIndex); + + // grayman #597 + + savefile->ReadInt(m_HideUntilTime); // arrow-hiding timer + + // grayman #2787 + + savefile->ReadVec3( m_VinePlantLoc ); + savefile->ReadVec3( m_VinePlantNormal ); + + + // Tels #2417: after Restore call RestoreScriptObject() of the scriptObject so the + // script object can restore f.i. sounds: + + const function_t *func = scriptObject.GetFunction( "RestoreScriptObject" ); + if (func) + { + idThread *thread = idThread::CurrentThread(); + if (!thread) + { + gameLocal.Printf("No running thread for RestoreScriptObject(), creating new one.\n"); + thread = new idThread(); + thread->SetThreadName( name.c_str() ); + } + // gameLocal.Warning( "Will call function '%s' in '%s'", "RestoreScriptObject", scriptObject.GetTypeName() ); + if ( func->type->NumParameters() != 1 ) { + gameLocal.Warning( "Function 'RestoreScriptObject' has the wrong number of parameters"); + } + thread->CallFunction( this, func, true ); + thread->DelayedStart( 0 ); + } +/* else + { + gameLocal.Warning("No RestoreScriptObject() function in script object for %s", GetName() ); + } +*/ + // done with calling "Restore()" on the script object +} + +/* +================ +idEntity::GetEntityDefName +================ +*/ +const char * idEntity::GetEntityDefName( void ) const +{ + if ( entityDefNumber < 0 ) { + return "*unknown*"; + } + return declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); +} + +/* +================ +idEntity::SetName +================ +*/ +void idEntity::SetName( const char *newname ) +{ + if ( name.Length() ) { + gameLocal.RemoveEntityFromHash( name.c_str(), this ); + gameLocal.program.SetEntity( name, NULL ); + } + + name = newname; + if ( name.Length() ) { + if ( ( name == "NULL" ) || ( name == "null_entity" ) ) { + gameLocal.Error( "Cannot name entity '%s'. '%s' is reserved for script.", name.c_str(), name.c_str() ); + } + gameLocal.AddEntityToHash( name.c_str(), this ); + gameLocal.program.SetEntity( name, this ); + } +} + +/* +================ +idEntity::GetName +================ +*/ +const char * idEntity::GetName( void ) const { + return name.c_str(); +} + + +/*********************************************************************** + + Thinking about LOD + + We pass a ptr to the current data, so that the SEED can let the spawned + entities think while still keeping their LOD data only once per class. + + This routine will only modify: + * m_LODLevel + * m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; + + It will also return the new alpha value for this entity, where 0.0f means + hidden and alpha > 0 means visible. + + The caller is responsible for calling SetAlpha() and Hide/Show on the + proper entity (e.g. the entity thet the m_LOD is for) as well as + switching the model and skin. + +***********************************************************************/ +float idEntity::ThinkAboutLOD( const lod_data_t *m_LOD, const float deltaSq ) +{ + // have no LOD + if (NULL == m_LOD) + { + // fully visible + return 1.0f; + } + + bool bWithinDist = false; + + // by default fully visible + float fAlpha = 1.0f; + +// gameLocal.Warning("%s: ThinkAboutLOD called with m_LOD %p deltaSq %0.2f", GetName(), m_LOD, deltaSq); + + // Tels: check in which LOD level we are + for (int i = 0; i < LOD_LEVELS; i++) + { +// gameLocal.Printf ("%s considering LOD %i (distance %f)\n", GetName(), i, m_LOD->DistLODSq[i] ); + + // skip this level (but not the first) + if (m_LOD->DistLODSq[i] <= 0 && i > 0) + { +// gameLocal.Printf ("%s skipping LOD %i (distance %f)\n", GetName(), i, m_LOD->DistLODSq[i] ); + continue; + } + + // find the next usable level + int nextLevel = i + 1; + while (nextLevel < LOD_LEVELS && m_LOD->DistLODSq[nextLevel] <= 0 ) + { + nextLevel++; + } + +// gameLocal.Printf ("%s ThinkAboutLOD deltaSq = %0.2f (this=%0.2f, nextLevel=%i, next=%0.2f, i=%i)\n", GetName(), deltaSq, m_LOD->DistLODSq[i], +// nextLevel, nextLevel < LOD_LEVELS ? m_LOD->DistLODSq[nextLevel] : -1, i ); + + // found a usable next level, or the last level is -1 (means no hide) + if (nextLevel < LOD_LEVELS) + { + bWithinDist = ((deltaSq > m_LOD->DistLODSq[i]) && (deltaSq <= m_LOD->DistLODSq[nextLevel])); + } + else + { + if (m_LOD->DistLODSq[ LOD_LEVELS - 1] < 0) + { +// gameLocal.Printf ("%s no next level (last level is -1)\n", GetName() ); + bWithinDist = (deltaSq > m_LOD->DistLODSq[ i ]); + } + else + { + if (i < LOD_LEVELS - 1) + { + bWithinDist = (deltaSq < m_LOD->DistLODSq[ LOD_LEVELS - 1]); + } + else + { + // only hide if hiding isn't disabled + // last usable level goes to infinity + bWithinDist = m_LOD->DistLODSq[i] > 0 && (deltaSq > m_LOD->DistLODSq[i]); + } + + // compute the alpha value of still inside the fade range + if (bWithinDist) + { + if (m_LOD->fLODFadeOutRange > 0) + { +// gameLocal.Printf ("%s outside hide_distance %0.2f (%0.2f) with fade %0.2f\n", GetName(), m_LOD->DistLODSq[i], deltaSq, m_LOD->fLODFadeOutRange); + if (deltaSq > (m_LOD->DistLODSq[i] + m_LOD->fLODFadeOutRange)) + { + fAlpha = 0.0f; + } + else + { + fAlpha = 1.0f - ( (deltaSq - m_LOD->DistLODSq[i]) / m_LOD->fLODFadeOutRange ); + } + // set the timestamp so we think the next frame again to get a smooth blend: + m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; + } + else + { + // just hide if outside + fAlpha = 0.0f; + } + m_LODLevel = i; + +// gameLocal.Printf (" %s returning LOD level %i, fAlpha = %0.2f", GetName(), i, fAlpha); + + // early out, we found the right level and switched + return fAlpha; + } + } + } + +// gameLocal.Printf (" %s passed LOD %i distance check %f (%f), inside?: %i (old level %i, prel. alpha %0.2f)\n", +// GetName(), i, m_LOD->DistLODSq[i], deltaSq, bWithinDist, m_LODLevel, fAlpha); + + // do this even if we are already in the same level + // && m_LODLevel != i) + if ( bWithinDist ) + { + m_LODLevel = i; + + // LOD level number i + // TODO: Hiding a LOD entity temp. completely would fail, + // as the LOD levels < LAST_LOD_LEVEL would show it again. + + if (i == 0 && m_LOD->fLODFadeInRange > 0) + { + // do we need to hide the entity, or fade it? + if (deltaSq < (m_LOD->DistLODSq[0] - m_LOD->fLODFadeInRange)) + { + fAlpha = 0.0f; // hide + } + else + { + fAlpha = (deltaSq - (m_LOD->DistLODSq[0] - m_LOD->fLODFadeInRange)) / m_LOD->fLODFadeOutRange; + // gameLocal.Printf ("%s fading in to %0.2f\n", GetName(), fAlpha); + } + // set the timestamp so we think the next frame again to get a smooth blend: + m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; + } + else + { + // visible in all other levels + fAlpha = 1.0f; // show + } + +// gameLocal.Printf (" %s returning LOD level %i, fAlpha = %0.2f (step 2)", GetName(), i, fAlpha); + + // We found the right level and will switch to it + return fAlpha; + } + + // end for all LOD levels + } + +// gameLocal.Warning("%s: ThinkAboutLOD fall out of lod levels, using fAlpha = 1.0f", GetName() ); + + return fAlpha; +} + +/* Tels: + + Call ThinkAboutLOD, then do the nec. things like calling Hide()/Show(), SetAlpha() etc. +*/ +bool idEntity::SwitchLOD( const lod_data_t *m_LOD, const float deltaSq ) +{ + if (!m_LOD) + { + gameLocal.Error("SwitchLOD() with NULL called.\n"); + } + // remember the current level + int oldLODLevel = m_LODLevel; + float fAlpha = ThinkAboutLOD( m_LOD, deltaSq ); + +// gameLocal.Printf("%s: Got fAlpha %0.2f\n", GetName(), fAlpha); + + if (fAlpha < 0.0001f) + { + if (!fl.hidden) + { +// gameLocal.Printf( "%s Hiding\n", GetName() ); + Hide(); + } + } + else + { + if (fl.hidden) + { +// gameLocal.Printf("Showing %s again (%0.2f)\n", GetName(), fAlpha); + Show(); + SetAlpha( fAlpha, true ); + } + // Only set the alpha if we are actually fading, but skip if it is 1.0f + else if (renderEntity.shaderParms[ SHADERPARM_ALPHA ] != fAlpha) + { +// gameLocal.Printf("%s: Setting alpha %0.2f\n", GetName(), fAlpha); + SetAlpha( fAlpha, true ); + } + } + + if (m_LODLevel != oldLODLevel) + { +// gameLocal.Printf( "%s LOD level changed from %i to %i\n", GetName(), oldLODLevel, m_LODLevel ); + if (m_ModelLODCur != m_LODLevel) + { +// gameLocal.Printf( "%s switching to LOD %i (model %s offset %f %f %f)\n", +// GetName(), m_LODLevel, m_LOD->ModelLOD[m_LODLevel].c_str(), m_LOD->OffsetLOD[m_LODLevel].x, m_LOD->OffsetLOD[m_LODLevel].x, m_LOD->OffsetLOD[m_LODLevel].z ); + // func_statics that have map geometry do not have a model, and their LOD data gets "" + // as model name so they can all share the same data. However, we must not use "" when + // setting a new model: + if (!m_LOD->ModelLOD[m_LODLevel].IsEmpty()) + { + SetModel( m_LOD->ModelLOD[m_LODLevel] ); + } + m_ModelLODCur = m_LODLevel; + // Fix 1.04 blinking bug: + // if the old LOD level had an offset, we need to revert this. + // and if the new one has an offset, we need to add it: + idVec3 originShift = m_LOD->OffsetLOD[oldLODLevel] + m_LOD->OffsetLOD[m_LODLevel]; + // avoid SetOrigin() if there is no change (it causes a lot of behind-the-scenes calls) + if (originShift.x != 0.0f || originShift.y != 0.0f || originShift.z != 0.0f) + { + SetOrigin( renderEntity.origin - m_LOD->OffsetLOD[oldLODLevel] + m_LOD->OffsetLOD[m_LODLevel] ); + } + } + + if ( m_SkinLODCur != m_LODLevel) + { + const idDeclSkin *skinD = declManager->FindSkin( m_LOD->SkinLOD[m_LODLevel] ); + if (skinD) + { + SetSkin( skinD ); + } + m_SkinLODCur = m_LODLevel; + } + // level 0 is the default + renderEntity.noShadow = (m_LOD->noshadowsLOD & (1 << (m_LODLevel + 1))) > 0 ? 1 : 0; + + // switched LOD + return true; + } + + // no switch done + return false; +} + +/* +================ +idEntity::GetLODDistance + +Returns the distance that should be considered for LOD and hiding, depending on: + +* the distance of the entity origin to the given player origin + (TODO: this should be actualy the distance to the closest point of the entity, + to aovid that very long entities get hidden when you are far from their origin, + but close to their corner) +* the lod-bias set in the menu +* some minimum and maximum distances based on entity size/importance + +The returned value is the (virtual) distance squared, and rounded down to an integer. +================ +*/ +float idEntity::GetLODDistance( const lod_data_t *m_LOD, const idVec3 &playerOrigin, const idVec3 &entOrigin, const idVec3 &entSize, const float lod_bias ) const +{ + idVec3 delta = playerOrigin - entOrigin; + // enforce an absolute minimum of 500 units for entities w/o LOD + float minDist = 0.0f; + + if( m_LOD && m_LOD->bDistCheckXYOnly) + { + // todo: allow passing in a different gravityNormal + idVec3 vGravNorm = GetPhysics()->GetGravityNormal(); + delta -= (vGravNorm * delta) * vGravNorm; + } + + // let the mapper override it + if ( m_LOD && m_LOD->fLODNormalDistance > 0) + { + // gameLocal.Printf ("%s: Using %0.2f lod_normal_distance, delta %0.2f.\n", GetName(), m_LOD->fLODNormalDistance, deltaSq); + minDist = m_LOD->fLODNormalDistance; + } + + // multiply with the user LOD bias setting, and return the result: + // floor the value to avoid inaccurancies leading to toggling when the player stands still: + assert(lod_bias > 0.01f); + float deltaSq = delta.LengthSqr(); + + // if the entity is inside the "lod_normal_distance", simply ignore any LOD_BIAS < 1.0f + // Tels: For v1.05 use at least 1.0f for lod_bias, so that any distance the mapper sets + // acts as the absolute minimum distance. Needs fixing later. + //if (minDist > 0 && lod_bias < 1.0f && deltaSq < (minDist * minDist)) + if (lod_bias <= 1.0f) + { + deltaSq = idMath::Floor( deltaSq ); + } + else + { + deltaSq = idMath::Floor( deltaSq / (lod_bias * lod_bias) ); + } + + // TODO: enforce minimum/maximum distances based on entity size/importance + return deltaSq; +} + +/* +================ +idEntity::Think +================ +*/ +void idEntity::Think( void ) +{ + RunPhysics(); + if ( (thinkFlags & TH_PHYSICS) && m_FrobBox ) + { + // update trigger position + // TODO: Tels: What about hidden entities, these would use (0,0,0) as origin here? + m_FrobBox->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + } + + if (m_LODHandle && m_DistCheckTimeStamp > NOLOD) + { + const lod_data_t *lod = gameLocal.m_ModelGenerator->GetLODDataPtr( m_LODHandle ); + + if (lod) + { + // If this entity has LOD, let it think about it: + + // Distance dependence checks + if ( ( lod->DistCheckInterval > 0) + && ( (gameLocal.time - m_DistCheckTimeStamp) > lod->DistCheckInterval ) ) + { + m_DistCheckTimeStamp = gameLocal.time; + +// gameLocal.Warning("%s: Think called with m_LOD %p, %i, interval %i, origin %s", +// GetName(), m_LOD, m_DistCheckTimeStamp, m_LOD->DistCheckInterval, GetPhysics()->GetOrigin().ToString() ); + + SwitchLOD( lod, + GetLODDistance( lod, gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin(), renderEntity.bounds.GetSize(), cv_lod_bias.GetFloat() ) ); + } + } + } + Present(); +} + +/* +================ +idEntity::DoDormantTests + +Monsters and other expensive entities that are completely closed +off from the player can skip all of their work +================ +*/ +bool idEntity::DoDormantTests( void ) +{ + if (cv_ai_opt_forceopt.GetBool()) return true; // Everything always dormant! + if ( fl.neverDormant ) { + return false; + } + + // if the monster area is not topologically connected to a player + if ( !gameLocal.InPlayerConnectedArea( this ) ) { + if ( dormantStart == 0 ) { + dormantStart = gameLocal.time; + } + if ( gameLocal.time - dormantStart < DELAY_DORMANT_TIME ) { + // just got closed off, don't go dormant yet + return false; + } + return true; + } else { + // the monster area is topologically connected to a player, but if + // the monster hasn't been woken up before, do the more precise PVS check + // TDM: Never wake up permanently; always do PVS check. + // (This may cause bugs. I did this for AI optimisation testing.) + // --Crispy + if ( true || !fl.hasAwakened ) { + if ( !gameLocal.InPlayerPVS( this ) ) { + return true; // stay dormant + } + } + + // wake up + dormantStart = 0; + fl.hasAwakened = true; // only go dormant when area closed off now, not just out of PVS + + return false; + } + +// return false; +} + +/* +================ +idEntity::CheckDormant + +Monsters and other expensive entities that are completely closed +off from the player can skip all of their work +================ +*/ +bool idEntity::CheckDormant( void ) +{ + bool dormant; + + dormant = DoDormantTests(); + if ( dormant && !fl.isDormant ) { + fl.isDormant = true; + DormantBegin(); + } else if ( !dormant && fl.isDormant ) { + fl.isDormant = false; + DormantEnd(); + } + + return dormant; +} + +/* +================ +idEntity::DormantBegin + +called when entity becomes dormant +================ +*/ +void idEntity::DormantBegin( void ) { +} + +/* +================ +idEntity::DormantEnd + +called when entity wakes from being dormant +================ +*/ +void idEntity::DormantEnd( void ) { +} + +/* +================ +idEntity::IsBroken +================ +*/ +bool idEntity::IsBroken( void ) const { + return m_bIsBroken; +} + + +/* +================ +idEntity::SpawnFlinder spawns zero, one or more flinder objects as +described by one FlinderSpawn struct. The activator is the entity +that caused this entity to break up. + +@return: -1 for error, or the number of entities spawned + +*/ +int idEntity::SpawnFlinder( const FlinderSpawn& fs, idEntity *activator ) +{ + int spawned = 0; + + for (int i = 0; i < fs.m_Count; i++) + { + // probability 0.6 => spawn in only 60% of all cases + if (fs.m_Probability < 1.0 && + gameLocal.random.RandomFloat() >= fs.m_Probability) + { + continue; + } + + const idDict *p_entityDef = gameLocal.FindEntityDefDict( fs.m_Entity.c_str(), false ); + if( p_entityDef ) + { + idEntity *flinder; + gameLocal.SpawnEntityDef( *p_entityDef, &flinder, false ); + idPhysics *physics; + idVec3 TumbleVec(vec3_zero); + + if ( !flinder ) + { + gameLocal.Error( "Failed to spawn flinder entity %s", fs.m_Entity.c_str() ); + return -1; + } + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Spawned entity %s\r", flinder->GetName() ); + + physics = flinder->GetPhysics(); + + // move the entity to the origin (plus offset) and orientation of the original + physics->SetOrigin( GetPhysics()->GetOrigin() + fs.m_Offset ); + physics->SetAxis( GetPhysics()->GetAxis() ); + // give the flinders the same speed as the original entity (in case it breaks + // up while on the move + // tels FIXME: We would need to count how many flinders were spawned then distribute + // the impulse from the activator in equal parts to each of them. + // tels FIXME: Currently these are zero when an arrow hits a bottle. + + // for now add a small random speed so the object moves + // tels FIXME: Doesn't work. Because the flinder is inside the still solid + // entity? + TumbleVec[0] += (gameLocal.random.RandomFloat() * 20) - 10; + TumbleVec[1] += (gameLocal.random.RandomFloat() * 20) - 10; + TumbleVec[2] += (gameLocal.random.RandomFloat() * 20) - 10; + + physics->SetLinearVelocity( + GetPhysics()->GetLinearVelocity() + + activator->GetPhysics()->GetLinearVelocity() + + TumbleVec + ); + physics->SetAngularVelocity( + GetPhysics()->GetAngularVelocity() + + activator->GetPhysics()->GetAngularVelocity() + + TumbleVec + ); + + /* + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Activator is: %s\r", activator->GetName() ); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Set linear velocity to %f %f %f:\r", + physics->GetLinearVelocity().x, + physics->GetLinearVelocity().y, + physics->GetLinearVelocity().z ); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Set angular velocity to %f %f %f:\r", + physics->GetAngularVelocity().x, + physics->GetAngularVelocity().y, + physics->GetAngularVelocity().z ); + */ + + if( activator->IsType(idActor::Type) ) + { + idActor *actor = static_cast(activator); + flinder->m_SetInMotionByActor = actor; + flinder->m_MovedByActor = actor; + } + + // activate the flinder, so it falls realistically down + flinder->BecomeActive(TH_PHYSICS|TH_THINK); + // FIXME if this entity has a skin, set the same skin on the flinder + // FIXME add a small random impulse outwards from entity origin + spawned++; + } + } // end for m_Count + + return spawned; +} + +/* +================ +idEntity::BecomeBroken +================ +*/ +void idEntity::BecomeBroken( idEntity *activator ) +{ + if (m_bIsBroken) + { + // we are already broken, so do nothing + return; + } + + m_bIsBroken = true; + + // switch to the brokenModel if it was defined + if ( brokenModel.Length() ) + { + SetModel( brokenModel ); + + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Breaking entity %s (solid: %i)\r", name.c_str(), spawnArgs.GetBool( "solid" ) ); + if ( spawnArgs.GetBool( "solid" ) ) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Setting new clipmodel '%s'\r)", brokenModel.c_str() ); + + idClipModel* clipmodel = new idClipModel( brokenModel ); + + if (clipmodel && clipmodel->IsTraceModel() && GetPhysics()) + { + GetPhysics()->SetClipModel( clipmodel, 1.0f ); + } + } + } + else if ( spawnArgs.GetBool( "hideModelOnBreak" ) ) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Hiding broken entity %s\r", name.c_str() ); + SetModel( "" ); + GetPhysics()->SetContents( 0 ); + } + + // tels: if a break_up_script is defined, run it: + idStr str; + if (this->spawnArgs.GetString("break_up_script", "", str)) + { + // Call the script + idThread* thread = CallScriptFunctionArgs(str.c_str(), true, 0, "e", this); + if (thread != NULL) + { + // Run the thread at once, the script result might be needed below. + thread->Execute(); + } + } + + // tels: if we have flinders to spawn on break, do so now + Flinderize( activator ); +} + +/* +================ +idEntity::IsActive +================ +*/ +bool idEntity::IsActive( void ) const { + return activeNode.InList(); +} + +/* +================ +idEntity::BecomeActive +================ +*/ +void idEntity::BecomeActive( int flags ) +{ + if ( ( flags & TH_PHYSICS ) ) { + // enable the team master if this entity is part of a physics team + if ( teamMaster && teamMaster != this ) { + teamMaster->BecomeActive( TH_PHYSICS ); + } else if ( !( thinkFlags & TH_PHYSICS ) ) { + // if this is a pusher + if ( physics->IsType( idPhysics_Parametric::Type ) || physics->IsType( idPhysics_Actor::Type ) ) { + gameLocal.sortPushers = true; + } + } + } + + int oldFlags = thinkFlags; + thinkFlags |= flags; + + if ( thinkFlags ) { + if ( !IsActive() ) { + activeNode.AddToEnd( gameLocal.activeEntities ); + } else if ( !oldFlags ) { + // we became inactive this frame, so we have to decrease the count of entities to deactivate + gameLocal.numEntitiesToDeactivate--; + } + } +} + +/* +================ +idEntity::BecomeInactive +================ +*/ +void idEntity::BecomeInactive( int flags ) +{ + if ( ( flags & TH_PHYSICS ) ) { + // may only disable physics on a team master if no team members are running physics or bound to a joints + if ( teamMaster == this ) { + for ( idEntity *ent = teamMaster->teamChain; ent; ent = ent->teamChain ) { + if ( ( ent->thinkFlags & TH_PHYSICS ) || ( ( ent->bindMaster == this ) && ( ent->bindJoint != INVALID_JOINT ) ) ) { + flags &= ~TH_PHYSICS; + break; + } + } + } + } + + if ( thinkFlags ) { + thinkFlags &= ~flags; + if ( !thinkFlags && IsActive() ) { + gameLocal.numEntitiesToDeactivate++; + } + } + + if ( ( flags & TH_PHYSICS ) ) { + // if this entity has a team master + if ( teamMaster && teamMaster != this ) { + // if the team master is at rest + if ( teamMaster->IsAtRest() ) { + teamMaster->BecomeInactive( TH_PHYSICS ); + } + } + } +} + +/*********************************************************************** + + Visuals + +***********************************************************************/ + +/* +================ +idEntity::SetShaderParm +================ +*/ +void idEntity::SetShaderParm( int parmnum, float value ) +{ + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Warning( "shader parm index (%d) out of range", parmnum ); + return; + } + + renderEntity.shaderParms[ parmnum ] = value; + // tels: TODO: UpdateVisuals does stuff like updating the Model Transform, + // calling updating the MD5 animation, clear the PVS areas, calling updateSound() + // etc. All these things might be unnec. for just modifying a shaderParm, see if + // we can optimize this. + UpdateVisuals(); +} + +/* +================ +idEntity::SetColor +================ +*/ +void idEntity::SetColor( const float red, const float green, const float blue ) { + renderEntity.shaderParms[ SHADERPARM_RED ] = red; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = green; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = blue; + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); +} + +/* +================ +idEntity::SetColor +================ +*/ +void idEntity::SetColor( const idVec3 &color ) { + SetColor( color[ 0 ], color[ 1 ], color[ 2 ] ); + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); +} + +/* +================ +idEntity::GetColor +================ +*/ +void idEntity::GetColor( idVec3 &out ) const { + out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ]; + out[ 1 ] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; + out[ 2 ] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; +} + +/* +================ +idEntity::SetColor +================ +*/ +void idEntity::SetColor( const idVec4 &color ) { + renderEntity.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ]; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); +} + +/* +================ +idEntity::SetAlpha + +Tels: Just set the alpha value. Note: Due to the D3 engine not being + able to render faces transparently with correct lighting (you + either get 100% opaque with correct light, or 50% transparent + with correct light, or X% transparent with incorrect light), + this doesn't actually work unless you have a material + shader that takes the alpha value into account. +================ +*/ +void idEntity::SetAlpha( const float alpha ) { + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = alpha; + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); +} + +/* +================ +idEntity::SetAlpha + +Tels: Set alpha including on our children +================ +*/ +void idEntity::SetAlpha( const float alpha, const bool bound ) { + + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = alpha; + + if (!bound) + { + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); + return; + } + + // show our bind-children + idEntity *ent; + idEntity *next; + + for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) + { + next = ent->GetNextTeamEntity(); + if ( ent->GetBindMaster() == this ) + { + ent->SetAlpha( alpha ); + } + } + // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. + UpdateVisuals(); +} + +/* +================ +idEntity::GetColor +================ +*/ +void idEntity::GetColor( idVec4 &out ) const { + out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ]; + out[ 1 ] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; + out[ 2 ] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; + out[ 3 ] = renderEntity.shaderParms[ SHADERPARM_ALPHA ]; +} + +/* +================ +idEntity::UpdateAnimationControllers +================ +*/ +bool idEntity::UpdateAnimationControllers( void ) { + // any ragdoll and IK animation controllers should be updated here + return false; +} + +/* +================ +idEntity::SetModel +================ +*/ +void idEntity::SetModel( const char *modelname ) { + assert( modelname ); + + FreeModelDef(); + + // FIXME: temp hack to replace obsolete ips particles with prt particles + if ( strstr( modelname, ".ips" ) != NULL ) { + idStr str = modelname; + str.Replace( ".ips", ".prt" ); + renderEntity.hModel = renderModelManager->FindModel( str ); + } else { + renderEntity.hModel = renderModelManager->FindModel( modelname ); + } + + if ( renderEntity.hModel ) { + renderEntity.hModel->Reset(); + } + + renderEntity.callback = NULL; + + renderEntity.numJoints = 0; + renderEntity.joints = NULL; + if ( renderEntity.hModel ) { + renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); + } else { + renderEntity.bounds.Zero(); + } + + UpdateVisuals(); +} + +/* +================ +idEntity::SetSkin +================ +*/ +void idEntity::SetSkin( const idDeclSkin *skin ) { + renderEntity.customSkin = skin; + UpdateVisuals(); +} + +/* +================ +idEntity::GetSkin +================ +*/ +const idDeclSkin *idEntity::GetSkin( void ) const { + return renderEntity.customSkin; +} + +/* +================ +idEntity::FreeModelDef +================ +*/ +void idEntity::FreeModelDef( void ) { + if ( modelDefHandle != -1 ) { + gameRenderWorld->FreeEntityDef( modelDefHandle ); + modelDefHandle = -1; + } +} + +/* +================ +idEntity::FreeLightDef +================ +*/ +void idEntity::FreeLightDef( void ) { +} + +/* +================ +idEntity::IsHidden +================ +*/ +bool idEntity::IsHidden( void ) const { + return fl.hidden; +} + +/* +================ +idEntity::SetHideUntilTime +================ +*/ +void idEntity::SetHideUntilTime(int time) // grayman #597 +{ + m_HideUntilTime = time; +} + +/* +================ +idEntity::GetHideUntilTime +================ +*/ +int idEntity::GetHideUntilTime() // grayman #597 +{ + return m_HideUntilTime; +} + +/* +================ +idEntity::Hide +================ +*/ +void idEntity::Hide( void ) +{ + if ( !IsHidden() ) + { + fl.hidden = true; + + idPhysics* p = GetPhysics(); + + m_preHideContents = p->GetContents(); + m_preHideClipMask = p->GetClipMask(); + + if( m_FrobBox ) + m_FrobBox->SetContents(0); + + FreeModelDef(); + UpdateVisuals(); + + // If we are hiding a currently frobbed entity, + // set the frob pointers to NULL to avoid stale pointers + idPlayer* player = gameLocal.GetLocalPlayer(); + + if (player != NULL) + { + if (player->m_FrobEntity.GetEntity() == this) + { + player->m_FrobEntity = NULL; + } + } + + // hide our bind-children + for (idEntity* ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity()) + { + if (ent->GetBindMaster() == this) + { + ent->Hide(); + + if (ent->IsType(idLight::Type)) + { + static_cast(ent)->Off(); + } + } + } + } +} + +/* +================ +idEntity::Show +================ +*/ +void idEntity::Show( void ) +{ + // greebo: If the pre-hide clipmask is still uninitialised on Show(), the entity + // has not been hidden before. Set this to something valid (i.e. the current clipmask) + if ( m_preHideClipMask == -1) + { + m_preHideClipMask = GetPhysics()->GetClipMask(); + } + + if ( m_preHideContents == -1) + { + m_preHideContents = GetPhysics()->GetContents(); + } + + if ( IsHidden() ) + { + fl.hidden = false; + if( m_FrobBox && m_bFrobable ) + { + m_FrobBox->SetContents( CONTENTS_FROBABLE ); + } + UpdateVisuals(); + + // show our bind-children + idEntity *ent; + idEntity *next; + + for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) + { + next = ent->GetNextTeamEntity(); + if ( ent->GetBindMaster() == this ) + { + if (gameLocal.time >= ent->GetHideUntilTime()) // grayman #597 - one second needs to pass before showing + { + ent->Show(); + if ( ent->IsType( idLight::Type ) ) + { + static_cast( ent )->On(); + } + } + } + } + } +} + +float idEntity::GetLightQuotient() +{ + if (m_LightQuotientLastEvalTime < gameLocal.time) + { + idPhysics* physics = GetPhysics(); + + // Get the bounds and move it upwards a tiny bit + idBounds bounds = physics->GetAbsBounds() + physics->GetGravityNormal() * 0.1f; // Tweak to stay out of floors + + // A single point doesn't work with ellipse intersection + bounds.ExpandSelf(0.1f); + + // Update the cache + m_LightQuotientLastEvalTime = gameLocal.time; + m_LightQuotient = LAS.queryLightingAlongLine(bounds[0], bounds[1], this, true); + } + + // Return the cached result + return m_LightQuotient; +} + +/* +================ +idEntity::Event_noShadows + +tels: Turn shadows from this entity on or off. +================ +*/ +void idEntity::Event_noShadows( bool noShadow ) +{ + renderEntity.noShadow = ( noShadow ? 1 : 0 ); + UpdateVisuals(); +} + +/* +================ +idEntity::Event_CheckMine + +grayman #2478: Replace an armed mine with its projectile counterpart +================ +*/ +void idEntity::Event_CheckMine() +{ + if ( !spawnArgs.GetBool( "armed", "0" ) ) + { + return; // not armed, nothing to do + } + + const char* replaceWith = spawnArgs.GetString( "def_armed" ); // get replacement entity def + + const idDict *resultDef = gameLocal.FindEntityDefDict( replaceWith, false ); + if ( resultDef ) + { + idEntity *newMine; + gameLocal.SpawnEntityDef( *resultDef, &newMine, false ); + idProjectile* projectile = static_cast(newMine); + projectile->Launch( GetPhysics()->GetOrigin(), idVec3( 0,0,1 ), vec3_origin ); + + // Undo the launch parameters to keep the mine from flying away. + + idPhysics* projPhysics = projectile->GetPhysics(); + projPhysics->SetOrigin( GetPhysics()->GetOrigin() ); + projPhysics->SetAxis( GetPhysics()->GetAxis() ); + projPhysics->SetLinearVelocity( vec3_origin ); + projPhysics->SetAngularVelocity( vec3_origin ); + projPhysics->PutToRest(); + projectile->UpdateVisuals(); + projectile->SetReplaced(); // grayman #2908 - note that this mine replaced an author-placed armed mine + + SetFrobable(false); + PostEventMS( &EV_Remove, 1 ); // Remove the mine, which has been replaced + } +} + +/* +================ +idEntity::Event_GetVinePlantLoc + +grayman #2787: Return the planting location resulting from a trace +================ +*/ +void idEntity::Event_GetVinePlantLoc() +{ + idThread::ReturnVector( m_VinePlantLoc ); +} + +/* +================ +idEntity::Event_GetVinePlantNormal + +grayman #2787: Return the planting location surface normal resulting from a trace +================ +*/ +void idEntity::Event_GetVinePlantNormal() +{ + idThread::ReturnVector( m_VinePlantNormal ); +} + +/* +================ +idEntity::UpdateModelTransform +================ +*/ +void idEntity::UpdateModelTransform( void ) { + idVec3 origin; + idMat3 axis; + + if ( GetPhysicsToVisualTransform( origin, axis ) ) { + renderEntity.axis = axis * GetPhysics()->GetAxis(); + renderEntity.origin = GetPhysics()->GetOrigin() + origin * renderEntity.axis; + } else { + renderEntity.axis = GetPhysics()->GetAxis(); + renderEntity.origin = GetPhysics()->GetOrigin(); + } +} + +/* +================ +idEntity::UpdateModel +================ +*/ +void idEntity::UpdateModel( void ) { + UpdateModelTransform(); + + // check if the entity has an MD5 model + idAnimator *animator = GetAnimator(); + if(animator && animator->ModelHandle()) + { + // set the callback to update the joints + renderEntity.callback = idEntity::ModelCallback; + } + + // set to invalid number to force an update the next time the PVS areas are retrieved + ClearPVSAreas(); + + // ensure that we call Present this frame + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idEntity::UpdateVisuals +================ +*/ +void idEntity::UpdateVisuals( void ) { + UpdateModel(); + UpdateSound(); +} + +/* +================ +idEntity::UpdatePVSAreas +================ +*/ +void idEntity::UpdatePVSAreas( void ) { + int localNumPVSAreas, localPVSAreas[32]; + idBounds modelAbsBounds; + int i; + + modelAbsBounds.FromTransformedBounds( renderEntity.bounds, renderEntity.origin, renderEntity.axis ); + localNumPVSAreas = gameLocal.pvs.GetPVSAreas( modelAbsBounds, localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); + + // FIXME: some particle systems may have huge bounds and end up in many PVS areas + // the first MAX_PVS_AREAS may not be visible to a network client and as a result the particle system may not show up when it should + if ( localNumPVSAreas > MAX_PVS_AREAS ) { + localNumPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( modelAbsBounds.GetCenter() ).Expand( 64.0f ), localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); + } + + for ( numPVSAreas = 0; numPVSAreas < MAX_PVS_AREAS && numPVSAreas < localNumPVSAreas; numPVSAreas++ ) { + PVSAreas[numPVSAreas] = localPVSAreas[numPVSAreas]; + } + + for( i = numPVSAreas; i < MAX_PVS_AREAS; i++ ) { + PVSAreas[ i ] = 0; + } +} + +/* +================ +idEntity::UpdatePVSAreas +================ +*/ +void idEntity::UpdatePVSAreas( const idVec3 &pos ) { + int i; + + numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( pos ), PVSAreas, MAX_PVS_AREAS ); + i = numPVSAreas; + while ( i < MAX_PVS_AREAS ) { + PVSAreas[ i++ ] = 0; + } +} + +/* +================ +idEntity::GetNumPVSAreas +================ +*/ +int idEntity::GetNumPVSAreas( void ) { + if ( numPVSAreas < 0 ) { + UpdatePVSAreas(); + } + return numPVSAreas; +} + +/* +================ +idEntity::GetPVSAreas +================ +*/ +const int *idEntity::GetPVSAreas( void ) { + if ( numPVSAreas < 0 ) { + UpdatePVSAreas(); + } + return PVSAreas; +} + +/* +================ +idEntity::ClearPVSAreas +================ +*/ +void idEntity::ClearPVSAreas( void ) { + numPVSAreas = -1; +} + +/* +================ +idEntity::PhysicsTeamInPVS + + FIXME: for networking also return true if any of the entity shadows is in the PVS +================ +*/ +bool idEntity::PhysicsTeamInPVS( pvsHandle_t pvsHandle ) { + idEntity *part; + + if ( teamMaster ) { + for ( part = teamMaster; part; part = part->teamChain ) { + if ( gameLocal.pvs.InCurrentPVS( pvsHandle, part->GetPVSAreas(), part->GetNumPVSAreas() ) ) { + return true; + } + } + } else { + return gameLocal.pvs.InCurrentPVS( pvsHandle, GetPVSAreas(), GetNumPVSAreas() ); + } + return false; +} + +/* +============== +idEntity::ProjectOverlay +============== +*/ +void idEntity::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { + float s, c; + idMat3 axis, axistemp; + idVec3 localOrigin, localAxis[2]; + idPlane localPlane[2]; + + // make sure the entity has a valid model handle + if ( modelDefHandle < 0 ) { + return; + } + + // only do this on dynamic md5 models + if ( renderEntity.hModel->IsDynamicModel() != DM_CACHED ) { + return; + } + + idMath::SinCos16( gameLocal.random.RandomFloat() * idMath::TWO_PI, s, c ); + + axis[2] = -dir; + axis[2].NormalVectors( axistemp[0], axistemp[1] ); + axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; + axis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; + + renderEntity.axis.ProjectVector( origin - renderEntity.origin, localOrigin ); + renderEntity.axis.ProjectVector( axis[0], localAxis[0] ); + renderEntity.axis.ProjectVector( axis[1], localAxis[1] ); + + size = 1.0f / size; + localAxis[0] *= size; + localAxis[1] *= size; + + localPlane[0] = localAxis[0]; + localPlane[0][3] = -( localOrigin * localAxis[0] ) + 0.5f; + + localPlane[1] = localAxis[1]; + localPlane[1][3] = -( localOrigin * localAxis[1] ) + 0.5f; + + const idMaterial *mtr = declManager->FindMaterial( material ); + + // project an overlay onto the model + gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr ); + + // make sure non-animating models update their overlay + UpdateVisuals(); +} + +/* +================ +idEntity::Present + +Present is called to allow entities to generate refEntities, lights, etc for the renderer. +================ +*/ +void idEntity::Present(void) +{ +/* + if( m_bFrobable ) + { +*/ +/* + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("this: %08lX FrobDistance: %lu\r", this, m_FrobDistance); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("RenderEntity: %08lX\r", renderEntity); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("SurfaceInView: %u\r", renderEntity.allowSurfaceInViewID); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("RenderModel: %08lX\r", renderEntity.hModel); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("CustomShader: %08lX\r", renderEntity.customShader); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ReferenceShader: %08lX\r", renderEntity.referenceShader); + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ReferenceShader: %08lX\r", renderEntity.referenceShader); + + for(int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++) + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("Shaderparam[%u]: %f\r", i, renderEntity.shaderParms[i]); + + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ForceUpdate: %u\r", renderEntity.forceUpdate); + + renderEntity.customShader = gameLocal.GetGlobalMaterial(); + } +*/ + + if(!gameLocal.isNewFrame ) + return; + + if( m_bFrobable ) + { + UpdateFrobState(); + UpdateFrobDisplay(); + } + + // don't present to the renderer if the entity hasn't changed + if(!(thinkFlags & TH_UPDATEVISUALS)) + return; + + if( !m_bFrobable ) + { + BecomeInactive( TH_UPDATEVISUALS ); + } + + // camera target for remote render views + if(cameraTarget && gameLocal.InPlayerPVS(this)) + renderEntity.remoteRenderView = cameraTarget->GetRenderView(); + + // if set to invisible, skip + if(!renderEntity.hModel || IsHidden()) + return; + + // add to refresh list + if ( modelDefHandle == -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } + + PresentRenderTrigger(); +} + +/* +================ +idEntity::GetRenderEntity +================ +*/ +renderEntity_t *idEntity::GetRenderEntity( void ) { + return &renderEntity; +} + +/* +================ +idEntity::GetModelDefHandle +================ +*/ +int idEntity::GetModelDefHandle( void ) { + return modelDefHandle; +} + +/* +================ +idEntity::UpdateRenderEntity +================ +*/ +bool idEntity::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) +{ + if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { + return false; + } + + idAnimator *animator = GetAnimator(); + if ( animator ) { + return animator->CreateFrame( gameLocal.time, false ); + } + + return false; +} + +/* +================ +idEntity::ModelCallback + + NOTE: may not change the game state whatsoever! +================ +*/ +bool idEntity::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) +{ + idEntity *ent; + + ent = gameLocal.entities[ renderEntity->entityNum ]; + + if ( !ent ) { + gameLocal.Error( "idEntity::ModelCallback: callback with NULL game entity" ); + } + + return ent->UpdateRenderEntity( renderEntity, renderView ); +} + +/* +================ +idEntity::GetAnimator + +Subclasses will be responsible for allocating animator. +================ +*/ +idAnimator *idEntity::GetAnimator( void ) { + return NULL; +} + +/* +============= +idEntity::GetRenderView + +This is used by remote camera views to look from an entity +============= +*/ +renderView_t *idEntity::GetRenderView( void ) { + if ( !renderView ) { + renderView = new renderView_t; + } + memset( renderView, 0, sizeof( *renderView ) ); + + renderView->vieworg = GetPhysics()->GetOrigin(); + renderView->fov_x = 120; + renderView->fov_y = 120; + renderView->viewaxis = GetPhysics()->GetAxis(); + + // copy global shader parms + for( int i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + renderView->shaderParms[ i ] = gameLocal.globalShaderParms[ i ]; + } + + renderView->globalMaterial = gameLocal.GetGlobalMaterial(); + + renderView->time = gameLocal.time; + + return renderView; +} + +void idEntity::Activate(idEntity* activator) +{ + // Fire the TRIGGER response + TriggerResponse(activator, ST_TRIGGER); + + if (RespondsTo(EV_Activate) || HasSignal(SIG_TRIGGER)) + { + Signal(SIG_TRIGGER); + ProcessEvent(&EV_Activate, activator); + TriggerGuis(); + } +} + +/*********************************************************************** + + Sound + +***********************************************************************/ + +/* +================ +idEntity::CanPlayChatterSounds + +Used for playing chatter sounds on monsters. +================ +*/ +bool idEntity::CanPlayChatterSounds( void ) const { + return true; +} + +/* +================ +idEntity::StartSound +================ +*/ +bool idEntity::StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length, float propVolMod) +{ + const idSoundShader *shader; + const char *sound; + + if ( length ) + *length = 0; + + // we should ALWAYS be playing sounds from the def. + // hardcoded sounds MUST be avoided at all times because they won't get precached. + assert( idStr::Icmpn( soundName, "snd_", 4 ) == 0 ); + + if ( !spawnArgs.GetString( soundName, "", &sound ) ) + return false; + + // ignore empty spawnargs + if ( sound[0] == '\0' ) + return false; + + if ( !gameLocal.isNewFrame ) + { + // don't play the sound, but don't report an error + return true; + } + + // DarkMod sound propagation: + PropSoundDirect(soundName, true, false, propVolMod); + + // play the audible sound + shader = declManager->FindSound( sound ); + + return StartSoundShader( shader, channel, soundShaderFlags, broadcast, length ); +} + +/* +================ +idEntity::StartSoundShader +================ +*/ +bool idEntity::StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length) { + float diversity; + int len; + + if ( length ) { + *length = 0; + } + + if ( !shader ) { + return false; + } + + if ( !gameLocal.isNewFrame ) { + return true; + } + + if ( gameLocal.isServer && broadcast ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_SOUND, shader->Index() ) ); + msg.WriteByte( channel ); + ServerSendEvent( EVENT_STARTSOUNDSHADER, &msg, false, -1 ); + } + + // set a random value for diversity unless one was parsed from the entity + + if ( refSound.diversity < 0.0f ) + { + diversity = gameLocal.random.RandomFloat(); + + // grayman #2341 - adjust diversity based on previous sound request, + // to eliminate consecutive sounds. This + // is necessary because sometimes the engine plays the + // wrong sound when the 'no_dup' flag is set. + + int n = shader->GetNumSounds(); + if (n > 1) // duplication is expected when there's only 1 sound choice + { + if (channel == SND_CHANNEL_VOICE) + { + if ((shader == previousVoiceShader) && (previousVoiceIndex == static_cast(diversity * n) + 1)) + { + diversity = (static_cast (previousVoiceIndex % n))/(static_cast (n)) + 0.01; // add 0.01 to move off the boundary + } + } + else if (channel == SND_CHANNEL_BODY) + { + if ((shader == previousBodyShader) && (previousBodyIndex == static_cast(diversity * n) + 1)) + { + diversity = (static_cast (previousBodyIndex % n))/(static_cast (n)) + 0.01; // add 0.01 to move off the boundary + } + } + } + } + else + { + diversity = refSound.diversity; + } + + // if we don't have a soundEmitter allocated yet, get one now + if ( !refSound.referenceSound ) { + refSound.referenceSound = gameSoundWorld->AllocSoundEmitter(); + } + + UpdateSound(); + + len = refSound.referenceSound->StartSound( shader, channel, diversity, soundShaderFlags ); + + // grayman #2341 - It's rare for the engine to not play the sound, but it can happen. If this happens, don't + // register this sound as the previous sound played. Stick with the one before that. + + if (len > 0) + { + if (channel == SND_CHANNEL_VOICE) + { + previousVoiceShader = (idSoundShader*)shader; // shader for the most recent voice request + previousVoiceIndex = static_cast(diversity * shader->GetNumSounds()) + 1; // index of most recent sound requested (1->N, where there are N sounds) + } + else if (channel == SND_CHANNEL_BODY) + { + previousBodyShader = (idSoundShader*)shader; // shader for the most recent body request + previousBodyIndex = static_cast(diversity * shader->GetNumSounds()) + 1; // index of most recent sound requested (1->N, where there are N sounds) + } + } + + if ( length ) { + *length = len; + } + + // set reference to the sound for shader synced effects + renderEntity.referenceSound = refSound.referenceSound; + + return true; +} + +/* +================ +idEntity::StopSound +================ +*/ +void idEntity::StopSound( const s_channelType channel, bool broadcast ) { + if ( !gameLocal.isNewFrame ) { + return; + } + + if ( gameLocal.isServer && broadcast ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteByte( channel ); + ServerSendEvent( EVENT_STOPSOUNDSHADER, &msg, false, -1 ); + } + + if ( refSound.referenceSound ) { + refSound.referenceSound->StopSound( channel ); + } +} + +/* +================ +idEntity::SetSoundVolume + + Must be called before starting a new sound. +================ +*/ +void idEntity::SetSoundVolume( float volume ) { + refSound.parms.volume = volume; +} + +/* +================ +idEntity::UpdateSound +================ +*/ +void idEntity::UpdateSound( void ) { + if ( refSound.referenceSound ) { + idVec3 origin; + idMat3 axis; + + if ( GetPhysicsToSoundTransform( origin, axis ) ) { + refSound.origin = GetPhysics()->GetOrigin() + origin * axis; + } else { + refSound.origin = GetPhysics()->GetOrigin(); + } + + refSound.referenceSound->UpdateEmitter( refSound.origin, refSound.listenerId, &refSound.parms ); + } +} + +/* +================ +idEntity::GetListenerId +================ +*/ +int idEntity::GetListenerId( void ) const { + return refSound.listenerId; +} + +/* +================ +idEntity::GetSoundEmitter +================ +*/ +idSoundEmitter *idEntity::GetSoundEmitter( void ) const { + return refSound.referenceSound; +} + +/* +================ +idEntity::FreeSoundEmitter +================ +*/ +void idEntity::FreeSoundEmitter( bool immediate ) { + if ( refSound.referenceSound ) { + refSound.referenceSound->Free( immediate ); + refSound.referenceSound = NULL; + } +} + +/* +================ +idEntity::PropSoundS +================ +*/ + +// note: the format for kv pair is: :volMod,durMod +// the last two values should be optional, so :volMod, +// and ,durMod also work. + +void idEntity::PropSoundS( const char *localName, const char *globalName, float VolModIn ) +{ + if (cv_sndprop_disable.GetBool()) + { + return; + } + + int start, end = -1, len; + bool bHasComma(false), bHasColon(false), bFoundSnd(false); + float volMod(0.0), durMod(1.0); + idStr gName(globalName); + + // if there is no local name, skip all the loading of local flags + // and parms. + if( localName == NULL ) + { + bFoundSnd = gameLocal.m_sndProp->CheckSound( globalName, false ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundS: Propagating global sound %s without checking local sound\r", globalName); + // note: if we are doing the global only, gName remains set to globalName + goto Quit; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundS: Found local sound %s, parsing local sound modifiers\r", localName); + + // parse the volMod and durMod if they are tacked on to the globalName + len = gName.Length(); + + // parse volMod, when durMod may or may not be present + if( (start = gName.Find(':')) != -1 ) + { + bHasColon = true; + start++; + end = gName.Find(','); + + if( end == -1 ) + end = gName.Length(); + + idStr tempstr = gName.Mid(start, (end - start)); + + if( !tempstr.IsNumeric() || start >= end ) + { + gameLocal.Warning( "[Soundprop] Bad volume multiplier for sound %s on entity %s.", localName, name.c_str() ); + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Bad volume multiplier for sound %s on entity %s.\r", localName, name.c_str() ); + } + else + { + volMod = atof( tempstr.c_str() ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local volume modifier %f \r", volMod); + } + } + + // parse durMod + if( (start = gName.Find(',')) != -1 ) + { + bHasComma = true; + start++; + end = gName.Length(); + + idStr tempstr = gName.Mid(start, (end - start)); + if( !tempstr.IsNumeric() || start >= end ) + { + gameLocal.Warning( "[Soundprop] Bad duration multiplier for sound %s on entity %s.", localName, name.c_str() ); + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Bad duration multiplier for sound %s on entity %s.\r", localName, name.c_str() ); + } + else + { + durMod = atof( tempstr.c_str() ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local duration modifier %f \r", durMod); + } + } + + // TODO: Get the extra flags, freqmod and bandwidthmod from another key/value pair + // we will need locName for this. + + // strip the durmod and volmod off of the global name + if( bHasColon ) + end = gName.Find(':'); + else if( bHasComma && !bHasColon ) + end = gName.Find(','); + else if( !bHasComma && !bHasColon ) + end = gName.Length(); + + gName = gName.Mid(0, end); + + bFoundSnd = gameLocal.m_sndProp->CheckSound( gName.c_str(), false ); + +Quit: + if( bFoundSnd ) + { + // add the input volume modifier + volMod += VolModIn; + + gameLocal.m_sndProp->Propagate( volMod, durMod, gName, + GetPhysics()->GetOrigin(), + this ); + } + + return; +} + +/* +================ +idEntity::PropSoundE +================ +*/ + +void idEntity::PropSoundE( const char *localName, const char *globalName, float VolModIn ) +{ + bool bFoundSnd(false); + float volMod(0.0); + idStr gName(globalName), locName(localName), tempstr; + + if( localName == NULL ) + { + bFoundSnd = gameLocal.m_sndProp->CheckSound( globalName, true ); + // if we are doing the global only, gName remains set to globalName + goto Quit; + } + + // do the parsing of the local vars that modify the Env. sound + + // strip gName of all modifiers at the end + + // add the input volume modifier + volMod += VolModIn; + +Quit: + + if( bFoundSnd ) + { + //TODO : Call soundprop to add env. sound to list + // have not written this sndprop functionality yet! + } + else + { + // log error, did not find sound in sound def file + } + return; +} + +/* +================ +idEntity::PropSoundDirect +================ +*/ + +void idEntity::PropSoundDirect( const char *sndName, bool bForceLocal, bool bAssumeEnv, float VolModIn ) +{ + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundDirect: Attempting to propagate sound \"%s\" Forcelocal = %d\r", sndName, (int) bForceLocal ); + + // Cut off the "snd_" prefix from the incoming sound name + idStr sprName = sndName; + + sprName.StripLeading("snd_"); + + // Check if we have spr* definitions on the local spawnargs + idStr sprNameSG; + idStr sprNameEG; + bool bIsSusp = spawnArgs.GetString( ("sprS_" + sprName) , "", sprNameSG ); + bool bIsEnv = spawnArgs.GetString( ("sprE_" + sprName) , "", sprNameEG ); + + if (bForceLocal && + ( !(idStr::Icmpn( sndName, "snd_", 4 ) == 0) || ( !bIsSusp && !bIsEnv ) ) ) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Attempted to propagate nonexistant local sound \"%s\" (forceLocal = true)\r", sndName ); + // gameLocal.Warning("[PropSound] Attempted to propagate nonexistant local sound \"%s\" (forceLocal = true)", sndName ); + return; + } + + if (bIsSusp) + { + PropSoundS( sprName.c_str(), sprNameSG.c_str(), VolModIn ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local suspicious sound def for %s on entity, attempting to propagate with global sound %s\r", sprName.c_str(), sprNameSG.c_str() ); + // exit here, because we don't want to allow playing both + // env. sound AND susp. sound for the same sound and entity + return; + } + else if (bIsEnv) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local environmental sound def for %s on entity, attempting to propagating with global sound %s\r", sprName.c_str(), sprNameEG.c_str() ); + PropSoundE( sprName.c_str(), sprNameEG.c_str(), VolModIn ); + return; + } + + // no environmental or suspicious sound + // play the unmodified, global sound directly + sprNameSG = sndName; + sprNameEG = sndName; + + // play the global sound directly. + if ( bAssumeEnv ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Did not find local def for sound %s, attempting to propagate it as global environmental\r", sprNameEG.c_str() ); + PropSoundE( NULL, sprNameEG.c_str(), VolModIn ); + return; + } + else + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Did not find local def for sound %s, attempting to propagate it as global suspicious\r", sprNameSG.c_str() ); + PropSoundS( NULL, sprNameSG.c_str(), VolModIn ); + } +} + +/*********************************************************************** + + entity binding + +***********************************************************************/ + +/* +================ +idEntity::PreBind +================ +*/ +void idEntity::PreBind( void ) +{ +} + +/* +================ +idEntity::PostBind +================ +*/ +void idEntity::PostBind( void ) +{ +} + +/* +================ +idEntity::PreUnbind +================ +*/ +void idEntity::PreUnbind( void ) +{ +} + +/* +================ +idEntity::PostUnbind +================ +*/ +void idEntity::PostUnbind( void ) +{ +} + +/* +================ +idEntity::InitBind +================ +*/ +bool idEntity::InitBind( idEntity *master ) +{ + if ( master == this ) { + gameLocal.Error( "Tried to bind an object to itself." ); + return false; + } + + if ( this == gameLocal.world ) { + gameLocal.Error( "Tried to bind world to another entity" ); + return false; + } + + // unbind myself from my master + // angua: only do this if the entity is already bound to something + // and the new master is different from the old one + if (bindMaster != NULL && master != bindMaster) + { + Unbind(); + } + + // add any bind constraints to an articulated figure + if ( master && IsType( idAFEntity_Base::Type ) ) { + static_cast(this)->AddBindConstraints(); + } + +// TDM: Removed the inability to bind something to the world +// Might have to put it back in if something unforseen happens later because of this +// if ( !master || master == gameLocal.world ) + if ( !master ) + { + // this can happen in scripts, so safely exit out. + return false; + } + + return true; +} + +/* +================ +idEntity::FinishBind +================ +*/ +void idEntity::FinishBind( void ) +{ + // set the master on the physics object + physics->SetMaster( bindMaster, fl.bindOrientated ); + + // We are now separated from our previous team and are either + // an individual, or have a team of our own. Now we can join + // the new bindMaster's team. Bindmaster must be set before + // joining the team, or we will be placed in the wrong position + // on the team. + JoinTeam( bindMaster ); + + // if our bindMaster is enabled during a cinematic, we must be, too + cinematic = bindMaster->cinematic; + + // make sure the team master is active so that physics get run + teamMaster->BecomeActive( TH_PHYSICS ); + + // Notify bindmaster of this binding + bindMaster->BindNotify( this ); +} + +/* +================ +idEntity::Bind + + bind relative to the visual position of the master +================ +*/ +void idEntity::Bind( idEntity *master, bool orientated ) +{ + if ( !InitBind( master ) ) + return; + + // ishtvan: 30/1/2010 : Check for ragdoll adding on idAFAttachment masters when just bind is called + // (previously only done when bindToJoint or bindToBody was called) + if ( + master->IsType( idAFAttachment::Type ) + && !IsType( idAnimatedEntity::Type ) + && ( GetPhysics()->GetClipModel() != NULL ) + && ( GetPhysics()->GetClipModel()->IsTraceModel() ) + && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) + ) + { + idAFAttachment *masterAFAtt = static_cast(master); + idEntity *masterBody = masterAFAtt->GetBody(); + if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) + static_cast(masterBody)->AddEntByJoint( this, masterAFAtt->GetAttachJoint() ); + } + + + PreBind(); + + bindJoint = INVALID_JOINT; + bindBody = -1; + bindMaster = master; + fl.bindOrientated = orientated; + + FinishBind(); + + PostBind( ); +} + +/* +================ +idEntity::BindToJoint + + bind relative to a joint of the md5 model used by the master +================ +*/ +void idEntity::BindToJoint( idEntity *master, const char *jointname, bool orientated ) { + jointHandle_t jointnum; + idAnimator *masterAnimator; + + masterAnimator = master->GetAnimator(); + if ( !masterAnimator ) + { + gameLocal.Warning( "idEntity::BindToJoint: entity '%s' cannot support skeletal models.", master->GetName() ); + return; + } + + jointnum = masterAnimator->GetJointHandle( jointname ); + + if ( !InitBind( master ) ) + return; + + // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) + if ( + (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) + && !IsType( idAnimatedEntity::Type ) + && ( jointnum != INVALID_JOINT ) + && ( GetPhysics()->GetClipModel() != NULL ) + && ( GetPhysics()->GetClipModel()->IsTraceModel() ) + && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) + ) + { + if( master->IsType( idAFEntity_Base::Type ) ) + static_cast(master)->AddEntByJoint( this, jointnum ); + else if( master->IsType( idAFAttachment::Type ) ) + { + idEntity *masterBody = static_cast(master)->GetBody(); + if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) + static_cast(masterBody)->AddEntByJoint( this, jointnum ); + } + } + + if ( jointnum == INVALID_JOINT ) { + gameLocal.Warning( "idEntity::BindToJoint: joint '%s' not found on entity '%s'.", jointname, master->GetName() ); + } + + PreBind(); + + bindJoint = jointnum; + bindBody = -1; + bindMaster = master; + fl.bindOrientated = orientated; + + FinishBind(); + + PostBind(); +} + +/* +================ +idEntity::BindToJoint + + bind relative to a joint of the md5 model used by the master +================ +*/ +void idEntity::BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated ) +{ + if ( !InitBind( master ) ) + return; + + // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) + if ( + (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) + && !IsType( idAnimatedEntity::Type ) + && ( jointnum != INVALID_JOINT ) + && ( GetPhysics()->GetClipModel() != NULL ) + && ( GetPhysics()->GetClipModel()->IsTraceModel() ) + && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) + ) + { + if( master->IsType( idAFEntity_Base::Type ) ) + static_cast(master)->AddEntByJoint( this, jointnum ); + else if( master->IsType( idAFAttachment::Type ) ) + { + idEntity *masterBody = static_cast(master)->GetBody(); + if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) + static_cast(masterBody)->AddEntByJoint( this, jointnum ); + } + } + + PreBind(); + + bindJoint = jointnum; + bindBody = -1; + bindMaster = master; + fl.bindOrientated = orientated; + + FinishBind(); + + PostBind(); +} + +/* +================ +idEntity::BindToBody + + bind relative to a collision model used by the physics of the master +================ +*/ +void idEntity::BindToBody( idEntity *master, int bodyId, bool orientated ) +{ + if ( !InitBind( master ) ) + return; + + // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) + if ( + (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) + && !IsType( idAnimatedEntity::Type ) + && ( GetPhysics()->GetClipModel() != NULL ) + && ( GetPhysics()->GetClipModel()->IsTraceModel() ) + && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) + ) + { + if( master->IsType( idAFEntity_Base::Type ) ) + static_cast(master)->AddEntByBody( this, bodyId ); + else if( master->IsType( idAFAttachment::Type ) ) + { + idEntity *masterBody = static_cast(master)->GetBody(); + if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) + static_cast(masterBody)->AddEntByBody( this, bodyId ); + } + } + + if ( bodyId < 0 ) + gameLocal.Warning( "idEntity::BindToBody: body '%d' not found.", bodyId ); + + PreBind(); + + bindJoint = INVALID_JOINT; + bindBody = bodyId; + bindMaster = master; + fl.bindOrientated = orientated; + + FinishBind(); + + PostBind(); +} + +/* +================ +idEntity::Unbind +================ +*/ +void idEntity::Unbind( void ) { + idEntity * prev; + idEntity * next; + idEntity * last; + idEntity * ent; + + // remove any bind constraints from an articulated figure + if ( IsType( idAFEntity_Base::Type ) ) { + static_cast(this)->RemoveBindConstraints(); + } + + if ( !bindMaster ) { + return; + } + + // TDM: Notify bindmaster of unbinding + bindMaster->UnbindNotify( this ); + + if ( !teamMaster ) { + // Teammaster already has been freed + bindMaster = NULL; + return; + } + + PreUnbind(); + + if ( physics ) { + physics->SetMaster( NULL, fl.bindOrientated ); + } + + // We're still part of a team, so that means I have to extricate myself + // and any entities that are bound to me from the old team. + // Find the node previous to me in the team + prev = teamMaster; + for( ent = teamMaster->teamChain; ent && ( ent != this ); ent = ent->teamChain ) { + prev = ent; + } + + assert( ent == this ); // If ent is not pointing to this, then something is very wrong. + + // Find the last node in my team that is bound to me. + // Also find the first node not bound to me, if one exists. + last = this; + for( next = teamChain; next != NULL; next = next->teamChain ) { + if ( !next->IsBoundTo( this ) ) { + break; + } + + // Tell them I'm now the teamMaster + next->teamMaster = this; + last = next; + } + + // disconnect the last member of our team from the old team + last->teamChain = NULL; + + // connect up the previous member of the old team to the node that + // follow the last node bound to me (if one exists). + if ( teamMaster != this ) { + prev->teamChain = next; + if ( !next && ( teamMaster == prev ) ) { + prev->teamMaster = NULL; + } + } else if ( next ) { + // If we were the teamMaster, then the nodes that were not bound to me are now + // a disconnected chain. Make them into their own team. + for( ent = next; ent->teamChain != NULL; ent = ent->teamChain ) { + ent->teamMaster = next; + } + next->teamMaster = next; + } + + // If we don't have anyone on our team, then clear the team variables. + if ( teamChain ) { + // make myself my own team + teamMaster = this; + } else { + // no longer a team + teamMaster = NULL; + } + + bindJoint = INVALID_JOINT; + bindBody = -1; + bindMaster = NULL; + + PostUnbind(); +} + +/* +================ +idEntity::RemoveBinds +================ +*/ +void idEntity::RemoveBinds( void ) { + idEntity *ent; + idEntity *next; + + for( ent = teamChain; ent != NULL; ent = next ) { + next = ent->teamChain; + // bound to us? + if ( ent->bindMaster == this ) { + ent->Unbind(); + + if( ent->spawnArgs.GetBool( "removeWithMaster", "1" ) ) { + ent->PostEventMS( &EV_Remove, 0 ); + } + next = teamChain; + } + } +} + +/* +================ +idEntity::DetachOnAlert + +tels: Remove attached entities when the alert index reaches their "unbindonalertindex". +The attached entities will be removed from the attached list and are also unbound. +================ +*/ +void idEntity::DetachOnAlert( const int alertIndex ) +{ + idEntity *ent = NULL; + + for ( int ind = 0; ind < m_Attachments.Num(); ind ++) + { + ent = m_Attachments[ind].ent.GetEntity(); + if( ent && m_Attachments[ind].ent.IsValid() ) + { + // Crispy: 9999 = "infinity" + if( alertIndex >= ent->spawnArgs.GetInt( "unbindonalertindex", "9999" )) + { + // Tels: + if ( ent->spawnArgs.GetInt("_spawned_by_anim","0") == 1 ) + { + // gameLocal.Printf("Removing entity %s spanwed by animation\n", ent->GetName() ); + // this entity was spawned automatically by an animation, remove it + // from the game to prevent left-overs from alerted-during-animation guards + ent->PostEventMS( &EV_Remove, 0 ); + // and make inactive in the meantime + ent->BecomeInactive(TH_PHYSICS|TH_THINK); + } + DetachInd(ind); + } + } + } +} + +/* +================ +idEntity::IsBound +================ +*/ +bool idEntity::IsBound( void ) const { + if ( bindMaster ) { + return true; + } + return false; +} + +/* +================ +idEntity::IsBoundTo +================ +*/ +bool idEntity::IsBoundTo( idEntity *master ) const { + idEntity *ent; + + if ( !bindMaster ) { + return false; + } + + for ( ent = bindMaster; ent != NULL; ent = ent->bindMaster ) { + if ( ent == master ) { + return true; + } + } + + return false; +} + +/* +================ +idEntity::GetBindMaster +================ +*/ +idEntity *idEntity::GetBindMaster( void ) const { + return bindMaster; +} + +/* +================ +idEntity::GetBindJoint +================ +*/ +jointHandle_t idEntity::GetBindJoint( void ) const { + return bindJoint; +} + +/* +================ +idEntity::GetBindBody +================ +*/ +int idEntity::GetBindBody( void ) const { + return bindBody; +} + +/* +================ +idEntity::GetTeamMaster +================ +*/ +idEntity *idEntity::GetTeamMaster( void ) const { + return teamMaster; +} + +/* +================ +idEntity::GetNextTeamEntity +================ +*/ +idEntity *idEntity::GetNextTeamEntity( void ) const { + return teamChain; +} + +/* +===================== +idEntity::ConvertLocalToWorldTransform +===================== +*/ +void idEntity::ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis ) { + UpdateModelTransform(); + + offset = renderEntity.origin + offset * renderEntity.axis; + axis *= renderEntity.axis; +} + +/* +================ +idEntity::GetLocalVector + +Takes a vector in worldspace and transforms it into the parent +object's localspace. + +Note: Does not take origin into acount. Use getLocalCoordinate to +convert coordinates. +================ +*/ +idVec3 idEntity::GetLocalVector( const idVec3 &vec ) const { + idVec3 pos; + + if ( !bindMaster ) { + return vec; + } + + idVec3 masterOrigin; + idMat3 masterAxis; + + GetMasterPosition( masterOrigin, masterAxis ); + masterAxis.ProjectVector( vec, pos ); + + return pos; +} + +/* +================ +idEntity::GetLocalCoordinates + +Takes a vector in world coordinates and transforms it into the parent +object's local coordinates. +================ +*/ +idVec3 idEntity::GetLocalCoordinates( const idVec3 &vec ) const { + idVec3 pos; + + if ( !bindMaster ) { + return vec; + } + + idVec3 masterOrigin; + idMat3 masterAxis; + + GetMasterPosition( masterOrigin, masterAxis ); + masterAxis.ProjectVector( vec - masterOrigin, pos ); + + return pos; +} + +/* +================ +idEntity::GetWorldVector + +Takes a vector in the parent object's local coordinates and transforms +it into world coordinates. + +Note: Does not take origin into acount. Use getWorldCoordinate to +convert coordinates. +================ +*/ +idVec3 idEntity::GetWorldVector( const idVec3 &vec ) const { + idVec3 pos; + + if ( !bindMaster ) { + return vec; + } + + idVec3 masterOrigin; + idMat3 masterAxis; + + GetMasterPosition( masterOrigin, masterAxis ); + masterAxis.UnprojectVector( vec, pos ); + + return pos; +} + +/* +================ +idEntity::GetWorldCoordinates + +Takes a vector in the parent object's local coordinates and transforms +it into world coordinates. +================ +*/ +idVec3 idEntity::GetWorldCoordinates( const idVec3 &vec ) const { + idVec3 pos; + + if ( !bindMaster ) { + return vec; + } + + idVec3 masterOrigin; + idMat3 masterAxis; + + GetMasterPosition( masterOrigin, masterAxis ); + masterAxis.UnprojectVector( vec, pos ); + pos += masterOrigin; + + return pos; +} + +/* +================ +idEntity::GetMasterPosition +================ +*/ +bool idEntity::GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const { + idVec3 localOrigin; + idMat3 localAxis; + idAnimator *masterAnimator; + + if ( bindMaster ) + { + // if bound to a joint of an animated model + if ( bindJoint != INVALID_JOINT ) + { + masterAnimator = bindMaster->GetAnimator(); + if ( !masterAnimator ) + { + masterOrigin = vec3_origin; + masterAxis = mat3_identity; + return false; + } else + { + // Use GetGlobalJointTransform for things bound to weapons + // This takes into account the view bob, weapon bob and other factors + if( bindMaster->IsType(idWeapon::Type) ) + { + static_cast(bindMaster)->GetGlobalJointTransform( true, bindJoint, masterOrigin, masterAxis ); + } + else + { + masterAnimator->GetJointTransform( bindJoint, gameLocal.time, masterOrigin, masterAxis ); + masterAxis *= bindMaster->renderEntity.axis; + masterOrigin = bindMaster->renderEntity.origin + masterOrigin * bindMaster->renderEntity.axis; + } + } + } else if ( bindBody >= 0 && bindMaster->GetPhysics() ) { + masterOrigin = bindMaster->GetPhysics()->GetOrigin( bindBody ); + masterAxis = bindMaster->GetPhysics()->GetAxis( bindBody ); + } else { + masterOrigin = bindMaster->renderEntity.origin; + masterAxis = bindMaster->renderEntity.axis; + } + return true; + } else { + masterOrigin = vec3_origin; + masterAxis = mat3_identity; + return false; + } +} + +/* +================ +idEntity::GetWorldVelocities +================ +*/ +void idEntity::GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const { + + linearVelocity = physics->GetLinearVelocity(); + angularVelocity = physics->GetAngularVelocity(); + + if ( bindMaster ) { + idVec3 masterOrigin, masterLinearVelocity, masterAngularVelocity; + idMat3 masterAxis; + + // get position of master + GetMasterPosition( masterOrigin, masterAxis ); + + // get master velocities + bindMaster->GetWorldVelocities( masterLinearVelocity, masterAngularVelocity ); + + // linear velocity relative to master plus master linear and angular velocity + linearVelocity = linearVelocity * masterAxis + masterLinearVelocity + + masterAngularVelocity.Cross( GetPhysics()->GetOrigin() - masterOrigin ); + } +} + +/* +================ +idEntity::JoinTeam +================ +*/ +void idEntity::JoinTeam( idEntity *teammember ) { + idEntity *ent; + idEntity *master; + idEntity *prev; + idEntity *next; + + // if we're already on a team, quit it so we can join this one + if ( teamMaster && ( teamMaster != this ) ) { + QuitTeam(); + } + + assert( teammember ); + + if ( teammember == this ) { + teamMaster = this; + return; + } + + // check if our new team mate is already on a team + master = teammember->teamMaster; + if ( !master ) { + // he's not on a team, so he's the new teamMaster + master = teammember; + teammember->teamMaster = teammember; + teammember->teamChain = this; + + // make anyone who's bound to me part of the new team + for( ent = teamChain; ent != NULL; ent = ent->teamChain ) { + ent->teamMaster = master; + } + } else { + // skip past the chain members bound to the entity we're teaming up with + prev = teammember; + next = teammember->teamChain; + if ( bindMaster ) { + // if we have a bindMaster, join after any entities bound to the entity + // we're joining + while( next && next->IsBoundTo( teammember ) ) { + prev = next; + next = next->teamChain; + } + } else { + // if we're not bound to someone, then put us at the end of the team + while( next ) { + prev = next; + next = next->teamChain; + } + } + + // make anyone who's bound to me part of the new team and + // also find the last member of my team + for( ent = this; ent->teamChain != NULL; ent = ent->teamChain ) { + ent->teamChain->teamMaster = master; + } + + prev->teamChain = this; + ent->teamChain = next; + } + + teamMaster = master; + + // reorder the active entity list + gameLocal.sortTeamMasters = true; +} + +idEntity* idEntity::FindMatchingTeamEntity(const idTypeInfo& type, idEntity* lastMatch) +{ + idEntity* part; + + if (lastMatch != NULL) + { + for (part = teamChain; part != NULL; part = part->teamChain) + { + if (part == lastMatch) + { + // We've found our previous match, increase the pointer and break; + part = part->teamChain; + break; + } + } + } + else + { + // No last match specified, set the pointer to the start + part = teamChain; + } + + for (/* no initialisation */; part != NULL; part = part->teamChain) + { + if (part->IsType(type)) + { + // Found a suitable one, return it + return part; + } + } + + return NULL; +} + +/* +================ +idEntity::QuitTeam +================ +*/ +void idEntity::QuitTeam( void ) { + idEntity *ent; + + if ( !teamMaster ) { + return; + } + + // check if I'm the teamMaster + if ( teamMaster == this ) { + // do we have more than one teammate? + if ( !teamChain->teamChain ) { + // no, break up the team + teamChain->teamMaster = NULL; + } else { + // yes, so make the first teammate the teamMaster + for( ent = teamChain; ent; ent = ent->teamChain ) { + ent->teamMaster = teamChain; + } + } + } else { + assert( teamMaster ); + assert( teamMaster->teamChain ); + + // find the previous member of the teamChain + ent = teamMaster; + while( ent->teamChain != this ) { + assert( ent->teamChain ); // this should never happen + ent = ent->teamChain; + } + + // remove this from the teamChain + ent->teamChain = teamChain; + + // if no one is left on the team, break it up + if ( !teamMaster->teamChain ) { + teamMaster->teamMaster = NULL; + } + } + + teamMaster = NULL; + teamChain = NULL; +} + +/*********************************************************************** + + Physics. + +***********************************************************************/ + +/* +================ +idEntity::InitDefaultPhysics +================ +*/ +void idEntity::InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis ) +{ + const char *temp; + idClipModel *clipModel = NULL; + + DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity [%s] test for clipmodel\r", name.c_str()); + + // check if a clipmodel key/value pair is set + if ( spawnArgs.GetString( "clipmodel", "", &temp ) ) { + if ( idClipModel::CheckModel( temp ) ) { + clipModel = new idClipModel( temp ); + } + } + + if(!spawnArgs.GetBool( "noclipmodel", "0" )) + { + // check if mins/maxs or size key/value pairs are set + if ( !clipModel ) + { + idVec3 size; + idBounds bounds; + bool setClipModel = false; + + if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) && + spawnArgs.GetVector( "maxs", NULL, bounds[1] ) ) + { + setClipModel = true; + if ( bounds[0][0] > bounds[1][0] || bounds[0][1] > bounds[1][1] || bounds[0][2] > bounds[1][2] ) + { + gameLocal.Error( "Invalid bounds '%s'-'%s' on entity '%s'", bounds[0].ToString(), bounds[1].ToString(), name.c_str() ); + } + } + else + if ( spawnArgs.GetVector( "size", NULL, size ) ) + { + if ( ( size.x < 0.0f ) || ( size.y < 0.0f ) || ( size.z < 0.0f ) ) + { + gameLocal.Error( "Invalid size '%s' on entity '%s'", size.ToString(), name.c_str() ); + } + bounds[0].Set( size.x * -0.5f, size.y * -0.5f, 0.0f ); + bounds[1].Set( size.x * 0.5f, size.y * 0.5f, size.z ); + setClipModel = true; + } + + if ( setClipModel ) { + int numSides; + idTraceModel trm; + + if ( spawnArgs.GetInt( "cylinder", "0", numSides ) && numSides > 0 ) { + trm.SetupCylinder( bounds, numSides < 3 ? 3 : numSides ); + } else if ( spawnArgs.GetInt( "cone", "0", numSides ) && numSides > 0 ) { + trm.SetupCone( bounds, numSides < 3 ? 3 : numSides ); + } else { + trm.SetupBox( bounds ); + } + clipModel = new idClipModel( trm ); + } + } + + // check if the visual model can be used as collision model + if ( !clipModel ) { + temp = spawnArgs.GetString( "model" ); + if ( ( temp != NULL ) && ( *temp != 0 ) ) { + if ( idClipModel::CheckModel( temp ) ) { + clipModel = new idClipModel( temp ); + } + } + } + } + else { + DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity [%s] does not contain a clipmodel\r", name.c_str()); + } + + defaultPhysicsObj.SetSelf( this ); + defaultPhysicsObj.SetClipModel( clipModel, 1.0f ); + defaultPhysicsObj.SetOrigin( origin ); + defaultPhysicsObj.SetAxis( axis ); + + physics = &defaultPhysicsObj; + + // create a frob box separate from the collision box for easier frobbing + bool bUseFrobBox(false); + idBounds bounds, FrobBounds; + idTraceModel FrobTrm; + int numSides(0); + + + // First check if frobbox_mins and frobbox_maxs are set + if ( spawnArgs.GetVector( "frobbox_mins", NULL, FrobBounds[0] ) && + spawnArgs.GetVector( "frobbox_maxs", NULL, FrobBounds[1] ) ) + { + if ( FrobBounds[0][0] > FrobBounds[1][0] || FrobBounds[0][1] >FrobBounds[1][1] || FrobBounds[0][2] > FrobBounds[1][2] ) + { + gameLocal.Error( "Invalid frob box bounds '%s'-'%s' on entity '%s'", FrobBounds[0].ToString(), FrobBounds[1].ToString(), name.c_str() ); + } + bUseFrobBox = true; + } + else + { + float tsize; + spawnArgs.GetFloat( "frobbox_size", "0.0", tsize ); + if( tsize != 0.0f ) + { + FrobBounds.Zero(); + FrobBounds.ExpandSelf( tsize ); + bUseFrobBox = true; + } + } + + // greebo: Allow the no_frob_box spawnarg to override the settings + if (spawnArgs.GetBool("no_frob_box", "0")) + { + bUseFrobBox = false; + } + + if( bUseFrobBox ) + { + if ( spawnArgs.GetInt( "frobbox_cylinder", "0", numSides ) && numSides > 0 ) + FrobTrm.SetupCylinder( FrobBounds, numSides < 3 ? 3 : numSides ); + else if ( spawnArgs.GetInt( "frobbox_cone", "0", numSides ) && numSides > 0 ) + FrobTrm.SetupCone( FrobBounds, numSides < 3 ? 3 : numSides ); + else + FrobTrm.SetupBox( FrobBounds ); + + // Initialize frob bounds based on previous spawnarg setup + m_FrobBox = new idClipModel( FrobTrm ); + m_FrobBox->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + // don't set contents of frob box here, wait for frobbing initialization + } + else + m_FrobBox = NULL; +} + +/* +================ +idEntity::SetPhysics +================ +*/ +void idEntity::SetPhysics( idPhysics *phys ) { + // clear any contacts the current physics object has + if ( physics ) { + physics->ClearContacts(); + } + // set new physics object or set the default physics if NULL + if ( phys != NULL ) { + defaultPhysicsObj.SetClipModel( NULL, 1.0f ); + physics = phys; + physics->Activate(); + } else { + physics = &defaultPhysicsObj; + } + physics->UpdateTime( gameLocal.time ); + physics->SetMaster( bindMaster, fl.bindOrientated ); +} + +/* +================ +idEntity::RestorePhysics +================ +*/ +void idEntity::RestorePhysics( idPhysics *phys ) { + assert( phys != NULL ); + // restore physics pointer + physics = phys; +} + +/* +================ +idEntity::GetPhysics +================ +*/ +idPhysics *idEntity::GetPhysics( void ) const { + return physics; +} + +/* +================ +idEntity::RunPhysics +================ +*/ +bool idEntity::RunPhysics( void ) { + int i, reachedTime, startTime, endTime; + idEntity * part, *blockedPart, *blockingEntity(NULL); + trace_t results; + bool moved; + + // don't run physics if not enabled + if ( !( thinkFlags & TH_PHYSICS ) ) { + // however do update any animation controllers + if ( UpdateAnimationControllers() ) { + BecomeActive( TH_ANIMATE ); + } + return false; + } + + // if this entity is a team slave don't do anything because the team master will handle everything + if ( teamMaster && teamMaster != this ) { + return false; + } + + // angua: since the AI are not thinking every frame, we need to rescale + // their velocities with the corrected time length to prevent them from dying. + if (IsType(idAI::Type)) + { + startTime = static_cast(this)->m_lastThinkTime; + } + else + { + startTime = gameLocal.previousTime; + } + endTime = gameLocal.time; + + gameLocal.push.InitSavingPushedEntityPositions(); + blockedPart = NULL; + + // save the physics state of the whole team and disable the team for collision detection + for ( part = this; part != NULL; part = part->teamChain ) { + if ( part->physics ) { + if ( !part->fl.solidForTeam ) { + part->physics->DisableClip(); + } + part->physics->SaveState(); + } + } + + // move the whole team + for ( part = this; part != NULL; part = part->teamChain ) { + + if ( part->physics ) + { + // run physics + moved = part->physics->Evaluate( endTime - startTime, endTime ); + // check if the object is blocked + blockingEntity = part->physics->GetBlockingEntity(); + if ( blockingEntity ) { + blockedPart = part; + break; + } + + // if moved or forced to update the visual position and orientation from the physics + if ( moved || part->fl.forcePhysicsUpdate ) { + part->UpdateFromPhysics( false ); + } + + // update any animation controllers here so an entity bound + // to a joint of this entity gets the correct position + if ( part->UpdateAnimationControllers() ) { + part->BecomeActive( TH_ANIMATE ); + } + } + } + + // enable the whole team for collision detection + for ( part = this; part != NULL; part = part->teamChain ) { + if ( part->physics ) + { +// Ish: I think Id screwed up here, but am not positive + // if ( !part->fl.solidForTeam ) { + part->physics->EnableClip(); + // } + } + } + + // if one of the team entities is a pusher and blocked + if ( blockedPart ) { + // move the parts back to the previous position + for ( part = this; part != blockedPart; part = part->teamChain ) { + + if ( part->physics ) { + // restore the physics state + part->physics->RestoreState(); + + // move back the visual position and orientation + part->UpdateFromPhysics( true ); + } + } + for ( part = this; part != NULL; part = part->teamChain ) { + if ( part->physics ) { + // update the physics time without moving + part->physics->UpdateTime( endTime ); + } + } + + // greebo: Apply the "reactio" to the team master + if (physics->IsType(idPhysics_RigidBody::Type)) + { + idPhysics_RigidBody* rigidBodyPhysics = static_cast(physics); + + // Calculate the movement (proportional to kinetic energy) + float movement = rigidBodyPhysics->GetLinearVelocity().LengthSqr() + + rigidBodyPhysics->GetAngularVelocity().LengthSqr(); + + //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Movement is %f\r", movement); + + if (movement < 10.0f) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Putting %s to rest, velocity was %f\r", name.c_str(), physics->GetLinearVelocity().LengthFast()); + physics->PutToRest(); + } + else + { + // Create a dummy impulse vector, it gets overwritten by the CollisionImpulse method anyway + idVec3 impulse(0,0,0); + rigidBodyPhysics->CollisionImpulse(*blockedPart->GetPhysics()->GetBlockingInfo(), impulse); + + // greebo: Apply some damping due to the collision with a slave + rigidBodyPhysics->State().i.linearMomentum *= 0.95f; + rigidBodyPhysics->State().i.angularMomentum *= 0.99f; + } + } + + // restore the positions of any pushed entities + gameLocal.push.RestorePushedEntityPositions(); + + if ( gameLocal.isClient ) { + return false; + } + + // if the master pusher has a "blocked" function, call it + Signal( SIG_BLOCKED ); + ProcessEvent( &EV_TeamBlocked, blockedPart, blockingEntity ); + // call the blocked function on the blocked part + blockedPart->ProcessEvent( &EV_PartBlocked, blockingEntity ); + return false; + } + + // set pushed + for ( i = 0; i < gameLocal.push.GetNumPushedEntities(); i++ ) { + idEntity *ent = gameLocal.push.GetPushedEntity( i ); + ent->physics->SetPushed( endTime - startTime ); + } + + if ( gameLocal.isClient ) { + return true; + } + + // post reached event if the current time is at or past the end point of the motion + for ( part = this; part != NULL; part = part->teamChain ) { + + if ( part->physics ) { + + reachedTime = part->physics->GetLinearEndTime(); + if ( startTime < reachedTime && endTime >= reachedTime ) { + part->ProcessEvent( &EV_ReachedPos ); + } + reachedTime = part->physics->GetAngularEndTime(); + if ( startTime < reachedTime && endTime >= reachedTime ) { + part->ProcessEvent( &EV_ReachedAng ); + } + } + } + + return true; +} + +/* +================ +idEntity::UpdateFromPhysics +================ +*/ +void idEntity::UpdateFromPhysics( bool moveBack ) { + + if ( IsType( idActor::Type ) ) { + idActor *actor = static_cast( this ); + + // set master delta angles for actors + if ( GetBindMaster() ) { + idAngles delta = actor->GetDeltaViewAngles(); + if ( moveBack ) { + delta.yaw -= static_cast(physics)->GetMasterDeltaYaw(); + } else { + delta.yaw += static_cast(physics)->GetMasterDeltaYaw(); + } + actor->SetDeltaViewAngles( delta ); + } + } + + UpdateVisuals(); +} + +/* +================ +idEntity::SetOrigin +================ +*/ +void idEntity::SetOrigin( const idVec3 &org ) { + + GetPhysics()->SetOrigin( org ); + + UpdateVisuals(); +} + +/* +================ +idEntity::SetAxis +================ +*/ +void idEntity::SetAxis( const idMat3 &axis ) { + + if ( GetPhysics()->IsType( idPhysics_Actor::Type ) ) { + static_cast(this)->viewAxis = axis; + } else { + GetPhysics()->SetAxis( axis ); + } + + UpdateVisuals(); +} + +/* +================ +idEntity::SetAngles +================ +*/ +void idEntity::SetAngles( const idAngles &ang ) { + SetAxis( ang.ToMat3() ); +} + +/* +================ +idEntity::GetFloorPos +================ +*/ +bool idEntity::GetFloorPos( float max_dist, idVec3 &floorpos ) const { + trace_t result; + + if ( !GetPhysics()->HasGroundContacts() ) { + GetPhysics()->ClipTranslation( result, GetPhysics()->GetGravityNormal() * max_dist, NULL ); + if ( result.fraction < 1.0f ) { + floorpos = result.endpos; + return true; + } else { + floorpos = GetPhysics()->GetOrigin(); + return false; + } + } else { + floorpos = GetPhysics()->GetOrigin(); + return true; + } +} + +/* +================ +idEntity::GetPhysicsToVisualTransform +================ +*/ +bool idEntity::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { + return false; +} + +/* +================ +idEntity::GetPhysicsToSoundTransform +================ +*/ +bool idEntity::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { + // by default play the sound at the center of the bounding box of the first clip model + if ( GetPhysics()->GetNumClipModels() > 0 ) { + origin = GetPhysics()->GetBounds().GetCenter(); + axis.Identity(); + return true; + } + return false; +} + +/* +================ +idEntity::Collide +================ +*/ + +bool idEntity::Collide( const trace_t &collision, const idVec3 &velocity ) { + return false; +} +/* +================ +idEntity::GetImpactInfo +================ +*/ +void idEntity::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { + GetPhysics()->GetImpactInfo( id, point, info ); +} + +/* +================ +idEntity::ApplyImpulse +================ +*/ +void idEntity::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + + // grayman #2603 - disallow impulse on candles and candle holders when the candle is being relit + + bool allowImpulse = true; + + // In case the entity itself is a light (tdm_light_holder light) + + if (IsType(idLight::Type)) + { + if (static_cast(this)->IsBeingRelit()) + { + allowImpulse = false; // relighting this light; no impulse + } + } + else if (IsType(idMoveable::Type)) + { + // Are there any light entities on this team? + + idList children; + GetTeamChildren(&children); + for (int i = 0 ; i < children.Num() ; i++) + { + // Based on reading other uses of GetTeamChildren(), it's + // prudent to check for recursion back to the original entity. + + idEntity* child = children[i]; + if (this == child) + { + break; + } + if (child->IsType(idLight::Type)) + { + if (static_cast(child)->IsBeingRelit()) + { + allowImpulse = false; // relighting this light; no impulse + break; + } + } + } + } + + if (allowImpulse) + { + GetPhysics()->ApplyImpulse( id, point, impulse ); + } +} + +/* +================ +idEntity::AddForce +================ +*/ +void idEntity::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { + GetPhysics()->AddForce( id, point, force ); +} + +/* +================ +idEntity::ActivatePhysics +================ +*/ +void idEntity::ActivatePhysics( idEntity *ent ) { + GetPhysics()->Activate(); +} + +/* +================ +idEntity::IsAtRest +================ +*/ +bool idEntity::IsAtRest( void ) const { + return GetPhysics()->IsAtRest(); +} + +/* +================ +idEntity::GetRestStartTime +================ +*/ +int idEntity::GetRestStartTime( void ) const { + return GetPhysics()->GetRestStartTime(); +} + +/* +================ +idEntity::AddContactEntity +================ +*/ +void idEntity::AddContactEntity( idEntity *ent ) { + GetPhysics()->AddContactEntity( ent ); +} + +/* +================ +idEntity::RemoveContactEntity +================ +*/ +void idEntity::RemoveContactEntity( idEntity *ent ) { + GetPhysics()->RemoveContactEntity( ent ); +} + + + +/*********************************************************************** + + Damage + +***********************************************************************/ + +/* +============ +idEntity::CanDamage + +Returns true if the inflictor can directly damage the target. Used for +explosions and melee attacks. +============ +*/ +bool idEntity::CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const { + idVec3 dest; + trace_t tr; + idVec3 midpoint; + + // use the midpoint of the bounds instead of the origin, because + // bmodels may have their origin at 0,0,0 + midpoint = ( GetPhysics()->GetAbsBounds()[0] + GetPhysics()->GetAbsBounds()[1] ) * 0.5; + + dest = midpoint; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + // this should probably check in the plane of projection, rather than in world coordinate + dest = midpoint; + dest[0] += 15.0; + dest[1] += 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + dest = midpoint; + dest[0] += 15.0; + dest[1] -= 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + dest = midpoint; + dest[0] -= 15.0; + dest[1] += 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + dest = midpoint; + dest[0] -= 15.0; + dest[1] -= 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + dest = midpoint; + dest[2] += 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + dest = midpoint; + dest[2] -= 15.0; + gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { + damagePoint = tr.endpos; + return true; + } + + return false; +} + +/* +================ +idEntity::DamageFeedback + +callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. +================ +*/ +void idEntity::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { + // implemented in subclasses +} + +/* +============ +Damage + +this entity that is being damaged +inflictor entity that is causing the damage +attacker entity that caused the inflictor to damage targ + example: this=monster, inflictor=rocket, attacker=player + +dir direction of the attack for knockback in global space +point point at which the damage is being inflicted, used for headshots +damage amount of damage being inflicted + +inflictor, attacker, dir, and point can be NULL for environmental effects + +============ +*/ +void idEntity::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, + const int location, trace_t *tr ) +{ + if ( !fl.takedamage ) { + return; + } + + if ( !inflictor ) { + inflictor = gameLocal.world; + } + + if ( !attacker ) { + attacker = gameLocal.world; + } + + const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) { + gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); + } + + int damage = damageDef->GetInt( "damage" ); + + // inform the attacker that they hit someone + attacker->DamageFeedback( this, inflictor, damage ); + if ( damage ) { + // do the damage + health -= damage; + if ( health <= 0 ) { + if ( health < -999 ) { + health = -999; + } + + Killed( inflictor, attacker, damage, dir, location ); + } else { + Pain( inflictor, attacker, damage, dir, location ); + } + } +} + +/* +================ +idEntity::AddDamageEffect +================ +*/ +void idEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { + const char *decal, *key; + idStr surfName; + + const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false ); + if ( def == NULL ) { + return; + } + + g_Global.GetSurfName( collision.c.material, surfName ); + + // start impact sound based on material type + key = va( "snd_%s", surfName.c_str() ); + + // ishtvan: No need to play the sound here anymore, right? +/* + sound = spawnArgs.GetString( key ); + if ( *sound == '\0' ) { + sound = def->dict.GetString( key ); + } + if ( *sound != '\0' ) { + StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); + } +*/ + + if ( g_decals.GetBool() ) { + // place a wound overlay on the model + key = va( "mtr_wound_%s", surfName.c_str() ); + decal = spawnArgs.RandomPrefix( key, gameLocal.random ); + if ( *decal == '\0' ) { + decal = def->dict.RandomPrefix( key, gameLocal.random ); + } + if ( *decal != '\0' ) { + idVec3 dir = velocity; + dir.Normalize(); + ProjectOverlay( collision.c.point, dir, 20.0f, decal ); + } + } +} + +/* +============ +idEntity::Pain + +Called whenever an entity recieves damage. Returns whether the entity responds to the pain. +This is a virtual function that subclasses are expected to implement. +============ +*/ +bool idEntity::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + return false; +} + +/* +============ +idEntity::Killed + +Called whenever an entity's health is reduced to 0 or less. +This is a virtual function that subclasses are expected to implement. +============ +*/ +void idEntity::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { +} + + +/*********************************************************************** + + Script functions + +***********************************************************************/ + +/* +================ +idEntity::ShouldConstructScriptObjectAtSpawn + +Called during idEntity::Spawn to see if it should construct the script object or not. +Overridden by subclasses that need to spawn the script object themselves. +================ +*/ +bool idEntity::ShouldConstructScriptObjectAtSpawn( void ) const { + return true; +} + +/* +================ +idEntity::ConstructScriptObject + +Called during idEntity::Spawn. Calls the constructor on the script object. +Can be overridden by subclasses when a thread doesn't need to be allocated. +================ +*/ +idThread *idEntity::ConstructScriptObject( void ) { + idThread *thread; + const function_t *constructor; + + // init the script object's data + scriptObject.ClearObject(); + + // call script object's constructor (usually "init()") + constructor = scriptObject.GetConstructor(); + if ( constructor ) { + // start a thread that will initialize after Spawn is done being called + thread = new idThread(); + thread->SetThreadName( name.c_str() ); + thread->CallFunction( this, constructor, true ); + thread->DelayedStart( 0 ); + } else { + thread = NULL; + } + + // clear out the object's memory + scriptObject.ClearObject(); + + return thread; +} + +/* +================ +idEntity::DeconstructScriptObject + +Called during idEntity::~idEntity. Calls the destructor on the script object. +Can be overridden by subclasses when a thread doesn't need to be allocated. +Not called during idGameLocal::MapShutdown. +================ +*/ +void idEntity::DeconstructScriptObject( void ) { + idThread *thread; + const function_t *destructor; + + // don't bother calling the script object's destructor on map shutdown + if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) { + return; + } + + // call script object's destructor + destructor = scriptObject.GetDestructor(); + if ( destructor ) { + // start a thread that will run immediately and be destroyed + thread = new idThread(); + thread->SetThreadName( name.c_str() ); + thread->CallFunction( this, destructor, true ); + thread->Execute(); + delete thread; + } +} + +/* +================ +idEntity::HasSignal +================ +*/ +bool idEntity::HasSignal( signalNum_t signalnum ) const { + if ( !signals ) { + return false; + } + assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); + return ( signals->signal[ signalnum ].Num() > 0 ); +} + +/* +================ +idEntity::SetSignal +================ +*/ +void idEntity::SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function ) { + int i; + int num; + signal_t sig; + int threadnum; + + assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); + + if ( !signals ) { + signals = new signalList_t; + } + + assert( thread ); + threadnum = thread->GetThreadNum(); + + num = signals->signal[ signalnum ].Num(); + for( i = 0; i < num; i++ ) { + if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) { + signals->signal[ signalnum ][ i ].function = function; + return; + } + } + + if ( num >= MAX_SIGNAL_THREADS ) { + thread->Error( "Exceeded maximum number of signals per object" ); + } + + sig.threadnum = threadnum; + sig.function = function; + signals->signal[ signalnum ].Append( sig ); +} + +/* +================ +idEntity::ClearSignal +================ +*/ +void idEntity::ClearSignal( idThread *thread, signalNum_t signalnum ) { + assert( thread ); + if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { + gameLocal.Error( "Signal out of range" ); + } + + if ( !signals ) { + return; + } + + signals->signal[ signalnum ].Clear(); +} + +/* +================ +idEntity::ClearSignalThread +================ +*/ +void idEntity::ClearSignalThread( signalNum_t signalnum, idThread *thread ) { + int i; + int num; + int threadnum; + + assert( thread ); + + if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { + gameLocal.Error( "Signal out of range" ); + } + + if ( !signals ) { + return; + } + + threadnum = thread->GetThreadNum(); + + num = signals->signal[ signalnum ].Num(); + for( i = 0; i < num; i++ ) { + if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) { + signals->signal[ signalnum ].RemoveIndex( i ); + return; + } + } +} + +/* +================ +idEntity::Signal +================ +*/ +void idEntity::Signal( signalNum_t signalnum ) { + int i; + int num; + signal_t sigs[ MAX_SIGNAL_THREADS ]; + idThread *thread; + + assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); + + if ( !signals ) { + return; + } + + // we copy the signal list since each thread has the potential + // to end any of the threads in the list. By copying the list + // we don't have to worry about the list changing as we're + // processing it. + num = signals->signal[ signalnum ].Num(); + for( i = 0; i < num; i++ ) { + sigs[ i ] = signals->signal[ signalnum ][ i ]; + } + + // clear out the signal list so that we don't get into an infinite loop + // TDM: Removed this, signal should stay after triggering by default + // signals->signal[ signalnum ].Clear(); + + for( i = 0; i < num; i++ ) { + thread = idThread::GetThread( sigs[ i ].threadnum ); + if ( thread ) + { + thread->CallFunction( this, sigs[ i ].function, true ); + thread->Execute(); + } + // TDM: Create a new thread if the thread that added the signal is not still around + else + { + thread = new idThread(sigs[i].function); + thread->CallFunction( this, sigs[ i ].function, true ); + thread->Execute(); + } + } +} + +/* +================ +idEntity::SignalEvent +================ +*/ +void idEntity::SignalEvent( idThread *thread, signalNum_t signalnum ) { + if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { + gameLocal.Error( "Signal out of range" ); + } + + if ( !signals ) { + return; + } + + Signal( signalnum ); +} + +/*********************************************************************** + + Guis. + +***********************************************************************/ + + +/* +================ +idEntity::TriggerGuis +================ +*/ +void idEntity::TriggerGuis( void ) { + int i; + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + if ( renderEntity.gui[ i ] ) { + renderEntity.gui[ i ]->Trigger( gameLocal.time ); + } + } +} + +/* +================ +idEntity::HandleGuiCommands +================ +*/ +bool idEntity::HandleGuiCommands( idEntity *entityGui, const char *cmds ) { + idEntity *targetEnt; + bool ret = false; + if ( entityGui && cmds && *cmds ) { + idLexer src; + idToken token, token2, token3, token4; + src.LoadMemory( cmds, strlen( cmds ), "guiCommands" ); + while( 1 ) { + + if ( !src.ReadToken( &token ) ) { + return ret; + } + + if ( token == ";" ) { + continue; + } + + if ( token.Icmp( "activate" ) == 0 ) { + bool targets = true; + if ( src.ReadToken( &token2 ) ) { + if ( token2 == ";" ) { + src.UnreadToken( &token2 ); + } else { + targets = false; + } + } + + if ( targets ) { + entityGui->ActivateTargets( this ); + } else { + idEntity *ent = gameLocal.FindEntity( token2 ); + if ( ent ) { + ent->Signal( SIG_TRIGGER ); + ent->PostEventMS( &EV_Activate, 0, this ); + } + } + + entityGui->renderEntity.shaderParms[ SHADERPARM_MODE ] = 1.0f; + continue; + } + + + if ( token.Icmp( "runScript" ) == 0 ) { + if ( src.ReadToken( &token2 ) ) { + while( src.CheckTokenString( "::" ) ) { + idToken token3; + if ( !src.ReadToken( &token3 ) ) { + gameLocal.Error( "Expecting function name following '::' in gui for entity '%s'", entityGui->name.c_str() ); + } + token2 += "::" + token3; + } + const function_t *func = gameLocal.program.FindFunction( token2 ); + if ( !func ) { + gameLocal.Error( "Can't find function '%s' for gui in entity '%s'", token2.c_str(), entityGui->name.c_str() ); + } else { + idThread *thread = new idThread( func ); + thread->DelayedStart( 0 ); + } + } + continue; + } + + if ( token.Icmp("play") == 0 ) { + if ( src.ReadToken( &token2 ) ) { + const idSoundShader *shader = declManager->FindSound(token2); + entityGui->StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL ); + } + continue; + } + + if ( token.Icmp( "setkeyval" ) == 0 ) { + if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) && src.ReadToken( &token4 ) ) { + idEntity *ent = gameLocal.FindEntity( token2 ); + if ( ent ) { + ent->spawnArgs.Set( token3, token4 ); + ent->UpdateChangeableSpawnArgs( NULL ); + ent->UpdateVisuals(); + } + } + continue; + } + + if ( token.Icmp( "setshaderparm" ) == 0 ) { + if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) ) { + entityGui->SetShaderParm( atoi( token2 ), atof( token3 ) ); + entityGui->UpdateVisuals(); + } + continue; + } + + if ( token.Icmp("close") == 0 ) { + ret = true; + continue; + } + + // handy for debugging GUI stuff + if ( !token.Icmp( "print" ) ) { + idStr msg; + while ( src.ReadToken( &token2 ) ) { + if ( token2 == ";" ) { + src.UnreadToken( &token2 ); + break; + } + msg += token2.c_str(); + } + common->Printf( "ent gui 0x%x '%s': %s\n", entityNumber, name.c_str(), msg.c_str() ); + continue; + } + + // if we get to this point we don't know how to handle it + src.UnreadToken(&token); + if ( !HandleSingleGuiCommand( entityGui, &src ) ) { + // not handled there see if entity or any of its targets can handle it + // this will only work for one target atm + if ( entityGui->HandleSingleGuiCommand( entityGui, &src ) ) { + continue; + } + + int c = entityGui->targets.Num(); + int i; + for ( i = 0; i < c; i++) { + targetEnt = entityGui->targets[ i ].GetEntity(); + if ( targetEnt && targetEnt->HandleSingleGuiCommand( entityGui, &src ) ) { + break; + } + } + + if ( i == c ) { + // not handled + common->DPrintf( "idEntity::HandleGuiCommands: '%s' not handled\n", token.c_str() ); + src.ReadToken( &token ); + } + } + + } + } + return ret; +} + +/* +================ +idEntity::HandleSingleGuiCommand +================ +*/ +bool idEntity::HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ) { + return false; +} + +/*********************************************************************** + + Targets + +***********************************************************************/ + +/* +=============== +idEntity::FindTargets + +We have to wait until all entities are spawned +Used to build lists of targets after the entity is spawned. Since not all entities +have been spawned when the entity is created at map load time, we have to wait +=============== +*/ +void idEntity::FindTargets( void ) { + int i; + + // targets can be a list of multiple names + gameLocal.GetTargets( spawnArgs, targets, "target" ); + + // grayman #2603 - add relight positions as targets + gameLocal.GetRelights(spawnArgs,targets,"relight_position"); + + // ensure that we don't target ourselves since that could cause an infinite loop when activating entities + for( i = 0; i < targets.Num(); i++ ) { + if ( targets[ i ].GetEntity() == this ) { + gameLocal.Error( "Entity '%s' is targeting itself", name.c_str() ); + } + } +} + +// grayman #2603 - convert relight_positions to targets + +void idEntity::FindRelights(void) +{ + gameLocal.GetRelights(spawnArgs,targets,"relight_position"); +} + +/* +================ +idEntity::RemoveNullTargets +================ +*/ +void idEntity::RemoveNullTargets( void ) { + int i; + + for( i = targets.Num() - 1; i >= 0; i-- ) { + if ( !targets[ i ].GetEntity() ) { + targets.RemoveIndex( i ); + } + } +} + +/* +============================== +idEntity::ActivateTargets + +"activator" should be set to the entity that initiated the firing. +============================== +*/ +void idEntity::ActivateTargets( idEntity *activator ) const +{ + for (int i = 0; i < targets.Num(); i++ ) + { + idEntity* ent = targets[i].GetEntity(); + + if (ent == NULL) continue; + + // Call the virtual function + ent->Activate(activator); + + for (int j = 0; j < MAX_RENDERENTITY_GUI; j++) + { + if ( ent->renderEntity.gui[j] ) { + ent->renderEntity.gui[j]->Trigger(gameLocal.time); + } + } + } +} + +void idEntity::RemoveTarget(idEntity* target) +{ + for (int i = 0; i < targets.Num(); i++) + { + if (targets[i].GetEntity() == target) + { + targets.RemoveIndex(i); + return; + } + } +} + +void idEntity::AddTarget(idEntity* target) +{ + idEntityPtr ptr; + ptr = target; + targets.AddUnique(ptr); +} + +/*********************************************************************** + + Misc. + +***********************************************************************/ + +/* +================ +idEntity::Teleport +================ +*/ +void idEntity::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { + + if (destination == NULL) + { + GetPhysics()->SetOrigin( origin ); + GetPhysics()->SetAxis( angles.ToMat3() ); + } + else + { + // tels: copy origin and angles from the destination, but + // use potential "teleport_offset" and "teleport_random_offset" spawnargs + idVec3 offset = spawnArgs.GetVector( "teleport_offset", "0 0 0" ); + idVec3 rand_offset = spawnArgs.GetVector( "teleport_random_offset", "0 0 0" ); + + // replace "3 0 0" with a value of "-1.5 .. 1.5, 0, 0" + rand_offset.x = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.x) - idMath::Fabs(rand_offset.x) / 2; + rand_offset.y = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.y) - idMath::Fabs(rand_offset.y) / 2; + rand_offset.z = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.z) - idMath::Fabs(rand_offset.z) / 2; + + GetPhysics()->SetOrigin( destination->GetPhysics()->GetOrigin() + offset + rand_offset ); + GetPhysics()->SetAxis( destination->GetPhysics()->GetAxis() ); + } + + UpdateVisuals(); +} + +/* +============ +idEntity::TouchTriggers + + Activate all trigger entities touched at the current position. +============ +*/ +bool idEntity::TouchTriggers( void ) const { + int i, numClipModels, numEntities; + idClipModel * cm; + idClipModel * clipModels[ MAX_GENTITIES ]; + idEntity * ent; + trace_t trace; + + memset( &trace, 0, sizeof( trace ) ); + trace.endpos = GetPhysics()->GetOrigin(); + trace.endAxis = GetPhysics()->GetAxis(); + + numClipModels = gameLocal.clip.ClipModelsTouchingBounds( GetPhysics()->GetAbsBounds(), CONTENTS_TRIGGER, clipModels, MAX_GENTITIES ); + numEntities = 0; + + for ( i = 0; i < numClipModels; i++ ) { + cm = clipModels[ i ]; + + // don't touch it if we're the owner + if ( cm->GetOwner() == this ) { + continue; + } + + ent = cm->GetEntity(); + + if ( !ent->RespondsTo( EV_Touch ) && !ent->HasSignal( SIG_TOUCH ) ) { + continue; + } + + if ( !GetPhysics()->ClipContents( cm ) ) { + continue; + } + + numEntities++; + + trace.c.contents = cm->GetContents(); + trace.c.entityNum = cm->GetEntity()->entityNumber; + trace.c.id = cm->GetId(); + + ent->Signal( SIG_TOUCH ); + ent->ProcessEvent( &EV_Touch, this, &trace ); + + if ( !gameLocal.entities[ entityNumber ] ) { + gameLocal.Printf( "entity was removed while touching triggers\n" ); + return true; + } + } + + return ( numEntities != 0 ); +} + +/* +================ +idEntity::GetSpline +================ +*/ +idCurve_Spline *idEntity::GetSpline( void ) const { + int i, numPoints, t; + const idKeyValue *kv; + idLexer lex; + idVec3 v; + idCurve_Spline *spline; + const char *curveTag = "curve_"; + + kv = spawnArgs.MatchPrefix( curveTag ); + if ( !kv ) { + return NULL; + } + + idStr str = kv->GetKey().Right( kv->GetKey().Length() - strlen( curveTag ) ); + if ( str.Icmp( "CatmullRomSpline" ) == 0 ) { + spline = new idCurve_CatmullRomSpline(); + } else if ( str.Icmp( "nubs" ) == 0 ) { + spline = new idCurve_NonUniformBSpline(); + } else if ( str.Icmp( "nurbs" ) == 0 ) { + spline = new idCurve_NURBS(); + } else { + spline = new idCurve_BSpline(); + } + + spline->SetBoundaryType( idCurve_Spline::BT_CLAMPED ); + + lex.LoadMemory( kv->GetValue(), kv->GetValue().Length(), curveTag ); + numPoints = lex.ParseInt(); + lex.ExpectTokenString( "(" ); + for ( t = i = 0; i < numPoints; i++, t += 100 ) { + v.x = lex.ParseFloat(); + v.y = lex.ParseFloat(); + v.z = lex.ParseFloat(); + spline->AddValue( t, v ); + } + lex.ExpectTokenString( ")" ); + + return spline; +} + +/* +=============== +idEntity::ShowEditingDialog +=============== +*/ +void idEntity::ShowEditingDialog( void ) { +} + +/*********************************************************************** + + Events + +***********************************************************************/ + +/* +================ +idEntity::Event_GetName +================ +*/ +void idEntity::Event_GetName( void ) { + idThread::ReturnString( name.c_str() ); +} + +/* +================ +idEntity::Event_SetName +================ +*/ +void idEntity::Event_SetName( const char *newname ) { + SetName( newname ); +} + +/* +================ +idEntity::Event_IsType +================ +*/ +void idEntity::Event_IsType( const char *pstr_typeName ) +{ + idTypeInfo* p_namedType = GetClass (pstr_typeName); + if (p_namedType == NULL) + { + idThread::ReturnInt (0); + } + else + { + if (IsType (*p_namedType)) + { + idThread::ReturnInt (1); + } + else + { + idThread::ReturnInt (0); + } + } +} + + +/* +=============== +idEntity::Event_FindTargets +=============== +*/ +void idEntity::Event_FindTargets( void ) { + FindTargets(); +} + +/* +============ +idEntity::Event_ActivateTargets + +Activates any entities targeted by this entity. Mainly used as an +event to delay activating targets. +============ +*/ +void idEntity::Event_ActivateTargets( idEntity *activator ) { + ActivateTargets( activator ); +} + + +void idEntity::Event_AddTarget(idEntity* target) +{ + AddTarget(target); +} + + +void idEntity::Event_RemoveTarget(idEntity* target) +{ + RemoveTarget(target); +} + + +/* +================ +idEntity::Event_NumTargets +================ +*/ +void idEntity::Event_NumTargets( void ) { + idThread::ReturnFloat( targets.Num() ); +} + +/* +================ +idEntity::Event_GetTarget +================ +*/ +void idEntity::Event_GetTarget( float index ) { + int i; + + i = ( int )index; + if ( ( i < 0 ) || i >= targets.Num() ) { + idThread::ReturnEntity( NULL ); + } else { + idThread::ReturnEntity( targets[ i ].GetEntity() ); + } +} + +/* +================ +idEntity::Event_RandomTarget +================ +*/ +void idEntity::Event_RandomTarget( const char *ignore ) { + int num; + idEntity *ent; + int i; + int ignoreNum; + + RemoveNullTargets(); + if ( !targets.Num() ) { + idThread::ReturnEntity( NULL ); + return; + } + + ignoreNum = -1; + if ( ignore && ( ignore[ 0 ] != 0 ) && ( targets.Num() > 1 ) ) { + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent && ( ent->name == ignore ) ) { + ignoreNum = i; + break; + } + } + } + + if ( ignoreNum >= 0 ) { + num = gameLocal.random.RandomInt( targets.Num() - 1 ); + if ( num >= ignoreNum ) { + num++; + } + } else { + num = gameLocal.random.RandomInt( targets.Num() ); + } + + ent = targets[ num ].GetEntity(); + idThread::ReturnEntity( ent ); +} + +/* +================ +idEntity::Event_BindToJoint +================ +*/ +void idEntity::Event_BindToJoint( idEntity *master, const char *jointname, float orientated ) { + BindToJoint( master, jointname, ( orientated != 0.0f ) ); +} + +/* +================ +idEntity::Event_BindToBody +================ +*/ +void idEntity::Event_BindToBody(idEntity *master, int bodyId, bool orientated) { + BindToBody( master, bodyId, orientated ); +} + + +/* +================ +idEntity::Event_RemoveBinds +================ +*/ +void idEntity::Event_RemoveBinds( void ) { + RemoveBinds(); +} + +/* +================ +idEntity::Event_Bind +================ +*/ +void idEntity::Event_Bind( idEntity *master ) { + Bind( master, true ); +} + +/* +================ +idEntity::Event_BindPosition +================ +*/ +void idEntity::Event_BindPosition( idEntity *master ) { + Bind( master, false ); +} + +/* +================ +idEntity::Event_Unbind +================ +*/ +void idEntity::Event_Unbind( void ) { + Unbind(); +} + +/* +================ +idEntity::Event_SpawnBind +================ +*/ +void idEntity::Event_SpawnBind( void ) +{ + idEntity *parent; + const char *bind, *joint, *bindanim; + jointHandle_t bindJoint; + bool bindOrientated; + int id; + const idAnim *anim; + int animNum; + idAnimator *parentAnimator; + + if ( spawnArgs.GetString( "bind", "", &bind ) ) + { + parent = gameLocal.FindEntity( bind ); + + bindOrientated = spawnArgs.GetBool( "bindOrientated", "1" ); + if ( parent ) + { + if (spawnArgs.GetBool("is_attachment")) + { + parent->Attach(this); + } + + // bind to a joint of the skeletal model of the parent + if ( spawnArgs.GetString( "bindToJoint", "", &joint ) && *joint ) + { + parentAnimator = parent->GetAnimator(); + if ( !parentAnimator ) + gameLocal.Error( "Cannot bind to joint '%s' on '%s'. Entity does not support skeletal models.", joint, name.c_str() ); + + bindJoint = parentAnimator->GetJointHandle( joint ); + if ( bindJoint == INVALID_JOINT ) + gameLocal.Error( "Joint '%s' not found for bind on '%s'", joint, name.c_str() ); + + // bind it relative to a specific anim + if ( ( parent->spawnArgs.GetString( "bindanim", "", &bindanim ) + || parent->spawnArgs.GetString( "anim", "", &bindanim ) ) && *bindanim ) + { + animNum = parentAnimator->GetAnim( bindanim ); + if ( !animNum ) { + gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() ); + } + anim = parentAnimator->GetAnim( animNum ); + if ( !anim ) { + gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() ); + } + + // make sure parent's render origin has been set + parent->UpdateModelTransform(); + + //FIXME: need a BindToJoint that accepts a joint position + parentAnimator->CreateFrame( gameLocal.time, true ); + idJointMat *frame = parent->renderEntity.joints; + gameEdit->ANIM_CreateAnimFrame( parentAnimator->ModelHandle(), anim->MD5Anim( 0 ), parent->renderEntity.numJoints, frame, 0, parentAnimator->ModelDef()->GetVisualOffset(), parentAnimator->RemoveOrigin() ); + BindToJoint( parent, joint, bindOrientated ); + parentAnimator->ForceUpdate(); + } + else + BindToJoint( parent, joint, bindOrientated ); + } + // bind to a body of the physics object of the parent + else if ( spawnArgs.GetInt( "bindToBody", "0", id ) ) + BindToBody( parent, id, bindOrientated ); + // no joint specified, bind to the parent + else + Bind( parent, bindOrientated ); + } + } +} + +/* +================ +idEntity::Event_SetOwner +================ +*/ +void idEntity::Event_SetOwner( idEntity *owner ) { + int i; + + for ( i = 0; i < GetPhysics()->GetNumClipModels(); i++ ) { + GetPhysics()->GetClipModel( i )->SetOwner( owner ); + } +} + +/* +================ +idEntity::Event_SetModel +================ +*/ +void idEntity::Event_SetModel( const char *modelname ) { + SetModel( modelname ); +} + +/* +================ +idEntity::Event_SetSkin +================ +*/ +void idEntity::Event_SetSkin( const char *skinname ) { + renderEntity.customSkin = declManager->FindSkin( skinname ); + UpdateVisuals(); +} + +/* +================ +idEntity::Event_GetShaderParm +================ +*/ +void idEntity::Event_GetShaderParm( int parmnum ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Error( "shader parm index (%d) out of range", parmnum ); + } + + idThread::ReturnFloat( renderEntity.shaderParms[ parmnum ] ); +} + +/* +================ +idEntity::Event_SetShaderParm +================ +*/ +void idEntity::Event_SetShaderParm( int parmnum, float value ) { + SetShaderParm( parmnum, value ); +} + +/* +================ +idEntity::Event_SetShaderParms +================ +*/ +void idEntity::Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 ) { + renderEntity.shaderParms[ SHADERPARM_RED ] = parm0; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = parm1; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = parm2; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = parm3; + UpdateVisuals(); +} + + +/* +================ +idEntity::Event_SetColor +================ +*/ +void idEntity::Event_SetColor( float red, float green, float blue ) { + SetColor( red, green, blue ); +} + +/* +================ +idEntity::Event_GetColor +================ +*/ +void idEntity::Event_GetColor( void ) { + idVec3 out; + + GetColor( out ); + idThread::ReturnVector( out ); +} + +/* +================ +idEntity::Event_IsHidden +================ +*/ +void idEntity::Event_IsHidden( void ) { + idThread::ReturnInt( fl.hidden ); +} + +/* +================ +idEntity::Event_Hide +================ +*/ +void idEntity::Event_Hide( void ) { + Hide(); +} + +/* +================ +idEntity::Event_Show +================ +*/ +void idEntity::Event_Show( void ) { + Show(); +} + +/* +================ +idEntity::Event_CacheSoundShader +================ +*/ +void idEntity::Event_CacheSoundShader( const char *soundName ) { + declManager->FindSound( soundName ); +} + +/* +================ +idEntity::Event_StartSoundShader +================ +*/ +void idEntity::Event_StartSoundShader( const char *soundName, int channel ) { + int length; + + StartSoundShader( declManager->FindSound( soundName ), (s_channelType)channel, 0, false, &length ); + idThread::ReturnFloat( MS2SEC( length ) ); +} + +/* +================ +idEntity::Event_StopSound +================ +*/ +void idEntity::Event_StopSound( int channel, int netSync ) { + StopSound( channel, ( netSync != 0 ) ); +} + +/* +================ +idEntity::Event_StartSound +================ +*/ +void idEntity::Event_StartSound( const char *soundName, int channel, int netSync ) { + int time; + + StartSound( soundName, ( s_channelType )channel, 0, ( netSync != 0 ), &time ); + idThread::ReturnFloat( MS2SEC( time ) ); +} + +/* +================ +idEntity::Event_FadeSound +================ +*/ +void idEntity::Event_FadeSound( int channel, float to, float over ) { + if ( refSound.referenceSound ) { + refSound.referenceSound->FadeSound( channel, to, over ); + } +} + +/* +================ +idEntity::Event_SetSoundVolume + +tels: +================ +*/ +void idEntity::Event_SetSoundVolume( float volume ) { + refSound.parms.volume = volume; +} + +/* +================ +idEntity::Event_GetWorldOrigin +================ +*/ +void idEntity::Event_GetWorldOrigin( void ) { + idThread::ReturnVector( GetPhysics()->GetOrigin() ); +} + +/* +================ +idEntity::Event_SetWorldOrigin +================ +*/ +void idEntity::Event_SetWorldOrigin( idVec3 const &org ) { + idVec3 neworg = GetLocalCoordinates( org ); + SetOrigin( neworg ); +} + +/* +================ +idEntity::Event_SetOrigin +================ +*/ +void idEntity::Event_SetOrigin( idVec3 const &org ) { + SetOrigin( org ); +} + +/* +================ +idEntity::Event_GetOrigin +================ +*/ +void idEntity::Event_GetOrigin( void ) { + idThread::ReturnVector( GetLocalCoordinates( GetPhysics()->GetOrigin() ) ); +} + +/* +================ +idEntity::Event_SetAngles +================ +*/ +void idEntity::Event_SetAngles( idAngles const &ang ) { + SetAngles( ang ); +} + +/* +================ +idEntity::Event_GetAngles +================ +*/ +void idEntity::Event_GetAngles( void ) { + idAngles ang = GetPhysics()->GetAxis().ToAngles(); + idThread::ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); +} + +/* +================ +idEntity::Event_SetLinearVelocity +================ +*/ +void idEntity::Event_SetLinearVelocity( const idVec3 &velocity ) { + GetPhysics()->SetLinearVelocity( velocity ); +} + +/* +================ +idEntity::Event_GetLinearVelocity +================ +*/ +void idEntity::Event_GetLinearVelocity( void ) { + idThread::ReturnVector( GetPhysics()->GetLinearVelocity() ); +} + +/* +================ +idEntity::Event_SetAngularVelocity +================ +*/ +void idEntity::Event_SetAngularVelocity( const idVec3 &velocity ) { + GetPhysics()->SetAngularVelocity( velocity ); +} + +/* +================ +idEntity::Event_GetAngularVelocity +================ +*/ +void idEntity::Event_GetAngularVelocity( void ) { + idThread::ReturnVector( GetPhysics()->GetAngularVelocity() ); +} + +/* +================ +idEntity::Event_SetSize +================ +*/ +void idEntity::Event_SetSize( idVec3 const &mins, idVec3 const &maxs ) { + GetPhysics()->SetClipBox( idBounds( mins, maxs ), 1.0f ); +} + +/* +================ +idEntity::Event_GetSize +================ +*/ +void idEntity::Event_GetSize( void ) { + idBounds bounds; + + bounds = GetPhysics()->GetBounds(); + idThread::ReturnVector( bounds[1] - bounds[0] ); +} + +/* +================ +idEntity::Event_GetMins +================ +*/ +void idEntity::Event_GetMins( void ) { + idThread::ReturnVector( GetPhysics()->GetBounds()[0] ); +} + +/* +================ +idEntity::Event_GetMaxs +================ +*/ +void idEntity::Event_GetMaxs( void ) { + idThread::ReturnVector( GetPhysics()->GetBounds()[1] ); +} + +/* +================ +idEntity::Event_Touches +================ +*/ +void idEntity::Event_Touches( idEntity *ent ) { + if ( !ent ) { + idThread::ReturnInt( false ); + return; + } + + const idBounds &myBounds = GetPhysics()->GetAbsBounds(); + const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); + + idThread::ReturnInt( myBounds.IntersectsBounds( entBounds ) ); +} + +/* +================ +idEntity::Event_GetNextKey +================ +*/ +void idEntity::Event_GetNextKey( const char *prefix, const char *lastMatch ) { + const idKeyValue *kv; + const idKeyValue *previous; + + if ( *lastMatch ) { + previous = spawnArgs.FindKey( lastMatch ); + } else { + previous = NULL; + } + + kv = spawnArgs.MatchPrefix( prefix, previous ); + if ( !kv ) { + idThread::ReturnString( "" ); + } else { + idThread::ReturnString( kv->GetKey() ); + } +} + +/* +================ +idEntity::Event_SetKey +================ +*/ +void idEntity::Event_SetKey( const char *key, const char *value ) { + spawnArgs.Set( key, value ); +} + +/* +================ +idEntity::Event_GetKey +================ +*/ +void idEntity::Event_GetKey( const char *key ) { + const char *value; + + spawnArgs.GetString( key, "", &value ); + idThread::ReturnString( value ); +} + +/* +================ +idEntity::Event_GetIntKey +================ +*/ +void idEntity::Event_GetIntKey( const char *key ) { + int value; + + spawnArgs.GetInt( key, "0", value ); + + // scripts only support floats + idThread::ReturnFloat( value ); +} + +/* +================ +idEntity::Event_GetFloatKey +================ +*/ +void idEntity::Event_GetFloatKey( const char *key ) { + float value; + + spawnArgs.GetFloat( key, "0", value ); + idThread::ReturnFloat( value ); +} + +/* +================ +idEntity::Event_GetVectorKey +================ +*/ +void idEntity::Event_GetVectorKey( const char *key ) { + idVec3 value; + + spawnArgs.GetVector( key, "0 0 0", value ); + idThread::ReturnVector( value ); +} + +/* +================ +idEntity::Event_GetEntityKey +================ +*/ +void idEntity::Event_GetEntityKey( const char *key ) { + idEntity *ent; + const char *entname; + + if ( !spawnArgs.GetString( key, NULL, &entname ) ) { + idThread::ReturnEntity( NULL ); + return; + } + + ent = gameLocal.FindEntity( entname ); + if ( !ent ) { + gameLocal.Warning( "Couldn't find entity '%s' specified in '%s' key in entity '%s'", entname, key, name.c_str() ); + } + + idThread::ReturnEntity( ent ); +} + +/* +================ +idEntity::Event_RemoveKey +================ +*/ +void idEntity::Event_RemoveKey( const char *key ) { + spawnArgs.Delete( key ); +} + +/* +================ +idEntity::Event_RestorePosition +================ +*/ +void idEntity::Event_RestorePosition( void ) { + idVec3 org; + idAngles angles; + idMat3 axis; + idEntity * part; + + spawnArgs.GetVector( "origin", "0 0 0", org ); + + // get the rotation matrix in either full form, or single angle form + if ( spawnArgs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) { + angles = axis.ToAngles(); + } else { + angles[ 0 ] = 0; + angles[ 1 ] = spawnArgs.GetFloat( "angle" ); + angles[ 2 ] = 0; + } + + Teleport( org, angles, NULL ); + + for ( part = teamChain; part != NULL; part = part->teamChain ) { + if ( part->bindMaster != this ) { + continue; + } + if ( part->GetPhysics()->IsType( idPhysics_Parametric::Type ) ) { + if ( static_cast(part->GetPhysics())->IsPusher() ) { + gameLocal.Warning( "teleported '%s' which has the pushing mover '%s' bound to it\n", GetName(), part->GetName() ); + } + } else if ( part->GetPhysics()->IsType( idPhysics_AF::Type ) ) { + gameLocal.Warning( "teleported '%s' which has the articulated figure '%s' bound to it\n", GetName(), part->GetName() ); + } + } +} + +/* +================ +idEntity::Event_UpdateCameraTarget +================ +*/ +void idEntity::Event_UpdateCameraTarget( void ) { + const char *target; + const idKeyValue *kv; + idVec3 dir; + + target = spawnArgs.GetString( "cameraTarget" ); + + cameraTarget = gameLocal.FindEntity( target ); + + if ( cameraTarget ) { + kv = cameraTarget->spawnArgs.MatchPrefix( "target", NULL ); + while( kv ) { + idEntity *ent = gameLocal.FindEntity( kv->GetValue() ); + if ( ent && idStr::Icmp( ent->GetEntityDefName(), "target_null" ) == 0) { + dir = ent->GetPhysics()->GetOrigin() - cameraTarget->GetPhysics()->GetOrigin(); + dir.Normalize(); + cameraTarget->SetAxis( dir.ToMat3() ); + SetAxis(dir.ToMat3()); + break; + } + kv = cameraTarget->spawnArgs.MatchPrefix( "target", kv ); + } + } + UpdateVisuals(); +} + +/* +================ +idEntity::Event_DistanceTo +================ +*/ +void idEntity::Event_DistanceTo( idEntity *ent ) { + if ( !ent ) { + // just say it's really far away + idThread::ReturnFloat( MAX_WORLD_SIZE ); + } else { + float dist = ( GetPhysics()->GetOrigin() - ent->GetPhysics()->GetOrigin() ).LengthFast(); + idThread::ReturnFloat( dist ); + } +} + +/* +================ +idEntity::Event_DistanceToPoint +================ +*/ +void idEntity::Event_DistanceToPoint( const idVec3 &point ) { + float dist = ( GetPhysics()->GetOrigin() - point ).LengthFast(); + idThread::ReturnFloat( dist ); +} + +/* +================ +idEntity::Event_StartFx +================ +*/ +void idEntity::Event_StartFx( const char *fx ) { + idEntityFx::StartFx( fx, NULL, NULL, this, true ); +} + +/* +================ +idEntity::Event_WaitFrame +================ +*/ +void idEntity::Event_WaitFrame( void ) { + idThread *thread; + + thread = idThread::CurrentThread(); + if ( thread ) { + thread->WaitFrame(); + } +} + +/* +===================== +idEntity::Event_Wait +===================== +*/ +void idEntity::Event_Wait( float time ) { + idThread *thread = idThread::CurrentThread(); + + if ( !thread ) { + gameLocal.Error( "Event 'wait' called from outside thread" ); + } + + thread->WaitSec( time ); +} + +/* +===================== +idEntity::Event_HasFunction +===================== +*/ +void idEntity::Event_HasFunction( const char *name ) { + const function_t *func; + + func = scriptObject.GetFunction( name ); + if ( func ) { + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/* +===================== +idEntity::Event_CallFunction +===================== +*/ +void idEntity::Event_CallFunction( const char *funcname ) { + const function_t *func; + idThread *thread; + + thread = idThread::CurrentThread(); + if ( !thread ) { + gameLocal.Error( "Event 'callFunction' called from outside thread" ); + } + + func = scriptObject.GetFunction( funcname ); + if ( !func ) { + gameLocal.Error( "Unknown function '%s' in '%s'", funcname, scriptObject.GetTypeName() ); + } + + if ( func->type->NumParameters() != 1 ) { + gameLocal.Error( "Function '%s' has the wrong number of parameters for 'callFunction'", funcname ); + } + if ( !scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { + gameLocal.Error( "Function '%s' is the wrong type for 'callFunction'", funcname ); + } + + // function args will be invalid after this call + thread->CallFunction( this, func, false ); +} + +/* +===================== +idEntity::Event_CallGlobalFunction +===================== +*/ +void idEntity::Event_CallGlobalFunction( const char *funcname, idEntity *ent ) { + const function_t *func; + idThread *thread; + + thread = idThread::CurrentThread(); + if ( !thread ) { + gameLocal.Error( "Event 'callGlobalFunction' called from outside thread" ); + } + + func = gameLocal.program.FindFunction( funcname ); + if ( !func ) { + gameLocal.Error( "Unknown global function '%s'", funcname ); + } + + if ( func->type->NumParameters() != 1 ) { + gameLocal.Error( "Function '%s' has the wrong number of parameters for 'callGlobalFunction'", funcname ); + } + /* + if ( !scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { + gameLocal.Error( "Function '%s' is the wrong type for 'callGlobalFunction'", funcname ); + } */ + + // function args will be invalid after this call + thread->CallFunction( ent, func, false ); +} + +/* +================ +idEntity::Event_SetNeverDormant +================ +*/ +void idEntity::Event_SetNeverDormant( int enable ) { + fl.neverDormant = ( enable != 0 ); + dormantStart = 0; +} + +#ifdef MOD_WATERPHYSICS + +/* + +================ + +idEntity::Event_GetMass MOD_WATERPHYSICS + +================ + +*/ + +void idEntity::Event_GetMass( int id ) { + + idThread::ReturnFloat(physics->GetMass(id)); + +} + + + +/* + +================ + +idEntity::Event_IsInLiquid MOD_WATERPHYSICS + +================ + +*/ + +void idEntity::Event_IsInLiquid( void ) { + + idThread::ReturnInt(physics->GetWater() != NULL); + +} + +#endif // MOD_WATERPHYSICS + + +/* +================ +idEntity::Event_CopyBind +================ +*/ + +void idEntity::Event_CopyBind( idEntity* other ) +{ + if (other == NULL) return; + + idEntity *master = other->GetBindMaster(); + + jointHandle_t joint = other->GetBindJoint(); + + int body = other->GetBindBody(); + if( joint != INVALID_JOINT ) + { + // joint is specified so bind to that joint + BindToJoint( master, joint, true ); + } + else if( body >= 0 ) + { + // body is specified so bind to it + BindToBody( master, body, true ); + } + else + { + // no joint and no body specified, so bind to master + Bind( master, true ); + + // greebo: If the bind master is static, set the solid for team flag + if (master && master->GetPhysics()->IsType(idPhysics_Static::Type)) + { + fl.solidForTeam = true; + } + } +} + +/*********************************************************************** + + Network + +***********************************************************************/ + +/* +================ +idEntity::ClientPredictionThink +================ +*/ +void idEntity::ClientPredictionThink( void ) { + RunPhysics(); + Present(); +} + +/* +================ +idEntity::WriteBindToSnapshot +================ +*/ +void idEntity::WriteBindToSnapshot( idBitMsgDelta &msg ) const { + int bindInfo; + + if ( bindMaster ) { + bindInfo = bindMaster->entityNumber; + bindInfo |= ( fl.bindOrientated & 1 ) << GENTITYNUM_BITS; + if ( bindJoint != INVALID_JOINT ) { + bindInfo |= 1 << ( GENTITYNUM_BITS + 1 ); + bindInfo |= bindJoint << ( 3 + GENTITYNUM_BITS ); + } else if ( bindBody != -1 ) { + bindInfo |= 2 << ( GENTITYNUM_BITS + 1 ); + bindInfo |= bindBody << ( 3 + GENTITYNUM_BITS ); + } + } else { + bindInfo = ENTITYNUM_NONE; + } + msg.WriteBits( bindInfo, GENTITYNUM_BITS + 3 + 9 ); +} + +/* +================ +idEntity::ReadBindFromSnapshot +================ +*/ +void idEntity::ReadBindFromSnapshot( const idBitMsgDelta &msg ) { + int bindInfo, bindEntityNum, bindPos; + bool bindOrientated; + idEntity *master; + + bindInfo = msg.ReadBits( GENTITYNUM_BITS + 3 + 9 ); + bindEntityNum = bindInfo & ( ( 1 << GENTITYNUM_BITS ) - 1 ); + + if ( bindEntityNum != ENTITYNUM_NONE ) { + master = gameLocal.entities[ bindEntityNum ]; + + bindOrientated = ( bindInfo >> GENTITYNUM_BITS ) & 1; + bindPos = ( bindInfo >> ( GENTITYNUM_BITS + 3 ) ); + switch( ( bindInfo >> ( GENTITYNUM_BITS + 1 ) ) & 3 ) { + case 1: { + BindToJoint( master, (jointHandle_t) bindPos, bindOrientated ); + break; + } + case 2: { + BindToBody( master, bindPos, bindOrientated ); + break; + } + default: { + Bind( master, bindOrientated ); + break; + } + } + } else if ( bindMaster ) { + Unbind(); + } +} + +/* +================ +idEntity::WriteColorToSnapshot +================ +*/ +void idEntity::WriteColorToSnapshot( idBitMsgDelta &msg ) const { + idVec4 color; + + color[0] = renderEntity.shaderParms[ SHADERPARM_RED ]; + color[1] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; + color[2] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; + color[3] = renderEntity.shaderParms[ SHADERPARM_ALPHA ]; + msg.WriteLong( PackColor( color ) ); +} + +/* +================ +idEntity::ReadColorFromSnapshot +================ +*/ +void idEntity::ReadColorFromSnapshot( const idBitMsgDelta &msg ) { + idVec4 color; + + UnpackColor( msg.ReadLong(), color ); + renderEntity.shaderParms[ SHADERPARM_RED ] = color[0]; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[1]; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[2]; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[3]; +} + +/* +================ +idEntity::WriteGUIToSnapshot +================ +*/ +void idEntity::WriteGUIToSnapshot( idBitMsgDelta &msg ) const { + // no need to loop over MAX_RENDERENTITY_GUI at this time + if ( renderEntity.gui[ 0 ] ) { + msg.WriteByte( renderEntity.gui[ 0 ]->State().GetInt( "networkState" ) ); + } else { + msg.WriteByte( 0 ); + } +} + +/* +================ +idEntity::ReadGUIFromSnapshot +================ +*/ +void idEntity::ReadGUIFromSnapshot( const idBitMsgDelta &msg ) { + int state; + idUserInterface *gui; + state = msg.ReadByte( ); + gui = renderEntity.gui[ 0 ]; + if ( gui && state != mpGUIState ) { + mpGUIState = state; + gui->SetStateInt( "networkState", state ); + gui->HandleNamedEvent( "networkState" ); + } +} + +/* +================ +idEntity::WriteToSnapshot +================ +*/ +void idEntity::WriteToSnapshot( idBitMsgDelta &msg ) const { +} + +/* +================ +idEntity::ReadFromSnapshot +================ +*/ +void idEntity::ReadFromSnapshot( const idBitMsgDelta &msg ) { +} + +/* +================ +idEntity::ServerSendEvent + + Saved events are also sent to any client that connects late so all clients + always receive the events nomatter what time they join the game. +================ +*/ +void idEntity::ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + if ( !gameLocal.isServer ) { + return; + } + + // prevent dupe events caused by frame re-runs + if ( !gameLocal.isNewFrame ) { + return; + } + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); + outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); + outMsg.WriteByte( eventId ); + outMsg.WriteLong( gameLocal.time ); + if ( msg ) { + outMsg.WriteBits( msg->GetSize(), idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + outMsg.WriteData( msg->GetData(), msg->GetSize() ); + } else { + outMsg.WriteBits( 0, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + } + + if ( excludeClient != -1 ) { + networkSystem->ServerSendReliableMessageExcluding( excludeClient, outMsg ); + } else { + networkSystem->ServerSendReliableMessage( -1, outMsg ); + } + + if ( saveEvent ) { + gameLocal.SaveEntityNetworkEvent( this, eventId, msg ); + } + } + +/* +================ +idEntity::ClientSendEvent +================ +*/ +void idEntity::ClientSendEvent( int eventId, const idBitMsg *msg ) const { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + if ( !gameLocal.isClient ) { + return; + } + + // prevent dupe events caused by frame re-runs + if ( !gameLocal.isNewFrame ) { + return; + } + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); + outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); + outMsg.WriteByte( eventId ); + outMsg.WriteLong( gameLocal.time ); + if ( msg ) { + outMsg.WriteBits( msg->GetSize(), idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + outMsg.WriteData( msg->GetData(), msg->GetSize() ); + } else { + outMsg.WriteBits( 0, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + } + + networkSystem->ClientSendReliableMessage( outMsg ); +} + +/* +================ +idEntity::ServerReceiveEvent +================ +*/ +bool idEntity::ServerReceiveEvent( int event, int time, const idBitMsg &msg ) { + switch( event ) { + case 0: { + } + default: { + return false; + } + } +} + +/* +================ +idEntity::ClientReceiveEvent +================ +*/ +bool idEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + int index; + const idSoundShader *shader; + s_channelType channel; + + switch( event ) { + case EVENT_STARTSOUNDSHADER: { + // the sound stuff would early out + assert( gameLocal.isNewFrame ); + if ( time < gameLocal.realClientTime - 1000 ) { + // too old, skip it ( reliable messages don't need to be parsed in full ) + common->DPrintf( "ent 0x%x: start sound shader too old (%d ms)\n", entityNumber, gameLocal.realClientTime - time ); + return true; + } + index = gameLocal.ClientRemapDecl( DECL_SOUND, msg.ReadLong() ); + if ( index >= 0 && index < declManager->GetNumDecls( DECL_SOUND ) ) { + shader = declManager->SoundByIndex( index, false ); + channel = (s_channelType)msg.ReadByte(); + StartSoundShader( shader, channel, 0, false, NULL ); + } + return true; + } + case EVENT_STOPSOUNDSHADER: { + // the sound stuff would early out + assert( gameLocal.isNewFrame ); + channel = (s_channelType)msg.ReadByte(); + StopSound( channel, false ); + return true; + } + default: { + return false; + } + } +// return false; +} + +/* +=============================================================================== + + idAnimatedEntity + +=============================================================================== +*/ + +const idEventDef EV_GetJointHandle( "getJointHandle", "s", 'd' ); +const idEventDef EV_ClearAllJoints( "clearAllJoints" ); +const idEventDef EV_ClearJoint( "clearJoint", "d" ); +const idEventDef EV_SetJointPos( "setJointPos", "ddv" ); +const idEventDef EV_SetJointAngle( "setJointAngle", "ddv" ); +const idEventDef EV_GetJointPos( "getJointPos", "d", 'v' ); +const idEventDef EV_GetJointAngle( "getJointAngle", "d", 'v' ); + +CLASS_DECLARATION( idEntity, idAnimatedEntity ) + EVENT( EV_GetJointHandle, idAnimatedEntity::Event_GetJointHandle ) + EVENT( EV_ClearAllJoints, idAnimatedEntity::Event_ClearAllJoints ) + EVENT( EV_ClearJoint, idAnimatedEntity::Event_ClearJoint ) + EVENT( EV_SetJointPos, idAnimatedEntity::Event_SetJointPos ) + EVENT( EV_SetJointAngle, idAnimatedEntity::Event_SetJointAngle ) + EVENT( EV_GetJointPos, idAnimatedEntity::Event_GetJointPos ) + EVENT( EV_GetJointAngle, idAnimatedEntity::Event_GetJointAngle ) +END_CLASS + +/* +================ +CAttachInfo::Save +================ +*/ +void CAttachInfo::Save( idSaveGame *savefile ) const +{ + ent.Save( savefile ); + savefile->WriteInt( channel ); + savefile->WriteString( name ); + savefile->WriteInt(savedContents); + savefile->WriteString(posName); // grayman #2603 +} + +/* +================ +CAttachInfo::Restore +================ +*/ +void CAttachInfo::Restore( idRestoreGame *savefile ) +{ + ent.Restore( savefile ); + savefile->ReadInt( channel ); + savefile->ReadString( name ); + savefile->ReadInt(savedContents); + savefile->ReadString(posName); // grayman #2603 +} + +/* +================ +idAnimatedEntity::idAnimatedEntity +================ +*/ +idAnimatedEntity::idAnimatedEntity() : + lastUpdateTime(-1) +{ + animator.SetEntity( this ); + damageEffects = NULL; +} + +/* +================ +idAnimatedEntity::~idAnimatedEntity +================ +*/ +idAnimatedEntity::~idAnimatedEntity() { + damageEffect_t *de; + + for ( de = damageEffects; de; de = damageEffects ) { + damageEffects = de->next; + delete de; + } +} + +/* +=============== +idAnimatedEntity::Spawn +=============== +*/ +void idAnimatedEntity::Spawn( void ) +{ + // Cache animation rates + CacheAnimRates(); + int anims = animator.NumAnims(); + m_animRates.Clear(); + m_animRates.AssureSize(anims); + for (int i=0; iName(); + m_animRates[i] = spawnArgs.GetFloat(spawnargname, "1"); + } else + { + m_animRates[i] = 1.0f; + } + } + + lastUpdateTime = 0; +} + +/* +================ +idAnimatedEntity::Save + +archives object for save game file +================ +*/ +void idAnimatedEntity::Save( idSaveGame *savefile ) const +{ + animator.Save( savefile ); + savefile->WriteInt(lastUpdateTime); + + // Wounds are very temporary, ignored at this time + //damageEffect_t *damageEffects; +} + +/* +================ +idAnimatedEntity::Restore + +unarchives object from save game file +================ +*/ +void idAnimatedEntity::Restore( idRestoreGame *savefile ) +{ + animator.Restore( savefile ); + savefile->ReadInt(lastUpdateTime); + + // check if the entity has an MD5 model + if ( animator.ModelHandle() ) + { + // set the callback to update the joints + renderEntity.callback = idEntity::ModelCallback; + + animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); + animator.GetBounds( gameLocal.time, renderEntity.bounds ); + if ( modelDefHandle != -1 ) { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } + } +} + +/* +================ +idAnimatedEntity::ClientPredictionThink +================ +*/ +void idAnimatedEntity::ClientPredictionThink( void ) { + RunPhysics(); + UpdateAnimation(); + Present(); +} + +/* +================ +idAnimatedEntity::Think +================ +*/ +void idAnimatedEntity::Think( void ) { + RunPhysics(); + UpdateAnimation(); + Present(); + UpdateDamageEffects(); +} + +/* +================ +idAnimatedEntity::UpdateAnimation +================ +*/ +void idAnimatedEntity::UpdateAnimation( void ) { + // don't do animations if they're not enabled + if ( !( thinkFlags & TH_ANIMATE ) ) { + return; + } + + // is the model an MD5? + if ( !animator.ModelHandle() ) { + // no, so nothing to do + return; + } + + // call any frame commands that have happened since the last update + if ( !fl.hidden ) + { + animator.ServiceAnims( lastUpdateTime, gameLocal.time ); + lastUpdateTime = gameLocal.time; + } + + // if the model is animating then we have to update it + if ( !animator.FrameHasChanged( gameLocal.time ) ) { + // still fine the way it was + return; + } + + // get the latest frame bounds + animator.GetBounds( gameLocal.time, renderEntity.bounds ); + if ( renderEntity.bounds.IsCleared() && !fl.hidden ) { + gameLocal.DPrintf( "%d: inside out bounds\n", gameLocal.time ); + } + + // update the renderEntity + UpdateVisuals(); + + // the animation is updated + animator.ClearForceUpdate(); +} + +/* +================ +idAnimatedEntity::GetAnimator +================ +*/ +idAnimator *idAnimatedEntity::GetAnimator( void ) { + return &animator; +} + +/* +================ +idAnimatedEntity::SetModel +================ +*/ +void idAnimatedEntity::SetModel( const char *modelname ) { + FreeModelDef(); + + renderEntity.hModel = animator.SetModel( modelname ); + if ( !renderEntity.hModel ) { + idEntity::SetModel( modelname ); + return; + } + + if ( !renderEntity.customSkin ) { + renderEntity.customSkin = animator.ModelDef()->GetDefaultSkin(); + } + + // set the callback to update the joints + renderEntity.callback = idEntity::ModelCallback; + + animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); + animator.GetBounds( gameLocal.time, renderEntity.bounds ); + + UpdateVisuals(); +} + +/* +===================== +idAnimatedEntity::GetJointWorldTransform +===================== +*/ +bool idAnimatedEntity::GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { + if ( !animator.GetJointTransform( jointHandle, currentTime, offset, axis ) ) { + return false; + } + + ConvertLocalToWorldTransform( offset, axis ); + return true; +} + +/* +============== +idAnimatedEntity::GetJointTransformForAnim +============== +*/ +bool idAnimatedEntity::GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int frameTime, idVec3 &offset, idMat3 &axis ) const { + const idAnim *anim; + int numJoints; + idJointMat *frame; + + anim = animator.GetAnim( animNum ); + if ( !anim ) { + assert( 0 ); + return false; + } + + numJoints = animator.NumJoints(); + if ( ( jointHandle < 0 ) || ( jointHandle >= numJoints ) ) { + assert( 0 ); + return false; + } + + frame = ( idJointMat * )_alloca16( numJoints * sizeof( idJointMat ) ); + gameEdit->ANIM_CreateAnimFrame( animator.ModelHandle(), anim->MD5Anim( 0 ), renderEntity.numJoints, frame, frameTime, animator.ModelDef()->GetVisualOffset(), animator.RemoveOrigin() ); + + offset = frame[ jointHandle ].ToVec3(); + axis = frame[ jointHandle ].ToMat3(); + + return true; +} + +/* +============== +idAnimatedEntity::AddDamageEffect + + Dammage effects track the animating impact position, spitting out particles. +============== +*/ +void idAnimatedEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { + jointHandle_t jointNum; + idVec3 origin, dir, localDir, localOrigin, localNormal; + idMat3 axis; + + if ( !g_bloodEffects.GetBool() || renderEntity.joints == NULL ) { + return; + } + + const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false ); + if ( def == NULL ) { + return; + } + + jointNum = CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ); + if ( jointNum == INVALID_JOINT ) { + return; + } + + dir = velocity; + dir.Normalize(); + + axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis; + origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis; + + localOrigin = ( collision.c.point - origin ) * axis.Transpose(); + localNormal = collision.c.normal * axis.Transpose(); + localDir = dir * axis.Transpose(); + + AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, def, collision.c.material ); + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteShort( (int)jointNum ); + msg.WriteFloat( localOrigin[0] ); + msg.WriteFloat( localOrigin[1] ); + msg.WriteFloat( localOrigin[2] ); + msg.WriteDir( localNormal, 24 ); + msg.WriteDir( localDir, 24 ); + msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_ENTITYDEF, def->Index() ) ); + msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_MATERIAL, collision.c.material->Index() ) ); + ServerSendEvent( EVENT_ADD_DAMAGE_EFFECT, &msg, false, -1 ); + } +} + +/* +============== +idAnimatedEntity::GetDefaultSurfaceType +============== +*/ +int idAnimatedEntity::GetDefaultSurfaceType( void ) const { + return SURFTYPE_METAL; +} + +/* +============== +idAnimatedEntity::AddLocalDamageEffect +============== +*/ +void idAnimatedEntity::AddLocalDamageEffect + ( + jointHandle_t jointNum, const idVec3 &localOrigin, + const idVec3 &localNormal, const idVec3 &localDir, + const idDeclEntityDef *def, const idMaterial *collisionMaterial + ) +{ + const char *splat, *decal, *bleed, *key; + damageEffect_t *de; + idVec3 origin, dir; + idMat3 axis; + idStr surfName; + + axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis; + origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis; + + origin = origin + localOrigin * axis; + dir = localDir * axis; + + if ( !collisionMaterial || collisionMaterial->GetSurfaceType() == SURFTYPE_NONE ) + { + surfName = gameLocal.sufaceTypeNames[ GetDefaultSurfaceType() ]; + } + else + { + g_Global.GetSurfName( collisionMaterial, surfName ); + } + + // start impact sound based on material type + key = va( "snd_%s", surfName.c_str() ); + // ishtvan: Shouldn't need to play the sound here anymore, right? +/* + sound = spawnArgs.GetString( key ); + if ( *sound == '\0' ) { + sound = def->dict.GetString( key ); + } + if ( *sound != '\0' ) { + StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); + } +*/ + + // blood splats are thrown onto nearby surfaces + key = va( "mtr_splat_%s", surfName.c_str() ); + splat = spawnArgs.RandomPrefix( key, gameLocal.random ); + if ( *splat == '\0' ) { + splat = def->dict.RandomPrefix( key, gameLocal.random ); + } + if ( *splat != '\0' ) { + gameLocal.BloodSplat( origin, dir, 64.0f, splat ); + } + + // can't see wounds on the player model in single player mode + if ( !( IsType( idPlayer::Type ) && !gameLocal.isMultiplayer ) ) { + // place a wound overlay on the model + key = va( "mtr_wound_%s", surfName.c_str() ); + decal = spawnArgs.RandomPrefix( key, gameLocal.random ); + if ( *decal == '\0' ) { + decal = def->dict.RandomPrefix( key, gameLocal.random ); + } + if ( *decal != '\0' ) { + ProjectOverlay( origin, dir, 20.0f, decal ); + } + } + + // a blood spurting wound is added + key = va( "smoke_wound_%s", surfName.c_str() ); + bleed = spawnArgs.GetString( key ); + if ( *bleed == '\0' ) { + bleed = def->dict.GetString( key ); + } + if ( *bleed != '\0' ) { + de = new damageEffect_t; + de->next = this->damageEffects; + this->damageEffects = de; + + de->jointNum = jointNum; + de->localOrigin = localOrigin; + de->localNormal = localNormal; + de->type = static_cast( declManager->FindType( DECL_PARTICLE, bleed ) ); + + key = va( "smoke_chance_%s", surfName.c_str() ); + float chance; + chance = def->dict.GetFloat( va("smoke_chance_%s", surfName.c_str()), "1.0" ); + if( gameLocal.random.RandomFloat() > chance ) + de->type = NULL; + de->time = gameLocal.time; + } +} + +/* +============== +idAnimatedEntity::UpdateDamageEffects +============== +*/ +void idAnimatedEntity::UpdateDamageEffects( void ) { + damageEffect_t *de, **prev; + + // free any that have timed out + prev = &this->damageEffects; + while ( *prev ) { + de = *prev; + if ( de->time == 0 ) { // FIXME:SMOKE + *prev = de->next; + delete de; + } else { + prev = &de->next; + } + } + + if ( !g_bloodEffects.GetBool() ) { + return; + } + + // emit a particle for each bleeding wound + for ( de = this->damageEffects; de; de = de->next ) { + idVec3 origin, start; + idMat3 axis; + + animator.GetJointTransform( de->jointNum, gameLocal.time, origin, axis ); + axis *= renderEntity.axis; + origin = renderEntity.origin + origin * renderEntity.axis; + start = origin + de->localOrigin * axis; + if ( !gameLocal.smokeParticles->EmitSmoke( de->type, de->time, gameLocal.random.CRandomFloat(), start, axis ) ) { + de->time = 0; + } + } +} + +/* +================ +idAnimatedEntity::ClientReceiveEvent +================ +*/ +bool idAnimatedEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + int damageDefIndex; + int materialIndex; + jointHandle_t jointNum; + idVec3 localOrigin, localNormal, localDir; + + switch( event ) { + case EVENT_ADD_DAMAGE_EFFECT: { + jointNum = (jointHandle_t) msg.ReadShort(); + localOrigin[0] = msg.ReadFloat(); + localOrigin[1] = msg.ReadFloat(); + localOrigin[2] = msg.ReadFloat(); + localNormal = msg.ReadDir( 24 ); + localDir = msg.ReadDir( 24 ); + damageDefIndex = gameLocal.ClientRemapDecl( DECL_ENTITYDEF, msg.ReadLong() ); + materialIndex = gameLocal.ClientRemapDecl( DECL_MATERIAL, msg.ReadLong() ); + const idDeclEntityDef *damageDef = static_cast( declManager->DeclByIndex( DECL_ENTITYDEF, damageDefIndex ) ); + const idMaterial *collisionMaterial = static_cast( declManager->DeclByIndex( DECL_MATERIAL, materialIndex ) ); + AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, damageDef, collisionMaterial ); + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +================ +idAnimatedEntity::Attach +================ +*/ +void idAnimatedEntity::Attach( idEntity *ent, const char *PosName, const char *AttName ) +{ + idVec3 origin; + idMat3 axis; + jointHandle_t joint; + idStr jointName; + idAngles angleOffset, angleSubOffset(0.0f,0.0f,0.0f); + idVec3 originOffset, originSubOffset(vec3_zero); + idStr nm; + idStr ClassName; + SAttachPosition *pos; + +// New position system: + if( PosName && ((pos = GetAttachPosition(PosName)) != NULL) ) + { + joint = pos->joint; + + originOffset = pos->originOffset; + angleOffset = pos->angleOffset; + + // entity-specific offsets to a given position + // entity-specific offsets to a given position + originSubOffset = ent->spawnArgs.GetVector( va("origin_%s", PosName ) ); + angleSubOffset = ent->spawnArgs.GetAngles( va("angles_%s", PosName ) ); + } +// Old system, will be phased out + else + { + jointName = ent->spawnArgs.GetString( "joint" ); + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) + { + jointName = ent->spawnArgs.GetString("bindToJoint"); + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) + { + gameLocal.Error( "Joint '%s' not found for attaching '%s' on '%s'", jointName.c_str(), ent->GetClassname(), name.c_str() ); + } + } + + // Sparhawk's classname-specific offset system + // Will be phased out in favor of attachment positions + spawnArgs.GetString("classname", "", ClassName); + sprintf(nm, "angles_%s", ClassName.c_str()); + if(ent->spawnArgs.GetAngles(nm.c_str(), "0 0 0", angleOffset) == false) + angleOffset = ent->spawnArgs.GetAngles( "angles" ); + + sprintf(nm, "origin_%s", ClassName.c_str()); + if(ent->spawnArgs.GetVector(nm.c_str(), "0 0 0", originOffset) == false) + { + originOffset = ent->spawnArgs.GetVector( "origin" ); + } + } + + GetAttachingTransform( joint, origin, axis ); + idMat3 rotate = angleOffset.ToMat3(); + idMat3 newAxis = rotate * axis; + + // Use the local joint axis instead of the overall AI axis + if (!ent->spawnArgs.GetBool("is_attachment")) + { + // angua: don't set origin and axis for attachments added in the map + // rather than spawned dynamically, this would lead to the entity + // floating around through half of the map + ent->SetOrigin( origin + originOffset * axis + originSubOffset * newAxis ); + ent->SetAxis( angleSubOffset.ToMat3() * newAxis ); + } + + ent->BindToJoint( this, joint, true ); + ent->cinematic = cinematic; + + CAttachInfo &attach = m_Attachments.Alloc(); + attach.channel = animator.GetChannelForJoint( joint ); + attach.ent = ent; + attach.name = AttName; + attach.posName = PosName; // grayman #2603 + + // Update name->m_Attachment index mapping + int index = m_Attachments.Num() - 1; + if( AttName != NULL ) + m_AttNameMap.insert(AttNameMap::value_type(AttName, index)); +} + +/* +================ +idAnimatedEntity::GetAttachingTransform +================ +*/ +void idAnimatedEntity::GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) +{ + GetJointWorldTransform( jointHandle, gameLocal.time, offset, axis ); +} + +/* +======================== +idAnimatedEntity::ReAttachToCoords +======================== +*/ +void idAnimatedEntity::ReAttachToCoords + ( const char *AttName, idStr jointName, + const idVec3 offset, const idAngles angles ) +{ + idEntity *ent( NULL ); + idVec3 origin; + idMat3 axis, rotate, newAxis; + jointHandle_t joint; + CAttachInfo *attachment( NULL ); + + attachment = GetAttachInfo( AttName ); + if( attachment ) + ent = attachment->ent.GetEntity(); + + if( !attachment || !attachment->ent.IsValid() || !ent ) + { + // TODO: log bad attachment entity error + goto Quit; + } + + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) + { + // TODO: log error + gameLocal.Warning( "Joint '%s' not found for attaching '%s' on '%s'", jointName.c_str(), ent->GetClassname(), name.c_str() ); + goto Quit; + } + + attachment->channel = animator.GetChannelForJoint( joint ); + GetJointWorldTransform( joint, gameLocal.time, origin, axis ); + + rotate = angles.ToMat3(); + newAxis = rotate * axis; + + ent->Unbind(); + + // greebo: Note that Unbind() will invalidate the entity pointer in the attachment list + // Hence, re-assign the attachment entity pointer (the index itself is ok) + attachment->ent = ent; + + ent->SetAxis( newAxis ); + // Use the local joint axis instead of the overall AI axis + ent->SetOrigin( origin + offset * axis ); + + ent->BindToJoint( this, joint, true ); + ent->cinematic = cinematic; + + // set the spawnargs for later retrieval as well + ent->spawnArgs.Set( "joint", jointName.c_str() ); + ent->spawnArgs.SetVector( "origin", offset ); + ent->spawnArgs.SetAngles( "angles", angles ); + + attachment->posName = jointName; // grayman #2603 + +Quit: + return; +} + +/* +=============== +idAnimatedEntity::CacheAnimRates +=============== +*/ +void idAnimatedEntity::CacheAnimRates( void ) +{ + // Cache animation rates + int anims = animator.NumAnims(); + m_animRates.Clear(); + m_animRates.AssureSize(anims); + for (int i=0; iName(); + m_animRates[i] = spawnArgs.GetFloat(spawnargname, "1"); + } else + { + m_animRates[i] = 1.0f; + } + } +} + +/* +================ +idAnimatedEntity::GetJointWorldPos + +Returns the position of the joint (by joint name) in worldspace +================ +*/ +idVec3 idAnimatedEntity::GetJointWorldPos( const char *jointname ) { + idVec3 offset; + idMat3 axis; + + jointHandle_t jointnum = animator.GetJointHandle( jointname ); + if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + return offset; +} + +/* +================ +idAnimatedEntity::GetEntityFromClassClosestToJoint + +tels: Returns the entity that is nearest to the given joint, selected from all entities +that have a spawnarg "AIUse" matching AIUseType. max_dist_sqr = max_dist * max_dist +================ +*/ +idEntity* idAnimatedEntity::GetEntityFromClassClosestToJoint( const idVec3 joint_origin, const char* AIUseType, const float max_dist_sqr ) +{ + idEntity* closest = NULL; + float closest_distance = idMath::INFINITY; + + idStr aiuse = AIUseType; + aiuse = aiuse.Left(6); + + // if the selector is not "AIUSE_...", skip this step + if (aiuse != "AIUSE_") { + return NULL; + } + + // for all entities + for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + if ( ent == NULL ) { continue; } + + // does it have the proper AIUse spawnarg? + if (idStr::Cmp(ent->spawnArgs.GetString("AIUse"), AIUseType) != 0) + { + continue; + } + + //gameLocal.Warning ( " Looking at entity for AIUse spawnarg %s", tempkv->GetValue().c_str() ); + + // has the proper AIUse type, so compute distance + //gameLocal.Printf("Has %s\n", AIUseType); + + const idVec3& deb = ent->GetPhysics()->GetOrigin(); + idVec3 diff = joint_origin - deb; + + // gameLocal.Printf("Distance: %f %f %f - %f %f %f = %f %f %f\n", joint_origin.x, joint_origin.y, joint_origin.z, deb.x, deb.y, deb.z, diff.x, diff.y, diff.z); + + float distance = diff.LengthSqr(); + + //gameLocal.Printf(" Distance %f < closest %f ? < max_dist_sqr %f ?.\n", distance, closest_distance, max_dist_sqr); + + if (distance < closest_distance && distance < max_dist_sqr) + { + // use this one + //gameLocal.Printf(" Distance %f < closest %f and < max_dist_sqr %f, so will use this entity.\n", distance, closest_distance, max_dist_sqr); + closest_distance = distance; + closest = ent; + } + + // try ent + } + + return closest; +} + +/* +================ +idAnimatedEntity::GetEntityClosestToJoint + +tels: Returns the entity that is nearest to the given joint. The entitySelector is either +an entity name (like "atdm_moveable_food_apple_2" or an entity AIUSE type like "AIUSE_FOOD". + +First the code looks at the idAnimatedEntity itself for spawnargs matching the given prefix, +each entity mentioned in this spawnarg is used as the entitySelector first. +If after this round no entity could be found, we fall back to entitySelector and try again. +================ +*/ +idEntity* idAnimatedEntity::GetEntityClosestToJoint( const char* posName, const char* entitySelector, const char* prefix, const float max_dist ) { + idEntity* closest = NULL; + float closest_distance = 1000000.0f; + idVec3 joint_origin; + idMat3 joint_axis; + const float max_dist_sqr = max_dist * max_dist; + SAttachPosition *pos; + + jointHandle_t jointnum = INVALID_JOINT; + +// New position system: + if( (pos = GetAttachPosition(posName)) != NULL) { + jointnum = pos->joint; + } + if (jointnum < 0) { + gameLocal.Warning( "GetEntityClosestToJoint: Cannot find joint from attach pos %s", posName ); + return NULL; + } + if ( !GetJointWorldTransform( jointnum, gameLocal.time, joint_origin, joint_axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + // first see if the entity (the animation is running on) defines an entity + // via spawnarg: "pickup_" + "name_of_the_animation" (we get this as prefix) + + if (prefix && *prefix != 0x00) + { + const idKeyValue *kv = spawnArgs.MatchPrefix( prefix, NULL ); + while( kv ) + { + idEntity *target = gameLocal.FindEntity( kv->GetValue() ); + if (!target) { + gameLocal.Warning ( " Can't find entity by name %s, so looking for AIUSE instead.", kv->GetValue().c_str() ); + // haven't found an entity, maybe it is something like "AIUSE_FOOD"? + target = GetEntityFromClassClosestToJoint( joint_origin, kv->GetValue().c_str(), max_dist_sqr ); + } + // if we found an entity and it is not ourself: + if (target != NULL && target != this) + { + // check that it is closer than the closest match so far + idVec3 diff = joint_origin - target->GetPhysics()->GetOrigin(); + float distance = diff.LengthSqr(); + if (distance < closest_distance && distance < max_dist_sqr) { + // closer and close enough + gameLocal.Printf ( " distance %f < closest_distance %f and < max_dist_sqr %f ", distance, closest_distance, max_dist_sqr ); + closest_distance = distance; + closest = target; + } + } + // next spawnarg + kv = spawnArgs.MatchPrefix( prefix, kv ); + } + } + + if (closest == NULL) { + // couldn't find any usable entity from the the spawnargs + // so try to use the entity named in the animation + if (prefix && *prefix != 0x00) + { + gameLocal.Warning ( " Didn't find an entity from the %s spawnargs, trying %s directly.", prefix, entitySelector ); + } + closest = gameLocal.FindEntity( entitySelector ); + if (closest) { + idVec3 diff = joint_origin - closest->GetPhysics()->GetOrigin(); + float distance = diff.LengthSqr(); + if (distance > max_dist_sqr) { + // cannot use this one, too far + gameLocal.Warning ( " Direct entity %s too far away. (%f > %f).", entitySelector, distance, max_dist_sqr ); + closest = NULL; + } + } + // could not be found either or was too far away? + if (closest == NULL) { + // maybe it is a generic AIUSE class, try to find a suitable entity + gameLocal.Warning ( " Can't find entity by name %s, so looking for AIUSE class.", entitySelector ); + closest = GetEntityFromClassClosestToJoint( joint_origin, entitySelector, max_dist_sqr ); + } + } + +// gameLocal.Printf ( " End of selecting closest entity."); + + // now return the found entity or NULL + return closest; +} + +/* +================ +idAnimatedEntity::Event_GetJointHandle + +looks up the number of the specified joint. returns INVALID_JOINT if the joint is not found. +================ +*/ +void idAnimatedEntity::Event_GetJointHandle( const char *jointname ) { + + jointHandle_t jointnum = animator.GetJointHandle( jointname ); + idThread::ReturnInt( jointnum ); +} + +/* +================ +idAnimatedEntity::Event_ClearAllJoints + +removes any custom transforms on all joints +================ +*/ +void idAnimatedEntity::Event_ClearAllJoints( void ) { + animator.ClearAllJoints(); +} + +/* +================ +idAnimatedEntity::Event_ClearJoint + +removes any custom transforms on the specified joint +================ +*/ +void idAnimatedEntity::Event_ClearJoint( jointHandle_t jointnum ) { + animator.ClearJoint( jointnum ); +} + +/* +================ +idAnimatedEntity::Event_SetJointPos + +modifies the position of the joint based on the transform type +================ +*/ +void idAnimatedEntity::Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ) { + animator.SetJointPos( jointnum, transform_type, pos ); +} + +/* +================ +idAnimatedEntity::Event_SetJointAngle + +modifies the orientation of the joint based on the transform type +================ +*/ +void idAnimatedEntity::Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ) { + idMat3 mat; + + mat = angles.ToMat3(); + animator.SetJointAxis( jointnum, transform_type, mat ); +} + +/* +================ +idAnimatedEntity::Event_GetJointPos + +returns the position of the joint in worldspace +================ +*/ +void idAnimatedEntity::Event_GetJointPos( jointHandle_t jointnum ) { + idVec3 offset; + idMat3 axis; + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + idThread::ReturnVector( offset ); +} + +/* +================ +idAnimatedEntity::Event_GetJointAngle + +returns the orientation of the joint in worldspace +================ +*/ +void idAnimatedEntity::Event_GetJointAngle( jointHandle_t jointnum ) { + idVec3 offset; + idMat3 axis; + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + idAngles ang = axis.ToAngles(); + idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); + idThread::ReturnVector( vec ); +} + +/* +=============================================================================== + + End of idAnimatedEntity + +=============================================================================== +*/ + +void idEntity::Flinderize( idEntity *activator ) +{ + // Create a new struct + FlinderSpawn fs; + // count of entities that were actually spawned + int spawned = 0; + + // tels: go through all the def_flinder spawnargs and call SpawnFlinder() for each + const idKeyValue *kv = spawnArgs.MatchPrefix( "def_flinder", NULL ); + while( kv ) + { + idStr temp = kv->GetValue(); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Loading def_flinder %s:\r", temp.c_str() ); + if( !temp.IsEmpty() ) + { + // fill in the name and some defaults + fs.m_Entity = temp; + fs.m_Offset.Zero(); + fs.m_Count = 0; + fs.m_Probability = 1.0; + + // check if we have spawnargs like count, offset or probability: + idStr index; + idStr spawnarg = kv->GetKey(); + // strlen("def_flinder") == 11 + if (spawnarg.Length() > 11) + { + index = spawnarg.Right( spawnarg.Length() - 11 ); + } + // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Index is %s:\r", index.c_str() ); + spawnArgs.GetVector("flinder_offset" + index, "", fs.m_Offset); + spawnArgs.GetInt ("flinder_count" + index, "1", fs.m_Count); + spawnArgs.GetFloat ("flinder_probability" + index, "1.0", fs.m_Probability); + + // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Offset is %f,%f,%f:\r", fs.m_Offset.x, fs.m_Offset.y, fs.m_Offset.z ); + // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Count is %i:\r", fs.m_Count ); + // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Probability is %f:\r", fs.m_Probability ); + // evaluate what we found and spawn the individual pieces + spawned += SpawnFlinder( fs, activator ); + + } + kv = spawnArgs.MatchPrefix( "def_flinder", kv ); + } // while MatchPrefix ("def_flinder") + + // if we spawned flinders, but have no broken model, remove this entity + if ( spawned > 0 && !brokenModel.Length() ) + { + Hide(); + // remove us in 0.01 seconds + PostEventMS( &EV_Remove, 10 ); + // and make inactive in the meantime + BecomeInactive(TH_PHYSICS|TH_THINK); + } +} + +void idEntity::LoadTDMSettings(void) +{ + idStr str; + + // If an item has the frobable flag set to true we will use the + // the default value. If the frobdistance is set in the item + // it will override the defaultsetting. If none of that is set + // the frobdistance will be set to 0 meaning no frobbing on that item. + // If the frobsetting is alread initialized we can skip this. + if(m_FrobDistance == 0) + { + spawnArgs.GetBool("frobable", "0", m_bFrobable); + spawnArgs.GetBool("frob_simple", "0", m_bFrobSimple); + spawnArgs.GetInt("frob_distance", "0", m_FrobDistance); + spawnArgs.GetFloat("frob_bias", "1.0", m_FrobBias); + + if( m_FrobDistance <= 0 ) + m_FrobDistance = cv_frob_distance_default.GetInteger(); + + if( m_bFrobable && m_FrobBox ) + m_FrobBox->SetContents(CONTENTS_FROBABLE); + } + + // update the max frobdistance if necessary + if( m_FrobDistance > g_Global.m_MaxFrobDistance ) + g_Global.m_MaxFrobDistance = m_FrobDistance; + + // Override the frob action script to apply custom events to + // specific entities. + if(spawnArgs.GetString("frob_action_script", "", str)) + m_FrobActionScript = str; + + // Check if this entity is associated to a master frob entity. + str = spawnArgs.GetString("frob_master"); + + // Disallow "self" to be added as same name + if (!str.IsEmpty() && str != name) + { + m_MasterFrob = str; + } + + const idKeyValue *kv = spawnArgs.MatchPrefix( "frob_peer", NULL ); + // Fill the list of frob peers + while( kv ) + { + idStr temp = kv->GetValue(); + if( !temp.IsEmpty() ) + m_FrobPeers.AddUnique(temp); + kv = spawnArgs.MatchPrefix( "frob_peer", kv ); + } + + // Check if this entity can be used by others. + for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by", kv)) + { + // argh, backwards compatibility, must keep old used_by format for used_by_name + // explicitly ignore stuff with other prefixes + idStr kn = kv->GetKey(); + if( !kn.IcmpPrefix("used_by_inv_name") || !kn.IcmpPrefix("used_by_category") || !kn.IcmpPrefix("used_by_classname") ) + continue; + + // Add each entity name to the list + m_UsedByName.AddUnique(kv->GetValue()); + } + for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_inv_name"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_inv_name", kv)) + { + m_UsedByInvName.AddUnique(kv->GetValue()); + } + for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_category"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_category", kv)) + { + m_UsedByCategory.AddUnique(kv->GetValue()); + } + for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_classname"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_classname", kv)) + { + m_UsedByClassname.AddUnique(kv->GetValue()); + } + + m_AbsenceNoticeability = spawnArgs.GetFloat("absence_noticeability", "0"); + + team = spawnArgs.GetInt("team", "-1"); + + m_bAttachedAlertControlsSolidity = spawnArgs.GetBool("on_attach_alert_become_solid"); + + m_bIsObjective = spawnArgs.GetBool( "objective_ent", "0" ); + + m_bIsClimbableRope = spawnArgs.GetBool( "is_climbable_rope", "0" ); + + m_bIsMantleable = spawnArgs.GetBool( "is_mantleable", "1" ); + + DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("[%s] this: %08lX FrobDistance: %u\r", name.c_str(), this, m_FrobDistance); +} + +void idEntity::UpdateFrobState() +{ + // hidden objects are skipped + if (IsHidden()) + { + return; + } + + // greebo: Allow the grabbed entity to stay highlighted + if (cv_dragged_item_highlight.GetBool() && gameLocal.m_Grabber->GetSelected() == this) + { + SetFrobHighlightState(true); + return; + } + + if( !m_bFrobbed ) + { + // The m_bFrobbed variable is FALSE, hence the player is not looking at this entity + // or any of its peers. Check if we need to change our state. + if (m_bFrobHighlightState) + { + // stop highlight + SetFrobHighlightState(false); + } + + // Done, we're not frobbed, frobhighlight state is cleared + return; + } + + // The player is looking at this entity, clear m_bFrobbed for the next frame + m_bFrobbed = false; + + // Change the highlight state to TRUE + SetFrobHighlightState(true); +} + +void idEntity::SetFrobHighlightState(bool newState) +{ + if (m_bFrobHighlightState == newState) return; // Avoid unnecessary work + + // The incoming state is differing from our current one, save the timestamp + m_FrobChangeTime = gameLocal.time; + + // Update the boolean, the UpdateFrobDisplay() routine will pick it up + m_bFrobHighlightState = newState; + + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("Entity [%s] is highlighted\r", name.c_str()); +} + +void idEntity::UpdateFrobDisplay() +{ + // FIX: If we have just been set not frobable, go instantly to un-frobbed hilight state + if (!m_bFrobable) + { + m_FrobChangeTime = gameLocal.time; + SetShaderParm(FROB_SHADERPARM, 0.0f); + return; + } + + float param = renderEntity.shaderParms[ FROB_SHADERPARM ]; + + if ( (param == 0 && !m_bFrobHighlightState) || (param >= 1.0f && m_bFrobHighlightState) ) + { + // Nothing to do + return; + } + + float timePassed = static_cast(gameLocal.time - m_FrobChangeTime); + + if( m_bFrobHighlightState ) + { + param += timePassed / cv_frob_fadetime.GetFloat(); + } + else + { + param -= timePassed / cv_frob_fadetime.GetFloat(); + } + + m_FrobChangeTime = gameLocal.time; + + // clamp between 0 and 1 + param = idMath::ClampFloat(0.0, 1.0f, param); + + SetShaderParm(FROB_SHADERPARM, param); +} + +void idEntity::FrobAction(bool frobMaster, bool isFrobPeerAction) +{ + if (m_FrobActionLock) return; // prevent double-entering this function + + if (IsHidden()) return; // don't do frobactions on hidden entities + + m_FrobActionLock = true; + + // greebo: If we have a frob master, just redirect the call and skip everything else + idEntity* master = GetFrobMaster(); + + if (master != NULL) + { + master->FrobAction(frobMaster, isFrobPeerAction); + + m_FrobActionLock = false; + return; + } + + // Propagate frobactions to all peers to get them triggered as well. + if (!isFrobPeerAction) + { + for (int i = 0; i < m_FrobPeers.Num(); i++) + { + idEntity* ent = gameLocal.FindEntity(m_FrobPeers[i]); + + if (ent != NULL && ent != this) + { + // Propagate the frob action, but inhibit calls to frob_masters + ent->FrobAction(false, true); + } + } + } + + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("This: [%s] Master: %08lX (%u)\r", name.c_str(), m_MasterFrob.c_str(), frobMaster); + + // Call the frob action script, if available + if (m_FrobActionScript.Length() > 0) + { + idThread* thread = CallScriptFunctionArgs(m_FrobActionScript, true, 0, "e", this); + + if (thread != NULL) + { + // greebo: Run the thread at once, the script result might be needed below. + thread->Execute(); + } + } + else + { + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("(%08lX->[%s]) FrobAction has been triggered with empty FrobActionScript!\r", this, name.c_str()); + } + + // Play the (optional) acquire sound (greebo: What's this? Isn't this the wrong place here?) + StartSound( "snd_acquire", SND_CHANNEL_ANY, 0, false, NULL ); + + m_FrobActionLock = false; +} + +void idEntity::AttackAction(idPlayer* player) +{ + idEntity* master = GetFrobMaster(); + + if (master != NULL) + { + master->AttackAction(player); + } +} + +bool idEntity::CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse) +{ + if (item == NULL) return false; + + // Redirect the call to the master if we have one + idEntity* master = GetFrobMaster(); + if( master != NULL ) + return master->CanBeUsedBy(item, isFrobUse); + + // No frob master set + // Check entity name (if exists), inv_name, inv_category, and classname + bool bMatchName( false ), bMatchInvName( false ); + bool bMatchCategory( false ), bMatchClassname( false ); + + idEntity* ent = item->GetItemEntity(); + if( ent != NULL ) + { + bMatchName = ( m_UsedByName.FindIndex(ent->name) != -1 ); + bMatchClassname = ( m_UsedByClassname.FindIndex(ent->GetEntityDefName()) != -1 ); + } + if( bMatchName || bMatchClassname ) + return true; + + bMatchInvName = ( m_UsedByInvName.FindIndex(item->GetName()) != -1 ); + bMatchCategory = ( m_UsedByCategory.FindIndex(item->Category()->GetName()) != -1 ); + + return (bMatchInvName || bMatchCategory); +} + +bool idEntity::CanBeUsedBy(idEntity* entity, const bool isFrobUse) +{ + if (entity == NULL) return false; + + // Redirect the call to the master if we have one + idEntity* master = GetFrobMaster(); + + if (master != NULL) + return master->CanBeUsedBy(entity, isFrobUse); + + // No frob master set + // Check entity name, inv_name, inv_category, and classname + bool bMatchName( false ), bMatchInvName( false ); + bool bMatchCategory( false ), bMatchClassname( false ); + + bMatchName = ( m_UsedByName.FindIndex(entity->name) != -1 ); + bMatchClassname = ( m_UsedByClassname.FindIndex(entity->GetEntityDefName()) != -1 ); + + if( bMatchName || bMatchClassname ) + return true; + + // Tels: TODO: Try here also English names instead of "#str_12345" +// gameLocal.Printf("canUsedBy name %s category %s\n", +// entity->spawnArgs.GetString("inv_name"), +// entity->spawnArgs.GetString("inv_category") ); + + // This may be called when the entity is not in the inventory, so have to read from spawnargs + bMatchInvName = ( m_UsedByInvName.FindIndex(entity->spawnArgs.GetString("inv_name")) != -1 ); + bMatchCategory = ( m_UsedByCategory.FindIndex(entity->spawnArgs.GetString("inv_category")) != -1 ); + + return (bMatchInvName || bMatchCategory); +} + +bool idEntity::UseBy(EImpulseState impulseState, const CInventoryItemPtr& item) +{ + // Redirect the call to the master if we have one + idEntity* master = GetFrobMaster(); + + if (master != NULL) + return master->UseBy(impulseState, item); + + // no master, continue... + // Ishtvan: Call used_by script. First check for scripts with the specific name/inv_name/classname/category/ + // only call the most-specific script + idStrList suffixes; + idEntity *ent = item->GetItemEntity(); + if( ent != NULL ) + { + suffixes.Append( ent->name ); + suffixes.Append( ent->GetEntityDefName() ); + } + // inv_name comes before classname + suffixes.Insert( item->GetName(), 1 ); + suffixes.Append( item->Category()->GetName() ); + + idThread* thread = NULL; + bool bFoundKey = false; + for( int i=0; i < suffixes.Num(); i++ ) + { + idStr scriptName = "used_action_script_" + suffixes[i]; + const idKeyValue *kv = spawnArgs.FindKey( scriptName.c_str() ); + if( kv != NULL && kv->GetValue().Length() > 0 ) + { + idThread* thread = CallScriptFunctionArgs(kv->GetValue().c_str(), true, 0, "e", this); + bFoundKey = true; + break; + } + } + + // if we didn't find a specific suffix, use "used_action_script" by itself + if( !bFoundKey ) + { + const idKeyValue *kv = spawnArgs.FindKey( "used_action_script" ); + if( kv != NULL && kv->GetValue().Length() > 0 ) + { + idThread* thread = CallScriptFunctionArgs(kv->GetValue().c_str(), true, 0, "e", this); + } + } + + if (thread != NULL) + { + // greebo: Run the thread at once, the script result might be needed below. + thread->Execute(); + return true; + } + + return false; +} + +void idEntity::SetFrobbed( bool val ) +{ + if (m_bFrobbed == val) return; // avoid loopbacks and unnecessary work + + m_bFrobbed = val; + + // resolve the peer names into entities + for (int i = 0; i < m_FrobPeers.Num(); i++) + { + if (m_FrobPeers[i].Length() == 0) continue; + + idEntity* ent = gameLocal.FindEntity(m_FrobPeers[i]); + + // don't call it on self, would get stuck in a loop + if (ent != NULL && ent != this) + { + ent->SetFrobbed(m_bFrobbed); + } + } +} + +bool idEntity::IsFrobbed( void ) +{ + return m_bFrobbed; +} + +void idEntity::SetFrobable( bool bVal ) +{ + // greebo: This is to avoid infinite loops + if (m_bFrobable == bVal) return; + + m_bFrobable = bVal; + + // If this entity is currently being hilighted, make sure to un-frob it + if( !bVal ) + { + SetFrobbed(false); + SetFrobHighlightState(false); + if( m_FrobBox ) + m_FrobBox->SetContents(0); + } + else + { + if( m_FrobBox ) + m_FrobBox->SetContents(CONTENTS_FROBABLE); + } + + UpdateFrobState(); + UpdateFrobDisplay(); + + // Make sure Present gets called when we make something frobable + BecomeActive( TH_UPDATEVISUALS ); + + // greebo: Also update all frob peers + for (int i = 0; i < m_FrobPeers.Num(); i++) + { + idEntity* peer = gameLocal.FindEntity(m_FrobPeers[i]); + if (peer == NULL) continue; + + peer->SetFrobable(bVal); + } +} + +void idEntity::Event_StimAdd(int stimType, float radius) +{ + AddStim(static_cast(stimType), radius); +} + +void idEntity::Event_StimRemove(int stimType) +{ + RemoveStim(static_cast(stimType)); +} + +void idEntity::Event_StimEnable(int stimType, int enabled) +{ + SetStimEnabled(static_cast(stimType), enabled != 0); +} + +void idEntity::Event_StimClearIgnoreList(int stimType) +{ + ClearStimIgnoreList(static_cast(stimType)); +} + +void idEntity::Event_ResponseEnable(int stimType, int enabled) +{ + SetResponseEnabled(static_cast(stimType), enabled != 0); +} + +void idEntity::Event_ResponseAdd(int stimType) +{ + AddResponse(static_cast(stimType)); +} + +void idEntity::Event_ResponseTrigger(idEntity* source, int stimType) +{ + TriggerResponse(source, static_cast(stimType)); +} + +void idEntity::Event_ResponseRemove(int stimType) +{ + RemoveResponse(static_cast(stimType)); +} + +void idEntity::Event_ResponseIgnore(int stimType, idEntity *e) +{ + IgnoreResponse(static_cast(stimType), e); +} + +void idEntity::Event_ResponseAllow(int stimType, idEntity *e) +{ + AllowResponse(static_cast(stimType), e); +} + +void idEntity::Event_ResponseSetAction(int stimType, const char* action) +{ + CResponsePtr resp = m_StimResponseColl->GetResponseByType(static_cast(stimType)); + + if (resp != NULL) + { + resp->SetResponseAction(action); + } +} + +void idEntity::AllowResponse(StimType type, idEntity* fromEntity) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(type); + + if (stim != NULL) + { + stim->RemoveResponseIgnore(fromEntity); + } +} + +void idEntity::IgnoreResponse(StimType type, idEntity* fromEntity) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(type); + + if (stim != NULL) + { + stim->AddResponseIgnore(fromEntity); + } +} + +// grayman #2872 + +bool idEntity::CheckResponseIgnore(StimType type, idEntity* fromEntity) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(type); + + if (stim != NULL) + { + return ( stim->CheckResponseIgnore(fromEntity) ); + } + return true; +} + + +void idEntity::SetStimEnabled(StimType type, bool enabled) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(type); + + if (stim != NULL) + { + stim->SetEnabled(enabled); + } +} + +void idEntity::SetResponseEnabled(StimType type, bool enabled) +{ + CResponsePtr response = m_StimResponseColl->GetResponseByType(type); + + if (response != NULL) + { + response->SetEnabled(enabled); + } +} + +void idEntity::ClearStimIgnoreList(StimType type) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(type); + + if (stim != NULL) + { + stim->ClearResponseIgnoreList(); + } +} + +void idEntity::RemoveStim(StimType type) +{ + if (m_StimResponseColl->RemoveStim(type) == 0) + { + gameLocal.RemoveStim(this); + } +} + +void idEntity::RemoveResponse(StimType type) +{ + if (m_StimResponseColl->RemoveResponse(type) == 0) + { + gameLocal.RemoveResponse(this); + } +} + +CStimPtr idEntity::AddStim(StimType type, float radius, bool removable, bool isDefault) +{ + CStimPtr stim = m_StimResponseColl->AddStim(this, type, radius, removable, isDefault); + + gameLocal.AddStim(this); + + return stim; +} + +CResponsePtr idEntity::AddResponse(StimType type, bool removable, bool isDefault) +{ + CResponsePtr response = m_StimResponseColl->AddResponse(this, type, removable, isDefault); + + gameLocal.AddResponse(this); + + return response; +} + +void idEntity::TriggerResponse(idEntity* source, StimType type) +{ + // Try to lookup the response for this item + CResponsePtr resp = GetStimResponseCollection()->GetResponseByType(type); + + if (resp == NULL || resp->m_State != SS_ENABLED) + { + return; + } + + // There is an enabled response defined + // Check duration, disable if past duration + if (resp->m_Duration && (gameLocal.time - resp->m_EnabledTimeStamp) > resp->m_Duration) + { + resp->Disable(); + } + else + { + // Fire the response and pass the originating entity and no stim object + // no stim means that this is no "real" stim just a temporary or virtual one + resp->TriggerResponse(source); + } +} + + +/** Called when m_renderTrigger is rendered. + * It will resume the m_renderWaitingThread. + */ +bool idEntity::WaitForRenderTriggered( renderEntity_s* renderEntity, const renderView_s* view ) +{ + // NOTE: We must avoid changing the game state from within this function. + // However, we'll add an event to resume the suspended thread. + + idEntity* ent = gameLocal.entities[ renderEntity->entityNum ]; + if ( !ent ) + gameLocal.Error( "idEntity::WaitForRenderTriggered: callback with NULL game entity" ); + + renderEntity->callback = NULL; + + if ( ent->m_renderWaitingThread ) + { + // Fortunately, this doesn't execute the script immediately, so + // I think it's safe to call from here. + idThread::ObjectMoveDone( ent->m_renderWaitingThread, ent ); + ent->m_renderWaitingThread = 0; + } + + return false; +} + +/** Called to update m_renderTrigger after the render entity is modified. + * Only updates the render trigger if a thread is waiting for it. + */ +void idEntity::PresentRenderTrigger() +{ + if ( !m_renderWaitingThread ) + { + goto Quit; + } + + // Update the renderTrigger to match renderEntity's bounding box. + // In order to ensure that other code can easily add to the bounding + // box, we're going to pre-rotate the bounding box, and keep the axis + // unrotated. + m_renderTrigger.origin = renderEntity.origin; + m_renderTrigger.bounds = renderEntity.bounds * renderEntity.axis; + // I haven't yet figured out where renderEntity.entityNum is set... + // but it looks like we have to manually set it for m_renderTrigger. + m_renderTrigger.entityNum = entityNumber; + + // Update the renderTrigger in the render world. + if ( m_renderTriggerHandle == -1 ) + m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); + else + gameRenderWorld->UpdateEntityDef( m_renderTriggerHandle, &m_renderTrigger ); + + Quit: + return; +} + +/* +================ +idEntity::Inventory + +This returns the inventory object of this entity. If this entity doesn't +have one, it creates the inventory. +================ +*/ +const CInventoryPtr& idEntity::Inventory() +{ + if (m_Inventory == NULL ) + { + m_Inventory = CInventoryPtr(new CInventory()); + m_Inventory->SetOwner(this); + } + + return m_Inventory; +} + +/* +================ +idEntity::InventoryCursor + +This returns the inventory cursor object of this entity. If this entity +doesn't have one, it creates the inventory cursor. + +The cursor is intended for arbitrary use, and need not point to this +entity's inventory. +================ +*/ +const CInventoryCursorPtr& idEntity::InventoryCursor() +{ + if (m_InventoryCursor == NULL) + { + m_InventoryCursor = Inventory()->CreateCursor(); + } + + return m_InventoryCursor; +} + +void idEntity::OnAddToLocationEntity(CObjectiveLocation* locationEnt) +{ + idEntityPtr locationEntPtr; + locationEntPtr = locationEnt; + + // Ensure that objective locations don't add themselves twice or more times + // Tels: The assert below triggers under Debug build when loading Heart, took + // it out since it will be ignored under Release builds anyway + //assert(m_objLocations.FindIndex(locationEntPtr) == -1); + if (m_objLocations.FindIndex(locationEntPtr) != -1) + { + return; + } + + m_objLocations.Alloc() = locationEntPtr; +} + +void idEntity::OnRemoveFromLocationEntity(CObjectiveLocation* locationEnt) +{ + idEntityPtr locationEntPtr; + locationEntPtr = locationEnt; + + // Ensure that only registered location ents are removed + assert(m_objLocations.FindIndex(locationEntPtr) != -1); + + m_objLocations.Remove(locationEntPtr); +} + +void idEntity::Event_PropSound( const char *sndName ) +{ + PropSoundDirect( sndName, false, false, 0.0f ); +} + +void idEntity::Event_PropSoundMod( const char *sndName, float VolModIn ) +{ + PropSoundDirect( sndName, false, false, VolModIn ); +} + +/* +================ +idEntity::Event_InPVS + +Returns non-zero if this entity is in the player's PVS, zero otherwise. +================ +*/ +void idEntity::Event_InPVS() +{ + idThread::ReturnFloat( gameLocal.InPlayerPVS( this ) ); +} + +/* +================ +idEntity::Event_WaitForRender + +Called by sys.waitForRender(ent) to find out if it can wait for this entity to render. +================ +*/ +void idEntity::Event_WaitForRender() +{ + if ( !m_renderWaitingThread ) + { + // Give the renderTrigger an invisible model to prevent a black cube from showing up. + if ( !m_renderTrigger.hModel ) + m_renderTrigger.hModel = renderModelManager->FindModel( cv_empty_model.GetString() ); + if ( !m_renderTrigger.hModel ) + gameLocal.Error( "Unable to load model: %s\n", cv_empty_model.GetString() ); + + m_renderTrigger.callback = idEntity::WaitForRenderTriggered; + m_renderWaitingThread = idThread::CurrentThreadNum(); + + // Make sure Present() gets called. + BecomeActive( TH_UPDATEVISUALS ); + + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/* +================ +idEntity::Event_SetGui + +Changes the GUI file that's loaded by an overlay. Overlays 1, 2 and 3 are +reserved for the entity GUIs, and special code is implemented to change them. +A changed GUI does not see gui_parm spawn args. (for one thing, if there's a +script changing GUIs, then the script could easily send spawnargs to the GUI +if it wanted to.) +================ +*/ +void idEntity::Event_SetGui( int handle, const char *guiFile ) { + if ( !uiManager->CheckGui(guiFile) ) { + gameLocal.Warning( "Unable to load GUI file: %s\n", guiFile ); + goto Quit; + } + + if ( !m_overlays.exists( handle ) ) { + gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); + goto Quit; + } + + // Entity GUIs are handled differently from regular ones. + if ( handle >= 1 && handle <= MAX_RENDERENTITY_GUI ) { + + assert( m_overlays.isExternal( handle ) ); + + if ( renderEntity.gui[ handle-1 ] && renderEntity.gui[ handle-1 ]->IsUniqued() ) { + + // We're dealing with an existing unique GUI. + // We need to read a new GUI into it. + + // Clear the state. + const idDict &state = renderEntity.gui[ handle-1 ]->State(); + const idKeyValue *kv; + while ( ( kv = state.MatchPrefix( "" ) ) != NULL ) + renderEntity.gui[ handle-1 ]->DeleteStateVar( kv->GetKey() ); + + renderEntity.gui[ handle-1 ]->InitFromFile( guiFile ); + + } else { + + // We're either dealing with a non-existant GUI, or a non-unique one. + // It's safe to just set the render entity to point to a new GUI without + // bothering to deallocate the previous GUI. + renderEntity.gui[ handle-1 ] = uiManager->FindGui( guiFile, true, true ); + m_overlays.setGui( handle, renderEntity.gui[ handle - 1 ] ); + assert( renderEntity.gui[ handle-1 ] ); + + } + + } else if ( !m_overlays.isExternal( handle ) ) { + + bool result = m_overlays.setGui( handle, guiFile ); + assert( result ); + + } else { + gameLocal.Warning( "Cannot call setGui() on external handle: %d\n", handle ); + } + + Quit: + return; +} + +/* +================ +idEntity::Event_GetGui + +Returns the file loaded by a specific GUI. +================ +*/ +void idEntity::Event_GetGui( int handle ) { + idUserInterface *gui = m_overlays.getGui( handle ); + if ( gui ) + idThread::ReturnString( gui->Name() ); + else + idThread::ReturnString( "" ); +} + +void idEntity::SetGuiString(int handle, const char *key, const char *val) +{ + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui(handle); + if(gui == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + goto Quit; + } + + if(!gui->IsUniqued()) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); + goto Quit; + } + + gui->SetStateString(key, val); + gui->StateChanged(gameLocal.time); + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); + } + +Quit: + return; +} + +/* +================ +idEntity::Event_SetGuiString + +Sets a parameter for a GUI. (note that the GUI needs to be unique) +================ +*/ +void idEntity::Event_SetGuiString(int handle, const char *key, const char *val) +{ + SetGuiString(handle, key, val); +} + +const char *idEntity::GetGuiString(int handle, const char *key) +{ + const char *retStr = NULL; + + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui(handle); + if(gui) + retStr = gui->GetStateString(key); + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + + return retStr; +} + +void idEntity::Event_GetGuiString(int handle, const char *key) +{ + const char *retStr = GetGuiString(handle, key); + + if(retStr == NULL) + retStr = ""; + + idThread::ReturnString(retStr); +} + +void idEntity::SetGuiFloat( int handle, const char *key, float f) +{ + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui(handle); + if(gui == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + goto Quit; + } + + if(!gui->IsUniqued()) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); + goto Quit; + } + + gui->SetStateFloat(key, f); + gui->StateChanged(gameLocal.time); + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); + +Quit: + return; +} + +void idEntity::Event_SetGuiFloat(int handle, const char *key, float f) +{ + SetGuiFloat(handle, key, f); +} + +float idEntity::GetGuiFloat(int handle, const char *key) +{ + float retVal = 0; + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui( handle ); + if (gui) + retVal = gui->GetStateFloat(key); + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); + + return retVal; +} + +void idEntity::Event_GetGuiFloat(int handle, const char *key) +{ + idThread::ReturnFloat(GetGuiFloat(handle, key)); +} + +void idEntity::SetGuiInt( int handle, const char *key, int n) +{ + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui(handle); + if(gui == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + goto Quit; + } + + if(!gui->IsUniqued()) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); + goto Quit; + } + + gui->SetStateInt(key, n); + gui->StateChanged(gameLocal.time); + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); + +Quit: + return; +} + +void idEntity::Event_SetGuiInt(int handle, const char *key, int n) +{ + SetGuiInt(handle, key, n); +} + +int idEntity::GetGuiInt(int handle, const char *key) +{ + int retVal = 0; + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui(handle); + if (gui) + retVal = gui->GetStateInt(key); + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); + + return retVal; +} + +void idEntity::Event_GetGuiInt(int handle, const char *key) +{ + idThread::ReturnInt(GetGuiInt(handle, key)); +} + +/* +================ +idEntity::Event_SetGuiStringFromKey + +This is a kludge. It's hopefully temporary, but probably not. Anyway, it's +used by readables to bypass the 127 char limit on string variables in scripts. +================ +*/ +void idEntity::Event_SetGuiStringFromKey( int handle, const char *key, idEntity *src, const char *spawnArg ) +{ + if(!src) + { + gameLocal.Warning( "Unable to get key, since the source entity was NULL.\n" ); + return; + } + + if(!m_overlays.exists(handle)) + { + gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); + return; + } + + idUserInterface *gui = m_overlays.getGui( handle ); + if(!gui) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); + return; + } + + if(!gui->IsUniqued()) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); + return; + } + + gui->SetStateString( key, gameLocal.m_I18N->Translate( src->spawnArgs.GetString( spawnArg, "" ) ) ); + gui->StateChanged( gameLocal.time ); +} + +void idEntity::CallGui(int handle, const char *namedEvent) +{ + if(m_overlays.exists(handle)) + { + idUserInterface *gui = m_overlays.getGui( handle ); + if(gui == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, namedEvent); + return; + } + + if(!gui->IsUniqued()) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, namedEvent); + return; + } + + gui->HandleNamedEvent( namedEvent ); + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d [%s]\r", handle, namedEvent); + } + +} + +/* +================ +idEntity::Event_CallGui + +Calls a named event in a GUI. (note that the GUI needs to be unique) +================ +*/ +void idEntity::Event_CallGui(int handle, const char *namedEvent) +{ + CallGui(handle, namedEvent); +} + +/* +================ +idEntity::Event_LoadExternalData + +Used to load an external xdata declaration into this +object's spawn args. The prefix will be prepended to +the names of all keys in the declaration. +================ +*/ +void idEntity::Event_LoadExternalData( const char *xdFile, const char* prefix ) +{ + const tdmDeclXData *xd = static_cast< const tdmDeclXData* >( declManager->FindType( DECL_XDATA, xdFile, false ) ); + if ( xd != NULL ) { + const idDict *data = &(xd->m_data); + const idKeyValue *kv; + + int i = data->GetNumKeyVals(); + while ( i-- ) { + kv = data->GetKeyVal(i); + spawnArgs.Set( prefix + kv->GetKey(), kv->GetValue() ); + } + + idThread::ReturnInt( 1 ); + } + else + { + gameLocal.Warning("Non-existant xdata declaration: %s\n", xdFile); + idThread::ReturnInt( 0 ); + } +} + +/* +================ +idEntity::Event_GetInventory + +Returns the entity containing us. +================ +*/ +void idEntity::Event_GetInventory() +{ +/* CInventoryItem* item = InventoryItem(); + if ( item != NULL ) { + CInventory* inv = item->Inventory(); + if ( inv != NULL ) { + idThread::ReturnEntity( inv->m_owner.GetEntity() ); + } else { + idThread::ReturnEntity( NULL ); + } + } +*/ +} + +idThread *idEntity::CallScriptFunctionArgs(const char *fkt, bool ClearStack, int delay, const char *fmt, ...) +{ + idThread *pThread = NULL; + va_list argptr; + + const function_t *pScriptFkt = scriptObject.GetFunction(fkt); + if(pScriptFkt == NULL) + { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Action: %s not found in local space, checking for global namespace.\r", fkt); + pScriptFkt = gameLocal.program.FindFunction(fkt); + } + + if(pScriptFkt) + { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Running scriptfunction '%s'\r", fkt); + pThread = new idThread(pScriptFkt); + va_start(argptr, fmt); + pThread->CallFunctionArgsVN(pScriptFkt, ClearStack, fmt, argptr); + va_end(argptr); + pThread->DelayedStart(delay); + } + else + DM_LOG(LC_MISC, LT_ERROR)LOGSTRING("Scriptfunction not found! [%s]\r", fkt); + + return pThread; +} + +void idEntity::Attach( idEntity *ent, const char *PosName, const char *AttName ) +{ + idVec3 origin; + idMat3 axis; + idAngles angleOffset, angleSubOffset(0.0f,0.0f,0.0f); + idVec3 originOffset, originSubOffset(vec3_zero); + SAttachPosition *pos; + +// New position system: + if( PosName && ((pos = GetAttachPosition(PosName)) != NULL) ) + { + originOffset = pos->originOffset; + angleOffset = pos->angleOffset; + + // entity-specific offsets to a given position + originSubOffset = ent->spawnArgs.GetVector( va("origin_%s", PosName ) ); + angleSubOffset = ent->spawnArgs.GetAngles( va("angles_%s", PosName ) ); + } +// The following is the old system and will be phased out + else + { + //gameLocal.Warning("%s is attaching %s using the deprecated attachment system.\n", name.c_str(), ent->name.c_str()); + angleOffset = ent->spawnArgs.GetAngles( "angles" ); + originOffset = ent->spawnArgs.GetVector( "origin" ); + } + + origin = GetPhysics()->GetOrigin(); + axis = GetPhysics()->GetAxis(); + + idMat3 rotate = angleOffset.ToMat3(); + idMat3 newAxis = rotate * axis; + ent->SetOrigin( origin + originOffset * axis + originSubOffset * newAxis ); + ent->SetAxis( angleSubOffset.ToMat3() * newAxis ); + ent->Bind( this, true ); + ent->cinematic = cinematic; + + CAttachInfo &attach = m_Attachments.Alloc(); + attach.channel = 0; // overloaded in animated classes + attach.ent = ent; + attach.name = AttName; + idStr positionString = PosName; + attach.posName = positionString; // grayman #2603 + + // Update name->m_Attachment index mapping + int index = m_Attachments.Num() - 1; + if( AttName != NULL ) + m_AttNameMap.insert(AttNameMap::value_type(AttName, index)); +} + +void idEntity::Detach( const char *AttName ) +{ + int ind = GetAttachmentIndex( AttName ); + if (ind >= 0 && ind < m_Attachments.Num() ) + { + DetachInd( ind ); + } + else + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Detach called with invalid attachment name %s\r", AttName); + } +} + +void idEntity::DetachInd( int ind ) +{ + idEntity *ent = NULL; + + // DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Detach called for index %d\r", ind); + if( ind < 0 || ind >= m_Attachments.Num() ) + { + // TODO: log invalid index error + goto Quit; + } + + ent = m_Attachments[ind].ent.GetEntity(); + + if( !ent || !m_Attachments[ind].ent.IsValid() ) + { + // TODO: log bad attachment entity error + goto Quit; + } + + // DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Detach: Ent %s unbound\r", ent->name.c_str()); + ent->Unbind(); + // We don't want to remove it from the list, otherwise mapping of name to index gets screwed up + m_Attachments[ind].ent = NULL; + + // remove from name->index mapping + m_AttNameMap.erase( m_Attachments[ind].name.c_str() ); + +Quit: + return; +} + +void idEntity::ReAttachToCoords + ( const char *AttName, idVec3 offset, idAngles angles ) +{ + idEntity *ent( NULL ); + idVec3 origin; + idMat3 axis, rotate, newAxis; + CAttachInfo *attachment( NULL ); + + attachment = GetAttachInfo( AttName ); + if( attachment ) + ent = attachment->ent.GetEntity(); + + if( !attachment || !attachment->ent.IsValid() || !ent ) + { + // TODO: log bad attachment entity error + goto Quit; + } + + axis = GetPhysics()->GetAxis(); + origin = GetPhysics()->GetOrigin(); + rotate = angles.ToMat3(); + newAxis = rotate * axis; + + ent->Unbind(); + + // greebo: Note that Unbind() will invalidate the entity pointer in the attachment list + // Hence, re-assign the attachment entity pointer (the index itself is ok) + attachment->ent = ent; + + ent->SetAxis( newAxis ); + ent->SetOrigin( origin + offset * axis ); + + ent->Bind( this, true ); + ent->cinematic = cinematic; + + // set the spawnargs for later retrieval as well + ent->spawnArgs.Set( "joint", "" ); + ent->spawnArgs.SetVector( "origin", offset ); + ent->spawnArgs.SetAngles( "angles", angles ); + +Quit: + return; +} + +void idEntity::ReAttachToPos + ( const char *AttName, const char *PosName ) +{ + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ReAttachToPos called with attachment name %s, positiong %s, on entity %s\r", AttName, PosName, name.c_str()); + + int ind = GetAttachmentIndex( AttName ); + if (ind == -1 ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); + return; + } + + idEntity* ent = GetAttachment( ind ); + + if( !ent ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", AttName, name.c_str()); + return; + } + + // Hack: Detaching leaves a null entry in the array to preserve indices + // To leverage existing Attach function, we detach and then re-insert + // into this place in the array. + + DetachInd( ind ); + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ReAttaching...\r"); + Attach( ent, PosName, AttName ); + + int indEnd = m_Attachments.Num(); + + // greebo: Decrease the end index by 1 before passing it to operator[] + indEnd--; + + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("End index is %d\r", indEnd); + + // Copy the attachment info from the end of the list over the previous index + m_Attachments[ind] = m_Attachments[indEnd]; + + // remove the newly created end entry (is a duplicate now) + m_Attachments.RemoveIndex( indEnd ); + + // Fix the name mapping to map back to the original index + m_AttNameMap.erase( AttName ); + m_AttNameMap.insert(AttNameMap::value_type(AttName, ind)); +} + +void idEntity::ShowAttachment( const char *AttName, bool bShow ) +{ + int ind = GetAttachmentIndex( AttName ); + if (ind >= 0 ) + { + ShowAttachmentInd( ind, bShow ); + } + else + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ShowAttachment called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); + } +} + +void idEntity::ShowAttachmentInd( int ind, bool bShow ) +{ + idEntity *ent( NULL ); + + if( ind < 0 || ind >= m_Attachments.Num() ) + { + // TODO: log invalid index error + goto Quit; + } + + ent = m_Attachments[ind].ent.GetEntity(); + + if( !ent || !m_Attachments[ind].ent.IsValid() ) + { + // TODO: log bad attachment entity error + goto Quit; + } + + if( bShow ) + ent->Show(); + else + ent->Hide(); + +Quit: + return; +} + +int idEntity::GetAttachmentIndex( const char *AttName ) +{ + AttNameMap::iterator k; + k = m_AttNameMap.find(AttName); + if (k != m_AttNameMap.end() && k->second < m_Attachments.Num() ) + { + return k->second; + } + else + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Attempt to access invalid attachment name %s on entity %s\r", AttName, name.c_str()); + return -1; + } +} + +idEntity *idEntity::GetAttachment( const char *AttName ) +{ + /* tels: use GetAttachmentIndex() to bypass GetAttachInfo() */ + int ind = GetAttachmentIndex(AttName); + if( ind >= 0 ) + return m_Attachments[ind].ent.GetEntity(); + else + return NULL; + + /*CAttachInfo *AttInfo = GetAttachInfo( AttName ); + + if( AttInfo ) + return AttInfo->ent.GetEntity(); + else + return NULL;*/ +} + +idEntity *idEntity::GetAttachment( int ind ) +{ + idEntity *ent = NULL; + + if( ind < 0 || ind >= m_Attachments.Num() ) + { + // TODO: log invalid index error + goto Quit; + } + + ent = m_Attachments[ind].ent.GetEntity(); + + if( !ent || !m_Attachments[ind].ent.IsValid() ) + { + // TODO: log bad attachment entity error + ent = NULL; + goto Quit; + } + +Quit: + return ent; +} + +CAttachInfo *idEntity::GetAttachInfo( const char *AttName ) +{ + int ind = GetAttachmentIndex(AttName); + if( ind >= 0 ) + return &m_Attachments[ind]; + else + return NULL; +} + +// Tels: Get the entity attached at the position given by the attachment position +// grayman #2603 - resurrected and spruced up for relight work +idEntity* idEntity::GetAttachmentByPosition( idStr PosName ) +{ + int num = m_Attachments.Num(); + + for (int i = 0 ; i < num ; i++) + { + if ((m_Attachments[i].ent.GetEntity() != NULL) && m_Attachments[i].ent.IsValid()) + { + if (m_Attachments[i].posName == PosName) + { + return m_Attachments[i].ent.GetEntity(); + } + } + } + + // not found + return NULL; +} + + +idEntity *idEntity::GetAttachmentFromTeam( const char *AttName ) +{ + /* tels: Look directly at this entity for the attachment */ + int ind = GetAttachmentIndex(AttName); + if( ind >= 0 ) + { + /* we found it */ + //gameLocal.Printf(" Found entity %s at index %i\n", m_Attachments[ind].ent.GetEntity()->name.c_str(), ind); + return m_Attachments[ind].ent.GetEntity(); + } + + /* tels: not found, look at entities bound to this entity */ + idEntity* NextEnt = this; + + if ( bindMaster ) + { + NextEnt = bindMaster; + } + + while ( NextEnt != NULL ) + { + //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); + idEntity* AttEnt = NextEnt->GetAttachment( AttName ); + if (AttEnt) + { + /* we found it */ + //gameLocal.Printf(" Found entity %s at entity %s.\n", + // AttEnt->name.c_str(), NextEnt->name.c_str()); + return AttEnt; + } + /* not found yet, get next Team member */ + NextEnt = NextEnt->GetNextTeamEntity(); + } + + /* not found at all */ + return NULL; +} + +void idEntity::BindNotify( idEntity *ent ) +{ +} + +void idEntity::UnbindNotify( idEntity *ent ) +{ + // greebo: Activate physics on "Unbind" of any slaves + physics->Activate(); +} + +void idEntity::Event_TimerCreate(int stimType, int Hour, int Minute, int Seconds, int Millisecond) +{ + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Create Timer: Stimtype %d, Hour: %d, Minute: %d, Seconds: %d, Milliseconds: %d\r", + stimType, Hour, Minute, Seconds, Millisecond); + + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + + CStimResponseTimer* timer = stim->AddTimerToGame(); + timer->SetTimer(Hour, Minute, Seconds, Millisecond); +} + +void idEntity::Event_TimerStop(int stimType) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + CStimResponseTimer *timer = (stim != NULL) ? stim->GetTimer() : NULL; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StopTimer: Stimtype %d\r", stimType); + if (timer != NULL) + { + timer->Stop(); + } +} + +void idEntity::Event_TimerStart(int stimType) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StartTimer: Stimtype %d \r", stimType); + + if (timer != NULL) + { + timer->Start(static_cast(sys->GetClockTicks())); + } +} + +void idEntity::Event_TimerRestart(int stimType) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("RestartTimer: Stimtype %d \r", stimType); + + if (timer != NULL) + { + timer->Restart(static_cast(sys->GetClockTicks())); + } +} + +void idEntity::Event_TimerReset(int stimType) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("ResetTimer: Stimtype %d \r", stimType); + + if (timer != NULL) + { + timer->Reset(); + } +} + +void idEntity::Event_TimerSetState(int stimType, int state) +{ + CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); + + CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("SetTimerState: Stimtype-%d State: %d\r", stimType, state); + + if (timer != NULL) + { + timer->SetState(static_cast(state)); + } +} + +void idEntity::Event_SetFrobable(bool bVal) +{ + SetFrobable( bVal ); +} + +void idEntity::Event_IsFrobable( void ) +{ + idThread::ReturnInt( (int) m_bFrobable ); +} + +void idEntity::Event_Frob() +{ + idPlayer* player = static_cast(gameLocal.entities[gameLocal.localClientNum]); + if (player != NULL) + { + // Let the player frob this entity. + player->PerformFrob(EPressed, this); + } +} + +void idEntity::Event_IsHilighted( void ) +{ + int retVal = 0; + if ( m_bFrobHighlightState ) + retVal++; + if ( m_bFrobbed ) + retVal++; + idThread::ReturnInt( retVal ); +} + + +void idEntity::Event_FrobHilight( bool bVal ) +{ + SetFrobHighlightState( bVal ); +} + +void idEntity::Event_CheckAbsence() +{ + if (m_AbsenceNoticeability > 0) + { + idBounds currentBounds = GetPhysics()->GetAbsBounds(); + float tolerance = spawnArgs.GetFloat("absence_bounds_tolerance", "0"); + + currentBounds.ExpandSelf(tolerance); + + idEntity* location(NULL); + bool isAbsent(true); + int locationsCount(0); + + for (const idKeyValue* kv = spawnArgs.MatchPrefix("absence_location"); kv != NULL; kv = spawnArgs.MatchPrefix("absence_location", kv)) + { + locationsCount++; + location = gameLocal.FindEntity(kv->GetValue()); + if (location != NULL) + { + isAbsent = !currentBounds.IntersectsBounds(location->GetPhysics()->GetAbsBounds()); + } + if (!isAbsent) + { + break; + } + } + + if (locationsCount == 0) + { + isAbsent = !currentBounds.IntersectsBounds(m_StartBounds); + } + + if (isAbsent && !m_AbsenceStatus) + { + // was there before, is absent now + SpawnAbsenceMarker(); + } + else if (!isAbsent && m_AbsenceStatus) + { + // was absent, is back + DestroyAbsenceMarker(); + } + + // set absence status + m_AbsenceStatus = isAbsent; + + PostEventMS(&EV_CheckAbsence, 5000); + } +} + +void idEntity::Event_CanBeUsedBy( idEntity *itemEnt ) +{ + idThread::ReturnInt( CanBeUsedBy( itemEnt, true ) ); +} + + +bool idEntity::SpawnAbsenceMarker() +{ + idStr absenceMarkerDefName = spawnArgs.GetString("def_absence_marker", "atdm:absence_marker"); + const idDict* markerDef = gameLocal.FindEntityDefDict(absenceMarkerDefName, false); + + if (markerDef == NULL) + { + gameLocal.Error( "Failed to find definition of absence marker entity " ); + return false; + } + + idEntity* ent; + gameLocal.SpawnEntityDef(*markerDef, &ent, false); + + if (!ent || !ent->IsType(CAbsenceMarker::Type)) + { + gameLocal.Error( "Failed to spawn absence marker entity" ); + return false; + } + + CAbsenceMarker* absenceMarker = static_cast(ent); + m_AbsenceMarker = absenceMarker; + + // absenceMarker->Init(); + if (!absenceMarker->initAbsenceReference (this, m_StartBounds)) + { + gameLocal.Error( "Failed to initialize absence reference in absence marker entity" ); + return false; + } + + // Success + return true; +} + +bool idEntity::DestroyAbsenceMarker() +{ + idEntity* absenceMarker = m_AbsenceMarker.GetEntity(); + if (absenceMarker != NULL) + { + absenceMarker->PostEventMS(&EV_Remove, 0); + m_AbsenceMarker = NULL; + } + return true; +} + +float idEntity::GetAbsenceNoticeability() +{ + return m_AbsenceNoticeability; +} + +/* +================ +idEntity::Event_RangedThreatTo +================ +*/ +void idEntity::Event_RangedThreatTo(idEntity* target) +{ + // This needs to be virtual, but I don't think events themselves + // can be virtual; so this just wraps a virtual method. + float result = this->RangedThreatTo(target); + idThread::ReturnFloat(result); +} + +/* +================ +idEntity::RangedThreatTo + +Return nonzero if this entity could potentially +attack the given (target) entity at range, or +entities in general if target is NULL. +For example, for the player this should return 1 +if the player has a bow equipped and 0 otherwise. +================ +*/ +float idEntity::RangedThreatTo(idEntity* target) +{ + // Most entities are not capable of attacking at range + return 0; +} + +void idEntity::GetTeamChildren( idList *list ) +{ +// ishtvan: TODO: I think this is WRONG and can go up and across the team hierarchy when called on bind children +// It only works as advertised when called on bindmasters + idEntity *NextEnt = NULL; + + list->Clear(); + for( NextEnt = GetNextTeamEntity(); NextEnt != NULL; NextEnt = NextEnt->GetNextTeamEntity() ) + { + if( NextEnt != this ) + list->Append( NextEnt ); + } +} + +void idEntity::Event_GetBindMaster( void ) +{ + idThread::ReturnEntity( GetBindMaster() ); +} + +void idEntity::Event_NumBindChildren( void ) +{ + idList ChildList; + GetTeamChildren( &ChildList ); + + idThread::ReturnInt( ChildList.Num() ); +} + +void idEntity::Event_GetBindChild( int ind ) +{ + idEntity *pReturnVal( NULL ); + + idList ChildList; + GetTeamChildren( &ChildList ); + + if( (ChildList.Num() - 1) >= ind ) + pReturnVal = ChildList[ ind ]; + + idThread::ReturnEntity( pReturnVal ); +} + +void idEntity::Event_GetNextInvItem() +{ + NextPrevInventoryItem(1); + + CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); + + idThread::ReturnEntity( (item != NULL) ? item->GetItemEntity() : NULL ); +} + +void idEntity::Event_GetPrevInvItem() +{ + NextPrevInventoryItem(-1); + + CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); + + idThread::ReturnEntity( (item != NULL) ? item->GetItemEntity() : NULL ); +} + +void idEntity::Event_SetCurInvCategory(const char* categoryName) +{ + CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); + + InventoryCursor()->SetCurrentCategory(categoryName); + + OnInventorySelectionChanged(prev); + + idThread::ReturnInt( InventoryCursor()->GetCurrentCategory()->GetName() == categoryName ); +} + +void idEntity::Event_SetCurInvItem(const char* itemName) +{ + CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); + + InventoryCursor()->SetCurrentItem(itemName); + + OnInventorySelectionChanged(prev); + + idThread::ReturnInt( InventoryCursor()->GetCurrentItem()->GetName() == itemName ); +} + +void idEntity::Event_GetCurInvCategory() +{ + idThread::ReturnString( InventoryCursor()->GetCurrentCategory()->GetName() ); +} + +void idEntity::Event_GetCurInvItemEntity() +{ + idThread::ReturnEntity( InventoryCursor()->GetCurrentItem()->GetItemEntity() ); +} + +void idEntity::Event_GetCurInvItemName() +{ + idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetName() ); +} + +void idEntity::Event_GetCurInvItemId() +{ + idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetItemId() ); +} + +void idEntity::Event_GetCurInvIcon() +{ + idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetIcon() ); +} + +void idEntity::Event_InitInventory(int callCount) +{ + // grayman #2820 - At the time of this writing, this routine checks + // for loot AND belonging in someone's inventory. If anything else is + // added here, the pre-check in ai.cpp that wraps around "PostEventMS( &EV_InitInventory, 0, 0 )" + // must account for that. The pre-check is needed to prevent unnecessary + // event posting that leads to doing nothing here. (I.e. the entity isn't + // loot, and it doesn't belong in someone's inventory.) + + // greebo: Check if this entity represents loot - if yes, update the total mission loot count + + // grayman #2820 - It probably never happens, but if loot is placed in the player's + // inventory at map start, it could get double-counted here if the player hasn't + // spawned yet and this routine has to call itself below. 'callCount' tracks how many + // times an attempt has been made, so we'll wrap the loot check in a callCount check + // to make sure it doesn't get done more than once. + + if ( callCount == 0 ) + { + int lootValue = spawnArgs.GetInt("inv_loot_value", "0"); + int lootType = spawnArgs.GetInt("inv_loot_type", "0"); + + // Check if the loot type is valid + if (lootType > LOOT_NONE && lootType < LOOT_COUNT && lootValue != 0) + { + gameLocal.m_MissionData->AddMissionLoot(static_cast(lootType), lootValue); + } + } + + // Check if this object should be put into the inventory of some entity + // when the object spawns. Default is no. + if (spawnArgs.GetBool("inv_map_start", "0")) + { + // Get the name of the target entity, defaults to PLAYER1 + idStr target = spawnArgs.GetString("inv_target", "player1"); + + idEntity* targetEnt = gameLocal.FindEntity(target.c_str()); + if (targetEnt != NULL) + { + // Put the item into the target entity's inventory + targetEnt->Inventory()->PutItem(this, targetEnt); + } + else + { + // Target entity not found (not spawned yet?) Postpone this event + // Check how often we've been called to avoid infinite postponing + if (callCount < 20) + { + // Try again in 250 ms. + PostEventMS(&EV_InitInventory, 250, callCount+1); + } + } + } +} + +void idEntity::Event_GetLootAmount(int lootType) +{ + int gold, jewelry, goods; + int total = Inventory()->GetLoot(gold, jewelry, goods); + + switch (lootType) + { + case LOOT_GOLD: + idThread::ReturnInt(gold); + return; + break; + + case LOOT_GOODS: + idThread::ReturnInt(goods); + return; + break; + + case LOOT_JEWELS: + idThread::ReturnInt(jewelry); + return; + break; + + default: + idThread::ReturnInt(total); + return; + break; + } + + idThread::ReturnInt(0); +} + +void idEntity::Event_ChangeLootAmount(int lootType, int amount) +{ + idThread::ReturnInt( ChangeLootAmount(lootType, amount) ); +} + +void idEntity::Event_AddInvItem(idEntity* ent) +{ + if (ent == NULL || ent->spawnArgs.FindKey("inv_name") == NULL) + { + gameLocal.Warning("Cannot add entity %s without 'inv_name' spawnarg to inventory of %s", ent->name.c_str(), name.c_str()); + return; + } + + AddToInventory(ent); +} + +void idEntity::Event_AddItemToInv(idEntity* ent) +{ + // no target, ignore + if (ent == NULL) + { + gameLocal.Warning("Cannot add entity %s to inventory of NULL target", GetName() ); + return; + } + + if (spawnArgs.FindKey("inv_name") == NULL) + { + gameLocal.Warning("Cannot add entity %s without 'inv_name' spawnarg to inventory of %s", GetName(), ent->name.c_str() ); + return; + } + + gameLocal.Printf("Adding entity %s to inventory of %s.\n", GetName(), ent->name.c_str() ); + ent->AddToInventory(this); +} + +CInventoryItemPtr idEntity::AddToInventory(idEntity *ent) +{ + // Sanity check + if (ent == NULL) return CInventoryItemPtr(); + + // Check if we have an inventory item. + idStr invName; + if (!ent->spawnArgs.GetString("inv_name", "", invName)) + { + return CInventoryItemPtr(); // not an inventory item + } + + // Get (create) the InventoryCursor of this Entity. + const CInventoryCursorPtr& crsr = InventoryCursor(); + + // Add the new item to the Inventory (with as owner) + CInventoryItemPtr item = crsr->Inventory()->PutItem(ent, this); + + if (item == NULL) + { + // not an inventory item + gameLocal.Warning("Couldn't add entity %s to inventory of %s", ent->name.c_str(), name.c_str()); + return item; + } + + // Play the (optional) acquire sound + idStr soundName = ent->spawnArgs.GetString("snd_acquire", ""); + if (! soundName.IsEmpty()) + { + StartSoundShader(declManager->FindSound(soundName), SCHANNEL_ANY, 0, false, NULL); + } + + return item; +} + +bool idEntity::ReplaceInventoryItem(idEntity* oldItem, idEntity* newItem) +{ + bool result = Inventory()->ReplaceItem(oldItem, newItem); + + // Fire the general "item changed" event + OnInventoryItemChanged(); + + return result; +} + +void idEntity::Event_ReplaceInvItem(idEntity* oldItem, idEntity* newItem) +{ + idThread::ReturnInt(ReplaceInventoryItem(oldItem, newItem) ? 1 : 0); +} + +int idEntity::ChangeLootAmount(int lootType, int amount) +{ + int groupTotal = 0; + int rc = 0; + idStr groupname; + + int gold, jewelry, goods; + int total = Inventory()->GetLoot(gold, jewelry, goods); + bool gained = (amount >= 0); + + switch(lootType) + { + case LOOT_GOLD: + gold += amount; + groupTotal = gold; + groupname = "loot_gold"; + rc = gold; + break; + + case LOOT_GOODS: + goods += amount; + groupTotal = goods; + groupname = "loot_goods"; + rc = goods; + break; + + case LOOT_JEWELS: + jewelry += amount; + groupTotal = jewelry; + groupname = "loot_jewels"; + rc = jewelry; + break; + + default: + rc = 0; + break; + } + + // Set the new values + Inventory()->SetLoot(gold, jewelry, goods); + + if (rc != 0) + { + gameLocal.m_MissionData->InventoryCallback(NULL, groupname, groupTotal, total, gained); + gameLocal.m_MissionData->ChangeFoundLoot(static_cast(lootType), amount); + } + + return rc; +} + +void idEntity::ChangeInventoryLightgemModifier(const char* invName, const char* invCategory, int value) +{ + CInventoryItemPtr item = Inventory()->GetItem(invName, invCategory); + if (item != NULL) + { + // Item found, set the value + item->SetLightgemModifier(value); + } + else + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change lightgem modifier, item %s not found\r", invName); + } +} + +void idEntity::ChangeInventoryIcon(const char* invName, const char* invCategory, const char* icon) +{ + CInventoryItemPtr item = Inventory()->GetItem(invName, invCategory); + + if (item != NULL) + { + // Item found, set the icon + item->SetIcon(icon); + } + else + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change inventory icon, item %s not found\r", invName); + } +} + +void idEntity::NextPrevInventoryItem(int direction) +{ + const CInventoryCursorPtr& cursor = InventoryCursor(); + assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() + + CInventoryItemPtr prev = cursor->GetCurrentItem(); + if (prev != NULL && prev->GetName() == TDM_DUMMY_ITEM && IsType(idPlayer::Type)) + { + // If current item is dummy then try to restore cursor to the last real item + CInventoryItemPtr lastItemRestored = Inventory()->GetItem(static_cast(this)->m_LastItemNameBeforeClear); + if (lastItemRestored != NULL) + { + cursor->SetCurrentItem(lastItemRestored); + } + static_cast(this)->m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; + } + // If the current item has not changed yet, move to the prev/next item + if (cursor->GetCurrentItem() == prev) + { + // direction parameter specifies whether next of previous item is chosen + if (direction > 0) cursor->GetNextItem(); + if (direction < 0) cursor->GetPrevItem(); + } + + // Call the selection changed event + OnInventorySelectionChanged(prev); +} + +void idEntity::NextPrevInventoryGroup(int direction) +{ + const CInventoryCursorPtr& cursor = InventoryCursor(); + + assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() + + CInventoryItemPtr prev = cursor->GetCurrentItem(); + + // direction parameter specifies whether next of previous item is chosen + if (direction > 0) cursor->GetNextCategory(); + if (direction < 0) cursor->GetPrevCategory(); + + OnInventorySelectionChanged(prev); +} + +void idEntity::CycleInventoryGroup(const idStr& groupName) +{ + const CInventoryCursorPtr& cursor = InventoryCursor(); + + assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() + + assert(cursor->GetCurrentCategory() != NULL); + + CInventoryItemPtr prev = cursor->GetCurrentItem(); + + if (cursor->GetCurrentCategory()->GetName() == groupName) + { + // We are already in the specified group + CInventoryItemPtr next = cursor->GetNextItem(); + + if (next->Category()->GetName() != groupName) + { + // We've changed groups, this means that the cursor has wrapAround set to false + // Set the cursor back to the first item + cursor->SetCurrentCategory(groupName); + } + } + else + { + // Not in the desired group yet, set the cursor to the first item in that group + cursor->SetCurrentCategory(groupName); + } + + OnInventorySelectionChanged(prev); +} + +void idEntity::OnInventoryItemChanged() +{ + // Nothing here, can be overriden by subclasses +} + +void idEntity::OnInventorySelectionChanged(const CInventoryItemPtr& prevItem) +{ + // Nothing here, can be overriden by subclasses +} + +void idEntity::ChangeInventoryItemCount(const char* invName, const char* invCategory, int amount) +{ + const CInventoryPtr& inventory = Inventory(); + bool bIsLoot( false ); + + CInventoryCategoryPtr category = inventory->GetCategory(invCategory); + if (category == NULL) + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change item count, inventory category %s not found\r", invCategory); + return; + } + + CInventoryItemPtr item = category->GetItem(invName); + if (item == NULL) + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change item count, item name %s not found\r", invName); + return; + } + + // Change the counter by amount (explicitly allow negative values) + item->SetCount(item->GetCount() + amount); + + // We consider items "dropped" if the amount is negative + bool dropped = (amount < 0); + + // Assume item does not have an overall value since it's not loot + gameLocal.m_MissionData->InventoryCallback + ( + item->GetItemEntity(), + item->GetName(), + item->GetValue(), + 1, + !dropped + ); + + if (item->GetCount() <= 0) + { + // Stackable item count reached zero, remove item from category + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Removing empty item from category.\r"); + + category->RemoveItem(item); + + // Advance the cursor (after removal, otherwise we stick to an invalid id) + InventoryCursor()->GetNextItem(); + + // Call the selection changed event, passing the removed item as previously selected item + OnInventorySelectionChanged(item); + } + + // Check for empty categories after the item has been removed + if (category->IsEmpty()) + { + // Remove empty category from inventory + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Removing empty inventory category.\r"); + + inventory->RemoveCategory(category); + + // Switch the cursor to the next category (after removal) + InventoryCursor()->GetNextCategory(); + + // There shouldn't be a need to call OnInventorySelectionChanged(), as this + // has already been done by the code above. + } +} + +void idEntity::AddFrobPeer(const idStr& frobPeerName) +{ + m_FrobPeers.AddUnique(frobPeerName); +} + +void idEntity::AddFrobPeer(idEntity* peer) +{ + if (peer != NULL) + { + AddFrobPeer(peer->name); + } +} + +void idEntity::RemoveFrobPeer(const idStr& frobPeerName) +{ + m_FrobPeers.Remove(frobPeerName); +} + +void idEntity::RemoveFrobPeer(idEntity* peer) +{ + if (peer != NULL) + { + RemoveFrobPeer(peer->name); + } +} + +idEntity* idEntity::GetFrobMaster() +{ + if (m_MasterFrob.IsEmpty()) return NULL; + + idEntity* master = gameLocal.FindEntity(m_MasterFrob); + + if (master == NULL) + { + // master doesn't exist anymore + m_MasterFrob.Clear(); + return NULL; + } + + return master; +} + +void idEntity::Event_DestroyOverlay(int handle) +{ + DestroyOverlay(handle); +} + +void idEntity::DestroyOverlay(int handle) +{ + if ( handle != OVERLAYS_MIN_HANDLE ) { + idUserInterface *gui = m_overlays.getGui( handle ); + if ( gui ) + gui->Activate( false, gameLocal.time ); + m_overlays.destroyOverlay( handle ); + } else { + gameLocal.Warning( "Cannot destroy HUD.\n" ); + } +} + +void idEntity::Event_CreateOverlay( const char *guiFile, int layer ) +{ + idThread::ReturnInt(CreateOverlay(guiFile, layer)); +} + +int idEntity::CreateOverlay(const char *guiFile, int layer) +{ + int handle = OVERLAYS_INVALID_HANDLE; + + if(guiFile == NULL || guiFile[0] == 0) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Invalid GUI file name\r"); + return OVERLAYS_INVALID_HANDLE; + } + + + if(!uiManager->CheckGui(guiFile)) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load GUI file: [%s]\r", guiFile); + return OVERLAYS_INVALID_HANDLE; + } + handle = m_overlays.createOverlay( layer ); + if(handle == OVERLAYS_INVALID_HANDLE) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to create overlay for GUI [%s]\r", guiFile); + return OVERLAYS_INVALID_HANDLE; + } + + m_overlays.setGui(handle, guiFile); + idUserInterface *gui = m_overlays.getGui(handle); + if(gui == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load GUI [%s] into overlay.\r", guiFile); + // free handle, or we would leak + m_overlays.destroyOverlay(handle); + return OVERLAYS_INVALID_HANDLE; + } + + gui->SetStateInt("handle", handle); + gui->Activate(true, gameLocal.time); + // Let's set a good default value for whether or not the overlay is interactive. + m_overlays.setInteractive(handle, gui->IsInteractive()); + + // scale the GUI according to gui_Width/gui_Height/gui_CenterX/gui_CenterY + gameLocal.UpdateGUIScaling( gui ); + + return handle; +} + +idUserInterface* idEntity::GetOverlay(int handle) +{ + return m_overlays.getGui(handle); +} + +/** +* If this entity (or any entity that it is attached to) has mantling disabled, +* then this returns false. Otherwise, returns true. +**/ +bool idEntity::IsMantleable() +{ + bool returnVal = true; + idEntity* ent=this; + while (ent!=NULL) + { + if (!ent->m_bIsMantleable) + { + returnVal = false; + break; + } + ent = ent->GetBindMaster(); + } + return returnVal; +} + +int idEntity::heal(const char* healDefName, float healScale) { + const idDict* healDef = gameLocal.FindEntityDefDict( healDefName ); + if ( !healDef ) { + gameLocal.Error( "Unknown healDef '%s'\n", healDefName ); + } + + int healAmount = static_cast(healDef->GetInt( "heal_amount" ) * healScale); + int healInterval = healDef->GetInt("heal_interval", "0"); + int healStepAmount = healDef->GetInt("heal_step_amount", "5"); + float healIntervalFactor = healDef->GetInt("heal_interval_factor", "1"); + bool isAir = idStr(healDef->GetString("heal_type", "")) == "air"; + + // Check if the entity can be healed in the first place + if ( healAmount == 0 || (!isAir && health >= spawnArgs.GetInt("health")) ) { + return 0; + } + + // Check for air potions + if (isAir) { + if (!IsType(idActor::Type)) { + // Don't apply air healing to non-actors + return 0; + } + + // Try to cast this entity onto idAI or idPlayer + idAI* ai = dynamic_cast(this); + idPlayer* player = dynamic_cast(this); + + if (ai != NULL) { + // This entity is an AI + ai->setAirTicks(ai->getAirTicks() + healAmount); + return 1; + } + else if (player != NULL) { + // This entity is a player + player->setAirTicks(player->getAirTicks() + healAmount); + return 1; + } + + return 0; + } + // Is this "instant" healing? + else if (healInterval == 0) { + // Yes, heal the entity + health += healAmount; + + // It may be possible that negative healAmounts are applied and the entity dies + if ( health <= 0 ) { + if ( health < -999 ) { + health = -999; + } + + Killed( gameLocal.world, gameLocal.world, abs(healAmount), GetLocalCoordinates(GetPhysics()->GetOrigin()), 0); + } + return 1; + } + // Is this a gradual healing def? This would only apply to idPlayer + else if (healInterval > 0 && healStepAmount != 0 && IsType(idPlayer::Type)) + { + idPlayer* player = dynamic_cast(this); + + if (player != NULL) { + player->GiveHealthPool(healAmount); + // Set the parameters of the health pool + player->setHealthPoolTimeInterval(healInterval, healIntervalFactor, healStepAmount); + } + return 1; + } + else { + // Nothing suitable found in the def arguments, return 0 + return 0; + } +} + +// Deals damage to this entity, documentation: see header +void idEntity::Event_Damage( idEntity *inflictor, idEntity *attacker, + const idVec3 &dir, const char *damageDefName, + const float damageScale ) +{ + // Pass the call to the regular member method of this class + Damage(inflictor, attacker, dir, damageDefName, damageScale, 0, NULL); +} + +void idEntity::Event_Heal( const char *healDefName, const float healScale ) +{ + // Pass the call to the idEntity::heal method + idThread::ReturnInt(heal(healDefName, healScale)); +} + +// tels: +void idEntity::Event_TeleportTo(idEntity* target) +{ + Teleport( vec3_origin, idAngles( 0.0f, 0.0f, 0.0f ), target ); +} + +void idEntity::Event_IsDroppable( void ) +{ + idThread::ReturnInt( spawnArgs.GetBool("inv_droppable") ); +} + +void idEntity::Event_SetDroppable( bool Droppable ) +{ + spawnArgs.SetBool( "inv_droppable", Droppable ); + // update the item in the player's inventory, if there is one + if( spawnArgs.FindKey("inv_name") != NULL ) + { + idStr itemName = spawnArgs.GetString("inv_name"); + CInventoryItemPtr item = gameLocal.GetLocalPlayer()->Inventory()->GetItem( itemName ); + if( item != NULL ) + item->SetDroppable( Droppable ); + } +} + +// tels: +// lightFalloff == 0 - none +// lightFalloff == 0.5 - sqrt(linear) +// lightFalloff == 1 - liniear with distance (falls off already too fast) +// lightFalloff == 2 - squared with distance +// lightDistScale is a scaling factor to divide the distance. Sensible values are around 1..2 +void idEntity::Event_GetLightInPVS( const float lightFalloff, const float lightDistScale ) +{ + idVec3 sum(0,0,0); + idVec3 local_light; + idVec3 local_light_radius; + idVec3 origin; + // divide dist by this factor, so 1 as light in 500 units stays, is half in 1000 etc + float dist_scaling = 5000 * lightDistScale; + + // If this is a player, use the eye location to match what the script does + // with $player1.GetLocation() + const idPlayer* player = gameLocal.GetLocalPlayer(); + + if (player == this) + { + origin = player->GetEyePosition(); + } + else + { + origin = GetPhysics()->GetOrigin(); + } + int areaNum = gameRenderWorld->PointInArea( origin ); + + // Find all light entities, then check if they are in the same area as the player: + for( idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) + { + if ( !ent || !ent->IsType( idLight::Type ) ) { + continue; + } + + idLight* light = static_cast( ent ); + + // this makes it add all lights in the PVS, which is not good, albeit it makes leaning a bit better + //if ( gameLocal.InPlayerPVS( light ) ) { + + // light is in the same area? + idVec3 light_origin = light->GetLightOrigin(); + if ( areaNum == gameRenderWorld->PointInArea( light_origin ) ) { + light->GetColor( local_light ); + // multiple the light color by the radius to get a fake "light energy": + light->GetRadius( local_light_radius ); + // fireplace: 180+180+120/3 => 160 / 800 => 0.2 + // candle: 130+130+120/3 => 123 / 800 => 0.15 + // firearrow: 10+ 10+ 10/3 => 10 / 800 => 0.0125 + //gameLocal.Printf (" Adding light %s color %s radius %s\n", light->GetName(), local_light.ToString(), local_light_radius.ToString() ); + local_light *= (float) + (local_light_radius.x + + local_light_radius.y + + local_light_radius.z) / 2400; + // dimish light with distance? + if (lightFalloff > 0) + { + // compute distance + idVec3 dist3 = light_origin - origin; + // == 1 + float dist; + if (lightFalloff < 1) + { + dist = idMath::Sqrt( dist3.Length() ); // square root of dist + } + else if (lightFalloff > 1) + { + // squared + dist = dist3.LengthSqr(); + } + else + { + // linear + dist = dist3.Length(); + } + // divide by dist + //gameLocal.Warning(" dist %0.2f, falloff %0.0f\n", dist, lightFalloff ); + dist /= dist_scaling; + //gameLocal.Warning(" dist is now %0.2f\n", dist ); + //gameLocal.Warning(" local_light %s\n", local_light.ToString() ); + local_light /= dist; + //gameLocal.Warning(" local_light %s\n", local_light.ToString() ); + } + sum += local_light; + } + } + idThread::ReturnVector( sum ); +} + +bool idEntity::canSeeEntity(idEntity* target, int useLighting) { + // The target point is the origin of the other entity. + idVec3 toPos = target->GetPhysics()->GetOrigin(); + + trace_t tr; + // Perform a trace from the own origin to the target entity's origin + gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), toPos, MASK_OPAQUE, this ); + + if (tr.fraction >= 1.0f || gameLocal.GetTraceEntity(tr) == target) { + // Trace test passed, entity is visible + + if (useLighting) { + idBounds entityBounds = target->GetPhysics()->GetAbsBounds(); + entityBounds.ExpandSelf (0.1f); // A single point doesn't work with ellipse intersection + + idVec3 bottomPoint = entityBounds[0]; + idVec3 topPoint = entityBounds[1]; + + float lightQuotient = LAS.queryLightingAlongLine (bottomPoint, topPoint, this, true); + + // Return TRUE if the lighting exceeds the threshold. + return (lightQuotient >= VISIBILTIY_LIGHTING_THRESHOLD); + } + + // No lighting to consider, return true + return true; + } + else { + return false; + } +} + +void idEntity::Event_CanSeeEntity(idEntity* target, int useLighting) +{ + idThread::ReturnInt(canSeeEntity(target, useLighting) ? 1 : 0); +} + +void idEntity::ProcCollisionStims( idEntity *other, int body ) +{ + if (!other) + { + return; + } + + if (other->IsType(idAFEntity_Base::Type) && body >= 0) + { + idAFEntity_Base* otherAF = static_cast(other); + int bodID = otherAF->BodyForClipModelId( body ); + + //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ProcCollisionStims called GetBody on id %d\r", bodID); + + idAFBody* struckBody = otherAF->GetAFPhysics()->GetBody(bodID); + + idEntity* reroute = struckBody->GetRerouteEnt(); + + if (reroute) + { + other = reroute; + } + } + + assert(other->GetStimResponseCollection() != NULL); // always non-NULL by design + + if (other->GetStimResponseCollection()->HasResponse()) + { + CStimResponseCollection* thisColl = GetStimResponseCollection(); + + // check each stim to see if it's a collision stim + int numStims = thisColl->GetNumStims(); + + for (int i = 0; i < numStims; ++i) + { + const CStimPtr& stim = thisColl->GetStim(i); + + if (stim->m_bCollisionBased) + { + stim->m_bCollisionFired = true; + stim->m_CollisionEnts.Append(other); + } + } + } +} + +/* tels: Parses "def_attach" spawnargs and builds a list of idDicts that + * contain the spawnargs to spawn the attachments, which is done in + * ParseAttachments() later. This is a two-phase process to allow other + * code (e.g. SEED) to just parse the attachments without spawning them. + */ +void idEntity::ParseAttachmentSpawnargs( idList *argsList, idDict *from ) +{ + const idKeyValue *kv = from->MatchPrefix( "def_attach", NULL ); + while ( kv ) + { + idDict args; + + // Read the classname of the attachment + + // Don't process keyvalues equal to "-" (empty attachment). + if (kv->GetValue() != "-") + { + args.Set( "classname", kv->GetValue().c_str() ); + + // make items non-touchable so the player can't take them out of the character's hands + args.Set( "no_touch", "1" ); + + // don't let them drop to the floor + args.Set( "dropToFloor", "0" ); + + // check for attachment position spawnarg + idStr Suffix = kv->GetKey(); + Suffix.StripLeading( "def_attach" ); + idStr PosKey = "pos_attach" + Suffix; + // String name of the attachment for later accessing + idStr AttName = "name_attach" + Suffix; + idStr AttNameValue = from->GetString(AttName); + if (! AttNameValue) + { + // fall back to the position if no name was defined + AttNameValue = from->GetString(PosKey); + } + + // store for later query + args.Set("_poskey", PosKey); + args.Set("_attnamevalue", AttNameValue ); + + // tels: parse all "set .." spawnargs + const idKeyValue *kv_set = from->MatchPrefix( "set ", NULL ); + while ( kv_set ) + { + // "set FOO on BAR" "0.5 0.5 0" + // means set "_color" "0.5 0.5 0" on the entity attached to the attachment point + // named "BAR" (defined with "name_attach" "BAR" on the original entity) + + // Get the value + // example: "0.5 0.5 0" + idStr SpawnargValue(kv_set->GetValue()); + + // "set FOO on BAR" + idStr SetAttName(kv_set->GetKey()); + // "set FOO on BAR" => "FOO on BAR" + SetAttName = SetAttName.Right( kv_set->GetKey().Length() - 4 ); + + // "FOO on BAR" + idStr SpawnargName(SetAttName); + + // find position of first ' ' + int PosSpace = SetAttName.Find( ' ', 0, -1); + + if (PosSpace == -1) + { + gameLocal.Warning( "%s: Spawnarg '%s' (value '%s') w/o attachment name. Applying to to all attachments.", + GetName(), kv_set->GetKey().c_str(), kv_set->GetValue().c_str() ); + //kv_set = from->MatchPrefix( "set ", kv_set ); + //continue; + // pretend "set _color" "0.1 0.2 0.3" means "set _color on BAR" where BAR is the + // current attachement. So it applies to all of them. + // SpawnargName is already right + SetAttName = AttNameValue; + } + else + { + // "FOO on BAR" => "FOO" + SpawnargName = SpawnargName.Left( PosSpace ); + // "FOO on BAR" => "BAR" + SetAttName = SetAttName.Right( SetAttName.Length() - (PosSpace + 4) ); + } + + // gameLocal.Printf("SetAttName '%s'\n", SetAttName.c_str()); + // gameLocal.Printf("AttNameValue '%s'\n", AttNameValue.c_str()); + // gameLocal.Printf("SpawnargName '%s'\n", SpawnargName.c_str()); + + // does this spawnarg apply to the newly spawned entity? + if (SetAttName == AttNameValue) + { + // it matches, so this spawnarg must be applied directly to this entity + //gameLocal.Printf("Match: Setting '%s' to '%s'\n", SpawnargName.c_str(), SpawnargValue.c_str() ); + args.Set( SpawnargName, SpawnargValue ); + } + else + { + // pass along the original "set ..." spawnarg, it might apply to an + // def_attached entity of the newly spawned one + //gameLocal.Printf("No match: Passing along '%s' ('%s')\n", kv_set->GetKey().c_str(), SpawnargValue.c_str() ); + args.Set( kv_set->GetKey(), SpawnargValue ); + } + + kv_set = from->MatchPrefix( "set ", kv_set ); + // end while ( kv_set ) + } + + argsList->Append (args ); + } + + kv = from->MatchPrefix( "def_attach", kv ); + } +} + +/* tels: Parses "def_attach" spawnargs and spawns and attaches all entities + * that are mentioned there. Before each entity is spawned, spawnargs of the + * format "set XYZ on ABC" are parsed and either applied to the newly spawned + * entity, so it can pass them along to its own def_attachments, or converted + * to a real spawnarg and applied to the entity before spawn. */ +void idEntity::ParseAttachments( void ) +{ + idEntity *ent = NULL; // each spawned entity + const idKeyValue *kv = NULL; + idList args; + + ParseAttachmentSpawnargs( &args, &spawnArgs ); + + for (int i = 0; i < args.Num(); i++) + { + gameLocal.SpawnEntityDef( args[i], &ent ); + + if ( ent != NULL) + { + if( args[i].FindKey( "_poskey" )) + { + Attach( ent, spawnArgs.GetString( args[i].GetString( "_poskey" ) ), args[i].GetString( "_attnamevalue") ); + //gameLocal.Printf(" Attaching '%s' at pos '%s'\n", AttNameValue.c_str(), spawnArgs.GetString( args[i].GetString("poskey") ) ); + } + else + { + Attach( ent, NULL, args[i].GetString( "_attnamevalue") ); + //gameLocal.Printf(" Attaching '%s' at pos 'Unknown'\n", AttNameValue.c_str() ); + } + + // grayman #2603 - generate a "target" spawnarg for later processing + // when attaching a relight position. + + if (ent->name.Find("relight_position") >= 0) + { + idStr name = ent->name; // start with full name + int index = name.Last('_'); // find '_nnn' entity number at the end + idStr suffix = name.Right(name.Length() - index); // suffix = '_nnn' + idStr rpString = "relight_position" + suffix; // add suffix to "relight_position" + spawnArgs.Set(rpString,name); // add new spawnarg "relight_position_nnn" "" + } + } + else + { + gameLocal.Error( "Couldn't spawn '%s' to attach to entity '%s'", args[i].GetString("name"), name.c_str() ); + } + } + + // after we have spawned all our attachments, we can parse the "add_link" spawnargs: + kv = spawnArgs.MatchPrefix( "add_link", NULL ); + while ( kv ) + { + // get the "source to target" value + idStr Link = kv->GetValue(); + + // "SOURCE to TARGET" + // find position of first " to " + int PosSpace = Link.Find( ' ', 0, -1); + if (PosSpace == -1) + { + gameLocal.Warning( "Invalid spawnarg add_link '%s' on entity '%s'", + kv->GetValue().c_str(), name.c_str() ); + kv = spawnArgs.MatchPrefix( "add_link", kv ); + continue; + } + + // "SOURCE to TARGET" => "SOURCE" + idStr Source = Link.Left( PosSpace ); + // "SOURCE to TARGET" => "TARGET" + idStr Target = Link.Right( Link.Length() - (PosSpace + 4) ); + + // gameLocal.Printf("Match: add_link '%s' to '%s'\n", Source.c_str(), Target.c_str() ); + + // If the source contains ":attached:name", split it into the base entity + // and the attachment name: + idEntity *source_ent = this; + PosSpace = Source.Find( ":attached:", 0, -1); + if (PosSpace != -1) + { + // "test:attached:flame" => "test" + // ":attached:flame" => "" + idStr Source_Entity = Source.Left( PosSpace ); + // "test:attached:flame" => "flame" + idStr Source_Att = Source.Right( Source.Length() - (PosSpace + 10) ); + + if (Source_Entity.Length() > 0) + { + // "Name:attached:flame" => entity name, so use "Name" + gameLocal.Printf(" Link source: '%s'\n", Source_Entity.c_str() ); + + Source = Source_Entity; + source_ent = gameLocal.FindEntity( Source ); + if (!source_ent) + { + gameLocal.Warning( "Cannot find entity '%s'.", Source.c_str() ); + } + } + // else: ":attached:flame" => no entity name, so use ourself + + // now find the attached entity + source_ent = source_ent->GetAttachmentFromTeam( Source_Att.c_str() ); + if (!source_ent) + { + gameLocal.Warning( "Cannot find source attachment '%s' on entity '%s'.", + Source_Att.c_str(), Source.c_str() ); + } + else + { + //gameLocal.Printf(" Link source entity (GetAttachmentFromTeam): '%s'\n", source_ent->name.c_str() ); + } + } + else + { + // source is just an entity name + source_ent = gameLocal.FindEntity( Source ); + //if (source_ent) + // gameLocal.Printf(" Link source entity (Entity): '%s'\n", source_ent->name.c_str() ); + } + + // If the target contains ":attached:name", split it into the base entity + // and the attachment name: + idEntity *target_ent = this; + PosSpace = Target.Find( ":attached:", 0, -1); + if (PosSpace != -1) + { + // "test:attached:flame" => "test" + idStr Target_Entity = Target.Left( PosSpace ); + // "test:attached:flame" => "flame" + idStr Target_Att = Target.Right( Target.Length() - (PosSpace + 10) ); + + if (Target_Entity.Length() > 0) + { + // "Name:attached:flame" => entity name, so use "Name" + gameLocal.Printf(" Link target: '%s'\n", Target_Entity.c_str() ); + + Target = Target_Entity; + target_ent = gameLocal.FindEntity( Target ); + if (!target_ent) + { + gameLocal.Warning( "Cannot find entity '%s'.", Target.c_str() ); + } + } + // else: ":attached:flame" => no entity name, so use ourself + + // now find the attached entity by the attachment pos name: + idEntity *target_ent_att = target_ent->GetAttachmentFromTeam( Target_Att.c_str() ); + if (!target_ent_att) + { + gameLocal.Warning( "Cannot find target attachment '%s' on entity '%s'.", + Target_Att.c_str(), target_ent->name.c_str() ); + } + else + { + //gameLocal.Printf(" Link target entity (GetAttachmentFromTeam): '%s'\n", target_ent->name.c_str() ); + } + target_ent = target_ent_att; + } + else + { + // target is just an entity name + target_ent = gameLocal.FindEntity( Target ); + //if (target_ent) + // gameLocal.Printf(" Link target entity (Entity): '%s'\n", target_ent->name.c_str() ); + } + + // now that we have entities for source and target, add the link + if ( source_ent && target_ent ) + { + //gameLocal.Printf(" add_link from '%s' to '%s'\n", source_ent->name.c_str(), target_ent->name.c_str() ); + source_ent->AddTarget( target_ent ); + } + else + { + // tels: TODO: post an event for later adding + if ( !target_ent ) + gameLocal.Warning( "Cannot find target entity '%s' for add_link.", Target.c_str() ); + if ( !source_ent ) + gameLocal.Warning( "Cannot find source entity '%s' for add_link.", Source.c_str() ); + } + + // do we have another one? + kv = spawnArgs.MatchPrefix( "add_link", kv ); + } +} + +/* +================ +idEntity::ParseAttachPositions +================ +*/ +void idEntity::ParseAttachPositions( void ) +{ + SAttachPosition pos; + SAttachPosition *pPos; + idStr prefix, keyname, jointname; + const idKeyValue *kv(NULL); + + m_AttachPositions.Clear(); + + // Read off basic attachment positions + // (intended to be on base class for a skeleton type, e.g., humanoid) + while( ( kv = spawnArgs.MatchPrefix("attach_pos_name_", kv) ) != NULL ) + { + keyname = kv->GetKey(); + keyname.StripLeading("attach_pos_name_"); + + pos.name = kv->GetValue().c_str(); + + // If entity has joints, find the joint handle for the joint name + if( GetAnimator() ) + { + jointname = spawnArgs.GetString( ("attach_pos_joint_" + keyname).c_str() ); + pos.joint = GetAnimator()->GetJointHandle( jointname ); + if ( pos.joint == INVALID_JOINT ) + { + // TODO: Turn this into a warning and attach relative to entity origin instead? + gameLocal.Error( "Joint '%s' not found for attachment position '%s' on entity '%s'", jointname.c_str(), pos.name.c_str(), name.c_str() ); + } + } + else + pos.joint = INVALID_JOINT; + + pos.originOffset = spawnArgs.GetVector( ("attach_pos_origin_" + keyname).c_str() ); + pos.angleOffset = spawnArgs.GetAngles( ("attach_pos_angles_" + keyname).c_str() ); + + m_AttachPositions.Append( pos ); + } + + kv = NULL; + // Read off actor-specific offsets to this position and apply them + while( (kv = spawnArgs.MatchPrefix("attach_posmod_name_", kv)) != NULL ) + { + keyname = kv->GetKey(); + keyname.StripLeading("attach_posmod_name_"); + + // Try to find the position + pPos = GetAttachPosition( kv->GetValue().c_str() ); + // If we find the position by name, apply the offsets + if( pPos != NULL ) + { + idVec3 trans = spawnArgs.GetVector( ("attach_posmod_origin_" + keyname).c_str() ); + idAngles ang = spawnArgs.GetAngles( ("attach_posmod_angles_" + keyname).c_str() ); + + pPos->originOffset += trans; + // TODO: Prove mathematically that adding the angles is the same as converting + // the angles to rotation matrices and multiplying them?? + // stgatilov: It is wrong. As soon as anyone starts using this spawnarg the proper meaning + // of this line should be worked out. + gameLocal.Error( "Using spawn attach_posmod_* with uncertain meaning: report to coders."); + pPos->angleOffset += ang; + } + } +} + +/* +================ +idEntity::GetAttachPosition +================ +*/ +SAttachPosition *idEntity::GetAttachPosition( const char *AttachName ) +{ + idStr AttName = AttachName; + SAttachPosition *returnVal = NULL; + +// TODO: Probably not worth doing a hash for this short list, linear search OK? + for( int i=0; i < m_AttachPositions.Num(); i++ ) + { + if( AttName == m_AttachPositions[i].name ) + { + returnVal = &m_AttachPositions[i]; + break; + } + } + + return returnVal; +} + +void idEntity::SaveAttachmentContents() +{ + for (int i = 0; i < m_Attachments.Num(); ++i) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL) continue; + + m_Attachments[i].savedContents = (ent != NULL) ? ent->GetPhysics()->GetContents() : -1; + } +} + +// Sets all attachment contents to the given value +void idEntity::SetAttachmentContents(int newContents) +{ + for (int i = 0; i < m_Attachments.Num(); ++i) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL) continue; + + ent->GetPhysics()->SetContents(newContents); + } +} + +// Restores all CONTENTS values, previously saved with SaveAttachmentContents() +void idEntity::RestoreAttachmentContents() +{ + for (int i = 0; i < m_Attachments.Num(); ++i) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL) continue; + + int savedContents = m_Attachments[i].savedContents; + + if (savedContents != -1) + { + ent->GetPhysics()->SetContents(savedContents); + } + } +} + +/* +===================== +SAttachPosition::Save +===================== +*/ +void SAttachPosition::Save( idSaveGame *savefile ) const +{ + savefile->WriteString( name ); + savefile->WriteInt( (int) joint ); + savefile->WriteAngles( angleOffset ); + savefile->WriteVec3( originOffset ); +} + +/* +===================== +SAttachPosition::Restore +===================== +*/ +void SAttachPosition::Restore( idRestoreGame *savefile ) +{ + int jointInt; + savefile->ReadString( name ); + savefile->ReadInt( jointInt ); + joint = (jointHandle_t) jointInt; + savefile->ReadAngles( angleOffset ); + savefile->ReadVec3( originOffset ); +} + +void idEntity::Event_SetContents(const int contents) +{ + GetPhysics()->SetContents(contents); +} + +void idEntity::Event_GetContents() +{ + idThread::ReturnInt(GetPhysics()->GetContents()); +} + +void idEntity::Event_SetClipMask(const int clipMask) +{ + GetPhysics()->SetClipMask(clipMask); +} + +void idEntity::Event_GetClipMask() +{ + idThread::ReturnInt(GetPhysics()->GetClipMask()); +} + +void idEntity::Event_ExtinguishLights() +{ + // greebo: First, check if we ourselves are a light + if (IsType(idLight::Type)) + { + // Call the script function to extinguish this light + CallScriptFunctionArgs("frob_extinguish", true, 0, "e", this); + } + + // Now go through the teamChain and check for lights + for (idEntity* ent = teamChain; ent != NULL; ent = ent->teamChain) + { + if (ent->IsType(idLight::Type)) + { + ent->CallScriptFunctionArgs("frob_extinguish", true, 0, "e", ent); + } + } +} + +void idEntity::Event_GetResponseEntity() +{ + idThread::ReturnEntity(GetResponseEntity()); +} + +void idEntity::Event_GetTeam() +{ + idThread::ReturnInt(team); +} + +void idEntity::Event_SetTeam(int newTeam) +{ + gameLocal.Printf("%s: Changing to team %i.\n", GetName(), newTeam); + // greebo: No validity checking so far - todo? + team = newTeam; +} + +void idEntity::SetEntityRelation(idEntity* entity, int relation) +{ + m_EntityRelations[entity] = relation; +} + + // angua: this changes the current relation to an actor by adding the new amount +void idEntity::ChangeEntityRelation(idEntity* entity, int relationChange) +{ + assert(entity); + if (entity == NULL) + { + return; + } + + EntityRelationsMap::iterator found = m_EntityRelations.find(entity); + + if (found == m_EntityRelations.end()) + { + // Sanity-check, some entities like worldspawn have team == -1 + if (entity->team == -1) return; + + // not yet set, load default from relations manager + int defaultrel = gameLocal.m_RelationsManager->GetRelNum(team, entity->team); + + std::pair result = m_EntityRelations.insert( + EntityRelationsMap::value_type(entity, defaultrel) + ); + + // set iterator to newly inserted element + found = result.first; + } + + found->second += relationChange; +} + +bool idEntity::IsFriend(const idEntity *other) +{ + if (other == NULL) + { + return false; + } + else if (other->team == -1) + { + // entities with team -1 (not set) are neutral + return false; + } + else + { + // angua: look up entity specific relation + EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); + if (found != m_EntityRelations.end()) + { + return (found->second > 0); + } + + // angua: no specific relation found, fall back to standard team relations + return gameLocal.m_RelationsManager->IsFriend(team, other->team); + } +} + +bool idEntity::IsNeutral(const idEntity *other) +{ + if (other == NULL) + { + return false; + } + else if (other->team == -1) + { + // entities with team -1 (not set) are neutral + return true; + } + else + { + // angua: look up entity specific relation + EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); + if (found != m_EntityRelations.end()) + { + return (found->second == 0); + } + + // angua: no specific relation found, fall back to standard team relations + return gameLocal.m_RelationsManager->IsNeutral(team, other->team); + } +} + +bool idEntity::IsEnemy(const idEntity *other ) +{ + if (other == NULL) + { + // The NULL pointer is not your enemy! As long as you remember to check for it to avoid crashes. + return false; + } + else if (other->team == -1) + { + // entities with team -1 (not set) are neutral + return false; + } + else if (other->fl.notarget) + { + return false; + } + else + { + // angua: look up entity specific relation + EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); + if (found != m_EntityRelations.end()) + { + return (found->second < 0); + } + + // angua: no specific relation found, fall back to standard team relations + return gameLocal.m_RelationsManager->IsEnemy(team, other->team); + } +} + +void idEntity::Event_IsEnemy( idEntity *ent ) +{ + idThread::ReturnInt(static_cast(IsEnemy(ent))); +} + +void idEntity::Event_IsFriend( idEntity *ent ) +{ + idThread::ReturnInt(IsFriend(ent)); +} + +void idEntity::Event_IsNeutral( idEntity *ent ) +{ + idThread::ReturnInt(IsNeutral(ent)); +} + + +void idEntity::Event_SetEntityRelation(idEntity* entity, int relation) +{ + SetEntityRelation(entity,relation); +} + +void idEntity::Event_ChangeEntityRelation(idEntity* entity, int relationChange) +{ + ChangeEntityRelation(entity, relationChange); +} + +// grayman #2905 + +void idEntity::Event_IsLight() +{ + idThread::ReturnInt(static_cast(IsType(idLight::Type))); +} + diff --git a/game/Entity.h b/game/Entity.h new file mode 100644 index 000000000..28ef64f66 --- /dev/null +++ b/game/Entity.h @@ -0,0 +1,1833 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_ENTITY_H__ +#define __GAME_ENTITY_H__ + +#include "StimResponse/StimType.h" +#include "OverlaySys.h" +#include "UserManager.h" +#include "ModelGenerator.h" + +class CStimResponseCollection; +class CStim; +typedef boost::shared_ptr CStimPtr; +class CResponse; +typedef boost::shared_ptr CResponsePtr; +class CAbsenceMarker; +class CObjectiveLocation; + +class CInventory; +typedef boost::shared_ptr CInventoryPtr; +class CInventoryItem; +typedef boost::shared_ptr CInventoryItemPtr; +class CInventoryCursor; +typedef boost::shared_ptr CInventoryCursorPtr; + +/** +* This struct defines one entity with an optional offset, count and +* probability, to spawn it upon the death of another entity. +*/ +struct FlinderSpawn { + idStr m_Entity; //!< class of the entity to spawn + idVec3 m_Offset; //!< optional offset + int m_Count; //!< count (default: 1) + float m_Probability; //!< probability (0 .. 1.0) that this entity spawns +}; + +/* +=============================================================================== + + Game entity base class. + +=============================================================================== +*/ + +static const int DELAY_DORMANT_TIME = 3000; +/** +* greebo: This is the value that has to be exceeded by the lightingQuotient +* returned by the LAS routines (range 0.0 ... 1.0). +* 0.0 means no threshold - target entities are always visible +* This is used by the idEntity::canSeeEntity() member method. +*/ +static const float VISIBILTIY_LIGHTING_THRESHOLD = 0.2f; + +extern const idEventDef EV_PostSpawn; +extern const idEventDef EV_FindTargets; +extern const idEventDef EV_RemoveTarget; +extern const idEventDef EV_AddTarget; +extern const idEventDef EV_Touch; +extern const idEventDef EV_Use; +extern const idEventDef EV_Activate; +extern const idEventDef EV_ActivateTargets; +extern const idEventDef EV_Hide; +extern const idEventDef EV_Show; +extern const idEventDef EV_GetShaderParm; +extern const idEventDef EV_SetShaderParm; +extern const idEventDef EV_SetOwner; +extern const idEventDef EV_GetAngles; +extern const idEventDef EV_SetAngles; +extern const idEventDef EV_SetLinearVelocity; +extern const idEventDef EV_SetAngularVelocity; +extern const idEventDef EV_SetSkin; +extern const idEventDef EV_StartSoundShader; +extern const idEventDef EV_StopSound; +extern const idEventDef EV_CacheSoundShader; +extern const idEventDef EV_ExtinguishLights; +extern const idEventDef EV_TeleportTo; +extern const idEventDef EV_IsDroppable; +extern const idEventDef EV_SetDroppable; + +extern const idEventDef EV_IsType; + +#ifdef MOD_WATERPHYSICS + +extern const idEventDef EV_GetMass; // MOD_WATERPHYSICS + +extern const idEventDef EV_IsInLiquid; // MOD_WATERPHYSICS + +#endif // MOD_WATERPHYSICS + +extern const idEventDef EV_CopyBind; +extern const idEventDef EV_IsFrobable; +extern const idEventDef EV_SetFrobable; +extern const idEventDef EV_FrobHilight; +extern const idEventDef EV_InPVS; +extern const idEventDef EV_CanSeeEntity; +extern const idEventDef EV_CanBeUsedBy; + +// greebo: Script event definition for dealing damage +extern const idEventDef EV_Damage; +extern const idEventDef EV_Heal; + +extern const idEventDef EV_ResponseAllow; + +extern const idEventDef EV_DestroyOverlay; + +// Think flags +enum { + TH_ALL = -1, + TH_THINK = 1, // run think function each frame + TH_PHYSICS = 2, // run physics each frame + TH_ANIMATE = 4, // update animation each frame + TH_UPDATEVISUALS = 8, // update renderEntity + TH_UPDATEPARTICLES = 16, + TH_DOUSING = 32, // grayman #2603 - run think function to process latched dousing + TH_ARMED = 64 // grayman #2478 - run think function when mine is armed +}; + +// The impulse states a button can have +enum EImpulseState { + EPressed, // just pressed + ERepeat, // held down + EReleased, // just released + ENumImpulseStates, +}; + +// +// Signals +// make sure to change script/doom_defs.script if you add any, or change their order +// +typedef enum { + SIG_TOUCH, // object was touched + SIG_USE, // object was used + SIG_TRIGGER, // object was activated + SIG_REMOVED, // object was removed from the game + SIG_DAMAGE, // object was damaged + SIG_BLOCKED, // object was blocked + + SIG_MOVER_POS1, // mover at position 1 (door closed) + SIG_MOVER_POS2, // mover at position 2 (door open) + SIG_MOVER_1TO2, // mover changing from position 1 to 2 + SIG_MOVER_2TO1, // mover changing from position 2 to 1 + + NUM_SIGNALS +} signalNum_t; + +// FIXME: At some point we may want to just limit it to one thread per signal, but +// for now, I'm allowing multiple threads. We should reevaluate this later in the project +#define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16 + +struct signal_t { + int threadnum; + const function_t *function; +}; + +class signalList_t { +public: + idList signal[ NUM_SIGNALS ]; +}; + +// Inventory-related flags. +enum { + EINV_GROUP = 1, // Jump to the next/previous group. + EINV_PREV = 2, // Iterate backwards. + EINV_FAST = 4, // Don't use group histories. +}; + +/** +* Attachment system info +**/ +class CAttachInfo +{ +public: + CAttachInfo() : + channel(0), + savedContents(-1) + {} + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + idEntityPtr ent; + // Anim channel this attachment is on (if on an animated entity) + int channel; + // unique name by which the entity refers to this attachment + idStr name; + + // An additional int to save contents (used to set attachments nonsolid temporarily) + int savedContents; + + // grayman #2603 - save the position name to help find out what's in an AI's hands later + idStr posName; +}; + +/** +* Info structure for attaching things to named positions +**/ +typedef struct SAttachPosition_s +{ + idStr name; //!< name of this position + jointHandle_t joint; //!< joint it is relative to + idAngles angleOffset; //!< rotational offset relative to joint orientation + idVec3 originOffset; //!< origin offset relative to joint origin + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); +} SAttachPosition; + + +class idEntity : public idClass { +public: + static const int MAX_PVS_AREAS = 4; + + int entityNumber; // index into the entity list + int entityDefNumber; // index into the entity def list + + idLinkList spawnNode; // for being linked into spawnedEntities list + idLinkList activeNode; // for being linked into activeEntities list + + idLinkList snapshotNode; // for being linked into snapshotEntities list + int snapshotSequence; // last snapshot this entity was in + int snapshotBits; // number of bits this entity occupied in the last snapshot + + idStr name; // name of entity + idDict spawnArgs; // key/value pairs used to spawn and initialize entity + idScriptObject scriptObject; // contains all script defined data for this entity + + int thinkFlags; // TH_? flags + int dormantStart; // time that the entity was first closed off from player + bool cinematic; // during cinematics, entity will only think if cinematic is set + + renderView_t * renderView; // for camera views from this entity + idEntity * cameraTarget; // any remoteRenderMap shaders will use this + + idList< idEntityPtr > targets; // when this entity is activated these entities entity are activated + + int health; // FIXME: do all objects really need health? + int maxHealth; // greebo: Moved this from idInventory to here + + struct entityFlags_s { + bool notarget :1; // if true never attack or target this entity + bool noknockback :1; // if true no knockback from hits + bool takedamage :1; // if true this entity can be damaged + bool hidden :1; // if true this entity is not visible + bool bindOrientated :1; // if true both the master orientation is used for binding + bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities + bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not + bool selected :1; // if true the entity is selected for editing + bool neverDormant :1; // if true the entity never goes dormant + bool isDormant :1; // if true the entity is dormant + bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected + bool networkSync :1; // if true the entity is synchronized over the network + } fl; + + /** + * When an entity is hidden, these store the following information just before the hide: + * These store the clipmodel contents, clipmask and whether the clipmodel was enabled + * These variables are reset to this data when the entity is un-hidden + **/ + int m_preHideContents; + int m_preHideClipMask; + + /** + * Entity contents may be overwritten by a custom contents spawnarg + * Store it here to keep track of it, because derived classes can + * set the contents in their spawn method, and need to know to overwrite it + **/ + int m_CustomContents; + + /** + * UsedBy ist the list of entity names that this entity can be used by. + * i.e. A door can have a list of keys that can unlock it. A fountain can + * be used by a water arrow to make it holy, etc. + * The list is initialized by the key "used"_by" in the entity and contains + * the names of the entities seperated by ';'. If the first character of + * the name is a '*' the name donates a classname instead of an entity. In + * this case all entities of that class can be used by this entity. + * Example: If you have several holy fountains you would have to list all + * fountain names. Alternatively you can create a "holy_fountain" class and + * list it like this: + * "used_by" "*holy_fountain;*holy_bottle;holy_cross" + * In this example the entity can be used by any holy_fountain, any holy_bottle + * and addtionaly by the entity named holy_cross. + */ + idList m_UsedByName; + /** + * Same, but checks against inv_names + **/ + idList m_UsedByInvName; + /** + * Same, but checks against inv_categories + **/ + idList m_UsedByCategory; + /** + * Same, but checks against the entityDef name (e.g. atdm:playertools_lockpick*) + * This may be redundant sometimes, because classnames are often a part of the + * entity name. But not always, mappers can rename entities whatever they want + **/ + idList m_UsedByClassname; + + /** + * Set to true if objective locations should update the objectives system when + * this entity the objective area. + * May also determine inventory callbacks to objective system. + **/ + bool m_bIsObjective; + + /** + * greebo: The list of objective locations whose bounds this entity is currently within. + * This is needed to raise a safe mission event when this entity is destroyed, otherwise + * the objective location entity is unable to catch entity destructions. + */ + idList > m_objLocations; + + /** + * Set to true if the entity is frobable. May be dynamically changed. + **/ + bool m_bFrobable; + + /** + * Set to true if the entity is a "simple" frobable like a door, lever, button + * These items can still be frobbed while doing things like shouldering bodies + **/ + bool m_bFrobSimple; + + /** + * Frobdistance determines the distance in renderunits. If set to 0 + * the entity is not frobable. + **/ + int m_FrobDistance; + + /** + * Frob bias: Multiplies the angle deviation cosine test in idPlayer::FrobCheck + * Effectively biases the frob selection toward this object. Used for small objects + * to make them easier to frob when placed next to large objects. + **/ + float m_FrobBias; + + /** + * Controls whether this entity, when attached to an AI, will become solid when the AI + * is alerted and nonsolid when the AI is not alerted. + * Often applied in conjunction with attach_set_nonsolid spawnarg + **/ + bool m_bAttachedAlertControlsSolidity; + + /** + * Set to true if this entity is a climbable rope. This could be set on either + * static ropes or AF entities, so it makes sense to let all entities have this var + **/ + bool m_bIsClimbableRope; + + /** + * TDM: The default playback rate of each animation, indexed by the animation's + * index number. Only used by idActor; but the animation classes deal with idEntity + * directly, and it's more efficient to declare this on all entities than to do + * RTTI on every animation frame. + **/ + idList m_animRates; + + /** + * Actor who set this item in motion. Cleared when it comes to rest. + * Always NULL for non-physical items. + **/ + idEntityPtr m_SetInMotionByActor; + /** + * Actor who last moved this item. Never cleared. + * Always NULL for non-physical items. + **/ + idEntityPtr m_MovedByActor; + + // The light quotient for this entity, calculated by the LAS + float m_LightQuotient; + // The last time the above value has been calculated + int m_LightQuotientLastEvalTime; + + bool m_droppedByAI; // grayman #1330 + + /** + * Tels: Contains handle to (sharable, constant) LOD data if != 0. + */ + lod_handle m_LODHandle; + + /** + * Tels: Info for LOD, per entity. used if m_LODHandle != 0: + * Timestamp for next LOD think. If negative, LOD thinking is + * temp. disabled. + **/ + int m_DistCheckTimeStamp; + + /** + * Current LOD (0 - normal, 1,2,3,4,5 LOD, 6 hidden) + **/ + int m_LODLevel; + + /* Store the current model and skin to avoid flicker by not + * switching from one model/skin to the same model/skin when + * changing the LOD. + */ + int m_ModelLODCur; + int m_SkinLODCur; + + /* grayman #597 - hide until this timer expires. For + * hiding arrows when they're first nocked. + */ + int m_HideUntilTime; + + /* grayman #2787 - planting data needed for vines (vinearrow) + */ + idVec3 m_VinePlantLoc; + idVec3 m_VinePlantNormal; + +public: + ABSTRACT_PROTOTYPE( idEntity ); + + idEntity(); + virtual ~idEntity(); + + void Spawn( void ); + + /** + * Load and check the visual and collision model, as well as any model for + * the broken state. + */ + virtual void LoadModels( void ); + + /** + * Parse the LOD spawnargs and returns 0 if the entity has no LOD (or hide_distance), + * otherwise returns a handle registered with ModelGenerator::RegisterLODData(); + */ + lod_handle ParseLODSpawnargs( const idDict* dict, const float fRandom); + + /** + * Tels: Stop LOD changes permanently. If doTeam is true, also disables it on teammembers. + */ + void StopLOD( const bool doTeam); + + /** + * Tels: Stop LOD changes temporarily. If doTeam is true, also disables it on teammembers. + */ + void DisableLOD( const bool doTeam ); + void EnableLOD( const bool doTeam ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * greebo: This method is called before the savegame is writing its "object list" to the file, + * to give this entity an opportunity to register its subobjects (like the PickableLock class + * which is a non-spawned object of the BinaryFrobMover class). + */ + virtual void AddObjectsToSaveGame(idSaveGame* savefile); + + const char * GetEntityDefName( void ) const; + void SetName( const char *name ); + const char * GetName( void ) const; + + virtual void UpdateChangeableSpawnArgs( const idDict *source ); + + // clients generate views based on all the player specific options, + // cameras have custom code, and everything else just uses the axis orientation + virtual renderView_t * GetRenderView(); + + // greebo: Call this to trigger this entity + virtual void Activate(idEntity* activator); + + // thinking + virtual void Think( void ); + + // Tels: If LOD is enabled on this entity, compute new LOD level and new alpha value. + // We pass in a pointer to the data (so the LODE can use shared data) as well as the distance, + // so the lode can pre-compute the distance. + virtual float ThinkAboutLOD( const lod_data_t* lod_data, const float deltaSq ); + + // Tels: Returns the distance that should be considered for LOD and hiding, depending on: + // * the distance of the origin to the given player origin + // * the lod-bias set in the menu + // * some minimum and maximum distances based on entity size/importance + // The returned value is the actual distance squared, and rounded down to an integer. + float GetLODDistance( const lod_data_t *m_LOD, const idVec3 &playerOrigin, const idVec3 &entOrigin, const idVec3 &entSize, const float lod_bias ) const; + + // Tels: If LOD is enabled on this entity, call ThinkAboutLOD, computing new LOD level and new + // alpha value, then do the right things like Hide/Show, SetAlpha, switch models/skin etc. + // We pass in a pointer to the data (so the LODE can use shared data) as well as the distance, + // so the lode can pre-compute the distance. + virtual bool SwitchLOD( const lod_data_t *m_LOD, const float deltaSq ); + + bool CheckDormant( void ); //!< dormant == on the active list, but out of PVS + virtual void DormantBegin( void ); //!< called when entity becomes dormant + virtual void DormantEnd( void ); //!< called when entity wakes from being dormant + bool IsActive( void ) const; + void BecomeActive( int flags ); + void BecomeInactive( int flags ); + void BecomeBroken( idEntity *activator ); //!< Entity breaks up + void UpdatePVSAreas( const idVec3 &pos ); + + // visuals + virtual void Present( void ); + virtual renderEntity_t *GetRenderEntity( void ); + virtual int GetModelDefHandle( void ); + virtual void SetModel( const char *modelname ); + void SetSkin( const idDeclSkin *skin ); + const idDeclSkin * GetSkin( void ) const; + void SetShaderParm( int parmnum, float value ); + virtual void SetColor( const float red, const float green, const float blue ); + virtual void SetColor( const idVec3 &color ); + virtual void GetColor( idVec3 &out ) const; + virtual void SetColor( const idVec4 &color ); + virtual void GetColor( idVec4 &out ) const; + virtual void FreeModelDef( void ); + virtual void FreeLightDef( void ); + virtual void Hide( void ); + virtual void Show( void ); + bool IsHidden( void ) const; + + /** + * Tels: Only set the alpha channel to fade in/out + */ + virtual void SetAlpha( const float alpha ); + /** + * Tels: Same as SetAlpha(); but set bound children, too, if doTeam is true + */ + virtual void SetAlpha( const float alpha, const bool doTeam ); + + /** + * greebo: Returns the light quotient for this entity, a value determined by the + * number of lights hitting this entity's bounding box, determined by the LAS. + * + * AI are using this method to determine an object's visibility. The result + * is cached, to save it from being recalculated for multiple AI each frame. + */ + float GetLightQuotient(); + + // TDM: SZ: January 9, 2006 Made virtual to handle unique behavior in descendents + virtual void UpdateVisuals( void ); + + void UpdateModel( void ); + void UpdateModelTransform( void ); + virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); + int GetNumPVSAreas( void ); + const int * GetPVSAreas( void ); + void ClearPVSAreas( void ); + bool PhysicsTeamInPVS( pvsHandle_t pvsHandle ); + + // animation + virtual bool UpdateAnimationControllers( void ); + bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); + static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); + virtual idAnimator * GetAnimator( void ); // returns animator object used by this entity + + // sound + virtual bool CanPlayChatterSounds( void ) const; + + // angua: propVolMod only modifies the volume of the propagated sound + bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length, float propVolMod = 0); + bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length); + void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds + void SetSoundVolume( float volume ); + void UpdateSound( void ); + int GetListenerId( void ) const; + idSoundEmitter * GetSoundEmitter( void ) const; + void FreeSoundEmitter( bool immediate ); + + // entity binding + virtual void PreBind( void ); + virtual void PostBind( void ); + virtual void PreUnbind( void ); + virtual void PostUnbind( void ); + void JoinTeam( idEntity *teammember ); + + /** + * greebo: Returns the first team entity matching the given type. If the second + * argument is specified, it returns the next entity after that one. + * + * @returns: NULL if nothing found, the entity pointer otherwise. The entity pointer can be + * safely static_cast<> onto the given type, as the type check has already been performed in this function. + */ + idEntity* FindMatchingTeamEntity(const idTypeInfo& type, idEntity* lastMatch = NULL); + + void Bind( idEntity *master, bool orientated ); + void BindToJoint( idEntity *master, const char *jointname, bool orientated ); + void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated ); + void BindToBody( idEntity *master, int bodyId, bool orientated ); + void Unbind( void ); + bool IsBound( void ) const; + bool IsBroken( void ) const; //!< return true if model was broken + bool IsBoundTo( idEntity *master ) const; + idEntity * GetBindMaster( void ) const; + jointHandle_t GetBindJoint( void ) const; + int GetBindBody( void ) const; + idEntity * GetTeamMaster( void ) const; + idEntity * GetNextTeamEntity( void ) const; + /** + * TDM: Get a list of bound team members lower down on the chain than this one + * Populates the list in the argument argument with entity pointers + **/ + void GetTeamChildren( idList *list ); + void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis ); + idVec3 GetLocalVector( const idVec3 &vec ) const; + idVec3 GetLocalCoordinates( const idVec3 &vec ) const; + idVec3 GetWorldVector( const idVec3 &vec ) const; + idVec3 GetWorldCoordinates( const idVec3 &vec ) const; + bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const; + void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const; + int GetModelDefHandle(void) const { return modelDefHandle; }; + // physics + // set a new physics object to be used by this entity + void SetPhysics( idPhysics *phys ); + // get the physics object used by this entity + idPhysics * GetPhysics( void ) const; + // restore physics pointer for save games + void RestorePhysics( idPhysics *phys ); + // run the physics for this entity + bool RunPhysics( void ); + // set the origin of the physics object (relative to bindMaster if not NULL) + void SetOrigin( const idVec3 &org ); + // set the axis of the physics object (relative to bindMaster if not NULL) + void SetAxis( const idMat3 &axis ); + // use angles to set the axis of the physics object (relative to bindMaster if not NULL) + void SetAngles( const idAngles &ang ); + // get the floor position underneath the physics object + bool GetFloorPos( float max_dist, idVec3 &floorpos ) const; + // retrieves the transformation going from the physics origin/axis to the visual origin/axis + virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); + // retrieves the transformation going from the physics origin/axis to the sound origin/axis + virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); + // called from the physics object when colliding, should return true if the physics simulation should stop + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + /** + * TDM: Process collision stims when collisions occur + * Body is the AF body that was struck (defaults to -1) + **/ + virtual void ProcCollisionStims( idEntity *other, int body = -1 ); + // retrieves impact information, 'ent' is the entity retrieving the info + virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); + // apply an impulse to the physics object, 'ent' is the entity applying the impulse + virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + // add a force to the physics object, 'ent' is the entity adding the force + virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); + // activate the physics object, 'ent' is the entity activating this entity (and ignored in the code in entity.cpp...) + virtual void ActivatePhysics( idEntity *ent ); + // returns true if the physics object is at rest + virtual bool IsAtRest( void ) const; + // returns the time the physics object came to rest + virtual int GetRestStartTime( void ) const; + // add a contact entity + virtual void AddContactEntity( idEntity *ent ); + // remove a touching entity + virtual void RemoveContactEntity( idEntity *ent ); + + // damage + // returns true if this entity can be damaged from the given origin + virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const; + // applies damage to this entity + virtual void Damage( idEntity *inflictor, idEntity *attacker, + const idVec3 &dir, const char *damageDefName, + const float damageScale, const int location, trace_t *tr = NULL ); + // greebo: Heals this entity using the information found in the entitDef named healDefName + // returns 1 if the entity was healed, or 0 if the entity was already at full health + virtual int heal(const char* healDefName, float healScale); + // adds a damage effect like overlays, blood, sparks, debris etc. + virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); + // callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. + virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); + // notifies this entity that it is in pain + virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + // notifies this entity that is has been killed + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + + // scripting + virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; + virtual idThread * ConstructScriptObject( void ); + virtual void DeconstructScriptObject( void ); + void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function ); + void ClearSignal( idThread *thread, signalNum_t signalnum ); + void ClearSignalThread( signalNum_t signalnum, idThread *thread ); + bool HasSignal( signalNum_t signalnum ) const; + void Signal( signalNum_t signalnum ); + void SignalEvent( idThread *thread, signalNum_t signalnum ); + + // gui + void TriggerGuis( void ); + bool HandleGuiCommands( idEntity *entityGui, const char *cmds ); + virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ); + + // targets + void FindTargets( void ); + void RemoveNullTargets( void ); + void ActivateTargets( idEntity *activator ) const; + // greebo: Removes the given target ent from this entity's targets. + virtual void RemoveTarget(idEntity* target); + virtual void AddTarget(idEntity* target); + + // grayman #2603 - relight positions + void FindRelights(void); + + // misc + virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); + bool TouchTriggers( void ) const; + idCurve_Spline *GetSpline( void ) const; + virtual void ShowEditingDialog( void ); + + void SetHideUntilTime(int time); // grayman #597 + int GetHideUntilTime(void); // grayman #597 + + idEntity* GetAttachmentByPosition(idStr AttPos); // grayman #2603 + + enum { + EVENT_STARTSOUNDSHADER, + EVENT_STOPSOUNDSHADER, + EVENT_MAXEVENTS + }; + + virtual void ClientPredictionThink( void ); + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + void WriteBindToSnapshot( idBitMsgDelta &msg ) const; + void ReadBindFromSnapshot( const idBitMsgDelta &msg ); + void WriteColorToSnapshot( idBitMsgDelta &msg ) const; + void ReadColorFromSnapshot( const idBitMsgDelta &msg ); + void WriteGUIToSnapshot( idBitMsgDelta &msg ) const; + void ReadGUIFromSnapshot( const idBitMsgDelta &msg ); + + void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const; + void ClientSendEvent( int eventId, const idBitMsg *msg ) const; + + // ---===<* Darkmod functions *>===--- + + /** + * LoadTDMSettings will initialize the settings required for + * darkmod to operate. It should be called from idEntity::Spawn(), + * which will be valid for all entities. If a class needs + * to load additional settings, which are only of interest to this + * particular class it should override this virtual function but + * don't forget to call it for the base class. + */ + virtual void LoadTDMSettings(void); + + /** + * Will evaluate one def_broken flinder and find out how many of this piece + * to spawn, then spawn them. Called from Flinderize(). + * @return: Count of entities that where spawned or -1 for error. + * + */ + virtual int SpawnFlinder(const FlinderSpawn& bs, idEntity *activator); + + /** + * Evaluate def_flinder spawnargs and call SpawnFlinder() for each found. + */ + virtual void Flinderize (idEntity *activator); + + /** + * Parses spawnarg list of attachments and puts them into the list. + **/ + void ParseAttachmentSpawnargs( idList *argsList, idDict *from ); + + /** + * Frobaction will determine what a particular item should do when an entity is highlighted. + * The actual action depends on the type of the entity. + * Loot is being picked up and counted to the loot. + * Special items are transfered to the inventory. If the item is also loot it will count + * to that as well. + * Doors are tested for their state (locked/unlocked) and opened if unlocked. if the + * lockpicks or an appropriate key is equipped the door will either unlock or the + * lockpick HUD should appear. + * Windows are just smaller doors so they don't need special treatment. + * AI is tested for its state. If it is an ally some defined script should start. If + * it is unconscious or dead it is picked up and the player can carry it around. + * If it is a movable item the item is picked up and the player can carry it around. + * Switches are flipped and/or de-/activated and appropriate scripts are triggered. + * + * @frobMaster indicates whether the entity is allowed to call its master or not. + * + * @isFrobPeerAction: this is TRUE if this frob action was propagated from a peer. + */ + virtual void FrobAction(bool frobMaster, bool isFrobPeerAction = false); + + /** + * Function that is called if the player holds down the frob button on this object + * By default, does nothing + **/ + virtual void FrobHeld(bool frobMaster, bool isFrobPeerAction = false, int holdTime = 0) {}; + + /** + * Function that is called if the player holds down the frob button on this object + * By default, does nothing + **/ + virtual void FrobReleased(bool frobMaster, bool isFrobPeerAction = false, int holdTime = 0) {}; + + /** + * greebo: A frobbed entity might receive this signal if the player is hitting + * the attack button in this exact frame. (Used for lockpicking.) + * + * The player responsible for this action is passed as argument. + */ + virtual void AttackAction(idPlayer* player); + + /** + * greebo: Returns TRUE if the given inventory item matches this entity, i.e. + * if the entity can be used by the given inventory item, FALSE otherwise. + * Note: This just routes the call to the overloaded CanBeUsedBy(idEntity*); + * + * @isFrobUse: This is true if the Use action originated from a frob button hit. + */ + virtual bool CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse); + + /** + * greebo: Returns TRUE if the given entity matches this entity, i.e. + * if the entity can be used by the given entity, FALSE otherwise. + * If a frob_master was set, the call is redirected to that one. + * + * @isFrobUse: This is true if the Use action originated from a frob button hit. + * + * The standard entity returns FALSE, this method needs to be overridden + * by the subclasses. + */ + virtual bool CanBeUsedBy(idEntity* entity, const bool isFrobUse); + + /** + * greebo: Uses this entity by the given inventory item. The button state + * is needed to handle the exact user interaction, e.g. while lockpicking. + * If a frob_master was set, the call is redirected to that one. + * + * @returns: TRUE if the item could be used, FALSE otherwise. + */ + virtual bool UseBy(EImpulseState nState, const CInventoryItemPtr& item); + + /** + * Toggle whether the entity has been frobbed. Should ONLY be called by idPlayer::PerformFrobCheck + **/ + virtual void SetFrobbed( bool val ); + + /** + * Set whether this entity is frobable or not + **/ + virtual void SetFrobable( bool val ); + + /** + * Return whether the entity is currently frobbed. + * Should be false at the beginning of the frame + **/ + virtual bool IsFrobbed( void ); + + /** + * DarkMod sound prop functions (called by StartSound and StopSound) + **/ + + /** + * The following two functions propagate either a suspicious or + * an environmental sound. They are called by idEntity::StartSound. + * + * The parameters are the local sound name (ie, the name in the entity + * def file, INCLUDING the "snd_" at the beginning), and the global sound + * name (name in the soundprop def file, NOT including the prefix) + * + * (For now sounds can be suspicious or environmental, but not both. + * defining a sound as suspicious overrides any environmental def + * with the same sound name. ) + **/ + + /** + * Propagate a suspicious sound + **/ + void PropSoundS( const char *localName, const char *globalName, float VolModIn = 0.0f ); + + /** + * Propagate an environmental sound (called by PropSound) + **/ + void PropSoundE( const char *localName, const char *globalName, float VolModIn = 0.0f ); + + /** + * Propagate a sound directly, outside of StartSound + * Direct calling should be done in cases where the gamecode calls + * StartSoundShader directly, without going thru StartSound. + * + * PropSoundDirect first looks for a local definition of the sound + * on the entity, to find volume/duration modifier, extra flags + * and the "global" sound definition (in the sound def file) + * + * If the local definition is not found, it calls sound prop + * with the unmodified global definition. + * + * VolModIn is a modifier in dB added to the volume, in addition to + * any modifier that might be present in the local sound def. + **/ + void PropSoundDirect( const char *sndName, bool bForceLocal = false, + bool bAssumeEnv = false, float VolModIn = 0.0f ); + + CStimResponseCollection *GetStimResponseCollection(void) { return m_StimResponseColl; }; + + /** + * greebo: This allows an entity to "relay" the response to another entity. + * The default implementation of this virtual function returns the pointer, + * but subclasses may return any other entity (but not NULL!). + * + * Example: idAFAttachments return their "body" entity as response entity. + */ + virtual idEntity* GetResponseEntity() { return this; }; + + // Returns (and creates if necessary) this entity's inventory. + const CInventoryPtr& Inventory(); + // Returns (and creates if necessary) this entity's inventory cursor. + const CInventoryCursorPtr& InventoryCursor(); + + /** + * greebo: This is called when an objective location adds this entity + * to its list and starts tracking it. + */ + void OnAddToLocationEntity(CObjectiveLocation* locationEnt); + + /** + * greebo: This is called when an objective location removes this entity + * from its internal list and stops tracking it. + */ + void OnRemoveFromLocationEntity(CObjectiveLocation* locationEnt); + + /** + * greebo: This event gets fired right after spawn time. It checks the spawnargs + * and adds itself to someone else's inventory on demand. If the target entity + * is not found, the event postpones itself by a few hundred msec. + * The optional count argument takes care that this doesn't happen too often. + */ + void Event_InitInventory(int callCount = 0); + + /** + * CreateOverlay will create an overaly for the given entity. This is a hud element + * that displays some objects on the screen. The default is for the playerscreen + * to show the inventory items and other stats. However, each entity can have his own + * hud which allows him to add a custom display for inventory items. + */ + void Event_CreateOverlay( const char *guiFile, int layer ); + int CreateOverlay( const char *guiFile, int layer ); + + /** + * greebo: DestroyOverlay removes the overlay from this entity. Pass the handle + * as argument, it's the returned by CreateOverlay. + */ + void Event_DestroyOverlay(int handle); + void DestroyOverlay(int handle); + + // Returns the GUI with the given handle or NULL if not found + idUserInterface* GetOverlay(int handle); + + /** + * Generic function for calling a scriptfunction with arbitrary arguments. + * The the thread is returned or NULL. + */ + idThread *CallScriptFunctionArgs(const char *ScriptFunction, bool ClearStack, int Delay, const char *Format, ...); + + /** + * Attach another entity to this entity. The base version assumes single-clipmodel + * rigid body physics and simply calls idEntity::Bind. + * Will be overloaded in derived classes with joints to call BindToJoint. + * The position argument is an optional named attachment position + * Attachment name is the string name for future lookups, not actually used by idEntity + * but used in derived classes. + **/ + virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); + + /** + * Detach the attachment of that name. + * Note that to preserve the name->index mapping, the entry for + * the detached object stays in the m_Attachments list, but the entity + * field gets set to NULL so that it's skipped over in various operations + * NOTE: This could lead to memory hogging if something gets detached/attached + * many times. + **/ + virtual void Detach( const char *AttName ); + + /** + * Detach by index in the m_Attachments array. Otherwise same as above + **/ + virtual void DetachInd( int ind ); + + /** + * Reattach an existing attachment to the given offset and angles relative + * to the origin and orientatin of the entity + * + * A different version taking a joint argument exists on idAnimatedEntity + * for things with MD5 structures + **/ + virtual void ReAttachToCoords( const char *AttName, const idVec3 offset, const idAngles angles ); + + /** + * Reattach to a predefined attach position, otherwise same as above + **/ + virtual void ReAttachToPos( const char *AttName, const char *PosName ); + + /** + * Show or hide an attachment, by name or by attachment array index. + **/ + void ShowAttachment( const char *AttName, bool bShow ); + void ShowAttachmentInd( int ind, bool bShow ); + + /** + * Returns an entity pointer for a given attachment name. + * Returns NULL if no such named attachment exists on this entity. + **/ + virtual idEntity *GetAttachment( const char *AttName ); + + /** + * Returns an entity pointer for a given index of the attachment array. + * Returns NULL if no such named attachment exists directly on this entity. + **/ + virtual idEntity *GetAttachment( int ind ); + + /** + * Helper function that looks up the attachment index from the name->index map + * Returns -1 if the index is not present in the map or if it's out of bounds + * of the m_Attachments array. + **/ + virtual int GetAttachmentIndex( const char *AttName ); + + /** + * Returns an entity pointer for a given attachment name. + * Returns NULL if no such named attachment exists on this entity, + * or on any entity attached to this entity. + **/ + virtual idEntity *GetAttachmentFromTeam( const char *AttName ); + + + /** + * Returns a pointer to the attachment info structure for a given attachment. + * Returns NULL if no such named attachment exists on this entity. + **/ + virtual CAttachInfo *GetAttachInfo( const char *AttName ); + + /** + * Returns a pointer to the attachment position with this name. + * Returns NULL if no attachment position exists with this name. + **/ + virtual SAttachPosition *GetAttachPosition( const char *AttachName ); + + /** + * Store the attachment info in the argument references given. + * Returns false if the attachment index was invalid. + **/ + bool PrintAttachInfo( int ind, idStr &joint, idVec3 &offset, idAngles &angles ); + + /** + * Called when the given entity is about to attach (bind) to this entity. + * Does not actually bind it. + **/ + virtual void BindNotify( idEntity *ent ); + + /** + * Called when the given entity is about to detach (unbind) from this entity. + * Does not actually unbind it. + **/ + virtual void UnbindNotify( idEntity *ent ); + + /** + * Return nonzero if this entity could potentially attack the given (target) entity at range, + * or entities in general if target is NULL. + */ + virtual float RangedThreatTo(idEntity* target); + + /** + * AddToInventory will add an entity to the inventory. The item is only + * added if the appropriate spawnargs are set, otherwise it will be rejected + * and NULL is returned. + */ + virtual CInventoryItemPtr AddToInventory(idEntity *ent); + + // Cycles to the prev/next item in the inventory. + // direction<0 - cycles to previous, direction>0 - cycles to next + virtual void NextPrevInventoryItem(int direction); + // Cycles to the prev/next group in the inventory. + // direction<0 - cycles to previous, direction>0 - cycles to next + virtual void NextPrevInventoryGroup(int direction); + + /** + * greebo: This cycles through a specific inventory group (=category). + * If the cursor is already pointing to an item in the given group, it is advanced to the next item. + * If the cursor has reached the "end" of the group, it is set back to the first item. + * If the cursor is currently not pointing to an item of the given group, it is set to the + * first item in that group. + */ + virtual void CycleInventoryGroup(const idStr& groupName); + + // Gets called when the inventory cursor has changed its selection focus + virtual void OnInventorySelectionChanged(const CInventoryItemPtr& prevItem = CInventoryItemPtr()); + + /** + * greebo: Gets called when anything within the inventory has been altered (item count, item icon) + * This does NOT get called when the selection changes, only the inventory's contents. + */ + virtual void OnInventoryItemChanged(); + + /** + * Changes the inventory count of the given item in by + */ + void ChangeInventoryItemCount(const char* invName, const char* invCategory, int amount); + + /** + * Changes the amount of the given loot type in the inventory of this entity. + * @returns: the new amount of the affected loot type. + */ + int ChangeLootAmount(int lootType, int amount); + + /** + * greebo: This replaces the inventory item (represented by oldItem) with the + * given entity. needs to be a valid inventory item entity or NULL. + * + * is removed from the inventory and will take its position, provided + * both items share the same category name. If the categories are different, the position + * can not be guaranteed to be the same after the operation. + * + * If is NULL, will just be removed and no replacement takes place. + * + * @returns TRUE on success, FALSE otherwise. + */ + bool ReplaceInventoryItem(idEntity* oldItem, idEntity* newItem); + + /** + * Script event: Changes the lightgem modifier value of the given item in to + */ + void ChangeInventoryIcon(const char* invName, const char* invCategory, const char* icon); + + /** + * Script event: Changes the lightgem modifier value of the given item in to + */ + void ChangeInventoryLightgemModifier(const char* invName, const char* invCategory, int value); + + /** + * Return true if this entity can be mantled, false otherwise. + */ + virtual bool IsMantleable(); + + // Accessors for the frob peer list + virtual void AddFrobPeer(const idStr& frobPeerName); + virtual void AddFrobPeer(idEntity* peer); + virtual void RemoveFrobPeer(const idStr& frobPeerName); + virtual void RemoveFrobPeer(idEntity* peer); + + // Returns the frob master for this entity or NULL if not set (or not existing anymore). + idEntity* GetFrobMaster(); + + inline UserManager& GetUserManager() + { + return m_userManager; + } + + // Stim/Response methods + CStimPtr AddStim(StimType type, float radius = 0.0f, bool removable = true, bool isDefault = false); + CResponsePtr AddResponse(StimType type, bool removable = true, bool isDefault = false); + + /** + * RemoveStim/Response removes the given stim. If the entity has no + * stims/responses left, it is also removed from the global list in gameLocal. + */ + void RemoveStim(StimType type); + void RemoveResponse(StimType type); + + void IgnoreResponse(StimType type, idEntity* fromEntity); + void AllowResponse(StimType type, idEntity* fromEntity); + + void EnableResponse(StimType type) { SetResponseEnabled(type, true); } + void DisableResponse(StimType type) { SetResponseEnabled(type, false); } + + // Enables / disables the given response + void SetResponseEnabled(StimType type, bool enabled); + + void EnableStim(StimType type) { SetStimEnabled(type, true); } + void DisableStim(StimType type) { SetStimEnabled(type, false); } + + void SetStimEnabled(StimType type, bool enabled); + + void ClearStimIgnoreList(StimType type); + + bool CheckResponseIgnore(StimType type, idEntity* fromEntity); // grayman #2872 + + + /** + * This triggers a stand-alone response (without an actual Stim) on this entity. + * + * @source: The entity that caused the response. + * @stimType: the according stim index (e.g. ST_FROB) + */ + void TriggerResponse(idEntity* source, StimType type); + + // greebo: Callback invoked by the response on incoming stims to trigger custom code + // To be overridden by subclasses, default implementation is empty + virtual void OnStim(const CStimPtr& stim, idEntity* stimSource) + { } + + /** + * greebo: Script events to get/set the team of this entity. + */ + void Event_GetTeam(); + void Event_SetTeam(int newTeam); + + void Event_IsEnemy( idEntity *ent ); + void Event_IsFriend( idEntity *ent ); + void Event_IsNeutral( idEntity *ent ); + + void Event_SetEntityRelation (idEntity* entity, int relation); + void Event_ChangeEntityRelation(idEntity* entity, int relationChange); + + void Event_IsLight(); // grayman #2905 + + int team; + + // angua: entities can have personal relationships to other entities that are used instead of the team relations. + typedef std::map EntityRelationsMap; + EntityRelationsMap m_EntityRelations; + + // angua: set a relation to another entity + // this can be friendly (>0), neutral(0) or hostile (<0) + void SetEntityRelation(idEntity* entity, int relation); + + // angua: this changes the current relation to an entity by adding the new amount + void ChangeEntityRelation(idEntity* entity, int relationChange); + + /** + * Checks with the global Relationship Manager and the personal relations to see if the + * other entity is an enemy of this entity. + **/ + bool IsEnemy(const idEntity *other); + // As above, but checks for Friend + bool IsFriend(const idEntity *other); + // As above, but checks for Neutral + bool IsNeutral(const idEntity *other); + + + float GetAbsenceNoticeability(); + + // angua: this checks whether an entity has been removed or returned to the original position + // and spawns or destroys an absence marker + void Event_CheckAbsence(); + bool SpawnAbsenceMarker(); + bool DestroyAbsenceMarker(); + + // Saves the CONTENTS values of all attachments + void SaveAttachmentContents(); + + // Sets all attachment contents to the given value + void SetAttachmentContents(int newContents); + + // Restores all CONTENTS values, previously saved with SaveAttachmentContents() + void RestoreAttachmentContents(); + +protected: + /** + * Update frob highlight state if frobbed. + * Clears highlight state if it's no longer frobbed. + * Called in idEntity::Present + **/ + void UpdateFrobState(); + + /** + * This controls the shader parms for the frob highlighting, + * according to the frob highlight state. Includes fading algorithms. + * Called in idEntity::Present(). + **/ + void UpdateFrobDisplay(); + + /** + * Activate/deactivate frob highlighting on an entity + * Also calls this on any of the entity's peers + **/ + void SetFrobHighlightState( bool bVal ); + + /** + * Call ParseAttachmentSpawnargs, spawns the attachements and binds them on to the entity. + **/ + virtual void ParseAttachments( void ); + + /** + * Parse attachment positions from the spawnargs + **/ + virtual void ParseAttachPositions( void ); + + /** + * Bind to the same object that the "other" argument is bound to + **/ + void Event_CopyBind( idEntity *other ); + + /** + * Returns the bindmaster + **/ + void Event_GetBindMaster( void ); + + /** + * Return the number of bind team members lower in the chain than this one + **/ + void Event_NumBindChildren( void ); + /** + * Return the ind_th bind team member + **/ + void Event_GetBindChild( int ind ); + +protected: + renderEntity_t renderEntity; //!< used to present a model to the renderer + int modelDefHandle; //!< handle to static renderer model + refSound_t refSound; //!< used to present sound to the audio engine + idStr brokenModel; //!< model set when health drops down to or below zero + + /** + * List storing attachment data for each attachment + **/ + idList m_Attachments; + + /** + * Maps string name of an attachment to an index in m_Attachments + **/ + typedef std::map AttNameMap; + AttNameMap m_AttNameMap; + + /** + * List of predefined attachment positions for this entity + * If the entity doesn't have joints, positions are relative to origin + **/ + idList m_AttachPositions; + + /** + * Used to keep track of the GUIs used by this entity. + **/ + COverlaySys m_overlays; + + /** + * This is set by idPlayer if the player is looking at the entity in a way + * that will frob it. + **/ + bool m_bFrobbed; + + /** + * This is separate from m_bFrobbed due to peer frob highlighting, + * to let an entity display the highlight when not frobbed. + **/ + bool m_bFrobHighlightState; + + /** + * Timestamp indicating when the frob highlight last changed + * Used for continuous fade in and fade out. + **/ + int m_FrobChangeTime; + + /** + * FrobActionScript will contain the name of the script that is to be + * exected whenever a frobaction occurs. The default should be set by + * the constructor of the respective derived class but can be overriden + * by the property "frob_action_script" in the entity definition file. + */ + idStr m_FrobActionScript; + + /** + * FrobPeers lists the names of other entites that will also be + * frobbed when this entity is frobbed. + */ + idStrList m_FrobPeers; + + /** + * This contains the name of the "master" entity. If this entity receives + * an incoming FrobAction or inventory item usage, the action is redirected + * to the frob master. + */ + idStr m_MasterFrob; + + // Is set to TRUE once the frob action function is entered on this entity. Prevents stack overflows. + bool m_FrobActionLock; + + CStimResponseCollection *m_StimResponseColl; + + float m_AbsenceNoticeability; + idBounds m_StartBounds; + bool m_AbsenceStatus; + idEntityPtr m_AbsenceMarker; + + bool m_bIsMantleable; + + /** + * Set to true when entity becomes broken (via damage) + **/ + bool m_bIsBroken; + + /** Used to implement waitForRender()... + * This merely contains a bounding box and a callback. + */ + renderEntity_t m_renderTrigger; + /// The render world handle for m_renderTrigger. + int m_renderTriggerHandle; + /// The thread that's waiting for this entity to render. (via waitForRender()) + int m_renderWaitingThread; + + /** Called when m_renderTrigger is rendered. + * It will resume the m_renderWaitingThread. + */ + static bool WaitForRenderTriggered( renderEntity_s* renderEntity, const renderView_s* view ); + /** Called to update m_renderTrigger after the render entity is modified. + * Only updates the render trigger if a thread is waiting for it. + */ + void PresentRenderTrigger(); + + /** + * Set and get whether the entity is frobable + * Note: IsFrobable is only used by scripting, since we can check public var m_bFrobable + **/ + void Event_IsFrobable( void ); + void Event_SetFrobable( bool bVal ); + void Event_IsHilighted( void ); + + // Frobs this entity. + void Event_Frob(); + // Frobhighlights this entity or turns it off + void Event_FrobHilight( bool bVal ); + + // angua: List of actors that currently use this entity + UserManager m_userManager; + +private: + idPhysics_Static defaultPhysicsObj; // default physics object + idPhysics * physics; // physics used for this entity + /** + * TDM: Clipmodel for frobbing only (used to make frobbing easier without effecting physics) + **/ + idClipModel * m_FrobBox; + idEntity * bindMaster; // entity bound to if unequal NULL + jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT + int bindBody; // body bound to if unequal -1 + idEntity * teamMaster; // master of the physics team + idEntity * teamChain; // next entity in physics team + + int numPVSAreas; // number of renderer areas the entity covers + int PVSAreas[MAX_PVS_AREAS];// numbers of the renderer areas the entity covers + + signalList_t * signals; + + int mpGUIState; // local cache to avoid systematic SetStateInt + + // A pointer to our inventory. + CInventoryPtr m_Inventory; + + // A pointer to our cursor - the cursor is for arbitrary use, and may not point to our own inventory. + CInventoryCursorPtr m_InventoryCursor; + + // Information about the most recent voice and body sound requests. grayman - #2341 + idSoundShader * previousVoiceShader; // shader for the most recent voice request (safe because shader pointers are constant, being decls) + int previousVoiceIndex; // index of most recent voice sound requested (1->N, where there are N sounds in the shader) + idSoundShader * previousBodyShader; // shader for the most recent body request (safe because shader pointers are constant, being decls) + int previousBodyIndex; // index of most recent body sound requested (1->N, where there are N sounds in the shader) +private: + void FixupLocalizedStrings(); + + bool DoDormantTests( void ); // dormant == on the active list, but out of PVS + + // physics + // initialize the default physics + void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis ); + // update visual position from the physics + void UpdateFromPhysics( bool moveBack ); + + // entity binding + bool InitBind( idEntity *master ); // initialize an entity binding + void FinishBind( void ); // finish an entity binding + void RemoveBinds( void ); // deletes any entities bound to this object + void QuitTeam( void ); // leave the current team + + void UpdatePVSAreas( void ); + +public: // Events should be public, so they can be used from other places as well. + // events + void Event_GetName( void ); + void Event_SetName( const char *name ); + void Event_IsType ( const char *pstr_typeName ); + void Event_FindTargets( void ); + void Event_ActivateTargets( idEntity *activator ); + void Event_AddTarget(idEntity* target); + void Event_RemoveTarget(idEntity* target); + void Event_NumTargets( void ); + void Event_GetTarget( float index ); + void Event_RandomTarget( const char *ignore ); + void Event_Bind( idEntity *master ); + void Event_BindPosition( idEntity *master ); + void Event_BindToJoint( idEntity *master, const char *jointname, float orientated ); + void Event_BindToBody( idEntity *master, int bodyId, bool orientated ); + void Event_Unbind( void ); + void Event_RemoveBinds( void ); + void Event_SpawnBind( void ); + void Event_SetOwner( idEntity *owner ); + void Event_SetModel( const char *modelname ); + void Event_SetSkin( const char *skinname ); + void Event_GetShaderParm( int parmnum ); + void Event_SetShaderParm( int parmnum, float value ); + void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 ); + void Event_SetColor( float red, float green, float blue ); + void Event_GetColor( void ); + void Event_IsHidden( void ); + void Event_Hide( void ); + void Event_Show( void ); + void Event_CacheSoundShader( const char *soundName ); + void Event_StartSoundShader( const char *soundName, int channel ); + void Event_StopSound( int channel, int netSync ); + void Event_StartSound( const char *soundName, int channel, int netSync ); + void Event_FadeSound( int channel, float to, float over ); + void Event_SetSoundVolume( float to ); + void Event_GetWorldOrigin( void ); + void Event_SetWorldOrigin( idVec3 const &org ); + void Event_GetOrigin( void ); + void Event_SetOrigin( const idVec3 &org ); + void Event_GetAngles( void ); + void Event_SetAngles( const idAngles &ang ); + void Event_SetLinearVelocity( const idVec3 &velocity ); + void Event_GetLinearVelocity( void ); + void Event_SetAngularVelocity( const idVec3 &velocity ); + void Event_GetAngularVelocity( void ); + + void Event_SetContents(const int contents); + void Event_GetContents(); + void Event_SetClipMask(const int clipMask); + void Event_GetClipMask(); + + void Event_SetSize( const idVec3 &mins, const idVec3 &maxs ); + void Event_GetSize( void ); + void Event_GetMins( void ); + void Event_GetMaxs( void ); + void Event_Touches( idEntity *ent ); + void Event_GetNextKey( const char *prefix, const char *lastMatch ); + void Event_SetKey( const char *key, const char *value ); + void Event_GetKey( const char *key ); + void Event_GetIntKey( const char *key ); + void Event_GetFloatKey( const char *key ); + void Event_GetVectorKey( const char *key ); + void Event_GetEntityKey( const char *key ); + void Event_RemoveKey( const char *key ); + void Event_RestorePosition( void ); + void Event_UpdateCameraTarget( void ); + void Event_DistanceTo( idEntity *ent ); + void Event_DistanceToPoint( const idVec3 &point ); + void Event_StartFx( const char *fx ); + void Event_WaitFrame( void ); + void Event_Wait( float time ); + void Event_HasFunction( const char *name ); + void Event_CallFunction( const char *name ); + void Event_CallGlobalFunction( const char *funcname, idEntity *ent ); + void Event_SetNeverDormant( int enable ); + + /** + * greebo: Extinguishes all lights in the teamchain, including self. + */ + void Event_ExtinguishLights(); + + void Event_InPVS( void ); + void Event_WaitForRender( void ); + + /** + * greebo: This is the method that can be invoked from scripts. It basically + * passes the call to the member method Damage(). + * + * This Deals damage to this entity (gets translated into the idEntity::Damage() method within the SDK). + * + * @inflictor: This is the entity causing the damage (maybe a projectile) + * @attacker: This is the "parent" entity of the inflictor, the one that is responsible for the inflictor (can be the same) + * @dir: The direction the attack is coming from. + * @damageDefName: The name of the damage entityDef to know what damage is being dealt to (e.g. "damage_lava") + * @damageScale: The scale of the damage (pass 1.0 as default, this should be ok). + */ + void Event_Damage( idEntity *inflictor, idEntity *attacker, + const idVec3 &dir, const char *damageDefName, + const float damageScale ); + /** + * greebo: This method heals this entity using the values defined in the + * the entityDef specified by . + */ + void Event_Heal( const char *healDefName, const float healScale ); + void Event_SetGui( int handle, const char *guiFile ); + void Event_GetGui( int handle ); + void Event_SetGuiString( int handle, const char *key, const char *val ); + void Event_GetGuiString( int handle, const char *key ); + void Event_SetGuiFloat( int handle, const char *key, float f ); + void Event_GetGuiFloat( int handle, const char *key ); + void Event_SetGuiInt( int handle, const char *key, int n ); + void Event_GetGuiInt( int handle, const char *key ); + void Event_SetGuiStringFromKey( int handle, const char *key, idEntity *src, const char *spawnArg ); + void Event_CallGui( int handle, const char *namedEvent ); + + /** + * Tels: Teleport the entity to the given entity's origin and orientation. + */ + void Event_TeleportTo(idEntity *target); + /** + * Get/set droppable on this entity and its inventory item if it's already in the inventory + **/ + void Event_IsDroppable(); + void Event_SetDroppable( bool Droppable ); + /** + * Tels: Return the sum of all lights in the entities PVS. + */ + void Event_GetLightInPVS( const float lightFalloff, const float lightDistScale); + + /** + * Tels: Toggle the noShadow flag on this entity. + */ + void Event_noShadows( bool noShadow ); + + void Event_CheckMine(); // grayman #2478 + + void Event_GetVinePlantLoc(); // grayman #2787 + void Event_GetVinePlantNormal(); // grayman #2787 + + void Event_LoadExternalData( const char *xdFile, const char* prefix ); + + void Event_GetInventory(); + + void Event_GetLootAmount(int lootType); + void Event_ChangeLootAmount(int lootType, int amount); + void Event_AddInvItem(idEntity* ent); + // Tels: The reverse of AddInvItem() + void Event_AddItemToInv(idEntity* ent); + void Event_ReplaceInvItem(idEntity* oldItem, idEntity* newItem); + void Event_GetNextInvItem(); + void Event_GetPrevInvItem(); + void Event_SetCurInvCategory(const char* categoryName); + void Event_SetCurInvItem(const char* itemName); + void Event_GetCurInvCategory(); + void Event_GetCurInvItemEntity(); + void Event_GetCurInvItemName(); + void Event_GetCurInvItemId(); + void Event_GetCurInvIcon(); + + // tels: remove all bound entities that have "unbindonalertlevel" higher or equal than alertlevel + void RemoveBindsOnAlert( const int alertIndex ); + void DetachOnAlert( const int alertIndex ); + + // Stim/Response Script Event Interface + void Event_StimAdd(int stimType, float radius); + void Event_StimRemove(int stimType); + void Event_StimEnable(int stimType, int state); + void Event_StimClearIgnoreList(int stimType); + void Event_ResponseAdd(int stimType); + void Event_ResponseRemove(int stimType); + void Event_ResponseEnable(int stimType, int State); + void Event_ResponseTrigger(idEntity* source, int stimType); + void Event_ResponseIgnore(int stimType, idEntity*); + void Event_ResponseAllow(int stimType, idEntity*); + void Event_ResponseSetAction(int stimType, const char* action); + void Event_GetResponseEntity(); + + void Event_TimerCreate(int StimType, int Hour, int Minute, int Seconds, int Milisecond); + void Event_TimerStop(int StimType); + void Event_TimerStart(int StimType); + void Event_TimerRestart(int StimType); + void Event_TimerReset(int StimType); + void Event_TimerSetState(int StimType, int State); + + /** + * Used to propagate a sound directly via scripting, without playing the audible sound + * VolModIn is a volume modifier added to the sound's volume. + **/ + void Event_PropSoundMod( const char *sndName, float VolModIn = 0.0 ); + + void Event_PropSound( const char *sndName ); + +#ifdef MOD_WATERPHYSICS + + void Event_GetMass( int body ); // MOD_WATERPHYSICS + + void Event_IsInLiquid( void ); // MOD_WATERPHYSICS + +#endif // MOD_WATERPHYSICS + + void Event_RangedThreatTo(idEntity*); + + /** + * greebo: Returns true if the target entity can be seen + * + * @useLighting: If set to TRUE, takes lighting into account. + */ + bool canSeeEntity(idEntity* target, int useLighting); + + /** + * greebo: script event wrapper for the above canSeeEntity() method. + */ + void Event_CanSeeEntity(idEntity* target, int useLighting); + + /** + * ishtvan: Let script acces CanBeUsedBy on this entity + **/ + void Event_CanBeUsedBy(idEntity *itemEnt); + +public: // events that need to have an accessible counterpart + void SetGuiString(int handle, const char *key, const char *val); + const char *GetGuiString(int handle, const char *key); + void SetGuiFloat(int handle, const char *key, float f); + float GetGuiFloat(int handle, const char *key); + void SetGuiInt(int handle, const char *key, int n); + int GetGuiInt(int handle, const char *key); + void CallGui(int handle, const char *namedEvent); +}; + +/* +=============================================================================== + + Animated entity base class. + +=============================================================================== +*/ + +typedef struct damageEffect_s { + jointHandle_t jointNum; + idVec3 localOrigin; + idVec3 localNormal; + int time; + const idDeclParticle* type; + struct damageEffect_s * next; +} damageEffect_t; + +class idAnimatedEntity : public idEntity +{ +public: + CLASS_PROTOTYPE( idAnimatedEntity ); + + idAnimatedEntity(); + ~idAnimatedEntity(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); //TDM: added so that we can cache anim rates + + virtual void ClientPredictionThink( void ); + virtual void Think( void ); + + void UpdateAnimation( void ); + + virtual idAnimator * GetAnimator( void ); + virtual void SetModel( const char *modelname ); + + bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ); + bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const; + + virtual int GetDefaultSurfaceType( void ) const; + virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); + void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial ); + void UpdateDamageEffects( void ); + + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + /** + * Overloads idEntity::Attach to bind to a joint + * AttName is the optional name of the attachment for indexing purposes (e.g., "melee_weapon") + * Ent is the entity being attached + * PosName is the optional position name to attach to. + **/ + virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); + + /** + * Reattach an existing attachment + * + * The next arguments are the name of the joint to attach to, the translation + * offset from that joint, and a (pitch, yaw, roll) angle vector that defines the + * rotation of the attachment relative to the joint's orientation. + **/ + virtual void ReAttachToCoords( const char *AttName, idStr jointName, idVec3 offset, idAngles angles ); + + /** + * Cache the animation rates from spawnargs + * Always called at spawn, sometimes called later if spawnargs changed and rates need recaching + **/ + virtual void CacheAnimRates( void ); + + + /** + * Tels: Return the position of the joint (by name) in world coordinates + **/ + idVec3 GetJointWorldPos( const char *jointname ); + + /** + * Tels: Return the entity closest to the given joint, excluding itself. AIUseType is something + * like "AIUSE_FOOD" and only entites that have the spawnarg "AIUse" "AIUSE_FOOD" will be + * considered. From all these entities, the one closest to the joint is returned, or NULL + * if no such entity could be found. Called from GetEntityClosestToJoint(). + **/ + idEntity* GetEntityFromClassClosestToJoint( const idVec3 joint_origin, const char* AIUseType, const float max_dist_sqr ); + + /** + * Tels: Return the entity closest to the given joint, excluding itself. entitySelector is either + * a direct entity name or something like "AIUSE_FOOD". First we look at all spawnargs with + * prefix "prefix", and if these all fail to produce an entity, fall back to entitySelector. + * Returns NULL if no suitable entity could be found. + **/ + idEntity* GetEntityClosestToJoint( const char* jointname, const char* entitySelector, const char* prefix, const float max_dist ); + + enum { + EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS, + EVENT_MAXEVENTS + }; + +protected: + /** + * Used internally by the Attach methods. + * Offset and axis are filled with the correct offset and axis + * for attaching to a particular joint. + * Calls GetJointWorldTransform on idAnimated entities. + **/ + virtual void GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); + +protected: + idAnimator animator; + damageEffect_t * damageEffects; + + // The game time UpdateAnimation() has been called the last time + int lastUpdateTime; + +private: + void Event_GetJointHandle( const char *jointname ); + void Event_ClearAllJoints( void ); + void Event_ClearJoint( jointHandle_t jointnum ); + void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ); + void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ); + void Event_GetJointPos( jointHandle_t jointnum ); + void Event_GetJointAngle( jointHandle_t jointnum ); +}; + +#endif /* !__GAME_ENTITY_H__ */ diff --git a/DarkMod/EscapePointEvaluator.cpp b/game/EscapePointEvaluator.cpp similarity index 83% rename from DarkMod/EscapePointEvaluator.cpp rename to game/EscapePointEvaluator.cpp index 3bfe9a3a9..453ba4aae 100644 --- a/DarkMod/EscapePointEvaluator.cpp +++ b/game/EscapePointEvaluator.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/EscapePointEvaluator.h b/game/EscapePointEvaluator.h similarity index 83% rename from DarkMod/EscapePointEvaluator.h rename to game/EscapePointEvaluator.h index 7c013db9b..8ac308bbb 100644 --- a/DarkMod/EscapePointEvaluator.h +++ b/game/EscapePointEvaluator.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef ESCAPE_POINT_EVALUATOR__H #define ESCAPE_POINT_EVALUATOR__H diff --git a/DarkMod/EscapePointManager.cpp b/game/EscapePointManager.cpp similarity index 92% rename from DarkMod/EscapePointManager.cpp rename to game/EscapePointManager.cpp index c84fb216f..8ce70adee 100644 --- a/DarkMod/EscapePointManager.cpp +++ b/game/EscapePointManager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/EscapePointManager.h b/game/EscapePointManager.h similarity index 85% rename from DarkMod/EscapePointManager.h rename to game/EscapePointManager.h index 63acb2faa..1406f59c1 100644 --- a/DarkMod/EscapePointManager.h +++ b/game/EscapePointManager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef ESCAPE_POINT_MANAGER__H #define ESCAPE_POINT_MANAGER__H diff --git a/game/FX.cpp b/game/FX.cpp new file mode 100644 index 000000000..eb738f072 --- /dev/null +++ b/game/FX.cpp @@ -0,0 +1,789 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +=============================================================================== + + idEntityFx + +=============================================================================== +*/ + +const idEventDef EV_Fx_KillFx( "_killfx" ); +const idEventDef EV_Fx_Action( "_fxAction", "e" ); // implemented by subclasses + +CLASS_DECLARATION( idEntity, idEntityFx ) +EVENT( EV_Activate, idEntityFx::Event_Trigger ) +EVENT( EV_Fx_KillFx, idEntityFx::Event_ClearFx ) +END_CLASS + + +/* +================ +idEntityFx::Save +================ +*/ +void idEntityFx::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( started ); + savefile->WriteInt( nextTriggerTime ); + savefile->WriteFX( fxEffect ); + savefile->WriteString( systemName ); + + savefile->WriteInt( actions.Num() ); + + for ( i = 0; i < actions.Num(); i++ ) { + + if ( actions[i].lightDefHandle >= 0 ) { + savefile->WriteBool( true ); + savefile->WriteRenderLight( actions[i].renderLight ); + } else { + savefile->WriteBool( false ); + } + + if ( actions[i].modelDefHandle >= 0 ) { + savefile->WriteBool( true ); + savefile->WriteRenderEntity( actions[i].renderEntity ); + } else { + savefile->WriteBool( false ); + } + + savefile->WriteFloat( actions[i].delay ); + savefile->WriteInt( actions[i].start ); + savefile->WriteBool( actions[i].soundStarted ); + savefile->WriteBool( actions[i].shakeStarted ); + savefile->WriteBool( actions[i].decalDropped ); + savefile->WriteBool( actions[i].launched ); + } +} + +/* +================ +idEntityFx::Restore +================ +*/ +void idEntityFx::Restore( idRestoreGame *savefile ) { + int i; + int num; + bool hasObject; + + savefile->ReadInt( started ); + savefile->ReadInt( nextTriggerTime ); + savefile->ReadFX( fxEffect ); + savefile->ReadString( systemName ); + + savefile->ReadInt( num ); + + actions.SetNum( num ); + for ( i = 0; i < num; i++ ) { + + savefile->ReadBool( hasObject ); + if ( hasObject ) { + savefile->ReadRenderLight( actions[i].renderLight ); + actions[i].lightDefHandle = gameRenderWorld->AddLightDef( &actions[i].renderLight ); + } else { + memset( &actions[i].renderLight, 0, sizeof( renderLight_t ) ); + actions[i].lightDefHandle = -1; + } + + savefile->ReadBool( hasObject ); + if ( hasObject ) { + savefile->ReadRenderEntity( actions[i].renderEntity ); + actions[i].modelDefHandle = gameRenderWorld->AddEntityDef( &actions[i].renderEntity ); + } else { + memset( &actions[i].renderEntity, 0, sizeof( renderEntity_t ) ); + actions[i].modelDefHandle = -1; + } + + savefile->ReadFloat( actions[i].delay ); + + // let the FX regenerate the particleSystem + actions[i].particleSystem = -1; + + savefile->ReadInt( actions[i].start ); + savefile->ReadBool( actions[i].soundStarted ); + savefile->ReadBool( actions[i].shakeStarted ); + savefile->ReadBool( actions[i].decalDropped ); + savefile->ReadBool( actions[i].launched ); + } +} + +/* +================ +idEntityFx::Setup +================ +*/ +void idEntityFx::Setup( const char *fx ) { + + if ( started >= 0 ) { + return; // already started + } + + // early during MP Spawn() with no information. wait till we ReadFromSnapshot for more + if ( gameLocal.isClient && ( !fx || fx[0] == '\0' ) ) { + return; + } + + systemName = fx; + started = 0; + + fxEffect = static_cast( declManager->FindType( DECL_FX, systemName.c_str() ) ); + + if ( fxEffect ) { + idFXLocalAction localAction; + + memset( &localAction, 0, sizeof( idFXLocalAction ) ); + + actions.AssureSize( fxEffect->events.Num(), localAction ); + + for( int i = 0; ievents.Num(); i++ ) { + const idFXSingleAction& fxaction = fxEffect->events[i]; + + idFXLocalAction& laction = actions[i]; + if ( fxaction.random1 || fxaction.random2 ) { + laction.delay = fxaction.random1 + gameLocal.random.RandomFloat() * ( fxaction.random2 - fxaction.random1 ); + } else { + laction.delay = fxaction.delay; + } + laction.start = -1; + laction.lightDefHandle = -1; + laction.modelDefHandle = -1; + laction.particleSystem = -1; + laction.shakeStarted = false; + laction.decalDropped = false; + laction.launched = false; + } + } +} + +/* +================ +idEntityFx::EffectName +================ +*/ +const char *idEntityFx::EffectName( void ) { + return fxEffect ? fxEffect->GetName() : NULL; +} + +/* +================ +idEntityFx::Joint +================ +*/ +const char *idEntityFx::Joint( void ) { + return fxEffect ? fxEffect->joint.c_str() : NULL; +} + +/* +================ +idEntityFx::CleanUp +================ +*/ +void idEntityFx::CleanUp( void ) { + if ( !fxEffect ) { + return; + } + for( int i = 0; i < fxEffect->events.Num(); i++ ) { + const idFXSingleAction& fxaction = fxEffect->events[i]; + idFXLocalAction& laction = actions[i]; + CleanUpSingleAction( fxaction, laction ); + } +} + +/* +================ +idEntityFx::CleanUpSingleAction +================ +*/ +void idEntityFx::CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ) { + if ( laction.lightDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHLIGHT ) { + gameRenderWorld->FreeLightDef( laction.lightDefHandle ); + laction.lightDefHandle = -1; + } + if ( laction.modelDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHENTITY ) { + gameRenderWorld->FreeEntityDef( laction.modelDefHandle ); + laction.modelDefHandle = -1; + } + laction.start = -1; +} + +/* +================ +idEntityFx::Start +================ +*/ +void idEntityFx::Start( int time ) { + if ( !fxEffect ) { + return; + } + started = time; + for( int i = 0; i < fxEffect->events.Num(); i++ ) { + idFXLocalAction& laction = actions[i]; + laction.start = time; + laction.soundStarted = false; + laction.shakeStarted = false; + laction.particleSystem = -1; + laction.decalDropped = false; + laction.launched = false; + } +} + +/* +================ +idEntityFx::Stop +================ +*/ +void idEntityFx::Stop( void ) { + CleanUp(); + started = -1; +} + +/* +================ +idEntityFx::Duration +================ +*/ +const int idEntityFx::Duration( void ) { + int max = 0; + + if ( !fxEffect ) { + return max; + } + for( int i = 0; i < fxEffect->events.Num(); i++ ) { + const idFXSingleAction& fxaction = fxEffect->events[i]; + int d = static_cast(( fxaction.delay + fxaction.duration ) * 1000.0f); + if ( d > max ) { + max = d; + } + } + + return max; +} + + +/* +================ +idEntityFx::Done +================ +*/ +const bool idEntityFx::Done() { + if (started > 0 && gameLocal.time > started + Duration()) { + return true; + } + return false; +} + +/* +================ +idEntityFx::ApplyFade +================ +*/ +void idEntityFx::ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ) { + if ( fxaction.fadeInTime || fxaction.fadeOutTime ) { + float fadePct = (float)( time - actualStart ) / ( 1000.0f * ( ( fxaction.fadeInTime != 0 ) ? fxaction.fadeInTime : fxaction.fadeOutTime ) ); + if (fadePct > 1.0) { + fadePct = 1.0; + } + if ( laction.modelDefHandle != -1 ) { + laction.renderEntity.shaderParms[SHADERPARM_RED] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; + laction.renderEntity.shaderParms[SHADERPARM_GREEN] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; + laction.renderEntity.shaderParms[SHADERPARM_BLUE] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; + + gameRenderWorld->UpdateEntityDef( laction.modelDefHandle, &laction.renderEntity ); + } + if ( laction.lightDefHandle != -1 ) { + laction.renderLight.shaderParms[SHADERPARM_RED] = fxaction.lightColor.x * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); + laction.renderLight.shaderParms[SHADERPARM_GREEN] = fxaction.lightColor.y * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); + laction.renderLight.shaderParms[SHADERPARM_BLUE] = fxaction.lightColor.z * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); + + gameRenderWorld->UpdateLightDef( laction.lightDefHandle, &laction.renderLight ); + } + } +} + +/* +================ +idEntityFx::Run +================ +*/ +void idEntityFx::Run( int time ) { + int ieff, j; + idEntity *ent = NULL; + const idDict *projectileDef = NULL; + idProjectile *projectile = NULL; + + if ( !fxEffect ) { + return; + } + + for( ieff = 0; ieff < fxEffect->events.Num(); ieff++ ) { + const idFXSingleAction& fxaction = fxEffect->events[ieff]; + idFXLocalAction& laction = actions[ieff]; + + // + // if we're currently done with this one + // + if ( laction.start == -1 ) { + continue; + } + + // + // see if it's delayed + // + if ( laction.delay ) { + if ( laction.start + (time - laction.start) < laction.start + (laction.delay * 1000) ) { + continue; + } + } + + // + // each event can have it's own delay and restart + // + int actualStart = laction.delay ? laction.start + (int)( laction.delay * 1000 ) : laction.start; + float pct = (float)( time - actualStart ) / (1000 * fxaction.duration ); + if ( pct >= 1.0f ) { + laction.start = -1; + float totalDelay = 0.0f; + if ( fxaction.restart ) { + if ( fxaction.random1 || fxaction.random2 ) { + totalDelay = fxaction.random1 + gameLocal.random.RandomFloat() * (fxaction.random2 - fxaction.random1); + } else { + totalDelay = fxaction.delay; + } + laction.delay = totalDelay; + laction.start = time; + } + continue; + } + + if ( fxaction.fire.Length() ) { + for( j = 0; j < fxEffect->events.Num(); j++ ) { + if ( fxEffect->events[j].name.Icmp( fxaction.fire ) == 0 ) { + actions[j].delay = 0; + } + } + } + + idFXLocalAction *useAction; + if ( fxaction.sibling == -1 ) { + useAction = &laction; + } else { + useAction = &actions[fxaction.sibling]; + } + assert( useAction ); + + switch( fxaction.type ) { + case FX_ATTACHLIGHT: + case FX_LIGHT: { + if ( useAction->lightDefHandle == -1 ) { + if ( fxaction.type == FX_LIGHT ) { + memset( &useAction->renderLight, 0, sizeof( renderLight_t ) ); + useAction->renderLight.origin = GetPhysics()->GetOrigin() + fxaction.offset; + useAction->renderLight.axis = GetPhysics()->GetAxis(); + useAction->renderLight.lightRadius[0] = fxaction.lightRadius; + useAction->renderLight.lightRadius[1] = fxaction.lightRadius; + useAction->renderLight.lightRadius[2] = fxaction.lightRadius; + useAction->renderLight.shader = declManager->FindMaterial( fxaction.data, false ); + useAction->renderLight.shaderParms[ SHADERPARM_RED ] = fxaction.lightColor.x; + useAction->renderLight.shaderParms[ SHADERPARM_GREEN ] = fxaction.lightColor.y; + useAction->renderLight.shaderParms[ SHADERPARM_BLUE ] = fxaction.lightColor.z; + useAction->renderLight.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; + useAction->renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time ); + useAction->renderLight.referenceSound = refSound.referenceSound; + useAction->renderLight.pointLight = true; + if ( fxaction.noshadows ) { + useAction->renderLight.noShadows = true; + } + useAction->lightDefHandle = gameRenderWorld->AddLightDef( &useAction->renderLight ); + } + if ( fxaction.noshadows ) { + for( j = 0; j < fxEffect->events.Num(); j++ ) { + idFXLocalAction& laction2 = actions[j]; + if ( laction2.modelDefHandle != -1 ) { + laction2.renderEntity.noShadow = true; + } + } + } + } + ApplyFade( fxaction, *useAction, time, actualStart ); + break; + } + case FX_SOUND: { + if ( !useAction->soundStarted ) { + useAction->soundStarted = true; + const idSoundShader *shader = declManager->FindSound(fxaction.data); + StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL ); + for( j = 0; j < fxEffect->events.Num(); j++ ) { + idFXLocalAction& laction2 = actions[j]; + if ( laction2.lightDefHandle != -1 ) { + laction2.renderLight.referenceSound = refSound.referenceSound; + gameRenderWorld->UpdateLightDef( laction2.lightDefHandle, &laction2.renderLight ); + } + } + } + break; + } + case FX_DECAL: { + if ( !useAction->decalDropped ) { + useAction->decalDropped = true; + gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 8.0f, true, fxaction.size, fxaction.data ); + } + break; + } + case FX_SHAKE: { + if ( !useAction->shakeStarted ) { + idDict args; + args.Clear(); + args.SetFloat( "kick_time", fxaction.shakeTime ); + args.SetFloat( "kick_amplitude", fxaction.shakeAmplitude ); + for ( j = 0; j < gameLocal.numClients; j++ ) { + idPlayer *player = gameLocal.GetClientByNum( j ); + if ( player && ( player->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).LengthSqr() < Square( fxaction.shakeDistance ) ) { + if ( !gameLocal.isMultiplayer || !fxaction.shakeIgnoreMaster || GetBindMaster() != player ) { + player->playerView.DamageImpulse( fxaction.offset, &args ); + } + } + } + if ( fxaction.shakeImpulse != 0.0f && fxaction.shakeDistance != 0.0f ) { + idEntity *ignore_ent = NULL; + if ( gameLocal.isMultiplayer ) { + ignore_ent = this; + if ( fxaction.shakeIgnoreMaster ) { + ignore_ent = GetBindMaster(); + } + } + // lookup the ent we are bound to? + gameLocal.RadiusPush( GetPhysics()->GetOrigin(), fxaction.shakeDistance, fxaction.shakeImpulse, this, ignore_ent, 1.0f, true ); + } + useAction->shakeStarted = true; + } + break; + } + case FX_ATTACHENTITY: + case FX_PARTICLE: + case FX_MODEL: { + if ( useAction->modelDefHandle == -1 ) { + memset( &useAction->renderEntity, 0, sizeof( renderEntity_t ) ); + useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset; + useAction->renderEntity.axis = (fxaction.explicitAxis) ? fxaction.axis : GetPhysics()->GetAxis(); + useAction->renderEntity.hModel = renderModelManager->FindModel( fxaction.data ); + useAction->renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; + useAction->renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f; + useAction->renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; + useAction->renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time ); + useAction->renderEntity.shaderParms[3] = 1.0f; + useAction->renderEntity.shaderParms[5] = 0.0f; + if ( useAction->renderEntity.hModel ) { + useAction->renderEntity.bounds = useAction->renderEntity.hModel->Bounds( &useAction->renderEntity ); + } + useAction->modelDefHandle = gameRenderWorld->AddEntityDef( &useAction->renderEntity ); + } else if ( fxaction.trackOrigin ) { + useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset; + useAction->renderEntity.axis = fxaction.explicitAxis ? fxaction.axis : GetPhysics()->GetAxis(); + } + ApplyFade( fxaction, *useAction, time, actualStart ); + break; + } + case FX_LAUNCH: { + if ( gameLocal.isClient ) { + // client never spawns entities outside of ClientReadSnapshot + useAction->launched = true; + break; + } + if ( !useAction->launched ) { + useAction->launched = true; + projectile = NULL; + // FIXME: may need to cache this if it is slow + projectileDef = gameLocal.FindEntityDefDict( fxaction.data, false ); + if ( !projectileDef ) { + gameLocal.Warning( "projectile \'%s\' not found", fxaction.data.c_str() ); + } else { + gameLocal.SpawnEntityDef( *projectileDef, &ent, false ); + if ( ent && ent->IsType( idProjectile::Type ) ) { + projectile = ( idProjectile * )ent; + projectile->Create( this, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0] ); + projectile->Launch( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0], vec3_origin ); + } + } + } + break; + } + } + } +} + +/* +================ +idEntityFx::idEntityFx +================ +*/ +idEntityFx::idEntityFx() { + fxEffect = NULL; + started = -1; + nextTriggerTime = -1; + fl.networkSync = true; +} + +/* +================ +idEntityFx::~idEntityFx +================ +*/ +idEntityFx::~idEntityFx() { + CleanUp(); + fxEffect = NULL; +} + +/* +================ +idEntityFx::Spawn +================ +*/ +void idEntityFx::Spawn( void ) { + + if ( g_skipFX.GetBool() ) { + return; + } + + const char *fx; + nextTriggerTime = 0; + fxEffect = NULL; + if ( spawnArgs.GetString( "fx", "", &fx ) ) { + systemName = fx; + } + if ( !spawnArgs.GetBool( "triggered" ) ) { + Setup( fx ); + if ( spawnArgs.GetBool( "test" ) || spawnArgs.GetBool( "start" ) || spawnArgs.GetFloat ( "restart" ) ) { + PostEventMS( &EV_Activate, 0, this ); + } + } +} + +/* +================ +idEntityFx::Think + + Clears any visual fx started when {item,mob,player} was spawned +================ +*/ +void idEntityFx::Think( void ) { + if ( g_skipFX.GetBool() ) { + return; + } + + if ( thinkFlags & TH_THINK ) { + Run( gameLocal.time ); + } + + RunPhysics(); + Present(); +} + +/* +================ +idEntityFx::Event_ClearFx + + Clears any visual fx started when item(mob) was spawned +================ +*/ +void idEntityFx::Event_ClearFx( void ) { + + if ( g_skipFX.GetBool() ) { + return; + } + + Stop(); + CleanUp(); + BecomeInactive( TH_THINK ); + + if ( spawnArgs.GetBool("test") ) { + PostEventMS( &EV_Activate, 0, this ); + } else { + if ( spawnArgs.GetFloat( "restart" ) || !spawnArgs.GetBool( "triggered")) { + float rest = spawnArgs.GetFloat( "restart", "0" ); + if ( rest == 0.0f ) { + PostEventSec( &EV_Remove, 0.1f ); + } else { + rest *= gameLocal.random.RandomFloat(); + PostEventSec( &EV_Activate, rest, this ); + } + } + } +} + +/* +================ +idEntityFx::Event_Trigger +================ +*/ +void idEntityFx::Event_Trigger( idEntity *activator ) { + + if ( g_skipFX.GetBool() ) { + return; + } + + float fxActionDelay; + const char *fx; + + if ( gameLocal.time < nextTriggerTime ) { + return; + } + + if ( spawnArgs.GetString( "fx", "", &fx) ) { + Setup( fx ); + Start( gameLocal.time ); + PostEventMS( &EV_Fx_KillFx, Duration() ); + BecomeActive( TH_THINK ); + } + + fxActionDelay = spawnArgs.GetFloat( "fxActionDelay" ); + if ( fxActionDelay != 0.0f ) { + nextTriggerTime = gameLocal.time + SEC2MS( fxActionDelay ); + } else { + // prevent multiple triggers on same frame + nextTriggerTime = gameLocal.time + 1; + } + PostEventSec( &EV_Fx_Action, fxActionDelay, activator ); +} + + +/* +================ +idEntityFx::StartFx +================ +*/ +idEntityFx *idEntityFx::StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ) { + + if ( g_skipFX.GetBool() || !fx || !*fx ) { + return NULL; + } + + idDict args; + args.SetBool( "start", true ); + args.Set( "fx", fx ); + idEntityFx *nfx = static_cast( gameLocal.SpawnEntityType( idEntityFx::Type, &args ) ); + if ( nfx->Joint() && *nfx->Joint() ) { + nfx->BindToJoint( ent, nfx->Joint(), true ); + nfx->SetOrigin( vec3_origin ); + } else { + nfx->SetOrigin( (useOrigin) ? *useOrigin : ent->GetPhysics()->GetOrigin() ); + nfx->SetAxis( (useAxis) ? *useAxis : ent->GetPhysics()->GetAxis() ); + } + + // greebo: Don't call Bind again if a we're bound to a joint + if (bind && ((nfx->Joint() == NULL) || (*nfx->Joint() == '\0'))) + { + // never bind to world spawn + if (ent != gameLocal.world) + { + nfx->Bind(ent, true); + } + } + + nfx->Show(); + return nfx; +} + +/* +================= +idEntityFx::WriteToSnapshot +================= +*/ +void idEntityFx::WriteToSnapshot( idBitMsgDelta &msg ) const { + GetPhysics()->WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); + msg.WriteLong( ( fxEffect != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_FX, fxEffect->Index() ) : -1 ); + msg.WriteLong( started ); +} + +/* +================= +idEntityFx::ReadFromSnapshot +================= +*/ +void idEntityFx::ReadFromSnapshot( const idBitMsgDelta &msg ) { + int fx_index, start_time, max_lapse; + + GetPhysics()->ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + fx_index = gameLocal.ClientRemapDecl( DECL_FX, msg.ReadLong() ); + start_time = msg.ReadLong(); + + if ( fx_index != -1 && start_time > 0 && !fxEffect && started < 0 ) { + spawnArgs.GetInt( "effect_lapse", "1000", max_lapse ); + if ( gameLocal.time - start_time > max_lapse ) { + // too late, skip the effect completely + started = 0; + return; + } + const idDeclFX *fx = static_cast( declManager->DeclByIndex( DECL_FX, fx_index ) ); + if ( !fx ) { + gameLocal.Error( "FX at index %d not found", fx_index ); + } + fxEffect = fx; + Setup( fx->GetName() ); + Start( start_time ); + } +} + +/* +================= +idEntityFx::ClientPredictionThink +================= +*/ +void idEntityFx::ClientPredictionThink( void ) { + if ( gameLocal.isNewFrame ) { + Run( gameLocal.time ); + } + RunPhysics(); + Present(); +} + +/* +=============================================================================== + + idTeleporter + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntityFx, idTeleporter ) + EVENT( EV_Fx_Action, idTeleporter::Event_DoAction ) +END_CLASS + +/* +================ +idTeleporter::Event_DoAction +================ +*/ +void idTeleporter::Event_DoAction( idEntity *activator ) { + float angle; + + angle = spawnArgs.GetFloat( "angle" ); + idAngles a( 0, spawnArgs.GetFloat( "angle" ), 0 ); + activator->Teleport( GetPhysics()->GetOrigin(), a, NULL ); +} diff --git a/game/FX.h b/game/FX.h new file mode 100644 index 000000000..a911b656f --- /dev/null +++ b/game/FX.h @@ -0,0 +1,98 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_FX_H__ +#define __GAME_FX_H__ + +/* +=============================================================================== + + Special effects. + +=============================================================================== +*/ + +struct idFXSingleAction; + +typedef struct { + renderLight_t renderLight; // light presented to the renderer + qhandle_t lightDefHandle; // handle to renderer light def + renderEntity_t renderEntity; // used to present a model to the renderer + int modelDefHandle; // handle to static renderer model + float delay; + int particleSystem; + int start; + bool soundStarted; + bool shakeStarted; + bool decalDropped; + bool launched; +} idFXLocalAction; + +class idEntityFx : public idEntity { +public: + CLASS_PROTOTYPE( idEntityFx ); + + idEntityFx(); + virtual ~idEntityFx(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think(); + void Setup( const char *fx ); + void Run( int time ); + void Start( int time ); + void Stop( void ); + const int Duration( void ); + const char * EffectName( void ); + const char * Joint( void ); + const bool Done(); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + virtual void ClientPredictionThink( void ); + + static idEntityFx * StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ); + +protected: + void Event_Trigger( idEntity *activator ); + void Event_ClearFx( void ); + + void CleanUp( void ); + void CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ); + void ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ); + + int started; + int nextTriggerTime; + const idDeclFX * fxEffect; // GetFX() should be called before using fxEffect as a pointer + idList actions; + idStr systemName; +}; + +class idTeleporter : public idEntityFx { +public: + CLASS_PROTOTYPE( idTeleporter ); + +private: + // teleporters to this location + void Event_DoAction( idEntity *activator ); +}; + +#endif /* !__GAME_FX_H__ */ diff --git a/game/Force_Grab.cpp b/game/Force_Grab.cpp new file mode 100755 index 000000000..1842b8c05 --- /dev/null +++ b/game/Force_Grab.cpp @@ -0,0 +1,437 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "Force_Grab.h" +#include "Grabber.h" + +class CDarkModPlayer; + +CLASS_DECLARATION( idForce, CForce_Grab ) +END_CLASS + +/* +================ +CForce_Grab::CForce_Grab +================ +*/ +CForce_Grab::CForce_Grab( void ) +{ + m_damping = 0.0f; + m_physics = NULL; + m_id = 0; + m_p = vec3_zero; + m_dragPosition = vec3_zero; + m_dragAxis.Zero(); + m_centerOfMass = vec3_zero; + m_inertiaTensor.Identity(); + + m_bApplyDamping = false; + m_bLimitForce = false; + m_RefEnt = NULL; +} + +/* +================ +CForce_Grab::~CForce_Grab +================ +*/ +CForce_Grab::~CForce_Grab( void ) { +} + +/* +================ +CForce_Grab::Init +================ +*/ +void CForce_Grab::Init( float damping ) { + if ( damping >= 0.0f && damping < 1.0f ) + { + m_damping = damping; + } + else + { + m_damping = 0; + } +} + +void CForce_Grab::Save( idSaveGame *savefile ) const +{ + m_RefEnt.Save( savefile ); + savefile->WriteFloat(m_damping); + savefile->WriteVec3(m_centerOfMass); + savefile->WriteMat3(m_inertiaTensor); + + // Don't save m_physics, gets restored from the parent class after load + + savefile->WriteVec3(m_p); + savefile->WriteInt(m_id); + savefile->WriteVec3(m_dragPosition); + savefile->WriteMat3(m_dragAxis); + savefile->WriteBool(m_bApplyDamping); + savefile->WriteBool(m_bLimitForce); +} + +void CForce_Grab::Restore( idRestoreGame *savefile ) +{ + m_RefEnt.Restore( savefile ); + savefile->ReadFloat(m_damping); + savefile->ReadVec3(m_centerOfMass); + savefile->ReadMat3(m_inertiaTensor); + + m_physics = NULL; // gets restored from the parent class after loading + + savefile->ReadVec3(m_p); + savefile->ReadInt(m_id); + savefile->ReadVec3(m_dragPosition); + savefile->ReadMat3(m_dragAxis); + savefile->ReadBool(m_bApplyDamping); + savefile->ReadBool(m_bLimitForce); +} + +/* +================ +CForce_Grab::SetPhysics +================ +*/ +void CForce_Grab::SetPhysics( idPhysics *phys, int id, const idVec3 &p ) { + float mass, MassOut, density; + idClipModel *clipModel; + + m_physics = phys; + m_id = id; + m_p = p; + + clipModel = m_physics->GetClipModel( m_id ); + if ( clipModel != NULL && clipModel->IsTraceModel() ) + { + mass = m_physics->GetMass( m_id ); + // PROBLEM: No way to query physics object for density! + // Trick: Use a test density of 1.0 here, then divide the actual mass by output mass to get actual density + clipModel->GetMassProperties( 1.0f, MassOut, m_centerOfMass, m_inertiaTensor ); + density = mass / MassOut; + // Now correct the inertia tensor by using actual density + clipModel->GetMassProperties( density, mass, m_centerOfMass, m_inertiaTensor ); + } else + { + m_centerOfMass.Zero(); + m_inertiaTensor = mat3_identity; + } +} + +/* +================ +CForce_Grab::SetDragPosition +================ +*/ +void CForce_Grab::SetDragPosition( const idVec3 &pos ) +{ + m_dragPosition = pos; +} + +/* +================ +CForce_Grab::GetDragPosition +================ +*/ +const idVec3 &CForce_Grab::GetDragPosition( void ) const +{ + return m_dragPosition; +} + +/* +================ +CForce_Grab::SetDragAxis +================ +*/ +void CForce_Grab::SetDragAxis( const idMat3 &Axis ) +{ + m_dragAxis = Axis; +} + +/* +================ +CForce_Grab::GetDragAxis +================ +*/ +idMat3 CForce_Grab::GetDragAxis( void ) +{ + return m_dragAxis; +} + +/* +================ +CForce_Grab::GetDraggedPosition +================ +*/ +const idVec3 CForce_Grab::GetDraggedPosition( void ) const +{ + return ( m_physics->GetOrigin( m_id ) + m_p * m_physics->GetAxis( m_id ) ); +} + +/* +================ +CForce_Grab::Evaluate +================ +*/ +void CForce_Grab::Evaluate( int time ) +{ + float l1, Accel, dT; + idVec3 dragOrigin, dir1, dir2, velocity, COM, prevVel; + idRotation rotation; + + if ( !m_physics ) + { + return; + } + + CGrabber *grabber = gameLocal.m_Grabber; + +// ======================== LINEAR ========================= + + COM = this->GetCenterOfMass(); + dragOrigin = COM; + + dir1 = m_dragPosition - dragOrigin; + l1 = dir1.Normalize(); + dT = MS2SEC( USERCMD_MSEC ); // time elapsed is time between user mouse commands + + if( !m_bApplyDamping ) + m_damping = 0.0f; + + if( grabber->m_bIsColliding ) + { + // Zero out previous velocity when we start out colliding + prevVel = vec3_zero; + + idVec3 newDir = dir1; + + for( int i=0; i < grabber->m_CollNorms.Num(); i++ ) + { + // subtract out component of desired dir going in to surface + if( newDir * grabber->m_CollNorms[i] < 0.0f ) + { + newDir -= (newDir * grabber->m_CollNorms[i]) * grabber->m_CollNorms[i]; + } + + if( cv_drag_debug.GetBool() ) + gameRenderWorld->DebugArrow( colorBlue, COM, (COM + 30 * grabber->m_CollNorms[i]), 4.0f, 1); + } + + // Clear m_CollNorms so it can be filled next time there's a collision + grabber->m_CollNorms.Clear(); + + newDir.Normalize(); + + float newl1 = l1 * (dir1 * newDir); + + // avoid jittering due to floating point error + if( newl1 > 0.1f ) + { + l1 = newl1; // project the magnitude in the new direction + dir1 = newDir; + } + else + { + dir1 = vec3_zero; + l1 = 0.0f; + } + + if( cv_drag_debug.GetBool() ) + gameRenderWorld->DebugArrow( colorRed, COM, (COM + l1 * dir1), 4.0f, 1); + } + else + { + prevVel = m_physics->GetLinearVelocity( m_id ); + if( cv_drag_debug.GetBool() ) + gameRenderWorld->DebugArrow( colorGreen, COM, (COM + l1 * dir1), 4.0f, 1); + } + + // "Realistic" finite acceleration + Accel = ( 1.0f - m_damping ) * l1 / (dT * dT); + + if( m_bLimitForce ) + { + // max force our arms can exert + float MaxArmAccel = grabber->m_MaxForce / m_physics->GetMass(); + // if player moves object down, gravity will help + if( dir1 * m_physics->GetGravityNormal() > 0 ) + { + idVec3 gravNormal = m_physics->GetGravity(); + float gravMag = gravNormal.Normalize(); + float MaxAccelDown = MaxArmAccel + gravMag; + + // break up desired motion into with gravity and the rest + float DownAccel = Accel * (dir1 * gravNormal); + idVec3 vDownAccel = DownAccel * gravNormal; + idVec3 vOthAccel = Accel * dir1 - vDownAccel; + float OthAccel = vOthAccel.NormalizeFast(); + + OthAccel = idMath::ClampFloat(0.0f, MaxArmAccel, OthAccel ); + DownAccel = idMath::ClampFloat(0.0f, MaxAccelDown, DownAccel ); + // recalculate the vectors now that magnitude is clamped + vDownAccel = DownAccel * gravNormal; + vOthAccel = OthAccel * vOthAccel; + velocity = prevVel * m_damping + (vDownAccel + vOthAccel) * dT; + } + else + { + // we're nice and don't make the player's arms fight gravity + Accel = idMath::ClampFloat(0.0f, MaxArmAccel, Accel ); + velocity = prevVel * m_damping + dir1 * Accel * dT; + } + } + else + { + // unlimited force + velocity = prevVel * m_damping + dir1 * Accel * dT; + } + + if( m_RefEnt.GetEntity() ) + { + // reference frame velocity + velocity += m_RefEnt.GetEntity()->GetPhysics()->GetLinearVelocity(); + + // TODO: Add velocity due to spin angular momentum of reference entity + // e.g., player standing on spinning thing + } + m_physics->SetLinearVelocity( velocity, m_id ); + +// ======================== ANGULAR ========================= + idVec3 Alph, DeltAngVec, RotDir, PrevOmega, Omega; // angular acceleration + float AlphMag, MaxAlph, AlphMod, IAxis, DeltAngLen; + idMat3 DesiredRot; + + // TODO: Make the following into cvars / spawnargs: + float ang_damping = 0.0f; + float max_torque = 100000 * 40; + + // Don't rotate AFs at all for now + if( m_physics->GetSelf()->IsType( idAFEntity_Base::Type ) ) + return; + + // Find the rotation matrix needed to get from current rotation to desired rotation: + DesiredRot = m_dragAxis.Transpose() * m_physics->GetAxis( m_id ); + + // DeltAngVec = DeltAng.ToAngularVelocity(); + DeltAngVec = DesiredRot.ToAngularVelocity(); + RotDir = DeltAngVec; + DeltAngLen = RotDir.Normalize(); + DeltAngLen = DEG2RAD( idMath::AngleNormalize360( RAD2DEG(DeltAngLen) ) ); + DeltAngVec = DeltAngLen * RotDir; + + // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Desired angular velocity is %s\r", DeltAngVec.ToString() ); + // test for FP error + if( (DeltAngLen / dT) <= 0.00001 ) + { + m_physics->SetAngularVelocity( vec3_zero, m_id ); + m_dragAxis = m_physics->GetAxis( m_id ); + return; + } + + // Finite angular acceleration: + Alph = DeltAngVec * (1.0f - ang_damping) / (dT * dT); + AlphMag = Alph.Length(); + + // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Desird angular accel this frame is %s\r", Alph.ToString() ); + + if( m_bLimitForce ) + { + // Find the scalar moment of inertia about this axis: + IAxis = (m_inertiaTensor * RotDir) * RotDir; + + // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: I about axis is %f\r", IAxis ); + + // Calculate max alpha about this axis from max torque + MaxAlph = max_torque / IAxis; + AlphMod = idMath::ClampFloat(0.0f, MaxAlph, AlphMag ); + + // Finally, adjust our angular acceleration vector + Alph *= (AlphMod/AlphMag); + // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Modified alpha is %s\r", Alph.ToString() ); + } + + if( grabber->m_bIsColliding ) + PrevOmega = vec3_zero; + else + PrevOmega = m_physics->GetAngularVelocity( m_id ); + + Omega = PrevOmega * ang_damping + Alph * dT; + + // TODO: Toggle visual debugging with cvar + // gameRenderWorld->DebugLine( colorGreen, COM, (COM + 30 * RotDir), 1); + + // DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Force_Grab Eval: Setting angular velocity to %s\r", Omega.ToString() ); + m_physics->SetAngularVelocity( Omega, m_id ); +} + +/* +================ +CForce_Grab::RemovePhysics +================ +*/ +void CForce_Grab::RemovePhysics( const idPhysics *phys ) { + if ( m_physics == phys ) { + m_physics = NULL; + } +} + +/* +================ +CForce_Grab::GetCenterOfMass +================ +*/ +idVec3 CForce_Grab::GetCenterOfMass( void ) const +{ + return ( m_physics->GetOrigin( m_id ) + m_centerOfMass * m_physics->GetAxis( m_id ) ); +} + + +/* +================ +CForce_Grab::Rotate +================ +*/ +void CForce_Grab::Rotate( const idVec3 &vec, float angle ) +{ + idRotation r; + + r.Set( vec3_origin, vec, angle ); + r.RotatePoint( m_p ); +} + +void CForce_Grab::ApplyDamping( bool bVal ) +{ + m_bApplyDamping = bVal; +} + +void CForce_Grab::LimitForce( bool bVal ) +{ + m_bLimitForce = bVal; +} + +void CForce_Grab::SetRefEnt( idEntity *InputEnt ) +{ + m_RefEnt = InputEnt; +} diff --git a/game/Force_Grab.h b/game/Force_Grab.h new file mode 100755 index 000000000..b3e5cbfec --- /dev/null +++ b/game/Force_Grab.h @@ -0,0 +1,122 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_GRAB_H__ +#define __FORCE_GRAB_H__ + +#include "physics/Force.h" + +/* +=============================================================================== + + Grab force + +=============================================================================== +*/ + +class CForce_Grab : public idForce +{ + public: + CLASS_PROTOTYPE( CForce_Grab ); + + CForce_Grab( void ); + virtual ~CForce_Grab( void ); + // initialize the drag force + void Init( float damping ); + // set physics object being dragged + void SetPhysics( idPhysics *physics, int id, const idVec3 &p ); + // set position to drag towards + void SetDragPosition( const idVec3 &pos ); + // get the position dragged towards + const idVec3 & GetDragPosition( void ) const; + // get the position on the dragged physics object + /** + * Set/get orientation to rotate toward + **/ + void SetDragAxis( const idMat3 &Axis ); + idMat3 GetDragAxis( void ); + + const idVec3 GetDraggedPosition( void ) const; + // Gets the center of mass of the grabbed object + idVec3 GetCenterOfMass( void ) const; + // rotates p about the center of mass of the grabbed object + void Rotate( const idVec3 &vec, float angle ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * Toggle whether the force_grab should use a max force limit + **/ + void LimitForce( bool bVal ); + + /** + * Toggle whether the force_grab should apply damping or not + **/ + void ApplyDamping( bool bVal ); + + /** + * Set the reference entity + **/ + void SetRefEnt( idEntity *ent ); + + public: // common force interface + virtual void Evaluate( int time ); + virtual void RemovePhysics( const idPhysics *phys ); + + protected: + + /** + * Entity to which this drag force is referenced, if any + **/ + idEntityPtr m_RefEnt; + + /** + * If true, limit force or apply damping + **/ + bool m_bLimitForce; + bool m_bApplyDamping; + + // properties + float m_damping; + + // physics object properties + idVec3 m_centerOfMass; + idMat3 m_inertiaTensor; + + // positioning + idPhysics * m_physics; // physics object + idVec3 m_p; // position on clip model + int m_id; // clip model id of physics object + /** + * drag towards this position + **/ + idVec3 m_dragPosition; + /** + * Rotate toward this orientation + **/ + idMat3 m_dragAxis; + + /** + * Origin of the dragged entity in the previous frame + **/ + idVec3 m_prevOrigin; +}; + +#endif /* !__FORCE_GRAB_H__ */ diff --git a/game/FrobButton.cpp b/game/FrobButton.cpp new file mode 100644 index 000000000..4e4dc4d46 --- /dev/null +++ b/game/FrobButton.cpp @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "FrobButton.h" +#include "SndProp.h" + +//=============================================================================== +// CFrobButton +//=============================================================================== + +const idEventDef EV_TDM_Button_Operate("Operate", NULL); + +CLASS_DECLARATION( CBinaryFrobMover, CFrobButton ) + EVENT( EV_TDM_Button_Operate, CFrobButton::Operate) +END_CLASS + +void CFrobButton::Save(idSaveGame *savefile) const +{ + // nothing to save (yet) +} + +void CFrobButton::Restore( idRestoreGame *savefile ) +{ + // nothing to restore (yet) +} + +void CFrobButton::Spawn() +{ +} + +void CFrobButton::Operate() +{ + ToggleOpen(); +} + +void CFrobButton::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) +{ + // grayman #2603 - check "noimpact" flag + if (spawnArgs.GetBool("noimpact")) + { + return; // button can't be hit, so do nothing + } + + // grayman #2603 - ignore impulse from AI + + if (ent->IsType(idAI::Type)) + { + return; + } + + // Check if the impulse is applied in the right direction + if (impulse * m_Translation >= 0) + { + Operate(); + } +} diff --git a/game/FrobButton.h b/game/FrobButton.h new file mode 100644 index 000000000..8dab302cc --- /dev/null +++ b/game/FrobButton.h @@ -0,0 +1,48 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef FROBBUTTON_H +#define FROBBUTTON_H + +/** + * angua: This class is designed specifically for buttons. + * It doesn't do much more than using the BinaryFrobMover functions for now + * but I guess we will want some additional functionality in the future. + */ +class CFrobButton : + public CBinaryFrobMover +{ +public: + + CLASS_PROTOTYPE( CFrobButton ); + + void Spawn(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // this does only call open for now, might be that we want + // a more complex operation algorithm when the button is pressed in the future + virtual void Operate(); + + // Override the base class's ApplyImpulse method + virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse); +}; + +#endif /* FROBBUTTON_H */ diff --git a/DarkMod/FrobDoor.cpp b/game/FrobDoor.cpp similarity index 97% rename from DarkMod/FrobDoor.cpp rename to game/FrobDoor.cpp index fc8b15a49..6381fa0ef 100644 --- a/DarkMod/FrobDoor.cpp +++ b/game/FrobDoor.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2004 Gerhard W. Gruber // Copyright (C) 2004-2011 The Dark Mod Team @@ -16,19 +26,19 @@ static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" #include "BinaryFrobMover.h" -#include "Inventory/Item.h" +#include "Inventory/InventoryItem.h" #include "Inventory/Category.h" #include "FrobDoor.h" #include "FrobDoorHandle.h" -#include "../tools/compilers/aas/aasfile.h" -#include "sndProp.h" +#include "../tools/compilers/aas/AASFile.h" +#include "SndProp.h" #include "StimResponse/StimResponseTimer.h" #include "StimResponse/StimResponse.h" -#include "../game/ai/aas.h" +#include "../game/ai/AAS.h" //=============================================================================== //CFrobDoor diff --git a/DarkMod/FrobDoor.h b/game/FrobDoor.h similarity index 91% rename from DarkMod/FrobDoor.h rename to game/FrobDoor.h index 53c46d389..e8359e1bf 100644 --- a/DarkMod/FrobDoor.h +++ b/game/FrobDoor.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2004 Gerhard W. Gruber // diff --git a/game/FrobDoorHandle.cpp b/game/FrobDoorHandle.cpp new file mode 100644 index 000000000..4caaded13 --- /dev/null +++ b/game/FrobDoorHandle.cpp @@ -0,0 +1,105 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Gerhard W. Gruber +// + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "FrobDoor.h" +#include "FrobDoorHandle.h" + +//=============================================================================== +// CFrobDoorHandle +//=============================================================================== +const idEventDef EV_TDM_Handle_GetDoor( "GetDoor", NULL, 'e' ); + +CLASS_DECLARATION( CFrobHandle, CFrobDoorHandle ) + EVENT( EV_TDM_Handle_GetDoor, CFrobDoorHandle::Event_GetDoor ) +END_CLASS + +CFrobDoorHandle::CFrobDoorHandle() : + m_Door(NULL) +{} + +void CFrobDoorHandle::Save(idSaveGame *savefile) const +{ + savefile->WriteObject(m_Door); +} + +void CFrobDoorHandle::Restore( idRestoreGame *savefile ) +{ + savefile->ReadObject(reinterpret_cast(m_Door)); +} + +void CFrobDoorHandle::Spawn() +{} + +CFrobDoor* CFrobDoorHandle::GetDoor() +{ + return m_Door; +} + +void CFrobDoorHandle::SetDoor(CFrobDoor* door) +{ + m_Door = door; + + // Set the frob master accordingly + SetFrobMaster(m_Door); +} + +void CFrobDoorHandle::Event_GetDoor() +{ + return idThread::ReturnEntity(m_Door); +} + +void CFrobDoorHandle::OnOpenPositionReached() +{ + // The handle is "opened", trigger the door, but only if this is the master handle + if (IsMasterHandle() && m_Door != NULL && !m_Door->IsOpen()) + { + m_Door->OpenDoor(false); + } + + // Let the handle return to its initial position + Close(true); +} + +void CFrobDoorHandle::Tap() +{ + // Invoke the base class first + CFrobHandle::Tap(); + + // Only the master handle is allowed to trigger sounds + if (IsMasterHandle() && m_Door != NULL) + { + // Start the appropriate sound + FrobMoverStartSound(m_Door->IsLocked() ? "snd_tap_locked" : "snd_tap_default"); + } +} + +bool CFrobDoorHandle::DoorIsLocked() +{ + return m_Door ? m_Door->IsLocked() : IsLocked(); +} diff --git a/game/FrobDoorHandle.h b/game/FrobDoorHandle.h new file mode 100644 index 000000000..3675308ac --- /dev/null +++ b/game/FrobDoorHandle.h @@ -0,0 +1,90 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Gerhard W. Gruber +// + +#ifndef FROBDOORHANDLE_H +#define FROBDOORHANDLE_H + +#include "FrobHandle.h" + +class CFrobDoor; + +/** + * CFrobDoorHandle is the complement for CFrobDoors, it specialises + * the generic base class CFrobHandle. + * + * Basically, if a handle is frobbed instead of the actual door, + * all calls are forwarded to its door, so that the player doesn't + * notice the difference. From the player's perspective frobbing + * the handle feels the same as frobbing the door. + * + * When frobbing a door with a handle attached, the event chain is like this: + * Frob > Door::Open > Handle::Tap > Handle moves to open pos > Door::OpenDoor + */ +class CFrobDoorHandle : + public CFrobHandle +{ +public: + CLASS_PROTOTYPE( CFrobDoorHandle ); + + CFrobDoorHandle(); + + void Spawn(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * greebo: This method is invoked directly or it gets called by the attached master. + * For instance, a call to CFrobDoor::Open() gets re-routed here first to let + * the handle animation play before actually trying to open the door. + * + * The Tap() algorithm attempts to rotate the door handle down until and + * calls OpenDoor() when the handle reaches its end rotation/position. + * + * Overrides CFrobHandle::Tap() + */ + virtual void Tap(); + + /** + * Get/set the door associated with this handle. + */ + CFrobDoor* GetDoor(); + void SetDoor(CFrobDoor* door); + + // greebo: Returns TRUE if the associated door is locked (not to confuse with CBinaryFrobMover::IsLocked()) + bool DoorIsLocked(); + +protected: + // Specialise the OpenPositionReached method of BinaryFrobMover to trigger the door's Open() routine + virtual void OnOpenPositionReached(); + + // Script event interface + void Event_GetDoor(); + +protected: + /** + * Pointer to the door that is associated with this handle + **/ + CFrobDoor* m_Door; +}; + +#endif /* FROBDOORHANDLE_H */ diff --git a/DarkMod/FrobHandle.cpp b/game/FrobHandle.cpp similarity index 84% rename from DarkMod/FrobHandle.cpp rename to game/FrobHandle.cpp index d20f26a79..cd3b0b954 100644 --- a/DarkMod/FrobHandle.cpp +++ b/game/FrobHandle.cpp @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" #include "BinaryFrobMover.h" #include "FrobHandle.h" diff --git a/DarkMod/FrobHandle.h b/game/FrobHandle.h similarity index 81% rename from DarkMod/FrobHandle.h rename to game/FrobHandle.h index ae309a09e..96158425a 100644 --- a/DarkMod/FrobHandle.h +++ b/game/FrobHandle.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _FROB_HANDLE_H #define _FROB_HANDLE_H diff --git a/game/FrobLever.cpp b/game/FrobLever.cpp new file mode 100644 index 000000000..88b20c7ab --- /dev/null +++ b/game/FrobLever.cpp @@ -0,0 +1,109 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "FrobLever.h" + +const idEventDef EV_TDM_Lever_Operate( "Operate", NULL ); +const idEventDef EV_TDM_Lever_Switch( "Switch", "d" ); + +CLASS_DECLARATION( CBinaryFrobMover, CFrobLever ) + EVENT( EV_TDM_Lever_Operate, CFrobLever::Event_Operate) + EVENT( EV_TDM_Lever_Switch, CFrobLever::Event_Switch) +END_CLASS + +void CFrobLever::Save(idSaveGame *savefile) const +{ + savefile->WriteBool(m_Latch); +} + +void CFrobLever::Restore( idRestoreGame *savefile ) +{ + savefile->ReadBool(m_Latch); +} + +void CFrobLever::Spawn() +{} + +void CFrobLever::PostSpawn() +{ + // Call the base class first + CBinaryFrobMover::PostSpawn(); + + // Set the latch to TRUE if the mover starts out closed + m_Latch = IsAtClosedPosition(); +} + +void CFrobLever::SwitchState(bool newState) +{ + if (newState) + { + Open(); + } + else + { + Close(); + } +} + +void CFrobLever::Operate() +{ + // Just call the BinaryFrobMover method + ToggleOpen(); +} + +void CFrobLever::OnOpenPositionReached() +{ + // Only allow event firing when the latch is TRUE + if (m_Latch) + { + // Set the latch to false, we've reached the position + m_Latch = false; + + CBinaryFrobMover::OnOpenPositionReached(); + } +} + +void CFrobLever::OnClosedPositionReached() +{ + // Only allow event firing when the latch is FALSE + if (!m_Latch) + { + // Set the latch to false, we've reached the position + m_Latch = true; + + CBinaryFrobMover::OnClosedPositionReached(); + } +} + +void CFrobLever::Event_Operate() +{ + Operate(); +} + +void CFrobLever::Event_Switch(int newState) +{ + SwitchState(newState == 0 ? false : true); +} diff --git a/game/FrobLever.h b/game/FrobLever.h new file mode 100644 index 000000000..aa4c2b72e --- /dev/null +++ b/game/FrobLever.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _FROB_LEVER_H_ +#define _FROB_LEVER_H_ + +/** + * greebo: This class is designed specifically for levers. + * + * It builds on top of the BinaryFrobMover class and overrides + * the relevant virtual event functions to implement proper + * two-state lever behaviour. + */ +class CFrobLever : + public CBinaryFrobMover +{ +public: + + CLASS_PROTOTYPE( CFrobLever ); + + void Spawn(); + + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); + + // Switches the lever state to the given state (true = "open") + void SwitchState(bool newState); + + // Calling Operate() toggles the current state + void Operate(); + +protected: + // Specialise the postspawn event + virtual void PostSpawn(); + + // Specialise the BinaryFrobMover events + virtual void OnOpenPositionReached(); + virtual void OnClosedPositionReached(); + +protected: + // The latch is to keep track of our visited positions. + // For instance, the lever should not trigger the targets at + // its closed position when it wasn't fully opened before. + bool m_Latch; + +private: + // Script interface + void Event_Operate(); + void Event_Switch(int newState); +}; + +#endif /* _FROB_LEVER_H_ */ diff --git a/DarkMod/FrobLock.cpp b/game/FrobLock.cpp similarity index 95% rename from DarkMod/FrobLock.cpp rename to game/FrobLock.cpp index ad2b889cc..3ecdf1540 100644 --- a/DarkMod/FrobLock.cpp +++ b/game/FrobLock.cpp @@ -1,21 +1,31 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" #include "FrobLock.h" -#include "Inventory/Item.h" +#include "Inventory/InventoryItem.h" #include "Inventory/Category.h" const idEventDef EV_TDM_FrobLock_TriggerTargets("EV_TDM_FrobLock_TriggerTargets", NULL); // triggers general targets diff --git a/DarkMod/FrobLock.h b/game/FrobLock.h similarity index 78% rename from DarkMod/FrobLock.h rename to game/FrobLock.h index 62c839cd1..f2c547ca8 100644 --- a/DarkMod/FrobLock.h +++ b/game/FrobLock.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _FROB_LOCK_H_ #define _FROB_LOCK_H_ diff --git a/game/FrobLockHandle.cpp b/game/FrobLockHandle.cpp new file mode 100644 index 000000000..b65b0724d --- /dev/null +++ b/game/FrobLockHandle.cpp @@ -0,0 +1,105 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Gerhard W. Gruber +// + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "FrobLock.h" +#include "FrobLockHandle.h" + +//=============================================================================== +// CFrobLockHandle +//=============================================================================== +const idEventDef EV_TDM_Handle_GetLock( "GetLock", NULL, 'e' ); + +CLASS_DECLARATION( CFrobHandle, CFrobLockHandle ) + EVENT( EV_TDM_Handle_GetLock, CFrobLockHandle::Event_GetLock ) +END_CLASS + +CFrobLockHandle::CFrobLockHandle() : + m_FrobLock(NULL) +{} + +void CFrobLockHandle::Save(idSaveGame *savefile) const +{ + savefile->WriteObject(m_FrobLock); +} + +void CFrobLockHandle::Restore( idRestoreGame *savefile ) +{ + savefile->ReadObject(reinterpret_cast(m_FrobLock)); +} + +void CFrobLockHandle::Spawn() +{} + +CFrobLock* CFrobLockHandle::GetFrobLock() +{ + return m_FrobLock; +} + +void CFrobLockHandle::SetFrobLock(CFrobLock* lock) +{ + m_FrobLock = lock; + + // Set the frob master accordingly + SetFrobMaster(m_FrobLock); +} + +void CFrobLockHandle::Event_GetLock() +{ + return idThread::ReturnEntity(m_FrobLock); +} + +void CFrobLockHandle::OnOpenPositionReached() +{ + // The handle is "opened", trigger the lock, but only if this is the master handle + if (IsMasterHandle() && m_FrobLock != NULL) + { + m_FrobLock->OpenTargets(); + } + + // Let the handle return to its initial position + Close(true); +} + +void CFrobLockHandle::Tap() +{ + // Invoke the base class first + CFrobHandle::Tap(); + + // Only the master handle is allowed to trigger sounds + if (IsMasterHandle() && m_FrobLock != NULL) + { + // Start the appropriate sound + FrobMoverStartSound(m_FrobLock->IsLocked() ? "snd_tap_locked" : "snd_tap_default"); + } +} + +bool CFrobLockHandle::LockIsLocked() +{ + return m_FrobLock ? m_FrobLock->IsLocked() : IsLocked(); +} diff --git a/game/FrobLockHandle.h b/game/FrobLockHandle.h new file mode 100644 index 000000000..ebcdf87f3 --- /dev/null +++ b/game/FrobLockHandle.h @@ -0,0 +1,75 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _FROB_LOCK_HANDLE_H +#define _FROB_LOCK_HANDLE_H + +#include "FrobHandle.h" + +class CFrobLock; + +/** + * CFrobLockHandle is meant to be used as moveable part of a CFrobLock. + * It behaves similarly to the CFrobDoorHandle class, but is specialised for + * use with the static froblock. + */ +class CFrobLockHandle : + public CFrobHandle +{ +public: + CLASS_PROTOTYPE( CFrobLockHandle ); + + CFrobLockHandle(); + + void Spawn(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * greebo: This method is invoked directly or it gets called by the attached master. + * + * Overrides CFrobHandle::Tap() + */ + virtual void Tap(); + + /** + * Get/set the lock associated with this handle. + */ + CFrobLock* GetFrobLock(); + void SetFrobLock(CFrobLock* lock); + + // greebo: Returns TRUE if the associated lock is locked (not to confuse with CBinaryFrobMover::IsLocked()) + bool LockIsLocked(); + +protected: + // Specialise the OpenPositionReached method of BinaryFrobMover to trigger the lock's open event + virtual void OnOpenPositionReached(); + + // Script event interface + void Event_GetLock(); + +protected: + /** + * Pointer to the lock that is associated with this handle + **/ + CFrobLock* m_FrobLock; +}; + +#endif /* _FROB_LOCK_HANDLE_H */ diff --git a/game/Func_Shooter.cpp b/game/Func_Shooter.cpp new file mode 100644 index 000000000..235a3fc4c --- /dev/null +++ b/game/Func_Shooter.cpp @@ -0,0 +1,384 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Func_Shooter.h" +#include "StimResponse/StimResponseCollection.h" + +// Script event interface +const idEventDef EV_ShooterSetState( "shooterSetState", "d" ); +const idEventDef EV_ShooterFireProjectile( "shooterFireProjectile", NULL ); +const idEventDef EV_ShooterGetState( "shooterGetState", NULL, 'd' ); +const idEventDef EV_ShooterSetAmmo( "shooterSetAmmo", "d" ); +const idEventDef EV_ShooterGetAmmo( "shooterGetAmmo", NULL, 'd' ); + +// Event definitions +CLASS_DECLARATION( idStaticEntity, tdmFuncShooter ) + EVENT( EV_Activate, tdmFuncShooter::Event_Activate ) + EVENT( EV_ShooterSetState, tdmFuncShooter::Event_ShooterSetState ) + EVENT( EV_ShooterGetState, tdmFuncShooter::Event_ShooterGetState ) + EVENT( EV_ShooterFireProjectile, tdmFuncShooter::Event_ShooterFireProjectile ) + EVENT( EV_ShooterSetAmmo, tdmFuncShooter::Event_ShooterSetAmmo ) + EVENT( EV_ShooterGetAmmo, tdmFuncShooter::Event_ShooterGetAmmo ) +END_CLASS + +/* +=============== +tdmFuncShooter::tdmFuncShooter +=============== +*/ +tdmFuncShooter::tdmFuncShooter() : + _active(false), + _fireInterval(-1), + _fireIntervalFuzzyness(0), + _startDelay(0), + _endTime(-1), + _lastFireTime(0), + _nextFireTime(0), + _requiredStim(ST_DEFAULT), + _lastStimVisit(0), + _requiredStimTimeOut(0), + _triggerRequired(false), + _lastTriggerVisit(0), + _triggerTimeOut(0), + _ammo(-1), + _useAmmo(false) +{} + +/* +=============== +tdmFuncShooter::Spawn +=============== +*/ +void tdmFuncShooter::Spawn() +{ + _active = !spawnArgs.GetBool("start_off"); + _lastFireTime = 0; + _fireInterval = spawnArgs.GetInt("fire_interval", "-1"); + _fireIntervalFuzzyness = spawnArgs.GetInt("fire_interval_fuzzyness", "0"); + _startDelay = spawnArgs.GetInt("start_delay", "0"); + + idStr reqStimStr = spawnArgs.GetString("required_stim"); + + if (!reqStimStr.IsEmpty()) { + _requiredStim = CStimResponse::GetStimType(reqStimStr); + _requiredStimTimeOut = spawnArgs.GetInt("required_stim_timeout", "5000"); + } + + _triggerRequired = spawnArgs.GetBool("required_trigger"); + _triggerTimeOut = spawnArgs.GetInt("required_trigger_timeout", "4000"); + + _ammo = spawnArgs.GetInt("ammo", "-1"); + _useAmmo = (_ammo != -1); + + if (_active && _fireInterval > 0) + { + BecomeActive( TH_THINK ); + setupNextFireTime(); + _nextFireTime += _startDelay; + + // Set the end time if we have a positive lifetime + int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); + + if (maxLifeTime > 0) + { + _endTime = gameLocal.time + SEC2MS(maxLifeTime); + } + } + + // Always react to stims if a required stim is setup. + if (_requiredStim != ST_DEFAULT) + { + //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("tdmFuncShooter is requiring stim %d\r", _requiredStim); + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + } +} + +/* +=============== +tdmFuncShooter::Save +=============== +*/ +void tdmFuncShooter::Save( idSaveGame *savefile ) const +{ + savefile->WriteBool( _active ); + savefile->WriteInt(_endTime); + savefile->WriteInt( _lastFireTime ); + savefile->WriteInt( _nextFireTime ); + savefile->WriteInt( _fireInterval ); + savefile->WriteInt( _fireIntervalFuzzyness ); + savefile->WriteInt( _startDelay ); + savefile->WriteInt( _requiredStim ); + savefile->WriteInt( _requiredStimTimeOut ); + savefile->WriteInt( _lastStimVisit ); + savefile->WriteInt( _lastTriggerVisit ); + savefile->WriteBool( _triggerRequired ); + savefile->WriteInt( _triggerTimeOut ); + savefile->WriteInt( _ammo ); + savefile->WriteBool( _useAmmo ); +} + +/* +=============== +tdmFuncShooter::Restore +=============== +*/ +void tdmFuncShooter::Restore( idRestoreGame *savefile ) +{ + savefile->ReadBool( _active ); + savefile->ReadInt(_endTime); + savefile->ReadInt( _lastFireTime ); + savefile->ReadInt( _nextFireTime ); + savefile->ReadInt( _fireInterval ); + savefile->ReadInt( _fireIntervalFuzzyness ); + savefile->ReadInt( _startDelay ); + + int stimType; + savefile->ReadInt( stimType ); + _requiredStim = static_cast(stimType); + + savefile->ReadInt( _requiredStimTimeOut ); + savefile->ReadInt( _lastStimVisit ); + savefile->ReadInt( _lastTriggerVisit ); + savefile->ReadBool( _triggerRequired ); + savefile->ReadInt( _triggerTimeOut ); + savefile->ReadInt( _ammo ); + savefile->ReadBool( _useAmmo ); +} + +/* +================ +tdmFuncShooter::Event_Activate +================ +*/ +void tdmFuncShooter::Event_Activate( idEntity *activator ) +{ + if (_triggerRequired) + { + // This shooter requires constant triggering, save the time + _lastTriggerVisit = gameLocal.time; + } + else if ( thinkFlags & TH_THINK ) + { + BecomeInactive( TH_THINK ); + _active = false; + } + else + { + BecomeActive( TH_THINK ); + _active = true; + _ammo = spawnArgs.GetInt("ammo", "-1"); + _lastFireTime = gameLocal.time; + setupNextFireTime(); + _nextFireTime += _startDelay; + + // Set the end time if we have a positive lifetime + int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); + + if (maxLifeTime > 0) + { + _endTime = gameLocal.time + SEC2MS(maxLifeTime); + } + } +} + +void tdmFuncShooter::Event_ShooterGetState() +{ + idThread::ReturnInt(_active ? 1 : 0); +} + +void tdmFuncShooter::Event_ShooterSetState( bool state ) +{ + if (state == _active) return; // Nothing to change + + _active = state; + + if (_active) { + // Reset the ammo on script activation (useAmmo can still override this) + _ammo = spawnArgs.GetInt("ammo", "-1"); + setupNextFireTime(); + _nextFireTime += _startDelay; + + // Set the end time if we have a positive lifetime + int maxLifeTime = spawnArgs.GetInt("max_lifetime", "-1"); + + if (maxLifeTime > 0) + { + _endTime = gameLocal.time + SEC2MS(maxLifeTime); + } + } +} + +void tdmFuncShooter::Event_ShooterFireProjectile() +{ + Fire(); +} + +void tdmFuncShooter::Event_ShooterSetAmmo( int newAmmo ) +{ + _ammo = newAmmo; +} + +void tdmFuncShooter::Event_ShooterGetAmmo() +{ + idThread::ReturnInt(_ammo); +} + +void tdmFuncShooter::setupNextFireTime() +{ + // Calculate the next fire time + int randomness = static_cast( + _fireIntervalFuzzyness*(gameLocal.random.RandomFloat() - 0.5f) + ); + + _nextFireTime = gameLocal.time + _fireInterval + randomness; +} + +void tdmFuncShooter::stimulate(StimType stimId) +{ + if (stimId == _requiredStim && _requiredStim != ST_DEFAULT) + { + //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Stim is visiting at %d\r", gameLocal.time); + // Save the time the stim is visiting + _lastStimVisit = gameLocal.time; + } +} + +void tdmFuncShooter::Fire() +{ + _lastFireTime = gameLocal.time; + + // Spawn a projectile + idStr projectileDef = spawnArgs.GetString("def_projectile"); + if (!projectileDef.IsEmpty()) { + const idDict* projectileDict = gameLocal.FindEntityDefDict(projectileDef); + + idEntity* ent = NULL; + gameLocal.SpawnEntityDef(*projectileDict, &ent); + + if (ent == NULL) + { + gameLocal.Warning("Could not spawn projectile type: %s", projectileDef.c_str()); + return; + } + + if (ent->IsType(idProjectile::Type)) + { + idProjectile* projectile = static_cast(ent); + + // Get the default angle from the entity + float angle = spawnArgs.GetFloat("angle"); + float pitch = spawnArgs.GetFloat("pitch", "0"); + + // Check if the angle should be randomly chosen + if (spawnArgs.GetBool("random_angle")) + { + angle = gameLocal.random.RandomFloat() * 360; + } + + // Check for random pitch angle + if (spawnArgs.GetBool("random_pitch")) + { + pitch = gameLocal.random.RandomFloat() * 180 - 90; + } + + // Calculate the direction from "angle" and "pitch" + idVec3 direction( cos(DEG2RAD(angle)), sin(DEG2RAD(angle)), sin(DEG2RAD(pitch)) ); + direction.NormalizeFast(); + + // Check for a specified velocity on the shooter + float velocity = spawnArgs.GetFloat("velocity", "0"); + + if (velocity <= 0) + { + // Try to get a velocity from the projectile itself + velocity = projectileDict->GetVector("velocity", "0 0 0").Length(); + } + + // Set the brand of the projectile, it should know its roots + projectile->spawnArgs.Set("shooter", name.c_str()); + + // Fire! + projectile->Launch(GetPhysics()->GetOrigin(), direction, direction*velocity); + + if (spawnArgs.GetBool("override_projectile_angles", "0")) + { + // Read the angles from the projectile + idAngles tempAngles(projectile->spawnArgs.GetAngles("angles")); + + // Add the angles of the shoot direction + tempAngles.yaw += angle; + tempAngles.pitch += pitch; + tempAngles.roll += 0; + + // Convert the angles to an axis matrix and store it into the projectile + projectile->GetPhysics()->SetAxis(tempAngles.ToMat3()); + } + + // Check the ammonition + if (_useAmmo && --_ammo <= 0) + { + // Clamp the ammo value to zero + _ammo = 0; + // Inactivate the shooter as the max ammo was specified and has run out + Event_ShooterSetState(false); + } + } + } + + setupNextFireTime(); +} + +void tdmFuncShooter::Think() +{ + if (!_active) return; + + // We're active, so let's check if we have a lifetime + if (_endTime > 0 && gameLocal.time > _endTime) + { + // Lifetime has passed, deactivate ourselves + Event_ShooterSetState(false); + return; + } + + if (_fireInterval > 0 && gameLocal.time > _nextFireTime) + { + // greebo: Check before firing whether we have a required stim + if (_requiredStim != ST_DEFAULT && _lastStimVisit > 0 && + _lastStimVisit + _requiredStimTimeOut >= gameLocal.time) + { + // We have a required stim, but it was not too far in the past => fire + Fire(); + } + else if (_triggerRequired && _lastTriggerVisit > 0 && + _lastTriggerVisit + _triggerTimeOut >= gameLocal.time) + { + // Required constant triggering, last trigger was not too long ago => fire + Fire(); + } + else if (_requiredStim == ST_DEFAULT && !_triggerRequired) + { + // No required stim and no required trigger, fire away + Fire(); + } + } +} diff --git a/game/Func_Shooter.h b/game/Func_Shooter.h new file mode 100644 index 000000000..baef60ebd --- /dev/null +++ b/game/Func_Shooter.h @@ -0,0 +1,121 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_FUNC_SHOOTER_H__ +#define __GAME_FUNC_SHOOTER_H__ + +#include "StimResponse/StimResponse.h" + +/** +* greebo: This entity fires projectiles in (periodic) intervals. +* All the key paramaters can be specified in the according entityDef. +*/ +class tdmFuncShooter : + public idStaticEntity +{ +public: + CLASS_PROTOTYPE(tdmFuncShooter); + + // Constructor + tdmFuncShooter(); + + // Needed on game save/load + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // Gets called when this entity is actually being spawned + void Spawn(); + + // Event interface + void Event_Activate( idEntity *activator ); + void Event_ShooterSetState( bool state ); + void Event_ShooterGetState(); + void Event_ShooterSetAmmo( int newAmmo ); + void Event_ShooterGetAmmo(); + void Event_ShooterFireProjectile(); + + // Overload the derived idEntity::Think method so that this object gets called each frame + virtual void Think(); + + /** + * Fires a projectile and sets the timer to gameLocal.time. + */ + virtual void Fire(); + + /** + * Tries to stimulate this class with the given stimType. + * This checks whether the incoming stim is the required one and + * activated the shooter if this is the case. + */ + virtual void stimulate(StimType stimId); + +private: + // Calculates the next time this shooter should fire + void setupNextFireTime(); + + // is TRUE if the shooter can fire projectiles + bool _active; + + // The time interval between fires in ms + int _fireInterval; + + // This is the maximum tolerance the fireInterval can have + int _fireIntervalFuzzyness; + + // Start delay in ms + int _startDelay; + + // If positive, this is the game time beyond which we're becoming automatically inactive. + int _endTime; + + // The last time the shooter fired a projectile + int _lastFireTime; + + // The next game time the shooter should fire + int _nextFireTime; + + // This is != (ST_DEFAULT == -1) if a stim is required in order to stay active + StimType _requiredStim; + + // This is set to the last known time the requiredStim has visited this entity + int _lastStimVisit; + + // This specifies the time that can pass before the shooter becomes inactive + // if the requiredStim is not present. + int _requiredStimTimeOut; + + // TRUE if periodic triggering is needed for this shooter to stay active. + bool _triggerRequired; + + // This is set to the last known time the requiredStim has visited this entity + int _lastTriggerVisit; + + // If this time has passed without a trigger event, the shooter ceases to fire. + int _triggerTimeOut; + + // The maximum number of projectiles (ammo) for this shooter. + // A value of -1 means infinite ammonition + int _ammo; + + // This is true if the _ammo value should be considered or not + bool _useAmmo; +}; + +#endif /* !__GAME_FUNC_SHOOTER_H__ */ + diff --git a/game/Game.h b/game/Game.h new file mode 100644 index 000000000..050a72fb2 --- /dev/null +++ b/game/Game.h @@ -0,0 +1,371 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_H__ +#define __GAME_H__ + +#if defined(__linux__) || defined(MACOS_X) +#include "../idlib/Lib.h" +#include "../sound/sound.h" +#endif + +/* +=============================================================================== + + Public game interface with methods to run the game. + +=============================================================================== +*/ + +// default scripts +#define SCRIPT_DEFAULTDEFS "script/tdm_defs.script" +#define SCRIPT_DEFAULT "script/tdm_main.script" +#define SCRIPT_DEFAULTFUNC "tdm_main" + +typedef struct { + char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc + int consistencyHash; // used to check for network game divergence + int health; + int heartRate; + int stamina; + int combat; + bool syncNextGameFrame; // used when cinematics are skipped to prevent session from simulating several game frames to + // keep the game time in sync with real time +} gameReturn_t; + +typedef enum { + ALLOW_YES = 0, + ALLOW_BADPASS, // core will prompt for password and connect again + ALLOW_NOTYET, // core will wait with transmitted message + ALLOW_NO // core will abort with transmitted message +} allowReply_t; + +typedef enum { + ESC_IGNORE = 0, // do nothing + ESC_MAIN, // start main menu GUI + ESC_GUI // set an explicit GUI +} escReply_t; + +#define TIME_GROUP1 0 +#define TIME_GROUP2 1 + +class idRenderWorld; +class idSoundWorld; +class usercmd_t; +class idUserInterface; + +class idGame { +public: + virtual ~idGame() {} + + // Initialize the game for the first time. + virtual void Init( void ) = 0; + + // Shut down the entire game. + virtual void Shutdown( void ) = 0; + + // Set the local client number. Distinguishes listen ( == 0 ) / dedicated ( == -1 ) + virtual void SetLocalClient( int clientNum ) = 0; + + // Sets the user info for a client. + // if canModify is true, the game can modify the user info in the returned dictionary pointer, server will forward the change back + // canModify is never true on network client + virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ) = 0; + + // Retrieve the game's userInfo dict for a client. + virtual const idDict * GetUserInfo( int clientNum ) = 0; + + // The game gets a chance to alter userinfo before they are emitted to server. + virtual void ThrottleUserInfo( void ) = 0; + + // Sets the serverinfo at map loads and when it changes. + virtual void SetServerInfo( const idDict &serverInfo ) = 0; + + // The session calls this before moving the single player game to a new level. + virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0; + + // The session calls this right before a new level is loaded. + virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) = 0; + + // Loads a map and spawns all the entities. + virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) = 0; + + // Loads a map from a savegame file. + virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ) = 0; + + // Saves the current game state, the session may have written some data to the file already. + virtual void SaveGame( idFile *saveGameFile ) = 0; + + // Shut down the current map. + virtual void MapShutdown( void ) = 0; + + // Caches media referenced from in key/value pairs in the given dictionary. + virtual void CacheDictionaryMedia( const idDict *dict ) = 0; + + // Spawns the player entity to be used by the client. + virtual void SpawnPlayer( int clientNum ) = 0; + + // Runs a game frame, may return a session command for level changing, etc + virtual gameReturn_t RunFrame( const usercmd_t *clientCmds ) = 0; + + // Makes rendering and sound system calls to display for a given clientNum. + virtual bool Draw( int clientNum ) = 0; + + // Let the game do it's own UI when ESCAPE is used + virtual escReply_t HandleESC( idUserInterface **gui ) = 0; + + // get the games menu if appropriate ( multiplayer ) + virtual idUserInterface * StartMenu() = 0; + + // When the game is running it's own UI fullscreen, GUI commands are passed through here + // return NULL once the fullscreen UI mode should stop, or "main" to go to main menu + virtual const char * HandleGuiCommands( const char *menuCommand ) = 0; + + // main menu commands not caught in the engine are passed here + virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) = 0; + + // Early check to deny connect. + virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] ) = 0; + + // Connects a client. + virtual void ServerClientConnect( int clientNum, const char *guid ) = 0; + + // Spawns the player entity to be used by the client. + virtual void ServerClientBegin( int clientNum ) = 0; + + // Disconnects a client and removes the player entity from the game. + virtual void ServerClientDisconnect( int clientNum ) = 0; + + // Writes initial reliable messages a client needs to recieve when first joining the game. + virtual void ServerWriteInitialReliableMessages( int clientNum ) = 0; + + // Writes a snapshot of the server game state for the given client. + virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ) = 0; + + // Patches the network entity states at the server with a snapshot for the given client. + virtual bool ServerApplySnapshot( int clientNum, int sequence ) = 0; + + // Processes a reliable message from a client. + virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0; + + // Reads a snapshot and updates the client game state. + virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) = 0; + + // Patches the network entity states at the client with a snapshot. + virtual bool ClientApplySnapshot( int clientNum, int sequence ) = 0; + + // Processes a reliable message from the server. + virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0; + + // Runs prediction on entities at the client. + virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ) = 0; + + // Used to manage divergent time-lines + virtual void SelectTimeGroup( int timeGroup ) = 0; + virtual int GetTimeGroupTime( int timeGroup ) = 0; + + virtual void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ) = 0; + + // Returns a summary of stats for a given client + virtual void GetClientStats( int clientNum, char *data, const int len ) = 0; + + // Switch a player to a particular team + virtual void SwitchTeam( int clientNum, int team ) = 0; + + virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) = 0; + + virtual void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) = 0; +}; + +extern idGame * game; + + +/* +=============================================================================== + + Public game interface with methods for in-game editing. + +=============================================================================== +*/ + +class idSoundEmitter; +class idSoundShader; + +struct refSound_t { + idSoundEmitter * referenceSound; // this is the interface to the sound system, created + // with idSoundWorld::AllocSoundEmitter() when needed + idVec3 origin; + int listenerId; // SSF_PRIVATE_SOUND only plays if == listenerId from PlaceListener + // no spatialization will be performed if == listenerID + const idSoundShader * shader; // this really shouldn't be here, it is a holdover from single channel behavior + float diversity; // 0.0 to 1.0 value used to select which + // samples in a multi-sample list from the shader are used + bool waitfortrigger; // don't start it at spawn time + soundShaderParms_t parms; // override volume, flags, etc +}; + +enum { + TEST_PARTICLE_MODEL = 0, + TEST_PARTICLE_IMPACT, + TEST_PARTICLE_MUZZLE, + TEST_PARTICLE_FLIGHT, + TEST_PARTICLE_SELECTED +}; + +class idEntity; +class idMD5Anim; +typedef struct renderLight_s renderLight_t; +typedef struct renderEntity_s renderEntity_t; +class idRenderModel; + +// FIXME: this interface needs to be reworked but it properly separates code for the time being +class idGameEdit { +public: + virtual ~idGameEdit( void ) {} + + // These are the canonical idDict to parameter parsing routines used by both the game and tools. + virtual void ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight ); + virtual void ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity ); + virtual void ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound ); + + // Animation system calls for non-game based skeletal rendering. + virtual idRenderModel * ANIM_GetModelFromEntityDef( const char *classname ); + virtual const idVec3 &ANIM_GetModelOffsetFromEntityDef( const char *classname ); + virtual idRenderModel * ANIM_GetModelFromEntityDef( const idDict *args ); + virtual idRenderModel * ANIM_GetModelFromName( const char *modelName ); + virtual const idMD5Anim * ANIM_GetAnimFromEntityDef( const char *classname, const char *animname ); + virtual int ANIM_GetNumAnimsFromEntityDef( const idDict *args ); + virtual const char * ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum ); + virtual const idMD5Anim * ANIM_GetAnim( const char *fileName ); + virtual int ANIM_GetLength( const idMD5Anim *anim ); + virtual int ANIM_GetNumFrames( const idMD5Anim *anim ); + virtual void ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset ); + virtual idRenderModel * ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset ); + + // Articulated Figure calls for AF editor and Radiant. + virtual bool AF_SpawnEntity( const char *fileName ); + virtual void AF_UpdateEntities( const char *fileName ); + virtual void AF_UndoChanges( void ); + virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet ); + + + // Entity selection. + virtual void ClearEntitySelection( void ); + virtual int GetSelectedEntities( idEntity *list[], int max ); + virtual void AddSelectedEntity( idEntity *ent ); + + // Selection methods + virtual void TriggerSelected(); + + // Entity defs and spawning. + virtual const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const; + virtual void SpawnEntityDef( const idDict &args, idEntity **ent ); + virtual idEntity * FindEntity( const char *name ) const; + virtual const char * GetUniqueEntityName( const char *classname ) const; + + // Entity methods. + virtual void EntityGetOrigin( idEntity *ent, idVec3 &org ) const; + virtual void EntityGetAxis( idEntity *ent, idMat3 &axis ) const; + virtual void EntitySetOrigin( idEntity *ent, const idVec3 &org ); + virtual void EntitySetAxis( idEntity *ent, const idMat3 &axis ); + virtual void EntityTranslate( idEntity *ent, const idVec3 &org ); + virtual const idDict * EntityGetSpawnArgs( idEntity *ent ) const; + virtual void EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict ); + virtual void EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs ); + virtual void EntityUpdateVisuals( idEntity *ent ); + virtual void EntitySetModel( idEntity *ent, const char *val ); + virtual void EntityStopSound( idEntity *ent ); + virtual void EntityDelete( idEntity *ent ); + virtual void EntitySetColor( idEntity *ent, const idVec3 color ); + + // Player methods. + virtual bool PlayerIsValid() const; + virtual void PlayerGetOrigin( idVec3 &org ) const; + virtual void PlayerGetAxis( idMat3 &axis ) const; + virtual void PlayerGetViewAngles( idAngles &angles ) const; + virtual void PlayerGetEyePosition( idVec3 &org ) const; + + // In game map editing support. + virtual const idDict * MapGetEntityDict( const char *name ) const; + virtual void MapSave( const char *path = NULL ) const; + virtual void MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const ; + virtual void MapCopyDictToEntity( const char *name, const idDict *dict ) const; + virtual int MapGetUniqueMatchingKeyVals( const char *key, const char *list[], const int max ) const; + virtual void MapAddEntity( const idDict *dict ) const; + virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const; + virtual void MapRemoveEntity( const char *name ) const; + virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const; + +}; + +extern idGameEdit * gameEdit; + + +/* +=============================================================================== + + Game API. + +=============================================================================== +*/ + +const int GAME_API_VERSION = 8; + +class idCmdSystem; +class idNetworkSystem; +class idRenderSystem; +class idSoundSystem; +class idRenderModelManager; +class idUserInterfaceManager; +class idDeclManager; +class idAASFileManager; +class idCollisionModelManager; + +typedef struct { + + int version; // API version + idSys * sys; // non-portable system services + idCommon * common; // common + idCmdSystem * cmdSystem; // console command system + idCVarSystem * cvarSystem; // console variable system + idFileSystem * fileSystem; // file system + idNetworkSystem * networkSystem; // network system + idRenderSystem * renderSystem; // render system + idSoundSystem * soundSystem; // sound system + idRenderModelManager * renderModelManager; // render model manager + idUserInterfaceManager * uiManager; // user interface manager + idDeclManager * declManager; // declaration manager + idAASFileManager * AASFileManager; // AAS file manager + idCollisionModelManager * collisionModelManager; // collision model manager + +} gameImport_t; + +typedef struct { + + int version; // API version + idGame * game; // interface to run the game + idGameEdit * gameEdit; // interface for in-game editing + +} gameExport_t; + +extern "C" { +typedef gameExport_t * (*GetGameAPI_t)( gameImport_t *import ); +} + +#endif /* !__GAME_H__ */ diff --git a/game/GameEdit.cpp b/game/GameEdit.cpp new file mode 100644 index 000000000..a5861b695 --- /dev/null +++ b/game/GameEdit.cpp @@ -0,0 +1,1140 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "Emitter.h" + +/* +=============================================================================== + + Ingame cursor. + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idCursor3D ) +END_CLASS + +/* +=============== +idCursor3D::idCursor3D +=============== +*/ +idCursor3D::idCursor3D( void ) { + draggedPosition.Zero(); +} + +/* +=============== +idCursor3D::~idCursor3D +=============== +*/ +idCursor3D::~idCursor3D( void ) { +} + +/* +=============== +idCursor3D::Spawn +=============== +*/ +void idCursor3D::Spawn( void ) { +} + +/* +=============== +idCursor3D::Present +=============== +*/ +void idCursor3D::Present( void ) { + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { + return; + } + BecomeInactive( TH_UPDATEVISUALS ); + + const idVec3 &origin = GetPhysics()->GetOrigin(); + const idMat3 &axis = GetPhysics()->GetAxis(); + + gameRenderWorld->DebugArrow( colorYellow, origin + axis[1] * -5.0f + axis[2] * 5.0f, origin, 2 ); + gameRenderWorld->DebugArrow( colorRed, origin, draggedPosition, 2 ); +} + +/* +=============== +idCursor3D::Think +=============== +*/ +void idCursor3D::Think( void ) { + if ( thinkFlags & TH_THINK ) { + drag.Evaluate( gameLocal.time ); + } + Present(); +} + + +/* +=============================================================================== + + Allows entities to be dragged through the world with physics. + +=============================================================================== +*/ + +#define MAX_DRAG_TRACE_DISTANCE 2048.0f + +/* +============== +idDragEntity::idDragEntity +============== +*/ +idDragEntity::idDragEntity( void ) { + cursor = NULL; + Clear(); +} + +/* +============== +idDragEntity::~idDragEntity +============== +*/ +idDragEntity::~idDragEntity( void ) { + StopDrag(); + selected = NULL; + delete cursor; + cursor = NULL; +} + + +/* +============== +idDragEntity::Clear +============== +*/ +void idDragEntity::Clear() { + dragEnt = NULL; + joint = INVALID_JOINT; + id = 0; + localEntityPoint.Zero(); + localPlayerPoint.Zero(); + bodyName.Clear(); + selected = NULL; +} + +/* +============== +idDragEntity::StopDrag +============== +*/ +void idDragEntity::StopDrag( void ) { + dragEnt = NULL; + if ( cursor ) { + cursor->BecomeInactive( TH_THINK ); + } +} + +/* +============== +idDragEntity::Update +============== +*/ +void idDragEntity::Update( idPlayer *player ) { + idVec3 viewPoint, origin; + idMat3 viewAxis, axis; + trace_t trace; + idEntity *newEnt; + idAngles angles; + jointHandle_t newJoint(INVALID_JOINT); + idStr newBodyName; + + player->GetViewPos( viewPoint, viewAxis ); + + // if no entity selected for dragging + if ( !dragEnt.GetEntity() ) { + + if ( player->usercmd.buttons & BUTTON_ATTACK ) { + + gameLocal.clip.TracePoint( trace, viewPoint, viewPoint + viewAxis[0] * MAX_DRAG_TRACE_DISTANCE, (CONTENTS_SOLID|CONTENTS_RENDERMODEL|CONTENTS_BODY), player ); + if ( trace.fraction < 1.0f ) { + + newEnt = gameLocal.entities[ trace.c.entityNum ]; + if ( newEnt ) { + + // Ish: We sometimes want to select things that are bound + /* + if ( newEnt->GetBindMaster() ) { + if ( newEnt->GetBindJoint() ) { + trace.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( newEnt->GetBindJoint() ); + } else { + trace.c.id = newEnt->GetBindBody(); + } + newEnt = newEnt->GetBindMaster(); + } + */ + + if ( newEnt->IsType( idAFEntity_Base::Type ) && static_cast(newEnt)->IsActiveAF() ) { + idAFEntity_Base *af = static_cast(newEnt); + + // joint being dragged + newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ); + // get the body id from the trace model id which might be a joint handle + trace.c.id = af->BodyForClipModelId( trace.c.id ); + // get the name of the body being dragged + newBodyName = af->GetAFPhysics()->GetBody( trace.c.id )->GetName(); + + } else if ( !newEnt->IsType( idWorldspawn::Type ) ) { + + if ( trace.c.id < 0 ) { + newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ); + } else { + newJoint = INVALID_JOINT; + } + newBodyName = ""; + + } else { + + newJoint = INVALID_JOINT; + newEnt = NULL; + } + } + if ( newEnt ) { + dragEnt = newEnt; + selected = newEnt; + joint = newJoint; + id = trace.c.id; + bodyName = newBodyName; + + if ( !cursor ) { + cursor = ( idCursor3D * )gameLocal.SpawnEntityType( idCursor3D::Type ); + } + + idPhysics *phys = dragEnt.GetEntity()->GetPhysics(); + localPlayerPoint = ( trace.c.point - viewPoint ) * viewAxis.Transpose(); + origin = phys->GetOrigin( id ); + axis = phys->GetAxis( id ); + localEntityPoint = ( trace.c.point - origin ) * axis.Transpose(); + + cursor->drag.Init( g_dragDamping.GetFloat() ); + cursor->drag.SetPhysics( phys, id, localEntityPoint ); + cursor->Show(); + + if ( phys->IsType( idPhysics_AF::Type ) || + phys->IsType( idPhysics_RigidBody::Type ) || + phys->IsType( idPhysics_Monster::Type ) ) { + cursor->BecomeActive( TH_THINK ); + } + } + } + } + } + + // if there is an entity selected for dragging + idEntity *drag = dragEnt.GetEntity(); + if ( drag ) { + + if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) { + StopDrag(); + return; + } + + cursor->SetOrigin( viewPoint + localPlayerPoint * viewAxis ); + cursor->SetAxis( viewAxis ); + + cursor->drag.SetDragPosition( cursor->GetPhysics()->GetOrigin() ); + + renderEntity_t *renderEntity = drag->GetRenderEntity(); + idAnimator *dragAnimator = drag->GetAnimator(); + + if ( joint != INVALID_JOINT && renderEntity && dragAnimator ) { + dragAnimator->GetJointTransform( joint, gameLocal.time, cursor->draggedPosition, axis ); + cursor->draggedPosition = renderEntity->origin + cursor->draggedPosition * renderEntity->axis; + gameRenderWorld->DrawText( va( "%s\n%s\n%s, %s", drag->GetName(), drag->GetType()->classname, dragAnimator->GetJointName( joint ), bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 ); + } else { + cursor->draggedPosition = cursor->GetPhysics()->GetOrigin(); + gameRenderWorld->DrawText( va( "%s\n%s\n%s", drag->GetName(), drag->GetType()->classname, bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 ); + } + } + + // if there is a selected entity + if ( selected.GetEntity() && g_dragShowSelection.GetBool() ) { + // draw the bbox of the selected entity + renderEntity_t *renderEntity = selected.GetEntity()->GetRenderEntity(); + if ( renderEntity ) { + gameRenderWorld->DebugBox( colorYellow, idBox( renderEntity->bounds, renderEntity->origin, renderEntity->axis ) ); + } + } +} + +/* +============== +idDragEntity::SetSelected +============== +*/ +void idDragEntity::SetSelected( idEntity *ent ) { + selected = ent; + StopDrag(); +} + +/* +============== +idDragEntity::DeleteSelected +============== +*/ +void idDragEntity::DeleteSelected( void ) { + delete selected.GetEntity(); + selected = NULL; + StopDrag(); +} + +/* +============== +idDragEntity::BindSelected +============== +*/ +void idDragEntity::BindSelected( void ) { + int num, largestNum; + idLexer lexer; + idToken type, bodyName; + idStr key, value, bindBodyName; + const idKeyValue *kv; + idAFEntity_Base *af; + + af = static_cast(dragEnt.GetEntity()); + + if ( !af || !af->IsType( idAFEntity_Base::Type ) || !af->IsActiveAF() ) { + return; + } + + bindBodyName = af->GetAFPhysics()->GetBody( id )->GetName(); + largestNum = 1; + + // parse all the bind constraints + kv = af->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); + while ( kv ) { + key = kv->GetKey(); + key.Strip( "bindConstraint " ); + if ( sscanf( key, "bind%d", &num ) ) { + if ( num >= largestNum ) { + largestNum = num + 1; + } + } + + lexer.LoadMemory( kv->GetValue(), kv->GetValue().Length(), kv->GetKey() ); + lexer.ReadToken( &type ); + lexer.ReadToken( &bodyName ); + lexer.FreeSource(); + + // if there already exists a bind constraint for this body + if ( bodyName.Icmp( bindBodyName ) == 0 ) { + // delete the bind constraint + af->spawnArgs.Delete( kv->GetKey() ); + kv = NULL; + } + + kv = af->spawnArgs.MatchPrefix( "bindConstraint ", kv ); + } + + sprintf( key, "bindConstraint bind%d", largestNum ); + sprintf( value, "ballAndSocket %s %s", bindBodyName.c_str(), af->GetAnimator()->GetJointName( joint ) ); + + af->spawnArgs.Set( key, value ); + af->spawnArgs.Set( "bind", "worldspawn" ); + af->Bind( gameLocal.world, true ); +} + +/* +============== +idDragEntity::UnbindSelected +============== +*/ +void idDragEntity::UnbindSelected( void ) { + const idKeyValue *kv; + idAFEntity_Base *af; + + af = static_cast(selected.GetEntity()); + + if ( !af || !af->IsType( idAFEntity_Base::Type ) || !af->IsActiveAF() ) { + return; + } + + // unbind the selected entity + af->Unbind(); + + // delete all the bind constraints + kv = selected.GetEntity()->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); + while ( kv ) { + selected.GetEntity()->spawnArgs.Delete( kv->GetKey() ); + kv = selected.GetEntity()->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); + } + + // delete any bind information + af->spawnArgs.Delete( "bind" ); + af->spawnArgs.Delete( "bindToJoint" ); + af->spawnArgs.Delete( "bindToBody" ); +} + + +/* +=============================================================================== + + Handles ingame entity editing. + +=============================================================================== +*/ + +/* +============== +idEditEntities::idEditEntities +============== +*/ +idEditEntities::idEditEntities( void ) { + selectableEntityClasses.Clear(); + nextSelectTime = 0; +} + +/* +============= +idEditEntities::SelectEntity +============= +*/ +bool idEditEntities::SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip ) { + idVec3 end; + idEntity *ent; + + if ( !g_editEntityMode.GetInteger() || selectableEntityClasses.Num() == 0 ) { + return false; + } + + if ( gameLocal.time < nextSelectTime ) { + return true; + } + nextSelectTime = gameLocal.time + 300; + + end = origin + dir * 4096.0f; + + ent = NULL; + for ( int i = 0; i < selectableEntityClasses.Num(); i++ ) { + ent = gameLocal.FindTraceEntity( origin, end, *selectableEntityClasses[i].typeInfo, skip ); + if ( ent ) { + break; + } + } + if ( ent ) { + ClearSelectedEntities(); + if ( EntityIsSelectable( ent ) ) { + AddSelectedEntity( ent ); + gameLocal.Printf( "entity #%d: %s '%s'\n", ent->entityNumber, ent->GetClassname(), ent->name.c_str() ); + ent->ShowEditingDialog(); + return true; + } + } + return false; +} + +/* +============= +idEditEntities::AddSelectedEntity +============= +*/ +void idEditEntities::AddSelectedEntity(idEntity *ent) { + ent->fl.selected = true; + selectedEntities.AddUnique(ent); +} + +/* +============== +idEditEntities::RemoveSelectedEntity +============== +*/ +void idEditEntities::RemoveSelectedEntity( idEntity *ent ) { + if ( selectedEntities.Find( ent ) ) { + selectedEntities.Remove( ent ); + } +} + +/* +============= +idEditEntities::ClearSelectedEntities +============= +*/ +void idEditEntities::ClearSelectedEntities() { + int i, count; + + count = selectedEntities.Num(); + for ( i = 0; i < count; i++ ) { + selectedEntities[i]->fl.selected = false; + } + selectedEntities.Clear(); +} + + +/* +============= +idEditEntities::EntityIsSelectable +============= +*/ +bool idEditEntities::EntityIsSelectable( idEntity *ent, idVec4 *color, idStr *text ) { + for ( int i = 0; i < selectableEntityClasses.Num(); i++ ) { + if ( ent->GetType() == selectableEntityClasses[i].typeInfo ) { + if ( text ) { + *text = selectableEntityClasses[i].textKey; + } + if ( color ) { + if ( ent->fl.selected ) { + *color = colorRed; + } else { + switch( i ) { + case 1 : + *color = colorYellow; + break; + case 2 : + *color = colorBlue; + break; + default: + *color = colorGreen; + } + } + } + return true; + } + } + return false; +} + +/* +============= +idEditEntities::DisplayEntities +============= +*/ +void idEditEntities::DisplayEntities( void ) { + idEntity *ent; + + if ( !gameLocal.GetLocalPlayer() ) { + return; + } + + selectableEntityClasses.Clear(); + selectedTypeInfo_t sit; + + switch( g_editEntityMode.GetInteger() ) { + case 1: + sit.typeInfo = &idLight::Type; + sit.textKey = "texture"; + selectableEntityClasses.Append( sit ); + break; + case 2: + sit.typeInfo = &idSound::Type; + sit.textKey = "s_shader"; + selectableEntityClasses.Append( sit ); + sit.typeInfo = &idLight::Type; + sit.textKey = "texture"; + selectableEntityClasses.Append( sit ); + break; + case 3: + sit.typeInfo = &idAFEntity_Base::Type; + sit.textKey = "articulatedFigure"; + selectableEntityClasses.Append( sit ); + break; + case 4: + sit.typeInfo = &idFuncEmitter::Type; + sit.textKey = "model"; + selectableEntityClasses.Append( sit ); + break; + case 5: + sit.typeInfo = &idAI::Type; + sit.textKey = "name"; + selectableEntityClasses.Append( sit ); + break; + case 6: + sit.typeInfo = &idEntity::Type; + sit.textKey = "name"; + selectableEntityClasses.Append( sit ); + break; + case 7: + sit.typeInfo = &idEntity::Type; + sit.textKey = "model"; + selectableEntityClasses.Append( sit ); + break; + default: + return; + } + + idBounds viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); + idBounds viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); + idMat3 axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); + + viewBounds.ExpandSelf( 512 ); + viewTextBounds.ExpandSelf( 128 ); + + idStr textKey; + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + + idVec4 color; + + textKey = ""; + if ( !EntityIsSelectable( ent, &color, &textKey ) ) { + continue; + } + + bool drawArrows = false; + if ( ent->GetType() == &idAFEntity_Base::Type ) { + if ( !static_cast(ent)->IsActiveAF() ) { + continue; + } + } else if ( ent->GetType() == &idSound::Type ) { + if ( ent->fl.selected ) { + drawArrows = true; + } + const idSoundShader * ss = declManager->FindSound( ent->spawnArgs.GetString( textKey ) ); + if ( ss->HasDefaultSound() || ss->base->GetState() == DS_DEFAULTED ) { + color.Set( 1.0f, 0.0f, 1.0f, 1.0f ); + } + } else if ( ent->GetType() == &idFuncEmitter::Type ) { + if ( ent->fl.selected ) { + drawArrows = true; + } + } + + if ( !viewBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { + continue; + } + + gameRenderWorld->DebugBounds( color, idBounds( ent->GetPhysics()->GetOrigin() ).Expand( 8 ) ); + if ( drawArrows ) { + idVec3 start = ent->GetPhysics()->GetOrigin(); + idVec3 end = start + idVec3( 1, 0, 0 ) * 20.0f; + gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); + gameRenderWorld->DrawText( "x+", end + idVec3( 4, 0, 0 ), 0.15f, colorWhite, axis ); + end = start + idVec3( 1, 0, 0 ) * -20.0f; + gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); + gameRenderWorld->DrawText( "x-", end + idVec3( -4, 0, 0 ), 0.15f, colorWhite, axis ); + end = start + idVec3( 0, 1, 0 ) * +20.0f; + gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); + gameRenderWorld->DrawText( "y+", end + idVec3( 0, 4, 0 ), 0.15f, colorWhite, axis ); + end = start + idVec3( 0, 1, 0 ) * -20.0f; + gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); + gameRenderWorld->DrawText( "y-", end + idVec3( 0, -4, 0 ), 0.15f, colorWhite, axis ); + end = start + idVec3( 0, 0, 1 ) * +20.0f; + gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); + gameRenderWorld->DrawText( "z+", end + idVec3( 0, 0, 4 ), 0.15f, colorWhite, axis ); + end = start + idVec3( 0, 0, 1 ) * -20.0f; + gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); + gameRenderWorld->DrawText( "z-", end + idVec3( 0, 0, -4 ), 0.15f, colorWhite, axis ); + } + + if ( textKey.Length() ) { + const char *text = ent->spawnArgs.GetString( textKey ); + if ( viewTextBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { + gameRenderWorld->DrawText( text, ent->GetPhysics()->GetOrigin() + idVec3(0, 0, 12), 0.25, colorWhite, axis, 1 ); + } + } + } +} + + +/* +=============================================================================== + + idGameEdit + +=============================================================================== +*/ + +idGameEdit gameEditLocal; +idGameEdit * gameEdit = &gameEditLocal; + + +/* +============= +idGameEdit::GetSelectedEntities +============= +*/ +int idGameEdit::GetSelectedEntities( idEntity *list[], int max ) { + int num = 0; + idEntity *ent; + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->fl.selected ) { + list[num++] = ent; + if ( num >= max ) { + break; + } + } + } + return num; +} + +/* +============= +idGameEdit::TriggerSelected +============= +*/ +void idGameEdit::TriggerSelected() { + idEntity *ent; + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->fl.selected ) { + ent->ProcessEvent( &EV_Activate, gameLocal.GetLocalPlayer() ); + } + } +} + +/* +================ +idGameEdit::ClearEntitySelection +================ +*/ +void idGameEdit::ClearEntitySelection() { + idEntity *ent; + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + ent->fl.selected = false; + } + gameLocal.editEntities->ClearSelectedEntities(); +} + +/* +================ +idGameEdit::AddSelectedEntity +================ +*/ +void idGameEdit::AddSelectedEntity( idEntity *ent ) { + if ( ent ) { + gameLocal.editEntities->AddSelectedEntity( ent ); + } +} + +/* +================ +idGameEdit::FindEntityDefDict +================ +*/ +const idDict *idGameEdit::FindEntityDefDict( const char *name, bool makeDefault ) const { + return gameLocal.FindEntityDefDict( name, makeDefault ); +} + +/* +================ +idGameEdit::SpawnEntityDef +================ +*/ +void idGameEdit::SpawnEntityDef( const idDict &args, idEntity **ent ) { + gameLocal.SpawnEntityDef( args, ent ); +} + +/* +================ +idGameEdit::FindEntity +================ +*/ +idEntity *idGameEdit::FindEntity( const char *name ) const { + return gameLocal.FindEntity( name ); +} + +/* +============= +idGameEdit::GetUniqueEntityName + +generates a unique name for a given classname +============= +*/ +const char *idGameEdit::GetUniqueEntityName( const char *classname ) const { + int id; + static char name[1024]; + + // can only have MAX_GENTITIES, so if we have a spot available, we're guaranteed to find one + for( id = 0; id < MAX_GENTITIES; id++ ) { + idStr::snPrintf( name, sizeof( name ), "%s_%d", classname, id ); + if ( !gameLocal.FindEntity( name ) ) { + return name; + } + } + + // id == MAX_GENTITIES + 1, which can't be in use if we get here + idStr::snPrintf( name, sizeof( name ), "%s_%d", classname, id ); + return name; +} + +/* +================ +idGameEdit::EntityGetOrigin +================ +*/ +void idGameEdit::EntityGetOrigin( idEntity *ent, idVec3 &org ) const { + if ( ent ) { + org = ent->GetPhysics()->GetOrigin(); + } +} + +/* +================ +idGameEdit::EntityGetAxis +================ +*/ +void idGameEdit::EntityGetAxis( idEntity *ent, idMat3 &axis ) const { + if ( ent ) { + axis = ent->GetPhysics()->GetAxis(); + } +} + +/* +================ +idGameEdit::EntitySetOrigin +================ +*/ +void idGameEdit::EntitySetOrigin( idEntity *ent, const idVec3 &org ) { + if ( ent ) { + ent->SetOrigin( org ); + } +} + +/* +================ +idGameEdit::EntitySetAxis +================ +*/ +void idGameEdit::EntitySetAxis( idEntity *ent, const idMat3 &axis ) { + if ( ent ) { + ent->SetAxis( axis ); + } +} + +/* +================ +idGameEdit::EntitySetColor +================ +*/ +void idGameEdit::EntitySetColor( idEntity *ent, const idVec3 color ) { + if ( ent ) { + ent->SetColor( color ); + } +} + +/* +================ +idGameEdit::EntityTranslate +================ +*/ +void idGameEdit::EntityTranslate( idEntity *ent, const idVec3 &org ) { + if ( ent ) { + ent->GetPhysics()->Translate( org ); + } +} + +/* +================ +idGameEdit::EntityGetSpawnArgs +================ +*/ +const idDict *idGameEdit::EntityGetSpawnArgs( idEntity *ent ) const { + if ( ent ) { + return &ent->spawnArgs; + } + return NULL; +} + +/* +================ +idGameEdit::EntityUpdateChangeableSpawnArgs +================ +*/ +void idGameEdit::EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict ) { + if ( ent ) { + ent->UpdateChangeableSpawnArgs( dict ); + } +} + +/* +================ +idGameEdit::EntityChangeSpawnArgs +================ +*/ +void idGameEdit::EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs ) { + if ( ent ) { + for ( int i = 0 ; i < newArgs->GetNumKeyVals () ; i ++ ) { + const idKeyValue *kv = newArgs->GetKeyVal( i ); + + if ( kv->GetValue().Length() > 0 ) { + ent->spawnArgs.Set ( kv->GetKey() ,kv->GetValue() ); + } else { + ent->spawnArgs.Delete ( kv->GetKey() ); + } + } + } +} + +/* +================ +idGameEdit::EntityUpdateVisuals +================ +*/ +void idGameEdit::EntityUpdateVisuals( idEntity *ent ) { + if ( ent ) { + ent->UpdateVisuals(); + } +} + +/* +================ +idGameEdit::EntitySetModel +================ +*/ +void idGameEdit::EntitySetModel( idEntity *ent, const char *val ) { + if ( ent ) { + ent->spawnArgs.Set( "model", val ); + ent->SetModel( val ); + } +} + +/* +================ +idGameEdit::EntityStopSound +================ +*/ +void idGameEdit::EntityStopSound( idEntity *ent ) { + if ( ent ) { + ent->StopSound( SND_CHANNEL_ANY, false ); + } +} + +/* +================ +idGameEdit::EntityDelete +================ +*/ +void idGameEdit::EntityDelete( idEntity *ent ) { + delete ent; +} + +/* +================ +idGameEdit::PlayerIsValid +================ +*/ +bool idGameEdit::PlayerIsValid() const { + return ( gameLocal.GetLocalPlayer() != NULL ); +} + +/* +================ +idGameEdit::PlayerGetOrigin +================ +*/ +void idGameEdit::PlayerGetOrigin( idVec3 &org ) const { + org = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(); +} + +/* +================ +idGameEdit::PlayerGetAxis +================ +*/ +void idGameEdit::PlayerGetAxis( idMat3 &axis ) const { + axis = gameLocal.GetLocalPlayer()->GetPhysics()->GetAxis(); +} + +/* +================ +idGameEdit::PlayerGetViewAngles +================ +*/ +void idGameEdit::PlayerGetViewAngles( idAngles &angles ) const { + angles = gameLocal.GetLocalPlayer()->viewAngles; +} + +/* +================ +idGameEdit::PlayerGetEyePosition +================ +*/ +void idGameEdit::PlayerGetEyePosition( idVec3 &org ) const { + org = gameLocal.GetLocalPlayer()->GetEyePosition(); +} + + +/* +================ +idGameEdit::MapGetEntityDict +================ +*/ +const idDict *idGameEdit::MapGetEntityDict( const char *name ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile && name && *name ) { + idMapEntity *mapent = mapFile->FindEntity( name ); + if ( mapent ) { + return &mapent->epairs; + } + } + return NULL; +} + +/* +================ +idGameEdit::MapSave +================ +*/ +void idGameEdit::MapSave( const char *path ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if (mapFile) { + mapFile->Write( (path) ? path : mapFile->GetName(), ".map"); + } +} + +/* +================ +idGameEdit::MapSetEntityKeyVal +================ +*/ +void idGameEdit::MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile && name && *name ) { + idMapEntity *mapent = mapFile->FindEntity( name ); + if ( mapent ) { + mapent->epairs.Set( key, val ); + } + } +} + +/* +================ +idGameEdit::MapCopyDictToEntity +================ +*/ +void idGameEdit::MapCopyDictToEntity( const char *name, const idDict *dict ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile && name && *name ) { + idMapEntity *mapent = mapFile->FindEntity( name ); + if ( mapent ) { + for ( int i = 0; i < dict->GetNumKeyVals(); i++ ) { + const idKeyValue *kv = dict->GetKeyVal( i ); + const char *key = kv->GetKey(); + const char *val = kv->GetValue(); + mapent->epairs.Set( key, val ); + } + } + } +} + + + +/* +================ +idGameEdit::MapGetUniqueMatchingKeyVals +================ +*/ +int idGameEdit::MapGetUniqueMatchingKeyVals( const char *key, const char *list[], int max ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + int count = 0; + if ( mapFile ) { + for ( int i = 0; i < mapFile->GetNumEntities(); i++ ) { + idMapEntity *ent = mapFile->GetEntity( i ); + if ( ent ) { + const char *k = ent->epairs.GetString( key ); + if ( k && *k && count < max ) { + list[count++] = k; + } + } + } + } + return count; +} + +/* +================ +idGameEdit::MapAddEntity +================ +*/ +void idGameEdit::MapAddEntity( const idDict *dict ) const +{ + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile ) { + idMapEntity *ent = new idMapEntity(); + ent->epairs = *dict; + mapFile->AddEntity( ent ); + } +} + +/* +================ +idGameEdit::MapRemoveEntity +================ +*/ +void idGameEdit::MapRemoveEntity( const char *name ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile ) { + idMapEntity *ent = mapFile->FindEntity( name ); + if ( ent ) { + mapFile->RemoveEntity( ent ); + } + } +} + + +/* +================ +idGameEdit::MapGetEntitiesMatchignClassWithString +================ +*/ +int idGameEdit::MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + int count = 0; + if ( mapFile ) { + int entCount = mapFile->GetNumEntities(); + for ( int i = 0 ; i < entCount; i++ ) { + idMapEntity *ent = mapFile->GetEntity(i); + if (ent) { + idStr work = ent->epairs.GetString("classname"); + if ( work.Icmp( classname ) == 0 ) { + if ( match && *match ) { + work = ent->epairs.GetString( "soundgroup" ); + if ( count < max && work.Icmp( match ) == 0 ) { + list[count++] = ent->epairs.GetString( "name" ); + } + } else if ( count < max ) { + list[count++] = ent->epairs.GetString( "name" ); + } + } + } + } + } + return count; +} + + +/* +================ +idGameEdit::MapEntityTranslate +================ +*/ +void idGameEdit::MapEntityTranslate( const char *name, const idVec3 &v ) const { + idMapFile *mapFile = gameLocal.GetLevelMap(); + if ( mapFile && name && *name ) { + idMapEntity *mapent = mapFile->FindEntity( name ); + if ( mapent ) { + idVec3 origin; + mapent->epairs.GetVector( "origin", "", origin ); + origin += v; + mapent->epairs.SetVector( "origin", origin ); + } + } +} diff --git a/game/GameEdit.h b/game/GameEdit.h new file mode 100644 index 000000000..4a6f26e73 --- /dev/null +++ b/game/GameEdit.h @@ -0,0 +1,110 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_EDIT_H__ +#define __GAME_EDIT_H__ + + +/* +=============================================================================== + + Ingame cursor. + +=============================================================================== +*/ + +class idCursor3D : public idEntity { +public: + CLASS_PROTOTYPE( idCursor3D ); + + idCursor3D( void ); + ~idCursor3D( void ); + + void Spawn( void ); + void Present( void ); + void Think( void ); + + idForce_Drag drag; + idVec3 draggedPosition; +}; + + +/* +=============================================================================== + + Allows entities to be dragged through the world with physics. + +=============================================================================== +*/ + +class idDragEntity { +public: + idDragEntity( void ); + ~idDragEntity( void ); + + void Clear(); + void Update( idPlayer *player ); + void SetSelected( idEntity *ent ); + idEntity * GetSelected( void ) const { return selected.GetEntity(); } + void DeleteSelected( void ); + void BindSelected( void ); + void UnbindSelected( void ); + +private: + idEntityPtr dragEnt; // entity being dragged + jointHandle_t joint; // joint being dragged + int id; // id of body being dragged + idVec3 localEntityPoint; // dragged point in entity space + idVec3 localPlayerPoint; // dragged point in player space + idStr bodyName; // name of the body being dragged + idCursor3D * cursor; // cursor entity + idEntityPtr selected; // last dragged entity + + void StopDrag( void ); +}; + + +/* +=============================================================================== + + Handles ingame entity editing. + +=============================================================================== +*/ +typedef struct selectedTypeInfo_s { + idTypeInfo *typeInfo; + idStr textKey; +} selectedTypeInfo_t; + +class idEditEntities { +public: + idEditEntities( void ); + bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip ); + void AddSelectedEntity( idEntity *ent ); + void RemoveSelectedEntity( idEntity *ent ); + void ClearSelectedEntities( void ); + void DisplayEntities( void ); + bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL ); +private: + int nextSelectTime; + idList selectableEntityClasses; + idList selectedEntities; +}; + +#endif /* !__GAME_EDIT_H__ */ diff --git a/game/GamePlayTimer.h b/game/GamePlayTimer.h new file mode 100644 index 000000000..95fc6d46e --- /dev/null +++ b/game/GamePlayTimer.h @@ -0,0 +1,126 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAMEPLAY_TIMER_H__ +#define __GAMEPLAY_TIMER_H__ + +#include "../idlib/precompiled.h" +#include + +/** + * greebo: This class keeps track of the total gameplay time. Just call Update() + * in regular intervals and the class checks the time difference since the last update call. + * + * For saving and loading, this class provides separate routines. + */ +class GamePlayTimer +{ + std::time_t _lastTime; + std::time_t _curTime; + + // The passed time in seconds + unsigned int _timePassed; + + // TRUE if the timer updates the passed time + bool _enabled; +public: + GamePlayTimer() : + _timePassed(0) + {} + + // Defines the starting point + void Start() + { + // Remember this time as starting point + std::time(&_lastTime); + SetEnabled(true); + } + + void Stop() + { + SetEnabled(false); + } + + bool IsEnabled() const + { + return _enabled; + } + + void SetEnabled(bool enabled) + { + _enabled = enabled; + } + + void Clear() + { + _timePassed = 0; + std::time(&_lastTime); + } + + void Update() + { + if (!_enabled) + { + return; + } + + // Get the current time and calculate the difference + std::time(&_curTime); + + // Increase the time that has passed + _timePassed += _curTime - _lastTime; + + // Remember this last check time + _lastTime = _curTime; + } + + idStr GetTime() const { + return TimeToStr(_timePassed); + } + + // Returns the gameplay time in seconds + unsigned int GetTimeInSeconds() const + { + return _timePassed; + } + + void Save(idSaveGame *savefile) const + { + savefile->WriteUnsignedInt(_timePassed); + savefile->WriteBool(_enabled); + } + + void Restore(idRestoreGame *savefile) + { + savefile->ReadUnsignedInt(_timePassed); + savefile->ReadBool(_enabled); + } + + // Formats the given gameplay time + static idStr TimeToStr(unsigned int time) { + unsigned int hours = static_cast(idMath::Floor(time / 3600.0f)); + unsigned int minutes = time % 3600; + minutes = static_cast(idMath::Floor(minutes / 60.0f)); + unsigned int seconds = time % 60; + + return va("%02d:%02d:%02d", hours, minutes, seconds); + } +}; + +#endif /* __GAMEPLAY_TIMER_H__ */ diff --git a/game/Game_local.cpp b/game/Game_local.cpp new file mode 100644 index 000000000..36fe31756 --- /dev/null +++ b/game/Game_local.cpp @@ -0,0 +1,7324 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#pragma warning(disable : 4127 4996 4805 4800) + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "darkModLAS.h" +#include "decltdm_matinfo.h" +#include "declxdata.h" +#include "Grabber.h" +#include "Relations.h" +#include "Inventory/Inventory.h" +#include "SndProp.h" +#include "ai/AAS_local.h" +#include "StimResponse/StimResponseCollection.h" +#include "Objectives/MissionData.h" +#include "Objectives/CampaignStatistics.h" +#include "MultiStateMover.h" +#include "Func_Shooter.h" +#include "Shop/Shop.h" +#include "EscapePointManager.h" +#include "DownloadMenu.h" +#include "TimerManager.h" +#include "ai/Conversation/ConversationSystem.h" +#include "RevisionTracker.h" +#include "Missions/MissionManager.h" +#include "Missions/DownloadManager.h" +#include "Http/HttpConnection.h" +#include "Http/HttpRequest.h" +#include "StimResponse/StimType.h" // grayman #2721 + +#include +#include "randomizer/randomc.h" +#include +#include +#include + +#include + +CGlobal g_Global; +TRandomCombined rnd(time(0)); + +extern CMissionData g_MissionData; +extern CsndPropLoader g_SoundPropLoader; +extern CsndProp g_SoundProp; + +#define BUFFER_LEN 4096 + +#ifdef GAME_DLL + +idSys * sys = NULL; +idCommon * common = NULL; +idCmdSystem * cmdSystem = NULL; +idCVarSystem * cvarSystem = NULL; +idFileSystem * fileSystem = NULL; +idNetworkSystem * networkSystem = NULL; +idRenderSystem * renderSystem = NULL; +idSoundSystem * soundSystem = NULL; +idRenderModelManager * renderModelManager = NULL; +idUserInterfaceManager * uiManager = NULL; +idDeclManager * declManager = NULL; +idAASFileManager * AASFileManager = NULL; +idCollisionModelManager * collisionModelManager = NULL; +idCVar * idCVar::staticVars = NULL; + +idCVar com_forceGenericSIMD( "com_forceGenericSIMD", "0", CVAR_BOOL|CVAR_SYSTEM, "force generic platform independent SIMD" ); + +#endif + +idRenderWorld * gameRenderWorld = NULL; // all drawing is done to this world +idSoundWorld * gameSoundWorld = NULL; // all audio goes to this world +idSoundWorld * gameSoundWorldBuf = NULL; + +static gameExport_t gameExport; + +// global animation lib +idAnimManager animationLib; + +// the rest of the engine will only reference the "game" variable, while all local aspects stay hidden +idGameLocal gameLocal; +idGame * game = &gameLocal; // statically pointed at an idGameLocal + +const char *idGameLocal::sufaceTypeNames[ MAX_SURFACE_TYPES ] = { + "none", "metal", "stone", "flesh", "wood", "cardboard", "liquid", "glass", "plastic", + "ricochet", "surftype10", "surftype11", "surftype12", "surftype13", "surftype14", "surftype15" +}; + +/* This list isn't actually used by the code, it's here just for reference. The code + accepts any first word in the description as the surface type name: */ +// grayman - #1421/1422 - added "hardwood" +const char *idGameLocal::m_NewSurfaceTypes[ MAX_SURFACE_TYPES * 2 + 1] = { + "tile", "carpet", "dirt", "gravel", "grass", "rock", "twigs", "foliage", "sand", "mud", + "brokeglass", "snow", "ice", "squeakboard", "puddle", "moss", "cloth", "ceramic", "slate", + "straw", "armor_leath", "armor_chain", "armor_plate", "climbable", "paper","hardwood" +}; + +void PrintMessage( int x, int y, const char *szMessage, idVec4 colour, fontInfoEx_t &font ) +{ + renderSystem->SetColor( colour ); + + for( const char *p = szMessage; *p; p++ ) + { + glyphInfo_t &glyph = font.fontInfoSmall.glyphs[int(*p)]; + + renderSystem->DrawStretchPic( x, y - glyph.top, + glyph.imageWidth, glyph.imageHeight, + glyph.s, glyph.t, glyph.s2, glyph.t2, + glyph.glyph ); + + x += glyph.xSkip; + } +} + +/* +=========== +GetGameAPI +============ +*/ +#if __MWERKS__ +#pragma export on +#endif +#if __GNUC__ >= 4 +#pragma GCC visibility push(default) +#endif +extern "C" gameExport_t *GetGameAPI( gameImport_t *import ) { +#if __MWERKS__ +#pragma export off +#endif + + if ( import->version == GAME_API_VERSION ) { + + // set interface pointers used by the game + sys = import->sys; + common = import->common; + cmdSystem = import->cmdSystem; + cvarSystem = import->cvarSystem; + fileSystem = import->fileSystem; + networkSystem = import->networkSystem; + renderSystem = import->renderSystem; + soundSystem = import->soundSystem; + renderModelManager = import->renderModelManager; + uiManager = import->uiManager; + declManager = import->declManager; + AASFileManager = import->AASFileManager; + collisionModelManager = import->collisionModelManager; + } + else { + // Wrong game version, throw a meaningful error rather than leaving + // stuff initialised and getting segfaults. + std::cerr << "FATAL: Incorrect game version: required " + << GAME_API_VERSION << ", got " << import->version << "\n" + << "Ensure the correct Doom 3 patches are installed." << std::endl; + abort(); + } + + // set interface pointers used by idLib + idLib::sys = sys; + idLib::common = common; + idLib::cvarSystem = cvarSystem; + idLib::fileSystem = fileSystem; + + // setup export interface + gameExport.version = GAME_API_VERSION; + gameExport.game = game; + gameExport.gameEdit = gameEdit; + + // Initialize logging and all the global stuff for darkmod + g_Global.Init(); + + return &gameExport; +} +#if __GNUC__ >= 4 +#pragma GCC visibility pop +#endif + +/* +=========== +TestGameAPI +============ +*/ +void TestGameAPI( void ) { + gameImport_t testImport; + gameExport_t testExport; + + testImport.sys = ::sys; + testImport.common = ::common; + testImport.cmdSystem = ::cmdSystem; + testImport.cvarSystem = ::cvarSystem; + testImport.fileSystem = ::fileSystem; + testImport.networkSystem = ::networkSystem; + testImport.renderSystem = ::renderSystem; + testImport.soundSystem = ::soundSystem; + testImport.renderModelManager = ::renderModelManager; + testImport.uiManager = ::uiManager; + testImport.declManager = ::declManager; + testImport.AASFileManager = ::AASFileManager; + testImport.collisionModelManager = ::collisionModelManager; + + testExport = *GetGameAPI( &testImport ); +} + +/* +=========== +idGameLocal::idGameLocal +============ +*/ +idGameLocal::idGameLocal() : + postMissionScreenActive(false), + briefingVideoInfoLoaded(false), + curBriefingVideoPart(-1), + m_MissionResult(MISSION_NOTEVENSTARTED), + m_HighestSRId(0) +{ + Clear(); +} + +/* +=========== +idGameLocal::~idGameLocal +============ +*/ +idGameLocal::~idGameLocal() +{ +} + +/* +=========== +idGameLocal::Clear +============ +*/ +void idGameLocal::Clear( void ) +{ + int i; + + m_HighestSRId = 0; + m_StimTimer.Clear(); + m_Timer.Clear(); + m_StimEntity.Clear(); + m_RespEntity.Clear(); + + m_sndPropLoader = &g_SoundPropLoader; + m_sndProp = &g_SoundProp; + m_RelationsManager = CRelationsPtr(); + m_MissionData.reset(); + + mainMenuExited = false; + briefingVideo.Clear(); + debriefingVideo.Clear(); + + m_Grabber = NULL; + m_DifficultyManager.Clear(); + + m_ModMenu.reset(); + m_DownloadMenu.reset(); + m_DownloadManager.reset(); + m_Shop.reset(); + + m_TriggerFinalSave = false; + + m_StartPosition = ""; // grayman #2933 + + m_GUICommandStack.Clear(); + m_GUICommandArgs = 0; + + m_guiError.Clear(); + + m_AreaManager.Clear(); + m_ConversationSystem.reset(); + + if (m_ModelGenerator) + { + m_ModelGenerator->Clear(); + } + if (m_ImageMapManager) + { + m_ImageMapManager->Clear(); + } + if (m_LightController) + { + m_LightController->Clear(); + } + if (m_I18N) + { + m_I18N->Clear(); + } + +#ifdef TIMING_BUILD + debugtools::TimerManager::Instance().Clear(); +#endif + + m_EscapePointManager = CEscapePointManager::Instance(); + m_EscapePointManager->Clear(); + + m_Interleave = 0; + + m_lightGem.Clear(); + m_DoLightgem = true; + + m_InterMissionTriggers.Clear(); + + serverInfo.Clear(); + numClients = 0; + for ( i = 0; i < MAX_CLIENTS; i++ ) { + userInfo[i].Clear(); + persistentPlayerInfo[i].Clear(); + } + memset( usercmds, 0, sizeof( usercmds ) ); + memset( entities, 0, sizeof( entities ) ); + memset( spawnIds, -1, sizeof( spawnIds ) ); + firstFreeIndex = 0; + num_entities = 0; + spawnedEntities.Clear(); + activeEntities.Clear(); + spawnedAI.Clear(); + numEntitiesToDeactivate = 0; + sortPushers = false; + sortTeamMasters = false; + persistentLevelInfo.Clear(); + persistentPlayerInventory.reset(); + campaignInfoEntities.Clear(); + + memset( globalShaderParms, 0, sizeof( globalShaderParms ) ); + random.SetSeed( 0 ); + world = NULL; + frameCommandThread = NULL; + testmodel = NULL; + testFx = NULL; + clip.Shutdown(); + pvs.Shutdown(); + sessionCommand.Clear(); + locationEntities = NULL; + smokeParticles = NULL; + editEntities = NULL; + entityHash.Clear( 1024, MAX_GENTITIES ); + inCinematic = false; + cinematicSkipTime = 0; + cinematicStopTime = 0; + cinematicMaxSkipTime = 0; + framenum = 0; + previousTime = 0; + time = 0; + vacuumAreaNum = 0; + mapFileName.Clear(); + mapFile = NULL; + spawnCount = INITIAL_SPAWN_COUNT; + mapSpawnCount = 0; + camera = NULL; + aasList.Clear(); + aasNames.Clear(); + spawnArgs.Clear(); + gravity.Set( 0, 0, -1 ); + playerPVS.h = (unsigned int)-1; + playerConnectedAreas.h = (unsigned int)-1; + gamestate = GAMESTATE_UNINITIALIZED; + skipCinematic = false; + influenceActive = false; + + localClientNum = 0; + isMultiplayer = false; + isServer = false; + isClient = false; + realClientTime = 0; + isNewFrame = true; + clientSmoothing = 0.1f; + entityDefBits = 0; + + nextGibTime = 0; + globalMaterial = NULL; + newInfo.Clear(); + lastGUIEnt = NULL; + lastGUI = 0; + + memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); + memset( clientPVS, 0, sizeof( clientPVS ) ); + memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); + + eventQueue.Init(); + savedEventQueue.Init(); + memset( lagometer, 0, sizeof( lagometer ) ); + + portalSkyEnt = NULL; + portalSkyActive = false; + // ResetSlowTimeVars(); + + m_GamePlayTimer.Clear(); + + musicSpeakers.Clear(); +} + +/* +=========== +idGameLocal::Init + + initialize the game object, only happens once at startup, not each level load +============ +*/ +void idGameLocal::Init( void ) { + const idDict *dict; + idAAS *aas; + +#ifndef GAME_DLL + + TestGameAPI(); + +#else + // Attempt to change the D3 window title and icon + ChangeWindowTitleAndIcon(); + + // Initialize the image library, so we can use it later on. + ilInit(); + + // initialize idLib + idLib::Init(); + + // register static cvars declared in the game + idCVar::RegisterStaticVars(); + + // initialize processor specific SIMD + idSIMD::InitProcessor( "game", com_forceGenericSIMD.GetBool() ); + +#endif + + Printf( "--------- Initializing Game ----------\n" ); + Printf( "%s %d.%02d, code revision %d\n", + GAME_VERSION, + TDM_VERSION_MAJOR, TDM_VERSION_MINOR, + RevisionTracker::Instance().GetHighestRevision() + ); + Printf( "Build date: %s\n", __DATE__ ); + + // register game specific decl types + declManager->RegisterDeclType( "model", DECL_MODELDEF, idDeclAllocator ); + declManager->RegisterDeclType( "export", DECL_MODELEXPORT, idDeclAllocator ); + // TDM specific DECLs + declManager->RegisterDeclType( "xdata", DECL_XDATA, idDeclAllocator ); + declManager->RegisterDeclType( "tdm_matinfo", DECL_TDM_MATINFO, idDeclAllocator ); + + // register game specific decl folders + declManager->RegisterDeclFolder( "def", ".def", DECL_ENTITYDEF ); + declManager->RegisterDeclFolder( "fx", ".fx", DECL_FX ); + declManager->RegisterDeclFolder( "particles", ".prt", DECL_PARTICLE ); + declManager->RegisterDeclFolder( "af", ".af", DECL_AF ); + // TDM specific DECLs + declManager->RegisterDeclFolder( "xdata", ".xd", DECL_XDATA ); + declManager->RegisterDeclFolder( "materials", ".mtr", DECL_TDM_MATINFO ); + + cmdSystem->AddCommand( "listModelDefs", idListDecls_f, CMD_FL_SYSTEM|CMD_FL_GAME, "lists model defs" ); + cmdSystem->AddCommand( "printModelDefs", idPrintDecls_f, CMD_FL_SYSTEM|CMD_FL_GAME, "prints a model def", idCmdSystem::ArgCompletion_Decl ); + + Clear(); + + idEvent::Init(); + idClass::Init(); + + InitConsoleCommands(); + + // greebo: Let the proxy CVARs overwrite the closed source counter-part + cvarSystem->SetCVarInteger("s_doorDistanceAdd", cv_tdm_s_doorDistanceAdd.GetInteger()); + cvarSystem->SetCVarFloat("gui_mediumFontLimit", cv_tdm_gui_mediumFontLimit.GetFloat()); + cvarSystem->SetCVarFloat("gui_smallFontLimit", cv_tdm_gui_smallFontLimit.GetFloat()); + + if (cv_tdm_s_maxSoundsPerShader.GetInteger() != -1) + { + cvarSystem->SetCVarInteger("s_maxSoundsPerShader", cv_tdm_s_maxSoundsPerShader.GetInteger()); + } + + // load default scripts + program.Startup( SCRIPT_DEFAULT ); + + smokeParticles = new idSmokeParticles; + + // set up the aas + dict = FindEntityDefDict( "aas_types" ); + if ( !dict ) { + Error( "Unable to find entityDef for 'aas_types'" ); + } + + // allocate space for the aas + const idKeyValue *kv = dict->MatchPrefix( "type" ); + while( kv != NULL ) { + aas = idAAS::Alloc(); + aasList.Append( aas ); + aasNames.Append( kv->GetValue() ); + kv = dict->MatchPrefix( "type", kv ); + } + + gamestate = GAMESTATE_NOMAP; + + Printf( "...%d aas types\n", aasList.Num() ); + Printf( "game initialized.\n" ); + Printf( "--------------------------------------\n" ); + Printf( "Parsing material files\n" ); + + LoadLightMaterial("materials/lights.mtr", &g_Global.m_LightMaterial); + + m_MissionData = CMissionDataPtr(new CMissionData); + m_CampaignStats = CampaignStatsPtr(new CampaignStats); + m_RelationsManager = CRelationsPtr(new CRelations); + m_ModMenu = CModMenuPtr(new CModMenu); + m_DownloadMenu = CDownloadMenuPtr(new CDownloadMenu); + m_DownloadManager = CDownloadManagerPtr(new CDownloadManager); + m_ConversationSystem = ai::ConversationSystemPtr(new ai::ConversationSystem); + + // load the soundprop globals from the def file + m_sndPropLoader->GlobalsFromDef(); + + //FIX: pm_walkspeed keeps getting reset whenever a map loads. + // Copy the old value here and set it when the map starts up. + m_walkSpeed = pm_walkspeed.GetFloat(); + + // Initialize the LightGem - J.C.Denton + m_lightGem.Initialize(); + + // Initialise the I18N (internationalization) code (before the Mission Manager!) + m_I18N = CI18NPtr(new CI18N); + m_I18N->Init(); + const idStr *tdm_lang = m_I18N->GetCurrentLanguage(); + Printf("Current language: %s\n", tdm_lang->c_str() ); + + // Initialise the mission manager + m_MissionManager = CMissionManagerPtr(new CMissionManager); + m_MissionManager->Init(); + + // Initialise the model generator + m_ModelGenerator = CModelGeneratorPtr(new CModelGenerator); + m_ModelGenerator->Init(); + + // Initialise the image map manager + m_ImageMapManager = CImageMapManagerPtr(new CImageMapManager); + m_ImageMapManager->Init(); + + // Initialise the light controller + m_LightController = CLightControllerPtr(new CLightController); + m_LightController->Init(); + + // greebo: Create the persistent inventory - will be handled by game state changing code + persistentPlayerInventory.reset(new CInventory); + + m_Shop = CShopPtr(new CShop); + m_Shop->Init(); + + // Construct a new http connection object + if (cv_tdm_allow_http_access.GetBool()) + { + m_HttpConnection = CHttpConnectionPtr(new CHttpConnection); + } +} + +const idStr& idGameLocal::GetMapFileName() const +{ + return mapFileName; +} + +void idGameLocal::AddInterMissionTrigger(int missionNum, const idStr& activatorName, const idStr& targetName) +{ + InterMissionTrigger& trigger = m_InterMissionTriggers.Alloc(); + + trigger.missionNum = missionNum; + trigger.activatorName = activatorName; + trigger.targetName = targetName; +} + +void idGameLocal::CheckTDMVersion() +{ + GuiMessage msg; + msg.type = GuiMessage::MSG_OK; + msg.okCmd = "close_msg_box"; + + if (m_HttpConnection == NULL) + { + Printf("HTTP requests disabled, skipping TDM version check.\n"); + + msg.title = m_I18N->Translate( "#str_02136" ); + msg.message = m_I18N->Translate( "#str_02141" ); // HTTP Requests have been disabled,\n cannot check for updates. + + AddMainMenuMessage(msg); + return; + } + + idStr url = cv_tdm_version_check_url.GetString(); + Printf("Checking %s\n", url.c_str() ); + CHttpRequestPtr req = m_HttpConnection->CreateRequest( url.c_str() ); + + req->Perform(); + + // Check Request Status + if (req->GetStatus() != CHttpRequest::OK) + { + Printf("%s.\n", m_I18N->Translate( "#str_2002") ); // Connection Error + + msg.title = m_I18N->Translate( "#str_02136" ); // Version Check Failed + msg.message = m_I18N->Translate( "#str_02132" ); // Cannot connect to server. + + AddMainMenuMessage(msg); + return; + } + + XmlDocumentPtr doc = req->GetResultXml(); + + pugi::xpath_node node = doc->select_single_node("//tdm/currentVersion"); + + if (node) + { + int major = node.node().attribute("major").as_int(); + int minor = node.node().attribute("minor").as_int(); + + msg.title = va( m_I18N->Translate( "#str_02132" ), major, minor ); // Most recent version is: + + switch (CompareVersion(TDM_VERSION_MAJOR, TDM_VERSION_MINOR, major, minor)) + { + case EQUAL: + // "Your version %d.%02d is up to date." + msg.message = va( m_I18N->Translate( "#str_02133"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); + break; + case OLDER: + // "Your version %d.%02d needs updating." + msg.message = va( m_I18N->Translate( "#str_02134"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); + break; + case NEWER: + // "Your version %d.%02d is newer than the most recently published one." + msg.message = va( m_I18N->Translate( "#str_02135"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); + break; + }; + } + else + { + msg.title = m_I18N->Translate( "#str_02136" ); // "Version Check Failed" + msg.message = m_I18N->Translate( "#str_02137" ); // "Couldn't find current version tag." + + } + + AddMainMenuMessage(msg); +} + +void idGameLocal::AddMainMenuMessage(const GuiMessage& message) +{ + m_GuiMessages.Append(message); +} + +/* +=========== +idGameLocal::Shutdown + + shut down the entire game +============ +*/ +void idGameLocal::Shutdown( void ) { + if ( !common ) { + return; + } + + if (cv_tdm_fm_sync_config_files.GetBool()) + { + // greebo: Check if we have a game base. If yes, write the current configuration back to the + // "darkmod" game base folder, to preserve any settings made while an FM is installed. + idStr fs_game_base(cvarSystem->GetCVarString("fs_game_base")); + + if (!fs_game_base.IsEmpty()) + { + common->WriteConfigToFile("../" + fs_game_base + "/DoomConfig.cfg"); + } + } + + Printf( "------------ Game Shutdown -----------\n" ); + + m_lightGem.Deinitialize(); + mpGame.Shutdown(); + + MapShutdown(); + + // greebo: De-allocate the missiondata singleton, this is not + // done in MapShutdown() (needed for mission statistics) + m_MissionData.reset(); + m_CampaignStats.reset(); + + // Destroy the conversation system + m_ConversationSystem.reset(); + + // Destroy the mission manager + m_MissionManager.reset(); + + // Destroy the model generator + m_ModelGenerator.reset(); + + // Destroy the image map manager + m_ImageMapManager.reset(); + + // Destroy the light controller + m_LightController.reset(); + + // Destroy the I18N system + m_I18N.reset(); + + // Clear http connection + m_HttpConnection.reset(); + m_GuiMessages.Clear(); + + aasList.DeleteContents( true ); + aasNames.Clear(); + + idAI::FreeObstacleAvoidanceNodes(); + + // shutdown the model exporter + idModelExport::Shutdown(); + + idEvent::Shutdown(); + + delete[] locationEntities; + locationEntities = NULL; + + delete smokeParticles; + smokeParticles = NULL; + + idClass::Shutdown(); + + // clear list with forces + idForce::ClearForceList(); + + // free the program data + program.FreeData(); + + // delete the .map file + delete mapFile; + mapFile = NULL; + + // free the collision map + collisionModelManager->FreeMap(); + + ShutdownConsoleCommands(); + + // free memory allocated by class objects + Clear(); + + // shut down the animation manager + animationLib.Shutdown(); + + Printf( "--------------------------------------\n" ); + +#ifdef GAME_DLL + + // remove auto-completion function pointers pointing into this DLL + cvarSystem->RemoveFlaggedAutoCompletion( CVAR_GAME ); + + // enable leak test + Mem_EnableLeakTest( "game" ); + + // shutdown idLib + idLib::ShutDown(); + +#endif +} + +/* +=========== +idGameLocal::SaveGame + +save the current player state, level name, and level state +the session may have written some data to the file already +============ +*/ +void idGameLocal::SaveGame( idFile *f ) { + int i; + + idSaveGame savegame( f ); + + if (g_flushSave.GetBool( ) == true ) { + // force flushing with each write... for tracking down + // save game bugs. + f->ForceFlush(); + } + + savegame.WriteHeader(); + + // go through all entities and threads and add them to the object list + for (i = 0; i < MAX_GENTITIES; i++) + { + idEntity* ent = entities[i]; + + if (ent == NULL) continue; + + // greebo: Give all entities a chance to register sub-objects (to resolve issue #2502) + ent->AddObjectsToSaveGame(&savegame); + + if (ent->GetTeamMaster() && ent->GetTeamMaster() != ent) + { + continue; // skip bindslaves, these are added by the team master + } + + for (idEntity* link = ent; link != NULL; link = link->GetNextTeamEntity()) + { + savegame.AddObject( link ); + } + } + + idList threads; + threads = idThread::GetThreads(); + + for( i = 0; i < threads.Num(); i++ ) { + savegame.AddObject( threads[i] ); + } + + // DarkMod: Add darkmod specific objects here: + + savegame.AddObject( m_Grabber ); + + // write out complete object list + savegame.WriteObjectList(); + + program.Save( &savegame ); + + // Save the global hiding spot search collection + CHidingSpotSearchCollection::Instance().Save(&savegame); + + // Save our grabber pointer + savegame.WriteObject(m_Grabber); + + // Save whatever the model generator needs + m_ModelGenerator->Save(&savegame); + + // Save whatever the image map manager needs + m_ImageMapManager->Save(&savegame); + + // Save whatever the light controller needs + m_LightController->Save(&savegame); + + // Save whatever the I18N needs + m_I18N->Save(&savegame); + + m_DifficultyManager.Save(&savegame); + + for ( i = 0; i < NumAAS(); i++) + { + idAAS* aas = GetAAS(i); + if (aas != NULL) + { + aas->Save(&savegame); + } + } + + m_GamePlayTimer.Save(&savegame); + m_AreaManager.Save(&savegame); + m_ConversationSystem->Save(&savegame); + m_RelationsManager->Save(&savegame); + m_Shop->Save(&savegame); + LAS.Save(&savegame); + m_MissionManager->Save(&savegame); + +#ifdef TIMING_BUILD + debugtools::TimerManager::Instance().Save(&savegame); +#endif + + savegame.WriteInt( g_skill.GetInteger() ); + + savegame.WriteDict( &serverInfo ); + + savegame.WriteInt( numClients ); + for( i = 0; i < numClients; i++ ) { + savegame.WriteDict( &userInfo[ i ] ); + savegame.WriteUsercmd( usercmds[ i ] ); + savegame.WriteDict( &persistentPlayerInfo[ i ] ); + } + + for( i = 0; i < MAX_GENTITIES; i++ ) { + savegame.WriteObject( entities[ i ] ); + savegame.WriteInt( spawnIds[ i ] ); + } + + savegame.WriteInt( firstFreeIndex ); + savegame.WriteInt( num_entities ); + + // enityHash is restored by idEntity::Restore setting the entity name. + + savegame.WriteObject( world ); + + savegame.WriteInt( spawnedEntities.Num() ); + for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + savegame.WriteObject( ent ); + } + + savegame.WriteInt( activeEntities.Num() ); + for (idEntity* ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + savegame.WriteObject( ent ); + } + + // tels: save the list of music speakers + savegame.WriteInt( musicSpeakers.Num() ); + for( i = 0; i < musicSpeakers.Num(); i++ ) { + savegame.WriteInt( musicSpeakers[ i ] ); + } + + savegame.WriteInt(spawnedAI.Num()); + for (idAI* ai = spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) { + savegame.WriteObject(ai); + } + + savegame.WriteInt( numEntitiesToDeactivate ); + savegame.WriteBool( sortPushers ); + savegame.WriteBool( sortTeamMasters ); + savegame.WriteDict( &persistentLevelInfo ); + + persistentPlayerInventory->Save(&savegame); + + savegame.WriteInt(campaignInfoEntities.Num()); + for (i = 0; i < campaignInfoEntities.Num(); ++i) + { + savegame.WriteObject(campaignInfoEntities[i]); + } + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + savegame.WriteFloat( globalShaderParms[ i ] ); + } + + savegame.WriteBool(postMissionScreenActive); + + savegame.WriteInt( random.GetSeed() ); + savegame.WriteObject( frameCommandThread ); + + // clip + // push + // pvs + + testmodel = NULL; + testFx = NULL; + + savegame.WriteString( sessionCommand ); + + // FIXME: save smoke particles + + savegame.WriteInt( cinematicSkipTime ); + savegame.WriteInt( cinematicStopTime ); + savegame.WriteInt( cinematicMaxSkipTime ); + savegame.WriteBool( inCinematic ); + savegame.WriteBool( skipCinematic ); + + savegame.WriteBool( isMultiplayer ); + savegame.WriteInt( gameType ); + + savegame.WriteInt( framenum ); + savegame.WriteInt( previousTime ); + savegame.WriteInt( time ); + + savegame.WriteInt( vacuumAreaNum ); + + savegame.WriteInt( entityDefBits ); + savegame.WriteBool( isServer ); + savegame.WriteBool( isClient ); + + savegame.WriteInt( localClientNum ); + + // snapshotEntities is used for multiplayer only + + savegame.WriteInt( realClientTime ); + savegame.WriteBool( isNewFrame ); + savegame.WriteFloat( clientSmoothing ); + + portalSkyEnt.Save( &savegame ); + + savegame.WriteBool( portalSkyActive ); + + + + savegame.WriteBool( mapCycleLoaded ); + savegame.WriteInt( spawnCount ); + + if ( !locationEntities ) { + savegame.WriteInt( 0 ); + } else { + savegame.WriteInt( gameRenderWorld->NumAreas() ); + for( i = 0; i < gameRenderWorld->NumAreas(); i++ ) { + savegame.WriteObject( locationEntities[ i ] ); + } + } + + savegame.WriteObject( camera ); + + savegame.WriteMaterial( globalMaterial ); + + savegame.WriteDict( &spawnArgs ); + + savegame.WriteInt( playerPVS.i ); + savegame.WriteInt( playerPVS.h ); + savegame.WriteInt( playerConnectedAreas.i ); + savegame.WriteInt( playerConnectedAreas.h ); + + savegame.WriteVec3( gravity ); + + // gamestate + + savegame.WriteBool( influenceActive ); + savegame.WriteInt( nextGibTime ); + + //Save LightGem - J.C.Denton + m_lightGem.Save( savegame ); + + savegame.WriteInt(m_InterMissionTriggers.Num()); + for (int i = 0; i < m_InterMissionTriggers.Num(); ++i) + { + savegame.WriteInt(m_InterMissionTriggers[i].missionNum); + savegame.WriteString(m_InterMissionTriggers[i].activatorName); + savegame.WriteString(m_InterMissionTriggers[i].targetName); + } + + m_sndProp->Save(&savegame); + m_MissionData->Save(&savegame); + savegame.WriteInt(static_cast(m_MissionResult)); + + m_CampaignStats->Save(&savegame); + + savegame.WriteInt(m_HighestSRId); + + savegame.WriteInt(m_Timer.Num()); + for (int i = 0; i < m_Timer.Num(); i++) + { + m_Timer[i]->Save(&savegame); + } + + savegame.WriteInt(m_StimTimer.Num()); + for (int i = 0; i < m_StimTimer.Num(); i++) + { + savegame.WriteInt(m_StimTimer[i]->GetUniqueId()); + } + + savegame.WriteInt(m_StimEntity.Num()); + for (int i = 0; i < m_StimEntity.Num(); i++) + { + m_StimEntity[i].Save(&savegame); + } + + savegame.WriteInt(m_RespEntity.Num()); + for (int i = 0; i < m_RespEntity.Num(); i++) + { + m_RespEntity[i].Save(&savegame); + } + + m_EscapePointManager->Save(&savegame); + + // greebo: Save the maximum frob distance + savegame.WriteFloat(g_Global.m_MaxFrobDistance); + + // spawnSpots + // initialSpots + // currentInitialSpot + // newInfo + // makingBuild + // shakeSounds + + // write out pending events + idEvent::Save( &savegame ); + + // Tels: Save the GUI command stack + savegame.WriteInt( m_GUICommandArgs ); + int cmds = m_GUICommandStack.Num(); + savegame.WriteInt( cmds ); + for( i = 0; i < cmds; i++ ) { + savegame.WriteString( m_GUICommandStack[i] ); + } + + // greebo: Close the savegame, this will invoke a recursive Save on all registered objects + savegame.Close(); + + // save all accumulated cache to file + savegame.FinalizeCache(); + + // Send a message to the HUD + GetLocalPlayer()->SendHUDMessage("#str_02916"); // "Game Saved" +} + +/* +=========== +idGameLocal::GetPersistentPlayerInfo +============ +*/ +const idDict &idGameLocal::GetPersistentPlayerInfo( int clientNum ) { + idEntity *ent; + + persistentPlayerInfo[ clientNum ].Clear(); + ent = entities[ clientNum ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + static_cast(ent)->SavePersistantInfo(); + } + + return persistentPlayerInfo[ clientNum ]; +} + +/* +=========== +idGameLocal::SetPersistentPlayerInfo +============ +*/ +void idGameLocal::SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) { + persistentPlayerInfo[ clientNum ] = playerInfo; +} + +/* +============ +idGameLocal::Printf +============ +*/ +void idGameLocal::Printf( const char *fmt, ... ) const { + va_list argptr; + char text[MAX_STRING_CHARS]; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + common->Printf( "%s", text ); +} + +/* +============ +idGameLocal::DPrintf +============ +*/ +void idGameLocal::DPrintf( const char *fmt, ... ) const { + va_list argptr; + char text[MAX_STRING_CHARS]; + + if ( !developer.GetBool() ) { + return; + } + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + common->Printf( "%s", text ); +} + +/* +============ +idGameLocal::Warning +============ +*/ +void idGameLocal::Warning( const char *fmt, ... ) const { + va_list argptr; + char text[MAX_STRING_CHARS]; + idThread * thread; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + thread = idThread::CurrentThread(); + if ( thread ) { + thread->Warning( "%s", text ); + } else { + common->Warning( "%s", text ); + } +} + +/* +============ +idGameLocal::DWarning +============ +*/ +void idGameLocal::DWarning( const char *fmt, ... ) const { + va_list argptr; + char text[MAX_STRING_CHARS]; + idThread * thread; + + if ( !developer.GetBool() ) { + return; + } + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + thread = idThread::CurrentThread(); + if ( thread ) { + thread->Warning( "%s", text ); + } else { + common->DWarning( "%s", text ); + } +} + +/* +============ +idGameLocal::Error +============ +*/ +void idGameLocal::Error( const char *fmt, ... ) const { + va_list argptr; + char text[MAX_STRING_CHARS]; + idThread * thread; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + // Send this error message to the GUI queue + m_guiError = text; + + thread = idThread::CurrentThread(); + if ( thread ) { + thread->Error( "%s", text ); + } else { + common->Error( "%s", text ); + } +} + +/* +=============== +gameError +=============== +*/ +void gameError( const char *fmt, ... ) { + va_list argptr; + char text[MAX_STRING_CHARS]; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + gameLocal.Error( "%s", text ); +} + +/* +=========== +idGameLocal::SetLocalClient +============ +*/ +void idGameLocal::SetLocalClient( int clientNum ) { + localClientNum = clientNum; +} + +/* +=========== +idGameLocal::SetUserInfo +============ +*/ +const idDict* idGameLocal::SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ) { + int i; + bool modifiedInfo = false; + + this->isClient = isClient; + + if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) { + idGameLocal::userInfo[ clientNum ] = userInfo; + + // server sanity + if ( canModify ) { + + // don't let numeric nicknames, it can be exploited to go around kick and ban commands from the server + if ( idStr::IsNumeric( this->userInfo[ clientNum ].GetString( "ui_name" ) ) ) { + idGameLocal::userInfo[ clientNum ].Set( "ui_name", va( "%s_", idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ) ) ); + modifiedInfo = true; + } + + // don't allow dupe nicknames + for ( i = 0; i < numClients; i++ ) { + if ( i == clientNum ) { + continue; + } + if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { + if ( !idStr::Icmp( idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ), idGameLocal::userInfo[ i ].GetString( "ui_name" ) ) ) { + idGameLocal::userInfo[ clientNum ].Set( "ui_name", va( "%s_", idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ) ) ); + modifiedInfo = true; + i = -1; // rescan + continue; + } + } + } + } + + if ( entities[ clientNum ] && entities[ clientNum ]->IsType( idPlayer::Type ) ) { + modifiedInfo |= static_cast( entities[ clientNum ] )->UserInfoChanged(canModify); + } + + if ( !isClient ) { + // now mark this client in game + mpGame.EnterGame( clientNum ); + } + } + + if ( modifiedInfo ) { + assert( canModify ); + + newInfo = idGameLocal::userInfo[ clientNum ]; + return &newInfo; + } + return NULL; +} + +/* +=========== +idGameLocal::GetUserInfo +============ +*/ +const idDict* idGameLocal::GetUserInfo( int clientNum ) { + if ( entities[ clientNum ] && entities[ clientNum ]->IsType( idPlayer::Type ) ) { + return &userInfo[ clientNum ]; + } + return NULL; +} + +/* +=========== +idGameLocal::SetServerInfo +============ +*/ +void idGameLocal::SetServerInfo( const idDict &_serverInfo ) { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + serverInfo = _serverInfo; + UpdateServerInfoFlags(); + + if ( !isClient ) { + // Let our clients know the server info changed + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SERVERINFO ); + outMsg.WriteDeltaDict( gameLocal.serverInfo, NULL ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + } +} + + +/* +=================== +idGameLocal::LoadMap + +Initializes all map variables common to both save games and spawned games. +=================== +*/ +void idGameLocal::LoadMap( const char *mapName, int randseed ) { + int i; + bool sameMap = (mapFile && idStr::Icmp(mapFileName, mapName) == 0); + + // clear the sound system + gameSoundWorld->ClearAllSoundEmitters(); + + musicSpeakers.Clear(); // Tels: Clear the list even on reload to account for dynamic changes + cv_music_volume.SetModified(); // SnoopJeDi: we want to fade on level start + + InitAsyncNetwork(); + + if ( !sameMap || ( mapFile && mapFile->NeedsReload() ) ) { + // load the .map file + if ( mapFile ) { + delete mapFile; + } + mapFile = new idMapFile; + if ( !mapFile->Parse( idStr( mapName ) + ".map" ) ) { + delete mapFile; + mapFile = NULL; + Error( "Couldn't load %s", mapName ); + } + tdmDeclTDM_MatInfo::precacheMap( mapFile ); + } + mapFileName = mapFile->GetName(); + + // load the collision map + collisionModelManager->LoadMap( mapFile ); + + numClients = 0; + + // initialize all entities for this game + memset( entities, 0, sizeof( entities ) ); + memset( usercmds, 0, sizeof( usercmds ) ); + memset( spawnIds, -1, sizeof( spawnIds ) ); + spawnCount = INITIAL_SPAWN_COUNT; + + spawnedEntities.Clear(); + activeEntities.Clear(); + spawnedAI.Clear(); + numEntitiesToDeactivate = 0; + sortTeamMasters = false; + sortPushers = false; + lastGUIEnt = NULL; + lastGUI = 0; + + globalMaterial = NULL; + + memset( globalShaderParms, 0, sizeof( globalShaderParms ) ); + + // always leave room for the max number of clients, + // even if they aren't all used, so numbers inside that + // range are NEVER anything but clients + num_entities = MAX_CLIENTS; + firstFreeIndex = MAX_CLIENTS; + + // reset the random number generator. + // Tels: use a random seed for single-player, too, otherwise map content can't be random + //random.SetSeed( isMultiplayer ? randseed : 0 ); + random.SetSeed( randseed ); + + camera = NULL; + world = NULL; + testmodel = NULL; + testFx = NULL; + + previousTime = 0; + time = 0; + framenum = 0; + sessionCommand = ""; + nextGibTime = 0; + + portalSkyEnt = NULL; + + portalSkyActive = false; + + + + vacuumAreaNum = -1; // if an info_vacuum is spawned, it will set this + + if ( !editEntities ) { + editEntities = new idEditEntities; + } + + gravity.Set( 0, 0, -g_gravity.GetFloat() ); + + spawnArgs.Clear(); + + skipCinematic = false; + inCinematic = false; + cinematicSkipTime = 0; + cinematicStopTime = 0; + cinematicMaxSkipTime = 0; + + clip.Init(); + pvs.Init(); + + + // this will always fail for now, have not yet written the map compile + m_sndPropLoader->CompileMap( mapFile ); + + playerPVS.i = -1; + playerConnectedAreas.i = -1; + + // load navigation system for all the different monster sizes + for( i = 0; i < aasNames.Num(); i++ ) { + aasList[ i ]->Init( idStr( mapFileName ).SetFileExtension( aasNames[ i ] ).c_str(), mapFile->GetGeometryCRC() ); + } + + /*! + * The Dark Mod LAS: Init the Light Awareness System + * This must occur AFTER the AAS list is loaded + */ + LAS.initialize(); + + // clear the smoke particle free list + smokeParticles->Init(); + + // cache miscellanious media references + FindEntityDef( "preCacheExtras", false ); + + if ( !sameMap ) { + mapFile->RemovePrimitiveData(); + } + + // greebo: Reset the flag. When a map is loaded, the success screen is definitely not shown anymore. + // This is meant to catch cases where the player is reloading a map from the console without clicking + // the "Continue" button on the success GUI. I can't stop him, so I need to track this here. + postMissionScreenActive = false; + + if (m_MissionData != NULL) + { + m_MissionData->ClearGUIState(); + } + + m_strMainAmbientLightName = "ambient_world"; // Default name for main ambient light. J.C.Denton. + +} + +/* +=================== +idGameLocal::LocalMapRestart +=================== +*/ +void idGameLocal::LocalMapRestart( ) { + int i, latchSpawnCount; + + Printf( "----------- Game Map Restart ------------\n" ); + + gamestate = GAMESTATE_SHUTDOWN; + + for ( i = 0; i < MAX_CLIENTS; i++ ) { + if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { + static_cast< idPlayer * >( entities[ i ] )->PrepareForRestart(); + } + } + + eventQueue.Shutdown(); + savedEventQueue.Shutdown(); + + MapClear( false ); + + // clear the smoke particle free list + smokeParticles->Init(); + + // clear the sound system + if ( gameSoundWorld ) { + gameSoundWorld->ClearAllSoundEmitters(); + } + + /*! + * The Dark Mod LAS: Init the LAS + */ + LAS.initialize(); + + // the spawnCount is reset to zero temporarily to spawn the map entities with the same spawnId + // if we don't do that, network clients are confused and don't show any map entities + latchSpawnCount = spawnCount; + spawnCount = INITIAL_SPAWN_COUNT; + + gamestate = GAMESTATE_STARTUP; + + program.Restart(); + + InitScriptForMap(); + + MapPopulate(); + + // once the map is populated, set the spawnCount back to where it was so we don't risk any collision + // (note that if there are no players in the game, we could just leave it at it's current value) + spawnCount = latchSpawnCount; + + // setup the client entities again + for ( i = 0; i < MAX_CLIENTS; i++ ) { + if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { + static_cast< idPlayer * >( entities[ i ] )->Restart(); + } + } + + gamestate = GAMESTATE_ACTIVE; + m_MissionResult = MISSION_INPROGRESS; + + Printf( "--------------------------------------\n" ); +} + +/* +=================== +idGameLocal::MapRestart +=================== +*/ +void idGameLocal::MapRestart( ) { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + idDict newInfo; + int i; + const idKeyValue *keyval, *keyval2; + + if ( isClient ) { + LocalMapRestart(); + } else { + newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + for ( i = 0; i < newInfo.GetNumKeyVals(); i++ ) { + keyval = newInfo.GetKeyVal( i ); + keyval2 = serverInfo.FindKey( keyval->GetKey() ); + if ( !keyval2 ) { + break; + } + // a select set of si_ changes will cause a full restart of the server + if ( keyval->GetValue().Cmp( keyval2->GetValue() ) && + ( !keyval->GetKey().Cmp( "si_pure" ) || !keyval->GetKey().Cmp( "si_map" ) ) ) { + break; + } + } + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); + if ( i != newInfo.GetNumKeyVals() ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); + } else { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_RESTART ); + outMsg.WriteBits( 1, 1 ); + outMsg.WriteDeltaDict( serverInfo, NULL ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + + LocalMapRestart(); + mpGame.MapRestart(); + } + } +} + +/* +=================== +idGameLocal::MapRestart_f +=================== +*/ +void idGameLocal::MapRestart_f( const idCmdArgs &args ) { + if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { + common->Printf( "server is not running - use spawnServer\n" ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "spawnServer\n" ); + return; + } + + gameLocal.MapRestart( ); +} + +/* +=================== +idGameLocal::NextMap +=================== +*/ +bool idGameLocal::NextMap( void ) { + const function_t *func; + idThread *thread; + idDict newInfo; + const idKeyValue *keyval, *keyval2; + int i; + + if ( !g_mapCycle.GetString()[0] ) { + Printf( m_I18N->Translate( "#str_04294" ) ); + return false; + } + if ( fileSystem->ReadFile( g_mapCycle.GetString(), NULL, NULL ) < 0 ) { + if ( fileSystem->ReadFile( va( "%s.scriptcfg", g_mapCycle.GetString() ), NULL, NULL ) < 0 ) { + Printf( "map cycle script '%s': not found\n", g_mapCycle.GetString() ); + return false; + } else { + g_mapCycle.SetString( va( "%s.scriptcfg", g_mapCycle.GetString() ) ); + } + } + + Printf( "map cycle script: '%s'\n", g_mapCycle.GetString() ); + func = program.FindFunction( "mapcycle::cycle" ); + if ( !func ) { + program.CompileFile( g_mapCycle.GetString() ); + func = program.FindFunction( "mapcycle::cycle" ); + } + if ( !func ) { + Printf( "Couldn't find mapcycle::cycle\n" ); + return false; + } + thread = new idThread( func ); + thread->Start(); + delete thread; + + newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + for ( i = 0; i < newInfo.GetNumKeyVals(); i++ ) { + keyval = newInfo.GetKeyVal( i ); + keyval2 = serverInfo.FindKey( keyval->GetKey() ); + if ( !keyval2 || keyval->GetValue().Cmp( keyval2->GetValue() ) ) { + break; + } + } + return ( i != newInfo.GetNumKeyVals() ); +} + +/* +=================== +idGameLocal::NextMap_f +=================== +*/ +void idGameLocal::NextMap_f( const idCmdArgs &args ) { + if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { + common->Printf( "server is not running\n" ); + return; + } + + gameLocal.NextMap( ); + // next map was either voted for or triggered by a server command - always restart + gameLocal.MapRestart( ); +} + +/* +=================== +idGameLocal::MapPopulate +Dark Mod: Sound prop initialization added +=================== +*/ +void idGameLocal::MapPopulate( void ) { + + if ( isMultiplayer ) { + cvarSystem->SetCVarBool( "r_skipSpecular", false ); + } + + // parse the key/value pairs and spawn entities + SpawnMapEntities(); + + // mark location entities in all connected areas + SpreadLocations(); + + // prepare the list of randomized initial spawn spots + RandomizeInitialSpawns( ); + + // spawnCount - 1 is the number of entities spawned into the map, their indexes started at MAX_CLIENTS (included) + // mapSpawnCount is used as the max index of map entities, it's the first index of non-map entities + mapSpawnCount = MAX_CLIENTS + spawnCount - 1; + + // read in the soundprop data for various locations + m_sndPropLoader->FillLocationData(); + + // Transfer sound prop data from loader to gameplay object + m_sndProp->SetupFromLoader( m_sndPropLoader ); + + m_sndPropLoader->Shutdown(); + + // Initialise the escape point manager after all the entities have been spawned. + m_EscapePointManager->InitAAS(); + + // execute pending events before the very first game frame + // this makes sure the map script main() function is called + // before the physics are run so entities can bind correctly + Printf( "==== Processing events ====\n" ); + idEvent::ServiceEvents(); +} + +/* +=================== +idGameLocal::InitFromNewMap +=================== +*/ +void idGameLocal::InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) { + + this->isServer = isServer; + this->isClient = isClient; + this->isMultiplayer = isServer || isClient; + + if ( mapFileName.Length() ) { + MapShutdown(); + } + + idStr mapNameStr = mapName; + mapNameStr.StripLeadingOnce("maps/"); + mapNameStr.StripFileExtension(); + + idUserInterface* loadingGUI = uiManager->FindGui(va("guis/map/%s.gui", mapNameStr.c_str()), false, false, false); + + if (loadingGUI != NULL) + { + // Use our own randomizer, the gameLocal.random one is not yet initialised + loadingGUI->SetStateFloat("random_value", static_cast(rnd.Random())); + loadingGUI->HandleNamedEvent("OnRandomValueInitialised"); + } + + // greebo: Clear the mission data, it might have been filled during the objectives screen display + m_MissionData->Clear(); + + // Clear the persistent data if starting a new campaign + if (m_MissionManager->CurrentModIsCampaign() && m_MissionManager->GetCurrentMissionIndex() == 0) + { + ClearPersistentInfo(); + } + + Printf( "----------- Game Map Init ------------\n" ); + + gamestate = GAMESTATE_STARTUP; + + gameRenderWorld = renderWorld; + gameSoundWorld = soundWorld; + + LoadMap( mapName, randseed ); + + // Instantiate our grabber entity + m_Grabber = static_cast(CGrabber::Type.CreateInstance()); + + // greebo: Initialize the Difficulty Manager, before any entities are spawned + m_DifficultyManager.Init(mapFile); + m_ConversationSystem->Init(mapFile); + + // Immediately apply the CVAR difficulty settings + m_DifficultyManager.ApplyCVARDifficultySettings(); + + InitScriptForMap(); + + // Initialize the AI relationships + // greebo: Do this before spawning the rest of the map entities to give them a chance + // to override the default settings found on the entityDef + const idDict* defaultRelationsDict = FindEntityDefDict(cv_tdm_default_relations_def.GetString()); + + if (defaultRelationsDict != NULL) + { + m_RelationsManager->SetFromArgs(*defaultRelationsDict); + } + + MapPopulate(); + + // ishtvan: Set the player variable on the grabber + //m_Grabber->SetPlayer( GetLocalPlayer() ); // greebo: GetLocalPlayer() returns NULL, moved to idPlayer::Spawn() + + // greebo: Add the elevator reachabilities to the AAS + SetupEAS(); + + // Then, apply the worldspawn settings + m_RelationsManager->SetFromArgs( world->spawnArgs ); + + mpGame.Reset(); + + mpGame.Precache(); + + // free up any unused animations + animationLib.FlushUnusedAnims(); + + gamestate = GAMESTATE_ACTIVE; + m_MissionResult = MISSION_INPROGRESS; + + // Let the mission database know that we start playing + m_MissionManager->OnMissionStart(); + + // We need an objectives update now that we've loaded the map + m_MissionData->ClearGUIState(); + + Printf( "--------------------------------------\n" ); +} + +/* +================= +idGameLocal::InitFromSaveGame +================= +*/ +bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ) { + int i; + int num; + idEntity *ent; + idDict si; + + if ( mapFileName.Length() ) { + MapShutdown(); + } + + Printf( "------- Game Map Init SaveGame -------\n" ); + + gamestate = GAMESTATE_STARTUP; + + gameRenderWorld = renderWorld; + gameSoundWorld = soundWorld; + + idRestoreGame savegame( saveGameFile ); + + savegame.ReadHeader(); + + if (!cv_force_savegame_load.GetBool() && savegame.GetCodeRevision() != RevisionTracker::Instance().GetHighestRevision()) + { + gameLocal.Printf("Can't load this savegame, was saved with an old revision %d\n.", savegame.GetCodeRevision()); + return false; + } + + // Read and initialize cache from file + savegame.InitializeCache(); + + // Create the list of all objects in the game + savegame.CreateObjects(); + + // Load the idProgram, also checking to make sure scripting hasn't changed since the savegame + if ( program.Restore( &savegame ) == false ) { + + // Abort the load process, and let the session know so that it can restart the level + // with the player persistent data. + savegame.DeleteObjects(); + program.Restart(); + + return false; + } + + // load the map needed for this savegame + LoadMap( mapName, 0 ); + + // Restore the global hiding spot search collection + CHidingSpotSearchCollection::Instance().Restore(&savegame); + + // Restore our grabber pointer + savegame.ReadObject( reinterpret_cast(m_Grabber) ); + + m_ModelGenerator->Restore(&savegame); + m_ImageMapManager->Restore(&savegame); + m_LightController->Restore(&savegame); + m_I18N->Restore(&savegame); + + m_DifficultyManager.Restore(&savegame); + + for ( i = 0; i < NumAAS(); i++) + { + idAAS* aas = GetAAS(i); + if (aas != NULL) + { + aas->Restore(&savegame); + } + } + + m_GamePlayTimer.Restore(&savegame); + m_GamePlayTimer.SetEnabled(false); + m_AreaManager.Restore(&savegame); + m_ConversationSystem->Restore(&savegame); + m_RelationsManager->Restore(&savegame); + m_Shop->Restore(&savegame); + LAS.Restore(&savegame); + m_MissionManager->Restore(&savegame); + +#ifdef TIMING_BUILD + debugtools::TimerManager::Instance().Restore(&savegame); +#endif + + savegame.ReadInt( i ); + g_skill.SetInteger( i ); + + // precache the player + FindEntityDef( cv_player_spawnclass.GetString(), false ); + + // precache the empty model (used by idEntity::m_renderTrigger) + renderModelManager->FindModel( cv_empty_model.GetString() ); + + m_lightGem.SpawnLightGemEntity( mapFile ); + + // precache any media specified in the map + for ( i = 0; i < mapFile->GetNumEntities(); i++ ) { + idMapEntity *mapEnt = mapFile->GetEntity( i ); + + if ( !InhibitEntitySpawn( mapEnt->epairs ) ) { + CacheDictionaryMedia( &mapEnt->epairs ); + const char *classname = mapEnt->epairs.GetString( "classname" ); + if ( classname != '\0' ) { + FindEntityDef( classname, false ); + } + } + } + + savegame.ReadDict( &si ); + SetServerInfo( si ); + + savegame.ReadInt( numClients ); + for( i = 0; i < numClients; i++ ) { + savegame.ReadDict( &userInfo[ i ] ); + savegame.ReadUsercmd( usercmds[ i ] ); + savegame.ReadDict( &persistentPlayerInfo[ i ] ); + } + + for( i = 0; i < MAX_GENTITIES; i++ ) { + savegame.ReadObject( reinterpret_cast( entities[ i ] ) ); + savegame.ReadInt( spawnIds[ i ] ); + + // restore the entityNumber + if ( entities[ i ] != NULL ) { + entities[ i ]->entityNumber = i; + } + } + + savegame.ReadInt( firstFreeIndex ); + savegame.ReadInt( num_entities ); + + // enityHash is restored by idEntity::Restore setting the entity name. + + savegame.ReadObject( reinterpret_cast( world ) ); + + savegame.ReadInt( num ); + for( i = 0; i < num; i++ ) { + savegame.ReadObject( reinterpret_cast( ent ) ); + assert( ent ); + if ( ent ) { + ent->spawnNode.AddToEnd( spawnedEntities ); + } + } + + savegame.ReadInt( num ); + for( i = 0; i < num; i++ ) { + savegame.ReadObject( reinterpret_cast( ent ) ); + assert( ent ); + if ( ent ) { + ent->activeNode.AddToEnd( activeEntities ); + } + } + + // tels: restore the list of music speakers + savegame.ReadInt( num ); + musicSpeakers.Clear(); + for( i = 0; i < num; i++ ) { + int id; + savegame.ReadInt( id ); + musicSpeakers.Append( id ); + } + + savegame.ReadInt( num ); + for( i = 0; i < num; i++ ) + { + idAI* ai(NULL); + savegame.ReadObject(reinterpret_cast(ai)); + assert(ai != NULL); + + if (ai != NULL) + { + ai->aiNode.AddToEnd(spawnedAI); + } + } + + savegame.ReadInt( numEntitiesToDeactivate ); + savegame.ReadBool( sortPushers ); + savegame.ReadBool( sortTeamMasters ); + savegame.ReadDict( &persistentLevelInfo ); + + persistentPlayerInventory->Restore(&savegame); + + savegame.ReadInt(num); + campaignInfoEntities.SetNum(num); + for (i = 0; i < num; ++i) + { + savegame.ReadObject(reinterpret_cast(campaignInfoEntities[i])); + } + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + savegame.ReadFloat( globalShaderParms[ i ] ); + } + + savegame.ReadBool(postMissionScreenActive); + + savegame.ReadInt( i ); + random.SetSeed( i ); + + savegame.ReadObject( reinterpret_cast( frameCommandThread ) ); + + // clip + // push + // pvs + + // testmodel = "" + // testFx = "" + + savegame.ReadString( sessionCommand ); + + // FIXME: save smoke particles + + savegame.ReadInt( cinematicSkipTime ); + savegame.ReadInt( cinematicStopTime ); + savegame.ReadInt( cinematicMaxSkipTime ); + savegame.ReadBool( inCinematic ); + savegame.ReadBool( skipCinematic ); + + savegame.ReadBool( isMultiplayer ); + savegame.ReadInt( (int &)gameType ); + + savegame.ReadInt( framenum ); + savegame.ReadInt( previousTime ); + savegame.ReadInt( time ); + + savegame.ReadInt( vacuumAreaNum ); + + savegame.ReadInt( entityDefBits ); + savegame.ReadBool( isServer ); + savegame.ReadBool( isClient ); + + savegame.ReadInt( localClientNum ); + + // snapshotEntities is used for multiplayer only + + savegame.ReadInt( realClientTime ); + savegame.ReadBool( isNewFrame ); + savegame.ReadFloat( clientSmoothing ); + + portalSkyEnt.Restore( &savegame ); + + savegame.ReadBool( portalSkyActive ); + + + + savegame.ReadBool( mapCycleLoaded ); + savegame.ReadInt( spawnCount ); + + savegame.ReadInt( num ); + if ( num ) { + if ( num != gameRenderWorld->NumAreas() ) { + savegame.Error( "idGameLocal::InitFromSaveGame: number of areas in map differs from save game." ); + } + + locationEntities = new idLocationEntity *[ num ]; + for( i = 0; i < num; i++ ) { + savegame.ReadObject( reinterpret_cast( locationEntities[ i ] ) ); + } + } + + savegame.ReadObject( reinterpret_cast( camera ) ); + + savegame.ReadMaterial( globalMaterial ); + + savegame.ReadDict( &spawnArgs ); + + savegame.ReadInt( playerPVS.i ); + savegame.ReadInt( (int &)playerPVS.h ); + savegame.ReadInt( playerConnectedAreas.i ); + savegame.ReadInt( (int &)playerConnectedAreas.h ); + + savegame.ReadVec3( gravity ); + + // gamestate is restored after restoring everything else + + savegame.ReadBool( influenceActive ); + savegame.ReadInt( nextGibTime ); + + // Restore LightGem - J.C.Denton + m_lightGem.Restore( savegame ); + + savegame.ReadInt(num); + m_InterMissionTriggers.SetNum(num); + for (int i = 0; i < num; ++i) + { + savegame.ReadInt(m_InterMissionTriggers[i].missionNum); + savegame.ReadString(m_InterMissionTriggers[i].activatorName); + savegame.ReadString(m_InterMissionTriggers[i].targetName); + } + + m_sndProp->Restore(&savegame); + m_MissionData->Restore(&savegame); + + int missResult; + savegame.ReadInt(missResult); + m_MissionResult = static_cast(missResult); + + m_CampaignStats->Restore(&savegame); + + savegame.ReadInt(m_HighestSRId); + + savegame.ReadInt(num); + m_Timer.SetNum(num); + for (int i = 0; i < num; i++) + { + m_Timer[i] = new CStimResponseTimer; + m_Timer[i]->Restore(&savegame); + } + + // The list to take all the values, they will be restored later on + idList tempStimTimerIdList; + savegame.ReadInt(num); + tempStimTimerIdList.SetNum(num); + for (int i = 0; i < num; i++) + { + savegame.ReadInt(tempStimTimerIdList[i]); + } + + savegame.ReadInt(num); + m_StimEntity.SetNum(num); + for (int i = 0; i < num; i++) + { + m_StimEntity[i].Restore(&savegame); + } + + savegame.ReadInt(num); + m_RespEntity.SetNum(num); + for (int i = 0; i < num; i++) + { + m_RespEntity[i].Restore(&savegame); + } + + m_EscapePointManager->Restore(&savegame); + + // greebo: Restore the maximum frob distance + savegame.ReadFloat(g_Global.m_MaxFrobDistance); + + // spawnSpots + // initialSpots + // currentInitialSpot + // newInfo + // makingBuild + // shakeSounds + + // Read out pending events + idEvent::Restore( &savegame ); + + // Tels: Restore the GUI command stack + int cmds; + savegame.ReadInt( m_GUICommandArgs ); + savegame.ReadInt( cmds ); + m_GUICommandStack.Clear(); + m_GUICommandStack.SetNum( cmds ); + for( i = 0; i < cmds; i++ ) { + savegame.ReadString( m_GUICommandStack[i] ); + } + savegame.RestoreObjects(); + + mpGame.Reset(); + + mpGame.Precache(); + + // free up any unused animations + animationLib.FlushUnusedAnims(); + + gamestate = GAMESTATE_ACTIVE; + + //FIX: Set the walkspeed back to the stored value. + pm_walkspeed.SetFloat( m_walkSpeed ); + + // Restore the physics pointer in the grabber. + gameLocal.m_Grabber->SetPhysicsFromDragEntity(); + + // Restore the CStim* pointers in the m_StimTimer list + m_StimTimer.SetNum(tempStimTimerIdList.Num()); + for (int i = 0; i < tempStimTimerIdList.Num(); i++) + { + m_StimTimer[i] = static_cast(FindStimResponse(tempStimTimerIdList[i]).get()); + } + + // Let the mission database know that we start playing + m_MissionManager->OnMissionStart(); + + Printf( "--------------------------------------\n" ); + + // Restart the timer + m_GamePlayTimer.Start(); + + return true; +} + +/* +=========== +idGameLocal::MapClear +=========== +*/ +void idGameLocal::MapClear( bool clearClients ) { + int i; + + for( i = ( clearClients ? 0 : MAX_CLIENTS ); i < MAX_GENTITIES; i++ ) { + delete entities[ i ]; + // ~idEntity is in charge of setting the pointer to NULL + // it will also clear pending events for this entity + assert( !entities[ i ] ); + spawnIds[ i ] = -1; + } + + entityHash.Clear( 1024, MAX_GENTITIES ); + + if ( !clearClients ) { + // add back the hashes of the clients + for ( i = 0; i < MAX_CLIENTS; i++ ) { + if ( !entities[ i ] ) { + continue; + } + entityHash.Add( entityHash.GenerateKey( entities[ i ]->name.c_str(), true ), i ); + } + } + + delete frameCommandThread; + frameCommandThread = NULL; + + if ( editEntities ) { + delete editEntities; + editEntities = NULL; + } + + delete[] locationEntities; + locationEntities = NULL; +} + +/* +=========== +idGameLocal::MapShutdown +============ +*/ +void idGameLocal::MapShutdown( void ) { + Printf( "--------- Game Map Shutdown ----------\n" ); + + gamestate = GAMESTATE_SHUTDOWN; + + if ( gameRenderWorld ) { + // clear any debug lines, text, and polygons + gameRenderWorld->DebugClearLines( 0 ); + gameRenderWorld->DebugClearPolygons( 0 ); + } + + // clear out camera if we're in a cinematic + if ( inCinematic ) { + camera = NULL; + inCinematic = false; + } + + // Run the grabber->clear() method before the entities get deleted from the map + if (m_Grabber != NULL) + { + m_Grabber->Clear(); + } + + MapClear( true ); + + // reset the script to the state it was before the map was started + program.Restart(); + + if ( smokeParticles ) { + smokeParticles->Shutdown(); + } + + /*! + * The Dark Mod LAS: shut down the LAS + */ + LAS.shutDown(); + + pvs.Shutdown(); + + // Remove the grabber entity itself (note that it's safe to pass NULL pointers to delete) + delete m_Grabber; + m_Grabber = NULL; + + m_sndProp->Clear(); + if (m_RelationsManager != NULL) + { + m_RelationsManager->Clear(); + } + if (m_ConversationSystem != NULL) + { + m_ConversationSystem->Clear(); + } + + m_DifficultyManager.Clear(); + + if (m_ModelGenerator != NULL) + { + m_ModelGenerator->Print(); + m_ModelGenerator->Clear(); + } + if (m_ImageMapManager != NULL) + { + m_ImageMapManager->Clear(); + } + + if (m_LightController != NULL) + { + m_LightController->Clear(); + } + if (m_I18N != NULL) + { + m_I18N->Clear(); + } + + // greebo: Don't clear the shop - MapShutdown() is called right before loading a map + // m_Shop->Clear(); + + clip.Shutdown(); + idClipModel::ClearTraceModelCache(); + + ShutdownAsyncNetwork(); + + mapFileName.Clear(); + + gameRenderWorld = NULL; + gameSoundWorld = NULL; + + gamestate = GAMESTATE_NOMAP; + + // Save the current walkspeed + m_walkSpeed = pm_walkspeed.GetFloat(); + + Printf( "--------------------------------------\n" ); +} + +/* +=================== +idGameLocal::DumpOggSounds +=================== +*/ +void idGameLocal::DumpOggSounds( void ) { + int i, j, k, size, totalSize; + idFile *file; + idStrList oggSounds, weaponSounds; + const idSoundShader *soundShader; + const soundShaderParms_t *parms; + idStr soundName; + + for ( i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++ ) { + soundShader = static_cast(declManager->DeclByIndex( DECL_SOUND, i, false )); + parms = soundShader->GetParms(); + + if ( soundShader->EverReferenced() && soundShader->GetState() != DS_DEFAULTED ) { + + const_cast(soundShader)->EnsureNotPurged(); + + for ( j = 0; j < soundShader->GetNumSounds(); j++ ) { + soundName = soundShader->GetSound( j ); + soundName.BackSlashesToSlashes(); + + // don't OGG sounds that cause a shake because that would + // cause continuous seeking on the OGG file which is expensive + if ( parms->shakes != 0.0f ) { + shakeSounds.AddUnique( soundName ); + continue; + } + + // if not voice over or combat chatter + if ( soundName.Find( "/vo/", false ) == -1 && + soundName.Find( "/combat_chatter/", false ) == -1 && + soundName.Find( "/enpro/", false ) == - 1 ) { + // don't OGG weapon sounds + if ( soundName.Find( "weapon", false ) != -1 || + soundName.Find( "gun", false ) != -1 || + soundName.Find( "bullet", false ) != -1 || + soundName.Find( "plasma", false ) != -1 ) { + weaponSounds.AddUnique( soundName ); + continue; + } + } + + for ( k = 0; k < shakeSounds.Num(); k++ ) { + if ( shakeSounds[k].IcmpPath( soundName ) == 0 ) { + break; + } + } + if ( k < shakeSounds.Num() ) { + continue; + } + + oggSounds.AddUnique( soundName ); + } + } + } + + file = fileSystem->OpenFileWrite( "makeogg.bat", "fs_savepath" ); + if ( file == NULL ) { + common->Warning( "Couldn't open makeogg.bat" ); + return; + } + + // list all the shake sounds + totalSize = 0; + for ( i = 0; i < shakeSounds.Num(); i++ ) { + size = fileSystem->ReadFile( shakeSounds[i], NULL, NULL ); + totalSize += size; + shakeSounds[i].Replace( "/", "\\" ); + file->Printf( "echo \"%s\" (%d kB)\n", shakeSounds[i].c_str(), size >> 10 ); + } + file->Printf( "echo %d kB in shake sounds\n\n\n", totalSize >> 10 ); + + // list all the weapon sounds + totalSize = 0; + for ( i = 0; i < weaponSounds.Num(); i++ ) { + size = fileSystem->ReadFile( weaponSounds[i], NULL, NULL ); + totalSize += size; + weaponSounds[i].Replace( "/", "\\" ); + file->Printf( "echo \"%s\" (%d kB)\n", weaponSounds[i].c_str(), size >> 10 ); + } + file->Printf( "echo %d kB in weapon sounds\n\n\n", totalSize >> 10 ); + + // list commands to convert all other sounds to ogg + totalSize = 0; + for ( i = 0; i < oggSounds.Num(); i++ ) { + size = fileSystem->ReadFile( oggSounds[i], NULL, NULL ); + totalSize += size; + oggSounds[i].Replace( "/", "\\" ); + file->Printf( "w:\\doom\\ogg\\oggenc -q 0 \"c:\\doom\\base\\%s\"\n", oggSounds[i].c_str() ); + file->Printf( "del \"c:\\doom\\base\\%s\"\n", oggSounds[i].c_str() ); + } + file->Printf( "\n\necho %d kB in OGG sounds\n\n\n", totalSize >> 10 ); + + fileSystem->CloseFile( file ); + + shakeSounds.Clear(); +} + +/* +=================== +idGameLocal::GetShakeSounds +=================== +*/ +void idGameLocal::GetShakeSounds( const idDict *dict ) { + const idSoundShader *soundShader; + const char *soundShaderName; + idStr soundName; + + soundShaderName = dict->GetString( "s_shader" ); + if ( soundShaderName != '\0' && dict->GetFloat( "s_shakes" ) != 0.0f ) { + soundShader = declManager->FindSound( soundShaderName ); + + for ( int i = 0; i < soundShader->GetNumSounds(); i++ ) { + soundName = soundShader->GetSound( i ); + soundName.BackSlashesToSlashes(); + + shakeSounds.AddUnique( soundName ); + } + } +} + +/* +=================== +idGameLocal::CacheDictionaryMedia + +This is called after parsing an EntityDef and for each entity spawnArgs before +merging the entitydef. It could be done post-merge, but that would +avoid the fast pre-cache check associated with each entityDef +=================== +*/ +void idGameLocal::CacheDictionaryMedia( const idDict *dict ) { + const idKeyValue *kv; + + if ( dict == NULL ) { + if ( cvarSystem->GetCVarBool( "com_makingBuild") ) { + DumpOggSounds(); + } + return; + } + + if ( cvarSystem->GetCVarBool( "com_makingBuild" ) ) { + GetShakeSounds( dict ); + } + + kv = dict->MatchPrefix( "model" ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->MediaPrint( "Precaching model %s\n", kv->GetValue().c_str() ); + // precache model/animations + if ( declManager->FindType( DECL_MODELDEF, kv->GetValue(), false ) == NULL ) { + // precache the render model + renderModelManager->FindModel( kv->GetValue() ); + // precache .cm files only + collisionModelManager->LoadModel( kv->GetValue(), true ); + // load any tdm_matinfo decls for materials referenced by the model + tdmDeclTDM_MatInfo::precacheModel( renderModelManager->FindModel( kv->GetValue() ) ); + } + } + kv = dict->MatchPrefix( "model", kv ); + } + + kv = dict->FindKey( "s_shader" ); + if ( kv && kv->GetValue().Length() ) { + declManager->FindType( DECL_SOUND, kv->GetValue() ); + } + + kv = dict->MatchPrefix( "snd", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_SOUND, kv->GetValue() ); + } + kv = dict->MatchPrefix( "snd", kv ); + } + + + kv = dict->MatchPrefix( "gui", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + if ( !idStr::Icmp( kv->GetKey(), "gui_noninteractive" ) + || !idStr::Icmpn( kv->GetKey(), "gui_parm", 8 ) + || !idStr::Icmp( kv->GetKey(), "gui_inventory" ) ) { + // unfortunate flag names, they aren't actually a gui + } else { + declManager->MediaPrint( "Precaching gui %s\n", kv->GetValue().c_str() ); + idUserInterface *gui = uiManager->Alloc(); + if ( gui ) { + gui->InitFromFile( kv->GetValue() ); + uiManager->DeAlloc( gui ); + } + } + } + kv = dict->MatchPrefix( "gui", kv ); + } + + kv = dict->FindKey( "texture" ); + if ( kv && kv->GetValue().Length() ) { + declManager->FindType( DECL_MATERIAL, kv->GetValue() ); + declManager->FindType( DECL_TDM_MATINFO, kv->GetValue() ); + } + + kv = dict->MatchPrefix( "mtr", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_MATERIAL, kv->GetValue() ); + declManager->FindType( DECL_TDM_MATINFO, kv->GetValue() ); + } + kv = dict->MatchPrefix( "mtr", kv ); + } + + // handles hud icons + kv = dict->MatchPrefix( "inv_icon", NULL ); + while ( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_MATERIAL, kv->GetValue() ); + } + kv = dict->MatchPrefix( "inv_icon", kv ); + } + + // handles teleport fx.. this is not ideal but the actual decision on which fx to use + // is handled by script code based on the teleport number + kv = dict->MatchPrefix( "teleport", NULL ); + if ( kv && kv->GetValue().Length() ) { + int teleportType = atoi( kv->GetValue() ); + const char *p = ( teleportType ) ? va( "fx/teleporter%i.fx", teleportType ) : "fx/teleporter.fx"; + declManager->FindType( DECL_FX, p ); + } + + kv = dict->MatchPrefix( "fx", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->MediaPrint( "Precaching fx %s\n", kv->GetValue().c_str() ); + declManager->FindType( DECL_FX, kv->GetValue() ); + } + kv = dict->MatchPrefix( "fx", kv ); + } + + kv = dict->MatchPrefix( "smoke", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + idStr prtName = kv->GetValue(); + int dash = prtName.Find('-'); + if ( dash > 0 ) { + prtName = prtName.Left( dash ); + } + declManager->FindType( DECL_PARTICLE, prtName ); + } + kv = dict->MatchPrefix( "smoke", kv ); + } + + kv = dict->MatchPrefix( "skin", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->MediaPrint( "Precaching skin %s\n", kv->GetValue().c_str() ); + declManager->FindType( DECL_SKIN, kv->GetValue() ); + } + kv = dict->MatchPrefix( "skin", kv ); + } + + kv = dict->MatchPrefix( "def", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + FindEntityDef( kv->GetValue().c_str(), false ); + } + kv = dict->MatchPrefix( "def", kv ); + } + + kv = dict->MatchPrefix( "video", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_VIDEO, kv->GetValue().c_str(), false ); + } + kv = dict->MatchPrefix( "video", kv ); + } + + kv = dict->MatchPrefix( "audio", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_AUDIO, kv->GetValue().c_str(), false ); + } + kv = dict->MatchPrefix( "audio", kv ); + } + + kv = dict->MatchPrefix( "xdata", NULL ); + while( kv ) { + if ( kv->GetValue().Length() ) { + declManager->FindType( DECL_XDATA, kv->GetValue().c_str(), false ); + } + kv = dict->MatchPrefix( "xdata", kv ); + } +} + +/* +=========== +idGameLocal::InitScriptForMap +============ +*/ +void idGameLocal::InitScriptForMap( void ) { + // create a thread to run frame commands on + frameCommandThread = new idThread(); + frameCommandThread->ManualDelete(); + frameCommandThread->SetThreadName( "frameCommands" ); + + // run the main game script function (not the level specific main) + const function_t *func = program.FindFunction( SCRIPT_DEFAULTFUNC ); + if ( func != NULL ) { + idThread *thread = new idThread( func ); + if ( thread->Start() ) { + // thread has finished executing, so delete it + delete thread; + } + } +} + +/* +=========== +idGameLocal::SpawnPlayer +============ +*/ +void idGameLocal::SpawnPlayer( int clientNum ) +{ + // they can connect + Printf( "SpawnPlayer: %i\n", clientNum ); + + idStr playerClass = isMultiplayer ? "player_tdm_thief_mp" : cv_player_spawnclass.GetString(); + + // greebo: Allow worldspawn to specify a different player classname + if (!isMultiplayer && world != NULL && world->spawnArgs.FindKey("player_classname") != NULL) + { + playerClass = world->spawnArgs.GetString("player_classname", cv_player_spawnclass.GetString()); + } + + idDict args; + args.SetInt( "spawn_entnum", clientNum ); + args.Set( "name", va( "player%d", clientNum + 1 ) ); + args.Set( "classname", playerClass ); + + idEntity *ent; + if ( !SpawnEntityDef( args, &ent ) || !entities[ clientNum ] ) + { + Error( "Failed to spawn player as '%s'", args.GetString( "classname" ) ); + } + + // make sure it's a compatible class + if ( !ent->IsType( idPlayer::Type ) ) { + Error( "'%s' spawned the player as a '%s'. Player spawnclass must be a subclass of idPlayer.", args.GetString( "classname" ), ent->GetClassname() ); + } + + if ( clientNum >= numClients ) { + numClients = clientNum + 1; + } + + mpGame.SpawnPlayer( clientNum ); +} + +/* +================ +idGameLocal::GetClientByNum +================ +*/ +idPlayer *idGameLocal::GetClientByNum( int current ) const { + if ( current < 0 || current >= numClients ) { + current = 0; + } + if ( entities[current] ) { + return static_cast( entities[ current ] ); + } + return NULL; +} + +/* +================ +idGameLocal::GetClientByName +================ +*/ +idPlayer *idGameLocal::GetClientByName( const char *name ) const { + int i; + idEntity *ent; + for ( i = 0 ; i < numClients ; i++ ) { + ent = entities[ i ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + if ( idStr::IcmpNoColor( name, userInfo[ i ].GetString( "ui_name" ) ) == 0 ) { + return static_cast( ent ); + } + } + } + return NULL; +} + +/* +================ +idGameLocal::GetClientByCmdArgs +================ +*/ +idPlayer *idGameLocal::GetClientByCmdArgs( const idCmdArgs &args ) const { + idPlayer *player; + idStr client = args.Argv( 1 ); + if ( !client.Length() ) { + return NULL; + } + // we don't allow numeric ui_name so this can't go wrong + if ( client.IsNumeric() ) { + player = GetClientByNum( atoi( client.c_str() ) ); + } else { + player = GetClientByName( client.c_str() ); + } + if ( !player ) { + common->Printf( "Player '%s' not found\n", client.c_str() ); + } + return player; +} + +/* +================ +idGameLocal::GetNextClientNum +================ +*/ +int idGameLocal::GetNextClientNum( int _current ) const { + int i, current; + + current = 0; + for ( i = 0; i < numClients; i++) { + current = ( _current + i + 1 ) % numClients; + if ( entities[ current ] && entities[ current ]->IsType( idPlayer::Type ) ) { + return current; + } + } + + return current; +} + +/* +================ +idGameLocal::GetLocalPlayer + +Nothing in the game tic should EVER make a decision based on what the +local client number is, it shouldn't even be aware that there is a +draw phase even happening. This just returns client 0, which will +be correct for single player. +================ +*/ +idPlayer *idGameLocal::GetLocalPlayer() const { + if ( localClientNum < 0 ) { + return NULL; + } + + if ( !entities[ localClientNum ] || !entities[ localClientNum ]->IsType( idPlayer::Type ) ) { + // not fully in game yet + return NULL; + } + return static_cast( entities[ localClientNum ] ); +} + +/* +================ +idGameLocal::SetupClientPVS +================ +*/ +pvsHandle_t idGameLocal::GetClientPVS( idPlayer *player, pvsType_t type ) { + if ( player->GetPrivateCameraView() ) { + return pvs.SetupCurrentPVS( player->GetPrivateCameraView()->GetPVSAreas(), player->GetPrivateCameraView()->GetNumPVSAreas() ); + } else if ( camera ) { + return pvs.SetupCurrentPVS( camera->GetPVSAreas(), camera->GetNumPVSAreas() ); + } else { + return pvs.SetupCurrentPVS( player->GetPVSAreas(), player->GetNumPVSAreas() ); + } +} + +/* +================ +idGameLocal::SetupPlayerPVS +================ +*/ +void idGameLocal::SetupPlayerPVS( void ) { + int i; + idEntity * ent; + idPlayer * player; + pvsHandle_t otherPVS, newPVS; + + playerPVS.i = -1; + for ( i = 0; i < numClients; i++ ) { + ent = entities[i]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + + player = static_cast(ent); + + if ( playerPVS.i == -1 ) { + playerPVS = GetClientPVS( player, PVS_NORMAL ); + } else { + otherPVS = GetClientPVS( player, PVS_NORMAL ); + newPVS = pvs.MergeCurrentPVS( playerPVS, otherPVS ); + pvs.FreeCurrentPVS( playerPVS ); + pvs.FreeCurrentPVS( otherPVS ); + playerPVS = newPVS; + } + + if ( playerConnectedAreas.i == -1 ) { + playerConnectedAreas = GetClientPVS( player, PVS_CONNECTED_AREAS ); + } else { + otherPVS = GetClientPVS( player, PVS_CONNECTED_AREAS ); + newPVS = pvs.MergeCurrentPVS( playerConnectedAreas, otherPVS ); + pvs.FreeCurrentPVS( playerConnectedAreas ); + pvs.FreeCurrentPVS( otherPVS ); + playerConnectedAreas = newPVS; + } + + + // if portalSky is preset, then merge into pvs so we get rotating brushes, etc + + if ( portalSkyEnt.GetEntity() ) { + idEntity *skyEnt = portalSkyEnt.GetEntity(); + + otherPVS = pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); + newPVS = pvs.MergeCurrentPVS( playerPVS, otherPVS ); + pvs.FreeCurrentPVS( playerPVS ); + pvs.FreeCurrentPVS( otherPVS ); + playerPVS = newPVS; + + otherPVS = pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); + newPVS = pvs.MergeCurrentPVS( playerConnectedAreas, otherPVS ); + pvs.FreeCurrentPVS( playerConnectedAreas ); + pvs.FreeCurrentPVS( otherPVS ); + playerConnectedAreas = newPVS; + } + } +} + +/* +================ +idGameLocal::FreePlayerPVS +================ +*/ +void idGameLocal::FreePlayerPVS( void ) { + if ( playerPVS.i != -1 ) { + pvs.FreeCurrentPVS( playerPVS ); + playerPVS.i = -1; + } + if ( playerConnectedAreas.i != -1 ) { + pvs.FreeCurrentPVS( playerConnectedAreas ); + playerConnectedAreas.i = -1; + } +} + +/* +================ +idGameLocal::InPlayerPVS + + should only be called during entity thinking and event handling +================ +*/ +bool idGameLocal::InPlayerPVS( idEntity *ent ) const { + if ( playerPVS.i == -1 ) { + return false; + } + return pvs.InCurrentPVS( playerPVS, ent->GetPVSAreas(), ent->GetNumPVSAreas() ); +} + +/* +================ +idGameLocal::InPlayerConnectedArea + + should only be called during entity thinking and event handling +================ +*/ +bool idGameLocal::InPlayerConnectedArea( idEntity *ent ) const { + if ( playerConnectedAreas.i == -1 ) { + return false; + } + return pvs.InCurrentPVS( playerConnectedAreas, ent->GetPVSAreas(), ent->GetNumPVSAreas() ); +} + +/* +================ +idGameLocal::UpdateGravity +================ +*/ +void idGameLocal::UpdateGravity( void ) { + idEntity *ent; + + if ( g_gravity.IsModified() ) { + if ( g_gravity.GetFloat() == 0.0f ) { + g_gravity.SetFloat( 1.0f ); + } + gravity.Set( 0, 0, -g_gravity.GetFloat() ); + + // update all physics objects + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( idAFEntity_Generic::Type ) ) { + idPhysics *phys = ent->GetPhysics(); + if ( phys ) { + phys->SetGravity( gravity ); + } + } + } + g_gravity.ClearModified(); + } +} + +/* +================ +idGameLocal::GetGravity +================ +*/ +const idVec3 &idGameLocal::GetGravity( void ) const { + return gravity; +} + +/* +================ +idGameLocal::SortActiveEntityList + + Sorts the active entity list such that pushing entities come first, + actors come next and physics team slaves appear after their master. +================ +*/ +void idGameLocal::SortActiveEntityList( void ) { + idEntity *ent, *next_ent, *master, *part; + + // if the active entity list needs to be reordered to place physics team masters at the front + if ( sortTeamMasters ) { + for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { + next_ent = ent->activeNode.Next(); + master = ent->GetTeamMaster(); + if ( master && master == ent ) { + ent->activeNode.Remove(); + ent->activeNode.AddToFront( activeEntities ); + } + } + } + + // if the active entity list needs to be reordered to place pushers at the front + if ( sortPushers ) { + + for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { + next_ent = ent->activeNode.Next(); + master = ent->GetTeamMaster(); + if ( !master || master == ent ) { + // check if there is an actor on the team + for ( part = ent; part != NULL; part = part->GetNextTeamEntity() ) { + if ( part->GetPhysics()->IsType( idPhysics_Actor::Type ) ) { + break; + } + } + // if there is an actor on the team + if ( part ) { + ent->activeNode.Remove(); + ent->activeNode.AddToFront( activeEntities ); + } + } + } + + for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { + next_ent = ent->activeNode.Next(); + master = ent->GetTeamMaster(); + if ( !master || master == ent ) { + // check if there is an entity on the team using parametric physics + for ( part = ent; part != NULL; part = part->GetNextTeamEntity() ) { + if ( part->GetPhysics()->IsType( idPhysics_Parametric::Type ) ) { + break; + } + } + // if there is an entity on the team using parametric physics + if ( part ) { + ent->activeNode.Remove(); + ent->activeNode.AddToFront( activeEntities ); + } + } + } + } + + sortTeamMasters = false; + sortPushers = false; +} + +/* +================ +idGameLocal::RunFrame +================ +*/ +gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) { + idEntity * ent; + int num(-1); + float ms; + idTimer timer_think, timer_events, timer_singlethink; + gameReturn_t ret; + idPlayer *player; + const renderView_t *view; + int curframe = framenum; + + g_Global.m_Frame = curframe; + DM_LOG(LC_FRAME, LT_INFO)LOGSTRING("Frame start\r"); + +#ifdef _DEBUG + if ( isMultiplayer ) { + assert( !isClient ); + } +#endif + + player = GetLocalPlayer(); + + // Handle any mission downloads in progress + m_DownloadManager->ProcessDownloads(); + + if (framenum == 0 && player != NULL && !player->IsReady()) + { + // greebo: This is the first game frame, handle the "click to start GUI" + if (m_GamePlayTimer.IsEnabled()) + { + m_GamePlayTimer.Stop(); + } + + // set the user commands for this frame + memcpy(usercmds, clientCmds, numClients * sizeof(usercmds[0])); + + if (player->WaitUntilReady()) + { + // Player got ready this frame, start timer + m_GamePlayTimer.Start(); + } + } + else + { + // Update the gameplay timer + m_GamePlayTimer.Update(); + + if ( !isMultiplayer && g_stopTime.GetBool() ) { + // clear any debug lines from a previous frame + gameRenderWorld->DebugClearLines( time + 1 ); + + // set the user commands for this frame + memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); + + if ( player ) { + player->Think(); + } + } + else do + { + // update the game time + framenum++; + previousTime = time; + time += (int)(msec * g_timeModifier.GetFloat()); + realClientTime = time; + +#ifdef GAME_DLL + // allow changing SIMD usage on the fly + if ( com_forceGenericSIMD.IsModified() ) { + idSIMD::InitProcessor( "game", com_forceGenericSIMD.GetBool() ); + } +#endif + + // make sure the random number counter is used each frame so random events + // are influenced by the player's actions + random.RandomInt(); + + if ( player ) { + // update the renderview so that any gui videos play from the right frame + view = player->GetRenderView(); + if ( view ) { + gameRenderWorld->SetRenderView( view ); + } + } + + // clear any debug lines from a previous frame + gameRenderWorld->DebugClearLines( time ); + + // clear any debug polygons from a previous frame + gameRenderWorld->DebugClearPolygons( time ); + + // set the user commands for this frame + memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); + + // free old smoke particles + smokeParticles->FreeSmokes(); + + // process events on the server + ServerProcessEntityNetworkEventQueue(); + + // update our gravity vector if needed. + UpdateGravity(); + + // create a merged pvs for all players + SetupPlayerPVS(); + + idTimer lasTimer; + lasTimer.Clear(); + lasTimer.Start(); + // The Dark Mod + // 10/9/2005: SophisticatedZombie + // Update the Light Awareness System + LAS.updateLASState(); + lasTimer.Stop(); + DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("Time to update LAS: %lf\r", lasTimer.Milliseconds()); + + unsigned long ticks = static_cast(sys->GetClockTicks()); + + // Tick the timers. Should be done before stim/response, just to be safe. :) + ProcessTimer(ticks); + + // TDM: Work through the active stims/responses + ProcessStimResponse(ticks); + + // TDM: Update objective system + m_MissionData->UpdateObjectives(); + + // sort the active entity list + SortActiveEntityList(); + + timer_think.Clear(); + timer_think.Start(); + + // let entities think + if ( g_timeentities.GetFloat() ) { + num = 0; + for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + if ( g_cinematic.GetBool() && inCinematic && !ent->cinematic ) { + ent->GetPhysics()->UpdateTime( time ); + if (ent->IsType(idAI::Type)) // grayman #2654 - update m_lastThinkTime to keep non-cinematic AI from dying at CrashLand() + { + static_cast(ent)->m_lastThinkTime = time; + } + continue; + } + timer_singlethink.Clear(); + timer_singlethink.Start(); + ent->Think(); + timer_singlethink.Stop(); + ms = timer_singlethink.Milliseconds(); + if ( ms >= g_timeentities.GetFloat() ) { + Printf( "%d: entity '%s': %.1f ms\n", time, ent->name.c_str(), ms ); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("%d: entity '%s': %.3f ms\r", time, ent->name.c_str(), ms ); + } + num++; + } + } else { + if ( inCinematic ) { + num = 0; + for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + if ( g_cinematic.GetBool() && !ent->cinematic ) { + ent->GetPhysics()->UpdateTime( time ); + if (ent->IsType(idAI::Type)) // grayman #2654 - update m_lastThinkTime to keep non-cinematic AI from dying at CrashLand() + { + static_cast(ent)->m_lastThinkTime = time; + } + continue; + } + ent->Think(); + num++; + } + } else { + num = 0; + for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + ent->Think(); + num++; + } + } + } + + // remove any entities that have stopped thinking + if ( numEntitiesToDeactivate ) { + idEntity *next_ent; + int c = 0; + for( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { + next_ent = ent->activeNode.Next(); + if ( !ent->thinkFlags ) { + ent->activeNode.Remove(); + c++; + } + } + //assert( numEntitiesToDeactivate == c ); + numEntitiesToDeactivate = 0; + } + + timer_think.Stop(); + + //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Thinking timer: %lfms\r", timer_think.Milliseconds()); + + timer_events.Clear(); + timer_events.Start(); + + // service any pending events + idEvent::ServiceEvents(); + + timer_events.Stop(); + + // Process the active AI conversations + m_ConversationSystem->ProcessConversations(); + + // free the player pvs + FreePlayerPVS(); + + // do multiplayer related stuff + if ( isMultiplayer ) { + mpGame.Run(); + } + + if ( cv_music_volume.IsModified() ) { //SnoopJeDi, fade that sound! + float music_vol = cv_music_volume.GetFloat(); + for ( int i = 0; i < musicSpeakers.Num(); i++ ) { + idSound* ent = static_cast(entities[ musicSpeakers[ i ] ]); + // Printf( " Fading speaker %s (index %i) to %f\n", ent->name.c_str(), i, music_vol); + if (ent) + ent->Event_FadeSound( 0, music_vol, 0.5 ); + } + cv_music_volume.ClearModified(); + } + + // display how long it took to calculate the current game frame + if ( g_frametime.GetBool() ) { + Printf( "game %d: all:%.1f th:%.1f ev:%.1f %d ents \n", + time, timer_think.Milliseconds() + timer_events.Milliseconds(), + timer_think.Milliseconds(), timer_events.Milliseconds(), num ); + } + + // build the return value + ret.consistencyHash = 0; + ret.sessionCommand[0] = 0; + + if ( !isMultiplayer && player ) { + ret.health = player->health; + ret.heartRate = player->heartRate; + ret.stamina = idMath::FtoiFast( player->stamina ); + // combat is a 0-100 value based on lastHitTime and lastDmgTime + // each make up 50% of the time spread over 10 seconds + ret.combat = 0; + if ( player->lastDmgTime > 0 && time < player->lastDmgTime + 10000 ) { + ret.combat += int(50.0f * (float) ( time - player->lastDmgTime ) / 10000); + } + if ( player->lastHitTime > 0 && time < player->lastHitTime + 10000 ) { + ret.combat += int(50.0f * (float) ( time - player->lastHitTime ) / 10000); + } + } + + // Check for final save trigger - the player PVS is freed at this point, so we can go ahead and save the game + if (m_TriggerFinalSave) + { + m_TriggerFinalSave = false; + + idStr savegameName = va("Mission %d Final Save", m_MissionManager->GetCurrentMissionIndex() + 1); + cmdSystem->BufferCommandText(CMD_EXEC_NOW, va("savegame '%s'", savegameName.c_str())); + } + + // see if a target_sessionCommand has forced a changelevel + if ( sessionCommand.Length() ) { + strncpy( ret.sessionCommand, sessionCommand, sizeof( ret.sessionCommand ) ); + break; + } + + // make sure we don't loop forever when skipping a cinematic + if ( skipCinematic && ( time > cinematicMaxSkipTime ) ) { + Warning( "Exceeded maximum cinematic skip length. Cinematic may be looping infinitely." ); + skipCinematic = false; + break; + } + + if (m_DoLightgem) + { + player->ProcessLightgem(cv_lg_hud.GetInteger() == 0); + m_DoLightgem = false; + } + + } while( ( inCinematic || ( time < cinematicStopTime ) ) && skipCinematic ); + } + + ret.syncNextGameFrame = skipCinematic; + if ( skipCinematic ) { + soundSystem->SetMute( false ); + skipCinematic = false; + } + + // show any debug info for this frame + RunDebugInfo(); + D_DrawDebugLines(); + + DM_LOG(LC_FRAME, LT_INFO)LOGSTRING("Frame end %d - %d: all:%.1f th:%.1f ev:%.1f %d ents \r", + time, timer_think.Milliseconds() + timer_events.Milliseconds(), + timer_think.Milliseconds(), timer_events.Milliseconds(), num ); + + g_Global.m_Frame = 0; + + return ret; +} + + +/* +====================================================================== + + Game view drawing + +====================================================================== +*/ + +/* +==================== +idGameLocal::CalcFov + +Calculates the horizontal and vertical field of view based on a horizontal field of view and custom aspect ratio +==================== +*/ +void idGameLocal::CalcFov( float base_fov, float &fov_x, float &fov_y ) const { + float x; + float y; + float ratio_x; + float ratio_y; + float ratio_fov; + + if ( !sys->FPU_StackIsEmpty() ) { + Printf( sys->FPU_GetState() ); + Error( "idGameLocal::CalcFov: FPU stack not empty" ); + } + + // first, calculate the vertical fov based on a 640x480 view + x = 640.0f / tan( base_fov / 360.0f * idMath::PI ); + y = atan2( 480.0f, x ); + fov_y = y * 360.0f / idMath::PI; + + // FIXME: somehow, this is happening occasionally + assert( fov_y > 0 ); + if ( fov_y <= 0 ) { + Printf( sys->FPU_GetState() ); + Error( "idGameLocal::CalcFov: bad result" ); + } + + // if r_fovRatio != 0, use it directly: + ratio_fov = cv_r_fovRatio.GetFloat(); + + if (ratio_fov > 0.01) + { + ratio_x = ratio_fov; + ratio_y = 1.0f; + } + else + { + // old code, use r_aspectRatio + switch( r_aspectRatio.GetInteger() ) { + default : + case 0 : + // 4:3 + fov_x = base_fov; + return; + break; + case 1 : + // 16:9 + case 4 : + // TV 16:9 + ratio_x = 16.0f; + ratio_y = 9.0f; + break; + case 2 : + // 16:10 + ratio_x = 16.0f; + ratio_y = 10.0f; + break; + case 3 : + // 5:4 + ratio_x = 5.0f; + ratio_y = 4.0f; + break; + } + } + +// Printf( "Using FOV ratio %0.3f:%0.0f\n", ratio_x, ratio_y ); + + y = ratio_y / tan( fov_y / 360.0f * idMath::PI ); + fov_x = atan2( ratio_x, y ) * 360.0f / idMath::PI; + + if ( fov_x < base_fov ) { + fov_x = base_fov; + x = ratio_x / tan( fov_x / 360.0f * idMath::PI ); + fov_y = atan2( ratio_y, x ) * 360.0f / idMath::PI; + } + + // FIXME: somehow, this is happening occasionally + assert( ( fov_x > 0 ) && ( fov_y > 0 ) ); + if ( ( fov_y <= 0 ) || ( fov_x <= 0 ) ) { + Printf( sys->FPU_GetState() ); + Error( "idGameLocal::CalcFov: bad result" ); + } +} + +/* +================ +idGameLocal::Draw + +makes rendering and sound system calls +================ +*/ +bool idGameLocal::Draw( int clientNum ) +{ + if ( isMultiplayer ) { + return mpGame.Draw( clientNum ); + } + + idPlayer *player = static_cast(entities[ clientNum ]); + + if ( !player ) { + return false; + } + + // render the scene + player->playerView.RenderPlayerView(player->hud); + + // Make the rendershot appear on the hud + if (cv_lg_hud.GetInteger() != 0) + { + player->ProcessLightgem(true); + } + + m_DoLightgem = true; + return true; +} + +/* +================ +idGameLocal::HandleESC +================ +*/ +escReply_t idGameLocal::HandleESC( idUserInterface **gui ) { + + if ( isMultiplayer ) { + *gui = StartMenu(); + // we may set the gui back to NULL to hide it + return ESC_GUI; + } + + // If we're in the process of ending the mission, ignore all ESC keys. + if (GameState() == GAMESTATE_COMPLETED) { + return ESC_IGNORE; + } + + // greebo: Hitting the ESC key means that the main menu is about to be entered => stop the timer + m_GamePlayTimer.Stop(); + + idPlayer *player = GetLocalPlayer(); + if ( player ) { + if ( player->HandleESC() ) { + m_GamePlayTimer.SetEnabled(true); + return ESC_IGNORE; + } else { + return ESC_MAIN; + } + } + return ESC_MAIN; +} + +/* +================ +idGameLocal::StartMenu +================ +*/ +idUserInterface* idGameLocal::StartMenu( void ) { + if ( !isMultiplayer ) { + return NULL; + } + return mpGame.StartMenu(); +} + +/* +================ +idGameLocal::HandleGuiCommands +================ +*/ +const char* idGameLocal::HandleGuiCommands( const char *menuCommand ) { + if ( !isMultiplayer ) { + return NULL; + } + return mpGame.HandleGuiCommands( menuCommand ); +} + +int idGameLocal::LoadVideosFromString(const char* videosStr, const char* lengthStr, idList& targetList) +{ + targetList.Clear(); + + std::string videos = videosStr; + std::string lengths = lengthStr; + + // Remove leading and trailing semicolons + boost::algorithm::trim_if(videos, boost::algorithm::is_any_of(";")); + boost::algorithm::trim_if(lengths, boost::algorithm::is_any_of(";")); + + // Split strings into parts + std::vector vidParts; + std::vector lengthParts; + + boost::algorithm::split(vidParts, videos, boost::algorithm::is_any_of(";")); + boost::algorithm::split(lengthParts, lengths, boost::algorithm::is_any_of(";")); + + if (vidParts.size() != lengthParts.size()) + { + gameLocal.Warning("The video string array '%s' does not have the same number of elements as the length array '%s'!", videosStr, lengthStr); + return 0; + } + + if (vidParts.size() == 0) + { + return 0; + } + + int totalLength = 0; + + for (std::size_t i = 0; i < vidParts.size(); ++i) + { + BriefingVideoPart& part = targetList.Alloc(); + + part.material = vidParts[i].c_str(); + part.lengthMsec = atoi(lengthParts[i].c_str()); + + if (part.lengthMsec <= 0) + { + gameLocal.Warning("The video length %s is invalid or not numeric, must be an integer > 0", lengthParts[i].c_str()); + part.lengthMsec = 0; + } + + totalLength += part.lengthMsec; + } + + return totalLength; +} + +void idGameLocal::UpdateScreenResolutionFromGUI(idUserInterface* gui) +{ + if (cvarSystem->GetCVarInteger("r_aspectRatio") > 0) + { + // Wide-screen resolution selected in the GUI, set the mode to "custom" + cvarSystem->SetCVarInteger("r_mode", -1); + + // Set the custom height and width + int mode = cv_tdm_widescreenmode.GetInteger(); + + int width = 1024; + int height = 600; + + switch (mode) + { + case 0: + width = 1024; + height = 600; + break; + case 1: + width = 1280; + height = 800; + break; + case 2: + width = 1440; + height = 900; + break; + case 3: + width = 1680; + height = 1050; + break; + case 4: + width = 1920; + height = 1200; + break; + case 5: + width = 1366; + height = 768; + break; + case 6: + width = 1280; + height = 720; + break; + case 7: + width = 1920; + height = 1080; + break; + case 8: + width = 2560; + height = 1440; + break; + case 9: + width = 2560; + height = 1600; + break; + case 10: + width = 1280; + height = 1024; + break; + case 11: + width = 1800; + height = 1440; + break; + case 12: + width = 2560; + height = 2048; + break; + case 13: + width = 1360; + height = 768; + break; + case 14: + width = 1600; + height = 900; + break; + case 15: + width = 3280; + height = 2048; + break; + case 16: + width = 3360; + height = 2100; + break; + case 17: + width = 3840; + height = 2160; + break; + case 18: + width = 3840; + height = 2400; + break; + default: + break; + }; + + Printf("Widesreenmode %i, setting r_customWidth=%i, r_customHeight=%i\n", mode, width, height); + cvarSystem->SetCVarInteger("r_customWidth", width); + cvarSystem->SetCVarInteger("r_customHeight", height); + } + else + { + // Not widescreen, set r_mode to something reasonable (1024x768) + cvarSystem->SetCVarInteger("r_mode", 5); + } +} + +void idGameLocal::HandleGuiMessages(idUserInterface* ui) +{ + if (m_GuiMessages.Num() == 0) return; + + const GuiMessage& msg = m_GuiMessages[0]; + + ui->SetStateBool("MsgBoxVisible", true); + + ui->SetStateString("MsgBoxTitle", msg.title); + ui->SetStateString("MsgBoxText", msg.message); + + switch (msg.type) + { + case GuiMessage::MSG_OK: + ui->SetStateBool("MsgBoxLeftButtonVisible", false); + ui->SetStateBool("MsgBoxRightButtonVisible", false); + ui->SetStateBool("MsgBoxMiddleButtonVisible", true); + ui->SetStateString("MsgBoxMiddleButtonText", m_I18N->Translate("#str_04339")); // OK + break; + case GuiMessage::MSG_OK_CANCEL: + ui->SetStateBool("MsgBoxLeftButtonVisible", true); + ui->SetStateBool("MsgBoxRightButtonVisible", true); + ui->SetStateBool("MsgBoxMiddleButtonVisible", false); + + ui->SetStateString("MsgBoxLeftButtonText", m_I18N->Translate("#str_04339")); // OK + ui->SetStateString("MsgBoxRightButtonText", m_I18N->Translate("#str_07203")); // Cancel + break; + case GuiMessage::MSG_YES_NO: + ui->SetStateBool("MsgBoxLeftButtonVisible", true); + ui->SetStateBool("MsgBoxRightButtonVisible", true); + ui->SetStateBool("MsgBoxMiddleButtonVisible", false); + + ui->SetStateString("MsgBoxLeftButtonText", m_I18N->Translate("#str_02501")); // Yes + ui->SetStateString("MsgBoxRightButtonText", m_I18N->Translate("#str_02502")); // No + break; + }; + + ui->SetStateString("MsgBoxRightButtonCmd", msg.negativeCmd); + ui->SetStateString("MsgBoxLeftButtonCmd", msg.positiveCmd); + ui->SetStateString("MsgBoxMiddleButtonCmd", msg.okCmd); + + m_GuiMessages.RemoveIndex(0); +} + +/* +================ +idGameLocal::UpdateGUIScaling +================ +*/ +void idGameLocal::UpdateGUIScaling( idUserInterface *gui ) +{ + float wobble = 1.0f; + // this could be turned into a warble-wobble effect f.i. for player poisoned etc. + //float wobble = random.RandomFloat() * 0.02 + 0.98; + + float x_mul = cvarSystem->GetCVarFloat("gui_Width") * wobble; + if (x_mul < 0.1f) { x_mul = 0.1f; } + if (x_mul > 2.0f) { x_mul = 2.0f; } + float y_mul = cvarSystem->GetCVarFloat("gui_Height") * wobble; + if (y_mul < 0.1f) { y_mul = 0.1f; } + if (y_mul > 2.0f) { y_mul = 2.0f; } + float x_shift = cvarSystem->GetCVarFloat("gui_CenterX") * 640 * wobble; + float y_shift = cvarSystem->GetCVarFloat("gui_CenterY") * 480 * wobble; +// Printf("UpdateGUIScaling: width %0.2f height %0.2f centerX %0.02ff centerY %0.02f\n (%p)", x_mul, y_mul, x_shift, y_shift, gui); + gui->SetStateFloat("LEFT", x_shift - x_mul * 320); + gui->SetStateFloat("CENTERX", x_shift); + gui->SetStateFloat("TOP", y_shift - y_mul * 240); + gui->SetStateFloat("CENTERY", y_shift); + gui->SetStateFloat("WIDTH", x_mul); + gui->SetStateFloat("HEIGHT", y_mul); + // We have only one scaling factor to scale text, so use the average of X and Y + // This will have odd effects if W and H differ greatly, but is better than to not scale the text + gui->SetStateFloat("SCALE", (y_mul + x_mul) / 2); +} + +/* +================ +idGameLocal::initChoice + +Init a GUI or CVAR variable (including GUI text) from a list of choices and values. +================ +*/ +bool idGameLocal::InitGUIChoice( idUserInterface *gui, const char *varName, const char *inChoices, const char *inValues, const bool step) +{ + idStr cvarName = varName; + std::string choices = gameLocal.m_I18N->Translate( inChoices ); + std::string values = inValues; + + // figure out the current setting + idCVar *cvar = NULL; + + // special case: use this gui variable + if (cvarName.Left(5) != "gui::") + { + cvar = cvarSystem->Find( cvarName.c_str() ); + if (!cvar) + { + // ignore, the GUI command buffer was probably just overrun + Warning("initChoice: Cannot find CVAR '%s'.", cvarName.c_str() ); + return false; + } + } + // split the choices into a listt + std::vector choiceParts; + std::vector valuesParts; + boost::algorithm::split(choiceParts, choices, boost::algorithm::is_any_of(";")); + boost::algorithm::split(valuesParts, values, boost::algorithm::is_any_of(";")); + + if (choiceParts.size() != valuesParts.size()) + { + gameLocal.Warning("The choices string array '%s' does not have the same number of elements as the values array '%s' for %s!", + choices.c_str(), values.c_str(), cvarName.c_str() ); //gameLocal.m_I18N->Translate( m_GUICommandStack[2] ), m_GUICommandStack[3].c_str(), cvarName.c_str() ); + return false; + } + if (choiceParts.size() <= 0) + { + gameLocal.Warning("The choices and values string arrays are empty for %s.", cvarName.c_str()); + return false; + } + + // read out the current setting (this also works with boolean CVARs, as these are simply "0", "1") + idStr curValue; + if (cvar) + { + curValue = cvar->GetString(); + } + else + { + curValue = gui->GetStateString( cvarName.Right( cvarName.Length() -5 ).c_str(), "0" ); + } + + // Figure out the index of the selected choice/value pair by looking at all the values + int iSelected = -1; + for (unsigned int i = 0; i < valuesParts.size(); i++) + { + if (curValue == idStr( valuesParts[i].c_str() )) + { + // found it + iSelected = i; + i = valuesParts.size(); + break; + } + } + + // Printf("Current value: %s (index: %i)\n", curValue.c_str(), iSelected); + if (iSelected < 0) + { + gameLocal.Warning("The current value for %s (%s) is not in the list of valid choices '%s'.", cvarName.c_str(), curValue.c_str(), values.c_str()); + return false; + } + + // should we advance the setting? + if ( step ) + { + iSelected ++; + if ( (unsigned int)iSelected >= valuesParts.size()) + { + // wrap around + iSelected = 0; + } + // set the new value + Printf("Setting %s to %s (index: %i)\n", cvarName.c_str(), valuesParts[ iSelected ].c_str(), iSelected); + if (cvar) + { + cvar->SetString( valuesParts[ iSelected ].c_str() ); + } + } + + // Printf( "Setting %s to %s\n", GUIVar.c_str(), choiceParts[iSelected].c_str() ); + if (!cvar) + { + cvarName = cvarName.Right( cvarName.Length() -5 ); // remove "gui::" prefix + } + // store the value in "gui::cvarname", so the GUI can access it (important f.i. for the bloom slider visibility) + // Printf( "Setting %s to %s\n", cvarName.c_str(), valuesParts[iSelected].c_str() ); + gui->SetStateString( cvarName.c_str(), valuesParts[iSelected].c_str() ); + // and set it as text label + idStr GUIVar = cvarName + "_text"; // f.i.: tdm_menu_music_text + gui->SetStateString( GUIVar.c_str(), choiceParts[iSelected].c_str() ); + + return true; +} + +/* +================ +idGameLocal::HandleMainMenuCommands +================ +*/ +void idGameLocal::HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) +{ + /* Tels: This routine here is called for every "command" in the menu GUI. Unfortunately, + the interpretation of what is a command works a bit strange (as almost everything + else does in idTech4 :) + + In the following examples, there is usually another call to this routine with ";" + as the "menuCommand" param. But sometimes it does not appear, depending on whoknows. + + The following will cause this routine called twice (!), once with "mainmenu_heartbeat" + and once with ";" as command (if you add ";" before the last double quote, it will + still be called only twice): + + set "cmd" "mainmenu_heartbeat"; + + This will call it twice (or three times counting ";") with "mycommand" "myarg" and ";": + + set "cmd" "mycommand 'test'"; + + This calls it only once (!) (two times counting ";"), with "play": + + Set "play mymusic"; + + This calls it twice (three times counting ";"), with "notime" and then "1": + + Set "noTime" "1"; + + Note that the command buffer has only a certain, unknown length, and if too many + commands are issued in the same timeframe (onTime X..), then the buffer will overflow, + and certain commands might get cut-off. Usually this means that you see a ";" instead + of an expected argument, or that commands run together like "initChoicelog". When this + happens, the GUI must be adjusted to issue less commands (or issue them later). + To work around this issue, we call ExecuteCommandBuffer( void ) whenever we see an + initChoice command, in the hopes that the buffer won't overflow until the next one. + + The old code simply watched for certain words, and then issued the command. It was not + able to distinguish between commands and arguments. + + This routine now watches for the first command, ignoring any stray ";". If it sees + a command, it deduces the number of following arguments, and then collects them until + it has all of them, warning if there is a ";" coming unexpectedly. + + Once all arguments are collected, the command is finally handled, or silently ignored. + */ + if (!menuCommand || menuCommand[0] == 0x00) + { + // silently ignore + Warning("Seen NULL MainMenu cmd."); + return; + } + + int numArgs = m_GUICommandStack.Num(); + + if (numArgs == 0) + { + if ( menuCommand[0] == ';' && menuCommand[1] == 0x0 ) + { + // ignore stray any ";" + return; + } + + // have not seen anything? + idStr cmd = menuCommand; + // commands can appear in any case (like "notime", "noTime" etc) + cmd.ToLower(); + m_GUICommandStack.Append(cmd); + + // set the number of wanted args, default is none + m_GUICommandArgs = 0; + + // "log" and "notime" take one argument + if ( cmd == "log" || cmd == "notime") { m_GUICommandArgs = 1; } + // these two take 3 arguments each + if ( cmd == "initchoice" || cmd == "stepchoice") { m_GUICommandArgs = 3; } + // this takes one argument + if ( cmd == "setlang") { m_GUICommandArgs = 1; } + + if ( cmd != "log" && cmd != "mainmenu_heartbeat") + { +// Printf("Seen command '%s' ('%s'), takes %i args.\n", menuCommand, cmd.c_str(), m_GUICommandArgs ); + } + } + else + { + // append the current argument to the stack (but not if it is ";") + if ( menuCommand[0] != ';' || menuCommand[1] != 0x0 ) + { + m_GUICommandStack.Alloc() = menuCommand; +// Printf(" Seen argument '%s' for '%s'\n", menuCommand, m_GUICommandStack[0].c_str() ); + } + else + { + // seen a ";" even tho we have not yet as many arguments as we wanted? + if (numArgs - 1 < m_GUICommandArgs) + { + //Warning("MainMenu command %s takes %i arguments, but has only %i (last arg %s).\n", m_GUICommandStack[0].c_str(), m_GUICommandArgs, numArgs - 1, menuCommand); + Warning("Seen stray ';' - command %s takes %i arguments, but has only %i (last arg %s).\n", m_GUICommandStack[0].c_str(), m_GUICommandArgs, numArgs - 1, menuCommand); + // Ignore any stray ";" as they can be injected anywhere :( + numArgs = m_GUICommandArgs; + return; + } + } + } + + // Printf(" have %i vs wanted %i\n", numArgs, m_GUICommandArgs); + // do we have already as much arguments as we want? + if (numArgs < m_GUICommandArgs) + { + // no, wait for the next argument + return; + } + + // the command + const idStr& cmd = m_GUICommandStack[0]; + + // seen the command and its arguments, now handle it +/* if (cmd != "mainmenu_heartbeat" && cmd != "log") + { + // debug output, but ignore the frequent ones + Printf("MainMenu cmd: %s (%i args)\n", cmd.c_str(), numArgs); + } +*/ + + // Watch out for objectives GUI-related commands + // TODO: Handle here commands with arguments, too. + m_MissionData->HandleMainMenuCommands(cmd, gui); + + if (cmd == "mainmenu_heartbeat") + { + // greebo: Stop the timer, this is already done in HandleESC, but just to make sure... + m_GamePlayTimer.Stop(); + + if (GetMissionResult() == MISSION_COMPLETE) + { + // Check if we should show the success screen (also check the member variable + // to catch cases where the player reloaded the map via the console) + if (!gui->GetStateBool("PostMissionScreenActive") || !postMissionScreenActive) + { + // Check if this mission has a debriefing video + int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; // GUI mission numbers are 1-based + + const char* videoMaterials = gui->GetStateString(va("DebriefingVideoMaterials%d", missionNum)); + const char* videoLengths = gui->GetStateString(va("DebriefingVideoLengths%d", missionNum)); + const char* videoSoundCmd = gui->GetStateString(va("DebriefingVideoSoundCmd%d", missionNum)); + + // Calculate the total length of the video + int videoLengthMsec = LoadVideosFromString(videoMaterials, videoLengths, debriefingVideo); + + gui->SetStateInt("DebriefingVideoLength", videoLengthMsec); + gui->SetStateString("DebriefingVideoSoundCmd", videoSoundCmd); + + // Let the GUI know whether we have a debriefing video + gui->SetStateBool("HasDebriefingVideo", debriefingVideo.Num() > 0); + + // Show the post-mission GUI (might be a debriefing video or just the success screen) + gui->HandleNamedEvent("ShowPostMissionScreen"); + + // Avoid duplicate triggering + gui->SetStateBool("PostMissionScreenActive", true); + postMissionScreenActive = true; + } + + // tels: We handled this command, so clear the command stack + m_GUICommandStack.Clear(); + m_GUICommandArgs = 0; + return; + } + + // Check if any errors are in the queue + if (!m_guiError.IsEmpty()) + { + // Send the error to the GUI + gui->SetStateString("gameErrorMsg", m_guiError); + gui->HandleNamedEvent("OnGameError"); + + // Clear the string again + m_guiError.Empty(); + } + + // Check messages + if (m_GuiMessages.Num() > 0) + { + HandleGuiMessages(gui); + } + + // Make sure we have a valid mission number in the GUI, the first mission is always 1 + int curMissionNum = gui->GetStateInt("CurrentMission"); + + if (curMissionNum <= 0) + { + gui->SetStateInt("CurrentMission", 1); + } + + // Handle downloads in progress + m_DownloadManager->ProcessDownloads(); + + // Propagate the video CVARs to the GUI + gui->SetStateInt("video_aspectratio", cvarSystem->GetCVarInteger("r_aspectRatio")); + gui->SetStateBool("confirmQuit", cv_mainmenu_confirmquit.GetBool()); + gui->SetStateBool("menu_bg_music", cv_tdm_menu_music.GetBool()); + + if (cv_tdm_menu_music.IsModified()) + { + gui->HandleNamedEvent("OnMenuMusicSettingChanged"); + + cv_tdm_menu_music.ClearModified(); + } + } + else if (cmd == "setvideoreswidescreen") + { + // Called when widescreen size selection changes + UpdateScreenResolutionFromGUI(gui); + UpdateGUIScaling(gui); + } + else if (cmd == "aspectratiochanged") + { + UpdateScreenResolutionFromGUI(gui); + UpdateGUIScaling(gui); + } + else if (cmd == "loadcustomvideoresolution") + { + if (cvarSystem->GetCVarInteger("r_mode") == -1) + { + // Just set the state variable based on width + int width = cvarSystem->GetCVarInteger("r_customWidth"); + int height = cvarSystem->GetCVarInteger("r_customHeight"); + + switch (width) + { + case 1024: cv_tdm_widescreenmode.SetInteger(0); break; + // 1280 x 800 => 1 + // 1280 x 720 => 6 + // 1280 x 1024 => 10 + case 1280: cv_tdm_widescreenmode.SetInteger(height == 800 ? 1 : (height == 720 ? 6 : 10) ); break; + case 1360: cv_tdm_widescreenmode.SetInteger(13); break; + case 1366: cv_tdm_widescreenmode.SetInteger(5); break; + case 1440: cv_tdm_widescreenmode.SetInteger(2); break; + // 1600 x 900 + case 1600: cv_tdm_widescreenmode.SetInteger(14); break; + case 1680: cv_tdm_widescreenmode.SetInteger(3); break; + // 1800 x 1440 + case 1800: cv_tdm_widescreenmode.SetInteger(11); break; + case 1920: cv_tdm_widescreenmode.SetInteger(height == 1200 ? 4 : 7); break; + // 2560 x 1440 => 8 + // 2560 x 1600 => 9 + // 2560 x 2048 => 12 + case 2560: cv_tdm_widescreenmode.SetInteger(height == 1440 ? 8 : height == 1600 ? 9 : 12); break; + // 3280 x 2048 + case 3280: cv_tdm_widescreenmode.SetInteger(15); break; + // 3360 x 2100 + case 3360: cv_tdm_widescreenmode.SetInteger(16); break; + // 3840 x 2160 => 17 + // 3840 x 2400 => 18 + case 3840: cv_tdm_widescreenmode.SetInteger( height == 2160 ? 17 : 18); break; + default: cv_tdm_widescreenmode.SetInteger(0); break; + } + Printf("Widescreenmode was set to: %i (%ix%i)\n", cv_tdm_widescreenmode.GetInteger(), width, height ); + } + UpdateGUIScaling(gui); + } + // greebo: the "log" command is used to write stuff to the console + else if (cmd == "log") + { + // We should log the given argument + if (cv_debug_mainmenu.GetBool()) + { + Printf("MainMenu: %s\n", m_GUICommandStack[1].c_str() ); + } + + DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("%s\r", m_GUICommandStack[1].c_str() ); + } + else if (cmd == "close") + { + // Solarsplace: fix for #2424: + mainMenuExited = true; + + // Start the timer again, we're closing the menu + m_GamePlayTimer.Start(); + } + else if (cmd == "loadvideodefinitions") + { + // Check if we've set up the briefing video + if (!briefingVideoInfoLoaded) + { + briefingVideoInfoLoaded = true; + + // Tell the briefing video GUI to load all video materials into the state dict + gui->HandleNamedEvent("LoadVideoDefinitions"); + gui->HandleNamedEvent("LoadDebriefingVideoDefinitions"); + } + } + else if (cmd == "preparebriefingvideo") + { + // Ensure we've set up the briefing video (should already be done in "loadVideoDefinitions") + assert(briefingVideoInfoLoaded); + + // Check the video defs + int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; + + const char* videoMaterials = gui->GetStateString(va("BriefingVideoMaterials%d", missionNum)); + const char* videoLengths = gui->GetStateString(va("BriefingVideoLengths%d", missionNum)); + const char* videoSoundCmd = gui->GetStateString(va("BriefingVideoSoundCmd%d", missionNum)); + + // Calculate the total length of the video + int videoLengthMsec = LoadVideosFromString(videoMaterials, videoLengths, briefingVideo); + + gui->SetStateInt("BriefingVideoLength", videoLengthMsec); + gui->SetStateString("BriefingVideoSoundCmd", videoSoundCmd); + + // We start with the first part + curBriefingVideoPart = 0; + } + else if (cmd == "startbriefingvideo") + { + if (curBriefingVideoPart >= 0 && curBriefingVideoPart < briefingVideo.Num()) + { + gui->SetStateString("BriefingVideoMaterial", briefingVideo[curBriefingVideoPart].material); + + // Let the video windowDef reset its cinematics + gui->HandleNamedEvent("OnBriefingVideoPartChanged"); + } + else + { + // No video + gui->HandleNamedEvent("OnBriefingVideoFinished"); + } + } + else if (cmd == "briefingvideoheartbeat") + { + if (curBriefingVideoPart >= 0 && curBriefingVideoPart < briefingVideo.Num()) + { + int videoTime = gui->GetStateInt("briefingVideoTime"); + + videoTime += 16; + + if (videoTime >= briefingVideo[curBriefingVideoPart].lengthMsec) + { + curBriefingVideoPart++; + + // Briefing video part time exceeded + if (curBriefingVideoPart < briefingVideo.Num()) + { + // Switch to the next + gui->SetStateString("BriefingVideoMaterial", briefingVideo[curBriefingVideoPart].material); + gui->HandleNamedEvent("OnBriefingVideoPartChanged"); + + // Each part starts at 0 again + videoTime = 0; + } + else + { + // We're done with the video + gui->HandleNamedEvent("OnBriefingVideoFinished"); + } + } + + gui->SetStateInt("briefingVideoTime", videoTime); + } + } + else if (cmd == "preparedebriefingvideo") + { + // Ensure we've set up the debriefing video (should already be done in "loadVideoDefinitions") + assert(briefingVideoInfoLoaded); + + // We start with the first part + curDebriefingVideoPart = 0; + } + else if (cmd == "startdebriefingvideo") + { + if (curDebriefingVideoPart >= 0 && curDebriefingVideoPart < debriefingVideo.Num()) + { + gui->SetStateString("DebriefingVideoMaterial", debriefingVideo[curDebriefingVideoPart].material); + + // Let the video windowDef reset its cinematics + gui->HandleNamedEvent("OnDebriefingVideoPartChanged"); + } + else + { + // No video + gui->HandleNamedEvent("OnDebriefingVideoFinished"); + } + } + else if (cmd == "debriefingvideoheartbeat") + { + if (curDebriefingVideoPart >= 0 && curDebriefingVideoPart < debriefingVideo.Num()) + { + int videoTime = gui->GetStateInt("debriefingVideoTime"); + + videoTime += 16; + + if (videoTime >= debriefingVideo[curDebriefingVideoPart].lengthMsec) + { + curDebriefingVideoPart++; + + // Briefing video part time exceeded + if (curDebriefingVideoPart < debriefingVideo.Num()) + { + // Switch to the next + gui->SetStateString("DebriefingVideoMaterial", debriefingVideo[curDebriefingVideoPart].material); + gui->HandleNamedEvent("OnDebriefingVideoPartChanged"); + + // Each part starts at 0 again + videoTime = 0; + } + else + { + // We're done with the video + gui->HandleNamedEvent("OnDebriefingVideoFinished"); + } + } + + gui->SetStateInt("debriefingVideoTime", videoTime); + } + } + else if (cmd == "onsuccessscreencontinueclicked") + { + // Clear the mission result flag + SetMissionResult(MISSION_NOTEVENSTARTED); + + // Set the boolean back to false for the next map start + gui->SetStateBool("PostMissionScreenActive", false); + postMissionScreenActive = false; + + // Switch to the next mission if there is one + if (m_MissionManager->NextMissionAvailable()) + { + m_MissionManager->ProceedToNextMission(); + + // Store the new mission number into the GUI state + int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; + gui->SetStateInt("CurrentMission", missionNum); + + // Go to the next briefing / video + gui->HandleNamedEvent("SuccessProceedToNextMission"); + } + else + { + // Switch back to the main menu + gui->HandleNamedEvent("SuccessGoBackToMainMenu"); + } + } + else if (cmd == "setlpdifficulty") + { + // Lockpicking difficulty setting changed, update CVARs + int setting = gui->GetStateInt("lp_difficulty", "-1"); + + switch (setting) + { + case 0: // Trainer + cv_lp_auto_pick.SetBool(false); + cv_lp_pick_timeout.SetInteger(750); + break; + case 1: // Average + cv_lp_auto_pick.SetBool(false); + cv_lp_pick_timeout.SetInteger(500); + break; + case 2: // Hard + cv_lp_auto_pick.SetBool(false); + cv_lp_pick_timeout.SetInteger(400); + break; + case 3: // Expert + cv_lp_auto_pick.SetBool(false); + cv_lp_pick_timeout.SetInteger(300); + break; + case 4: // Automatic + cv_lp_auto_pick.SetBool(true); + cv_lp_pick_timeout.SetInteger(500); // auto-LP is using average timeout + break; + default: + gameLocal.Warning("Unknown value for lockpicking difficulty encountered!"); + }; + } + // load various game play settings, and update the GUI strings in one go + else if (cmd == "loadsettings") + { + int setting = 0; + if (cv_lp_auto_pick.GetBool()) + { + setting = 4; // automatic + } + else // auto-pick is false + { + if (cv_lp_pick_timeout.GetInteger() >= 750) + { + setting = 0; // Trainer + } + else if (cv_lp_pick_timeout.GetInteger() >= 500) + { + setting = 1; // Average + } + else if (cv_lp_pick_timeout.GetInteger() >= 400) + { + setting = 2; // Hard + } + else // if (cv_lp_pick_timeout.GetInteger() >= 300) + { + setting = 3; // Expert (default) + } + } + gui->SetStateInt("lp_difficulty", setting); + + idStr diffString = cv_melee_difficulty.GetString(); + bool bForbidAuto = cv_melee_forbid_auto_parry.GetBool(); + + if( diffString == "hard" ) + { + setting = 1; // Hard + } + else if( diffString == "expert" && !bForbidAuto ) + { + setting = 2; // Expert + } + else if( diffString == "expert" && bForbidAuto ) + { + setting = 3; // Master + } + else + { + setting = 0; // Normal by default + } + gui->SetStateInt("melee_difficulty", setting); + + // init various GUI variables + InitGUIChoice( gui, "gui::lp_difficulty", "#str_07318", "0;1;2;3;4" ); + InitGUIChoice( gui, "gui::melee_difficulty", "#str_07319", "0;1;2;3" ); + InitGUIChoice( gui, "tdm_door_auto_open_on_unlock", "#str_04221", "0;1" ); + InitGUIChoice( gui, "tdm_inv_use_on_frob", "#str_07300", "0;1" ); + InitGUIChoice( gui, "tdm_inv_hud_pickupmessages", "#str_04221", "0;1" ); + InitGUIChoice( gui, "tdm_inv_use_visual_feedback", "#str_07300", "0;1" ); + InitGUIChoice( gui, "tdm_dragged_item_highlight", "#str_07300", "0;1" ); + InitGUIChoice( gui, "tdm_hud_hide_lightgem", "#str_04221", "0;1" ); + + // Have the gui enable/disable auto parry + gui->HandleNamedEvent("UpdateAutoParryOption"); + } + else if (cmd == "updatemeleedifficulty") + { + // Melee difficulty setting changed, update CVARs + int setting = gui->GetStateInt("melee_difficulty", "-1"); + + switch (setting) + { + case 0: // Normal + cv_melee_difficulty.SetString("normal"); + cv_melee_forbid_auto_parry.SetBool(false); + break; + case 1: // Hard + cv_melee_difficulty.SetString("hard"); + cv_melee_forbid_auto_parry.SetBool(false); + break; + case 2: // Expert + cv_melee_difficulty.SetString("expert"); + cv_melee_forbid_auto_parry.SetBool(false); + break; + case 3: // Master, same as expert but forces manual parry to be enabled + cv_melee_difficulty.SetString("expert"); + cv_melee_auto_parry.SetBool(false); + cv_melee_forbid_auto_parry.SetBool(true); + break; + default: + gameLocal.Warning("Unknown value for melee difficulty encountered!"); + }; + + // Trigger an update for the auto-parry option when melee difficulty changes + gui->HandleNamedEvent("UpdateAutoParryOption"); + } + else if (cmd == "mainmenu_init") + { + gui->SetStateString("tdmversiontext", va("TDM %d.%02d", TDM_VERSION_MAJOR, TDM_VERSION_MINOR)); + UpdateGUIScaling(gui); + gui->SetStateString( "tdm_lang", m_I18N->GetCurrentLanguage()->c_str() ); + idStr gui_lang = "lang_"; gui_lang += m_I18N->GetCurrentLanguage()->c_str(); + gui->SetStateInt( gui_lang, 1 ); + } + else if (cmd == "check_tdm_version") + { + CheckTDMVersion(); + } + else if (cmd == "close_msg_box") + { + gui->SetStateBool("MsgBoxVisible", false); + } + else if (cmd == "updatecookedmathdata") // Adding a way to update cooked data from menu - J.C.Denton + { + // Add the command to buffer, but no need to issue it immediately. + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "tdm_updateCookedMathData" ); + } + else if (cmd == "resetbrightness") + { + idCVar * cvar = cvarSystem->Find( "r_brightness" ); + cvar ? cvar->SetFloat( 1.0f ) : Warning("Cannot find CVAR r_brightness."); + } + else if (cmd == "resetgamma") + { + idCVar * cvar = cvarSystem->Find( "r_gamma" ); + cvar ? cvar->SetFloat( 1.2f ) : Warning("Cannot find CVAR r_gamma."); + } + else if (cmd == "onstartmissionclicked") + { + // First mission to be started, reset index + m_MissionManager->SetCurrentMissionIndex(0); + gui->SetStateInt("CurrentMission", 1); + + ClearPersistentInfo(); + } + else if (cmd == "setlang") + { + const idStr *oldLang = m_I18N->GetCurrentLanguage(); + idStr newLang = m_GUICommandStack[1]; + + // reset lang_oldname and enable lang_newname + idStr gui_lang = "lang_"; gui_lang += newLang; +// Printf ("Setting %s to 1.\n", gui_lang.c_str() ); + gui->SetStateInt( gui_lang, 1 ); + gui_lang = "lang_"; gui_lang += oldLang->c_str(); +// Printf ("Setting %s to 0.\n", gui_lang.c_str() ); + gui->SetStateInt( gui_lang, 0 ); + + // do this after the step above, or oldLang will be incorrect: + Printf("GUI: Language changed to %s.\n", newLang.c_str() ); + // set the new language and store it, will also reload the GUI + gameLocal.m_I18N->SetLanguage( newLang.c_str() ); + + // store it, so the GUI can access it + gui->SetStateString( "tdm_lang", m_I18N->GetCurrentLanguage()->c_str() ); + } + // tels: #2796 build our own "choicedef" as integer/boolean option. + else if (cmd == "initchoice" || cmd == "stepchoice") + { + // DEBUG +// Printf("GUI: %s\n", cmd.c_str()); +// for (int i = 0; i < numArgs; i++) +// { +// Printf( "'%s' ", m_GUICommandStack[i+1].c_str() ); +// } + // arguments are: cvar-name choices values + InitGUIChoice( gui, m_GUICommandStack[1].c_str(), m_GUICommandStack[2].c_str(), m_GUICommandStack[3].c_str(), cmd == "stepchoice" ? true : false ); + } +// else +// { +// Warning("Unknown main menu command '%s'.\n", cmd.c_str()); +// } + + // TODO: These routines might want to handle arguments to commands, too, so + // add support for this here. E.g. instead of passing ("SomeCommand", gui), pass + // (m_GUICommandStack, gui) to them: + if (cmd != "log") + { + m_Shop->HandleCommands( menuCommand, gui); + m_ModMenu->HandleCommands( menuCommand, gui); + m_DownloadMenu->HandleCommands( cmd, gui); // expects commands in lowercase + } + + /*if (cv_debug_mainmenu.GetBool()) + { + const idDict& state = gui->State(); + + for (int i = 0; i < state.GetNumKeyVals(); ++i) + { + const idKeyValue* kv = state.GetKeyVal(i); + + const idStr key = kv->GetKey(); + const idStr value = kv->GetValue(); + + // Force the log file to write its stuff + g_Global.m_ClassArray[LC_MISC] = true; + g_Global.m_LogArray[LT_INFO] = true; + + DM_LOG(LC_MISC, LT_INFO)LOGSTRING("Mainmenu GUI State %s = %s\r", key.c_str(), value.c_str()); + } + }*/ + + // tels: We handled (or ignored) this command, so clear the command stack + m_GUICommandStack.Clear(); + m_GUICommandArgs = 0; +} + +/* +================ +idGameLocal::GetLevelMap + + should only be used for in-game level editing +================ +*/ +idMapFile *idGameLocal::GetLevelMap( void ) { + if ( mapFile && mapFile->HasPrimitiveData()) { + return mapFile; + } + if ( !mapFileName.Length() ) { + return NULL; + } + + if ( mapFile ) { + delete mapFile; + } + + mapFile = new idMapFile; + if ( !mapFile->Parse( mapFileName ) ) { + delete mapFile; + mapFile = NULL; + } + + return mapFile; +} + +/* +================ +idGameLocal::GetMapName +================ +*/ +const char *idGameLocal::GetMapName( void ) const { + return mapFileName.c_str(); +} + +/* +================ +idGameLocal::CallFrameCommand +================ +*/ +void idGameLocal::CallFrameCommand( idEntity *ent, const function_t *frameCommand ) { + frameCommandThread->CallFunction( ent, frameCommand, true ); + frameCommandThread->Execute(); +} + +/* +================ +idGameLocal::CallObjectFrameCommand +================ +*/ +void idGameLocal::CallObjectFrameCommand( idEntity *ent, const char *frameCommand ) { + const function_t *func; + + func = ent->scriptObject.GetFunction( frameCommand ); + if ( !func ) { + if ( !ent->IsType( idTestModel::Type ) ) { + Error( "Unknown function '%s' called for frame command on entity '%s'", frameCommand, ent->name.c_str() ); + } + } else { + frameCommandThread->CallFunction( ent, func, true ); + frameCommandThread->Execute(); + } +} + +/* +================ +idGameLocal::ShowTargets +================ +*/ +void idGameLocal::ShowTargets( void ) { + idMat3 axis = GetLocalPlayer()->viewAngles.ToMat3(); + idVec3 up = axis[ 2 ] * 5.0f; + const idVec3 &viewPos = GetLocalPlayer()->GetPhysics()->GetOrigin(); + idBounds viewTextBounds( viewPos ); + idBounds viewBounds( viewPos ); + idBounds box( idVec3( -4.0f, -4.0f, -4.0f ), idVec3( 4.0f, 4.0f, 4.0f ) ); + idEntity *ent; + idEntity *target; + int i; + idBounds totalBounds; + + viewTextBounds.ExpandSelf( 128.0f ); + viewBounds.ExpandSelf( 512.0f ); + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + totalBounds = ent->GetPhysics()->GetAbsBounds(); + for( i = 0; i < ent->targets.Num(); i++ ) { + target = ent->targets[ i ].GetEntity(); + if ( target ) { + totalBounds.AddBounds( target->GetPhysics()->GetAbsBounds() ); + } + } + + if ( !viewBounds.IntersectsBounds( totalBounds ) ) { + continue; + } + + float dist; + idVec3 dir = totalBounds.GetCenter() - viewPos; + dir.NormalizeFast(); + totalBounds.RayIntersection( viewPos, dir, dist ); + float frac = ( 512.0f - dist ) / 512.0f; + if ( frac < 0.0f ) { + continue; + } + + gameRenderWorld->DebugBounds( ( ent->IsHidden() ? colorLtGrey : colorOrange ) * frac, ent->GetPhysics()->GetAbsBounds() ); + if ( viewTextBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { + idVec3 center = ent->GetPhysics()->GetAbsBounds().GetCenter(); + gameRenderWorld->DrawText( ent->name.c_str(), center - up, 0.1f, colorWhite * frac, axis, 1 ); + gameRenderWorld->DrawText( ent->GetEntityDefName(), center, 0.1f, colorWhite * frac, axis, 1 ); + gameRenderWorld->DrawText( va( "#%d", ent->entityNumber ), center + up, 0.1f, colorWhite * frac, axis, 1 ); + } + + for( i = 0; i < ent->targets.Num(); i++ ) { + target = ent->targets[ i ].GetEntity(); + if ( target ) { + gameRenderWorld->DebugArrow( colorYellow * frac, ent->GetPhysics()->GetAbsBounds().GetCenter(), target->GetPhysics()->GetOrigin(), 10, 0 ); + gameRenderWorld->DebugBounds( colorGreen * frac, box, target->GetPhysics()->GetOrigin() ); + } + } + } +} + +/* +================ +idGameLocal::RunDebugInfo +================ +*/ +void idGameLocal::RunDebugInfo( void ) { + idEntity *ent; + idPlayer *player; + + player = GetLocalPlayer(); + if ( !player ) { + return; + } + + const idVec3 &origin = player->GetPhysics()->GetOrigin(); + + if ( g_showEntityInfo.GetBool() ) { + idMat3 axis = player->viewAngles.ToMat3(); + idVec3 up = axis[ 2 ] * 5.0f; + idBounds viewTextBounds( origin ); + idBounds viewBounds( origin ); + + viewTextBounds.ExpandSelf( 128.0f ); + viewBounds.ExpandSelf( 512.0f ); + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + // don't draw the worldspawn + if ( ent == world ) { + continue; + } + + // skip if the entity is very far away + if ( !viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { + continue; + } + + const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); + int contents = ent->GetPhysics()->GetContents(); + if ( contents & CONTENTS_BODY ) { + gameRenderWorld->DebugBounds( colorCyan, entBounds ); + } else if ( contents & CONTENTS_TRIGGER ) { + gameRenderWorld->DebugBounds( colorOrange, entBounds ); + } else if ( contents & CONTENTS_SOLID ) { + gameRenderWorld->DebugBounds( colorGreen, entBounds ); + } else { + if ( !entBounds.GetVolume() ) { + gameRenderWorld->DebugBounds( colorMdGrey, entBounds.Expand( 8.0f ) ); + } else { + gameRenderWorld->DebugBounds( colorMdGrey, entBounds ); + } + } + if ( viewTextBounds.IntersectsBounds( entBounds ) ) { + gameRenderWorld->DrawText( ent->name.c_str(), entBounds.GetCenter(), 0.1f, colorWhite, axis, 1 ); + gameRenderWorld->DrawText( va( "#%d", ent->entityNumber ), entBounds.GetCenter() + up, 0.1f, colorWhite, axis, 1 ); + gameRenderWorld->DrawText( + va( "%d / %d", ent->GetPhysics()->GetContents(), ent->GetPhysics()->GetClipMask() ), + entBounds.GetCenter() - up, 0.1f, + colorWhite, + axis, 1 + ); + } + } + } + + // debug tool to draw bounding boxes around active entities + if ( g_showActiveEntities.GetBool() ) { + for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + idBounds b = ent->GetPhysics()->GetBounds(); + if ( b.GetVolume() <= 0 ) { + b[0][0] = b[0][1] = b[0][2] = -8; + b[1][0] = b[1][1] = b[1][2] = 8; + } + if ( ent->fl.isDormant ) { + gameRenderWorld->DebugBounds( colorYellow, b, ent->GetPhysics()->GetOrigin() ); + } else { + gameRenderWorld->DebugBounds( colorGreen, b, ent->GetPhysics()->GetOrigin() ); + } + } + } + + if ( g_showTargets.GetBool() ) { + ShowTargets(); + } + + if ( g_showTriggers.GetBool() ) { + idTrigger::DrawDebugInfo(); + } + + if ( cv_show_health.GetBool() ) { + idMat3 axis = player->viewAngles.ToMat3(); + idBounds viewBounds( origin ); + viewBounds.ExpandSelf( 512.0f ); + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + // don't draw the worldspawn or "dead" entities + if ( ent == world || !ent->health) { + continue; + } + + // skip if the entity is very far away + if ( !viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { + continue; + } + + gameRenderWorld->DrawText(va("Health: %d", ent->health), ent->GetPhysics()->GetOrigin(), 0.2f, colorGreen, axis); + } + } + + if ( ai_showCombatNodes.GetBool() ) { + idCombatNode::DrawDebugInfo(); + } + + if ( ai_showPaths.GetBool() ) { + idPathCorner::DrawDebugInfo(); + } + + if ( g_editEntityMode.GetBool() ) { + editEntities->DisplayEntities(); + } + + if ( g_showCollisionWorld.GetBool() ) { + collisionModelManager->DrawModel( 0, vec3_origin, mat3_identity, origin, 128.0f ); + } + + if ( g_showCollisionModels.GetBool() ) { + clip.DrawClipModels( player->GetEyePosition(), g_maxShowDistance.GetFloat(), pm_thirdPerson.GetBool() ? NULL : player ); + } + + if ( g_showCollisionTraces.GetBool() ) { + clip.PrintStatistics(); + } + + if ( g_showPVS.GetInteger() ) { + pvs.DrawPVS( origin, ( g_showPVS.GetInteger() == 2 ) ? PVS_ALL_PORTALS_OPEN : PVS_NORMAL ); + } + + if ( aas_test.GetInteger() >= 0 ) { + idAAS *aas = GetAAS( aas_test.GetInteger() ); + if ( aas ) { + aas->Test( origin ); + if ( ai_testPredictPath.GetBool() ) { + idVec3 velocity; + predictedPath_t path; + + velocity.x = cos( DEG2RAD( player->viewAngles.yaw ) ) * 100.0f; + velocity.y = sin( DEG2RAD( player->viewAngles.yaw ) ) * 100.0f; + velocity.z = 0.0f; + idAI::PredictPath( player, aas, origin, velocity, 1000, 100, SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA, path ); + } + } + } + + if ( ai_showObstacleAvoidance.GetInteger() == 2 ) { + idAAS *aas = GetAAS("aas32"); + if ( aas ) { + idVec3 seekPos; + obstaclePath_t path; + + seekPos = player->GetPhysics()->GetOrigin() + player->viewAxis[0] * 200.0f; + idAI::FindPathAroundObstacles( player->GetPhysics(), aas, NULL, player->GetPhysics()->GetOrigin(), seekPos, path, player ); + } + } + + // collision map debug output + collisionModelManager->DebugOutput( player->GetEyePosition() ); +} + +/* +================== +idGameLocal::NumAAS +================== +*/ +int idGameLocal::NumAAS( void ) const { + return aasList.Num(); +} + +/* +================== +idGameLocal::GetAASId (TDM) +================== +*/ +int idGameLocal::GetAASId( idAAS* aas ) const +{ + // Do a reverse lookup in the aasList array + return aasList.FindIndex(aas); +} + +/* +================== +idGameLocal::GetAAS +================== +*/ +idAAS *idGameLocal::GetAAS( int num ) const { + if ( ( num >= 0 ) && ( num < aasList.Num() ) ) { + if ( aasList[ num ] && aasList[ num ]->GetSettings() ) { + return aasList[ num ]; + } + } + return NULL; +} + +/* +================== +idGameLocal::GetAAS +================== +*/ +idAAS *idGameLocal::GetAAS( const char *name ) const { + int i; + + for ( i = 0; i < aasNames.Num(); i++ ) { + if ( aasNames[ i ] == name ) { + if ( !aasList[ i ]->GetSettings() ) { + return NULL; + } else { + return aasList[ i ]; + } + } + } + return NULL; +} + +/* +================== +idGameLocal::SetAASAreaState +================== +*/ +void idGameLocal::SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed ) { + int i; + + for( i = 0; i < aasList.Num(); i++ ) { + aasList[ i ]->SetAreaState( bounds, areaContents, closed ); + } +} + +/* +================== +idGameLocal::AddAASObstacle +================== +*/ +aasHandle_t idGameLocal::AddAASObstacle( const idBounds &bounds ) { + int i; + aasHandle_t obstacle; + aasHandle_t check; + + if ( !aasList.Num() ) { + return -1; + } + + obstacle = aasList[ 0 ]->AddObstacle( bounds ); + for( i = 1; i < aasList.Num(); i++ ) { + check = aasList[ i ]->AddObstacle( bounds ); + assert( check == obstacle ); + } + + return obstacle; +} + +/* +================== +idGameLocal::RemoveAASObstacle +================== +*/ +void idGameLocal::RemoveAASObstacle( const aasHandle_t handle ) { + int i; + + for( i = 0; i < aasList.Num(); i++ ) { + aasList[ i ]->RemoveObstacle( handle ); + } +} + +/* +================== +idGameLocal::RemoveAllAASObstacles +================== +*/ +void idGameLocal::RemoveAllAASObstacles( void ) { + int i; + + for( i = 0; i < aasList.Num(); i++ ) { + aasList[ i ]->RemoveAllObstacles(); + } +} + +void idGameLocal::SetupEAS() +{ + // Cycle through the entities and find all elevators + for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + if (!ent->IsType(CMultiStateMover::Type)) + { + continue; + } + + // Get all position entities of that mover + CMultiStateMover* mover = static_cast(ent); + + for (int aasNum = 0; aasNum < NumAAS(); aasNum++) + { + idAASLocal* aas = dynamic_cast(GetAAS(aasNum)); + if (aas == NULL) continue; + + aas->AddElevator(mover); + } + } + + // All elevators registered, compile the routing information + for (int aasNum = 0; aasNum < NumAAS(); aasNum++) + { + idAASLocal* aas = dynamic_cast(GetAAS(aasNum)); + if (aas == NULL) continue; + + aas->CompileEAS(); + } +} + +/* +================== +idGameLocal::CheatsOk +================== +*/ +bool idGameLocal::CheatsOk( bool requirePlayer ) { + idPlayer *player; + + if ( isMultiplayer && !cvarSystem->GetCVarBool( "net_allowCheats" ) ) { + Printf( "Not allowed in multiplayer.\n" ); + return false; + } + + if ( developer.GetBool() ) { + return true; + } + + player = GetLocalPlayer(); + if ( !requirePlayer || ( player && ( player->health > 0 ) ) ) { + return true; + } + + Printf( "You must be alive to use this command.\n" ); + + return false; +} + +/* +=================== +idGameLocal::RegisterEntity +=================== +*/ +void idGameLocal::RegisterEntity( idEntity *ent ) { + int spawn_entnum; + + if ( spawnCount >= ( 1 << ( 32 - GENTITYNUM_BITS ) ) ) { + Error( "idGameLocal::RegisterEntity: spawn count overflow" ); + } + + if ( !spawnArgs.GetInt( "spawn_entnum", "0", spawn_entnum ) ) { + while( entities[firstFreeIndex] && firstFreeIndex < ENTITYNUM_MAX_NORMAL ) { + firstFreeIndex++; + } + if ( firstFreeIndex >= ENTITYNUM_MAX_NORMAL ) { + Error( "no free entities" ); + } + spawn_entnum = firstFreeIndex++; + } + + entities[ spawn_entnum ] = ent; + spawnIds[ spawn_entnum ] = spawnCount++; + ent->entityNumber = spawn_entnum; + ent->spawnNode.AddToEnd( spawnedEntities ); + + // this will also have the effect of spawnArgs.Clear() at the same time: + ent->spawnArgs.TransferKeyValues( spawnArgs ); + + if ( spawn_entnum >= num_entities ) { + num_entities++; + } +} + +/* +=================== +idGameLocal::UnregisterEntity +=================== +*/ +void idGameLocal::UnregisterEntity( idEntity *ent ) { + assert( ent ); + + if ( editEntities ) { + editEntities->RemoveSelectedEntity( ent ); + } + + if ( ( ent->entityNumber != ENTITYNUM_NONE ) && ( entities[ ent->entityNumber ] == ent ) ) { + ent->spawnNode.Remove(); + entities[ ent->entityNumber ] = NULL; + spawnIds[ ent->entityNumber ] = -1; + if ( ent->entityNumber >= MAX_CLIENTS && ent->entityNumber < firstFreeIndex ) { + firstFreeIndex = ent->entityNumber; + } + ent->entityNumber = ENTITYNUM_NONE; + } +} + +/* +================ +idGameLocal::SpawnEntityType +================ +*/ +idEntity *idGameLocal::SpawnEntityType( const idTypeInfo &classdef, const idDict *args, bool bIsClientReadSnapshot ) { + idClass *obj; + +#if _DEBUG + if ( isClient ) { + assert( bIsClientReadSnapshot ); + } +#endif + + if ( !classdef.IsType( idEntity::Type ) ) { + Error( "Attempted to spawn non-entity class '%s'", classdef.classname ); + } + + try { + if ( args ) { + spawnArgs = *args; + } else { + spawnArgs.Clear(); + } + obj = classdef.CreateInstance(); + obj->CallSpawn(); + } + + catch( idAllocError & ) { + obj = NULL; + } + spawnArgs.Clear(); + + return static_cast(obj); +} + +/* +=================== +idGameLocal::SpawnEntityDef + +Finds the spawn function for the entity and calls it, +returning false if not found +=================== +*/ +bool idGameLocal::SpawnEntityDef( const idDict &args, idEntity **ent, bool setDefaults ) { + const char *classname; + const char *spawn; + idTypeInfo *cls; + idClass *obj; + idStr error; + const char *name; + + if ( ent ) { + *ent = NULL; + } + + spawnArgs = args; + + if ( spawnArgs.GetString( "name", "", &name ) ) { + sprintf( error, " on '%s'", name); + } + + spawnArgs.GetString( "classname", NULL, &classname ); + const idDeclEntityDef *def = FindEntityDef( classname, false ); + + if ( !def ) { + Warning( "Unknown classname '%s'%s.\n", classname, error.c_str() ); + return false; + } + + // Tels: SetDefaults(), but without the "editor_" spawnargs + spawnArgs.SetDefaults( &def->dict, idStr("editor_") ); + + // greebo: Apply the difficulty settings before any values get filled from the spawnarg data + m_DifficultyManager.ApplyDifficultySettings(spawnArgs); + + // check if we should spawn a class object + spawnArgs.GetString( "spawnclass", NULL, &spawn ); + if ( spawn ) { + + cls = idClass::GetClass( spawn ); + if ( !cls ) { + Warning( "Could not spawn '%s'. Class '%s' not found%s.", classname, spawn, error.c_str() ); + return false; + } + + obj = cls->CreateInstance(); + if ( !obj ) { + Warning( "Could not spawn '%s'. Instance could not be created%s.", classname, error.c_str() ); + return false; + } + + obj->CallSpawn(); + + if ( ent && obj->IsType( idEntity::Type ) ) { + *ent = static_cast(obj); + } + + // Check for campaign info ents + if (idStr::Cmp(classname, "atdm:campaign_info") == 0) + { + assert(obj->IsType(idEntity::Type)); + campaignInfoEntities.Append(static_cast(obj)); + } + + return true; + } + + // check if we should call a script function to spawn + spawnArgs.GetString( "spawnfunc", NULL, &spawn ); + if ( spawn ) { + const function_t *func = program.FindFunction( spawn ); + if ( !func ) { + Warning( "Could not spawn '%s'. Script function '%s' not found%s.", classname, spawn, error.c_str() ); + return false; + } + idThread *thread = new idThread( func ); + thread->DelayedStart( 0 ); + return true; + } + + Warning( "%s doesn't include a spawnfunc or spawnclass%s.", classname, error.c_str() ); + return false; +} + +/* +================ +idGameLocal::FindEntityDef +================ +*/ +const idDeclEntityDef *idGameLocal::FindEntityDef( const char *name, bool makeDefault ) const { + const idDecl *decl = NULL; + if ( isMultiplayer ) { + decl = declManager->FindType( DECL_ENTITYDEF, va( "%s_mp", name ), false ); + } + if ( !decl ) { + decl = declManager->FindType( DECL_ENTITYDEF, name, makeDefault ); + } + return static_cast( decl ); +} + +/* +================ +idGameLocal::FindEntityDefDict +================ +*/ +const idDict *idGameLocal::FindEntityDefDict( const char *name, bool makeDefault ) const { + const idDeclEntityDef *decl = FindEntityDef( name, makeDefault ); + return decl ? &decl->dict : NULL; +} + +/* +================ +idGameLocal::InhibitEntitySpawn +================ +*/ +bool idGameLocal::InhibitEntitySpawn( idDict &spawnArgs ) { + + bool result = false; + + /* greebo: Disabled vanilla D3 stuff, will be handled by our DifficultyManager + if ( isMultiplayer ) { + spawnArgs.GetBool( "not_multiplayer", "0", result ); + } else if ( g_skill.GetInteger() == 0 ) { + spawnArgs.GetBool( "not_easy", "0", result ); + } else if ( g_skill.GetInteger() == 1 ) { + spawnArgs.GetBool( "not_medium", "0", result ); + } else { + spawnArgs.GetBool( "not_hard", "0", result ); + } + + const char *name; +#ifndef ID_DEMO_BUILD + if ( g_skill.GetInteger() == 3 ) { + name = spawnArgs.GetString( "classname" ); + if ( idStr::Icmp( name, "item_medkit" ) == 0 || idStr::Icmp( name, "item_medkit_small" ) == 0 ) { + result = true; + } + } +#endif + + }*/ + + // Consult the difficulty manager, whether this entity should be prevented from being spawned. + result = m_DifficultyManager.InhibitEntitySpawn(spawnArgs); + + return result; +} + +/* +================ +idGameLocal::SetSkill +================ +*/ +void idGameLocal::SetSkill( int value ) { + int skill_level; + + if ( value < 0 ) { + skill_level = 0; + } else if ( value > 3 ) { + skill_level = 3; + } else { + skill_level = value; + } + + g_skill.SetInteger( skill_level ); +} + +/* +============== +idGameLocal::GameState + +Used to allow entities to know if they're being spawned during the initial spawn. +============== +*/ +gameState_t idGameLocal::GameState( void ) const { + return gamestate; +} + +void idGameLocal::PrepareForMissionEnd() +{ + // Raise the gamestate to "Completed" + gamestate = GAMESTATE_COMPLETED; + + // Remove mission triggers now that we're done here + for (int i = 0; i < m_InterMissionTriggers.Num(); ) + { + if (m_InterMissionTriggers[i].missionNum == m_MissionManager->GetCurrentMissionIndex()) + { + m_InterMissionTriggers.RemoveIndex(i); + } + else + { + ++i; + } + } +} + +/* +============== +idGameLocal::SpawnMapEntities + +Parses textual entity definitions out of an entstring and spawns gentities. +============== +*/ +void idGameLocal::SpawnMapEntities( void ) { + int i; + int num; + int inhibit; + idMapEntity *mapEnt; + int numEntities; + idDict args; + + Printf( "Spawning entities\n" ); + + if ( mapFile == NULL ) { + Printf("No mapfile present\n"); + return; + } + + SetSkill( g_skill.GetInteger() ); + + // Add the lightgem to the map before anything else happened + // so it will be included as if it were a regular map entity. + m_lightGem.SpawnLightGemEntity( mapFile ); + + numEntities = mapFile->GetNumEntities(); + if ( numEntities == 0 ) { + Error( "...no entities" ); + } + + // the worldspawn is a special that performs any global setup + // needed by a level + mapEnt = mapFile->GetEntity( 0 ); + args = mapEnt->epairs; + args.SetInt( "spawn_entnum", ENTITYNUM_WORLD ); + if ( !SpawnEntityDef( args ) || !entities[ ENTITYNUM_WORLD ] || !entities[ ENTITYNUM_WORLD ]->IsType( idWorldspawn::Type ) ) { + Error( "Problem spawning world entity" ); + } + + num = 1; + inhibit = 0; + + // Clear out the campaign info cache + campaignInfoEntities.Clear(); + + for ( i = 1 ; i < numEntities ; i++ ) { + mapEnt = mapFile->GetEntity( i ); + args = mapEnt->epairs; + +#ifdef LOGBUILD + // Tels: This might need a lot of time, even when the logging is disabled, so make + // sure we execute this loop only if we need to log: + if(g_Global.m_ClassArray[LC_ENTITY] == true && g_Global.m_LogArray[LT_DEBUG] == true) + { + int n = args.GetNumKeyVals(); + for(int x = 0; x < n; x++) + { + const idKeyValue *p = args.GetKeyVal(x); + const idStr k = p->GetKey(); + const idStr v = p->GetValue(); + DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity[%u] Key:[%s] = [%s]\r", i, k.c_str(), v.c_str()); + } + } +#endif + + if (!InhibitEntitySpawn(args)) + { + // precache any media specified in the map entity + CacheDictionaryMedia(&args); + + SpawnEntityDef(args); + num++; + } else { + inhibit++; + } + } + + m_lightGem.InitializeLightGemEntity(); + + Printf( "...%i entities spawned, %i inhibited\n\n", num, inhibit ); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("... %i entities spawned, %i inhibited\r", num, inhibit); +} + +/* +================ +idGameLocal::AddEntityToHash +================ +*/ +void idGameLocal::AddEntityToHash( const char *name, idEntity *ent ) { + if ( FindEntity( name ) ) { + Error( "Multiple entities named '%s'", name ); + } + entityHash.Add( entityHash.GenerateKey( name, true ), ent->entityNumber ); +} + +/* +================ +idGameLocal::RemoveEntityFromHash +================ +*/ +bool idGameLocal::RemoveEntityFromHash( const char *name, idEntity *ent ) { + int hash, i; + + hash = entityHash.GenerateKey( name, true ); + for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { + if ( entities[i] && entities[i] == ent && entities[i]->name.Icmp( name ) == 0 ) { + entityHash.Remove( hash, i ); + return true; + } + } + return false; +} + +/* +================ +idGameLocal::GetTargets +================ +*/ +int idGameLocal::GetTargets( const idDict &args, idList< idEntityPtr > &list, const char *ref ) const { + int i, num, refLength; + const idKeyValue *arg; + idEntity *ent; + + list.Clear(); + + refLength = strlen( ref ); + num = args.GetNumKeyVals(); + for( i = 0; i < num; i++ ) { + + arg = args.GetKeyVal( i ); + if ( arg->GetKey().Icmpn( ref, refLength ) == 0 ) { + + ent = FindEntity( arg->GetValue() ); + if ( ent ) { + idEntityPtr &entityPtr = list.Alloc(); + entityPtr = ent; + } + } + } + + return list.Num(); +} + +/* +================ +idGameLocal::GetRelights - grayman #2603 - retrieve relight entities and add them to the target list +================ +*/ +int idGameLocal::GetRelights( const idDict &args, idList< idEntityPtr > &list, const char *ref ) const +{ + int i,num,refLength; + const idKeyValue *arg; + idEntity *ent; + + refLength = strlen(ref); + num = args.GetNumKeyVals(); + for (i = 0 ; i < num ; i++) + { + arg = args.GetKeyVal(i); + if (arg->GetKey().Icmpn(ref,refLength) == 0) + { + const idStr name = arg->GetValue(); + ent = FindEntity(name); + if (ent) + { + idEntityPtr &entityPtr = list.Alloc(); + entityPtr = ent; + } + } + } + + return list.Num(); +} + +/* +============= +idGameLocal::GetTraceEntity + +returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player. +============= +*/ +idEntity *idGameLocal::GetTraceEntity( const trace_t &trace ) const { + idEntity *master; + + if ( !entities[ trace.c.entityNum ] ) { + return NULL; + } + master = entities[ trace.c.entityNum ]->GetBindMaster(); + if ( master ) { + return master; + } + return entities[ trace.c.entityNum ]; +} + +/* +============= +idGameLocal::ArgCompletion_EntityName + +Argument completion for entity names +============= +*/ +void idGameLocal::ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + int i; + + for( i = 0; i < gameLocal.num_entities; i++ ) { + if ( gameLocal.entities[ i ] ) { + callback( va( "%s %s", args.Argv( 0 ), gameLocal.entities[ i ]->name.c_str() ) ); + } + } +} + +/* +============= +idGameLocal::FindEntity + +Returns the entity whose name matches the specified string. +============= +*/ +idEntity *idGameLocal::FindEntity( const char *name ) const { + int hash, i; + + hash = entityHash.GenerateKey( name, true ); + for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { + if ( entities[i] && entities[i]->name.Icmp( name ) == 0 ) { + return entities[i]; + } + } + + return NULL; +} + +/* +============= +idGameLocal::FindEntityUsingDef + +Searches all active entities for the next one using the specified entityDef. + +Searches beginning at the entity after from, or the beginning if NULL +NULL will be returned if the end of the list is reached. +============= +*/ +idEntity *idGameLocal::FindEntityUsingDef( idEntity *from, const char *match ) const { + idEntity *ent; + + if ( !from ) { + ent = spawnedEntities.Next(); + } else { + ent = from->spawnNode.Next(); + } + + for ( ; ent != NULL; ent = ent->spawnNode.Next() ) { + assert( ent ); + if ( idStr::Icmp( ent->GetEntityDefName(), match ) == 0 ) { + return ent; + } + } + + return NULL; +} + +/* +============= +idGameLocal::FindTraceEntity + +Searches all active entities for the closest ( to start ) match that intersects +the line start,end +============= +*/ +idEntity *idGameLocal::FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const { + idEntity *ent; + idEntity *bestEnt; + float scale; + float bestScale; + idBounds b; + + bestEnt = NULL; + bestScale = 1.0f; + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( c ) && ent != skip ) { + b = ent->GetPhysics()->GetAbsBounds().Expand( 16 ); + if ( b.RayIntersection( start, end-start, scale ) ) { + if ( scale >= 0.0f && scale < bestScale ) { + bestEnt = ent; + bestScale = scale; + } + } + } + } + + return bestEnt; +} + +/* +================ +idGameLocal::EntitiesWithinRadius +================ +*/ +int idGameLocal::EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const { + idEntity *ent; + idBounds bo( org ); + int entCount = 0; + + bo.ExpandSelf( radius ); + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->GetPhysics()->GetAbsBounds().IntersectsBounds( bo ) ) { + entityList[entCount++] = ent; + } + } + + return entCount; +} + +/* +================= +idGameLocal::KillBox + +Kills all entities that would touch the proposed new positioning of ent. The ent itself will not being killed. +Checks if player entities are in the teleporter, and marks them to die at teleport exit instead of immediately. +If catch_teleport, this only marks teleport players for death on exit +================= +*/ +void idGameLocal::KillBox( idEntity *ent, bool catch_teleport ) { + int i; + int num; + idEntity * hit; + idClipModel *cm; + idClipModel *clipModels[ MAX_GENTITIES ]; + idPhysics *phys; + + phys = ent->GetPhysics(); + if ( !phys->GetNumClipModels() ) { + return; + } + + num = clip.ClipModelsTouchingBounds( phys->GetAbsBounds(), phys->GetClipMask(), clipModels, MAX_GENTITIES ); + for ( i = 0; i < num; i++ ) { + cm = clipModels[ i ]; + + // don't check render entities + if ( cm->IsRenderModel() ) { + continue; + } + + hit = cm->GetEntity(); + if ( ( hit == ent ) || !hit->fl.takedamage ) { + continue; + } + + if ( !phys->ClipContents( cm ) ) { + continue; + } + + // nail it + if ( hit->IsType( idPlayer::Type ) && static_cast< idPlayer * >( hit )->IsInTeleport() ) { + static_cast< idPlayer * >( hit )->TeleportDeath( ent->entityNumber ); + } else if ( !catch_teleport ) { + hit->Damage( ent, ent, vec3_origin, "damage_telefrag", 1.0f, INVALID_JOINT ); + } + + if ( !gameLocal.isMultiplayer ) { + // let the mapper know about it + Warning( "'%s' telefragged '%s'", ent->name.c_str(), hit->name.c_str() ); + } + } +} + +/* +================ +idGameLocal::RequirementMet +================ +*/ +bool idGameLocal::RequirementMet( idEntity *activator, const idStr &requires, int removeItem ) { + if ( requires.Length() ) { + if ( activator->IsType( idPlayer::Type ) ) { + idPlayer *player = static_cast(activator); + idDict *item = NULL;//player->FindInventoryItem( requires ); + if ( item ) { + if ( removeItem ) { + //player->RemoveInventoryItem( item ); + } + return true; + } else { + return false; + } + } + } + + return true; +} + +/* +============ +idGameLocal::RadiusDamage +============ +*/ +void idGameLocal::RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower ) { + float dist, damageScale, attackerDamageScale, attackerPushScale; + idEntity * ent; + idEntity * entityList[ MAX_GENTITIES ]; + int numListedEntities; + idBounds bounds; + idVec3 v, damagePoint, dir; + int i, e, damage, radius, push; + + const idDict *damageDef = FindEntityDefDict( damageDefName, false ); + if ( !damageDef ) { + Warning( "Unknown damageDef '%s'", damageDefName ); + return; + } + + damageDef->GetInt( "damage", "20", damage ); + damageDef->GetInt( "radius", "50", radius ); + damageDef->GetInt( "push", va( "%d", damage * 100 ), push ); + damageDef->GetFloat( "attackerDamageScale", "0.5", attackerDamageScale ); + damageDef->GetFloat( "attackerPushScale", "0", attackerPushScale ); + + if ( radius < 1 ) { + radius = 1; + } + + bounds = idBounds( origin ).Expand( radius ); + // get all entities touching the bounds + numListedEntities = clip.EntitiesTouchingBounds( bounds, -1, entityList, MAX_GENTITIES ); + + if ( inflictor && inflictor->IsType( idAFAttachment::Type ) ) { + inflictor = static_cast(inflictor)->GetBody(); + } + if ( attacker && attacker->IsType( idAFAttachment::Type ) ) { + attacker = static_cast(attacker)->GetBody(); + } + if ( ignoreDamage && ignoreDamage->IsType( idAFAttachment::Type ) ) { + ignoreDamage = static_cast(ignoreDamage)->GetBody(); + } + + // apply damage to the entities + for ( e = 0; e < numListedEntities; e++ ) { + ent = entityList[ e ]; + assert( ent ); + + if ( !ent->fl.takedamage ) { + continue; + } + + if ( ent == inflictor || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == inflictor ) ) { + continue; + } + + if ( ent == ignoreDamage || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == ignoreDamage ) ) { + continue; + } + + // don't damage a dead player + if ( isMultiplayer && ent->entityNumber < MAX_CLIENTS && ent->IsType( idPlayer::Type ) && static_cast< idPlayer * >( ent )->health < 0 ) { + continue; + } + + // find the distance from the edge of the bounding box + for ( i = 0; i < 3; i++ ) { + if ( origin[ i ] < ent->GetPhysics()->GetAbsBounds()[0][ i ] ) { + v[ i ] = ent->GetPhysics()->GetAbsBounds()[0][ i ] - origin[ i ]; + } else if ( origin[ i ] > ent->GetPhysics()->GetAbsBounds()[1][ i ] ) { + v[ i ] = origin[ i ] - ent->GetPhysics()->GetAbsBounds()[1][ i ]; + } else { + v[ i ] = 0; + } + } + + dist = v.Length(); + if ( dist >= radius ) { + continue; + } + + if ( ent->CanDamage( origin, damagePoint ) ) { + // push the center of mass higher than the origin so players + // get knocked into the air more + dir = ent->GetPhysics()->GetOrigin() - origin; + dir[ 2 ] += 24; + + // get the damage scale + damageScale = dmgPower * ( 1.0f - dist / radius ); + if ( ent == attacker || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == attacker ) ) { + damageScale *= attackerDamageScale; + } + + ent->Damage( inflictor, attacker, dir, damageDefName, damageScale, INVALID_JOINT ); + } + } + + // push physics objects + if ( push ) { + RadiusPush( origin, radius, push * dmgPower, attacker, ignorePush, attackerPushScale, false ); + } +} + +/* +============== +idGameLocal::RadiusPush +============== +*/ +void idGameLocal::RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake ) { + int i, numListedClipModels; + idClipModel *clipModel; + idClipModel *clipModelList[ MAX_GENTITIES ]; + idVec3 dir; + idBounds bounds; + modelTrace_t result; + idEntity *ent; + float scale; + + dir.Set( 0.0f, 0.0f, 1.0f ); + + bounds = idBounds( origin ).Expand( radius ); + + // get all clip models touching the bounds + numListedClipModels = clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); + + if ( inflictor && inflictor->IsType( idAFAttachment::Type ) ) { + inflictor = static_cast(inflictor)->GetBody(); + } + if ( ignore && ignore->IsType( idAFAttachment::Type ) ) { + ignore = static_cast(ignore)->GetBody(); + } + + // apply impact to all the clip models through their associated physics objects + for ( i = 0; i < numListedClipModels; i++ ) { + + clipModel = clipModelList[i]; + + // never push render models + if ( clipModel->IsRenderModel() ) { + continue; + } + + ent = clipModel->GetEntity(); + + // never push projectiles + if ( ent->IsType( idProjectile::Type ) ) { + continue; + } + + // players use "knockback" in idPlayer::Damage + if ( ent->IsType( idPlayer::Type ) && !quake ) { + continue; + } + + // don't push the ignore entity + if ( ent == ignore || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == ignore ) ) { + continue; + } + + if ( gameRenderWorld->FastWorldTrace( result, origin, clipModel->GetOrigin() ) ) { + continue; + } + + // scale the push for the inflictor + if ( ent == inflictor || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == inflictor ) ) { + scale = inflictorScale; + } else { + scale = 1.0f; + } + + if ( quake ) { + clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), clipModel->GetOrigin(), scale * push * dir ); + } else { + RadiusPushClipModel( origin, scale * push, clipModel ); + } + } +} + +/* +============== +idGameLocal::RadiusPushClipModel +============== +*/ +void idGameLocal::RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel ) { + int i, j; + float dot, dist, area; + const idTraceModel *trm; + const traceModelPoly_t *poly; + idFixedWinding w; + idVec3 v, localOrigin, center, impulse; + + trm = clipModel->GetTraceModel(); + if ( !trm || 1 ) { + impulse = clipModel->GetAbsBounds().GetCenter() - origin; + impulse.Normalize(); + impulse.z += 1.0f; + clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), clipModel->GetOrigin(), push * impulse ); + return; + } + + localOrigin = ( origin - clipModel->GetOrigin() ) * clipModel->GetAxis().Transpose(); + for ( i = 0; i < trm->numPolys; i++ ) { + poly = &trm->polys[i]; + + center.Zero(); + for ( j = 0; j < poly->numEdges; j++ ) { + v = trm->verts[ trm->edges[ abs(poly->edges[j]) ].v[ INTSIGNBITSET( poly->edges[j] ) ] ]; + center += v; + v -= localOrigin; + v.NormalizeFast(); // project point on a unit sphere + w.AddPoint( v ); + } + center /= poly->numEdges; + v = center - localOrigin; + dist = v.NormalizeFast(); + dot = v * poly->normal; + if ( dot > 0.0f ) { + continue; + } + area = w.GetArea(); + // impulse in polygon normal direction + impulse = poly->normal * clipModel->GetAxis(); + // always push up for nicer effect + impulse.z -= 1.0f; + // scale impulse based on visible surface area and polygon angle + impulse *= push * ( dot * area * ( 1.0f / ( 4.0f * idMath::PI ) ) ); + // scale away distance for nicer effect + impulse *= ( dist * 2.0f ); + // impulse is applied to the center of the polygon + center = clipModel->GetOrigin() + center * clipModel->GetAxis(); + + clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), center, impulse ); + } +} + +/* +=============== +idGameLocal::ProjectDecal +=============== +*/ +void idGameLocal::ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle ) { + float s, c; + idMat3 axis, axistemp; + idFixedWinding winding; + idVec3 windingOrigin, projectionOrigin; + + static idVec3 decalWinding[4] = { + idVec3( 1.0f, 1.0f, 0.0f ), + idVec3( -1.0f, 1.0f, 0.0f ), + idVec3( -1.0f, -1.0f, 0.0f ), + idVec3( 1.0f, -1.0f, 0.0f ) + }; + + if ( !g_decals.GetBool() ) { + return; + } + + // randomly rotate the decal winding + idMath::SinCos16( ( angle ) ? angle : random.RandomFloat() * idMath::TWO_PI, s, c ); + + // winding orientation + axis[2] = dir; + axis[2].Normalize(); + axis[2].NormalVectors( axistemp[0], axistemp[1] ); + axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; + axis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; + + windingOrigin = origin + depth * axis[2]; + if ( parallel ) { + projectionOrigin = origin - depth * axis[2]; + } else { + projectionOrigin = origin; + } + + size *= 0.5f; + + winding.Clear(); + winding += idVec5( windingOrigin + ( axis * decalWinding[0] ) * size, idVec2( 1, 1 ) ); + winding += idVec5( windingOrigin + ( axis * decalWinding[1] ) * size, idVec2( 0, 1 ) ); + winding += idVec5( windingOrigin + ( axis * decalWinding[2] ) * size, idVec2( 0, 0 ) ); + winding += idVec5( windingOrigin + ( axis * decalWinding[3] ) * size, idVec2( 1, 0 ) ); + gameRenderWorld->ProjectDecalOntoWorld( winding, projectionOrigin, parallel, depth * 0.5f, declManager->FindMaterial( material ), time ); +} + +/* +============== +idGameLocal::BloodSplat +============== +*/ +void idGameLocal::BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { + float halfSize = size * 0.5f; + idVec3 verts[] = { idVec3( 0.0f, +halfSize, +halfSize ), + idVec3( 0.0f, +halfSize, -halfSize ), + idVec3( 0.0f, -halfSize, -halfSize ), + idVec3( 0.0f, -halfSize, +halfSize ) }; + idTraceModel trm; + idClipModel mdl; + trace_t results; + + // FIXME: get from damage def + if ( !g_bloodEffects.GetBool() ) { + return; + } + + size = halfSize + random.RandomFloat() * halfSize; + trm.SetupPolygon( verts, 4 ); + mdl.LoadModel( trm ); + clip.Translation( results, origin, origin + dir * 64.0f, &mdl, mat3_identity, CONTENTS_SOLID, NULL ); + ProjectDecal( results.endpos, dir, 2.0f * size, true, size, material ); +} + +/* +============= +idGameLocal::SetCamera +============= +*/ +void idGameLocal::SetCamera( idCamera *cam ) { + int i; + idEntity *ent; + idAI *ai; + + // this should fix going into a cinematic when dead.. rare but happens + idPlayer *client = GetLocalPlayer(); + if ( client->health <= 0 || client->AI_DEAD ) { + return; + } + + camera = cam; + if ( camera ) { + inCinematic = true; + + if ( skipCinematic && camera->spawnArgs.GetBool( "disconnect" ) ) { + camera->spawnArgs.SetBool( "disconnect", false ); + cvarSystem->SetCVarFloat( "r_znear", 3.0f ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + skipCinematic = false; + return; + } + + if ( time > cinematicStopTime ) { + cinematicSkipTime = time + CINEMATIC_SKIP_DELAY; + } + + // set r_znear so that transitioning into/out of the player's head doesn't clip through the view + cvarSystem->SetCVarFloat( "r_znear", 1.0f ); + + // hide all the player models + for( i = 0; i < numClients; i++ ) { + if ( entities[ i ] ) { + client = static_cast< idPlayer* >( entities[ i ] ); + client->EnterCinematic(); + } + } + + if ( !cam->spawnArgs.GetBool( "ignore_enemies" ) ) { + // kill any active monsters that are enemies of the player + for ( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->cinematic || ent->fl.isDormant ) { + // only kill entities that aren't needed for cinematics and aren't dormant + continue; + } + + if ( ent->IsType( idAI::Type ) ) { + ai = static_cast( ent ); + if ( !ai->GetEnemy() || !ai->IsActive() ) { + // no enemy, or inactive, so probably safe to ignore + continue; + } + } else if ( ent->IsType( idProjectile::Type ) ) { + // remove all projectiles + } else if ( ent->spawnArgs.GetBool( "cinematic_remove" ) ) { + // remove anything marked to be removed during cinematics + } else { + // ignore everything else + continue; + } + + // remove it + DPrintf( "removing '%s' for cinematic\n", ent->GetName() ); + ent->PostEventMS( &EV_Remove, 0 ); + } + } + + } else { + inCinematic = false; + cinematicStopTime = time + msec; + + // restore r_znear + cvarSystem->SetCVarFloat( "r_znear", 3.0f ); + + // show all the player models + for( i = 0; i < numClients; i++ ) { + if ( entities[ i ] ) { + idPlayer *client = static_cast< idPlayer* >( entities[ i ] ); + client->ExitCinematic(); + } + } + } +} + +/* +============= +idGameLocal::GetCamera +============= +*/ +idCamera *idGameLocal::GetCamera( void ) const { + return camera; +} + +/* +============= +idGameLocal::SkipCinematic +============= +*/ +bool idGameLocal::SkipCinematic( void ) { + if ( camera ) { + if ( camera->spawnArgs.GetBool( "disconnect" ) ) { + camera->spawnArgs.SetBool( "disconnect", false ); + cvarSystem->SetCVarFloat( "r_znear", 3.0f ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + skipCinematic = false; + return false; + } + + if ( camera->spawnArgs.GetBool( "instantSkip" ) ) { + camera->Stop(); + return false; + } + } + + soundSystem->SetMute( true ); + if ( !skipCinematic ) { + skipCinematic = true; + cinematicMaxSkipTime = gameLocal.time + SEC2MS( g_cinematicMaxSkipTime.GetFloat() ); + } + + return true; +} + + +/* +====================== +idGameLocal::SpreadLocations + +Now that everything has been spawned, associate areas with location entities +====================== +*/ +void idGameLocal::SpreadLocations() { + idEntity *ent; + + // allocate the area table + int numAreas = gameRenderWorld->NumAreas(); + locationEntities = new idLocationEntity *[ numAreas ]; + memset( locationEntities, 0, numAreas * sizeof( *locationEntities ) ); + + // for each location entity, make pointers from every area it touches + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( !ent->IsType( idLocationEntity::Type ) ) { + continue; + } + idVec3 point = ent->spawnArgs.GetVector( "origin" ); + int areaNum = gameRenderWorld->PointInArea( point ); + if ( areaNum < 0 ) { + Printf( "SpreadLocations: location '%s' is not in a valid area\n", ent->spawnArgs.GetString( "name" ) ); + continue; + } + if ( areaNum >= numAreas ) { + Error( "idGameLocal::SpreadLocations: areaNum >= gameRenderWorld->NumAreas()" ); + } + if ( locationEntities[areaNum] ) { + Warning( "location entity '%s' overlaps '%s'", ent->spawnArgs.GetString( "name" ), + locationEntities[areaNum]->spawnArgs.GetString( "name" ) ); + continue; + } + locationEntities[areaNum] = static_cast(ent); + + // spread to all other connected areas + for ( int i = 0 ; i < numAreas ; i++ ) { + if ( i == areaNum ) { + continue; + } + if ( gameRenderWorld->AreasAreConnected( areaNum, i, PS_BLOCK_LOCATION ) ) { + locationEntities[i] = static_cast(ent); + } + } + } +} + +/* +=================== +idGameLocal::LocationForPoint + +The player checks the location each frame to update the HUD text display +May return NULL +=================== +*/ +idLocationEntity *idGameLocal::LocationForPoint( const idVec3 &point ) { + if ( !locationEntities ) { + // before SpreadLocations() has been called + return NULL; + } + + int areaNum = gameRenderWorld->PointInArea( point ); + if ( areaNum < 0 ) { + return NULL; + } + if ( areaNum >= gameRenderWorld->NumAreas() ) { + Error( "idGameLocal::LocationForPoint: areaNum >= gameRenderWorld->NumAreas()" ); + } + + return locationEntities[ areaNum ]; +} + +/* +============ +idGameLocal::SetPortalState +============ +*/ +void idGameLocal::SetPortalState( qhandle_t portal, int blockingBits ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + if ( !gameLocal.isClient ) { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_PORTAL ); + outMsg.WriteLong( portal ); + outMsg.WriteBits( blockingBits, NUM_RENDER_PORTAL_BITS ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + } + gameRenderWorld->SetPortalState( portal, blockingBits ); +} + +/* +============ +idGameLocal::sortSpawnPoints +============ +*/ +int idGameLocal::sortSpawnPoints( const void *ptr1, const void *ptr2 ) { + const spawnSpot_t *spot1 = static_cast( ptr1 ); + const spawnSpot_t *spot2 = static_cast( ptr2 ); + float diff; + + diff = spot1->dist - spot2->dist; + if ( diff < 0.0f ) { + return 1; + } else if ( diff > 0.0f ) { + return -1; + } else { + return 0; + } +} + +/* +=========== +idGameLocal::RandomizeInitialSpawns +randomize the order of the initial spawns +prepare for a sequence of initial player spawns +============ +*/ +void idGameLocal::RandomizeInitialSpawns( void ) { + spawnSpot_t spot; + int i, j; + idEntity *ent; + + if ( !isMultiplayer || isClient ) { + return; + } + spawnSpots.Clear(); + initialSpots.Clear(); + spot.dist = 0; + spot.ent = FindEntityUsingDef( NULL, "info_player_deathmatch" ); + while( spot.ent ) { + spawnSpots.Append( spot ); + if ( spot.ent->spawnArgs.GetBool( "initial" ) ) { + initialSpots.Append( spot.ent ); + } + spot.ent = FindEntityUsingDef( spot.ent, "info_player_deathmatch" ); + } + if ( !spawnSpots.Num() ) { + common->Warning( "no info_player_deathmatch in map" ); + return; + } + common->Printf( "%d spawns (%d initials)\n", spawnSpots.Num(), initialSpots.Num() ); + // if there are no initial spots in the map, consider they can all be used as initial + if ( !initialSpots.Num() ) { + common->Warning( "no info_player_deathmatch entities marked initial in map" ); + for ( i = 0; i < spawnSpots.Num(); i++ ) { + initialSpots.Append( spawnSpots[ i ].ent ); + } + } + for ( i = 0; i < initialSpots.Num(); i++ ) { + j = random.RandomInt( initialSpots.Num() ); + ent = initialSpots[ i ]; + initialSpots[ i ] = initialSpots[ j ]; + initialSpots[ j ] = ent; + } + // reset the counter + currentInitialSpot = 0; +} + +/* +=========== +idGameLocal::SelectInitialSpawnPoint +spectators are spawned randomly anywhere +in-game clients are spawned based on distance to active players (randomized on the first half) +upon map restart, initial spawns are used (randomized ordered list of spawns flagged "initial") + if there are more players than initial spots, overflow to regular spawning +============ +*/ +idEntity *idGameLocal::SelectInitialSpawnPoint( idPlayer *player ) { + int i, j, which; + spawnSpot_t spot; + idVec3 pos; + float dist; + bool alone; + + if ( !isMultiplayer || !spawnSpots.Num() ) + { + // grayman #2933 - Did the player specify + // a starting point in the briefing? + + bool foundSpot = false; + if ( m_StartPosition != "" ) + { + spot.ent = FindEntity( m_StartPosition ); + if ( spot.ent != NULL ) + { + foundSpot = true; + } + } + + if ( !foundSpot ) + { + spot.ent = FindEntityUsingDef( NULL, "info_player_start" ); + if ( !spot.ent ) + { + Error( "No info_player_start on map.\n" ); + } + } + return spot.ent; + } + if ( player->spectating ) { + // plain random spot, don't bother + return spawnSpots[ random.RandomInt( spawnSpots.Num() ) ].ent; + } else if ( player->useInitialSpawns && currentInitialSpot < initialSpots.Num() ) { + return initialSpots[ currentInitialSpot++ ]; + } else { + // check if we are alone in map + alone = true; + for ( j = 0; j < MAX_CLIENTS; j++ ) { + if ( entities[ j ] && entities[ j ] != player ) { + alone = false; + break; + } + } + if ( alone ) { + // don't do distance-based + return spawnSpots[ random.RandomInt( spawnSpots.Num() ) ].ent; + } + + // find the distance to the closest active player for each spawn spot + for( i = 0; i < spawnSpots.Num(); i++ ) { + pos = spawnSpots[ i ].ent->GetPhysics()->GetOrigin(); + spawnSpots[ i ].dist = 0x7fffffff; + for( j = 0; j < MAX_CLIENTS; j++ ) { + if ( !entities[ j ] || !entities[ j ]->IsType( idPlayer::Type ) + || entities[ j ] == player + || static_cast< idPlayer * >( entities[ j ] )->spectating ) { + continue; + } + + dist = ( pos - entities[ j ]->GetPhysics()->GetOrigin() ).LengthSqr(); + if ( dist < spawnSpots[ i ].dist ) { + spawnSpots[ i ].dist = int(dist); + } + } + } + + // sort the list + qsort( ( void * )spawnSpots.Ptr(), spawnSpots.Num(), sizeof( spawnSpot_t ), ( int (*)(const void *, const void *) )sortSpawnPoints ); + + // choose a random one in the top half + which = random.RandomInt( spawnSpots.Num() / 2 ); + spot = spawnSpots[ which ]; + } + return spot.ent; +} + +/* +================ +idGameLocal::UpdateServerInfoFlags +================ +*/ +void idGameLocal::UpdateServerInfoFlags() { + gameType = GAME_SP; + if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "deathmatch" ) == 0 ) ) { + gameType = GAME_DM; + } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Tourney" ) == 0 ) ) { + gameType = GAME_TOURNEY; + } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Team DM" ) == 0 ) ) { + gameType = GAME_TDM; + } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Last Man" ) == 0 ) ) { + gameType = GAME_LASTMAN; + } + if ( gameType == GAME_LASTMAN ) { + if ( !serverInfo.GetInt( "si_warmup" ) ) { + common->Warning( "Last Man Standing - forcing warmup on" ); + serverInfo.SetInt( "si_warmup", 1 ); + } + if ( serverInfo.GetInt( "si_fraglimit" ) <= 0 ) { + common->Warning( "Last Man Standing - setting fraglimit 1" ); + serverInfo.SetInt( "si_fraglimit", 1 ); + } + } +} + + +/* +================ +idGameLocal::SetGlobalMaterial +================ +*/ +void idGameLocal::SetGlobalMaterial( const idMaterial *mat ) { + globalMaterial = mat; +} + +/* +================ +idGameLocal::GetGlobalMaterial +================ +*/ +const idMaterial *idGameLocal::GetGlobalMaterial() { + return globalMaterial; +} + +/* +================ +idGameLocal::GetSpawnId +================ +*/ +int idGameLocal::GetSpawnId( const idEntity* ent ) const { + return ( gameLocal.spawnIds[ ent->entityNumber ] << GENTITYNUM_BITS ) | ent->entityNumber; +} + +/* +================ +idGameLocal::ThrottleUserInfo +================ +*/ +void idGameLocal::ThrottleUserInfo( void ) { + mpGame.ThrottleUserInfo(); +} + +/* + +================= + +idPlayer::SetPortalSkyEnt + +================= + +*/ + +void idGameLocal::SetPortalSkyEnt( idEntity *ent ) { + portalSkyEnt = ent; +} + + + +/* +================= +idPlayer::IsPortalSkyAcive +================= +*/ +bool idGameLocal::IsPortalSkyAcive() { + return portalSkyActive; +} + + + +/* +=========== +idGameLocal::SelectTimeGroup +============ +*/ + +void idGameLocal::SelectTimeGroup( int timeGroup ) { } + + + +/* +=========== +idGameLocal::GetTimeGroupTime +============ +*/ +int idGameLocal::GetTimeGroupTime( int timeGroup ) { + return gameLocal.time; +} + + + +/* +=========== +idGameLocal::GetBestGameType +============ +*/ +void idGameLocal::GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ) { + strncpy( buf, gametype, MAX_STRING_CHARS ); + buf[ MAX_STRING_CHARS - 1 ] = '\0'; +} + +/* +=========== +idGameLocal::NeedRestart +============ +*/ +bool idGameLocal::NeedRestart() { + idDict newInfo; + const idKeyValue *keyval, *keyval2; + + newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); + + for ( int i = 0; i < newInfo.GetNumKeyVals(); i++ ) { + keyval = newInfo.GetKeyVal( i ); + keyval2 = serverInfo.FindKey( keyval->GetKey() ); + if ( !keyval2 ) { + return true; + } + + // a select set of si_ changes will cause a full restart of the server + if ( keyval->GetValue().Cmp( keyval2->GetValue() ) && ( !keyval->GetKey().Cmp( "si_pure" ) || !keyval->GetKey().Cmp( "si_map" ) ) ) { + return true; + } + } + return false; +} + + + +/* +================ +idGameLocal::GetClientStats +================ +*/ + +void idGameLocal::GetClientStats( int clientNum, char *data, const int len ) { + + mpGame.PlayerStats( clientNum, data, len ); +} + +void idGameLocal::SwitchTeam( int clientNum, int team ) +{ + idPlayer * player; + + player = clientNum >= 0 ? static_cast( gameLocal.entities[ clientNum ] ) : NULL; + if ( !player ) + return; + int oldTeam = player->team; + + // Put in spectator mode + if ( team == -1 ) { + static_cast< idPlayer * >( entities[ clientNum ] )->Spectate( true ); + } + + // Switch to a team + else { + mpGame.SwitchToTeam ( clientNum, oldTeam, team ); + } +} + +void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) +{ +} + +void idGameLocal::LoadLightMaterial(const char *pFN, idList *ml) +{ + idToken token; + idLexer src; + idStr Material, FallOff, Map, *add; + int level; // Nestinglevel for brackets + bool bAmbient; + CLightMaterial *mat; + + if(pFN == NULL || ml == NULL) + goto Quit; + + src.LoadFile(pFN); + + level = 0; + add = NULL; + bAmbient = false; + + while(1) + { + if(!src.ReadToken(&token)) + goto Quit; + +// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Token: [%s]\r", token.c_str()); + + if(token == "table") + { + src.SkipBracedSection(true); + continue; + } + + if(token == "lights") + { + Material = token; + while(src.ReadTokenOnLine(&token) == true) + { + Material += token; +// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Material: [%s]\r", token.c_str()); + } + + continue; + } + else if(level == 1 && token == "ambientLight") + { + bAmbient = true; + continue; + } + else if(token == "{") + { + level++; + if(level == 1) + bAmbient = false; + + continue; + } + else if(token == "}") + { + level--; + if(level == 0) + { + if(FallOff.Length() == 0 && Map.Length() == 0) + continue; + + mat = new CLightMaterial(Material, FallOff, Map); + mat->m_AmbientLight = bAmbient; + ml->Append(mat); + DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("Texture: [%s] - [%s]/[%s] - Ambient: %u\r", Material.c_str(), FallOff.c_str(), Map.c_str(), bAmbient); + } + continue; + } + else if(token == "map") + { + Map = ""; + while(src.ReadTokenOnLine(&token) == true) + { + if(token == "makeintensity") + continue; + else if(token == "(") + continue; + else if(token == ")") + break; + else + Map += token; +// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Map: [%s]\r", token.c_str()); + } + continue; + } + else if(token == "lightFalloffImage") + { + FallOff = ""; + + while(1) + { + if(!src.ReadToken(&token)) + { + DM_LOG(LC_SYSTEM, LT_ERROR)LOGSTRING("Invalid material file structure on line %u\r", src.GetLineNum()); + goto Quit; + } + + // Ignore makeintensity tag + if(token == "makeintensity") + continue; + else if(token == "(") + continue; + else if(token == ")") + break; + else + { + do + { + if(token == ")") + break; + + FallOff += token; +// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("FallOff: [%s]\r", token.c_str()); + } + while(src.ReadTokenOnLine(&token) == true); + break; + } + } + continue; + } + } + +Quit: + return; +} + +int idGameLocal::CheckStimResponse(idList< idEntityPtr > &list, idEntity *e) +{ + // Construct an idEntityPtr with the given entity + idEntityPtr entPtr; + entPtr = e; + + return list.FindIndex(entPtr); +} + +void idGameLocal::LinkStimEntity(idEntity* ent) +{ + if (ent != NULL && ent->GetStimResponseCollection()->HasStim()) + { + AddStim(ent); + } +} + +void idGameLocal::UnlinkStimEntity(idEntity* ent) +{ + RemoveStim(ent); +} + +bool idGameLocal::AddStim(idEntity *e) +{ + bool rc = true; + + if (CheckStimResponse(m_StimEntity, e) == -1) + { + idEntityPtr entPtr; + entPtr = e; + m_StimEntity.Append(entPtr); + } + + return rc; +} + +void idGameLocal::RemoveStim(idEntity *e) +{ + int i = CheckStimResponse(m_StimEntity, e); + + if (i != -1) + { + m_StimEntity.RemoveIndex(i); + } +} + +bool idGameLocal::AddResponse(idEntity *e) +{ + bool rc = true; + + if(CheckStimResponse(m_RespEntity, e) == -1) + { + idEntityPtr entPtr; + entPtr = e; + m_RespEntity.Append(entPtr); + } + + return rc; +} + + +void idGameLocal::RemoveResponse(idEntity *e) +{ + int i = CheckStimResponse(m_RespEntity, e); + + if (i != -1) + { + m_RespEntity.RemoveIndex(i); + } +} + +int idGameLocal::DoResponseAction(const CStimPtr& stim, int numEntities, idEntity* originator, const idVec3& stimOrigin) +{ + int numResponses = 0; + for (int i = 0; i < numEntities; i++) + { + // ignore the original entity because an entity shouldn't respond + // to its own stims. + if (srEntities[i] == originator || srEntities[i]->GetResponseEntity() == originator) + continue; + + // Check if the radius is really fitting. EntitiesTouchingBounds is using a rectangular volume + // greebo: Be sure to use this check only if "use bounds" is set to false + if (!stim->m_bCollisionBased && !stim->m_bUseEntBounds) + { + // take the square radius, is faster + float radiusSqr = stim->GetRadius(); + radiusSqr *= radiusSqr; + + // grayman #2468 - handle AI with no separate head entities + + idEntity *ent = srEntities[i]; + idVec3 entitySpot = ent->GetPhysics()->GetOrigin(); + + if (stim->m_StimTypeId == ST_GAS) // grayman #2721 - only need the mouth location if this is a gas stim + { + if (!ent->IsType(idAFAttachment::Type)) // is this an attached head? + { + // no separate head entity, so find the mouth + + if (ent->IsType(idAI::Type)) + { + idAI* entAI = static_cast(ent); + + entitySpot = entAI->GetEyePosition(); + entitySpot.z += entAI->m_MouthOffset.z; + } + } + } + + if ((entitySpot - stimOrigin).LengthSqr() > radiusSqr) + { + // Too far away + continue; + } + } + + // Check for a shooter entity, these don't need to have a response + if (srEntities[i]->IsType(tdmFuncShooter::Type)) + { + static_cast(srEntities[i])->stimulate(static_cast(stim->m_StimTypeId)); + } + + CResponsePtr response = srEntities[i]->GetStimResponseCollection()->GetResponseByType(stim->m_StimTypeId); + + if (response != NULL) + { + if (response->m_State == SS_ENABLED && stim->CheckResponseIgnore(srEntities[i]) == false) + { + // Check duration, disable if past duration + if (response->m_Duration && (gameLocal.time - response->m_EnabledTimeStamp) > response->m_Duration ) + { + response->Disable(); + continue; + } + + if (cv_sr_show.GetInteger() > 0) + { + // Show successful S/R + gameRenderWorld->DebugArrow(colorGreen, stimOrigin, srEntities[i]->GetPhysics()->GetOrigin(), 1, 4 * gameLocal.msec); + } + + // Fire the response and pass the originating entity plus the stim object itself + // The stim object can be queried for values like magnitude, falloff and such. + response->TriggerResponse(originator, stim); + numResponses++; + } + } + } + + // Return number of responses triggered + return numResponses; +} + +void idGameLocal::ProcessTimer(unsigned long ticks) +{ + int i, n; + CStimResponseTimer *t; + + n = m_Timer.Num(); + for(i = 0; i < n; i++) + { + t = m_Timer[i]; + + // We just let the timers tick. Querying them must be done by the respective owner, + // because we can not know from where it was called, and it doesn't make sense + // to use a callback, because the timer user still has to wait until it is expired. + // So the owner has to check it from time to time anyway. + if(t->GetState() == CStimResponseTimer::SRTS_RUNNING) + { + t = m_Timer[i]; + t->Tick(ticks); + } + } +} + +CStimResponsePtr idGameLocal::FindStimResponse(int uniqueId) +{ + for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + if (ent->GetStimResponseCollection() != NULL) + { + CStimResponsePtr candidate = ent->GetStimResponseCollection()->FindStimResponse(uniqueId); + + if (candidate != NULL) + { + // We found the stim/response, return it + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StimResponse with Id %d found.\r", uniqueId); + return candidate; + } + } + } + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Warning: StimResponse with Id %d NOT found.\r", uniqueId); + + // Search did not produce any results + return CStimResponsePtr(); +} + +void idGameLocal::ProcessStimResponse(unsigned long ticks) +{ + if (cv_sr_disable.GetBool()) + { + return; // S/R disabled, skip this + } + + idTimer srTimer; + srTimer.Clear(); + srTimer.Start(); + + // Check the timed stims first. + for (int i = 0; i < m_StimTimer.Num(); i++) + { + CStim* stim = m_StimTimer[i]; + + if (stim == NULL) continue; + + // Only advance the timer if the stim can be fired in the first place + if (stim->m_MaxFireCount > 0 || stim->m_MaxFireCount == -1) + { + // Advance the timer + CStimResponseTimer* timer = stim->GetTimer(); + + if (timer->GetState() == CStimResponseTimer::SRTS_RUNNING) + { + if (timer->Tick(ticks)) + { + //gameLocal.Printf("Stim timer elapsed! ProcessStimResponse - firing stim\n"); + // Enable the stim when the timer has expired + + stim->Enable(); + } + } + } + } + + int n; + idBounds bounds; + + // Now check the rest of the stims. + for (int i = 0; i < m_StimEntity.Num(); i++) + { + idEntity* entity = m_StimEntity[i].GetEntity(); + + if (entity == NULL) continue; + + // greebo: Get the S/R collection, this is always non-NULL + CStimResponseCollection* srColl = entity->GetStimResponseCollection(); + assert(srColl != NULL); + + idVec3 origin(entity->GetPhysics()->GetOrigin()); + + int numStims = srColl->GetNumStims(); + + // Traverse through all the stims on this entity + for (int stimIdx = 0; stimIdx < numStims; ++stimIdx) + { + const CStimPtr& stim = srColl->GetStim(stimIdx); + + if (stim->m_MaxFireCount == 0) + // Maximum number of firings reached, do not process this stim + continue; + + if (stim->m_State != SS_ENABLED) + continue; // Stim is not enabled + + if (stim->m_bCollisionBased && !stim->m_bCollisionFired) + continue; // Collision-based stim that did not fire with ::Collide this frame + + // Check the interleaving timer and don't eval stim if it's not up yet + if (gameLocal.time - stim->m_TimeInterleaveStamp < stim->m_TimeInterleave) + continue; + + // If stim has a finite duration, check if it expired. If so, disable the stim. + if (stim->m_Duration != 0 && (gameLocal.time - stim->m_EnabledTimeStamp) > stim->m_Duration ) + { + stim->Disable(); + continue; + } + + // Initial checks passed, decrease the fire count + if (stim->m_MaxFireCount > 0) + { + stim->m_MaxFireCount--; + } + + // Check if a stim velocity has been specified + if (stim->m_Velocity != idVec3(0,0,0)) { + // The velocity mutliplied by the time gives the translation + // Updates the location of this stim relative to the time it last fired. + origin += stim->m_Velocity * (gameLocal.time - stim->m_EnabledTimeStamp)/1000; + } + + // Save the current timestamp into the stim, so that we know when it was last fired + stim->m_TimeInterleaveStamp = gameLocal.time; + + // greebo: Check if the stim passes the "chance" test + // Do this AFTER the m_TimeInterleaveStamp has been set to avoid the stim + // from being re-evaluated in the very next frame in case it failed the test. + if (!stim->CheckChance()) + { + continue; + } + + // If stim is not disabled + if (stim->m_State == SS_DISABLED) + continue; + + float radius = stim->GetRadius(); + + if (radius != 0.0 || stim->m_bCollisionBased || + stim->m_bUseEntBounds || stim->m_Bounds.GetVolume() > 0) + { + int numResponses = 0; + + // Check if we have fixed bounds to work with (sr_bounds_mins & maxs set) + if (stim->m_Bounds.GetVolume() > 0) { + bounds = idBounds(stim->m_Bounds[0] + origin, stim->m_Bounds[1] + origin); + } + else { + // No bounds set, check for radius and useBounds + + // Find entities in the radius of the stim + if (stim->m_bUseEntBounds ) + { + bounds = entity->GetPhysics()->GetAbsBounds(); + } + else + { + bounds = idBounds(origin); + } + + bounds.ExpandSelf(radius); + } + + // Collision-based stims + if (stim->m_bCollisionBased) + { + n = stim->m_CollisionEnts.Num(); + + for (int n2 = 0; n2 < n; n2++) + { + srEntities[n2] = stim->m_CollisionEnts[n2]; + } + + // clear the collision vars for the next frame + stim->m_bCollisionFired = false; + stim->m_CollisionEnts.Clear(); + } + else + { + // Radius based stims + n = clip.EntitiesTouchingBounds(bounds, CONTENTS_RESPONSE, srEntities, MAX_GENTITIES); + //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Entities touching bounds: %d\r", n); + } + + if (n > 0) + { + if (cv_sr_show.GetInteger() > 1) + { + for (int n2 = 0; n2 < n; ++n2) + { + // Show failed S/R + gameRenderWorld->DebugArrow(colorRed, bounds.GetCenter(), srEntities[n2]->GetPhysics()->GetOrigin(), 1, 4 * gameLocal.msec); + } + } + + // Do responses for entities within the radius of the stim + numResponses = DoResponseAction(stim, n, entity, origin); + } + + // The stim has fired, let it do any post-firing activity it may have + stim->PostFired(numResponses); + } + } + } + + srTimer.Stop(); + DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Processing S/R took %lf\r", srTimer.Milliseconds()); +} + +/* +=================== +Dark Mod: +idGameLocal::LocationForArea +=================== +*/ +idLocationEntity *idGameLocal::LocationForArea( const int areaNum ) +{ + idLocationEntity *pReturnval( NULL ); + + if ( !locationEntities || areaNum < 0 || areaNum >= gameRenderWorld->NumAreas() ) + { + pReturnval = NULL; + goto Quit; + } + + pReturnval = locationEntities[ areaNum ]; + +Quit: + return pReturnval; +} + +/* +=================== +Dark Mod: +idGameLocal::PlayerTraceEntity +=================== +*/ +idEntity *idGameLocal::PlayerTraceEntity( void ) +{ + idVec3 start, end; + idEntity *returnEnt = NULL; + idPlayer *player = NULL; + trace_t trace; + int cm = 0; + + player = gameLocal.GetLocalPlayer(); + if( ! player ) + goto Quit; + + start = player->GetEyePosition(); + // do a trace 512 doom units ahead + end = start + 512.0f * (player->viewAngles.ToForward()); + + cm = CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_TRIGGER; + gameLocal.clip.TracePoint( trace, start, end, cm, player ); + if( trace.fraction < 1.0f ) + { + returnEnt = gameLocal.entities[ trace.c.entityNum ]; + // don't return the world + if( returnEnt == gameLocal.world ) + returnEnt = NULL; + } + +Quit: + return returnEnt; +} + +void idGameLocal::PauseGame( bool bPauseState ) +{ + if( bPauseState ) + { + gameSoundWorldBuf = soundSystem->GetPlayingSoundWorld(); + gameSoundWorldBuf->Pause(); + soundSystem->SetPlayingSoundWorld( NULL ); + + g_stopTime.SetBool( true ); + } + else + { + soundSystem->SetPlayingSoundWorld( gameSoundWorldBuf ); + soundSystem->GetPlayingSoundWorld()->UnPause(); + + g_stopTime.SetBool( false ); + } +} + +void idGameLocal::SetMissionResult(EMissionResult result) +{ + m_MissionResult = result; +} + +EMissionResult idGameLocal::GetMissionResult() const +{ + return m_MissionResult; +} + +float idGameLocal::CalcLightgem( idPlayer *a_pPlayer ) +{ + return m_lightGem.Calculate( a_pPlayer ); +} +/* +=================== +Dark Mod: +idGameLocal::FindMainAmbientLight +Author: J.C.Denton +Usage: Finds main ambient light by the name "ambient_world". + If it can't be found, finds ambient light with largest radius and rename it to ambient_world before returning pointer to it. +=================== +*/ + +idLight * idGameLocal::FindMainAmbientLight( bool a_bCreateNewIfNotFound /*= false */ ) +{ + int hash, i; + idEntity *pEntMainAmbientLight = NULL; + + hash = entityHash.GenerateKey( m_strMainAmbientLightName, true ); + for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { + if ( entities[i] && entities[i]->name.Icmp( m_strMainAmbientLightName ) == 0 ) { + pEntMainAmbientLight = entities[i]; + break; + } + } + + if ( NULL != pEntMainAmbientLight && pEntMainAmbientLight->IsType(idLight::Type) ) + return static_cast( pEntMainAmbientLight ); + else if( !a_bCreateNewIfNotFound ) + return NULL; + + gameLocal.Printf( "Ambient light by name of 'ambient_world' not found, attempting to create a new one. \n"); + + idLight *pLightEntMainAmbient = NULL; + float fMaxRadius = 0.0f; + int j=1; + for (int i = 0; i < MAX_GENTITIES; i++) + { + // Find the ambient light with greatest radius. + if( NULL != entities[i] && entities[i]->IsType(idLight::Type) ) + { + idVec3 vec3LightRadius; + idLight *pLight = static_cast( entities[i] ); +// gameLocal.Printf( "Light found %i \n", j++ ); + + if (!pLight->IsAmbient()) + continue; + + pLight->GetRadius( vec3LightRadius ); + + float fRadius = vec3LightRadius.Length(); + //gameLocal.Printf( "The Light is ambient, max radius: %f current radius: %f \n", fMaxRadius, fRadius ); + + if( fRadius > fMaxRadius ) + { + fMaxRadius = fRadius; + pLightEntMainAmbient = pLight; + } + } + } + + if( pLightEntMainAmbient ) + { + m_strMainAmbientLightName = pLightEntMainAmbient->GetName(); + gameLocal.Printf( "Found light %s and now is set as the main ambient light. \n", m_strMainAmbientLightName.c_str() ); + } + + return pLightEntMainAmbient; + +} + +#ifdef WIN32 +namespace +{ + // greebo: This little snippet is changing the window title to something more appropriate. + BOOL CALLBACK ChangeD3WindowTitle(HWND hwnd,LPARAM lParam) + { + // Find the window of our process + DWORD procId; + if (GetWindowThreadProcessId(hwnd, &procId) && procId == GetCurrentProcessId()) + { + if (!GetWindow(hwnd, GW_OWNER)) + { + char title[256]; + GetWindowText(hwnd, title, 255); + + if (std::string(title) == "DOOM 3") + { + std::string newTitle = va("%s %d.%02d", GAME_VERSION, TDM_VERSION_MAJOR, TDM_VERSION_MINOR); + SetWindowText(hwnd, newTitle.c_str()); + + fs::path darkmodPath = g_Global.GetDarkmodPath(); + darkmodPath /= "darkmod.ico"; + + HICON hIcon = (HICON)LoadImage(NULL, darkmodPath.file_string().c_str(), IMAGE_ICON, 32, 32, LR_LOADFROMFILE); + + if (hIcon) + { + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); + } + + return false; + } + } + } + + return true; + } +} +#endif + +void idGameLocal::ChangeWindowTitleAndIcon() +{ +#ifdef WIN32 + EnumWindows((WNDENUMPROC)ChangeD3WindowTitle, 0); +#endif +} + +void idGameLocal::ClearPersistentInfo() +{ + persistentPlayerInventory->Clear(); + persistentLevelInfo.Clear(); + m_CampaignStats.reset(new CampaignStats); + m_InterMissionTriggers.Clear(); +} + +void idGameLocal::ProcessInterMissionTriggers() +{ + for (int i = 0; i < m_InterMissionTriggers.Num(); ++i) + { + const InterMissionTrigger& trigger = m_InterMissionTriggers[i]; + + if (trigger.missionNum == m_MissionManager->GetCurrentMissionIndex()) + { + idEntity* target = FindEntity(trigger.targetName); + idEntity* activator = !trigger.activatorName.IsEmpty() ? FindEntity(trigger.activatorName) : GetLocalPlayer(); + + if (target != NULL) + { + target->Activate(activator); + } + else + { + gameLocal.Warning("Cannot find intermission trigger target entity %s", trigger.targetName.c_str()); + } + + // Don't remove the triggers yet, we might need them again when restarting the map + } + } +} diff --git a/game/Game_local.h b/game/Game_local.h new file mode 100644 index 000000000..b01c7b914 --- /dev/null +++ b/game/Game_local.h @@ -0,0 +1,1297 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_LOCAL_H__ +#define __GAME_LOCAL_H__ + +#include "Game.h" + +#ifdef __linux__ +#include "../framework/UsercmdGen.h" +#endif + +#pragma warning(disable : 4996) +/** +* Message pragma so we can show file and line info in comments easily +* Same principle as the one below but simpler to implement and use. +* Been using it for about 8 or 9 years not sure where I found it +* but I did have a subscription to windows developer journal so maybe thats where. +* Usage: #pragma Message( "your message goes here") +* +* Submitted by Thelvyn +* +* Here since I cannot include the globals file here. +*/ +#ifndef MacroStr2 +#define MacroStr(x) #x +#define MacroStr2(x) MacroStr(x) +#define Message(desc) message(__FILE__ "(" MacroStr2(__LINE__) ") :" #desc) +#endif + + +/** + * Global function to keep track of the files and it's version. + */ +bool FileVersionList(const char *str, bool state); + +// enables water physics +#define MOD_WATERPHYSICS + +/* +=============================================================================== + + Local implementation of the public game interface. + +=============================================================================== +*/ + +#define LAGO_IMG_WIDTH 64 +#define LAGO_IMG_HEIGHT 64 +#define LAGO_WIDTH 64 +#define LAGO_HEIGHT 44 +#define LAGO_MATERIAL "textures/sfx/lagometer" +#define LAGO_IMAGE "textures/sfx/lagometer.tga" + +// if set to 1 the server sends the client PVS with snapshots and the client compares against what it sees +#ifndef ASYNC_WRITE_PVS + #define ASYNC_WRITE_PVS 0 +#endif + +#ifdef ID_DEBUG_UNINITIALIZED_MEMORY +// This is real evil but allows the code to inspect arbitrary class variables. +#define private public +#define protected public +#endif + +class idLight; // J.C.Denton: Required for the declaration of FindMainAmbientLight + +class idRenderWorld; +extern idRenderWorld * gameRenderWorld; + +class idSoundWorld; +extern idSoundWorld * gameSoundWorld; +/** +* place to store the sound world pointer when we temporarily set it to NULL +**/ +extern idSoundWorld * gameSoundWorldBuf; + +// the "gameversion" client command will print this plus compile date +#define GAME_VERSION "The Dark Mod" + +// classes used by idGameLocal +class idEntity; +class idActor; +class idPlayer; +class idCamera; +class idWorldspawn; +class idTestModel; +class idAAS; +class idAI; +class idSmokeParticles; +class idEntityFx; +class idTypeInfo; +class idProgram; +class idThread; +class idEditEntities; +class idLocationEntity; + +#define MAX_CLIENTS 32 +#define GENTITYNUM_BITS 13 +#define MAX_GENTITIES (1< + +#ifdef __linux__ +#include "../renderer/RenderWorld.h" +#endif + +//============================================================================ + +class CLightMaterial; +class CsndPropLoader; +class CsndProp; +class CRelations; +typedef boost::shared_ptr CRelationsPtr; +class CMissionData; +typedef boost::shared_ptr CMissionDataPtr; +class CampaignStats; +typedef boost::shared_ptr CampaignStatsPtr; +class CStimResponse; +typedef boost::shared_ptr CStimResponsePtr; +class CStim; +typedef boost::shared_ptr CStimPtr; +class CStimResponseTimer; +class CGrabber; +class CEscapePointManager; +class CMissionManager; +typedef boost::shared_ptr CMissionManagerPtr; +class CHttpConnection; +typedef boost::shared_ptr CHttpConnectionPtr; +class CInventory; +typedef boost::shared_ptr CInventoryPtr; + +class CModMenu; +typedef boost::shared_ptr CModMenuPtr; + +class CModelGenerator; +typedef boost::shared_ptr CModelGeneratorPtr; +class CImageMapManager; +typedef boost::shared_ptr CImageMapManagerPtr; +class CLightController; +typedef boost::shared_ptr CLightControllerPtr; +class CI18N; +typedef boost::shared_ptr CI18NPtr; + +// Forward declare the Conversation System +namespace ai { + class ConversationSystem; + typedef boost::shared_ptr ConversationSystemPtr; +} // namespace + +class CDownloadMenu; +typedef boost::shared_ptr CDownloadMenuPtr; +class CDownloadManager; +typedef boost::shared_ptr CDownloadManagerPtr; + +class CShop; +typedef boost::shared_ptr CShopPtr; + +const int MAX_GAME_MESSAGE_SIZE = 8192; +const int MAX_ENTITY_STATE_SIZE = 512; +const int ENTITY_PVS_SIZE = ((MAX_GENTITIES+31)>>5); +const int NUM_RENDER_PORTAL_BITS = idMath::BitsForInteger( PS_BLOCK_ALL ); + +typedef struct entityState_s { + int entityNumber; + idBitMsg state; + byte stateBuf[MAX_ENTITY_STATE_SIZE]; + struct entityState_s * next; +} entityState_t; + +typedef struct snapshot_s { + int sequence; + entityState_t * firstEntityState; + int pvs[ENTITY_PVS_SIZE]; + struct snapshot_s * next; +} snapshot_t; + +const int MAX_EVENT_PARAM_SIZE = 128; + +typedef struct entityNetEvent_s { + int spawnId; + int event; + int time; + int paramsSize; + byte paramsBuf[MAX_EVENT_PARAM_SIZE]; + struct entityNetEvent_s *next; + struct entityNetEvent_s *prev; +} entityNetEvent_t; + +enum { + GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP, + GAME_RELIABLE_MESSAGE_REMAP_DECL, + GAME_RELIABLE_MESSAGE_SPAWN_PLAYER, + GAME_RELIABLE_MESSAGE_DELETE_ENT, + GAME_RELIABLE_MESSAGE_CHAT, + GAME_RELIABLE_MESSAGE_TCHAT, + GAME_RELIABLE_MESSAGE_SOUND_EVENT, + GAME_RELIABLE_MESSAGE_SOUND_INDEX, + GAME_RELIABLE_MESSAGE_DB, + GAME_RELIABLE_MESSAGE_KILL, + GAME_RELIABLE_MESSAGE_DROPWEAPON, + GAME_RELIABLE_MESSAGE_RESTART, + GAME_RELIABLE_MESSAGE_SERVERINFO, + GAME_RELIABLE_MESSAGE_TOURNEYLINE, + GAME_RELIABLE_MESSAGE_CALLVOTE, + GAME_RELIABLE_MESSAGE_CASTVOTE, + GAME_RELIABLE_MESSAGE_STARTVOTE, + GAME_RELIABLE_MESSAGE_UPDATEVOTE, + GAME_RELIABLE_MESSAGE_PORTALSTATES, + GAME_RELIABLE_MESSAGE_PORTAL, + GAME_RELIABLE_MESSAGE_VCHAT, + GAME_RELIABLE_MESSAGE_STARTSTATE, + GAME_RELIABLE_MESSAGE_MENU, + GAME_RELIABLE_MESSAGE_WARMUPTIME, + GAME_RELIABLE_MESSAGE_EVENT +}; + +typedef enum { + GAMESTATE_UNINITIALIZED, // prior to Init being called + GAMESTATE_NOMAP, // no map loaded + GAMESTATE_STARTUP, // inside InitFromNewMap(). spawning map entities. + GAMESTATE_ACTIVE, // normal gameplay + GAMESTATE_COMPLETED, // greebo: Active during "Mission Complete" (TDM) + GAMESTATE_SHUTDOWN // inside MapShutdown(). clearing memory. +} gameState_t; + +// Message type for user interaction in the main menu +struct GuiMessage +{ + idStr title; + idStr message; + + enum Type + { + MSG_OK, + MSG_YES_NO, + MSG_OK_CANCEL, + }; + + Type type; + + idStr positiveCmd; // which "cmd" to execute on OK / Yes + idStr negativeCmd; // which "cmd" to execute on Cancel / No + idStr okCmd; // which "cmd" to execute on OK (only for MSG_OK) +}; + +typedef struct { + idEntity *ent; + int dist; +} spawnSpot_t; + +/** +* Sound prop. flags are used by many classes (Actor, soundprop, entity, etc) +* Therefore they are global. +* See sound prop doc file for definitions of these flags. +**/ + +typedef struct SSprFlagBits_s +{ + // team alert flags + unsigned int friendly : 1; + unsigned int neutral : 1; + unsigned int enemy : 1; + unsigned int same : 1; + + // propagation flags + unsigned int omni_dir : 1; // omnidirectional + unsigned int unique_loc : 1; // sound comes from a unique location + unsigned int urgent : 1; // urgent (AI tries to respond ASAP) + unsigned int global_vol : 1; // sound has same volume over whole map + unsigned int check_touched : 1; // for non-AI, check who last touched the entity +} SSprFlagBits; + +typedef union USprFlags_s +{ + unsigned int m_field; + SSprFlagBits m_bits; +} USprFlags; + +/** +* Sound propagation parameters: needed for function arguments +**/ + +struct SSprParms +{ + USprFlags flags; + + idStr name; // sound name + float propVol; // propagated volume + + // Apparent direction of the sound, determined by the path point on the portal + idVec3 direction; + // actual origin of the sound, used for some localization simulation + idVec3 origin; + float duration; // duration + int frequency; // int representing the octave of the sound + float bandwidth; // sound bandwidth + + float loudness; // this is set by AI hearing response + float alertFactor; // angua: alert increase is scaled by this factor + float alertMax; // angua: alert increase can not become higher than this + + bool bSameArea; // true if the sound came from same portal area + bool bDetailedPath; // true if detailed path minimization was used to obtain the sound path + int floods; // number of portals the sound travelled thru before it hit the AI + + idEntity* maker; // it turns out the AI needs to know who made the sound to avoid bugs in some cases + idAI* makerAI; // a shorthand of the above. If this is non NULL the entity is an AI. +}; + +//============================================================================ + +class idEventQueue { +public: + typedef enum { + OUTOFORDER_IGNORE, + OUTOFORDER_DROP, + OUTOFORDER_SORT + } outOfOrderBehaviour_t; + + idEventQueue() : start( NULL ), end( NULL ) {} + + entityNetEvent_t * Alloc(); + void Free( entityNetEvent_t *event ); + void Shutdown(); + + void Init(); + void Enqueue( entityNetEvent_t* event, outOfOrderBehaviour_t oooBehaviour ); + entityNetEvent_t * Dequeue( void ); + entityNetEvent_t * RemoveLast( void ); + + entityNetEvent_t * Start( void ) { return start; } + +private: + entityNetEvent_t * start; + entityNetEvent_t * end; + idBlockAlloc eventAllocator; +}; + +//============================================================================ + +template< class type > +class idEntityPtr { +public: + idEntityPtr(); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + idEntityPtr & operator=( type *ent ); + bool operator==(const idEntityPtr& other) const; + + // synchronize entity pointers over the network + int GetSpawnId( void ) const { return spawnId; } + bool SetSpawnId( int id ); + bool UpdateSpawnId( void ); + + bool IsValid( void ) const; + type * GetEntity( void ) const; + int GetEntityNum( void ) const; + +private: + int spawnId; +}; + +// Note: Because lightgem.h uses idEntityPr, the file should be included here or +// idEntityPtr Definition should be moved to lightgem.h. - J.C.Denton + +#include "LightGem.h" +//============================================================================ + +class idDeclEntityDef; + +class idGameLocal : public idGame { +public: + idDict serverInfo; // all the tunable parameters, like numclients, etc + int numClients; // pulled from serverInfo and verified + idDict userInfo[MAX_CLIENTS]; // client specific settings + usercmd_t usercmds[MAX_CLIENTS]; // client input commands + idDict persistentPlayerInfo[MAX_CLIENTS]; + idEntity * entities[MAX_GENTITIES];// index to entities + int spawnIds[MAX_GENTITIES];// for use in idEntityPtr + + // greebo: For use in Stim/Response system (gets invalidated each frame) + idEntity* srEntities[MAX_GENTITIES]; + + int firstFreeIndex; // first free index in the entities array + int num_entities; // current number <= MAX_GENTITIES + idHashIndex entityHash; // hash table to quickly find entities by name + idWorldspawn * world; // world entity + idLinkList spawnedEntities; // all spawned entities + idLinkList activeEntities; // all thinking entities (idEntity::thinkFlags != 0) + idLinkList spawnedAI; // greebo: all spawned AI + int numEntitiesToDeactivate;// number of entities that became inactive in current frame + bool sortPushers; // true if active lists needs to be reordered to place pushers at the front + bool sortTeamMasters; // true if active lists needs to be reordered to place physics team masters before their slaves + idDict persistentLevelInfo; // contains args that are kept around between levels + + // The inventory class which keeps items safe between maps + CInventoryPtr persistentPlayerInventory; + + // The list of campaign info entities in this map + idList campaignInfoEntities; + + // greebo: Is set to TRUE if the post-mission screen (debriefing or success screen) is currently active. + // (Usually these state variables should be kept in the GUI, but in this case I need it to be accessible + // when the player loads a new map via the console.) + bool postMissionScreenActive; + + // Toggle to keep track whether the GUI state variables have been set up + bool briefingVideoInfoLoaded; + + // Hold information about a single video piece + struct BriefingVideoPart + { + idStr material; // name of the material + int lengthMsec; // length in msecs + }; + + // The list of briefing videos for the current mission + idList briefingVideo; + + // Index into the above list + int curBriefingVideoPart; + + // The list of DE-briefing videos for the current mission + idList debriefingVideo; + + // Index into the above list + int curDebriefingVideoPart; + + bool mainMenuExited; // Solarsplace 19th Nov 2010 - Bug tracker id 0002424 + + // can be used to automatically effect every material in the world that references globalParms + float globalShaderParms[ MAX_GLOBAL_SHADER_PARMS ]; + + idRandom random; // random number generator used throughout the game + + idProgram program; // currently loaded script and data space + idThread * frameCommandThread; + + idClip clip; // collision detection + idPush push; // geometric pushing + idPVS pvs; // potential visible set + + idTestModel * testmodel; // for development testing of models + idEntityFx * testFx; // for development testing of fx + + idStr sessionCommand; // a target_sessionCommand can set this to return something to the session + + idMultiplayerGame mpGame; // handles rules for standard dm + + idSmokeParticles * smokeParticles; // global smoke trails + idEditEntities * editEntities; // in game editing + + // Darkmod's grabber to help with object manipulation + CGrabber* m_Grabber; + + // The object handling the difficulty settings + difficulty::DifficultyManager m_DifficultyManager; + + // The manager for handling AI => Area mappings (needed for AI to remember locked doors, for instance) + ai::AreaManager m_AreaManager; + + // The manager class for all map conversations + ai::ConversationSystemPtr m_ConversationSystem; + + /** + * greebo: The fan-mission-handling class. Also contains GUI handling code. + */ + CModMenuPtr m_ModMenu; + + // The download menu handler + CDownloadMenuPtr m_DownloadMenu; + + // The download manager + CDownloadManagerPtr m_DownloadManager; + + /** + * greebo: The mission manager instance, for manipulating mission PK4s and saving play info. + */ + CMissionManagerPtr m_MissionManager; + + /** + * tels: The model generator instance, for manipulating/generating models on the fly. + */ + CModelGeneratorPtr m_ModelGenerator; + + /** + * tels: The image mapmanager instance, for loading/sharing image maps for the SEED system. + */ + CImageMapManagerPtr m_ImageMapManager; + + /** + * tels: The light controller instance, used to control local ambient lights. + */ + CLightControllerPtr m_LightController; + + /** + * tels: The I18N object (for translation etc.) + */ + CI18NPtr m_I18N; + + /** + * greebo: The class handling the main menu's shop GUI. + */ + CShopPtr m_Shop; + + /** + * This list is some sort of queue of error messages collected by + * gameLocal.Error(). The messages here will be sent + * to the main menu GUI once it is displayed again after the error. + */ + mutable idStr m_guiError; + + mutable idList m_GuiMessages; + + /** + * Pointer to global AI Relations object + **/ + CRelationsPtr m_RelationsManager; + + /** + * Pointer to global Mission Data object (objectives & stats) + **/ + CMissionDataPtr m_MissionData; + EMissionResult m_MissionResult; // holds the global mission state + + // Campaign statistics + CampaignStatsPtr m_CampaignStats; + + /** + * Pointer to global sound prop loader object + **/ + CsndPropLoader * m_sndPropLoader; + + /** + * Pointer to global sound prop gameplay object + **/ + CsndProp * m_sndProp; + + /** + * greebo: The escape point manager which is keeping track + * of all the tdmPathFlee entities. + */ + CEscapePointManager* m_EscapePointManager; + + /** + * greebo: This timer keeps track of the actual gameplay time. + */ + GamePlayTimer m_GamePlayTimer; + + // The singleton connection object + CHttpConnectionPtr m_HttpConnection; + + /** + * Temporary storage of the walkspeed. This is a workaround + * because the walkspeed keeps getting reset. + **/ + float m_walkSpeed; + + // The highest used unique stim/response id + int m_HighestSRId; + + idList m_Timer; // generic timer used for other purposes than stims. + idList m_StimTimer; // All stims that have a timer associated. + idList< idEntityPtr > m_StimEntity; // all entities that currently have a stim regardless of it's state + idList< idEntityPtr > m_RespEntity; // all entities that currently have a response regardless of it's state + + int cinematicSkipTime; // don't allow skipping cinemetics until this time has passed so player doesn't skip out accidently from a firefight + int cinematicStopTime; // cinematics have several camera changes, so keep track of when we stop them so that we don't reset cinematicSkipTime unnecessarily + int cinematicMaxSkipTime; // time to end cinematic when skipping. there's a possibility of an infinite loop if the map isn't set up right. + bool inCinematic; // game is playing cinematic (player controls frozen) + bool skipCinematic; + + // are kept up to date with changes to serverInfo + int framenum; + int previousTime; // time in msec of last frame + int time; // in msec + int m_Interleave; // How often should the lightgem calculation be skipped? + static const int msec = USERCMD_MSEC; // time since last update in milliseconds + + int vacuumAreaNum; // -1 if level doesn't have any outside areas + + gameType_t gameType; + bool isMultiplayer; // set if the game is run in multiplayer mode + bool isServer; // set if the game is run for a dedicated or listen server + bool isClient; // set if the game is run for a client + // discriminates between the RunFrame path and the ClientPrediction path + // NOTE: on a listen server, isClient is false + int localClientNum; // number of the local client. MP: -1 on a dedicated + idLinkList snapshotEntities; // entities from the last snapshot + int realClientTime; // real client time + bool isNewFrame; // true if this is a new game frame, not a rerun due to prediction + float clientSmoothing; // smoothing of other clients in the view + int entityDefBits; // bits required to store an entity def number + + static const char * sufaceTypeNames[ MAX_SURFACE_TYPES ]; // text names for surface types + /** + * DarkMod: text names for new surface types + **/ + static const char * m_NewSurfaceTypes[ MAX_SURFACE_TYPES*2 + 1]; + + idEntityPtr lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f + int lastGUI; // last GUI on the lastGUIEnt + + idEntityPtr portalSkyEnt; + bool portalSkyActive; + + void SetPortalSkyEnt( idEntity *ent ); + bool IsPortalSkyAcive(); + + // tels: a list of all speaker entities with s_music set, these are affected by s_vol_music: + idList musicSpeakers; + + // A flag set by the player to fire a "final save" which must occur at the end of this frame + bool m_TriggerFinalSave; + + // grayman #2933 - store the start position selected during the mission briefing, if any + const char * m_StartPosition; + + // ---------------------- Public idGame Interface ------------------- + + idGameLocal(); + ~idGameLocal(); + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void SetLocalClient( int clientNum ); + virtual void ThrottleUserInfo( void ); + virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ); + virtual const idDict * GetUserInfo( int clientNum ); + virtual void SetServerInfo( const idDict &serverInfo ); + + virtual const idDict & GetPersistentPlayerInfo( int clientNum ); + virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ); + virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed ); + virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ); + virtual void SaveGame( idFile *saveGameFile ); + virtual void MapShutdown( void ); + virtual void CacheDictionaryMedia( const idDict *dict ); + virtual void SpawnPlayer( int clientNum ); + virtual gameReturn_t RunFrame( const usercmd_t *clientCmds ); + + /** + * TDM: Pause/Unpause game + **/ + virtual void PauseGame( bool bPauseState ); + virtual bool Draw( int clientNum ); + virtual escReply_t HandleESC( idUserInterface **gui ); + virtual idUserInterface *StartMenu( void ); + virtual const char * HandleGuiCommands( const char *menuCommand ); + virtual bool InitGUIChoice( idUserInterface *gui, const char *varName, const char *inChoices, const char *inValues, const bool step = false ); + virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ); + /** + * Adjusts the size of GUI variables to support stretching/scaling of the GUI. + */ + virtual void UpdateGUIScaling( idUserInterface *gui ); + virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] ); + virtual void ServerClientConnect( int clientNum, const char *guid ); + virtual void ServerClientBegin( int clientNum ); + virtual void ServerClientDisconnect( int clientNum ); + virtual void ServerWriteInitialReliableMessages( int clientNum ); + virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ); + virtual bool ServerApplySnapshot( int clientNum, int sequence ); + virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ); + virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ); + virtual bool ClientApplySnapshot( int clientNum, int sequence ); + virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ); + virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ); + + virtual void GetClientStats( int clientNum, char *data, const int len ); + virtual void SwitchTeam( int clientNum, int team ); + + virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ); + + // ---------------------- Public idGameLocal Interface ------------------- + + void Printf( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void DPrintf( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void DWarning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + + // Initializes all map variables common to both save games and spawned games + void LoadMap( const char *mapName, int randseed ); + + void LocalMapRestart( void ); + void MapRestart( void ); + static void MapRestart_f( const idCmdArgs &args ); + bool NextMap( void ); // returns whether serverinfo settings have been modified + static void NextMap_f( const idCmdArgs &args ); + + idMapFile * GetLevelMap( void ); + const char * GetMapName( void ) const; + + int NumAAS( void ) const; + int GetAASId( idAAS* aas ) const; // greebo: Returns the ID for the given pointer (-1 for invalid pointers) + idAAS * GetAAS( int num ) const; + idAAS * GetAAS( const char *name ) const; + void SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed ); + aasHandle_t AddAASObstacle( const idBounds &bounds ); + void RemoveAASObstacle( const aasHandle_t handle ); + void RemoveAllAASObstacles( void ); + + // greebo: Initialises the EAS (routing system for elevators) + void SetupEAS(); + + bool CheatsOk( bool requirePlayer = true ); + void SetSkill( int value ); + gameState_t GameState( void ) const; + + /** + * greebo: Prepares the running map for mission end. Does nothing if the current gamestate + * is lower than GAMESTATE_ACTIVE. Removes all entities of certain types from the + * world and sets all moveables to rest. + */ + void PrepareForMissionEnd(); + + void SetMissionResult(EMissionResult result); + ID_INLINE EMissionResult GetMissionResult() const; + + idEntity * SpawnEntityType( const idTypeInfo &classdef, const idDict *args = NULL, bool bIsClientReadSnapshot = false ); + bool SpawnEntityDef( const idDict &args, idEntity **ent = NULL, bool setDefaults = true ); + int GetSpawnId( const idEntity *ent ) const; + + const idDeclEntityDef * FindEntityDef( const char *name, bool makeDefault = true ) const; + const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const; + + void RegisterEntity( idEntity *ent ); + void UnregisterEntity( idEntity *ent ); + + bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem ); + + bool InPlayerPVS( idEntity *ent ) const; + bool InPlayerConnectedArea( idEntity *ent ) const; + + pvsHandle_t GetPlayerPVS() { return playerPVS; }; + + void SetCamera( idCamera *cam ); + idCamera * GetCamera( void ) const; + bool SkipCinematic( void ); + void CalcFov( float base_fov, float &fov_x, float &fov_y ) const; + + void AddEntityToHash( const char *name, idEntity *ent ); + bool RemoveEntityFromHash( const char *name, idEntity *ent ); + int GetTargets( const idDict &args, idList< idEntityPtr >& list, const char *ref ) const; + int GetRelights(const idDict &args, idList >& list, const char *ref) const; // grayman #2603 + + // returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player. + idEntity * GetTraceEntity( const trace_t &trace ) const; + + static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) ); + idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const; + idEntity * FindEntity( const char *name ) const; + idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const; + int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const; + + /** + * Get the entity that the player is looking at + * Currently called by console commands, does a long trace so should not be + * called every frame. + **/ + idEntity * PlayerTraceEntity( void ); + + void KillBox( idEntity *ent, bool catch_teleport = false ); + void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f ); + void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake ); + void RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel ); + + void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 ); + void BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); + + void CallFrameCommand( idEntity *ent, const function_t *frameCommand ); + void CallObjectFrameCommand( idEntity *ent, const char *frameCommand ); + + const idVec3 & GetGravity( void ) const; + + // added the following to assist licensees with merge issues + int GetFrameNum() const { return framenum; }; + int GetTime() const { return time; }; + int GetMSec() const { return msec; }; + + int GetNextClientNum( int current ) const; + idPlayer * GetClientByNum( int current ) const; + idPlayer * GetClientByName( const char *name ) const; + idPlayer * GetClientByCmdArgs( const idCmdArgs &args ) const; + + idPlayer * GetLocalPlayer() const; + + void SpreadLocations(); + idLocationEntity * LocationForPoint( const idVec3 &point ); // May return NULL + /** + * LocationForArea returns a pointer to the location entity for the given area number + * Returns NULL if the area number is out of bounds, or if locations haven't sprad yet + **/ + idLocationEntity * LocationForArea( const int areaNum ); + + idEntity * SelectInitialSpawnPoint( idPlayer *player ); + + void SetPortalState( qhandle_t portal, int blockingBits ); + void SaveEntityNetworkEvent( const idEntity *ent, int event, const idBitMsg *msg ); + void ServerSendChatMessage( int to, const char *name, const char *text ); + int ServerRemapDecl( int clientNum, declType_t type, int index ); + int ClientRemapDecl( declType_t type, int index ); + + void SetGlobalMaterial( const idMaterial *mat ); + const idMaterial * GetGlobalMaterial(); + + void SetGibTime( int _time ) { nextGibTime = _time; }; + int GetGibTime() { return nextGibTime; }; + + bool NeedRestart(); + + /** + * LoadLightMaterial loads the falloff textures from the light materials. The appropriate + * textures are only loaded when the light is spawned and requests the texture. + */ + void LoadLightMaterial(const char *Filename, idList *); + + /** + * CalcLightgem will do the rendersnapshot and analyze the snaphost image in order + * to determine the lightvalue for the lightgem. + */ + float CalcLightgem(idPlayer*); + + ID_INLINE idList &GetLightgemRenderBuffer(void) + { + return m_lightGem.GetLightgemRenderBuffer(); + } + + bool AddStim(idEntity *); + void RemoveStim(idEntity *); + bool AddResponse(idEntity *); + void RemoveResponse(idEntity *); + + /************************************************************************/ + /* J.C.Denton: Finds the main ambient light and creates a new one if */ + /* the main ambient is not found */ + /************************************************************************/ + idLight * FindMainAmbientLight( bool a_bCreateNewIfNotFound = false ); + + /** + * greebo: Links the given entity into the list of Stim entities, such that + * it gets considered each frame as potential stim emitter. + */ + void LinkStimEntity(idEntity* ent); + + /** + * greebo: Removes the given entity from the global list of stimming entities. + * Although it might have active stims, it is no longer considered each frame. + */ + void UnlinkStimEntity(idEntity* ent); + + /** + * Checks whether the entity is in the given list named . + * @returns: the list index or -1 if the entity is not in the list. + */ + int CheckStimResponse(idList< idEntityPtr > &list, idEntity *); + + /** + * Fires off all the enabled responses to this stim of the entities in the given entites list. + * If the trigger is coming from a timer, is set to true. + * + * @return The number of responses triggered + * + */ + int DoResponseAction(const CStimPtr& stim, int numEntities, idEntity* originator, const idVec3& stimOrigin); + + /** + * Process the timer ticks for all timers that are used for other purposes than stim/responses. + */ + void ProcessTimer(unsigned long ticks); + + /** + * ProcessStimResponse will check whether stims are in reach of a response and if so activate them. + */ + void ProcessStimResponse(unsigned long ticks); + + /** + * greebo: Traverses the entities and tries to find the Stim/Response with the given ID. + * This is expensive, so don't call this during map runtime, only in between maps. + * + * @returns: the pointer to the class, or NULL if the uniqueId couldn't be found. + */ + CStimResponsePtr FindStimResponse(int uniqueId); + + // Checks the TDM version + void CheckTDMVersion(); + + void AddMainMenuMessage(const GuiMessage& message); + void HandleGuiMessages(idUserInterface* ui); + + // Tels: Return mapFileName as it is private + const idStr& GetMapFileName() const; + + /** + * greebo: Register a trigger that is to be fired when the mission is loaded. + * The activatorName is stored along with the name of the target to be triggered. When the target map + * has been loaded and all entities have been spawned the game will try to resolve these names + * and issue the activation event. + * If the activator's name is empty, the local player will be used as activator. + */ + void AddInterMissionTrigger(int missionNum, const idStr& activatorName, const idStr& targetName); + + // For internal use, is public to be callable by the event system + void ProcessInterMissionTriggers(); + + // Remove any persistent inventory items, clear inter-mission triggers, etc. + void ClearPersistentInfo(); + +private: + const static int INITIAL_SPAWN_COUNT = 1; + + idStr m_strMainAmbientLightName; // The name of main ambient light, default is: "ambient_world". - J.C.Denton + idStr mapFileName; // name of the map, empty string if no map loaded + idMapFile * mapFile; // will be NULL during the game unless in-game editing is used + bool mapCycleLoaded; + + int spawnCount; + int mapSpawnCount; // it's handy to know which entities are part of the map + + idLocationEntity ** locationEntities; // for location names, etc + + idCamera * camera; + const idMaterial * globalMaterial; // for overriding everything + + idList aasList; // area system + idStrList aasNames; + + idDict spawnArgs; // spawn args used during entity spawning FIXME: shouldn't be necessary anymore + + pvsHandle_t playerPVS; // merged pvs of all players + pvsHandle_t playerConnectedAreas; // all areas connected to any player area + + idVec3 gravity; // global gravity vector + gameState_t gamestate; // keeps track of whether we're spawning, shutting down, or normal gameplay + bool influenceActive; // true when a phantasm is happening + int nextGibTime; + + idList clientDeclRemap[MAX_CLIENTS][DECL_MAX_TYPES]; + + entityState_t * clientEntityStates[MAX_CLIENTS][MAX_GENTITIES]; + int clientPVS[MAX_CLIENTS][ENTITY_PVS_SIZE]; + snapshot_t * clientSnapshots[MAX_CLIENTS]; + idBlockAllocentityStateAllocator; + idBlockAllocsnapshotAllocator; + + idEventQueue eventQueue; + idEventQueue savedEventQueue; + + idStaticList spawnSpots; + idStaticList initialSpots; + int currentInitialSpot; + + idDict newInfo; + + idStrList shakeSounds; + + byte lagometer[ LAGO_IMG_HEIGHT ][ LAGO_IMG_WIDTH ][ 4 ]; + + bool m_DoLightgem; // Signal when the lightgem may be processed. + LightGem m_lightGem; + + // A container for keeping the inter-mission trigger information + struct InterMissionTrigger + { + // The number of the mission this trigger applies to + int missionNum; + + // The name of the entity that should be used as activator. Is resolved immediately after spawn time. + // If empty, the player will be used. + idStr activatorName; + + // The name of the target entity to be triggered. Is resolved immediately after spawn time. + idStr targetName; + }; + + idList m_InterMissionTriggers; + + // Tels: For each part in a GUI command in 'set "cmd" "command arg1 arg2;" the game will + // call HandleMainMenuCommand(), sometimes with a final call with the ";". + // This list here keeps all these parts so we can execute the command + // and have all the arguments, too. + idList m_GUICommandStack; + // how many arguments do we expect for the current command (m_GUICommandStack[0]): + int m_GUICommandArgs; + + void Clear( void ); + // returns true if the entity shouldn't be spawned at all in this game type or difficulty level + bool InhibitEntitySpawn( idDict &spawnArgs ); + // spawn entities from the map file + void SpawnMapEntities( void ); + // commons used by init, shutdown, and restart + void MapPopulate( void ); + void MapClear( bool clearClients ); + + pvsHandle_t GetClientPVS( idPlayer *player, pvsType_t type ); + void SetupPlayerPVS( void ); + void FreePlayerPVS( void ); + void UpdateGravity( void ); + void SortActiveEntityList( void ); + void ShowTargets( void ); + void RunDebugInfo( void ); + + void InitScriptForMap( void ); + + void InitConsoleCommands( void ); + void ShutdownConsoleCommands( void ); + + void InitAsyncNetwork( void ); + void ShutdownAsyncNetwork( void ); + void InitLocalClient( int clientNum ); + void InitClientDeclRemap( int clientNum ); + void ServerSendDeclRemapToClient( int clientNum, declType_t type, int index ); + void FreeSnapshotsOlderThanSequence( int clientNum, int sequence ); + bool ApplySnapshot( int clientNum, int sequence ); + void WriteGameStateToSnapshot( idBitMsgDelta &msg ) const; + void ReadGameStateFromSnapshot( const idBitMsgDelta &msg ); + void NetworkEventWarning( const entityNetEvent_t *event, const char *fmt, ... ) id_attribute((format(printf,3,4))); + void ServerProcessEntityNetworkEventQueue( void ); + void ClientProcessEntityNetworkEventQueue( void ); + void ClientShowSnapshot( int clientNum ) const; + // call after any change to serverInfo. Will update various quick-access flags + void UpdateServerInfoFlags( void ); + void RandomizeInitialSpawns( void ); + static int sortSpawnPoints( const void *ptr1, const void *ptr2 ); + + void DumpOggSounds( void ); + void GetShakeSounds( const idDict *dict ); + void SelectTimeGroup( int timeGroup ); + int GetTimeGroupTime( int timeGroup ); + void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ); + + void Tokenize( idStrList &out, const char *in ); + + void UpdateLagometer( int aheadOfServer, int dupeUsercmds ); + + void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ); + + // Sets the video CVARs according to the settings in the given GUI + void UpdateScreenResolutionFromGUI(idUserInterface* gui); + + // Splits the given string and stores the found video materials in the target list. + // Calculates the length of the ROQ videos as defined in the string (each material + // is separated by a semicolon) Returns the total length in milliseconds, or -1 on failure. + // The lengthStr corresponds to the videosStr, but contains the lengths of the clips + static int LoadVideosFromString(const char* videosStr, const char* lengthStr, + idList& targetList); + + // Platform-specific implementation to change the D3's title and icon + void ChangeWindowTitleAndIcon(); +}; + +//============================================================================ + +extern idGameLocal gameLocal; +extern idAnimManager animationLib; + +//============================================================================ + +template< class type > +ID_INLINE idEntityPtr::idEntityPtr() { + spawnId = 0; +} + +template< class type > +ID_INLINE void idEntityPtr::Save( idSaveGame *savefile ) const { + savefile->WriteInt( spawnId ); +} + +template< class type > +ID_INLINE void idEntityPtr::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( spawnId ); +} + +template< class type > +ID_INLINE idEntityPtr &idEntityPtr::operator=( type *ent ) { + if ( ent == NULL ) { + spawnId = 0; + } else { + spawnId = ( gameLocal.spawnIds[ent->entityNumber] << GENTITYNUM_BITS ) | ent->entityNumber; + } + return *this; +} + +template< class type > +ID_INLINE bool idEntityPtr::operator==(const idEntityPtr& other) const +{ + return spawnId == other.spawnId; +} + +template< class type > +ID_INLINE bool idEntityPtr::SetSpawnId( int id ) { + // the reason for this first check is unclear: + // the function returning false may mean the spawnId is already set right, or the entity is missing + if ( id == spawnId ) { + return false; + } + if ( ( id >> GENTITYNUM_BITS ) == gameLocal.spawnIds[ id & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) { + spawnId = id; + return true; + } + return false; +} + +template< class type > +ID_INLINE bool idEntityPtr::IsValid( void ) const { + return ( gameLocal.spawnIds[ spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] == ( spawnId >> GENTITYNUM_BITS ) ); +} + +template< class type > +ID_INLINE type *idEntityPtr::GetEntity( void ) const { + int entityNum = spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ); + if ( ( gameLocal.spawnIds[ entityNum ] == ( spawnId >> GENTITYNUM_BITS ) ) ) { + return static_cast( gameLocal.entities[ entityNum ] ); + } + return NULL; +} + +template< class type > +ID_INLINE int idEntityPtr::GetEntityNum( void ) const { + return ( spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ); +} + +//============================================================================ + +class idGameError : public idException { +public: + idGameError( const char *text ) : idException( text ) {} +}; + +//============================================================================ + + +// +// these defines work for all startsounds from all entity types +// make sure to change script/tdm_defs.script if you add any channels, or change their order +// +typedef enum { + SND_CHANNEL_ANY = SCHANNEL_ANY, + SND_CHANNEL_VOICE = SCHANNEL_ONE, + SND_CHANNEL_VOICE2, + SND_CHANNEL_BODY, + SND_CHANNEL_BODY2, + SND_CHANNEL_BODY3, + SND_CHANNEL_WEAPON, + SND_CHANNEL_ITEM, + SND_CHANNEL_HEART, + SND_CHANNEL_UNUSED, + SND_CHANNEL_DEMONIC, + SND_CHANNEL_UNUSED_2, + + // internal use only. not exposed to script or framecommands. + // tels: Have now been exposed to script and framecommands. Why were they internal only? + SND_CHANNEL_AMBIENT, + SND_CHANNEL_DAMAGE +} gameSoundChannel_t; + +// content masks +#define MASK_ALL (-1) +#define MASK_SOLID (CONTENTS_SOLID) +#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_BODY) +#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY) +#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP) +#define MASK_WATER (CONTENTS_WATER) +#define MASK_OPAQUE (CONTENTS_OPAQUE) +#define MASK_SHOT_RENDERMODEL (CONTENTS_SOLID|CONTENTS_RENDERMODEL) +#define MASK_SHOT_BOUNDINGBOX (CONTENTS_SOLID|CONTENTS_BODY) + +const float DEFAULT_GRAVITY = 1066.0f; +#define DEFAULT_GRAVITY_STRING "1066" +const idVec3 DEFAULT_GRAVITY_VEC3( 0, 0, -DEFAULT_GRAVITY ); + +const int CINEMATIC_SKIP_DELAY = SEC2MS( 2.0f ); + +//============================================================================ + +#include "physics/Force.h" +#include "physics/Force_Constant.h" +#include "physics/Force_Drag.h" +#include "physics/Force_Field.h" +#include "physics/Force_Spring.h" +#include "physics/Physics.h" +#include "physics/Physics_Static.h" +#include "physics/Physics_StaticMulti.h" +#include "physics/Physics_Base.h" +#include "physics/Physics_Actor.h" +#include "physics/Physics_Monster.h" +#include "physics/Physics_Player.h" +#include "physics/Physics_Parametric.h" +#include "physics/Physics_RigidBody.h" +#include "physics/Physics_AF.h" +#include "physics/Physics_Liquid.h" + +#include "SmokeParticles.h" + +#include "Entity.h" +#include "GameEdit.h" +#include "AF.h" +#include "IK.h" +#include "AFEntity.h" +#include "Misc.h" +#include "Actor.h" +#include "Projectile.h" +#include "Weapon.h" +#include "Light.h" +#include "WorldSpawn.h" +#include "Item.h" +#include "PlayerView.h" +#include "PlayerIcon.h" +#include "Player.h" +#include "Mover.h" +#include "Camera.h" +#include "Moveable.h" +#include "Target.h" +#include "Trigger.h" +#include "Sound.h" +#include "FX.h" +#include "SecurityCamera.h" +#include "BrittleFracture.h" +#include "Liquid.h" + +#include "ai/AI.h" +#include "anim/Anim_Testmodel.h" + +#include "script/Script_Compiler.h" +#include "script/Script_Interpreter.h" +#include "script/Script_Thread.h" + +const float RB_VELOCITY_MAX = 16000; +const int RB_VELOCITY_TOTAL_BITS = 16; +const int RB_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_VELOCITY_MAX ) ) + 1; +const int RB_VELOCITY_MANTISSA_BITS = RB_VELOCITY_TOTAL_BITS - 1 - RB_VELOCITY_EXPONENT_BITS; +const float RB_MOMENTUM_MAX = 1e20f; +const int RB_MOMENTUM_TOTAL_BITS = 16; +const int RB_MOMENTUM_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_MOMENTUM_MAX ) ) + 1; +const int RB_MOMENTUM_MANTISSA_BITS = RB_MOMENTUM_TOTAL_BITS - 1 - RB_MOMENTUM_EXPONENT_BITS; +const float RB_FORCE_MAX = 1e20f; +const int RB_FORCE_TOTAL_BITS = 16; +const int RB_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_FORCE_MAX ) ) + 1; +const int RB_FORCE_MANTISSA_BITS = RB_FORCE_TOTAL_BITS - 1 - RB_FORCE_EXPONENT_BITS; + +#endif /* !__GAME_LOCAL_H__ */ diff --git a/game/Game_network.cpp b/game/Game_network.cpp new file mode 100644 index 000000000..747102a6f --- /dev/null +++ b/game/Game_network.cpp @@ -0,0 +1,1758 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +=============================================================================== + + Client running game code: + - entity events don't work and should not be issued + - entities should never be spawned outside idGameLocal::ClientReadSnapshot + +=============================================================================== +*/ + +// adds tags to the network protocol to detect when things go bad ( internal consistency ) +// NOTE: this changes the network protocol +#ifndef ASYNC_WRITE_TAGS + #define ASYNC_WRITE_TAGS 0 +#endif + +idCVar net_clientShowSnapshot( "net_clientShowSnapshot", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar net_clientShowSnapshotRadius( "net_clientShowSnapshotRadius", "128", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar net_clientSmoothing( "net_clientSmoothing", "0.8", CVAR_GAME | CVAR_FLOAT, "smooth other clients angles and position.", 0.0f, 0.95f ); +idCVar net_clientSelfSmoothing( "net_clientSelfSmoothing", "0.6", CVAR_GAME | CVAR_FLOAT, "smooth self position if network causes prediction error.", 0.0f, 0.95f ); +idCVar net_clientMaxPrediction( "net_clientMaxPrediction", "1000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of milliseconds a client can predict ahead of server." ); +idCVar net_clientLagOMeter( "net_clientLagOMeter", "1", CVAR_GAME | CVAR_BOOL | CVAR_NOCHEAT | CVAR_ARCHIVE, "draw prediction graph" ); + +/* +================ +idGameLocal::InitAsyncNetwork +================ +*/ +void idGameLocal::InitAsyncNetwork( void ) { + int i, type; + + for ( i = 0; i < MAX_CLIENTS; i++ ) { + for ( type = 0; type < declManager->GetNumDeclTypes(); type++ ) { + clientDeclRemap[i][type].Clear(); + } + } + + memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); + memset( clientPVS, 0, sizeof( clientPVS ) ); + memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); + + eventQueue.Init(); + savedEventQueue.Init(); + + entityDefBits = -( idMath::BitsForInteger( declManager->GetNumDecls( DECL_ENTITYDEF ) ) + 1 ); + localClientNum = 0; // on a listen server SetLocalUser will set this right + realClientTime = 0; + isNewFrame = true; + clientSmoothing = net_clientSmoothing.GetFloat(); +} + +/* +================ +idGameLocal::ShutdownAsyncNetwork +================ +*/ +void idGameLocal::ShutdownAsyncNetwork( void ) { + entityStateAllocator.Shutdown(); + snapshotAllocator.Shutdown(); + eventQueue.Shutdown(); + savedEventQueue.Shutdown(); + memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); + memset( clientPVS, 0, sizeof( clientPVS ) ); + memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); +} + +/* +================ +idGameLocal::InitLocalClient +================ +*/ +void idGameLocal::InitLocalClient( int clientNum ) { + isServer = false; + isClient = true; + localClientNum = clientNum; + clientSmoothing = net_clientSmoothing.GetFloat(); +} + +/* +================ +idGameLocal::InitClientDeclRemap +================ +*/ +void idGameLocal::InitClientDeclRemap( int clientNum ) { + int type, i, num; + + for ( type = 0; type < declManager->GetNumDeclTypes(); type++ ) { + + // only implicit materials and sound shaders decls are used + if ( type != DECL_MATERIAL && type != DECL_SOUND ) { + continue; + } + + num = declManager->GetNumDecls( (declType_t) type ); + clientDeclRemap[clientNum][type].Clear(); + clientDeclRemap[clientNum][type].AssureSize( num, -1 ); + + // pre-initialize the remap with non-implicit decls, all non-implicit decls are always going + // to be in order and in sync between server and client because of the decl manager checksum + for ( i = 0; i < num; i++ ) { + const idDecl *decl = declManager->DeclByIndex( (declType_t) type, i, false ); + if ( decl->IsImplicit() ) { + // once the first implicit decl is found all remaining decls are considered implicit as well + break; + } + clientDeclRemap[clientNum][type][i] = i; + } + } +} + +/* +================ +idGameLocal::ServerSendDeclRemapToClient +================ +*/ +void idGameLocal::ServerSendDeclRemapToClient( int clientNum, declType_t type, int index ) { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + // if no client connected for this spot + if ( entities[clientNum] == NULL ) { + return; + } + // increase size of list if required + if ( index >= clientDeclRemap[clientNum][type].Num() ) { + clientDeclRemap[clientNum][(int)type].AssureSize( index + 1, -1 ); + } + // if already remapped + if ( clientDeclRemap[clientNum][(int)type][index] != -1 ) { + return; + } + + const idDecl *decl = declManager->DeclByIndex( type, index, false ); + if ( decl == NULL ) { + gameLocal.Error( "server tried to remap bad %s decl index %d", declManager->GetDeclNameFromType( type ), index ); + return; + } + + // set the index at the server + clientDeclRemap[clientNum][(int)type][index] = index; + + // write update to client + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_REMAP_DECL ); + outMsg.WriteByte( type ); + outMsg.WriteLong( index ); + outMsg.WriteString( decl->GetName() ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); +} + +/* +================ +idGameLocal::ServerRemapDecl +================ +*/ +int idGameLocal::ServerRemapDecl( int clientNum, declType_t type, int index ) { + + // only implicit materials and sound shaders decls are used + if ( type != DECL_MATERIAL && type != DECL_SOUND ) { + return index; + } + + if ( clientNum == -1 ) { + for ( int i = 0; i < MAX_CLIENTS; i++ ) { + ServerSendDeclRemapToClient( i, type, index ); + } + } else { + ServerSendDeclRemapToClient( clientNum, type, index ); + } + return index; +} + +/* +================ +idGameLocal::ClientRemapDecl +================ +*/ +int idGameLocal::ClientRemapDecl( declType_t type, int index ) { + + // only implicit materials and sound shaders decls are used + if ( type != DECL_MATERIAL && type != DECL_SOUND ) { + return index; + } + + // negative indexes are sometimes used for NULL decls + if ( index < 0 ) { + return index; + } + + // make sure the index is valid + if ( clientDeclRemap[localClientNum][(int)type].Num() == 0 ) { + gameLocal.Error( "client received decl index %d before %s decl remap was initialized", index, declManager->GetDeclNameFromType( type ) ); + return -1; + } + if ( index >= clientDeclRemap[localClientNum][(int)type].Num() ) { + gameLocal.Error( "client received unmapped %s decl index %d from server", declManager->GetDeclNameFromType( type ), index ); + return -1; + } + if ( clientDeclRemap[localClientNum][(int)type][index] == -1 ) { + gameLocal.Error( "client received unmapped %s decl index %d from server", declManager->GetDeclNameFromType( type ), index ); + return -1; + } + return clientDeclRemap[localClientNum][type][index]; +} + +/* +================ +idGameLocal::ServerAllowClient +================ +*/ +allowReply_t idGameLocal::ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[ MAX_STRING_CHARS ] ) { + reason[0] = '\0'; + + if ( serverInfo.GetInt( "si_pure" ) && !mpGame.IsPureReady() ) { + idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07139" ); + return ALLOW_NOTYET; + } + + if ( !serverInfo.GetInt( "si_maxPlayers" ) ) { + idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07140" ); + return ALLOW_NOTYET; + } + + if ( numClients >= serverInfo.GetInt( "si_maxPlayers" ) ) { + idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07141" ); + return ALLOW_NOTYET; + } + + if ( !cvarSystem->GetCVarBool( "si_usepass" ) ) { + return ALLOW_YES; + } + + const char *pass = cvarSystem->GetCVarString( "g_password" ); + if ( pass[ 0 ] == '\0' ) { + common->Warning( "si_usepass is set but g_password is empty" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "say si_usepass is set but g_password is empty" ); + // avoids silent misconfigured state + idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07142" ); + return ALLOW_NOTYET; + } + + if ( !idStr::Cmp( pass, password ) ) { + return ALLOW_YES; + } + + idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07143" ); + Printf( "Rejecting client %s from IP %s: invalid password\n", guid, IP ); + return ALLOW_BADPASS; +} + +/* +================ +idGameLocal::ServerClientConnect +================ +*/ +void idGameLocal::ServerClientConnect( int clientNum, const char *guid ) { + // make sure no parasite entity is left + if ( entities[ clientNum ] ) { + common->DPrintf( "ServerClientConnect: remove old player entity\n" ); + delete entities[ clientNum ]; + } + userInfo[ clientNum ].Clear(); + mpGame.ServerClientConnect( clientNum ); + Printf( "client %d connected.\n", clientNum ); +} + +/* +================ +idGameLocal::ServerClientBegin +================ +*/ +void idGameLocal::ServerClientBegin( int clientNum ) { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + // initialize the decl remap + InitClientDeclRemap( clientNum ); + + // send message to initialize decl remap at the client (this is always the very first reliable game message) + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + + // spawn the player + SpawnPlayer( clientNum ); + if ( clientNum == localClientNum ) { + mpGame.EnterGame( clientNum ); + } + + // send message to spawn the player at the clients + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SPAWN_PLAYER ); + outMsg.WriteByte( clientNum ); + outMsg.WriteLong( spawnIds[ clientNum ] ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); +} + +/* +================ +idGameLocal::ServerClientDisconnect +================ +*/ +void idGameLocal::ServerClientDisconnect( int clientNum ) { + int i; + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DELETE_ENT ); + outMsg.WriteBits( ( spawnIds[ clientNum ] << GENTITYNUM_BITS ) | clientNum, 32 ); // see GetSpawnId + networkSystem->ServerSendReliableMessage( -1, outMsg ); + + // free snapshots stored for this client + FreeSnapshotsOlderThanSequence( clientNum, 0x7FFFFFFF ); + + // free entity states stored for this client + for ( i = 0; i < MAX_GENTITIES; i++ ) { + if ( clientEntityStates[ clientNum ][ i ] ) { + entityStateAllocator.Free( clientEntityStates[ clientNum ][ i ] ); + clientEntityStates[ clientNum ][ i ] = NULL; + } + } + + // clear the client PVS + memset( clientPVS[ clientNum ], 0, sizeof( clientPVS[ clientNum ] ) ); + + // delete the player entity + delete entities[ clientNum ]; + + mpGame.DisconnectClient( clientNum ); + +} + +/* +================ +idGameLocal::ServerWriteInitialReliableMessages + + Send reliable messages to initialize the client game up to a certain initial state. +================ +*/ +void idGameLocal::ServerWriteInitialReliableMessages( int clientNum ) { + int i; + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + entityNetEvent_t *event; + + // spawn players + for ( i = 0; i < MAX_CLIENTS; i++ ) { + if ( entities[i] == NULL || i == clientNum ) { + continue; + } + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting( ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SPAWN_PLAYER ); + outMsg.WriteByte( i ); + outMsg.WriteLong( spawnIds[ i ] ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + } + + // send all saved events + for ( event = savedEventQueue.Start(); event; event = event->next ) { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); + outMsg.WriteBits( event->spawnId, 32 ); + outMsg.WriteByte( event->event ); + outMsg.WriteLong( event->time ); + outMsg.WriteBits( event->paramsSize, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + if ( event->paramsSize ) { + outMsg.WriteData( event->paramsBuf, event->paramsSize ); + } + + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + } + + // update portals for opened doors + int numPortals = gameRenderWorld->NumPortals(); + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_PORTALSTATES ); + outMsg.WriteLong( numPortals ); + for ( i = 0; i < numPortals; i++ ) { + outMsg.WriteBits( gameRenderWorld->GetPortalState( (qhandle_t) (i+1) ) , NUM_RENDER_PORTAL_BITS ); + } + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + + mpGame.ServerWriteInitialReliableMessages( clientNum ); +} + +/* +================ +idGameLocal::SaveEntityNetworkEvent +================ +*/ +void idGameLocal::SaveEntityNetworkEvent( const idEntity *ent, int eventId, const idBitMsg *msg ) { + entityNetEvent_t *event; + + event = savedEventQueue.Alloc(); + event->spawnId = GetSpawnId( ent ); + event->event = eventId; + event->time = time; + if ( msg ) { + event->paramsSize = msg->GetSize(); + memcpy( event->paramsBuf, msg->GetData(), msg->GetSize() ); + } else { + event->paramsSize = 0; + } + + savedEventQueue.Enqueue( event, idEventQueue::OUTOFORDER_IGNORE ); +} + +/* +================ +idGameLocal::FreeSnapshotsOlderThanSequence +================ +*/ +void idGameLocal::FreeSnapshotsOlderThanSequence( int clientNum, int sequence ) { + snapshot_t *snapshot, *lastSnapshot, *nextSnapshot; + entityState_t *state; + + for ( lastSnapshot = NULL, snapshot = clientSnapshots[clientNum]; snapshot; snapshot = nextSnapshot ) { + nextSnapshot = snapshot->next; + if ( snapshot->sequence < sequence ) { + for ( state = snapshot->firstEntityState; state; state = snapshot->firstEntityState ) { + snapshot->firstEntityState = snapshot->firstEntityState->next; + entityStateAllocator.Free( state ); + } + if ( lastSnapshot ) { + lastSnapshot->next = snapshot->next; + } else { + clientSnapshots[clientNum] = snapshot->next; + } + snapshotAllocator.Free( snapshot ); + } else { + lastSnapshot = snapshot; + } + } +} + +/* +================ +idGameLocal::ApplySnapshot +================ +*/ +bool idGameLocal::ApplySnapshot( int clientNum, int sequence ) { + snapshot_t *snapshot, *lastSnapshot, *nextSnapshot; + entityState_t *state; + + FreeSnapshotsOlderThanSequence( clientNum, sequence ); + + for ( lastSnapshot = NULL, snapshot = clientSnapshots[clientNum]; snapshot; snapshot = nextSnapshot ) { + nextSnapshot = snapshot->next; + if ( snapshot->sequence == sequence ) { + for ( state = snapshot->firstEntityState; state; state = state->next ) { + if ( clientEntityStates[clientNum][state->entityNumber] ) { + entityStateAllocator.Free( clientEntityStates[clientNum][state->entityNumber] ); + } + clientEntityStates[clientNum][state->entityNumber] = state; + } + memcpy( clientPVS[clientNum], snapshot->pvs, sizeof( snapshot->pvs ) ); + if ( lastSnapshot ) { + lastSnapshot->next = nextSnapshot; + } else { + clientSnapshots[clientNum] = nextSnapshot; + } + snapshotAllocator.Free( snapshot ); + return true; + } else { + lastSnapshot = snapshot; + } + } + + return false; +} + +/* +================ +idGameLocal::WriteGameStateToSnapshot +================ +*/ +void idGameLocal::WriteGameStateToSnapshot( idBitMsgDelta &msg ) const { + int i; + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + msg.WriteFloat( globalShaderParms[i] ); + } + + mpGame.WriteToSnapshot( msg ); +} + +/* +================ +idGameLocal::ReadGameStateFromSnapshot +================ +*/ +void idGameLocal::ReadGameStateFromSnapshot( const idBitMsgDelta &msg ) { + int i; + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + globalShaderParms[i] = msg.ReadFloat(); + } + + mpGame.ReadFromSnapshot( msg ); +} + +/* +================ +idGameLocal::ServerWriteSnapshot + + Write a snapshot of the current game state for the given client. +================ +*/ +void idGameLocal::ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ) { + int i, msgSize, msgWriteBit; + idPlayer *player, *spectated = NULL; + idEntity *ent; + pvsHandle_t pvsHandle; + idBitMsgDelta deltaMsg; + snapshot_t *snapshot; + entityState_t *base, *newBase; + int numSourceAreas, sourceAreas[ idEntity::MAX_PVS_AREAS ]; + + player = static_cast( entities[ clientNum ] ); + if ( !player ) { + return; + } + if ( player->spectating && player->spectator != clientNum && entities[ player->spectator ] ) { + spectated = static_cast< idPlayer * >( entities[ player->spectator ] ); + } else { + spectated = player; + } + + // free too old snapshots + FreeSnapshotsOlderThanSequence( clientNum, sequence - 64 ); + + // allocate new snapshot + snapshot = snapshotAllocator.Alloc(); + snapshot->sequence = sequence; + snapshot->firstEntityState = NULL; + snapshot->next = clientSnapshots[clientNum]; + clientSnapshots[clientNum] = snapshot; + memset( snapshot->pvs, 0, sizeof( snapshot->pvs ) ); + + // get PVS for this player + // don't use PVSAreas for networking - PVSAreas depends on animations (and md5 bounds), which are not synchronized + numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS ); + pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL ); + + // Add portalSky areas to PVS + if ( portalSkyEnt.GetEntity() ) { + pvsHandle_t otherPVS, newPVS; + idEntity *skyEnt = portalSkyEnt.GetEntity(); + + otherPVS = gameLocal.pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); + newPVS = gameLocal.pvs.MergeCurrentPVS( pvsHandle, otherPVS ); + pvs.FreeCurrentPVS( pvsHandle ); + pvs.FreeCurrentPVS( otherPVS ); + pvsHandle = newPVS; + } + +#if ASYNC_WRITE_TAGS + idRandom tagRandom; + tagRandom.SetSeed( random.RandomInt() ); + msg.WriteLong( tagRandom.GetSeed() ); +#endif + + // create the snapshot + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + + // if the entity is not in the player PVS + if ( !ent->PhysicsTeamInPVS( pvsHandle ) && ent->entityNumber != clientNum ) { + continue; + } + + // add the entity to the snapshot pvs + snapshot->pvs[ ent->entityNumber >> 5 ] |= 1 << ( ent->entityNumber & 31 ); + + // if that entity is not marked for network synchronization + if ( !ent->fl.networkSync ) { + continue; + } + + // save the write state to which we can revert when the entity didn't change at all + msg.SaveWriteState( msgSize, msgWriteBit ); + + // write the entity to the snapshot + msg.WriteBits( ent->entityNumber, GENTITYNUM_BITS ); + + base = clientEntityStates[clientNum][ent->entityNumber]; + if ( base ) { + base->state.BeginReading(); + } + newBase = entityStateAllocator.Alloc(); + newBase->entityNumber = ent->entityNumber; + newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); + newBase->state.BeginWriting(); + + deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); + + deltaMsg.WriteBits( spawnIds[ ent->entityNumber ], 32 - GENTITYNUM_BITS ); + deltaMsg.WriteBits( ent->GetType()->typeNum, idClass::GetTypeNumBits() ); + deltaMsg.WriteBits( ServerRemapDecl( -1, DECL_ENTITYDEF, ent->entityDefNumber ), entityDefBits ); + + // write the class specific data to the snapshot + ent->WriteToSnapshot( deltaMsg ); + + if ( !deltaMsg.HasChanged() ) { + msg.RestoreWriteState( msgSize, msgWriteBit ); + entityStateAllocator.Free( newBase ); + } else { + newBase->next = snapshot->firstEntityState; + snapshot->firstEntityState = newBase; + +#if ASYNC_WRITE_TAGS + msg.WriteLong( tagRandom.RandomInt() ); +#endif + } + } + + msg.WriteBits( ENTITYNUM_NONE, GENTITYNUM_BITS ); + + // write the PVS to the snapshot +#if ASYNC_WRITE_PVS + for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { + if ( i < numSourceAreas ) { + msg.WriteLong( sourceAreas[ i ] ); + } else { + msg.WriteLong( 0 ); + } + } + gameLocal.pvs.WritePVS( pvsHandle, msg ); +#endif + for ( i = 0; i < ENTITY_PVS_SIZE; i++ ) { + msg.WriteDeltaLong( clientPVS[clientNum][i], snapshot->pvs[i] ); + } + + // free the PVS + pvs.FreeCurrentPVS( pvsHandle ); + + // write the game and player state to the snapshot + base = clientEntityStates[clientNum][ENTITYNUM_NONE]; // ENTITYNUM_NONE is used for the game and player state + if ( base ) { + base->state.BeginReading(); + } + newBase = entityStateAllocator.Alloc(); + newBase->entityNumber = ENTITYNUM_NONE; + newBase->next = snapshot->firstEntityState; + snapshot->firstEntityState = newBase; + newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); + newBase->state.BeginWriting(); + deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); + if ( player->spectating && player->spectator != player->entityNumber && gameLocal.entities[ player->spectator ] && gameLocal.entities[ player->spectator ]->IsType( idPlayer::Type ) ) { + static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->WritePlayerStateToSnapshot( deltaMsg ); + } else { + player->WritePlayerStateToSnapshot( deltaMsg ); + } + WriteGameStateToSnapshot( deltaMsg ); + + // copy the client PVS string + memcpy( clientInPVS, snapshot->pvs, ( numPVSClients + 7 ) >> 3 ); + LittleRevBytes( clientInPVS, sizeof( int ), sizeof( clientInPVS ) / sizeof ( int ) ); +} + +/* +================ +idGameLocal::ServerApplySnapshot +================ +*/ +bool idGameLocal::ServerApplySnapshot( int clientNum, int sequence ) { + return ApplySnapshot( clientNum, sequence ); +} + +/* +================ +idGameLocal::NetworkEventWarning +================ +*/ +void idGameLocal::NetworkEventWarning( const entityNetEvent_t *event, const char *fmt, ... ) { + char buf[1024]; + int length = 0; + va_list argptr; + + int entityNum = event->spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ); + int id = event->spawnId >> GENTITYNUM_BITS; + + length += idStr::snPrintf( buf+length, sizeof(buf)-1-length, "event %d for entity %d %d: ", event->event, entityNum, id ); + va_start( argptr, fmt ); + length = idStr::vsnPrintf( buf+length, sizeof(buf)-1-length, fmt, argptr ); + va_end( argptr ); + idStr::Append( buf, sizeof(buf), "\n" ); + + common->DWarning( buf ); +} + +/* +================ +idGameLocal::ServerProcessEntityNetworkEventQueue +================ +*/ +void idGameLocal::ServerProcessEntityNetworkEventQueue( void ) { + idEntity *ent; + entityNetEvent_t *event; + idBitMsg eventMsg; + + while ( eventQueue.Start() ) { + event = eventQueue.Start(); + + if ( event->time > time ) { + break; + } + + idEntityPtr< idEntity > entPtr; + + if( !entPtr.SetSpawnId( event->spawnId ) ) { + NetworkEventWarning( event, "Entity does not exist any longer, or has not been spawned yet." ); + } else { + ent = entPtr.GetEntity(); + assert( ent ); + + eventMsg.Init( event->paramsBuf, sizeof( event->paramsBuf ) ); + eventMsg.SetSize( event->paramsSize ); + eventMsg.BeginReading(); + if ( !ent->ServerReceiveEvent( event->event, event->time, eventMsg ) ) { + NetworkEventWarning( event, "unknown event" ); + } + } + + entityNetEvent_t* freedEvent = eventQueue.Dequeue(); + assert( freedEvent == event ); + eventQueue.Free( event ); + } +} + +/* +================ +idGameLocal::ServerSendChatMessage +================ +*/ +void idGameLocal::ServerSendChatMessage( int to, const char *name, const char *text ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CHAT ); + outMsg.WriteString( name ); + outMsg.WriteString( text, -1, false ); + networkSystem->ServerSendReliableMessage( to, outMsg ); + + if ( to == -1 || to == localClientNum ) { + mpGame.AddChatLine( "%s^0: %s\n", name, text ); + } +} + +/* +================ +idGameLocal::ServerProcessReliableMessage +================ +*/ +void idGameLocal::ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) { + int id; + + id = msg.ReadByte(); + switch( id ) { + case GAME_RELIABLE_MESSAGE_CHAT: + case GAME_RELIABLE_MESSAGE_TCHAT: { + char name[128]; + char text[128]; + + msg.ReadString( name, sizeof( name ) ); + msg.ReadString( text, sizeof( text ) ); + + mpGame.ProcessChatMessage( clientNum, id == GAME_RELIABLE_MESSAGE_TCHAT, name, text, NULL ); + + break; + } + case GAME_RELIABLE_MESSAGE_VCHAT: { + int index = msg.ReadLong(); + bool team = msg.ReadBits( 1 ) != 0; + mpGame.ProcessVoiceChat( clientNum, team, index ); + break; + } + case GAME_RELIABLE_MESSAGE_KILL: { + mpGame.WantKilled( clientNum ); + break; + } + case GAME_RELIABLE_MESSAGE_DROPWEAPON: { + mpGame.DropWeapon( clientNum ); + break; + } + case GAME_RELIABLE_MESSAGE_CALLVOTE: { + mpGame.ServerCallVote( clientNum, msg ); + break; + } + case GAME_RELIABLE_MESSAGE_CASTVOTE: { + bool vote = ( msg.ReadByte() != 0 ); + mpGame.CastVote( clientNum, vote ); + break; + } +#if 0 + // uncomment this if you want to track when players are in a menu + case GAME_RELIABLE_MESSAGE_MENU: { + bool menuUp = ( msg.ReadBits( 1 ) != 0 ); + break; + } +#endif + case GAME_RELIABLE_MESSAGE_EVENT: { + entityNetEvent_t *event; + + // allocate new event + event = eventQueue.Alloc(); + eventQueue.Enqueue( event, idEventQueue::OUTOFORDER_DROP ); + + event->spawnId = msg.ReadBits( 32 ); + event->event = msg.ReadByte(); + event->time = msg.ReadLong(); + + event->paramsSize = msg.ReadBits( idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + if ( event->paramsSize ) { + if ( event->paramsSize > MAX_EVENT_PARAM_SIZE ) { + NetworkEventWarning( event, "invalid param size" ); + return; + } + msg.ReadByteAlign(); + msg.ReadData( event->paramsBuf, event->paramsSize ); + } + break; + } + default: { + Warning( "Unknown client->server reliable message: %d", id ); + break; + } + } +} + +/* +================ +idGameLocal::ClientShowSnapshot +================ +*/ +void idGameLocal::ClientShowSnapshot( int clientNum ) const { + int baseBits; + idEntity *ent; + idPlayer *player; + idMat3 viewAxis; + idBounds viewBounds; + entityState_t *base; + + if ( !net_clientShowSnapshot.GetInteger() ) { + return; + } + + player = static_cast( entities[clientNum] ); + if ( !player ) { + return; + } + + viewAxis = player->viewAngles.ToMat3(); + viewBounds = player->GetPhysics()->GetAbsBounds().Expand( net_clientShowSnapshotRadius.GetFloat() ); + + for( ent = snapshotEntities.Next(); ent != NULL; ent = ent->snapshotNode.Next() ) { + + if ( net_clientShowSnapshot.GetInteger() == 1 && ent->snapshotBits == 0 ) { + continue; + } + + const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); + + if ( !entBounds.IntersectsBounds( viewBounds ) ) { + continue; + } + + base = clientEntityStates[clientNum][ent->entityNumber]; + if ( base ) { + baseBits = base->state.GetNumBitsWritten(); + } else { + baseBits = 0; + } + + if ( net_clientShowSnapshot.GetInteger() == 2 && baseBits == 0 ) { + continue; + } + + gameRenderWorld->DebugBounds( colorGreen, entBounds ); + gameRenderWorld->DrawText( va( "%d: %s (%d,%d bytes of %d,%d)\n", ent->entityNumber, + ent->name.c_str(), ent->snapshotBits >> 3, ent->snapshotBits & 7, baseBits >> 3, baseBits & 7 ), + entBounds.GetCenter(), 0.1f, colorWhite, viewAxis, 1 ); + } +} + +/* +================ +idGameLocal::UpdateLagometer +================ +*/ +void idGameLocal::UpdateLagometer( int aheadOfServer, int dupeUsercmds ) { + int i, j, ahead; + for ( i = 0; i < LAGO_HEIGHT; i++ ) { + memmove( (byte *)lagometer + LAGO_WIDTH * 4 * i, (byte *)lagometer + LAGO_WIDTH * 4 * i + 4, ( LAGO_WIDTH - 1 ) * 4 ); + } + j = LAGO_WIDTH - 1; + for ( i = 0; i < LAGO_HEIGHT; i++ ) { + lagometer[i][j][0] = lagometer[i][j][1] = lagometer[i][j][2] = lagometer[i][j][3] = 0; + } + ahead = static_cast(idMath::Rint( (float)aheadOfServer / 16.0f )); + if ( ahead >= 0 ) { + for ( i = 2 * Max( 0, 5 - ahead ); i < 2 * 5; i++ ) { + lagometer[i][j][1] = 255; + lagometer[i][j][3] = 255; + } + } else { + for ( i = 2 * 5; i < 2 * ( 5 + Min( 10, -ahead ) ); i++ ) { + lagometer[i][j][0] = 255; + lagometer[i][j][1] = 255; + lagometer[i][j][3] = 255; + } + } + for ( i = LAGO_HEIGHT - 2 * Min( 6, dupeUsercmds ); i < LAGO_HEIGHT; i++ ) { + lagometer[i][j][0] = 255; + if ( dupeUsercmds <= 2 ) { + lagometer[i][j][1] = 255; + } + lagometer[i][j][3] = 255; + } +} + +/* +================ +idGameLocal::ClientReadSnapshot +================ +*/ +void idGameLocal::ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) { + int i, typeNum, entityDefNumber, numBitsRead; + idTypeInfo *typeInfo; + idEntity *ent; + idPlayer *player, *spectated; + pvsHandle_t pvsHandle; + idDict args; + const char *classname; + idBitMsgDelta deltaMsg; + snapshot_t *snapshot; + entityState_t *base, *newBase; + int spawnId; + int numSourceAreas, sourceAreas[ idEntity::MAX_PVS_AREAS ]; + idWeapon *weap; + + if ( net_clientLagOMeter.GetBool() && renderSystem ) { + UpdateLagometer( aheadOfServer, dupeUsercmds ); + if ( !renderSystem->UploadImage( LAGO_IMAGE, (byte *)lagometer, LAGO_IMG_WIDTH, LAGO_IMG_HEIGHT ) ) { + common->Printf( "lagometer: UploadImage failed. turning off net_clientLagOMeter\n" ); + net_clientLagOMeter.SetBool( false ); + } + } + + InitLocalClient( clientNum ); + + // clear any debug lines from a previous frame + gameRenderWorld->DebugClearLines( time ); + + // clear any debug polygons from a previous frame + gameRenderWorld->DebugClearPolygons( time ); + + // update the game time + framenum = gameFrame; + time = gameTime; + previousTime = time - msec; + + // so that StartSound/StopSound doesn't risk skipping + isNewFrame = true; + + // clear the snapshot entity list + snapshotEntities.Clear(); + + // allocate new snapshot + snapshot = snapshotAllocator.Alloc(); + snapshot->sequence = sequence; + snapshot->firstEntityState = NULL; + snapshot->next = clientSnapshots[clientNum]; + clientSnapshots[clientNum] = snapshot; + +#if ASYNC_WRITE_TAGS + idRandom tagRandom; + tagRandom.SetSeed( msg.ReadLong() ); +#endif + + // read all entities from the snapshot + for ( i = msg.ReadBits( GENTITYNUM_BITS ); i != ENTITYNUM_NONE; i = msg.ReadBits( GENTITYNUM_BITS ) ) { + + base = clientEntityStates[clientNum][i]; + if ( base ) { + base->state.BeginReading(); + } + newBase = entityStateAllocator.Alloc(); + newBase->entityNumber = i; + newBase->next = snapshot->firstEntityState; + snapshot->firstEntityState = newBase; + newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); + newBase->state.BeginWriting(); + + numBitsRead = msg.GetNumBitsRead(); + + deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); + + spawnId = deltaMsg.ReadBits( 32 - GENTITYNUM_BITS ); + typeNum = deltaMsg.ReadBits( idClass::GetTypeNumBits() ); + entityDefNumber = ClientRemapDecl( DECL_ENTITYDEF, deltaMsg.ReadBits( entityDefBits ) ); + + typeInfo = idClass::GetType( typeNum ); + if ( !typeInfo ) { + Error( "Unknown type number %d for entity %d with class number %d", typeNum, i, entityDefNumber ); + } + + ent = entities[i]; + + // if there is no entity or an entity of the wrong type + if ( !ent || ent->GetType()->typeNum != typeNum || ent->entityDefNumber != entityDefNumber || spawnId != spawnIds[ i ] ) { + + if ( i < MAX_CLIENTS && ent ) { + // SPAWN_PLAYER should be taking care of spawning the entity with the right spawnId + common->Warning( "ClientReadSnapshot: recycling client entity %d\n", i ); + } + + delete ent; + + spawnCount = spawnId; + + args.Clear(); + args.SetInt( "spawn_entnum", i ); + args.Set( "name", va( "entity%d", i ) ); + + if ( entityDefNumber >= 0 ) { + if ( entityDefNumber >= declManager->GetNumDecls( DECL_ENTITYDEF ) ) { + Error( "server has %d entityDefs instead of %d", entityDefNumber, declManager->GetNumDecls( DECL_ENTITYDEF ) ); + } + classname = declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); + args.Set( "classname", classname ); + if ( !SpawnEntityDef( args, &ent ) || !entities[i] || entities[i]->GetType()->typeNum != typeNum ) { + Error( "Failed to spawn entity with classname '%s' of type '%s'", classname, typeInfo->classname ); + } + } else { + ent = SpawnEntityType( *typeInfo, &args, true ); + if ( !entities[i] || entities[i]->GetType()->typeNum != typeNum ) { + Error( "Failed to spawn entity of type '%s'", typeInfo->classname ); + } + } + if ( i < MAX_CLIENTS && i >= numClients ) { + numClients = i + 1; + } + } + + // add the entity to the snapshot list + ent->snapshotNode.AddToEnd( snapshotEntities ); + ent->snapshotSequence = sequence; + + // read the class specific data from the snapshot + ent->ReadFromSnapshot( deltaMsg ); + + ent->snapshotBits = msg.GetNumBitsRead() - numBitsRead; + +#if ASYNC_WRITE_TAGS + if ( msg.ReadLong() != tagRandom.RandomInt() ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "writeGameState" ); + if ( entityDefNumber >= 0 && entityDefNumber < declManager->GetNumDecls( DECL_ENTITYDEF ) ) { + classname = declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); + Error( "write to and read from snapshot out of sync for classname '%s' of type '%s'", classname, typeInfo->classname ); + } else { + Error( "write to and read from snapshot out of sync for type '%s'", typeInfo->classname ); + } + } +#endif + } + + player = static_cast( entities[clientNum] ); + if ( !player ) { + return; + } + + // if prediction is off, enable local client smoothing + player->SetSelfSmooth( dupeUsercmds > 2 ); + + if ( player->spectating && player->spectator != clientNum && entities[ player->spectator ] ) { + spectated = static_cast< idPlayer * >( entities[ player->spectator ] ); + } else { + spectated = player; + } + + // get PVS for this player + // don't use PVSAreas for networking - PVSAreas depends on animations (and md5 bounds), which are not synchronized + numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS ); + pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL ); + + // read the PVS from the snapshot +#if ASYNC_WRITE_PVS + int serverPVS[idEntity::MAX_PVS_AREAS]; + i = numSourceAreas; + while ( i < idEntity::MAX_PVS_AREAS ) { + sourceAreas[ i++ ] = 0; + } + for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { + serverPVS[ i ] = msg.ReadLong(); + } + if ( memcmp( sourceAreas, serverPVS, idEntity::MAX_PVS_AREAS * sizeof( int ) ) ) { + common->Warning( "client PVS areas != server PVS areas, sequence 0x%x", sequence ); + for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { + common->DPrintf( "%3d ", sourceAreas[ i ] ); + } + common->DPrintf( "\n" ); + for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { + common->DPrintf( "%3d ", serverPVS[ i ] ); + } + common->DPrintf( "\n" ); + } + gameLocal.pvs.ReadPVS( pvsHandle, msg ); +#endif + for ( i = 0; i < ENTITY_PVS_SIZE; i++ ) { + snapshot->pvs[i] = msg.ReadDeltaLong( clientPVS[clientNum][i] ); + } + + // add entities in the PVS that haven't changed since the last applied snapshot + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + + // if the entity is already in the snapshot + if ( ent->snapshotSequence == sequence ) { + continue; + } + + // if the entity is not in the snapshot PVS + if ( !( snapshot->pvs[ent->entityNumber >> 5] & ( 1 << ( ent->entityNumber & 31 ) ) ) ) { + if ( ent->PhysicsTeamInPVS( pvsHandle ) ) { + if ( ent->entityNumber >= MAX_CLIENTS && ent->entityNumber < mapSpawnCount ) { + // server says it's not in PVS, client says it's in PVS + // if that happens on map entities, most likely something is wrong + // I can see that moving pieces along several PVS could be a legit situation though + // this is a band aid, which means something is not done right elsewhere + common->DWarning( "client thinks map entity 0x%x (%s) is stale, sequence 0x%x", ent->entityNumber, ent->name.c_str(), sequence ); + } else { + ent->FreeModelDef(); + ent->UpdateVisuals(); + ent->GetPhysics()->UnlinkClip(); + } + } + continue; + } + + // add the entity to the snapshot list + ent->snapshotNode.AddToEnd( snapshotEntities ); + ent->snapshotSequence = sequence; + ent->snapshotBits = 0; + + base = clientEntityStates[clientNum][ent->entityNumber]; + if ( !base ) { + // entity has probably fl.networkSync set to false + continue; + } + + base->state.BeginReading(); + + deltaMsg.Init( &base->state, NULL, (const idBitMsg *)NULL ); + + spawnId = deltaMsg.ReadBits( 32 - GENTITYNUM_BITS ); + typeNum = deltaMsg.ReadBits( idClass::GetTypeNumBits() ); + entityDefNumber = deltaMsg.ReadBits( entityDefBits ); + + typeInfo = idClass::GetType( typeNum ); + + // if the entity is not the right type + if ( !typeInfo || ent->GetType()->typeNum != typeNum || ent->entityDefNumber != entityDefNumber ) { + // should never happen - it does though. with != entityDefNumber only? + common->DWarning( "entity '%s' is not the right type %p 0x%d 0x%x 0x%x 0x%x", ent->GetName(), typeInfo, ent->GetType()->typeNum, typeNum, ent->entityDefNumber, entityDefNumber ); + continue; + } + + // read the class specific data from the base state + ent->ReadFromSnapshot( deltaMsg ); + } + + // free the PVS + pvs.FreeCurrentPVS( pvsHandle ); + + // read the game and player state from the snapshot + base = clientEntityStates[clientNum][ENTITYNUM_NONE]; // ENTITYNUM_NONE is used for the game and player state + if ( base ) { + base->state.BeginReading(); + } + newBase = entityStateAllocator.Alloc(); + newBase->entityNumber = ENTITYNUM_NONE; + newBase->next = snapshot->firstEntityState; + snapshot->firstEntityState = newBase; + newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); + newBase->state.BeginWriting(); + deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); + if ( player->spectating && player->spectator != player->entityNumber && gameLocal.entities[ player->spectator ] && gameLocal.entities[ player->spectator ]->IsType( idPlayer::Type ) ) { + static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->ReadPlayerStateFromSnapshot( deltaMsg ); + weap = static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->weapon.GetEntity(); + if ( weap && ( weap->GetRenderEntity()->bounds[0] == weap->GetRenderEntity()->bounds[1] ) ) { + // update the weapon's viewmodel bounds so that the model doesn't flicker in the spectator's view + weap->GetAnimator()->GetBounds( gameLocal.time, weap->GetRenderEntity()->bounds ); + weap->UpdateVisuals(); + } + } else { + player->ReadPlayerStateFromSnapshot( deltaMsg ); + } + ReadGameStateFromSnapshot( deltaMsg ); + + // visualize the snapshot + ClientShowSnapshot( clientNum ); + + // process entity events + ClientProcessEntityNetworkEventQueue(); +} + +/* +================ +idGameLocal::ClientApplySnapshot +================ +*/ +bool idGameLocal::ClientApplySnapshot( int clientNum, int sequence ) { + return ApplySnapshot( clientNum, sequence ); +} + +/* +================ +idGameLocal::ClientProcessEntityNetworkEventQueue +================ +*/ +void idGameLocal::ClientProcessEntityNetworkEventQueue( void ) { + idEntity *ent; + entityNetEvent_t *event; + idBitMsg eventMsg; + + while( eventQueue.Start() ) { + event = eventQueue.Start(); + + // only process forward, in order + if ( event->time > time ) { + break; + } + + idEntityPtr< idEntity > entPtr; + + if( !entPtr.SetSpawnId( event->spawnId ) ) { + if( !gameLocal.entities[ event->spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) { + // if new entity exists in this position, silently ignore + NetworkEventWarning( event, "Entity does not exist any longer, or has not been spawned yet." ); + } + } else { + ent = entPtr.GetEntity(); + assert( ent ); + + eventMsg.Init( event->paramsBuf, sizeof( event->paramsBuf ) ); + eventMsg.SetSize( event->paramsSize ); + eventMsg.BeginReading(); + if ( !ent->ClientReceiveEvent( event->event, event->time, eventMsg ) ) { + NetworkEventWarning( event, "unknown event" ); + } + } + + entityNetEvent_t* freedEvent = eventQueue.Dequeue(); + assert( freedEvent == event ); + eventQueue.Free( event ); + } +} + +/* +================ +idGameLocal::ClientProcessReliableMessage +================ +*/ +void idGameLocal::ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) { + int id, line; + idPlayer *p; + idDict backupSI; + + InitLocalClient( clientNum ); + + id = msg.ReadByte(); + switch( id ) { + case GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP: { + InitClientDeclRemap( clientNum ); + break; + } + case GAME_RELIABLE_MESSAGE_REMAP_DECL: { + int type, index; + char name[MAX_STRING_CHARS]; + + type = msg.ReadByte(); + index = msg.ReadLong(); + msg.ReadString( name, sizeof( name ) ); + + const idDecl *decl = declManager->FindType( (declType_t)type, name, false ); + if ( decl != NULL ) { + if ( index >= clientDeclRemap[clientNum][type].Num() ) { + clientDeclRemap[clientNum][type].AssureSize( index + 1, -1 ); + } + clientDeclRemap[clientNum][type][index] = decl->Index(); + } + break; + } + case GAME_RELIABLE_MESSAGE_SPAWN_PLAYER: { + int client = msg.ReadByte(); + int spawnId = msg.ReadLong(); + if ( !entities[ client ] ) { + SpawnPlayer( client ); + entities[ client ]->FreeModelDef(); + } + // fix up the spawnId to match what the server says + // otherwise there is going to be a bogus delete/new of the client entity in the first ClientReadFromSnapshot + spawnIds[ client ] = spawnId; + break; + } + case GAME_RELIABLE_MESSAGE_DELETE_ENT: { + int spawnId = msg.ReadBits( 32 ); + idEntityPtr< idEntity > entPtr; + if( !entPtr.SetSpawnId( spawnId ) ) { + break; + } + delete entPtr.GetEntity(); + break; + } + case GAME_RELIABLE_MESSAGE_CHAT: + case GAME_RELIABLE_MESSAGE_TCHAT: { // (client should never get a TCHAT though) + char name[128]; + char text[128]; + msg.ReadString( name, sizeof( name ) ); + msg.ReadString( text, sizeof( text ) ); + mpGame.AddChatLine( "%s^0: %s\n", name, text ); + break; + } + case GAME_RELIABLE_MESSAGE_SOUND_EVENT: { + snd_evt_t snd_evt = (snd_evt_t)msg.ReadByte(); + mpGame.PlayGlobalSound( -1, snd_evt ); + break; + } + case GAME_RELIABLE_MESSAGE_SOUND_INDEX: { + int index = gameLocal.ClientRemapDecl( DECL_SOUND, msg.ReadLong() ); + if ( index >= 0 && index < declManager->GetNumDecls( DECL_SOUND ) ) { + const idSoundShader *shader = declManager->SoundByIndex( index ); + mpGame.PlayGlobalSound( -1, SND_COUNT, shader->GetName() ); + } + break; + } + case GAME_RELIABLE_MESSAGE_DB: { + idMultiplayerGame::msg_evt_t msg_evt = (idMultiplayerGame::msg_evt_t)msg.ReadByte(); + int parm1, parm2; + parm1 = msg.ReadByte( ); + parm2 = msg.ReadByte( ); + mpGame.PrintMessageEvent( -1, msg_evt, parm1, parm2 ); + break; + } + case GAME_RELIABLE_MESSAGE_EVENT: { + entityNetEvent_t *event; + + // allocate new event + event = eventQueue.Alloc(); + eventQueue.Enqueue( event, idEventQueue::OUTOFORDER_IGNORE ); + + event->spawnId = msg.ReadBits( 32 ); + event->event = msg.ReadByte(); + event->time = msg.ReadLong(); + + event->paramsSize = msg.ReadBits( idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); + if ( event->paramsSize ) { + if ( event->paramsSize > MAX_EVENT_PARAM_SIZE ) { + NetworkEventWarning( event, "invalid param size" ); + return; + } + msg.ReadByteAlign(); + msg.ReadData( event->paramsBuf, event->paramsSize ); + } + break; + } + case GAME_RELIABLE_MESSAGE_SERVERINFO: { + idDict info; + msg.ReadDeltaDict( info, NULL ); + gameLocal.SetServerInfo( info ); + break; + } + case GAME_RELIABLE_MESSAGE_RESTART: { + MapRestart(); + break; + } + case GAME_RELIABLE_MESSAGE_TOURNEYLINE: { + line = msg.ReadByte( ); + p = static_cast< idPlayer * >( entities[ clientNum ] ); + if ( !p ) { + break; + } + p->tourneyLine = line; + break; + } + case GAME_RELIABLE_MESSAGE_STARTVOTE: { + char voteString[ MAX_STRING_CHARS ]; + int clientNum = msg.ReadByte( ); + msg.ReadString( voteString, sizeof( voteString ) ); + mpGame.ClientStartVote( clientNum, voteString ); + break; + } + case GAME_RELIABLE_MESSAGE_UPDATEVOTE: { + int result = msg.ReadByte( ); + int yesCount = msg.ReadByte( ); + int noCount = msg.ReadByte( ); + mpGame.ClientUpdateVote( (idMultiplayerGame::vote_result_t)result, yesCount, noCount ); + break; + } + case GAME_RELIABLE_MESSAGE_PORTALSTATES: { + int numPortals = msg.ReadLong(); + assert( numPortals == gameRenderWorld->NumPortals() ); + for ( int i = 0; i < numPortals; i++ ) { + gameRenderWorld->SetPortalState( (qhandle_t) (i+1), msg.ReadBits( NUM_RENDER_PORTAL_BITS ) ); + } + break; + } + case GAME_RELIABLE_MESSAGE_PORTAL: { + qhandle_t portal = msg.ReadLong(); + int blockingBits = msg.ReadBits( NUM_RENDER_PORTAL_BITS ); + assert( portal > 0 && portal <= gameRenderWorld->NumPortals() ); + gameRenderWorld->SetPortalState( portal, blockingBits ); + break; + } + case GAME_RELIABLE_MESSAGE_STARTSTATE: { + mpGame.ClientReadStartState( msg ); + break; + } + case GAME_RELIABLE_MESSAGE_WARMUPTIME: { + mpGame.ClientReadWarmupTime( msg ); + break; + } + default: { + Error( "Unknown server->client reliable message: %d", id ); + break; + } + } +} + +/* +================ +idGameLocal::ClientPrediction +================ +*/ +gameReturn_t idGameLocal::ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ) { + idEntity *ent; + idPlayer *player; + gameReturn_t ret; + + ret.sessionCommand[ 0 ] = '\0'; + + player = static_cast( entities[clientNum] ); + if ( !player ) { + return ret; + } + + // check for local client lag + if ( networkSystem->ClientGetTimeSinceLastPacket() >= net_clientMaxPrediction.GetInteger() ) { + player->isLagged = true; + } else { + player->isLagged = false; + } + + InitLocalClient( clientNum ); + + // update the game time + framenum++; + previousTime = time; + time += msec; + + // update the real client time and the new frame flag + if ( time > realClientTime ) { + realClientTime = time; + isNewFrame = true; + } else { + isNewFrame = false; + } + + // set the user commands for this frame + memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); + + // run prediction on all entities from the last snapshot + for( ent = snapshotEntities.Next(); ent != NULL; ent = ent->snapshotNode.Next() ) { + ent->thinkFlags |= TH_PHYSICS; + ent->ClientPredictionThink(); + } + + // service any pending events + idEvent::ServiceEvents(); + + // show any debug info for this frame + if ( isNewFrame ) { + RunDebugInfo(); + D_DrawDebugLines(); + } + + if ( sessionCommand.Length() ) { + strncpy( ret.sessionCommand, sessionCommand, sizeof( ret.sessionCommand ) ); + } + return ret; +} + +/* +=============== +idGameLocal::Tokenize +=============== +*/ +void idGameLocal::Tokenize( idStrList &out, const char *in ) { + char buf[ MAX_STRING_CHARS ]; + char *token, *next; + + idStr::Copynz( buf, in, MAX_STRING_CHARS ); + token = buf; + next = strchr( token, ';' ); + while ( token ) { + if ( next ) { + *next = '\0'; + } + idStr::ToLower( token ); + out.Append( token ); + if ( next ) { + token = next + 1; + next = strchr( token, ';' ); + } else { + token = NULL; + } + } +} + +/* +=============== +idGameLocal::DownloadRequest +=============== +*/ +bool idGameLocal::DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) { + if ( !cvarSystem->GetCVarInteger( "net_serverDownload" ) ) { + return false; + } + if ( cvarSystem->GetCVarInteger( "net_serverDownload" ) == 1 ) { + // 1: single URL redirect + if ( !strlen( cvarSystem->GetCVarString( "si_serverURL" ) ) ) { + common->Warning( "si_serverURL not set" ); + return false; + } + idStr::snPrintf( urls, MAX_STRING_CHARS, "1;%s", cvarSystem->GetCVarString( "si_serverURL" ) ); + return true; + } else { + // 2: table of pak URLs + // first token is the game pak if request, empty if not requested by the client + // there may be empty tokens for paks the server couldn't pinpoint - the order matters + idStr reply = "2;"; + idStrList dlTable, pakList; + int i, j; + + Tokenize( dlTable, cvarSystem->GetCVarString( "net_serverDlTable" ) ); + Tokenize( pakList, paks ); + + for ( i = 0; i < pakList.Num(); i++ ) { + if ( i > 0 ) { + reply += ";"; + } + if ( pakList[ i ][ 0 ] == '\0' ) { + if ( i == 0 ) { + // pak 0 will always miss when client doesn't ask for game bin + common->DPrintf( "no game pak request\n" ); + } else { + common->DPrintf( "no pak %d\n", i ); + } + continue; + } + for ( j = 0; j < dlTable.Num(); j++ ) { + if ( !fileSystem->FilenameCompare( pakList[ i ], dlTable[ j ] ) ) { + break; + } + } + if ( j == dlTable.Num() ) { + common->Printf( "download for %s: pak not matched: %s\n", IP, pakList[ i ].c_str() ); + } else { + idStr url = cvarSystem->GetCVarString( "net_serverDlBaseURL" ); + url.AppendPath( dlTable[ j ] ); + reply += url; + common->DPrintf( "download for %s: %s\n", IP, url.c_str() ); + } + } + + idStr::Copynz( urls, reply, MAX_STRING_CHARS ); + return true; + } +// return false; +} + +/* +=============== +idEventQueue::Alloc +=============== +*/ +entityNetEvent_t* idEventQueue::Alloc() { + entityNetEvent_t* event = eventAllocator.Alloc(); + event->prev = NULL; + event->next = NULL; + return event; +} + +/* +=============== +idEventQueue::Free +=============== +*/ +void idEventQueue::Free( entityNetEvent_t *event ) { + // should only be called on an unlinked event! + assert( !event->next && !event->prev ); + eventAllocator.Free( event ); +} + +/* +=============== +idEventQueue::Shutdown +=============== +*/ +void idEventQueue::Shutdown() { + eventAllocator.Shutdown(); + this->Init(); +} + +/* +=============== +idEventQueue::Init +=============== +*/ +void idEventQueue::Init( void ) { + start = NULL; + end = NULL; +} + +/* +=============== +idEventQueue::Dequeue +=============== +*/ +entityNetEvent_t* idEventQueue::Dequeue( void ) { + entityNetEvent_t* event = start; + if ( !event ) { + return NULL; + } + + start = start->next; + + if ( !start ) { + end = NULL; + } else { + start->prev = NULL; + } + + event->next = NULL; + event->prev = NULL; + + return event; +} + +/* +=============== +idEventQueue::RemoveLast +=============== +*/ +entityNetEvent_t* idEventQueue::RemoveLast( void ) { + entityNetEvent_t *event = end; + if ( !event ) { + return NULL; + } + + end = event->prev; + + if ( !end ) { + start = NULL; + } else { + end->next = NULL; + } + + event->next = NULL; + event->prev = NULL; + + return event; +} + +/* +=============== +idEventQueue::Enqueue +=============== +*/ +void idEventQueue::Enqueue( entityNetEvent_t *event, outOfOrderBehaviour_t behaviour ) { + if ( behaviour == OUTOFORDER_DROP ) { + // go backwards through the queue and determine if there are + // any out-of-order events + while ( end && end->time > event->time ) { + entityNetEvent_t *outOfOrder = RemoveLast(); + common->DPrintf( "WARNING: new event with id %d ( time %d ) caused removal of event with id %d ( time %d ), game time = %d.\n", event->event, event->time, outOfOrder->event, outOfOrder->time, gameLocal.time ); + Free( outOfOrder ); + } + } else if ( behaviour == OUTOFORDER_SORT && end ) { + // NOT TESTED -- sorting out of order packets hasn't been + // tested yet... wasn't strictly necessary for + // the patch fix. + entityNetEvent_t *cur = end; + // iterate until we find a time < the new event's + while ( cur && cur->time > event->time ) { + cur = cur->prev; + } + if ( !cur ) { + // add to start + event->next = start; + event->prev = NULL; + start = event; + } else { + // insert + event->prev = cur; + event->next = cur->next; + cur->next = event; + } + return; + } + + // add the new event + event->next = NULL; + event->prev = NULL; + + if ( end ) { + end->next = event; + event->prev = end; + } else { + start = event; + } + end = event; +} diff --git a/DarkMod/Grabber.cpp b/game/Grabber.cpp similarity index 98% rename from DarkMod/Grabber.cpp rename to game/Grabber.cpp index 789c1f945..0dcbf57a0 100755 --- a/DarkMod/Grabber.cpp +++ b/game/Grabber.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // TODO: Make sure drag to point is not within a solid // TODO: Detecting stuck items (distance + angular offset) @@ -16,7 +26,7 @@ static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" #include "Grabber.h" diff --git a/DarkMod/Grabber.h b/game/Grabber.h similarity index 93% rename from DarkMod/Grabber.h rename to game/Grabber.h index 43db23755..2b63c5c96 100755 --- a/DarkMod/Grabber.h +++ b/game/Grabber.h @@ -1,17 +1,27 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __GRABBER_H__ #define __GRABBER_H__ -#include "../game/entity.h" -#include "force_grab.h" +#include "Entity.h" +#include "Force_Grab.h" class idPlayer; diff --git a/DarkMod/HidingSpotSearchCollection.cpp b/game/HidingSpotSearchCollection.cpp similarity index 89% rename from DarkMod/HidingSpotSearchCollection.cpp rename to game/HidingSpotSearchCollection.cpp index 041754fcc..6a8e59ebf 100644 --- a/DarkMod/HidingSpotSearchCollection.cpp +++ b/game/HidingSpotSearchCollection.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/HidingSpotSearchCollection.h b/game/HidingSpotSearchCollection.h similarity index 82% rename from DarkMod/HidingSpotSearchCollection.h rename to game/HidingSpotSearchCollection.h index 670e5a505..83b133afb 100644 --- a/DarkMod/HidingSpotSearchCollection.h +++ b/game/HidingSpotSearchCollection.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once /** diff --git a/game/Http/HttpConnection.cpp b/game/Http/HttpConnection.cpp new file mode 100644 index 000000000..3abcad8a9 --- /dev/null +++ b/game/Http/HttpConnection.cpp @@ -0,0 +1,76 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "HttpConnection.h" +#include "HttpRequest.h" + +#ifdef WIN32 +#pragma warning(disable: 4800) // stgatilov: suppress "forcing value to bool" warning in WinSDK +#include // greebo: need to include winsock2 before curl/curl.h +#include +#include +#endif + +#include + +CHttpConnection::CHttpConnection() +{ + curl_global_init(CURL_GLOBAL_ALL); +} + +CHttpConnection::~CHttpConnection() +{ + // Clean up cURL + curl_global_cleanup(); +} + +bool CHttpConnection::HasProxy() +{ + return idStr::Length(cv_tdm_proxy.GetString()) > 0; +} + +idStr CHttpConnection::GetProxyHost() +{ + return cv_tdm_proxy.GetString(); +} + +idStr CHttpConnection::GetProxyUsername() +{ + return cv_tdm_proxy_user.GetString(); +} + +idStr CHttpConnection::GetProxyPassword() +{ + return cv_tdm_proxy_pass.GetString(); +} + +CHttpRequestPtr CHttpConnection::CreateRequest(const std::string& url) +{ + return CHttpRequestPtr(new CHttpRequest(*this, url)); +} + +CHttpRequestPtr CHttpConnection::CreateRequest(const std::string& url, const std::string& destFilename) +{ + return CHttpRequestPtr(new CHttpRequest(*this, url, destFilename)); +} diff --git a/game/Http/HttpConnection.h b/game/Http/HttpConnection.h new file mode 100644 index 000000000..84d493337 --- /dev/null +++ b/game/Http/HttpConnection.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _HTTP_CONNECTION_H_ +#define _HTTP_CONNECTION_H_ + +#include + +class CHttpRequest; +typedef boost::shared_ptr CHttpRequestPtr; + +/** + * greebo: An object representing a single HttpConnection, holding + * proxy settings and providing error handling. + * + * Use the CreateRequest() method to generate a new request object. + * + * TDM provides a single http connection object via the gameLocal class: + * + * gameLocal.m_HttpConnection->CreateRequest("http://www.thedarkmod.com"); + * + * Note: the m_HttpConnection object can be NULL if HTTP requests have been + * disabled by the user. + */ +class CHttpConnection +{ + friend class idGameLocal; + +private: + CHttpConnection(); + +public: + ~CHttpConnection(); + + bool HasProxy(); + + idStr GetProxyHost(); + idStr GetProxyUsername(); + idStr GetProxyPassword(); + + /** + * Constructs a new HTTP request using the given URL (optional: filename) + */ + CHttpRequestPtr CreateRequest(const std::string& url); + CHttpRequestPtr CreateRequest(const std::string& url, const std::string& destFilename); +}; +typedef boost::shared_ptr CHttpConnectionPtr; + +#endif /* _HTTP_CONNECTION_H_ */ diff --git a/DarkMod/Http/HttpRequest.cpp b/game/Http/HttpRequest.cpp similarity index 85% rename from DarkMod/Http/HttpRequest.cpp rename to game/Http/HttpRequest.cpp index 0ba78706c..fa757abf8 100644 --- a/DarkMod/Http/HttpRequest.cpp +++ b/game/Http/HttpRequest.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -17,6 +27,7 @@ static bool init_version = FileVersionList("$Id$", init_version); #ifdef WIN32 #pragma warning(disable: 4800) // stgatilov: suppress "forcing value to bool" warning in WinSDK + #include // greebo: need to include winsock2 before curl/curl.h #include #include diff --git a/game/Http/HttpRequest.h b/game/Http/HttpRequest.h new file mode 100644 index 000000000..bf9ad2baa --- /dev/null +++ b/game/Http/HttpRequest.h @@ -0,0 +1,109 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _HTTP_REQUEST_H_ +#define _HTTP_REQUEST_H_ + +#include +#include + +class CHttpConnection; + +#include "../pugixml/pugixml.hpp" +typedef void CURL; + +// Shared_ptr typedef +typedef boost::shared_ptr XmlDocumentPtr; + +/** + * greebo: An object representing a single HttpRequest, holding + * the result (string) and status information. + * + * Use the Perform() method to execute the request. + */ +class CHttpRequest +{ +public: + + enum RequestStatus + { + NOT_PERFORMED_YET, + OK, // successful + IN_PROGRESS, + FAILED, + ABORTED, + }; + +private: + // The connection we're working with + CHttpConnection& _conn; + + // The URL we're supposed to query + std::string _url; + + std::vector _buffer; + + // The curl handle + CURL* _handle; + + // The current state + RequestStatus _status; + + std::string _destFilename; + + std::ofstream _destStream; + + // True if we should cancel the download + bool _cancelFlag; + + double _progress; + +public: + CHttpRequest(CHttpConnection& conn, const std::string& url); + + CHttpRequest(CHttpConnection& conn, const std::string& url, const std::string& destFilename); + + // Callbacks for CURL + static size_t WriteMemoryCallback(void* ptr, size_t size, size_t nmemb, CHttpRequest* self); + static size_t WriteFileCallback(void* ptr, size_t size, size_t nmemb, CHttpRequest* self); + + RequestStatus GetStatus(); + + // Perform the request + void Perform(); + + void Cancel(); + + // Between 0.0 and 1.0 + double GetProgressFraction(); + + // Returns the result string + std::string GetResultString(); + + // Returns the result as XML document + XmlDocumentPtr GetResultXml(); + +private: + void InitRequest(); + + void UpdateProgress(); +}; +typedef boost::shared_ptr CHttpRequestPtr; + +#endif /* _HTTP_REQUEST_H_ */ diff --git a/DarkMod/I18N.cpp b/game/I18N.cpp similarity index 95% rename from DarkMod/I18N.cpp rename to game/I18N.cpp index ce052e057..748e8cdf3 100644 --- a/DarkMod/I18N.cpp +++ b/game/I18N.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* =============================================================================== diff --git a/DarkMod/I18N.h b/game/I18N.h similarity index 80% rename from DarkMod/I18N.h rename to game/I18N.h index 56384a0d3..8c6863088 100644 --- a/DarkMod/I18N.h +++ b/game/I18N.h @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2011 Tels (Donated to The Dark Mod) diff --git a/game/IK.cpp b/game/IK.cpp new file mode 100644 index 000000000..cf0da1dc3 --- /dev/null +++ b/game/IK.cpp @@ -0,0 +1,1121 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +=============================================================================== + + idIK + +=============================================================================== +*/ + +/* +================ +idIK::idIK +================ +*/ +idIK::idIK( void ) { + ik_activate = false; + initialized = false; + self = NULL; + animator = NULL; + modifiedAnim = 0; + modelOffset.Zero(); +} + +/* +================ +idIK::~idIK +================ +*/ +idIK::~idIK( void ) { +} + +/* +================ +idIK::Save +================ +*/ +void idIK::Save( idSaveGame *savefile ) const { + savefile->WriteBool( initialized ); + savefile->WriteBool( ik_activate ); + savefile->WriteObject( self ); + savefile->WriteString( animator != NULL && animator->GetAnim( modifiedAnim ) ? animator->GetAnim( modifiedAnim )->Name() : "" ); + savefile->WriteVec3( modelOffset ); +} + +/* +================ +idIK::Restore +================ +*/ +void idIK::Restore( idRestoreGame *savefile ) { + idStr anim; + + savefile->ReadBool( initialized ); + savefile->ReadBool( ik_activate ); + savefile->ReadObject( reinterpret_cast( self ) ); + savefile->ReadString( anim ); + savefile->ReadVec3( modelOffset ); + + if ( self ) { + animator = self->GetAnimator(); + if ( animator == NULL || animator->ModelDef() == NULL ) { + gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no model set.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + } + modifiedAnim = animator->GetAnim( anim ); + if ( modifiedAnim == 0 ) { + gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no modified animation.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + } + } else { + animator = NULL; + modifiedAnim = 0; + } +} + +/* +================ +idIK::IsInitialized +================ +*/ +bool idIK::IsInitialized( void ) const { + return initialized && ik_enable.GetBool(); +} + +/* +================ +idIK::Init +================ +*/ +bool idIK::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { + idRenderModel *model; + + if ( self == NULL ) { + return false; + } + + this->self = self; + + animator = self->GetAnimator(); + if ( animator == NULL || animator->ModelDef() == NULL ) { + gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + if ( animator->ModelDef()->ModelHandle() == NULL ) { + gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) uses default model.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + model = animator->ModelHandle(); + if ( model == NULL ) { + gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + modifiedAnim = animator->GetAnim( anim ); + if ( modifiedAnim == 0 ) { + gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no modified animation.", + self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); + return false; + } + + this->modelOffset = modelOffset; + + return true; +} + +/* +================ +idIK::Evaluate +================ +*/ +void idIK::Evaluate( void ) { +} + +/* +================ +idIK::ClearJointMods +================ +*/ +void idIK::ClearJointMods( void ) { + ik_activate = false; +} + +/* +================ +idIK::SolveTwoBones +================ +*/ +bool idIK::SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos ) { + float length, lengthSqr, lengthInv, x, y; + idVec3 vec0, vec1; + + vec0 = endPos - startPos; + lengthSqr = vec0.LengthSqr(); + lengthInv = idMath::InvSqrt( lengthSqr ); + length = lengthInv * lengthSqr; + + // if the start and end position are too far out or too close to each other + if ( length > len0 + len1 || length < idMath::Fabs( len0 - len1 ) ) { + jointPos = startPos + 0.5f * vec0; + return false; + } + + vec0 *= lengthInv; + vec1 = dir - vec0 * dir * vec0; + vec1.Normalize(); + + x = ( length * length + len0 * len0 - len1 * len1 ) * ( 0.5f * lengthInv ); + y = idMath::Sqrt( len0 * len0 - x * x ); + + jointPos = startPos + x * vec0 + y * vec1; + + return true; +} + +/* +================ +idIK::GetBoneAxis +================ +*/ +float idIK::GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis ) { + float length; + axis[0] = endPos - startPos; + length = axis[0].Normalize(); + axis[1] = dir - axis[0] * dir * axis[0]; + axis[1].Normalize(); + axis[2].Cross( axis[1], axis[0] ); + return length; +} + + +/* +=============================================================================== + + idIK_Walk + +=============================================================================== +*/ + +/* +================ +idIK_Walk::idIK_Walk +================ +*/ +idIK_Walk::idIK_Walk() { + int i; + + initialized = false; + footModel = NULL; + numLegs = 0; + enabledLegs = 0; + for ( i = 0; i < MAX_LEGS; i++ ) { + footJoints[i] = INVALID_JOINT; + ankleJoints[i] = INVALID_JOINT; + kneeJoints[i] = INVALID_JOINT; + hipJoints[i] = INVALID_JOINT; + dirJoints[i] = INVALID_JOINT; + hipForward[i].Zero(); + kneeForward[i].Zero(); + upperLegLength[i] = 0.0f; + lowerLegLength[i] = 0.0f; + upperLegToHipJoint[i].Identity(); + lowerLegToKneeJoint[i].Identity(); + oldAnkleHeights[i] = 0.0f; + } + waistJoint = INVALID_JOINT; + + smoothing = 0.75f; + waistSmoothing = 0.5f; + footShift = 0.0f; + waistShift = 0.0f; + minWaistFloorDist = 0.0f; + minWaistAnkleDist = 0.0f; + footUpTrace = 32.0f; + footDownTrace = 32.0f; + tiltWaist = false; + usePivot = false; + + pivotFoot = -1; + pivotYaw = 0.0f; + pivotPos.Zero(); + + oldHeightsValid = false; + oldWaistHeight = 0.0f; + waistOffset.Zero(); +} + +/* +================ +idIK_Walk::~idIK_Walk +================ +*/ +idIK_Walk::~idIK_Walk() { + if ( footModel ) { + delete footModel; + } +} + +/* +================ +idIK_Walk::Save +================ +*/ +void idIK_Walk::Save( idSaveGame *savefile ) const { + int i; + + idIK::Save( savefile ); + + savefile->WriteClipModel( footModel ); + + savefile->WriteInt( numLegs ); + savefile->WriteInt( enabledLegs ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteInt( footJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteInt( ankleJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteInt( kneeJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteInt( hipJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteInt( dirJoints[i] ); + savefile->WriteInt( waistJoint ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteVec3( hipForward[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteVec3( kneeForward[i] ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteFloat( upperLegLength[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteFloat( lowerLegLength[i] ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteMat3( upperLegToHipJoint[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->WriteMat3( lowerLegToKneeJoint[i] ); + + savefile->WriteFloat( smoothing ); + savefile->WriteFloat( waistSmoothing ); + savefile->WriteFloat( footShift ); + savefile->WriteFloat( waistShift ); + savefile->WriteFloat( minWaistFloorDist ); + savefile->WriteFloat( minWaistAnkleDist ); + savefile->WriteFloat( footUpTrace ); + savefile->WriteFloat( footDownTrace ); + savefile->WriteBool( tiltWaist ); + savefile->WriteBool( usePivot ); + + savefile->WriteInt( pivotFoot ); + savefile->WriteFloat( pivotYaw ); + savefile->WriteVec3( pivotPos ); + savefile->WriteBool( oldHeightsValid ); + savefile->WriteFloat( oldWaistHeight ); + for ( i = 0; i < MAX_LEGS; i++ ) { + savefile->WriteFloat( oldAnkleHeights[i] ); + } + savefile->WriteVec3( waistOffset ); +} + +/* +================ +idIK_Walk::Restore +================ +*/ +void idIK_Walk::Restore( idRestoreGame *savefile ) { + int i; + + idIK::Restore( savefile ); + + savefile->ReadClipModel( footModel ); + + savefile->ReadInt( numLegs ); + savefile->ReadInt( enabledLegs ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadInt( (int&)footJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadInt( (int&)ankleJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadInt( (int&)kneeJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadInt( (int&)hipJoints[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadInt( (int&)dirJoints[i] ); + savefile->ReadInt( (int&)waistJoint ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadVec3( hipForward[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadVec3( kneeForward[i] ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadFloat( upperLegLength[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadFloat( lowerLegLength[i] ); + + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadMat3( upperLegToHipJoint[i] ); + for ( i = 0; i < MAX_LEGS; i++ ) + savefile->ReadMat3( lowerLegToKneeJoint[i] ); + + savefile->ReadFloat( smoothing ); + savefile->ReadFloat( waistSmoothing ); + savefile->ReadFloat( footShift ); + savefile->ReadFloat( waistShift ); + savefile->ReadFloat( minWaistFloorDist ); + savefile->ReadFloat( minWaistAnkleDist ); + savefile->ReadFloat( footUpTrace ); + savefile->ReadFloat( footDownTrace ); + savefile->ReadBool( tiltWaist ); + savefile->ReadBool( usePivot ); + + savefile->ReadInt( pivotFoot ); + savefile->ReadFloat( pivotYaw ); + savefile->ReadVec3( pivotPos ); + savefile->ReadBool( oldHeightsValid ); + savefile->ReadFloat( oldWaistHeight ); + for ( i = 0; i < MAX_LEGS; i++ ) { + savefile->ReadFloat( oldAnkleHeights[i] ); + } + savefile->ReadVec3( waistOffset ); +} + +/* +================ +idIK_Walk::Init +================ +*/ +bool idIK_Walk::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { + int i; + float footSize; + idVec3 verts[4]; + idTraceModel trm; + const char *jointName; + idVec3 dir, ankleOrigin, kneeOrigin, hipOrigin, dirOrigin; + idMat3 axis, ankleAxis, kneeAxis, hipAxis; + + static idVec3 footWinding[4] = { + idVec3( 1.0f, 1.0f, 0.0f ), + idVec3( -1.0f, 1.0f, 0.0f ), + idVec3( -1.0f, -1.0f, 0.0f ), + idVec3( 1.0f, -1.0f, 0.0f ) + }; + + if ( !self ) { + return false; + } + + numLegs = Min( self->spawnArgs.GetInt( "ik_numLegs", "0" ), MAX_LEGS ); + if ( numLegs == 0 ) { + return true; + } + + if ( !idIK::Init( self, anim, modelOffset ) ) { + return false; + } + + int numJoints = animator->NumJoints(); + idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); + + // create the animation frame used to setup the IK + gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() ); + + enabledLegs = 0; + + // get all the joints + for ( i = 0; i < numLegs; i++ ) { + + jointName = self->spawnArgs.GetString( va( "ik_foot%d", i+1 ) ); + footJoints[i] = animator->GetJointHandle( jointName ); + if ( footJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Walk::Init: invalid foot joint '%s'", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_ankle%d", i+1 ) ); + ankleJoints[i] = animator->GetJointHandle( jointName ); + if ( ankleJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Walk::Init: invalid ankle joint '%s'", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_knee%d", i+1 ) ); + kneeJoints[i] = animator->GetJointHandle( jointName ); + if ( kneeJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Walk::Init: invalid knee joint '%s'\n", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_hip%d", i+1 ) ); + hipJoints[i] = animator->GetJointHandle( jointName ); + if ( hipJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Walk::Init: invalid hip joint '%s'\n", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_dir%d", i+1 ) ); + dirJoints[i] = animator->GetJointHandle( jointName ); + + enabledLegs |= 1 << i; + } + + jointName = self->spawnArgs.GetString( "ik_waist" ); + waistJoint = animator->GetJointHandle( jointName ); + if ( waistJoint == INVALID_JOINT ) { + gameLocal.Error( "idIK_Walk::Init: invalid waist joint '%s'\n", jointName ); + } + + // get the leg bone lengths and rotation matrices + for ( i = 0; i < numLegs; i++ ) { + oldAnkleHeights[i] = 0.0f; + + ankleAxis = joints[ ankleJoints[ i ] ].ToMat3(); + ankleOrigin = joints[ ankleJoints[ i ] ].ToVec3(); + + kneeAxis = joints[ kneeJoints[ i ] ].ToMat3(); + kneeOrigin = joints[ kneeJoints[ i ] ].ToVec3(); + + hipAxis = joints[ hipJoints[ i ] ].ToMat3(); + hipOrigin = joints[ hipJoints[ i ] ].ToVec3(); + + // get the IK direction + if ( dirJoints[i] != INVALID_JOINT ) { + dirOrigin = joints[ dirJoints[ i ] ].ToVec3(); + dir = dirOrigin - kneeOrigin; + } else { + dir.Set( 1.0f, 0.0f, 0.0f ); + } + + hipForward[i] = dir * hipAxis.Transpose(); + kneeForward[i] = dir * kneeAxis.Transpose(); + + // conversion from upper leg bone axis to hip joint axis + upperLegLength[i] = GetBoneAxis( hipOrigin, kneeOrigin, dir, axis ); + upperLegToHipJoint[i] = hipAxis * axis.Transpose(); + + // conversion from lower leg bone axis to knee joint axis + lowerLegLength[i] = GetBoneAxis( kneeOrigin, ankleOrigin, dir, axis ); + lowerLegToKneeJoint[i] = kneeAxis * axis.Transpose(); + } + + smoothing = self->spawnArgs.GetFloat( "ik_smoothing", "0.75" ); + waistSmoothing = self->spawnArgs.GetFloat( "ik_waistSmoothing", "0.75" ); + footShift = self->spawnArgs.GetFloat( "ik_footShift", "0" ); + waistShift = self->spawnArgs.GetFloat( "ik_waistShift", "0" ); + minWaistFloorDist = self->spawnArgs.GetFloat( "ik_minWaistFloorDist", "0" ); + minWaistAnkleDist = self->spawnArgs.GetFloat( "ik_minWaistAnkleDist", "0" ); + footUpTrace = self->spawnArgs.GetFloat( "ik_footUpTrace", "32" ); + footDownTrace = self->spawnArgs.GetFloat( "ik_footDownTrace", "32" ); + tiltWaist = self->spawnArgs.GetBool( "ik_tiltWaist", "0" ); + usePivot = self->spawnArgs.GetBool( "ik_usePivot", "0" ); + + // setup a clip model for the feet + footSize = self->spawnArgs.GetFloat( "ik_footSize", "4" ) * 0.5f; + if ( footSize > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + verts[i] = footWinding[i] * footSize; + } + trm.SetupPolygon( verts, 4 ); + footModel = new idClipModel( trm ); + } + + initialized = true; + + return true; +} + +/* +================ +idIK_Walk::Evaluate +================ +*/ +void idIK_Walk::Evaluate( void ) { + int i; + int newPivotFoot = 0; + float modelHeight, jointHeight, lowestHeight, floorHeights[MAX_LEGS]; + float shift, smallestShift, newHeight, step, newPivotYaw, height, largestAnkleHeight; + idVec3 modelOrigin, normal, hipDir, kneeDir, start, end, jointOrigins[MAX_LEGS]; + idVec3 footOrigin, ankleOrigin, kneeOrigin, hipOrigin, waistOrigin; + idMat3 modelAxis, waistAxis, axis; + idMat3 hipAxis[MAX_LEGS], kneeAxis[MAX_LEGS], ankleAxis[MAX_LEGS]; + trace_t results; + + if ( !self || !gameLocal.isNewFrame ) { + return; + } + + // if no IK enabled on any legs + if ( !enabledLegs ) { + return; + } + + normal = - self->GetPhysics()->GetGravityNormal(); + modelOrigin = self->GetPhysics()->GetOrigin(); + modelAxis = self->GetRenderEntity()->axis; + modelHeight = modelOrigin * normal; + + modelOrigin += modelOffset * modelAxis; + + // create frame without joint mods + animator->CreateFrame( gameLocal.time, false ); + + // get the joint positions for the feet + lowestHeight = idMath::INFINITY; + for ( i = 0; i < numLegs; i++ ) { + animator->GetJointTransform( footJoints[i], gameLocal.time, footOrigin, axis ); + jointOrigins[i] = modelOrigin + footOrigin * modelAxis; + jointHeight = jointOrigins[i] * normal; + if ( jointHeight < lowestHeight ) { + lowestHeight = jointHeight; + newPivotFoot = i; + } + } + + if ( usePivot ) { + + newPivotYaw = modelAxis[0].ToYaw(); + + // change pivot foot + if ( newPivotFoot != pivotFoot || idMath::Fabs( idMath::AngleNormalize180( newPivotYaw - pivotYaw ) ) > 30.0f ) { + pivotFoot = newPivotFoot; + pivotYaw = newPivotYaw; + animator->GetJointTransform( footJoints[pivotFoot], gameLocal.time, footOrigin, axis ); + pivotPos = modelOrigin + footOrigin * modelAxis; + } + + // keep pivot foot in place + jointOrigins[pivotFoot] = pivotPos; + } + + // get the floor heights for the feet + for ( i = 0; i < numLegs; i++ ) { + + if ( !( enabledLegs & ( 1 << i ) ) ) { + continue; + } + + start = jointOrigins[i] + normal * footUpTrace; + end = jointOrigins[i] - normal * footDownTrace; + gameLocal.clip.Translation( results, start, end, footModel, mat3_identity, CONTENTS_SOLID|CONTENTS_IKCLIP, self ); + floorHeights[i] = results.endpos * normal; + + if ( ik_debug.GetBool() && footModel ) { + idFixedWinding w; + for ( int j = 0; j < footModel->GetTraceModel()->numVerts; j++ ) { + w += footModel->GetTraceModel()->verts[j]; + } + gameRenderWorld->DebugWinding( colorRed, w, results.endpos, results.endAxis ); + } + } + + const idPhysics *phys = self->GetPhysics(); + + // test whether or not the character standing on the ground + bool onGround = phys->HasGroundContacts(); + + // test whether or not the character is standing on a plat + bool onPlat = false; + for ( i = 0; i < phys->GetNumContacts(); i++ ) { + idEntity *ent = gameLocal.entities[ phys->GetContact( i ).entityNum ]; + if ( ent != NULL && ent->IsType( idPlat::Type ) ) { + onPlat = true; + break; + } + } + + // adjust heights of the ankles + smallestShift = idMath::INFINITY; + largestAnkleHeight = -idMath::INFINITY; + for ( i = 0; i < numLegs; i++ ) { + + if ( onGround && ( enabledLegs & ( 1 << i ) ) ) { + shift = floorHeights[i] - modelHeight + footShift; + } else { + shift = 0.0f; + } + + if ( shift < smallestShift ) { + smallestShift = shift; + } + + animator->GetJointTransform( ankleJoints[i], gameLocal.time, ankleOrigin, ankleAxis[i] ); + jointOrigins[i] = modelOrigin + ankleOrigin * modelAxis; + + height = jointOrigins[i] * normal; + + if ( oldHeightsValid && !onPlat ) { + step = height + shift - oldAnkleHeights[i]; + shift -= smoothing * step; + } + + newHeight = height + shift; + if ( newHeight > largestAnkleHeight ) { + largestAnkleHeight = newHeight; + } + + oldAnkleHeights[i] = newHeight; + + jointOrigins[i] += shift * normal; + } + + animator->GetJointTransform( waistJoint, gameLocal.time, waistOrigin, waistAxis ); + waistOrigin = modelOrigin + waistOrigin * modelAxis; + + // adjust position of the waist + waistOffset = ( smallestShift + waistShift ) * normal; + + // if the waist should be at least a certain distance above the floor + if ( minWaistFloorDist > 0.0f && waistOffset * normal < 0.0f ) { + start = waistOrigin; + end = waistOrigin + waistOffset - normal * minWaistFloorDist; + gameLocal.clip.Translation( results, start, end, footModel, modelAxis, CONTENTS_SOLID|CONTENTS_IKCLIP, self ); + height = ( waistOrigin + waistOffset - results.endpos ) * normal; + if ( height < minWaistFloorDist ) { + waistOffset += ( minWaistFloorDist - height ) * normal; + } + } + + // if the waist should be at least a certain distance above the ankles + if ( minWaistAnkleDist > 0.0f ) { + height = ( waistOrigin + waistOffset ) * normal; + if ( height - largestAnkleHeight < minWaistAnkleDist ) { + waistOffset += ( minWaistAnkleDist - ( height - largestAnkleHeight ) ) * normal; + } + } + + if ( oldHeightsValid ) { + // smoothly adjust height of waist + newHeight = ( waistOrigin + waistOffset ) * normal; + step = newHeight - oldWaistHeight; + waistOffset -= waistSmoothing * step * normal; + } + + // save height of waist for smoothing + oldWaistHeight = ( waistOrigin + waistOffset ) * normal; + + if ( !oldHeightsValid ) { + oldHeightsValid = true; + return; + } + + // solve IK + for ( i = 0; i < numLegs; i++ ) { + + // get the position of the hip in world space + animator->GetJointTransform( hipJoints[i], gameLocal.time, hipOrigin, axis ); + hipOrigin = modelOrigin + waistOffset + hipOrigin * modelAxis; + hipDir = hipForward[i] * axis * modelAxis; + + // get the IK bend direction + animator->GetJointTransform( kneeJoints[i], gameLocal.time, kneeOrigin, axis ); + kneeDir = kneeForward[i] * axis * modelAxis; + + // solve IK and calculate knee position + SolveTwoBones( hipOrigin, jointOrigins[i], kneeDir, upperLegLength[i], lowerLegLength[i], kneeOrigin ); + + if ( ik_debug.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, hipOrigin, kneeOrigin ); + gameRenderWorld->DebugLine( colorRed, kneeOrigin, jointOrigins[i] ); + gameRenderWorld->DebugLine( colorYellow, kneeOrigin, kneeOrigin + hipDir ); + gameRenderWorld->DebugLine( colorGreen, kneeOrigin, kneeOrigin + kneeDir ); + } + + // get the axis for the hip joint + GetBoneAxis( hipOrigin, kneeOrigin, hipDir, axis ); + hipAxis[i] = upperLegToHipJoint[i] * ( axis * modelAxis.Transpose() ); + + // get the axis for the knee joint + GetBoneAxis( kneeOrigin, jointOrigins[i], kneeDir, axis ); + kneeAxis[i] = lowerLegToKneeJoint[i] * ( axis * modelAxis.Transpose() ); + } + + // set the joint mods + animator->SetJointAxis( waistJoint, JOINTMOD_WORLD_OVERRIDE, waistAxis ); + animator->SetJointPos( waistJoint, JOINTMOD_WORLD_OVERRIDE, ( waistOrigin + waistOffset - modelOrigin ) * modelAxis.Transpose() ); + for ( i = 0; i < numLegs; i++ ) { + animator->SetJointAxis( hipJoints[i], JOINTMOD_WORLD_OVERRIDE, hipAxis[i] ); + animator->SetJointAxis( kneeJoints[i], JOINTMOD_WORLD_OVERRIDE, kneeAxis[i] ); + animator->SetJointAxis( ankleJoints[i], JOINTMOD_WORLD_OVERRIDE, ankleAxis[i] ); + } + + ik_activate = true; +} + +/* +================ +idIK_Walk::ClearJointMods +================ +*/ +void idIK_Walk::ClearJointMods( void ) { + int i; + + if ( !self || !ik_activate ) { + return; + } + + animator->SetJointAxis( waistJoint, JOINTMOD_NONE, mat3_identity ); + animator->SetJointPos( waistJoint, JOINTMOD_NONE, vec3_origin ); + for ( i = 0; i < numLegs; i++ ) { + animator->SetJointAxis( hipJoints[i], JOINTMOD_NONE, mat3_identity ); + animator->SetJointAxis( kneeJoints[i], JOINTMOD_NONE, mat3_identity ); + animator->SetJointAxis( ankleJoints[i], JOINTMOD_NONE, mat3_identity ); + } + + ik_activate = false; +} + +/* +================ +idIK_Walk::EnableAll +================ +*/ +void idIK_Walk::EnableAll( void ) { + enabledLegs = ( 1 << numLegs ) - 1; + oldHeightsValid = false; +} + +/* +================ +idIK_Walk::DisableAll +================ +*/ +void idIK_Walk::DisableAll( void ) { + enabledLegs = 0; + oldHeightsValid = false; +} + +/* +================ +idIK_Walk::EnableLeg +================ +*/ +void idIK_Walk::EnableLeg( int num ) { + enabledLegs |= 1 << num; +} + +/* +================ +idIK_Walk::DisableLeg +================ +*/ +void idIK_Walk::DisableLeg( int num ) { + enabledLegs &= ~( 1 << num ); +} + + +/* +=============================================================================== + + idIK_Reach + +=============================================================================== +*/ + +/* +================ +idIK_Reach::idIK_Reach +================ +*/ +idIK_Reach::idIK_Reach() { + int i; + + initialized = false; + numArms = 0; + enabledArms = 0; + for ( i = 0; i < MAX_ARMS; i++ ) { + handJoints[i] = INVALID_JOINT; + elbowJoints[i] = INVALID_JOINT; + shoulderJoints[i] = INVALID_JOINT; + dirJoints[i] = INVALID_JOINT; + shoulderForward[i].Zero(); + elbowForward[i].Zero(); + upperArmLength[i] = 0.0f; + lowerArmLength[i] = 0.0f; + upperArmToShoulderJoint[i].Identity(); + lowerArmToElbowJoint[i].Identity(); + } +} + +/* +================ +idIK_Reach::~idIK_Reach +================ +*/ +idIK_Reach::~idIK_Reach() { +} + +/* +================ +idIK_Reach::Save +================ +*/ +void idIK_Reach::Save( idSaveGame *savefile ) const { + int i; + idIK::Save( savefile ); + + savefile->WriteInt( numArms ); + savefile->WriteInt( enabledArms ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteInt( handJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteInt( elbowJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteInt( shoulderJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteInt( dirJoints[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteVec3( shoulderForward[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteVec3( elbowForward[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteFloat( upperArmLength[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteFloat( lowerArmLength[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteMat3( upperArmToShoulderJoint[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->WriteMat3( lowerArmToElbowJoint[i] ); +} + +/* +================ +idIK_Reach::Restore +================ +*/ +void idIK_Reach::Restore( idRestoreGame *savefile ) { + int i; + idIK::Restore( savefile ); + + savefile->ReadInt( numArms ); + savefile->ReadInt( enabledArms ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadInt( (int&)handJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadInt( (int&)elbowJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadInt( (int&)shoulderJoints[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadInt( (int&)dirJoints[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadVec3( shoulderForward[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadVec3( elbowForward[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadFloat( upperArmLength[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadFloat( lowerArmLength[i] ); + + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadMat3( upperArmToShoulderJoint[i] ); + for ( i = 0; i < MAX_ARMS; i++ ) + savefile->ReadMat3( lowerArmToElbowJoint[i] ); +} + +/* +================ +idIK_Reach::Init +================ +*/ +bool idIK_Reach::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { + int i; + const char *jointName; + idTraceModel trm; + idVec3 dir, handOrigin, elbowOrigin, shoulderOrigin, dirOrigin; + idMat3 axis, handAxis, elbowAxis, shoulderAxis; + + if ( !self ) { + return false; + } + + numArms = Min( self->spawnArgs.GetInt( "ik_numArms", "0" ), MAX_ARMS ); + if ( numArms == 0 ) { + return true; + } + + if ( !idIK::Init( self, anim, modelOffset ) ) { + return false; + } + + int numJoints = animator->NumJoints(); + idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); + + // create the animation frame used to setup the IK + gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() ); + + enabledArms = 0; + + // get all the joints + for ( i = 0; i < numArms; i++ ) { + + jointName = self->spawnArgs.GetString( va( "ik_hand%d", i+1 ) ); + handJoints[i] = animator->GetJointHandle( jointName ); + if ( handJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Reach::Init: invalid hand joint '%s'", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_elbow%d", i+1 ) ); + elbowJoints[i] = animator->GetJointHandle( jointName ); + if ( elbowJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Reach::Init: invalid elbow joint '%s'\n", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_shoulder%d", i+1 ) ); + shoulderJoints[i] = animator->GetJointHandle( jointName ); + if ( shoulderJoints[i] == INVALID_JOINT ) { + gameLocal.Error( "idIK_Reach::Init: invalid shoulder joint '%s'\n", jointName ); + } + + jointName = self->spawnArgs.GetString( va( "ik_elbowDir%d", i+1 ) ); + dirJoints[i] = animator->GetJointHandle( jointName ); + + enabledArms |= 1 << i; + } + + // get the arm bone lengths and rotation matrices + for ( i = 0; i < numArms; i++ ) { + + handAxis = joints[ handJoints[ i ] ].ToMat3(); + handOrigin = joints[ handJoints[ i ] ].ToVec3(); + + elbowAxis = joints[ elbowJoints[ i ] ].ToMat3(); + elbowOrigin = joints[ elbowJoints[ i ] ].ToVec3(); + + shoulderAxis = joints[ shoulderJoints[ i ] ].ToMat3(); + shoulderOrigin = joints[ shoulderJoints[ i ] ].ToVec3(); + + // get the IK direction + if ( dirJoints[i] != INVALID_JOINT ) { + dirOrigin = joints[ dirJoints[ i ] ].ToVec3(); + dir = dirOrigin - elbowOrigin; + } else { + dir.Set( -1.0f, 0.0f, 0.0f ); + } + + shoulderForward[i] = dir * shoulderAxis.Transpose(); + elbowForward[i] = dir * elbowAxis.Transpose(); + + // conversion from upper arm bone axis to should joint axis + upperArmLength[i] = GetBoneAxis( shoulderOrigin, elbowOrigin, dir, axis ); + upperArmToShoulderJoint[i] = shoulderAxis * axis.Transpose(); + + // conversion from lower arm bone axis to elbow joint axis + lowerArmLength[i] = GetBoneAxis( elbowOrigin, handOrigin, dir, axis ); + lowerArmToElbowJoint[i] = elbowAxis * axis.Transpose(); + } + + initialized = true; + + return true; +} + +/* +================ +idIK_Reach::Evaluate +================ +*/ +void idIK_Reach::Evaluate( void ) { + int i; + idVec3 modelOrigin, shoulderOrigin, elbowOrigin, handOrigin, shoulderDir, elbowDir; + idMat3 modelAxis, axis; + idMat3 shoulderAxis[MAX_ARMS], elbowAxis[MAX_ARMS]; + trace_t trace; + + modelOrigin = self->GetRenderEntity()->origin; + modelAxis = self->GetRenderEntity()->axis; + + // solve IK + for ( i = 0; i < numArms; i++ ) { + + // get the position of the shoulder in world space + animator->GetJointTransform( shoulderJoints[i], gameLocal.time, shoulderOrigin, axis ); + shoulderOrigin = modelOrigin + shoulderOrigin * modelAxis; + shoulderDir = shoulderForward[i] * axis * modelAxis; + + // get the position of the hand in world space + animator->GetJointTransform( handJoints[i], gameLocal.time, handOrigin, axis ); + handOrigin = modelOrigin + handOrigin * modelAxis; + + // get first collision going from shoulder to hand + gameLocal.clip.TracePoint( trace, shoulderOrigin, handOrigin, CONTENTS_SOLID, self ); + handOrigin = trace.endpos; + + // get the IK bend direction + animator->GetJointTransform( elbowJoints[i], gameLocal.time, elbowOrigin, axis ); + elbowDir = elbowForward[i] * axis * modelAxis; + + // solve IK and calculate elbow position + SolveTwoBones( shoulderOrigin, handOrigin, elbowDir, upperArmLength[i], lowerArmLength[i], elbowOrigin ); + + if ( ik_debug.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, shoulderOrigin, elbowOrigin ); + gameRenderWorld->DebugLine( colorRed, elbowOrigin, handOrigin ); + gameRenderWorld->DebugLine( colorYellow, elbowOrigin, elbowOrigin + elbowDir ); + gameRenderWorld->DebugLine( colorGreen, elbowOrigin, elbowOrigin + shoulderDir ); + } + + // get the axis for the shoulder joint + GetBoneAxis( shoulderOrigin, elbowOrigin, shoulderDir, axis ); + shoulderAxis[i] = upperArmToShoulderJoint[i] * ( axis * modelAxis.Transpose() ); + + // get the axis for the elbow joint + GetBoneAxis( elbowOrigin, handOrigin, elbowDir, axis ); + elbowAxis[i] = lowerArmToElbowJoint[i] * ( axis * modelAxis.Transpose() ); + } + + for ( i = 0; i < numArms; i++ ) { + animator->SetJointAxis( shoulderJoints[i], JOINTMOD_WORLD_OVERRIDE, shoulderAxis[i] ); + animator->SetJointAxis( elbowJoints[i], JOINTMOD_WORLD_OVERRIDE, elbowAxis[i] ); + } + + ik_activate = true; +} + +/* +================ +idIK_Reach::ClearJointMods +================ +*/ +void idIK_Reach::ClearJointMods( void ) { + int i; + + if ( !self || !ik_activate ) { + return; + } + + for ( i = 0; i < numArms; i++ ) { + animator->SetJointAxis( shoulderJoints[i], JOINTMOD_NONE, mat3_identity ); + animator->SetJointAxis( elbowJoints[i], JOINTMOD_NONE, mat3_identity ); + animator->SetJointAxis( handJoints[i], JOINTMOD_NONE, mat3_identity ); + } + + ik_activate = false; +} diff --git a/game/IK.h b/game/IK.h new file mode 100644 index 000000000..1a99724fd --- /dev/null +++ b/game/IK.h @@ -0,0 +1,173 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_IK_H__ +#define __GAME_IK_H__ + +/* +=============================================================================== + + IK base class with a simple fast two bone solver. + +=============================================================================== +*/ + +#define IK_ANIM "ik_pose" + +class idIK { +public: + idIK( void ); + virtual ~idIK( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + bool IsInitialized( void ) const; + + virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); + virtual void Evaluate( void ); + virtual void ClearJointMods( void ); + + bool SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos ); + float GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis ); + +protected: + bool initialized; + bool ik_activate; + idEntity * self; // entity using the animated model + idAnimator * animator; // animator on entity + int modifiedAnim; // animation modified by the IK + idVec3 modelOffset; +}; + + +/* +=============================================================================== + + IK controller for a walking character with an arbitrary number of legs. + +=============================================================================== +*/ + +class idIK_Walk : public idIK { +public: + + idIK_Walk( void ); + virtual ~idIK_Walk( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); + virtual void Evaluate( void ); + virtual void ClearJointMods( void ); + + void EnableAll( void ); + void DisableAll( void ); + void EnableLeg( int num ); + void DisableLeg( int num ); + +private: + static const int MAX_LEGS = 8; + + idClipModel * footModel; + + int numLegs; + int enabledLegs; + jointHandle_t footJoints[MAX_LEGS]; + jointHandle_t ankleJoints[MAX_LEGS]; + jointHandle_t kneeJoints[MAX_LEGS]; + jointHandle_t hipJoints[MAX_LEGS]; + jointHandle_t dirJoints[MAX_LEGS]; + jointHandle_t waistJoint; + + idVec3 hipForward[MAX_LEGS]; + idVec3 kneeForward[MAX_LEGS]; + + float upperLegLength[MAX_LEGS]; + float lowerLegLength[MAX_LEGS]; + + idMat3 upperLegToHipJoint[MAX_LEGS]; + idMat3 lowerLegToKneeJoint[MAX_LEGS]; + + float smoothing; + float waistSmoothing; + float footShift; + float waistShift; + float minWaistFloorDist; + float minWaistAnkleDist; + float footUpTrace; + float footDownTrace; + bool tiltWaist; + bool usePivot; + + // state + int pivotFoot; + float pivotYaw; + idVec3 pivotPos; + bool oldHeightsValid; + float oldWaistHeight; + float oldAnkleHeights[MAX_LEGS]; + idVec3 waistOffset; +}; + + +/* +=============================================================================== + + IK controller for reaching a position with an arm or leg. + +=============================================================================== +*/ + +class idIK_Reach : public idIK { +public: + + idIK_Reach( void ); + virtual ~idIK_Reach( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); + virtual void Evaluate( void ); + virtual void ClearJointMods( void ); + +private: + + static const int MAX_ARMS = 2; + + int numArms; + int enabledArms; + jointHandle_t handJoints[MAX_ARMS]; + jointHandle_t elbowJoints[MAX_ARMS]; + jointHandle_t shoulderJoints[MAX_ARMS]; + jointHandle_t dirJoints[MAX_ARMS]; + + idVec3 shoulderForward[MAX_ARMS]; + idVec3 elbowForward[MAX_ARMS]; + + float upperArmLength[MAX_ARMS]; + float lowerArmLength[MAX_ARMS]; + + idMat3 upperArmToShoulderJoint[MAX_ARMS]; + idMat3 lowerArmToElbowJoint[MAX_ARMS]; +}; + +#endif /* !__GAME_IK_H__ */ diff --git a/DarkMod/ImageMapManager.cpp b/game/ImageMapManager.cpp similarity index 92% rename from DarkMod/ImageMapManager.cpp rename to game/ImageMapManager.cpp index f152b268b..fb6553aec 100644 --- a/DarkMod/ImageMapManager.cpp +++ b/game/ImageMapManager.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* Copyright (C) 2011 Tels (Donated to The Dark Mod Team) diff --git a/DarkMod/ImageMapManager.h b/game/ImageMapManager.h similarity index 83% rename from DarkMod/ImageMapManager.h rename to game/ImageMapManager.h index 0cae55fff..fd1f98086 100644 --- a/DarkMod/ImageMapManager.h +++ b/game/ImageMapManager.h @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2011 Tels (Donated to The Dark Mod) @@ -14,7 +24,7 @@ #define __DARKMOD_IMAGEMAPMANAGER_H__ // to get CImage -#include "../DarkMod/CImage.h" +#include "CImage.h" /* =============================================================================== diff --git a/DarkMod/IniFile.cpp b/game/IniFile.cpp similarity index 90% rename from DarkMod/IniFile.cpp rename to game/IniFile.cpp index 752addca2..82ca7114a 100644 --- a/DarkMod/IniFile.cpp +++ b/game/IniFile.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/IniFile.h b/game/IniFile.h similarity index 84% rename from DarkMod/IniFile.h rename to game/IniFile.h index 4e2793829..03bbd3cfc 100644 --- a/DarkMod/IniFile.h +++ b/game/IniFile.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef TDM_INI_FILE_H_ #define TDM_INI_FILE_H_ diff --git a/DarkMod/Intersection.cpp b/game/Intersection.cpp similarity index 95% rename from DarkMod/Intersection.cpp rename to game/Intersection.cpp index 671a7c246..caf81c35c 100644 --- a/DarkMod/Intersection.cpp +++ b/game/Intersection.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -13,7 +23,7 @@ static bool init_version = FileVersionList("$Id$", init_version); // #include "math.h" -#include "../DarkMod/DarkModGlobals.h" +#include "DarkModGlobals.h" #include "Intersection.h" EIntersection IntersectLinesegmentEllipsoid(const idVec3 Segment[LSG_COUNT], diff --git a/DarkMod/Intersection.h b/game/Intersection.h similarity index 82% rename from DarkMod/Intersection.h rename to game/Intersection.h index 07867ef7b..f360ae961 100644 --- a/DarkMod/Intersection.h +++ b/game/Intersection.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /** * This file contains functions to calculate intersections between various diff --git a/DarkMod/Inventory/Category.cpp b/game/Inventory/Category.cpp similarity index 86% rename from DarkMod/Inventory/Category.cpp rename to game/Inventory/Category.cpp index 8e9cb83cf..1052c66cb 100644 --- a/DarkMod/Inventory/Category.cpp +++ b/game/Inventory/Category.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop #pragma warning(disable : 4533 4800) diff --git a/DarkMod/Inventory/Category.h b/game/Inventory/Category.h similarity index 79% rename from DarkMod/Inventory/Category.h rename to game/Inventory/Category.h index 000c5d85e..cbdaf8409 100644 --- a/DarkMod/Inventory/Category.h +++ b/game/Inventory/Category.h @@ -1,15 +1,25 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __DARKMOD_INVENTORYCATEGORY_H__ #define __DARKMOD_INVENTORYCATEGORY_H__ -#include "Item.h" +#include "InventoryItem.h" /** * InventoryCategory is just a container for items that are currently held by an entity. diff --git a/DarkMod/Inventory/Cursor.cpp b/game/Inventory/Cursor.cpp similarity index 91% rename from DarkMod/Inventory/Cursor.cpp rename to game/Inventory/Cursor.cpp index c78f02719..44420dd5f 100644 --- a/DarkMod/Inventory/Cursor.cpp +++ b/game/Inventory/Cursor.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop #pragma warning(disable : 4533 4800) diff --git a/DarkMod/Inventory/Cursor.h b/game/Inventory/Cursor.h similarity index 85% rename from DarkMod/Inventory/Cursor.h rename to game/Inventory/Cursor.h index a5b2524ac..ca81a04fe 100644 --- a/DarkMod/Inventory/Cursor.h +++ b/game/Inventory/Cursor.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __DARKMOD_INVENTORYCURSOR_H__ #define __DARKMOD_INVENTORYCURSOR_H__ diff --git a/DarkMod/Inventory/Inventory.cpp b/game/Inventory/Inventory.cpp similarity index 97% rename from DarkMod/Inventory/Inventory.cpp rename to game/Inventory/Inventory.cpp index 0f633febd..d9be12601 100644 --- a/DarkMod/Inventory/Inventory.cpp +++ b/game/Inventory/Inventory.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop #pragma warning(disable : 4533 4800) @@ -17,7 +27,7 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "Inventory.h" #include "WeaponItem.h" -#include "../game/game_local.h" +#include "../Game_local.h" #include "../Objectives/MissionData.h" #include "../Shop/Shop.h" // grayman (#2376) diff --git a/DarkMod/Inventory/Inventory.h b/game/Inventory/Inventory.h similarity index 93% rename from DarkMod/Inventory/Inventory.h rename to game/Inventory/Inventory.h index 45152b692..f3dfc78dc 100644 --- a/DarkMod/Inventory/Inventory.h +++ b/game/Inventory/Inventory.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __DARKMOD_INVENTORY_H__ #define __DARKMOD_INVENTORY_H__ diff --git a/game/Inventory/InventoryItem.cpp b/game/Inventory/InventoryItem.cpp new file mode 100644 index 000000000..3dcc63a23 --- /dev/null +++ b/game/Inventory/InventoryItem.cpp @@ -0,0 +1,431 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#pragma warning(disable : 4533 4800) + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "InventoryItem.h" +#include "Inventory.h" +#include + +CInventoryItem::CInventoryItem(idEntity *owner) +{ + m_Owner = owner; + m_Item = NULL; + m_Category = NULL; + m_Type = IT_ITEM; + m_LootType = LOOT_NONE; + m_Value = 0; + m_Stackable = false; + m_Count = 1; + m_Droppable = false; + m_Overlay = OVERLAYS_INVALID_HANDLE; + m_Hud = false; + m_Orientated = false; + m_Persistent = false; + m_LightgemModifier = 0; + m_MovementModifier = 1.0f; + m_FrobDistanceCap = -1; + m_UseOnFrob = false; + m_DropOrientation = mat3_identity; +} + +CInventoryItem::CInventoryItem(idEntity* itemEntity, idEntity* owner) { + // Don't allow NULL pointers + assert(owner && itemEntity); + + // Parse a few common spawnargs + ParseSpawnargs(itemEntity->spawnArgs); + + m_Category = NULL; + m_Overlay = OVERLAYS_INVALID_HANDLE; + m_Hud = false; + + m_Owner = owner; + m_Item = itemEntity; + + // Determine and set the loot type + m_LootType = GetLootTypeFromSpawnargs(itemEntity->spawnArgs); + + // Read the spawnargs into the member variables + m_Name = itemEntity->spawnArgs.GetString("inv_name", ""); + // Tels: Replace "\n" with \x0a, otherwise multiline names set inside DR do not work + m_Name.Replace( "\\n", "\n" ); + m_Value = itemEntity->spawnArgs.GetInt("inv_loot_value", "-1"); + m_Stackable = itemEntity->spawnArgs.GetBool("inv_stackable", "0"); + m_UseOnFrob = itemEntity->spawnArgs.GetBool("inv_use_on_frob", "0"); + + m_Count = (m_Stackable) ? itemEntity->spawnArgs.GetInt("inv_count", "1") : 1; + + m_Droppable = itemEntity->spawnArgs.GetBool("inv_droppable", "0"); + m_ItemId = itemEntity->spawnArgs.GetString("inv_item_id", ""); + + if (m_Icon.IsEmpty() && m_LootType == LOOT_NONE) + { + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Information: non-loot item %s has no icon.\r", itemEntity->name.c_str()); + } + + if (m_LootType != LOOT_NONE && m_Value <= 0) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Warning: Value for loot item missing on entity %s\r", itemEntity->name.c_str()); + } + + // Set the item type according to the loot property + m_Type = (m_LootType != LOOT_NONE) ? IT_LOOT : IT_ITEM; + + m_BindMaster = itemEntity->GetBindMaster(); + m_Orientated = itemEntity->fl.bindOrientated; + + idStr hudName; + // Item could be added to the inventory, check for custom HUD + if (itemEntity->spawnArgs.GetString("inv_hud", "", hudName) != false) + { + int hudLayer; + itemEntity->spawnArgs.GetInt("inv_hud_layer", "0", hudLayer); + SetHUD(hudName, hudLayer); + } + + // Check for a preferred drop orientation, if not, use current orientation + if( itemEntity->spawnArgs.FindKey("drop_angles") ) + { + idAngles DropAngles; + DropAngles = itemEntity->spawnArgs.GetAngles("drop_angles"); + m_DropOrientation = DropAngles.ToMat3(); + } + else + { + idVec3 dummy; + idMat3 playerView; + gameLocal.GetLocalPlayer()->GetViewPos(dummy, playerView); + // drop orientation is relative to the player view yaw only + idAngles viewYaw = playerView.ToAngles(); + // ignore pitch and roll + viewYaw[0] = 0; + viewYaw[2] = 0; + idMat3 playerViewYaw = viewYaw.ToMat3(); + + m_DropOrientation = itemEntity->GetPhysics()->GetAxis() * playerViewYaw.Transpose(); + } +} + +void CInventoryItem::Save( idSaveGame *savefile ) const +{ + m_Owner.Save(savefile); + m_Item.Save(savefile); + + savefile->WriteBool(m_ItemDict != NULL); + + if (m_ItemDict != NULL) + { + savefile->WriteDict(m_ItemDict.get()); + } + + m_BindMaster.Save(savefile); + + savefile->WriteString(m_Name); + savefile->WriteString(m_HudName); + savefile->WriteString(m_ItemId); + + savefile->WriteInt(static_cast(m_Type)); + savefile->WriteInt(static_cast(m_LootType)); + + savefile->WriteInt(m_Value); + savefile->WriteInt(m_Overlay); + savefile->WriteInt(m_Count); + + savefile->WriteBool(m_Stackable); + savefile->WriteBool(m_Droppable); + savefile->WriteBool(m_Hud); + + savefile->WriteString(m_Icon); + + savefile->WriteBool(m_Orientated); + savefile->WriteBool(m_Persistent); + + savefile->WriteInt(m_LightgemModifier); + savefile->WriteFloat(m_MovementModifier); + savefile->WriteBool(m_UseOnFrob); + savefile->WriteFloat(m_FrobDistanceCap); + savefile->WriteMat3(m_DropOrientation); +} + +void CInventoryItem::Restore( idRestoreGame *savefile ) +{ + m_Owner.Restore(savefile); + m_Item.Restore(savefile); + + bool hasDict; + savefile->ReadBool(hasDict); + + if (hasDict) + { + m_ItemDict.reset(new idDict); + savefile->ReadDict(m_ItemDict.get()); + } + else + { + m_ItemDict.reset(); + } + + m_BindMaster.Restore(savefile); + + savefile->ReadString(m_Name); + savefile->ReadString(m_HudName); + savefile->ReadString(m_ItemId); + + int tempInt; + savefile->ReadInt(tempInt); + m_Type = static_cast(tempInt); + + savefile->ReadInt(tempInt); + m_LootType = static_cast(tempInt); + + savefile->ReadInt(m_Value); + savefile->ReadInt(m_Overlay); + savefile->ReadInt(m_Count); + + savefile->ReadBool(m_Stackable); + savefile->ReadBool(m_Droppable); + savefile->ReadBool(m_Hud); + + savefile->ReadString(m_Icon); + + savefile->ReadBool(m_Orientated); + savefile->ReadBool(m_Persistent); + + savefile->ReadInt(m_LightgemModifier); + savefile->ReadFloat(m_MovementModifier); + savefile->ReadBool(m_UseOnFrob); + savefile->ReadFloat(m_FrobDistanceCap); + savefile->ReadMat3(m_DropOrientation); +} + +void CInventoryItem::ParseSpawnargs(const idDict& spawnArgs) +{ + m_Persistent = spawnArgs.GetBool("inv_persistent", "0"); + m_LightgemModifier = spawnArgs.GetInt("inv_lgmodifier", "0"); + m_MovementModifier = spawnArgs.GetFloat("inv_movement_modifier", "1"); + m_FrobDistanceCap = spawnArgs.GetFloat("inv_frob_distance_cap", "-1"); + m_Icon = spawnArgs.GetString("inv_icon", ""); +} + +void CInventoryItem::SetLootType(LootType t) +{ + // Only positive values are allowed + if (t >= LOOT_NONE && t <= LOOT_COUNT) + { + m_LootType = t; + } + else + { + m_LootType = LOOT_NONE; + } + + NotifyItemChanged(); +} + +void CInventoryItem::SetValue(int n) +{ + // Only positive values are allowed + if (n >= 0) + { + m_Value = n; + + NotifyItemChanged(); + } +} + +void CInventoryItem::SaveItemEntityDict() +{ + idEntity* ent = GetItemEntity(); + + if (ent == NULL) + { + return; + } + + // We have a non-NULL item entity, save its spawnargs + m_ItemDict.reset(new idDict); + + // Copy spawnargs over + *m_ItemDict = ent->spawnArgs; +} + +void CInventoryItem::RestoreItemEntityFromDict(const idVec3& entPosition) +{ + if (!m_ItemDict) + { + return; // no saved spawnargs, do nothing + } + + // We have an item dictionary, let's respawn our entity + idEntity* ent; + + if (!gameLocal.SpawnEntityDef(*m_ItemDict, &ent)) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Can't respawn inventory item entity '%s'!\r", m_ItemDict->GetString("name")); + gameLocal.Error("Can't respawn inventory item entity '%s'!", m_ItemDict->GetString("name")); + } + + // Place the entity at the given position + ent->SetOrigin(entPosition); + + // Hide the entity (don't delete it) + CInventory::RemoveEntityFromMap(ent, false); + + // Set this as new item entity + SetItemEntity(ent); + + // Finally, remove our saved spawnargs + m_ItemDict.reset(); +} + +const idDict* CInventoryItem::GetSavedItemEntityDict() const +{ + return m_ItemDict ? m_ItemDict.get() : NULL; +} + +void CInventoryItem::SetCount(int n) +{ + // Only positive values are allowed + m_Count = (n >= 0) ? n : 0; + + NotifyItemChanged(); +} + +void CInventoryItem::SetStackable(bool stack) +{ + m_Stackable = stack; +} + +void CInventoryItem::SetHUD(const idStr &HudName, int layer) +{ + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Setting hud %s on layer %d\r", HudName.c_str(), layer); + if (m_Overlay == OVERLAYS_INVALID_HANDLE || m_HudName != HudName) + { + idEntity *owner = GetOwner(); + + m_Hud = true; + m_HudName = HudName; + m_Overlay = owner->CreateOverlay(HudName, layer); + idEntity* it = m_Item.GetEntity(); + if (it != NULL) + { + it->CallScriptFunctionArgs("inventory_item_init", true, 0, "eefs", it, owner, (float)m_Overlay, HudName.c_str()); + } + } + + NotifyItemChanged(); +} + +void CInventoryItem::SetOverlay(const idStr &HudName, int overlay) +{ + if (overlay != OVERLAYS_INVALID_HANDLE) + { + idEntity *owner = GetOwner(); + + m_Hud = true; + m_HudName = HudName; + m_Overlay = overlay; + idEntity* it = m_Item.GetEntity(); + if (it != NULL) + { + it->CallScriptFunctionArgs("inventory_item_init", true, 0, "eefs", it, owner, (float)m_Overlay, HudName.c_str()); + } + } + else + { + m_Hud = false; + } +} + +LootType CInventoryItem::GetLootTypeFromSpawnargs(const idDict& spawnargs) +{ + // Determine the loot type + int lootTypeInt; + LootType returnValue = LOOT_NONE; + + if (spawnargs.GetInt("inv_loot_type", "", lootTypeInt) != false) + { + if (lootTypeInt >= LOOT_NONE && lootTypeInt < LOOT_COUNT) + { + returnValue = static_cast(lootTypeInt); + } + else + { + DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("Invalid loot type: %d\r", lootTypeInt); + } + } + + return returnValue; +} + +int CInventoryItem::GetPersistentCount() +{ + if (m_Persistent) + { + return m_Count; + } + else + { + return 0; + } +} + +void CInventoryItem::SetPersistent(bool newValue) +{ + m_Persistent = newValue; +} + +void CInventoryItem::SetLightgemModifier(int newValue) +{ + // greebo: Clamp the value to [0..1] + m_LightgemModifier = idMath::ClampInt(0, DARKMOD_LG_MAX, newValue); +} + +void CInventoryItem::SetMovementModifier(float newValue) +{ + if (newValue > 0) + { + m_MovementModifier = newValue; + } +} + +void CInventoryItem::SetDropOrientation(const idMat3& newAxis) +{ + m_DropOrientation = newAxis; +} + +void CInventoryItem::SetIcon(const idStr& newIcon) +{ + m_Icon = newIcon; + + NotifyItemChanged(); +} + +void CInventoryItem::NotifyItemChanged() +{ + if (m_Owner.GetEntity() == NULL) return; + + m_Owner.GetEntity()->OnInventoryItemChanged(); +} diff --git a/game/Inventory/InventoryItem.h b/game/Inventory/InventoryItem.h new file mode 100644 index 000000000..933e64fc4 --- /dev/null +++ b/game/Inventory/InventoryItem.h @@ -0,0 +1,220 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __DARKMOD_INVENTORYITEM_H__ +#define __DARKMOD_INVENTORYITEM_H__ + +#include "LootType.h" + +/* FORWARD DECLS */ +class CInventoryCategory; + +/** + * InventoryItem is an item that belongs to a group. + */ +class CInventoryItem +{ +public: + enum ItemType + { + IT_ITEM, // Normal item, which is associated to an entity + IT_LOOT, // this is a loot item + IT_LOOT_INFO, // loot info item + IT_WEAPON, // a weapon item + IT_DUMMY, // This also doesn't have an entity, but provides a dummy so + // we can have an empty space in the inventory. + IT_COUNT + }; + +public: + CInventoryItem(idEntity *m_Owner); + + // Create an inventoryitem out of the given entity and the given owner + CInventoryItem(idEntity* itemEntity, idEntity* owner); + + virtual void Save( idSaveGame *savefile ) const; + virtual void Restore( idRestoreGame *savefile ); + + CInventoryCategory* Category() const { return m_Category; } + void SetCategory(CInventoryCategory* newCategory) { m_Category = newCategory; }; + + idEntity* GetOwner() { return m_Owner.GetEntity(); }; + void SetOwner(idEntity* newOwner) { m_Owner = newOwner; }; + + void SetItemEntity(idEntity *ent) { m_Item = ent; }; + idEntity* GetItemEntity() { return m_Item.GetEntity(); } + + // Stores the item entity's spawnargs locally - used before ending a mission to prepare an item/entity transfer + // Does nothing if the item entity is NULL + virtual void SaveItemEntityDict(); + + // Restores the item entity from the saved dictionary. Does nothing if the saved dictionary is empty. + // The position is needed to place the respawned entity somewhere valid + virtual void RestoreItemEntityFromDict(const idVec3& entPosition); + + // Get a reference to the saved item entity dictionary. Returns NULL if the spawnargs didn't get saved + // This usually returns non-NULL for items stored in the game's persistent inventory, for inter-mission item transfer + const idDict* GetSavedItemEntityDict() const; + + void SetType(CInventoryItem::ItemType type) { m_Type = type; }; + ItemType GetType() { return m_Type; }; + + int GetCount() { return m_Count; }; + void SetCount(int Amount); + + bool IsStackable() { return m_Stackable; }; + void SetStackable(bool); + + void SetDroppable(bool bDroppable) { m_Droppable = bDroppable; }; + bool IsDroppable() { return m_Droppable; }; + + void SetLootType(LootType t); + LootType GetLootType() { return m_LootType; }; + + void SetValue(int n); + int GetValue() { return m_Value; }; + + void SetName(const idStr &n) { m_Name = n; }; + const idStr& GetName() { return m_Name; }; + + void SetItem(idEntity *item) { m_Item = item; }; + idEntity* GetItem() { return m_Item.GetEntity(); }; + + int GetOverlay() { return m_Overlay; }; + void SetOverlay(const idStr &HudName, int Overlay); + bool HasHUD() { return m_Hud; }; + void SetHUD(const idStr &HudName, int layer); + const idStr& GetHUD() { return m_HudName; }; + + const idStr& GetIcon() { return m_Icon; }; + void SetIcon(const idStr& newIcon); + + void SetItemId(const idStr &id) { m_ItemId = id; }; + const idStr& GetItemId() { return m_ItemId; }; + + static LootType GetLootTypeFromSpawnargs(const idDict& spawnargs); + + /** + * greebo: This returns the number of persistent items contained in this InventoryItem. + * For ordinary persistent items, this is always 1, for non-persistent items this is 0. + * Stackable persistent items will return the current stack count. + */ + int GetPersistentCount(); + + bool IsPersistent() const { return m_Persistent; }; + void SetPersistent(bool newValue); + + /** + * greebo: When this item is active, the lightgem can be modified by this value. + * The integer value should be between 0 and DARKMOD_LG_MAX and is added to the + * the result of the lightgem renderpasses. Corresponds to the spawnarg "inv_lgmodifier" + */ + int GetLightgemModifier() { return m_LightgemModifier; } + void SetLightgemModifier(int newValue); + + /** + * greebo: When this item is active, the owner can be encumbered (or even accelerated?) + * by a certain factor. Each item can have its own movement modifier, which is defined + * in the "inv_movement_modifer" spawnarg. + * + * @modifier value range: a floating point variable in [0, INF]. This value is applied to + * the maximum player movement speed by multiplication. + */ + float GetMovementModifier() { return m_MovementModifier; } + void SetMovementModifier(float newValue); + /** + * Get/set the drop orientation + **/ + const idMat3& GetDropOrientation() { return m_DropOrientation; } + void SetDropOrientation(const idMat3& newAxis); + + // Returns true when this item should be used by the 'frob' impulse + bool UseOnFrob() const { return m_UseOnFrob; } + + // Returns the frob distance cap. If this item doesn't enforce such a value, this returns idMath::INFINITY. + float GetFrobDistanceCap() + { + return (m_FrobDistanceCap == -1) ? idMath::INFINITY : m_FrobDistanceCap; + } + +protected: + // Reads the values from the given spawnargs into the member variables + void ParseSpawnargs(const idDict& spawnArgs); + + // Calls the owner's OnInventoryItemChanged() method + void NotifyItemChanged(); + +protected: + idEntityPtr m_Owner; + idEntityPtr m_Item; + + // greebo: Optional item dictionary. This is used to transfer inventory items between missions + // including their item entities. These entities will be saved at mission end and re-spawned at the + // start of the next mission. + boost::shared_ptr m_ItemDict; + + idEntityPtr m_BindMaster; + idStr m_Name; + idStr m_HudName; // filename for the hud file if it has a custom hud + idStr m_ItemId; // Arbitrary Id, that the mapper can use to idenitfy an item. + // It is also needed to identify items which are stackable + // to make them identifiable. This can be used, for example + // to create a fake health potion which shows up in the inventory + // as a regular health potion, but actually deals damage. Needs + // custom scripting to actually do this though. + CInventoryCategory* m_Category; + ItemType m_Type; + LootType m_LootType; + int m_Value; + int m_Overlay; + int m_Count; // How many of that item are currently represented (i.e. Arrows) + bool m_Stackable; // Counter can be used if true, otherwise it's a unique item + bool m_Droppable; // If the item is not dropable it will be inaccessible after it + // is put into the inventory + bool m_Hud; + idStr m_Icon; // The inventory icon string + bool m_Orientated; // Taken from the entity + + bool m_Persistent; // Can be taken to the next map (default is FALSE) + + int m_LightgemModifier; // Is added to the lightgem when this item is active + + // A value in [0,1] defining the fraction of the regular movement speed + // which the owner is allowed to move with when this item is equipped. + float m_MovementModifier; + + /** + * greebo: When this inventory item is selected, the frob distance can not be higher + * than the value defined here. Is -1 if not set. + */ + float m_FrobDistanceCap; + + bool m_UseOnFrob; // Whether this item can be used by the 'frob' button + + /** + * Which way the object should orient itself when dropping + * Relative to the player's view axis (x,y,z = forward,left,up) + * Typically it maintains the same relative orientation to the player + * that it had when the player picked it up. + * Except for pitch, which is the same as its original pitch + **/ + idMat3 m_DropOrientation; +}; +typedef boost::shared_ptr CInventoryItemPtr; + +#endif /* __DARKMOD_INVENTORYITEM_H__ */ diff --git a/game/Inventory/LootType.h b/game/Inventory/LootType.h new file mode 100644 index 000000000..1da729aab --- /dev/null +++ b/game/Inventory/LootType.h @@ -0,0 +1,31 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __DARKMOD_LOOTTYPES_H__ +#define __DARKMOD_LOOTTYPES_H__ + +enum LootType +{ + LOOT_NONE, // No lootobject + LOOT_JEWELS, + LOOT_GOLD, + LOOT_GOODS, + LOOT_COUNT +}; + +#endif diff --git a/DarkMod/Inventory/WeaponItem.cpp b/game/Inventory/WeaponItem.cpp similarity index 87% rename from DarkMod/Inventory/WeaponItem.cpp rename to game/Inventory/WeaponItem.cpp index b2ec4138c..532e8133f 100644 --- a/DarkMod/Inventory/WeaponItem.cpp +++ b/game/Inventory/WeaponItem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop #pragma warning(disable : 4533 4800) diff --git a/DarkMod/Inventory/WeaponItem.h b/game/Inventory/WeaponItem.h similarity index 83% rename from DarkMod/Inventory/WeaponItem.h rename to game/Inventory/WeaponItem.h index b6672bd71..d0ae6dcd7 100644 --- a/DarkMod/Inventory/WeaponItem.h +++ b/game/Inventory/WeaponItem.h @@ -1,15 +1,25 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __DARKMOD_INVENTORYWEAPONITEM_H__ #define __DARKMOD_INVENTORYWEAPONITEM_H__ -#include "Item.h" +#include "InventoryItem.h" /** * WeaponInventoryItem is an item that belongs to a group. This item represents diff --git a/game/Item.cpp b/game/Item.cpp new file mode 100644 index 000000000..ae38daddb --- /dev/null +++ b/game/Item.cpp @@ -0,0 +1,1151 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/** +* TDM: There is absolutely no reason to use this class any more!!! +* All inventory and frob functionality has been moved to idEntity +**/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#pragma warning(disable : 4996) + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "StimResponse/StimResponseCollection.h" +#include "AbsenceMarker.h" + +/* +=============================================================================== + + idItem + +=============================================================================== +*/ + +const idEventDef EV_DropToFloor( "" ); +const idEventDef EV_RespawnItem( "respawn" ); +const idEventDef EV_RespawnFx( "" ); +const idEventDef EV_GetPlayerPos( "" ); +const idEventDef EV_HideObjective( "", "e" ); +const idEventDef EV_CamShot( "" ); + +CLASS_DECLARATION( idEntity, idItem ) + EVENT( EV_DropToFloor, idItem::Event_DropToFloor ) + EVENT( EV_Touch, idItem::Event_Touch ) + EVENT( EV_Activate, idItem::Event_Trigger ) + EVENT( EV_RespawnItem, idItem::Event_Respawn ) + EVENT( EV_RespawnFx, idItem::Event_RespawnFx ) +END_CLASS + + +/* +================ +idItem::idItem +================ +*/ +idItem::idItem() +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); + + spin = false; + inView = false; + inViewTime = 0; + lastCycle = 0; + lastRenderViewTime = -1; + itemShellHandle = -1; + shellMaterial = NULL; + orgOrigin.Zero(); + canPickUp = true; + fl.networkSync = true; + + m_FrobActionScript = "frob_item"; + + noticeabilityIfAbsent = 0.0; + b_orgOriginSet = false; + + +} + +/* +================ +idItem::~idItem +================ +*/ +idItem::~idItem() { + // remove the highlight shell + if ( itemShellHandle != -1 ) { + gameRenderWorld->FreeEntityDef( itemShellHandle ); + } +} + +/* +================ +idItem::Save +================ +*/ +void idItem::Save( idSaveGame *savefile ) const { + + savefile->WriteVec3( orgOrigin ); + savefile->WriteBool( spin ); + savefile->WriteBool( pulse ); + savefile->WriteBool( canPickUp ); + + savefile->WriteMaterial( shellMaterial ); + + savefile->WriteBool( inView ); + savefile->WriteInt( inViewTime ); + savefile->WriteInt( lastCycle ); + savefile->WriteInt( lastRenderViewTime ); + savefile->WriteFloat (noticeabilityIfAbsent); + absenceEntityPtr.Save (savefile); +} + +/* +================ +idItem::Restore +================ +*/ +void idItem::Restore( idRestoreGame *savefile ) { + + savefile->ReadVec3( orgOrigin ); + savefile->ReadBool( spin ); + savefile->ReadBool( pulse ); + savefile->ReadBool( canPickUp ); + + savefile->ReadMaterial( shellMaterial ); + + savefile->ReadBool( inView ); + savefile->ReadInt( inViewTime ); + savefile->ReadInt( lastCycle ); + savefile->ReadInt( lastRenderViewTime ); + savefile->ReadFloat (noticeabilityIfAbsent); + absenceEntityPtr.Restore (savefile); + + itemShellHandle = -1; +} + +/* +================ +idItem::UpdateRenderEntity +================ +*/ +bool idItem::UpdateRenderEntity(renderEntity_s *renderEntity, const renderView_t *renderView) +{ + bool bRc = true; + + if(pulse) + { + if(lastRenderViewTime == renderView->time) + return false; + + lastRenderViewTime = renderView->time; + + // check for glow highlighting if near the center of the view + idVec3 dir = renderEntity->origin - renderView->vieworg; + dir.Normalize(); + float d = dir * renderView->viewaxis[0]; + + // two second pulse cycle + float cycle = ( renderView->time - inViewTime ) / 2000.0f; + + if(d > 0.94f) + { + if(!inView) + { + inView = true; + if(cycle > lastCycle) + { + // restart at the beginning + inViewTime = renderView->time; + cycle = 0.0f; + } + } + } + else + { + if(inView) + { + inView = false; + lastCycle = static_cast(ceil(cycle)); + } + } + + if(!inView && cycle > lastCycle) + { + renderEntity->shaderParms[4] = 0.0f; + } + else + { + // pulse up in 1/4 second + cycle -= (int)cycle; + if ( cycle < 0.1f ) { + renderEntity->shaderParms[4] = cycle * 10.0f; + } else if ( cycle < 0.2f ) { + renderEntity->shaderParms[4] = 1.0f; + } else if ( cycle < 0.3f ) { + renderEntity->shaderParms[4] = 1.0f - ( cycle - 0.2f ) * 10.0f; + } else { + // stay off between pulses + renderEntity->shaderParms[4] = 0.0f; + } + } + } + + // update every single time this is in view + return bRc; +} + + + +/* +================ +idItem::ModelCallback +================ +*/ +bool idItem::ModelCallback( renderEntity_t *renderEntity, const renderView_t *renderView ) +{ + idItem *ent; + + // this may be triggered by a model trace or other non-view related source + if ( !renderView ) + { + return false; + } + + ent = static_cast(gameLocal.entities[ renderEntity->entityNum ]); + if(!ent) + { + gameLocal.Error( "idItem::ModelCallback: callback with NULL game entity" ); + } + + return ent->UpdateRenderEntity( renderEntity, renderView ); +} + +/* +================ +idItem::Think +================ +*/ +void idItem::Think( void ) +{ + if ( thinkFlags & TH_THINK ) + { + if(spin) + { + idAngles ang; + idVec3 org; + + ang.pitch = ang.roll = 0.0f; + ang.yaw = ( gameLocal.time & 4095 ) * 360.0f / -4096.0f; + SetAngles( ang ); + + float scale = 0.005f + entityNumber * 0.00001f; + + org = orgOrigin; + org.z += 4.0f + cos( ( gameLocal.time + 2000 ) * scale ) * 4.0f; + SetOrigin( org ); + } + } + + Present(); +} + +/* +================ +idItem::Present +================ +*/ +void idItem::Present( void ) +{ + idEntity::Present(); + + if(!fl.hidden && pulse) + { + // also add a highlight shell model + renderEntity_t shell; + + shell = renderEntity; + + // we will mess with shader parms when the item is in view + // to give the "item pulse" effect + shell.callback = idItem::ModelCallback; + + shell.entityNum = entityNumber; + shell.customShader = shellMaterial; + if ( itemShellHandle == -1 ) + { + itemShellHandle = gameRenderWorld->AddEntityDef( &shell ); + } + else + { + gameRenderWorld->UpdateEntityDef( itemShellHandle, &shell ); + } + } +} + +/* +================ +idItem::Spawn +================ +*/ +void idItem::Spawn( void ) +{ + idStr giveTo; + idEntity * ent; + float tsize; + + if ( spawnArgs.GetBool( "dropToFloor" ) ) + { + PostEventMS( &EV_DropToFloor, 0 ); + } + + if ( spawnArgs.GetFloat( "triggersize", "0", tsize ) ) { + GetPhysics()->GetClipModel()->LoadModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) ); + GetPhysics()->GetClipModel()->Link( gameLocal.clip ); + } + + if ( spawnArgs.GetBool( "start_off" ) ) + { + GetPhysics()->SetContents( 0 ); + Hide(); + } else + { + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + } + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + giveTo = spawnArgs.GetString( "owner" ); + if ( giveTo.Length() ) + { + ent = gameLocal.FindEntity( giveTo ); + if ( !ent ) + { + gameLocal.Error( "Item couldn't find owner '%s'", giveTo.c_str() ); + } + PostEventMS( &EV_Touch, 0, ent, 0 ); + } + + if ( spawnArgs.GetBool( "spin" ) || gameLocal.isMultiplayer ) + { + spin = true; + BecomeActive( TH_THINK ); + } + + //pulse = !spawnArgs.GetBool( "nopulse" ); + //temp hack for tim + pulse = false; + orgOrigin = GetPhysics()->GetOrigin(); + b_orgOriginSet = true; + + noticeabilityIfAbsent = spawnArgs.GetFloat("noticeabilityIfAbsent"); + + + canPickUp = !( spawnArgs.GetBool( "triggerFirst" ) || spawnArgs.GetBool( "no_touch" ) ); + + inViewTime = -1000; + lastCycle = -1; + itemShellHandle = -1; + shellMaterial = declManager->FindMaterial( "itemHighlightShell" ); + + // What team owns it? + spawnArgs.GetInt ("ownerTeam", "0", ownerTeam); +} + +/* +================ +idItem::GetAttributes +================ +*/ +void idItem::GetAttributes( idDict &attributes ) +{ + int i; + const idKeyValue *arg; + + int num = spawnArgs.GetNumKeyVals(); + for( i = 0; i < num; i++ ) { + arg = spawnArgs.GetKeyVal( i ); + if ( arg->GetKey().Cmpn( "inv_", 4 ) ) { + attributes.Set( arg->GetKey().Right( arg->GetKey().Length() - 4 ), arg->GetValue() ); + } + } +} + +/* +================ +idItem::GiveToPlayer +================ +*/ +bool idItem::GiveToPlayer( idPlayer *player ) +{ + if ( player == NULL ) + { + return false; + } + + // greebo: Inventory Items are not handled here. InvItems should be added to the inventory + // by calling AddToInventory(). + + /*if ( spawnArgs.GetBool( "inv_carry" ) ) + { + return player->GiveInventoryItem( &spawnArgs ); + }*/ + + return false;//player->GiveItem( this ); +} + + +/* +================ +TDM: Darkmod spawns an absence marker entity +================ + +bool idItem::spawnAbsenceMarkerEntity() +{ + const char* pstr_markerDefName = "atdm:absence_marker"; + const idDict *p_markerDef = gameLocal.FindEntityDefDict( pstr_markerDefName, false ); + if( p_markerDef ) + { + idEntity *ent2; + gameLocal.SpawnEntityDef( *p_markerDef, &ent2, false ); + + if ( !ent2 || !ent2->IsType( AbsenceMarker::Type ) ) + { + gameLocal.Error( "Failed to spawn absence marker entity" ); + return false; + } + + AbsenceMarker* p_absenceMarker = static_cast( ent2 ); + + // The absence marker has been created + absenceEntityPtr = p_absenceMarker; + + // Initialize it + idEntityPtr thisPtr; + thisPtr = ((idEntity*) this); + idMat3 orgOrientation; + orgOrientation.Identity(); + + p_absenceMarker->Init(); + if (!p_absenceMarker->initAbsenceReference (thisPtr, orgOrigin, orgOrientation)) + { + gameLocal.Error( "Failed to initialize absence reference in absence marker entity" ); + return false; + } + } + else + { + gameLocal.Error( "Failed to find definition of absence marker entity " ); + return false; + } + + // Success + return true; + +} +*/ +/* +================ +TDM: Darkmod destroys an absence marker entity +================ + +void idItem::destroyAbsenceMarkerEntity() +{ + if (absenceEntityPtr.IsValid()) + { + AbsenceMarker* p_absenceMarker = static_cast( absenceEntityPtr.GetEntity() ); + delete p_absenceMarker; + absenceEntityPtr = NULL; + } +} +*/ +/* +================ +TDM: Darkmod checks if origin changed to create absence marker entity +idItem::UpdateVisuals +================ +*/ +void idItem::UpdateVisuals() +{ + // Call base class version + idEntity::UpdateVisuals(); + + // If we have not already spawned our absence entity and we are interested in spawning + // one if the item moves + if + ( + (noticeabilityIfAbsent > 0.0) && + (!absenceEntityPtr.IsValid()) + ) + if + ( + ( (b_orgOriginSet) && (GetPhysics()->GetOrigin() != orgOrigin) ) || + ( IsHidden() ) + ) + { + // Spawn an absence entity + // spawnAbsenceMarkerEntity(); + + } + // End has been moved, should be noticed, no absence marker spawned yet + else if + ( + (noticeabilityIfAbsent > 0.0) && + (absenceEntityPtr.IsValid()) && + (b_orgOriginSet) && + ((GetPhysics()->GetOrigin() -orgOrigin).LengthFast() < 256.0) + ) // End should be noticed, absence marker spawned, it was put back + { + // Destroy the absence marker entity + // destroyAbsenceMarkerEntity(); + } + + +} + +/* +================ +idItem::Pickup +================ +*/ +bool idItem::Pickup( idPlayer *player ) +{ + if ( !GiveToPlayer( player ) ) + { + return false; + } + + if ( gameLocal.isServer ) + { + ServerSendEvent( EVENT_PICKUP, NULL, false, -1 ); + } + + // play pickup sound + StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL ); + + // trigger our targets + ActivateTargets( player ); + + // clear our contents so the object isn't picked up twice + GetPhysics()->SetContents( 0 ); + + // hide the model + Hide(); + + // add the highlight shell + if ( itemShellHandle != -1 ) + { + gameRenderWorld->FreeEntityDef( itemShellHandle ); + itemShellHandle = -1; + } + + // Spawn an absence marker entity + // spawnAbsenceMarkerEntity(); + + float respawn = spawnArgs.GetFloat( "respawn" ); + bool dropped = spawnArgs.GetBool( "dropped" ); + bool no_respawn = spawnArgs.GetBool( "no_respawn" ); + + if ( gameLocal.isMultiplayer && respawn == 0.0f ) { + respawn = 20.0f; + } + + if ( respawn && !dropped && !no_respawn ) { + const char *sfx = spawnArgs.GetString( "fxRespawn" ); + if ( sfx && *sfx ) { + PostEventSec( &EV_RespawnFx, respawn - 0.5f ); + } + PostEventSec( &EV_RespawnItem, respawn ); + } else if ( !spawnArgs.GetBool( "inv_objective" ) && !no_respawn ) { + // give some time for the pickup sound to play + // FIXME: Play on the owner + if ( !spawnArgs.GetBool( "inv_carry" ) ) { + PostEventMS( &EV_Remove, 5000 ); + } + } + + BecomeInactive( TH_THINK ); + return true; +} + +/* +================ +idItem::ClientPredictionThink +================ +*/ +void idItem::ClientPredictionThink( void ) { + // only think forward because the state is not synced through snapshots + if ( !gameLocal.isNewFrame ) { + return; + } + Think(); +} + +/* +================ +idItem::WriteFromSnapshot +================ +*/ +void idItem::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteBits( IsHidden(), 1 ); +} + +/* +================ +idItem::ReadFromSnapshot +================ +*/ +void idItem::ReadFromSnapshot( const idBitMsgDelta &msg ) { + if ( msg.ReadBits( 1 ) ) { + Hide(); + } else { + Show(); + } +} + +/* +================ +idItem::ClientReceiveEvent +================ +*/ +bool idItem::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + + switch( event ) { + case EVENT_PICKUP: { + + // play pickup sound + StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL ); + + // hide the model + Hide(); + + // remove the highlight shell + if ( itemShellHandle != -1 ) { + gameRenderWorld->FreeEntityDef( itemShellHandle ); + itemShellHandle = -1; + } + return true; + } + case EVENT_RESPAWN: { + Event_Respawn(); + return true; + } + case EVENT_RESPAWNFX: { + Event_RespawnFx(); + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +================ +idItem::Event_DropToFloor +================ +*/ +void idItem::Event_DropToFloor( void ) { + trace_t trace; + + // don't drop the floor if bound to another entity + if ( GetBindMaster() != NULL && GetBindMaster() != this ) { + return; + } + + gameLocal.clip.TraceBounds( trace, renderEntity.origin, renderEntity.origin - idVec3( 0, 0, 64 ), renderEntity.bounds, MASK_SOLID | CONTENTS_CORPSE, this ); + SetOrigin( trace.endpos ); +} + +/* +================ +idItem::Event_Touch +================ +*/ +void idItem::Event_Touch( idEntity *other, trace_t *trace ) { + // only allow touches from the player + if ( !other->IsType( idPlayer::Type ) ) { + return; + } + + if ( !canPickUp ) { + return; + } + + Pickup( static_cast(other) ); +} + +/* +================ +idItem::Event_Trigger +================ +*/ +void idItem::Event_Trigger( idEntity *activator ) { + + if ( !canPickUp && spawnArgs.GetBool( "triggerFirst" ) ) { + canPickUp = true; + return; + } + + if ( activator && activator->IsType( idPlayer::Type ) ) { + Pickup( static_cast( activator ) ); + } +} + +/* +================ +idItem::Event_Respawn +================ +*/ +void idItem::Event_Respawn( void ) { + if ( gameLocal.isServer ) { + ServerSendEvent( EVENT_RESPAWN, NULL, false, -1 ); + } + BecomeActive( TH_THINK ); + Show(); + inViewTime = -1000; + lastCycle = -1; + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + SetOrigin( orgOrigin ); + StartSound( "snd_respawn", SND_CHANNEL_ITEM, 0, false, NULL ); + CancelEvents( &EV_RespawnItem ); // don't double respawn +} + +/* +================ +idItem::Event_RespawnFx +================ +*/ +void idItem::Event_RespawnFx( void ) { + if ( gameLocal.isServer ) { + ServerSendEvent( EVENT_RESPAWNFX, NULL, false, -1 ); + } + const char *sfx = spawnArgs.GetString( "fxRespawn" ); + if ( sfx && *sfx ) { + idEntityFx::StartFx( sfx, NULL, NULL, this, true ); + } +} + +/* +=============================================================================== + + idMoveableItem + +=============================================================================== +*/ + +CLASS_DECLARATION( idItem, idMoveableItem ) + EVENT( EV_DropToFloor, idMoveableItem::Event_DropToFloor ) + EVENT( EV_Gib, idMoveableItem::Event_Gib ) +END_CLASS + +/* +================ +idMoveableItem::idMoveableItem +================ +*/ +idMoveableItem::idMoveableItem() { + trigger = NULL; + smoke = NULL; + smokeTime = 0; +} + +/* +================ +idMoveableItem::~idMoveableItem +================ +*/ +idMoveableItem::~idMoveableItem() { + if ( trigger ) { + delete trigger; + } +} + +/* +================ +idMoveableItem::Save +================ +*/ +void idMoveableItem::Save( idSaveGame *savefile ) const { + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteClipModel( trigger ); + + savefile->WriteParticle( smoke ); + savefile->WriteInt( smokeTime ); +} + +/* +================ +idMoveableItem::Restore +================ +*/ +void idMoveableItem::Restore( idRestoreGame *savefile ) { + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadClipModel( trigger ); + + savefile->ReadParticle( smoke ); + savefile->ReadInt( smokeTime ); +} + +/* +================ +idMoveableItem::Spawn +================ +*/ +void idMoveableItem::Spawn( void ) +{ + idTraceModel trm; + float density, friction, air_friction_linear, air_friction_angular, bouncyness, tsize; + idStr clipModelName; + idBounds bounds, FrobBounds; + idTraceModel FrobTrm; + int numSides(0); + + // create a frob box separate from the collision box for easier frobbing + // First check if frobbox_mins and frobbox_maxs are set + if ( spawnArgs.GetVector( "frobbox_mins", NULL, FrobBounds[0] ) && + spawnArgs.GetVector( "frobbox_maxs", NULL, FrobBounds[1] ) ) + { + if ( FrobBounds[0][0] > FrobBounds[1][0] || FrobBounds[0][1] >FrobBounds[1][1] || FrobBounds[0][2] > FrobBounds[1][2] ) + { + gameLocal.Error( "Invalid frob box bounds '%s'-'%s' on entity '%s'", FrobBounds[0].ToString(), FrobBounds[1].ToString(), name.c_str() ); + } + } + else + { + spawnArgs.GetFloat( "frobbox_size", "10.0", tsize ); + FrobBounds.Zero(); + FrobBounds.ExpandSelf( tsize ); + } + + if ( spawnArgs.GetInt( "frobbox_cylinder", "0", numSides ) && numSides > 0 ) { + FrobTrm.SetupCylinder( FrobBounds, numSides < 3 ? 3 : numSides ); + } else if ( spawnArgs.GetInt( "frobbox_cone", "0", numSides ) && numSides > 0 ) { + FrobTrm.SetupCone( FrobBounds, numSides < 3 ? 3 : numSides ); + } else { + FrobTrm.SetupBox( FrobBounds ); + } + + // Initialize frob bounds based on previous spawnarg setup + trigger = new idClipModel( FrobTrm ); + trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + trigger->SetContents( CONTENTS_FROBABLE ); + + // check if a clip model is set + spawnArgs.GetString( "clipmodel", "", clipModelName ); + if ( !clipModelName[0] ) { + clipModelName = spawnArgs.GetString( "model" ); // use the visual model + } + + // load the trace model + if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { + gameLocal.Error( "idMoveableItem '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() ); + return; + } + + // if the model should be shrinked + if ( spawnArgs.GetBool( "clipshrink" ) ) { + trm.Shrink( CM_CLIP_EPSILON ); + } + + // get rigid body properties + spawnArgs.GetFloat( "density", "0.5", density ); + density = idMath::ClampFloat( 0.001f, 1000.0f, density ); + spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness ); + bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); + + spawnArgs.GetFloat( "friction", "0.05", friction ); + // reverse compatibility, new contact_friction key replaces friction only if present + if( spawnArgs.FindKey("contact_friction") ) + { + spawnArgs.GetFloat( "contact_friction", "0.05", friction ); + } + spawnArgs.GetFloat( "linear_friction", "0.6", air_friction_linear ); + spawnArgs.GetFloat( "angular_friction", "0.6", air_friction_angular ); + + // setup the physics + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( trm ), density ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetBouncyness( bouncyness ); + physicsObj.SetFriction( air_friction_linear, air_friction_angular, friction ); + physicsObj.SetGravity( gameLocal.GetGravity() ); + physicsObj.SetContents( CONTENTS_RENDERMODEL ); + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); + + // greebo: Allow the entityDef to override the clipmodel contents + if( spawnArgs.FindKey( "clipmodel_contents" ) ) + { + physicsObj.SetContents( spawnArgs.GetInt("clipmodel_contents") ); + } + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + SetPhysics( &physicsObj ); + + smoke = NULL; + smokeTime = 0; + const char *smokeName = spawnArgs.GetString( "smoke_trail" ); + if ( *smokeName != '\0' ) { + smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + smokeTime = gameLocal.time; + BecomeActive( TH_UPDATEPARTICLES ); + } +} + +/* +================ +idMoveableItem::Think +================ +*/ +void idMoveableItem::Think( void ) { + + RunPhysics(); + + if ( thinkFlags & TH_PHYSICS ) { + // update trigger position + trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity ); + } + + if ( thinkFlags & TH_UPDATEPARTICLES ) { + if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { + smokeTime = 0; + BecomeInactive( TH_UPDATEPARTICLES ); + } + } + + Present(); +} + +/* +================ +idMoveableItem::Pickup +================ +*/ +bool idMoveableItem::Pickup( idPlayer *player ) { + bool ret = idItem::Pickup( player ); + if ( ret ) { + trigger->SetContents( 0 ); + } + return ret; +} + +/* +================ +idMoveableItem::DropItem +================ +*/ +idEntity *idMoveableItem::DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay ) { + idDict args; + idEntity *item; + + args.Set( "classname", classname ); + args.Set( "dropped", "1" ); + + // we sometimes drop idMoveables here, so set 'nodrop' to 1 so that it doesn't get put on the floor + args.Set( "nodrop", "1" ); + + if ( activateDelay ) { + args.SetBool( "triggerFirst", true ); + } + + gameLocal.SpawnEntityDef( args, &item ); + if ( item ) { + // set item position + item->GetPhysics()->SetOrigin( origin ); + item->GetPhysics()->SetAxis( axis ); + item->GetPhysics()->SetLinearVelocity( velocity ); + item->UpdateVisuals(); + if ( activateDelay ) { + item->PostEventMS( &EV_Activate, activateDelay, item ); + } + +/** +* TDM: Do not automatically remove dropped items +* (Original Id code automatically removed it after 5 minutes) +**/ + if ( removeDelay ) + { + item->PostEventMS( &EV_Remove, removeDelay ); + } + } + return item; +} + +/* +================ +idMoveableItem::DropItems + + The entity should have the following key/value pairs set: + "def_dropItem" "item def" + "dropItemJoint" "joint name" + "dropItemRotation" "pitch yaw roll" + "dropItemOffset" "x y z" + "skin_drop" "skin name" + To drop multiple items the following key/value pairs can be used: + "def_dropItem" "item def" + "dropItemJoint" "joint name" + "dropItemRotation" "pitch yaw roll" + "dropItemOffset" "x y z" + where is an aribtrary string. +================ +*/ +void idMoveableItem::DropItems( idAnimatedEntity *ent, const char *type, idList *list ) { + const idKeyValue *kv; + const char *skinName, *c, *jointName; + idStr key, key2; + idVec3 origin; + idMat3 axis; + idAngles angles; + const idDeclSkin *skin; + jointHandle_t joint; + idEntity *item; + + // drop all items + kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), NULL ); + while ( kv ) { + + c = kv->GetKey().c_str() + kv->GetKey().Length(); + if ( idStr::Icmp( c - 5, "Joint" ) != 0 && idStr::Icmp( c - 8, "Rotation" ) != 0 ) { + + key = kv->GetKey().c_str() + 4; + key2 = key; + key += "Joint"; + key2 += "Offset"; + jointName = ent->spawnArgs.GetString( key ); + joint = ent->GetAnimator()->GetJointHandle( jointName ); + if ( !ent->GetJointWorldTransform( joint, gameLocal.time, origin, axis ) ) { + gameLocal.Warning( "%s refers to invalid joint '%s' on entity '%s'\n", key.c_str(), jointName, ent->name.c_str() ); + origin = ent->GetPhysics()->GetOrigin(); + axis = ent->GetPhysics()->GetAxis(); + } + if ( g_dropItemRotation.GetString()[0] ) { + angles.Zero(); + sscanf( g_dropItemRotation.GetString(), "%f %f %f", &angles.pitch, &angles.yaw, &angles.roll ); + } else { + key = kv->GetKey().c_str() + 4; + key += "Rotation"; + ent->spawnArgs.GetAngles( key, "0 0 0", angles ); + } + axis = angles.ToMat3() * axis; + + origin += ent->spawnArgs.GetVector( key2, "0 0 0" ); + + item = DropItem( kv->GetValue(), origin, axis, vec3_origin, 0, 0 ); + if ( list && item ) { + list->Append( item ); + } + } + + kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), kv ); + } + + // change the skin to hide all items + skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) ); + if ( skinName[0] ) { + skin = declManager->FindSkin( skinName ); + ent->SetSkin( skin ); + } +} + +/* +====================== +idMoveableItem::WriteToSnapshot +====================== +*/ +void idMoveableItem::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); +} + +/* +====================== +idMoveableItem::ReadFromSnapshot +====================== +*/ +void idMoveableItem::ReadFromSnapshot( const idBitMsgDelta &msg ) { + physicsObj.ReadFromSnapshot( msg ); + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + +/* +============ +idMoveableItem::Gib +============ +*/ +void idMoveableItem::Gib( const idVec3 &dir, const char *damageDefName ) { + // spawn smoke puff + const char *smokeName = spawnArgs.GetString( "smoke_gib" ); + if ( *smokeName != '\0' ) { + const idDeclParticle *smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + gameLocal.smokeParticles->EmitSmoke( smoke, gameLocal.time, gameLocal.random.CRandomFloat(), renderEntity.origin, renderEntity.axis ); + } + // remove the entity + PostEventMS( &EV_Remove, 0 ); +} + +/* +================ +idMoveableItem::Event_DropToFloor +================ +*/ +void idMoveableItem::Event_DropToFloor( void ) { + // the physics will drop the moveable to the floor +} + +/* +============ +idMoveableItem::Event_Gib +============ +*/ +void idMoveableItem::Event_Gib( const char *damageDefName ) { + Gib( idVec3( 0, 0, 1 ), damageDefName ); +} + +void idMoveableItem::Hide( void ) +{ + idEntity::Hide(); + physicsObj.SetContents( 0 ); + trigger->SetContents( 0 ); +} + +void idMoveableItem::Show( void ) +{ + idEntity::Show(); + physicsObj.SetContents( m_preHideContents ); + + trigger->SetContents( CONTENTS_FROBABLE ); +} + diff --git a/game/Item.h b/game/Item.h new file mode 100644 index 000000000..7bfe50b90 --- /dev/null +++ b/game/Item.h @@ -0,0 +1,142 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_ITEM_H__ +#define __GAME_ITEM_H__ + + +/* +=============================================================================== + + Items the player can pick up or use. + +=============================================================================== +*/ + +class idItem : public idEntity { +public: + CLASS_PROTOTYPE( idItem ); + + idItem(); + virtual ~idItem(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + void GetAttributes( idDict &attributes ); + virtual bool GiveToPlayer( idPlayer *player ); + virtual bool Pickup( idPlayer *player ); + virtual void Think( void ); + virtual void Present(); + + + enum { + EVENT_PICKUP = idEntity::EVENT_MAXEVENTS, + EVENT_RESPAWN, + EVENT_RESPAWNFX, + EVENT_MAXEVENTS + }; + + virtual void ClientPredictionThink( void ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + // networking + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + // TDM: SZ: UpdateVisuals is overridden to check if the object moved in case + // we have to spawn an absence entity + virtual void UpdateVisuals( void ); + + // This indicates which team owns the item (or thinks it does :P ) + int ownerTeam; + +private: + idVec3 orgOrigin; + bool spin; + bool pulse; + bool canPickUp; + + // This should scale from 0.0 (none) to 1.0 (hard to miss) + float noticeabilityIfAbsent; + + + // Has the original origin been set? + bool b_orgOriginSet; + idEntityPtr absenceEntityPtr; + + // for item pulse effect + int itemShellHandle; + const idMaterial * shellMaterial; + + // used to update the item pulse effect + mutable bool inView; + mutable int inViewTime; + mutable int lastCycle; + mutable int lastRenderViewTime; + + bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); + static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); + + void Event_DropToFloor( void ); + void Event_Touch( idEntity *other, trace_t *trace ); + void Event_Trigger( idEntity *activator ); + void Event_Respawn( void ); + void Event_RespawnFx( void ); +}; + + +class idMoveableItem : public idItem { +public: + CLASS_PROTOTYPE( idMoveableItem ); + + idMoveableItem(); + virtual ~idMoveableItem(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + virtual void Think( void ); + virtual bool Pickup( idPlayer *player ); + + static void DropItems( idAnimatedEntity *ent, const char *type, idList *list ); + static idEntity * DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + +protected: + void Hide(); + void Show(); + +private: + idPhysics_RigidBody physicsObj; + idClipModel * trigger; + const idDeclParticle * smoke; + int smokeTime; + + void Gib( const idVec3 &dir, const char *damageDefName ); + + void Event_DropToFloor( void ); + void Event_Gib( const char *damageDefName ); +}; + +#endif /* !__GAME_ITEM_H__ */ diff --git a/game/Light.cpp b/game/Light.cpp new file mode 100644 index 000000000..44c8ab3f9 --- /dev/null +++ b/game/Light.cpp @@ -0,0 +1,2062 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "StimResponse/StimResponseCollection.h" +#include "Grabber.h" + +/* +=============================================================================== + + idLight + +=============================================================================== +*/ + +const idEventDef EV_Light_SetShader( "setShader", "s" ); +const idEventDef EV_Light_GetLightParm( "getLightParm", "d", 'f' ); +const idEventDef EV_Light_SetLightParm( "setLightParm", "df" ); +const idEventDef EV_Light_SetLightParms( "setLightParms", "ffff" ); +const idEventDef EV_Light_SetRadiusXYZ( "setRadiusXYZ", "fff" ); +const idEventDef EV_Light_SetRadius( "setRadius", "f" ); +const idEventDef EV_Light_On( "On", NULL ); +const idEventDef EV_Light_Off( "Off", NULL ); +const idEventDef EV_Light_FadeOut( "fadeOutLight", "f" ); +const idEventDef EV_Light_FadeIn( "fadeInLight", "f" ); + +// TDM Additions: +const idEventDef EV_Light_GetLightOrigin( "getLightOrigin", NULL, 'v' ); +const idEventDef EV_Light_SetLightOrigin( "setLightOrigin", "v" ); +const idEventDef EV_Light_GetLightLevel ("getLightLevel", NULL, 'f'); +const idEventDef EV_Light_AddToLAS("addToLAS", NULL); +const idEventDef EV_Light_FadeToLight( "fadeToLight", "vf" ); +const idEventDef EV_Smoking("smoking", "d"); +const idEventDef EV_SetStartedOff("setStartedOff", NULL); // grayman #2905 + + +CLASS_DECLARATION( idEntity, idLight ) + EVENT( EV_Light_SetShader, idLight::Event_SetShader ) + EVENT( EV_Light_GetLightParm, idLight::Event_GetLightParm ) + EVENT( EV_Light_SetLightParm, idLight::Event_SetLightParm ) + EVENT( EV_Light_SetLightParms, idLight::Event_SetLightParms ) + EVENT( EV_Light_SetRadiusXYZ, idLight::Event_SetRadiusXYZ ) + EVENT( EV_Light_SetRadius, idLight::Event_SetRadius ) + EVENT( EV_Hide, idLight::Event_Hide ) + EVENT( EV_Show, idLight::Event_Show ) + EVENT( EV_Light_On, idLight::Event_On ) + EVENT( EV_Light_Off, idLight::Event_Off ) + EVENT( EV_Activate, idLight::Event_ToggleOnOff ) + EVENT( EV_PostSpawn, idLight::Event_SetSoundHandles ) + EVENT( EV_Light_FadeOut, idLight::Event_FadeOut ) + EVENT( EV_Light_FadeIn, idLight::Event_FadeIn ) + + EVENT( EV_Light_SetLightOrigin, idLight::Event_SetLightOrigin ) + EVENT( EV_Light_GetLightOrigin, idLight::Event_GetLightOrigin ) + EVENT( EV_Light_GetLightLevel, idLight::Event_GetLightLevel ) + EVENT( EV_Light_AddToLAS, idLight::Event_AddToLAS ) + EVENT( EV_InPVS, idLight::Event_InPVS ) + EVENT( EV_Light_FadeToLight, idLight::Event_FadeToLight ) + EVENT( EV_Smoking, idLight::Event_Smoking ) // grayman #2603 + EVENT( EV_SetStartedOff, idLight::Event_SetStartedOff ) // grayman #2905 +END_CLASS + + +/* +================ +idGameEdit::ParseSpawnArgsToRenderLight + +parse the light parameters +this is the canonical renderLight parm parsing, +which should be used by dmap and the editor +================ +*/ +void idGameEdit::ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight ) { + bool gotTarget, gotUp, gotRight; + const char *texture; + idVec3 color; + + memset( renderLight, 0, sizeof( *renderLight ) ); + + if (!args->GetVector("light_origin", "", renderLight->origin)) { + args->GetVector( "origin", "", renderLight->origin ); + } + + gotTarget = args->GetVector( "light_target", "", renderLight->target ); + gotUp = args->GetVector( "light_up", "", renderLight->up ); + gotRight = args->GetVector( "light_right", "", renderLight->right ); + args->GetVector( "light_start", "0 0 0", renderLight->start ); + if ( !args->GetVector( "light_end", "", renderLight->end ) ) { + renderLight->end = renderLight->target; + } + + // we should have all of the target/right/up or none of them + if ( ( gotTarget || gotUp || gotRight ) != ( gotTarget && gotUp && gotRight ) ) { + gameLocal.Printf( "Light at (%f,%f,%f) has bad target info\n", + renderLight->origin[0], renderLight->origin[1], renderLight->origin[2] ); + return; + } + + if ( !gotTarget ) { + renderLight->pointLight = true; + + // allow an optional relative center of light and shadow offset + args->GetVector( "light_center", "0 0 0", renderLight->lightCenter ); + + // create a point light + if (!args->GetVector( "light_radius", "300 300 300", renderLight->lightRadius ) ) { + float radius; + + args->GetFloat( "light", "300", radius ); + renderLight->lightRadius[0] = renderLight->lightRadius[1] = renderLight->lightRadius[2] = radius; + } + } + + // get the rotation matrix in either full form, or single angle form + idAngles angles; + idMat3 mat; + if ( !args->GetMatrix( "light_rotation", "1 0 0 0 1 0 0 0 1", mat ) ) { + if ( !args->GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", mat ) ) { + args->GetFloat( "angle", "0", angles[ 1 ] ); + angles[ 0 ] = 0; + angles[ 1 ] = idMath::AngleNormalize360( angles[ 1 ] ); + angles[ 2 ] = 0; + mat = angles.ToMat3(); + } + } + + // fix degenerate identity matrices + mat[0].FixDegenerateNormal(); + mat[1].FixDegenerateNormal(); + mat[2].FixDegenerateNormal(); + + renderLight->axis = mat; + + // check for other attributes + args->GetVector( "_color", "1 1 1", color ); + renderLight->shaderParms[ SHADERPARM_RED ] = color[0]; + renderLight->shaderParms[ SHADERPARM_GREEN ] = color[1]; + renderLight->shaderParms[ SHADERPARM_BLUE ] = color[2]; + args->GetFloat( "shaderParm3", "1", renderLight->shaderParms[ SHADERPARM_TIMESCALE ] ); + if ( !args->GetFloat( "shaderParm4", "0", renderLight->shaderParms[ SHADERPARM_TIMEOFFSET ] ) ) { + // offset the start time of the shader to sync it to the game time + renderLight->shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + } + + args->GetFloat( "shaderParm5", "0", renderLight->shaderParms[5] ); + args->GetFloat( "shaderParm6", "0", renderLight->shaderParms[6] ); + args->GetFloat( "shaderParm7", "0", renderLight->shaderParms[ SHADERPARM_MODE ] ); + args->GetBool( "noshadows", "0", renderLight->noShadows ); + args->GetBool( "nospecular", "0", renderLight->noSpecular ); + args->GetBool( "parallel", "0", renderLight->parallel ); + + args->GetString( "texture", "lights/squarelight1", &texture ); + // allow this to be NULL + renderLight->shader = declManager->FindMaterial( texture, false ); +} + +/* +================ +idLight::UpdateChangeableSpawnArgs +================ +*/ +void idLight::UpdateChangeableSpawnArgs( const idDict *source ) { + + idEntity::UpdateChangeableSpawnArgs( source ); + + if ( source ) { + source->Print(); + } + FreeSoundEmitter( true ); + gameEdit->ParseSpawnArgsToRefSound( source ? source : &spawnArgs, &refSound ); + if ( refSound.shader && !refSound.waitfortrigger ) { + StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); + } + + gameEdit->ParseSpawnArgsToRenderLight( source ? source : &spawnArgs, &renderLight ); + + UpdateVisuals(); +} + +/* +================ +idLight::idLight +================ +*/ +idLight::idLight() +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX %s\r", this, __FUNCTION__); + + memset( &renderLight, 0, sizeof( renderLight ) ); + localLightOrigin = vec3_zero; + localLightAxis = mat3_identity; + lightDefHandle = -1; + levels = 0; + currentLevel = 0; + baseColor = vec3_zero; + breakOnTrigger = false; + count = 0; + triggercount = 0; + lightParent = NULL; + switchList.Clear(); // grayman #2603 - list of my switches + beingRelit = false; // grayman #2603 + chanceNegativeBark = 1.0f; // grayman #2603 + whenTurnedOff = 0; // grayman #2603 + nextTimeLightOutBark = 0; // grayman #2603 + relightAfter = 0; // grayman #2603 + aiBarks.Clear(); // grayman #2603 + + fadeFrom.Set( 1, 1, 1, 1 ); + fadeTo.Set( 1, 1, 1, 1 ); + fadeStart = 0; + fadeEnd = 0; + soundWasPlaying = false; + m_MaxLightRadius = 0.0f; + m_LightMaterial = NULL; + + /*! + Darkmod LAS + */ + LASAreaIndex = -1; + +} + +/* +================ +idLight::~idLight +================ +*/ +idLight::~idLight() +{ + if ( lightDefHandle != -1 ) { + gameRenderWorld->FreeLightDef( lightDefHandle ); + } + + /*! + * Darkmod LAS + */ + // Remove light from LAS + if (LASAreaIndex != -1) + { + LAS.removeLight(this); + } + + /*! + Darkmod player lighting + */ + idPlayer* player = gameLocal.GetLocalPlayer(); + if (player != NULL) + { + player->RemoveLight(this); + } +} + +/* +================ +idLight::Save + +archives object for save game file +================ +*/ +void idLight::Save( idSaveGame *savefile ) const { + savefile->WriteRenderLight( renderLight ); + + savefile->WriteBool( renderLight.prelightModel != NULL ); + + savefile->WriteVec3( localLightOrigin ); + savefile->WriteMat3( localLightAxis ); + + savefile->WriteInt( levels ); + savefile->WriteInt( currentLevel ); + + savefile->WriteVec3( baseColor ); + savefile->WriteBool( breakOnTrigger ); + savefile->WriteInt( count ); + savefile->WriteInt( triggercount ); + savefile->WriteObject( lightParent ); + savefile->WriteBool(beingRelit); // grayman #2603 + savefile->WriteFloat(chanceNegativeBark); // grayman #2603 + savefile->WriteInt(whenTurnedOff); // grayman #2603 + savefile->WriteInt(nextTimeLightOutBark); // grayman #2603 + savefile->WriteInt(relightAfter); // grayman #2603 + savefile->WriteFloat(nextTimeVerticalCheck); // grayman #2603 + savefile->WriteBool(smoking); // grayman #2603 + savefile->WriteInt(whenToDouse); // grayman #2603 + savefile->WriteBool(startedOff); // grayman #2905 + + savefile->WriteInt(switchList.Num()); // grayman #2603 + for (int i = 0; i < switchList.Num(); i++) + { + switchList[i].Save(savefile); + } + + savefile->WriteVec4( fadeFrom ); + savefile->WriteVec4( fadeTo ); + savefile->WriteInt( fadeStart ); + savefile->WriteInt( fadeEnd ); + savefile->WriteBool( soundWasPlaying ); + + // grayman #2603 - ai bark counts + + savefile->WriteInt(aiBarks.Num()); + for (int i = 0 ; i < aiBarks.Num() ; i++) + { + AIBarks barks = aiBarks[i]; + + savefile->WriteInt(barks.count); + barks.ai.Save(savefile); + } + + savefile->WriteFloat(m_MaxLightRadius); + savefile->WriteInt(LASAreaIndex); + + // Don't save m_LightMaterial +} + +/* +================ +idLight::Restore + +unarchives object from save game file +================ +*/ +void idLight::Restore( idRestoreGame *savefile ) { + bool hadPrelightModel; + + savefile->ReadRenderLight( renderLight ); + + savefile->ReadBool( hadPrelightModel ); + renderLight.prelightModel = renderModelManager->CheckModel( va( "_prelight_%s", name.c_str() ) ); + if ( ( renderLight.prelightModel == NULL ) && hadPrelightModel ) { + assert( 0 ); + if ( developer.GetBool() ) { + // we really want to know if this happens + gameLocal.Error( "idLight::Restore: prelightModel '_prelight_%s' not found", name.c_str() ); + } else { + // but let it slide after release + gameLocal.Warning( "idLight::Restore: prelightModel '_prelight_%s' not found", name.c_str() ); + } + } + + savefile->ReadVec3( localLightOrigin ); + savefile->ReadMat3( localLightAxis ); + + savefile->ReadInt( levels ); + savefile->ReadInt( currentLevel ); + + savefile->ReadVec3( baseColor ); + savefile->ReadBool( breakOnTrigger ); + savefile->ReadInt( count ); + savefile->ReadInt( triggercount ); + savefile->ReadObject( reinterpret_cast( lightParent ) ); + savefile->ReadBool( beingRelit ); // grayman #2603 + savefile->ReadFloat( chanceNegativeBark ); // grayman #2603 + savefile->ReadInt( whenTurnedOff ); // grayman #2603 + savefile->ReadInt( nextTimeLightOutBark ); // grayman #2603 + savefile->ReadInt( relightAfter ); // grayman #2603 + savefile->ReadFloat(nextTimeVerticalCheck); // grayman #2603 + savefile->ReadBool(smoking); // grayman #2603 + savefile->ReadInt(whenToDouse); // grayman #2603 + savefile->ReadBool(startedOff); // grayman #2905 + + // grayman #2603 + switchList.Clear(); + int num; + savefile->ReadInt(num); + switchList.SetNum(num); + for (int i = 0; i < num; i++) + { + switchList[i].Restore(savefile); + } + + savefile->ReadVec4( fadeFrom ); + savefile->ReadVec4( fadeTo ); + savefile->ReadInt( fadeStart ); + savefile->ReadInt( fadeEnd ); + savefile->ReadBool( soundWasPlaying ); + + // grayman #2603 - ai bark counts + + savefile->ReadInt(num); + aiBarks.SetNum(num); + for (int i = 0 ; i < num ; i++) + { + savefile->ReadInt(aiBarks[i].count); + aiBarks[i].ai.Restore(savefile); + } + + savefile->ReadFloat(m_MaxLightRadius); + savefile->ReadInt(LASAreaIndex); + + lightDefHandle = -1; + + SetLightLevel(); + + m_MaterialName = NULL; + spawnArgs.GetString( "texture", "lights/squarelight1", &m_MaterialName); + + // Re-acquire light material, now that the material name is known + m_LightMaterial = g_Global.GetMaterial(m_MaterialName); +} + +/* +================ +idLight::Spawn +================ +*/ +void idLight::Spawn( void ) +{ + const char *demonic_shader; + + // do the parsing the same way dmap and the editor do + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &renderLight ); + + // we need the origin and axis relative to the physics origin/axis + localLightOrigin = ( renderLight.origin - GetPhysics()->GetOrigin() ) * GetPhysics()->GetAxis().Transpose(); + localLightAxis = renderLight.axis * GetPhysics()->GetAxis().Transpose(); + + // set the base color from the shader parms + baseColor.Set( renderLight.shaderParms[ SHADERPARM_RED ], renderLight.shaderParms[ SHADERPARM_GREEN ], renderLight.shaderParms[ SHADERPARM_BLUE ] ); + + // set the number of light levels + spawnArgs.GetInt( "levels", "1", levels ); + currentLevel = levels; + if ( levels <= 0 ) { + gameLocal.Error( "Invalid light level set on entity #%d(%s)", entityNumber, name.c_str() ); + } + + // make sure the demonic shader is cached + if ( spawnArgs.GetString( "mat_demonic", NULL, &demonic_shader ) ) { + declManager->FindType( DECL_MATERIAL, demonic_shader ); + } + + // game specific functionality, not mirrored in + // editor or dmap light parsing + + // also put the light texture on the model, so light flares + // can get the current intensity of the light + renderEntity.referenceShader = renderLight.shader; + + lightDefHandle = -1; // no static version yet + + // see if an optimized shadow volume exists + // the renderer will ignore this value after a light has been moved, + // but there may still be a chance to get it wrong if the game moves + // a light before the first present, and doesn't clear the prelight + renderLight.prelightModel = 0; + if ( name[ 0 ] ) { + // this will return 0 if not found + renderLight.prelightModel = renderModelManager->CheckModel( va( "_prelight_%s", name.c_str() ) ); + } + + // grayman #2905 - remember if the light started off because it's important during relighting attempts + + bool startOff = spawnArgs.GetBool( "start_off", "0" ); + if ( startOff ) + { + Event_SetStartedOff(); + Off(); + } + + health = spawnArgs.GetInt( "health", "0" ); + spawnArgs.GetBool( "break", "0", breakOnTrigger ); + spawnArgs.GetInt( "count", "1", count ); + + triggercount = 0; + + fadeFrom.Set( 1, 1, 1, 1 ); + fadeTo.Set( 1, 1, 1, 1 ); + fadeStart = 0; + fadeEnd = 0; + + // load visual and collision models + LoadModels(); + + PostEventMS( &EV_PostSpawn, 0 ); + + UpdateVisuals(); + + if(renderLight.pointLight == true) + m_MaxLightRadius = renderLight.lightRadius.Length(); + else + { + idVec3 pos = GetPhysics()->GetOrigin(); + idVec3 max = renderLight.target + renderLight.right + renderLight.up; + m_MaxLightRadius = max.Length(); + } + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("this: %08lX [%s] MaxLightRadius: %f\r", this, name.c_str(), m_MaxLightRadius); + + m_MaterialName = NULL; + spawnArgs.GetString( "texture", "lights/squarelight1", &m_MaterialName); + if(m_MaterialName != NULL) + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light has an image: %s\r", m_MaterialName); + + idImage *pImage; + if(renderLight.shader != NULL && (pImage = renderLight.shader->LightFalloffImage()) != NULL) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light has an image: %08lX\r", pImage); + } + + // grayman #2603 - set up flames for vertical check + + idStr lightType = spawnArgs.GetString(AIUSE_LIGHTTYPE_KEY); + if (lightType == AIUSE_LIGHTTYPE_TORCH) + { + if (!spawnArgs.GetBool("should_be_vert","0")) // don't check verticality if it doesn't matter + { + nextTimeVerticalCheck = idMath::INFINITY; // never + } + else + { + nextTimeVerticalCheck = gameLocal.time + 3000 + gameLocal.random.RandomFloat()*3000; // randomize so checks are done at different times + } + } + else // non-flames + { + nextTimeVerticalCheck = idMath::INFINITY; // never + } + + smoking = false; // grayman #2603 + + whenToDouse = -1; // grayman #2603 + + // Sophisiticated Zombie (DMH) + // Darkmod Light Awareness System: Also need to add light to LAS + + PostEventMS(&EV_Light_AddToLAS, 40); + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("this: %08lX [%s] noShadows: %u noSpecular: %u pointLight: %u parallel: %u\r", + this, name.c_str(), + renderLight.noShadows, + renderLight.noSpecular, + renderLight.pointLight, + renderLight.parallel); + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Red: %f Green: %f Blue: %f\r", baseColor.x, baseColor.y, baseColor.z); + + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Origin", GetPhysics()->GetOrigin()); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Radius", renderLight.lightRadius); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Center", renderLight.lightCenter); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Target", renderLight.target); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Right", renderLight.right); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Up", renderLight.up); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Start", renderLight.start); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "End", renderLight.end); +} + +/* +================ +idLight::SetLightLevel +================ +*/ +void idLight::SetLightLevel( void ) { + idVec3 color; + float intensity; + + intensity = ( float )currentLevel / ( float )levels; + color = baseColor * intensity; + renderLight.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; + renderLight.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ]; + renderLight.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; + renderEntity.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; + renderEntity.shaderParms[ SHADERPARM_GREEN ]= color[ 1 ]; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; + PresentLightDefChange(); + PresentModelDefChange(); +} + +/* +================ +tels: idLight::GetLightOrigin returns the origin of the light in the world. This +is different from the physics origin, since the light can be offset. +================ +void idLight::GetLightOrigin( idVec3 &out ) const { + out[0] = renderLight.origin[0]; + out[1] = renderLight.origin[1]; + out[2] = renderLight.origin[2]; +} +*/ + +/* +================ +idLight::GetColor +================ +*/ +void idLight::GetColor( idVec3 &out ) const { + out[ 0 ] = renderLight.shaderParms[ SHADERPARM_RED ]; + out[ 1 ] = renderLight.shaderParms[ SHADERPARM_GREEN ]; + out[ 2 ] = renderLight.shaderParms[ SHADERPARM_BLUE ]; +} + +/* +================ +idLight::GetColor +================ +*/ +void idLight::GetColor( idVec4 &out ) const { + out[ 0 ] = renderLight.shaderParms[ SHADERPARM_RED ]; + out[ 1 ] = renderLight.shaderParms[ SHADERPARM_GREEN ]; + out[ 2 ] = renderLight.shaderParms[ SHADERPARM_BLUE ]; + out[ 3 ] = renderLight.shaderParms[ SHADERPARM_ALPHA ]; +} + +/* +================ +idLight::SetColor +================ +*/ +void idLight::SetColor( const float red, const float green, const float blue ) +{ + // Tels: If the light is currently fading, stop this: + fadeEnd = 0; + BecomeInactive( TH_THINK ); + baseColor.Set( red, green, blue ); + SetLightLevel(); +} + +/* +================ +idLight::SetColor +================ +*/ +void idLight::SetColor( const idVec4 &color ) { + // Tels: If the light is currently fading, stop this: + fadeEnd = 0; + BecomeInactive( TH_THINK ); + baseColor = color.ToVec3(); + renderLight.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; + SetLightLevel(); +} + +/* +================ +idLight::SetShader +================ +*/ +void idLight::SetShader( const char *shadername ) { + // allow this to be NULL + renderLight.shader = declManager->FindMaterial( shadername, false ); + PresentLightDefChange(); +} + +/* +================ +idLight::SetLightParm +================ +*/ +void idLight::SetLightParm( int parmnum, float value ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Error( "shader parm index (%d) out of range", parmnum ); + } + + renderLight.shaderParms[ parmnum ] = value; + PresentLightDefChange(); +} + +/* +================ +idLight::SetLightParms +================ +*/ +void idLight::SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { + renderLight.shaderParms[ SHADERPARM_RED ] = parm0; + renderLight.shaderParms[ SHADERPARM_GREEN ] = parm1; + renderLight.shaderParms[ SHADERPARM_BLUE ] = parm2; + renderLight.shaderParms[ SHADERPARM_ALPHA ] = parm3; + renderEntity.shaderParms[ SHADERPARM_RED ] = parm0; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = parm1; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = parm2; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = parm3; + PresentLightDefChange(); + PresentModelDefChange(); +} + +/* +================ +idLight::SetRadiusXYZ +================ +*/ +void idLight::SetRadiusXYZ( const float x, const float y, const float z ) { + renderLight.lightRadius[0] = x; + renderLight.lightRadius[1] = y; + renderLight.lightRadius[2] = z; + PresentLightDefChange(); +} + +/* +================ +idLight::SetRadius +================ +*/ +void idLight::SetRadius( const float radius ) { + renderLight.lightRadius[0] = renderLight.lightRadius[1] = renderLight.lightRadius[2] = radius; + PresentLightDefChange(); +} + +/* + * ================ + * Tels: idLight:GetRadius + * ================ + * */ +void idLight::GetRadius( idVec3 &out ) const { + out.x = renderLight.lightRadius[0]; + out.y = renderLight.lightRadius[1]; + out.z = renderLight.lightRadius[2]; +} + +/* +================ +idLight::On +================ +*/ +void idLight::On( void ) { + + currentLevel = levels; + // offset the start time of the shader to sync it to the game time + renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + if ( ( soundWasPlaying || refSound.waitfortrigger ) && refSound.shader ) { + StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); + soundWasPlaying = false; + } + + const function_t* func = scriptObject.GetFunction("LightsOn"); + if (func == NULL) + { + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::On: 'LightsOn' not found in local space, checking for global.\r"); + func = gameLocal.program.FindFunction("LightsOn"); + } + + if (func != NULL) + { + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::On: turning light on\r"); + idThread *pThread = new idThread(func); + pThread->CallFunction(this,func, true); + pThread->DelayedStart(0); + } + else + { + DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("idLight::On: 'LightsOn' not found!\r"); + } + + aiBarks.Clear(); // grayman #2603 - let the AI comment again + +// grayman #2603 - let script change skins, plus set the vis stim. + +/* const char *skinName; + const idDeclSkin *skin; + + // Tels: set "skin_lit" if it is defined + spawnArgs.GetString( "skin_lit", "", &skinName ); + skin = declManager->FindSkin( skinName ); + if (skin) { + SetSkin( skin ); + // set the spawnarg to the current active skin + spawnArgs.Set( "skin", skinName ); + } + */ + SetLightLevel(); + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idLight::Off +================ +*/ +void idLight::Off( const bool stopSound ) { + + currentLevel = 0; + + if ( stopSound && refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) { + StopSound( SND_CHANNEL_ANY, false ); + soundWasPlaying = true; + } + + const function_t* func = scriptObject.GetFunction("LightsOff"); + if (func == NULL) + { + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::Off: 'LightsOff' not found in local space, checking for global.\r"); + func = gameLocal.program.FindFunction("LightsOff"); + } + + if (func != NULL) + { + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::Off: turning light off\r"); + idThread *pThread = new idThread(func); + pThread->CallFunction(this,func,true); + pThread->DelayedStart(0); + whenTurnedOff = gameLocal.time; // grayman #2603 + } + else + { + DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("idLight::Off: 'LightsOff' not found!\r"); + } + +// grayman #2603 - let script change skins, plus set the vis stim. + +/* // Tels: set "skin_unlit" if it is defined + const char *skinName; + const idDeclSkin *skin; + spawnArgs.GetString( "skin_unlit", "", &skinName ); + skin = declManager->FindSkin( skinName ); + if (skin) { + SetSkin( skin ); + // set the spawnarg to the current active skin + spawnArgs.Set( "skin", skinName ); + } + */ + SetLightLevel(); + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idLight::Fade +================ +*/ +void idLight::Fade( const idVec4 &to, float fadeTime ) { + GetColor( fadeFrom ); + // Tels: we already have the same color we should become, so we can skip this + if (fadeFrom == to) + { + return; + } + // Tels: If the fade time is shorter than 1/60 (e.g. one frame), just set the color directly + if (fadeTime < 0.0167f) + { + if (to == colorBlack) + { + // The fade does not happen (time too short), so Off() would not be called so do it now (#2440) + // avoid the sound stopping, because this might be snd_extinguished + Off( false ); + } + else + { + SetColor(to); + } + return; + } + fadeTo = to; + fadeStart = gameLocal.time; + fadeEnd = gameLocal.time + SEC2MS( fadeTime ); + BecomeActive( TH_THINK ); +} + +/* +================ +idLight::FadeOut +================ +*/ +void idLight::FadeOut( float time ) { + if (baseColor.x == 0 && baseColor.y == 0 && baseColor.z == 0) + { + // The fade would not happen, so Off() would not be called, so do it now (#2440) + // avoid the sound stopping, because this might be snd_extinguished + Off( false ); + } + else + { + // Tels: Think() will call Off() once the fade is done, since we use colorBlack as fade target + Fade( colorBlack, time ); + } +} + +/* +================ +idLight::FadeIn +================ +*/ +void idLight::FadeIn( float time ) { + idVec3 color; + idVec4 color4; + + currentLevel = levels; + // restore the original light color + spawnArgs.GetVector( "_color", "1 1 1", color ); + color4.Set( color.x, color.y, color.z, 1.0f ); + Fade( color4, time ); +} + +/* +================ +idLight::FadeTo +================ +*/ +void idLight::FadeTo( idVec3 color, float time ) { + + idVec4 color4; + + // tels: TODO: this step sets the intensity of the light to the maximum, + // do we really want this? + currentLevel = levels; + color4.Set( color.x, color.y, color.z, 1.0f ); + Fade( color4, time ); +} + +/* +================ +idLight::Killed +================ +*/ +void idLight::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + BecomeBroken( attacker ); +} + +int idLight::GetLightLevel() const +{ + return currentLevel; +} + +/* +================ +idLight::BecomeBroken +================ +*/ +void idLight::BecomeBroken( idEntity *activator ) { + const char *damageDefName; + + idEntity::BecomeBroken ( activator ); + + if ( gameLocal.isServer ) { + + ServerSendEvent( EVENT_BECOMEBROKEN, NULL, true, -1 ); + + if ( spawnArgs.GetString( "def_damage", "", &damageDefName ) ) { + idVec3 origin = renderEntity.origin + renderEntity.bounds.GetCenter() * renderEntity.axis; + gameLocal.RadiusDamage( origin, activator, activator, this, this, damageDefName ); + } + + } + + ActivateTargets( activator ); + + // offset the start time of the shader to sync it to the game time + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + // set the state parm + renderEntity.shaderParms[ SHADERPARM_MODE ] = 1; + renderLight.shaderParms[ SHADERPARM_MODE ] = 1; + + // if the light has a sound, either start the alternate (broken) sound, or stop the sound + const char *parm = spawnArgs.GetString( "snd_broken" ); + if ( refSound.shader || ( parm && *parm ) ) { + StopSound( SND_CHANNEL_ANY, false ); + const idSoundShader *alternate = refSound.shader ? refSound.shader->GetAltSound() : declManager->FindSound( parm ); + if ( alternate ) { + // start it with no diversity, so the leadin break sound plays + refSound.referenceSound->StartSound( alternate, SND_CHANNEL_ANY, 0.0, 0 ); + } + } + + parm = spawnArgs.GetString( "mtr_broken" ); + if ( parm && *parm ) { + SetShader( parm ); + } + + UpdateVisuals(); +} + +/* +================ +idLight::PresentLightDefChange +================ +*/ +void idLight::PresentLightDefChange( void ) +{ +/* +DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s] Radius ( %0.3f / %0.3f / %03f )\r", this, name.c_str(), + renderLight.lightRadius[0], // x + renderLight.lightRadius[1], // y + renderLight.lightRadius[2]); // z +*/ + + // let the renderer apply it to the world + if ( ( lightDefHandle != -1 ) ) { + gameRenderWorld->UpdateLightDef( lightDefHandle, &renderLight ); + } else { + lightDefHandle = gameRenderWorld->AddLightDef( &renderLight ); + } +} + +/* +================ +idLight::PresentModelDefChange +================ +*/ +void idLight::PresentModelDefChange( void ) { + + if ( !renderEntity.hModel || IsHidden() ) { + return; + } + + // add to refresh list + if ( modelDefHandle == -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } +} + +/* +================ +idLight::Present +================ +*/ +void idLight::Present( void ) { + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { + return; + } + + // Clear the bounds, so idLight::PresentRenderTrigger() has a way to know + // if idEntity::PresentRenderTrigger() added anything. + m_renderTrigger.bounds.Clear(); + + // add the model + idEntity::Present(); + + // current transformation + renderLight.axis = localLightAxis * GetPhysics()->GetAxis(); + renderLight.origin = GetPhysics()->GetOrigin() + GetPhysics()->GetAxis() * localLightOrigin; + + // reference the sound for shader synced effects + if ( lightParent ) { + renderLight.referenceSound = lightParent->GetSoundEmitter(); + renderEntity.referenceSound = lightParent->GetSoundEmitter(); + } + else { + renderLight.referenceSound = refSound.referenceSound; + renderEntity.referenceSound = refSound.referenceSound; + } + + // update the renderLight and renderEntity to render the light and flare + PresentLightDefChange(); + PresentModelDefChange(); + PresentRenderTrigger(); +} + +/* +================ +idLight::IsVertical +*/ + +bool idLight::IsVertical(float degreesFromVertical) +{ + idStr lightType = spawnArgs.GetString(AIUSE_LIGHTTYPE_KEY); + bool shouldBeVert = spawnArgs.GetBool("should_be_vert","0"); + + // Only makes sense for flames with the "douse_horiz" spawnarg + + if ((lightType == AIUSE_LIGHTTYPE_TORCH) && shouldBeVert) + { + const idVec3& gravityNormal = GetPhysics()->GetGravityNormal(); + idMat3 axis = GetPhysics()->GetAxis(); + idVec3 result(0,0,0); + axis.ProjectVector(-gravityNormal,result); + float verticality = result * (-gravityNormal); + if (verticality < idMath::Cos(DEG2RAD(degreesFromVertical))) // > 10 degrees from vertical + { + return false; + } + } + return true; +} + +/* +================ +idLight::Think +================ +*/ +void idLight::Think( void ) { + idVec4 color; + + if ( thinkFlags & TH_THINK ) { + if ( fadeEnd > 0 ) { + if ( gameLocal.time < fadeEnd ) { + color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) ); + } else { + color = fadeTo; + fadeEnd = 0; + // Tels: Fix issues like 2440: FadeOff() does not switch the light to the off state + if (color[0] == 0 && color[1] == 0 && color[2] == 0) + { + // avoid the sound stopping, because this might be snd_extinguished + Off( false ); + } + BecomeInactive( TH_THINK ); + } + // don't call SetColor(), as it stops the fade, instead inline the second part of it: + baseColor = color.ToVec3(); + renderLight.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; + renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; + SetLightLevel(); + } + } + + // grayman #2603 - every so often, check if a lit flame not being held by an AI is non-vertical (> 45 degrees from vertical). if so, douse it + + if (gameLocal.time >= nextTimeVerticalCheck) + { + nextTimeVerticalCheck = gameLocal.time + 1000; + + if (GetLightLevel() > 0) // is it on? + { + bool isVertical = IsVertical(45); // w/in 45 degrees of vertical? + if (!isVertical) + { + // is an AI holding this light? + + bool isHeld = false; + idEntity* bindMaster = GetBindMaster(); + while (bindMaster != NULL) // not held when bindMaster == NULL + { + if (bindMaster->IsType(idAI::Type)) + { + isHeld = true; + break; + } + bindMaster = bindMaster->GetBindMaster(); // go up the hierarchy + } + + if (!isHeld) + { + // Is the player holding this light? + + CGrabber* grabber = gameLocal.m_Grabber; + if (grabber) + { + idEntity* heldEnt = grabber->GetSelected(); + if (heldEnt) + { + bindMaster = GetBindMaster(); + while (bindMaster != NULL) // not held when bindMaster == NULL + { + if (heldEnt == bindMaster) + { + isHeld = true; + break; + } + bindMaster = bindMaster->GetBindMaster(); + } + } + } + } + + if (!isHeld) + { + if (whenToDouse == -1) + { + whenToDouse = gameLocal.time + 5000; // douse this later if still non-vertical + BecomeActive(TH_DOUSING); // set this so you can continue thinking after coming to rest and TH_PHYSICS shuts off + } + else if (gameLocal.time >= whenToDouse) + { + CallScriptFunctionArgs("frob_extinguish", true, 0, "e", this); + whenToDouse = -1; // reset + BecomeInactive(TH_DOUSING); // reset + } + } + else + { + whenToDouse = -1; // non-vertical, but it's being held, so turn off any latched non-vertical douse + BecomeInactive(TH_DOUSING); // reset + } + } + else + { + whenToDouse = -1; // vertical, so turn off any latched non-vertical douse + BecomeInactive(TH_DOUSING); // reset + } + } + } + + RunPhysics(); + Present(); +} + +/* +================ +idLight::GetPhysicsToSoundTransform +================ +*/ +bool idLight::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { + origin = localLightOrigin + renderLight.lightCenter; + axis = localLightAxis * GetPhysics()->GetAxis(); + return true; +} + +/* +================ +idLight::FreeLightDef +================ +*/ +void idLight::FreeLightDef( void ) { + if ( lightDefHandle != -1 ) { + gameRenderWorld->FreeLightDef( lightDefHandle ); + lightDefHandle = -1; + } +} + +/* +================ +idLight::SaveState +================ +*/ +void idLight::SaveState( idDict *args ) { + int i, c = spawnArgs.GetNumKeyVals(); + for ( i = 0; i < c; i++ ) { + const idKeyValue *pv = spawnArgs.GetKeyVal(i); + if ( pv->GetKey().Find( "editor_", false ) >= 0 || pv->GetKey().Find( "parse_", false ) >= 0 ) { + continue; + } + args->Set( pv->GetKey(), pv->GetValue() ); + } +} + +/* +=============== +idLight::ShowEditingDialog +=============== +*/ +void idLight::ShowEditingDialog( void ) { + if ( g_editEntityMode.GetInteger() == 1 ) { + common->InitTool( EDITOR_LIGHT, &spawnArgs ); + } else { + common->InitTool( EDITOR_SOUND, &spawnArgs ); + } +} + +/* +================ +idLight::Event_SetShader +================ +*/ +void idLight::Event_SetShader( const char *shadername ) { + SetShader( shadername ); +} + +/* +================ +idLight::Event_GetLightParm +================ +*/ +void idLight::Event_GetLightParm( int parmnum ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Error( "shader parm index (%d) out of range", parmnum ); + } + + idThread::ReturnFloat( renderLight.shaderParms[ parmnum ] ); +} + +/* +================ +idLight::Event_SetLightParm +================ +*/ +void idLight::Event_SetLightParm( int parmnum, float value ) { + SetLightParm( parmnum, value ); +} + +/* +================ +idLight::Event_SetLightParms +================ +*/ +void idLight::Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { + SetLightParms( parm0, parm1, parm2, parm3 ); +} + +/* +================ +idLight::Event_SetRadiusXYZ +================ +*/ +void idLight::Event_SetRadiusXYZ( float x, float y, float z ) { + SetRadiusXYZ( x, y, z ); +} + +/* +================ +idLight::Event_SetRadius +================ +*/ +void idLight::Event_SetRadius( float radius ) { + SetRadius( radius ); +} + +/* +================ +idLight::Event_Hide +================ +*/ +void idLight::Event_Hide( void ) { + Hide(); + smoking = false; // grayman #2603 + PresentModelDefChange(); + Off(); +} + +/* +================ +idLight::Event_Show +================ +*/ +void idLight::Event_Show( void ) { + Show(); + PresentModelDefChange(); + On(); +} + +/* +================ +idLight::Event_On +================ +*/ +void idLight::Event_On( void ) { + On(); +} + +/* +================ +idLight::Event_Off +================ +*/ +void idLight::Event_Off( void ) { + Off(); +} + +/* +================ +idLight::Event_ToggleOnOff +================ +*/ +void idLight::Event_ToggleOnOff( idEntity *activator ) { + triggercount++; + if ( triggercount < count ) { + return; + } + + // reset trigger count + triggercount = 0; + + if ( breakOnTrigger ) { + BecomeBroken( activator ); + breakOnTrigger = false; + return; + } + + if ( !currentLevel ) { + On(); + } + else { + currentLevel--; + if ( !currentLevel ) { + Off(); + } + else { + SetLightLevel(); + } + } +} + +/* +================ +idLight::Event_SetSoundHandles + + set the same sound def handle on all targeted lights +================ +*/ +void idLight::Event_SetSoundHandles( void ) { + + int i; + idEntity *targetEnt; + + if ( !refSound.referenceSound ) { + return; + } + + for ( i = 0; i < targets.Num(); i++ ) { + targetEnt = targets[ i ].GetEntity(); + if ( targetEnt && targetEnt->IsType( idLight::Type ) ) { + idLight *light = static_cast(targetEnt); + light->lightParent = this; + + // explicitly delete any sounds on the entity + light->FreeSoundEmitter( true ); + + // manually set the refSound to this light's refSound + light->renderEntity.referenceSound = renderEntity.referenceSound; + + // update the renderEntity to the renderer + light->UpdateVisuals(); + } + } +} + +/* +================ +idLight::Event_FadeOut +================ +*/ +void idLight::Event_FadeOut( float time ) { + FadeOut( time ); +} + +/* +================ +idLight::Event_FadeIn +================ +*/ +void idLight::Event_FadeIn( float time ) { + FadeIn( time ); +} + +/* +================ +idLight::Event_FadeToLight +================ +*/ +void idLight::Event_FadeToLight( idVec3 &color, float time ) { + FadeTo( color, time ); +} + +/* +================ +idLight::ClientPredictionThink +================ +*/ +void idLight::ClientPredictionThink( void ) { + Think(); +} + +/* +================ +idLight::WriteToSnapshot +================ +*/ +void idLight::WriteToSnapshot( idBitMsgDelta &msg ) const { + + GetPhysics()->WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); + + msg.WriteByte( currentLevel ); + msg.WriteLong( PackColor( baseColor ) ); + // msg.WriteBits( lightParent.GetEntityNum(), GENTITYNUM_BITS ); + +/* // only helps prediction + msg.WriteLong( PackColor( fadeFrom ) ); + msg.WriteLong( PackColor( fadeTo ) ); + msg.WriteLong( fadeStart ); + msg.WriteLong( fadeEnd ); +*/ + + // FIXME: send renderLight.shader + msg.WriteFloat( renderLight.lightRadius[0], 5, 10 ); + msg.WriteFloat( renderLight.lightRadius[1], 5, 10 ); + msg.WriteFloat( renderLight.lightRadius[2], 5, 10 ); + + msg.WriteLong( PackColor( idVec4( renderLight.shaderParms[SHADERPARM_RED], + renderLight.shaderParms[SHADERPARM_GREEN], + renderLight.shaderParms[SHADERPARM_BLUE], + renderLight.shaderParms[SHADERPARM_ALPHA] ) ) ); + + msg.WriteFloat( renderLight.shaderParms[SHADERPARM_TIMESCALE], 5, 10 ); + msg.WriteLong( renderLight.shaderParms[SHADERPARM_TIMEOFFSET] ); + //msg.WriteByte( renderLight.shaderParms[SHADERPARM_DIVERSITY] ); + msg.WriteShort( renderLight.shaderParms[SHADERPARM_MODE] ); + + WriteColorToSnapshot( msg ); +} + +/* +================ +idLight::ReadFromSnapshot +================ +*/ +void idLight::ReadFromSnapshot( const idBitMsgDelta &msg ) { + idVec4 shaderColor; + int oldCurrentLevel = currentLevel; + idVec3 oldBaseColor = baseColor; + + GetPhysics()->ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + + currentLevel = msg.ReadByte(); + if ( currentLevel != oldCurrentLevel ) { + // need to call On/Off for flickering lights to start/stop the sound + // while doing it this way rather than through events, the flickering is out of sync between clients + // but at least there is no question about saving the event and having them happening globally in the world + if ( currentLevel ) { + On(); + } else { + Off(); + } + } + UnpackColor( msg.ReadLong(), baseColor ); + // lightParentEntityNum = msg.ReadBits( GENTITYNUM_BITS ); + +/* // only helps prediction + UnpackColor( msg.ReadLong(), fadeFrom ); + UnpackColor( msg.ReadLong(), fadeTo ); + fadeStart = msg.ReadLong(); + fadeEnd = msg.ReadLong(); +*/ + + // FIXME: read renderLight.shader + renderLight.lightRadius[0] = msg.ReadFloat( 5, 10 ); + renderLight.lightRadius[1] = msg.ReadFloat( 5, 10 ); + renderLight.lightRadius[2] = msg.ReadFloat( 5, 10 ); + + UnpackColor( msg.ReadLong(), shaderColor ); + renderLight.shaderParms[SHADERPARM_RED] = shaderColor[0]; + renderLight.shaderParms[SHADERPARM_GREEN] = shaderColor[1]; + renderLight.shaderParms[SHADERPARM_BLUE] = shaderColor[2]; + renderLight.shaderParms[SHADERPARM_ALPHA] = shaderColor[3]; + + renderLight.shaderParms[SHADERPARM_TIMESCALE] = msg.ReadFloat( 5, 10 ); + renderLight.shaderParms[SHADERPARM_TIMEOFFSET] = msg.ReadLong(); + //renderLight.shaderParms[SHADERPARM_DIVERSITY] = msg.ReadFloat(); + renderLight.shaderParms[SHADERPARM_MODE] = msg.ReadShort(); + + ReadColorFromSnapshot( msg ); + + if ( msg.HasChanged() ) { + if ( ( currentLevel != oldCurrentLevel ) || ( baseColor != oldBaseColor ) ) { + SetLightLevel(); + } else { + PresentLightDefChange(); + PresentModelDefChange(); + } + } +} + +/* +================ +idLight::ClientReceiveEvent +================ +*/ +bool idLight::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + + switch( event ) { + case EVENT_BECOMEBROKEN: { + BecomeBroken( NULL ); + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + + +/** Returns a bounding box surrounding the light. + */ +idBounds idLight::GetBounds() +{ + // NOTE: I need to add caching. + + idBounds b; + + if ( renderLight.pointLight ) + { + b = idBounds( -renderLight.lightRadius, renderLight.lightRadius ); + } else { + gameLocal.Warning("idLight::GetBounds() not correctly implemented for projected lights."); + // Fake a set of bounds. This might work ok for squarish spotlights with no start/stop specified. + // FIXME: These bounds are incorrect. + b.Zero(); + b.AddPoint( renderLight.target ); + b.AddPoint( renderLight.target + renderLight.up + renderLight.right ); + b.AddPoint( renderLight.target + renderLight.up - renderLight.right ); + b.AddPoint( renderLight.target - renderLight.up + renderLight.right ); + b.AddPoint( renderLight.target - renderLight.up - renderLight.right ); + } + + return b; +} + + +/** Called to update m_renderTrigger after the render entity is modified. + * Only updates the render trigger if a thread is waiting for it. + */ +void idLight::PresentRenderTrigger() +{ + if ( !m_renderWaitingThread ) { + goto Quit; + } + + // Have the bounds been set yet? + if ( m_renderTrigger.bounds.IsCleared() ) + { + // No. + + // Pre-rotate our bounds and give them to m_renderTrigger. + m_renderTrigger.origin = renderLight.origin; + m_renderTrigger.bounds = GetBounds() * renderLight.axis; + + } else { + // Yes. + + // Convert our light's bounds to be relative to m_renderTrigger, + // and add them to what already exists. + m_renderTrigger.bounds += GetBounds() * renderLight.axis + ( renderLight.origin - m_renderTrigger.origin ); + } + + // I haven't yet figured out where renderEntity.entityNum is set... + m_renderTrigger.entityNum = entityNumber; + + // Update the renderTrigger in the render world. + if ( m_renderTriggerHandle == -1 ) + m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); + else + gameRenderWorld->UpdateEntityDef( m_renderTriggerHandle, &m_renderTrigger ); + + Quit: + return; +} + + +int idLight::GetTextureIndex(float x, float y, int w, int h, int bpp) +{ + int rc = 0; + float w2, h2; + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Calculating texture index: x/y: %f/%f w/h: %u/%u\r", x, y, w, h); + + w2 = ((float)w)/2.0; + h2 = ((float)h)/2.0; + + if(renderLight.pointLight) + { + // The lighttextures are spread out over the range of the axis. The z axis + // can be ignored for this and we assume that the x/y is already properly + // calculated. + x = w2 - (w2/renderLight.lightRadius.x) * x; + y = h2 - (h2/renderLight.lightRadius.y) * y; + } + else + { + // TODO: Just for now until the projected lights are implemented to not cause any crash. + // x = right + // y = up +//#pragma message(DARKMOD_NOTE "-------------------------------------------------idLight::GetTextureIndex") +//#pragma message(DARKMOD_NOTE "For projected lights this is likely not enough. As long as the light will") +//#pragma message(DARKMOD_NOTE "be straight up or down it should work, but if the cone is angled it might") +//#pragma message(DARKMOD_NOTE "give wrong results. greebo: See DarkRadiant code for starters.") +//#pragma message(DARKMOD_NOTE "-------------------------------------------------idLight::GetTextureIndex") + x = w2 - (w2/renderLight.right.x) * x; + y = h2 - (h2/renderLight.up.y) * y; + } + + if(y > h) + y = h; + if(x > w) + x = w; + + if(x < 0) + x = 0; + if(y < 0) + y = 0; + + rc = ((int)y * (w*bpp)) + ((int)x*bpp); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Index result: %u x/y: %f/%f\r", rc, x, y); + + return rc; +} + + +float idLight::GetDistanceColor(float fDistance, float fx, float fy) +{ + float fColVal(0), fImgVal(0); + int fw(0), fh(0), iw(0), ih(0), i(0), fbpp(0), ibpp(0); + const unsigned char *img = NULL; + const unsigned char *fot = NULL; + + if(m_LightMaterial == NULL) + { + if((m_LightMaterial = g_Global.GetMaterial(m_MaterialName)) != NULL) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Material found for [%s]\r", name.c_str()); + fot = m_LightMaterial->GetFallOffTexture(fw, fh, fbpp); + img = m_LightMaterial->GetImage(iw, ih, ibpp); + } + } + else + { + fot = m_LightMaterial->GetFallOffTexture(fw, fh, fbpp); + img = m_LightMaterial->GetImage(iw, ih, ibpp); + } + + fColVal = (baseColor.x * DARKMOD_LG_RED + baseColor.y * DARKMOD_LG_GREEN + baseColor.z * DARKMOD_LG_BLUE); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Pointlight: %u Red: %f/%f Green: %f/%f Blue: %f/%f ColVal: %f\r", renderLight.pointLight, + baseColor.x, baseColor.x * DARKMOD_LG_RED, + baseColor.y, baseColor.y * DARKMOD_LG_GREEN, + baseColor.z, baseColor.z * DARKMOD_LG_BLUE, + fColVal); + + // If we have neither falloff texture nor a projection image, we do a + // simple linear falloff + if(fot == NULL && img == NULL) + { + // TODO: Light falloff calculation +//#pragma message(DARKMOD_NOTE "------------------------------------------------idLight::GetDistanceColor") +//#pragma message(DARKMOD_NOTE "The lightfalloff should be calculated for ellipsoids instead of spheres") +//#pragma message(DARKMOD_NOTE "when no textures are defined. The current code will give wrong results") +//#pragma message(DARKMOD_NOTE "when a light is defined as an ellipsoid.") +//#pragma message(DARKMOD_NOTE "------------------------------------------------idLight::GetDistanceColor") + fColVal = (fColVal / m_MaxLightRadius) * (m_MaxLightRadius - fDistance); + fImgVal = 1; + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("No textures defined using distance: [%f]\r", fDistance); + } + else + { + // If we have a falloff texture ... + if(fot != NULL) + { + i = GetTextureIndex((float)fabs(fx), (float)fabs(fy), fw, fh, fbpp); + fColVal = fColVal * (fot[i] * DARKMOD_LG_SCALE); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Falloff: Index: %u Value: %u [%f]\r", i, (int)fot[i], (float)(fot[i] * DARKMOD_LG_SCALE)); + } + else + fColVal = 1; + + // ... or a projection image. + if(img != NULL) + { + i = GetTextureIndex((float)fabs(fx), (float)fabs(fy), iw, ih, ibpp); + fImgVal = img[i] * DARKMOD_LG_SCALE; + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Map: Index: %u Value: %u [%f]\r", i, (int)img[i], (float)(img[i] * DARKMOD_LG_SCALE)); + } + else + fImgVal = 1; + } + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Final ColVal: %f ImgVal: %f\r", fColVal, fImgVal); + + return (fColVal*fImgVal); +} + +bool idLight::CastsShadow(void) +{ + if(m_LightMaterial == NULL) + m_LightMaterial = g_Global.GetMaterial(m_MaterialName); + + if(m_LightMaterial != NULL) + { + if(m_LightMaterial->m_AmbientLight == true) + return false; + } + + return !renderLight.noShadows; +} + +bool idLight::GetLightCone(idVec3 &Origin, idVec3 &Target, idVec3 &Right, idVec3 &Up, idVec3 &Start, idVec3 &End) +{ + bool rc = false; + + Origin = GetPhysics()->GetOrigin(); + Target = renderLight.target; + Right = renderLight.right; + Up = renderLight.up; + + Start = renderLight.start; + End = renderLight.end; + + return rc; +} + +bool idLight::GetLightCone(idVec3 &Origin, idVec3 &Axis, idVec3 &Center) +{ + bool rc = false; + + Origin = GetPhysics()->GetOrigin(); + Axis = renderLight.lightRadius; + Center = renderLight.lightCenter; + + return rc; +} + +void idLight::Event_SetLightOrigin( idVec3 &pos ) +{ + localLightOrigin = pos; + BecomeActive( TH_UPDATEVISUALS ); +} + +void idLight::Event_GetLightOrigin( void ) +{ + idThread::ReturnVector( localLightOrigin ); +} + +void idLight::Event_GetLightLevel ( void ) +{ + idThread::ReturnFloat( currentLevel ); +} + +void idLight::Event_AddToLAS() +{ + LAS.addLight(this); + + // Also register this light with the local player + idPlayer* player = gameLocal.GetLocalPlayer(); + if (player != NULL) + { + player->AddLight(this); + } +} + +/** Returns 1 if the light is in PVS. + * Doesn't take into account vis-area optimizations for shadowcasting lights. + */ +void idLight::Event_InPVS() +// NOTE: Current extremely inefficent. +// Caching needs to be done. +{ + int localNumPVSAreas, localPVSAreas[32]; + idBounds modelAbsBounds; + + m_renderTrigger.bounds = GetBounds(); // currently too innefficient but I'll worry about caching later + m_renderTrigger.origin = renderLight.origin; + m_renderTrigger.axis = renderLight.axis; + + modelAbsBounds.FromTransformedBounds( m_renderTrigger.bounds, m_renderTrigger.origin, m_renderTrigger.axis ); + localNumPVSAreas = gameLocal.pvs.GetPVSAreas( modelAbsBounds, localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); + + idThread::ReturnFloat( gameLocal.pvs.InCurrentPVS( gameLocal.GetPlayerPVS(), localPVSAreas, localNumPVSAreas ) ); +} + +// Returns true if this is an ambient light. - J.C.Denton +bool idLight::IsAmbient(void) +{ + if( renderLight.shader ) + return renderLight.shader->IsAmbientLight(); + + return false; +} + +// grayman #2603 - keep a list of switches for this light +void idLight::AddSwitch(idEntity* newSwitch) +{ + idEntityPtr switchPtr; + switchPtr = newSwitch; + switchList.Append(switchPtr); +} + +// grayman #2603 - If there are switches, return the closest one to the calling user +idEntity* idLight::GetSwitch(idAI* user) +{ + if (switchList.Num() == 0) // quick check + { + return NULL; + } + + idEntity* closestSwitch = NULL; + float shortestDistSqr = idMath::INFINITY; + idVec3 userOrg = user->GetPhysics()->GetOrigin(); + for (int i = 0 ; i < switchList.Num() ; i++) + { + idEntity* e = switchList[i].GetEntity(); + if (e) + { + float distSqr = (e->GetPhysics()->GetOrigin() - userOrg).LengthSqr(); + if (distSqr < shortestDistSqr) + { + shortestDistSqr = distSqr; + closestSwitch = e; + } + } + } + return closestSwitch; +} + + +// grayman #2603 - Change the flag that says if this light is being relit. + +void idLight::SetBeingRelit(bool relighting) +{ + beingRelit = relighting; +} + +// grayman #2603 - Is an AI in the process or relighting this light? + +bool idLight::IsBeingRelit() +{ + return beingRelit; +} + +// grayman #2603 - Set the chance that this light can be barked about negatively + +void idLight::SetChanceNegativeBark(float newChance) +{ + chanceNegativeBark = newChance; +} + +// grayman #2603 - Time when this light was turned off + +int idLight::GetWhenTurnedOff() +{ + return whenTurnedOff; +} + + // grayman #2603 - when can this light be relit + +int idLight::GetRelightAfter() +{ + return relightAfter; +} + +void idLight::SetRelightAfter() +{ + relightAfter = gameLocal.time + 15000; +} + + // grayman #2603 - Set when an AI can next emit a "light's out" or "won't relight" bark + +int idLight::GetNextTimeLightOutBark() +{ + return nextTimeLightOutBark; +} + +void idLight::SetNextTimeLightOutBark(int newNextTimeLightOutBark) +{ + nextTimeLightOutBark = newNextTimeLightOutBark; +} + +// grayman #2603 - can an AI make a negative bark about this light (found off, or won't relight) + +bool idLight::NegativeBark(idAI* ai) +{ + idEntityPtr aiPtr; + aiPtr = ai; + int aiBarksIndex = -1; // index of this ai in the aiBarks list + bool barking = false; + + // Don't allow barks if the Alert Level is above 1. + + if (ai->AI_AlertLevel >= ai->thresh_1) + { + return false; + } + + // Check the number of times this AI has negatively barked about this light. + // Once they reach a certain number, the barks are disallowed until the + // light is relit. + + for (int i = 0 ; i < aiBarks.Num() ; i++) + { + if (aiBarks[i].ai == aiPtr) + { + aiBarksIndex = i; // note for use below + if (aiBarks[i].count > 1) + { + return false; + } + break; + } + } + + if ((gameLocal.time >= ai->GetMemory().nextTimeLightStimBark) && (gameLocal.time >= nextTimeLightOutBark)) + { + if (gameLocal.random.RandomFloat() < chanceNegativeBark) + { + ai->GetMemory().lastTimeVisualStimBark = gameLocal.time; + ai->GetMemory().nextTimeLightStimBark = gameLocal.time + REBARK_DELAY; + nextTimeLightOutBark = gameLocal.time + REBARK_DELAY + 5*gameLocal.random.RandomFloat(); + + // As a light receives negative barks ("light out" and "won't relight light"), the odds of emitting + // this type of bark go down. When the light is relit, the odds are reset to 100%. This should reduce + // the number of such barks, which can get tiresome. + + chanceNegativeBark -= 0.2f; // reduce next chance of a negative bark + if (chanceNegativeBark < 0.0f) + { + chanceNegativeBark = 0.0f; + } + barking = true; + + // Bump the number of times this AI has negatively barked about this light. + + if (aiBarksIndex >= 0) + { + aiBarks[aiBarksIndex].count++; + } + else // create a new entry for this AI + { + AIBarks barks; + barks.count = 1; + barks.ai = aiPtr; + aiBarks.Append(barks); + } + } + } + + return barking; +} + +void idLight::Event_Smoking( int state ) // grayman #2603 +{ + smoking = (state == 1); // true: smoking, false: not smoking +} + +bool idLight::IsSmoking() // grayman #2603 +{ + return smoking; +} + +void idLight::Event_SetStartedOff() // grayman #2905 - the light was out at spawn time +{ + // Set startedOff to TRUE if this light and all of any bindmasters have shouldBeOn values == 0. + + startedOff = true; // default assumes shouldBeOn == 0 + + int shouldBeOn = spawnArgs.GetInt("shouldBeOn","0"); + if ( shouldBeOn > 0 ) + { + startedOff = false; + } + else // check for bindmasters + { + idEntity* bindMaster = GetBindMaster(); + while ( bindMaster != NULL ) + { + shouldBeOn = bindMaster->spawnArgs.GetInt("shouldBeOn","0"); + if ( shouldBeOn > 0 ) + { + startedOff = false; + break; + } + bindMaster = bindMaster->GetBindMaster(); // go up the hierarchy + } + } +} + +bool idLight::GetStartedOff() // grayman #2905 - was the light out at spawn time? +{ + return startedOff; +} + + + diff --git a/game/Light.h b/game/Light.h new file mode 100644 index 000000000..3214b841f --- /dev/null +++ b/game/Light.h @@ -0,0 +1,366 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_LIGHT_H__ +#define __GAME_LIGHT_H__ + +/* +=============================================================================== + + Generic light. + +=============================================================================== +*/ +class CLightMaterial; + +extern const idEventDef EV_Light_GetLightParm; +extern const idEventDef EV_Light_SetLightParm; +extern const idEventDef EV_Light_SetLightParms; + +class idLight : public idEntity { +public: + CLASS_PROTOTYPE( idLight ); + + idLight(); + virtual ~idLight(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + virtual void UpdateChangeableSpawnArgs( const idDict *source ); + virtual void Think( void ); + virtual void FreeLightDef( void ); + virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); + void Present( void ); + + void SaveState( idDict *args ); + virtual void SetColor( const float red, const float green, const float blue ); + virtual void SetColor( const idVec4 &color ); + virtual void GetColor( idVec3 &out ) const; + virtual void GetColor( idVec4 &out ) const; + + /** + * Tels: idLight::GetLightOrigin returns the origin of the light in the world. This + * is different from the physics origin, since the light can be offset. + */ + const idVec3 & GetLightOrigin( void ) const { return renderLight.origin; } + + const idVec3 & GetBaseColor( void ) const { return baseColor; } + void SetShader( const char *shadername ); + void SetLightParm( int parmnum, float value ); + void SetLightParms( float parm0, float parm1, float parm2, float parm3 ); + void SetRadiusXYZ( const float x, const float y, const float z ); + void SetRadius( const float radius ); + void On( void ); + void Off( const bool stopSound = true ); + void Fade( const idVec4 &to, float fadeTime ); + void FadeOut( float time ); + void FadeIn( float time ); + void FadeTo( idVec3 color, float time ); + void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + void BecomeBroken( idEntity *activator ); + qhandle_t GetLightDefHandle( void ) const { return lightDefHandle; } + void SetLightParent( idEntity *lparent ) { lightParent = lparent; } + void SetLightLevel( void ); + + /** + * greebo: Returns the current lightlevel (currentlevel). + */ + int GetLightLevel() const; + + /** + * Tels: return the current light radius. + */ + void GetRadius( idVec3 &out ) const; + + virtual void ShowEditingDialog( void ); + + enum { + EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS, + EVENT_MAXEVENTS + }; + + virtual void ClientPredictionThink( void ); + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + /** Returns a bounding box surrounding the light. + */ + idBounds GetBounds(); + /** Called to update m_renderTrigger after the render light is modified. + * Only updates the render trigger if a thread is waiting for it. + */ + void PresentRenderTrigger(); + + /** + * This will return a grayscale value dependent on the value from the light. + * X and Y are the coordinates returned by calculating the position from the + * player related to the light. The Z coordinate can be ignored. The distance + * is required when the light has no textures to calculate a falloff. + */ + float GetDistanceColor(float distance, float x, float y); + + /** + * GetTextureIndex calculates the index into the texture based on the x/y coordinates + * given and returns the index. + */ + int GetTextureIndex(float x, float y, int TextureWidth, int TextureHeight, int BytesPerPixel); + + /** + * Returns true if the light is a parallel light. + */ + inline bool IsParallel(void) { return renderLight.parallel; }; + inline bool IsPointlight(void) { return renderLight.pointLight; }; + bool CastsShadow(void); + bool IsAmbient(void); // Returns true if this is an ambient light. - J.C.Denton + + /** + * GetLightCone returns the lightdata. + * If the light is a pointlight it will return an ellipsoid defining the light. + * In case of a projected light, the returned data is a cone. + * If the light is a projected light and uses the additional vectors for + * cut off cones, it will return true. + */ + bool GetLightCone(idVec3 &Origin, idVec3 &Axis, idVec3 &Center); + bool GetLightCone(idVec3 &Origin, idVec3 &Target, idVec3 &Right, idVec3 &Up, idVec3 &Start, idVec3 &End); + + /** + * grayman #2603 - add a switch to the switch list + */ + + void AddSwitch(idEntity* newSwitch); + + /** + * grayman #2603 - If there are switches, returns the closest one to the calling user + */ + + idEntity* GetSwitch(idAI* user); + + /** + * grayman #2603 - Change the flag that says if this light is being relit. + */ + + void SetBeingRelit(bool relighting); + + /** + * grayman #2603 - Is an AI in the process or relighting this light? + */ + + bool IsBeingRelit(); + + /** + * grayman #2603 - Set the chance that this light can be barked about negatively + */ + + void SetChanceNegativeBark(float newChance); + + /** + * grayman #2603 - can an AI make a negative bark about this light (found off, or won't relight) + */ + + bool NegativeBark(idAI* ai); + + /** + * grayman #2603 - Get when the light was turned off + */ + + int GetWhenTurnedOff(); + + /** + * grayman #2603 - Get when can this light be relit + */ + + int GetRelightAfter(); + + /** + * grayman #2603 - Set when can this light be relit + */ + + void SetRelightAfter(); + + /* + * grayman #2603 - Get when an AI can next emit a "light's out" or "won't relight" bark + */ + + int GetNextTimeLightOutBark(); + + /* + * grayman #2603 - Set when an AI can next emit a "light's out" or "won't relight" bark + */ + + void SetNextTimeLightOutBark(int newNextTimeLightOutBark); + + /* + * grayman #2603 - Is a flame vertical? + */ + + bool IsVertical(float degreesFromVertical); + + /* + * grayman #2603 - flame is out and smoking? + */ + + bool IsSmoking(); + + /* + * grayman #2905 - was the light out at spawn time? + */ + + bool GetStartedOff(); + +private: + renderLight_t renderLight; // light presented to the renderer + idVec3 localLightOrigin; // light origin relative to the physics origin + idMat3 localLightAxis; // light axis relative to physics axis + qhandle_t lightDefHandle; // handle to renderer light def + int levels; + int currentLevel; + idVec3 baseColor; + bool breakOnTrigger; + int count; + int triggercount; + idEntity * lightParent; + bool beingRelit; // grayman #2603 - true if being relit + idList< idEntityPtr > switchList; // grayman #2603 - list of my switches + float chanceNegativeBark; // grayman #2603 - chance of negative barks ("light's out" and "won't relight") + int whenTurnedOff; // grayman #2603 - when this light was turned off + int nextTimeLightOutBark; // grayman #2603 - the next time an AI can bark about a light that's out, or a decision not to relight it + int relightAfter; // grayman #2603 - when a light can be relit + float nextTimeVerticalCheck; // grayman #2603 - the next time to check if a lit flame is vertical + bool smoking; // grayman #2603 - the flame model has changed to a smoke partical model; considered "out" + int whenToDouse; // grayman #2603 - when a non-vertical flame can be doused + bool startedOff; // grayman #2905 - was the light off at spawn time? + + idVec4 fadeFrom; + idVec4 fadeTo; + int fadeStart; + int fadeEnd; + bool soundWasPlaying; + + /** + * grayman #2603 - Per-AI info for counting negative barks. This allows + * lights to keep track of the number of negative barks it elicits from + * passing AI. AI are only allowed 2 negative barks per light. The list + * is cleared when the light is relit, allowing AI to once again make + * negative barks. + */ + struct AIBarks + { + // The number of negative barks for this AI + int count; + + // The AI who made them + idEntityPtr ai; + }; + + idList aiBarks; // grayman #2603 + + +private: + void PresentLightDefChange( void ); + void PresentModelDefChange( void ); + + void Event_SetShader( const char *shadername ); + void Event_GetLightParm( int parmnum ); + void Event_SetLightParm( int parmnum, float value ); + void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ); + void Event_SetRadiusXYZ( float x, float y, float z ); + void Event_SetRadius( float radius ); + void Event_Hide( void ); + void Event_Show( void ); + void Event_On( void ); + void Event_Off( void ); + void Event_ToggleOnOff( idEntity *activator ); + void Event_SetSoundHandles( void ); + void Event_FadeOut( float time ); + void Event_FadeIn( float time ); + /** + * Tels: Allows the color of the light to fade over to a new value over a time period. + */ + void Event_FadeToLight( idVec3 &color, float time ); + /** + * Allows script to get and set the light origin separate from model origin. + * Used to achieve moving lights with a stationary model + **/ + void Event_GetLightOrigin( void ); + void Event_SetLightOrigin( idVec3 &pos ); + + /** + * Allows us to get the light level, and tell if the light is on or off. + * "On" light levels are > 0.0 + */ + void Event_GetLightLevel(); + + + /* + * Add the light to the appropriate LAS area + */ + void Event_AddToLAS(); + + /** Returns 1 if the light is in PVS. + * Doesn't take into account vis-area optimizations for shadowcasting lights. + */ + void Event_InPVS(); + + /** + * grayman #2603 + */ + + void Event_Smoking(int state); + + /** + * grayman #2905 + */ + + void Event_SetStartedOff(); + + /** + * Texturename for the falloff image + */ + const char *m_MaterialName; + + /** + * Pointer to the material that is used for this light. This pointer + * is only loaded once. If the material needs to change dynamically + * for a light, the m_FalloffImage must be set to the new material name + * and m_LightMaterial must be set to NULL, to force the reload, next + * time the light should use a new material. + */ + CLightMaterial *m_LightMaterial; + +public: + + /** + * Each light also gets the maxlightradius, which determines which value + * is the maximum radius for that particular light, + */ + float m_MaxLightRadius; + + /*! + * Darkmod LAS + * The area the light is in, assigned by The Dark Mod Lighting Awareness System (LAS) + */ + int LASAreaIndex; + +}; + +#endif /* !__GAME_LIGHT_H__ */ diff --git a/DarkMod/LightController.cpp b/game/LightController.cpp similarity index 83% rename from DarkMod/LightController.cpp rename to game/LightController.cpp index a30c4377b..202906f92 100644 --- a/DarkMod/LightController.cpp +++ b/game/LightController.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2010 Tels (Donated to The Dark Mod Team) diff --git a/game/LightController.h b/game/LightController.h new file mode 100644 index 000000000..b3939dd42 --- /dev/null +++ b/game/LightController.h @@ -0,0 +1,107 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2010 Tels (Donated to The Dark Mod) + +#ifndef __DARKMOD_LIGHTCONTROLLER_H__ +#define __DARKMOD_LIGHTCONTROLLER_H__ + +/* +=============================================================================== + + Light Controller - control local ambient lights depending on which lights + are in the same area/close to them. + + This class is a singleton and initiated/destroyed from gameLocal. + +=============================================================================== +*/ + +// Defines data for each ambient light the light controller controls: +typedef struct { + idVec3 origin; + idVec3 color; // current color of the light + idVec3 target_color; // the target coloer +} light_controller_ambient_t; + +// Defines data for each light the light controller uses to control the ambients: +typedef struct { + idVec3 origin; + idVec3 color; // current color of the light + float radius; // average of the radius +} light_controller_light_t; + + +class CLightController { +public: + //CLASS_PROTOTYPE( CModelGenerator ); + + CLightController( void ); + + ~CLightController(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /** + * Called by gameLocal. + */ + void Init ( void ); + void Clear ( void ); + + /** + * Register a light with the controller. + */ + void RegisterLight ( void ); + + /** + * De-register a light with the controller. + */ + void UnregisterLight ( void ); + + /** + * Register a local ambient light with the controller. + */ + void RegisterAmbient ( void ); + + /** + * Unregister a local ambient light with the controller. + */ + void UnregisterAmbient ( void ); + + /** + * Update the local ambient lights because the light has changed. + */ + void LightChanged( const int entityNum ); + +private: + // Called by the dtor + void Shutdown(); + +private: + + idList< light_controller_ambient_t > m_Ambients; + idList< light_controller_light_t > m_Lights; + + bool m_bActive; +}; + +#endif /* !__DARKMOD_LIGHTCONTROLLER_H__ */ + diff --git a/game/LightGem.cpp b/game/LightGem.cpp new file mode 100644 index 000000000..afe8d465e --- /dev/null +++ b/game/LightGem.cpp @@ -0,0 +1,486 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "LightGem.h" + +// Temporary profiling related macros + +//#define ENABLE_PROFILING + +#ifdef ENABLE_PROFILING +#define PROFILE_BLOCK( block_tag ) \ +class __profile_block { \ + idTimer m_timeStamp; \ +public: \ + __profile_block() { \ + m_timeStamp.Start(); \ + } \ + ~__profile_block() { \ + m_timeStamp.Stop(); \ + gameLocal.Printf( #block_tag" : %lf \n\n", m_timeStamp.Milliseconds() ); \ + } \ +} _profile_blockInstance_##block_tag; \ + + +#define PROFILE_BLOCK_START( block_tag ) \ + idTimer timer##block_tag; \ + timer##block_tag.Start() \ + +// PROFILE_BLOCK_END requires PROFILE_BLOCK_START to be placed before it, to work. +#define PROFILE_BLOCK_END( block_tag ) \ + timer##block_tag.Stop(); \ + gameLocal.Printf( #block_tag": %lf \n", timer##block_tag.Milliseconds() ) \ + +#else + +#define PROFILE_BLOCK( block_tag ) +#define PROFILE_BLOCK_START( block_tag ) +#define PROFILE_BLOCK_END( block_tag ) + +#endif +//------------------------ +// Construction/Destruction +//---------------------------------------------------- +LightGem::LightGem() +{ +} + +LightGem::~LightGem() +{ + Deinitialize(); +} + + +//---------------------------------------------------- +// Initialization +//---------------------------------------------------- +void LightGem::Initialize() +{ +} + +void LightGem::Deinitialize() +{ + // free all dynamically allocated memory + m_LightgemRenderBuffer.Clear(); +} + +void LightGem::Clear() +{ + m_LightgemSurface = NULL; + m_LightgemShotSpot = 0; + for(unsigned int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) + m_LightgemShotValue[i] = 0.0; +} + +void LightGem::SpawnLightGemEntity( idMapFile * a_mapFile ) +{ + static const char *LightgemName = DARKMOD_LG_ENTITY_NAME; + idMapEntity *mapEnt = NULL; + + mapEnt = a_mapFile->FindEntity(LightgemName); + if(mapEnt == NULL) + { + mapEnt = new idMapEntity(); + a_mapFile->AddEntity(mapEnt); + mapEnt->epairs.Set("classname", "func_static"); + mapEnt->epairs.Set("name", LightgemName); + if(strlen(cv_lg_model.GetString()) == 0) + mapEnt->epairs.Set("model", DARKMOD_LG_RENDER_MODEL); + else + mapEnt->epairs.Set("model", cv_lg_model.GetString()); + mapEnt->epairs.Set("origin", "0 0 0"); + mapEnt->epairs.Set("noclipmodel", "1"); + } +} + +void LightGem::InitializeLightGemEntity( void ) +{ + m_LightgemSurface = gameLocal.FindEntity(DARKMOD_LG_ENTITY_NAME); + m_LightgemSurface.GetEntity()->GetRenderEntity()->allowSurfaceInViewID = DARKMOD_LG_VIEWID; + m_LightgemSurface.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noDynamicInteractions = false; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noShadow = true; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noSelfShadow = true; + DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("LightgemSurface: [%08lX]\r", m_LightgemSurface.GetEntity()); +} + +//---------------------------------------------------- +// State Persistence +//---------------------------------------------------- + +void LightGem::Save( idSaveGame & a_saveGame ) +{ + m_LightgemSurface.Save( &a_saveGame ); + a_saveGame.WriteInt(m_LightgemShotSpot); + for (int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) + { + a_saveGame.WriteFloat(m_LightgemShotValue[i]); + } +} + +void LightGem::Restore( idRestoreGame & a_savedGame ) +{ + m_LightgemSurface.Restore( &a_savedGame ); + a_savedGame.ReadInt(m_LightgemShotSpot); + for (int i = 0; i < DARKMOD_LG_MAX_RENDERPASSES; i++) + { + a_savedGame.ReadFloat(m_LightgemShotValue[i]); + } + + m_LightgemSurface.GetEntity()->GetRenderEntity()->allowSurfaceInViewID = DARKMOD_LG_VIEWID; + m_LightgemSurface.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noDynamicInteractions = false; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noShadow = true; + m_LightgemSurface.GetEntity()->GetRenderEntity()->noSelfShadow = true; + DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("LightgemSurface: [%08lX]\r", m_LightgemSurface.GetEntity()); +} + +//---------------------------------------------------- +// Calculation +//---------------------------------------------------- +float LightGem::Calculate(idPlayer *player) +{ + PROFILE_BLOCK( LightGem_Calculate ); + + PROFILE_BLOCK_START( LightGem_Calculate_Setup); + float dist = cv_lg_distance.GetFloat(); // reasonable distance to get a good look at the player/test model + float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]; + float fRetVal = 0.0; + int playerid; // player viewid + int headid; // head viewid + int pdef; // player modeldef + int hdef; // head modeldef + int psid; // player shadow viewid + int hsid; // head shadow viewid + int i, nRenderPasses, k, dim, l; + idStr dps; + renderView_t rv/*, rv1*/; + idEntity *lg; + renderEntity_t *prent; // Player renderentity + renderEntity_t *hrent; // Head renderentity + renderEntity_t *lgrend; + const char *dp = NULL; + + lg = m_LightgemSurface.GetEntity(); + idVec3 Cam = player->GetEyePosition(); + idVec3 Pos = player->GetPhysics()->GetOrigin(); + idVec3 LGPos = Pos; // Set the lightgem position to that of the player + LGPos.x += ( Cam.x - Pos.x ) * 0.3; // Move the lightgem out a fraction along the leaning x vector + LGPos.y += ( Cam.y - Pos.y ) * 0.3; // Move the lightgem out a fraction along the leaning y vector + LGPos.z = Cam.z; // Set the lightgem's Z-axis position to that of the player's eyes + + if (LGPos.z < Pos.z + 50 && static_cast(player->GetPlayerPhysics())->IsCrouching()) + { + // Prevent lightgem from clipping into the floor while crouching + LGPos.z = Pos.z + 50; + } + + // Adjust the modelposition with userdefined offsets. + // Move the lightgem testmodel to the players feet based on the eye position + LGPos.x += cv_lg_oxoffs.GetInteger(); + LGPos.y += cv_lg_oyoffs.GetInteger(); + LGPos.z += cv_lg_ozoffs.GetInteger(); + lg->SetOrigin(LGPos); + + memset(&rv, 0, sizeof(rv)); + + for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) + fColVal[i] = 0.0; + + for(i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) + rv.shaderParms[i] = gameLocal.globalShaderParms[i]; + + rv.globalMaterial = gameLocal.GetGlobalMaterial(); + // rv.width = SCREEN_WIDTH; + // rv.height = SCREEN_HEIGHT; + rv.width = cv_lg_screen_width.GetInteger(); + rv.height = cv_lg_screen_height.GetInteger(); + rv.fov_x = cv_lg_fov.GetInteger(); + rv.fov_y = cv_lg_fov.GetInteger(); // Bigger values means more compressed view + rv.forceUpdate = false; + rv.x = 0; + rv.y = 0; + rv.time = gameLocal.GetTime(); + + nRenderPasses = cv_lg_renderpasses.GetInteger(); + // limit the renderpasses between 1 and 4 + if(nRenderPasses < 1) nRenderPasses = 1; + if(nRenderPasses > DARKMOD_LG_MAX_RENDERPASSES) nRenderPasses = DARKMOD_LG_MAX_RENDERPASSES; + + k = cv_lg_hud.GetInteger()-1; + lgrend = lg->GetRenderEntity(); + + // Set the viewid to our private screenshot snapshot. If this number is changed + // for some reason, it has to be changed in player.cpp as well. + rv.viewID = DARKMOD_LG_VIEWID; + lgrend->suppressShadowInViewID = 0; + + if(cv_lg_player.GetBool() == false) + lgrend->allowSurfaceInViewID = rv.viewID; + else + lgrend->allowSurfaceInViewID = 0; + + // Tell the renderengine about the change for this entity. + prent = lg->GetRenderEntity(); + if((pdef = lg->GetModelDefHandle()) != -1) + gameRenderWorld->UpdateEntityDef(pdef, prent); + + prent = player->GetRenderEntity(); + hrent = player->GetHeadEntity()->GetRenderEntity(); + + playerid = prent->suppressSurfaceInViewID; + psid = prent->suppressShadowInViewID; + prent->suppressShadowInViewID = rv.viewID; + prent->suppressSurfaceInViewID = rv.viewID; + + headid = hrent->suppressSurfaceInViewID; + hsid = hrent->suppressShadowInViewID; + hrent->suppressShadowInViewID = rv.viewID; + hrent->suppressSurfaceInViewID = rv.viewID; + + if((pdef = player->GetModelDefHandle()) != -1) + gameRenderWorld->UpdateEntityDef(pdef, prent); + + if((hdef = player->GetHeadEntity()->GetModelDefHandle()) != -1) + gameRenderWorld->UpdateEntityDef(hdef, hrent); + + dim = cv_lg_image_width.GetInteger(); + if(dim <= 0 || dim > 1024) + dim = DARKMOD_LG_RENDER_WIDTH; + + fRetVal = 0.0; + +// rv1 = rv; + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("RenderTurn %u", m_LightgemShotSpot); + + PROFILE_BLOCK_END( LightGem_Calculate_Setup); + + for(i = 0; i < nRenderPasses; i++) + { + PROFILE_BLOCK( LightGem_Calculate_ForLoop); + +// rv = rv1; + rv.vieworg = LGPos; + + // If it's not the turn for this lightgem shot, then + // we skip over it. We also skip it if the splitting is disabled. + if(cv_lg_split.GetBool() == true) + { + if(m_LightgemShotSpot != i) + continue; + } + + m_LightgemShotValue[i] = 0.0; + + PROFILE_BLOCK_START( LightGem_Calculate_ForLoop_switchCase ); + switch(i) + { + case 0: // From the top to bottom + { + rv.vieworg.z += cv_lg_zoffs.GetInteger(); + rv.vieworg.z += dist; + rv.viewaxis = idMat3( + 0.0, 0.0, -1.0, + 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0 + ); + } + break; + + case 1: + { + // From bottom to top + rv.vieworg.z -= cv_lg_zoffs.GetInteger(); + rv.vieworg.z -= dist; + rv.viewaxis = idMat3( + 0.0, 0.0, 1.0, + 0.0, 1.0, 0.0, + -1.0, 0.0, 0.0 + ); + } + break; + } + PROFILE_BLOCK_END( LightGem_Calculate_ForLoop_switchCase ); + + // If the hud is enabled we either process all of them in case it is set to 0, + // then we don't care which one is actually displayed (most likely the last or + // the first one), or we only show the one that should be shown. + if(k == -1 || k == i) + { + // We always use a square image, because we render now an overhead shot which + // covers all four side of the player at once, using a diamond or pyramid shape. + // The result is an image that is split in four triangles with an angle of + // 45 degree, thus the square shape. + PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_RenderScene ); + renderSystem->CropRenderSize(dim, dim, true); + gameRenderWorld->SetRenderView(&rv); + gameRenderWorld->RenderScene(&rv); + PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_RenderScene ); + + PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_CaptureRenderToFile ); + renderSystem->CaptureRenderToFile(DARKMOD_LG_FILENAME); + PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_CaptureRenderToFile ); + + dp = cv_lg_path.GetString(); + if(dp != NULL && strlen(dp) != 0) + { + sprintf(dps, "%s_%u.tga", dp, i); + dp = dps.c_str(); + renderSystem->CaptureRenderToFile(dp); + } + else + dp = NULL; + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Rendering to lightgem render buffer\n"); + renderSystem->UnCrop(); + + PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_AnalyzeRenderImage ); + AnalyzeRenderImage(fColVal); + PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_AnalyzeRenderImage ); + + PROFILE_BLOCK_START ( LightGem_Calculate_ForLoop_Cleanup ); + + // Check which of the images has the brightest value, and this is what we will use. + for(l = 0; l < DARKMOD_LG_MAX_IMAGESPLIT; l++) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("fColVal[%u] = %f/%f\n", l, fColVal[l], m_LightgemShotValue[i]); + if(fColVal[l] > m_LightgemShotValue[i]) + m_LightgemShotValue[i] = fColVal[l]; + } + PROFILE_BLOCK_END ( LightGem_Calculate_ForLoop_Cleanup ); + } + } + + PROFILE_BLOCK_START ( LightGem_Calculate_UnSetup ); + + m_LightgemShotSpot++; + if(m_LightgemShotSpot >= nRenderPasses) + m_LightgemShotSpot = 0; + + for(i = 0; i < nRenderPasses; i++) + { + if(m_LightgemShotValue[i] > fRetVal) + fRetVal = m_LightgemShotValue[i]; + } + + prent->suppressSurfaceInViewID = playerid; + prent->suppressShadowInViewID = psid; + hrent->suppressSurfaceInViewID = headid; + hrent->suppressShadowInViewID = hsid; + + // and switch back our renderdefinition. + if(pdef != -1) + gameRenderWorld->UpdateEntityDef(pdef, prent); + + if(hdef != -1) + gameRenderWorld->UpdateEntityDef(hdef, hrent); + + PROFILE_BLOCK_END ( LightGem_Calculate_UnSetup ); + + return(fRetVal); +} + +void LightGem::AnalyzeRenderImage(float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]) +{ + CImage *im = &g_Global.m_RenderImage ; + unsigned long counter[DARKMOD_LG_MAX_IMAGESPLIT]; + int i, in, k, kn, h, x; + + im->LoadImageFromMemory(&m_LightgemRenderBuffer[0], m_LightgemRenderBuffer.Num(), DARKMOD_LG_FILENAME); + const unsigned char *buffer = im->GetImageData(); + + // This is just an errorhandling to inform the player that something is wrong. + // The lightgem will simply blink if the renderbuffer doesn't work. + if(buffer == NULL) + { + static int indicator = 0; + static int lasttime; + DM_LOG(LC_SYSTEM, LT_ERROR)LOGSTRING("Unable to read image from lightgem render-buffer\r"); + for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) + fColVal[i] = indicator; + + if(gameLocal.time/1000 != lasttime) + { + lasttime = gameLocal.time/1000; + indicator = !indicator; + } + + goto Quit; + } + + for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) + counter[i] = 0; + + // We always assume a BPP 4 here. We also always assume a square image with an even + // number of lines. An odd number might have only a very small influence though and + // most likely get canceled out if a bigger image is used. + kn = im->m_Height; + h = kn/2; + in = im->m_Width; + + // First we do the top half + for(k = 0; k < h; k++) + { + for(i = 0; i < in; i++) + { + if(i < k) + x = 0; + else if(i > kn-k-1) + x = 2; + else + x = 1; + + // The order is RGBA. + fColVal[x] += ((buffer[0] * DARKMOD_LG_RED + buffer[1] * DARKMOD_LG_GREEN + buffer[2] * DARKMOD_LG_BLUE) * DARKMOD_LG_SCALE); + counter[x]++; + buffer += im->m_Bpp; + } + } + + // Then we do the bottom half where the triangles are inverted. + for(k = (h-1); k >= 0; k--) + { + for(i = 0; i < in; i++) + { + if(i < k) + x = 0; + else if(i > kn-k-1) + x = 2; + else + x = 3; + + // The order is RGBA. + fColVal[x] += ((buffer[0] * DARKMOD_LG_RED + buffer[1] * DARKMOD_LG_GREEN + buffer[2] * DARKMOD_LG_BLUE) * DARKMOD_LG_SCALE); + counter[x]++; + buffer += im->m_Bpp; + } + } + + // Calculate the average for each value + for(i = 0; i < DARKMOD_LG_MAX_IMAGESPLIT; i++) + fColVal[i] = fColVal[i]/counter[i]; + +Quit: + return; +} diff --git a/game/LightGem.h b/game/LightGem.h new file mode 100644 index 000000000..8540c35cd --- /dev/null +++ b/game/LightGem.h @@ -0,0 +1,103 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __LIGHTGEM_H__ +#define __LIGHTGEM_H__ + +//---------------------------------- +// Preprocessor Constants +//---------------------------------- +// Number of passes that we can do at most. This is 6 because it's simply a cube that is rendered +// from all sides. This is not needed though, because a top and a bottom render with a pyramidic +// shape would be sufficient to cover all lighting situations. For silouhette detection we might +// consider more stages though. +#define DARKMOD_LG_MAX_RENDERPASSES 2 +#define DARKMOD_LG_MAX_IMAGESPLIT 4 +#define DARKMOD_LG_RENDER_MODEL "models/darkmod/misc/system/lightgem.lwo" +#define DARKMOD_LG_ENTITY_NAME "lightgem_surface" +// The lightgem viewid defines the viewid that is to be used for the lightgem surfacetestmodel +#define DARKMOD_LG_VIEWID -1 +#define DARKMOD_LG_RENDER_WIDTH 50 + +#define DARKMOD_LG_FILENAME "TDM_lightgem" +// The colour is converted to a grayscale value which determines the state +// of the lightgem. +// LightGem = (0.29900*R+0.58700*G+0.11400*B) * 0.0625 + +#define DARKMOD_LG_MIN 1 +#define DARKMOD_LG_MAX 32 +#define DARKMOD_LG_FRACTION (1.0f/32.0f) +#define DARKMOD_LG_RED 0.29900f +#define DARKMOD_LG_GREEN 0.58700f +#define DARKMOD_LG_BLUE 0.11400f +#define DARKMOD_LG_SCALE (1.0/255.0) // scaling factor for grayscale value + +//---------------------------------- +// Class Declarations. +//---------------------------------- + +class LightGem +{ +private: + int m_LightgemShotSpot; + float m_LightgemShotValue[DARKMOD_LG_MAX_RENDERPASSES]; + idEntityPtr m_LightgemSurface; + + // stgatilov: The buffer for captured lightgem image + idList m_LightgemRenderBuffer; + +public: + ID_INLINE idList &GetLightgemRenderBuffer ( void ) { return m_LightgemRenderBuffer; } + + //--------------------------------- + // Construction/Destruction + //--------------------------------- + LightGem (); + ~LightGem (); + + //--------------------------------- + // Initialization + //--------------------------------- + void Initialize (); + void Deinitialize (); + void Clear (); + + //--------------------------------- + // Persistence + //--------------------------------- + void Save ( idSaveGame & a_saveGame ); + void Restore ( idRestoreGame & a_savedGame ); + //--------------------------------- + + //--------------------------------- + // SpawnlightgemEntity will create exactly one lightgem entity for the map and ensures + // that no multiple copies of it will exist. + //--------------------------------- + void SpawnLightGemEntity( idMapFile * a_mapFile ); + void InitializeLightGemEntity(); + + //--------------------------------- + // Calculation + //--------------------------------- + float Calculate ( idPlayer * a_pPlayer ); + +private: + void AnalyzeRenderImage (float fColVal[DARKMOD_LG_MAX_IMAGESPLIT]); +}; + +#endif // __LIGHTGEM_H__ \ No newline at end of file diff --git a/game/Liquid.cpp b/game/Liquid.cpp new file mode 100644 index 000000000..ca623cb0e --- /dev/null +++ b/game/Liquid.cpp @@ -0,0 +1,283 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "StimResponse/StimResponseCollection.h" + +#ifdef MOD_WATERPHYSICS + +// We do these splashes if the mass of the colliding object is less than these values. +// Anything large than MEDIUM_SPLASH does a large splash. (get it?) +const int SMALL_SPLASH = 5; +const int MEDIUM_SPLASH = 20; + +/* +=============================================================================== + + idLiquid + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idLiquid ) + EVENT( EV_Touch, idLiquid::Event_Touch ) +END_CLASS + +idLiquid::idLiquid( void ) { +} + +/* +================ +idLiquid::Save +================ +*/ +void idLiquid::Save( idSaveGame *savefile ) const { + + int i; + + savefile->WriteStaticObject( this->physicsObj ); + + savefile->WriteString(smokeName.c_str()); + savefile->WriteString(soundName.c_str()); + + for( i = 0; i < 3; i++ ) + savefile->WriteParticle(this->splash[i]); + savefile->WriteParticle(this->waves); +} + +/* +================ +idLiquid::Restore +================ +*/ +void idLiquid::Restore( idRestoreGame *savefile ) { + + int i; + + savefile->ReadStaticObject( this->physicsObj ); + RestorePhysics( &this->physicsObj ); + + savefile->ReadString(this->smokeName); + savefile->ReadString(this->soundName); + + for( i = 0; i < 3; i++ ) + savefile->ReadParticle(this->splash[i]); + savefile->ReadParticle(this->waves); +} + +idLiquid::~idLiquid() +{ + // Traverse all spawned entities and remove ourselves as water if necessary + for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + if (ent->GetPhysics() != NULL && ent->GetPhysics()->GetWater() == &physicsObj) + { + ent->GetPhysics()->SetWater(NULL, 0.0f); + } + } +} + +/* +================ +idLiquid::Spawn +================ +*/ +void idLiquid::Spawn() { +/* + model = dynamic_cast( renderEntity.hModel ); + if ( !model ) { + gameLocal.Error( "Entity '%s' must have liquid model", name.c_str() ); + } + model->Reset(); +*/ + float liquidDensity; + float liquidViscosity; + float liquidFriction; + idVec3 minSplash; + idVec3 minWave; + idStr temp; + const char *splashName; + + //common->Printf("idLiquid:%s) Spawned\n",this->GetName() ); + + // getters + spawnArgs.GetFloat("density","0.001043f",liquidDensity); + spawnArgs.GetFloat("viscosity","3.0f",liquidViscosity); + spawnArgs.GetFloat("friction","3.0f",liquidFriction); + spawnArgs.GetString("liquid_name","water",temp); + spawnArgs.GetVector("minSplashVelocity","100 100 100",minSplash); + spawnArgs.GetVector("minWaveVelocity","60 60 60",minWave); + + // setters + this->smokeName = "smoke_"; + this->smokeName.Append(temp); + + this->soundName = "snd_"; + this->soundName.Append(temp); + + splashName = spawnArgs.GetString("smoke_small","water_splash_small"); + this->splash[0] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); + + splashName = spawnArgs.GetString("smoke_medium","water_splash"); + this->splash[1] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); + + splashName = spawnArgs.GetString("smoke_large","water_splash_large"); + this->splash[2] = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); + + splashName = spawnArgs.GetString("smoke_waves","water_waves"); + this->waves = static_cast(declManager->FindType(DECL_PARTICLE,splashName)); + + // setup physics + this->physicsObj.SetSelf(this); + this->physicsObj.SetClipModel( new idClipModel(this->GetPhysics()->GetClipModel()), liquidDensity ); + this->physicsObj.SetOrigin(this->GetPhysics()->GetOrigin()); + this->physicsObj.SetAxis(this->GetPhysics()->GetAxis()); + this->physicsObj.SetGravity( gameLocal.GetGravity() ); + this->physicsObj.SetContents( CONTENTS_WATER | CONTENTS_TRIGGER ); + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + this->physicsObj.SetDensity(liquidDensity); + this->physicsObj.SetViscosity(liquidViscosity); + this->physicsObj.SetMinSplashVelocity(minSplash); + this->physicsObj.SetMinWaveVelocity(minWave); + + this->SetPhysics( &this->physicsObj ); + + renderEntity.shaderParms[ 3 ] = spawnArgs.GetFloat( "shaderParm3", "1" ); + renderEntity.shaderParms[ 4 ] = spawnArgs.GetFloat( "shaderParm4", "0" ); + renderEntity.shaderParms[ 5 ] = spawnArgs.GetFloat( "shaderParm5", "0.1" ); + renderEntity.shaderParms[ 6 ] = spawnArgs.GetFloat( "shaderParm6", "1.5" ); + renderEntity.shaderParms[ 7 ] = spawnArgs.GetFloat( "shaderParm7", "0" ); + renderEntity.shaderParms[ 8 ] = spawnArgs.GetFloat( "shaderParm8", "0" ); + renderEntity.shaderParms[ 9 ] = spawnArgs.GetFloat( "shaderParm9", "0" ); + renderEntity.shaderParms[ 10 ] = spawnArgs.GetFloat( "shaderParm10", "0" ); + renderEntity.shaderParms[ 11 ] = spawnArgs.GetFloat( "shaderParm11", "0" ); + + BecomeActive( TH_THINK ); +} + +/* +================ +idLiquid::Event_Touch + + This is mainly used for actors who touch the liquid, it spawns a splash + near they're feet if they're moving fast enough. +================ +*/ +void idLiquid::Event_Touch( idEntity *other, trace_t *trace ) { +// FIXME: for QuakeCon +/* + idVec3 pos; + + pos = other->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + model->IntersectBounds( other->GetPhysics()->GetBounds().Translate( pos ), -10.0f ); +*/ + + idPhysics_Liquid *liquid; + idPhysics_Actor *phys; + + if( !other->GetPhysics()->IsType(idPhysics_Actor::Type) ) + return; + + phys = static_cast(other->GetPhysics()); + if( phys->GetWaterLevel() != WATERLEVEL_FEET ) + return; + + impactInfo_t info; + other->GetImpactInfo(this,trace->c.id,trace->c.point,&info); + liquid = &this->physicsObj; + + trace->c.point = info.position + other->GetPhysics()->GetOrigin(); + trace->c.entityNum = other->entityNumber; + + // stop actors from constantly splashing when they're in the water + // (this is such a bad thing to do!!!) + // TODO: Fixme... + // 1) Probably the best way to fix this is put a wait timer inside the actor and have this + // function set/reset that timer for when the actor should spawn particles at it's feet. + // 2) Actors don't spawn particles at their feet, it's usually at the origin, for some + // reason info.position is (null), needs a fix so that splash position is correct + if( gameLocal.random.RandomFloat() > 0.5f ) + return; + + this->Collide(*trace,info.velocity); +} + +/* +================ +idLiquid::Collide + Spawns a splash particle and attaches a sound to the colliding entity. +================ +*/ +bool idLiquid::Collide( const trace_t &collision, const idVec3 &velocity ) { + idEntity *e = gameLocal.entities[collision.c.entityNum]; + idPhysics_Liquid *phys = static_cast( this->GetPhysics() ); + const idDeclParticle *splash; + const char *sName; + float eMass; + idVec3 splashSpot; + float velSquare = velocity.LengthSqr(); + + ProcCollisionStims( e, collision.c.id ); + + eMass = e->GetPhysics()->GetMass(); + splashSpot = collision.c.point; + + if( velSquare > phys->GetMinSplashVelocity().LengthSqr() ) { + // pick which splash particle to spawn + // first we check the entity, if it's not defined we use + // one defined for this liquid. + sName = e->spawnArgs.GetString(this->smokeName.c_str()); + if( *sName != '\0' ) { + // load entity particle + splash = static_cast(declManager->FindType(DECL_PARTICLE,sName)); + } + else { + // load a liquid particle based on the mass of the splashing entity + if( eMass < SMALL_SPLASH ) + splash = this->splash[0]; + else if( eMass < MEDIUM_SPLASH ) + splash = this->splash[1]; + else + splash = this->splash[2]; + } + + // only play the sound for a splash + e->StartSound( this->soundName.c_str(), SND_CHANNEL_ANY, 0, false, NULL); + } + else if( velSquare > phys->GetMinWaveVelocity().LengthSqr() ) { + splash = this->waves; + } + else { + // the object is moving to slow so we abort + return true; + } + + // spawn the particle + gameLocal.smokeParticles->EmitSmoke( splash, gameLocal.time, gameLocal.random.RandomFloat(), splashSpot, collision.endAxis ); + return true; +} + +#endif diff --git a/game/Liquid.h b/game/Liquid.h new file mode 100644 index 000000000..7c4f2d515 --- /dev/null +++ b/game/Liquid.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LIQUID_H__ +#define __LIQUID_H__ + +/* +=============================================================================== + + idLiquid + + Base class for all liquid object. The entity part of the liquid is + responsible for spawning splashes and sounds to match. + + The physics portion is as usual, responsible for the physics. +=============================================================================== +*/ + +#define MOD_WATERPHYSICS_VER "Water Physics 0.8 ^7by Lloyd" +#ifdef MOD_WATERPHYSICS + +class idRenderModelLiquid; + +class idLiquid : public idEntity { +public: + CLASS_PROTOTYPE( idLiquid ); + + idLiquid( void ); + + virtual ~idLiquid(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + +private: + void Event_Touch( idEntity *other, trace_t *trace ); + + idPhysics_Liquid physicsObj; + + idRenderModelLiquid *model; + + const idDeclParticle *splash[3]; + const idDeclParticle *waves; + + idStr smokeName; + idStr soundName; +}; + +#endif // MOD_WATERPHYISCS +#endif // __LIQUID_H__ diff --git a/DarkMod/MaterialConverter.cpp b/game/MaterialConverter.cpp similarity index 98% rename from DarkMod/MaterialConverter.cpp rename to game/MaterialConverter.cpp index 317b38a24..392bca7dd 100644 --- a/DarkMod/MaterialConverter.cpp +++ b/game/MaterialConverter.cpp @@ -1,16 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop -#include "../game/game_local.h" +#include "Game_local.h" #include "MaterialConverter.h" MaterialConversionStatusReport::MaterialConversionStatusReport() diff --git a/DarkMod/MaterialConverter.h b/game/MaterialConverter.h similarity index 84% rename from DarkMod/MaterialConverter.h rename to game/MaterialConverter.h index e74b42374..2b1e65b83 100644 --- a/DarkMod/MaterialConverter.h +++ b/game/MaterialConverter.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef TDM_MATERIAL_CONVERTER_H_ #define TDM_MATERIAL_CONVERTER_H_ diff --git a/DarkMod/MatrixSq.h b/game/MatrixSq.h similarity index 91% rename from DarkMod/MatrixSq.h rename to game/MatrixSq.h index 77ad89d14..47cfa3509 100644 --- a/DarkMod/MatrixSq.h +++ b/game/MatrixSq.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /******************************************************** * * CLASS DESCRIPTION: @@ -18,6 +28,7 @@ #ifndef MATRIXSQ_H #define MATRIXSQ_H +#include "DarkModGlobals.h" #include template diff --git a/DarkMod/MeleeWeapon.cpp b/game/MeleeWeapon.cpp similarity index 98% rename from DarkMod/MeleeWeapon.cpp rename to game/MeleeWeapon.cpp index fd90985a2..f290fdec0 100644 --- a/DarkMod/MeleeWeapon.cpp +++ b/game/MeleeWeapon.cpp @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "Grabber.h" #include "DarkModGlobals.h" #include "MeleeWeapon.h" diff --git a/DarkMod/MeleeWeapon.h b/game/MeleeWeapon.h similarity index 90% rename from DarkMod/MeleeWeapon.h rename to game/MeleeWeapon.h index 26fc04ddf..d4175799c 100644 --- a/DarkMod/MeleeWeapon.h +++ b/game/MeleeWeapon.h @@ -1,17 +1,27 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __MELEEWEAPON_H__ #define __MELEEWEAPON_H__ -#include "../game/entity.h" -#include "../game/actor.h" +#include "Entity.h" +#include "Actor.h" class idPlayer; diff --git a/game/Misc.cpp b/game/Misc.cpp new file mode 100644 index 000000000..49d79b1cd --- /dev/null +++ b/game/Misc.cpp @@ -0,0 +1,3436 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* + +Various utility objects and functions. + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "SndProp.h" +#include "EscapePointManager.h" +#include "Objectives/MissionData.h" +#include "StimResponse/StimResponseCollection.h" + +/* +=============================================================================== + +idSpawnableEntity + +A simple, spawnable entity with a model and no functionable ability of it's own. +For example, it can be used as a placeholder during development, for marking +locations on maps for script, or for simple placed models without any behavior +that can be bound to other entities. Should not be subclassed. +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idSpawnableEntity ) +END_CLASS + +/* +====================== +idSpawnableEntity::Spawn +====================== +*/ +void idSpawnableEntity::Spawn() { + // this just holds dict information +} + +/* +=============================================================================== + + idPlayerStart + +=============================================================================== +*/ + +const idEventDef EV_TeleportStage( "", "e" ); + +CLASS_DECLARATION( idEntity, idPlayerStart ) + EVENT( EV_Activate, idPlayerStart::Event_TeleportPlayer ) + EVENT( EV_TeleportStage, idPlayerStart::Event_TeleportStage ) +END_CLASS + +/* +=============== +idPlayerStart::idPlayerStart +================ +*/ +idPlayerStart::idPlayerStart( void ) { + teleportStage = 0; +} + +/* +=============== +idPlayerStart::Spawn +================ +*/ +void idPlayerStart::Spawn( void ) { + teleportStage = 0; +} + +/* +================ +idPlayerStart::Save +================ +*/ +void idPlayerStart::Save( idSaveGame *savefile ) const { + savefile->WriteInt( teleportStage ); +} + +/* +================ +idPlayerStart::Restore +================ +*/ +void idPlayerStart::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( teleportStage ); +} + +/* +================ +idPlayerStart::ClientReceiveEvent +================ +*/ +bool idPlayerStart::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + int entityNumber; + + switch( event ) { + case EVENT_TELEPORTPLAYER: { + entityNumber = msg.ReadBits( GENTITYNUM_BITS ); + idPlayer *player = static_cast( gameLocal.entities[entityNumber] ); + if ( player != NULL && player->IsType( idPlayer::Type ) ) { + Event_TeleportPlayer( player ); + } + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +=============== +idPlayerStart::Event_TeleportStage + +FIXME: add functionality to fx system ( could be done with player scripting too ) +================ +*/ +void idPlayerStart::Event_TeleportStage( idEntity *_player ) { + idPlayer *player; + + if ( !_player->IsType( idPlayer::Type ) ) { + + common->Warning( "idPlayerStart::Event_TeleportStage: entity is not an idPlayer\n" ); + + return; + + } + + player = static_cast(_player); + + float teleportDelay = spawnArgs.GetFloat( "teleportDelay" ); + switch ( teleportStage ) { + case 0: + player->playerView.Flash( colorWhite, 125 ); + player->SetInfluenceLevel( INFLUENCE_LEVEL3 ); + player->SetInfluenceView( spawnArgs.GetString( "mtr_teleportFx" ), NULL, 0.0f, NULL ); + gameSoundWorld->FadeSoundClasses( 0, -20.0f, teleportDelay ); + player->StartSound( "snd_teleport_start", SND_CHANNEL_BODY2, 0, false, NULL ); + teleportStage++; + PostEventSec( &EV_TeleportStage, teleportDelay, player ); + break; + case 1: + gameSoundWorld->FadeSoundClasses( 0, 0.0f, 0.25f ); + teleportStage++; + PostEventSec( &EV_TeleportStage, 0.25f, player ); + break; + case 2: + player->SetInfluenceView( NULL, NULL, 0.0f, NULL ); + TeleportPlayer( player ); + player->StopSound( SND_CHANNEL_BODY2, false ); + player->SetInfluenceLevel( INFLUENCE_NONE ); + teleportStage = 0; + break; + default: + break; + } +} + +/* +=============== +idPlayerStart::TeleportPlayer +================ +*/ +void idPlayerStart::TeleportPlayer( idPlayer *player ) { + float pushVel = spawnArgs.GetFloat( "push", "300" ); + float f = spawnArgs.GetFloat( "visualEffect", "0" ); + const char *viewName = spawnArgs.GetString( "visualView", "" ); + idEntity *ent = viewName ? gameLocal.FindEntity( viewName ) : NULL; + + if ( f && ent ) { + // place in private camera view for some time + // the entity needs to teleport to where the camera view is to have the PVS right + player->Teleport( ent->GetPhysics()->GetOrigin(), ang_zero, this ); + player->StartSound( "snd_teleport_enter", SND_CHANNEL_ANY, 0, false, NULL ); + player->SetPrivateCameraView( static_cast(ent) ); + // the player entity knows where to spawn from the previous Teleport call + if ( !gameLocal.isClient ) { + player->PostEventSec( &EV_Player_ExitTeleporter, f ); + } + } else { + // direct to exit, Teleport will take care of the killbox + player->Teleport( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis().ToAngles(), NULL ); + + // multiplayer hijacked this entity, so only push the player in multiplayer + if ( gameLocal.isMultiplayer ) { + player->GetPhysics()->SetLinearVelocity( GetPhysics()->GetAxis()[0] * pushVel ); + } + } +} + +/* +=============== +idPlayerStart::Event_TeleportPlayer +================ +*/ +void idPlayerStart::Event_TeleportPlayer( idEntity *activator ) { + idPlayer *player; + + if ( activator->IsType( idPlayer::Type ) ) { + player = static_cast( activator ); + } else { + player = gameLocal.GetLocalPlayer(); + } + if ( player ) { + if ( spawnArgs.GetBool( "visualFx" ) ) { + + teleportStage = 0; + Event_TeleportStage( player ); + + } else { + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteBits( player->entityNumber, GENTITYNUM_BITS ); + ServerSendEvent( EVENT_TELEPORTPLAYER, &msg, false, -1 ); + } + + TeleportPlayer( player ); + } + } +} + +/* +=============================================================================== + + idActivator + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idActivator ) + EVENT( EV_Activate, idActivator::Event_Activate ) +END_CLASS + +/* +=============== +idActivator::Save +================ +*/ +void idActivator::Save( idSaveGame *savefile ) const { + savefile->WriteBool( stay_on ); +} + +/* +=============== +idActivator::Restore +================ +*/ +void idActivator::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( stay_on ); + + if ( stay_on ) { + BecomeActive( TH_THINK ); + } +} + +/* +=============== +idActivator::Spawn +================ +*/ +void idActivator::Spawn( void ) { + bool start_off; + + spawnArgs.GetBool( "stay_on", "0", stay_on ); + spawnArgs.GetBool( "start_off", "0", start_off ); + + GetPhysics()->SetClipBox( idBounds( vec3_origin ).Expand( 4 ), 1.0f ); + GetPhysics()->SetContents( 0 ); + + if ( !start_off ) { + BecomeActive( TH_THINK ); + } +} + +/* +=============== +idActivator::Think +================ +*/ +void idActivator::Think( void ) { + RunPhysics(); + if ( thinkFlags & TH_THINK ) { + if ( TouchTriggers() ) { + if ( !stay_on ) { + BecomeInactive( TH_THINK ); + } + } + } + Present(); +} + +/* +=============== +idActivator::Activate +================ +*/ +void idActivator::Event_Activate( idEntity *activator ) { + if ( thinkFlags & TH_THINK ) { + BecomeInactive( TH_THINK ); + } else { + BecomeActive( TH_THINK ); + } +} + + +/* +=============================================================================== + +idPathCorner + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idPathCorner ) + EVENT( AI_RandomPath, idPathCorner::Event_RandomPath ) +END_CLASS + +/* +===================== +idPathCorner::Spawn +===================== +*/ +void idPathCorner::Spawn( void ) { +} + +/* +===================== +idPathCorner::DrawDebugInfo +===================== +*/ +void idPathCorner::DrawDebugInfo( void ) { + idEntity *ent; + idBounds bnds( idVec3( -4.0, -4.0f, -8.0f ), idVec3( 4.0, 4.0f, 64.0f ) ); + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( !ent->IsType( idPathCorner::Type ) ) { + continue; + } + + idVec3 org = ent->GetPhysics()->GetOrigin(); + gameRenderWorld->DebugBounds( colorRed, bnds, org, 0 ); + } +} + +/* +============ +idPathCorner::RandomPath +============ +*/ +idPathCorner *idPathCorner::RandomPath( const idEntity *source, const idEntity *ignore, idAI* owner ) { + idPathCorner *path[ MAX_GENTITIES ]; + + int num(0); + float rand(gameLocal.random.RandomFloat()); + float accumulatedChance(0); + float maxChance(0); + + idEntity* candidate(NULL); + + for (int i = 0; i < source->targets.Num(); i++ ) { + idEntity* ent = source->targets[ i ].GetEntity(); + if ( ent && ( ent != ignore ) && ent->IsType( idPathCorner::Type ) ) + { + + if (owner) + { + if (owner->HasSeenEvidence() && ent->spawnArgs.GetBool("idle_only", "0")) + { + continue; + } + else if (!owner->HasSeenEvidence() && ent->spawnArgs.GetBool("alert_idle_only", "0")) + { + continue; + } + } + + float chance = ent->spawnArgs.GetFloat("chance", "0"); + if (chance) + { + // angua: path has chance spawn arg set + // sum of the probability of this path and of the previous ones + accumulatedChance += chance; + + // if the random number is between the current and the previous sum, this is our next path + if (rand < accumulatedChance) + { + return static_cast( ent ); + } + + // store the path with the highest chance + if (chance > maxChance) + { + maxChance = chance; + candidate = ent; + } + } + else + { + // path doesn't have chance spawn arg set + // add to list + path[ num++ ] = static_cast( ent ); + if ( num >= MAX_GENTITIES ) { + break; + } + } + } + } + + // probability comparison didn't return a path + + // no path without chance spawn arg (chance sum is < 1) + if ( !num ) { + if (candidate) + { + // return the path with the highest chance + return static_cast(candidate); + } + return NULL; + } + + // choose one from the list + int which = gameLocal.random.RandomInt( num ); + return path[ which ]; +} + +/* +===================== +idPathCorner::Event_RandomPath +===================== +*/ +void idPathCorner::Event_RandomPath( void ) { + idPathCorner *path; + + path = RandomPath( this, NULL, NULL ); + idThread::ReturnEntity( path ); +} + +/* +=============================================================================== + +tdmPathFlee + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, tdmPathFlee ) +END_CLASS + +tdmPathFlee::~tdmPathFlee() +{ + // Unregister self with the escape point manager + gameLocal.m_EscapePointManager->RemoveEscapePoint(this); +} + +/* +===================== +tdmPathFlee::Spawn +===================== +*/ +void tdmPathFlee::Spawn( void ) { + + // Get the location of this entity within the AAS + + + // Register this class with the escape point manager + gameLocal.m_EscapePointManager->AddEscapePoint(this); +} + +/* +=============================================================================== + + idDamagable + +=============================================================================== +*/ + +const idEventDef EV_RestoreDamagable( "" ); + +CLASS_DECLARATION( idEntity, idDamagable ) + EVENT( EV_Activate, idDamagable::Event_BecomeBroken ) + EVENT( EV_RestoreDamagable, idDamagable::Event_RestoreDamagable ) +END_CLASS + +/* +================ +idDamagable::idDamagable +================ +*/ +idDamagable::idDamagable( void ) { + count = 0; + nextTriggerTime = 0; +} + +/* +================ +idDamagable::Save +================ +*/ +void idDamagable::Save( idSaveGame *savefile ) const { + savefile->WriteInt( count ); + savefile->WriteInt( nextTriggerTime ); +} + +/* +================ +idDamagable::Restore +================ +*/ +void idDamagable::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( count ); + savefile->ReadInt( nextTriggerTime ); +} + +/* +================ +idDamagable::Spawn +================ +*/ +void idDamagable::Spawn( void ) +{ + idStr broken; + + health = spawnArgs.GetInt( "health", "5" ); + spawnArgs.GetInt( "count", "1", count ); + nextTriggerTime = 0; + + // make sure the model gets cached + spawnArgs.GetString( "broken", "", broken ); + if ( broken.Length() && !renderModelManager->CheckModel( broken ) ) { + gameLocal.Error( "idDamagable '%s' at (%s): cannot load broken model '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), broken.c_str() ); + } + + fl.takedamage = true; + GetPhysics()->SetContents( CONTENTS_SOLID ); + if( m_CustomContents != -1 ) + GetPhysics()->SetContents( m_CustomContents ); + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); +} + +/* +================ +idDamagable::BecomeBroken +================ +*/ +void idDamagable::BecomeBroken( idEntity *activator ) { + float forceState; + int numStates; + int cycle; + float wait; + + if ( gameLocal.time < nextTriggerTime ) { + return; + } + + spawnArgs.GetFloat( "wait", "0.1", wait ); + nextTriggerTime = gameLocal.time + SEC2MS( wait ); + if ( count > 0 ) { + count--; + if ( !count ) { + fl.takedamage = false; + } else { + health = spawnArgs.GetInt( "health", "5" ); + } + } + + idStr broken; + + spawnArgs.GetString( "broken", "", broken ); + if ( broken.Length() ) { + SetModel( broken ); + } + + // offset the start time of the shader to sync it to the gameLocal time + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + spawnArgs.GetInt( "numstates", "1", numStates ); + spawnArgs.GetInt( "cycle", "0", cycle ); + spawnArgs.GetFloat( "forcestate", "0", forceState ); + + // set the state parm + if ( cycle ) { + renderEntity.shaderParms[ SHADERPARM_MODE ]++; + if ( renderEntity.shaderParms[ SHADERPARM_MODE ] > numStates ) { + renderEntity.shaderParms[ SHADERPARM_MODE ] = 0; + } + } else if ( forceState ) { + renderEntity.shaderParms[ SHADERPARM_MODE ] = forceState; + } else { + renderEntity.shaderParms[ SHADERPARM_MODE ] = gameLocal.random.RandomInt( numStates ) + 1; + } + + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + ActivateTargets( activator ); + + if ( spawnArgs.GetBool( "hideWhenBroken" ) ) { + Hide(); + PostEventMS( &EV_RestoreDamagable, nextTriggerTime - gameLocal.time ); + BecomeActive( TH_THINK ); + } +} + +/* +================ +idDamagable::Killed +================ +*/ +void idDamagable::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) +{ + bool bPlayerResponsible(false); + + if ( gameLocal.time < nextTriggerTime ) + { + health += damage; + return; + } + + if ( attacker && attacker->IsType( idPlayer::Type ) ) + bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); + else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) + bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); + + gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); + BecomeBroken( attacker ); +} + +/* +================ +idDamagable::Event_BecomeBroken +================ +*/ +void idDamagable::Event_BecomeBroken( idEntity *activator ) { + BecomeBroken( activator ); +} + +/* +================ +idDamagable::Event_RestoreDamagable +================ +*/ +void idDamagable::Event_RestoreDamagable( void ) { + health = spawnArgs.GetInt( "health", "5" ); + Show(); +} + + +/* +=============================================================================== + + idExplodable + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idExplodable ) + EVENT( EV_Activate, idExplodable::Event_Explode ) +END_CLASS + +/* +================ +idExplodable::Spawn +================ +*/ +void idExplodable::Spawn( void ) { + Hide(); +} + +/* +================ +idExplodable::Event_Explode +================ +*/ +void idExplodable::Event_Explode( idEntity *activator ) { + const char *temp; + + if ( spawnArgs.GetString( "def_damage", "damage_explosion", &temp ) ) { + gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), activator, activator, this, this, temp ); + } + + StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL ); + + // Show() calls UpdateVisuals, so we don't need to call it ourselves after setting the shaderParms + renderEntity.shaderParms[SHADERPARM_RED] = 1.0f; + renderEntity.shaderParms[SHADERPARM_GREEN] = 1.0f; + renderEntity.shaderParms[SHADERPARM_BLUE] = 1.0f; + renderEntity.shaderParms[SHADERPARM_ALPHA] = 1.0f; + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + renderEntity.shaderParms[SHADERPARM_DIVERSITY] = 0.0f; + Show(); + + PostEventMS( &EV_Remove, 2000 ); + + ActivateTargets( activator ); +} + + +/* +=============================================================================== + + idSpring + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idSpring ) + EVENT( EV_PostSpawn, idSpring::Event_LinkSpring ) +END_CLASS + +/* +================ +idSpring::Think +================ +*/ +void idSpring::Think( void ) { + idVec3 start, end, origin; + idMat3 axis; + + // run physics + RunPhysics(); + + if ( thinkFlags & TH_THINK ) { + // evaluate force + spring.Evaluate( gameLocal.time ); + + start = p1; + if ( ent1->GetPhysics() ) { + axis = ent1->GetPhysics()->GetAxis(); + origin = ent1->GetPhysics()->GetOrigin(); + start = origin + start * axis; + } + + end = p2; + if ( ent2->GetPhysics() ) { + axis = ent2->GetPhysics()->GetAxis(); + origin = ent2->GetPhysics()->GetOrigin(); + end = origin + p2 * axis; + } + + gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true ); + } + + Present(); +} + +/* +================ +idSpring::Event_LinkSpring +================ +*/ +void idSpring::Event_LinkSpring( void ) { + idStr name1, name2; + + spawnArgs.GetString( "ent1", "", name1 ); + spawnArgs.GetString( "ent2", "", name2 ); + + if ( name1.Length() ) { + ent1 = gameLocal.FindEntity( name1 ); + if ( !ent1 ) { + gameLocal.Error( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() ); + } + } + else { + ent1 = gameLocal.entities[ENTITYNUM_WORLD]; + } + + if ( name2.Length() ) { + ent2 = gameLocal.FindEntity( name2 ); + if ( !ent2 ) { + gameLocal.Error( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() ); + } + } + else { + ent2 = gameLocal.entities[ENTITYNUM_WORLD]; + } + spring.SetPosition( ent1->GetPhysics(), id1, p1, ent2->GetPhysics(), id2, p2 ); + BecomeActive( TH_THINK ); +} + +/* +================ +idSpring::Spawn +================ +*/ +void idSpring::Spawn( void ) { + float Kstretch, damping, restLength; + + spawnArgs.GetInt( "id1", "0", id1 ); + spawnArgs.GetInt( "id2", "0", id2 ); + spawnArgs.GetVector( "point1", "0 0 0", p1 ); + spawnArgs.GetVector( "point2", "0 0 0", p2 ); + spawnArgs.GetFloat( "constant", "100.0f", Kstretch ); + spawnArgs.GetFloat( "damping", "10.0f", damping ); + spawnArgs.GetFloat( "restlength", "0.0f", restLength ); + + spring.InitSpring( Kstretch, 0.0f, damping, restLength ); + + ent1 = ent2 = NULL; + + PostEventMS( &EV_PostSpawn, 0 ); +} + +/* +=============================================================================== + + idForceField + +=============================================================================== +*/ + +const idEventDef EV_Toggle( "Toggle", NULL ); + +CLASS_DECLARATION( idEntity, idForceField ) + EVENT( EV_Activate, idForceField::Event_Activate ) + EVENT( EV_Toggle, idForceField::Event_Toggle ) + EVENT( EV_FindTargets, idForceField::Event_FindTargets ) +END_CLASS + +/* +=============== +idForceField::Toggle +================ +*/ +void idForceField::Toggle( void ) { + if ( thinkFlags & TH_THINK ) { + BecomeInactive( TH_THINK ); + } else { + BecomeActive( TH_THINK ); + } +} + +/* +================ +idForceField::Think +================ +*/ +void idForceField::Think( void ) { + if ( thinkFlags & TH_THINK ) { + // evaluate force + forceField.Evaluate( gameLocal.time ); + } + Present(); +} + +/* +================ +idForceField::Save +================ +*/ +void idForceField::Save( idSaveGame *savefile ) const { + savefile->WriteStaticObject( forceField ); +} + +/* +================ +idForceField::Restore +================ +*/ +void idForceField::Restore( idRestoreGame *savefile ) { + savefile->ReadStaticObject( forceField ); +} + +/* +================ +idForceField::Spawn +================ +*/ +void idForceField::Spawn( void ) { + idVec3 uniform; + float explosion, implosion, randomTorque; + + if ( spawnArgs.GetVector( "uniform", "0 0 0", uniform ) ) { + forceField.Uniform( uniform ); + } else if ( spawnArgs.GetFloat( "explosion", "0", explosion ) ) { + forceField.Explosion( explosion ); + } else if ( spawnArgs.GetFloat( "implosion", "0", implosion ) ) { + forceField.Implosion( implosion ); + } + + if ( spawnArgs.GetFloat( "randomTorque", "0", randomTorque ) ) { + forceField.RandomTorque( randomTorque ); + } + + if ( spawnArgs.GetBool( "applyForce", "0" ) ) { + forceField.SetApplyType( FORCEFIELD_APPLY_FORCE ); + } else if ( spawnArgs.GetBool( "applyImpulse", "0" ) ) { + forceField.SetApplyType( FORCEFIELD_APPLY_IMPULSE ); + } else { + forceField.SetApplyType( FORCEFIELD_APPLY_VELOCITY ); + } + + forceField.SetPlayerOnly( spawnArgs.GetBool( "playerOnly", "0" ) ); + forceField.SetMonsterOnly( spawnArgs.GetBool( "monsterOnly", "0" ) ); + + // set the collision model on the force field + forceField.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ) ); + + // remove the collision model from the physics object + GetPhysics()->SetClipModel( NULL, 1.0f ); + + if ( spawnArgs.GetBool( "start_on" ) ) { + BecomeActive( TH_THINK ); + } +} + +/* +=============== +idForceField::Event_Toggle +================ +*/ +void idForceField::Event_Toggle( void ) { + Toggle(); +} + +/* +================ +idForceField::Event_Activate +================ +*/ +void idForceField::Event_Activate( idEntity *activator ) { + float wait; + + Toggle(); + if ( spawnArgs.GetFloat( "wait", "0.01", wait ) ) { + PostEventSec( &EV_Toggle, wait ); + } +} + +/* +================ +idForceField::Event_FindTargets +================ +*/ +void idForceField::Event_FindTargets( void ) { + FindTargets(); + RemoveNullTargets(); + if ( targets.Num() ) { + forceField.Uniform( targets[0].GetEntity()->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ); + } +} + + +/* +=============================================================================== + + idAnimated + +=============================================================================== +*/ + +const idEventDef EV_Animated_Start( "" ); +const idEventDef EV_LaunchMissiles( "launchMissiles", "ssssdf" ); +const idEventDef EV_LaunchMissilesUpdate( "", "dddd" ); +const idEventDef EV_AnimDone( "", "d" ); +const idEventDef EV_StartRagdoll( "startRagdoll" ); + +CLASS_DECLARATION( idAFEntity_Gibbable, idAnimated ) + EVENT( EV_Activate, idAnimated::Event_Activate ) + EVENT( EV_Animated_Start, idAnimated::Event_Start ) + EVENT( EV_StartRagdoll, idAnimated::Event_StartRagdoll ) + EVENT( EV_AnimDone, idAnimated::Event_AnimDone ) + EVENT( EV_Footstep, idAnimated::Event_Footstep ) + EVENT( EV_FootstepLeft, idAnimated::Event_Footstep ) + EVENT( EV_FootstepRight, idAnimated::Event_Footstep ) + EVENT( EV_LaunchMissiles, idAnimated::Event_LaunchMissiles ) + EVENT( EV_LaunchMissilesUpdate, idAnimated::Event_LaunchMissilesUpdate ) +END_CLASS + +/* +=============== +idAnimated::idAnimated +================ +*/ +idAnimated::idAnimated() { + anim = 0; + blendFrames = 0; + soundJoint = INVALID_JOINT; + activated = false; + combatModel = NULL; + activator = NULL; + current_anim_index = 0; + num_anims = 0; + +} + +/* +=============== +idAnimated::idAnimated +================ +*/ +idAnimated::~idAnimated() { + delete combatModel; + combatModel = NULL; +} + +/* +=============== +idAnimated::Save +================ +*/ +void idAnimated::Save( idSaveGame *savefile ) const { + savefile->WriteInt( current_anim_index ); + savefile->WriteInt( num_anims ); + savefile->WriteInt( anim ); + savefile->WriteInt( blendFrames ); + savefile->WriteJoint( soundJoint ); + activator.Save( savefile ); + savefile->WriteBool( activated ); +} + +/* +=============== +idAnimated::Restore +================ +*/ +void idAnimated::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( current_anim_index ); + savefile->ReadInt( num_anims ); + savefile->ReadInt( anim ); + savefile->ReadInt( blendFrames ); + savefile->ReadJoint( soundJoint ); + activator.Restore( savefile ); + savefile->ReadBool( activated ); +} + +/* +=============== +idAnimated::Spawn +================ +*/ +void idAnimated::Spawn( void ) { + idStr animname; + int anim2; + float wait; + const char *joint; + + joint = spawnArgs.GetString( "sound_bone", "origin" ); + soundJoint = animator.GetJointHandle( joint ); + if ( soundJoint == INVALID_JOINT ) { + gameLocal.Warning( "idAnimated '%s' at (%s): cannot find joint '%s' for sound playback", name.c_str(), GetPhysics()->GetOrigin().ToString(0), joint ); + } + + LoadAF(); + + // allow bullets to collide with a combat model + if ( spawnArgs.GetBool( "combatModel", "0" ) ) { + combatModel = new idClipModel( modelDefHandle ); + } + + // allow the entity to take damage + if ( spawnArgs.GetBool( "takeDamage", "0" ) ) { + fl.takedamage = true; + } + + blendFrames = 0; + + current_anim_index = 0; + spawnArgs.GetInt( "num_anims", "0", num_anims ); + + blendFrames = spawnArgs.GetInt( "blend_in" ); + + animname = spawnArgs.GetString( num_anims ? "anim1" : "anim" ); + if ( !animname.Length() ) { + anim = 0; + } else { + anim = animator.GetAnim( animname ); + if ( !anim ) { + gameLocal.Error( "idAnimated '%s' at (%s): cannot find anim '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), animname.c_str() ); + } + } + + if ( spawnArgs.GetBool( "hide" ) ) { + Hide(); + + if ( !num_anims ) { + blendFrames = 0; + } + } else if ( spawnArgs.GetString( "start_anim", "", animname ) ) { + anim2 = animator.GetAnim( animname ); + if ( !anim2 ) { + gameLocal.Error( "idAnimated '%s' at (%s): cannot find anim '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), animname.c_str() ); + } + animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, 0 ); + } else if ( anim ) { + // init joints to the first frame of the animation + animator.SetFrame( ANIMCHANNEL_ALL, anim, 1, gameLocal.time, 0 ); + + if ( !num_anims ) { + blendFrames = 0; + } + } + + spawnArgs.GetFloat( "wait", "-1", wait ); + + if ( wait >= 0 ) { + PostEventSec( &EV_Activate, wait, this ); + } +} + +/* +=============== +idAnimated::LoadAF +=============== +*/ +bool idAnimated::LoadAF( void ) +{ + bool bReturnVal = false; + idStr fileName; + + if ( !spawnArgs.GetString( "ragdoll", "*unknown*", fileName ) ) + { + goto Quit; + } + af.SetAnimator( GetAnimator() ); + bReturnVal = af.Load( this, fileName ); + SetUpGroundingVars(); + + if( m_bAFPushMoveables ) + { + af.SetupPose( this, gameLocal.time ); + af.GetPhysics()->EnableClip(); + } + +Quit: + return bReturnVal; +} + +/* +=============== +idAnimated::GetPhysicsToSoundTransform +=============== +*/ +bool idAnimated::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { + animator.GetJointTransform( soundJoint, gameLocal.time, origin, axis ); + axis = renderEntity.axis; + return true; +} + +/* +================ +idAnimated::StartRagdoll +================ +*/ +bool idAnimated::StartRagdoll( void ) { + // if no AF loaded + if ( !af.IsLoaded() ) { + return false; + } + + // if the AF is already active + if ( af.IsActive() ) { + return true; + } + + // disable any collision model used + GetPhysics()->DisableClip(); + + // start using the AF + af.StartFromCurrentPose( spawnArgs.GetInt( "velocityTime", "0" ) ); + + return true; +} + +/* +===================== +idAnimated::PlayNextAnim +===================== +*/ +void idAnimated::PlayNextAnim( void ) { + const char *animname; + int len; + int cycle; + + if ( current_anim_index >= num_anims ) { + Hide(); + if ( spawnArgs.GetBool( "remove" ) ) { + PostEventMS( &EV_Remove, 0 ); + } else { + current_anim_index = 0; + } + return; + } + + Show(); + current_anim_index++; + + spawnArgs.GetString( va( "anim%d", current_anim_index ), NULL, &animname ); + if ( !animname ) { + anim = 0; + animator.Clear( ANIMCHANNEL_ALL, gameLocal.time, FRAME2MS( blendFrames ) ); + return; + } + + anim = animator.GetAnim( animname ); + if ( !anim ) { + gameLocal.Warning( "missing anim '%s' on %s", animname, name.c_str() ); + return; + } + + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' start anim '%s'\n", gameLocal.framenum, GetName(), animname ); + } + + spawnArgs.GetInt( "cycle", "1", cycle ); + if ( ( current_anim_index == num_anims ) && spawnArgs.GetBool( "loop_last_anim" ) ) { + cycle = -1; + } + + animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( blendFrames ) ); + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); + + len = animator.CurrentAnim( ANIMCHANNEL_ALL )->PlayLength(); + if ( len >= 0 ) { + PostEventMS( &EV_AnimDone, len, current_anim_index ); + } + + // offset the start time of the shader to sync it to the game time + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + animator.ForceUpdate(); + UpdateAnimation(); + UpdateVisuals(); + Present(); +} + +/* +=============== +idAnimated::Event_StartRagdoll +================ +*/ +void idAnimated::Event_StartRagdoll( void ) { + StartRagdoll(); +} + +/* +=============== +idAnimated::Event_AnimDone +================ +*/ +void idAnimated::Event_AnimDone( int animindex ) { + if ( g_debugCinematic.GetBool() ) { + const idAnim *animPtr = animator.GetAnim( anim ); + gameLocal.Printf( "%d: '%s' end anim '%s'\n", gameLocal.framenum, GetName(), animPtr ? animPtr->Name() : "" ); + } + + if ( ( animindex >= num_anims ) && spawnArgs.GetBool( "remove" ) ) { + Hide(); + PostEventMS( &EV_Remove, 0 ); + } else if ( spawnArgs.GetBool( "auto_advance" ) ) { + PlayNextAnim(); + } else { + activated = false; + } + + ActivateTargets( activator.GetEntity() ); +} + +/* +=============== +idAnimated::Event_Activate +================ +*/ +void idAnimated::Event_Activate( idEntity *_activator ) { + if ( num_anims ) { + PlayNextAnim(); + activator = _activator; + return; + } + + if ( activated ) { + // already activated + return; + } + + activated = true; + activator = _activator; + ProcessEvent( &EV_Animated_Start ); +} + +/* +=============== +idAnimated::Event_Start +================ +*/ +void idAnimated::Event_Start( void ) { + int cycle; + int len; + + Show(); + + if ( num_anims ) { + PlayNextAnim(); + return; + } + + if ( anim ) { + if ( g_debugCinematic.GetBool() ) { + const idAnim *animPtr = animator.GetAnim( anim ); + gameLocal.Printf( "%d: '%s' start anim '%s'\n", gameLocal.framenum, GetName(), animPtr ? animPtr->Name() : "" ); + } + spawnArgs.GetInt( "cycle", "1", cycle ); + animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( blendFrames ) ); + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); + + len = animator.CurrentAnim( ANIMCHANNEL_ALL )->PlayLength(); + if ( len >= 0 ) { + PostEventMS( &EV_AnimDone, len, 1 ); + } + } + + // offset the start time of the shader to sync it to the game time + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + animator.ForceUpdate(); + UpdateAnimation(); + UpdateVisuals(); + Present(); +} + +/* +=============== +idAnimated::Event_Footstep +=============== +*/ +void idAnimated::Event_Footstep( void ) { + StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL ); +} + +/* +===================== +idAnimated::Event_LaunchMissilesUpdate +===================== +*/ +void idAnimated::Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay ) { + idVec3 launchPos; + idVec3 targetPos; + idMat3 axis; + idVec3 dir; + idEntity * ent; + idProjectile * projectile; + const idDict * projectileDef; + const char * projectilename; + + projectilename = spawnArgs.GetString( "projectilename" ); + projectileDef = gameLocal.FindEntityDefDict( projectilename, false ); + if ( !projectileDef ) { + gameLocal.Warning( "idAnimated '%s' at (%s): 'launchMissiles' called with unknown projectile '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); + return; + } + + StartSound( "snd_missile", SND_CHANNEL_WEAPON, 0, false, NULL ); + + animator.GetJointTransform( ( jointHandle_t )launchjoint, gameLocal.time, launchPos, axis ); + launchPos = renderEntity.origin + launchPos * renderEntity.axis; + + animator.GetJointTransform( ( jointHandle_t )targetjoint, gameLocal.time, targetPos, axis ); + targetPos = renderEntity.origin + targetPos * renderEntity.axis; + + dir = targetPos - launchPos; + dir.Normalize(); + + gameLocal.SpawnEntityDef( *projectileDef, &ent, false ); + if ( !ent || !ent->IsType( idProjectile::Type ) ) { + gameLocal.Error( "idAnimated '%s' at (%s): in 'launchMissiles' call '%s' is not an idProjectile", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); + } + projectile = ( idProjectile * )ent; + projectile->Create( this, launchPos, dir ); + projectile->Launch( launchPos, dir, vec3_origin ); + + if ( numshots > 0 ) { + PostEventMS( &EV_LaunchMissilesUpdate, FRAME2MS( framedelay ), launchjoint, targetjoint, numshots - 1, framedelay ); + } +} + +/* +===================== +idAnimated::Event_LaunchMissiles +===================== +*/ +void idAnimated::Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay ) { + const idDict * projectileDef; + jointHandle_t launch; + jointHandle_t target; + + projectileDef = gameLocal.FindEntityDefDict( projectilename, false ); + if ( !projectileDef ) { + gameLocal.Warning( "idAnimated '%s' at (%s): unknown projectile '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); + return; + } + + launch = animator.GetJointHandle( launchjoint ); + if ( launch == INVALID_JOINT ) { + gameLocal.Warning( "idAnimated '%s' at (%s): unknown launch joint '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), launchjoint ); + gameLocal.Error( "Unknown joint '%s'", launchjoint ); + } + + target = animator.GetJointHandle( targetjoint ); + if ( target == INVALID_JOINT ) { + gameLocal.Warning( "idAnimated '%s' at (%s): unknown target joint '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), targetjoint ); + } + + spawnArgs.Set( "projectilename", projectilename ); + spawnArgs.Set( "missilesound", sound ); + + CancelEvents( &EV_LaunchMissilesUpdate ); + ProcessEvent( &EV_LaunchMissilesUpdate, launch, target, numshots - 1, framedelay ); +} + + +/* +=============================================================================== + + idStaticEntity + + Some static entities may be optimized into inline geometry by dmap + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idStaticEntity ) + EVENT( EV_Activate, idStaticEntity::Event_Activate ) +END_CLASS + +/* +=============== +idStaticEntity::idStaticEntity +=============== +*/ +idStaticEntity::idStaticEntity( void ) { + spawnTime = 0; + active = false; + fadeFrom.Set( 1, 1, 1, 1 ); + fadeTo.Set( 1, 1, 1, 1 ); + fadeStart = 0; + fadeEnd = 0; + runGui = false; + + m_LODHandle = 0; +} + +/* +=============== +idStaticEntity::Save +=============== +*/ +void idStaticEntity::Save( idSaveGame *savefile ) const { + savefile->WriteInt( spawnTime ); + savefile->WriteBool( active ); + savefile->WriteVec4( fadeFrom ); + savefile->WriteVec4( fadeTo ); + savefile->WriteInt( fadeStart ); + savefile->WriteInt( fadeEnd ); + savefile->WriteBool( runGui ); +} + +/* +=============== +idStaticEntity::Restore +=============== +*/ +void idStaticEntity::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( spawnTime ); + savefile->ReadBool( active ); + savefile->ReadVec4( fadeFrom ); + savefile->ReadVec4( fadeTo ); + savefile->ReadInt( fadeStart ); + savefile->ReadInt( fadeEnd ); + savefile->ReadBool( runGui ); +} + +/* +=============== +idStaticEntity::Spawn +=============== +*/ +void idStaticEntity::Spawn( void ) { + bool solid; + + // an inline static model will not do anything at all + if ( spawnArgs.GetBool( "inline" ) || gameLocal.world->spawnArgs.GetBool( "inlineAllStatics" ) ) { + Hide(); + return; + } + + solid = spawnArgs.GetBool( "solid" ); + + // ishtvan fix : Let clearing contents happen naturally on Hide instead of + // checking hidden here and clearing contents prematurely + if ( solid ) + { + GetPhysics()->SetContents( CONTENTS_SOLID | CONTENTS_OPAQUE ); + if( m_CustomContents != -1 ) + GetPhysics()->SetContents( m_CustomContents ); + } + else + { + GetPhysics()->SetContents( 0 ); + } + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + spawnTime = gameLocal.time; + active = false; + + idStr model = spawnArgs.GetString( "model" ); + if ( model.Find( ".prt" ) >= 0 ) { + + // we want the parametric particles out of sync with each other + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = gameLocal.random.RandomInt( 32767 ); + } + + fadeFrom.Set( 1, 1, 1, 1 ); + fadeTo.Set( 1, 1, 1, 1 ); + fadeStart = 0; + fadeEnd = 0; + + // NOTE: this should be used very rarely because it is expensive + runGui = spawnArgs.GetBool( "runGui" ); + if ( runGui ) { + BecomeActive( TH_THINK ); + } + + if (ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ) ) + { + // Have to start thinking if we're distance dependent + BecomeActive( TH_THINK ); + } +} + +/* +================ +idStaticEntity::ShowEditingDialog +================ +*/ +void idStaticEntity::ShowEditingDialog( void ) { + common->InitTool( EDITOR_PARTICLE, &spawnArgs ); +} + +/* +================ +idStaticEntity::Think +================ +*/ +void idStaticEntity::Think( void ) +{ + // will also do LOD thinking: + idEntity::Think(); + + if ( thinkFlags & TH_THINK ) + { + if ( runGui && renderEntity.gui[0] ) + { + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player ) + { + renderEntity.gui[0]->StateChanged( gameLocal.time, true ); + if ( renderEntity.gui[1] ) { + renderEntity.gui[1]->StateChanged( gameLocal.time, true ); + } + if ( renderEntity.gui[2] ) { + renderEntity.gui[2]->StateChanged( gameLocal.time, true ); + } + } + } + if ( fadeEnd > 0 ) + { + idVec4 color; + if ( gameLocal.time < fadeEnd ) { + color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) ); + } else { + color = fadeTo; + fadeEnd = 0; + + // TDM: Don't deactivate if we have to keep doing distance checks + if (m_DistCheckTimeStamp == 0) + BecomeInactive( TH_THINK ); + } + SetColor( color ); + } + } +} + +/* +================ +idStaticEntity::Fade +================ +*/ +void idStaticEntity::Fade( const idVec4 &to, float fadeTime ) { + GetColor( fadeFrom ); + fadeTo = to; + fadeStart = gameLocal.time; + fadeEnd = gameLocal.time + SEC2MS( fadeTime ); + BecomeActive( TH_THINK ); +} + +/* +================ +idStaticEntity::Hide +================ +*/ +void idStaticEntity::Hide( void ) { + idEntity::Hide(); + GetPhysics()->SetContents( 0 ); +} + +/* +================ +idStaticEntity::Show +================ +*/ +void idStaticEntity::Show( void ) { + idEntity::Show(); + GetPhysics()->SetContents( m_preHideContents ); +} + +/* +================ +idStaticEntity::Event_Activate +================ +*/ +void idStaticEntity::Event_Activate( idEntity *activator ) { + + spawnTime = gameLocal.time; + active = !active; + + const idKeyValue *kv = spawnArgs.FindKey( "hide" ); + if ( kv ) { + if ( IsHidden() ) { + Show(); + } else { + Hide(); + } + } + + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( spawnTime ); + renderEntity.shaderParms[5] = active; + // this change should be a good thing, it will automatically turn on + // lights etc.. when triggered so that does not have to be specifically done + // with trigger parms.. it MIGHT break things so need to keep an eye on it + renderEntity.shaderParms[ SHADERPARM_MODE ] = ( renderEntity.shaderParms[ SHADERPARM_MODE ] ) ? 0.0f : 1.0f; + BecomeActive( TH_UPDATEVISUALS ); +} + +/* +================ +idStaticEntity::WriteToSnapshot +================ +*/ +void idStaticEntity::WriteToSnapshot( idBitMsgDelta &msg ) const { + GetPhysics()->WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); + WriteColorToSnapshot( msg ); + WriteGUIToSnapshot( msg ); + msg.WriteBits( IsHidden()?1:0, 1 ); +} + +/* +================ +idStaticEntity::ReadFromSnapshot +================ +*/ +void idStaticEntity::ReadFromSnapshot( const idBitMsgDelta &msg ) { + bool hidden; + + GetPhysics()->ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + ReadColorFromSnapshot( msg ); + ReadGUIFromSnapshot( msg ); + hidden = msg.ReadBits( 1 ) == 1; + if ( hidden != IsHidden() ) { + if ( hidden ) { + Hide(); + } else { + Show(); + } + } + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + + +/* +=============================================================================== + +idFuncSmoke + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idFuncSmoke ) +EVENT( EV_Activate, idFuncSmoke::Event_Activate ) +END_CLASS + +/* +=============== +idFuncSmoke::idFuncSmoke +=============== +*/ +idFuncSmoke::idFuncSmoke() { + smokeTime = 0; + smoke = NULL; + restart = false; + m_LODHandle = 0; +} + +/* +=============== +idFuncSmoke::Save +=============== +*/ +void idFuncSmoke::Save( idSaveGame *savefile ) const { + savefile->WriteInt( smokeTime ); + savefile->WriteParticle( smoke ); + savefile->WriteBool( restart ); +} + +/* +=============== +idFuncSmoke::Restore +=============== +*/ +void idFuncSmoke::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( smokeTime ); + savefile->ReadParticle( smoke ); + savefile->ReadBool( restart ); +} + +/* +=============== +idFuncSmoke::Spawn +=============== +*/ +void idFuncSmoke::Spawn( void ) { + const char *smokeName = spawnArgs.GetString( "smoke" ); + if ( *smokeName != '\0' ) { + smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + } else { + smoke = NULL; + } + if ( spawnArgs.GetBool( "start_off" ) ) { + smokeTime = 0; + restart = false; + } else if ( smoke ) { + smokeTime = gameLocal.time; + BecomeActive( TH_UPDATEPARTICLES ); + restart = true; + } + GetPhysics()->SetContents( 0 ); +} + +/* +================ +idFuncSmoke::Event_Activate +================ +*/ +void idFuncSmoke::Event_Activate( idEntity *activator ) { + if ( thinkFlags & TH_UPDATEPARTICLES ) { + restart = false; + return; + } else { + BecomeActive( TH_UPDATEPARTICLES ); + restart = true; + smokeTime = gameLocal.time; + } +} + +/* +=============== +idFuncSmoke::Think +================ +*/ +void idFuncSmoke::Think( void ) { + + // if we are completely closed off from the player, don't do anything at all + if ( CheckDormant() || smoke == NULL || smokeTime == -1 ) { + return; + } + + if ( ( thinkFlags & TH_UPDATEPARTICLES) && !fl.hidden ) { + if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { + if ( restart ) { + smokeTime = gameLocal.time; + } else { + smokeTime = 0; + BecomeInactive( TH_UPDATEPARTICLES ); + } + } + } + + if (m_LODHandle) + { + // If this entity has LOD, let it think about it: + // Distance dependence checks + const lod_data_t *lod = gameLocal.m_ModelGenerator->GetLODDataPtr( m_LODHandle ); + if (lod) + { + if ( ( lod->DistCheckInterval > 0) + && ( (gameLocal.time - m_DistCheckTimeStamp) > lod->DistCheckInterval ) ) + { + m_DistCheckTimeStamp = gameLocal.time; +// gameLocal.Warning("%s: Think called with m_LOD %p, %i, interval %i, origin %s", +// GetName(), lod, m_DistCheckTimeStamp, m_LOD->DistCheckInterval, GetPhysics()->GetOrigin().ToString() ); + SwitchLOD( lod, + GetLODDistance( lod, gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin(), renderEntity.bounds.GetSize(), cv_lod_bias.GetFloat() ) ); + } + } + } +} + + +/* +=============================================================================== + + idTextEntity + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idTextEntity ) +END_CLASS + +/* +================ +idTextEntity::Spawn +================ +*/ +void idTextEntity::Spawn( void ) { + // these are cached as the are used each frame + text = spawnArgs.GetString( "text" ); + playerOriented = spawnArgs.GetBool( "playerOriented" ); + bool force = spawnArgs.GetBool( "force" ); + if ( developer.GetBool() || force ) { + BecomeActive(TH_THINK); + } +} + +/* +================ +idTextEntity::Save +================ +*/ +void idTextEntity::Save( idSaveGame *savefile ) const { + savefile->WriteString( text ); + savefile->WriteBool( playerOriented ); +} + +/* +================ +idTextEntity::Restore +================ +*/ +void idTextEntity::Restore( idRestoreGame *savefile ) { + savefile->ReadString( text ); + savefile->ReadBool( playerOriented ); +} + +/* +================ +idTextEntity::Think +================ +*/ +void idTextEntity::Think( void ) { + if ( thinkFlags & TH_THINK ) { + gameRenderWorld->DrawText( text, GetPhysics()->GetOrigin(), 0.25, colorWhite, playerOriented ? gameLocal.GetLocalPlayer()->viewAngles.ToMat3() : GetPhysics()->GetAxis().Transpose(), 1 ); + for ( int i = 0; i < targets.Num(); i++ ) { + if ( targets[i].GetEntity() ) { + gameRenderWorld->DebugArrow( colorBlue, GetPhysics()->GetOrigin(), targets[i].GetEntity()->GetPhysics()->GetOrigin(), 1 ); + } + } + } else { + BecomeInactive( TH_ALL ); + } +} + + +/* +=============================================================================== + + idVacuumSeperatorEntity + + Can be triggered to let vacuum through a portal (blown out window) + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idVacuumSeparatorEntity ) + EVENT( EV_Activate, idVacuumSeparatorEntity::Event_Activate ) +END_CLASS + + +/* +================ +idVacuumSeparatorEntity::idVacuumSeparatorEntity +================ +*/ +idVacuumSeparatorEntity::idVacuumSeparatorEntity( void ) { + portal = 0; +} + +/* +================ +idVacuumSeparatorEntity::Save +================ +*/ +void idVacuumSeparatorEntity::Save( idSaveGame *savefile ) const { + savefile->WriteInt( (int)portal ); + savefile->WriteInt( gameRenderWorld->GetPortalState( portal ) ); +} + +/* +================ +idVacuumSeparatorEntity::Restore +================ +*/ +void idVacuumSeparatorEntity::Restore( idRestoreGame *savefile ) { + int state; + + savefile->ReadInt( (int &)portal ); + savefile->ReadInt( state ); + + gameLocal.SetPortalState( portal, state ); +} + +/* +================ +idVacuumSeparatorEntity::Spawn +================ +*/ +void idVacuumSeparatorEntity::Spawn() { + idBounds b; + + b = idBounds( spawnArgs.GetVector( "origin" ) ).Expand( 16 ); + portal = gameRenderWorld->FindPortal( b ); + if ( !portal ) { + gameLocal.Warning( "VacuumSeparator '%s' didn't contact a portal", spawnArgs.GetString( "name" ) ); + return; + } + gameLocal.SetPortalState( portal, PS_BLOCK_AIR | PS_BLOCK_LOCATION ); +} + +/* +================ +idVacuumSeparatorEntity::Event_Activate +================ +*/ +void idVacuumSeparatorEntity::Event_Activate( idEntity *activator ) { + if ( !portal ) { + return; + } + gameLocal.SetPortalState( portal, PS_BLOCK_NONE ); +} + + +/* +=============================================================================== + +idLocationSeparatorEntity + +=============================================================================== +*/ + +const idEventDef EV_GetPortalHandle( "getPortalHandle", NULL, 'f' ); + +CLASS_DECLARATION( idEntity, idLocationSeparatorEntity ) + EVENT( EV_GetPortalHandle, idLocationSeparatorEntity::Event_GetPortalHandle ) +END_CLASS + +/* +================ +idLocationSeparatorEntity::Spawn +================ +*/ +void idLocationSeparatorEntity::Spawn() +{ + idBounds b; + + // Tels: TODO: keep the portal handle as member, add Save/Restore + // and a script event to return the portal handle, so getPortalSoundLoss() + // and setPortalSoundLoss() can use it. + b = idBounds( spawnArgs.GetVector( "origin" ) ).Expand( 16 ); + m_Portal = gameRenderWorld->FindPortal( b ); + + if ( !m_Portal ) + { + gameLocal.Warning( "LocationSeparator '%s' didn't contact a portal", GetName() ); + return; + } + gameLocal.SetPortalState( m_Portal, PS_BLOCK_LOCATION ); + + // update the sound loss for the associated portal (Note sound loss must be positive) + m_SoundLoss = spawnArgs.GetFloat("sound_loss", "0.0"); + gameLocal.m_sndPropLoader->SetPortalLoss( m_Portal, idMath::Fabs(m_SoundLoss) ); + + // store the light loss factor for this portal + m_LightLoss = spawnArgs.GetFloat("light_loss", "0.0"); + +} + +/* +================ +idLocationSeparatorEntity::Save + +Tels: Each idLocationSeparatorEntity contains the handle of the portal it + is connected to, so we can let it return the handle. +================ +*/ +void idLocationSeparatorEntity::Save( idSaveGame *savefile ) const +{ + savefile->WriteFloat( m_SoundLoss ); + savefile->WriteFloat( m_LightLoss ); + savefile->WriteInt( m_Portal ); +} + +void idLocationSeparatorEntity::Restore( idRestoreGame *savefile ) +{ + savefile->ReadFloat( m_SoundLoss ); + savefile->ReadFloat( m_LightLoss ); + savefile->ReadInt( m_Portal ); +} + +void idLocationSeparatorEntity::Event_GetPortalHandle( void ) +{ + if ( !m_Portal ) { + return idThread::ReturnFloat( -1.0f ); + } + idThread::ReturnFloat( (float) m_Portal ); +} + +qhandle_t idLocationSeparatorEntity::GetPortalHandle( void ) const +{ + return m_Portal; +} + +float idLocationSeparatorEntity::GetLightLoss( void ) const +{ + return m_LightLoss; +} + +/* +=============================================================================== + + idVacuumEntity + + Levels should only have a single vacuum entity. + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idVacuumEntity ) +END_CLASS + +/* +================ +idVacuumEntity::Spawn +================ +*/ +void idVacuumEntity::Spawn() { + if ( gameLocal.vacuumAreaNum != -1 ) { + gameLocal.Warning( "idVacuumEntity::Spawn: multiple idVacuumEntity in level" ); + return; + } + + idVec3 org = spawnArgs.GetVector( "origin" ); + + gameLocal.vacuumAreaNum = gameRenderWorld->PointInArea( org ); +} + + +/* +=============================================================================== + +idLocationEntity + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idLocationEntity ) +END_CLASS + +/* +====================== +idLocationEntity::idLocationEntity +====================== +*/ +idLocationEntity::idLocationEntity( void ) +{ + m_SndLossMult = 1.0; + m_SndVolMod = 0.0; + m_ObjectiveGroup.Clear(); +} + +/* +====================== +idLocationEntity::Spawn +====================== +*/ +void idLocationEntity::Spawn() +{ + idStr realName; + + // this just holds dict information + + // if "location" not already set, use the entity name. + if ( !spawnArgs.GetString( "location", "", realName ) ) + { + spawnArgs.Set( "location", name ); + } + + m_SndLossMult = idMath::Fabs( spawnArgs.GetFloat("sound_loss_mult", "1.0") ); + m_SndVolMod = spawnArgs.GetFloat( "sound_vol_offset", "0.0" ); + m_ObjectiveGroup = spawnArgs.GetString( "objective_group", "" ); +} + +/* +====================== +idLocationEntity::Save +====================== +*/ +void idLocationEntity::Save( idSaveGame *savefile ) const +{ + savefile->WriteFloat( m_SndLossMult ); + savefile->WriteFloat( m_SndVolMod ); + savefile->WriteString( m_ObjectiveGroup ); +} + +/* +====================== +idLocationEntity::Restore +====================== +*/ +void idLocationEntity::Restore( idRestoreGame *savefile ) +{ + savefile->ReadFloat( m_SndLossMult ); + savefile->ReadFloat( m_SndVolMod ); + savefile->ReadString( m_ObjectiveGroup ); +} + +/* +====================== +idLocationEntity::GetLocation +====================== +*/ +const char *idLocationEntity::GetLocation( void ) const { + return spawnArgs.GetString( "location" ); +} + +/* +=============================================================================== + + idBeam + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idBeam ) + EVENT( EV_PostSpawn, idBeam::Event_MatchTarget ) + EVENT( EV_Activate, idBeam::Event_Activate ) +END_CLASS + +/* +=============== +idBeam::idBeam +=============== +*/ +idBeam::idBeam() { + target = NULL; + master = NULL; +} + +/* +=============== +idBeam::Save +=============== +*/ +void idBeam::Save( idSaveGame *savefile ) const { + target.Save( savefile ); + master.Save( savefile ); +} + +/* +=============== +idBeam::Restore +=============== +*/ +void idBeam::Restore( idRestoreGame *savefile ) { + target.Restore( savefile ); + master.Restore( savefile ); +} + +/* +=============== +idBeam::Spawn +=============== +*/ +void idBeam::Spawn( void ) { + float width; + + if ( spawnArgs.GetFloat( "width", "0", width ) ) { + renderEntity.shaderParms[ SHADERPARM_BEAM_WIDTH ] = width; + } + + SetModel( "_BEAM" ); + Hide(); + PostEventMS( &EV_PostSpawn, 0 ); +} + +/* +================ +idBeam::Think +================ +*/ +void idBeam::Think( void ) { + idBeam *masterEnt; + + if ( !IsHidden() && !target.GetEntity() ) { + // hide if our target is removed + Hide(); + } + + RunPhysics(); + + masterEnt = master.GetEntity(); + if ( masterEnt ) { + const idVec3 &origin = GetPhysics()->GetOrigin(); + masterEnt->SetBeamTarget( origin ); + } + Present(); +} + +/* +================ +idBeam::SetMaster +================ +*/ +void idBeam::SetMaster( idBeam *masterbeam ) { + master = masterbeam; +} + +/* +================ +idBeam::SetBeamTarget +================ +*/ +void idBeam::SetBeamTarget( const idVec3 &origin ) { + if ( ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_X ] != origin.x ) || ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_Y ] != origin.y ) || ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_Z ] != origin.z ) ) { + renderEntity.shaderParms[ SHADERPARM_BEAM_END_X ] = origin.x; + renderEntity.shaderParms[ SHADERPARM_BEAM_END_Y ] = origin.y; + renderEntity.shaderParms[ SHADERPARM_BEAM_END_Z ] = origin.z; + UpdateVisuals(); + } +} + +/* +================ +idBeam::Show +================ +*/ +void idBeam::Show( void ) { + idBeam *targetEnt; + + idEntity::Show(); + + targetEnt = target.GetEntity(); + if ( targetEnt ) { + const idVec3 &origin = targetEnt->GetPhysics()->GetOrigin(); + SetBeamTarget( origin ); + } +} + +/* +================ +idBeam::Event_MatchTarget +================ +*/ +void idBeam::Event_MatchTarget( void ) { + int i; + idEntity *targetEnt; + idBeam *targetBeam; + + if ( !targets.Num() ) { + return; + } + + targetBeam = NULL; + for( i = 0; i < targets.Num(); i++ ) { + targetEnt = targets[ i ].GetEntity(); + if ( targetEnt && targetEnt->IsType( idBeam::Type ) ) { + targetBeam = static_cast( targetEnt ); + break; + } + } + + if ( !targetBeam ) { + gameLocal.Error( "Could not find valid beam target for '%s'", name.c_str() ); + } + + target = targetBeam; + targetBeam->SetMaster( this ); + if ( !spawnArgs.GetBool( "start_off" ) ) { + Show(); + } +} + +/* +================ +idBeam::Event_Activate +================ +*/ +void idBeam::Event_Activate( idEntity *activator ) { + if ( IsHidden() ) { + Show(); + } else { + Hide(); + } +} + +/* +================ +idBeam::WriteToSnapshot +================ +*/ +void idBeam::WriteToSnapshot( idBitMsgDelta &msg ) const { + GetPhysics()->WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); + WriteColorToSnapshot( msg ); + msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_X] ); + msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_Y] ); + msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_Z] ); +} + +/* +================ +idBeam::ReadFromSnapshot +================ +*/ +void idBeam::ReadFromSnapshot( const idBitMsgDelta &msg ) { + GetPhysics()->ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + ReadColorFromSnapshot( msg ); + renderEntity.shaderParms[SHADERPARM_BEAM_END_X] = msg.ReadFloat(); + renderEntity.shaderParms[SHADERPARM_BEAM_END_Y] = msg.ReadFloat(); + renderEntity.shaderParms[SHADERPARM_BEAM_END_Z] = msg.ReadFloat(); + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + + +/* +=============================================================================== + + idLiquid + +=============================================================================== +*/ + +#ifndef MOD_WATERPHYSICS +CLASS_DECLARATION( idEntity, idLiquid ) + EVENT( EV_Touch, idLiquid::Event_Touch ) +END_CLASS + +/* +================ +idLiquid::Save +================ +*/ +void idLiquid::Save( idSaveGame *savefile ) const { + // Nothing to save +} + +/* +================ +idLiquid::Restore +================ +*/ +void idLiquid::Restore( idRestoreGame *savefile ) { + //FIXME: NO! + Spawn(); +} + +/* +================ +idLiquid::Spawn +================ +*/ +void idLiquid::Spawn() { +/* + model = dynamic_cast( renderEntity.hModel ); + if ( !model ) { + gameLocal.Error( "Entity '%s' must have liquid model", name.c_str() ); + } + model->Reset(); + GetPhysics()->SetContents( CONTENTS_TRIGGER ); +*/ +} + +/* +================ +idLiquid::Event_Touch +================ +*/ +void idLiquid::Event_Touch( idEntity *other, trace_t *trace ) { + // FIXME: for QuakeCon +/* + idVec3 pos; + + pos = other->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + model->IntersectBounds( other->GetPhysics()->GetBounds().Translate( pos ), -10.0f ); +*/ +} +#endif + +/* +=============================================================================== + + idShaking + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idShaking ) + EVENT( EV_Activate, idShaking::Event_Activate ) +END_CLASS + +/* +=============== +idShaking::idShaking +=============== +*/ +idShaking::idShaking() { + active = false; +} + +/* +=============== +idShaking::Save +=============== +*/ +void idShaking::Save( idSaveGame *savefile ) const { + savefile->WriteBool( active ); + savefile->WriteStaticObject( physicsObj ); +} + +/* +=============== +idShaking::Restore +=============== +*/ +void idShaking::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( active ); + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); +} + +/* +=============== +idShaking::Spawn +=============== +*/ +void idShaking::Spawn( void ) { + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + SetPhysics( &physicsObj ); + + active = false; + if ( !spawnArgs.GetBool( "start_off" ) ) { + BeginShaking(); + } +} + +/* +================ +idShaking::BeginShaking +================ +*/ +void idShaking::BeginShaking( void ) { + int phase; + idAngles shake; + int period; + + active = true; + phase = gameLocal.random.RandomInt( 1000 ); + shake = spawnArgs.GetAngles( "shake", "0.5 0.5 0.5" ); + period = static_cast(spawnArgs.GetFloat( "period", "0.05" ) * 1000); + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), phase, static_cast(period * 0.25f), GetPhysics()->GetAxis().ToAngles(), shake, ang_zero ); +} + +/* +================ +idShaking::Event_Activate +================ +*/ +void idShaking::Event_Activate( idEntity *activator ) { + if ( !active ) { + BeginShaking(); + } else { + active = false; + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, physicsObj.GetAxis().ToAngles(), ang_zero, ang_zero ); + } +} + +/* +=============================================================================== + + idEarthQuake + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idEarthQuake ) + EVENT( EV_Activate, idEarthQuake::Event_Activate ) +END_CLASS + +/* +=============== +idEarthQuake::idEarthQuake +=============== +*/ +idEarthQuake::idEarthQuake() { + wait = 0.0f; + random = 0.0f; + nextTriggerTime = 0; + shakeStopTime = 0; + triggered = false; + playerOriented = false; + disabled = false; + shakeTime = 0.0f; +} + +/* +=============== +idEarthQuake::Save +=============== +*/ +void idEarthQuake::Save( idSaveGame *savefile ) const { + savefile->WriteInt( nextTriggerTime ); + savefile->WriteInt( shakeStopTime ); + savefile->WriteFloat( wait ); + savefile->WriteFloat( random ); + savefile->WriteBool( triggered ); + savefile->WriteBool( playerOriented ); + savefile->WriteBool( disabled ); + savefile->WriteFloat( shakeTime ); +} + +/* +=============== +idEarthQuake::Restore +=============== +*/ +void idEarthQuake::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( nextTriggerTime ); + savefile->ReadInt( shakeStopTime ); + savefile->ReadFloat( wait ); + savefile->ReadFloat( random ); + savefile->ReadBool( triggered ); + savefile->ReadBool( playerOriented ); + savefile->ReadBool( disabled ); + savefile->ReadFloat( shakeTime ); + + if ( shakeStopTime > gameLocal.time ) { + BecomeActive( TH_THINK ); + } +} + +/* +=============== +idEarthQuake::Spawn +=============== +*/ +void idEarthQuake::Spawn( void ) { + nextTriggerTime = 0; + shakeStopTime = 0; + wait = spawnArgs.GetFloat( "wait", "15" ); + random = spawnArgs.GetFloat( "random", "5" ); + triggered = spawnArgs.GetBool( "triggered" ); + playerOriented = spawnArgs.GetBool( "playerOriented" ); + disabled = false; + shakeTime = spawnArgs.GetFloat( "shakeTime", "0" ); + + if ( !triggered ){ + PostEventSec( &EV_Activate, spawnArgs.GetFloat( "wait" ), this ); + } + BecomeInactive( TH_THINK ); +} + +/* +================ +idEarthQuake::Event_Activate +================ +*/ +void idEarthQuake::Event_Activate( idEntity *activator ) { + + if ( nextTriggerTime > gameLocal.time ) { + return; + } + + if ( disabled && activator == this ) { + return; + } + + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player == NULL ) { + return; + } + + nextTriggerTime = 0; + + if ( !triggered && activator != this ){ + // if we are not triggered ( i.e. random ), disable or enable + disabled ^= 1; + if (disabled) { + return; + } else { + PostEventSec( &EV_Activate, wait + random * gameLocal.random.CRandomFloat(), this ); + } + } + + ActivateTargets( activator ); + + const idSoundShader *shader = declManager->FindSound( spawnArgs.GetString( "snd_quake" ) ); + if ( playerOriented ) { + player->StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); + } else { + StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); + } + + if ( shakeTime > 0.0f ) { + shakeStopTime = gameLocal.time + SEC2MS( shakeTime ); + BecomeActive( TH_THINK ); + } + + if ( wait > 0.0f ) { + if ( !triggered ) { + PostEventSec( &EV_Activate, wait + random * gameLocal.random.CRandomFloat(), this ); + } else { + nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); + } + } else if ( shakeTime == 0.0f ) { + PostEventMS( &EV_Remove, 0 ); + } +} + + +/* +=============== +idEarthQuake::Think +================ +*/ +void idEarthQuake::Think( void ) { + if ( thinkFlags & TH_THINK ) { + if ( gameLocal.time > shakeStopTime ) { + BecomeInactive( TH_THINK ); + if ( wait <= 0.0f ) { + PostEventMS( &EV_Remove, 0 ); + } + return; + } + float shakeVolume = gameSoundWorld->CurrentShakeAmplitudeForPosition( gameLocal.time, gameLocal.GetLocalPlayer()->firstPersonViewOrigin ); + gameLocal.RadiusPush( GetPhysics()->GetOrigin(), 256, 1500 * shakeVolume, this, this, 1.0f, true ); + } + BecomeInactive( TH_UPDATEVISUALS ); +} + +/* +=============================================================================== + + idFuncPortal + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idFuncPortal ) + EVENT( EV_Activate, idFuncPortal::Event_Activate ) +END_CLASS + +/* +=============== +idFuncPortal::idFuncPortal +=============== +*/ +idFuncPortal::idFuncPortal() +{ + portal = 0; + state = false; + m_bDistDependent = false; + m_Distance = 0; + + m_TimeStamp = 0; + m_Interval = 1000; +} + +/* +=============== +idFuncPortal::Save +=============== +*/ +void idFuncPortal::Save( idSaveGame *savefile ) const +{ + savefile->WriteInt( (int)portal ); + savefile->WriteBool( state ); + + savefile->WriteBool( m_bDistDependent ); + savefile->WriteFloat( m_Distance ); + savefile->WriteInt( m_TimeStamp ); + savefile->WriteInt( m_Interval ); +} + +/* +=============== +idFuncPortal::Restore +=============== +*/ +void idFuncPortal::Restore( idRestoreGame *savefile ) +{ + savefile->ReadInt( (int &)portal ); + savefile->ReadBool( state ); + gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); + + savefile->ReadBool( m_bDistDependent ); + savefile->ReadFloat( m_Distance ); + savefile->ReadInt( m_TimeStamp ); + savefile->ReadInt( m_Interval ); +} + +/* +=============== +idFuncPortal::Spawn +=============== +*/ +void idFuncPortal::Spawn( void ) +{ + portal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds().Expand( 32.0f ) ); + if ( portal > 0 ) + { + state = spawnArgs.GetBool( "start_on" ); + gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); + } + + if( (m_Distance = spawnArgs.GetFloat( "portal_dist", "0.0" )) <= 0 ) + goto Quit; + + // distance dependent portals from this point on: + m_bDistDependent = true; + m_Distance *= m_Distance; + m_Interval = (int) (1000.0f * spawnArgs.GetFloat( "distcheck_period", "1.0" )); + + // add some phase diversity to the checks so that they don't all run in one frame + // make sure they all run on the first frame though, by initializing m_TimeStamp to + // be at least one interval early. + m_TimeStamp = gameLocal.time - (int) (m_Interval * (1.0f + 0.5f*gameLocal.random.RandomFloat()) ); + + // only start thinking if it's distance dependent. + BecomeActive( TH_THINK ); + +Quit: + return; +} + +/* +================ +idFuncPortal::Event_Activate +================ +*/ +void idFuncPortal::Event_Activate( idEntity *activator ) +{ + if ( portal > 0 ) + { + state = !state; + gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); + } + + // activate our targets + PostEventMS( &EV_ActivateTargets, 0, activator ); +} + +void idFuncPortal::Think( void ) +{ + idVec3 delta; + bool bWithinDist; + + if( !m_bDistDependent ) + goto Quit; + + if( (gameLocal.time - m_TimeStamp) < m_Interval ) + goto Quit; + + m_TimeStamp = gameLocal.time; + bWithinDist = false; + + delta = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(); + delta -= GetPhysics()->GetOrigin(); + + bWithinDist = (delta.LengthSqr() < m_Distance); + + if( (!state && !bWithinDist) || (state && bWithinDist) ) + { + // toggle portal and trigger targets + Event_Activate( gameLocal.GetLocalPlayer() ); + } + +Quit: + idEntity::Think(); + return; +} + +/* +=============================================================================== + + idFuncAASPortal + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idFuncAASPortal ) + EVENT( EV_Activate, idFuncAASPortal::Event_Activate ) +END_CLASS + +/* +=============== +idFuncAASPortal::idFuncAASPortal +=============== +*/ +idFuncAASPortal::idFuncAASPortal() { + state = false; +} + +/* +=============== +idFuncAASPortal::Save +=============== +*/ +void idFuncAASPortal::Save( idSaveGame *savefile ) const { + savefile->WriteBool( state ); +} + +/* +=============== +idFuncAASPortal::Restore +=============== +*/ +void idFuncAASPortal::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( state ); + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); +} + +/* +=============== +idFuncAASPortal::Spawn +=============== +*/ +void idFuncAASPortal::Spawn( void ) { + state = spawnArgs.GetBool( "start_on" ); + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); +} + +/* +================ +idFuncAASPortal::Event_Activate +================ +*/ +void idFuncAASPortal::Event_Activate( idEntity *activator ) { + state ^= 1; + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); +} + +/* +=============================================================================== + + idFuncAASObstacle + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idFuncAASObstacle ) + EVENT( EV_Activate, idFuncAASObstacle::Event_Activate ) +END_CLASS + +/* +=============== +idFuncAASObstacle::idFuncAASObstacle +=============== +*/ +idFuncAASObstacle::idFuncAASObstacle() { + state = false; +} + +/* +=============== +idFuncAASObstacle::Save +=============== +*/ +void idFuncAASObstacle::Save( idSaveGame *savefile ) const { + savefile->WriteBool( state ); +} + +/* +=============== +idFuncAASObstacle::Restore +=============== +*/ +void idFuncAASObstacle::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( state ); + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); +} + +/* +=============== +idFuncAASObstacle::Spawn +=============== +*/ +void idFuncAASObstacle::Spawn( void ) { + state = spawnArgs.GetBool( "start_on" ); + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); + if (cv_ai_show_aasfuncobstacle_state.GetBool()) + { + gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 15000); + } +} + +/* +================ +idFuncAASObstacle::Event_Activate +================ +*/ +void idFuncAASObstacle::Event_Activate( idEntity *activator ) { + state ^= 1; + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); + if (cv_ai_show_aasfuncobstacle_state.GetBool()) + { + gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 2000); + } +} + +void idFuncAASObstacle::SetAASState(bool newState) +{ + state = newState; + gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); + if (cv_ai_show_aasfuncobstacle_state.GetBool()) + { + gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 2000); + } +} + + +/* +=============================================================================== + + idPhantomObjects + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idPhantomObjects ) + EVENT( EV_Activate, idPhantomObjects::Event_Activate ) +END_CLASS + +/* +=============== +idPhantomObjects::idPhantomObjects +=============== +*/ +idPhantomObjects::idPhantomObjects() { + target = NULL; + end_time = 0; + throw_time = 0.0f; + shake_time = 0.0f; + shake_ang.Zero(); + speed = 0.0f; + min_wait = 0; + max_wait = 0; + fl.neverDormant = false; +} + +/* +=============== +idPhantomObjects::Save +=============== +*/ +void idPhantomObjects::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( end_time ); + savefile->WriteFloat( throw_time ); + savefile->WriteFloat( shake_time ); + savefile->WriteVec3( shake_ang ); + savefile->WriteFloat( speed ); + savefile->WriteInt( min_wait ); + savefile->WriteInt( max_wait ); + target.Save( savefile ); + savefile->WriteInt( targetTime.Num() ); + for( i = 0; i < targetTime.Num(); i++ ) { + savefile->WriteInt( targetTime[ i ] ); + } + + for( i = 0; i < lastTargetPos.Num(); i++ ) { + savefile->WriteVec3( lastTargetPos[ i ] ); + } +} + +/* +=============== +idPhantomObjects::Restore +=============== +*/ +void idPhantomObjects::Restore( idRestoreGame *savefile ) { + int num; + int i; + + savefile->ReadInt( end_time ); + savefile->ReadFloat( throw_time ); + savefile->ReadFloat( shake_time ); + savefile->ReadVec3( shake_ang ); + savefile->ReadFloat( speed ); + savefile->ReadInt( min_wait ); + savefile->ReadInt( max_wait ); + target.Restore( savefile ); + + savefile->ReadInt( num ); + targetTime.SetGranularity( 1 ); + targetTime.SetNum( num ); + lastTargetPos.SetGranularity( 1 ); + lastTargetPos.SetNum( num ); + + for( i = 0; i < num; i++ ) { + savefile->ReadInt( targetTime[ i ] ); + } + + if ( savefile->GetBuildNumber() == INITIAL_RELEASE_BUILD_NUMBER ) { + // these weren't saved out in the first release + for( i = 0; i < num; i++ ) { + lastTargetPos[ i ].Zero(); + } + } else { + for( i = 0; i < num; i++ ) { + savefile->ReadVec3( lastTargetPos[ i ] ); + } + } +} + +/* +=============== +idPhantomObjects::Spawn +=============== +*/ +void idPhantomObjects::Spawn( void ) { + throw_time = spawnArgs.GetFloat( "time", "5" ); + speed = spawnArgs.GetFloat( "speed", "1200" ); + shake_time = spawnArgs.GetFloat( "shake_time", "1" ); + throw_time -= shake_time; + if ( throw_time < 0.0f ) { + throw_time = 0.0f; + } + min_wait = SEC2MS( spawnArgs.GetFloat( "min_wait", "1" ) ); + max_wait = SEC2MS( spawnArgs.GetFloat( "max_wait", "3" ) ); + + shake_ang = spawnArgs.GetVector( "shake_ang", "65 65 65" ); + Hide(); + GetPhysics()->SetContents( 0 ); +} + +/* +================ +idPhantomObjects::Event_Activate +================ +*/ +void idPhantomObjects::Event_Activate( idEntity *activator ) { + int i; + float time; + float frac; + float scale; + + if ( thinkFlags & TH_THINK ) { + BecomeInactive( TH_THINK ); + return; + } + + RemoveNullTargets(); + if ( !targets.Num() ) { + return; + } + + if ( !activator || !activator->IsType( idActor::Type ) ) { + target = gameLocal.GetLocalPlayer(); + } else { + target = static_cast( activator ); + } + + end_time = gameLocal.time + SEC2MS( spawnArgs.GetFloat( "end_time", "0" ) ); + + targetTime.SetNum( targets.Num() ); + lastTargetPos.SetNum( targets.Num() ); + + const idVec3 &toPos = target.GetEntity()->GetEyePosition(); + + // calculate the relative times of all the objects + time = 0.0f; + for( i = 0; i < targetTime.Num(); i++ ) { + targetTime[ i ] = SEC2MS( time ); + lastTargetPos[ i ] = toPos; + + frac = 1.0f - ( float )i / ( float )targetTime.Num(); + time += ( gameLocal.random.RandomFloat() + 1.0f ) * 0.5f * frac + 0.1f; + } + + // scale up the times to fit within throw_time + scale = throw_time / time; + for( i = 0; i < targetTime.Num(); i++ ) { + targetTime[ i ] = static_cast(gameLocal.time + SEC2MS( shake_time )+ targetTime[ i ] * scale); + } + + BecomeActive( TH_THINK ); +} + +/* +=============== +idPhantomObjects::Think +================ +*/ +void idPhantomObjects::Think( void ) { + int i; + int num; + float time; + idVec3 vel; + idVec3 ang; + idEntity *ent; + idActor *targetEnt; + idPhysics *entPhys; + trace_t tr; + + // if we are completely closed off from the player, don't do anything at all + if ( CheckDormant() ) { + return; + } + + if ( !( thinkFlags & TH_THINK ) ) { + BecomeInactive( thinkFlags & ~TH_THINK ); + return; + } + + targetEnt = target.GetEntity(); + if ( !targetEnt || ( targetEnt->health <= 0 ) || ( end_time && ( gameLocal.time > end_time ) ) || gameLocal.inCinematic ) { + BecomeInactive( TH_THINK ); + } + + const idVec3 &toPos = targetEnt->GetEyePosition(); + + num = 0; + for ( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( !ent ) { + continue; + } + + if ( ent->fl.hidden ) { + // don't throw hidden objects + continue; + } + + if ( !targetTime[ i ] ) { + // already threw this object + continue; + } + + num++; + + time = MS2SEC( targetTime[ i ] - gameLocal.time ); + if ( time > shake_time ) { + continue; + } + + entPhys = ent->GetPhysics(); + const idVec3 &entOrg = entPhys->GetOrigin(); + + gameLocal.clip.TracePoint( tr, entOrg, toPos, MASK_OPAQUE, ent ); + if ( tr.fraction >= 1.0f || ( gameLocal.GetTraceEntity( tr ) == targetEnt ) ) { + lastTargetPos[ i ] = toPos; + } + + if ( time < 0.0f ) { + idAI::PredictTrajectory( entPhys->GetOrigin(), lastTargetPos[ i ], speed, entPhys->GetGravity(), + entPhys->GetClipModel(), entPhys->GetClipMask(), 256.0f, ent, targetEnt, ai_debugTrajectory.GetBool() ? 1 : 0, vel ); + vel *= speed; + entPhys->SetLinearVelocity( vel ); + if ( !end_time ) { + targetTime[ i ] = 0; + } else { + targetTime[ i ] = gameLocal.time + gameLocal.random.RandomInt( max_wait - min_wait ) + min_wait; + } + if ( ent->IsType( idMoveable::Type ) ) { + idMoveable *ment = static_cast( ent ); + ment->EnableDamage( true, 2.5f ); + } + } else { + // this is not the right way to set the angular velocity, but the effect is nice, so I'm keeping it. :) + ang.Set( gameLocal.random.CRandomFloat() * shake_ang.x, gameLocal.random.CRandomFloat() * shake_ang.y, gameLocal.random.CRandomFloat() * shake_ang.z ); + ang *= ( 1.0f - time / shake_time ); + entPhys->SetAngularVelocity( ang ); + } + } + + if ( !num ) { + BecomeInactive( TH_THINK ); + } +} + +/* +=============================================================================== +idPortalSky +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idPortalSky ) + + EVENT( EV_PostSpawn, idPortalSky::Event_PostSpawn ) + EVENT( EV_Activate, idPortalSky::Event_Activate ) + +END_CLASS + +/* +=============== +idPortalSky::idPortalSky +=============== +*/ + +idPortalSky::idPortalSky( void ) { +} + +/* +=============== +idPortalSky::~idPortalSky +=============== +*/ + +idPortalSky::~idPortalSky( void ) { +} + +/* +=============== +idPortalSky::Spawn +=============== +*/ + +void idPortalSky::Spawn( void ) { + if ( !spawnArgs.GetBool( "triggered" ) ) { + PostEventMS( &EV_PostSpawn, 1 ); + } +} + +/* +================ +idPortalSky::Event_PostSpawn +================ + +*/ + +void idPortalSky::Event_PostSpawn() { + + gameLocal.SetPortalSkyEnt( this ); + +} + +/* +================ +idPortalSky::Event_Activate +================ +*/ + +void idPortalSky::Event_Activate( idEntity *activator ) { + gameLocal.SetPortalSkyEnt( this ); +} + + +/* +=============================================================================== + + tdmVine - climbable vine piece (grayman #2787) + +=============================================================================== +*/ + +const idEventDef EV_Vine_SetPrime( "setPrime", "e", 0 ); +const idEventDef EV_Vine_GetPrime( "getPrime", NULL, 'e' ); +const idEventDef EV_Vine_AddDescendant( "addDescendant", "e", 0 ); +const idEventDef EV_Vine_CanWater( "canWater", NULL, 'f' ); +const idEventDef EV_Vine_SetWatered( "setWatered", NULL, 0 ); +const idEventDef EV_Vine_ClearWatered( "clearWatered", NULL, 0 ); +const idEventDef EV_Vine_ScaleVine( "scaleVine", "f", 0 ); + +CLASS_DECLARATION( idStaticEntity, tdmVine ) + EVENT( EV_Vine_SetPrime, tdmVine::Event_SetPrime) + EVENT( EV_Vine_GetPrime, tdmVine::Event_GetPrime) + EVENT( EV_Vine_AddDescendant, tdmVine::Event_AddDescendant) + EVENT( EV_Vine_CanWater, tdmVine::Event_CanWater) + EVENT( EV_Vine_SetWatered, tdmVine::Event_SetWatered) + EVENT( EV_Vine_ClearWatered, tdmVine::Event_ClearWatered ) + EVENT( EV_Vine_ScaleVine, tdmVine::Event_ScaleVine ) +END_CLASS + +tdmVine::tdmVine( void ) +{ + _watered = false; + _prime = NULL; + _descendants.Clear(); +} + +void tdmVine::Save( idSaveGame *savefile ) const +{ + savefile->WriteBool( _watered ); + savefile->WriteObject( _prime ); + savefile->WriteInt( _descendants.Num() ); + for ( int i = 0 ; i < _descendants.Num() ; i++) + { + _descendants[i].Save( savefile ); + } +} + +void tdmVine::Restore( idRestoreGame *savefile ) +{ + savefile->ReadBool( _watered ); + savefile->ReadObject( reinterpret_cast( _prime ) ); + int num; + savefile->ReadInt( num ); + _descendants.SetNum( num ); + for ( int i = 0 ; i < num ; i++ ) + { + _descendants[i].Restore( savefile ); + } +} + +void tdmVine::Spawn() +{ +} + +void tdmVine::Event_SetPrime( tdmVine* newPrime ) +{ + _prime = newPrime; +} + +void tdmVine::Event_GetPrime() +{ + idThread::ReturnEntity( _prime ); +} + +void tdmVine::Event_AddDescendant( tdmVine* descendant ) +{ + idEntityPtr< tdmVine > tdmVinePtr; + tdmVinePtr = descendant; + _descendants.Append( tdmVinePtr ); +} + +void tdmVine::Event_ClearWatered() +{ + _watered = false; +} + +void tdmVine::Event_SetWatered() +{ + _watered = true; +} + +void tdmVine::Event_CanWater() +{ + // For a given vine family, only allow two pieces to be + // watered by a water stim. Otherwise, growth can be + // rampant as the stim falls through the family. + + float canWater = 1; + int wateredCount = 0; + if ( _watered ) // the prime vine should check itself first + { + wateredCount++; + } + for ( int i = 0 ; i < _descendants.Num() ; i++ ) + { + idEntityPtr< tdmVine > tdmVinePtr = _descendants[i]; + tdmVine* vine = tdmVinePtr.GetEntity(); + if ( vine && vine->_watered ) + { + if ( ++wateredCount >= 2 ) + { + canWater = 0; + break; + } + } + } + idThread::ReturnFloat( canWater ); +} + +void tdmVine::Event_ScaleVine(float factor) +{ + idMat3 axis = GetPhysics()->GetAxis(); + axis *= factor; + GetPhysics()->SetAxis( axis ); + UpdateVisuals(); +} diff --git a/game/Misc.h b/game/Misc.h new file mode 100644 index 000000000..8bb248802 --- /dev/null +++ b/game/Misc.h @@ -0,0 +1,822 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_MISC_H__ +#define __GAME_MISC_H__ + +/* +=============================================================================== + +idSpawnableEntity + +A simple, spawnable entity with a model and no functionable ability of it's own. +For example, it can be used as a placeholder during development, for marking +locations on maps for script, or for simple placed models without any behavior +that can be bound to other entities. Should not be subclassed. +=============================================================================== +*/ + +class idSpawnableEntity : public idEntity { +public: + CLASS_PROTOTYPE( idSpawnableEntity ); + + void Spawn( void ); + +private: +}; + +/* +=============================================================================== + + Potential spawning position for players. + The first time a player enters the game, they will be at an 'initial' spot. + Targets will be fired when someone spawns in on them. + + When triggered, will cause player to be teleported to spawn spot. + +=============================================================================== +*/ + +class idPlayerStart : public idEntity { +public: + CLASS_PROTOTYPE( idPlayerStart ); + + enum { + EVENT_TELEPORTPLAYER = idEntity::EVENT_MAXEVENTS, + EVENT_MAXEVENTS + }; + + idPlayerStart( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + +private: + int teleportStage; + + void Event_TeleportPlayer( idEntity *activator ); + void Event_TeleportStage( idEntity *player ); + void TeleportPlayer( idPlayer *player ); +}; + + +/* +=============================================================================== + + Non-displayed entity used to activate triggers when it touches them. + Bind to a mover to have the mover activate a trigger as it moves. + When target by triggers, activating the trigger will toggle the + activator on and off. Check "start_off" to have it spawn disabled. + +=============================================================================== +*/ + +class idActivator : public idEntity { +public: + CLASS_PROTOTYPE( idActivator ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + +private: + bool stay_on; + + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + + Path entities for monsters to follow. + +=============================================================================== +*/ +class idPathCorner : public idEntity { +public: + CLASS_PROTOTYPE( idPathCorner ); + + void Spawn( void ); + + static void DrawDebugInfo( void ); + + static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore, idAI* owner ); + +private: + void Event_RandomPath( void ); +}; + +/* +=============================================================================== + + Path entities for AI to flee to. + +=============================================================================== +*/ +class tdmPathFlee : public idEntity { +public: + CLASS_PROTOTYPE( tdmPathFlee ); + + virtual ~tdmPathFlee(); + + void Spawn( void ); + + static void DrawDebugInfo( void ); +}; + +/* +=============================================================================== + + Object that fires targets and changes shader parms when damaged. + +=============================================================================== +*/ + +class idDamagable : public idEntity { +public: + CLASS_PROTOTYPE( idDamagable ); + + idDamagable( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + +private: + int count; + int nextTriggerTime; + + void BecomeBroken( idEntity *activator ); + void Event_BecomeBroken( idEntity *activator ); + void Event_RestoreDamagable( void ); +}; + + +/* +=============================================================================== + + Hidden object that explodes when activated + +=============================================================================== +*/ + +class idExplodable : public idEntity { +public: + CLASS_PROTOTYPE( idExplodable ); + + void Spawn( void ); + +private: + void Event_Explode( idEntity *activator ); +}; + + +/* +=============================================================================== + + idSpring + +=============================================================================== +*/ + +class idSpring : public idEntity { +public: + CLASS_PROTOTYPE( idSpring ); + + void Spawn( void ); + + virtual void Think( void ); + +private: + idEntity * ent1; + idEntity * ent2; + int id1; + int id2; + idVec3 p1; + idVec3 p2; + idForce_Spring spring; + + void Event_LinkSpring( void ); +}; + + +/* +=============================================================================== + + idForceField + +=============================================================================== +*/ + +class idForceField : public idEntity { +public: + CLASS_PROTOTYPE( idForceField ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + + virtual void Think( void ); + +private: + idForce_Field forceField; + + void Toggle( void ); + + void Event_Activate( idEntity *activator ); + void Event_Toggle( void ); + void Event_FindTargets( void ); +}; + + +/* +=============================================================================== + + idAnimated + +=============================================================================== +*/ + +class idAnimated : public idAFEntity_Gibbable { +public: + CLASS_PROTOTYPE( idAnimated ); + + idAnimated(); + virtual ~idAnimated(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + virtual bool LoadAF( void ); + bool StartRagdoll( void ); + virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); + +private: + int num_anims; + int current_anim_index; + int anim; + int blendFrames; + jointHandle_t soundJoint; + idEntityPtr activator; + bool activated; + + void PlayNextAnim( void ); + + void Event_Activate( idEntity *activator ); + void Event_Start( void ); + void Event_StartRagdoll( void ); + void Event_AnimDone( int animIndex ); + void Event_Footstep( void ); + void Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay ); + void Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay ); +}; + + +/* +=============================================================================== + + idStaticEntity + +=============================================================================== +*/ + +class idStaticEntity : public idEntity { +public: + CLASS_PROTOTYPE( idStaticEntity ); + + idStaticEntity( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + void ShowEditingDialog( void ); + virtual void Hide( void ); + virtual void Show( void ); + void Fade( const idVec4 &to, float fadeTime ); + virtual void Think( void ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + +private: + void Event_Activate( idEntity *activator ); + + int spawnTime; + bool active; + idVec4 fadeFrom; + idVec4 fadeTo; + int fadeStart; + int fadeEnd; + bool runGui; +}; + + +/* +=============================================================================== + +idFuncSmoke + +=============================================================================== +*/ + +class idFuncSmoke : public idEntity { +public: + CLASS_PROTOTYPE( idFuncSmoke ); + + idFuncSmoke(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + void Event_Activate( idEntity *activator ); + +private: + int smokeTime; + const idDeclParticle * smoke; + bool restart; +}; + + +/* +=============================================================================== + +idTextEntity + +=============================================================================== +*/ + +class idTextEntity : public idEntity { +public: + CLASS_PROTOTYPE( idTextEntity ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + +private: + idStr text; + bool playerOriented; +}; + + +/* +=============================================================================== + +idLocationEntity + +=============================================================================== +*/ + +class idLocationEntity : public idEntity { +public: + CLASS_PROTOTYPE( idLocationEntity ); + + idLocationEntity( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + const char * GetLocation( void ) const; + +public: + /** + * Soundprop: Loss multiplier for atmospheric attenuation + **/ + float m_SndLossMult; + /** + * Soundprop: Volume offset for sounds originating in location + **/ + float m_SndVolMod; + /** + * Objective system: Location's objective group name for objective checks + **/ + idStr m_ObjectiveGroup; + +private: +}; + +class idLocationSeparatorEntity : public idEntity { +public: + CLASS_PROTOTYPE( idLocationSeparatorEntity ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + qhandle_t GetPortalHandle( void ) const; + // Returns a factor (0..1.0) that says how much light the portal lets through + float GetLightLoss( void ) const; + void Event_GetPortalHandle( void ); + +private: + + /** + * Soundprop: Volume loss for sounds traveling through this portal, in + * addition to a potential door on this portal. + **/ + float m_SoundLoss; + + /** + * Tels: Lightprop: Volume loss for sounds traveling through this portal + **/ + float m_LightLoss; + + /** + * Tels: Handle of the portal this entity touches. + **/ + qhandle_t m_Portal; +}; + +class idVacuumSeparatorEntity : public idEntity { +public: + CLASS_PROTOTYPE( idVacuumSeparatorEntity ); + + idVacuumSeparatorEntity( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Event_Activate( idEntity *activator ); + +private: + qhandle_t portal; +}; + +class idVacuumEntity : public idEntity { +public: + CLASS_PROTOTYPE( idVacuumEntity ); + + void Spawn( void ); + +private: +}; + + +/* +=============================================================================== + + idBeam + +=============================================================================== +*/ + +class idBeam : public idEntity { +public: + CLASS_PROTOTYPE( idBeam ); + + idBeam(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + + void SetMaster( idBeam *masterbeam ); + void SetBeamTarget( const idVec3 &origin ); + + virtual void Show( void ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + +private: + void Event_MatchTarget( void ); + void Event_Activate( idEntity *activator ); + + idEntityPtr target; + idEntityPtr master; +}; + + +/* +=============================================================================== + + idLiquid + +=============================================================================== +*/ + +#ifndef MOD_WATERPHYSICS +class idRenderModelLiquid; + +class idLiquid : public idEntity { +public: + CLASS_PROTOTYPE( idLiquid ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + void Event_Touch( idEntity *other, trace_t *trace ); + + + idRenderModelLiquid *model; +}; +#endif + +/* +=============================================================================== + + idShaking + +=============================================================================== +*/ + +class idShaking : public idEntity { +public: + CLASS_PROTOTYPE( idShaking ); + + idShaking(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + idPhysics_Parametric physicsObj; + bool active; + + void BeginShaking( void ); + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + + idEarthQuake + +=============================================================================== +*/ + +class idEarthQuake : public idEntity { +public: + CLASS_PROTOTYPE( idEarthQuake ); + + idEarthQuake(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + +private: + int nextTriggerTime; + int shakeStopTime; + float wait; + float random; + bool triggered; + bool playerOriented; + bool disabled; + float shakeTime; + + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + + idFuncPortal + +=============================================================================== +*/ + +class idFuncPortal : public idEntity { +public: + CLASS_PROTOTYPE( idFuncPortal ); + + idFuncPortal(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + void Think( void ); + +private: + qhandle_t portal; + bool state; + + /** + * Set to true if the portal state depends on distance from player + **/ + bool m_bDistDependent; + + /** + * Timestamp and interval between checks, in milliseconds + **/ + int m_TimeStamp; + int m_Interval; + /** + * Distance at which the portal shuts off, if it is distance dependent + **/ + float m_Distance; + + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + + idFuncAASPortal + +=============================================================================== +*/ + +class idFuncAASPortal : public idEntity { +public: + CLASS_PROTOTYPE( idFuncAASPortal ); + + idFuncAASPortal(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + bool state; + + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + + idFuncAASObstacle + +=============================================================================== +*/ + +class idFuncAASObstacle : public idEntity { +public: + CLASS_PROTOTYPE( idFuncAASObstacle ); + + idFuncAASObstacle(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // greebo: Public function to set the state directly + // Note: Passing TRUE means that the AAS area is DISABLED + void SetAASState(bool newState); + +private: + bool state; + + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + + idPhantomObjects + +=============================================================================== +*/ + +class idPhantomObjects : public idEntity { +public: + CLASS_PROTOTYPE( idPhantomObjects ); + + idPhantomObjects(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + +private: + void Event_Activate( idEntity *activator ); + void Event_Throw( void ); + void Event_ShakeObject( idEntity *object, int starttime ); + + int end_time; + float throw_time; + float shake_time; + idVec3 shake_ang; + float speed; + int min_wait; + int max_wait; + idEntityPtrtarget; + idList targetTime; + idList lastTargetPos; +}; + +/* +=============================================================================== + +idPortalSky + +=============================================================================== +*/ + +class idPortalSky : public idEntity { + +public: + + CLASS_PROTOTYPE( idPortalSky ); + + idPortalSky(); + + virtual ~idPortalSky(); + + void Spawn( void ); + void Event_PostSpawn(); + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + + CVine + +=============================================================================== +*/ + +class tdmVine: public idStaticEntity +{ +public: + CLASS_PROTOTYPE( tdmVine); + // Constructor + tdmVine(); + + // Needed on game save/load + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // Gets called when this entity is actually being spawned + void Spawn(); + +private: + bool _watered; // true if a vine piece was watered during this watering event + tdmVine* _prime; // initial, or prime, vine piece + idList< idEntityPtr >_descendants; // a list of all descendants (kept by prime only) + +protected: + void Event_SetPrime( tdmVine* newPrime ); + void Event_GetPrime(); + void Event_AddDescendant( tdmVine* descendant ); + void Event_ClearWatered(); + void Event_SetWatered(); + void Event_CanWater(); + void Event_ScaleVine(float factor); +}; + + +#endif /* !__GAME_MISC_H__ */ + diff --git a/DarkMod/Missions/Download.cpp b/game/Missions/Download.cpp similarity index 84% rename from DarkMod/Missions/Download.cpp rename to game/Missions/Download.cpp index a613551f8..2120f7720 100644 --- a/DarkMod/Missions/Download.cpp +++ b/game/Missions/Download.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/Missions/Download.h b/game/Missions/Download.h similarity index 82% rename from DarkMod/Missions/Download.h rename to game/Missions/Download.h index 4e9ad6e23..a63870d65 100644 --- a/DarkMod/Missions/Download.h +++ b/game/Missions/Download.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _DOWNLOAD_H_ #define _DOWNLOAD_H_ diff --git a/game/Missions/DownloadManager.cpp b/game/Missions/DownloadManager.cpp new file mode 100644 index 000000000..467a9fea8 --- /dev/null +++ b/game/Missions/DownloadManager.cpp @@ -0,0 +1,120 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "DownloadManager.h" + +CDownloadManager::CDownloadManager() : + _nextAvailableId(1), + _allDownloadsDone(true) +{} + +int CDownloadManager::AddDownload(const CDownloadPtr& download) +{ + int id = _nextAvailableId++; + + _downloads[id] = download; + + _allDownloadsDone = false; + + return id; +} + +CDownloadPtr CDownloadManager::GetDownload(int id) +{ + Downloads::iterator found = _downloads.find(id); + + return (found != _downloads.end()) ? found->second : CDownloadPtr(); +} + +void CDownloadManager::ClearDownloads() +{ + _downloads.clear(); +} + +bool CDownloadManager::DownloadInProgress() +{ + for (Downloads::const_iterator i = _downloads.begin(); i != _downloads.end(); ++i) + { + if (i->second->GetStatus() == CDownload::IN_PROGRESS) + { + return true; + } + } + + return false; +} + +void CDownloadManager::RemoveDownload(int id) +{ + Downloads::iterator found = _downloads.find(id); + + if (found != _downloads.end()) + { + _downloads.erase(found); + } +} + +void CDownloadManager::ProcessDownloads() +{ + if (_allDownloadsDone || _downloads.empty()) + { + return; // nothing to do + } + + if (DownloadInProgress()) + { + return; // download still in progress + } + + // No download in progress, pick a new from the queue + for (Downloads::const_iterator i = _downloads.begin(); i != _downloads.end(); ++i) + { + if (i->second->GetStatus() == CDownload::NOT_STARTED_YET) + { + DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("Starting download: %i", i->first); + + i->second->Start(); + + // Check if this download has a related one, if yes, launch both at once + int relatedId = i->second->GetRelatedDownloadId(); + + if (relatedId != -1) + { + CDownloadPtr related = GetDownload(relatedId); + + if (related) + { + DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("Starting related download: %i", relatedId); + + related->Start(); + } + } + + return; + } + } + + // No download left to handle + _allDownloadsDone = true; +} diff --git a/game/Missions/DownloadManager.h b/game/Missions/DownloadManager.h new file mode 100644 index 000000000..04e6c5765 --- /dev/null +++ b/game/Missions/DownloadManager.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _MISSION_DOWNLOAD_MANAGER_H_ +#define _MISSION_DOWNLOAD_MANAGER_H_ + +#include +#include "Download.h" + +/** + * The class handling the actual mission downloads. + */ +class CDownloadManager +{ +private: + // Ongoing downloads + typedef std::map Downloads; + Downloads _downloads; + + int _nextAvailableId; + + bool _allDownloadsDone; + +public: + CDownloadManager(); + + void ProcessDownloads(); + + void ClearDownloads(); + + int AddDownload(const CDownloadPtr& download); + void RemoveDownload(int id); + + CDownloadPtr GetDownload(int id); + + // Returns true if there is a download already in progress + bool DownloadInProgress(); +}; +typedef boost::shared_ptr CDownloadManagerPtr; + +#endif /* _MISSION_DOWNLOAD_MANAGER_H_ */ diff --git a/DarkMod/Missions/MissionDB.cpp b/game/Missions/MissionDB.cpp similarity index 83% rename from DarkMod/Missions/MissionDB.cpp rename to game/Missions/MissionDB.cpp index 43c13e585..99b91e25a 100644 --- a/DarkMod/Missions/MissionDB.cpp +++ b/game/Missions/MissionDB.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/Missions/MissionDB.h b/game/Missions/MissionDB.h new file mode 100644 index 000000000..2d3efabdf --- /dev/null +++ b/game/Missions/MissionDB.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _MISSION_DB_H_ +#define _MISSION_DB_H_ + +#include +#include +#include "ModInfo.h" + +/** + * greebo: The mission database class holds the list of available TDM missions + * and the corresponding data like play statistics, size info, etc. + */ +class CMissionDB +{ +private: + // Named mission info structures (fs_game => info) + typedef std::map MissionInfoMap; + MissionInfoMap _missionInfo; + +public: + CMissionDB(); + + void Init(); + + // Saves changed data to disk + void Save(); + + // Returns the mission info structure for this fs_game + // Always returns non-NULL, if the name is not existing, + // a new structure will be created + const CModInfoPtr& GetModInfo(const idStr& name); + + // Checks whether there is a record for the given mod name + bool ModInfoExists(const idStr& name); + +private: + void ReloadMissionInfoFile(); +}; +typedef boost::shared_ptr CMissionDBPtr; + +#endif /* _MISSION_DB_H_ */ diff --git a/DarkMod/Missions/MissionManager.cpp b/game/Missions/MissionManager.cpp similarity index 98% rename from DarkMod/Missions/MissionManager.cpp rename to game/Missions/MissionManager.cpp index 7d8912024..0e361c17a 100644 --- a/DarkMod/Missions/MissionManager.cpp +++ b/game/Missions/MissionManager.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -19,8 +29,8 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "../Inventory/Inventory.h" #include "DownloadManager.h" -#include "../DarkMod/Http/HttpConnection.h" -#include "../DarkMod/Http/HttpRequest.h" +#include "../Http/HttpConnection.h" +#include "../Http/HttpRequest.h" #include #include #include diff --git a/DarkMod/Missions/MissionManager.h b/game/Missions/MissionManager.h similarity index 94% rename from DarkMod/Missions/MissionManager.h rename to game/Missions/MissionManager.h index 62822ab30..80114eb58 100644 --- a/DarkMod/Missions/MissionManager.h +++ b/game/Missions/MissionManager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _MISSION_MANAGER_H_ #define _MISSION_MANAGER_H_ diff --git a/DarkMod/Missions/ModInfo.cpp b/game/Missions/ModInfo.cpp similarity index 88% rename from DarkMod/Missions/ModInfo.cpp rename to game/Missions/ModInfo.cpp index 904402627..2156f149a 100644 --- a/DarkMod/Missions/ModInfo.cpp +++ b/game/Missions/ModInfo.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -58,24 +68,22 @@ idStr CModInfo::GetModFolderSizeString() { float size = static_cast(GetModFolderSize()); - // TODO: i18n idStr str; - if (size < 1024) { - str = va("%0.2f %s", size, gameLocal.m_I18N->Translate( "#str_02010" )); // Bytes + str = va("%0.2f %s", size, gameLocal.m_I18N->Translate( "#str_02050" )); // Bytes } else if (size < 1024*1024) { - str = va("%0.0f %s", size/1024.0f, gameLocal.m_I18N->Translate( "#str_02014" )); // kB + str = va("%0.0f %s", size/1024.0f, gameLocal.m_I18N->Translate( "#str_02054" )); // kB } else if (size < 1024.0f*1024.0f*1024.0f) { - str = va("%0.0f %s", size/(1024.0f*1024.0f), gameLocal.m_I18N->Translate( "#str_02015" )); // MB + str = va("%0.0f %s", size/(1024.0f*1024.0f), gameLocal.m_I18N->Translate( "#str_02055" )); // MB } else if (size < 1024.0f*1024.0f*1024.0f*1024.0f) { - str = va("%0.2f %s", size/(1024.0f*1024.0f*1024.0f), gameLocal.m_I18N->Translate( "#str_02016" )); // GB + str = va("%0.2f %s", size/(1024.0f*1024.0f*1024.0f), gameLocal.m_I18N->Translate( "#str_02056" )); // GB } return str; diff --git a/DarkMod/Missions/ModInfo.h b/game/Missions/ModInfo.h similarity index 81% rename from DarkMod/Missions/ModInfo.h rename to game/Missions/ModInfo.h index 9cb1ed6d9..c50a727c7 100644 --- a/DarkMod/Missions/ModInfo.h +++ b/game/Missions/ModInfo.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _MOD_INFO_H_ #define _MOD_INFO_H_ diff --git a/game/Missions/ModInfoDecl.cpp b/game/Missions/ModInfoDecl.cpp new file mode 100644 index 000000000..33cee4eb8 --- /dev/null +++ b/game/Missions/ModInfoDecl.cpp @@ -0,0 +1,111 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "ModInfoDecl.h" + +const char* const CModInfoDecl::TYPE_NAME = "tdm_missioninfo"; + +bool CModInfoDecl::Parse(idLexer& src) +{ + idToken key; + idToken value; + + if (!src.ReadToken(&key)) + { + src.Warning("Unclosed mod info declaration."); + return false; + } + + if (key.type != TT_PUNCTUATION || key.subtype != P_BRACEOPEN) + { + src.Warning("Cannot find opening brace in file %s:%d.", src.GetFileName(), src.GetLineNum()); + return false; + } + + while (true) + { + // If there's an EOF, this is an error. + if (!src.ReadToken(&key)) + { + src.Warning("Unclosed mod info declaration."); + return false; + } + + // Quit upon encountering the closing brace. + if (key.type == TT_PUNCTUATION && key.subtype == P_BRACECLOSE) + { + break; + } + else if (key.type == TT_STRING) + { + // Found a string, this must be a key + if (!src.ReadToken(&value)) + { + src.Warning("Unexpected EOF in key/value pair."); + return false; + } + + if (value.type == TT_STRING) + { + // Save the key:value pair. + data.Set(key.c_str(), value.c_str()); + } + else + { + src.Warning("Invalid value: %s", value.c_str()); + continue; + } + } + else + { + src.Warning("Unrecognized token: %s", key.c_str()); + continue; + } + } + + return true; +} + +void CModInfoDecl::Update(const idStr& name) +{ + _bodyText = TYPE_NAME; + _bodyText += " " + name; + _bodyText += "\n{\n"; + + // Dump the keyvalues + for (int i = 0; i < data.GetNumKeyVals(); ++i) + { + const idKeyValue* kv = data.GetKeyVal(i); + + _bodyText += "\t\"" + kv->GetKey() + "\""; + _bodyText += "\t\"" + kv->GetValue() + "\"\n"; + } + + _bodyText += "}\n\n"; +} + +void CModInfoDecl::SaveToFile(idFile* file) +{ + file->Write(_bodyText.c_str(), _bodyText.Length()); +} diff --git a/game/Missions/ModInfoDecl.h b/game/Missions/ModInfoDecl.h new file mode 100644 index 000000000..ef97b594a --- /dev/null +++ b/game/Missions/ModInfoDecl.h @@ -0,0 +1,49 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _MOD_INFO_DECL_H_ +#define _MOD_INFO_DECL_H_ + +#include "../../idlib/precompiled.h" +#include + +class CModInfoDecl +{ +private: + // The body text used for saving + idStr _bodyText; + +public: + // Construct this declaration from the given token stream + bool Parse(idLexer& src); + + /// Key/value data parsed from the mod info decl. + idDict data; + + // Regenerates the declaration body using the given name as decl name + void Update(const idStr& name); + + // Append the data to the given file + void SaveToFile(idFile* file); + + static const char* const TYPE_NAME; +}; +typedef boost::shared_ptr CModInfoDeclPtr; + +#endif /* _MOD_INFO_DECL_H_ */ diff --git a/DarkMod/ModMenu.cpp b/game/ModMenu.cpp similarity index 93% rename from DarkMod/ModMenu.cpp rename to game/ModMenu.cpp index c6751115f..903ed2d10 100644 --- a/DarkMod/ModMenu.cpp +++ b/game/ModMenu.cpp @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -// Copyright (C) 2004 Id Software, Inc. -// - +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -18,11 +25,11 @@ static bool init_version = FileVersionList("$Id$", init_version); #include #include "ModMenu.h" -#include "../DarkMod/Shop/Shop.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/declxdata.h" -#include "../DarkMod/ZipLoader/ZipLoader.h" -#include "../DarkMod/Missions/MissionManager.h" +#include "Shop/Shop.h" +#include "Objectives/MissionData.h" +#include "declxdata.h" +#include "ZipLoader/ZipLoader.h" +#include "Missions/MissionManager.h" #ifdef _WINDOWS #include @@ -178,6 +185,10 @@ void CModMenu::HandleCommands(const idStr& cmd, idUserInterface* gui) { UninstallMod(gui); } + else if (cmd == "startSelect") // grayman #2933 - save mission start position + { + gameLocal.m_StartPosition = gui->GetStateString("startSelect", ""); + } } void CModMenu::UpdateSelectedMod(idUserInterface* gui) diff --git a/game/ModMenu.h b/game/ModMenu.h new file mode 100644 index 000000000..d84b64d6c --- /dev/null +++ b/game/ModMenu.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _MOD_MENU_H_ +#define _MOD_MENU_H_ + +#pragma once + +#include + +class CModInfo; +typedef boost::shared_ptr CModInfoPtr; + +// Handles mainmenu that displays list of mods (FMs) and lets user +// chose which one to load. Also handles display of briefing page +class CModMenu +{ +private: + // The index of the first displayed mod + int _modTop; + + int _briefingPage; + +public: + CModMenu(); + + // handles main menu commands + void HandleCommands(const idStr& cmd, idUserInterface* gui); + + // updates the GUI variables + void UpdateGUI(idUserInterface* gui); + + // displays the current briefing page + void DisplayBriefingPage(idUserInterface* gui); + +private: + + // Performs the version check and returns TRUE if positive, + // returns FALSE otherwise (and issues failure calls to the given GUI) + bool PerformVersionCheck(const CModInfoPtr& mission, idUserInterface* gui); + + void UpdateSelectedMod(idUserInterface* gui); + + // Installs the given mod (doesn't accept NULL pointers); + void InstallMod(const CModInfoPtr& mod, idUserInterface* gui); + + // Uninstalls the current FM + void UninstallMod(idUserInterface* gui); + + // Restarts the game after mod installation + void RestartGame(); +}; + +#endif /* _MOD_MENU_H_ */ diff --git a/DarkMod/ModelGenerator.cpp b/game/ModelGenerator.cpp similarity index 98% rename from DarkMod/ModelGenerator.cpp rename to game/ModelGenerator.cpp index 6b602a972..22e188df5 100644 --- a/DarkMod/ModelGenerator.cpp +++ b/game/ModelGenerator.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* ModelGenerator diff --git a/DarkMod/ModelGenerator.h b/game/ModelGenerator.h similarity index 92% rename from DarkMod/ModelGenerator.h rename to game/ModelGenerator.h index 0132e0287..001aa86ec 100644 --- a/DarkMod/ModelGenerator.h +++ b/game/ModelGenerator.h @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2010 Tels (Donated to The Dark Mod) diff --git a/game/Moveable.cpp b/game/Moveable.cpp new file mode 100644 index 000000000..03ef6838e --- /dev/null +++ b/game/Moveable.cpp @@ -0,0 +1,1525 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "Objectives/MissionData.h" +#include "StimResponse/StimResponseCollection.h" + +/* +=============================================================================== + + idMoveable + +=============================================================================== +*/ + +const idEventDef EV_BecomeNonSolid( "becomeNonSolid" ); +const idEventDef EV_SetOwnerFromSpawnArgs( "" ); +const idEventDef EV_IsAtRest( "isAtRest", NULL, 'd' ); +const idEventDef EV_EnableDamage( "enableDamage", "f" ); + +CLASS_DECLARATION( idEntity, idMoveable ) + EVENT( EV_Activate, idMoveable::Event_Activate ) + EVENT( EV_BecomeNonSolid, idMoveable::Event_BecomeNonSolid ) + EVENT( EV_SetOwnerFromSpawnArgs, idMoveable::Event_SetOwnerFromSpawnArgs ) + EVENT( EV_IsAtRest, idMoveable::Event_IsAtRest ) + EVENT( EV_EnableDamage, idMoveable::Event_EnableDamage ) +END_CLASS + + +static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f; +static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f; +static const float SLIDING_VELOCITY_THRESHOLD = 5.0f; + +/* +================ +idMoveable::idMoveable +================ +*/ +idMoveable::idMoveable( void ) { + minDamageVelocity = 100.0f; + maxDamageVelocity = 200.0f; + nextCollideFxTime = 0; + nextDamageTime = 0; + nextSoundTime = 0; + m_nextCollideScriptTime = 0; + // 0 => never, -1 => always, positive number X => X times + m_collideScriptCounter = 0; + m_minScriptVelocity = 0.0f; + initialSpline = NULL; + initialSplineDir = vec3_zero; + explode = false; + unbindOnDeath = false; + allowStep = false; + canDamage = false; + + // greebo: A fraction of -1 is considered to be an invalid trace here + memset(&lastCollision, 0, sizeof(lastCollision)); + lastCollision.fraction = -1; + + isPushed = false; + wasPushedLastFrame = false; + pushDirection = vec3_zero; + lastPushOrigin = vec3_zero; + + // by default no LOD + m_LODHandle = 0; + m_DistCheckTimeStamp = 0; +} + +/* +================ +idMoveable::~idMoveable +================ +*/ +idMoveable::~idMoveable( void ) { + delete initialSpline; + initialSpline = NULL; +} + +/* +================ +idMoveable::Spawn +================ +*/ +void idMoveable::Spawn( void ) { + idTraceModel trm; + float density, friction, bouncyness, mass, air_friction_linear, air_friction_angular; + int clipShrink; + idStr clipModelName; + idVec3 maxForce, maxTorque; + + // check if a clip model is set + spawnArgs.GetString( "clipmodel", "", clipModelName ); + if ( !clipModelName[0] ) { + clipModelName = spawnArgs.GetString( "model" ); // use the visual model + } + + // tels: support "model" "" with "noclipmodel" "0" - do not attempt to load + // the clipmodel from the non-existing model name in this case: + if (clipModelName.Length()) { + if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { + gameLocal.Error( "idMoveable '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() ); + return; + } + + // angua: check if the cm is valid + if (idMath::Fabs(trm.bounds[0].x) == idMath::INFINITY) + { + gameLocal.Error( "idMoveable '%s': invalid collision model %s", name.c_str(), clipModelName.c_str() ); + } + + // if the model should be shrunk + clipShrink = spawnArgs.GetInt( "clipshrink" ); + if ( clipShrink != 0 ) { + trm.Shrink( clipShrink * CM_CLIP_EPSILON ); + } + } + + // get rigid body properties + spawnArgs.GetFloat( "density", "0.5", density ); + density = idMath::ClampFloat( 0.001f, 1000.0f, density ); + spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness ); + bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); + explode = spawnArgs.GetBool( "explode" ); + unbindOnDeath = spawnArgs.GetBool( "unbindondeath" ); + + spawnArgs.GetFloat( "friction", "0.05", friction ); + // reverse compatibility, new contact_friction key replaces friction only if present + if( spawnArgs.FindKey("contact_friction") ) + { + spawnArgs.GetFloat( "contact_friction", "0.05", friction ); + } + spawnArgs.GetFloat( "linear_friction", "0.6", air_friction_linear ); + spawnArgs.GetFloat( "angular_friction", "0.6", air_friction_angular ); + + fxCollide = spawnArgs.GetString( "fx_collide" ); + nextCollideFxTime = 0; + + // tels: + m_scriptCollide = spawnArgs.GetString( "script_collide" ); + m_nextCollideScriptTime = 0; + m_collideScriptCounter = spawnArgs.GetInt( "collide_script_counter", "1" ); + // override the default of 1 with 0 if no script is defined + if (m_scriptCollide == "") + { + m_collideScriptCounter = 0; + } + m_minScriptVelocity = spawnArgs.GetFloat( "min_script_velocity", "5.0" ); + + damage = spawnArgs.GetString( "def_damage", "" ); + canDamage = spawnArgs.GetBool( "damageWhenActive" ) ? false : true; + minDamageVelocity = spawnArgs.GetFloat( "minDamageVelocity", "100" ); + maxDamageVelocity = spawnArgs.GetFloat( "maxDamageVelocity", "200" ); + nextDamageTime = 0; + nextSoundTime = 0; + + health = spawnArgs.GetInt( "health", "0" ); + + // tels: load a visual model, as well as an optional brokenModel + LoadModels(); + + // setup the physics + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( trm ), density ); + physicsObj.GetClipModel()->SetMaterial( GetRenderModelMaterial() ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetBouncyness( bouncyness ); + physicsObj.SetFriction( air_friction_linear, air_friction_angular, friction ); + physicsObj.SetGravity( gameLocal.GetGravity() ); + + int contents = CONTENTS_SOLID | CONTENTS_OPAQUE; + // ishtvan: overwrite with custom contents, if present + if( m_CustomContents != -1 ) + contents = m_CustomContents; + + // greebo: Set the frobable contents flag if the spawnarg says so + if (spawnArgs.GetBool("frobable", "0")) + { + contents |= CONTENTS_FROBABLE; + } + + physicsObj.SetContents( contents ); + + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); + SetPhysics( &physicsObj ); + + if ( spawnArgs.GetFloat( "mass", "10", mass ) ) { + physicsObj.SetMass( mass ); + } + + // tels + if ( spawnArgs.GetVector( "max_force", "", maxForce ) ) { + physicsObj.SetMaxForce( maxForce ); + } + if ( spawnArgs.GetVector( "max_torque", "", maxTorque ) ) { + physicsObj.SetMaxTorque( maxTorque ); + } + + if ( spawnArgs.GetBool( "nodrop" ) ) { + physicsObj.PutToRest(); + } else { + physicsObj.DropToFloor(); + } + + if ( spawnArgs.GetBool( "noimpact" ) || spawnArgs.GetBool( "notpushable" ) ) { + physicsObj.DisableImpact(); + } + + if (!spawnArgs.GetBool( "solid" ) ) { + BecomeNonSolid(); + } + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + { + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + } + + m_preHideContents = physicsObj.GetContents(); + m_preHideClipMask = physicsObj.GetClipMask(); + + allowStep = spawnArgs.GetBool( "allowStep", "1" ); + + // parse LOD spawnargs + if (ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ) ) + { + // Have to start thinking if we're distance dependent + BecomeActive( TH_THINK ); + } + + // grayman #2820 - don't queue EV_SetOwnerFromSpawnArgs if it's going to + // end up doing nothing. Queuing this for every moveable causes a lot + // of event posting during frame 0. If extra work is added to + // EV_SetOwnerFromSpawnArgs, then that must be accounted for here, to + // make sure it has a chance of getting done. + + idStr owner; + if ( spawnArgs.GetString( "owner", "", owner ) ) + { + PostEventMS( &EV_SetOwnerFromSpawnArgs, 0 ); + } +} + +/* +================ +idMoveable::Save +================ +*/ +void idMoveable::Save( idSaveGame *savefile ) const { + + savefile->WriteString( brokenModel ); + savefile->WriteString( damage ); + savefile->WriteString( m_scriptCollide ); + savefile->WriteInt( m_collideScriptCounter ); + savefile->WriteInt( m_nextCollideScriptTime ); + savefile->WriteFloat( m_minScriptVelocity ); + savefile->WriteString( fxCollide ); + savefile->WriteInt( nextCollideFxTime ); + savefile->WriteFloat( minDamageVelocity ); + savefile->WriteFloat( maxDamageVelocity ); + savefile->WriteBool( explode ); + savefile->WriteBool( unbindOnDeath ); + savefile->WriteBool( allowStep ); + savefile->WriteBool( canDamage ); + savefile->WriteInt( nextDamageTime ); + savefile->WriteInt( nextSoundTime ); + savefile->WriteInt( initialSpline != NULL ? (int)initialSpline->GetTime( 0 ) : -1 ); + savefile->WriteVec3( initialSplineDir ); + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteTrace(lastCollision); + savefile->WriteBool(isPushed); + savefile->WriteBool(wasPushedLastFrame); + savefile->WriteVec3(pushDirection); + savefile->WriteVec3(lastPushOrigin); +} + +/* +================ +idMoveable::Restore +================ +*/ +void idMoveable::Restore( idRestoreGame *savefile ) { + int initialSplineTime; + + savefile->ReadString( brokenModel ); + savefile->ReadString( damage ); + savefile->ReadString( m_scriptCollide ); + savefile->ReadInt( m_collideScriptCounter ); + savefile->ReadInt( m_nextCollideScriptTime ); + savefile->ReadFloat( m_minScriptVelocity ); + savefile->ReadString( fxCollide ); + savefile->ReadInt( nextCollideFxTime ); + savefile->ReadFloat( minDamageVelocity ); + savefile->ReadFloat( maxDamageVelocity ); + savefile->ReadBool( explode ); + savefile->ReadBool( unbindOnDeath ); + savefile->ReadBool( allowStep ); + savefile->ReadBool( canDamage ); + savefile->ReadInt( nextDamageTime ); + savefile->ReadInt( nextSoundTime ); + savefile->ReadInt( initialSplineTime ); + savefile->ReadVec3( initialSplineDir ); + + if ( initialSplineTime != -1 ) { + InitInitialSpline( initialSplineTime ); + } else { + initialSpline = NULL; + } + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadTrace(lastCollision); + savefile->ReadBool(isPushed); + savefile->ReadBool(wasPushedLastFrame); + savefile->ReadVec3(pushDirection); + savefile->ReadVec3(lastPushOrigin); +} + +/* +================ +idMoveable::Hide +================ +*/ +void idMoveable::Hide( void ) { + idEntity::Hide(); + physicsObj.SetContents( 0 ); +} + +/* +================ +idMoveable::Show +================ +*/ +void idMoveable::Show( void ) +{ + idEntity::Show(); + physicsObj.SetContents( m_preHideContents ); +} + +/* +================= +idMoveable::Collide +================= +*/ + +bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) +{ + // greebo: Check whether we are colliding with the nearly exact same point again + bool sameCollisionAgain = (lastCollision.fraction != -1 && lastCollision.c.point.Compare(collision.c.point, 0.05f)); + + // greebo: Save the collision info for the next call + lastCollision = collision; + + float v = -( velocity * collision.c.normal ); + + if ( !sameCollisionAgain ) + { + float bounceSoundMinVelocity = cv_bounce_sound_min_vel.GetFloat(); + float bounceSoundMaxVelocity = cv_bounce_sound_max_vel.GetFloat(); + + if ( v > bounceSoundMinVelocity && gameLocal.time > nextSoundTime ) + { + const idMaterial *material = collision.c.material; + + idStr sndNameLocal; + idStr surfaceName; // "tile", "glass", etc. + + if (material != NULL) + { + surfaceName = g_Global.GetSurfName(material); + + // Prepend the snd_bounce_ prefix to check for a surface-specific sound + idStr sndNameWithSurface = "snd_bounce_" + surfaceName; + + if (spawnArgs.FindKey(sndNameWithSurface) != NULL) + { + sndNameLocal = sndNameWithSurface; + } + else + { + sndNameLocal = "snd_bounce"; + } + } + + const char* sound = spawnArgs.GetString(sndNameLocal); + const idSoundShader* sndShader = declManager->FindSound(sound); + + //f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ); + + // angua: modify the volume set in the def instead of setting a fixed value. + // At minimum velocity, the volume should be "min_velocity_volume_decrease" lower (in db) than the one specified in the def + float f = v > bounceSoundMaxVelocity ? 0.0f : spawnArgs.GetFloat("min_velocity_volume_decrease", "0") * ( idMath::Sqrt(v - bounceSoundMinVelocity) * (1.0f / idMath::Sqrt( bounceSoundMaxVelocity - bounceSoundMinVelocity)) - 1 ); + + float volume = sndShader->GetParms()->volume + f; + + if (cv_moveable_collision.GetBool()) + { + gameRenderWorld->DrawText( va("Velocity: %f", v), (physicsObj.GetOrigin() + idVec3(0, 0, 20)), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); + gameRenderWorld->DrawText( va("Volume: %f", volume), (physicsObj.GetOrigin() + idVec3(0, 0, 10)), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); + gameRenderWorld->DebugArrow( colorMagenta, collision.c.point, (collision.c.point + 30 * collision.c.normal), 4.0f, 1); + } + + SetSoundVolume(volume); + + // greebo: We don't use StartSound() here, we want to do the sound propagation call manually + StartSoundShader(sndShader, SND_CHANNEL_ANY, 0, false, NULL); + + // grayman #2603 - don't propagate a sound if this is a doused torch dropped by an AI + + if (!spawnArgs.GetBool("is_torch","0")) + { + idStr sndPropName = GetSoundPropNameForMaterial(surfaceName); + + // Propagate a suspicious sound, using the "group" convention (soft, hard, small, med, etc.) + PropSoundS( NULL, sndPropName, f ); + } + + SetSoundVolume(0.0f); + + nextSoundTime = gameLocal.time + 500; + } + + // tels: + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Moveable %s might call script_collide %s because m_collideScriptCounter=%i and v=%f and time=%f > m_nextCollideScriptTime=%f.\r", + name.c_str(), m_scriptCollide.c_str(), m_collideScriptCounter, v, gameLocal.time, m_nextCollideScriptTime ); + if ( m_collideScriptCounter != 0 && v > m_minScriptVelocity && gameLocal.time > m_nextCollideScriptTime ) + { + if ( m_collideScriptCounter > 0) + { + // if positive, decrement it, so -1 stays as it is (for 0, we never come here) + m_collideScriptCounter --; + } + + // call the script + const function_t* pScriptFun = scriptObject.GetFunction( m_scriptCollide.c_str() ); + if (pScriptFun == NULL) + { + // Local function not found, check in global namespace + pScriptFun = gameLocal.program.FindFunction( m_scriptCollide.c_str() ); + } + if (pScriptFun != NULL) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Moveable %s calling script_collide %s.\r", + name.c_str(), m_scriptCollide.c_str()); + idThread *pThread = new idThread( pScriptFun ); + pThread->CallFunctionArgs( pScriptFun, true, "e", this ); + pThread->DelayedStart( 0 ); + } + else + { + // script function not found! + DM_LOG(LC_ENTITY, LT_ERROR)LOGSTRING("Moveable %s could not find script_collide %s.\r", + name.c_str(), m_scriptCollide.c_str()); + m_collideScriptCounter = 0; + } + + m_nextCollideScriptTime = gameLocal.time + 300; + } + + } + + idEntity* ent = gameLocal.entities[ collision.c.entityNum ]; + + if ( canDamage && damage.Length() && gameLocal.time > nextDamageTime ) + { + if ( ent && v > minDamageVelocity ) + { + float f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( v - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) ); + idVec3 dir = velocity; + dir.NormalizeFast(); + ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, CLIPMODEL_ID_TO_JOINT_HANDLE(collision.c.id), const_cast(&collision) ); + nextDamageTime = gameLocal.time + 1000; + } + } + + // Darkmod: Collision stims and a tactile alert if it collides with an AI + if ( ent ) + { + ProcCollisionStims( ent, collision.c.id ); + + if( ent->IsType( idAI::Type ) ) + { + idAI *alertee = static_cast(ent); + alertee->TactileAlert( this ); + } + } + + if ( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) { + idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false ); + nextCollideFxTime = gameLocal.time + 3500; + } + + return false; +} + +idStr idMoveable::GetSoundPropNameForMaterial(const idStr& materialName) +{ + // Object type defaults to "medium" and "hard" + return idStr("bounce_") + spawnArgs.GetString("spr_object_size", "medium") + + "_" + spawnArgs.GetString("spr_object_hardness", "hard") + + "_on_" + g_Global.GetSurfaceHardness(materialName); +} + +/* +============ +idMoveable::Killed +============ +*/ +void idMoveable::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) +{ + bool bPlayerResponsible(false); + + if ( unbindOnDeath ) { + Unbind(); + } + + // tels: call base class method to switch to broken model + idEntity::BecomeBroken( inflictor ); + + if ( explode ) { + if ( brokenModel == "" ) { + PostEventMS( &EV_Remove, 1000 ); + } + } + + if ( renderEntity.gui[ 0 ] ) { + renderEntity.gui[ 0 ] = NULL; + } + + ActivateTargets( this ); + + fl.takedamage = false; + + if ( attacker && attacker->IsType( idPlayer::Type ) ) + bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); + else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) + bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); + + gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); +} + +/* +================ +idMoveable::AllowStep +================ +*/ +bool idMoveable::AllowStep( void ) const { + return allowStep; +} + +/* +================ +idMoveable::BecomeNonSolid +================ +*/ +void idMoveable::BecomeNonSolid( void ) { + // set CONTENTS_RENDERMODEL so bullets still collide with the moveable + physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); + + // SR CONTENTS_RESPONSE FIX: + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); +} + +/* +================ +idMoveable::EnableDamage +================ +*/ +void idMoveable::EnableDamage( bool enable, float duration ) { + canDamage = enable; + if ( duration ) { + PostEventSec( &EV_EnableDamage, duration, ( !enable ) ? 0.0f : 1.0f ); + } +} + +/* +================ +idMoveable::InitInitialSpline +================ +*/ +void idMoveable::InitInitialSpline( int startTime ) { + int initialSplineTime; + + initialSpline = GetSpline(); + initialSplineTime = spawnArgs.GetInt( "initialSplineTime", "300" ); + + if ( initialSpline != NULL ) { + initialSpline->MakeUniform( initialSplineTime ); + initialSpline->ShiftTime( startTime - initialSpline->GetTime( 0 ) ); + initialSplineDir = initialSpline->GetCurrentFirstDerivative( startTime ); + initialSplineDir *= physicsObj.GetAxis().Transpose(); + initialSplineDir.Normalize(); + BecomeActive( TH_THINK ); + } +} + +/* +================ +idMoveable::FollowInitialSplinePath +================ +*/ +bool idMoveable::FollowInitialSplinePath( void ) { + if ( initialSpline != NULL ) { + if ( gameLocal.time < initialSpline->GetTime( initialSpline->GetNumValues() - 1 ) ) { + idVec3 splinePos = initialSpline->GetCurrentValue( gameLocal.time ); + idVec3 linearVelocity = ( splinePos - physicsObj.GetOrigin() ) * USERCMD_HZ; + physicsObj.SetLinearVelocity( linearVelocity ); + + idVec3 splineDir = initialSpline->GetCurrentFirstDerivative( gameLocal.time ); + idVec3 dir = initialSplineDir * physicsObj.GetAxis(); + idVec3 angularVelocity = dir.Cross( splineDir ); + angularVelocity.Normalize(); + angularVelocity *= idMath::ACos16( dir * splineDir / splineDir.Length() ) * USERCMD_HZ; + physicsObj.SetAngularVelocity( angularVelocity ); + return true; + } else { + delete initialSpline; + initialSpline = NULL; + } + } + return false; +} + +/* +================ +idMoveable::Think +================ +*/ +void idMoveable::Think( void ) { + if ( thinkFlags & TH_THINK ) { + if ( !FollowInitialSplinePath() && !isPushed && !m_LODHandle) { + BecomeInactive( TH_THINK ); + } + } + + // will also handle LOD thinking + idEntity::Think(); + + UpdateSlidingSounds(); +} + +/* +================ +idMoveable::GetRenderModelMaterial +================ +*/ +const idMaterial *idMoveable::GetRenderModelMaterial( void ) const { + if ( renderEntity.customShader ) { + return renderEntity.customShader; + } + if ( renderEntity.hModel && renderEntity.hModel->NumSurfaces() ) { + return renderEntity.hModel->Surface( 0 )->shader; + } + return NULL; +} + +/* +================ +idMoveable::WriteToSnapshot +================ +*/ +void idMoveable::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); +} + +/* +================ +idMoveable::ReadFromSnapshot +================ +*/ +void idMoveable::ReadFromSnapshot( const idBitMsgDelta &msg ) { + physicsObj.ReadFromSnapshot( msg ); + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + +void idMoveable::SetIsPushed(bool isNowPushed, const idVec3& pushDirection) +{ + isPushed = isNowPushed; + this->pushDirection = pushDirection; + lastPushOrigin = GetPhysics()->GetOrigin(); + + // Update our think flags to allow UpdateMoveables to be called. + if (isPushed) + { + BecomeActive(TH_THINK); + } +} + +bool idMoveable::IsPushed() +{ + return isPushed; +} + +void idMoveable::UpdateSlidingSounds() +{ + if (isPushed) + { + const idVec3& curVelocity = GetPhysics()->GetLinearVelocity(); + const idVec3& gravityNorm = GetPhysics()->GetGravityNormal(); + + idVec3 xyVelocity = curVelocity - (curVelocity * gravityNorm) * gravityNorm; + + // Only consider the xyspeed if the velocity is in pointing in the same direction as we're being pushed + float xySpeed = (idMath::Fabs(xyVelocity * pushDirection) > 0.2f) ? xyVelocity.NormalizeFast() : 0; + + //gameRenderWorld->DrawText( idStr(xySpeed), GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + //gameRenderWorld->DebugArrow(colorWhite, GetPhysics()->GetAbsBounds().GetCenter(), GetPhysics()->GetAbsBounds().GetCenter() + xyVelocity, 1, gameLocal.msec ); + + if (wasPushedLastFrame && xySpeed <= SLIDING_VELOCITY_THRESHOLD) + { + // We are still being pushed, but we are not fast enough + StopSound(SND_CHANNEL_BODY3, false); + BecomeInactive(TH_THINK); + + isPushed = false; + wasPushedLastFrame = false; + } + else if (!wasPushedLastFrame && xySpeed > SLIDING_VELOCITY_THRESHOLD) + { + if (lastPushOrigin.Compare(GetPhysics()->GetOrigin(), 0.05f)) + { + // We did not really move, despite what the velocity says + StopSound(SND_CHANNEL_BODY3, false); + BecomeInactive(TH_THINK); + isPushed = false; + } + else + { + // We just got into pushed state and are fast enough + StartSound("snd_sliding", SND_CHANNEL_BODY3, 0, false, NULL); + + // Update the state flag for the next round + wasPushedLastFrame = true; + } + } + + lastPushOrigin = GetPhysics()->GetOrigin(); + } + else if (wasPushedLastFrame) + { + // We are not pushed anymore + StopSound(SND_CHANNEL_BODY3, false); + BecomeInactive(TH_THINK); + + // Update the state flag for the next round + wasPushedLastFrame = false; + } +} + +/* +================ +idMoveable::Event_BecomeNonSolid +================ +*/ +void idMoveable::Event_BecomeNonSolid( void ) { + BecomeNonSolid(); +} + +/* +================ +idMoveable::Event_Activate +================ +*/ +void idMoveable::Event_Activate( idEntity *activator ) { + float delay; + idVec3 init_velocity, init_avelocity; + + Show(); + + if ( !spawnArgs.GetInt( "notpushable" ) ) { + physicsObj.EnableImpact(); + } + + physicsObj.Activate(); + + spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); + spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); + + delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); + if ( delay == 0.0f ) { + physicsObj.SetLinearVelocity( init_velocity ); + } else { + PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); + } + + delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); + if ( delay == 0.0f ) { + physicsObj.SetAngularVelocity( init_avelocity ); + } else { + PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); + } + + InitInitialSpline( gameLocal.time ); +} + +/* +================ +idMoveable::Event_SetOwnerFromSpawnArgs +================ +*/ +void idMoveable::Event_SetOwnerFromSpawnArgs( void ) +{ + // grayman #2820 - At the time of this writing, this routine ONLY checks + // whether this moveable has its 'owner' spawnarg set. If anything else is + // added here, the pre-check in moveable.cpp that wraps around "PostEventMS( &EV_SetOwnerFromSpawnArgs, 0 )" + // must account for that. That pre-check is needed to prevent unnecessary + // event posting that leads to doing nothing here. (I.e. the moveable has no owner.) + + idStr owner; + if ( spawnArgs.GetString( "owner", "", owner ) ) + { + ProcessEvent( &EV_SetOwner, gameLocal.FindEntity( owner ) ); + } +} + +/* +================ +idMoveable::Event_IsAtRest +================ +*/ +void idMoveable::Event_IsAtRest( void ) { + idThread::ReturnInt( physicsObj.IsAtRest() ); +} + +/* +================ +idMoveable::Event_EnableDamage +================ +*/ +void idMoveable::Event_EnableDamage( float enable ) { + canDamage = ( enable != 0.0f ); +} + + +/* +=============================================================================== + + idBarrel + +=============================================================================== +*/ + +CLASS_DECLARATION( idMoveable, idBarrel ) +END_CLASS + +/* +================ +idBarrel::idBarrel +================ +*/ +idBarrel::idBarrel() { + radius = 1.0f; + barrelAxis = 0; + lastOrigin.Zero(); + lastAxis.Identity(); + additionalRotation = 0.0f; + additionalAxis.Identity(); + fl.networkSync = true; +} + +/* +================ +idBarrel::Save +================ +*/ +void idBarrel::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( radius ); + savefile->WriteInt( barrelAxis ); + savefile->WriteVec3( lastOrigin ); + savefile->WriteMat3( lastAxis ); + savefile->WriteFloat( additionalRotation ); + savefile->WriteMat3( additionalAxis ); +} + +/* +================ +idBarrel::Restore +================ +*/ +void idBarrel::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( radius ); + savefile->ReadInt( barrelAxis ); + savefile->ReadVec3( lastOrigin ); + savefile->ReadMat3( lastAxis ); + savefile->ReadFloat( additionalRotation ); + savefile->ReadMat3( additionalAxis ); +} + +/* +================ +idBarrel::BarrelThink +================ +*/ +void idBarrel::BarrelThink( void ) { + bool wasAtRest, onGround; + float movedDistance, rotatedDistance, angle; + idVec3 curOrigin, gravityNormal, dir; + idMat3 curAxis, axis; + + wasAtRest = IsAtRest(); + + // run physics + RunPhysics(); + + // only need to give the visual model an additional rotation if the physics were run + if ( !wasAtRest ) { + + // current physics state + onGround = GetPhysics()->HasGroundContacts(); + curOrigin = GetPhysics()->GetOrigin(); + curAxis = GetPhysics()->GetAxis(); + + // if the barrel is on the ground + if ( onGround ) { + gravityNormal = GetPhysics()->GetGravityNormal(); + + dir = curOrigin - lastOrigin; + dir -= gravityNormal * dir * gravityNormal; + movedDistance = dir.LengthSqr(); + + // if the barrel moved and the barrel is not aligned with the gravity direction + if ( movedDistance > 0.0f && idMath::Fabs( gravityNormal * curAxis[barrelAxis] ) < 0.7f ) { + + // barrel movement since last think frame orthogonal to the barrel axis + movedDistance = idMath::Sqrt( movedDistance ); + dir *= 1.0f / movedDistance; + movedDistance = ( 1.0f - idMath::Fabs( dir * curAxis[barrelAxis] ) ) * movedDistance; + + // get rotation about barrel axis since last think frame + angle = lastAxis[(barrelAxis+1)%3] * curAxis[(barrelAxis+1)%3]; + angle = idMath::ACos( angle ); + // distance along cylinder hull + rotatedDistance = angle * radius; + + // if the barrel moved further than it rotated about it's axis + if ( movedDistance > rotatedDistance ) { + + // additional rotation of the visual model to make it look + // like the barrel rolls instead of slides + angle = 180.0f * (movedDistance - rotatedDistance) / (radius * idMath::PI); + if ( gravityNormal.Cross( curAxis[barrelAxis] ) * dir < 0.0f ) { + additionalRotation += angle; + } else { + additionalRotation -= angle; + } + dir = vec3_origin; + dir[barrelAxis] = 1.0f; + additionalAxis = idRotation( vec3_origin, dir, additionalRotation ).ToMat3(); + } + } + } + + // save state for next think + lastOrigin = curOrigin; + lastAxis = curAxis; + } + + Present(); +} + +/* +================ +idBarrel::Think +================ +*/ +void idBarrel::Think( void ) { + if ( thinkFlags & TH_THINK ) { + if ( !FollowInitialSplinePath() ) { + BecomeInactive( TH_THINK ); + } + } + + BarrelThink(); +} + +/* +================ +idBarrel::GetPhysicsToVisualTransform +================ +*/ +bool idBarrel::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { + origin = vec3_origin; + axis = additionalAxis; + return true; +} + +/* +================ +idBarrel::Spawn +================ +*/ +void idBarrel::Spawn( void ) { + const idBounds &bounds = GetPhysics()->GetBounds(); + + // radius of the barrel cylinder + radius = ( bounds[1][0] - bounds[0][0] ) * 0.5f; + + // always a vertical barrel with cylinder axis parallel to the z-axis + barrelAxis = 2; + + lastOrigin = GetPhysics()->GetOrigin(); + lastAxis = GetPhysics()->GetAxis(); + + additionalRotation = 0.0f; + additionalAxis.Identity(); +} + +/* +================ +idBarrel::ClientPredictionThink +================ +*/ +void idBarrel::ClientPredictionThink( void ) { + Think(); +} + + +/* +=============================================================================== + +idExplodingBarrel + +=============================================================================== +*/ +const idEventDef EV_Respawn( "" ); +const idEventDef EV_TriggerTargets( "" ); + +CLASS_DECLARATION( idBarrel, idExplodingBarrel ) + EVENT( EV_Activate, idExplodingBarrel::Event_Activate ) + EVENT( EV_Respawn, idExplodingBarrel::Event_Respawn ) + EVENT( EV_Explode, idExplodingBarrel::Event_Explode ) + EVENT( EV_TriggerTargets, idExplodingBarrel::Event_TriggerTargets ) +END_CLASS + +/* +================ +idExplodingBarrel::idExplodingBarrel +================ +*/ +idExplodingBarrel::idExplodingBarrel() { + spawnOrigin.Zero(); + spawnAxis.Zero(); + state = NORMAL; + particleModelDefHandle = -1; + lightDefHandle = -1; + memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) ); + memset( &light, 0, sizeof( light ) ); + particleTime = 0; + lightTime = 0; + time = 0.0f; +} + +/* +================ +idExplodingBarrel::~idExplodingBarrel +================ +*/ +idExplodingBarrel::~idExplodingBarrel() { + if ( particleModelDefHandle >= 0 ){ + gameRenderWorld->FreeEntityDef( particleModelDefHandle ); + } + if ( lightDefHandle >= 0 ) { + gameRenderWorld->FreeLightDef( lightDefHandle ); + } +} + +/* +================ +idExplodingBarrel::Save +================ +*/ +void idExplodingBarrel::Save( idSaveGame *savefile ) const { + savefile->WriteVec3( spawnOrigin ); + savefile->WriteMat3( spawnAxis ); + + savefile->WriteInt( state ); + savefile->WriteInt( particleModelDefHandle ); + savefile->WriteInt( lightDefHandle ); + + savefile->WriteRenderEntity( particleRenderEntity ); + savefile->WriteRenderLight( light ); + + savefile->WriteInt( particleTime ); + savefile->WriteInt( lightTime ); + savefile->WriteFloat( time ); +} + +/* +================ +idExplodingBarrel::Restore +================ +*/ +void idExplodingBarrel::Restore( idRestoreGame *savefile ) { + savefile->ReadVec3( spawnOrigin ); + savefile->ReadMat3( spawnAxis ); + + savefile->ReadInt( (int &)state ); + savefile->ReadInt( (int &)particleModelDefHandle ); + savefile->ReadInt( (int &)lightDefHandle ); + + savefile->ReadRenderEntity( particleRenderEntity ); + savefile->ReadRenderLight( light ); + + savefile->ReadInt( particleTime ); + savefile->ReadInt( lightTime ); + savefile->ReadFloat( time ); +} + +/* +================ +idExplodingBarrel::Spawn +================ +*/ +void idExplodingBarrel::Spawn( void ) { + health = spawnArgs.GetInt( "health", "5" ); + fl.takedamage = true; + spawnOrigin = GetPhysics()->GetOrigin(); + spawnAxis = GetPhysics()->GetAxis(); + state = NORMAL; + particleModelDefHandle = -1; + lightDefHandle = -1; + lightTime = 0; + particleTime = 0; + time = spawnArgs.GetFloat( "time" ); + memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) ); + memset( &light, 0, sizeof( light ) ); +} + +/* +================ +idExplodingBarrel::Think +================ +*/ +void idExplodingBarrel::Think( void ) { + idBarrel::BarrelThink(); + + if ( lightDefHandle >= 0 ){ + if ( state == BURNING ) { + // ramp the color up over 250 ms + float pct = (gameLocal.time - lightTime) / 250.f; + if ( pct > 1.0f ) { + pct = 1.0f; + } + light.origin = physicsObj.GetAbsBounds().GetCenter(); + light.axis = mat3_identity; + light.shaderParms[ SHADERPARM_RED ] = pct; + light.shaderParms[ SHADERPARM_GREEN ] = pct; + light.shaderParms[ SHADERPARM_BLUE ] = pct; + light.shaderParms[ SHADERPARM_ALPHA ] = pct; + gameRenderWorld->UpdateLightDef( lightDefHandle, &light ); + } else { + if ( gameLocal.time - lightTime > 250 ) { + gameRenderWorld->FreeLightDef( lightDefHandle ); + lightDefHandle = -1; + } + return; + } + } + + if ( !gameLocal.isClient && state != BURNING && state != EXPLODING ) { + BecomeInactive( TH_THINK ); + return; + } + + if ( particleModelDefHandle >= 0 ){ + particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter(); + particleRenderEntity.axis = mat3_identity; + gameRenderWorld->UpdateEntityDef( particleModelDefHandle, &particleRenderEntity ); + } +} + +/* +================ +idExplodingBarrel::AddParticles +================ +*/ +void idExplodingBarrel::AddParticles( const char *name, bool burn ) { + if ( name && *name ) { + if ( particleModelDefHandle >= 0 ){ + gameRenderWorld->FreeEntityDef( particleModelDefHandle ); + } + memset( &particleRenderEntity, 0, sizeof ( particleRenderEntity ) ); + const idDeclModelDef *modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name ) ); + if ( modelDef ) { + particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter(); + particleRenderEntity.axis = mat3_identity; + particleRenderEntity.hModel = modelDef->ModelHandle(); + float rgb = ( burn ) ? 0.0f : 1.0f; + particleRenderEntity.shaderParms[ SHADERPARM_RED ] = rgb; + particleRenderEntity.shaderParms[ SHADERPARM_GREEN ] = rgb; + particleRenderEntity.shaderParms[ SHADERPARM_BLUE ] = rgb; + particleRenderEntity.shaderParms[ SHADERPARM_ALPHA ] = rgb; + particleRenderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.realClientTime ); + particleRenderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = ( burn ) ? 1.0f : gameLocal.random.RandomInt( 90 ); + if ( !particleRenderEntity.hModel ) { + particleRenderEntity.hModel = renderModelManager->FindModel( name ); + } + particleModelDefHandle = gameRenderWorld->AddEntityDef( &particleRenderEntity ); + if ( burn ) { + BecomeActive( TH_THINK ); + } + particleTime = gameLocal.realClientTime; + } + } +} + +/* +================ +idExplodingBarrel::AddLight +================ +*/ +void idExplodingBarrel::AddLight( const char *name, bool burn ) { + if ( lightDefHandle >= 0 ){ + gameRenderWorld->FreeLightDef( lightDefHandle ); + } + memset( &light, 0, sizeof ( light ) ); + light.axis = mat3_identity; + light.lightRadius.x = spawnArgs.GetFloat( "light_radius" ); + light.lightRadius.y = light.lightRadius.z = light.lightRadius.x; + light.origin = physicsObj.GetOrigin(); + light.origin.z += 128; + light.pointLight = true; + light.shader = declManager->FindMaterial( name ); + light.shaderParms[ SHADERPARM_RED ] = 2.0f; + light.shaderParms[ SHADERPARM_GREEN ] = 2.0f; + light.shaderParms[ SHADERPARM_BLUE ] = 2.0f; + light.shaderParms[ SHADERPARM_ALPHA ] = 2.0f; + lightDefHandle = gameRenderWorld->AddLightDef( &light ); + lightTime = gameLocal.realClientTime; + BecomeActive( TH_THINK ); +} + +/* +================ +idExplodingBarrel::ExplodingEffects +================ +*/ +void idExplodingBarrel::ExplodingEffects( void ) { + const char *temp; + + StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL ); + + temp = spawnArgs.GetString( "model_damage" ); + if ( *temp != '\0' ) { + SetModel( temp ); + Show(); + } + + temp = spawnArgs.GetString( "model_detonate" ); + if ( *temp != '\0' ) { + AddParticles( temp, false ); + } + + temp = spawnArgs.GetString( "mtr_lightexplode" ); + if ( *temp != '\0' ) { + AddLight( temp, false ); + } + + temp = spawnArgs.GetString( "mtr_burnmark" ); + if ( *temp != '\0' ) { + gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 128.0f, true, 96.0f, temp ); + } +} + +/* +================ +idExplodingBarrel::Killed +================ +*/ +void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + + if ( IsHidden() || state == EXPLODING || state == BURNING ) { + return; + } + + float f = spawnArgs.GetFloat( "burn" ); + if ( f > 0.0f && state == NORMAL ) { + state = BURNING; + PostEventSec( &EV_Explode, f ); + StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL ); + AddParticles( spawnArgs.GetString ( "model_burn", "" ), true ); + return; + } else { + state = EXPLODING; + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( gameLocal.time ); + ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 ); + } + } + + // do this before applying radius damage so the ent can trace to any damagable ents nearby + Hide(); + physicsObj.SetContents( 0 ); + + const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" ); + if ( splash && *splash ) { + gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash ); + } + + ExplodingEffects( ); + + //FIXME: need to precache all the debris stuff here and in the projectiles + const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" ); + // bool first = true; + while ( kv ) { + const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false ); + if ( debris_args ) { + idEntity *ent; + idVec3 dir; + idDebris *debris; + //if ( first ) { + dir = physicsObj.GetAxis()[1]; + // first = false; + //} else { + dir.x += gameLocal.random.CRandomFloat() * 4.0f; + dir.y += gameLocal.random.CRandomFloat() * 4.0f; + //dir.z = gameLocal.random.RandomFloat() * 8.0f; + //} + dir.Normalize(); + + gameLocal.SpawnEntityDef( *debris_args, &ent, false ); + if ( !ent || !ent->IsType( idDebris::Type ) ) { + gameLocal.Error( "'projectile_debris' is not an idDebris" ); + } + + debris = static_cast(ent); + debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() ); + debris->Launch(); + debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f; + debris->UpdateVisuals(); + + } + kv = spawnArgs.MatchPrefix( "def_debris", kv ); + } + + physicsObj.PutToRest(); + CancelEvents( &EV_Explode ); + CancelEvents( &EV_Activate ); + + f = spawnArgs.GetFloat( "respawn" ); + if ( f > 0.0f ) { + PostEventSec( &EV_Respawn, f ); + } else { + PostEventMS( &EV_Remove, 5000 ); + } + + if ( spawnArgs.GetBool( "triggerTargets" ) ) { + ActivateTargets( this ); + } +} + +/* +================ +idExplodingBarrel::Damage +================ +*/ +void idExplodingBarrel::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, trace_t *tr ) +{ + + const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) { + gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); + } + if ( damageDef->FindKey( "radius" ) && GetPhysics()->GetContents() != 0 && GetBindMaster() == NULL ) { + PostEventMS( &EV_Explode, 400 ); + } else { + idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); + } +} + +/* +================ +idExplodingBarrel::Event_TriggerTargets +================ +*/ +void idExplodingBarrel::Event_TriggerTargets() { + ActivateTargets( this ); +} + +/* +================ +idExplodingBarrel::Event_Explode +================ +*/ +void idExplodingBarrel::Event_Explode() { + if ( state == NORMAL || state == BURNING ) { + state = BURNEXPIRED; + Killed( NULL, NULL, 0, vec3_zero, 0 ); + } +} + +/* +================ +idExplodingBarrel::Event_Respawn +================ +*/ +void idExplodingBarrel::Event_Respawn() { + int i; + int minRespawnDist = spawnArgs.GetInt( "respawn_range", "256" ); + if ( minRespawnDist ) { + float minDist = -1; + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { + continue; + } + idVec3 v = gameLocal.entities[ i ]->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + float dist = v.Length(); + if ( minDist < 0 || dist < minDist ) { + minDist = dist; + } + } + if ( minDist < minRespawnDist ) { + PostEventSec( &EV_Respawn, spawnArgs.GetInt( "respawn_again", "10" ) ); + return; + } + } + const char *temp = spawnArgs.GetString( "model" ); + if ( temp && *temp ) { + SetModel( temp ); + } + health = spawnArgs.GetInt( "health", "5" ); + fl.takedamage = true; + physicsObj.SetOrigin( spawnOrigin ); + physicsObj.SetAxis( spawnAxis ); + physicsObj.SetContents( CONTENTS_SOLID ); + // override with custom contents if present + if( m_CustomContents != -1 ) + physicsObj.SetContents( m_CustomContents ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + physicsObj.DropToFloor(); + state = NORMAL; + Show(); + UpdateVisuals(); +} + +/* +================ +idMoveable::Event_Activate +================ +*/ +void idExplodingBarrel::Event_Activate( idEntity *activator ) { + Killed( activator, activator, 0, vec3_origin, 0 ); +} + +/* +================ +idMoveable::WriteToSnapshot +================ +*/ +void idExplodingBarrel::WriteToSnapshot( idBitMsgDelta &msg ) const { + idMoveable::WriteToSnapshot( msg ); + msg.WriteBits( IsHidden(), 1 ); +} + +/* +================ +idMoveable::ReadFromSnapshot +================ +*/ +void idExplodingBarrel::ReadFromSnapshot( const idBitMsgDelta &msg ) { + + idMoveable::ReadFromSnapshot( msg ); + if ( msg.ReadBits( 1 ) ) { + Hide(); + } else { + Show(); + } +} + +/* +================ +idExplodingBarrel::ClientReceiveEvent +================ +*/ +bool idExplodingBarrel::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + + switch( event ) { + case EVENT_EXPLODE: { + if ( gameLocal.realClientTime - msg.ReadLong() < spawnArgs.GetInt( "explode_lapse", "1000" ) ) { + ExplodingEffects( ); + } + return true; + } + default: { + return idBarrel::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} diff --git a/game/Moveable.h b/game/Moveable.h new file mode 100644 index 000000000..f937f4e4d --- /dev/null +++ b/game/Moveable.h @@ -0,0 +1,218 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_MOVEABLE_H__ +#define __GAME_MOVEABLE_H__ + +/* +=============================================================================== + + Entity using rigid body physics. + +=============================================================================== +*/ + +extern const idEventDef EV_BecomeNonSolid; +extern const idEventDef EV_IsAtRest; + +class idMoveable : public idEntity { +public: + CLASS_PROTOTYPE( idMoveable ); + + idMoveable( void ); + virtual ~idMoveable( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + + virtual void Hide( void ); + virtual void Show( void ); + + bool AllowStep( void ) const; + void EnableDamage( bool enable, float duration ); + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + // Update the "pushed" state of this entity + virtual void SetIsPushed(bool isPushed, const idVec3& pushDirection); + + // Returns true if the entity is pushed by something or someone + virtual bool IsPushed(); + +protected: + idPhysics_RigidBody physicsObj; // physics object + idStr damage; // if > 0 apply damage to hit entities + idStr fxCollide; // fx system to start when collides with something + int nextCollideFxTime; // next time it is ok to spawn collision fx + + /** + * TDM Collision scripts + **/ + idStr m_scriptCollide; // script function to call when collides with something + int m_nextCollideScriptTime;// next time it is ok to call collision script + int m_collideScriptCounter; // how often to call the collision script + // 0 => never, -1 => always, +X => X times + float m_minScriptVelocity; // minimum velocity before calling collide script + + float minDamageVelocity; // minimum velocity before moveable applies damage + float maxDamageVelocity; // velocity at which the maximum damage is applied + idCurve_Spline *initialSpline; // initial spline path the moveable follows + idVec3 initialSplineDir; // initial relative direction along the spline path + bool explode; // entity explodes when health drops down to or below zero + bool unbindOnDeath; // unbind from master when health drops down to or below zero + bool allowStep; // allow monsters to step on the object + bool canDamage; // only apply damage when this is set + int nextDamageTime; // next time the movable can hurt the player + int nextSoundTime; // next time the moveable can make a sound + + // greebo: Stores the last collision info to avoid constant playing of the collision sound when stuck + trace_t lastCollision; + + bool isPushed; // true if the entity is pushed by something/someone + bool wasPushedLastFrame; // true if the entity was pushed the last frame + idVec3 pushDirection; // the direction the moveable is pushed in + idVec3 lastPushOrigin; // the old origin during pushing to compare whether we have actually moved somewhere + + const idMaterial * GetRenderModelMaterial( void ) const; + void BecomeNonSolid( void ); + void InitInitialSpline( int startTime ); + bool FollowInitialSplinePath( void ); + + // greebo: Returns the soundprop name for the given material (e.g. "sprS_bounce_small_hard_on_soft") + idStr GetSoundPropNameForMaterial(const idStr& materialName); + + // greebo: Updates the sliding sounds according to the "pushed" state + void UpdateSlidingSounds(); + + void Event_Activate( idEntity *activator ); + void Event_BecomeNonSolid( void ); + void Event_SetOwnerFromSpawnArgs( void ); + void Event_IsAtRest( void ); + void Event_EnableDamage( float enable ); +}; + + +/* +=============================================================================== + + A barrel using rigid body physics. The barrel has special handling of + the view model orientation to make it look like it rolls instead of slides. + +=============================================================================== +*/ + +class idBarrel : public idMoveable { + +public: + CLASS_PROTOTYPE( idBarrel ); + idBarrel(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void BarrelThink( void ); + virtual void Think( void ); + virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); + virtual void ClientPredictionThink( void ); + +private: + float radius; // radius of barrel + int barrelAxis; // one of the coordinate axes the barrel cylinder is parallel to + idVec3 lastOrigin; // origin of the barrel the last think frame + idMat3 lastAxis; // axis of the barrel the last think frame + float additionalRotation; // additional rotation of the barrel about it's axis + idMat3 additionalAxis; // additional rotation axis +}; + + +/* +=============================================================================== + + A barrel using rigid body physics and special handling of the view model + orientation to make it look like it rolls instead of slides. The barrel + can burn and explode when damaged. + +=============================================================================== +*/ + +class idExplodingBarrel : public idBarrel { +public: + CLASS_PROTOTYPE( idExplodingBarrel ); + + idExplodingBarrel(); + virtual ~idExplodingBarrel(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName,const float damageScale, + const int location, trace_t *tr = NULL ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + enum { + EVENT_EXPLODE = idEntity::EVENT_MAXEVENTS, + EVENT_MAXEVENTS + }; + +private: + typedef enum { + NORMAL = 0, + BURNING, + BURNEXPIRED, + EXPLODING + } explode_state_t; + explode_state_t state; + + idVec3 spawnOrigin; + idMat3 spawnAxis; + qhandle_t particleModelDefHandle; + qhandle_t lightDefHandle; + renderEntity_t particleRenderEntity; + renderLight_t light; + int particleTime; + int lightTime; + float time; + + void AddParticles( const char *name, bool burn ); + void AddLight( const char *name , bool burn ); + void ExplodingEffects( void ); + + void Event_Activate( idEntity *activator ); + void Event_Respawn(); + void Event_Explode(); + void Event_TriggerTargets(); +}; + +#endif /* !__GAME_MOVEABLE_H__ */ diff --git a/game/Mover.cpp b/game/Mover.cpp new file mode 100644 index 000000000..c398eb2c3 --- /dev/null +++ b/game/Mover.cpp @@ -0,0 +1,3372 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "Objectives/MissionData.h" +#include "StimResponse/StimResponseCollection.h" + +// a mover will update any gui entities in its target list with +// a key/val pair of "mover" "state" from below.. guis can represent +// realtime info like this +// binary only +static const char *guiBinaryMoverStates[] = { + "1", // pos 1 + "2", // pos 2 + "3", // moving 1 to 2 + "4" // moving 2 to 1 +}; + + +/* +=============================================================================== + +idMover + +=============================================================================== +*/ + +const idEventDef EV_FindGuiTargets( "", NULL ); +const idEventDef EV_TeamBlocked( "", "ee" ); +const idEventDef EV_PartBlocked( "", "e" ); +const idEventDef EV_ReachedPos( "", NULL ); +const idEventDef EV_ReachedAng( "", NULL ); +const idEventDef EV_PostRestore( "", "ddddd" ); +const idEventDef EV_StopMoving( "stopMoving", NULL ); +const idEventDef EV_StopRotating( "stopRotating", NULL ); +const idEventDef EV_Speed( "speed", "f" ); +const idEventDef EV_Time( "time", "f" ); +const idEventDef EV_AccelTime( "accelTime", "f" ); +const idEventDef EV_DecelTime( "decelTime", "f" ); +const idEventDef EV_MoveTo( "moveTo", "e" ); +const idEventDef EV_MoveToPos( "moveToPos", "v" ); +const idEventDef EV_Move( "move", "ff" ); +const idEventDef EV_MoveAccelerateTo( "accelTo", "ff" ); +const idEventDef EV_MoveDecelerateTo( "decelTo", "ff" ); +const idEventDef EV_RotateDownTo( "rotateDownTo", "df" ); +const idEventDef EV_RotateUpTo( "rotateUpTo", "df" ); +const idEventDef EV_RotateTo( "rotateTo", "v" ); +const idEventDef EV_Rotate( "rotate", "v" ); +const idEventDef EV_RotateOnce( "rotateOnce", "v" ); +const idEventDef EV_Bob( "bob", "ffv" ); +const idEventDef EV_Sway( "sway", "ffv" ); +const idEventDef EV_Mover_OpenPortal( "openPortal" ); +const idEventDef EV_Mover_ClosePortal( "closePortal" ); +const idEventDef EV_AccelSound( "accelSound", "s" ); +const idEventDef EV_DecelSound( "decelSound", "s" ); +const idEventDef EV_MoveSound( "moveSound", "s" ); +const idEventDef EV_Mover_InitGuiTargets( "", NULL ); +const idEventDef EV_EnableSplineAngles( "enableSplineAngles", NULL ); +const idEventDef EV_DisableSplineAngles( "disableSplineAngles", NULL ); +const idEventDef EV_RemoveInitialSplineAngles( "removeInitialSplineAngles", NULL ); +const idEventDef EV_StartSpline( "startSpline", "e" ); +const idEventDef EV_StopSpline( "stopSpline", NULL ); +const idEventDef EV_IsMoving( "isMoving", NULL, 'd' ); +const idEventDef EV_IsRotating( "isRotating", NULL, 'd' ); + +CLASS_DECLARATION( idEntity, idMover ) + EVENT( EV_FindGuiTargets, idMover::Event_FindGuiTargets ) + EVENT( EV_Thread_SetCallback, idMover::Event_SetCallback ) + EVENT( EV_TeamBlocked, idMover::Event_TeamBlocked ) + EVENT( EV_PartBlocked, idMover::Event_PartBlocked ) + EVENT( EV_ReachedPos, idMover::Event_UpdateMove ) + EVENT( EV_ReachedAng, idMover::Event_UpdateRotation ) + EVENT( EV_PostRestore, idMover::Event_PostRestore ) + EVENT( EV_StopMoving, idMover::Event_StopMoving ) + EVENT( EV_StopRotating, idMover::Event_StopRotating ) + EVENT( EV_Speed, idMover::Event_SetMoveSpeed ) + EVENT( EV_Time, idMover::Event_SetMoveTime ) + EVENT( EV_AccelTime, idMover::Event_SetAccellerationTime ) + EVENT( EV_DecelTime, idMover::Event_SetDecelerationTime ) + EVENT( EV_MoveTo, idMover::Event_MoveTo ) + EVENT( EV_MoveToPos, idMover::Event_MoveToPos ) + EVENT( EV_Move, idMover::Event_MoveDir ) + EVENT( EV_MoveAccelerateTo, idMover::Event_MoveAccelerateTo ) + EVENT( EV_MoveDecelerateTo, idMover::Event_MoveDecelerateTo ) + EVENT( EV_RotateDownTo, idMover::Event_RotateDownTo ) + EVENT( EV_RotateUpTo, idMover::Event_RotateUpTo ) + EVENT( EV_RotateTo, idMover::Event_RotateTo ) + EVENT( EV_Rotate, idMover::Event_Rotate ) + EVENT( EV_RotateOnce, idMover::Event_RotateOnce ) + EVENT( EV_Bob, idMover::Event_Bob ) + EVENT( EV_Sway, idMover::Event_Sway ) + EVENT( EV_Mover_OpenPortal, idMover::Event_OpenPortal ) + EVENT( EV_Mover_ClosePortal, idMover::Event_ClosePortal ) + EVENT( EV_AccelSound, idMover::Event_SetAccelSound ) + EVENT( EV_DecelSound, idMover::Event_SetDecelSound ) + EVENT( EV_MoveSound, idMover::Event_SetMoveSound ) + EVENT( EV_Mover_InitGuiTargets, idMover::Event_InitGuiTargets ) + EVENT( EV_EnableSplineAngles, idMover::Event_EnableSplineAngles ) + EVENT( EV_DisableSplineAngles, idMover::Event_DisableSplineAngles ) + EVENT( EV_RemoveInitialSplineAngles, idMover::Event_RemoveInitialSplineAngles ) + EVENT( EV_StartSpline, idMover::Event_StartSpline ) + EVENT( EV_StopSpline, idMover::Event_StopSpline ) + EVENT( EV_Activate, idMover::Event_Activate ) + EVENT( EV_IsMoving, idMover::Event_IsMoving ) + EVENT( EV_IsRotating, idMover::Event_IsRotating ) +END_CLASS + +/* +================ +idMover::idMover +================ +*/ +idMover::idMover(void) +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); + + memset( &move, 0, sizeof( move ) ); + memset( &rot, 0, sizeof( rot ) ); + move_thread = 0; + rotate_thread = 0; + dest_angles.Zero(); + angle_delta.Zero(); + dest_position.Zero(); + move_delta.Zero(); + move_speed = 0.0f; + move_time = 0; + deceltime = 0; + acceltime = 0; + stopRotation = false; + useSplineAngles = true; + lastCommand = MOVER_NONE; + damage = 0.0f; + areaPortal = 0; + fl.networkSync = true; + m_FrobActionScript = "frob_mover"; +} + +/* +================ +idMover::Save +================ +*/ +void idMover::Save( idSaveGame *savefile ) const +{ + int i; + + savefile->WriteStaticObject( physicsObj ); + savefile->WriteInt( move.stage ); + savefile->WriteInt( move.acceleration ); + savefile->WriteInt( move.movetime ); + + savefile->WriteInt( move.deceleration ); + savefile->WriteVec3( move.dir ); + + savefile->WriteInt( rot.stage ); + savefile->WriteInt( rot.acceleration ); + savefile->WriteInt( rot.movetime ); + savefile->WriteInt( rot.deceleration ); + savefile->WriteAngles( rot.rot ); + + savefile->WriteInt( move_thread ); + savefile->WriteInt( rotate_thread ); + + savefile->WriteAngles( dest_angles ); + savefile->WriteAngles( angle_delta ); + savefile->WriteVec3( dest_position ); + savefile->WriteVec3( move_delta ); + + savefile->WriteFloat( move_speed ); + savefile->WriteInt( move_time ); + savefile->WriteInt( deceltime ); + savefile->WriteInt( acceltime ); + savefile->WriteBool( stopRotation ); + savefile->WriteBool( useSplineAngles ); + savefile->WriteInt( lastCommand ); + savefile->WriteFloat( damage ); + + savefile->WriteInt( areaPortal ); + if ( areaPortal > 0 ) { + savefile->WriteInt( gameRenderWorld->GetPortalState( areaPortal ) ); + } + + savefile->WriteInt( guiTargets.Num() ); + for( i = 0; i < guiTargets.Num(); i++ ) { + guiTargets[ i ].Save( savefile ); + } + + if ( splineEnt.GetEntity() && splineEnt.GetEntity()->GetSpline() ) { + idCurve_Spline *spline = physicsObj.GetSpline(); + + savefile->WriteBool( true ); + splineEnt.Save( savefile ); + savefile->WriteInt( static_cast(spline->GetTime( 0 )) ); + savefile->WriteInt( static_cast(spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 )) ); + savefile->WriteInt( physicsObj.GetSplineAcceleration() ); + savefile->WriteInt( physicsObj.GetSplineDeceleration() ); + savefile->WriteInt( (int)physicsObj.UsingSplineAngles() ); + + } else { + savefile->WriteBool( false ); + } +} + +/* +================ +idMover::Restore +================ +*/ +void idMover::Restore( idRestoreGame *savefile ) { + int i, num; + bool hasSpline = false; + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadInt( (int&)move.stage ); + savefile->ReadInt( move.acceleration ); + savefile->ReadInt( move.movetime ); + savefile->ReadInt( move.deceleration ); + savefile->ReadVec3( move.dir ); + + savefile->ReadInt( (int&)rot.stage ); + savefile->ReadInt( rot.acceleration ); + savefile->ReadInt( rot.movetime ); + savefile->ReadInt( rot.deceleration ); + + savefile->ReadAngles( rot.rot ); + + savefile->ReadInt( move_thread ); + savefile->ReadInt( rotate_thread ); + + savefile->ReadAngles( dest_angles ); + savefile->ReadAngles( angle_delta ); + savefile->ReadVec3( dest_position ); + savefile->ReadVec3( move_delta ); + + savefile->ReadFloat( move_speed ); + savefile->ReadInt( move_time ); + savefile->ReadInt( deceltime ); + savefile->ReadInt( acceltime ); + savefile->ReadBool( stopRotation ); + savefile->ReadBool( useSplineAngles ); + savefile->ReadInt( (int &)lastCommand ); + savefile->ReadFloat( damage ); + + savefile->ReadInt( areaPortal ); + if ( areaPortal > 0 ) { + int portalState = 0; + savefile->ReadInt( portalState ); + gameLocal.SetPortalState( areaPortal, portalState ); + } + + guiTargets.Clear(); + savefile->ReadInt( num ); + guiTargets.SetNum( num ); + for( i = 0; i < num; i++ ) { + guiTargets[ i ].Restore( savefile ); + } + + savefile->ReadBool( hasSpline ); + if ( hasSpline ) { + int starttime; + int totaltime; + int accel; + int decel; + int useAngles; + + splineEnt.Restore( savefile ); + savefile->ReadInt( starttime ); + savefile->ReadInt( totaltime ); + savefile->ReadInt( accel ); + savefile->ReadInt( decel ); + savefile->ReadInt( useAngles ); + + PostEventMS( &EV_PostRestore, 0, starttime, totaltime, accel, decel, useAngles ); + } +} + +/* +================ +idMover::Event_PostRestore +================ +*/ +void idMover::Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng ) { + idCurve_Spline *spline; + + idEntity *splineEntity = splineEnt.GetEntity(); + if ( !splineEntity ) { + // We should never get this event if splineEnt is invalid + common->Warning( "Invalid spline entity during restore\n" ); + return; + } + + spline = splineEntity->GetSpline(); + + spline->MakeUniform( total ); + spline->ShiftTime( start - spline->GetTime( 0 ) ); + + physicsObj.SetSpline( spline, accel, decel, ( useSplineAng != 0 ) ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); +} + +/* +================ +idMover::Spawn +================ +*/ +void idMover::Spawn( void ) +{ + move_thread = 0; + rotate_thread = 0; + stopRotation = false; + lastCommand = MOVER_NONE; + + acceltime = static_cast(1000.0f * spawnArgs.GetFloat( "accel_time", "0" )); + deceltime = static_cast(1000.0f * spawnArgs.GetFloat( "decel_time", "0" )); + move_time = static_cast(1000.0f * spawnArgs.GetFloat( "move_time", "1" )); // safe default value + move_speed = spawnArgs.GetFloat( "move_speed", "0" ); + + spawnArgs.GetFloat( "damage" , "0", damage ); + + dest_position = GetPhysics()->GetOrigin(); + dest_angles = GetPhysics()->GetAxis().ToAngles(); + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "solid", "1" ) ) { + physicsObj.SetContents( 0 ); + } + if ( !renderEntity.hModel || !spawnArgs.GetBool( "nopush" ) ) { + // greebo: Check if we should be able to push the player (default is yes) + if (spawnArgs.GetBool("push_player", "1")) { + physicsObj.SetPusher(0); + } + else { + physicsObj.SetPusher(PUSHFL_NOPLAYER); + } + } + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); + SetPhysics( &physicsObj ); + + // see if we are on an areaportal + areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); + + if ( spawnArgs.MatchPrefix( "guiTarget" ) ) { + if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { + PostEventMS( &EV_FindGuiTargets, 0 ); + } else { + // not during spawn, so it's ok to get the targets + FindGuiTargets(); + } + } + + health = spawnArgs.GetInt( "health" ); + if ( health ) { + fl.takedamage = true; + } +} + +/* +================ +idMover::Hide +================ +*/ +void idMover::Hide( void ) { + idEntity::Hide(); + physicsObj.SetContents( 0 ); +} + +/* +================ +idMover::Show +================ +*/ +void idMover::Show( void ) { + idEntity::Show(); + physicsObj.SetContents( m_preHideContents ); + SetPhysics( &physicsObj ); +} + +/* +============ +idMover::Killed +============ +*/ +void idMover::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) +{ + bool bPlayerResponsible(false); + + fl.takedamage = false; + ActivateTargets( this ); + + if ( attacker && attacker->IsType( idPlayer::Type ) ) + bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); + else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) + bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); + + gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); +} + + +/* +================ +idMover::Event_SetCallback +================ +*/ +void idMover::Event_SetCallback( void ) { + if ( ( lastCommand == MOVER_ROTATING ) && !rotate_thread ) { + lastCommand = MOVER_NONE; + rotate_thread = idThread::CurrentThreadNum(); + idThread::ReturnInt( true ); + } else if ( ( lastCommand == MOVER_MOVING || lastCommand == MOVER_SPLINE ) && !move_thread ) { + lastCommand = MOVER_NONE; + move_thread = idThread::CurrentThreadNum(); + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/* +================ +idMover::VectorForDir +================ +*/ +void idMover::VectorForDir( float angle, idVec3 &vec ) { + idAngles ang; + + switch( ( int )angle ) { + case DIR_UP : + vec.Set( 0, 0, 1 ); + break; + + case DIR_DOWN : + vec.Set( 0, 0, -1 ); + break; + + case DIR_LEFT : + physicsObj.GetLocalAngles( ang ); + ang.pitch = 0; + ang.roll = 0; + ang.yaw += 90; + vec = ang.ToForward(); + break; + + case DIR_RIGHT : + physicsObj.GetLocalAngles( ang ); + ang.pitch = 0; + ang.roll = 0; + ang.yaw -= 90; + vec = ang.ToForward(); + break; + + case DIR_FORWARD : + physicsObj.GetLocalAngles( ang ); + ang.pitch = 0; + ang.roll = 0; + vec = ang.ToForward(); + break; + + case DIR_BACK : + physicsObj.GetLocalAngles( ang ); + ang.pitch = 0; + ang.roll = 0; + ang.yaw += 180; + vec = ang.ToForward(); + break; + + case DIR_REL_UP : + vec.Set( 0, 0, 1 ); + break; + + case DIR_REL_DOWN : + vec.Set( 0, 0, -1 ); + break; + + case DIR_REL_LEFT : + physicsObj.GetLocalAngles( ang ); + ang.ToVectors( NULL, &vec ); + vec *= -1; + break; + + case DIR_REL_RIGHT : + physicsObj.GetLocalAngles( ang ); + ang.ToVectors( NULL, &vec ); + break; + + case DIR_REL_FORWARD : + physicsObj.GetLocalAngles( ang ); + vec = ang.ToForward(); + break; + + case DIR_REL_BACK : + physicsObj.GetLocalAngles( ang ); + vec = ang.ToForward() * -1; + break; + + default: + ang.Set( 0, angle, 0 ); + vec = GetWorldVector( ang.ToForward() ); + break; + } +} + +/* +================ +idMover::FindGuiTargets +================ +*/ +void idMover::FindGuiTargets( void ) { + gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" ); +} + +/* +============================== +idMover::SetGuiState + +key/val will be set to any renderEntity->gui's on the list +============================== +*/ +void idMover::SetGuiState( const char *key, const char *val ) const { + gameLocal.Printf( "Setting %s to %s\n", key, val ); + for( int i = 0; i < guiTargets.Num(); i++ ) { + idEntity *ent = guiTargets[ i ].GetEntity(); + if ( ent ) { + for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { + if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) { + ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); + ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time, true ); + } + } + ent->UpdateVisuals(); + } + } +} + +/* +================ +idMover::Event_InitGuiTargets +================ +*/ +void idMover::Event_FindGuiTargets( void ) { + FindGuiTargets(); +} + +/* +================ +idMover::SetGuiStates +================ +*/ +void idMover::SetGuiStates( const char *state ) { + int i; + if ( guiTargets.Num() ) { + SetGuiState( "movestate", state ); + } + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + if ( renderEntity.gui[ i ] ) { + renderEntity.gui[ i ]->SetStateString( "movestate", state ); + renderEntity.gui[ i ]->StateChanged( gameLocal.time, true ); + } + } +} + +/* +================ +idMover::Event_InitGuiTargets +================ +*/ +void idMover::Event_InitGuiTargets( void ) { + SetGuiStates( guiBinaryMoverStates[MOVER_POS1] ); +} + +/*********************************************************************** + + Translation control functions + +***********************************************************************/ + +/* +================ +idMover::Event_StopMoving +================ +*/ +void idMover::Event_StopMoving( void ) { + physicsObj.GetLocalOrigin( dest_position ); + DoneMoving(); +} + +/* +================ +idMover::DoneMoving +================ +*/ +void idMover::DoneMoving( void ) { + + if ( lastCommand != MOVER_SPLINE ) { + // set our final position so that we get rid of any numerical inaccuracy + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); + } + + lastCommand = MOVER_NONE; + idThread::ObjectMoveDone( move_thread, this ); + move_thread = 0; + + StopSound( SND_CHANNEL_BODY, false ); +} + +/* +================ +idMover::UpdateMoveSound +================ +*/ +void idMover::UpdateMoveSound( moveStage_t stage ) { + switch( stage ) { + case ACCELERATION_STAGE: { + StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + break; + } + case LINEAR_STAGE: { + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + break; + } + case DECELERATION_STAGE: { + StopSound( SND_CHANNEL_BODY, false ); + StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); + break; + } + case FINISHED_STAGE: { + StopSound( SND_CHANNEL_BODY, false ); + break; + } + } +} + +/* +================ +idMover::Event_UpdateMove +================ +*/ +void idMover::Event_UpdateMove( void ) { + idVec3 org; + + physicsObj.GetLocalOrigin( org ); + + UpdateMoveSound( move.stage ); + + switch( move.stage ) { + case ACCELERATION_STAGE: { + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, move.acceleration, org, move.dir, vec3_origin ); + if ( move.movetime > 0 ) { + move.stage = LINEAR_STAGE; + } else if ( move.deceleration > 0 ) { + move.stage = DECELERATION_STAGE; + } else { + move.stage = FINISHED_STAGE; + } + break; + } + case LINEAR_STAGE: { + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, move.movetime, org, move.dir, vec3_origin ); + if ( move.deceleration ) { + move.stage = DECELERATION_STAGE; + } else { + move.stage = FINISHED_STAGE; + } + break; + } + case DECELERATION_STAGE: { + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, move.deceleration, org, move.dir, vec3_origin ); + move.stage = FINISHED_STAGE; + break; + } + case FINISHED_STAGE: { + if ( g_debugMover.GetBool() ) { + gameLocal.Printf( "%d: '%s' move done\n", gameLocal.time, name.c_str() ); + } + DoneMoving(); + break; + } + } +} + +/* +================ +idMover::BeginMove +================ +*/ +void idMover::BeginMove( idThread *thread ) { + moveStage_t stage; + idVec3 org; + float dist; + float acceldist; + int totalacceltime; + int at; + int dt; + + lastCommand = MOVER_MOVING; + move_thread = 0; + + physicsObj.GetLocalOrigin( org ); + + move_delta = dest_position - org; + if ( move_delta.Compare( vec3_zero ) ) { + DoneMoving(); + return; + } + + // scale times up to whole physics frames + at = idPhysics::SnapTimeToPhysicsFrame( acceltime ); + move_time += at - acceltime; + acceltime = at; + dt = idPhysics::SnapTimeToPhysicsFrame( deceltime ); + move_time += dt - deceltime; + deceltime = dt; + + // if we're moving at a specific speed, we need to calculate the move time + if ( move_speed ) { + dist = move_delta.Length(); + + totalacceltime = acceltime + deceltime; + + // calculate the distance we'll move during acceleration and deceleration + acceldist = totalacceltime * 0.5f * 0.001f * move_speed; + if ( acceldist >= dist ) { + // going too slow for this distance to move at a constant speed + move_time = totalacceltime; + } else { + // calculate move time taking acceleration into account + move_time = static_cast(totalacceltime + 1000.0f * ( dist - acceldist ) / move_speed); + } + } + + // scale time up to a whole physics frames + move_time = idPhysics::SnapTimeToPhysicsFrame( move_time ); + + if ( acceltime ) { + stage = ACCELERATION_STAGE; + } else if ( move_time <= deceltime ) { + stage = DECELERATION_STAGE; + } else { + stage = LINEAR_STAGE; + } + + at = acceltime; + dt = deceltime; + + if ( at + dt > move_time ) { + // there's no real correct way to handle this, so we just scale + // the times to fit into the move time in the same proportions + at = idPhysics::SnapTimeToPhysicsFrame( at * move_time / ( at + dt ) ); + dt = move_time - at; + } + + move_delta = move_delta * ( 1000.0f / ( (float) move_time - ( at + dt ) * 0.5f ) ); + + move.stage = stage; + move.acceleration = at; + move.movetime = move_time - at - dt; + move.deceleration = dt; + move.dir = move_delta; + + ProcessEvent( &EV_ReachedPos ); +} + +/*********************************************************************** + + Rotation control functions + +***********************************************************************/ + +/* +================ +idMover::Event_StopRotating +================ +*/ +void idMover::Event_StopRotating( void ) { + physicsObj.GetLocalAngles( dest_angles ); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); + DoneRotating(); +} + +/* +================ +idMover::DoneRotating +================ +*/ +void idMover::DoneRotating( void ) { + lastCommand = MOVER_NONE; + idThread::ObjectMoveDone( rotate_thread, this ); + rotate_thread = 0; + + StopSound( SND_CHANNEL_BODY, false ); +} + +/* +================ +idMover::UpdateRotationSound +================ +*/ +void idMover::UpdateRotationSound( moveStage_t stage ) { + switch( stage ) { + case ACCELERATION_STAGE: { + StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + break; + } + case LINEAR_STAGE: { + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + break; + } + case DECELERATION_STAGE: { + StopSound( SND_CHANNEL_BODY, false ); + StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); + break; + } + case FINISHED_STAGE: { + StopSound( SND_CHANNEL_BODY, false ); + break; + } + } +} + +/* +================ +idMover::Event_UpdateRotation +================ +*/ +void idMover::Event_UpdateRotation( void ) { + idAngles ang; + + physicsObj.GetLocalAngles( ang ); + + UpdateRotationSound( rot.stage ); + + switch( rot.stage ) { + case ACCELERATION_STAGE: { + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, rot.acceleration, ang, rot.rot, ang_zero ); + if ( rot.movetime > 0 ) { + rot.stage = LINEAR_STAGE; + } else if ( rot.deceleration > 0 ) { + rot.stage = DECELERATION_STAGE; + } else { + rot.stage = FINISHED_STAGE; + } + break; + } + case LINEAR_STAGE: { + if ( !stopRotation && !rot.deceleration ) { + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, rot.movetime, ang, rot.rot, ang_zero ); + } else { + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, rot.movetime, ang, rot.rot, ang_zero ); + } + + if ( rot.deceleration ) { + rot.stage = DECELERATION_STAGE; + } else { + rot.stage = FINISHED_STAGE; + } + break; + } + case DECELERATION_STAGE: { + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, rot.deceleration, ang, rot.rot, ang_zero ); + rot.stage = FINISHED_STAGE; + break; + } + case FINISHED_STAGE: { + lastCommand = MOVER_NONE; + if ( stopRotation ) { + // set our final angles so that we get rid of any numerical inaccuracy + dest_angles.Normalize360(); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); + stopRotation = false; + } else if ( physicsObj.GetAngularExtrapolationType() == EXTRAPOLATION_ACCELLINEAR ) { + // keep our angular velocity constant + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, rot.rot, ang_zero ); + } + + if ( g_debugMover.GetBool() ) { + gameLocal.Printf( "%d: '%s' rotation done\n", gameLocal.time, name.c_str() ); + } + + DoneRotating(); + break; + } + } +} + +float idMover::GetMoveTimeFraction() +{ + return 1.0f; +} + +/* +================ +idMover::BeginRotation +================ +*/ +void idMover::BeginRotation( idThread *thread, bool stopwhendone ) { + moveStage_t stage; + idAngles ang; + int at; + int dt; + + lastCommand = MOVER_ROTATING; + rotate_thread = 0; + + int moveTime = move_time; + + // rotation always uses moveTime so that if a move was started before the rotation, + // the rotation will take the same amount of time as the move. If no move has been + // started and no time is set, the rotation takes 1 second. + if ( !moveTime ) { + moveTime = 1; + } + + physicsObj.GetLocalAngles( ang ); + angle_delta = dest_angles - ang; + if ( angle_delta.Compare(ang_zero, VECTOR_EPSILON) ) { + // set our final angles so that we get rid of any numerical inaccuracy + dest_angles.Normalize360(); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); + stopRotation = false; + DoneRotating(); + return; + } + + // greebo: Calculate the moveTime fraction according to the current rotation state + // this is overridden by BinaryFrobMovers to achieve a flexible rotation move time. + float moveTimeFraction = GetMoveTimeFraction(); + + moveTime = static_cast(moveTime*moveTimeFraction); + + // scale times up to whole physics frames + at = idPhysics::SnapTimeToPhysicsFrame( acceltime ); + moveTime += at - acceltime; + acceltime = at; + dt = idPhysics::SnapTimeToPhysicsFrame( deceltime ); + moveTime += dt - deceltime; + deceltime = dt; + moveTime = idPhysics::SnapTimeToPhysicsFrame( moveTime ); + + if ( acceltime ) { + stage = ACCELERATION_STAGE; + } else if ( moveTime <= deceltime ) { + stage = DECELERATION_STAGE; + } else { + stage = LINEAR_STAGE; + } + + at = acceltime; + dt = deceltime; + + if ( at + dt > moveTime ) { + // there's no real correct way to handle this, so we just scale + // the times to fit into the move time in the same proportions + at = idPhysics::SnapTimeToPhysicsFrame( at * moveTime / ( at + dt ) ); + dt = moveTime - at; + } + + angle_delta = angle_delta * ( 1000.0f / ( (float) moveTime - ( at + dt ) * 0.5f ) ); + + stopRotation = stopwhendone || ( dt != 0 ); + + rot.stage = stage; + rot.acceleration = at; + rot.movetime = moveTime - at - dt; + rot.deceleration = dt; + rot.rot = angle_delta; + + ProcessEvent( &EV_ReachedAng ); +} + +void idMover::OnTeamBlocked(idEntity* blockedEntity, idEntity* blockingEntity) +{ + // empty default implementation, overridden by subclasses +} + +/*********************************************************************** + + Script callable routines + +***********************************************************************/ + +/* +=============== +idMover::Event_TeamBlocked +=============== +*/ +void idMover::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { + if ( g_debugMover.GetBool() ) { + gameLocal.Printf( "%d: '%s' stopped due to team member '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockedEntity->name.c_str(), blockingEntity->name.c_str() ); + } + + // greebo: Pass the call to the virtual function + OnTeamBlocked(blockedEntity, blockingEntity); +} + +/* +=============== +idMover::Event_PartBlocked +=============== +*/ +void idMover::Event_PartBlocked( idEntity *blockingEntity ) { + if ( damage > 0.0f ) { + blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); + } + if ( g_debugMover.GetBool() ) { + gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockingEntity->name.c_str() ); + } +} + +/* +================ +idMover::Event_SetMoveSpeed +================ +*/ +void idMover::Event_SetMoveSpeed( float speed ) { + if ( speed <= 0 ) { + gameLocal.Error( "Cannot set speed less than or equal to 0." ); + } + + move_speed = speed; + move_time = 0; // move_time is calculated for each move when move_speed is non-0 +} + +/* +================ +idMover::Event_SetMoveTime +================ +*/ +void idMover::Event_SetMoveTime( float time ) { + if ( time <= 0 ) { + gameLocal.Error( "Cannot set time less than or equal to 0." ); + } + + move_speed = 0; + move_time = SEC2MS( time ); +} + +/* +================ +idMover::Event_SetAccellerationTime +================ +*/ +void idMover::Event_SetAccellerationTime( float time ) { + if ( time < 0 ) { + gameLocal.Error( "Cannot set acceleration time less than 0." ); + } + + acceltime = SEC2MS( time ); +} + +/* +================ +idMover::Event_SetDecelerationTime +================ +*/ +void idMover::Event_SetDecelerationTime( float time ) { + if ( time < 0 ) { + gameLocal.Error( "Cannot set deceleration time less than 0." ); + } + + deceltime = SEC2MS( time ); +} + +/* +================ +idMover::Event_MoveTo +================ +*/ +void idMover::Event_MoveTo( idEntity *ent ) { + if ( !ent ) { + gameLocal.Warning( "Entity not found" ); + } + + dest_position = GetLocalCoordinates( ent->GetPhysics()->GetOrigin() ); + BeginMove( idThread::CurrentThread() ); +} + +/* +================ +idMover::MoveToPos +================ +*/ +void idMover::MoveToPos( const idVec3 &pos ) { + dest_position = GetLocalCoordinates( pos ); + BeginMove( NULL ); +} + +/* +================ +idMover::MoveToLocalPos +================ +*/ +void idMover::MoveToLocalPos( const idVec3 &pos ) { + dest_position = pos; + BeginMove( NULL ); +} +/* +================ +idMover::Event_MoveToPos +================ +*/ +void idMover::Event_MoveToPos( idVec3 &pos ) { + MoveToPos( pos ); +} + +/* +================ +idMover::Event_MoveDir +================ +*/ +void idMover::Event_MoveDir( float angle, float distance ) { + idVec3 dir; + idVec3 org; + + physicsObj.GetLocalOrigin( org ); + VectorForDir( angle, dir ); + dest_position = org + dir * distance; + + BeginMove( idThread::CurrentThread() ); +} + +/* +================ +idMover::Event_MoveAccelerateTo +================ +*/ +void idMover::Event_MoveAccelerateTo( float speed, float time ) { + float v; + idVec3 org, dir; + int at; + + if ( time < 0 ) { + gameLocal.Error( "idMover::Event_MoveAccelerateTo: cannot set acceleration time less than 0." ); + } + + dir = physicsObj.GetLinearVelocity(); + v = dir.Normalize(); + + // if not moving already + if ( v == 0.0f ) { + gameLocal.Error( "idMover::Event_MoveAccelerateTo: not moving." ); + } + + // if already moving faster than the desired speed + if ( v >= speed ) { + return; + } + + at = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); + + lastCommand = MOVER_MOVING; + + physicsObj.GetLocalOrigin( org ); + + move.stage = ACCELERATION_STAGE; + move.acceleration = at; + move.movetime = 0; + move.deceleration = 0; + + StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, move.acceleration, org, dir * ( speed - v ), dir * v ); +} + +/* +================ +idMover::Event_MoveDecelerateTo +================ +*/ +void idMover::Event_MoveDecelerateTo( float speed, float time ) { + float v; + idVec3 org, dir; + int dt; + + if ( time < 0 ) { + gameLocal.Error( "idMover::Event_MoveDecelerateTo: cannot set deceleration time less than 0." ); + } + + dir = physicsObj.GetLinearVelocity(); + v = dir.Normalize(); + + // if not moving already + if ( v == 0.0f ) { + gameLocal.Error( "idMover::Event_MoveDecelerateTo: not moving." ); + } + + // if already moving slower than the desired speed + if ( v <= speed ) { + return; + } + + dt = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); + + lastCommand = MOVER_MOVING; + + physicsObj.GetLocalOrigin( org ); + + move.stage = DECELERATION_STAGE; + move.acceleration = 0; + move.movetime = 0; + move.deceleration = dt; + + StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); + StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, move.deceleration, org, dir * ( v - speed ), dir * speed ); +} + +/* +================ +idMover::Event_RotateDownTo +================ +*/ +void idMover::Event_RotateDownTo( int axis, float angle ) { + idAngles ang; + + if ( ( axis < 0 ) || ( axis > 2 ) ) { + gameLocal.Error( "Invalid axis" ); + } + + physicsObj.GetLocalAngles( ang ); + + dest_angles[ axis ] = angle; + if ( dest_angles[ axis ] > ang[ axis ] ) { + dest_angles[ axis ] -= 360; + } + + BeginRotation( idThread::CurrentThread(), true ); +} + +/* +================ +idMover::Event_RotateUpTo +================ +*/ +void idMover::Event_RotateUpTo( int axis, float angle ) { + idAngles ang; + + if ( ( axis < 0 ) || ( axis > 2 ) ) { + gameLocal.Error( "Invalid axis" ); + } + + physicsObj.GetLocalAngles( ang ); + + dest_angles[ axis ] = angle; + if ( dest_angles[ axis ] < ang[ axis ] ) { + dest_angles[ axis ] += 360; + } + + BeginRotation( idThread::CurrentThread(), true ); +} + +/* +================ +idMover::Event_RotateTo +================ +*/ +void idMover::Event_RotateTo( idAngles &angles ) { + dest_angles = angles; + BeginRotation( idThread::CurrentThread(), true ); +} + +/* +================ +idMover::Event_Rotate +================ +*/ +void idMover::Event_Rotate( idAngles &angles ) { + if ( rotate_thread ) { + DoneRotating(); + } + + dest_angles = physicsObj.GetLocalAngles() + angles * ( move_time - ( acceltime + deceltime ) / 2 ) * 0.001f; + + BeginRotation( idThread::CurrentThread(), false ); +} + +/* +================ +idMover::Event_RotateOnce +================ +*/ +void idMover::Event_RotateOnce( idAngles &angles ) { + if ( rotate_thread ) { + DoneRotating(); + } + + dest_angles = physicsObj.GetLocalAngles() + angles; + + BeginRotation( idThread::CurrentThread(), true ); +} + +/* +================ +idMover::Event_Bob +================ +*/ +void idMover::Event_Bob( float speed, float phase, idVec3 &depth ) { + idVec3 org; + + physicsObj.GetLocalOrigin( org ); + physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(speed * 1000 * phase), static_cast(speed * 500), org, depth * 2.0f, vec3_origin ); +} + +/* +================ +idMover::Event_Sway +================ +*/ +void idMover::Event_Sway( float speed, float phase, idAngles &depth ) { + idAngles ang, angSpeed; + float duration; + + physicsObj.GetLocalAngles( ang ); + assert ( speed > 0.0f ); + duration = idMath::Sqrt( depth[0] * depth[0] + depth[1] * depth[1] + depth[2] * depth[2] ) / speed; + angSpeed = depth / ( duration * idMath::SQRT_1OVER2 ); + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(duration * 1000.0f * phase), static_cast(duration * 1000.0f), ang, angSpeed, ang_zero ); +} + +/* +================ +idMover::Event_OpenPortal + +Sets the portal associtated with this mover to be open +================ +*/ +void idMover::Event_OpenPortal( void ) +{ + // angua: call the virtual function + OpenPortal(); +} + +/* +================ +idMover::Event_ClosePortal + +Sets the portal associtated with this mover to be closed +================ +*/ +void idMover::Event_ClosePortal( void ) +{ + // angua: call the virtual function + ClosePortal(); +} + + +/* +================ +idMover::OpenPortal + +Sets the portal associtated with this mover to be open +================ +*/ +void idMover::OpenPortal() { + if ( areaPortal ) { + SetPortalState( true ); + } +} + +/* +================ +idMover::ClosePortal + +Sets the portal associtated with this mover to be closed +================ +*/ +void idMover::ClosePortal() { + if ( areaPortal ) { + SetPortalState( false ); + } +} + + + + +/* +================ +idMover::Event_SetAccelSound +================ +*/ +void idMover::Event_SetAccelSound( const char *sound ) { +// refSound.SetSound( "accel", sound ); +} + +/* +================ +idMover::Event_SetDecelSound +================ +*/ +void idMover::Event_SetDecelSound( const char *sound ) { +// refSound.SetSound( "decel", sound ); +} + +/* +================ +idMover::Event_SetMoveSound +================ +*/ +void idMover::Event_SetMoveSound( const char *sound ) { +// refSound.SetSound( "move", sound ); +} + +/* +================ +idMover::Event_EnableSplineAngles +================ +*/ +void idMover::Event_EnableSplineAngles( void ) { + useSplineAngles = true; +} + +/* +================ +idMover::Event_DisableSplineAngles +================ +*/ +void idMover::Event_DisableSplineAngles( void ) { + useSplineAngles = false; +} + +/* +================ +idMover::Event_RemoveInitialSplineAngles +================ +*/ +void idMover::Event_RemoveInitialSplineAngles( void ) { + idCurve_Spline *spline; + idAngles ang; + + spline = physicsObj.GetSpline(); + if ( !spline ) { + return; + } + ang = spline->GetCurrentFirstDerivative( 0 ).ToAngles(); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, -ang, ang_zero, ang_zero ); +} + +/* +================ +idMover::Event_StartSpline +================ +*/ +void idMover::Event_StartSpline( idEntity *splineEntity ) { + idCurve_Spline *spline; + + if ( !splineEntity ) { + return; + } + + // Needed for savegames + splineEnt = splineEntity; + + spline = splineEntity->GetSpline(); + if ( !spline ) { + return; + } + + lastCommand = MOVER_SPLINE; + move_thread = 0; + + if ( acceltime + deceltime > move_time ) { + acceltime = move_time / 2; + deceltime = move_time - acceltime; + } + move.stage = FINISHED_STAGE; + move.acceleration = acceltime; + move.movetime = move_time; + move.deceleration = deceltime; + + spline->MakeUniform( move_time ); + spline->ShiftTime( gameLocal.time - spline->GetTime( 0 ) ); + + physicsObj.SetSpline( spline, move.acceleration, move.deceleration, useSplineAngles ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); +} + +/* +================ +idMover::Event_StopSpline +================ +*/ +void idMover::Event_StopSpline( void ) { + physicsObj.SetSpline( NULL, 0, 0, useSplineAngles ); + splineEnt = NULL; +} + +/* +================ +idMover::Event_Activate +================ +*/ +void idMover::Event_Activate( idEntity *activator ) { + Show(); + Event_StartSpline( this ); +} + +/* +================ +idMover::Event_IsMoving +================ +*/ +void idMover::Event_IsMoving( void ) { + if ( physicsObj.GetLinearExtrapolationType() == EXTRAPOLATION_NONE ) { + idThread::ReturnInt( false ); + } else { + idThread::ReturnInt( true ); + } +} + +/* +================ +idMover::Event_IsRotating +================ +*/ +void idMover::Event_IsRotating( void ) { + if ( physicsObj.GetAngularExtrapolationType() == EXTRAPOLATION_NONE ) { + idThread::ReturnInt( false ); + } else { + idThread::ReturnInt( true ); + } +} + +/* +================ +idMover::WriteToSnapshot +================ +*/ +void idMover::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); + msg.WriteBits( move.stage, 3 ); + msg.WriteBits( rot.stage, 3 ); + WriteBindToSnapshot( msg ); + WriteGUIToSnapshot( msg ); +} + +/* +================ +idMover::ReadFromSnapshot +================ +*/ +void idMover::ReadFromSnapshot( const idBitMsgDelta &msg ) { + moveStage_t oldMoveStage = move.stage; + moveStage_t oldRotStage = rot.stage; + + physicsObj.ReadFromSnapshot( msg ); + move.stage = (moveStage_t) msg.ReadBits( 3 ); + rot.stage = (moveStage_t) msg.ReadBits( 3 ); + ReadBindFromSnapshot( msg ); + ReadGUIFromSnapshot( msg ); + + if ( msg.HasChanged() ) { + if ( move.stage != oldMoveStage ) { + UpdateMoveSound( oldMoveStage ); + } + if ( rot.stage != oldRotStage ) { + UpdateRotationSound( oldRotStage ); + } + UpdateVisuals(); + } +} + +/* +================ +idMover::SetPortalState +================ +*/ +void idMover::SetPortalState( bool open ) { + assert( areaPortal ); + gameLocal.SetPortalState( areaPortal, open ? PS_BLOCK_NONE : PS_BLOCK_ALL ); +} + +/* +================ +idMover::IsBlocked +================ +*/ +bool idMover::IsBlocked( void ) +{ + const trace_t* trace = physicsObj.GetBlockingInfo(); + return (trace != NULL); +} + + +/* +=============================================================================== + + idSplinePath, holds a spline path to be used by an idMover + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idSplinePath ) +END_CLASS + +/* +================ +idSplinePath::idSplinePath +================ +*/ +idSplinePath::idSplinePath() { +} + +/* +================ +idSplinePath::Spawn +================ +*/ +void idSplinePath::Spawn( void ) { +} + + +/* +=============================================================================== + +idMover_Binary + +Doors, plats, and buttons are all binary (two position) movers +Pos1 is "at rest", pos2 is "activated" + +=============================================================================== +*/ + +const idEventDef EV_Mover_ReturnToPos1( "", NULL ); +const idEventDef EV_Mover_MatchTeam( "", "dd" ); +const idEventDef EV_Mover_Enable( "enable", NULL ); +const idEventDef EV_Mover_Disable( "disable", NULL ); + +CLASS_DECLARATION( idEntity, idMover_Binary ) + EVENT( EV_FindGuiTargets, idMover_Binary::Event_FindGuiTargets ) + EVENT( EV_Thread_SetCallback, idMover_Binary::Event_SetCallback ) + EVENT( EV_Mover_ReturnToPos1, idMover_Binary::Event_ReturnToPos1 ) + EVENT( EV_Activate, idMover_Binary::Event_Use_BinaryMover ) + EVENT( EV_ReachedPos, idMover_Binary::Event_Reached_BinaryMover ) + EVENT( EV_Mover_MatchTeam, idMover_Binary::Event_MatchActivateTeam ) + EVENT( EV_Mover_Enable, idMover_Binary::Event_Enable ) + EVENT( EV_Mover_Disable, idMover_Binary::Event_Disable ) + EVENT( EV_Mover_OpenPortal, idMover_Binary::Event_OpenPortal ) + EVENT( EV_Mover_ClosePortal, idMover_Binary::Event_ClosePortal ) + EVENT( EV_Mover_InitGuiTargets, idMover_Binary::Event_InitGuiTargets ) +END_CLASS + +/* +================ +idMover_Binary::idMover_Binary() +================ +*/ +idMover_Binary::idMover_Binary() +{ + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); + + pos1.Zero(); + pos2.Zero(); + moverState = MOVER_POS1; + moveMaster = NULL; + activateChain = NULL; + soundPos1 = 0; + sound1to2 = 0; + sound2to1 = 0; + soundPos2 = 0; + soundLoop = 0; + wait = 0.0f; + damage = 0.0f; + duration = 0; + accelTime = 0; + decelTime = 0; + activatedBy = this; + stateStartTime = 0; + team.Clear(); + enabled = false; + move_thread = 0; + updateStatus = 0; + areaPortal = 0; + blocked = false; + fl.networkSync = true; + m_FrobActionScript = "frob_binary_mover"; +} + +/* +================ +idMover_Binary::~idMover_Binary +================ +*/ +idMover_Binary::~idMover_Binary() +{ + idMover_Binary *mover; + + // if this is the mover master + if ( this == moveMaster ) { + // make the next mover in the chain the move master + for ( mover = moveMaster; mover; mover = mover->activateChain ) { + mover->moveMaster = this->activateChain; + } + } + else { + // remove mover from the activate chain + for ( mover = moveMaster; mover; mover = mover->activateChain ) { + if ( mover->activateChain == this ) { + mover->activateChain = this->activateChain; + break; + } + } + } +} + +/* +================ +idMover_Binary::Save +================ +*/ +void idMover_Binary::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteVec3( pos1 ); + savefile->WriteVec3( pos2 ); + savefile->WriteInt( (moverState_t)moverState ); + + savefile->WriteObject( moveMaster ); + savefile->WriteObject( activateChain ); + + savefile->WriteInt( soundPos1 ); + savefile->WriteInt( sound1to2 ); + savefile->WriteInt( sound2to1 ); + savefile->WriteInt( soundPos2 ); + savefile->WriteInt( soundLoop ); + + savefile->WriteFloat( wait ); + savefile->WriteFloat( damage ); + + savefile->WriteInt( duration ); + savefile->WriteInt( accelTime ); + savefile->WriteInt( decelTime ); + + activatedBy.Save( savefile ); + + savefile->WriteInt( stateStartTime ); + savefile->WriteString( team ); + savefile->WriteBool( enabled ); + + savefile->WriteInt( move_thread ); + savefile->WriteInt( updateStatus ); + + savefile->WriteInt( buddies.Num() ); + for ( i = 0; i < buddies.Num(); i++ ) { + savefile->WriteString( buddies[ i ] ); + } + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteInt( areaPortal ); + if ( areaPortal ) { + savefile->WriteInt( gameRenderWorld->GetPortalState( areaPortal ) ); + } + savefile->WriteBool( blocked ); + + savefile->WriteInt( guiTargets.Num() ); + for( i = 0; i < guiTargets.Num(); i++ ) { + guiTargets[ i ].Save( savefile ); + } +} + +/* +================ +idMover_Binary::Restore +================ +*/ +void idMover_Binary::Restore( idRestoreGame *savefile ) { + int i, num, portalState; + idStr temp; + + savefile->ReadVec3( pos1 ); + savefile->ReadVec3( pos2 ); + savefile->ReadInt( (int &)moverState ); + + savefile->ReadObject( reinterpret_cast( moveMaster ) ); + savefile->ReadObject( reinterpret_cast( activateChain ) ); + + savefile->ReadInt( soundPos1 ); + savefile->ReadInt( sound1to2 ); + savefile->ReadInt( sound2to1 ); + savefile->ReadInt( soundPos2 ); + savefile->ReadInt( soundLoop ); + + savefile->ReadFloat( wait ); + savefile->ReadFloat( damage ); + + savefile->ReadInt( duration ); + savefile->ReadInt( accelTime ); + savefile->ReadInt( decelTime ); + + activatedBy.Restore( savefile ); + + savefile->ReadInt( stateStartTime ); + + savefile->ReadString( team ); + savefile->ReadBool( enabled ); + + savefile->ReadInt( move_thread ); + savefile->ReadInt( updateStatus ); + + savefile->ReadInt( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadString( temp ); + buddies.Append( temp ); + } + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadInt( areaPortal ); + if ( areaPortal ) { + savefile->ReadInt( portalState ); + gameLocal.SetPortalState( areaPortal, portalState ); + } + savefile->ReadBool( blocked ); + + guiTargets.Clear(); + savefile->ReadInt( num ); + guiTargets.SetNum( num ); + for( i = 0; i < num; i++ ) { + guiTargets[ i ].Restore( savefile ); + } +} + +/* +================ +idMover_Binary::Spawn + +Base class for all movers. + +"wait" wait before returning (3 default, -1 = never return) +"speed" movement speed +================ +*/ +void idMover_Binary::Spawn( void ) +{ + idEntity *ent; + const char *temp; + + move_thread = 0; + enabled = true; + areaPortal = 0; + + activateChain = NULL; + + spawnArgs.GetFloat( "wait", "0", wait ); + + spawnArgs.GetInt( "updateStatus", "0", updateStatus ); + + const idKeyValue *kv = spawnArgs.MatchPrefix( "buddy", NULL ); + while( kv ) { + buddies.Append( kv->GetValue() ); + kv = spawnArgs.MatchPrefix( "buddy", kv ); + } + + spawnArgs.GetString( "team", "", &temp ); + team = temp; + + if ( !team.Length() ) { + ent = this; + } else { + // find the first entity spawned on this team (which could be us) + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( idMover_Binary::Type ) && !idStr::Icmp( static_cast(ent)->team.c_str(), temp ) ) { + break; + } + } + if ( !ent ) { + ent = this; + } + } + moveMaster = static_cast(ent); + + // create a physics team for the binary mover parts + if ( ent != this ) { + JoinTeam( ent ); + } + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "solid", "1" ) ) { + physicsObj.SetContents( 0 ); + } + if ( !spawnArgs.GetBool( "nopush" ) ) { + physicsObj.SetPusher( 0 ); + } + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); + physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetAxis().ToAngles(), ang_zero, ang_zero ); + SetPhysics( &physicsObj ); + + if ( moveMaster != this ) { + JoinActivateTeam( moveMaster ); + } + + idBounds soundOrigin; + idMover_Binary *slave; + + soundOrigin.Clear(); + for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + soundOrigin += slave->GetPhysics()->GetAbsBounds(); + } + moveMaster->refSound.origin = soundOrigin.GetCenter(); + + if ( spawnArgs.MatchPrefix( "guiTarget" ) ) { + if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { + PostEventMS( &EV_FindGuiTargets, 0 ); + } else { + // not during spawn, so it's ok to get the targets + FindGuiTargets(); + } + } +} + +/* +=============== +idMover_Binary::GetMovedir + +The editor only specifies a single value for angles (yaw), +but we have special constants to generate an up or down direction. +Angles will be cleared, because it is being used to represent a direction +instead of an orientation. +=============== +*/ +void idMover_Binary::GetMovedir( float angle, idVec3 &movedir ) { + if ( angle == -1 ) { + movedir.Set( 0, 0, 1 ); + } else if ( angle == -2 ) { + movedir.Set( 0, 0, -1 ); + } else { + movedir = idAngles( 0, angle, 0 ).ToForward(); + } +} + +/* +================ +idMover_Binary::Event_SetCallback +================ +*/ +void idMover_Binary::Event_SetCallback( void ) { + if ( ( moverState == MOVER_1TO2 ) || ( moverState == MOVER_2TO1 ) ) { + move_thread = idThread::CurrentThreadNum(); + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/* +=============== +idMover_Binary::UpdateMoverSound +=============== +*/ +void idMover_Binary::UpdateMoverSound( moverState_t state ) { + if ( moveMaster == this ) { + switch( state ) { + case MOVER_POS1: + break; + case MOVER_POS2: + break; + case MOVER_1TO2: + StartSound( "snd_open", SND_CHANNEL_ANY, 0, false, NULL ); + break; + case MOVER_2TO1: + StartSound( "snd_close", SND_CHANNEL_ANY, 0, false, NULL ); + break; + } + } +} + +/* +=============== +idMover_Binary::SetMoverState +=============== +*/ +void idMover_Binary::SetMoverState( moverState_t newstate, int time ) { + idVec3 delta; + + moverState = newstate; + move_thread = 0; + + UpdateMoverSound( newstate ); + + stateStartTime = time; + switch( moverState ) { + case MOVER_POS1: { + Signal( SIG_MOVER_POS1 ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, time, 0, pos1, vec3_origin, vec3_origin ); + break; + } + case MOVER_POS2: { + Signal( SIG_MOVER_POS2 ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, time, 0, pos2, vec3_origin, vec3_origin ); + break; + } + case MOVER_1TO2: { + Signal( SIG_MOVER_1TO2 ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, time, duration, pos1, ( pos2 - pos1 ) * 1000.0f / duration, vec3_origin ); + if ( accelTime != 0 || decelTime != 0 ) { + physicsObj.SetLinearInterpolation( time, accelTime, decelTime, duration, pos1, pos2 ); + } else { + physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 ); + } + break; + } + case MOVER_2TO1: { + Signal( SIG_MOVER_2TO1 ); + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, time, duration, pos2, ( pos1 - pos2 ) * 1000.0f / duration, vec3_origin ); + if ( accelTime != 0 || decelTime != 0 ) { + physicsObj.SetLinearInterpolation( time, accelTime, decelTime, duration, pos2, pos1 ); + } else { + physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 ); + } + break; + } + } +} + +/* +================ +idMover_Binary::MatchActivateTeam + +All entities in a mover team will move from pos1 to pos2 +in the same amount of time +================ +*/ +void idMover_Binary::MatchActivateTeam( moverState_t newstate, int time ) { + idMover_Binary *slave; + + for ( slave = this; slave != NULL; slave = slave->activateChain ) { + slave->SetMoverState( newstate, time ); + } +} + +/* +================ +idMover_Binary::Enable +================ +*/ +void idMover_Binary::Enable( bool b ) { + enabled = b; +} + +/* +================ +idMover_Binary::Event_MatchActivateTeam +================ +*/ +void idMover_Binary::Event_MatchActivateTeam( moverState_t newstate, int time ) { + MatchActivateTeam( newstate, time ); +} + +/* +================ +idMover_Binary::BindTeam + +All entities in a mover team will be bound +================ +*/ +void idMover_Binary::BindTeam( idEntity *bindTo ) { + idMover_Binary *slave; + + for ( slave = this; slave != NULL; slave = slave->activateChain ) { + slave->Bind( bindTo, true ); + } +} + +/* +================ +idMover_Binary::JoinActivateTeam + +Set all entities in a mover team to be enabled +================ +*/ +void idMover_Binary::JoinActivateTeam( idMover_Binary *master ) { + this->activateChain = master->activateChain; + master->activateChain = this; +} + +/* +================ +idMover_Binary::Event_Enable + +Set all entities in a mover team to be enabled +================ +*/ +void idMover_Binary::Event_Enable( void ) { + idMover_Binary *slave; + + for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + slave->Enable( false ); + } +} + +/* +================ +idMover_Binary::Event_Disable + +Set all entities in a mover team to be disabled +================ +*/ +void idMover_Binary::Event_Disable( void ) { + idMover_Binary *slave; + + for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + slave->Enable( false ); + } +} + +/* +================ +idMover_Binary::Event_OpenPortal + +Sets the portal associtated with this mover to be open +================ +*/ +void idMover_Binary::Event_OpenPortal( void ) { + idMover_Binary *slave; + + for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + if ( slave->areaPortal ) { + slave->SetPortalState( true ); + } + } +} + +/* +================ +idMover_Binary::Event_ClosePortal + +Sets the portal associtated with this mover to be closed +================ +*/ +void idMover_Binary::Event_ClosePortal( void ) { + idMover_Binary *slave; + + for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + if ( !slave->IsHidden() ) { + if ( slave->areaPortal ) { + slave->SetPortalState( false ); + } + } + } +} + +/* +================ +idMover_Binary::Event_ReturnToPos1 +================ +*/ +void idMover_Binary::Event_ReturnToPos1( void ) { + MatchActivateTeam( MOVER_2TO1, gameLocal.time ); +} + +/* +================ +idMover_Binary::Event_Reached_BinaryMover +================ +*/ +void idMover_Binary::Event_Reached_BinaryMover( void ) { + + if ( moverState == MOVER_1TO2 ) { + // reached pos2 + idThread::ObjectMoveDone( move_thread, this ); + move_thread = 0; + + if ( moveMaster == this ) { + StartSound( "snd_opened", SND_CHANNEL_ANY, 0, false, NULL ); + } + + SetMoverState( MOVER_POS2, gameLocal.time ); + + SetGuiStates( guiBinaryMoverStates[MOVER_POS2] ); + + UpdateBuddies( 1 ); + + if ( enabled && wait >= 0 && !spawnArgs.GetBool( "toggle" ) ) { + // return to pos1 after a delay + PostEventSec( &EV_Mover_ReturnToPos1, wait ); + } + + // fire targets + ActivateTargets( moveMaster->GetActivator() ); + + + SetBlocked(false); + + } else if ( moverState == MOVER_2TO1 ) { + // reached pos1 + idThread::ObjectMoveDone( move_thread, this ); + move_thread = 0; + + SetMoverState( MOVER_POS1, gameLocal.time ); + + SetGuiStates( guiBinaryMoverStates[MOVER_POS1] ); + + UpdateBuddies( 0 ); + + // close areaportals + if ( moveMaster == this ) { + ProcessEvent( &EV_Mover_ClosePortal ); + } + + if ( enabled && wait >= 0 && spawnArgs.GetBool( "continuous" ) ) { + PostEventSec( &EV_Activate, wait, this ); + } + + + SetBlocked(false); + + } else { + gameLocal.Error( "Event_Reached_BinaryMover: bad moverState" ); + } +} + +/* +================ +idMover_Binary::GotoPosition1 +================ +*/ +void idMover_Binary::GotoPosition1( void ) { + idMover_Binary *slave; + int partial; + + // only the master should control this + if ( moveMaster != this ) { + moveMaster->GotoPosition1(); + return; + } + + SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] ); + + if ( ( moverState == MOVER_POS1 ) || ( moverState == MOVER_2TO1 ) ) { + // already there, or on the way + return; + } + + if ( moverState == MOVER_POS2 ) { + for ( slave = this; slave != NULL; slave = slave->activateChain ) { + slave->CancelEvents( &EV_Mover_ReturnToPos1 ); + } + if ( !spawnArgs.GetBool( "toggle" ) ) { + ProcessEvent( &EV_Mover_ReturnToPos1 ); + } + return; + } + + // only partway up before reversing + if ( moverState == MOVER_1TO2 ) { + // use the physics times because this might be executed during the physics simulation + partial = physicsObj.GetLinearEndTime() - physicsObj.GetTime(); + assert( partial >= 0 ); + if ( partial < 0 ) { + partial = 0; + } + MatchActivateTeam( MOVER_2TO1, physicsObj.GetTime() - partial ); + // if already at at position 1 (partial == duration) execute the reached event + if ( partial >= duration ) { + Event_Reached_BinaryMover(); + } + } +} + +/* +================ +idMover_Binary::GotoPosition2 +================ +*/ +void idMover_Binary::GotoPosition2( void ) { + int partial; + + // only the master should control this + if ( moveMaster != this ) { + moveMaster->GotoPosition2(); + return; + } + + SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] ); + + if ( ( moverState == MOVER_POS2 ) || ( moverState == MOVER_1TO2 ) ) { + // already there, or on the way + return; + } + + if ( moverState == MOVER_POS1 ) { + MatchActivateTeam( MOVER_1TO2, gameLocal.time ); + + // open areaportal + ProcessEvent( &EV_Mover_OpenPortal ); + return; + } + + + // only partway up before reversing + if ( moverState == MOVER_2TO1 ) { + // use the physics times because this might be executed during the physics simulation + partial = physicsObj.GetLinearEndTime() - physicsObj.GetTime(); + assert( partial >= 0 ); + if ( partial < 0 ) { + partial = 0; + } + MatchActivateTeam( MOVER_1TO2, physicsObj.GetTime() - partial ); + // if already at at position 2 (partial == duration) execute the reached event + if ( partial >= duration ) { + Event_Reached_BinaryMover(); + } + } +} + +/* +================ +idMover_Binary::UpdateBuddies +================ +*/ +void idMover_Binary::UpdateBuddies( int val ) { + int i, c; + + if ( updateStatus == 2 ) { + c = buddies.Num(); + for ( i = 0; i < c; i++ ) { + idEntity *buddy = gameLocal.FindEntity( buddies[i] ); + if ( buddy ) { + buddy->SetShaderParm( SHADERPARM_MODE, val ); + buddy->UpdateVisuals(); + } + } + } +} + +/* +================ +idMover_Binary::SetGuiStates +================ +*/ +void idMover_Binary::SetGuiStates( const char *state ) { + if ( guiTargets.Num() ) { + SetGuiState( "movestate", state ); + } + + idMover_Binary *mb = activateChain; + while( mb ) { + if ( mb->guiTargets.Num() ) { + mb->SetGuiState( "movestate", state ); + } + mb = mb->activateChain; + } +} + +/* +================ +idMover_Binary::Use_BinaryMover +================ +*/ +void idMover_Binary::Use_BinaryMover( idEntity *activator ) { + // only the master should be used + if ( moveMaster != this ) { + moveMaster->Use_BinaryMover( activator ); + return; + } + + if ( !enabled ) { + return; + } + + activatedBy = activator; + + if ( moverState == MOVER_POS1 ) { + // FIXME: start moving USERCMD_MSEC later, because if this was player + // triggered, gameLocal.time hasn't been advanced yet + MatchActivateTeam( MOVER_1TO2, gameLocal.time + USERCMD_MSEC ); + + SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] ); + // open areaportal + ProcessEvent( &EV_Mover_OpenPortal ); + return; + } + + // if all the way up, just delay before coming down + if ( moverState == MOVER_POS2 ) { + idMover_Binary *slave; + + if ( wait == -1 ) { + return; + } + + SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] ); + + for ( slave = this; slave != NULL; slave = slave->activateChain ) { + slave->CancelEvents( &EV_Mover_ReturnToPos1 ); + slave->PostEventSec( &EV_Mover_ReturnToPos1, spawnArgs.GetBool( "toggle" ) ? 0 : wait ); + } + return; + } + + // only partway down before reversing + if ( moverState == MOVER_2TO1 ) { + GotoPosition2(); + return; + } + + // only partway up before reversing + if ( moverState == MOVER_1TO2 ) { + GotoPosition1(); + return; + } +} + +/* +================ +idMover_Binary::Event_Use_BinaryMover +================ +*/ +void idMover_Binary::Event_Use_BinaryMover( idEntity *activator ) { + Use_BinaryMover( activator ); +} + +/* +================ +idMover_Binary::PreBind +================ +*/ +void idMover_Binary::PreBind( void ) { + pos1 = GetWorldCoordinates( pos1 ); + pos2 = GetWorldCoordinates( pos2 ); +} + +/* +================ +idMover_Binary::PostBind +================ +*/ +void idMover_Binary::PostBind( void ) { + pos1 = GetLocalCoordinates( pos1 ); + pos2 = GetLocalCoordinates( pos2 ); +} + +/* +================ +idMover_Binary::FindGuiTargets +================ +*/ +void idMover_Binary::FindGuiTargets( void ) { + gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" ); +} + +/* +============================== +idMover_Binary::SetGuiState + +key/val will be set to any renderEntity->gui's on the list +============================== +*/ +void idMover_Binary::SetGuiState( const char *key, const char *val ) const { + int i; + + for( i = 0; i < guiTargets.Num(); i++ ) { + idEntity *ent = guiTargets[ i ].GetEntity(); + if ( ent ) { + for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { + if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) { + ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); + ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time, true ); + } + } + ent->UpdateVisuals(); + } + } +} + +/* +================ +idMover_Binary::Event_InitGuiTargets +================ +*/ +void idMover_Binary::Event_FindGuiTargets( void ) { + FindGuiTargets(); +} + +/* +================ +idMover_Binary::Event_InitGuiTargets +================ +*/ +void idMover_Binary::Event_InitGuiTargets( void ) { + if ( guiTargets.Num() ) { + SetGuiState( "movestate", guiBinaryMoverStates[MOVER_POS1] ); + } +} + +/* +================ +idMover_Binary::InitSpeed + +pos1, pos2, and speed are passed in so the movement delta can be calculated +================ +*/ +void idMover_Binary::InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime ) { + idVec3 move; + float distance; + float speed; + + pos1 = mpos1; + pos2 = mpos2; + + accelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( maccelTime ) ); + decelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mdecelTime ) ); + + speed = mspeed ? mspeed : 100; + + // calculate time to reach second position from speed + move = pos2 - pos1; + distance = move.Length(); + duration = idPhysics::SnapTimeToPhysicsFrame( static_cast(distance * 1000 / speed) ); + if ( duration <= 0 ) { + duration = 1; + } + + moverState = MOVER_POS1; + + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, pos1, vec3_origin, vec3_origin ); + physicsObj.SetLinearInterpolation( 0, 0, 0, 0, vec3_origin, vec3_origin ); + SetOrigin( pos1 ); + + PostEventMS( &EV_Mover_InitGuiTargets, 0 ); +} + +/* +================ +idMover_Binary::InitTime + +pos1, pos2, and time are passed in so the movement delta can be calculated +================ +*/ +void idMover_Binary::InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime ) { + + pos1 = mpos1; + pos2 = mpos2; + + accelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( maccelTime ) ); + decelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mdecelTime ) ); + + duration = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mtime ) ); + if ( duration <= 0 ) { + duration = 1; + } + + moverState = MOVER_POS1; + + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, pos1, vec3_origin, vec3_origin ); + physicsObj.SetLinearInterpolation( 0, 0, 0, 0, vec3_origin, vec3_origin ); + SetOrigin( pos1 ); + + PostEventMS( &EV_Mover_InitGuiTargets, 0 ); +} + +/* +================ +idMover_Binary::SetBlocked +================ +*/ +void idMover_Binary::SetBlocked( bool b ) { + for ( idMover_Binary *slave = moveMaster; slave != NULL; slave = slave->activateChain ) { + slave->blocked = b; + if ( b ) { + const idKeyValue *kv = slave->spawnArgs.MatchPrefix( "triggerBlocked" ); + while( kv ) { + idEntity *ent = gameLocal.FindEntity( kv->GetValue() ); + if ( ent ) { + ent->PostEventMS( &EV_Activate, 0, moveMaster->GetActivator() ); + } + kv = slave->spawnArgs.MatchPrefix( "triggerBlocked", kv ); + } + } + } +} + +/* +================ +idMover_Binary::IsBlocked +================ +*/ +bool idMover_Binary::IsBlocked( void ) { + return blocked; +} + +/* +================ +idMover_Binary::GetActivator +================ +*/ +idEntity *idMover_Binary::GetActivator( void ) const { + return activatedBy.GetEntity(); +} + +/* +================ +idMover_Binary::WriteToSnapshot +================ +*/ +void idMover_Binary::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); + msg.WriteBits( moverState, 3 ); + WriteBindToSnapshot( msg ); +} + +/* +================ +idMover_Binary::ReadFromSnapshot +================ +*/ +void idMover_Binary::ReadFromSnapshot( const idBitMsgDelta &msg ) { + moverState_t oldMoverState = moverState; + + physicsObj.ReadFromSnapshot( msg ); + moverState = (moverState_t) msg.ReadBits( 3 ); + ReadBindFromSnapshot( msg ); + + if ( msg.HasChanged() ) { + if ( moverState != oldMoverState ) { + UpdateMoverSound( moverState ); + } + UpdateVisuals(); + } +} + +/* +================ +idMover_Binary::SetPortalState +================ +*/ +void idMover_Binary::SetPortalState( bool open ) { + assert( areaPortal ); + gameLocal.SetPortalState( areaPortal, open ? PS_BLOCK_NONE : PS_BLOCK_ALL ); +} + +/* +=============================================================================== + +idPlat + +=============================================================================== +*/ + +CLASS_DECLARATION( idMover_Binary, idPlat ) + EVENT( EV_Touch, idPlat::Event_Touch ) + EVENT( EV_TeamBlocked, idPlat::Event_TeamBlocked ) + EVENT( EV_PartBlocked, idPlat::Event_PartBlocked ) +END_CLASS + +/* +=============== +idPlat::idPlat +=============== +*/ +idPlat::idPlat( void ) { + trigger = NULL; + localTriggerOrigin.Zero(); + localTriggerAxis.Identity(); +} + +/* +=============== +idPlat::~idPlat +=============== +*/ +idPlat::~idPlat( void ) { + if ( trigger ) { + delete trigger; + } +} + +/* +=============== +idPlat::Save +=============== +*/ +void idPlat::Save( idSaveGame *savefile ) const { + savefile->WriteClipModel( trigger ); + savefile->WriteVec3( localTriggerOrigin ); + savefile->WriteMat3( localTriggerAxis ); +} + +/* +=============== +idPlat::Restore +=============== +*/ +void idPlat::Restore( idRestoreGame *savefile ) { + savefile->ReadClipModel( trigger ); + savefile->ReadVec3( localTriggerOrigin ); + savefile->ReadMat3( localTriggerAxis ); +} + +/* +=============== +idPlat::Spawn +=============== +*/ +void idPlat::Spawn( void ) +{ + float lip; + float height; + float time; + float speed; + float accel; + float decel; + bool noTouch; + + spawnArgs.GetFloat( "speed", "100", speed ); + spawnArgs.GetFloat( "damage", "0", damage ); + spawnArgs.GetFloat( "wait", "1", wait ); + spawnArgs.GetFloat( "lip", "8", lip ); + spawnArgs.GetFloat( "accel_time", "0.25", accel ); + spawnArgs.GetFloat( "decel_time", "0.25", decel ); + + // create second position + if ( !spawnArgs.GetFloat( "height", "0", height ) ) { + height = ( GetPhysics()->GetBounds()[1][2] - GetPhysics()->GetBounds()[0][2] ) - lip; + } + + spawnArgs.GetBool( "no_touch", "0", noTouch ); + + // pos1 is the rest (bottom) position, pos2 is the top + pos2 = GetPhysics()->GetOrigin(); + pos1 = pos2; + pos1[2] -= height; + + if ( spawnArgs.GetFloat( "time", "1", time ) ) { + InitTime( pos1, pos2, time, accel, decel ); + } else { + InitSpeed( pos1, pos2, speed, accel, decel ); + } + + SetMoverState( MOVER_POS1, gameLocal.time ); + UpdateVisuals(); + + // spawn the trigger if one hasn't been custom made + if ( !noTouch ) { + // spawn trigger + SpawnPlatTrigger( pos1 ); + } +} + +/* +================ +idPlat::Think +================ +*/ +void idPlat::Think( void ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + idMover_Binary::Think(); + + if ( thinkFlags & TH_PHYSICS ) { + // update trigger position + if ( GetMasterPosition( masterOrigin, masterAxis ) ) { + if ( trigger ) { + trigger->Link( gameLocal.clip, this, 0, masterOrigin + localTriggerOrigin * masterAxis, localTriggerAxis * masterAxis ); + } + } + } +} + +/* +================ +idPlat::PreBind +================ +*/ +void idPlat::PreBind( void ) { + idMover_Binary::PreBind(); +} + +/* +================ +idPlat::PostBind +================ +*/ +void idPlat::PostBind( void ) { + idMover_Binary::PostBind(); + GetLocalTriggerPosition( trigger ); +} + +/* +================ +idPlat::GetLocalTriggerPosition +================ +*/ +void idPlat::GetLocalTriggerPosition( const idClipModel *trigger ) { + idVec3 origin; + idMat3 axis; + + if ( !trigger ) { + return; + } + + GetMasterPosition( origin, axis ); + localTriggerOrigin = ( trigger->GetOrigin() - origin ) * axis.Transpose(); + localTriggerAxis = trigger->GetAxis() * axis.Transpose(); +} + +/* +============== +idPlat::SpawnPlatTrigger +=============== +*/ +void idPlat::SpawnPlatTrigger( idVec3 &pos ) { + idBounds bounds; + idVec3 tmin; + idVec3 tmax; + + // the middle trigger will be a thin trigger just + // above the starting position + + bounds = GetPhysics()->GetBounds(); + + tmin[0] = bounds[0][0] + 33; + tmin[1] = bounds[0][1] + 33; + tmin[2] = bounds[0][2]; + + tmax[0] = bounds[1][0] - 33; + tmax[1] = bounds[1][1] - 33; + tmax[2] = bounds[1][2] + 8; + + if ( tmax[0] <= tmin[0] ) { + tmin[0] = ( bounds[0][0] + bounds[1][0] ) * 0.5f; + tmax[0] = tmin[0] + 1; + } + if ( tmax[1] <= tmin[1] ) { + tmin[1] = ( bounds[0][1] + bounds[1][1] ) * 0.5f; + tmax[1] = tmin[1] + 1; + } + + trigger = new idClipModel( idTraceModel( idBounds( tmin, tmax ) ) ); + trigger->Link( gameLocal.clip, this, 255, GetPhysics()->GetOrigin(), mat3_identity ); + trigger->SetContents( CONTENTS_TRIGGER ); +} + +/* +============== +idPlat::Event_Touch +=============== +*/ +void idPlat::Event_Touch( idEntity *other, trace_t *trace ) { + if ( !other->IsType( idPlayer::Type ) ) { + return; + } + + if ( ( GetMoverState() == MOVER_POS1 ) && trigger && ( trace->c.id == trigger->GetId() ) && ( other->health > 0 ) ) { + Use_BinaryMover( other ); + } +} + +/* +================ +idPlat::Event_TeamBlocked +================ +*/ +void idPlat::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { + // reverse direction + Use_BinaryMover( activatedBy.GetEntity() ); +} + +/* +=============== +idPlat::Event_PartBlocked +=============== +*/ +void idPlat::Event_PartBlocked( idEntity *blockingEntity ) { + if ( damage > 0.0f ) { + blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); + } +} + + +/* +=============================================================================== + +idMover_Periodic + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idMover_Periodic ) + EVENT( EV_TeamBlocked, idMover_Periodic::Event_TeamBlocked ) + EVENT( EV_PartBlocked, idMover_Periodic::Event_PartBlocked ) +END_CLASS + +/* +=============== +idMover_Periodic::idMover_Periodic +=============== +*/ +idMover_Periodic::idMover_Periodic( void ) { + damage = 0.0f; + fl.neverDormant = false; +} + +/* +=============== +idMover_Periodic::Spawn +=============== +*/ +void idMover_Periodic::Spawn( void ) { + spawnArgs.GetFloat( "damage", "0", damage ); + if ( !spawnArgs.GetBool( "solid", "1" ) ) { + GetPhysics()->SetContents( 0 ); + } +} + +/* +=============== +idMover_Periodic::Save +=============== +*/ +void idMover_Periodic::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( damage ); + savefile->WriteStaticObject( physicsObj ); +} + +/* +=============== +idMover_Periodic::Restore +=============== +*/ +void idMover_Periodic::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( damage ); + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); +} + +/* +================ +idMover_Periodic::Think +================ +*/ +void idMover_Periodic::Think( void ) { + // if we are completely closed off from the player, don't do anything at all + if ( CheckDormant() ) { + return; + } + + RunPhysics(); + Present(); +} + +/* +=============== +idMover_Periodic::Event_TeamBlocked +=============== +*/ +void idMover_Periodic::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { +} + +/* +=============== +idMover_Periodic::Event_PartBlocked +=============== +*/ +void idMover_Periodic::Event_PartBlocked( idEntity *blockingEntity ) { + if ( damage > 0.0f ) { + blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); + } +} + +/* +================ +idMover_Periodic::WriteToSnapshot +================ +*/ +void idMover_Periodic::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); +} + +/* +================ +idMover_Periodic::ReadFromSnapshot +================ +*/ +void idMover_Periodic::ReadFromSnapshot( const idBitMsgDelta &msg ) { + physicsObj.ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + + +/* +=============================================================================== + +idRotater + +=============================================================================== +*/ + +CLASS_DECLARATION( idMover_Periodic, idRotater ) + EVENT( EV_Activate, idRotater::Event_Activate ) +END_CLASS + +/* +=============== +idRotater::idRotater +=============== +*/ +idRotater::idRotater( void ) : + nextTriggerDirectionIsForward(true) +{ + activatedBy = this; +} + +/* +=============== +idRotater::Spawn +=============== +*/ +void idRotater::Spawn( void ) +{ + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "nopush" ) ) { + physicsObj.SetPusher( 0 ); + } + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, gameLocal.time, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, GetPhysics()->GetAxis().ToAngles(), ang_zero, ang_zero ); + SetPhysics( &physicsObj ); + + if ( spawnArgs.GetBool( "start_on" ) ) { + ProcessEvent( &EV_Activate, this ); + } +} + +/* +=============== +idRotater::Save +=============== +*/ +void idRotater::Save( idSaveGame *savefile ) const +{ + activatedBy.Save( savefile ); + savefile->WriteBool(nextTriggerDirectionIsForward); +} + +/* +=============== +idRotater::Restore +=============== +*/ +void idRotater::Restore( idRestoreGame *savefile ) +{ + activatedBy.Restore( savefile ); + savefile->ReadBool(nextTriggerDirectionIsForward); +} + +/* +=============== +idRotater::Event_Activate +=============== +*/ +void idRotater::Event_Activate( idEntity *activator ) +{ + activatedBy = activator; + + bool isRotating = spawnArgs.GetBool("rotate"); + + // greebo: If rotate direction inversion is activated, toggle the boolean, else leave it alone + if (!isRotating && spawnArgs.GetBool("invert_on_trigger", "0")) + { + nextTriggerDirectionIsForward = !nextTriggerDirectionIsForward; + } + + // greebo: Invert the "rotate" spawnarg, this toggles the rotation itself + spawnArgs.Set("rotate", isRotating ? "0" : "1"); + + // Start or stop the rotation, based on the spawnargs (forward direction) + SetRotationFromSpawnargs(nextTriggerDirectionIsForward); +} + +void idRotater::SetRotationFromSpawnargs(bool forward) +{ + idAngles delta(0,0,0); + + if (spawnArgs.GetBool("rotate")) + { + // We should be rotating, read the parameters + float speed = spawnArgs.GetFloat("speed", "100"); + bool x_axis = spawnArgs.GetBool("x_axis", "0"); + bool y_axis = spawnArgs.GetBool("y_axis", "0"); + bool z_axis = !x_axis && !y_axis; + bool applyDirectionFix = spawnArgs.GetBool("apply_direction_fix", "0"); + + // Invert the speed if the direction boolean is false + if (!forward) + { + speed *= -1; + } + + if (applyDirectionFix) + { + idAngles curAngles = physicsObj.GetAxis().ToAngles().Normalize360(); + idAngles spawnAngles = spawnArgs.GetMatrix("rotation", "1 0 0 0 1 0 0 0 1").ToAngles().Normalize360(); + + // greebo: Euler angles are ambiguous - it might happen that a positive speed value + // applied to "roll" means something different than it would have meant at spawn time + // To yield the same orientation with a different set of angles one usually has + // to employ two 180 degree rotations - check this. If anybody has a more elegant way of checking that, let me know! + if (x_axis && fabs(spawnAngles[1] - curAngles[1]) == 180 && fabs(spawnAngles[0] - curAngles[0]) == 180) + { + speed *= -1; + } + else if (y_axis && fabs(spawnAngles[1] - curAngles[1]) == 180 && fabs(spawnAngles[2] - curAngles[2]) == 180) + { + speed *= -1; + } + else if (z_axis && fabs(spawnAngles[0] - curAngles[0]) == 180 && fabs(spawnAngles[2] - curAngles[2]) == 180) + { + speed *= -1; + } + } + + // Set the axis of rotation + if (x_axis) // roll + { + delta[2] = speed; + } + else if (y_axis) // pitch + { + delta[0] = speed; + } + else // z_axis == yaw + { + delta[1] = speed; + } + } + + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, physicsObj.GetAxis().ToAngles().Normalize360(), delta, ang_zero ); +} + +void idRotater::SetDirection(bool forward) +{ + // Read the rotation parameters again, but consider the direction + SetRotationFromSpawnargs(forward); +} + +/* +=============================================================================== + +idBobber + +=============================================================================== +*/ + +CLASS_DECLARATION( idMover_Periodic, idBobber ) +END_CLASS + +/* +=============== +idBobber::idBobber +=============== +*/ +idBobber::idBobber( void ) { +} + +/* +=============== +idBobber::Spawn +=============== +*/ +void idBobber::Spawn( void ) +{ + float speed; + float height; + float phase; + bool x_axis; + bool y_axis; + idVec3 delta; + + spawnArgs.GetFloat( "speed", "4", speed ); + spawnArgs.GetFloat( "height", "32", height ); + spawnArgs.GetFloat( "phase", "0", phase ); + spawnArgs.GetBool( "x_axis", "0", x_axis ); + spawnArgs.GetBool( "y_axis", "0", y_axis ); + + // set the axis of bobbing + delta = vec3_origin; + if ( x_axis ) { + delta[ 0 ] = height; + } else if ( y_axis ) { + delta[ 1 ] = height; + } else { + delta[ 2 ] = height; + } + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "nopush" ) ) { + physicsObj.SetPusher( 0 ); + } + physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(phase * 1000), static_cast(speed * 500), GetPhysics()->GetOrigin(), delta * 2.0f, vec3_origin ); + SetPhysics( &physicsObj ); +} + + +/* +=============================================================================== + +idPendulum + +=============================================================================== +*/ + +CLASS_DECLARATION( idMover_Periodic, idPendulum ) +END_CLASS + +/* +=============== +idPendulum::idPendulum +=============== +*/ +idPendulum::idPendulum( void ) { +} + +/* +=============== +idPendulum::Spawn +=============== +*/ +void idPendulum::Spawn( void ) +{ + float speed; + float freq; + float length; + float phase; + + spawnArgs.GetFloat( "speed", "30", speed ); + spawnArgs.GetFloat( "phase", "0", phase ); + + if ( spawnArgs.GetFloat( "freq", "", freq ) ) { + if ( freq <= 0.0f ) { + gameLocal.Error( "Invalid frequency on entity '%s'", GetName() ); + } + } else { + // find pendulum length + length = idMath::Fabs( GetPhysics()->GetBounds()[0][2] ); + if ( length < 8 ) { + length = 8; + } + + freq = 1 / ( idMath::TWO_PI ) * idMath::Sqrt( g_gravity.GetFloat() / ( 3 * length ) ); + } + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "nopush" ) ) { + physicsObj.SetPusher( 0 ); + } + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(phase * 1000), static_cast(500/freq), GetPhysics()->GetAxis().ToAngles(), idAngles( 0, 0, speed * 2.0f ), ang_zero ); + SetPhysics( &physicsObj ); +} + + +/* +=============================================================================== + +idBobber + +=============================================================================== +*/ + +CLASS_DECLARATION( idMover_Periodic, idRiser ) +EVENT( EV_Activate, idRiser::Event_Activate ) +END_CLASS + +/* +=============== +idRiser::idRiser +=============== +*/ +idRiser::idRiser( void ) { +} + +/* +=============== +idRiser::Spawn +=============== +*/ +void idRiser::Spawn( void ) +{ + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + + physicsObj.SetClipMask( MASK_SOLID ); + if ( !spawnArgs.GetBool( "solid", "1" ) ) { + physicsObj.SetContents( 0 ); + } + if ( !spawnArgs.GetBool( "nopush" ) ) { + physicsObj.SetPusher( 0 ); + } + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); + SetPhysics( &physicsObj ); +} + +/* +================ +idRiser::Event_Activate +================ +*/ +void idRiser::Event_Activate( idEntity *activator ) { + + if ( !IsHidden() && spawnArgs.GetBool("hide") ) { + Hide(); + } else { + Show(); + float time; + float height; + idVec3 delta; + + spawnArgs.GetFloat( "time", "4", time ); + spawnArgs.GetFloat( "height", "32", height ); + + delta = vec3_origin; + delta[ 2 ] = height; + + physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, static_cast(time * 1000), physicsObj.GetOrigin(), delta, vec3_origin ); + } +} + + diff --git a/game/Mover.h b/game/Mover.h new file mode 100644 index 000000000..119c873d4 --- /dev/null +++ b/game/Mover.h @@ -0,0 +1,455 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_MOVER_H__ +#define __GAME_MOVER_H__ + +extern const idEventDef EV_TeamBlocked; +extern const idEventDef EV_PartBlocked; +extern const idEventDef EV_ReachedPos; +extern const idEventDef EV_ReachedAng; + +/* +=============================================================================== + + General movers. + +=============================================================================== +*/ + +class idMover : public idEntity { +public: + CLASS_PROTOTYPE( idMover ); + + idMover( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + virtual void Hide( void ); + virtual void Show( void ); + + void SetPortalState( bool open ); + + bool IsBlocked( void ); + + ID_INLINE idPhysics_Parametric* GetMoverPhysics() + { + return &physicsObj; + } + + +protected: + typedef enum { + ACCELERATION_STAGE, + LINEAR_STAGE, + DECELERATION_STAGE, + FINISHED_STAGE + } moveStage_t; + + typedef enum { + MOVER_NONE, + MOVER_ROTATING, + MOVER_MOVING, + MOVER_SPLINE + } moverCommand_t; + + // + // mover directions. make sure to change script/doom_defs.script if you add any, or change their order + // + typedef enum { + DIR_UP = -1, + DIR_DOWN = -2, + DIR_LEFT = -3, + DIR_RIGHT = -4, + DIR_FORWARD = -5, + DIR_BACK = -6, + DIR_REL_UP = -7, + DIR_REL_DOWN = -8, + DIR_REL_LEFT = -9, + DIR_REL_RIGHT = -10, + DIR_REL_FORWARD = -11, + DIR_REL_BACK = -12 + } moverDir_t; + + typedef struct { + moveStage_t stage; + int acceleration; + int movetime; + int deceleration; + idVec3 dir; + } moveState_t; + + typedef struct { + moveStage_t stage; + int acceleration; + int movetime; + int deceleration; + idAngles rot; + } rotationState_t; + + idPhysics_Parametric physicsObj; + + void Event_OpenPortal( void ); + void Event_ClosePortal( void ); + virtual void OpenPortal(); + virtual void ClosePortal(); + void Event_PartBlocked( idEntity *blockingEntity ); + virtual void OnTeamBlocked(idEntity* blockedEntity, idEntity* blockingEntity); + + void MoveToPos( const idVec3 &pos); + void MoveToLocalPos( const idVec3 &pos ); + + void UpdateMoveSound( moveStage_t stage ); + void UpdateRotationSound( moveStage_t stage ); + void SetGuiStates( const char *state ); + void FindGuiTargets( void ); + void SetGuiState( const char *key, const char *val ) const; + + virtual void DoneMoving( void ); + virtual void DoneRotating( void ); + virtual void BeginMove( idThread *thread = NULL ); + virtual void BeginRotation( idThread *thread, bool stopwhendone ); + + /** + * greebo: Calculates the fraction of the move_time (the time it takes to complete the whole + * movement) based on the current state. For standard-movers, this does nothing (returns 1), + * but subclasses might do more complicated things based on the current rotation state, + * like BinaryFrobMovers do. + * + * Note: This is an internal function used by BeginRotation() only + */ + virtual float GetMoveTimeFraction(); + + moveState_t move; + +protected: + rotationState_t rot; + + int move_thread; + int rotate_thread; + idAngles dest_angles; + idAngles angle_delta; + idVec3 dest_position; + idVec3 move_delta; + float move_speed; + int move_time; + int deceltime; + int acceltime; + bool stopRotation; + bool useSplineAngles; + idEntityPtr splineEnt; + moverCommand_t lastCommand; + float damage; + + qhandle_t areaPortal; // 0 = no portal + + idList< idEntityPtr > guiTargets; + + void VectorForDir( float dir, idVec3 &vec ); + idCurve_Spline *GetSpline( idEntity *splineEntity ) const; + +public: + void Event_SetCallback( void ); + void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity ); + void Event_StopMoving( void ); + void Event_StopRotating( void ); + void Event_UpdateMove( void ); + void Event_UpdateRotation( void ); + void Event_SetMoveSpeed( float speed ); + void Event_SetMoveTime( float time ); + void Event_SetDecelerationTime( float time ); + void Event_SetAccellerationTime( float time ); + void Event_MoveTo( idEntity *ent ); + void Event_MoveToPos( idVec3 &pos ); + void Event_MoveDir( float angle, float distance ); + void Event_MoveAccelerateTo( float speed, float time ); + void Event_MoveDecelerateTo( float speed, float time ); + void Event_RotateDownTo( int axis, float angle ); + void Event_RotateUpTo( int axis, float angle ); + void Event_RotateTo( idAngles &angles ); + void Event_Rotate( idAngles &angles ); + void Event_RotateOnce( idAngles &angles ); + void Event_Bob( float speed, float phase, idVec3 &depth ); + void Event_Sway( float speed, float phase, idAngles &depth ); + void Event_SetAccelSound( const char *sound ); + void Event_SetDecelSound( const char *sound ); + void Event_SetMoveSound( const char *sound ); + void Event_FindGuiTargets( void ); + void Event_InitGuiTargets( void ); + void Event_EnableSplineAngles( void ); + void Event_DisableSplineAngles( void ); + void Event_RemoveInitialSplineAngles( void ); + void Event_StartSpline( idEntity *splineEntity ); + void Event_StopSpline( void ); + void Event_Activate( idEntity *activator ); + void Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng ); + void Event_IsMoving( void ); + void Event_IsRotating( void ); +}; + +class idSplinePath : public idEntity { +public: + CLASS_PROTOTYPE( idSplinePath ); + + idSplinePath(); + + void Spawn( void ); +}; + + +struct floorInfo_s { + idVec3 pos; + idStr door; + int floor; +}; + +/* +=============================================================================== + + Binary movers. + +=============================================================================== +*/ + +typedef enum { + MOVER_POS1, + MOVER_POS2, + MOVER_1TO2, + MOVER_2TO1 +} moverState_t; + +class idMover_Binary : public idEntity { +public: + CLASS_PROTOTYPE( idMover_Binary ); + + idMover_Binary(); + ~idMover_Binary(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void PreBind( void ); + virtual void PostBind( void ); + + void Enable( bool b ); + void InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime ); + void InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime ); + void GotoPosition1( void ); + void GotoPosition2( void ); + void Use_BinaryMover( idEntity *activator ); + void SetGuiStates( const char *state ); + void UpdateBuddies( int val ); + idMover_Binary * GetActivateChain( void ) const { return activateChain; } + idMover_Binary * GetMoveMaster( void ) const { return moveMaster; } + void BindTeam( idEntity *bindTo ); + void SetBlocked( bool b ); + bool IsBlocked( void ); + idEntity * GetActivator( void ) const; + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + void SetPortalState( bool open ); + +protected: + idVec3 pos1; + idVec3 pos2; + moverState_t moverState; + idMover_Binary * moveMaster; + idMover_Binary * activateChain; + int soundPos1; + int sound1to2; + int sound2to1; + int soundPos2; + int soundLoop; + float wait; + float damage; + int duration; + int accelTime; + int decelTime; + idEntityPtr activatedBy; + int stateStartTime; + idStr team; + bool enabled; + int move_thread; + int updateStatus; // 1 = lock behaviour, 2 = open close status + idStrList buddies; + idPhysics_Parametric physicsObj; + qhandle_t areaPortal; // 0 = no portal + bool blocked; + idList< idEntityPtr > guiTargets; + + void MatchActivateTeam( moverState_t newstate, int time ); + void JoinActivateTeam( idMover_Binary *master ); + + void UpdateMoverSound( moverState_t state ); + void SetMoverState( moverState_t newstate, int time ); + moverState_t GetMoverState( void ) const { return moverState; } + void FindGuiTargets( void ); + void SetGuiState( const char *key, const char *val ) const; + + void Event_SetCallback( void ); + void Event_ReturnToPos1( void ); + void Event_Use_BinaryMover( idEntity *activator ); + void Event_Reached_BinaryMover( void ); + void Event_MatchActivateTeam( moverState_t newstate, int time ); + void Event_Enable( void ); + void Event_Disable( void ); + void Event_OpenPortal( void ); + void Event_ClosePortal( void ); + void Event_FindGuiTargets( void ); + void Event_InitGuiTargets( void ); + + static void GetMovedir( float dir, idVec3 &movedir ); +}; + +class idPlat : public idMover_Binary { +public: + CLASS_PROTOTYPE( idPlat ); + + idPlat( void ); + ~idPlat( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + virtual void PreBind( void ); + virtual void PostBind( void ); + +private: + idClipModel * trigger; + idVec3 localTriggerOrigin; + idMat3 localTriggerAxis; + + void GetLocalTriggerPosition( const idClipModel *trigger ); + void SpawnPlatTrigger( idVec3 &pos ); + + void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ); + void Event_PartBlocked( idEntity *blockingEntity ); + void Event_Touch( idEntity *other, trace_t *trace ); +}; + + +/* +=============================================================================== + + Special periodic movers. + +=============================================================================== +*/ + +class idMover_Periodic : public idEntity { +public: + CLASS_PROTOTYPE( idMover_Periodic ); + + idMover_Periodic( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + +protected: + idPhysics_Parametric physicsObj; + float damage; + + void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ); + void Event_PartBlocked( idEntity *blockingEntity ); +}; + +class idRotater : public idMover_Periodic { +public: + CLASS_PROTOTYPE( idRotater ); + + idRotater( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // greebo: Allows callers to invert the rotation direction + void SetDirection(bool forward); + +private: + // Reads the rotation axis and speed from the spawnargs and starts/stops to rotate + void SetRotationFromSpawnargs(bool forward); + + idEntityPtr activatedBy; + + // If true, the next activation will let the mover rotate in forward direction + // this is only used when "invert_on_trigger" is set to "1" + bool nextTriggerDirectionIsForward; + + void Event_Activate( idEntity *activator ); +}; + +class idBobber : public idMover_Periodic { +public: + CLASS_PROTOTYPE( idBobber ); + + idBobber( void ); + + void Spawn( void ); + +private: +}; + +class idPendulum : public idMover_Periodic { +public: + CLASS_PROTOTYPE( idPendulum ); + + idPendulum( void ); + + void Spawn( void ); + +private: +}; + +class idRiser : public idMover_Periodic { +public: + CLASS_PROTOTYPE( idRiser ); + + idRiser( void ); + + void Spawn( void ); + +private: + void Event_Activate( idEntity *activator ); +}; + +#endif /* !__GAME_MOVER_H__ */ diff --git a/DarkMod/MultiStateMover.cpp b/game/MultiStateMover.cpp similarity index 93% rename from DarkMod/MultiStateMover.cpp rename to game/MultiStateMover.cpp index d1d896f69..a2a1de5cd 100644 --- a/DarkMod/MultiStateMover.cpp +++ b/game/MultiStateMover.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/MultiStateMover.h b/game/MultiStateMover.h similarity index 82% rename from DarkMod/MultiStateMover.h rename to game/MultiStateMover.h index 83bafef19..9ea8ecdb9 100644 --- a/DarkMod/MultiStateMover.h +++ b/game/MultiStateMover.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _MULTI_STATE_MOVER_H_ #define _MULTI_STATE_MOVER_H_ diff --git a/game/MultiStateMoverButton.cpp b/game/MultiStateMoverButton.cpp new file mode 100644 index 000000000..e33469f5d --- /dev/null +++ b/game/MultiStateMoverButton.cpp @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "DarkModGlobals.h" +#include "MultiStateMoverButton.h" +#include "MultiStateMover.h" + +//=============================================================================== +// CMultiStateMoverButton +//=============================================================================== + +const idEventDef EV_RegisterSelfWithElevator("MSMBRegisterSelfWithElevator", NULL); + +CLASS_DECLARATION( CFrobButton, CMultiStateMoverButton ) + EVENT( EV_RegisterSelfWithElevator, CMultiStateMoverButton::Event_RegisterSelfWithElevator) +END_CLASS + +void CMultiStateMoverButton::Spawn() +{ + if (!spawnArgs.GetBool("ride", "0") && !spawnArgs.GetBool("fetch", "0")) + { + gameLocal.Warning("Elevator button %s has neither 'fetch' nor 'ride' spawnargs set. AI will not be able to use this button!", name.c_str()); + } + + PostEventMS(&EV_RegisterSelfWithElevator, 10); +} + +void CMultiStateMoverButton::Event_RegisterSelfWithElevator() +{ + for (int i = 0; i < targets.Num(); i++) + { + idEntity* ent = targets[i].GetEntity(); + + if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) + { + continue; + } + + CMultiStateMover* elevator = static_cast(ent); + + // Send the information about us to the elevator + if (spawnArgs.GetBool("ride", "0")) + { + elevator->RegisterButton(this, BUTTON_TYPE_RIDE); + } + + if (spawnArgs.GetBool("fetch", "0")) + { + elevator->RegisterButton(this, BUTTON_TYPE_FETCH); + } + } +} diff --git a/game/MultiStateMoverButton.h b/game/MultiStateMoverButton.h new file mode 100644 index 000000000..66dd75562 --- /dev/null +++ b/game/MultiStateMoverButton.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MULTISTATEMOVER_BUTTON_H_ +#define __MULTISTATEMOVER_BUTTON_H_ + +#include "FrobButton.h" + +enum EMMButtonType +{ + BUTTON_TYPE_RIDE = 0, + BUTTON_TYPE_FETCH, + NUM_BUTTON_TYPES, +}; + +/** + * greebo: A MultiStateMoverButton is a bit more intelligent + * than an ordinary FrobButton as it is "communicating" with + * the targetted elevator a bit at spawn time. + */ +class CMultiStateMoverButton : + public CFrobButton +{ +public: + + CLASS_PROTOTYPE( CMultiStateMoverButton ); + + void Spawn(); + +private: + void Event_RegisterSelfWithElevator(); +}; + +#endif /* __MULTISTATEMOVER_BUTTON_H_ */ diff --git a/DarkMod/MultiStateMoverPosition.cpp b/game/MultiStateMoverPosition.cpp similarity index 83% rename from DarkMod/MultiStateMoverPosition.cpp rename to game/MultiStateMoverPosition.cpp index ee8e4fd6d..a78cb3f15 100644 --- a/DarkMod/MultiStateMoverPosition.cpp +++ b/game/MultiStateMoverPosition.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/MultiStateMoverPosition.h b/game/MultiStateMoverPosition.h similarity index 77% rename from DarkMod/MultiStateMoverPosition.h rename to game/MultiStateMoverPosition.h index cb759eb3a..c0f54fdc1 100644 --- a/DarkMod/MultiStateMoverPosition.h +++ b/game/MultiStateMoverPosition.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _MULTI_STATE_MOVER_POSITION_H_ #define _MULTI_STATE_MOVER_POSITION_H_ diff --git a/game/MultiplayerGame.cpp b/game/MultiplayerGame.cpp new file mode 100644 index 000000000..18d636f76 --- /dev/null +++ b/game/MultiplayerGame.cpp @@ -0,0 +1,3406 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +// could be a problem if players manage to go down sudden deaths till this .. oh well +#define LASTMAN_NOLIVES -20 + +idCVar g_spectatorChat( "g_spectatorChat", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "let spectators talk to everyone during game" ); + +// global sounds transmitted by index - 0 .. SND_COUNT +// sounds in this list get precached on MP start +const char *idMultiplayerGame::GlobalSoundStrings[] = { + "sound/feedback/voc_youwin.wav", + "sound/feedback/voc_youlose.wav", + "sound/feedback/fight.wav", + "sound/feedback/vote_now.wav", + "sound/feedback/vote_passed.wav", + "sound/feedback/vote_failed.wav", + "sound/feedback/three.wav", + "sound/feedback/two.wav", + "sound/feedback/one.wav", + "sound/feedback/sudden_death.wav", +}; + +// handy verbose +const char *idMultiplayerGame::GameStateStrings[] = { + "INACTIVE", + "WARMUP", + "COUNTDOWN", + "GAMEON", + "SUDDENDEATH", + "GAMEREVIEW", + "NEXTGAME" +}; + +const char *idMultiplayerGame::MPGuis[] = { + "guis/mphud.gui", + "guis/mpmain.gui", + "guis/mpmsgmode.gui", + "guis/netmenu.gui", + NULL +}; + +const char *idMultiplayerGame::ThrottleVars[] = { + "ui_spectate", + "ui_ready", + "ui_team", + NULL +}; + +const char *idMultiplayerGame::ThrottleVarsInEnglish[] = { + "#str_06738", + "#str_06737", + "#str_01991", + NULL +}; + +const int idMultiplayerGame::ThrottleDelay[] = { + 8, + 5, + 5 +}; + +/* +================ +idMultiplayerGame::idMultiplayerGame +================ +*/ +idMultiplayerGame::idMultiplayerGame() { + scoreBoard = NULL; + spectateGui = NULL; + guiChat = NULL; + mainGui = NULL; + mapList = NULL; + msgmodeGui = NULL; + lastGameType = GAME_SP; + Clear(); +} + +/* +================ +idMultiplayerGame::Shutdown +================ +*/ +void idMultiplayerGame::Shutdown( void ) { + Clear(); +} + +/* +================ +idMultiplayerGame::SetMenuSkin +================ +*/ +void idMultiplayerGame::SetMenuSkin( void ) { + // skins + idStr str = cvarSystem->GetCVarString( "mod_validSkins" ); + idStr uiSkin = cvarSystem->GetCVarString( "ui_skin" ); + idStr skin; + int skinId = 1; + int count = 1; + while ( str.Length() ) { + int n = str.Find( ";" ); + if ( n >= 0 ) { + skin = str.Left( n ); + str = str.Right( str.Length() - n - 1 ); + } else { + skin = str; + str = ""; + } + if ( skin.Icmp( uiSkin ) == 0 ) { + skinId = count; + } + count++; + } + + for ( int i = 0; i < count; i++ ) { + mainGui->SetStateInt( va( "skin%i", i+1 ), 0 ); + } + mainGui->SetStateInt( va( "skin%i", skinId ), 1 ); +} + +/* +================ +idMultiplayerGame::Reset +================ +*/ +void idMultiplayerGame::Reset() { + Clear(); + assert( !scoreBoard && !spectateGui && !guiChat && !mainGui && !mapList ); + scoreBoard = uiManager->FindGui( "guis/scoreboard.gui", true, false, true ); + spectateGui = uiManager->FindGui( "guis/spectate.gui", true, false, true ); + guiChat = uiManager->FindGui( "guis/chat.gui", true, false, true ); + mainGui = uiManager->FindGui( "guis/mpmain.gui", true, false, true ); + mapList = uiManager->AllocListGUI( ); + mapList->Config( mainGui, "mapList" ); + // set this GUI so that our Draw function is still called when it becomes the active/fullscreen GUI + mainGui->SetStateBool( "gameDraw", true ); + mainGui->SetKeyBindingNames(); + mainGui->SetStateInt( "com_machineSpec", cvarSystem->GetCVarInteger( "com_machineSpec" ) ); + SetMenuSkin(); + msgmodeGui = uiManager->FindGui( "guis/mpmsgmode.gui", true, false, true ); + msgmodeGui->SetStateBool( "gameDraw", true ); + ClearGuis(); + ClearChatData(); + warmupEndTime = 0; +} + +/* +================ +idMultiplayerGame::ServerClientConnect +================ +*/ +void idMultiplayerGame::ServerClientConnect( int clientNum ) { + memset( &playerState[ clientNum ], 0, sizeof( playerState[ clientNum ] ) ); +} + +/* +================ +idMultiplayerGame::SpawnPlayer +================ +*/ +void idMultiplayerGame::SpawnPlayer( int clientNum ) { + + bool ingame = playerState[ clientNum ].ingame; + + memset( &playerState[ clientNum ], 0, sizeof( playerState[ clientNum ] ) ); + if ( !gameLocal.isClient ) { + idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); + p->spawnedTime = gameLocal.time; + if ( gameLocal.gameType == GAME_TDM ) { + SwitchToTeam( clientNum, -1, p->team ); + } + p->tourneyRank = 0; + if ( gameLocal.gameType == GAME_TOURNEY && gameState == GAMEON ) { + p->tourneyRank++; + } + playerState[ clientNum ].ingame = ingame; + } +} + +/* +================ +idMultiplayerGame::Clear +================ +*/ +void idMultiplayerGame::Clear() { + int i; + + gameState = INACTIVE; + nextState = INACTIVE; + pingUpdateTime = 0; + vote = VOTE_NONE; + voteTimeOut = 0; + voteExecTime = 0; + nextStateSwitch = 0; + matchStartedTime = 0; + currentTourneyPlayer[ 0 ] = -1; + currentTourneyPlayer[ 1 ] = -1; + one = two = three = false; + memset( &playerState, 0 , sizeof( playerState ) ); + lastWinner = -1; + currentMenu = 0; + bCurrentMenuMsg = false; + nextMenu = 0; + pureReady = false; + scoreBoard = NULL; + spectateGui = NULL; + guiChat = NULL; + mainGui = NULL; + msgmodeGui = NULL; + if ( mapList ) { + uiManager->FreeListGUI( mapList ); + mapList = NULL; + } + fragLimitTimeout = 0; + memset( &switchThrottle, 0, sizeof( switchThrottle ) ); + voiceChatThrottle = 0; + for ( i = 0; i < NUM_CHAT_NOTIFY; i++ ) { + chatHistory[ i ].line.Clear(); + } + warmupText.Clear(); + voteValue.Clear(); + voteString.Clear(); + startFragLimit = -1; +} + +/* +================ +idMultiplayerGame::ClearGuis +================ +*/ +void idMultiplayerGame::ClearGuis() { + int i; + + for ( i = 0; i < MAX_CLIENTS; i++ ) { + scoreBoard->SetStateString( va( "player%i",i+1 ), "" ); + scoreBoard->SetStateString( va( "player%i_score", i+1 ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_tscore", i+1 ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_score", i+1 ), "" ); + scoreBoard->SetStateString( va( "player%i_wins", i+1 ), "" ); + scoreBoard->SetStateString( va( "player%i_status", i+1 ), "" ); + scoreBoard->SetStateInt( va( "rank%i", i+1 ), 0 ); + scoreBoard->SetStateInt( "rank_self", 0 ); + + idPlayer *player = static_cast( gameLocal.entities[ i ] ); + if ( !player || !player->hud ) { + continue; + } + player->hud->SetStateString( va( "player%i",i+1 ), "" ); + player->hud->SetStateString( va( "player%i_score", i+1 ), "" ); + player->hud->SetStateString( va( "player%i_ready", i+1 ), "" ); + scoreBoard->SetStateInt( va( "rank%i", i+1 ), 0 ); + player->hud->SetStateInt( "rank_self", 0 ); + } +} + +/* +================ +idMultiplayerGame::UpdatePlayerRanks +================ +*/ +void idMultiplayerGame::UpdatePlayerRanks() { + int i, j, k; + idPlayer *players[MAX_CLIENTS]; + idEntity *ent; + idPlayer *player; + + memset( players, 0, sizeof( players ) ); + numRankedPlayers = 0; + + for ( i = 0; i < gameLocal.numClients; i++ ) { + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + player = static_cast< idPlayer * >( ent ); + if ( !CanPlay( player ) ) { + continue; + } + if ( gameLocal.gameType == GAME_TOURNEY ) { + if ( i != currentTourneyPlayer[ 0 ] && i != currentTourneyPlayer[ 1 ] ) { + continue; + } + } + if ( gameLocal.gameType == GAME_LASTMAN && playerState[ i ].fragCount == LASTMAN_NOLIVES ) { + continue; + } + for ( j = 0; j < numRankedPlayers; j++ ) { + bool insert = false; + if ( gameLocal.gameType == GAME_TDM ) { + if ( player->team != players[ j ]->team ) { + if ( playerState[ i ].teamFragCount > playerState[ players[ j ]->entityNumber ].teamFragCount ) { + // team scores + insert = true; + } else if ( playerState[ i ].teamFragCount == playerState[ players[ j ]->entityNumber ].teamFragCount && player->team < players[ j ]->team ) { + // at equal scores, sort by team number + insert = true; + } + } else if ( playerState[ i ].fragCount > playerState[ players[ j ]->entityNumber ].fragCount ) { + // in the same team, sort by frag count + insert = true; + } + } else { + insert = ( playerState[ i ].fragCount > playerState[ players[ j ]->entityNumber ].fragCount ); + } + if ( insert ) { + for ( k = numRankedPlayers; k > j; k-- ) { + players[ k ] = players[ k-1 ]; + } + players[ j ] = player; + break; + } + } + if ( j == numRankedPlayers ) { + players[ numRankedPlayers ] = player; + } + numRankedPlayers++; + } + + memcpy( rankedPlayers, players, sizeof( players ) ); +} + + +/* +================ +idMultiplayerGame::UpdateRankColor +================ +*/ +void idMultiplayerGame::UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec ) { + for ( int j = 1; j < 4; j++ ) { + gui->SetStateFloat( va( mask, i, j ), vec[ j - 1 ] ); + } +} + +/* +================ +idMultiplayerGame::UpdateScoreboard +================ +*/ +void idMultiplayerGame::UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player ) { + int i, j, iline, k; + idStr gameinfo; + idStr livesinfo; + idStr timeinfo; + idEntity *ent; + idPlayer *p; + int value; + + scoreBoard->SetStateString( "scoretext", gameLocal.gameType == GAME_LASTMAN ? gameLocal.m_I18N->Translate( "#str_04242" ) : gameLocal.m_I18N->Translate( "#str_04243" ) ); + + iline = 0; // the display lines + if ( gameState != WARMUP ) { + for ( i = 0; i < numRankedPlayers; i++ ) { + // ranked player + iline++; + scoreBoard->SetStateString( va( "player%i", iline ), rankedPlayers[ i ]->GetUserInfo()->GetString( "ui_name" ) ); + if ( gameLocal.gameType == GAME_TDM ) { + value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); + scoreBoard->SetStateInt( va( "player%i_tdm_score", iline ), value ); + value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].teamFragCount ); + scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), va( "/ %i", value ) ); + scoreBoard->SetStateString( va( "player%i_score", iline ), "" ); + } else { + value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); + scoreBoard->SetStateInt( va( "player%i_score", iline ), value ); + scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); + } + value = idMath::ClampInt( 0, MP_PLAYER_MAXWINS, playerState[ rankedPlayers[ i ]->entityNumber ].wins ); + scoreBoard->SetStateInt( va( "player%i_wins", iline ), value ); + scoreBoard->SetStateInt( va( "player%i_ping", iline ), playerState[ rankedPlayers[ i ]->entityNumber ].ping ); + // set the color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); + UpdateRankColor( scoreBoard, "rank%i_color%i", iline, rankedPlayers[ i ]->colorBar ); + if ( rankedPlayers[ i ] == player ) { + // highlight who we are + scoreBoard->SetStateInt( "rank_self", iline ); + } + } + } + + // if warmup, this draws everyone, otherwise it goes over spectators only + // when doing warmup we loop twice to draw ready/not ready first *then* spectators + // NOTE: in tourney, shows spectators according to their playing rank order? + for ( k = 0; k < ( gameState == WARMUP ? 2 : 1 ); k++ ) { + for ( i = 0; i < MAX_CLIENTS; i++ ) { + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( gameState != WARMUP ) { + // check he's not covered by ranks already + for ( j = 0; j < numRankedPlayers; j++ ) { + if ( ent == rankedPlayers[ j ] ) { + break; + } + } + if ( j != numRankedPlayers ) { + continue; + } + } + p = static_cast< idPlayer * >( ent ); + if ( gameState == WARMUP ) { + if ( k == 0 && p->spectating ) { + continue; + } + if ( k == 1 && !p->spectating ) { + continue; + } + } + + iline++; + if ( !playerState[ i ].ingame ) { + scoreBoard->SetStateString( va( "player%i", iline ), gameLocal.m_I18N->Translate( "#str_04244" ) ); + scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04245" ) ); + // no color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); + } else { + scoreBoard->SetStateString( va( "player%i", iline ), gameLocal.userInfo[ i ].GetString( "ui_name" ) ); + if ( gameState == WARMUP ) { + if ( p->spectating ) { + scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04246" ) ); + // no color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); + } else { + scoreBoard->SetStateString( va( "player%i_score", iline ), p->IsReady() ? gameLocal.m_I18N->Translate( "#str_04247" ) : gameLocal.m_I18N->Translate( "#str_04248" ) ); + // set the color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); + UpdateRankColor( scoreBoard, "rank%i_color%i", iline, p->colorBar ); + } + } else { + if ( gameLocal.gameType == GAME_LASTMAN && playerState[ i ].fragCount == LASTMAN_NOLIVES ) { + scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_06736" ) ); + // set the color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); + UpdateRankColor( scoreBoard, "rank%i_color%i", iline, p->colorBar ); + } else { + scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04246" ) ); + // no color band + scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); + } + } + } + scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_wins", iline ), "" ); + scoreBoard->SetStateInt( va( "player%i_ping", iline ), playerState[ i ].ping ); + if ( i == player->entityNumber ) { + // highlight who we are + scoreBoard->SetStateInt( "rank_self", iline ); + } + } + } + + // clear remaining lines (empty slots) + iline++; + while ( iline < 5 ) { + scoreBoard->SetStateString( va( "player%i", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_score", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_wins", iline ), "" ); + scoreBoard->SetStateString( va( "player%i_ping", iline ), "" ); + scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); + iline++; + } + + gameinfo = va( "%s: %s", gameLocal.m_I18N->Translate( "#str_02376" ), gameLocal.serverInfo.GetString( "si_gameType" ) ); + if ( gameLocal.gameType == GAME_LASTMAN ) { + if ( gameState == GAMEON || gameState == SUDDENDEATH ) { + livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_04264" ), startFragLimit ); + } else { + livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_04264" ), gameLocal.serverInfo.GetInt( "si_fragLimit" ) ); + } + + } else { + livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_01982" ), gameLocal.serverInfo.GetInt( "si_fragLimit" ) ); + } + if ( gameLocal.serverInfo.GetInt( "si_timeLimit" ) > 0 ) { + timeinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_01983" ), gameLocal.serverInfo.GetInt( "si_timeLimit" ) ); + } else { + timeinfo = va("%s", gameLocal.m_I18N->Translate( "#str_07209" )); + } + scoreBoard->SetStateString( "gameinfo", gameinfo ); + scoreBoard->SetStateString( "livesinfo", livesinfo ); + scoreBoard->SetStateString( "timeinfo", timeinfo ); + + scoreBoard->Redraw( gameLocal.time ); +} + +/* +================ +idMultiplayerGame::GameTime +================ +*/ +const char *idMultiplayerGame::GameTime() { + static char buff[16]; + int m, s, t, ms; + + if ( gameState == COUNTDOWN ) { + ms = warmupEndTime - gameLocal.realClientTime; + s = ms / 1000 + 1; + if ( ms <= 0 ) { + strcpy( buff, "WMP --" ); + } else { + sprintf( buff, "WMP %i", s ); + } + } else { + int timeLimit = gameLocal.serverInfo.GetInt( "si_timeLimit" ); + if ( timeLimit ) { + ms = ( timeLimit * 60000 ) - ( gameLocal.time - matchStartedTime ); + } else { + ms = gameLocal.time - matchStartedTime; + } + if ( ms < 0 ) { + ms = 0; + } + + s = ms / 1000; + m = s / 60; + s -= m * 60; + t = s / 10; + s -= t * 10; + + sprintf( buff, "%i:%i%i", m, t, s ); + } + return &buff[0]; +} + +/* +================ +idMultiplayerGame::NumActualClients +================ +*/ +int idMultiplayerGame::NumActualClients( bool countSpectators, int *teamcounts ) { + idPlayer *p; + int c = 0; + + if ( teamcounts ) { + teamcounts[ 0 ] = teamcounts[ 1 ] = 0; + } + for( int i = 0 ; i < gameLocal.numClients ; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + p = static_cast< idPlayer * >( ent ); + if ( countSpectators || CanPlay( p ) ) { + c++; + } + if ( teamcounts && CanPlay( p ) ) { + teamcounts[ p->team ]++; + } + } + return c; +} + +/* +================ +idMultiplayerGame::EnoughClientsToPlay +================ +*/ +bool idMultiplayerGame::EnoughClientsToPlay() { + int team[ 2 ]; + int clients = NumActualClients( false, &team[ 0 ] ); + if ( gameLocal.gameType == GAME_TDM ) { + return clients >= 2 && team[ 0 ] && team[ 1 ]; + } else { + return clients >= 2; + } +} + +/* +================ +idMultiplayerGame::AllPlayersReady +================ +*/ +bool idMultiplayerGame::AllPlayersReady() { + int i; + idEntity *ent; + idPlayer *p; + int team[ 2 ]; + + if ( NumActualClients( false, &team[ 0 ] ) <= 1 ) { + return false; + } + + if ( gameLocal.gameType == GAME_TDM ) { + if ( !team[ 0 ] || !team[ 1 ] ) { + return false; + } + } + + if ( !gameLocal.serverInfo.GetBool( "si_warmup" ) ) { + return true; + } + + for( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.gameType == GAME_TOURNEY && i != currentTourneyPlayer[ 0 ] && i != currentTourneyPlayer[ 1 ] ) { + continue; + } + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + p = static_cast< idPlayer * >( ent ); + if ( CanPlay( p ) && !p->IsReady() ) { + return false; + } + team[ p->team ]++; + } + + return true; +} + +/* +================ +idMultiplayerGame::FragLimitHit +return the winning player (team player) +if there is no FragLeader(), the game is tied and we return NULL +================ +*/ +idPlayer *idMultiplayerGame::FragLimitHit() { + int i; + int fragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); + idPlayer *leader; + + leader = FragLeader(); + if ( !leader ) { + return NULL; + } + + if ( fragLimit <= 0 ) { + fragLimit = MP_PLAYER_MAXFRAGS; + } + + if ( gameLocal.gameType == GAME_LASTMAN ) { + // we have a leader, check if any other players have frags left + assert( !static_cast< idPlayer * >( leader )->lastManOver ); + for( i = 0 ; i < gameLocal.numClients ; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( !CanPlay( static_cast< idPlayer * >( ent ) ) ) { + continue; + } + if ( ent == leader ) { + continue; + } + if ( playerState[ ent->entityNumber ].fragCount > 0 ) { + return NULL; + } + } + // there is a leader, his score may even be negative, but no one else has frags left or is !lastManOver + return leader; + } else if ( gameLocal.gameType == GAME_TDM ) { + if ( playerState[ leader->entityNumber ].teamFragCount >= fragLimit ) { + return leader; + } + } else { + if ( playerState[ leader->entityNumber ].fragCount >= fragLimit ) { + return leader; + } + } + + return NULL; +} + +/* +================ +idMultiplayerGame::TimeLimitHit +================ +*/ +bool idMultiplayerGame::TimeLimitHit() { + int timeLimit = gameLocal.serverInfo.GetInt( "si_timeLimit" ); + if ( timeLimit ) { + if ( gameLocal.time >= matchStartedTime + timeLimit * 60000 ) { + return true; + } + } + return false; +} + +/* +================ +idMultiplayerGame::FragLeader +return the current winner ( or a player from the winning team ) +NULL if even +================ +*/ +idPlayer *idMultiplayerGame::FragLeader( void ) { + int i; + int frags[ MAX_CLIENTS ]; + idPlayer *leader = NULL; + idEntity *ent; + idPlayer *p; + int high = -9999; + int count = 0; + bool teamLead[ 2 ] = { false, false }; + + for ( i = 0 ; i < gameLocal.numClients ; i++ ) { + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( !CanPlay( static_cast< idPlayer * >( ent ) ) ) { + continue; + } + if ( gameLocal.gameType == GAME_TOURNEY && ent->entityNumber != currentTourneyPlayer[ 0 ] && ent->entityNumber != currentTourneyPlayer[ 1 ] ) { + continue; + } + if ( static_cast< idPlayer * >( ent )->lastManOver ) { + continue; + } + + int fragc = ( gameLocal.gameType == GAME_TDM ) ? playerState[i].teamFragCount : playerState[i].fragCount; + if ( fragc > high ) { + high = fragc; + } + + frags[ i ] = fragc; + } + + for ( i = 0; i < gameLocal.numClients; i++ ) { + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + p = static_cast< idPlayer * >( ent ); + p->SetLeader( false ); + + if ( !CanPlay( p ) ) { + continue; + } + if ( gameLocal.gameType == GAME_TOURNEY && ent->entityNumber != currentTourneyPlayer[ 0 ] && ent->entityNumber != currentTourneyPlayer[ 1 ] ) { + continue; + } + if ( p->lastManOver ) { + continue; + } + if ( p->spectating ) { + continue; + } + + if ( frags[ i ] >= high ) { + leader = p; + count++; + p->SetLeader( true ); + if ( gameLocal.gameType == GAME_TDM ) { + teamLead[ p->team ] = true; + } + } + } + + if ( gameLocal.gameType != GAME_TDM ) { + // more than one player at the highest frags + if ( count > 1 ) { + return NULL; + } else { + return leader; + } + } else { + if ( teamLead[ 0 ] && teamLead[ 1 ] ) { + // even game in team play + return NULL; + } + return leader; + } +} + +/* +================ +idGameLocal::UpdateWinsLosses +================ +*/ +void idMultiplayerGame::UpdateWinsLosses( idPlayer *winner ) { + if ( winner ) { + // run back through and update win/loss count + for( int i = 0; i < gameLocal.numClients; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + idPlayer *player = static_cast(ent); + if ( gameLocal.gameType == GAME_TDM ) { + if ( player == winner || ( player != winner && player->team == winner->team ) ) { + playerState[ i ].wins++; + PlayGlobalSound( player->entityNumber, SND_YOUWIN ); + } else { + PlayGlobalSound( player->entityNumber, SND_YOULOSE ); + } + } else if ( gameLocal.gameType == GAME_LASTMAN ) { + if ( player == winner ) { + playerState[ i ].wins++; + PlayGlobalSound( player->entityNumber, SND_YOUWIN ); + } else if ( !player->wantSpectate ) { + PlayGlobalSound( player->entityNumber, SND_YOULOSE ); + } + } else if ( gameLocal.gameType == GAME_TOURNEY ) { + if ( player == winner ) { + playerState[ i ].wins++; + PlayGlobalSound( player->entityNumber, SND_YOUWIN ); + } else if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { + PlayGlobalSound( player->entityNumber, SND_YOULOSE ); + } + } else { + if ( player == winner ) { + playerState[i].wins++; + PlayGlobalSound( player->entityNumber, SND_YOUWIN ); + } else if ( !player->wantSpectate ) { + PlayGlobalSound( player->entityNumber, SND_YOULOSE ); + } + } + } + } + if ( winner ) { + lastWinner = winner->entityNumber; + } else { + lastWinner = -1; + } +} + +/* +================ +idMultiplayerGame::TeamScore +================ +*/ +void idMultiplayerGame::TeamScore( int entityNumber, int team, int delta ) { + playerState[ entityNumber ].fragCount += delta; + for( int i = 0 ; i < gameLocal.numClients ; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + idPlayer *player = static_cast(ent); + if ( player->team == team ) { + playerState[ player->entityNumber ].teamFragCount += delta; + } + } +} + +/* +================ +idMultiplayerGame::PlayerDeath +================ +*/ +void idMultiplayerGame::PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag ) { + + // don't do PrintMessageEvent and shit + assert( !gameLocal.isClient ); + + if ( killer ) { + if ( gameLocal.gameType == GAME_LASTMAN ) { + playerState[ dead->entityNumber ].fragCount--; + } else if ( gameLocal.gameType == GAME_TDM ) { + if ( killer == dead || killer->team == dead->team ) { + // suicide or teamkill + TeamScore( killer->entityNumber, killer->team, -1 ); + } else { + TeamScore( killer->entityNumber, killer->team, +1 ); + } + } else { + playerState[ killer->entityNumber ].fragCount += ( killer == dead ) ? -1 : 1; + } + } + + if ( killer && killer == dead ) { + PrintMessageEvent( -1, MSG_SUICIDE, dead->entityNumber ); + } else if ( killer ) { + if ( telefrag ) { + PrintMessageEvent( -1, MSG_TELEFRAGGED, dead->entityNumber, killer->entityNumber ); + } else if ( gameLocal.gameType == GAME_TDM && dead->team == killer->team ) { + PrintMessageEvent( -1, MSG_KILLEDTEAM, dead->entityNumber, killer->entityNumber ); + } else { + PrintMessageEvent( -1, MSG_KILLED, dead->entityNumber, killer->entityNumber ); + } + } else { + PrintMessageEvent( -1, MSG_DIED, dead->entityNumber ); + playerState[ dead->entityNumber ].fragCount--; + } +} + +/* +================ +idMultiplayerGame::PlayerStats +================ +*/ +void idMultiplayerGame::PlayerStats( int clientNum, char *data, const int len ) { + + idEntity *ent; + int team; + + *data = 0; + + // make sure we don't exceed the client list + if ( clientNum < 0 || clientNum > gameLocal.numClients ) { + return; + } + + // find which team this player is on + ent = gameLocal.entities[ clientNum ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + team = static_cast< idPlayer * >(ent)->team; + } else { + return; + } + + idStr::snPrintf( data, len, "team=%d score=%d tks=%d", team, playerState[ clientNum ].fragCount, playerState[ clientNum ].teamFragCount ); + + return; + +} + +/* +================ +idMultiplayerGame::PlayerVote +================ +*/ +void idMultiplayerGame::PlayerVote( int clientNum, playerVote_t vote ) { + playerState[ clientNum ].vote = vote; +} + +/* +================ +idMultiplayerGame::DumpTourneyLine +================ +*/ +void idMultiplayerGame::DumpTourneyLine( void ) { + int i; + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { + common->Printf( "client %d: rank %d\n", i, static_cast< idPlayer * >( gameLocal.entities[ i ] )->tourneyRank ); + } + } +} + +/* +================ +idMultiplayerGame::NewState +================ +*/ +void idMultiplayerGame::NewState( gameState_t news, idPlayer *player ) { + idBitMsg outMsg; + byte msgBuf[MAX_GAME_MESSAGE_SIZE]; + int i; + + assert( news != gameState ); + assert( !gameLocal.isClient ); + gameLocal.DPrintf( "%s -> %s\n", GameStateStrings[ gameState ], GameStateStrings[ news ] ); + switch( news ) { + case GAMEON: { + gameLocal.LocalMapRestart(); + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_RESTART ); + outMsg.WriteBits( 0, 1 ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + + PlayGlobalSound( -1, SND_FIGHT ); + matchStartedTime = gameLocal.time; + fragLimitTimeout = 0; + for( i = 0; i < gameLocal.numClients; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + idPlayer *p = static_cast( ent ); + p->SetLeader( false ); // don't carry the flag from previous games + if ( gameLocal.gameType == GAME_TOURNEY && currentTourneyPlayer[ 0 ] != i && currentTourneyPlayer[ 1 ] != i ) { + p->ServerSpectate( true ); + p->tourneyRank++; + } else { + int fragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); + int startingCount = ( gameLocal.gameType == GAME_LASTMAN ) ? fragLimit : 0; + playerState[ i ].fragCount = startingCount; + playerState[ i ].teamFragCount = startingCount; + if ( !static_cast(ent)->wantSpectate ) { + static_cast(ent)->ServerSpectate( false ); + if ( gameLocal.gameType == GAME_TOURNEY ) { + p->tourneyRank = 0; + } + } + } + if ( CanPlay( p ) ) { + p->lastManPresent = true; + } else { + p->lastManPresent = false; + } + } + cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); + switchThrottle[ 1 ] = 0; // passby the throttle + startFragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); + break; + } + case GAMEREVIEW: { + nextState = INACTIVE; // used to abort a game. cancel out any upcoming state change + // set all players not ready and spectating + for( i = 0; i < gameLocal.numClients; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + static_cast< idPlayer *>( ent )->forcedReady = false; + static_cast(ent)->ServerSpectate( true ); + } + UpdateWinsLosses( player ); + break; + } + case SUDDENDEATH: { + PrintMessageEvent( -1, MSG_SUDDENDEATH ); + PlayGlobalSound( -1, SND_SUDDENDEATH ); + break; + } + case COUNTDOWN: { + idBitMsg outMsg; + byte msgBuf[ 128 ]; + + warmupEndTime = gameLocal.time + 1000*cvarSystem->GetCVarInteger( "g_countDown" ); + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_WARMUPTIME ); + outMsg.WriteLong( warmupEndTime ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + + break; + } + default: + break; + } + + gameState = news; +} + +/* +================ +idMultiplayerGame::FillTourneySlots +NOTE: called each frame during warmup to keep the tourney slots filled +================ +*/ +void idMultiplayerGame::FillTourneySlots( ) { + int i, j, rankmax, rankmaxindex; + idEntity *ent; + idPlayer *p; + + // fill up the slots based on tourney ranks + for ( i = 0; i < 2; i++ ) { + if ( currentTourneyPlayer[ i ] != -1 ) { + continue; + } + rankmax = -1; + rankmaxindex = -1; + for ( j = 0; j < gameLocal.numClients; j++ ) { + ent = gameLocal.entities[ j ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( currentTourneyPlayer[ 0 ] == j || currentTourneyPlayer[ 1 ] == j ) { + continue; + } + p = static_cast< idPlayer * >( ent ); + if ( p->wantSpectate ) { + continue; + } + if ( p->tourneyRank >= rankmax ) { + // when ranks are equal, use time in game + if ( p->tourneyRank == rankmax ) { + assert( rankmaxindex >= 0 ); + if ( p->spawnedTime > static_cast< idPlayer * >( gameLocal.entities[ rankmaxindex ] )->spawnedTime ) { + continue; + } + } + rankmax = static_cast< idPlayer * >( ent )->tourneyRank; + rankmaxindex = j; + } + } + currentTourneyPlayer[ i ] = rankmaxindex; // may be -1 if we found nothing + } +} + +/* +================ +idMultiplayerGame::UpdateTourneyLine +we manipulate tourneyRank on player entities for internal ranking. it's easier to deal with. +but we need a real wait list to be synced down to clients for GUI +ignore current players, ignore wantSpectate +================ +*/ +void idMultiplayerGame::UpdateTourneyLine( void ) { + int i, j, imax, max, globalmax = -1; + idPlayer *p; + + assert( !gameLocal.isClient ); + if ( gameLocal.gameType != GAME_TOURNEY ) { + return; + } + + for ( j = 1; j <= gameLocal.numClients; j++ ) { + max = -1; imax = -1; + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( currentTourneyPlayer[ 0 ] == i || currentTourneyPlayer[ 1 ] == i ) { + continue; + } + p = static_cast< idPlayer * >( gameLocal.entities[ i ] ); + if ( !p || p->wantSpectate ) { + continue; + } + if ( p->tourneyRank > max && ( globalmax == -1 || p->tourneyRank < globalmax ) ) { + imax = i; + max = p->tourneyRank; + } + } + if ( imax == -1 ) { + break; + } + + idBitMsg outMsg; + byte msgBuf[1024]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_TOURNEYLINE ); + outMsg.WriteByte( j ); + networkSystem->ServerSendReliableMessage( imax, outMsg ); + + globalmax = max; + } +} + +/* +================ +idMultiplayerGame::CycleTourneyPlayers +================ +*/ +void idMultiplayerGame::CycleTourneyPlayers( ) { + int i; + idEntity *ent; + idPlayer *player; + + currentTourneyPlayer[ 0 ] = -1; + currentTourneyPlayer[ 1 ] = -1; + // if any, winner from last round will play again + if ( lastWinner != -1 ) { + idEntity *ent = gameLocal.entities[ lastWinner ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + currentTourneyPlayer[ 0 ] = lastWinner; + } + } + FillTourneySlots( ); + // force selected players in/out of the game and update the ranks + for ( i = 0 ; i < gameLocal.numClients ; i++ ) { + if ( currentTourneyPlayer[ 0 ] == i || currentTourneyPlayer[ 1 ] == i ) { + player = static_cast( gameLocal.entities[ i ] ); + player->ServerSpectate( false ); + } else { + ent = gameLocal.entities[ i ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + player = static_cast( gameLocal.entities[ i ] ); + player->ServerSpectate( true ); + } + } + } + UpdateTourneyLine(); +} + +/* +================ +idMultiplayerGame::ExecuteVote +the votes are checked for validity/relevance before they are started +we assume that they are still legit when reaching here +================ +*/ +void idMultiplayerGame::ExecuteVote( void ) { + bool needRestart; + switch ( vote ) { + case VOTE_RESTART: + gameLocal.MapRestart(); + break; + case VOTE_TIMELIMIT: + si_timeLimit.SetInteger( atoi( voteValue ) ); + needRestart = gameLocal.NeedRestart(); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); + if ( needRestart ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); + } + break; + case VOTE_FRAGLIMIT: + si_fragLimit.SetInteger( atoi( voteValue ) ); + needRestart = gameLocal.NeedRestart(); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); + if ( needRestart ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); + } + break; + case VOTE_GAMETYPE: + si_gameType.SetString( voteValue ); + gameLocal.MapRestart(); + break; + case VOTE_KICK: + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %s", voteValue.c_str() ) ); + break; + case VOTE_MAP: + si_map.SetString( voteValue ); + gameLocal.MapRestart(); + break; + case VOTE_SPECTATORS: + si_spectators.SetBool( !si_spectators.GetBool() ); + needRestart = gameLocal.NeedRestart(); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); + if ( needRestart ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); + } + break; + case VOTE_NEXTMAP: + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "serverNextMap\n" ); + break; + default: + break; + } +} + +/* +================ +idMultiplayerGame::CheckVote +================ +*/ +void idMultiplayerGame::CheckVote( void ) { + int numVoters, i; + + if ( vote == VOTE_NONE ) { + return; + } + + if ( voteExecTime ) { + if ( gameLocal.time > voteExecTime ) { + voteExecTime = 0; + ClientUpdateVote( VOTE_RESET, 0, 0 ); + ExecuteVote(); + vote = VOTE_NONE; + } + return; + } + + // count voting players + numVoters = 0; + for ( i = 0; i < gameLocal.numClients; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( playerState[ i ].vote != PLAYER_VOTE_NONE ) { + numVoters++; + } + } + if ( !numVoters ) { + // abort + vote = VOTE_NONE; + ClientUpdateVote( VOTE_ABORTED, static_cast(yesVotes), static_cast(noVotes) ); + return; + } + if ( yesVotes / numVoters > 0.5f ) { + ClientUpdateVote( VOTE_PASSED, static_cast(yesVotes), static_cast(noVotes) ); + voteExecTime = gameLocal.time + 2000; + return; + } + if ( gameLocal.time > voteTimeOut || noVotes / numVoters >= 0.5f ) { + ClientUpdateVote( VOTE_FAILED, static_cast(yesVotes), static_cast(noVotes) ); + vote = VOTE_NONE; + return; + } +} + +/* +================ +idMultiplayerGame::Warmup +================ +*/ +bool idMultiplayerGame::Warmup() { + return ( gameState == WARMUP ); +} + +/* +================ +idMultiplayerGame::Run +================ +*/ +void idMultiplayerGame::Run() { + int i, timeLeft; + idPlayer *player; + int gameReviewPause; + + assert( gameLocal.isMultiplayer ); + assert( !gameLocal.isClient ); + + pureReady = true; + + if ( gameState == INACTIVE ) { + lastGameType = gameLocal.gameType; + NewState( WARMUP ); + } + + CheckVote(); + + CheckRespawns(); + + if ( nextState != INACTIVE && gameLocal.time > nextStateSwitch ) { + NewState( nextState ); + nextState = INACTIVE; + } + + // don't update the ping every frame to save bandwidth + if ( gameLocal.time > pingUpdateTime ) { + for ( i = 0; i < gameLocal.numClients; i++ ) { + playerState[i].ping = networkSystem->ServerGetClientPing( i ); + } + pingUpdateTime = gameLocal.time + 1000; + } + + warmupText = ""; + + switch( gameState ) { + case GAMEREVIEW: { + if ( nextState == INACTIVE ) { + gameReviewPause = cvarSystem->GetCVarInteger( "g_gameReviewPause" ); + nextState = NEXTGAME; + nextStateSwitch = gameLocal.time + 1000 * gameReviewPause; + } + break; + } + case NEXTGAME: { + if ( nextState == INACTIVE ) { + // game rotation, new map, gametype etc. + if ( gameLocal.NextMap() ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "serverMapRestart\n" ); + return; + } + NewState( WARMUP ); + if ( gameLocal.gameType == GAME_TOURNEY ) { + CycleTourneyPlayers(); + } + // put everyone back in from endgame spectate + for ( i = 0; i < gameLocal.numClients; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + if ( !static_cast< idPlayer * >( ent )->wantSpectate ) { + CheckRespawns( static_cast( ent ) ); + } + } + } + } + break; + } + case WARMUP: { + if ( AllPlayersReady() ) { + NewState( COUNTDOWN ); + nextState = GAMEON; + nextStateSwitch = gameLocal.time + 1000 * cvarSystem->GetCVarInteger( "g_countDown" ); + } + warmupText = "Warming up.. waiting for players to get ready"; + one = two = three = false; + break; + } + case COUNTDOWN: { + timeLeft = ( nextStateSwitch - gameLocal.time ) / 1000 + 1; + if ( timeLeft == 3 && !three ) { + PlayGlobalSound( -1, SND_THREE ); + three = true; + } else if ( timeLeft == 2 && !two ) { + PlayGlobalSound( -1, SND_TWO ); + two = true; + } else if ( timeLeft == 1 && !one ) { + PlayGlobalSound( -1, SND_ONE ); + one = true; + } + warmupText = va( "Match starts in %i", timeLeft ); + break; + } + case GAMEON: { + player = FragLimitHit(); + if ( player ) { + // delay between detecting frag limit and ending game. let the death anims play + if ( !fragLimitTimeout ) { + common->DPrintf( "enter FragLimit timeout, player %d is leader\n", player->entityNumber ); + fragLimitTimeout = gameLocal.time + FRAGLIMIT_DELAY; + } + if ( gameLocal.time > fragLimitTimeout ) { + NewState( GAMEREVIEW, player ); + PrintMessageEvent( -1, MSG_FRAGLIMIT, player->entityNumber ); + } + } else { + if ( fragLimitTimeout ) { + // frag limit was hit and cancelled. means the two teams got even during FRAGLIMIT_DELAY + // enter sudden death, the next frag leader will win + SuddenRespawn(); + PrintMessageEvent( -1, MSG_HOLYSHIT ); + fragLimitTimeout = 0; + NewState( SUDDENDEATH ); + } else if ( TimeLimitHit() ) { + player = FragLeader(); + if ( !player ) { + NewState( SUDDENDEATH ); + } else { + NewState( GAMEREVIEW, player ); + PrintMessageEvent( -1, MSG_TIMELIMIT ); + } + } + } + break; + } + case SUDDENDEATH: { + player = FragLeader(); + if ( player ) { + if ( !fragLimitTimeout ) { + common->DPrintf( "enter sudden death FragLeader timeout, player %d is leader\n", player->entityNumber ); + fragLimitTimeout = gameLocal.time + FRAGLIMIT_DELAY; + } + if ( gameLocal.time > fragLimitTimeout ) { + NewState( GAMEREVIEW, player ); + PrintMessageEvent( -1, MSG_FRAGLIMIT, player->entityNumber ); + } + } else if ( fragLimitTimeout ) { + SuddenRespawn(); + PrintMessageEvent( -1, MSG_HOLYSHIT ); + fragLimitTimeout = 0; + } + break; + } + default: break; + } +} + +/* +================ +idMultiplayerGame::UpdateMainGui +================ +*/ +void idMultiplayerGame::UpdateMainGui( void ) { + int i; + mainGui->SetStateInt( "readyon", gameState == WARMUP ? 1 : 0 ); + mainGui->SetStateInt( "readyoff", gameState != WARMUP ? 1 : 0 ); + idStr strReady = cvarSystem->GetCVarString( "ui_ready" ); + if ( strReady.Icmp( "ready") == 0 ){ + strReady = gameLocal.m_I18N->Translate( "#str_04248" ); + } else { + strReady = gameLocal.m_I18N->Translate( "#str_04247" ); + } + mainGui->SetStateString( "ui_ready", strReady ); + mainGui->SetStateInt( "teamon", gameLocal.gameType == GAME_TDM ? 1 : 0 ); + mainGui->SetStateInt( "teamoff", gameLocal.gameType != GAME_TDM ? 1 : 0 ); + if ( gameLocal.gameType == GAME_TDM ) { + idPlayer *p = gameLocal.GetClientByNum( gameLocal.localClientNum ); + mainGui->SetStateInt( "team", p->team ); + } + // setup vote + mainGui->SetStateInt( "voteon", ( vote != VOTE_NONE && !voted ) ? 1 : 0 ); + mainGui->SetStateInt( "voteoff", ( vote != VOTE_NONE && !voted ) ? 0 : 1 ); + // last man hack + mainGui->SetStateInt( "isLastMan", gameLocal.gameType == GAME_LASTMAN ? 1 : 0 ); + // send the current serverinfo values + for ( i = 0; i < gameLocal.serverInfo.GetNumKeyVals(); i++ ) { + const idKeyValue *keyval = gameLocal.serverInfo.GetKeyVal( i ); + mainGui->SetStateString( keyval->GetKey(), keyval->GetValue() ); + } + mainGui->StateChanged( gameLocal.time ); +#if defined( __linux__ ) + // replacing the oh-so-useful s_reverse with sound backend prompt + mainGui->SetStateString( "driver_prompt", "1" ); +#else + mainGui->SetStateString( "driver_prompt", "0" ); +#endif +} + +/* +================ +idMultiplayerGame::StartMenu +================ +*/ +idUserInterface* idMultiplayerGame::StartMenu( void ) { + + if ( mainGui == NULL ) { + return NULL; + } + + int i, j; + if ( currentMenu ) { + currentMenu = 0; + cvarSystem->SetCVarBool( "ui_chat", false ); + } else { + if ( nextMenu >= 2 ) { + currentMenu = nextMenu; + } else { + // for default and explicit + currentMenu = 1; + } + cvarSystem->SetCVarBool( "ui_chat", true ); + } + nextMenu = 0; + gameLocal.sessionCommand = ""; // in case we used "game_startMenu" to trigger the menu + if ( currentMenu == 1 ) { + UpdateMainGui(); + + // UpdateMainGui sets most things, but it doesn't set these because + // it'd be pointless and/or harmful to set them every frame (for various reasons) + // Currenty the gui doesn't update properly if they change anyway, so we'll leave it like this. + + // setup callvote + if ( vote == VOTE_NONE ) { + bool callvote_ok = false; + for ( i = 0; i < VOTE_COUNT; i++ ) { + // flag on means vote is denied, so default value 0 means all votes and -1 disables + mainGui->SetStateInt( va( "vote%d", i ), g_voteFlags.GetInteger() & ( 1 << i ) ? 0 : 1 ); + if ( !( g_voteFlags.GetInteger() & ( 1 << i ) ) ) { + callvote_ok = true; + } + } + mainGui->SetStateInt( "callvote", callvote_ok ); + } else { + mainGui->SetStateInt( "callvote", 2 ); + } + + // player kick data + idStr kickList; + j = 0; + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { + if ( kickList.Length() ) { + kickList += ";"; + } + kickList += va( "\"%d - %s\"", i, gameLocal.userInfo[ i ].GetString( "ui_name" ) ); + kickVoteMap[ j ] = i; + j++; + } + } + mainGui->SetStateString( "kickChoices", kickList ); + + mainGui->SetStateString( "chattext", "" ); + mainGui->Activate( true, gameLocal.time ); + return mainGui; + } else if ( currentMenu == 2 ) { + // the setup is done in MessageMode + msgmodeGui->Activate( true, gameLocal.time ); + cvarSystem->SetCVarBool( "ui_chat", true ); + return msgmodeGui; + } + return NULL; +} + +/* +================ +idMultiplayerGame::DisableMenu +================ +*/ +void idMultiplayerGame::DisableMenu( void ) { + gameLocal.sessionCommand = ""; // in case we used "game_startMenu" to trigger the menu + if ( currentMenu == 1 ) { + mainGui->Activate( false, gameLocal.time ); + } else if ( currentMenu == 2 ) { + msgmodeGui->Activate( false, gameLocal.time ); + } + currentMenu = 0; + nextMenu = 0; + cvarSystem->SetCVarBool( "ui_chat", false ); +} + +/* +================ +idMultiplayerGame::SetMapShot +================ +*/ +void idMultiplayerGame::SetMapShot( void ) { + char screenshot[ MAX_STRING_CHARS ]; + int mapNum = mapList->GetSelection( NULL, 0 ); + const idDict *dict = NULL; + if ( mapNum >= 0 ) { + dict = fileSystem->GetMapDecl( mapNum ); + } + fileSystem->FindMapScreenshot( dict ? dict->GetString( "path" ) : "", screenshot, MAX_STRING_CHARS ); + mainGui->SetStateString( "current_levelshot", screenshot ); +} + +/* +================ +idMultiplayerGame::HandleGuiCommands +================ +*/ +const char* idMultiplayerGame::HandleGuiCommands( const char *_menuCommand ) { + idUserInterface *currentGui; + const char *voteValue; + int vote_clientNum; + int icmd; + idCmdArgs args; + + if ( !_menuCommand[ 0 ] ) { + common->Printf( "idMultiplayerGame::HandleGuiCommands: empty command\n" ); + return "continue"; + } + assert( currentMenu ); + if ( currentMenu == 1 ) { + currentGui = mainGui; + } else { + currentGui = msgmodeGui; + } + + args.TokenizeString( _menuCommand, false ); + + for( icmd = 0; icmd < args.Argc(); ) { + const char *cmd = args.Argv( icmd++ ); + + if ( !idStr::Icmp( cmd, ";" ) ) { + continue; + } else if ( !idStr::Icmp( cmd, "video" ) ) { + idStr vcmd; + if ( args.Argc() - icmd >= 1 ) { + vcmd = args.Argv( icmd++ ); + } + + int oldSpec = cvarSystem->GetCVarInteger( "com_machineSpec" ); + + if ( idStr::Icmp( vcmd, "low" ) == 0 ) { + cvarSystem->SetCVarInteger( "com_machineSpec", 0 ); + } else if ( idStr::Icmp( vcmd, "medium" ) == 0 ) { + cvarSystem->SetCVarInteger( "com_machineSpec", 1 ); + } else if ( idStr::Icmp( vcmd, "high" ) == 0 ) { + cvarSystem->SetCVarInteger( "com_machineSpec", 2 ); + } else if ( idStr::Icmp( vcmd, "ultra" ) == 0 ) { + cvarSystem->SetCVarInteger( "com_machineSpec", 3 ); + } else if ( idStr::Icmp( vcmd, "recommended" ) == 0 ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" ); + } + + if ( oldSpec != cvarSystem->GetCVarInteger( "com_machineSpec" ) ) { + currentGui->SetStateInt( "com_machineSpec", cvarSystem->GetCVarInteger( "com_machineSpec" ) ); + currentGui->StateChanged( gameLocal.realClientTime ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "execMachineSpec\n" ); + } + + if ( idStr::Icmp( vcmd, "restart" ) == 0) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" ); + } + + continue; + } else if ( !idStr::Icmp( cmd, "play" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idStr snd = args.Argv( icmd++ ); + int channel = 1; + if ( snd.Length() == 1 ) { + channel = atoi( snd ); + snd = args.Argv( icmd++ ); + } + gameSoundWorld->PlayShaderDirectly( snd, channel ); + } + continue; + } else if ( !idStr::Icmp( cmd, "mpSkin" ) ) { + idStr skin; + if ( args.Argc() - icmd >= 1 ) { + skin = args.Argv( icmd++ ); + cvarSystem->SetCVarString( "ui_skin", skin ); + } + SetMenuSkin(); + continue; + } else if ( !idStr::Icmp( cmd, "quit" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + return NULL; + } else if ( !idStr::Icmp( cmd, "disconnect" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); + return NULL; + } else if ( !idStr::Icmp( cmd, "close" ) ) { + DisableMenu( ); + return NULL; + } else if ( !idStr::Icmp( cmd, "spectate" ) ) { + ToggleSpectate(); + DisableMenu( ); + return NULL; + } else if ( !idStr::Icmp( cmd, "chatmessage" ) ) { + int mode = currentGui->State().GetInt( "messagemode" ); + if ( mode ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "sayTeam \"%s\"", currentGui->State().GetString( "chattext" ) ) ); + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", currentGui->State().GetString( "chattext" ) ) ); + } + currentGui->SetStateString( "chattext", "" ); + if ( currentMenu == 1 ) { + return "continue"; + } else { + DisableMenu(); + return NULL; + } + } else if ( !idStr::Icmp( cmd, "readytoggle" ) ) { + ToggleReady( ); + DisableMenu( ); + return NULL; + } else if ( !idStr::Icmp( cmd, "teamtoggle" ) ) { + ToggleTeam( ); + DisableMenu( ); + return NULL; + } else if ( !idStr::Icmp( cmd, "callVote" ) ) { + vote_flags_t voteIndex = (vote_flags_t)mainGui->State().GetInt( "voteIndex" ); + if ( voteIndex == VOTE_MAP ) { + int mapNum = mapList->GetSelection( NULL, 0 ); + if ( mapNum >= 0 ) { + const idDict *dict = fileSystem->GetMapDecl( mapNum ); + if ( dict ) { + ClientCallVote( VOTE_MAP, dict->GetString( "path" ) ); + } + } + } else { + voteValue = mainGui->State().GetString( "str_voteValue" ); + if ( voteIndex == VOTE_KICK ) { + vote_clientNum = kickVoteMap[ atoi( voteValue ) ]; + ClientCallVote( voteIndex, va( "%d", vote_clientNum ) ); + } else { + ClientCallVote( voteIndex, voteValue ); + } + } + DisableMenu(); + return NULL; + } else if ( !idStr::Icmp( cmd, "voteyes" ) ) { + CastVote( gameLocal.localClientNum, true ); + DisableMenu(); + return NULL; + } else if ( !idStr::Icmp( cmd, "voteno" ) ) { + CastVote( gameLocal.localClientNum, false ); + DisableMenu(); + return NULL; + } else if ( !idStr::Icmp( cmd, "bind" ) ) { + if ( args.Argc() - icmd >= 2 ) { + idStr key = args.Argv( icmd++ ); + idStr bind = args.Argv( icmd++ ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "bindunbindtwo \"%s\" \"%s\"", key.c_str(), bind.c_str() ) ); + mainGui->SetKeyBindingNames(); + } + continue; + } else if ( !idStr::Icmp( cmd, "clearbind" ) ) { + if ( args.Argc() - icmd >= 1 ) { + idStr bind = args.Argv( icmd++ ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "unbind \"%s\"", bind.c_str() ) ); + mainGui->SetKeyBindingNames(); + } + continue; + } else if ( !idStr::Icmp( cmd, "MAPScan" ) ) { + const char *gametype = gameLocal.serverInfo.GetString( "si_gameType" ); + if ( gametype == NULL || *gametype == 0 || idStr::Icmp( gametype, "singleplayer" ) == 0 ) { + gametype = "Deathmatch"; + } + + int i, num; + idStr si_map = gameLocal.serverInfo.GetString("si_map"); + const idDict *dict; + + mapList->Clear(); + mapList->SetSelection( -1 ); + num = fileSystem->GetNumMaps(); + for ( i = 0; i < num; i++ ) { + dict = fileSystem->GetMapDecl( i ); + if ( dict ) { + // any MP gametype supported + bool isMP = false; + int igt = GAME_SP + 1; + while ( si_gameTypeArgs[ igt ] ) { + if ( dict->GetBool( si_gameTypeArgs[ igt ] ) ) { + isMP = true; + break; + } + igt++; + } + if ( isMP ) { + const char *mapName = dict->GetString( "name" ); + if ( mapName[0] == '\0' ) { + mapName = dict->GetString( "path" ); + } + mapName = gameLocal.m_I18N->Translate( mapName ); + mapList->Add( i, mapName ); + if ( !si_map.Icmp( dict->GetString( "path" ) ) ) { + mapList->SetSelection( mapList->Num() - 1 ); + } + } + } + } + // set the current level shot + SetMapShot( ); + return "continue"; + } else if ( !idStr::Icmp( cmd, "click_maplist" ) ) { + SetMapShot( ); + return "continue"; + } else if ( strstr( cmd, "sound" ) == cmd ) { + // pass that back to the core, will know what to do with it + return _menuCommand; + } + common->Printf( "idMultiplayerGame::HandleGuiCommands: '%s' unknown\n", cmd ); + + } + return "continue"; +} + +/* +================ +idMultiplayerGame::Draw +================ +*/ +bool idMultiplayerGame::Draw( int clientNum ) { + idPlayer *player, *viewPlayer; + + // clear the render entities for any players that don't need + // icons and which might not be thinking because they weren't in + // the last snapshot. + for ( int i = 0; i < gameLocal.numClients; i++ ) { + player = static_cast( gameLocal.entities[ i ] ); + if ( player && !player->NeedsIcon() ) { + player->HidePlayerIcons(); + } + } + + player = viewPlayer = static_cast( gameLocal.entities[ clientNum ] ); + + if ( player == NULL ) { + return false; + } + + if ( player->spectating ) { + viewPlayer = static_cast( gameLocal.entities[ player->spectator ] ); + if ( viewPlayer == NULL ) { + return false; + } + } + + UpdatePlayerRanks(); + UpdateHud( viewPlayer, player->hud ); + // use the hud of the local player + viewPlayer->playerView.RenderPlayerView( player->hud ); + + if ( currentMenu ) { +#if 0 + // uncomment this if you want to track when players are in a menu + if ( !bCurrentMenuMsg ) { + idBitMsg outMsg; + byte msgBuf[ 128 ]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_MENU ); + outMsg.WriteBits( 1, 1 ); + networkSystem->ClientSendReliableMessage( outMsg ); + + bCurrentMenuMsg = true; + } +#endif + if ( player->wantSpectate ) { + mainGui->SetStateString( "spectext", gameLocal.m_I18N->Translate( "#str_04249" ) ); + } else { + mainGui->SetStateString( "spectext", gameLocal.m_I18N->Translate( "#str_04250" ) ); + } + DrawChat(); + if ( currentMenu == 1 ) { + UpdateMainGui(); + mainGui->Redraw( gameLocal.time ); + } else { + msgmodeGui->Redraw( gameLocal.time ); + } + } else { +#if 0 + // uncomment this if you want to track when players are in a menu + if ( bCurrentMenuMsg ) { + idBitMsg outMsg; + byte msgBuf[ 128 ]; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_MENU ); + outMsg.WriteBits( 0, 1 ); + networkSystem->ClientSendReliableMessage( outMsg ); + + bCurrentMenuMsg = false; + } +#endif + if ( player->spectating ) { + idStr spectatetext[ 2 ]; + int ispecline = 0; + if ( gameLocal.gameType == GAME_TOURNEY ) { + if ( !player->wantSpectate ) { + spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_04246" ); + switch ( player->tourneyLine ) { + case 0: + spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07003" ); + break; + case 1: + spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07004" ); + break; + case 2: + spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07005" ); + break; + default: + spectatetext[ 0 ] += va( gameLocal.m_I18N->Translate( "#str_07006" ), player->tourneyLine ); + break; + } + ispecline++; + } + } else if ( gameLocal.gameType == GAME_LASTMAN ) { + if ( !player->wantSpectate ) { + spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_07007" ); + ispecline++; + } + } + if ( player->spectator != player->entityNumber ) { + spectatetext[ ispecline ] = va( gameLocal.m_I18N->Translate( "#str_07008" ), viewPlayer->GetUserInfo()->GetString( "ui_name" ) ); + } else if ( !ispecline ) { + spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_04246" ); + } + spectateGui->SetStateString( "spectatetext0", spectatetext[0].c_str() ); + spectateGui->SetStateString( "spectatetext1", spectatetext[1].c_str() ); + if ( vote != VOTE_NONE ) { + spectateGui->SetStateString( "vote", va( "%s (y: %d n: %d)", voteString.c_str(), (int)yesVotes, (int)noVotes ) ); + } else { + spectateGui->SetStateString( "vote", "" ); + } + spectateGui->Redraw( gameLocal.time ); + } + DrawChat(); + DrawScoreBoard( player ); + } + + return true; +} + +/* +================ +idMultiplayerGame::UpdateHud +================ +*/ +void idMultiplayerGame::UpdateHud( idPlayer *player, idUserInterface *hud ) { + int i; + + if ( !hud ) { + return; + } + + hud->SetStateBool( "warmup", Warmup() ); + + if ( gameState == WARMUP ) { + if ( player->IsReady() ) { + hud->SetStateString( "warmuptext", gameLocal.m_I18N->Translate( "#str_04251" ) ); + } else { + hud->SetStateString( "warmuptext", gameLocal.m_I18N->Translate( "#str_07002" ) ); + } + } + + hud->SetStateString( "timer", ( Warmup() ) ? gameLocal.m_I18N->Translate( "#str_04251" ) : ( gameState == SUDDENDEATH ) ? gameLocal.m_I18N->Translate( "#str_04252" ) : GameTime() ); + if ( vote != VOTE_NONE ) { + hud->SetStateString( "vote", va( "%s (y: %d n: %d)", voteString.c_str(), (int)yesVotes, (int)noVotes ) ); + } else { + hud->SetStateString( "vote", "" ); + } + + hud->SetStateInt( "rank_self", 0 ); + if ( gameState == GAMEON ) { + for ( i = 0; i < numRankedPlayers; i++ ) { + if ( gameLocal.gameType == GAME_TDM ) { + hud->SetStateInt( va( "player%i_score", i+1 ), playerState[ rankedPlayers[ i ]->entityNumber ].teamFragCount ); + } else { + hud->SetStateInt( va( "player%i_score", i+1 ), playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); + } + hud->SetStateInt( va( "rank%i", i+1 ), 1 ); + UpdateRankColor( hud, "rank%i_color%i", i+1, rankedPlayers[ i ]->colorBar ); + if ( rankedPlayers[ i ] == player ) { + hud->SetStateInt( "rank_self", i+1 ); + } + } + } + for ( i = ( gameState == GAMEON ? numRankedPlayers : 0 ) ; i < 5; i++ ) { + hud->SetStateString( va( "player%i", i+1 ), "" ); + hud->SetStateString( va( "player%i_score", i+1 ), "" ); + hud->SetStateInt( va( "rank%i", i+1 ), 0 ); + } +} + +/* +================ +idMultiplayerGame::DrawScoreBoard +================ +*/ +void idMultiplayerGame::DrawScoreBoard( idPlayer *player ) { + if ( player->scoreBoardOpen || gameState == GAMEREVIEW ) { + if ( !playerState[ player->entityNumber ].scoreBoardUp ) { + scoreBoard->Activate( true, gameLocal.time ); + playerState[ player->entityNumber ].scoreBoardUp = true; + } + UpdateScoreboard( scoreBoard, player ); + } else { + if ( playerState[ player->entityNumber ].scoreBoardUp ) { + scoreBoard->Activate( false, gameLocal.time ); + playerState[ player->entityNumber ].scoreBoardUp = false; + } + } +} + +/* +=============== +idMultiplayerGame::ClearChatData +=============== +*/ +void idMultiplayerGame::ClearChatData() { + chatHistoryIndex = 0; + chatHistorySize = 0; + chatDataUpdated = true; +} + +/* +=============== +idMultiplayerGame::AddChatLine +=============== +*/ +void idMultiplayerGame::AddChatLine( const char *fmt, ... ) { + idStr temp; + va_list argptr; + + va_start( argptr, fmt ); + vsprintf( temp, fmt, argptr ); + va_end( argptr ); + + gameLocal.Printf( "%s\n", temp.c_str() ); + + chatHistory[ chatHistoryIndex % NUM_CHAT_NOTIFY ].line = temp; + chatHistory[ chatHistoryIndex % NUM_CHAT_NOTIFY ].fade = 6; + + chatHistoryIndex++; + if ( chatHistorySize < NUM_CHAT_NOTIFY ) { + chatHistorySize++; + } + chatDataUpdated = true; + lastChatLineTime = gameLocal.time; +} + +/* +=============== +idMultiplayerGame::DrawChat +=============== +*/ +void idMultiplayerGame::DrawChat() { + int i, j; + if ( guiChat ) { + if ( gameLocal.time - lastChatLineTime > CHAT_FADE_TIME ) { + if ( chatHistorySize > 0 ) { + for ( i = chatHistoryIndex - chatHistorySize; i < chatHistoryIndex; i++ ) { + chatHistory[ i % NUM_CHAT_NOTIFY ].fade--; + if ( chatHistory[ i % NUM_CHAT_NOTIFY ].fade < 0 ) { + chatHistorySize--; // this assumes the removals are always at the beginning + } + } + chatDataUpdated = true; + } + lastChatLineTime = gameLocal.time; + } + if ( chatDataUpdated ) { + j = 0; + i = chatHistoryIndex - chatHistorySize; + while ( i < chatHistoryIndex ) { + guiChat->SetStateString( va( "chat%i", j ), chatHistory[ i % NUM_CHAT_NOTIFY ].line ); + // don't set alpha above 4, the gui only knows that + guiChat->SetStateInt( va( "alpha%i", j ), Min( 4, (int)chatHistory[ i % NUM_CHAT_NOTIFY ].fade ) ); + j++; i++; + } + while ( j < NUM_CHAT_NOTIFY ) { + guiChat->SetStateString( va( "chat%i", j ), "" ); + j++; + } + guiChat->Activate( true, gameLocal.time ); + chatDataUpdated = false; + } + guiChat->Redraw( gameLocal.time ); + } +} + +const int ASYNC_PLAYER_FRAG_BITS = -idMath::BitsForInteger( MP_PLAYER_MAXFRAGS - MP_PLAYER_MINFRAGS ); // player can have negative frags +const int ASYNC_PLAYER_WINS_BITS = idMath::BitsForInteger( MP_PLAYER_MAXWINS ); +const int ASYNC_PLAYER_PING_BITS = idMath::BitsForInteger( MP_PLAYER_MAXPING ); + +/* +================ +idMultiplayerGame::WriteToSnapshot +================ +*/ +void idMultiplayerGame::WriteToSnapshot( idBitMsgDelta &msg ) const { + int i; + int value; + + msg.WriteByte( gameState ); + msg.WriteShort( currentTourneyPlayer[ 0 ] ); + msg.WriteShort( currentTourneyPlayer[ 1 ] ); + for ( i = 0; i < MAX_CLIENTS; i++ ) { + // clamp all values to min/max possible value that we can send over + value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[i].fragCount ); + msg.WriteBits( value, ASYNC_PLAYER_FRAG_BITS ); + value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[i].teamFragCount ); + msg.WriteBits( value, ASYNC_PLAYER_FRAG_BITS ); + value = idMath::ClampInt( 0, MP_PLAYER_MAXWINS, playerState[i].wins ); + msg.WriteBits( value, ASYNC_PLAYER_WINS_BITS ); + value = idMath::ClampInt( 0, MP_PLAYER_MAXPING, playerState[i].ping ); + msg.WriteBits( value, ASYNC_PLAYER_PING_BITS ); + msg.WriteBits( playerState[i].ingame, 1 ); + } +} + +/* +================ +idMultiplayerGame::ReadFromSnapshot +================ +*/ +void idMultiplayerGame::ReadFromSnapshot( const idBitMsgDelta &msg ) { + int i; + gameState_t newState; + + newState = (idMultiplayerGame::gameState_t)msg.ReadByte(); + if ( newState != gameState ) { + gameLocal.DPrintf( "%s -> %s\n", GameStateStrings[ gameState ], GameStateStrings[ newState ] ); + gameState = newState; + // these could be gathered in a BGNewState() kind of thing, as we have to do them in NewState as well + if ( gameState == GAMEON ) { + matchStartedTime = gameLocal.time; + cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); + switchThrottle[ 1 ] = 0; // passby the throttle + startFragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); + } + } + currentTourneyPlayer[ 0 ] = msg.ReadShort(); + currentTourneyPlayer[ 1 ] = msg.ReadShort(); + for ( i = 0; i < MAX_CLIENTS; i++ ) { + playerState[i].fragCount = msg.ReadBits( ASYNC_PLAYER_FRAG_BITS ); + playerState[i].teamFragCount = msg.ReadBits( ASYNC_PLAYER_FRAG_BITS ); + playerState[i].wins = msg.ReadBits( ASYNC_PLAYER_WINS_BITS ); + playerState[i].ping = msg.ReadBits( ASYNC_PLAYER_PING_BITS ); + playerState[i].ingame = msg.ReadBits( 1 ) != 0; + } +} + +/* +================ +idMultiplayerGame::PlayGlobalSound +================ +*/ +void idMultiplayerGame::PlayGlobalSound( int to, snd_evt_t evt, const char *shader ) { + const idSoundShader *shaderDecl; + + if ( to == -1 || to == gameLocal.localClientNum ) { + if ( shader ) { + gameSoundWorld->PlayShaderDirectly( shader ); + } else { + gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ evt ] ); + } + } + + if ( !gameLocal.isClient ) { + idBitMsg outMsg; + byte msgBuf[1024]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + + if ( shader ) { + shaderDecl = declManager->FindSound( shader ); + if ( !shaderDecl ) { + return; + } + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SOUND_INDEX ); + outMsg.WriteLong( gameLocal.ServerRemapDecl( to, DECL_SOUND, shaderDecl->Index() ) ); + } else { + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SOUND_EVENT ); + outMsg.WriteByte( evt ); + } + + networkSystem->ServerSendReliableMessage( to, outMsg ); + } +} + +/* +================ +idMultiplayerGame::PrintMessageEvent +================ +*/ +void idMultiplayerGame::PrintMessageEvent( int to, msg_evt_t evt, int parm1, int parm2 ) { + switch ( evt ) { + case MSG_SUICIDE: + assert( parm1 >= 0 ); + AddChatLine( gameLocal.m_I18N->Translate( "#str_04293" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + break; + case MSG_KILLED: + assert( parm1 >= 0 && parm2 >= 0 ); + AddChatLine( gameLocal.m_I18N->Translate( "#str_04292" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); + break; + case MSG_KILLEDTEAM: + assert( parm1 >= 0 && parm2 >= 0 ); + AddChatLine( gameLocal.m_I18N->Translate( "#str_04291" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); + break; + case MSG_TELEFRAGGED: + assert( parm1 >= 0 && parm2 >= 0 ); + AddChatLine( gameLocal.m_I18N->Translate( "#str_04290" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); + break; + case MSG_DIED: + assert( parm1 >= 0 ); + AddChatLine( gameLocal.m_I18N->Translate( "#str_04289" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + break; + case MSG_VOTE: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04288" ) ); + break; + case MSG_SUDDENDEATH: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04287" ) ); + break; + case MSG_FORCEREADY: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04286" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + if ( gameLocal.entities[ parm1 ] && gameLocal.entities[ parm1 ]->IsType( idPlayer::Type ) ) { + static_cast< idPlayer * >( gameLocal.entities[ parm1 ] )->forcedReady = true; + } + break; + case MSG_JOINEDSPEC: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04285" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + break; + case MSG_TIMELIMIT: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04284" ) ); + break; + case MSG_FRAGLIMIT: + if ( gameLocal.gameType == GAME_LASTMAN ) { + AddChatLine( gameLocal.m_I18N->Translate( "#str_04283" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + } else if ( gameLocal.gameType == GAME_TDM ) { + AddChatLine( gameLocal.m_I18N->Translate( "#str_04282" ), gameLocal.userInfo[ parm1 ].GetString( "ui_team" ) ); + } else { + AddChatLine( gameLocal.m_I18N->Translate( "#str_04281" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); + } + break; + case MSG_JOINTEAM: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04280" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), parm2 ? gameLocal.m_I18N->Translate( "#str_02500" ) : gameLocal.m_I18N->Translate( "#str_02499" ) ); + break; + case MSG_HOLYSHIT: + AddChatLine( gameLocal.m_I18N->Translate( "#str_06732" ) ); + break; + default: + gameLocal.DPrintf( "PrintMessageEvent: unknown message type %d\n", evt ); + return; + } + if ( !gameLocal.isClient ) { + idBitMsg outMsg; + byte msgBuf[1024]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DB ); + outMsg.WriteByte( evt ); + outMsg.WriteByte( parm1 ); + outMsg.WriteByte( parm2 ); + networkSystem->ServerSendReliableMessage( to, outMsg ); + } +} + +/* +================ +idMultiplayerGame::SuddenRespawns +solely for LMN if an end game ( fragLimitTimeout ) was entered and aborted before expiration +LMN players which still have lives left need to be respawned without being marked lastManOver +================ +*/ +void idMultiplayerGame::SuddenRespawn( void ) { + int i; + + if ( gameLocal.gameType != GAME_LASTMAN ) { + return; + } + + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { + continue; + } + if ( !CanPlay( static_cast< idPlayer * >( gameLocal.entities[ i ] ) ) ) { + continue; + } + if ( static_cast< idPlayer * >( gameLocal.entities[ i ] )->lastManOver ) { + continue; + } + static_cast< idPlayer * >( gameLocal.entities[ i ] )->lastManPlayAgain = true; + } +} + +/* +================ +idMultiplayerGame::CheckSpawns +================ +*/ +void idMultiplayerGame::CheckRespawns( idPlayer *spectator ) { + for( int i = 0 ; i < gameLocal.numClients ; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + idPlayer *p = static_cast(ent); + // once we hit sudden death, nobody respawns till game has ended + if ( WantRespawn( p ) || p == spectator ) { + if ( gameState == SUDDENDEATH && gameLocal.gameType != GAME_LASTMAN ) { + // respawn rules while sudden death are different + // sudden death may trigger while a player is dead, so there are still cases where we need to respawn + // don't do any respawns while we are in end game delay though + if ( !fragLimitTimeout ) { + if ( gameLocal.gameType == GAME_TDM || p->IsLeader() ) { +#ifdef _DEBUG + if ( gameLocal.gameType == GAME_TOURNEY ) { + assert( p->entityNumber == currentTourneyPlayer[ 0 ] || p->entityNumber == currentTourneyPlayer[ 1 ] ); + } +#endif + p->ServerSpectate( false ); + } else if ( !p->IsLeader() ) { + // sudden death is rolling, this player is not a leader, have him spectate + p->ServerSpectate( true ); + CheckAbortGame(); + } + } + } else { + if ( gameLocal.gameType == GAME_DM || + gameLocal.gameType == GAME_TDM ) { + if ( gameState == WARMUP || gameState == COUNTDOWN || gameState == GAMEON ) { + p->ServerSpectate( false ); + } + } else if ( gameLocal.gameType == GAME_TOURNEY ) { + if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { + if ( gameState == WARMUP || gameState == COUNTDOWN || gameState == GAMEON ) { + p->ServerSpectate( false ); + } + } else if ( gameState == WARMUP ) { + // make sure empty tourney slots get filled first + FillTourneySlots( ); + if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { + p->ServerSpectate( false ); + } + } + } else if ( gameLocal.gameType == GAME_LASTMAN ) { + if ( gameState == WARMUP || gameState == COUNTDOWN ) { + p->ServerSpectate( false ); + } else if ( gameState == GAMEON || gameState == SUDDENDEATH ) { + if ( gameState == GAMEON && playerState[ i ].fragCount > 0 && p->lastManPresent ) { + assert( !p->lastManOver ); + p->ServerSpectate( false ); + } else if ( p->lastManPlayAgain && p->lastManPresent ) { + assert( gameState == SUDDENDEATH ); + p->ServerSpectate( false ); + } else { + // if a fragLimitTimeout was engaged, do NOT mark lastManOver as that could mean + // everyone ends up spectator and game is stalled with no end + // if the frag limit delay is engaged and cancels out before expiring, LMN players are + // respawned to play the tie again ( through SuddenRespawn and lastManPlayAgain ) + if ( !fragLimitTimeout && !p->lastManOver ) { + common->DPrintf( "client %d has lost all last man lives\n", i ); + // end of the game for this guy, send him to spectators + p->lastManOver = true; + // clients don't have access to lastManOver + // so set the fragCount to something silly ( used in scoreboard and player ranking ) + playerState[ i ].fragCount = LASTMAN_NOLIVES; + p->ServerSpectate( true ); + + //Check for a situation where the last two player dies at the same time and don't + //try to respawn manually...This was causing all players to go into spectate mode + //and the server got stuck + { + int j; + for ( j = 0; j < gameLocal.numClients; j++ ) { + if ( !gameLocal.entities[ j ] ) { + continue; + } + if ( !CanPlay( static_cast< idPlayer * >( gameLocal.entities[ j ] ) ) ) { + continue; + } + if ( !static_cast< idPlayer * >( gameLocal.entities[ j ] )->lastManOver ) { + break; + } + } + if( j == gameLocal.numClients) { + //Everyone is dead so don't allow this player to spectate + //so the match will end + p->ServerSpectate( false ); + } + } + } + } + } + } + } + } else if ( p->wantSpectate && !p->spectating ) { + playerState[ i ].fragCount = 0; // whenever you willingly go spectate during game, your score resets + p->ServerSpectate( true ); + UpdateTourneyLine(); + CheckAbortGame(); + } + } +} + +/* +================ +idMultiplayerGame::ForceReady +================ +*/ +void idMultiplayerGame::ForceReady( ) { + + for( int i = 0 ; i < gameLocal.numClients ; i++ ) { + idEntity *ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + idPlayer *p = static_cast( ent ); + if ( !p->IsReady() ) { + PrintMessageEvent( -1, MSG_FORCEREADY, i ); + p->forcedReady = true; + } + } +} + +/* +================ +idMultiplayerGame::ForceReady_f +================ +*/ +void idMultiplayerGame::ForceReady_f( const idCmdArgs &args ) { + if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { + common->Printf( "forceReady: multiplayer server only\n" ); + return; + } + gameLocal.mpGame.ForceReady(); +} + +/* +================ +idMultiplayerGame::DropWeapon +================ +*/ +void idMultiplayerGame::DropWeapon( int clientNum ) { + assert( !gameLocal.isClient ); + idEntity *ent = gameLocal.entities[ clientNum ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + return; + } + static_cast< idPlayer* >( ent )->DropWeapon( false ); +} + +/* +================ +idMultiplayerGame::DropWeapon_f +================ +*/ +void idMultiplayerGame::DropWeapon_f( const idCmdArgs &args ) { + if ( !gameLocal.isMultiplayer ) { + common->Printf( "clientDropWeapon: only valid in multiplayer\n" ); + return; + } + idBitMsg outMsg; + byte msgBuf[128]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DROPWEAPON ); + networkSystem->ClientSendReliableMessage( outMsg ); +} + +/* +================ +idMultiplayerGame::MessageMode_f +================ +*/ +void idMultiplayerGame::MessageMode_f( const idCmdArgs &args ) { + gameLocal.mpGame.MessageMode( args ); +} + +/* +================ +idMultiplayerGame::MessageMode +================ +*/ +void idMultiplayerGame::MessageMode( const idCmdArgs &args ) { + const char *mode; + int imode; + + if ( !gameLocal.isMultiplayer ) { + common->Printf( "clientMessageMode: only valid in multiplayer\n" ); + return; + } + if ( !mainGui ) { + common->Printf( "no local client\n" ); + return; + } + mode = args.Argv( 1 ); + if ( !mode[ 0 ] ) { + imode = 0; + } else { + imode = atoi( mode ); + } + msgmodeGui->SetStateString( "messagemode", imode ? "1" : "0" ); + msgmodeGui->SetStateString( "chattext", "" ); + nextMenu = 2; + // let the session know that we want our ingame main menu opened + gameLocal.sessionCommand = "game_startmenu"; +} + +/* +================ +idMultiplayerGame::Vote_f +FIXME: voting from console +================ +*/ +void idMultiplayerGame::Vote_f( const idCmdArgs &args ) { } + +/* +================ +idMultiplayerGame::CallVote_f +FIXME: voting from console +================ +*/ +void idMultiplayerGame::CallVote_f( const idCmdArgs &args ) { } + +/* +================ +idMultiplayerGame::ServerStartVote +================ +*/ +void idMultiplayerGame::ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *value ) { + int i; + + assert( vote == VOTE_NONE ); + + // setup + yesVotes = 1; + noVotes = 0; + vote = voteIndex; + voteValue = value; + voteTimeOut = gameLocal.time + 20000; + // mark players allowed to vote - only current ingame players, players joining during vote will be ignored + for ( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { + playerState[ i ].vote = ( i == clientNum ) ? PLAYER_VOTE_YES : PLAYER_VOTE_WAIT; + } else { + playerState[i].vote = PLAYER_VOTE_NONE; + } + } +} + +/* +================ +idMultiplayerGame::ClientStartVote +================ +*/ +void idMultiplayerGame::ClientStartVote( int clientNum, const char *_voteString ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + if ( !gameLocal.isClient ) { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_STARTVOTE ); + outMsg.WriteByte( clientNum ); + outMsg.WriteString( _voteString ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + } + + voteString = _voteString; + AddChatLine( va( gameLocal.m_I18N->Translate( "#str_04279" ), gameLocal.userInfo[ clientNum ].GetString( "ui_name" ) ) ); + gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE ] ); + if ( clientNum == gameLocal.localClientNum ) { + voted = true; + } else { + voted = false; + } + if ( gameLocal.isClient ) { + // the the vote value to something so the vote line is displayed + vote = VOTE_RESTART; + yesVotes = 1; + noVotes = 0; + } +} + +/* +================ +idMultiplayerGame::ClientUpdateVote +================ +*/ +void idMultiplayerGame::ClientUpdateVote( vote_result_t status, int yesCount, int noCount ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + if ( !gameLocal.isClient ) { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_UPDATEVOTE ); + outMsg.WriteByte( status ); + outMsg.WriteByte( yesCount ); + outMsg.WriteByte( noCount ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + } + + if ( vote == VOTE_NONE ) { + // clients coming in late don't get the vote start and are not allowed to vote + return; + } + + switch ( status ) { + case VOTE_FAILED: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04278" ) ); + gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE_FAILED ] ); + if ( gameLocal.isClient ) { + vote = VOTE_NONE; + } + break; + case VOTE_PASSED: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04277" ) ); + gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE_PASSED ] ); + break; + case VOTE_RESET: + if ( gameLocal.isClient ) { + vote = VOTE_NONE; + } + break; + case VOTE_ABORTED: + AddChatLine( gameLocal.m_I18N->Translate( "#str_04276" ) ); + if ( gameLocal.isClient ) { + vote = VOTE_NONE; + } + break; + default: + break; + } + if ( gameLocal.isClient ) { + yesVotes = yesCount; + noVotes = noCount; + } +} + +/* +================ +idMultiplayerGame::ClientCallVote +================ +*/ +void idMultiplayerGame::ClientCallVote( vote_flags_t voteIndex, const char *voteValue ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + + // send + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CALLVOTE ); + outMsg.WriteByte( voteIndex ); + outMsg.WriteString( voteValue ); + networkSystem->ClientSendReliableMessage( outMsg ); +} + +/* +================ +idMultiplayerGame::CastVote +================ +*/ +void idMultiplayerGame::CastVote( int clientNum, bool castVote ) { + idBitMsg outMsg; + byte msgBuf[ 128 ]; + + if ( clientNum == gameLocal.localClientNum ) { + voted = true; + } + + if ( gameLocal.isClient ) { + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CASTVOTE ); + outMsg.WriteByte( castVote ); + networkSystem->ClientSendReliableMessage( outMsg ); + return; + } + + // sanity + if ( vote == VOTE_NONE ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04275" ) ); + common->DPrintf( "client %d: cast vote while no vote in progress\n", clientNum ); + return; + } + if ( playerState[ clientNum ].vote != PLAYER_VOTE_WAIT ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04274" ) ); + common->DPrintf( "client %d: cast vote - vote %d != PLAYER_VOTE_WAIT\n", clientNum, playerState[ clientNum ].vote ); + return; + } + + if ( castVote ) { + playerState[ clientNum ].vote = PLAYER_VOTE_YES; + yesVotes++; + } else { + playerState[ clientNum ].vote = PLAYER_VOTE_NO; + noVotes++; + } + + ClientUpdateVote( VOTE_UPDATE, static_cast(yesVotes), static_cast(noVotes) ); +} + +/* +================ +idMultiplayerGame::ServerCallVote +================ +*/ +void idMultiplayerGame::ServerCallVote( int clientNum, const idBitMsg &msg ) { + vote_flags_t voteIndex; + int vote_timeLimit, vote_fragLimit, vote_clientNum, vote_gameTypeIndex; //, vote_kickIndex; + char value[ MAX_STRING_CHARS ]; + + assert( clientNum != -1 ); + assert( !gameLocal.isClient ); + + voteIndex = (vote_flags_t)msg.ReadByte( ); + msg.ReadString( value, sizeof( value ) ); + + // sanity checks - setup the vote + if ( vote != VOTE_NONE ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04273" ) ); + common->DPrintf( "client %d: called vote while voting already in progress - ignored\n", clientNum ); + return; + } + switch ( voteIndex ) { + case VOTE_RESTART: + ServerStartVote( clientNum, voteIndex, "" ); + ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04271" ) ); + break; + case VOTE_NEXTMAP: + ServerStartVote( clientNum, voteIndex, "" ); + ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04272" ) ); + break; + case VOTE_TIMELIMIT: + vote_timeLimit = strtol( value, NULL, 10 ); + if ( vote_timeLimit == gameLocal.serverInfo.GetInt( "si_timeLimit" ) ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04270" ) ); + common->DPrintf( "client %d: already at the voted Time Limit\n", clientNum ); + return; + } + if ( vote_timeLimit < si_timeLimit.GetMinValue() || vote_timeLimit > si_timeLimit.GetMaxValue() ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04269" ) ); + common->DPrintf( "client %d: timelimit value out of range for vote: %s\n", clientNum, value ); + return; + } + ServerStartVote( clientNum, voteIndex, value ); + ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04268" ), vote_timeLimit ) ); + break; + case VOTE_FRAGLIMIT: + vote_fragLimit = strtol( value, NULL, 10 ); + if ( vote_fragLimit == gameLocal.serverInfo.GetInt( "si_fragLimit" ) ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04267" ) ); + common->DPrintf( "client %d: already at the voted Frag Limit\n", clientNum ); + return; + } + if ( vote_fragLimit < si_fragLimit.GetMinValue() || vote_fragLimit > si_fragLimit.GetMaxValue() ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04266" ) ); + common->DPrintf( "client %d: fraglimit value out of range for vote: %s\n", clientNum, value ); + return; + } + ServerStartVote( clientNum, voteIndex, value ); + ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04303" ), gameLocal.gameType == GAME_LASTMAN ? gameLocal.m_I18N->Translate( "#str_04264" ) : gameLocal.m_I18N->Translate( "#str_04265" ), vote_fragLimit ) ); + break; + case VOTE_GAMETYPE: + vote_gameTypeIndex = strtol( value, NULL, 10 ); + assert( vote_gameTypeIndex >= 0 && vote_gameTypeIndex <= 3 ); + switch ( vote_gameTypeIndex ) { + case 0: + strcpy( value, "Deathmatch" ); + break; + case 1: + strcpy( value, "Tourney" ); + break; + case 2: + strcpy( value, "Team DM" ); + break; + case 3: + strcpy( value, "Last Man" ); + break; + } + if ( !idStr::Icmp( value, gameLocal.serverInfo.GetString( "si_gameType" ) ) ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04259" ) ); + common->DPrintf( "client %d: already at the voted Game Type\n", clientNum ); + return; + } + ServerStartVote( clientNum, voteIndex, value ); + ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04258" ), value ) ); + break; + case VOTE_KICK: + vote_clientNum = strtol( value, NULL, 10 ); + if ( vote_clientNum == gameLocal.localClientNum ) { + gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04257" ) ); + common->DPrintf( "client %d: called kick for the server host\n", clientNum ); + return; + } + ServerStartVote( clientNum, voteIndex, va( "%d", vote_clientNum ) ); + ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04302" ), vote_clientNum, gameLocal.userInfo[ vote_clientNum ].GetString( "ui_name" ) ) ); + break; + case VOTE_MAP: { + if ( idStr::FindText( gameLocal.serverInfo.GetString( "si_map" ), value ) != -1 ) { + gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04295" ), value ) ); + common->DPrintf( "client %d: already running the voted map: %s\n", clientNum, value ); + return; + } + int num = fileSystem->GetNumMaps(); + int i; + const idDict *dict; + bool haveMap = false; + for ( i = 0; i < num; i++ ) { + dict = fileSystem->GetMapDecl( i ); + if ( dict && !idStr::Icmp( dict->GetString( "path" ), value ) ) { + haveMap = true; + break; + } + } + if ( !haveMap ) { + gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04296" ), value ) ); + common->Printf( "client %d: map not found: %s\n", clientNum, value ); + return; + } + ServerStartVote( clientNum, voteIndex, value ); + ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04256" ), gameLocal.m_I18N->Translate( dict ? dict->GetString( "name" ) : value ) ) ); + break; + } + case VOTE_SPECTATORS: + if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { + ServerStartVote( clientNum, voteIndex, "" ); + ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04255" ) ); + } else { + ServerStartVote( clientNum, voteIndex, "" ); + ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04254" ) ); + } + break; + default: + gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04297" ), (int)voteIndex ) ); + common->DPrintf( "client %d: unknown vote index %d\n", clientNum, voteIndex ); + } +} + +/* +================ +idMultiplayerGame::DisconnectClient +================ +*/ +void idMultiplayerGame::DisconnectClient( int clientNum ) { + if ( lastWinner == clientNum ) { + lastWinner = -1; + } + UpdatePlayerRanks(); + CheckAbortGame(); +} + +/* +================ +idMultiplayerGame::CheckAbortGame +================ +*/ +void idMultiplayerGame::CheckAbortGame( void ) { + int i; + if ( gameLocal.gameType == GAME_TOURNEY && gameState == WARMUP ) { + // if a tourney player joined spectators, let someone else have his spot + for ( i = 0; i < 2; i++ ) { + if ( !gameLocal.entities[ currentTourneyPlayer[ i ] ] || static_cast< idPlayer * >( gameLocal.entities[ currentTourneyPlayer[ i ] ] )->spectating ) { + currentTourneyPlayer[ i ] = -1; + } + } + } + // only checks for aborts -> game review below + if ( gameState != COUNTDOWN && gameState != GAMEON && gameState != SUDDENDEATH ) { + return; + } + switch ( gameLocal.gameType ) { + case GAME_TOURNEY: + for ( i = 0; i < 2; i++ ) { + if ( !gameLocal.entities[ currentTourneyPlayer[ i ] ] || static_cast< idPlayer * >( gameLocal.entities[ currentTourneyPlayer[ i ] ] )->spectating ) { + NewState( GAMEREVIEW ); + return; + } + } + break; + default: + if ( !EnoughClientsToPlay() ) { + NewState( GAMEREVIEW ); + } + break; + } +} + +/* +================ +idMultiplayerGame::WantKilled +================ +*/ +void idMultiplayerGame::WantKilled( int clientNum ) { + idEntity *ent = gameLocal.entities[ clientNum ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + static_cast( ent )->Kill( false, false ); + } +} + +/* +================ +idMultiplayerGame::MapRestart +================ +*/ +void idMultiplayerGame::MapRestart( void ) { + int clientNum; + + assert( !gameLocal.isClient ); + if ( gameState != WARMUP ) { + NewState( WARMUP ); + nextState = INACTIVE; + nextStateSwitch = 0; + } + if ( g_balanceTDM.GetBool() && lastGameType != GAME_TDM && gameLocal.gameType == GAME_TDM ) { + for ( clientNum = 0; clientNum < gameLocal.numClients; clientNum++ ) { + if ( gameLocal.entities[ clientNum ] && gameLocal.entities[ clientNum ]->IsType( idPlayer::Type ) ) { + if ( static_cast< idPlayer* >( gameLocal.entities[ clientNum ] )->BalanceTDM() ) { + // core is in charge of syncing down userinfo changes + // it will also call back game through SetUserInfo with the current info for update + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "updateUI %d\n", clientNum ) ); + } + } + } + } + lastGameType = gameLocal.gameType; +} + +/* +================ +idMultiplayerGame::SwitchToTeam +================ +*/ +void idMultiplayerGame::SwitchToTeam( int clientNum, int oldteam, int newteam ) { + idEntity *ent; + int i; + + assert( gameLocal.gameType == GAME_TDM ); + assert( oldteam != newteam ); + assert( !gameLocal.isClient ); + + if ( !gameLocal.isClient && newteam >= 0 && IsInGame( clientNum ) ) { + PrintMessageEvent( -1, MSG_JOINTEAM, clientNum, newteam ); + } + // assign the right teamFragCount + for( i = 0; i < gameLocal.numClients; i++ ) { + if ( i == clientNum ) { + continue; + } + ent = gameLocal.entities[ i ]; + if ( ent && ent->IsType( idPlayer::Type ) && static_cast< idPlayer * >(ent)->team == newteam ) { + playerState[ clientNum ].teamFragCount = playerState[ i ].teamFragCount; + break; + } + } + if ( i == gameLocal.numClients ) { + // alone on this team + playerState[ clientNum ].teamFragCount = 0; + } + if ( gameState == GAMEON && oldteam != -1 ) { + // when changing teams during game, kill and respawn + idPlayer *p = static_cast( gameLocal.entities[ clientNum ] ); + if ( p->IsInTeleport() ) { + p->ServerSendEvent( idPlayer::EVENT_ABORT_TELEPORTER, NULL, false, -1 ); + p->SetPrivateCameraView( NULL ); + } + p->Kill( true, true ); + CheckAbortGame(); + } +} + +/* +================ +idMultiplayerGame::ProcessChatMessage +================ +*/ +void idMultiplayerGame::ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound ) { + idBitMsg outMsg; + byte msgBuf[ 256 ]; + const char *prefix = NULL; + int send_to; // 0 - all, 1 - specs, 2 - team + int i; + idEntity *ent; + idPlayer *p; + idStr prefixed_name; + + assert( !gameLocal.isClient ); + + if ( clientNum >= 0 ) { + p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); + if ( !( p && p->IsType( idPlayer::Type ) ) ) { + return; + } + + if ( p->spectating ) { + prefix = "spectating"; + if ( team || ( !g_spectatorChat.GetBool() && ( gameState == GAMEON || gameState == SUDDENDEATH ) ) ) { + // to specs + send_to = 1; + } else { + // to all + send_to = 0; + } + } else if ( team ) { + prefix = "team"; + // to team + send_to = 2; + } else { + // to all + send_to = 0; + } + } else { + p = NULL; + send_to = 0; + } + // put the message together + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CHAT ); + if ( prefix ) { + prefixed_name = va( "(%s) %s", prefix, name ); + } else { + prefixed_name = name; + } + outMsg.WriteString( prefixed_name ); + outMsg.WriteString( text, -1, false ); + if ( !send_to ) { + AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); + networkSystem->ServerSendReliableMessage( -1, outMsg ); + if ( sound ) { + PlayGlobalSound( -1, SND_COUNT, sound ); + } + } else { + for ( i = 0; i < gameLocal.numClients; i++ ) { + ent = gameLocal.entities[ i ]; + if ( !ent || !ent->IsType( idPlayer::Type ) ) { + continue; + } + if ( send_to == 1 && static_cast< idPlayer * >( ent )->spectating ) { + if ( sound ) { + PlayGlobalSound( i, SND_COUNT, sound ); + } + if ( i == gameLocal.localClientNum ) { + AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); + } else { + networkSystem->ServerSendReliableMessage( i, outMsg ); + } + } else if ( send_to == 2 && static_cast< idPlayer * >( ent )->team == p->team ) { + if ( sound ) { + PlayGlobalSound( i, SND_COUNT, sound ); + } + if ( i == gameLocal.localClientNum ) { + AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); + } else { + networkSystem->ServerSendReliableMessage( i, outMsg ); + } + } + } + } +} + +/* +================ +idMultiplayerGame::Precache +================ +*/ +void idMultiplayerGame::Precache( void ) { + int i; + idFile *f; + + if ( !gameLocal.isMultiplayer ) { + return; + } + gameLocal.FindEntityDefDict( cv_player_spawnclass.GetString(), false );; + + // skins + idStr str = cvarSystem->GetCVarString( "mod_validSkins" ); + idStr skin; + while ( str.Length() ) { + int n = str.Find( ";" ); + if ( n >= 0 ) { + skin = str.Left( n ); + str = str.Right( str.Length() - n - 1 ); + } else { + skin = str; + str = ""; + } + declManager->FindSkin( skin, false ); + } + + for ( i = 0; ui_skinArgs[ i ]; i++ ) { + declManager->FindSkin( ui_skinArgs[ i ], false ); + } + // MP game sounds + for ( i = 0; i < SND_COUNT; i++ ) { + f = fileSystem->OpenFileRead( GlobalSoundStrings[ i ] ); + fileSystem->CloseFile( f ); + } + // MP guis. just make sure we hit all of them + i = 0; + while ( MPGuis[ i ] ) { + uiManager->FindGui( MPGuis[ i ], true ); + i++; + } +} + +/* +================ +idMultiplayerGame::ToggleSpectate +================ +*/ +void idMultiplayerGame::ToggleSpectate( void ) { + bool spectating; + assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); + + spectating = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_spectate" ), "Spectate" ) == 0 ); + if ( spectating ) { + // always allow toggling to play + cvarSystem->SetCVarString( "ui_spectate", "Play" ); + } else { + // only allow toggling to spectate if spectators are enabled. + if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { + cvarSystem->SetCVarString( "ui_spectate", "Spectate" ); + } else { + gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( "#str_06747" ) ); + } + } +} + +/* +================ +idMultiplayerGame::ToggleReady +================ +*/ +void idMultiplayerGame::ToggleReady( void ) { + bool ready; + assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); + + ready = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_ready" ), "Ready" ) == 0 ); + if ( ready ) { + cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); + } else { + cvarSystem->SetCVarString( "ui_ready", "Ready" ); + } +} + +/* +================ +idMultiplayerGame::ToggleTeam +================ +*/ +void idMultiplayerGame::ToggleTeam( void ) { + bool team; + assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); + + team = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_team" ), "Red" ) == 0 ); + if ( team ) { + cvarSystem->SetCVarString( "ui_team", "Blue" ); + } else { + cvarSystem->SetCVarString( "ui_team", "Red" ); + } +} + +/* +================ +idMultiplayerGame::ToggleUserInfo +================ +*/ +void idMultiplayerGame::ThrottleUserInfo( void ) { + int i; + + assert( gameLocal.localClientNum >= 0 ); + + i = 0; + while ( ThrottleVars[ i ] ) { + if ( idStr::Icmp( gameLocal.userInfo[ gameLocal.localClientNum ].GetString( ThrottleVars[ i ] ), + cvarSystem->GetCVarString( ThrottleVars[ i ] ) ) ) { + if ( gameLocal.realClientTime < switchThrottle[ i ] ) { + AddChatLine( gameLocal.m_I18N->Translate( "#str_04299" ), gameLocal.m_I18N->Translate( ThrottleVarsInEnglish[ i ] ), ( switchThrottle[ i ] - gameLocal.time ) / 1000 + 1 ); + cvarSystem->SetCVarString( ThrottleVars[ i ], gameLocal.userInfo[ gameLocal.localClientNum ].GetString( ThrottleVars[ i ] ) ); + } else { + switchThrottle[ i ] = gameLocal.time + ThrottleDelay[ i ] * 1000; + } + } + i++; + } +} + +/* +================ +idMultiplayerGame::CanPlay +================ +*/ +bool idMultiplayerGame::CanPlay( idPlayer *p ) { + return !p->wantSpectate && playerState[ p->entityNumber ].ingame; +} + +/* +================ +idMultiplayerGame::EnterGame +================ +*/ +void idMultiplayerGame::EnterGame( int clientNum ) { + assert( !gameLocal.isClient ); + + if ( !playerState[ clientNum ].ingame ) { + playerState[ clientNum ].ingame = true; + if ( gameLocal.isMultiplayer ) { + // can't use PrintMessageEvent as clients don't know the nickname yet + gameLocal.ServerSendChatMessage( -1, gameLocal.m_I18N->Translate( "#str_02047" ), va( gameLocal.m_I18N->Translate( "#str_07177" ), gameLocal.userInfo[ clientNum ].GetString( "ui_name" ) ) ); + } + } +} + +/* +================ +idMultiplayerGame::WantRespawn +================ +*/ +bool idMultiplayerGame::WantRespawn( idPlayer *p ) { + return p->forceRespawn && !p->wantSpectate && playerState[ p->entityNumber ].ingame; +} + +/* +================ +idMultiplayerGame::VoiceChat +================ +*/ +void idMultiplayerGame::VoiceChat_f( const idCmdArgs &args ) { + gameLocal.mpGame.VoiceChat( args, false ); +} + +/* +================ +idMultiplayerGame::VoiceChatTeam +================ +*/ +void idMultiplayerGame::VoiceChatTeam_f( const idCmdArgs &args ) { + gameLocal.mpGame.VoiceChat( args, true ); +} + +/* +================ +idMultiplayerGame::VoiceChat +================ +*/ +void idMultiplayerGame::VoiceChat( const idCmdArgs &args, bool team ) { + idBitMsg outMsg; + byte msgBuf[128]; + const char *voc; + const idDict *spawnArgs; + const idKeyValue *keyval; + int index; + + if ( !gameLocal.isMultiplayer ) { + common->Printf( "clientVoiceChat: only valid in multiplayer\n" ); + return; + } + if ( args.Argc() != 2 ) { + common->Printf( "clientVoiceChat: bad args\n" ); + return; + } + // throttle + if ( gameLocal.realClientTime < voiceChatThrottle ) { + return; + } + + voc = args.Argv( 1 ); + spawnArgs = gameLocal.FindEntityDefDict( "player_doommarine", false ); + keyval = spawnArgs->MatchPrefix( "snd_voc_", NULL ); + index = 0; + while ( keyval ) { + if ( !keyval->GetValue().Icmp( voc ) ) { + break; + } + keyval = spawnArgs->MatchPrefix( "snd_voc_", keyval ); + index++; + } + if ( !keyval ) { + common->Printf( "Voice command not found: %s\n", voc ); + return; + } + voiceChatThrottle = gameLocal.realClientTime + 1000; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_VCHAT ); + outMsg.WriteLong( index ); + outMsg.WriteBits( team ? 1 : 0, 1 ); + networkSystem->ClientSendReliableMessage( outMsg ); +} + +/* +================ +idMultiplayerGame::ProcessVoiceChat +================ +*/ +void idMultiplayerGame::ProcessVoiceChat( int clientNum, bool team, int index ) { + const idDict *spawnArgs; + const idKeyValue *keyval; + idStr name; + idStr snd_key; + idStr text_key; + idPlayer *p; + + p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); + if ( !( p && p->IsType( idPlayer::Type ) ) ) { + return; + } + + if ( p->spectating ) { + return; + } + + // lookup the sound def + spawnArgs = gameLocal.FindEntityDefDict( "player_doommarine", false ); + keyval = spawnArgs->MatchPrefix( "snd_voc_", NULL ); + while ( index > 0 && keyval ) { + keyval = spawnArgs->MatchPrefix( "snd_voc_", keyval ); + index--; + } + if ( !keyval ) { + common->DPrintf( "ProcessVoiceChat: unknown chat index %d\n", index ); + return; + } + snd_key = keyval->GetKey(); + name = gameLocal.userInfo[ clientNum ].GetString( "ui_name" ); + sprintf( text_key, "txt_%s", snd_key.Right( snd_key.Length() - 4 ).c_str() ); + if ( team || gameState == COUNTDOWN || gameState == GAMEREVIEW ) { + ProcessChatMessage( clientNum, team, name, spawnArgs->GetString( text_key ), spawnArgs->GetString( snd_key ) ); + } else { + p->StartSound( snd_key, SND_CHANNEL_ANY, 0, true, NULL ); + ProcessChatMessage( clientNum, team, name, spawnArgs->GetString( text_key ), NULL ); + } +} + +/* +================ +idMultiplayerGame::ServerWriteInitialReliableMessages +================ +*/ +void idMultiplayerGame::ServerWriteInitialReliableMessages( int clientNum ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + int i; + idEntity *ent; + + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_STARTSTATE ); + // send the game state and start time + outMsg.WriteByte( gameState ); + outMsg.WriteLong( matchStartedTime ); + outMsg.WriteShort( startFragLimit ); + // send the powerup states and the spectate states + for( i = 0; i < gameLocal.numClients; i++ ) { + ent = gameLocal.entities[ i ]; + if ( i != clientNum && ent && ent->IsType( idPlayer::Type ) ) { + outMsg.WriteShort( i ); +// outMsg.WriteShort( static_cast< idPlayer * >( ent )->inventory.powerups ); + outMsg.WriteBits( static_cast< idPlayer * >( ent )->spectating, 1 ); + } + } + outMsg.WriteShort( MAX_CLIENTS ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + + // we send SI in connectResponse messages, but it may have been modified already + outMsg.BeginWriting( ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SERVERINFO ); + outMsg.WriteDeltaDict( gameLocal.serverInfo, NULL ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + + // warmup time + if ( gameState == COUNTDOWN ) { + outMsg.BeginWriting(); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_WARMUPTIME ); + outMsg.WriteLong( warmupEndTime ); + networkSystem->ServerSendReliableMessage( clientNum, outMsg ); + } +} + +/* +================ +idMultiplayerGame::ClientReadStartState +================ +*/ +void idMultiplayerGame::ClientReadStartState( const idBitMsg &msg ) { + int i, client, powerup; + + // read the state in preparation for reading snapshot updates + gameState = (idMultiplayerGame::gameState_t)msg.ReadByte(); + matchStartedTime = msg.ReadLong( ); + startFragLimit = msg.ReadShort( ); + while ( ( client = msg.ReadShort() ) != MAX_CLIENTS ) { + assert( gameLocal.entities[ client ] && gameLocal.entities[ client ]->IsType( idPlayer::Type ) ); + powerup = msg.ReadShort(); + for ( i = 0; i < MAX_POWERUPS; i++ ) { + if ( powerup & ( 1 << i ) ) { + static_cast< idPlayer * >( gameLocal.entities[ client ] )->GivePowerUp( i, 0 ); + } + } + bool spectate = ( msg.ReadBits( 1 ) != 0 ); + static_cast< idPlayer * >( gameLocal.entities[ client ] )->Spectate( spectate ); + } +} + +/* +================ +idMultiplayerGame::ClientReadWarmupTime +================ +*/ +void idMultiplayerGame::ClientReadWarmupTime( const idBitMsg &msg ) { + warmupEndTime = msg.ReadLong(); +} + diff --git a/game/MultiplayerGame.h b/game/MultiplayerGame.h new file mode 100644 index 000000000..628af25f5 --- /dev/null +++ b/game/MultiplayerGame.h @@ -0,0 +1,366 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MULTIPLAYERGAME_H__ +#define __MULTIPLAYERGAME_H__ + +#ifdef __linux__ +#include "../ui/ListGUI.h" +#endif + +/* +=============================================================================== + + Basic DOOM multiplayer + +=============================================================================== +*/ + +class idPlayer; + +typedef enum { + GAME_SP, + GAME_DM, + GAME_TOURNEY, + GAME_TDM, + GAME_LASTMAN +} gameType_t; + +typedef enum { + PLAYER_VOTE_NONE, + PLAYER_VOTE_NO, + PLAYER_VOTE_YES, + PLAYER_VOTE_WAIT // mark a player allowed to vote +} playerVote_t; + +typedef struct mpPlayerState_s { + int ping; // player ping + int fragCount; // kills + int teamFragCount; // team kills + int wins; // wins + playerVote_t vote; // player's vote + bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui + bool ingame; +} mpPlayerState_t; + +const int NUM_CHAT_NOTIFY = 5; +const int CHAT_FADE_TIME = 400; +const int FRAGLIMIT_DELAY = 2000; + +const int MP_PLAYER_MINFRAGS = -100; +const int MP_PLAYER_MAXFRAGS = 100; +const int MP_PLAYER_MAXWINS = 100; +const int MP_PLAYER_MAXPING = 999; + +typedef struct mpChatLine_s { + idStr line; + short fade; // starts high and decreases, line is removed once reached 0 +} mpChatLine_t; + +typedef enum { + SND_YOUWIN = 0, + SND_YOULOSE, + SND_FIGHT, + SND_VOTE, + SND_VOTE_PASSED, + SND_VOTE_FAILED, + SND_THREE, + SND_TWO, + SND_ONE, + SND_SUDDENDEATH, + SND_COUNT +} snd_evt_t; + +class idMultiplayerGame { +public: + + idMultiplayerGame(); + + void Shutdown( void ); + + // resets everything and prepares for a match + void Reset( void ); + + // setup local data for a new player + void SpawnPlayer( int clientNum ); + + // checks rules and updates state of the mp game + void Run( void ); + + // draws mp hud, scoredboard, etc.. + bool Draw( int clientNum ); + + // updates a player vote + void PlayerVote( int clientNum, playerVote_t vote ); + + // updates frag counts and potentially ends the match in sudden death + void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag ); + + void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3))); + + void UpdateMainGui( void ); + idUserInterface*StartMenu( void ); + const char* HandleGuiCommands( const char *menuCommand ); + void SetMenuSkin( void ); + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + + // game state + typedef enum { + INACTIVE = 0, // not running + WARMUP, // warming up + COUNTDOWN, // post warmup pre-game + GAMEON, // game is on + SUDDENDEATH, // game is on but in sudden death, first frag wins + GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value) + NEXTGAME, + STATE_COUNT + } gameState_t; + static const char *GameStateStrings[ STATE_COUNT ]; + idMultiplayerGame::gameState_t GetGameState( void ) const; + + static const char *GlobalSoundStrings[ SND_COUNT ]; + void PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL ); + + // more compact than a chat line + typedef enum { + MSG_SUICIDE = 0, + MSG_KILLED, + MSG_KILLEDTEAM, + MSG_DIED, + MSG_VOTE, + MSG_VOTEPASSED, + MSG_VOTEFAILED, + MSG_SUDDENDEATH, + MSG_FORCEREADY, + MSG_JOINEDSPEC, + MSG_TIMELIMIT, + MSG_FRAGLIMIT, + MSG_TELEFRAGGED, + MSG_JOINTEAM, + MSG_HOLYSHIT, + MSG_COUNT + } msg_evt_t; + void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 ); + + void DisconnectClient( int clientNum ); + static void ForceReady_f( const idCmdArgs &args ); + static void DropWeapon_f( const idCmdArgs &args ); + static void MessageMode_f( const idCmdArgs &args ); + static void VoiceChat_f( const idCmdArgs &args ); + static void VoiceChatTeam_f( const idCmdArgs &args ); + + typedef enum { + VOTE_RESTART = 0, + VOTE_TIMELIMIT, + VOTE_FRAGLIMIT, + VOTE_GAMETYPE, + VOTE_KICK, + VOTE_MAP, + VOTE_SPECTATORS, + VOTE_NEXTMAP, + VOTE_COUNT, + VOTE_NONE + } vote_flags_t; + + typedef enum { + VOTE_UPDATE, + VOTE_FAILED, + VOTE_PASSED, // passed, but no reset yet + VOTE_ABORTED, + VOTE_RESET // tell clients to reset vote state + } vote_result_t; + + static void Vote_f( const idCmdArgs &args ); + static void CallVote_f( const idCmdArgs &args ); + void ClientCallVote( vote_flags_t voteIndex, const char *voteValue ); + void ServerCallVote( int clientNum, const idBitMsg &msg ); + void ClientStartVote( int clientNum, const char *voteString ); + void ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue ); + void ClientUpdateVote( vote_result_t result, int yesCount, int noCount ); + void CastVote( int clientNum, bool vote ); + void ExecuteVote( void ); + + void WantKilled( int clientNum ); + int NumActualClients( bool countSpectators, int *teamcount = NULL ); + void DropWeapon( int clientNum ); + void MapRestart( void ); + // called by idPlayer whenever it detects a team change (init or switch) + void SwitchToTeam( int clientNum, int oldteam, int newteam ); + bool IsPureReady( void ) const; + void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound ); + void ProcessVoiceChat( int clientNum, bool team, int index ); + + void Precache( void ); + + // throttle UI switch rates + void ThrottleUserInfo( void ); + void ToggleSpectate( void ); + void ToggleReady( void ); + void ToggleTeam( void ); + + void ClearFrags( int clientNum ); + + void EnterGame( int clientNum ); + bool CanPlay( idPlayer *p ); + bool IsInGame( int clientNum ); + bool WantRespawn( idPlayer *p ); + + void ServerWriteInitialReliableMessages( int clientNum ); + void ClientReadStartState( const idBitMsg &msg ); + void ClientReadWarmupTime( const idBitMsg &msg ); + + void ServerClientConnect( int clientNum ); + + void PlayerStats( int clientNum, char *data, const int len ); + +private: + static const char *MPGuis[]; + static const char *ThrottleVars[]; + static const char *ThrottleVarsInEnglish[]; + static const int ThrottleDelay[]; + + // state vars + gameState_t gameState; // what state the current game is in + gameState_t nextState; // state to switch to when nextStateSwitch is hit + int pingUpdateTime; // time to update ping + + mpPlayerState_t playerState[ MAX_CLIENTS ]; + + // keep track of clients which are willingly in spectator mode + + // vote vars + vote_flags_t vote; // active vote or VOTE_NONE + int voteTimeOut; // when the current vote expires + int voteExecTime; // delay between vote passed msg and execute + float yesVotes; // counter for yes votes + float noVotes; // and for no votes + idStr voteValue; // the data voted upon ( server ) + idStr voteString; // the vote string ( client ) + bool voted; // hide vote box ( client ) + int kickVoteMap[ MAX_CLIENTS ]; + + // time related + int nextStateSwitch; // time next state switch + int warmupEndTime; // warmup till.. + int matchStartedTime; // time current match started + + // tourney + int currentTourneyPlayer[2];// our current set of players + int lastWinner; // plays again + + // warmup + idStr warmupText; // text shown in warmup area of screen + bool one, two, three; // keeps count down voice from repeating + + // guis + idUserInterface *scoreBoard; // scoreboard + idUserInterface *spectateGui; // spectate info + idUserInterface *guiChat; // chat text + idUserInterface *mainGui; // ready / nick / votes etc. + idListGUI *mapList; + idUserInterface *msgmodeGui; // message mode + int currentMenu; // 0 - none, 1 - mainGui, 2 - msgmodeGui + int nextMenu; // if 0, will do mainGui + bool bCurrentMenuMsg; // send menu state updates to server + + // chat data + mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ]; + int chatHistoryIndex; + int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY + bool chatDataUpdated; + int lastChatLineTime; + + // rankings are used by UpdateScoreboard and UpdateHud + int numRankedPlayers; // ranked players, others may be empty slots or spectators + idPlayer * rankedPlayers[MAX_CLIENTS]; + + bool pureReady; // defaults to false, set to true once server game is running with pure checksums + int fragLimitTimeout; + + int switchThrottle[ 3 ]; + int voiceChatThrottle; + + gameType_t lastGameType; // for restarts + int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON + +private: + void UpdatePlayerRanks(); + + // updates the passed gui with current score information + void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec ); + void UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player ); + + void ClearGuis( void ); + void DrawScoreBoard( idPlayer *player ); + void UpdateHud( idPlayer *player, idUserInterface *hud ); + bool Warmup( void ); + void CheckVote( void ); + bool AllPlayersReady( void ); + idPlayer * FragLimitHit( void ); + idPlayer * FragLeader( void ); + bool TimeLimitHit( void ); + void NewState( gameState_t news, idPlayer *player = NULL ); + void UpdateWinsLosses( idPlayer *winner ); + // fill any empty tourney slots based on the current tourney ranks + void FillTourneySlots( void ); + void CycleTourneyPlayers( void ); + // walk through the tourneyRank to build a wait list for the clients + void UpdateTourneyLine( void ); + const char * GameTime( void ); + void Clear( void ); + bool EnoughClientsToPlay( void ); + void ClearChatData( void ); + void DrawChat( void ); + // go through the clients, and see if they want to be respawned, and if the game allows it + // called during normal gameplay for death -> respawn cycles + // and for a spectator who want back in the game (see param) + void CheckRespawns( idPlayer *spectator = NULL ); + void ForceReady(); + // when clients disconnect or join spectate during game, check if we need to end the game + void CheckAbortGame( void ); + void MessageMode( const idCmdArgs &args ); + void DisableMenu( void ); + void SetMapShot( void ); + // scores in TDM + void TeamScore( int entityNumber, int team, int delta ); + void VoiceChat( const idCmdArgs &args, bool team ); + void DumpTourneyLine( void ); + void SuddenRespawn( void ); +}; + +ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const { + return gameState; +} + +ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const { + return pureReady; +} + +ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) { + playerState[ clientNum ].fragCount = 0; +} + +ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) { + return playerState[ clientNum ].ingame; +} + +#endif /* !__MULTIPLAYERGAME_H__ */ + diff --git a/game/Objectives/BoolParseNode.h b/game/Objectives/BoolParseNode.h new file mode 100644 index 000000000..88ad1d62e --- /dev/null +++ b/game/Objectives/BoolParseNode.h @@ -0,0 +1,74 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef TDM_OBJECTIVE_BOOLPARSENODE_H +#define TDM_OBJECTIVE_BOOLPARSENODE_H + +#include "../../idlib/precompiled.h" + +/** +* Structure for parsing boolean logic +**/ +struct SBoolParseNode +{ + int Ident; + bool bNotted; // set to true if this node is NOTed + + idList< idList< SBoolParseNode > > Cols; // list of columns, each can contain a different number of rows + + // Link back to previous node this one branched off from + SBoolParseNode* PrevNode; + + // matrix coordinates of this node within the matrix of the previous node + int PrevCol; + int PrevRow; + + // Functions: + + SBoolParseNode() + { + Clear(); + } + + ~SBoolParseNode() + { + Clear(); + } + + bool IsEmpty() const + { + return (Cols.Num() == 0 && Ident == -1); + } + + /** + * Clear the parse node + **/ + void Clear( void ) + { + Ident = -1; + PrevCol = -1; + PrevRow = -1; + + bNotted = false; + Cols.Clear(); + PrevNode = NULL; + } +}; + +#endif diff --git a/game/Objectives/CampaignStatistics.cpp b/game/Objectives/CampaignStatistics.cpp new file mode 100644 index 000000000..b7c2f87c6 --- /dev/null +++ b/game/Objectives/CampaignStatistics.cpp @@ -0,0 +1,55 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "CampaignStatistics.h" + +void CampaignStats::Save(idSaveGame* savefile) const +{ + savefile->WriteInt(_stats.Num()); + + for (int i = 0; i < _stats.Num(); ++i) + { + _stats[i].Save(savefile); + } +} + +void CampaignStats::Restore(idRestoreGame* savefile) +{ + int num; + savefile->ReadInt(num); + _stats.SetNum(num); + + for (int i = 0; i < num; ++i) + { + _stats[i].Restore(savefile); + } +} + +void CampaignStats::EnsureSize(int size) +{ + if (_stats.Num() < size) + { + _stats.SetNum(size); + } +} diff --git a/game/Objectives/CampaignStatistics.h b/game/Objectives/CampaignStatistics.h new file mode 100644 index 000000000..abde39924 --- /dev/null +++ b/game/Objectives/CampaignStatistics.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef TDM_CAMPAIGN_STATISTICS_H +#define TDM_CAMPAIGN_STATISTICS_H + +#include "../../idlib/precompiled.h" + +#include "MissionStatistics.h" + +/** + * Multiple mission stats structs combined => campaign stats. + * First mission is carrying index 0. + */ +class CampaignStats +{ +private: + // The internal array of statistics + idList _stats; + +public: + // greebo: Use this operator to get access to the stats of the mission with the given index + // The internal list will automatically be resized to fit. + MissionStatistics& operator[] (int index) + { + EnsureSize(index + 1); + return _stats[index]; + } + + const MissionStatistics& operator[] (int index) const + { + return _stats[index]; + } + + int Num() const + { + return _stats.Num(); + } + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + +private: + void EnsureSize(int size); +}; + +#endif diff --git a/game/Objectives/EMissionResult.h b/game/Objectives/EMissionResult.h new file mode 100644 index 000000000..c743f42ce --- /dev/null +++ b/game/Objectives/EMissionResult.h @@ -0,0 +1,30 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef EMISSIONRESULT_H_ +#define EMISSIONRESULT_H_ + +enum EMissionResult { + MISSION_NOTEVENSTARTED = 0, // before any map is loaded (at game startup, for instance) + MISSION_INPROGRESS = 1, // mission not yet accomplished (in-game) + MISSION_FAILED = 2, // mission failed + MISSION_COMPLETE = 3, // mission completed +}; + +#endif /*EMISSIONRESULT_H_*/ diff --git a/DarkMod/Objectives/MissionData.cpp b/game/Objectives/MissionData.cpp similarity index 98% rename from DarkMod/Objectives/MissionData.cpp rename to game/Objectives/MissionData.cpp index 20b14d46c..87906819e 100644 --- a/DarkMod/Objectives/MissionData.cpp +++ b/game/Objectives/MissionData.cpp @@ -1,25 +1,35 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop -#include "../game/game_local.h" +#include "../Game_local.h" static bool init_version = FileVersionList("$Id$", init_version); #pragma warning(disable : 4996) #include "MissionData.h" -#include "../AI/Memory.h" +#include "../ai/Memory.h" #include "../DifficultyManager.h" -#include "../../game/player.h" +#include "../Player.h" #include "../StimResponse/StimResponseCollection.h" #include "../Missions/MissionManager.h" diff --git a/DarkMod/Objectives/MissionData.h b/game/Objectives/MissionData.h similarity index 95% rename from DarkMod/Objectives/MissionData.h rename to game/Objectives/MissionData.h index 335c42110..ead06973c 100644 --- a/DarkMod/Objectives/MissionData.h +++ b/game/Objectives/MissionData.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2006 Chris Sarantos @@ -19,7 +29,7 @@ #ifndef MISSIONDATA_H #define MISSIONDATA_H -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #include "Objective.h" #include "ObjectiveComponent.h" @@ -48,7 +58,7 @@ enum EMissionEventType EVENT_INVALID, }; -// TODO: move to game_local.h? +// TODO: move to Game_local.h? struct SObjEntParms { idStr name; diff --git a/DarkMod/Objectives/MissionStatistics.cpp b/game/Objectives/MissionStatistics.cpp similarity index 86% rename from DarkMod/Objectives/MissionStatistics.cpp rename to game/Objectives/MissionStatistics.cpp index c485ce23f..5b3d7ceca 100644 --- a/DarkMod/Objectives/MissionStatistics.cpp +++ b/game/Objectives/MissionStatistics.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/Objectives/MissionStatistics.h b/game/Objectives/MissionStatistics.h new file mode 100644 index 000000000..f7593e280 --- /dev/null +++ b/game/Objectives/MissionStatistics.h @@ -0,0 +1,109 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef MISSIONSTATISTICS_H +#define MISSIONSTATISTICS_H + +#include "../../idlib/precompiled.h" + +#include "Objective.h" // for objective state enum +#include "../Inventory/LootType.h" // for loot type enum + +// Maximum array sizes: +#define MAX_TEAMS 64 +#define MAX_TYPES 16 +#define MAX_AICOMP 16 +#define MAX_ALERTLEVELS 16 + +struct SStat +{ + int Overall; + int ByTeam[ MAX_TEAMS ]; + int ByType[ MAX_TYPES ]; + int ByInnocence[2]; + int WhileAirborne; + + SStat() + { + Clear(); + } + + void Clear(); +}; + +/** +* Mission stats: Keep track of everything except for loot groups, which are tracked by the inventory +**/ +class MissionStatistics +{ +public: + // AI Stats: + SStat AIStats[ MAX_AICOMP ]; + + SStat AIAlerts[ MAX_ALERTLEVELS ]; + + int DamageDealt; + int DamageReceived; + int HealthReceived; + int PocketsPicked; + + // Item stats are handled by the inventory, not here, + // Might need this for copying over to career stats though + int FoundLoot[LOOT_COUNT]; + + // greebo: This is the available amount of loot in the mission + int LootInMission[LOOT_COUNT]; + + // This gets read out right at "mission complete" time, is 0 before + unsigned int TotalGamePlayTime; + + // Use an array to store the objective states after mission complete + // We need the historic state data to handle conditional objectives. + // This list will be empty throughout the mission, and is filled on mission complete + idList ObjectiveStates; + + // grayman #2887 - for tracking how often and for how long the player was seen + int numberTimesPlayerSeen; + int totalTimePlayerSeen; + + MissionStatistics() + { + Clear(); + } + + void Clear(); + + // Returns the state of the objective specified by the (0-based) index + // Will return INVALID if the objective index is out of bounds or no data is available + EObjCompletionState GetObjectiveState(int objNum) const; + + // Store the objective state into the ObjectiveStates array + void SetObjectiveState(int objNum, EObjCompletionState state); + + // Returns the sum of all found loot types (gold+jewels+goods) + int GetFoundLootValue() const; + + // Returns the total of all loot types in the mission (gold+jewels+goods) + int GetTotalLootInMission() const; + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); +}; + +#endif /* MISSIONSTATISTICS_H */ diff --git a/DarkMod/Objectives/Objective.cpp b/game/Objectives/Objective.cpp similarity index 86% rename from DarkMod/Objectives/Objective.cpp rename to game/Objectives/Objective.cpp index 54ceb7de2..0e3cac12f 100644 --- a/DarkMod/Objectives/Objective.cpp +++ b/game/Objectives/Objective.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/Objectives/Objective.h b/game/Objectives/Objective.h similarity index 81% rename from DarkMod/Objectives/Objective.h rename to game/Objectives/Objective.h index d70949c34..1ed4eeeda 100644 --- a/DarkMod/Objectives/Objective.h +++ b/game/Objectives/Objective.h @@ -1,16 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef TDM_OBJECTIVE_H #define TDM_OBJECTIVE_H -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #include "BoolParseNode.h" #include "ObjectiveComponent.h" diff --git a/DarkMod/Objectives/ObjectiveComponent.cpp b/game/Objectives/ObjectiveComponent.cpp similarity index 80% rename from DarkMod/Objectives/ObjectiveComponent.cpp rename to game/Objectives/ObjectiveComponent.cpp index dbc5b72e1..a64f1d67d 100644 --- a/DarkMod/Objectives/ObjectiveComponent.cpp +++ b/game/Objectives/ObjectiveComponent.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/Objectives/ObjectiveComponent.h b/game/Objectives/ObjectiveComponent.h similarity index 84% rename from DarkMod/Objectives/ObjectiveComponent.h rename to game/Objectives/ObjectiveComponent.h index 6c749e1df..29fbaa217 100644 --- a/DarkMod/Objectives/ObjectiveComponent.h +++ b/game/Objectives/ObjectiveComponent.h @@ -1,16 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef TDM_OBJECTIVE_COMPONENT_H #define TDM_OBJECTIVE_COMPONENT_H -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" /** * Objective component action types diff --git a/DarkMod/Objectives/ObjectiveCondition.cpp b/game/Objectives/ObjectiveCondition.cpp similarity index 84% rename from DarkMod/Objectives/ObjectiveCondition.cpp rename to game/Objectives/ObjectiveCondition.cpp index 180296004..92acf3e74 100644 --- a/DarkMod/Objectives/ObjectiveCondition.cpp +++ b/game/Objectives/ObjectiveCondition.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop #include "MissionData.h" diff --git a/game/Objectives/ObjectiveCondition.h b/game/Objectives/ObjectiveCondition.h new file mode 100644 index 000000000..88b3fd43c --- /dev/null +++ b/game/Objectives/ObjectiveCondition.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef TDM_OBJECTIVE_CONDITION_H +#define TDM_OBJECTIVE_CONDITION_H + +#include "../../idlib/precompiled.h" + +#include "Objective.h" + +class CMissionData; + +class ObjectiveCondition +{ +private: + // Possible effect types + enum Type + { + CHANGE_STATE, // changes state of target objective + CHANGE_VISIBILITY, // changes visibility of target objective + CHANGE_MANDATORY, // changes mandatory flag of target objetive + INVALID_TYPE, // not a valid type + }; + + Type _type; + + int _value; + int _srcMission; + EObjCompletionState _srcState; + int _srcObj; + int _targetObj; + +public: + // Default constructor + ObjectiveCondition(); + + // Construct from a given dictionary + ObjectiveCondition(const idDict& dict, int index); + + // Returns TRUE if the condition has enough valid parameters to be functional + bool IsValid() const; + + // Applies this conditional action to the given objectives + // Returns TRUE if the condition was applicable, FALSE otherwise + bool Apply(CMissionData& missionData); + +private: + void ParseFromSpawnargs(const idDict& dict, int index); +}; + +#endif diff --git a/DarkMod/Objectives/ObjectiveLocation.cpp b/game/Objectives/ObjectiveLocation.cpp similarity index 89% rename from DarkMod/Objectives/ObjectiveLocation.cpp rename to game/Objectives/ObjectiveLocation.cpp index dde14b6e8..c47fcbd26 100644 --- a/DarkMod/Objectives/ObjectiveLocation.cpp +++ b/game/Objectives/ObjectiveLocation.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/Objectives/ObjectiveLocation.h b/game/Objectives/ObjectiveLocation.h new file mode 100644 index 000000000..8cab5db0a --- /dev/null +++ b/game/Objectives/ObjectiveLocation.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef TDM_OBJECTIVE_LOCATION_H +#define TDM_OBJECTIVE_LOCATION_H + +#include "../../idlib/precompiled.h" + +// Helper entity for objective locations +class CObjectiveLocation : public idEntity +{ +public: + CLASS_PROTOTYPE( CObjectiveLocation ); + + CObjectiveLocation(); + + ~CObjectiveLocation(); + + void Think( void ); + void Spawn( void ); + + // Called by ~idEntity to catch entity destructions + void OnEntityDestroyed(idEntity* ent); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +protected: + /** + * Clock interval [seconds] + **/ + int m_Interval; + + int m_TimeStamp; + + /** + * List of entity names that intersected bounds in previous clock tick + **/ + idList< idEntityPtr > m_EntsInBounds; + /** + * Objective system: Location's objective group name for objective checks + **/ + idStr m_ObjectiveGroup; + +private: + idClipModel * clipModel; + +}; // CObjectiveLocation + +#endif diff --git a/game/OverlaySys.cpp b/game/OverlaySys.cpp new file mode 100644 index 000000000..3e8feca4d --- /dev/null +++ b/game/OverlaySys.cpp @@ -0,0 +1,626 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +#include "OverlaySys.h" + +// I'm keeping these functions seperate from the overlaysys code, +// in case I end up needing to implement recycling. +static inline idUserInterface* newGui(const char* file) +{ + //return uiManager->FindGui( file, true, false, true ); + return uiManager->FindGui(file, true, true); +} +static inline void delGui(idUserInterface* gui) +{ + uiManager->DeAlloc(gui); +} + +COverlaySys::COverlaySys() +{ + m_lastUsedHandle = 0; + m_lastUsedOverlay = NULL; + m_updateOpaque = false; + m_highestOpaque = NULL; + m_updateInteractive = false; + m_highestInteractive = NULL; + m_nextHandle = OVERLAYS_MIN_HANDLE; +} + +COverlaySys::~COverlaySys() +{ + SOverlay* overlay; + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + overlay = oNode->Owner(); + oNode = oNode->NextNode(); + + if (!overlay->m_external) + delGui(overlay->m_gui); + + delete overlay; + } +} + +void COverlaySys::Save( idSaveGame *savefile ) const +{ + SOverlay* overlay; + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + overlay = oNode->Owner(); + savefile->WriteInt( overlay->m_handle ); + savefile->WriteInt( overlay->m_layer ); + savefile->WriteBool( overlay->m_external ); + savefile->WriteBool( overlay->m_opaque ); + savefile->WriteBool( overlay->m_interactive ); + if ( !overlay->m_external ) + savefile->WriteUserInterface( overlay->m_gui, false ); + + oNode = oNode->NextNode(); + } + savefile->WriteInt( OVERLAYS_INVALID_HANDLE ); +} + +void COverlaySys::Restore( idRestoreGame *savefile ) +{ + int handle; + SOverlay* overlay; + + savefile->ReadInt( handle ); + while(handle >= OVERLAYS_MIN_HANDLE) + { + overlay = new SOverlay; + if(!overlay) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to allocate SOverlay.\r"); + goto Quit; + } + + overlay->m_node.SetOwner( overlay ); + overlay->m_node.AddToEnd( m_overlays ); + overlay->m_handle = handle; + savefile->ReadInt( overlay->m_layer ); + savefile->ReadBool( overlay->m_external ); + savefile->ReadBool( overlay->m_opaque ); + savefile->ReadBool( overlay->m_interactive ); + if (overlay->m_external) + overlay->m_gui = NULL; // I don't think there's a way to save/restore pointers to GUIs saved by other things. + else + savefile->ReadUserInterface(overlay->m_gui); + + savefile->ReadInt(handle); + } + + m_updateOpaque = m_updateInteractive = true; + +Quit: + return; +} + +void COverlaySys::drawOverlays() +{ + idUserInterface* gui; + idLinkList* oNode = findOpaque(); + if(!oNode) + oNode = m_overlays.NextNode(); + + while(oNode) + { + gui = oNode->Owner()->m_gui; + if(gui) + { + gameLocal.UpdateGUIScaling(gui); + + int time = gameLocal.realClientTime; + + // greebo: We have a special GUI that is updated before control is passed to this method + // there is a time offset stored in that GUI, add that to the realClientTime. + time += gui->GetStateInt("GuiTimeOffset"); + + gui->Redraw(time); + } + oNode = oNode->NextNode(); + } +} + +bool COverlaySys::isOpaque() { + return findOpaque() != NULL; +} + +int COverlaySys::getNextOverlay( int handle ) +{ + int retHandle = OVERLAYS_INVALID_HANDLE; + + idLinkList *oNode; + SOverlay *overlay = findOverlay( handle, false ); + if(overlay) + oNode = overlay->m_node.NextNode(); + else if(handle == OVERLAYS_INVALID_HANDLE) + oNode = m_overlays.NextNode(); + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getNextOverlay: Non-existant GUI handle: %d\r", handle); + return retHandle; + } + + if(oNode) + { + m_lastUsedOverlay = oNode->Owner(); + m_lastUsedHandle = m_lastUsedOverlay->m_handle; + retHandle = m_lastUsedHandle; + } + + return retHandle; +} + +int COverlaySys::createOverlay( int layer, int handle ) +{ + assert( handle >= OVERLAYS_MIN_HANDLE || handle == OVERLAYS_INVALID_HANDLE ); + + int retHandle = OVERLAYS_INVALID_HANDLE; + + // Find a valid handle for our overlay. + idLinkList* oNode; + if(handle == OVERLAYS_INVALID_HANDLE) + { + // Any handle will do. + bool foundHandle = false; + + // Iterate through all available handles until we come back to where we started. + handle = m_nextHandle; + do + { + // Check if the overlay has the handle. + oNode = m_overlays.NextNode(); + while(oNode) + { + if(oNode->Owner()->m_handle == handle) + break; + oNode = oNode->NextNode(); + } + + // If we went all the way through the loop, the handle doesn't already exist. + if(!oNode) + { + foundHandle = true; + break; + } + + handle++; + if(handle < OVERLAYS_MIN_HANDLE) + handle = OVERLAYS_MIN_HANDLE; + } while(handle != m_nextHandle); + + if(!foundHandle) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("No more handles available.\r"); + return retHandle; + } + + m_nextHandle = handle + 1; + if ( m_nextHandle < OVERLAYS_MIN_HANDLE ) + m_nextHandle = OVERLAYS_MIN_HANDLE; + + } + else + { + // There's a specific handle that is desired. + oNode = m_overlays.NextNode(); + while(oNode) + { + // If the handle is unavailable, don't create anything. + if(oNode->Owner()->m_handle == handle) + return retHandle; + + oNode = oNode->NextNode(); + } + } + + // At this point, 'handle' is the handle our overlay will have. + + // Find the position after which we will insert our overlay. + idLinkList* position = &m_overlays; // The position after which we will insert the new overlay + oNode = m_overlays.NextNode(); + while(oNode) + { + if(layer >= oNode->Owner()->m_layer) + position = oNode; + + oNode = oNode->NextNode(); + } + + SOverlay* overlay = new SOverlay; + if(!overlay) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to allocate overlay.\r"); + return retHandle; + } + + overlay->m_node.SetOwner( overlay ); + overlay->m_node.InsertAfter( *position ); + overlay->m_gui = NULL; + overlay->m_handle = handle; + overlay->m_layer = layer; + overlay->m_external = true; + overlay->m_opaque = false; + overlay->m_interactive = false; + + return handle; +} + +void COverlaySys::destroyOverlay( int handle ) +{ + SOverlay* overlay = findOverlay( handle, false ); + if ( overlay == NULL ) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + goto Quit; + } + + // If the last-used cache points to the overlay, clear it. + if(m_lastUsedOverlay == overlay) + { + m_lastUsedHandle = OVERLAYS_INVALID_HANDLE; + m_lastUsedOverlay = NULL; // not necessary, but perhaps safer + } + + // If this was an opaque overlay, we need to update opacity. + if(overlay->m_opaque) + m_updateOpaque = true; + + // If this was an interactive overlay, we need to update interactivity. + if (overlay->m_interactive) + m_updateInteractive = true; + + if (!overlay->m_external) + delGui(overlay->m_gui); + + delete overlay; + +Quit: + return; +} + +/// Returns whether or not an overlay exists. +bool COverlaySys::exists(int handle) +{ + return findOverlay(handle) != NULL; +} + +/// Sets the overlay's GUI to an external GUI. +void COverlaySys::setGui(int handle, idUserInterface* gui) +{ + SOverlay* overlay = findOverlay(handle); + if(overlay) + { + if(!overlay->m_external) + { + delGui( overlay->m_gui ); + overlay->m_external = true; + } + + overlay->m_gui = gui; + } + else + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); +} + +/// Sets the overlay's GUI to an internal, unique one. +bool COverlaySys::setGui( int handle, const char* file ) +{ + bool retVal = false; + SOverlay* overlay = findOverlay( handle ); + if(overlay) + { + idUserInterface* gui = newGui(file); + if(gui) + { + if(!overlay->m_external) + delGui(overlay->m_gui); + + overlay->m_gui = gui; + overlay->m_external = false; + retVal = true; + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load gui: %s\r", file); + goto Quit; + } + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d [%s]\r", handle, file); + goto Quit; + } + +Quit: + return retVal; +} + +idUserInterface* COverlaySys::getGui(int handle) +{ + SOverlay* overlay = findOverlay(handle); + if ( overlay ) + return overlay->m_gui; + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + return NULL; + } +} + +void COverlaySys::setLayer( int handle, int layer ) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + // Find the new spot for the overlay. + idLinkList* position = &m_overlays; // insert the new overlay AFTER this position + idLinkList* oNode = m_overlays.NextNode(); + while ( oNode ) + { + if ( layer >= oNode->Owner()->m_layer ) + position = oNode; + oNode = oNode->NextNode(); + } + + // Did we actually change positions? + if ( position->Next() != overlay && position != &overlay->m_node ) + { + overlay->m_node.InsertAfter( *position ); + overlay->m_layer = layer; + + // If this is an opaque overlay, we need to update opacity. + if ( overlay->m_opaque ) + m_updateOpaque = true; + + // If this is an interactive overlay, we need to update interactivity. + if ( overlay->m_interactive ) + m_updateInteractive = true; + } + + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + } +} + +int COverlaySys::getLayer( int handle ) +{ + SOverlay* overlay = findOverlay( handle ); + if(overlay) + return overlay->m_layer; + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + return 0; + } +} + +bool COverlaySys::isExternal(int handle) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + return overlay->m_external; + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + return false; + } +} + +void COverlaySys::setOpaque( int handle, bool isOpaque ) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + if ( overlay->m_opaque != isOpaque ) + { + overlay->m_opaque = isOpaque; + m_updateOpaque = true; + } + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + } +} + +bool COverlaySys::isOpaque( int handle ) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + return overlay->m_opaque; + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + return false; + } +} + +void COverlaySys::setInteractive( int handle, bool isInteractive ) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + if ( overlay->m_interactive != isInteractive ) + { + overlay->m_interactive = isInteractive; + m_updateInteractive = true; + } + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + } +} + +bool COverlaySys::isInteractive( int handle ) +{ + SOverlay* overlay = findOverlay( handle ); + if ( overlay ) + { + return overlay->m_interactive; + } + else + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("getGui: Non-existant GUI handle: %d\r", handle); + return false; + } +} + +SOverlay* COverlaySys::findOverlay( int handle, bool updateCache ) +{ + SOverlay* retVal = NULL; + + if ( handle < OVERLAYS_MIN_HANDLE ) + return NULL; + + // Are we looking for the same handle as last time? + if ( handle == m_lastUsedHandle ) + { + return m_lastUsedOverlay; + } + + idLinkList* oNode = m_overlays.NextNode(); + while ( oNode ) + { + // Did we find the handle we're looking for? + if ( handle == oNode->Owner()->m_handle ) + { + retVal = oNode->Owner(); + + if ( updateCache ) + { + m_lastUsedHandle = handle; + m_lastUsedOverlay = retVal; + } + return retVal; + } + + oNode = oNode->NextNode(); + } + + return NULL; +} + +idLinkList* COverlaySys::findOpaque() +{ + if ( m_updateOpaque ) + { + // Find the highest opaque overlay. + idLinkList* oNode = m_overlays.PrevNode(); + while ( oNode ) + { + if ( oNode->Owner()->m_opaque ) + break; + oNode = oNode->PrevNode(); + } + m_highestOpaque = oNode; + m_updateOpaque = false; + } + return m_highestOpaque; +} + +idUserInterface* COverlaySys::findInteractive() +{ + if ( m_updateInteractive ) + { + // Find the highest interactive overlay. + idLinkList* oNode = m_overlays.PrevNode(); + while ( oNode ) + { + if ( oNode->Owner()->m_interactive ) + break; + oNode = oNode->PrevNode(); + } + m_highestInteractive = oNode ? oNode->Owner()->m_gui : NULL; + m_updateInteractive = false; + } + return m_highestInteractive; +} + +void COverlaySys::broadcastNamedEvent(const char* eventName) +{ + // Cycle through the nodes + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + oNode->Owner()->m_gui->HandleNamedEvent(eventName); + oNode = oNode->NextNode(); + } +} + +void COverlaySys::setGlobalStateString(const char* varName, const char *value) +{ + // Cycle through the nodes + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + oNode->Owner()->m_gui->SetStateString(varName, value); + oNode = oNode->NextNode(); + } +} + +void COverlaySys::setGlobalStateBool(const char* varName, const bool value) +{ + // Cycle through the nodes + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + oNode->Owner()->m_gui->SetStateBool(varName, value); + oNode = oNode->NextNode(); + } +} + +void COverlaySys::setGlobalStateInt(const char* varName, const int value) +{ + // Cycle through the nodes + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + oNode->Owner()->m_gui->SetStateInt(varName, value); + oNode = oNode->NextNode(); + } +} + +void COverlaySys::setGlobalStateFloat(const char* varName, const float value) +{ + // Cycle through the nodes + idLinkList* oNode = m_overlays.NextNode(); + while(oNode) + { + oNode->Owner()->m_gui->SetStateFloat(varName, value); + oNode = oNode->NextNode(); + } +} diff --git a/game/OverlaySys.h b/game/OverlaySys.h new file mode 100644 index 000000000..3137f836c --- /dev/null +++ b/game/OverlaySys.h @@ -0,0 +1,180 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DARKMOD_OVERLAYSYS_H__ +#define __DARKMOD_OVERLAYSYS_H__ + +const int OVERLAYS_MIN_HANDLE = 1; +const int OVERLAYS_INVALID_HANDLE = 0; + +/** +* These is the layer order of the overlay for the player GUI. +*/ +enum +{ + LAYER_UNDERWATER = 0, // Draw the underwater overlay first + LAYER_MAIN_HUD = 1, + LAYER_INVENTORY = 2, + LAYER_OBJECTIVES = 12, + LAYER_WAITUNTILREADY = 13, +}; + +struct SOverlay; + +/// Container class to keep track of multiple GUIs. +/** An overlay system is used to keep track of an arbitrary number of GUIs. + * The overlay system consists of zero or more 'overlays'. An overlay + * contains a GUI and some bookkeeping information. Each overlay has a + * 'layer' which is used to sort the order the overlays are drawn in. + * Overlays in higher layers are drawn on top of overlays in lower layers. + * Multiple overlays may exist in the same layer, but their drawing order + * with respect to eachother is undefined. + * + * An overlay may be opaque. If/when the overlay system is rendered directly + * to screen, this overlay is assumed to have no transparent sections, and + * nothing underneath it will be rendered. This has no effect on GUIs that + * are in the game-world. + * + * An overlay may be interactive. If the overlay system is asked which GUI + * interactivity should be routed to, it will return the GUI in the highest + * interactive overlay. This has no effect on GUIs that are in the + * game-world. + * + * An overlay may be external, meaning that its GUI points to a GUI defined + * externally. Note that although external overlays are saved and restored, + * their GUI pointer isn't, and needs to be set again. + * + * I'm assuming the overlay system will only be used to contain a few + * overlays at a time, so I've opted for simpler data structures and easier + * code, rather than trying to make the most efficient system possible. + * However, certain easy optimizatons have been made; although accessing a + * different overlay from last time is O(N) with respect to the number of + * overlays contained, repeatedly accessing the same overlay is very fast. + * Similarly, results relating to which layers are opaque/interactive are + * cached. + */ +class COverlaySys +{ + public: + + COverlaySys(); + ~COverlaySys(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + /// Draws the contained GUIs to the screen, in order. + void drawOverlays(); + /// Returns true if any of the GUIs are opaque. + bool isOpaque(); + /// Returns the interactive GUI. + idUserInterface* findInteractive(); + /// Used for iterating through the overlays in drawing-order. + /** Very efficient if used properly: + * int h = OVERLAYS_INVALID_HANDLE; + * while ( (h = o.getNextOverlay(h) ) != OVERLAYS_INVALID_HANDLE ) + * o.doSomethingWith( h ); + * It loses efficiency if a handle is accessed other than the one returned. + */ + int getNextOverlay( int handle ); + + /// Create a new overlay, returning a handle for that overlay. + int createOverlay( int layer, int handle = OVERLAYS_INVALID_HANDLE ); + /// Destroy an overlay. + void destroyOverlay( int handle ); + /// Returns whether or not an overlay exists. + bool exists( int handle ); + /// Sets the overlay's GUI to an external GUI. + void setGui( int handle, idUserInterface* gui ); + /// Sets the overlay's GUI to an internal, unique one. + bool setGui( int handle, const char* file ); + /// Return an overlay's GUI. + idUserInterface* getGui( int handle ); + /// Change an overlay's layer. + void setLayer( int handle, int layer ); + /// Return an overlay's layer. + int getLayer( int handle ); + /// Return whether or not an overlay is external. + bool isExternal( int handle ); + /// Change whether or not an overlay is considered opaque. + void setOpaque( int handle, bool isOpaque ); + /// Return whether or not an overlay is considered opaque. + bool isOpaque( int handle ); + /// Change whether or not an overlay is considered interactive. + void setInteractive( int handle, bool isInteractive ); + /// Return whether or not an overlay is considered interactive. + bool isInteractive( int handle ); + + /** + * greebo: This cycles through all overlays and calls HandleNamedEvent() + * on each visible GUI. + */ + void broadcastNamedEvent(const char* eventName); + + /** + * greebo: Use these methods to set the state variables of ALL active overlays. + * This is similar to the broadcastNamedEvent, but these routines only set + * a GUI state variable (e.g. "gui::HUD_Opacity"). + */ + void setGlobalStateString(const char* varName, const char *value); + void setGlobalStateBool(const char* varName, const bool value); + void setGlobalStateInt(const char* varName, const int value); + void setGlobalStateFloat(const char* varName, const float value); + + private: + + /// Returns the overlay associated with a handle. + SOverlay* findOverlay( int handle, bool updateCache = true ); + /// Returns the highest opaque overlay. + idLinkList* findOpaque(); + + /// The list of overlays. + idLinkList m_overlays; + + /// The last handle accessed. + int m_lastUsedHandle; + /// The overlay of the last handle accessed. + SOverlay* m_lastUsedOverlay; + + /// Whether or not the highest opaque overlay needs to be recalculated. + bool m_updateOpaque; + /// The cached value of the highest opaque overlay. + idLinkList* m_highestOpaque; + + /// Whether or not the interactive overlay needs to be recalculated. + bool m_updateInteractive; + /// The cached value of the interactive overlay. + idUserInterface* m_highestInteractive; + + /// This is the next handle to try out when creating a new overlay. + int m_nextHandle; +}; + +struct SOverlay +{ + idLinkList m_node; + idUserInterface* m_gui; + int m_handle; + int m_layer; + bool m_external; + bool m_opaque; + bool m_interactive; +}; + +#endif /* __DARKMOD_OVERLAYSYS_H__ */ diff --git a/DarkMod/PVSToAASMapping.cpp b/game/PVSToAASMapping.cpp similarity index 88% rename from DarkMod/PVSToAASMapping.cpp rename to game/PVSToAASMapping.cpp index c259bcaef..ba21662ac 100644 --- a/DarkMod/PVSToAASMapping.cpp +++ b/game/PVSToAASMapping.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop @@ -13,11 +23,10 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "PVSToAASMapping.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../game/pvs.h" -#include "../renderer/renderworld.h" -#include "../DarkMod/Intersection.h" -#include "../game/pvs.h" +#include "DarkModGlobals.h" +#include "Pvs.h" +#include "../renderer/RenderWorld.h" +#include "Intersection.h" //---------------------------------------------------------------------------- diff --git a/DarkMod/PVSToAASMapping.h b/game/PVSToAASMapping.h similarity index 76% rename from DarkMod/PVSToAASMapping.h rename to game/PVSToAASMapping.h index 602333918..3c4b27f8f 100644 --- a/DarkMod/PVSToAASMapping.h +++ b/game/PVSToAASMapping.h @@ -1,18 +1,25 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once -// DarkMod globals (needed for ../game/Light.h) -#include "../game/light.h" - -//#include "../darkmod/darkmodglobals.h" +#include "../game/Light.h" //------------------------------------------------------ diff --git a/DarkMod/PickableLock.cpp b/game/PickableLock.cpp similarity index 96% rename from DarkMod/PickableLock.cpp rename to game/PickableLock.cpp index 5e47b5d11..cd952e335 100644 --- a/DarkMod/PickableLock.cpp +++ b/game/PickableLock.cpp @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); -#include "../game/game_local.h" +#include "Game_local.h" #include "DarkModGlobals.h" #include "PickableLock.h" #include "randomizer/randomc.h" diff --git a/DarkMod/PickableLock.h b/game/PickableLock.h similarity index 89% rename from DarkMod/PickableLock.h rename to game/PickableLock.h index af809009d..cc2d9f819 100644 --- a/DarkMod/PickableLock.h +++ b/game/PickableLock.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _PICKABLE_LOCK_H_ #define _PICKABLE_LOCK_H_ diff --git a/game/Player.cpp b/game/Player.cpp new file mode 100644 index 000000000..c966566f7 --- /dev/null +++ b/game/Player.cpp @@ -0,0 +1,11463 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#pragma warning(disable : 4355) // greebo: Disable warning "'this' used in constructor" + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "ai/AAS_local.h" +#include "DarkModGlobals.h" +#include "Grabber.h" +#include "Intersection.h" +#include "Relations.h" +#include "DarkmodAASHidingSpotFinder.h" +#include "StimResponse/StimResponseCollection.h" +#include "Objectives/MissionData.h" +#include "Missions/MissionManager.h" +#include "Inventory/Inventory.h" +#include "Inventory/WeaponItem.h" +#include "Shop/Shop.h" + +/* +=============================================================================== + + Player control of the TDM player thief. + This object handles all player movement and world interaction. + +=============================================================================== +*/ + +// amount of health per dose from the health station +const int HEALTH_PER_DOSE = 10; + +// time before a weapon dropped to the floor disappears +const int WEAPON_DROP_TIME = 20 * 1000; + +// time before a next or prev weapon switch happens +const int WEAPON_SWITCH_DELAY = 150; + +// how many units to raise spectator above default view height so it's in the head of someone +const int SPECTATE_RAISE = 25; + +const int HEALTHPULSE_TIME = 333; + +// minimum speed to bob and play run/walk animations at +const float MIN_BOB_SPEED = 5.0f; + +// shouldered body immobilizations +const int SHOULDER_IMMOBILIZATIONS = EIM_CLIMB | EIM_ITEM_SELECT | EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_USE | EIM_MANTLE | EIM_FROB_COMPLEX; +const float SHOULDER_JUMP_HINDERANCE = 0.25f; + +const idEventDef EV_Player_GetButtons( "getButtons", NULL, 'd' ); +const idEventDef EV_Player_GetMove( "getMove", NULL, 'v' ); +const idEventDef EV_Player_GetViewAngles( "getViewAngles", NULL, 'v' ); +const idEventDef EV_Player_GetMouseGesture( "getMouseGesture", NULL, 'd'); +const idEventDef EV_Player_MouseGestureFinished( "mouseGestureFinished", NULL, 'd' ); +const idEventDef EV_Player_ClearMouseDeadTime("clearMouseDeadTime"); +const idEventDef EV_Player_StartMouseGesture( "startMouseGesture", "ddddfdd" ); +const idEventDef EV_Player_StopMouseGesture( "stopMouseGesture" ); +const idEventDef EV_Player_StopFxFov( "stopFxFov" ); +const idEventDef EV_Player_EnableWeapon( "enableWeapon" ); +const idEventDef EV_Player_DisableWeapon( "disableWeapon" ); +const idEventDef EV_Player_GetCurrentWeapon( "getCurrentWeapon", NULL, 's' ); +const idEventDef EV_Player_GetPreviousWeapon( "getPreviousWeapon", NULL, 's' ); +const idEventDef EV_Player_SelectWeapon( "selectWeapon", "s" ); +const idEventDef EV_Player_GetWeaponEntity( "getWeaponEntity", NULL, 'e' ); +const idEventDef EV_Player_ExitTeleporter( "exitTeleporter" ); +const idEventDef EV_SpectatorTouch( "spectatorTouch", "et" ); +const idEventDef EV_Player_GetIdealWeapon( "getIdealWeapon", NULL, 's' ); + +const idEventDef EV_Player_GetEyePos( "getEyePos", NULL, 'v' ); +const idEventDef EV_Player_SetImmobilization( "setImmobilization", "sd" ); +const idEventDef EV_Player_GetImmobilization( "getImmobilization", "s", 'd' ); +const idEventDef EV_Player_GetNextImmobilization( "getNextImmobilization", "ss", 's' ); +const idEventDef EV_Player_SetHinderance( "setHinderance", "sff" ); +const idEventDef EV_Player_GetHinderance( "getHinderance", "s", 'v' ); +const idEventDef EV_Player_GetNextHinderance( "getNextHinderance", "ss", 's' ); +const idEventDef EV_Player_SetTurnHinderance( "setTurnHinderance", "sff" ); +const idEventDef EV_Player_GetTurnHinderance( "getTurnHinderance", "s", 'v' ); +const idEventDef EV_Player_GetNextTurnHinderance( "getNextTurnHinderance", "ss", 's' ); + +const idEventDef EV_Player_SetGui( "setGui", "ds" ); +const idEventDef EV_Player_GetInventoryOverlay( "getInventoryOverlay", NULL, 'd' ); + +const idEventDef EV_Player_PlayStartSound( "playStartSound", NULL ); +const idEventDef EV_Player_MissionFailed("missionFailed", NULL ); +const idEventDef EV_Player_CustomDeath("customDeath", NULL ); +const idEventDef EV_Player_DeathMenu("deathMenu", NULL ); +const idEventDef EV_Player_HoldEntity( "holdEntity", "E", 'f' ); +const idEventDef EV_Player_HeldEntity( "heldEntity", NULL, 'E' ); + +const idEventDef EV_Player_RopeRemovalCleanup( "ropeRemovalCleanup", "e" ); +// NOTE: The following all take the "user" objective indices, starting at 1 instead of 0 +const idEventDef EV_Player_SetObjectiveState( "setObjectiveState", "dd" ); +const idEventDef EV_Player_GetObjectiveState( "getObjectiveState", "d", 'd'); +const idEventDef EV_Player_SetObjectiveComp( "setObjectiveComp", "ddd" ); +const idEventDef EV_Player_GetObjectiveComp( "getObjectiveComp", "dd", 'd' ); +const idEventDef EV_Player_ObjectiveUnlatch( "objectiveUnlatch", "d" ); +const idEventDef EV_Player_ObjectiveCompUnlatch( "objectiveCompUnlatch", "dd" ); +const idEventDef EV_Player_SetObjectiveVisible( "setObjectiveVisible", "dd" ); +const idEventDef EV_Player_SetObjectiveOptional( "setObjectiveOptional", "dd" ); +const idEventDef EV_Player_SetObjectiveOngoing( "setObjectiveOngoing", "dd" ); +const idEventDef EV_Player_SetObjectiveEnabling( "setObjectiveEnabling", "ds" ); +// greebo: This allows scripts to set the "healthpool" for gradual healing +const idEventDef EV_Player_GiveHealthPool("giveHealthPool", "f"); +const idEventDef EV_Player_WasDamaged("wasDamaged", NULL, 'd'); + +const idEventDef EV_Mission_Success("missionSuccess", NULL); +const idEventDef EV_TriggerMissionEnd("triggerMissionEnd", NULL); +const idEventDef EV_DisconnectFromMission("_disconnectFromMission", NULL); + +// Private event to process intermission triggers +const idEventDef EV_ProcessInterMissionTriggers("_processInterMissionTriggers"); + +const idEventDef EV_GetLocation("getLocation", NULL, 'e'); + +// greebo: These events are handling the FOV. +const idEventDef EV_Player_StartZoom("startZoom", "fff"); +const idEventDef EV_Player_EndZoom("endZoom", "f"); +const idEventDef EV_Player_ResetZoom("resetZoom", NULL); +const idEventDef EV_Player_GetFov("getFov", NULL, 'f'); + +const idEventDef EV_Player_PauseGame("pauseGame", NULL); +const idEventDef EV_Player_UnpauseGame("unpauseGame", NULL); +const idEventDef EV_Player_StartGamePlayTimer("startGamePlayTimer", NULL); + +const idEventDef EV_CheckAAS("checkAAS", NULL); + +// greebo: Allows scripts to set a named lightgem modifier to a certain value (e.g. "lantern" => 32) +const idEventDef EV_Player_SetLightgemModifier("setLightgemModifier", "sd"); +const idEventDef EV_ReadLightgemModifierFromWorldspawn("readLightgemModifierFromWorldspawn", NULL); + +// greebo: Changes the projectile entityDef name of the given weapon (e.g. "broadhead"). +const idEventDef EV_ChangeWeaponProjectile("changeWeaponProjectile", "ss", NULL); +const idEventDef EV_ResetWeaponProjectile("resetWeaponProjectile", "s", NULL); +const idEventDef EV_ChangeWeaponName("changeWeaponName", "ss", NULL); +const idEventDef EV_GetCurWeaponName("getCurWeaponName", NULL, 's'); +const idEventDef EV_SetActiveInventoryMapEnt("setActiveInventoryMapEnt", "e"); +const idEventDef EV_ClearActiveInventoryMap("clearActiveInventoryMap", NULL); + +// ishtvan: Let scripts get the currently frobbed entity, and set "frob only used by" mode +const idEventDef EV_Player_GetFrobbed("getFrobbed", NULL, 'e'); +const idEventDef EV_Player_SetFrobOnlyUsedByInv("setFrobOnlyUsedByInv", "d", NULL); + +CLASS_DECLARATION( idActor, idPlayer ) + EVENT( EV_Player_GetButtons, idPlayer::Event_GetButtons ) + EVENT( EV_Player_GetMove, idPlayer::Event_GetMove ) + EVENT( EV_Player_GetViewAngles, idPlayer::Event_GetViewAngles ) + EVENT( EV_Player_GetMouseGesture, idPlayer::Event_GetMouseGesture ) + EVENT( EV_Player_MouseGestureFinished, idPlayer::Event_MouseGestureFinished ) + EVENT( EV_Player_StartMouseGesture, idPlayer::StartMouseGesture ) + EVENT( EV_Player_StopMouseGesture, idPlayer::StopMouseGesture ) + EVENT( EV_Player_ClearMouseDeadTime, idPlayer::Event_ClearMouseDeadTime ) + EVENT( EV_Player_StopFxFov, idPlayer::Event_StopFxFov ) + EVENT( EV_Player_EnableWeapon, idPlayer::Event_EnableWeapon ) + EVENT( EV_Player_DisableWeapon, idPlayer::Event_DisableWeapon ) + EVENT( EV_Player_GetCurrentWeapon, idPlayer::Event_GetCurrentWeapon ) + EVENT( EV_Player_GetPreviousWeapon, idPlayer::Event_GetPreviousWeapon ) + EVENT( EV_Player_SelectWeapon, idPlayer::Event_SelectWeapon ) + EVENT( EV_Player_GetWeaponEntity, idPlayer::Event_GetWeaponEntity ) + EVENT( EV_Player_ExitTeleporter, idPlayer::Event_ExitTeleporter ) + EVENT( EV_Gibbed, idPlayer::Event_Gibbed ) + + EVENT( EV_Player_GetEyePos, idPlayer::Event_GetEyePos ) + EVENT( EV_Player_SetImmobilization, idPlayer::Event_SetImmobilization ) + EVENT( EV_Player_GetImmobilization, idPlayer::Event_GetImmobilization ) + EVENT( EV_Player_GetNextImmobilization, idPlayer::Event_GetNextImmobilization ) + EVENT( EV_Player_SetHinderance, idPlayer::Event_SetHinderance ) + EVENT( EV_Player_GetHinderance, idPlayer::Event_GetHinderance ) + EVENT( EV_Player_GetNextHinderance, idPlayer::Event_GetNextHinderance ) + EVENT( EV_Player_SetTurnHinderance, idPlayer::Event_SetTurnHinderance ) + EVENT( EV_Player_GetTurnHinderance, idPlayer::Event_GetTurnHinderance ) + EVENT( EV_Player_GetNextTurnHinderance, idPlayer::Event_GetNextTurnHinderance ) + + EVENT( EV_Player_SetGui, idPlayer::Event_SetGui ) + EVENT( EV_Player_GetInventoryOverlay, idPlayer::Event_GetInventoryOverlay ) + + EVENT( EV_Player_PlayStartSound, idPlayer::Event_PlayStartSound ) + EVENT( EV_Player_MissionFailed, idPlayer::Event_MissionFailed ) + EVENT( EV_Player_CustomDeath, idPlayer::Event_CustomDeath ) + EVENT( EV_Player_DeathMenu, idPlayer::Event_LoadDeathMenu ) + EVENT( EV_Player_HoldEntity, idPlayer::Event_HoldEntity ) + EVENT( EV_Player_HeldEntity, idPlayer::Event_HeldEntity ) + EVENT( EV_Player_RopeRemovalCleanup, idPlayer::Event_RopeRemovalCleanup ) + EVENT( EV_Player_SetObjectiveState, idPlayer::Event_SetObjectiveState ) + EVENT( EV_Player_GetObjectiveState, idPlayer::Event_GetObjectiveState ) + EVENT( EV_Player_SetObjectiveComp, idPlayer::Event_SetObjectiveComp ) + EVENT( EV_Player_GetObjectiveComp, idPlayer::Event_GetObjectiveComp ) + EVENT( EV_Player_ObjectiveUnlatch, idPlayer::Event_ObjectiveUnlatch ) + EVENT( EV_Player_ObjectiveCompUnlatch, idPlayer::Event_ObjectiveComponentUnlatch ) + EVENT( EV_Player_SetObjectiveVisible, idPlayer::Event_SetObjectiveVisible ) + EVENT( EV_Player_SetObjectiveOptional, idPlayer::Event_SetObjectiveOptional ) + EVENT( EV_Player_SetObjectiveOngoing, idPlayer::Event_SetObjectiveOngoing ) + EVENT( EV_Player_SetObjectiveEnabling, idPlayer::Event_SetObjectiveEnabling ) + + EVENT( EV_Player_GiveHealthPool, idPlayer::Event_GiveHealthPool ) + EVENT( EV_Player_WasDamaged, idPlayer::Event_WasDamaged ) + + EVENT( EV_Player_SetLightgemModifier, idPlayer::Event_SetLightgemModifier ) + EVENT( EV_ReadLightgemModifierFromWorldspawn, idPlayer::Event_ReadLightgemModifierFromWorldspawn ) + + EVENT( EV_Player_StartZoom, idPlayer::Event_StartZoom ) + EVENT( EV_Player_EndZoom, idPlayer::Event_EndZoom ) + EVENT( EV_Player_ResetZoom, idPlayer::Event_ResetZoom ) + EVENT( EV_Player_GetFov, idPlayer::Event_GetFov ) + + // Events needed for the Objectives GUI (is a blocking GUI - pauses the game) + EVENT( EV_Player_PauseGame, idPlayer::Event_Pausegame ) + EVENT( EV_Player_UnpauseGame, idPlayer::Event_Unpausegame ) + EVENT( EV_Player_StartGamePlayTimer, idPlayer::Event_StartGamePlayTimer ) + + EVENT( EV_Mission_Success, idPlayer::Event_MissionSuccess) + EVENT( EV_TriggerMissionEnd, idPlayer::Event_TriggerMissionEnd ) + EVENT( EV_DisconnectFromMission, idPlayer::Event_DisconnectFromMission ) + + EVENT( EV_GetLocation, idPlayer::Event_GetLocation ) + + EVENT( EV_ChangeWeaponProjectile, idPlayer::Event_ChangeWeaponProjectile ) + EVENT( EV_ResetWeaponProjectile, idPlayer::Event_ResetWeaponProjectile ) + EVENT( EV_ChangeWeaponName, idPlayer::Event_ChangeWeaponName ) + EVENT( EV_GetCurWeaponName, idPlayer::Event_GetCurWeaponName ) + EVENT( EV_SetActiveInventoryMapEnt, idPlayer::Event_SetActiveInventoryMapEnt ) + EVENT( EV_ClearActiveInventoryMap, idPlayer::Event_ClearActiveInventoryMap ) + + EVENT( EV_Player_GetFrobbed, idPlayer::Event_GetFrobbed ) + EVENT( EV_Player_SetFrobOnlyUsedByInv, idPlayer::Event_SetFrobOnlyUsedByInv ) + + EVENT( EV_ProcessInterMissionTriggers, idPlayer::Event_ProcessInterMissionTriggers ) + EVENT( EV_CheckAAS, idPlayer::Event_CheckAAS ) + +END_CLASS + +const int MAX_RESPAWN_TIME = 10000; +const int RAGDOLL_DEATH_TIME = 3000; +const int STEPUP_TIME = 200; + +idVec3 idPlayer::colorBarTable[ 5 ] = { + idVec3( 0.25f, 0.25f, 0.25f ), + idVec3( 1.00f, 0.00f, 0.00f ), + idVec3( 0.00f, 0.80f, 0.10f ), + idVec3( 0.20f, 0.50f, 0.80f ), + idVec3( 1.00f, 0.80f, 0.10f ) +}; + +/* +============== +idPlayer::idPlayer +============== +*/ +idPlayer::idPlayer() : + m_ButtonStateTracker(this) +{ + memset( &usercmd, 0, sizeof( usercmd ) ); + + noclip = false; + godmode = false; + + spawnAnglesSet = false; + spawnAngles = ang_zero; + viewAngles = ang_zero; + cmdAngles = ang_zero; + + oldButtons = 0; + buttonMask = 0; + oldFlags = 0; + + lastHitTime = 0; + lastSndHitTime = 0; + lastSavingThrowTime = 0; + + lockpickHUD = 0; + + hasLanded = false; + + weapon = NULL; + + hud = NULL; + inventoryHUDNeedsUpdate = true; + + heartRate = BASE_HEARTRATE; + heartInfo.Init( 0, 0, 0, 0 ); + lastHeartAdjust = 0; + lastHeartBeat = 0; + lastDmgTime = 0; + deathClearContentsTime = 0; + lastArmorPulse = -10000; + stamina = 0.0f; + healthPool = 0.0f; + nextHealthPulse = 0; + healthPulse = false; + nextHealthTake = 0; + healthTake = false; + healthPoolTimeInterval = HEALTHPULSE_TIME; + healthPoolTimeIntervalFactor = 1.0f; + healthPoolStepAmount = 5; + + scoreBoardOpen = false; + forceScoreBoard = false; + forceRespawn = false; + spectating = false; + spectator = 0; + colorBar = vec3_zero; + colorBarIndex = 0; + forcedReady = false; + wantSpectate = false; + + lastHitToggle = false; + + minRespawnTime = 0; + maxRespawnTime = 0; + + m_WaitUntilReadyGuiHandle = OVERLAYS_INVALID_HANDLE; + m_WaitUntilReadyGuiTime = 0; + + firstPersonViewOrigin = vec3_zero; + firstPersonViewAxis = mat3_identity; + + hipJoint = INVALID_JOINT; + chestJoint = INVALID_JOINT; + headJoint = INVALID_JOINT; + + bobFoot = 0; + bobFrac = 0.0f; + bobfracsin = 0.0f; + bobCycle = 0; + xyspeed = 0.0f; + stepUpTime = 0; + stepUpDelta = 0.0f; + idealLegsYaw = 0.0f; + legsYaw = 0.0f; + legsForward = true; + oldViewYaw = 0.0f; + viewBobAngles = ang_zero; + viewBob = vec3_zero; + landChange = 0; + landTime = 0; + lastFootstepPlaytime = -1; + + currentWeapon = -1; + idealWeapon = -1; + previousWeapon = -1; + weaponSwitchTime = 0; + weaponEnabled = true; + weapon_fists = -1; + showWeaponViewModel = true; + + skin = NULL; + powerUpSkin = NULL; + baseSkinName = ""; + + numProjectilesFired = 0; + numProjectileHits = 0; + + airless = false; + airTics = 0; + lastAirDamage = 0; + underWaterEffectsActive = false; + underWaterGUIHandle = -1; + + gibDeath = false; + gibsLaunched = false; + gibsDir = vec3_zero; + + zoomFov.Init( 0, 0, 0, 0 ); + centerView.Init( 0, 0, 0, 0 ); + fxFov = false; + + influenceFov = 0; + influenceActive = 0; + influenceRadius = 0.0f; + influenceEntity = NULL; + influenceMaterial = NULL; + influenceSkin = NULL; + + privateCameraView = NULL; + + m_ListenerLoc = vec3_zero; + m_DoorListenLoc = vec3_zero; + + // m_immobilization.Clear(); + m_immobilizationCache = 0; + + // m_hinderance.Clear(); + m_hinderanceCache = 1.0f; + m_TurnHinderanceCache = 1.0f; + m_JumpHinderanceCache = 1.0f; + + memset( loggedViewAngles, 0, sizeof( loggedViewAngles ) ); + memset( loggedAccel, 0, sizeof( loggedAccel ) ); + currentLoggedAccel = 0; + +#if 0 + focusTime = 0; + focusGUIent = NULL; + focusUI = NULL; + focusCharacter = NULL; + talkCursor = 0; + focusVehicle = NULL; +#endif + cursor = NULL; + + oldMouseX = 0; + oldMouseY = 0; + + lastDamageDef = 0; + lastDamageDir = vec3_zero; + lastDamageLocation = 0; + m_bDamagedThisFrame = false; + smoothedFrame = 0; + smoothedOriginUpdated = false; + smoothedOrigin = vec3_zero; + smoothedAngles = ang_zero; + + fl.networkSync = true; + + latchedTeam = -1; + doingDeathSkin = false; + weaponGone = false; + useInitialSpawns = false; + tourneyRank = 0; + lastSpectateTeleport = 0; + tourneyLine = 0; + hiddenWeapon = false; + tipUp = false; + teleportEntity = NULL; + teleportKiller = -1; + respawning = false; + ready = false; + leader = false; + lastSpectateChange = 0; + lastTeleFX = -9999; + weaponCatchup = false; + lastSnapshotSequence = 0; + + MPAim = -1; + lastMPAim = -1; + lastMPAimTime = 0; + MPAimFadeTime = 0; + MPAimHighlight = false; + + spawnedTime = 0; + lastManOver = false; + lastManPlayAgain = false; + lastManPresent = false; + + isTelefragged = false; + + isLagged = false; + isChatting = false; + selfSmooth = false; + + m_FrobPressedTarget = NULL; + + m_FrobEntity = NULL; + m_FrobJoint = INVALID_JOINT; + m_FrobID = 0; + // greebo: Initialise the frob trace contact material to avoid + // crashing during map save when nothing has been frobbed yet + memset(&m_FrobTrace, 0, sizeof(trace_t)); + m_bFrobOnlyUsedByInv = false; + + m_bGrabberActive = false; + m_bDraggingBody = false; + m_bShoulderingBody = false; + + m_IdealCrouchState = false; + m_CrouchIntent = false; + + m_LeanButtonTimeStamp = 0; + m_InventoryOverlay = -1; + objectivesOverlay = -1; + m_WeaponCursor = CInventoryCursorPtr(); + m_MapCursor = CInventoryCursorPtr(); + m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; + + m_LightgemModifier = 0; + m_LightgemValue = 0; + m_fColVal = 0; + m_fBlendColVal = 0; + m_LightgemInterleave = 0; + ignoreWeaponAttack = false; // grayman #597 +} + +/* +============== +idPlayer::LinkScriptVariables + +set up conditions for animation +============== +*/ +void idPlayer::LinkScriptVariables() +{ + // Call the base class first + idActor::LinkScriptVariables(); + + AI_FORWARD.LinkTo( scriptObject, "AI_FORWARD" ); + AI_BACKWARD.LinkTo( scriptObject, "AI_BACKWARD" ); + AI_STRAFE_LEFT.LinkTo( scriptObject, "AI_STRAFE_LEFT" ); + AI_STRAFE_RIGHT.LinkTo( scriptObject, "AI_STRAFE_RIGHT" ); + AI_ATTACK_HELD.LinkTo( scriptObject, "AI_ATTACK_HELD" ); + AI_BLOCK_HELD.LinkTo( scriptObject, "AI_BLOCK_HELD" ); + AI_WEAPON_FIRED.LinkTo( scriptObject, "AI_WEAPON_FIRED" ); + AI_WEAPON_BLOCKED.LinkTo( scriptObject, "AI_WEAPON_BLOCKED" ); + AI_JUMP.LinkTo( scriptObject, "AI_JUMP" ); + AI_CROUCH.LinkTo( scriptObject, "AI_CROUCH" ); + AI_ONGROUND.LinkTo( scriptObject, "AI_ONGROUND" ); + AI_ONLADDER.LinkTo( scriptObject, "AI_ONLADDER" ); + AI_HARDLANDING.LinkTo( scriptObject, "AI_HARDLANDING" ); + AI_SOFTLANDING.LinkTo( scriptObject, "AI_SOFTLANDING" ); + AI_RUN.LinkTo( scriptObject, "AI_RUN" ); + AI_PAIN.LinkTo( scriptObject, "AI_PAIN" ); + AI_RELOAD.LinkTo( scriptObject, "AI_RELOAD" ); + AI_TELEPORT.LinkTo( scriptObject, "AI_TELEPORT" ); + AI_TURN_LEFT.LinkTo( scriptObject, "AI_TURN_LEFT" ); + AI_TURN_RIGHT.LinkTo( scriptObject, "AI_TURN_RIGHT" ); + AI_LEAN_LEFT.LinkTo( scriptObject, "AI_LEAN_LEFT" ); + AI_LEAN_RIGHT.LinkTo( scriptObject, "AI_LEAN_RIGHT" ); + AI_LEAN_FORWARD.LinkTo( scriptObject, "AI_LEAN_FORWARD" ); + AI_CREEP.LinkTo( scriptObject, "AI_CREEP" ); +} + +/* +============== +idPlayer::SetupWeaponEntity +============== +*/ +void idPlayer::SetupWeaponEntity() +{ + if ( weapon.GetEntity() ) { + // get rid of old weapon + weapon.GetEntity()->Clear(); + currentWeapon = -1; + } + else if ( !gameLocal.isClient ) { + weapon = static_cast( gameLocal.SpawnEntityType( idWeapon::Type, NULL ) ); + weapon.GetEntity()->SetOwner( this ); + currentWeapon = -1; + } + + for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) + { + if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs + + idWeapon::CacheWeapon(kv->GetValue()); + } +} + +/* +============== +idPlayer::Init +============== +*/ +void idPlayer::Init( void ) { + const char *value; + const idKeyValue *kv; + + noclip = false; + godmode = false; + + oldButtons = 0; + oldFlags = 0; + + currentWeapon = -1; + idealWeapon = 0; + previousWeapon = -1; + weaponSwitchTime = 0; + weaponEnabled = true; + weapon_fists = 0;//SlotForWeapon( "weapon_fists" ); + showWeaponViewModel = GetUserInfo()->GetBool( "ui_showGun" ); + + lastDmgTime = 0; + lastArmorPulse = -10000; + lastHeartAdjust = 0; + lastHeartBeat = 0; + heartInfo.Init( 0, 0, 0, 0 ); + + bobCycle = 0; + bobFrac = 0.0f; + landChange = 0; + landTime = 0; + lastFootstepPlaytime = -1; + isPushing = false; + zoomFov.Init( 0, 0, 0, 0 ); + + centerView.Init( 0, 0, 0, 0 ); + fxFov = false; + + influenceFov = 0; + influenceActive = 0; + influenceRadius = 0.0f; + influenceEntity = NULL; + influenceMaterial = NULL; + influenceSkin = NULL; + + currentLoggedAccel = 0; + +#if 0 + focusTime = 0; + focusGUIent = NULL; + focusUI = NULL; + focusCharacter = NULL; + talkCursor = 0; + focusVehicle = NULL; +#endif + + // remove any damage effects + playerView.ClearEffects(); + + // damage values + fl.takedamage = true; + ClearPain(); + + // restore persistent data + RestorePersistantInfo(); + + bobCycle = 0; + stamina = 0.0f; + healthPool = 0.0f; + nextHealthPulse = 0; + healthPulse = false; + nextHealthTake = 0; + healthTake = false; + + SetupWeaponEntity(); + currentWeapon = -1; + previousWeapon = -1; + + heartRate = BASE_HEARTRATE; + AdjustHeartRate( BASE_HEARTRATE, 0.0f, 0.0f, true ); + + idealLegsYaw = 0.0f; + legsYaw = 0.0f; + legsForward = true; + oldViewYaw = 0.0f; + + // set the pm_ cvars + if ( !gameLocal.isMultiplayer || gameLocal.isServer ) { + kv = spawnArgs.MatchPrefix( "pm_", NULL ); + while( kv ) { + cvarSystem->SetCVarString( kv->GetKey(), kv->GetValue() ); + kv = spawnArgs.MatchPrefix( "pm_", kv ); + } + } + + // Commented out by Dram. TDM does not use stamina +/* + // disable stamina on hell levels + if ( gameLocal.world && gameLocal.world->spawnArgs.GetBool( "no_stamina" ) ) { + pm_stamina.SetFloat( 0.0f ); + } + + // stamina always initialized to maximum + stamina = pm_stamina.GetFloat(); +*/ + stamina = 0.0f; // Set stamina to 0 - Dram + + // air always initialized to maximum too + airTics = pm_airTics.GetInteger(); + airless = false; + + gibDeath = false; + gibsLaunched = false; + gibsDir.Zero(); + + // set the gravity + physicsObj.SetGravity( gameLocal.GetGravity() ); + + // start out standing + SetEyeHeight( pm_normalviewheight.GetFloat() ); + + stepUpTime = 0; + stepUpDelta = 0.0f; + viewBobAngles.Zero(); + viewBob.Zero(); + + value = spawnArgs.GetString( "model" ); + if ( value && ( *value != 0 ) ) { + SetModel( value ); + } + + if ( cursor ) { + cursor->SetStateInt( "talkcursor", 0 ); + cursor->SetStateString( "combatcursor", "1" ); + cursor->SetStateString( "itemcursor", "0" ); + cursor->SetStateString( "guicursor", "0" ); + } + + if ( ( gameLocal.isMultiplayer || g_testDeath.GetBool() ) && skin ) { + SetSkin( skin ); + renderEntity.shaderParms[6] = 0.0f; + } else if ( spawnArgs.GetString( "spawn_skin", NULL, &value ) ) { + skin = declManager->FindSkin( value ); + SetSkin( skin ); + renderEntity.shaderParms[6] = 0.0f; + } + + value = spawnArgs.GetString( "bone_hips", "" ); + hipJoint = animator.GetJointHandle( value ); + if ( hipJoint == INVALID_JOINT ) { + gameLocal.Error( "Joint '%s' not found for 'bone_hips' on '%s'", value, name.c_str() ); + } + + value = spawnArgs.GetString( "bone_chest", "" ); + chestJoint = animator.GetJointHandle( value ); + if ( chestJoint == INVALID_JOINT ) { + gameLocal.Error( "Joint '%s' not found for 'bone_chest' on '%s'", value, name.c_str() ); + } + + value = spawnArgs.GetString( "bone_head", "" ); + headJoint = animator.GetJointHandle( value ); + if ( headJoint == INVALID_JOINT ) { + gameLocal.Error( "Joint '%s' not found for 'bone_head' on '%s'", value, name.c_str() ); + } + + // initialize the script variables + AI_FORWARD = false; + AI_BACKWARD = false; + AI_STRAFE_LEFT = false; + AI_STRAFE_RIGHT = false; + AI_ATTACK_HELD = false; + AI_BLOCK_HELD = false; + AI_WEAPON_FIRED = false; + AI_WEAPON_BLOCKED = false; + AI_JUMP = false; + AI_DEAD = false; + AI_CROUCH = false; + AI_ONGROUND = true; + AI_ONLADDER = false; + AI_HARDLANDING = false; + AI_SOFTLANDING = false; + AI_RUN = false; + AI_PAIN = false; + AI_RELOAD = false; + AI_TELEPORT = false; + AI_TURN_LEFT = false; + AI_TURN_RIGHT = false; + + AI_LEAN_LEFT = false; + AI_LEAN_RIGHT = false; + AI_LEAN_FORWARD = false; + + AI_CREEP = false; + + m_pathRank = 1000; // grayman #2345 + + // reset the script object + ConstructScriptObject(); + + // execute the script so the script object's constructor takes effect immediately + scriptThread->Execute(); + + forceScoreBoard = false; + forcedReady = false; + + privateCameraView = NULL; + + lastSpectateChange = 0; + lastTeleFX = -9999; + + hiddenWeapon = false; + tipUp = false; + teleportEntity = NULL; + teleportKiller = -1; + leader = false; + + SetPrivateCameraView( NULL ); + + lastSnapshotSequence = 0; + + MPAim = -1; + lastMPAim = -1; + lastMPAimTime = 0; + MPAimFadeTime = 0; + MPAimHighlight = false; + + if ( hud ) { + hud->HandleNamedEvent( "aim_clear" ); + } + + cvarSystem->SetCVarBool( "ui_chat", false ); +} + +/* +============== +idPlayer::Spawn + +Prepare any resources used by the player. +============== +*/ +void idPlayer::Spawn( void ) +{ + int i; + idStr temp; + idBounds bounds; + + if ( entityNumber >= MAX_CLIENTS ) { + gameLocal.Error( "entityNum > MAX_CLIENTS for player. Player may only be spawned with a client." ); + } + + // allow thinking during cinematics + cinematic = true; + + if ( gameLocal.isMultiplayer ) { + // always start in spectating state waiting to be spawned in + // do this before SetClipModel to get the right bounding box + spectating = true; + } + + maxHealth = spawnArgs.GetInt("maxhealth", "100"); + + m_immobilization.Clear(); + m_immobilizationCache = 0; + + m_hinderance.Clear(); + m_hinderanceCache = 1.0f; + + m_TurnHinderance.Clear(); + m_TurnHinderanceCache = 1.0f; + + // set our collision model + physicsObj.SetSelf( this ); + SetClipModel(); + physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) ); + physicsObj.SetContents( CONTENTS_BODY ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + physicsObj.SetClipMask( MASK_PLAYERSOLID ); + SetPhysics( &physicsObj ); + InitAASLocation(); + + skin = renderEntity.customSkin; + + // only the local player needs guis + if ( !gameLocal.isMultiplayer || entityNumber == gameLocal.localClientNum ) { + + // load HUD + if ( gameLocal.isMultiplayer ) { + // I need the HUD uniqued for the inventory code to interact with it. + //hud = uiManager->FindGui( "guis/mphud.gui", true, false, true ); + hud = uiManager->FindGui( "guis/mphud.gui", true, true ); + } else if ( spawnArgs.GetString( "hud", "", temp ) ) { + // I need the HUD uniqued for the inventory code to interact with it. + //hud = uiManager->FindGui( temp, true, false, true ); + hud = uiManager->FindGui( temp, true, true ); + } + if ( hud ) { + hud->Activate( true, gameLocal.time ); + } + + // load cursor + if ( spawnArgs.GetString( "cursor", "", temp ) ) { + cursor = uiManager->FindGui( temp, true, gameLocal.isMultiplayer, gameLocal.isMultiplayer ); + } + if ( cursor ) { + cursor->Activate( true, gameLocal.time ); + } + } + + // Remove entity GUIs from our overlay system. + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) + m_overlays.destroyOverlay( OVERLAYS_MIN_HANDLE + i ); + // Add the HUD. + if ( m_overlays.createOverlay( 0, LAYER_MAIN_HUD ) >= OVERLAYS_MIN_HANDLE ) + m_overlays.setGui( OVERLAYS_MIN_HANDLE , hud ); + else + gameLocal.Warning( "Unable to create overlay for HUD.\n" ); + + SetLastHitTime( 0 ); + + // load the armor sound feedback + declManager->FindSound( "player_sounds_hitArmor" ); + + // set up conditions for animation + LinkScriptVariables(); + + animator.RemoveOriginOffset( true ); + + // initialize user info related settings + // on server, we wait for the userinfo broadcast, as this controls when the player is initially spawned in game + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) { + UserInfoChanged(false); + } + + // create combat collision hull for exact collision detection + SetCombatModel(); + + // init the damage effects + playerView.SetPlayerEntity( this ); + + // suppress model in non-player views, but allow it in mirrors and remote views + renderEntity.suppressSurfaceInViewID = entityNumber+1; + + // don't project shadow on self or weapon + renderEntity.noSelfShadow = true; + + idAFAttachment *headEnt = head.GetEntity(); + if ( headEnt ) { + headEnt->GetRenderEntity()->suppressSurfaceInViewID = entityNumber+1; + headEnt->GetRenderEntity()->noSelfShadow = true; + } + + if ( gameLocal.isMultiplayer ) + { + Init(); + Hide(); // properly hidden if starting as a spectator + if ( !gameLocal.isClient ) + { + // set yourself ready to spawn. idMultiplayerGame will decide when/if appropriate and call SpawnFromSpawnSpot + SetupWeaponEntity(); + SpawnFromSpawnSpot(); + forceRespawn = true; + assert( spectating ); + } + } + else + { + SetupWeaponEntity(); + SpawnFromSpawnSpot(); + } + + // trigger playtesting item gives, if we didn't get here from a previous level + // the devmap key will be set on the first devmap, but cleared on any level + // transitions + if ( !gameLocal.isMultiplayer && gameLocal.serverInfo.FindKey( "devmap" ) ) { + // fire a trigger with the name "devmap" + idEntity *ent = gameLocal.FindEntity( "devmap" ); + if ( ent ) { + ent->ActivateTargets( this ); + } + } + + if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) + { + hiddenWeapon = true; + if ( weapon.GetEntity() ) + weapon.GetEntity()->LowerWeapon(); + idealWeapon = 0; + } + else + hiddenWeapon = false; + + if ( hud ) + { + UpdateHudWeapon(); + hud->StateChanged( gameLocal.time ); + // greebo: Initialise the Message code on the HUD + hud->HandleNamedEvent("SetupMessageSystem"); + } + + tipUp = false; + + // copy step volumes over from cvars + UpdateMoveVolumes(); + + if ( !gameLocal.isMultiplayer ) + { + if ( g_skill.GetInteger() < 2 ) + { + if ( health < 25 ) + { + health = 25; + } + if ( g_useDynamicProtection.GetBool() ) + { + g_damageScale.SetFloat( 1.0f ); + } + } + else + { + g_damageScale.SetFloat( 1.0f ); + g_armorProtection.SetFloat( ( g_skill.GetInteger() < 2 ) ? 0.4f : 0.2f ); +#ifndef ID_DEMO_BUILD + if ( g_skill.GetInteger() == 3 ) + { + healthTake = true; + nextHealthTake = gameLocal.time + g_healthTakeTime.GetInteger() * 1000; + } +#endif + } + } + + lockpickHUD = CreateOverlay("guis/tdm_lockpick.gui", 20); + + // Clear the lightgem modifiers + m_LightgemModifierList.clear(); + + //FIX: Set the walkspeed back to the stored value. + pm_walkspeed.SetFloat( gameLocal.m_walkSpeed ); + SetupInventory(); + + // greebo: Set the player variable on the grabber + gameLocal.m_Grabber->SetPlayer(this); + + // greebo: Initialise the default fov. + zoomFov.Init(gameLocal.time, 0, g_fov.GetFloat(), g_fov.GetFloat()); + + // Post an event to read the LG modifier from the worldspawn entity + PostEventMS(&EV_ReadLightgemModifierFromWorldspawn, 0); + + // Process inter-mission triggers after the first few frames to ensure all entities have acquired their targets + PostEventMS(&EV_ProcessInterMissionTriggers, 48); + + // Start the gameplay timer half a second after spawn + PostEventMS(&EV_Player_StartGamePlayTimer, 500); + + // Check the AAS status + PostEventMS(&EV_CheckAAS, 0); +} + +CInventoryWeaponItemPtr idPlayer::GetCurrentWeaponItem() +{ + if (m_WeaponCursor == NULL) + { + return CInventoryWeaponItemPtr(); + } + + return boost::dynamic_pointer_cast(m_WeaponCursor->GetCurrentItem()); +} + +CInventoryWeaponItemPtr idPlayer::GetWeaponItem(const idStr& weaponName) +{ + if (m_WeaponCursor == NULL) + { + return CInventoryWeaponItemPtr(); + } + + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + if (weaponCategory == NULL) + { + return CInventoryWeaponItemPtr(); + } + + // Cycle through all available weapons and find the one with the given name + for (int i = 0; i < weaponCategory->GetNumItems(); ++i) + { + CInventoryWeaponItemPtr weapon = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); + + if (weapon != NULL && weaponName == weapon->GetWeaponName()) + { + return weapon; // Found! + } + } + + return CInventoryWeaponItemPtr(); +} + +void idPlayer::SortWeaponItems() +{ + // A local storage, to sort weapons by index + // This code is kind of cumbersome, the idList<>::Sort code is not really suitable for non-raw pointers + std::map weapons; + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Sorting weapon items.\r"); + + // Add it to the weapon category + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + for (int i = 0; i < weaponCategory->GetNumItems(); ++i) + { + CInventoryWeaponItemPtr item = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); + + if (item == NULL) continue; + + // Store the item in the map + weapons[item->GetWeaponIndex()] = item; + } + + // Finally, add all found weapons to our inventory category, sorted by their index + for (std::map::const_iterator i = weapons.begin(); i != weapons.end(); ++i) + { + // Remove first, will be pushed to back + weaponCategory->RemoveItem(i->second); + + // Add it to the weapon category + weaponCategory->PutItemBack(i->second); + } + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon items sorted, we have now %d items.\r", weaponCategory->GetNumItems()); +} + +void idPlayer::AddWeaponsToInventory() +{ + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) + { + if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs + + // Get the weapon index from the key by removing the prefix + idStr weaponNumStr = kv->GetKey(); + weaponNumStr.StripLeading("def_weapon"); + + if (weaponNumStr.IsEmpty() || !weaponNumStr.IsNumeric()) continue; // not a numeric weapon + + int weaponNum = atoi(weaponNumStr); + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Trying to add weapon as defined by key %s to inventory (index %d)\r", kv->GetKey().c_str(), weaponNum); + + idStr weaponDef(kv->GetValue()); + + if (gameLocal.FindEntityDefDict(weaponDef) == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Weapon entityDef not found: %s\r", weaponDef.c_str()); + continue; + } + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Adding weapon to inventory: %s\r", weaponDef.c_str()); + + // Allocate a new weapon item using the found entityDef + CInventoryWeaponItemPtr item(new CInventoryWeaponItem(weaponDef, this)); + + item->SetWeaponIndex(weaponNum); + + // Add it to the weapon category, will be sorted later on + weaponCategory->PutItemBack(item); + } + + SortWeaponItems(); + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Total number of weapons: %d\r", m_WeaponCursor->GetCurrentCategory()->GetNumItems()); +} + +void idPlayer::NextInventoryMap() +{ + if (GetImmobilization() & EIM_ITEM_SELECT) return; + + if (m_MapCursor == NULL) + { + return; // We have no cursor! + } + + CInventoryItemPtr prevMapItem = m_MapCursor->GetCurrentItem(); + + if (prevMapItem != NULL) + { + // We already have a map selected, toggle it off + UseInventoryItem(EPressed, prevMapItem, 0, false); + } + + // Clear any previously active maps + ClearActiveInventoryMap(); + + if (m_MapCursor->IsLastItemInCategory()) + { + // Reached last map, return without cycling to the next map + // Clear the item, so that we start afresh next time + m_MapCursor->ClearItem(); + return; + } + + // Advance the cursor to the next item + CInventoryItemPtr nextMapItem = m_MapCursor->GetNextItem(); + + if (nextMapItem != NULL && nextMapItem != prevMapItem) + { + // Use this new item + UseInventoryItem(EPressed, nextMapItem, 0, false); + } +} + +bool idPlayer::WaitUntilReady() +{ + if (IsReady() || !cv_player_waituntilready.GetBool()) + { + ready = true; + return true; + } + + // Create the overlay if necessary + if (m_WaitUntilReadyGuiHandle == OVERLAYS_INVALID_HANDLE) + { + m_WaitUntilReadyGuiHandle = CreateOverlay(cv_tdm_waituntilready_gui_file.GetString(), LAYER_WAITUNTILREADY); + + if (m_WaitUntilReadyGuiHandle == OVERLAYS_INVALID_HANDLE) + { + gameLocal.Warning("Cannot find wait-until-ready GUI %s", cv_tdm_waituntilready_gui_file.GetString()); + ready = true; + return ready; // done + } + } + + idUserInterface* gui = GetOverlay(m_WaitUntilReadyGuiHandle); + + // Make sure we have a valid mission number in the GUI, the first mission is always 1 + int missionNum = gameLocal.m_MissionManager->GetCurrentMissionIndex() + 1; + gui->SetStateInt("CurrentMission", missionNum); + + // Remember button state of the previous frame + oldButtons = usercmd.buttons; + + // grab out usercmd + usercmd_t oldCmd = usercmd; + usercmd = gameLocal.usercmds[ entityNumber ]; + buttonMask &= usercmd.buttons; + usercmd.buttons &= ~buttonMask; + + // Allow cursor movement in the GUI, even if it's hidden anyway + if (usercmd.mx != oldMouseX || usercmd.my != oldMouseY) + { + sysEvent_t ev = sys->GenerateMouseMoveEvent(usercmd.mx - oldMouseX, usercmd.my - oldMouseY); + gui->HandleEvent(&ev, m_WaitUntilReadyGuiTime); + oldMouseX = usercmd.mx; + oldMouseY = usercmd.my; + } + + // Allow attack button actions to be propagated to the GUI + if ((oldButtons ^ usercmd.buttons) & BUTTON_ATTACK) + { + bool updateVisuals = false; + + sysEvent_t ev = sys->GenerateMouseButtonEvent(1, ( usercmd.buttons & BUTTON_ATTACK ) != 0); + idStr cmd = gui->HandleEvent(&ev, m_WaitUntilReadyGuiTime, &updateVisuals); + + if (cmd == "playerIsReady") + { + int delay = gui->GetStateInt("DestroyDelay"); + + PostEventMS(&EV_DestroyOverlay, delay, m_WaitUntilReadyGuiHandle); + + // We can safely disconnect the GUI handle now, it has been passed by value to the event system + m_WaitUntilReadyGuiHandle = OVERLAYS_INVALID_HANDLE; + + // We're handing control over to the Overlay System, add the time offset to the GUI + gui->SetStateInt("GuiTimeOffset", m_WaitUntilReadyGuiTime); + + // We're done here, the GUI will be doing it's stuff and be destroyed after the given delay + // In the meantime, the overlay system will issue a few Redraw() calls to the GUI using our time offset. + ready = true; + } + } + + // Redraw the GUI + gui->Redraw(m_WaitUntilReadyGuiTime); + + // Increase the "private" GUI time + m_WaitUntilReadyGuiTime += gameLocal.msec; + + return ready; +} + +void idPlayer::CreateObjectivesGUI() +{ + if (objectivesOverlay != -1) return; + + objectivesOverlay = CreateOverlay(cv_tdm_obj_gui_file.GetString(), LAYER_OBJECTIVES); + + idUserInterface* objGUI = GetOverlay(objectivesOverlay); + + if (objGUI == NULL) + { + gameLocal.Error("Failed setting up objectives GUI: %s", cv_tdm_obj_gui_file.GetString()); + return; + } + + objGUI->HandleNamedEvent("InitObjectivesGUI"); + + // Set the weapon and inventory immobilisation flags + SetImmobilization("objectivesDisplay", EIM_WEAPON_SELECT | EIM_ITEM_USE | EIM_ITEM_SELECT | EIM_ITEM_DROP | EIM_FROB | EIM_FROB_COMPLEX); + + // Trigger an update + UpdateObjectivesGUI(); +} + +void idPlayer::DestroyObjectivesGUI() +{ + if (objectivesOverlay == -1) return; + + SetImmobilization("objectivesDisplay", 0); + + DestroyOverlay(objectivesOverlay); + objectivesOverlay = -1; +} + +void idPlayer::ToggleObjectivesGUI() +{ + if (objectivesOverlay == -1) + { + CreateObjectivesGUI(); + } + else + { + DestroyObjectivesGUI(); + } +} + +void idPlayer::UpdateObjectivesGUI() +{ + if (objectivesOverlay == -1) return; + + idUserInterface* objGUI = m_overlays.getGui(objectivesOverlay); + + if (objGUI == NULL) + { + gameLocal.Error("Could not find objectives GUI: %s", cv_tdm_obj_gui_file.GetString()); + return; + } + + // Trigger an update for this GUI + gameLocal.m_MissionData->UpdateGUIState(objGUI); +} + +void idPlayer::SetupInventory() +{ + m_InventoryOverlay = CreateOverlay(cv_tdm_inv_gui_file.GetString(), LAYER_INVENTORY); + + idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); + + if (invGUI == NULL) + { + gameLocal.Error("Could not set up inventory GUI: %s", cv_tdm_inv_gui_file.GetString()); + return; + } + + // Initialise the pickup message system + invGUI->HandleNamedEvent("SetupInventoryPickUpMessageSystem"); + + const CInventoryPtr& inv = Inventory(); + int idx = 0; + + // We create a cursor and a category for the weapons, which is then locked + // to this category, so we can only cycle within that one group. + m_WeaponCursor = inv->CreateCursor(); + inv->CreateCategory(TDM_PLAYER_WEAPON_CATEGORY, &idx); + m_WeaponCursor->SetCurrentCategory(idx); + m_WeaponCursor->SetCategoryLock(true); + + // greebo: Parse the spawnargs and add the weapon items to the inventory. + AddWeaponsToInventory(); + + // Disable all non-ammo weapons except unarmed, the items will be given by the shop + CInventoryCategoryPtr category = m_WeaponCursor->GetCurrentCategory(); + for (int i = 0; i < category->GetNumItems(); i++) + { + CInventoryWeaponItemPtr item = + boost::dynamic_pointer_cast(category->GetItem(i)); + + if (item->GetWeaponIndex() != 0 && item->IsAllowedEmpty()) + { + // Doesn't need ammo, disable this weapon for now + item->SetEnabled(false); + } + } + + // greebo: Create the cursor for map/floorplan inventory items. + m_MapCursor = inv->CreateCursor(); + inv->CreateCategory(TDM_PLAYER_MAPS_CATEGORY, &idx); + m_MapCursor->SetCurrentCategory(idx); + m_MapCursor->SetCategoryLock(true); + m_MapCursor->SetWrapAround(true); + m_MapCursor->ClearItem(); // invalidate the cursor + + // give the player weapon ammo based on shop purchases + category = m_WeaponCursor->GetCurrentCategory(); + const ShopItemList& startingItems = gameLocal.m_Shop->GetPlayerStartingEquipment(); + + for (int si = 0; si < startingItems.Num(); si++) + { + const CShopItemPtr& shopItem = startingItems[si]; + idStr weaponName = shopItem->GetID(); + + // greebo: Append "atdm:" if it's missing, all weapon entityDefs are atdm:* now + if (idStr::Cmpn(weaponName, "atdm:", 5) != 0) + { + weaponName = "atdm:" + weaponName; + } + + if (idStr::Cmpn(weaponName, "atdm:weapon_", 12) == 0) + { + weaponName.Strip("atdm:weapon_"); + + for (int i = 0; i < category->GetNumItems(); i++) + { + CInventoryWeaponItemPtr item = + boost::dynamic_pointer_cast(category->GetItem(i)); + + if (item->GetWeaponName() == weaponName) + { + // Enable non-ammo weapons, if the count is > 0 + if (item->IsAllowedEmpty()) + { + item->SetEnabled(shopItem->GetCount() > 0); + } + + // greebo: Don't set the persistent flag for weapons, they need to be persistent at all times + // The carry-over limits can be controlled via atdm:campaign_info objects + // item->SetPersistent(shopItem->GetPersistent()); + + // Set the ammo + item->SetAmmo(shopItem->GetCount()); + break; + } + } + } + } + + // Now create the standard cursor for all the other inventory items (excl. weapons) + CInventoryCursorPtr crsr = InventoryCursor(); + + // We set the filter to ignore the weapon category, since this will be + // handled by the weapon cursor. We don't want the weapons to show up + // in the weapon slot AND in the inventory at the same time. + crsr->AddCategoryIgnored(TDM_PLAYER_WEAPON_CATEGORY); + + // The player always gets a dummyentry (so the player can have an empty space if he + // chooses to not see the inventory all the time. + CInventoryItemPtr it(new CInventoryItem(this)); + it->SetName(TDM_DUMMY_ITEM); + it->SetType(CInventoryItem::IT_DUMMY); + it->SetCount(0); + it->SetStackable(false); + crsr->Inventory()->PutItem(it, TDM_INVENTORY_DEFAULT_GROUP); + + // Focus on the empty dummy inventory item + crsr->SetCurrentItem(TDM_DUMMY_ITEM); + m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; + + // greebo: Set up the loot inventory item + const idDeclEntityDef* lootItemDef = static_cast( + declManager->FindType(DECL_ENTITYDEF, cv_tdm_inv_loot_item_def.GetString()) + ); + + if (lootItemDef == NULL) + { + gameLocal.Error("Could not find loot inventory entityDef.\n"); + } + + idEntity* lootItemEnt; + gameLocal.SpawnEntityDef(lootItemDef->dict, &lootItemEnt); + + assert(lootItemEnt != NULL); // must succeed + + CInventoryItemPtr lootItem = Inventory()->PutItem(lootItemEnt, this); + assert(lootItem != NULL); // must succeed as well + + // Flag this item as loot info item + lootItem->SetType(CInventoryItem::IT_LOOT_INFO); + + // Give player non-weapon items obtained from the Shop + for (int si = 0; si < startingItems.Num(); si++) + { + const CShopItemPtr& item = startingItems[si]; + + idStr itemName = item->GetID(); + int count = item->GetCount(); + + // greebo: Append "atdm:" if it's missing, all weapon entityDefs are atdm:* now + if (idStr::Cmpn(itemName, "atdm:", 5) != 0) + { + itemName = "atdm:" + itemName; + } + + if (idStr::Cmpn(itemName, "atdm:weapon_", 12) != 0 && count > 0) + { + const idStringList& classNames = item->GetClassnames(); + + for (int j = 0; j < classNames.Num(); ++j) + { + // Spawn this entitydef + const idDict* itemDict = gameLocal.FindEntityDefDict(classNames[j], true); + + idEntity* entity = NULL; + gameLocal.SpawnEntityDef( *itemDict, &entity ); + + // Inhibit pickup messages for these items + entity->spawnArgs.Set("inv_no_pickup_message", "1"); + + // grayman #2467 - Items added in this manner should be set to inv_map_start = 0. + // Otherwise they run the risk of being deleted when the map processes inv_map_start/1 items. + // Since this item is now in the inventory, inv_map_start should no longer need to be queried. + entity->spawnArgs.Set("inv_map_start", "0"); + + // add it to the inventory + CInventoryItemPtr invItem = crsr->Inventory()->PutItem(entity, this); + + invItem->SetCount(count); + invItem->SetPersistent(item->GetPersistent()); + } + } + } + + // Carry over persistent items from the previous map + AddPersistentInventoryItems(); +} + +void idPlayer::AddPersistentInventoryItems() +{ + // Copy all persistent items into our own inventory + Inventory()->CopyPersistentItemsFrom(*gameLocal.persistentPlayerInventory, this); + + // There might be new weapons coming in, sort the category again + SortWeaponItems(); + + // We've changed maps, let's respawn our item entities where needed, put them to our own position + Inventory()->RestoreItemEntities(GetPhysics()->GetOrigin()); +} + +/* +============== +idPlayer::~idPlayer() + +Release any resources used by the player. +============== +*/ +idPlayer::~idPlayer() +{ + delete weapon.GetEntity(); + weapon = NULL; +} + +/* +=========== +idPlayer::Save +=========== +*/ +void idPlayer::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteUsercmd( usercmd ); + playerView.Save( savefile ); + + savefile->WriteBool( noclip ); + savefile->WriteBool( godmode ); + + // don't save spawnAnglesSet, since we'll have to reset them after loading the savegame + savefile->WriteAngles( spawnAngles ); + savefile->WriteAngles( viewAngles ); + savefile->WriteAngles( cmdAngles ); + + // Mouse gesture + m_MouseGesture.Save( savefile ); + m_FrobPressedTarget.Save( savefile ); + + m_FrobEntity.Save(savefile); + savefile->WriteJoint(m_FrobJoint); + savefile->WriteInt(m_FrobID); + savefile->WriteTrace(m_FrobTrace); + savefile->WriteBool(m_bFrobOnlyUsedByInv); + + savefile->WriteInt( buttonMask ); + savefile->WriteInt( oldButtons ); + savefile->WriteInt( oldFlags ); + + savefile->WriteInt( lastHitTime ); + savefile->WriteInt( lastSndHitTime ); + savefile->WriteInt( lastSavingThrowTime ); + + savefile->WriteInt( lockpickHUD ); + savefile->WriteBool( hasLanded ); + + // idBoolFields don't need to be saved, just re-linked in Restore + + weapon.Save( savefile ); + + savefile->WriteUserInterface( hud, false ); + savefile->WriteBool(inventoryHUDNeedsUpdate); + + savefile->WriteInt(hudMessages.Num()); + for (int i = 0; i < hudMessages.Num(); i++) + { + savefile->WriteString(hudMessages[i]); + } + + savefile->WriteInt(inventoryPickedUpMessages.Num()); + for (int i = 0; i < inventoryPickedUpMessages.Num(); i++) + { + savefile->WriteString(inventoryPickedUpMessages[i]); + } + + savefile->WriteInt( weapon_fists ); + + savefile->WriteInt( heartRate ); + savefile->WriteBool(m_HeartBeatAllow); + + savefile->WriteFloat( heartInfo.GetStartTime() ); + savefile->WriteFloat( heartInfo.GetDuration() ); + savefile->WriteFloat( heartInfo.GetStartValue() ); + savefile->WriteFloat( heartInfo.GetEndValue() ); + + savefile->WriteInt( lastHeartAdjust ); + savefile->WriteInt( lastHeartBeat ); + savefile->WriteInt( lastDmgTime ); + savefile->WriteInt( deathClearContentsTime ); + savefile->WriteBool( doingDeathSkin ); + savefile->WriteInt( lastArmorPulse ); + savefile->WriteFloat( stamina ); + savefile->WriteFloat( healthPool ); + savefile->WriteInt( nextHealthPulse ); + savefile->WriteBool( healthPulse ); + savefile->WriteInt( nextHealthTake ); + savefile->WriteBool( healthTake ); + + savefile->WriteInt(healthPoolStepAmount); + savefile->WriteInt(healthPoolTimeInterval); + savefile->WriteFloat(healthPoolTimeIntervalFactor); + + savefile->WriteBool( hiddenWeapon ); + + savefile->WriteInt( spectator ); + savefile->WriteVec3( colorBar ); + savefile->WriteInt( colorBarIndex ); + savefile->WriteBool( scoreBoardOpen ); + savefile->WriteBool( forceScoreBoard ); + savefile->WriteBool( forceRespawn ); + savefile->WriteBool( spectating ); + savefile->WriteInt( lastSpectateTeleport ); + savefile->WriteBool( lastHitToggle ); + savefile->WriteBool( forcedReady ); + savefile->WriteBool( wantSpectate ); + savefile->WriteBool( weaponGone ); + savefile->WriteBool( useInitialSpawns ); + savefile->WriteInt( latchedTeam ); + savefile->WriteInt( tourneyRank ); + savefile->WriteInt( tourneyLine ); + + teleportEntity.Save( savefile ); + savefile->WriteInt( teleportKiller ); + + savefile->WriteInt( minRespawnTime ); + savefile->WriteInt( maxRespawnTime ); + + savefile->WriteVec3( firstPersonViewOrigin ); + savefile->WriteMat3( firstPersonViewAxis ); + + // don't bother saving dragEntity since it's a dev tool + + savefile->WriteJoint( hipJoint ); + savefile->WriteJoint( chestJoint ); + savefile->WriteJoint( headJoint ); + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteInt( aasLocation.Num() ); + for( i = 0; i < aasLocation.Num(); i++ ) { + savefile->WriteInt( aasLocation[ i ].areaNum ); + savefile->WriteVec3( aasLocation[ i ].pos ); + } + + savefile->WriteInt( bobFoot ); + savefile->WriteFloat( bobFrac ); + savefile->WriteFloat( bobfracsin ); + savefile->WriteInt( bobCycle ); + savefile->WriteFloat( xyspeed ); + savefile->WriteInt( stepUpTime ); + savefile->WriteFloat( stepUpDelta ); + savefile->WriteFloat( idealLegsYaw ); + savefile->WriteFloat( legsYaw ); + savefile->WriteBool( legsForward ); + savefile->WriteFloat( oldViewYaw ); + savefile->WriteAngles( viewBobAngles ); + savefile->WriteVec3( viewBob ); + savefile->WriteInt( landChange ); + savefile->WriteInt( landTime ); + savefile->WriteInt( lastFootstepPlaytime ); + savefile->WriteBool(isPushing); + + savefile->WriteInt( currentWeapon ); + savefile->WriteInt( idealWeapon ); + savefile->WriteInt( previousWeapon ); + savefile->WriteInt( weaponSwitchTime ); + savefile->WriteBool( weaponEnabled ); + savefile->WriteBool( showWeaponViewModel ); + + savefile->WriteSkin( skin ); + savefile->WriteSkin( powerUpSkin ); + savefile->WriteString( baseSkinName ); + + savefile->WriteInt( numProjectilesFired ); + savefile->WriteInt( numProjectileHits ); + + savefile->WriteBool( airless ); + savefile->WriteInt( airTics ); + savefile->WriteInt( lastAirDamage ); + + savefile->WriteBool(underWaterEffectsActive); + savefile->WriteInt(underWaterGUIHandle); + + savefile->WriteBool( gibDeath ); + savefile->WriteBool( gibsLaunched ); + savefile->WriteVec3( gibsDir ); + + savefile->WriteFloat( zoomFov.GetStartTime() ); + savefile->WriteFloat( zoomFov.GetDuration() ); + savefile->WriteFloat( zoomFov.GetStartValue() ); + savefile->WriteFloat( zoomFov.GetEndValue() ); + + savefile->WriteFloat( centerView.GetStartTime() ); + savefile->WriteFloat( centerView.GetDuration() ); + savefile->WriteFloat( centerView.GetStartValue() ); + savefile->WriteFloat( centerView.GetEndValue() ); + + savefile->WriteBool( fxFov ); + + savefile->WriteFloat( influenceFov ); + savefile->WriteInt( influenceActive ); + savefile->WriteFloat( influenceRadius ); + savefile->WriteObject( influenceEntity ); + savefile->WriteMaterial( influenceMaterial ); + savefile->WriteSkin( influenceSkin ); + + savefile->WriteObject( privateCameraView ); + savefile->WriteVec3( m_ListenerLoc ); + savefile->WriteVec3( m_DoorListenLoc ); + + savefile->WriteDict( &m_immobilization ); + savefile->WriteInt( m_immobilizationCache ); + + savefile->WriteDict( &m_hinderance ); + savefile->WriteFloat( m_hinderanceCache ); + savefile->WriteDict( &m_TurnHinderance ); + savefile->WriteFloat( m_TurnHinderanceCache ); + + for( i = 0; i < NUM_LOGGED_VIEW_ANGLES; i++ ) { + savefile->WriteAngles( loggedViewAngles[ i ] ); + } + for( i = 0; i < NUM_LOGGED_ACCELS; i++ ) { + savefile->WriteInt( loggedAccel[ i ].time ); + savefile->WriteVec3( loggedAccel[ i ].dir ); + } + savefile->WriteInt( currentLoggedAccel ); + +#if 0 + savefile->WriteObject( focusGUIent ); + // can't save focusUI + savefile->WriteObject( focusCharacter ); + savefile->WriteInt( talkCursor ); + savefile->WriteInt( focusTime ); + savefile->WriteObject( focusVehicle ); +#endif + savefile->WriteUserInterface( cursor, false ); + + savefile->WriteInt( oldMouseX ); + savefile->WriteInt( oldMouseY ); + + savefile->WriteBool( tipUp ); + + savefile->WriteInt( lastDamageDef ); + savefile->WriteVec3( lastDamageDir ); + savefile->WriteInt( lastDamageLocation ); + savefile->WriteBool( m_bDamagedThisFrame ); + savefile->WriteInt( smoothedFrame ); + savefile->WriteBool( smoothedOriginUpdated ); + savefile->WriteVec3( smoothedOrigin ); + savefile->WriteAngles( smoothedAngles ); + + savefile->WriteBool( ready ); + savefile->WriteBool( respawning ); + savefile->WriteBool( leader ); + savefile->WriteInt( lastSpectateChange ); + savefile->WriteInt( lastTeleFX ); + + // Commented out by Dram. TDM does not use stamina + //savefile->WriteFloat( pm_stamina.GetFloat() ); + + savefile->WriteBool( m_bGrabberActive ); + savefile->WriteBool( m_bDraggingBody ); + savefile->WriteBool( m_bShoulderingBody ); + + savefile->WriteBool( m_IdealCrouchState ); + savefile->WriteBool( m_CrouchIntent ); + + savefile->WriteInt(m_InventoryOverlay); + + savefile->WriteInt(m_WaitUntilReadyGuiHandle); + savefile->WriteInt(m_WaitUntilReadyGuiTime); + + savefile->WriteInt(objectivesOverlay); + + savefile->WriteBool(m_WeaponCursor != NULL); + if (m_WeaponCursor != NULL) { + savefile->WriteInt(m_WeaponCursor->GetId()); + } + + savefile->WriteBool(m_MapCursor != NULL); + if (m_MapCursor != NULL) { + savefile->WriteInt(m_MapCursor->GetId()); + } + + savefile->WriteString(m_LastItemNameBeforeClear.c_str()); + + m_ActiveInventoryMapEnt.Save(savefile); + + savefile->WriteInt(m_LightgemModifier); + + savefile->WriteInt(static_cast(m_LightgemModifierList.size())); + for (std::map::const_iterator i = m_LightgemModifierList.begin(); i != m_LightgemModifierList.end(); ++i) + { + savefile->WriteString(i->first.c_str()); + savefile->WriteInt(i->second); + } + + savefile->WriteInt(m_LightList.Num()); + for (int i = 0; i < m_LightList.Num(); i++) + { + savefile->WriteObject(m_LightList[i]); + } + + savefile->WriteInt(m_LightgemValue); + savefile->WriteFloat(m_fColVal); + savefile->WriteInt(m_LightgemInterleave); + savefile->WriteBool(ignoreWeaponAttack); // grayman #597 + + if(hud) + { + hud->SetStateString( "message", gameLocal.m_I18N->Translate( "#str_02916" ) ); + hud->HandleNamedEvent( "Message" ); + } +} + +/* +=========== +idPlayer::Restore +=========== +*/ +void idPlayer::Restore( idRestoreGame *savefile ) { + int i; + int num; + float set; + + savefile->ReadUsercmd( usercmd ); + playerView.Restore( savefile ); + + savefile->ReadBool( noclip ); + savefile->ReadBool( godmode ); + + savefile->ReadAngles( spawnAngles ); + savefile->ReadAngles( viewAngles ); + savefile->ReadAngles( cmdAngles ); + + memset( usercmd.angles, 0, sizeof( usercmd.angles ) ); + SetViewAngles( viewAngles ); + spawnAnglesSet = true; + + m_MouseGesture.Restore( savefile ); + m_FrobPressedTarget.Restore( savefile ); + + m_FrobEntity.Restore(savefile); + savefile->ReadJoint(m_FrobJoint); + savefile->ReadInt(m_FrobID); + savefile->ReadTrace(m_FrobTrace); + savefile->ReadBool(m_bFrobOnlyUsedByInv); + + savefile->ReadInt( buttonMask ); + savefile->ReadInt( oldButtons ); + savefile->ReadInt( oldFlags ); + + usercmd.flags = 0; + oldFlags = 0; + + savefile->ReadInt( lastHitTime ); + savefile->ReadInt( lastSndHitTime ); + savefile->ReadInt( lastSavingThrowTime ); + + savefile->ReadInt( lockpickHUD ); + savefile->ReadBool( hasLanded ); + + // Re-link idBoolFields to the scriptObject, values will be restored in scriptObject's restore + LinkScriptVariables(); + + weapon.Restore( savefile ); + + savefile->ReadUserInterface( hud ); + savefile->ReadBool(inventoryHUDNeedsUpdate); + + savefile->ReadInt(num); + hudMessages.Clear(); + hudMessages.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(hudMessages[i]); + } + + savefile->ReadInt(num); + inventoryPickedUpMessages.Clear(); + inventoryPickedUpMessages.SetNum(num); + for (i = 0; i < num; i++) + { + savefile->ReadString(inventoryPickedUpMessages[i]); + } + + savefile->ReadInt( weapon_fists ); + + savefile->ReadInt( heartRate ); + savefile->ReadBool(m_HeartBeatAllow); + + savefile->ReadFloat( set ); + heartInfo.SetStartTime( set ); + savefile->ReadFloat( set ); + heartInfo.SetDuration( set ); + savefile->ReadFloat( set ); + heartInfo.SetStartValue( set ); + savefile->ReadFloat( set ); + heartInfo.SetEndValue( set ); + + savefile->ReadInt( lastHeartAdjust ); + savefile->ReadInt( lastHeartBeat ); + savefile->ReadInt( lastDmgTime ); + savefile->ReadInt( deathClearContentsTime ); + savefile->ReadBool( doingDeathSkin ); + savefile->ReadInt( lastArmorPulse ); + savefile->ReadFloat( stamina ); + savefile->ReadFloat( healthPool ); + savefile->ReadInt( nextHealthPulse ); + savefile->ReadBool( healthPulse ); + savefile->ReadInt( nextHealthTake ); + savefile->ReadBool( healthTake ); + + savefile->ReadInt(healthPoolStepAmount); + savefile->ReadInt(healthPoolTimeInterval); + savefile->ReadFloat(healthPoolTimeIntervalFactor); + + savefile->ReadBool( hiddenWeapon ); + + savefile->ReadInt( spectator ); + savefile->ReadVec3( colorBar ); + savefile->ReadInt( colorBarIndex ); + savefile->ReadBool( scoreBoardOpen ); + savefile->ReadBool( forceScoreBoard ); + savefile->ReadBool( forceRespawn ); + savefile->ReadBool( spectating ); + savefile->ReadInt( lastSpectateTeleport ); + savefile->ReadBool( lastHitToggle ); + savefile->ReadBool( forcedReady ); + savefile->ReadBool( wantSpectate ); + savefile->ReadBool( weaponGone ); + savefile->ReadBool( useInitialSpawns ); + savefile->ReadInt( latchedTeam ); + savefile->ReadInt( tourneyRank ); + savefile->ReadInt( tourneyLine ); + + teleportEntity.Restore( savefile ); + savefile->ReadInt( teleportKiller ); + + savefile->ReadInt( minRespawnTime ); + savefile->ReadInt( maxRespawnTime ); + + savefile->ReadVec3( firstPersonViewOrigin ); + savefile->ReadMat3( firstPersonViewAxis ); + + // don't bother saving dragEntity since it's a dev tool + dragEntity.Clear(); + + savefile->ReadJoint( hipJoint ); + savefile->ReadJoint( chestJoint ); + savefile->ReadJoint( headJoint ); + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadInt( num ); + aasLocation.SetGranularity( 1 ); + aasLocation.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadInt( aasLocation[ i ].areaNum ); + savefile->ReadVec3( aasLocation[ i ].pos ); + } + + savefile->ReadInt( bobFoot ); + savefile->ReadFloat( bobFrac ); + savefile->ReadFloat( bobfracsin ); + savefile->ReadInt( bobCycle ); + savefile->ReadFloat( xyspeed ); + savefile->ReadInt( stepUpTime ); + savefile->ReadFloat( stepUpDelta ); + savefile->ReadFloat( idealLegsYaw ); + savefile->ReadFloat( legsYaw ); + savefile->ReadBool( legsForward ); + savefile->ReadFloat( oldViewYaw ); + savefile->ReadAngles( viewBobAngles ); + savefile->ReadVec3( viewBob ); + savefile->ReadInt( landChange ); + savefile->ReadInt( landTime ); + savefile->ReadInt( lastFootstepPlaytime ); + savefile->ReadBool(isPushing); + + savefile->ReadInt( currentWeapon ); + savefile->ReadInt( idealWeapon ); + savefile->ReadInt( previousWeapon ); + savefile->ReadInt( weaponSwitchTime ); + savefile->ReadBool( weaponEnabled ); + savefile->ReadBool( showWeaponViewModel ); + + savefile->ReadSkin( skin ); + savefile->ReadSkin( powerUpSkin ); + savefile->ReadString( baseSkinName ); + + savefile->ReadInt( numProjectilesFired ); + savefile->ReadInt( numProjectileHits ); + + savefile->ReadBool( airless ); + savefile->ReadInt( airTics ); + savefile->ReadInt( lastAirDamage ); + + savefile->ReadBool(underWaterEffectsActive); + savefile->ReadInt(underWaterGUIHandle); + + savefile->ReadBool( gibDeath ); + savefile->ReadBool( gibsLaunched ); + savefile->ReadVec3( gibsDir ); + + savefile->ReadFloat( set ); + zoomFov.SetStartTime( set ); + savefile->ReadFloat( set ); + zoomFov.SetDuration( set ); + savefile->ReadFloat( set ); + zoomFov.SetStartValue( set ); + savefile->ReadFloat( set ); + zoomFov.SetEndValue( set ); + + savefile->ReadFloat( set ); + centerView.SetStartTime( set ); + savefile->ReadFloat( set ); + centerView.SetDuration( set ); + savefile->ReadFloat( set ); + centerView.SetStartValue( set ); + savefile->ReadFloat( set ); + centerView.SetEndValue( set ); + + savefile->ReadBool( fxFov ); + + savefile->ReadFloat( influenceFov ); + savefile->ReadInt( influenceActive ); + savefile->ReadFloat( influenceRadius ); + savefile->ReadObject( reinterpret_cast( influenceEntity ) ); + savefile->ReadMaterial( influenceMaterial ); + savefile->ReadSkin( influenceSkin ); + + savefile->ReadObject( reinterpret_cast( privateCameraView ) ); + savefile->ReadVec3( m_ListenerLoc ); + savefile->ReadVec3( m_DoorListenLoc ); + + savefile->ReadDict( &m_immobilization ); + savefile->ReadInt( m_immobilizationCache ); + + savefile->ReadDict( &m_hinderance ); + savefile->ReadFloat( m_hinderanceCache ); + savefile->ReadDict( &m_TurnHinderance ); + savefile->ReadFloat( m_TurnHinderanceCache ); + + for( i = 0; i < NUM_LOGGED_VIEW_ANGLES; i++ ) { + savefile->ReadAngles( loggedViewAngles[ i ] ); + } + for( i = 0; i < NUM_LOGGED_ACCELS; i++ ) { + savefile->ReadInt( loggedAccel[ i ].time ); + savefile->ReadVec3( loggedAccel[ i ].dir ); + } + savefile->ReadInt( currentLoggedAccel ); + +#if 0 + savefile->ReadObject( reinterpret_cast( focusGUIent ) ); + // can't save focusUI + focusUI = NULL; + savefile->ReadObject( reinterpret_cast( focusCharacter ) ); + savefile->ReadInt( talkCursor ); + savefile->ReadInt( focusTime ); + savefile->ReadObject( reinterpret_cast( focusVehicle ) ); +#endif + savefile->ReadUserInterface( cursor ); + + savefile->ReadInt( oldMouseX ); + savefile->ReadInt( oldMouseY ); + + savefile->ReadBool( tipUp ); + + savefile->ReadInt( lastDamageDef ); + savefile->ReadVec3( lastDamageDir ); + savefile->ReadInt( lastDamageLocation ); + savefile->ReadBool( m_bDamagedThisFrame ); + savefile->ReadInt( smoothedFrame ); + savefile->ReadBool( smoothedOriginUpdated ); + savefile->ReadVec3( smoothedOrigin ); + savefile->ReadAngles( smoothedAngles ); + + savefile->ReadBool( ready ); + savefile->ReadBool( respawning ); + savefile->ReadBool( leader ); + savefile->ReadInt( lastSpectateChange ); + savefile->ReadInt( lastTeleFX ); + + // set the pm_ cvars + const idKeyValue *kv; + kv = spawnArgs.MatchPrefix( "pm_", NULL ); + while( kv ) { + cvarSystem->SetCVarString( kv->GetKey(), kv->GetValue() ); + kv = spawnArgs.MatchPrefix( "pm_", kv ); + } + + // savefile->ReadFloat( set ); + // Commented out by Dram. TDM does not use stamina + //pm_stamina.SetFloat( set ); + + savefile->ReadBool( m_bGrabberActive ); + savefile->ReadBool( m_bDraggingBody ); + savefile->ReadBool( m_bShoulderingBody ); + + savefile->ReadBool( m_IdealCrouchState ); + savefile->ReadBool( m_CrouchIntent ); + + savefile->ReadInt(m_InventoryOverlay); + + savefile->ReadInt(m_WaitUntilReadyGuiHandle); + savefile->ReadInt(m_WaitUntilReadyGuiTime); + + savefile->ReadInt(objectivesOverlay); + + bool hasWeaponCursor; + savefile->ReadBool(hasWeaponCursor); + if (hasWeaponCursor) { + int cursorId; + savefile->ReadInt(cursorId); + m_WeaponCursor = Inventory()->GetCursor(cursorId); + } + + bool hasMapCursor; + savefile->ReadBool(hasMapCursor); + if (hasMapCursor) { + int cursorId; + savefile->ReadInt(cursorId); + m_MapCursor = Inventory()->GetCursor(cursorId); + } + + savefile->ReadString(m_LastItemNameBeforeClear); + + m_ActiveInventoryMapEnt.Restore(savefile); + + savefile->ReadInt(m_LightgemModifier); + + savefile->ReadInt(num); + for (int i = 0; i < num; i++) + { + idStr name; + int value; + savefile->ReadString(name); + savefile->ReadInt(value); + // Store the pair into the map + m_LightgemModifierList[std::string(name.c_str())] = value; + } + + savefile->ReadInt(num); + m_LightList.SetNum(num); + for (int i = 0; i < num; i++) + { + idLight* light = NULL; + savefile->ReadObject(reinterpret_cast(light)); + m_LightList[i] = light; + } + + savefile->ReadInt(m_LightgemValue); + savefile->ReadFloat(m_fColVal); + savefile->ReadInt(m_LightgemInterleave); + savefile->ReadBool(ignoreWeaponAttack); // grayman #597 + + // create combat collision hull for exact collision detection + SetCombatModel(); + + // Necessary, since the overlay system can't save external GUI pointers. + if ( m_overlays.isExternal( OVERLAYS_MIN_HANDLE ) ) + m_overlays.setGui( OVERLAYS_MIN_HANDLE, hud ); + else + gameLocal.Warning( "Unable to relink HUD to overlay system.\n" ); +} + +/* +=============== +idPlayer::PrepareForRestart +================ +*/ +void idPlayer::PrepareForRestart( void ) { + Spectate( true ); + forceRespawn = true; + + // we will be restarting program, clear the client entities from program-related things first + ShutdownThreads(); + + // the sound world is going to be cleared, don't keep references to emitters + FreeSoundEmitter( false ); +} + +/* +=============== +idPlayer::Restart +================ +*/ +void idPlayer::Restart( void ) { + idActor::Restart(); + + // client needs to setup the animation script object again + if ( gameLocal.isClient ) { + Init(); + } else { + // choose a random spot and prepare the point of view in case player is left spectating + assert( spectating ); + SpawnFromSpawnSpot(); + } + + useInitialSpawns = true; + UpdateSkinSetup( true ); +} + +/* +=============== +idPlayer::ServerSpectate +================ +*/ +void idPlayer::ServerSpectate( bool spectate ) { + assert( !gameLocal.isClient ); + + if ( spectating != spectate ) { + Spectate( spectate ); + if ( spectate ) { + SetSpectateOrigin(); + } else { + if ( gameLocal.gameType == GAME_DM ) { + // make sure the scores are reset so you can't exploit by spectating and entering the game back + // other game types don't matter, as you either can't join back, or it's team scores + gameLocal.mpGame.ClearFrags( entityNumber ); + } + } + } + if ( !spectate ) { + SpawnFromSpawnSpot(); + } +} + +/* +=========== +idPlayer::SelectInitialSpawnPoint + +Try to find a spawn point marked 'initial', otherwise +use normal spawn selection. +============ +*/ +void idPlayer::SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles ) { + idEntity *spot; + idStr skin; + + spot = gameLocal.SelectInitialSpawnPoint( this ); + + // set the player skin from the spawn location + if ( spot->spawnArgs.GetString( "skin", NULL, skin ) ) { + spawnArgs.Set( "spawn_skin", skin ); + } + + // activate the spawn locations targets + spot->PostEventMS( &EV_ActivateTargets, 0, this ); + + origin = spot->GetPhysics()->GetOrigin(); + origin[2] += 4.0f + CM_BOX_EPSILON; // move up to make sure the player is at least an epsilon above the floor + angles = spot->GetPhysics()->GetAxis().ToAngles(); +} + +/* +=========== +idPlayer::SpawnFromSpawnSpot + +Chooses a spawn location and spawns the player +============ +*/ +void idPlayer::SpawnFromSpawnSpot( void ) { + idVec3 spawn_origin; + idAngles spawn_angles; + + SelectInitialSpawnPoint( spawn_origin, spawn_angles ); + SpawnToPoint( spawn_origin, spawn_angles ); +} + +/* +=========== +idPlayer::SpawnToPoint + +Called every time a client is placed fresh in the world: +after the first ClientBegin, and after each respawn +Initializes all non-persistant parts of playerState + +when called here with spectating set to true, just place yourself and init +============ +*/ +void idPlayer::SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles ) { + idVec3 spec_origin; + + assert( !gameLocal.isClient ); + + respawning = true; + + Init(); + + fl.noknockback = false; + + // stop any ragdolls being used + StopRagdoll(); + + // set back the player physics + SetPhysics( &physicsObj ); + + physicsObj.SetClipModelAxis(); + physicsObj.EnableClip(); + + if ( !spectating ) { + SetCombatContents( true ); + } + + physicsObj.SetLinearVelocity( vec3_origin ); + + // setup our initial view + if ( !spectating ) { + SetOrigin( spawn_origin ); + } else { + spec_origin = spawn_origin; + spec_origin[ 2 ] += pm_normalheight.GetFloat(); + spec_origin[ 2 ] += SPECTATE_RAISE; + SetOrigin( spec_origin ); + } + + // if this is the first spawn of the map, we don't have a usercmd yet, + // so the delta angles won't be correct. This will be fixed on the first think. + viewAngles = ang_zero; + SetDeltaViewAngles( ang_zero ); + SetViewAngles( spawn_angles ); + spawnAngles = spawn_angles; + spawnAnglesSet = false; + + legsForward = true; + legsYaw = 0.0f; + idealLegsYaw = 0.0f; + oldViewYaw = viewAngles.yaw; + + if ( spectating ) { + Hide(); + } else { + Show(); + } + + if ( gameLocal.isMultiplayer ) { + if ( !spectating ) { + // we may be called twice in a row in some situations. avoid a double fx and 'fly to the roof' + if ( lastTeleFX < gameLocal.time - 1000 ) { + idEntityFx::StartFx( spawnArgs.GetString( "fx_spawn" ), &spawn_origin, NULL, this, true ); + lastTeleFX = gameLocal.time; + } + } + AI_TELEPORT = true; + } else { + AI_TELEPORT = false; + } + + // kill anything at the new position + if ( !spectating ) { + physicsObj.SetClipMask( MASK_PLAYERSOLID ); // the clip mask is usually maintained in Move(), but KillBox requires it + gameLocal.KillBox( this ); + } + + // don't allow full run speed for a bit + physicsObj.SetKnockBack( 100 ); + + // set our respawn time and buttons so that if we're killed we don't respawn immediately + minRespawnTime = gameLocal.time; + maxRespawnTime = gameLocal.time; + if ( !spectating ) { + forceRespawn = false; + } + + privateCameraView = NULL; + + BecomeActive( TH_THINK ); + + // run a client frame to drop exactly to the floor, + // initialize animations and other things + Think(); + + respawning = false; + lastManOver = false; + lastManPlayAgain = false; + isTelefragged = false; +} + +/* +=============== +idPlayer::SavePersistantInfo + +Saves any inventory and player stats when changing levels. +=============== +*/ +void idPlayer::SavePersistantInfo( void ) { + idDict &playerInfo = gameLocal.persistentPlayerInfo[entityNumber]; + + playerInfo.Clear(); + + // greebo: Don't persist current weapon when switching maps (issue #2774) + // Keep writing the health value to the dict, the engine is using that to query the player's health + playerInfo.SetInt( "health", health ); +#if 0 + playerInfo.SetInt( "current_weapon", currentWeapon ); +#endif +} + +/* +=============== +idPlayer::RestorePersistantInfo + +Restores any inventory and player stats when changing levels. +=============== +*/ +void idPlayer::RestorePersistantInfo( void ) { + if ( gameLocal.isMultiplayer ) { + gameLocal.persistentPlayerInfo[entityNumber].Clear(); + } + + // greebo: TDM doesn't need to load health or weapon from the dict, that is not (yet) intended since + // map switching within missions is not yet planned or fleshed out +#if 0 + spawnArgs.Copy( gameLocal.persistentPlayerInfo[entityNumber] ); + + health = spawnArgs.GetInt( "health", "100" ); + if ( !gameLocal.isClient ) { + idealWeapon = spawnArgs.GetInt( "current_weapon", "0" ); + } +#endif +} + +/* +================ +idPlayer::GetUserInfo +================ +*/ +idDict *idPlayer::GetUserInfo( void ) { + return &gameLocal.userInfo[ entityNumber ]; +} + +/* +============== +idPlayer::UpdateSkinSetup +============== +*/ +void idPlayer::UpdateSkinSetup( bool restart ) { + if ( restart ) { + team = ( idStr::Icmp( GetUserInfo()->GetString( "ui_team" ), "Blue" ) == 0 ); + } + if ( gameLocal.gameType == GAME_TDM ) { + if ( team ) { + baseSkinName = "skins/characters/player/marine_mp_blue"; + } else { + baseSkinName = "skins/characters/player/marine_mp_red"; + } + if ( !gameLocal.isClient && team != latchedTeam ) { + gameLocal.mpGame.SwitchToTeam( entityNumber, latchedTeam, team ); + } + latchedTeam = team; + } else { + baseSkinName = GetUserInfo()->GetString( "ui_skin" ); + } + if ( !baseSkinName.Length() ) { + baseSkinName = "skins/characters/player/marine_mp"; + } + skin = declManager->FindSkin( baseSkinName, false ); + assert( skin ); + // match the skin to a color band for scoreboard + if ( baseSkinName.Find( "red" ) != -1 ) { + colorBarIndex = 1; + } else if ( baseSkinName.Find( "green" ) != -1 ) { + colorBarIndex = 2; + } else if ( baseSkinName.Find( "blue" ) != -1 ) { + colorBarIndex = 3; + } else if ( baseSkinName.Find( "yellow" ) != -1 ) { + colorBarIndex = 4; + } else { + colorBarIndex = 0; + } + colorBar = colorBarTable[ colorBarIndex ]; +} + +/* +============== +idPlayer::BalanceTDM +============== +*/ +bool idPlayer::BalanceTDM( void ) { + int i, balanceTeam, teamCount[2]; + idEntity *ent; + + teamCount[ 0 ] = teamCount[ 1 ] = 0; + for( i = 0; i < gameLocal.numClients; i++ ) { + ent = gameLocal.entities[ i ]; + if ( ent && ent->IsType( idPlayer::Type ) ) { + teamCount[ static_cast< idPlayer * >( ent )->team ]++; + } + } + balanceTeam = -1; + if ( teamCount[ 0 ] < teamCount[ 1 ] ) { + balanceTeam = 0; + } else if ( teamCount[ 0 ] > teamCount[ 1 ] ) { + balanceTeam = 1; + } + if ( balanceTeam != -1 && team != balanceTeam ) { + common->DPrintf( "team balance: forcing player %d to %s team\n", entityNumber, balanceTeam ? "blue" : "red" ); + team = balanceTeam; + GetUserInfo()->Set( "ui_team", team ? "Blue" : "Red" ); + return true; + } + return false; +} + +/* +============== +idPlayer::UserInfoChanged +============== +*/ +bool idPlayer::UserInfoChanged( bool canModify ) { + idDict *userInfo; + bool modifiedInfo; + bool spec; + bool newready; + + userInfo = GetUserInfo(); + showWeaponViewModel = userInfo->GetBool( "ui_showGun" ); + + if ( !gameLocal.isMultiplayer ) { + return false; + } + + modifiedInfo = false; + + spec = ( idStr::Icmp( userInfo->GetString( "ui_spectate" ), "Spectate" ) == 0 ); + if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { + // never let spectators go back to game while sudden death is on + if ( canModify && gameLocal.mpGame.GetGameState() == idMultiplayerGame::SUDDENDEATH && !spec && wantSpectate == true ) { + + userInfo->Set( "ui_spectate", "Spectate" ); + modifiedInfo |= true; + } else { + if ( spec != wantSpectate && !spec ) { + // returning from spectate, set forceRespawn so we don't get stuck in spectate forever + forceRespawn = true; + } + wantSpectate = spec; + } + } else { + if ( canModify && spec ) { + + userInfo->Set( "ui_spectate", "Play" ); + modifiedInfo |= true; + } else if ( spectating ) { + // allow player to leaving spectator mode if they were in it when si_spectators got turned off + + forceRespawn = true; + } + wantSpectate = false; + } + newready = ( idStr::Icmp( userInfo->GetString( "ui_ready" ), "Ready" ) == 0 ); + if ( ready != newready && gameLocal.mpGame.GetGameState() == idMultiplayerGame::WARMUP && !wantSpectate ) { + gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( "#str_07180" ), userInfo->GetString( "ui_name" ), newready ? gameLocal.m_I18N->Translate( "#str_04300" ) : gameLocal.m_I18N->Translate( "#str_04301" ) ); + } + ready = newready; + team = ( idStr::Icmp( userInfo->GetString( "ui_team" ), "Blue" ) == 0 ); + // server maintains TDM balance + if ( canModify && gameLocal.gameType == GAME_TDM && !gameLocal.mpGame.IsInGame( entityNumber ) && g_balanceTDM.GetBool() ) { + + modifiedInfo |= BalanceTDM( ); + } + UpdateSkinSetup( false ); + + isChatting = userInfo->GetBool( "ui_chat", "0" ); + if ( canModify && isChatting && AI_DEAD ) { + + // if dead, always force chat icon off. + isChatting = false; + userInfo->SetBool( "ui_chat", false ); + modifiedInfo |= true; + } + + return modifiedInfo; +} + +/* +=============== +idPlayer::UpdateHudAmmo +=============== +*/ +void idPlayer::UpdateHudAmmo() +{ + CInventoryWeaponItemPtr curWeapon = GetCurrentWeaponItem(); + + // If no weapon item there, or the first one is selected, switch off the HUD + bool weaponSelected = (curWeapon != NULL && curWeapon->GetWeaponIndex() > 0); + + hud->SetStateBool("WeaponAmmoVisible", weaponSelected && curWeapon->NeedsAmmo()); + + if (!weaponSelected) return; // done here + + hud->SetStateString("WeaponAmmoAmount", va("%d", curWeapon->GetAmmo())); +} + +/* +=============== +idPlayer::UpdateHudStats +=============== +*/ +void idPlayer::UpdateHudStats( idUserInterface *_hud ) +{ + // Commented out by Dram. TDM does not use stamina + //int staminapercentage; + //float max_stamina; + + assert( _hud ); + + // Commented out by Dram. TDM does not use stamina + /*max_stamina = pm_stamina.GetFloat(); + if ( !max_stamina ) { + // stamina disabled, so show full stamina bar + staminapercentage = 100; + } else { + staminapercentage = idMath::FtoiFast( 100.0f * stamina / max_stamina ); + }*/ + + _hud->SetStateInt( "player_health", health ); + // Commented out by Dram. TDM does not use stamina + //_hud->SetStateInt( "player_stamina", staminapercentage ); + _hud->SetStateInt( "player_shadow", 1 ); + + _hud->SetStateInt( "player_hr", heartRate ); + // Commented out by Dram. TDM does not use stamina + //_hud->SetStateInt( "player_nostamina", ( max_stamina == 0 ) ? 1 : 0 ); + + _hud->HandleNamedEvent( "updateArmorHealthAir" ); + + if ( healthPulse ) { + _hud->HandleNamedEvent( "healthPulse" ); + StartSound( "snd_healthpulse", SND_CHANNEL_ITEM, 0, false, NULL ); + healthPulse = false; + } + + if ( healthTake ) { + _hud->HandleNamedEvent( "healthPulse" ); + StartSound( "snd_healthtake", SND_CHANNEL_ITEM, 0, false, NULL ); + healthTake = false; + } + + UpdateHudAmmo(); +} + +/* +=============== +idPlayer::UpdateHudWeapon +=============== +*/ +void idPlayer::UpdateHudWeapon( bool flashWeapon ) +{ + // if updating the hud of a followed client + if ( gameLocal.localClientNum >= 0 && gameLocal.entities[ gameLocal.localClientNum ] && gameLocal.entities[ gameLocal.localClientNum ]->IsType( idPlayer::Type ) ) { + idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ gameLocal.localClientNum ] ); + if ( p->spectating && p->spectator == entityNumber ) { + assert( p->hud ); + hud = p->hud; + } + } + + if (hud == NULL || m_WeaponCursor == NULL) { + return; + } + + CInventoryWeaponItemPtr curWeapon = GetCurrentWeaponItem(); + + // If no weapon item there, or the first one is selected, switch off the HUD + bool weaponSelected = (curWeapon != NULL && curWeapon->GetWeaponIndex() > 0); + + // Update the visibility of the various GUI elements + hud->SetStateBool("WeaponIconVisible", weaponSelected); + hud->SetStateBool("WeaponNameVisible", weaponSelected); + + if (!weaponSelected) return; // done here + + // Set the icon and name strings + hud->SetStateString("WeaponName", gameLocal.m_I18N->Translate( curWeapon->GetName().c_str() )); + hud->SetStateString("WeaponIcon", curWeapon->GetIcon().c_str()); + + hud->HandleNamedEvent("OnWeaponChange"); + + UpdateHudAmmo(); +} + +void idPlayer::PrintDebugHUD(void) +{ + idStr strText; + idVec3 a, b, c; + int y; + + // TODO: Remove this when no longer needed. + y = 100; + sprintf(strText, "ViewOrg: x: %f y: %f z: %f", renderView->vieworg.x, renderView->vieworg.y, renderView->vieworg.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + renderView->viewaxis.GetMat3Params(a, b, c); + sprintf(strText, "ViewMatrix:", renderView->vieworg.x, renderView->vieworg.y, renderView->vieworg.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "x: %f y: %f z: %f", a.x, a.y, a.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "x: %f y: %f z: %f", b.x, b.y, b.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "x: %f y: %f z: %f", c.x, c.y, c.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "FOV x: %f y: %f", renderView->fov_x, renderView->fov_y); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "ViewAngles Pitch: %f Yaw: %f Roll: %f", viewAngles.pitch, viewAngles.yaw, viewAngles.roll); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + sprintf(strText, "ViewBobAngles Pitch: %f Yaw: %f Roll: %f", viewBobAngles.pitch, viewBobAngles.yaw, viewBobAngles.roll); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + y += 12; + a = GetEyePosition(); + sprintf(strText, "EyePosition x: %f y: %f z: %f", a.x, a.y, a.z); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); +} + +/* +=============== +idPlayer::DrawHUD +=============== +*/ +void idPlayer::DrawHUD(idUserInterface *_hud) +{ +// if(cv_lg_debug.GetInteger() != 0) +// PrintDebugHUD(); + + /*renderSystem->DrawSmallStringExt(1, 30, + va("Player velocity: %f", physicsObj.GetLinearVelocity().Length()), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" ));*/ + + const char *name; + if((name = cv_dm_distance.GetString()) != NULL) + { + idEntity *e; + + if((e = gameLocal.FindEntity(name)) != NULL) + { + idStr strText; + float d; + int y; + + d = (GetPhysics()->GetOrigin() - e->GetPhysics()->GetOrigin()).Length(); + + y = 100; + sprintf(strText, "Entity [%s] distance: %f", name, d); + renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + } + } + + if (cv_frob_debug_hud.GetBool()) + { + idStr name = m_FrobEntity.GetEntity() != NULL ? m_FrobEntity.GetEntity()->name : "none"; + renderSystem->DrawSmallStringExt(1, 120, "Frobbed entity: " + name, idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + + if (m_FrobEntity.GetEntity() != NULL) + { + float distance = (GetEyePosition() - m_FrobTrace.endpos).Length(); + idStr distanceStr = "Distance: " + idStr(distance); + renderSystem->DrawSmallStringExt(1, 150, distanceStr, idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); + } + } + + if(_hud) + { + DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("PlayerHUD: [%s]\r", (_hud->Name() == NULL)?"null":_hud->Name()); + } + else + { + DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("PlayerHUD: NULL\r"); + } + + if ( !weapon.GetEntity() || influenceActive != INFLUENCE_NONE || privateCameraView || gameLocal.GetCamera() || !_hud || !g_showHud.GetBool() ) { + return; + } + + UpdateHudStats( _hud ); + + //_hud->SetStateString( "weapicon", weapon.GetEntity()->Icon() ); + + // FIXME: this is temp to allow the sound meter to show up in the hud + // it should be commented out before shipping but the code can remain + // for mod developers to enable for the same functionality + _hud->SetStateInt( "s_debug", cvarSystem->GetCVarInteger( "s_showLevelMeter" ) ); + + weapon.GetEntity()->UpdateGUI(); + + //_hud->Redraw( gameLocal.realClientTime ); + m_overlays.drawOverlays(); + + // weapon targeting crosshair + +#if 0 // greebo: disabled cursor calls entirely + if ( !GuiActive() ) { + if ( cursor && weapon.GetEntity()->ShowCrosshair() ) { + cursor->Redraw( gameLocal.realClientTime ); + } + } +#endif + + // Only use this if the old lightgem is selected. This may be usefull for + // slower machines. + if (cv_lg_weak.GetBool()) + { + CalculateWeakLightgem(); + } + + // J.C.Denton Start + float fFadeDelay = Max(0.0001f, cv_lg_fade_delay.GetFloat() ); // Avoid divide by zero errors. + m_fBlendColVal = Lerp( m_fBlendColVal, (float)m_LightgemValue, (gameLocal.time - gameLocal.previousTime)/(1000.0f * fFadeDelay ) ); + // J.C.Denton End + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Setting Lightgemvalue: %u on hud: %08lX\r\r", m_LightgemValue, hud); + hud->SetStateFloat("lightgem_val", m_fBlendColVal ); +} + +/* +=============== +idPlayer::EnterCinematic +=============== +*/ +void idPlayer::EnterCinematic( void ) { + Hide(); + + physicsObj.SetLinearVelocity( vec3_origin ); + + SetState( "EnterCinematic" ); + UpdateScript(); + + if ( weaponEnabled && weapon.GetEntity() ) { + weapon.GetEntity()->EnterCinematic(); + } + + AI_FORWARD = false; + AI_BACKWARD = false; + AI_STRAFE_LEFT = false; + AI_STRAFE_RIGHT = false; + AI_RUN = false; + AI_ATTACK_HELD = false; + AI_BLOCK_HELD = false; + AI_WEAPON_FIRED = false; + AI_WEAPON_BLOCKED = false; + AI_JUMP = false; + AI_CROUCH = false; + AI_ONGROUND = true; + AI_ONLADDER = false; + AI_DEAD = ( health <= 0 ); + AI_RUN = false; + AI_PAIN = false; + AI_HARDLANDING = false; + AI_SOFTLANDING = false; + AI_RELOAD = false; + AI_TELEPORT = false; + AI_TURN_LEFT = false; + AI_TURN_RIGHT = false; + + AI_LEAN_LEFT = false; + AI_LEAN_RIGHT = false; + AI_LEAN_FORWARD = false; + + AI_CREEP = false; + + m_pathRank = 1000; // grayman #2345 +} + +/* +=============== +idPlayer::ExitCinematic +=============== +*/ +void idPlayer::ExitCinematic( void ) { + Show(); + + if ( weaponEnabled && weapon.GetEntity() ) { + weapon.GetEntity()->ExitCinematic(); + } + + SetState( "ExitCinematic" ); + UpdateScript(); +} + +/* +===================== +idPlayer::UpdateConditions +===================== +*/ +void idPlayer::UpdateConditions( void ) +{ + idVec3 velocity; + float fallspeed; + float forwardspeed; + float sidespeed; + + // minus the push velocity to avoid playing the walking animation and sounds when riding a mover + velocity = physicsObj.GetLinearVelocity() - physicsObj.GetPushedLinearVelocity(); + fallspeed = velocity * physicsObj.GetGravityNormal(); + + if ( influenceActive ) { + AI_FORWARD = false; + AI_BACKWARD = false; + AI_STRAFE_LEFT = false; + AI_STRAFE_RIGHT = false; + } else if ( gameLocal.time - lastDmgTime < 500 ) { + forwardspeed = velocity * viewAxis[ 0 ]; + sidespeed = velocity * viewAxis[ 1 ]; + AI_FORWARD = AI_ONGROUND && ( forwardspeed > 20.01f ); + AI_BACKWARD = AI_ONGROUND && ( forwardspeed < -20.01f ); + AI_STRAFE_LEFT = AI_ONGROUND && ( sidespeed > 20.01f ); + AI_STRAFE_RIGHT = AI_ONGROUND && ( sidespeed < -20.01f ); + } else if ( xyspeed > MIN_BOB_SPEED ) { + AI_FORWARD = AI_ONGROUND && ( usercmd.forwardmove > 0 ); + AI_BACKWARD = AI_ONGROUND && ( usercmd.forwardmove < 0 ); + AI_STRAFE_LEFT = AI_ONGROUND && ( usercmd.rightmove < 0 ); + AI_STRAFE_RIGHT = AI_ONGROUND && ( usercmd.rightmove > 0 ); + } else { + AI_FORWARD = false; + AI_BACKWARD = false; + AI_STRAFE_LEFT = false; + AI_STRAFE_RIGHT = false; + } + + m_pathRank = AI_FORWARD ? rank : 1000; // grayman #2345 + + // stamina disabled, always run regardless of stamina + //AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); + AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && true ; + AI_DEAD = ( health <= 0 ); + + // DarkMod: Catch the creep modifier + AI_CREEP =( usercmd.buttons & BUTTON_5 ) && true; +} + +/* +================== +WeaponFireFeedback + +Called when a weapon fires, generates head twitches, etc +================== +*/ +void idPlayer::WeaponFireFeedback( const idDict *weaponDef ) { + // force a blink + blink_time = 0; + + // play the fire animation + AI_WEAPON_FIRED = true; + + // update view feedback + playerView.WeaponFireFeedback( weaponDef ); +} + +/* +=============== +idPlayer::StopFiring +=============== +*/ +void idPlayer::StopFiring( void ) +{ + AI_ATTACK_HELD = false; + AI_BLOCK_HELD = false; + AI_WEAPON_BLOCKED = false; + AI_WEAPON_FIRED = false; + AI_RELOAD = false; + if ( weapon.GetEntity() ) { + weapon.GetEntity()->EndAttack(); + } +} + +/* +=============== +idPlayer::FireWeapon +=============== +*/ +void idPlayer::FireWeapon( void ) +{ + idMat3 axis; + idVec3 muzzle; + + if ( privateCameraView ) { + return; + } + + if ( g_editEntityMode.GetInteger() ) { + GetViewPos( muzzle, axis ); + if ( gameLocal.editEntities->SelectEntity( muzzle, axis[0], this ) ) { + return; + } + } + + if ( !hiddenWeapon && weapon.GetEntity()->IsReady() ) + { + if ( weapon.GetEntity()->AmmoInClip() || weapon.GetEntity()->AmmoAvailable() ) + { + AI_ATTACK_HELD = true; + weapon.GetEntity()->BeginAttack(); + } else if( cv_weapon_next_on_empty.GetBool() ) + { + NextBestWeapon(); + } + } +} + +/* +=============== +idPlayer::BlockWeapon +=============== +*/ +void idPlayer::BlockWeapon( void ) +{ + if ( privateCameraView ) + { + return; + } + + if ( !hiddenWeapon && weapon.GetEntity()->IsReady() ) + { + if (AI_ATTACK_HELD) // grayman #597 + { + ignoreWeaponAttack = true; + } + AI_BLOCK_HELD = true; + weapon.GetEntity()->BeginBlock(); + } +} + +/* +=============== +idPlayer::CacheWeapons +=============== +*/ +void idPlayer::CacheWeapons() +{ + // greebo: Cache all weapons, regardless if we have them or not + for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) + { + if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs + + idWeapon::CacheWeapon(kv->GetValue()); + } +} + +/* +=============== +idPlayer::Give +=============== +*/ +bool idPlayer::Give( const char *statname, const char *value ) { + int amount; + + if ( AI_DEAD ) { + return false; + } + + if ( !idStr::Icmp( statname, "health" ) ) { + if ( health >= maxHealth ) { + return false; + } + amount = atoi( value ); + if ( amount ) { + health += amount; + if ( health > maxHealth ) { + health = maxHealth; + } + if ( hud ) { + hud->HandleNamedEvent( "healthPulse" ); + } + } + + } else if ( !idStr::Icmp( statname, "stamina" ) ) { + if ( stamina >= 100 ) { + return false; + } + stamina += atof( value ); + if ( stamina > 100 ) { + stamina = 100; + } + + } else if ( !idStr::Icmp( statname, "heartRate" ) ) { + heartRate += atoi( value ); + if ( heartRate > MAX_HEARTRATE ) { + heartRate = MAX_HEARTRATE; + } + + } else if ( !idStr::Icmp( statname, "air" ) ) { + if ( airTics >= pm_airTics.GetInteger() ) { + return false; + } + airTics += static_cast(atof( value ) / 100.0 * pm_airTics.GetInteger()); + if ( airTics > pm_airTics.GetInteger() ) { + airTics = pm_airTics.GetInteger(); + } + } else { + return false;//inventory.Give( this, spawnArgs, statname, value, &idealWeapon, true ); + } + return true; +} + + +/* +=============== +idPlayer::GiveHealthPool + +adds health to the player health pool +=============== +*/ +void idPlayer::GiveHealthPool( float amt ) { + + if ( AI_DEAD ) { + return; + } + + if ( health > 0 ) { + healthPool += amt; + if ( healthPool > maxHealth - health ) { + healthPool = maxHealth - health; + } + nextHealthPulse = gameLocal.time; + + // Reset the values to default + healthPoolTimeInterval = HEALTHPULSE_TIME; + healthPoolTimeIntervalFactor = 1.0f; + healthPoolStepAmount = 5; + } +} + +/* +=============== +idPlayer::PowerUpModifier +=============== +*/ +float idPlayer::PowerUpModifier( int type ) { + // greebo: Unused at the moment, maybe in the future + return 1.0f; +} + +/* +=============== +idPlayer::GivePowerUp +=============== +*/ +bool idPlayer::GivePowerUp( int powerup, int time ) { + const char *sound; + const char *skin; + + if ( powerup >= 0 && powerup < MAX_POWERUPS ) { + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteShort( powerup ); + msg.WriteBits( 1, 1 ); + ServerSendEvent( EVENT_POWERUP, &msg, false, -1 ); + } + + const idDeclEntityDef *def = NULL; + + switch( powerup ) { + case BERSERK: { + if ( spawnArgs.GetString( "snd_berserk_third", "", &sound ) ) { + StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_DEMONIC, 0, false, NULL ); + } + if ( baseSkinName.Length() ) { + powerUpSkin = declManager->FindSkin( baseSkinName + "_berserk" ); + } + if ( !gameLocal.isClient ) { + idealWeapon = 0; + } + break; + } + case INVISIBILITY: { + spawnArgs.GetString( "skin_invisibility", "", &skin ); + powerUpSkin = declManager->FindSkin( skin ); + // remove any decals from the model + if ( modelDefHandle != -1 ) { + gameRenderWorld->RemoveDecals( modelDefHandle ); + } + if ( weapon.GetEntity() ) { + weapon.GetEntity()->UpdateSkin(); + } + if ( spawnArgs.GetString( "snd_invisibility", "", &sound ) ) { + StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_ANY, 0, false, NULL ); + } + break; + } + case ADRENALINE: { + stamina = 100.0f; + break; + } + case MEGAHEALTH: { + if ( spawnArgs.GetString( "snd_megahealth", "", &sound ) ) { + StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_ANY, 0, false, NULL ); + } + def = gameLocal.FindEntityDef( "powerup_megahealth", false ); + if ( def ) { + health = def->dict.GetInt( "inv_health" ); + } + break; + } + } + + if ( hud ) { + hud->HandleNamedEvent( "itemPickup" ); + } + + return true; + } else { + gameLocal.Warning( "Player given power up %i\n which is out of range", powerup ); + } + return false; +} + +/* +============== +idPlayer::UpdatePowerUps +============== +*/ +void idPlayer::UpdatePowerUps( void ) { + if ( health > 0 ) { + if ( powerUpSkin ) { + renderEntity.customSkin = powerUpSkin; + } else { + renderEntity.customSkin = skin; + } + } + + if ( healthPool && gameLocal.time > nextHealthPulse && !AI_DEAD && health > 0 ) { + assert( !gameLocal.isClient ); // healthPool never be set on client + + //int amt = ( healthPool > 5 ) ? 5 : healthPool; // old code + // greebo: Changed step amount to be a variable that can be set from the "outside" + int amt = ( healthPool > healthPoolStepAmount ) ? healthPoolStepAmount : static_cast(healthPool); + + int oldHealth = health; + + health += amt; + if ( health > maxHealth ) { + health = maxHealth; + healthPool = 0; + } else { + healthPool -= amt; + } + + // greebo: Check how much health we actually took + int healthTaken = health - oldHealth; + // Update the mission statistics + gameLocal.m_MissionData->HealthReceivedByPlayer(healthTaken); + + nextHealthPulse = gameLocal.time + healthPoolTimeInterval; + + // Check whether we have a valid interval factor and if yes: apply it + if (healthPoolTimeIntervalFactor > 0) { + healthPoolTimeInterval = static_cast(healthPoolTimeInterval*healthPoolTimeIntervalFactor); + } + + healthPulse = true; + } +#ifndef ID_DEMO_BUILD + if ( !gameLocal.inCinematic && influenceActive == 0 && g_skill.GetInteger() == 3 && gameLocal.time > nextHealthTake && !AI_DEAD && health > g_healthTakeLimit.GetInteger() ) { + assert( !gameLocal.isClient ); // healthPool never be set on client + health -= g_healthTakeAmt.GetInteger(); + if ( health < g_healthTakeLimit.GetInteger() ) { + health = g_healthTakeLimit.GetInteger(); + } + nextHealthTake = gameLocal.time + g_healthTakeTime.GetInteger() * 1000; + healthTake = true; + } +#endif +} + +/* +=============== +idPlayer::GiveItem +=============== +*/ +void idPlayer::GiveItem( const char *itemname ) { + idDict args; + + args.Set( "classname", itemname ); + args.Set( "owner", name.c_str() ); + gameLocal.SpawnEntityDef( args ); + if ( hud ) { + hud->HandleNamedEvent( "itemPickup" ); + } +} + +/* +================== +idPlayer::SlotForWeapon +================== +*/ +int idPlayer::SlotForWeapon( const char *weaponName ) +{ + // Find the weapon category + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + if (weaponCategory == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find weapon category in inventory.\r"); + return -1; + } + + // Look for the weapon with the given name + for (int i = 0; i < weaponCategory->GetNumItems(); i++) + { + CInventoryWeaponItemPtr weaponItem = + boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); + + // Is this the right weapon? + if (weaponItem != NULL && weaponItem->GetWeaponName() == weaponName) + { + // We're done + return i; + } + } + + // not found + return -1; +} + +/* +=============== +idPlayer::Reload +=============== +*/ +void idPlayer::Reload( void ) { + if ( gameLocal.isClient ) { + return; + } + + if ( spectating || gameLocal.inCinematic || influenceActive ) { + return; + } + + if ( weapon.GetEntity() && weapon.GetEntity()->IsLinked() ) { + weapon.GetEntity()->Reload(); + } +} + +/* +=============== +idPlayer::NextBestWeapon +=============== +*/ +void idPlayer::NextBestWeapon( void ) { + // greebo: No "best" weapons in TDM, route the call to NextWeapon() + NextWeapon(); +} + +int idPlayer::GetHightestWeaponIndex() +{ + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + assert(weaponCategory != NULL); + + int numWeapons = weaponCategory->GetNumItems(); + + int highestIndex = -1; + + for (int i = 0; i < numWeapons; ++i) + { + CInventoryWeaponItemPtr item = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); + + assert(item != NULL); + + int candidate = item->GetWeaponIndex(); + + if (candidate > highestIndex) + { + highestIndex = candidate; + } + } + + return highestIndex; +} + +/* +=============== +idPlayer::NextWeapon +=============== +*/ +void idPlayer::NextWeapon() { + if ( !weaponEnabled || spectating || hiddenWeapon || gameLocal.inCinematic || gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) || health < 0 ) { + return; + } + + if ( gameLocal.isClient ) { + return; + } + + if (m_WeaponCursor == NULL || m_WeaponCursor->GetCurrentCategory() == NULL) { + return; + } + + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + int numWeapons = weaponCategory->GetNumItems(); + + if (numWeapons == 0) { + return; // no weapons... + } + + // Get the current weaponItem + CInventoryWeaponItemPtr curItem = GetCurrentWeaponItem(); + + if (curItem == NULL) { + return; + } + + int curWeaponIndex = curItem->GetWeaponIndex(); + int highestIndex = GetHightestWeaponIndex(); + + int nextWeaponIndex = curWeaponIndex; + + do + { + // Try to select the next weapon item + nextWeaponIndex++; + + if (nextWeaponIndex > highestIndex) + { + nextWeaponIndex = 0; + } + } while (!SelectWeapon(nextWeaponIndex, false) && nextWeaponIndex != curWeaponIndex); +} + +/* +=============== +idPlayer::PrevWeapon +=============== +*/ +void idPlayer::PrevWeapon( void ) { + if ( !weaponEnabled || spectating || hiddenWeapon || gameLocal.inCinematic || gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) || health < 0 ) { + return; + } + + if ( gameLocal.isClient ) { + return; + } + + if (m_WeaponCursor == NULL || m_WeaponCursor->GetCurrentCategory() == NULL) { + return; + } + + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + int numWeapons = weaponCategory->GetNumItems(); + + if (numWeapons == 0) { + return; // no weapons... + } + + // Get the current weaponItem + CInventoryWeaponItemPtr curItem = GetCurrentWeaponItem(); + + if (curItem == NULL) { + return; + } + + int curWeaponIndex = curItem->GetWeaponIndex(); + int highestIndex = GetHightestWeaponIndex(); + + int prevWeaponIndex = curWeaponIndex; + + do + { + // Try to select the previous weapon item + prevWeaponIndex--; + + if (prevWeaponIndex < 0) + { + prevWeaponIndex = highestIndex; + } + } while (!SelectWeapon(prevWeaponIndex, false) && prevWeaponIndex != curWeaponIndex); +} + +/* +=============== +idPlayer::SelectWeapon +=============== +*/ +bool idPlayer::SelectWeapon( int num, bool force ) +{ + if ( !weaponEnabled || spectating || gameLocal.inCinematic || health < 0 ) { + return false; + } + + if ( gameLocal.isClient ) { + return false; + } + + if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { + num = weapon_fists; + hiddenWeapon ^= 1; + if ( hiddenWeapon && weapon.GetEntity() ) { + weapon.GetEntity()->LowerWeapon(); + } else { + weapon.GetEntity()->RaiseWeapon(); + } + } + + if (m_WeaponCursor == NULL) { + return false; + } + + // Check if we want to toggle the current weapon item (requested index == current index) + CInventoryWeaponItemPtr item = GetCurrentWeaponItem(); + + if (item != NULL && item->GetWeaponIndex() == num && item->IsToggleable()) { + // Requested toggleable weapon is already active, hide it (switch to unarmed) + num = 0; + } + + CInventoryCategoryPtr category = m_WeaponCursor->GetCurrentCategory(); + if (category == NULL) { + return false; + } + + // Cycle through the weapons and find the one with the given weaponIndex + for (int i = 0; i < category->GetNumItems(); i++) + { + // Try to retrieve a weapon item from the given category + CInventoryWeaponItemPtr item = + boost::dynamic_pointer_cast(category->GetItem(i)); + + if (item != NULL && item->GetWeaponIndex() == num) + { + if (item->GetAmmo() <= 0 && item->NeedsAmmo()) + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon requires ammo. Cannot select: %d\r", num); + break; + } + + if (!item->IsEnabled()) + { + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon not enabled, cannot select: %d\r", num); + break; + } + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Selecting weapon #%d\r", num); + + // Set the cursor onto this item + m_WeaponCursor->SetCurrentItem(item); + + weaponSwitchTime = gameLocal.time + WEAPON_SWITCH_DELAY; + idealWeapon = num; + + UpdateHudWeapon(); + return true; + } + } + + return false; +} + +/* +================= +idPlayer::DropWeapon +================= +*/ +void idPlayer::DropWeapon( bool died ) { + idVec3 forward, up; + int inclip, ammoavailable; + + assert( !gameLocal.isClient ); + + if ( spectating || weaponGone || weapon.GetEntity() == NULL ) { + return; + } + + if ( ( !died && !weapon.GetEntity()->IsReady() ) || weapon.GetEntity()->IsReloading() ) { + return; + } + // ammoavailable is how many shots we can fire + // inclip is which amount is in clip right now + ammoavailable = weapon.GetEntity()->AmmoAvailable(); + inclip = weapon.GetEntity()->AmmoInClip(); + + // don't drop a grenade if we have none left + /*if ( !idStr::Icmp( idWeapon::GetAmmoNameForNum( weapon.GetEntity()->GetAmmoType() ), "ammo_grenades" ) && ( ammoavailable - inclip <= 0 ) ) { + return; + }*/ + + // expect an ammo setup that makes sense before doing any dropping + // ammoavailable is -1 for infinite ammo, and weapons like chainsaw + // a bad ammo config usually indicates a bad weapon state, so we should not drop + // used to be an assertion check, but it still happens in edge cases + if ( ( ammoavailable != -1 ) && ( ammoavailable - inclip < 0 ) ) { + common->DPrintf( "idPlayer::DropWeapon: bad ammo setup\n" ); + return; + } + idEntity *item = NULL; + if ( died ) { + // ain't gonna throw you no weapon if I'm dead + item = weapon.GetEntity()->DropItem( vec3_origin, 0, WEAPON_DROP_TIME, died ); + } else { + viewAngles.ToVectors( &forward, NULL, &up ); + item = weapon.GetEntity()->DropItem( 250.0f * forward + 150.0f * up, 500, WEAPON_DROP_TIME, died ); + } + if ( !item ) { + return; + } + // set the appropriate ammo in the dropped object + const idKeyValue * keyval = item->spawnArgs.MatchPrefix( "inv_ammo_" ); + if ( keyval ) { + item->spawnArgs.SetInt( keyval->GetKey(), ammoavailable ); + idStr inclipKey = keyval->GetKey(); + inclipKey.Insert( "inclip_", 4 ); + item->spawnArgs.SetInt( inclipKey, inclip ); + } + if ( !died ) { + // remove from our local inventory completely + weapon.GetEntity()->ResetAmmoClip(); + NextWeapon(); + weapon.GetEntity()->WeaponStolen(); + weaponGone = true; + } +} + +/* +================= +idPlayer::StealWeapon +steal the target player's current weapon +================= +*/ +void idPlayer::StealWeapon( idPlayer *player ) +{ + assert( !gameLocal.isClient ); + + // make sure there's something to steal + idWeapon *player_weapon = static_cast< idWeapon * >( player->weapon.GetEntity() ); + if ( !player_weapon || !player_weapon->CanDrop() || weaponGone ) { + return; + } + // steal - we need to effectively force the other player to abandon his weapon + int newweap = player->currentWeapon; + if ( newweap == -1 ) { + return; + } + + const char *weapon_classname = spawnArgs.GetString( va( "def_weapon%d", newweap ) ); + assert( weapon_classname ); + int ammoavailable = player->weapon.GetEntity()->AmmoAvailable(); + int inclip = player->weapon.GetEntity()->AmmoInClip(); + if ( ( ammoavailable != -1 ) && ( ammoavailable - inclip < 0 ) ) { + // see DropWeapon + common->DPrintf( "idPlayer::StealWeapon: bad ammo setup\n" ); + // we still steal the weapon, so let's use the default ammo levels + inclip = -1; + const idDeclEntityDef *decl = gameLocal.FindEntityDef( weapon_classname ); + assert( decl ); + const idKeyValue *keypair = decl->dict.MatchPrefix( "inv_ammo_" ); + assert( keypair ); + ammoavailable = atoi( keypair->GetValue() ); + } + + player->weapon.GetEntity()->WeaponStolen(); + //player->inventory.Drop( player->spawnArgs, NULL, newweap ); + player->SelectWeapon( weapon_fists, false ); + // in case the robbed player is firing rounds with a continuous fire weapon like the chaingun/plasma etc. + // this will ensure the firing actually stops + player->weaponGone = true; + + // give weapon, setup the ammo count + Give( "weapon", weapon_classname ); + idealWeapon = newweap; +} + +/* +=============== +idPlayer::ActiveGui +=============== +*/ +idUserInterface *idPlayer::ActiveGui( void ) +{ + if ( m_overlays.findInteractive() ) + return m_overlays.findInteractive(); + + return NULL; // greebo: No focusUI anymore + //return focusUI; +} + +/* +=============== +idPlayer::Weapon_Combat +=============== +*/ +void idPlayer::Weapon_Combat( void ) { + if ( influenceActive || !weaponEnabled || gameLocal.inCinematic || privateCameraView ) { + return; + } + + weapon.GetEntity()->RaiseWeapon(); + if ( weapon.GetEntity()->IsReloading() ) { + if ( !AI_RELOAD ) { + AI_RELOAD = true; + SetState( "ReloadWeapon" ); + UpdateScript(); + } + } else { + AI_RELOAD = false; + } + + if ( idealWeapon != currentWeapon ) { + if ( weaponCatchup ) { + assert( gameLocal.isClient ); + + currentWeapon = idealWeapon; + weaponGone = false; + animPrefix = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); + weapon.GetEntity()->GetWeaponDef( animPrefix, 0 /*inventory.clip[ currentWeapon ]*/ ); + animPrefix.Strip( "weapon_" ); + + weapon.GetEntity()->NetCatchup(); + const function_t *newstate = GetScriptFunction( "NetCatchup" ); + if ( newstate ) { + SetState( newstate ); + UpdateScript(); + } + weaponCatchup = false; + } else { + + // grayman #597 - if the current weapon is an arrow, and the ideal + // weapon is also an arrow, make the switch, but + // don't play the "lower bow, then raise bow" animation. + + weapon.GetEntity()->SetArrow2Arrow((currentWeapon >= ARROW_WEAPON_INDEX_BEGIN) && (idealWeapon >= ARROW_WEAPON_INDEX_BEGIN)); + + if ( weapon.GetEntity()->IsReady() ) { + weapon.GetEntity()->PutAway(); + if (usercmd.buttons & BUTTON_ATTACK) // grayman #597 - is this an aborted attack while the attack button is depressed? + { + ignoreWeaponAttack = true; // this stays true until the attack button is released + } + } + + if ( weapon.GetEntity()->IsHolstered() ) { + assert( idealWeapon >= 0 ); + + if ( !spawnArgs.GetBool( va( "weapon%d_toggle", currentWeapon ) ) ) { + previousWeapon = currentWeapon; + } + currentWeapon = idealWeapon; + weaponGone = false; + animPrefix = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); + weapon.GetEntity()->GetWeaponDef( animPrefix, 0/*inventory.clip[ currentWeapon ]*/ ); + animPrefix.Strip( "weapon_" ); + weapon.GetEntity()->Raise(); + } + } + } else { + weaponGone = false; // if you drop and re-get weap, you may miss the = false above + if ( weapon.GetEntity()->IsHolstered() ) { + if ( !weapon.GetEntity()->AmmoAvailable() ) + { + // weapons can switch automatically if they have no more ammo + // ishtvan: Only if the cvar is set + if (cv_weapon_next_on_empty.GetBool()) + { + NextBestWeapon(); + } + else + { + // Switch to unarmed if no more ammo available + SelectWeapon(weapon_fists, false); + } + } + else + { + weapon.GetEntity()->Raise(); + state = GetScriptFunction( "RaiseWeapon" ); + if ( state ) { + SetState( state ); + } + } + } + } + + if (!(usercmd.buttons & BUTTON_ATTACK) && (oldButtons & BUTTON_ATTACK)) // grayman #597 - was the attack button just released? + { + ignoreWeaponAttack = false; + } + + // check for attack + AI_WEAPON_FIRED = false; + if ( !influenceActive ) + { + // grayman #597 - if ignoreWeaponAttack is true, the weapon is no longer in the attack state, but the attack button is still depressed + if ( ( usercmd.buttons & BUTTON_ATTACK ) && !weaponGone && !ignoreWeaponAttack) + { + FireWeapon(); + } + else if ( oldButtons & BUTTON_ATTACK ) + { + AI_ATTACK_HELD = false; + weapon.GetEntity()->EndAttack(); + } + } + + // check for block + AI_WEAPON_BLOCKED = false; + if ( !influenceActive ) + { + if ( ( usercmd.buttons & BUTTON_ZOOM ) && !weaponGone ) + { + BlockWeapon(); + } + else if ( oldButtons & BUTTON_ZOOM ) + { + AI_BLOCK_HELD = false; + weapon.GetEntity()->EndBlock(); + } + } + + // update our ammo clip in our inventory + if ( currentWeapon == idealWeapon ) { + UpdateHudAmmo(); + } +} + +/* +=============== +idPlayer::Weapon_NPC +=============== +*/ +#if 0 +void idPlayer::Weapon_NPC( void ) { + if ( idealWeapon != currentWeapon ) { + Weapon_Combat(); + } + StopFiring(); + weapon.GetEntity()->LowerWeapon(); + + if ( ( usercmd.buttons & BUTTON_ATTACK ) && !( oldButtons & BUTTON_ATTACK ) ) { + buttonMask |= BUTTON_ATTACK; + focusCharacter->TalkTo( this ); + } +} +#endif + +/* +=============== +idPlayer::LowerWeapon +=============== +*/ +void idPlayer::LowerWeapon( void ) { + if ( weapon.GetEntity() && !weapon.GetEntity()->IsHidden() ) { + weapon.GetEntity()->LowerWeapon(); + } +} + +/* +=============== +idPlayer::RaiseWeapon +=============== +*/ +void idPlayer::RaiseWeapon( void ) +{ + if (weapon.GetEntity() && + weapon.GetEntity()->IsHidden() && + !(GetImmobilization() & EIM_ATTACK)) + { + weapon.GetEntity()->RaiseWeapon(); + } +} + +/* +=============== +idPlayer::WeaponLoweringCallback +=============== +*/ +void idPlayer::WeaponLoweringCallback( void ) { + SetState( "LowerWeapon" ); + UpdateScript(); + UpdateWeaponEncumbrance(); +} + +/* +=============== +idPlayer::WeaponRisingCallback +=============== +*/ +void idPlayer::WeaponRisingCallback( void ) { + SetState( "RaiseWeapon" ); + UpdateScript(); + UpdateWeaponEncumbrance(); +} + +/* +=============== +idPlayer::Weapon_GUI +=============== +*/ +void idPlayer::Weapon_GUI( void ) +{ + if ( idealWeapon != currentWeapon ) { + Weapon_Combat(); + } + StopFiring(); + weapon.GetEntity()->LowerWeapon(); + + // disable click prediction for the GUIs. handy to check the state sync does the right thing + if ( gameLocal.isClient && !net_clientPredictGUI.GetBool() ) { + return; + } + + if ( ( oldButtons ^ usercmd.buttons ) & BUTTON_ATTACK ) { + sysEvent_t ev; + const char *command = NULL; + bool updateVisuals = false; + + idUserInterface *ui = ActiveGui(); + if ( ui ) { + ev = sys->GenerateMouseButtonEvent( 1, ( usercmd.buttons & BUTTON_ATTACK ) != 0 ); + command = ui->HandleEvent( &ev, gameLocal.time, &updateVisuals ); +#if 0 + if ( updateVisuals && focusGUIent && ui == focusUI ) { + focusGUIent->UpdateVisuals(); + } +#endif + } + if ( gameLocal.isClient ) { + // we predict enough, but don't want to execute commands + return; + } + +#if 0 + if ( focusGUIent ) { + HandleGuiCommands( focusGUIent, command ); + } else { + HandleGuiCommands( this, command ); + } +#else // greebo: Replaced the above with this, no focusGUIEnt anymore + HandleGuiCommands( this, command ); +#endif + } +} + +/* +=============== +idPlayer::UpdateWeapon +=============== +*/ +void idPlayer::UpdateWeapon( void ) { + if ( health <= 0 ) { + return; + } + + assert( !spectating ); + + if ( gameLocal.isClient ) { + // clients need to wait till the weapon and it's world model entity + // are present and synchronized ( weapon.worldModel idEntityPtr to idAnimatedEntity ) + if ( !weapon.GetEntity()->IsWorldModelReady() ) { + return; + } + } + + // always make sure the weapon is correctly setup before accessing it + if ( !weapon.GetEntity()->IsLinked() ) { + if ( idealWeapon != -1 ) { + animPrefix = spawnArgs.GetString( va( "def_weapon%d", idealWeapon ) ); + weapon.GetEntity()->GetWeaponDef( animPrefix, 0/*inventory.clip[ idealWeapon ]*/ ); + assert( weapon.GetEntity()->IsLinked() ); + } else { + return; + } + } + + if ( g_dragEntity.GetBool() ) { + StopFiring(); + weapon.GetEntity()->LowerWeapon(); + dragEntity.Update( this ); + } else if ( ActiveGui() ) { + // gui handling overrides weapon use + Weapon_GUI(); +#if 0 + } else if ( focusCharacter && ( focusCharacter->health > 0 ) ) { + Weapon_NPC(); +#endif + } else if( gameLocal.m_Grabber->GetSelected() ) { + gameLocal.m_Grabber->Update( this, true ); + } else { + Weapon_Combat(); + } + + if( GetImmobilization() & EIM_ATTACK ) + { + StopFiring(); + weapon.GetEntity()->LowerWeapon(); + } + + if ( hiddenWeapon ) { + weapon.GetEntity()->LowerWeapon(); + } + + // update weapon state, particles, dlights, etc + weapon.GetEntity()->PresentWeapon( showWeaponViewModel ); +} + +void idPlayer::ChangeWeaponProjectile(const idStr& weaponName, const idStr& projectileDefName) +{ + CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); + if (weaponItem == NULL) return; + + weaponItem->SetProjectileDefName(projectileDefName); +} + +void idPlayer::ResetWeaponProjectile(const idStr& weaponName) +{ + CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); + if (weaponItem == NULL) return; + + weaponItem->ResetProjectileDefName(); +} + +void idPlayer::ChangeWeaponName(const idStr& weaponName, const idStr& displayName) +{ + CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); + if (weaponItem == NULL) return; + + if (!displayName.IsEmpty()) + { + weaponItem->SetName(displayName); + } + else + { + const idDeclEntityDef* def = gameLocal.FindEntityDef(weaponItem->GetWeaponDefName()); + + if (def != NULL) + { + // Empty name passed, reset to definition + weaponItem->SetName(def->dict.GetString("inv_name")); + } + } + + UpdateHudWeapon(); +} + +void idPlayer::SetIsPushing(bool isPushing) +{ + this->isPushing = isPushing; + + // Raise/lower the weapons according to our push state + SetImmobilization("pushing", isPushing ? EIM_ATTACK : 0); +} + +bool idPlayer::IsPushing() +{ + return isPushing; +} + +void idPlayer::OnStartShoulderingBody(idEntity* body) +{ + // grayman #2478 - shouldering light bodies, like rats, shouldn't elicit shouldering sounds + + idStr sound = "snd_shoulder_body"; + + // Check if the other body is at least 30 kg heavier than us + + if ( body->GetPhysics()->GetMass() >= ( GetPhysics()->GetMass() + 30 ) ) + { + sound = "snd_shoulder_body_heavy"; + } + else if ( body->GetPhysics()->GetMass() <= 10 ) // very light? + { + sound = ""; + } + + // play the sound on the player, not the body (that was creating inconsistent volume) + if ( sound.Length() > 0 ) + { + StartSound( sound.c_str(), SND_CHANNEL_ITEM, 0, false, NULL ); + } + + // set immobilizations + int immob = SHOULDER_IMMOBILIZATIONS; + + // TODO: Also make sure you can't grab anything else (hands are full) + // requires a new EIM flag? + SetImmobilization( "ShoulderedBody", SHOULDER_IMMOBILIZATIONS ); + + // set hinderance + float maxSpeed = body->spawnArgs.GetFloat("shouldered_maxspeed","1.0f"); + SetHinderance( "ShoulderedBody", 1.0f, maxSpeed ); + SetJumpHinderance( "ShoulderedBody", 1.0f, SHOULDER_JUMP_HINDERANCE ); + + // greebo: Determine which text to display on the HUD + idStr itemName; + if( body->health > 0 ) + { + itemName = body->spawnArgs.GetString("shouldered_name", "#str_02410" ); // Body + } + else + { + itemName = body->spawnArgs.GetString("shouldered_name_dead", "#str_02409" ); // Corpse + } + + // Send the name to the inventory HUD + SetGuiString(m_InventoryOverlay, "GrabbedItemName", gameLocal.m_I18N->Translate( itemName ) ); + + // Notify all GUIs about the event + m_overlays.broadcastNamedEvent("OnStartShoulderingBody"); + + // Clear the inventory cursor + SelectInventoryItem(""); + + m_bShoulderingBody = true; +} + +void idPlayer::OnStopShoulderingBody(idEntity* body) +{ + // clear immobilizations + SetImmobilization( "ShoulderedBody", 0 ); + SetHinderance( "ShoulderedBody", 1.0f, 1.0f ); + SetJumpHinderance( "ShoulderedBody", 1.0f, 1.0f ); + + // grayman #2478 - unshouldering light bodies, like rats, shouldn't elicit unshouldering sounds + + if ( body->GetPhysics()->GetMass() > 10 ) + { + StartSound( "snd_shoulder_body", SND_CHANNEL_ITEM, 0, false, NULL ); + } + + m_overlays.broadcastNamedEvent("OnStopShoulderingBody"); + + // Send the name to the inventory HUD + SetGuiString(m_InventoryOverlay, "GrabbedItemName", ""); + + m_bShoulderingBody = false; +} + +/* +=============== +idPlayer::SpectateFreeFly +=============== +*/ +void idPlayer::SpectateFreeFly( bool force ) { + idPlayer *player; + idVec3 newOrig; + idVec3 spawn_origin; + idAngles spawn_angles; + + player = gameLocal.GetClientByNum( spectator ); + if ( force || gameLocal.time > lastSpectateChange ) { + spectator = entityNumber; + if ( player && player != this && !player->spectating && !player->IsInTeleport() ) { + newOrig = player->GetPhysics()->GetOrigin(); + if ( player->physicsObj.IsCrouching() ) { + newOrig[ 2 ] += pm_crouchviewheight.GetFloat(); + } else { + newOrig[ 2 ] += pm_normalviewheight.GetFloat(); + } + newOrig[ 2 ] += SPECTATE_RAISE; + idBounds b = idBounds( vec3_origin ).Expand( pm_spectatebbox.GetFloat() * 0.5f ); + idVec3 start = player->GetPhysics()->GetOrigin(); + start[2] += pm_spectatebbox.GetFloat() * 0.5f; + trace_t t; + // assuming spectate bbox is inside stand or crouch box + gameLocal.clip.TraceBounds( t, start, newOrig, b, MASK_PLAYERSOLID, player ); + newOrig.Lerp( start, newOrig, t.fraction ); + SetOrigin( newOrig ); + idAngles angle = player->viewAngles; + angle[ 2 ] = 0; + SetViewAngles( angle ); + } else { + SelectInitialSpawnPoint( spawn_origin, spawn_angles ); + spawn_origin[ 2 ] += pm_normalviewheight.GetFloat(); + spawn_origin[ 2 ] += SPECTATE_RAISE; + SetOrigin( spawn_origin ); + SetViewAngles( spawn_angles ); + } + lastSpectateChange = gameLocal.time + 500; + } +} + +/* +=============== +idPlayer::SpectateCycle +=============== +*/ +void idPlayer::SpectateCycle( void ) { + idPlayer *player; + + if ( gameLocal.time > lastSpectateChange ) { + int latchedSpectator = spectator; + spectator = gameLocal.GetNextClientNum( spectator ); + player = gameLocal.GetClientByNum( spectator ); + assert( player ); // never call here when the current spectator is wrong + // ignore other spectators + while ( latchedSpectator != spectator && player->spectating ) { + spectator = gameLocal.GetNextClientNum( spectator ); + player = gameLocal.GetClientByNum( spectator ); + } + lastSpectateChange = gameLocal.time + 500; + } +} + +/* +=============== +idPlayer::UpdateSpectating +=============== +*/ +void idPlayer::UpdateSpectating( void ) { + assert( spectating ); + assert( !gameLocal.isClient ); + assert( IsHidden() ); + idPlayer *player; + if ( !gameLocal.isMultiplayer ) { + return; + } + player = gameLocal.GetClientByNum( spectator ); + if ( !player || ( player->spectating && player != this ) ) { + SpectateFreeFly( true ); + } else if ( usercmd.upmove > 0 ) { + SpectateFreeFly( false ); + } else if ( usercmd.buttons & BUTTON_ATTACK ) { + SpectateCycle(); + } +} + +/* +=============== +idPlayer::HandleSingleGuiCommand +=============== +*/ +bool idPlayer::HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ) { + idToken token; + + if ( !src->ReadToken( &token ) ) { + return false; + } + + if ( token == ";" ) { + return false; + } + + if ( token.Icmp( "addhealth" ) == 0 ) { + if ( entityGui && health < 100 ) { + int _health = entityGui->spawnArgs.GetInt( "gui_parm1" ); + int amt = ( _health >= HEALTH_PER_DOSE ) ? HEALTH_PER_DOSE : _health; + _health -= amt; + entityGui->spawnArgs.SetInt( "gui_parm1", _health ); + if ( entityGui->GetRenderEntity() && entityGui->GetRenderEntity()->gui[ 0 ] ) { + entityGui->GetRenderEntity()->gui[ 0 ]->SetStateInt( "gui_parm1", _health ); + } + health += amt; + if ( health > 100 ) { + health = 100; + } + } + return true; + } + + if ( token.Icmp( "ready" ) == 0 ) { + PerformImpulse( IMPULSE_17 ); + return true; + } + + src->UnreadToken( &token ); + return false; +} + +/* +============== +idPlayer::Collide +============== +*/ + +bool idPlayer::Collide( const trace_t &collision, const idVec3 &velocity ) { + if( collision.fraction == 1.0f || collision.c.type == CONTACT_NONE // didnt hit anything + || gameLocal.isClient // server computes + ) + { + return false; + } + idEntity *other = gameLocal.entities[ collision.c.entityNum ]; + // don't let player collide with grabber entity + if ( other && other != gameLocal.m_Grabber->GetSelected() ) + { + ProcCollisionStims( other, collision.c.id ); + + other->Signal( SIG_TOUCH ); + if ( !spectating ) { + if ( other->RespondsTo( EV_Touch ) ) { + other->ProcessEvent( &EV_Touch, this, &collision ); + } + } else { + if ( other->RespondsTo( EV_SpectatorTouch ) ) { + other->ProcessEvent( &EV_SpectatorTouch, this, &collision ); + } + } + } + return false; +} + +/* +================ +idPlayer::UpdateLocation + +Searches nearby locations +================ +*/ +void idPlayer::UpdateLocation( void ) { + if ( hud ) { + idLocationEntity *locationEntity = gameLocal.LocationForPoint( GetEyePosition() ); + if ( locationEntity ) { + // Tels: Make it possible that location names like "#str_01234" are automatically translated to "Kitchen" + hud->SetStateString( "location", gameLocal.m_I18N->Translate( locationEntity->GetLocation() ) ); + } else { + hud->SetStateString( "location", gameLocal.m_I18N->Translate( "#str_02911" ) ); + } + } +} + +/* +================ +idPlayer::GetLocation +================ +*/ +idLocationEntity *idPlayer::GetLocation( void ) +{ + return gameLocal.LocationForPoint( GetEyePosition() ); +} + +/* +================ +idPlayer::ClearFocus + +Clears the focus cursor +================ +*/ +#if 0 +void idPlayer::ClearFocus( void ) { + focusCharacter = NULL; + focusGUIent = NULL; + focusUI = NULL; + focusVehicle = NULL; + talkCursor = 0; +} +#endif + +/* +================ +idPlayer::UpdateFocus + +Searches nearby entities for interactive guis, possibly making one of them +the focus and sending it a mouse move event +================ +*/ +#if 0 +void idPlayer::UpdateFocus( void ) { + idClipModel *clipModelList[ MAX_GENTITIES ]; + idClipModel *clip; + int listedClipModels; + idEntity *oldFocus; + idEntity *ent; + idUserInterface *oldUI; + idAI *oldChar; + int oldTalkCursor; + idAFEntity_Vehicle *oldVehicle; + int i; + idVec3 start, end; + bool allowFocus; + const char *command; + trace_t trace; + guiPoint_t pt; + sysEvent_t ev; + idUserInterface *ui; + + if ( gameLocal.inCinematic ) { + return; + } + + // only update the focus character when attack button isn't pressed so players + // can still chainsaw NPC's + if ( gameLocal.isMultiplayer || ( !focusCharacter && ( usercmd.buttons & BUTTON_ATTACK ) ) ) { + allowFocus = false; + } else { + allowFocus = true; + } + + oldFocus = focusGUIent; + oldUI = focusUI; + oldChar = focusCharacter; + oldTalkCursor = talkCursor; + oldVehicle = focusVehicle; + + if ( focusTime <= gameLocal.time ) { + ClearFocus(); + } + + // don't let spectators interact with GUIs + if ( spectating ) { + return; + } + + start = GetEyePosition(); + end = start + viewAngles.ToForward() * 80.0f; + + // player identification -> names to the hud + if ( gameLocal.isMultiplayer && entityNumber == gameLocal.localClientNum ) { + idVec3 end = start + viewAngles.ToForward() * 768.0f; + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); + int iclient = -1; + if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum < MAX_CLIENTS ) ) { + iclient = trace.c.entityNum; + } + if ( MPAim != iclient ) { + lastMPAim = MPAim; + MPAim = iclient; + lastMPAimTime = gameLocal.realClientTime; + } + } + + idBounds bounds( start ); + bounds.AddPoint( end ); + + listedClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); + + // no pretense at sorting here, just assume that there will only be one active + // gui within range along the trace + for ( i = 0; i < listedClipModels; i++ ) { + clip = clipModelList[ i ]; + ent = clip->GetEntity(); + + if ( ent->IsHidden() ) { + continue; + } + + if ( allowFocus ) { + if ( ent->IsType( idAFAttachment::Type ) ) { + idEntity *body = static_cast( ent )->GetBody(); + if ( body && body->IsType( idAI::Type ) && ( static_cast( body )->GetTalkState() >= TALK_OK ) ) { + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); + if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { + ClearFocus(); + focusCharacter = static_cast( body ); + talkCursor = 1; + focusTime = gameLocal.time + FOCUS_TIME; + break; + } + } + continue; + } + + if ( ent->IsType( idAI::Type ) ) { + if ( static_cast( ent )->GetTalkState() >= TALK_OK ) { + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); + if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { + ClearFocus(); + focusCharacter = static_cast( ent ); + talkCursor = 1; + focusTime = gameLocal.time + FOCUS_TIME; + break; + } + } + continue; + } + + if ( ent->IsType( idAFEntity_Vehicle::Type ) ) { + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); + if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { + ClearFocus(); + focusVehicle = static_cast( ent ); + focusTime = gameLocal.time + FOCUS_TIME; + break; + } + continue; + } + } + + if ( !ent->GetRenderEntity() || !ent->GetRenderEntity()->gui[ 0 ] || !ent->GetRenderEntity()->gui[ 0 ]->IsInteractive() ) { + continue; + } + + if ( ent->spawnArgs.GetBool( "inv_item" ) ) { + // don't allow guis on pickup items focus + continue; + } + + pt = gameRenderWorld->GuiTrace( ent->GetModelDefHandle(), start, end ); + if ( pt.x != -1 ) { + // we have a hit + renderEntity_t *focusGUIrenderEntity = ent->GetRenderEntity(); + if ( !focusGUIrenderEntity ) { + continue; + } + + if ( pt.guiId == 1 ) { + ui = focusGUIrenderEntity->gui[ 0 ]; + } else if ( pt.guiId == 2 ) { + ui = focusGUIrenderEntity->gui[ 1 ]; + } else { + ui = focusGUIrenderEntity->gui[ 2 ]; + } + + if ( ui == NULL ) { + continue; + } + + ClearFocus(); + focusGUIent = ent; + focusUI = ui; + + // clamp the mouse to the corner + ev = sys->GenerateMouseMoveEvent( -2000, -2000 ); + command = focusUI->HandleEvent( &ev, gameLocal.time ); + HandleGuiCommands( focusGUIent, command ); + + // move to an absolute position + ev = sys->GenerateMouseMoveEvent( static_cast(pt.x) * SCREEN_WIDTH, static_cast(pt.y) * SCREEN_HEIGHT ); + command = focusUI->HandleEvent( &ev, gameLocal.time ); + HandleGuiCommands( focusGUIent, command ); + focusTime = gameLocal.time + FOCUS_GUI_TIME; + break; + } + } + + if ( focusGUIent && focusUI ) { + if ( !oldFocus || oldFocus != focusGUIent ) { + command = focusUI->Activate( true, gameLocal.time ); + HandleGuiCommands( focusGUIent, command ); + StartSound( "snd_guienter", SND_CHANNEL_ANY, 0, false, NULL ); + // HideTip(); + // HideObjective(); + } + } else if ( oldFocus && oldUI ) { + command = oldUI->Activate( false, gameLocal.time ); + HandleGuiCommands( oldFocus, command ); + StartSound( "snd_guiexit", SND_CHANNEL_ANY, 0, false, NULL ); + } + + if ( cursor && ( oldTalkCursor != talkCursor ) ) { + cursor->SetStateInt( "talkcursor", talkCursor ); + } + + if ( oldChar != focusCharacter && hud ) { + if ( focusCharacter ) { + hud->SetStateString( "npc", focusCharacter->spawnArgs.GetString( "npc_name", "Joe" ) ); + hud->HandleNamedEvent( "showNPC" ); + // HideTip(); + // HideObjective(); + } else { + hud->SetStateString( "npc", "" ); + hud->HandleNamedEvent( "hideNPC" ); + } + } +} +#endif + +/* +================= +idPlayer::CrashLand + +Check for hard landings that generate sound events +================= +*/ + +void idPlayer::CrashLand( const idVec3 &savedOrigin, const idVec3 &savedVelocity ) { + + AI_SOFTLANDING = false; + AI_HARDLANDING = false; + + CrashLandResult result = idActor::CrashLand( physicsObj, savedOrigin, savedVelocity ); + + if (result.hasLanded && + ( (!AI_CROUCH && savedVelocity.z < -300) || savedVelocity.z < -600) ) + { + hasLanded = true; + + PlayFootStepSound(); + } + else + { + hasLanded = false; + } + + + if (health < 0) + { + // This was a deadly fall + AI_HARDLANDING = true; + landChange = -32; + landTime = gameLocal.time; + } + else if (result.damageDealt >= m_damage_thresh_hard) + { + AI_HARDLANDING = true; + landChange = -24; + landTime = gameLocal.time; + } + else if (result.hasLanded || result.damageDealt >= m_damage_thresh_min) + { + AI_SOFTLANDING = true; + landChange = -8; + landTime = gameLocal.time; + } + + // otherwise, just walk on +} + +/* +=============== +idPlayer::BobCycle +=============== +*/ +void idPlayer::BobCycle( const idVec3 &pushVelocity ) { + float bobmove; + int old, deltaTime; + idVec3 vel, gravityDir, velocity; + idMat3 viewaxis; + float bob; + float delta; + float speed; + float f; + + // + // calculate speed and cycle to be used for + // all cyclic walking effects + // + velocity = physicsObj.GetLinearVelocity() - pushVelocity; + + gravityDir = physicsObj.GetGravityNormal(); + vel = velocity - ( velocity * gravityDir ) * gravityDir; + xyspeed = vel.LengthFast(); + + // do not evaluate the bob for other clients + // when doing a spectate follow, don't do any weapon bobbing + if ( gameLocal.isClient && entityNumber != gameLocal.localClientNum ) { + viewBobAngles.Zero(); + viewBob.Zero(); + return; + } + + if ( !physicsObj.HasGroundContacts() || influenceActive == INFLUENCE_LEVEL2 || ( gameLocal.isMultiplayer && spectating ) ) { + // airborne + bobCycle = 0; + bobFoot = 0; + bobfracsin = 0; + } + else if (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD || noclip) + { + // No viewbob when fully underwater or in noclip mode, start at beginning of cycle again + bobCycle = 0; + bobFoot = 0; + bobfracsin = 0; + } + else if ( ( !usercmd.forwardmove && !usercmd.rightmove ) || ( xyspeed <= MIN_BOB_SPEED ) ) { + // Play a footstep sound when we stop walking (the foot is lowered to the ground; + // also this prevents exploits) + if (bobCycle != 0) { + PlayFootStepSound(); + } + // start at beginning of cycle again + bobCycle = 0; + bobFoot = 0; + bobfracsin = 0; + } + else { + if ( physicsObj.IsCrouching() ) { + // greebo: Double the crouchbob speed when fully running + bobmove = pm_crouchbob.GetFloat() * (1 + bobFrac); + } + else + { + // vary the bobbing based on the speed of the player + bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; + } + + // greebo: is the player creeping? (Only kicks in when not running, run key cancels out creep key) + if (usercmd.buttons & BUTTON_5 && !(usercmd.buttons & BUTTON_RUN)) + { + bobmove *= 0.5f * (1 - bobFrac); + } + + // additional explanatory comments added by Crispy + + old = bobCycle; + + // bobCycle is effectively an 8-bit integer, which increases at a speed determined by bobmove + // and wraps around when it exceeds 8 bits. + bobCycle = (int)( old + bobmove * gameLocal.msec ) & 255; + + // bobFoot = most significant bit of bobCycle, so it will be equal to 1 for half the time, + // and 0 for the other half. This represents which foot we're placing our weight on right now. + bobFoot = ( bobCycle & 128 ) >> 7; + + // Take the other 7 bits of bobCycle, scale them to range from 0 to PI, and take the sine. + // The result produces positive values only, from within the first "hump" of the function. + // (Look at the graph of sin(x) with x = 0...PI) + bobfracsin = idMath::Fabs( sin( ( bobCycle & 127 ) / 127.0 * idMath::PI ) ); + + // Crispy: Play footstep sounds when we hit the bottom of the cycle (i.e. when bobFoot changes) + if ((old&128) != (bobCycle&128)) { + // We've changed feet, so play a footstep + PlayFootStepSound(); + } + } + + // calculate angles for view bobbing + viewBobAngles.Zero(); + + viewaxis = viewAngles.ToMat3() * physicsObj.GetGravityAxis(); + + // add angles based on velocity + delta = velocity * viewaxis[0]; + viewBobAngles.pitch += delta * pm_runpitch.GetFloat(); + + delta = velocity * viewaxis[1]; + viewBobAngles.roll -= delta * pm_runroll.GetFloat(); + + // add angles based on bob + // make sure the bob is visible even at low speeds + speed = xyspeed > 200 ? xyspeed : 200; + + delta = bobfracsin * pm_bobpitch.GetFloat() * speed; + if ( physicsObj.IsCrouching() ) { + delta *= 3; // crouching + } + viewBobAngles.pitch += delta; + delta = bobfracsin * pm_bobroll.GetFloat() * speed; + if ( physicsObj.IsCrouching() ) { + delta *= 3; // crouching accentuates roll + } + if ( bobFoot & 1 ) { + delta = -delta; + } + viewBobAngles.roll += delta; + + // calculate position for view bobbing + viewBob.Zero(); + + if ( physicsObj.HasSteppedUp() ) { + + // check for stepping up before a previous step is completed + deltaTime = gameLocal.time - stepUpTime; + if ( deltaTime < STEPUP_TIME ) { + stepUpDelta = stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME + physicsObj.GetStepUp(); + } else { + stepUpDelta = physicsObj.GetStepUp(); + } + if ( stepUpDelta > 2.0f * pm_stepsize.GetFloat() ) { + stepUpDelta = 2.0f * pm_stepsize.GetFloat(); + } + stepUpTime = gameLocal.time; + } + + idVec3 gravity = physicsObj.GetGravityNormal(); + + // if the player stepped up recently + deltaTime = gameLocal.time - stepUpTime; + if ( deltaTime < STEPUP_TIME ) { + viewBob += gravity * ( stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME ); + } + + // add bob height after any movement smoothing + bob = bobfracsin * xyspeed * pm_bobup.GetFloat(); + if ( bob > 6 ) { + bob = 6; + } + viewBob[2] += bob; + + // add fall height + delta = gameLocal.time - landTime; + if ( delta < LAND_DEFLECT_TIME ) { + f = delta / LAND_DEFLECT_TIME; + viewBob -= gravity * ( landChange * f ); + } else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) { + delta -= LAND_DEFLECT_TIME; + f = 1.0 - ( delta / LAND_RETURN_TIME ); + viewBob -= gravity * ( landChange * f ); + } +} + +/* +================ +idPlayer::UpdateDeltaViewAngles +================ +*/ +void idPlayer::UpdateDeltaViewAngles( const idAngles &angles ) { + // set the delta angle + idAngles delta; + for( int i = 0; i < 3; i++ ) { + delta[ i ] = angles[ i ] - SHORT2ANGLE( usercmd.angles[ i ] ); + } + + SetDeltaViewAngles( delta ); +} + +/* +================ +idPlayer::SetViewAngles +================ +*/ +void idPlayer::SetViewAngles( const idAngles &angles ) { + UpdateDeltaViewAngles( angles ); + viewAngles = angles; +} + +/* +================ +idPlayer::UpdateViewAngles +================ +*/ +void idPlayer::UpdateViewAngles( void ) +{ + int i; + idAngles delta; + idAngles TestAngles = viewAngles; + + if ( !noclip && + ( gameLocal.inCinematic || privateCameraView || gameLocal.GetCamera() || + influenceActive == INFLUENCE_LEVEL2 || GetImmobilization() & EIM_VIEW_ANGLE ) ) + { + // no view changes at all, but we still want to update the deltas or else when + // we get out of this mode, our view will snap to a kind of random angle + UpdateDeltaViewAngles( viewAngles ); + goto Quit; + } + + // if dead + if ( health <= 0 ) { + if ( pm_thirdPersonDeath.GetBool() ) { + viewAngles.roll = 0.0f; + viewAngles.pitch = 30.0f; + } else { + viewAngles.roll = 40.0f; + viewAngles.pitch = -15.0f; + } + goto Quit; + } + + // circularly clamp the angles with deltas + for ( i = 0; i < 3; i++ ) + { + cmdAngles[i] = SHORT2ANGLE( usercmd.angles[i] ); + if ( influenceActive == INFLUENCE_LEVEL3 ) + { + TestAngles[i] += idMath::ClampFloat( -1.0f, 1.0f, idMath::AngleDelta( idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ) , viewAngles[i] ) ); + } + else if( GetTurnHinderance() != 1.0f ) + { + TestAngles[i] += GetTurnHinderance() * idMath::AngleDelta( idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ) , viewAngles[i] ); + } + else + { + TestAngles[i] = idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ); + } + } + if ( !centerView.IsDone( gameLocal.time ) ) { + TestAngles.pitch = centerView.GetCurrentValue(gameLocal.time); + } + + // clamp the pitch + if ( noclip ) { + if ( TestAngles.pitch > 89.0f ) { + // don't let the player look down more than 89 degrees while noclipping + TestAngles.pitch = 89.0f; + } else if ( TestAngles.pitch < -89.0f ) { + // don't let the player look up more than 89 degrees while noclipping + TestAngles.pitch = -89.0f; + } + } else { + if ( TestAngles.pitch > pm_maxviewpitch.GetFloat() ) { + // don't let the player look down enough to see the shadow of his (non-existant) feet + TestAngles.pitch = pm_maxviewpitch.GetFloat(); + } else if ( TestAngles.pitch < pm_minviewpitch.GetFloat() ) { + // don't let the player look up more than 89 degrees + TestAngles.pitch = pm_minviewpitch.GetFloat(); + } + } + + // TDM: Check for collisions due to delta yaw when leaning, overwrite test angles to avoid + physicsObj.UpdateLeanedInputYaw( TestAngles ); + viewAngles = TestAngles; + + UpdateDeltaViewAngles( viewAngles ); + + // orient the model towards the direction we're looking + // LeanMod: SophisticatedZombie: Added roll to this + SetAngles( idAngles( 0.0f, viewAngles.yaw, viewAngles.roll ) ); + + // save in the log for analyzing weapon angle offsets + loggedViewAngles[ gameLocal.framenum & (NUM_LOGGED_VIEW_ANGLES-1) ] = viewAngles; + +Quit: + return; +} + +/* +============== +idPlayer::AdjustHeartRate + +Player heartrate works as follows + +DEF_HEARTRATE is resting heartrate + +Taking damage when health is above 75 adjusts heart rate by 1 beat per second +Taking damage when health is below 75 adjusts heart rate by 5 beats per second +Maximum heartrate from damage is MAX_HEARTRATE + +Firing a weapon adds 1 beat per second up to a maximum of COMBAT_HEARTRATE + +Being at less than 25% stamina adds 5 beats per second up to ZEROSTAMINA_HEARTRATE + +All heartrates are target rates.. the heart rate will start falling as soon as there have been no adjustments for 5 seconds +Once it starts falling it always tries to get to DEF_HEARTRATE + +The exception to the above rule is upon death at which point the rate is set to DYING_HEARTRATE and starts falling +immediately to zero + +Heart rate volumes go from zero ( -40 db for DEF_HEARTRATE to 5 db for MAX_HEARTRATE ) the volume is +scaled linearly based on the actual rate + +Exception to the above rule is once the player is dead, the dying heart rate starts at either the current volume if +it is audible or -10db and scales to 8db on the last few beats +============== +*/ +void idPlayer::AdjustHeartRate( int target, float timeInSecs, float delay, bool force ) { + + if ( heartInfo.GetEndValue() == target ) { + return; + } + + if ( AI_DEAD && !force ) { + return; + } + + lastHeartAdjust = gameLocal.time; + + heartInfo.Init( gameLocal.time + delay * 1000, timeInSecs * 1000, heartRate, target ); +} + +/* +============== +idPlayer::GetBaseHeartRate +============== +*/ +int idPlayer::GetBaseHeartRate( void ) { + /* + int base = idMath::FtoiFast( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( (float)health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ); + int rate = idMath::FtoiFast( base + ( ZEROSTAMINA_HEARTRATE - base ) * ( 1.0f - stamina / pm_stamina.GetFloat() ) ); + int diff = ( lastDmgTime ) ? gameLocal.time - lastDmgTime : 99999; + rate += ( diff < 5000 ) ? ( diff < 2500 ) ? ( diff < 1000 ) ? 15 : 10 : 5 : 0; + return rate; + */ + return BASE_HEARTRATE; +} + +/* +============== +idPlayer::SetCurrentHeartRate +============== +*/ +void idPlayer::SetCurrentHeartRate( void ) { + /// reasons why we should exit + if( false == airless && health > 0 ) + { + if( true == m_HeartBeatAllow ) + { + AdjustHeartRate( BASE_HEARTRATE, 5.5f, 0.0f, false );/// We were allowing so fade it + } + else /// We were NOT allowing it so set to default + { + heartRate = BASE_HEARTRATE; + } + m_HeartBeatAllow = false; + return; + } + /* + if( false == m_HeartBeatAllow )/// we did not want heartbeat heard so make sure + { + heartInfo.Init( gameLocal.time, 0, BASE_HEARTRATE, BASE_HEARTRATE ); + heartRate = BASE_HEARTRATE; + StopSound( SND_CHANNEL_HEART, false ); + } + */ + m_HeartBeatAllow = true; + + + int base = idMath::FtoiFast( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( (float) health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ); + + /// removed adrenaline affect - Rich + heartRate = idMath::FtoiFast( heartInfo.GetCurrentValue( gameLocal.time ) ); + int currentRate = GetBaseHeartRate(); + if ( health >= 0 && gameLocal.time > lastHeartAdjust + 2500 ) { + AdjustHeartRate( currentRate, 2.5f, 0.0f, false ); + } + int bps = idMath::FtoiFast( 60.0f / heartRate * 1000.0f ); + if ( gameLocal.time - lastHeartBeat > bps ) { + int dmgVol = DMG_VOLUME; + int deathVol = DEATH_VOLUME; + int zeroVol = ZERO_VOLUME; + float pct = 0.0; + if ( heartRate > BASE_HEARTRATE && health > 0 ) { + pct = (float)(heartRate - base) / (MAX_HEARTRATE - base); + pct *= ((float)dmgVol - (float)zeroVol); + } else if ( health <= 0 ) { + pct = (float)(heartRate - DYING_HEARTRATE) / (BASE_HEARTRATE - DYING_HEARTRATE); + if ( pct > 1.0f ) { + pct = 1.0f; + } else if (pct < 0.0f) { + pct = 0.0f; + } + pct *= ((float)deathVol - (float)zeroVol); + } + + pct += (float)zeroVol; + + if ( pct != zeroVol ) { + StartSound( "snd_heartbeat", SND_CHANNEL_HEART, SSF_PRIVATE_SOUND, false, NULL ); + // modify just this channel to a custom volume + soundShaderParms_t parms; + memset( &parms, 0, sizeof( parms ) ); + parms.volume = pct; + refSound.referenceSound->ModifySound( SND_CHANNEL_HEART, &parms ); + } + + lastHeartBeat = gameLocal.time; + } +} + +/* +============== +idPlayer::UpdateAir +============== +*/ +void idPlayer::UpdateAir( void ) { + if ( health <= 0 ) { + return; + } + + // see if the player is connected to the info_vacuum + bool newAirless = false; + + if ( gameLocal.vacuumAreaNum != -1 ) { + int num = GetNumPVSAreas(); + if ( num > 0 ) { + int areaNum; + + // if the player box spans multiple areas, get the area from the origin point instead, + // otherwise a rotating player box may poke into an outside area + if ( num == 1 ) { + const int *pvsAreas = GetPVSAreas(); + areaNum = pvsAreas[0]; + } else { + areaNum = gameRenderWorld->PointInArea( this->GetPhysics()->GetOrigin() ); + } + newAirless = gameRenderWorld->AreasAreConnected( gameLocal.vacuumAreaNum, areaNum, PS_BLOCK_AIR ); + } + } + +#ifdef MOD_WATERPHYSICS // check if the player is in water + + idPhysics* phys = GetPhysics(); + + if (phys != NULL && phys->IsType(idPhysics_Actor::Type) && + static_cast(phys)->GetWaterLevel() >= WATERLEVEL_HEAD ) + { + newAirless = true; // MOD_WATERPHYSICS + } + +#endif // MOD_WATERPHYSICS + + + if ( newAirless ) { + if ( !airless ) { + StartSound( "snd_decompress", SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); + StartSound( "snd_noAir", SND_CHANNEL_BODY2, 0, false, NULL ); + if ( hud ) { + hud->HandleNamedEvent( "noAir" ); + } + } + airTics--; + if ( airTics < 0 ) { + airTics = 0; + // check for damage + const idDict *damageDef = gameLocal.FindEntityDefDict( "damage_noair", false ); + int dmgTiming = 1000 * (damageDef ? static_cast(damageDef->GetFloat( "delay", "3.0" )) : 3 ); + if ( gameLocal.time > lastAirDamage + dmgTiming ) { + Damage( NULL, NULL, vec3_origin, "damage_noair", 1.0f, 0 ); + lastAirDamage = gameLocal.time; + } + } + + } else { + if ( airless ) { + StartSound( "snd_recompress", SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); + StopSound( SND_CHANNEL_BODY2, false ); + if ( hud ) { + hud->HandleNamedEvent( "Air" ); + } + } + airTics+=2; // regain twice as fast as lose + if ( airTics > pm_airTics.GetInteger() ) { + airTics = pm_airTics.GetInteger(); + } + } + + airless = newAirless; + + if ( hud ) { + hud->SetStateInt( "player_air", 100 * airTics / pm_airTics.GetInteger() ); + } +} + +int idPlayer::getAirTicks() const { + return airTics; +} + +void idPlayer::setAirTicks(int airTicks) { + airTics = airTicks; + // Clamp to maximum value + if( airTics > pm_airTics.GetInteger() ) { + airTics = pm_airTics.GetInteger(); + } +} + +/* +============== +idPlayer::ToggleScoreboard +============== +*/ +void idPlayer::ToggleScoreboard( void ) { + scoreBoardOpen ^= 1; +} + +/* +============== +idPlayer::Spectate +============== +*/ +void idPlayer::Spectate( bool spectate ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + // track invisible player bug + // all hiding and showing should be performed through Spectate calls + // except for the private camera view, which is used for teleports + assert( ( teleportEntity.GetEntity() != NULL ) || ( IsHidden() == spectating ) ); + + if ( spectating == spectate ) { + return; + } + + spectating = spectate; + + if ( gameLocal.isServer ) { + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteBits( spectating, 1 ); + ServerSendEvent( EVENT_SPECTATE, &msg, false, -1 ); + } + + if ( spectating ) { + // join the spectators + spectator = this->entityNumber; + Init(); + StopRagdoll(); + SetPhysics( &physicsObj ); + physicsObj.DisableClip(); + Hide(); + Event_DisableWeapon(); + if ( hud ) { + hud->HandleNamedEvent( "aim_clear" ); + MPAimFadeTime = 0; + } + } else { + // put everything back together again + currentWeapon = -1; // to make sure the def will be loaded if necessary + Show(); + Event_EnableWeapon(); + } + SetClipModel(); +} + +/* +============== +idPlayer::SetClipModel +============== +*/ +void idPlayer::SetClipModel( void ) { + idBounds bounds; + + if ( spectating ) { + bounds = idBounds( vec3_origin ).Expand( pm_spectatebbox.GetFloat() * 0.5f ); + } else { + bounds[0].Set( -pm_bboxwidth.GetFloat() * 0.5f, -pm_bboxwidth.GetFloat() * 0.5f, 0 ); + bounds[1].Set( pm_bboxwidth.GetFloat() * 0.5f, pm_bboxwidth.GetFloat() * 0.5f, pm_normalheight.GetFloat() ); + } + // the origin of the clip model needs to be set before calling SetClipModel + // otherwise our physics object's current origin value gets reset to 0 + idClipModel *newClip; + if ( pm_usecylinder.GetBool() ) { + newClip = new idClipModel( idTraceModel( bounds, 8 ) ); + newClip->Translate( physicsObj.PlayerGetOrigin() ); + physicsObj.SetClipModel( newClip, 1.0f ); + } else { + newClip = new idClipModel( idTraceModel( bounds ) ); + newClip->Translate( physicsObj.PlayerGetOrigin() ); + physicsObj.SetClipModel( newClip, 1.0f ); + } +} + +/* +============== +idPlayer::UseVehicle +============== +*/ +void idPlayer::UseVehicle( void ) { + trace_t trace; + idVec3 start, end; + idEntity *ent; + + if ( GetBindMaster() && GetBindMaster()->IsType( idAFEntity_Vehicle::Type ) ) { + Show(); + static_cast(GetBindMaster())->Use( this ); + } else { + start = GetEyePosition(); + end = start + viewAngles.ToForward() * 80.0f; + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); + if ( trace.fraction < 1.0f ) { + ent = gameLocal.entities[ trace.c.entityNum ]; + if ( ent && ent->IsType( idAFEntity_Vehicle::Type ) ) { + Hide(); + static_cast(ent)->Use( this ); + } + } + } +} + +/* +============== +idPlayer::PerformImpulse +============== +*/ +void idPlayer::PerformImpulse( int impulse ) { + + if ( gameLocal.isClient ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + assert( entityNumber == gameLocal.localClientNum ); + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteBits( impulse, 6 ); + ClientSendEvent( EVENT_IMPULSE, &msg ); + } + + if ( impulse >= IMPULSE_0 && impulse <= IMPULSE_12 ) + { + // Prevent the player from choosing to switch weapons. + if ( GetImmobilization() & EIM_WEAPON_SELECT ) + { + return; + } + + SelectWeapon( impulse, false ); + return; + } + + switch( impulse ) + { + case IMPULSE_13: + { + Reload(); + break; + } + + case IMPULSE_14: // Next weapon + { + // If the grabber is active, next weapon modifies the distance based on the CVAR setting + if (m_bGrabberActive) + { + gameLocal.m_Grabber->IncrementDistance( cv_reverse_grab_control.GetBool() ); + } + + // Pass the "next weapon" event to the GUIs + m_overlays.broadcastNamedEvent("nextWeapon"); + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Prevent the player from choosing to switch weapons. + if ( GetImmobilization() & EIM_WEAPON_SELECT ) + { + return; + } + + NextWeapon(); + break; + } + case IMPULSE_15: // Previous Weapon + { + // If the grabber is active, previous weapon modifies the distance based on the CVAR setting + if (m_bGrabberActive) + { + gameLocal.m_Grabber->IncrementDistance( !cv_reverse_grab_control.GetBool() ); + } + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Pass the "previous weapon" event to the GUIs + m_overlays.broadcastNamedEvent("prevWeapon"); + + // Prevent the player from choosing to switch weapons. + if ( GetImmobilization() & EIM_WEAPON_SELECT ) + { + return; + } + + PrevWeapon(); + break; + } + case IMPULSE_17: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + gameLocal.mpGame.ToggleReady(); + } + break; + } + + case IMPULSE_18: + { + centerView.Init(gameLocal.time, 200, viewAngles.pitch, 0); + break; + } + case IMPULSE_19: // Toggle Objectives GUI (was previously assigned to the PDA) + { + ToggleObjectivesGUI(); + break; + } + case IMPULSE_20: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + gameLocal.mpGame.ToggleTeam(); + } + break; + } + case IMPULSE_22: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + gameLocal.mpGame.ToggleSpectate(); + } + break; + } + + case IMPULSE_23: // Crouch + { + if (!cv_tdm_crouch_toggle.GetBool()) + { + m_CrouchIntent = true; + } + + m_ButtonStateTracker.StartTracking(impulse); + } + break; + + case IMPULSE_24: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + physicsObj.PerformMantle(); + } + break; + } + + // DarkMod: Sophisticated Zombie: For testing purposes only + // This tests the hiding spot search function relative to the player + case IMPULSE_25: // Test hiding spots. + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Attempting hiding spot test"); + idVec3 searchOrigin = GetEyePosition(); + idBounds searchBounds (searchOrigin); + + idVec3 forward; + idVec3 right; + viewAngles.ToVectors (&forward, &right); + right.Normalize(); + forward.Normalize(); + + idVec3 widthPoint = searchOrigin + (right * 300.0f); + searchBounds.AddPoint (widthPoint); + idVec3 widthPoint2 = searchOrigin - (right * 300.0f); + searchBounds.AddPoint (widthPoint2); + idVec3 endPoint = searchOrigin + (forward * 1000.0f); + searchBounds.AddPoint (endPoint); + + // Get AAS + idAAS* p_aas = NULL; + for (int i = 0; i < gameLocal.NumAAS(); i++) { + p_aas = gameLocal.GetAAS(i); + if (p_aas != NULL) { + CDarkmodAASHidingSpotFinder::testFindHidingSpots( + searchOrigin, + 0.35f, + searchBounds, + this, // Ignore self as a hiding screen + p_aas + ); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Done hiding spot test"); + } + } + + if (p_aas == NULL) + { + DM_LOG(LC_AI, LT_WARNING)LOGSTRING("No default AAS is present for map, number of AAS: %d\n", gameLocal.NumAAS()); + } + + } + break; + + case IMPULSE_27: + { + //LAS.pvsToAASMappingTable.DebugShowMappings(10000); + idAASLocal* aas = dynamic_cast(gameLocal.GetAAS(cv_debug_aastype.GetString())); + + if (aas != NULL) + { + aas->DrawAreas(GetEyePosition()); + } + } + break; + + case IMPULSE_28: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + gameLocal.mpGame.CastVote( gameLocal.localClientNum, true ); + } + } + break; + + case IMPULSE_29: + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + gameLocal.mpGame.CastVote( gameLocal.localClientNum, false ); + } + } + break; + + case IMPULSE_40: // TDM: grab item with grabber + { + CGrabber *grabber = gameLocal.m_Grabber; + idEntity *useEnt = grabber->GetSelected(); + if(useEnt == NULL) + { + idEntity *frob = m_FrobEntity.GetEntity(); + if(frob != NULL) + grabber->PutInHands(frob, frob->GetPhysics()->GetAxis() ); + } + } + break; + + case IMPULSE_41: // TDM Use/Frob + { + // Register the button for tracking + m_ButtonStateTracker.StartTracking(impulse); + // Perform the frob + PerformFrob(); + } + break; + + /*! + * Lean forward is impulse 44 + */ + case IMPULSE_44: // Lean forward + { + m_ButtonStateTracker.StartTracking(impulse); + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + physicsObj.ToggleLean(90.0); + } + break; + + /*! + * Lean left is impulse 45 + */ + case IMPULSE_45: // Lean left + { + m_ButtonStateTracker.StartTracking(impulse); + DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Left lean impulse pressed\r"); + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + // Do we need to enter the leaning state? + DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Left leaning started\r"); + physicsObj.ToggleLean(180.0); + } + } + break; + + /*! + * Lean right is impulse 46 + */ + case IMPULSE_46: // Lean right + { + m_ButtonStateTracker.StartTracking(impulse); + DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Right lean impulse pressed\r"); + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + physicsObj.ToggleLean(0.0); + } + break; + + case IMPULSE_47: // Inventory previous item + { + // If the grabber is active, prev item modifies the distance based on the CVAR setting + if (m_bGrabberActive) + { + gameLocal.m_Grabber->IncrementDistance( !cv_reverse_grab_control.GetBool() ); + } + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Notify the GUIs about the button event + m_overlays.broadcastNamedEvent("inventoryPrevItem"); + + if(GetImmobilization() & EIM_ITEM_SELECT) + return; + + NextPrevInventoryItem(-1); + } + break; + + case IMPULSE_48: // Inventory next item + { + // If the grabber is active, next item modifies the distance based on the CVAR setting + if (m_bGrabberActive) + { + gameLocal.m_Grabber->IncrementDistance( cv_reverse_grab_control.GetBool() ); + } + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Notify the GUIs about the button event + m_overlays.broadcastNamedEvent("inventoryNextItem"); + + if(GetImmobilization() & EIM_ITEM_SELECT) + return; + + NextPrevInventoryItem(1); + } + break; + + case IMPULSE_49: // Inventory previous group + { + // Check for a held grabber entity, which should be put back into the inventory + if (AddGrabberEntityToInventory()) + return; + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Notify the GUIs about the button event + m_overlays.broadcastNamedEvent("inventoryPrevGroup"); + + if(GetImmobilization() & EIM_ITEM_SELECT) + return; + + NextPrevInventoryGroup(-1); + } + break; + + case IMPULSE_50: // Inventory next group + { + // Check for a held grabber entity, which should be put back into the inventory + if (AddGrabberEntityToInventory()) + return; + + // Trigger an objectives GUI update if applicable + UpdateObjectivesGUI(); + + // Notify the GUIs about the button event + m_overlays.broadcastNamedEvent("inventoryNextGroup"); + + if(GetImmobilization() & EIM_ITEM_SELECT) + return; + + NextPrevInventoryGroup(1); + } + break; + + case IMPULSE_51: // Inventory use item + { + // Use key has "hold down" functions + m_ButtonStateTracker.StartTracking(impulse); + // Pass the call + UseInventoryItem(); + } + break; + + case IMPULSE_52: // Inventory drop item + { + // Pass the "inventoryDropItem" event to the GUIs + m_overlays.broadcastNamedEvent("inventoryDropItem"); + + if (GetImmobilization() & EIM_ITEM_DROP) { + return; + } + + DropInventoryItem(); + } + break; + + } +} + +void idPlayer::PerformKeyRepeat(int impulse, int holdTime) +{ + + + switch (impulse) + { + case IMPULSE_23: // TDM Crouch + { + if (holdTime > cv_tdm_crouch_toggle_hold_time.GetFloat()) + { + if (physicsObj.OnRope()) + { + physicsObj.RopeDetach(); + physicsObj.m_bClimbDetachCrouchHeld = true; + } + else if (physicsObj.OnLadder()) + { + physicsObj.ClimbDetach(); + physicsObj.m_bClimbDetachCrouchHeld = true; + } + } + + } + break; + + case IMPULSE_41: // TDM Use/Frob + { + PerformFrobKeyRepeat(holdTime); + } + break; + + case IMPULSE_51: // Inventory Use Item + { + const CInventoryCursorPtr& crsr = InventoryCursor(); + CInventoryItemPtr it = crsr->GetCurrentItem(); + + if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) + { + UseInventoryItem(ERepeat, it, holdTime, false); + } + } + break; + } +} + +void idPlayer::PerformKeyRelease(int impulse, int holdTime) +{ + // The key associated to has been released + DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Button %d has been released, has been held down %d ms.\r", impulse, holdTime); + + switch (impulse) + { + case IMPULSE_23: // TDM crouch + if (cv_tdm_crouch_toggle.GetBool()) + { + if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) + { + m_CrouchIntent = !m_CrouchIntent; + } + } + else + { + m_CrouchIntent = false; + } + + // clear climb detach intent when crouch is released + physicsObj.m_bClimbDetachCrouchHeld = false; + + break; + + case IMPULSE_41: // TDM Use/Frob + { + PerformFrobKeyRelease(holdTime); + } + break; + + + + case IMPULSE_44: + if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) + physicsObj.ToggleLean(90.0); + break; + + case IMPULSE_45: + if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) + physicsObj.ToggleLean(180.0); + break; + + case IMPULSE_46: + if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) + physicsObj.ToggleLean(0.0); + break; + + case IMPULSE_51: // Inventory Use item + { + InventoryUseKeyRelease(holdTime); + } + break; + } +} + +bool idPlayer::HandleESC( void ) { + if ( gameLocal.inCinematic ) { + return SkipCinematic(); + } + + if ( m_overlays.findInteractive() ) { + // Handle the escape? + // Not yet implemented. + // return true? + } + + return false; +} + +bool idPlayer::SkipCinematic( void ) { + StartSound( "snd_skipcinematic", SND_CHANNEL_ANY, 0, false, NULL ); + return gameLocal.SkipCinematic(); +} + + +/* +============== +idPlayer::GetImmobilization +============== +*/ +int idPlayer::GetImmobilization() +{ + // Has something changed since the cache was last calculated? + if ( m_immobilizationCache & EIM_UPDATE ) + { + // Recalculate the immobilization from scratch. + m_immobilizationCache = 0; + + for (const idKeyValue* kv = m_immobilization.MatchPrefix(""); kv != NULL; kv = m_immobilization.MatchPrefix("", kv)) + { + m_immobilizationCache |= atoi(kv->GetValue()); + } + } + + return m_immobilizationCache; +} + +/* +============== +idPlayer::GetHinderance +============== +*/ +float idPlayer::GetHinderance( void ) +{ + // Has something changed since the cache was last calculated? + if (m_hinderanceCache < 0.0f) + { + // Recalculate the hinderance from scratch. + float mCap = 1.0f, aCap = 1.0f; + + for (const idKeyValue* kv = m_hinderance.MatchPrefix("", NULL); kv != NULL; kv = m_hinderance.MatchPrefix("", kv)) + { + idVec3 vec = m_hinderance.GetVector(kv->GetKey()); + mCap *= vec[0]; + + if ( aCap > vec[1] ) + { + aCap = vec[1]; + } + } + + if ( aCap > mCap ) + { + aCap = mCap; + } + + m_hinderanceCache = aCap; + } + + return m_hinderanceCache; +} + +/* +============== +idPlayer::GetTurnHinderance +============== +*/ +float idPlayer::GetTurnHinderance( void ) +{ + // Has something changed since the cache was last calculated? + if (m_TurnHinderanceCache < 0.0f) + { + // Recalculate the hinderance from scratch. + float mCap = 1.0f, aCap = 1.0f; + + for (const idKeyValue* kv = m_TurnHinderance.MatchPrefix( "", NULL ); kv != NULL; kv = m_TurnHinderance.MatchPrefix("", kv)) + { + idVec3 vec = m_TurnHinderance.GetVector(kv->GetKey()); + mCap *= vec[0]; + + if ( aCap > vec[1] ) + { + aCap = vec[1]; + } + } + + if ( aCap > mCap ) + { + aCap = mCap; + } + + m_TurnHinderanceCache = aCap; + } + + return m_TurnHinderanceCache; +} + +/* +============== +idPlayer::EvaluateControls +============== +*/ +void idPlayer::EvaluateControls( void ) +{ + // check for respawning + // TDM: Section removed, click-to-respawn functionality not needed for TDM + // TDM: Added lean key check + + // in MP, idMultiplayerGame decides spawns + if ( forceRespawn && !gameLocal.isMultiplayer && !g_testDeath.GetBool() ) { + // in single player, we let the session handle restarting the level or loading a game + gameLocal.sessionCommand = "died"; + } + + if( m_MouseGesture.bActive ) + UpdateMouseGesture(); + + if ( ( usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) + { + PerformImpulse( usercmd.impulse ); + } + + scoreBoardOpen = ( ( usercmd.buttons & BUTTON_SCORES ) != 0 || forceScoreBoard ); + + oldFlags = usercmd.flags; + + AdjustSpeed(); + + // update the viewangles + UpdateViewAngles(); +} + + +void idPlayer::EvaluateCrouch() +{ + if ( GetImmobilization() & EIM_CROUCH) + { + m_IdealCrouchState = false; + return; + } + m_IdealCrouchState = m_CrouchIntent; +} + + + +/** +* TDM Mouse Gestures +**/ +void idPlayer::StartMouseGesture( int impulse, int thresh, EMouseTest test, bool bInverted, float TurnHinderance, int DecideTime, int DeadTime ) +{ + m_MouseGesture.bActive = true; + m_MouseGesture.test = test; + m_MouseGesture.bInverted = bInverted; + m_MouseGesture.key = impulse; + m_MouseGesture.thresh = thresh; + m_MouseGesture.DecideTime = DecideTime; + m_MouseGesture.DeadTime = DeadTime; + + m_MouseGesture.started = gameLocal.time; + m_MouseGesture.StartPos.x = usercmd.mx; + m_MouseGesture.StartPos.y = usercmd.my; + m_MouseGesture.motion = vec2_zero; + + // NOTE: Do not clear the last result as we may use it again if we can't decide + + SetTurnHinderance( "MouseGesture", 1.0f, TurnHinderance ); +} + +void idPlayer::UpdateMouseGesture( void ) +{ + bool bStop( false ); + float mag(0.0f); + EMouseDir CurrentDir; + + m_MouseGesture.motion.x += usercmd.mx - m_MouseGesture.StartPos.x; + m_MouseGesture.motion.y += usercmd.my - m_MouseGesture.StartPos.y; + if( m_MouseGesture.bInverted ) + m_MouseGesture.motion = -m_MouseGesture.motion; + + EMouseTest test = m_MouseGesture.test; + idVec2 motion = m_MouseGesture.motion; + + // Get the current dominant direction and magnitude + // NOTE: Apparently y is positive if we go down, not up? + if( test == MOUSETEST_UPDOWN ) + { + if( motion.y < 0 ) + CurrentDir = MOUSEDIR_UP; + else + CurrentDir = MOUSEDIR_DOWN; + + mag = idMath::Fabs( motion.y ); + } + else if ( test == MOUSETEST_LEFTRIGHT ) + { + if( motion.x > 0 ) + CurrentDir = MOUSEDIR_RIGHT; + else + CurrentDir = MOUSEDIR_LEFT; + + mag = idMath::Fabs( motion.x ); + } + else if( test == MOUSETEST_4DIR ) + { + // up/down motion dominant + if( idMath::Fabs(motion.y) > idMath::Fabs(motion.x) ) + { + if( motion.y < 0 ) + CurrentDir = MOUSEDIR_UP; + else + CurrentDir = MOUSEDIR_DOWN; + + mag = idMath::Fabs( motion.y ); + } + // side/side dominant (default left for zero input) + else + { + if( motion.x > 0 ) + CurrentDir = MOUSEDIR_RIGHT; + else + CurrentDir = MOUSEDIR_LEFT; + + mag = idMath::Fabs( motion.x ); + } + } + else + { + // Test along 8 directions (NOT TESTED!) + + // Step 1, resolve onto diagonal basis + idVec2 DiagVec; + // upper right + DiagVec.x = motion * idMath::SQRT_1OVER2 * idVec2(1.0f,1.0f); + // lower right + DiagVec.y = motion * idMath::SQRT_1OVER2 * idVec2(1.0f,-1.0f); + + // figure out which is dominant + idList dirs; + dirs.Append(idMath::Fabs(motion.y)); + dirs.Append(idMath::Fabs(motion.x)); + dirs.Append(idMath::Fabs(DiagVec.x)); + dirs.Append(idMath::Fabs(DiagVec.y)); + + mag = 0.0f; + int MaxAxis = 1; // default to left if we have zero motion + + for( int i=0; i < 4; i++ ) + { + if( dirs[i] > mag ) + { + mag = dirs[i]; + MaxAxis = i; + } + } + + // up/down + if( MaxAxis == 0 ) + { + if( motion.y < 0 ) + CurrentDir = MOUSEDIR_UP; + else + CurrentDir = MOUSEDIR_DOWN; + } + // left/right + else if( MaxAxis == 1) + { + if( motion.x > 0 ) + CurrentDir = MOUSEDIR_RIGHT; + else + CurrentDir = MOUSEDIR_LEFT; + } + // lower right/upper left + else if( MaxAxis == 2) + { + if( DiagVec.x < 0 ) + CurrentDir = MOUSEDIR_UP_LEFT; + else + CurrentDir = MOUSEDIR_DOWN_RIGHT; + } + // upper right/lower left + else + { + if( DiagVec.y < 0 ) + CurrentDir = MOUSEDIR_DOWN_LEFT; + else + CurrentDir = MOUSEDIR_UP_RIGHT; + } + } + + + // If above threshold, decision timer ran out, or button released, we're done + if( mag > m_MouseGesture.thresh + || (m_MouseGesture.DecideTime >= 0 && (gameLocal.time - m_MouseGesture.started) > m_MouseGesture.DecideTime) + || !common->ButtonState(m_MouseGesture.key) ) + { + m_MouseGesture.result = CurrentDir; + StopMouseGesture(); + } +} + +void idPlayer::StopMouseGesture( void ) +{ + m_MouseGesture.bActive = false; + + // clear the angular hinderance, or if dead time is still going, schedule an event to clear it + if( (gameLocal.time - m_MouseGesture.started) > m_MouseGesture.DeadTime ) + SetTurnHinderance( "MouseGesture", 1.0f, 1.0f ); + else + PostEventMS( &EV_Player_ClearMouseDeadTime, (m_MouseGesture.DeadTime - (gameLocal.time - m_MouseGesture.started)) ); +} + +EMouseDir idPlayer::GetMouseGesture( void ) +{ + return m_MouseGesture.result; +} + +void idPlayer::Event_GetMouseGesture( void ) +{ + idThread::ReturnInt( (int) GetMouseGesture() ); +} + +void idPlayer::Event_MouseGestureFinished( void ) +{ + idThread::ReturnInt( !m_MouseGesture.bActive ); +} + +void idPlayer::Event_ClearMouseDeadTime( void ) +{ + SetTurnHinderance( "MouseGesture", 1.0f, 1.0f ); +} + +/* +============== +idPlayer::AdjustSpeed + +DarkMod Note: Wow... this was pretty badly written +============== +*/ +void idPlayer::AdjustSpeed( void ) +{ + float speed(0.0f); + float crouchspeed(0.0f); + float rate(0.0f); + + float maxSpeed = pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat() * GetHinderance(); + + if ( spectating ) + { + speed = pm_spectatespeed.GetFloat(); + bobFrac = 0.0f; + } + else if ( noclip && !( usercmd.buttons & BUTTON_RUN )) + { + // "Walk" noclip + speed = pm_noclipspeed.GetFloat(); + bobFrac = 0.0f; + } + else if ( noclip && ( usercmd.buttons & BUTTON_RUN )) + { + // "run" noclip + speed = pm_noclipspeed.GetFloat() * cv_pm_runmod.GetFloat(); + bobFrac = 0.0f; + } + // running case + // TDM: removed check for not crouching.. + else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) ) + { + float walkSpeed = pm_walkspeed.GetFloat(); + + speed = walkSpeed * cv_pm_runmod.GetFloat(); + + // greebo: Only adjust bob fraction if actually running + if (physicsObj.HasRunningVelocity()) + { + // Scale the viewbob with the velocity + // At walkspeed, bobfrac is 0, at full run speed it should be 1 + const idVec3& vel = physicsObj.GetLinearVelocity(); + bobFrac = idMath::ClampFloat(0, 1, (vel.LengthFast() - walkSpeed) / (speed - walkSpeed)); + } + + // ishtvan: we'll see if this works to prevent backwards running, depends on order things are set + // Don't apply backwards run penalty to crouch run. It's already slow enough. + crouchspeed = speed * cv_pm_crouchmod.GetFloat(); + if( usercmd.forwardmove < 0 ) + { + speed *= cv_pm_run_backmod.GetFloat(); + } + + // Clamp to encumbrance limits: + speed = idMath::ClampFloat(0, maxSpeed, speed); + crouchspeed = idMath::ClampFloat(0, maxSpeed, crouchspeed); + } + else // standing still, walking, or creeping case + { + speed = pm_walkspeed.GetFloat(); + bobFrac = 0.0f; + + // apply creep modifier; creep is on button_5 + if( usercmd.buttons & BUTTON_5 ) + { + speed *= cv_pm_creepmod.GetFloat(); + } + + // apply movement multipliers to crouch as well + crouchspeed = speed * cv_pm_crouchmod.GetFloat(); + + // Clamp to encumbrance limits: + speed = idMath::ClampFloat(0, maxSpeed, speed); + crouchspeed = idMath::ClampFloat(0, maxSpeed, crouchspeed); + } + + // greebo: Clamp speed if swimming to 1.3 x walkspeed + if (physicsObj.GetWaterLevel() >= WATERLEVEL_WAIST) + { + speed = idMath::ClampFloat(0, pm_walkspeed.GetFloat() * cv_pm_max_swimspeed_mod.GetFloat(), speed); + } + + // TDM: leave this in for speed potions or something + speed *= PowerUpModifier(SPEED); + + if (influenceActive == INFLUENCE_LEVEL3) + { + speed *= 0.33f; + } + + physicsObj.SetSpeed(speed, crouchspeed); + + //gameRenderWorld->DrawText(va("bobFrac: %f\n", bobFrac), GetEyePosition() + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); + //gameRenderWorld->DrawText(va("speed: %f\n", physicsObj.GetLinearVelocity().Length()), GetEyePosition() + idVec3(0,0,-20) + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); + //gameLocal.Printf("bobFrac: %f\n", bobFrac); +} + +/* +============== +idPlayer::AdjustBodyAngles +============== +*/ +void idPlayer::AdjustBodyAngles( void ) { + idMat3 lookAxis; + idMat3 legsAxis; + bool blend; + float diff; + float frac; + float upBlend; + float forwardBlend; + float downBlend; + + if ( health < 0 ) { + return; + } + + blend = true; + + if ( !physicsObj.HasGroundContacts() ) { + idealLegsYaw = 0.0f; + legsForward = true; + } else if ( usercmd.forwardmove < 0 ) { + idealLegsYaw = idMath::AngleNormalize180( idVec3( -usercmd.forwardmove, usercmd.rightmove, 0.0f ).ToYaw() ); + legsForward = false; + } else if ( usercmd.forwardmove > 0 ) { + idealLegsYaw = idMath::AngleNormalize180( idVec3( usercmd.forwardmove, -usercmd.rightmove, 0.0f ).ToYaw() ); + legsForward = true; + } else if ( ( usercmd.rightmove != 0 ) && physicsObj.IsCrouching() ) { + if ( !legsForward ) { + idealLegsYaw = idMath::AngleNormalize180( idVec3( idMath::Abs( usercmd.rightmove ), usercmd.rightmove, 0.0f ).ToYaw() ); + } else { + idealLegsYaw = idMath::AngleNormalize180( idVec3( idMath::Abs( usercmd.rightmove ), -usercmd.rightmove, 0.0f ).ToYaw() ); + } + } else if ( usercmd.rightmove != 0 ) { + idealLegsYaw = 0.0f; + legsForward = true; + } else { + legsForward = true; + diff = idMath::Fabs( idealLegsYaw - legsYaw ); + idealLegsYaw = idealLegsYaw - idMath::AngleNormalize180( viewAngles.yaw - oldViewYaw ); + if ( diff < 0.1f ) { + legsYaw = idealLegsYaw; + blend = false; + } + } + + if ( !physicsObj.IsCrouching() ) { + legsForward = true; + } + + oldViewYaw = viewAngles.yaw; + + AI_TURN_LEFT = false; + AI_TURN_RIGHT = false; + if ( idealLegsYaw < -45.0f ) { + idealLegsYaw = 0; + AI_TURN_RIGHT = true; + blend = true; + } else if ( idealLegsYaw > 45.0f ) { + idealLegsYaw = 0; + AI_TURN_LEFT = true; + blend = true; + } + + if ( blend ) { + legsYaw = legsYaw * 0.9f + idealLegsYaw * 0.1f; + } + legsAxis = idAngles( 0.0f, legsYaw, 0.0f ).ToMat3(); + animator.SetJointAxis( hipJoint, JOINTMOD_WORLD, legsAxis ); + + // calculate the blending between down, straight, and up + frac = viewAngles.pitch / 90.0f; + if ( frac > 0.0f ) { + downBlend = frac; + forwardBlend = 1.0f - frac; + upBlend = 0.0f; + } else { + downBlend = 0.0f; + forwardBlend = 1.0f + frac; + upBlend = -frac; + } + + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, downBlend ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, forwardBlend ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 2, upBlend ); + + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, downBlend ); + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, forwardBlend ); + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 2, upBlend ); +} + +/* +============== +idPlayer::InitAASLocation +============== +*/ +void idPlayer::InitAASLocation( void ) { + int i; + int num; + idVec3 size; + idBounds bounds; + idAAS *aas; + idVec3 origin; + + GetFloorPos( 64.0f, origin ); + + num = gameLocal.NumAAS(); + aasLocation.SetGranularity( 1 ); + aasLocation.SetNum( num ); + for( i = 0; i < aasLocation.Num(); i++ ) { + aasLocation[ i ].areaNum = 0; + aasLocation[ i ].pos = origin; + aas = gameLocal.GetAAS( i ); + if ( aas && aas->GetSettings() ) { + size = aas->GetSettings()->boundingBoxes[0][1]; + bounds[0] = -size; + size.z = 32.0f; + bounds[1] = size; + + aasLocation[ i ].areaNum = aas->PointReachableAreaNum( origin, bounds, AREA_REACHABLE_WALK ); + } + } +} + +/* +============== +idPlayer::SetAASLocation +============== +*/ +void idPlayer::SetAASLocation( void ) { + int i; + int areaNum; + idVec3 size; + idBounds bounds; + idAAS *aas; + idVec3 origin; + + if ( !GetFloorPos( 64.0f, origin ) ) { + return; + } + + for( i = 0; i < aasLocation.Num(); i++ ) { + aas = gameLocal.GetAAS( i ); + if ( !aas ) { + continue; + } + + size = aas->GetSettings()->boundingBoxes[0][1]; + bounds[0] = -size; + size.z = 32.0f; + bounds[1] = size; + + areaNum = aas->PointReachableAreaNum( origin, bounds, AREA_REACHABLE_WALK ); + if ( areaNum ) { + aasLocation[ i ].pos = origin; + aasLocation[ i ].areaNum = areaNum; + } + } +} + +/* +============== +idPlayer::GetAASLocation +============== +*/ +void idPlayer::GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const { + int i; + + if ( aas != NULL ) { + for( i = 0; i < aasLocation.Num(); i++ ) { + if ( aas == gameLocal.GetAAS( i ) ) { + areaNum = aasLocation[ i ].areaNum; + pos = aasLocation[ i ].pos; + return; + } + } + } + + areaNum = 0; + pos = physicsObj.GetOrigin(); +} + +/* +============== +idPlayer::Move +============== +*/ +void idPlayer::Move( void ) +{ + float newEyeOffset; + idVec3 savedOrigin; + idVec3 savedVelocity; + idVec3 pushVelocity; + + // save old origin and velocity for crashlanding + savedOrigin = physicsObj.GetOrigin(); + savedVelocity = physicsObj.GetLinearVelocity(); + + pushVelocity = physicsObj.GetPushedLinearVelocity(); + + // set physics variables + physicsObj.SetMaxStepHeight( pm_stepsize.GetFloat() ); + physicsObj.SetMaxJumpHeight( pm_jumpheight.GetFloat()*GetJumpHinderance() ); + + if ( noclip ) { + physicsObj.SetContents( 0 ); + physicsObj.SetMovementType( PM_NOCLIP ); + } else if ( spectating ) { + physicsObj.SetContents( 0 ); + physicsObj.SetMovementType( PM_SPECTATOR ); + } else if ( health <= 0 ) { + physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ); + physicsObj.SetMovementType( PM_DEAD ); + } else if ( gameLocal.inCinematic || gameLocal.GetCamera() || privateCameraView || ( influenceActive == INFLUENCE_LEVEL2 ) ) { + physicsObj.SetContents( CONTENTS_BODY ); + physicsObj.SetMovementType( PM_FREEZE ); + } else { + physicsObj.SetContents( CONTENTS_BODY ); + physicsObj.SetMovementType( PM_NORMAL ); + } + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + if ( spectating ) { + physicsObj.SetClipMask( MASK_DEADSOLID ); + } else if ( health <= 0 ) { + physicsObj.SetClipMask( MASK_DEADSOLID ); + } else { + physicsObj.SetClipMask( MASK_PLAYERSOLID ); + } + + physicsObj.SetDebugLevel( g_debugMove.GetBool() ); + physicsObj.SetPlayerInput( usercmd, viewAngles ); + + // FIXME: physics gets disabled somehow + BecomeActive( TH_PHYSICS ); + RunPhysics(); + + // update our last valid AAS location for the AI + SetAASLocation(); + + if ( spectating ) { + newEyeOffset = 0.0f; + } else if ( health <= 0 ) { + newEyeOffset = pm_deadviewheight.GetFloat(); + } else if ( physicsObj.IsCrouching() ) { + newEyeOffset = pm_crouchviewheight.GetFloat(); + } else if ( GetBindMaster() && GetBindMaster()->IsType( idAFEntity_Vehicle::Type ) ) { + newEyeOffset = 0.0f; + } else { + newEyeOffset = pm_normalviewheight.GetFloat(); + } + + if ( EyeHeight() != newEyeOffset ) { + if ( spectating ) { + SetEyeHeight( newEyeOffset ); + } else { + // smooth out duck height changes + SetEyeHeight( EyeHeight() * pm_crouchrate.GetFloat() + newEyeOffset * ( 1.0f - pm_crouchrate.GetFloat() ) ); + } + } + + if ( noclip || gameLocal.inCinematic || ( influenceActive == INFLUENCE_LEVEL2 ) ) { + AI_CROUCH = false; + AI_ONGROUND = ( influenceActive == INFLUENCE_LEVEL2 ); + AI_ONLADDER = false; + AI_JUMP = false; + } else { + AI_CROUCH = physicsObj.IsCrouching(); + AI_ONGROUND = physicsObj.HasGroundContacts(); + AI_ONLADDER = physicsObj.OnLadder(); + AI_JUMP = physicsObj.HasJumped(); + + // check if we're standing on top of a monster and give a push if we are + idEntity *groundEnt = physicsObj.GetGroundEntity(); + if + ( + groundEnt && groundEnt->IsType( idAI::Type ) + && groundEnt->health > 0 + && static_cast(groundEnt)->m_bPushOffPlayer + ) + { + idVec3 vel = physicsObj.GetLinearVelocity(); + if ( vel.ToVec2().LengthSqr() < 0.1f ) { + vel.ToVec2() = physicsObj.GetOrigin().ToVec2() - groundEnt->GetPhysics()->GetAbsBounds().GetCenter().ToVec2(); + vel.ToVec2().NormalizeFast(); + vel.ToVec2() *= pm_walkspeed.GetFloat(); + } else { + // give em a push in the direction they're going + vel *= 1.1f; + } + physicsObj.SetLinearVelocity( vel ); + } + } + + if ( AI_JUMP ) + { + // bounce the view weapon + loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; + currentLoggedAccel++; + acc->time = gameLocal.time; + acc->dir[2] = 200; + acc->dir[0] = acc->dir[1] = 0; + } + + // play rope movement sounds + if (physicsObj.OnRope()) + { + // Correct for moving reference frame + int startTime = gameLocal.previousTime; + int endTime = gameLocal.time; + float refZOffset = MS2SEC(endTime - startTime) * physicsObj.GetRefEntVel().z; + + int old_vert = static_cast(savedOrigin.z / cv_pm_rope_snd_rep_dist.GetInteger()); + int new_vert = static_cast((physicsObj.GetOrigin().z - refZOffset) / cv_pm_rope_snd_rep_dist.GetInteger()); + + if (old_vert != new_vert) + { + // greebo: Get the rope entity and read the material/sound type from its spawnargs + idEntity* rope = physicsObj.GetRopeEntity(); + + // If we have a valid rope entity, copy the rope movement snd_ value from it to the player's spawnargs + if (rope != NULL) + { + const char* const tempKey = "snd_rope_climb_temp__"; // temporary key + + // Check if the rope has an override keyvalue + const idKeyValue* kv = rope->spawnArgs.FindKey("snd_rope_climb"); + + // Fill the temporary key on the player entity + if (kv != NULL && kv->GetValue().Length() > 0) + { + spawnArgs.Set(tempKey, kv->GetValue()); + } + else + { + // No special climb sound on the entity, use the one in the player def + spawnArgs.Set(tempKey, spawnArgs.GetString("snd_rope_climb")); + } + + // Start the sound using the temporary key + StartSound(tempKey, SND_CHANNEL_ANY, 0, false, NULL); + } + else + { + // No rope entity?! Fall back to player default + StartSound("snd_rope_climb", SND_CHANNEL_ANY, 0, false, NULL); + } + } + } + // play climbing movement sounds + else if (AI_ONLADDER) + { + // Correct for moving reference frame + int startTime = gameLocal.previousTime; + int endTime = gameLocal.time; + idVec3 RefFrameOffset = MS2SEC(endTime - startTime) * physicsObj.GetRefEntVel(); + idVec3 GravNormal = physicsObj.GetGravityNormal(); + idVec3 RefFrameOffsetXY = RefFrameOffset - (RefFrameOffset * GravNormal ) * GravNormal; + + int old_vert = static_cast(savedOrigin.z / physicsObj.GetClimbSndRepDistVert()); + int new_vert = static_cast((physicsObj.GetOrigin().z - RefFrameOffset.z) / physicsObj.GetClimbSndRepDistVert()); + + int old_horiz = static_cast(physicsObj.GetClimbLateralCoord( savedOrigin ) / physicsObj.GetClimbSndRepDistHoriz()); + int new_horiz = static_cast(physicsObj.GetClimbLateralCoord( physicsObj.GetOrigin() - RefFrameOffsetXY ) / physicsObj.GetClimbSndRepDistHoriz()); + + idStr localSound; + + if (old_vert != new_vert) + { + localSound = "snd_climb_vert_"; + } + else if (old_horiz != new_horiz) + { + localSound = "snd_climb_horiz_"; + } + + if (localSound.Length() > 0) + { + idStr surfaceName = physicsObj.GetClimbSurfaceType(); + + idStr tempStr = localSound + surfaceName; + idStr sound = spawnArgs.GetString(tempStr.c_str()); + + if (sound.Length() == 0) + { + tempStr = localSound + "default"; + sound = spawnArgs.GetString(tempStr.c_str()); + } + // DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Climb sound: %s\r", TempStr.c_str() ); + if (sound.Length() > 0) + { + StartSound(tempStr.c_str(), SND_CHANNEL_BODY, 0, false, NULL); // grayman - #2341 - was SND_CHANNEL_ANY + } + } + } + + if (health > 0) + { + CrashLand(savedOrigin, savedVelocity); + } + + BobCycle(pushVelocity); +} + +/* +============== +idPlayer::UpdateHUD +============== +*/ +void idPlayer::UpdateHUD() +{ + if (hud == NULL) return; + + if ( entityNumber != gameLocal.localClientNum ) { + return; + } + + // Broadcast the HUD opacity value + m_overlays.setGlobalStateFloat("HUD_Opacity", cv_tdm_hud_opacity.GetFloat()); + + // Propagate the CVAR to the HUD + hud->SetStateBool("HUD_LightgemVisible", !cv_tdm_hud_hide_lightgem.GetBool()); + + // Update the inventory HUD + UpdateInventoryHUD(); + + // Check if any HUD messages are pending + UpdateHUDMessages(); + UpdateInventoryPickedUpMessages(); + + // Update the playing time in the HUD, if desired + hud->SetStateString("PlayingTime", cv_show_gameplay_time.GetBool() ? gameLocal.m_GamePlayTimer.GetTime().c_str() : ""); + + hud->SetStateBool("PlayerIsCrouched", m_CrouchIntent ? true : false); +} + +void idPlayer::UpdateInventoryHUD() +{ + if (!inventoryHUDNeedsUpdate) return; // nothing to do + + // Clear the flag right before taking any action + inventoryHUDNeedsUpdate = false; + + CInventoryItemPtr curItem = InventoryCursor()->GetCurrentItem(); + + if (curItem == NULL) return; // no current item, nothing to do + + idEntity* curItemEnt = curItem->GetItemEntity(); + + if (curItemEnt != NULL) + { + // Call the item's update routine for the update + idThread* thread = curItemEnt->CallScriptFunctionArgs( + "inventory_item_update", true, 0, + "eef", curItemEnt, curItem->GetOwner(), static_cast(curItem->GetOverlay()) + ); + + if (thread != NULL) + { + thread->Execute(); + } + } + + // Now take the correct action based on the selected type + switch (curItem->GetType()) + { + case CInventoryItem::IT_ITEM: + { + // We display the default hud if the item doesn't have its own. Each item + // with its own gui is responsible for switching it on and off + // appropriately with their respective events. + if (curItem->HasHUD() == false) + { + SetGuiInt(m_InventoryOverlay, "Inventory_GroupVisible", 1); + SetGuiInt(m_InventoryOverlay, "Inventory_ItemVisible", 1); + + idStr itemName = gameLocal.m_I18N->Translate( curItem->GetName() ); + + // Tels: translated names can have two lines, so tell the GUI about it + SetGuiInt(m_InventoryOverlay, "Inventory_ItemNameMultiline", itemName.Find( '\n' ) != -1 ? 1 : 0 ); + + SetGuiFloat(m_InventoryOverlay, "Inventory_ItemStackable", curItem->IsStackable() ? 1 : 0); + SetGuiString(m_InventoryOverlay, "Inventory_ItemGroup", gameLocal.m_I18N->Translate( curItem->Category()->GetName() ) ); + SetGuiString(m_InventoryOverlay, "Inventory_ItemName", itemName ); + SetGuiInt(m_InventoryOverlay, "Inventory_ItemCount", curItem->GetCount()); + SetGuiString(m_InventoryOverlay, "Inventory_ItemIcon", curItem->GetIcon().c_str()); + } + } + break; + + case CInventoryItem::IT_DUMMY: + { + // All objects are set to empty, so we have an empty entry in the inventory. + SetGuiInt(m_InventoryOverlay, "Inventory_ItemVisible", 0); + SetGuiInt(m_InventoryOverlay, "Inventory_LootVisible", 0); + SetGuiInt(m_InventoryOverlay, "Inventory_GroupVisible", 0); + } + break; + + default: break; + } + + idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); + if (invGUI != NULL) + { + invGUI->StateChanged(gameLocal.time); + } +} + +void idPlayer::UpdateHUDMessages() +{ + if (hudMessages.Num() == 0) { + return; // nothing to do + } + + // We have a message to display, check if the HUD is ready for it + if (hud == NULL) { + return; // no HUD? + } + + int hasMessage = hud->GetStateInt("HasMessage"); + + if (hasMessage == 1) { + // The HUD is still busy, leave it for the moment being + return; + } + + // greebo: We have a message and the HUD is ready, shove it into the GUI. + hud->SetStateString("MessageText", hudMessages[0]); + hud->HandleNamedEvent("DisplayMessage"); + + // Remove the first string, now that it's been moved into the GUI + hudMessages.RemoveIndex(0); +} + +void idPlayer::UpdateInventoryPickedUpMessages() +{ + if (inventoryPickedUpMessages.Num() == 0) return; // nothing to do + + // We have a message to display, check if the HUD is ready for it + + idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); + + if (invGUI == NULL) + { + DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find inventory HUD, cannot update pickup messages.\r"); + return; // no overlay? + } + + /* + greebo: Commented this out to let new pickup messages overwrite the old ones. + Put this back in to let the GUI display one message after the other. + + int hasMessage = invGUI->GetStateInt("HasInventoryPickUpMessage"); + + if (hasMessage == 1) + { + // The HUD is still busy, leave it for the moment being + return; + }*/ + + // greebo: We have a message and the HUD is ready, shove it into the GUI. + invGUI->SetStateString("InventoryPickUpMessageText", inventoryPickedUpMessages[0]); + invGUI->HandleNamedEvent("DisplayInventoryPickUpMessage"); + + // Remove the first string, now that it's been moved into the GUI + inventoryPickedUpMessages.RemoveIndex(0); +} + +/* +============== +idPlayer::UpdateDeathSkin +============== +*/ +void idPlayer::UpdateDeathSkin( bool state_hitch ) { + if ( !( gameLocal.isMultiplayer || g_testDeath.GetBool() ) ) { + return; + } + if ( health <= 0 ) { + if ( !doingDeathSkin ) { + deathClearContentsTime = spawnArgs.GetInt( "deathSkinTime" ); + doingDeathSkin = true; + renderEntity.noShadow = true; + if ( state_hitch ) { + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f - 2.0f; + } else { + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; + } + UpdateVisuals(); + } + + // wait a bit before switching off the content + if ( deathClearContentsTime && gameLocal.time > deathClearContentsTime ) { + SetCombatContents( false ); + deathClearContentsTime = 0; + } + } else { + renderEntity.noShadow = false; + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = 0.0f; + UpdateVisuals(); + doingDeathSkin = false; + } +} + +/* +============== +idPlayer::StartFxOnBone +============== +*/ +void idPlayer::StartFxOnBone( const char *fx, const char *bone ) { + idVec3 offset; + idMat3 axis; + jointHandle_t jointHandle = GetAnimator()->GetJointHandle( bone ); + + if ( jointHandle == INVALID_JOINT ) { + gameLocal.Printf( "Cannot find bone %s\n", bone ); + return; + } + + if ( GetAnimator()->GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { + offset = GetPhysics()->GetOrigin() + offset * GetPhysics()->GetAxis(); + axis = axis * GetPhysics()->GetAxis(); + } + + idEntityFx::StartFx( fx, &offset, &axis, this, true ); +} + +void idPlayer::UpdateUnderWaterEffects() { + if ( physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD ) { + if (!underWaterEffectsActive) { + StartSound( "snd_airless", SND_CHANNEL_DEMONIC, 0, false, NULL ); + + // Underwater GUI section, allows custom water guis for each water entity etc - Dram + idStr overlay; + idPhysics_Liquid* CurWaterEnt = GetPlayerPhysics()->GetWater(); + if (CurWaterEnt != NULL) { // Get the GUI from the current water entity + idEntity* CurEnt = CurWaterEnt->GetSelf(); + if (CurEnt != NULL) { + overlay = CurEnt->spawnArgs.GetString("underwater_gui"); + } + gameLocal.Printf( "UNDERWATER: After water check overlay is %s\n", overlay.c_str() ); + } + if (overlay.IsEmpty()) { // If the overlay string is empty it has failed to find the GUI on the entity, so give warning + gameLocal.Warning( "UNDERWATER: water check overlay failed, check key/val pairs\n" ); + } + else if (!overlay.IsEmpty()) { + underWaterGUIHandle = CreateOverlay(overlay.c_str(), LAYER_UNDERWATER); + } + underWaterEffectsActive = true; + } + } + else { + if (underWaterEffectsActive) + { + StopSound( SND_CHANNEL_DEMONIC, false ); + if (underWaterGUIHandle != -1) { + DestroyOverlay(underWaterGUIHandle); + underWaterGUIHandle = -1; + } + + // If we were underwater for more than 4 seconds, play the "take breath" sound + if (gameLocal.time > physicsObj.GetSubmerseTime() + 4000) + { + StartSound( "snd_resurface", SND_CHANNEL_VOICE, 0, false, NULL ); + } + + underWaterEffectsActive = false; + } + } +} + +/* +============== +idPlayer::Think + +Called every tic for each player +============== +*/ +void idPlayer::Think( void ) +{ + bool allowAttack = false; + renderEntity_t *headRenderEnt; + UpdatePlayerIcons(); + + // latch button actions + oldButtons = usercmd.buttons; + + // grab out usercmd + usercmd_t oldCmd = usercmd; + usercmd = gameLocal.usercmds[ entityNumber ]; + buttonMask &= usercmd.buttons; + usercmd.buttons &= ~buttonMask; + + // Solarsplace 19th Nov 2010 - Bug tracker id 0002424 + if ( ! (gameLocal.mainMenuExited && ( usercmd.buttons & BUTTON_ATTACK )) ) + { + allowAttack = true; + gameLocal.mainMenuExited = false; + } + + // angua: disable doom3 crouching + if (usercmd.upmove < 0) + { + usercmd.upmove = 0; + } + + // greebo: Check always run + if (cvarSystem->GetCVarBool("in_alwaysRun")) + { + // Always run active, invert the behaviour, user has to hold down button to walk + usercmd.buttons ^= BUTTON_RUN; + } + + if( !AI_PAIN ) + m_bDamagedThisFrame = false; + + if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { + return; + } + + // clear the ik before we do anything else so the skeleton doesn't get updated twice + walkIK.ClearJointMods(); + + // if this is the very first frame of the map, set the delta view angles + // based on the usercmd angles + if ( !spawnAnglesSet && ( gameLocal.GameState() != GAMESTATE_STARTUP ) ) { + spawnAnglesSet = true; + SetViewAngles( spawnAngles ); + oldFlags = usercmd.flags; + } + + if ( gameLocal.inCinematic || influenceActive ) + { + usercmd.forwardmove = 0; + usercmd.rightmove = 0; + usercmd.upmove = 0; + } + + // I'm not sure if this is the best way to do things, since it doesn't yet + // take into account whether the player is swimming/climbing, etc. But it + // should be good enough for now. I'll improve it later. + // -Gildoran + if ( GetImmobilization() & EIM_MOVEMENT ) { + usercmd.forwardmove = 0; + usercmd.rightmove = 0; + } + // Note to self: I should probably be thinking about having some sort of + // flag where the player is kept crouching if that's how they started out. + + // angua: crouch immobilization is handled in EvaluateCrouch now + if ( GetImmobilization() & EIM_JUMP && usercmd.upmove > 0 ) { + usercmd.upmove = 0; + } + + // log movement changes for weapon bobbing effects + if ( usercmd.forwardmove != oldCmd.forwardmove ) { + loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; + currentLoggedAccel++; + acc->time = gameLocal.time; + acc->dir[0] = usercmd.forwardmove - oldCmd.forwardmove; + acc->dir[1] = acc->dir[2] = 0; + } + + if ( usercmd.rightmove != oldCmd.rightmove ) { + loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; + currentLoggedAccel++; + acc->time = gameLocal.time; + acc->dir[1] = usercmd.rightmove - oldCmd.rightmove; + acc->dir[0] = acc->dir[2] = 0; + } + + // freelook centering + if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_MLOOK ) { + centerView.Init( gameLocal.time, 200, viewAngles.pitch, 0 ); + } + + // zooming (greebo: Disabled this due to interference with the spyglass, isn't needed anymore) + /*if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_ZOOM ) { + if ( ( usercmd.buttons & BUTTON_ZOOM ) && weapon.GetEntity() ) { + zoomFov.Init( gameLocal.time, 200.0f, CalcFov( false ), weapon.GetEntity()->GetZoomFov() ); + } else { + zoomFov.Init( gameLocal.time, 200.0f, zoomFov.GetCurrentValue( gameLocal.time ), DefaultFov() ); + } + }*/ + + // if we have an active gui, we will unrotate the view angles as + // we turn the mouse movements into gui events + idUserInterface *gui = ActiveGui(); + if ( gui /*&& gui != focusUI*/ ) { + RouteGuiMouse( gui ); + } + + // set the push velocity on the weapon before running the physics + if ( weapon.GetEntity() ) { + weapon.GetEntity()->SetPushVelocity( physicsObj.GetPushedLinearVelocity() ); + } + + EvaluateControls(); + + EvaluateCrouch(); + + + if ( !af.IsActive() ) { + AdjustBodyAngles(); + CopyJointsFromBodyToHead(); + } + + Move(); + + if ( !g_stopTime.GetBool() ) { + + if ( !noclip && !spectating && ( health > 0 ) && !IsHidden() ) { + TouchTriggers(); + } + + // not done on clients for various reasons. don't do it on server and save the sound channel for other things + /*if ( !gameLocal.isMultiplayer ) { + SetCurrentHeartRate(); + float scale = g_damageScale.GetFloat(); + if ( g_useDynamicProtection.GetBool() && scale < 1.0f && gameLocal.time - lastDmgTime > 500 ) { + if ( scale < 1.0f ) { + scale += 0.05f; + } + if ( scale > 1.0f ) { + scale = 1.0f; + } + g_damageScale.SetFloat( scale ); + } + }*/ + +#if 0 + // update GUIs, Items, and character interactions + UpdateFocus(); +#endif + + UpdateLocation(); + + // update player script + UpdateScript(); + + // service animations + if ( !spectating && !af.IsActive() && !gameLocal.inCinematic ) { + // Update the button state, this calls PerformKeyRelease() if a button has been released + m_ButtonStateTracker.Update(); + + UpdateConditions(); + + UpdateAnimState(); + CheckBlink(); + } + + // clear out our pain flag so we can tell if we recieve any damage between now and the next time we think + AI_PAIN = false; + } + + // calculate the exact bobbed view position, which is used to + // position the view weapon, among other things + CalculateFirstPersonView(); + + // this may use firstPersonView, or a thirdPerson / camera view + CalculateRenderView(); + + PerformFrobCheck(); + + // greebo: Close any opened inventory maps when releasing the attack button (#2460) + if (m_ActiveInventoryMapEnt.GetEntity() != NULL && (oldButtons & BUTTON_ATTACK) && !(usercmd.buttons & BUTTON_ATTACK)) + { + ClearActiveInventoryMap(); + + // Disallow attacks to avoid triggering the weapon immediately after closing the map + allowAttack = false; + } + + // Check if we just hit the attack button + idEntity* frobbedEnt = m_FrobEntity.GetEntity(); + + // Solarsplace: allowAttack - bug fix for #2424 + if (frobbedEnt != NULL && usercmd.buttons & BUTTON_ATTACK && !(oldButtons & BUTTON_ATTACK) && allowAttack) + { + frobbedEnt->AttackAction(this); + } + +/* + // TODO: remove this because it is just to determine how to fill out the renderstructure. + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("RenderViewId: %u\r", renderView->viewID); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("x: %u y: %u w: %u h: %u\r", renderView->x, renderView->y, renderView->width, renderView->height); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("FovX: %f FovY: %f\r", renderView->fov_x, renderView->fov_y); + DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "vieworg", renderView->vieworg); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("cramZNear: %u forceUpdate: %u\r", renderView->cramZNear, renderView->forceUpdate); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("time: %u\r", renderView->time); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("time: %u\r", renderView->globalMaterial); + for(i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++) + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Param[%u]: %f\r", i, renderView->shaderParms[i]); +*/ + if ( spectating ) { + UpdateSpectating(); + } else if ( health > 0 && allowAttack) { + UpdateWeapon(); + } + + UpdateAir(); + + // greebo: update underwater overlay and sounds + UpdateUnderWaterEffects(); + + UpdateHUD(); + + UpdatePowerUps(); + + UpdateDeathSkin( false ); + + if ( gameLocal.isMultiplayer ) { + DrawPlayerIcons(); + } + + if ( head.GetEntity() ) { + headRenderEnt = head.GetEntity()->GetRenderEntity(); + } else { + headRenderEnt = NULL; + } + + if ( headRenderEnt ) { + if ( influenceSkin ) { + headRenderEnt->customSkin = influenceSkin; + } else { + headRenderEnt->customSkin = NULL; + } + } + + if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() ) { + renderEntity.suppressShadowInViewID = 0; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInViewID = 0; + } + } else { + renderEntity.suppressShadowInViewID = entityNumber+1; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInViewID = entityNumber+1; + } + } + // never cast shadows from our first-person muzzle flashes + renderEntity.suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; + } + + if ( !g_stopTime.GetBool() ) { + UpdateAnimation(); + + Present(); + + UpdateDamageEffects(); + + LinkCombat(); + + playerView.CalculateShake(); + } + + if ( !( thinkFlags & TH_THINK ) ) { + gameLocal.Printf( "player %d not thinking?\n", entityNumber ); + } + + if ( g_showEnemies.GetBool() ) { + idActor *ent; + int num = 0; + for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + gameLocal.Printf( "enemy (%d)'%s'\n", ent->entityNumber, ent->name.c_str() ); + gameRenderWorld->DebugBounds( colorRed, ent->GetPhysics()->GetBounds().Expand( 2 ), ent->GetPhysics()->GetOrigin() ); + num++; + } + gameLocal.Printf( "%d: enemies\n", num ); + } + + if (cv_pm_show_waterlevel.GetBool()) + { + idStr waterStr; + switch (physicsObj.GetWaterLevel()) + { + case WATERLEVEL_NONE: waterStr = "WATERLEVEL: NONE"; break; + case WATERLEVEL_FEET: waterStr = "WATERLEVEL: FEET"; break; + case WATERLEVEL_WAIST: waterStr = "WATERLEVEL: WAIST"; break; + case WATERLEVEL_HEAD: waterStr = "WATERLEVEL: HEAD"; break; + default: waterStr = "WATERLEVEL: ???"; break; + }; + gameRenderWorld->DrawText(waterStr.c_str(), GetEyePosition() + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); + } + + // determine if portal sky is in pvs + gameLocal.portalSkyActive = gameLocal.pvs.CheckAreasForPortalSky( gameLocal.GetPlayerPVS(), GetPhysics()->GetOrigin() ); +} + +/* +================= +idPlayer::RouteGuiMouse +================= +*/ +void idPlayer::RouteGuiMouse( idUserInterface *gui ) { + sysEvent_t ev; + const char *command; + + /*if ( gui == m_overlays.findInteractive() ) { + // Ensure that gui overlays are always able to execute commands, + // even if the player isn't moving the mouse. + ev = sys->GenerateMouseMoveEvent( usercmd.mx - oldMouseX, usercmd.my - oldMouseY ); + command = gui->HandleEvent( &ev, gameLocal.time ); + HandleGuiCommands( this, command ); + oldMouseX = usercmd.mx; + oldMouseY = usercmd.my; + }*/ + + if ( usercmd.mx != oldMouseX || usercmd.my != oldMouseY ) { + ev = sys->GenerateMouseMoveEvent( usercmd.mx - oldMouseX, usercmd.my - oldMouseY ); + command = gui->HandleEvent( &ev, gameLocal.time ); + oldMouseX = usercmd.mx; + oldMouseY = usercmd.my; + } +} + +/* +================== +idPlayer::LookAtKiller +================== +*/ +void idPlayer::LookAtKiller( idEntity *inflictor, idEntity *attacker ) { + idVec3 dir; + + if ( attacker && attacker != this ) { + dir = attacker->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + } else if ( inflictor && inflictor != this ) { + dir = inflictor->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + } else { + dir = viewAxis[ 0 ]; + } + + idAngles ang( 0, dir.ToYaw(), 0 ); + SetViewAngles( ang ); +} + +/* +============== +idPlayer::Kill +============== +*/ +void idPlayer::Kill( bool delayRespawn, bool nodamage ) { + if ( spectating ) { + SpectateFreeFly( false ); + } else if ( health > 0 ) { + godmode = false; + if ( nodamage ) { + ServerSpectate( true ); + forceRespawn = true; + } else { + Damage( this, this, vec3_origin, "damage_suicide", 1.0f, INVALID_JOINT ); + if ( delayRespawn ) { + forceRespawn = false; + int delay = spawnArgs.GetInt( "respawn_delay" ); + minRespawnTime = gameLocal.time + SEC2MS( delay ); + maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; + } + } + } +} + +/* +================== +idPlayer::Killed +================== +*/ +void idPlayer::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + float delay; + + assert( !gameLocal.isClient ); + + // stop taking knockback once dead + fl.noknockback = true; + if ( health < -999 ) { + health = -999; + } + + if ( AI_DEAD ) { + AI_PAIN = true; + return; + } + + heartInfo.Init( 0, 0, 0, BASE_HEARTRATE ); + AdjustHeartRate( DEAD_HEARTRATE, 10.0f, 0.0f, true ); + + AI_DEAD = true; + + // greebo: Before posting mission failed and going to ragdoll, check for custom death script + if (gameLocal.world != NULL && gameLocal.world->spawnArgs.GetInt("custom_death_delay") > 0) + { + // greebo: Still call the ownerdied method to cleanup the weapon script state + weapon.GetEntity()->OwnerDied(); + + // Run the death event in a few seconds + PostEventMS(&EV_Player_CustomDeath, SEC2MS(gameLocal.world->spawnArgs.GetInt("custom_death_delay"))); + return; // stop death processing here + } + + this->PostEventMS( &EV_Player_MissionFailed, spawnArgs.GetInt("death_transit_time", "2000") ); + + SetAnimState( ANIMCHANNEL_LEGS, "Legs_Death", 4 ); + SetAnimState( ANIMCHANNEL_TORSO, "Torso_Death", 4 ); + SetWaitState( "" ); + + animator.ClearAllJoints(); + +// NOTE: RespawnTime not used anymore in TDM except maybe for third person death later? + if ( StartRagdoll() ) { + pm_modelView.SetInteger( 0 ); + minRespawnTime = gameLocal.time + RAGDOLL_DEATH_TIME; + maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; + } else { + // don't allow respawn until the death anim is done + // g_forcerespawn may force spawning at some later time + delay = spawnArgs.GetFloat( "respawn_delay" ); + minRespawnTime = gameLocal.time + SEC2MS( delay ); + maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; + } + + physicsObj.SetMovementType( PM_DEAD ); + + // greebo: Prevent all movement, weapon and item usage when dead + SetImmobilization("death", EIM_ALL); + + // Play the death sound on the voice channel + idStr deathSound = (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD) ? "snd_death_liquid" : "snd_death"; + StartSound( deathSound, SND_CHANNEL_VOICE, 0, false, NULL ); + + StopSound( SND_CHANNEL_BODY2, false ); + + fl.takedamage = true; // can still be gibbed + + // get rid of weapon + weapon.GetEntity()->OwnerDied(); + + // drop the weapon as an item + DropWeapon( true ); + + if ( !g_testDeath.GetBool() ) { + LookAtKiller( inflictor, attacker ); + } + + if ( gameLocal.isMultiplayer || g_testDeath.GetBool() ) { + idPlayer *killer = NULL; + // no gibbing in MP. Event_Gib will early out in MP + if ( attacker->IsType( idPlayer::Type ) ) { + killer = static_cast(attacker); + if ( health < -20 ) { + gibDeath = true; + gibsDir = dir; + gibsLaunched = false; + } + } + gameLocal.mpGame.PlayerDeath( this, killer, isTelefragged ); + } else + { + physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + { + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + } + } + + UpdateVisuals(); + + isChatting = false; +} + +/* +===================== +idPlayer::GetAIAimTargets + +Returns positions for the AI to aim at. +===================== +*/ +void idPlayer::GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ) { + idVec3 offset; + idMat3 axis; + idVec3 origin; + + origin = lastSightPos - physicsObj.GetOrigin(); + + GetJointWorldTransform( chestJoint, gameLocal.time, offset, axis ); + headPos = offset + origin; + + GetJointWorldTransform( headJoint, gameLocal.time, offset, axis ); + chestPos = offset + origin; +} + +/* +================ +idPlayer::DamageFeedback + +callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. +================ +*/ +void idPlayer::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { + assert( !gameLocal.isClient ); + damage = static_cast(damage * PowerUpModifier( BERSERK )); + if ( damage && ( victim != this ) && victim->IsType( idActor::Type ) ) { + SetLastHitTime( gameLocal.time ); + } + + // greebo: Update the mission statistics, we've damaged another actor + gameLocal.m_MissionData->AIDamagedByPlayer(damage); +} + +/* +================= +idPlayer::CalcDamagePoints + +Calculates how many health and armor points will be inflicted, but +doesn't actually do anything with them. This is used to tell when an attack +would have killed the player, possibly allowing a "saving throw" +================= +*/ +void idPlayer::CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef, + const float damageScale, const int location, int *health, int *armor ) { + int damage; + int armorSave; + + damageDef->GetInt( "damage", "20", damage ); + damage = GetDamageForLocation( damage, location ); + + idPlayer *player = attacker->IsType( idPlayer::Type ) ? static_cast(attacker) : NULL; + if ( !gameLocal.isMultiplayer ) { + if ( inflictor != gameLocal.world ) { + switch ( g_skill.GetInteger() ) { + case 0: + damage *= 0.80f; + if ( damage < 1 ) { + damage = 1; + } + break; + case 2: + damage *= 1.70f; + break; + case 3: + damage *= 3.5f; + break; + default: + break; + } + } + } + + damage *= damageScale; + + // always give half damage if hurting self + if ( attacker == this ) { + if ( gameLocal.isMultiplayer ) { + // only do this in mp so single player plasma and rocket splash is very dangerous in close quarters + damage *= damageDef->GetFloat( "selfDamageScale", "0.5" ); + } else { + damage *= damageDef->GetFloat( "selfDamageScale", "1" ); + } + } + + // check for completely getting out of the damage + if ( !damageDef->GetBool( "noGod" ) ) { + // check for godmode + if ( godmode ) { + damage = 0; + } + } + + // inform the attacker that they hit someone + attacker->DamageFeedback( this, inflictor, damage ); + + // save some from armor + if ( !damageDef->GetBool( "noArmor" ) ) { + /*float armor_protection; + + armor_protection = ( gameLocal.isMultiplayer ) ? g_armorProtectionMP.GetFloat() : g_armorProtection.GetFloat(); + + armorSave = ceil( damage * armor_protection ); + if ( armorSave >= inventory.armor ) { + armorSave = inventory.armor; + }*/ + armorSave = 0; + + if ( !damage ) { + armorSave = 0; + } else if ( armorSave >= damage ) { + armorSave = damage - 1; + damage = 1; + } else { + damage -= armorSave; + } + } else { + armorSave = 0; + } + + // check for team damage + if ( gameLocal.gameType == GAME_TDM + && !gameLocal.serverInfo.GetBool( "si_teamDamage" ) + && !damageDef->GetBool( "noTeam" ) + && player + && player != this // you get self damage no matter what + && player->team == team ) { + damage = 0; + } + + *health = damage; + *armor = armorSave; +} + +/* +============ +Damage + +this entity that is being damaged +inflictor entity that is causing the damage +attacker entity that caused the inflictor to damage targ + example: this=monster, inflictor=rocket, attacker=player + +dir direction of the attack for knockback in global space + +damageDef an idDict with all the options for damage effects + +inflictor, attacker, dir, and point can be NULL for environmental effects +============ +*/ +void idPlayer::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision ) +{ + idVec3 kick; + int damage; + int armorSave; + int knockback; + idVec3 damage_from; + idVec3 localDamageVector; + float attackerPushScale; + + // damage is only processed on server + if ( gameLocal.isClient ) { + return; + } + + if ( !fl.takedamage || noclip || spectating || gameLocal.inCinematic ) { + return; + } + + if ( !inflictor ) { + inflictor = gameLocal.world; + } + if ( !attacker ) { + attacker = gameLocal.world; + } + + if ( attacker->IsType( idAI::Type ) ) { + // don't take damage from monsters during influences + if ( influenceActive != 0 ) { + return; + } + } + + const idDeclEntityDef *damageDef = gameLocal.FindEntityDef( damageDefName, false ); + if ( !damageDef ) { + gameLocal.Warning( "Unknown damageDef '%s'", damageDefName ); + return; + } + + if ( damageDef->dict.GetBool( "ignore_player" ) ) { + return; + } + + CalcDamagePoints( inflictor, attacker, &damageDef->dict, damageScale, location, &damage, &armorSave ); + + // determine knockback + damageDef->dict.GetInt( "knockback", "20", knockback ); + + if ( knockback != 0 && !fl.noknockback ) { + if ( attacker == this ) { + damageDef->dict.GetFloat( "attackerPushScale", "0", attackerPushScale ); + } else { + attackerPushScale = 1.0f; + } + + kick = dir; + kick.Normalize(); + kick *= g_knockback.GetFloat() * knockback * attackerPushScale / 200.0f; + physicsObj.SetLinearVelocity( physicsObj.GetLinearVelocity() + kick ); + + // set the timer so that the player can't cancel out the movement immediately + physicsObj.SetKnockBack( idMath::ClampInt( 50, 200, knockback * 2 ) ); + } + + // give feedback on the player view and audibly when armor is helping + /*if ( armorSave ) { + inventory.armor -= armorSave; + + if ( gameLocal.time > lastArmorPulse + 200 ) { + StartSound( "snd_hitArmor", SND_CHANNEL_ITEM, 0, false, NULL ); + } + lastArmorPulse = gameLocal.time; + }*/ + + if ( damageDef->dict.GetBool( "burn" ) ) + { + StartSound( "snd_burn", SND_CHANNEL_BODY3, 0, false, NULL ); + } + + if ( g_debugDamage.GetInteger() ) { + gameLocal.Printf( "client:%i health:%i damage:%i armor:%i\n", + entityNumber, health, damage, armorSave ); + } + + // move the world direction vector to local coordinates + damage_from = dir; + damage_from.Normalize(); + + viewAxis.ProjectVector( damage_from, localDamageVector ); + + // add to the damage inflicted on a player this frame + // the total will be turned into screen blends and view angle kicks + // at the end of the frame + if ( health > 0 ) { + playerView.DamageImpulse( localDamageVector, &damageDef->dict ); + } + + // do the damage + if ( damage > 0 ) + { + + if ( !gameLocal.isMultiplayer ) + { + float scale = g_damageScale.GetFloat(); + /*if ( g_useDynamicProtection.GetBool() && g_skill.GetInteger() < 2 ) { + if ( gameLocal.time > lastDmgTime + 500 && scale > 0.25f ) { + scale -= 0.05f; + g_damageScale.SetFloat( scale ); + } + }*/ + + if ( scale > 0.0f ) + { + damage *= scale; + } + } + + if ( damage < 1 ) + { + damage = 1; + } + +// int oldHealth = health; + health -= damage; + + // greebo: Update mission statistics, we've taken damage + gameLocal.m_MissionData->PlayerDamaged(damage); + + // ishtvan bugfix: set m_bDamagedThisFrame here, rather than in ::Think + // compare against pain threshold so that things like low-grade poison gas don't prevent player actions + if ( damage > pain_threshold ) + m_bDamagedThisFrame = true; + + if ( health <= 0 ) + { + + if ( health < -999 ) + { + health = -999; + } + + isTelefragged = damageDef->dict.GetBool( "telefrag" ); + + lastDmgTime = gameLocal.time; + Killed( inflictor, attacker, damage, dir, location ); + + } else + { + // force a blink + blink_time = 0; + + if (!damageDef->dict.GetBool( "no_pain" )) + { + // let the anim script know we took damage + AI_PAIN = Pain( inflictor, attacker, damage, dir, location, &damageDef->dict ); + } + + // FIX: if drowning, stop pain SFX and play drown SFX on voice channel + if ( damageDef->dict.GetBool( "no_air" ) ) + { + if ( !armorSave && health > 0 ) + { + StopSound( SND_CHANNEL_VOICE, false ); + StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); + } + } + + if ( !g_testDeath.GetBool() ) + { + lastDmgTime = gameLocal.time; + } + } + } else + { + // don't accumulate impulses + if ( af.IsLoaded() ) + { + // clear impacts + af.Rest(); + + // physics is turned off by calling af.Rest() + BecomeActive( TH_PHYSICS ); + } + } + + lastDamageDef = damageDef->Index(); + lastDamageDir = damage_from; + lastDamageLocation = location; +} + +/* +=========== +idPlayer::Teleport +============ +*/ +void idPlayer::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { + idVec3 org; + + if ( weapon.GetEntity() ) { + weapon.GetEntity()->LowerWeapon(); + } + + SetOrigin( origin + idVec3( 0, 0, CM_CLIP_EPSILON ) ); + if ( !gameLocal.isMultiplayer && GetFloorPos( 16.0f, org ) ) { + SetOrigin( org ); + } + + // clear the ik heights so model doesn't appear in the wrong place + walkIK.EnableAll(); + + GetPhysics()->SetLinearVelocity( vec3_origin ); + + SetViewAngles( angles ); + + legsYaw = 0.0f; + idealLegsYaw = 0.0f; + oldViewYaw = viewAngles.yaw; + + if ( gameLocal.isMultiplayer ) { + playerView.Flash( colorWhite, 140 ); + } + + UpdateVisuals(); + + teleportEntity = destination; + + if ( !gameLocal.isClient && !noclip ) { + if ( gameLocal.isMultiplayer ) { + // kill anything at the new position or mark for kill depending on immediate or delayed teleport + gameLocal.KillBox( this, destination != NULL ); + } else { + // kill anything at the new position + gameLocal.KillBox( this, true ); + } + } +} + +/* +==================== +idPlayer::SetPrivateCameraView +==================== +*/ +void idPlayer::SetPrivateCameraView( idCamera *camView ) { + privateCameraView = camView; + if ( camView ) { + StopFiring(); + Hide(); + } else { + if ( !spectating ) { + Show(); + } + } +} + +/* +==================== +idPlayer::DefaultFov + +Returns the base FOV +==================== +*/ +float idPlayer::DefaultFov( void ) const { + float fov; + + fov = g_fov.GetFloat(); + if ( gameLocal.isMultiplayer ) { + if ( fov < 90.0f ) { + return 90.0f; + } else if ( fov > 110.0f ) { + return 110.0f; + } + } + + return fov; +} + +/* +==================== +idPlayer::CalcFov + +Fixed fov at intermissions, otherwise account for fov variable and zooms. +==================== +*/ +float idPlayer::CalcFov( bool honorZoom ) { + float fov; + float defaultFov = DefaultFov(); + + if ( fxFov ) { + return defaultFov + 10.0f + cos( ( gameLocal.time + 2000 ) * 0.01 ) * 10.0f; + } + + if ( influenceFov ) { + return influenceFov; + } + + // prevent FOV from zooming if the player is holding an object + if( gameLocal.m_Grabber->GetSelected() ) { + return defaultFov; + } + + // Check if a transition is still ongoing + bool zoomDone = zoomFov.IsDone(gameLocal.time); + float curZoomFov = zoomFov.GetCurrentValue(gameLocal.time); + + // Take the interpolation value, if the zoom is enabled, take the default otherwise + fov = (zoomFov.Enabled()) ? curZoomFov : defaultFov; + + // Check if we need the zoom interpolation anymore + if (zoomFov.Enabled() && zoomDone && curZoomFov == defaultFov) + { + // Zoom is done and is equal to default fov, so we no longer need it + zoomFov.SetEnabled(false); + fov = DefaultFov(); + } + + // bound normal viewsize + if ( fov < 1 ) { + fov = 1; + } else if ( fov > 179 ) { + fov = 179; + } + + return fov; +} + +/* +============== +idPlayer::GunTurningOffset + +generate a rotational offset for the gun based on the view angle +history in loggedViewAngles +============== +*/ +idAngles idPlayer::GunTurningOffset( void ) { + idAngles a; + + a.Zero(); + + if ( gameLocal.framenum < NUM_LOGGED_VIEW_ANGLES ) { + return a; + } + + idAngles current = loggedViewAngles[ gameLocal.framenum & (NUM_LOGGED_VIEW_ANGLES-1) ]; + + idAngles av, base; + int weaponAngleOffsetAverages; + float weaponAngleOffsetScale, weaponAngleOffsetMax; + + weapon.GetEntity()->GetWeaponAngleOffsets( &weaponAngleOffsetAverages, &weaponAngleOffsetScale, &weaponAngleOffsetMax ); + + av = current; + + // calcualte this so the wrap arounds work properly + for ( int j = 1 ; j < weaponAngleOffsetAverages ; j++ ) { + idAngles a2 = loggedViewAngles[ ( gameLocal.framenum - j ) & (NUM_LOGGED_VIEW_ANGLES-1) ]; + + idAngles delta = a2 - current; + + if ( delta[1] > 180 ) { + delta[1] -= 360; + } else if ( delta[1] < -180 ) { + delta[1] += 360; + } + + av += delta * ( 1.0f / weaponAngleOffsetAverages ); + } + + a = ( av - current ) * weaponAngleOffsetScale; + + for ( int i = 0 ; i < 3 ; i++ ) { + if ( a[i] < -weaponAngleOffsetMax ) { + a[i] = -weaponAngleOffsetMax; + } else if ( a[i] > weaponAngleOffsetMax ) { + a[i] = weaponAngleOffsetMax; + } + } + + return a; +} + +/* +============== +idPlayer::GunAcceleratingOffset + +generate a positional offset for the gun based on the movement +history in loggedAccelerations +============== +*/ +idVec3 idPlayer::GunAcceleratingOffset( void ) { + idVec3 ofs; + + float weaponOffsetTime, weaponOffsetScale; + + ofs.Zero(); + + weapon.GetEntity()->GetWeaponTimeOffsets( &weaponOffsetTime, &weaponOffsetScale ); + + int stop = currentLoggedAccel - NUM_LOGGED_ACCELS; + if ( stop < 0 ) { + stop = 0; + } + for ( int i = currentLoggedAccel-1 ; i > stop ; i-- ) { + loggedAccel_t *acc = &loggedAccel[i&(NUM_LOGGED_ACCELS-1)]; + + float f; + float t = gameLocal.time - acc->time; + if ( t >= weaponOffsetTime ) { + break; // remainder are too old to care about + } + + f = t / weaponOffsetTime; + f = ( cos( f * 2.0f * idMath::PI ) - 1.0f ) * 0.5f; + ofs += f * weaponOffsetScale * acc->dir; + } + + return ofs; +} + +/* +============== +idPlayer::CalculateViewWeaponPos + +Calculate the bobbing position of the view weapon +============== +*/ +void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { + float scale; + float fracsin1; + float fracsin2; + float fracsin3; + idAngles angles; + int delta; + + // CalculateRenderView must have been called first + const idVec3 &viewOrigin = firstPersonViewOrigin; + const idMat3 &viewAxis = firstPersonViewAxis; + + // these cvars are just for hand tweaking before moving a value to the weapon def + idVec3 gunpos( g_gun_x.GetFloat(), g_gun_y.GetFloat(), g_gun_z.GetFloat() ); + + // as the player changes direction, the gun will take a small lag + idVec3 gunOfs = GunAcceleratingOffset(); + origin = viewOrigin + ( gunpos + gunOfs ) * viewAxis; + + // on odd legs, invert some angles + if ( bobCycle & 128 ) { + scale = -xyspeed; + } else { + scale = xyspeed; + } + + // gun angles from bobbing + angles.roll = scale * bobfracsin * 0.005f; + angles.yaw = scale * bobfracsin * 0.01f; + angles.pitch = xyspeed * bobfracsin * 0.005f; + + // gun angles from turning + if ( gameLocal.isMultiplayer ) { + idAngles offset = GunTurningOffset(); + offset *= g_mpWeaponAngleScale.GetFloat(); + angles += offset; + } else { + angles += GunTurningOffset(); + } + + idVec3 gravity = physicsObj.GetGravityNormal(); + + // drop the weapon when landing after a jump / fall + delta = gameLocal.time - landTime; + if ( delta < LAND_DEFLECT_TIME ) { + origin -= gravity * ( landChange*0.25f * delta / LAND_DEFLECT_TIME ); + } else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) { + origin -= gravity * ( landChange*0.25f * (LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta) / LAND_RETURN_TIME ); + } + + // speed sensitive idle drift + // Dram: Changed so that each axis has it's own fracsin. Now they move independantly of each other + scale = xyspeed + 40.0f; + fracsin1 = scale * sin( MS2SEC( gameLocal.time * 0.42 ) ) * 0.006f; + fracsin2 = scale * sin( MS2SEC( gameLocal.time * 1.63 ) ) * 0.01f; + fracsin3 = scale * sin( MS2SEC( gameLocal.time * 2 ) ) * 0.01f; + angles.roll += fracsin1; + angles.yaw += fracsin2; + angles.pitch += fracsin3; + + axis = angles.ToMat3() * viewAxis; +} + +/* +=============== +idPlayer::OffsetThirdPersonView +=============== +*/ +void idPlayer::OffsetThirdPersonView( float angle, float range, float height, bool clip ) { + idVec3 view; + idVec3 focusAngles; + trace_t trace; + idVec3 focusPoint; + float focusDist; + float forwardScale, sideScale; + idVec3 origin; + idAngles angles; + idMat3 axis; + idBounds bounds; + + angles = viewAngles; + GetViewPos( origin, axis ); + + if ( angle ) { + angles.pitch = 0.0f; + } + + if ( angles.pitch > 45.0f ) { + angles.pitch = 45.0f; // don't go too far overhead + } + + focusPoint = origin + angles.ToForward() * THIRD_PERSON_FOCUS_DISTANCE; + focusPoint.z += height; + view = origin; + view.z += 8 + height; + + angles.pitch *= 0.5f; + renderView->viewaxis = angles.ToMat3() * physicsObj.GetGravityAxis(); + + idMath::SinCos( DEG2RAD( angle ), sideScale, forwardScale ); + view -= range * forwardScale * renderView->viewaxis[ 0 ]; + view += range * sideScale * renderView->viewaxis[ 1 ]; + + if ( clip ) { + // trace a ray from the origin to the viewpoint to make sure the view isn't + // in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything + bounds = idBounds( idVec3( -4, -4, -4 ), idVec3( 4, 4, 4 ) ); + gameLocal.clip.TraceBounds( trace, origin, view, bounds, MASK_SOLID, this ); + if ( trace.fraction != 1.0f ) { + view = trace.endpos; + view.z += ( 1.0f - trace.fraction ) * 32.0f; + + // try another trace to this position, because a tunnel may have the ceiling + // close enough that this is poking out + gameLocal.clip.TraceBounds( trace, origin, view, bounds, MASK_SOLID, this ); + view = trace.endpos; + } + } + + // select pitch to look at focus point from vieword + focusPoint -= view; + focusDist = idMath::Sqrt( focusPoint[0] * focusPoint[0] + focusPoint[1] * focusPoint[1] ); + if ( focusDist < 1.0f ) { + focusDist = 1.0f; // should never happen + } + + angles.pitch = - RAD2DEG( atan2( focusPoint.z, focusDist ) ); + angles.yaw -= angle; + + renderView->vieworg = view; + renderView->viewaxis = angles.ToMat3() * physicsObj.GetGravityAxis(); + renderView->viewID = 0; +} + +/* +=============== +idPlayer::GetEyePosition +=============== +*/ +idVec3 idPlayer::GetEyePosition( void ) const { + idVec3 org; + + // use the smoothed origin if spectating another player in multiplayer + if ( gameLocal.isClient && entityNumber != gameLocal.localClientNum ) { + org = smoothedOrigin; + } else { + org = GetPhysics()->GetOrigin(); + } + + /*! + * Lean Mod + * @author sophisticatedZombie (DH) + * Move eye position due to leaning + * angua: need to check whether physics type is correct, dead player uses AF physics + */ + idPhysics* physics = GetPhysics(); + if (physics->IsType(idPhysics_Player::Type)) + { + org += static_cast(physics)->GetViewLeanTranslation(); + } + + // This was in SDK untouched + return org + ( GetPhysics()->GetGravityNormal() * -eyeOffset.z ); +} + +/* +=============== +idPlayer::GetViewPos +=============== +*/ +void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { + idAngles angles; + + // if dead, fix the angle and don't add any kick + if ( health <= 0 ) { + angles.yaw = viewAngles.yaw; + angles.roll = 40; + angles.pitch = -15; + axis = angles.ToMat3(); + origin = GetEyePosition(); + } else { + origin = GetEyePosition() + viewBob; + angles = viewAngles + viewBobAngles + physicsObj.GetViewLeanAngles() + playerView.AngleOffset(); + + axis = angles.ToMat3() * physicsObj.GetGravityAxis(); + + // adjust the origin based on the camera nodal distance (eye distance from neck) + origin += physicsObj.GetGravityNormal() * g_viewNodalZ.GetFloat(); + origin += axis[0] * g_viewNodalX.GetFloat() + axis[2] * g_viewNodalZ.GetFloat(); + } +} + +/* +=============== +idPlayer::CalculateFirstPersonView +=============== +*/ +void idPlayer::CalculateFirstPersonView( void ) +{ + idPhysics* physics = GetPhysics(); + + if ( ( pm_modelView.GetInteger() == 1 ) || ( ( pm_modelView.GetInteger() == 2 ) && ( health <= 0 ) ) ) + { + // Displays the view from the point of view of the "camera" joint in the player model + + idMat3 axis; + idVec3 origin; + idAngles ang = viewBobAngles + playerView.AngleOffset(); + + /*! + * Lean mod: + * @author: sophisticatedZombie + */ + if (physics->IsType(idPhysics_Player::Type)) + { + ang += static_cast(physics)->GetViewLeanAngles(); + } + + ang.yaw += viewAxis[ 0 ].ToYaw(); + + jointHandle_t joint = animator.GetJointHandle( "camera" ); + animator.GetJointTransform( joint, gameLocal.time, origin, axis ); + firstPersonViewOrigin = ( origin + modelOffset ) * ( viewAxis * physicsObj.GetGravityAxis() ) + physicsObj.GetOrigin() + viewBob + physicsObj.GetViewLeanTranslation(); + firstPersonViewAxis = axis * ang.ToMat3() * physicsObj.GetGravityAxis(); + } else + { + // offset for local bobbing and kicks + GetViewPos( firstPersonViewOrigin, firstPersonViewAxis ); +#if 0 + // shakefrom sound stuff only happens in first person + firstPersonViewAxis = firstPersonViewAxis * playerView.ShakeAxis(); +#endif + } + + // Set the listener location (on the other side of a door if door leaning) + if (physics->IsType(idPhysics_Player::Type) && + static_cast(physics)->IsDoorLeaning() && + !gameLocal.inCinematic) + { + SetListenerLoc( m_DoorListenLoc ); + } + else + { + SetListenerLoc( firstPersonViewOrigin ); + } +} + +/* +================== +idPlayer::GetRenderView + +Returns the renderView that was calculated for this tic +================== +*/ +renderView_t *idPlayer::GetRenderView( void ) { + return renderView; +} + +/* +================== +idPlayer::CalculateRenderView + +create the renderView for the current tic +================== +*/ +void idPlayer::CalculateRenderView( void ) { + int i; + float range; + + if ( !renderView ) { + renderView = new renderView_t; + } + memset( renderView, 0, sizeof( *renderView ) ); + + // copy global shader parms + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + renderView->shaderParms[ i ] = gameLocal.globalShaderParms[ i ]; + } + renderView->globalMaterial = gameLocal.GetGlobalMaterial(); + renderView->time = gameLocal.time; + + // calculate size of 3D view + renderView->x = 0; + renderView->y = 0; + renderView->width = SCREEN_WIDTH; + renderView->height = SCREEN_HEIGHT; + renderView->viewID = 0; + + // check if we should be drawing from a camera's POV + if ( !noclip && (gameLocal.GetCamera() || privateCameraView) ) { + // get origin, axis, and fov + if ( privateCameraView ) { + privateCameraView->GetViewParms( renderView ); + } else { + gameLocal.GetCamera()->GetViewParms( renderView ); + } + } else { + if ( g_stopTime.GetBool() ) { + renderView->vieworg = firstPersonViewOrigin; + renderView->viewaxis = firstPersonViewAxis; + + if ( !pm_thirdPerson.GetBool() ) { + // set the viewID to the clientNum + 1, so we can suppress the right player bodies and + // allow the right player view weapons + renderView->viewID = entityNumber + 1; + } + } else if ( pm_thirdPerson.GetBool() ) { + OffsetThirdPersonView( pm_thirdPersonAngle.GetFloat(), pm_thirdPersonRange.GetFloat(), pm_thirdPersonHeight.GetFloat(), pm_thirdPersonClip.GetBool() ); + } else if ( pm_thirdPersonDeath.GetBool() ) { + range = gameLocal.time < minRespawnTime ? ( gameLocal.time + RAGDOLL_DEATH_TIME - minRespawnTime ) * ( 120.0f / RAGDOLL_DEATH_TIME ) : 120.0f; + OffsetThirdPersonView( 0.0f, 20.0f + range, 0.0f, false ); + } else { + renderView->vieworg = firstPersonViewOrigin; + renderView->viewaxis = firstPersonViewAxis; + + // set the viewID to the clientNum + 1, so we can suppress the right player bodies and + // allow the right player view weapons + renderView->viewID = entityNumber + 1; + } + + // field of view + gameLocal.CalcFov( CalcFov( true ), renderView->fov_x, renderView->fov_y ); + } + + if ( renderView->fov_y == 0 ) { + common->Error( "renderView->fov_y == 0" ); + } + + if ( g_showviewpos.GetBool() ) { + gameLocal.Printf( "%s : %s\n", renderView->vieworg.ToString(), renderView->viewaxis.ToAngles().ToString() ); + } +} + +/* +============= +idPlayer::AddProjectilesFired +============= +*/ +void idPlayer::AddProjectilesFired( int count ) { + numProjectilesFired += count; +} + +/* +============= +idPlayer::AddProjectileHites +============= +*/ +void idPlayer::AddProjectileHits( int count ) { + numProjectileHits += count; +} + +/* +============= +idPlayer::SetLastHitTime +============= +*/ +void idPlayer::SetLastHitTime( int time ) { + idPlayer *aimed = NULL; + + if ( time && lastHitTime != time ) { + lastHitToggle ^= 1; + } + lastHitTime = time; + if ( !time ) { + // level start and inits + return; + } + if ( gameLocal.isMultiplayer && ( time - lastSndHitTime ) > 10 ) { + lastSndHitTime = time; + StartSound( "snd_hit_feedback", SND_CHANNEL_ANY, SSF_PRIVATE_SOUND, false, NULL ); + } + if ( cursor ) { + cursor->HandleNamedEvent( "hitTime" ); + } + if ( hud ) { + if ( MPAim != -1 ) { + if ( gameLocal.entities[ MPAim ] && gameLocal.entities[ MPAim ]->IsType( idPlayer::Type ) ) { + aimed = static_cast< idPlayer * >( gameLocal.entities[ MPAim ] ); + } + assert( aimed ); + // full highlight, no fade till loosing aim + hud->SetStateString( "aim_text", gameLocal.userInfo[ MPAim ].GetString( "ui_name" ) ); + if ( aimed ) { + hud->SetStateFloat( "aim_color", aimed->colorBarIndex ); + } + hud->HandleNamedEvent( "aim_flash" ); + MPAimHighlight = true; + MPAimFadeTime = 0; + } else if ( lastMPAim != -1 ) { + if ( gameLocal.entities[ lastMPAim ] && gameLocal.entities[ lastMPAim ]->IsType( idPlayer::Type ) ) { + aimed = static_cast< idPlayer * >( gameLocal.entities[ lastMPAim ] ); + } + assert( aimed ); + // start fading right away + hud->SetStateString( "aim_text", gameLocal.userInfo[ lastMPAim ].GetString( "ui_name" ) ); + if ( aimed ) { + hud->SetStateFloat( "aim_color", aimed->colorBarIndex ); + } + hud->HandleNamedEvent( "aim_flash" ); + hud->HandleNamedEvent( "aim_fade" ); + MPAimHighlight = false; + MPAimFadeTime = gameLocal.realClientTime; + } + } +} + +/* +============= +idPlayer::SetInfluenceLevel +============= +*/ +void idPlayer::SetInfluenceLevel( int level ) { + if ( level != influenceActive ) { + if ( level ) { + for ( idEntity *ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( idProjectile::Type ) ) { + // remove all projectiles + ent->PostEventMS( &EV_Remove, 0 ); + } + } + if ( weaponEnabled && weapon.GetEntity() ) { + weapon.GetEntity()->EnterCinematic(); + } + } else { + physicsObj.SetLinearVelocity( vec3_origin ); + if ( weaponEnabled && weapon.GetEntity() ) { + weapon.GetEntity()->ExitCinematic(); + } + } + influenceActive = level; + } +} + +/* +============= +idPlayer::SetInfluenceView +============= +*/ +void idPlayer::SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent ) { + influenceMaterial = NULL; + influenceEntity = NULL; + influenceSkin = NULL; + if ( mtr && *mtr ) { + influenceMaterial = declManager->FindMaterial( mtr ); + } + if ( skinname && *skinname ) { + influenceSkin = declManager->FindSkin( skinname ); + if ( head.GetEntity() ) { + head.GetEntity()->GetRenderEntity()->shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + } + UpdateVisuals(); + } + influenceRadius = radius; + if ( radius > 0.0f ) { + influenceEntity = ent; + } +} + +/* +============= +idPlayer::SetInfluenceFov +============= +*/ +void idPlayer::SetInfluenceFov( float fov ) { + influenceFov = fov; +} + +/* +================ +idPlayer::OnLadder +================ +*/ +bool idPlayer::OnLadder( void ) const { + return physicsObj.OnLadder(); +} + +CMultiStateMover* idPlayer::OnElevator(bool mustBeMoving) const +{ + idEntity* ent = physicsObj.GetGroundEntity(); + + // Return false if ground entity is not a mover + if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) return NULL; + + CMultiStateMover* mover = static_cast(ent); + + if (mustBeMoving) + { + return (!mover->IsAtRest()) ? mover : NULL; + } + return mover; +} + +/* +================== +idPlayer::Event_GetButtons +================== +*/ +void idPlayer::Event_GetButtons( void ) { + idThread::ReturnInt( usercmd.buttons ); +} + +/* +================== +idPlayer::Event_GetMove +================== +*/ +void idPlayer::Event_GetMove( void ) { + idVec3 move( usercmd.forwardmove, usercmd.rightmove, usercmd.upmove ); + idThread::ReturnVector( move ); +} + +/* +================ +idPlayer::Event_GetViewAngles +================ +*/ +void idPlayer::Event_GetViewAngles( void ) { + idThread::ReturnVector( idVec3( viewAngles[0], viewAngles[1], viewAngles[2] ) ); +} + +/* +================== +idPlayer::Event_StopFxFov +================== +*/ +void idPlayer::Event_StopFxFov( void ) { + fxFov = false; +} + +/* +================== +idPlayer::StartFxFov +================== +*/ +void idPlayer::StartFxFov( float duration ) { + fxFov = true; + PostEventSec( &EV_Player_StopFxFov, duration ); +} + +/* +================== +idPlayer::Event_EnableWeapon +================== +*/ +void idPlayer::Event_EnableWeapon( void ) { + hiddenWeapon = gameLocal.world->spawnArgs.GetBool( "no_Weapons" ); + weaponEnabled = true; + if ( weapon.GetEntity() ) { + weapon.GetEntity()->ExitCinematic(); + } +} + +/* +================== +idPlayer::Event_DisableWeapon +================== +*/ +void idPlayer::Event_DisableWeapon( void ) { + hiddenWeapon = gameLocal.world->spawnArgs.GetBool( "no_Weapons" ); + weaponEnabled = false; + if ( weapon.GetEntity() ) { + weapon.GetEntity()->EnterCinematic(); + } +} + +/* +================== +idPlayer::Event_GetCurrentWeapon +================== +*/ +void idPlayer::Event_GetCurrentWeapon( void ) { + const char *weapon; + + if ( currentWeapon >= 0 ) { + weapon = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); + idThread::ReturnString( weapon ); + } else { + idThread::ReturnString( "" ); + } +} + +/* +================== +idPlayer::Event_GetPreviousWeapon +================== +*/ +void idPlayer::Event_GetPreviousWeapon( void ) { + const char *weapon; + + if ( previousWeapon >= 0 ) { + int pw = ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) ? 0 : previousWeapon; + weapon = spawnArgs.GetString( va( "def_weapon%d", pw) ); + idThread::ReturnString( weapon ); + } else { + idThread::ReturnString( spawnArgs.GetString( "def_weapon0" ) ); + } +} + +/* +================== +idPlayer::Event_SelectWeapon +================== +*/ +void idPlayer::Event_SelectWeapon( const char *weaponName ) +{ + if ( gameLocal.isClient ) { + gameLocal.Warning( "Cannot switch weapons from script in multiplayer" ); + return; + } + + if ( hiddenWeapon && gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { + idealWeapon = weapon_fists; + weapon.GetEntity()->HideWeapon(); + return; + } + + int weaponNum = SlotForWeapon(weaponName); + + if (weaponNum != -1) + { + // Found, select it + SelectWeapon(weaponNum, false); + } +} + +/* +================== +idPlayer::Event_GetWeaponEntity +================== +*/ +void idPlayer::Event_GetWeaponEntity( void ) { + idThread::ReturnEntity( weapon.GetEntity() ); +} + +/* +================== +idPlayer::TeleportDeath +================== +*/ +void idPlayer::TeleportDeath( int killer ) { + teleportKiller = killer; +} + +/* +================== +idPlayer::Event_ExitTeleporter +================== +*/ +void idPlayer::Event_ExitTeleporter( void ) { + idEntity *exitEnt; + float pushVel; + + // verify and setup + exitEnt = teleportEntity.GetEntity(); + if ( !exitEnt ) { + common->DPrintf( "Event_ExitTeleporter player %d while not being teleported\n", entityNumber ); + return; + } + + pushVel = exitEnt->spawnArgs.GetFloat( "push", "300" ); + + if ( gameLocal.isServer ) { + ServerSendEvent( EVENT_EXIT_TELEPORTER, NULL, false, -1 ); + } + + SetPrivateCameraView( NULL ); + // setup origin and push according to the exit target + SetOrigin( exitEnt->GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); + SetViewAngles( exitEnt->GetPhysics()->GetAxis().ToAngles() ); + physicsObj.SetLinearVelocity( exitEnt->GetPhysics()->GetAxis()[ 0 ] * pushVel ); + physicsObj.ClearPushedVelocity(); + // teleport fx + playerView.Flash( colorWhite, 120 ); + + // clear the ik heights so model doesn't appear in the wrong place + walkIK.EnableAll(); + + UpdateVisuals(); + + StartSound( "snd_teleport_exit", SND_CHANNEL_ANY, 0, false, NULL ); + + if ( teleportKiller != -1 ) { + // we got killed while being teleported + Damage( gameLocal.entities[ teleportKiller ], gameLocal.entities[ teleportKiller ], vec3_origin, "damage_telefrag", 1.0f, INVALID_JOINT ); + teleportKiller = -1; + } else { + // kill anything that would have waited at teleport exit + gameLocal.KillBox( this ); + } + teleportEntity = NULL; +} + +/* +================ +idPlayer::ClientPredictionThink +================ +*/ +void idPlayer::ClientPredictionThink( void ) { + renderEntity_t *headRenderEnt; + + oldFlags = usercmd.flags; + oldButtons = usercmd.buttons; + + usercmd = gameLocal.usercmds[ entityNumber ]; + + if ( entityNumber != gameLocal.localClientNum ) + { + // ignore attack button of other clients. that's no good for predictions + + usercmd.buttons &= ~BUTTON_ATTACK; + // tdm: Also ignore block button + usercmd.buttons &= ~BUTTON_ZOOM; + } + + + + buttonMask &= usercmd.buttons; + usercmd.buttons &= ~buttonMask; + + // clear the ik before we do anything else so the skeleton doesn't get updated twice + walkIK.ClearJointMods(); + + if ( gameLocal.isNewFrame ) { + if ( ( usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) { + PerformImpulse( usercmd.impulse ); + } + } + + scoreBoardOpen = ( ( usercmd.buttons & BUTTON_SCORES ) != 0 || forceScoreBoard ); + + AdjustSpeed(); + + UpdateViewAngles(); + + // update the smoothed view angles + if ( gameLocal.framenum >= smoothedFrame && entityNumber != gameLocal.localClientNum ) { + idAngles anglesDiff = viewAngles - smoothedAngles; + anglesDiff.Normalize180(); + if ( idMath::Fabs( anglesDiff.yaw ) < 90.0f && idMath::Fabs( anglesDiff.pitch ) < 90.0f ) { + // smoothen by pushing back to the previous angles + viewAngles -= gameLocal.clientSmoothing * anglesDiff; + viewAngles.Normalize180(); + } + smoothedAngles = viewAngles; + } + smoothedOriginUpdated = false; + + if ( !af.IsActive() ) { + AdjustBodyAngles(); + } + + if ( !isLagged ) { + // don't allow client to move when lagged + Move(); + } + +#if 0 + // update GUIs, Items, and character interactions + UpdateFocus(); +#endif + + // service animations + if ( !spectating && !af.IsActive() ) { + m_ButtonStateTracker.Update(); + UpdateConditions(); + UpdateAnimState(); + CheckBlink(); + } + + // clear out our pain flag so we can tell if we recieve any damage between now and the next time we think + AI_PAIN = false; + + // calculate the exact bobbed view position, which is used to + // position the view weapon, among other things + CalculateFirstPersonView(); + + // this may use firstPersonView, or a thirdPerson / camera view + CalculateRenderView(); + + if ( !gameLocal.inCinematic && weapon.GetEntity() && ( health > 0 ) && !( gameLocal.isMultiplayer && spectating ) ) { + UpdateWeapon(); + } + + UpdateHUD(); + + if ( gameLocal.isNewFrame ) { + UpdatePowerUps(); + } + + UpdateDeathSkin( false ); + + if ( head.GetEntity() ) { + headRenderEnt = head.GetEntity()->GetRenderEntity(); + } else { + headRenderEnt = NULL; + } + + if ( headRenderEnt ) { + if ( influenceSkin ) { + headRenderEnt->customSkin = influenceSkin; + } else { + headRenderEnt->customSkin = NULL; + } + } + + if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() ) { + renderEntity.suppressShadowInViewID = 0; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInViewID = 0; + } + } else { + renderEntity.suppressShadowInViewID = entityNumber+1; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInViewID = entityNumber+1; + } + } + // never cast shadows from our first-person muzzle flashes + renderEntity.suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; + if ( headRenderEnt ) { + headRenderEnt->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; + } + + if ( !gameLocal.inCinematic ) { + UpdateAnimation(); + } + + if ( gameLocal.isMultiplayer ) { + DrawPlayerIcons(); + } + + Present(); + + UpdateDamageEffects(); + + LinkCombat(); + + if ( gameLocal.isNewFrame && entityNumber == gameLocal.localClientNum ) { + playerView.CalculateShake(); + } + + // determine if portal sky is in pvs + + pvsHandle_t clientPVS = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); + + gameLocal.portalSkyActive = gameLocal.pvs.CheckAreasForPortalSky( clientPVS, GetPhysics()->GetOrigin() ); + + gameLocal.pvs.FreeCurrentPVS( clientPVS ); + +} + +/* +================ +idPlayer::GetPhysicsToVisualTransform +================ +*/ +bool idPlayer::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { + if ( af.IsActive() ) { + af.GetPhysicsToVisualTransform( origin, axis ); + return true; + } + + // smoothen the rendered origin and angles of other clients + if ( gameLocal.isClient && gameLocal.framenum >= smoothedFrame && ( entityNumber != gameLocal.localClientNum || selfSmooth ) ) { + + // render origin and axis + idMat3 renderAxis = viewAxis * GetPhysics()->GetAxis(); + idVec3 renderOrigin = GetPhysics()->GetOrigin() + modelOffset * renderAxis; + + // update the smoothed origin + if ( !smoothedOriginUpdated ) { + idVec2 originDiff = renderOrigin.ToVec2() - smoothedOrigin.ToVec2(); + if ( originDiff.LengthSqr() < Square( 100.0f ) ) { + // smoothen by pushing back to the previous position + if ( selfSmooth ) { + + assert( entityNumber == gameLocal.localClientNum ); + + renderOrigin.ToVec2() -= net_clientSelfSmoothing.GetFloat() * originDiff; + + } else { + + renderOrigin.ToVec2() -= gameLocal.clientSmoothing * originDiff; + } + } + smoothedOrigin = renderOrigin; + + smoothedFrame = gameLocal.framenum; + smoothedOriginUpdated = true; + } + + axis = idAngles( 0.0f, smoothedAngles.yaw, 0.0f ).ToMat3(); + origin = ( smoothedOrigin - GetPhysics()->GetOrigin() ) * axis.Transpose(); + + } else { + + axis = viewAxis; + origin = modelOffset; + } + return true; +} + +/* +================ +idPlayer::GetPhysicsToSoundTransform +================ +*/ +bool idPlayer::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { + idCamera *camera; + + if ( privateCameraView ) { + camera = privateCameraView; + } else { + camera = gameLocal.GetCamera(); + } + + if ( camera ) { + renderView_t view; + + memset( &view, 0, sizeof( view ) ); + camera->GetViewParms( &view ); + origin = view.vieworg; + axis = view.viewaxis; + return true; + } else { + return idActor::GetPhysicsToSoundTransform( origin, axis ); + } +} + +/* +================ +idPlayer::WriteToSnapshot +================ +*/ +void idPlayer::WriteToSnapshot( idBitMsgDelta &msg ) const { + physicsObj.WriteToSnapshot( msg ); + WriteBindToSnapshot( msg ); + msg.WriteDeltaFloat( 0.0f, deltaViewAngles[0] ); + msg.WriteDeltaFloat( 0.0f, deltaViewAngles[1] ); + msg.WriteDeltaFloat( 0.0f, deltaViewAngles[2] ); + msg.WriteShort( health ); + msg.WriteBits( gameLocal.ServerRemapDecl( -1, DECL_ENTITYDEF, lastDamageDef ), gameLocal.entityDefBits ); + msg.WriteDir( lastDamageDir, 9 ); + msg.WriteShort( lastDamageLocation ); + msg.WriteBits( idealWeapon, idMath::BitsForInteger( 256 ) ); + msg.WriteBits( weapon.GetSpawnId(), 32 ); + msg.WriteBits( spectator, idMath::BitsForInteger( MAX_CLIENTS ) ); + msg.WriteBits( lastHitToggle, 1 ); + msg.WriteBits( weaponGone, 1 ); + msg.WriteBits( isLagged, 1 ); + msg.WriteBits( isChatting, 1 ); +} + +/* +================ +idPlayer::ReadFromSnapshot +================ +*/ +void idPlayer::ReadFromSnapshot( const idBitMsgDelta &msg ) { + int oldHealth, newIdealWeapon, weaponSpawnId; + bool newHitToggle, stateHitch; + + if ( snapshotSequence - lastSnapshotSequence > 1 ) { + stateHitch = true; + } else { + stateHitch = false; + } + lastSnapshotSequence = snapshotSequence; + + oldHealth = health; + + physicsObj.ReadFromSnapshot( msg ); + ReadBindFromSnapshot( msg ); + deltaViewAngles[0] = msg.ReadDeltaFloat( 0.0f ); + deltaViewAngles[1] = msg.ReadDeltaFloat( 0.0f ); + deltaViewAngles[2] = msg.ReadDeltaFloat( 0.0f ); + health = msg.ReadShort(); + lastDamageDef = gameLocal.ClientRemapDecl( DECL_ENTITYDEF, msg.ReadBits( gameLocal.entityDefBits ) ); + lastDamageDir = msg.ReadDir( 9 ); + lastDamageLocation = msg.ReadShort(); + newIdealWeapon = msg.ReadBits( idMath::BitsForInteger( 256 ) ); + weaponSpawnId = msg.ReadBits( 32 ); + spectator = msg.ReadBits( idMath::BitsForInteger( MAX_CLIENTS ) ); + newHitToggle = msg.ReadBits( 1 ) != 0; + weaponGone = msg.ReadBits( 1 ) != 0; + isLagged = msg.ReadBits( 1 ) != 0; + isChatting = msg.ReadBits( 1 ) != 0; + + // no msg reading below this + + if ( weapon.SetSpawnId( weaponSpawnId ) ) { + if ( weapon.GetEntity() ) { + // maintain ownership locally + weapon.GetEntity()->SetOwner( this ); + } + currentWeapon = -1; + } + + if ( oldHealth > 0 && health <= 0 ) { + if ( stateHitch ) { + // so we just hide and don't show a death skin + UpdateDeathSkin( true ); + } + // die + AI_DEAD = true; + SetAnimState( ANIMCHANNEL_LEGS, "Legs_Death", 4 ); + SetAnimState( ANIMCHANNEL_TORSO, "Torso_Death", 4 ); + SetWaitState( "" ); + animator.ClearAllJoints(); + if ( entityNumber == gameLocal.localClientNum ) { + playerView.Fade( colorBlack, 12000 ); + } + StartRagdoll(); + physicsObj.SetMovementType( PM_DEAD ); + if ( !stateHitch ) { + StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); + } + if ( weapon.GetEntity() ) { + weapon.GetEntity()->OwnerDied(); + } + } else if ( oldHealth <= 0 && health > 0 ) { + // respawn + Init(); + StopRagdoll(); + SetPhysics( &physicsObj ); + physicsObj.EnableClip(); + SetCombatContents( true ); + } else if ( health < oldHealth && health > 0 ) { + if ( stateHitch ) { + lastDmgTime = gameLocal.time; + } else { + // damage feedback + const idDeclEntityDef *def = static_cast( declManager->DeclByIndex( DECL_ENTITYDEF, lastDamageDef, false ) ); + if ( def ) { + playerView.DamageImpulse( lastDamageDir * viewAxis.Transpose(), &def->dict ); + AI_PAIN = Pain( NULL, NULL, oldHealth - health, lastDamageDir, lastDamageLocation, &def->dict ); + lastDmgTime = gameLocal.time; + } else { + common->Warning( "NET: no damage def for damage feedback '%d'\n", lastDamageDef ); + } + } + } else if ( health > oldHealth && !stateHitch ) { + // just pulse, for any health raise + healthPulse = true; + } + + // If the player is alive, restore proper physics object + + if ( health > 0 && IsActiveAF() ) { + + StopRagdoll(); + + SetPhysics( &physicsObj ); + + physicsObj.EnableClip(); + + SetCombatContents( true ); + + } + + + + if ( idealWeapon != newIdealWeapon ) { + if ( stateHitch ) { + weaponCatchup = true; + } + idealWeapon = newIdealWeapon; + UpdateHudWeapon(); + } + + if ( lastHitToggle != newHitToggle ) { + SetLastHitTime( gameLocal.realClientTime ); + } + + if ( msg.HasChanged() ) { + UpdateVisuals(); + } +} + +/* +================ +idPlayer::WritePlayerStateToSnapshot +================ +*/ +void idPlayer::WritePlayerStateToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteByte( bobCycle ); + msg.WriteLong( stepUpTime ); + msg.WriteFloat( stepUpDelta ); +} + +/* +================ +idPlayer::ReadPlayerStateFromSnapshot +================ +*/ +void idPlayer::ReadPlayerStateFromSnapshot( const idBitMsgDelta &msg ) { + bobCycle = msg.ReadByte(); + stepUpTime = msg.ReadLong(); + stepUpDelta = msg.ReadFloat(); +} + +/* +================ +idPlayer::ServerReceiveEvent +================ +*/ +bool idPlayer::ServerReceiveEvent( int event, int time, const idBitMsg &msg ) { + + if ( idEntity::ServerReceiveEvent( event, time, msg ) ) { + return true; + } + + // client->server events + switch( event ) { + case EVENT_IMPULSE: { + PerformImpulse( msg.ReadBits( 6 ) ); + return true; + } + default: { + return false; + } + } +} + +/* +================ +idPlayer::ClientReceiveEvent +================ +*/ +bool idPlayer::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + switch ( event ) { + case EVENT_EXIT_TELEPORTER: + Event_ExitTeleporter(); + return true; + case EVENT_ABORT_TELEPORTER: + SetPrivateCameraView( NULL ); + return true; + case EVENT_POWERUP: { + // greebo: No EVENT_POWERUP handling at the moment + return true; + } + case EVENT_SPECTATE: { + bool spectate = ( msg.ReadBits( 1 ) != 0 ); + Spectate( spectate ); + return true; + } + case EVENT_ADD_DAMAGE_EFFECT: { + if ( spectating ) { + // if we're spectating, ignore + // happens if the event and the spectate change are written on the server during the same frame (fraglimit) + return true; + } + return idActor::ClientReceiveEvent( event, time, msg ); + } + default: { + return idActor::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +================ +idPlayer::Hide +================ +*/ +void idPlayer::Hide( void ) { + idWeapon *weap; + + idActor::Hide(); + weap = weapon.GetEntity(); + if ( weap ) { + weap->HideWorldModel(); + } +} + +/* +================ +idPlayer::Show +================ +*/ +void idPlayer::Show( void ) { + idWeapon *weap; + + idActor::Show(); + weap = weapon.GetEntity(); + if ( weap ) { + weap->ShowWorldModel(); + } +} + +/* +=============== +idPlayer::SetSpectateOrigin +=============== +*/ +void idPlayer::SetSpectateOrigin( void ) { + idVec3 neworig; + + neworig = GetPhysics()->GetOrigin(); + neworig[ 2 ] += EyeHeight(); + neworig[ 2 ] += 25; + SetOrigin( neworig ); +} + +/* +=============== +idPlayer::RemoveWeapon +=============== +*/ +void idPlayer::RemoveWeapon( const char *weap ) { + if ( weap && *weap ) { + // greebo: Not yet implemented for TDM inventory + //inventory.Drop( spawnArgs, spawnArgs.GetString( weap ), -1 ); + } +} + +/* +=============== +idPlayer::CanShowWeaponViewmodel +=============== +*/ +bool idPlayer::CanShowWeaponViewmodel( void ) const { + return showWeaponViewModel; +} + +void idPlayer::UpdateWeaponEncumbrance() +{ + if (m_WeaponCursor != NULL) // grayman #2773 + { + // Get the currently selected weapon + CInventoryItemPtr weapon = m_WeaponCursor->GetCurrentItem(); + + if (weapon != NULL) + { + SetHinderance("weapon", weapon->GetMovementModifier(), 1.0f); + } + } +} + +/* +=============== +idPlayer::Event_Gibbed +=============== +*/ +void idPlayer::Event_Gibbed( void ) { + // do nothing +} + +/* +================== +idPlayer::Event_GetIdealWeapon +================== +*/ +void idPlayer::Event_GetIdealWeapon( void ) { + const char *weapon; + + if ( idealWeapon >= 0 ) { + weapon = spawnArgs.GetString( va( "def_weapon%d", idealWeapon ) ); + idThread::ReturnString( weapon ); + } else { + idThread::ReturnString( "" ); + } +} + +/* +=============== +idPlayer::UpdatePlayerIcons +=============== +*/ +void idPlayer::UpdatePlayerIcons( void ) { + int time = networkSystem->ServerGetClientTimeSinceLastPacket( entityNumber ); + if ( time > cvarSystem->GetCVarInteger( "net_clientMaxPrediction" ) ) { + isLagged = true; + } else { + isLagged = false; + } + // TODO: chatting, PDA, etc? +} + +/* +=============== +idPlayer::DrawPlayerIcons +=============== +*/ +void idPlayer::DrawPlayerIcons( void ) { + if ( !NeedsIcon() ) { + playerIcon.FreeIcon(); + return; + } + playerIcon.Draw( this, headJoint ); +} + +/* +=============== +idPlayer::HidePlayerIcons +=============== +*/ +void idPlayer::HidePlayerIcons( void ) { + playerIcon.FreeIcon(); +} + +/* +=============== +idPlayer::NeedsIcon +============== +*/ +bool idPlayer::NeedsIcon( void ) { + // local clients don't render their own icons... they're only info for other clients + + return entityNumber != gameLocal.localClientNum && ( isLagged || isChatting ); +} + +int idPlayer::ProcessLightgem(bool processing) +{ + float fValue = m_fColVal; + + int n = cv_lg_interleave.GetInteger(); + + // Skip every nth frame according to the value set in + if (processing && !cv_lg_weak.GetBool() && n > 0) + { + m_LightgemInterleave++; + + if (m_LightgemInterleave >= n) + { + m_LightgemInterleave = 0; + + fValue = gameLocal.CalcLightgem(this); + +// if( cv_interaction_vfp_type.GetBool() ) // If HDR is enabled then make sure that we decode the compressed value and tone-map it. J.C.Denton +// { +// //Decode +// fValue = fValue /( 1 - fValue ); +// +// // Tone-map +// fValue *= ((1.0f / Max(cv_lg_maxColorIntensity.GetFloat(), 0.0001f )) * fValue + 1.0); +// fValue /= (fValue + 1); +// +// } + } + } + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Averaged colorvalue total: %f\r", fValue); + + fValue += cv_lg_adjust.GetFloat(); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Adjustment %f\r", cv_lg_adjust.GetFloat()); + + // Tels: #2324 Water should decrease visibility + // Subtract the adjustment value from the water body we are in so we can + // have clear water, murky water etc. + if (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD) + { + float murkiness = physicsObj.GetWaterMurkiness(); + fValue -= murkiness; + // gameLocal.Printf( "Water murkiness %0.2f, final value: %0.2f\n", murkiness, value); + } + + m_fColVal = fValue; + m_LightgemValue = int(DARKMOD_LG_MAX * fValue); + + // Give the inventory items a chance to adjust the lightgem (fire arrow, crouching) + m_LightgemValue = GetLightgemModifier(m_LightgemValue); + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("After player adjustment %d\r", m_LightgemValue); + + m_LightgemValue = idMath::ClampInt(DARKMOD_LG_MIN, DARKMOD_LG_MAX, m_LightgemValue); + + return m_LightgemValue; +} + +void idPlayer::CalculateWeakLightgem() +{ + double fx, fy; + idLight *helper; + trace_t trace; + int h = -1; + bool bMinOneLight = false, bStump; + + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("[%s]\r", __FUNCTION__); + + double fLightgemVal = 0; + int n = m_LightList.Num(); + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%u entities found within lightradius\r", n); + idVec3 vStart(GetEyePosition()); + idVec3 vPlayerPos(GetPhysics()->GetOrigin()); + idVec3 vPlayerSeg[LSG_COUNT]; + idVec3 vLightCone[ELC_COUNT]; + idVec3 vResult[2]; + EIntersection inter; + + vPlayerSeg[LSG_ORIGIN] = vPlayerPos; + vPlayerSeg[LSG_DIRECTION] = vStart - vPlayerPos; + + for (int i = 0; i < n; i++) + { + idLight* light = m_LightList[i]; + idVec3 vLight = light->GetPhysics()->GetOrigin(); + + idVec3 vPlayer = vPlayerPos; + vPlayer.z = vLight.z; + + idVec3 vDifference = vPlayer - vLight; + double distance = vDifference.LengthFast(); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Ligth: [%s] %i px: %f py: %f pz: %f - lx: %f ly: %f lz: %f Distance: %f\r", + light->name.c_str(), i, vPlayer.x, vPlayer.y, vPlayer.z, vLight.x, vLight.y, vLight.z, distance); + + // Fast and cheap test to see if the player could be in the area of the light. + // Well, it is not exactly cheap, but it is the cheapest test that we can do at this point. :) + if (distance > light->m_MaxLightRadius) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%s is outside distance: %f/%f\r", light->name.c_str(), light->m_MaxLightRadius, distance); + if(h == -1) + h = i; + continue; + } + + if (light->IsPointlight()) + { + light->GetLightCone(vLightCone[ELL_ORIGIN], vLightCone[ELA_AXIS], vLightCone[ELA_CENTER]); + inter = IntersectLineEllipsoid(vPlayerSeg, vLightCone, vResult); + + // If this is a centerlight we have to move the origin from the original origin to where the + // center of the light is supposed to be. + // Centerlight means that the center of the ellipsoid is not the same as the origin. It has to + // be adjusted because if it casts shadows we have to trace to it, and in this case the light + // might be inside geometry and would be reported as not being visible even though it casts + // a visible light outside the geometry it is embedded. If it is not a centerlight and has + // cast shadows enabled, it wouldn't cast any light at all in such a case because it would + // be blocked by the geometry. + vLight = vLightCone[ELL_ORIGIN] + vLightCone[ELA_CENTER]; + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("IntersectLineEllipsoid returned %u\r", inter); + } + else + { + bStump = false; + light->GetLightCone(vLightCone[ELC_ORIGIN], vLightCone[ELA_TARGET], vLightCone[ELA_RIGHT], vLightCone[ELA_UP], vLightCone[ELA_START], vLightCone[ELA_END]); + inter = IntersectLineCone(vPlayerSeg, vLightCone, vResult, bStump); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("IntersectLineCone returned %u\r", inter); + } + + // The line intersection can only return three states. Either the line is passing + // through the lightcone in which case we will get two intersection points, the line + // is not passing through which means that the player is fully outside, or the line + // is touching the cone in exactly one point. The last case is not really helpfull in + // our case and doesn't make a difference for the gameplay so we simply ignore it and + // consider only cases where the player is at least partially inside the cone. + if (inter != INTERSECT_FULL) + continue; + + if (light->CastsShadow()) + { + gameLocal.clip.TracePoint(trace, vStart, vLight, CONTENTS_SOLID|CONTENTS_OPAQUE|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP + |CONTENTS_MOVEABLECLIP|CONTENTS_BODY|CONTENTS_CORPSE|CONTENTS_RENDERMODEL + |CONTENTS_FLASHLIGHT_TRIGGER, this); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("TraceFraction: %f\r", trace.fraction); + if(trace.fraction < 1.0f) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light [%s] can not be seen\r", light->name.c_str()); + continue; + } + } + + int l = (vResult[0].z < vResult[1].z) ? 0 : 1; + + if (vResult[l].z < vPlayerPos.z) + { + fx = vPlayerPos.x; + fy = vPlayerPos.y; + } + else + { + fx = vResult[l].x; + fy = vResult[l].y; + } + + bMinOneLight = true; + + fLightgemVal += light->GetDistanceColor(distance, vLightCone[ELL_ORIGIN].x - fx, vLightCone[ELL_ORIGIN].y - fy); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%s in x/y: %f/%f Distance: %f/%f Brightness: %f\r", + light->name.c_str(), fx, fy, fLightgemVal, distance, light->m_MaxLightRadius); + + // Exchange the position of these lights, so that nearer lights are more + // at the beginning of the list. You may not use the arrayentry from this point on now. + // This sorting is not exactly good, but it is very cheap and we don't want to waste + // time to sort an everchanging array. + if (h != -1) + { + helper = m_LightList[h]; + m_LightList[h] = light; + m_LightList[i] = helper; + h = -1; + } + + // No need to do further calculations when we are fully lit. 0 < n < 1 + if (fLightgemVal >= 1.0) + { + fLightgemVal = 1.0; + break; + } + } + + m_LightgemValue = static_cast(DARKMOD_LG_MAX * fLightgemVal); + + // Clamp the result to [DARKMOD_LG_MIN .. DARKMOD_LG_MAX] + m_LightgemValue = idMath::ClampInt(DARKMOD_LG_MIN, DARKMOD_LG_MAX, m_LightgemValue); + + // if the player is in a lit area and the lightgem would be totally dark we set it to at least + // one step higher. + if (bMinOneLight && m_LightgemValue <= DARKMOD_LG_MIN) + { + m_LightgemValue++; + } +} + +int idPlayer::AddLight(idLight *light) +{ + if (light != NULL) + { + m_LightList.Append(light); + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("%08lX [%s] %lu added to LightList\r", light, light->name.c_str(), m_LightList.Num()); + } + + return m_LightList.Num(); +} + +int idPlayer::RemoveLight(idLight *light) +{ + int found = m_LightList.FindIndex(light); + + if (found != -1) + { + // Light found, remove it + m_LightList.RemoveIndex(found); + DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("%08lX [%s] %lu removed from LightList\r", light, light->name.c_str(), m_LightList.Num()); + } + + return m_LightList.Num(); +} + +void idPlayer::UpdateMoveVolumes( void ) +{ + // copy step volumes from current cvar value + m_stepvol_walk = cv_pm_stepvol_walk.GetFloat(); + m_stepvol_run = cv_pm_stepvol_run.GetFloat(); + m_stepvol_creep = cv_pm_stepvol_creep.GetFloat(); + + m_stepvol_crouch_walk = cv_pm_stepvol_crouch_walk.GetFloat(); + m_stepvol_crouch_creep = cv_pm_stepvol_crouch_creep.GetFloat(); + m_stepvol_crouch_run = cv_pm_stepvol_crouch_run.GetFloat(); +} + +/* +===================== +idPlayer::GetMovementVolMod +===================== +*/ + +float idPlayer::GetMovementVolMod( void ) +{ + float returnval = 0.0f; + + bool isCrouched = AI_CROUCH != 0; + + // figure out which of the 6 possible cases we have: + // NOTE: running always has priority over creeping + if( AI_RUN ) + { + if (physicsObj.HasRunningVelocity()) + { + returnval = (isCrouched) ? m_stepvol_crouch_run : m_stepvol_run; + } + else + { + returnval = (isCrouched) ? m_stepvol_crouch_walk : m_stepvol_walk; + } + } + else if( AI_CREEP ) + { + returnval = (isCrouched) ? m_stepvol_crouch_creep : m_stepvol_creep; + } + // else it is not: AI_RUN or AI_CREEP + else + { + returnval = (isCrouched) ? m_stepvol_crouch_walk : m_stepvol_walk; + } + //gameRenderWorld->DrawText(idStr(returnval), GetEyePosition() + viewAngles.ToForward()*20, 0.15f, colorWhite, viewAngles.ToMat3(), 1, 500); + + return returnval; +} + +void idPlayer::InventoryUseKeyRelease(int holdTime) +{ + const CInventoryCursorPtr& crsr = InventoryCursor(); + CInventoryItemPtr it = crsr->GetCurrentItem(); + + // Check for a held grabber entity, which should be put back into the inventory + if (!AddGrabberEntityToInventory()) + { + // Check if there is a valid item selected + if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) + { + UseInventoryItem(EReleased, it, holdTime, false); + } + } +} + +void idPlayer::UseInventoryItem() +{ + // If the grabber item can be equipped/dequipped, use item does this + if ( gameLocal.m_Grabber->GetSelected() || gameLocal.m_Grabber->GetEquipped() ) + { + if( gameLocal.m_Grabber->ToggleEquip() ) + { + return; + } + } + + // If the player has an item that is selected we need to check if this + // is a usable item (like a key). In this case the use action takes + // precedence over the frobaction. + const CInventoryCursorPtr& crsr = InventoryCursor(); + CInventoryItemPtr it = crsr->GetCurrentItem(); + + if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) + { + bool couldBeUsed = UseInventoryItem(EPressed, it, 0, false); // false => not a frob action + + // Give optional visual feedback on the KeyDown event + if (cv_tdm_inv_use_visual_feedback.GetBool()) + { + m_overlays.broadcastNamedEvent(couldBeUsed ? "onInvPositiveFeedback" : "onInvNegativeFeedback"); + } + } +} + +bool idPlayer::UseInventoryItem(EImpulseState impulseState, const CInventoryItemPtr& item, int holdTime, bool isFrobUse) +{ + if (impulseState == EPressed) + { + // Pass the "inventoryUseItem" event to the GUIs + m_overlays.broadcastNamedEvent("inventoryUseItem"); + } + + // Check if we're allowed to use items at all + if (GetImmobilization() & EIM_ITEM_USE) return false; + + // Sanity check + if (item == NULL) return false; + + idEntity* ent = item->GetItemEntity(); + if (ent == NULL) return false; + + idEntity* highlightedEntity = m_FrobEntity.GetEntity(); + + bool itemIsUsable = ent->spawnArgs.GetBool("usable"); + + if (highlightedEntity != NULL && itemIsUsable && highlightedEntity->CanBeUsedBy(item, isFrobUse)) + { + // Pass the use call + if (highlightedEntity->UseBy(impulseState, item)) + { + // Item could be used, return TRUE, we're done + return true; + } + } + + // Item could not be used on the highlighted entity, launch the use script + + idThread* thread = NULL; + + if (impulseState == EPressed) + { + thread = ent->CallScriptFunctionArgs("inventoryUse", true, 0, "eeed", ent, this, highlightedEntity, impulseState); + } + else if (impulseState == EReleased) + { + thread = ent->CallScriptFunctionArgs("inventoryUseKeyRelease", true, 0, "eeef", ent, this, highlightedEntity, static_cast(holdTime)); + } + + if (thread != NULL) + { + thread->Execute(); // Start the thread immediately. + + // A working scriptfunction means the item could be used + return true; + } + + return false; +} + +void idPlayer::DropInventoryItem() +{ + bool bDropped = false; + CGrabber *grabber = gameLocal.m_Grabber; + idEntity *heldEntity = grabber->GetSelected(); + idEntity *equippedEntity = grabber->GetEquipped(); + + // Dequip or drop the item in the grabber hands first + if( equippedEntity != NULL ) + { + grabber->Dequip(); + } + else if(heldEntity != NULL) + { + grabber->Update( this, false ); + } + else + { + // Grabber is empty (no item is held), drop the current inventory item + const CInventoryCursorPtr& cursor = InventoryCursor(); + + CInventoryItemPtr item = cursor->GetCurrentItem(); + CInventoryCategoryPtr category = cursor->GetCurrentCategory(); + + // Do we have a droppable item in the first place? + if (item != NULL && item->IsDroppable() && item->GetCount() > 0) + { + // Retrieve the actual entity behind the inventory item + idEntity* ent = item->GetItemEntity(); + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Attempting to drop inventory entity %s\r", ent->name.c_str()); + + // greebo: Try to locate a drop script function on the entity's scriptobject + const function_t* dropScript = ent->scriptObject.GetFunction(TDM_INVENTORY_DROPSCRIPT); + + if( dropScript != NULL ) + { + // Call the custom drop script + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Running inventory drop script...\r"); + idThread* thread = new idThread(dropScript); + thread->CallFunctionArgs(dropScript, true, "ee", ent, this); + thread->DelayedStart(0); + + // The dropScript changes the inventory count itself, so don't set + // bDropped to true here. + } + // greebo: Only place the entity in the world, if there is no custom dropscript + // The flashbomb for example is spawning projectiles on its own. + else if( DropToHands( ent, item ) ) + { + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item was successfully put in hands: %s\r", ent->name.c_str()); + bDropped = true; + } + else + { + // There wasn't space to drop the item + StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Grabber did not find space in the world to fit entity in hands: %s\r", ent->name.c_str()); + } + + // Decrease the inventory count (this will also clear empty categories) + // This applies for both stackable as well as droppable items + if( bDropped) + { + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item dropped, changing inventory count.\r"); + + ChangeInventoryItemCount(item->GetName(), category->GetName(), -1); + } + + // Always update the HUD, the drop script might have changed the inventory count itself. + inventoryHUDNeedsUpdate = true; + } + } +} + +bool idPlayer::SelectInventoryItem(const idStr& name) +{ + CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); + idStr itemName(name); + + if (itemName.IsEmpty()) + { + // Empty name specified, clear the inventory cursor + itemName = TDM_DUMMY_ITEM; + if (prev->GetName() != itemName) + { + // Save name of current item (to restore it in idEntity::NextPrevInventoryItem) + m_LastItemNameBeforeClear = prev->GetName(); + } + } + + // Try to lookup the item in the inventory + CInventoryItemPtr item = Inventory()->GetItem(itemName); + + if (item != NULL) + { + // Item found, set the cursor to it + InventoryCursor()->SetCurrentItem(item); + + // Trigger an update, passing the previous item along + OnInventorySelectionChanged(prev); + return true; + } + else + { + gameLocal.Printf("Could not find item in player inventory: %s\n", itemName.c_str()); + return false; + } +} + +void idPlayer::OnInventoryItemChanged() +{ + // Call the base class + idEntity::OnInventoryItemChanged(); + + inventoryHUDNeedsUpdate = true; +} + +void idPlayer::OnInventorySelectionChanged(const CInventoryItemPtr& prevItem) +{ + // Call the base class first + idEntity::OnInventorySelectionChanged(prevItem); + + // Set the "dirty" flag, the HUD needs a redraw + inventoryHUDNeedsUpdate = true; + + // Notify the GUIs about the change event + m_overlays.broadcastNamedEvent("inventorySelectionChange"); + + // Get the current item + const CInventoryCursorPtr& cursor = InventoryCursor(); + const CInventoryItemPtr& curItem = cursor->GetCurrentItem(); + + if (prevItem != NULL && prevItem != curItem) + { + // We had a valid previous item, un-select the old one + idEntity* prevItemEnt = prevItem->GetItemEntity(); + + // greebo: Call the "UN-SELECT" script method on the "old" item + if (prevItemEnt != NULL) + { + idThread* thread = prevItemEnt->CallScriptFunctionArgs( + "inventory_item_unselect", + true, 0, + "eef", prevItemEnt, prevItem->GetOwner(), static_cast(prevItem->GetOverlay()) + ); + + if (thread != NULL) + { + thread->Execute(); + } + } + + // Remove the hinderance of the previous item + SetHinderance("inventory_item", 1.0f, 1.0f); + } + + if (curItem != NULL && prevItem != curItem) + { + // We have a valid curItem and it is different to the previously selected one + idEntity* curItemEnt = curItem->GetItemEntity(); + + // greebo: Call the "SELECT" script method on the newly selected item to give it a chance to initialise. + if (curItemEnt != NULL) + { + idThread* thread = curItemEnt->CallScriptFunctionArgs( + "inventory_item_select", + true, 0, + "eef", curItemEnt, curItem->GetOwner(), static_cast(curItem->GetOverlay()) + ); + + if (thread != NULL) + { + thread->Execute(); + } + } + + // Update the player's encumbrance based on the new item + SetHinderance("inventory_item", curItem->GetMovementModifier(), 1.0f); + } + + // Lastly, let's see if the category has changed + if (curItem != NULL && prevItem != NULL && curItem->Category() != prevItem->Category()) + { + idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); + if (invGUI != NULL) + { + invGUI->HandleNamedEvent("onInventoryCategoryChanged"); + } + } +} + +bool idPlayer::DropToHands( idEntity *ent, CInventoryItemPtr item ) +{ + bool rc = false; + CGrabber *grabber = gameLocal.m_Grabber; + + if( !ent || !grabber ) + return false; + + // get player view data to apply yaw and roll to dropped object's orientation + idVec3 playViewPos; + idMat3 playViewAxis; + GetViewPos( playViewPos, playViewAxis ); + idAngles viewYaw = playViewAxis.ToAngles(); + // ignore pitch and roll + viewYaw[0] = 0; + viewYaw[2] = 0; + idMat3 playViewYaw = viewYaw.ToMat3(); + + // Set up the initial orientation and point at which we want to drop + idMat3 dropAxis; + if( item != NULL ) + dropAxis = item->GetDropOrientation(); + else if( ent->spawnArgs.FindKey("drop_angles") ) + { + idAngles dropAngles = ent->spawnArgs.GetAngles("drop_angles"); + dropAxis = dropAngles.ToMat3(); + } + else + dropAxis = ent->GetPhysics()->GetAxis(); + + dropAxis *= playViewYaw; + + // flip dropped bodies if appropriate... move elsewhere? + if( ent->IsType(idAFEntity_Base::Type) && ent->spawnArgs.GetBool("shoulderable") ) + { + if( grabber->m_bDropBodyFaceUp ) + dropAxis *= idAngles(0.0f,0.0f,180.0f).ToMat3(); + } + + idVec3 dropPoint; + if( ent->spawnArgs.FindKey("drop_point") ) + { + dropPoint = ent->spawnArgs.GetVector("drop_point"); + dropPoint *= playViewYaw; + dropPoint += playViewPos; + } + else + { + dropPoint = grabber->GetHoldPoint( ent ); + } + + // Stackables: Test that the item fits in world with dummy item first, before spawning the drop item + // NOTE: TestDropItemRotations will overwrite DropAxis if the supplied doesn't work and it finds a working one + if( TestDropItemRotations(ent, playViewPos, dropPoint, dropAxis) ) + { + // Drop the item into the grabber hands + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item fits in hands.\r"); + + // Stackable items only have one "real" entity for the whole item stack. + // When the stack size == 1, this entity can be dropped as it is, + // otherwise we need to spawn a new entity. + if( item && item->IsStackable() && item->GetCount() > 1 ) + { + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Spawning new entity from stackable inventory item...\r"); + // Spawn a new entity of this type + idEntity* spawnedEntity; + const idDict* entityDef = gameLocal.FindEntityDefDict(ent->GetEntityDefName()); + gameLocal.SpawnEntityDef(*entityDef, &spawnedEntity); + + // Replace the entity to be dropped with the newly spawned one. + ent = spawnedEntity; + } + + // If the item is referenced by any objective with a item-location component set the flag + // so it will be considered by location entities. + if ( gameLocal.m_MissionData->MatchLocationObjectives( ent ) ) + { + ent->m_bIsObjective = true; + } + + grabber->PutInHands( ent, dropPoint, dropAxis ); + DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item was successfully put in hands: %s\r", ent->name.c_str()); + rc = true; + + // check if the item drops straight to the ground, not going in hands first + if( !ent->spawnArgs.GetBool("drop_to_hands","1") ) + { + grabber->Update( this, false ); + } + + // Tels: #2826: re-enable LOD again, in case the entity was in the inventory (like a shoulderable body) + ent->EnableLOD( true ); + } + + return rc; +} + +bool idPlayer::TestDropItemRotations( idEntity *ent, idVec3 viewPoint, idVec3 DropPoint, idMat3 &DropAxis ) +{ + bool bReturnVal(false); + + idList Rotations; + // first try the supplied orientation + Rotations.Append( mat3_identity ); + // yaw rotations + Rotations.Append( idAngles(0.0f, 90.0f, 0.0f).ToMat3() ); + Rotations.Append( idAngles(0.0f, 180.0f, 0.0f).ToMat3() ); + Rotations.Append( idAngles(0.0f, 270.0f, 0.0f).ToMat3() ); + // roll rotations + Rotations.Append( idAngles(0.0f, 0.0f, 90.0f).ToMat3() ); + Rotations.Append( idAngles(0.0f, 0.0f, 180.0f).ToMat3() ); + Rotations.Append( idAngles(0.0f, 0.0f, 270.0f).ToMat3() ); + // pitch up and down + // Dropping upside-down should always be a last resort + if( !gameLocal.m_Grabber->m_bDropBodyFaceUp ) + { + Rotations.Append( idAngles(-90.0f, 0.0f, 0.0f).ToMat3() ); + Rotations.Append( idAngles(90.0f, 0.0f, 0.0f).ToMat3() ); + } + else + { + Rotations.Append( idAngles(90.0f, 0.0f, 0.0f).ToMat3() ); + Rotations.Append( idAngles(-90.0f, 0.0f, 0.0f).ToMat3() ); + } + + // test each orientation to see if it fits in the world + idMat3 InitAxis = DropAxis; + idMat3 TestAxis( mat3_identity ); + for( int i=0; i < Rotations.Num(); i++ ) + { + TestAxis = Rotations[i] * InitAxis; + if( gameLocal.m_Grabber->FitsInWorld( ent, viewPoint, DropPoint, TestAxis ) ) + { + bReturnVal = true; + DropAxis = TestAxis; + break; + } + } + + return bReturnVal; +} + +void idPlayer::Event_GetEyePos( void ) +{ + idThread::ReturnVector( firstPersonViewOrigin ); +} + +void idPlayer::Event_SetImmobilization( const char *source, int type ) +{ + SetImmobilization( source, type ); +} + +/* +===================== +idPlayer::Event_GetImmobilization +===================== +*/ +void idPlayer::Event_GetImmobilization( const char *source ) +{ + if (idStr::Length(source)) { + idThread::ReturnInt( m_immobilization.GetInt(source) ); + } else { + idThread::ReturnInt( GetImmobilization() ); + } +} + +/* +===================== +idPlayer::Event_GetNextImmobilization +===================== +*/ +void idPlayer::Event_GetNextImmobilization( const char *prefix, const char *lastMatch ) +{ + // Code is plagarized from getNextKey() + const idKeyValue *kv; + const idKeyValue *previous; + + if ( *lastMatch ) { + previous = m_immobilization.FindKey( lastMatch ); + } else { + previous = NULL; + } + + kv = m_immobilization.MatchPrefix( prefix, previous ); + if ( !kv ) { + idThread::ReturnString( "" ); + } else { + idThread::ReturnString( kv->GetKey() ); + } +} + +/* +===================== +idPlayer::Event_SetHinderance +===================== +*/ +void idPlayer::Event_SetHinderance( const char *source, float mCap, float aCap ) +{ + SetHinderance( source, mCap, aCap ); +} + +/* +===================== +idPlayer::Event_SetTurnHinderance +===================== +*/ +void idPlayer::Event_SetTurnHinderance( const char *source, float mCap, float aCap ) +{ + SetTurnHinderance(source, mCap, aCap); +} + +/* +===================== +idPlayer::Event_GetHinderance +===================== +*/ +void idPlayer::Event_GetHinderance( const char *source ) +{ + if (idStr::Length(source)) { + idThread::ReturnVector( m_hinderance.GetVector( source, "1 1 0" ) ); + } else { + float h = GetHinderance(); + idVec3 vec( h, h, 0.0f ); + idThread::ReturnVector( vec ); + } +} + +/* +===================== +idPlayer::Event_GetTurnHinderance +===================== +*/ +void idPlayer::Event_GetTurnHinderance( const char *source ) +{ + if (idStr::Length(source)) { + idThread::ReturnVector( m_TurnHinderance.GetVector( source, "1 1 0" ) ); + } else { + float h = GetTurnHinderance(); + idVec3 vec( h, h, 0.0f ); + idThread::ReturnVector( vec ); + } +} + +/* +===================== +idPlayer::Event_GetNextHinderance +===================== +*/ +void idPlayer::Event_GetNextHinderance( const char *prefix, const char *lastMatch ) +{ + // Code is plagarized from getNextKey() + const idKeyValue *kv; + const idKeyValue *previous; + + if ( *lastMatch ) { + previous = m_hinderance.FindKey( lastMatch ); + } else { + previous = NULL; + } + + kv = m_hinderance.MatchPrefix( prefix, previous ); + if ( !kv ) { + idThread::ReturnString( "" ); + } else { + idThread::ReturnString( kv->GetKey() ); + } +} + +/* +===================== +idPlayer::Event_GetNextTurnHinderance +===================== +*/ +void idPlayer::Event_GetNextTurnHinderance( const char *prefix, const char *lastMatch ) +{ + // Code is plagarized from getNextKey() + const idKeyValue *kv; + const idKeyValue *previous; + + if ( *lastMatch ) { + previous = m_TurnHinderance.FindKey( lastMatch ); + } else { + previous = NULL; + } + + kv = m_TurnHinderance.MatchPrefix( prefix, previous ); + if ( !kv ) { + idThread::ReturnString( "" ); + } else { + idThread::ReturnString( kv->GetKey() ); + } +} + +/* +===================== +idPlayer::Event_SetGui +===================== +*/ +void idPlayer::Event_SetGui( int handle, const char *guiFile ) { + if ( !uiManager->CheckGui(guiFile) ) { + gameLocal.Warning( "Unable to load GUI file: %s\n", guiFile ); + goto Quit; + } + + if ( !m_overlays.exists( handle ) ) { + gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); + goto Quit; + } + + // Entity GUIs are handled differently from regular ones. + if ( handle == OVERLAYS_MIN_HANDLE ) { + + assert( hud ); + assert( m_overlays.isExternal( handle ) ); + + // We're dealing with an existing unique GUI. + // We need to read a new GUI into it. + + // Clear the state. + const idDict &state = hud->State(); + const idKeyValue *kv; + while ( ( kv = state.MatchPrefix( "" ) ) != NULL ) + hud->DeleteStateVar( kv->GetKey() ); + + hud->InitFromFile( guiFile ); + + } else if ( !m_overlays.isExternal( handle ) ) { + + bool result = m_overlays.setGui( handle, guiFile ); + assert( result ); + + idUserInterface *gui = m_overlays.getGui( handle ); + if ( gui ) { + gui->SetStateInt( "handle", handle ); + gui->Activate( true, gameLocal.time ); + // Let's set a good default value for whether or not the overlay is interactive. + m_overlays.setInteractive( handle, gui->IsInteractive() ); + } else { + gameLocal.Warning( "Unknown error: Unable to load GUI into overlay.\n" ); + } + + } else { + gameLocal.Warning( "Cannot call setGui() on external handle: %d\n", handle ); + } + + Quit: + return; +} + +void idPlayer::Event_GetInventoryOverlay(void) +{ + idThread::ReturnInt(m_InventoryOverlay); +} + +void idPlayer::Event_PlayStartSound( void ) +{ + StartSound("snd_mission_start", SND_CHANNEL_ANY, 0, false, NULL); +} + +void idPlayer::Event_MissionFailed( void ) +{ + gameLocal.m_MissionData->Event_MissionFailed(); +} + +void idPlayer::Event_CustomDeath() +{ + // Run the custom death script + idThread* thread = CallScriptFunctionArgs("custom_death", true, 0, "e", this); + + if (thread != NULL) { + // Run immediately + thread->Execute(); + } +} + +void idPlayer::Event_LoadDeathMenu( void ) +{ + forceRespawn = true; +} + +/* +================ +idPlayer::Event_HoldEntity +================ +*/ +void idPlayer::Event_HoldEntity( idEntity *ent ) +{ + if ( ent ) + { + bool successful = gameLocal.m_Grabber->PutInHands( ent, ent->GetPhysics()->GetAxis() ); + idThread::ReturnInt( successful ); + } + else + { + gameLocal.m_Grabber->Update( this, false ); + idThread::ReturnInt( 1 ); + } +} + +/* +================ +idPlayer::Event_HeldEntity +================ +*/ +void idPlayer::Event_HeldEntity( void ) +{ + idThread::ReturnEntity(gameLocal.m_Grabber->GetSelected()); +} + +void idPlayer::Event_RopeRemovalCleanup(idEntity *RopeEnt) +{ + if (GetPhysics()->IsType(idPhysics_Player::Type)) + { + static_cast(GetPhysics())->RopeRemovalCleanup( RopeEnt ); + } +} + +void idPlayer::Event_SetObjectiveState( int ObjIndex, int State ) +{ + // when calling this function externally, the "user" indices are + // used, so subtract one from the index + gameLocal.m_MissionData->SetCompletionState( ObjIndex - 1, State ); +} + +void idPlayer::Event_GetObjectiveState( int ObjIndex ) +{ + int CompState = gameLocal.m_MissionData->GetCompletionState( ObjIndex - 1 ); + idThread::ReturnInt( CompState ); +} + +void idPlayer::Event_SetObjectiveComp( int ObjIndex, int CompIndex, int bState ) +{ + gameLocal.m_MissionData->SetComponentState_Ext( ObjIndex, CompIndex, (bState != 0) ); +} + +void idPlayer::Event_GetObjectiveComp( int ObjIndex, int CompIndex ) +{ + bool bCompState = gameLocal.m_MissionData->GetComponentState( ObjIndex -1, CompIndex -1 ); + + idThread::ReturnInt( (int) bCompState ); +} + +void idPlayer::Event_ObjectiveUnlatch( int ObjIndex ) +{ + gameLocal.m_MissionData->UnlatchObjective( ObjIndex - 1 ); +} + +void idPlayer::Event_ObjectiveComponentUnlatch( int ObjIndex, int CompIndex ) +{ + gameLocal.m_MissionData->UnlatchObjectiveComp( ObjIndex - 1, CompIndex -1 ); +} + +void idPlayer::Event_SetObjectiveVisible( int ObjIndex, bool bVal ) +{ + gameLocal.m_MissionData->SetObjectiveVisibility(ObjIndex, bVal); +} + +void idPlayer::Event_SetObjectiveOptional( int ObjIndex, bool bVal ) +{ + gameLocal.m_MissionData->SetObjectiveMandatory(ObjIndex, !bVal); // negate the incoming bool +} + +void idPlayer::Event_SetObjectiveOngoing( int ObjIndex, bool bVal ) +{ + gameLocal.m_MissionData->SetObjectiveOngoing(ObjIndex, bVal); +} + +void idPlayer::Event_SetObjectiveEnabling( int ObjIndex, const char *strIn ) +{ + gameLocal.m_MissionData->SetEnablingObjectives(ObjIndex, strIn); +} + +void idPlayer::Event_GiveHealthPool( float amount ) { + // Pass the call to the proper member method + GiveHealthPool(amount); +} + +void idPlayer::Event_WasDamaged( void ) +{ + idThread::ReturnInt(m_bDamagedThisFrame); +} + +void idPlayer::Event_StartZoom(float duration, float startFOV, float endFOV) +{ + // greebo: Start the new transition from startFOV >> endFOV, this enables the idInterpolate + zoomFov.Init(gameLocal.time, duration, startFOV, endFOV); +} + +void idPlayer::Event_EndZoom(float duration) +{ + // greebo: Make a transition from the current FOV back to the default FOV, this enables the idInterpolate + zoomFov.Init(gameLocal.time, duration, zoomFov.GetCurrentValue(gameLocal.time), DefaultFov()); +} + +void idPlayer::Event_ResetZoom() +{ + // Reset the FOV to the default values, this enables the idInterpolate + zoomFov.Init(gameLocal.time, 0, DefaultFov(), DefaultFov()); +} + +void idPlayer::Event_GetFov() +{ + // greebo: Return the current fov + idThread::ReturnFloat(CalcFov(true)); +} + +void idPlayer::PerformFrobCheck() +{ + // greebo: Don't run this when dead + if (AI_DEAD) + { + return; + } + + // greebo: Don't run the frobcheck when we're dragging items around + if (m_bGrabberActive) + { + return; + } + + // ishtvan: Don't run if frob hilighting is disabled + // TODO: Should we just add this functionality to EIM_FROB and get rid of EIM_FROBHILIGHT? + if ( GetImmobilization() & EIM_FROB_HILIGHT ) + { + m_FrobEntity = NULL; + return; + } + + idVec3 eyePos = GetEyePosition(); + float maxFrobDistance = g_Global.m_MaxFrobDistance; + + // greebo: Let the currently selected inventory item affect the frob distance (lockpicks, for instance) + CInventoryItemPtr curItem = InventoryCursor()->GetCurrentItem(); + + idVec3 start = eyePos; + idVec3 end = start + viewAngles.ToForward() * maxFrobDistance; + + // Do frob trace first, along view axis, record distance traveled + // Frob collision mask: + int cm = CONTENTS_SOLID|CONTENTS_OPAQUE|CONTENTS_BODY + |CONTENTS_CORPSE|CONTENTS_RENDERMODEL|CONTENTS_FROBABLE; + + trace_t trace; + gameLocal.clip.TracePoint(trace, start, end, cm, this); + + float traceDist = g_Global.m_MaxFrobDistance * trace.fraction; + + if ( trace.fraction < 1.0f ) + { + idEntity *ent = gameLocal.entities[ trace.c.entityNum ]; + + float extraSpace = 0; // grayman #2478 - a little extra room to disarm a mine + if ( ent->IsType(idProjectile::Type) && static_cast(ent)->IsMine() ) + { + extraSpace = 8; + } + + DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Frob: Direct hit on entity %s\r", ent->name.c_str()); + + // This is taking locked items into account + bool lockedItemCheck = true; + // If we are in the mode where we only frob ents used by our inventory item, this checks if it passes the test + bool bUsedByCheck = true; + + // greebo: Check if the frobbed entity is the bindmaster of the currently climbed rope + bool isRopeMaster = physicsObj.OnRope() && physicsObj.GetRopeEntity()->GetBindMaster() == ent; + + // ishtvan: Check if the frobbed entity is a dynamically added AF body linked to another entity + if ( ent->IsType(idAFEntity_Base::Type) ) + { + idAFEntity_Base *afEnt = static_cast(ent); + idAFBody *AFbod = afEnt->GetAFPhysics()->GetBody( afEnt->BodyForClipModelId(trace.c.id) ); + + if ( AFbod->GetRerouteEnt() && AFbod->GetRerouteEnt()->m_bFrobable ) + { + ent = AFbod->GetRerouteEnt(); + } + } + + // Inventory items might impose a reduction of the frob distance to some entities + if ( curItem != NULL ) + { + bool bCanBeUsed = ent->CanBeUsedBy(curItem, true); + + if ( bCanBeUsed && ( traceDist > curItem->GetFrobDistanceCap() + extraSpace ) ) + { + // Failed the distance check for locked items, disable this entity + lockedItemCheck = false; + } + + if ( m_bFrobOnlyUsedByInv && !bCanBeUsed ) + { + // frob only used by is active and ent can't be used, failed check + bUsedByCheck = false; + } + } + + // If shouldering a body, we only allow "simple" frobs + bool frobAllowed = !m_bShoulderingBody || ent->m_bFrobSimple; + + // only frob frobable, non-hidden entities within their frobdistance + // also, do not frob the ent we are currently holding in our hands + if ( ent->m_bFrobable && frobAllowed && lockedItemCheck && bUsedByCheck && !isRopeMaster + && !ent->IsHidden() && ( traceDist < ent->m_FrobDistance ) + && ( ent != gameLocal.m_Grabber->GetSelected() ) ) + { + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING(" Entity %s was within frobdistance\r", ent->name.c_str()); + + // Mark as frobbed for this frame + ent->SetFrobbed(true); + + // Store the trace for later reference + m_FrobTrace = trace; + // Store the frob entity + m_FrobEntity = ent; + + // we have found our frobbed entity, so exit + return; + } + } + + // If the trace didn't hit anything frobable, do the radius test + DM_LOG(LC_FROBBING,LT_INFO)LOGSTRING("No entity frobbed by direct LOS frob, trying frob radius.\r"); + + idBounds frobBounds(trace.endpos); + frobBounds.ExpandSelf( cv_frob_width.GetFloat() ); + + // Optional debug drawing of frob bounds + if( cv_frob_debug_bounds.GetBool() ) + { + gameRenderWorld->DebugBounds( colorBlue, frobBounds ); + } + + static idEntity* frobRangeEnts[MAX_GENTITIES]; + + int numFrobEnt = gameLocal.clip.EntitiesTouchingBounds(frobBounds, -1, frobRangeEnts, MAX_GENTITIES); + + idVec3 vecForward = viewAngles.ToForward(); + float bestDot = 0; + idEntity* bestEnt = NULL; + + for ( int i = 0 ; i < numFrobEnt ; i++ ) + { + idEntity *ent = frobRangeEnts[i]; + + if (ent == NULL) + { + continue; + } + + if (!ent->m_FrobDistance || ent->IsHidden() || !ent->m_bFrobable) + { + continue; + } + + // If shouldering a body, we only allow "simple" frobs + if (m_bShoulderingBody && !ent->m_bFrobSimple) + { + continue; + } + + // Get the frob distance from the entity candidate + float frobDist = ent->m_FrobDistance; + idVec3 delta = ent->GetPhysics()->GetOrigin() - eyePos; + + float entDistance = delta.LengthFast(); + + if (entDistance > frobDist) + { + continue; // too far + } + + if (curItem != NULL) // grayman #2478 - rearranged code + { + bool canBeUsed = ent->CanBeUsedBy(curItem, true); + + // Inventory items might impose a reduction of the frob distance to some entities. + // grayman #2478 - If the frobbed entity is a mine, increase the distance. + + // Special case for armed mine and lockpick. + + bool isMine = ( ent->IsType(idProjectile::Type) && static_cast(ent)->IsMine() ); + if ( isMine ) + { + if ( !canBeUsed || ( entDistance > ( curItem->GetFrobDistanceCap() + 8 ) ) ) + { + continue; + } + } + else if ( canBeUsed && ( entDistance > curItem->GetFrobDistanceCap() ) ) + { + // Failed inventory item distance check, ignore this entity + continue; + } + + // Frob only used by inv. item is active, and this entity cannot be used by it + if ( m_bFrobOnlyUsedByInv && !canBeUsed ) + { + continue; + } + } + + delta.NormalizeFast(); + float currentDot = delta * vecForward; + currentDot *= ent->m_FrobBias; + + if ( currentDot > bestDot ) + { + bestDot = currentDot; + bestEnt = ent; + } + } + + if ( ( bestEnt != NULL ) && ( bestEnt != gameLocal.m_Grabber->GetSelected() ) ) + { + // Mark the entity as frobbed this frame + bestEnt->SetFrobbed(true); + // Store the frob entity + m_FrobEntity = bestEnt; + // and the trace for reference + m_FrobTrace = trace; + + return; // done + } + + // No frob entity + m_FrobEntity = NULL; +} + +int idPlayer::GetImmobilization( const char *source ) +{ + // greebo: Return named immobilizations or return the sum of all immobilizations + return (idStr::Length(source) > 0) ? m_immobilization.GetInt(source) : GetImmobilization(); +} + +void idPlayer::SetImmobilization( const char *source, int type ) +{ + if (idStr::Length(source)) + { + // The user cannot set the update bit directly. + type &= ~EIM_UPDATE; + + if (type != 0) + { + m_immobilization.SetInt( source, type ); + } + else + { + m_immobilization.Delete( source ); + } + + m_immobilizationCache |= EIM_UPDATE; + } + else + { + gameLocal.Warning( "source was empty; no immobilization set\n" ); + } +} + +void idPlayer::SetHinderance( const char *source, float mCap, float aCap ) +{ + if (idStr::Length(source)) + { + // Clamp the values to [0,1] + mCap = idMath::ClampFloat(0, 1, mCap); + aCap = idMath::ClampFloat(0, 1, aCap); + + if (mCap < 1.0f || aCap < 1.0f) + { + // Store the values into a vector and into the hinderance dictionary + m_hinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); + } + else + { + // greebo: Both values are 1 == no hinderance, delete the value + m_hinderance.Delete( source ); + } + + m_hinderanceCache = -1; + } + else + { + gameLocal.Warning( "source was empty; no hinderance set\n" ); + } +} + +void idPlayer::SetTurnHinderance( const char *source, float mCap, float aCap ) +{ + if (idStr::Length(source)) + { + // Clamp the values to [0,1] + mCap = idMath::ClampFloat(0, 1, mCap); + aCap = idMath::ClampFloat(0, 1, aCap); + + if (mCap < 1.0f || aCap < 1.0f) + { + // Store the values into a vector and into the hinderance dictionary + m_TurnHinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); + } + else + { + m_TurnHinderance.Delete( source ); + } + + m_TurnHinderanceCache = -1; + } + else + { + gameLocal.Warning( "source was empty; no turn hinderance set\n" ); + } +} + +float idPlayer::GetJumpHinderance() +{ + // Has something changed since the cache was last calculated? + if (m_JumpHinderanceCache < 0.0f) + { + // Recalculate the hinderance from scratch. + float mCap = 1.0f, aCap = 1.0f; + + for (const idKeyValue* kv = m_JumpHinderance.MatchPrefix( "", NULL ); kv != NULL; kv = m_JumpHinderance.MatchPrefix("", kv)) + { + idVec3 vec = m_JumpHinderance.GetVector(kv->GetKey()); + mCap *= vec[0]; + + if ( aCap > vec[1] ) + { + aCap = vec[1]; + } + } + + if ( aCap > mCap ) + { + aCap = mCap; + } + + m_JumpHinderanceCache = aCap; + } + + return m_JumpHinderanceCache; +} + +void idPlayer::SetJumpHinderance( const char *source, float mCap, float aCap ) +{ + if (idStr::Length(source)) + { + // Clamp the values to [0,1] + mCap = idMath::ClampFloat(0, 1, mCap); + aCap = idMath::ClampFloat(0, 1, aCap); + + if (mCap < 1.0f || aCap < 1.0f) + { + // Store the values into a vector and into the hinderance dictionary + m_JumpHinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); + } + else + { + m_JumpHinderance.Delete( source ); + } + + m_JumpHinderanceCache = -1; + } + else + { + gameLocal.Warning( "source was empty; no jump hinderance set\n" ); + } +} + +void idPlayer::PlayFootStepSound() +{ + if ( !GetPhysics()->HasGroundContacts() ) { + return; + } + + // This implements a certain dead time before the next footstep is allowed to be played + if (gameLocal.time <= lastFootstepPlaytime + cv_pm_min_stepsound_interval.GetInteger()) + { + return; + } + + idStr localSound; + + // DarkMod: make the string to identify the movement speed (crouch_run, creep, etc) + // Currently only players have movement flags set up this way, not AI. We could change that later. + idStr moveType(""); + + UpdateMoveVolumes(); + + // angua: check whether the player has just landed from jumping or a fall + if (!hasLanded) + { + if (AI_CROUCH) + { + moveType = "_crouch"; + } + + // greebo: Make sure that "_run" is only applied when actually running + if (AI_RUN && physicsObj.HasRunningVelocity()) + { + moveType += "_run"; + } + else if (AI_CREEP) + { + moveType += "_creep"; + } + else + { + moveType += "_walk"; + } + } + + // start footstep sound based on material type + const idMaterial* material = GetPhysics()->GetContact( 0 ).material; + if ( material != NULL ) + { + DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Player %s stepped on entity %s, material %s \r", name.c_str(), gameLocal.entities[GetPhysics()->GetContact( 0 ).entityNum]->name.c_str(), material->GetName() ); + g_Global.GetSurfName(material, localSound); + if (hasLanded) + { + localSound = "snd_jump_" + localSound; + } + else + { + localSound = "snd_footstep_" + localSound; + } + + DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Found surface type sound: %s\r", localSound.c_str() ); + } + + waterLevel_t waterLevel = physicsObj.GetWaterLevel(); + // If player is walking in liquid, replace the bottom surface sound with water sounds + if (waterLevel == WATERLEVEL_FEET ) + { + if (hasLanded) + { + localSound = "snd_jump_puddle"; + } + else + { + localSound = "snd_footstep_puddle"; + } + } + else if (waterLevel == WATERLEVEL_WAIST) + { + localSound = "snd_footstep_wading"; + } + // greebo: Added this to disable the walking sound when completely underwater + // this should be replaced by snd_ + else if (waterLevel == WATERLEVEL_HEAD) + { + localSound = "snd_footstep_swim"; + } + + idStr sound; + + if (cv_tdm_footfalls_movetype_specific.GetBool()) + { + sound = spawnArgs.GetString( localSound + moveType ); + + if (sound.IsEmpty()) + { + //gameLocal.Warning("Did not find footstep sound %s", (localSound + moveType).c_str()); + + // Fall back to normal sound + sound = spawnArgs.GetString( localSound ); + } + } + else + { + sound = spawnArgs.GetString( localSound ); + } + + if ( sound.IsEmpty() && waterLevel != WATERLEVEL_HEAD ) + { + localSound = "snd_footstep"; + } + + // if a sound was not found for that specific material, use default + if( sound.IsEmpty() && waterLevel != WATERLEVEL_HEAD ) + { + sound = spawnArgs.GetString( "snd_footstep" ); + localSound = "snd_footstep"; + } + + // The player always considers the movement type when propagating + if (!hasLanded) + { + localSound += moveType; + } + + if ( !sound.IsEmpty() ) + { + // apply the movement type modifier to the volume + const idSoundShader* sndShader = declManager->FindSound( sound ); + SetSoundVolume( sndShader->GetParms()->volume + GetMovementVolMod() ); + StartSoundShader( sndShader, SND_CHANNEL_BODY, 0, false, NULL ); + SetSoundVolume( 0.0f ); + + // propagate the suspicious sound to other AI + PropSoundDirect( localSound, true, false ); + + lastFootstepPlaytime = gameLocal.time; + } +} + +/* +================ +idPlayer::RangedThreatTo + +Return nonzero if this entity could potentially +attack the given (target) entity at range, or +entities in general if target is NULL. +i.e. Return 1 if we have a projectile weapon +equipped, and 0 otherwise. +================ +*/ +float idPlayer::RangedThreatTo(idEntity* target) { + idWeapon* weaponEnt = weapon.GetEntity(); + + return weaponEnt->IsRanged(); +} + +void idPlayer::SetListenerLoc( idVec3 loc ) +{ + m_ListenerLoc = loc; +} + +idVec3 idPlayer::GetListenerLoc( void ) +{ + return m_ListenerLoc; +} + +void idPlayer::SetDoorListenLoc( idVec3 loc ) +{ + m_DoorListenLoc = loc; +} + +idVec3 idPlayer::GetDoorListenLoc( void ) +{ + return m_DoorListenLoc; +} + +CInventoryItemPtr idPlayer::AddToInventory(idEntity *ent) +{ + // Pass the call to the base class first + CInventoryItemPtr returnValue = idEntity::AddToInventory(ent); + + // Has this item been added to a weapon item? + CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast(returnValue); + + CInventoryItemPtr prev; + + if (weaponItem != NULL) + { + // greebo: This is a weapon-related inventory item, use the weapon inventory cursor + // Do it only if the respective CVAR is set + if (cv_frob_weapon_selects_weapon.GetBool()) + { + m_WeaponCursor->SetCurrentItem(returnValue); + SelectWeapon(weaponItem->GetWeaponIndex(), false); + } + } + else if (returnValue != NULL) + { + // Ordinary inventory item, set the cursor onto it + prev = InventoryCursor()->GetCurrentItem(); + // Focus the cursor on the newly added item + InventoryCursor()->SetCurrentItem(returnValue); + + // Fire the script events and update the HUD + OnInventorySelectionChanged(prev); + } + + return returnValue; +} + +void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target) +{ + // greebo: Don't perform frobs on hidden or NULL entities + if (target == NULL || target->IsHidden()) + { + return; + } + + // if we only allow "simple" frob actions and this isn't one, play forbidden sound + if( (GetImmobilization() & EIM_FROB_COMPLEX) && !target->m_bFrobSimple ) + { + // TODO: Rename this "uh-uh" sound to something more general? + StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); + return; + } + + // greebo: Check the frob entity, this might be the same as the argument + // Retrieve the entity before trying to add it to the inventory, the pointer + // might be cleared after calling AddToInventory(). + idEntity* highlightedEntity = m_FrobEntity.GetEntity(); + + if (impulseState == EPressed) + { + // Fire the STIM_FROB response on key down (if defined) on this entity + target->TriggerResponse(this, ST_FROB); + } + + // Do we allow use on frob? + if (cv_tdm_inv_use_on_frob.GetBool()) + { + // Check if we have a "use" relationship with the currently selected inventory item (key => door) + CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); + + // Only allow items with UseOnFrob == TRUE to be used when frobbing + if (item != NULL && item->UseOnFrob() && highlightedEntity->CanBeUsedBy(item, true)) + { + // Try to use the item + bool couldBeUsed = UseInventoryItem(impulseState, item, gameLocal.msec, true); // true => is frob action + + // Give optional visual feedback on the KeyDown event + if (impulseState == EPressed && cv_tdm_inv_use_visual_feedback.GetBool()) + { + m_overlays.broadcastNamedEvent(couldBeUsed ? "onInvPositiveFeedback" : "onInvNegativeFeedback"); + } + + return; + } + } + + // If FrobUsedOnlyByInv mode is active, we can only perform use_on_frob actions, so skip all the rest + if( m_bFrobOnlyUsedByInv ) + return; + + // Inventory item could not be used with the highlighted entity, proceed with ordinary frob action + + // These actions are only applicable for EPressed buttonstate + if (impulseState == EPressed) + { + // Trigger the frob action script on key down + target->FrobAction(true); + + DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("USE: frob target: %s \r", target->name.c_str()); + + // note which target we started pressing frob on + m_FrobPressedTarget = target; + + // First we have to check whether that entity is an inventory + // item. In that case, we have to add it to the inventory and + // hide the entity. + CInventoryItemPtr addedItem = AddToInventory(target); + + // Check if the frobbed entity is the one currently highlighted by the player + if (addedItem != NULL && highlightedEntity == target) + { + // Item has been added to the inventory, clear the entity pointer + m_FrobEntity = NULL; + } + + // Grab it if it's a grabable class + if (target->IsType(idMoveable::Type) || target->IsType(idAFEntity_Base::Type) || + target->IsType(idMoveableItem::Type) || target->IsType(idAFAttachment::Type)) + { + // allow override of default grabbing behavior + if( !target->spawnArgs.GetBool("grabable","1") ) + return; + + // Do not pick up live, conscious AI + if( target->IsType( idAI::Type ) ) + { + idAI *AItarget = static_cast(target); + if( AItarget->health > 0 && !AItarget->IsKnockedOut() ) + return; + } + + gameLocal.m_Grabber->Update( this ); + } + } +} + +void idPlayer::PerformFrob() +{ + // Ignore frobs if player-frobbing is immobilized. + if ( GetImmobilization() & EIM_FROB ) + { + return; + } + + // if the grabber is currently holding something and frob is pressed, + // release it. Do not frob anything new since you're holding an item. + if( gameLocal.m_Grabber->GetSelected() ) + { + gameLocal.m_Grabber->Update( this ); + return; + } + + // Get the currently frobbed entity + idEntity* frob = m_FrobEntity.GetEntity(); + + // Relay the function to the specialised method + PerformFrob(EPressed, frob); +} + +void idPlayer::PerformFrobKeyRepeat(int holdTime) +{ + // Ignore frobs if player-frobbing is immobilized. + if ( GetImmobilization() & EIM_FROB ) return; + + // Get the currently frobbed entity + idEntity* frob = m_FrobEntity.GetEntity(); + + // use the original target until frob is released and pressed again + if( m_FrobPressedTarget.IsValid() && m_FrobPressedTarget.GetEntity() != NULL ) + m_FrobPressedTarget.GetEntity()->FrobHeld( true, false, holdTime ); + + // Relay the function to the specialised method + PerformFrob(ERepeat, frob); +} + +void idPlayer::PerformFrobKeyRelease(int holdTime) +{ + // Ignore frobs if player-frobbing is immobilized. + if ( GetImmobilization() & EIM_FROB ) return; + + // Get the currently frobbed entity + idEntity* frob = m_FrobEntity.GetEntity(); + + // use the original target until frob is released and pressed again + if( m_FrobPressedTarget.IsValid() && m_FrobPressedTarget.GetEntity() != NULL ) + m_FrobPressedTarget.GetEntity()->FrobReleased( true, false, holdTime ); + + // Relay the function to the specialised method + PerformFrob(EReleased, frob); +} + +void idPlayer::setHealthPoolTimeInterval(int newTimeInterval, float factor, int stepAmount) { + healthPoolTimeInterval = newTimeInterval; + healthPoolTimeIntervalFactor = factor; + healthPoolStepAmount = stepAmount; +} + +bool idPlayer::AddGrabberEntityToInventory() +{ + CGrabber* grabber = gameLocal.m_Grabber; + idEntity* heldEntity = grabber->GetSelected(); + + if (heldEntity != NULL) + { + CInventoryItemPtr item = AddToInventory(heldEntity); + + if (item != NULL) + { + // greebo: Release any items from the grabber, this immobilized the player somehow before + grabber->Update( this, false ); + + // greebo: Prevent the grabber from checking the added entity (it may be + // entirely removed from the game, which would cause crashes). + grabber->RemoveFromClipList(heldEntity); + + return true; + } + } + + return false; +} + +int idPlayer::GetLightgemModifier(int curLightgemValue) +{ + // Take the compiled lightgem modifier as starting point + int returnValue = curLightgemValue + m_LightgemModifier; + + // greebo: Take the current velocity into account + // This is a multiplicative modifier and is applied first + { + // Get the velocity, but don't take "inherited" speed into account. + idVec3 velocityVec = physicsObj.GetLinearVelocity() - physicsObj.GetPushedLinearVelocity(); + + const idVec3& gravityDir = physicsObj.GetGravityNormal(); + velocityVec -= (velocityVec * gravityDir) * gravityDir; + + float velocity = velocityVec.LengthFast(); + float minVelocity = cv_lg_velocity_mod_min_velocity.GetFloat(); + float maxVelocity = cv_lg_velocity_mod_max_velocity.GetFloat(); + + float velocityFactor = (velocity - minVelocity) / (maxVelocity - minVelocity); + + // Force the factor into [0..1] + if (velocityFactor > 1) velocityFactor = 1; + if (velocityFactor < 0) velocityFactor = 0; + + float factor = 1.0f + velocityFactor*cv_lg_velocity_mod_amount.GetFloat(); + returnValue = static_cast(returnValue * factor); + } + + // Check the weapon/inventory items + if (m_WeaponCursor != NULL) + { + CInventoryItemPtr weapon = m_WeaponCursor->GetCurrentItem(); + if (weapon != NULL) + { + returnValue += weapon->GetLightgemModifier(); + } + } + + CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); + if (item != NULL) + { + returnValue += item->GetLightgemModifier(); + } + + // Take the crouching into account + if (physicsObj.IsCrouching()) + { + returnValue += cv_lg_crouch_modifier.GetInteger(); + } + + // No need to cap the value, this is done in idGameLocal again. + + return returnValue; +} + +void idPlayer::Event_SetLightgemModifier(const char* modifierName, int amount) +{ + if (amount != 0) + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Setting modifier %s to %d\r", modifierName, amount); + m_LightgemModifierList[std::string(modifierName)] = amount; + } + else + { + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Removing modifier %s as %d was passed\r", modifierName, amount); + // Zero value passed, remove the named value + std::string modifierNameStr(modifierName); + std::map::iterator i = m_LightgemModifierList.find(modifierNameStr); + + if (i != m_LightgemModifierList.end()) { + // Value found, remove it + m_LightgemModifierList.erase(i); + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Removed.\r"); + } + } + + // Recalculate the lightgem modifier value + m_LightgemModifier = 0; + + for (std::map::const_iterator i = m_LightgemModifierList.begin(); + i != m_LightgemModifierList.end(); + ++i) + { + // Add the value to the lightgem modifier + m_LightgemModifier += i->second; + } + + DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("New lightgem modifier value: %d\r", m_LightgemModifier); +} + +void idPlayer::Event_ReadLightgemModifierFromWorldspawn() +{ + int modifierValue(0); + + idEntity* worldspawn = gameLocal.entities[ENTITYNUM_WORLD]; + + if (worldspawn != NULL) + { + // Read the modifier value from the worldspawn, default to zero + modifierValue = worldspawn->spawnArgs.GetInt("lightgem_adjust", "0"); + } + + Event_SetLightgemModifier("world", modifierValue); +} + +void idPlayer::SendHUDMessage(const idStr& text) +{ + if (text.IsEmpty()) { + return; + } + + hudMessages.Append( gameLocal.m_I18N->Translate( text ) ); +} + +void idPlayer::SendInventoryPickedUpMessage(const idStr& text) +{ + if (text.IsEmpty()) return; + + inventoryPickedUpMessages.Append(text); +} + +void idPlayer::EnforcePersistentInventoryItemLimits() +{ + idStr diffPrefix = va("diff_%d_", gameLocal.m_DifficultyManager.GetDifficultyLevel()); + + for (int i = 0; i < gameLocal.campaignInfoEntities.Num(); ++i) + { + idEntity* campaignInfo = gameLocal.campaignInfoEntities[i]; + assert(campaignInfo != NULL); + + // Enforce weapon limits + CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); + + idList itemsToRemove; + + for (int w = 0; w < weaponCategory->GetNumItems(); ++w) + { + CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast(weaponCategory->GetItem(w)); + + if (weaponItem->GetPersistentCount() <= 0) + { + continue; // not a persistent weapon + } + + const idStr& weaponName = weaponItem->GetWeaponName(); + + // Get the active limit, check non-difficulty-specific ones first, defaults to no limit + int limit = campaignInfo->spawnArgs.GetInt("weapon_limit_" + weaponName, "-1"); + + // Let the difficulty-specific limit override the global one + limit = campaignInfo->spawnArgs.GetInt(diffPrefix + "weapon_limit_" + weaponName, va("%d", limit)); + + if (limit == -1) + { + continue; // no limit specified for this weapon + } + + bool needsAmmo = weaponItem->NeedsAmmo(); + + if (needsAmmo) + { + if (weaponItem->GetAmmo() > limit) + { + weaponItem->SetAmmo(limit); + } + } + else + { + // Weapons without ammonition + if (limit == 0) + { + // Limit set to 0, drop this weapon + itemsToRemove.Append(weaponItem); + } + } + } + + // Remove all marked items from this category + for (int w = 0; w < itemsToRemove.Num(); ++w) + { + weaponCategory->RemoveItem(itemsToRemove[w]); + } + + // Enforce regular inventory item limits + for (const idKeyValue* kv = campaignInfo->spawnArgs.MatchPrefix("item_"); + kv != NULL; kv = campaignInfo->spawnArgs.MatchPrefix("item_", kv)) + { + idStr indexStr = kv->GetKey(); + indexStr.StripLeadingOnce("item_"); + + int index = atoi(indexStr.c_str()); + + const idStr& itemName = kv->GetValue(); + int limit = campaignInfo->spawnArgs.GetInt(va("limit_%d", index), "-1"); + + // let difficulty-specific settings override this + limit = campaignInfo->spawnArgs.GetInt(diffPrefix + va("limit_%d", index), va("%d", limit)); + + // Item limit of -1 means: no limit + if (limit == -1) + { + continue; + } + + DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Trying to enforce inventory item limit: %s => max %d\r", itemName.c_str(), limit); + + CInventoryItemPtr item = Inventory()->GetItem(itemName); + + if (!item) + { + continue; // no item with that name + } + + if (item->IsPersistent() && item->GetCount() > limit) + { + ChangeInventoryItemCount(item->GetName(), item->Category()->GetName(), limit - item->GetCount()); + } + } + } +} + +void idPlayer::Event_Pausegame() +{ + gameLocal.PauseGame(true); +} + +void idPlayer::Event_Unpausegame() +{ + gameLocal.PauseGame(false); +} + +void idPlayer::Event_MissionSuccess() +{ + // Clear the persistent inventory, it might have old data from the previous mission + gameLocal.persistentPlayerInventory->Clear(); + + // Enfore item limits on mission end - drop everything exceeding the limits + EnforcePersistentInventoryItemLimits(); + + // Save current inventory into the persistent one + Inventory()->CopyTo(*gameLocal.persistentPlayerInventory); + + // Save the item entities of all persistent items + gameLocal.persistentPlayerInventory->SaveItemEntities(true); + + // Schedule the disconnect command, this needs to be done before issuing the save call + PostEventMS(&EV_DisconnectFromMission, 0); + + // Issue an automatic save at the end of this mission + // greebo: Don't do this immediately, the player PVS must be freed before saving! + gameLocal.m_TriggerFinalSave = true; +} + +void idPlayer::Event_DisconnectFromMission() +{ + // Set the gamestate + gameLocal.SetMissionResult(MISSION_COMPLETE); + gameLocal.sessionCommand = "disconnect"; +} + +void idPlayer::Event_TriggerMissionEnd() +{ + if (hudMessages.Num() > 0) + { + // There are still HUD messages pending, postpone this event + PostEventMS(&EV_TriggerMissionEnd, 3000); + return; + } + + gameLocal.PrepareForMissionEnd(); + + idVec4 fadeColor(0,0,0,1); + playerView.Fade(fadeColor, 1500); + + // Schedule an mission success event right after fadeout + PostEventMS(&EV_Mission_Success, 1500); +} + +void idPlayer::Event_GetLocation() +{ + idThread::ReturnEntity( GetLocation() ); +} + +void idPlayer::Event_StartGamePlayTimer() +{ + gameLocal.m_GamePlayTimer.Clear(); + gameLocal.m_GamePlayTimer.Start(); +} + +void idPlayer::Event_CheckAAS() +{ + if (gameLocal.GameState() >= GAMESTATE_ACTIVE) + { + idList aasNames; + + for (idAI* ai = gameLocal.spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) + { + if (ai->GetAAS() == NULL) + { + idStr aasName = ai->spawnArgs.GetString("use_aas"); + aasNames.AddUnique(aasName); + } + } + + for (int i = 0; i < aasNames.Num(); i++) + { + SendHUDMessage("Warning: " + aasNames[i] + " is out of date!"); + } + } +} + +void idPlayer::Event_ChangeWeaponProjectile(const char* weaponName, const char* projectileDefName) +{ + // Just wrap to the actual method + ChangeWeaponProjectile(weaponName, projectileDefName); +} + +void idPlayer::Event_ResetWeaponProjectile(const char* weaponName) +{ + ResetWeaponProjectile(weaponName); +} + +void idPlayer::Event_ChangeWeaponName(const char* weaponName, const char* newName) +{ + ChangeWeaponName(weaponName, newName); +} + +void idPlayer::Event_GetCurWeaponName() +{ + CInventoryWeaponItemPtr weaponItem = GetCurrentWeaponItem(); + if (weaponItem == NULL) return; + + idThread::ReturnString( weaponItem->GetWeaponName().c_str() ); +} + +void idPlayer::ClearActiveInventoryMap() +{ + idEntity* mapEnt = m_ActiveInventoryMapEnt.GetEntity(); + + if (mapEnt == NULL) return; + + // Call the method inventory_map::clear(entity userEnt) + idThread* thread = mapEnt->CallScriptFunctionArgs("clear", true, 0, "ee", mapEnt, this); + + if (thread != NULL) + { + // Run the thread at once + thread->Execute(); + } + + m_ActiveInventoryMapEnt = NULL; +} + +void idPlayer::Event_ClearActiveInventoryMap() +{ + ClearActiveInventoryMap(); +} + +void idPlayer::Event_SetActiveInventoryMapEnt(idEntity* mapEnt) +{ + // Check for a previously active map and clear it if necessary + if (m_ActiveInventoryMapEnt.GetEntity() != NULL) + { + ClearActiveInventoryMap(); + } + + m_ActiveInventoryMapEnt = mapEnt; +} + +void idPlayer::Event_GetFrobbed() +{ + idThread::ReturnEntity( m_FrobEntity.GetEntity() ); +} + +void idPlayer::Event_SetFrobOnlyUsedByInv( bool value ) +{ + m_bFrobOnlyUsedByInv = value; +} + +void idPlayer::Event_ProcessInterMissionTriggers() +{ + gameLocal.ProcessInterMissionTriggers(); +} diff --git a/game/Player.h b/game/Player.h new file mode 100644 index 000000000..db4913fc4 --- /dev/null +++ b/game/Player.h @@ -0,0 +1,1424 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/#ifndef __GAME_PLAYER_H__ +#define __GAME_PLAYER_H__ + +#include "ButtonStateTracker.h" +class CInventoryItem; +typedef boost::shared_ptr CInventoryItemPtr; + +class CInventoryWeaponItem; +typedef boost::shared_ptr CInventoryWeaponItemPtr; + +/* +=============================================================================== + + Player entity. + +=============================================================================== +*/ + +extern const idEventDef EV_Player_GetButtons; +extern const idEventDef EV_Player_GetMove; +extern const idEventDef EV_Player_GetViewAngles; +extern const idEventDef EV_Player_GetMouseGesture; +extern const idEventDef EV_Player_MouseGestureFinished; +extern const idEventDef EV_Player_StartMouseGesture; +extern const idEventDef EV_Player_StopMouseGesture; +extern const idEventDef EV_Player_ClearMouseDeadTime; +extern const idEventDef EV_Player_EnableWeapon; +extern const idEventDef EV_Player_DisableWeapon; +extern const idEventDef EV_Player_ExitTeleporter; +extern const idEventDef EV_Player_SelectWeapon; +extern const idEventDef EV_SpectatorTouch; +extern const idEventDef EV_Player_PlayStartSound; +extern const idEventDef EV_Player_DeathMenu; +extern const idEventDef EV_Player_MissionFailed; +extern const idEventDef EV_Player_GiveHealthPool; +extern const idEventDef EV_Player_WasDamaged; +extern const idEventDef EV_Mission_Success; +extern const idEventDef EV_TriggerMissionEnd; +extern const idEventDef EV_Player_GetLocation; +extern const idEventDef EV_Player_GetFrobbed; +extern const idEventDef EV_Player_SetFrobOnlyUsedByInv; + +const float THIRD_PERSON_FOCUS_DISTANCE = 512.0f; +const int LAND_DEFLECT_TIME = 150; +const int LAND_RETURN_TIME = 300; +const int FOCUS_TIME = 300; +const int FOCUS_GUI_TIME = 500; + +#define TDM_PLAYER_WEAPON_CATEGORY "Weapons" +#define TDM_PLAYER_MAPS_CATEGORY "#str_02390" + +#define ARROW_WEAPON_INDEX_BEGIN 3 // grayman #597 - weapons at or above this index are arrows + +const int DEAD_HEARTRATE = 0; // fall to as you die +const int LOWHEALTH_HEARTRATE_ADJ = 20; // +const int DYING_HEARTRATE = 30; // used for volumen calc when dying/dead +const int BASE_HEARTRATE = 70; // default +const int ZEROSTAMINA_HEARTRATE = 115; // no stamina +const int MAX_HEARTRATE = 130; // maximum +const int ZERO_VOLUME = -40; // volume at zero +const int DMG_VOLUME = 5; // volume when taking damage +const int DEATH_VOLUME = 15; // volume at death + +const int SAVING_THROW_TIME = 5000; // maximum one "saving throw" every five seconds + +const int ASYNC_PLAYER_INV_AMMO_BITS = idMath::BitsForInteger( 999 ); // 9 bits to cover the range [0, 999] +const int ASYNC_PLAYER_INV_CLIP_BITS = -7; // -7 bits to cover the range [-1, 60] + +// powerups - the "type" in item .def must match +enum { + BERSERK = 0, + INVISIBILITY, + MEGAHEALTH, + ADRENALINE, + MAX_POWERUPS +}; + +// powerup modifiers +enum { + SPEED = 0, + PROJECTILE_DAMAGE, + MELEE_DAMAGE, + MELEE_DISTANCE +}; + +// influence levels +enum { + INFLUENCE_NONE = 0, // none + INFLUENCE_LEVEL1, // no gun or hud + INFLUENCE_LEVEL2, // no gun, hud, movement + INFLUENCE_LEVEL3, // slow player movement +}; + +/** +* Possible mouse directions, for mouse gestures +**/ +typedef enum { + MOUSEDIR_NONE, + MOUSEDIR_LEFT, + MOUSEDIR_UP_LEFT, + MOUSEDIR_UP, + MOUSEDIR_UP_RIGHT, + MOUSEDIR_RIGHT, + MOUSEDIR_DOWN_RIGHT, + MOUSEDIR_DOWN, + MOUSEDIR_DOWN_LEFT +} EMouseDir; + +/** +* Possible tests, for mouse gestues +**/ +typedef enum +{ + MOUSETEST_UPDOWN, + MOUSETEST_LEFTRIGHT, + MOUSETEST_4DIR, // up down left right + MOUSETEST_8DIR, // 4 DIR + the diagonals +} EMouseTest; + +/** +* Mouse gesture data +**/ +typedef struct SMouseGesture_s +{ + bool bActive; // we are currently checking a mouse gesture + EMouseTest test; // defines which directions we're testing for movement + bool bInverted; // mouse motions are inverted + + int key; // key being checked + int thresh; // mouse input threshold required to decide + int DecideTime; // time in ms before we auto-decide (default -1, wait forever) + int DeadTime; // time over which the response is dampened, can be greater than decide time + + int started; // time in ms at which we started + idVec2 StartPos; // mouse position at which we started + idVec2 motion; // accumulated mouse motion over the gesture + EMouseDir result; // result of the last gesture, using the MOUSEDIR_* enum + + SMouseGesture_s( void ) + { + bActive = false; + test = MOUSETEST_LEFTRIGHT; + bInverted = false; + key = 0; + thresh = 0; + DecideTime = -1; + DeadTime = 0; + started = 0; + StartPos = vec2_zero; + motion = vec2_zero; + result = MOUSEDIR_RIGHT; + }; + + void Save(idSaveGame *savefile) const + { + savefile->WriteBool( bActive ); + savefile->WriteInt( (int) test ); + savefile->WriteBool( bInverted ); + savefile->WriteInt( key ); + savefile->WriteInt( thresh ); + savefile->WriteInt( DecideTime ); + savefile->WriteInt( started ); + savefile->WriteVec2( StartPos ); + savefile->WriteVec2( motion ); + savefile->WriteInt( (int) result ); + }; + void Restore(idRestoreGame *savefile) + { + int tempInt; + + savefile->ReadBool(bActive); + savefile->ReadInt( tempInt ); + test = (EMouseTest) tempInt; + savefile->ReadBool( bInverted ); + savefile->ReadInt( key ); + savefile->ReadInt( thresh ); + savefile->ReadInt( DecideTime ); + savefile->ReadInt( started ); + savefile->ReadVec2( StartPos ); + savefile->ReadVec2( motion ); + savefile->ReadInt( tempInt ); + result = (EMouseDir) tempInt; + }; +} SMouseGesture; + +// Player control immobilization categories. +enum { + EIM_ALL = -1, + EIM_UPDATE = BIT( 0), // For internal use only. True if immobilization needs to be recalculated. + EIM_VIEW_ANGLE = BIT( 1), // Looking around + EIM_MOVEMENT = BIT( 2), // Forwards/backwards, strafing and swimming. + EIM_CROUCH = BIT( 3), // Crouching. + EIM_CROUCH_HOLD = BIT( 4), // Prevent changes to crouching state. (NYI) + EIM_JUMP = BIT( 5), // Jumping. + EIM_MANTLE = BIT( 6), // Mantling (excluding jumping) + EIM_CLIMB = BIT( 7), // Climbing ladders, ropes and mantling. + EIM_FROB = BIT( 8), // Frobbing. + EIM_FROB_HILIGHT = BIT( 9), // Frobbing AND frob hilighting (not sure if needed or if EIM_FROB can disable hilight also) + EIM_FROB_COMPLEX = BIT(10), // Frobbing of "complex" items (not a door, lever, button, etc) + EIM_ATTACK = BIT(11), // Using weapons + EIM_ATTACK_RANGED = BIT(12), // Using ranged weapons (bows) + EIM_WEAPON_SELECT = BIT(13), // Selecting weapons. + EIM_ITEM_USE = BIT(14), // Using items + EIM_ITEM_SELECT = BIT(15), // Selecting items. + EIM_ITEM_DROP = BIT(16), // Dropping inventory items. +}; + +typedef struct { + int time; + idVec3 dir; // scaled larger for running +} loggedAccel_t; + +typedef struct { + int areaNum; + idVec3 pos; +} aasLocation_t; + +class idPlayer : public idActor { +public: + enum { + EVENT_IMPULSE = idEntity::EVENT_MAXEVENTS, + EVENT_EXIT_TELEPORTER, + EVENT_ABORT_TELEPORTER, + EVENT_POWERUP, + EVENT_SPECTATE, + EVENT_MAXEVENTS + }; + + usercmd_t usercmd; + + class idPlayerView playerView; // handles damage kicks and effects + + bool noclip; + bool godmode; + + bool spawnAnglesSet; // on first usercmd, we must set deltaAngles + idAngles spawnAngles; + idAngles viewAngles; // player view angles + idAngles cmdAngles; // player cmd angles + + int buttonMask; + int oldButtons; + int oldFlags; + + int lastHitTime; // last time projectile fired by player hit target + int lastSndHitTime; // MP hit sound - != lastHitTime because we throttle + int lastSavingThrowTime; // for the "free miss" effect + + // The GUI of the lockpick visualisation HUD + int lockpickHUD; + + // angua: this is true when the player lands after jumping or a fall + // to play the jumping footstep sounds + bool hasLanded; + + idScriptBool AI_FORWARD; + idScriptBool AI_BACKWARD; + idScriptBool AI_STRAFE_LEFT; + idScriptBool AI_STRAFE_RIGHT; + idScriptBool AI_ATTACK_HELD; + idScriptBool AI_BLOCK_HELD; + idScriptBool AI_WEAPON_FIRED; + idScriptBool AI_WEAPON_BLOCKED; + idScriptBool AI_JUMP; + idScriptBool AI_CROUCH; + idScriptBool AI_ONGROUND; + idScriptBool AI_ONLADDER; + //idScriptBool AI_DEAD; // is defined on idActor now + idScriptBool AI_RUN; + idScriptBool AI_PAIN; + idScriptBool AI_HARDLANDING; + idScriptBool AI_SOFTLANDING; + idScriptBool AI_RELOAD; + idScriptBool AI_TELEPORT; + idScriptBool AI_TURN_LEFT; + idScriptBool AI_TURN_RIGHT; + /** + * Leaning + **/ + idScriptBool AI_LEAN_LEFT; + idScriptBool AI_LEAN_RIGHT; + idScriptBool AI_LEAN_FORWARD; + + /** + * Ishtvan: Set to true for the duration of the frame if the AI takes damage + * (more reliable than AI_PAIN) + **/ + bool m_bDamagedThisFrame; + + /** + * Set to true if the player is creeping + **/ + idScriptBool AI_CREEP; + + /** + * greebo: Helper class keeping track of which buttons are currently + * held down and which got released. + * calls PerformButtonRelease() on this entity on this occasion. + */ + ButtonStateTracker m_ButtonStateTracker; + + /** + * Player's current/last mouse gesture: + **/ + SMouseGesture m_MouseGesture; + + // ---- Frob-related members (moved from CDarkmodPlayer to here) ---- + + /** + * Ishtvan: The target that we initially started pressing frob on + * keep track of this for things that react to frob held, so we don't + * move from one target to another without first letting go of frob + **/ + idEntityPtr m_FrobPressedTarget; + + /** + * FrobEntity is NULL when no entity is highlighted. Otherwise it will point + * to the entity which is currently highlighted. + */ + idEntityPtr m_FrobEntity; + + /** + * Frobbed joint and frobbed clipmodel ID if an AF has been frobbed + * Set to INVALID and -1 if the frobbed entity is not an AF + **/ + jointHandle_t m_FrobJoint; + int m_FrobID; + + /** + * The trace that was done for frobbing + * Read off by idEntity::UpdateFrob when something has been newly frobbed + **/ + trace_t m_FrobTrace; + + /** + * If true, this only allows frobbing of entities that can be used by + * the currently selected inventory item. + * This also disables normal frob actions on pressing frob, + * only allowing the "used by" action. + **/ + bool m_bFrobOnlyUsedByInv; + + /** + * Set to true if the player is holding an item with the Grabber + **/ + bool m_bGrabberActive; + + /** + * Set to true if the player is dragging a body + * NOT YET IMPLEMENTED + **/ + bool m_bDraggingBody; + + /** + * Set to true if the player is shouldering a body + **/ + bool m_bShoulderingBody; + + + // angua: whether the player should be crouching + bool m_IdealCrouchState; + + // angua: this is true when the player is holding the crocuh button + // or toggle crouch is active + bool m_CrouchIntent; + + + /** + * Hack to fix the leaning test of key-releases + * Timestamp to wait a few frames before testing for button release + **/ + int m_LeanButtonTimeStamp; + + idEntityPtr weapon; + idUserInterface * hud; // MP: is NULL if not local player + + // greebo: This is true if the inventory HUD needs a refresh + bool inventoryHUDNeedsUpdate; + + // greebo: A list of HUD messages which are displayed one after the other + idList hudMessages; + idList inventoryPickedUpMessages; + + int weapon_fists; + + bool m_HeartBeatAllow; /// disable hearbeat except when dying or drowning - Need this to track state + int heartRate; + idInterpolate heartInfo; + int lastHeartAdjust; + int lastHeartBeat; + int lastDmgTime; + int deathClearContentsTime; + bool doingDeathSkin; + int lastArmorPulse; // lastDmgTime if we had armor at time of hit + float stamina; + float healthPool; // amount of health to give over time + int nextHealthPulse; + bool healthPulse; + bool healthTake; + int nextHealthTake; + // greebo: added these to make the interval customisable + int healthPoolStepAmount; // The amount of healing in each pulse + int healthPoolTimeInterval; // The time between health pulses + float healthPoolTimeIntervalFactor; // The factor to increase the time interval after each pulse + + + bool hiddenWeapon; // if the weapon is hidden ( in noWeapons maps ) + + // mp stuff + static idVec3 colorBarTable[ 5 ]; + int spectator; + idVec3 colorBar; // used for scoreboard and hud display + int colorBarIndex; + bool scoreBoardOpen; + bool forceScoreBoard; + bool forceRespawn; + bool spectating; + int lastSpectateTeleport; + bool lastHitToggle; + bool forcedReady; + bool wantSpectate; // from userInfo + bool weaponGone; // force stop firing + bool useInitialSpawns; // toggled by a map restart to be active for the first game spawn + int latchedTeam; // need to track when team gets changed + int tourneyRank; // for tourney cycling - the higher, the more likely to play next - server + int tourneyLine; // client side - our spot in the wait line. 0 means no info. + int spawnedTime; // when client first enters the game + + idEntityPtr teleportEntity; // while being teleported, this is set to the entity we'll use for exit + int teleportKiller; // entity number of an entity killing us at teleporter exit + bool lastManOver; // can't respawn in last man anymore (srv only) + bool lastManPlayAgain; // play again when end game delay is cancelled out before expiring (srv only) + bool lastManPresent; // true when player was in when game started (spectators can't join a running LMS) + bool isLagged; // replicated from server, true if packets haven't been received from client. + bool isChatting; // replicated from server, true if the player is chatting. + + // timers + int minRespawnTime; // can respawn when time > this, force after g_forcerespawn + int maxRespawnTime; // force respawn after this time + + // the first person view values are always calculated, even + // if a third person view is used + idVec3 firstPersonViewOrigin; + idMat3 firstPersonViewAxis; + + idDragEntity dragEntity; + + // A pointer to our weaponslot. + CInventoryCursorPtr m_WeaponCursor; + // A pointer to the current map/floorplan. + CInventoryCursorPtr m_MapCursor; + // The name of the item that was current before pressing inventory clear + idStr m_LastItemNameBeforeClear; + + // The currently active inventory map entity + idEntityPtr m_ActiveInventoryMapEnt; + + int m_WaitUntilReadyGuiHandle; + int m_WaitUntilReadyGuiTime; + +public: + CLASS_PROTOTYPE( idPlayer ); + + idPlayer(); + virtual ~idPlayer(); + + void Spawn( void ); + void Think( void ); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + virtual void Hide( void ); + virtual void Show( void ); + + void Init( void ); + void PrepareForRestart( void ); + virtual void Restart( void ); + void LinkScriptVariables( void ); + void SetupWeaponEntity( void ); + void SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles ); + void SpawnFromSpawnSpot( void ); + void SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles ); + void SetClipModel( void ); // spectator mode uses a different bbox size + + void SavePersistantInfo( void ); + void RestorePersistantInfo( void ); + + bool UserInfoChanged( bool canModify ); + idDict * GetUserInfo( void ); + bool BalanceTDM( void ); + + void CacheWeapons( void ); + + void EnterCinematic( void ); + void ExitCinematic( void ); + bool HandleESC( void ); + bool SkipCinematic( void ); + + int GetImmobilization(); + int GetImmobilization( const char *source ); + void SetImmobilization( const char *source, int type ); + + // greebo: Consolidate these three hinderances into one, selectable via an enum? + float GetHinderance(); + float GetTurnHinderance(); + float GetJumpHinderance(); + + /** + * Sets the linear movement hinderance. + * This should be a fraction relative to max movement speed + * mCap values multiply together with those of other hinderances, aCap is an absolute cap + * for this particular hinderance. + **/ + void SetHinderance( const char *source, float mCap, float aCap ); + /** + * Same as SetHinderance, but applies to angular view turning speed + **/ + void SetTurnHinderance( const char *source, float mCap, float aCap ); + + void SetJumpHinderance( const char *source, float mCap, float aCap ); + + // greebo: Sets the "player is pushing something heavy" state to the given bool (virtual override) + virtual void SetIsPushing(bool isPushing); + // Returns whether the player is currently pushing something heavy (virtual override) + virtual bool IsPushing(); + + // Called by the grabber to signal that we start/stop shouldering a body + void OnStartShoulderingBody(idEntity* body); + void OnStopShoulderingBody(idEntity* body); + + /** + * greebo: Plays the footstep sound according to the current movement type. + */ + virtual void PlayFootStepSound(); + + void UpdateConditions( void ); + void SetViewAngles( const idAngles &angles ); + + // delta view angles to allow movers to rotate the view of the player + void UpdateDeltaViewAngles( const idAngles &angles ); + + /** + * Get or set the listener location for the player, in world coordinates + **/ + idVec3 GetListenerLoc( void ); + void SetListenerLoc( idVec3 loc ); + + /** + * Set/Get the door listening location + **/ + void SetDoorListenLoc( idVec3 loc ); + idVec3 GetDoorListenLoc( void ); + + + void CrashLand( const idVec3 &savedOrigin, const idVec3 &savedVelocity ); + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + + virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const; + virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ); + virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); + void CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef, + const float damageScale, const int location, int *health, int *armor ); + virtual void Damage + ( + idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision = NULL + ); + + // use exitEntityNum to specify a teleport with private camera view and delayed exit + virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); + + void Kill( bool delayRespawn, bool nodamage ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + void StartFxOnBone(const char *fx, const char *bone); + + renderView_t * GetRenderView( void ); + void CalculateRenderView( void ); // called every tic by player code + void CalculateFirstPersonView( void ); + + void DrawHUD( idUserInterface *hud ); + + void WeaponFireFeedback( const idDict *weaponDef ); + + float DefaultFov( void ) const; + float CalcFov( bool honorZoom ); + void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ); + idVec3 GetEyePosition( void ) const; + void GetViewPos( idVec3 &origin, idMat3 &axis ) const; + void OffsetThirdPersonView( float angle, float range, float height, bool clip ); + + bool Give( const char *statname, const char *value ); + void GiveItem( const char *name ); + void GiveHealthPool( float amt ); + + bool GivePowerUp( int powerup, int time ); + float PowerUpModifier( int type ); + + int SlotForWeapon( const char *weaponName ); + void Reload( void ); + void NextWeapon( void ); + void NextBestWeapon( void ); + void PrevWeapon( void ); + + // greebo: Returns the highest weapon index in the weapon inventory category (-1 if empty/error) + // Traverses the entire category, so this is not the fastest code + int GetHightestWeaponIndex(); + + // returns FALSE if the weapon with the requested index could not be selected + bool SelectWeapon( int num, bool force ); + + /** + * greebo: This returns the current weapon being focused at by the weapon inventory cursor. + * Can return NULL, but should not in 99% of the cases. + */ + CInventoryWeaponItemPtr GetCurrentWeaponItem(); + + /** + * greebo: Returns the inventory weapon item with the given name (e.g. "shortsword" or "broadhead"). + * This can actually return NULL if no weapon item with the given name exists. + */ + CInventoryWeaponItemPtr GetWeaponItem(const idStr& weaponName); + + void DropWeapon( bool died ) ; + void StealWeapon( idPlayer *player ); + void AddProjectilesFired( int count ); + void AddProjectileHits( int count ); + void SetLastHitTime( int time ); + void LowerWeapon( void ); + void RaiseWeapon( void ); + void WeaponLoweringCallback( void ); + void WeaponRisingCallback( void ); + void RemoveWeapon( const char *weap ); + bool CanShowWeaponViewmodel( void ) const; + // greebo: This method updates the player's movement hinderance when weapons are drawn + void UpdateWeaponEncumbrance(); + + void AdjustHeartRate( int target, float timeInSecs, float delay, bool force ); + void SetCurrentHeartRate( void ); + int GetBaseHeartRate( void ); + void UpdateAir( void ); + + /** + * This updates the audiovisual effects when the player is underwater + */ + void UpdateUnderWaterEffects(); + + /** + * greebo: Accessor methods for the airTicks member variable. + */ + int getAirTicks() const; + void setAirTicks(int airTicks); + + virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ); +#if 0 + bool GuiActive( void ) { return focusGUIent != NULL; } +#endif + + void PerformImpulse( int impulse ); + + /** + * greebo: This gets called by the ButtonStateTracker helper class + * whenever a key is released. + * + * @impulse: The impulse number + * @holdTime: The time the button has been held down + */ + void PerformKeyRelease(int impulse, int holdTime); + + /** + * sparhawk: This gets called by the ButtonStateTracker helper class + * whenever a key is held. + * + * @impulse: The impulse number + * @holdTime: The time the button has been held down + */ + void PerformKeyRepeat(int impulse, int holdTime); + + /** + * Ishtvan: Start tracking a mouse gesture that started when the key "impulse" was pressed + * Discretizes analog mouse movement into a few different gesture possibilities + * "Impulse" arg can also be a "button," see the UB_* enum in usercmdgen.h + * + * Waits until the threshold mouse input is reached before deciding + * The test argument determines what to test for (up/down, left/right, etc) + * determined by the enum EMouseTest + * TurnHinderane sets the max palyer view turn rate when checking this mouse gesture + * 0 => player view locked, 1.0 => no effect on view turning + * DecideTime is the time in milliseconds after which the mouse gesture is auto-decided, + * in the event that the mouse movement threshold was not reached. + * For now, only one mouse gesture check at a time. + **/ + void StartMouseGesture( int impulse, int thresh, EMouseTest test, bool bInverted, float TurnHinderance, int DecideTime = -1, int DeadTime = 0 ); + void UpdateMouseGesture( void ); + void StopMouseGesture( void ); + /** + * Returns the result of the last mouse gesture (MOUSEDIR_* enum) + **/ + EMouseDir GetMouseGesture( void ); + + void Spectate( bool spectate ); + void ToggleScoreboard( void ); + + void RouteGuiMouse( idUserInterface *gui ); + void UpdateHUD(); + + // greebo: Checks if any messages are still pending. + void UpdateHUDMessages(); + + // Updates the HUD for the inventory items + void UpdateInventoryHUD(); + void UpdateInventoryPickedUpMessages(); + + void SetInfluenceFov( float fov ); + void SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent ); + void SetInfluenceLevel( int level ); + int GetInfluenceLevel( void ) { return influenceActive; }; + void SetPrivateCameraView( idCamera *camView ); + idCamera * GetPrivateCameraView( void ) const { return privateCameraView; } + void StartFxFov( float duration ); + void UpdateHudWeapon( bool flashWeapon = true ); + void UpdateHudStats( idUserInterface *hud ); + void UpdateHudAmmo(); + + virtual void ClientPredictionThink( void ); + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + void WritePlayerStateToSnapshot( idBitMsgDelta &msg ) const; + void ReadPlayerStateFromSnapshot( const idBitMsgDelta &msg ); + + virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg ); + + virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); + virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); + + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + bool IsReady( void ); + bool IsRespawning( void ); + bool IsInTeleport( void ); + + idEntity *GetInfluenceEntity( void ) { return influenceEntity; }; + const idMaterial *GetInfluenceMaterial( void ) { return influenceMaterial; }; + float GetInfluenceRadius( void ) { return influenceRadius; }; + + // server side work for in/out of spectate. takes care of spawning it into the world as well + void ServerSpectate( bool spectate ); + // for very specific usage. != GetPhysics() + idPhysics *GetPlayerPhysics( void ); + void TeleportDeath( int killer ); + void SetLeader( bool lead ); + bool IsLeader( void ); + + void UpdateSkinSetup( bool restart ); + + bool OnLadder( void ) const; + // Virtal override of idActor::OnElevator() + virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; + + virtual void UpdatePlayerIcons( void ); + virtual void DrawPlayerIcons( void ); + virtual void HidePlayerIcons( void ); + bool NeedsIcon( void ); + + bool SelfSmooth( void ); + + void SetSelfSmooth( bool b ); + + + /** + * Do the frobbing trace and bounds intersection to mark entities as frobable + **/ + void PerformFrobCheck(); + + /** + * greebo: Performs a frob action on the given entity. The above method + * PerformFrob() without arguments redirects the call to this one. + * This method might be invoked by scripts as well to simulate + * a frob action without having the player to hit any buttons. + * + * @impulseState: the button state of the frob key. Pass EPressed if you + * want to simulate a one-time frob event. + * + * Hold time: The amount of time the button has been held, if applicable (0 by default) + */ + void PerformFrob(EImpulseState impulseState, idEntity* frobbed); + + // Gets called when the player hits the frob button. + void PerformFrob(); + // Gets repeatedly called when the player holds down the frob button + void PerformFrobKeyRepeat(int holdTime); + // Gets called when the player releases the frob button + void PerformFrobKeyRelease(int holdTime); + + + // angua: Set ideal crouch state + void EvaluateCrouch(); + + ID_INLINE bool GetIdealCrouchState() + { + return m_IdealCrouchState; + } + + + /** + * CalculateWeakLightgem (formerly AdjustLightgem) will do the "weak" + * lightgem calculation, based on a list of lights, not using the rendershot. + */ + void CalculateWeakLightgem(); + + // Register/unregister a light for the weak lightgem calculation + int AddLight(idLight* lightToAdd); + int RemoveLight(idLight* lightToRemove); + + /** + * GetHeadEntity will return the entity for the head of the playermodel + */ + idEntity *GetHeadEntity(void) { return head.GetEntity(); }; + + /** + * Update movement volumes: Reads the movement volume + * modifiers from cvars (for now) + **/ + void UpdateMoveVolumes( void ); + + /** + * Get the volume modifier for a given movement type + **/ + float GetMovementVolMod( void ); + + /** + * greebo: Cycles through the inventory and opens the next map. + * If no map is displayed currently, the first map is toggled. + * If there is a map currently on the HUD, the next one is chosen. + * If there is no next map, the map is closed again. + */ + void NextInventoryMap(); + + // Shows/hides the in-game objectives GUI + void ToggleObjectivesGUI(); + + /** + * Physically test whether an item would fit in the world when + * dropped with its center of mass (not origin!) at the specified point + * Initially tries the supplied orientation, and tries all possible 90 degree + * rotations, overwriting the supplied orientation with the one that fits + **/ + bool TestDropItemRotations( idEntity *ent, idVec3 viewPoint, idVec3 DropPoint, idMat3 &DropAxis ); + + /** + * Uses the currently held/selected item. + **/ + void UseInventoryItem(); + + /** + * Tries to drop the currently held/selected item. + **/ + void DropInventoryItem(); + + /** + * Physically put the item in the hands, returns true if it fits + * Called by DropInventoryItem, also called from Grabber::Dequip + * When dropping an item from the inventory, item argument should be supplied + * When dropping other objects (e.g., equipped junk item), it need not be + **/ + bool DropToHands( idEntity *ent, CInventoryItemPtr item = CInventoryItemPtr() ); + + // Performs the inventory action for onButtonRelease + void InventoryUseKeyRelease(int holdTime); + + // Uses a specific inventory item + bool UseInventoryItem(EImpulseState nState, const CInventoryItemPtr& item, int holdTime, bool isFrobUse); + + // Changes the inventory selection to the item with the given name + // Returns false if there is no such item + bool SelectInventoryItem(const idStr& name); + + // Override idEntity method to get notified upon item changes + virtual void OnInventoryItemChanged(); + + // Override idEntity method: the "selection changed" event is called after the inventory cursor has changed its position + virtual void OnInventorySelectionChanged(const CInventoryItemPtr& prevItem); + + /** + * Overload the idEntity::AddToInventory method to catch weapon items. + */ + virtual CInventoryItemPtr AddToInventory(idEntity *ent); + + /** + * greebo: Attempts to put the current grabber item back into the inventory. + * + * @returns: TRUE if an item was put back, FALSE if the grabber hands are empty. + */ + bool AddGrabberEntityToInventory(); + + // Returns the current lightgem value + int GetCurrentLightgemValue() { return m_LightgemValue; } + + // Runs the (strong) lightgem calculation, returns the resulting value + int ProcessLightgem(bool processing); + + /** + * greebo: Returns the lightgem modifier value according to the currently selected inventory items + * and other factors (like crouching). Returns a value between 0 and DARKMOD_LG_MAX. + * This value is added to the calculated lightgem value. + */ + int GetLightgemModifier(int curLightgemValue); + + /// Am I a ranged threat to the given entity (or entities in general if target is NULL)? + float RangedThreatTo(idEntity* target); + + // greebo: Sends a message to the HUD (used for "Game Saved" and such). + void SendHUDMessage(const idStr& text); + + // greebo: Sends a "picked up so and so" message to the inventory HUD + void SendInventoryPickedUpMessage(const idStr& text); + + // Updates the in-game Objectives GUI, if visible (otherwise nothing happens) + void UpdateObjectivesGUI(); + + void PrintDebugHUD(); + + // Runs the "Click when ready" GUI, returns TRUE if the player is ready + bool WaitUntilReady(); + + /** + * greebo: Sets the time between health "pulses" if the healthPool > 0 + * + * @newTimeInterval: the new value for the time interval + * @factor: The factor that the time interval is being multiplied with after each pulse. + * This can be used to increase the time between pulses gradually. + * @stepAmount: The amount of health to be taken from the healthpool at each step + */ + void setHealthPoolTimeInterval(int newTimeInterval, float factor, int stepAmount); + + + /** + * Get the current idLocation entity for the location the player is in + **/ + idLocationEntity *GetLocation( void ); + +protected: + /** + * greebo: This creates all the default inventory items and adds the weapons. + */ + void SetupInventory(); + + void AddPersistentInventoryItems(); + + // greebo: Methods used to manage the GUI layer for the in-game objectives + void CreateObjectivesGUI(); + void DestroyObjectivesGUI(); + + /** + * greebo: Parses the spawnargs for any weapon definitions and adds them + * to the inventory. Expects the weapon category to exist. + */ + void AddWeaponsToInventory(); + + // Sorts the weapon item category by weapon index + void SortWeaponItems(); + +private: + jointHandle_t hipJoint; + jointHandle_t chestJoint; + jointHandle_t headJoint; + + idPhysics_Player physicsObj; // player physics + + idList aasLocation; // for AI tracking the player + + int bobFoot; + float bobFrac; + float bobfracsin; + int bobCycle; // for view bobbing and footstep generation + float xyspeed; + int stepUpTime; + float stepUpDelta; + float idealLegsYaw; + float legsYaw; + bool legsForward; + float oldViewYaw; + idAngles viewBobAngles; + idVec3 viewBob; + int landChange; + int landTime; + int lastFootstepPlaytime; + bool isPushing; // is true while the player is pushing something heavy + + int currentWeapon; + int idealWeapon; + int previousWeapon; + int weaponSwitchTime; + bool weaponEnabled; + bool showWeaponViewModel; + + const idDeclSkin * skin; + const idDeclSkin * powerUpSkin; + idStr baseSkinName; + + int numProjectilesFired; // number of projectiles fired + int numProjectileHits; // number of hits on mobs + + bool airless; + int airTics; // set to pm_airTics at start, drops in vacuum + int lastAirDamage; + + bool underWaterEffectsActive; // True, if the under water effects are in charge + int underWaterGUIHandle; // The handle of the GUI underwater overlay + + bool gibDeath; + bool gibsLaunched; + idVec3 gibsDir; + int m_InventoryOverlay; + + // The GUI handle used by the in-game objectives display + int objectivesOverlay; + + idInterpolate zoomFov; + idInterpolate centerView; + bool fxFov; + + float influenceFov; + int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement + idEntity * influenceEntity; + const idMaterial * influenceMaterial; + float influenceRadius; + const idDeclSkin * influenceSkin; + + idCamera * privateCameraView; + + /** + * Location of the player's ears for sound rendering + **/ + idVec3 m_ListenerLoc; + + /** + * Location of the player's ear point when the player is leaning against + * a door (i.e., a point on the other side of the door) + **/ + idVec3 m_DoorListenLoc; + + /** + * m_immobilization keeps track of sources of immobilization. + * m_immobilizationCache caches the total immobilization so it + * only gets recalculated when something is changed. + **/ + idDict m_immobilization; + int m_immobilizationCache; + + /** + * m_hinderance keeps track of sources of hinderance. (slowing the player) + * m_hinderanceCache caches the current hinderance level so it + * only gets recalculated when something is changed. + **/ + idDict m_hinderance; + float m_hinderanceCache; + + /** + * m_TurnHinderance keeps track of sources of turn hinderance. + * These slow down the rate at which the player can turn their view + * m_TurnHinderanceCache works the same as m_hinderanceCache above + **/ + idDict m_TurnHinderance; + float m_TurnHinderanceCache; + + /** + * m_JumpHinderance keeps track of sources of jump height hinderance. + * These limit the height which the player can jump. + * m_JumpHinderanceCache works the same as m_hinderanceCache above + **/ + idDict m_JumpHinderance; + float m_JumpHinderanceCache; + + /** + * greebo: This is the list of named lightgem modifier values. These can be accessed + * via script events to allow several modifiers to be active at the same time. + * To save for performance, the sum of these values is stored in m_LightgemModifier + */ + std::map m_LightgemModifierList; + + // greebo: The sum of the values in the above list + int m_LightgemModifier; + + /** + * Each light entity must register here itself. This is used + * to calculate the value for the weak lightgem. + */ + idList m_LightList; + + /** + * LightgemValue determines the level of visibility of the player. + * This value is used to light up the lightgem and is defined as + * DARKMOD_LG_MIN (1) <= N <= DARKMOG_LG_MAX (32) + */ + int m_LightgemValue; + + /** + * Contains the last lightgem value. This is stored for interleaving. + */ + float m_fColVal; + float m_fBlendColVal; // Store the result for smooth fading of lightgem - J.C.Denton + + // An integer keeping track of the lightgem interleaving + int m_LightgemInterleave; + + // grayman #597 - ignore attack button if depressed, but weapon has been lowered + bool ignoreWeaponAttack; + + static const int NUM_LOGGED_VIEW_ANGLES = 64; // for weapon turning angle offsets + idAngles loggedViewAngles[NUM_LOGGED_VIEW_ANGLES]; // [gameLocal.framenum&(LOGGED_VIEW_ANGLES-1)] + static const int NUM_LOGGED_ACCELS = 16; // for weapon turning angle offsets + loggedAccel_t loggedAccel[NUM_LOGGED_ACCELS]; // [currentLoggedAccel & (NUM_LOGGED_ACCELS-1)] + int currentLoggedAccel; + + // if there is a focusGUIent, the attack button will be changed into mouse clicks +#if 0 + idEntity * focusGUIent; + idUserInterface * focusUI; // focusGUIent->renderEntity.gui, gui2, or gui3 + idAI * focusCharacter; + int talkCursor; // show the state of the focusCharacter (0 == can't talk/dead, 1 == ready to talk, 2 == busy talking) + int focusTime; + idAFEntity_Vehicle * focusVehicle; +#endif + idUserInterface * cursor; + + // full screen guis track mouse movements directly + int oldMouseX; + int oldMouseY; + + bool tipUp; + + int lastDamageDef; + idVec3 lastDamageDir; + int lastDamageLocation; + int smoothedFrame; + bool smoothedOriginUpdated; + idVec3 smoothedOrigin; + idAngles smoothedAngles; + + // mp + bool ready; // from userInfo + bool respawning; // set to true while in SpawnToPoint for telefrag checks + bool leader; // for sudden death situations + int lastSpectateChange; + int lastTeleFX; + unsigned int lastSnapshotSequence; // track state hitches on clients + bool weaponCatchup; // raise up the weapon silently ( state catchups ) + int MPAim; // player num in aim + int lastMPAim; + int lastMPAimTime; // last time the aim changed + int MPAimFadeTime; // for GUI fade + bool MPAimHighlight; + bool isTelefragged; // proper obituaries + + idPlayerIcon playerIcon; + + bool selfSmooth; + + + void LookAtKiller( idEntity *inflictor, idEntity *attacker ); + + void StopFiring( void ); + void FireWeapon( void ); + void BlockWeapon( void ); + void Weapon_Combat( void ); +#if 0 + void Weapon_NPC( void ); +#endif + void Weapon_GUI( void ); + void UpdateWeapon( void ); + + /** + * greebo: Changes the projectileDef name of the weapon inventory item with the given name. + * The name is defined in the "inv_weapon_name" spawnarg in the weaponDef. + */ + void ChangeWeaponProjectile(const idStr& weaponName, const idStr& projectileDefName); + + // greebo: Resets the weapon projectile as originally defined in the weaponDef + void ResetWeaponProjectile(const idStr& weaponName); + + /** + * greebo: Changes the name of the given weapon item to a new string. Pass an empty string "" to this + * function to reset the name to the value defined in the weaponDef. + */ + void ChangeWeaponName(const idStr& weaponName, const idStr& displayName); + + void UpdateSpectating( void ); + void SpectateFreeFly( bool force ); // ignore the timeout to force when followed spec is no longer valid + void SpectateCycle( void ); + idAngles GunTurningOffset( void ); + idVec3 GunAcceleratingOffset( void ); + + void UseObjects( void ); + void BobCycle( const idVec3 &pushVelocity ); + void UpdateViewAngles( void ); + void EvaluateControls( void ); + void AdjustSpeed( void ); + void AdjustBodyAngles( void ); + void InitAASLocation( void ); + void SetAASLocation( void ); + void Move( void ); + void UpdatePowerUps( void ); + void UpdateDeathSkin( bool state_hitch ); + void SetSpectateOrigin( void ); + +#if 0 + void ClearFocus( void ); + void UpdateFocus( void ); +#endif + + void UpdateLocation( void ); + idUserInterface * ActiveGui( void ); + void ExtractEmailInfo( const idStr &email, const char *scan, idStr &out ); + + void UseVehicle( void ); + + void ClearActiveInventoryMap(); + + // Considers item limits as defined in atdm:campaign_info entities placed in the map + // All items exceeding the defined limits are removed from the player's inventory + void EnforcePersistentInventoryItemLimits(); + + void Event_GetButtons( void ); + void Event_GetMove( void ); + void Event_GetViewAngles( void ); + void Event_StopFxFov( void ); + void Event_EnableWeapon( void ); + void Event_DisableWeapon( void ); + void Event_GetCurrentWeapon( void ); + void Event_GetPreviousWeapon( void ); + void Event_SelectWeapon( const char *weaponName ); + void Event_GetWeaponEntity( void ); + void Event_ExitTeleporter( void ); + void Event_Gibbed( void ); + void Event_GetIdealWeapon( void ); + void Event_RopeRemovalCleanup( idEntity *RopeEnt ); + + +/** +* TDM Events +**/ + void Event_GetEyePos( void ); + void Event_SetImmobilization( const char *source, int type ); + void Event_GetImmobilization( const char *source ); + void Event_GetNextImmobilization( const char *prefix, const char *lastMatch ); + void Event_SetHinderance( const char *source, float mCap, float aCap ); + void Event_GetHinderance( const char *source ); + void Event_GetNextHinderance( const char *prefix, const char *lastMatch ); + void Event_SetTurnHinderance( const char *source, float mCap, float aCap ); + void Event_GetTurnHinderance( const char *source ); + void Event_GetNextTurnHinderance( const char *prefix, const char *lastMatch ); + + + void Event_SetGui( int handle, const char *guiFile ); + void Event_GetInventoryOverlay(void); + + void Event_PlayStartSound( void ); + + // greebo: Gets posted when the player is dead and the "custom_death_delay" spawnarg is set to a positive value on worldspawn + void Event_CustomDeath(); + + void Event_MissionFailed( void ); + void Event_LoadDeathMenu( void ); + + void Event_HoldEntity( idEntity *ent ); + void Event_HeldEntity( void ); + + /** + * Return the last mouse gesture result to the script + **/ + void Event_GetMouseGesture( void ); + /** + * Return to script whether we are currently waiting for a mouse gesture to finish + **/ + void Event_MouseGestureFinished( void ); + /** + * Clear the mouse dead time if it extends beyond the time used to determine the gesture + **/ + void Event_ClearMouseDeadTime( void ); + + /** + * greebo: Sets the named lightgem modifier to a particular value. + * Setting the modifier to 0 removes it from the internal list. + */ + void Event_SetLightgemModifier(const char* modifierName, int amount); + + /** + * greebo: Reads the lightgem modifier setting from the worldspawn entity (defaults to 0). + */ + void Event_ReadLightgemModifierFromWorldspawn(); + + /** + * NOTE: The following objective functions all take the "user" objective indices + * That is, the indices start at 1 instead of 0 + * + * If the objective/component for that index was not found + * The getters return -1 for completion state and FALSE for component state + **/ + void Event_SetObjectiveState( int ObjIndex, int State ); + void Event_GetObjectiveState( int ObjIndex ); + void Event_SetObjectiveComp( int ObjIndex, int CompIndex, int bState ); + void Event_GetObjectiveComp( int ObjIndex, int CompIndex ); + void Event_ObjectiveUnlatch( int ObjIndex ); + void Event_ObjectiveComponentUnlatch( int ObjIndex, int CompIndex ); + void Event_SetObjectiveVisible( int ObjIndex, bool bVal ); + void Event_SetObjectiveOptional( int ObjIndex, bool bVal ); + void Event_SetObjectiveOngoing( int ObjIndex, bool bVal ); + void Event_SetObjectiveEnabling( int ObjIndex, const char *strIn ); + + /** + * greebo: This scriptevent routes the call to the member method "GiveHealthPool". + */ + void Event_GiveHealthPool( float amount ); + + /** Returns true if we were damaged this frame **/ + void Event_WasDamaged( void ); + + /** + * greebo: These scriptevents handle the player zoom in/out behaviour. + */ + void Event_StartZoom(float duration, float startFOV, float endFOV); + void Event_EndZoom(float duration); + void Event_ResetZoom(); + void Event_GetFov(); + + // Objectives GUI-related events + void Event_Pausegame(); + void Event_Unpausegame(); + + // Ends the game (fade out, success.gui, etc.) + void Event_MissionSuccess(); + + // greebo: This event prepares the running map for mission success. + // Basically waits for any HUD messages and fades out the screen, afterwards + // the Mission Success event is called. + void Event_TriggerMissionEnd(); + + // Disconnects the player from the mission, this is the final action during gameplay + void Event_DisconnectFromMission(); + + /** Returns to script the current idLocation of the player **/ + void Event_GetLocation(); + + // Gets called in the first few frames + void Event_StartGamePlayTimer(); + + // Checks the AAS status and displays the HUD warning + void Event_CheckAAS(); + + // Changes the projectile def name of the given weapon inventory item + void Event_ChangeWeaponProjectile(const char* weaponName, const char* projectileDefName); + void Event_ResetWeaponProjectile(const char* weaponName); + void Event_ChangeWeaponName(const char* weaponName, const char* newName); + void Event_GetCurWeaponName(); + + // Clears any active inventory maps + void Event_ClearActiveInventoryMap(); + + // Sets the currently active map (feedback method for inventory map scripts) + void Event_SetActiveInventoryMapEnt(idEntity* mapEnt); + + // return the frobbed entity + void Event_GetFrobbed(); + // enables "frob only ents used by active inventory item" mode + void Event_SetFrobOnlyUsedByInv( bool Value ); + + // Call gameLocal.ProcessInterMissionTriggers + void Event_ProcessInterMissionTriggers(); + +}; + +ID_INLINE bool idPlayer::IsReady( void ) { + return ready || forcedReady; +} + +ID_INLINE bool idPlayer::IsRespawning( void ) { + return respawning; +} + +ID_INLINE idPhysics* idPlayer::GetPlayerPhysics( void ) { + return &physicsObj; +} + +ID_INLINE bool idPlayer::IsInTeleport( void ) { + return ( teleportEntity.GetEntity() != NULL ); +} + +ID_INLINE void idPlayer::SetLeader( bool lead ) { + leader = lead; +} + +ID_INLINE bool idPlayer::IsLeader( void ) { + return leader; +} + +ID_INLINE bool idPlayer::SelfSmooth( void ) { + return selfSmooth; +} + +ID_INLINE void idPlayer::SetSelfSmooth( bool b ) { + selfSmooth = b; +} + +#endif /* !__GAME_PLAYER_H__ */ + diff --git a/game/PlayerIcon.cpp b/game/PlayerIcon.cpp new file mode 100644 index 000000000..ace5f65e2 --- /dev/null +++ b/game/PlayerIcon.cpp @@ -0,0 +1,176 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "PlayerIcon.h" + +static const char * iconKeys[ ICON_NONE ] = { + "mtr_icon_lag", + "mtr_icon_chat" +}; + +/* +=============== +idPlayerIcon::idPlayerIcon +=============== +*/ +idPlayerIcon::idPlayerIcon() { + iconHandle = -1; + iconType = ICON_NONE; +} + +/* +=============== +idPlayerIcon::~idPlayerIcon +=============== +*/ +idPlayerIcon::~idPlayerIcon() { + FreeIcon(); +} + +/* +=============== +idPlayerIcon::Draw +=============== +*/ +void idPlayerIcon::Draw( idPlayer *player, jointHandle_t joint ) { + idVec3 origin; + idMat3 axis; + + if ( joint == INVALID_JOINT ) { + FreeIcon(); + return; + } + + player->GetJointWorldTransform( joint, gameLocal.time, origin, axis ); + origin.z += 16.0f; + + Draw( player, origin ); +} + +/* +=============== +idPlayerIcon::Draw +=============== +*/ +void idPlayerIcon::Draw( idPlayer *player, const idVec3 &origin ) { + idPlayer *localPlayer = gameLocal.GetLocalPlayer(); + if ( !localPlayer || !localPlayer->GetRenderView() ) { + FreeIcon(); + return; + } + + idMat3 axis = localPlayer->GetRenderView()->viewaxis; + + if ( player->isLagged ) { + // create the icon if necessary, or update if already created + if ( !CreateIcon( player, ICON_LAG, origin, axis ) ) { + UpdateIcon( player, origin, axis ); + } + } else if ( player->isChatting ) { + if ( !CreateIcon( player, ICON_CHAT, origin, axis ) ) { + UpdateIcon( player, origin, axis ); + } + } else { + FreeIcon(); + } +} + +/* +=============== +idPlayerIcon::FreeIcon +=============== +*/ +void idPlayerIcon::FreeIcon( void ) { + if ( iconHandle != - 1 ) { + gameRenderWorld->FreeEntityDef( iconHandle ); + iconHandle = -1; + } + iconType = ICON_NONE; +} + +/* +=============== +idPlayerIcon::CreateIcon +=============== +*/ +bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ) { + assert( type != ICON_NONE ); + const char *mtr = player->spawnArgs.GetString( iconKeys[ type ], "_default" ); + return CreateIcon( player, type, mtr, origin, axis ); +} + +/* +=============== +idPlayerIcon::CreateIcon +=============== +*/ +bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ) { + assert( type != ICON_NONE ); + + if ( type == iconType ) { + return false; + } + + FreeIcon(); + + memset( &renderEnt, 0, sizeof( renderEnt ) ); + renderEnt.origin = origin; + renderEnt.axis = axis; + renderEnt.shaderParms[ SHADERPARM_RED ] = 1.0f; + renderEnt.shaderParms[ SHADERPARM_GREEN ] = 1.0f; + renderEnt.shaderParms[ SHADERPARM_BLUE ] = 1.0f; + renderEnt.shaderParms[ SHADERPARM_ALPHA ] = 1.0f; + renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ] = 16.0f; + renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ] = 16.0f; + renderEnt.hModel = renderModelManager->FindModel( "_sprite" ); + renderEnt.callback = NULL; + renderEnt.numJoints = 0; + renderEnt.joints = NULL; + renderEnt.customSkin = 0; + renderEnt.noShadow = true; + renderEnt.noSelfShadow = true; + renderEnt.customShader = declManager->FindMaterial( mtr ); + renderEnt.referenceShader = 0; + renderEnt.bounds = renderEnt.hModel->Bounds( &renderEnt ); + + iconHandle = gameRenderWorld->AddEntityDef( &renderEnt ); + iconType = type; + + return true; +} + +/* +=============== +idPlayerIcon::UpdateIcon +=============== +*/ +void idPlayerIcon::UpdateIcon( idPlayer *player, const idVec3 &origin, const idMat3 &axis ) { + assert( iconHandle >= 0 ); + + renderEnt.origin = origin; + renderEnt.axis = axis; + gameRenderWorld->UpdateEntityDef( iconHandle, &renderEnt ); +} + diff --git a/game/PlayerIcon.h b/game/PlayerIcon.h new file mode 100644 index 000000000..0a2267a11 --- /dev/null +++ b/game/PlayerIcon.h @@ -0,0 +1,54 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PLAYERICON_H__ +#define __PLAYERICON_H__ + +typedef enum { + ICON_LAG, + ICON_CHAT, + ICON_NONE +} playerIconType_t; + +class idPlayerIcon { +public: + +public: + idPlayerIcon(); + ~idPlayerIcon(); + + void Draw( idPlayer *player, jointHandle_t joint ); + void Draw( idPlayer *player, const idVec3 &origin ); + +public: + playerIconType_t iconType; + renderEntity_t renderEnt; + qhandle_t iconHandle; + +public: + void FreeIcon( void ); + bool CreateIcon( idPlayer* player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ); + bool CreateIcon( idPlayer* player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ); + void UpdateIcon( idPlayer* player, const idVec3 &origin, const idMat3 &axis ); + +}; + + +#endif /* !_PLAYERICON_H_ */ + diff --git a/game/PlayerView.cpp b/game/PlayerView.cpp new file mode 100644 index 000000000..4d2f0e665 --- /dev/null +++ b/game/PlayerView.cpp @@ -0,0 +1,1136 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +#include "sourcehook/sourcehook.h" + +extern SourceHook::ISourceHook *g_SHPtr; +extern int g_PLID; + +SH_DECL_HOOK2_void( idCmdSystem, BufferCommandText, SH_NOATTRIB, 0, cmdExecution_t, const char * ); + +static int MakePowerOfTwo( int num ) { + int pot; + + for (pot = 1 ; pot < num ; pot<<=1) {} + + return pot; +} + +const int IMPULSE_DELAY = 150; + +/* +============== +idPlayerView::idPlayerView +============== +*/ +idPlayerView::idPlayerView() : +m_postProcessManager() // Invoke the postprocess Manager Constructor - J.C.Denton +{ + memset( screenBlobs, 0, sizeof( screenBlobs ) ); + memset( &view, 0, sizeof( view ) ); + player = NULL; + dvMaterial = declManager->FindMaterial( "_scratch" ); + tunnelMaterial = declManager->FindMaterial( "textures/decals/tunnel" ); + armorMaterial = declManager->FindMaterial( "armorViewEffect" ); + berserkMaterial = declManager->FindMaterial( "textures/decals/berserk" ); + irGogglesMaterial = declManager->FindMaterial( "textures/decals/irblend" ); + bloodSprayMaterial = declManager->FindMaterial( "textures/decals/bloodspray" ); + lagoMaterial = declManager->FindMaterial( LAGO_MATERIAL, false ); + + dvFinishTime = 0; + kickFinishTime = 0; + kickAngles.Zero(); + lastDamageTime = 0.0f; + fadeTime = 0; + fadeRate = 0.0; + fadeFromColor.Zero(); + fadeToColor.Zero(); + fadeColor.Zero(); + shakeAng.Zero(); + + /* + fxManager = NULL; + + if ( !fxManager ) { + fxManager = new FullscreenFXManager; + fxManager->Initialize( this ); + } + */ + + ClearEffects(); + + // greebo: Set the bool to the inverse of the CVAR, so that the code triggers + // an update in the first frame + //cur_amb_method = !cv_ambient_method.GetBool(); + // JC: Just set the flag so that we know that the update is needed. + cv_ambient_method.SetModified(); + cv_interaction_vfp_type.SetModified(); // Always update interaction shader the first time. J.C.Denton +} + +/* +============== +idPlayerView::Save +============== +*/ +void idPlayerView::Save( idSaveGame *savefile ) const { + int i; + const screenBlob_t *blob; + + blob = &screenBlobs[ 0 ]; + for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) { + savefile->WriteMaterial( blob->material ); + savefile->WriteFloat( blob->x ); + savefile->WriteFloat( blob->y ); + savefile->WriteFloat( blob->w ); + savefile->WriteFloat( blob->h ); + savefile->WriteFloat( blob->s1 ); + savefile->WriteFloat( blob->t1 ); + savefile->WriteFloat( blob->s2 ); + savefile->WriteFloat( blob->t2 ); + savefile->WriteInt( blob->finishTime ); + savefile->WriteInt( blob->startFadeTime ); + savefile->WriteFloat( blob->driftAmount ); + } + + savefile->WriteInt( dvFinishTime ); + savefile->WriteMaterial( dvMaterial ); + savefile->WriteInt( kickFinishTime ); + savefile->WriteAngles( kickAngles ); + + savefile->WriteMaterial( tunnelMaterial ); + savefile->WriteMaterial( armorMaterial ); + savefile->WriteMaterial( berserkMaterial ); + savefile->WriteMaterial( irGogglesMaterial ); + savefile->WriteMaterial( bloodSprayMaterial ); + savefile->WriteFloat( lastDamageTime ); + + savefile->WriteVec4( fadeColor ); + savefile->WriteVec4( fadeToColor ); + savefile->WriteVec4( fadeFromColor ); + savefile->WriteFloat( fadeRate ); + savefile->WriteInt( fadeTime ); + + savefile->WriteAngles( shakeAng ); + + savefile->WriteObject( player ); + savefile->WriteRenderView( view ); + + // Save games are not going to work after this change - JC Denton + // savefile->WriteBool(cur_amb_method); +} + +/* +============== +idPlayerView::Restore +============== +*/ +void idPlayerView::Restore( idRestoreGame *savefile ) { + int i; + screenBlob_t *blob; + + blob = &screenBlobs[ 0 ]; + for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) { + savefile->ReadMaterial( blob->material ); + savefile->ReadFloat( blob->x ); + savefile->ReadFloat( blob->y ); + savefile->ReadFloat( blob->w ); + savefile->ReadFloat( blob->h ); + savefile->ReadFloat( blob->s1 ); + savefile->ReadFloat( blob->t1 ); + savefile->ReadFloat( blob->s2 ); + savefile->ReadFloat( blob->t2 ); + savefile->ReadInt( blob->finishTime ); + savefile->ReadInt( blob->startFadeTime ); + savefile->ReadFloat( blob->driftAmount ); + } + + savefile->ReadInt( dvFinishTime ); + savefile->ReadMaterial( dvMaterial ); + savefile->ReadInt( kickFinishTime ); + savefile->ReadAngles( kickAngles ); + + savefile->ReadMaterial( tunnelMaterial ); + savefile->ReadMaterial( armorMaterial ); + savefile->ReadMaterial( berserkMaterial ); + savefile->ReadMaterial( irGogglesMaterial ); + savefile->ReadMaterial( bloodSprayMaterial ); + savefile->ReadFloat( lastDamageTime ); + + savefile->ReadVec4( fadeColor ); + savefile->ReadVec4( fadeToColor ); + savefile->ReadVec4( fadeFromColor ); + savefile->ReadFloat( fadeRate ); + savefile->ReadInt( fadeTime ); + + savefile->ReadAngles( shakeAng ); + + savefile->ReadObject( reinterpret_cast( player ) ); + savefile->ReadRenderView( view ); + + // Save games are not going to work after this change - JC Denton + // savefile->ReadBool(cur_amb_method); + + // Re-Initialize the PostProcess Manager. - JC Denton + this->m_postProcessManager.Initialize(); +} + +/* +============== +idPlayerView::SetPlayerEntity +============== +*/ +void idPlayerView::SetPlayerEntity( idPlayer *playerEnt ) { + player = playerEnt; +} + +/* +============== +idPlayerView::ClearEffects +============== +*/ +void idPlayerView::ClearEffects() { + lastDamageTime = MS2SEC( gameLocal.time - 99999 ); + + dvFinishTime = ( gameLocal.time - 99999 ); + kickFinishTime = ( gameLocal.time - 99999 ); + + for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) { + screenBlobs[i].finishTime = gameLocal.time; + } + + fadeTime = 0; +} + +/* +============== +idPlayerView::GetScreenBlob +============== +*/ +screenBlob_t *idPlayerView::GetScreenBlob() { + screenBlob_t *oldest = &screenBlobs[0]; + + for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) { + if ( screenBlobs[i].finishTime < oldest->finishTime ) { + oldest = &screenBlobs[i]; + } + } + return oldest; +} + +/* +============== +idPlayerView::DamageImpulse + +LocalKickDir is the direction of force in the player's coordinate system, +which will determine the head kick direction +============== +*/ +void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) { + // + // double vision effect + // + if ( lastDamageTime > 0.0f && SEC2MS( lastDamageTime ) + IMPULSE_DELAY > gameLocal.time ) { + // keep shotgun from obliterating the view + return; + } + + float dvTime = damageDef->GetFloat( "dv_time" ); + if ( dvTime ) { + if ( dvFinishTime < gameLocal.time ) { + dvFinishTime = gameLocal.time; + } + dvFinishTime += static_cast(g_dvTime.GetFloat() * dvTime); + // don't let it add up too much in god mode + if ( dvFinishTime > gameLocal.time + 5000 ) { + dvFinishTime = gameLocal.time + 5000; + } + } + + // + // head angle kick + // + float kickTime = damageDef->GetFloat( "kick_time" ); + if ( kickTime ) { + kickFinishTime = gameLocal.time + static_cast(g_kickTime.GetFloat() * kickTime); + + // forward / back kick will pitch view + kickAngles[0] = localKickDir[0]; + + // side kick will yaw view + kickAngles[1] = localKickDir[1]*0.5f; + + // up / down kick will pitch view + kickAngles[0] += localKickDir[2]; + + // roll will come from side + kickAngles[2] = localKickDir[1]; + + float kickAmplitude = damageDef->GetFloat( "kick_amplitude" ); + if ( kickAmplitude ) { + kickAngles *= kickAmplitude; + } + } + + // + // screen blob + // + float blobTime = damageDef->GetFloat( "blob_time" ); + if ( blobTime ) { + screenBlob_t *blob = GetScreenBlob(); + blob->startFadeTime = gameLocal.time; + blob->finishTime = gameLocal.time + static_cast(blobTime * g_blobTime.GetFloat()); + + const char *materialName = damageDef->GetString( "mtr_blob" ); + blob->material = declManager->FindMaterial( materialName ); + blob->x = damageDef->GetFloat( "blob_x" ); + blob->x += ( gameLocal.random.RandomInt()&63 ) - 32; + blob->y = damageDef->GetFloat( "blob_y" ); + blob->y += ( gameLocal.random.RandomInt()&63 ) - 32; + + float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; + blob->w = damageDef->GetFloat( "blob_width" ) * g_blobSize.GetFloat() * scale; + blob->h = damageDef->GetFloat( "blob_height" ) * g_blobSize.GetFloat() * scale; + blob->s1 = 0; + blob->t1 = 0; + blob->s2 = 1; + blob->t2 = 1; + } + + // + // save lastDamageTime for tunnel vision accentuation + // + lastDamageTime = MS2SEC( gameLocal.time ); + +} + +/* +================== +idPlayerView::AddBloodSpray + +If we need a more generic way to add blobs then we can do that +but having it localized here lets the material be pre-looked up etc. +================== +*/ +void idPlayerView::AddBloodSpray( float duration ) { + /* + if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) { + return; + } + // visit this for chainsaw + screenBlob_t *blob = GetScreenBlob(); + blob->startFadeTime = gameLocal.time; + blob->finishTime = gameLocal.time + ( duration * 1000 ); + blob->material = bloodSprayMaterial; + blob->x = ( gameLocal.random.RandomInt() & 63 ) - 32; + blob->y = ( gameLocal.random.RandomInt() & 63 ) - 32; + blob->driftAmount = 0.5f + gameLocal.random.CRandomFloat() * 0.5; + float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; + blob->w = 600 * g_blobSize.GetFloat() * scale; + blob->h = 480 * g_blobSize.GetFloat() * scale; + float s1 = 0.0f; + float t1 = 0.0f; + float s2 = 1.0f; + float t2 = 1.0f; + if ( blob->driftAmount < 0.6 ) { + s1 = 1.0f; + s2 = 0.0f; + } else if ( blob->driftAmount < 0.75 ) { + t1 = 1.0f; + t2 = 0.0f; + } else if ( blob->driftAmount < 0.85 ) { + s1 = 1.0f; + s2 = 0.0f; + t1 = 1.0f; + t2 = 0.0f; + } + blob->s1 = s1; + blob->t1 = t1; + blob->s2 = s2; + blob->t2 = t2; + */ +} + +/* +================== +idPlayerView::WeaponFireFeedback + +Called when a weapon fires, generates head twitches, etc +================== +*/ +void idPlayerView::WeaponFireFeedback( const idDict *weaponDef ) { + int recoilTime; + + recoilTime = weaponDef->GetInt( "recoilTime" ); + // don't shorten a damage kick in progress + if ( recoilTime && kickFinishTime < gameLocal.time ) { + idAngles angles; + weaponDef->GetAngles( "recoilAngles", "5 0 0", angles ); + kickAngles = angles; + int finish = gameLocal.time + static_cast(g_kickTime.GetFloat() * recoilTime); + kickFinishTime = finish; + } + +} + +/* +=================== +idPlayerView::CalculateShake +=================== +*/ +void idPlayerView::CalculateShake() { + idVec3 origin, matrix; + + float shakeVolume = gameSoundWorld->CurrentShakeAmplitudeForPosition( gameLocal.time, player->firstPersonViewOrigin ); + // + // shakeVolume should somehow be molded into an angle here + // it should be thought of as being in the range 0.0 -> 1.0, although + // since CurrentShakeAmplitudeForPosition() returns all the shake sounds + // the player can hear, it can go over 1.0 too. + // + shakeAng[0] = gameLocal.random.CRandomFloat() * shakeVolume; + shakeAng[1] = gameLocal.random.CRandomFloat() * shakeVolume; + shakeAng[2] = gameLocal.random.CRandomFloat() * shakeVolume; +} + +/* +=================== +idPlayerView::ShakeAxis +=================== +*/ +idMat3 idPlayerView::ShakeAxis() const { + return shakeAng.ToMat3(); +} + +/* +=================== +idPlayerView::AngleOffset + +kickVector, a world space direction that the attack should +=================== +*/ +idAngles idPlayerView::AngleOffset() const { + idAngles ang; + + ang.Zero(); + + if ( gameLocal.time < kickFinishTime ) { + float offset = kickFinishTime - gameLocal.time; + + ang = kickAngles * offset * offset * g_kickAmplitude.GetFloat(); + + for ( int i = 0 ; i < 3 ; i++ ) { + if ( ang[i] > 70.0f ) { + ang[i] = 70.0f; + } else if ( ang[i] < -70.0f ) { + ang[i] = -70.0f; + } + } + } + return ang; +} + +/* +================== +idPlayerView::SingleView +================== +*/ +void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view, bool drawHUD ) { + + // normal rendering + if ( !view ) { + return; + } + + // place the sound origin for the player + // TODO: Support overriding the location area so that reverb settings can be applied for listening thru doors? + gameSoundWorld->PlaceListener( player->GetListenerLoc(), view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" ); + + // hack the shake in at the very last moment, so it can't cause any consistency problems + renderView_t hackedView = *view; + hackedView.viewaxis = hackedView.viewaxis * ShakeAxis(); + + //gameRenderWorld->RenderScene( &hackedView ); + + if ( gameLocal.portalSkyEnt.GetEntity() && gameLocal.IsPortalSkyAcive() && g_enablePortalSky.GetBool() ) { + + renderView_t portalView = hackedView; + + portalView.vieworg = gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetOrigin(); + portalView.viewaxis = portalView.viewaxis * gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetAxis(); + + // setup global fixup projection vars + if ( 1 ) { + int vidWidth, vidHeight; + idVec2 shiftScale; + + renderSystem->GetGLSettings( vidWidth, vidHeight ); + + float pot; + int w = vidWidth; + pot = MakePowerOfTwo( w ); + shiftScale.x = (float)w / pot; + + int h = vidHeight; + pot = MakePowerOfTwo( h ); + shiftScale.y = (float)h / pot; + + hackedView.shaderParms[6] = shiftScale.x; + hackedView.shaderParms[7] = shiftScale.y; + } + + gameRenderWorld->RenderScene( &portalView ); + renderSystem->CaptureRenderToImage( "_currentRender" ); + + hackedView.forceUpdate = true; // FIX: for smoke particles not drawing when portalSky present + } + + hackedView.forceUpdate = true; // Fix for lightgem problems? -Gildoran + gameRenderWorld->RenderScene( &hackedView ); + // process the frame + + // fxManager->Process( &hackedView ); + + + if ( player->spectating ) { + return; + } + + // draw screen blobs + if ( !pm_thirdPerson.GetBool() && !g_skipViewEffects.GetBool() ) { + for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) { + screenBlob_t *blob = &screenBlobs[i]; + if ( blob->finishTime <= gameLocal.time ) { + continue; + } + + blob->y += blob->driftAmount; + + float fade = (float)( blob->finishTime - gameLocal.time ) / ( blob->finishTime - blob->startFadeTime ); + if ( fade > 1.0f ) { + fade = 1.0f; + } + if ( fade ) { + renderSystem->SetColor4( 1,1,1,fade ); + renderSystem->DrawStretchPic( blob->x, blob->y, blob->w, blob->h,blob->s1, blob->t1, blob->s2, blob->t2, blob->material ); + } + } + if (drawHUD) + { + player->DrawHUD( hud ); + } + + // armor impulse feedback + float armorPulse = ( gameLocal.time - player->lastArmorPulse ) / 250.0f; + + if ( armorPulse > 0.0f && armorPulse < 1.0f ) { + renderSystem->SetColor4( 1, 1, 1, 1.0 - armorPulse ); + renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, armorMaterial ); + } + + + // tunnel vision + float health = 0.0f; + if ( g_testHealthVision.GetFloat() != 0.0f ) { + health = g_testHealthVision.GetFloat(); + } else { + health = player->health; + } + float alpha = health / 100.0f; + if ( alpha < 0.0f ) { + alpha = 0.0f; + } + if ( alpha > 1.0f ) { + alpha = 1.0f; + } + + if ( alpha < 1.0f ) { + renderSystem->SetColor4( ( player->health <= 0.0f ) ? MS2SEC( gameLocal.time ) : lastDamageTime, 1.0f, 1.0f, ( player->health <= 0.0f ) ? 0.0f : alpha ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial ); + } + + } + + // Rotoscope (Cartoon-like) rendering - (Rotoscope Shader v1.0 by Hellborg) - added by Dram + if ( g_rotoscope.GetBool() ) { + const idMaterial *mtr = declManager->FindMaterial( "textures/postprocess/rotoedge", false ); + if ( !mtr ) { + common->Printf( "Rotoscope material not found.\n" ); + } else { + renderSystem->CaptureRenderToImage( "_currentRender" ); + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr ); + } + } + + // test a single material drawn over everything + if ( g_testPostProcess.GetString()[0] ) { + const idMaterial *mtr = declManager->FindMaterial( g_testPostProcess.GetString(), false ); + if ( !mtr ) { + common->Printf( "Material not found.\n" ); + g_testPostProcess.SetString( "" ); + } else { + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr ); + } + } +} + +/* +=================== +idPlayerView::DoubleVision +=================== +*/ +void idPlayerView::DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ) { + + if ( !g_doubleVision.GetBool() ) { + SingleView( hud, view ); + return; + } + + float scale = offset * g_dvAmplitude.GetFloat(); + if ( scale > 0.5f ) { + scale = 0.5f; + } + float shift = scale * sin( sqrt( (float)offset ) * g_dvFrequency.GetFloat() ); + shift = fabs( shift ); + + // if double vision, render to a texture + renderSystem->CropRenderSize( SCREEN_WIDTH, SCREEN_HEIGHT, true ); + + // greebo: Draw the single view, but skip the HUD, this is done later + SingleView( hud, view, false ); + + renderSystem->CaptureRenderToImage( "_scratch" ); + renderSystem->UnCrop(); + + // carry red tint if in berserk mode + idVec4 color(1, 1, 1, 1); + /*if ( gameLocal.time < player->inventory.powerupEndTime[ BERSERK ] ) { + color.y = 0; + color.z = 0; + }*/ + + renderSystem->SetColor4( color.x, color.y, color.z, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, shift, 1-shift, 1, 0, dvMaterial ); + renderSystem->SetColor4( color.x, color.y, color.z, 0.5f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1-shift, shift, dvMaterial ); + + // Do not post-process the HUD - JC Denton + // Bloom related - added by Dram + // if ( r_bloom_hud.GetBool() || !r_bloom.GetBool() ) // If HUD blooming is enabled or bloom is disabled + // { + // player->DrawHUD(hud); + // } +} + +/* +=================== +idPlayerView::BerserkVision +=================== +*/ +void idPlayerView::BerserkVision( idUserInterface *hud, const renderView_t *view ) { + renderSystem->CropRenderSize( 512, 256, true ); + SingleView( hud, view ); + renderSystem->CaptureRenderToImage( "_scratch" ); + renderSystem->UnCrop(); + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, dvMaterial ); +} + + +/* +================= +idPlayerView::Flash + +flashes the player view with the given color +================= +*/ +void idPlayerView::Flash(idVec4 color, int time ) { + Fade(idVec4(0, 0, 0, 0), time); + fadeFromColor = colorWhite; +} + +/* +================= +idPlayerView::Fade + +used for level transition fades +assumes: color.w is 0 or 1 +================= +*/ +void idPlayerView::Fade( idVec4 color, int time ) { + + if ( !fadeTime ) { + fadeFromColor.Set( 0.0f, 0.0f, 0.0f, 1.0f - color[ 3 ] ); + } else { + fadeFromColor = fadeColor; + } + fadeToColor = color; + + if ( time <= 0 ) { + fadeRate = 0; + time = 0; + fadeColor = fadeToColor; + } else { + fadeRate = 1.0f / ( float )time; + } + + if ( gameLocal.realClientTime == 0 && time == 0 ) { + fadeTime = 1; + } else { + fadeTime = gameLocal.realClientTime + time; + } +} + +/* +================= +idPlayerView::ScreenFade +================= +*/ +void idPlayerView::ScreenFade() { + int msec; + float t; + + if ( !fadeTime ) { + return; + } + + msec = fadeTime - gameLocal.realClientTime; + + if ( msec <= 0 ) { + fadeColor = fadeToColor; + if ( fadeColor[ 3 ] == 0.0f ) { + fadeTime = 0; + } + } else { + t = ( float )msec * fadeRate; + fadeColor = fadeFromColor * t + fadeToColor * ( 1.0f - t ); + } + + if ( fadeColor[ 3 ] != 0.0f ) { + renderSystem->SetColor4( fadeColor[ 0 ], fadeColor[ 1 ], fadeColor[ 2 ], fadeColor[ 3 ] ); + renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) ); + } +} + +/* +=================== +idPlayerView::InfluenceVision +=================== +*/ +void idPlayerView::InfluenceVision( idUserInterface *hud, const renderView_t *view ) { + + float distance = 0.0f; + float pct = 1.0f; + if ( player->GetInfluenceEntity() ) { + distance = ( player->GetInfluenceEntity()->GetPhysics()->GetOrigin() - player->GetPhysics()->GetOrigin() ).Length(); + if ( player->GetInfluenceRadius() != 0.0f && distance < player->GetInfluenceRadius() ) { + pct = distance / player->GetInfluenceRadius(); + pct = 1.0f - idMath::ClampFloat( 0.0f, 1.0f, pct ); + } + } + if ( player->GetInfluenceMaterial() ) { + SingleView( hud, view ); + renderSystem->CaptureRenderToImage( "_currentRender" ); + + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, pct ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() ); + } else if ( player->GetInfluenceEntity() == NULL ) { + SingleView( hud, view ); + return; + } else { + int offset = static_cast(25 + sin(static_cast(gameLocal.time))); + DoubleVision( hud, view, static_cast(pct * offset) ); + } +} + +/* +=================== +idPlayerView::RenderPlayerView +=================== +*/ +void idPlayerView::RenderPlayerView( idUserInterface *hud ) +{ + const renderView_t *view = player->GetRenderView(); + + if(g_skipViewEffects.GetBool()) + { + SingleView( hud, view ); + } else { + + /*if ( player->GetInfluenceMaterial() || player->GetInfluenceEntity() ) { + InfluenceVision( hud, view ); + } else if ( gameLocal.time < dvFinishTime ) { + DoubleVision( hud, view, dvFinishTime - gameLocal.time ); + } else {*/ + + // greebo: For underwater effects, use the Doom3 Doubleview + if (static_cast(player->GetPlayerPhysics())->GetWaterLevel() >= WATERLEVEL_HEAD) + { + DoubleVision(hud, view, cv_tdm_underwater_blur.GetInteger()); + } + else + { + // Do not postprocess the HUD + // if ( r_bloom_hud.GetBool() || !r_bloom.GetBool() ) // If HUD blooming is enabled or bloom is disabled + // { + // SingleView( hud, view ); + // } + // else + { + SingleView( hud, view, false ); + } + } + //} + + // Bloom related - J.C.Denton + /* Update post-process */ + this->m_postProcessManager.Update(); + + ScreenFade(); + } + + player->DrawHUD(hud); + + + // TDM Ambient Method checking. By Dram + // Modified by JC Denton + if ( cv_ambient_method.IsModified() ) // If the ambient method option has changed + { + UpdateAmbientLight(); + } +} + +void idPlayerView::UpdateAmbientLight() +{ + // Finds a light with name set as ambient_world, or turns the ambient light with greatest radius into main ambient. + idLight* pAmbientLight = gameLocal.FindMainAmbientLight(true); + + if (pAmbientLight != NULL) // If the light exists + { + if ( 0 == cv_ambient_method.GetInteger() ) // If the Ambient Light method is used + { + gameLocal.globalShaderParms[5] = 0; // Make sure we set this flag to 0 so that materials know which pass is to be enabled. + gameLocal.globalShaderParms[2] = 0; // Set global shader parm 2 to 0 + gameLocal.globalShaderParms[3] = 0; // Set global shader parm 3 to 0 + gameLocal.globalShaderParms[4] = 0; // Set global shader parm 4 to 0 + + pAmbientLight->On(); // Turn on ambient light + } + else // If the Texture Brightness method is used + { + + gameLocal.globalShaderParms[5] = Min( 2, Max (1, cv_ambient_method.GetInteger() ) ); + idVec3 ambient_color = pAmbientLight->spawnArgs.GetVector( "_color" ); // Get the ambient color from the spawn arguments + gameLocal.globalShaderParms[2] = ambient_color.x * 1.5f; // Set global shader parm 2 to Red value of ambient light + gameLocal.globalShaderParms[3] = ambient_color.y * 1.5f; // Set global shader parm 3 to Green value of ambient light + gameLocal.globalShaderParms[4] = ambient_color.z * 1.5f; // Set global shader parm 4 to Blue value of ambient light + + pAmbientLight->Off(); // Turn off ambient light + + } + } + else // The ambient light does not exist + { + gameLocal.Printf( "Note: The main ambient light could not be determined\n"); // Show in console of light not existing in map + } + cv_ambient_method.ClearModified(); + // Clean this up later since not needed. JC Denton + // cur_amb_method = cv_ambient_method.GetBool(); // Set the current ambient method to the CVar value +} + + +/* +=================== +idPlayerView::dnPostProcessManager Class Definitions - JC Denton +=================== +*/ + +idPlayerView::dnPostProcessManager::dnPostProcessManager(): +m_imageCurrentRender ( "_currentRender" ), +m_imageBloom ( "_bloomImage" ), +m_imageCookedMath ( "_cookedMath" ), + +m_matBrightPass ( declManager->FindMaterial( "postprocess/brightPassOptimized" ) ), +m_matGaussBlurX ( declManager->FindMaterial( "postprocess/blurx" ) ), +m_matGaussBlurY ( declManager->FindMaterial( "postprocess/blury" ) ), +//m_matFinalScenePass ( declManager->FindMaterial( "postprocess/finalScenePass" ) ), +m_matFinalScenePass ( declManager->FindMaterial( "postprocess/finalScenePassOptimized" ) ), + +m_matCookMath_pass1 ( declManager->FindMaterial( "postprocess/cookMath_pass1" ) ), +m_matCookMath_pass2 ( declManager->FindMaterial( "postprocess/cookMath_pass2" ) ) +{ + + m_iScreenHeight = m_iScreenWidth = 0; + m_iScreenHeightPowOf2 = m_iScreenWidthPowOf2 = 0; + m_nFramesToUpdateCookedData = 0; + + // Initialize once this object is created. + this->Initialize(); + + SH_ADD_HOOK_MEMFUNC(idCmdSystem, BufferCommandText, cmdSystem, this, &idPlayerView::dnPostProcessManager::Hook_BufferCommandText, false ); + +} + + idPlayerView::dnPostProcessManager::~dnPostProcessManager() + { + // Remove Source Hook before closing. + SH_REMOVE_HOOK_MEMFUNC(idCmdSystem, BufferCommandText, cmdSystem, this, &idPlayerView::dnPostProcessManager::Hook_BufferCommandText, false ); + } + + void idPlayerView::dnPostProcessManager::Hook_BufferCommandText( cmdExecution_t a_eType, const char *a_pcText ) + { + // Using idStr::FindText to make sure that we account for trailing white spaces. However, even an invalid command + // e.g. like "reloadImagesADEAW" would update the cooked data, but that should not be a problem. + if( NULL != a_pcText && + ( 0 == idStr::FindText( a_pcText, "reloadimages", false ) || 0 == idStr::FindText(a_pcText, "vid_restart", false ) || 0 == idStr::FindText(a_pcText, "image_anisotropy", false ) ) + ) + { + + m_nFramesToUpdateCookedData = 1; + if( r_postprocess.GetBool() ) + gameLocal.Printf("Cooked Data will be updated after %d frames...\n", m_nFramesToUpdateCookedData ); + else + gameLocal.Printf("Cooked Data will be updated after %d frames immediately after r_postprocess is enabled.\n", m_nFramesToUpdateCookedData ); + } + + RETURN_META(MRES_IGNORED ); + } + +void idPlayerView::dnPostProcessManager::Initialize() +{ + m_bForceUpdateOnCookedData = true; + r_postprocess_bloomKernelSize.SetModified(); // This will print message in console about bloom kernel size. +} + +void idPlayerView::dnPostProcessManager::UpdateCookedData( void ) +{ + + if( m_nFramesToUpdateCookedData > 0 ) + { + m_nFramesToUpdateCookedData --; + m_bForceUpdateOnCookedData = true; + return; + } + + if ( m_bForceUpdateOnCookedData || + r_postprocess_colorCurveBias.IsModified() || r_postprocess_brightPassOffset.IsModified() || + r_postprocess_brightPassThreshold.IsModified() || r_postprocess_sceneExposure.IsModified() || + r_postprocess_sceneGamma.IsModified() || r_postprocess_colorCorrection.IsModified() || + r_postprocess_colorCorrectBias.IsModified() + ) + { + + if( m_bForceUpdateOnCookedData ) + gameLocal.Printf( "Forcing an update on cooked math data.\n" ); + + gameLocal.Printf( "Cooking math data please wait...\n" ); + + //------------------------------------------------------------------------ + // Crop backbuffer image to the size of our cooked math image + //------------------------------------------------------------------------ + renderSystem->CropRenderSize(256, 1, true); + //------------------------------------------------------------------------ + + //------------------------------------------------------------------------ + // Cook math Pass 1 + //------------------------------------------------------------------------ + renderSystem->SetColor4( r_postprocess_colorCurveBias.GetFloat(), r_postprocess_sceneGamma.GetFloat(), r_postprocess_sceneExposure.GetFloat(), 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matCookMath_pass1 ); + renderSystem->CaptureRenderToImage( m_imageCookedMath ); + + //------------------------------------------------------------------------ + // Cook math Pass 2 + //------------------------------------------------------------------------ + float fColorCurveBias = Max ( Min ( r_postprocess_colorCorrectBias.GetFloat(), 1.0f ), 0.0f ); + renderSystem->SetColor4( r_postprocess_brightPassThreshold.GetFloat(), r_postprocess_brightPassOffset.GetFloat(), r_postprocess_colorCorrection.GetFloat(), fColorCurveBias ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matCookMath_pass2 ); + renderSystem->CaptureRenderToImage( m_imageCookedMath ); + + //------------------------------------------------------------------------ + renderSystem->UnCrop(); + //------------------------------------------------------------------------ + r_postprocess_colorCurveBias.ClearModified(); + r_postprocess_brightPassOffset.ClearModified(); + r_postprocess_brightPassThreshold.ClearModified(); + r_postprocess_sceneExposure.ClearModified(); + r_postprocess_sceneGamma.ClearModified(); + r_postprocess_colorCorrection.ClearModified(); + r_postprocess_colorCorrectBias.ClearModified(); + + m_bForceUpdateOnCookedData = false; + + gameLocal.Printf( "Cooking complete.\n" ); + + //gameLocal.Printf( "Screen size: %d, %d Power of 2 Size: %d, %d", m_iScreenWidth, m_iScreenHeight, m_iScreenWidthPowOf2, m_iScreenHeightPowOf2 ); + } +} + + +void idPlayerView::dnPostProcessManager::Update( void ) +{ + float fBloomImageDownScale = Max(Min(r_postprocess_bloomKernelSize.GetInteger(), 2), 1 ) == 1 ? 2 : 4; + + if( r_postprocess_bloomKernelSize.IsModified() ) + { + gameLocal.Printf(" Bloom Kernel size is set to: %s \n", fBloomImageDownScale == 2.0f ? "Large": "Small" ); + r_postprocess_bloomKernelSize.ClearModified(); + } + + // Check the interaction.vfp settings + if( cv_interaction_vfp_type.IsModified() ) + { + this->UpdateInteractionShader(); + cv_interaction_vfp_type.ClearModified(); + } + + const int iPostProcessType = r_postprocess.GetInteger(); + + if ( iPostProcessType != 0 ) + { + this->UpdateBackBufferParameters(); + + // Note to self1: CropRenderSize if not used before CaptureRenderToImage, then image caputured is of screen's size(non power of two) + // Note to self2: CropRenderSize when used with dimensions greater than backbuffer res, automatically crops screen to res <= backbuffer res. + + renderSystem->CaptureRenderToImage( m_imageCurrentRender ); + + this->UpdateCookedData(); + + const float fBloomIntensity = r_postprocess_bloomIntensity.GetFloat(); + + if( fBloomIntensity > 0.0f ) + { + //------------------------------------------------- + // Apply the bright-pass filter to acquire bloom image + //------------------------------------------------- + renderSystem->CropRenderSize(m_iScreenWidthPowOf2/fBloomImageDownScale, m_iScreenHeightPowOf2/fBloomImageDownScale, true); + + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matBrightPass ); + renderSystem->CaptureRenderToImage( m_imageBloom ); + + //------------------------------------------------- + // Apply Gaussian Smoothing to create bloom + //------------------------------------------------- + + renderSystem->SetColor4( fBloomImageDownScale/m_iScreenWidthPowOf2, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matGaussBlurX ); + renderSystem->CaptureRenderToImage( m_imageBloom ); + renderSystem->SetColor4( fBloomImageDownScale/m_iScreenHeightPowOf2, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matGaussBlurY ); + + renderSystem->CaptureRenderToImage( m_imageBloom ); + renderSystem->UnCrop(); + //--------------------- + + } + + //------------------------------------------------- + // Calculate and Render Final Image + //------------------------------------------------- + float fDesaturation = Max ( Min ( r_postprocess_desaturation.GetFloat(), 1.0f ), 0.0f ); + renderSystem->SetColor4( fBloomIntensity, fDesaturation, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, m_fShiftScale_y, m_fShiftScale_x, 0, m_matFinalScenePass ); + //------------------------------------------------- + + this->RenderDebugTextures(); + } +} + +void idPlayerView::dnPostProcessManager::UpdateBackBufferParameters() +{ + // This condition makes sure that, the 2 loops inside run once only when resolution changes or map starts. + if( m_iScreenHeight != renderSystem->GetScreenHeight() || m_iScreenWidth !=renderSystem->GetScreenWidth() ) + { + m_iScreenWidthPowOf2 = 256, m_iScreenHeightPowOf2 = 256; + + // This should probably fix the ATI issue... + renderSystem->GetGLSettings( m_iScreenWidth, m_iScreenHeight ); + + //assert( iScreenWidth != 0 && iScreenHeight != 0 ); + + while( m_iScreenWidthPowOf2 < m_iScreenWidth ) { + m_iScreenWidthPowOf2 <<= 1; + } + while( m_iScreenHeightPowOf2 < m_iScreenHeight ) { + m_iScreenHeightPowOf2 <<= 1; + } + m_fShiftScale_x = m_iScreenWidth / (float)m_iScreenWidthPowOf2; + m_fShiftScale_y = m_iScreenHeight / (float)m_iScreenHeightPowOf2; + } +} + +void idPlayerView::dnPostProcessManager::RenderDebugTextures() +{ + const int iDebugTexture = r_postprocess_debugMode.GetInteger(); + + if( 0 < iDebugTexture && 4 > iDebugTexture ) + { + struct { + dnImageWrapper *m_pImage; + float m_fShiftScaleX, m_fShiftScaleY; + } + const arrStretchedImages[3] = { + {&m_imageCurrentRender, m_fShiftScale_x, m_fShiftScale_y }, + {&m_imageBloom, m_fShiftScale_x, m_fShiftScale_y }, + {&m_imageCookedMath, 1.0f, 1.0f}, + }; + + int i = iDebugTexture - 1; + + renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); + renderSystem->DrawStretchPic( 0, SCREEN_HEIGHT * .2f, SCREEN_WIDTH * 0.6f, SCREEN_HEIGHT * 0.6f, 0, + arrStretchedImages[i].m_fShiftScaleY, arrStretchedImages[i].m_fShiftScaleX, 0, + *arrStretchedImages[i].m_pImage ); + } +} + +// Moved Greebo's method from gameLocal to here. - J.C.Denton +// The CVar is rendering related and from now on, would work when g_stoptime is set to 0 + +void idPlayerView::dnPostProcessManager::UpdateInteractionShader() +{ + // Check the CVARs + switch (cv_interaction_vfp_type.GetInteger()) + { + case 0: // Doom 3's default interaction shader + gameLocal.Printf("Using default interaction.vfp\n"); + cvarSystem->SetCVarInteger("r_testARBProgram", 0); + break; + + case 1: // JC Denton's enhanced interaction + gameLocal.Printf("Using TDM's enhanced interaction\n"); + cvarSystem->SetCVarInteger("r_testARBProgram", 1); + break; + + default: + gameLocal.Warning("Unknown interaction type setting found, reverting to enhanced standard."); + cv_interaction_vfp_type.SetInteger(0); + this->UpdateInteractionShader(); + }; +} + diff --git a/game/PlayerView.h b/game/PlayerView.h new file mode 100644 index 000000000..3abba7b48 --- /dev/null +++ b/game/PlayerView.h @@ -0,0 +1,185 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_PLAYERVIEW_H__ +#define __GAME_PLAYERVIEW_H__ + +/* +=============================================================================== + + Player view. + +=============================================================================== +*/ + +// screenBlob_t are for the on-screen damage claw marks, etc +typedef struct { + const idMaterial * material; + float x, y, w, h; + float s1, t1, s2, t2; + int finishTime; + int startFadeTime; + float driftAmount; +} screenBlob_t; + +#define MAX_SCREEN_BLOBS 8 + +class idPlayerView { +public: + idPlayerView(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void SetPlayerEntity( class idPlayer *playerEnt ); + + void ClearEffects( void ); + + void DamageImpulse( idVec3 localKickDir, const idDict *damageDef ); + + void WeaponFireFeedback( const idDict *weaponDef ); + + idAngles AngleOffset( void ) const; // returns the current kick angle + + idMat3 ShakeAxis( void ) const; // returns the current shake angle + + void CalculateShake( void ); + + // this may involve rendering to a texture and displaying + // that with a warp model or in double vision mode + void RenderPlayerView( idUserInterface *hud ); + + void Fade( idVec4 color, int time ); + + void Flash( idVec4 color, int time ); + + void AddBloodSpray( float duration ); + +private: + void SingleView( idUserInterface *hud, const renderView_t *view, bool drawHUD = true); + void DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ); + void BerserkVision( idUserInterface *hud, const renderView_t *view ); + void InfluenceVision( idUserInterface *hud, const renderView_t *view ); + void ScreenFade(); + + // Updates the ambient light settings + void UpdateAmbientLight(); + + screenBlob_t * GetScreenBlob(); + + screenBlob_t screenBlobs[MAX_SCREEN_BLOBS]; + + int dvFinishTime; // double vision will be stopped at this time + const idMaterial * dvMaterial; // material to take the double vision screen shot + + int kickFinishTime; // view kick will be stopped at this time + idAngles kickAngles; + + class dnImageWrapper + { + private: + // Changed const idStr to idStr, so that compiler can provide a default implementation for the assignment operator. + // E.g. copying contents of idPlayerView object to another would be impossible otherwise. + idStr m_strImage; + const idMaterial *m_matImage; + + public: + dnImageWrapper( const char *a_strImage ) : + m_strImage ( a_strImage ), + m_matImage ( declManager->FindMaterial(a_strImage) ) + { + } + ID_INLINE operator const char * () const + { + return m_strImage.c_str(); + } + ID_INLINE operator const idMaterial *() const + { + return m_matImage; + } + }; + + class dnPostProcessManager + { + private: + int m_iScreenHeight; + int m_iScreenWidth; + int m_iScreenHeightPowOf2; + int m_iScreenWidthPowOf2; + float m_fShiftScale_x; + float m_fShiftScale_y; + + int m_nFramesToUpdateCookedData; // After these number of frames Cooked data will be updated. 0 means no update. + + bool m_bForceUpdateOnCookedData; + + dnImageWrapper m_imageCurrentRender; + dnImageWrapper m_imageBloom; + + // Every channel of this image will have a cooked mathematical data. + dnImageWrapper m_imageCookedMath; + const idMaterial* m_matCookMath_pass1; + const idMaterial* m_matCookMath_pass2; + + const idMaterial *m_matBrightPass; + const idMaterial *m_matGaussBlurX; + const idMaterial *m_matGaussBlurY; + + const idMaterial *m_matFinalScenePass; + + public: + dnPostProcessManager(); + ~dnPostProcessManager(); + + // Methods + void Initialize (); // This method should be invoked when idPlayerView::Restore is called. + void Update (); // Called Every Frame. + + private: + // Following methods should not be called by any other object, but itself. + void UpdateBackBufferParameters (); + void RenderDebugTextures (); + void UpdateCookedData (); + void UpdateInteractionShader (); // Chooses between the various VFP files according to the CVAR settings. Only call this if settings got changed. + void Hook_BufferCommandText( cmdExecution_t a_eType, const char *a_pcText ); // Source Hook for idCmdSystem::BufferCommandText - JC. + }; + + dnPostProcessManager m_postProcessManager; + + const idMaterial * tunnelMaterial; // health tunnel vision + const idMaterial * armorMaterial; // armor damage view effect + const idMaterial * berserkMaterial; // berserk effect + const idMaterial * irGogglesMaterial; // ir effect + const idMaterial * bloodSprayMaterial; // blood spray + const idMaterial * lagoMaterial; // lagometer drawing + float lastDamageTime; // accentuate the tunnel effect for a while + + idVec4 fadeColor; // fade color + idVec4 fadeToColor; // color to fade to + idVec4 fadeFromColor; // color to fade from + float fadeRate; // fade rate + int fadeTime; // fade time + + idAngles shakeAng; // from the sound sources + + idPlayer * player; + renderView_t view; +}; + +#endif /* !__GAME_PLAYERVIEW_H__ */ diff --git a/DarkMod/PositionWithinRangeFinder.cpp b/game/PositionWithinRangeFinder.cpp similarity index 76% rename from DarkMod/PositionWithinRangeFinder.cpp rename to game/PositionWithinRangeFinder.cpp index 848d5e9fa..792167bc8 100644 --- a/DarkMod/PositionWithinRangeFinder.cpp +++ b/game/PositionWithinRangeFinder.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/game/PositionWithinRangeFinder.h b/game/PositionWithinRangeFinder.h new file mode 100644 index 000000000..2525896b6 --- /dev/null +++ b/game/PositionWithinRangeFinder.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef POSITION_WITHIN_RANGE_FINDER__H +#define POSITION_WITHIN_RANGE_FINDER__H + +#include "../idlib/precompiled.h" + +class PositionWithinRangeFinder : + public idAASCallback +{ +private: + idVec3 _targetPos; + idVec3 _eyeOffset; + const idAI* _self; + idMat3 _gravityAxis; + float _maxDistance; + bool _haveBestGoal; + + + idBounds excludeBounds; + pvsHandle_t targetPVS; + int PVSAreas[ idEntity::MAX_PVS_AREAS ]; + int numPVSAreas; + + aasGoal_t bestGoal; + float bestGoalDistance; + + +public: + PositionWithinRangeFinder(const idAI *self, const idMat3 &gravityAxis, + const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistance); + + ~PositionWithinRangeFinder(); + + bool TestArea( const idAAS *aas, int areaNum ); + + bool GetBestGoalResult(float& out_bestGoalDistance, aasGoal_t& out_bestGoal); +}; + +#endif /* POSITION_WITHIN_RANGE_FINDER__H */ diff --git a/game/Projectile.cpp b/game/Projectile.cpp new file mode 100644 index 000000000..435371c6b --- /dev/null +++ b/game/Projectile.cpp @@ -0,0 +1,2527 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "ProjectileResult.h" +#include "StimResponse/StimResponseCollection.h" // grayman #2885 + +/* +=============================================================================== + + idProjectile + +=============================================================================== +*/ + + +static const float BOUNCE_SOUND_MIN_VELOCITY = 200.0f; +static const float BOUNCE_SOUND_MAX_VELOCITY = 400.0f; + +const idEventDef EV_Explode( "", NULL ); +const idEventDef EV_Fizzle( "", NULL ); +const idEventDef EV_RadiusDamage( "", "e" ); +const idEventDef EV_GetProjectileState( "getProjectileState", NULL, 'd' ); +// greebo: The launch method (takes 3 vectors as arguments) +const idEventDef EV_Launch("launch", "vvv"); +const idEventDef EV_ActivateProjectile("", NULL); +const idEventDef EV_TDM_Mine_ClearPlayerImmobilization("EV_TDM_Mine_ClearPlayerImmobilization", "e"); // grayman #2478 - allows player to handle weapons again +const idEventDef EV_Mine_Replace("", NULL); // grayman #2478 + +CLASS_DECLARATION( idEntity, idProjectile ) + EVENT( EV_Explode, idProjectile::Event_Explode ) + EVENT( EV_Fizzle, idProjectile::Event_Fizzle ) + EVENT( EV_Touch, idProjectile::Event_Touch ) + EVENT( EV_RadiusDamage, idProjectile::Event_RadiusDamage ) + EVENT( EV_GetProjectileState, idProjectile::Event_GetProjectileState ) + EVENT( EV_Launch, idProjectile::Event_Launch ) + EVENT( EV_ActivateProjectile, idProjectile::Event_ActivateProjectile ) + EVENT( EV_TDM_Mine_ClearPlayerImmobilization, idProjectile::Event_ClearPlayerImmobilization ) // grayman #2478 + EVENT( EV_TDM_Lock_OnLockPicked, idProjectile::Event_Lock_OnLockPicked ) // grayman #2478 + EVENT( EV_Mine_Replace, idProjectile::Event_Mine_Replace ) // grayman #2478 +END_CLASS + +/* +================ +idProjectile::idProjectile +================ +*/ +idProjectile::idProjectile( void ) { + owner = NULL; + lightDefHandle = -1; + thrust = 0.0f; + thrust_end = 0; + smokeFly = NULL; + smokeFlyTime = 0; + state = SPAWNED; + lightOffset = vec3_zero; + lightStartTime = 0; + lightEndTime = 0; + lightColor = vec3_zero; + damagePower = 1.0f; + memset( &projectileFlags, 0, sizeof( projectileFlags ) ); + memset( &renderLight, 0, sizeof( renderLight ) ); + + // note: for net_instanthit projectiles, we will force this back to false at spawn time + + fl.networkSync = true; + netSyncPhysics = false; + m_Lock = NULL; // grayman #2478 + isMine = false; // grayman #2478 + replaced = false; // grayman #2908 +} + +/* +================ +idProjectile::Spawn +================ +*/ +void idProjectile::Spawn( void ) { + physicsObj.SetSelf( this ); + + if (!GetPhysics()->GetClipModel()->IsTraceModel()) + { + // greebo: Clipmodel is not a trace model, try to construct it from the collision mesh + idTraceModel traceModel; + + if ( !collisionModelManager->TrmFromModel( spawnArgs.GetString("model"), traceModel ) ) + { + gameLocal.Error( "idProjectile '%s': cannot load tracemodel from %s", name.c_str(), spawnArgs.GetString("model") ); + return; + } + + // Construct a new clipmodel from that loaded tracemodel + physicsObj.SetClipModel(new idClipModel(traceModel), 1); + } + else + { + // Use the existing clipmodel, it's good enough + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + } + + physicsObj.SetContents( 0 ); + physicsObj.SetClipMask( 0 ); + physicsObj.PutToRest(); + SetPhysics( &physicsObj ); +} + +void idProjectile::AddObjectsToSaveGame(idSaveGame* savefile) // grayman #2478 +{ + idEntity::AddObjectsToSaveGame(savefile); + + savefile->AddObject(m_Lock); +} + +/* +================ +idProjectile::Save +================ +*/ +void idProjectile::Save( idSaveGame *savefile ) const { + + owner.Save( savefile ); + + projectileFlags_s flags = projectileFlags; + + LittleBitField( &flags, sizeof( flags ) ); + + savefile->Write( &flags, sizeof( flags ) ); + + + savefile->WriteFloat( thrust ); + savefile->WriteInt( thrust_end ); + + savefile->WriteRenderLight( renderLight ); + savefile->WriteInt( (int)lightDefHandle ); + savefile->WriteVec3( lightOffset ); + savefile->WriteInt( lightStartTime ); + savefile->WriteInt( lightEndTime ); + savefile->WriteVec3( lightColor ); + + savefile->WriteParticle( smokeFly ); + savefile->WriteInt( smokeFlyTime ); + + savefile->WriteInt( (int)state ); + + savefile->WriteFloat( damagePower ); + savefile->WriteBool(isMine); // grayman #2478 + savefile->WriteBool(replaced); // grayman #2908 + + savefile->WriteStaticObject( physicsObj ); + savefile->WriteStaticObject( thruster ); +} + +/* +================ +idProjectile::Restore +================ +*/ +void idProjectile::Restore( idRestoreGame *savefile ) { + + owner.Restore( savefile ); + + savefile->Read( &projectileFlags, sizeof( projectileFlags ) ); + LittleBitField( &projectileFlags, sizeof( projectileFlags ) ); + + + savefile->ReadFloat( thrust ); + savefile->ReadInt( thrust_end ); + + savefile->ReadRenderLight( renderLight ); + savefile->ReadInt( (int &)lightDefHandle ); + savefile->ReadVec3( lightOffset ); + savefile->ReadInt( lightStartTime ); + savefile->ReadInt( lightEndTime ); + savefile->ReadVec3( lightColor ); + + savefile->ReadParticle( smokeFly ); + savefile->ReadInt( smokeFlyTime ); + + savefile->ReadInt( (int &)state ); + + savefile->ReadFloat( damagePower ); + savefile->ReadBool(isMine); // grayman #2478 + savefile->ReadBool(replaced); // grayman #2908 + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadStaticObject( thruster ); + thruster.SetPhysics( &physicsObj ); + + if ( smokeFly != NULL ) { + idVec3 dir; + dir = physicsObj.GetLinearVelocity(); + dir.NormalizeFast(); + gameLocal.smokeParticles->EmitSmoke( smokeFly, gameLocal.time, gameLocal.random.RandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + } +} + +/* +================ +idProjectile::GetOwner +================ +*/ +idEntity *idProjectile::GetOwner( void ) const { + return owner.GetEntity(); +} + +/* +================ +idProjectile::SetReplaced +================ +*/ +void idProjectile::SetReplaced() // grayman #2908 +{ + this->replaced = true; +} + +/* +================ +idProjectile::Create +================ +*/ +void idProjectile::Create( idEntity *owner, const idVec3 &start, const idVec3 &dir ) { + idDict args; + idStr shaderName; + idVec3 light_color; + idVec3 light_offset; + idVec3 tmp; + idMat3 axis; + + Unbind(); + + // align z-axis of model with the direction + axis = dir.ToMat3(); + tmp = axis[2]; + axis[2] = axis[0]; + axis[0] = -tmp; + + physicsObj.SetOrigin( start ); + physicsObj.SetAxis( axis ); + + physicsObj.GetClipModel()->SetOwner( owner ); + + this->owner = owner; + + memset( &renderLight, 0, sizeof( renderLight ) ); + shaderName = spawnArgs.GetString( "mtr_light_shader" ); + if ( *(const char*)shaderName ) { + renderLight.shader = declManager->FindMaterial( shaderName, false ); + renderLight.pointLight = true; + renderLight.lightRadius[0] = + renderLight.lightRadius[1] = + renderLight.lightRadius[2] = spawnArgs.GetFloat( "light_radius" ); + spawnArgs.GetVector( "light_color", "1 1 1", light_color ); + renderLight.shaderParms[0] = light_color[0]; + renderLight.shaderParms[1] = light_color[1]; + renderLight.shaderParms[2] = light_color[2]; + renderLight.shaderParms[3] = 1.0f; + renderLight.noShadows = spawnArgs.GetBool("light_noshadows", "0"); + } + + spawnArgs.GetVector( "light_offset", "0 0 0", lightOffset ); + + lightStartTime = 0; + lightEndTime = 0; + smokeFlyTime = 0; + + damagePower = 1.0f; + + UpdateVisuals(); + + state = CREATED; + + + if ( spawnArgs.GetBool( "net_fullphysics" ) ) { + netSyncPhysics = true; + } +} + +/* +================= +idProjectile::~idProjectile +================= +*/ +idProjectile::~idProjectile() { + StopSound( SND_CHANNEL_ANY, false ); + FreeLightDef(); + delete m_Lock; // grayman #2478 +} + +/* +================= +idProjectile::FreeLightDef +================= +*/ +void idProjectile::FreeLightDef( void ) { + if ( lightDefHandle != -1 ) { + gameRenderWorld->FreeLightDef( lightDefHandle ); + lightDefHandle = -1; + } +} + +/* +================= +idProjectile::Launch +================= +*/ +void idProjectile::Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire, const float launchPower, const float dmgPower ) { + float fuse; + float startthrust; + float endthrust; + idVec3 velocity; + idAngles angular_velocity; + float linear_friction; + float angular_friction; + float contact_friction; + float bounce; + float mass; + float speed; + float delay; + float gravity; + idVec3 gravVec; + idVec3 tmp; + idMat3 axis; + int thrust_start; + int contents; + int clipMask; + + // allow characters to throw projectiles during cinematics, but not the player + if ( owner.GetEntity() && !owner.GetEntity()->IsType( idPlayer::Type ) ) { + cinematic = owner.GetEntity()->cinematic; + } else { + cinematic = false; + } + + thrust = spawnArgs.GetFloat( "thrust" ); + startthrust = spawnArgs.GetFloat( "thrust_start" ); + endthrust = spawnArgs.GetFloat( "thrust_end" ); + + spawnArgs.GetVector( "velocity", "0 0 0", velocity ); + + speed = velocity.Length() * launchPower; + + damagePower = dmgPower; + + spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); + + linear_friction = spawnArgs.GetFloat( "linear_friction" ); + angular_friction = spawnArgs.GetFloat( "angular_friction" ); + contact_friction = spawnArgs.GetFloat( "contact_friction" ); + bounce = spawnArgs.GetFloat( "bounce" ); + mass = spawnArgs.GetFloat( "mass" ); + + // greebo: Fall back to default gravity if the spawnarg is missing completely (still allows "0" gravity being set) + if (!spawnArgs.GetFloat("gravity", "0", gravity)) + { + gravity = gameLocal.GetGravity().Length(); + } + + fuse = spawnArgs.GetFloat( "fuse" ); + delay = spawnArgs.GetFloat( "delay" ); + + projectileFlags.detonate_on_world = spawnArgs.GetBool( "detonate_on_world" ); + projectileFlags.detonate_on_actor = spawnArgs.GetBool( "detonate_on_actor" ); + projectileFlags.randomShaderSpin = spawnArgs.GetBool( "random_shader_spin" ); + + if ( mass <= 0 ) { + gameLocal.Error( "Invalid mass on '%s'\n", GetEntityDefName() ); + } + + thrust *= mass; + thrust_start = SEC2MS( startthrust ) + gameLocal.time; + thrust_end = SEC2MS( endthrust ) + gameLocal.time; + + lightStartTime = 0; + lightEndTime = 0; + + if ( health ) { + fl.takedamage = true; + } + + gravVec = gameLocal.GetGravity(); + gravVec.NormalizeFast(); + + Unbind(); + + // align z-axis of model with the direction + axis = dir.ToMat3(); + tmp = axis[2]; + axis[2] = axis[0]; + axis[0] = -tmp; + + contents = 0; + clipMask = MASK_SHOT_RENDERMODEL; + if ( spawnArgs.GetBool( "detonate_on_trigger" ) ) { + contents |= CONTENTS_TRIGGER; + } + if ( !spawnArgs.GetBool( "no_contents" ) ) { + contents |= CONTENTS_PROJECTILE|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP; + clipMask |= CONTENTS_PROJECTILE; + } + + // don't do tracers on client, we don't know origin and direction + if ( spawnArgs.GetBool( "tracers" ) && gameLocal.random.RandomFloat() > 0.5f ) { + SetModel( spawnArgs.GetString( "model_tracer" ) ); + projectileFlags.isTracer = true; + } + + physicsObj.SetMass( mass ); + physicsObj.SetFriction( linear_friction, angular_friction, contact_friction ); + if ( contact_friction == 0.0f ) { + physicsObj.NoContact(); + } + physicsObj.SetBouncyness( bounce ); + physicsObj.SetGravity( gravVec * gravity ); + physicsObj.SetContents( contents ); + physicsObj.SetClipMask( clipMask ); + physicsObj.SetLinearVelocity( axis[ 2 ] * speed + pushVelocity ); + physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); + physicsObj.SetOrigin( start ); + + // greebo: Allow overriding of the projectile orientation via "angles" spawnarg + idAngles angles; + if (spawnArgs.GetAngles("angles", "0 0 0", angles)) + { + axis = angles.ToMat3(); + } + physicsObj.SetAxis( axis ); + + // grayman #2478 - is this a mine? + isMine = spawnArgs.GetBool("is_mine","0"); + + thruster.SetPosition( &physicsObj, 0, idVec3( GetPhysics()->GetBounds()[ 0 ].x, 0, 0 ) ); + + if ( !gameLocal.isClient ) { + if ( fuse <= 0 ) { + // run physics for 1 second + RunPhysics(); + PostEventMS( &EV_Remove, spawnArgs.GetInt( "remove_time", "1500" ) ); + } else if ( spawnArgs.GetBool( "detonate_on_fuse" ) ) { + fuse -= timeSinceFire; + if ( fuse < 0.0f ) { + fuse = 0.0f; + } + PostEventSec( &EV_Explode, fuse ); + } + // greebo: Added this to allow for mines + else if ( spawnArgs.GetBool( "no_fizzle" ) ) { + if ( fuse < 0.0f ) { + fuse = 0.0f; + } + } + else { + fuse -= timeSinceFire; + if ( fuse < 0.0f ) { + fuse = 0.0f; + } + PostEventSec( &EV_Fizzle, fuse ); + } + } + + if (delay > 0.0f) { + // Activate this projectile in seconds + PostEventSec( &EV_ActivateProjectile, delay); + } + + if ( projectileFlags.isTracer ) { + StartSound( "snd_tracer", SND_CHANNEL_BODY, 0, false, NULL ); + } else { + StartSound( "snd_fly", SND_CHANNEL_BODY, 0, false, NULL ); + } + + smokeFlyTime = 0; + const char *smokeName = spawnArgs.GetString( "smoke_fly" ); + if ( *smokeName != '\0' ) { + smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + smokeFlyTime = gameLocal.time; + } + + // used for the plasma bolts but may have other uses as well + if ( projectileFlags.randomShaderSpin ) { + float f = gameLocal.random.RandomFloat(); + f *= 0.5f; + renderEntity.shaderParms[SHADERPARM_DIVERSITY] = f; + } + + UpdateVisuals(); + + // Set this to inactive if there is a delay set + state = (delay > 0) ? INACTIVE : LAUNCHED; +} + +/* +========================= +idProjectile::IsMine - grayman #2478 +========================= +*/ + +bool idProjectile::IsMine() +{ + return isMine; +} + +/* +========================= +idProjectile::IsArmed - grayman #2906 +========================= +*/ + +bool idProjectile::IsArmed() +{ + return ( state == LAUNCHED ); +} + +/* +========================= +idProjectile::AngleAdjust - grayman #2478 +========================= +*/ + +float idProjectile::AngleAdjust(float angle) +{ + // Adjust a mine's pitch and roll angles so that it wants to + // return to the vertical. A larger adjustment occurs when + // the given angle is near +- 90 degrees. A smaller adjustment + // occurs when the angle is near zero or near +- 180 degrees. + // This keeps mines from flipping over if they land upside-down, + // but allows them to correct when in flight. The amount of + // adjustment varies between 0 and 5 degrees. + + float factor = 5.0f/90.0f; + float adjust = 0; + + if (abs(angle) >= 10) // small adjustments are not interesting + { + if (angle < -90) + { + adjust = factor*angle + 10; + } + else if (angle < 90) + { + adjust = -factor*angle; + } + else + { + adjust = factor*angle - 10; + } + } + + return adjust; +} + +/* +================ +idProjectile::Think +================ +*/ + +void idProjectile::Think( void ) { + if ( thinkFlags & TH_THINK ) { + if ( thrust && ( gameLocal.time < thrust_end ) ) { + // evaluate force + thruster.SetForce( GetPhysics()->GetAxis()[ 0 ] * thrust ); + thruster.Evaluate( gameLocal.time ); + } + } + + if ( IsMine() ) + { + // grayman #2478 - if this is a mine in flight, adjust its pitch and + // roll slightly so it has a better chance of landing rightside-up. + + if ( !IsAtRest() && !(thinkFlags & TH_ARMED) ) + { + idAngles ang = GetPhysics()->GetAxis().ToAngles(); + ang.pitch += AngleAdjust(ang.pitch); + ang.roll += AngleAdjust(ang.roll); + SetAngles(ang); + } + + if ( thinkFlags & TH_ARMED ) // grayman #2478 - if armed, this is a ticking mine + { + // Any AI around? For AI who manage to avoid a collision with the mine, catch them here if they're close enough and moving/rotating. + + idEntity* entityList[ MAX_GENTITIES ]; + idVec3 org = GetPhysics()->GetOrigin(); + idBounds bounds = GetPhysics()->GetAbsBounds(); + float closeEnough = Square(23); + + // get all entities touching the bounds + + int numListedEntities = gameLocal.clip.EntitiesTouchingBounds( bounds, -1, entityList, MAX_GENTITIES ); + + for ( int i = 0 ; i < numListedEntities ; i++ ) + { + idEntity* ent = entityList[ i ]; + if ( ent && ent->IsType(idAI::Type) ) + { + idAI* entAI = static_cast(ent); + if ( entAI->AI_FORWARD || (entAI->GetPhysics()->GetAngularVelocity().LengthSqr() > 0) ) + { + if ( (entAI->GetPhysics()->GetOrigin() - org).LengthSqr() <= closeEnough ) + { + MineExplode( entAI->entityNumber ); + break; + } + } + } + } + } + } + + /*idStr stateStr; + switch (state) + { + case SPAWNED: stateStr = "SPAWNED"; break; + case CREATED: stateStr = "CREATED"; break; + case LAUNCHED: stateStr = "LAUNCHED"; break; + case FIZZLED: stateStr = "FIZZLED"; break; + case EXPLODED: stateStr = "EXPLODED"; break; + case INACTIVE: stateStr = "INACTIVE"; break; + }; + + gameRenderWorld->DrawText(stateStr, physicsObj.GetOrigin(), 0.2f, colorRed, gameLocal.GetLocalPlayer()->viewAxis);*/ + + // run physics + RunPhysics(); + + Present(); + + // add the particles + if ( smokeFly != NULL && smokeFlyTime && !IsHidden() ) { + idVec3 dir = -GetPhysics()->GetLinearVelocity(); + dir.Normalize(); + if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.RandomFloat(), GetPhysics()->GetOrigin(), dir.ToMat3() ) ) { + smokeFlyTime = gameLocal.time; + } + } + + // add the light + if ( renderLight.lightRadius.x > 0.0f && g_projectileLights.GetBool() ) { + renderLight.origin = GetPhysics()->GetOrigin() + GetPhysics()->GetAxis() * lightOffset; + renderLight.axis = GetPhysics()->GetAxis(); + if ( ( lightDefHandle != -1 ) ) { + if ( lightEndTime > 0 && gameLocal.time <= lightEndTime + gameLocal.GetMSec() ) { + idVec3 color( 0, 0, 0 ); + if ( gameLocal.time < lightEndTime ) { + float frac = ( float )( gameLocal.time - lightStartTime ) / ( float )( lightEndTime - lightStartTime ); + color.Lerp( lightColor, color, frac ); + } + renderLight.shaderParms[SHADERPARM_RED] = color.x; + renderLight.shaderParms[SHADERPARM_GREEN] = color.y; + renderLight.shaderParms[SHADERPARM_BLUE] = color.z; + } + gameRenderWorld->UpdateLightDef( lightDefHandle, &renderLight ); + } else { + lightDefHandle = gameRenderWorld->AddLightDef( &renderLight ); + } + } +} + +/* +================= +idProjectile::Collide +================= +*/ +bool idProjectile::Collide( const trace_t &collision, const idVec3 &velocity ) { + idEntity *ent; + idEntity *ignore; + const char *damageDefName; + idVec3 dir; + float push; + float damageScale; + idStr SurfTypeName; + + if ( state == INACTIVE ) { + // projectile not active, return FALSE + return false; + } + + if ( state == EXPLODED || state == FIZZLED ) { + return true; + } + + // predict the explosion + if ( gameLocal.isClient ) { + if ( ClientPredictionCollide( this, spawnArgs, collision, velocity, !spawnArgs.GetBool( "net_instanthit" ) ) ) { + Explode( collision, NULL ); + return true; + } + return false; + } + + // remove projectile when a 'noimpact' surface is hit + if ( ( collision.c.material != NULL ) && ( collision.c.material->GetSurfaceFlags() & SURF_NOIMPACT ) ) { + PostEventMS( &EV_Remove, 0 ); + common->DPrintf( "Projectile collision no impact\n" ); + return true; + } + + // get the entity the projectile collided with + ent = gameLocal.entities[ collision.c.entityNum ]; + + if ( ent ) + { + ProcCollisionStims( ent, collision.c.id ); + + if( ent->IsType( idAI::Type ) ) + { + idAI *alertee = static_cast(ent); + alertee->TactileAlert( this ); + } + } + + if ( ent == owner.GetEntity() ) { + assert( 0 ); + return true; + } + + // just get rid of the projectile when it hits a player in noclip + if ( ent->IsType( idPlayer::Type ) && static_cast( ent )->noclip ) { + PostEventMS( &EV_Remove, 0 ); + return true; + } + + // direction of projectile + dir = velocity; + dir.Normalize(); + + // projectiles can apply an additional impulse next to the rigid body physics impulse + if ( spawnArgs.GetFloat( "push", "0", push ) && ( push > 0.0f ) ) + { + idVec3 pushDir = dir; + if ( IsMine() ) // grayman #2478 - if this is a mine, push up + { + pushDir = idVec3( 0,0,1 ); + } + ent->ApplyImpulse( this, collision.c.id, collision.c.point, push * pushDir ); + } + + // MP: projectiles open doors + // tels: TODO 2010-06-11 need another way to find out if entity is a door (low priority, we don't have MP in TDM yet) + //if ( gameLocal.isMultiplayer && ent->IsType( idDoor::Type ) && !static_cast< idDoor * >(ent)->IsOpen() && !ent->spawnArgs.GetBool( "no_touch" ) ) { + // ent->ProcessEvent( &EV_Activate , this ); + //} + + if ( ent->IsType( idActor::Type ) || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody()->IsType( idActor::Type ) ) ) { + if ( !projectileFlags.detonate_on_actor ) { + return false; + } + } else { + if ( !projectileFlags.detonate_on_world ) { + if ( !StartSound( "snd_ricochet", SND_CHANNEL_ITEM, 0, true, NULL ) ) { + float len = velocity.Length(); + if ( len > BOUNCE_SOUND_MIN_VELOCITY ) { + SetSoundVolume( len > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( len - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ) ); + StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, true, NULL ); + } + } + return false; + } + } + + SetOrigin( collision.endpos ); + SetAxis( collision.endAxis ); + + // unlink the clip model because we no longer need it + GetPhysics()->UnlinkClip(); + + damageDefName = spawnArgs.GetString( "def_damage" ); + + ignore = NULL; + + bool damageInflicted = false; // grayman #2794 - whether damage was inflicted below + + // if the hit entity takes damage + if ( ent->fl.takedamage ) + { + if ( damagePower ) { + damageScale = damagePower; + } else { + damageScale = 1.0f; + } + + // scale the damage by the surface type multiplier, if any + g_Global.GetSurfName( collision.c.material, SurfTypeName ); + SurfTypeName = "damage_mult_" + SurfTypeName; + + damageScale *= spawnArgs.GetFloat( SurfTypeName.c_str(), "1.0" ); + + // if the projectile owner is a player + if ( owner.GetEntity() && owner.GetEntity()->IsType( idPlayer::Type ) ) { + // if the projectile hit an actor + if ( ent->IsType( idActor::Type ) ) { + idPlayer *player = static_cast( owner.GetEntity() ); + player->AddProjectileHits( 1 ); + damageScale *= player->PowerUpModifier( PROJECTILE_DAMAGE ); + } + } + + if ( damageDefName[0] != '\0' ) + { + // grayman #2794 - if no damage is being inflicted, then there's no need for a damage effect + + const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); + if ( !damageDef ) + { + gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); + } + + int damage = damageDef->GetInt( "damage" ); + damageInflicted = ( damage > 0 ); + + // grayman #2906 - check for the special case of hitting a mine. + // If a mine is unarmed, it won't take damage or explode. + + if ( damageInflicted ) + { + if ( ent->IsType(idProjectile::Type) ) + { + idProjectile *proj = static_cast(ent); + if ( proj->IsMine() && !proj->IsArmed() ) // is mine armed? + { + damageInflicted = false; + } + } + } + + if ( damageInflicted ) // grayman #2906 - only run the damage code if there's damage + { + ent->Damage( this, owner.GetEntity(), dir, damageDefName, damageScale, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ), const_cast(&collision) ); + } + ignore = ent; + } + } + + if ( damageInflicted ) // grayman #2794 + { + // if the projectile causes a damage effect + if ( spawnArgs.GetBool( "impact_damage_effect" ) ) + { + // if the hit entity has a special damage effect + if ( ent->spawnArgs.GetBool( "bleed" ) ) + { + ent->AddDamageEffect( collision, velocity, damageDefName ); + } + else + { + AddDefaultDamageEffect( collision, velocity ); + } + } + } + + Explode( collision, ignore ); + + return true; +} + +/* +================================= +idProjectile::AddDamageEffect - grayman #2478 +================================= +*/ + +void idProjectile::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) +{ + AddDefaultDamageEffect( collision, velocity ); +} + +/* +================= +idProjectile::DefaultDamageEffect +================= +*/ + +void idProjectile::DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity ) { + const char *decal, *sound; + idStr typeName; + + if ( collision.c.material != NULL ) + { + g_Global.GetSurfName( collision.c.material, typeName ); + } + else + { + typeName = gameLocal.sufaceTypeNames[ SURFTYPE_METAL ]; + } + + // play impact sound + sound = projectileDef.GetString( va( "snd_%s", typeName.c_str() ) ); + if ( *sound == '\0' ) { + sound = projectileDef.GetString( "snd_metal" ); + } + if ( *sound == '\0' ) { + sound = projectileDef.GetString( "snd_impact" ); + } + if ( *sound != '\0' ) { + soundEnt->StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); + } + + // project decal + decal = projectileDef.GetString( va( "mtr_detonate_%s", typeName.c_str() ) ); + if ( *decal == '\0' ) { + decal = projectileDef.GetString( "mtr_detonate" ); + } + if ( *decal != '\0' ) { + gameLocal.ProjectDecal( collision.c.point, -collision.c.normal, 8.0f, true, projectileDef.GetFloat( "decal_size", "6.0" ), decal ); + } +} + +/* +================= +idProjectile::AddDefaultDamageEffect +================= +*/ +void idProjectile::AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity ) { + + DefaultDamageEffect( this, spawnArgs, collision, velocity ); + + if ( gameLocal.isServer && fl.networkSync ) { + + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + int excludeClient; + + if ( spawnArgs.GetBool( "net_instanthit" ) ) { + excludeClient = owner.GetEntityNum(); + } else { + excludeClient = -1; + } + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.BeginWriting(); + msg.WriteFloat( collision.c.point[0] ); + msg.WriteFloat( collision.c.point[1] ); + msg.WriteFloat( collision.c.point[2] ); + msg.WriteDir( collision.c.normal, 24 ); + msg.WriteLong( ( collision.c.material != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_MATERIAL, collision.c.material->Index() ) : -1 ); + msg.WriteFloat( velocity[0], 5, 10 ); + msg.WriteFloat( velocity[1], 5, 10 ); + msg.WriteFloat( velocity[2], 5, 10 ); + ServerSendEvent( EVENT_DAMAGE_EFFECT, &msg, false, excludeClient ); + } +} + +/* +================ +idProjectile::Killed +================ +*/ +void idProjectile::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + if ( spawnArgs.GetBool( "detonate_on_death" ) ) { + trace_t collision; + + memset( &collision, 0, sizeof( collision ) ); + collision.endAxis = GetPhysics()->GetAxis(); + collision.endpos = GetPhysics()->GetOrigin(); + collision.c.point = GetPhysics()->GetOrigin(); + collision.c.normal.Set( 0, 0, 1 ); + Explode( collision, NULL ); + physicsObj.ClearContacts(); + physicsObj.PutToRest(); + } else { + Fizzle(); + } +} + +/* +================ +idProjectile::Fizzle +================ +*/ +void idProjectile::Fizzle( void ) { + + if ( state == INACTIVE || state == EXPLODED || state == FIZZLED ) { + return; + } + + StopSound( SND_CHANNEL_BODY, false ); + StartSound( "snd_fizzle", SND_CHANNEL_BODY, 0, false, NULL ); + + // fizzle FX + const char *psystem = spawnArgs.GetString( "smoke_fuse" ); + if ( psystem && *psystem ) { +//FIXME:SMOKE gameLocal.particles->SpawnParticles( GetPhysics()->GetOrigin(), vec3_origin, psystem ); + } + + // we need to work out how long the effects last and then remove them at that time + // for example, bullets have no real effects + if ( smokeFly && smokeFlyTime ) { + smokeFlyTime = 0; + } + + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.GetClipModel()->Unlink(); + physicsObj.PutToRest(); + + Hide(); + FreeLightDef(); + + state = FIZZLED; + + if ( gameLocal.isClient ) { + return; + } + + CancelEvents( &EV_Fizzle ); + PostEventMS( &EV_Remove, spawnArgs.GetInt( "remove_time", "1500" ) ); +} + +/** +* greebo: This event is being scheduled by the Launch() method, if a "delay" is set on the projectileDef +*/ +void idProjectile::Event_ActivateProjectile() +{ + state = LAUNCHED; + + // grayman #2478 - arm it if it's a mine + + if ( IsMine() ) + { + // The mine is now armed, so loop the armed sound. + + // grayman #2908 - determine if this mine was set by the map author or thrown by the player + if ( !replaced ) + { + m_SetInMotionByActor = gameLocal.GetLocalPlayer(); + } + + StartSound( "snd_mine_armed", SND_CHANNEL_BODY, 0, true, NULL ); + + // Make it frobable. It won't highlight, though, for any inventory + // item other than a lockpick, so that the player doesn't get the + // impression that he can frob it. + + SetFrobable( true ); + m_FrobDistance = cv_frob_distance_default.GetInteger(); + + // Make it locked and pickable. + + // Set up our PickableLock instance + + m_Lock = static_cast( PickableLock::CreateInstance() ); + m_Lock->InitFromSpawnargs( spawnArgs ); // Load the spawnargs for the lock + m_Lock->SetOwner( this ); + m_Lock->SetLocked( true ); + + BecomeActive( TH_ARMED ); // guarantee continued thinking + } +} + +/* +================ +idProjectile::Event_RadiusDamage +================ +*/ + +void idProjectile::Event_RadiusDamage( idEntity *ignore ) { + const char *splash_damage = spawnArgs.GetString( "def_splash_damage" ); + if ( splash_damage[0] != '\0' ) { + gameLocal.RadiusDamage( physicsObj.GetOrigin(), this, owner.GetEntity(), ignore, this, splash_damage, damagePower ); + } +} + +/* +================ +idProjectile::Event_GetProjectileState +================ +*/ +void idProjectile::Event_GetProjectileState( void ) { + idThread::ReturnInt( state ); +} + +/* +================ +idProjectile::Explode +================ +*/ +void idProjectile::Explode( const trace_t &collision, idEntity *ignore ) { + const char *fxname, *light_shader, *sndExplode; + idStr SurfTypeName; + float light_fadetime; + idVec3 normal, tempVel, tempAngVel; + int removeTime; + bool bActivated; + + if ( state == INACTIVE || state == EXPLODED || state == FIZZLED ) { + return; + } + + // stop sound + StopSound( SND_CHANNEL_BODY2, false ); + StopSound( SND_CHANNEL_BODY, false ); + + // DarkMod: Check material list to see if it's activated + g_Global.GetSurfName( collision.c.material, SurfTypeName ); + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Weapon: Projectile surface was %s \r", SurfTypeName.c_str() ); + + bActivated = TestActivated( SurfTypeName.c_str() ); +// TODO: Add spawnarg option to only play explode sound and explode light on activate + + // play explode sound + switch ( ( int ) damagePower ) { + case 2: sndExplode = "snd_explode2"; break; + case 3: sndExplode = "snd_explode3"; break; + case 4: sndExplode = "snd_explode4"; break; + default: sndExplode = "snd_explode"; break; + } + StartSound( sndExplode, SND_CHANNEL_BODY, 0, true, NULL ); + + // we need to work out how long the effects last and then remove them at that time + // for example, bullets have no real effects + if ( smokeFly && smokeFlyTime ) { + smokeFlyTime = 0; + } + + Hide(); + FreeLightDef(); + + if ( spawnArgs.GetVector( "detonation_axis", "", normal ) ) { + GetPhysics()->SetAxis( normal.ToMat3() ); + } + GetPhysics()->SetOrigin( collision.endpos + 2.0f * collision.c.normal ); + + // default remove time + removeTime = spawnArgs.GetInt( "remove_time", "1500" ); + + // change the model, usually to a PRT + fxname = NULL; + if ( g_testParticle.GetInteger() == TEST_PARTICLE_IMPACT ) { + fxname = g_testParticleName.GetString(); + } else { + fxname = spawnArgs.GetString( "model_detonate" ); + } + + int surfaceType = collision.c.material != NULL ? collision.c.material->GetSurfaceType() : SURFTYPE_METAL; + if ( !( fxname && *fxname ) ) { + if ( ( surfaceType == SURFTYPE_NONE ) || ( surfaceType == SURFTYPE_METAL ) || ( surfaceType == SURFTYPE_STONE ) ) { + fxname = spawnArgs.GetString( "model_smokespark" ); + } else if ( surfaceType == SURFTYPE_RICOCHET ) { + fxname = spawnArgs.GetString( "model_ricochet" ); + } else { + fxname = spawnArgs.GetString( "model_smoke" ); + } + } + + if ( fxname && *fxname ) { + SetModel( fxname ); + renderEntity.shaderParms[SHADERPARM_RED] = + renderEntity.shaderParms[SHADERPARM_GREEN] = + renderEntity.shaderParms[SHADERPARM_BLUE] = + renderEntity.shaderParms[SHADERPARM_ALPHA] = 1.0f; + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + renderEntity.shaderParms[SHADERPARM_DIVERSITY] = gameLocal.random.CRandomFloat(); + Show(); + removeTime = ( removeTime > 3000 ) ? removeTime : 3000; + } + + // explosion light + light_shader = spawnArgs.GetString( "mtr_explode_light_shader" ); + if ( *light_shader ) { + renderLight.shader = declManager->FindMaterial( light_shader, false ); + renderLight.pointLight = true; + renderLight.lightRadius[0] = + renderLight.lightRadius[1] = + renderLight.lightRadius[2] = spawnArgs.GetFloat( "explode_light_radius" ); + spawnArgs.GetVector( "explode_light_color", "1 1 1", lightColor ); + renderLight.shaderParms[SHADERPARM_RED] = lightColor.x; + renderLight.shaderParms[SHADERPARM_GREEN] = lightColor.y; + renderLight.shaderParms[SHADERPARM_BLUE] = lightColor.z; + renderLight.shaderParms[SHADERPARM_ALPHA] = 1.0f; + renderLight.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + renderLight.noShadows = spawnArgs.GetBool("explode_light_noshadows", "0"); + light_fadetime = spawnArgs.GetFloat( "explode_light_fadetime", "0.5" ); + lightStartTime = gameLocal.time; + lightEndTime = gameLocal.time + SEC2MS( light_fadetime ); + BecomeActive( TH_THINK ); + } + + // store the last known velocity and angular velocity for later use + tempVel = GetPhysics()->GetLinearVelocity(); + tempAngVel = GetPhysics()->GetAngularVelocity(); + + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.PutToRest(); + + state = EXPLODED; + BecomeInactive( TH_ARMED ); // grayman #2478 - disable armed thinking + + if ( gameLocal.isClient ) { + return; + } + + // + // bind the projectile to the impact entity if necesary + // NOW: with special handling for the bind to AFEntity case. + // Lloyd: Fixed binding objects to bodies: this doesn't work for animated objects, + // need to bind to joints instead + if ( gameLocal.entities[collision.c.entityNum] && spawnArgs.GetBool( "bindOnImpact" ) ) { + idEntity *e = gameLocal.entities[ collision.c.entityNum ]; + + if( e->IsType( idAFEntity_Base::Type ) ) { + +// idAFEntity_Base *af = static_cast< idAFEntity_Base * >( e ); + + this->BindToJoint( e, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ), true ); + } + else { + Bind( gameLocal.entities[collision.c.entityNum], true ); + } + } + + // splash damage + if ( !projectileFlags.noSplashDamage ) { + float delay = spawnArgs.GetFloat( "delay_splash" ); + if ( delay ) { + if ( removeTime < delay * 1000 ) { + removeTime = static_cast( delay + 0.10f ) * 1000; + } + PostEventSec( &EV_RadiusDamage, delay, ignore ); + } else { + Event_RadiusDamage( ignore ); + } + } + + // spawn debris entities + int fxdebris = spawnArgs.GetInt( "debris_count" ); + if ( fxdebris ) { + const idDict *debris = gameLocal.FindEntityDefDict( "projectile_debris", false ); + if ( debris ) { + int amount = gameLocal.random.RandomInt( fxdebris ); + for ( int i = 0; i < amount; i++ ) { + idEntity *ent; + idVec3 dir; + dir.x = gameLocal.random.CRandomFloat() * 4.0f; + dir.y = gameLocal.random.CRandomFloat() * 4.0f; + dir.z = gameLocal.random.RandomFloat() * 8.0f; + dir.Normalize(); + + gameLocal.SpawnEntityDef( *debris, &ent, false ); + if ( !ent || !ent->IsType( idDebris::Type ) ) { + gameLocal.Error( "'projectile_debris' is not an idDebris" ); + } + + idDebris *debris = static_cast(ent); + debris->Create( owner.GetEntity(), physicsObj.GetOrigin(), dir.ToMat3() ); + debris->Launch(); + } + } + debris = gameLocal.FindEntityDefDict( "projectile_shrapnel", false ); + if ( debris ) { + int amount = gameLocal.random.RandomInt( fxdebris ); + for ( int i = 0; i < amount; i++ ) { + idEntity *ent; + idVec3 dir; + dir.x = gameLocal.random.CRandomFloat() * 8.0f; + dir.y = gameLocal.random.CRandomFloat() * 8.0f; + dir.z = gameLocal.random.RandomFloat() * 8.0f + 8.0f; + dir.Normalize(); + + gameLocal.SpawnEntityDef( *debris, &ent, false ); + if ( !ent || !ent->IsType( idDebris::Type ) ) { + gameLocal.Error( "'projectile_shrapnel' is not an idDebris" ); + } + + idDebris *debris = static_cast(ent); + debris->Create( owner.GetEntity(), physicsObj.GetOrigin(), dir.ToMat3() ); + debris->Launch(); + } + } + } + + // DarkMod: Spawn projectile result entity + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Checking projectile result:\r" ); + if( spawnArgs.GetBool( "has_result", "0" ) ) + { + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Has_result set to true\r" ); + const char* resultName = spawnArgs.GetString("def_result"); + + const idDict *resultDef = gameLocal.FindEntityDefDict( resultName, false ); + if( resultDef ) + { + idEntity *ent2; + + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("Result object found for projectile %s\r", name.c_str()); + + gameLocal.SpawnEntityDef( *resultDef, &ent2, false ); + if ( !ent2 || !ent2->IsType( CProjectileResult::Type ) ) + { + DM_LOG(LC_WEAPON, LT_ERROR)LOGSTRING("Projectile %s has a non projectile result entity in projectile_result.\r", name.c_str()); + gameLocal.Error( "'projectile_result' is not a CProjectileResult" ); + } + + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Spawned projectile result\r" ); + + CProjectileResult *result = static_cast( ent2 ); + + // Populate the data object to pass to the projectile result object + SFinalProjData DataIn; + + DataIn.Owner = owner.GetEntity(); + DataIn.FinalOrigin = collision.endpos; + DataIn.FinalAxis = GetPhysics()->GetAxis(); + DataIn.LinVelocity = tempVel; + DataIn.AngVelocity = tempAngVel; + // rotate the axial direction by the axis to get world direction vector + DataIn.AxialDir = DataIn.FinalAxis * spawnArgs.GetVector( "axial_dir", "0 0 1" ); + DataIn.mass = GetPhysics()->GetMass(); + DataIn.SurfaceType = SurfTypeName; + + // Set up the projectile result with the last known results of the projectile + result->Init( &DataIn, collision, this, bActivated ); + } + } + + CancelEvents( &EV_Explode ); + PostEventMS( &EV_Remove, removeTime ); + + // grayman #2885 - turn off any visual stims this projectile is generating + + if ( GetStimResponseCollection()->HasStim() ) + { + GetStimResponseCollection()->RemoveStim( ST_VISUAL ); + } +} + +// grayman #2934 + +void idProjectile::AttackAction(idPlayer* player) +{ + if ( m_Lock != NULL ) + { + m_Lock->AttackAction(player); + } +} + + + +/* +================ +idProjectile::GetVelocity +================ +*/ +idVec3 idProjectile::GetVelocity( const idDict *projectile ) { + idVec3 velocity; + + projectile->GetVector( "velocity", "0 0 0", velocity ); + return velocity; +} + +/* +================ +idProjectile::GetGravity +================ +*/ +idVec3 idProjectile::GetGravity( const idDict *projectile ) { + float gravity; + + gravity = projectile->GetFloat( "gravity" ); + return idVec3( 0, 0, -gravity ); +} + +/* +================ +idProjectile::Event_Launch +================ +*/ +void idProjectile::Event_Launch( idVec3 const &origin, idVec3 const &direction, idVec3 const &velocity ) { + Launch(origin, direction, velocity); +} + +/* +================ +idProjectile::Event_Explode +================ +*/ +void idProjectile::Event_Explode( void ) { + trace_t collision; + + memset( &collision, 0, sizeof( collision ) ); + collision.endAxis = GetPhysics()->GetAxis(); + collision.endpos = GetPhysics()->GetOrigin(); + collision.c.point = GetPhysics()->GetOrigin(); + collision.c.normal.Set( 0, 0, 1 ); + AddDefaultDamageEffect( collision, collision.c.normal ); + Explode( collision, NULL ); +} + +/* +================ +idProjectile::MineExplode - grayman #2478 +================ +*/ +void idProjectile::MineExplode( int entityNumber ) // entityNumber belongs to the entity that stepped on you +{ + if ( state == LAUNCHED ) // only explode if you're armed and haven't already blown up + { + trace_t collision; + memset( &collision, 0, sizeof( collision ) ); + collision.endAxis = GetPhysics()->GetAxis(); + collision.endpos = GetPhysics()->GetOrigin(); + collision.c.point = collision.endpos; + collision.c.normal.Set( 0, 0, 1 ); + collision.c.entityNum = entityNumber; + AddDefaultDamageEffect( collision, collision.c.normal ); + Collide( collision, idVec3(0,0,0) ); + } +} + +/* +================ +idProjectile::Event_Fizzle +================ +*/ +void idProjectile::Event_Fizzle( void ) { + Fizzle(); +} + +/* +================ +idProjectile::Event_Touch +================ +*/ +void idProjectile::Event_Touch( idEntity *other, trace_t *trace ) +{ + if ( state == INACTIVE ) { + // greebo: projectile not active yet, return FALSE + return; + } + + if ( IsHidden() ) { + return; + } + + if ( other != owner.GetEntity() ) { + trace_t collision; + memset( &collision, 0, sizeof( collision ) ); + collision.endAxis = GetPhysics()->GetAxis(); + collision.endpos = GetPhysics()->GetOrigin(); + collision.c.point = GetPhysics()->GetOrigin(); + collision.c.normal.Set( 0, 0, 1 ); + AddDefaultDamageEffect( collision, collision.c.normal ); + Explode( collision, NULL ); + } +} + +/* +================= +idProjectile::ClientPredictionCollide +================= +*/ +bool idProjectile::ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect ) { + idEntity *ent; + + // remove projectile when a 'noimpact' surface is hit + if ( collision.c.material && ( collision.c.material->GetSurfaceFlags() & SURF_NOIMPACT ) ) { + return false; + } + + // get the entity the projectile collided with + ent = gameLocal.entities[ collision.c.entityNum ]; + if ( ent == NULL ) { + return false; + } + + // At this point it's for sure that the projectile is colliding with an entity, check the type + + // don't do anything if hitting a noclip player + if ( ent->IsType( idPlayer::Type ) && static_cast( ent )->noclip ) { + return false; + } + + // Are we hitting an actor? + if ( ent->IsType( idActor::Type ) || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody()->IsType( idActor::Type ) ) ) { + // Yes, check if we should detonate on actors + if ( !projectileDef.GetBool( "detonate_on_actor" ) ) { + return false; + } + } else { + // Not an actor, check if we should detonate on something else + if ( !projectileDef.GetBool( "detonate_on_world" ) ) { + return false; + } + } + + // if the projectile causes a damage effect + if ( addDamageEffect && projectileDef.GetBool( "impact_damage_effect" ) ) { + // if the hit entity does not have a special damage effect + if ( !ent->spawnArgs.GetBool( "bleed" ) ) { + // predict damage effect + DefaultDamageEffect( soundEnt, projectileDef, collision, velocity ); + } + } + return true; +} + +/* +================ +idProjectile::ClientPredictionThink +================ +*/ +void idProjectile::ClientPredictionThink( void ) { + if ( !renderEntity.hModel ) { + return; + } + Think(); +} + +/* +================ +idProjectile::WriteToSnapshot +================ +*/ +void idProjectile::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteBits( owner.GetSpawnId(), 32 ); + + msg.WriteBits( state, 3 ); + + msg.WriteBits( fl.hidden, 1 ); + + if ( netSyncPhysics ) { + + msg.WriteBits( 1, 1 ); + + physicsObj.WriteToSnapshot( msg ); + + } else { + + msg.WriteBits( 0, 1 ); + + const idVec3 &origin = physicsObj.GetOrigin(); + + const idVec3 &velocity = physicsObj.GetLinearVelocity(); + + + + msg.WriteFloat( origin.x ); + + msg.WriteFloat( origin.y ); + + msg.WriteFloat( origin.z ); + + + + msg.WriteDeltaFloat( 0.0f, velocity[0], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + msg.WriteDeltaFloat( 0.0f, velocity[1], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + msg.WriteDeltaFloat( 0.0f, velocity[2], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + } + +} + +/* +================ +idProjectile::ReadFromSnapshot +================ +*/ +void idProjectile::ReadFromSnapshot( const idBitMsgDelta &msg ) { + projectileState_t newState; + + owner.SetSpawnId( msg.ReadBits( 32 ) ); + newState = (projectileState_t) msg.ReadBits( 3 ); + if ( msg.ReadBits( 1 ) ) { + Hide(); + } else { + Show(); + } + + while( state != newState ) { + switch( state ) { + case SPAWNED: { + Create( owner.GetEntity(), vec3_origin, idVec3( 1, 0, 0 ) ); + break; + } + case CREATED: { + // the right origin and direction are required if you want bullet traces + Launch( vec3_origin, idVec3( 1, 0, 0 ), vec3_origin ); + break; + } + case LAUNCHED: { + if ( newState == FIZZLED ) { + Fizzle(); + } else { + trace_t collision; + memset( &collision, 0, sizeof( collision ) ); + collision.endAxis = GetPhysics()->GetAxis(); + collision.endpos = GetPhysics()->GetOrigin(); + collision.c.point = GetPhysics()->GetOrigin(); + collision.c.normal.Set( 0, 0, 1 ); + Explode( collision, NULL ); + } + break; + } + case FIZZLED: + case EXPLODED: { + StopSound( SND_CHANNEL_BODY2, false ); + gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &renderEntity ); + state = SPAWNED; + break; + } + case INACTIVE: { + state = INACTIVE; + break; + } + } + } + + if ( msg.ReadBits( 1 ) ) { + + physicsObj.ReadFromSnapshot( msg ); + + } else { + + idVec3 origin; + + idVec3 velocity; + + idVec3 tmp; + + idMat3 axis; + + + + origin.x = msg.ReadFloat(); + + origin.y = msg.ReadFloat(); + + origin.z = msg.ReadFloat(); + + + + velocity.x = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + velocity.y = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + velocity.z = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + + + + physicsObj.SetOrigin( origin ); + + physicsObj.SetLinearVelocity( velocity ); + + + + // align z-axis of model with the direction + + velocity.NormalizeFast(); + + axis = velocity.ToMat3(); + + tmp = axis[2]; + + axis[2] = axis[0]; + + axis[0] = -tmp; + + physicsObj.SetAxis( axis ); + + } + + + + if ( msg.HasChanged() ) { + + UpdateVisuals(); + + } + +} + +/* +================ +idProjectile::ClientReceiveEvent +================ +*/ +bool idProjectile::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + trace_t collision; + idVec3 velocity; + + switch( event ) { + case EVENT_DAMAGE_EFFECT: { + memset( &collision, 0, sizeof( collision ) ); + collision.c.point[0] = msg.ReadFloat(); + collision.c.point[1] = msg.ReadFloat(); + collision.c.point[2] = msg.ReadFloat(); + collision.c.normal = msg.ReadDir( 24 ); + int index = gameLocal.ClientRemapDecl( DECL_MATERIAL, msg.ReadLong() ); + collision.c.material = ( index != -1 ) ? static_cast( declManager->DeclByIndex( DECL_MATERIAL, index ) ) : NULL; + velocity[0] = msg.ReadFloat( 5, 10 ); + velocity[1] = msg.ReadFloat( 5, 10 ); + velocity[2] = msg.ReadFloat( 5, 10 ); + DefaultDamageEffect( this, spawnArgs, collision, velocity ); + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +================ +idProjectile::TestActivated +DarkMod Addition +================ +*/ + +bool idProjectile::TestActivated( const char *typeName ) +{ + bool bReturnVal(false), bAssumeActive(false); + idStr MaterialsList; + + if( !spawnArgs.GetBool( "assume_active", "0" ) ) + { + if( !spawnArgs.GetString( "active_surfaces", "", MaterialsList ) + || !typeName ) + { + // return false if the surfaces list is blank + goto Quit; + } + } + else + { + bAssumeActive = true; + + if( !spawnArgs.GetString( "dud_surfaces", "", MaterialsList ) + || !typeName ) + { + // return true if the surfaces list is blank and we assume active + bReturnVal = true; + goto Quit; + } + } + + // pad front and back with spaces for unique name searching + MaterialsList.Insert(' ', 0 ); + MaterialsList.Append(' '); + + bReturnVal = ( MaterialsList.Find( va(" %s ", typeName) ) != -1 ); + // this XOR should cover both cases, assumed active and found dud, assumed dud found active + bReturnVal ^= bAssumeActive; + +Quit: + return bReturnVal; +} + +/* +========================= +idProjectile::CanBeUsedBy - grayman #2478 +========================= +*/ + +bool idProjectile::CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse) +{ + if (item == NULL) + { + return false; + } + + assert(item->Category() != NULL); + + // FIXME: Move this to idEntity to some sort of "usable_by_inv_category" list? + const idStr& categoryName = item->Category()->GetName(); + if (categoryName == "#str_02389" ) // Lockpicks + { + if (!m_Lock->IsPickable()) + { + // Lock is not pickable + return false; + } + + // Lockpicks behave similar to keys + return (isFrobUse) ? IsLocked() : true; + } + + return false; +} + +/* +=================== +idProjectile::UseBy - grayman #2478 +=================== +*/ + +bool idProjectile::UseBy(EImpulseState impulseState, const CInventoryItemPtr& item) +{ + if (item == NULL) + { + return false; + } + + assert(item->Category() != NULL); + + // Retrieve the entity behind that item and reject NULL entities + idEntity* itemEntity = item->GetItemEntity(); + if (itemEntity == NULL) + { + return false; + } + + // Get the name of this inventory category + const idStr& categoryName = item->Category()->GetName(); + + if (categoryName == "#str_02389" ) // Lockpicks + { + if (!m_Lock->IsPickable()) + { + // Lock is not pickable + DM_LOG(LC_LOCKPICK, LT_DEBUG)LOGSTRING("FrobDoor %s is not pickable\r", name.c_str()); + return false; + } + + // Lockpicks are different, we need to look at the button state + // First we check if this item is a lockpick. It has to be of the toolclass lockpick + // and the type must be set. + idStr str = itemEntity->spawnArgs.GetString( "lockpick_type", "" ); + + if (str.Length() == 1) + { + // greebo: Check if the item owner is a player, and if yes, + // update the immobilization flags. + idEntity* itemOwner = item->GetOwner(); + + if (itemOwner->IsType(idPlayer::Type)) + { + idPlayer* playerOwner = static_cast(itemOwner); + playerOwner->SetImmobilization("Lockpicking", EIM_ATTACK); + + // Schedule an event 1/3 sec. from now, to enable weapons again after this time + CancelEvents(&EV_TDM_Mine_ClearPlayerImmobilization); + PostEventMS(&EV_TDM_Mine_ClearPlayerImmobilization, 300, playerOwner); + } + + // Pass the call to the lockpick routine + return m_Lock->ProcessLockpickImpulse(impulseState, static_cast(str[0])); + } + else + { + gameLocal.Warning("Wrong 'type' spawnarg for lockpicking on item %s, must be a single character.", itemEntity->name.c_str()); + return false; + } + } + + return false; +} + +/* +====================== +idProjectile::IsLocked - grayman #2478 +====================== +*/ + +bool idProjectile::IsLocked() +{ + return m_Lock->IsLocked(); +} + +/* +============================================= +idProjectile::Event_ClearPlayerImmobilization - grayman #2478 +============================================= +*/ + +void idProjectile::Event_ClearPlayerImmobilization(idEntity* player) +{ + if (!player->IsType(idPlayer::Type)) + { + return; + } + + // Release the immobilization imposed on the player by Lockpicking + static_cast(player)->SetImmobilization("Lockpicking", 0); +} + +/* +===================================== +idProjectile::Event_Lock_OnLockPicked - grayman #2478 +===================================== +*/ + +void idProjectile::Event_Lock_OnLockPicked() +{ + // "Lock is picked" signal + + m_Lock->SetLocked(false); + state = INACTIVE; // disarm the mine + BecomeInactive( TH_ARMED ); // disable armed thinking + StartSound( "snd_mine_disarmed", SND_CHANNEL_BODY, 0, true, NULL ); + SetFrobable(false); // can't frob this until after the disarm sound is finished + PostEventSec( &EV_Mine_Replace, 1.0f ); +} + +/* +================================ +idProjectile::Event_Mine_Replace - grayman #2478 +================================ +*/ + +void idProjectile::Event_Mine_Replace() +{ + // Change the projectile into a mine entity the player can put back into inventory. + + const char* resultName = spawnArgs.GetString("def_disarmed"); + + const idDict *resultDef = gameLocal.FindEntityDefDict( resultName, false ); + if ( resultDef ) + { + idEntity *newMine; + gameLocal.SpawnEntityDef( *resultDef, &newMine, false ); + newMine->GetPhysics()->SetOrigin( GetPhysics()->GetOrigin() ); + newMine->GetPhysics()->SetAxis( GetPhysics()->GetAxis() ); + newMine->BecomeInactive( TH_PHYSICS ); // turn off physics so the new mine doesn't sink through the floor + + SetFrobable(false); + PostEventMS( &EV_Remove, 1 ); // Remove the projectile, which has been replaced + } +} + +/* +=============================================================================== + + idGuidedProjectile + +=============================================================================== +*/ + +CLASS_DECLARATION( idProjectile, idGuidedProjectile ) +END_CLASS + +/* +================ +idGuidedProjectile::idGuidedProjectile +================ +*/ +idGuidedProjectile::idGuidedProjectile( void ) { + enemy = NULL; + speed = 0.0f; + turn_max = 0.0f; + clamp_dist = 0.0f; + rndScale = ang_zero; + rndAng = ang_zero; + rndUpdateTime = 0; + angles = ang_zero; + burstMode = false; + burstDist = 0; + burstVelocity = 0.0f; + unGuided = false; +} + +/* +================= +idGuidedProjectile::~idGuidedProjectile +================= +*/ +idGuidedProjectile::~idGuidedProjectile( void ) { +} + +/* +================ +idGuidedProjectile::Spawn +================ +*/ +void idGuidedProjectile::Spawn( void ) { +} + +/* +================ +idGuidedProjectile::Save +================ +*/ +void idGuidedProjectile::Save( idSaveGame *savefile ) const { + enemy.Save( savefile ); + savefile->WriteFloat( speed ); + savefile->WriteAngles( rndScale ); + savefile->WriteAngles( rndAng ); + savefile->WriteInt( rndUpdateTime ); + savefile->WriteFloat( turn_max ); + savefile->WriteFloat( clamp_dist ); + savefile->WriteAngles( angles ); + savefile->WriteBool( burstMode ); + savefile->WriteBool( unGuided ); + savefile->WriteFloat( burstDist ); + savefile->WriteFloat( burstVelocity ); + // The lock class is saved by the idSaveGame class on close, no need to handle it here + savefile->WriteObject(m_Lock); // grayman #2478 +} + +/* +================ +idGuidedProjectile::Restore +================ +*/ +void idGuidedProjectile::Restore( idRestoreGame *savefile ) { + enemy.Restore( savefile ); + savefile->ReadFloat( speed ); + savefile->ReadAngles( rndScale ); + savefile->ReadAngles( rndAng ); + savefile->ReadInt( rndUpdateTime ); + savefile->ReadFloat( turn_max ); + savefile->ReadFloat( clamp_dist ); + savefile->ReadAngles( angles ); + savefile->ReadBool( burstMode ); + savefile->ReadBool( unGuided ); + savefile->ReadFloat( burstDist ); + savefile->ReadFloat( burstVelocity ); + // The lock class is restored by the idRestoreGame, don't handle it here + savefile->ReadObject(reinterpret_cast(m_Lock)); // grayman #2478 +} + + +/* +================ +idGuidedProjectile::GetSeekPos +================ +*/ +void idGuidedProjectile::GetSeekPos( idVec3 &out ) { + idEntity *enemyEnt = enemy.GetEntity(); + if ( enemyEnt ) { + if ( enemyEnt->IsType( idActor::Type ) ) { + out = static_cast(enemyEnt)->GetEyePosition(); + out.z -= 12.0f; + } else { + out = enemyEnt->GetPhysics()->GetOrigin(); + } + } else { + out = GetPhysics()->GetOrigin() + physicsObj.GetLinearVelocity() * 2.0f; + } +} + +/* +================ +idGuidedProjectile::Think +================ +*/ +void idGuidedProjectile::Think( void ) { + idVec3 dir; + idVec3 seekPos; + idVec3 velocity; + idVec3 nose; + idVec3 tmp; + idMat3 axis; + idAngles dirAng; + idAngles diff; + float dist; + float frac; + int i; + + if ( state == LAUNCHED && !unGuided ) { + + GetSeekPos( seekPos ); + + if ( rndUpdateTime < gameLocal.time ) { + rndAng[ 0 ] = rndScale[ 0 ] * gameLocal.random.CRandomFloat(); + rndAng[ 1 ] = rndScale[ 1 ] * gameLocal.random.CRandomFloat(); + rndAng[ 2 ] = rndScale[ 2 ] * gameLocal.random.CRandomFloat(); + rndUpdateTime = gameLocal.time + 200; + } + + nose = physicsObj.GetOrigin() + 10.0f * physicsObj.GetAxis()[0]; + + dir = seekPos - nose; + dist = dir.Normalize(); + dirAng = dir.ToAngles(); + + // make it more accurate as it gets closer + frac = dist / clamp_dist; + if ( frac > 1.0f ) { + frac = 1.0f; + } + + diff = dirAng - angles + rndAng * frac; + + // clamp the to the max turn rate + diff.Normalize180(); + for( i = 0; i < 3; i++ ) { + if ( diff[ i ] > turn_max ) { + diff[ i ] = turn_max; + } else if ( diff[ i ] < -turn_max ) { + diff[ i ] = -turn_max; + } + } + angles += diff; + + // make the visual model always points the dir we're traveling + dir = angles.ToForward(); + velocity = dir * speed; + + if ( burstMode && dist < burstDist ) { + unGuided = true; + velocity *= burstVelocity; + } + + physicsObj.SetLinearVelocity( velocity ); + + // align z-axis of model with the direction + axis = dir.ToMat3(); + tmp = axis[2]; + axis[2] = axis[0]; + axis[0] = -tmp; + + GetPhysics()->SetAxis( axis ); + } + + idProjectile::Think(); +} + +/* +================= +idGuidedProjectile::Launch +================= +*/ +void idGuidedProjectile::Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire, const float launchPower, float dmgPower ) { + idProjectile::Launch( start, dir, pushVelocity, timeSinceFire, launchPower, dmgPower ); + if ( owner.GetEntity() ) { + if ( owner.GetEntity()->IsType( idAI::Type ) ) { + enemy = static_cast( owner.GetEntity() )->GetEnemy(); + } else if ( owner.GetEntity()->IsType( idPlayer::Type ) ) { + trace_t tr; + idPlayer *player = static_cast( owner.GetEntity() ); + idVec3 start = player->GetEyePosition(); + idVec3 end = start + player->viewAxis[0] * 1000.0f; + gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL | CONTENTS_BODY, owner.GetEntity() ); + if ( tr.fraction < 1.0f ) { + enemy = gameLocal.GetTraceEntity( tr ); + } + // ignore actors on the player's team + if ( enemy.GetEntity() == NULL || !enemy.GetEntity()->IsType( idActor::Type ) || ( static_cast( enemy.GetEntity() )->team == player->team ) ) { + enemy = player->EnemyWithMostHealth(); + } + } + } + const idVec3 &vel = physicsObj.GetLinearVelocity(); + angles = vel.ToAngles(); + speed = vel.Length(); + rndScale = spawnArgs.GetAngles( "random", "15 15 0" ); + turn_max = spawnArgs.GetFloat( "turn_max", "180" ) / ( float )USERCMD_HZ; + clamp_dist = spawnArgs.GetFloat( "clamp_dist", "256" ); + burstMode = spawnArgs.GetBool( "burstMode" ); + unGuided = false; + burstDist = spawnArgs.GetFloat( "burstDist", "64" ); + burstVelocity = spawnArgs.GetFloat( "burstVelocity", "1.25" ); + UpdateVisuals(); +} + + +/* +=============================================================================== + + idDebris + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idDebris ) +EVENT( EV_Explode, idDebris::Event_Explode ) +EVENT( EV_Fizzle, idDebris::Event_Fizzle ) +END_CLASS + +/* +================ +idDebris::Spawn +================ +*/ +void idDebris::Spawn( void ) { + owner = NULL; + smokeFly = NULL; + smokeFlyTime = 0; +} + +/* +================ +idDebris::Create +================ +*/ +void idDebris::Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ) { + Unbind(); + GetPhysics()->SetOrigin( start ); + GetPhysics()->SetAxis( axis ); + GetPhysics()->SetContents( 0 ); + this->owner = owner; + smokeFly = NULL; + smokeFlyTime = 0; + sndBounce = NULL; + UpdateVisuals(); +} + +/* +================= +idDebris::idDebris +================= +*/ +idDebris::idDebris( void ) { + owner = NULL; + smokeFly = NULL; + smokeFlyTime = 0; + sndBounce = NULL; +} + +/* +================= +idDebris::~idDebris +================= +*/ +idDebris::~idDebris( void ) { +} + +/* +================= +idDebris::Save +================= +*/ +void idDebris::Save( idSaveGame *savefile ) const { + owner.Save( savefile ); + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteParticle( smokeFly ); + savefile->WriteInt( smokeFlyTime ); + savefile->WriteSoundShader( sndBounce ); +} + +/* +================= +idDebris::Restore +================= +*/ +void idDebris::Restore( idRestoreGame *savefile ) { + owner.Restore( savefile ); + + savefile->ReadStaticObject( physicsObj ); + RestorePhysics( &physicsObj ); + + savefile->ReadParticle( smokeFly ); + savefile->ReadInt( smokeFlyTime ); + savefile->ReadSoundShader( sndBounce ); +} + +/* +================= +idDebris::Launch +================= +*/ +void idDebris::Launch( void ) { + float fuse; + idVec3 velocity; + idAngles angular_velocity; + float linear_friction; + float angular_friction; + float contact_friction; + float bounce; + float mass; + float gravity; + idVec3 gravVec; + bool randomVelocity; + idMat3 axis; + + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + spawnArgs.GetVector( "velocity", "0 0 0", velocity ); + spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); + + linear_friction = spawnArgs.GetFloat( "linear_friction" ); + angular_friction = spawnArgs.GetFloat( "angular_friction" ); + contact_friction = spawnArgs.GetFloat( "contact_friction" ); + bounce = spawnArgs.GetFloat( "bounce" ); + mass = spawnArgs.GetFloat( "mass" ); + gravity = spawnArgs.GetFloat( "gravity" ); + fuse = spawnArgs.GetFloat( "fuse" ); + randomVelocity = spawnArgs.GetBool ( "random_velocity" ); + + if ( mass <= 0 ) { + gameLocal.Error( "Invalid mass on '%s'\n", GetEntityDefName() ); + } + + if ( randomVelocity ) { + velocity.x *= gameLocal.random.RandomFloat() + 0.5f; + velocity.y *= gameLocal.random.RandomFloat() + 0.5f; + velocity.z *= gameLocal.random.RandomFloat() + 0.5f; + } + + if ( health ) { + fl.takedamage = true; + } + + gravVec = gameLocal.GetGravity(); + gravVec.NormalizeFast(); + axis = GetPhysics()->GetAxis(); + + Unbind(); + + physicsObj.SetSelf( this ); + + // check if a clip model is set + const char *clipModelName; + idTraceModel trm; + spawnArgs.GetString( "clipmodel", "", &clipModelName ); + if ( !clipModelName[0] ) { + clipModelName = spawnArgs.GetString( "model" ); // use the visual model + } + + // load the trace model + if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { + // default to a box + physicsObj.SetClipBox( renderEntity.bounds, 1.0f ); + } else { + physicsObj.SetClipModel( new idClipModel( trm ), 1.0f ); + } + + physicsObj.GetClipModel()->SetOwner( owner.GetEntity() ); + physicsObj.SetMass( mass ); + physicsObj.SetFriction( linear_friction, angular_friction, contact_friction ); + if ( contact_friction == 0.0f ) { + physicsObj.NoContact(); + } + physicsObj.SetBouncyness( bounce ); + physicsObj.SetGravity( gravVec * gravity ); + physicsObj.SetContents( 0 ); + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); + physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); + physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( axis ); + SetPhysics( &physicsObj ); + + if ( !gameLocal.isClient ) { + if ( fuse <= 0 ) { + // run physics for 1 second + RunPhysics(); + PostEventMS( &EV_Remove, 0 ); + } else if ( spawnArgs.GetBool( "detonate_on_fuse" ) ) { + if ( fuse < 0.0f ) { + fuse = 0.0f; + } + RunPhysics(); + PostEventSec( &EV_Explode, fuse ); + } else { + if ( fuse < 0.0f ) { + fuse = 0.0f; + } + PostEventSec( &EV_Fizzle, fuse ); + } + } + + StartSound( "snd_fly", SND_CHANNEL_BODY, 0, false, NULL ); + + smokeFly = NULL; + smokeFlyTime = 0; + const char *smokeName = spawnArgs.GetString( "smoke_fly" ); + if ( *smokeName != '\0' ) { + smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + smokeFlyTime = gameLocal.time; + gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + } + + const char *sndName = spawnArgs.GetString( "snd_bounce" ); + if ( *sndName != '\0' ) { + sndBounce = declManager->FindSound( sndName ); + } + + UpdateVisuals(); +} + +/* +================ +idDebris::Think +================ +*/ +void idDebris::Think( void ) { + + // run physics + RunPhysics(); + Present(); + + if ( smokeFly && smokeFlyTime ) { + if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { + smokeFlyTime = 0; + } + } +} + +/* +================ +idDebris::Killed +================ +*/ +void idDebris::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + if ( spawnArgs.GetBool( "detonate_on_death" ) ) { + Explode(); + } else { + Fizzle(); + } +} + +/* +================= +idDebris::Collide +================= +*/ +bool idDebris::Collide( const trace_t &collision, const idVec3 &velocity ) { + if ( sndBounce != NULL ) { + StartSoundShader( sndBounce, SND_CHANNEL_BODY, 0, false, NULL ); + } + sndBounce = NULL; + return false; +} + + +/* +================ +idDebris::Fizzle +================ +*/ +void idDebris::Fizzle( void ) { + if ( IsHidden() ) { + // already exploded + return; + } + + StopSound( SND_CHANNEL_ANY, false ); + StartSound( "snd_fizzle", SND_CHANNEL_BODY, 0, false, NULL ); + + // fizzle FX + const char *smokeName = spawnArgs.GetString( "smoke_fuse" ); + if ( *smokeName != '\0' ) { + smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + smokeFlyTime = gameLocal.time; + gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + } + + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.PutToRest(); + + Hide(); + + if ( gameLocal.isClient ) { + return; + } + + CancelEvents( &EV_Fizzle ); + PostEventMS( &EV_Remove, 0 ); +} + +/* +================ +idDebris::Explode +================ +*/ +void idDebris::Explode( void ) { + if ( IsHidden() ) { + // already exploded + return; + } + + StopSound( SND_CHANNEL_ANY, false ); + StartSound( "snd_explode", SND_CHANNEL_BODY, 0, false, NULL ); + + Hide(); + + // these must not be "live forever" particle systems + smokeFly = NULL; + smokeFlyTime = 0; + const char *smokeName = spawnArgs.GetString( "smoke_detonate" ); + if ( *smokeName != '\0' ) { + smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + smokeFlyTime = gameLocal.time; + gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); + } + + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.PutToRest(); + + CancelEvents( &EV_Explode ); + PostEventMS( &EV_Remove, 0 ); +} + +/* +================ +idDebris::Event_Explode +================ +*/ +void idDebris::Event_Explode( void ) { + Explode(); +} + +/* +================ +idDebris::Event_Fizzle +================ +*/ +void idDebris::Event_Fizzle( void ) { + Fizzle(); +} + + diff --git a/game/Projectile.h b/game/Projectile.h new file mode 100644 index 000000000..c04883a88 --- /dev/null +++ b/game/Projectile.h @@ -0,0 +1,287 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_PROJECTILE_H__ +#define __GAME_PROJECTILE_H__ + +#include "PickableLock.h" +#include "Inventory/InventoryItem.h" +#include "Inventory/Category.h" + +/** +* SFinalProjData: Structure storing the final projectile data at impact +* Passed on to CProjectileResult object +**/ +typedef struct SFinalProjData_s +{ + /** + * greebo: The entity which fired the projectile + */ + idEntityPtr Owner; + + /** + * Final world position of the origin of the projectile on impact + **/ + idVec3 FinalOrigin; + + /** + * Final orientation of the projectile on impact + **/ + idMat3 FinalAxis; + + /** + * Final linear velocity of the projectile just before impact + **/ + idVec3 LinVelocity; + + /** + * Final angular velocity of the projectile just before impact + **/ + idVec3 AngVelocity; + + /** + * Direction vector for the axis of the arrow. Needed for pushing it in. + **/ + idVec3 AxialDir; + + /** + * Max Angle of incidence when projectile hits surface + * (Calculated in CProjectileResult::Init ) + **/ + float IncidenceAngle; + + /** + * Mass of the projectile (might be useful) + **/ + float mass; + + /** + * Name of the surface that was struck + **/ + idStr SurfaceType; + +} SFinalProjData; + +/* +=============================================================================== + + idProjectile + +=============================================================================== +*/ + +extern const idEventDef EV_Explode; +// greebo: Exposed projectile launch method to scripts +extern const idEventDef EV_Launch; + +class idProjectile : public idEntity { +public : + CLASS_PROTOTYPE( idProjectile ); + + idProjectile(); + virtual ~idProjectile(); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Create( idEntity *owner, const idVec3 &start, const idVec3 &dir ); + virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f ); + virtual void FreeLightDef( void ); + + idEntity * GetOwner( void ) const; + void SetReplaced(); // grayman #2908 + + virtual void Think( void ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + virtual void Explode( const trace_t &collision, idEntity *ignore ); + void Fizzle( void ); + + static idVec3 GetVelocity( const idDict *projectile ); + static idVec3 GetGravity( const idDict *projectile ); + + enum { + EVENT_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS, + EVENT_MAXEVENTS + }; + + static void DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity ); + static bool ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect ); + virtual void ClientPredictionThink( void ); + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + void MineExplode( int entityNumber ); // grayman #2478 + bool IsMine(); // grayman #2478 + bool IsArmed(); // grayman #2906 + void AttackAction(idPlayer* player); // grayman #2934 + void Event_ActivateProjectile(); + +protected: + idEntityPtr owner; + + struct projectileFlags_s { + bool detonate_on_world : 1; + bool detonate_on_actor : 1; + bool randomShaderSpin : 1; + bool isTracer : 1; + bool noSplashDamage : 1; + } projectileFlags; + + float thrust; + int thrust_end; + float damagePower; + + renderLight_t renderLight; + qhandle_t lightDefHandle; // handle to renderer light def + idVec3 lightOffset; + int lightStartTime; + int lightEndTime; + idVec3 lightColor; + + idForce_Constant thruster; + idPhysics_RigidBody physicsObj; + + const idDeclParticle * smokeFly; + int smokeFlyTime; + + typedef enum { + // must update these in script/doom_defs.script if changed + SPAWNED = 0, + CREATED = 1, + LAUNCHED = 2, + FIZZLED = 3, + EXPLODED = 4, + INACTIVE = 5 // greebo: this applies to mines that haven't become active yet + } projectileState_t; + + projectileState_t state; + + PickableLock* m_Lock; // grayman #2478 - A lock implementation for this mover + bool isMine; // grayman #2478 - true if this is a mine + bool replaced; // grayman #2908 - true if this is a projectile mine that replaced a map author-placed armed mine + +protected: + /** + * Determine whether the projectile "activates" based on the surface type argument + * This checks a space-delimited spawnarg list of activating materials and + * returns true if the struck material activates this projectile + **/ + bool TestActivated( const char *typeName ); + +private: + bool netSyncPhysics; + + void AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity ); + + void AddObjectsToSaveGame(idSaveGame* savefile); // grayman #2478 + bool CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse); // grayman #2478 + bool UseBy(EImpulseState impulseState, const CInventoryItemPtr& item); // grayman #2478 + bool IsLocked(); // grayman #2478 + void Event_ClearPlayerImmobilization(idEntity* player); // grayman #2478 + + void Event_Explode( void ); + void Event_Fizzle( void ); + void Event_RadiusDamage( idEntity *ignore ); + void Event_Touch( idEntity *other, trace_t *trace ); + void Event_GetProjectileState( void ); + void Event_Launch( idVec3 const &origin, idVec3 const &direction, idVec3 const &velocity ); + void Event_Lock_OnLockPicked(); // grayman #2478 + void Event_Mine_Replace(); // grayman #2478 + float AngleAdjust(float angle); // grayman #2478 + void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); // grayman #2478 +}; + +class idGuidedProjectile : public idProjectile { +public : + CLASS_PROTOTYPE( idGuidedProjectile ); + + idGuidedProjectile( void ); + ~idGuidedProjectile( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + virtual void Think( void ); + virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f ); + +protected: + float speed; + idEntityPtr enemy; + virtual void GetSeekPos( idVec3 &out ); + +private: + idAngles rndScale; + idAngles rndAng; + idAngles angles; + int rndUpdateTime; + float turn_max; + float clamp_dist; + bool burstMode; + bool unGuided; + float burstDist; + float burstVelocity; +}; + + +/* +=============================================================================== + + idDebris + +=============================================================================== +*/ + +class idDebris : public idEntity { +public : + CLASS_PROTOTYPE( idDebris ); + + idDebris(); + ~idDebris(); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void Spawn( void ); + + void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ); + void Launch( void ); + void Think( void ); + void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + void Explode( void ); + void Fizzle( void ); + virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); + + +private: + idEntityPtr owner; + idPhysics_RigidBody physicsObj; + const idDeclParticle * smokeFly; + int smokeFlyTime; + const idSoundShader * sndBounce; + + void Event_Explode( void ); + void Event_Fizzle( void ); +}; + +#endif /* !__GAME_PROJECTILE_H__ */ diff --git a/DarkMod/ProjectileResult.cpp b/game/ProjectileResult.cpp similarity index 93% rename from DarkMod/ProjectileResult.cpp rename to game/ProjectileResult.cpp index 6a487a644..44fb6147d 100644 --- a/DarkMod/ProjectileResult.cpp +++ b/game/ProjectileResult.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2006 Chris Sarantos @@ -15,8 +25,8 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "ProjectileResult.h" -#include "../game/game_local.h" -#include "../game/projectile.h" +#include "Game_local.h" +#include "Projectile.h" #include "StimResponse/Stim.h" #include "DarkModGlobals.h" diff --git a/game/ProjectileResult.h b/game/ProjectileResult.h new file mode 100644 index 000000000..ba96e0bdc --- /dev/null +++ b/game/ProjectileResult.h @@ -0,0 +1,99 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2006 Chris Sarantos + +#ifndef PROJECTILE_RESULT_H +#define PROJECTILE_RESULT_H + +/** +* CProjectileResult is a dummy object that may be spawned when a projectile hits +* a surface. This object handles things like determining whether the projectile +* sticks in to the surface and may be retrieved, or if it breaks. This object +* is also used to store any stim/response information on the projectile (e.g., +* water arrow puts out torches when it detonates), and run other scripts if desired. +* +* NOTE: This object MUST be destroyed/removed in the scripts that are run +**/ + + +class CProjectileResult : public idEntity { +public: + CLASS_PROTOTYPE( CProjectileResult ); + + CProjectileResult(void); + ~CProjectileResult(void); + +/** +* Initialize the projectile result, called by the projectile +**/ + void Init + ( + SFinalProjData *pData, const trace_t &collision, + idProjectile *pProj, bool bActivate + ); + +protected: + /** + * Chooses whether to run the "active" or "dud" script, based on the material + * type hit and the activating material types. + **/ + void RunResultScript( void ); + +protected: + /** + * Collision data from the impacted projectile + **/ + trace_t m_Collision; + + /** + * Other data from the impacted projectile + **/ + SFinalProjData m_ProjData; + + /** + * True => projectile activated, false => projectile is a dud + **/ + bool m_bActivated; + + /** + * Getter events for scripting + **/ + void Event_GetFinalVel( void ); + + void Event_GetFinalAngVel( void ); + + void Event_GetAxialDir( void ); + + void Event_GetProjMass( void ); + + void Event_GetSurfType( void ); + + void Event_GetSurfNormal( void ); + + void Event_GetStruckEnt( void ); + + void Event_GetIncidenceAngle( void ); + + void Event_GetActualStruckEnt( void ); // grayman #837 + + void Event_IsVineFriendly( void ); // grayman #2787 +}; + +#endif diff --git a/game/Pvs.cpp b/game/Pvs.cpp new file mode 100644 index 000000000..fe347f81c --- /dev/null +++ b/game/Pvs.cpp @@ -0,0 +1,1456 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +#define MAX_BOUNDS_AREAS 16 + + +typedef struct pvsPassage_s { + byte * canSee; // bit set for all portals that can be seen through this passage +} pvsPassage_t; + + +typedef struct pvsPortal_s { + int areaNum; // area this portal leads to + idWinding * w; // winding goes counter clockwise seen from the area this portal is part of + idBounds bounds; // winding bounds + idPlane plane; // winding plane, normal points towards the area this portal leads to + pvsPassage_t * passages; // passages to portals in the area this portal leads to + bool done; // true if pvs is calculated for this portal + byte * vis; // PVS for this portal + byte * mightSee; // used during construction +} pvsPortal_t; + + +typedef struct pvsArea_s { + int numPortals; // number of portals in this area + idBounds bounds; // bounds of the whole area + pvsPortal_t ** portals; // array with pointers to the portals of this area +} pvsArea_t; + + +typedef struct pvsStack_s { + struct pvsStack_s * next; // next stack entry + byte * mightSee; // bit set for all portals that might be visible through this passage/portal stack +} pvsStack_t; + + +/* +================ +idPVS::idPVS +================ +*/ +idPVS::idPVS( void ) { + int i; + + numAreas = 0; + numPortals = 0; + + connectedAreas = NULL; + areaQueue = NULL; + areaPVS = NULL; + + for ( i = 0; i < MAX_CURRENT_PVS; i++ ) { + currentPVS[i].handle.i = -1; + currentPVS[i].handle.h = 0; + currentPVS[i].pvs = NULL; + } + + pvsAreas = NULL; + pvsPortals = NULL; +} + +/* +================ +idPVS::~idPVS +================ +*/ +idPVS::~idPVS( void ) { + Shutdown(); +} + +/* +================ +idPVS::GetPortalCount +================ +*/ +int idPVS::GetPortalCount( void ) const { + int i, na, np; + + na = gameRenderWorld->NumAreas(); + np = 0; + for ( i = 0; i < na; i++ ) { + np += gameRenderWorld->NumPortalsInArea( i ); + } + return np; +} + +/* +================ +idPVS::CreatePVSData +================ +*/ +void idPVS::CreatePVSData( void ) { + int i, j, n, cp; + exitPortal_t portal; + pvsArea_t *area; + pvsPortal_t *p, **portalPtrs; + + if ( !numPortals ) { + return; + } + + pvsPortals = new pvsPortal_t[numPortals]; + pvsAreas = new pvsArea_t[numAreas]; + memset( pvsAreas, 0, numAreas * sizeof( *pvsAreas ) ); + + cp = 0; + portalPtrs = new pvsPortal_t*[numPortals]; + + for ( i = 0; i < numAreas; i++ ) { + + area = &pvsAreas[i]; + area->bounds.Clear(); + area->portals = portalPtrs + cp; + + n = gameRenderWorld->NumPortalsInArea( i ); + + for ( j = 0; j < n; j++ ) { + + portal = gameRenderWorld->GetPortal( i, j ); + + p = &pvsPortals[cp++]; + // the winding goes counter clockwise seen from this area + p->w = portal.w->Copy(); + p->areaNum = portal.areas[1]; // area[1] is always the area the portal leads to + + p->vis = new byte[portalVisBytes]; + memset( p->vis, 0, portalVisBytes ); + p->mightSee = new byte[portalVisBytes]; + memset( p->mightSee, 0, portalVisBytes ); + p->w->GetBounds( p->bounds ); + p->w->GetPlane( p->plane ); + // plane normal points to outside the area + p->plane = -p->plane; + // no PVS calculated for this portal yet + p->done = false; + + area->portals[area->numPortals] = p; + area->numPortals++; + + area->bounds += p->bounds; + } + } +} + +/* +================ +idPVS::DestroyPVSData +================ +*/ +void idPVS::DestroyPVSData( void ) { + int i; + + if ( !pvsAreas ) { + return; + } + + // delete portal pointer array + delete[] pvsAreas[0].portals; + + // delete all areas + delete[] pvsAreas; + pvsAreas = NULL; + + // delete portal data + for ( i = 0; i < numPortals; i++ ) { + delete[] pvsPortals[i].vis; + delete[] pvsPortals[i].mightSee; + delete pvsPortals[i].w; + } + + // delete portals + delete[] pvsPortals; + pvsPortals = NULL; +} + +/* +================ +idPVS::FloodFrontPortalPVS_r +================ +*/ +void idPVS::FloodFrontPortalPVS_r( pvsPortal_t *portal, int areaNum ) const { + int i, n; + pvsArea_t *area; + pvsPortal_t *p; + + area = &pvsAreas[ areaNum ]; + + for ( i = 0; i < area->numPortals; i++ ) { + p = area->portals[i]; + n = p - pvsPortals; + // don't flood through if this portal is not at the front + if ( !( portal->mightSee[ n>>3 ] & (1 << (n&7)) ) ) { + continue; + } + // don't flood through if already visited this portal + if ( portal->vis[ n>>3 ] & (1 << (n&7)) ) { + continue; + } + // this portal might be visible + portal->vis[ n>>3 ] |= (1 << (n&7)); + // flood through the portal + FloodFrontPortalPVS_r( portal, p->areaNum ); + } +} + +/* +================ +idPVS::FrontPortalPVS +================ +*/ +void idPVS::FrontPortalPVS( void ) const { + int i, j, k, n, p, side1, side2, areaSide; + pvsPortal_t *p1, *p2; + pvsArea_t *area; + + for ( i = 0; i < numPortals; i++ ) { + p1 = &pvsPortals[i]; + + for ( j = 0; j < numAreas; j++ ) { + + area = &pvsAreas[j]; + + areaSide = side1 = area->bounds.PlaneSide( p1->plane ); + + // if the whole area is at the back side of the portal + if ( areaSide == PLANESIDE_BACK ) { + continue; + } + + for ( p = 0; p < area->numPortals; p++ ) { + + p2 = area->portals[p]; + + // if we the whole area is not at the front we need to check + if ( areaSide != PLANESIDE_FRONT ) { + // if the second portal is completely at the back side of the first portal + side1 = p2->bounds.PlaneSide( p1->plane ); + if ( side1 == PLANESIDE_BACK ) { + continue; + } + } + + // if the first portal is completely at the front of the second portal + side2 = p1->bounds.PlaneSide( p2->plane ); + if ( side2 == PLANESIDE_FRONT ) { + continue; + } + + // if the second portal is not completely at the front of the first portal + if ( side1 != PLANESIDE_FRONT ) { + // more accurate check + for ( k = 0; k < p2->w->GetNumPoints(); k++ ) { + // if more than an epsilon at the front side + if ( p1->plane.Side( (*p2->w)[k].ToVec3(), ON_EPSILON ) == PLANESIDE_FRONT ) { + break; + } + } + if ( k >= p2->w->GetNumPoints() ) { + continue; // second portal is at the back of the first portal + } + } + + // if the first portal is not completely at the back side of the second portal + if ( side2 != PLANESIDE_BACK ) { + // more accurate check + for ( k = 0; k < p1->w->GetNumPoints(); k++ ) { + // if more than an epsilon at the back side + if ( p2->plane.Side( (*p1->w)[k].ToVec3(), ON_EPSILON ) == PLANESIDE_BACK ) { + break; + } + } + if ( k >= p1->w->GetNumPoints() ) { + continue; // first portal is at the front of the second portal + } + } + + // the portal might be visible at the front + n = p2 - pvsPortals; + p1->mightSee[ n >> 3 ] |= 1 << (n&7); + } + } + } + + // flood the front portal pvs for all portals + for ( i = 0; i < numPortals; i++ ) { + p1 = &pvsPortals[i]; + FloodFrontPortalPVS_r( p1, p1->areaNum ); + } +} + +/* +=============== +idPVS::FloodPassagePVS_r +=============== +*/ +pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *portal, pvsStack_t *prevStack ) const { + int i, j, n, m; + pvsPortal_t *p; + pvsArea_t *area; + pvsStack_t *stack; + pvsPassage_t *passage; + long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; + + area = &pvsAreas[portal->areaNum]; + + stack = prevStack->next; + // if no next stack entry allocated + if ( !stack ) { + stack = reinterpret_cast(new byte[sizeof(pvsStack_t) + portalVisBytes]); + stack->mightSee = (reinterpret_cast(stack)) + sizeof(pvsStack_t); + stack->next = NULL; + prevStack->next = stack; + } + + // check all portals for flooding into other areas + for ( i = 0; i < area->numPortals; i++ ) { + + passage = &portal->passages[i]; + + // if this passage is completely empty + if ( !passage->canSee ) { + continue; + } + + p = area->portals[i]; + n = p - pvsPortals; + + // if this portal cannot be seen through our current portal/passage stack + if ( !( prevStack->mightSee[n >> 3] & (1 << (n & 7)) ) ) { + continue; + } + + // mark the portal as visible + source->vis[n >> 3] |= (1 << (n & 7)); + + // get pointers to vis data + prevMightSee = reinterpret_cast(prevStack->mightSee); + passageVis = reinterpret_cast(passage->canSee); + sourceVis = reinterpret_cast(source->vis); + mightSee = reinterpret_cast(stack->mightSee); + + more = 0; + // use the portal PVS if it has been calculated + if ( p->done ) { + portalVis = reinterpret_cast(p->vis); + for ( j = 0; j < portalVisLongs; j++ ) { + // get new PVS which is decreased by going through this passage + m = *prevMightSee++ & *passageVis++ & *portalVis++; + // check if anything might be visible through this passage that wasn't yet visible + more |= (m & ~(*sourceVis++)); + // store new PVS + *mightSee++ = m; + } + } + else { + // the p->mightSee is implicitely stored in the passageVis + for ( j = 0; j < portalVisLongs; j++ ) { + // get new PVS which is decreased by going through this passage + m = *prevMightSee++ & *passageVis++; + // check if anything might be visible through this passage that wasn't yet visible + more |= (m & ~(*sourceVis++)); + // store new PVS + *mightSee++ = m; + } + } + + // if nothing more can be seen + if ( !more ) { + continue; + } + + // go through the portal + stack->next = FloodPassagePVS_r( source, p, stack ); + } + + return stack; +} + +/* +=============== +idPVS::PassagePVS +=============== +*/ +void idPVS::PassagePVS( void ) const { + int i; + pvsPortal_t *source; + pvsStack_t *stack, *s; + + // create the passages + CreatePassages(); + + // allocate first stack entry + stack = reinterpret_cast(new byte[sizeof(pvsStack_t) + portalVisBytes]); + stack->mightSee = (reinterpret_cast(stack)) + sizeof(pvsStack_t); + stack->next = NULL; + + // calculate portal PVS by flooding through the passages + for ( i = 0; i < numPortals; i++ ) { + source = &pvsPortals[i]; + memset( source->vis, 0, portalVisBytes ); + memcpy( stack->mightSee, source->mightSee, portalVisBytes ); + FloodPassagePVS_r( source, source, stack ); + source->done = true; + } + + // free the allocated stack + for ( s = stack; s; s = stack ) { + stack = stack->next; + delete[] s; + } + + // destroy the passages + DestroyPassages(); +} + +/* +=============== +idPVS::AddPassageBoundaries +=============== +*/ +void idPVS::AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const { + int i, j, k, l; + idVec3 v1, v2, normal; + float d, dist; + bool flipTest, front; + idPlane plane; + + + // check all combinations + for ( i = 0; i < source.GetNumPoints(); i++ ) { + + l = (i + 1) % source.GetNumPoints(); + v1 = source[l].ToVec3() - source[i].ToVec3(); + + // find a vertex of pass that makes a plane that puts all of the + // vertices of pass on the front side and all of the vertices of + // source on the back side + for ( j = 0; j < pass.GetNumPoints(); j++ ) { + + v2 = pass[j].ToVec3() - source[i].ToVec3(); + + normal = v1.Cross( v2 ); + if ( normal.Normalize() < 0.01f ) { + continue; + } + dist = normal * pass[j].ToVec3(); + + // + // find out which side of the generated seperating plane has the + // source portal + // + flipTest = false; + for ( k = 0; k < source.GetNumPoints(); k++ ) { + if ( k == i || k == l ) { + continue; + } + d = source[k].ToVec3() * normal - dist; + if ( d < -ON_EPSILON ) { + // source is on the negative side, so we want all + // pass and target on the positive side + flipTest = false; + break; + } + else if ( d > ON_EPSILON ) { + // source is on the positive side, so we want all + // pass and target on the negative side + flipTest = true; + break; + } + } + if ( k == source.GetNumPoints() ) { + continue; // planar with source portal + } + + // flip the normal if the source portal is backwards + if (flipTest) { + normal = -normal; + dist = -dist; + } + + // if all of the pass portal points are now on the positive side, + // this is the seperating plane + front = false; + for ( k = 0; k < pass.GetNumPoints(); k++ ) { + if ( k == j ) { + continue; + } + d = pass[k].ToVec3() * normal - dist; + if ( d < -ON_EPSILON ) { + break; + } + else if ( d > ON_EPSILON ) { + front = true; + } + } + if ( k < pass.GetNumPoints() ) { + continue; // points on negative side, not a seperating plane + } + if ( !front ) { + continue; // planar with seperating plane + } + + // flip the normal if we want the back side + if ( flipClip ) { + plane.SetNormal( -normal ); + plane.SetDist( -dist ); + } + else { + plane.SetNormal( normal ); + plane.SetDist( dist ); + } + + // check if the plane is already a passage boundary + for ( k = 0; k < numBounds; k++ ) { + if ( plane.Compare( bounds[k], 0.001f, 0.01f ) ) { + break; + } + } + if ( k < numBounds ) { + break; + } + + if ( numBounds >= maxBounds ) { + gameLocal.Warning( "max passage boundaries." ); + break; + } + bounds[numBounds] = plane; + numBounds++; + break; + } + } +} + +/* +================ +idPVS::CreatePassages +================ +*/ +#define MAX_PASSAGE_BOUNDS 128 + +void idPVS::CreatePassages( void ) const { + int i, j, l, n, numBounds, front, passageMemory, byteNum, bitNum; + int sides[MAX_PASSAGE_BOUNDS]; + idPlane passageBounds[MAX_PASSAGE_BOUNDS]; + pvsPortal_t *source, *target, *p; + pvsArea_t *area; + pvsPassage_t *passage; + idFixedWinding winding; + byte canSee, mightSee, bit; + + passageMemory = 0; + for ( i = 0; i < numPortals; i++ ) { + source = &pvsPortals[i]; + area = &pvsAreas[source->areaNum]; + + source->passages = new pvsPassage_t[area->numPortals]; + + for ( j = 0; j < area->numPortals; j++ ) { + target = area->portals[j]; + n = target - pvsPortals; + + passage = &source->passages[j]; + + // if the source portal cannot see this portal + if ( !( source->mightSee[ n>>3 ] & (1 << (n&7)) ) ) { + // not all portals in the area have to be visible because areas are not necesarily convex + // also no passage has to be created for the portal which is the opposite of the source + passage->canSee = NULL; + continue; + } + + passage->canSee = new byte[portalVisBytes]; + passageMemory += portalVisBytes; + + // boundary plane normals point inwards + numBounds = 0; + AddPassageBoundaries( *(source->w), *(target->w), false, passageBounds, numBounds, MAX_PASSAGE_BOUNDS ); + AddPassageBoundaries( *(target->w), *(source->w), true, passageBounds, numBounds, MAX_PASSAGE_BOUNDS ); + + // get all portals visible through this passage + for ( byteNum = 0; byteNum < portalVisBytes; byteNum++) { + + canSee = 0; + mightSee = source->mightSee[byteNum] & target->mightSee[byteNum]; + + // go through eight portals at a time to speed things up + for ( bitNum = 0; bitNum < 8; bitNum++ ) { + + bit = 1 << bitNum; + + if ( !( mightSee & bit ) ) { + continue; + } + + p = &pvsPortals[(byteNum << 3) + bitNum]; + + if ( p->areaNum == source->areaNum ) { + continue; + } + + for ( front = 0, l = 0; l < numBounds; l++ ) { + sides[l] = p->bounds.PlaneSide( passageBounds[l] ); + // if completely at the back of the passage bounding plane + if ( sides[l] == PLANESIDE_BACK ) { + break; + } + // if completely at the front + if ( sides[l] == PLANESIDE_FRONT ) { + front++; + } + } + // if completely outside the passage + if ( l < numBounds ) { + continue; + } + + // if not at the front of all bounding planes and thus not completely inside the passage + if ( front != numBounds ) { + + winding = *p->w; + + for ( l = 0; l < numBounds; l++ ) { + // only clip if the winding possibly crosses this plane + if ( sides[l] != PLANESIDE_CROSS ) { + continue; + } + // clip away the part at the back of the bounding plane + winding.ClipInPlace( passageBounds[l] ); + // if completely clipped away + if ( !winding.GetNumPoints() ) { + break; + } + } + // if completely outside the passage + if ( l < numBounds ) { + continue; + } + } + + canSee |= bit; + } + + // store results of all eight portals + passage->canSee[byteNum] = canSee; + } + + // can always see the target portal + passage->canSee[n >> 3] |= (1 << (n&7)); + } + } + if ( passageMemory < 1024 ) { + gameLocal.Printf( "%5d bytes passage memory used to build PVS\n", passageMemory ); + } + else { + gameLocal.Printf( "%5d KB passage memory used to build PVS\n", passageMemory>>10 ); + } +} + +/* +================ +idPVS::DestroyPassages +================ +*/ +void idPVS::DestroyPassages( void ) const { + int i, j; + pvsPortal_t *p; + pvsArea_t *area; + + for ( i = 0; i < numPortals; i++ ) { + p = &pvsPortals[i]; + area = &pvsAreas[p->areaNum]; + for ( j = 0; j < area->numPortals; j++ ) { + if ( p->passages[j].canSee ) { + delete[] p->passages[j].canSee; + } + } + delete[] p->passages; + } +} + +/* +================ +idPVS::CopyPortalPVSToMightSee +================ +*/ +void idPVS::CopyPortalPVSToMightSee( void ) const { + int i; + pvsPortal_t *p; + + for ( i = 0; i < numPortals; i++ ) { + p = &pvsPortals[i]; + memcpy( p->mightSee, p->vis, portalVisBytes ); + } +} + +/* +================ +idPVS::AreaPVSFromPortalPVS +================ +*/ +int idPVS::AreaPVSFromPortalPVS( void ) const { + int i, j, k, areaNum, totalVisibleAreas; + long *p1, *p2; + byte *pvs, *portalPVS; + pvsArea_t *area; + + totalVisibleAreas = 0; + + if ( !numPortals ) { + return totalVisibleAreas; + } + + memset( areaPVS, 0, numAreas * areaVisBytes ); + + for ( i = 0; i < numAreas; i++ ) { + area = &pvsAreas[i]; + pvs = areaPVS + i * areaVisBytes; + + // the area is visible to itself + pvs[ i >> 3 ] |= 1 << (i & 7); + + if ( !area->numPortals ) { + continue; + } + + // store the PVS of all portals in this area at the first portal + for ( j = 1; j < area->numPortals; j++ ) { + p1 = reinterpret_cast(area->portals[0]->vis); + p2 = reinterpret_cast(area->portals[j]->vis); + for ( k = 0; k < portalVisLongs; k++ ) { + *p1++ |= *p2++; + } + } + + // the portals of this area are always visible + for ( j = 0; j < area->numPortals; j++ ) { + k = area->portals[j] - pvsPortals; + area->portals[0]->vis[ k >> 3 ] |= 1 << (k & 7); + } + + // set all areas to visible that can be seen from the portals of this area + portalPVS = area->portals[0]->vis; + for ( j = 0; j < numPortals; j++ ) { + // if this portal is visible + if ( portalPVS[j>>3] & (1 << (j&7)) ) { + areaNum = pvsPortals[j].areaNum; + pvs[ areaNum >> 3 ] |= 1 << (areaNum & 7); + } + } + + // count the number of visible areas + for ( j = 0; j < numAreas; j++ ) { + if ( pvs[j>>3] & (1 << (j&7)) ) { + totalVisibleAreas++; + } + } + } + return totalVisibleAreas; +} + +/* +================ +idPVS::Init +================ +*/ +void idPVS::Init( void ) { + int totalVisibleAreas; + + Shutdown(); + + numAreas = gameRenderWorld->NumAreas(); + if ( numAreas <= 0 ) { + return; + } + + connectedAreas = new bool[numAreas]; + areaQueue = new int[numAreas]; + + areaVisBytes = ( ((numAreas+31)&~31) >> 3); + areaVisLongs = areaVisBytes/sizeof(long); + + areaPVS = new byte[numAreas * areaVisBytes]; + memset( areaPVS, 0xFF, numAreas * areaVisBytes ); + + numPortals = GetPortalCount(); + + portalVisBytes = ( ((numPortals+31)&~31) >> 3); + portalVisLongs = portalVisBytes/sizeof(long); + + for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { + currentPVS[i].handle.i = -1; + currentPVS[i].handle.h = 0; + currentPVS[i].pvs = new byte[areaVisBytes]; + memset( currentPVS[i].pvs, 0, areaVisBytes ); + } + + idTimer timer; + timer.Start(); + + CreatePVSData(); + + FrontPortalPVS(); + + CopyPortalPVSToMightSee(); + + PassagePVS(); + + totalVisibleAreas = AreaPVSFromPortalPVS(); + + DestroyPVSData(); + + timer.Stop(); + + gameLocal.Printf( "%5.0f msec to calculate PVS\n", timer.Milliseconds() ); + gameLocal.Printf( "%5d areas\n", numAreas ); + gameLocal.Printf( "%5d portals\n", numPortals ); + gameLocal.Printf( "%5d areas visible on average\n", totalVisibleAreas / numAreas ); + if ( numAreas * areaVisBytes < 1024 ) { + gameLocal.Printf( "%5d bytes PVS data\n", numAreas * areaVisBytes ); + } + else { + gameLocal.Printf( "%5d KB PVS data\n", (numAreas * areaVisBytes) >> 10 ); + } +} + +/* +================ +idPVS::Shutdown +================ +*/ +void idPVS::Shutdown( void ) { + if ( connectedAreas ) { + delete[] connectedAreas; + connectedAreas = NULL; + } + if ( areaQueue ) { + delete[] areaQueue; + areaQueue = NULL; + } + if ( areaPVS ) { + delete[] areaPVS; + areaPVS = NULL; + } + if ( currentPVS ) { + for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { + delete[] currentPVS[i].pvs; + currentPVS[i].pvs = NULL; + } + } +} + +/* +================ +idPVS::GetConnectedAreas + + assumes the 'areas' array is initialized to false +================ +*/ +void idPVS::GetConnectedAreas( int srcArea, bool *areas ) const { + int curArea, nextArea; + int queueStart, queueEnd; + int i, n; + exitPortal_t portal; + + queueStart = -1; + queueEnd = 0; + areas[srcArea] = true; + + for ( curArea = srcArea; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) { + + n = gameRenderWorld->NumPortalsInArea( curArea ); + + for ( i = 0; i < n; i++ ) { + portal = gameRenderWorld->GetPortal( curArea, i ); + + if ( portal.blockingBits & PS_BLOCK_VIEW ) { + continue; + } + + // area[1] is always the area the portal leads to + nextArea = portal.areas[1]; + + // if already visited this area + if ( areas[nextArea] ) { + continue; + } + + // add area to queue + areaQueue[queueEnd++] = nextArea; + areas[nextArea] = true; + } + } +} + +/* +================ +idPVS::GetPVSArea +================ +*/ +int idPVS::GetPVSArea( const idVec3 &point ) const { + return gameRenderWorld->PointInArea( point ); +} + +/* +================ +idPVS::GetPVSAreas +================ +*/ +int idPVS::GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const { + return gameRenderWorld->BoundsInAreas( bounds, areas, maxAreas ); +} + +/* +================ +idPVS::SetupCurrentPVS +================ +*/ +pvsHandle_t idPVS::SetupCurrentPVS( const idVec3 &source, const pvsType_t type ) const { + int sourceArea; + + sourceArea = gameRenderWorld->PointInArea( source ); + + return SetupCurrentPVS( sourceArea, type ); +} + +/* +================ +idPVS::SetupCurrentPVS +================ +*/ +pvsHandle_t idPVS::SetupCurrentPVS( const idBounds &source, const pvsType_t type ) const { + int numSourceAreas, sourceAreas[MAX_BOUNDS_AREAS]; + + numSourceAreas = gameRenderWorld->BoundsInAreas( source, sourceAreas, MAX_BOUNDS_AREAS ); + + return SetupCurrentPVS( sourceAreas, numSourceAreas, type ); +} + +/* +================ +idPVS::SetupCurrentPVS +================ +*/ +pvsHandle_t idPVS::SetupCurrentPVS( const int sourceArea, const pvsType_t type ) const { + int i; + pvsHandle_t handle; + + handle = AllocCurrentPVS( *reinterpret_cast(&sourceArea) ); + + if ( sourceArea < 0 || sourceArea >= numAreas ) { + memset( currentPVS[handle.i].pvs, 0, areaVisBytes ); + return handle; + } + + if ( type != PVS_CONNECTED_AREAS ) { + memcpy( currentPVS[handle.i].pvs, areaPVS + sourceArea * areaVisBytes, areaVisBytes ); + } else { + memset( currentPVS[handle.i].pvs, -1, areaVisBytes ); + } + + if ( type == PVS_ALL_PORTALS_OPEN ) { + return handle; + } + + memset( connectedAreas, 0, numAreas * sizeof( *connectedAreas ) ); + + GetConnectedAreas( sourceArea, connectedAreas ); + + for ( i = 0; i < numAreas; i++ ) { + if ( !connectedAreas[i] ) { + currentPVS[handle.i].pvs[i>>3] &= ~(1 << (i&7)); + } + } + + return handle; +} + +/* +================ +idPVS::SetupCurrentPVS +================ +*/ +pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const { + int i, j; + unsigned int h; + long *vis, *pvs; + pvsHandle_t handle; + + h = 0; + for ( i = 0; i < numSourceAreas; i++ ) { + h ^= *reinterpret_cast(&sourceAreas[i]); + } + handle = AllocCurrentPVS( h ); + + if ( !numSourceAreas || sourceAreas[0] < 0 || sourceAreas[0] >= numAreas) { + memset( currentPVS[handle.i].pvs, 0, areaVisBytes ); + return handle; + } + + if ( type != PVS_CONNECTED_AREAS ) { + // merge PVS of all areas the source is in + memcpy( currentPVS[handle.i].pvs, areaPVS + sourceAreas[0] * areaVisBytes, areaVisBytes ); + for ( i = 1; i < numSourceAreas; i++ ) { + + assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); + + vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); + pvs = reinterpret_cast(currentPVS[handle.i].pvs); + for ( j = 0; j < areaVisLongs; j++ ) { + *pvs++ |= *vis++; + } + } + } else { + memset( currentPVS[handle.i].pvs, -1, areaVisBytes ); + } + + if ( type == PVS_ALL_PORTALS_OPEN ) { + return handle; + } + + memset( connectedAreas, 0, numAreas * sizeof( *connectedAreas ) ); + + // get all areas connected to any of the source areas + for ( i = 0; i < numSourceAreas; i++ ) { + if ( !connectedAreas[sourceAreas[i]] ) { + GetConnectedAreas( sourceAreas[i], connectedAreas ); + } + } + + // remove unconnected areas from the PVS + for ( i = 0; i < numAreas; i++ ) { + if ( !connectedAreas[i] ) { + currentPVS[handle.i].pvs[i>>3] &= ~(1 << (i&7)); + } + } + + return handle; +} + +/* +================ +idPVS::MergeCurrentPVS +================ +*/ +pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { + int i; + long *pvs1Ptr, *pvs2Ptr, *ptr; + pvsHandle_t handle; + + if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h || + pvs2.i < 0 || pvs2.i >= MAX_CURRENT_PVS || pvs2.h != currentPVS[pvs2.i].handle.h ) { + gameLocal.Error( "idPVS::MergeCurrentPVS: invalid handle" ); + } + + handle = AllocCurrentPVS( pvs1.h ^ pvs2.h ); + + ptr = reinterpret_cast(currentPVS[handle.i].pvs); + pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); + pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); + + for ( i = 0; i < areaVisLongs; i++ ) { + *ptr++ = *pvs1Ptr++ | *pvs2Ptr++; + } + + return handle; +} + +/* +================ +idPVS::AllocCurrentPVS +================ +*/ +pvsHandle_t idPVS::AllocCurrentPVS( unsigned int h ) const { + int i; + pvsHandle_t handle; + + for ( i = 0; i < MAX_CURRENT_PVS; i++ ) { + if ( currentPVS[i].handle.i == -1 ) { + currentPVS[i].handle.i = i; + currentPVS[i].handle.h = h; +/* + // angua: debug output, shows allocated PVS numbers in front of the player + idVec3 viewPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + idVec3(0,0,50+6*i) + + gameLocal.GetLocalPlayer()->viewAngles.ToForward() * 30; + idStr maxPVS(i); + gameRenderWorld->DrawText(maxPVS.c_str(), viewPos, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); +*/ + return currentPVS[i].handle; + } + } + + gameLocal.Error( "idPVS::AllocCurrentPVS: no free PVS left" ); + + handle.i = -1; + handle.h = 0; + return handle; +} + +/* +================ +idPVS::FreeCurrentPVS +================ +*/ +void idPVS::FreeCurrentPVS( pvsHandle_t handle ) const { + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Warning( "idPVS::FreeCurrentPVS: invalid handle" ); + return; + } + + currentPVS[handle.i].handle.i = -1; +} + +/* +================ +idPVS::InCurrentPVS +================ +*/ +bool idPVS::InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const { + int targetArea; + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || + handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); + } + + targetArea = gameRenderWorld->PointInArea( target ); + + if ( targetArea == -1 ) { + return false; + } + + return ( ( currentPVS[handle.i].pvs[targetArea>>3] & (1 << (targetArea&7)) ) != 0 ); +} + +/* +================ +idPVS::InCurrentPVS +================ +*/ +bool idPVS::InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const { + int i, numTargetAreas, targetAreas[MAX_BOUNDS_AREAS]; + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || + handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); + } + + numTargetAreas = gameRenderWorld->BoundsInAreas( target, targetAreas, MAX_BOUNDS_AREAS ); + + for ( i = 0; i < numTargetAreas; i++ ) { + if ( currentPVS[handle.i].pvs[targetAreas[i]>>3] & (1 << (targetAreas[i]&7)) ) { + return true; + } + } + return false; +} + +/* +================ +idPVS::InCurrentPVS +================ +*/ +bool idPVS::InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const { + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || + handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); + } + + if ( targetArea < 0 || targetArea >= numAreas ) { + return false; + } + + return ( ( currentPVS[handle.i].pvs[targetArea>>3] & (1 << (targetArea&7)) ) != 0 ); +} + +/* +================ +idPVS::InCurrentPVS +================ +*/ +bool idPVS::InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const { + int i; + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || + handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); + } + + for ( i = 0; i < numTargetAreas; i++ ) { + if ( targetAreas[i] < 0 || targetAreas[i] >= numAreas ) { + continue; + } + if ( currentPVS[handle.i].pvs[targetAreas[i]>>3] & (1 << (targetAreas[i]&7)) ) { + return true; + } + } + return false; +} + +/* +================ +idPVS::DrawPVS +================ +*/ +void idPVS::DrawPVS( const idVec3 &source, const pvsType_t type ) const { + int i, j, k, numPoints, n, sourceArea; + exitPortal_t portal; + idPlane plane; + idVec3 offset; + idVec4 *color; + pvsHandle_t handle; + + sourceArea = gameRenderWorld->PointInArea( source ); + + if ( sourceArea == -1 ) { + return; + } + + handle = SetupCurrentPVS( source, type ); + + for ( j = 0; j < numAreas; j++ ) { + + if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { + continue; + } + + if ( j == sourceArea ) { + color = &colorRed; + } + else { + color = &colorCyan; + } + + n = gameRenderWorld->NumPortalsInArea( j ); + + // draw all the portals of the area + for ( i = 0; i < n; i++ ) { + portal = gameRenderWorld->GetPortal( j, i ); + + numPoints = portal.w->GetNumPoints(); + + portal.w->GetPlane( plane ); + offset = plane.Normal() * 4.0f; + for ( k = 0; k < numPoints; k++ ) { + gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); + } + } + } + + FreeCurrentPVS( handle ); +} + +/* +================ +idPVS::DrawPVS +================ +*/ +void idPVS::DrawPVS( const idBounds &source, const pvsType_t type ) const { + int i, j, k, numPoints, n, num, areas[MAX_BOUNDS_AREAS]; + exitPortal_t portal; + idPlane plane; + idVec3 offset; + idVec4 *color; + pvsHandle_t handle; + + num = gameRenderWorld->BoundsInAreas( source, areas, MAX_BOUNDS_AREAS ); + + if ( !num ) { + return; + } + + handle = SetupCurrentPVS( source, type ); + + for ( j = 0; j < numAreas; j++ ) { + + if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { + continue; + } + + for ( i = 0; i < num; i++ ) { + if ( j == areas[i] ) { + break; + } + } + if ( i < num ) { + color = &colorRed; + } + else { + color = &colorCyan; + } + + n = gameRenderWorld->NumPortalsInArea( j ); + + // draw all the portals of the area + for ( i = 0; i < n; i++ ) { + portal = gameRenderWorld->GetPortal( j, i ); + + numPoints = portal.w->GetNumPoints(); + + portal.w->GetPlane( plane ); + offset = plane.Normal() * 4.0f; + for ( k = 0; k < numPoints; k++ ) { + gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); + } + } + } + + FreeCurrentPVS( handle ); +} + +/* +================ +idPVS::DrawPVS +================ +*/ +void idPVS::DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const { + int i, j, k, numPoints, n, sourceArea; + exitPortal_t portal; + idPlane plane; + idVec3 offset; + idVec4 *color; + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || + handle.h != currentPVS[handle.i].handle.h ) { + gameLocal.Error( "idPVS::DrawCurrentPVS: invalid handle" ); + } + + sourceArea = gameRenderWorld->PointInArea( source ); + + if ( sourceArea == -1 ) { + return; + } + + for ( j = 0; j < numAreas; j++ ) { + + if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { + continue; + } + + if ( j == sourceArea ) { + color = &colorRed; + } + else { + color = &colorCyan; + } + + n = gameRenderWorld->NumPortalsInArea( j ); + + // draw all the portals of the area + for ( i = 0; i < n; i++ ) { + portal = gameRenderWorld->GetPortal( j, i ); + + numPoints = portal.w->GetNumPoints(); + + portal.w->GetPlane( plane ); + offset = plane.Normal() * 4.0f; + for ( k = 0; k < numPoints; k++ ) { + gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); + } + } + } +} + +#if ASYNC_WRITE_PVS + +/* +=================== +idPVS::WritePVS +=================== +*/ +void idPVS::WritePVS( const pvsHandle_t handle, idBitMsg &msg ) { + msg.WriteData( currentPVS[ handle.i ].pvs, areaVisBytes ); +} + +/* +=================== +idPVS::ReadPVS +=================== +*/ +void idPVS::ReadPVS( const pvsHandle_t handle, const idBitMsg &msg ) { + byte l_pvs[ 256 ]; + int i; + + assert( areaVisBytes <= 256 ); + msg.ReadData( l_pvs, areaVisBytes ); + if ( memcmp( l_pvs, currentPVS[ handle.i ].pvs, areaVisBytes ) ) { + common->Printf( "PVS not matching ( %d areaVisBytes ) - server then client:\n", areaVisBytes ); + for ( i = 0; i < areaVisBytes; i++ ) { + common->Printf( "%x ", l_pvs[ i ] ); + } + common->Printf( "\n" ); + for ( i = 0; i < areaVisBytes; i++ ) { + common->Printf( "%x ", currentPVS[ handle.i ].pvs[ i ] ); + } + common->Printf( "\n" ); + } +} + +#endif + + +/* +================ +idPVS::CheckAreasForPortalSky +================ +*/ +bool idPVS::CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin ) { + int j, sourceArea; + + if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || handle.h != currentPVS[handle.i].handle.h ) { + return false; + } + + sourceArea = gameRenderWorld->PointInArea( origin ); + + if ( sourceArea == -1 ) { + return false; + } + + for ( j = 0; j < numAreas; j++ ) { + + if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { + continue; + } + + if ( gameRenderWorld->CheckAreaForPortalSky( j ) ) { + return true; + } + } + + return false; +} diff --git a/game/Pvs.h b/game/Pvs.h new file mode 100644 index 000000000..f9a279781 --- /dev/null +++ b/game/Pvs.h @@ -0,0 +1,122 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_PVS_H__ +#define __GAME_PVS_H__ + +/* +=================================================================================== + + PVS + + Note: mirrors and other special view portals are not taken into account + +=================================================================================== +*/ + + +typedef struct pvsHandle_s { + int i; // index to current pvs + unsigned int h; // handle for current pvs +} pvsHandle_t; + + +typedef struct pvsCurrent_s { + pvsHandle_t handle; // current pvs handle + byte * pvs; // current pvs bit string +} pvsCurrent_t; + +#define MAX_CURRENT_PVS 16 // must be a power of 2 + +typedef enum { + PVS_NORMAL = 0, // PVS through portals taking portal states into account + PVS_ALL_PORTALS_OPEN = 1, // PVS through portals assuming all portals are open + PVS_CONNECTED_AREAS = 2 // PVS considering all topologically connected areas visible +} pvsType_t; + + +class idPVS { +public: + idPVS( void ); + ~idPVS( void ); + // setup for the current map + void Init( void ); + void Shutdown( void ); + // get the area(s) the source is in + int GetPVSArea( const idVec3 &point ) const; // returns the area number + int GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const; // returns number of areas + // setup current PVS for the source + pvsHandle_t SetupCurrentPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const; + pvsHandle_t SetupCurrentPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const; + pvsHandle_t SetupCurrentPVS( const int sourceArea, const pvsType_t type = PVS_NORMAL ) const; + pvsHandle_t SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type = PVS_NORMAL ) const; + pvsHandle_t MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const; + void FreeCurrentPVS( pvsHandle_t handle ) const; + // returns true if the target is within the current PVS + bool InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const; + bool InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const; + bool InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const; + bool InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const; + // draw all portals that are within the PVS of the source + void DrawPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const; + void DrawPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const; + // visualize the PVS the handle points to + void DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const; + +#if ASYNC_WRITE_PVS + void WritePVS( const pvsHandle_t handle, idBitMsg &msg ); + void ReadPVS( const pvsHandle_t handle, const idBitMsg &msg ); +#endif + + bool CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin ); + +private: + int numAreas; + int numPortals; + bool * connectedAreas; + int * areaQueue; + byte * areaPVS; + // current PVS for a specific source possibly taking portal states (open/closed) into account + mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; + // used to create PVS + int portalVisBytes; + int portalVisLongs; + int areaVisBytes; + int areaVisLongs; + struct pvsPortal_s * pvsPortals; + struct pvsArea_s * pvsAreas; + +private: + int GetPortalCount( void ) const; + void CreatePVSData( void ); + void DestroyPVSData( void ); + void CopyPortalPVSToMightSee( void ) const; + void FloodFrontPortalPVS_r( struct pvsPortal_s *portal, int areaNum ) const; + void FrontPortalPVS( void ) const; + struct pvsStack_s * FloodPassagePVS_r( struct pvsPortal_s *source, const struct pvsPortal_s *portal, struct pvsStack_s *prevStack ) const; + void PassagePVS( void ) const; + void AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const; + void CreatePassages( void ) const; + void DestroyPassages( void ) const; + int AreaPVSFromPortalPVS( void ) const; + void GetConnectedAreas( int srcArea, bool *connectedAreas ) const; + pvsHandle_t AllocCurrentPVS( unsigned int h ) const; +}; + +#endif /* !__GAME_PVS_H__ */ diff --git a/game/RawVector.cpp b/game/RawVector.cpp new file mode 100644 index 000000000..ad0da0c0e --- /dev/null +++ b/game/RawVector.cpp @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "RawVector.h" + +CRawVector::CRawVector() + : m_Pointer(0) + , m_Size(0), m_Capacity(0) +{ + reallocate(INITIAL_CAPACITY); +} + +CRawVector::~CRawVector() +{ + free(m_Pointer); +} + +void CRawVector::reallocate(int newSize) { + int newCapacity = m_Capacity << 1; + if (newCapacity < newSize) newCapacity = newSize; + + char *newbuffer = (char*)realloc(m_Pointer, newCapacity); + if (!newbuffer) + common->FatalError("CRawBuffer::resize: realloc failed (from %d to %d bytes)", m_Capacity, newCapacity); + + m_Pointer = newbuffer; + m_Capacity = newCapacity; +} + +void CRawVector::clear() { + resize(0); +} + +namespace std { + void swap(CRawVector &a, CRawVector &b) { + static const int RVS = sizeof(CRawVector); + char buffer[RVS]; + memcpy(buffer, &a, RVS); + memcpy(&a, &b, RVS); + memcpy(&b, buffer, RVS); + } +} diff --git a/game/RawVector.h b/game/RawVector.h new file mode 100644 index 000000000..df242d790 --- /dev/null +++ b/game/RawVector.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef RAW_VECTOR_H +#define RAW_VECTOR_H + +/** + * std::vector-like raw buffer class. + * Contains raw bytes, uses C allocation routines. + * Grows exponentially, never shrinks. + * No initialization or checks are done. + * If malloc error happens then Error() is called + * Only the most necessary methods are implemented. + */ +class CRawVector { + static const int INITIAL_CAPACITY = 16; +public: + CRawVector(); + ~CRawVector(); + + ID_INLINE int size() const { return m_Size; } + ID_INLINE char &operator[] (int i) { return m_Pointer[i]; } + ID_INLINE const char &operator[] (int i) const { return m_Pointer[i]; } + + inline void resize(int newSize) + { + if (newSize > m_Capacity) reallocate(newSize); + m_Size = newSize; + } + + //note: does not free memory! + void clear(); + +private: + ///Pointer to data (allocated with malloc). + char *m_Pointer; + ///Size of vector (number of bytes). + int m_Size; + ///Size of allocated buffer. + int m_Capacity; + + ///Reallocate the memory buffer + void reallocate(int newSize); + + //Non-copyable + CRawVector(const CRawVector &other); + CRawVector &operator= (const CRawVector &other); +}; + +namespace std { + void swap(CRawVector &a, CRawVector &b); +} + +#endif diff --git a/DarkMod/Relations.cpp b/game/Relations.cpp similarity index 92% rename from DarkMod/Relations.cpp rename to game/Relations.cpp index e88ff2a58..8e1cebaf4 100644 --- a/DarkMod/Relations.cpp +++ b/game/Relations.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /******************************************************************************/ /* */ /* Dark Mod AI Relationships (C) by Chris Sarantos in USA 2005 */ @@ -23,7 +33,7 @@ #include "../idlib/precompiled.h" #pragma hdrstop -#include "../game/game_local.h" +#include "Game_local.h" static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/Relations.h b/game/Relations.h similarity index 88% rename from DarkMod/Relations.h rename to game/Relations.h index a792772cb..ea42a5def 100644 --- a/DarkMod/Relations.h +++ b/game/Relations.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /******************************************************************************/ /* */ /* Dark Mod AI Relationships (C) by Chris Sarantos in USA 2005 */ diff --git a/game/RevisionTracker.cpp b/game/RevisionTracker.cpp new file mode 100644 index 000000000..f8fae97a9 --- /dev/null +++ b/game/RevisionTracker.cpp @@ -0,0 +1,91 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#pragma warning(disable : 4533 4800) + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "RevisionTracker.h" + +#include +#include +#include +#include +#include + +RevisionTracker::RevisionTracker() : + _highestRevision(0), + _lowestRevision(INT_MAX), + _numFiles(0) +{} + +int RevisionTracker::GetHighestRevision() const +{ + return _highestRevision; +} + +int RevisionTracker::GetLowestRevision() const +{ + return _lowestRevision; +} + +int RevisionTracker::GetNumFiles() const +{ + return _numFiles; +} + +void RevisionTracker::AddRevision(int revision) +{ + _numFiles++; + + if (_highestRevision < revision) + { + _highestRevision = revision; + } + + if (_lowestRevision > revision) + { + _lowestRevision = revision; + } +} + +void RevisionTracker::ParseSVNIdString(const char* input) +{ + std::string revStr(input); + std::vector parts; + + // Split the incoming string into parts + boost::algorithm::split(parts, revStr, boost::algorithm::is_any_of(" ")); + + if (parts.size() > 1) + { + // The third token is the SVN revision, convert it to integer and pass it along + Instance().AddRevision(atoi(parts[2].c_str())); + } +} + +// Accessor to the singleton +RevisionTracker& RevisionTracker::Instance() +{ + static RevisionTracker _instance; + return _instance; +} diff --git a/game/RevisionTracker.h b/game/RevisionTracker.h new file mode 100644 index 000000000..2110f81a6 --- /dev/null +++ b/game/RevisionTracker.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __TDM_REVISION_TRACKER_H__ +#define __TDM_REVISION_TRACKER_H__ + +/** + * greebo: This class is a simple singleton keeping track of the highest and + * lowest SVN revision numbers. + * + * The global function FileRevisionList() is taking care of registering + * the revision numbers to this class. + */ +class RevisionTracker +{ + // Some stats + int _highestRevision; + int _lowestRevision; + int _numFiles; + +public: + /** + * Constructor is taking care of initialising the members. + */ + RevisionTracker(); + + /** + * greebo: Accessor methods. Retrieves the highest and lowest revision + * and the number of registered files. + */ + int GetHighestRevision() const; + int GetLowestRevision() const; + int GetNumFiles() const; + + /** + * Use this method to register a new revision. + */ + void AddRevision(int revision); + + /** + * Entry point for FileVersionList(). Take this method to + * parse an SVN id string and retrieve the revision. + * This methods passes the call to AddRevision. + */ + static void ParseSVNIdString(const char* input); + + // Accessor to the singleton + static RevisionTracker& Instance(); +}; + +#endif /* __TDM_REVISION_TRACKER_H__ */ diff --git a/DarkMod/SEED.cpp b/game/SEED.cpp similarity index 99% rename from DarkMod/SEED.cpp rename to game/SEED.cpp index 8aad843ea..8c6a48b80 100644 --- a/DarkMod/SEED.cpp +++ b/game/SEED.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2010-2011 Tels (Donated to The Dark Mod Team) @@ -1615,7 +1625,7 @@ void Seed::AddClassFromEntity( idEntity *ent, const bool watch, const bool getSp // consisting of a flat plane get 0 as size: // gameLocal.Printf( "SEED %s: size %0.2f x %0.2f.\n", GetName(), fmax( 0.1, SeedClass.size.x), fmax( 0.1, SeedClass.size.y ) ); - float size = (std::max(0.1f, SeedClass.size.x) + SeedClass.spacing) * (std::max( 0.1f, SeedClass.size.y) + SeedClass.spacing); + float size = (Max(0.1f, SeedClass.size.x) + SeedClass.spacing) * (Max( 0.1f, SeedClass.size.y) + SeedClass.spacing); // if falloff != none, correct the density, because the ellipse-shape is smaller then the rectangle if ( SeedClass.falloff >= 1 && SeedClass.falloff <= 3) @@ -1631,9 +1641,9 @@ void Seed::AddClassFromEntity( idEntity *ent, const bool watch, const bool getSp fMin = 0.000001f; // scale the per-class size by the per-class density - float fDensity = std::max( fMin, ent->spawnArgs.GetFloat( "seed_density", "1.0" ) ); + float fDensity = Max( fMin, ent->spawnArgs.GetFloat( "seed_density", "1.0" ) ); // scale the per-class size by the per-class density multiplied by the base density - float fBaseDensity = std::max( fMin, ent->spawnArgs.GetFloat( "seed_base_density", "1.0" ) ); + float fBaseDensity = Max( fMin, ent->spawnArgs.GetFloat( "seed_base_density", "1.0" ) ); // gameLocal.Printf( "SEED %s: Scaling class size by %0.4f (%0.6f * %0.6f).\n", GetName(), fDensity*fBaseDensity, fDensity, fBaseDensity); // gameLocal.Printf( "SEED %s: size = %0.6f fImgDensity = %0.6f\n", GetName(), size, fImgDensity ); @@ -1699,7 +1709,7 @@ void Seed::ComputeEntityCount( void ) fDensity *= LODBIAS(); } - fDensity = std::max( fDensity, 0.00001f); // at minimum 0.00001f + fDensity = Max( fDensity, 0.00001f); // at minimum 0.00001f idBounds bounds = renderEntity.bounds; idVec3 size = bounds.GetSize(); @@ -1749,7 +1759,7 @@ void Seed::ComputeEntityCount( void ) if (max_entities > 0) { // max entities is set on the SEED, so use the score to calculate the entities for each class - newNum = std::max( 1, (max_entities * m_Classes[i].score) / iScoreSum ); // at least one from each class + newNum = Max( 1, (max_entities * m_Classes[i].score) / iScoreSum ); // at least one from each class } else { @@ -1846,7 +1856,7 @@ void Seed::AddTemplateFromEntityDef( idStr base, const idList *sa ) // templateX_skin = "abc, def, '', abc" idStr skin = spawnArgs.GetString( base + "_skin", "" ); // select one at random - skin = skin.RandomPart(); + skin = skin.RandomPart(gameLocal.random.RandomFloat()); //gameLocal.Printf("Using random skin '%s'.\n", skin.c_str() ); args.Set( "skin", skin ); diff --git a/DarkMod/SEED.h b/game/SEED.h similarity index 95% rename from DarkMod/SEED.h rename to game/SEED.h index ce868d217..75acaff0e 100644 --- a/DarkMod/SEED.h +++ b/game/SEED.h @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2010-2011 Tels (Donated to The Dark Mod) @@ -33,12 +43,12 @@ ============================================================================= */ -#include "../game/game_local.h" +#include "Game_local.h" #include "StaticMulti.h" #include "Objectives/MissionData.h" -#include "func_shooter.h" -#include "../game/emitter.h" -#include "../idlib/containers/list.h" +#include "Func_Shooter.h" +#include "Emitter.h" +#include "../idlib/containers/List.h" #define SEED_DEBUG_MATERIAL_COUNT 13 /** List of debug materials to use for the SEED megamodels */ diff --git a/game/SecurityCamera.cpp b/game/SecurityCamera.cpp new file mode 100644 index 000000000..351b1b8e6 --- /dev/null +++ b/game/SecurityCamera.cpp @@ -0,0 +1,595 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* + + SecurityCamera.cpp + + Security camera that triggers targets when player is in view + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "StimResponse/StimResponseCollection.h" + + +/*********************************************************************** + + idSecurityCamera + +***********************************************************************/ + +const idEventDef EV_SecurityCam_ReverseSweep( "" ); +const idEventDef EV_SecurityCam_ContinueSweep( "" ); +const idEventDef EV_SecurityCam_Pause( "" ); +const idEventDef EV_SecurityCam_Alert( "" ); +const idEventDef EV_SecurityCam_AddLight( "" ); + +CLASS_DECLARATION( idEntity, idSecurityCamera ) + EVENT( EV_SecurityCam_ReverseSweep, idSecurityCamera::Event_ReverseSweep ) + EVENT( EV_SecurityCam_ContinueSweep, idSecurityCamera::Event_ContinueSweep ) + EVENT( EV_SecurityCam_Pause, idSecurityCamera::Event_Pause ) + EVENT( EV_SecurityCam_Alert, idSecurityCamera::Event_Alert ) + EVENT( EV_SecurityCam_AddLight, idSecurityCamera::Event_AddLight ) +END_CLASS + +/* +================ +idSecurityCamera::Save +================ +*/ +void idSecurityCamera::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( angle ); + savefile->WriteFloat( sweepAngle ); + savefile->WriteInt( modelAxis ); + savefile->WriteBool( flipAxis ); + savefile->WriteFloat( scanDist ); + savefile->WriteFloat( scanFov ); + + savefile->WriteFloat( sweepStart ); + savefile->WriteFloat( sweepEnd ); + savefile->WriteBool( negativeSweep ); + savefile->WriteBool( sweeping ); + savefile->WriteInt( alertMode ); + savefile->WriteFloat( stopSweeping ); + savefile->WriteFloat( scanFovCos ); + + savefile->WriteVec3( viewOffset ); + + savefile->WriteInt( pvsArea ); + savefile->WriteStaticObject( physicsObj ); + savefile->WriteTraceModel( trm ); +} + +/* +================ +idSecurityCamera::Restore +================ +*/ +void idSecurityCamera::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( angle ); + savefile->ReadFloat( sweepAngle ); + savefile->ReadInt( modelAxis ); + savefile->ReadBool( flipAxis ); + savefile->ReadFloat( scanDist ); + savefile->ReadFloat( scanFov ); + + savefile->ReadFloat( sweepStart ); + savefile->ReadFloat( sweepEnd ); + savefile->ReadBool( negativeSweep ); + savefile->ReadBool( sweeping ); + savefile->ReadInt( alertMode ); + savefile->ReadFloat( stopSweeping ); + savefile->ReadFloat( scanFovCos ); + + savefile->ReadVec3( viewOffset ); + + savefile->ReadInt( pvsArea ); + savefile->ReadStaticObject( physicsObj ); + savefile->ReadTraceModel( trm ); +} + +/* +================ +idSecurityCamera::Spawn +================ +*/ +void idSecurityCamera::Spawn( void ) { + idStr str; + + sweepAngle = spawnArgs.GetFloat( "sweepAngle", "90" ); + health = spawnArgs.GetInt( "health", "100" ); + scanFov = spawnArgs.GetFloat( "scanFov", "90" ); + scanDist = spawnArgs.GetFloat( "scanDist", "200" ); + flipAxis = spawnArgs.GetBool( "flipAxis" ); + + modelAxis = spawnArgs.GetInt( "modelAxis" ); + if ( modelAxis < 0 || modelAxis > 2 ) { + modelAxis = 0; + } + + spawnArgs.GetVector( "viewOffset", "0 0 0", viewOffset ); + + if ( spawnArgs.GetBool( "spotLight" ) ) { + PostEventMS( &EV_SecurityCam_AddLight, 0 ); + } + + negativeSweep = ( sweepAngle < 0 ) ? true : false; + sweepAngle = fabs( sweepAngle ); + + scanFovCos = cos( scanFov * idMath::PI / 360.0f ); + + angle = GetPhysics()->GetAxis().ToAngles().yaw; + StartSweep(); + SetAlertMode( SCANNING ); + BecomeActive( TH_THINK ); + + if ( health ) { + fl.takedamage = true; + } + + pvsArea = gameLocal.pvs.GetPVSArea( GetPhysics()->GetOrigin() ); + // if no target specified use ourself + str = spawnArgs.GetString( "cameraTarget" ); + if ( str.Length() == 0 ) { + spawnArgs.Set( "cameraTarget", spawnArgs.GetString( "name" ) ); + } + + // check if a clip model is set + spawnArgs.GetString( "clipmodel", "", str ); + if ( !str[0] ) { + str = spawnArgs.GetString( "model" ); // use the visual model + } + + if ( !collisionModelManager->TrmFromModel( str, trm ) ) { + gameLocal.Error( "idSecurityCamera '%s': cannot load collision model %s", name.c_str(), str.c_str() ); + return; + } + + GetPhysics()->SetContents( CONTENTS_SOLID ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + GetPhysics()->SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); + // setup the physics + UpdateChangeableSpawnArgs( NULL ); +} + +/* +================ +idSecurityCamera::Event_AddLight +================ +*/ +void idSecurityCamera::Event_AddLight( void ) { + idDict args; + idVec3 right, up, target, temp; + idVec3 dir; + float radius; + idVec3 lightOffset; + idLight *spotLight; + + dir = GetAxis(); + dir.NormalVectors( right, up ); + target = GetPhysics()->GetOrigin() + dir * scanDist; + + radius = tan( scanFov * idMath::PI / 360.0f ); + up = dir + up * radius; + up.Normalize(); + up = GetPhysics()->GetOrigin() + up * scanDist; + up -= target; + + right = dir + right * radius; + right.Normalize(); + right = GetPhysics()->GetOrigin() + right * scanDist; + right -= target; + + spawnArgs.GetVector( "lightOffset", "0 0 0", lightOffset ); + + args.Set( "origin", ( GetPhysics()->GetOrigin() + lightOffset ).ToString() ); + args.Set( "light_target", target.ToString() ); + args.Set( "light_right", right.ToString() ); + args.Set( "light_up", up.ToString() ); + args.SetFloat( "angle", GetPhysics()->GetAxis()[0].ToYaw() ); + + spotLight = static_cast( gameLocal.SpawnEntityType( idLight::Type, &args ) ); + spotLight->Bind( this, true ); + spotLight->UpdateVisuals(); +} + +/* +================ +idSecurityCamera::DrawFov +================ +*/ +void idSecurityCamera::DrawFov( void ) { + int i; + float radius, a, s, c, halfRadius; + idVec3 right, up; + idVec4 color(1, 0, 0, 1), color2(0, 0, 1, 1); + idVec3 lastPoint, point, lastHalfPoint, halfPoint, center; + + idVec3 dir = GetAxis(); + dir.NormalVectors( right, up ); + + radius = tan( scanFov * idMath::PI / 360.0f ); + halfRadius = radius * 0.5f; + lastPoint = dir + up * radius; + lastPoint.Normalize(); + lastPoint = GetPhysics()->GetOrigin() + lastPoint * scanDist; + lastHalfPoint = dir + up * halfRadius; + lastHalfPoint.Normalize(); + lastHalfPoint = GetPhysics()->GetOrigin() + lastHalfPoint * scanDist; + center = GetPhysics()->GetOrigin() + dir * scanDist; + for ( i = 1; i < 12; i++ ) { + a = idMath::TWO_PI * i / 12.0f; + idMath::SinCos( a, s, c ); + point = dir + right * s * radius + up * c * radius; + point.Normalize(); + point = GetPhysics()->GetOrigin() + point * scanDist; + gameRenderWorld->DebugLine( color, lastPoint, point ); + gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), point ); + lastPoint = point; + + halfPoint = dir + right * s * halfRadius + up * c * halfRadius; + halfPoint.Normalize(); + halfPoint = GetPhysics()->GetOrigin() + halfPoint * scanDist; + gameRenderWorld->DebugLine( color2, point, halfPoint ); + gameRenderWorld->DebugLine( color2, lastHalfPoint, halfPoint ); + lastHalfPoint = halfPoint; + + gameRenderWorld->DebugLine( color2, halfPoint, center ); + } +} + +/* +================ +idSecurityCamera::GetRenderView +================ +*/ +renderView_t *idSecurityCamera::GetRenderView() { + renderView_t *rv = idEntity::GetRenderView(); + rv->fov_x = scanFov; + rv->fov_y = scanFov; + rv->viewaxis = GetAxis().ToAngles().ToMat3(); + rv->vieworg = GetPhysics()->GetOrigin() + viewOffset; + return rv; +} + +/* +================ +idSecurityCamera::CanSeePlayer +================ +*/ +bool idSecurityCamera::CanSeePlayer( void ) { + int i; + float dist; + idPlayer *ent; + trace_t tr; + idVec3 dir; + pvsHandle_t handle; + + handle = gameLocal.pvs.SetupCurrentPVS( pvsArea ); + + for ( i = 0; i < gameLocal.numClients; i++ ) { + ent = static_cast(gameLocal.entities[ i ]); + + if ( !ent || ( ent->fl.notarget ) ) { + continue; + } + + // if there is no way we can see this player + if ( !gameLocal.pvs.InCurrentPVS( handle, ent->GetPVSAreas(), ent->GetNumPVSAreas() ) ) { + continue; + } + + dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + dist = dir.Normalize(); + + if ( dist > scanDist ) { + continue; + } + + if ( dir * GetAxis() < scanFovCos ) { + continue; + } + + idVec3 eye; + + eye = ent->EyeOffset(); + + gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), ent->GetPhysics()->GetOrigin() + eye, MASK_OPAQUE, this ); + if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == ent ) ) { + gameLocal.pvs.FreeCurrentPVS( handle ); + return true; + } + } + + gameLocal.pvs.FreeCurrentPVS( handle ); + + return false; +} + +/* +================ +idSecurityCamera::SetAlertMode +================ +*/ +void idSecurityCamera::SetAlertMode( int alert ) { + if (alert >= SCANNING && alert <= ACTIVATED) { + alertMode = alert; + } + renderEntity.shaderParms[ SHADERPARM_MODE ] = alertMode; + UpdateVisuals(); +} + +/* +================ +idSecurityCamera::Think +================ +*/ +void idSecurityCamera::Think( void ) { + float pct; + float travel; + + if ( thinkFlags & TH_THINK ) { + if ( g_showEntityInfo.GetBool() ) { + DrawFov(); + } + + if (health <= 0) { + BecomeInactive( TH_THINK ); + return; + } + } + + // run physics + RunPhysics(); + + if ( thinkFlags & TH_THINK ) { + if (CanSeePlayer()) { + if (alertMode == SCANNING) { + float sightTime; + + SetAlertMode(ALERT); + stopSweeping = gameLocal.time; + if (sweeping) { + CancelEvents( &EV_SecurityCam_Pause ); + } else { + CancelEvents( &EV_SecurityCam_ReverseSweep ); + } + sweeping = false; + StopSound( SND_CHANNEL_ANY, false ); + StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL ); + + sightTime = spawnArgs.GetFloat( "sightTime", "5" ); + PostEventSec(&EV_SecurityCam_Alert, sightTime); + } + } else { + if (alertMode == ALERT) { + float sightResume; + + SetAlertMode(LOSINGINTEREST); + CancelEvents( &EV_SecurityCam_Alert ); + + sightResume = spawnArgs.GetFloat( "sightResume", "1.5" ); + PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume ); + } + + if ( sweeping ) { + idAngles a = GetPhysics()->GetAxis().ToAngles(); + + pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart ); + travel = pct * sweepAngle; + if ( negativeSweep ) { + a.yaw = angle + travel; + } else { + a.yaw = angle - travel; + } + + SetAngles( a ); + } + } + } + Present(); +} + +/* +================ +idSecurityCamera::GetAxis +================ +*/ +const idVec3 idSecurityCamera::GetAxis( void ) const { + return (flipAxis) ? -GetPhysics()->GetAxis()[modelAxis] : GetPhysics()->GetAxis()[modelAxis]; +}; + +/* +================ +idSecurityCamera::SweepSpeed +================ +*/ +float idSecurityCamera::SweepSpeed( void ) const { + return spawnArgs.GetFloat( "sweepSpeed", "5" ); +} + +/* +================ +idSecurityCamera::StartSweep +================ +*/ +void idSecurityCamera::StartSweep( void ) { + int speed; + + sweeping = true; + sweepStart = gameLocal.time; + speed = SEC2MS( SweepSpeed() ); + sweepEnd = sweepStart + speed; + PostEventMS( &EV_SecurityCam_Pause, speed ); + StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL ); +} + +/* +================ +idSecurityCamera::Event_ContinueSweep +================ +*/ +void idSecurityCamera::Event_ContinueSweep( void ) { + float pct = (stopSweeping - sweepStart) / (sweepEnd - sweepStart); + float f = gameLocal.time - (sweepEnd - sweepStart) * pct; + int speed; + + sweepStart = f; + speed = static_cast(MS2SEC( SweepSpeed() )); + sweepEnd = sweepStart + speed; + PostEventMS( &EV_SecurityCam_Pause, static_cast(speed * (1.0f - pct))); + StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL ); + SetAlertMode(SCANNING); + sweeping = true; +} + +/* +================ +idSecurityCamera::Event_Alert +================ +*/ +void idSecurityCamera::Event_Alert( void ) { + float wait; + + SetAlertMode(ACTIVATED); + StopSound( SND_CHANNEL_ANY, false ); + StartSound( "snd_activate", SND_CHANNEL_BODY, 0, false, NULL ); + ActivateTargets(this); + CancelEvents( &EV_SecurityCam_ContinueSweep ); + + wait = spawnArgs.GetFloat( "wait", "20" ); + PostEventSec( &EV_SecurityCam_ContinueSweep, wait ); +} + +/* +================ +idSecurityCamera::Event_ReverseSweep +================ +*/ +void idSecurityCamera::Event_ReverseSweep( void ) { + angle = GetPhysics()->GetAxis().ToAngles().yaw; + negativeSweep = !negativeSweep; + StartSweep(); +} + +/* +================ +idSecurityCamera::Event_Pause +================ +*/ +void idSecurityCamera::Event_Pause( void ) { + float sweepWait; + + sweepWait = spawnArgs.GetFloat( "sweepWait", "0.5" ); + sweeping = false; + StopSound( SND_CHANNEL_ANY, false ); + StartSound( "snd_stop", SND_CHANNEL_BODY, 0, false, NULL ); + PostEventSec( &EV_SecurityCam_ReverseSweep, sweepWait ); +} + +/* +============ +idSecurityCamera::Killed +============ +*/ +void idSecurityCamera::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + sweeping = false; + StopSound( SND_CHANNEL_ANY, false ); + const char *fx = spawnArgs.GetString( "fx_destroyed" ); + if ( fx[0] != '\0' ) { + idEntityFx::StartFx( fx, NULL, NULL, this, true ); + } + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( trm ), 0.02f ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + physicsObj.SetBouncyness( 0.2f ); + physicsObj.SetFriction( 0.6f, 0.6f, 0.2f ); + physicsObj.SetGravity( gameLocal.GetGravity() ); + physicsObj.SetContents( CONTENTS_SOLID ); + physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); + SetPhysics( &physicsObj ); + physicsObj.DropToFloor(); +} + + +/* +============ +idSecurityCamera::Pain +============ +*/ +bool idSecurityCamera::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { + const char *fx = spawnArgs.GetString( "fx_damage" ); + if ( fx[0] != '\0' ) { + idEntityFx::StartFx( fx, NULL, NULL, this, true ); + } + return true; +} + + +/* +================ +idSecurityCamera::Present + +Present is called to allow entities to generate refEntities, lights, etc for the renderer. +================ +*/ +void idSecurityCamera::Present( void ) +{ + if( m_FrobDistance ) + { + UpdateFrobState(); + UpdateFrobDisplay(); + } + + // don't present to the renderer if the entity hasn't changed + if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { + return; + } + BecomeInactive( TH_UPDATEVISUALS ); + + // camera target for remote render views + if ( cameraTarget ) { + renderEntity.remoteRenderView = cameraTarget->GetRenderView(); + } + + // if set to invisible, skip + if ( !renderEntity.hModel || IsHidden() ) { + return; + } + + // add to refresh list + if ( modelDefHandle == -1 ) { + modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + } else { + gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); + } +} diff --git a/game/SecurityCamera.h b/game/SecurityCamera.h new file mode 100644 index 000000000..2479e4cb8 --- /dev/null +++ b/game/SecurityCamera.h @@ -0,0 +1,88 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_SECURITYCAMERA_H__ +#define __GAME_SECURITYCAMERA_H__ + +/* +=================================================================================== + + Security camera + +=================================================================================== +*/ + + +class idSecurityCamera : public idEntity { +public: + CLASS_PROTOTYPE( idSecurityCamera ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Think( void ); + + virtual renderView_t * GetRenderView(); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + virtual void Present( void ); + + +private: + + enum { SCANNING, LOSINGINTEREST, ALERT, ACTIVATED }; + + float angle; + float sweepAngle; + int modelAxis; + bool flipAxis; + float scanDist; + float scanFov; + + float sweepStart; + float sweepEnd; + bool negativeSweep; + bool sweeping; + int alertMode; + float stopSweeping; + float scanFovCos; + + idVec3 viewOffset; + + int pvsArea; + idPhysics_RigidBody physicsObj; + idTraceModel trm; + + void StartSweep( void ); + bool CanSeePlayer( void ); + void SetAlertMode( int status ); + void DrawFov( void ); + const idVec3 GetAxis( void ) const; + float SweepSpeed( void ) const; + + void Event_ReverseSweep( void ); + void Event_ContinueSweep( void ); + void Event_Pause( void ); + void Event_Alert( void ); + void Event_AddLight( void ); +}; + +#endif /* !__GAME_SECURITYCAMERA_H__ */ diff --git a/DarkMod/Shop/LootRuleSet.cpp b/game/Shop/LootRuleSet.cpp similarity index 80% rename from DarkMod/Shop/LootRuleSet.cpp rename to game/Shop/LootRuleSet.cpp index 2e60440a4..b45a09a0b 100644 --- a/DarkMod/Shop/LootRuleSet.cpp +++ b/game/Shop/LootRuleSet.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/Shop/LootRuleSet.h b/game/Shop/LootRuleSet.h new file mode 100644 index 000000000..676ec630b --- /dev/null +++ b/game/Shop/LootRuleSet.h @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef TDM_LOOTRULESET_H +#define TDM_LOOTRULESET_H + +#include "../Inventory/LootType.h" + +/** + * greebo: A structure defining loot carry-over rules for the shop. + * The mapper can define how much of the collected loot + * makes it into the shop. + * + * A default-constructed LootRules set won't change the incoming loot values + * everything is losslessly passed through with a 1:1 conversion, + * and the player is allowed to keep his money. + */ +struct LootRuleSet +{ + // The conversion rate for each loot type. Before entering the shop + // every loot type is converted to gold. + float conversionRate[LOOT_COUNT]; + + // Gold loss after conversion (defaults to 0 => no loss) + int goldLoss; + + // Gold loss by percent after conversion (defaults to 0 => no loss) + float goldLossPercent; + + // Minimum amount of gold available in the shop. At least this value is guaranteed to be returned by ApplyToFoundLoot + int goldMin; + + // Maximum amount of gold available in the shop. Enforced after conversion. (default is -1 => no cap) + int goldCap; + + LootRuleSet() + { + Clear(); + } + + void Clear(); + + // Equality operator, returns true if this class is the same as the other. Doesn't check LOOT_NONE conversion. + bool operator==(const LootRuleSet& other) const; + + // Returns TRUE if this lootrule structure is at default values + // This is a comparably slow call, so don't use it excessively + bool IsEmpty() const + { + // Compare this instance against a default-constructed one + return *this == LootRuleSet(); + } + + // Load the ruleset from the spawnargs matching the given prefix + void LoadFromDict(const idDict& dict, const idStr& prefix); + + /** + * Apply this ruleset to the given amount of found loot and shop start budget. + * + * @foundLoot: The loot collected values. + * @shopStartingGold: The amount of starting gold for the shop. This value + * is added after applying the losses, but before the min/max caps are applied. + * + * Returns the amount of resulting gold, which is at least goldMin. + */ + int ApplyToFoundLoot(const int foundLoot[LOOT_COUNT], int shopStartingGold); +}; + +#endif diff --git a/DarkMod/Shop/Shop.cpp b/game/Shop/Shop.cpp similarity index 97% rename from DarkMod/Shop/Shop.cpp rename to game/Shop/Shop.cpp index 8898a5a01..fe1ee95d7 100644 --- a/DarkMod/Shop/Shop.cpp +++ b/game/Shop/Shop.cpp @@ -1,20 +1,30 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); #include "Shop.h" -#include "../../game/game_local.h" +#include "../Game_local.h" #include "../Objectives/MissionData.h" #include "../Objectives/CampaignStatistics.h" #include "../Missions/MissionManager.h" diff --git a/DarkMod/Shop/Shop.h b/game/Shop/Shop.h similarity index 86% rename from DarkMod/Shop/Shop.h rename to game/Shop/Shop.h index 63d9a8370..9e22fe646 100644 --- a/DarkMod/Shop/Shop.h +++ b/game/Shop/Shop.h @@ -1,13 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __SHOP_H__ #define __SHOP_H__ diff --git a/DarkMod/Shop/ShopItem.cpp b/game/Shop/ShopItem.cpp similarity index 83% rename from DarkMod/Shop/ShopItem.cpp rename to game/Shop/ShopItem.cpp index bf3bfbe05..2fc42a505 100644 --- a/DarkMod/Shop/ShopItem.cpp +++ b/game/Shop/ShopItem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/Shop/ShopItem.h b/game/Shop/ShopItem.h similarity index 77% rename from DarkMod/Shop/ShopItem.h rename to game/Shop/ShopItem.h index 9a1f1f540..bfcf4c692 100644 --- a/DarkMod/Shop/ShopItem.h +++ b/game/Shop/ShopItem.h @@ -1,12 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __SHOPITEM_H__ #define __SHOPITEM_H__ diff --git a/game/SmokeParticles.cpp b/game/SmokeParticles.cpp new file mode 100644 index 000000000..65b2b93f9 --- /dev/null +++ b/game/SmokeParticles.cpp @@ -0,0 +1,414 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +static const char *smokeParticle_SnapshotName = "_SmokeParticle_Snapshot_"; + +/* +================ +idSmokeParticles::idSmokeParticles +================ +*/ +idSmokeParticles::idSmokeParticles( void ) { + initialized = false; + memset( &renderEntity, 0, sizeof( renderEntity ) ); + renderEntityHandle = -1; + memset( smokes, 0, sizeof( smokes ) ); + freeSmokes = NULL; + numActiveSmokes = 0; + currentParticleTime = -1; +} + +/* +================ +idSmokeParticles::Init +================ +*/ +void idSmokeParticles::Init( void ) { + if ( initialized ) { + Shutdown(); + } + + // set up the free list + for ( int i = 0; i < MAX_SMOKE_PARTICLES-1; i++ ) { + smokes[i].next = &smokes[i+1]; + } + smokes[MAX_SMOKE_PARTICLES-1].next = NULL; + freeSmokes = &smokes[0]; + numActiveSmokes = 0; + + activeStages.Clear(); + + memset( &renderEntity, 0, sizeof( renderEntity ) ); + + renderEntity.bounds.Clear(); + renderEntity.axis = mat3_identity; + renderEntity.shaderParms[ SHADERPARM_RED ] = 1; + renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1; + renderEntity.shaderParms[3] = 1; + + renderEntity.hModel = renderModelManager->AllocModel(); + renderEntity.hModel->InitEmpty( smokeParticle_SnapshotName ); + + // we certainly don't want particle shadows + renderEntity.noShadow = 1; + + // huge bounds, so it will be present in every world area + renderEntity.bounds.AddPoint( idVec3(-100000, -100000, -100000) ); + renderEntity.bounds.AddPoint( idVec3( 100000, 100000, 100000) ); + + renderEntity.callback = idSmokeParticles::ModelCallback; + // add to renderer list + renderEntityHandle = gameRenderWorld->AddEntityDef( &renderEntity ); + + currentParticleTime = -1; + + initialized = true; +} + +/* +================ +idSmokeParticles::Shutdown +================ +*/ +void idSmokeParticles::Shutdown( void ) { + // make sure the render entity is freed before the model is freed + if ( renderEntityHandle != -1 ) { + gameRenderWorld->FreeEntityDef( renderEntityHandle ); + renderEntityHandle = -1; + } + if ( renderEntity.hModel != NULL ) { + renderModelManager->FreeModel( renderEntity.hModel ); + renderEntity.hModel = NULL; + } + initialized = false; +} + +/* +================ +idSmokeParticles::FreeSmokes +================ +*/ +void idSmokeParticles::FreeSmokes( void ) { + for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) { + singleSmoke_t *smoke, *next, *last; + + activeSmokeStage_t *active = &activeStages[activeStageNum]; + const idParticleStage *stage = active->stage; + + for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) { + next = smoke->next; + + float frac = (float)( gameLocal.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 ); + if ( frac >= 1.0f ) { + // remove the particle from the stage list + if ( last != NULL ) { + last->next = smoke->next; + } else { + active->smokes = smoke->next; + } + // put the particle on the free list + smoke->next = freeSmokes; + freeSmokes = smoke; + numActiveSmokes--; + continue; + } + + last = smoke; + } + + if ( !active->smokes ) { + // remove this from the activeStages list + activeStages.RemoveIndex( activeStageNum ); + activeStageNum--; + } + } +} + +/* +================ +idSmokeParticles::EmitSmoke + +Called by game code to drop another particle into the list +================ +*/ +bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemStartTime, const float diversity, const idVec3 &origin, const idMat3 &axis ) { + bool continues = false; + + if ( !smoke ) { + return false; + } + + if ( !gameLocal.isNewFrame ) { + return false; + } + + // dedicated doesn't smoke. No UpdateRenderEntity, so they would not be freed + if ( gameLocal.localClientNum < 0 ) { + return false; + } + + assert( gameLocal.time == 0 || systemStartTime <= gameLocal.time ); + if ( systemStartTime > gameLocal.time ) { + return false; + } + + idRandom steppingRandom( static_cast(0xffff * diversity) ); + + // for each stage in the smoke that is still emitting particles, emit a new singleSmoke_t + for ( int stageNum = 0; stageNum < smoke->stages.Num(); stageNum++ ) { + const idParticleStage *stage = smoke->stages[stageNum]; + + if ( !stage->cycleMsec ) { + continue; + } + + if ( !stage->material ) { + continue; + } + + if ( stage->particleLife <= 0 ) { + continue; + } + + // see how many particles we should emit this tic + // FIXME: smoke.privateStartTime += stage->timeOffset; + int finalParticleTime = static_cast(stage->spawnBunching * stage->cycleMsec); + int deltaMsec = gameLocal.time - systemStartTime; + + int nowCount = 0, prevCount; + if ( finalParticleTime == 0 ) { + // if spawnBunching is 0, they will all come out at once + if ( gameLocal.time == systemStartTime ) { + prevCount = -1; + nowCount = stage->totalParticles-1; + } else { + prevCount = stage->totalParticles; + } + } else { + nowCount = static_cast(floor( ( (float)deltaMsec / finalParticleTime ) * stage->totalParticles )); + if ( nowCount >= stage->totalParticles ) { + nowCount = stage->totalParticles-1; + } + prevCount = static_cast(floor( ((float)( deltaMsec - USERCMD_MSEC ) / finalParticleTime) * stage->totalParticles )); + if ( prevCount < -1 ) { + prevCount = -1; + } + } + + if ( prevCount >= stage->totalParticles ) { + // no more particles from this stage + continue; + } + + if ( nowCount < stage->totalParticles-1 ) { + // the system will need to emit particles next frame as well + continues = true; + } + + // find an activeSmokeStage that matches this + activeSmokeStage_t *active(NULL); + int i; + for ( i = 0 ; i < activeStages.Num() ; i++ ) { + active = &activeStages[i]; + if ( active->stage == stage ) { + break; + } + } + if ( i == activeStages.Num() ) { + // add a new one + activeSmokeStage_t newActive; + + newActive.smokes = NULL; + newActive.stage = stage; + i = activeStages.Append( newActive ); + active = &activeStages[i]; + } + + // add all the required particles + for ( prevCount++ ; prevCount <= nowCount ; prevCount++ ) { + if ( !freeSmokes ) { + gameLocal.Printf( "idSmokeParticles::EmitSmoke: no free smokes with %d active stages\n", activeStages.Num() ); + return true; + } + singleSmoke_t *newSmoke = freeSmokes; + freeSmokes = freeSmokes->next; + numActiveSmokes++; + + newSmoke->index = prevCount; + newSmoke->axis = axis; + newSmoke->origin = origin; + newSmoke->random = steppingRandom; + newSmoke->privateStartTime = systemStartTime + prevCount * finalParticleTime / stage->totalParticles; + newSmoke->next = active->smokes; + active->smokes = newSmoke; + + steppingRandom.RandomInt(); // advance the random + } + } + + return continues; +} + +/* +================ +idSmokeParticles::UpdateRenderEntity +================ +*/ +bool idSmokeParticles::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) { + + // FIXME: re-use model surfaces + renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName ); + + // this may be triggered by a model trace or other non-view related source, + // to which we should look like an empty model + if ( !renderView ) { + return false; + } + + // don't regenerate it if it is current + if ( renderView->time == currentParticleTime && !renderView->forceUpdate ) { + return false; + } + currentParticleTime = renderView->time; + + particleGen_t g; + + g.renderEnt = renderEntity; + g.renderView = renderView; + + for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) { + singleSmoke_t *smoke, *next, *last; + + activeSmokeStage_t *active = &activeStages[activeStageNum]; + const idParticleStage *stage = active->stage; + + if ( !stage->material ) { + continue; + } + + // allocate a srfTriangles that can hold all the particles + int count = 0; + for ( smoke = active->smokes; smoke; smoke = smoke->next ) { + count++; + } + int quads = count * stage->NumQuadsPerParticle(); + srfTriangles_t *tri = renderEntity->hModel->AllocSurfaceTriangles( quads * 4, quads * 6 ); + tri->numIndexes = quads * 6; + tri->numVerts = quads * 4; + + // just always draw the particles + tri->bounds[0][0] = + tri->bounds[0][1] = + tri->bounds[0][2] = -99999; + tri->bounds[1][0] = + tri->bounds[1][1] = + tri->bounds[1][2] = 99999; + + tri->numVerts = 0; + for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) { + next = smoke->next; + + g.frac = (float)( gameLocal.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 ); + if ( g.frac >= 1.0f ) { + // remove the particle from the stage list + if ( last != NULL ) { + last->next = smoke->next; + } else { + active->smokes = smoke->next; + } + // put the particle on the free list + smoke->next = freeSmokes; + freeSmokes = smoke; + numActiveSmokes--; + continue; + } + + g.index = smoke->index; + g.random = smoke->random; + + g.origin = smoke->origin; + g.axis = smoke->axis; + + g.originalRandom = g.random; + g.age = g.frac * stage->particleLife; + + tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts ); + + last = smoke; + } + if ( tri->numVerts > quads * 4 ) { + gameLocal.Error( "idSmokeParticles::UpdateRenderEntity: miscounted verts" ); + } + + if ( tri->numVerts == 0 ) { + + // they were all removed + renderEntity->hModel->FreeSurfaceTriangles( tri ); + + if ( !active->smokes ) { + // remove this from the activeStages list + activeStages.RemoveIndex( activeStageNum ); + activeStageNum--; + } + } else { + // build the index list + int indexes = 0; + for ( int i = 0 ; i < tri->numVerts ; i += 4 ) { + tri->indexes[indexes+0] = i; + tri->indexes[indexes+1] = i+2; + tri->indexes[indexes+2] = i+3; + tri->indexes[indexes+3] = i; + tri->indexes[indexes+4] = i+3; + tri->indexes[indexes+5] = i+1; + indexes += 6; + } + tri->numIndexes = indexes; + + modelSurface_t surf; + surf.geometry = tri; + surf.shader = stage->material; + surf.id = 0; + + renderEntity->hModel->AddSurface( surf ); + } + } + return true; +} + +/* +================ +idSmokeParticles::ModelCallback +================ +*/ +bool idSmokeParticles::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) { + // update the particles + if ( gameLocal.smokeParticles ) { + return gameLocal.smokeParticles->UpdateRenderEntity( renderEntity, renderView ); + } + + return true; +} diff --git a/game/SmokeParticles.h b/game/SmokeParticles.h new file mode 100644 index 000000000..ec1ce4c76 --- /dev/null +++ b/game/SmokeParticles.h @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SMOKEPARTICLES_H__ +#define __SMOKEPARTICLES_H__ + +/* +=============================================================================== + + Smoke systems are for particles that are emitted off of things that are + constantly changing position and orientation, like muzzle smoke coming + from a bone on a weapon, blood spurting from a wound, or particles + trailing from a monster limb. + + The smoke particles are always evaluated and rendered each tic, so there + is a performance cost with using them for continuous effects. The general + particle systems are completely parametric, and have no performance + overhead when not in view. + + All smoke systems share the same shaderparms, so any coloration must be + done in the particle definition. + + Each particle model has its own shaderparms, which can be used by the + particle materials. + +=============================================================================== +*/ + +typedef struct singleSmoke_s { + struct singleSmoke_s * next; + int privateStartTime; // start time for this particular particle + int index; // particle index in system, 0 <= index < stage->totalParticles + idRandom random; + idVec3 origin; + idMat3 axis; +} singleSmoke_t; + +class idParticleStage; + +typedef struct { + const idParticleStage * stage; + singleSmoke_t * smokes; +} activeSmokeStage_t; + + +class idSmokeParticles { +public: + idSmokeParticles( void ); + + // creats an entity covering the entire world that will call back each rendering + void Init( void ); + void Shutdown( void ); + + // spits out a particle, returning false if the system will not emit any more particles in the future + bool EmitSmoke( const idDeclParticle *smoke, const int startTime, const float diversity, + const idVec3 &origin, const idMat3 &axis ); + + // free old smokes + void FreeSmokes( void ); + +private: + bool initialized; + + renderEntity_t renderEntity; // used to present a model to the renderer + int renderEntityHandle; // handle to static renderer model + + static const int MAX_SMOKE_PARTICLES = 10000; + singleSmoke_t smokes[MAX_SMOKE_PARTICLES]; + + idList activeStages; + singleSmoke_t * freeSmokes; + int numActiveSmokes; + int currentParticleTime; // don't need to recalculate if == view time + + bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); + static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); +}; + +#endif /* !__SMOKEPARTICLES_H__ */ diff --git a/game/SndProp.cpp b/game/SndProp.cpp new file mode 100644 index 000000000..faa62740d --- /dev/null +++ b/game/SndProp.cpp @@ -0,0 +1,1672 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/******************************************************************************/ +/* */ +/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ +/* All rights reserved */ +/* */ +/******************************************************************************/ + +/****************************************************************************** +* +* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI +* during gameplay. Friend class to CsndPropLoader. +* +*****************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Game_local.h" + +static bool init_version = FileVersionList("$Id$", init_version); + +#pragma warning(disable : 4996) + +#include "SndPropLoader.h" +#include "SndProp.h" +#include "MatrixSq.h" +#include "DarkModGlobals.h" +#include "Relations.h" +#include "ai/AI.h" + +// NOTES: +// ALL LOSSES ARE POSITIVE (ie, loss of +10dB subtracts 10dB from vol) + +// ALL INITIAL VOLUMES ARE SWL [dB] (power level of the source, 10*log(power/1E-12 Watts)) + +// TODO: Add volInit to propParms instead of continually passing it as an argument + +const float s_DOOM_TO_METERS = 0.0254f; // doom to meters +const float s_METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom + +/** +* Max number of areas to flood when doing wavefront expansion +* +* When the expansion goes above this number, it is terminated +* +* TODO: Read this from soundprop def file! +**/ +const int s_MAX_FLOODNODES = 200; + +/** +* Volume ( SPL [dB] ) threshold after which the sound stops propagating +* +* Should correspond to the absolute lowest volume we want AI to be +* able to detect +* +* TODO: Read this from soundprop def file! +**/ +const float s_MIN_AUD_THRESH = 15; + +/** +* Max number of expansion nodes within which to use detailed path minimization +* (That is, trace the path back from AI thru the portals to find the optimum +* points on the portal surface the path travels thru). +* +* TODO: Read this from soundprop def file! +**/ +const float s_MAX_DETAILNODES = 3; + + +/** +* 1/log(10), useful for change of base between log and log10 +**/ +const float s_invLog10 = 0.434294482f; + + +/************************************************** +* BEGIN CsndProp Implementation +***************************************************/ + +CsndProp::CsndProp ( void ) +{ + m_bLoadSuccess = false; + m_bDefaultSpherical = false; + + m_EventAreas = NULL; + m_PopAreas = NULL; + m_sndAreas = NULL; + m_PortData = NULL; + + m_numAreas = 0; + m_numPortals = 0; + + m_TimeStampProp = 0; + m_TimeStampPortLoss = 0; +} + +void CsndProp::Clear( void ) +{ + SPortEvent *pPortEv; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing sound prop gameplay object.\r"); + + m_AreaPropsG.Clear(); + + m_bLoadSuccess = false; + m_bDefaultSpherical = false; + + if( m_EventAreas != NULL ) + { + // delete portal event data array + for( int i=0; i < m_numAreas; i++ ) + { + pPortEv = m_EventAreas[i].PortalDat; + if( pPortEv != NULL ) + delete[] pPortEv; + } + + delete[] m_EventAreas; + m_EventAreas = NULL; + } + + if( m_PopAreas != NULL ) + { + for( int i=0; i < m_numAreas; i++ ) + { + m_PopAreas[i].AIContents.Clear(); + m_PopAreas[i].VisitedPorts.Clear(); + } + + delete[] m_PopAreas; + m_PopAreas = NULL; + } + + // delete m_sndAreas and m_PortData + DestroyAreasData(); +} + +CsndProp::~CsndProp ( void ) +{ + Clear(); +} + +void CsndProp::Save(idSaveGame *savefile) const +{ + // Pass the call to the base class first + CsndPropBase::Save(savefile); + + savefile->WriteInt(m_TimeStampProp); + savefile->WriteInt(m_TimeStampPortLoss); + + savefile->WriteInt(m_PopAreasInd.Num()); + for (int i = 0; i < m_PopAreasInd.Num(); i++) + { + savefile->WriteInt(m_PopAreasInd[i]); + } + + for (int i = 0; i < m_numAreas; i++) + { + savefile->WriteInt(m_PopAreas[i].addedTime); + savefile->WriteBool(m_PopAreas[i].bVisited); + + savefile->WriteInt(m_PopAreas[i].AIContents.Num()); + for (int j = 0; j < m_PopAreas[i].AIContents.Num(); j++) + { + m_PopAreas[i].AIContents[j].Save(savefile); + } + + savefile->WriteInt(m_PopAreas[i].VisitedPorts.Num()); + for (int j = 0; j < m_PopAreas[i].VisitedPorts.Num(); j++) + { + savefile->WriteInt(m_PopAreas[i].VisitedPorts[j]); + } + } + + for (int i = 0; i < m_numAreas; i++) + { + savefile->WriteBool(m_EventAreas[i].bVisited); + + for (int portal = 0; portal < m_sndAreas[i].numPortals; portal++) + { + savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Loss); + savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Dist); + savefile->WriteFloat(m_EventAreas[i].PortalDat[portal].Att); + savefile->WriteInt(m_EventAreas[i].PortalDat[portal].Floods); + + // Don't save ThisPort, it's just pointing at m_sndAreas + + // greebo: TODO: How to save PrevPort? + } + } +} + +void CsndProp::Restore(idRestoreGame *savefile) +{ + int num; + + // Pass the call to the base class first + CsndPropBase::Restore(savefile); + + savefile->ReadInt(m_TimeStampProp); + savefile->ReadInt(m_TimeStampPortLoss); + + m_PopAreasInd.Clear(); + savefile->ReadInt(num); + m_PopAreasInd.SetNum(num); + for (int i = 0; i < num; i++) + { + savefile->ReadInt(m_PopAreasInd[i]); + } + + m_PopAreas = new SPopArea[m_numAreas]; + for (int i = 0; i < m_numAreas; i++) + { + savefile->ReadInt(m_PopAreas[i].addedTime); + savefile->ReadBool(m_PopAreas[i].bVisited); + + savefile->ReadInt(num); + m_PopAreas[i].AIContents.Clear(); + for (int j = 0; j < num; j++) + { + idEntityPtr ai; + ai.Restore(savefile); + m_PopAreas[i].AIContents.Append(ai); + } + + savefile->ReadInt(num); + m_PopAreas[i].VisitedPorts.Clear(); + m_PopAreas[i].VisitedPorts.SetNum(num); + for (int j = 0; j < num; j++) + { + savefile->ReadInt(m_PopAreas[i].VisitedPorts[j]); + } + } + + m_EventAreas = new SEventArea[m_numAreas]; + for (int i = 0; i < m_numAreas; i++) + { + savefile->ReadBool(m_EventAreas[i].bVisited); + + m_EventAreas[i].PortalDat = new SPortEvent[m_sndAreas[i].numPortals]; + + for (int portal = 0; portal < m_sndAreas[i].numPortals; portal++) + { + savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Loss); + savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Dist); + savefile->ReadFloat(m_EventAreas[i].PortalDat[portal].Att); + savefile->ReadInt(m_EventAreas[i].PortalDat[portal].Floods); + + // Restore the ThisPort pointer, it's just pointing at m_sndAreas + m_EventAreas[i].PortalDat[portal].ThisPort = &m_sndAreas[i].portals[portal]; + + // greebo: TODO: How to restore PrevPort? + } + } +} + +void CsndProp::SetupFromLoader( const CsndPropLoader *in ) +{ + SAreaProp defaultArea; + int tempint(0); + int numPorts; + SEventArea *pEvArea; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting up soundprop gameplay object\r"); + + Clear(); + + m_SndGlobals = in->m_SndGlobals; + + if( !in->m_bLoadSuccess ) + { + // setup the default sound prop object for failed loads + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SndPropLoader failed to load from the .spr file.\r"); + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SndProp is using default (simple, single area) setup\r"); + + //TODO: Uncomment these when soundprop from file is fully implemented + //gameLocal.Warning("[DM SPR] SndPropLoader failed to load from the .spr file."); + //gameLocal.Warning("[DM SPR] "SndProp is the using default (simple, single area) setup."); + + //TODO : Need better default behavior for bad file, this isn't going to work + defaultArea.area = 0; + defaultArea.LossMult = 1.0 * m_SndGlobals.kappa0; + defaultArea.VolMod = 0.0; + defaultArea.DataEntered = false; + + m_AreaPropsG.Append( defaultArea ); + m_AreaPropsG.Condense(); + + goto Quit; + } + + m_bLoadSuccess = true; + + m_numAreas = in->m_numAreas; + m_numPortals = in->m_numPortals; + + // copy the connectivity database from sndPropLoader + if( (m_sndAreas = new SsndArea[m_numAreas]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when copying area connectivity database to gameplay object\r"); + goto Quit; + } + + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Attempting to copy m_PortData with %d portals\r", m_numPortals); + // copy the handle-indexed portal data from sndPropLoader + if( (m_PortData = new SPortData[m_numPortals]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when copying portal data array to gameplay object\r"); + goto Quit; + } + + // copy the areas array, element by element + for( int i=0; i < m_numAreas; i++ ) + { + m_sndAreas[i].LossMult = in->m_sndAreas[i].LossMult; + m_sndAreas[i].VolMod = in->m_sndAreas[i].VolMod; + + tempint = in->m_sndAreas[i].numPortals; + m_sndAreas[i].numPortals = tempint; + + m_sndAreas[i].center = in->m_sndAreas[i].center; + + m_sndAreas[i].portals = new SsndPortal[ tempint ]; + for( int k=0; k < tempint; k++ ) + m_sndAreas[i].portals[k] = in->m_sndAreas[i].portals[k]; + + m_sndAreas[i].portalDists = new CMatRUT; + + // Copy the values + if (in->m_sndAreas[i].portalDists->size() > 0) + { + *m_sndAreas[i].portalDists = *(in->m_sndAreas[i].portalDists); + } + else + { + m_sndAreas[i].portalDists->Clear(); + } + } + + + // copy the portal data array, element by element + for( int k=0; k < m_numPortals; k++ ) + { + m_PortData[k].loss = in->m_PortData[k].loss; + + m_PortData[k].Areas[0] = in->m_PortData[k].Areas[0]; + m_PortData[k].Areas[1] = in->m_PortData[k].Areas[1]; + m_PortData[k].LocalIndex[0] = in->m_PortData[k].LocalIndex[0]; + m_PortData[k].LocalIndex[1] = in->m_PortData[k].LocalIndex[1]; + } + + m_bDefaultSpherical = in->m_bDefaultSpherical; + m_AreaPropsG = in->m_AreaPropsG; + + // initialize Event Areas + if( (m_EventAreas = new SEventArea[m_numAreas]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing m_EventAreas\r"); + goto Quit; + } + + // initialize Populated Areas + if( (m_PopAreas = new SPopArea[m_numAreas]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing m_PopAreas\r"); + goto Quit; + } + + // Initialize the timestamp in Populated Areas + + for ( int k=0; kbVisited = false; + + numPorts = m_sndAreas[j].numPortals; + + if( (pEvArea->PortalDat = new SPortEvent[ numPorts ]) + == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing portal data array for area %d in m_EventAreas\r", j); + goto Quit; + } + + // point the event portals to the m_sndAreas portals + for( int l=0; lPortalDat[l]; + pEvPtr->ThisPort = &m_sndAreas[j].portals[l]; + } + } + +Quit: + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Soundprop gameplay object finished loading\r"); + return; +} + +// NOTE: Propagate does not call CheckSound. CheckSound should be called before +// calling Propagate, in order to make sure the sound exists somewhere. + +void CsndProp::Propagate + ( float volMod, float durMod, const idStr& sndName, + idVec3 origin, idEntity *maker, + USprFlags *addFlags ) + +{ + bool bValidTeam(false), + bExpandFinished(false); + int mteam; + float range; + + UTeamMask tmask, compMask; + + idBounds envBounds(origin); + idAI *testAI; + idList validTypeEnts, validEnts; + SPopArea *pPopArea; + + idTimer timer_Prop; + timer_Prop.Clear(); + timer_Prop.Start(); + + m_TimeStampProp= gameLocal.time; + + if( cv_spr_debug.GetBool() ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PROPAGATING: From entity %s, sound \"%s\", volume modifier %f, duration modifier %f \r", maker->name.c_str(), sndName.c_str(), volMod, durMod ); + gameLocal.Printf("PROPAGATING: From entity %s, sound \"%s\", volume modifier %f, duration modifier %f \n", maker->name.c_str(), sndName.c_str(), volMod, durMod ); + } + + // clear the old populated areas list + m_PopAreasInd.Clear(); + + // grayman #2907 - Initialize the timestamp in Populated Areas. This + // becomes important if more than one sound propagates in the same frame. + + for ( int k = 0 ; k < m_numAreas ; k++ ) + { + m_PopAreas[k].addedTime = 0; + } + + // initialize the comparison team mask + compMask.m_field = 0; + + // find the dict def for the specific sound + const idDict* parms = gameLocal.FindEntityDefDict( va("sprGS_%s", sndName.c_str() ), false ); + + // redundancy, this is already checked in CheckSound() + if (!parms) return; + + float vol0 = parms->GetFloat("vol","0") + volMod; + + // add the area-specific volMod, if we're in an area + int areaNum = gameRenderWorld->PointInArea(origin); + vol0 += (areaNum >= 0) ? m_AreaPropsG[areaNum].VolMod : 0; + + // scale the volume by some amount that is a cvar for now for tweaking + // later we will put a permananet value in the def for globals->Vol + vol0 += cv_ai_sndvol.GetFloat(); + + if (cv_moveable_collision.GetBool() && maker->IsType(idMoveable::Type)) + { + gameRenderWorld->DrawText( va("PropVol: %f", vol0), maker->GetPhysics()->GetOrigin(), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); + } + + SSprParms propParms; + propParms.name = sndName; + propParms.alertFactor = parms->GetFloat("alert_factor","1"); + propParms.alertMax = parms->GetFloat("alert_max","30"); + + // set team alert and propagation flags from the parms + SetupParms( parms, &propParms, addFlags, &tmask ); + + propParms.duration *= durMod; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found modified duration %f\r", propParms.duration); + propParms.maker = maker; + propParms.makerAI = (maker->IsType(idAI::Type)) ? static_cast(maker) : NULL; + propParms.origin = origin; + + // For objects (non-actors) the team will be set to -1 + mteam = (maker->IsType(idActor::Type)) ? static_cast(maker)->team : -1; + + // Calculate the range, assuming peceived loudness of a sound doubles every 7 dB + // (we want to overestimate a bit. With the current settings, cutoff for a footstep + // at 50dB is ~15 meters ( ~45 ft ) + + // keep in mind that due to FOV compression, visual distances in FPS look shorter + // than they actually are. + + range = pow(2.0f, ((vol0 - m_SndGlobals.MaxRangeCalVol) / 7.0f) ) * m_SndGlobals.MaxRange * s_METERS_TO_DOOM; + + if( cv_spr_debug.GetBool() ) + gameLocal.Printf("Propagation volume: %0.02f Range: %0.02f units (%0.02f m)\n", vol0, range, range / s_METERS_TO_DOOM); + + // Debug drawing of the range + if (cv_spr_radius_show.GetBool()) + { + gameRenderWorld->DebugCircle(colorWhite, origin, idVec3(0,0,1), range, 100, 1000); + } + + idBounds bounds(origin); + bounds.ExpandSelf(range); + + // get a list of all ents with type idAI's or Listeners + + for (idAI* ai = gameLocal.spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) + { + // TODO: Put in Listeners later + validTypeEnts.Append(ai); + } + + if( cv_spr_debug.GetBool() ) + { + gameLocal.Printf("Found %d ents with valid type for propagation\n", validTypeEnts.Num() ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found %d ents with valid type for propagation\r", validTypeEnts.Num() ); + } + + timer_Prop.Stop(); + DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished finding all AI entities, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); + timer_Prop.Start(); + // cull the list by testing distance and valid team flag + + for ( int i=0; i( validTypeEnts[i] ); + + // do not propagate to dead or unconscious AI + if( testAI->health <= 0 || testAI->IsKnockedOut() ) + continue; + + if( !bounds.ContainsPoint( testAI->GetEyePosition() ) ) + { + if( cv_spr_debug.GetBool() ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s is not within propagation cutoff range %f\r", testAI->name.c_str(), range ); + gameLocal.Printf("AI %s is not within propagation cutoff range %0.2f\n", testAI->name.c_str(), range ); + } + continue; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s is within propagation cutoff range %f\r", testAI->name.c_str(), range ); + + if( mteam == -1 ) + { + // for now, inanimate objects alert everyone + bValidTeam = true; + if( cv_spr_debug.GetBool() ) + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound was propagated from inanimate object: Alerts all teams\r" ); + } + else + { + compMask.m_bits.same = ( testAI->team == mteam ); + compMask.m_bits.friendly = testAI->IsFriend(maker); + compMask.m_bits.neutral = testAI->IsNeutral(maker); + compMask.m_bits.enemy = testAI->IsEnemy(maker); + + // do the comparison + if ( tmask.m_field & compMask.m_field ) + { + bValidTeam = true; + if( cv_spr_debug.GetBool() ) + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s has a valid team for soundprop\r", testAI->name.c_str() ); + } + } + + // TODO : Add another else if for the case of Listeners + + // don't alert the AI that caused the sound + if( bValidTeam && testAI != maker ) + { + if( cv_spr_debug.GetBool() ) + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found a valid propagation target: %s\r", testAI->name.c_str() ); + validEnts.Append( validTypeEnts[i] ); + continue; + } + if( cv_spr_debug.GetBool() ) + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI %s does not have a valid team for propagation\r", testAI->name.c_str() ); + + } + + timer_Prop.Stop(); + DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished culling AI list, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); + timer_Prop.Start(); + + /* handle environmental sounds here + + envBounds = bounds; + envBounds.Expand( s_MAX_ENV_SNDRANGE * s_METERS_TO_DOOM); + + envBounds -= bounds; + + numEnt = gameLocal.clip.EntitiesTouchingBounds( envBounds, -1, inrangeEnts2, MAX_ENTS ); + + for( int j =0; j < numEnt; j++) + { + // if the entities are in the env. sound hash + // add them to the list of env. sounds to check for this propagation + } + */ + + // Don't bother propagation if no one is in range + if (validEnts.Num() == 0) return; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Beginning propagation to %d targets\r", validEnts.Num() ); + + + // ======================== BEGIN WAVEFRONT EXPANSION =================== + + // Populate the AI lists in the m_PopAreas array, use timestamp method to check if it's the first visit + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Filling populated areas array with AI\r" ); + for(int j = 0; j < validEnts.Num(); j++) + { + int AIAreaNum = gameRenderWorld->PointInArea( validEnts[j]->GetPhysics()->GetOrigin() ); + + //Sometimes PointInArea returns -1, don't know why + if (AIAreaNum < 0) + continue; + + pPopArea = &m_PopAreas[AIAreaNum]; + + if( pPopArea == NULL ) + continue; + + //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("TimeStamp Debug: Area timestamp %d, new timestamp %d \r", pPopArea->addedTime, m_TimeStampProp); + + // check if this is the first update to the pop. area in this propagation + if( pPopArea->addedTime != m_TimeStampProp ) + { + //update the timestamp + pPopArea->addedTime = m_TimeStampProp; + + pPopArea->bVisited = false; + pPopArea->AIContents.Clear(); + pPopArea->VisitedPorts.Clear(); + + // add the first AI to the contents list + idEntityPtr ai; + ai = static_cast(validEnts[j]); + pPopArea->AIContents.Append(ai); + + // append the index of this area to the popAreasInd list for later processing + m_PopAreasInd.Append( AIAreaNum ); + } + else + { + // This area has already been updated in this propagation, just add the next AI + idEntityPtr ai; + ai = static_cast(validEnts[j]); + pPopArea->AIContents.Append(ai); + } + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processed AI %s in area %d\r", validEnts[j]->name.c_str(), AIAreaNum ); + } + + timer_Prop.Stop(); + DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: Finished filling populated areas, comptime=%lf [ms]\r", timer_Prop.Milliseconds() ); + timer_Prop.Start(); + + bExpandFinished = ExpandWave( vol0, origin ); + + //TODO: If bExpandFinished == false, either fake propagation or + // delay further expansion until later frame + if(bExpandFinished == false) + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion was stopped when max node number %d was exceeded, or propagation was aborted\r", s_MAX_FLOODNODES ); + + timer_Prop.Stop(); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion done, processing AI\r" ); + DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Timer: COMPTIME=%lf [ms]\r", timer_Prop.Milliseconds() ); + timer_Prop.Start(); + + ProcessPopulated( vol0, origin, &propParms ); + + timer_Prop.Stop(); + DM_LOG(LC_SOUND, LT_INFO)LOGSTRING("Total TIME for propagation: %lf [ms]\r", timer_Prop.Milliseconds() ); +} + +void CsndProp::SetupParms( const idDict *parms, SSprParms *propParms, USprFlags *addFlags, UTeamMask *tmask ) +{ + USprFlags tempflags; + + tempflags.m_field = 0; + tmask->m_field = 0; + + DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Parsing team alert and propagation flags from propagated_sounds.def\r"); + + // note: by default, if the key is not found, GetBool returns false + tempflags.m_bits.same = parms->GetBool("prop_to_same"); + tempflags.m_bits.friendly = parms->GetBool("prop_to_friend"); + tempflags.m_bits.neutral = parms->GetBool("prop_to_neutral"); + tempflags.m_bits.enemy = parms->GetBool("prop_to_enemy", "1"); + + tempflags.m_bits.omni_dir = parms->GetBool("omnidir"); + tempflags.m_bits.unique_loc = parms->GetBool("unique_loc"); + tempflags.m_bits.urgent = parms->GetBool("urgent"); + tempflags.m_bits.global_vol = parms->GetBool("global_vol"); + tempflags.m_bits.check_touched = parms->GetBool("check_touched"); + + if( addFlags ) + { + tempflags.m_field = tempflags.m_field | addFlags->m_field; + if( cv_spr_debug.GetBool() ) + DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Added additional sound propagation flags from local sound \r"); + } + + // set the team mask from the sprflags + tmask->m_bits.same = tempflags.m_bits.same; + tmask->m_bits.friendly = tempflags.m_bits.friendly; + tmask->m_bits.neutral = tempflags.m_bits.neutral; + tmask->m_bits.enemy = tempflags.m_bits.enemy; + + // copy flags to parms + propParms->flags = tempflags; + + // setup other parms + propParms->duration = parms->GetFloat("dur","200"); + propParms->frequency = parms->GetInt("freq","-1"); + propParms->bandwidth = parms->GetFloat("width", "-1"); + + if( cv_spr_debug.GetBool() ) + { + DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Finished transfering sound prop parms\r"); + } +} + +bool CsndProp::CheckSound( const char *sndNameGlobal, bool isEnv ) +{ + const idDict *parms; + bool returnval; + + if (isEnv) + parms = gameLocal.FindEntityDefDict( va("sprGE_%s", sndNameGlobal ), false ); + else + parms = gameLocal.FindEntityDefDict( va("sprGS_%s", sndNameGlobal ), false ); + + if ( !parms ) + { + // Don't log this, because it happens all the time. Most sounds played with idEntity::StartSound are not propagated. + //if( cv_spr_debug.GetBool() ) + //gameLocal.Warning("[Soundprop] Could not find sound def for sound \"%s\" Sound not propagated.", sndNameGlobal ); + //DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Could not find sound def for sound \"%s\" Sound not propagated.\r", sndNameGlobal ); + returnval = false; + goto Quit; + } + + else + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found propagated sound \"%s\" in the def.\r", sndNameGlobal ); + returnval = true; + } + +Quit: + return returnval; +} + +bool CsndProp::ExpandWave(float volInit, idVec3 origin) +{ + bool returnval; + int //popIndex(-1), + floods(1), nodes(0), area, LocalPort; + float tempDist(0), tempAtt(1), tempLoss(0), AddedDist(0); + idList NextAreas; // expansion queue + idList AddedAreas; // temp storage for next expansion queue + SExpQue tempQEntry; + SPortEvent *pPortEv; // pointer to portal event data + SPopArea *pPopArea; // pointer to populated area data + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting wavefront expansion\r" ); + + // clear the visited settings on m_EventAreas from previous propagations + for(int i=0; i < m_numAreas; i++) + m_EventAreas[i].bVisited = false; + + NextAreas.Clear(); + AddedAreas.Clear(); + + + // ======================== Handle the initial area ========================= + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing initial area\r" ); + + int initArea = gameRenderWorld->PointInArea( origin ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound origin is in portal area: %d\r", initArea ); + if( initArea == -1 ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound origin is outside the map, aborting propagation.\r" ); + return false; + } + + m_EventAreas[ initArea ].bVisited = true; + + // Update m_PopAreas to show that the area has been visited + m_PopAreas[ initArea ].bVisited = true; + + // array index pointers to save on calculation + SsndArea *pSndAreas = &m_sndAreas[ initArea ]; + SEventArea *pEventAreas = &m_EventAreas[ initArea ]; + + // calculate initial portal losses from the sound origin point + for( int i2=0; i2 < pSndAreas->numPortals; i2++) + { + idVec3 portalCoord = pSndAreas->portals[i2].center; + tempDist = (origin - portalCoord).LengthFast() * s_DOOM_TO_METERS; + + // calculate and set initial portal losses + tempAtt = m_AreaPropsG[ initArea ].LossMult * tempDist; + + // add the door loss + tempAtt += m_PortData[ pSndAreas->portals[i2].handle - 1 ].loss; + + // get the current loss + tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; + + pPortEv = &pEventAreas->PortalDat[i2]; + + pPortEv->Loss = tempLoss; + pPortEv->Dist = tempDist; + pPortEv->Att = tempAtt; + pPortEv->Floods = 1; + pPortEv->PrevPort = NULL; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Loss at portal %d is %f [dB]\r", i2, tempLoss); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist at portal %d is %f [m]\r", i2, tempDist); + + + // add the portal destination to flooding queue if the sound has + // not dropped below threshold at the portal + if( (volInit - tempLoss) > s_MIN_AUD_THRESH ) + { + tempQEntry.area = pSndAreas->portals[i2].to; + tempQEntry.curDist = tempDist; + tempQEntry.curAtt = tempAtt; + tempQEntry.curLoss = tempLoss; + tempQEntry.portalH = pSndAreas->portals[i2].handle; + tempQEntry.PrevPort = NULL; + + NextAreas.Append( tempQEntry ); + } + else + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Wavefront intensity dropped below threshold at portal %d\r", i2); + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting main loop\r" ); + + +// done with initial area, begin main loop + + while( NextAreas.Num() > 0 && nodes < s_MAX_FLOODNODES ) + { + floods++; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion loop, iteration %d\r", floods); + + AddedAreas.Clear(); + + for(int j=0; j < NextAreas.Num(); j++) + { + nodes++; + + area = NextAreas[j].area; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Flooding area %d thru portal handle %d\r", area, NextAreas[j].portalH); + + // array index pointers to save on calculation + pSndAreas = &m_sndAreas[ area ]; + pEventAreas = &m_EventAreas[ area ]; + pPopArea = &m_PopAreas[area]; + + // find the local portal number in area for the portal handle + int portHandle = NextAreas[j].portalH; + + SPortData *pPortData = &m_PortData[ portHandle - 1 ]; + if( pPortData->Areas[0] == area ) + LocalPort = pPortData->LocalIndex[0]; + else + LocalPort = pPortData->LocalIndex[1]; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Identified local portal index %d\r", LocalPort ); + + pPortEv = &pEventAreas->PortalDat[ LocalPort ]; + + // copy information from the portal's other side + pPortEv->Dist = NextAreas[j].curDist; + pPortEv->Att = NextAreas[j].curAtt; + pPortEv->Loss = NextAreas[j].curLoss; + pPortEv->Floods = floods - 1; + pPortEv->PrevPort = NextAreas[j].PrevPort; + + + // Updated the Populated Areas to show that it's been visited + // Only do this for populated areas that matter (ie, they've been updated + // on this propagation + + if ( pPopArea->addedTime == m_TimeStampProp ) + { + pPopArea->bVisited = true; + // note the portal flooded in on for later processing + pPopArea->VisitedPorts.AddUnique( LocalPort ); + } + + // Flood to portals in this area + for( int i=0; i < pSndAreas->numPortals; i++) + { + // do not flood back thru same portal we came in + if( LocalPort == i) + continue; + + // set up the portal event pointer + pPortEv = &pEventAreas->PortalDat[i]; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d to portal %d in area %d\r", LocalPort, i, area); + + // Obtain loss at this portal and store in temp var + tempDist = NextAreas[j].curDist; + AddedDist = pSndAreas->portalDists->GetRev( LocalPort, i ); + tempDist += AddedDist; + + tempAtt = NextAreas[j].curAtt; + tempAtt += AddedDist * m_AreaPropsG[ area ].LossMult; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Total distance now %f\r", tempDist ); + + // add any specific loss on the portal + tempAtt += m_PortData[ pSndAreas->portals[i].handle - 1 ].loss; + + tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; + + // check if we've visited the area, and do not add destination area + // if loss is greater this time + if( pEventAreas->bVisited + && tempLoss >= pPortEv->Loss ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Cancelling flood thru portal %d in previously visited area %d\r", i, area); + continue; + } + + if( ( volInit - tempLoss ) < s_MIN_AUD_THRESH ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Wavefront intensity dropped below abs min audibility at portal %d in area %d\r", i, area); + continue; + } + + // path has been determined to be minimal loss, above cutoff intensity + // store the loss value + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Further expansion valid thru portal %d in area %d\r", i, area); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Set loss at portal %d to %f [dB]\r", i, tempLoss); + + pPortEv->Loss = tempLoss; + pPortEv->Dist = tempDist; + pPortEv->Att = tempAtt; + pPortEv->Floods = floods; + pPortEv->PrevPort = &pEventAreas->PortalDat[ LocalPort ]; + + // add the portal destination to flooding queue + tempQEntry.area = pSndAreas->portals[i].to; + tempQEntry.curDist = tempDist; + tempQEntry.curAtt = tempAtt; + tempQEntry.curLoss = tempLoss; + tempQEntry.portalH = pSndAreas->portals[i].handle; + tempQEntry.PrevPort = pPortEv->PrevPort; + + AddedAreas.Append( tempQEntry ); + + } // end portal flood loop + + m_EventAreas[area].bVisited = true; + } // end area flood loop + + // create the next expansion queue + NextAreas = AddedAreas; + + } // end main loop + + // return true if the expansion died out naturally rather than being stopped + returnval = ( !NextAreas.Num() ); + + return returnval; +} // end function + +void CsndProp::ProcessPopulated( float volInit, idVec3 origin, SSprParms *propParms ) +{ + float LeastLoss, TestLoss, tempDist, tempAtt, tempLoss; + int LoudPort(0), portNum; + idVec3 testLoc; + SPortEvent *pPortEv; + SPopArea *pPopArea; + idList showPoints; + + int initArea = gameRenderWorld->PointInArea( origin ); + + for( int i=0; i < m_PopAreasInd.Num(); i++ ) + { + int area = m_PopAreasInd[i]; + + pPopArea = &m_PopAreas[area]; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing pop. area %d\r", area); + + // Special case: AI area = initial area - no portal flooded in on in this case + if( area == initArea ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Special case: AI in initial area %d\r", area); + + propParms->bSameArea = true; + propParms->direction = origin; + + for(int j=0; j < pPopArea->AIContents.Num(); j++) + { + idAI* ai = pPopArea->AIContents[j].GetEntity(); + + if (ai == NULL) + continue; + + tempDist = (origin - ai->GetEyePosition()).LengthFast() * s_DOOM_TO_METERS; + tempAtt = tempDist * m_AreaPropsG[ area ].LossMult; + tempLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; + + propParms->propVol = volInit - tempLoss; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in (source area) area %d\r", ai->name.c_str(), area); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist to AI: %f [m], Propagated volume found to be %f [dB]\r", tempDist, propParms->propVol); + + ProcessAI( ai, origin, propParms ); + + // draw debug lines if show soundprop cvar is set + if( cv_spr_show.GetBool() ) + { + showPoints.Clear(); + showPoints.Append( ai->GetEyePosition() ); + showPoints.Append( propParms->origin ); + DrawLines(showPoints); + } + } + } + // Normal propagation to a surrounding area + else if ( pPopArea->bVisited == true ) + { + propParms->bSameArea = false; + + // figure out the least loss portal + // May be different for each AI (esp. in large rooms) + // TODO OPTIMIZATION: Don't do this extra loop for each AI if + // we only visited one portal in the area + + for( int aiNum = 0; aiNum < pPopArea->AIContents.Num(); aiNum++ ) + { + idAI* ai = pPopArea->AIContents[ aiNum ].GetEntity(); + + if (ai == NULL) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("NULL AI pointer for AI %d in area %d\r", aiNum, area); + continue; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating least loss for AI %s in area %d\r", ai->name.c_str(), area); + + LeastLoss = idMath::INFINITY; + + for(int k=0; k < pPopArea->VisitedPorts.Num(); k++ ) + { + portNum = pPopArea->VisitedPorts[ k ]; + pPortEv = &m_EventAreas[area].PortalDat[ portNum ]; + + //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d, DEBUG k=%d, portsnum = %d\r", portNum, k, m_PopAreas[i].VisitedPorts.Num()); + + testLoc = m_sndAreas[area].portals[portNum].center; + + tempDist = (testLoc - ai->GetEyePosition()).LengthFast() * s_DOOM_TO_METERS; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Distance to AI = %f [m]\r", tempDist); + + tempAtt = tempDist * m_AreaPropsG[ area ].LossMult; + tempDist += pPortEv->Dist; + tempAtt += pPortEv->Att; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Portal %d has total Dist = %f [m]\r", portNum, tempDist); + + // add loss from portal to AI to total loss at portal + TestLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(tempDist) + tempAtt + 8; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("AI Calc: Portal %d has total Loss = %f [dB]\r", portNum, TestLoss); + + if( TestLoss < LeastLoss ) + { + LeastLoss = TestLoss; + LoudPort = portNum; + } + } + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Portal %d has least loss %f [dB]\r", LoudPort, LeastLoss ); + + pPortEv = &m_EventAreas[area].PortalDat[ LoudPort ]; + propParms->floods = pPortEv->Floods; + + // Detailed Path Minimization: + + // check if AI is within the flood range for detailed path minimization + if( pPortEv->Floods <= s_MAX_DETAILNODES ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting detailed path minimization for portal %d\r", LoudPort ); + propParms->bDetailedPath = true; + + // call detailed path minimization, which writes results to propParms + DetailedMin( ai, propParms, pPortEv, area, volInit ); + + // message the AI + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated volume found to be %f\r", propParms->propVol); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in area %d\r", ai->name.c_str(), area); + + ProcessAI( ai, origin, propParms ); + + continue; + } + + propParms->bDetailedPath = false; + propParms->direction = m_sndAreas[area].portals[ LoudPort ].center; + propParms->propVol = volInit - LeastLoss; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated volume found to be %f\r", propParms->propVol); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Messaging AI %s in area %d\r", ai->name.c_str(), area); + ProcessAI( ai, origin, propParms ); + } + } + // Propagation was stopped before this area was reached + else if ( pPopArea->bVisited == false ) + { + // Do nothing for now + // TODO: Keep track of these areas for delayed calculation? + } + } + + // greebo: We're done propagating, clear the message list of the issuing AI, if appropriate + if (propParms->makerAI != NULL) + { + propParms->makerAI->ClearMessages(); + } +} + +void CsndProp::ProcessAI(idAI* ai, idVec3 origin, SSprParms *propParms) +{ + if( ai == NULL ) return; + + // check AI hearing, get environmental noise, etc + if( cv_spr_debug.GetBool() ) + { + gameLocal.Printf("Propagated sound %s to AI %s, from origin %s : Propagated volume %f, Apparent origin of sound: %s \r", + propParms->name.c_str(), ai->name.c_str(), origin.ToString(), propParms->propVol, propParms->direction.ToString() ); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Propagated sound %s to AI %s, from origin %s : Propagated volume %f, Apparent origin of sound: %s \r", + propParms->name.c_str(), ai->name.c_str(), origin.ToString(), propParms->propVol, propParms->direction.ToString() ); + } + + if( cv_spr_show.GetBool() ) + { + gameRenderWorld->DrawText( va("Volume: %.2f", propParms->propVol), + (ai->GetEyePosition() - ai->GetPhysics()->GetGravityNormal() * 65.0f), 0.25f, + colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec * 30); + } + + // convert the SPL to loudness and store it in parms + ai->SPLtoLoudness( propParms ); + + if (ai->CheckHearing(propParms)) + { + // TODO: Add env. sound masking check here + // GetEnvNoise should check all the env. noises on the list we made, plus global ones + + // noiseVol = GetEnvNoise( &propParms, origin, AI->GetEyePosition() ); + float noise = 0; + + //message the AI + ai->HearSound( propParms, noise, origin ); + } +} + +/** +* CsndProp::OptSurfPoint +* PSUEDOCODE +* +* 1. Define the surface coordinates by taking vectors to two consecutive +* points in the winding. +* +* 2. Obtain intersection point with winding plane. +* 2.A Test if this point is within the rectangle. If so, we're done. (goto Quit) +* +* 3. Obtain a1 and a2, the coordinates when line is resolved onto the axes +* +* 4. Test sign of a1 and a2 to determine which edge they should intersect +* write the lower numbered point of the intersection edge to edgeNum +* +* +* 5. Find the point along the edge closest to point A +* -Find line that goes thru point isect, and is also perpendicular to the edge +* +* 6. Return this point in world coordinates, we're done. +**/ +idVec3 CsndProp::OptSurfPoint( idVec3 p1, idVec3 p2, const idWinding& wind, idVec3 WCenter ) +{ + idVec3 line, u1, u2, v1, v2, edge, isect, lineSect; + idVec3 returnVec, tempVec, pointA; + idPlane WPlane; + float lenV1, lenV2, lineU1, lineU2, Scale(0), frac; + int edgeStart(0), edgeStop(0); + + // If the winding is not a rectangle, just return the center coordinate + if( wind.GetNumPoints() != 4 ) + { + returnVec = WCenter; + goto Quit; + } + + // Want to find a point on the portal rectangle closest to this line: + line = p2 - p1; + + // define the portal coordinates and extent of the two corners + u1 = (wind[0].ToVec3() - WCenter); + u2 = (wind[1].ToVec3() - WCenter); + u1.NormalizeFast(); + u2.NormalizeFast(); + + // define other coordinates going to midpoint between two points (useful to see if point is on portal) + v1 = (wind[1].ToVec3() + wind[0].ToVec3()) / 2 - WCenter; + v2 = (wind[2].ToVec3() + wind[1].ToVec3()) / 2 - WCenter; + lenV1 = v1.LengthFast(); + lenV2 = v2.LengthFast(); + + wind.GetPlane(WPlane); + + tempVec = p2-p1; + tempVec.NormalizeFast(); + + // find ray intersection point, in terms of p1 + (p2-p1)*Scale + WPlane.RayIntersection( p1, tempVec, Scale ); + + isect = p1 + Scale * tempVec; + lineSect = isect - WCenter; + + if( cv_spr_show.GetBool() ) + { + gameRenderWorld->DebugLine( colorRed, WCenter, (wind[1].ToVec3() + wind[0].ToVec3()) / 2, 3000); + gameRenderWorld->DebugLine( colorRed, WCenter, (wind[2].ToVec3() + wind[1].ToVec3()) / 2, 3000); + //gameRenderWorld->DebugLine( colorYellow, WCenter, isect, 3000); + } + + // resolve into surface coordinates + lineU1 = lineSect * u1; + lineU2 = lineSect * u2; + + // If point is within the rectangular surface boundaries, we're done + // Use the v axes (going to edge midpoints) to check if point is within rectangle + if( fabs(lineSect * v1/lenV1) <= lenV1 && fabs( lineSect * v2/lenV2) <= lenV2 ) + { +// DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MinSurf: Line itersects inside portal surface\r" ); +// DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("v1/lenV1 = %f, v2/lenV2 = %f\r", fabs(lineSect * v1/lenV1)/lenV1, fabs( lineSect * v2/lenV2)/lenV2 ); + returnVec = isect; + goto Quit; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MinSurf: Line intersected outside of portal\r"); + // find the edge that the line intersects + if( lineU1 >= 0 && lineU2 >= 0 ) + { + edgeStart = 0; + edgeStop = 1; + } + else if( lineU1 <= 0 && lineU2 >= 0 ) + { + edgeStart = 1; + edgeStop = 2; + } + else if( lineU1 <= 0 && lineU2 <= 0 ) + { + edgeStart = 2; + edgeStop = 3; + } + else if( lineU1 >= 0 && lineU2 <= 0 ) + { + edgeStart = 3; + edgeStop = 0; + } + + pointA = wind[edgeStart].ToVec3(); + edge = wind[edgeStop].ToVec3() - pointA; + + // Find the closest point on the edge to the isect point + // This is the point we're looking for + frac = ((isect - pointA) * edge )/ edge.LengthSqr(); + + // check if the point is outside the actual edge, if not, set it to + // the appropriate endpoint. + if( frac < 0 ) + returnVec = pointA; + else if( frac > 1.0 ) + returnVec = pointA + edge; + else + returnVec = pointA + frac * edge; + +Quit: + return returnVec; +} + +void CsndProp::DetailedMin( idAI* AI, SSprParms *propParms, SPortEvent *pPortEv, int AIArea, float volInit ) +{ + idList pathPoints; // pathpoints[0] = closest path point to the TARGET + idList PortPtrs; // pointers to the portals along the path + idVec3 point, p1, p2, AIpos; + int floods, curArea; + float tempAtt, tempDist, totAtt, totDist, totLoss; + SPortEvent *pPortTest; + SsndPortal *pPort2nd; + + floods = pPortEv->Floods; + pPortTest = pPortEv; + + AIpos = AI->GetEyePosition(); + p1 = AIpos; + + + // first iteration, populate pathPoints going "backwards" from target to source + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Performing first iteration for %d floods\r", floods ); + + for( int i = 0; i < floods; i++ ) + { + if( pPortEv->ThisPort == NULL) + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("ERROR: pPortEv->ThisPort is NULL\r" ); + + // calculate optimum point for this leg of the path + point = OptSurfPoint( p1, propParms->origin, *pPortTest->ThisPort->winding, + pPortTest->ThisPort->center ); + + pathPoints.Append(point); + PortPtrs.Append(pPortTest); + + p1 = point; + pPortTest = pPortTest->PrevPort; + } + + // check if we have enough floods to perform the 2nd iteration + if( (floods - 2) < 0 ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Skipping second iteration, not enough portals\r" ); + goto Quit; + } + + // second iteration, going forwards from source to target + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Path min: Performing second iteration\r" ); + + + p1 = propParms->origin; + + for( int k = 0; k < floods; k++ ) + { + // recalculate the N-1th point using the Nth point and N-2th point on either side + pPort2nd = PortPtrs[floods - k - 1]->ThisPort; + if( pPort2nd == NULL) + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("ERROR: pPort2nd is NULL\r" ); + + // the last point tested must be the AI position + if( (floods - k - 2) >= 0 ) + p2 = pathPoints[floods - k - 2]; + else + p2 = AIpos; + + // DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("2nd iter: Finding optimum surface point\r" ); + point = OptSurfPoint( p1, p2, *pPort2nd->winding, pPort2nd->center ); + pathPoints[floods - k -1] = point; + + p1 = point; + } + +Quit: + +// Now go through and calculate the new loss + + // get loss to 1st point on the path + totDist = (AIpos - pathPoints[0]).LengthFast() * s_DOOM_TO_METERS; + curArea = PortPtrs[0]->ThisPort->to; + totAtt = totDist * m_AreaPropsG[ curArea ].LossMult; + + totAtt += PortPtrs[0]->Att; + + // add the rest of the loss from the path points + for( int j = 0; j < (floods - 1); j++ ) + { + tempDist = (pathPoints[j+1] - pathPoints[j]).LengthFast() * s_DOOM_TO_METERS; + curArea = PortPtrs[j]->ThisPort->to; + tempAtt = tempDist * m_AreaPropsG[ curArea ].LossMult; + + totDist += tempDist; + totAtt += tempAtt; + + totAtt += PortPtrs[j + 1]->Att; + } + + // add the loss from the final path point to the source + tempDist = ( pathPoints[floods - 1] - propParms->origin ).LengthFast() * s_DOOM_TO_METERS; + curArea = PortPtrs[ floods - 1 ]->ThisPort->to; + tempAtt = tempDist * m_AreaPropsG[ curArea ].LossMult; + + totDist += tempDist; + totAtt += tempAtt; + + // Finally, convert to acoustic spreading + attenuation loss in dB + totLoss = m_SndGlobals.Falloff_Ind * s_invLog10*idMath::Log16(totDist) + totAtt + 8; + + propParms->direction = pathPoints[0]; + propParms->propVol = volInit - totLoss; + + // draw debug lines if show soundprop cvar is set + if( cv_spr_show.GetBool() ) + { + pathPoints.Insert(AIpos, 0); + pathPoints.Append(propParms->origin); + DrawLines(pathPoints); + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Detailed path minimization for AI %s finished\r", AI->name.c_str() ); + + return; +} + +void CsndProp::DrawLines(idList& pointlist) +{ + for (int i = 0; i < (pointlist.Num() - 1); i++) + { + gameRenderWorld->DebugLine( colorGreen, pointlist[i], pointlist[i+1], 3000); + } +} + +void CsndProp::SetPortalLoss( int handle, float value ) +{ + CsndPropBase::SetPortalLoss( handle, value ); + + // update the portal loss info timestamp + m_TimeStampPortLoss = gameLocal.time; +} + +bool CsndProp::ExpandWaveFast( float volInit, idVec3 origin, float MaxDist, int MaxFloods ) +{ + bool bDistLimit(false); + int //popIndex(-1), + floods(1), nodes(0), area, LocalPort, FloodLimit; + float tempDist(0), tempAtt(1), AddedDist(0); + idList NextAreas; // expansion queue + idList AddedAreas; // temp storage for next expansion queue + SExpQue tempQEntry; + SPortEvent *pPortEv; // pointer to portal event data + SPopArea *pPopArea; // pointer to populated area data + + if( MaxDist != -1 ) + bDistLimit = true; + + if( MaxFloods == -1 ) + FloodLimit = s_MAX_FLOODNODES; + else + FloodLimit = MaxFloods; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting wavefront expansion (fast), DistLimit = %f, NodeLimit = %d\r", MaxDist, FloodLimit ); + + // clear the visited settings on m_EventAreas from previous propagations + for(int i=0; i < m_numAreas; i++) + m_EventAreas[i].bVisited = false; + + NextAreas.Clear(); + AddedAreas.Clear(); + + + // ======================== Handle the initial area ========================= + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Processing initial area\r" ); + + int initArea = gameRenderWorld->PointInArea( origin ); + + m_EventAreas[ initArea ].bVisited = true; + + // Update m_PopAreas to show that the area has been visited + m_PopAreas[ initArea ].bVisited = true; + + // array index pointers to save on calculation + SsndArea *pSndAreas = &m_sndAreas[ initArea ]; + SEventArea *pEventAreas = &m_EventAreas[ initArea ]; + + // calculate initial portal losses from the sound origin point + for( int i2=0; i2 < pSndAreas->numPortals; i2++) + { + idVec3 portalCoord = pSndAreas->portals[i2].center; + + tempDist = (origin - portalCoord).LengthFast() * s_DOOM_TO_METERS; + // calculate and set initial portal losses + tempAtt = m_AreaPropsG[ initArea ].LossMult * tempDist; + + // add the door loss + tempAtt += m_PortData[ pSndAreas->portals[i2].handle - 1 ].loss; + + pPortEv = &pEventAreas->PortalDat[i2]; + + pPortEv->Dist = tempDist; + pPortEv->Att = tempAtt; + pPortEv->Floods = 1; + pPortEv->PrevPort = NULL; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Dist at portal %d is %f [m]\r", i2, tempDist); + + + // add the portal destination to flooding queue if the sound has + // not dropped below threshold at the portal + if( !bDistLimit || tempDist < MaxDist ) + { + tempQEntry.area = pSndAreas->portals[i2].to; + tempQEntry.curDist = tempDist; + tempQEntry.curAtt = tempAtt; + tempQEntry.portalH = pSndAreas->portals[i2].handle; + tempQEntry.PrevPort = NULL; + tempQEntry.curLoss = 0.0f; // greebo: Initialised to 0.0f to fix gcc warning + + NextAreas.Append( tempQEntry ); + } + else + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Distance rose above max distance at portal %d\r", i2); + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Starting main loop\r" ); + + +// done with initial area, begin main loop + + while( NextAreas.Num() > 0 && ( (floods < FloodLimit) ) ) + { + floods++; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Expansion loop, iteration %d\r", floods); + + AddedAreas.Clear(); + + for(int j=0; j < NextAreas.Num(); j++) + { + nodes++; + + area = NextAreas[j].area; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Flooding area %d thru portal handle %d\r", area, NextAreas[j].portalH); + + // array index pointers to save on calculation + pSndAreas = &m_sndAreas[ area ]; + pEventAreas = &m_EventAreas[ area ]; + pPopArea = &m_PopAreas[area]; + + // find the local portal number in area for the portal handle + int portHandle = NextAreas[j].portalH; + + SPortData *pPortData = &m_PortData[ portHandle - 1 ]; + if( pPortData->Areas[0] == area ) + LocalPort = pPortData->LocalIndex[0]; + else + LocalPort = pPortData->LocalIndex[1]; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Identified local portal index %d\r", LocalPort ); + + pPortEv = &pEventAreas->PortalDat[ LocalPort ]; + + // copy information from the portal's other side + pPortEv->Dist = NextAreas[j].curDist; + pPortEv->Att = NextAreas[j].curAtt; + pPortEv->Floods = floods - 1; + pPortEv->PrevPort = NextAreas[j].PrevPort; + + + // Updated the Populated Areas to show that it's been visited + // Only do this for populated areas that matter (ie, they've been updated + // on this propagation + + if ( pPopArea->addedTime == m_TimeStampProp ) + { + pPopArea->bVisited = true; + // note the portal flooded in on for later processing + pPopArea->VisitedPorts.Append( LocalPort ); + } + + // Flood to portals in this area + for( int i=0; i < pSndAreas->numPortals; i++) + { + // do not flood back thru same portal we came in + if( LocalPort == i) + continue; + + // set up the portal event pointer + pPortEv = &pEventAreas->PortalDat[i]; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Calculating loss from portal %d to portal %d in area %d\r", LocalPort, i, area); + + // Obtain loss at this portal and store in temp var + tempDist = NextAreas[j].curDist; + AddedDist = pSndAreas->portalDists->GetRev( LocalPort, i ); + tempDist += AddedDist; + + tempAtt = NextAreas[j].curAtt; + tempAtt += AddedDist * m_AreaPropsG[ area ].LossMult; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Total distance now %f\r", tempDist ); + + // add any specific loss on the portal + tempAtt += m_PortData[ pSndAreas->portals[i].handle - 1 ].loss; + + // check if we've visited the area. Fast prop only visits an area once + if( pEventAreas->bVisited ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Cancelling flood thru portal %d in previously visited area %d\r", i, area); + continue; + } + + if( bDistLimit && tempDist > MaxDist ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Distance rose above max distance at portal %d in area %d\r", i, area); + continue; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Further expansion valid thru portal %d in area %d\r", i, area); + + pPortEv->Dist = tempDist; + pPortEv->Att = tempAtt; + pPortEv->Floods = floods; + pPortEv->PrevPort = &pEventAreas->PortalDat[ LocalPort ]; + + // add the portal destination to flooding queue + tempQEntry.area = pSndAreas->portals[i].to; + tempQEntry.curDist = tempDist; + tempQEntry.curAtt = tempAtt; + tempQEntry.portalH = pSndAreas->portals[i].handle; + tempQEntry.PrevPort = pPortEv->PrevPort; + tempQEntry.curLoss = 0.0f; // greebo: Initialised to 0.0f to fix gcc warning + + AddedAreas.Append( tempQEntry ); + + } // end portal flood loop + + m_EventAreas[area].bVisited = true; + + } // end area flood loop + + // create the next expansion queue + NextAreas = AddedAreas; + + } // end main loop + + // return true if the expansion died out naturally rather than being stopped + return !NextAreas.Num(); +} diff --git a/game/SndProp.h b/game/SndProp.h new file mode 100644 index 000000000..99e7ff977 --- /dev/null +++ b/game/SndProp.h @@ -0,0 +1,296 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/******************************************************************************/ +/* */ +/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ +/* All rights reserved */ +/* */ +/******************************************************************************/ + +/****************************************************************************** +* +* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI +* during gameplay. Friend class to CsndPropLoader. +* +*****************************************************************************/ + +#ifndef SNDPROP_H +#define SNDPROP_H + +#include "SndPropLoader.h" + +/****************************************************************************** +* +* DESCRIPTION: Sound propagation class for propagating suspicious sounds to AI +* during gameplay. Friend class to CsndPropLoader. +* +*****************************************************************************/ + +template +class CMatRUT; + +/** +* Team bitmask definition, for comparing team alert flags +* with team status of an entity +**/ + +typedef struct STeamBits_s +{ + unsigned int friendly : 1; + unsigned int neutral : 1; + unsigned int enemy : 1; + unsigned int same : 1; +} STeamBits; + +typedef union UTeamMask_s +{ + unsigned int m_field; + STeamBits m_bits; +} UTeamMask; + +/** +* Array entry in populated areas array +**/ +typedef struct SPopArea_s +{ + int addedTime; // timestamp at which this entry was added from the AI list + + bool bVisited; // area was visited at least once in wavefront expansion + + idList< idEntityPtr > AIContents; // list of AI that are present in area + + //TODO: Handle Listeners in another list here + + idList VisitedPorts; // portals that the sound flooded in on (reduces comp. time to store this) + +} SPopArea; + +/** +* Portal data stored in an event area +**/ +typedef struct SPortEvent_s +{ + float Loss; // dynamic array to store the current loss at the portal + + float Dist; // distance at portal (used to add AI loss to existing loss) + + float Att; // attenuation at portal (again used for final AI calculation) + + int Floods; // How many floods did it take to get to that particular portal + + SsndPortal *ThisPort; // pointer to the snd portal object for this portal + + SPortEvent_s *PrevPort; // the portal visited immediately before each portal + +} SPortEvent; + +/** +* Array entry in event areas array (storing visited areas information) +**/ +typedef struct SEventArea_s +{ + bool bVisited; // area was visited at least once in wavefront expansion + + SPortEvent *PortalDat; // Array of event data for each portal in the area + +} SEventArea; + +/** +* Expansion queue entry for the wavefront expansion algorithm +**/ +typedef struct SExpQue_s +{ + int area; // area number + + int portalH; // portal handle of the portal flooded in on + + float curDist; // total distance travelled by wave so far + + float curAtt; // total attenuation due to material losses so far + + float curLoss; // total loss so far + + SPortEvent *PrevPort; // previous portal flooded through along path + +} SExpQue; + + + + +class CsndProp : public CsndPropBase { + +public: + CsndProp( void ); + ~CsndProp( void ); + + void Clear( void ); + + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); + + void Propagate( float volMod, float durMod, const idStr& soundName, + idVec3 origin, idEntity *maker, USprFlags *addFlags = NULL ); + + /** + * Get the appropriate vars from the sndPropLoader after + * it has loaded data for the map. + * + * Also looks up door entity pointers for current map and + * puts them into area/portal tree + * + * Also initializes various members + **/ + void SetupFromLoader( const CsndPropLoader *in ); + + /** + * Check if a sound is defined in the soundprop def file + **/ + bool CheckSound( const char *sndNameGlobal, bool isEnv ); + + /** + * Insert the loss argument into the portal data array entry for + * the given portal handle. + * + * This one calls the base class function, plus updates the portal losses timestamp + **/ + void SetPortalLoss( int handle, float value ); + + /** + * Static var for AI checking the default threshold + **/ + static float s_SPROP_DEFAULT_TRESHOLD; + +protected: + + /** + * Wavefront expansion algorithm, starts with volume volInit at point origin + * + * Returns true if the expansion died out naturally rather than being stopped + * by a computation limit. + **/ + bool ExpandWave(float volInit, idVec3 origin); + + /** + * Faster and less accurate wavefront expansion algorithm. + * Only visits areas once. + * + * The wave expands until it reaches the maxDist argument distance or until + * the number of nodes traversed exceeds the MaxNodes argument. Note the float/int + * difference between the last two default-valued arguments. + * + * If MaxDist is set to -1, no distance limit is applied. + * If MaxFloods is set to -1, the global maximum flood limit is used. + **/ + bool ExpandWaveFast( float volInit, idVec3 origin, + float MaxDist = -1, int MaxFloods = -1 ); + + /** + * Process the populated areas after a sound propagation event. + **/ + void ProcessPopulated( float volInit, idVec3 origin, SSprParms *propParms ); + + /** + * Process individual AI. Messages the individual AI, and will later calculate + * the effects of environmental sounds in the signal/noise response of the AI. + * + * Called by ProcessPopulated + **/ + void ProcessAI( idAI* ai, idVec3 origin, SSprParms *propParms ); + + /** + * Copy parms from loader object, and also initialize several member vars + **/ + void SetupParms( const idDict *parms, SSprParms *propParms, + USprFlags *addFlags, UTeamMask *tmask ); + + /** + * Detailed path minimization. Finds the optimum path taking points along the portal surfaces + * Writes the final loss info and apparent location of the sound to propParms. + **/ + void DetailedMin( idAI* AI, SSprParms *propParms, + SPortEvent *pPortEv, int AIArea, float volInit ); + + /** + * Takes point 1, point 2, a winding, and the center point of the winding + * Returns the point on the winding surface that is closest + * to the line p1-p2. + * + * If the line intersects the portal surface, the optimum point will + * be the intersection point. Otherwise, the point will be somewhere + * along the outer boundary of the surface. + * + * Assumes a rectangular portal with 4 winding points. + **/ + idVec3 OptSurfPoint( idVec3 p1, idVec3 p2, const idWinding& wind, idVec3 WCenter ); + + /** + * Draws debug lines between a list of points. Used for soundprop debugging + **/ + void DrawLines(idList& pointlist); + + +protected: + + /** + * Time stamp for the current propagation event [ms] + **/ + int m_TimeStampProp; + + /** + * Time stamp for the last time portal losses were updated + * Used to see if env. sounds need to be repropagated when doors/windows change state + **/ + int m_TimeStampPortLoss; + + /** + * Populated areas : List of indices of AI populated areas for this expansion + **/ + idList m_PopAreasInd; + + /** + * Populated areas array: Lists the AI present in each area + * and which portals the sound flowed in on, for later AI processing. + * + * Stays in memory between events. Each entry has a timestamp, + * and only entries whose indices are in the m_PopAreasInd list are + * checked when processing AI. + **/ + SPopArea *m_PopAreas; + + /** + * Array of areas. Areas that have been visited will have the + * current loss at each portal. Size is the total number of areas + * Entries for areas not visited in this propagation are NULL + * + * For now, this is cleared and re-written for every new sound event + * later on, we might see if we can re-use it for multiple events that + * come from close to the same spot, for optimization. + **/ + SEventArea *m_EventAreas; + +}; + +#endif + + + + + + + diff --git a/game/SndPropLoader.cpp b/game/SndPropLoader.cpp new file mode 100644 index 000000000..5031ae2f4 --- /dev/null +++ b/game/SndPropLoader.cpp @@ -0,0 +1,919 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/******************************************************************************/ +/* */ +/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ +/* All rights reserved */ +/* */ +/******************************************************************************/ + +/****************************************************************************** +* +* DESCRIPTION: Sound propagation class for compiling sound propagation data +* from a Mapfile and write it to a file. Also used to read the file on map init. +* +*****************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Game_local.h" + +static bool init_version = FileVersionList("$Id$", init_version); + +#pragma warning(disable : 4996) + +#include "SndPropLoader.h" +#include "MatrixSq.h" +#include "Misc.h" + +class idLocationEntity; + +// TODO: Write the mapfile timestamp to the .spr file and compare them + +const float s_DOOM_TO_METERS = 0.0254f; // doom to meters +const float s_METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom + + +const float s_DBM_TO_M = 1.0/(10*log10( idMath::E )); // convert between dB/m and 1/m + +void SsndPGlobals::Save(idSaveGame *savefile) const +{ + savefile->WriteString(AreaPropName); + savefile->WriteString(fileExt); + savefile->WriteInt(MaxPaths); + savefile->WriteFloat(DoorExpand); + savefile->WriteFloat(Falloff_Outd); + savefile->WriteFloat(Falloff_Ind); + savefile->WriteFloat(kappa0); + savefile->WriteFloat(DefaultDoorLoss); + savefile->WriteFloat(DefaultThreshold); + savefile->WriteFloat(Vol); + savefile->WriteFloat(MaxRange); + savefile->WriteFloat(MaxRangeCalVol); + savefile->WriteFloat(MaxEnvRange); + savefile->WriteBool(bDebug); +} + +void SsndPGlobals::Restore(idRestoreGame *savefile) +{ + savefile->ReadString(AreaPropName); + savefile->ReadString(fileExt); + savefile->ReadInt(MaxPaths); + savefile->ReadFloat(DoorExpand); + savefile->ReadFloat(Falloff_Outd); + savefile->ReadFloat(Falloff_Ind); + savefile->ReadFloat(kappa0); + savefile->ReadFloat(DefaultDoorLoss); + savefile->ReadFloat(DefaultThreshold); + savefile->ReadFloat(Vol); + savefile->ReadFloat(MaxRange); + savefile->ReadFloat(MaxRangeCalVol); + savefile->ReadFloat(MaxEnvRange); + savefile->ReadBool(bDebug); +} + +/********************************************************* +* +* CsndPropBase Implementation +* +**********************************************************/ + +void CsndPropBase::Save(idSaveGame *savefile) const +{ + m_SndGlobals.Save(savefile); + savefile->WriteBool(m_bLoadSuccess); + savefile->WriteBool(m_bDefaultSpherical); + savefile->WriteInt(m_numAreas); + savefile->WriteInt(m_numPortals); + + for (int area = 0; area < m_numAreas; area++) + { + savefile->WriteFloat(m_sndAreas[area].LossMult); + savefile->WriteFloat(m_sndAreas[area].VolMod); + savefile->WriteInt(m_sndAreas[area].numPortals); + savefile->WriteVec3(m_sndAreas[area].center); + + for (int portal = 0; portal < m_sndAreas[area].numPortals; portal++) + { + SsndPortal_s& soundportal = m_sndAreas[area].portals[portal]; + + savefile->WriteInt(soundportal.handle); + savefile->WriteInt(soundportal.portalNum); + savefile->WriteInt(soundportal.from); + savefile->WriteInt(soundportal.to); + savefile->WriteVec3(soundportal.center); + savefile->WriteVec3(soundportal.normal); + // greebo: Don't save winding pointer, gets restored from idRenderWorld. + } + + m_sndAreas[area].portalDists->Save(savefile); + } + + savefile->WriteInt(m_AreaPropsG.Num()); + for (int i = 0; i < m_AreaPropsG.Num(); i++) + { + savefile->WriteInt(m_AreaPropsG[i].area); + savefile->WriteFloat(m_AreaPropsG[i].LossMult); + savefile->WriteFloat(m_AreaPropsG[i].VolMod); + savefile->WriteBool(m_AreaPropsG[i].DataEntered); + } + + for (int i = 0; i < m_numPortals; i++) + { + savefile->WriteInt(m_PortData[i].LocalIndex[0]); + savefile->WriteInt(m_PortData[i].LocalIndex[1]); + savefile->WriteInt(m_PortData[i].Areas[0]); + savefile->WriteInt(m_PortData[i].Areas[1]); + savefile->WriteFloat(m_PortData[i].loss); + } +} + +void CsndPropBase::Restore(idRestoreGame *savefile) +{ + m_SndGlobals.Restore(savefile); + + savefile->ReadBool(m_bLoadSuccess); + savefile->ReadBool(m_bDefaultSpherical); + savefile->ReadInt(m_numAreas); + savefile->ReadInt(m_numPortals); + + m_sndAreas = new SsndArea[m_numAreas]; + + for (int area = 0; area < m_numAreas; area++) + { + savefile->ReadFloat(m_sndAreas[area].LossMult); + savefile->ReadFloat(m_sndAreas[area].VolMod); + savefile->ReadInt(m_sndAreas[area].numPortals); + savefile->ReadVec3(m_sndAreas[area].center); + + m_sndAreas[area].portals = new SsndPortal[m_sndAreas[area].numPortals]; + + for (int portal = 0; portal < m_sndAreas[area].numPortals; portal++) + { + SsndPortal_s& soundportal = m_sndAreas[area].portals[portal]; + + savefile->ReadInt(soundportal.handle); + savefile->ReadInt(soundportal.portalNum); + savefile->ReadInt(soundportal.from); + savefile->ReadInt(soundportal.to); + savefile->ReadVec3(soundportal.center); + savefile->ReadVec3(soundportal.normal); + + // Restore the winding pointer from idRenderWorld + exitPortal_t p = gameRenderWorld->GetPortal(area, portal); + soundportal.winding = p.w; + } + + // Allocate and resize the triangle matrix + m_sndAreas[area].portalDists = new CMatRUT; + m_sndAreas[area].portalDists->Restore(savefile); + } + + int num; + savefile->ReadInt(num); + m_AreaPropsG.Clear(); + m_AreaPropsG.SetNum(num); + for (int i = 0; i < num; i++) + { + savefile->ReadInt(m_AreaPropsG[i].area); + savefile->ReadFloat(m_AreaPropsG[i].LossMult); + savefile->ReadFloat(m_AreaPropsG[i].VolMod); + savefile->ReadBool(m_AreaPropsG[i].DataEntered); + } + + m_PortData = new SPortData[m_numPortals]; + for (int i = 0; i < m_numPortals; i++) + { + savefile->ReadInt(m_PortData[i].LocalIndex[0]); + savefile->ReadInt(m_PortData[i].LocalIndex[1]); + savefile->ReadInt(m_PortData[i].Areas[0]); + savefile->ReadInt(m_PortData[i].Areas[1]); + savefile->ReadFloat(m_PortData[i].loss); + } +} + +void CsndPropBase::GlobalsFromDef( void ) +{ + const idDict *def; + + def = gameLocal.FindEntityDefDict( "atdm:soundprop_globals", false ); + + if(!def) + { + gameLocal.Warning("[DarkMod Sound Prop] : Did not find def for atdm:soundprop_globals. Bad or missing tdm_soundprop.def file. Using default values."); + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Did not find def for atdm:soundprop_globals. Using default values.\r"); + DefaultGlobals(); + goto Quit; + } + + m_SndGlobals.bDebug = def->GetBool("debug", "0"); + m_SndGlobals.AreaPropName = def->GetString("aprop_name", ""); + m_SndGlobals.fileExt = def->GetString("file_ext", "spr"); + + m_SndGlobals.MaxPaths = def->GetInt("maxpaths", "3"); + m_SndGlobals.DoorExpand = def->GetFloat("doorexpand", "1.0"); + m_SndGlobals.Falloff_Outd = def->GetFloat("falloff_outd", "10.0"); + m_SndGlobals.Falloff_Ind = def->GetFloat("falloff_ind", "9.0"); + m_SndGlobals.kappa0 = def->GetFloat("kappa_dbm", "0.015"); + + m_SndGlobals.DefaultDoorLoss = def->GetFloat("default_doorloss", "20"); + m_SndGlobals.MaxRange = def->GetFloat("maxrange", "2.2"); + m_SndGlobals.MaxRangeCalVol = def->GetFloat("maxrange_cal", "30"); + m_SndGlobals.MaxEnvRange = def->GetFloat("max_envrange", "50"); + + m_SndGlobals.Vol = def->GetFloat("vol_ai", "0.0"); + m_SndGlobals.DefaultThreshold = def->GetFloat("default_thresh", "20.0"); + +Quit: + return; +} + +void CsndPropBase::DefaultGlobals( void ) +{ + m_SndGlobals.bDebug = false; + m_SndGlobals.AreaPropName = ""; + m_SndGlobals.fileExt = "spr"; + + m_SndGlobals.MaxPaths = 3; + m_SndGlobals.DoorExpand = 1.0f; + m_SndGlobals.Falloff_Outd = 10.0f; + m_SndGlobals.Falloff_Ind = 9.0f; + m_SndGlobals.kappa0 = 0.015f; + + m_SndGlobals.DefaultDoorLoss = 20.0f; + m_SndGlobals.MaxRange = 2.2f; + m_SndGlobals.MaxRangeCalVol = 30; + m_SndGlobals.MaxEnvRange = 50; + + m_SndGlobals.Vol = 0.0; + m_SndGlobals.DefaultThreshold = 20.0f; +} + +void CsndPropBase::UpdateGlobals( void ) +{ + // link console vars to globals here +} + + +/********************************************************* +* +* CsndPropLoader Implementation +* +**********************************************************/ + + +CsndPropLoader::CsndPropLoader ( void ) +{ + m_PortData = NULL; + m_sndAreas = NULL; + m_numAreas = 0; + m_numPortals = 0; + m_bDefaultSpherical = false; + m_bLoadSuccess = false; +} + +CsndPropLoader::~CsndPropLoader ( void ) +{ + // Call shutdown in case it was not called before destruction + Shutdown(); +} + +void CsndPropLoader::Save(idSaveGame *savefile) const +{ + // Pass the call to the base class first + CsndPropBase::Save(savefile); + + // TODO +} + +void CsndPropLoader::Restore(idRestoreGame *savefile) +{ + // Pass the call to the base class first + CsndPropBase::Restore(savefile); + + // TODO +} + +/** +* MapEntBounds PSUEDOCODE: +* DOORS WITH BRUSHES: +* For each plane: add the direction normal vector * d to the origin. +* This sould be the point we want to add to bounds for each plane, +* to generate a bounding box containing the planes +**/ + +bool CsndPropLoader::MapEntBounds( idBounds &bounds, idMapEntity *mapEnt ) +{ + bool returnval; + idMapPrimitive *testPrim; + idMapBrush *brush(NULL); + idMapBrushSide *face; + idPlane plane; + int numFaces, numPrim; + idVec3 norm, *addpoints, debugCenter; + idMat3 rotation; + float dist, angle; + const char *modelName; + cmHandle_t cmHandle; // collision model handle for getting bounds + + idDict args = mapEnt->epairs; + const idVec3 origin = args.GetVector("origin","0 0 0"); + modelName = args.GetString("model"); + + // if a door doesn't have a model, the modelname will be the same as the doorname + if( strcmp(modelName,args.GetString("name")) ) + { + // NOTE: In the LoadModel call, Precache is set to false currnetly. If it was set to + // TRUE, this would force the door model to have a .cm file, otherwise + // LoadModel would return 0 in this case. (precache = true, no .cm file) + cmHandle = collisionModelManager->LoadModel( modelName, false ); + if ( cmHandle == 0) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Failed to load collision model for entity %s with model %s. Entity will be ignored.\r", args.GetString("name"), modelName); + returnval = false; + goto Quit; + } + + collisionModelManager->GetModelBounds( cmHandle, bounds ); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found bounds with volume %f for entity %s with model %s.\r", bounds.GetVolume(), args.GetString("name"), modelName); + // Rotation copied from Entity::ParseSpawnArgsToRenderEntity() + // get the rotation matrix in either full form, or single angle form + if ( !args.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", rotation ) ) + { + angle = args.GetFloat( "angle" ); + if ( angle != 0.0f ) + { + rotation = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } + else + { + rotation.Identity(); + } + } + bounds.RotateSelf(rotation); + // Translate and rotate the bounds to be in sync with the model + bounds.TranslateSelf(origin); + // NOTE FOR FUTURE REFERENCE: MUST ROTATE THEN TRANSLATE + /** + * Global DoorExpand is applied to correct door bound inaccuracies. + **/ + ExpandBoundsMinAxis(&bounds, m_SndGlobals.DoorExpand); + debugCenter = bounds.GetCenter(); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Model Bounds center: %s , MapEntity origin: %s\r",debugCenter.ToString(),origin.ToString()); + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Bounds rotation: %s\r", rotation.ToString()); + returnval = true; + goto Quit; + // Brian says it's okay if LoadModel is run twice, it just won't load it the 2nd time. + // Therefore we won't worry about freeing the model now. (this caused a crash when I tried) + } + + // Continue on if the door does not have a model: + + if( (numPrim = mapEnt->GetNumPrimitives()) == 0 ) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Door %s has no primitive data. Door will be ignored.\r", args.GetString("name")); + returnval = false; + goto Quit; + } + for (int j=0; j < numPrim; j++) + { + testPrim = mapEnt->GetPrimitive(j); + if ( testPrim->GetType() == testPrim->TYPE_BRUSH ) + { + brush = static_cast(testPrim); + break; + } + } + if (brush == NULL) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Door %s does not have a brush primitive. Door will be ignored\r", args.GetString("name")); + returnval = false; + goto Quit; + } + + numFaces = brush->GetNumSides(); + addpoints = new idVec3[numFaces]; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("MapEntBounds: Door %s has %d faces\r", mapEnt->epairs.GetString("name"), numFaces ); + + for(int i = 0; i < numFaces; i++) + { + face = brush->GetSide(i); + plane = face->GetPlane(); + norm = plane.Normal(); + dist = plane.Dist(); + norm.Normalize(); + //addpoints[i] = ( norm/norm.Normalize() * dist ) + origin; + //TODO: Make sure this change works correctly: + addpoints[i] = ( norm * dist ) + origin; + //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Added point: %s to bounds for %s\r", addpoints[i].ToString(), mapEnt->epairs.GetString("name")); + } + + bounds.FromPoints(static_cast(addpoints), static_cast(numFaces)); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Entity %s has bounds with volume %f\r", args.GetString("name"), bounds.GetVolume() ); + + delete[] addpoints; + + returnval = true; + +Quit: + return returnval; +} + +void CsndPropLoader::ExpandBoundsMinAxis( idBounds *bounds, float percent ) +{ + idVec3 points[8], diff, mindiff, addpoints[2], oppPoint; + bounds->ToPoints(points); + float diffDist, mindiffDist(100000.0f); // initialize mindiffDist to a really big number + // find the minimum axis and direction vector between minimum points + for( int i = 1; i<8; i++ ) + { + diff = points[0] - points[i]; + diffDist = diff.LengthFast(); + if (diffDist < mindiffDist) + { + mindiffDist = diffDist; + mindiff = diff; + oppPoint = points[i]; + } + } + // expand the axis by adding points along that axis + addpoints[0] = points[0] + mindiff * percent; + addpoints[1] = oppPoint - mindiff * percent; + bounds->AddPoint(addpoints[0]); + bounds->AddPoint(addpoints[1]); +} + + +void CsndPropLoader::ParseMapEntities ( idMapFile *MapFile ) +{ + int i; + //int count(0), missedCount(0); + idDict args; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Soundprop: Parsing Map entities\r"); + for (i = 0; i < ( MapFile->GetNumEntities() ); i++ ) + { + idMapEntity *mapEnt = MapFile->GetEntity( i ); + args = mapEnt->epairs; + const char *classname = args.GetString("classname"); + + if( !strcmp(classname,m_SndGlobals.AreaPropName) ) + { + ParseAreaPropEnt(args); + } + + if( !strcmp(classname,"worldspawn") ) + { + ParseWorldSpawn(args); + } + } + + m_AreaProps.Condense(); + + FillAPGfromAP( gameRenderWorld->NumAreas() ); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Finished parsing map entities\r"); +} + +void CsndPropLoader::ParseWorldSpawn ( idDict args ) +{ + bool SpherDefault; + + SpherDefault = args.GetBool("outdoor_propmodel","0"); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Parsing worldspawn sound prop data...\r" ); + if(SpherDefault) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Using outdoor sound prop model as the default for this map\r"); + } + else + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Using indoor sound prop model as the default for this map\r" ); + } + m_bDefaultSpherical = SpherDefault; +} + +void CsndPropLoader::ParseAreaPropEnt ( idDict args ) +{ + int area; + float lossMult, VolMod; +// bool SpherSpread(false); + SAreaProp propEntry; + idStr lossvalue, VolOffset; + + if ( ( area = gameRenderWorld->PointInArea(args.GetVector("origin")) ) == -1 ) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Sound area properties entity %s is not placed in any area. It will be ignored\r", args.GetString("name") ); + goto Quit; + } + + lossvalue = args.GetString("sound_loss_mult", "1.0"); + + if(!( lossvalue.IsNumeric() )) + { + lossMult = 1.0; + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Non-numeric loss_mult value on area data entity: %s. Default value assumed\r", args.GetString("name") ); + } + else + lossMult = fabs(atof(lossvalue)); + + VolOffset = args.GetString("sound_vol_offset", "0.0"); + + if(!( VolOffset.IsNumeric() )) + { + VolMod = 0.0; + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Warning: Non-numeric volume offset value on area data entity: %s. Default value assumed\r", args.GetString("name") ); + } + else + VolMod = atof(VolOffset); + + // multiply Loss Mult by default attenuation constant + propEntry.LossMult = lossMult * m_SndGlobals.kappa0; + propEntry.VolMod = VolMod; + propEntry.area = area; + propEntry.DataEntered = false; // greebo: Initialised to false to fix gcc warning + + //add to the area properties list + m_AreaProps.Append( static_cast(propEntry) ); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Entity %s is a sound area entity. Applied loss multiplier %f, volume modifier %f\r", args.GetString("name"), lossMult, VolMod ); + +Quit: + return; +} + +void CsndPropLoader::FillAPGfromAP ( int numAreas ) +{ + int i, j, area(0); + + m_AreaPropsG.Clear(); + + m_AreaPropsG.SetNum( numAreas ); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Allocated m_AreaPropsG for %d areas\r", numAreas ); + + // set default values on each area + for (i=0; iNumPortalsInArea(area); + for (int i = 0; i < np; i++) + { + portalTmp = gameRenderWorld->GetPortal(area,i); + //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("FindSndPortal: Desired handle %d, handle of portal %d: %d\r", pHandle, i, areaP->portals[i].handle ); //Uncomment for portal handle debugging + if(portalTmp.portalHandle == pHandle) + { + val = i; + goto Quit; + } + } +Quit: + return val; +} + +void CsndPropLoader::CreateAreasData ( void ) +{ + int i, j, k, np, anum, propscount(0), numAreas(0), numPortals(0), PortIndex; + sndAreaPtr area; + exitPortal_t portalTmp; + idVec3 pCenters; + + numAreas = gameRenderWorld->NumAreas(); + numPortals = gameRenderWorld->NumPortals(); + pCenters.Zero(); + + if( (m_sndAreas = new SsndArea[m_numAreas]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Create Areas: Out of memory when allocating array of %d Areas\r", m_numAreas); + goto Quit; + } + + if( (m_PortData = new SPortData[m_numPortals]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when allocating array of %d portals\r", m_numPortals); + goto Quit; + } + + // Initialize portal data array + for ( int k2 = 0; k2 < m_numPortals; k2++ ) + { + m_PortData[k2].loss = 0; + + m_PortData[k2].LocalIndex[0] = -1; + m_PortData[k2].LocalIndex[1] = -1; + m_PortData[k2].Areas[0] = -1; + m_PortData[k2].Areas[1] = -1; + } + + for ( i = 0; i < m_numAreas; i++ ) + { + area = &m_sndAreas[i]; + area->LossMult = 1.0; + np = gameRenderWorld->NumPortalsInArea(i); + area->numPortals = np; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Number of Portals in Area %d = %d\r", i, np); + + if( (area->portals = new SsndPortal[np]) == NULL ) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Create Areas: Out of memory when building portals array for Area %d\r", i); + goto Quit; + } + for ( j = 0; j < np; j++ ) + { + portalTmp = gameRenderWorld->GetPortal(i,j); + + area->portals[j].portalNum = j; + area->portals[j].handle = portalTmp.portalHandle; + area->portals[j].from = portalTmp.areas[0]; // areas[0] is the 'from' area + area->portals[j].to = portalTmp.areas[1]; + area->portals[j].center = portalTmp.w->GetCenter(); + area->portals[j].winding = portalTmp.w; + + pCenters += area->portals[j].center; + + // enter the data into the portal data array + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting up portal handle %d from area %d\r",portalTmp.portalHandle, i); + SPortData *pPortData = &m_PortData[ portalTmp.portalHandle - 1 ]; + + // make sure we don't overwrite the data from the area on the other side + if(pPortData->Areas[0] == -1 ) + PortIndex = 0; + else + PortIndex = 1; + + pPortData->Areas[ PortIndex ] = i; + pPortData->LocalIndex[ PortIndex ] = j; + } + + // average the portal center coordinates to obtain the area center + if ( np ) + { + area->center = pCenters / np; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Area %d has approximate center %s\r", i, area->center.ToString() ); + } + } + + // Apply special area Properties + for(k = 0; k < m_AreaProps.Num(); k++) + { + anum = m_AreaProps[k].area; + m_sndAreas[anum].LossMult = m_AreaProps[k].LossMult; + m_sndAreas[anum].VolMod = m_AreaProps[k].VolMod; + propscount++; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("%d Area specific losses applied\r", propscount); + + // calculate the portal losses and populate the losses array for each area + WritePortLosses(); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Create Areas array finished.\r"); +Quit: + return; +} + + +void CsndPropLoader::WritePortLosses( void ) +{ + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Writing portal losses...\r"); + + int row, col, area(0), numPorts(0); + float lossval(0); + + for( area=0; area < m_numAreas; area++ ) + { + numPorts = m_sndAreas[area].numPortals; + + if ( (m_sndAreas[area].portalDists = new CMatRUT) == NULL) + { + DM_LOG(LC_SOUND, LT_ERROR)LOGSTRING("Out of memory when initializing portal losses array for area %d\r", area); + goto Quit; + } + + // no need to write a matrix if the area only has one portal + if (numPorts == 1) + continue; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Initializing area %d with %d portals\r", area, numPorts); + + // initialize the RUT matrix to the right size + m_sndAreas[area].portalDists->Init( numPorts ); + + // fill the RUT matrix + for( row=0; row < numPorts; row++ ) + { + for( col=(row + 1); col < numPorts; col++ ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Setting loss for portal %d to portal %d in area %d\r", row, col, area ); + lossval = CalcPortDist( area, row, col ); + + m_sndAreas[area].portalDists->Set( row, col, lossval ); + } + } + } +Quit: + return; +} + +float CsndPropLoader::CalcPortDist( int area, int port1, int port2) +{ + float dist; + idVec3 center1, center2, delta; + // TODO: PHASE 3 SOUNDPROP: Implement design for geometrically calculating loss between portals + // for now, just take center to center distance, correct in a lot of cases + center1 = m_sndAreas[area].portals[port1].center; + center2 = m_sndAreas[area].portals[port2].center; + + delta = center1 - center2; + //TODO: If optimization is needed, use delta.LengthFast() + dist = delta.Length(); + dist *= s_DOOM_TO_METERS; + + return dist; +} + +void CsndPropBase::DestroyAreasData( void ) +{ + int i; + SsndPortal *portalPtr; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing m_sndAreas \r"); + if( m_sndAreas ) + { + for( i=0; i < m_numAreas; i++ ) + { + portalPtr = m_sndAreas[i].portals; + delete[] portalPtr; + + m_sndAreas[i].portalDists->Clear(); + } + + delete[] m_sndAreas; + m_sndAreas = NULL; + m_numAreas = 0; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing m_PortData with %d portals \r", m_numPortals); + if( m_PortData ) + { + delete[] m_PortData; + m_PortData = NULL; + m_numPortals = 0; + } + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Destroy Areas data finished.\r"); +} + +void CsndPropBase::SetPortalLoss( int handle, float value ) +{ + // make sure the handle is valid + if( handle < 1 || handle > gameRenderWorld->NumPortals() ) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("SetPortalLoss called with invalid portal handle %d.\r", handle ); + gameLocal.Warning( "SetPortalLoss called with invalid portal handle %d.\n", handle ); + + goto Quit; + } + + m_PortData[ handle - 1 ].loss = value; + +Quit: + return; +} + +float CsndPropBase::GetPortalLoss( int handle ) +{ + float returnval; + + // make sure the handle is valid + if( handle < 1 || handle > gameRenderWorld->NumPortals() ) + { + DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("GetPortalLoss called with invalid portal handle %d, returning zero loss.\r", handle ); + gameLocal.Warning( "GetPortalLoss called with invalid portal handle %d, returning zero loss.\n", handle ); + + returnval = 0.0; + goto Quit; + } + + returnval = m_PortData[ handle - 1 ].loss; + +Quit: + return returnval; +} + + +// ======================= CsndPropLoader ============================= + +void CsndPropLoader::CompileMap( idMapFile *MapFile ) +{ + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound propagation system initializing...\r"); + + // Just in case this was somehow not done before now + DestroyAreasData(); + + // clear the area properties + m_AreaProps.Clear(); + + m_numAreas = gameRenderWorld->NumAreas(); + + m_numPortals = gameRenderWorld->NumPortals(); + + ParseMapEntities(MapFile); + + CreateAreasData(); + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Sound propagation system finished loading.\r"); + + m_bLoadSuccess = true; +} + +void CsndPropLoader::FillLocationData( void ) +{ + idLocationEntity *pLocEnt; + SAreaProp *pAreaProp; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Filling location soundprop data.\r"); + + if ( !m_AreaPropsG.Num() ) + goto Quit; + + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Checking %d areas\r", gameRenderWorld->NumAreas() ); + for(int i = 0; i < gameRenderWorld->NumAreas(); i++) + { + pAreaProp = &m_AreaPropsG[i]; + if( pAreaProp->DataEntered ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Data already entered for are %d, skipping\r", i ); + continue; + } + + pLocEnt = gameLocal.LocationForArea( i ); + if ( !pLocEnt ) + { + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("No location for area %d, skipping\r", i ); + continue; + } + + pAreaProp->LossMult = pLocEnt->m_SndLossMult; + pAreaProp->VolMod = pLocEnt->m_SndVolMod; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found location data for area %d, entering lossmult %f, volmod %f\r", i, pAreaProp->LossMult, pAreaProp->VolMod ); + } + +Quit: + return; +} + +void CsndPropLoader::Shutdown( void ) +{ + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Clearing sound propagation data loader.\r"); + DestroyAreasData(); + + // clear the area properties + m_AreaProps.Clear(); + + m_bDefaultSpherical = false; + m_bLoadSuccess = false; + + m_AreaPropsG.Clear(); +} diff --git a/game/SndPropLoader.h b/game/SndPropLoader.h new file mode 100644 index 000000000..089358518 --- /dev/null +++ b/game/SndPropLoader.h @@ -0,0 +1,486 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/******************************************************************************/ +/* */ +/* Dark Mod Sound Propagation (C) by Chris Sarantos in USA 2005 */ +/* All rights reserved */ +/* */ +/******************************************************************************/ + +/****************************************************************************** +* +* DESCRIPTION: Sound propagation class for propagating suspicious sounds +* to AI Used on map initialization. +* +* This class will be only for map loading and generation of the Loss Matrix. +* Actual gameplay functions will be handled by another class, CsndProp, for +* ease of maintenance. +* +*****************************************************************************/ + +#ifndef SNDPROPLOADER_H +#define SNDPROPLOADER_H + +#include "../idlib/precompiled.h" +#include "DarkModGlobals.h" + +template +class CMatRUT; + +/** +* Global soundprop settings +* Populated from entityDef atdm:soundprop_globals +**/ +class SsndPGlobals +{ +public: + // names + idStr AreaPropName; // classname of area properties entity + idStr fileExt; // soundprop file extension + + // Map compiling: + // Maximum number of paths to calculate for a given loss matrix element + int MaxPaths; + + /** + * Amount to expand the bounding box of a door model in its thinnest dimension + * when checking for portals in doors. + **/ + float DoorExpand; + + /************** + * The following settings effect both gameplay and compiling: + * They are not set const so they may be changed dynamically, + * but keep in mind the compiled soundprop file for the map + * will NOT change until recompiled. + ***************/ + + float Falloff_Outd; // outdoor sound falloff, multiplied by log(dist^2) + float Falloff_Ind; // indoor sound falloff, multiplied by log(dist^2) + + /** + * Kappa0 is the decay constant [db/M] for a sound wave in air + * In reality this depends on freqeuncy, humidity, etc. + * But the effet is small compared to geometric spreading, (~1%) + * So we assume it's a constant. + **/ + float kappa0; + + /************* + * The following settings effect only gameplay, and can + * safely be linked to cVars if we want. + **************/ + + /** + * If a func_door is not a func_darkmod_door, this is the default + * loss that will be applied when sound propagates thru the door. + **/ + float DefaultDoorLoss; + + // AI settings: + + /** + * Default threshold of hearing for an AI (SPL) + * This corresponds to the minimum audible loudness before + * an AI starts getting alerted by a sound. + * (Think of leaves rustling or a very soft whisper) + * In reality this is about 20dB SPL for the average human + **/ + float DefaultThreshold; + + /** + * AI Volume: All sounds propagated to AI will be scaled + * by this amount. This is intended for gameplay balance, + * and should be linked to a cVar for realtime testing. + * This is in dB, so the default value is zero. + **/ + float Vol; + + + float MaxRange; // Range in meters above which sound propagation is not calculated + float MaxRangeCalVol; // volume value to normalize by for the max soundrange (in dB) + // NOT YET IMPLEMENTED: + float MaxEnvRange; // Range in which environmental sounds are heard by AI + + bool bDebug; + + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); +}; + +//TODO: Move this stuff to documentation + +/** +* NOTE: MaxRange is the maximum distance (in meters) that a sound with +* volume equal to MaxRangeCalVol will be propagated. +* At the default values, these settings are calibrated so that the cutoff +* for a whisper (30dB SWL) is 2 meters (~6 ft) +* +* Formula for cutoff range: +* For a given volume vol0, +* Max Range is calculate with the following "empirical" formula,loosely based on +* the fact that sounds sound twice as loud when they differ by 10 dB +* +* range = pow(2, ((vol0 - MaxRangeCalVol) / 7) ) * MaxRange +* +* The penalty for overestimated the cutoff range is more AI included in the computation +* The penalty for underestimating is AI not hearing a sound that they should have heard. +* Ideally, you want the maxrange to be just a few meters past where the sound falls +* below the AI's threshold volume. +**/ + +/** +* ADDITIONAL NOTES: +* The formula for calculating how much an AI is alerted from a sound is: +* +* psychLoud [in "alert" units] = 1 + (propParms->loudness - threshold) +* +* An alert unit of 1 is a barely heard sound (whisper) heard for ~100mS +* An alert unit of 10 corresponds to hearing twice as loud a sound. +**/ + +/** +* Portal data stored in portal data array indexed by handles +* Contains local portal numbers and attenuation for that portal +**/ +typedef struct SPortData_s +{ + // indices of the portal in the two areas connected by it + // order is arbitrary + int LocalIndex[2]; + int Areas[2]; // area numbers that match up with the local index numbers + float loss; // acoustical loss [dB] when going through the portal +} SPortData; + +/** +* Structure containing special area properties +* lossMultiplier defaults to 1.0 if not set. +**/ +typedef struct SAreaProp_s +{ + int area; // number of the area, for list lookup + float LossMult; // loss multiplier + float VolMod; // added to volume of all sounds originating in this area + bool DataEntered; // set to true if this area has specific data (used for area<-locatoin overriding) +} SAreaProp; + +/** +* SsndPortal and SSndArea are structures for storing the area/portal +* connectivity database. They will be copied over to the gameplay object. +**/ +typedef struct SsndPortal_s +{ + qhandle_t handle; // portal handle + + int portalNum; // integer ID of the portal in the area + + int from; // area the portal is in + + int to; // area the portal goes to + + idVec3 center; // coordinates of the center of the portal + + idVec3 normal; // normal vector of portal (by convention, this points into the room) + + const idWinding *winding; // point information + +} SsndPortal; + +typedef SsndPortal* sndPortalPtr; + +/** +* Array entry for the area->portals tree +**/ +typedef struct SsndArea_s +{ + float LossMult; // loss multiplier (in dB/meter, less than 1 => less loss) + + float VolMod; // Volume offset of sounds originating in this area, in dB. + + int numPortals; // number of portals in this area + + idVec3 center; // approximate center of the area + + SsndPortal_s *portals; // array containing the portals of this area + + CMatRUT *portalDists; // acoustical distances from each portal in room to each other portal + +} SsndArea; + +typedef SsndArea* sndAreaPtr; + + + +// ==================================================================== +/** +* CLASS DESCRIPTION: CsndPropBase has functions and members +* inherited by both CsndPropLoader and CsndProp (the gameplay class) +**/ + +class CsndPropBase { + +public: + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); + + /** + * Structure containing global sound properties. + **/ + SsndPGlobals m_SndGlobals; + + /** + * Fill the global properties structure from the + * soundpropglobals entityDef (defined in soundprop.def. + * This could probably be put on CsndPropLoader instead of + * the base class, but just in case CsndProp needs it, it's here. + * + * Logs a warning and sets defaults if it cannot find the def + * for atdm:soundprop_globals. + **/ + void GlobalsFromDef( void ); + + /** + * Insert the loss argument into the portal data array entry for + * the given portal handle + **/ + void SetPortalLoss( int handle, float value ); + + /** + * Get the acoustical loss for the given portal handle + * Portal handle must be between 1 and the number of portals in the map + **/ + float GetPortalLoss( int handle ); + + +protected: + + /** + * Updates any global sound properties that are linked + * to console vars or other realtime vars + **/ + void UpdateGlobals( void ); + + /** + * Set the globals to some default values if the atdm:soundprop_globals + * def is missing. + **/ + void DefaultGlobals( void ); + + /** + * Delete the m_sndAreas array + **/ + void DestroyAreasData( void ); + +protected: + + /** + * This gets set to TRUE when a .spr file is successfully loaded + * for the current map. + **/ + bool m_bLoadSuccess; + + /** + * If set to true, the default sound model will be indoor propagation + * This bool is read from the worldspawn entity, and defaults to false + **/ + bool m_bDefaultSpherical; + + /** + * Count of the number of areas in a map + **/ + int m_numAreas; + + /** + * Count of the number of unique portals in a map + **/ + int m_numPortals; + + + /******************************************************************** + * GAMEPLAY MEMBERS + * Members after this point must be passed along to be used in gameplay! + *********************************************************************/ + + /** + * Area and portal connectivity database + * Created by loader, used during gameplay + **/ + SsndArea *m_sndAreas; + + /** + * m_AreaPropsG contains the area properties of ALL areas for use + * during propagation. + * defaults are loss multiplier = 1.0, and VolMod = 0.0. + **/ + idList m_AreaPropsG; + + /** + * Portal data array indexed by portal handle + * Used to optimize lookup of local portal number + * Also stores the current attenuation value of the portal + **/ + SPortData *m_PortData; +}; + + +/** +* CLASS DESCRIPTION: CsndPropLoader class. Handles parsing of mapfile +* into sound prop data, precalculating portal losses. Also handles +* loading of existing sound propagation files (.spr) for a given map, +* and writing of these files after the mapfile compilation is done. +* +**/ + +class CsndPropLoader : public CsndPropBase { +public: + + friend class CsndProp; + + CsndPropLoader ( void ); + ~CsndPropLoader ( void ); + + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); + + /** + * Load sound prop system from a loaded mapfile. + * This does the actual parsing of the map file and will do + * the generating of the Loss Matrix, as opposed to LoadSprFile + * which just loads the file for the map. + * For now, this is run in game_local every map load as a test + * When the actual system is in place, we must check to see if the map + * has an existing .spr file, and load that instead of running this. + * + * This should probably be renamed to CompileMap. This is what we + * call from the editor console to compile the .spr AFTER compiling + * the map with dmap. + * + * Also, this function will have to load the mapfile + * idMapFile pointer for the appropriate map itself instead of relying on + * something else to pass it. + **/ + void CompileMap( idMapFile *MapFile ); + + /** + * Destroy sound prop data when switching to a new map, game ends, etc + **/ + void Shutdown( void ); + + /** + * To be run AFTER entities spawn. Goes through the location areas and fills + * in location data for each area. Note area data objects override location data. + **/ + void FillLocationData( void ); + +private: + + /** + * The following functions go through the mapfile and identify map entities + * that are associated with sound prop. ParseMapEntities calls ParseWorldSpawn, + * ParseAreapropEnt and ParseDoor. + **/ + + void ParseMapEntities ( idMapFile *MapFile ); + + /** + * ParseWorldSpawn gets map-wide sound information from the worldspawn entity + * This information includes whether the default sound prop model should be + * indoor or outdoor (whether the map is predominantly indoor or outdoor) + **/ + void ParseWorldSpawn ( idDict args ); + + /** + * Area property entities are parsed to add their properties to + * the area properties array. + **/ + void ParseAreaPropEnt ( idDict args ); + + /** + * Searches the provided area number for the portal handle pHandle. + * Then returns the integer index of the portal within the portal list + * of that area. (As defined in gameRenderWorld->GetPortal(area num,portal num)) + * Returns -1 if the portal is not found. + **/ + int FindSndPortal( int area, qhandle_t pHandle ); + + /** + * Finds the bounds of a map entity and writes it to bounds argument. + * + * If the map entity has a model, the bounds of the collision model are returned. + * If no collision model is available for the given model, the rendermodel + * is used as the collision model. This is usually not good since rendermodels can + * be high poly. + * + * If the map entity has no model, the first primitive brush found is used to + * generate a bounding box. Primitive patches are ignored. + * + * This function is currently only used for finding the bounds of doors + * to check if a given door contains a portal. + **/ + bool MapEntBounds( idBounds &bounds, idMapEntity *mapEnt ); + + /** + * Helper function : TODO : move to a more general library, perhaps idBounds + * Expand the bounds only in the direction that they are the thinnest. + * Expands by percent * the thinnest width of the box (note 1.0 = 100%) + **/ + void ExpandBoundsMinAxis( idBounds *bounds, float percent ); + + /** + * Create the Areas array that stores which portals connect which areas + * as well as area sound loss multipliers. + * NOTE: Destroy is on base class + **/ + void CreateAreasData ( void ); + + /** + * Precalculated the portal-to-portal losses and write them to m_sndAreas + * To be called by or after CreateAreasData + **/ + void WritePortLosses( void ); + + /** + * Calculate the distance a sound wave would travel between two + * portal centers Often this is a straight line, but sometimes it bounces. + **/ + float CalcPortDist( int area, int port1, int port2 ); + + /** + * Fill the m_AreaPropsG array from the m_AreaProps array. + * Default loss multiplier = 1.0, default sound model = indoor + **/ + void FillAPGfromAP ( int numAreas ); + +protected: + + /************************************************************ + * PRE-GAMEPLAY MEMBERS + * These members are only used by the pre-gameplay object and don't need + * to be copied to the gameplay object. + ***********************************************************/ + + /** + * List of area properties. + * Only contains areas with non-default properties. + **/ + idList m_AreaProps; + +}; + +#endif diff --git a/game/Sound.cpp b/game/Sound.cpp new file mode 100644 index 000000000..217b80ee5 --- /dev/null +++ b/game/Sound.cpp @@ -0,0 +1,302 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +=============================================================================== + + SOUND + +=============================================================================== +*/ + +const idEventDef EV_Speaker_On( "On", NULL ); +const idEventDef EV_Speaker_Off( "Off", NULL ); +const idEventDef EV_Speaker_Timer( "", NULL ); + +CLASS_DECLARATION( idEntity, idSound ) + EVENT( EV_Activate, idSound::Event_Trigger ) + EVENT( EV_Speaker_On, idSound::Event_On ) + EVENT( EV_Speaker_Off, idSound::Event_Off ) + EVENT( EV_Speaker_Timer, idSound::Event_Timer ) +END_CLASS + + +/* +================ +idSound::idSound +================ +*/ +idSound::idSound( void ) { + lastSoundVol = 0.0f; + soundVol = 0.0f; + shakeTranslate.Zero(); + shakeRotate.Zero(); + random = 0.0f; + wait = 0.0f; + timerOn = false; + playingUntilTime = 0; +} + +/* +================ +idSound::Save +================ +*/ +void idSound::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( lastSoundVol ); + savefile->WriteFloat( soundVol ); + savefile->WriteFloat( random ); + savefile->WriteFloat( wait ); + savefile->WriteBool( timerOn ); + savefile->WriteVec3( shakeTranslate ); + savefile->WriteAngles( shakeRotate ); + savefile->WriteInt( playingUntilTime ); +} + +/* +================ +idSound::Restore +================ +*/ +void idSound::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( lastSoundVol ); + savefile->ReadFloat( soundVol ); + savefile->ReadFloat( random ); + savefile->ReadFloat( wait ); + savefile->ReadBool( timerOn ); + savefile->ReadVec3( shakeTranslate ); + savefile->ReadAngles( shakeRotate ); + savefile->ReadInt( playingUntilTime ); +} + +/* +================ +idSound::Spawn +================ +*/ +void idSound::Spawn( void ) { + spawnArgs.GetVector( "move", "0 0 0", shakeTranslate ); + spawnArgs.GetAngles( "rotate", "0 0 0", shakeRotate ); + spawnArgs.GetFloat( "random", "0", random ); + spawnArgs.GetFloat( "wait", "0", wait ); + + if ( ( wait > 0.0f ) && ( random >= wait ) ) { + random = wait - 0.001; + gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + soundVol = 0.0f; + lastSoundVol = 0.0f; + + if ( ( shakeRotate != ang_zero ) || ( shakeTranslate != vec3_zero ) ) { + BecomeActive( TH_THINK ); + } + + if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) { + timerOn = true; + PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); + } else { + timerOn = false; + } + // add this speaker to the list of ambient music speakers affected by tdm_music_volume + if ( spawnArgs.GetBool( "s_music" ) ) { + gameLocal.musicSpeakers.Append( entityNumber ); + } +} + +/* +================ +idSound::Event_Trigger + +this will toggle the idle idSound on and off +================ +*/ +void idSound::Event_Trigger( idEntity *activator ) { + if ( wait > 0.0f ) { + if ( timerOn ) { + timerOn = false; + CancelEvents( &EV_Speaker_Timer ); + } else { + timerOn = true; + DoSound( true ); + PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); + } + } else { + if ( gameLocal.isMultiplayer ) { + if ( refSound.referenceSound && ( gameLocal.time < playingUntilTime ) ) { + DoSound( false ); + } else { + DoSound( true ); + } + } else { + if ( refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) { + DoSound( false ); + } else { + DoSound( true ); + } + } + } +} + +/* +================ +idSound::Event_Timer +================ +*/ +void idSound::Event_Timer( void ) { + DoSound( true ); + PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); +} + +/* +================ +idSound::Think +================ +*/ +void idSound::Think( void ) { + idAngles ang; + + // run physics + RunPhysics(); + + // clear out our update visuals think flag since we never call Present + BecomeInactive( TH_UPDATEVISUALS ); +} + +/* +=============== +idSound::UpdateChangableSpawnArgs +=============== +*/ +void idSound::UpdateChangeableSpawnArgs( const idDict *source ) { + + idEntity::UpdateChangeableSpawnArgs( source ); + + if ( source ) { + FreeSoundEmitter( true ); + spawnArgs.Copy( *source ); + idSoundEmitter *saveRef = refSound.referenceSound; + gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound ); + refSound.referenceSound = saveRef; + + idVec3 origin; + idMat3 axis; + + if ( GetPhysicsToSoundTransform( origin, axis ) ) { + refSound.origin = GetPhysics()->GetOrigin() + origin * axis; + } else { + refSound.origin = GetPhysics()->GetOrigin(); + } + + spawnArgs.GetFloat( "random", "0", random ); + spawnArgs.GetFloat( "wait", "0", wait ); + + if ( ( wait > 0.0f ) && ( random >= wait ) ) { + random = wait - 0.001; + gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) { + timerOn = true; + DoSound( false ); + CancelEvents( &EV_Speaker_Timer ); + PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); + } else if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) { + // start it if it isn't already playing, and we aren't waitForTrigger + DoSound( true ); + timerOn = false; + } + } +} + +/* +=============== +idSound::SetSound +=============== +*/ +void idSound::SetSound( const char *sound, int channel ) { + const idSoundShader *shader = declManager->FindSound( sound ); + if ( shader != refSound.shader ) { + FreeSoundEmitter( true ); + } + gameEdit->ParseSpawnArgsToRefSound(&spawnArgs, &refSound); + refSound.shader = shader; + // start it if it isn't already playing, and we aren't waitForTrigger + if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) { + DoSound( true ); + } +} + +/* +================ +idSound::DoSound +================ +*/ +void idSound::DoSound( bool play ) { + if ( play ) { + StartSoundShader( refSound.shader, SND_CHANNEL_ANY, refSound.parms.soundShaderFlags, true, &playingUntilTime ); + playingUntilTime += gameLocal.time; + } else { + StopSound( SND_CHANNEL_ANY, true ); + playingUntilTime = 0; + } +} + +/* +================ +idSound::Event_On +================ +*/ +void idSound::Event_On( void ) { + if ( wait > 0.0f ) { + timerOn = true; + PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); + } + DoSound( true ); +} + +/* +================ +idSound::Event_Off +================ +*/ +void idSound::Event_Off( void ) { + if ( timerOn ) { + timerOn = false; + CancelEvents( &EV_Speaker_Timer ); + } + DoSound( false ); +} + +/* +=============== +idSound::ShowEditingDialog +=============== +*/ +void idSound::ShowEditingDialog( void ) { + common->InitTool( EDITOR_SOUND, &spawnArgs ); +} + diff --git a/game/Sound.h b/game/Sound.h new file mode 100644 index 000000000..c1b1e09fd --- /dev/null +++ b/game/Sound.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_SOUND_H__ +#define __GAME_SOUND_H__ + +/* +=============================================================================== + + Generic sound emitter. + +=============================================================================== +*/ + +class idSound : public idEntity { +public: + CLASS_PROTOTYPE( idSound ); + + idSound( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void UpdateChangeableSpawnArgs( const idDict *source ); + + void Spawn( void ); + + void ToggleOnOff( idEntity *other, idEntity *activator ); + void Think( void ); + void SetSound( const char *sound, int channel = SND_CHANNEL_ANY ); + + virtual void ShowEditingDialog( void ); + +private: + float lastSoundVol; + float soundVol; + float random; + float wait; + bool timerOn; + idVec3 shakeTranslate; + idAngles shakeRotate; + int playingUntilTime; + + void Event_Trigger( idEntity *activator ); + void Event_Timer( void ); + void Event_On( void ); + void Event_Off( void ); + void DoSound( bool play ); +}; + +#endif /* !__GAME_SOUND_H__ */ diff --git a/DarkMod/StaticMulti.cpp b/game/StaticMulti.cpp similarity index 96% rename from DarkMod/StaticMulti.cpp rename to game/StaticMulti.cpp index 911d634f4..b3bebf861 100644 --- a/DarkMod/StaticMulti.cpp +++ b/game/StaticMulti.cpp @@ -1,12 +1,22 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* diff --git a/DarkMod/StaticMulti.h b/game/StaticMulti.h similarity index 83% rename from DarkMod/StaticMulti.h rename to game/StaticMulti.h index 30cabdfd0..77e3eb2dd 100644 --- a/DarkMod/StaticMulti.h +++ b/game/StaticMulti.h @@ -1,21 +1,31 @@ // vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // Copyright (C) 2010 Tels (Donated to The Dark Mod) #ifndef __DAKRMOD_STATICMULTI_H__ #define __DARKMOD_STATICMULTI_H__ -#include "../game/misc.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/ModelGenerator.h" +#include "Misc.h" +#include "StimResponse/StimResponseCollection.h" +#include "ModelGenerator.h" /* =============================================================================== diff --git a/DarkMod/StimResponse/Response.cpp b/game/StimResponse/Response.cpp similarity index 90% rename from DarkMod/StimResponse/Response.cpp rename to game/StimResponse/Response.cpp index b141b7977..32f454d71 100644 --- a/DarkMod/StimResponse/Response.cpp +++ b/game/StimResponse/Response.cpp @@ -1,12 +1,22 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/StimResponse/Response.h b/game/StimResponse/Response.h similarity index 77% rename from DarkMod/StimResponse/Response.h rename to game/StimResponse/Response.h index 1bb814a23..90380488f 100644 --- a/DarkMod/StimResponse/Response.h +++ b/game/StimResponse/Response.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef SR_RESPONSE__H #define SR_RESPONSE__H diff --git a/game/StimResponse/ResponseEffect.cpp b/game/StimResponse/ResponseEffect.cpp new file mode 100644 index 000000000..200b49706 --- /dev/null +++ b/game/StimResponse/ResponseEffect.cpp @@ -0,0 +1,88 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "ResponseEffect.h" + +/********************************************************************/ +/* CResponseEffect */ +/********************************************************************/ + +CResponseEffect::CResponseEffect( + const function_t* scriptFunction, + const idStr& effectPostfix, + const idStr& scriptName , + bool localScript) : + _scriptFunction(scriptFunction), + _scriptName(scriptName), + _effectPostfix(effectPostfix), + _localScript(localScript), + _scriptFunctionValid(true) +{} + +void CResponseEffect::runScript(idEntity* owner, idEntity* stimEntity, float magnitude) { + if (!_scriptFunctionValid) + { + if (owner == NULL) + { + DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("Cannot restore scriptfunction, owner is NULL: %s\r", _scriptName.c_str()); + return; + } + + _scriptFunctionValid = true; + + if (_localScript) { + // Local scriptfunction + _scriptFunction = owner->scriptObject.GetFunction(_scriptName.c_str()); + } + else { + // Global Method + _scriptFunction = gameLocal.program.FindFunction(_scriptName.c_str()); + } + } + + if (_scriptFunction == NULL) return; + + DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Running ResponseEffect Script, effectPostfix = %s...\r", _effectPostfix.c_str()); + + idThread *pThread = new idThread(_scriptFunction); + int n = pThread->GetThreadNum(); + pThread->CallFunctionArgs(_scriptFunction, true, "eesff", owner, stimEntity, _effectPostfix.c_str(), magnitude, n); + pThread->DelayedStart(0); +} + +void CResponseEffect::Save(idSaveGame *savefile) const +{ + savefile->WriteString(_effectPostfix.c_str()); + savefile->WriteString(_scriptName.c_str()); + savefile->WriteBool(_localScript); +} + +void CResponseEffect::Restore(idRestoreGame *savefile) +{ + savefile->ReadString(_effectPostfix); + savefile->ReadString(_scriptName); + savefile->ReadBool(_localScript); + + // The script function pointer has to be restored after loading, set the dirty flag + _scriptFunctionValid = false; +} diff --git a/game/StimResponse/ResponseEffect.h b/game/StimResponse/ResponseEffect.h new file mode 100644 index 000000000..d80cc5eaa --- /dev/null +++ b/game/StimResponse/ResponseEffect.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef SR_RESPONSEEFFECT__H +#define SR_RESPONSEEFFECT__H + +class CStim; + +class CResponseEffect +{ +protected: + const function_t* _scriptFunction; + + // The name of the script + idStr _scriptName; + + // The effect postfix, "1_1" for example + // This is passed to the script along with the "owner" entity, + // so that the script can lookup any arguments it might need. + idStr _effectPostfix; + + // Is TRUE of the script function is on the entity scriptobject, FALSE for local functions + bool _localScript; + + // This is set to FALSE after loading, so that the script function + // gets resolved again. + bool _scriptFunctionValid; + +public: + // Pass the scriptowner to this structure or NULL for global functions + CResponseEffect(const function_t* scriptFunction, + const idStr& effectPostfix, + const idStr& scriptName , + bool localScript); + + void Save(idSaveGame *savefile) const; + void Restore(idRestoreGame *savefile); + + /** + * Runs the attached response effect script + * (does nothing if the scriptfunc pointer is NULL) + * + * @owner: The entity this script is affecting + * @stimEntity: The entity that triggered this response + * @magnitude: the magnitude of the stim (min = 0, max = stim->magnitude) + */ + virtual void runScript(idEntity* owner, idEntity* stimEntity, float magnitude); +}; + +#endif /* SR_RESPONSEEFFECT__H */ diff --git a/DarkMod/StimResponse/Stim.cpp b/game/StimResponse/Stim.cpp similarity index 84% rename from DarkMod/StimResponse/Stim.cpp rename to game/StimResponse/Stim.cpp index d9207a598..1da156d82 100644 --- a/DarkMod/StimResponse/Stim.cpp +++ b/game/StimResponse/Stim.cpp @@ -1,12 +1,22 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/StimResponse/Stim.h b/game/StimResponse/Stim.h similarity index 88% rename from DarkMod/StimResponse/Stim.h rename to game/StimResponse/Stim.h index 2426b6f0d..dbb3801c8 100644 --- a/DarkMod/StimResponse/Stim.h +++ b/game/StimResponse/Stim.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef SR_STIM__H #define SR_STIM__H diff --git a/DarkMod/StimResponse/StimResponse.cpp b/game/StimResponse/StimResponse.cpp similarity index 84% rename from DarkMod/StimResponse/StimResponse.cpp rename to game/StimResponse/StimResponse.cpp index c94e19223..a1d297aee 100644 --- a/DarkMod/StimResponse/StimResponse.cpp +++ b/game/StimResponse/StimResponse.cpp @@ -1,12 +1,22 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/StimResponse/StimResponse.h b/game/StimResponse/StimResponse.h similarity index 82% rename from DarkMod/StimResponse/StimResponse.h rename to game/StimResponse/StimResponse.h index b39298437..e364d998a 100644 --- a/DarkMod/StimResponse/StimResponse.h +++ b/game/StimResponse/StimResponse.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef SR_STIMRESPONSE__H #define SR_STIMRESPONSE__H diff --git a/DarkMod/StimResponse/StimResponseCollection.cpp b/game/StimResponse/StimResponseCollection.cpp similarity index 94% rename from DarkMod/StimResponse/StimResponseCollection.cpp rename to game/StimResponse/StimResponseCollection.cpp index 6b3d792f2..5019f4096 100644 --- a/DarkMod/StimResponse/StimResponseCollection.cpp +++ b/game/StimResponse/StimResponseCollection.cpp @@ -1,12 +1,22 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/StimResponse/StimResponseCollection.h b/game/StimResponse/StimResponseCollection.h similarity index 88% rename from DarkMod/StimResponse/StimResponseCollection.h rename to game/StimResponse/StimResponseCollection.h index 826fd23bd..c0ce8af7a 100644 --- a/DarkMod/StimResponse/StimResponseCollection.h +++ b/game/StimResponse/StimResponseCollection.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef SR_STIMRESPONSECOLLECTION__H #define SR_STIMRESPONSECOLLECTION__H diff --git a/DarkMod/StimResponse/StimResponseTimer.cpp b/game/StimResponse/StimResponseTimer.cpp similarity index 90% rename from DarkMod/StimResponse/StimResponseTimer.cpp rename to game/StimResponse/StimResponseTimer.cpp index 49f9eac4c..7a8b99e91 100644 --- a/DarkMod/StimResponse/StimResponseTimer.cpp +++ b/game/StimResponse/StimResponseTimer.cpp @@ -1,12 +1,22 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/StimResponse/StimResponseTimer.h b/game/StimResponse/StimResponseTimer.h similarity index 88% rename from DarkMod/StimResponse/StimResponseTimer.h rename to game/StimResponse/StimResponseTimer.h index 687104122..dd29812da 100644 --- a/DarkMod/StimResponse/StimResponseTimer.h +++ b/game/StimResponse/StimResponseTimer.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef SR_RESPONSETIMER__H #define SR_RESPONSETIMER__H diff --git a/game/StimResponse/StimType.h b/game/StimResponse/StimType.h new file mode 100644 index 000000000..9125e6b29 --- /dev/null +++ b/game/StimResponse/StimType.h @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef _STIMTYPE_H_ +#define _STIMTYPE_H_ + +// greebo: RichEdit.h defines the same symbol +#ifdef ST_DEFAULT +#undef ST_DEFAULT +#endif + +// If default stims are to be added here, the static array in the StimResponse.cpp file +// also must be updated. USER and UNDEFINED are not to be added though, as +// they have special meanings. +enum StimType +{ + ST_FROB, // Frobbed + ST_FIRE, // Fire + ST_WATER, // Water + ST_DAMAGE, // damages target + ST_SHIELD, // protects against arrows or physical blows + ST_HEALING, // heals target + ST_HOLY, // holy is applied + ST_MAGIC, // Magic is being used + ST_TOUCH, // triggered if touched + ST_KNOCKOUT, // target is knocked out + ST_KILL, // target is killed + ST_RESTORE, // target is restored + ST_LIGHT, // triggered by light + ST_SOUND, // triggered by sound + ST_VISUAL, // visual contact + ST_INVITE, // can be used to trigger special behaviour (like a stool can invite an AI to sit down) + ST_READ, // Can be read + ST_RANDOM, // Random response is selected + ST_TIMER, // Timer trigger + ST_COMMUNICATION, // A communication stimulus (see CommunicationStim.h) + ST_GAS, // triggered by gas arrows + ST_TRIGGER, // Triggered by triggering :) + ST_TARGET_REACHED, // Emitted, if the AI has reached its target (induced by effect_moveToPosition) + ST_PLAYER, // The Stim emitted by the player + ST_FLASH, // Emitted by flashbombs + ST_BLIND, // A stim that immediately blinds the AI (no visibility is needed) - for use in flashmines + ST_USER = 1000, // User defined types should use this as it's base + ST_DEFAULT = -1 +}; + +#endif /* _STIMTYPE_H_ */ diff --git a/game/Target.cpp b/game/Target.cpp new file mode 100644 index 000000000..e7de661d1 --- /dev/null +++ b/game/Target.cpp @@ -0,0 +1,2271 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* + +Invisible entities that affect other entities or the world when activated. + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "Objectives/MissionData.h" +#include "Missions/MissionManager.h" +#include "ai/Conversation/ConversationSystem.h" +#include "StimResponse/StimResponseCollection.h" + +/* +=============================================================================== + +idTarget + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idTarget ) +END_CLASS + + +/* +=============================================================================== + +idTarget_Remove + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_Remove ) + EVENT( EV_Activate, idTarget_Remove::Event_Activate ) +END_CLASS + +/* +================ +idTarget_Remove::Event_Activate +================ +*/ +void idTarget_Remove::Event_Activate( idEntity *activator ) { + int i; + idEntity *ent; + + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->PostEventMS( &EV_Remove, 0 ); + } + } + + // delete our self when done + PostEventMS( &EV_Remove, 0 ); +} + + +/* +=============================================================================== + +idTarget_Show + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_Show ) + EVENT( EV_Activate, idTarget_Show::Event_Activate ) +END_CLASS + +/* +================ +idTarget_Show::Event_Activate +================ +*/ +void idTarget_Show::Event_Activate( idEntity *activator ) { + int i; + idEntity *ent; + + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->Show(); + } + } + + // delete our self when done + PostEventMS( &EV_Remove, 0 ); +} + + +/* +=============================================================================== + +idTarget_Damage + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_Damage ) + EVENT( EV_Activate, idTarget_Damage::Event_Activate ) +END_CLASS + +/* +================ +idTarget_Damage::Event_Activate +================ +*/ +void idTarget_Damage::Event_Activate( idEntity *activator ) { + int i; + const char *damage; + idEntity * ent; + + damage = spawnArgs.GetString( "def_damage", "damage_generic" ); + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->Damage( this, this, vec3_origin, damage, 1.0f, INVALID_JOINT ); + } + } +} + + +/* +=============================================================================== + +idTarget_SessionCommand + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SessionCommand ) + EVENT( EV_Activate, idTarget_SessionCommand::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SessionCommand::Event_Activate +================ +*/ +void idTarget_SessionCommand::Event_Activate( idEntity *activator ) { + gameLocal.sessionCommand = spawnArgs.GetString( "command" ); +} + + +/* +=============================================================================== + +idTarget_EndLevel + +Just a modified form of idTarget_SessionCommand +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_EndLevel ) + EVENT( EV_Activate, idTarget_EndLevel::Event_Activate ) +END_CLASS + +/* +================ +idTarget_EndLevel::Event_Activate +================ +*/ +void idTarget_EndLevel::Event_Activate( idEntity *activator ) { + idStr nextMap; + +#ifdef ID_DEMO_BUILD + if ( spawnArgs.GetBool( "endOfGame" ) ) { + cvarSystem->SetCVarBool( "g_nightmare", true ); + gameLocal.sessionCommand = "endofDemo"; + return; + } +#else + if ( spawnArgs.GetBool( "endOfGame" ) ) { + cvarSystem->SetCVarBool( "g_nightmare", true ); + gameLocal.sessionCommand = "disconnect"; + return; + } +#endif + if ( !spawnArgs.GetString( "nextMap", "", nextMap ) ) { + gameLocal.Printf( "idTarget_SessionCommand::Event_Activate: no nextMap key\n" ); + return; + } + + if ( spawnArgs.GetInt( "devmap", "0" ) ) { + gameLocal.sessionCommand = "devmap "; // only for special demos + } else { + gameLocal.sessionCommand = "map "; + } + + gameLocal.sessionCommand += nextMap; +} + + +/* +=============================================================================== + +idTarget_WaitForButton + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_WaitForButton ) + EVENT( EV_Activate, idTarget_WaitForButton::Event_Activate ) +END_CLASS + +/* +================ +idTarget_WaitForButton::Event_Activate +================ +*/ +void idTarget_WaitForButton::Event_Activate( idEntity *activator ) { + if ( thinkFlags & TH_THINK ) { + BecomeInactive( TH_THINK ); + } else { + // always allow during cinematics + cinematic = true; + BecomeActive( TH_THINK ); + } +} + +/* +================ +idTarget_WaitForButton::Think +================ +*/ +void idTarget_WaitForButton::Think( void ) { + idPlayer *player; + + if ( thinkFlags & TH_THINK ) { + player = gameLocal.GetLocalPlayer(); + if ( player && ( !player->oldButtons & BUTTON_ATTACK ) && ( player->usercmd.buttons & BUTTON_ATTACK ) ) { + player->usercmd.buttons &= ~BUTTON_ATTACK; + BecomeInactive( TH_THINK ); + ActivateTargets( player ); + } + } else { + BecomeInactive( TH_ALL ); + } +} + + +/* +=============================================================================== + +idTarget_SetGlobalShaderParm + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetGlobalShaderTime ) +EVENT( EV_Activate, idTarget_SetGlobalShaderTime::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SetGlobalShaderTime::Event_Activate +================ +*/ +void idTarget_SetGlobalShaderTime::Event_Activate( idEntity *activator ) { + int parm = spawnArgs.GetInt( "globalParm" ); + float time = -MS2SEC( gameLocal.time ); + if ( parm >= 0 && parm < MAX_GLOBAL_SHADER_PARMS ) { + gameLocal.globalShaderParms[parm] = time; + } +} + +/* +=============================================================================== + +idTarget_SetShaderParm + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetShaderParm ) + EVENT( EV_Activate, idTarget_SetShaderParm::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SetShaderParm::Event_Activate +================ +*/ +void idTarget_SetShaderParm::Event_Activate( idEntity *activator ) { + int i; + idEntity * ent; + float value; + idVec3 color; + int parmnum; + + // set the color on the targets + if ( spawnArgs.GetVector( "_color", "1 1 1", color ) ) { + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->SetColor( color[ 0 ], color[ 1 ], color[ 2 ] ); + } + } + } + + // set any shader parms on the targets + for( parmnum = 0; parmnum < MAX_ENTITY_SHADER_PARMS; parmnum++ ) { + if ( spawnArgs.GetFloat( va( "shaderParm%d", parmnum ), "0", value ) ) { + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->SetShaderParm( parmnum, value ); + } + } + if (spawnArgs.GetBool("toggle") && (value == 0 || value == 1)) { + int val = static_cast(value); + val ^= 1; + value = val; + spawnArgs.SetFloat(va("shaderParm%d", parmnum), value); + } + } + } +} + + +/* +=============================================================================== + +idTarget_SetShaderTime + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetShaderTime ) + EVENT( EV_Activate, idTarget_SetShaderTime::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SetShaderTime::Event_Activate +================ +*/ +void idTarget_SetShaderTime::Event_Activate( idEntity *activator ) { + int i; + idEntity * ent; + float time; + + time = -MS2SEC( gameLocal.time ); + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->SetShaderParm( SHADERPARM_TIMEOFFSET, time ); + if ( ent->IsType( idLight::Type ) ) { + static_cast(ent)->SetLightParm( SHADERPARM_TIMEOFFSET, time ); + } + } + } +} + +/* +=============================================================================== + +idTarget_FadeEntity + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_FadeEntity ) + EVENT( EV_Activate, idTarget_FadeEntity::Event_Activate ) +END_CLASS + +/* +================ +idTarget_FadeEntity::idTarget_FadeEntity +================ +*/ +idTarget_FadeEntity::idTarget_FadeEntity( void ) { + fadeFrom.Zero(); + fadeStart = 0; + fadeEnd = 0; +} + +/* +================ +idTarget_FadeEntity::Save +================ +*/ +void idTarget_FadeEntity::Save( idSaveGame *savefile ) const { + savefile->WriteVec4( fadeFrom ); + savefile->WriteInt( fadeStart ); + savefile->WriteInt( fadeEnd ); +} + +/* +================ +idTarget_FadeEntity::Restore +================ +*/ +void idTarget_FadeEntity::Restore( idRestoreGame *savefile ) { + savefile->ReadVec4( fadeFrom ); + savefile->ReadInt( fadeStart ); + savefile->ReadInt( fadeEnd ); +} + +/* +================ +idTarget_FadeEntity::Event_Activate +================ +*/ +void idTarget_FadeEntity::Event_Activate( idEntity *activator ) { + idEntity *ent; + int i; + + if ( !targets.Num() ) { + return; + } + + // always allow during cinematics + cinematic = true; + BecomeActive( TH_THINK ); + + ent = this; + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->GetColor( fadeFrom ); + break; + } + } + + fadeStart = gameLocal.time; + fadeEnd = gameLocal.time + SEC2MS( spawnArgs.GetFloat( "fadetime" ) ); +} + +/* +================ +idTarget_FadeEntity::Think +================ +*/ +void idTarget_FadeEntity::Think( void ) { + int i; + idEntity *ent; + idVec4 color; + idVec4 fadeTo; + float frac; + + if ( thinkFlags & TH_THINK ) { + GetColor( fadeTo ); + if ( gameLocal.time >= fadeEnd ) { + color = fadeTo; + BecomeInactive( TH_THINK ); + } else { + frac = ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ); + color.Lerp( fadeFrom, fadeTo, frac ); + } + + // set the color on the targets + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->SetColor( color ); + } + } + } else { + BecomeInactive( TH_ALL ); + } +} + +/* +=============================================================================== + +idTarget_LightFadeIn + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_LightFadeIn ) + EVENT( EV_Activate, idTarget_LightFadeIn::Event_Activate ) +END_CLASS + +/* +================ +idTarget_LightFadeIn::Event_Activate +================ +*/ +void idTarget_LightFadeIn::Event_Activate( idEntity *activator ) { + idEntity *ent; + idLight *light; + int i; + float time; + + if ( !targets.Num() ) { + return; + } + + time = spawnArgs.GetFloat( "fadetime" ); + ent = this; + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( !ent ) { + continue; + } + if ( ent->IsType( idLight::Type ) ) { + light = static_cast( ent ); + light->FadeIn( time ); + } else { + gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() ); + } + } +} + +/* +=============================================================================== + +idTarget_LightFadeOut + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_LightFadeOut ) + EVENT( EV_Activate, idTarget_LightFadeOut::Event_Activate ) +END_CLASS + +/* +================ +idTarget_LightFadeOut::Event_Activate +================ +*/ +void idTarget_LightFadeOut::Event_Activate( idEntity *activator ) { + idEntity *ent; + idLight *light; + int i; + float time; + + if ( !targets.Num() ) { + return; + } + + time = spawnArgs.GetFloat( "fadetime" ); + ent = this; + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( !ent ) { + continue; + } + if ( ent->IsType( idLight::Type ) ) { + light = static_cast( ent ); + light->FadeOut( time ); + } else { + gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() ); + } + } +} + +/* +=============================================================================== + +idTarget_Give + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_Give ) + EVENT( EV_Activate, idTarget_Give::Event_Activate ) +END_CLASS + +/* +================ +idTarget_Give::Spawn +================ +*/ +void idTarget_Give::Spawn( void ) { + if ( spawnArgs.GetBool( "onSpawn" ) ) { + PostEventMS( &EV_Activate, 50 ); + } +} + +/* +================ +idTarget_Give::Event_Activate +================ +*/ +void idTarget_Give::Event_Activate( idEntity *activator ) { + + if ( spawnArgs.GetBool( "development" ) && developer.GetInteger() == 0 ) { + return; + } + + static int giveNum = 0; + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player ) { + const idKeyValue *kv = spawnArgs.MatchPrefix( "item", NULL ); + while ( kv ) { + const idDict *dict = gameLocal.FindEntityDefDict( kv->GetValue(), false ); + if ( dict ) { + idDict d2; + d2.Copy( *dict ); + d2.Set( "name", va( "givenitem_%i", giveNum++ ) ); + idEntity *ent = NULL; + if ( gameLocal.SpawnEntityDef( d2, &ent ) && ent && ent->IsType( idItem::Type ) ) { + idItem *item = static_cast(ent); + item->GiveToPlayer( gameLocal.GetLocalPlayer() ); + } + } + kv = spawnArgs.MatchPrefix( "item", kv ); + } + } +} + +/* +=============================================================================== + +idTarget_SetModel + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetModel ) + EVENT( EV_Activate, idTarget_SetModel::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SetModel::Spawn +================ +*/ +void idTarget_SetModel::Spawn( void ) { + const char *model; + + model = spawnArgs.GetString( "newmodel" ); + if ( declManager->FindType( DECL_MODELDEF, model, false ) == NULL ) { + // precache the render model + renderModelManager->FindModel( model ); + // precache .cm files only + collisionModelManager->LoadModel( model, true ); + } +} + +/* +================ +idTarget_SetModel::Event_Activate +================ +*/ +void idTarget_SetModel::Event_Activate( idEntity *activator ) { + for( int i = 0; i < targets.Num(); i++ ) { + idEntity *ent = targets[ i ].GetEntity(); + if ( ent ) { + ent->SetModel( spawnArgs.GetString( "newmodel" ) ); + } + } +} + + +/* +=============================================================================== + +idTarget_SetInfluence + +=============================================================================== +*/ + +const idEventDef EV_RestoreInfluence( "" ); +const idEventDef EV_GatherEntities( "" ); +const idEventDef EV_Flash( "", "fd" ); +const idEventDef EV_ClearFlash( "", "f" ); + +CLASS_DECLARATION( idTarget, idTarget_SetInfluence ) + EVENT( EV_Activate, idTarget_SetInfluence::Event_Activate ) + EVENT( EV_RestoreInfluence, idTarget_SetInfluence::Event_RestoreInfluence ) + EVENT( EV_GatherEntities, idTarget_SetInfluence::Event_GatherEntities ) + EVENT( EV_Flash, idTarget_SetInfluence::Event_Flash ) + EVENT( EV_ClearFlash, idTarget_SetInfluence::Event_ClearFlash ) +END_CLASS + +/* +================ +idTarget_SetInfluence::idTarget_SetInfluence +================ +*/ +idTarget_SetInfluence::idTarget_SetInfluence( void ) { + flashIn = 0.0f; + flashOut = 0.0f; + delay = 0.0f; + switchToCamera = NULL; + soundFaded = false; + restoreOnTrigger = false; +} + +/* +================ +idTarget_SetInfluence::Save +================ +*/ +void idTarget_SetInfluence::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( lightList.Num() ); + for( i = 0; i < lightList.Num(); i++ ) { + savefile->WriteInt( lightList[ i ] ); + } + + savefile->WriteInt( guiList.Num() ); + for( i = 0; i < guiList.Num(); i++ ) { + savefile->WriteInt( guiList[ i ] ); + } + + savefile->WriteInt( soundList.Num() ); + for( i = 0; i < soundList.Num(); i++ ) { + savefile->WriteInt( soundList[ i ] ); + } + + savefile->WriteInt( genericList.Num() ); + for( i = 0; i < genericList.Num(); i++ ) { + savefile->WriteInt( genericList[ i ] ); + } + + savefile->WriteFloat( flashIn ); + savefile->WriteFloat( flashOut ); + + savefile->WriteFloat( delay ); + + savefile->WriteString( flashInSound ); + savefile->WriteString( flashOutSound ); + + savefile->WriteObject( switchToCamera ); + + savefile->WriteFloat( fovSetting.GetStartTime() ); + savefile->WriteFloat( fovSetting.GetDuration() ); + savefile->WriteFloat( fovSetting.GetStartValue() ); + savefile->WriteFloat( fovSetting.GetEndValue() ); + + savefile->WriteBool( soundFaded ); + savefile->WriteBool( restoreOnTrigger ); +} + +/* +================ +idTarget_SetInfluence::Restore +================ +*/ +void idTarget_SetInfluence::Restore( idRestoreGame *savefile ) { + int i, num; + int itemNum; + float set; + + savefile->ReadInt( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadInt( itemNum ); + lightList.Append( itemNum ); + } + + savefile->ReadInt( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadInt( itemNum ); + guiList.Append( itemNum ); + } + + savefile->ReadInt( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadInt( itemNum ); + soundList.Append( itemNum ); + } + + savefile->ReadInt( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadInt( itemNum ); + genericList.Append( itemNum ); + } + + savefile->ReadFloat( flashIn ); + savefile->ReadFloat( flashOut ); + + savefile->ReadFloat( delay ); + + savefile->ReadString( flashInSound ); + savefile->ReadString( flashOutSound ); + + savefile->ReadObject( reinterpret_cast( switchToCamera ) ); + + savefile->ReadFloat( set ); + fovSetting.SetStartTime( set ); + savefile->ReadFloat( set ); + fovSetting.SetDuration( set ); + savefile->ReadFloat( set ); + fovSetting.SetStartValue( set ); + savefile->ReadFloat( set ); + fovSetting.SetEndValue( set ); + + savefile->ReadBool( soundFaded ); + savefile->ReadBool( restoreOnTrigger ); +} + +/* +================ +idTarget_SetInfluence::Spawn +================ +*/ +void idTarget_SetInfluence::Spawn() { + PostEventMS( &EV_GatherEntities, 0 ); + flashIn = spawnArgs.GetFloat( "flashIn", "0" ); + flashOut = spawnArgs.GetFloat( "flashOut", "0" ); + flashInSound = spawnArgs.GetString( "snd_flashin" ); + flashOutSound = spawnArgs.GetString( "snd_flashout" ); + delay = spawnArgs.GetFloat( "delay" ); + soundFaded = false; + restoreOnTrigger = false; + + // always allow during cinematics + cinematic = true; +} + +/* +================ +idTarget_SetInfluence::Event_Flash +================ +*/ +void idTarget_SetInfluence::Event_Flash( float flash, int out ) { + idPlayer *player = gameLocal.GetLocalPlayer(); + player->playerView.Fade( idVec4( 1, 1, 1, 1 ), static_cast(flash) ); + const idSoundShader *shader = NULL; + if ( !out && flashInSound.Length() ){ + shader = declManager->FindSound( flashInSound ); + player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL ); + } else if ( out && ( flashOutSound.Length() || flashInSound.Length() ) ) { + shader = declManager->FindSound( flashOutSound.Length() ? flashOutSound : flashInSound ); + player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL ); + } + PostEventSec( &EV_ClearFlash, flash, flash ); +} + + +/* +================ +idTarget_SetInfluence::Event_ClearFlash +================ +*/ +void idTarget_SetInfluence::Event_ClearFlash( float flash ) { + idPlayer *player = gameLocal.GetLocalPlayer(); + player->playerView.Fade( vec4_zero , static_cast(flash) ); +} +/* +================ +idTarget_SetInfluence::Event_GatherEntities +================ +*/ +void idTarget_SetInfluence::Event_GatherEntities() { + int i, listedEntities; + idEntity *entityList[ MAX_GENTITIES ]; + +// bool demonicOnly = spawnArgs.GetBool( "effect_demonic" ); + bool lights = spawnArgs.GetBool( "effect_lights" ); + bool sounds = spawnArgs.GetBool( "effect_sounds" ); + bool guis = spawnArgs.GetBool( "effect_guis" ); + bool models = spawnArgs.GetBool( "effect_models" ); + bool vision = spawnArgs.GetBool( "effect_vision" ); + bool targetsOnly = spawnArgs.GetBool( "targetsOnly" ); + + lightList.Clear(); + guiList.Clear(); + soundList.Clear(); + + if ( spawnArgs.GetBool( "effect_all" ) ) { + lights = sounds = guis = models = vision = true; + } + + if ( targetsOnly ) { + listedEntities = targets.Num(); + for ( i = 0; i < listedEntities; i++ ) { + entityList[i] = targets[i].GetEntity(); + } + } else { + float radius = spawnArgs.GetFloat( "radius" ); + listedEntities = gameLocal.EntitiesWithinRadius( GetPhysics()->GetOrigin(), radius, entityList, MAX_GENTITIES ); + } + + for( i = 0; i < listedEntities; i++ ) { + idEntity *ent = entityList[ i ]; + if ( ent ) { + if ( lights && ent->IsType( idLight::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) { + lightList.Append( ent->entityNumber ); + continue; + } + if ( sounds && ent->IsType( idSound::Type ) && ent->spawnArgs.FindKey( "snd_demonic" ) ) { + soundList.Append( ent->entityNumber ); + continue; + } + if ( guis && ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ 0 ] && ent->spawnArgs.FindKey( "gui_demonic" ) ) { + guiList.Append( ent->entityNumber ); + continue; + } + if ( ent->IsType( idStaticEntity::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) { + genericList.Append( ent->entityNumber ); + continue; + } + } + } + idStr temp; + temp = spawnArgs.GetString( "switchToView" ); + switchToCamera = ( temp.Length() ) ? gameLocal.FindEntity( temp ) : NULL; + +} + +/* +================ +idTarget_SetInfluence::Event_Activate +================ +*/ +void idTarget_SetInfluence::Event_Activate( idEntity *activator ) { + int i, j; + idEntity *ent; + idLight *light; + idSound *sound; + idStaticEntity *generic; + const char *parm; + const char *skin; + bool update; + idVec3 color; + idVec4 colorTo; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + + if ( spawnArgs.GetBool( "triggerActivate" ) ) { + if ( restoreOnTrigger ) { + ProcessEvent( &EV_RestoreInfluence ); + restoreOnTrigger = false; + return; + } + restoreOnTrigger = true; + } + + float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" ); + + if ( delay > 0.0f ) { + PostEventSec( &EV_Activate, delay, activator ); + delay = 0.0f; + // start any sound fading now + if ( fadeTime ) { + gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime ); + soundFaded = true; + } + return; + } else if ( fadeTime && !soundFaded ) { + gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime ); + soundFaded = true; + } + + if ( spawnArgs.GetBool( "triggerTargets" ) ) { + ActivateTargets( activator ); + } + + if ( flashIn ) { + PostEventSec( &EV_Flash, 0.0f, flashIn, 0 ); + } + + parm = spawnArgs.GetString( "snd_influence" ); + if ( parm && *parm ) { + PostEventSec( &EV_StartSoundShader, flashIn, parm, SND_CHANNEL_ANY ); + } + + if ( switchToCamera ) { + switchToCamera->PostEventSec( &EV_Activate, flashIn + 0.05f, this ); + } + + int fov = spawnArgs.GetInt( "fov" ); + if ( fov ) { + fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "fovTime" ) ), player->DefaultFov(), fov ); + BecomeActive( TH_THINK ); + } + + for ( i = 0; i < genericList.Num(); i++ ) { + ent = gameLocal.entities[genericList[i]]; + if ( ent == NULL ) { + continue; + } + generic = static_cast( ent ); + color = generic->spawnArgs.GetVector( "color_demonic" ); + colorTo.Set( color.x, color.y, color.z, 1.0f ); + generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); + } + + for ( i = 0; i < lightList.Num(); i++ ) { + ent = gameLocal.entities[lightList[i]]; + if ( ent == NULL || !ent->IsType( idLight::Type ) ) { + continue; + } + light = static_cast(ent); + parm = light->spawnArgs.GetString( "mat_demonic" ); + if ( parm && *parm ) { + light->SetShader( parm ); + } + + color = light->spawnArgs.GetVector( "_color" ); + color = light->spawnArgs.GetVector( "color_demonic", color.ToString() ); + colorTo.Set( color.x, color.y, color.z, 1.0f ); + light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); + } + + for ( i = 0; i < soundList.Num(); i++ ) { + ent = gameLocal.entities[soundList[i]]; + if ( ent == NULL || !ent->IsType( idSound::Type ) ) { + continue; + } + sound = static_cast(ent); + parm = sound->spawnArgs.GetString( "snd_demonic" ); + if ( parm && *parm ) { + if ( sound->spawnArgs.GetBool( "overlayDemonic" ) ) { + sound->StartSound( "snd_demonic", SND_CHANNEL_DEMONIC, 0, false, NULL ); + } else { + sound->StopSound( SND_CHANNEL_ANY, false ); + sound->SetSound( parm ); + } + } + } + + for ( i = 0; i < guiList.Num(); i++ ) { + ent = gameLocal.entities[guiList[i]]; + if ( ent == NULL || ent->GetRenderEntity() == NULL ) { + continue; + } + update = false; + for ( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { + if ( ent->GetRenderEntity()->gui[ j ] && ent->spawnArgs.FindKey( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ) ) { + ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ), true ); + update = true; + } + } + + if ( update ) { + ent->UpdateVisuals(); + ent->Present(); + } + } + + player->SetInfluenceLevel( spawnArgs.GetInt( "influenceLevel" ) ); + + int snapAngle = spawnArgs.GetInt( "snapAngle" ); + if ( snapAngle ) { + idAngles ang( 0, snapAngle, 0 ); + player->SetViewAngles( ang ); + player->SetAngles( ang ); + } + + if ( spawnArgs.GetBool( "effect_vision" ) ) { + parm = spawnArgs.GetString( "mtrVision" ); + skin = spawnArgs.GetString( "skinVision" ); + player->SetInfluenceView( parm, skin, spawnArgs.GetInt( "visionRadius" ), this ); + } + + parm = spawnArgs.GetString( "mtrWorld" ); + if ( parm && *parm ) { + gameLocal.SetGlobalMaterial( declManager->FindMaterial( parm ) ); + } + + if ( !restoreOnTrigger ) { + PostEventMS( &EV_RestoreInfluence, SEC2MS( spawnArgs.GetFloat( "time" ) ) ); + } +} + +/* +================ +idTarget_SetInfluence::Think +================ +*/ +void idTarget_SetInfluence::Think( void ) { + if ( thinkFlags & TH_THINK ) { + idPlayer *player = gameLocal.GetLocalPlayer(); + player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) ); + if ( fovSetting.IsDone( gameLocal.time ) ) { + if ( !spawnArgs.GetBool( "leaveFOV" ) ) { + player->SetInfluenceFov( 0 ); + } + BecomeInactive( TH_THINK ); + } + } else { + BecomeInactive( TH_ALL ); + } +} + + +/* +================ +idTarget_SetInfluence::Event_RestoreInfluence +================ +*/ +void idTarget_SetInfluence::Event_RestoreInfluence() { + int i, j; + idEntity *ent; + idLight *light; + idSound *sound; + idStaticEntity *generic; + bool update; + idVec3 color; + idVec4 colorTo; + + if ( flashOut ) { + PostEventSec( &EV_Flash, 0.0f, flashOut, 1 ); + } + + if ( switchToCamera ) { + switchToCamera->PostEventMS( &EV_Activate, 0, this ); + } + + for ( i = 0; i < genericList.Num(); i++ ) { + ent = gameLocal.entities[genericList[i]]; + if ( ent == NULL ) { + continue; + } + generic = static_cast( ent ); + colorTo.Set( 1.0f, 1.0f, 1.0f, 1.0f ); + generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); + } + + for ( i = 0; i < lightList.Num(); i++ ) { + ent = gameLocal.entities[lightList[i]]; + if ( ent == NULL || !ent->IsType( idLight::Type ) ) { + continue; + } + light = static_cast(ent); + if ( !light->spawnArgs.GetBool( "leave_demonic_mat" ) ) { + const char *texture = light->spawnArgs.GetString( "texture", "lights/squarelight1" ); + light->SetShader( texture ); + } + color = light->spawnArgs.GetVector( "_color" ); + colorTo.Set( color.x, color.y, color.z, 1.0f ); + light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); + } + + for ( i = 0; i < soundList.Num(); i++ ) { + ent = gameLocal.entities[soundList[i]]; + if ( ent == NULL || !ent->IsType( idSound::Type ) ) { + continue; + } + sound = static_cast(ent); + sound->StopSound( SND_CHANNEL_ANY, false ); + sound->SetSound( sound->spawnArgs.GetString( "s_shader" ) ); + } + + for ( i = 0; i < guiList.Num(); i++ ) { + ent = gameLocal.entities[guiList[i]]; + if ( ent == NULL || GetRenderEntity() == NULL ) { + continue; + } + update = false; + for( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { + if ( ent->GetRenderEntity()->gui[ j ] ) { + ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui" : va( "gui%d", j+1 ) ) ); + update = true; + } + } + if ( update ) { + ent->UpdateVisuals(); + ent->Present(); + } + } + + idPlayer *player = gameLocal.GetLocalPlayer(); + player->SetInfluenceLevel( 0 ); + player->SetInfluenceView( NULL, NULL, 0.0f, NULL ); + player->SetInfluenceFov( 0 ); + gameLocal.SetGlobalMaterial( NULL ); + float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" ); + if ( fadeTime ) { + gameSoundWorld->FadeSoundClasses( 0, 0.0f, fadeTime / 2.0f ); + } + +} + +/* +=============================================================================== + +idTarget_SetKeyVal + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetKeyVal ) + EVENT( EV_Activate, idTarget_SetKeyVal::Event_Activate ) +END_CLASS + +/* +================ +idTarget_SetKeyVal::Event_Activate +================ +*/ +void idTarget_SetKeyVal::Event_Activate( idEntity *activator ) { + int i; + idStr key, val; + idEntity *ent; + const idKeyValue *kv; + int n; + + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent ) { + kv = spawnArgs.MatchPrefix("keyval"); + while ( kv ) { + n = kv->GetValue().Find( ";" ); + if ( n > 0 ) { + key = kv->GetValue().Left( n ); + val = kv->GetValue().Right( kv->GetValue().Length() - n - 1 ); + ent->spawnArgs.Set( key, val ); + for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { + if ( ent->GetRenderEntity()->gui[ j ] ) { + if ( idStr::Icmpn( key, "gui_", 4 ) == 0 ) { + ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); + ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time ); + } + } + } + } + kv = spawnArgs.MatchPrefix( "keyval", kv ); + } + ent->UpdateChangeableSpawnArgs( NULL ); + ent->UpdateVisuals(); + ent->Present(); + } + } +} + +/* +=============================================================================== + +idTarget_SetFov + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_SetFov ) + EVENT( EV_Activate, idTarget_SetFov::Event_Activate ) +END_CLASS + + +/* +================ +idTarget_SetFov::Save +================ +*/ +void idTarget_SetFov::Save( idSaveGame *savefile ) const { + + savefile->WriteFloat( fovSetting.GetStartTime() ); + savefile->WriteFloat( fovSetting.GetDuration() ); + savefile->WriteFloat( fovSetting.GetStartValue() ); + savefile->WriteFloat( fovSetting.GetEndValue() ); +} + +/* +================ +idTarget_SetFov::Restore +================ +*/ +void idTarget_SetFov::Restore( idRestoreGame *savefile ) { + float setting; + + savefile->ReadFloat( setting ); + fovSetting.SetStartTime( setting ); + savefile->ReadFloat( setting ); + fovSetting.SetDuration( setting ); + savefile->ReadFloat( setting ); + fovSetting.SetStartValue( static_cast(setting) ); + savefile->ReadFloat( setting ); + fovSetting.SetEndValue( static_cast(setting) ); + + fovSetting.GetCurrentValue( gameLocal.time ); +} + +/* +================ +idTarget_SetFov::Event_Activate +================ +*/ +void idTarget_SetFov::Event_Activate( idEntity *activator ) { + // always allow during cinematics + cinematic = true; + + idPlayer *player = gameLocal.GetLocalPlayer(); + fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "time" ) ), static_cast(player ? player->DefaultFov() : g_fov.GetFloat()), static_cast(spawnArgs.GetFloat( "fov" )) ); + BecomeActive( TH_THINK ); +} + +/* +================ +idTarget_SetFov::Think +================ +*/ +void idTarget_SetFov::Think( void ) { + if ( thinkFlags & TH_THINK ) { + idPlayer *player = gameLocal.GetLocalPlayer(); + player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) ); + if ( fovSetting.IsDone( gameLocal.time ) ) { + player->SetInfluenceFov( 0.0f ); + BecomeInactive( TH_THINK ); + } + } else { + BecomeInactive( TH_ALL ); + } +} + +/* +=============================================================================== + +idTarget_CallObjectFunction + +Tels: + +If "pass_self" is true, the first argument of the called object function is the +triggered entity. This is useful for teleportTo(target), for instance. + +If "pass_activator" is true, the first argument of the called object function +is the entity that caused the trigger. +This is useful for atdm:voice, for instance. + +If "pass_self" and "pass_activator" are true, then the order of arguments +is first "target", then as second argument "activator". + +Note that the method you want to call needs to have exactly the number +of arguments, e.g. zero (pass_self and pass_activator false), 1 (pass_self +or pass_activator true) or two (both are true). + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_CallObjectFunction ) + EVENT( EV_Activate, idTarget_CallObjectFunction::Event_Activate ) +END_CLASS + +/* +================ +idTarget_CallObjectFunction::Event_Activate +================ +*/ +void idTarget_CallObjectFunction::Event_Activate( idEntity *activator ) { + int i; + idEntity *ent; + const function_t *func; + const char *funcName; + idThread *thread; + + funcName = spawnArgs.GetString( "call" ); + // we delay each post by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget + float wait = spawnArgs.GetFloat ( "wait", "0"); + float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); + float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); + float delay = spawnArgs.GetFloat ( "delay", "0"); + bool pass_self = spawnArgs.GetBool ( "pass_self", "0"); + bool pass_activator = spawnArgs.GetBool ( "pass_activator", "0"); + + // avoid a negative delay + if (wait < 0) { wait = 0; } + if (delay < 0) { delay = 0; } + // wait_add can be negative, we will later make sure that wait is never negative + // + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("%s: Calling object function %s on %i targets.\r", name.c_str(), funcName, targets.Num() ); + + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent && ent->scriptObject.HasObject() ) { + func = ent->scriptObject.GetFunction( funcName ); + if ( !func ) { + gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + int numParams = 1; + if (pass_self) { numParams ++; } + if (pass_activator) { numParams ++; } + + if ( func->type->NumParameters() != numParams ) { + gameLocal.Error( "Function '%s' on entity '%s' has the wrong number of parameters for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { + gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Starting call for target #%i\r", i); + // create a thread and call the function + thread = new idThread(); + if (numParams == 1) { + thread->CallFunction( ent, func, true ); + } else if (numParams == 2) { + if (pass_self) { + thread->CallFunctionArgs( func, true, "ee", ent, this ); + } else { + thread->CallFunctionArgs( func, true, "ee", ent, activator ); + } + } else { // if (numParams == 3) { + thread->CallFunctionArgs( func, true, "eee", ent, this, activator ); + } + thread->DelayedStart( delay ); + + delay += wait; + wait += wait_add; + wait *= wait_mul; + // avoid a negative delay + if (wait < 0) { wait = 0; } + } + else + { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No entity or no script object on target #%i.\r", i ); + } + } +} + +/* +=============================================================================== + +Tels idTarget_PostScriptEvent + +This locks up the named event and then posts it with the specified "delay" +for each target. The delay is increased for each target as specified with +the "wait" spawnarg. + +If "pass_self" is true, the first argument of the posted event is the +triggered entity. This is useful for target->teleportTo(triggeredEntity). + +If "pass_activator" is true, the first argument of the posted event is the +entity that activated the trigger. This is useful for target->AddItemToInv(activator). + +If "propagate_to_team" is true, then the event will be posted to all members +of the team that the target is a member of. Useful for posting events +to entites that have other entities bound to them like holders with lights. + +In case the named event cannot be found, this tries to call the script +object function on each target entity, provided the entity in question +has a script object (if not, a warning is issued) and the method +there exists (if not, an error is thrown). +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_PostScriptEvent ) + EVENT( EV_Activate, idTarget_PostScriptEvent::Event_Activate ) +END_CLASS + +void idTarget_PostScriptEvent::TryPostOrCall( idEntity *ent, idEntity *activator, const idEventDef *ev, const char* funcName, const bool pass_self, const bool pass_activator, const float delay) +{ + const function_t *func; + + if (ev) { + if (pass_self) { + ent->PostEventSec( ev, delay, this ); + } + else if (pass_activator && !pass_self) { + ent->PostEventSec( ev, delay, activator ); + } else { + // both pass_self and pass_activator + ent->PostEventSec( ev, delay, this, activator ); + } + } else { + // try the script object function + if ( ent->scriptObject.HasObject() ) { + func = ent->scriptObject.GetFunction( funcName ); + if ( !func ) { + gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + int numParams = 1; + if (pass_self || pass_activator) { numParams = 2; } + if (pass_self && pass_activator) { numParams = 3; } + + if ( func->type->NumParameters() != numParams ) { + gameLocal.Error( "Function '%s' on entity '%s' has the wrong number of parameters for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + + if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { + gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); + } + + // create a thread and call the function + idThread *thread = new idThread(); + if (numParams == 1) { + thread->CallFunction( ent, func, true ); + } else if (numParams == 2) { + thread->CallFunctionArgs( func, true, "ee", ent, this ); + } else { + thread->CallFunctionArgs( func, true, "eee", ent, this, activator ); + } + thread->DelayedStart( delay ); + } + else + { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No script object on target %s.\r", ent->name.c_str() ); + } + } +} + +/* +================ +idTarget_PostScriptEvent::Event_Activate +================ +*/ + +void idTarget_PostScriptEvent::Event_Activate( idEntity *activator ) { + int i; + idEntity *ent; + idEntity *NextEnt; + + // we delay each post by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget + float wait = spawnArgs.GetFloat ( "wait", "0"); + float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); + float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); + float delay = spawnArgs.GetFloat ( "delay", "0"); + const char* evName = spawnArgs.GetString( "event" ); + bool pass_self = spawnArgs.GetBool ( "pass_self", "0"); + bool pass_activator = spawnArgs.GetBool ( "pass_activator", "0"); + bool do_team = spawnArgs.GetBool ( "propagate_to_team", "0"); + + // avoid a negative delay + if (wait < 0) { wait = 0; } + if (delay < 0) { delay = 0; } + // wait_add can be negative, we will later make sure that wait is never negative + + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("%s: Posting event %s on %i targets (team: %i, pass_self: %i).\r", name.c_str(), evName, targets.Num(), do_team, pass_self ); + const idEventDef *ev = idEventDef::FindEvent( evName ); + + if ( !ev ) { + gameLocal.Error( "Unknown event '%s' on entity '%s'", evName, name.c_str() ); + } + + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + + if (!ent) { continue; } + + // DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Posting event on target #%i.\r", i); + if (do_team) { + NextEnt = ent; + idEntity* bind_master = ent->GetBindMaster(); + if (bind_master) { + NextEnt = bind_master; + } + + while ( NextEnt != NULL ) { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING(" Posting event on team member %s of target #%i.\r", NextEnt->GetName(), i); + TryPostOrCall( NextEnt, activator, ev, evName, pass_self, pass_activator, delay); + /* get next Team member */ + NextEnt = NextEnt->GetNextTeamEntity(); + } + + } else { + // we should post only to the target directly + TryPostOrCall( ent, activator, ev, evName, pass_self, pass_activator, delay); + } + + delay += wait; + wait += wait_add; + wait *= wait_mul; + // avoid a negative delay + if (wait < 0) { wait = 0; } + } // end for all targets +} + + +/* +=============================================================================== + +idTarget_EnableLevelWeapons + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_EnableLevelWeapons ) + EVENT( EV_Activate, idTarget_EnableLevelWeapons::Event_Activate ) +END_CLASS + +/* +================ +idTarget_EnableLevelWeapons::Event_Activate +================ +*/ +void idTarget_EnableLevelWeapons::Event_Activate( idEntity *activator ) { + int i; + const char *weap; + + gameLocal.world->spawnArgs.SetBool( "no_Weapons", spawnArgs.GetBool( "disable" ) ); + + if ( spawnArgs.GetBool( "disable" ) ) { + for( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] ) { + gameLocal.entities[ i ]->ProcessEvent( &EV_Player_DisableWeapon ); + } + } + } else { + weap = spawnArgs.GetString( "weapon" ); + for( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] ) { + gameLocal.entities[ i ]->ProcessEvent( &EV_Player_EnableWeapon ); + if ( weap && weap[ 0 ] ) { + gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, weap ); + } + } + } + } +} + +/* +=============================================================================== + +idTarget_RemoveWeapons + +=============================================================================== +*/ + +CLASS_DECLARATION( idTarget, idTarget_RemoveWeapons ) +EVENT( EV_Activate, idTarget_RemoveWeapons::Event_Activate ) +END_CLASS + +/* +================ +idTarget_RemoveWeapons::Event_Activate +================ +*/ +void idTarget_RemoveWeapons::Event_Activate( idEntity *activator ) { + for( int i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] ) { + idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] ); + const idKeyValue *kv = spawnArgs.MatchPrefix( "weapon", NULL ); + while ( kv ) { + player->RemoveWeapon( kv->GetValue() ); + kv = spawnArgs.MatchPrefix( "weapon", kv ); + } + player->SelectWeapon( player->weapon_fists, true ); + } + } +} + + +/* +=============================================================================== + +idTarget_FadeSoundClass + +=============================================================================== +*/ + +const idEventDef EV_RestoreVolume( "" ); +CLASS_DECLARATION( idTarget, idTarget_FadeSoundClass ) +EVENT( EV_Activate, idTarget_FadeSoundClass::Event_Activate ) +EVENT( EV_RestoreVolume, idTarget_FadeSoundClass::Event_RestoreVolume ) +END_CLASS + +/* +================ +idTarget_FadeSoundClass::Event_Activate +================ +*/ +void idTarget_FadeSoundClass::Event_Activate( idEntity *activator ) { + float fadeTime = spawnArgs.GetFloat( "fadeTime" ); + float fadeDB = spawnArgs.GetFloat( "fadeDB" ); + float fadeDuration = spawnArgs.GetFloat( "fadeDuration" ); + int fadeClass = spawnArgs.GetInt( "fadeClass" ); + // start any sound fading now + if ( fadeTime ) { + gameSoundWorld->FadeSoundClasses( fadeClass, spawnArgs.GetBool( "fadeIn" ) ? fadeDB : 0.0f - fadeDB, fadeTime ); + if ( fadeDuration ) { + PostEventSec( &EV_RestoreVolume, fadeDuration ); + } + } +} + +/* +================ +idTarget_FadeSoundClass::Event_RestoreVolume +================ +*/ +void idTarget_FadeSoundClass::Event_RestoreVolume() { + float fadeTime = spawnArgs.GetFloat( "fadeTime" ); + float fadeDB = spawnArgs.GetFloat( "fadeDB" ); +// int fadeClass = spawnArgs.GetInt( "fadeClass" ); + // restore volume + gameSoundWorld->FadeSoundClasses( 0, fadeDB, fadeTime ); +} + +/* +=============================================================================== + +CTarget_AddObjectives + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_AddObjectives ) + EVENT( EV_Activate, CTarget_AddObjectives::Event_Activate ) +END_CLASS + +void CTarget_AddObjectives::Spawn( void ) +{ + if( !spawnArgs.GetBool( "wait_for_trigger" ) ) + PostEventMS( &EV_Activate, 0, this ); +} + +void CTarget_AddObjectives::Event_Activate( idEntity *activator ) +{ + int SetVal(-1); + + if( gameLocal.m_MissionData ) + { + SetVal = gameLocal.m_MissionData->AddObjsFromEnt( this ); + } + + // greebo: If the entity is not the world entity, notify the player + if (spawnArgs.GetBool("wait_for_trigger") && activator != gameLocal.world) + { + gameLocal.m_MissionData->Event_NewObjective(); + } + + spawnArgs.Set( "obj_num_offset", va("%d", SetVal) ); +} + +/* +=============================================================================== + +CTarget_SetObjectiveState + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_SetObjectiveState ) + EVENT( EV_Activate, CTarget_SetObjectiveState::Event_Activate ) +END_CLASS + +void CTarget_SetObjectiveState::Spawn( void ) +{ + if( !spawnArgs.GetBool( "wait_for_trigger" ) ) + { + // Immediately fire the activate event, as we + // don't need to wait for a trigger event + PostEventMS(&EV_Activate, 0, this); + } +} + +void CTarget_SetObjectiveState::Event_Activate( idEntity *activator ) +{ + // greebo: Get the state we should set the objectives to + int state = spawnArgs.GetInt("obj_state", "0"); + + // Find all values that match the given prefix + const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); + + // greebo: Cycle through all matching spawnargs + while (keyVal != NULL) { + int objId = atoi(keyVal->GetValue().c_str()); + + if (objId > 0) { + // "Unlock" the objective first, if desired + if (spawnArgs.GetBool("unlatch_irreversible_objectives", "1")) + { + gameLocal.m_MissionData->UnlatchObjective(objId-1); + } + + // Now set the completion state + gameLocal.m_MissionData->SetCompletionState(objId-1, state); + } + else { + gameLocal.Warning("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); + } + + // greebo: Lookup the next matching spawnarg + keyVal = spawnArgs.MatchPrefix("obj_id", keyVal); + } +} + +/* +=============================================================================== + +CTarget_SetObjectiveVisibility + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_SetObjectiveVisibility ) + EVENT( EV_Activate, CTarget_SetObjectiveVisibility::Event_Activate ) +END_CLASS + +void CTarget_SetObjectiveVisibility::Spawn( void ) +{ + if( !spawnArgs.GetBool( "wait_for_trigger" ) ) + { + // Immediately fire the activate event, as we + // don't need to wait for a trigger event + PostEventMS(&EV_Activate, 0, this); + } +} + +void CTarget_SetObjectiveVisibility::Event_Activate( idEntity *activator ) +{ + // Get the visibility we should set the objectives to + bool bVisible = spawnArgs.GetBool("obj_visibility", "0"); + + // Find all values that match the given prefix + const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); + + // Cycle through all matching spawnargs + for (const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); keyVal != NULL; + keyVal = spawnArgs.MatchPrefix("obj_id", keyVal)) + { + int objId = atoi(keyVal->GetValue().c_str()); + + if (objId > 0) + { + gameLocal.m_MissionData->SetObjectiveVisibility(objId - 1, bVisible); + } + else + { + gameLocal.Warning("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); + DM_LOG(LC_OBJECTIVES, LT_ERROR)LOGSTRING("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); + } + } +} + +/* +=============================================================================== + +CTarget_SetObjectiveComponentState + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_SetObjectiveComponentState ) + EVENT( EV_Activate, CTarget_SetObjectiveComponentState::Event_Activate ) +END_CLASS + +void CTarget_SetObjectiveComponentState::Spawn( void ) +{ + if( !spawnArgs.GetBool( "wait_for_trigger" ) ) + { + // Immediately fire the activate event, as we + // don't need to wait for a trigger event + PostEventMS(&EV_Activate, 0, this); + } +} + +void CTarget_SetObjectiveComponentState::Event_Activate( idEntity *activator ) +{ + // Get the state we should set the objectives to + bool state = spawnArgs.GetBool("comp_state", "0"); + + // Find all values that match the given prefix + const idKeyValue* keyVal = spawnArgs.MatchPrefix("comp_id"); + + // Cycle through all matching spawnargs + while (keyVal != NULL) + { + idStr StringID = keyVal->GetValue(); + idStr objIDStr(StringID), compIDStr(StringID); + + objIDStr.StripTrailing(","); + compIDStr.StripLeading(","); + + int objId = atoi( objIDStr.c_str() ); + int compId = atoi( compIDStr.c_str() ); + + if (objId > 0 && compId > 0) + gameLocal.m_MissionData->SetComponentState_Ext(objId, compId, state); + else + gameLocal.Warning("Invalid objective component ID %s on CTarget_SetObjectiveState %s\n", StringID.c_str(), name.c_str()); + + // Lookup the next matching spawnarg + keyVal = spawnArgs.MatchPrefix("comp_id", keyVal); + } +} + +/* +=============================================================================== + +CTarget_StartConversation + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_StartConversation ) + EVENT( EV_Activate, CTarget_StartConversation::Event_Activate ) +END_CLASS + +void CTarget_StartConversation::Spawn( void ) +{ + if (spawnArgs.FindKey("conversation") == NULL) + { + gameLocal.Warning("Target %s has no 'conversation' spawnarg set!", name.c_str()); + return; + } +} + +void CTarget_StartConversation::Event_Activate( idEntity *activator ) +{ + idStr conversationName = spawnArgs.GetString("conversation"); + + if (conversationName.IsEmpty()) + { + gameLocal.Printf("Target %s has no 'conversation' spawnarg set!\n", name.c_str()); + return; + } + + // Try to find the conversation + int convIndex = gameLocal.m_ConversationSystem->GetConversationIndex(conversationName); + + if (convIndex == -1) + { + gameLocal.Printf("Target %s references non-existent conversation %s!\n", name.c_str(), conversationName.c_str()); + return; + } + + // Pass the torch to the conversationsystem to do the rest + gameLocal.m_ConversationSystem->StartConversation(convIndex); +} + +/* +=============================================================================== + +CTarget_SetFrobable + +=============================================================================== +*/ +CLASS_DECLARATION( idTarget, CTarget_SetFrobable ) + EVENT( EV_Activate, CTarget_SetFrobable::Event_Activate ) +END_CLASS + +CTarget_SetFrobable::CTarget_SetFrobable( void ) +{ + m_bCurFrobState = false; + m_EntsSetUnfrobable.Clear(); +} + +void CTarget_SetFrobable::Spawn( void ) +{ + spawnArgs.GetBool( "start_frobable", "0", m_bCurFrobState ); + + // Set the contents to a useless trigger so that the collision model will be loaded + // FLASHLIGHT_TRIGGER seems to be the only one that doesn't do anything else we don't want + GetPhysics()->SetContents( CONTENTS_FLASHLIGHT_TRIGGER ); + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + // Disable the clipmodel for now, only enable when needed + GetPhysics()->DisableClip(); + + // If we don't start frobable, activate once and set everything to not frobable + // This saves the mapper the time of manually setting everything inside not frobable to start out with + if( !m_bCurFrobState ) + { + m_bCurFrobState = true; + PostEventMS( &EV_Activate, 0, this ); + } +} + +void CTarget_SetFrobable::Event_Activate( idEntity *activator ) +{ + idEntity *Ents[MAX_GENTITIES]; + bool bOnList(false); + + // Contents mask: + int cm = CONTENTS_SOLID | CONTENTS_CORPSE | CONTENTS_RENDERMODEL | CONTENTS_BODY | CONTENTS_FROBABLE; + + // bounding box test to get entities inside + GetPhysics()->EnableClip(); + int numEnts = gameLocal.clip.EntitiesTouchingBounds(GetPhysics()->GetAbsBounds(), cm, Ents, MAX_GENTITIES); + GetPhysics()->DisableClip(); + + // toggle frobability + m_bCurFrobState = !m_bCurFrobState; + + for (int i = 0; i < numEnts; i++) + { + idEntity* ent = Ents[i]; + + // Don't set self or the world, or the player frobable + if (ent == NULL || ent == this || + ent == gameLocal.world || ent == gameLocal.GetLocalPlayer()) + { + continue; + } + + if (ent->spawnArgs.GetBool("immune_to_target_setfrobable", "0")) + { + continue; // greebo: per-entity exclusion + } + + if( m_bCurFrobState ) + { + // Before setting something frobable, check if it is on the + // list of things we set un-frobable earlier + bOnList = false; + + for( int k=0; k < m_EntsSetUnfrobable.Num(); k++ ) + { + if( m_EntsSetUnfrobable[k] == ent->name ) + { + bOnList = true; + break; + } + } + + if( bOnList ) + ent->SetFrobable( m_bCurFrobState ); + } + else + { + // setting unfrobable + if( ent->m_bFrobable ) + { + m_EntsSetUnfrobable.AddUnique( ent->name ); + ent->SetFrobable( m_bCurFrobState ); + } + } + +// Uncomment for debugging + + idStr frobnofrob = "not frobable."; + if( m_bCurFrobState ) + frobnofrob = "frobable."; + + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_SetFrobable: Set entity %s to frob state: %s\r", Ents[i]->name.c_str(), frobnofrob.c_str() ); + + } +} + +void CTarget_SetFrobable::Save( idSaveGame *savefile ) const +{ + savefile->WriteBool( m_bCurFrobState ); + + savefile->WriteInt( m_EntsSetUnfrobable.Num() ); + for( int i=0;i < m_EntsSetUnfrobable.Num(); i++ ) + savefile->WriteString( m_EntsSetUnfrobable[i] ); +} + +void CTarget_SetFrobable::Restore( idRestoreGame *savefile ) +{ + int num; + + savefile->ReadBool( m_bCurFrobState ); + + m_EntsSetUnfrobable.Clear(); + savefile->ReadInt( num ); + m_EntsSetUnfrobable.SetNum( num ); + for( int i=0;i < num; i++ ) + savefile->ReadString( m_EntsSetUnfrobable[i] ); +} + +/* +================ +CTarget_CallScriptFunction +================ +*/ +CLASS_DECLARATION( idTarget, CTarget_CallScriptFunction ) + EVENT( EV_Activate, CTarget_CallScriptFunction::Event_Activate ) +END_CLASS + +void CTarget_CallScriptFunction::Event_Activate( idEntity *activator ) +{ + // Get the function name + idStr funcName = spawnArgs.GetString("call"); + if (funcName.IsEmpty()) + { + gameLocal.Warning("Target %s has no script function to call!", name.c_str()); + return; + } + + // Get the function + const function_t* scriptFunction = gameLocal.program.FindFunction(funcName); + if (scriptFunction == NULL) + { + // script function not found! + gameLocal.Warning("Target %s specifies non-existent script function!", funcName.c_str()); + return; + } + + bool forEach = spawnArgs.GetBool("foreach","0"); + + if (forEach) + { + // we delay each call by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget + float wait = spawnArgs.GetFloat ( "wait", "0"); + float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); + float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); + float delay = spawnArgs.GetFloat ( "delay", "0"); + + // avoid a negative delay + if (wait < 0) { wait = 0; } + if (delay < 0) { delay = 0; } + // wait_add can be negative, we will later make sure that wait is never negative + + for(int i = 0; i < targets.Num(); i++ ) + { + idEntity* ent = targets[ i ].GetEntity(); + if (!ent) + { + DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No entity for script call on target #%i.\r", i ); + continue; + } + + // each call in its own thread so they can run in parallel + idThread* thread = new idThread(); + // Call "Foo(target, activator, triggred_entity);" + thread->CallFunctionArgs( scriptFunction, true, "eee", ent, activator, this ); + // and finally start the new thread after "delay" ms: + thread->DelayedStart(delay); + + delay += wait; + wait += wait_add; + wait *= wait_mul; + // avoid a negative delay + if (wait < 0) { wait = 0; } + } + } + else + { + idThread* thread = new idThread(scriptFunction); + thread->DelayedStart(0); + } +} + +/* +================ +CTarget_ChangeLockState +================ +*/ +CLASS_DECLARATION( idTarget, CTarget_ChangeLockState ) + EVENT( EV_Activate, CTarget_ChangeLockState::Event_Activate ) +END_CLASS + +void CTarget_ChangeLockState::Event_Activate(idEntity *activator) +{ + // Find all targetted frobmovers + for (int i = 0; i < targets.Num(); i++) + { + idEntity* ent = targets[i].GetEntity(); + + if (ent == NULL) continue; + + if (ent->IsType(CBinaryFrobMover::Type)) + { + CBinaryFrobMover* frobMover = static_cast(ent); + + if (spawnArgs.GetBool("toggle", "0")) + { + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Toggling lock state of entity %s\r", ent->name.c_str()); + frobMover->ToggleLock(); + } + else if (spawnArgs.GetBool("unlock", "1")) + { + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Unlocking entity %s\r", ent->name.c_str()); + frobMover->Unlock(); + } + else + { + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Locking entity %s\r", ent->name.c_str()); + frobMover->Lock(); + } + } + } +} + +/* +================ +CTarget_ChangeTarget +================ +*/ +CLASS_DECLARATION( idTarget, CTarget_ChangeTarget ) + EVENT( EV_Activate, CTarget_ChangeTarget::Event_Activate ) +END_CLASS + +void CTarget_ChangeTarget::Event_Activate(idEntity *activator) +{ + // Get the targetted entities + for (int i = 0; i < targets.Num(); i++) + { + idEntity* ent = targets[i].GetEntity(); + + if (ent == NULL) continue; + + // Let's check if we should remove a target + idEntity* removeEnt = gameLocal.FindEntity(spawnArgs.GetString("remove")); + + if (removeEnt != NULL) + { + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeTarget: Removing target %s from %s\r", removeEnt->name.c_str(), ent->name.c_str()); + ent->RemoveTarget(removeEnt); + } + + // Let's check if we should add a target (happens after the removal) + idEntity* addEnt = gameLocal.FindEntity(spawnArgs.GetString("add")); + + if (addEnt != NULL) + { + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeTarget: Adding target %s to %s\r", addEnt->name.c_str(), ent->name.c_str()); + ent->AddTarget(addEnt); + } + } +} + +CLASS_DECLARATION( idTarget, CTarget_InterMissionTrigger ) + EVENT( EV_Activate, CTarget_InterMissionTrigger::Event_Activate ) +END_CLASS + +void CTarget_InterMissionTrigger::Event_Activate(idEntity* activator) +{ + // greebo: Get the target mission number, defaults to the next mission number (which is current+2 to get the 1-based index, see comment below) + // We don't care if this is the last mission. + int missionNum = spawnArgs.GetInt("mission"); + + if (missionNum == 0) + { + missionNum = gameLocal.m_MissionManager->GetCurrentMissionIndex() + 2; + } + + // The mission number is 0-based but the mapper can use 1-based indices for convenience => subtract 1 after reading the spawnarg. + missionNum--; + + if (missionNum < 0) + { + return; + } + + // Get the name of the activating entity, can be overridden by the spawnarg, otherwise defaults to the activator passed in + idStr activatorName = spawnArgs.GetString("activator"); + + if (activatorName.IsEmpty() && activator != NULL) + { + activatorName = activator->name; + } + + // Now register an inter-mission trigger for each target spawnarg we find on this entity + for (const idKeyValue* kv = spawnArgs.MatchPrefix("target"); kv != NULL; kv = spawnArgs.MatchPrefix("target", kv)) + { + const idStr& targetName = kv->GetValue(); + + DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Registering Inter-Mission trigger for mission %d, from %s to %s\r", missionNum, activatorName.c_str(), targetName.c_str()); + + gameLocal.AddInterMissionTrigger(missionNum, activatorName, targetName); + } +} + +/* ************************************** Target setTeam ********************************* */ + +// Tels: Can be targetted from a trigger and changes the team of all of its targets to the +// team according to the spawnarg "team". Will also cause the affected actors to re- +// evaluate their targets (so if they "see" someone, they might consider them an +// enemy, or friend now): + +CLASS_DECLARATION( idEntity, CTarget_SetTeam ) + EVENT( EV_Activate, CTarget_SetTeam::Event_Activate ) +END_CLASS + +void CTarget_SetTeam::Event_Activate(idEntity* activator) +{ + float newTeam = spawnArgs.GetFloat("team", 0); + + // for all targets + int t = targets.Num(); + for( int i = 0; i < t; i++ ) + { + idEntity *ent = targets[ i ].GetEntity(); + if ( ent ) + //if ( ent && ent->IsType(idActor::Type) ) + { + // idActor* actor = static_cast(ent); + ent->Event_SetTeam( newTeam ); + } + } +} diff --git a/game/Target.h b/game/Target.h new file mode 100644 index 000000000..5d90d74fa --- /dev/null +++ b/game/Target.h @@ -0,0 +1,649 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_TARGET_H__ +#define __GAME_TARGET_H__ + + +/* +=============================================================================== + +idTarget + +=============================================================================== +*/ + +class idTarget : public idEntity { +public: + CLASS_PROTOTYPE( idTarget ); +}; + + +/* +=============================================================================== + +idTarget_Remove + +=============================================================================== +*/ + +class idTarget_Remove : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_Remove ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_Show + +=============================================================================== +*/ + +class idTarget_Show : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_Show ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_Damage + +=============================================================================== +*/ + +class idTarget_Damage : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_Damage ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SessionCommand + +=============================================================================== +*/ + +class idTarget_SessionCommand : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SessionCommand ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_EndLevel + +=============================================================================== +*/ + +class idTarget_EndLevel : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_EndLevel ); + +private: + void Event_Activate( idEntity *activator ); + +}; + + +/* +=============================================================================== + +idTarget_WaitForButton + +=============================================================================== +*/ + +class idTarget_WaitForButton : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_WaitForButton ); + + void Think( void ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +idTarget_SetGlobalShaderTime + +=============================================================================== +*/ + +class idTarget_SetGlobalShaderTime : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetGlobalShaderTime ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SetShaderParm + +=============================================================================== +*/ + +class idTarget_SetShaderParm : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetShaderParm ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SetShaderTime + +=============================================================================== +*/ + +class idTarget_SetShaderTime : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetShaderTime ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +idTarget_FadeEntity + +=============================================================================== +*/ + +class idTarget_FadeEntity : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_FadeEntity ); + + idTarget_FadeEntity( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Think( void ); + +private: + idVec4 fadeFrom; + int fadeStart; + int fadeEnd; + + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +idTarget_LightFadeIn + +=============================================================================== +*/ + +class idTarget_LightFadeIn : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_LightFadeIn ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +idTarget_LightFadeOut + +=============================================================================== +*/ + +class idTarget_LightFadeOut : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_LightFadeOut ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +idTarget_Give + +=============================================================================== +*/ + +class idTarget_Give : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_Give ); + + void Spawn( void ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SetModel + +=============================================================================== +*/ + +class idTarget_SetModel : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetModel ); + + void Spawn( void ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SetInfluence + +=============================================================================== +*/ + +class idTarget_SetInfluence : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetInfluence ); + + idTarget_SetInfluence( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + +private: + void Event_Activate( idEntity *activator ); + void Event_RestoreInfluence(); + void Event_GatherEntities(); + void Event_Flash( float flash, int out ); + void Event_ClearFlash( float flash ); + void Think( void ); + + idList lightList; + idList guiList; + idList soundList; + idList genericList; + float flashIn; + float flashOut; + float delay; + idStr flashInSound; + idStr flashOutSound; + idEntity * switchToCamera; + idInterpolatefovSetting; + bool soundFaded; + bool restoreOnTrigger; +}; + + +/* +=============================================================================== + +idTarget_SetKeyVal + +=============================================================================== +*/ + +class idTarget_SetKeyVal : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetKeyVal ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_SetFov + +=============================================================================== +*/ + +class idTarget_SetFov : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_SetFov ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Think( void ); + +private: + idInterpolate fovSetting; + + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_CallObjectFunction + +=============================================================================== +*/ + +class idTarget_CallObjectFunction : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_CallObjectFunction ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/* +=============================================================================== + +Tels: idTarget_PostScriptEvent + +=============================================================================== +*/ + +class idTarget_PostScriptEvent : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_PostScriptEvent ); + +private: + void Event_Activate( idEntity *activator ); + void TryPostOrCall( idEntity *ent, idEntity *activator, const idEventDef *ev, const char* funcName, const bool pass_self, const bool pass_activator, const float delay); +}; + +/* +=============================================================================== + +idTarget_LockDoor + +=============================================================================== +*/ + +class idTarget_EnableLevelWeapons : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_EnableLevelWeapons ); + +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_Tip + +=============================================================================== +*/ + +class idTarget_Tip : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_Tip ); + + idTarget_Tip( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + idVec3 playerPos; + + void Event_Activate( idEntity *activator ); + void Event_TipOff( void ); + void Event_GetPlayerPos( void ); +}; + +/* +=============================================================================== + +idTarget_RemoveWeapons + +=============================================================================== +*/ +class idTarget_RemoveWeapons : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_RemoveWeapons ); +private: + void Event_Activate( idEntity *activator ); +}; + + +/* +=============================================================================== + +idTarget_FadeSoundClass + +=============================================================================== +*/ +class idTarget_FadeSoundClass : public idTarget { +public: + CLASS_PROTOTYPE( idTarget_FadeSoundClass ); +private: + void Event_Activate( idEntity *activator ); + void Event_RestoreVolume(); +}; + +/** +* CTarget_AddObjectives +* Helper entity for the objectives system. When triggered, adds the +* objectives on it into the objectives system. +* +* It sets the spawnargs "obj_num_offset" on itself for the numerical offset +* of the first objective it added, used for later addressing that objective. +**/ +class CTarget_AddObjectives : public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_AddObjectives ); +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +}; + +/** + * greebo: Target for altering the state of certain objectives. + */ +class CTarget_SetObjectiveState : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_SetObjectiveState ); +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +}; + +/** +* Target for hiding or showing certain objectives. +**/ +class CTarget_SetObjectiveVisibility : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_SetObjectiveVisibility ); +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +}; + +/** +* Target for setting the state of an objective component +**/ +class CTarget_SetObjectiveComponentState : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_SetObjectiveComponentState ); +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +}; + +/** + * greebo: Target for triggerig conversations. + */ +class CTarget_StartConversation : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_StartConversation ); +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +}; + +/** +* CTarget_SetFrobable +* Sets all items inside frobable or not when triggered +**/ +class CTarget_SetFrobable : public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_SetFrobable ); + + CTarget_SetFrobable( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + void Event_Activate( idEntity *activator ); + virtual void Spawn( void ); +private: + /** + * Current frob state, whether stuff inside has been set frobable or not + **/ + bool m_bCurFrobState; + + /** + * List of the names of entities previously set unfrobable + * This list is maintained to avoid accidentally setting anything frobable + * that was not frobable before it went in the brush + * Only ents that get added to this list will become frobable. + **/ + idStrList m_EntsSetUnfrobable; +}; + +/** + * greebo: This target calls a specific script function (with no arguments). + */ +class CTarget_CallScriptFunction : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_CallScriptFunction ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/** + * greebo: This target locks or unlocks a specific frobmover. + */ +class CTarget_ChangeLockState : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_ChangeLockState ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/** + * greebo: This target changes the targets of existing entities. + */ +class CTarget_ChangeTarget : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_ChangeTarget ); + +private: + void Event_Activate( idEntity *activator ); +}; + +/** + * greebo: This target eats incoming triggers and releases them when the next map loads. + */ +class CTarget_InterMissionTrigger : + public idTarget +{ +public: + CLASS_PROTOTYPE( CTarget_InterMissionTrigger ); + +private: + void Event_Activate(idEntity* activator); +}; + +/* +=============================================================================== + +Tels: set the team of its targets. + +=============================================================================== +*/ + +class CTarget_SetTeam : public idTarget { +public: + CLASS_PROTOTYPE( CTarget_SetTeam ); + +private: + void Event_Activate( idEntity *activator ); +}; + +#endif /* !__GAME_TARGET_H__ */ diff --git a/DarkMod/TimerManager.cpp b/game/TimerManager.cpp similarity index 86% rename from DarkMod/TimerManager.cpp rename to game/TimerManager.cpp index ce761bc63..ad838885a 100644 --- a/DarkMod/TimerManager.cpp +++ b/game/TimerManager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/TimerManager.h b/game/TimerManager.h similarity index 76% rename from DarkMod/TimerManager.h rename to game/TimerManager.h index 36f2d95ed..d3a0bb01b 100644 --- a/DarkMod/TimerManager.h +++ b/game/TimerManager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef TIMER_MANAGER_H #define TIMER_MANAGER_H diff --git a/game/Trigger.cpp b/game/Trigger.cpp new file mode 100644 index 000000000..6382a1f4b --- /dev/null +++ b/game/Trigger.cpp @@ -0,0 +1,1206 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "StimResponse/StimResponseCollection.h" + +/* +=============================================================================== + + idTrigger + +=============================================================================== +*/ + +const idEventDef EV_Enable( "enable", NULL ); +const idEventDef EV_Disable( "disable", NULL ); + +CLASS_DECLARATION( idEntity, idTrigger ) + EVENT( EV_Enable, idTrigger::Event_Enable ) + EVENT( EV_Disable, idTrigger::Event_Disable ) +END_CLASS + +/* +================ +idTrigger::DrawDebugInfo +================ +*/ +void idTrigger::DrawDebugInfo( void ) { + idMat3 axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); + idVec3 up = axis[ 2 ] * 5.0f; + idBounds viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); + idBounds viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); + idBounds box( idVec3( -4.0f, -4.0f, -4.0f ), idVec3( 4.0f, 4.0f, 4.0f ) ); + idEntity *ent; + idEntity *target; + int i; + bool show; + const function_t *func; + + viewTextBounds.ExpandSelf( 128.0f ); + viewBounds.ExpandSelf( 512.0f ); + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->GetPhysics()->GetContents() & ( CONTENTS_TRIGGER | CONTENTS_FLASHLIGHT_TRIGGER ) ) { + show = viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ); + if ( !show ) { + for( i = 0; i < ent->targets.Num(); i++ ) { + target = ent->targets[ i ].GetEntity(); + if ( target && viewBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) { + show = true; + break; + } + } + } + + if ( !show ) { + continue; + } + + gameRenderWorld->DebugBounds( colorOrange, ent->GetPhysics()->GetAbsBounds() ); + if ( viewTextBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { + gameRenderWorld->DrawText( ent->name.c_str(), ent->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 ); + gameRenderWorld->DrawText( ent->GetEntityDefName(), ent->GetPhysics()->GetAbsBounds().GetCenter() + up, 0.1f, colorWhite, axis, 1 ); + if ( ent->IsType( idTrigger::Type ) ) { + func = static_cast( ent )->GetScriptFunction(); + } else { + func = NULL; + } + + if ( func ) { + gameRenderWorld->DrawText( va( "call script '%s'", func->Name() ), ent->GetPhysics()->GetAbsBounds().GetCenter() - up, 0.1f, colorWhite, axis, 1 ); + } + } + + for( i = 0; i < ent->targets.Num(); i++ ) { + target = ent->targets[ i ].GetEntity(); + if ( target ) { + gameRenderWorld->DebugArrow( colorYellow, ent->GetPhysics()->GetAbsBounds().GetCenter(), target->GetPhysics()->GetOrigin(), 10, 0 ); + gameRenderWorld->DebugBounds( colorGreen, box, target->GetPhysics()->GetOrigin() ); + if ( viewTextBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) { + gameRenderWorld->DrawText( target->name.c_str(), target->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 ); + } + } + } + } + } +} + +/* +================ +idTrigger::Enable +================ +*/ +void idTrigger::Enable( void ) +{ + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + GetPhysics()->EnableClip(); +} + +/* +================ +idTrigger::Disable +================ +*/ +void idTrigger::Disable( void ) { + // we may be relinked if we're bound to another object, so clear the contents as well + GetPhysics()->SetContents( 0 ); + GetPhysics()->DisableClip(); +} + +/* +================ +idTrigger::CallScript +================ +*/ +void idTrigger::CallScript( void ) const { + idThread *thread; + + if ( scriptFunction ) { + thread = new idThread( scriptFunction ); + thread->DelayedStart( 0 ); + } +} + +/* +================ +idTrigger::GetScriptFunction +================ +*/ +const function_t *idTrigger::GetScriptFunction( void ) const { + return scriptFunction; +} + +/* +================ +idTrigger::Save +================ +*/ +void idTrigger::Save( idSaveGame *savefile ) const { + if ( scriptFunction ) { + savefile->WriteString( scriptFunction->Name() ); + } else { + savefile->WriteString( "" ); + } +} + +/* +================ +idTrigger::Restore +================ +*/ +void idTrigger::Restore( idRestoreGame *savefile ) { + idStr funcname; + savefile->ReadString( funcname ); + if ( funcname.Length() ) { + scriptFunction = gameLocal.program.FindFunction( funcname ); + if ( scriptFunction == NULL ) { + gameLocal.Warning( "idTrigger_Multi '%s' at (%s) calls unknown function '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), funcname.c_str() ); + } + } else { + scriptFunction = NULL; + } +} + +/* +================ +idTrigger::Event_Enable +================ +*/ +void idTrigger::Event_Enable( void ) { + Enable(); +} + +/* +================ +idTrigger::Event_Disable +================ +*/ +void idTrigger::Event_Disable( void ) { + Disable(); +} + +/* +================ +idTrigger::idTrigger +================ +*/ +idTrigger::idTrigger() { + scriptFunction = NULL; +} + +/* +================ +idTrigger::Spawn +================ +*/ +void idTrigger::Spawn( void ) +{ + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); + + idStr funcname = spawnArgs.GetString( "call", "" ); + if ( funcname.Length() ) { + scriptFunction = gameLocal.program.FindFunction( funcname ); + if ( scriptFunction == NULL ) { + gameLocal.Warning( "trigger '%s' at (%s) calls unknown function '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), funcname.c_str() ); + } + } else { + scriptFunction = NULL; + } +} + + +/* +=============================================================================== + + idTrigger_Multi + +=============================================================================== +*/ + +const idEventDef EV_TriggerAction( "", "e" ); + +CLASS_DECLARATION( idTrigger, idTrigger_Multi ) + EVENT( EV_Touch, idTrigger_Multi::Event_Touch ) + EVENT( EV_Activate, idTrigger_Multi::Event_Trigger ) + EVENT( EV_TriggerAction, idTrigger_Multi::Event_TriggerAction ) +END_CLASS + + +/* +================ +idTrigger_Multi::idTrigger_Multi +================ +*/ +idTrigger_Multi::idTrigger_Multi( void ) { + wait = 0.0f; + random = 0.0f; + delay = 0.0f; + random_delay = 0.0f; + nextTriggerTime = 0; + removeItem = 0; + touchClient = false; + touchOther = false; + triggerFirst = false; + triggerWithSelf = false; +} + +/* +================ +idTrigger_Multi::Save +================ +*/ +void idTrigger_Multi::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( wait ); + savefile->WriteFloat( random ); + savefile->WriteFloat( delay ); + savefile->WriteFloat( random_delay ); + savefile->WriteInt( nextTriggerTime ); + savefile->WriteString( requires ); + savefile->WriteInt( removeItem ); + savefile->WriteBool( touchClient ); + savefile->WriteBool( touchOther ); + savefile->WriteBool( triggerFirst ); + savefile->WriteBool( triggerWithSelf ); +} + +/* +================ +idTrigger_Multi::Restore +================ +*/ +void idTrigger_Multi::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( wait ); + savefile->ReadFloat( random ); + savefile->ReadFloat( delay ); + savefile->ReadFloat( random_delay ); + savefile->ReadInt( nextTriggerTime ); + savefile->ReadString( requires ); + savefile->ReadInt( removeItem ); + savefile->ReadBool( touchClient ); + savefile->ReadBool( touchOther ); + savefile->ReadBool( triggerFirst ); + savefile->ReadBool( triggerWithSelf ); +} + +/* +================ +idTrigger_Multi::Spawn + +"wait" : Seconds between triggerings, 0.5 default, -1 = one time only. +"call" : Script function to call when triggered +"random" wait variance, default is 0 +Variable sized repeatable trigger. Must be targeted at one or more entities. +so, the basic time between firing is a random time between +(wait - random) and (wait + random) +================ +*/ +void idTrigger_Multi::Spawn( void ) { + spawnArgs.GetFloat( "wait", "0.5", wait ); + spawnArgs.GetFloat( "random", "0", random ); + spawnArgs.GetFloat( "delay", "0", delay ); + spawnArgs.GetFloat( "random_delay", "0", random_delay ); + + if ( random && ( random >= wait ) && ( wait >= 0 ) ) { + random = wait - 1; + gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) { + random_delay = delay - 1; + gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + spawnArgs.GetString( "requires", "", requires ); + spawnArgs.GetInt( "removeItem", "0", removeItem ); + spawnArgs.GetBool( "triggerFirst", "0", triggerFirst ); + spawnArgs.GetBool( "triggerWithSelf", "0", triggerWithSelf ); + + if ( spawnArgs.GetBool( "anyTouch" ) ) { + touchClient = true; + touchOther = true; + } else if ( spawnArgs.GetBool( "noTouch" ) ) { + touchClient = false; + touchOther = false; + } else if ( spawnArgs.GetBool( "noClient" ) ) { + touchClient = false; + touchOther = true; + } else { + touchClient = true; + touchOther = false; + } + + nextTriggerTime = 0; + + if ( spawnArgs.GetBool( "flashlight_trigger" ) ) { + GetPhysics()->SetContents( CONTENTS_FLASHLIGHT_TRIGGER ); + } else { + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + } + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); +} + +/* +================ +idTrigger_Multi::CheckFacing +================ +*/ +bool idTrigger_Multi::CheckFacing( idEntity *activator ) { + if ( spawnArgs.GetBool( "facing" ) ) { + if ( !activator->IsType( idPlayer::Type ) ) { + return true; + } + idPlayer *player = static_cast< idPlayer* >( activator ); + float dot = player->viewAngles.ToForward() * GetPhysics()->GetAxis()[0]; + float angle = RAD2DEG( idMath::ACos( dot ) ); + if ( angle > spawnArgs.GetFloat( "angleLimit", "30" ) ) { + return false; + } + } + return true; +} + + +/* +================ +idTrigger_Multi::TriggerAction +================ +*/ +void idTrigger_Multi::TriggerAction( idEntity *activator ) { + ActivateTargets( triggerWithSelf ? this : activator ); + CallScript(); + + if ( wait >= 0 ) { + nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); + } else { + // we can't just remove (this) here, because this is a touch function + // called while looping through area links... + nextTriggerTime = gameLocal.time + 1; + PostEventMS( &EV_Remove, 0 ); + } +} + +/* +================ +idTrigger_Multi::Event_TriggerAction +================ +*/ +void idTrigger_Multi::Event_TriggerAction( idEntity *activator ) { + TriggerAction( activator ); +} + +/* +================ +idTrigger_Multi::Event_Trigger + +the trigger was just activated +activated should be the entity that originated the activation sequence (ie. the original target) +activator should be set to the activator so it can be held through a delay +so wait for the delay time before firing +================ +*/ +void idTrigger_Multi::Event_Trigger( idEntity *activator ) { + if ( nextTriggerTime > gameLocal.time ) { + // can't retrigger until the wait is over + return; + } + + // see if this trigger requires an item + if ( !gameLocal.RequirementMet( activator, requires, removeItem ) ) { + return; + } + + if ( !CheckFacing( activator ) ) { + return; + } + + if ( triggerFirst ) { + triggerFirst = false; + return; + } + + // don't allow it to trigger twice in a single frame + nextTriggerTime = gameLocal.time + 1; + + if ( delay > 0 ) { + // don't allow it to trigger again until our delay has passed + nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); + PostEventSec( &EV_TriggerAction, delay, activator ); + } else { + TriggerAction( activator ); + } +} + +/* +================ +idTrigger_Multi::Event_Touch +================ +*/ +void idTrigger_Multi::Event_Touch( idEntity *other, trace_t *trace ) { + if( triggerFirst ) { + return; + } + + bool player = other->IsType( idPlayer::Type ); + if ( player ) { + if ( !touchClient ) { + return; + } + if ( static_cast< idPlayer * >( other )->spectating ) { + return; + } + } else if ( !touchOther ) { + return; + } + + if ( nextTriggerTime > gameLocal.time ) { + // can't retrigger until the wait is over + return; + } + + // see if this trigger requires an item + if ( !gameLocal.RequirementMet( other, requires, removeItem ) ) { + return; + } + + if ( !CheckFacing( other ) ) { + return; + } + + if ( spawnArgs.GetBool( "toggleTriggerFirst" ) ) { + triggerFirst = true; + } + + nextTriggerTime = gameLocal.time + 1; + if ( delay > 0 ) { + // don't allow it to trigger again until our delay has passed + nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); + PostEventSec( &EV_TriggerAction, delay, other ); + } else { + TriggerAction( other ); + } +} + +/* +=============================================================================== + + idTrigger_EntityName + +=============================================================================== +*/ + +CLASS_DECLARATION( idTrigger, idTrigger_EntityName ) + EVENT( EV_Touch, idTrigger_EntityName::Event_Touch ) + EVENT( EV_Activate, idTrigger_EntityName::Event_Trigger ) + EVENT( EV_TriggerAction, idTrigger_EntityName::Event_TriggerAction ) +END_CLASS + +/* +================ +idTrigger_EntityName::idTrigger_EntityName +================ +*/ +idTrigger_EntityName::idTrigger_EntityName( void ) { + wait = 0.0f; + random = 0.0f; + delay = 0.0f; + random_delay = 0.0f; + nextTriggerTime = 0; + triggerFirst = false; +} + +/* +================ +idTrigger_EntityName::Save +================ +*/ +void idTrigger_EntityName::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( wait ); + savefile->WriteFloat( random ); + savefile->WriteFloat( delay ); + savefile->WriteFloat( random_delay ); + savefile->WriteInt( nextTriggerTime ); + savefile->WriteBool( triggerFirst ); + savefile->WriteString( entityName ); +} + +/* +================ +idTrigger_EntityName::Restore +================ +*/ +void idTrigger_EntityName::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( wait ); + savefile->ReadFloat( random ); + savefile->ReadFloat( delay ); + savefile->ReadFloat( random_delay ); + savefile->ReadInt( nextTriggerTime ); + savefile->ReadBool( triggerFirst ); + savefile->ReadString( entityName ); +} + +/* +================ +idTrigger_EntityName::Spawn +================ +*/ +void idTrigger_EntityName::Spawn( void ) +{ + spawnArgs.GetFloat( "wait", "0.5", wait ); + spawnArgs.GetFloat( "random", "0", random ); + spawnArgs.GetFloat( "delay", "0", delay ); + spawnArgs.GetFloat( "random_delay", "0", random_delay ); + + if ( random && ( random >= wait ) && ( wait >= 0 ) ) { + random = wait - 1; + gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) { + random_delay = delay - 1; + gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + spawnArgs.GetBool( "triggerFirst", "0", triggerFirst ); + + entityName = spawnArgs.GetString( "entityname" ); + if ( !entityName.Length() ) { + gameLocal.Error( "idTrigger_EntityName '%s' at (%s) doesn't have 'entityname' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + nextTriggerTime = 0; + + if ( !spawnArgs.GetBool( "noTouch" ) ) + { + GetPhysics()->SetContents( CONTENTS_TRIGGER ); + } + // SR CONTENTS_RESPONSE FIX + if( m_StimResponseColl->HasResponse() ) + GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); +} + +/* +================ +idTrigger_EntityName::TriggerAction +================ +*/ +void idTrigger_EntityName::TriggerAction( idEntity *activator ) { + ActivateTargets( activator ); + CallScript(); + + if ( wait >= 0 ) { + nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); + } else { + // we can't just remove (this) here, because this is a touch function + // called while looping through area links... + nextTriggerTime = gameLocal.time + 1; + PostEventMS( &EV_Remove, 0 ); + } +} + +/* +================ +idTrigger_EntityName::Event_TriggerAction +================ +*/ +void idTrigger_EntityName::Event_TriggerAction( idEntity *activator ) { + TriggerAction( activator ); +} + +/* +================ +idTrigger_EntityName::Event_Trigger + +the trigger was just activated +activated should be the entity that originated the activation sequence (ie. the original target) +activator should be set to the activator so it can be held through a delay +so wait for the delay time before firing +================ +*/ +void idTrigger_EntityName::Event_Trigger( idEntity *activator ) { + if ( nextTriggerTime > gameLocal.time ) { + // can't retrigger until the wait is over + return; + } + + if ( !activator || ( activator->name != entityName ) ) { + return; + } + + if ( triggerFirst ) { + triggerFirst = false; + return; + } + + // don't allow it to trigger twice in a single frame + nextTriggerTime = gameLocal.time + 1; + + if ( delay > 0 ) { + // don't allow it to trigger again until our delay has passed + nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); + PostEventSec( &EV_TriggerAction, delay, activator ); + } else { + TriggerAction( activator ); + } +} + +/* +================ +idTrigger_EntityName::Event_Touch +================ +*/ +void idTrigger_EntityName::Event_Touch( idEntity *other, trace_t *trace ) { + if( triggerFirst ) { + return; + } + + if ( nextTriggerTime > gameLocal.time ) { + // can't retrigger until the wait is over + return; + } + + if ( !other || ( other->name != entityName ) ) { + return; + } + + nextTriggerTime = gameLocal.time + 1; + if ( delay > 0 ) { + // don't allow it to trigger again until our delay has passed + nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); + PostEventSec( &EV_TriggerAction, delay, other ); + } else { + TriggerAction( other ); + } +} + +/* +=============================================================================== + + idTrigger_Timer + +=============================================================================== +*/ + +const idEventDef EV_Timer( "", NULL ); + +CLASS_DECLARATION( idTrigger, idTrigger_Timer ) + EVENT( EV_Timer, idTrigger_Timer::Event_Timer ) + EVENT( EV_Activate, idTrigger_Timer::Event_Use ) +END_CLASS + +/* +================ +idTrigger_Timer::idTrigger_Timer +================ +*/ +idTrigger_Timer::idTrigger_Timer( void ) { + random = 0.0f; + wait = 0.0f; + on = false; + delay = 0.0f; +} + +/* +================ +idTrigger_Timer::Save +================ +*/ +void idTrigger_Timer::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( random ); + savefile->WriteFloat( wait ); + savefile->WriteBool( on ); + savefile->WriteFloat( delay ); + savefile->WriteString( onName ); + savefile->WriteString( offName ); +} + +/* +================ +idTrigger_Timer::Restore +================ +*/ +void idTrigger_Timer::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( random ); + savefile->ReadFloat( wait ); + savefile->ReadBool( on ); + savefile->ReadFloat( delay ); + savefile->ReadString( onName ); + savefile->ReadString( offName ); +} + +/* +================ +idTrigger_Timer::Spawn + +Repeatedly fires its targets. +Can be turned on or off by using. +================ +*/ +void idTrigger_Timer::Spawn( void ) { + spawnArgs.GetFloat( "random", "1", random ); + spawnArgs.GetFloat( "wait", "1", wait ); + spawnArgs.GetBool( "start_on", "0", on ); + spawnArgs.GetFloat( "delay", "0", delay ); + onName = spawnArgs.GetString( "onName" ); + offName = spawnArgs.GetString( "offName" ); + + if ( random >= wait && wait >= 0 ) { + random = wait - 0.001; + gameLocal.Warning( "idTrigger_Timer '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); + } + + if ( on ) { + PostEventSec( &EV_Timer, delay ); + } +} + +/* +================ +idTrigger_Timer::Enable +================ +*/ +void idTrigger_Timer::Enable( void ) { + // if off, turn it on + if ( !on ) { + on = true; + PostEventSec( &EV_Timer, delay ); + } +} + +/* +================ +idTrigger_Timer::Disable +================ +*/ +void idTrigger_Timer::Disable( void ) { + // if on, turn it off + if ( on ) { + on = false; + CancelEvents( &EV_Timer ); + } +} + +/* +================ +idTrigger_Timer::Event_Timer +================ +*/ +void idTrigger_Timer::Event_Timer( void ) { + ActivateTargets( this ); + + // set time before next firing + if ( wait >= 0.0f ) { + PostEventSec( &EV_Timer, wait + gameLocal.random.CRandomFloat() * random ); + } +} + +/* +================ +idTrigger_Timer::Event_Use +================ +*/ +void idTrigger_Timer::Event_Use( idEntity *activator ) { + // if on, turn it off + if ( on ) { + if ( offName.Length() && offName.Icmp( activator->GetName() ) ) { + return; + } + on = false; + CancelEvents( &EV_Timer ); + } else { + // turn it on + if ( onName.Length() && onName.Icmp( activator->GetName() ) ) { + return; + } + on = true; + PostEventSec( &EV_Timer, delay ); + } +} + +/* +=============================================================================== + + idTrigger_Count + +=============================================================================== +*/ + +CLASS_DECLARATION( idTrigger, idTrigger_Count ) + EVENT( EV_Activate, idTrigger_Count::Event_Trigger ) + EVENT( EV_TriggerAction, idTrigger_Count::Event_TriggerAction ) +END_CLASS + +/* +================ +idTrigger_Count::idTrigger_Count +================ +*/ +idTrigger_Count::idTrigger_Count( void ) { + goal = 0; + count = 0; + delay = 0.0f; +} + +/* +================ +idTrigger_Count::Save +================ +*/ +void idTrigger_Count::Save( idSaveGame *savefile ) const { + savefile->WriteInt( goal ); + savefile->WriteInt( count ); + savefile->WriteFloat( delay ); +} + +/* +================ +idTrigger_Count::Restore +================ +*/ +void idTrigger_Count::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( goal ); + savefile->ReadInt( count ); + savefile->ReadFloat( delay ); +} + +/* +================ +idTrigger_Count::Spawn +================ +*/ +void idTrigger_Count::Spawn( void ) { + spawnArgs.GetInt( "count", "1", goal ); + spawnArgs.GetFloat( "delay", "0", delay ); + count = 0; +} + +/* +================ +idTrigger_Count::Event_Trigger +================ +*/ +void idTrigger_Count::Event_Trigger( idEntity *activator ) { + // goal of -1 means trigger has been exhausted + if (goal >= 0) { + count++; + if ( count >= goal ) { + if (spawnArgs.GetBool("repeat")) { + count = 0; + } else { + goal = -1; + } + PostEventSec( &EV_TriggerAction, delay, activator ); + } + } +} + +/* +================ +idTrigger_Count::Event_TriggerAction +================ +*/ +void idTrigger_Count::Event_TriggerAction( idEntity *activator ) { + ActivateTargets( activator ); + CallScript(); + if ( goal == -1 ) { + PostEventMS( &EV_Remove, 0 ); + } +} + +/* +=============================================================================== + + idTrigger_Hurt + +=============================================================================== +*/ + +CLASS_DECLARATION( idTrigger, idTrigger_Hurt ) + EVENT( EV_Touch, idTrigger_Hurt::Event_Touch ) + EVENT( EV_Activate, idTrigger_Hurt::Event_Toggle ) +END_CLASS + + +/* +================ +idTrigger_Hurt::idTrigger_Hurt +================ +*/ +idTrigger_Hurt::idTrigger_Hurt( void ) { + on = false; + delay = 0.0f; + nextTime = 0; +} + +/* +================ +idTrigger_Hurt::Save +================ +*/ +void idTrigger_Hurt::Save( idSaveGame *savefile ) const { + savefile->WriteBool( on ); + savefile->WriteFloat( delay ); + savefile->WriteInt( nextTime ); +} + +/* +================ +idTrigger_Hurt::Restore +================ +*/ +void idTrigger_Hurt::Restore( idRestoreGame *savefile ) { + savefile->ReadBool( on ); + savefile->ReadFloat( delay ); + savefile->ReadInt( nextTime ); +} + +/* +================ +idTrigger_Hurt::Spawn + + Damages activator + Can be turned on or off by using. +================ +*/ +void idTrigger_Hurt::Spawn( void ) { + spawnArgs.GetBool( "on", "1", on ); + spawnArgs.GetFloat( "delay", "1.0", delay ); + nextTime = gameLocal.time; + Enable(); +} + +/* +================ +idTrigger_Hurt::Event_Touch +================ +*/ +void idTrigger_Hurt::Event_Touch( idEntity *other, trace_t *trace ) { + const char *damage; + + if ( on && other && gameLocal.time >= nextTime ) { + damage = spawnArgs.GetString( "def_damage", "damage_painTrigger" ); + other->Damage( NULL, NULL, vec3_origin, damage, 1.0f, INVALID_JOINT ); + + ActivateTargets( other ); + CallScript(); + + nextTime = gameLocal.time + SEC2MS( delay ); + } +} + +/* +================ +idTrigger_Hurt::Event_Toggle +================ +*/ +void idTrigger_Hurt::Event_Toggle( idEntity *activator ) { + on = !on; +} + + +/* +=============================================================================== + + idTrigger_Fade + +=============================================================================== +*/ + +CLASS_DECLARATION( idTrigger, idTrigger_Fade ) + EVENT( EV_Activate, idTrigger_Fade::Event_Trigger ) +END_CLASS + +/* +================ +idTrigger_Fade::Event_Trigger +================ +*/ +void idTrigger_Fade::Event_Trigger( idEntity *activator ) { + idVec4 fadeColor; + int fadeTime; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( player ) { + fadeColor = spawnArgs.GetVec4( "fadeColor", "0, 0, 0, 1" ); + fadeTime = SEC2MS( spawnArgs.GetFloat( "fadeTime", "0.5" ) ); + player->playerView.Fade( fadeColor, fadeTime ); + PostEventMS( &EV_ActivateTargets, fadeTime, activator ); + } +} + +/* +=============================================================================== + + idTrigger_Touch + +=============================================================================== +*/ + +CLASS_DECLARATION( idTrigger, idTrigger_Touch ) + EVENT( EV_Activate, idTrigger_Touch::Event_Trigger ) +END_CLASS + + +/* +================ +idTrigger_Touch::idTrigger_Touch +================ +*/ +idTrigger_Touch::idTrigger_Touch( void ) { + clipModel = NULL; +} + +/* +================ +idTrigger_Touch::Spawn +================ +*/ +void idTrigger_Touch::Spawn( void ) { + // get the clip model + clipModel = new idClipModel( GetPhysics()->GetClipModel() ); + + // remove the collision model from the physics object + GetPhysics()->SetClipModel( NULL, 1.0f ); + + if ( spawnArgs.GetBool( "start_on" ) ) { + BecomeActive( TH_THINK ); + } +} + +/* +================ +idTrigger_Touch::Save +================ +*/ +void idTrigger_Touch::Save( idSaveGame *savefile ) { + savefile->WriteClipModel( clipModel ); +} + +/* +================ +idTrigger_Touch::Restore +================ +*/ +void idTrigger_Touch::Restore( idRestoreGame *savefile ) { + savefile->ReadClipModel( clipModel ); +} + +/* +================ +idTrigger_Touch::TouchEntities +================ +*/ +void idTrigger_Touch::TouchEntities( void ) { + int numClipModels, i; + idBounds bounds; + idClipModel *cm, *clipModelList[ MAX_GENTITIES ]; + + if ( clipModel == NULL) + { + return; + } + + bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); + numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); + + for ( i = 0; i < numClipModels; i++ ) { + cm = clipModelList[ i ]; + + if ( !cm->IsTraceModel() ) { + continue; + } + + idEntity *entity = cm->GetEntity(); + + if ( !entity ) { + continue; + } + + if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1, + clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) { + continue; + } + + ActivateTargets( entity ); + + if (scriptFunction != NULL) + { + idThread *thread = new idThread(); + thread->CallFunction( entity, scriptFunction, false ); + thread->DelayedStart( 0 ); + } + } +} + +/* +================ +idTrigger_Touch::Think +================ +*/ +void idTrigger_Touch::Think( void ) { + if ( thinkFlags & TH_THINK ) { + TouchEntities(); + } + idEntity::Think(); +} + +/* +================ +idTrigger_Touch::Event_Trigger +================ +*/ +void idTrigger_Touch::Event_Trigger( idEntity *activator ) { + if ( thinkFlags & TH_THINK ) { + BecomeInactive( TH_THINK ); + } else { + BecomeActive( TH_THINK ); + } +} + +/* +================ +idTrigger_Touch::Enable +================ +*/ +void idTrigger_Touch::Enable( void ) { + BecomeActive( TH_THINK ); +} + +/* +================ +idTrigger_Touch::Disable +================ +*/ +void idTrigger_Touch::Disable( void ) { + BecomeInactive( TH_THINK ); +} diff --git a/game/Trigger.h b/game/Trigger.h new file mode 100644 index 000000000..46726128e --- /dev/null +++ b/game/Trigger.h @@ -0,0 +1,278 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_TRIGGER_H__ +#define __GAME_TRIGGER_H__ + +extern const idEventDef EV_Enable; +extern const idEventDef EV_Disable; + +/* +=============================================================================== + + Trigger base. + +=============================================================================== +*/ + +class idTrigger : public idEntity { +public: + CLASS_PROTOTYPE( idTrigger ); + + static void DrawDebugInfo( void ); + + idTrigger(); + void Spawn( void ); + + const function_t * GetScriptFunction( void ) const; + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + virtual void Enable( void ); + virtual void Disable( void ); + +protected: + void CallScript( void ) const; + + void Event_Enable( void ); + void Event_Disable( void ); + + const function_t * scriptFunction; +}; + + +/* +=============================================================================== + + Trigger which can be activated multiple times. + +=============================================================================== +*/ + +class idTrigger_Multi : public idTrigger { +public: + CLASS_PROTOTYPE( idTrigger_Multi ); + + idTrigger_Multi( void ); + + void Spawn( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +private: + float wait; + float random; + float delay; + float random_delay; + int nextTriggerTime; + idStr requires; + int removeItem; + bool touchClient; + bool touchOther; + bool triggerFirst; + bool triggerWithSelf; + + bool CheckFacing( idEntity *activator ); + void TriggerAction( idEntity *activator ); + void Event_TriggerAction( idEntity *activator ); + void Event_Trigger( idEntity *activator ); + void Event_Touch( idEntity *other, trace_t *trace ); +}; + + +/* +=============================================================================== + + Trigger which can only be activated by an entity with a specific name. + +=============================================================================== +*/ + +class idTrigger_EntityName : public idTrigger { +public: + CLASS_PROTOTYPE( idTrigger_EntityName ); + + idTrigger_EntityName( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + +private: + float wait; + float random; + float delay; + float random_delay; + int nextTriggerTime; + bool triggerFirst; + idStr entityName; + + void TriggerAction( idEntity *activator ); + void Event_TriggerAction( idEntity *activator ); + void Event_Trigger( idEntity *activator ); + void Event_Touch( idEntity *other, trace_t *trace ); +}; + +/* +=============================================================================== + + Trigger which repeatedly fires targets. + +=============================================================================== +*/ + +class idTrigger_Timer : public idTrigger { +public: + CLASS_PROTOTYPE( idTrigger_Timer ); + + idTrigger_Timer( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + + virtual void Enable( void ); + virtual void Disable( void ); + +private: + float random; + float wait; + bool on; + float delay; + idStr onName; + idStr offName; + + void Event_Timer( void ); + void Event_Use( idEntity *activator ); +}; + + +/* +=============================================================================== + + Trigger which fires targets after being activated a specific number of times. + +=============================================================================== +*/ + +class idTrigger_Count : public idTrigger { +public: + CLASS_PROTOTYPE( idTrigger_Count ); + + idTrigger_Count( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + +private: + int goal; + int count; + float delay; + + void Event_Trigger( idEntity *activator ); + void Event_TriggerAction( idEntity *activator ); +}; + + +/* +=============================================================================== + + Trigger which hurts touching entities. + +=============================================================================== +*/ + +class idTrigger_Hurt : public idTrigger { +public: + CLASS_PROTOTYPE( idTrigger_Hurt ); + + idTrigger_Hurt( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + +private: + bool on; + float delay; + int nextTime; + + void Event_Touch( idEntity *other, trace_t *trace ); + void Event_Toggle( idEntity *activator ); +}; + + +/* +=============================================================================== + + Trigger which fades the player view. + +=============================================================================== +*/ + +class idTrigger_Fade : public idTrigger { +public: + + CLASS_PROTOTYPE( idTrigger_Fade ); + +private: + void Event_Trigger( idEntity *activator ); +}; + + +/* +=============================================================================== + + Trigger which continuously tests whether other entities are touching it. + +=============================================================================== +*/ + +class idTrigger_Touch : public idTrigger { +public: + + CLASS_PROTOTYPE( idTrigger_Touch ); + + idTrigger_Touch( void ); + + void Spawn( void ); + virtual void Think( void ); + + void Save( idSaveGame *savefile ); + void Restore( idRestoreGame *savefile ); + + virtual void Enable( void ); + virtual void Disable( void ); + + void TouchEntities( void ); + +private: + idClipModel * clipModel; + + void Event_Trigger( idEntity *activator ); +}; + +#endif /* !__GAME_TRIGGER_H__ */ diff --git a/DarkMod/UserManager.cpp b/game/UserManager.cpp similarity index 84% rename from DarkMod/UserManager.cpp rename to game/UserManager.cpp index 5f5715682..75712754c 100644 --- a/DarkMod/UserManager.cpp +++ b/game/UserManager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/game/UserManager.h b/game/UserManager.h new file mode 100644 index 000000000..896f8146a --- /dev/null +++ b/game/UserManager.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef USER_MANAGER_H +#define USER_MANAGER_H + +class UserManager +{ + +public: + + int GetNumUsers(); + + // Adds user to the list, sorted by alert level + void AddUser(idActor*); + + void AppendUser(idActor* actor); // grayman #1327 - append to the list, don't care about alert level + + void RemoveUser(idActor*); + + idActor* GetMasterUser(); + + idActor* GetUserAtIndex(const int index); // grayman #2345 + void InsertUserAtIndex(idActor* actor,const int index); // grayman #2345 + + int GetIndex(idActor* user); // grayman #2345 + void ResetMaster(CFrobDoor* frobDoor); // grayman #2706 + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + +private: + + idList< idEntityPtr > m_users; + + + +}; + +#endif /* USER_MANAGER_H */ diff --git a/game/Weapon.cpp b/game/Weapon.cpp new file mode 100644 index 000000000..6983baafb --- /dev/null +++ b/game/Weapon.cpp @@ -0,0 +1,3601 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" +#include "DarkModGlobals.h" +#include "Inventory/WeaponItem.h" + +/*********************************************************************** + + idWeapon + +***********************************************************************/ + +// +// event defs +// +const idEventDef EV_Weapon_Clear( "" ); +const idEventDef EV_Weapon_GetOwner( "getOwner", NULL, 'e' ); +const idEventDef EV_Weapon_Next( "nextWeapon" ); +const idEventDef EV_Weapon_State( "weaponState", "sd" ); +const idEventDef EV_Weapon_UseAmmo( "useAmmo", "d" ); +const idEventDef EV_Weapon_AddToClip( "addToClip", "d" ); +const idEventDef EV_Weapon_AmmoInClip( "ammoInClip", NULL, 'f' ); +const idEventDef EV_Weapon_AmmoAvailable( "ammoAvailable", NULL, 'f' ); +const idEventDef EV_Weapon_TotalAmmoCount( "totalAmmoCount", NULL, 'f' ); +const idEventDef EV_Weapon_ClipSize( "clipSize", NULL, 'f' ); +const idEventDef EV_Weapon_WeaponOutOfAmmo( "weaponOutOfAmmo" ); +const idEventDef EV_Weapon_WeaponReady( "weaponReady" ); +const idEventDef EV_Weapon_WeaponReloading( "weaponReloading" ); +const idEventDef EV_Weapon_WeaponHolstered( "weaponHolstered" ); +const idEventDef EV_Weapon_WeaponRising( "weaponRising" ); +const idEventDef EV_Weapon_WeaponLowering( "weaponLowering" ); +const idEventDef EV_Weapon_Flashlight( "flashlight", "d" ); +const idEventDef EV_Weapon_LaunchProjectiles( "launchProjectiles", "dffff" ); +const idEventDef EV_Weapon_CreateProjectile( "createProjectile", NULL, 'e' ); +const idEventDef EV_Weapon_EjectBrass( "ejectBrass" ); +const idEventDef EV_Weapon_Melee( "melee", NULL, 'd' ); +const idEventDef EV_Weapon_GetWorldModel( "getWorldModel", NULL, 'e' ); +const idEventDef EV_Weapon_AllowDrop( "allowDrop", "d" ); +const idEventDef EV_Weapon_AutoReload( "autoReload", NULL, 'f' ); +const idEventDef EV_Weapon_NetReload( "netReload" ); +const idEventDef EV_Weapon_IsInvisible( "isInvisible", NULL, 'f' ); +const idEventDef EV_Weapon_NetEndReload( "netEndReload" ); +const idEventDef EV_Weapon_ShowAttachment( "showAttachment", "sd" ); +const idEventDef EV_Weapon_ShowAttachmentInd( "showAttachmentInd", "dd" ); + +// +// class def +// +CLASS_DECLARATION( idAnimatedEntity, idWeapon ) + EVENT( EV_Weapon_Clear, idWeapon::Event_Clear ) + EVENT( EV_Weapon_GetOwner, idWeapon::Event_GetOwner ) + EVENT( EV_Weapon_State, idWeapon::Event_WeaponState ) + EVENT( EV_Weapon_WeaponReady, idWeapon::Event_WeaponReady ) + EVENT( EV_Weapon_WeaponOutOfAmmo, idWeapon::Event_WeaponOutOfAmmo ) + EVENT( EV_Weapon_WeaponReloading, idWeapon::Event_WeaponReloading ) + EVENT( EV_Weapon_WeaponHolstered, idWeapon::Event_WeaponHolstered ) + EVENT( EV_Weapon_WeaponRising, idWeapon::Event_WeaponRising ) + EVENT( EV_Weapon_WeaponLowering, idWeapon::Event_WeaponLowering ) + EVENT( EV_Weapon_UseAmmo, idWeapon::Event_UseAmmo ) + EVENT( EV_Weapon_AddToClip, idWeapon::Event_AddToClip ) + EVENT( EV_Weapon_AmmoInClip, idWeapon::Event_AmmoInClip ) + EVENT( EV_Weapon_AmmoAvailable, idWeapon::Event_AmmoAvailable ) + EVENT( EV_Weapon_TotalAmmoCount, idWeapon::Event_TotalAmmoCount ) + EVENT( EV_Weapon_ClipSize, idWeapon::Event_ClipSize ) + EVENT( AI_PlayAnim, idWeapon::Event_PlayAnim ) + EVENT( AI_PauseAnim, idWeapon::Event_PauseAnim ) + EVENT( AI_AnimIsPaused, idWeapon::Event_AnimIsPaused ) + EVENT( AI_PlayCycle, idWeapon::Event_PlayCycle ) + EVENT( AI_SetBlendFrames, idWeapon::Event_SetBlendFrames ) + EVENT( AI_GetBlendFrames, idWeapon::Event_GetBlendFrames ) + EVENT( AI_AnimDone, idWeapon::Event_AnimDone ) + EVENT( EV_Weapon_Next, idWeapon::Event_Next ) + EVENT( EV_SetSkin, idWeapon::Event_SetSkin ) + EVENT( EV_Weapon_ShowAttachment, idWeapon::ShowAttachment ) + EVENT( EV_Weapon_ShowAttachmentInd, idWeapon::ShowAttachmentInd ) + EVENT( EV_Weapon_Flashlight, idWeapon::Event_Flashlight ) + EVENT( EV_Light_GetLightParm, idWeapon::Event_GetLightParm ) + EVENT( EV_Light_SetLightParm, idWeapon::Event_SetLightParm ) + EVENT( EV_Light_SetLightParms, idWeapon::Event_SetLightParms ) + EVENT( EV_Weapon_LaunchProjectiles, idWeapon::Event_LaunchProjectiles ) + EVENT( EV_Weapon_CreateProjectile, idWeapon::Event_CreateProjectile ) + EVENT( EV_Weapon_EjectBrass, idWeapon::Event_EjectBrass ) + EVENT( EV_Weapon_Melee, idWeapon::Event_Melee ) + EVENT( EV_Weapon_GetWorldModel, idWeapon::Event_GetWorldModel ) + EVENT( EV_Weapon_AllowDrop, idWeapon::Event_AllowDrop ) + EVENT( EV_Weapon_AutoReload, idWeapon::Event_AutoReload ) + EVENT( EV_Weapon_NetReload, idWeapon::Event_NetReload ) + EVENT( EV_Weapon_IsInvisible, idWeapon::Event_IsInvisible ) + EVENT( EV_Weapon_NetEndReload, idWeapon::Event_NetEndReload ) +END_CLASS + +/*********************************************************************** + + init + +***********************************************************************/ + +/* +================ +idWeapon::idWeapon() +================ +*/ +idWeapon::idWeapon() { + owner = NULL; + worldModel = NULL; + weaponDef = NULL; + thread = NULL; + + memset( &guiLight, 0, sizeof( guiLight ) ); + memset( &muzzleFlash, 0, sizeof( muzzleFlash ) ); + memset( &worldMuzzleFlash, 0, sizeof( worldMuzzleFlash ) ); + memset( &nozzleGlow, 0, sizeof( nozzleGlow ) ); + + muzzleFlashEnd = 0; + flashColor = vec3_origin; + muzzleFlashHandle = -1; + worldMuzzleFlashHandle = -1; + guiLightHandle = -1; + nozzleGlowHandle = -1; + modelDefHandle = -1; + + berserk = 2; + brassDelay = 0; + + allowDrop = true; + + Clear(); + + fl.networkSync = true; +} + +/* +================ +idWeapon::~idWeapon() +================ +*/ +idWeapon::~idWeapon() +{ + // destroy weapon attachments + for( int i=0; iEvent_Remove(); + } + + Clear(); + delete worldModel.GetEntity(); +} + + +/* +================ +idWeapon::Spawn +================ +*/ +void idWeapon::Spawn( void ) { + if ( !gameLocal.isClient ) { + // setup the world model + worldModel = static_cast< idAnimatedEntity * >( gameLocal.SpawnEntityType( idAnimatedEntity::Type, NULL ) ); + worldModel.GetEntity()->fl.networkSync = true; + } + + thread = new idThread(); + thread->ManualDelete(); + thread->ManualControl(); +} + +/* +================ +idWeapon::SetOwner + +Only called at player spawn time, not each weapon switch +================ +*/ +void idWeapon::SetOwner( idPlayer *_owner ) { + assert( !owner ); + owner = _owner; + SetName( va( "%s_weapon", owner->name.c_str() ) ); + + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->SetName( va( "%s_weapon_worldmodel", owner->name.c_str() ) ); + } +} + +/* +================ +idWeapon::ShouldConstructScriptObjectAtSpawn + +Called during idEntity::Spawn to see if it should construct the script object or not. +Overridden by subclasses that need to spawn the script object themselves. +================ +*/ +bool idWeapon::ShouldConstructScriptObjectAtSpawn( void ) const { + return false; +} + +/* +================ +idWeapon::CacheWeapon +================ +*/ +void idWeapon::CacheWeapon( const char *weaponName ) { + const idDeclEntityDef *weaponDef; + const char *brassDefName; + const char *clipModelName; + idTraceModel trm; + const char *guiName; + + weaponDef = gameLocal.FindEntityDef( weaponName, false ); + if ( !weaponDef ) { + return; + } + + // precache the brass collision model + brassDefName = weaponDef->dict.GetString( "def_ejectBrass" ); + if ( brassDefName[0] ) { + const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( brassDefName, false ); + if ( brassDef ) { + brassDef->dict.GetString( "clipmodel", "", &clipModelName ); + if ( !clipModelName[0] ) { + clipModelName = brassDef->dict.GetString( "model" ); // use the visual model + } + // load the trace model + collisionModelManager->TrmFromModel( clipModelName, trm ); + } + } + + guiName = weaponDef->dict.GetString( "gui" ); + if ( guiName[0] ) { + uiManager->FindGui( guiName, true, false, true ); + } +} + +/* +================ +idWeapon::Save +================ +*/ +void idWeapon::Save( idSaveGame *savefile ) const { + + savefile->WriteInt( status ); + savefile->WriteObject( thread ); + savefile->WriteString( state ); + savefile->WriteString( idealState ); + savefile->WriteInt( animBlendFrames ); + savefile->WriteInt( animDoneTime ); + savefile->WriteBool( isLinked ); + + savefile->WriteObject( owner ); + worldModel.Save( savefile ); + + savefile->WriteInt( hideTime ); + savefile->WriteFloat( hideDistance ); + savefile->WriteInt( hideStartTime ); + savefile->WriteFloat( hideStart ); + savefile->WriteFloat( hideEnd ); + savefile->WriteFloat( hideOffset ); + savefile->WriteBool( hide ); + savefile->WriteBool( disabled ); + + savefile->WriteInt( berserk ); + + savefile->WriteVec3( playerViewOrigin ); + savefile->WriteMat3( playerViewAxis ); + + savefile->WriteVec3( viewWeaponOrigin ); + savefile->WriteMat3( viewWeaponAxis ); + + savefile->WriteVec3( muzzleOrigin ); + savefile->WriteMat3( muzzleAxis ); + + savefile->WriteVec3( pushVelocity ); + + savefile->WriteString( weaponDef->GetName() ); + savefile->WriteFloat( meleeDistance ); + savefile->WriteString( meleeDefName ); + savefile->WriteInt( brassDelay ); + savefile->WriteString( icon ); + + savefile->WriteInt( guiLightHandle ); + savefile->WriteRenderLight( guiLight ); + + savefile->WriteInt( muzzleFlashHandle ); + savefile->WriteRenderLight( muzzleFlash ); + + savefile->WriteInt( worldMuzzleFlashHandle ); + savefile->WriteRenderLight( worldMuzzleFlash ); + + savefile->WriteVec3( flashColor ); + savefile->WriteInt( muzzleFlashEnd ); + savefile->WriteInt( flashTime ); + + savefile->WriteBool( lightOn ); + + savefile->WriteInt( kick_endtime ); + savefile->WriteInt( muzzle_kick_time ); + savefile->WriteInt( muzzle_kick_maxtime ); + savefile->WriteAngles( muzzle_kick_angles ); + savefile->WriteVec3( muzzle_kick_offset ); + + savefile->WriteInt( ammoRequired ); + savefile->WriteInt( clipSize ); + savefile->WriteInt( ammoClip ); + savefile->WriteInt( lowAmmo ); + savefile->WriteBool( powerAmmo ); + + // savegames <= 17 + savefile->WriteInt( 0 ); + + savefile->WriteInt( zoomFov ); + + savefile->WriteJoint( barrelJointView ); + savefile->WriteJoint( flashJointView ); + savefile->WriteJoint( ejectJointView ); + savefile->WriteJoint( guiLightJointView ); + savefile->WriteJoint( ventLightJointView ); + + savefile->WriteJoint( flashJointWorld ); + savefile->WriteJoint( barrelJointWorld ); + savefile->WriteJoint( ejectJointWorld ); + + savefile->WriteBool( hasBloodSplat ); + + savefile->WriteSoundShader( sndHum ); + + savefile->WriteParticle( weaponSmoke ); + savefile->WriteInt( weaponSmokeStartTime ); + savefile->WriteBool( continuousSmoke ); + savefile->WriteParticle( strikeSmoke ); + savefile->WriteInt( strikeSmokeStartTime ); + savefile->WriteVec3( strikePos ); + savefile->WriteMat3( strikeAxis ); + savefile->WriteInt( nextStrikeFx ); + + savefile->WriteBool( nozzleFx ); + savefile->WriteInt( nozzleFxFade ); + + savefile->WriteInt( lastAttack ); + + savefile->WriteInt( nozzleGlowHandle ); + savefile->WriteRenderLight( nozzleGlow ); + + savefile->WriteVec3( nozzleGlowColor ); + savefile->WriteMaterial( nozzleGlowShader ); + savefile->WriteFloat( nozzleGlowRadius ); + + savefile->WriteInt( weaponAngleOffsetAverages ); + savefile->WriteFloat( weaponAngleOffsetScale ); + savefile->WriteFloat( weaponAngleOffsetMax ); + savefile->WriteFloat( weaponOffsetTime ); + savefile->WriteFloat( weaponOffsetScale ); + + savefile->WriteBool( allowDrop ); + savefile->WriteObject( projectileEnt ); + + savefile->WriteInt(m_Attachments.Num()); + for (int i = 0; i < m_Attachments.Num(); i++) + { + m_Attachments[i].Save(savefile); + } +} + +/* +================ +idWeapon::Restore +================ +*/ +void idWeapon::Restore( idRestoreGame *savefile ) { + + savefile->ReadInt( (int &)status ); + savefile->ReadObject( reinterpret_cast( thread ) ); + savefile->ReadString( state ); + savefile->ReadString( idealState ); + savefile->ReadInt( animBlendFrames ); + savefile->ReadInt( animDoneTime ); + savefile->ReadBool( isLinked ); + + // Re-link script fields + WEAPON_ATTACK.LinkTo( scriptObject, "WEAPON_ATTACK" ); + WEAPON_BLOCK.LinkTo( scriptObject, "WEAPON_BLOCK" ); + WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); + WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); + WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); + WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); + WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); + WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); + + savefile->ReadObject( reinterpret_cast( owner ) ); + worldModel.Restore( savefile ); + + savefile->ReadInt( hideTime ); + savefile->ReadFloat( hideDistance ); + savefile->ReadInt( hideStartTime ); + savefile->ReadFloat( hideStart ); + savefile->ReadFloat( hideEnd ); + savefile->ReadFloat( hideOffset ); + savefile->ReadBool( hide ); + savefile->ReadBool( disabled ); + + savefile->ReadInt( berserk ); + + savefile->ReadVec3( playerViewOrigin ); + savefile->ReadMat3( playerViewAxis ); + + savefile->ReadVec3( viewWeaponOrigin ); + savefile->ReadMat3( viewWeaponAxis ); + + savefile->ReadVec3( muzzleOrigin ); + savefile->ReadMat3( muzzleAxis ); + + savefile->ReadVec3( pushVelocity ); + + idStr objectname; + savefile->ReadString( objectname ); + weaponDef = gameLocal.FindEntityDef( objectname ); + meleeDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_melee" ), false ); + + /*const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_projectile" ), false ); + if ( projectileDef ) { + projectileDict = projectileDef->dict; + } else { + projectileDict.Clear(); + }*/ + + const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_ejectBrass" ), false ); + if ( brassDef ) { + brassDict = brassDef->dict; + } else { + brassDict.Clear(); + } + + savefile->ReadFloat( meleeDistance ); + savefile->ReadString( meleeDefName ); + savefile->ReadInt( brassDelay ); + savefile->ReadString( icon ); + + savefile->ReadInt( guiLightHandle ); + savefile->ReadRenderLight( guiLight ); + + savefile->ReadInt( muzzleFlashHandle ); + savefile->ReadRenderLight( muzzleFlash ); + + savefile->ReadInt( worldMuzzleFlashHandle ); + savefile->ReadRenderLight( worldMuzzleFlash ); + + savefile->ReadVec3( flashColor ); + savefile->ReadInt( muzzleFlashEnd ); + savefile->ReadInt( flashTime ); + + savefile->ReadBool( lightOn ); + + savefile->ReadInt( kick_endtime ); + savefile->ReadInt( muzzle_kick_time ); + savefile->ReadInt( muzzle_kick_maxtime ); + savefile->ReadAngles( muzzle_kick_angles ); + savefile->ReadVec3( muzzle_kick_offset ); + + savefile->ReadInt( ammoRequired ); + savefile->ReadInt( clipSize ); + savefile->ReadInt( ammoClip ); + savefile->ReadInt( lowAmmo ); + savefile->ReadBool( powerAmmo ); + + // savegame versions <= 17 + int foo; + savefile->ReadInt( foo ); + + savefile->ReadInt( zoomFov ); + + savefile->ReadJoint( barrelJointView ); + savefile->ReadJoint( flashJointView ); + savefile->ReadJoint( ejectJointView ); + savefile->ReadJoint( guiLightJointView ); + savefile->ReadJoint( ventLightJointView ); + + savefile->ReadJoint( flashJointWorld ); + savefile->ReadJoint( barrelJointWorld ); + savefile->ReadJoint( ejectJointWorld ); + + savefile->ReadBool( hasBloodSplat ); + + savefile->ReadSoundShader( sndHum ); + + savefile->ReadParticle( weaponSmoke ); + savefile->ReadInt( weaponSmokeStartTime ); + savefile->ReadBool( continuousSmoke ); + savefile->ReadParticle( strikeSmoke ); + savefile->ReadInt( strikeSmokeStartTime ); + savefile->ReadVec3( strikePos ); + savefile->ReadMat3( strikeAxis ); + savefile->ReadInt( nextStrikeFx ); + + savefile->ReadBool( nozzleFx ); + savefile->ReadInt( nozzleFxFade ); + + savefile->ReadInt( lastAttack ); + + savefile->ReadInt( nozzleGlowHandle ); + savefile->ReadRenderLight( nozzleGlow ); + + savefile->ReadVec3( nozzleGlowColor ); + savefile->ReadMaterial( nozzleGlowShader ); + savefile->ReadFloat( nozzleGlowRadius ); + + savefile->ReadInt( weaponAngleOffsetAverages ); + savefile->ReadFloat( weaponAngleOffsetScale ); + savefile->ReadFloat( weaponAngleOffsetMax ); + savefile->ReadFloat( weaponOffsetTime ); + savefile->ReadFloat( weaponOffsetScale ); + + savefile->ReadBool( allowDrop ); + savefile->ReadObject( reinterpret_cast( projectileEnt ) ); + + int num; + savefile->ReadInt(num); + m_Attachments.SetNum(num); + for (int i = 0; i < num; i++) + { + m_Attachments[i].Restore(savefile); + } +} + +/*********************************************************************** + + Weapon definition management + +***********************************************************************/ + +/* +================ +idWeapon::Clear +================ +*/ +void idWeapon::Clear( void ) { + CancelEvents( &EV_Weapon_Clear ); + + DeconstructScriptObject(); + scriptObject.Free(); + + WEAPON_ATTACK.Unlink(); + WEAPON_BLOCK.Unlink(); + WEAPON_RELOAD.Unlink(); + WEAPON_NETRELOAD.Unlink(); + WEAPON_NETENDRELOAD.Unlink(); + WEAPON_NETFIRING.Unlink(); + WEAPON_RAISEWEAPON.Unlink(); + WEAPON_LOWERWEAPON.Unlink(); + + if ( muzzleFlashHandle != -1 ) { + gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + muzzleFlashHandle = -1; + } + if ( muzzleFlashHandle != -1 ) { + gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + muzzleFlashHandle = -1; + } + if ( worldMuzzleFlashHandle != -1 ) { + gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + worldMuzzleFlashHandle = -1; + } + if ( guiLightHandle != -1 ) { + gameRenderWorld->FreeLightDef( guiLightHandle ); + guiLightHandle = -1; + } + if ( nozzleGlowHandle != -1 ) { + gameRenderWorld->FreeLightDef( nozzleGlowHandle ); + nozzleGlowHandle = -1; + } + + memset( &renderEntity, 0, sizeof( renderEntity ) ); + renderEntity.entityNum = entityNumber; + + renderEntity.noShadow = true; + renderEntity.noSelfShadow = true; + renderEntity.customSkin = NULL; + + // set default shader parms + renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; + renderEntity.shaderParms[ SHADERPARM_GREEN ]= 1.0f; + renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; + renderEntity.shaderParms[3] = 1.0f; + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = 0.0f; + renderEntity.shaderParms[5] = 0.0f; + renderEntity.shaderParms[6] = 0.0f; + renderEntity.shaderParms[7] = 0.0f; + + if ( refSound.referenceSound ) { + refSound.referenceSound->Free( true ); + } + memset( &refSound, 0, sizeof( refSound_t ) ); + + // setting diversity to 0 results in no random sound. -1 indicates random. + refSound.diversity = -1.0f; + + if ( owner ) { + // don't spatialize the weapon sounds + refSound.listenerId = owner->GetListenerId(); + } + + // clear out the sounds from our spawnargs since we'll copy them from the weapon def + const idKeyValue *kv = spawnArgs.MatchPrefix( "snd_" ); + while( kv ) + { + spawnArgs.Delete( kv->GetKey() ); + kv = spawnArgs.MatchPrefix( "snd_" ); + } + // And the propagated sounds: + kv = spawnArgs.MatchPrefix( "sprS_" ); + while( kv ) + { + spawnArgs.Delete( kv->GetKey() ); + kv = spawnArgs.MatchPrefix( "sprS_" ); + } + + hideTime = 300; + hideDistance = -15.0f; + hideStartTime = gameLocal.time - hideTime; + hideStart = 0.0f; + hideEnd = 0.0f; + hideOffset = 0.0f; + hide = false; + disabled = false; + + weaponSmoke = NULL; + weaponSmokeStartTime = 0; + continuousSmoke = false; + strikeSmoke = NULL; + strikeSmokeStartTime = 0; + strikePos.Zero(); + strikeAxis = mat3_identity; + nextStrikeFx = 0; + + icon = ""; + + playerViewAxis.Identity(); + playerViewOrigin.Zero(); + viewWeaponAxis.Identity(); + viewWeaponOrigin.Zero(); + muzzleAxis.Identity(); + muzzleOrigin.Zero(); + pushVelocity.Zero(); + + status = WP_HOLSTERED; + state = ""; + idealState = ""; + animBlendFrames = 0; + animDoneTime = 0; + + meleeDef = NULL; + meleeDefName = ""; + meleeDistance = 0.0f; + brassDict.Clear(); + + flashTime = 250; + lightOn = false; + + ammoRequired = 0; + ammoClip = 0; + clipSize = 0; + lowAmmo = 0; + powerAmmo = false; + + kick_endtime = 0; + muzzle_kick_time = 0; + muzzle_kick_maxtime = 0; + muzzle_kick_angles.Zero(); + muzzle_kick_offset.Zero(); + + zoomFov = 90; + + barrelJointView = INVALID_JOINT; + flashJointView = INVALID_JOINT; + ejectJointView = INVALID_JOINT; + guiLightJointView = INVALID_JOINT; + ventLightJointView = INVALID_JOINT; + + barrelJointWorld = INVALID_JOINT; + flashJointWorld = INVALID_JOINT; + ejectJointWorld = INVALID_JOINT; + + hasBloodSplat = false; + nozzleFx = false; + nozzleFxFade = 1500; + lastAttack = 0; + nozzleGlowHandle = -1; + nozzleGlowShader = NULL; + nozzleGlowRadius = 10; + nozzleGlowColor.Zero(); + + weaponAngleOffsetAverages = 0; + weaponAngleOffsetScale = 0.0f; + weaponAngleOffsetMax = 0.0f; + weaponOffsetTime = 0.0f; + weaponOffsetScale = 0.0f; + + allowDrop = true; + + animator.ClearAllAnims( gameLocal.time, 0 ); + FreeModelDef(); + + sndHum = NULL; + + isLinked = false; + projectileEnt = NULL; + + isFiring = false; + + // TDM: destroy previous weapon attachments + for( int i=0; iEvent_Remove(); + } + + m_Attachments.Clear(); + + m_animRates.Clear(); + + // clear attack flags on the player + if( owner ) + { + owner->SetAttackFlag(COMBAT_MELEE, false); + owner->SetAttackFlag(COMBAT_RANGED, false); + } +} + +/* +================ +idWeapon::InitWorldModel +================ +*/ +void idWeapon::InitWorldModel( const idDeclEntityDef *def ) { + idEntity *ent; + + ent = worldModel.GetEntity(); + + assert( ent ); + assert( def ); + + const char *model = def->dict.GetString( "model_world" ); + const char *attach = def->dict.GetString( "joint_attach" ); + + ent->SetSkin( NULL ); + if ( model[0] && attach[0] ) { + ent->Show(); + ent->SetModel( model ); + if ( ent->GetAnimator()->ModelDef() ) { + ent->SetSkin( ent->GetAnimator()->ModelDef()->GetDefaultSkin() ); + } + ent->GetPhysics()->SetContents( 0 ); + ent->GetPhysics()->SetClipModel( NULL, 1.0f ); + ent->BindToJoint( owner, attach, true ); + ent->GetPhysics()->SetOrigin( vec3_origin ); + ent->GetPhysics()->SetAxis( mat3_identity ); + + // supress model in player views, but allow it in mirrors and remote views + renderEntity_t *worldModelRenderEntity = ent->GetRenderEntity(); + if ( worldModelRenderEntity ) { + worldModelRenderEntity->suppressSurfaceInViewID = owner->entityNumber+1; + worldModelRenderEntity->suppressShadowInViewID = owner->entityNumber+1; + worldModelRenderEntity->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; + } + } else { + ent->SetModel( "" ); + ent->Hide(); + } + + flashJointWorld = ent->GetAnimator()->GetJointHandle( "flash" ); + barrelJointWorld = ent->GetAnimator()->GetJointHandle( "muzzle" ); + ejectJointWorld = ent->GetAnimator()->GetJointHandle( "eject" ); +} + +/* +================ +idWeapon::GetWeaponDef +================ +*/ +void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { + const char *shader; + const char *objectType; + const char *vmodel; + const char *guiName; + const char *brassDefName; + const char *smokeName; + int ammoAvail = 0; + + Clear(); + + if ( !objectname || !objectname[ 0 ] ) { + return; + } + + assert( owner ); + + weaponDef = gameLocal.FindEntityDef( objectname ); + + ammoRequired = weaponDef->dict.GetInt( "ammo_required" ); + + idStr ammoDefName = weaponDef->dict.GetString("def_ammo"); + + if (ammoDefName.IsEmpty() && weaponDef->dict.GetBool("ammo_required")) + { + gameLocal.Error("No 'ammo' spawnarg defined for weapon %s", objectname); + } + + + clipSize = weaponDef->dict.GetInt( "clipSize" ); + lowAmmo = weaponDef->dict.GetInt( "lowAmmo" ); + + icon = weaponDef->dict.GetString( "icon" ); + powerAmmo = weaponDef->dict.GetBool( "powerAmmo" ); + + muzzle_kick_time = SEC2MS( weaponDef->dict.GetFloat( "muzzle_kick_time" ) ); + muzzle_kick_maxtime = SEC2MS( weaponDef->dict.GetFloat( "muzzle_kick_maxtime" ) ); + muzzle_kick_angles = weaponDef->dict.GetAngles( "muzzle_kick_angles" ); + muzzle_kick_offset = weaponDef->dict.GetVector( "muzzle_kick_offset" ); + + hideTime = SEC2MS( weaponDef->dict.GetFloat( "hide_time", "0.3" ) ); + hideDistance = weaponDef->dict.GetFloat( "hide_distance", "-15" ); + + // muzzle smoke + smokeName = weaponDef->dict.GetString( "smoke_muzzle" ); + if ( *smokeName != '\0' ) { + weaponSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + } else { + weaponSmoke = NULL; + } + continuousSmoke = weaponDef->dict.GetBool( "continuousSmoke" ); + weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal.time : 0; + + smokeName = weaponDef->dict.GetString( "smoke_strike" ); + if ( *smokeName != '\0' ) { + strikeSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); + } else { + strikeSmoke = NULL; + } + strikeSmokeStartTime = 0; + strikePos.Zero(); + strikeAxis = mat3_identity; + nextStrikeFx = 0; + + // setup gui light + memset( &guiLight, 0, sizeof( guiLight ) ); + const char *guiLightShader = weaponDef->dict.GetString( "mtr_guiLightShader" ); + if ( *guiLightShader != '\0' ) { + guiLight.shader = declManager->FindMaterial( guiLightShader, false ); + guiLight.lightRadius[0] = guiLight.lightRadius[1] = guiLight.lightRadius[2] = 3; + guiLight.pointLight = true; + } + + // setup the view model + vmodel = weaponDef->dict.GetString( "model_view" ); + SetModel( vmodel ); + + // setup the world model + InitWorldModel( weaponDef ); + + // copy the sounds from the weapon view model def into out spawnargs + const idKeyValue *kv = weaponDef->dict.MatchPrefix( "snd_" ); + while( kv ) + { + spawnArgs.Set( kv->GetKey(), kv->GetValue() ); + kv = weaponDef->dict.MatchPrefix( "snd_", kv ); + } + // And the propagated sounds + kv = weaponDef->dict.MatchPrefix( "sprS_" ); + while( kv ) + { + spawnArgs.Set( kv->GetKey(), kv->GetValue() ); + kv = weaponDef->dict.MatchPrefix( "sprS_", kv ); + } + + // find some joints in the model for locating effects + barrelJointView = animator.GetJointHandle( "barrel" ); + flashJointView = animator.GetJointHandle( "flash" ); + ejectJointView = animator.GetJointHandle( "eject" ); + guiLightJointView = animator.GetJointHandle( "guiLight" ); + ventLightJointView = animator.GetJointHandle( "ventLight" ); + + // ishtvan: Cache the anim rates here to adjust weapon anim speeds + int anims = animator.NumAnims(); + m_animRates.Clear(); + m_animRates.AssureSize(anims); + for (int i=0; iName(); + m_animRates[i] = weaponDef->dict.GetFloat(spawnargname, "1"); + } else + { + m_animRates[i] = 1.0f; + } + } + + // get the projectile + // greebo: Disabled, the projectile def is loaded on demand + /*projectileName = weaponDef->dict.GetString( "def_projectile" ); + if ( projectileName[0] != '\0' ) { + const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( projectileName, false ); + if ( !projectileDef ) { + gameLocal.Warning( "Unknown projectile '%s' in weapon '%s'", projectileName, objectname ); + } else { + const char *spawnclass = projectileDef->dict.GetString( "spawnclass" ); + idTypeInfo *cls = idClass::GetClass( spawnclass ); + if ( !cls || !cls->IsType( idProjectile::Type ) ) { + gameLocal.Warning( "Invalid spawnclass '%s' on projectile '%s' (used by weapon '%s')", spawnclass, projectileName, objectname ); + } else { + projectileDict = projectileDef->dict; + } + } + }*/ + + // set up muzzleflash render light + const idMaterial*flashShader; + idVec3 flashTarget; + idVec3 flashUp; + idVec3 flashRight; + float flashRadius; + bool flashPointLight; + + weaponDef->dict.GetString( "mtr_flashShader", "", &shader ); + flashShader = declManager->FindMaterial( shader, false ); + flashPointLight = weaponDef->dict.GetBool( "flashPointLight", "1" ); + weaponDef->dict.GetVector( "flashColor", "0 0 0", flashColor ); + flashRadius = (float)weaponDef->dict.GetInt( "flashRadius" ); // if 0, no light will spawn + flashTime = SEC2MS( weaponDef->dict.GetFloat( "flashTime", "0.25" ) ); + flashTarget = weaponDef->dict.GetVector( "flashTarget" ); + flashUp = weaponDef->dict.GetVector( "flashUp" ); + flashRight = weaponDef->dict.GetVector( "flashRight" ); + + memset( &muzzleFlash, 0, sizeof( muzzleFlash ) ); + muzzleFlash.lightId = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; + muzzleFlash.allowLightInViewID = owner->entityNumber+1; + + // the weapon lights will only be in first person + guiLight.allowLightInViewID = owner->entityNumber+1; + nozzleGlow.allowLightInViewID = owner->entityNumber+1; + + muzzleFlash.pointLight = flashPointLight; + muzzleFlash.shader = flashShader; + muzzleFlash.shaderParms[ SHADERPARM_RED ] = flashColor[0]; + muzzleFlash.shaderParms[ SHADERPARM_GREEN ] = flashColor[1]; + muzzleFlash.shaderParms[ SHADERPARM_BLUE ] = flashColor[2]; + muzzleFlash.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; + + muzzleFlash.lightRadius[0] = flashRadius; + muzzleFlash.lightRadius[1] = flashRadius; + muzzleFlash.lightRadius[2] = flashRadius; + + if ( !flashPointLight ) { + muzzleFlash.target = flashTarget; + muzzleFlash.up = flashUp; + muzzleFlash.right = flashRight; + muzzleFlash.end = flashTarget; + } + + // the world muzzle flash is the same, just positioned differently + worldMuzzleFlash = muzzleFlash; + worldMuzzleFlash.suppressLightInViewID = owner->entityNumber+1; + worldMuzzleFlash.allowLightInViewID = 0; + worldMuzzleFlash.lightId = LIGHTID_WORLD_MUZZLE_FLASH + owner->entityNumber; + + //----------------------------------- + + nozzleFx = weaponDef->dict.GetBool("nozzleFx"); + nozzleFxFade = weaponDef->dict.GetInt("nozzleFxFade", "1500"); + nozzleGlowColor = weaponDef->dict.GetVector("nozzleGlowColor", "1 1 1"); + nozzleGlowRadius = weaponDef->dict.GetFloat("nozzleGlowRadius", "10"); + weaponDef->dict.GetString( "mtr_nozzleGlowShader", "", &shader ); + nozzleGlowShader = declManager->FindMaterial( shader, false ); + + // get the melee damage def + meleeDistance = weaponDef->dict.GetFloat( "melee_distance" ); + meleeDefName = weaponDef->dict.GetString( "def_melee" ); + if ( meleeDefName.Length() ) { + meleeDef = gameLocal.FindEntityDef( meleeDefName, false ); + if ( !meleeDef ) { + gameLocal.Error( "Unknown melee '%s'", meleeDefName.c_str() ); + } + } + + // get the brass def + brassDict.Clear(); + brassDelay = weaponDef->dict.GetInt( "ejectBrassDelay", "0" ); + brassDefName = weaponDef->dict.GetString( "def_ejectBrass" ); + + if ( brassDefName[0] ) { + const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( brassDefName, false ); + if ( !brassDef ) { + gameLocal.Warning( "Unknown brass '%s'", brassDefName ); + } else { + brassDict = brassDef->dict; + } + } + + ammoClip = ammoinclip; + if ( ( ammoClip < 0 ) || ( ammoClip > clipSize ) ) { + // first time using this weapon so have it fully loaded to start + ammoClip = clipSize; + CInventoryWeaponItemPtr weaponItem = owner->GetCurrentWeaponItem(); + if (weaponItem != NULL) { + ammoAvail = weaponItem->HasAmmo(); + } + if ( ammoClip > ammoAvail ) { + ammoClip = ammoAvail; + } + } + + renderEntity.gui[ 0 ] = NULL; + guiName = weaponDef->dict.GetString( "gui" ); + if ( guiName[0] ) { + renderEntity.gui[ 0 ] = uiManager->FindGui( guiName, true, false, true ); + } + + zoomFov = weaponDef->dict.GetInt( "zoomFov", "70" ); + berserk = weaponDef->dict.GetInt( "berserk", "2" ); + + weaponAngleOffsetAverages = weaponDef->dict.GetInt( "weaponAngleOffsetAverages", "10" ); + weaponAngleOffsetScale = weaponDef->dict.GetFloat( "weaponAngleOffsetScale", "0.25" ); + weaponAngleOffsetMax = weaponDef->dict.GetFloat( "weaponAngleOffsetMax", "10" ); + + weaponOffsetTime = weaponDef->dict.GetFloat( "weaponOffsetTime", "400" ); + weaponOffsetScale = weaponDef->dict.GetFloat( "weaponOffsetScale", "0.005" ); + + // Bow aimer related -- By Dram + const idKeyValue *AimerKeyVal = weaponDef->dict.MatchPrefix( "def_aimer", NULL ); + idEntity *bow_aimer( NULL ); + if ( AimerKeyVal ) // grayman - always attach the aimer + { + idDict aimerArgs; + aimerArgs.Set( "classname", AimerKeyVal->GetValue().c_str() ); + aimerArgs.Set( "dropToFloor", "0" ); + gameLocal.SpawnEntityDef( aimerArgs, &bow_aimer ); + if ( bow_aimer ) + { + Attach( bow_aimer, NULL, NULL ); + } + + // show it or hide it initially based on the menu setting + + if ( !cv_bow_aimer.GetBool() ) + { + bow_aimer->Hide(); + } + } + + // spawn any weapon attachments we might have + const idKeyValue *KeyVal = weaponDef->dict.MatchPrefix( "def_attach", NULL ); + idEntity *ent(NULL); + + while ( KeyVal ) + { + idDict args2; + + args2.Set( "classname", KeyVal->GetValue().c_str() ); + + // don't let them drop to the floor + args2.Set( "dropToFloor", "0" ); + + gameLocal.SpawnEntityDef( args2, &ent ); + if ( !ent ) + { + gameLocal.Error( "Couldn't spawn '%s' to attach to entity '%s'", KeyVal->GetValue().c_str(), name.c_str() ); + } else + { + DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("Def_Attaching entity %s to weapon entity %s.\r", ent->name.c_str(), name.c_str()); + + // check for attachment position spawnarg + idStr Suffix = KeyVal->GetKey(); + Suffix.StripLeading( "def_attach" ); + idStr PosKey = "pos_attach" + Suffix; + // String name of the attachment for later accessing + idStr AttName = "name_attach" + Suffix; + + if( weaponDef->dict.FindKey(PosKey.c_str()) ) + Attach( ent, weaponDef->dict.GetString(PosKey.c_str()), + weaponDef->dict.GetString(AttName.c_str()) ); + else + Attach( ent, NULL, weaponDef->dict.GetString(AttName.c_str()) ); + if (IsRanged()) // grayman #597 - hide arrows for one second & play an 'equip' sound + { + ent->Hide(); + ent->SetHideUntilTime(gameLocal.time + 1000); + + // Play an arrow-equipping sound + + if (arrow2Arrow) + { + const char *shader = "arrow_equip"; + const idSoundShader *sndEquip = declManager->FindSound(shader); + StartSoundShader(sndEquip,SND_CHANNEL_BODY,0,false,NULL); + } + } + } + KeyVal = weaponDef->dict.MatchPrefix( "def_attach", KeyVal ); + } + + if ( !weaponDef->dict.GetString( "weapon_scriptobject", NULL, &objectType ) ) { + gameLocal.Error( "No 'weapon_scriptobject' set on '%s'.", objectname ); + } + + // setup script object + if ( !scriptObject.SetType( objectType ) ) { + gameLocal.Error( "Script object '%s' not found on weapon '%s'.", objectType, objectname ); + } + + WEAPON_ATTACK.LinkTo( scriptObject, "WEAPON_ATTACK" ); + WEAPON_BLOCK.LinkTo( scriptObject, "WEAPON_BLOCK" ); + WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); + WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); + WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); + WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); + WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); + WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); + + spawnArgs = weaponDef->dict; + + shader = spawnArgs.GetString( "snd_hum" ); + if ( shader && *shader ) { + sndHum = declManager->FindSound( shader ); + StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + } + + isLinked = true; + + // call script object's constructor + ConstructScriptObject(); + + // make sure we have the correct skin + UpdateSkin(); + + // update attack flags on the player + if(weaponDef->dict.GetBool("is_weapon_melee")) + { + owner->SetAttackFlag(COMBAT_MELEE, true); + } + else if(weaponDef->dict.GetBool("is_weapon_ranged")) + { + owner->SetAttackFlag(COMBAT_RANGED, true); + } +} + +/*********************************************************************** + + GUIs + +***********************************************************************/ + +/* +================ +idWeapon::Icon +================ +*/ +const char *idWeapon::Icon( void ) const { + return icon; +} + +/* +================ +idWeapon::UpdateGUI +================ +*/ +void idWeapon::UpdateGUI( void ) { + if ( !renderEntity.gui[ 0 ] ) { + return; + } + + if ( status == WP_HOLSTERED ) { + return; + } + + if ( owner->weaponGone ) { + // dropping weapons was implemented wierd, so we have to not update the gui when it happens or we'll get a negative ammo count + return; + } + + if ( gameLocal.localClientNum != owner->entityNumber ) { + // if updating the hud for a followed client + if ( gameLocal.localClientNum >= 0 && gameLocal.entities[ gameLocal.localClientNum ] && gameLocal.entities[ gameLocal.localClientNum ]->IsType( idPlayer::Type ) ) { + idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ gameLocal.localClientNum ] ); + if ( !p->spectating || p->spectator != owner->entityNumber ) { + return; + } + } else { + return; + } + } + + int inclip = AmmoInClip(); + int ammoamount = AmmoAvailable(); + + if ( ammoamount < 0 ) { + // show infinite ammo + renderEntity.gui[ 0 ]->SetStateString( "player_ammo", "" ); + } else { + // show remaining ammo + renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount - inclip) ); + renderEntity.gui[ 0 ]->SetStateString( "player_ammo", ClipSize() ? va( "%i", inclip ) : "--" ); + renderEntity.gui[ 0 ]->SetStateString( "player_clips", ClipSize() ? va("%i", ammoamount / ClipSize()) : "--" ); + renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount - inclip ) ); + } + renderEntity.gui[ 0 ]->SetStateBool( "player_ammo_empty", ( ammoamount == 0 ) ); + renderEntity.gui[ 0 ]->SetStateBool( "player_clip_empty", ( inclip == 0 ) ); + renderEntity.gui[ 0 ]->SetStateBool( "player_clip_low", ( inclip <= lowAmmo ) ); +} + +/*********************************************************************** + + Model and muzzleflash + +***********************************************************************/ + +/* +================ +idWeapon::UpdateFlashPosition +================ +*/ +void idWeapon::UpdateFlashPosition( void ) { + // the flash has an explicit joint for locating it + GetGlobalJointTransform( true, flashJointView, muzzleFlash.origin, muzzleFlash.axis ); + + // if the desired point is inside or very close to a wall, back it up until it is clear + idVec3 start = muzzleFlash.origin - playerViewAxis[0] * 16; + idVec3 end = muzzleFlash.origin + playerViewAxis[0] * 8; + trace_t tr; + gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL, owner ); + // be at least 8 units away from a solid + muzzleFlash.origin = tr.endpos - playerViewAxis[0] * 8; + + // put the world muzzle flash on the end of the joint, no matter what + GetGlobalJointTransform( false, flashJointWorld, worldMuzzleFlash.origin, worldMuzzleFlash.axis ); +} + +/* +================ +idWeapon::MuzzleFlashLight +================ +*/ +void idWeapon::MuzzleFlashLight( void ) { + + if ( !lightOn && ( !g_muzzleFlash.GetBool() || !muzzleFlash.lightRadius[0] ) ) { + return; + } + + if ( flashJointView == INVALID_JOINT ) { + return; + } + + UpdateFlashPosition(); + + // these will be different each fire + muzzleFlash.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + muzzleFlash.shaderParms[ SHADERPARM_DIVERSITY ] = renderEntity.shaderParms[ SHADERPARM_DIVERSITY ]; + + worldMuzzleFlash.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + worldMuzzleFlash.shaderParms[ SHADERPARM_DIVERSITY ] = renderEntity.shaderParms[ SHADERPARM_DIVERSITY ]; + + // the light will be removed at this time + muzzleFlashEnd = gameLocal.time + flashTime; + + if ( muzzleFlashHandle != -1 ) { + gameRenderWorld->UpdateLightDef( muzzleFlashHandle, &muzzleFlash ); + gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); + } else { + muzzleFlashHandle = gameRenderWorld->AddLightDef( &muzzleFlash ); + worldMuzzleFlashHandle = gameRenderWorld->AddLightDef( &worldMuzzleFlash ); + } +} + +/* +================ +idWeapon::UpdateSkin +================ +*/ +bool idWeapon::UpdateSkin( void ) { + const function_t *func; + + if ( !isLinked ) { + return false; + } + + func = scriptObject.GetFunction( "UpdateSkin" ); + if ( !func ) { + common->Warning( "Can't find function 'UpdateSkin' in object '%s'", scriptObject.GetTypeName() ); + return false; + } + + // use the frameCommandThread since it's safe to use outside of framecommands + gameLocal.frameCommandThread->CallFunction( this, func, true ); + gameLocal.frameCommandThread->Execute(); + + return true; +} + +/* +================ +idWeapon::SetModel +================ +*/ +void idWeapon::SetModel( const char *modelname ) { + assert( modelname ); + + if ( modelDefHandle >= 0 ) { + gameRenderWorld->RemoveDecals( modelDefHandle ); + } + + renderEntity.hModel = animator.SetModel( modelname ); + if ( renderEntity.hModel ) { + renderEntity.customSkin = animator.ModelDef()->GetDefaultSkin(); + animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); + } else { + renderEntity.customSkin = NULL; + renderEntity.callback = NULL; + renderEntity.numJoints = 0; + renderEntity.joints = NULL; + } + + // hide the model until an animation is played + Hide(); +} + +/* +================ +idWeapon::GetGlobalJointTransform + +This returns the offset and axis of a weapon bone in world space, suitable for attaching models or lights +================ +*/ +bool idWeapon::GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) { + if ( viewModel ) { + // view model + if ( animator.GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { + offset = offset * viewWeaponAxis + viewWeaponOrigin; + axis = axis * viewWeaponAxis; + return true; + } + } else { + // world model + if ( worldModel.GetEntity() && worldModel.GetEntity()->GetAnimator()->GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { + offset = worldModel.GetEntity()->GetPhysics()->GetOrigin() + offset * worldModel.GetEntity()->GetPhysics()->GetAxis(); + axis = axis * worldModel.GetEntity()->GetPhysics()->GetAxis(); + return true; + } + } + offset = viewWeaponOrigin; + axis = viewWeaponAxis; + return false; +} + +/* +================ +idWeapon::SetPushVelocity +================ +*/ +void idWeapon::SetPushVelocity( const idVec3 &pushVelocity ) { + this->pushVelocity = pushVelocity; +} + + +/*********************************************************************** + + State control/player interface + +***********************************************************************/ + +/* +================ +idWeapon::Think +================ +*/ +void idWeapon::Think( void ) { + // do nothing because the present is called from the player through PresentWeapon +} + +/* +================ +idWeapon::Raise +================ +*/ +void idWeapon::Raise( void ) { + if ( isLinked ) { + WEAPON_RAISEWEAPON = true; + } +} + +/* +================ +idWeapon::PutAway +================ +*/ +void idWeapon::PutAway( void ) { + hasBloodSplat = false; + if ( isLinked ) { + WEAPON_LOWERWEAPON = true; + } +} + +/* +================ +idWeapon::SetArrow2Arrow +================ +*/ +void idWeapon::SetArrow2Arrow( bool state ) // grayman #597 +{ + arrow2Arrow = state; +} + + +/* +================ +idWeapon::Reload +NOTE: this is only for impulse-triggered reload, auto reload is scripted +================ +*/ +void idWeapon::Reload( void ) { + if ( isLinked ) { + WEAPON_RELOAD = true; + } +} + +/* +================ +idWeapon::LowerWeapon +================ +*/ +void idWeapon::LowerWeapon( void ) { + if ( !hide ) { + hideStart = 0.0f; + hideEnd = hideDistance; + if ( gameLocal.time - hideStartTime < hideTime ) { + hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); + } else { + hideStartTime = gameLocal.time; + } + hide = true; + } +} + +/* +================ +idWeapon::RaiseWeapon +================ +*/ +void idWeapon::RaiseWeapon( void ) { + Show(); + + if ( hide ) { + hideStart = hideDistance; + hideEnd = 0.0f; + if ( gameLocal.time - hideStartTime < hideTime ) { + hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); + } else { + hideStartTime = gameLocal.time; + } + hide = false; + } +} + +/* +================ +idWeapon::HideWeapon +================ +*/ +void idWeapon::HideWeapon( void ) { + Hide(); + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->Hide(); + } + muzzleFlashEnd = 0; + + // hide attachments: + for(int i=0; iHide(); + } +} + +/* +================ +idWeapon::ShowWeapon +================ +*/ +void idWeapon::ShowWeapon( void ) { + Show(); + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->Show(); + } + if ( lightOn ) { + MuzzleFlashLight(); + } + + // show attachments + + // grayman #597 - don't show attachments if they're hidden and there's a hide timeout + + for (int i = 0; i < m_Attachments.Num() ; i++) + { + idEntity *e = m_Attachments[i].ent.GetEntity(); + if ((gameLocal.time >= e->GetHideUntilTime()) && e->IsHidden()) + { + e->Show(); + } + } +} + +/* +================ +idWeapon::HideWorldModel +================ +*/ +void idWeapon::HideWorldModel( void ) { + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->Hide(); + } +} + +/* +================ +idWeapon::ShowWorldModel +================ +*/ +void idWeapon::ShowWorldModel( void ) { + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->Show(); + } +} + +/* +================ +idWeapon::OwnerDied +================ +*/ +void idWeapon::OwnerDied( void ) { + if ( isLinked ) { + SetState( "OwnerDied", 0 ); + thread->Execute(); + } + + Hide(); + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->Hide(); + } + + // don't clear the weapon immediately since the owner might have killed himself by firing the weapon + // within the current stack frame + PostEventMS( &EV_Weapon_Clear, 0 ); +} + +/* +================ +idWeapon::BeginAttack +================ +*/ +void idWeapon::BeginAttack( void ) +{ + if ( status != WP_OUTOFAMMO ) { + lastAttack = gameLocal.time; + } + + if ( !isLinked ) { + return; + } + + if ( !WEAPON_ATTACK ) + { + if ( sndHum ) + { + StopSound( SND_CHANNEL_BODY, false ); + } + + // grayman #597 - show hidden arrows the first time through + + if (IsRanged()) + { + for (int i = 0; i < m_Attachments.Num() ; i++) + { + idEntity *e = m_Attachments[i].ent.GetEntity(); + + // grayman - If this is the bow aimer, and the player is using it, show it. + // If the player isn't using it, hide it. + + if ( idStr::Cmp( e->spawnArgs.GetString("classname"), "atdm:attachment_aimer" ) == 0 ) + { + if ( cv_bow_aimer.GetBool() ) + { + if ( e->IsHidden() ) + { + e->Show(); + } + } + else if ( !e->IsHidden() ) + { + e->Hide(); + } + } + else if ( e->IsHidden() ) // attachments other than the bow aimer + { + e->Show(); + } + } + } + } + + WEAPON_ATTACK = true; +} + +/* +================ +idWeapon::EndAttack +================ +*/ +void idWeapon::EndAttack( void ) +{ + if ( !WEAPON_ATTACK.IsLinked() ) + return; + if ( WEAPON_ATTACK ) { + WEAPON_ATTACK = false; + if ( sndHum ) { + StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + } + } +} + +/* +================ +idWeapon::BeginBlock +================ +*/ +void idWeapon::BeginBlock( void ) +{ + lastBlock = gameLocal.time; + + if ( !isLinked ) + return; + + if ( !WEAPON_BLOCK ) + { + if ( sndHum ) + { + StopSound( SND_CHANNEL_BODY, false ); + } + } + WEAPON_BLOCK = true; +} + +/* +================ +idWeapon::EndBlock +================ +*/ +void idWeapon::EndBlock( void ) +{ + if ( !WEAPON_BLOCK.IsLinked() ) + return; + + if ( WEAPON_BLOCK ) + { + WEAPON_BLOCK = false; + if ( sndHum ) + StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + } +} + +/* +================ +idWeapon::isReady +================ +*/ +bool idWeapon::IsReady( void ) const { + return !hide && !IsHidden() && ( ( status == WP_RELOAD ) || ( status == WP_READY ) || ( status == WP_OUTOFAMMO ) ); +} + +/* +================ +idWeapon::IsReloading +================ +*/ +bool idWeapon::IsReloading( void ) const { + return ( status == WP_RELOAD ); +} + +/* +================ +idWeapon::IsHolstered +================ +*/ +bool idWeapon::IsHolstered( void ) const { + return ( status == WP_HOLSTERED ); +} + +/* +================ +idWeapon::ShowCrosshair +================ +*/ +bool idWeapon::ShowCrosshair( void ) const { +// return !( state == idStr( WP_RISING ) || state == idStr( WP_LOWERING ) || state == idStr( WP_HOLSTERED ) ); + // Never show the crosshair in TDM. + return false; +} + +/* +===================== +idWeapon::CanDrop +===================== +*/ +bool idWeapon::CanDrop( void ) const { + if ( !weaponDef || !worldModel.GetEntity() ) { + return false; + } + const char *classname = weaponDef->dict.GetString( "def_dropItem" ); + if ( !classname[ 0 ] ) { + return false; + } + return true; +} + +/* +================ +idWeapon::WeaponStolen +================ +*/ +void idWeapon::WeaponStolen( void ) { + assert( !gameLocal.isClient ); + if ( projectileEnt ) { + if ( isLinked ) { + SetState( "WeaponStolen", 0 ); + thread->Execute(); + } + projectileEnt = NULL; + } + + // set to holstered so we can switch weapons right away + status = WP_HOLSTERED; + + HideWeapon(); +} + +/* +===================== +idWeapon::DropItem +===================== +*/ +idEntity * idWeapon::DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died ) { + if ( !weaponDef || !worldModel.GetEntity() ) { + return NULL; + } + if ( !allowDrop ) { + return NULL; + } + const char *classname = weaponDef->dict.GetString( "def_dropItem" ); + if ( !classname[0] ) { + return NULL; + } + StopSound( SND_CHANNEL_BODY, true ); + StopSound( SND_CHANNEL_BODY3, true ); + + return idMoveableItem::DropItem( classname, worldModel.GetEntity()->GetPhysics()->GetOrigin(), worldModel.GetEntity()->GetPhysics()->GetAxis(), velocity, activateDelay, removeDelay ); +} + +/*********************************************************************** + + Script state management + +***********************************************************************/ + +/* +===================== +idWeapon::SetState +===================== +*/ +void idWeapon::SetState( const char *statename, int blendFrames ) { + const function_t *func; + + if ( !isLinked ) { + return; + } + + func = scriptObject.GetFunction( statename ); + if ( !func ) { + assert( 0 ); + gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); + } + + thread->CallFunction( this, func, true ); + state = statename; + + animBlendFrames = blendFrames; + if ( g_debugWeapon.GetBool() ) { + gameLocal.Printf( "%d: weapon state : %s\n", gameLocal.time, statename ); + } + + idealState = ""; +} + + +/*********************************************************************** + + Particles/Effects + +***********************************************************************/ + +/* +================ +idWeapon::UpdateNozzelFx +================ +*/ +void idWeapon::UpdateNozzleFx( void ) { + if ( !nozzleFx ) { + return; + } + + // + // shader parms + // + int la = gameLocal.time - lastAttack + 1; + float s = 1.0f; + float l = 0.0f; + if ( la < nozzleFxFade ) { + s = ((float)la / nozzleFxFade); + l = 1.0f - s; + } + renderEntity.shaderParms[5] = s; + renderEntity.shaderParms[6] = l; + + if ( ventLightJointView == INVALID_JOINT ) { + return; + } + + // + // vent light + // + if ( nozzleGlowHandle == -1 ) { + memset(&nozzleGlow, 0, sizeof(nozzleGlow)); + if ( owner ) { + nozzleGlow.allowLightInViewID = owner->entityNumber+1; + } + nozzleGlow.pointLight = true; + nozzleGlow.noShadows = true; + nozzleGlow.lightRadius.x = nozzleGlowRadius; + nozzleGlow.lightRadius.y = nozzleGlowRadius; + nozzleGlow.lightRadius.z = nozzleGlowRadius; + nozzleGlow.shader = nozzleGlowShader; + nozzleGlow.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; + nozzleGlow.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + GetGlobalJointTransform( true, ventLightJointView, nozzleGlow.origin, nozzleGlow.axis ); + nozzleGlowHandle = gameRenderWorld->AddLightDef(&nozzleGlow); + } + + GetGlobalJointTransform( true, ventLightJointView, nozzleGlow.origin, nozzleGlow.axis ); + + nozzleGlow.shaderParms[ SHADERPARM_RED ] = nozzleGlowColor.x * s; + nozzleGlow.shaderParms[ SHADERPARM_GREEN ] = nozzleGlowColor.y * s; + nozzleGlow.shaderParms[ SHADERPARM_BLUE ] = nozzleGlowColor.z * s; + gameRenderWorld->UpdateLightDef(nozzleGlowHandle, &nozzleGlow); +} + + +/* +================ +idWeapon::BloodSplat +================ +*/ +bool idWeapon::BloodSplat( float size ) { + float s, c; + idMat3 localAxis, axistemp; + idVec3 localOrigin, normal; + + if ( hasBloodSplat ) { + return true; + } + + hasBloodSplat = true; + + if ( modelDefHandle < 0 ) { + return false; + } + + if ( !GetGlobalJointTransform( true, ejectJointView, localOrigin, localAxis ) ) { + return false; + } + + localOrigin[0] += gameLocal.random.RandomFloat() * -10.0f; + localOrigin[1] += gameLocal.random.RandomFloat() * 1.0f; + localOrigin[2] += gameLocal.random.RandomFloat() * -2.0f; + + normal = idVec3( gameLocal.random.CRandomFloat(), -gameLocal.random.RandomFloat(), -1 ); + normal.Normalize(); + + idMath::SinCos16( gameLocal.random.RandomFloat() * idMath::TWO_PI, s, c ); + + localAxis[2] = -normal; + localAxis[2].NormalVectors( axistemp[0], axistemp[1] ); + localAxis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; + localAxis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; + + localAxis[0] *= 1.0f / size; + localAxis[1] *= 1.0f / size; + + idPlane localPlane[2]; + + localPlane[0] = localAxis[0]; + localPlane[0][3] = -(localOrigin * localAxis[0]) + 0.5f; + + localPlane[1] = localAxis[1]; + localPlane[1][3] = -(localOrigin * localAxis[1]) + 0.5f; + + const idMaterial *mtr = declManager->FindMaterial( "textures/decals/duffysplatgun" ); + + gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr ); + + return true; +} + + +/*********************************************************************** + + Visual presentation + +***********************************************************************/ + +/* +================ +idWeapon::MuzzleRise + +The machinegun and chaingun will incrementally back up as they are being fired +================ +*/ +void idWeapon::MuzzleRise( idVec3 &origin, idMat3 &axis ) { + int time; + float amount; + idAngles ang; + idVec3 offset; + + time = kick_endtime - gameLocal.time; + if ( time <= 0 ) { + return; + } + + if ( muzzle_kick_maxtime <= 0 ) { + return; + } + + if ( time > muzzle_kick_maxtime ) { + time = muzzle_kick_maxtime; + } + + amount = ( float )time / ( float )muzzle_kick_maxtime; + ang = muzzle_kick_angles * amount; + offset = muzzle_kick_offset * amount; + + origin = origin - axis * offset; + axis = ang.ToMat3() * axis; +} + +/* +================ +idWeapon::ConstructScriptObject + +Called during idEntity::Spawn. Calls the constructor on the script object. +Can be overridden by subclasses when a thread doesn't need to be allocated. +================ +*/ +idThread *idWeapon::ConstructScriptObject( void ) { + const function_t *constructor; + + thread->EndThread(); + + // call script object's constructor + constructor = scriptObject.GetConstructor(); + if ( !constructor ) { + gameLocal.Error( "Missing constructor on '%s' for weapon", scriptObject.GetTypeName() ); + } + + // init the script object's data + scriptObject.ClearObject(); + thread->CallFunction( this, constructor, true ); + thread->Execute(); + + return thread; +} + +/* +================ +idWeapon::DeconstructScriptObject + +Called during idEntity::~idEntity. Calls the destructor on the script object. +Can be overridden by subclasses when a thread doesn't need to be allocated. +Not called during idGameLocal::MapShutdown. +================ +*/ +void idWeapon::DeconstructScriptObject( void ) { + const function_t *destructor; + + if ( !thread ) { + return; + } + + // don't bother calling the script object's destructor on map shutdown + if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) { + return; + } + + thread->EndThread(); + + // call script object's destructor + destructor = scriptObject.GetDestructor(); + if ( destructor ) { + // start a thread that will run immediately and end + thread->CallFunction( this, destructor, true ); + thread->Execute(); + thread->EndThread(); + } + + // clear out the object's memory + scriptObject.ClearObject(); +} + +/* +================ +idWeapon::UpdateScript +================ +*/ +void idWeapon::UpdateScript( void ) { + int count; + + if ( !isLinked ) { + return; + } + + // only update the script on new frames + if ( !gameLocal.isNewFrame ) { + return; + } + + if ( idealState.Length() ) { + SetState( idealState, animBlendFrames ); + } + + // update script state, which may call Event_LaunchProjectiles, among other things + count = 10; + while( ( thread->Execute() || idealState.Length() ) && count-- ) { + // happens for weapons with no clip (like grenades) + if ( idealState.Length() ) { + SetState( idealState, animBlendFrames ); + } + } + + WEAPON_RELOAD = false; +} + +/* +================ +idWeapon::AlertMonsters +================ +*/ +void idWeapon::AlertMonsters( void ) { + trace_t tr; + idEntity *ent; + idVec3 end = muzzleFlash.origin + muzzleFlash.axis * muzzleFlash.target; + + gameLocal.clip.TracePoint( tr, muzzleFlash.origin, end, CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER, owner ); + if ( g_debugWeapon.GetBool() ) { + gameRenderWorld->DebugLine( colorYellow, muzzleFlash.origin, end, 0 ); + gameRenderWorld->DebugArrow( colorGreen, muzzleFlash.origin, tr.endpos, 2, 0 ); + } + + if ( tr.fraction < 1.0f ) { + ent = gameLocal.GetTraceEntity( tr ); + if ( ent->IsType( idAI::Type ) ) { + static_cast( ent )->TouchedByFlashlight( owner ); + } else if ( ent->IsType( idTrigger::Type ) ) { + ent->Signal( SIG_TOUCH ); + ent->ProcessEvent( &EV_Touch, owner, &tr ); + } + } + + // jitter the trace to try to catch cases where a trace down the center doesn't hit the monster + end += muzzleFlash.axis * muzzleFlash.right * idMath::Sin16( MS2SEC( gameLocal.time ) * 31.34f ); + end += muzzleFlash.axis * muzzleFlash.up * idMath::Sin16( MS2SEC( gameLocal.time ) * 12.17f ); + gameLocal.clip.TracePoint( tr, muzzleFlash.origin, end, CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER, owner ); + if ( g_debugWeapon.GetBool() ) { + gameRenderWorld->DebugLine( colorYellow, muzzleFlash.origin, end, 0 ); + gameRenderWorld->DebugArrow( colorGreen, muzzleFlash.origin, tr.endpos, 2, 0 ); + } + + if ( tr.fraction < 1.0f ) { + ent = gameLocal.GetTraceEntity( tr ); + if ( ent->IsType( idAI::Type ) ) { + static_cast( ent )->TouchedByFlashlight( owner ); + } else if ( ent->IsType( idTrigger::Type ) ) { + ent->Signal( SIG_TOUCH ); + ent->ProcessEvent( &EV_Touch, owner, &tr ); + } + } +} + +/* +================ +idWeapon::PresentWeapon +================ +*/ +void idWeapon::PresentWeapon( bool showViewModel ) +{ + playerViewOrigin = owner->firstPersonViewOrigin; + playerViewAxis = owner->firstPersonViewAxis; + + // calculate weapon position based on player movement bobbing + owner->CalculateViewWeaponPos( viewWeaponOrigin, viewWeaponAxis ); + + // hide offset is for dropping the gun when approaching a GUI or NPC + // This is simpler to manage than doing the weapon put-away animation + if ( gameLocal.time - hideStartTime < hideTime ) { + float frac = ( float )( gameLocal.time - hideStartTime ) / ( float )hideTime; + if ( hideStart < hideEnd ) { + frac = 1.0f - frac; + frac = 1.0f - frac * frac; + } else { + frac = frac * frac; + } + hideOffset = hideStart + ( hideEnd - hideStart ) * frac; + } else { + hideOffset = hideEnd; + if ( hide && disabled ) { + Hide(); + } + } + viewWeaponOrigin += hideOffset * viewWeaponAxis[ 2 ]; + + // kick up based on repeat firing + MuzzleRise( viewWeaponOrigin, viewWeaponAxis ); + + // set the physics position and orientation + GetPhysics()->SetOrigin( viewWeaponOrigin ); + GetPhysics()->SetAxis( viewWeaponAxis ); + + // TDM/Ishtvan : Call RunPhysics to update bound entity positions + RunPhysics(); + + UpdateVisuals(); + + // update the weapon script + UpdateScript(); + + UpdateGUI(); + + // update animation + UpdateAnimation(); + + // only show the surface in player view + renderEntity.allowSurfaceInViewID = owner->entityNumber+1; + + // crunch the depth range so it never pokes into walls this breaks the machine gun gui + renderEntity.weaponDepthHack = true; + + // present the model + if ( showViewModel ) { + Present(); + } else { + FreeModelDef(); + } + + if ( worldModel.GetEntity() && worldModel.GetEntity()->GetRenderEntity() ) { + // deal with the third-person visible world model + // don't show shadows of the world model in first person + if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() || pm_thirdPerson.GetBool() ) { + worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; + } else { + worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = owner->entityNumber+1; + worldModel.GetEntity()->GetRenderEntity()->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; + } + } + + if ( nozzleFx ) { + UpdateNozzleFx(); + } + + // muzzle smoke + if ( showViewModel && !disabled && weaponSmoke && ( weaponSmokeStartTime != 0 ) ) { + // use the barrel joint if available + if ( barrelJointView ) { + GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); + } else { + // default to going straight out the view + muzzleOrigin = playerViewOrigin; + muzzleAxis = playerViewAxis; + } + // spit out a particle + if ( !gameLocal.smokeParticles->EmitSmoke( weaponSmoke, weaponSmokeStartTime, gameLocal.random.RandomFloat(), muzzleOrigin, muzzleAxis ) ) { + weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal.time : 0; + } + } + + if ( showViewModel && strikeSmoke && strikeSmokeStartTime != 0 ) { + // spit out a particle + if ( !gameLocal.smokeParticles->EmitSmoke( strikeSmoke, strikeSmokeStartTime, gameLocal.random.RandomFloat(), strikePos, strikeAxis ) ) { + strikeSmokeStartTime = 0; + } + } + + // remove the muzzle flash light when it's done + if ( ( !lightOn && ( gameLocal.time >= muzzleFlashEnd ) ) || IsHidden() ) { + if ( muzzleFlashHandle != -1 ) { + gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + muzzleFlashHandle = -1; + } + if ( worldMuzzleFlashHandle != -1 ) { + gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + worldMuzzleFlashHandle = -1; + } + } + + // update the muzzle flash light, so it moves with the gun + if ( muzzleFlashHandle != -1 ) { + UpdateFlashPosition(); + gameRenderWorld->UpdateLightDef( muzzleFlashHandle, &muzzleFlash ); + gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); + + // wake up monsters with the flashlight + if ( !gameLocal.isMultiplayer && lightOn && !owner->fl.notarget ) { + AlertMonsters(); + } + } + + // update the gui light + if ( guiLight.lightRadius[0] && guiLightJointView != INVALID_JOINT ) { + GetGlobalJointTransform( true, guiLightJointView, guiLight.origin, guiLight.axis ); + + if ( ( guiLightHandle != -1 ) ) { + gameRenderWorld->UpdateLightDef( guiLightHandle, &guiLight ); + } else { + guiLightHandle = gameRenderWorld->AddLightDef( &guiLight ); + } + } + + if ( status != WP_READY && sndHum ) { + StopSound( SND_CHANNEL_BODY, false ); + } + + UpdateSound(); +} + +/* +================ +idWeapon::EnterCinematic +================ +*/ +void idWeapon::EnterCinematic( void ) { + StopSound( SND_CHANNEL_ANY, false ); + + if ( isLinked ) { + SetState( "EnterCinematic", 0 ); + thread->Execute(); + + WEAPON_ATTACK = false; + WEAPON_BLOCK = false; + WEAPON_RELOAD = false; + WEAPON_NETRELOAD = false; + WEAPON_NETENDRELOAD = false; + WEAPON_NETFIRING = false; + WEAPON_RAISEWEAPON = false; + WEAPON_LOWERWEAPON = false; + } + + disabled = true; + arrow2Arrow = false; // grayman #597 - for arrow switching + + LowerWeapon(); +} + +/* +================ +idWeapon::ExitCinematic +================ +*/ +void idWeapon::ExitCinematic( void ) { + disabled = false; + + if ( isLinked ) { + SetState( "ExitCinematic", 0 ); + thread->Execute(); + } + + RaiseWeapon(); +} + +/* +================ +idWeapon::NetCatchup +================ +*/ +void idWeapon::NetCatchup( void ) { + if ( isLinked ) { + SetState( "NetCatchup", 0 ); + thread->Execute(); + } +} + +/* +================ +idWeapon::GetZoomFov +================ +*/ +int idWeapon::GetZoomFov( void ) { + return zoomFov; +} + +/* +================ +idWeapon::GetWeaponAngleOffsets +================ +*/ +void idWeapon::GetWeaponAngleOffsets( int *average, float *scale, float *max ) { + *average = weaponAngleOffsetAverages; + *scale = weaponAngleOffsetScale; + *max = weaponAngleOffsetMax; +} + +/* +================ +idWeapon::GetWeaponTimeOffsets +================ +*/ +void idWeapon::GetWeaponTimeOffsets( float *time, float *scale ) { + *time = weaponOffsetTime; + *scale = weaponOffsetScale; +} + + +/*********************************************************************** + + Ammo + +***********************************************************************/ + +/* +================ +idWeapon::GetAmmoNumForName +================ + +ammo_t idWeapon::GetAmmoNumForName( const char *ammoname ) { + int num; + const idDict *ammoDict; + + assert( ammoname ); + + ammoDict = gameLocal.FindEntityDefDict( "ammo_types", false ); + if ( !ammoDict ) { + gameLocal.Error( "Could not find entity definition for 'ammo_types'\n" ); + } + + if ( !ammoname[ 0 ] ) { + return 0; + } + + if ( !ammoDict->GetInt( ammoname, "-1", num ) ) { + gameLocal.Error( "Unknown ammo type '%s'", ammoname ); + } + + if ( ( num < 0 ) || ( num >= AMMO_NUMTYPES ) ) { + gameLocal.Error( "Ammo type '%s' value out of range. Maximum ammo types is %d.\n", ammoname, AMMO_NUMTYPES ); + } + + return ( ammo_t )num; +}*/ + +/* +================ +idWeapon::GetAmmoNameForNum +================ +*/ +const char *idWeapon::GetAmmoNameForNum( int ammonum ) { + int i; + int num; + const idDict *ammoDict; + const idKeyValue *kv; + char text[ 32 ]; + + ammoDict = gameLocal.FindEntityDefDict( "ammo_types", false ); + if ( !ammoDict ) { + gameLocal.Error( "Could not find entity definition for 'ammo_types'\n" ); + } + + sprintf( text, "%d", ammonum ); + + num = ammoDict->GetNumKeyVals(); + for( i = 0; i < num; i++ ) { + kv = ammoDict->GetKeyVal( i ); + if ( kv->GetValue() == text ) { + return kv->GetKey(); + } + } + + return NULL; +} + +/* +================ +idWeapon::GetAmmoPickupNameForNum +================ +*/ +const char *idWeapon::GetAmmoPickupNameForNum( int ammonum ) { + int i; + int num; + const idDict *ammoDict; + const idKeyValue *kv; + + ammoDict = gameLocal.FindEntityDefDict( "ammo_names", false ); + if ( !ammoDict ) { + gameLocal.Error( "Could not find entity definition for 'ammo_names'\n" ); + } + + const char *name = GetAmmoNameForNum( ammonum ); + + if ( name && *name ) { + num = ammoDict->GetNumKeyVals(); + for( i = 0; i < num; i++ ) { + kv = ammoDict->GetKeyVal( i ); + if ( idStr::Icmp( kv->GetKey(), name) == 0 ) { + return kv->GetValue(); + } + } + } + + return ""; +} + +/* +================ +idWeapon::AmmoAvailable +================ +*/ +int idWeapon::AmmoAvailable( void ) const { + if (owner && owner->GetCurrentWeaponItem()) { + return owner->GetCurrentWeaponItem()->HasAmmo(); + } else { + return 0; + } +} + +/* +================ +idWeapon::AmmoInClip +================ +*/ +int idWeapon::AmmoInClip( void ) const { + return ammoClip; +} + +/* +================ +idWeapon::ResetAmmoClip +================ +*/ +void idWeapon::ResetAmmoClip( void ) { + ammoClip = -1; +} + +/* +================ +idWeapon::ClipSize +================ +*/ +int idWeapon::ClipSize( void ) const { + return clipSize; +} + +/* +================ +idWeapon::LowAmmo +================ +*/ +int idWeapon::LowAmmo() const { + return lowAmmo; +} + +/* +================ +idWeapon::AmmoRequired +================ +*/ +int idWeapon::AmmoRequired( void ) const { + return ammoRequired; +} + +/* +================ +idWeapon::WriteToSnapshot +================ +*/ +void idWeapon::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteBits( ammoClip, ASYNC_PLAYER_INV_CLIP_BITS ); + msg.WriteBits( worldModel.GetSpawnId(), 32 ); + msg.WriteBits( lightOn, 1 ); + msg.WriteBits( isFiring ? 1 : 0, 1 ); +} + +/* +================ +idWeapon::ReadFromSnapshot +================ +*/ +void idWeapon::ReadFromSnapshot( const idBitMsgDelta &msg ) { + ammoClip = msg.ReadBits( ASYNC_PLAYER_INV_CLIP_BITS ); + worldModel.SetSpawnId( msg.ReadBits( 32 ) ); + bool snapLight = msg.ReadBits( 1 ) != 0; + isFiring = msg.ReadBits( 1 ) != 0; + + // WEAPON_NETFIRING is only turned on for other clients we're predicting. not for local client + if ( owner && gameLocal.localClientNum != owner->entityNumber && WEAPON_NETFIRING.IsLinked() ) { + + // immediately go to the firing state so we don't skip fire animations + if ( !WEAPON_NETFIRING && isFiring ) { + idealState = "Fire"; + } + + // immediately switch back to idle + if ( WEAPON_NETFIRING && !isFiring ) { + idealState = "Idle"; + } + + WEAPON_NETFIRING = isFiring; + } + + if ( snapLight != lightOn ) { + Reload(); + } +} + +/* +================ +idWeapon::ClientReceiveEvent +================ +*/ +bool idWeapon::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { + + switch( event ) { + case EVENT_RELOAD: { + if ( gameLocal.time - time < 1000 ) { + if ( WEAPON_NETRELOAD.IsLinked() ) { + WEAPON_NETRELOAD = true; + WEAPON_NETENDRELOAD = false; + } + } + return true; + } + case EVENT_ENDRELOAD: { + if ( WEAPON_NETENDRELOAD.IsLinked() ) { + WEAPON_NETENDRELOAD = true; + } + return true; + } + case EVENT_CHANGESKIN: { + int index = gameLocal.ClientRemapDecl( DECL_SKIN, msg.ReadLong() ); + renderEntity.customSkin = ( index != -1 ) ? static_cast( declManager->DeclByIndex( DECL_SKIN, index ) ) : NULL; + UpdateVisuals(); + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->SetSkin( renderEntity.customSkin ); + } + return true; + } + default: { + return idEntity::ClientReceiveEvent( event, time, msg ); + } + } +// return false; +} + +/* +idWeapon::IsRanged +*/ +bool idWeapon::IsRanged() { + // greebo: Check the weapon dictionary, whether a projectile def is declared + return (weaponDef != NULL && weaponDef->dict.FindKey("def_projectile") != NULL); +} + +/*********************************************************************** + + Script events + +***********************************************************************/ + +/* +=============== +idWeapon::Event_Clear +=============== +*/ +void idWeapon::Event_Clear( void ) { + Clear(); +} + +/* +=============== +idWeapon::Event_GetOwner +=============== +*/ +void idWeapon::Event_GetOwner( void ) { + idThread::ReturnEntity( owner ); +} + +/* +=============== +idWeapon::Event_WeaponState +=============== +*/ +void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { + const function_t *func; + + func = scriptObject.GetFunction( statename ); + if ( !func ) { + assert( 0 ); + gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); + } + + idealState = statename; + + if ( !idealState.Icmp( "Fire" ) ) { + isFiring = true; + } else { + isFiring = false; + } + + animBlendFrames = blendFrames; + thread->DoneProcessing(); +} + +/* +=============== +idWeapon::Event_WeaponReady +=============== +*/ +void idWeapon::Event_WeaponReady( void ) { + status = WP_READY; + if ( isLinked ) { + WEAPON_RAISEWEAPON = false; + } + if ( sndHum ) { + StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + } + +} + +/* +=============== +idWeapon::Event_WeaponOutOfAmmo +=============== +*/ +void idWeapon::Event_WeaponOutOfAmmo( void ) { + status = WP_OUTOFAMMO; + if ( isLinked ) { + WEAPON_RAISEWEAPON = false; + } +} + +/* +=============== +idWeapon::Event_WeaponReloading +=============== +*/ +void idWeapon::Event_WeaponReloading( void ) { + status = WP_RELOAD; +} + +/* +=============== +idWeapon::Event_WeaponHolstered +=============== +*/ +void idWeapon::Event_WeaponHolstered( void ) { + status = WP_HOLSTERED; + if ( isLinked ) { + WEAPON_LOWERWEAPON = false; + } +} + +/* +=============== +idWeapon::Event_WeaponRising +=============== +*/ +void idWeapon::Event_WeaponRising( void ) { + status = WP_RISING; + if ( isLinked ) { + WEAPON_LOWERWEAPON = false; + } + owner->WeaponRisingCallback(); +} + +/* +=============== +idWeapon::Event_WeaponLowering +=============== +*/ +void idWeapon::Event_WeaponLowering( void ) { + status = WP_LOWERING; + if ( isLinked ) { + WEAPON_RAISEWEAPON = false; + } + owner->WeaponLoweringCallback(); +} + +/* +=============== +idWeapon::Event_UseAmmo +=============== +*/ +void idWeapon::Event_UseAmmo( int amount ) { + if ( gameLocal.isClient ) { + return; + } + + owner->GetCurrentWeaponItem()->UseAmmo(( powerAmmo ) ? amount : ( amount * ammoRequired ) ); + if ( clipSize && ammoRequired ) { + ammoClip -= powerAmmo ? amount : ( amount * ammoRequired ); + if ( ammoClip < 0 ) { + ammoClip = 0; + } + } +} + +/* +=============== +idWeapon::Event_AddToClip +=============== +*/ +void idWeapon::Event_AddToClip( int amount ) { + int ammoAvail; + + if ( gameLocal.isClient ) { + return; + } + + ammoClip += amount; + if ( ammoClip > clipSize ) { + ammoClip = clipSize; + } + + ammoAvail = owner->GetCurrentWeaponItem()->HasAmmo(); + if ( ammoClip > ammoAvail ) { + ammoClip = ammoAvail; + } +} + +/* +=============== +idWeapon::Event_AmmoInClip +=============== +*/ +void idWeapon::Event_AmmoInClip( void ) { + int ammo = AmmoInClip(); + idThread::ReturnFloat( ammo ); +} + +/* +=============== +idWeapon::Event_AmmoAvailable +=============== +*/ +void idWeapon::Event_AmmoAvailable( void ) { + CInventoryWeaponItemPtr currentWeapon = owner->GetCurrentWeaponItem(); + int ammoAvail = (currentWeapon != NULL) ? currentWeapon->HasAmmo() : 0; + idThread::ReturnFloat( ammoAvail ); +} + +/* +=============== +idWeapon::Event_TotalAmmoCount +=============== +*/ +void idWeapon::Event_TotalAmmoCount( void ) { + CInventoryWeaponItemPtr currentWeapon = owner->GetCurrentWeaponItem(); + int ammoAvail = (currentWeapon != NULL) ? currentWeapon->HasAmmo() : 0; + idThread::ReturnFloat( ammoAvail ); +} + +/* +=============== +idWeapon::Event_ClipSize +=============== +*/ +void idWeapon::Event_ClipSize( void ) { + idThread::ReturnFloat( clipSize ); +} + +/* +=============== +idWeapon::Event_AutoReload +=============== +*/ +void idWeapon::Event_AutoReload( void ) { + assert( owner ); + if ( gameLocal.isClient ) { + idThread::ReturnFloat( 0.0f ); + return; + } + idThread::ReturnFloat( gameLocal.userInfo[ owner->entityNumber ].GetBool( "ui_autoReload" ) ); +} + +/* +=============== +idWeapon::Event_NetReload +=============== +*/ +void idWeapon::Event_NetReload( void ) { + assert( owner ); + if ( gameLocal.isServer ) { + ServerSendEvent( EVENT_RELOAD, NULL, false, -1 ); + } +} + +/* +=============== +idWeapon::Event_NetEndReload +=============== +*/ +void idWeapon::Event_NetEndReload( void ) { + assert( owner ); + if ( gameLocal.isServer ) { + ServerSendEvent( EVENT_ENDRELOAD, NULL, false, -1 ); + } +} + +/* +=============== +idWeapon::Event_PlayAnim +=============== +*/ +void idWeapon::Event_PlayAnim( int channel, const char *animname ) { + int anim; + + anim = animator.GetAnim( animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + gameLocal.Warning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); +#endif + + animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); + animDoneTime = 0; + } else { + + // grayman #597 - if this is a raise or lower animation, and we're + // switching from one arrow to another, skip the animation. + + idStr raiseString = "raise"; + idStr lowerString = "lower"; + bool raiseOrLower = ((raiseString.Cmp(animname) == 0) || (lowerString.Cmp(animname) == 0)); + if (arrow2Arrow && raiseOrLower) + { + animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); + animDoneTime = 0; + if (lowerString.Cmp(animname) == 0) + { + status = WP_HOLSTERED; // do this right away, otherwise it takes 12 frames to have it done elsewhere + // and you see a gap in the bow animation + } + } + else + { + if ( !( owner && owner->GetInfluenceLevel() ) ) { + Show(); + } + animator.PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + animDoneTime = animator.CurrentAnim( channel )->GetEndTime(); + if ( worldModel.GetEntity() ) { + anim = worldModel.GetEntity()->GetAnimator()->GetAnim( animname ); + if ( anim ) { + worldModel.GetEntity()->GetAnimator()->PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + } + } + } + } + animBlendFrames = 0; + idThread::ReturnInt( 0 ); +} + +/* +=============== +idWeapon::Event_PlayCycle +=============== +*/ +void idWeapon::Event_PlayCycle( int channel, const char *animname ) { + int anim; + + anim = animator.GetAnim( animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + gameLocal.Warning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); +#endif + + animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); + animDoneTime = 0; + } else { + if ( !( owner && owner->GetInfluenceLevel() ) ) { + Show(); + } + animator.CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + animDoneTime = animator.CurrentAnim( channel )->GetEndTime(); + if ( worldModel.GetEntity() ) { + anim = worldModel.GetEntity()->GetAnimator()->GetAnim( animname ); + worldModel.GetEntity()->GetAnimator()->CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); + } + } + animBlendFrames = 0; + idThread::ReturnInt( 0 ); +} + +/* +=============== +idWeapon::Event_PauseAnim +=============== +*/ +void idWeapon::Event_PauseAnim( int channel, bool bPause ) +{ + animator.CurrentAnim( channel )->Pause( bPause ); +} + +/* +=============== +idWeapon::Event_AnimIsPaused +=============== +*/ +void idWeapon::Event_AnimIsPaused( int channel ) +{ + idThread::ReturnInt( animator.CurrentAnim( channel )->IsPaused() ); +} + +/* +=============== +idWeapon::Event_AnimDone +=============== +*/ +void idWeapon::Event_AnimDone( int channel, int blendFrames ) +{ +// ishtvan: rewrote this to be more like what happens in idActor/idAnimState + int DoneTime = animator.CurrentAnim( channel )->GetEndTime(); + + if (DoneTime < 0) + { + // playing a cycle or paused + idThread::ReturnInt( false ); + } + else if ( DoneTime - FRAME2MS( blendFrames ) <= gameLocal.time ) + { + idThread::ReturnInt( true ); + } else + { + idThread::ReturnInt( false ); + } +} + +/* +=============== +idWeapon::Event_SetBlendFrames +=============== +*/ +void idWeapon::Event_SetBlendFrames( int channel, int blendFrames ) +{ + // ishtvan: this is a problem with animrate?? + animBlendFrames = blendFrames; +} + +/* +=============== +idWeapon::Event_GetBlendFrames +=============== +*/ +void idWeapon::Event_GetBlendFrames( int channel ) { + idThread::ReturnInt( animBlendFrames ); +} + +/* +================ +idWeapon::Event_Next +================ +*/ +void idWeapon::Event_Next( void ) { + // change to another weapon if possible + owner->NextBestWeapon(); +} + +/* +================ +idWeapon::Event_SetSkin +================ +*/ +void idWeapon::Event_SetSkin( const char *skinname ) { + const idDeclSkin *skinDecl; + + if ( !skinname || !skinname[ 0 ] ) { + skinDecl = NULL; + } else { + skinDecl = declManager->FindSkin( skinname ); + } + + renderEntity.customSkin = skinDecl; + UpdateVisuals(); + + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->SetSkin( skinDecl ); + } + + if ( gameLocal.isServer ) { + idBitMsg msg; + byte msgBuf[MAX_EVENT_PARAM_SIZE]; + + msg.Init( msgBuf, sizeof( msgBuf ) ); + msg.WriteLong( ( skinDecl != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_SKIN, skinDecl->Index() ) : -1 ); + ServerSendEvent( EVENT_CHANGESKIN, &msg, false, -1 ); + } +} + +/* +================ +idWeapon::Event_Flashlight +================ +*/ +void idWeapon::Event_Flashlight( int enable ) { + if ( enable ) { + lightOn = true; + MuzzleFlashLight(); + } else { + lightOn = false; + muzzleFlashEnd = 0; + } +} + +/* +================ +idWeapon::Event_GetLightParm +================ +*/ +void idWeapon::Event_GetLightParm( int parmnum ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Error( "shader parm index (%d) out of range", parmnum ); + } + + idThread::ReturnFloat( muzzleFlash.shaderParms[ parmnum ] ); +} + +/* +================ +idWeapon::Event_SetLightParm +================ +*/ +void idWeapon::Event_SetLightParm( int parmnum, float value ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { + gameLocal.Error( "shader parm index (%d) out of range", parmnum ); + } + + muzzleFlash.shaderParms[ parmnum ] = value; + worldMuzzleFlash.shaderParms[ parmnum ] = value; + UpdateVisuals(); +} + +/* +================ +idWeapon::Event_SetLightParms +================ +*/ +void idWeapon::Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { + muzzleFlash.shaderParms[ SHADERPARM_RED ] = parm0; + muzzleFlash.shaderParms[ SHADERPARM_GREEN ] = parm1; + muzzleFlash.shaderParms[ SHADERPARM_BLUE ] = parm2; + muzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = parm3; + + worldMuzzleFlash.shaderParms[ SHADERPARM_RED ] = parm0; + worldMuzzleFlash.shaderParms[ SHADERPARM_GREEN ] = parm1; + worldMuzzleFlash.shaderParms[ SHADERPARM_BLUE ] = parm2; + worldMuzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = parm3; + + UpdateVisuals(); +} + +/* +================ +idWeapon::Event_CreateProjectile +================ +*/ +void idWeapon::Event_CreateProjectile() +{ + if ( !gameLocal.isClient ) + { + projectileEnt = NULL; + + // Try to get the weapon inventory item + CInventoryWeaponItemPtr weaponItem = owner->GetWeaponItem(weaponDef->dict.GetString("inv_weapon_name")); + + if (weaponItem == NULL) + { + idThread::ReturnEntity( NULL ); + return; + } + + // Retrieve the currently active projectile def name from the inventory item + const idStr& projectileDefName = weaponItem->GetProjectileDefName(); + + const idDeclEntityDef* projectileDef = gameLocal.FindEntityDef(projectileDefName); + + if (projectileDef != NULL) + { + gameLocal.SpawnEntityDef( projectileDef->dict, &projectileEnt, false ); + + if ( projectileEnt ) + { + projectileEnt->SetOrigin( GetPhysics()->GetOrigin() ); + projectileEnt->Bind( owner, false ); + projectileEnt->Hide(); + } + } + + idThread::ReturnEntity( projectileEnt ); + } + else + { + idThread::ReturnEntity( NULL ); + } +} + +/* +================ +idWeapon::Event_LaunchProjectiles +================ +*/ +void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ) { + idProjectile *proj; + idEntity *ent; + int i; + idVec3 dir; + float ang; + float spin; + trace_t tr; + idVec3 start; + idVec3 muzzle_pos; + idBounds ownerBounds, projBounds; + + if ( IsHidden() ) { + return; + } + + /*if ( !projectileDict.GetNumKeyVals() ) { + const char *classname = weaponDef->dict.GetString( "classname" ); + gameLocal.Warning( "No projectile defined on '%s'", classname ); + return; + }*/ + CInventoryWeaponItemPtr weaponItem = owner->GetWeaponItem(weaponDef->dict.GetString("inv_weapon_name")); + if (weaponItem == NULL) return; + + // Retrieve the currently active projectile def name from the inventory item + const idStr& projectileDefName = weaponItem->GetProjectileDefName(); + + if (projectileDefName.IsEmpty()) + { + gameLocal.Warning("No projectile entityDef defined on '%s'", name.c_str()); + return; + } + + const idDeclEntityDef* projectileDef = gameLocal.FindEntityDef(projectileDefName); + + if (projectileDef == NULL) + { + gameLocal.Warning("Projectile entityDef %s not found.", projectileDefName.c_str()); + return; + } + + // avoid all ammo considerations on an MP client + if ( !gameLocal.isClient ) { + + CInventoryWeaponItemPtr weaponItem = owner->GetCurrentWeaponItem(); + + // check if we're out of ammo or the clip is empty + int ammoAvail = weaponItem->HasAmmo(); + if ( !ammoAvail || ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) ) { + return; + } + + weaponItem->UseAmmo(ammoRequired); + + if ( clipSize && ammoRequired ) { + ammoClip -= powerAmmo ? (int) dmgPower : 1; + } + } + + // set the shader parm to the time of last projectile firing, + // which the gun material shaders can reference for single shot barrel glows, etc + renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = gameLocal.random.CRandomFloat(); + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.realClientTime ); + + if ( worldModel.GetEntity() ) { + worldModel.GetEntity()->SetShaderParm( SHADERPARM_DIVERSITY, renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] ); + worldModel.GetEntity()->SetShaderParm( SHADERPARM_TIMEOFFSET, renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] ); + } + + // calculate the muzzle position + if ( barrelJointView != INVALID_JOINT && projectileDef->dict.GetBool( "launchFromBarrel" ) ) { + // there is an explicit joint for the muzzle + GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); + } else { + // go straight out of the view + muzzleOrigin = playerViewOrigin; + muzzleAxis = playerViewAxis; + } + + // add some to the kick time, incrementally moving repeat firing weapons back + if ( kick_endtime < gameLocal.realClientTime ) { + kick_endtime = gameLocal.realClientTime; + } + kick_endtime += muzzle_kick_time; + if ( kick_endtime > gameLocal.realClientTime + muzzle_kick_maxtime ) { + kick_endtime = gameLocal.realClientTime + muzzle_kick_maxtime; + } + + if ( gameLocal.isClient ) { + + // predict instant hit projectiles + if ( projectileDef->dict.GetBool( "net_instanthit" ) ) { + float spreadRad = DEG2RAD( spread ); + muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; + for( i = 0; i < num_projectiles; i++ ) { + ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); + spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); + //dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); + dir = muzzleAxis[ 0 ]; // Dram: Make the weapon shoot directly from the barrel bone. Found by Ishtvan + dir.Normalize(); + gameLocal.clip.Translation( tr, muzzle_pos, muzzle_pos + dir * 4096.0f, NULL, mat3_identity, MASK_SHOT_RENDERMODEL, owner ); + if ( tr.fraction < 1.0f ) { + idProjectile::ClientPredictionCollide( this, projectileDef->dict, tr, vec3_origin, true ); + } + } + } + + } else { + + ownerBounds = owner->GetPhysics()->GetAbsBounds(); + + owner->AddProjectilesFired( num_projectiles ); + + float spreadRad = DEG2RAD( spread ); + for( i = 0; i < num_projectiles; i++ ) { + ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); + spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); + //dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); + dir = muzzleAxis[ 0 ]; // Dram: Make the weapon shoot directly from the barrel bone. Found by Ishtvan + + if (projectileDef->dict.GetBool("fire_along_playerview", "0")) + { + // greebo: Fire the projectile along the playerview direction + dir = playerViewAxis.ToAngles().ToForward(); + } + + dir.Normalize(); + + //gameRenderWorld->DebugArrow(colorWhite, muzzleOrigin, muzzleOrigin + dir*100, 1, 15000); + + if ( projectileEnt ) { + ent = projectileEnt; + ent->Show(); + ent->Unbind(); + projectileEnt = NULL; + } else { + gameLocal.SpawnEntityDef( projectileDef->dict, &ent, false ); + } + + if ( !ent || !ent->IsType( idProjectile::Type ) ) { + const char *projectileName = weaponDef->dict.GetString( "def_projectile" ); + gameLocal.Error( "'%s' is not an idProjectile", projectileName ); + } + + if ( projectileDef->dict.GetBool( "net_instanthit" ) ) { + // don't synchronize this on top of the already predicted effect + ent->fl.networkSync = false; + } + + proj = static_cast(ent); + proj->Create( owner, muzzleOrigin, dir ); + + projBounds = proj->GetPhysics()->GetBounds().Rotate( proj->GetPhysics()->GetAxis() ); + + // make sure the projectile start point does not clip with anything + if ( i == 0 ) { + muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; + start = ownerBounds.GetCenter(); + /* stgatilov: translate to viewpoint first, then to muzzle point. + Otherwise shot while leaning over the corner would lag. Picture: + XXXX M C - center of player's bbox + XXXX | V - player's view origin + XXXX | M - muzzle position + C----V + */ + idClipModel *clm = proj->GetPhysics()->GetClipModel(); + if (!gameLocal.clip.Translation( tr, start, playerViewOrigin, clm, clm->GetAxis(), MASK_SHOT_RENDERMODEL, owner )) { + gameLocal.clip.Translation( tr, playerViewOrigin, muzzle_pos, clm, clm->GetAxis(), MASK_SHOT_RENDERMODEL, owner ); + } + muzzle_pos = tr.endpos; + + } + + proj->Launch( muzzle_pos, dir, pushVelocity, fuseOffset, launchPower, dmgPower ); + + // TDM: Update responsible actor for the projectile, so it can be tracked for alerts + proj->m_SetInMotionByActor = owner; + proj->m_MovedByActor = owner; + } + + // toss the brass + PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); + } + + // add the light for the muzzleflash + if ( !lightOn ) { + MuzzleFlashLight(); + } + + owner->WeaponFireFeedback( &weaponDef->dict ); + + // reset muzzle smoke + weaponSmokeStartTime = gameLocal.realClientTime; +} + +/* +===================== +idWeapon::Event_Melee +===================== +*/ +void idWeapon::Event_Melee( void ) { + idEntity *ent; + trace_t tr; + + if ( !meleeDef ) { + gameLocal.Error( "No meleeDef on '%s'", weaponDef->dict.GetString( "classname" ) ); + } + + if ( !gameLocal.isClient ) { + idVec3 start = playerViewOrigin; + idVec3 end = start + playerViewAxis[0] * ( meleeDistance * owner->PowerUpModifier( MELEE_DISTANCE ) ); + gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL, owner ); + if ( tr.fraction < 1.0f && gameLocal.entities[tr.c.entityNum] ) + { + //ent = gameLocal.GetTraceEntity( tr ); + ent = gameLocal.entities[ tr.c.entityNum ]; + } else + { + ent = NULL; + } + + if ( g_debugWeapon.GetBool() ) { + gameRenderWorld->DebugLine( colorYellow, start, end, 100 ); + if ( ent ) { + gameRenderWorld->DebugBounds( colorRed, ent->GetPhysics()->GetBounds(), ent->GetPhysics()->GetOrigin(), 100 ); + } + } + + bool hit = false; + idStr hitSound = meleeDef->dict.GetString( "snd_miss" ); + idStr sndName = "snd_miss"; + + if ( ent ) { + + float push = meleeDef->dict.GetFloat( "push" ); + idVec3 impulse = -push * owner->PowerUpModifier( SPEED ) * tr.c.normal; + + if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) && ( ent->IsType( idActor::Type ) || ent->IsType( idAFAttachment::Type) ) ) { + idThread::ReturnInt( 0 ); + return; + } + + ent->ApplyImpulse( this, tr.c.id, tr.c.point, impulse ); + + // weapon stealing - do this before damaging so weapons are not dropped twice + if ( gameLocal.isMultiplayer + && weaponDef && weaponDef->dict.GetBool( "stealing" ) + && ent->IsType( idPlayer::Type ) + && ( gameLocal.gameType != GAME_TDM || gameLocal.serverInfo.GetBool( "si_teamDamage" ) || ( owner->team != static_cast< idPlayer * >( ent )->team ) ) + ) { + owner->StealWeapon( static_cast< idPlayer * >( ent ) ); + } + + if ( ent->fl.takedamage ) { + idVec3 kickDir, globalKickDir; + meleeDef->dict.GetVector( "kickDir", "0 0 0", kickDir ); + globalKickDir = muzzleAxis * kickDir; + + ent->Damage( owner, owner, globalKickDir, meleeDefName, owner->PowerUpModifier( MELEE_DAMAGE ), CLIPMODEL_ID_TO_JOINT_HANDLE(tr.c.id), &tr ); + + // apply a LARGE tactile alert to AI + if( ent->IsType(idAI::Type) ) + { + static_cast(ent)->TactileAlert( GetOwner(), 100 ); + } + + hit = true; + } + + if ( weaponDef->dict.GetBool( "impact_damage_effect" ) ) { + + if ( ent->spawnArgs.GetBool( "bleed" ) ) { + + hitSound = meleeDef->dict.GetString( "snd_hit" ); + sndName = "snd_hit"; + + ent->AddDamageEffect( tr, impulse, meleeDef->dict.GetString( "classname" ) ); + + } else + { + + idStr materialType; + int type = tr.c.material->GetSurfaceType(); + + if ( type == SURFTYPE_NONE ) + materialType = gameLocal.sufaceTypeNames[ GetDefaultSurfaceType() ]; + else + g_Global.GetSurfName( tr.c.material, materialType ); + + // start impact sound based on material type + hitSound = meleeDef->dict.GetString( va( "snd_%s", materialType.c_str() ) ); + sndName = va( "snd_%s", materialType.c_str() ); + + if ( hitSound.IsEmpty() ) + { + hitSound = meleeDef->dict.GetString( "snd_metal" ); + sndName = "snd_metal"; + } + + if ( gameLocal.time > nextStrikeFx ) { + const char *decal; + // project decal + decal = weaponDef->dict.GetString( "mtr_strike" ); + if ( decal && *decal ) { + gameLocal.ProjectDecal( tr.c.point, -tr.c.normal, 8.0f, true, 6.0, decal ); + } + nextStrikeFx = gameLocal.time + 200; + } else { + hitSound = ""; + sndName = ""; + } + + strikeSmokeStartTime = gameLocal.time; + strikePos = tr.c.point; + strikeAxis = -tr.endAxis; + } + } + } + + if ( !hitSound.IsEmpty() ) + { + const idSoundShader *snd = declManager->FindSound( hitSound.c_str() ); + StartSoundShader( snd, SND_CHANNEL_BODY2, 0, true, NULL ); + + // Propagate the sound to AI, must find global sound first because it's on a different dict + sndName.StripLeading("snd_"); + sndName = meleeDef->dict.GetString( va("sprS_%s", sndName.c_str()) ); + if( !sndName.IsEmpty() ) + PropSoundDirect( sndName.c_str(), false, false ); + } + + idThread::ReturnInt( hit ); + owner->WeaponFireFeedback( &weaponDef->dict ); + return; + } + + idThread::ReturnInt( 0 ); + owner->WeaponFireFeedback( &weaponDef->dict ); +} + +/* +===================== +idWeapon::Event_GetWorldModel +===================== +*/ +void idWeapon::Event_GetWorldModel( void ) { + idThread::ReturnEntity( worldModel.GetEntity() ); +} + +/* +===================== +idWeapon::Event_AllowDrop +===================== +*/ +void idWeapon::Event_AllowDrop( int allow ) { + if ( allow ) { + allowDrop = true; + } else { + allowDrop = false; + } +} + +/* +================ +idWeapon::Event_EjectBrass + +Toss a shell model out from the breach if the bone is present +================ +*/ +void idWeapon::Event_EjectBrass( void ) { + if ( !g_showBrass.GetBool() || !owner->CanShowWeaponViewmodel() ) { + return; + } + + if ( ejectJointView == INVALID_JOINT || !brassDict.GetNumKeyVals() ) { + return; + } + + if ( gameLocal.isClient ) { + return; + } + + idMat3 axis; + idVec3 origin, linear_velocity, angular_velocity; + idEntity *ent; + + if ( !GetGlobalJointTransform( true, ejectJointView, origin, axis ) ) { + return; + } + + gameLocal.SpawnEntityDef( brassDict, &ent, false ); + if ( !ent || !ent->IsType( idDebris::Type ) ) { + gameLocal.Error( "'%s' is not an idDebris", weaponDef ? weaponDef->dict.GetString( "def_ejectBrass" ) : "def_ejectBrass" ); + } + idDebris *debris = static_cast(ent); + debris->Create( owner, origin, axis ); + debris->Launch(); + + linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] ); + angular_velocity.Set( 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat() ); + + debris->GetPhysics()->SetLinearVelocity( linear_velocity ); + debris->GetPhysics()->SetAngularVelocity( angular_velocity ); +} + +/* +=============== +idWeapon::Event_IsInvisible +=============== +*/ +void idWeapon::Event_IsInvisible( void ) { + // greebo: No invisibility in TDM currently + idThread::ReturnFloat( 0 ); +} + +/* +=============== +idWeapon::ClientPredictionThink +=============== +*/ +void idWeapon::ClientPredictionThink( void ) { + UpdateAnimation(); +} + +/* +================ +idWeapon::Attach +================ +*/ +void idWeapon::Attach( idEntity *ent, const char *PosName, const char *AttName ) +{ + idAnimatedEntity::Attach( ent, PosName, AttName ); + + // set up the same rendering conditions as the weapon viewmodel + ent->GetRenderEntity()->allowSurfaceInViewID = owner->entityNumber+1; + ent->GetRenderEntity()->weaponDepthHack = true; +} + +/* +================ +idWeapon::GetAttachingTransform +================ +*/ +void idWeapon::GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) +{ + GetGlobalJointTransform( true, jointHandle, offset, axis ); +} + + diff --git a/game/Weapon.h b/game/Weapon.h new file mode 100644 index 000000000..b7016f9d0 --- /dev/null +++ b/game/Weapon.h @@ -0,0 +1,394 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_WEAPON_H__ +#define __GAME_WEAPON_H__ + +/* +=============================================================================== + + Player Weapon + +=============================================================================== +*/ + +typedef enum { + WP_READY, + WP_OUTOFAMMO, + WP_RELOAD, + WP_HOLSTERED, + WP_RISING, + WP_LOWERING +} weaponStatus_t; + +class idPlayer; + +static const int LIGHTID_WORLD_MUZZLE_FLASH = 1; +static const int LIGHTID_VIEW_MUZZLE_FLASH = 100; + +class idMoveableItem; + +class idWeapon : public idAnimatedEntity { +public: + CLASS_PROTOTYPE( idWeapon ); + + idWeapon(); + virtual ~idWeapon(); + + // Init + void Spawn( void ); + void SetOwner( idPlayer *owner ); + idPlayer* GetOwner( void ); + virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; + + static void CacheWeapon( const char *weaponName ); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + // Weapon definition management + void Clear( void ); + void GetWeaponDef( const char *objectname, int ammoinclip ); + bool IsLinked( void ); + bool IsWorldModelReady( void ); + + // GUIs + const char * Icon( void ) const; + void UpdateGUI( void ); + + virtual void SetModel( const char *modelname ); + bool GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); + void SetPushVelocity( const idVec3 &pushVelocity ); + bool UpdateSkin( void ); + + // State control/player interface + void Think( void ); + void Raise( void ); + void PutAway( void ); + void Reload( void ); + void LowerWeapon( void ); + void RaiseWeapon( void ); + void HideWeapon( void ); + void ShowWeapon( void ); + void HideWorldModel( void ); + void ShowWorldModel( void ); + void OwnerDied( void ); + void BeginAttack( void ); + void EndAttack( void ); + void BeginBlock( void ); + void EndBlock( void ); + bool IsReady( void ) const; + bool IsReloading( void ) const; + bool IsHolstered( void ) const; + bool ShowCrosshair( void ) const; + idEntity * DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died ); + bool CanDrop( void ) const; + void WeaponStolen( void ); + void SetArrow2Arrow( bool state); // grayman #597 + + // Script state management + virtual idThread * ConstructScriptObject( void ); + virtual void DeconstructScriptObject( void ); + void SetState( const char *statename, int blendFrames ); + void UpdateScript( void ); + void EnterCinematic( void ); + void ExitCinematic( void ); + void NetCatchup( void ); + + // Visual presentation + void PresentWeapon( bool showViewModel ); + int GetZoomFov( void ); + void GetWeaponAngleOffsets( int *average, float *scale, float *max ); + void GetWeaponTimeOffsets( float *time, float *scale ); + bool BloodSplat( float size ); + + // Ammo + static const char *GetAmmoNameForNum( int ammonum ); + static const char *GetAmmoPickupNameForNum( int ammonum ); + int AmmoAvailable( void ) const; + int AmmoInClip( void ) const; + void ResetAmmoClip( void ); + int ClipSize( void ) const; + int LowAmmo( void ) const; + int AmmoRequired( void ) const; + + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); + + /** + * TDM: Attach an entity to the weapon's AF. Different than plain entity attachment + * Does not use position name for now + **/ + virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); + + enum { + EVENT_RELOAD = idEntity::EVENT_MAXEVENTS, + EVENT_ENDRELOAD, + EVENT_CHANGESKIN, + EVENT_MAXEVENTS + }; + virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); + + virtual void ClientPredictionThink( void ); + + /** + * TDM: Return true if this is a ranged weapon + **/ + bool IsRanged(); + +protected: + /** + * Used internally by the Attach methods. + * Offset and axis are filled with the correct offset and axis + * for attaching to a particular joint. + * Overloaded to call GetJointGlobalTransform on idWeapon entities. + **/ + virtual void GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); + +private: + // script control + idScriptBool WEAPON_ATTACK; + idScriptBool WEAPON_BLOCK; + idScriptBool WEAPON_RELOAD; + idScriptBool WEAPON_NETRELOAD; + idScriptBool WEAPON_NETENDRELOAD; + idScriptBool WEAPON_NETFIRING; + idScriptBool WEAPON_RAISEWEAPON; + idScriptBool WEAPON_LOWERWEAPON; + weaponStatus_t status; + idThread * thread; + idStr state; + idStr idealState; + int animBlendFrames; + /** + * TDM: animDoneTime no longer used, but keep it around + * for compatibility with future patches/engines + **/ + int animDoneTime; + bool isLinked; + + // precreated projectile + idEntity *projectileEnt; + + idPlayer * owner; + idEntityPtr worldModel; + + // hiding (for GUIs and NPCs) + int hideTime; + float hideDistance; + int hideStartTime; + float hideStart; + float hideEnd; + float hideOffset; + bool hide; + bool disabled; + + // berserk + int berserk; + + // these are the player render view parms, which include bobbing + idVec3 playerViewOrigin; + idMat3 playerViewAxis; + + // the view weapon render entity parms + idVec3 viewWeaponOrigin; + idMat3 viewWeaponAxis; + + // the muzzle bone's position, used for launching projectiles and trailing smoke + idVec3 muzzleOrigin; + idMat3 muzzleAxis; + + idVec3 pushVelocity; + + // weapon definition + // we maintain local copies of the projectile and brass dictionaries so they + // do not have to be copied across the DLL boundary when entities are spawned + const idDeclEntityDef * weaponDef; + const idDeclEntityDef * meleeDef; + + // greebo: This is not needed anymore - the projectile dictionary is requested when it's actually needed + //idDict projectileDict; + float meleeDistance; + idStr meleeDefName; + idDict brassDict; + int brassDelay; + idStr icon; + + // view weapon gui light + renderLight_t guiLight; + int guiLightHandle; + + // muzzle flash + renderLight_t muzzleFlash; // positioned on view weapon bone + int muzzleFlashHandle; + + renderLight_t worldMuzzleFlash; // positioned on world weapon bone + int worldMuzzleFlashHandle; + + idVec3 flashColor; + int muzzleFlashEnd; + int flashTime; + bool lightOn; + bool allowDrop; + + int hideUntilTime; // grayman #597 - keep hidden until timer expires (for arrow spawning) + + // effects + bool hasBloodSplat; + + // weapon kick + int kick_endtime; + int muzzle_kick_time; + int muzzle_kick_maxtime; + idAngles muzzle_kick_angles; + idVec3 muzzle_kick_offset; + + // ammo management + int ammoRequired; // amount of ammo to use each shot. 0 means weapon doesn't need ammo. + int clipSize; // 0 means no reload + int ammoClip; + int lowAmmo; // if ammo in clip hits this threshold, snd_ + bool powerAmmo; // true if the clip reduction is a factor of the power setting when + // a projectile is launched + // mp client + bool isFiring; + + // zoom + int zoomFov; // variable zoom fov per weapon + + // joints from models + jointHandle_t barrelJointView; + jointHandle_t flashJointView; + jointHandle_t ejectJointView; + jointHandle_t guiLightJointView; + jointHandle_t ventLightJointView; + + jointHandle_t flashJointWorld; + jointHandle_t barrelJointWorld; + jointHandle_t ejectJointWorld; + + // sound + const idSoundShader * sndHum; + + // new style muzzle smokes + const idDeclParticle * weaponSmoke; // null if it doesn't smoke + int weaponSmokeStartTime; // set to gameLocal.time every weapon fire + bool continuousSmoke; // if smoke is continuous ( chainsaw ) + const idDeclParticle * strikeSmoke; // striking something in melee + int strikeSmokeStartTime; // timing + idVec3 strikePos; // position of last melee strike + idMat3 strikeAxis; // axis of last melee strike + int nextStrikeFx; // used for sound and decal ( may use for strike smoke too ) + + // nozzle effects + bool nozzleFx; // does this use nozzle effects ( parm5 at rest, parm6 firing ) + // this also assumes a nozzle light atm + int nozzleFxFade; // time it takes to fade between the effects + int lastAttack; // last time an attack occurred + int lastBlock; // last time a block occurred + renderLight_t nozzleGlow; // nozzle light + int nozzleGlowHandle; // handle for nozzle light + + idVec3 nozzleGlowColor; // color of the nozzle glow + const idMaterial * nozzleGlowShader; // shader for glow light + float nozzleGlowRadius; // radius of glow light + + // weighting for viewmodel angles + int weaponAngleOffsetAverages; + float weaponAngleOffsetScale; + float weaponAngleOffsetMax; + float weaponOffsetTime; + float weaponOffsetScale; + + // weapon switching + bool arrow2Arrow; // grayman #597 + + // flashlight + void AlertMonsters( void ); + + // Visual presentation + void InitWorldModel( const idDeclEntityDef *def ); + void MuzzleFlashLight( void ); + void MuzzleRise( idVec3 &origin, idMat3 &axis ); + void UpdateNozzleFx( void ); + void UpdateFlashPosition( void ); + + // script events + void Event_Clear( void ); + void Event_GetOwner( void ); + void Event_WeaponState( const char *statename, int blendFrames ); + void Event_SetWeaponStatus( float newStatus ); + void Event_WeaponReady( void ); + void Event_WeaponOutOfAmmo( void ); + void Event_WeaponReloading( void ); + void Event_WeaponHolstered( void ); + void Event_WeaponRising( void ); + void Event_WeaponLowering( void ); + void Event_UseAmmo( int amount ); + void Event_AddToClip( int amount ); + void Event_AmmoInClip( void ); + void Event_AmmoAvailable( void ); + void Event_TotalAmmoCount( void ); + void Event_ClipSize( void ); + void Event_PlayAnim( int channel, const char *animname ); + void Event_PauseAnim( int channel, bool bPause ); + void Event_AnimIsPaused( int channel ); + void Event_PlayCycle( int channel, const char *animname ); + void Event_AnimDone( int channel, int blendFrames ); + void Event_SetBlendFrames( int channel, int blendFrames ); + void Event_GetBlendFrames( int channel ); + void Event_Next( void ); + void Event_SetSkin( const char *skinname ); +/** +* TDM: Show or hide the weapon attachments +* The first argument is an index to the attachments list, starting at 1 +* Second argument is set to true if it should be shown, false for hiding. +**/ + void Event_ShowAttachment( int id, bool bShow ); + + void Event_Flashlight( int enable ); + void Event_GetLightParm( int parmnum ); + void Event_SetLightParm( int parmnum, float value ); + void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ); + void Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ); + void Event_CreateProjectile( void ); + void Event_EjectBrass( void ); + void Event_Melee( void ); + void Event_GetWorldModel( void ); + void Event_AllowDrop( int allow ); + void Event_AutoReload( void ); + void Event_NetReload( void ); + void Event_IsInvisible( void ); + void Event_NetEndReload( void ); +}; + +ID_INLINE bool idWeapon::IsLinked( void ) { + return isLinked; +} + +ID_INLINE bool idWeapon::IsWorldModelReady( void ) { + return ( worldModel.GetEntity() != NULL ); +} + +ID_INLINE idPlayer* idWeapon::GetOwner( void ) { + return owner; +} + +#endif /* !__GAME_WEAPON_H__ */ diff --git a/game/WorldSpawn.cpp b/game/WorldSpawn.cpp new file mode 100644 index 000000000..d0b19e29e --- /dev/null +++ b/game/WorldSpawn.cpp @@ -0,0 +1,145 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* +game_worldspawn.cpp + +Worldspawn class. Each map has one worldspawn which handles global spawnargs. + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Game_local.h" + +/* +================ +idWorldspawn + +Every map should have exactly one worldspawn. +================ +*/ +CLASS_DECLARATION( idEntity, idWorldspawn ) + EVENT( EV_Remove, idWorldspawn::Event_Remove ) + EVENT( EV_SafeRemove, idWorldspawn::Event_Remove ) +END_CLASS + +/* +================ +idWorldspawn::Spawn +================ +*/ +void idWorldspawn::Spawn( void ) { + idStr scriptname; + idThread *thread; + const function_t *func; + const idKeyValue *kv; + + assert( gameLocal.world == NULL ); + gameLocal.world = this; + + g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); + + // Commented out by Dram. TDM does not use stamina + /* + // disable stamina on hell levels + if ( spawnArgs.GetBool( "no_stamina" ) ) { + pm_stamina.SetFloat( 0.0f ); + }*/ + + // load script + scriptname = gameLocal.GetMapName(); + scriptname.SetFileExtension( ".script" ); + if ( fileSystem->ReadFile( scriptname, NULL, NULL ) > 0 ) { + gameLocal.program.CompileFile( scriptname ); + + // call the main function by default + func = gameLocal.program.FindFunction( "main" ); + if ( func != NULL ) { + thread = new idThread( func ); + thread->DelayedStart( 0 ); + } + } + + // call any functions specified in worldspawn + kv = spawnArgs.MatchPrefix( "call" ); + while( kv != NULL ) { + func = gameLocal.program.FindFunction( kv->GetValue() ); + if ( func == NULL ) { + gameLocal.Error( "Function '%s' not found in script for '%s' key on worldspawn", kv->GetValue().c_str(), kv->GetKey().c_str() ); + } + + thread = new idThread( func ); + thread->DelayedStart( 0 ); + kv = spawnArgs.MatchPrefix( "call", kv ); + } + + // activate worldspawn's targets when it spawns + PostEventMS( &EV_ActivateTargets, 0, this ); +} + +/* +================= +idWorldspawn::Save +================= +*/ +void idWorldspawn::Save( idRestoreGame *savefile ) { +} + +/* +================= +idWorldspawn::Restore +================= +*/ +void idWorldspawn::Restore( idRestoreGame *savefile ) { + assert( gameLocal.world == this ); + + g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); + + // Commented out by Dram. TDM does not use stamina + /*// disable stamina on hell levels + if ( spawnArgs.GetBool( "no_stamina" ) ) { + pm_stamina.SetFloat( 0.0f ); + }*/ +} + +/* +================ +idWorldspawn::~idWorldspawn +================ +*/ +idWorldspawn::~idWorldspawn() { + if ( gameLocal.world == this ) { + gameLocal.world = NULL; + } +} + +/* +================ +idWorldspawn::Event_Remove +================ +*/ +void idWorldspawn::Event_Remove( void ) { + gameLocal.Error( "Tried to remove world" ); +} diff --git a/game/WorldSpawn.h b/game/WorldSpawn.h new file mode 100644 index 000000000..7537d216c --- /dev/null +++ b/game/WorldSpawn.h @@ -0,0 +1,46 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAME_WORLDSPAWN_H__ +#define __GAME_WORLDSPAWN_H__ + +/* +=============================================================================== + + World entity. + +=============================================================================== +*/ + +class idWorldspawn : public idEntity { +public: + CLASS_PROTOTYPE( idWorldspawn ); + + virtual ~idWorldspawn(); + + void Spawn( void ); + + void Save( idRestoreGame *savefile ); + void Restore( idRestoreGame *savefile ); + +private: + void Event_Remove( void ); +}; + +#endif /* !__GAME_WORLDSPAWN_H__ */ diff --git a/DarkMod/ZipLoader/ZipLoader.cpp b/game/ZipLoader/ZipLoader.cpp similarity index 78% rename from DarkMod/ZipLoader/ZipLoader.cpp rename to game/ZipLoader/ZipLoader.cpp index 0f5682af6..62efdf95e 100644 --- a/DarkMod/ZipLoader/ZipLoader.cpp +++ b/game/ZipLoader/ZipLoader.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma hdrstop #include "ZipLoader.h" diff --git a/game/ZipLoader/ZipLoader.h b/game/ZipLoader/ZipLoader.h new file mode 100644 index 000000000..0be32e055 --- /dev/null +++ b/game/ZipLoader/ZipLoader.h @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef ZIPLOADER_H_ +#define ZIPLOADER_H_ + +#pragma hdrstop + +#include "../../idlib/precompiled.h" +#include +#include "minizip/unzip.h" + +/** + * A class wrapping around a minizip file handle, providing + * some convenience method to easily extract data from PK4s. + */ +class CZipFile +{ + // The handle for the zip archive + unzFile _handle; + +public: + CZipFile(unzFile handle); + + ~CZipFile(); + + /** + * greebo: returns TRUE when this archive contains the given file. + */ + bool ContainsFile(const idStr& fileName); + + /** + * Attempts to load the given text file. The string will be empty + * if the file failed to load. + */ + idStr LoadTextFile(const idStr& fileName); + + /** + * greebo: Extracts the given file to the given destination path. + * @returns: TRUE on success, FALSE otherwise. + */ + bool ExtractFileTo(const idStr& fileName, const idStr& destPath); +}; +typedef boost::shared_ptr CZipFilePtr; + +/** + * greebo: This service class can be used to load and inspect zip files and + * retrieve specific files from the archive. D3 filesystem doesn't expose + * ZIP loading functionality, so this is the do-it-yourself approach. + */ +class CZipLoader +{ + // Private constructor + CZipLoader(); + +public: + /** + * Tries to load the given file (path is absolute, use D3 VFS functions + * to resolve a relative D3 path to a full OS path). + * + * @returns: NULL on failure, the file object on success. + */ + CZipFilePtr OpenFile(const idStr& fullOSPath); + + // Singleton instance + static CZipLoader& Instance(); +}; + +#endif /* ZIPLOADER_H_ */ diff --git a/game/actor.cpp b/game/actor.cpp deleted file mode 100644 index 0eeb0baa6..000000000 --- a/game/actor.cpp +++ /dev/null @@ -1,4975 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/TimerManager.h" -#include "../DarkMod/MeleeWeapon.h" -#include "../DarkMod/AbsenceMarker.h" - -// #include "logmgr.h" -/*********************************************************************** - - idAnimState - -***********************************************************************/ - -/* -===================== -idAnimState::idAnimState -===================== -*/ -idAnimState::idAnimState() { - self = NULL; - animator = NULL; - thread = NULL; - idleAnim = true; - disabled = true; - channel = ANIMCHANNEL_ALL; - animBlendFrames = 0; - lastAnimBlendFrames = 0; -} - -/* -===================== -idAnimState::~idAnimState -===================== -*/ -idAnimState::~idAnimState() { - delete thread; -} - -/* -===================== -idAnimState::Save -===================== -*/ -void idAnimState::Save( idSaveGame *savefile ) const { - - savefile->WriteObject( self ); - - // Save the entity owner of the animator - savefile->WriteObject( animator->GetEntity() ); - - savefile->WriteObject( thread ); - - savefile->WriteString( state ); - - savefile->WriteInt( animBlendFrames ); - savefile->WriteInt( lastAnimBlendFrames ); - savefile->WriteInt( channel ); - savefile->WriteBool( idleAnim ); - savefile->WriteBool( disabled ); -} - -/* -===================== -idAnimState::Restore -===================== -*/ -void idAnimState::Restore( idRestoreGame *savefile ) { - savefile->ReadObject( reinterpret_cast( self ) ); - - idEntity *animowner; - savefile->ReadObject( reinterpret_cast( animowner ) ); - if ( animowner ) { - animator = animowner->GetAnimator(); - } - - savefile->ReadObject( reinterpret_cast( thread ) ); - - savefile->ReadString( state ); - - savefile->ReadInt( animBlendFrames ); - savefile->ReadInt( lastAnimBlendFrames ); - savefile->ReadInt( channel ); - savefile->ReadBool( idleAnim ); - savefile->ReadBool( disabled ); -} - -/* -===================== -idAnimState::Init -===================== -*/ -void idAnimState::Init( idActor *owner, idAnimator *_animator, int animchannel ) { - assert( owner ); - assert( _animator ); - self = owner; - animator = _animator; - channel = animchannel; - - if ( !thread ) { - thread = new idThread(); - thread->ManualDelete(); - } - thread->EndThread(); - thread->ManualControl(); -} - -/* -===================== -idAnimState::Shutdown -===================== -*/ -void idAnimState::Shutdown( void ) { - delete thread; - thread = NULL; -} - -/* -===================== -idAnimState::SetState -===================== -*/ -void idAnimState::SetState( const char *statename, int blendFrames ) { - const function_t *func; - - func = self->scriptObject.GetFunction( statename ); - if ( !func ) { - assert( 0 ); - gameLocal.Error( "Can't find function '%s' in object '%s'", statename, self->scriptObject.GetTypeName() ); - } - - if (cv_ai_debug_anims.GetBool() && self != gameLocal.GetLocalPlayer()) - { - gameLocal.Printf("Frame %d: New animstate %s (%s)\n", gameLocal.framenum, statename, self->name.c_str()); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame %d: New animstate %s (%s)\r", gameLocal.framenum, statename, self->name.c_str()); - } - - state = statename; - disabled = false; - animBlendFrames = blendFrames; - lastAnimBlendFrames = blendFrames; - thread->CallFunction( self, func, true ); - - animBlendFrames = blendFrames; - lastAnimBlendFrames = blendFrames; - disabled = false; - idleAnim = false; - - if ( ai_debugScript.GetInteger() == self->entityNumber ) { - gameLocal.Printf( "%d: %s: Animstate: %s\n", gameLocal.time, self->name.c_str(), state.c_str() ); - } -} - -/* -===================== -idAnimState::SetFrame -===================== -*/ - -void idAnimState::SetFrame( int anim, int frame ) -{ - animator->SetFrame( channel, anim, frame, gameLocal.time, 0 ); -} - -/* -===================== -idAnimState::StopAnim -===================== -*/ -void idAnimState::StopAnim( int frames ) { - animBlendFrames = 0; - animator->Clear( channel, gameLocal.time, FRAME2MS( frames ) ); -} - -/* -===================== -idAnimState::PlayAnim -===================== -*/ -void idAnimState::PlayAnim( int anim ) { - if ( anim ) { - animator->PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - } - animBlendFrames = 0; -} - -/* -===================== -idAnimState::CycleAnim -===================== -*/ -void idAnimState::CycleAnim( int anim ) { - if ( anim ) { - animator->CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - } - animBlendFrames = 0; -} - -void idAnimState::PauseAnim( int channel, bool bPause) -{ - animator->CurrentAnim( channel )->Pause( bPause ); -} - -bool idAnimState::AnimIsPaused( int channel ) -{ - return animator->CurrentAnim( channel )->IsPaused(); -} - -/* -===================== -idAnimState::BecomeIdle -===================== -*/ -void idAnimState::BecomeIdle( void ) { - idleAnim = true; -} - -/* -===================== -idAnimState::Disabled -===================== -*/ -bool idAnimState::Disabled( void ) const { - return disabled; -} - -/* -===================== -idAnimState::AnimDone -===================== -*/ -bool idAnimState::AnimDone( int blendFrames ) const { - int animDoneTime; - - animDoneTime = animator->CurrentAnim( channel )->GetEndTime(); - if ( animDoneTime < 0 ) { - // playing a cycle - return false; - } else if ( animDoneTime - FRAME2MS( blendFrames ) <= gameLocal.time ) { - return true; - } else { - return false; - } -} - -/* -===================== -idAnimState::IsIdle -===================== -*/ -bool idAnimState::IsIdle( void ) const { - return disabled || idleAnim; -} - -/* -===================== -idAnimState::GetAnimFlags -===================== -*/ -animFlags_t idAnimState::GetAnimFlags( void ) const { - animFlags_t flags; - - memset( &flags, 0, sizeof( flags ) ); - if ( !disabled && !AnimDone( 0 ) ) { - flags = animator->GetAnimFlags( animator->CurrentAnim( channel )->AnimNum() ); - } - - return flags; -} - -idAnimator* idAnimState::GetAnimator() -{ - return animator; -} - -/* -===================== -idAnimState::Enable -===================== -*/ -void idAnimState::Enable( int blendFrames ) { - if ( disabled ) { - disabled = false; - animBlendFrames = blendFrames; - lastAnimBlendFrames = blendFrames; - if ( state.Length() ) { - SetState( state.c_str(), blendFrames ); - } - } -} - -/* -===================== -idAnimState::Disable -===================== -*/ -void idAnimState::Disable( void ) { - disabled = true; - idleAnim = false; -} - -/* -===================== -idAnimState::UpdateState -===================== -*/ -bool idAnimState::UpdateState( void ) { - if ( disabled ) { - return false; - } - - if ( ai_debugScript.GetInteger() == self->entityNumber ) { - thread->EnableDebugInfo(); - } else { - thread->DisableDebugInfo(); - } - - thread->Execute(); - - return true; -} - - -/* -===================== -idAnimState::FinishAction -===================== -*/ -void idAnimState::FinishAction(const idStr& actionname) -{ - if ( waitState == actionname ) { - SetWaitState( "" ); - } -} - -/* -===================== -idAnimState::SetWaitState -===================== -*/ -void idAnimState::SetWaitState( const char *_waitstate ) -{ - waitState = _waitstate; -} - -/* -===================== -idAnimState::WaitState -===================== -*/ -const char *idAnimState::WaitState( void ) const -{ - if ( waitState.Length() ) { - return waitState; - } else { - return NULL; - } -} - - - - - -/*********************************************************************** - - idActor - -***********************************************************************/ - -const char *idActor::MeleeTypeNames[ NUM_MELEE_TYPES ] = { - "Over", "LR", "RL", "Thrust", "General", "General" -}; - -const idEventDef AI_EnableEyeFocus( "enableEyeFocus" ); -const idEventDef AI_DisableEyeFocus( "disableEyeFocus" ); -const idEventDef EV_Footstep( "footstep" ); -const idEventDef EV_FootstepLeft( "leftFoot" ); -const idEventDef EV_FootstepRight( "rightFoot" ); -const idEventDef EV_EnableWalkIK( "EnableWalkIK" ); -const idEventDef EV_DisableWalkIK( "DisableWalkIK" ); -const idEventDef EV_EnableLegIK( "EnableLegIK", "d" ); -const idEventDef EV_DisableLegIK( "DisableLegIK", "d" ); -const idEventDef AI_StopAnim( "stopAnim", "dd" ); -// NOTE: Id defines playanim here, but it is also overloaded in a roundabout way -// by idWeapon (maybe due to limited polymorphism in scripting?) -const idEventDef AI_PlayAnim( "playAnim", "ds", 'd' ); -const idEventDef AI_PauseAnim( "pauseAnim", "dd" ); -const idEventDef AI_AnimIsPaused( "animIsPaused", "d", 'd' ); -const idEventDef AI_PlayCycle( "playCycle", "ds", 'd' ); -const idEventDef AI_IdleAnim( "idleAnim", "ds", 'd' ); -const idEventDef AI_SetSyncedAnimWeight( "setSyncedAnimWeight", "ddf" ); -const idEventDef AI_SyncAnimChannels("syncAnimChannels", "ddf"); -const idEventDef AI_SetBlendFrames( "setBlendFrames", "dd" ); -const idEventDef AI_GetBlendFrames( "getBlendFrames", "d", 'd' ); -const idEventDef AI_AnimState( "animState", "dsd" ); -const idEventDef AI_GetAnimState( "getAnimState", "d", 's' ); -const idEventDef AI_InAnimState( "inAnimState", "ds", 'd' ); -const idEventDef AI_FinishAction( "finishAction", "s" ); -const idEventDef AI_FinishChannelAction( "finishChannelAction", "ds" ); -const idEventDef AI_AnimDone( "animDone", "dd", 'd' ); -const idEventDef AI_OverrideAnim( "overrideAnim", "d" ); -const idEventDef AI_EnableAnim( "enableAnim", "dd" ); -const idEventDef AI_DisableAnimchannel( "disableAnimchannel", "d" ); -const idEventDef AI_PreventPain( "preventPain", "f" ); -const idEventDef AI_DisablePain( "disablePain" ); -const idEventDef AI_EnablePain( "enablePain" ); -const idEventDef AI_GetPainAnim( "getPainAnim", NULL, 's' ); -const idEventDef AI_SetAnimPrefix( "setAnimPrefix", "s" ); -const idEventDef AI_HasAnim( "hasAnim", "ds", 'f' ); -const idEventDef AI_CheckAnim( "checkAnim", "ds" ); -const idEventDef AI_ChooseAnim( "chooseAnim", "ds", 's' ); -const idEventDef AI_AnimLength( "animLength", "ds", 'f' ); -const idEventDef AI_AnimDistance( "animDistance", "ds", 'f' ); -const idEventDef AI_HasEnemies( "hasEnemies", NULL, 'd' ); -const idEventDef AI_NextEnemy( "nextEnemy", "E", 'e' ); -const idEventDef AI_ClosestEnemyToPoint( "closestEnemyToPoint", "v", 'e' ); -const idEventDef AI_SetNextState( "setNextState", "s" ); -const idEventDef AI_SetState( "setState", "s" ); -const idEventDef AI_GetState( "getState", NULL, 's' ); -const idEventDef AI_GetHead( "getHead", NULL, 'e' ); -const idEventDef AI_GetEyePos( "getEyePos", NULL, 'v' ); - -// greebo: Moved these from ai_events.cpp to here -const idEventDef AI_SetHealth( "setHealth", "f" ); -const idEventDef AI_GetHealth( "getHealth", NULL, 'f' ); - -// Attachment Related Events: -const idEventDef AI_Attach( "attach", "es" ); -const idEventDef AI_AttachToPos( "attachToPos", "ess" ); -const idEventDef AI_ReAttachToPos( "reAttachToPos", "ss" ); -const idEventDef AI_ReAttachToCoords( "reAttachToCoords", "ssvv" ); -const idEventDef AI_DropAttachment( "dropAttachment", "s" ); -const idEventDef AI_ShowAttachment( "showAttachment", "sd" ); -const idEventDef AI_DropAttachmentInd( "dropAttachmentInd", "d" ); -const idEventDef AI_ShowAttachmentInd( "showAttachmentInd", "dd" ); -const idEventDef AI_GetAttachment( "getAttachment", "s", 'e' ); -const idEventDef AI_GetAttachmentInd( "getAttachmentInd", "d", 'e' ); -const idEventDef AI_GetNumAttachments( "getNumAttachments", NULL, 'd' ); -// Weapon attachment related events -const idEventDef AI_GetNumRangedWeapons( "getNumRangedWeapons", NULL, 'd' ); -const idEventDef AI_GetNumMeleeWeapons( "getNumMeleeWeapons", NULL, 'd' ); - -// Getting/setting attack flags -const idEventDef AI_GetAttackFlag( "getAttackFlag", "d", 'd' ); -const idEventDef AI_SetAttackFlag( "setAttackFlag", "dd" ); - -// melee combat events -const idEventDef AI_MeleeAttackStarted( "meleeAttackStarted", "d" ); -const idEventDef AI_MeleeParryStarted( "meleeParryStarted", "d" ); -const idEventDef AI_MeleeActionHeld( "meleeActionHeld" ); -const idEventDef AI_MeleeActionReleased( "meleeActionReleased" ); -const idEventDef AI_MeleeActionFinished( "meleeActionFinished" ); -const idEventDef AI_GetMeleeActionState( "getMeleeActState", NULL, 'd' ); -const idEventDef AI_GetMeleeActionPhase( "getMeleeActPhase", NULL, 'd' ); -const idEventDef AI_GetMeleeActionType( "getMeleeActType", NULL, 'd' ); -const idEventDef AI_GetMeleeLastActTime( "getMeleeLastActTime", NULL, 'd' ); -const idEventDef AI_GetMeleeResult( "getMeleeResult", NULL, 'd' ); -const idEventDef AI_GetMeleeLastHitByType( "getMeleeLastHitByType", NULL, 'd' ); -const idEventDef AI_MeleeBestParry( "meleeBestParry", NULL, 'd' ); -const idEventDef AI_MeleeNameForNum( "meleeNameForNum", "d", 's' ); - -// greebo: anim replacement script events -const idEventDef AI_SetReplacementAnim( "setReplacementAnim", "ss"); -const idEventDef AI_LookupReplacementAnim( "lookupReplacementAnim", "s", 's'); -const idEventDef AI_RemoveReplacementAnim( "removeReplacementAnim", "s"); - -CLASS_DECLARATION( idAFEntity_Gibbable, idActor ) - EVENT( AI_EnableEyeFocus, idActor::Event_EnableEyeFocus ) - EVENT( AI_DisableEyeFocus, idActor::Event_DisableEyeFocus ) - EVENT( EV_Footstep, idActor::Event_Footstep ) - EVENT( EV_FootstepLeft, idActor::Event_Footstep ) - EVENT( EV_FootstepRight, idActor::Event_Footstep ) - EVENT( EV_EnableWalkIK, idActor::Event_EnableWalkIK ) - EVENT( EV_DisableWalkIK, idActor::Event_DisableWalkIK ) - EVENT( EV_EnableLegIK, idActor::Event_EnableLegIK ) - EVENT( EV_DisableLegIK, idActor::Event_DisableLegIK ) - EVENT( AI_PreventPain, idActor::Event_PreventPain ) - EVENT( AI_DisablePain, idActor::Event_DisablePain ) - EVENT( AI_EnablePain, idActor::Event_EnablePain ) - EVENT( AI_GetPainAnim, idActor::Event_GetPainAnim ) - EVENT( AI_SetAnimPrefix, idActor::Event_SetAnimPrefix ) - EVENT( AI_StopAnim, idActor::Event_StopAnim ) - EVENT( AI_PlayAnim, idActor::Event_PlayAnim ) - EVENT( AI_PauseAnim, idActor::Event_PauseAnim ) - EVENT( AI_AnimIsPaused, idActor::Event_AnimIsPaused ) - EVENT( AI_PlayCycle, idActor::Event_PlayCycle ) - EVENT( AI_IdleAnim, idActor::Event_IdleAnim ) - EVENT( AI_SetSyncedAnimWeight, idActor::Event_SetSyncedAnimWeight ) - EVENT( AI_SyncAnimChannels, idActor::Event_SyncAnimChannels) - EVENT( AI_SetBlendFrames, idActor::Event_SetBlendFrames ) - EVENT( AI_GetBlendFrames, idActor::Event_GetBlendFrames ) - EVENT( AI_AnimState, idActor::Event_AnimState ) - EVENT( AI_GetAnimState, idActor::Event_GetAnimState ) - EVENT( AI_InAnimState, idActor::Event_InAnimState ) - EVENT( AI_FinishAction, idActor::Event_FinishAction ) - EVENT( AI_FinishChannelAction, idActor::Event_FinishChannelAction ) - EVENT( AI_AnimDone, idActor::Event_AnimDone ) - EVENT( AI_OverrideAnim, idActor::Event_OverrideAnim ) - EVENT( AI_EnableAnim, idActor::Event_EnableAnim ) - EVENT( AI_DisableAnimchannel, idActor::Event_DisableAnimchannel ) - EVENT( AI_HasAnim, idActor::Event_HasAnim ) - EVENT( AI_CheckAnim, idActor::Event_CheckAnim ) - EVENT( AI_ChooseAnim, idActor::Event_ChooseAnim ) - EVENT( AI_AnimLength, idActor::Event_AnimLength ) - EVENT( AI_AnimDistance, idActor::Event_AnimDistance ) - EVENT( AI_HasEnemies, idActor::Event_HasEnemies ) - EVENT( AI_NextEnemy, idActor::Event_NextEnemy ) - EVENT( AI_ClosestEnemyToPoint, idActor::Event_ClosestEnemyToPoint ) - EVENT( AI_MeleeAttackStarted, idActor::Event_MeleeAttackStarted ) - EVENT( AI_MeleeParryStarted, idActor::Event_MeleeParryStarted ) - EVENT( AI_MeleeActionHeld, idActor::Event_MeleeActionHeld ) - EVENT( AI_MeleeActionReleased, idActor::Event_MeleeActionReleased ) - EVENT( AI_MeleeActionFinished, idActor::Event_MeleeActionFinished ) - EVENT( AI_GetMeleeActionState, idActor::Event_GetMeleeActionState ) - EVENT( AI_GetMeleeActionPhase, idActor::Event_GetMeleeActionPhase ) - EVENT( AI_GetMeleeActionType, idActor::Event_GetMeleeActionType ) - EVENT( AI_GetMeleeLastActTime, idActor::Event_GetMeleeLastActTime ) - EVENT( AI_GetMeleeResult, idActor::Event_GetMeleeResult ) - EVENT( AI_GetMeleeLastHitByType, idActor::Event_GetMeleeLastHitByType ) - EVENT( AI_MeleeBestParry, idActor::Event_MeleeBestParry ) - EVENT( AI_MeleeNameForNum, idActor::Event_MeleeNameForNum ) - EVENT( EV_StopSound, idActor::Event_StopSound ) - EVENT( AI_SetNextState, idActor::Event_SetNextState ) - EVENT( AI_SetState, idActor::Event_SetState ) - EVENT( AI_GetState, idActor::Event_GetState ) - EVENT( AI_GetHead, idActor::Event_GetHead ) - EVENT( AI_GetEyePos, idActor::Event_GetEyePos ) - EVENT( AI_SetHealth, idActor::Event_SetHealth ) - EVENT( AI_GetHealth, idActor::Event_GetHealth ) - - EVENT ( AI_Attach, idActor::Event_Attach ) - EVENT ( AI_AttachToPos, idActor::Event_AttachToPos ) - EVENT ( AI_ReAttachToPos, idActor::ReAttachToPos ) - EVENT ( AI_ReAttachToCoords, idActor::ReAttachToCoords ) - EVENT ( AI_DropAttachment, idActor::Detach ) - EVENT ( AI_ShowAttachment, idActor::ShowAttachment ) - EVENT ( AI_DropAttachmentInd, idActor::DetachInd ) - EVENT ( AI_ShowAttachmentInd, idActor::ShowAttachmentInd ) - EVENT ( AI_GetAttachment, idActor::Event_GetAttachment ) - EVENT ( AI_GetAttachmentInd, idActor::Event_GetAttachmentInd ) - EVENT ( AI_GetNumAttachments, idActor::Event_GetNumAttachments ) - EVENT ( AI_GetNumRangedWeapons, idActor::Event_GetNumRangedWeapons ) - EVENT ( AI_GetNumMeleeWeapons, idActor::Event_GetNumMeleeWeapons ) - - EVENT ( AI_SetReplacementAnim, idActor::Event_SetReplacementAnim ) - EVENT ( AI_LookupReplacementAnim, idActor::Event_LookupReplacementAnim ) - EVENT ( AI_RemoveReplacementAnim, idActor::Event_RemoveReplacementAnim ) - - EVENT ( AI_GetAttackFlag, idActor::Event_GetAttackFlag ) - EVENT ( AI_SetAttackFlag, idActor::Event_SetAttackFlag ) - -END_CLASS - -/* -===================== -idActor::idActor -===================== -*/ -idActor::idActor( void ) { - viewAxis.Identity(); - - scriptThread = NULL; // initialized by ConstructScriptObject, which is called by idEntity::Spawn - - use_combat_bbox = false; - head = NULL; - - m_AItype = 0; - m_Innocent = false; - rank = 0; - - greetingState = ECannotGreet; - - m_fovDotHoriz = 0.0f; - m_fovDotVert = 0.0f; - m_SneakAttackMult = 1.0f; - m_SneakAttackThresh = idMath::INFINITY; - eyeOffset.Zero(); - pain_debounce_time = 0; - pain_delay = 0; - pain_threshold = 0; - - melee_range_unarmed = 0.0f; - melee_range = 0.0f; - melee_range_vert = 0.0f; // grayman #2655 - m_MeleePredictedAttTime = 0.0f; - m_MeleePredictedAttTimeUnarmed = 0.0f; - m_MeleeDamageMult = 1.0f; - m_MeleeHoldTimeMin = 0; - m_MeleeHoldTimeMax = 0; - m_MeleeCurrentHoldTime = 0; - m_MeleeAttackRecoveryMin = 0; - m_MeleeAttackRecoveryMax = 0; - m_MeleeCurrentAttackRecovery = 0; - m_MeleeAttackLongRecoveryMin = 0; - m_MeleeAttackLongRecoveryMax = 0; - m_MeleeCurrentAttackLongRecovery = 0; - m_MeleeParryRecoveryMin = 0; - m_MeleeParryRecoveryMax = 0; - m_MeleeCurrentParryRecovery = 0; - m_MeleeRiposteRecoveryMin = 0; - m_MeleeRiposteRecoveryMax = 0; - m_MeleeCurrentRiposteRecovery = 0; - m_MeleePreParryDelayMin = 0; - m_MeleePreParryDelayMax = 0; - m_MeleeCurrentPreParryDelay = 0; - m_MeleeRepeatedPreParryDelayMin = 0; - m_MeleeRepeatedPreParryDelayMax = 0; - m_MeleeCurrentRepeatedPreParryDelay = 0; - m_MeleeNumRepAttacks = 0; - m_MeleeRepAttackTime = 0; - m_MeleePostParryDelayMin = 0; - m_MeleePostParryDelayMax = 0; - m_MeleeCurrentPostParryDelay = 0; - m_MeleeRepeatedPostParryDelayMin = 0; - m_MeleeRepeatedPostParryDelayMax = 0; - m_MeleeCurrentRepeatedPostParryDelay = 0; - - - state = NULL; - idealState = NULL; - - leftEyeJoint = INVALID_JOINT; - rightEyeJoint = INVALID_JOINT; - soundJoint = INVALID_JOINT; - - modelOffset.Zero(); - deltaViewAngles.Zero(); - - painTime = 0; - allowPain = false; - allowEyeFocus = false; - - waitState = ""; - - blink_anim = 0; - blink_time = 0; - blink_min = 0; - blink_max = 0; - - finalBoss = false; - - m_Attachments.SetGranularity( 1 ); - - enemyNode.SetOwner( this ); - enemyList.SetOwner( this ); - - INIT_TIMER_HANDLE(actorGetObstaclesTimer); - INIT_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer); - INIT_TIMER_HANDLE(actorGetWallEdgesTimer); - INIT_TIMER_HANDLE(actorSortWallEdgesTimer); - INIT_TIMER_HANDLE(actorBuildPathTreeTimer); - INIT_TIMER_HANDLE(actorPrunePathTreeTimer); - INIT_TIMER_HANDLE(actorFindOptimalPathTimer); - INIT_TIMER_HANDLE(actorRouteToGoalTimer); - INIT_TIMER_HANDLE(actorSubSampleWalkPathTimer); - INIT_TIMER_HANDLE(actorWalkPathValidTimer); - -} - -/* -===================== -idActor::~idActor -===================== -*/ -idActor::~idActor( void ) { - int i; - idEntity *ent; - - DeconstructScriptObject(); - scriptObject.Free(); - - StopSound( SND_CHANNEL_ANY, false ); - - delete combatModel; - combatModel = NULL; - - if ( head.GetEntity() ) { - head.GetEntity()->ClearBody(); - head.GetEntity()->PostEventMS( &EV_Remove, 0 ); - } - - // remove any attached entities - for( i = 0; i < m_Attachments.Num(); i++ ) { - ent = m_Attachments[ i ].ent.GetEntity(); - if ( ent ) { - ent->PostEventMS( &EV_SafeRemove, 0 ); - } - } - - ShutdownThreads(); -} - -/* -===================== -idActor::Spawn -===================== -*/ -void idActor::Spawn( void ) -{ - idStr jointName; - float fovDegHoriz, fovDegVert; - copyJoints_t copyJoint; - const idKeyValue *kv = NULL; - - animPrefix = ""; - state = NULL; - idealState = NULL; - - spawnArgs.GetFloat( "collision_damage_threshold_hard", "25", m_damage_thresh_hard ); // greebo: dealing 50+ hit points is considered "hard" - spawnArgs.GetFloat( "collision_damage_threshold_min", "5", m_damage_thresh_min ); // falling ~12 ft, g = 1066 - - spawnArgs.GetFloat( "collision_delta_scale", "1.0", m_delta_scale ); - spawnArgs.GetInt( "rank", "0", rank ); - spawnArgs.GetInt( "type", "0", m_AItype ); - spawnArgs.GetBool( "innocent", "0", m_Innocent ); - spawnArgs.GetVector("offsetModel", "0 0 0", modelOffset); - - spawnArgs.GetBool( "use_combat_bbox", "0", use_combat_bbox ); - - viewAxis = GetPhysics()->GetAxis(); - - spawnArgs.GetFloat( "fov", "150", fovDegHoriz ); - // If fov_vert is -1, it will be set the same as horizontal - spawnArgs.GetFloat( "fov_vert", "-1", fovDegVert ); - SetFOV( fovDegHoriz, fovDegVert ); - - pain_debounce_time = 0; - - pain_delay = SEC2MS( spawnArgs.GetFloat( "pain_delay" ) ); - pain_threshold = spawnArgs.GetInt( "pain_threshold" ); - - // load melee settings based on AI skill level + player difficulty - LoadMeleeSet(); - // adjust health based on multiplier that may be in melee set - health += spawnArgs.GetFloat("health_offset", "0.0"); - - melee_range_unarmed = spawnArgs.GetFloat( "melee_range","64"); - melee_range = melee_range_unarmed; - - // grayman #2655 - if "melee_range_vert" has a value, use that, - // otherwise set it to melee_range - - melee_range_vert = spawnArgs.GetFloat( "melee_range_vert","0"); - if (melee_range_vert == 0) - { - melee_range_vert = melee_range; - } - - m_MeleePredictedAttTimeUnarmed = 0.001f * spawnArgs.GetFloat("melee_predicted_attack_time"); - m_MeleePredictedAttTime = m_MeleePredictedAttTimeUnarmed; - m_MeleeDamageMult = spawnArgs.GetFloat("melee_damage_mod","1.0f"); - m_MeleeHoldTimeMin = spawnArgs.GetInt("melee_hold_time_min"); - m_MeleeHoldTimeMax = spawnArgs.GetInt("melee_hold_time_max"); - m_MeleeParryHoldMax = spawnArgs.GetInt("melee_parry_hold_max"); - m_MeleeParryHoldMin = spawnArgs.GetInt("melee_parry_hold_min"); - m_MeleeAttackRecoveryMin = spawnArgs.GetInt("melee_attack_recovery_min"); - m_MeleeAttackRecoveryMax = spawnArgs.GetInt("melee_attack_recovery_max"); - m_MeleeAttackLongRecoveryMin = spawnArgs.GetInt("melee_attack_long_recovery_min"); - m_MeleeAttackLongRecoveryMax = spawnArgs.GetInt("melee_attack_long_recovery_max"); - m_MeleeParryRecoveryMin = spawnArgs.GetInt("melee_parry_recovery_min"); - m_MeleeParryRecoveryMax = spawnArgs.GetInt("melee_parry_recovery_max"); - m_MeleeRiposteRecoveryMin = spawnArgs.GetInt("melee_riposte_recovery_min"); - m_MeleeRiposteRecoveryMax = spawnArgs.GetInt("melee_riposte_recovery_max"); - m_MeleePreParryDelayMin = spawnArgs.GetInt("melee_pre_parry_delay_min"); - m_MeleePreParryDelayMax = spawnArgs.GetInt("melee_pre_parry_delay_max"); - m_MeleeRepeatedPreParryDelayMin = spawnArgs.GetInt("melee_repeated_pre_parry_delay_min"); - m_MeleeRepeatedPreParryDelayMax = spawnArgs.GetInt("melee_repeated_pre_parry_delay_max"); - m_MeleePostParryDelayMin = spawnArgs.GetInt("melee_post_parry_delay_min"); - m_MeleePostParryDelayMax = spawnArgs.GetInt("melee_post_parry_delay_max"); - m_MeleeRepeatedPostParryDelayMin = spawnArgs.GetInt("melee_repeated_post_parry_delay_min"); - m_MeleeRepeatedPostParryDelayMax = spawnArgs.GetInt("melee_repeated_post_parry_delay_max"); - m_MeleeNumRepAttacks = spawnArgs.GetInt("melee_num_rep_attacks"); - m_MeleeRepAttackTime = spawnArgs.GetInt("melee_rep_attack_time"); - - LoadAF(); - - walkIK.Init( this, IK_ANIM, modelOffset ); - - // the animation used to be set to the IK_ANIM at this point, but that was fixed, resulting in - // attachments not binding correctly, so we're stuck setting the IK_ANIM before attaching things. - animator.ClearAllAnims( gameLocal.time, 0 ); - animator.SetFrame( ANIMCHANNEL_ALL, animator.GetAnim( IK_ANIM ), 0, 0, 0 ); - - SetupDamageGroups(); - ParseAttachmentsAF(); - SetupHead(); - - // clear the bind anim - animator.ClearAllAnims( gameLocal.time, 0 ); - - idEntity *headEnt = head.GetEntity(); - idAnimator *headAnimator; - if ( headEnt ) { - headAnimator = headEnt->GetAnimator(); - } else { - headAnimator = &animator; - } - - if ( headEnt ) { - // set up the list of joints to copy to the head - for( kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) { - if ( kv->GetValue() == "" ) { - // probably clearing out inherited key, so skip it - continue; - } - - jointName = kv->GetKey(); - if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) { - copyJoint.mod = JOINTMOD_WORLD_OVERRIDE; - } else { - jointName.StripLeadingOnce( "copy_joint " ); - copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE; - } - - copyJoint.from = animator.GetJointHandle( jointName ); - if ( copyJoint.from == INVALID_JOINT ) { - gameLocal.Warning( "Unknown copy_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); - continue; - } - - jointName = kv->GetValue(); - copyJoint.to = headAnimator->GetJointHandle( jointName ); - if ( copyJoint.to == INVALID_JOINT ) { - gameLocal.Warning( "Unknown copy_joint '%s' on head of entity %s", jointName.c_str(), name.c_str() ); - continue; - } - - copyJoints.Append( copyJoint ); - } - } - - greetingState = spawnArgs.GetBool("canGreet", "0") ? ENotGreetingAnybody : ECannotGreet; - - // set up blinking - blink_anim = headAnimator->GetAnim( "blink" ); - blink_time = 0; // it's ok to blink right away - blink_min = SEC2MS( spawnArgs.GetFloat( "blink_min", "0.5" ) ); - blink_max = SEC2MS( spawnArgs.GetFloat( "blink_max", "8" ) ); - - // set up the head anim if necessary - int headAnim = headAnimator->GetAnim( "def_head" ); - if ( headAnim ) { - if ( headEnt ) { - headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, 0 ); - } else { - headAnimator->CycleAnim( ANIMCHANNEL_HEAD, headAnim, gameLocal.time, 0 ); - } - } - - if ( spawnArgs.GetString( "sound_bone", "", jointName ) ) { - soundJoint = animator.GetJointHandle( jointName ); - if ( soundJoint == INVALID_JOINT ) { - gameLocal.Warning( "idAnimated '%s' at (%s): cannot find joint '%s' for sound playback", name.c_str(), GetPhysics()->GetOrigin().ToString(0), jointName.c_str() ); - } - } - - finalBoss = spawnArgs.GetBool( "finalBoss" ); - - canUseElevators = spawnArgs.GetBool("canOperateElevators", "0"); - - // greebo: Set up the melee flags for AI without weapons - if (spawnArgs.GetBool("unarmed_melee")) - { - SetAttackFlag(COMBAT_MELEE, true); - // add the general unarmed attack to possible melee attacks list - // this will be overridden if they get a weapon attached - // TODO: Add this back in if the weapon is later detached? - m_MeleeStatus.m_attacks.Append(MELEETYPE_UNBLOCKABLE); - } - - if (spawnArgs.GetBool("unarmed_ranged")) - { - SetAttackFlag(COMBAT_RANGED, true); - } - - lowHealthThreshold = spawnArgs.GetInt("low_health_threshold", "-1"); - lowHealthScript = spawnArgs.GetString("low_health_script"); - - LoadVocalSet(); - - // Load replacement animations from our own spawnargs - LoadReplacementAnims(spawnArgs); - - FinishSetup(); - - CREATE_TIMER(actorGetObstaclesTimer, name, "GetObstacles"); - CREATE_TIMER(actorGetPointOutsideObstaclesTimer, name, "GetPointOutsideObstacles"); - CREATE_TIMER(actorGetWallEdgesTimer, name, "GetWallEdges"); - CREATE_TIMER(actorSortWallEdgesTimer, name, "SortWallEdges"); - CREATE_TIMER(actorBuildPathTreeTimer, name, "BuildPathTree"); - CREATE_TIMER(actorPrunePathTreeTimer, name, "PrunePathTree"); - CREATE_TIMER(actorFindOptimalPathTimer, name, "FindOptimalPath"); - CREATE_TIMER(actorRouteToGoalTimer, name, "RouteToGoal"); - CREATE_TIMER(actorSubSampleWalkPathTimer, name, "SubSampleWalkPath"); - CREATE_TIMER(actorWalkPathValidTimer, name, "WalkPathValid"); - - m_pathRank = rank; // grayman #2345 - rank for path-finding - m_nextKickTime = 0; // grayman #2728 -} - -/* -================ -idActor::FinishSetup -================ -*/ -void idActor::FinishSetup( void ) { - const char *scriptObjectName; - - // setup script object - if ( spawnArgs.GetString( "scriptobject", NULL, &scriptObjectName ) ) { - if ( !scriptObject.SetType( scriptObjectName ) ) { - gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() ); - } - - ConstructScriptObject(); - } - - SetupBody(); -} - -/* -================ -idActor::SetupHead -================ -*/ -void idActor::SetupHead() -{ - if(gameLocal.isClient) - return; - - idStr headModelDefName = spawnArgs.GetString( "def_head", "" ); - - if (!headModelDefName.IsEmpty()) - { - // We look if the head model is defined as a key to have a specific offset. - // If that is not the case, then we use the default value, if it exists, - // otherwise there is no offset at all. - mHeadModelOffset = spawnArgs.GetVector(headModelDefName, "0 0 0"); - - // greebo: Regardless what happens, the offsetHeadModel vector always gets added to the offset - mHeadModelOffset += spawnArgs.GetVector("offsetHeadModel", "0 0 0"); - - idStr jointName = spawnArgs.GetString( "head_joint" ); - jointHandle_t joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Joint '%s' not found for 'head_joint' on '%s'", jointName.c_str(), name.c_str() ); - } - - // set the damage joint to be part of the head damage group (if possible) - jointHandle_t damageJoint = joint; - - for (int i = 0; i < damageGroups.Num(); i++ ) - { - if ( damageGroups[ i ] == "head" ) { - damageJoint = static_cast( i ); - break; - } - } - - // Setup the default spawnargs for all heads - idDict args; - - const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); - - if (def == NULL) - { - gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); - - // Try to fallback on the default head entityDef - def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); - } - - if (def != NULL) - { - // Make a copy of the default spawnargs - args = def->dict; - } - else - { - gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); - } - - // Copy any sounds in case we have frame commands on the head - for (const idKeyValue* kv = spawnArgs.MatchPrefix("snd_", NULL); kv != NULL; kv = spawnArgs.MatchPrefix("snd_", kv)) - { - args.Set(kv->GetKey(), kv->GetValue()); - } - - // Spawn the head entity - idEntity* ent = gameLocal.SpawnEntityType(idAFAttachment::Type, &args); - idAFAttachment* headEnt = static_cast(ent); - headEnt->SetName( name + "_head" ); - - // Retrieve the actual model from the head entityDef - idStr headModel = args.GetString("model"); - if (headModel.IsEmpty()) - { - gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); - } - headEnt->SetBody( this, headModel, damageJoint ); - headEnt->SetCombatModel(); - - // Store the head locally - head = headEnt; - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("SETBODY: Actor %s : damage joint %d for attached head is part of damage group %s\r", name.c_str(), (int) damageJoint, GetDamageGroup( damageJoint ) ); - - // Add the head as attachment - idVec3 origin; - idMat3 axis; - CAttachInfo& attach = m_Attachments.Alloc(); - - attach.channel = animator.GetChannelForJoint( joint ); - animator.GetJointTransform( joint, gameLocal.time, origin, axis ); - origin = renderEntity.origin + ( origin + modelOffset + mHeadModelOffset ) * renderEntity.axis; - attach.ent = headEnt; - attach.posName = jointName; // grayman #2603 - - headEnt->SetOrigin( origin ); - headEnt->SetAxis( renderEntity.axis ); - headEnt->BindToJoint( this, joint, true ); - - // greebo: Setup the frob-peer relationship between head and body - m_FrobPeers.AddUnique(headEnt->name); - } -} - -/* -================ -idActor::CopyJointsFromBodyToHead -================ -*/ -void idActor::CopyJointsFromBodyToHead( void ) { - idEntity *headEnt = head.GetEntity(); - idAnimator *headAnimator; - int i; - idMat3 mat; - idMat3 axis; - idVec3 pos; - - if ( !headEnt ) { - return; - } - - headAnimator = headEnt->GetAnimator(); - - // copy the animation from the body to the head - for( i = 0; i < copyJoints.Num(); i++ ) { - if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) { - mat = headEnt->GetPhysics()->GetAxis().Transpose(); - GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); - pos -= headEnt->GetPhysics()->GetOrigin(); - headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat ); - headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat ); - } else { - animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); - headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos ); - headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis ); - } - } -} - -/* -================ -idActor::Restart -================ -*/ -void idActor::Restart( void ) { - assert( !head.GetEntity() ); - SetupHead(); - FinishSetup(); -} - -/* -================ -idActor::Save - -archive object for savegame file -================ -*/ -void idActor::Save( idSaveGame *savefile ) const { - idActor *ent; - int i; - - savefile->WriteInt( rank ); - savefile->WriteInt( m_AItype ); - savefile->WriteBool( m_Innocent ); - savefile->WriteMat3( viewAxis ); - - savefile->WriteInt( enemyList.Num() ); - for ( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - savefile->WriteObject( ent ); - } - - savefile->WriteInt(static_cast(greetingState)); - - // melee stuff - m_MeleeStatus.Save( savefile ); - savefile->WriteFloat( melee_range_unarmed ); - savefile->WriteFloat( melee_range ); - savefile->WriteFloat( melee_range_vert ); // grayman #2655 - savefile->WriteFloat( m_MeleePredictedAttTimeUnarmed ); - savefile->WriteFloat( m_MeleePredictedAttTime ); - savefile->WriteFloat( m_MeleeDamageMult ); - savefile->WriteInt( m_MeleeHoldTimeMin ); - savefile->WriteInt( m_MeleeHoldTimeMax ); - savefile->WriteInt( m_MeleeCurrentHoldTime ); - savefile->WriteInt( m_MeleeAttackRecoveryMin ); - savefile->WriteInt( m_MeleeAttackRecoveryMax ); - savefile->WriteInt( m_MeleeCurrentAttackRecovery ); - savefile->WriteInt( m_MeleeAttackLongRecoveryMin ); - savefile->WriteInt( m_MeleeAttackLongRecoveryMax ); - savefile->WriteInt( m_MeleeCurrentAttackLongRecovery ); - savefile->WriteInt( m_MeleeParryRecoveryMin ); - savefile->WriteInt( m_MeleeParryRecoveryMax ); - savefile->WriteInt( m_MeleeCurrentParryRecovery ); - savefile->WriteInt( m_MeleeRiposteRecoveryMin ); - savefile->WriteInt( m_MeleeRiposteRecoveryMax ); - savefile->WriteInt( m_MeleeCurrentRiposteRecovery ); - savefile->WriteInt( m_MeleePreParryDelayMin ); - savefile->WriteInt( m_MeleePreParryDelayMax ); - savefile->WriteInt( m_MeleeCurrentPreParryDelay ); - savefile->WriteInt( m_MeleeRepeatedPreParryDelayMin ); - savefile->WriteInt( m_MeleeRepeatedPreParryDelayMax ); - savefile->WriteInt( m_MeleeCurrentRepeatedPreParryDelay ); - savefile->WriteInt( m_MeleeNumRepAttacks ); - savefile->WriteInt( m_MeleeRepAttackTime ); - savefile->WriteInt( m_MeleePostParryDelayMin ); - savefile->WriteInt( m_MeleePostParryDelayMax ); - savefile->WriteInt( m_MeleeCurrentPostParryDelay ); - savefile->WriteInt( m_MeleeRepeatedPostParryDelayMin ); - savefile->WriteInt( m_MeleeRepeatedPostParryDelayMax ); - savefile->WriteInt( m_MeleeCurrentRepeatedPostParryDelay ); - savefile->WriteInt( m_pathRank ); // grayman #2345 - savefile->WriteInt( m_nextKickTime ); // grayman #2728 - - savefile->WriteFloat( m_fovDotHoriz ); - savefile->WriteFloat( m_fovDotVert ); - savefile->WriteVec3( eyeOffset ); - savefile->WriteVec3( modelOffset ); - savefile->WriteVec3(mHeadModelOffset); - savefile->WriteAngles( deltaViewAngles ); - - savefile->WriteInt( pain_debounce_time ); - savefile->WriteInt( pain_delay ); - savefile->WriteInt( pain_threshold ); - - savefile->WriteInt( damageGroups.Num() ); - for( i = 0; i < damageGroups.Num(); i++ ) { - savefile->WriteString( damageGroups[ i ] ); - } - - savefile->WriteInt( damageScale.Num() ); - for( i = 0; i < damageScale.Num(); i++ ) { - savefile->WriteFloat( damageScale[ i ] ); - } - - savefile->WriteInt(lowHealthThreshold); - savefile->WriteString(lowHealthScript); - - savefile->WriteFloat( m_SneakAttackThresh ); - savefile->WriteFloat( m_SneakAttackMult ); - - savefile->WriteBool( use_combat_bbox ); - head.Save( savefile ); - - savefile->WriteInt( copyJoints.Num() ); - for( i = 0; i < copyJoints.Num(); i++ ) { - savefile->WriteInt( copyJoints[i].mod ); - savefile->WriteJoint( copyJoints[i].from ); - savefile->WriteJoint( copyJoints[i].to ); - } - - savefile->WriteJoint( leftEyeJoint ); - savefile->WriteJoint( rightEyeJoint ); - savefile->WriteJoint( soundJoint ); - - walkIK.Save( savefile ); - - savefile->WriteString( animPrefix ); - savefile->WriteString( painAnim ); - - savefile->WriteInt( blink_anim ); - savefile->WriteInt( blink_time ); - savefile->WriteInt( blink_min ); - savefile->WriteInt( blink_max ); - - // script variables - savefile->WriteObject( scriptThread ); - - savefile->WriteString( waitState ); - - headAnim.Save( savefile ); - torsoAnim.Save( savefile ); - legsAnim.Save( savefile ); - - savefile->WriteBool( allowPain ); - savefile->WriteBool( allowEyeFocus ); - - savefile->WriteInt( painTime ); - - savefile->WriteBool(canUseElevators); - - savefile->WriteBool( finalBoss ); - savefile->WriteFloat( m_damage_thresh_hard ); - savefile->WriteFloat( m_delta_scale ); - savefile->WriteFloat( m_damage_thresh_min ); - - idToken token; - - //FIXME: this is unneccesary - if ( state ) { - idLexer src( state->Name(), idStr::Length( state->Name() ), "idAI::Save" ); - - src.ReadTokenOnLine( &token ); - src.ExpectTokenString( "::" ); - src.ReadTokenOnLine( &token ); - - savefile->WriteString( token ); - } else { - savefile->WriteString( "" ); - } - - if ( idealState ) { - idLexer src( idealState->Name(), idStr::Length( idealState->Name() ), "idAI::Save" ); - - src.ReadTokenOnLine( &token ); - src.ExpectTokenString( "::" ); - src.ReadTokenOnLine( &token ); - - savefile->WriteString( token ); - } else { - savefile->WriteString( "" ); - } - - savefile->WriteFloat(m_stepvol_walk); - savefile->WriteFloat(m_stepvol_run); - savefile->WriteFloat(m_stepvol_creep); - - savefile->WriteFloat(m_stepvol_crouch_walk); - savefile->WriteFloat(m_stepvol_crouch_creep); - savefile->WriteFloat(m_stepvol_crouch_run); - - savefile->WriteDict(&m_replacementAnims); - - savefile->WriteInt(static_cast(m_AttackFlags.size())); - for (std::set::const_iterator i = m_AttackFlags.begin(); i != m_AttackFlags.end(); ++i) - { - savefile->WriteInt(static_cast(*i)); - } - - SAVE_TIMER_HANDLE(actorGetObstaclesTimer, savefile); - SAVE_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer, savefile); - SAVE_TIMER_HANDLE(actorGetWallEdgesTimer, savefile); - SAVE_TIMER_HANDLE(actorSortWallEdgesTimer, savefile); - SAVE_TIMER_HANDLE(actorBuildPathTreeTimer, savefile); - SAVE_TIMER_HANDLE(actorPrunePathTreeTimer, savefile); - SAVE_TIMER_HANDLE(actorFindOptimalPathTimer, savefile); - SAVE_TIMER_HANDLE(actorRouteToGoalTimer, savefile); - SAVE_TIMER_HANDLE(actorSubSampleWalkPathTimer, savefile); - SAVE_TIMER_HANDLE(actorWalkPathValidTimer, savefile); -} - -/* -================ -idActor::Restore - -unarchives object from save game file -================ -*/ -void idActor::Restore( idRestoreGame *savefile ) { - int i, num; - idActor *ent; - - savefile->ReadInt( rank ); - savefile->ReadInt( m_AItype ); - savefile->ReadBool( m_Innocent ); - savefile->ReadMat3( viewAxis ); - - savefile->ReadInt( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadObject( reinterpret_cast( ent ) ); - assert( ent ); - if ( ent ) { - ent->enemyNode.AddToEnd( enemyList ); - } - } - - savefile->ReadInt(i); - assert(i >= ECannotGreet && i < ENumAIGreetingStates); - greetingState = static_cast(i); - - // melee stuff - m_MeleeStatus.Restore( savefile ); - savefile->ReadFloat( melee_range_unarmed ); - savefile->ReadFloat( melee_range ); - savefile->ReadFloat( melee_range_vert ); // grayman #2655 - savefile->ReadFloat( m_MeleePredictedAttTimeUnarmed ); - savefile->ReadFloat( m_MeleePredictedAttTime ); - savefile->ReadFloat( m_MeleeDamageMult ); - savefile->ReadInt( m_MeleeHoldTimeMin ); - savefile->ReadInt( m_MeleeHoldTimeMax ); - savefile->ReadInt( m_MeleeCurrentHoldTime ); - savefile->ReadInt( m_MeleeAttackRecoveryMin ); - savefile->ReadInt( m_MeleeAttackRecoveryMax ); - savefile->ReadInt( m_MeleeCurrentAttackRecovery ); - savefile->ReadInt( m_MeleeAttackLongRecoveryMin ); - savefile->ReadInt( m_MeleeAttackLongRecoveryMax ); - savefile->ReadInt( m_MeleeCurrentAttackLongRecovery ); - savefile->ReadInt( m_MeleeParryRecoveryMin ); - savefile->ReadInt( m_MeleeParryRecoveryMax ); - savefile->ReadInt( m_MeleeCurrentParryRecovery ); - savefile->ReadInt( m_MeleeRiposteRecoveryMin ); - savefile->ReadInt( m_MeleeRiposteRecoveryMax ); - savefile->ReadInt( m_MeleeCurrentRiposteRecovery ); - savefile->ReadInt( m_MeleePreParryDelayMin ); - savefile->ReadInt( m_MeleePreParryDelayMax ); - savefile->ReadInt( m_MeleeCurrentPreParryDelay ); - savefile->ReadInt( m_MeleeRepeatedPreParryDelayMin ); - savefile->ReadInt( m_MeleeRepeatedPreParryDelayMax ); - savefile->ReadInt( m_MeleeCurrentRepeatedPreParryDelay ); - savefile->ReadInt( m_MeleeNumRepAttacks ); - savefile->ReadInt( m_MeleeRepAttackTime ); - savefile->ReadInt( m_MeleePostParryDelayMin ); - savefile->ReadInt( m_MeleePostParryDelayMax ); - savefile->ReadInt( m_MeleeCurrentPostParryDelay ); - savefile->ReadInt( m_MeleeRepeatedPostParryDelayMin ); - savefile->ReadInt( m_MeleeRepeatedPostParryDelayMax ); - savefile->ReadInt( m_MeleeCurrentRepeatedPostParryDelay ); - savefile->ReadInt( m_pathRank ); // grayman #2345 - savefile->ReadInt(m_nextKickTime); // grayman #2728 - - savefile->ReadFloat( m_fovDotHoriz ); - savefile->ReadFloat( m_fovDotVert ); - savefile->ReadVec3( eyeOffset ); - savefile->ReadVec3( modelOffset ); - savefile->ReadVec3(mHeadModelOffset); - savefile->ReadAngles( deltaViewAngles ); - - savefile->ReadInt( pain_debounce_time ); - savefile->ReadInt( pain_delay ); - savefile->ReadInt( pain_threshold ); - - savefile->ReadInt( num ); - damageGroups.SetGranularity( 1 ); - damageGroups.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadString( damageGroups[ i ] ); - } - - savefile->ReadInt( num ); - damageScale.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadFloat( damageScale[ i ] ); - } - - savefile->ReadInt(lowHealthThreshold); - savefile->ReadString(lowHealthScript); - - savefile->ReadFloat( m_SneakAttackThresh ); - savefile->ReadFloat( m_SneakAttackMult ); - - savefile->ReadBool( use_combat_bbox ); - head.Restore( savefile ); - - savefile->ReadInt( num ); - copyJoints.SetNum( num ); - for( i = 0; i < num; i++ ) { - int val; - savefile->ReadInt( val ); - copyJoints[i].mod = static_cast( val ); - savefile->ReadJoint( copyJoints[i].from ); - savefile->ReadJoint( copyJoints[i].to ); - } - - savefile->ReadJoint( leftEyeJoint ); - savefile->ReadJoint( rightEyeJoint ); - savefile->ReadJoint( soundJoint ); - - walkIK.Restore( savefile ); - - savefile->ReadString( animPrefix ); - savefile->ReadString( painAnim ); - - savefile->ReadInt( blink_anim ); - savefile->ReadInt( blink_time ); - savefile->ReadInt( blink_min ); - savefile->ReadInt( blink_max ); - - savefile->ReadObject( reinterpret_cast( scriptThread ) ); - - savefile->ReadString( waitState ); - - headAnim.Restore( savefile ); - torsoAnim.Restore( savefile ); - legsAnim.Restore( savefile ); - - savefile->ReadBool( allowPain ); - savefile->ReadBool( allowEyeFocus ); - - savefile->ReadInt( painTime ); - savefile->ReadBool(canUseElevators); - - savefile->ReadBool( finalBoss ); - savefile->ReadFloat( m_damage_thresh_hard ); - savefile->ReadFloat( m_delta_scale ); - savefile->ReadFloat( m_damage_thresh_min ); - - idStr statename; - - savefile->ReadString( statename ); - if ( statename.Length() > 0 ) { - state = GetScriptFunction( statename ); - } - - savefile->ReadString( statename ); - if ( statename.Length() > 0 ) { - idealState = GetScriptFunction( statename ); - } - - savefile->ReadFloat(m_stepvol_walk); - savefile->ReadFloat(m_stepvol_run); - savefile->ReadFloat(m_stepvol_creep); - - savefile->ReadFloat(m_stepvol_crouch_walk); - savefile->ReadFloat(m_stepvol_crouch_creep); - savefile->ReadFloat(m_stepvol_crouch_run); - - savefile->ReadDict(&m_replacementAnims); - - m_AttackFlags.clear(); - savefile->ReadInt(num); - for (int i = 0; i < num; i++) - { - int temp; - savefile->ReadInt(temp); - assert(static_cast(temp) >= COMBAT_NONE && static_cast(temp) <= COMBAT_RANGED); - m_AttackFlags.insert(temp); - } - - RESTORE_TIMER_HANDLE(actorGetObstaclesTimer, savefile); - RESTORE_TIMER_HANDLE(actorGetPointOutsideObstaclesTimer, savefile); - RESTORE_TIMER_HANDLE(actorGetWallEdgesTimer, savefile); - RESTORE_TIMER_HANDLE(actorSortWallEdgesTimer, savefile); - RESTORE_TIMER_HANDLE(actorBuildPathTreeTimer, savefile); - RESTORE_TIMER_HANDLE(actorPrunePathTreeTimer, savefile); - RESTORE_TIMER_HANDLE(actorFindOptimalPathTimer, savefile); - RESTORE_TIMER_HANDLE(actorRouteToGoalTimer, savefile); - RESTORE_TIMER_HANDLE(actorSubSampleWalkPathTimer, savefile); - RESTORE_TIMER_HANDLE(actorWalkPathValidTimer, savefile); - -} - -/* -================ -idActor::Hide -================ -*/ -void idActor::Hide( void ) -{ - idAFEntity_Base::Hide(); - if ( head.GetEntity() ) - { - head.GetEntity()->Hide(); - } - UnlinkCombat(); -} - -/* -================ -idActor::Show -================ -*/ -void idActor::Show( void ) -{ - idAFEntity_Base::Show(); - if ( head.GetEntity() ) { - head.GetEntity()->Show(); - } - - LinkCombat(); -} - -/* -============== -idActor::GetDefaultSurfaceType -============== -*/ -int idActor::GetDefaultSurfaceType( void ) const { - return SURFTYPE_FLESH; -} - -/* -================ -idActor::ProjectOverlay -================ -*/ -void idActor::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { - idEntity *ent; - idEntity *next; - - idEntity::ProjectOverlay( origin, dir, size, material ); - - for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { - next = ent->GetNextTeamEntity(); - if ( ent->GetBindMaster() == this ) { - if ( ent->fl.takedamage && ent->spawnArgs.GetBool( "bleed" ) ) { - ent->ProjectOverlay( origin, dir, size, material ); - } - } - } -} - -/* -================ -idActor::LoadAF -================ -*/ -bool idActor::LoadAF( void ) -{ - bool bReturnVal = false; - idStr fileName; - - if ( !spawnArgs.GetString( "ragdoll", "*unknown*", fileName ) || !fileName.Length() ) - { - goto Quit; - } - af.SetAnimator( GetAnimator() ); - bReturnVal = af.Load( this, fileName ); - SetUpGroundingVars(); - - if( m_bAFPushMoveables ) - { - af.SetupPose( this, gameLocal.time ); - af.GetPhysics()->EnableClip(); - } - -Quit: - return bReturnVal; -} - -/* -===================== -idActor::SetupBody -===================== -*/ -void idActor::SetupBody( void ) { - const char *jointname; - - animator.ClearAllAnims( gameLocal.time, 0 ); - animator.ClearAllJoints(); - - idEntity *headEnt = head.GetEntity(); - if ( headEnt ) { - jointname = spawnArgs.GetString( "bone_leftEye" ); - leftEyeJoint = headEnt->GetAnimator()->GetJointHandle( jointname ); - - jointname = spawnArgs.GetString( "bone_rightEye" ); - rightEyeJoint = headEnt->GetAnimator()->GetJointHandle( jointname ); - - // set up the eye height. check if it's specified in the def. - if ( !spawnArgs.GetFloat( "eye_height", "0", eyeOffset.z ) ) { - // if not in the def, then try to base it off the idle animation - int anim = headEnt->GetAnimator()->GetAnim( "idle" ); - if ( anim && ( leftEyeJoint != INVALID_JOINT ) ) { - idVec3 pos; - idMat3 axis; - headEnt->GetAnimator()->PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, 0 ); - headEnt->GetAnimator()->GetJointTransform( leftEyeJoint, gameLocal.time, pos, axis ); - headEnt->GetAnimator()->ClearAllAnims( gameLocal.time, 0 ); - headEnt->GetAnimator()->ForceUpdate(); - pos += headEnt->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - eyeOffset = pos + modelOffset; - } else { - // just base it off the bounding box size - eyeOffset.z = GetPhysics()->GetBounds()[ 1 ].z - 6; - } - } - headAnim.Init( this, headEnt->GetAnimator(), ANIMCHANNEL_ALL ); - } else { - jointname = spawnArgs.GetString( "bone_leftEye" ); - leftEyeJoint = animator.GetJointHandle( jointname ); - - jointname = spawnArgs.GetString( "bone_rightEye" ); - rightEyeJoint = animator.GetJointHandle( jointname ); - - // set up the eye height. check if it's specified in the def. - if ( !spawnArgs.GetFloat( "eye_height", "0", eyeOffset.z ) ) { - // if not in the def, then try to base it off the idle animation - int anim = animator.GetAnim( "idle" ); - if ( anim && ( leftEyeJoint != INVALID_JOINT ) ) { - idVec3 pos; - idMat3 axis; - animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, 0 ); - animator.GetJointTransform( leftEyeJoint, gameLocal.time, pos, axis ); - animator.ClearAllAnims( gameLocal.time, 0 ); - animator.ForceUpdate(); - eyeOffset = pos + modelOffset; - } else { - // just base it off the bounding box size - eyeOffset.z = GetPhysics()->GetBounds()[ 1 ].z - 6; - } - } - headAnim.Init( this, &animator, ANIMCHANNEL_HEAD ); - } - - waitState = ""; - - torsoAnim.Init( this, &animator, ANIMCHANNEL_TORSO ); - legsAnim.Init( this, &animator, ANIMCHANNEL_LEGS ); -} - -/* -===================== -idActor::CheckBlink -===================== -*/ -void idActor::CheckBlink( void ) { - // check if it's time to blink - if ( !blink_anim || ( health <= 0 ) || !allowEyeFocus || ( blink_time > gameLocal.time ) ) { - return; - } - - idEntity *headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->GetAnimator()->PlayAnim( ANIMCHANNEL_EYELIDS, blink_anim, gameLocal.time, 1 ); - } else { - animator.PlayAnim( ANIMCHANNEL_EYELIDS, blink_anim, gameLocal.time, 1 ); - } - - // set the next blink time - blink_time = gameLocal.time + blink_min + gameLocal.random.RandomInt( blink_max - blink_min ); -} - -/* -================ -idActor::GetPhysicsToVisualTransform -================ -*/ -bool idActor::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { - if ( af.IsActive() ) { - af.GetPhysicsToVisualTransform( origin, axis ); - return true; - } - origin = modelOffset; - axis = viewAxis; - return true; -} - -/* -================ -idActor::GetPhysicsToSoundTransform -================ -*/ -bool idActor::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { - if ( soundJoint != INVALID_JOINT ) { - animator.GetJointTransform( soundJoint, gameLocal.time, origin, axis ); - origin += modelOffset; - axis = viewAxis; - } else { - origin = GetPhysics()->GetGravityNormal() * -eyeOffset.z; - axis.Identity(); - } - return true; -} - -/*********************************************************************** - - script state management - -***********************************************************************/ - -/* -================ -idActor::ShutdownThreads -================ -*/ -void idActor::ShutdownThreads( void ) { - headAnim.Shutdown(); - torsoAnim.Shutdown(); - legsAnim.Shutdown(); - - if ( scriptThread ) { - scriptThread->EndThread(); - scriptThread->PostEventMS( &EV_Remove, 0 ); - delete scriptThread; - scriptThread = NULL; - } -} - -/* -================ -idActor::ShouldConstructScriptObjectAtSpawn - -Called during idEntity::Spawn to see if it should construct the script object or not. -Overridden by subclasses that need to spawn the script object themselves. -================ -*/ -bool idActor::ShouldConstructScriptObjectAtSpawn( void ) const { - return false; -} - -/* -================ -idActor::ConstructScriptObject - -Called during idEntity::Spawn. Calls the constructor on the script object. -Can be overridden by subclasses when a thread doesn't need to be allocated. -================ -*/ -idThread *idActor::ConstructScriptObject( void ) { - const function_t *constructor; - - // make sure we have a scriptObject - if ( !scriptObject.HasObject() ) { - gameLocal.Error( "No scriptobject set on '%s'. Check the '%s' entityDef.", name.c_str(), GetEntityDefName() ); - } - - if ( !scriptThread ) { - // create script thread - scriptThread = new idThread(); - scriptThread->ManualDelete(); - scriptThread->ManualControl(); - scriptThread->SetThreadName( name.c_str() ); - } else { - scriptThread->EndThread(); - } - - // call script object's constructor - constructor = scriptObject.GetConstructor(); - if ( !constructor ) { - gameLocal.Error( "Missing constructor on '%s' for entity '%s'", scriptObject.GetTypeName(), name.c_str() ); - } - - // init the script object's data - scriptObject.ClearObject(); - - // just set the current function on the script. we'll execute in the subclasses. - scriptThread->CallFunction( this, constructor, true ); - - return scriptThread; -} - -/* -===================== -idActor::GetScriptFunction -===================== -*/ -const function_t *idActor::GetScriptFunction( const char *funcname ) { - const function_t *func; - - func = scriptObject.GetFunction( funcname ); - if ( !func ) { - scriptThread->Error( "Unknown function '%s' in '%s'", funcname, scriptObject.GetTypeName() ); - } - - return func; -} - -/* -===================== -idActor::SetState -===================== -*/ -void idActor::SetState( const function_t *newState ) { - if ( !newState ) { - gameLocal.Error( "idActor::SetState: Null state" ); - } - - if ( ai_debugScript.GetInteger() == entityNumber ) { - gameLocal.Printf( "%d: %s: State: %s\n", gameLocal.time, name.c_str(), newState->Name() ); - } - - state = newState; - idealState = state; - scriptThread->CallFunction( this, state, true ); -} - -/* -===================== -idActor::SetState -===================== -*/ -void idActor::SetState( const char *statename ) { - const function_t *newState; - - newState = GetScriptFunction( statename ); - SetState( newState ); -} - -/* -===================== -idActor::UpdateScript -===================== -*/ -void idActor::UpdateScript( void ) { - int i; - - if ( ai_debugScript.GetInteger() == entityNumber ) { - scriptThread->EnableDebugInfo(); - } else { - scriptThread->DisableDebugInfo(); - } - - // a series of state changes can happen in a single frame. - // this loop limits them in case we've entered an infinite loop. - for( i = 0; i < 20; i++ ) { - if ( idealState != state ) { - SetState( idealState ); - } - - // don't call script until it's done waiting - if ( scriptThread->IsWaiting() ) { - break; - } - - scriptThread->Execute(); - if ( idealState == state ) { - break; - } - } - - if ( i == 20 ) { - scriptThread->Warning( "idActor::UpdateScript: exited loop to prevent lockup" ); - } -} - -/*********************************************************************** - - vision - -***********************************************************************/ - -/* -===================== -idActor::setFov -===================== -*/ -void idActor::SetFOV( float fovHoriz, float fovVert ) -{ - m_fovDotHoriz = (float) cos( DEG2RAD( fovHoriz * 0.5f ) ); - - // if fovVert not specified (default val of -1), make same as horizontal - if( fovVert == -1 ) - m_fovDotVert = m_fovDotHoriz; - else - m_fovDotVert = (float) cos( DEG2RAD( fovVert * 0.5f) ); -} - -/* -===================== -idActor::SetEyeHeight -===================== -*/ -void idActor::SetEyeHeight( float height ) { - eyeOffset.z = height; -} - -/* -===================== -idActor::EyeHeight -===================== -*/ -float idActor::EyeHeight( void ) const { - return eyeOffset.z; -} - -/* -===================== -idActor::EyeOffset -===================== -*/ -idVec3 idActor::EyeOffset( void ) const { - return GetPhysics()->GetGravityNormal() * -eyeOffset.z; -} - -/* -===================== -idActor::GetEyePosition -===================== -*/ -idVec3 idActor::GetEyePosition( void ) const { - return GetPhysics()->GetOrigin() + ( GetPhysics()->GetGravityNormal() * -eyeOffset.z ); -} - -/* -===================== -idActor::GetViewPos -===================== -*/ -void idActor::GetViewPos( idVec3 &origin, idMat3 &axis ) const { - origin = GetEyePosition(); - axis = viewAxis; -} - -/* -===================== -idActor::CheckFOV -===================== -*/ -bool idActor::CheckFOV( const idVec3 &pos ) const -{ - //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("idActor::CheckFOV was called\r"); - - if ( m_fovDotHoriz == 1.0f ) { - return true; - } - - float dot; - idVec3 delta; - - delta = pos - GetEyePosition(); - - // get our gravity normal - const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); - - // infinite vertical vision, so project it onto our orientation plane - delta -= gravityDir * ( gravityDir * delta ); - - delta.Normalize(); - dot = viewAxis[ 0 ] * delta; - - return ( dot >= m_fovDotHoriz ); -} - -/* -===================== -idActor::CanSee -===================== -*/ -bool idActor::CanSee( idEntity *ent, bool useFov ) const -{ - // TDM: We need to be able to see lights that are off and hence hidden - /*if ( ent->IsHidden() ) - { - return false; - }*/ - - // The entity's origin - - // grayman #2861 - in the case of doors, use the 'closed origin' and not the 'origin' - - idVec3 origin; - if ( ent->IsType(CBinaryFrobMover::Type) ) - { - CBinaryFrobMover* door = static_cast(ent); - origin = door->GetClosedOrigin(); - } - else - { - origin = ent->GetPhysics()->GetOrigin(); - } - - const idVec3& entityOrigin = origin; - - // Check the field of view if specified - if (useFov && !CheckFOV(entityOrigin)) - { - // FOV check failed - return false; - } - - // This will hold the results of the traces - trace_t result; - - // eye position of the AI - idVec3 eye(GetEyePosition()); - - // angua: If the target entity is an idActor, - // use its eyeposition, the origin and the shoulders - if (ent->IsType(idActor::Type)) - { - idActor* actor = static_cast(ent); - idVec3 entityEyePos = actor->GetEyePosition(); - - if (!gameLocal.clip.TracePoint(result, eye, entityEyePos, MASK_OPAQUE, this) || - gameLocal.GetTraceEntity(result) == actor) - { - // Eye to eye trace succeeded - // gameRenderWorld->DebugArrow(colorGreen,eye, entityEyePos, 1, 32); - return true; - } - else if (!gameLocal.clip.TracePoint(result, eye, entityOrigin, MASK_OPAQUE, this) || - gameLocal.GetTraceEntity(result) == actor) - { - // Eye to origin trace succeeded - // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin, 1, 32); - return true; - } - else - { - idVec3 origin; - idMat3 viewaxis; - actor->GetViewPos(origin, viewaxis); - - const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); - idVec3 dir = (viewaxis[0] - gravityDir * ( gravityDir * viewaxis[0] )).Cross(gravityDir); - - float dist = 8; - - if (!gameLocal.clip.TracePoint(result, eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, MASK_OPAQUE, this) - || gameLocal.GetTraceEntity(result) == actor - || !gameLocal.clip.TracePoint(result, eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, MASK_OPAQUE, this) - || gameLocal.GetTraceEntity(result) == actor) - { - // Eye to shoulders traces succeeded - // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f + dir * dist, 1, 32); - // gameRenderWorld->DebugArrow(colorGreen,eye, entityOrigin + (entityEyePos - entityOrigin)*0.7f - dir * dist, 1, 32); - return true; - } - } - } - // otherwise just use the origin (for general entities). - // Perform a trace from the eye position to the target entity - // TracePoint will return FALSE, when the trace.result is >= 1 - else - { - if (!gameLocal.clip.TracePoint(result, eye, entityOrigin, MASK_OPAQUE, this) || - gameLocal.GetTraceEntity(result) == ent) - { - // Trace succeeded or hit the target entity itself - return true; - } - - // grayman #2603 - We can't see the entity itself. If we're trying to see a light source, - // however, it might be embedded in a candle and/or a candle holder. - // So we have to look up the chain of bindmasters, and if we can see any of them, we'll take it - // that we can see the light source itself. - - if (ent->IsType(idLight::Type)) - { - idEntity* bindMaster = ent->GetBindMaster(); - while (bindMaster != NULL) // exit when bindMaster == NULL or we can see one of them - { - const idVec3& bindMasterOrigin = bindMaster->GetPhysics()->GetOrigin(); - - if (!gameLocal.clip.TracePoint(result, eye, bindMasterOrigin, MASK_OPAQUE, this) || - gameLocal.GetTraceEntity(result) == bindMaster) - { - // Trace succeeded or hit the target entity itself - return true; - } - bindMaster = bindMaster->GetBindMaster(); // go up the hierarchy - } - } - else if ( ent->IsType(CAbsenceMarker::Type) ) // grayman #2860 - { - // We're trying to see an absence marker and can't. Check for the case where the missing item - // was replaced by another item. For example, a lootable painting replaced by an empty frame. - // If a replacement item is present, is that what the trace hit? If so, the trace was successful. - - CAbsenceMarker* marker = static_cast(ent); - const idDict& refSpawnargs = marker->GetRefSpawnargs(); - idStr replacedByClass = refSpawnargs.GetString("replace"); - if ( !replacedByClass.IsEmpty() ) - { - idEntity* entHit = gameLocal.GetTraceEntity(result); // the trace hit this - if ( entHit != NULL ) - { - if ( idStr::Icmp( entHit->spawnArgs.GetString("classname"),replacedByClass ) == 0 ) - { - return true; // we hit the replacement item, which means a successful trace - } - } - } - } - } - - return false; -} - -/* -===================== -idActor::PointVisible -===================== -*/ -bool idActor::PointVisible( const idVec3 &point ) const { - trace_t results; - idVec3 start, end; - - start = GetEyePosition(); - end = point; - end[2] += 1.0f; - - gameLocal.clip.TracePoint( results, start, end, MASK_OPAQUE, this ); - return ( results.fraction >= 1.0f ); -} - -/* -===================== -idActor::GetAIAimTargets - -Returns positions for the AI to aim at. -===================== -*/ -void idActor::GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ) { - headPos = lastSightPos + EyeOffset(); - chestPos = ( headPos + lastSightPos + GetPhysics()->GetBounds().GetCenter() ) * 0.5f; -} - -/* -===================== -idActor::GetRenderView -===================== -*/ -renderView_t *idActor::GetRenderView() { - renderView_t *rv = idEntity::GetRenderView(); - rv->viewaxis = viewAxis; - rv->vieworg = GetEyePosition(); - return rv; -} - -/*********************************************************************** - - Model/Ragdoll - -***********************************************************************/ - -/* -================ -idActor::SetCombatModel -================ -*/ -void idActor::SetCombatModel( void ) { - idAFAttachment *headEnt; - - if ( !use_combat_bbox ) { - if ( combatModel ) { - combatModel->Unlink(); - combatModel->LoadModel( modelDefHandle ); - } else { - combatModel = new idClipModel( modelDefHandle ); - } - - headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->SetCombatModel(); - } - } -} - -/* -================ -idActor::GetCombatModel -================ -*/ -idClipModel *idActor::GetCombatModel( void ) const { - return combatModel; -} - -/* -================ -idActor::LinkCombat -================ -*/ -void idActor::LinkCombat( void ) { - idAFAttachment *headEnt; - - if ( fl.hidden || use_combat_bbox ) { - return; - } - - if ( combatModel ) { - combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); - } - headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->LinkCombat(); - } -} - -/* -================ -idActor::UnlinkCombat -================ -*/ -void idActor::UnlinkCombat( void ) { - idAFAttachment *headEnt; - - if ( combatModel != NULL ) { - combatModel->Unlink(); - } - headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->UnlinkCombat(); - } -} - -/* -================ -idActor::StartRagdoll -================ -*/ -bool idActor::StartRagdoll( void ) { - float slomoStart, slomoEnd; - float jointFrictionDent, jointFrictionDentStart, jointFrictionDentEnd; - float contactFrictionDent, contactFrictionDentStart, contactFrictionDentEnd; - - // if no AF loaded - if ( !af.IsLoaded() ) { - return false; - } - - // if the AF is already active - if ( af.IsActive() ) { - return true; - } - - // disable the monster bounding box - if (spawnArgs.GetBool("nonsolid_on_ragdoll", "1")) - { - GetPhysics()->DisableClip(); - } - - // ishtvan: Establish AF constraints for any AF bodies of bound entities - UpdateAddedEntConstraints(); - - // start using the AF - af.StartFromCurrentPose( spawnArgs.GetInt( "velocityTime", "0" ) ); - - slomoStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_slomoStart", "-1.6" ); - slomoEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_slomoEnd", "0.8" ); - - // do the first part of the death in slow motion - af.GetPhysics()->SetTimeScaleRamp( slomoStart, slomoEnd ); - - jointFrictionDent = spawnArgs.GetFloat( "ragdoll_jointFrictionDent", "0.1" ); - jointFrictionDentStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_jointFrictionStart", "0.2" ); - jointFrictionDentEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_jointFrictionEnd", "1.2" ); - - // set joint friction dent - af.GetPhysics()->SetJointFrictionDent( jointFrictionDent, jointFrictionDentStart, jointFrictionDentEnd ); - - contactFrictionDent = spawnArgs.GetFloat( "ragdoll_contactFrictionDent", "0.1" ); - contactFrictionDentStart = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_contactFrictionStart", "1.0" ); - contactFrictionDentEnd = MS2SEC( gameLocal.time ) + spawnArgs.GetFloat( "ragdoll_contactFrictionEnd", "2.0" ); - - // set contact friction dent - af.GetPhysics()->SetContactFrictionDent( contactFrictionDent, contactFrictionDentStart, contactFrictionDentEnd ); - - // drop any items the actor is holding - idMoveableItem::DropItems( this, "death", NULL ); - - // drop any articulated figures the actor is holding - idAFEntity_Base::DropAFs( this, "death", NULL ); - - RemoveAttachments(); - - return true; -} - -/* -================ -idActor::StopRagdoll -================ -*/ -void idActor::StopRagdoll( void ) { - if ( af.IsActive() ) { - af.Stop(); - } -} - -/* -================ -idActor::UpdateAnimationControllers -================ -*/ -bool idActor::UpdateAnimationControllers( void ) { - - if ( af.IsActive() ) { - return idAFEntity_Base::UpdateAnimationControllers(); - } else { - animator.ClearAFPose(); - } - - if ( walkIK.IsInitialized() ) { - walkIK.Evaluate(); - return true; - } - - return false; -} - -/* -================ -idActor::RemoveAttachments -================ -*/ -void idActor::RemoveAttachments( void ) -{ - int i; - idEntity *ent; - - // remove any attached entities - for( i = 0; i < m_Attachments.Num(); i++ ) { - ent = m_Attachments[ i ].ent.GetEntity(); - if ( ent && ent->spawnArgs.GetBool( "remove" ) ) { - ent->PostEventMS( &EV_SafeRemove, 0 ); - } - } -} - -/* -================ -idActor::Attach -================ -*/ -void idActor::Attach( idEntity *ent, const char *PosName, const char *AttName ) -{ - idAnimatedEntity::Attach( ent, PosName, AttName ); - - // If the ent we're attaching is an AFAttachment, call SetBody to set up damage propagation, physics propagation, etc. - // NOTE: We read ent->GetBindJoint here, assuming the bind went okay. - if( ent->IsType(idAFAttachment::Type) ) - { - // TODO: Is this line correct? Won't know until we test. - idStr modelName = ent->spawnArgs.GetString("model",""); - static_cast(ent)->SetBody( this, modelName.c_str(), ent->GetBindJoint() ); - } - - // check various spawnargs for special behaviors on attaching (not frobable, contents corpse, etc) - if( ent->spawnArgs.GetBool("on_attach_contents_corpse") ) - { - // clear solid contents, set corpse contents - int oldContents = ent->GetPhysics()->GetContents(); - ent->GetPhysics()->SetContents( (oldContents & ~CONTENTS_SOLID) | CONTENTS_CORPSE ); - } - if( ent->spawnArgs.GetBool("on_attach_nonsolid") ) - { - // clear solid and corpse contents - int oldContents = ent->GetPhysics()->GetContents(); - ent->GetPhysics()->SetContents( (oldContents & ~CONTENTS_SOLID) & ~CONTENTS_CORPSE ); - } - if( ent->spawnArgs.GetBool("on_attach_not_frobable") ) - ent->SetFrobable(false); - - - if( ent->IsType(CMeleeWeapon::Type) ) - { - static_cast(ent)->AttachedToActor( this ); - } -} - -/* -================ -idActor::BindNotify -================ -*/ -void idActor::BindNotify( idEntity *ent ) -{ - idAFEntity_Base::BindNotify(ent); - - // Override our animations based on the bound entity's replace_anim_* spawnargs - LoadReplacementAnims(ent->spawnArgs); -} - -/* -================ -idActor::UnbindNotify -================ -*/ -void idActor::UnbindNotify( idEntity *ent ) -{ - idAFEntity_Base::UnbindNotify(ent); - - // Remove animation overrides - const idKeyValue *KeyVal = ent->spawnArgs.MatchPrefix( "replace_anim_", NULL ); - while ( KeyVal ) - { - idStr key = KeyVal->GetKey(); - key.StripLeadingOnce("replace_anim_"); - - if (strcmp(m_replacementAnims.GetString( key ), KeyVal->GetValue().c_str()) == 0 ) - { - // This animation override is present, so remove it - //gameLocal.Warning( "idActor: Removing replacement animation %s", KeyVal->GetValue().c_str() ); - m_replacementAnims.Delete( key ); - } - - KeyVal = ent->spawnArgs.MatchPrefix( "replace_anim_", KeyVal ); - } - - // angua: remove from attachments - for (int i = 0; i < m_Attachments.Num(); i++) - { - idEntity* attachment = m_Attachments[i].ent.GetEntity(); - - if (attachment != NULL && attachment->name == ent->name) - { - m_Attachments[i].ent = NULL; - } - } -} - -/* -================ -idActor::Teleport -================ -*/ -void idActor::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { - - GetPhysics()->SetLinearVelocity( vec3_origin ); - if (destination == NULL) - { - GetPhysics()->SetOrigin( origin + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - viewAxis = angles.ToMat3(); - } - else - { - GetPhysics()->SetOrigin( destination->GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - viewAxis = destination->GetPhysics()->GetAxis(); - } - - UpdateVisuals(); - - if ( !IsHidden() ) { - // kill anything at the new position - gameLocal.KillBox( this ); - } -} - -/* -================ -idActor::GetDeltaViewAngles -================ -*/ -const idAngles &idActor::GetDeltaViewAngles( void ) const { - return deltaViewAngles; -} - -/* -================ -idActor::SetDeltaViewAngles -================ -*/ -void idActor::SetDeltaViewAngles( const idAngles &delta ) { - deltaViewAngles = delta; -} - -/* -================ -idActor::HasEnemies -================ -*/ -bool idActor::HasEnemies( void ) const { - idActor *ent; - - for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - if ( !ent->fl.hidden ) { - return true; - } - } - - return false; -} - -/* -================ -idActor::ClosestEnemyToPoint -================ -*/ -idActor *idActor::ClosestEnemyToPoint( const idVec3 &pos ) { - idActor *ent; - idActor *bestEnt; - float bestDistSquared; - float distSquared; - idVec3 delta; - - bestDistSquared = idMath::INFINITY; - bestEnt = NULL; - for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - if ( ent->fl.hidden ) { - continue; - } - delta = ent->GetPhysics()->GetOrigin() - pos; - distSquared = delta.LengthSqr(); - if ( distSquared < bestDistSquared ) { - bestEnt = ent; - bestDistSquared = distSquared; - } - } - - return bestEnt; -} - -/* -================ -idActor::EnemyWithMostHealth -================ -*/ -idActor *idActor::EnemyWithMostHealth() { - idActor *ent; - idActor *bestEnt; - - int most = -9999; - bestEnt = NULL; - for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - if ( !ent->fl.hidden && ( ent->health > most ) ) { - bestEnt = ent; - most = ent->health; - } - } - return bestEnt; -} - -/* -================ -idActor::ClosestAttackingEnemy -================ -*/ -idActor *idActor::ClosestAttackingEnemy( bool bUseFOV ) -{ - idActor *ent(NULL); - idActor *bestEnt(NULL); - float bestDistSquared(idMath::INFINITY); - float distSquared(0.0f); - idVec3 delta; - - for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) - { - if ( ent->fl.hidden ) - continue; - - CMeleeStatus *pStatus = &ent->m_MeleeStatus; - // TODO: Differentiate between phases of the action state, holding attack, etc? - if ( !(pStatus->m_ActionState == MELEEACTION_ATTACK) ) - continue; - - idVec3 entOrigin = ent->GetPhysics()->GetOrigin(); - delta = entOrigin - GetPhysics()->GetOrigin(); - distSquared = delta.LengthSqr(); - - // check FOV, using idActor version which only checks horizontal angle - if( bUseFOV && !idActor::CheckFOV( entOrigin) ) - { - continue; - } - - if ( distSquared < bestDistSquared ) - { - bestEnt = ent; - bestDistSquared = distSquared; - } - } - - return bestEnt; -} - -/* -================ -idActor::GetBestParry -================ -*/ -EMeleeType idActor::GetBestParry( void ) -{ - idActor *AttEnemy; - EMeleeType ParryType; - - if( m_MeleeStatus.m_bCanParryAll ) - ParryType = MELEETYPE_BLOCKALL; - else if( (AttEnemy = ClosestAttackingEnemy( true )) != NULL - && AttEnemy->m_MeleeStatus.m_ActionType != MELEETYPE_UNBLOCKABLE ) - { - ParryType = AttEnemy->m_MeleeStatus.m_ActionType; - } - else - ParryType = MELEETYPE_RL; - - return ParryType; -} - -/* -================ -idActor::OnLadder -================ -*/ -bool idActor::OnLadder( void ) const { - return false; -} - -CMultiStateMover* idActor::OnElevator(bool mustBeMoving) const -{ - return NULL; -} - -/* -============== -idActor::GetAASLocation -============== -*/ -void idActor::GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const { - idVec3 size; - idBounds bounds; - - GetFloorPos( 64.0f, pos ); - if ( !aas ) { - areaNum = 0; - return; - } - - size = aas->GetSettings()->boundingBoxes[0][1]; - bounds[0] = -size; - size.z = 32.0f; - bounds[1] = size; - - areaNum = aas->PointReachableAreaNum( pos, bounds, AREA_REACHABLE_WALK ); - if ( areaNum ) { - aas->PushPointIntoAreaNum( areaNum, pos ); - } -} - -/*********************************************************************** - - animation state - -***********************************************************************/ - -/* -===================== -idActor::SetAnimState -===================== -*/ -void idActor::SetAnimState( int channel, const char *statename, int blendFrames ) { - const function_t *func; - - // greebo: Try to lookup the script function of this animstate - func = scriptObject.GetFunction( statename ); - if ( !func ) { -// assert( 0 ); // greebo: don't just crash, a missing script function can happen... - gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); - } - - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.SetState( statename, blendFrames ); - allowEyeFocus = true; - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.SetState( statename, blendFrames ); - legsAnim.Enable( blendFrames ); - allowPain = true; - allowEyeFocus = true; - break; - - case ANIMCHANNEL_LEGS : - legsAnim.SetState( statename, blendFrames ); - torsoAnim.Enable( blendFrames ); - allowPain = true; - allowEyeFocus = true; - break; - - default: - gameLocal.Error( "idActor::SetAnimState: Unknown anim group" ); - break; - } -} - -/* -===================== -idActor::GetAnimState -===================== -*/ -const char *idActor::GetAnimState( int channel ) const { - switch( channel ) { - case ANIMCHANNEL_HEAD : - return headAnim.state; - break; - - case ANIMCHANNEL_TORSO : - return torsoAnim.state; - break; - - case ANIMCHANNEL_LEGS : - return legsAnim.state; - break; - - default: - gameLocal.Error( "idActor::GetAnimState: Unknown anim group" ); - return NULL; - break; - } -} - -/* -===================== -idActor::InAnimState -===================== -*/ -bool idActor::InAnimState( int channel, const char *statename ) const { - switch( channel ) { - case ANIMCHANNEL_HEAD : - if ( headAnim.state == statename ) { - return true; - } - break; - - case ANIMCHANNEL_TORSO : - if ( torsoAnim.state == statename ) { - return true; - } - break; - - case ANIMCHANNEL_LEGS : - if ( legsAnim.state == statename ) { - return true; - } - break; - - default: - gameLocal.Error( "idActor::InAnimState: Unknown anim group" ); - break; - } - - return false; -} - -/* -===================== -idActor::WaitState -===================== -*/ -const char *idActor::WaitState( void ) const { - if ( waitState.Length() ) { - return waitState; - } else { - return NULL; - } -} - - -const char *idActor::WaitState( int channel ) const -{ - switch( channel ) - { - case ANIMCHANNEL_HEAD : - return headAnim.WaitState(); - break; - - case ANIMCHANNEL_TORSO : - return torsoAnim.WaitState(); - break; - - case ANIMCHANNEL_LEGS : - return legsAnim.WaitState(); - break; - - default: - gameLocal.Error( "idActor::WaitState: Unknown anim group" ); - break; - } - - return NULL; -} - - - -/* -===================== -idActor::SetWaitState -===================== -*/ -void idActor::SetWaitState( const char *_waitstate ) { - waitState = _waitstate; -} - -void idActor::SetWaitState(int channel, const char *_waitstate) -{ - switch( channel ) - { - case ANIMCHANNEL_HEAD : - headAnim.SetWaitState(_waitstate); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.SetWaitState(_waitstate); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.SetWaitState(_waitstate); - break; - - default: - gameLocal.Error( "idActor::SetWaitState: Unknown anim group" ); - break; - } - -} - -/* -===================== -idActor::UpdateAnimState -===================== -*/ -void idActor::UpdateAnimState( void ) { - headAnim.UpdateState(); - torsoAnim.UpdateState(); - legsAnim.UpdateState(); -} - -/* -===================== -idActor::GetAnim -===================== -*/ -int idActor::GetAnim( int channel, const char *animname ) { - int anim; - const char *temp; - idAnimator *animatorPtr; - - if ( channel == ANIMCHANNEL_HEAD ) { - if ( !head.GetEntity() ) { - return 0; - } - animatorPtr = head.GetEntity()->GetAnimator(); - } else { - animatorPtr = &animator; - } - - if ( animPrefix.Length() ) - { - temp = va( "%s_%s", animPrefix.c_str(), animname ); - - const char* replacement = LookupReplacementAnim( temp ); - - if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer() && idStr::Cmp(replacement, temp) != 0) - { - gameLocal.Printf("Frame: %d - replacing %s with %s\n", gameLocal.framenum, animname, replacement); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - replacing %s with %s\r", gameLocal.framenum, animname, replacement); - } - - anim = animatorPtr->GetAnim( replacement ); - if (!anim) anim = animatorPtr->GetAnim( temp ); - if (anim) { - return anim; - } - } - - const char* replacement = LookupReplacementAnim( animname ); - - if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer() && idStr::Cmp(replacement, animname) != 0) - { - gameLocal.Printf("Frame: %d - replacing %s with %s\n", gameLocal.framenum, animname, replacement); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - replacing %s with %s\r", gameLocal.framenum, animname, replacement); - } - - anim = animatorPtr->GetAnim( replacement ); - if (!anim) anim = animatorPtr->GetAnim( animname ); - - return anim; -} - -idAnimator* idActor::GetAnimatorForChannel(int channel) -{ - switch (channel) - { - case ANIMCHANNEL_HEAD : - if (head.GetEntity() == NULL) - { - return headAnim.GetAnimator(); - } - return head.GetEntity()->GetAnimator(); - break; - - case ANIMCHANNEL_TORSO : - return torsoAnim.GetAnimator(); - break; - - case ANIMCHANNEL_LEGS : - return legsAnim.GetAnimator(); - break; - - default: - gameLocal.Error("GetAnimatorForChannel: Unknown anim group"); - break; - }; - - return NULL; -} - -/* -===================== -idActor::LookupReplacementAnim -(TDM) -===================== -*/ -const char* idActor::LookupReplacementAnim( const char *animname ) -{ - // Recursively lookup the animation to find its replacement animation - const char* replacement = animname; - int tries = 0; // Infinite loop prevention counter - - while ( m_replacementAnims.FindKey( replacement ) ) - { - replacement = m_replacementAnims.GetString( replacement ); - - // Avoid infinite loops - tries++; - if (tries > 500) - { - gameLocal.Warning("Infinite loop detected in replacements for animation '%s' applied to actor '%s'\n", - animname, this->name.c_str()); - break; - } - } - - return replacement; -} - -void idActor::LoadReplacementAnims(const idDict& spawnArgs) -{ - for (const idKeyValue* kv = spawnArgs.MatchPrefix("replace_anim_", NULL); - kv != NULL; kv = spawnArgs.MatchPrefix("replace_anim_", kv)) - { - idStr key = kv->GetKey(); - key.StripLeadingOnce("replace_anim_"); - - SetReplacementAnim(key, kv->GetValue()); - } -} - -void idActor::SetReplacementAnim(const idStr& animToReplace, const idStr& replacementAnim) -{ - m_replacementAnims.Set(animToReplace, replacementAnim); -} - -void idActor::RemoveReplacementAnim(const idStr& replacedAnim) -{ - m_replacementAnims.Delete(replacedAnim); -} - -void idActor::StopAnim(int channel, int frames) -{ - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.StopAnim( frames ); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.StopAnim( frames ); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.StopAnim( frames ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - -/* -=============== -idActor::SyncAnimChannels -=============== -*/ -void idActor::SyncAnimChannels( int channel, int syncToChannel, int blendFrames ) { - idAnimator *headAnimator; - idAFAttachment *headEnt; - int anim; - idAnimBlend *syncAnim; - int starttime; - int blendTime; - int cycle; - - blendTime = FRAME2MS( blendFrames ); - if ( channel == ANIMCHANNEL_HEAD ) { - headEnt = head.GetEntity(); - if ( headEnt ) { - headAnimator = headEnt->GetAnimator(); - syncAnim = animator.CurrentAnim( syncToChannel ); - if ( syncAnim ) { - anim = headAnimator->GetAnim( syncAnim->AnimFullName() ); - if ( !anim ) { - anim = headAnimator->GetAnim( syncAnim->AnimName() ); - } - if ( anim ) { - cycle = animator.CurrentAnim( syncToChannel )->GetCycleCount(); - starttime = animator.CurrentAnim( syncToChannel )->GetStartTime(); - headAnimator->PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, blendTime ); - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->SetStartTime( starttime ); - } else { - headEnt->PlayIdleAnim( blendTime ); - } - } - } - } else if ( syncToChannel == ANIMCHANNEL_HEAD ) { - headEnt = head.GetEntity(); - if ( headEnt ) { - headAnimator = headEnt->GetAnimator(); - syncAnim = headAnimator->CurrentAnim( ANIMCHANNEL_ALL ); - if ( syncAnim ) { - anim = GetAnim( channel, syncAnim->AnimFullName() ); - if ( !anim ) { - anim = GetAnim( channel, syncAnim->AnimName() ); - } - if ( anim ) { - cycle = headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetCycleCount(); - starttime = headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime(); - animator.PlayAnim( channel, anim, gameLocal.time, blendTime ); - animator.CurrentAnim( channel )->SetCycleCount( cycle ); - animator.CurrentAnim( channel )->SetStartTime( starttime ); - } - } - } - } else { - animator.SyncAnimChannels( channel, syncToChannel, gameLocal.time, blendTime ); - } -} - -/*********************************************************************** - - Damage - -***********************************************************************/ - -/* -============ -idActor::Gib -============ -*/ -void idActor::Gib( const idVec3 &dir, const char *damageDefName ) { - // no gibbing in multiplayer - by self damage or by moving objects - if ( gameLocal.isMultiplayer ) { - return; - } - // only gib once - if ( gibbed ) { - return; - } - idAFEntity_Gibbable::Gib( dir, damageDefName ); - if ( head.GetEntity() ) { - head.GetEntity()->Hide(); - } - StopSound( SND_CHANNEL_VOICE, false ); -} - - -/* -============ -idActor::Damage - -this entity that is being damaged -inflictor entity that is causing the damage -attacker entity that caused the inflictor to damage targ - example: this=monster, inflictor=rocket, attacker=player - -dir direction of the attack for knockback in global space -point point at which the damage is being inflicted, used for headshots -damage amount of damage being inflicted - -collision trace info for the collision that caused the damage. Defaults to NULL. - -inflictor, attacker, dir, and point can be NULL for environmental effects - -Bleeding wounds and surface overlays are applied in the collision code that -calls Damage() -============ -*/ -void idActor::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision ) -{ - if (collision != NULL) - { - int bodID = BodyForClipModelId( collision->c.id ); - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Fun is trying to call getBody with bodyID %d\r", bodID ); - idAFBody* StruckBody = GetAFPhysics()->GetBody( bodID ); - - if( StruckBody != NULL ) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Struck body %s\r",StruckBody->GetName().c_str()); - idEntity* reroute = StruckBody->GetRerouteEnt(); - if (reroute != NULL) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Rerouting damage from the AF of entity %s to bound entity %s\r",name.c_str(), reroute->name.c_str()); - // TODO: Technically location is wrong here, it's a joint that's not on the reroute entity (not sure if it will matter) - reroute->Damage( inflictor, attacker, dir, damageDefName, damageScale, location, collision ); - return; - } - } - } - - if ( !fl.takedamage ) { - return; - } - - // grayman #2478 - why take more damage if you're already dead? - - if (health <= 0) - { - return; - } - - if ( !inflictor ) { - inflictor = gameLocal.world; - } - if ( !attacker ) { - attacker = gameLocal.world; - } - - // Try to find the damage entityDef - const idDict* damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) { - gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); - } - - // Get the damage amount - int damage = static_cast(damageDef->GetInt( "damage" ) * damageScale); - - damage = GetDamageForLocation( damage, location ); - - // apply stealth damage multiplier - only active for derived AI class - damage *= StealthDamageMult(); - - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Actor %s received damage %d at joint %d, corresponding to damage group %s\r", name.c_str(), damage, (int) location, GetDamageGroup(location) ); - - // inform the attacker that they hit someone - attacker->DamageFeedback( this, inflictor, damage ); - - // DarkMod: check for KO damage type and knockout AI if appropriate - bool bKO = damageDef->GetBool( "knockout" ); - bool bKOPowerBlow = damageDef->GetBool( "knockout_power" ); - - if( (bKO || bKOPowerBlow) && collision ) - { - if( TestKnockoutBlow( attacker, dir, collision, location, bKOPowerBlow ) ) - { - // For now, first KO blow does no health damage - damage = 0; - } - } - - if ( damage > 0 ) - { - // Apply the damage - health -= damage; - - if (lowHealthThreshold != -1 && health <= lowHealthThreshold) - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s's fell below health threshold %d, firing script %s\r", name.c_str(), lowHealthThreshold, lowHealthScript.c_str()); - - if (!lowHealthScript.IsEmpty()) - { - CallScriptFunctionArgs(lowHealthScript, true, 0, "e", this); - } - } - - if ( health <= 0 ) - { - if ( health < -999 ) - { - health = -999; - } - Killed( inflictor, attacker, damage, dir, location ); - if ( ( health < -20 ) && spawnArgs.GetBool( "gib" ) && damageDef->GetBool( "gib" ) ) - { - Gib( dir, damageDefName ); - } - } - else - { - Pain( inflictor, attacker, damage, dir, location, damageDef ); - - // FIX: if drowning, stop pain SFX and play drown SFX on voice channel - if ( damageDef->GetBool( "no_air" ) ) - { - StopSound( SND_CHANNEL_VOICE, false ); - SetSoundVolume(-10); // grayman #1488 - less volume underwater - StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); - } - } - } - // Ishtvan: Try commenting this out, it doesn't make sense to ignore nonzero "push" in the DmgDef just - // because the attack happens to hit armor and do no damage... - // Cleary Id was trying to fix something here, but I'm not sure what -/* - else - { - // Ishtvan: THIS IS WHAT'S CAUSING PLATE ARMOR HITS NOT TO MOVE AI... WHY DID ID DO THIS? - - // don't accumulate knockback - if ( af.IsLoaded() ) - { - // clear impacts - af.Rest(); - - // physics is turned off by calling af.Rest() - BecomeActive( TH_PHYSICS ); - } - } -*/ -} - -/* -===================== -idActor::ClearPain -===================== -*/ -void idActor::ClearPain( void ) { - pain_debounce_time = 0; -} - -/* -===================== -idActor::Pain -===================== -*/ -bool idActor::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ) { - if ( af.IsLoaded() && !IsKnockedOut() ) { - // clear impacts - af.Rest(); - - // physics is turned off by calling af.Rest() - BecomeActive( TH_PHYSICS ); - } - - if ( gameLocal.time < pain_debounce_time ) { - return false; - } - - // don't play pain sounds more than necessary - pain_debounce_time = gameLocal.time + pain_delay; - - if (damageDef != NULL && damageDef->FindKey("snd_damage") != NULL) - { - // The damage def defines a special damage sound, use that one - // Copy it into our own spawnargs for use with StartSound() routine - spawnArgs.Set("snd_damage_internal___", damageDef->GetString("snd_damage")); - - StartSound( "snd_damage_internal___", SND_CHANNEL_VOICE, 0, false, NULL ); - } - else - { - // Ordinary health-based pain sound - if ( health > 75 ) { - StartSound( "snd_pain_small", SND_CHANNEL_VOICE, 0, false, NULL ); - } else if ( health > 50 ) { - StartSound( "snd_pain_medium", SND_CHANNEL_VOICE, 0, false, NULL ); - } else if ( health > 25 ) { - StartSound( "snd_pain_large", SND_CHANNEL_VOICE, 0, false, NULL ); - } else { - StartSound( "snd_pain_huge", SND_CHANNEL_VOICE, 0, false, NULL ); - } - } - - if ( !allowPain || ( gameLocal.time < painTime ) ) { - // don't play a pain anim - return false; - } - - if ( pain_threshold && ( damage < pain_threshold ) ) { - return false; - } - - // set the pain anim - idStr damageGroup = GetDamageGroup( location ); - - painAnim = ""; - if ( animPrefix.Length() ) { - if ( damageGroup.Length() && ( damageGroup != "legs" ) ) { - sprintf( painAnim, "%s_pain_%s", animPrefix.c_str(), damageGroup.c_str() ); - if ( !animator.HasAnim( painAnim ) ) { - sprintf( painAnim, "pain_%s", damageGroup.c_str() ); - if ( !animator.HasAnim( painAnim ) ) { - painAnim = ""; - } - } - } - - if ( !painAnim.Length() ) { - sprintf( painAnim, "%s_pain", animPrefix.c_str() ); - if ( !animator.HasAnim( painAnim ) ) { - painAnim = ""; - } - } - } else if ( damageGroup.Length() && ( damageGroup != "legs" ) ) { - sprintf( painAnim, "pain_%s", damageGroup.c_str() ); - if ( !animator.HasAnim( painAnim ) ) { - sprintf( painAnim, "pain_%s", damageGroup.c_str() ); - if ( !animator.HasAnim( painAnim ) ) { - painAnim = ""; - } - } - } - - if ( !painAnim.Length() ) { - painAnim = "pain"; - } - - if ( g_debugDamage.GetBool() ) { - gameLocal.Printf( "Damage: joint: '%s', zone '%s', anim '%s'\n", animator.GetJointName( ( jointHandle_t )location ), - damageGroup.c_str(), painAnim.c_str() ); - } - - return true; -} - -void idActor::SetIsPushing(bool isPushing) -{ - // do nothing, is handled by the subclasses -} - -bool idActor::IsPushing() -{ - return false; -} - -/* -===================== -idActor::SpawnGibs -===================== -*/ -void idActor::SpawnGibs( const idVec3 &dir, const char *damageDefName ) { - idAFEntity_Gibbable::SpawnGibs( dir, damageDefName ); - RemoveAttachments(); -} - -/* -===================== -idActor::SetupDamageGroups - -FIXME: only store group names once and store an index for each joint -===================== -*/ -void idActor::SetupDamageGroups( void ) { - int i; - const idKeyValue *arg; - idStr groupname; - idList jointList; - int jointnum; - float scale; - - // create damage zones - damageGroups.SetNum( animator.NumJoints() ); - arg = spawnArgs.MatchPrefix( "damage_zone ", NULL ); - while ( arg ) { - groupname = arg->GetKey(); - groupname.Strip( "damage_zone " ); - animator.GetJointList( arg->GetValue(), jointList ); - for( i = 0; i < jointList.Num(); i++ ) { - jointnum = jointList[ i ]; - damageGroups[ jointnum ] = groupname; - } - jointList.Clear(); - arg = spawnArgs.MatchPrefix( "damage_zone ", arg ); - } - - // initilize the damage zones to normal damage - damageScale.SetNum( animator.NumJoints() ); - for( i = 0; i < damageScale.Num(); i++ ) { - damageScale[ i ] = 1.0f; - } - - // set the percentage on damage zones - arg = spawnArgs.MatchPrefix( "damage_scale ", NULL ); - while ( arg ) { - scale = atof( arg->GetValue() ); - groupname = arg->GetKey(); - groupname.Strip( "damage_scale " ); - for( i = 0; i < damageScale.Num(); i++ ) { - if ( damageGroups[ i ] == groupname ) { - damageScale[ i ] = scale; - } - } - arg = spawnArgs.MatchPrefix( "damage_scale ", arg ); - } -} - -/* -===================== -idActor::GetDamageForLocation -===================== -*/ -int idActor::GetDamageForLocation( int damage, int location ) { - if ( ( location < 0 ) || ( location >= damageScale.Num() ) ) { - return damage; - } - - return (int)ceil( damage * damageScale[ location ] ); -} - -/* -===================== -idActor::GetDamageGroup -===================== -*/ -const char *idActor::GetDamageGroup( int location ) { - if ( ( location < 0 ) || ( location >= damageGroups.Num() ) ) { - return ""; - } - - return damageGroups[ location ]; -} - -/* -===================== -idActor::PlayFootStepSound -===================== -*/ -void idActor::PlayFootStepSound( void ) -{ - // empty, override this in the subclasses -} - -void idActor::LinkScriptVariables() -{ - // Link the script variables to our script object - AI_DEAD.LinkTo(scriptObject, "AI_DEAD"); -} - -bool idActor::ReEvaluateArea(int areaNum) -{ - // Default implementation for actors: return positive - return true; -} - -void idActor::LoadVocalSet() -{ - // Try to look up the entityDef - idStr vocalSet = spawnArgs.GetString("def_vocal_set"); - - if (vocalSet.IsEmpty()) return; // nothing to do - - const idDeclEntityDef* def = gameLocal.FindEntityDef(vocalSet, false); - - if (def == NULL) - { - gameLocal.Warning("Could not find def_vocal_set %s!", vocalSet.c_str()); - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Could not find def_vocal_set %s!", vocalSet.c_str()); - return; - } - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copying vocal set %s to actor %s", vocalSet.c_str(), name.c_str()); - - int i = 0; - - // Copy all snd_* spawnargs over to this entity - for (const idKeyValue* kv = def->dict.MatchPrefix("snd_"); kv != NULL; kv = def->dict.MatchPrefix("snd_", kv), i++) - { - spawnArgs.Set(kv->GetKey(), kv->GetValue()); - } - - // Copy all sound prop "spr*" spawnargs over to this entity - for (const idKeyValue* kv = def->dict.MatchPrefix("spr"); kv != NULL; kv = def->dict.MatchPrefix("spr", kv), i++) - { - spawnArgs.Set(kv->GetKey(), kv->GetValue()); - } - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copied %d vocal set spawnargs to actor %s", i, name.c_str()); -} - -void idActor::LoadMeleeSet() -{ - idStr MeleeSet = spawnArgs.GetString("def_melee_set"); - if (MeleeSet.IsEmpty()) return; // nothing to do - - // tack on difficulty string - // if we do it this way, def will not be precached, but that's okay for just some numbers? - MeleeSet += va("_%s", cv_melee_difficulty.GetString()); - - const idDeclEntityDef* def = gameLocal.FindEntityDef(MeleeSet, false); - - if (def == NULL) - { - gameLocal.Warning("Could not find def_melee_set %s!", MeleeSet.c_str()); - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Could not find def_melee_set %s!", MeleeSet.c_str()); - return; - } - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Copying melee set %s to actor %s", MeleeSet.c_str(), name.c_str()); - - // Copy ALL spawnargs from melee set over to this entity - spawnArgs.Copy( def->dict ); - - // re-cache the anim rates in case they changed - CacheAnimRates(); -} - -/*********************************************************************** - - Events - -***********************************************************************/ - -/* -===================== -idActor::Event_EnableEyeFocus -===================== -*/ -void idActor::Event_EnableEyeFocus( void ) { - allowEyeFocus = true; - blink_time = gameLocal.time + blink_min + gameLocal.random.RandomInt( blink_max - blink_min ); -} - -/* -===================== -idActor::Event_DisableEyeFocus -===================== -*/ -void idActor::Event_DisableEyeFocus( void ) { - allowEyeFocus = false; - - idEntity *headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->GetAnimator()->Clear( ANIMCHANNEL_EYELIDS, gameLocal.time, FRAME2MS( 2 ) ); - } else { - animator.Clear( ANIMCHANNEL_EYELIDS, gameLocal.time, FRAME2MS( 2 ) ); - } -} - -/* -=============== -idActor::Event_Footstep -=============== -*/ -void idActor::Event_Footstep( void ) { - PlayFootStepSound(); -} - -/* -===================== -idActor::Event_EnableWalkIK -===================== -*/ -void idActor::Event_EnableWalkIK( void ) { - walkIK.EnableAll(); -} - -/* -===================== -idActor::Event_DisableWalkIK -===================== -*/ -void idActor::Event_DisableWalkIK( void ) { - walkIK.DisableAll(); -} - -/* -===================== -idActor::Event_EnableLegIK -===================== -*/ -void idActor::Event_EnableLegIK( int num ) { - walkIK.EnableLeg( num ); -} - -/* -===================== -idActor::Event_DisableLegIK -===================== -*/ -void idActor::Event_DisableLegIK( int num ) { - walkIK.DisableLeg( num ); -} - -/* -===================== -idActor::Event_PreventPain -===================== -*/ -void idActor::Event_PreventPain( float duration ) { - painTime = gameLocal.time + SEC2MS( duration ); -} - -/* -=============== -idActor::Event_DisablePain -=============== -*/ -void idActor::Event_DisablePain( void ) { - allowPain = false; -} - -/* -=============== -idActor::Event_EnablePain -=============== -*/ -void idActor::Event_EnablePain( void ) { - allowPain = true; -} - -/* -===================== -idActor::Event_GetPainAnim -===================== -*/ -void idActor::Event_GetPainAnim( void ) { - if ( !painAnim.Length() ) { - idThread::ReturnString( "pain" ); - } else { - idThread::ReturnString( painAnim ); - } -} - -/* -===================== -idActor::Event_SetAnimPrefix -===================== -*/ -void idActor::Event_SetAnimPrefix( const char *prefix ) { - animPrefix = prefix; -} - -/* -=============== -idActor::Event_StopAnim -=============== -*/ -void idActor::Event_StopAnim( int channel, int frames ) { - StopAnim(channel, frames); -} - -/* -=============== -idActor::Event_PlayAnim -=============== -*/ -void idActor::Event_PlayAnim( int channel, const char *animname ) { - animFlags_t flags; - idEntity *headEnt; - int anim; - - if (cv_ai_debug_anims.GetBool() && this != gameLocal.GetLocalPlayer()) - { - gameLocal.Printf("Frame: %d - playing anim %s (%s)\n", gameLocal.framenum, animname, name.c_str()); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - playing anim %s (%s)\r", gameLocal.framenum, animname, name.c_str()); - } - - anim = GetAnim( channel, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { - gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); - } else { - //gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); - } -#endif - - idThread::ReturnInt( 0 ); - return; - } - - switch( channel ) { - case ANIMCHANNEL_HEAD : - headEnt = head.GetEntity(); - if ( headEnt ) { - headAnim.idleAnim = false; - headAnim.PlayAnim( anim ); - flags = headAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( torsoAnim.IsIdle() ) { - torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - if ( legsAnim.IsIdle() ) { - legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - } - } - } - } - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.idleAnim = false; - torsoAnim.PlayAnim( anim ); - flags = torsoAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( headAnim.IsIdle() ) { - headAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - if ( legsAnim.IsIdle() ) { - legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - } - break; - - case ANIMCHANNEL_LEGS : - legsAnim.idleAnim = false; - legsAnim.PlayAnim( anim ); - flags = legsAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( torsoAnim.IsIdle() ) { - torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - if ( headAnim.IsIdle() ) { - headAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - } - } - } - break; - - default : - gameLocal.Error( "Unknown anim group" ); - break; - } - idThread::ReturnInt( 1 ); -} - -/* -=============== -idActor::Event_PlayCycle -=============== -*/ -void idActor::Event_PlayCycle( int channel, const char *animname ) { - animFlags_t flags; - int anim; - - anim = GetAnim( channel, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { - gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); - } else { - gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); - } -#endif - - idThread::ReturnInt( false ); - return; - } - - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.idleAnim = false; - headAnim.CycleAnim( anim ); - flags = headAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( torsoAnim.IsIdle() && legsAnim.IsIdle() ) { - torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - } - } - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.idleAnim = false; - torsoAnim.CycleAnim( anim ); - flags = torsoAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( headAnim.IsIdle() ) { - headAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - if ( legsAnim.IsIdle() ) { - legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - } - break; - - case ANIMCHANNEL_LEGS : - legsAnim.idleAnim = false; - legsAnim.CycleAnim( anim ); - flags = legsAnim.GetAnimFlags(); - if ( !flags.prevent_idle_override ) { - if ( torsoAnim.IsIdle() ) { - torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - if ( headAnim.IsIdle() ) { - headAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - } - } - } - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } - - idThread::ReturnInt( true ); -} - -/* -=============== -idActor::Event_PauseAnim -=============== -*/ -void idActor::Event_PauseAnim( int channel, bool bPause ) -{ - animator.CurrentAnim( channel )->Pause( bPause ); -} - -/* -=============== -idActor::Event_AnimIsPaused -=============== -*/ -void idActor::Event_AnimIsPaused( int channel ) -{ - idThread::ReturnInt( animator.CurrentAnim( channel )->IsPaused() ); -} - -/* -=============== -idActor::Event_IdleAnim -=============== -*/ -void idActor::Event_IdleAnim( int channel, const char *animname ) { - int anim; - - anim = GetAnim( channel, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - if ( ( channel == ANIMCHANNEL_HEAD ) && head.GetEntity() ) { - gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), spawnArgs.GetString( "def_head", "" ) ); - } else { - gameLocal.Printf( "missing '%s' animation on '%s' (%s)\n", animname, name.c_str(), GetEntityDefName() ); - } -#endif - - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.BecomeIdle(); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.BecomeIdle(); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.BecomeIdle(); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } - - idThread::ReturnInt( false ); - return; - } - - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.BecomeIdle(); - if ( torsoAnim.GetAnimFlags().prevent_idle_override ) { - // don't sync to torso body if it doesn't override idle anims - headAnim.CycleAnim( anim ); - } else if ( torsoAnim.IsIdle() && legsAnim.IsIdle() ) { - // everything is idle, so play the anim on the head and copy it to the torso and legs - headAnim.CycleAnim( anim ); - torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - legsAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_HEAD, headAnim.lastAnimBlendFrames ); - } else if ( torsoAnim.IsIdle() ) { - // sync the head and torso to the legs - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, headAnim.animBlendFrames ); - torsoAnim.animBlendFrames = headAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, torsoAnim.animBlendFrames ); - } else { - // sync the head to the torso - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, headAnim.animBlendFrames ); - } - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.BecomeIdle(); - if ( legsAnim.GetAnimFlags().prevent_idle_override ) { - // don't sync to legs if legs anim doesn't override idle anims - torsoAnim.CycleAnim( anim ); - } else if ( legsAnim.IsIdle() ) { - // play the anim in both legs and torso - torsoAnim.CycleAnim( anim ); - legsAnim.animBlendFrames = torsoAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } else { - // sync the anim to the legs - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, torsoAnim.animBlendFrames ); - } - - if ( headAnim.IsIdle() ) { - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - break; - - case ANIMCHANNEL_LEGS : - legsAnim.BecomeIdle(); - if ( torsoAnim.GetAnimFlags().prevent_idle_override ) { - // don't sync to torso if torso anim doesn't override idle anims - legsAnim.CycleAnim( anim ); - } else if ( torsoAnim.IsIdle() ) { - // play the anim in both legs and torso - legsAnim.CycleAnim( anim ); - torsoAnim.animBlendFrames = legsAnim.lastAnimBlendFrames; - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - if ( headAnim.IsIdle() ) { - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - } - } else { - // sync the anim to the torso - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, legsAnim.animBlendFrames ); - } - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } - - idThread::ReturnInt( true ); -} - -/* -================ -idActor::Event_SetSyncedAnimWeight -================ -*/ -void idActor::Event_SetSyncedAnimWeight( int channel, int anim, float weight ) { - idEntity *headEnt; - - headEnt = head.GetEntity(); - switch( channel ) { - case ANIMCHANNEL_HEAD : - if ( headEnt ) { - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); - } else { - animator.CurrentAnim( ANIMCHANNEL_HEAD )->SetSyncedAnimWeight( anim, weight ); - } - if ( torsoAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); - if ( legsAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); - } - } - break; - - case ANIMCHANNEL_TORSO : - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); - if ( legsAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); - } - if ( headEnt && headAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); - } - break; - - case ANIMCHANNEL_LEGS : - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( anim, weight ); - if ( torsoAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( anim, weight ); - if ( headEnt && headAnim.IsIdle() ) { - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetSyncedAnimWeight( anim, weight ); - } - } - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } -} - -void idActor::Event_SyncAnimChannels(int fromChannel, int toChannel, float blendFrames) -{ - SyncAnimChannels(fromChannel, toChannel, static_cast(blendFrames)); -} - -/* -=============== -idActor::Event_OverrideAnim -=============== -*/ -void idActor::Event_OverrideAnim( int channel ) { - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.Disable(); - if ( !torsoAnim.IsIdle() ) { - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } else { - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - } - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.Disable(); - SyncAnimChannels( ANIMCHANNEL_TORSO, ANIMCHANNEL_LEGS, legsAnim.lastAnimBlendFrames ); - if ( headAnim.IsIdle() ) { - SyncAnimChannels( ANIMCHANNEL_HEAD, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - } - break; - - case ANIMCHANNEL_LEGS : - legsAnim.Disable(); - SyncAnimChannels( ANIMCHANNEL_LEGS, ANIMCHANNEL_TORSO, torsoAnim.lastAnimBlendFrames ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - -/* -=============== -idActor::Event_EnableAnim -=============== -*/ -void idActor::Event_EnableAnim( int channel, int blendFrames ) { - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.Enable( blendFrames ); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.Enable( blendFrames ); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.Enable( blendFrames ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - - -/* -=============== -idActor::Event_DisableAnimchannel -=============== -*/ -void idActor::Event_DisableAnimchannel( int channel ) { - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.Disable(); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.Disable(); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.Disable(); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - -/* -=============== -idActor::Event_SetBlendFrames -=============== -*/ -void idActor::Event_SetBlendFrames( int channel, int blendFrames ) { - switch( channel ) { - case ANIMCHANNEL_HEAD : - headAnim.animBlendFrames = blendFrames; - headAnim.lastAnimBlendFrames = blendFrames; - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.animBlendFrames = blendFrames; - torsoAnim.lastAnimBlendFrames = blendFrames; - break; - - case ANIMCHANNEL_LEGS : - legsAnim.animBlendFrames = blendFrames; - legsAnim.lastAnimBlendFrames = blendFrames; - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - -/* -=============== -idActor::Event_GetBlendFrames -=============== -*/ -void idActor::Event_GetBlendFrames( int channel ) { - switch( channel ) { - case ANIMCHANNEL_HEAD : - idThread::ReturnInt( headAnim.animBlendFrames ); - break; - - case ANIMCHANNEL_TORSO : - idThread::ReturnInt( torsoAnim.animBlendFrames ); - break; - - case ANIMCHANNEL_LEGS : - idThread::ReturnInt( legsAnim.animBlendFrames ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - break; - } -} - -/* -=============== -idActor::Event_AnimState -=============== -*/ -void idActor::Event_AnimState( int channel, const char *statename, int blendFrames ) { - SetAnimState( channel, statename, blendFrames ); -} - -/* -=============== -idActor::Event_GetAnimState -=============== -*/ -void idActor::Event_GetAnimState( int channel ) { - const char *state; - - state = GetAnimState( channel ); - idThread::ReturnString( state ); -} - -/* -=============== -idActor::Event_InAnimState -=============== -*/ -void idActor::Event_InAnimState( int channel, const char *statename ) { - bool instate; - - instate = InAnimState( channel, statename ); - idThread::ReturnInt( instate ); -} - -/* -=============== -idActor::Event_FinishAction -=============== -*/ -void idActor::Event_FinishAction( const char *actionname ) { - if ( waitState == actionname ) { - SetWaitState( "" ); - } -} - -void idActor::Event_FinishChannelAction( int channel, const char *actionname) -{ - switch( channel ) - { - case ANIMCHANNEL_HEAD : - headAnim.FinishAction( actionname); - break; - - case ANIMCHANNEL_TORSO : - torsoAnim.FinishAction( actionname); - break; - - case ANIMCHANNEL_LEGS : - legsAnim.FinishAction( actionname ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } -} - -bool idActor::AnimDone( int channel, int blendFrames ) const -{ - bool result = false; - - switch( channel ) { - case ANIMCHANNEL_HEAD : - result = headAnim.AnimDone( blendFrames ); - break; - - case ANIMCHANNEL_TORSO : - result = torsoAnim.AnimDone( blendFrames ); - break; - - case ANIMCHANNEL_LEGS : - result = legsAnim.AnimDone( blendFrames ); - break; - - default: - gameLocal.Error( "Unknown anim group" ); - } - - return result; -} - -/* -=============== -idActor::Event_AnimDone -=============== -*/ -void idActor::Event_AnimDone( int channel, int blendFrames ) { - idThread::ReturnInt(AnimDone(channel, blendFrames)); -} - -/* -================ -idActor::Event_HasAnim -================ -*/ -void idActor::Event_HasAnim( int channel, const char *animname ) { - if ( GetAnim( channel, animname ) ) { - idThread::ReturnFloat( 1.0f ); - } else { - idThread::ReturnFloat( 0.0f ); - } -} - -/* -================ -idActor::Event_CheckAnim -================ -*/ -void idActor::Event_CheckAnim( int channel, const char *animname ) { - if ( !GetAnim( channel, animname ) ) { - if ( animPrefix.Length() ) { - gameLocal.Error( "Can't find anim '%s_%s' for '%s'", animPrefix.c_str(), animname, name.c_str() ); - } else { - gameLocal.Error( "Can't find anim '%s' for '%s'", animname, name.c_str() ); - } - } -} - -/* -================ -idActor::Event_ChooseAnim -================ -*/ -void idActor::Event_ChooseAnim( int channel, const char *animname ) { - int anim; - - anim = GetAnim( channel, animname ); - if ( anim ) { - if ( channel == ANIMCHANNEL_HEAD ) { - if ( head.GetEntity() ) { - idThread::ReturnString( head.GetEntity()->GetAnimator()->AnimFullName( anim ) ); - return; - } - } else { - idThread::ReturnString( animator.AnimFullName( anim ) ); - return; - } - } - - idThread::ReturnString( "" ); -} - -/* -================ -idActor::Event_AnimLength -================ -*/ -void idActor::Event_AnimLength( int channel, const char *animname ) { - int anim; - - anim = GetAnim( channel, animname ); - if ( anim ) { - if ( channel == ANIMCHANNEL_HEAD ) { - if ( head.GetEntity() ) { - idThread::ReturnFloat( MS2SEC( head.GetEntity()->GetAnimator()->AnimLength( anim ) ) ); - return; - } - } else { - idThread::ReturnFloat( MS2SEC( animator.AnimLength( anim ) ) ); - return; - } - } - - idThread::ReturnFloat( 0.0f ); -} - -/* -================ -idActor::Event_AnimDistance -================ -*/ -void idActor::Event_AnimDistance( int channel, const char *animname ) { - int anim; - - anim = GetAnim( channel, animname ); - if ( anim ) { - if ( channel == ANIMCHANNEL_HEAD ) { - if ( head.GetEntity() ) { - idThread::ReturnFloat( head.GetEntity()->GetAnimator()->TotalMovementDelta( anim ).Length() ); - return; - } - } else { - idThread::ReturnFloat( animator.TotalMovementDelta( anim ).Length() ); - return; - } - } - - idThread::ReturnFloat( 0.0f ); -} - -/* -================ -idActor::Event_HasEnemies -================ -*/ -void idActor::Event_HasEnemies( void ) { - bool hasEnemy; - - hasEnemy = HasEnemies(); - idThread::ReturnInt( hasEnemy ); -} - -/* -================ -idActor::Event_NextEnemy -================ -*/ -void idActor::Event_NextEnemy( idEntity *ent ) { - idActor *actor; - - if ( !ent || ( ent == this ) ) { - actor = enemyList.Next(); - } else { - if ( !ent->IsType( idActor::Type ) ) { - gameLocal.Error( "'%s' cannot be an enemy", ent->name.c_str() ); - } - - actor = static_cast( ent ); - if ( actor->enemyNode.ListHead() != &enemyList ) { - gameLocal.Error( "'%s' is not in '%s' enemy list", actor->name.c_str(), name.c_str() ); - } - } - - for( ; actor != NULL; actor = actor->enemyNode.Next() ) { - if ( !actor->fl.hidden ) { - idThread::ReturnEntity( actor ); - return; - } - } - - idThread::ReturnEntity( NULL ); -} - -/* -================ -idActor::Event_ClosestEnemyToPoint -================ -*/ -void idActor::Event_ClosestEnemyToPoint( const idVec3 &pos ) { - idActor *bestEnt = ClosestEnemyToPoint( pos ); - idThread::ReturnEntity( bestEnt ); -} - -/* -================ -idActor::Event_MeleeBestParry -================ -*/ -void idActor::Event_MeleeBestParry() -{ - idThread::ReturnInt( GetBestParry() ); -} - -/* -================ -idActor::Event_MeleeNameForNum -================ -*/ -void idActor::Event_MeleeNameForNum( int num ) -{ - if( num >= 0 && num < NUM_MELEE_TYPES ) - idThread::ReturnString( MeleeTypeNames[num] ); - else - { - gameLocal.Warning("Actor %s attempted to look up bad melee type number %d", name.c_str(), num ); - idThread::ReturnString( "" ); - } -} - -/* -================ -idActor::Event_StopSound -================ -*/ -void idActor::Event_StopSound( int channel, int netSync ) { - if ( channel == SND_CHANNEL_VOICE ) { - idEntity *headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->StopSound( channel, ( netSync != 0 ) ); - } - } - StopSound( channel, ( netSync != 0 ) ); -} - -/* -===================== -idActor::Event_SetNextState -===================== -*/ -void idActor::Event_SetNextState( const char *name ) { - idealState = GetScriptFunction( name ); - if ( idealState == state ) { - state = NULL; - } -} - -/* -===================== -idActor::Event_SetState -===================== -*/ -void idActor::Event_SetState( const char *name ) { - idealState = GetScriptFunction( name ); - if ( idealState == state ) { - state = NULL; - } - scriptThread->DoneProcessing(); -} - -/* -===================== -idActor::Event_GetState -===================== -*/ -void idActor::Event_GetState( void ) { - if ( state ) { - idThread::ReturnString( state->Name() ); - } else { - idThread::ReturnString( "" ); - } -} - -/* -===================== -idActor::Event_GetHead -===================== -*/ -void idActor::Event_GetHead( void ) { - idThread::ReturnEntity( head.GetEntity() ); -} - -/* -===================== -idActor::Event_GetEyePos -===================== -*/ -void idActor::Event_GetEyePos( void ) -{ - idThread::ReturnVector( GetEyePosition() ); -} - -/* -===================== -idActor::Event_SetHealth -===================== -*/ -void idActor::Event_SetHealth( float newHealth ) { - health = static_cast(newHealth); - fl.takedamage = true; - if ( health > 0 ) { - AI_DEAD = false; - } else { - AI_DEAD = true; - } -} - -/* -===================== -idActor::Event_GetHealth -===================== -*/ -void idActor::Event_GetHealth( void ) { - idThread::ReturnFloat( health ); -} - -/* -===================== -idActor::Event_Attach -===================== -*/ -void idActor::Event_Attach( idEntity *ent, const char *AttName ) -{ - Attach( ent, NULL, AttName ); -} - -/* -===================== -idActor::Event_AttachToPos -===================== -*/ -void idActor::Event_AttachToPos( idEntity *ent, const char *PosName, const char *AttName ) -{ - Attach( ent, PosName, AttName ); -} - -/* -===================== -idActor::Event_GetAttachment -===================== -*/ -void idActor::Event_GetAttachment( const char *AttName ) -{ - idEntity *ent = GetAttachment( AttName ); - idThread::ReturnEntity( ent ); -} - -/* -===================== -idActor::Event_GetAttachmentInd -===================== -*/ -void idActor::Event_GetAttachmentInd( int ind ) -{ - idEntity *ent = GetAttachment( ind ); - idThread::ReturnEntity( ent ); -} - -/* -===================== -idActor::Event_GetNumAttachments -===================== -*/ -void idActor::Event_GetNumAttachments( void ) -{ - idThread::ReturnInt( m_Attachments.Num() ); -} - -/* -===================== -idActor::Event_GetNumMeleeWeapons -===================== -*/ -void idActor::Event_GetNumMeleeWeapons() -{ - idThread::ReturnInt(GetNumMeleeWeapons()); -} - -/* -===================== -idActor::Event_GetNumRangedWeapons -===================== -*/ -void idActor::Event_GetNumRangedWeapons() -{ - idThread::ReturnInt(GetNumRangedWeapons()); -} - -int idActor::GetNumMeleeWeapons() -{ - int numMeleeWeapons(0); - - // greebo: Always return 1 if this type of actor doesn't need weapons to fight - if (spawnArgs.GetBool("unarmed_melee", "0")) { - return 1; - } - - for (int i = 0; i < m_Attachments.Num(); i++) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL || !m_Attachments[i].ent.IsValid()) - { - continue; - } - - if (ent->spawnArgs.GetBool("is_weapon_melee")) - { - numMeleeWeapons++; - } - } - - return numMeleeWeapons; -} - -int idActor::GetNumRangedWeapons() -{ - int numRangedWeapons(0); - - if (spawnArgs.GetBool("unarmed_ranged", "0")) { - return 1; - } - - for (int i = 0; i < m_Attachments.Num(); i++) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL || !m_Attachments[i].ent.IsValid()) - { - continue; - } - - if (ent->spawnArgs.GetBool("is_weapon_ranged")) - { - numRangedWeapons++; - } - } - - return numRangedWeapons; -} - -bool idActor::GetAttackFlag(ECombatType type) const -{ - return m_AttackFlags.find(static_cast(type)) != m_AttackFlags.end(); -} - -void idActor::SetAttackFlag(ECombatType type, bool enabled) -{ - if (enabled) - { - m_AttackFlags.insert(type); - } - else - { - m_AttackFlags.erase(type); - } -} - -/**************************************************************************************** - ===================== - idActor::CrashLand - handle collision(Falling) damage to AI/Players - Added by Richard Day - ===================== -****************************************************************************************/ -CrashLandResult idActor::CrashLand( const idPhysics_Actor& physicsObj, const idVec3 &savedOrigin, const idVec3 &savedVelocity ) -{ - CrashLandResult result; - result.damageDealt = 0; - result.hasLanded = false; - - if (GetPhysics() == NULL) return result; - - idPhysics& physics = *GetPhysics(); // shortcut - - // no falling damage if touching a nodamage surface - // We do this here since the sound wont be played otherwise - // as we do no damage if this is true. - for( int i = 0; i < physics.GetNumContacts(); i++ ) - { - const contactInfo_t &contact = physics.GetContact( i ); - if ( contact.material->GetSurfaceFlags() & SURF_NODAMAGE ) - { - StartSound( "snd_land_hard", SND_CHANNEL_ANY, 0, false, NULL ); - result.hasLanded = true; - return result; - } - } - - const idVec3& vGravNorm = physics.GetGravityNormal(); - const idVec3& curVelocity = physics.GetLinearVelocity(); - - // The current speed parallel to gravity - idVec3 curGravVelocity = (curVelocity*vGravNorm) * vGravNorm; - - // Get the vdelta (how much the velocity has changed in this frame) - idVec3 deltaVec = (savedVelocity - curVelocity); - - // greebo: Get the vertical portion of the velocity - idVec3 deltaVecVert = (deltaVec * vGravNorm) * vGravNorm; - // Get the horizontal portion by subtracting the vertical one from the velocity - idVec3 deltaVecHoriz = deltaVec - deltaVecVert; - - float deltaHoriz = deltaVecHoriz.LengthSqr(); - float deltaVert = deltaVec.LengthSqr() - deltaHoriz; - - // conversion factor to 10s of MJ/kg, horizontal and vertical weighted differently - double delta = cv_collision_damage_scale_vert.GetFloat() * deltaVert; - delta += cv_collision_damage_scale_horiz.GetFloat() * deltaHoriz; - - // damage scale per actor - delta *= m_delta_scale; - - // greebo: Check if we are still using actor physics, we might already be in ragdoll mode - if (physics.IsType(idPhysics_Actor::Type)) - { - waterLevel_t waterLevel = static_cast(physics).GetWaterLevel(); - - // reduce falling damage if there is standing water - switch (waterLevel) - { - case WATERLEVEL_NONE: - break; - case WATERLEVEL_FEET: delta *= 0.8f; // -20% for shallow water - break; - case WATERLEVEL_WAIST: delta *= 0.5f; // -50% for medium water - break; - case WATERLEVEL_HEAD: delta *= 0.25f; // -75% for deep water - break; - default: - break; - }; - } - - // We've been moving downwards with a certain velocity, set the flag - if (curGravVelocity.LengthFast() < 1 && deltaVecVert*vGravNorm > 100) - { - result.hasLanded = true; - } - - if (delta < 390000) - { - // Below this threshold, nothing happens - return result; - } - - // greebo: Now calibrate the damage using the sixth power of the velocity (=square^3) - // The damage has a linear relationship to the sixth power of vdelta - delta = delta*delta*delta; - int damage = static_cast(1.4E-16 * delta - 3); - - // gameRenderWorld->DrawText(idStr(damage), GetPhysics()->GetOrigin(), 0.15, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 16); - - // Check if the damage is above our threshold, ignore otherwise - if (damage >= m_damage_thresh_min) - { - //gameRenderWorld->DrawText(idStr(deltaVert), GetPhysics()->GetOrigin(), 0.15, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 50000); - - //gameRenderWorld->DrawText(idStr(damage), GetPhysics()->GetOrigin(), 0.15, colorRed, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 5000); - gameLocal.Printf("Damage dealt: %d\n", damage); - - pain_debounce_time = gameLocal.time + pain_delay + 1; // ignore pain since we'll play our landing anim - - // Update our return value - result.damageDealt = damage; - - if (damage > m_damage_thresh_hard) - { - // greebo: the damage_fall_hard entityDef has a damage value of 1, which is scaled by the calculated damage integer - StartSound("snd_damage_land_hard", SND_CHANNEL_VOICE, 0, false, NULL); - Damage(NULL, NULL, vGravNorm, "damage_fall_hard", damage, 0); - } - else - { - // We are below the "hard" threshold, just deal the "soft" damage - StartSound("snd_damage_land_soft", SND_CHANNEL_VOICE, 0, false, NULL); - Damage(NULL, NULL, vGravNorm, "damage_fall_soft", damage, 0); - } - } - - return result; -} - -void idActor::Event_MeleeAttackStarted( int num ) -{ - m_MeleeStatus.m_ActionResult = MELEERESULT_IN_PROGRESS; - m_MeleeStatus.m_ActionState = MELEEACTION_ATTACK; - m_MeleeStatus.m_ActionType = (EMeleeType) num; - m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; - m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; - - // randomize minimum times to events after this one - // TODO: Rewrite this so we only set the times we need according to the result? - float fRand = gameLocal.random.RandomFloat(); - m_MeleeCurrentHoldTime = m_MeleeHoldTimeMin + fRand*(m_MeleeHoldTimeMax - m_MeleeHoldTimeMin); - m_MeleeCurrentAttackRecovery = m_MeleeAttackRecoveryMin + fRand*(m_MeleeAttackRecoveryMax - m_MeleeAttackRecoveryMin); - m_MeleeCurrentAttackLongRecovery = m_MeleeAttackLongRecoveryMin + fRand*(m_MeleeAttackLongRecoveryMax - m_MeleeAttackLongRecoveryMin); - m_MeleeCurrentParryRecovery = m_MeleeParryRecoveryMin + fRand*(m_MeleeParryRecoveryMax - m_MeleeParryRecoveryMin); -} - -void idActor::Event_MeleeParryStarted( int num ) -{ - m_MeleeStatus.m_ActionResult = MELEERESULT_IN_PROGRESS; - m_MeleeStatus.m_ActionState = MELEEACTION_PARRY; - m_MeleeStatus.m_ActionType = (EMeleeType) num; - m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; - m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; - - // randomize minimum times to events after this one - // TODO: Rewrite this so we only set what we need based on result? - float fRand = gameLocal.random.RandomFloat(); - m_MeleeCurrentParryHold = m_MeleeParryHoldMin + fRand*(m_MeleeParryHoldMax - m_MeleeParryHoldMin); - m_MeleeCurrentAttackLongRecovery = m_MeleeAttackLongRecoveryMin + fRand*(m_MeleeAttackLongRecoveryMax - m_MeleeAttackLongRecoveryMin); - m_MeleeCurrentParryRecovery = m_MeleeParryRecoveryMin + fRand*(m_MeleeParryRecoveryMax - m_MeleeParryRecoveryMin); - m_MeleeCurrentRiposteRecovery = m_MeleeRiposteRecoveryMin + fRand*(m_MeleeRiposteRecoveryMax - m_MeleeRiposteRecoveryMin); - m_MeleeCurrentPreParryDelay = m_MeleePreParryDelayMin + fRand*(m_MeleePreParryDelayMax - m_MeleePreParryDelayMin); - m_MeleeCurrentRepeatedPreParryDelay = m_MeleeRepeatedPreParryDelayMin + fRand*(m_MeleeRepeatedPreParryDelayMax - m_MeleeRepeatedPreParryDelayMin); - m_MeleeCurrentPostParryDelay = m_MeleePostParryDelayMin + fRand*(m_MeleePostParryDelayMax - m_MeleePostParryDelayMin); - m_MeleeCurrentRepeatedPostParryDelay = m_MeleeRepeatedPostParryDelayMin + fRand*(m_MeleeRepeatedPostParryDelayMax - m_MeleeRepeatedPostParryDelayMin); -} - -void idActor::Event_MeleeActionHeld() -{ - m_MeleeStatus.m_ActionPhase = MELEEPHASE_HOLDING; - m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; -} - -void idActor::Event_MeleeActionReleased() -{ - // attacks go to executing phase, parries jump straight to recovering - // CMeleeWeapon handles toggling attacks from executing to recovering - if( m_MeleeStatus.m_ActionState == MELEEACTION_ATTACK ) - m_MeleeStatus.m_ActionPhase = MELEEPHASE_EXECUTING; - else - m_MeleeStatus.m_ActionPhase = MELEEPHASE_RECOVERING; - - - m_MeleeStatus.m_PhaseChangeTime = gameLocal.time; -} - -void idActor::Event_MeleeActionFinished() -{ - m_MeleeStatus.m_ActionState = MELEEACTION_READY; - m_MeleeStatus.m_ActionPhase = MELEEPHASE_PREPARING; - m_MeleeStatus.m_LastActTime = gameLocal.time; -} - -void idActor::Event_GetMeleeActionState() -{ - idThread::ReturnInt( m_MeleeStatus.m_ActionState ); -} - -void idActor::Event_GetMeleeActionPhase() -{ - idThread::ReturnInt( m_MeleeStatus.m_ActionPhase ); -} - -void idActor::Event_GetMeleeActionType() -{ - idThread::ReturnInt( m_MeleeStatus.m_ActionType ); -} - -void idActor::Event_GetMeleeLastActTime() -{ - idThread::ReturnInt( m_MeleeStatus.m_LastActTime ); -} - -void idActor::Event_GetMeleeResult() -{ - idThread::ReturnInt( m_MeleeStatus.m_ActionResult ); -} - -void idActor::Event_GetMeleeLastHitByType() -{ - idThread::ReturnInt( m_MeleeStatus.m_LastHitByType ); -} - -void idActor::Event_SetReplacementAnim(const char* animToReplace, const char* replacementAnim) -{ - SetReplacementAnim(animToReplace, replacementAnim); -} - -void idActor::Event_RemoveReplacementAnim(const char* animName) -{ - RemoveReplacementAnim(animName); -} - -void idActor::Event_LookupReplacementAnim(const char* animName) -{ - idThread::ReturnString(LookupReplacementAnim(animName)); -} - -void idActor::Event_GetAttackFlag(int combatType) -{ - if (combatType < COMBAT_NONE || combatType >= NUM_COMBAT_TYPES) - { - idThread::ReturnInt(0); - } - - idThread::ReturnInt(GetAttackFlag(static_cast(combatType)) ? 1 : 0); -} - -void idActor::Event_SetAttackFlag(int combatType, int enabled) -{ - if (combatType < COMBAT_NONE || combatType >= NUM_COMBAT_TYPES) - { - // do nothing - gameLocal.Warning("Script is trying to set invalid combatType %d", combatType); - return; - } - - SetAttackFlag(static_cast(combatType), enabled == 1); -} - -// ========== CMeleeStatus implementation ========= -CMeleeStatus::CMeleeStatus( void ) -{ - m_ActionState = MELEEACTION_READY; - m_ActionPhase = MELEEPHASE_PREPARING; - m_ActionType = MELEETYPE_OVER; - - m_PhaseChangeTime = 0; - m_LastActTime = 0; - - m_ActionResult = MELEERESULT_IN_PROGRESS; - - m_bWasHit = false; // NYI - m_LastHitByType = MELEETYPE_UNBLOCKABLE; - - m_bCanParry = false; - m_bCanParryAll = false; - m_attacks.Clear(); -} - -CMeleeStatus::~CMeleeStatus( void ) -{ - m_attacks.Clear(); -} - -void CMeleeStatus::Save( idSaveGame *savefile ) const -{ - savefile->WriteInt( m_ActionState ); - savefile->WriteInt( m_ActionPhase ); - savefile->WriteInt( m_ActionType ); - savefile->WriteInt( m_PhaseChangeTime ); - savefile->WriteInt( m_LastActTime ); - savefile->WriteInt( m_ActionResult ); - - savefile->WriteBool( m_bWasHit ); - savefile->WriteInt( m_LastHitByType ); - - savefile->WriteBool( m_bCanParry ); - savefile->WriteBool( m_bCanParryAll ); - - int num = m_attacks.Num(); - savefile->WriteInt( num ); - for( int i =0; i < num; i++ ) - { - savefile->WriteInt( m_attacks[i] ); - } -} - -void CMeleeStatus::Restore( idRestoreGame *savefile ) -{ - int i = 0; - savefile->ReadInt( i ); - m_ActionState = (EMeleeActState) i; - savefile->ReadInt( i ); - m_ActionPhase = (EMeleeActPhase) i; - savefile->ReadInt( i ); - m_ActionType = (EMeleeType) i; - savefile->ReadInt( m_PhaseChangeTime ); - savefile->ReadInt( m_LastActTime ); - savefile->ReadInt( i ); - m_ActionResult = (EMeleeResult) i; - - savefile->ReadBool( m_bWasHit ); - savefile->ReadInt( i ); - m_LastHitByType = (EMeleeType) i; - - savefile->ReadBool( m_bCanParry ); - savefile->ReadBool( m_bCanParryAll ); - - int num; - savefile->ReadInt( num ); - m_attacks.SetNum( num ); - for( int j =0; j < num; j++ ) - { - savefile->ReadInt( i ); - m_attacks[j] = (EMeleeType) i; - } -} diff --git a/game/actor.h b/game/actor.h deleted file mode 100644 index cfe6dbea5..000000000 --- a/game/actor.h +++ /dev/null @@ -1,893 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_ACTOR_H__ -#define __GAME_ACTOR_H__ - -#include "../DarkMod/MultiStateMoverPosition.h" -#include "../DarkMod/AI/EAS/RouteInfo.h" -#include - -// greebo: Keep the values in scripts/tdm_defs.script in sync with these -enum ECombatType -{ - COMBAT_NONE, - COMBAT_MELEE, - COMBAT_RANGED, - NUM_COMBAT_TYPES -}; - -/** Melee Attack/Parry types **/ -typedef enum -{ - MELEETYPE_OVER, - MELEETYPE_LR, // slashing (attacker's) left to right - MELEETYPE_RL, // slashing (attacker's) right to left - MELEETYPE_THRUST, - MELEETYPE_UNBLOCKABLE, // unblockable attacks (e.g. animal claws) - MELEETYPE_BLOCKALL, // blocks all attacks except unblockable (e.g., shield) - NUM_MELEE_TYPES -} EMeleeType; - -/** Melee Overall Action States **/ -typedef enum -{ - MELEEACTION_READY, // ready to attack or parry - MELEEACTION_ATTACK, - MELEEACTION_PARRY -} EMeleeActState; - -/** Melee phases of each action (applies to both attack and parry) **/ -typedef enum -{ - MELEEPHASE_PREPARING, // Moving to backswing or parry position - MELEEPHASE_HOLDING, // holding a backswing or parry - MELEEPHASE_EXECUTING, // executing a threatening attack (doesn't apply to parries) - MELEEPHASE_RECOVERING // recovering the current attack/parry back to guard position -} EMeleeActPhase; - -/** Possible outcomes of a melee action (includes attacks and parries) **/ -enum EMeleeResult -{ - MELEERESULT_IN_PROGRESS, // no result yet, still in progress - MELEERESULT_AT_HIT, - MELEERESULT_AT_MISSED, - MELEERESULT_AT_PARRIED, - MELEERESULT_PAR_BLOCKED, // successfully parried the attack - MELEERESULT_PAR_FAILED, // got hit while parrying (TODO: Does not catch all cases, only catches parry type mismatch) - MELEERESULT_PAR_ABORTED, // gave up parrying - - NUM_MELEE_RESULTS -}; - -/** class for storing current melee combat status **/ -class CMeleeStatus -{ -public: - CMeleeStatus( void ); - virtual ~CMeleeStatus( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // clears the current action - void ClearAction( void ); - - EMeleeActState m_ActionState; // current action - EMeleeActPhase m_ActionPhase; // phase within that action - EMeleeType m_ActionType; // type of attack/parry - - // time the phase of our action last changed - int m_PhaseChangeTime; - // time that our most recent action ended - int m_LastActTime; - - // Result of most recent action - // Will be considered "in progress" until back in the "Ready" state - EMeleeResult m_ActionResult; - - // were we just hit by a melee attack? may take longer to perform next action - // NYI - bool m_bWasHit; - - /** What attack type were we last hit by? (used by trainers to give feedback) **/ - EMeleeType m_LastHitByType; - - // melee capabilities of weapon - bool m_bCanParry; - bool m_bCanParryAll; - idList m_attacks; // possible attacks with current weapon - -}; // CMeleeStatus - - -/* -=============================================================================== - - idActor - -=============================================================================== -*/ - -extern const idEventDef AI_EnableEyeFocus; -extern const idEventDef AI_DisableEyeFocus; -extern const idEventDef EV_Footstep; -extern const idEventDef EV_FootstepLeft; -extern const idEventDef EV_FootstepRight; -extern const idEventDef EV_EnableWalkIK; -extern const idEventDef EV_DisableWalkIK; -extern const idEventDef EV_EnableLegIK; -extern const idEventDef EV_DisableLegIK; -extern const idEventDef AI_SetAnimPrefix; -extern const idEventDef AI_PlayAnim; -extern const idEventDef AI_PauseAnim; -extern const idEventDef AI_AnimIsPaused; -extern const idEventDef AI_PlayCycle; -extern const idEventDef AI_AnimDone; -extern const idEventDef AI_SetBlendFrames; -extern const idEventDef AI_GetBlendFrames; - -extern const idEventDef AI_MeleeAttackStarted; -extern const idEventDef AI_MeleeParryStarted; -extern const idEventDef AI_MeleeActionHeld; -extern const idEventDef AI_MeleeActionReleased; -extern const idEventDef AI_MeleeActionFinished; -extern const idEventDef AI_GetMeleeActionState; -extern const idEventDef AI_GetMeleeActionPhase; -extern const idEventDef AI_GetMeleeActionType; -extern const idEventDef AI_GetMeleeLastActTime; -extern const idEventDef AI_GetMeleeResult; -extern const idEventDef AI_GetMeleeLastHitByType; -extern const idEventDef AI_MeleeBestParry; -extern const idEventDef AI_MeleeNameForNum; - -class idDeclParticle; - -class idAnimState { -public: - bool idleAnim; - idStr state; - int animBlendFrames; - int lastAnimBlendFrames; // allows override anims to blend based on the last transition time - -public: - idAnimState(); - ~idAnimState(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Init( idActor *owner, idAnimator *_animator, int animchannel ); - void Shutdown( void ); - void SetState( const char *name, int blendFrames ); - void SetFrame( int anim, int frame ); - void StopAnim( int frames ); - void PlayAnim( int anim ); - void PauseAnim( int channel, bool bPause ); - bool AnimIsPaused( int anim ); - void CycleAnim( int anim ); - void BecomeIdle( void ); - bool UpdateState( void ); - bool Disabled( void ) const; - void Enable( int blendFrames ); - void Disable( void ); - bool AnimDone( int blendFrames ) const; - bool IsIdle( void ) const; - animFlags_t GetAnimFlags( void ) const; - idAnimator* GetAnimator(); - void FinishAction(const idStr& actionname); - const char * WaitState( void ) const; - void SetWaitState( const char *_waitstate ); - - -private: - idStr waitState; - idActor * self; - idAnimator * animator; - idThread * thread; - int channel; - bool disabled; -}; - -typedef struct { - jointModTransform_t mod; - jointHandle_t from; - jointHandle_t to; -} copyJoints_t; - -struct CrashLandResult -{ - int damageDealt; // contains the damage done to the actor - bool hasLanded; // true if the actor hit the ground after a fall this frame -}; - -enum GreetingState -{ - ECannotGreet = 0, // actor is not able to greet (e.g. spiders) - ENotGreetingAnybody, // actor is currently not greeting anybody (free) - EWaitingForGreeting, // actor is receiving a greeting from somebody else - EGoingToGreet, // actor is about to greet somebody - EIsGreeting, // actor is currently playing its greeting sound - EAfterGreeting, // actor is in the small pause after greeting - ENumAIGreetingStates, // invalid state -}; - -#define TDM_HEAD_ENTITYDEF "atdm:ai_head_base" - -class idActor : public idAFEntity_Gibbable { -public: - CLASS_PROTOTYPE( idActor ); - - int rank; // monsters don't fight back if the attacker's rank is higher - /** - * TDM: Defines the type of the AI (human, beast, undead, bot, etc) - **/ - int m_AItype; - /** - * TDM: Whether this actor is considered a non-combatant - **/ - bool m_Innocent; - idMat3 viewAxis; // view axis of the actor - - idLinkList enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him - idLinkList enemyList; // list of characters that have targeted the player as their enemy - - // The greeting state this actor is currently in (to coordinate greeting barks in between actors) - GreetingState greetingState; - - /** - * TDM: Moved up from idAI - * These ranges are the best guess for the max range at which the AI can hit - * an enemy. melee_range_unarmed is the range with no weapon, read from - * the melee_range spawnarg on the AI. - * If the AI has no weapon, melee_range = melee_range_unarmed. - * melee_range includes the reach of the current weapon, updated when weapons are attached - **/ - float melee_range_unarmed; // potential - float melee_range; // includes reach of current weapon - /** - * grayman #2655 - some AI need a different vertical melee_range, i.e. the werebeast crawler - **/ - float melee_range_vert; - /** - * This should roughly correspond to the time it takes them to swing the weapon - * In seconds (read from spawnarg in milliseconds and converted) - * Currently it is used for AI predicting whether they will be able to hit - * their enemy in the future if they start our attack now - * It may be used for other things later - **/ - float m_MeleePredictedAttTime; - // and without a weapon (need to store in case they get disarmed somehow) - float m_MeleePredictedAttTimeUnarmed; - - - /** - * Stores what this actor is currently doing in melee combat - * ishtvan: Made public to avoid lots of gets/sets - **/ - CMeleeStatus m_MeleeStatus; - /** - * Number representing the ability of this actor to inflict melee damage - * multiplies the baseline melee damage set on the weapon by this amount - **/ - float m_MeleeDamageMult; - /** - * Melee timing: Time between the backswing and forward swing - * Actual number is random, between this min and max - * Number is in milliseconds - **/ - int m_MeleeHoldTimeMin; - int m_MeleeHoldTimeMax; - int m_MeleeCurrentHoldTime; - /** - * Melee timing: Max time that we will hold a parry, waiting for the attack - **/ - int m_MeleeParryHoldMin; - int m_MeleeParryHoldMax; - int m_MeleeCurrentParryHold; - /** - * Melee timing: Time between subsequent attacks (in milliseconds) - **/ - int m_MeleeAttackRecoveryMin; - int m_MeleeAttackRecoveryMax; - int m_MeleeCurrentAttackRecovery; - /** - * Melee timing: Time after being parried or getting hit that we can attack (longer than the normal time) - **/ - int m_MeleeAttackLongRecoveryMin; - int m_MeleeAttackLongRecoveryMax; - int m_MeleeCurrentAttackLongRecovery; - /** - * Melee timing: Time after last action that we can parry (fairly short) - * TODO: the name of this could be confusing, we're not recovering FROM a parry - **/ - int m_MeleeParryRecoveryMin; - int m_MeleeParryRecoveryMax; - int m_MeleeCurrentParryRecovery; - /** - * Melee timing: Time after a successful (or aborted) parry that we can attack - **/ - int m_MeleeRiposteRecoveryMin; - int m_MeleeRiposteRecoveryMax; - int m_MeleeCurrentRiposteRecovery; - /** - * Melee timing: Time delay between when we decide to parry and when the anim starts - * Acts as a human reaction time to an oncoming attack - **/ - int m_MeleePreParryDelayMin; - int m_MeleePreParryDelayMax; - int m_MeleeCurrentPreParryDelay; - /** - * Same as above, but use a shorter delay when responding to repeated attacks - * along the same direction - **/ - int m_MeleeRepeatedPreParryDelayMin; - int m_MeleeRepeatedPreParryDelayMax; - int m_MeleeCurrentRepeatedPreParryDelay; - /** - * Controls how many times the attack has to be repeated in a row - * in order to use the faster response time - **/ - int m_MeleeNumRepAttacks; - /** - * Time duration over which the same attacks in a row have to occur - * in order to be anticipated and use faster response - **/ - int m_MeleeRepAttackTime; - /** - * Melee timing: Time delay between when we decide to stop parrying and when the animation goes - * Acts as a human reaction time to the cessation of an attack - **/ - int m_MeleePostParryDelayMin; - int m_MeleePostParryDelayMax; - int m_MeleeCurrentPostParryDelay; - /** - * Same as above, but use a shorter delay when responding to repeated attacks - * along the same direction - **/ - int m_MeleeRepeatedPostParryDelayMin; - int m_MeleeRepeatedPostParryDelayMax; - int m_MeleeCurrentRepeatedPostParryDelay; - - /** - * Correspondence between melee type and string name suffix of the action - **/ - static const char * MeleeTypeNames[ NUM_MELEE_TYPES ]; - - /** - * grayman #2345 - rank for path-finding - **/ - int m_pathRank; - - /** - * grayman #2728 - next time this actor can be kicked by another actor - **/ - int m_nextKickTime; - -public: - idActor( void ); - virtual ~idActor( void ); - - void Spawn( void ); - virtual void Restart( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Hide( void ); - virtual void Show( void ); - virtual int GetDefaultSurfaceType( void ) const; - virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); - - virtual bool LoadAF( void ); - void SetupBody( void ); - - void CheckBlink( void ); - - virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); - virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); - - // script state management - void ShutdownThreads( void ); - virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; - virtual idThread * ConstructScriptObject( void ); - virtual void UpdateScript(); - const function_t *GetScriptFunction( const char *funcname ); - void SetState( const function_t *newState ); - void SetState( const char *statename ); - - // vision testing - void SetEyeHeight( float height ); - float EyeHeight( void ) const; - idVec3 EyeOffset( void ) const; - virtual idVec3 GetEyePosition( void ) const; - virtual void GetViewPos( idVec3 &origin, idMat3 &axis ) const; - /** - * Sets the actor's field of view (doesn't apply to players) - * Input is horizontal FOV, vertical FOV. - * If no vertical is provided, it is assumed the same as the vertical - * - * Sets the FOV dot products to those of the half-angles of the full fov - **/ - void SetFOV( float fovHoriz, float fovVert = -1 ); - virtual bool CheckFOV( const idVec3 &pos ) const; - - /** - * greebo: This method returns TRUE, if the given entity is visible by this actor. - * For actor entities, the eye position is taken into account, for ordinary entities, - * the origin is taken. - * First, the origin/eye position is checked against the FOV of this actor, and second, - * a trace is performed from eye (this) to origin/eye (other entity). If the trace is - * blocked, the entity is considered hidden and the method returns FALSE. - */ - virtual bool CanSee( idEntity *ent, bool useFOV ) const; - bool PointVisible( const idVec3 &point ) const; - virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ); - - // damage - void SetupDamageGroups( void ); - // DarkMod: Added trace reference to damage - virtual void Damage - ( - idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision = NULL - ); - - /** - * Return the stealth damage multiplier - * Only used by derived class idAI - **/ - virtual float StealthDamageMult( void ) { return 1.0; }; - - /** - * Melee callbacks so the melee system can let the actor know what happened - * And to keep the melee status up to date - **/ - void MeleeAttackMissed( void ); - void MeleeAttackHit( idEntity *ent ); - void MeleeAttackParried( idEntity *owner, idEntity *weapon = NULL ); - void MeleeParrySuccess( idEntity *other ); - - /**************************************************************************************** - ===================== - idActor::CrashLand - handle collision(Falling) damage to AI/Players - Added by Richard Day - ===================== - // greebo: Changed return type: the amount of damage points is contained in the struct - ****************************************************************************************/ - CrashLandResult CrashLand( const idPhysics_Actor& physicsObj, const idVec3 &oldOrigin, const idVec3 &oldVelocity ); - - int GetDamageForLocation( int damage, int location ); - const char * GetDamageGroup( int location ); - void ClearPain( void ); - virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ); - - // greebo: Sets the "player is pushing something heavy" state to the given bool. - virtual void SetIsPushing(bool isPushing); - // Returns whether the player is currently pushing something heavy - virtual bool IsPushing(); - - // model/combat model/ragdoll - void SetCombatModel( void ); - idClipModel * GetCombatModel( void ) const; - virtual void LinkCombat( void ); - virtual void UnlinkCombat( void ); - bool StartRagdoll( void ); - void StopRagdoll( void ); - virtual bool UpdateAnimationControllers( void ); - - // delta view angles to allow movers to rotate the view of the actor - const idAngles & GetDeltaViewAngles( void ) const; - void SetDeltaViewAngles( const idAngles &delta ); - - bool HasEnemies( void ) const; - idActor * ClosestEnemyToPoint( const idVec3 &pos ); - idActor * EnemyWithMostHealth(); - /** - * Get closest enemy who is in the process of launching a melee attack - **/ - idActor * ClosestAttackingEnemy( bool bUseFOV ); - /** - * Returns the enum of the best parry given the attacks at the time - * If no attacking enemy is found, returns default of "RL" - * See dActor::MeleeTypeNames for the list of melee attack/parry names - **/ - EMeleeType GetBestParry( void ); - - virtual bool OnLadder( void ) const; - // Returns the elevator entity if the actor is standing on an elevator - // angua: if mustBeMoving is true, the elevator is only returned when it is moving - virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; - - virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const; - - /** - * Called when the given ent is about to be bound/attached to this actor. - **/ - void BindNotify( idEntity *ent ); - - /** - * Called when the given ent is about to be unbound/detached from this actor. - **/ - virtual void UnbindNotify( idEntity *ent ); - - /** - * Attach an entity. Entity spawnArgs checked for attachments are: - * "origin", "angles", and "joint". - * AttName is the optional name of the attachment for indexing purposes (e.g., "melee_weapon") - * Ent is the entity being attached - * PosName is the optional position name to attach to. - **/ - virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); - - /** - * greebo: Returns the number of attached melee weapons. These are the entities - * with the according spawnarg "is_weapon_melee" etc. set to "1". - */ - int GetNumMeleeWeapons(); - int GetNumRangedWeapons(); - - ID_INLINE float GetMeleeRange() const - { - return melee_range; - } - - /** - * greebo: Returns TRUE whether combat is allowed for the given type. - * Even though an actor has a weapon attached, it might still be sheathed and - * combat is "disabled" therefore, which is represented by the AttackFlag. - */ - bool GetAttackFlag(ECombatType type) const; - void SetAttackFlag(ECombatType type, bool enabled); - - virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); - - virtual renderView_t * GetRenderView(); - - // animation state control - int GetAnim( int channel, const char *name ); - idAnimator* GetAnimatorForChannel(int channel); - - // greebo: Searches the given dictionary for animation replacement spawnargs and applies them to this actor - void LoadReplacementAnims(const idDict& spawnArgs); - - const char* LookupReplacementAnim( const char *name ); - - // greebo: Replaces the given animToReplace by the animation replacementAnim - void SetReplacementAnim(const idStr& animToReplace, const idStr& replacementAnim); - - // greebo: Removes any replacement for the given anim. - void RemoveReplacementAnim(const idStr& replacedAnim); - void StopAnim(int channel, int frames); - void UpdateAnimState( void ); - void SetAnimState( int channel, const char *name, int blendFrames ); - const char * GetAnimState( int channel ) const; - bool InAnimState( int channel, const char *name ) const; - const char * WaitState( void ) const; - const char * WaitState( int channel ) const; - void SetWaitState( const char *_waitstate ); - void SetWaitState( int channel, const char *_waitstate ); - bool AnimDone( int channel, int blendFrames ) const; - virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName ); - - /** - * Returns the modification to movement volume based on the movement type - * (crouch walk, creep, run, etc) - * Called in derived classes idPlayer and idAI. - **/ - virtual float GetMovementVolMod( void ) { return 0; }; - - virtual bool IsKnockedOut( void ) { return false; }; - - virtual bool CanUseElevators() const { return canUseElevators; } - - /** - * greebo: This gets called by the pathing routine to let the actor - * reconsider the "forbidden" status of the given area. After some time - * AI should be able to re-try opening locked doors otherwise the door's AAS area - * stays flagged as "forbidden" for all times. - * - * Note: This method is overriden by the AI class. - * - * @returns: TRUE if the area is now considered as "allowed", FALSE otherwise. - */ - virtual bool ReEvaluateArea(int areaNum); - -public: - // Moved from player/AI to here - idScriptBool AI_DEAD; - -protected: - - /* CrashLand variables Added by Richard Day */ - - float m_damage_thresh_min; // min damage. anything at or below this does 0 damage - float m_damage_thresh_hard; // any damage above this is considered "hard" - float m_delta_scale; ///< scale the damage based on this. delta is divide by this - - - friend class idAnimState; - - float m_fovDotHoriz; // cos( Horizontal fov [degrees] ) - float m_fovDotVert; // cos( Vertical fov [degrees] ) - idVec3 eyeOffset; // offset of eye relative to physics origin - idVec3 modelOffset; // offset of visual model relative to the physics origin - idVec3 mHeadModelOffset; // offset for the head - - idAngles deltaViewAngles; // delta angles relative to view input angles - - int pain_debounce_time; // next time the actor can show pain - int pain_delay; // time between playing pain sound - int pain_threshold; // how much damage monster can take at any one time before playing pain animation - - idStrList damageGroups; // body damage groups - idList damageScale; // damage scale per damage group - - // greebo: If not -1, the actor will fire a script when its health falls below this value - int lowHealthThreshold; - idStr lowHealthScript; - - /** - * Alertnum threshold above which sneak attacks won't work, - **/ - float m_SneakAttackThresh; - /** - * Damage multiplier applied for sneak attack damage - **/ - float m_SneakAttackMult; - - bool use_combat_bbox; // whether to use the bounding box for combat collision - idEntityPtr head; - idList copyJoints; // copied from the body animation to the head model - - // state variables - const function_t *state; - const function_t *idealState; - -protected: - - // joint handles - jointHandle_t leftEyeJoint; - jointHandle_t rightEyeJoint; - jointHandle_t soundJoint; - - idIK_Walk walkIK; - - idStr animPrefix; - idStr painAnim; - - // blinking - int blink_anim; - int blink_time; - int blink_min; - int blink_max; - - // script variables - idThread * scriptThread; - idStr waitState; - idAnimState headAnim; - idAnimState torsoAnim; - idAnimState legsAnim; - - bool allowPain; - bool allowEyeFocus; - bool finalBoss; - - int painTime; - - // greebo: Is set to TRUE if this actor can use elevators. - bool canUseElevators; - -// idList m_Attachments; - - // Maps animation names to the names of their replacements - idDict m_replacementAnims; - - /** - * This is the set of attack flags. If the corresponding enum value ECombatType - * is present in this set, the actor is ready for attacking with that attack type. - */ - std::set m_AttackFlags; - - /** - * Movement volume modifiers. Ones for the player are taken from - * cvars (for now), ones for AI are taken from spawnargs. - * Walking and not crouching is the default volume. - **/ - - float m_stepvol_walk; - float m_stepvol_run; - float m_stepvol_creep; - - float m_stepvol_crouch_walk; - float m_stepvol_crouch_creep; - float m_stepvol_crouch_run; - - virtual void Gib( const idVec3 &dir, const char *damageDefName ); - - // removes attachments with "remove" set for when character dies - void RemoveAttachments( void ); - - // copies animation from body to head joints - void CopyJointsFromBodyToHead( void ); - - /** - * Updates the volume offsets for various movement modes - * (eg walk, run, creep + crouch ). - * Used by derived classes idPlayer and idAI. - **/ - virtual void UpdateMoveVolumes( void ) {}; - - /** - * TestKnockoutBlow, only defined in derived classes - * Returns true if going from conscious to unconscious - **/ - virtual bool TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ) - { - return false; - }; - - /** - * greebo: Plays the footstep sound according to the current movement type. - * Note: AI and Player are overriding this method. - */ - virtual void PlayFootStepSound(); // empty default implementation - - // Links script variables (is overridden by idAI and idPlayer) - virtual void LinkScriptVariables(); - -private: - void SyncAnimChannels( int channel, int syncToChannel, int blendFrames ); - void FinishSetup( void ); - - /** - * greebo: This loads the vocal set (the snd_* spawnargs) into this entity's spawnargs. - */ - void LoadVocalSet(); - - /** - * ishtvan: Load a set of melee difficulty options - **/ - void LoadMeleeSet(); - - void SetupHead( void ); - -public: - void Event_EnableEyeFocus( void ); - void Event_DisableEyeFocus( void ); - void Event_Footstep( void ); - void Event_EnableWalkIK( void ); - void Event_DisableWalkIK( void ); - void Event_EnableLegIK( int num ); - void Event_DisableLegIK( int num ); - void Event_SetAnimPrefix( const char *name ); - void Event_LookAtEntity( idEntity *ent, float duration ); - void Event_PreventPain( float duration ); - void Event_DisablePain( void ); - void Event_EnablePain( void ); - void Event_GetPainAnim( void ); - void Event_StopAnim( int channel, int frames ); - void Event_PlayAnim( int channel, const char *name ); - void Event_PauseAnim( int channel, bool bPause ); - void Event_AnimIsPaused( int channel ); - void Event_PlayCycle( int channel, const char *name ); - void Event_IdleAnim( int channel, const char *name ); - void Event_SetSyncedAnimWeight( int channel, int anim, float weight ); - void Event_SyncAnimChannels(int fromChannel, int toChannel, float blendFrames); - void Event_OverrideAnim( int channel ); - void Event_EnableAnim( int channel, int blendFrames ); - void Event_DisableAnimchannel( int channel ); - void Event_SetBlendFrames( int channel, int blendFrames ); - void Event_GetBlendFrames( int channel ); - void Event_AnimState( int channel, const char *name, int blendFrames ); - void Event_GetAnimState( int channel ); - void Event_InAnimState( int channel, const char *name ); - void Event_FinishAction( const char *name ); - void Event_FinishChannelAction(int channel, const char *name ); - void Event_AnimDone( int channel, int blendFrames ); - void Event_HasAnim( int channel, const char *name ); - void Event_CheckAnim( int channel, const char *animname ); - void Event_ChooseAnim( int channel, const char *animname ); - void Event_AnimLength( int channel, const char *animname ); - void Event_AnimDistance( int channel, const char *animname ); - void Event_HasEnemies( void ); - void Event_NextEnemy( idEntity *ent ); - void Event_ClosestEnemyToPoint( const idVec3 &pos ); - void Event_StopSound( int channel, int netsync ); - void Event_SetNextState( const char *name ); - void Event_SetState( const char *name ); - void Event_GetState( void ); - void Event_GetHead( void ); - void Event_GetEyePos( void ); - - // greebo: Moved these from idAI to here - void Event_SetHealth( float newHealth ); - void Event_GetHealth( void ); - - /** - * Attaches the entity and gives it the given attachment name - **/ - void Event_Attach( idEntity *ent, const char *AttName ); - /** - * Attaches the entity to the named position PosName and gives it the attachment name AttName - **/ - void Event_AttachToPos( idEntity *ent, const char *PosName, const char *AttName ); - void Event_GetAttachment( const char *AttName ); - void Event_GetAttachmentInd( int ind ); - void Event_GetNumAttachments( void ); - - // Returns the number of ranged/melee weapons attached to the calling script - void Event_GetNumMeleeWeapons(); - void Event_GetNumRangedWeapons(); - /** - * Registers the start of a given melee attack/parry - * Intended to be called from a script that also starts the animation - **/ - void Event_MeleeAttackStarted( int AttType ); - void Event_MeleeParryStarted( int ParType ); - /** Called when the melee action reaches the "hold" point **/ - void Event_MeleeActionHeld( void ); - /** Called when the melee action is released from the hold point **/ - void Event_MeleeActionReleased( void ); - /** Called when the animation for the melee action has finished **/ - void Event_MeleeActionFinished( void ); - /** Get the current melee action state **/ - void Event_GetMeleeActionState( void ); - /** Get the current melee action phase **/ - void Event_GetMeleeActionPhase( void ); - /** Get the current melee action type **/ - void Event_GetMeleeActionType( void ); - /** Get the time at which the previous melee action finished **/ - void Event_GetMeleeLastActTime( void ); - /** Called by script to get result of last melee action **/ - void Event_GetMeleeResult( void ); - /** Get the type of the last melee attack we were hit with (defaults to MELEETYPE_UNBLOCKABLE if we were not hit) **/ - void Event_GetMeleeLastHitByType( void ); - - /** - * Returns the melee type integer of the optimal melee parry given current attackers - * If no attackers are found within the FOV, - * returns a default of MELEETYPE_RL (sabre parry #4) - **/ - void Event_MeleeBestParry(); - /** - * Convert a melee type integer to the corresponding string name - **/ - void Event_MeleeNameForNum( int num ); - - // Script interface for replacing anims with different ones - void Event_SetReplacementAnim(const char* animToReplace, const char* replacementAnim); - void Event_RemoveReplacementAnim(const char* animName); - void Event_LookupReplacementAnim(const char* animName); - - void Event_GetAttackFlag(int combatType); - void Event_SetAttackFlag(int combatType, int enabled); - -#ifdef TIMING_BUILD -public: - int actorGetObstaclesTimer; - int actorGetPointOutsideObstaclesTimer; - int actorGetWallEdgesTimer; - int actorSortWallEdgesTimer; - int actorBuildPathTreeTimer; - int actorPrunePathTreeTimer; - int actorFindOptimalPathTimer; - int actorRouteToGoalTimer; - int actorSubSampleWalkPathTimer; - int actorWalkPathValidTimer; -#endif -}; - -#endif /* !__GAME_ACTOR_H__ */ diff --git a/game/af.cpp b/game/af.cpp deleted file mode 100644 index d7e5ea23a..000000000 --- a/game/af.cpp +++ /dev/null @@ -1,1395 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - - -/* -=============================================================================== - - Articulated figure controller. - -=============================================================================== -*/ -#define ARTICULATED_FIGURE_ANIM "af_pose" -#define POSE_BOUNDS_EXPANSION 5.0f - -/* -================ -idAF::idAF -================ -*/ -idAF::idAF( void ) { - self = NULL; - animator = NULL; - modifiedAnim = 0; - baseOrigin.Zero(); - baseAxis.Identity(); - poseTime = -1; - restStartTime = -1; - isLoaded = false; - isActive = false; - hasBindConstraints = false; -} - -/* -================ -idAF::~idAF -================ -*/ -idAF::~idAF( void ) { -} - -/* -================ -idAF::Save -================ -*/ -void idAF::Save( idSaveGame *savefile ) const { - savefile->WriteObject( self ); - savefile->WriteString( GetName() ); - savefile->WriteBool( hasBindConstraints ); - savefile->WriteVec3( baseOrigin ); - savefile->WriteMat3( baseAxis ); - savefile->WriteInt( poseTime ); - savefile->WriteInt( restStartTime ); - savefile->WriteBool( isLoaded ); - savefile->WriteBool( isActive ); - savefile->WriteStaticObject( physicsObj ); -} - -/* -================ -idAF::Restore -================ -*/ -void idAF::Restore( idRestoreGame *savefile ) { - savefile->ReadObject( reinterpret_cast( self ) ); - savefile->ReadString( name ); - savefile->ReadBool( hasBindConstraints ); - savefile->ReadVec3( baseOrigin ); - savefile->ReadMat3( baseAxis ); - savefile->ReadInt( poseTime ); - savefile->ReadInt( restStartTime ); - savefile->ReadBool( isLoaded ); - savefile->ReadBool( isActive ); - - animator = NULL; - modifiedAnim = 0; - - if ( self ) { - SetAnimator( self->GetAnimator() ); - Load( self, name ); - if ( hasBindConstraints ) { - AddBindConstraints(); - } - } - - savefile->ReadStaticObject( physicsObj ); - - if ( self ) { - if ( isActive ) { - // clear all animations - animator->ClearAllAnims( gameLocal.time, 0 ); - animator->ClearAllJoints(); - - // switch to articulated figure physics - self->RestorePhysics( &physicsObj ); - physicsObj.EnableClip(); - } - UpdateAnimation(); - } -} - -/* -================ -idAF::UpdateAnimation -================ -*/ -bool idAF::UpdateAnimation( void ) { - int i; - idVec3 origin, renderOrigin, bodyOrigin; - idMat3 axis, renderAxis, bodyAxis; - renderEntity_t *renderEntity; - - if ( !IsLoaded() ) { - return false; - } - - if ( !IsActive() ) { - return false; - } - - renderEntity = self->GetRenderEntity(); - if ( !renderEntity ) { - return false; - } - - if ( physicsObj.IsAtRest() ) { - if ( restStartTime == physicsObj.GetRestStartTime() ) { - return false; - } - restStartTime = physicsObj.GetRestStartTime(); - } - - // get the render position - origin = physicsObj.GetOrigin( 0 ); - axis = physicsObj.GetAxis( 0 ); - renderAxis = baseAxis.Transpose() * axis; - renderOrigin = origin - baseOrigin * renderAxis; - - // create an animation frame which reflects the current pose of the articulated figure - animator->InitAFPose(); - for ( i = 0; i < jointMods.Num(); i++ ) { - // check for the origin joint - if ( jointMods[i].jointHandle == 0 ) { - continue; - } - bodyOrigin = physicsObj.GetOrigin( jointMods[i].bodyId ); - bodyAxis = physicsObj.GetAxis( jointMods[i].bodyId ); - axis = jointMods[i].jointBodyAxis.Transpose() * ( bodyAxis * renderAxis.Transpose() ); - origin = ( bodyOrigin - jointMods[i].jointBodyOrigin * axis - renderOrigin ) * renderAxis.Transpose(); - - // TDM: Do not add AF jointmod if it has AF_JOINTMOD_NONE - // This is used for added bodies that we don't want to stretch the mesh - if( jointMods[i].jointMod != AF_JOINTMOD_NONE ) - animator->SetAFPoseJointMod( jointMods[i].jointHandle, jointMods[i].jointMod, axis, origin ); - } - animator->FinishAFPose( modifiedAnim, GetBounds().Expand( POSE_BOUNDS_EXPANSION ), gameLocal.time ); - animator->SetAFPoseBlendWeight( 1.0f ); - - return true; -} - -/* -================ -idAF::GetBounds - - returns bounds for the current pose -================ -*/ -idBounds idAF::GetBounds( void ) const { - int i; - idAFBody *body; - idVec3 origin, entityOrigin; - idMat3 axis, entityAxis; - idBounds bounds, b; - - bounds.Clear(); - - // get model base transform - origin = physicsObj.GetOrigin( 0 ); - axis = physicsObj.GetAxis( 0 ); - - entityAxis = baseAxis.Transpose() * axis; - entityOrigin = origin - baseOrigin * entityAxis; - - // get bounds relative to base - for ( i = 0; i < jointMods.Num(); i++ ) { - body = physicsObj.GetBody( jointMods[i].bodyId ); - origin = ( body->GetWorldOrigin() - entityOrigin ) * entityAxis.Transpose(); - axis = body->GetWorldAxis() * entityAxis.Transpose(); - b.FromTransformedBounds( body->GetClipModel()->GetBounds(), origin, axis ); - - bounds += b; - } - - return bounds; -} - -/* -================ -idAF::SetupPose - - Transforms the articulated figure to match the current animation pose of the given entity. -================ -*/ -void idAF::SetupPose( idEntity *ent, int time ) { - int i; - idAFBody *body; - idVec3 origin; - idMat3 axis; - idAnimator *animatorPtr; - renderEntity_t *renderEntity; - - if ( !IsLoaded() || !ent ) { - return; - } - - animatorPtr = ent->GetAnimator(); - if ( !animatorPtr ) { - return; - } - - renderEntity = ent->GetRenderEntity(); - if ( !renderEntity ) { - return; - } - - // if the animation is driven by the physics - if ( self->GetPhysics() == &physicsObj ) { - return; - } - - // if the pose was already updated this frame - if ( poseTime == time ) { - return; - } - poseTime = time; - - for ( i = 0; i < jointMods.Num(); i++ ) { - body = physicsObj.GetBody( jointMods[i].bodyId ); - animatorPtr->GetJointTransform( jointMods[i].jointHandle, time, origin, axis ); - body->SetWorldOrigin( renderEntity->origin + ( origin + jointMods[i].jointBodyOrigin * axis ) * renderEntity->axis ); - body->SetWorldAxis( jointMods[i].jointBodyAxis * axis * renderEntity->axis ); - } - - if ( isActive ) { - physicsObj.UpdateClipModels(); - } -} - -/* -================ -idAF::ChangePose - - Change the articulated figure to match the current animation pose of the given entity - and set the velocity relative to the previous pose. -================ -*/ -void idAF::ChangePose( idEntity *ent, int time ) { - int i; - float invDelta; - idAFBody *body; - idVec3 origin, lastOrigin; - idMat3 axis; - idAnimator *animatorPtr; - renderEntity_t *renderEntity; - -// if ( !IsLoaded() || !ent ) { - if ( !IsLoaded() || !ent || IsActive() ) { - return; - } - - animatorPtr = ent->GetAnimator(); - if ( !animatorPtr ) { - return; - } - - renderEntity = ent->GetRenderEntity(); - if ( !renderEntity ) { - return; - } - - // if the animation is driven by the physics - if ( self->GetPhysics() == &physicsObj ) { - return; - } - - // if the pose was already updated this frame - if ( poseTime == time ) { - return; - } - invDelta = 1.0f / MS2SEC( time - poseTime ); - poseTime = time; - - for ( i = 0; i < jointMods.Num(); i++ ) { - body = physicsObj.GetBody( jointMods[i].bodyId ); - animatorPtr->GetJointTransform( jointMods[i].jointHandle, time, origin, axis ); - lastOrigin = body->GetWorldOrigin(); - body->SetWorldOrigin( renderEntity->origin + ( origin + jointMods[i].jointBodyOrigin * axis ) * renderEntity->axis ); - body->SetWorldAxis( jointMods[i].jointBodyAxis * axis * renderEntity->axis ); - body->SetLinearVelocity( ( body->GetWorldOrigin() - lastOrigin ) * invDelta ); - } - - physicsObj.UpdateClipModels(); -} - -/* -================ -idAF::EntitiesTouchingAF -================ -*/ -int idAF::EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const { - int i, j, numClipModels; - idAFBody *body; - idClipModel *cm; - idClipModel *clipModels[ MAX_GENTITIES ]; - int numTouching; - - if ( !IsLoaded() ) { - return 0; - } - - numTouching = 0; - numClipModels = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), -1, clipModels, MAX_GENTITIES ); - - for ( i = 0; i < jointMods.Num(); i++ ) { - body = physicsObj.GetBody( jointMods[i].bodyId ); - - // ishtvan: don't test bodies with their clipmodels disabled - if( !body->GetClipMask() ) - continue; - - for ( j = 0; j < numClipModels; j++ ) { - cm = clipModels[j]; - - if ( !cm || cm->GetEntity() == self ) { - continue; - } - - if ( !cm->IsTraceModel() ) { - continue; - } - - if ( !body->GetClipModel()->GetAbsBounds().IntersectsBounds( cm->GetAbsBounds() ) ) { - continue; - } - - // ishtvan: Apply the body clipmask - if ( gameLocal.clip.ContentsModel( body->GetWorldOrigin(), body->GetClipModel(), body->GetWorldAxis(), body->GetClipMask(), cm->Handle(), cm->GetOrigin(), cm->GetAxis() ) ) { - touchList[ numTouching ].touchedByBody = body; - touchList[ numTouching ].touchedClipModel = cm; - touchList[ numTouching ].touchedEnt = cm->GetEntity(); - numTouching++; - clipModels[j] = NULL; - } - } - } - - return numTouching; -} - -/* -================ -idAF::BodyForClipModelId -================ -*/ -int idAF::BodyForClipModelId( int id ) const { - if ( id >= 0 ) { - return id; - } else { - id = CLIPMODEL_ID_TO_JOINT_HANDLE( id ); - if ( id < jointBody.Num() ) { - return jointBody[id]; - } else { - return 0; - } - } -} - -/* -================ -idAF::JointForBody -================ -*/ -jointHandle_t idAF::JointForBody( int body ) -{ - /* tels: if no jointBody[i] == body, this - will return -1 */ - jointHandle_t joint = (jointHandle_t)-1; - for( int i=0; i < jointBody.Num(); i++ ) - { - if( jointBody[i] == body ) - { - joint = (jointHandle_t) i; - break; - } - } - return joint; -} - -/* -================ -idAF::BodyForJoint -================ -*/ -int idAF::BodyForJoint( jointHandle_t joint ) -{ - if ( joint < jointBody.Num() ) - return jointBody[ joint ]; - else - return 0; -} - -/* -================ -idAF::GetPhysicsToVisualTransform -================ -*/ -void idAF::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const { - origin = - baseOrigin; - axis = baseAxis.Transpose(); -} - -/* -================ -idAF::GetImpactInfo -================ -*/ -void idAF::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { - SetupPose( self, gameLocal.time ); - physicsObj.GetImpactInfo( BodyForClipModelId( id ), point, info ); -} - -/* -================ -idAF::ApplyImpulse -================ -*/ -void idAF::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - SetupPose( self, gameLocal.time ); - physicsObj.ApplyImpulse( BodyForClipModelId( id ), point, impulse ); -} - -/* -================ -idAF::AddForce -================ -*/ -void idAF::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { - SetupPose( self, gameLocal.time ); - physicsObj.AddForce( BodyForClipModelId( id ), point, force ); -} - -/* -================ -idAF::AddBody - - Adds a body. -================ -*/ -void idAF::AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod ) { - int index; - jointHandle_t handle; - idVec3 origin; - idMat3 axis; - - handle = animator->GetJointHandle( jointName ); - if ( handle == INVALID_JOINT ) { - gameLocal.Error( "idAF for entity '%s' at (%s) modifies unknown joint '%s'", self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), jointName ); - } - - assert( handle < animator->NumJoints() ); - origin = joints[ handle ].ToVec3(); - axis = joints[ handle ].ToMat3(); - - index = jointMods.Num(); - jointMods.SetNum( index + 1, false ); - jointMods[index].bodyId = physicsObj.GetBodyId( body ); - jointMods[index].bodyName = body->GetName(); - jointMods[index].jointHandle = handle; - jointMods[index].jointMod = mod; - jointMods[index].jointBodyOrigin = ( body->GetWorldOrigin() - origin ) * axis.Transpose(); - jointMods[index].jointBodyAxis = body->GetWorldAxis() * axis.Transpose(); -} - -void idAF::AddBodyExtern -( - idAFEntity_Base *ent, idAFBody *bodyNew, - idAFBody *bodyExist, AFJointModType_t mod, - jointHandle_t joint -) -{ - int indexNew(0), indexExist(-1), matchID(0); - jointHandle_t tempJoint = INVALID_JOINT; - - idVec3 origin; - idMat3 axis; - - // if we are not given a joint, copy it from the existing body - if( joint != INVALID_JOINT ) - { - tempJoint = joint; - assert( tempJoint < animator->NumJoints() ); - } - else - { - matchID = physicsObj.GetBodyId( bodyExist ); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("idAF::AddBodyExtern: Existing body name is %s, id is %d\r", bodyExist->GetName().c_str(), matchID); - for( int i = 0; i < jointMods.Num(); i++ ) - { - if( jointMods[i].bodyId == matchID ) - { - tempJoint = jointMods[i].jointHandle; - if ( tempJoint == INVALID_JOINT ) - { - gameLocal.Error( "idAF for entity '%s' at (%s) modifies unknown joint %d", self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), (int) tempJoint ); - } - assert( tempJoint < animator->NumJoints() ); - break; - } - } - } - - if( tempJoint != INVALID_JOINT ) - { - ent->GetJointWorldTransform( tempJoint, gameLocal.time, origin, axis ); - - indexNew = jointMods.Num(); - jointMods.SetNum( indexNew + 1, false ); - jointMods[indexNew].bodyId = physicsObj.GetBodyId( bodyNew ); - jointMods[indexNew].bodyName = bodyNew->GetName(); - jointMods[indexNew].jointHandle = tempJoint; - jointMods[indexNew].jointMod = mod; - jointMods[indexNew].jointBodyOrigin = ( bodyNew->GetWorldOrigin() - origin ) * axis.Transpose(); - jointMods[indexNew].jointBodyAxis = bodyNew->GetWorldAxis() * axis.Transpose(); - } -} - -void idAF::DeleteBodyExtern( idAFEntity_Base *ent, const char *bodyName ) -{ - if( ent ) - { - for( int i = jointMods.Num() - 1; i >= 0; i-- ) - { - if( jointMods[i].bodyName == bodyName ) - { - //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Removed body %s from AF\r", bodyName ); - jointMods.RemoveIndex(i); - } - } - } - - // Refresh the bodyIDs in the list, since they will have changed - // When AF physics condenses the list when removing a body in the middle - for( int i = jointMods.Num() - 1; i >= 0; i-- ) - { - jointMods[i].bodyId = ent->GetAFPhysics()->GetBodyId( jointMods[i].bodyName ); - } -} - -/* -================ -idAF::SetBase - - Sets the base body. -================ -*/ -void idAF::SetBase( idAFBody *body, const idJointMat *joints ) { - physicsObj.ForceBodyId( body, 0 ); - baseOrigin = body->GetWorldOrigin(); - baseAxis = body->GetWorldAxis(); - AddBody( body, joints, animator->GetJointName( animator->GetFirstChild( "origin" ) ), AF_JOINTMOD_AXIS ); -} - -/* -================ -idAF::LoadBody -================ -*/ -bool idAF::LoadBody( const idDeclAF_Body *fb, const idJointMat *joints ) { - int id, i; - float length, mass; - idTraceModel trm; - idClipModel *clip; - idAFBody *body; - idMat3 axis, inertiaTensor; - idVec3 centerOfMass, origin; - idBounds bounds; - idList jointList; - - origin = fb->origin.ToVec3(); - axis = fb->angles.ToMat3(); - bounds[0] = fb->v1.ToVec3(); - bounds[1] = fb->v2.ToVec3(); - - switch( fb->modelType ) { - case TRM_BOX: { - trm.SetupBox( bounds ); - break; - } - case TRM_OCTAHEDRON: { - trm.SetupOctahedron( bounds ); - break; - } - case TRM_DODECAHEDRON: { - trm.SetupDodecahedron( bounds ); - break; - } - case TRM_CYLINDER: { - trm.SetupCylinder( bounds, fb->numSides ); - break; - } - case TRM_CONE: { - // place the apex at the origin - bounds[0].z -= bounds[1].z; - bounds[1].z = 0.0f; - trm.SetupCone( bounds, fb->numSides ); - break; - } - case TRM_BONE: { - // direction of bone - axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3(); - length = axis[2].Normalize(); - // axis of bone trace model - axis[2].NormalVectors( axis[0], axis[1] ); - axis[1] = -axis[1]; - // create bone trace model - trm.SetupBone( length, fb->width ); - break; - } - default: - assert( 0 ); - break; - } - trm.GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor ); - trm.Translate( -centerOfMass ); - origin += centerOfMass * axis; - - body = physicsObj.GetBody( fb->name ); - if ( body ) { - clip = body->GetClipModel(); - if ( !clip->IsEqual( trm ) ) { - clip = new idClipModel( trm ); - clip->SetContents( fb->contents ); - clip->Link( gameLocal.clip, self, 0, origin, axis ); - body->SetClipModel( clip ); - } - clip->SetContents( fb->contents ); - body->SetDensity( fb->density, fb->inertiaScale ); - body->SetWorldOrigin( origin ); - body->SetWorldAxis( axis ); - id = physicsObj.GetBodyId( body ); - } - else { - clip = new idClipModel( trm ); - clip->SetContents( fb->contents ); - clip->Link( gameLocal.clip, self, 0, origin, axis ); - body = new idAFBody( fb->name, clip, fb->density ); - if ( fb->inertiaScale != mat3_identity ) { - body->SetDensity( fb->density, fb->inertiaScale ); - } - id = physicsObj.AddBody( body ); - } - if ( fb->linearFriction != -1.0f ) { - body->SetFriction( fb->linearFriction, fb->angularFriction, fb->contactFriction ); - } - // TDM FIX: Remove MOVEABLE_CLIP flag that the parser seems to add in by default - body->SetClipMask( fb->clipMask & ~CONTENTS_MOVEABLECLIP ); - body->SetSelfCollision( fb->selfCollision ); - - if ( fb->jointName == "origin" ) { - SetBase( body, joints ); - } else { - AFJointModType_t mod; - if ( fb->jointMod == DECLAF_JOINTMOD_AXIS ) { - mod = AF_JOINTMOD_AXIS; - } else if ( fb->jointMod == DECLAF_JOINTMOD_ORIGIN ) { - mod = AF_JOINTMOD_ORIGIN; - } else if ( fb->jointMod == DECLAF_JOINTMOD_BOTH ) { - mod = AF_JOINTMOD_BOTH; - } else { - mod = AF_JOINTMOD_AXIS; - } - AddBody( body, joints, fb->jointName, mod ); - } - - if ( fb->frictionDirection.ToVec3() != vec3_origin ) { - body->SetFrictionDirection( fb->frictionDirection.ToVec3() ); - } - if ( fb->contactMotorDirection.ToVec3() != vec3_origin ) { - body->SetContactMotorDirection( fb->contactMotorDirection.ToVec3() ); - } - - // update table to find the nearest articulated figure body for a joint of the skeletal model - animator->GetJointList( fb->containedJoints, jointList ); - for( i = 0; i < jointList.Num(); i++ ) { - if ( jointBody[ jointList[ i ] ] != -1 ) { - gameLocal.Warning( "%s: joint '%s' is already contained by body '%s'", - name.c_str(), animator->GetJointName( (jointHandle_t)jointList[i] ), - physicsObj.GetBody( jointBody[ jointList[ i ] ] )->GetName().c_str() ); - } - jointBody[ jointList[ i ] ] = id; - } - - return true; -} - -/* -================ -idAF::LoadConstraint -================ -*/ -bool idAF::LoadConstraint( const idDeclAF_Constraint *fc ) { - idAFBody *body1, *body2; - idAngles angles; - idMat3 axis; - - body1 = physicsObj.GetBody( fc->body1 ); - body2 = physicsObj.GetBody( fc->body2 ); - - switch( fc->type ) { - case DECLAF_CONSTRAINT_FIXED: { - idAFConstraint_Fixed *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_Fixed( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - break; - } - case DECLAF_CONSTRAINT_BALLANDSOCKETJOINT: { - idAFConstraint_BallAndSocketJoint *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_BallAndSocketJoint( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - c->SetAnchor( fc->anchor.ToVec3() ); - c->SetFriction( fc->friction ); - switch( fc->limit ) { - case idDeclAF_Constraint::LIMIT_CONE: { - c->SetConeLimit( fc->limitAxis.ToVec3(), fc->limitAngles[0], fc->shaft[0].ToVec3() ); - break; - } - case idDeclAF_Constraint::LIMIT_PYRAMID: { - angles = fc->limitAxis.ToVec3().ToAngles(); - angles.roll = fc->limitAngles[2]; - axis = angles.ToMat3(); - c->SetPyramidLimit( axis[0], axis[1], fc->limitAngles[0], fc->limitAngles[1], fc->shaft[0].ToVec3() ); - break; - } - default: { - c->SetNoLimit(); - break; - } - } - break; - } - case DECLAF_CONSTRAINT_UNIVERSALJOINT: { - idAFConstraint_UniversalJoint *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_UniversalJoint( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - c->SetAnchor( fc->anchor.ToVec3() ); - c->SetShafts( fc->shaft[0].ToVec3(), fc->shaft[1].ToVec3() ); - c->SetFriction( fc->friction ); - switch( fc->limit ) { - case idDeclAF_Constraint::LIMIT_CONE: { - c->SetConeLimit( fc->limitAxis.ToVec3(), fc->limitAngles[0] ); - break; - } - case idDeclAF_Constraint::LIMIT_PYRAMID: { - angles = fc->limitAxis.ToVec3().ToAngles(); - angles.roll = fc->limitAngles[2]; - axis = angles.ToMat3(); - c->SetPyramidLimit( axis[0], axis[1], fc->limitAngles[0], fc->limitAngles[1] ); - break; - } - default: { - c->SetNoLimit(); - break; - } - } - break; - } - case DECLAF_CONSTRAINT_HINGE: { - idAFConstraint_Hinge *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_Hinge( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - c->SetAnchor( fc->anchor.ToVec3() ); - c->SetAxis( fc->axis.ToVec3() ); - c->SetFriction( fc->friction ); - switch( fc->limit ) { - case idDeclAF_Constraint::LIMIT_CONE: { - idVec3 left, up, axis, shaft; - fc->axis.ToVec3().OrthogonalBasis( left, up ); - axis = left * idRotation( vec3_origin, fc->axis.ToVec3(), fc->limitAngles[0] ); - shaft = left * idRotation( vec3_origin, fc->axis.ToVec3(), fc->limitAngles[2] ); - c->SetLimit( axis, fc->limitAngles[1], shaft ); - break; - } - default: { - c->SetNoLimit(); - break; - } - } - break; - } - case DECLAF_CONSTRAINT_SLIDER: { - idAFConstraint_Slider *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_Slider( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - c->SetAxis( fc->axis.ToVec3() ); - break; - } - case DECLAF_CONSTRAINT_SPRING: { - idAFConstraint_Spring *c; - c = static_cast(physicsObj.GetConstraint( fc->name )); - if ( c ) { - c->SetBody1( body1 ); - c->SetBody2( body2 ); - } - else { - c = new idAFConstraint_Spring( fc->name, body1, body2 ); - physicsObj.AddConstraint( c ); - } - c->SetAnchor( fc->anchor.ToVec3(), fc->anchor2.ToVec3() ); - c->SetSpring( fc->stretch, fc->compress, fc->damping, fc->restLength ); - c->SetLimit( fc->minLength, fc->maxLength ); - break; - } - default: break; - } - return true; -} - -/* -================ -GetJointTransform -================ -*/ -static bool GetJointTransform( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ) { - jointHandle_t joint; - - joint = reinterpret_cast(model)->GetJointHandle( jointName ); - if ( ( joint >= 0 ) && ( joint < reinterpret_cast(model)->NumJoints() ) ) { - origin = frame[ joint ].ToVec3(); - axis = frame[ joint ].ToMat3(); - return true; - } else { - return false; - } -} - -/* -================ -idAF::Load -================ -*/ -bool idAF::Load( idEntity *ent, const char *fileName ) { - int i, j; - const idDeclAF *file; - const idDeclModelDef *modelDef; - idRenderModel *model; - int numJoints; - idJointMat *joints; - - assert( ent ); - - self = ent; - physicsObj.SetSelf( self ); - - if ( animator == NULL ) { - gameLocal.Warning( "Couldn't load af '%s' for entity '%s' at (%s): NULL animator\n", name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - - name = fileName; - name.StripFileExtension(); - - file = static_cast( declManager->FindType( DECL_AF, name ) ); - if ( !file ) { - gameLocal.Warning( "Couldn't load af '%s' for entity '%s' at (%s)\n", name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - - if ( file->bodies.Num() == 0 || file->bodies[0]->jointName != "origin" ) { - gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no body which modifies the origin joint.", - name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - - modelDef = animator->ModelDef(); - if ( modelDef == NULL || modelDef->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no or defaulted modelDef '%s'", - name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), modelDef ? modelDef->GetName() : "" ); - return false; - } - - model = animator->ModelHandle(); - if ( model == NULL || model->IsDefaultModel() ) { - gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no or defaulted model '%s'", - name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), model ? model->Name() : "" ); - return false; - } - - // get the modified animation - modifiedAnim = animator->GetAnim( ARTICULATED_FIGURE_ANIM ); - if ( !modifiedAnim ) { - gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) has no modified animation '%s'", - name.c_str(), ent->name.c_str(), ent->GetPhysics()->GetOrigin().ToString(0), ARTICULATED_FIGURE_ANIM ); - return false; - } - - // create the animation frame used to setup the articulated figure - numJoints = animator->NumJoints(); - joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); - gameEdit->ANIM_CreateAnimFrame( model, animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset(), animator->RemoveOrigin() ); - - // set all vector positions from model joints - file->Finish( GetJointTransform, joints, animator ); - - // initialize articulated figure physics - physicsObj.SetGravity( gameLocal.GetGravity() ); - physicsObj.SetClipMask( file->clipMask ); - physicsObj.SetDefaultFriction( file->defaultLinearFriction, file->defaultAngularFriction, file->defaultContactFriction ); - physicsObj.SetSuspendSpeed( file->suspendVelocity, file->suspendAcceleration ); - physicsObj.SetSuspendTolerance( file->noMoveTime, file->noMoveTranslation, file->noMoveRotation ); - physicsObj.SetSuspendTime( file->minMoveTime, file->maxMoveTime ); - physicsObj.SetSelfCollision( file->selfCollision ); - - // clear the list with transforms from joints to bodies - jointMods.SetNum( 0, false ); - - // clear the joint to body conversion list - jointBody.AssureSize( animator->NumJoints() ); - for ( i = 0; i < jointBody.Num(); i++ ) { - jointBody[i] = -1; - } - - // delete any bodies in the physicsObj that are no longer in the idDeclAF - for ( i = 0; i < physicsObj.GetNumBodies(); i++ ) { - idAFBody *body = physicsObj.GetBody( i ); - for ( j = 0; j < file->bodies.Num(); j++ ) { - if ( file->bodies[j]->name.Icmp( body->GetName() ) == 0 ) { - break; - } - } - if ( j >= file->bodies.Num() ) { - physicsObj.DeleteBody( i ); - i--; - } - } - - // delete any constraints in the physicsObj that are no longer in the idDeclAF - for ( i = 0; i < physicsObj.GetNumConstraints(); i++ ) { - idAFConstraint *constraint = physicsObj.GetConstraint( i ); - for ( j = 0; j < file->constraints.Num(); j++ ) { - if ( file->constraints[j]->name.Icmp( constraint->GetName() ) == 0 && - file->constraints[j]->type == constraint->GetType() ) { - break; - } - } - if ( j >= file->constraints.Num() ) { - physicsObj.DeleteConstraint( i ); - i--; - } - } - - // load bodies from the file - for ( i = 0; i < file->bodies.Num(); i++ ) { - LoadBody( file->bodies[i], joints ); - } - - // load constraints from the file - for ( i = 0; i < file->constraints.Num(); i++ ) { - LoadConstraint( file->constraints[i] ); - } - - physicsObj.UpdateClipModels(); - - // check if each joint is contained by a body - for( i = 0; i < animator->NumJoints(); i++ ) { - if ( jointBody[i] == -1 ) { - gameLocal.Warning( "idAF::Load: articulated figure '%s' for entity '%s' at (%s) joint '%s' is not contained by a body", - name.c_str(), self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0), animator->GetJointName( (jointHandle_t)i ) ); - } - } - -#ifdef MOD_WATERPHYSICS - // load how the body will be floated in liquid - bool isFixedDensity; - if( ent->spawnArgs.GetBool( "fixedDensityBuoyancy", "1", isFixedDensity ) ) - physicsObj.SetFixedDensityBuoyancy( isFixedDensity ); - -// load liquid density from file - float liquidDensity; - if( ent->spawnArgs.GetFloat( "liquidDensity", "", liquidDensity ) ) - physicsObj.SetLiquidDensity( liquidDensity ); -#endif // MOD_WATERPHYSICS - - physicsObj.SetMass( file->totalMass ); - physicsObj.SetChanged(); - physicsObj.BuildTrees(); - - // disable the articulated figure for collision detection until activated - physicsObj.DisableClip(); - - isLoaded = true; - - physicsObj.SetNumOrigBodies( physicsObj.GetNumBodies() ); - physicsObj.SetNumOrigConstraints( physicsObj.GetNumConstraints() ); - - return true; -} - -/* -================ -idAF::Start -================ -*/ -void idAF::Start( void ) { - if ( !IsLoaded() ) { - return; - } - // clear all animations - animator->ClearAllAnims( gameLocal.time, 0 ); - animator->ClearAllJoints(); - // switch to articulated figure physics - self->SetPhysics( &physicsObj ); - // start the articulated figure physics simulation - physicsObj.EnableClip(); - physicsObj.Activate(); - isActive = true; -} - -/* -================ -idAF::TestSolid -================ -*/ -bool idAF::TestSolid( void ) const { - int i; - idAFBody *body; - trace_t trace; - idStr str; - bool solid; - - if ( !IsLoaded() ) { - return false; - } - - if ( !af_testSolid.GetBool() ) { - return false; - } - - solid = false; - - for ( i = 0; i < physicsObj.GetNumBodies(); i++ ) { - body = physicsObj.GetBody( i ); - if ( gameLocal.clip.Translation( trace, body->GetWorldOrigin(), body->GetWorldOrigin(), body->GetClipModel(), body->GetWorldAxis(), body->GetClipMask(), self ) ) { - float depth = idMath::Fabs( trace.c.point * trace.c.normal - trace.c.dist ); - - body->SetWorldOrigin( body->GetWorldOrigin() + trace.c.normal * ( depth + 8.0f ) ); - - gameLocal.DWarning( "%s: body '%s' stuck in %d (normal = %.2f %.2f %.2f, depth = %.2f)", self->name.c_str(), - body->GetName().c_str(), trace.c.contents, trace.c.normal.x, trace.c.normal.y, trace.c.normal.z, depth ); - solid = true; - - } - } - return solid; -} - -/* -================ -idAF::StartFromCurrentPose -================ -*/ -void idAF::StartFromCurrentPose( int inheritVelocityTime ) { - - if ( !IsLoaded() ) { - return; - } - - // if the ragdoll should inherit velocity from the animation - if ( inheritVelocityTime > 0 ) { - - // make sure the ragdoll is at rest - physicsObj.PutToRest(); - - // set the pose for some time back - SetupPose( self, gameLocal.time - inheritVelocityTime ); - - // change the pose for the current time and set velocities - ChangePose( self, gameLocal.time ); - } - else { - // transform the articulated figure to reflect the current animation pose - SetupPose( self, gameLocal.time ); - } - - physicsObj.UpdateClipModels(); - - TestSolid(); - - Start(); - - UpdateAnimation(); - - // update the render entity origin and axis - self->UpdateModel(); - - // make sure the renderer gets the updated origin and axis - self->Present(); -} - -/* -================ -idAF::Stop -================ -*/ -void idAF::Stop( void ) { - // disable the articulated figure for collision detection - physicsObj.UnlinkClip(); - isActive = false; -} - -/* -================ -idAF::Rest -================ -*/ -void idAF::Rest( void ) { - physicsObj.PutToRest(); -} - -/* -================ -idAF::SetConstraintPosition - - Only moves constraints that bind the entity to another entity. -================ -*/ -void idAF::SetConstraintPosition( const char *name, const idVec3 &pos ) { - idAFConstraint *constraint; - - constraint = GetPhysics()->GetConstraint( name ); - - if ( !constraint ) { - gameLocal.Warning( "can't find a constraint with the name '%s'", name ); - return; - } - - if ( constraint->GetBody2() != NULL ) { - gameLocal.Warning( "constraint '%s' does not bind to another entity", name ); - return; - } - - switch( constraint->GetType() ) { - case CONSTRAINT_BALLANDSOCKETJOINT: { - idAFConstraint_BallAndSocketJoint *bs = static_cast(constraint); - bs->Translate( pos - bs->GetAnchor() ); - break; - } - case CONSTRAINT_UNIVERSALJOINT: { - idAFConstraint_UniversalJoint *uj = static_cast(constraint); - uj->Translate( pos - uj->GetAnchor() ); - break; - } - case CONSTRAINT_HINGE: { - idAFConstraint_Hinge *hinge = static_cast(constraint); - hinge->Translate( pos - hinge->GetAnchor() ); - break; - } - default: { - gameLocal.Warning( "cannot set the constraint position for '%s'", name ); - break; - } - } -} - -/* -================ -idAF::SaveState -================ -*/ -void idAF::SaveState( idDict &args ) const { - int i; - idAFBody *body; - idStr key, value; - - for ( i = 0; i < jointMods.Num(); i++ ) { - body = physicsObj.GetBody( jointMods[i].bodyId ); - - key = "body " + body->GetName(); - value = body->GetWorldOrigin().ToString( 8 ); - value += " "; - value += body->GetWorldAxis().ToAngles().ToString( 8 ); - args.Set( key, value ); - } -} - -/* -================ -idAF::LoadState -================ -*/ -void idAF::LoadState( const idDict &args ) { - const idKeyValue *kv; - idStr name; - idAFBody *body; - idVec3 origin; - idAngles angles; - - kv = args.MatchPrefix( "body ", NULL ); - while ( kv ) { - - name = kv->GetKey(); - name.Strip( "body " ); - body = physicsObj.GetBody( name ); - if ( body ) { - sscanf( kv->GetValue(), "%f %f %f %f %f %f", &origin.x, &origin.y, &origin.z, &angles.pitch, &angles.yaw, &angles.roll ); - body->SetWorldOrigin( origin ); - body->SetWorldAxis( angles.ToMat3() ); - } else { - gameLocal.Warning("Unknown body part %s in articulated figure %s", name.c_str(), this->name.c_str()); - } - - kv = args.MatchPrefix( "body ", kv ); - } - - physicsObj.UpdateClipModels(); -} - -/* -================ -idAF::AddBindConstraints -================ -*/ -void idAF::AddBindConstraints( void ) { - const idKeyValue *kv; - idStr name; - idAFBody *body; - idLexer lexer; - idToken type, bodyName, jointName; - idVec3 origin, renderOrigin; - idMat3 axis, renderAxis; - - if ( !IsLoaded() ) { - return; - } - - const idDict &args = self->spawnArgs; - - // get the render position - origin = physicsObj.GetOrigin( 0 ); - axis = physicsObj.GetAxis( 0 ); - renderAxis = baseAxis.Transpose() * axis; - renderOrigin = origin - baseOrigin * renderAxis; - - // parse all the bind constraints - for ( kv = args.MatchPrefix( "bindConstraint ", NULL ); kv; kv = args.MatchPrefix( "bindConstraint ", kv ) ) { - name = kv->GetKey(); - name.Strip( "bindConstraint " ); - - lexer.LoadMemory( kv->GetValue(), kv->GetValue().Length(), kv->GetKey() ); - lexer.ReadToken( &type ); - - lexer.ReadToken( &bodyName ); - body = physicsObj.GetBody( bodyName ); - if ( !body ) { - gameLocal.Warning( "idAF::AddBindConstraints: body '%s' not found on entity '%s'", bodyName.c_str(), self->name.c_str() ); - lexer.FreeSource(); - continue; - } - - if ( type.Icmp( "fixed" ) == 0 ) { - idAFConstraint_Fixed *c; - - c = new idAFConstraint_Fixed( name, body, NULL ); - physicsObj.AddConstraint( c ); - } - else if ( type.Icmp( "ballAndSocket" ) == 0 ) { - idAFConstraint_BallAndSocketJoint *c; - - c = new idAFConstraint_BallAndSocketJoint( name, body, NULL ); - physicsObj.AddConstraint( c ); - lexer.ReadToken( &jointName ); - - jointHandle_t joint = animator->GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Warning( "idAF::AddBindConstraints: joint '%s' not found", jointName.c_str() ); - } - - animator->GetJointTransform( joint, gameLocal.time, origin, axis ); - c->SetAnchor( renderOrigin + origin * renderAxis ); - } - else if ( type.Icmp( "universal" ) == 0 ) { - idAFConstraint_UniversalJoint *c; - - c = new idAFConstraint_UniversalJoint( name, body, NULL ); - physicsObj.AddConstraint( c ); - lexer.ReadToken( &jointName ); - - jointHandle_t joint = animator->GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Warning( "idAF::AddBindConstraints: joint '%s' not found", jointName.c_str() ); - } - animator->GetJointTransform( joint, gameLocal.time, origin, axis ); - c->SetAnchor( renderOrigin + origin * renderAxis ); - c->SetShafts( idVec3( 0, 0, 1 ), idVec3( 0, 0, -1 ) ); - } - else { - gameLocal.Warning( "idAF::AddBindConstraints: unknown constraint type '%s' on entity '%s'", type.c_str(), self->name.c_str() ); - } - - lexer.FreeSource(); - } - - hasBindConstraints = true; -} - -/* -================ -idAF::RemoveBindConstraints -================ -*/ -void idAF::RemoveBindConstraints( void ) { - const idKeyValue *kv; - - if ( !IsLoaded() ) { - return; - } - - const idDict &args = self->spawnArgs; - idStr name; - - kv = args.MatchPrefix( "bindConstraint ", NULL ); - while ( kv ) { - name = kv->GetKey(); - name.Strip( "bindConstraint " ); - - if ( physicsObj.GetConstraint( name ) ) { - physicsObj.DeleteConstraint( name ); - } - - kv = args.MatchPrefix( "bindConstraint ", kv ); - } - - hasBindConstraints = false; -} diff --git a/game/af.h b/game/af.h deleted file mode 100644 index 42cf0bc82..000000000 --- a/game/af.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_AF_H__ -#define __GAME_AF_H__ - - -/* -=============================================================================== - - Articulated figure controller. - -=============================================================================== -*/ - -/* FORWRD DECLS */ -class idDeclAF_Body; -class idDeclAF_Constraint; - -typedef struct jointConversion_s { - int bodyId; // id of the body - idStr bodyName; // TDM: String name of body. Only used on add/remove for performance - jointHandle_t jointHandle; // handle of joint this body modifies - AFJointModType_t jointMod; // modify joint axis, origin or both - idVec3 jointBodyOrigin; // origin of body relative to joint - idMat3 jointBodyAxis; // axis of body relative to joint -} jointConversion_t; - -typedef struct afTouch_s { - idEntity * touchedEnt; - idClipModel * touchedClipModel; - idAFBody * touchedByBody; -} afTouch_t; - -class idAF { -public: - idAF( void ); - virtual ~idAF( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void SetAnimator( idAnimator *a ) { animator = a; } - bool Load( idEntity *ent, const char *fileName ); - bool IsLoaded( void ) const { return isLoaded && self != NULL; } - const char * GetName( void ) const { return name.c_str(); } - void SetupPose( idEntity *ent, int time ); - void ChangePose( idEntity *ent, int time ); - int EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const; - void Start( void ); - void StartFromCurrentPose( int inheritVelocityTime ); - void Stop( void ); - void Rest( void ); - bool IsActive( void ) const { return isActive; } - void SetConstraintPosition( const char *name, const idVec3 &pos ); - - idPhysics_AF * GetPhysics( void ) { return &physicsObj; } - const idPhysics_AF * GetPhysics( void ) const { return &physicsObj; } - idBounds GetBounds( void ) const; - bool UpdateAnimation( void ); - - void GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const; - void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); - void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); - int BodyForClipModelId( int id ) const; - /** - * Find the joint associated with the given body - **/ - jointHandle_t JointForBody( int body ); - int BodyForJoint( jointHandle_t joint ); - - void SaveState( idDict &args ) const; - void LoadState( const idDict &args ); - - void AddBindConstraints( void ); - void RemoveBindConstraints( void ); - - /** - * TDM: Allows adding a body not in the AF file, bodyNew. Must be referenced to an existing body in the AF file, bodyExist. - * Also needs the entity for which we are doing this. - **/ - void AddBodyExtern - ( idAFEntity_Base *ent, idAFBody *bodyNew, - idAFBody *bodyExist, AFJointModType_t mod, - jointHandle_t joint = INVALID_JOINT ); - - /** - * TDM: Delete an externally added body - * NOTE: Must remove the body on the AFPhysics object BEFORE calling this. - * Because this also refreshes the jointMod bodyID's based on the physics object. - **/ - void DeleteBodyExtern( idAFEntity_Base *ent, const char *bodyName ); - -protected: - idStr name; // name of the loaded .af file - idPhysics_AF physicsObj; // articulated figure physics - idEntity * self; // entity using the animated model - idAnimator * animator; // animator on entity - int modifiedAnim; // anim to modify - idVec3 baseOrigin; // offset of base body relative to skeletal model origin - idMat3 baseAxis; // axis of base body relative to skeletal model origin - idListjointMods; // list with transforms from skeletal model joints to articulated figure bodies - idList jointBody; // table to find the nearest articulated figure body for a joint of the skeletal model - int poseTime; // last time the articulated figure was transformed to reflect the current animation pose - int restStartTime; // time the articulated figure came to rest - bool isLoaded; // true when the articulated figure is properly loaded - bool isActive; // true if the articulated figure physics is active - bool hasBindConstraints; // true if the bind constraints have been added - -protected: - void SetBase( idAFBody *body, const idJointMat *joints ); - void AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod ); - - bool LoadBody( const idDeclAF_Body *fb, const idJointMat *joints ); - bool LoadConstraint( const idDeclAF_Constraint *fc ); - - bool TestSolid( void ) const; -}; - -#endif /* !__GAME_AF_H__ */ diff --git a/game/afentity.cpp b/game/afentity.cpp deleted file mode 100644 index 5e656f262..000000000 --- a/game/afentity.cpp +++ /dev/null @@ -1,3655 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -/* -=============================================================================== - - idMultiModelAF - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idMultiModelAF ) -END_CLASS - -/* -================ -idMultiModelAF::Spawn -================ -*/ -void idMultiModelAF::Spawn( void ) { - physicsObj.SetSelf( this ); -} - -/* -================ -idMultiModelAF::~idMultiModelAF -================ -*/ -idMultiModelAF::~idMultiModelAF( void ) { - int i; - - for ( i = 0; i < modelDefHandles.Num(); i++ ) { - if ( modelDefHandles[i] != -1 ) { - gameRenderWorld->FreeEntityDef( modelDefHandles[i] ); - modelDefHandles[i] = -1; - } - } -} - -/* -================ -idMultiModelAF::SetModelForId -================ -*/ -void idMultiModelAF::SetModelForId( int id, const idStr &modelName ) { - modelHandles.AssureSize( id+1, NULL ); - modelDefHandles.AssureSize( id+1, -1 ); - modelHandles[id] = renderModelManager->FindModel( modelName ); -} - -/* -================ -idMultiModelAF::Present -================ -*/ -void idMultiModelAF::Present( void ) -{ - int i; - - if( m_bFrobable ) - { - UpdateFrobState(); - UpdateFrobDisplay(); - } - - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) - { - return; - } - BecomeInactive( TH_UPDATEVISUALS ); - - for ( i = 0; i < modelHandles.Num(); i++ ) { - - if ( !modelHandles[i] ) { - continue; - } - - renderEntity.origin = physicsObj.GetOrigin( i ); - renderEntity.axis = physicsObj.GetAxis( i ); - renderEntity.hModel = modelHandles[i]; - renderEntity.bodyId = i; - - // add to refresh list - if ( modelDefHandles[i] == -1 ) { - modelDefHandles[i] = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandles[i], &renderEntity ); - } - } -} - -/* -================ -idMultiModelAF::Think -================ -*/ -void idMultiModelAF::Think( void ) { - RunPhysics(); - Present(); -} - -/* -====================== -idMultiModelAF::ParseAttachments -====================== -*/ -void idMultiModelAF::ParseAttachments( void ) -{ - return; -} - -/* -====================== -idMultiModelAF::ParseAttachmentsAF -====================== -*/ -void idMultiModelAF::ParseAttachmentsAF( void ) -{ - idEntity::ParseAttachments(); -} - - -/* -=============================================================================== - - idChain - -=============================================================================== -*/ - -CLASS_DECLARATION( idMultiModelAF, idChain ) -END_CLASS - -/* -================ -idChain::BuildChain - - builds a chain hanging down from the ceiling - the highest link is a child of the link below it etc. - this allows an object to be attached to multiple chains while keeping a single tree structure -================ -*/ -void idChain::BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld ) { - int i; - float halfLinkLength = linkLength * 0.5f; - idTraceModel trm; - idClipModel *clip; - idAFBody *body, *lastBody; - idAFConstraint_BallAndSocketJoint *bsj; - idAFConstraint_UniversalJoint *uj; - idVec3 org; - - // create a trace model - trm = idTraceModel( linkLength, linkWidth ); - trm.Translate( -trm.offset ); - - org = origin - idVec3( 0, 0, halfLinkLength ); - - lastBody = NULL; - for ( i = 0; i < numLinks; i++ ) { - - // add body - clip = new idClipModel( trm ); - clip->SetContents( CONTENTS_SOLID ); - clip->Link( gameLocal.clip, this, 0, org, mat3_identity ); - body = new idAFBody( name + idStr(i), clip, density ); - physicsObj.AddBody( body ); - - // visual model for body - SetModelForId( physicsObj.GetBodyId( body ), spawnArgs.GetString( "model" ) ); - - // add constraint - if ( bindToWorld ) { - if ( !lastBody ) { - uj = new idAFConstraint_UniversalJoint( name + idStr(i), body, lastBody ); - uj->SetShafts( idVec3( 0, 0, -1 ), idVec3( 0, 0, 1 ) ); - //uj->SetConeLimit( idVec3( 0, 0, -1 ), 30.0f ); - //uj->SetPyramidLimit( idVec3( 0, 0, -1 ), idVec3( 1, 0, 0 ), 90.0f, 30.0f ); - } - else { - uj = new idAFConstraint_UniversalJoint( name + idStr(i), lastBody, body ); - uj->SetShafts( idVec3( 0, 0, 1 ), idVec3( 0, 0, -1 ) ); - //uj->SetConeLimit( idVec3( 0, 0, 1 ), 30.0f ); - } - uj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) ); - uj->SetFriction( 0.9f ); - physicsObj.AddConstraint( uj ); - } - else { - if ( lastBody ) { - bsj = new idAFConstraint_BallAndSocketJoint( "joint" + idStr(i), lastBody, body ); - bsj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) ); - bsj->SetConeLimit( idVec3( 0, 0, 1 ), 60.0f, idVec3( 0, 0, 1 ) ); - physicsObj.AddConstraint( bsj ); - } - } - - org[2] -= linkLength; - - lastBody = body; - } -} - -/* -================ -idChain::Spawn -================ -*/ -void idChain::Spawn( void ) { - int numLinks; - float length, linkLength, linkWidth, density; - bool drop; - idVec3 origin; - - spawnArgs.GetBool( "drop", "0", drop ); - spawnArgs.GetInt( "links", "3", numLinks ); - spawnArgs.GetFloat( "length", idStr( numLinks * 32.0f ), length ); - spawnArgs.GetFloat( "width", "8", linkWidth ); - spawnArgs.GetFloat( "density", "0.2", density ); - linkLength = length / numLinks; - origin = GetPhysics()->GetOrigin(); - - // initialize physics - physicsObj.SetSelf( this ); - physicsObj.SetGravity( gameLocal.GetGravity() ); - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY ); - SetPhysics( &physicsObj ); - - BuildChain( "link", origin, linkLength, linkWidth, density, numLinks, !drop ); - - ParseAttachmentsAF(); -} - -/* -=============================================================================== - - idAFAttachment - -=============================================================================== -*/ - -CLASS_DECLARATION( idAnimatedEntity, idAFAttachment ) -END_CLASS - -/* -===================== -idAFAttachment::idAFAttachment -===================== -*/ -idAFAttachment::idAFAttachment( void ) { - body = NULL; - combatModel = NULL; - idleAnim = 0; - attachJoint = INVALID_JOINT; -} - -/* -===================== -idAFAttachment::~idAFAttachment -===================== -*/ -idAFAttachment::~idAFAttachment( void ) { - - StopSound( SND_CHANNEL_ANY, false ); - - delete combatModel; - combatModel = NULL; -} - -/* -===================== -idAFAttachment::Spawn -===================== -*/ -void idAFAttachment::Spawn( void ) { - idleAnim = animator.GetAnim( "idle" ); -} - -/* -===================== -idAFAttachment::SetBody -===================== -*/ -void idAFAttachment::SetBody( idEntity *bodyEnt, const char *model, jointHandle_t attachJoint ) -{ - bool bleed; - - body = bodyEnt; - this->attachJoint = attachJoint; - SetModel( model ); - fl.takedamage = true; - - bleed = body->spawnArgs.GetBool( "bleed" ); - spawnArgs.SetBool( "bleed", bleed ); - - // greebo: Add the body as frob peer - m_FrobPeers.AddUnique(bodyEnt->name); - - // ishtvan: Go through our bind children and copy the actor body info over to them - // might end up doing a few extra calls if GetTeamChildren is broken like we think, - // but that's okay, add extra check of direct bindmaster to prevent infinite recursion - idList children; - GetTeamChildren( &children ); - for( int i=0; i < children.Num(); i++ ) - { - if( !children[i]->IsType(idAFAttachment::Type) ) - continue; - if( !children[i]->IsBoundTo( this ) ) - continue; - else - { - CopyBodyTo( static_cast(children[i]) ); - } - } -} - -/* -===================== -idAFAttachment::ClearBody -===================== -*/ -void idAFAttachment::ClearBody( void ) { - body = NULL; - attachJoint = INVALID_JOINT; - Hide(); -} - -/* -===================== -idAFAttachment::GetBody -===================== -*/ -idEntity *idAFAttachment::GetBody( void ) const { - return body; -} - -/* -===================== -idAFAttachment::GetAttachJoint -===================== -*/ -jointHandle_t idAFAttachment::GetAttachJoint( void ) const -{ - return attachJoint; -} - -/** -* Return true if we can mantle this attachment, false otherwise. -**/ -bool idAFAttachment::IsMantleable() -{ - return (!body || body->IsMantleable()) && idEntity::IsMantleable(); -} - -/** -* idAFAttachment::BindNotify -**/ -void idAFAttachment::BindNotify( idEntity *ent ) -{ - // copy information over to a bound idAfAttachment - if( ent->IsType(idAFAttachment::Type) ) - { - CopyBodyTo( static_cast(ent) ); - } -} - -void idAFAttachment::UnbindNotify( idEntity *ent ) -{ - idEntity::UnbindNotify( ent ); - // remove ent from AF if it was dynamically added as an AF body - if( body && body->IsType(idAFEntity_Base::Type) ) - static_cast(body)->RemoveAddedEnt( ent ); -} - -void idAFAttachment::PostUnbind( void ) -{ - // no longer bound to an actor - body = NULL; - attachJoint = INVALID_JOINT; -} - -void idAFAttachment::DropOnRagdoll( void ) -{ - // some stuff copied from idAI::DropOnRagdoll - idEntity *ent = NULL; - int mask(0); - - // Drop TDM attachments - for( int i=0; ispawnArgs.GetBool( "drop_set_nonsolid" )) - { - int curContents = ent->GetPhysics()->GetContents(); - - // ishtvan: Also clear the CONTENTS_CORPSE flag (maybe this was a typo in original code?) - ent->GetPhysics()->SetContents(curContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE)); - - // also have to iterate thru stuff attached to this attachment - // ishtvan: left this commentd out because I'm not sure if GetTeamChildren is bugged or not - // don't want to accidentally set all attachments to the AI to nonsolid - /* - idList AttChildren; - ent->GetTeamChildren( &AttChildren ); - gameLocal.Printf("TEST: drop_set_nonsolid, Num team children = %d", AttChildren.Num() ); - for( int i=0; i < AttChildren.Num(); i++ ) - { - idPhysics *pChildPhys = AttChildren[i]->GetPhysics(); - if( pChildPhys == NULL ) - continue; - - int childContents = pChildPhys->GetContents(); - pChildPhys->SetContents( childContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); - } - */ - } - - bool bDrop = ent->spawnArgs.GetBool( "drop_when_ragdoll" ); - - if( !bDrop ) { - continue; - } - - bool bSetSolid = ent->spawnArgs.GetBool( "drop_add_contents_solid" ); - bool bSetCorpse = ent->spawnArgs.GetBool( "drop_add_contents_corpse" ); - bool bSetFrob = ent->spawnArgs.GetBool( "drop_set_frobable" ); - bool bExtinguish = ent->spawnArgs.GetBool("extinguish_on_drop", "0"); - - // Proceed with droppage - DetachInd( i ); - - if( bSetSolid ) - mask = CONTENTS_SOLID; - if( bSetCorpse ) - mask = mask | CONTENTS_CORPSE; - - if( mask ) - ent->GetPhysics()->SetContents( ent->GetPhysics()->GetContents() | mask ); - - if( bSetFrob ) - ent->m_bFrobable = true; - - // greebo: Check if we should extinguish the attachment, like torches - if ( bExtinguish ) - { - // Get the delay in milliseconds - int delay = SEC2MS(ent->spawnArgs.GetInt("extinguish_on_drop_delay", "3")); - if (delay < 0) { - delay = 0; - } - - // Schedule the extinguish event - ent->PostEventMS(&EV_ExtinguishLights, delay); - } - - ent->GetPhysics()->Activate(); - ent->m_droppedByAI = true; // grayman #1330 - } -} - -void idAFAttachment::CopyBodyTo( idAFAttachment *other ) -{ - if( body ) - { - idStr modelName = other->spawnArgs.GetString("model",""); - other->SetBody( body, modelName.c_str(), attachJoint ); - } -} - -/* -================ -idAFAttachment::Save - -archive object for savegame file -================ -*/ -void idAFAttachment::Save( idSaveGame *savefile ) const { - savefile->WriteObject( body ); - savefile->WriteInt( idleAnim ); - savefile->WriteJoint( attachJoint ); -} - -/* -================ -idAFAttachment::Restore - -unarchives object from save game file -================ -*/ -void idAFAttachment::Restore( idRestoreGame *savefile ) { - savefile->ReadObject( reinterpret_cast( body ) ); - savefile->ReadInt( idleAnim ); - savefile->ReadJoint( attachJoint ); - - SetCombatModel(); - LinkCombat(); -} - -/* -================ -idAFAttachment::Hide -================ -*/ -void idAFAttachment::Hide( void ) -{ - idEntity::Hide(); - - // ishtvan: Should hide any bind children of the head (copied from idActor) - idEntity *ent; - idEntity *next; - for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { - next = ent->GetNextTeamEntity(); - if ( ent->GetBindMaster() == this ) { - ent->Hide(); - if ( ent->IsType( idLight::Type ) ) { - static_cast( ent )->Off(); - } - } - } - - UnlinkCombat(); -} - -/* -================ -idAFAttachment::Show -================ -*/ -void idAFAttachment::Show( void ) -{ - idEntity::Show(); - - // ishtvan: Should show any bind children of the head (copied from idActor) - idEntity *ent; - idEntity *next; - - for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) { - next = ent->GetNextTeamEntity(); - if ( ent->GetBindMaster() == this ) { - ent->Show(); - if ( ent->IsType( idLight::Type ) ) { - static_cast( ent )->On(); - } - } - } - LinkCombat(); -} - -/* -============ -idAFAttachment::Damage - -Pass damage to body at the bindjoint -============ -*/ -void idAFAttachment::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, trace_t *tr ) -{ - trace_t *pTrace = NULL; - - if( tr ) - { - trace_t TraceCopy = *tr; - - //TDM Fix: Propagate the trace. - // Also, some things like KO check the endpoint of the trace rather than the "location" for the joint hit - // So change this in the trace to the attach joint on the body we're attached to. - TraceCopy.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ); - pTrace = &TraceCopy; - } - - if ( body ) - { - body->Damage( inflictor, attacker, dir, damageDefName, damageScale, attachJoint, pTrace ); - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AF Attachment %s passed along damage to actor %s at attachjoint %d \r", name.c_str(), body->name.c_str(), (int) attachJoint ); - } -} - -/* -================ -idAFAttachment::AddDamageEffect -================ -*/ -void idAFAttachment::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { - if ( body ) { - trace_t c = collision; - c.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ); - body->AddDamageEffect( c, velocity, damageDefName ); - } -} - -/* -================ -idAFAttachment::GetImpactInfo -================ -*/ -void idAFAttachment::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { - if ( body ) { - body->GetImpactInfo( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, info ); - } else { - idEntity::GetImpactInfo( ent, id, point, info ); - } -} - -/* -================ -idAFAttachment::ApplyImpulse -================ -*/ -void idAFAttachment::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - if ( body ) { - body->ApplyImpulse( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, impulse ); - } else { - idEntity::ApplyImpulse( ent, id, point, impulse ); - } -} - -/* -================ -idAFAttachment::AddForce -================ -*/ -void idAFAttachment::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { - if ( body ) { - body->AddForce( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, force ); - } else { - idEntity::AddForce( ent, id, point, force ); - } -} - -/* -================ -idAFAttachment::PlayIdleAnim -================ -*/ -void idAFAttachment::PlayIdleAnim( int blendTime ) { - if ( idleAnim && ( idleAnim != animator.CurrentAnim( ANIMCHANNEL_ALL )->AnimNum() ) ) { - animator.CycleAnim( ANIMCHANNEL_ALL, idleAnim, gameLocal.time, blendTime ); - } -} - -/* -================ -idAfAttachment::Think -================ -*/ -void idAFAttachment::Think( void ) { - idAnimatedEntity::Think(); - if ( thinkFlags & TH_UPDATEPARTICLES ) { - UpdateDamageEffects(); - } -} - -/* -================ -idAFAttachment::SetCombatModel -================ -*/ -void idAFAttachment::SetCombatModel( void ) { - if ( combatModel ) { - combatModel->Unlink(); - combatModel->LoadModel( modelDefHandle ); - } else { - combatModel = new idClipModel( modelDefHandle ); - } - - if (m_StimResponseColl->HasResponse()) - { - combatModel->SetContents( combatModel->GetContents() | CONTENTS_RESPONSE ); - } - - combatModel->SetOwner( body ); -} - -/* -================ -idAFAttachment::GetCombatModel -================ -*/ -idClipModel *idAFAttachment::GetCombatModel( void ) const { - return combatModel; -} - -/* -================ -idAFAttachment::LinkCombat -================ -*/ -void idAFAttachment::LinkCombat( void ) { - if ( fl.hidden ) { - return; - } - - if ( combatModel ) { - combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); - } -} - -/* -================ -idAFAttachment::UnlinkCombat -================ -*/ -void idAFAttachment::UnlinkCombat( void ) { - if ( combatModel ) { - combatModel->Unlink(); - } -} - -idEntity* idAFAttachment::GetResponseEntity() -{ - return body; -} - -/* -=============================================================================== - - idAFEntity_Base - -=============================================================================== -*/ - -const idEventDef EV_SetConstraintPosition( "SetConstraintPosition", "sv" ); -const idEventDef EV_GetLinearVelocityB( "getLinearVelocityB", "d", 'v' ); -const idEventDef EV_GetAngularVelocityB( "getAngularVelocityB", "d", 'v' ); -const idEventDef EV_SetLinearVelocityB( "setLinearVelocityB", "vd" ); -const idEventDef EV_SetAngularVelocityB( "setAngularVelocityB", "vd" ); -const idEventDef EV_GetNumBodies( "getNumBodies", NULL, 'd' ); -const idEventDef EV_RestoreAddedEnts( "restoreAddedEnts", NULL ); - -CLASS_DECLARATION( idAnimatedEntity, idAFEntity_Base ) - EVENT( EV_SetConstraintPosition, idAFEntity_Base::Event_SetConstraintPosition ) - EVENT( EV_GetLinearVelocityB, idAFEntity_Base::Event_GetLinearVelocityB ) - EVENT( EV_GetAngularVelocityB, idAFEntity_Base::Event_GetAngularVelocityB ) - EVENT( EV_SetLinearVelocityB, idAFEntity_Base::Event_SetLinearVelocityB ) - EVENT( EV_SetAngularVelocityB, idAFEntity_Base::Event_SetAngularVelocityB ) - EVENT( EV_GetNumBodies, idAFEntity_Base::Event_GetNumBodies ) - EVENT( EV_RestoreAddedEnts, idAFEntity_Base::RestoreAddedEnts ) - -END_CLASS - -static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f; -static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f; - -/* -================ -idAFEntity_Base::idAFEntity_Base -================ -*/ -idAFEntity_Base::idAFEntity_Base( void ) -{ - combatModel = NULL; - combatModelContents = 0; - nextSoundTime = 0; - spawnOrigin.Zero(); - spawnAxis.Identity(); - m_bGroundWhenDragged = false; - m_GroundBodyMinNum = 0; - m_bDragAFDamping = false; - m_bCollideWithTeam = true; - m_bAFPushMoveables = false; - m_AddedEnts.Clear(); -} - -/* -================ -idAFEntity_Base::~idAFEntity_Base -================ -*/ -idAFEntity_Base::~idAFEntity_Base( void ) -{ - delete combatModel; - combatModel = NULL; - m_GroundBodyList.Clear(); - m_AddedEnts.Clear(); -} - -/* -================ -idAFEntity_Base::Save -================ -*/ -void idAFEntity_Base::Save( idSaveGame *savefile ) const -{ - savefile->WriteInt( combatModelContents ); - savefile->WriteClipModel( combatModel ); - savefile->WriteVec3( spawnOrigin ); - savefile->WriteMat3( spawnAxis ); - savefile->WriteInt( nextSoundTime ); - - savefile->WriteBool( m_bGroundWhenDragged ); - savefile->WriteInt( m_GroundBodyList.Num() ); - for( int i = 0; i < m_GroundBodyList.Num(); i++ ) - savefile->WriteInt( m_GroundBodyList[i] ); - savefile->WriteInt( m_GroundBodyMinNum ); - savefile->WriteBool( m_bDragAFDamping ); - savefile->WriteBool( m_bCollideWithTeam ); - savefile->WriteBool( m_bAFPushMoveables ); - - savefile->WriteInt( m_AddedEnts.Num() ); - for( int j = 0; j < m_AddedEnts.Num(); j++ ) - { - m_AddedEnts[j].ent.Save( savefile ); - savefile->WriteString( m_AddedEnts[j].bodyName ); - savefile->WriteString( m_AddedEnts[j].AddedToBody ); - savefile->WriteInt( m_AddedEnts[j].entContents ); - savefile->WriteInt( m_AddedEnts[j].entClipMask ); - // Check the body contents and clipmask just before saving, instead of putting in - // the variables bodyContents and bodyClipMask. These are only used on restoring. - // go to hell, const correctness! - idAFEntity_Base *thisNoConst = const_cast(this); - idAFBody *body = thisNoConst->GetAFPhysics()->GetBody( m_AddedEnts[j].bodyName.c_str() ); - savefile->WriteInt( body->GetClipModel()->GetContents() ); - savefile->WriteInt( body->GetClipMask() ); - } - - af.Save( savefile ); -} - -/* -================ -idAFEntity_Base::Restore -================ -*/ -void idAFEntity_Base::Restore( idRestoreGame *savefile ) -{ - savefile->ReadInt( combatModelContents ); - savefile->ReadClipModel( combatModel ); - savefile->ReadVec3( spawnOrigin ); - savefile->ReadMat3( spawnAxis ); - savefile->ReadInt( nextSoundTime ); - LinkCombat(); - - savefile->ReadBool( m_bGroundWhenDragged ); - - int GroundBodyListNum; - savefile->ReadInt( GroundBodyListNum ); - m_GroundBodyList.SetNum( GroundBodyListNum ); - for( int i = 0; i < GroundBodyListNum; i++ ) - savefile->ReadInt( m_GroundBodyList[i] ); - - savefile->ReadInt( m_GroundBodyMinNum ); - savefile->ReadBool( m_bDragAFDamping ); - savefile->ReadBool( m_bCollideWithTeam ); - savefile->ReadBool( m_bAFPushMoveables ); - - int AddedEntsNum; - savefile->ReadInt( AddedEntsNum ); - m_AddedEnts.SetNum( AddedEntsNum ); - for( int j = 0; j < AddedEntsNum; j++ ) - { - m_AddedEnts[j].ent.Restore( savefile ); - savefile->ReadString( m_AddedEnts[j].bodyName ); - savefile->ReadString( m_AddedEnts[j].AddedToBody ); - savefile->ReadInt( m_AddedEnts[j].entContents ); - savefile->ReadInt( m_AddedEnts[j].entClipMask ); - savefile->ReadInt( m_AddedEnts[j].bodyContents ); - savefile->ReadInt( m_AddedEnts[j].bodyClipMask ); - } - - af.Restore( savefile ); - if( m_bAFPushMoveables ) - { - af.SetupPose( this, gameLocal.time ); - af.GetPhysics()->EnableClip(); - } - - // Schedule any added entities for re-adding when they have spawned - PostEventMS( &EV_RestoreAddedEnts, 0 ); -} - -/* -================ -idAFEntity_Base::Spawn -================ -*/ -void idAFEntity_Base::Spawn( void ) -{ - spawnOrigin = GetPhysics()->GetOrigin(); - spawnAxis = GetPhysics()->GetAxis(); - nextSoundTime = 0; - m_bGroundWhenDragged = spawnArgs.GetBool( "ground_when_dragged", "0" ); - m_GroundBodyMinNum = spawnArgs.GetInt( "ground_min_number", "0" ); - m_bDragAFDamping = spawnArgs.GetBool( "drag_af_damping", "0" ); - m_bCollideWithTeam = spawnArgs.GetBool( "af_collide_with_team", "1" ); // true by default - m_bAFPushMoveables = spawnArgs.GetBool( "af_push_moveables", "0" ); -} - -/* -================ -idAFEntity_Base::LoadAF -================ -*/ -bool idAFEntity_Base::LoadAF( void ) -{ - idStr fileName; - - if ( !spawnArgs.GetString( "articulatedFigure", "*unknown*", fileName ) ) { - return false; - } - - af.SetAnimator( GetAnimator() ); - if ( !af.Load( this, fileName ) ) { - gameLocal.Error( "idAFEntity_Base::LoadAF: Couldn't load af file '%s' on entity '%s'", fileName.c_str(), name.c_str() ); - } - - af.Start(); - - af.GetPhysics()->Rotate( spawnAxis.ToRotation() ); - af.GetPhysics()->Translate( spawnOrigin ); - - LoadState( spawnArgs ); - - af.UpdateAnimation(); - animator.CreateFrame( gameLocal.time, true ); - UpdateVisuals(); - - SetUpGroundingVars(); - - if( m_bAFPushMoveables ) - { - af.SetupPose( this, gameLocal.time ); - af.GetPhysics()->EnableClip(); - } - - return true; -} - -/* -================ -idAFEntity_Base::Think -================ -*/ -void idAFEntity_Base::Think( void ) -{ - if( !IsHidden() ) - { - RunPhysics(); - UpdateAnimation(); - } - if ( thinkFlags & TH_UPDATEVISUALS ) - { - Present(); - LinkCombat(); - } - -// TDM: Anim/AF physics mods, generalized behavior that originally was just on AI - - // Update the AF bodies for the anim if we are set to do that - if ( m_bAFPushMoveables && af.IsLoaded() - && !IsType(idAI::Type) && !IsHidden() - && animator.FrameHasChanged( gameLocal.time ) ) - { - af.ChangePose( this, gameLocal.time ); - - // copied from idAI::PushWithAF - afTouch_t touchList[ MAX_GENTITIES ]; - idEntity *pushed_ents[ MAX_GENTITIES ]; - idEntity *ent; - idVec3 vel( vec3_origin ); - int num_pushed(0), i, j; - - int num = af.EntitiesTouchingAF( touchList ); - for( i = 0; i < num; i++ ) - { - // skip projectiles - if ( touchList[ i ].touchedEnt->IsType( idProjectile::Type ) ) - continue; - - // make sure we havent pushed this entity already. this avoids causing double damage - for( j = 0; j < num_pushed; j++ ) - { - if ( pushed_ents[ j ] == touchList[ i ].touchedEnt ) - break; - } - if ( j >= num_pushed ) - { - ent = touchList[ i ].touchedEnt; - pushed_ents[num_pushed++] = ent; - vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin(); - vel.Normalize(); - ent->ApplyImpulse( this, touchList[i].touchedClipModel->GetId(), ent->GetPhysics()->GetOrigin(), cv_ai_bumpobject_impulse.GetFloat() * vel ); - } - } - } -} - -/* -================ -idAFEntity_Base::BodyForClipModelId -================ -*/ -int idAFEntity_Base::BodyForClipModelId( int id ) const { - return af.BodyForClipModelId( id ); -} - -/* -================ -idAFEntity_Base::SaveState -================ -*/ -void idAFEntity_Base::SaveState( idDict &args ) const { - const idKeyValue *kv; - - // save the ragdoll pose - af.SaveState( args ); - - // save all the bind constraints - kv = spawnArgs.MatchPrefix( "bindConstraint ", NULL ); - while ( kv ) { - args.Set( kv->GetKey(), kv->GetValue() ); - kv = spawnArgs.MatchPrefix( "bindConstraint ", kv ); - } - - // save the bind if it exists - kv = spawnArgs.FindKey( "bind" ); - if ( kv ) { - args.Set( kv->GetKey(), kv->GetValue() ); - } - kv = spawnArgs.FindKey( "bindToJoint" ); - if ( kv ) { - args.Set( kv->GetKey(), kv->GetValue() ); - } - kv = spawnArgs.FindKey( "bindToBody" ); - if ( kv ) { - args.Set( kv->GetKey(), kv->GetValue() ); - } -} - -/* -================ -idAFEntity_Base::LoadState -================ -*/ -void idAFEntity_Base::LoadState( const idDict &args ) { - af.LoadState( args ); -} - -/* -================ -idAFEntity_Base::AddBindConstraints -================ -*/ -void idAFEntity_Base::AddBindConstraints( void ) { - af.AddBindConstraints(); -} - -/* -================ -idAFEntity_Base::RemoveBindConstraints -================ -*/ -void idAFEntity_Base::RemoveBindConstraints( void ) { - af.RemoveBindConstraints(); -} - -/* -================ -idAFEntity_Base::GetImpactInfo -================ -*/ -void idAFEntity_Base::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { - if ( af.IsActive() ) { - af.GetImpactInfo( ent, id, point, info ); - } else { - idEntity::GetImpactInfo( ent, id, point, info ); - } -} - -/* -================ -idAFEntity_Base::ApplyImpulse -================ -*/ -void idAFEntity_Base::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - if ( af.IsLoaded() ) { - af.ApplyImpulse( ent, id, point, impulse ); - } - if ( !af.IsActive() ) { - idEntity::ApplyImpulse( ent, id, point, impulse ); - } -} - -/* -================ -idAFEntity_Base::AddForce -================ -*/ -void idAFEntity_Base::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { - if ( af.IsLoaded() ) { - af.AddForce( ent, id, point, force ); - } - if ( !af.IsActive() ) { - idEntity::AddForce( ent, id, point, force ); - } -} - -/* -================ -idAFEntity_Base::Collide -================ -*/ -bool idAFEntity_Base::Collide( const trace_t &collision, const idVec3 &velocity ) { - float v, f; - - idEntity *e = gameLocal.entities[collision.c.entityNum]; - - if(e) - { - ProcCollisionStims( e, collision.c.id ); - if( e->IsType( idAI::Type ) ) - { - idAI *alertee = static_cast(e); - alertee->TactileAlert( this ); - } - } - - if ( af.IsActive() ) - { - v = -( velocity * collision.c.normal ); - if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) { - f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ); - if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) { - // don't set the volume unless there is a bounce sound as it overrides the entire channel - // which causes footsteps on ai's to not honor their shader parms - SetSoundVolume( f ); - } - nextSoundTime = gameLocal.time + 500; - } - } - - return false; -} - -/* -================ -idAFEntity_Base::GetPhysicsToVisualTransform -================ -*/ -bool idAFEntity_Base::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { - if ( af.IsActive() ) { - af.GetPhysicsToVisualTransform( origin, axis ); - return true; - } - return idEntity::GetPhysicsToVisualTransform( origin, axis ); -} - -/* -================ -idAFEntity_Base::UpdateAnimationControllers -================ -*/ -bool idAFEntity_Base::UpdateAnimationControllers( void ) { - if ( af.IsActive() ) { - if ( af.UpdateAnimation() ) { - return true; - } - } - return false; -} - -/* -================ -idAFEntity_Base::SetCombatModel -================ -*/ -void idAFEntity_Base::SetCombatModel( void ) { - if ( combatModel ) { - combatModel->Unlink(); - combatModel->LoadModel( modelDefHandle ); - } else { - combatModel = new idClipModel( modelDefHandle ); - } -} - -/* -================ -idAFEntity_Base::GetCombatModel -================ -*/ -idClipModel *idAFEntity_Base::GetCombatModel( void ) const { - return combatModel; -} - -/* -================ -idAFEntity_Base::SetCombatContents -================ -*/ -bool idAFEntity_Base::SetCombatContents( bool enable ) { - assert( combatModel ); - bool oldIsEnabled = (combatModel->GetContents() != 0); - if ( enable && combatModelContents ) { - assert( !combatModel->GetContents() ); - combatModel->SetContents( combatModelContents ); - combatModelContents = 0; - } else if ( !enable && combatModel->GetContents() ) { - assert( !combatModelContents ); - combatModelContents = combatModel->GetContents(); - combatModel->SetContents( 0 ); - } - return oldIsEnabled; -} - -/* -================ -idAFEntity_Base::LinkCombat -================ -*/ -void idAFEntity_Base::LinkCombat( void ) { - if ( fl.hidden ) { - return; - } - if ( combatModel ) { - combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); - } -} - -/* -================ -idAFEntity_Base::UnlinkCombat -================ -*/ -void idAFEntity_Base::UnlinkCombat( void ) { - if ( combatModel ) { - combatModel->Unlink(); - } -} - -/* -================ -idAFEntity_Base::FreeModelDef -================ -*/ -void idAFEntity_Base::FreeModelDef( void ) { - UnlinkCombat(); - idEntity::FreeModelDef(); -} - -/* -=============== -idAFEntity_Base::ShowEditingDialog -=============== -*/ -void idAFEntity_Base::ShowEditingDialog( void ) { - common->InitTool( EDITOR_AF, &spawnArgs ); -} - -/* -================ -idAFEntity_Base::DropAFs - - The entity should have the following key/value pairs set: - "def_dropAF" "af def" - "dropSkin" "skin name" - To drop multiple articulated figures the following key/value pairs can be used: - "def_dropAF*" "af def" - where * is an aribtrary string. -================ -*/ -void idAFEntity_Base::DropAFs( idEntity *ent, const char *type, idList *list ) { - const idKeyValue *kv; - const char *skinName; - idEntity *newEnt; - idAFEntity_Base *af; - idDict args; - const idDeclSkin *skin; - - // drop the articulated figures - kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), NULL ); - while ( kv ) { - - args.Set( "classname", kv->GetValue() ); - gameLocal.SpawnEntityDef( args, &newEnt ); - - if ( newEnt && newEnt->IsType( idAFEntity_Base::Type ) ) { - af = static_cast(newEnt); - af->GetPhysics()->SetOrigin( ent->GetPhysics()->GetOrigin() ); - af->GetPhysics()->SetAxis( ent->GetPhysics()->GetAxis() ); - af->af.SetupPose( ent, gameLocal.time ); - if ( list ) { - list->Append( af ); - } - } - - kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), kv ); - } - - // change the skin to hide all the dropped articulated figures - skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) ); - if ( skinName[0] ) { - skin = declManager->FindSkin( skinName ); - ent->SetSkin( skin ); - } -} - -/* -================ -idAFEntity_Base::Event_SetConstraintPosition -================ -*/ -void idAFEntity_Base::Event_SetConstraintPosition( const char *name, const idVec3 &pos ) { - af.SetConstraintPosition( name, pos ); -} - -void idAFEntity_Base::Event_SetLinearVelocityB( idVec3 &NewVelocity, int id ) -{ - GetPhysics()->SetLinearVelocity( NewVelocity, id ); -} - -void idAFEntity_Base::Event_SetAngularVelocityB( idVec3 &NewVelocity, int id ) -{ - GetPhysics()->SetAngularVelocity( NewVelocity, id ); -} - -void idAFEntity_Base::Event_GetLinearVelocityB( int id ) -{ - idThread::ReturnVector( GetPhysics()->GetLinearVelocity( id ) ); -} - -void idAFEntity_Base::Event_GetAngularVelocityB( int id ) -{ - idThread::ReturnVector( GetPhysics()->GetAngularVelocity( id ) ); -} - -void idAFEntity_Base::Event_GetNumBodies( void ) -{ - idThread::ReturnInt( static_cast( GetPhysics() )->GetNumBodies() ); -} - -void idAFEntity_Base::SetUpGroundingVars( void ) -{ - if( m_bGroundWhenDragged && af.IsLoaded() ) - { - idLexer src; - idToken token; - idStr tempStr = spawnArgs.GetString( "ground_critical_bodies", "" ); - - m_GroundBodyList.Clear(); - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Parsing critical ground bodies list %s\r", tempStr.c_str()); - if( tempStr.Length() ) - { - src.LoadMemory( tempStr.c_str(), tempStr.Length(), "" ); - src.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS | LEXFL_ALLOWPATHNAMES ); - - while( src.ReadToken( &token ) ) - m_GroundBodyList.Append( GetAFPhysics()->GetBodyId(token.c_str()) ); - - src.FreeSource(); - } - } -} - -bool idAFEntity_Base::CollidesWithTeam( void ) -{ - return m_bCollideWithTeam; -} - -void idAFEntity_Base::AddEntByJoint( idEntity *ent, jointHandle_t joint ) -{ - int bodID(0); - - if( af.IsLoaded() ) - { - bodID = BodyForClipModelId( JOINT_HANDLE_TO_CLIPMODEL_ID( joint ) ); - AddEntByBody( ent, bodID, joint ); - } -} - -void idAFEntity_Base::AddEntByBody( idEntity *ent, int bodID, jointHandle_t joint ) -{ - float EntMass(0.0), AFMass(0.0), MassOut(0.0), density(0.0); - idVec3 COM(vec3_zero), orig(vec3_zero); - idMat3 inertiaTensor, axis; - idClipModel *EntClip(NULL), *NewClip(NULL); - int newBodID(0); - SAddedEnt Entry; - idStr AddName; - - if( !af.IsLoaded() ) return; - - //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AddEntByBody: Called, ent %s, body %d\r", ent->name.c_str(), bodID ); - - - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Entity origin: %s \r", orig.ToString() ); - - EntClip = ent->GetPhysics()->GetClipModel(); - axis = EntClip->GetAxis(); - orig = EntClip->GetOrigin(); - - NewClip = new idClipModel(EntClip); - - // Propagate CONTENTS_CORPSE from AF to new clipmodel - if( GetAFPhysics()->GetContents() & CONTENTS_CORPSE ) - NewClip->SetContents( (NewClip->GetContents() & (~CONTENTS_SOLID)) | CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); - - // EntMass = ent->GetPhysics()->GetMass(); - // FIX: Large masses aren't working, the AFs are not quite that flexible that you can put on a huge mass - // Or it could be the occasional small negative elements in the inertia tensor. - // In any case for now, we set the masses to 1 so they only collide, don't pull on the AF - EntMass = 1.0f; - if ( EntMass <= 0.0f || FLOAT_IS_NAN( EntMass ) ) - { - EntMass = 1.0f; - } - AFMass = GetAFPhysics()->GetMass(); - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Retrieved masses. AF mass: %f , Ent mass: %f \r", AFMass, EntMass ); - - // Trick: Use a test density of 1.0 here, then divide the actual mass by output mass to get actual density - NewClip->GetMassProperties( 1.0f, MassOut, COM, inertiaTensor ); - - // AF bodies want to have their origin at the center of mass - NewClip->TranslateOrigin( -COM ); - orig += COM * axis; - - // DEBUG: -// idVec3 COMNew; -// NewClip->GetMassProperties( 1.0f, MassOut, COMNew, inertiaTensor ); -// DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("AF Bind: New Clip COM: %s \r", COMNew.ToString() ); -// DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("AF Bind: Modified origin: %s \r", orig.ToString() ); - - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Linking clipmodel copy... \r" ); - // FIXME: Do we really want to set id 0 here? Won't this conflict? - NewClip->Link( gameLocal.clip, this, 0, orig, axis ); - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Clipmodel linked.\r"); - - // Add the mass in the AF Structure - density = idMath::Fabs( EntMass / MassOut ); - GetAFPhysics()->SetMass( AFMass + EntMass ); - - AddName = ent->name + idStr(gameLocal.time); - - idAFBody *bodyExist = GetAFPhysics()->GetBody(bodID); - idAFBody *body = new idAFBody( AddName, NewClip, density ); - body->SetClipMask( bodyExist->GetClipMask() ); - body->SetSelfCollision( false ); - body->SetRerouteEnt( ent ); - body->SetWorldOrigin( orig ); - body->SetWorldAxis( axis ); - newBodID = GetAFPhysics()->AddBody( body ); - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Body added to physics_AF with id %d.\r", newBodID); - - // ishtvan: Don't add the constraint while animating, wait until full ragdoll mode - if( af.IsActive() ) - { - idAFConstraint_Fixed *cf = new idAFConstraint_Fixed( AddName, body, bodyExist ); - GetAFPhysics()->AddConstraint( cf ); - } - - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Constraint added between new body %s and original body %s.\r", body->GetName().c_str(), bodyExist->GetName().c_str()); - - // Now add body to AF object, for updating with idAF::ChangePos and the like - // We use AF_JOINTMOD_NONE since this new AF shouldn't actually stretch joints on the model when it moves - af.AddBodyExtern( this, body, bodyExist, AF_JOINTMOD_NONE, joint ); - - // Add to list - Entry.ent = ent; - Entry.AddedToBody = bodyExist->GetName(); - Entry.bodyName = AddName; - Entry.bodyContents = body->GetClipModel()->GetContents(); - Entry.bodyClipMask = body->GetClipMask(); - Entry.entContents = EntClip->GetContents(); - Entry.entClipMask = ent->GetPhysics()->GetClipMask(); - - m_AddedEnts.Append( Entry ); - - // Disable the entity's clipmodel - // leave CONTENTS_RESPONSE and CONTENTS_FROBABLE alone - int SetContents = 0; - if( (EntClip->GetContents() & CONTENTS_RESPONSE) != 0 ) - SetContents = CONTENTS_RESPONSE; - - if( (EntClip->GetContents() & CONTENTS_FROBABLE) != 0 - // Temporary fix: CONTENTS_FROBABLE is not currently set on all frobables - || ent->m_bFrobable ) - SetContents = SetContents | CONTENTS_FROBABLE; - - EntClip->SetContents( SetContents ); - ent->GetPhysics()->SetClipMask( 0 ); - - // Make sure the AF activates as soon as this is done - if( af.IsActive() ) - GetAFPhysics()->Activate(); - - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AddEntByBody: Done.\r"); -} - -/* -================ -idAFEntity_Base::RemoveAddedEnt -================ -*/ -void idAFEntity_Base::RemoveAddedEnt( idEntity *ent ) -{ - bool bRemoved = false; - idStr bodyName; - - for( int i=m_AddedEnts.Num() - 1; i >= 0; i-- ) - { - if(ent && (m_AddedEnts[i].ent.GetEntity() == ent)) - { - bodyName = m_AddedEnts[i].bodyName; - GetAFPhysics()->DeleteBody( bodyName.c_str() ); - af.DeleteBodyExtern( this, bodyName.c_str() ); - - ent->GetPhysics()->SetContents( m_AddedEnts[i].entContents ); - ent->GetPhysics()->SetClipMask( m_AddedEnts[i].entClipMask ); - m_AddedEnts.RemoveIndex(i); - // Added ent AF bodies have a mass of 1 for now - // GetAFPhysics()->SetMass( GetPhysics()->GetMass() - ent->GetPhysics()->GetMass() ); - GetAFPhysics()->SetMass( GetPhysics()->GetMass() - 1.0f ); - - bRemoved = true; - } - } - - if( bRemoved && IsActiveAF() ) - ActivatePhysics( this ); -} - -jointHandle_t idAFEntity_Base::JointForBody( int body ) -{ - return af.JointForBody( body ); -} - -int idAFEntity_Base::BodyForJoint( jointHandle_t joint ) -{ - return af.BodyForJoint( joint ); -} - -idAFBody *idAFEntity_Base::AFBodyForEnt( idEntity *ent ) -{ - idAFBody *returnBody = NULL; - for( int i=0; i < m_AddedEnts.Num(); i++ ) - { - if( m_AddedEnts[i].ent.GetEntity() == ent ) - { - idStr bodyName = m_AddedEnts[i].bodyName; - returnBody = GetAFPhysics()->GetBody( bodyName.c_str() ); - break; - } - } - - return returnBody; -} - -void idAFEntity_Base::RestoreAddedEnts( void ) -{ - // This must be called after all entities are loaded - int TempContents, TempClipMask, bodyID; - idEntity *ent; - idList OldAdded; - idStr temp; - - OldAdded = m_AddedEnts; - m_AddedEnts.Clear(); - - for(int i=0; iGetPhysics()->SetContents( TempContents ); - ent->GetPhysics()->SetClipMask( TempClipMask ); - - bodyID = GetAFPhysics()->GetBodyId( OldAdded[i].AddedToBody ); - - // Add the body again - AddEntByBody( ent, bodyID ); - - // restore the saved contents and clipmask of the AF body just added - idAFBody *body = AFBodyForEnt( ent ); - if( body ) - { - TempContents = OldAdded[i].bodyContents; - TempClipMask = OldAdded[i].bodyClipMask; - body->GetClipModel()->SetContents( TempContents ); - body->SetClipMask( TempClipMask ); - } - } -} - -void idAFEntity_Base::UpdateAddedEntConstraints( void ) -{ - for( int i=0; i < m_AddedEnts.Num(); i++ ) - { - idStr AddName = m_AddedEnts[i].bodyName; - idAFBody *body = GetAFPhysics()->GetBody( AddName.c_str() ); - idAFBody *bodyExist = GetAFPhysics()->GetBody( m_AddedEnts[i].AddedToBody ); - - // get the AF bodies in their most recent position (just before ragdoll start) - af.ChangePose( this, gameLocal.time ); - // add a constraint for the current position - idAFConstraint_Fixed *cf = new idAFConstraint_Fixed( AddName, body, bodyExist ); - GetAFPhysics()->AddConstraint( cf ); - } -} - -void idAFEntity_Base::UnbindNotify( idEntity *ent ) -{ - idEntity::UnbindNotify( ent ); - // remove ent from AF if it was dynamically added as an AF body - RemoveAddedEnt( ent ); -} - -void idAFEntity_Base::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, trace_t *tr ) -{ - idEntity *reroute = NULL; - idAFBody *StruckBody = NULL; - int bodID; - - if( tr ) - { - bodID = BodyForClipModelId( tr->c.id ); - StruckBody = GetAFPhysics()->GetBody( bodID ); - - if( StruckBody != NULL ) - reroute = StruckBody->GetRerouteEnt(); - } - - // check for reroute entity on the AF body and damage this instead - if( reroute != NULL ) - reroute->Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); - else - idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); -} - -/* -====================== -idAFEntity_Base::ParseAttachments -====================== -*/ -void idAFEntity_Base::ParseAttachments( void ) -{ - return; -} - -/* -====================== -idAFEntity_Base::ParseAttachmentsAF -====================== -*/ -void idAFEntity_Base::ParseAttachmentsAF( void ) -{ - // FIX: Preserve initial frame facing when posing the AF prior to attaching - // otherwise relationships between new AF bodies and AF bodies they're attached to - // get screwed up (since attached entities are attached when the AFEntity is still facing 0,0,0) - idMat3 tempAxis = renderEntity.axis; - idMat3 tempAxis2 = GetPhysics()->GetAxis(); - renderEntity.axis = mat3_identity; - SetAxis(mat3_identity); - - af.SetupPose(this, gameLocal.time); - idEntity::ParseAttachments(); - - renderEntity.axis = tempAxis; - SetAxis(tempAxis2); -} - -void idAFEntity_Base::ReAttachToPos - ( const char *AttName, const char *PosName ) -{ - int ind = GetAttachmentIndex( AttName ); - if (ind == -1 ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); - return; - } - - idEntity* ent = GetAttachment( ind ); - - if( !ent ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", AttName, name.c_str()); - return; - } - - // retain the AF body contents (don't want to accidentally re-enable them if clip disabled) - idAFBody *body = NULL; - int bodyContents = 0, bodyClipMask = 0; - bool bStoredAFBodyInfo = false; - if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL ) - { - bodyContents = body->GetClipModel()->GetContents(); - bodyClipMask = body->GetClipMask(); - bStoredAFBodyInfo = true; - } - - idEntity::ReAttachToPos( AttName, PosName ); - - // copy over the old AF body contents - if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL - && bStoredAFBodyInfo ) - { - body->GetClipModel()->SetContents( bodyContents ); - body->SetClipMask( bodyClipMask ); - } -} - -void idAFEntity_Base::ReAttachToCoords - ( const char *AttName, idStr jointName, - idVec3 offset, idAngles angles ) -{ - idEntity *ent(NULL); - CAttachInfo *attachment = GetAttachInfo( AttName ); - - if( !attachment ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); - return; - } - - ent = attachment->ent.GetEntity(); - if( !attachment->ent.IsValid() || !ent ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", name.c_str()); - return; - } - - // retain the AF body contents (don't want to accidentally re-enable them if clip disabled) - idAFBody *body = NULL; - int bodyContents = 0, bodyClipMask = 0; - bool bStoredAFBodyInfo = false; - if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL ) - { - bodyContents = body->GetClipModel()->GetContents(); - bodyClipMask = body->GetClipMask(); - bStoredAFBodyInfo = true; - } - - idAnimatedEntity::ReAttachToCoords( AttName, jointName, offset, angles ); - - // copy over the old AF body contents - if( (body = static_cast(this)->AFBodyForEnt( ent )) != NULL - && bStoredAFBodyInfo ) - { - body->GetClipModel()->SetContents( bodyContents ); - body->SetClipMask( bodyClipMask ); - } -} - -/* -=============================================================================== - -idAFEntity_Gibbable - -=============================================================================== -*/ - -const idEventDef EV_Gib( "gib", "s" ); -const idEventDef EV_Gibbed( "" ); - -CLASS_DECLARATION( idAFEntity_Base, idAFEntity_Gibbable ) - EVENT( EV_Gib, idAFEntity_Gibbable::Event_Gib ) - EVENT( EV_Gibbed, idAFEntity_Base::Event_Remove ) -END_CLASS - - -/* -================ -idAFEntity_Gibbable::idAFEntity_Gibbable -================ -*/ -idAFEntity_Gibbable::idAFEntity_Gibbable( void ) { - skeletonModel = NULL; - skeletonModelDefHandle = -1; - gibbed = false; -} - -/* -================ -idAFEntity_Gibbable::~idAFEntity_Gibbable -================ -*/ -idAFEntity_Gibbable::~idAFEntity_Gibbable() { - if ( skeletonModelDefHandle != -1 ) { - gameRenderWorld->FreeEntityDef( skeletonModelDefHandle ); - skeletonModelDefHandle = -1; - } -} - -/* -================ -idAFEntity_Gibbable::Save -================ -*/ -void idAFEntity_Gibbable::Save( idSaveGame *savefile ) const { - savefile->WriteBool( gibbed ); - savefile->WriteBool( combatModel != NULL ); -} - -/* -================ -idAFEntity_Gibbable::Restore -================ -*/ -void idAFEntity_Gibbable::Restore( idRestoreGame *savefile ) { - bool hasCombatModel; - - savefile->ReadBool( gibbed ); - savefile->ReadBool( hasCombatModel ); - - InitSkeletonModel(); - - if ( hasCombatModel ) { - SetCombatModel(); - LinkCombat(); - } -} - -/* -================ -idAFEntity_Gibbable::Spawn -================ -*/ -void idAFEntity_Gibbable::Spawn( void ) { - InitSkeletonModel(); - - gibbed = false; -} - -/* -================ -idAFEntity_Gibbable::InitSkeletonModel -================ -*/ -void idAFEntity_Gibbable::InitSkeletonModel( void ) { - const char *modelName; - const idDeclModelDef *modelDef; - - skeletonModel = NULL; - skeletonModelDefHandle = -1; - - modelName = spawnArgs.GetString( "model_gib" ); - - modelDef = NULL; - if ( modelName[0] != '\0' ) { - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelName, false ) ); - if ( modelDef ) { - skeletonModel = modelDef->ModelHandle(); - } else { - skeletonModel = renderModelManager->FindModel( modelName ); - } - if ( skeletonModel != NULL && renderEntity.hModel != NULL ) { - if ( skeletonModel->NumJoints() != renderEntity.hModel->NumJoints() ) { - gameLocal.Error( "gib model '%s' has different number of joints than model '%s'", - skeletonModel->Name(), renderEntity.hModel->Name() ); - } - } - } -} - -/* -================ -idAFEntity_Gibbable::Present -================ -*/ -void idAFEntity_Gibbable::Present( void ) { - renderEntity_t skeleton; - - if ( !gameLocal.isNewFrame ) { - return; - } - - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { - return; - } - - // update skeleton model - if ( gibbed && !IsHidden() && skeletonModel != NULL ) { - skeleton = renderEntity; - skeleton.hModel = skeletonModel; - // add to refresh list - if ( skeletonModelDefHandle == -1 ) { - skeletonModelDefHandle = gameRenderWorld->AddEntityDef( &skeleton ); - } else { - gameRenderWorld->UpdateEntityDef( skeletonModelDefHandle, &skeleton ); - } - } - - idEntity::Present(); -} - -/* -================ -idAFEntity_Gibbable::Damage -================ -*/ -void idAFEntity_Gibbable::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, trace_t *tr ) -{ - idAFEntity_Base::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); - - if ( !fl.takedamage ) - { - return; - } - - if ( health < -20 && spawnArgs.GetBool( "gib" ) ) { - Gib( dir, damageDefName ); - } -} - -/* -===================== -idAFEntity_Gibbable::SpawnGibs -===================== -*/ -void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefName ) { - int i; - bool gibNonSolid; - idVec3 entityCenter, velocity; - idList list; - - assert( !gameLocal.isClient ); - - const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) { - gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); - } - - // spawn gib articulated figures - idAFEntity_Base::DropAFs( this, "gib", &list ); - - // spawn gib items - idMoveableItem::DropItems( this, "gib", &list ); - - // blow out the gibs in the given direction away from the center of the entity - entityCenter = GetPhysics()->GetAbsBounds().GetCenter(); - gibNonSolid = damageDef->GetBool( "gibNonSolid" ); - for ( i = 0; i < list.Num(); i++ ) { - if ( gibNonSolid ) { - list[i]->GetPhysics()->SetContents( 0 ); - list[i]->GetPhysics()->SetClipMask( 0 ); - list[i]->GetPhysics()->UnlinkClip(); - list[i]->GetPhysics()->PutToRest(); - } else { - list[i]->GetPhysics()->SetContents( CONTENTS_CORPSE ); - list[i]->GetPhysics()->SetClipMask( CONTENTS_SOLID ); - velocity = list[i]->GetPhysics()->GetAbsBounds().GetCenter() - entityCenter; - velocity.NormalizeFast(); - velocity += ( i & 1 ) ? dir : -dir; - list[i]->GetPhysics()->SetLinearVelocity( velocity * 75.0f ); - } - list[i]->GetRenderEntity()->noShadow = true; - list[i]->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; - list[i]->PostEventSec( &EV_Remove, 4.0f ); - } -} - -/* -============ -idAFEntity_Gibbable::Gib -============ -*/ -void idAFEntity_Gibbable::Gib( const idVec3 &dir, const char *damageDefName ) { - // only gib once - if ( gibbed ) { - return; - } - - const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) { - gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); - } - - if ( damageDef->GetBool( "gibNonSolid" ) ) { - GetAFPhysics()->SetContents( 0 ); - GetAFPhysics()->SetClipMask( 0 ); - GetAFPhysics()->UnlinkClip(); - GetAFPhysics()->PutToRest(); - } else { - GetAFPhysics()->SetContents( CONTENTS_CORPSE ); - GetAFPhysics()->SetClipMask( CONTENTS_SOLID ); - } - - UnlinkCombat(); - - if ( g_bloodEffects.GetBool() ) { - if ( gameLocal.time > gameLocal.GetGibTime() ) { - gameLocal.SetGibTime( gameLocal.time + GIB_DELAY ); - SpawnGibs( dir, damageDefName ); - renderEntity.noShadow = true; - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; - StartSound( "snd_gibbed", SND_CHANNEL_ANY, 0, false, NULL ); - gibbed = true; - } - } else { - gibbed = true; - } - - - PostEventSec( &EV_Gibbed, 4.0f ); -} - -/* -============ -idAFEntity_Gibbable::Event_Gib -============ -*/ -void idAFEntity_Gibbable::Event_Gib( const char *damageDefName ) { - Gib( idVec3( 0, 0, 1 ), damageDefName ); -} - -/* -=============================================================================== - - idAFEntity_Generic - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Gibbable, idAFEntity_Generic ) - EVENT( EV_Activate, idAFEntity_Generic::Event_Activate ) -END_CLASS - -/* -================ -idAFEntity_Generic::idAFEntity_Generic -================ -*/ -idAFEntity_Generic::idAFEntity_Generic( void ) { - keepRunningPhysics = false; -} - -/* -================ -idAFEntity_Generic::~idAFEntity_Generic -================ -*/ -idAFEntity_Generic::~idAFEntity_Generic( void ) { -} - -/* -================ -idAFEntity_Generic::Save -================ -*/ -void idAFEntity_Generic::Save( idSaveGame *savefile ) const { - savefile->WriteBool( keepRunningPhysics ); -} - -/* -================ -idAFEntity_Generic::Restore -================ -*/ -void idAFEntity_Generic::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( keepRunningPhysics ); -} - -/* -================ -idAFEntity_Generic::Think -================ -*/ -void idAFEntity_Generic::Think( void ) { - idAFEntity_Base::Think(); - - if ( keepRunningPhysics && !IsHidden() ) - { - BecomeActive( TH_PHYSICS ); - } -} - -/* -================ -idAFEntity_Generic::Spawn -================ -*/ -void idAFEntity_Generic::Spawn( void ) { - if ( !LoadAF() ) { - gameLocal.Error( "Couldn't load af file on entity '%s'", name.c_str() ); - } - - SetCombatModel(); - - SetPhysics( af.GetPhysics() ); - - ParseAttachmentsAF(); - - af.GetPhysics()->PutToRest(); - if ( !spawnArgs.GetBool( "nodrop", "0" ) ) { - af.GetPhysics()->Activate(); - } - - fl.takedamage = true; -} - -/* -================ -idAFEntity_Generic::Event_Activate -================ -*/ -void idAFEntity_Generic::Event_Activate( idEntity *activator ) { - float delay; - idVec3 init_velocity, init_avelocity; - - Show(); - - af.GetPhysics()->EnableImpact(); - af.GetPhysics()->Activate(); - - spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); - spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); - - delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); - if ( delay == 0.0f ) { - af.GetPhysics()->SetLinearVelocity( init_velocity ); - } else { - PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); - } - - delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); - if ( delay == 0.0f ) { - af.GetPhysics()->SetAngularVelocity( init_avelocity ); - } else { - PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); - } - - // greebo: Reactivate the animation flag, just in case - // This hopefully helps rope arrows to not stick out straight in the air - BecomeActive(TH_ANIMATE); -} - - -/* -=============================================================================== - - idAFEntity_WithAttachedHead - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Gibbable, idAFEntity_WithAttachedHead ) - EVENT( EV_Gib, idAFEntity_WithAttachedHead::Event_Gib ) - EVENT( EV_Activate, idAFEntity_WithAttachedHead::Event_Activate ) -END_CLASS - -/* -================ -idAFEntity_WithAttachedHead::idAFEntity_WithAttachedHead -================ -*/ -idAFEntity_WithAttachedHead::idAFEntity_WithAttachedHead() { - head = NULL; -} - -/* -================ -idAFEntity_WithAttachedHead::~idAFEntity_WithAttachedHead -================ -*/ -idAFEntity_WithAttachedHead::~idAFEntity_WithAttachedHead() { - if ( head.GetEntity() ) { - head.GetEntity()->ClearBody(); - head.GetEntity()->PostEventMS( &EV_Remove, 0 ); - } -} - -/* -================ -idAFEntity_WithAttachedHead::Spawn -================ -*/ -void idAFEntity_WithAttachedHead::Spawn( void ) -{ - LoadAF(); - - SetCombatModel(); - - SetPhysics( af.GetPhysics() ); - - SetupHead(); - ParseAttachmentsAF(); - - af.GetPhysics()->PutToRest(); - if ( !spawnArgs.GetBool( "nodrop", "0" ) ) { - af.GetPhysics()->Activate(); - } - - fl.takedamage = true; - - if ( head.GetEntity() ) { - int anim = head.GetEntity()->GetAnimator()->GetAnim( "dead" ); - - if ( anim ) { - head.GetEntity()->GetAnimator()->SetFrame( ANIMCHANNEL_ALL, anim, 0, gameLocal.time, 0 ); - } - } -} - -/* -================ -idAFEntity_WithAttachedHead::Save -================ -*/ -void idAFEntity_WithAttachedHead::Save( idSaveGame *savefile ) const { - head.Save( savefile ); -} - -/* -================ -idAFEntity_WithAttachedHead::Restore -================ -*/ -void idAFEntity_WithAttachedHead::Restore( idRestoreGame *savefile ) { - head.Restore( savefile ); -} - -/* -================ -idAFEntity_WithAttachedHead::SetupHead -================ -*/ -void idAFEntity_WithAttachedHead::SetupHead() -{ - idStr headModelDefName = spawnArgs.GetString( "def_head", "" ); - - idVec3 modelOffset = spawnArgs.GetVector("offsetModel", "0 0 0"); - idVec3 HeadModelOffset = spawnArgs.GetVector("offsetHeadModel", "0 0 0"); - - if ( !headModelDefName.IsEmpty() ) - { - // We look if the head model is defined as a key to have a specific offset. - // If that is not the case, then we use the default value, if it exists, - // otherwise there is no offset at all. - if (spawnArgs.FindKey(headModelDefName) != NULL) - { - HeadModelOffset = spawnArgs.GetVector(headModelDefName, "0 0 0"); - } - - idStr jointName = spawnArgs.GetString( "head_joint" ); - jointHandle_t joint = animator.GetJointHandle( jointName.c_str() ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Joint '%s' not found for 'head_joint' on '%s'", jointName.c_str(), name.c_str() ); - } - - // Setup the default spawnargs for all heads - idDict args; - - const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); - - if (def == NULL) - { - gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); - - // Try to fallback on the default head entityDef - def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); - } - - if (def != NULL) - { - // Make a copy of the default spawnargs - args = def->dict; - } - else - { - gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); - } - - // Spawn the head entity - idEntity* ent = gameLocal.SpawnEntityType(idAFAttachment::Type, &args); - idAFAttachment* headEnt = static_cast(ent); - - // Retrieve the actual model from the head entityDef - idStr headModel = args.GetString("model"); - if (headModel.IsEmpty()) - { - gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); - } - - headEnt->SetName( va( "%s_head", name.c_str() ) ); - headEnt->SetBody( this, headModel, joint ); - headEnt->SetCombatModel(); - head = headEnt; - - idVec3 origin; - idMat3 axis; - animator.GetJointTransform( joint, gameLocal.time, origin, axis ); - origin = renderEntity.origin + ( origin + modelOffset + HeadModelOffset ) * renderEntity.axis; - headEnt->SetOrigin( origin ); - headEnt->SetAxis( renderEntity.axis ); - headEnt->BindToJoint( this, joint, true ); - - // greebo: Setup the frob-peer relationship between head and body - m_FrobPeers.AddUnique(headEnt->name); - } -} - -/* -================ -idAFEntity_WithAttachedHead::Think -================ -*/ -void idAFEntity_WithAttachedHead::Think( void ) { - idAFEntity_Base::Think(); -} - -/* -================ -idAFEntity_WithAttachedHead::LinkCombat -================ -*/ -void idAFEntity_WithAttachedHead::LinkCombat( void ) { - idAFAttachment *headEnt; - - if ( fl.hidden ) { - return; - } - - if ( combatModel ) { - combatModel->Link( gameLocal.clip, this, 0, renderEntity.origin, renderEntity.axis, modelDefHandle ); - } - headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->LinkCombat(); - } -} - -/* -================ -idAFEntity_WithAttachedHead::UnlinkCombat -================ -*/ -void idAFEntity_WithAttachedHead::UnlinkCombat( void ) { - idAFAttachment *headEnt; - - if ( combatModel ) { - combatModel->Unlink(); - } - headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->UnlinkCombat(); - } -} - -/* -================ -idAFEntity_WithAttachedHead::Hide -================ -*/ -void idAFEntity_WithAttachedHead::Hide( void ) { - idAFEntity_Base::Hide(); - if ( head.GetEntity() ) { - head.GetEntity()->Hide(); - } - UnlinkCombat(); -} - -/* -================ -idAFEntity_WithAttachedHead::Show -================ -*/ -void idAFEntity_WithAttachedHead::Show( void ) { - idAFEntity_Base::Show(); - if ( head.GetEntity() ) { - head.GetEntity()->Show(); - } - LinkCombat(); -} - -/* -================ -idAFEntity_WithAttachedHead::ProjectOverlay -================ -*/ -void idAFEntity_WithAttachedHead::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { - - idEntity::ProjectOverlay( origin, dir, size, material ); - - if ( head.GetEntity() ) { - head.GetEntity()->ProjectOverlay( origin, dir, size, material ); - } -} - -/* -============ -idAFEntity_WithAttachedHead::Gib -============ -*/ -void idAFEntity_WithAttachedHead::Gib( const idVec3 &dir, const char *damageDefName ) { - // only gib once - if ( gibbed ) { - return; - } - idAFEntity_Gibbable::Gib( dir, damageDefName ); - if ( head.GetEntity() ) { - head.GetEntity()->Hide(); - } -} - -/* -============ -idAFEntity_WithAttachedHead::Event_Gib -============ -*/ -void idAFEntity_WithAttachedHead::Event_Gib( const char *damageDefName ) { - Gib( idVec3( 0, 0, 1 ), damageDefName ); -} - -/* -================ -idAFEntity_WithAttachedHead::Event_Activate -================ -*/ -void idAFEntity_WithAttachedHead::Event_Activate( idEntity *activator ) { - float delay; - idVec3 init_velocity, init_avelocity; - - Show(); - - af.GetPhysics()->EnableImpact(); - af.GetPhysics()->Activate(); - - spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); - spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); - - delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); - if ( delay == 0.0f ) { - af.GetPhysics()->SetLinearVelocity( init_velocity ); - } else { - PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); - } - - delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); - if ( delay == 0.0f ) { - af.GetPhysics()->SetAngularVelocity( init_avelocity ); - } else { - PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); - } -} - - -/* -=============================================================================== - - idAFEntity_Vehicle - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Base, idAFEntity_Vehicle ) -END_CLASS - -/* -================ -idAFEntity_Vehicle::idAFEntity_Vehicle -================ -*/ -idAFEntity_Vehicle::idAFEntity_Vehicle( void ) { - player = NULL; - eyesJoint = INVALID_JOINT; - steeringWheelJoint = INVALID_JOINT; - wheelRadius = 0.0f; - steerAngle = 0.0f; - steerSpeed = 0.0f; - dustSmoke = NULL; -} - -/* -================ -idAFEntity_Vehicle::Spawn -================ -*/ -void idAFEntity_Vehicle::Spawn( void ) { - const char *eyesJointName = spawnArgs.GetString( "eyesJoint", "eyes" ); - const char *steeringWheelJointName = spawnArgs.GetString( "steeringWheelJoint", "steeringWheel" ); - - LoadAF(); - - SetCombatModel(); - - SetPhysics( af.GetPhysics() ); - - ParseAttachmentsAF(); - - fl.takedamage = true; - - if ( !eyesJointName[0] ) { - gameLocal.Error( "idAFEntity_Vehicle '%s' no eyes joint specified", name.c_str() ); - } - eyesJoint = animator.GetJointHandle( eyesJointName ); - if ( !steeringWheelJointName[0] ) { - gameLocal.Error( "idAFEntity_Vehicle '%s' no steering wheel joint specified", name.c_str() ); - } - steeringWheelJoint = animator.GetJointHandle( steeringWheelJointName ); - - spawnArgs.GetFloat( "wheelRadius", "20", wheelRadius ); - spawnArgs.GetFloat( "steerSpeed", "5", steerSpeed ); - - player = NULL; - steerAngle = 0.0f; - - const char *smokeName = spawnArgs.GetString( "smoke_vehicle_dust", "muzzlesmoke" ); - if ( *smokeName != '\0' ) { - dustSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } -} - -/* -================ -idAFEntity_Vehicle::Use -================ -*/ -void idAFEntity_Vehicle::Use( idPlayer *other ) { - idVec3 origin; - idMat3 axis; - - if ( player ) { - if ( player == other ) { - other->Unbind(); - player = NULL; - - af.GetPhysics()->SetComeToRest( true ); - } - } - else { - player = other; - animator.GetJointTransform( eyesJoint, gameLocal.time, origin, axis ); - origin = renderEntity.origin + origin * renderEntity.axis; - player->GetPhysics()->SetOrigin( origin ); - player->BindToBody( this, 0, true ); - - af.GetPhysics()->SetComeToRest( false ); - af.GetPhysics()->Activate(); - } -} - -/* -================ -idAFEntity_Vehicle::GetSteerAngle -================ -*/ -float idAFEntity_Vehicle::GetSteerAngle( void ) { - float idealSteerAngle, angleDelta; - - idealSteerAngle = player->usercmd.rightmove * ( 30.0f / 128.0f ); - angleDelta = idealSteerAngle - steerAngle; - - if ( angleDelta > steerSpeed ) { - steerAngle += steerSpeed; - } else if ( angleDelta < -steerSpeed ) { - steerAngle -= steerSpeed; - } else { - steerAngle = idealSteerAngle; - } - - return steerAngle; -} - - -/* -=============================================================================== - - idAFEntity_VehicleSimple - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleSimple ) -END_CLASS - -/* -================ -idAFEntity_VehicleSimple::idAFEntity_VehicleSimple -================ -*/ -idAFEntity_VehicleSimple::idAFEntity_VehicleSimple( void ) { - int i; - for ( i = 0; i < 4; i++ ) { - suspension[i] = NULL; - } -} - -/* -================ -idAFEntity_VehicleSimple::~idAFEntity_VehicleSimple -================ -*/ -idAFEntity_VehicleSimple::~idAFEntity_VehicleSimple( void ) { - delete wheelModel; - wheelModel = NULL; -} - -/* -================ -idAFEntity_VehicleSimple::Spawn -================ -*/ -void idAFEntity_VehicleSimple::Spawn( void ) { - static const char *wheelJointKeys[] = { - "wheelJointFrontLeft", - "wheelJointFrontRight", - "wheelJointRearLeft", - "wheelJointRearRight" - }; - static idVec3 wheelPoly[4] = { idVec3( 2, 2, 0 ), idVec3( 2, -2, 0 ), idVec3( -2, -2, 0 ), idVec3( -2, 2, 0 ) }; - - int i; - idVec3 origin; - idMat3 axis; - idTraceModel trm; - - trm.SetupPolygon( wheelPoly, 4 ); - trm.Translate( idVec3( 0, 0, -wheelRadius ) ); - wheelModel = new idClipModel( trm ); - - for ( i = 0; i < 4; i++ ) { - const char *wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); - if ( !wheelJointName[0] ) { - gameLocal.Error( "idAFEntity_VehicleSimple '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); - } - wheelJoints[i] = animator.GetJointHandle( wheelJointName ); - if ( wheelJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idAFEntity_VehicleSimple '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); - } - - GetAnimator()->GetJointTransform( wheelJoints[i], 0, origin, axis ); - origin = renderEntity.origin + origin * renderEntity.axis; - - suspension[i] = new idAFConstraint_Suspension(); - suspension[i]->Setup( va( "suspension%d", i ), af.GetPhysics()->GetBody( 0 ), origin, af.GetPhysics()->GetAxis( 0 ), wheelModel ); - suspension[i]->SetSuspension( g_vehicleSuspensionUp.GetFloat(), - g_vehicleSuspensionDown.GetFloat(), - g_vehicleSuspensionKCompress.GetFloat(), - g_vehicleSuspensionDamping.GetFloat(), - g_vehicleTireFriction.GetFloat() ); - - af.GetPhysics()->AddConstraint( suspension[i] ); - } - - memset( wheelAngles, 0, sizeof( wheelAngles ) ); - BecomeActive( TH_THINK ); -} - -/* -================ -idAFEntity_VehicleSimple::Think -================ -*/ -void idAFEntity_VehicleSimple::Think( void ) { - int i; - float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; - idVec3 origin; - idMat3 axis; - idRotation wheelRotation, steerRotation; - - if ( thinkFlags & TH_THINK ) { - - if ( player ) { - // capture the input from a player - velocity = g_vehicleVelocity.GetFloat(); - if ( player->usercmd.forwardmove < 0 ) { - velocity = -velocity; - } - force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); - steerAngle = GetSteerAngle(); - } - - // update the wheel motor force and steering - for ( i = 0; i < 2; i++ ) { - - // front wheel drive - if ( velocity != 0.0f ) { - suspension[i]->EnableMotor( true ); - } else { - suspension[i]->EnableMotor( false ); - } - suspension[i]->SetMotorVelocity( velocity ); - suspension[i]->SetMotorForce( force ); - - // update the wheel steering - suspension[i]->SetSteerAngle( steerAngle ); - } - - // adjust wheel velocity for better steering because there are no differentials between the wheels - if ( steerAngle < 0.0f ) { - suspension[0]->SetMotorVelocity( velocity * 0.5f ); - } else if ( steerAngle > 0.0f ) { - suspension[1]->SetMotorVelocity( velocity * 0.5f ); - } - - // update suspension with latest cvar settings - for ( i = 0; i < 4; i++ ) { - suspension[i]->SetSuspension( g_vehicleSuspensionUp.GetFloat(), - g_vehicleSuspensionDown.GetFloat(), - g_vehicleSuspensionKCompress.GetFloat(), - g_vehicleSuspensionDamping.GetFloat(), - g_vehicleTireFriction.GetFloat() ); - } - - // run the physics - RunPhysics(); - - // move and rotate the wheels visually - for ( i = 0; i < 4; i++ ) { - idAFBody *body = af.GetPhysics()->GetBody( 0 ); - - origin = suspension[i]->GetWheelOrigin(); - velocity = body->GetPointVelocity( origin ) * body->GetWorldAxis()[0]; - wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; - - // additional rotation about the wheel axis - wheelRotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); - wheelRotation.SetVec( 0, -1, 0 ); - - if ( i < 2 ) { - // rotate the wheel for steering - steerRotation.SetAngle( steerAngle ); - steerRotation.SetVec( 0, 0, 1 ); - // set wheel rotation - animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() * steerRotation.ToMat3() ); - } else { - // set wheel rotation - animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() ); - } - - // set wheel position for suspension - origin = ( origin - renderEntity.origin ) * renderEntity.axis.Transpose(); - GetAnimator()->SetJointPos( wheelJoints[i], JOINTMOD_WORLD_OVERRIDE, origin ); - } -/* - // spawn dust particle effects - if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { - int numContacts; - idAFConstraint_Contact *contacts[2]; - for ( i = 0; i < 4; i++ ) { - numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); - for ( int j = 0; j < numContacts; j++ ) { - gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); - } - } - } -*/ - } - - UpdateAnimation(); - if ( thinkFlags & TH_UPDATEVISUALS ) { - Present(); - LinkCombat(); - } -} - - -/* -=============================================================================== - - idAFEntity_VehicleFourWheels - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleFourWheels ) -END_CLASS - - -/* -================ -idAFEntity_VehicleFourWheels::idAFEntity_VehicleFourWheels -================ -*/ -idAFEntity_VehicleFourWheels::idAFEntity_VehicleFourWheels( void ) { - int i; - - for ( i = 0; i < 4; i++ ) { - wheels[i] = NULL; - wheelJoints[i] = INVALID_JOINT; - wheelAngles[i] = 0.0f; - } - steering[0] = NULL; - steering[1] = NULL; -} - -/* -================ -idAFEntity_VehicleFourWheels::Spawn -================ -*/ -void idAFEntity_VehicleFourWheels::Spawn( void ) { - int i; - static const char *wheelBodyKeys[] = { - "wheelBodyFrontLeft", - "wheelBodyFrontRight", - "wheelBodyRearLeft", - "wheelBodyRearRight" - }; - static const char *wheelJointKeys[] = { - "wheelJointFrontLeft", - "wheelJointFrontRight", - "wheelJointRearLeft", - "wheelJointRearRight" - }; - static const char *steeringHingeKeys[] = { - "steeringHingeFrontLeft", - "steeringHingeFrontRight", - }; - - const char *wheelBodyName, *wheelJointName, *steeringHingeName; - - for ( i = 0; i < 4; i++ ) { - wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" ); - if ( !wheelBodyName[0] ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] ); - } - wheels[i] = af.GetPhysics()->GetBody( wheelBodyName ); - if ( !wheels[i] ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName ); - } - wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); - if ( !wheelJointName[0] ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); - } - wheelJoints[i] = animator.GetJointHandle( wheelJointName ); - if ( wheelJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); - } - } - - for ( i = 0; i < 2; i++ ) { - steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" ); - if ( !steeringHingeName[0] ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] ); - } - steering[i] = static_cast(af.GetPhysics()->GetConstraint( steeringHingeName )); - if ( !steering[i] ) { - gameLocal.Error( "idAFEntity_VehicleFourWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName ); - } - } - - memset( wheelAngles, 0, sizeof( wheelAngles ) ); - BecomeActive( TH_THINK ); -} - -/* -================ -idAFEntity_VehicleFourWheels::Think -================ -*/ -void idAFEntity_VehicleFourWheels::Think( void ) { - int i; - float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; - idVec3 origin; - idMat3 axis; - idRotation rotation; - - if ( thinkFlags & TH_THINK ) { - - if ( player ) { - // capture the input from a player - velocity = g_vehicleVelocity.GetFloat(); - if ( player->usercmd.forwardmove < 0 ) { - velocity = -velocity; - } - force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); - steerAngle = GetSteerAngle(); - } - - // update the wheel motor force - for ( i = 0; i < 2; i++ ) { - wheels[2+i]->SetContactMotorVelocity( velocity ); - wheels[2+i]->SetContactMotorForce( force ); - } - - // adjust wheel velocity for better steering because there are no differentials between the wheels - if ( steerAngle < 0.0f ) { - wheels[2]->SetContactMotorVelocity( velocity * 0.5f ); - } - else if ( steerAngle > 0.0f ) { - wheels[3]->SetContactMotorVelocity( velocity * 0.5f ); - } - - // update the wheel steering - steering[0]->SetSteerAngle( steerAngle ); - steering[1]->SetSteerAngle( steerAngle ); - for ( i = 0; i < 2; i++ ) { - steering[i]->SetSteerSpeed( 3.0f ); - } - - // update the steering wheel - animator.GetJointTransform( steeringWheelJoint, gameLocal.time, origin, axis ); - rotation.SetVec( axis[2] ); - rotation.SetAngle( -steerAngle ); - animator.SetJointAxis( steeringWheelJoint, JOINTMOD_WORLD, rotation.ToMat3() ); - - // run the physics - RunPhysics(); - - // rotate the wheels visually - for ( i = 0; i < 4; i++ ) { - if ( force == 0.0f ) { - velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0]; - } - wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; - // give the wheel joint an additional rotation about the wheel axis - rotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); - axis = af.GetPhysics()->GetAxis( 0 ); - rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] ); - animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, rotation.ToMat3() ); - } - - // spawn dust particle effects - if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { - int numContacts; - idAFConstraint_Contact *contacts[2]; - for ( i = 0; i < 4; i++ ) { - numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); - for ( int j = 0; j < numContacts; j++ ) { - gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); - } - } - } - } - - UpdateAnimation(); - if ( thinkFlags & TH_UPDATEVISUALS ) { - Present(); - LinkCombat(); - } -} - - -/* -=============================================================================== - - idAFEntity_VehicleSixWheels - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Vehicle, idAFEntity_VehicleSixWheels ) -END_CLASS - - /* -================ -idAFEntity_VehicleSixWheels::idAFEntity_VehicleSixWheels -================ -*/ -idAFEntity_VehicleSixWheels::idAFEntity_VehicleSixWheels( void ) { - int i; - - for ( i = 0; i < 6; i++ ) { - wheels[i] = NULL; - wheelJoints[i] = INVALID_JOINT; - wheelAngles[i] = 0.0f; - } - steering[0] = NULL; - steering[1] = NULL; - steering[2] = NULL; - steering[3] = NULL; -} - -/* -================ -idAFEntity_VehicleSixWheels::Spawn -================ -*/ -void idAFEntity_VehicleSixWheels::Spawn( void ) { - int i; - static const char *wheelBodyKeys[] = { - "wheelBodyFrontLeft", - "wheelBodyFrontRight", - "wheelBodyMiddleLeft", - "wheelBodyMiddleRight", - "wheelBodyRearLeft", - "wheelBodyRearRight" - }; - static const char *wheelJointKeys[] = { - "wheelJointFrontLeft", - "wheelJointFrontRight", - "wheelJointMiddleLeft", - "wheelJointMiddleRight", - "wheelJointRearLeft", - "wheelJointRearRight" - }; - static const char *steeringHingeKeys[] = { - "steeringHingeFrontLeft", - "steeringHingeFrontRight", - "steeringHingeRearLeft", - "steeringHingeRearRight" - }; - - const char *wheelBodyName, *wheelJointName, *steeringHingeName; - - for ( i = 0; i < 6; i++ ) { - wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" ); - if ( !wheelBodyName[0] ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] ); - } - wheels[i] = af.GetPhysics()->GetBody( wheelBodyName ); - if ( !wheels[i] ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName ); - } - wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" ); - if ( !wheelJointName[0] ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] ); - } - wheelJoints[i] = animator.GetJointHandle( wheelJointName ); - if ( wheelJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName ); - } - } - - for ( i = 0; i < 4; i++ ) { - steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" ); - if ( !steeringHingeName[0] ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] ); - } - steering[i] = static_cast(af.GetPhysics()->GetConstraint( steeringHingeName )); - if ( !steering[i] ) { - gameLocal.Error( "idAFEntity_VehicleSixWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName ); - } - } - - memset( wheelAngles, 0, sizeof( wheelAngles ) ); - BecomeActive( TH_THINK ); -} - -/* -================ -idAFEntity_VehicleSixWheels::Think -================ -*/ -void idAFEntity_VehicleSixWheels::Think( void ) { - int i; - float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; - idVec3 origin; - idMat3 axis; - idRotation rotation; - - if ( thinkFlags & TH_THINK ) { - - if ( player ) { - // capture the input from a player - velocity = g_vehicleVelocity.GetFloat(); - if ( player->usercmd.forwardmove < 0 ) { - velocity = -velocity; - } - force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); - steerAngle = GetSteerAngle(); - } - - // update the wheel motor force - for ( i = 0; i < 6; i++ ) { - wheels[i]->SetContactMotorVelocity( velocity ); - wheels[i]->SetContactMotorForce( force ); - } - - // adjust wheel velocity for better steering because there are no differentials between the wheels - if ( steerAngle < 0.0f ) { - for ( i = 0; i < 3; i++ ) { - wheels[(i<<1)]->SetContactMotorVelocity( velocity * 0.5f ); - } - } - else if ( steerAngle > 0.0f ) { - for ( i = 0; i < 3; i++ ) { - wheels[1+(i<<1)]->SetContactMotorVelocity( velocity * 0.5f ); - } - } - - // update the wheel steering - steering[0]->SetSteerAngle( steerAngle ); - steering[1]->SetSteerAngle( steerAngle ); - steering[2]->SetSteerAngle( -steerAngle ); - steering[3]->SetSteerAngle( -steerAngle ); - for ( i = 0; i < 4; i++ ) { - steering[i]->SetSteerSpeed( 3.0f ); - } - - // update the steering wheel - animator.GetJointTransform( steeringWheelJoint, gameLocal.time, origin, axis ); - rotation.SetVec( axis[2] ); - rotation.SetAngle( -steerAngle ); - animator.SetJointAxis( steeringWheelJoint, JOINTMOD_WORLD, rotation.ToMat3() ); - - // run the physics - RunPhysics(); - - // rotate the wheels visually - for ( i = 0; i < 6; i++ ) { - if ( force == 0.0f ) { - velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0]; - } - wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; - // give the wheel joint an additional rotation about the wheel axis - rotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); - axis = af.GetPhysics()->GetAxis( 0 ); - rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] ); - animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, rotation.ToMat3() ); - } - - // spawn dust particle effects - if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { - int numContacts; - idAFConstraint_Contact *contacts[2]; - for ( i = 0; i < 6; i++ ) { - numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); - for ( int j = 0; j < numContacts; j++ ) { - gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); - } - } - } - } - - UpdateAnimation(); - if ( thinkFlags & TH_UPDATEVISUALS ) { - Present(); - LinkCombat(); - } -} - - -/* -=============================================================================== - - idAFEntity_SteamPipe - -=============================================================================== -*/ - -CLASS_DECLARATION( idAFEntity_Base, idAFEntity_SteamPipe ) -END_CLASS - - -/* -================ -idAFEntity_SteamPipe::idAFEntity_SteamPipe -================ -*/ -idAFEntity_SteamPipe::idAFEntity_SteamPipe( void ) { - steamBody = 0; - steamForce = 0.0f; - steamUpForce = 0.0f; - steamModelDefHandle = -1; - memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) ); -} - -/* -================ -idAFEntity_SteamPipe::~idAFEntity_SteamPipe -================ -*/ -idAFEntity_SteamPipe::~idAFEntity_SteamPipe( void ) { - if ( steamModelDefHandle >= 0 ){ - gameRenderWorld->FreeEntityDef( steamModelDefHandle ); - } -} - -/* -================ -idAFEntity_SteamPipe::Save -================ -*/ -void idAFEntity_SteamPipe::Save( idSaveGame *savefile ) const { -} - -/* -================ -idAFEntity_SteamPipe::Restore -================ -*/ -void idAFEntity_SteamPipe::Restore( idRestoreGame *savefile ) { - Spawn(); -} - -/* -================ -idAFEntity_SteamPipe::Spawn -================ -*/ -void idAFEntity_SteamPipe::Spawn( void ) { - idVec3 steamDir; - const char *steamBodyName; - - LoadAF(); - - SetCombatModel(); - - SetPhysics( af.GetPhysics() ); - - ParseAttachmentsAF(); - - fl.takedamage = true; - - steamBodyName = spawnArgs.GetString( "steamBody", "" ); - steamForce = spawnArgs.GetFloat( "steamForce", "2000" ); - steamUpForce = spawnArgs.GetFloat( "steamUpForce", "10" ); - steamDir = af.GetPhysics()->GetAxis( steamBody )[2]; - steamBody = af.GetPhysics()->GetBodyId( steamBodyName ); - force.SetPosition( af.GetPhysics(), steamBody, af.GetPhysics()->GetOrigin( steamBody ) ); - force.SetForce( steamDir * -steamForce ); - - InitSteamRenderEntity(); - - BecomeActive( TH_THINK ); -} - -/* -================ -idAFEntity_SteamPipe::InitSteamRenderEntity -================ -*/ -void idAFEntity_SteamPipe::InitSteamRenderEntity( void ) { - const char *temp; - const idDeclModelDef *modelDef; - - memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) ); - steamRenderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; - steamRenderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f; - steamRenderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; - modelDef = NULL; - temp = spawnArgs.GetString ( "model_steam" ); - if ( *temp != '\0' ) { - if ( !strstr( temp, "." ) ) { - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, temp, false ) ); - if ( modelDef ) { - steamRenderEntity.hModel = modelDef->ModelHandle(); - } - } - - if ( !steamRenderEntity.hModel ) { - steamRenderEntity.hModel = renderModelManager->FindModel( temp ); - } - - if ( steamRenderEntity.hModel ) { - steamRenderEntity.bounds = steamRenderEntity.hModel->Bounds( &steamRenderEntity ); - } else { - steamRenderEntity.bounds.Zero(); - } - steamRenderEntity.origin = af.GetPhysics()->GetOrigin( steamBody ); - steamRenderEntity.axis = af.GetPhysics()->GetAxis( steamBody ); - steamModelDefHandle = gameRenderWorld->AddEntityDef( &steamRenderEntity ); - } -} - -/* -================ -idAFEntity_SteamPipe::Think -================ -*/ -void idAFEntity_SteamPipe::Think( void ) { - idVec3 steamDir; - - if ( thinkFlags & TH_THINK ) { - steamDir.x = gameLocal.random.CRandomFloat() * steamForce; - steamDir.y = gameLocal.random.CRandomFloat() * steamForce; - steamDir.z = steamUpForce; - force.SetForce( steamDir ); - force.Evaluate( gameLocal.time ); - //gameRenderWorld->DebugArrow( colorWhite, af.GetPhysics()->GetOrigin( steamBody ), af.GetPhysics()->GetOrigin( steamBody ) - 10.0f * steamDir, 4 ); - } - - if ( steamModelDefHandle >= 0 ){ - steamRenderEntity.origin = af.GetPhysics()->GetOrigin( steamBody ); - steamRenderEntity.axis = af.GetPhysics()->GetAxis( steamBody ); - gameRenderWorld->UpdateEntityDef( steamModelDefHandle, &steamRenderEntity ); - } - - idAFEntity_Base::Think(); -} - - -/* -=============================================================================== - - editor support routines - -=============================================================================== -*/ - - -/* -================ -idGameEdit::AF_SpawnEntity -================ -*/ -bool idGameEdit::AF_SpawnEntity( const char *fileName ) { - idDict args; - idPlayer *player; - idAFEntity_Generic *ent; - const idDeclAF *af; - idVec3 org; - float yaw; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk( false ) ) { - return false; - } - - af = static_cast( declManager->FindType( DECL_AF, fileName ) ); - if ( !af ) { - return false; - } - - yaw = player->viewAngles.yaw; - args.Set( "angle", va( "%f", yaw + 180 ) ); - org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); - args.Set( "origin", org.ToString() ); - args.Set( "spawnclass", "idAFEntity_Generic" ); - if ( af->model[0] ) { - args.Set( "model", af->model.c_str() ); - } else { - args.Set( "model", fileName ); - } - if ( af->skin[0] ) { - args.Set( "skin", af->skin.c_str() ); - } - args.Set( "articulatedFigure", fileName ); - args.Set( "nodrop", "1" ); - ent = static_cast(gameLocal.SpawnEntityType( idAFEntity_Generic::Type, &args)); - - // always update this entity - ent->BecomeActive( TH_THINK ); - ent->KeepRunningPhysics(); - ent->fl.forcePhysicsUpdate = true; - - player->dragEntity.SetSelected( ent ); - - return true; -} - -/* -================ -idGameEdit::AF_UpdateEntities -================ -*/ -void idGameEdit::AF_UpdateEntities( const char *fileName ) { - idEntity *ent; - idAFEntity_Base *af; - idStr name; - - name = fileName; - name.StripFileExtension(); - - // reload any idAFEntity_Generic which uses the given articulated figure file - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( idAFEntity_Base::Type ) ) { - af = static_cast(ent); - if ( name.Icmp( af->GetAFName() ) == 0 ) { - af->LoadAF(); - af->GetAFPhysics()->PutToRest(); - } - } - } -} - -/* -================ -idGameEdit::AF_UndoChanges -================ -*/ -void idGameEdit::AF_UndoChanges( void ) { - int i, c; - idEntity *ent; - idAFEntity_Base *af; - idDeclAF *decl; - - c = declManager->GetNumDecls( DECL_AF ); - for ( i = 0; i < c; i++ ) { - decl = static_cast( const_cast( declManager->DeclByIndex( DECL_AF, i, false ) ) ); - if ( !decl->modified ) { - continue; - } - - decl->Invalidate(); - declManager->FindType( DECL_AF, decl->GetName() ); - - // reload all AF entities using the file - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( idAFEntity_Base::Type ) ) { - af = static_cast(ent); - if ( idStr::Icmp( decl->GetName(), af->GetAFName() ) == 0 ) { - af->LoadAF(); - } - } - } - } -} - -/* -================ -GetJointTransform -================ -*/ -typedef struct { - renderEntity_t *ent; - const idMD5Joint *joints; -} jointTransformData_t; - -static bool GetJointTransform( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ) { - int i; - jointTransformData_t *data = reinterpret_cast(model); - - for ( i = 0; i < data->ent->numJoints; i++ ) { - if ( data->joints[i].name.Icmp( jointName ) == 0 ) { - break; - } - } - if ( i >= data->ent->numJoints ) { - return false; - } - origin = frame[i].ToVec3(); - axis = frame[i].ToMat3(); - return true; -} - -/* -================ -GetArgString -================ -*/ -static const char *GetArgString( const idDict &args, const idDict *defArgs, const char *key ) { - const char *s; - - s = args.GetString( key ); - if ( !s[0] && defArgs ) { - s = defArgs->GetString( key ); - } - return s; -} - -/* -================ -idGameEdit::AF_CreateMesh -================ -*/ -idRenderModel *idGameEdit::AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet ) { - int i(0), jointNum(0); - const idDeclAF *af(NULL); - const idDeclAF_Body *fb(NULL); - renderEntity_t ent; - idVec3 origin, *bodyOrigin(NULL), *newBodyOrigin(NULL), *modifiedOrigin(NULL); - idMat3 axis, *bodyAxis(NULL), *newBodyAxis(NULL), *modifiedAxis(NULL); - declAFJointMod_t *jointMod(NULL); - idAngles angles; - const idDict *defArgs(NULL); - const idKeyValue *arg(NULL); - idStr name; - jointTransformData_t data; - const char *classname(NULL), *afName(NULL), *modelName(NULL); - idRenderModel *md5(NULL); - const idDeclModelDef *modelDef(NULL); - const idMD5Anim *MD5anim(NULL); - const idMD5Joint *MD5joint(NULL); - const idMD5Joint *MD5joints(NULL); - int numMD5joints; - idJointMat *originalJoints(NULL); - int parentNum; - - poseIsSet = false; - meshOrigin.Zero(); - meshAxis.Identity(); - - classname = args.GetString( "classname" ); - defArgs = gameLocal.FindEntityDefDict( classname ); - - // get the articulated figure - afName = GetArgString( args, defArgs, "articulatedFigure" ); - af = static_cast( declManager->FindType( DECL_AF, afName ) ); - if ( !af ) { - return NULL; - } - - // get the md5 model - modelName = GetArgString( args, defArgs, "model" ); - modelDef = static_cast< const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, modelName, false ) ); - if ( !modelDef ) { - return NULL; - } - - // make sure model hasn't been purged - if ( modelDef->ModelHandle() && !modelDef->ModelHandle()->IsLoaded() ) { - modelDef->ModelHandle()->LoadModel(); - } - - // get the md5 - md5 = modelDef->ModelHandle(); - if ( !md5 || md5->IsDefaultModel() ) { - return NULL; - } - - // get the articulated figure pose anim - int animNum = modelDef->GetAnim( "af_pose" ); - if ( !animNum ) { - return NULL; - } - const idAnim *anim = modelDef->GetAnim( animNum ); - if ( !anim ) { - return NULL; - } - MD5anim = anim->MD5Anim( 0 ); - MD5joints = md5->GetJoints(); - numMD5joints = md5->NumJoints(); - - // setup a render entity - memset( &ent, 0, sizeof( ent ) ); - ent.customSkin = modelDef->GetSkin(); - ent.bounds.Clear(); - ent.numJoints = numMD5joints; - ent.joints = ( idJointMat * )_alloca16( ent.numJoints * sizeof( *ent.joints ) ); - - // create animation from of the af_pose - ANIM_CreateAnimFrame( md5, MD5anim, ent.numJoints, ent.joints, 1, modelDef->GetVisualOffset(), false ); - - // buffers to store the initial origin and axis for each body - bodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) ); - bodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) ); - newBodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) ); - newBodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) ); - - // finish the AF positions - data.ent = &ent; - data.joints = MD5joints; - af->Finish( GetJointTransform, ent.joints, &data ); - - // get the initial origin and axis for each AF body - for ( i = 0; i < af->bodies.Num(); i++ ) { - fb = af->bodies[i]; - - if ( fb->modelType == TRM_BONE ) { - // axis of bone trace model - axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3(); - axis[2].Normalize(); - axis[2].NormalVectors( axis[0], axis[1] ); - axis[1] = -axis[1]; - } else { - axis = fb->angles.ToMat3(); - } - - newBodyOrigin[i] = bodyOrigin[i] = fb->origin.ToVec3(); - newBodyAxis[i] = bodyAxis[i] = axis; - } - - // get any new body transforms stored in the key/value pairs - for ( arg = args.MatchPrefix( "body ", NULL ); arg; arg = args.MatchPrefix( "body ", arg ) ) { - name = arg->GetKey(); - name.Strip( "body " ); - for ( i = 0; i < af->bodies.Num(); i++ ) { - fb = af->bodies[i]; - if ( fb->name.Icmp( name ) == 0 ) { - break; - } - } - if ( i >= af->bodies.Num() ) { - continue; - } - sscanf( arg->GetValue(), "%f %f %f %f %f %f", &origin.x, &origin.y, &origin.z, &angles.pitch, &angles.yaw, &angles.roll ); - - if ( fb->jointName.Icmp( "origin" ) == 0 ) { - meshAxis = bodyAxis[i].Transpose() * angles.ToMat3(); - meshOrigin = origin - bodyOrigin[i] * meshAxis; - poseIsSet = true; - } else { - newBodyOrigin[i] = origin; - newBodyAxis[i] = angles.ToMat3(); - } - } - - // save the original joints - originalJoints = ( idJointMat * )_alloca16( numMD5joints * sizeof( originalJoints[0] ) ); - memcpy( originalJoints, ent.joints, numMD5joints * sizeof( originalJoints[0] ) ); - - // buffer to store the joint mods - jointMod = (declAFJointMod_t *) _alloca16( numMD5joints * sizeof( declAFJointMod_t ) ); - memset( jointMod, -1, numMD5joints * sizeof( declAFJointMod_t ) ); - modifiedOrigin = (idVec3 *) _alloca16( numMD5joints * sizeof( idVec3 ) ); - memset( modifiedOrigin, 0, numMD5joints * sizeof( idVec3 ) ); - modifiedAxis = (idMat3 *) _alloca16( numMD5joints * sizeof( idMat3 ) ); - memset( modifiedAxis, 0, numMD5joints * sizeof( idMat3 ) ); - - // get all the joint modifications - for ( i = 0; i < af->bodies.Num(); i++ ) { - fb = af->bodies[i]; - - if ( fb->jointName.Icmp( "origin" ) == 0 ) { - continue; - } - - for ( jointNum = 0; jointNum < numMD5joints; jointNum++ ) { - if ( MD5joints[jointNum].name.Icmp( fb->jointName ) == 0 ) { - break; - } - } - - if ( jointNum >= 0 && jointNum < ent.numJoints ) { - jointMod[ jointNum ] = fb->jointMod; - modifiedAxis[ jointNum ] = ( bodyAxis[i] * originalJoints[jointNum].ToMat3().Transpose() ).Transpose() * ( newBodyAxis[i] * meshAxis.Transpose() ); - // FIXME: calculate correct modifiedOrigin - modifiedOrigin[ jointNum ] = originalJoints[ jointNum ].ToVec3(); - } - } - - // apply joint modifications to the skeleton - MD5joint = MD5joints + 1; - for( i = 1; i < numMD5joints; i++, MD5joint++ ) { - - parentNum = MD5joint->parent - MD5joints; - idMat3 parentAxis = originalJoints[ parentNum ].ToMat3(); - idMat3 localm = originalJoints[i].ToMat3() * parentAxis.Transpose(); - idVec3 localt = ( originalJoints[i].ToVec3() - originalJoints[ parentNum ].ToVec3() ) * parentAxis.Transpose(); - - switch( jointMod[i] ) { - case DECLAF_JOINTMOD_ORIGIN: { - ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() ); - ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] ); - break; - } - case DECLAF_JOINTMOD_AXIS: { - ent.joints[ i ].SetRotation( modifiedAxis[ i ] ); - ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() ); - break; - } - case DECLAF_JOINTMOD_BOTH: { - ent.joints[ i ].SetRotation( modifiedAxis[ i ] ); - ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] ); - break; - } - default: { - ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() ); - ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() ); - break; - } - } - } - - // instantiate a mesh using the joint information from the render entity - return md5->InstantiateDynamicModel( &ent, NULL, NULL ); -} diff --git a/game/afentity.h b/game/afentity.h deleted file mode 100644 index b485585bd..000000000 --- a/game/afentity.h +++ /dev/null @@ -1,644 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_AFENTITY_H__ -#define __GAME_AFENTITY_H__ - - -/* -=============================================================================== - -idMultiModelAF - -Entity using multiple separate visual models animated with a single -articulated figure. Only used for debugging! - -=============================================================================== -*/ -const int GIB_DELAY = 200; // only gib this often to keep performace hits when blowing up several mobs - -class idMultiModelAF : public idEntity { -public: - CLASS_PROTOTYPE( idMultiModelAF ); - - void Spawn( void ); - virtual ~idMultiModelAF( void ); - - virtual void Think( void ); - virtual void Present( void ); - -protected: - /** - * Parsing attachments happens at a different time in the spawn routine for - * idAFEntities. To accomplish this, the function is overloaded to do - * nothing and a new function is called at the proper time. - **/ - virtual void ParseAttachments( void ); - - /** - * Same as idEntity::ParseAttachments, but called at a different point in spawn routine - **/ - virtual void ParseAttachmentsAF( void ); - -protected: - idPhysics_AF physicsObj; - - void SetModelForId( int id, const idStr &modelName ); - -private: - idList modelHandles; - idList modelDefHandles; -}; - - -/* -=============================================================================== - -idChain - -Chain hanging down from the ceiling. Only used for debugging! - -=============================================================================== -*/ - -class idChain : public idMultiModelAF { -public: - CLASS_PROTOTYPE( idChain ); - - void Spawn( void ); - -protected: - void BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld = true ); -}; - - -/* -=============================================================================== - -idAFAttachment - -=============================================================================== -*/ - -class idAFAttachment : public idAnimatedEntity { -public: - CLASS_PROTOTYPE( idAFAttachment ); - - idAFAttachment( void ); - virtual ~idAFAttachment( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void SetBody( idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint ); - void ClearBody( void ); - idEntity * GetBody( void ) const; - // ishtvan: Added this - jointHandle_t GetAttachJoint( void ) const; - - bool IsMantleable( void ); - - virtual void Think( void ); - - virtual void Hide( void ); - virtual void Show( void ); - - void PlayIdleAnim( int blendTime ); - - virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); - virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); - - virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, - const int location, trace_t *tr = NULL ); - virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); - - void SetCombatModel( void ); - idClipModel * GetCombatModel( void ) const; - virtual void LinkCombat( void ); - virtual void UnlinkCombat( void ); - - /** - * greebo: Virtual override of idEntity::GetResponseEntity(). This is used - * to relay stims to the "body" entity. - */ - virtual idEntity* GetResponseEntity(); - - /** - * Overload bind notify so that when another idAFAttachment is - * bound to us, we copy over our data on the actor we're bound to - **/ - virtual void BindNotify( idEntity *ent ); - - /** - * Also overload UnbindNotify to update the clipmodel physics on the AF we're attacehd to - **/ - virtual void UnbindNotify( idEntity *ent ); - - /** Also overload PostUnBind to clear the body information **/ - virtual void PostUnbind( void ); - - /** Use this to set up stuff attached to AI's heads when they go ragdoll **/ - virtual void DropOnRagdoll( void ); - -protected: - idEntity * body; - idClipModel * combatModel; // render model for hit detection of head - int idleAnim; - jointHandle_t attachJoint; - -protected: - /** - * Copy idActor bindmaster information to another idAFAttachment - **/ - void CopyBodyTo( idAFAttachment *other ); -}; - - -/* -=============================================================================== - -idAFEntity_Base - -=============================================================================== -*/ - -/** -* TDM: Used for dynamically adding ents with clipmodels to the AF -**/ -typedef struct SAddedEnt_s -{ - idEntityPtr ent; // associated entity - - // Must store string name because body ID's get reassigned when any are deleted - idStr bodyName; - // don't need to store constraint since they are deleted along with body - - idStr AddedToBody; // original body we added on to - - int entContents; // original entity clipmodel contents - int entClipMask; // original entity clipmask - int bodyContents; // AF body contents (for saving/restoring) - int bodyClipMask; // AF body clipmask (for saving/restoring) -} SAddedEnt; - - -class idAFEntity_Base : public idAnimatedEntity -{ -public: - CLASS_PROTOTYPE( idAFEntity_Base ); - - idAFEntity_Base( void ); - virtual ~idAFEntity_Base( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); - virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); - virtual bool UpdateAnimationControllers( void ); - virtual void FreeModelDef( void ); - - virtual bool LoadAF( void ); - bool IsActiveAF( void ) const { return af.IsActive(); } - const char * GetAFName( void ) const { return af.GetName(); } - idPhysics_AF * GetAFPhysics( void ) { return af.GetPhysics(); } - - virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, - const int location, trace_t *tr = NULL ); - void SetCombatModel( void ); - idClipModel * GetCombatModel( void ) const; - - // set contents of combatModel to 0 (if false) or restore proper contents (if true) - // returns the contents state before call (false = were disabled, true = were enabled) - bool SetCombatContents( bool enable ); - virtual void LinkCombat( void ); - virtual void UnlinkCombat( void ); - - int BodyForClipModelId( int id ) const; - - void SaveState( idDict &args ) const; - void LoadState( const idDict &args ); - - void AddBindConstraints( void ); - void RemoveBindConstraints( void ); - - /** - * Called when the given ent is about to be unbound/detached - * Updates m_AddedEnts if this ent's clipmodel was added to the AF - **/ - virtual void UnbindNotify( idEntity *ent ); - - /** - * Overloaded idAnimatedEntity::ReAttach methods to take into account AF body clipmask and contents - **/ - virtual void ReAttachToCoords( const char *AttName, idStr jointName, idVec3 offset, idAngles angles ); - virtual void ReAttachToPos( const char *AttName, const char *PosName ); - - /** - * TDM: Adds the clipmodel of the given entity to the AF structure - * Called during the binding process - * AddEntByBody is called by BindToBody, AddEntByJoint called by BindToJoint - * AddEntByBody takes an option joint argument to control the positin of the body with a joint - * If this is not specified, joint information is copied from the AF body we bind to - **/ - void AddEntByBody( idEntity *ent, int bodyID, jointHandle_t joint = INVALID_JOINT ); - void AddEntByJoint( idEntity *ent, jointHandle_t joint ); - - /** - * TDM: Remove a dynamically added ent from the AF of this AFEntity - * Called by UnBindNotify - **/ - void RemoveAddedEnt( idEntity *ent ); - - /** - * TDM: Get an AF body ID for a given joint, and vice versa - **/ - jointHandle_t JointForBody( int body ); - int BodyForJoint( jointHandle_t joint ); - - /** - * TDM: Get AF body for the given added entity - * returns NULL if added ent could not be found - **/ - idAFBody * AFBodyForEnt( idEntity *ent ); - - virtual void ShowEditingDialog( void ); - - static void DropAFs( idEntity *ent, const char *type, idList *list ); - - /** - * Return whether this entity should collide with its team when bound to a team - **/ - bool CollidesWithTeam( void ); - -public: - /** - * This AF should not be able to be picked up off the ground completely when dragged - **/ - bool m_bGroundWhenDragged; - - /** - * List of integer Id's of "critical" bodies to check for touching the ground - * when seeing if the AF is being lifted off the ground - **/ - idList m_GroundBodyList; - - /** - * Number of "critical" bodies that must be kept on the ground at all times - * If the number is below this, dragging the AF up will not be allowed - **/ - int m_GroundBodyMinNum; - - /** - * If set to true, this will use the "af" damping when being grabbed instead of the default damping - **/ - bool m_bDragAFDamping; - -protected: - idAF af; // articulated figure - idClipModel * combatModel; // render model for hit detection - int combatModelContents; - idVec3 spawnOrigin; // spawn origin - idMat3 spawnAxis; // rotation axis used when spawned - int nextSoundTime; // next time this can make a sound - - /** - * List of ents that have been dynamically added to the AF via binding - **/ - idList m_AddedEnts; - - /** - * Set to true if this entity should collide with team members when bound to them - **/ - bool m_bCollideWithTeam; - - /** - * Set to true if this animated AF should activate the AF body collision models - * and move them around to collide with the world when animating. - * NOTE: This MUST be set on AI in order for animation-based tactile alert - * to work properly. - **/ - bool m_bAFPushMoveables; - -protected: - /** - * Set up grounding vars, which apply when the AF might not be able to be - * lifted completely off the ground by the player - **/ - void SetUpGroundingVars( void ); - - void Event_SetConstraintPosition( const char *name, const idVec3 &pos ); - - /** - * GetNumBodies returns the number of bodies in the AF. - * If the AF physics pointer is NULL, it returns 0. - **/ - void Event_GetNumBodies( void ); - - /** - * Parsing attachments happens at a different time in the spawn routine for - * idAFEntities. To accomplish this, the function is overloaded to do - * nothing and a new function is called at the proper time. - **/ - virtual void ParseAttachments( void ); - - /** - * Same as idEntity::ParseAttachments, but called at a different point in spawn routine - **/ - virtual void ParseAttachmentsAF( void ); - - /** - * Restore attached entities that have been added to the AF after a save - **/ - virtual void RestoreAddedEnts( void ); - - /** - * Updates added ent constraints when going ragdoll, to resolve issue of ents bound to joints that can animate and move without the AF body moving - **/ - virtual void UpdateAddedEntConstraints( void ); - - /** - * Set the linear and angular velocities of a particular body given by ID argument - * If the ID is invalid, no velocity is set. - **/ - void Event_SetLinearVelocityB( idVec3 &NewVelocity, int id ); - void Event_SetAngularVelocityB( idVec3 &NewVelocity, int id ); - - /** - * Get the linear and angular velocities of a particular body given by int ID. - * If the body ID is invalid, returns (0,0,0) - **/ - void Event_GetLinearVelocityB( int id ); - void Event_GetAngularVelocityB( int id ); - -}; - -/* -=============================================================================== - -idAFEntity_Gibbable - -=============================================================================== -*/ - -extern const idEventDef EV_Gib; -extern const idEventDef EV_Gibbed; - -class idAFEntity_Gibbable : public idAFEntity_Base { -public: - CLASS_PROTOTYPE( idAFEntity_Gibbable ); - - idAFEntity_Gibbable( void ); - virtual ~idAFEntity_Gibbable( void ); - - void Spawn( void ); - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - virtual void Present( void ); - virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, - const float damageScale, const int location, trace_t *tr = NULL ); - virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName ); - -protected: - idRenderModel * skeletonModel; - int skeletonModelDefHandle; - bool gibbed; - - virtual void Gib( const idVec3 &dir, const char *damageDefName ); - void InitSkeletonModel( void ); - - void Event_Gib( const char *damageDefName ); -}; - -/* -=============================================================================== - - idAFEntity_Generic - -=============================================================================== -*/ - -class idAFEntity_Generic : public idAFEntity_Gibbable { -public: - CLASS_PROTOTYPE( idAFEntity_Generic ); - - idAFEntity_Generic( void ); - virtual ~idAFEntity_Generic( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - void KeepRunningPhysics( void ) { keepRunningPhysics = true; } - -private: - void Event_Activate( idEntity *activator ); - - bool keepRunningPhysics; -}; - - -/* -=============================================================================== - -idAFEntity_WithAttachedHead - -=============================================================================== -*/ - -class idAFEntity_WithAttachedHead : public idAFEntity_Gibbable { -public: - CLASS_PROTOTYPE( idAFEntity_WithAttachedHead ); - - idAFEntity_WithAttachedHead(); - virtual ~idAFEntity_WithAttachedHead(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void SetupHead( void ); - - virtual void Think( void ); - - virtual void Hide( void ); - virtual void Show( void ); - virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); - - virtual void LinkCombat( void ); - virtual void UnlinkCombat( void ); - -protected: - virtual void Gib( const idVec3 &dir, const char *damageDefName ); - -private: - idEntityPtr head; - - void Event_Gib( const char *damageDefName ); - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idAFEntity_Vehicle - -=============================================================================== -*/ - -class idAFEntity_Vehicle : public idAFEntity_Base { -public: - CLASS_PROTOTYPE( idAFEntity_Vehicle ); - - idAFEntity_Vehicle( void ); - - void Spawn( void ); - void Use( idPlayer *player ); - -protected: - idPlayer * player; - jointHandle_t eyesJoint; - jointHandle_t steeringWheelJoint; - float wheelRadius; - float steerAngle; - float steerSpeed; - const idDeclParticle * dustSmoke; - - float GetSteerAngle( void ); -}; - - -/* -=============================================================================== - -idAFEntity_VehicleSimple - -=============================================================================== -*/ - -class idAFEntity_VehicleSimple : public idAFEntity_Vehicle { -public: - CLASS_PROTOTYPE( idAFEntity_VehicleSimple ); - - idAFEntity_VehicleSimple( void ); - virtual ~idAFEntity_VehicleSimple( void ); - - void Spawn( void ); - virtual void Think( void ); - -protected: - idClipModel * wheelModel; - idAFConstraint_Suspension * suspension[4]; - jointHandle_t wheelJoints[4]; - float wheelAngles[4]; -}; - - -/* -=============================================================================== - -idAFEntity_VehicleFourWheels - -=============================================================================== -*/ - -class idAFEntity_VehicleFourWheels : public idAFEntity_Vehicle { -public: - CLASS_PROTOTYPE( idAFEntity_VehicleFourWheels ); - - idAFEntity_VehicleFourWheels( void ); - - void Spawn( void ); - virtual void Think( void ); - -protected: - idAFBody * wheels[4]; - idAFConstraint_Hinge * steering[2]; - jointHandle_t wheelJoints[4]; - float wheelAngles[4]; -}; - - -/* -=============================================================================== - -idAFEntity_VehicleSixWheels - -=============================================================================== -*/ - -class idAFEntity_VehicleSixWheels : public idAFEntity_Vehicle { -public: - CLASS_PROTOTYPE( idAFEntity_VehicleSixWheels ); - - idAFEntity_VehicleSixWheels( void ); - - void Spawn( void ); - virtual void Think( void ); - -private: - idAFBody * wheels[6]; - idAFConstraint_Hinge * steering[4]; - jointHandle_t wheelJoints[6]; - float wheelAngles[6]; -}; - - -/* -=============================================================================== - -idAFEntity_SteamPipe - -=============================================================================== -*/ - -class idAFEntity_SteamPipe : public idAFEntity_Base { -public: - CLASS_PROTOTYPE( idAFEntity_SteamPipe ); - - idAFEntity_SteamPipe( void ); - virtual ~idAFEntity_SteamPipe( void ); - - void Spawn( void ); - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - -private: - int steamBody; - float steamForce; - float steamUpForce; - idForce_Constant force; - renderEntity_t steamRenderEntity; - qhandle_t steamModelDefHandle; - - void InitSteamRenderEntity( void ); -}; - - -#endif /* !__GAME_AFENTITY_H__ */ diff --git a/game/ai/AAS.cpp b/game/ai/AAS.cpp new file mode 100644 index 000000000..b6af877c0 --- /dev/null +++ b/game/ai/AAS.cpp @@ -0,0 +1,522 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "AAS_local.h" + + +/* +============ +idAAS::Alloc +============ +*/ +idAAS *idAAS::Alloc( void ) { + return new idAASLocal; +} + +/* +============ +idAAS::idAAS +============ +*/ +idAAS::~idAAS( void ) { +} + +/* +============ +idAASLocal::idAASLocal +============ +*/ +idAASLocal::idAASLocal( void ) +{ + elevatorSystem = new eas::tdmEAS(this); + file = NULL; +} + +/* +============ +idAASLocal::~idAASLocal +============ +*/ +idAASLocal::~idAASLocal( void ) { + Shutdown(); + + if (elevatorSystem != NULL) + { + delete elevatorSystem; + } +} + +/* +============ +idAASLocal::Init +============ +*/ +bool idAASLocal::Init( const idStr &mapName, unsigned int mapFileCRC ) { + // Clear the elevator system before reloading + elevatorSystem->Clear(); + + if ( file && mapName.Icmp( file->GetName() ) == 0 && mapFileCRC == file->GetCRC() ) { + common->Printf( "Keeping %s\n", file->GetName() ); + RemoveAllObstacles(); + } + else { + Shutdown(); + + file = AASFileManager->LoadAAS( mapName, mapFileCRC ); + if ( !file ) { + common->DWarning( "Couldn't load AAS file: '%s'", mapName.c_str() ); + return false; + } + mapName.ExtractFileExtension(name); + + SetupRouting(); + } + return true; +} + +/* +============ +idAASLocal::Shutdown +============ +*/ +void idAASLocal::Shutdown( void ) { + if ( file ) { + elevatorSystem->Clear(); + ShutdownRouting(); + RemoveAllObstacles(); + AASFileManager->FreeAAS( file ); + file = NULL; + } +} + +/* +============ +idAASLocal::TestIfBarrierIsolatesReachability +============ +*/ +bool idAASLocal::TestIfBarrierIsolatesReachability +( + idReachability* p_reachability, + int areaIndex, + idBounds barrierBounds +) const +{ + /* + * Test params + */ + if ( p_reachability == NULL) + { + return false; + } + + // Test the paths from the reachability to all other reachabilities leaving + // the area. If a reachability has no path to another reachability that does not + // intersect the barrier, then return true. Also if there are no other reachbilities + // return true. Otherwise return false; + + // Iterate the other reachabilities + bool b_hadPath = false; + bool b_foundClearPath = false; + idReachability* p_reach2 = GetAreaFirstReachability(areaIndex); + + while (p_reach2 != NULL) + { + if (p_reach2 != p_reachability) + { + b_hadPath = true; + + // Test if path between the reachabilities is blocked by the barrier bounds + if (barrierBounds.LineIntersection (p_reachability->start, p_reach2->start)) + { + // Blocked + return true; + } + /* + // Its not blocked + b_foundClearPath = true; + } + */ + + } // Not same reachability + + // Is it blocked? + if (b_foundClearPath) + { + // End iteration early if we already found a clear path + p_reach2 = NULL; + } + else + { + p_reach2 = p_reach2->next; + } + + } // Next other reachability on same area + + return false; + + /* + + // Return result of test + if ( (b_hadPath) && (!b_foundClearPath) ) + { + // Its isolated by the bounds given + return true; + } + else + { + // Its not isolated by the bounds given + return false; + } + */ + +} + + +/* +============ +idAASLocal::Stats +============ +*/ +void idAASLocal::Stats( void ) const { + if ( !file ) { + return; + } + common->Printf( "[%s]\n", file->GetName() ); + file->PrintInfo(); + RoutingStats(); +} + +/* +============ +idAASLocal::GetSettings +============ +*/ +const idAASSettings *idAASLocal::GetSettings( void ) const { + if ( !file ) { + return NULL; + } + return &file->GetSettings(); +} + +/* +============ +idAASLocal::PointAreaNum +============ +*/ +int idAASLocal::PointAreaNum( const idVec3 &origin ) const { + if ( !file ) { + return 0; + } + return file->PointAreaNum( origin ); +} + +/* +============ +idAASLocal::PointReachableAreaNum +============ +*/ +int idAASLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const { + if ( !file ) { + return 0; + } + + return file->PointReachableAreaNum( origin, searchBounds, areaFlags, TFL_INVALID ); +} + +/* +============ +idAASLocal::BoundsReachableAreaNum +============ +*/ +int idAASLocal::BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const { + if ( !file ) { + return 0; + } + + return file->BoundsReachableAreaNum( bounds, areaFlags, TFL_INVALID ); +} + +/* +============ +idAASLocal::PushPointIntoAreaNum +============ +*/ +void idAASLocal::PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const { + if ( !file ) { + return; + } + file->PushPointIntoAreaNum( areaNum, origin ); +} + +/* +============ +idAASLocal::AreaCenter +============ +*/ +idVec3 idAASLocal::AreaCenter( int areaNum ) const { + if ( !file ) { + return vec3_origin; + } + return file->GetArea( areaNum ).center; +} + +/* +============ +idAASLocal::AreaFlags +============ +*/ +int idAASLocal::AreaFlags( int areaNum ) const { + if ( !file ) { + return 0; + } + return file->GetArea( areaNum ).flags; +} + +/* +============ +idAASLocal::AreaTravelFlags +============ +*/ +int idAASLocal::AreaTravelFlags( int areaNum ) const { + if ( !file ) { + return 0; + } + return file->GetArea( areaNum ).travelFlags; +} + +/* +============ +idAASLocal::Trace +============ +*/ +bool idAASLocal::Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const { + if ( !file ) { + trace.fraction = 0.0f; + trace.lastAreaNum = 0; + trace.numAreas = 0; + return true; + } + return file->Trace( trace, start, end ); +} + +/* +============ +idAASLocal::GetPlane +============ +*/ +const idPlane &idAASLocal::GetPlane( int planeNum ) const { + if ( !file ) { + static idPlane dummy; + return dummy; + } + return file->GetPlane( planeNum ); +} + +/* +============ +idAASLocal::GetEdgeVertexNumbers +============ +*/ +void idAASLocal::GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const { + if ( !file ) { + verts[0] = verts[1] = 0; + return; + } + const int *v = file->GetEdge( abs(edgeNum) ).vertexNum; + verts[0] = v[INTSIGNBITSET(edgeNum)]; + verts[1] = v[INTSIGNBITNOTSET(edgeNum)]; +} + +/* +============ +idAASLocal::GetEdge +============ +*/ +void idAASLocal::GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const { + if ( !file ) { + start.Zero(); + end.Zero(); + return; + } + const int *v = file->GetEdge( abs(edgeNum) ).vertexNum; + start = file->GetVertex( v[INTSIGNBITSET(edgeNum)] ); + end = file->GetVertex( v[INTSIGNBITNOTSET(edgeNum)] ); +} + + +/* +**********************************************************8 +Added for Darkmod by SophisticatedZombie +**********************************************************8 +*/ + + +/* +============ +idAASLocal::GetAreaBounds +============ +*/ +idBounds idAASLocal::GetAreaBounds( int areaNum ) const { + if ( !file ) + { + idBounds emptyBounds; + return emptyBounds; + } + return file->AreaBounds(areaNum); +} + +/* +============ +idAASLocal::GetNumAreas +============ +*/ +int idAASLocal::GetNumAreas() const +{ + if (!file) + { + return -1; + } + else + { + return file->GetNumAreas(); + } + +} + +/* +============ +idAASLocal::GetAreaFirstReachability +============ +*/ + +idReachability* idAASLocal::GetAreaFirstReachability(int areaNum) const +{ + if ( !file ) + { + return NULL; + } + aasArea_t area = file->GetArea (areaNum); + return area.reach; + +} + +void idAASLocal::SetAreaTravelFlag( int index, int flag ) +{ + if (file != NULL) + { + file->SetAreaTravelFlag(index, flag); + } +} + +void idAASLocal::RemoveAreaTravelFlag( int index, int flag ) +{ + if (file != NULL) + { + file->RemoveAreaTravelFlag(index, flag); + } +} + +int idAASLocal::GetClusterNum(int areaNum) +{ + return file->GetArea( areaNum ).cluster; +} + +void idAASLocal::ReferenceDoor(CFrobDoor* door, int areaNum) +{ + _doors[areaNum] = door; +} + +void idAASLocal::DeReferenceDoor(CFrobDoor* door, int areaNum) +{ + DoorMap::iterator found = _doors.find(areaNum); + + if (found != _doors.end()) + { + _doors.erase(found); + } +} + +CFrobDoor* idAASLocal::GetDoor(int areaNum) const +{ + DoorMap::const_iterator found = _doors.find(areaNum); + if (found != _doors.end()) + { + return found->second; + } + return NULL; +} + +void idAASLocal::Save(idSaveGame* savefile) const +{ + elevatorSystem->Save(savefile); +} + +void idAASLocal::Restore(idRestoreGame* savefile) +{ + elevatorSystem->Restore(savefile); +} + +/* +============ +idAASLocal::BuildReachbilityImpactList +============ +*/ + +bool idAASLocal::BuildReachabilityImpactList +( + TReachabilityTrackingList& inout_reachabilityList, + idBounds impactBounds +) const +{ + + // Start with empty list + inout_reachabilityList.Clear(); + + // For each area + int numAreas = GetNumAreas(); + for (int areaIndex = 0; areaIndex < numAreas; areaIndex ++) + { + // Test this area's reachabilties + idReachability* p_reach = GetAreaFirstReachability (areaIndex); + + while (p_reach != NULL) + { + // If this reachability is isolated by the impact bounds, then ad it to the list + if (TestIfBarrierIsolatesReachability (p_reach, areaIndex, impactBounds)) + { + inout_reachabilityList.Append (p_reach); + } + + // Next reachability + p_reach = p_reach->next; + + } // Reachability intersects given bounds + + + } // Next area + + // Done + return true; + +} diff --git a/game/ai/AAS.h b/game/ai/AAS.h new file mode 100644 index 000000000..f5d847c67 --- /dev/null +++ b/game/ai/AAS.h @@ -0,0 +1,278 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AAS_H__ +#define __AAS_H__ + +// Need linked list +#include "../../idlib/containers/List.h" +#include "EAS/RouteInfo.h" + +class CFrobDoor; + +#ifdef __linux__ +#include "tools/compilers/aas/AASFile.h" +#endif + +/* +=============================================================================== + + Area Awareness System + +=============================================================================== +*/ + +enum { + PATHTYPE_WALK, + PATHTYPE_WALKOFFLEDGE, + PATHTYPE_BARRIERJUMP, + PATHTYPE_JUMP, + PATHTYPE_DOOR, + PATHTYPE_ELEVATOR, // greebo: Added for TDM +}; + +typedef struct aasPath_s { + int type; // path type + idVec3 moveGoal; // point the AI should move towards + int moveAreaNum; // number of the area the AI should move towards + idVec3 secondaryGoal; // secondary move goal for complex navigation + const idReachability * reachability; // reachability used for navigation + eas::RouteInfoPtr elevatorRoute; // EAS reachability information (NULL if unused) + CFrobDoor* firstDoor; // angua: when a door is in the path, this is stored here (NULL otherwise) +} aasPath_t; + + +typedef struct aasGoal_s { + int areaNum; // area the goal is in + idVec3 origin; // position of goal +} aasGoal_t; + + +typedef struct aasObstacle_s { + idBounds absBounds; // absolute bounds of obstacle + idBounds expAbsBounds; // expanded absolute bounds of obstacle +} aasObstacle_t; + +class idAASCallback { +public: + virtual ~idAASCallback() {}; + virtual bool TestArea( const class idAAS *aas, int areaNum ) = 0; +}; + +typedef int aasHandle_t; + +/** +* This is the typedef for a reachability tracking list +*/ +typedef idList TReachabilityTrackingList; +namespace eas { class tdmEAS; } + +class idAAS { +public: + static idAAS * Alloc( void ); + virtual ~idAAS( void ) = 0; + // Initialize for the given map. + virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ) = 0; + // Print AAS stats. + virtual void Stats( void ) const = 0; + // Test from the given origin. + virtual void Test( const idVec3 &origin ) = 0; + // Get the AAS settings. + virtual const idAASSettings *GetSettings( void ) const = 0; + // Returns the number of the area the origin is in. + virtual int PointAreaNum( const idVec3 &origin ) const = 0; + // Returns the number of the nearest reachable area for the given point. + virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &bounds, const int areaFlags ) const = 0; + // Returns the number of the first reachable area in or touching the bounds. + virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const = 0; + + // Push the point into the area. + /** + * greebo: Copied from d3world: this is what brian from id said about PushPointIntoAreaNum: + * + * Quote: "If the point is already in the specified area, it does nothing, otherwise it 'pushes' + * the point into the area by moving it along the surface normal of all the planes that make up the area. + * Imagine if an area were a box and the point were outside the bottom right side of the box, + * it would first push the point along the right normal so it would be below the box, then it + * would push the point along the bottom normal so it would be inside the box." + * + * greebo: So basically, this alters the given idVec3 , so that it ends up being in the area box. + */ + virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const = 0; + + // Returns a reachable point inside the given area. + virtual idVec3 AreaCenter( int areaNum ) const = 0; + // Returns the area flags. + virtual int AreaFlags( int areaNum ) const = 0; + // Returns the travel flags for traveling through the area. + virtual int AreaTravelFlags( int areaNum ) const = 0; + // Trace through the areas and report the first collision. + virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0; + // Get a plane for a trace. + virtual const idPlane & GetPlane( int planeNum ) const = 0; + // Get wall edges. + virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const = 0; + // Sort the wall edges to create continuous sequences of walls. + virtual void SortWallEdges( int *edges, int numEdges ) const = 0; + // Get the vertex numbers for an edge. + virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const = 0; + // Get an edge. + virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const = 0; + // Find all areas within or touching the bounds with the given contents and disable/enable them for routing. + virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) = 0; + + // angua: disable / enable a specific area + virtual void DisableArea( int areanum ) = 0; + virtual void EnableArea( int areanum ) = 0; + + // Add an obstacle to the routing system. + virtual aasHandle_t AddObstacle( const idBounds &bounds ) = 0; + // Remove an obstacle from the routing system. + virtual void RemoveObstacle( const aasHandle_t handle ) = 0; + // Remove all obstacles from the routing system. + virtual void RemoveAllObstacles( void ) = 0; + // Returns the travel time towards the goal area in 100th of a second. + virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const = 0; + + /** + * greebo: Tries to set up a reachability between and . Uses the local routingcache. + * + * @areaNum/origin: the starting position and AAS area number. + * @goalAreaNum: The AAS area number of the destination + * @travelFlags: The allowed travelflags (used to determine which routing cache should be used). + * + * @travelTime: Will hold the total traveltime of the best reachability or 0 if no route is found. + * @reach: A reference to a idReachability* pointer. The pointer is set to NULL if no route is found, otherwise it contains the best reachability. + * @door: if there is a door in the path, this stores a pointer to in (NULL otherwise) + * @actor: the calling actor (optional). Is used to determine whether walk paths are valid (through locked doors, for instance). + * + * @returns TRUE if a route is available, FALSE otherwise. + * + * Note: A route is usually available if + * a) the goal area and the starting area are in the same cluster (no portals in between) + * b) the clusters are connected via a portal. + */ + // Get the travel time and first reachability to be used towards the goal, returns true if there is a path. + virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach, CFrobDoor** firstDoor, idActor* actor ) const = 0; + + /** + * greebo: Tries to set up a walk path from areaNum/origin to goalAreaNum/goalOrigin for the given travel flags. + * + * @path: The path structure which will contain the resulting path information. Will contain the starting point if no path is found. + * @areaNum/origin: the AAS area number and origin of the starting point. + * @goalAreaNum/goalOrigin: the AAS area number and origin of the destination. + * @travelFlags: the allowed travelflags (e.g. TFL_WALK|TFL_DOOR) + * @actor: The calling actor (optional), this is used to identify locked doors, which the actor is aware of. + * + * @returns: TRUE if a walk path could be found, FALSE otherwise. + */ + // Creates a walk path towards the goal. + virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ) = 0; + + /** + * Returns true if one can walk along a straight line from the origin to the goal origin. + * angua: actor is used to handle AI-specific pathing, such as forbidden areas (e.g. locked doors) + * actor can be NULL + */ + virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor ) const = 0; + // Creates a fly path towards the goal. + virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0; + // Returns true if one can fly along a straight line from the origin to the goal origin. + virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0; + // Show the walk path from the origin towards the area. + virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) = 0; + // Show the fly path from the origin towards the area. + virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0; + // Find the nearest goal which satisfies the callback. + virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxDistance=0 ) const = 0; + + // Find the goal cloest to the target which satisfies the callback. + virtual bool FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const = 0; + + // Added for DarkMod by SophisticatedZombie(DMH) + virtual idBounds GetAreaBounds (int areaNum) const = 0; + virtual int GetNumAreas() const = 0; + virtual idReachability* GetAreaFirstReachability(int areaNum) const = 0; + + virtual void SetAreaTravelFlag( int index, int flag ) = 0; + virtual void RemoveAreaTravelFlag( int index, int flag ) = 0; + + virtual void ReferenceDoor(CFrobDoor* door, int areaNum) = 0; + virtual void DeReferenceDoor(CFrobDoor* door, int areaNum) = 0; + + virtual CFrobDoor* GetDoor(int areaNum) const = 0; + + /** + * This function fills a reachability list + * given an aas and the bounds for which any + * intersecting reachabilities should be considered + * impacted. + * + * @param inout_reachbilityList The list which will be + * initialized to only the idReachability pointers + * which are intersected by the impactBounds parameter + * + * @param impactBounds The bounds we check against + * reachabilities for intersection to determine impact. + * + * @return true on success + * + * @return false on failure + */ + virtual bool BuildReachabilityImpactList + ( + TReachabilityTrackingList& inout_reachabilityList, + idBounds impactBounds + ) const = 0; + + /** + * This method tests if a reachability is cut off from all + * other reachabilities in the same area by the bounds + * given. Note that iff there are no other reachabilities on + * then the reachability is NOT considered isolated. + * + * @param p_reachability The reachability that we are testing + * to see if the given barrierBounds isolate it from any + * other reachabilities on the same area. + * + * @param areaIndex The index of the area to which the reachability belongs + * + * @param barrierBounds The bounds of the barrier we are considering + * + * @return true if the reachability is isolated by the given bounds + * from all other reachbailities on the same area + * + * @return false otherwise + */ + virtual bool TestIfBarrierIsolatesReachability + ( + idReachability* p_reachability, + int areaIndex, + idBounds barrierBounds + ) const = 0; + + // Accessor function for the EAS + virtual eas::tdmEAS* GetEAS() = 0; + + // Save/Restore routines + virtual void Save(idSaveGame* savefile) const = 0; + virtual void Restore(idRestoreGame* savefile) = 0; +}; + +#endif /* !__AAS_H__ */ diff --git a/game/ai/AAS_debug.cpp b/game/ai/AAS_debug.cpp new file mode 100644 index 000000000..327b8c82f --- /dev/null +++ b/game/ai/AAS_debug.cpp @@ -0,0 +1,569 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "AAS_local.h" +#include "../Game_local.h" // for cvars and debug drawing + + +/* +============ +idAASLocal::DrawCone +============ +*/ +void idAASLocal::DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const { + int i; + idMat3 axis; + idVec3 center, top, p, lastp; + + axis[2] = dir; + axis[2].NormalVectors( axis[0], axis[1] ); + axis[1] = -axis[1]; + + center = origin + dir; + top = center + dir * (3.0f * radius); + lastp = center + radius * axis[1]; + + for ( i = 20; i <= 360; i += 20 ) { + p = center + sin( DEG2RAD(i) ) * radius * axis[0] + cos( DEG2RAD(i) ) * radius * axis[1]; + gameRenderWorld->DebugLine( color, lastp, p, 0 ); + gameRenderWorld->DebugLine( color, p, top, 0 ); + lastp = p; + } +} + +/* +============ +idAASLocal::DrawReachability +============ +*/ +void idAASLocal::DrawReachability( const idReachability *reach ) const +{ + idVec4 reachColor = colorCyan; + if (reach->travelType & TFL_DOOR) + { + reachColor = colorRed; + } + gameRenderWorld->DebugArrow( reachColor, reach->start, reach->end, 1, 10000 ); + + gameRenderWorld->DebugArrow( colorLtGrey, AreaCenter(reach->fromAreaNum), AreaCenter(reach->toAreaNum), 1, 10000); + + if ( gameLocal.GetLocalPlayer() ) { + gameRenderWorld->DrawText( va( "%d", reach->edgeNum ), ( reach->start + reach->end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAxis, 1, 10000 ); + } + + switch( reach->travelType ) { + case TFL_WALK: { +// const idReachability_Walk *walk = static_cast(reach); + break; + } + default: { + break; + } + } +} + +/* +============ +idAASLocal::DrawEdge +============ +*/ +void idAASLocal::DrawEdge( int edgeNum, bool arrow ) const { + const aasEdge_t *edge; + idVec4 *color; + + if ( !file ) { + return; + } + + edge = &file->GetEdge( edgeNum ); + color = &colorRed; + if ( arrow ) { + gameRenderWorld->DebugArrow( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ), 1 ); + } else { + gameRenderWorld->DebugLine( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ) ); + } + + if ( gameLocal.GetLocalPlayer() ) { + gameRenderWorld->DrawText( va( "%d", edgeNum ), ( file->GetVertex( edge->vertexNum[0] ) + file->GetVertex( edge->vertexNum[1] ) ) * 0.5f + idVec3(0,0,4), 0.1f, colorRed, gameLocal.GetLocalPlayer()->viewAxis ); + } +} + +/* +============ +idAASLocal::DrawFace +============ +*/ +void idAASLocal::DrawFace( int faceNum, bool side ) const { + int i, j, numEdges, firstEdge; + const aasFace_t *face; + idVec3 mid, end; + + if ( !file ) { + return; + } + + face = &file->GetFace( faceNum ); + numEdges = face->numEdges; + firstEdge = face->firstEdge; + + mid = vec3_origin; + for ( i = 0; i < numEdges; i++ ) { + DrawEdge( abs( file->GetEdgeIndex( firstEdge + i ) ), ( face->flags & FACE_FLOOR ) != 0 ); + j = file->GetEdgeIndex( firstEdge + i ); + mid += file->GetVertex( file->GetEdge( abs( j ) ).vertexNum[ j < 0 ] ); + } + + mid /= numEdges; + if ( side ) { + end = mid - 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal(); + } else { + end = mid + 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal(); + } + gameRenderWorld->DebugArrow( colorGreen, mid, end, 1 ); +} + +/* +============ +idAASLocal::DrawArea +============ +*/ +void idAASLocal::DrawArea( int areaNum ) const { + int i, numFaces, firstFace; + const aasArea_t *area; + idReachability *reach; + + if ( !file ) { + return; + } + + area = &file->GetArea( areaNum ); + numFaces = area->numFaces; + firstFace = area->firstFace; + + for ( i = 0; i < numFaces; i++ ) { + DrawFace( abs( file->GetFaceIndex( firstFace + i ) ), file->GetFaceIndex( firstFace + i ) < 0 ); + } + + for ( reach = area->reach; reach; reach = reach->next ) { + DrawReachability( reach ); + } +} + +/* +============ +idAASLocal::DefaultSearchBounds +============ +*/ +const idBounds &idAASLocal::DefaultSearchBounds( void ) const { + return file->GetSettings().boundingBoxes[0]; +} + +/* +============ +idAASLocal::ShowArea +============ +*/ +void idAASLocal::ShowArea( const idVec3 &origin ) const { + static int lastAreaNum; + int areaNum; + const aasArea_t *area; + idVec3 org; + + areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + org = origin; + PushPointIntoAreaNum( areaNum, org ); + + if ( aas_goalArea.GetInteger() ) { + int travelTime; + idReachability *reach; + + RouteToGoalArea( areaNum, org, aas_goalArea.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach, NULL, NULL ); + gameLocal.Printf( "\rtt = %4d", travelTime ); + if ( reach ) { + gameLocal.Printf( " to area %4d", reach->toAreaNum ); + DrawArea( reach->toAreaNum ); + } + } + + if ( areaNum != lastAreaNum ) { + area = &file->GetArea( areaNum ); + gameLocal.Printf( "area %d: ", areaNum ); + if ( area->flags & AREA_LEDGE ) { + gameLocal.Printf( "AREA_LEDGE " ); + } + if (area->flags & AREA_DOOR) + { + gameLocal.Printf( "AREA_DOOR " ); + } + if ( area->flags & AREA_REACHABLE_WALK ) { + gameLocal.Printf( "AREA_REACHABLE_WALK " ); + } + if ( area->flags & AREA_REACHABLE_FLY ) { + gameLocal.Printf( "AREA_REACHABLE_FLY " ); + } + if ( area->contents & AREACONTENTS_CLUSTERPORTAL ) { + gameLocal.Printf( "AREACONTENTS_CLUSTERPORTAL " ); + } + if ( area->contents & AREACONTENTS_OBSTACLE ) { + gameLocal.Printf( "AREACONTENTS_OBSTACLE " ); + } + gameLocal.Printf( "\n" ); + lastAreaNum = areaNum; + } + + if ( org != origin ) { + idBounds bnds = file->GetSettings().boundingBoxes[ 0 ]; + bnds[ 1 ].z = bnds[ 0 ].z; + gameRenderWorld->DebugBounds( colorYellow, bnds, org ); + } + + DrawArea( areaNum ); +} + +/* +============ +idAASLocal::ShowWalkPath +============ +*/ +void idAASLocal::ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) { + int i, areaNum, curAreaNum, travelTime; + idReachability *reach; + idVec3 org, areaCenter; + aasPath_t path; + + if ( !file ) { + return; + } + + org = origin; + areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_WALK ); + PushPointIntoAreaNum( areaNum, org ); + curAreaNum = areaNum; + + for ( i = 0; i < 100; i++ ) { + + if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_AIR, travelTime, &reach, NULL, NULL ) ) { + break; + } + + if ( !reach ) { + break; + } + + gameRenderWorld->DebugArrow( colorGreen, org, reach->start, 1, 10000 ); + DrawReachability( reach ); + + if ( reach->toAreaNum == goalAreaNum ) { + break; + } + + curAreaNum = reach->toAreaNum; + org = reach->end; + } + + if ( WalkPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_AIR, NULL ) ) { + gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 1, 10000 ); + } +} + +/* +============ +idAASLocal::ShowFlyPath +============ +*/ +void idAASLocal::ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const { + int i, areaNum, curAreaNum, travelTime; + idReachability *reach; + idVec3 org, areaCenter; + aasPath_t path; + + if ( !file ) { + return; + } + + org = origin; + areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_FLY ); + PushPointIntoAreaNum( areaNum, org ); + curAreaNum = areaNum; + + for ( i = 0; i < 100; i++ ) { + + if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_FLY|TFL_AIR, travelTime, &reach, NULL, NULL ) ) { + break; + } + + if ( !reach ) { + break; + } + + gameRenderWorld->DebugArrow( colorPurple, org, reach->start, 2 ); + DrawReachability( reach ); + + if ( reach->toAreaNum == goalAreaNum ) { + break; + } + + curAreaNum = reach->toAreaNum; + org = reach->end; + } + + if ( FlyPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_FLY|TFL_AIR ) ) { + gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 ); + } +} + +/* +============ +idAASLocal::ShowWallEdges +============ +*/ +void idAASLocal::ShowWallEdges( const idVec3 &origin ) const { + int i, areaNum, numEdges, edges[1024]; + idVec3 start, end; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + + areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 ); + for ( i = 0; i < numEdges; i++ ) { + GetEdge( edges[i], start, end ); + gameRenderWorld->DebugLine( colorRed, start, end ); + gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis ); + } +} + +/* +============ +idAASLocal::ShowHideArea +============ +*/ +void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) { + int areaNum, numObstacles; + idVec3 target; + aasGoal_t goal; + aasObstacle_t obstacles[10]; + + areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + target = AreaCenter( targetAreaNum ); + + // consider the target an obstacle + obstacles[0].absBounds = idBounds( target ).Expand( 16 ); + numObstacles = 1; + + DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow ); + + idAASFindCover findCover( NULL, NULL, target ); + if ( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK|TFL_AIR, obstacles, numObstacles, findCover ) ) { + DrawArea( goal.areaNum ); + ShowWalkPath( origin, goal.areaNum, goal.origin ); + DrawCone( goal.origin, idVec3(0,0,1), 16.0f, colorWhite ); + } +} + +/* +============ +idAASLocal::PullPlayer +============ +*/ +bool idAASLocal::PullPlayer( const idVec3 &origin, int toAreaNum ) { + int areaNum; + idVec3 areaCenter, dir, vel; + idAngles delta; + aasPath_t path; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return true; + } + + idPhysics *physics = player->GetPhysics(); + if ( !physics ) { + return true; + } + + if ( !toAreaNum ) { + return false; + } + + areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + areaCenter = AreaCenter( toAreaNum ); + if ( player->GetPhysics()->GetAbsBounds().Expand( 8 ).ContainsPoint( areaCenter ) ) { + return false; + } + if ( WalkPathToGoal( path, areaNum, origin, toAreaNum, areaCenter, TFL_WALK|TFL_AIR, NULL ) ) { + dir = path.moveGoal - origin; + dir[2] *= 0.5f; + dir.Normalize(); + delta = dir.ToAngles() - player->cmdAngles - player->GetDeltaViewAngles(); + delta.Normalize180(); + player->SetDeltaViewAngles( player->GetDeltaViewAngles() + delta * 0.1f ); + dir[2] = 0.0f; + dir.Normalize(); + dir *= 100.0f; + vel = physics->GetLinearVelocity(); + dir[2] = vel[2]; + physics->SetLinearVelocity( dir ); + return true; + } + else { + return false; + } +} + +/* +============ +idAASLocal::RandomPullPlayer +============ +*/ +void idAASLocal::RandomPullPlayer( const idVec3 &origin ) { + int rnd, i, n; + + if ( !PullPlayer( origin, aas_pullPlayer.GetInteger() ) ) { + + rnd = gameLocal.random.RandomInt(file->GetNumAreas()); + + for ( i = 0; i < file->GetNumAreas(); i++ ) { + n = (rnd + i) % file->GetNumAreas(); + if ( file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { + aas_pullPlayer.SetInteger( n ); + } + } + } else { + ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); + } +} + +/* +============ +idAASLocal::ShowPushIntoArea +============ +*/ +void idAASLocal::ShowPushIntoArea( const idVec3 &origin ) const { + int areaNum; + idVec3 target; + + target = origin; + areaNum = PointReachableAreaNum( target, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + PushPointIntoAreaNum( areaNum, target ); + gameRenderWorld->DebugArrow( colorGreen, origin, target, 1 ); +} + +/* +============ +idAASLocal::Test +============ +*/ +void idAASLocal::Test( const idVec3 &origin ) { + + if ( !file ) { + return; + } + + if ( aas_randomPullPlayer.GetBool() ) { + RandomPullPlayer( origin ); + } + if ( ( aas_pullPlayer.GetInteger() > 0 ) && ( aas_pullPlayer.GetInteger() < file->GetNumAreas() ) ) { + ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); + PullPlayer( origin, aas_pullPlayer.GetInteger() ); + } + if ( ( aas_showPath.GetInteger() > 0 ) && ( aas_showPath.GetInteger() < file->GetNumAreas() ) ) { + ShowWalkPath( origin, aas_showPath.GetInteger(), AreaCenter( aas_showPath.GetInteger() ) ); + } + if ( ( aas_showFlyPath.GetInteger() > 0 ) && ( aas_showFlyPath.GetInteger() < file->GetNumAreas() ) ) { + ShowFlyPath( origin, aas_showFlyPath.GetInteger(), AreaCenter( aas_showFlyPath.GetInteger() ) ); + } + if ( ( aas_showHideArea.GetInteger() > 0 ) && ( aas_showHideArea.GetInteger() < file->GetNumAreas() ) ) { + ShowHideArea( origin, aas_showHideArea.GetInteger() ); + } + if ( aas_showAreas.GetBool() ) { + ShowArea( origin ); + } + if ( aas_showWallEdges.GetBool() ) { + ShowWallEdges( origin ); + } + if ( aas_showPushIntoArea.GetBool() ) { + ShowPushIntoArea( origin ); + } +} + +void idAASLocal::DrawAreas(const idVec3& playerOrigin) +{ + if (file == NULL) return; + + // Get a colour for each cluster + idList colours; + for (int c = 0; c < file->GetNumClusters(); c++) + { + colours.Alloc() = idVec4(gameLocal.random.RandomFloat() + 0.1f, gameLocal.random.RandomFloat() + 0.1f, gameLocal.random.RandomFloat() + 0.1f, 1); + } + + idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); + + idList clusterNums; + + for (int i = 0; i < file->GetNumAreas(); i++) + { + idBounds areaBounds = GetAreaBounds(i); + idVec3 areaCenter = AreaCenter(i); + + int clusterNum = file->GetArea(i).cluster; + clusterNums.AddUnique(clusterNum); + + idVec4 colour = (clusterNum <= 0) ? colorWhite : colours[clusterNum]; + + // angua: only draw areas near the player, no need to see them at the other end of the map + if ((areaCenter - playerOrigin).LengthFast() < 300) + { + gameRenderWorld->DrawText(va("%d", i), areaCenter, 0.2f, colour, playerViewMatrix, 1, 1000); + gameRenderWorld->DebugBox(colour, idBox(areaBounds), 1000); + } + } + + for (int i = 0; i < clusterNums.Num(); i++) + { + int area = GetAreaInCluster(clusterNums[i]); + if (area <= 0) continue; + + idVec3 origin = file->GetArea(area).center; + if ((origin - playerOrigin).LengthFast() < 1000) + { + gameRenderWorld->DrawText(va("%d", clusterNums[i]), origin, 1, colorRed, playerViewMatrix, 1, 1000); + } + } +} + +void idAASLocal::DrawEASRoute( const idVec3& playerOrigin, int goalArea ) +{ + idVec3 origin = playerOrigin; + int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + + PushPointIntoAreaNum( areaNum, origin ); + + elevatorSystem->DrawRoute(areaNum, goalArea); +} diff --git a/game/ai/AAS_local.h b/game/ai/AAS_local.h new file mode 100644 index 000000000..dee7c4d54 --- /dev/null +++ b/game/ai/AAS_local.h @@ -0,0 +1,262 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AAS_LOCAL_H__ +#define __AAS_LOCAL_H__ + +#include "AAS.h" +#include "../Pvs.h" +#include "EAS/EAS.h" +#include + +class CFrobDoor; + +class idRoutingCache { + friend class idAASLocal; + +public: + idRoutingCache( int size ); + ~idRoutingCache( void ); + + int Size( void ) const; + +private: + int type; // portal or area cache + int size; // size of cache + int cluster; // cluster of the cache + int areaNum; // area of the cache + int travelFlags; // combinations of the travel flags + idRoutingCache * next; // next in list + idRoutingCache * prev; // previous in list + idRoutingCache * time_next; // next in time based list + idRoutingCache * time_prev; // previous in time based list + unsigned short startTravelTime; // travel time to start with + unsigned char * reachabilities; // reachabilities used for routing + unsigned short * travelTimes; // travel time for every area +}; + + +class idRoutingUpdate { + friend class idAASLocal; + +private: + int cluster; // cluster number of this update + int areaNum; // area number of this update + unsigned short tmpTravelTime; // temporary travel time + unsigned short * areaTravelTimes; // travel times within the area + idVec3 start; // start point into area + idRoutingUpdate * next; // next in list + idRoutingUpdate * prev; // prev in list + bool isInList; // true if the update is in the list +}; + + +class idRoutingObstacle { + friend class idAASLocal; + idRoutingObstacle( void ) { } + +private: + idBounds bounds; // obstacle bounds + idList areas; // areas the bounds are in +}; + + +class CMultiStateMover; +namespace eas { class tdmEAS; } + +class idAASLocal : + public idAAS +{ + friend class eas::tdmEAS; // TDM's EAS is our friend + +public: + idAASLocal( void ); + virtual ~idAASLocal( void ); + virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ); + virtual void Shutdown( void ); + + virtual void Stats( void ) const; + virtual void Test( const idVec3 &origin ); + virtual const idAASSettings *GetSettings( void ) const; + virtual int PointAreaNum( const idVec3 &origin ) const; + virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const; + virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const; + virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const; + virtual idVec3 AreaCenter( int areaNum ) const; + virtual int AreaFlags( int areaNum ) const; + virtual int AreaTravelFlags( int areaNum ) const; + virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const; + virtual const idPlane & GetPlane( int planeNum ) const; + virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const; + virtual void SortWallEdges( int *edges, int numEdges ) const; + virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const; + virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const; + virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ); + virtual aasHandle_t AddObstacle( const idBounds &bounds ); + virtual void RemoveObstacle( const aasHandle_t handle ); + virtual void RemoveAllObstacles( void ); + virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const; + virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach, CFrobDoor** firstDoor, idActor* actor ) const; + virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ); + virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor) const; + virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const; + virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const; + virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ); + virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const; + virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxTravelCost=0 ) const; + virtual bool FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const; + + // Added for DarkMod by SophisticatedZombie(DMH) + virtual idBounds GetAreaBounds (int areaNum) const; + virtual int GetNumAreas() const; + virtual idReachability* GetAreaFirstReachability(int areaNum) const; + + virtual void SetAreaTravelFlag( int index, int flag ); + + virtual void RemoveAreaTravelFlag( int index, int flag ); + + // angua: this returns the cluster number of this area + virtual int GetClusterNum(int areaNum); + + virtual void ReferenceDoor(CFrobDoor* door, int areaNum); + virtual void DeReferenceDoor(CFrobDoor* door, int areaNum); + + CFrobDoor* GetDoor(int areaNum) const; + + /*! + * See base class for interface definition + */ + virtual bool BuildReachabilityImpactList + ( + TReachabilityTrackingList& inout_reachabilityList, + idBounds impactBounds + ) const ; + + /*! + * See base class for interface definition + */ + virtual bool TestIfBarrierIsolatesReachability + ( + idReachability* p_reachability, + int areaIndex, + idBounds barrierBounds + ) const; + + /** + * greebo: Adds the given elevator to this AAS class. This will add + * additional routing possibilities for AI between clusters. + */ + virtual void AddElevator(CMultiStateMover* mover); + + /** + * greebo: Assembles the elevator routing information. + */ + virtual void CompileEAS(); + + // Accessor function for the EAS + virtual eas::tdmEAS* GetEAS() { return elevatorSystem; } + + // Save/Restore routines + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + +private: + idAASFile * file; + idStr name; + + typedef std::map DoorMap; + DoorMap _doors; + + +private: // routing data + idRoutingCache *** areaCacheIndex; // for each area in each cluster the travel times to all other areas in the cluster + int areaCacheIndexSize; // number of area cache entries + idRoutingCache ** portalCacheIndex; // for each area in the world the travel times from each portal + int portalCacheIndexSize; // number of portal cache entries + idRoutingUpdate * areaUpdate; // memory used to update the area routing cache + idRoutingUpdate * portalUpdate; // memory used to update the portal routing cache + unsigned short * goalAreaTravelTimes; // travel times to goal areas + unsigned short * areaTravelTimes; // travel times through the areas + int numAreaTravelTimes; // number of area travel times + mutable idRoutingCache * cacheListStart; // start of list with cache sorted from oldest to newest + mutable idRoutingCache * cacheListEnd; // end of list with cache sorted from oldest to newest + mutable int totalCacheMemory; // total cache memory used + idList obstacleList; // list with obstacles + + // greebo: This is TDM's EAS "Elevator Awareness System" :) + eas::tdmEAS* elevatorSystem; + +private: // routing + bool SetupRouting( void ); + void ShutdownRouting( void ); + unsigned short AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const; + void CalculateAreaTravelTimes( void ); + void DeleteAreaTravelTimes( void ); + void SetupRoutingCache( void ); + void DeleteClusterCache( int clusterNum ); + void DeletePortalCache( void ); + void ShutdownRoutingCache( void ); + void RoutingStats( void ) const; + void LinkCache( idRoutingCache *cache ) const; + void UnlinkCache( idRoutingCache *cache ) const; + void DeleteOldestCache( void ) const; + idReachability * GetAreaReachability( int areaNum, int reachabilityNum ) const; + int ClusterAreaNum( int clusterNum, int areaNum ) const; + void UpdateAreaRoutingCache( idRoutingCache *areaCache ) const; + idRoutingCache * GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const; + void UpdatePortalRoutingCache( idRoutingCache *portalCache ) const; + idRoutingCache * GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const; + void RemoveRoutingCacheUsingArea( int areaNum ); + +public: + void DisableArea( int areaNum ); + void EnableArea( int areaNum ); + +private: + bool SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled ); + void GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList &areas ) const; + void SetObstacleState( const idRoutingObstacle *obstacle, bool enable ); + + // returns an area within that cluster (SLOW!), returns -1 if none found + int GetAreaInCluster(int clusterNum); + +private: // pathing + bool EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const; + bool FloorEdgeSplitPoint( idVec3 &split, int areaNum, const idPlane &splitPlane, const idPlane &frontPlane, bool closest ) const; + idVec3 SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum, idActor* actor ); + idVec3 SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const; + +public: // debug + const idBounds & DefaultSearchBounds( void ) const; + void DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const; + void DrawArea( int areaNum ) const; + void DrawFace( int faceNum, bool side ) const; + void DrawEdge( int edgeNum, bool arrow ) const; + void DrawReachability( const idReachability *reach ) const; + void ShowArea( const idVec3 &origin ) const; + void ShowWallEdges( const idVec3 &origin ) const; + void ShowHideArea( const idVec3 &origin, int targerAreaNum ); + bool PullPlayer( const idVec3 &origin, int toAreaNum ); + void RandomPullPlayer( const idVec3 &origin ); + void ShowPushIntoArea( const idVec3 &origin ) const; + void DrawAreas( const idVec3& playerOrigin ); + void DrawEASRoute( const idVec3& playerOrigin, int goalArea ); +}; + +#endif /* !__AAS_LOCAL_H__ */ diff --git a/game/ai/AAS_pathing.cpp b/game/ai/AAS_pathing.cpp new file mode 100644 index 000000000..4b52dc302 --- /dev/null +++ b/game/ai/AAS_pathing.cpp @@ -0,0 +1,741 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Source$ $Revision$ $Date$", init_version); + +#include "AAS_local.h" +#include "../TimerManager.h" + + +#define SUBSAMPLE_WALK_PATH 1 +#define SUBSAMPLE_FLY_PATH 0 + +const int maxWalkPathIterations = 10; +const float maxWalkPathDistance = 500.0f; +const float walkPathSampleDistance = 8.0f; + +const int maxFlyPathIterations = 10; +const float maxFlyPathDistance = 500.0f; +const float flyPathSampleDistance = 8.0f; + + +/* +============ +idAASLocal::EdgeSplitPoint + + calculates split point of the edge with the plane + returns true if the split point is between the edge vertices +============ +*/ +bool idAASLocal::EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const { + const aasEdge_t *edge; + idVec3 v1, v2; + float d1, d2; + + edge = &file->GetEdge( edgeNum ); + v1 = file->GetVertex( edge->vertexNum[0] ); + v2 = file->GetVertex( edge->vertexNum[1] ); + d1 = v1 * plane.Normal() - plane.Dist(); + d2 = v2 * plane.Normal() - plane.Dist(); + + //if ( (d1 < CM_CLIP_EPSILON && d2 < CM_CLIP_EPSILON) || (d1 > -CM_CLIP_EPSILON && d2 > -CM_CLIP_EPSILON) ) { + if ( FLOATSIGNBITSET( d1 ) == FLOATSIGNBITSET( d2 ) ) { + return false; + } + split = v1 + (d1 / (d1 - d2)) * (v2 - v1); + return true; +} + +/* +============ +idAASLocal::FloorEdgeSplitPoint + + calculates either the closest or furthest point on the floor of the area which also lies on the pathPlane + the point has to be on the front side of the frontPlane to be valid +============ +*/ +bool idAASLocal::FloorEdgeSplitPoint( idVec3 &bestSplit, int areaNum, const idPlane &pathPlane, const idPlane &frontPlane, bool closest ) const { + int i, j, faceNum, edgeNum; + const aasArea_t *area; + const aasFace_t *face; + idVec3 split; + float dist, bestDist; + + if ( closest ) { + bestDist = maxWalkPathDistance; + } else { + bestDist = -0.1f; + } + + area = &file->GetArea( areaNum ); + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = file->GetFaceIndex( area->firstFace + i ); + face = &file->GetFace( abs(faceNum) ); + + if ( !(face->flags & FACE_FLOOR ) ) { + continue; + } + + for ( j = 0; j < face->numEdges; j++ ) { + edgeNum = file->GetEdgeIndex( face->firstEdge + j ); + + if ( !EdgeSplitPoint( split, abs( edgeNum ), pathPlane ) ) { + continue; + } + dist = frontPlane.Distance( split ); + if ( closest ) { + if ( dist >= -0.1f && dist < bestDist ) { + bestDist = dist; + bestSplit = split; + } + } else { + if ( dist > bestDist ) { + bestDist = dist; + bestSplit = split; + } + } + } + } + + if ( closest ) { + return ( bestDist < maxWalkPathDistance ); + } else { + return ( bestDist > -0.1f ); + } +} + +/* +============ +idAASLocal::WalkPathValid + + returns true if one can walk in a straight line between origin and goalOrigin +============ +*/ +bool idAASLocal::WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor ) const { + + START_SCOPED_TIMING(actor->actorWalkPathValidTimer, scopedWalkPathValidTimer); + + int curAreaNum, lastAreaNum, lastAreas[4], lastAreaIndex; + idPlane pathPlane, frontPlane, farPlane; + idReachability *reach; + const aasArea_t *area; + idVec3 p, dir; + + if ( file == NULL ) { + endPos = goalOrigin; + endAreaNum = 0; + return true; + } + + lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum; + lastAreaIndex = 0; + + pathPlane.SetNormal( (goalOrigin - origin).Cross( file->GetSettings().gravityDir ) ); + pathPlane.Normalize(); + pathPlane.FitThroughPoint( origin ); + + frontPlane.SetNormal( goalOrigin - origin ); + frontPlane.Normalize(); + frontPlane.FitThroughPoint( origin ); + + farPlane.SetNormal( frontPlane.Normal() ); + farPlane.FitThroughPoint( goalOrigin ); + + curAreaNum = areaNum; + lastAreaNum = curAreaNum; + + while ( 1 ) { + + // find the furthest floor face split point on the path + if ( !FloorEdgeSplitPoint( endPos, curAreaNum, pathPlane, frontPlane, false ) ) { + endPos = origin; + } + + // if we found a point near or further than the goal we're done + if ( farPlane.Distance( endPos ) > -0.5f ) { + break; + } + + // if we reached the goal area we're done + if ( curAreaNum == goalAreaNum ) { + break; + } + + frontPlane.SetDist( frontPlane.Normal() * endPos ); + + area = &file->GetArea( curAreaNum ); + + for ( reach = area->reach; reach; reach = reach->next ) { + if ( reach->travelType != TFL_WALK ) { + continue; + } + + // if the reachability goes back to a previous area + if ( reach->toAreaNum == lastAreas[0] || reach->toAreaNum == lastAreas[1] || + reach->toAreaNum == lastAreas[2] || reach->toAreaNum == lastAreas[3] ) { + continue; + } + + // if undesired travel flags are required to travel through the area + if ( file->GetArea( reach->toAreaNum ).travelFlags & ~travelFlags ) { + continue; + } + + // don't optimize through an area near a ledge + if ( file->GetArea( reach->toAreaNum ).flags & AREA_LEDGE ) { + continue; + } + + // find the closest floor face split point on the path + if ( !FloorEdgeSplitPoint( p, reach->toAreaNum, pathPlane, frontPlane, true ) ) { + continue; + } + + // direction parallel to gravity + dir = ( file->GetSettings().gravityDir * endPos * file->GetSettings().gravityDir ) - + ( file->GetSettings().gravityDir * p * file->GetSettings().gravityDir ); + if ( dir.LengthSqr() > Square( file->GetSettings().maxStepHeight ) ) { + continue; + } + + // direction orthogonal to gravity + dir = endPos - p - dir; + if ( dir.LengthSqr() > Square( 0.2f ) ) { + continue; + } +/* + // angua: area is forbidden (e.g. locked door) + if (actor != NULL && gameLocal.m_AreaManager.AreaIsForbidden(reach->toAreaNum, actor)) + { + continue; + } +*/ + break; + } + + if ( !reach ) { + return false; + } + + lastAreas[lastAreaIndex] = curAreaNum; + lastAreaIndex = ( lastAreaIndex + 1 ) & 3; + + curAreaNum = reach->toAreaNum; + } + + endAreaNum = curAreaNum; + + return true; +} + +/* +============ +idAASLocal::SubSampleWalkPath +============ +*/ +idVec3 idAASLocal::SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum, idActor* actor ) { + + START_SCOPED_TIMING(actor->actorSubSampleWalkPathTimer, scopedSubSampleWalkPathTimer); + + int i, numSamples, curAreaNum; + idVec3 dir, point, nextPoint, endPos; + + dir = end - start; + numSamples = (int) (dir.Length() / walkPathSampleDistance) + 1; + + point = start; + for ( i = 1; i < numSamples; i++ ) { + nextPoint = start + dir * ((float) i / numSamples); + if ( (point - nextPoint).LengthSqr() > Square( maxWalkPathDistance ) ) { + return point; + } + if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum, actor ) ) { + return point; + } + point = nextPoint; + endAreaNum = curAreaNum; + } + return point; +} + +/* +============ +idAASLocal::WalkPathToGoal + + FIXME: don't stop optimizing on first failure ? +============ +*/ +bool idAASLocal::WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ) { + // Set the default values + path.type = PATHTYPE_WALK; + path.moveGoal = origin; + path.moveAreaNum = areaNum; + path.secondaryGoal = origin; + path.reachability = NULL; + path.elevatorRoute = eas::RouteInfoPtr(); + path.firstDoor = NULL; + + if ( file == NULL || areaNum == goalAreaNum ) { + path.moveGoal = goalOrigin; + return true; + } + + CFrobDoor* door = NULL; + + int lastAreas[4] = { areaNum, areaNum, areaNum, areaNum }; + int lastAreaIndex = 0; + + int curAreaNum = areaNum; + idReachability* reach(NULL); + idVec3 endPos; + int travelTime, endAreaNum; + + for ( int i = 0; i < maxWalkPathIterations; i++ ) + { + + if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach, &door, actor ) ) { + break; + } + + if ( !reach ) { + return false; + } + + if (door != NULL && path.firstDoor == NULL) + { + path.firstDoor = door; + } + + // no need to check through the first area + if ( areaNum != curAreaNum ) { + // only optimize a limited distance ahead + if ( (reach->start - origin).LengthSqr() > Square( maxWalkPathDistance ) ) { +#if SUBSAMPLE_WALK_PATH + path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum, actor ); +#endif + return true; + } + + if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum, actor ) ) { +#if SUBSAMPLE_WALK_PATH + path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum, actor ); +#endif + return true; + } + } + + path.moveGoal = reach->start; + path.moveAreaNum = curAreaNum; + + if ( reach->travelType != TFL_WALK ) { + break; + } + + if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum, actor ) ) { + return true; + } + + path.moveGoal = reach->end; + path.moveAreaNum = reach->toAreaNum; + + if ( reach->toAreaNum == goalAreaNum ) { + if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum, actor ) ) { +#if SUBSAMPLE_WALK_PATH + path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum, actor ); +#endif + return true; + } + path.moveGoal = goalOrigin; + path.moveAreaNum = goalAreaNum; + return true; + } + + lastAreas[lastAreaIndex] = curAreaNum; + lastAreaIndex = ( lastAreaIndex + 1 ) & 3; + + curAreaNum = reach->toAreaNum; + + if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] || + curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) { + common->Warning( "idAASLocal::WalkPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum ); + break; + } + } + + if ( !reach ) { + // No standard reachability, check if the actor can use elevators + if (actor != NULL && actor->CanUseElevators()) + { + return elevatorSystem->FindRouteToGoal(path, areaNum, origin, goalAreaNum, goalOrigin, travelFlags, actor); + } + + return false; + } + + switch( reach->travelType ) { + case TFL_WALKOFFLEDGE: + path.type = PATHTYPE_WALKOFFLEDGE; + path.secondaryGoal = reach->end; + path.reachability = reach; + break; + case TFL_BARRIERJUMP: + path.type |= PATHTYPE_BARRIERJUMP; + path.secondaryGoal = reach->end; + path.reachability = reach; + break; + case TFL_JUMP: + path.type |= PATHTYPE_JUMP; + path.secondaryGoal = reach->end; + path.reachability = reach; + break; + default: + break; + } + + return true; +} + +/* +============ +idAASLocal::FlyPathValid + + returns true if one can fly in a straight line between origin and goalOrigin +============ +*/ +bool idAASLocal::FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const { + aasTrace_t trace; + + if ( file == NULL ) { + endPos = goalOrigin; + endAreaNum = 0; + return true; + } + + file->Trace( trace, origin, goalOrigin ); + + endPos = trace.endpos; + endAreaNum = trace.lastAreaNum; + + if ( trace.fraction >= 1.0f ) { + return true; + } + + return false; +} + +/* +============ +idAASLocal::SubSampleFlyPath +============ +*/ +idVec3 idAASLocal::SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const { + int i, numSamples, curAreaNum; + idVec3 dir, point, nextPoint, endPos; + + dir = end - start; + numSamples = (int) (dir.Length() / flyPathSampleDistance) + 1; + + point = start; + for ( i = 1; i < numSamples; i++ ) { + nextPoint = start + dir * ((float) i / numSamples); + if ( (point - nextPoint).LengthSqr() > Square( maxFlyPathDistance ) ) { + return point; + } + if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) { + return point; + } + point = nextPoint; + endAreaNum = curAreaNum; + } + return point; +} + +/* +============ +idAASLocal::FlyPathToGoal + + FIXME: don't stop optimizing on first failure ? +============ +*/ +bool idAASLocal::FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const { + int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum; + idReachability *reach(NULL); + idVec3 endPos; + + path.type = PATHTYPE_WALK; + path.moveGoal = origin; + path.moveAreaNum = areaNum; + path.secondaryGoal = origin; + path.reachability = NULL; + path.elevatorRoute = eas::RouteInfoPtr(); + path.firstDoor = NULL; + + if ( file == NULL || areaNum == goalAreaNum ) { + path.moveGoal = goalOrigin; + return true; + } + + lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum; + lastAreaIndex = 0; + + curAreaNum = areaNum; + + for ( i = 0; i < maxFlyPathIterations; i++ ) { + + if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach, &path.firstDoor, NULL ) ) { + break; + } + + if ( !reach ) { + return false; + } + + // no need to check through the first area + if ( areaNum != curAreaNum ) { + if ( (reach->start - origin).LengthSqr() > Square( maxFlyPathDistance ) ) { +#if SUBSAMPLE_FLY_PATH + path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum ); +#endif + return true; + } + + if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) { +#if SUBSAMPLE_FLY_PATH + path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum ); +#endif + return true; + } + } + + path.moveGoal = reach->start; + path.moveAreaNum = curAreaNum; + + if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) { + return true; + } + + path.moveGoal = reach->end; + path.moveAreaNum = reach->toAreaNum; + + if ( reach->toAreaNum == goalAreaNum ) { + if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) { +#if SUBSAMPLE_FLY_PATH + path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum ); +#endif + return true; + } + path.moveGoal = goalOrigin; + path.moveAreaNum = goalAreaNum; + return true; + } + + lastAreas[lastAreaIndex] = curAreaNum; + lastAreaIndex = ( lastAreaIndex + 1 ) & 3; + + curAreaNum = reach->toAreaNum; + + if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] || + curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) { + common->Warning( "idAASLocal::FlyPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum ); + break; + } + } + + if ( !reach ) { + return false; + } + + return true; +} + +typedef struct wallEdge_s { + int edgeNum; + int verts[2]; + struct wallEdge_s * next; +} wallEdge_t; + +/* +============ +idAASLocal::SortWallEdges +============ +*/ +void idAASLocal::SortWallEdges( int *edges, int numEdges ) const +{ + int i, j, k, numSequences; + wallEdge_t **sequenceFirst, **sequenceLast, *wallEdges, *wallEdge; + + wallEdges = (wallEdge_t *) _alloca16( numEdges * sizeof( wallEdge_t ) ); + sequenceFirst = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) ); + sequenceLast = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) ); + + for ( i = 0; i < numEdges; i++ ) { + wallEdges[i].edgeNum = edges[i]; + GetEdgeVertexNumbers( edges[i], wallEdges[i].verts ); + wallEdges[i].next = NULL; + sequenceFirst[i] = &wallEdges[i]; + sequenceLast[i] = &wallEdges[i]; + } + + numSequences = numEdges; + for ( i = 0; i < numSequences; i++ ) { + for ( j = i+1; j < numSequences; j++ ) { + if ( sequenceFirst[i]->verts[0] == sequenceLast[j]->verts[1] ) { + sequenceLast[j]->next = sequenceFirst[i]; + sequenceFirst[i] = sequenceFirst[j]; + break; + } + if ( sequenceLast[i]->verts[1] == sequenceFirst[j]->verts[0] ) { + sequenceLast[i]->next = sequenceFirst[j]; + break; + } + } + if ( j < numSequences ) { + numSequences--; + for ( k = j; k < numSequences; k++ ) { + sequenceFirst[k] = sequenceFirst[k+1]; + sequenceLast[k] = sequenceLast[k+1]; + } + i = -1; + } + } + + k = 0; + for ( i = 0; i < numSequences; i++ ) { + for ( wallEdge = sequenceFirst[i]; wallEdge; wallEdge = wallEdge->next ) { + edges[k++] = wallEdge->edgeNum; + } + } +} + +/* +============ +idAASLocal::GetWallEdges +============ +*/ +int idAASLocal::GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const +{ + if ( !file ) + { + return 0; + } + + int numEdges = 0; + int numAreas = file->GetNumAreas(); + + byte *areasVisited = (byte *) _alloca16( numAreas); + memset( areasVisited, 0, numAreas * sizeof( byte ) ); + int *areaQueue = (int *) _alloca16( numAreas * sizeof( int ) ); + + int queueStart = -1; + int queueEnd = 0; + areaQueue[0] = areaNum; + areasVisited[areaNum] = true; + + idReachability *reach; + + for (int curArea = areaNum; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) { + + const aasArea_t *area = &file->GetArea( curArea ); + + for (int i = 0; i < area->numFaces; i++) { + int face1Num = file->GetFaceIndex(area->firstFace + i); + const aasFace_t *face1 = &file->GetFace( abs(face1Num) ); + + if ( !(face1->flags & FACE_FLOOR ) ) { + continue; + } + + for (int j = 0; j < face1->numEdges; j++ ) { + int edge1Num = file->GetEdgeIndex(face1->firstEdge + j); + int absEdge1Num = abs( edge1Num ); + + // test if the edge is shared by another floor face of this area + int k; + for (k = 0; k < area->numFaces; k++ ) { + if ( k == i ) { + continue; + } + int face2Num = file->GetFaceIndex( area->firstFace + k ); + const aasFace_t *face2 = &file->GetFace( abs(face2Num) ); + + if ( !(face2->flags & FACE_FLOOR ) ) { + continue; + } + int l; + for (l = 0; l < face2->numEdges; l++ ) { + int edge2Num = abs( file->GetEdgeIndex( face2->firstEdge + l ) ); + if ( edge2Num == absEdge1Num ) { + break; + } + } + if ( l < face2->numEdges ) { + break; + } + } + if ( k < area->numFaces ) { + continue; + } + + // test if the edge is used by a reachability + for (reach = area->reach; reach; reach = reach->next ) { + if ( reach->travelType & travelFlags ) { + if ( reach->edgeNum == absEdge1Num ) { + break; + } + } + } + if ( reach ) { + continue; + } + + // test if the edge is already in the list + for ( k = 0; k < numEdges; k++ ) { + if ( edge1Num == edges[k] ) { + break; + } + } + if ( k < numEdges ) { + continue; + } + + // add the edge to the list + edges[numEdges++] = edge1Num; + if ( numEdges >= maxEdges ) { + return numEdges; + } + } + } + + // add new areas to the queue + for ( reach = area->reach; reach; reach = reach->next ) { + if ( reach->travelType & travelFlags ) { + // if the area the reachability leads to hasn't been visited yet and the area bounds touch the search bounds + if ( !areasVisited[reach->toAreaNum] && bounds.IntersectsBounds( file->GetArea( reach->toAreaNum ).bounds ) ) { + areaQueue[queueEnd++] = reach->toAreaNum; + areasVisited[reach->toAreaNum] = true; + } + } + } + } + return numEdges; +} diff --git a/game/ai/AAS_routing.cpp b/game/ai/AAS_routing.cpp new file mode 100644 index 000000000..77f04d553 --- /dev/null +++ b/game/ai/AAS_routing.cpp @@ -0,0 +1,1696 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "AAS_local.h" +#include "../Game_local.h" // for print and error + +#include "../DarkModGlobals.h" +#include "../MultiStateMover.h" +#include "../MultiStateMoverPosition.h" +#include "../TimerManager.h" + +#define CACHETYPE_AREA 1 +#define CACHETYPE_PORTAL 2 + +#define MAX_ROUTING_CACHE_MEMORY (2*1024*1024) + +#define LEDGE_TRAVELTIME_PANALTY 250 + +/* +============ +idRoutingCache::idRoutingCache +============ +*/ +idRoutingCache::idRoutingCache( int size ) { + areaNum = 0; + cluster = 0; + next = prev = NULL; + time_next = time_prev = NULL; + travelFlags = 0; + startTravelTime = 0; + type = 0; + this->size = size; + reachabilities = new byte[size]; + memset( reachabilities, 0, size * sizeof( reachabilities[0] ) ); + travelTimes = new unsigned short[size]; + memset( travelTimes, 0, size * sizeof( travelTimes[0] ) ); +} + +/* +============ +idRoutingCache::~idRoutingCache +============ +*/ +idRoutingCache::~idRoutingCache( void ) { + delete [] reachabilities; + delete [] travelTimes; +} + +/* +============ +idRoutingCache::Size +============ +*/ +int idRoutingCache::Size( void ) const { + return sizeof( idRoutingCache ) + size * sizeof( reachabilities[0] ) + size * sizeof( travelTimes[0] ); +} + +/* +============ +idAASLocal::AreaTravelTime +============ +*/ +unsigned short idAASLocal::AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const { + float dist; + + dist = ( end - start ).Length(); + + if ( file->GetArea( areaNum ).travelFlags & TFL_CROUCH ) { + dist *= 100.0f / 100.0f; + } else if ( file->GetArea( areaNum ).travelFlags & TFL_WATER ) { + dist *= 100.0f / 150.0f; + } else { + dist *= 100.0f / 300.0f; + } + if ( dist < 1.0f ) { + return 1; + } + return (unsigned short) idMath::FtoiFast( dist ); +} + +/* +============ +idAASLocal::CalculateAreaTravelTimes +============ +*/ +void idAASLocal::CalculateAreaTravelTimes(void) { + int n, i, j, numReach, numRevReach, t, maxt; + byte *bytePtr; + idReachability *reach, *rev_reach; + + // get total memory for all area travel times + numAreaTravelTimes = 0; + for ( n = 0; n < file->GetNumAreas(); n++ ) { + + if ( !(file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { + continue; + } + + numReach = 0; + for ( reach = file->GetArea( n ).reach; reach; reach = reach->next ) { + numReach++; + } + + numRevReach = 0; + for ( rev_reach = file->GetArea( n ).rev_reach; rev_reach; rev_reach = rev_reach->rev_next ) { + numRevReach++; + } + numAreaTravelTimes += numReach * numRevReach; + } + + areaTravelTimes = (unsigned short *) Mem_Alloc( numAreaTravelTimes * sizeof( unsigned short ) ); + bytePtr = (byte *) areaTravelTimes; + + for ( n = 0; n < file->GetNumAreas(); n++ ) { + + if ( !(file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { + continue; + } + + // for each reachability that starts in this area calculate the travel time + // towards all the reachabilities that lead towards this area + for ( maxt = i = 0, reach = file->GetArea( n ).reach; reach; reach = reach->next, i++ ) { + assert( i < MAX_REACH_PER_AREA ); + if ( i >= MAX_REACH_PER_AREA ) { + gameLocal.Error( "i >= MAX_REACH_PER_AREA" ); + } + reach->number = i; + reach->disableCount = 0; + reach->areaTravelTimes = (unsigned short *) bytePtr; + for ( j = 0, rev_reach = file->GetArea( n ).rev_reach; rev_reach; rev_reach = rev_reach->rev_next, j++ ) { + t = AreaTravelTime( n, reach->start, rev_reach->end ); + reach->areaTravelTimes[j] = t; + if ( t > maxt ) { + maxt = t; + } + } + bytePtr += j * sizeof( unsigned short ); + } + + // if this area is a portal + if ( file->GetArea( n ).cluster < 0 ) { + // set the maximum travel time through this portal + file->SetPortalMaxTravelTime( -file->GetArea( n ).cluster, maxt ); + } + } + + assert( ( (unsigned int) bytePtr - (unsigned int) areaTravelTimes ) <= numAreaTravelTimes * sizeof( unsigned short ) ); +} + +/* +============ +idAASLocal::DeleteAreaTravelTimes +============ +*/ +void idAASLocal::DeleteAreaTravelTimes( void ) { + Mem_Free( areaTravelTimes ); + areaTravelTimes = NULL; + numAreaTravelTimes = 0; +} + +/* +============ +idAASLocal::SetupRoutingCache +============ +*/ +void idAASLocal::SetupRoutingCache( void ) { + + // greebo: First, determine the number of areas in the map by adding all reachable areas of all clusters + areaCacheIndexSize = 0; + for ( int i = 0; i < file->GetNumClusters(); i++ ) { + areaCacheIndexSize += file->GetCluster(i).numReachableAreas; + } + + /** + * greebo: Next, we need to allocate the memory for the idRoutingCache* pointers (only the pointers, not the structs!) + * Take one pointer array per cluster and add one pointer for each area. The area pointers + * are grouped after their clusters. + * + * The area cache index is then looking like this (divided into two large sections). The first + * section serves as "index" for the pointers further down in memory. + * + * idRoutingCache** cluster0 (pointing to the "area0" pointer below) + * idRoutingCache** cluster1 (pointing to the "area3" pointer below) + * idRoutingCache** cluster2 (pointing to the "area5" pointer below) + * ... + * + * idRoutingCache* area0 (belonging to Cluster 0) + * idRoutingCache* area1 (belonging to Cluster 0) + * idRoutingCache* area2 (belonging to Cluster 0) + * + * idRoutingCache* area3 (belonging to Cluster 1) + * idRoutingCache* area4 (belonging to Cluster 1) + * + * idRoutingCache* area5 (belonging to Cluster 2) + * idRoutingCache* area6 (belonging to Cluster 2) + * ... + * + * This whole pointer structure is stored in a dynamically allocated area, hence the type idRoutingCache*** + */ + areaCacheIndex = (idRoutingCache***) Mem_ClearedAlloc( file->GetNumClusters() * sizeof(idRoutingCache**) + + areaCacheIndexSize * sizeof(idRoutingCache*) ); + + // Now initialise the areaCacheIndex pointers + + // skip the index part, i.e. the first pointers + byte* bytePtr = ((byte *)areaCacheIndex) + file->GetNumClusters() * sizeof(idRoutingCache**); + + // Initialise the first pointer section (the clusterN pointers), which point to the second (area) section + for ( int i = 0; i < file->GetNumClusters(); i++ ) { + // Set the i-th cluster pointer to the first area pointer (corresponding to this cluster) + areaCacheIndex[i] = (idRoutingCache**) bytePtr; + + // Set the pointer to the next array + bytePtr += file->GetCluster(i).numReachableAreas * sizeof(idRoutingCache*); + } + + // At this point, all the area idRoutingCache* pointers are NULL and the index pointers are initialised + + // greebo: Allocate an idRoutingCache pointer for each area in the world and set the pointers to 0 + portalCacheIndexSize = file->GetNumAreas(); + portalCacheIndex = (idRoutingCache**) Mem_ClearedAlloc( portalCacheIndexSize * sizeof(idRoutingCache*) ); + + // greebo: Allocate as many idRoutingUpdate structures as there are AREAS in the map, and set everything to 0 + areaUpdate = (idRoutingUpdate*) Mem_ClearedAlloc( file->GetNumAreas() * sizeof(idRoutingUpdate) ); + + // greebo: Allocate as many idRoutingUpdate structures as there are PORTALS+1 in the map, and set everything to 0 + portalUpdate = (idRoutingUpdate*) Mem_ClearedAlloc( (file->GetNumPortals()+1) * sizeof(idRoutingUpdate) ); + + // greebo: For each area in the map, allocate a traveltime integer and initialise them to 0 + goalAreaTravelTimes = (unsigned short *) Mem_ClearedAlloc( file->GetNumAreas() * sizeof(unsigned short) ); + + cacheListStart = cacheListEnd = NULL; + totalCacheMemory = 0; +} + +/* +============ +idAASLocal::DeleteClusterCache +============ +*/ +void idAASLocal::DeleteClusterCache( int clusterNum ) { + int i; + idRoutingCache *cache; + + for ( i = 0; i < file->GetCluster( clusterNum ).numReachableAreas; i++ ) { + for ( cache = areaCacheIndex[clusterNum][i]; cache; cache = areaCacheIndex[clusterNum][i] ) { + areaCacheIndex[clusterNum][i] = cache->next; + UnlinkCache( cache ); + delete cache; + } + } +} + +/* +============ +idAASLocal::DeletePortalCache +============ +*/ +void idAASLocal::DeletePortalCache( void ) { + int i; + idRoutingCache *cache; + + for ( i = 0; i < file->GetNumAreas(); i++ ) { + for ( cache = portalCacheIndex[i]; cache; cache = portalCacheIndex[i] ) { + portalCacheIndex[i] = cache->next; + UnlinkCache( cache ); + delete cache; + } + } +} + +/* +============ +idAASLocal::ShutdownRoutingCache +============ +*/ +void idAASLocal::ShutdownRoutingCache( void ) { + int i; + + for ( i = 0; i < file->GetNumClusters(); i++ ) { + DeleteClusterCache( i ); + } + + DeletePortalCache(); + + Mem_Free( areaCacheIndex ); + areaCacheIndex = NULL; + areaCacheIndexSize = 0; + Mem_Free( portalCacheIndex ); + portalCacheIndex = NULL; + portalCacheIndexSize = 0; + Mem_Free( areaUpdate ); + areaUpdate = NULL; + Mem_Free( portalUpdate ); + portalUpdate = NULL; + Mem_Free( goalAreaTravelTimes ); + goalAreaTravelTimes = NULL; + + cacheListStart = cacheListEnd = NULL; + totalCacheMemory = 0; +} + +/* +============ +idAASLocal::SetupRouting +============ +*/ +bool idAASLocal::SetupRouting( void ) { + CalculateAreaTravelTimes(); + SetupRoutingCache(); + return true; +} + +/* +============ +idAASLocal::ShutdownRouting +============ +*/ +void idAASLocal::ShutdownRouting( void ) { + DeleteAreaTravelTimes(); + ShutdownRoutingCache(); +} + +/* +============ +idAASLocal::RoutingStats +============ +*/ +void idAASLocal::RoutingStats( void ) const { + idRoutingCache *cache; + int numAreaCache, numPortalCache; + int totalAreaCacheMemory, totalPortalCacheMemory; + + numAreaCache = numPortalCache = 0; + totalAreaCacheMemory = totalPortalCacheMemory = 0; + for ( cache = cacheListStart; cache; cache = cache->time_next ) { + if ( cache->type == CACHETYPE_AREA ) { + numAreaCache++; + totalAreaCacheMemory += sizeof( idRoutingCache ) + cache->size * (sizeof( unsigned short ) + sizeof( byte )); + } else { + numPortalCache++; + totalPortalCacheMemory += sizeof( idRoutingCache ) + cache->size * (sizeof( unsigned short ) + sizeof( byte )); + } + } + + gameLocal.Printf( "%6d area cache (%d KB)\n", numAreaCache, totalAreaCacheMemory >> 10 ); + gameLocal.Printf( "%6d portal cache (%d KB)\n", numPortalCache, totalPortalCacheMemory >> 10 ); + gameLocal.Printf( "%6d total cache (%d KB)\n", numAreaCache + numPortalCache, totalCacheMemory >> 10 ); + gameLocal.Printf( "%6d area travel times (%d KB)\n", numAreaTravelTimes, ( numAreaTravelTimes * sizeof( unsigned short ) ) >> 10 ); + gameLocal.Printf( "%6d area cache entries (%d KB)\n", areaCacheIndexSize, ( areaCacheIndexSize * sizeof( idRoutingCache * ) ) >> 10 ); + gameLocal.Printf( "%6d portal cache entries (%d KB)\n", portalCacheIndexSize, ( portalCacheIndexSize * sizeof( idRoutingCache * ) ) >> 10 ); +} + +/* +============ +idAASLocal::RemoveRoutingCacheUsingArea +============ +*/ +void idAASLocal::RemoveRoutingCacheUsingArea( int areaNum ) { + int clusterNum; + + clusterNum = file->GetArea( areaNum ).cluster; + if ( clusterNum > 0 ) { + // remove all the cache in the cluster the area is in + DeleteClusterCache( clusterNum ); + } + else { + // if this is a portal remove all cache in both the front and back cluster + DeleteClusterCache( file->GetPortal( -clusterNum ).clusters[0] ); + DeleteClusterCache( file->GetPortal( -clusterNum ).clusters[1] ); + } + DeletePortalCache(); +} + +/* +============ +idAASLocal::DisableArea +============ +*/ +void idAASLocal::DisableArea( int areaNum ) { + assert( areaNum > 0 && areaNum < file->GetNumAreas() ); + + if ( file->GetArea( areaNum ).travelFlags & TFL_INVALID ) { + return; + } + + file->SetAreaTravelFlag( areaNum, TFL_INVALID ); + + RemoveRoutingCacheUsingArea( areaNum ); +} + +/* +============ +idAASLocal::EnableArea +============ +*/ +void idAASLocal::EnableArea( int areaNum ) { + assert( areaNum > 0 && areaNum < file->GetNumAreas() ); + + if ( !( file->GetArea( areaNum ).travelFlags & TFL_INVALID ) ) { + return; + } + + file->RemoveAreaTravelFlag( areaNum, TFL_INVALID ); + + RemoveRoutingCacheUsingArea( areaNum ); +} + +/* +============ +idAASLocal::SetAreaState_r +============ +*/ +bool idAASLocal::SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled ) { + int res; + const aasNode_t *node; + bool foundClusterPortal = false; + + while( nodeNum != 0 ) { + if ( nodeNum < 0 ) { + // if this area is a cluster portal + if ( file->GetArea( -nodeNum ).contents & areaContents ) { + if ( disabled ) { + DisableArea( -nodeNum ); + } else { + EnableArea( -nodeNum ); + } + foundClusterPortal |= true; + } + break; + } + node = &file->GetNode( nodeNum ); + res = bounds.PlaneSide( file->GetPlane( node->planeNum ) ); + if ( res == PLANESIDE_BACK ) { + nodeNum = node->children[1]; + } + else if ( res == PLANESIDE_FRONT ) { + nodeNum = node->children[0]; + } + else { + foundClusterPortal |= SetAreaState_r( node->children[1], bounds, areaContents, disabled ); + nodeNum = node->children[0]; + } + } + + return foundClusterPortal; +} + +/* +============ +idAASLocal::SetAreaState +============ +*/ +bool idAASLocal::SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) { + idBounds expBounds; + + if ( !file ) { + return false; + } + + expBounds[0] = bounds[0] - file->GetSettings().boundingBoxes[0][1]; + expBounds[1] = bounds[1] - file->GetSettings().boundingBoxes[0][0]; + + // find all areas within or touching the bounds with the given contents and disable/enable them for routing + return SetAreaState_r( 1, expBounds, areaContents, disabled ); +} + +/* +============ +idAASLocal::GetBoundsAreas_r +============ +*/ +void idAASLocal::GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList &areas ) const { + int res; + const aasNode_t *node; + + while( nodeNum != 0 ) { + if ( nodeNum < 0 ) { + areas.Append( -nodeNum ); + break; + } + node = &file->GetNode( nodeNum ); + res = bounds.PlaneSide( file->GetPlane( node->planeNum ) ); + if ( res == PLANESIDE_BACK ) { + nodeNum = node->children[1]; + } + else if ( res == PLANESIDE_FRONT ) { + nodeNum = node->children[0]; + } + else { + GetBoundsAreas_r( node->children[1], bounds, areas ); + nodeNum = node->children[0]; + } + } +} + +/* +============ +idAASLocal::SetObstacleState +============ +*/ +void idAASLocal::SetObstacleState( const idRoutingObstacle *obstacle, bool enable ) { + int i; + const aasArea_t *area; + idReachability *reach, *rev_reach; + bool inside; + + for ( i = 0; i < obstacle->areas.Num(); i++ ) { + + RemoveRoutingCacheUsingArea( obstacle->areas[i] ); + + area = &file->GetArea( obstacle->areas[i] ); + + for ( rev_reach = area->rev_reach; rev_reach; rev_reach = rev_reach->rev_next ) { + + + /** SZ: I'm commenting this out as it prevents disabling obstacles from making areas + * Accessible again + */ + /* + if ( rev_reach->travelType & TFL_INVALID ) { + continue; + } + */ + + inside = false; + + if ( obstacle->bounds.ContainsPoint( rev_reach->end ) ) { + inside = true; + } + else { + for ( reach = area->reach; reach; reach = reach->next ) { + if ( obstacle->bounds.LineIntersection( rev_reach->end, reach->start ) ) { + inside = true; + break; + } + } + } + + // SZ: I'm commenting out the original Doom3 code below because it is broken + // It appears as if the if ( enable ) line is supposed to be if ( !enable) + // Enable refers to the obstacle being on or off, not to the reachability being + // enabled or disabled. If the obstacle is enabled, then the reachability is + // disabled. This appears to have thus been a semantic error by Id. + if ( inside ) { + //if ( enable ) { + if (!enable) { + rev_reach->disableCount--; + if ( rev_reach->disableCount <= 0 ) { + rev_reach->travelType &= ~TFL_INVALID; + rev_reach->disableCount = 0; + } + } + else { + rev_reach->travelType |= TFL_INVALID; + rev_reach->disableCount++; + } + } + } + } +} + +/* +============ +idAASLocal::AddObstacle +============ +*/ +aasHandle_t idAASLocal::AddObstacle( const idBounds &bounds ) { + idRoutingObstacle *obstacle; + + if ( !file ) { + return -1; + } + + obstacle = new idRoutingObstacle; + obstacle->bounds[0] = bounds[0] - file->GetSettings().boundingBoxes[0][1]; + obstacle->bounds[1] = bounds[1] - file->GetSettings().boundingBoxes[0][0]; + GetBoundsAreas_r( 1, obstacle->bounds, obstacle->areas ); + SetObstacleState( obstacle, true ); + + obstacleList.Append( obstacle ); + return obstacleList.Num() - 1; +} + +/* +============ +idAASLocal::RemoveObstacle +============ +*/ +void idAASLocal::RemoveObstacle( const aasHandle_t handle ) { + if ( !file ) { + return; + } + if ( ( handle >= 0 ) && ( handle < obstacleList.Num() ) ) { + SetObstacleState( obstacleList[handle], false ); + + delete obstacleList[handle]; + obstacleList.RemoveIndex( handle ); + } +} + +/* +============ +idAASLocal::RemoveAllObstacles +============ +*/ +void idAASLocal::RemoveAllObstacles( void ) { + int i; + + if ( !file ) { + return; + } + + for ( i = 0; i < obstacleList.Num(); i++ ) { + SetObstacleState( obstacleList[i], false ); + delete obstacleList[i]; + } + obstacleList.Clear(); +} + +/* +============ +idAASLocal::LinkCache + + link the cache in the cache list sorted from oldest to newest cache +============ +*/ +void idAASLocal::LinkCache( idRoutingCache *cache ) const { + + // if the cache is already linked + if ( cache->time_next || cache->time_prev || cacheListStart == cache ) { + UnlinkCache( cache ); + } + + totalCacheMemory += cache->Size(); + + // add cache to the end of the list + cache->time_next = NULL; + cache->time_prev = cacheListEnd; + if ( cacheListEnd ) { + cacheListEnd->time_next = cache; + } + cacheListEnd = cache; + if ( !cacheListStart ) { + cacheListStart = cache; + } +} + +/* +============ +idAASLocal::UnlinkCache +============ +*/ +void idAASLocal::UnlinkCache( idRoutingCache *cache ) const { + + totalCacheMemory -= cache->Size(); + + // unlink the cache + if ( cache->time_next ) { + cache->time_next->time_prev = cache->time_prev; + } else { + cacheListEnd = cache->time_prev; + } + if ( cache->time_prev ) { + cache->time_prev->time_next = cache->time_next; + } else { + cacheListStart = cache->time_next; + } + cache->time_next = cache->time_prev = NULL; +} + +/* +============ +idAASLocal::DeleteOldestCache +============ +*/ +void idAASLocal::DeleteOldestCache( void ) const { + idRoutingCache *cache; + + assert( cacheListStart ); + + // unlink the oldest cache + cache = cacheListStart; + UnlinkCache( cache ); + + // unlink the oldest cache from the area or portal cache index + if ( cache->next ) { + cache->next->prev = cache->prev; + } + if ( cache->prev ) { + cache->prev->next = cache->next; + } + else if ( cache->type == CACHETYPE_AREA ) { + areaCacheIndex[cache->cluster][ClusterAreaNum( cache->cluster, cache->areaNum )] = cache->next; + } + else if ( cache->type == CACHETYPE_PORTAL ) { + portalCacheIndex[cache->areaNum] = cache->next; + } + + delete cache; +} + +/* +============ +idAASLocal::GetAreaReachability +============ +*/ +idReachability *idAASLocal::GetAreaReachability( int areaNum, int reachabilityNum ) const { + idReachability *reach; + + for ( reach = file->GetArea( areaNum ).reach; reach; reach = reach->next ) { + if ( --reachabilityNum < 0 ) { + return reach; + } + } + return NULL; +} + +/* +============ +idAASLocal::ClusterAreaNum +============ +*/ +ID_INLINE int idAASLocal::ClusterAreaNum( int clusterNum, int areaNum ) const { + int side, areaCluster; + + areaCluster = file->GetArea( areaNum ).cluster; + if ( areaCluster > 0 ) { + return file->GetArea( areaNum ).clusterAreaNum; + } + else { + side = file->GetPortal( -areaCluster ).clusters[0] != clusterNum; + return file->GetPortal( -areaCluster ).clusterAreaNum[side]; + } +} + +/* +============ +idAASLocal::UpdateAreaRoutingCache +============ +*/ +void idAASLocal::UpdateAreaRoutingCache( idRoutingCache *areaCache ) const { + // number of reachability areas within this cluster + int numReachableAreas = file->GetCluster(areaCache->cluster).numReachableAreas; + + // number of the start area within the cluster + int clusterAreaNum = ClusterAreaNum(areaCache->cluster, areaCache->areaNum); + + if (clusterAreaNum >= numReachableAreas) { + return; // cluster area is not a reachable area + } + + areaCache->travelTimes[clusterAreaNum] = areaCache->startTravelTime; + int badTravelFlags = ~areaCache->travelFlags; + + unsigned short startAreaTravelTimes[MAX_REACH_PER_AREA]; + memset( startAreaTravelTimes, 0, sizeof( startAreaTravelTimes ) ); + + // initialize first update + idRoutingUpdate* curUpdate = &areaUpdate[clusterAreaNum]; + + curUpdate->areaNum = areaCache->areaNum; + curUpdate->areaTravelTimes = startAreaTravelTimes; + curUpdate->tmpTravelTime = areaCache->startTravelTime; + curUpdate->next = NULL; + curUpdate->prev = NULL; + + idRoutingUpdate* updateListStart = curUpdate; + idRoutingUpdate* updateListEnd = curUpdate; + + // while there are updates in the list + while( updateListStart ) { + + curUpdate = updateListStart; + if ( curUpdate->next ) { + curUpdate->next->prev = NULL; + } + else { + updateListEnd = NULL; + } + updateListStart = curUpdate->next; + + curUpdate->isInList = false; + + idReachability* reach; + int i; + for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).rev_reach; reach; reach = reach->rev_next, i++ ) { + + // if the reachability uses an undesired travel type + if ( reach->travelType & badTravelFlags ) { + continue; + } + + // next area the reversed reachability leads to + int nextAreaNum = reach->fromAreaNum; + const aasArea_t* nextArea = &file->GetArea( nextAreaNum ); + + // if traveling through the next area requires an undesired travel flag + if ( nextArea->travelFlags & badTravelFlags ) { + continue; + } + + // get the cluster number of the area + int cluster = nextArea->cluster; + // don't leave the cluster, however do flood into cluster portals + if ( cluster > 0 && cluster != areaCache->cluster ) { + continue; + } + + // get the number of the area in the cluster + clusterAreaNum = ClusterAreaNum( areaCache->cluster, nextAreaNum ); + if ( clusterAreaNum >= numReachableAreas ) { + continue; // should never happen + } + + assert( clusterAreaNum < areaCache->size ); + + // time already travelled plus the traveltime through the current area + // plus the travel time of the reachability towards the next area + unsigned short t = curUpdate->tmpTravelTime + curUpdate->areaTravelTimes[i] + reach->travelTime; + + if ( !areaCache->travelTimes[clusterAreaNum] || t < areaCache->travelTimes[clusterAreaNum] ) { + + areaCache->travelTimes[clusterAreaNum] = t; + areaCache->reachabilities[clusterAreaNum] = reach->number; // reversed reachability used to get into this area + idRoutingUpdate* nextUpdate = &areaUpdate[clusterAreaNum]; + nextUpdate->areaNum = nextAreaNum; + nextUpdate->tmpTravelTime = t; + nextUpdate->areaTravelTimes = reach->areaTravelTimes; + + // if we are not allowed to fly + if ( badTravelFlags & TFL_FLY ) { + // avoid areas near ledges + if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) { + nextUpdate->tmpTravelTime += LEDGE_TRAVELTIME_PANALTY; + } + } + + if ( !nextUpdate->isInList ) { + nextUpdate->next = NULL; + nextUpdate->prev = updateListEnd; + if ( updateListEnd ) { + updateListEnd->next = nextUpdate; + } + else { + updateListStart = nextUpdate; + } + updateListEnd = nextUpdate; + nextUpdate->isInList = true; + } + } + } + } +} + +/* +============ +idAASLocal::GetAreaRoutingCache +============ +*/ +idRoutingCache *idAASLocal::GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const { + int clusterAreaNum; + idRoutingCache *cache, *clusterCache; + + // number of the area in the cluster + clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); + // pointer to the cache for the area in the cluster + clusterCache = areaCacheIndex[clusterNum][clusterAreaNum]; + // check if cache without undesired travel flags already exists + for ( cache = clusterCache; cache; cache = cache->next ) { + if ( cache->travelFlags == travelFlags ) { + break; + } + } + // if no cache found + if ( !cache ) { + cache = new idRoutingCache( file->GetCluster( clusterNum ).numReachableAreas ); + cache->type = CACHETYPE_AREA; + cache->cluster = clusterNum; + cache->areaNum = areaNum; + cache->startTravelTime = 1; + cache->travelFlags = travelFlags; + cache->prev = NULL; + cache->next = clusterCache; + if ( clusterCache ) { + clusterCache->prev = cache; + } + areaCacheIndex[clusterNum][clusterAreaNum] = cache; + UpdateAreaRoutingCache( cache ); + } + LinkCache( cache ); + return cache; +} + +/* +============ +idAASLocal::UpdatePortalRoutingCache +============ +*/ +void idAASLocal::UpdatePortalRoutingCache( idRoutingCache *portalCache ) const { + int i, portalNum, clusterAreaNum; + unsigned short t; + const aasPortal_t *portal; + const aasCluster_t *cluster; + idRoutingCache *cache; + idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; + + curUpdate = &portalUpdate[ file->GetNumPortals() ]; + curUpdate->cluster = portalCache->cluster; + curUpdate->areaNum = portalCache->areaNum; + curUpdate->tmpTravelTime = portalCache->startTravelTime; + + //put the area to start with in the current read list + curUpdate->next = NULL; + curUpdate->prev = NULL; + updateListStart = curUpdate; + updateListEnd = curUpdate; + + // while there are updates in the current list + while( updateListStart ) { + + curUpdate = updateListStart; + // remove the current update from the list + if ( curUpdate->next ) { + curUpdate->next->prev = NULL; + } + else { + updateListEnd = NULL; + } + updateListStart = curUpdate->next; + // current update is removed from the list + curUpdate->isInList = false; + + cluster = &file->GetCluster( curUpdate->cluster ); + cache = GetAreaRoutingCache( curUpdate->cluster, curUpdate->areaNum, portalCache->travelFlags ); + + // take all portals of the cluster + for ( i = 0; i < cluster->numPortals; i++ ) { + portalNum = file->GetPortalIndex( cluster->firstPortal + i ); + assert( portalNum < portalCache->size ); + portal = &file->GetPortal( portalNum ); + + clusterAreaNum = ClusterAreaNum( curUpdate->cluster, portal->areaNum ); + if ( clusterAreaNum >= cluster->numReachableAreas ) { + continue; + } + + t = cache->travelTimes[clusterAreaNum]; + if ( t == 0 ) { + continue; + } + t += curUpdate->tmpTravelTime; + + if ( !portalCache->travelTimes[portalNum] || t < portalCache->travelTimes[portalNum] ) { + + portalCache->travelTimes[portalNum] = t; + portalCache->reachabilities[portalNum] = cache->reachabilities[clusterAreaNum]; + nextUpdate = &portalUpdate[portalNum]; + if ( portal->clusters[0] == curUpdate->cluster ) { + nextUpdate->cluster = portal->clusters[1]; + } + else { + nextUpdate->cluster = portal->clusters[0]; + } + nextUpdate->areaNum = portal->areaNum; + // add travel time through the actual portal area for the next update + nextUpdate->tmpTravelTime = t + portal->maxAreaTravelTime; + + if ( !nextUpdate->isInList ) { + + nextUpdate->next = NULL; + nextUpdate->prev = updateListEnd; + if ( updateListEnd ) { + updateListEnd->next = nextUpdate; + } + else { + updateListStart = nextUpdate; + } + updateListEnd = nextUpdate; + nextUpdate->isInList = true; + } + } + } + } +} + +/* +============ +idAASLocal::GetPortalRoutingCache +============ +*/ +idRoutingCache *idAASLocal::GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const { + idRoutingCache *cache; + + // check if cache without undesired travel flags already exists + for ( cache = portalCacheIndex[areaNum]; cache; cache = cache->next ) { + if ( cache->travelFlags == travelFlags ) { + break; + } + } + // if no cache found + if ( !cache ) { + cache = new idRoutingCache( file->GetNumPortals() ); + cache->type = CACHETYPE_PORTAL; + cache->cluster = clusterNum; + cache->areaNum = areaNum; + cache->startTravelTime = 1; + cache->travelFlags = travelFlags; + cache->prev = NULL; + cache->next = portalCacheIndex[areaNum]; + if ( portalCacheIndex[areaNum] ) { + portalCacheIndex[areaNum]->prev = cache; + } + portalCacheIndex[areaNum] = cache; + UpdatePortalRoutingCache( cache ); + } + LinkCache( cache ); + return cache; +} + +/* +============ +idAASLocal::RouteToGoalArea +============ +*/ +bool idAASLocal::RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, + int travelFlags, int &travelTime, idReachability **reach, + CFrobDoor** firstDoor, idActor* actor ) const +{ +#ifdef TIMING_BUILD + if (actor != NULL) + { + START_SCOPED_TIMING(actor->actorRouteToGoalTimer, scopedRouteToGoalTimer); + } +#endif + + + // Set the default return values + travelTime = 0; + *reach = NULL; + + if (firstDoor != NULL) + { + *firstDoor = NULL; + } + + if ( !file ) { + return false; + } + + if ( areaNum == goalAreaNum ) { + return true; + } + + if ( areaNum <= 0 || areaNum >= file->GetNumAreas() ) { + gameLocal.Printf( "RouteToGoalArea: areaNum %d out of range\n", areaNum ); + return false; + } + if ( goalAreaNum <= 0 || goalAreaNum >= file->GetNumAreas() ) { + gameLocal.Printf( "RouteToGoalArea: goalAreaNum %d out of range\n", goalAreaNum ); + return false; + } + + while( totalCacheMemory > MAX_ROUTING_CACHE_MEMORY ) { + DeleteOldestCache(); + } + + int clusterNum = file->GetArea( areaNum ).cluster; + int goalClusterNum = file->GetArea( goalAreaNum ).cluster; + + idRoutingCache* portalCache = NULL; + const aasPortal_t* portal = NULL; + + // if the source area is a cluster portal, read directly from the portal cache + if ( clusterNum < 0 ) { + // if the goal area is a portal + if ( goalClusterNum < 0 ) { + // just assume the goal area is part of the front cluster + portal = &file->GetPortal( -goalClusterNum ); + goalClusterNum = portal->clusters[0]; + } + // get the portal routing cache + portalCache = GetPortalRoutingCache( goalClusterNum, goalAreaNum, travelFlags ); + *reach = GetAreaReachability( areaNum, portalCache->reachabilities[-clusterNum] ); + travelTime = portalCache->travelTimes[-clusterNum] + AreaTravelTime( areaNum, origin, (*reach)->start ); + return true; + } + + unsigned short int bestTime = 0; + idReachability* bestReach = NULL; + + // check if the goal area is a portal of the source area cluster + if ( goalClusterNum < 0 ) { + portal = &file->GetPortal( -goalClusterNum ); + if ( portal->clusters[0] == clusterNum || portal->clusters[1] == clusterNum) { + goalClusterNum = clusterNum; + } + } + + int clusterAreaNum = 0; + idRoutingCache* clusterCache = NULL; + + // if both areas are in the same cluster + if ( clusterNum > 0 && goalClusterNum > 0 && clusterNum == goalClusterNum ) { + clusterCache = GetAreaRoutingCache( clusterNum, goalAreaNum, travelFlags ); + clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); + + if ( clusterCache->travelTimes[clusterAreaNum] ) { + bestReach = GetAreaReachability( areaNum, clusterCache->reachabilities[clusterAreaNum] ); + bestTime = clusterCache->travelTimes[clusterAreaNum] + AreaTravelTime( areaNum, origin, bestReach->start ); + } + else { + clusterCache = NULL; + } + } + + clusterNum = file->GetArea( areaNum ).cluster; + goalClusterNum = file->GetArea( goalAreaNum ).cluster; + + // if the goal area is a portal + if ( goalClusterNum < 0 ) { + // just assume the goal area is part of the front cluster + portal = &file->GetPortal( -goalClusterNum ); + goalClusterNum = portal->clusters[0]; + } + // get the portal routing cache + portalCache = GetPortalRoutingCache( goalClusterNum, goalAreaNum, travelFlags ); + + // the cluster the area is in + const aasCluster_t* cluster = &file->GetCluster( clusterNum ); + // current area inside the current cluster + clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); + // if the area is not a reachable area + if ( clusterAreaNum >= cluster->numReachableAreas) { + return false; + } + + int bestPortalAreaNum = 0; + // find the portal of the source area cluster leading towards the goal area + for (int i = 0; i < cluster->numPortals; i++ ) { + int portalNum = file->GetPortalIndex( cluster->firstPortal + i ); + + // if the goal area isn't reachable from the portal + if ( !portalCache->travelTimes[portalNum] ) { + continue; + } + + portal = &file->GetPortal( portalNum ); + int portalAreaNum = portal->areaNum; + + // angua: area is forbidden (e.g. locked door) + if (actor != NULL && gameLocal.m_AreaManager.AreaIsForbidden(portalAreaNum, static_cast(actor))) + { + continue; + } + + // get the cache of the portal area + idRoutingCache* areaCache = GetAreaRoutingCache( clusterNum, portal->areaNum, travelFlags ); + // if the portal is not reachable from this area + if ( !areaCache->travelTimes[clusterAreaNum] ) { + continue; + } + + idReachability* r = GetAreaReachability( areaNum, areaCache->reachabilities[clusterAreaNum] ); + + if ( clusterCache ) { + // if the next reachability from the portal leads back into the cluster + idReachability* nextr = GetAreaReachability( portal->areaNum, portalCache->reachabilities[portalNum] ); + if ( file->GetArea( nextr->toAreaNum ).cluster < 0 || file->GetArea( nextr->toAreaNum ).cluster == clusterNum ) { + continue; + } + } + + // the total travel time is the travel time from the portal area to the goal area + // plus the travel time from the source area towards the portal area + unsigned short int t = portalCache->travelTimes[portalNum] + areaCache->travelTimes[clusterAreaNum]; + + // NOTE: Should add the exact travel time through the portal area. + // However we add the largest travel time through the portal area. + // We cannot directly calculate the exact travel time through the portal area + // because the reachability used to travel into the portal area is not known. + t += portal->maxAreaTravelTime; + + // if the time is better than the one already found + if ( !bestTime || t < bestTime ) { + bestPortalAreaNum = portalAreaNum; + bestReach = r; + bestTime = t; + } + } + + if (bestPortalAreaNum > 0) + { + // angua: check if there is a door in the path + aasArea_t portalArea = file->GetArea(bestPortalAreaNum); + if (portalArea.travelFlags & TFL_DOOR) + { + CFrobDoor* door = GetDoor(bestPortalAreaNum); + if (door != NULL && firstDoor != NULL) + { + *firstDoor = door; + } + } + } + + + if ( !bestReach ) { + return false; + } + + *reach = bestReach; + travelTime = bestTime; + + return true; +} + +/* +============ +idAASLocal::TravelTimeToGoalArea +============ +*/ +int idAASLocal::TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const { + int travelTime; + idReachability *reach; + + if ( !file ) { + return 0; + } + + if ( !RouteToGoalArea( areaNum, origin, goalAreaNum, travelFlags, travelTime, &reach, NULL, actor ) ) { + return 0; + } + return travelTime; +} + +/* +============ +idAASLocal::FindNearestGoal +maxTravelCost is optional and defaults to 0, meaning no maximum +============ +*/ +bool idAASLocal::FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxTravelCost ) const { + int i, j, k, badTravelFlags, nextAreaNum, bestAreaNum; + unsigned short t, bestTravelTime; + idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; + idReachability *reach; + const aasArea_t *nextArea; + idVec3 v1, v2, p; + float targetDist, dist; + + if ( file == NULL || areaNum <= 0 ) { + goal.areaNum = areaNum; + goal.origin = origin; + return false; + } + + // if the first area is valid goal, just return the origin + if ( callback.TestArea( this, areaNum ) ) { + goal.areaNum = areaNum; + goal.origin = origin; + return true; + } + + // setup obstacles + for ( k = 0; k < numObstacles; k++ ) { + obstacles[k].expAbsBounds[0] = obstacles[k].absBounds[0] - file->GetSettings().boundingBoxes[0][1]; + obstacles[k].expAbsBounds[1] = obstacles[k].absBounds[1] - file->GetSettings().boundingBoxes[0][0]; + } + + badTravelFlags = ~travelFlags; + SIMDProcessor->Memset( goalAreaTravelTimes, 0, file->GetNumAreas() * sizeof( unsigned short ) ); + + targetDist = (target - origin).Length(); + + // initialize first update + curUpdate = &areaUpdate[areaNum]; + curUpdate->areaNum = areaNum; + curUpdate->tmpTravelTime = 0; + curUpdate->start = origin; + curUpdate->next = NULL; + curUpdate->prev = NULL; + updateListStart = curUpdate; + updateListEnd = curUpdate; + + bestTravelTime = 0; + bestAreaNum = 0; + + // while there are updates in the list + while ( updateListStart ) { + + curUpdate = updateListStart; + if ( curUpdate->next ) { + curUpdate->next->prev = NULL; + } + else { + updateListEnd = NULL; + } + updateListStart = curUpdate->next; + + curUpdate->isInList = false; + + // if we already found a closer location + if ( bestTravelTime && curUpdate->tmpTravelTime >= bestTravelTime ) { + continue; + } + + for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).reach; reach; reach = reach->next, i++ ) { + + // if the reachability uses an undesired travel type + if ( reach->travelType & badTravelFlags ) { + continue; + } + + // next area the reversed reachability leads to + nextAreaNum = reach->toAreaNum; + nextArea = &file->GetArea( nextAreaNum ); + + // if traveling through the next area requires an undesired travel flag + if ( nextArea->travelFlags & badTravelFlags ) { + continue; + } + + t = curUpdate->tmpTravelTime + + AreaTravelTime( curUpdate->areaNum, curUpdate->start, reach->start ) + + reach->travelTime; + + // Don't travel too far + if (maxTravelCost && t >= maxTravelCost) { + continue; + } + + // project target origin onto movement vector through the area + v1 = reach->end - curUpdate->start; + v1.Normalize(); + v2 = target - curUpdate->start; + p = curUpdate->start + (v2 * v1) * v1; + + // get the point on the path closest to the target + for ( j = 0; j < 3; j++ ) { + if ( (p[j] > curUpdate->start[j] + 0.1f && p[j] > reach->end[j] + 0.1f) || + (p[j] < curUpdate->start[j] - 0.1f && p[j] < reach->end[j] - 0.1f) ) { + break; + } + } + if ( j >= 3 ) { + dist = (target - p).Length(); + } else { + dist = (target - reach->end).Length(); + } + + // avoid moving closer to the target + if ( dist < targetDist ) { + t += static_cast(( targetDist - dist ) * 10); + } + + // if we already found a closer location + if ( bestTravelTime && t >= bestTravelTime ) { + continue; + } + + // if this is not the best path towards the next area + if ( goalAreaTravelTimes[nextAreaNum] && t >= goalAreaTravelTimes[nextAreaNum] ) { + continue; + } + + // path may not go through any obstacles + for ( k = 0; k < numObstacles; k++ ) { + // if the movement vector intersects the expanded obstacle bounds + if ( obstacles[k].expAbsBounds.LineIntersection( curUpdate->start, reach->end ) ) { + break; + } + } + if ( k < numObstacles ) { + continue; + } + + goalAreaTravelTimes[nextAreaNum] = t; + nextUpdate = &areaUpdate[nextAreaNum]; + nextUpdate->areaNum = nextAreaNum; + nextUpdate->tmpTravelTime = t; + nextUpdate->start = reach->end; + + // if we are not allowed to fly + if ( badTravelFlags & TFL_FLY ) { + // avoid areas near ledges + if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) { + nextUpdate->tmpTravelTime += LEDGE_TRAVELTIME_PANALTY; + } + } + + if ( !nextUpdate->isInList ) { + nextUpdate->next = NULL; + nextUpdate->prev = updateListEnd; + if ( updateListEnd ) { + updateListEnd->next = nextUpdate; + } else { + updateListStart = nextUpdate; + } + updateListEnd = nextUpdate; + nextUpdate->isInList = true; + } + + // don't put goal near a ledge + if ( !( nextArea->flags & AREA_LEDGE ) ) { + + // add travel time through the area + t += AreaTravelTime( reach->toAreaNum, reach->end, nextArea->center ); + + if ( !bestTravelTime || t < bestTravelTime ) { + // if the area is not visible to the target + if ( callback.TestArea( this, reach->toAreaNum ) ) { + bestTravelTime = t; + bestAreaNum = reach->toAreaNum; + } + } + } + } + } + + if ( bestAreaNum ) { + goal.areaNum = bestAreaNum; + goal.origin = AreaCenter( bestAreaNum ); + return true; + } + + return false; +} + +/* +============ +idAASLocal::FindClosestTargetToGoal +============ +*/ +bool idAASLocal::FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const +{ + int i, k, badTravelFlags, nextAreaNum, bestAreaNum; + bool b_haveClosestDistance; + float closestDistanceToTarget; + float distanceToTarget; + idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; + idReachability *reach; + const aasArea_t *nextArea; + idVec3 v1, v2, p; + float targetDist; + + if ( file == NULL || areaNum <= 0 ) + { + goal.areaNum = areaNum; + goal.origin = origin; + return false; + } + + /* + // We want closest to target, not closest to us + // if the first area is valid goal, just return the origin + if ( callback.TestArea( this, areaNum ) ) + { + goal.areaNum = areaNum; + goal.origin = origin; + return true; + } + */ + + // setup obstacles + for ( k = 0; k < numObstacles; k++ ) + { + obstacles[k].expAbsBounds[0] = obstacles[k].absBounds[0] - file->GetSettings().boundingBoxes[0][1]; + obstacles[k].expAbsBounds[1] = obstacles[k].absBounds[1] - file->GetSettings().boundingBoxes[0][0]; + } + + badTravelFlags = ~travelFlags; + SIMDProcessor->Memset( goalAreaTravelTimes, 0, file->GetNumAreas() * sizeof( unsigned short ) ); + + targetDist = (target - origin).Length(); + + // Clear the area update tmpTravelTime members, as we use those as breadcrumbs + int numAreas = file->GetNumAreas(); + for (int ai = 0; ai < numAreas; ai ++) + { + areaUpdate[ai].tmpTravelTime = 0; + } + + + // initialize first update + curUpdate = &areaUpdate[areaNum]; + curUpdate->areaNum = areaNum; + curUpdate->tmpTravelTime = 0; + curUpdate->start = origin; + curUpdate->next = NULL; + curUpdate->prev = NULL; + updateListStart = curUpdate; + updateListEnd = curUpdate; + + closestDistanceToTarget = 0.0; + b_haveClosestDistance = false; + bestAreaNum = 0; + + // while there are updates in the list + while ( updateListStart ) + { + + curUpdate = updateListStart; + if ( curUpdate->next ) + { + curUpdate->next->prev = NULL; + } + else + { + updateListEnd = NULL; + } + updateListStart = curUpdate->next; + + curUpdate->isInList = false; + + // If we already checked this area, we are done with it + // We use the tmpTravelTime as a boolean flag to indicate if we have searched an area or not + if (curUpdate->tmpTravelTime > 1.0) + { + continue; + } + else + { + // We are checking it + curUpdate->tmpTravelTime = 2; + } + + + // What is the distance to the target + distanceToTarget = (file->AreaCenter(curUpdate->areaNum) - target).Length(); + + // If is closest so far + if ( !b_haveClosestDistance || distanceToTarget < closestDistanceToTarget) + { + // if the area is not visible to the target + if ( callback.TestArea( this, curUpdate->areaNum ) ) + { + closestDistanceToTarget = distanceToTarget; + b_haveClosestDistance = true; + bestAreaNum = curUpdate->areaNum; + } + } + + // if we already found a closer location we are done + /* + if + ( + ( b_haveClosestDistance) && + ((closestDistanceToTarget * 2.0) <= distanceToTarget) + ) + { + continue; + } + */ + + for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).reach; reach; reach = reach->next, i++ ) + { + // if the reachability uses an undesired travel type + if ( reach->travelType & badTravelFlags ) + { + continue; + } + + // next area the reversed reachability leads to + nextAreaNum = reach->toAreaNum; + nextArea = &file->GetArea( nextAreaNum ); + + // if traveling through the next area requires an undesired travel flag + if ( nextArea->travelFlags & badTravelFlags ) + { + continue; + } + + // path may not go through any obstacles + for ( k = 0; k < numObstacles; k++ ) + { + // if the movement vector intersects the expanded obstacle bounds + if ( obstacles[k].expAbsBounds.LineIntersection( curUpdate->start, reach->end ) ) + { + break; + } + } + if ( k < numObstacles ) + { + continue; + } + + nextUpdate = &areaUpdate[nextAreaNum]; + nextUpdate->areaNum = nextAreaNum; + nextUpdate->start = reach->end; + + + // if we are not allowed to fly + if ( badTravelFlags & TFL_FLY ) + { + // avoid areas near ledges + if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) + { + continue; + } + } + + if ( !nextUpdate->isInList ) + { + nextUpdate->next = NULL; + nextUpdate->prev = updateListEnd; + if ( updateListEnd ) + { + updateListEnd->next = nextUpdate; + } + else + { + updateListStart = nextUpdate; + } + updateListEnd = nextUpdate; + nextUpdate->isInList = true; + + } + + /* + // don't put goal near a ledge + distanceToTarget = (file->AreaCenter(reach->toAreaNum) - target).Length(); + if ( !( nextArea->flags & AREA_LEDGE ) ) + { + // If is closest so far + if ( !b_haveClosestDistance || distanceToTarget < closestDistanceToTarget) + { + // if the area is not visible to the target + if ( callback.TestArea( this, reach->toAreaNum ) ) + { + closestDistanceToTarget = distanceToTarget; + b_haveClosestDistance = true; + bestAreaNum = reach->toAreaNum; + } + } + } + */ + } + } + + if ( bestAreaNum ) + { + goal.areaNum = bestAreaNum; + goal.origin = AreaCenter( bestAreaNum ); + return true; + } + + return false; +} + +void idAASLocal::AddElevator(CMultiStateMover* mover) +{ + elevatorSystem->AddElevator(mover); +} + +void idAASLocal::CompileEAS() +{ + elevatorSystem->Compile(); +} + +int idAASLocal::GetAreaInCluster(int clusterNum) +{ + if (!file) return -1; + + // Find an area within that cluster + for (int i = 0; i < file->GetNumAreas(); i++) + { + const aasArea_t& area = file->GetArea(i); + if (area.cluster == clusterNum && (area.flags & AREA_REACHABLE_WALK) != 0) + { + return i; + } + } + + return -1; +} diff --git a/game/ai/AI.cpp b/game/ai/AI.cpp new file mode 100644 index 000000000..409e86e48 --- /dev/null +++ b/game/ai/AI.cpp @@ -0,0 +1,11633 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "Mind.h" +#include "Subsystem.h" +#include "MovementSubsystem.h" +#include "Memory.h" +#include "States/KnockedOutState.h" +#include "States/DeadState.h" +#include "States/ConversationState.h" +#include "States/PainState.h" +#include "States/IdleState.h" +#include "States/ObservantState.h" +#include "States/SuspiciousState.h" +#include "States/SearchingState.h" +#include "States/AgitatedSearchingState.h" +#include "States/CombatState.h" +#include "Tasks/SingleBarkTask.h" +#include "Conversation/ConversationSystem.h" +#include "../Relations.h" +#include "../Objectives/MissionData.h" +#include "../StimResponse/StimResponseCollection.h" +#include "../AbsenceMarker.h" +#include "../BloodMarker.h" +#include "../DarkModGlobals.h" +#include "../MultiStateMover.h" +#include "../MeleeWeapon.h" +#include "../SndProp.h" +#include "../EscapePointManager.h" +#include "../PositionWithinRangeFinder.h" +#include "../TimerManager.h" +#include "../ProjectileResult.h" // grayman #2872 + +// For handling the opening of doors and other binary Frob movers +#include "../BinaryFrobMover.h" +#include "../FrobDoor.h" +#include "../FrobDoorHandle.h" +#include "tdmAASFindEscape.h" +#include "AreaManager.h" + +#include + +//TODO: Move these to AI def: + +// Visual detection parameters + +/** +* amount of time to normalize by for the % check, in seconds +* this gets modified by 1 / the cvar dm_ai_sight. +**/ +static const float s_VisNormtime = 0.2f; + +/** +* In pitch darkness, player is invisible +**/ +// full bright minimum distance is 0 +static const float s_VisFDMin = 0.0f; + +// full bright maximum distance is zero (because probability is always zero anyway) +static const float s_VisFDMax = 0.0f; + +// TODO: Move this to def file or INI +static const float s_AITactDist = 1.0f; + +const float s_DOOM_TO_METERS = 0.0254f; + +// TDM: Maximum flee distance for any AI +const float MAX_FLEE_DISTANCE = 10000.0f; + +class CRelations; +class CsndProp; +class CDarkModPlayer; +class CMissionData; + +static const char *moveCommandString[ NUM_MOVE_COMMANDS ] = { + "MOVE_NONE", + "MOVE_FACE_ENEMY", + "MOVE_FACE_ENTITY", + "MOVE_TO_ENEMY", + "MOVE_TO_ENEMYHEIGHT", + "MOVE_TO_ENTITY", + "MOVE_OUT_OF_RANGE", + "MOVE_TO_ATTACK_POSITION", + "MOVE_TO_COVER", + "MOVE_TO_POSITION", + "MOVE_TO_POSITION_DIRECT", + "MOVE_SLIDE_TO_POSITION", + "MOVE_WANDER" +}; + +/* +============ +idAASFindCover::idAASFindCover +============ +*/ +idAASFindCover::idAASFindCover( const idActor* hidingActor, const idEntity* hideFromEnt, const idVec3 &hideFromPos ) { + this->hidingActor = hidingActor; // This should not be NULL + this->hideFromEnt = hideFromEnt; // May be NULL + this->hideFromPos = hideFromPos; +} + +/* +============ +idAASFindCover::~idAASFindCover +============ +*/ +idAASFindCover::~idAASFindCover() { +} + +/* +============ +idAASFindCover::TestArea +============ +*/ +bool idAASFindCover::TestArea( const idAAS *aas, int areaNum ) +{ + idVec3 areaCenter; + trace_t trace, trace2; + + if (areaNum == aas->PointAreaNum(hidingActor->GetPhysics()->GetOrigin())) + { + // We're in this AAS area; assume that our current position can never be cover. + // (If it was, we probably wouldn't be trying to move into cover.) + return false; + } + + // Get location of feet + // Assumes they're at the centre of the bounding box in the X and Y axes, + // but at the bottom in the Z axis. + idBounds bounds = hidingActor->GetPhysics()->GetAbsBounds(); + idVec3 feet = (bounds[0] + bounds[1]) * 0.5f; + feet.z = bounds[0].z; + + // Get location to trace to + areaCenter = aas->AreaCenter( areaNum ); + + // Adjust areaCenter to factor in height of AI, so we trace from the estimated eye position + areaCenter += hidingActor->GetEyePosition() - feet; + + gameLocal.clip.TracePoint(trace, hideFromPos, areaCenter, MASK_OPAQUE, hideFromEnt); + if (trace.fraction < 1.0f) + { + // The trace was interrupted, so this location is probably cover. + //gameRenderWorld->DebugLine( colorGreen, hideFromPos, areaCenter, 5000, true); + + // But before we say for certain, let's look at the floor as well. + areaCenter = aas->AreaCenter( areaNum ); + gameLocal.clip.TracePoint(trace2, hideFromPos, areaCenter, MASK_OPAQUE, hideFromEnt); + if (trace2.fraction < 1.0f) + { + // Yes, the feet are hidden too, so this is almost certainly cover + //gameRenderWorld->DebugLine( colorGreen, hideFromPos, areaCenter, 5000, true); + return true; + } + + // Oops; the head is hidden but the feet are not, so this isn't very good cover at all. + //gameRenderWorld->DebugLine( colorRed, hideFromPos, areaCenter, 5000, true); + return false; + } + + // The trace found a clear path, so this location is not cover. + //gameRenderWorld->DebugLine( colorRed, hideFromPos, areaCenter, 5000, true); + return false; +} + +/* +============ +idAASFindAreaOutOfRange::idAASFindAreaOutOfRange +============ +*/ +idAASFindAreaOutOfRange::idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist ) { + this->targetPos = targetPos; + this->maxDistSqr = maxDist * maxDist; +} + +/* +============ +idAASFindAreaOutOfRange::TestArea +============ +*/ +bool idAASFindAreaOutOfRange::TestArea( const idAAS *aas, int areaNum ) { + const idVec3 &areaCenter = aas->AreaCenter( areaNum ); + trace_t trace; + float dist; + + dist = ( targetPos.ToVec2() - areaCenter.ToVec2() ).LengthSqr(); + + if ( ( maxDistSqr > 0.0f ) && ( dist < maxDistSqr ) ) { + return false; + } + + gameLocal.clip.TracePoint( trace, targetPos, areaCenter + idVec3( 0.0f, 0.0f, 1.0f ), MASK_OPAQUE, NULL ); + if ( trace.fraction < 1.0f ) { + return false; + } + + return true; +} + +/* +============ +idAASFindAttackPosition::idAASFindAttackPosition +============ +*/ +idAASFindAttackPosition::idAASFindAttackPosition(idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset) +{ + int numPVSAreas; + + this->target = target; + this->targetPos = targetPos; + this->fireOffset = fireOffset; + this->self = self; + this->gravityAxis = gravityAxis; + + excludeBounds = idBounds( idVec3( -64.0, -64.0f, -8.0f ), idVec3( 64.0, 64.0f, 64.0f ) ); + excludeBounds.TranslateSelf( self->GetPhysics()->GetOrigin() ); + + // setup PVS + idBounds bounds( targetPos - idVec3( 16, 16, 0 ), targetPos + idVec3( 16, 16, 64 ) ); + numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); + targetPVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); +} + +/* +============ +idAASFindAttackPosition::~idAASFindAttackPosition +============ +*/ +idAASFindAttackPosition::~idAASFindAttackPosition() { + gameLocal.pvs.FreeCurrentPVS( targetPVS ); +} + +/* +============ +idAASFindAttackPosition::TestArea +============ +*/ +bool idAASFindAttackPosition::TestArea( const idAAS *aas, int areaNum ) { + idVec3 dir; + idVec3 local_dir; + idVec3 fromPos; + idMat3 axis; + idVec3 areaCenter; + int numPVSAreas; + int PVSAreas[ idEntity::MAX_PVS_AREAS ]; + + areaCenter = aas->AreaCenter( areaNum ); + areaCenter[ 2 ] += 1.0f; + + if ( excludeBounds.ContainsPoint( areaCenter ) ) { + // too close to where we already are + return false; + } + + numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); + if ( !gameLocal.pvs.InCurrentPVS( targetPVS, PVSAreas, numPVSAreas ) ) { + return false; + } + + // calculate the world transform of the launch position + dir = targetPos - areaCenter; + gravityAxis.ProjectVector( dir, local_dir ); + local_dir.z = 0.0f; + local_dir.ToVec2().Normalize(); + axis = local_dir.ToMat3(); + fromPos = areaCenter + fireOffset * axis; + + return self->GetAimDir( fromPos, target, self, dir ); +} + + +/* +============ +idAASFindObservationPosition::idAASFindObservationPosition +============ +*/ +idAASFindObservationPosition::idAASFindObservationPosition( const idAI *self, const idMat3 &gravityAxis, const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistanceFromWhichToObserve ) +{ + int numPVSAreas; + + this->targetPos = targetPos; + this->eyeOffset = eyeOffset; + this->self = self; + this->gravityAxis = gravityAxis; + this->maxObservationDistance = maxDistanceFromWhichToObserve; + this->b_haveBestGoal = false; + + + // setup PVS + idBounds bounds( targetPos - idVec3( 16, 16, 0 ), targetPos + idVec3( 16, 16, 64 ) ); + numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); + targetPVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); +} + +/* +============ +idAASFindObservationPosition::~idAASFindObservationPosition +============ +*/ +idAASFindObservationPosition::~idAASFindObservationPosition() { + gameLocal.pvs.FreeCurrentPVS( targetPVS ); +} + +/* +============ +idAASFindObservationPosition::TestArea +============ +*/ +bool idAASFindObservationPosition::TestArea( const idAAS *aas, int areaNum ) +{ + idVec3 dir; + idVec3 local_dir; + idVec3 fromPos; + idMat3 axis; + idVec3 areaCenter; + + areaCenter = aas->AreaCenter( areaNum ); + areaCenter[ 2 ] += 1.0f; + + /* + numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); + if ( !gameLocal.pvs.InCurrentPVS( targetPVS, PVSAreas, numPVSAreas ) ) { + return false; + } + */ + + // calculate the world transform of the view position + dir = targetPos - areaCenter; + gravityAxis.ProjectVector( dir, local_dir ); + local_dir.z = 0.0f; + local_dir.ToVec2().Normalize(); + axis = local_dir.ToMat3(); + + fromPos = areaCenter + eyeOffset * axis; + + // Run trace + trace_t results; + gameLocal.clip.TracePoint( results, fromPos, targetPos, MASK_SOLID, self ); + if ( results.fraction >= 1.0f ) + { + // What is the observation distance? + float distance = (fromPos - targetPos).Length(); + + // Remember best result, even if outside max distance allowed + if ((!b_haveBestGoal) || (distance < bestGoalDistance)) + { + b_haveBestGoal = true; + bestGoalDistance = distance; + bestGoal.areaNum = areaNum; + bestGoal.origin = areaCenter; + } + if (distance > maxObservationDistance) + { + // Can't use this point, its too far + return false; + } + return true; + } + else + { + return false; + } + +} + +//------------------------------------------------------------------------------ + +bool idAASFindObservationPosition::getBestGoalResult +( + float& out_bestGoalDistance, + aasGoal_t& out_bestGoal +) +{ + if (b_haveBestGoal) + { + out_bestGoalDistance = bestGoalDistance; + out_bestGoal = bestGoal; + return true; + } + else + { + return false; + } +} + + +/* +===================== +idAI::idAI +===================== +*/ +idAI::idAI() +{ + aiNode.SetOwner(this); + + aas = NULL; + travelFlags = TFL_WALK|TFL_AIR|TFL_DOOR; + lastAreaReevaluationTime = -1; + maxAreaReevaluationInterval = 2000; // msec + doorRetryTime = 120000; // msec + + kickForce = 60.0f; // grayman #2568 - default Doom 3 value + ignore_obstacles = false; + blockedRadius = 0.0f; + blockedMoveTime = 750; + blockedAttackTime = 750; + turnRate = 360.0f; + turnVel = 0.0f; + anim_turn_yaw = 0.0f; + anim_turn_amount = 0.0f; + anim_turn_angles = 0.0f; + reachedpos_bbox_expansion = 0.0f; + aas_reachability_z_tolerance = 75; + fly_offset = 0; + fly_seek_scale = 1.0f; + fly_roll_scale = 0.0f; + fly_roll_max = 0.0f; + fly_roll = 0.0f; + fly_pitch_scale = 0.0f; + fly_pitch_max = 0.0f; + fly_pitch = 0.0f; + allowMove = false; + allowHiddenMovement = false; + fly_speed = 0.0f; + fly_bob_strength = 0.0f; + fly_bob_vert = 0.0f; + fly_bob_horz = 0.0f; + lastHitCheckResult = false; + lastHitCheckTime = 0; + lastAttackTime = 0; + fire_range = 0.0f; + projectile_height_to_distance_ratio = 1.0f; + activeProjectile.projEnt = NULL; + curProjectileIndex = -1; + talk_state = TALK_NEVER; + talkTarget = NULL; + + particles.Clear(); + restartParticles = true; + useBoneAxis = false; + + wakeOnFlashlight = false; + lastUpdateEnemyPositionTime = -1; + + // grayman #2887 - for keeping track of the total time this AI saw the player + lastTimePlayerSeen = -1; + lastTimePlayerLost = -1; + + memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); + worldMuzzleFlashHandle = -1; + + enemy = NULL; + lastVisibleEnemyPos.Zero(); + lastVisibleEnemyEyeOffset.Zero(); + lastVisibleReachableEnemyPos.Zero(); + lastReachableEnemyPos.Zero(); + enemyReachable = false; + shrivel_rate = 0.0f; + shrivel_start = 0; + fl.neverDormant = false; // AI's can go dormant + current_yaw = 0.0f; + ideal_yaw = 0.0f; + + num_cinematics = 0; + current_cinematic = 0; + + allowEyeFocus = true; + allowPain = true; + allowJointMod = true; + focusEntity = NULL; + focusTime = 0; + alignHeadTime = 0; + forceAlignHeadTime = 0; + + currentFocusPos.Zero(); + eyeAng.Zero(); + lookAng.Zero(); + destLookAng.Zero(); + lookMin.Zero(); + lookMax.Zero(); + + eyeMin.Zero(); + eyeMax.Zero(); + muzzleFlashEnd = 0; + flashTime = 0; + flashJointWorld = INVALID_JOINT; + + focusJoint = INVALID_JOINT; + orientationJoint = INVALID_JOINT; + flyTiltJoint = INVALID_JOINT; + + eyeVerticalOffset = 0.0f; + eyeHorizontalOffset = 0.0f; + eyeFocusRate = 0.0f; + headFocusRate = 0.0f; + focusAlignTime = 0; + m_tactileEntity = NULL; // grayman #2345 + m_canResolveBlock = true; // grayman #2345 + m_leftQueue = false; // grayman #2345 + m_performRelight = false; // grayman #2603 + + m_SoundDir.Zero(); + m_LastSight.Zero(); + m_AlertLevelThisFrame = 0.0f; + m_prevAlertIndex = 0; + m_maxAlertLevel = 0; + m_maxAlertIndex = 0; + m_AlertedByActor = NULL; + + m_TactAlertEnt = NULL; + m_AlertGraceActor = NULL; + m_AlertGraceStart = 0; + m_AlertGraceTime = 0; + m_AlertGraceThresh = 0; + m_AlertGraceCount = 0; + m_AlertGraceCountLimit = 0; + m_AudThreshold = 0.0f; + m_oldVisualAcuity = 0.0f; + + /** + * Darkmod: No hiding spot search by default + */ + m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; + + m_bCanDrown = true; + m_AirCheckTimer = 0; + m_AirTics = 0; + m_AirTicksMax = 0; + m_HeadBodyID = 0; + m_HeadJointID = INVALID_JOINT; + m_OrigHeadCM = NULL; + m_bHeadCMSwapped = false; + m_MouthOffset = vec3_zero; + + m_bCanBeKnockedOut = true; + m_HeadCenterOffset = vec3_zero; + m_FOVRot = mat3_identity; + m_bKoAlertImmune = false; + m_KoDotVert = 0; + m_KoDotHoriz = 0; + m_KoAlertDotHoriz = 0; + m_KoRot = mat3_identity; + + m_bCanBeGassed = true; // grayman #2468 + m_koState = KO_NOT; // grayman #2604 + m_earlyThinkCounter = 5 + gameLocal.random.RandomInt(5); // grayman #2654 + m_bCanExtricate = true; // grayman #2603 + + m_bCanOperateDoors = false; + + m_lipSyncActive = false; + + m_bPushOffPlayer = false; + + m_bCanBeFlatFooted = false; + m_bFlatFooted = false; + m_FlatFootedTimer = 0; + m_FlatFootedTime = 0; + + m_FlatFootParryNum = 0; + m_FlatFootParryMax = 0; + m_FlatFootParryTimer = 0; + m_FlatFootParryTime = 0; + m_MeleeCounterAttChance = 0.0f; + m_bMeleePredictProximity = false; + + m_maxInterleaveThinkFrames = 0; + m_minInterleaveThinkDist = 1000; + m_maxInterleaveThinkDist = 3000; + m_lastThinkTime = 0; + m_nextThinkFrame = 0; + + INIT_TIMER_HANDLE(aiThinkTimer); + INIT_TIMER_HANDLE(aiMindTimer); + INIT_TIMER_HANDLE(aiAnimationTimer); + INIT_TIMER_HANDLE(aiPushWithAFTimer); + INIT_TIMER_HANDLE(aiUpdateEnemyPositionTimer); + INIT_TIMER_HANDLE(aiScriptTimer); + INIT_TIMER_HANDLE(aiAnimMoveTimer); + INIT_TIMER_HANDLE(aiObstacleAvoidanceTimer); + INIT_TIMER_HANDLE(aiPhysicsTimer); + INIT_TIMER_HANDLE(aiGetMovePosTimer); + INIT_TIMER_HANDLE(aiPathToGoalTimer); + INIT_TIMER_HANDLE(aiGetFloorPosTimer); + INIT_TIMER_HANDLE(aiPointReachableAreaNumTimer); + INIT_TIMER_HANDLE(aiCanSeeTimer); + +} + +/* +===================== +idAI::~idAI +===================== +*/ +idAI::~idAI() +{ + DeconstructScriptObject(); + scriptObject.Free(); + if ( worldMuzzleFlashHandle != -1 ) + { + gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + worldMuzzleFlashHandle = -1; + } + + /** + * Darkmod: Get rid of current hiding spot search if there is one. + */ + destroyCurrentHidingSpotSearch(); + + aiNode.Remove(); + + if( m_OrigHeadCM ) + delete m_OrigHeadCM; +} + +/* +===================== +idAI::Save +===================== +*/ +void idAI::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( travelFlags ); + savefile->WriteInt(lastAreaReevaluationTime); + savefile->WriteInt(maxAreaReevaluationInterval); + savefile->WriteInt(doorRetryTime); + + move.Save( savefile ); + savedMove.Save( savefile ); + + // greebo: save the movestack + savefile->WriteInt(static_cast(moveStack.size())); + for (std::list::const_iterator m = moveStack.begin(); m != moveStack.end(); ++m) + { + m->Save(savefile); + } + + savefile->WriteFloat( kickForce ); + savefile->WriteBool( ignore_obstacles ); + savefile->WriteFloat( blockedRadius ); + savefile->WriteInt( blockedMoveTime ); + savefile->WriteInt( blockedAttackTime ); + + savefile->WriteFloat( ideal_yaw ); + savefile->WriteFloat( current_yaw ); + savefile->WriteFloat( turnRate ); + savefile->WriteFloat( turnVel ); + savefile->WriteFloat( anim_turn_yaw ); + savefile->WriteFloat( anim_turn_amount ); + savefile->WriteFloat( anim_turn_angles ); + savefile->WriteVec3(sitting_turn_pivot); + + savefile->WriteFloat(reachedpos_bbox_expansion); + savefile->WriteFloat(aas_reachability_z_tolerance); + + savefile->WriteStaticObject( physicsObj ); + + savefile->WriteFloat( fly_speed ); + savefile->WriteFloat( fly_bob_strength ); + savefile->WriteFloat( fly_bob_vert ); + savefile->WriteFloat( fly_bob_horz ); + savefile->WriteInt( fly_offset ); + savefile->WriteFloat( fly_seek_scale ); + savefile->WriteFloat( fly_roll_scale ); + savefile->WriteFloat( fly_roll_max ); + savefile->WriteFloat( fly_roll ); + savefile->WriteFloat( fly_pitch_scale ); + savefile->WriteFloat( fly_pitch_max ); + savefile->WriteFloat( fly_pitch ); + + savefile->WriteBool( allowMove ); + savefile->WriteBool( allowHiddenMovement ); + savefile->WriteBool( disableGravity ); + + savefile->WriteBool( lastHitCheckResult ); + savefile->WriteInt( lastHitCheckTime ); + savefile->WriteInt( lastAttackTime ); + savefile->WriteFloat( fire_range ); + savefile->WriteFloat( projectile_height_to_distance_ratio ); + + savefile->WriteInt( missileLaunchOffset.Num() ); + for( i = 0; i < missileLaunchOffset.Num(); i++ ) { + savefile->WriteVec3( missileLaunchOffset[ i ] ); + } + + savefile->WriteInt(projectileInfo.Num()); + + for (i = 0; i < projectileInfo.Num(); ++i) + { + const ProjectileInfo& info = projectileInfo[i]; + + // Save projectile def names instead of dict* pointers, will be resolved at restore time + // also leave clipmodel pointer alone, will be initialised to NULL on restore and + // reloaded on demand + savefile->WriteString(info.defName); + savefile->WriteFloat(info.radius); + savefile->WriteFloat(info.speed); + savefile->WriteVec3(info.velocity); + savefile->WriteVec3(info.gravity); + } + + savefile->WriteInt(curProjectileIndex); + + // Active Projectile + savefile->WriteString(activeProjectile.info.defName); + savefile->WriteFloat(activeProjectile.info.radius); + savefile->WriteFloat(activeProjectile.info.speed); + savefile->WriteVec3(activeProjectile.info.velocity); + savefile->WriteVec3(activeProjectile.info.gravity); + activeProjectile.projEnt.Save(savefile); + + savefile->WriteString( attack ); + + // grayman #2603 - delayed stim list + + savefile->WriteInt(delayedStims.Num()); + for (i = 0 ; i < delayedStims.Num() ; i++) + { + DelayedStim ds = delayedStims[i]; + + savefile->WriteInt(ds.nextTimeToConsider); + ds.stim.Save(savefile); + } + + savefile->WriteInt( talk_state ); + talkTarget.Save( savefile ); + + savefile->WriteInt( num_cinematics ); + savefile->WriteInt( current_cinematic ); + + savefile->WriteBool( allowJointMod ); + focusEntity.Save( savefile ); + savefile->WriteVec3( currentFocusPos ); + savefile->WriteInt( focusTime ); + savefile->WriteInt( alignHeadTime ); + savefile->WriteInt( forceAlignHeadTime ); + savefile->WriteAngles( eyeAng ); + savefile->WriteAngles( lookAng ); + savefile->WriteAngles( destLookAng ); + savefile->WriteAngles( lookMin ); + savefile->WriteAngles( lookMax ); + + savefile->WriteInt( lookJoints.Num() ); + for( i = 0; i < lookJoints.Num(); i++ ) { + savefile->WriteJoint( lookJoints[ i ] ); + savefile->WriteAngles( lookJointAngles[ i ] ); + } + savefile->WriteInt( lookJointsCombat.Num() ); + for( i = 0; i < lookJointsCombat.Num(); i++ ) { + savefile->WriteJoint( lookJointsCombat[ i ] ); + savefile->WriteAngles( lookJointAnglesCombat[ i ] ); + } + + savefile->WriteFloat( shrivel_rate ); + savefile->WriteInt( shrivel_start ); + + savefile->WriteInt( particles.Num() ); + for ( i = 0; i < particles.Num(); i++ ) { + savefile->WriteParticle( particles[i].particle ); + savefile->WriteInt( particles[i].time ); + savefile->WriteJoint( particles[i].joint ); + } + savefile->WriteBool( restartParticles ); + savefile->WriteBool( useBoneAxis ); + + enemy.Save( savefile ); + savefile->WriteVec3( lastVisibleEnemyPos ); + savefile->WriteVec3( lastVisibleEnemyEyeOffset ); + savefile->WriteVec3( lastVisibleReachableEnemyPos ); + savefile->WriteVec3( lastReachableEnemyPos ); + savefile->WriteBool( enemyReachable ); + savefile->WriteBool( wakeOnFlashlight ); + savefile->WriteInt(lastUpdateEnemyPositionTime); + + savefile->WriteInt(lastTimePlayerSeen); // grayman #2887 + savefile->WriteInt(lastTimePlayerLost); // grayman #2887 + + savefile->WriteAngles( eyeMin ); + savefile->WriteAngles( eyeMax ); + + savefile->WriteFloat( eyeVerticalOffset ); + savefile->WriteFloat( eyeHorizontalOffset ); + savefile->WriteFloat( eyeFocusRate ); + savefile->WriteFloat( headFocusRate ); + savefile->WriteInt( focusAlignTime ); + savefile->WriteObject(m_tactileEntity); // grayman #2345 + savefile->WriteBool(m_canResolveBlock); // grayman #2345 + savefile->WriteBool(m_leftQueue); // grayman #2345 + savefile->WriteBool(m_performRelight); // grayman #2603 + savefile->WriteJoint( flashJointWorld ); + savefile->WriteInt( muzzleFlashEnd ); + + savefile->WriteJoint( focusJoint ); + savefile->WriteJoint( orientationJoint ); + savefile->WriteJoint( flyTiltJoint ); + + // TDM Alerts: + savefile->WriteInt( m_Acuities.Num() ); + for( i = 0; i < m_Acuities.Num(); i++ ) + { + savefile->WriteFloat( m_Acuities[ i ] ); + } + savefile->WriteFloat(m_oldVisualAcuity); + savefile->WriteFloat( m_AudThreshold ); + savefile->WriteVec3( m_SoundDir ); + savefile->WriteVec3( m_LastSight ); + savefile->WriteFloat( m_AlertLevelThisFrame ); + savefile->WriteInt( m_prevAlertIndex ); + savefile->WriteFloat( m_maxAlertLevel); + savefile->WriteInt( m_maxAlertIndex); + savefile->WriteFloat(m_lastAlertLevel); + savefile->WriteBool( m_bIgnoreAlerts ); + + m_AlertedByActor.Save( savefile ); + + for (i = 0; i < ai::EAlertTypeCount; i++) + { + savefile->WriteInt(alertTypeWeight[i]); + } + + m_TactAlertEnt.Save( savefile ); + m_AlertGraceActor.Save( savefile ); + savefile->WriteInt( m_AlertGraceStart ); + savefile->WriteInt( m_AlertGraceTime ); + savefile->WriteFloat( m_AlertGraceThresh ); + savefile->WriteInt( m_AlertGraceCount ); + savefile->WriteInt( m_AlertGraceCountLimit ); + + savefile->WriteInt(m_Messages.Num()); + for (i = 0; i < m_Messages.Num(); i++) + { + m_Messages[i]->Save(savefile); + } + + savefile->WriteBool( GetPhysics() == static_cast(&physicsObj) ); + + savefile->WriteFloat(m_VisDistMax); + + savefile->WriteInt(m_HidingSpotSearchHandle); + m_hidingSpots.Save(savefile); + + savefile->WriteInt(m_AirCheckTimer); + savefile->WriteBool(m_bCanDrown); + savefile->WriteInt(m_HeadBodyID); + savefile->WriteJoint(m_HeadJointID); + + savefile->WriteBool( m_bHeadCMSwapped ); +// if( m_bHeadCMSwapped && m_OrigHeadCM ) +// m_OrigHeadCM->Save( savefile ); + + savefile->WriteInt(m_AirTics); + savefile->WriteInt(m_AirTicksMax); + savefile->WriteInt(m_AirCheckInterval); + + savefile->WriteVec3(m_MouthOffset); + savefile->WriteBool(m_bCanBeKnockedOut); + savefile->WriteVec3(m_HeadCenterOffset); + savefile->WriteMat3(m_FOVRot); + savefile->WriteString(m_KoZone); + savefile->WriteInt(m_KoAlertState); + savefile->WriteInt(m_KoAlertImmuneState); + savefile->WriteBool(m_bKoAlertImmune); + savefile->WriteFloat(m_KoDotVert); + savefile->WriteFloat(m_KoDotHoriz); + savefile->WriteFloat(m_KoAlertDotVert); + savefile->WriteFloat(m_KoAlertDotHoriz); + savefile->WriteMat3(m_KoRot); + + savefile->WriteBool(m_bCanBeGassed); // grayman #2468 + savefile->WriteInt( m_koState ); // grayman #2604 + savefile->WriteInt( m_earlyThinkCounter ); // grayman #2654 + savefile->WriteBool( m_bCanExtricate ); // grayman #2603 + + savefile->WriteFloat(thresh_1); + savefile->WriteFloat(thresh_2); + savefile->WriteFloat(thresh_3); + savefile->WriteFloat(thresh_4); + savefile->WriteFloat(thresh_5); + + savefile->WriteFloat(m_gracetime_1); + savefile->WriteFloat(m_gracetime_2); + savefile->WriteFloat(m_gracetime_3); + savefile->WriteFloat(m_gracetime_4); + savefile->WriteFloat(m_gracefrac_1); + savefile->WriteFloat(m_gracefrac_2); + savefile->WriteFloat(m_gracefrac_3); + savefile->WriteFloat(m_gracefrac_4); + savefile->WriteFloat(m_gracecount_1); + savefile->WriteFloat(m_gracecount_2); + savefile->WriteFloat(m_gracecount_3); + savefile->WriteFloat(m_gracecount_4); + + savefile->WriteFloat(atime1); + savefile->WriteFloat(atime2); + savefile->WriteFloat(atime3); + savefile->WriteFloat(atime4); + savefile->WriteFloat(atime_fleedone); + + savefile->WriteFloat(atime1_fuzzyness); + savefile->WriteFloat(atime2_fuzzyness); + savefile->WriteFloat(atime3_fuzzyness); + savefile->WriteFloat(atime4_fuzzyness); + savefile->WriteFloat(atime_fleedone_fuzzyness); + + savefile->WriteInt(m_timeBetweenHeadTurnChecks); + savefile->WriteFloat(m_headTurnChanceIdle); + savefile->WriteFloat(m_headTurnFactorAlerted); + savefile->WriteFloat(m_headTurnMaxYaw); + savefile->WriteFloat(m_headTurnMaxPitch); + savefile->WriteInt(m_headTurnMinDuration); + savefile->WriteInt(m_headTurnMaxDuration); + + savefile->WriteInt(static_cast(backboneStates.size())); + for (BackboneStateMap::const_iterator i = backboneStates.begin(); i != backboneStates.end(); ++i) + { + savefile->WriteInt(i->first); + savefile->WriteString(i->second); + } + + savefile->WriteInt(m_maxInterleaveThinkFrames); + savefile->WriteFloat(m_minInterleaveThinkDist); + savefile->WriteFloat(m_maxInterleaveThinkDist); + + savefile->WriteInt(m_lastThinkTime); + savefile->WriteInt(m_nextThinkFrame); + + savefile->WriteBool(m_bPushOffPlayer); + + savefile->WriteBool(m_bCanBeFlatFooted); + savefile->WriteBool(m_bFlatFooted); + savefile->WriteInt(m_FlatFootedTimer); + savefile->WriteInt(m_FlatFootedTime); + savefile->WriteInt(m_FlatFootParryNum); + savefile->WriteInt(m_FlatFootParryMax); + savefile->WriteInt(m_FlatFootParryTimer); + savefile->WriteInt(m_FlatFootParryTime); + savefile->WriteFloat(m_MeleeCounterAttChance); + savefile->WriteBool(m_bMeleePredictProximity); + + savefile->WriteBool(m_bCanOperateDoors); + savefile->WriteBool(m_HandlingDoor); + savefile->WriteBool(m_HandlingElevator); + savefile->WriteBool(m_RelightingLight); // grayman #2603 + savefile->WriteBool(m_ExaminingRope); // grayman #2872 + savefile->WriteBool(m_DroppingTorch); // grayman #2603 + savefile->WriteBool(m_RestoreMove); // grayman #2706 + savefile->WriteBool(m_LatchedSearch); // grayman #2603 + + // grayman #2603 + savefile->WriteInt( m_dousedLightsSeen.Num() ); + for (int i = 0 ; i < m_dousedLightsSeen.Num() ; i++ ) + { + m_dousedLightsSeen[i].Save(savefile); + } + + int size = unlockableDoors.size(); + savefile->WriteInt(size); + for (FrobMoverList::const_iterator i = unlockableDoors.begin(); i != unlockableDoors.end(); ++i) + { + savefile->WriteObject(*i); + } + + savefile->WriteInt(tactileIgnoreEntities.size()); + + for (TactileIgnoreList::const_iterator i = tactileIgnoreEntities.begin(); i != tactileIgnoreEntities.end(); ++i) + { + savefile->WriteObject(*i); + } + + mind->Save(savefile); + + senseSubsystem->Save(savefile); + movementSubsystem->Save(savefile); + commSubsystem->Save(savefile); + actionSubsystem->Save(savefile); + + SAVE_TIMER_HANDLE(aiThinkTimer, savefile); + SAVE_TIMER_HANDLE(aiMindTimer, savefile); + SAVE_TIMER_HANDLE(aiAnimationTimer, savefile); + SAVE_TIMER_HANDLE(aiPushWithAFTimer, savefile); + SAVE_TIMER_HANDLE(aiUpdateEnemyPositionTimer, savefile); + SAVE_TIMER_HANDLE(aiScriptTimer, savefile); + SAVE_TIMER_HANDLE(aiAnimMoveTimer, savefile); + SAVE_TIMER_HANDLE(aiObstacleAvoidanceTimer, savefile); + SAVE_TIMER_HANDLE(aiPhysicsTimer, savefile); + SAVE_TIMER_HANDLE(aiGetMovePosTimer, savefile); + SAVE_TIMER_HANDLE(aiPathToGoalTimer, savefile); + SAVE_TIMER_HANDLE(aiGetFloorPosTimer, savefile); + SAVE_TIMER_HANDLE(aiPointReachableAreaNumTimer, savefile); + SAVE_TIMER_HANDLE(aiCanSeeTimer, savefile); + +} + +/* +===================== +idAI::Restore +===================== +*/ +void idAI::Restore( idRestoreGame *savefile ) { + bool restorePhysics; + int i; + int num; + idBounds bounds; + + savefile->ReadInt( travelFlags ); + savefile->ReadInt(lastAreaReevaluationTime); + savefile->ReadInt(maxAreaReevaluationInterval); + savefile->ReadInt(doorRetryTime); + + move.Restore( savefile ); + savedMove.Restore( savefile ); + + // greebo: restore the movestack + moveStack.clear(); + savefile->ReadInt(num); + for (i = 0; i < num; i++) + { + moveStack.push_back(idMoveState()); + moveStack.back().Restore(savefile); + } + + savefile->ReadFloat( kickForce ); + savefile->ReadBool( ignore_obstacles ); + savefile->ReadFloat( blockedRadius ); + savefile->ReadInt( blockedMoveTime ); + savefile->ReadInt( blockedAttackTime ); + + savefile->ReadFloat( ideal_yaw ); + savefile->ReadFloat( current_yaw ); + savefile->ReadFloat( turnRate ); + savefile->ReadFloat( turnVel ); + savefile->ReadFloat( anim_turn_yaw ); + savefile->ReadFloat( anim_turn_amount ); + savefile->ReadFloat( anim_turn_angles ); + savefile->ReadVec3(sitting_turn_pivot); + + savefile->ReadFloat(reachedpos_bbox_expansion); + savefile->ReadFloat(aas_reachability_z_tolerance); + + savefile->ReadStaticObject( physicsObj ); + + savefile->ReadFloat( fly_speed ); + savefile->ReadFloat( fly_bob_strength ); + savefile->ReadFloat( fly_bob_vert ); + savefile->ReadFloat( fly_bob_horz ); + savefile->ReadInt( fly_offset ); + savefile->ReadFloat( fly_seek_scale ); + savefile->ReadFloat( fly_roll_scale ); + savefile->ReadFloat( fly_roll_max ); + savefile->ReadFloat( fly_roll ); + savefile->ReadFloat( fly_pitch_scale ); + savefile->ReadFloat( fly_pitch_max ); + savefile->ReadFloat( fly_pitch ); + + savefile->ReadBool( allowMove ); + savefile->ReadBool( allowHiddenMovement ); + savefile->ReadBool( disableGravity ); + + savefile->ReadBool( lastHitCheckResult ); + savefile->ReadInt( lastHitCheckTime ); + savefile->ReadInt( lastAttackTime ); + savefile->ReadFloat( fire_range ); + savefile->ReadFloat( projectile_height_to_distance_ratio ); + + savefile->ReadInt( num ); + missileLaunchOffset.SetGranularity( 1 ); + missileLaunchOffset.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadVec3( missileLaunchOffset[ i ] ); + } + + savefile->ReadInt(num); + projectileInfo.SetNum(num); + + for (i = 0; i < projectileInfo.Num(); ++i) + { + ProjectileInfo& info = projectileInfo[i]; + + savefile->ReadString(info.defName); + // Resolve projectile def pointers from names + info.def = (info.defName.Length() > 0) ? gameLocal.FindEntityDefDict(info.defName) : NULL; + + // leave clipmodel pointer alone, is already initialised to NULL + savefile->ReadFloat(info.radius); + savefile->ReadFloat(info.speed); + savefile->ReadVec3(info.velocity); + savefile->ReadVec3(info.gravity); + } + + savefile->ReadInt(curProjectileIndex); + + // Active Projectile + savefile->ReadString(activeProjectile.info.defName); + + // Resolve projectile def pointers from names + if (activeProjectile.info.defName.Length() > 0) + { + activeProjectile.info.def = gameLocal.FindEntityDefDict(activeProjectile.info.defName); + } + else + { + activeProjectile.info.def = NULL; + } + + savefile->ReadFloat(activeProjectile.info.radius); + savefile->ReadFloat(activeProjectile.info.speed); + savefile->ReadVec3(activeProjectile.info.velocity); + savefile->ReadVec3(activeProjectile.info.gravity); + activeProjectile.projEnt.Restore(savefile); + + savefile->ReadString( attack ); + + // grayman #2603 - delayed stim list + + savefile->ReadInt(num); + delayedStims.SetNum(num); + for (i = 0 ; i < num ; i++) + { + savefile->ReadInt(delayedStims[i].nextTimeToConsider); + delayedStims[i].stim.Restore(savefile); + } + + savefile->ReadInt( i ); + talk_state = static_cast( i ); + talkTarget.Restore( savefile ); + + savefile->ReadInt( num_cinematics ); + savefile->ReadInt( current_cinematic ); + + savefile->ReadBool( allowJointMod ); + focusEntity.Restore( savefile ); + savefile->ReadVec3( currentFocusPos ); + savefile->ReadInt( focusTime ); + savefile->ReadInt( alignHeadTime ); + savefile->ReadInt( forceAlignHeadTime ); + savefile->ReadAngles( eyeAng ); + savefile->ReadAngles( lookAng ); + savefile->ReadAngles( destLookAng ); + savefile->ReadAngles( lookMin ); + savefile->ReadAngles( lookMax ); + + savefile->ReadInt( num ); + lookJoints.SetGranularity( 1 ); + lookJoints.SetNum( num ); + lookJointAngles.SetGranularity( 1 ); + lookJointAngles.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadJoint( lookJoints[ i ] ); + savefile->ReadAngles( lookJointAngles[ i ] ); + } + + savefile->ReadInt( num ); + lookJointsCombat.SetGranularity( 1 ); + lookJointsCombat.SetNum( num ); + lookJointAnglesCombat.SetGranularity( 1 ); + lookJointAnglesCombat.SetNum( num ); + for( i = 0; i < num; i++ ) { + savefile->ReadJoint( lookJointsCombat[ i ] ); + savefile->ReadAngles( lookJointAnglesCombat[ i ] ); + } + + savefile->ReadFloat( shrivel_rate ); + savefile->ReadInt( shrivel_start ); + + savefile->ReadInt( num ); + particles.SetNum( num ); + for ( i = 0; i < particles.Num(); i++ ) { + savefile->ReadParticle( particles[i].particle ); + savefile->ReadInt( particles[i].time ); + savefile->ReadJoint( particles[i].joint ); + } + savefile->ReadBool( restartParticles ); + savefile->ReadBool( useBoneAxis ); + + enemy.Restore( savefile ); + savefile->ReadVec3( lastVisibleEnemyPos ); + savefile->ReadVec3( lastVisibleEnemyEyeOffset ); + savefile->ReadVec3( lastVisibleReachableEnemyPos ); + savefile->ReadVec3( lastReachableEnemyPos ); + savefile->ReadBool( enemyReachable ); + savefile->ReadBool( wakeOnFlashlight ); + savefile->ReadInt(lastUpdateEnemyPositionTime); + savefile->ReadInt(lastTimePlayerSeen); // grayman #2887 + savefile->ReadInt(lastTimePlayerLost); // grayman #2887 + + savefile->ReadAngles( eyeMin ); + savefile->ReadAngles( eyeMax ); + + savefile->ReadFloat( eyeVerticalOffset ); + savefile->ReadFloat( eyeHorizontalOffset ); + savefile->ReadFloat( eyeFocusRate ); + savefile->ReadFloat( headFocusRate ); + savefile->ReadInt( focusAlignTime ); + savefile->ReadObject(reinterpret_cast(m_tactileEntity)); // grayman #2345 + savefile->ReadBool(m_canResolveBlock); // grayman #2345 + savefile->ReadBool(m_leftQueue); // grayman #2345 + savefile->ReadBool(m_performRelight); // grayman #2603 + savefile->ReadJoint( flashJointWorld ); + savefile->ReadInt( muzzleFlashEnd ); + + savefile->ReadJoint( focusJoint ); + savefile->ReadJoint( orientationJoint ); + savefile->ReadJoint( flyTiltJoint ); + + // TDM Alerts: + savefile->ReadInt( num ); + m_Acuities.SetNum( num ); + for( i = 0; i < num; i++ ) + { + savefile->ReadFloat( m_Acuities[ i ] ); + } + savefile->ReadFloat(m_oldVisualAcuity); + savefile->ReadFloat( m_AudThreshold ); + savefile->ReadVec3( m_SoundDir ); + savefile->ReadVec3( m_LastSight ); + savefile->ReadFloat( m_AlertLevelThisFrame ); + savefile->ReadInt( m_prevAlertIndex ); + savefile->ReadFloat( m_maxAlertLevel ); + savefile->ReadInt( m_maxAlertIndex); + savefile->ReadFloat(m_lastAlertLevel); + savefile->ReadBool( m_bIgnoreAlerts ); + + m_AlertedByActor.Restore( savefile ); + for (i = 0; i < ai::EAlertTypeCount; i++) + { + savefile->ReadInt(alertTypeWeight[i]); + } + m_TactAlertEnt.Restore( savefile ); + m_AlertGraceActor.Restore( savefile ); + savefile->ReadInt( m_AlertGraceStart ); + savefile->ReadInt( m_AlertGraceTime ); + savefile->ReadFloat( m_AlertGraceThresh ); + savefile->ReadInt( m_AlertGraceCount ); + savefile->ReadInt( m_AlertGraceCountLimit ); + + savefile->ReadInt(num); + m_Messages.Clear(); + for (int i = 0; i < num; i++) + { + ai::CommMessagePtr message(new ai::CommMessage); + message->Restore(savefile); + m_Messages.Append(message); + } + + savefile->ReadBool( restorePhysics ); + + // Set the AAS if the character has the correct gravity vector + idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); + gravity *= g_gravity.GetFloat(); + if ( gravity == gameLocal.GetGravity() ) { + SetAAS(); + } + + savefile->ReadFloat(m_VisDistMax); + + savefile->ReadInt(m_HidingSpotSearchHandle); + m_hidingSpots.Restore(savefile); + + savefile->ReadInt(m_AirCheckTimer); + savefile->ReadBool(m_bCanDrown); + savefile->ReadInt(m_HeadBodyID); + savefile->ReadJoint(m_HeadJointID); + + savefile->ReadBool( m_bHeadCMSwapped ); + // Ishtvan: if the head CM was swapped at save, swap it again + // (I tried to do this more correctly, but the AF itself isn't saving its new clipmodel) + if( m_bHeadCMSwapped ) + { + m_OrigHeadCM = NULL; + m_bHeadCMSwapped = false; + SwapHeadAFCM( true ); + } + + savefile->ReadInt(m_AirTics); + savefile->ReadInt(m_AirTicksMax); + savefile->ReadInt(m_AirCheckInterval); + + savefile->ReadVec3(m_MouthOffset); + savefile->ReadBool(m_bCanBeKnockedOut); + savefile->ReadVec3(m_HeadCenterOffset); + savefile->ReadMat3(m_FOVRot); + savefile->ReadString(m_KoZone); + savefile->ReadInt(m_KoAlertState); + savefile->ReadInt(m_KoAlertImmuneState); + savefile->ReadBool(m_bKoAlertImmune); + savefile->ReadFloat(m_KoDotVert); + savefile->ReadFloat(m_KoDotHoriz); + savefile->ReadFloat(m_KoAlertDotVert); + savefile->ReadFloat(m_KoAlertDotHoriz); + savefile->ReadMat3(m_KoRot); + + savefile->ReadBool(m_bCanBeGassed); // grayman #2468 + savefile->ReadInt( i ); // grayman #2604 + m_koState = static_cast( i ); + savefile->ReadInt(m_earlyThinkCounter); // grayman #2654 + savefile->ReadBool(m_bCanExtricate); // grayman #2603 + savefile->ReadFloat(thresh_1); + savefile->ReadFloat(thresh_2); + savefile->ReadFloat(thresh_3); + savefile->ReadFloat(thresh_4); + savefile->ReadFloat(thresh_5); + + savefile->ReadFloat(m_gracetime_1); + savefile->ReadFloat(m_gracetime_2); + savefile->ReadFloat(m_gracetime_3); + savefile->ReadFloat(m_gracetime_4); + savefile->ReadFloat(m_gracefrac_1); + savefile->ReadFloat(m_gracefrac_2); + savefile->ReadFloat(m_gracefrac_3); + savefile->ReadFloat(m_gracefrac_4); + savefile->ReadInt(m_gracecount_1); + savefile->ReadInt(m_gracecount_2); + savefile->ReadInt(m_gracecount_3); + savefile->ReadInt(m_gracecount_4); + + savefile->ReadFloat(atime1); + savefile->ReadFloat(atime2); + savefile->ReadFloat(atime3); + savefile->ReadFloat(atime4); + savefile->ReadFloat(atime_fleedone); + + savefile->ReadFloat(atime1_fuzzyness); + savefile->ReadFloat(atime2_fuzzyness); + savefile->ReadFloat(atime3_fuzzyness); + savefile->ReadFloat(atime4_fuzzyness); + savefile->ReadFloat(atime_fleedone_fuzzyness); + + savefile->ReadInt(m_timeBetweenHeadTurnChecks); + savefile->ReadFloat(m_headTurnChanceIdle); + savefile->ReadFloat(m_headTurnFactorAlerted); + savefile->ReadFloat(m_headTurnMaxYaw); + savefile->ReadFloat(m_headTurnMaxPitch); + savefile->ReadInt(m_headTurnMinDuration); + savefile->ReadInt(m_headTurnMaxDuration); + + backboneStates.clear(); + savefile->ReadInt(num); + + for (int i = 0; i < num; ++i) + { + int state = 0; + savefile->ReadInt(state); + + std::pair result = backboneStates.insert( + BackboneStateMap::value_type(static_cast(state), idStr()) + ); + + savefile->ReadString(result.first->second); + } + + savefile->ReadInt(m_maxInterleaveThinkFrames); + savefile->ReadFloat(m_minInterleaveThinkDist); + savefile->ReadFloat(m_maxInterleaveThinkDist); + + savefile->ReadInt(m_lastThinkTime); + savefile->ReadInt(m_nextThinkFrame); + + savefile->ReadBool(m_bPushOffPlayer); + + savefile->ReadBool(m_bCanBeFlatFooted); + savefile->ReadBool(m_bFlatFooted); + savefile->ReadInt(m_FlatFootedTimer); + savefile->ReadInt(m_FlatFootedTime); + savefile->ReadInt(m_FlatFootParryNum); + savefile->ReadInt(m_FlatFootParryMax); + savefile->ReadInt(m_FlatFootParryTimer); + savefile->ReadInt(m_FlatFootParryTime); + savefile->ReadFloat(m_MeleeCounterAttChance); + savefile->ReadBool(m_bMeleePredictProximity); + + savefile->ReadBool(m_bCanOperateDoors); + savefile->ReadBool(m_HandlingDoor); + savefile->ReadBool(m_HandlingElevator); + savefile->ReadBool(m_RelightingLight); // grayman #2603 + savefile->ReadBool(m_ExaminingRope); // grayman #2872 + savefile->ReadBool(m_DroppingTorch); // grayman #2603 + savefile->ReadBool(m_RestoreMove); // grayman #2706 + savefile->ReadBool(m_LatchedSearch); // grayman #2603 + + // grayman #2603 + m_dousedLightsSeen.Clear(); + savefile->ReadInt( num ); + m_dousedLightsSeen.SetNum( num ); + for (int i = 0; i < num; i++) + { + m_dousedLightsSeen[i].Restore(savefile); + } + + int size; + savefile->ReadInt(size); + unlockableDoors.clear(); + for (int i = 0; i < size; i++) + { + CBinaryFrobMover* mover; + savefile->ReadObject( reinterpret_cast( mover ) ); + unlockableDoors.insert(mover); + } + + savefile->ReadInt(size); + tactileIgnoreEntities.clear(); + for (int i = 0; i < size; i++) + { + idEntity* tactEnt; + savefile->ReadObject(reinterpret_cast(tactEnt)); + tactileIgnoreEntities.insert(tactEnt); + } + + mind = ai::MindPtr(new ai::Mind(this)); + mind->Restore(savefile); + + // Allocate and install the subsystems + movementSubsystem = ai::MovementSubsystemPtr(new ai::MovementSubsystem(ai::SubsysMovement, this)); + senseSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysSenses, this)); + commSubsystem = ai::CommunicationSubsystemPtr(new ai::CommunicationSubsystem(ai::SubsysCommunication, this)); + actionSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysAction, this)); + + senseSubsystem->Restore(savefile); + movementSubsystem->Restore(savefile); + commSubsystem->Restore(savefile); + actionSubsystem->Restore(savefile); + + SetCombatModel(); + LinkCombat(); + + InitMuzzleFlash(); + + // Link the script variables back to the scriptobject + LinkScriptVariables(); + + if ( restorePhysics ) { + RestorePhysics( &physicsObj ); + } + + RESTORE_TIMER_HANDLE(aiThinkTimer, savefile); + RESTORE_TIMER_HANDLE(aiMindTimer, savefile); + RESTORE_TIMER_HANDLE(aiAnimationTimer, savefile); + RESTORE_TIMER_HANDLE(aiPushWithAFTimer, savefile); + RESTORE_TIMER_HANDLE(aiUpdateEnemyPositionTimer, savefile); + RESTORE_TIMER_HANDLE(aiScriptTimer, savefile); + RESTORE_TIMER_HANDLE(aiAnimMoveTimer, savefile); + RESTORE_TIMER_HANDLE(aiObstacleAvoidanceTimer, savefile); + RESTORE_TIMER_HANDLE(aiPhysicsTimer, savefile); + RESTORE_TIMER_HANDLE(aiGetMovePosTimer, savefile); + RESTORE_TIMER_HANDLE(aiPathToGoalTimer, savefile); + RESTORE_TIMER_HANDLE(aiGetFloorPosTimer, savefile); + RESTORE_TIMER_HANDLE(aiPointReachableAreaNumTimer, savefile); + RESTORE_TIMER_HANDLE(aiCanSeeTimer, savefile); +} + +ai::Subsystem* idAI::GetSubsystem(ai::SubsystemId id) +{ + switch (id) + { + case ai::SubsysSenses: + return senseSubsystem.get(); + case ai::SubsysMovement: + return movementSubsystem.get(); + case ai::SubsysCommunication: + return commSubsystem.get(); + case ai::SubsysAction: + return actionSubsystem.get(); + default: + gameLocal.Error("Request for unknown subsystem %d", static_cast(id)); + return NULL; + }; +} + +/* +===================== +idAI::Spawn +===================== +*/ +void idAI::Spawn( void ) +{ + const char *jointname; + const idKeyValue *kv; + idStr jointName; + idAngles jointScale; + jointHandle_t joint; + idVec3 local_dir; + bool talks; + + aiNode.AddToEnd(gameLocal.spawnedAI); + + // Allocate a new default mind + mind = ai::MindPtr(new ai::Mind(this)); + + // Allocate and install the subsystems + movementSubsystem = ai::MovementSubsystemPtr(new ai::MovementSubsystem(ai::SubsysMovement, this)); + senseSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysSenses, this)); + commSubsystem = ai::CommunicationSubsystemPtr(new ai::CommunicationSubsystem(ai::SubsysCommunication, this)); + actionSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysAction, this)); + + if ( !g_monsters.GetBool() ) { + PostEventMS( &EV_Remove, 0 ); + return; + } + + spawnArgs.GetInt( "team", "1", team ); + spawnArgs.GetInt( "rank", "0", rank ); + spawnArgs.GetInt( "fly_offset", "0", fly_offset ); + spawnArgs.GetFloat( "fly_speed", "100", fly_speed ); + spawnArgs.GetFloat( "fly_bob_strength", "50", fly_bob_strength ); + spawnArgs.GetFloat( "fly_bob_vert", "2", fly_bob_vert ); + spawnArgs.GetFloat( "fly_bob_horz", "2.7", fly_bob_horz ); + spawnArgs.GetFloat( "fly_seek_scale", "4", fly_seek_scale ); + spawnArgs.GetFloat( "fly_roll_scale", "90", fly_roll_scale ); + spawnArgs.GetFloat( "fly_roll_max", "60", fly_roll_max ); + spawnArgs.GetFloat( "fly_pitch_scale", "45", fly_pitch_scale ); + spawnArgs.GetFloat( "fly_pitch_max", "30", fly_pitch_max ); + + maxAreaReevaluationInterval = spawnArgs.GetInt( "max_area_reevaluation_interval", "2000"); + doorRetryTime = SEC2MS(spawnArgs.GetInt( "door_retry_time", "120")); + + spawnArgs.GetFloat( "fire_range", "0", fire_range ); + spawnArgs.GetFloat( "projectile_height_to_distance_ratio", "1", projectile_height_to_distance_ratio ); + + spawnArgs.GetFloat( "turn_rate", "360", turnRate ); + + spawnArgs.GetVector("sitting_turn_pivot", "-20 0 0", sitting_turn_pivot); + + reachedpos_bbox_expansion = spawnArgs.GetFloat("reachedpos_bbox_expansion", "0"); + aas_reachability_z_tolerance = spawnArgs.GetFloat("aas_reachability_z_tolerance", "75"); + + spawnArgs.GetBool( "talks", "0", talks ); + + //// DarkMod: Alert level parameters + // The default values of these spawnargs are normally set in tdm_ai_base.def, so the default values + // here are somewhat superfluous. It's better than having defaults of 0 here though. + spawnArgs.GetFloat( "alert_thresh1", "1.5", thresh_1 ); + spawnArgs.GetFloat( "alert_thresh2", "6", thresh_2 ); + spawnArgs.GetFloat( "alert_thresh3", "8", thresh_3 ); + spawnArgs.GetFloat( "alert_thresh4", "18", thresh_4 ); + spawnArgs.GetFloat( "alert_thresh5", "23", thresh_5 ); + // Grace period info for each alert level + spawnArgs.GetFloat( "alert_gracetime1", "2", m_gracetime_1 ); + spawnArgs.GetFloat( "alert_gracetime2", "2", m_gracetime_2 ); + spawnArgs.GetFloat( "alert_gracetime3", "3.5", m_gracetime_3 ); + spawnArgs.GetFloat( "alert_gracetime4", "2", m_gracetime_4 ); + spawnArgs.GetFloat( "alert_gracefrac1", "1.2", m_gracefrac_1 ); + spawnArgs.GetFloat( "alert_gracefrac2", "1.2", m_gracefrac_2 ); + spawnArgs.GetFloat( "alert_gracefrac3", "1.2", m_gracefrac_3 ); + spawnArgs.GetFloat( "alert_gracefrac4", "1.0", m_gracefrac_4 ); + spawnArgs.GetInt ( "alert_gracecount1", "5", m_gracecount_1 ); + spawnArgs.GetInt ( "alert_gracecount2", "5", m_gracecount_2 ); + spawnArgs.GetInt ( "alert_gracecount3", "5", m_gracecount_3 ); + spawnArgs.GetInt ( "alert_gracecount4", "4", m_gracecount_4 ); + // De-alert times for each alert level + spawnArgs.GetFloat( "alert_time1", "4", atime1 ); + spawnArgs.GetFloat( "alert_time2", "6", atime2 ); + spawnArgs.GetFloat( "alert_time3", "30", atime3 ); + spawnArgs.GetFloat( "alert_time4", "120", atime4 ); + spawnArgs.GetFloat( "alert_time1_fuzzyness", "4", atime1_fuzzyness ); + spawnArgs.GetFloat( "alert_time2_fuzzyness", "6", atime2_fuzzyness ); + spawnArgs.GetFloat( "alert_time3_fuzzyness", "30", atime3_fuzzyness ); + spawnArgs.GetFloat( "alert_time4_fuzzyness", "120", atime4_fuzzyness ); + + spawnArgs.GetFloat( "alert_time_fleedone", "60", atime_fleedone ); + spawnArgs.GetFloat( "alert_time_fleedone_fuzzyness", "10", atime_fleedone_fuzzyness ); + + // State setup + backboneStates.clear(); + + backboneStates[ai::ERelaxed] = spawnArgs.GetString("state_name_0", STATE_IDLE); + backboneStates[ai::EObservant] = spawnArgs.GetString("state_name_1", STATE_OBSERVANT); + backboneStates[ai::ESuspicious] = spawnArgs.GetString("state_name_2", STATE_SUSPICIOUS); + backboneStates[ai::EInvestigating] = spawnArgs.GetString("state_name_3", STATE_SEARCHING); + backboneStates[ai::EAgitatedSearching] = spawnArgs.GetString("state_name_4", STATE_AGITATED_SEARCHING); + backboneStates[ai::ECombat] = spawnArgs.GetString("state_name_5", STATE_COMBAT); + + spawnArgs.GetInt( "max_interleave_think_frames", "12", m_maxInterleaveThinkFrames ); + spawnArgs.GetFloat( "min_interleave_think_dist", "1000", m_minInterleaveThinkDist); + spawnArgs.GetFloat( "max_interleave_think_dist", "3000", m_maxInterleaveThinkDist); + + spawnArgs.GetBool( "ignore_alerts", "0", m_bIgnoreAlerts ); + + if (spawnArgs.GetBool("canOperateElevators", "0")) + { + travelFlags |= TFL_ELEVATOR; + } + + float headTurnSec; + spawnArgs.GetFloat( "headturn_delay_min", "3", headTurnSec); + m_timeBetweenHeadTurnChecks = SEC2MS(headTurnSec); + + spawnArgs.GetFloat( "headturn_chance_idle", "0.1", m_headTurnChanceIdle); + spawnArgs.GetFloat( "headturn_factor_alerted", "2", m_headTurnFactorAlerted); + spawnArgs.GetFloat( "headturn_yaw", "60", m_headTurnMaxYaw); + spawnArgs.GetFloat( "headturn_pitch", "40", m_headTurnMaxPitch); + + spawnArgs.GetFloat( "headturn_duration_min", "1", headTurnSec); + m_headTurnMinDuration = SEC2MS(headTurnSec); + + spawnArgs.GetFloat( "headturn_duration_max", "3", headTurnSec); + m_headTurnMaxDuration = SEC2MS(headTurnSec); + + alertTypeWeight[ai::EAlertTypeEnemy] = 50; + alertTypeWeight[ai::EAlertTypeDamage] = 45; + alertTypeWeight[ai::EAlertTypeDeadPerson] = 41; + alertTypeWeight[ai::EAlertTypeUnconsciousPerson] = 40; + alertTypeWeight[ai::EAlertTypeWeapon] = 35; + alertTypeWeight[ai::EAlertTypeRope] = 34; // grayman #2872 + alertTypeWeight[ai::EAlertTypeSuspiciousItem] = 33; // grayman #1327 + alertTypeWeight[ai::EAlertTypeBlood] = 30; + alertTypeWeight[ai::EAlertTypeBrokenItem] = 26; + alertTypeWeight[ai::EAlertTypeMissingItem] = 25; + alertTypeWeight[ai::EAlertTypeDoor] = 20; + alertTypeWeight[ai::EAlertTypeLightSource] = 10; + alertTypeWeight[ai::EAlertTypeSuspicious] = 5; + alertTypeWeight[ai::EAlertTypeNone] = 0; + + // DarkMod: Get the movement type audible volumes from the spawnargs + spawnArgs.GetFloat( "stepvol_walk", "0", m_stepvol_walk ); + spawnArgs.GetFloat( "stepvol_run", "0", m_stepvol_run ); + spawnArgs.GetFloat( "stepvol_creep", "0", m_stepvol_creep ); + + spawnArgs.GetFloat( "stepvol_crouch_walk", "0", m_stepvol_crouch_walk ); + spawnArgs.GetFloat( "stepvol_run", "0", m_stepvol_crouch_run ); + spawnArgs.GetFloat( "stepvol_creep", "0", m_stepvol_crouch_creep ); + + if ( spawnArgs.GetString( "npc_name", NULL ) != NULL ) { + if ( talks ) { + talk_state = TALK_OK; + } else { + talk_state = TALK_BUSY; + } + } else { + talk_state = TALK_NEVER; + } + + spawnArgs.GetBool( "animate_z", "0", disableGravity ); + spawnArgs.GetFloat( "kick_force", "60", kickForce ); // grayman #2568 - use default Doom 3 value + spawnArgs.GetBool( "ignore_obstacles", "0", ignore_obstacles ); + spawnArgs.GetFloat( "blockedRadius", "-1", blockedRadius ); + spawnArgs.GetInt( "blockedMoveTime", "750", blockedMoveTime ); + spawnArgs.GetInt( "blockedAttackTime", "750", blockedAttackTime ); + + // DarkMod: Set the AI acuities from the spawnargs. + + m_Acuities.Clear(); + for( int ind=0; ind < g_Global.m_AcuityNames.Num(); ind++) + { + float tempFloat = spawnArgs.GetFloat( va("acuity_%s", g_Global.m_AcuityNames[ind].c_str()), "100" ); + // angua: divide by 100 to transform percent into fractions + tempFloat *= 0.01f; + m_Acuities.Append( tempFloat ); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Acuities Array: index %d, name %s, value %f\r", ind, g_Global.m_AcuityNames[ind].c_str(), m_Acuities[ind]); + } + m_oldVisualAcuity = GetAcuity("vis"); // Tels fix #2408 + + spawnArgs.GetFloat("alert_aud_thresh", va("%f",gameLocal.m_sndProp->m_SndGlobals.DefaultThreshold), m_AudThreshold ); + + spawnArgs.GetInt( "num_cinematics", "0", num_cinematics ); + current_cinematic = 0; + + LinkScriptVariables(); + + /** + * Initialize Darkmod AI vars + **/ + AI_ALERTED = false; + AI_CROUCH = false; + AI_RUN = false; + AI_CREEP = false; + + AI_LAY_DOWN_LEFT = true; + + AI_HEARDSOUND = false; + AI_VISALERT = false; + AI_TACTALERT = false; + + fl.takedamage = !spawnArgs.GetBool( "noDamage" ); + enemy = NULL; + allowMove = true; + allowHiddenMovement = false; + + animator.RemoveOriginOffset( true ); + + // create combat collision hull for exact collision detection + SetCombatModel(); + + lookMin = spawnArgs.GetAngles( "look_min", "-80 -75 0" ); + lookMax = spawnArgs.GetAngles( "look_max", "80 75 0" ); + + lookJoints.SetGranularity( 1 ); + lookJointAngles.SetGranularity( 1 ); + kv = spawnArgs.MatchPrefix( "look_joint", NULL ); + while( kv ) { + jointName = kv->GetKey(); + jointName.StripLeadingOnce( "look_joint " ); + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) { + gameLocal.Warning( "Unknown look_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); + } else { + jointScale = spawnArgs.GetAngles( kv->GetKey(), "0 0 0" ); + jointScale.roll = 0.0f; + + // if no scale on any component, then don't bother adding it. this may be done to + // zero out rotation from an inherited entitydef. + if ( jointScale != ang_zero ) { + lookJoints.Append( joint ); + lookJointAngles.Append( jointScale ); + } + } + kv = spawnArgs.MatchPrefix( "look_joint", kv ); + } + + lookJointsCombat.SetGranularity( 1 ); + lookJointAnglesCombat.SetGranularity( 1 ); + kv = spawnArgs.MatchPrefix( "combat_look_joint", NULL ); + while( kv ) { + jointName = kv->GetKey(); + jointName.StripLeadingOnce( "combat_look_joint " ); + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) { + gameLocal.Warning( "Unknown combat_look_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); + } else { + jointScale = spawnArgs.GetAngles( kv->GetKey(), "0 0 0" ); + jointScale.roll = 0.0f; + + // if no scale on any component, then don't bother adding it. this may be done to + // zero out rotation from an inherited entitydef. + if ( jointScale != ang_zero ) { + lookJointsCombat.Append( joint ); + lookJointAnglesCombat.Append( jointScale ); + } + } + kv = spawnArgs.MatchPrefix( "combat_look_joint", kv ); + } + + // calculate joint positions on attack frames so we can do proper "can hit" tests + CalculateAttackOffsets(); + + eyeMin = spawnArgs.GetAngles( "eye_turn_min", "-10 -30 0" ); + eyeMax = spawnArgs.GetAngles( "eye_turn_max", "10 30 0" ); + eyeVerticalOffset = spawnArgs.GetFloat( "eye_verticle_offset", "5" ); + eyeHorizontalOffset = spawnArgs.GetFloat( "eye_horizontal_offset", "-8" ); + eyeFocusRate = spawnArgs.GetFloat( "eye_focus_rate", "0.5" ); + headFocusRate = spawnArgs.GetFloat( "head_focus_rate", "0.1" ); + focusAlignTime = SEC2MS( spawnArgs.GetFloat( "focus_align_time", "1" ) ); + + // DarkMod: State of mind, allow the FM author to set initial values + AI_AlertLevel = spawnArgs.GetFloat( "alert_initial", "0" ); + + flashJointWorld = animator.GetJointHandle( "flash" ); + + if ( head.GetEntity() ) + { + idAnimator *headAnimator = head.GetEntity()->GetAnimator(); + + jointname = spawnArgs.GetString( "bone_focus" ); + if ( *jointname ) + { + focusJoint = headAnimator->GetJointHandle( jointname ); + if ( focusJoint == INVALID_JOINT ) + { + gameLocal.Warning( "Joint '%s' not found on head on '%s'", jointname, name.c_str() ); + } + } + } else + { + jointname = spawnArgs.GetString( "bone_focus" ); + if ( *jointname ) + { + focusJoint = animator.GetJointHandle( jointname ); + if ( focusJoint == INVALID_JOINT ) + { + gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + } + } + } + + jointname = spawnArgs.GetString( "bone_orientation" ); + if ( *jointname ) { + orientationJoint = animator.GetJointHandle( jointname ); + if ( orientationJoint == INVALID_JOINT ) { + gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + } + } + + jointname = spawnArgs.GetString( "bone_flytilt" ); + if ( *jointname ) { + flyTiltJoint = animator.GetJointHandle( jointname ); + if ( flyTiltJoint == INVALID_JOINT ) { + gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + } + } + + InitMuzzleFlash(); + + physicsObj.SetSelf( this ); + physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); + + physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) ); + kickForce = 2*physicsObj.GetMass(); // grayman #2568 - equation arrived at empirically + + physicsObj.SetStepUpIncrease(spawnArgs.GetFloat("step_up_increase", "0")); + + if ( spawnArgs.GetBool( "big_monster" ) ) { + physicsObj.SetContents( 0 ); + physicsObj.SetClipMask( MASK_MONSTERSOLID & ~CONTENTS_BODY ); + } else { + if ( use_combat_bbox ) { + physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); + } else { + physicsObj.SetContents( CONTENTS_BODY ); + } + physicsObj.SetClipMask( MASK_MONSTERSOLID ); + } + +// SR CONTENTS_RESPONSE fix: + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + // move up to make sure the monster is at least an epsilon above the floor + physicsObj.SetOrigin( GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); + + if ( num_cinematics ) { + physicsObj.SetGravity( vec3_origin ); + } else { + idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); + gravity *= g_gravity.GetFloat(); + physicsObj.SetGravity( gravity ); + } + + SetPhysics( &physicsObj ); + + physicsObj.GetGravityAxis().ProjectVector( viewAxis[ 0 ], local_dir ); + current_yaw = local_dir.ToYaw(); + ideal_yaw = idMath::AngleNormalize180( current_yaw ); + + move.blockTime = 0; + + SetAAS(); + + InitProjectileInfo(); + + delayedStims.Clear(); // grayman #2603 + + particles.Clear(); + restartParticles = true; + useBoneAxis = spawnArgs.GetBool( "useBoneAxis" ); + SpawnParticles( "smokeParticleSystem" ); + + if ( num_cinematics || spawnArgs.GetBool( "hide" ) || spawnArgs.GetBool( "teleport" ) || spawnArgs.GetBool( "trigger_anim" ) ) { + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.GetClipModel()->Unlink(); + Hide(); + } else { + // play a looping ambient sound if we have one + StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); + } + + if ( health <= 0 ) { + gameLocal.Warning( "entity '%s' doesn't have health set", name.c_str() ); + health = 1; + } + + // Dark Mod: set up drowning + m_MouthOffset = spawnArgs.GetVector("mouth_offset"); + // set up drowning timer (add a random bit to make it asynchronous w/ respect to other AI) + m_bCanDrown = spawnArgs.GetBool( "can_drown", "1" ); + m_AirCheckTimer = gameLocal.time + gameLocal.random.RandomInt( 8000 ); + m_AirTicksMax = spawnArgs.GetInt( "max_air_tics", "5" ); + m_AirTics = m_AirTicksMax; + m_AirCheckInterval = static_cast(1000.0f * spawnArgs.GetFloat( "air_check_interval", "4.0" )); + // end drowning setup + + m_bPushOffPlayer = spawnArgs.GetBool("push_off_player", "1"); + + m_bCanBeFlatFooted = spawnArgs.GetBool("can_be_flatfooted", "1"); + m_FlatFootedTime = spawnArgs.GetInt("flatfooted_time"); + m_FlatFootParryMax = spawnArgs.GetInt("flatfoot_parry_num"); + m_FlatFootParryTime = spawnArgs.GetInt("flatfoot_parry_time"); + // Convert percent chance to fractional + m_MeleeCounterAttChance = spawnArgs.GetInt("melee_chance_to_counter") / 100.0f; + m_bMeleePredictProximity = spawnArgs.GetBool("melee_predicts_proximity"); + + if (spawnArgs.GetBool("melee_attacks_enabled_at_spawn_time", "0")) + { + SetAttackFlag(COMBAT_MELEE, true); + } + + if (spawnArgs.GetBool("ranged_attacks_enabled_at_spawn_time", "0")) + { + SetAttackFlag(COMBAT_RANGED, true); + } + + m_bCanOperateDoors = spawnArgs.GetBool("canOperateDoors", "0"); + m_HandlingDoor = false; + m_RestoreMove = false; // grayman #2706 + m_LatchedSearch = false; // grayman #2603 + m_dousedLightsSeen.Clear(); // grayman #2603 + + m_HandlingElevator = false; + m_RelightingLight = false; // grayman #2603 + m_ExaminingRope = false; // grayman #2872 + m_DroppingTorch = false; // grayman #2603 + + // =============== Set up KOing and FOV ============== + const char *HeadJointName = spawnArgs.GetString("head_jointname", "Head"); + + m_HeadJointID = animator.GetJointHandle(HeadJointName); + if( m_HeadJointID == INVALID_JOINT ) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Invalid head joint for joint %s on AI %s \r", HeadJointName, name.c_str()); + m_HeadBodyID = 0; + } + else + { + m_HeadBodyID = BodyForJoint(m_HeadJointID); + } + + if( head.GetEntity() ) + { + CopyHeadKOInfo(); + } + + ParseKnockoutInfo(); + + // ================== End KO setup ==================== + + // Sneak attack setup + const char *tempc1; + tempc1 = spawnArgs.GetString("sneak_attack_alert_state"); + m_SneakAttackThresh = spawnArgs.GetFloat( va("alert_thresh%s", tempc1), va("%f",idMath::INFINITY) ); + m_SneakAttackMult = spawnArgs.GetFloat( "sneak_attack_mult", "1.0" ); + + BecomeActive( TH_THINK ); + + // init the move variables + StopMove( MOVE_STATUS_DONE ); + + // Schedule a post-spawn event to parse the rest of the spawnargs + PostEventMS( &EV_PostSpawn, 1 ); + + m_lastThinkTime = gameLocal.time; + + CREATE_TIMER(aiThinkTimer, name, "Think"); + CREATE_TIMER(aiMindTimer, name, "Mind"); + CREATE_TIMER(aiAnimationTimer, name, "Animation"); + CREATE_TIMER(aiPushWithAFTimer, name, "PushWithAF"); + CREATE_TIMER(aiUpdateEnemyPositionTimer, name, "UpdateEnemyPosition"); + CREATE_TIMER(aiScriptTimer, name, "UpdateScript"); + CREATE_TIMER(aiAnimMoveTimer, name, "AnimMove"); + CREATE_TIMER(aiObstacleAvoidanceTimer, name, "ObstacleAvoidance"); + CREATE_TIMER(aiPhysicsTimer, name, "RunPhysics"); + CREATE_TIMER(aiGetMovePosTimer, name, "GetMovePos"); + CREATE_TIMER(aiPathToGoalTimer, name, "PathToGoal"); + CREATE_TIMER(aiGetFloorPosTimer, name, "GetFloorPos"); + CREATE_TIMER(aiPointReachableAreaNumTimer, name, "PointReachableAreaNum"); + CREATE_TIMER(aiCanSeeTimer, name, "CanSee"); + + m_pathRank = rank; // grayman #2345 - rank for path-finding + + m_bCanBeGassed = !(spawnArgs.GetBool( "gas_immune", "0" )); // grayman #2468 +} + +void idAI::InitProjectileInfo() +{ + activeProjectile.projEnt = NULL; + + // greebo: Pre-cache the properties of each projectile def. + for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_projectile"); kv != NULL; kv = spawnArgs.MatchPrefix("def_projectile", kv)) + { + const idStr& projectileName = kv->GetValue(); + + if (projectileName.Length() == 0) continue; + + ProjectileInfo& info = projectileInfo.Alloc(); + + // Pass to specialised routine + InitProjectileInfoFromDict(info, projectileName); + } + + // Roll a random projectile for starters + curProjectileIndex = gameLocal.random.RandomInt(projectileInfo.Num()); +} + +void idAI::InitProjectileInfoFromDict(idAI::ProjectileInfo& info, const char* entityDef) const +{ + const idDict* dict = gameLocal.FindEntityDefDict(entityDef); + + if (dict == NULL) + { + gameLocal.Error("Cannot load projectile info for entityDef %s", entityDef); + } + + InitProjectileInfoFromDict(info, dict); +} + +void idAI::InitProjectileInfoFromDict(idAI::ProjectileInfo& info, const idDict* dict) const +{ + assert(dict != NULL); + + info.defName = dict->GetString("classname"); + info.def = dict; + + // Create a projectile of this specific type to retrieve its properties + idProjectile* proj = SpawnProjectile(info.def); + + info.radius = proj->GetPhysics()->GetClipModel()->GetBounds().GetRadius(); + info.velocity = idProjectile::GetVelocity(info.def); + info.gravity = idProjectile::GetGravity(info.def); + info.speed = info.velocity.Length(); + + // dispose after this short use + delete proj; +} + +/* +=================== +idAI::InitMuzzleFlash +=================== +*/ +void idAI::InitMuzzleFlash( void ) { + const char *shader; + idVec3 flashColor; + + spawnArgs.GetString( "mtr_flashShader", "muzzleflash", &shader ); + spawnArgs.GetVector( "flashColor", "0 0 0", flashColor ); + float flashRadius = spawnArgs.GetFloat( "flashRadius" ); + flashTime = SEC2MS( spawnArgs.GetFloat( "flashTime", "0.25" ) ); + + memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); + + worldMuzzleFlash.pointLight = true; + worldMuzzleFlash.shader = declManager->FindMaterial( shader, false ); + worldMuzzleFlash.shaderParms[ SHADERPARM_RED ] = flashColor[0]; + worldMuzzleFlash.shaderParms[ SHADERPARM_GREEN ] = flashColor[1]; + worldMuzzleFlash.shaderParms[ SHADERPARM_BLUE ] = flashColor[2]; + worldMuzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = 1.0f; + worldMuzzleFlash.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; + worldMuzzleFlash.lightRadius[0] = flashRadius; + worldMuzzleFlash.lightRadius[1] = flashRadius; + worldMuzzleFlash.lightRadius[2] = flashRadius; + + worldMuzzleFlashHandle = -1; +} + +/* +=================== +idAI::List_f +=================== +*/ +void idAI::List_f( const idCmdArgs &args ) { + int e; + idAI *check; + int count; + const char *statename; + + count = 0; + + gameLocal.Printf( "%-4s %-20s %s\n", " Num", "EntityDef", "Name" ); + gameLocal.Printf( "------------------------------------------------\n" ); + for( e = 0; e < MAX_GENTITIES; e++ ) { + check = static_cast(gameLocal.entities[ e ]); + if ( !check || !check->IsType( idAI::Type ) ) { + continue; + } + + if ( check->state ) { + statename = check->state->Name(); + } else { + statename = "NULL state"; + } + + gameLocal.Printf( "%4i: %-20s %-20s %s move: %d\n", e, check->GetEntityDefName(), check->name.c_str(), statename, check->allowMove ); + count++; + } + + gameLocal.Printf( "...%d monsters\n", count ); +} + +/* +================ +idAI::DormantBegin + +called when entity becomes dormant +================ +*/ +void idAI::DormantBegin( void ) { + // since dormant happens on a timer, we wont get to update particles to + // hidden through the think loop, but we need to hide them though. + if ( particles.Num() ) { + for ( int i = 0; i < particles.Num(); i++ ) { + particles[i].time = 0; + } + } + + if ( enemyNode.InList() ) { + // remove ourselves from the enemy's enemylist + enemyNode.Remove(); + } + idActor::DormantBegin(); +} + +/* +================ +idAI::DormantEnd + +called when entity wakes from being dormant +================ +*/ +void idAI::DormantEnd( void ) { + if ( enemy.GetEntity() && !enemyNode.InList() ) { + // let our enemy know we're back on the trail + enemyNode.AddToEnd( enemy.GetEntity()->enemyList ); + } + + if ( particles.Num() ) { + for ( int i = 0; i < particles.Num(); i++ ) { + particles[i].time = gameLocal.time; + } + } + + idActor::DormantEnd(); + m_lastThinkTime = gameLocal.time; +} + +/* +===================== +idAI::Think +===================== +*/ +void idAI::Think( void ) +{ + START_SCOPED_TIMING(aiThinkTimer, scopedThinkTimer); + if (cv_ai_opt_nothink.GetBool()) + { + return; // Thinking is disabled. + } + + // Interleaved thinking + if (!ThinkingIsAllowed()) + { + return; + } + + SetNextThinkFrame(); + + // if we are completely closed off from the player, don't do anything at all + // angua: only go dormant while in idle + // grayman #2536 - move alert check up in front + if (AI_AlertIndex < 1) + { + bool outsidePVS = CheckDormant(); + if (outsidePVS && cv_ai_opt_disable.GetBool()) + { + return; + } + } + + // grayman #2536 - if dormant and alert index > 0, wake up + + if ((AI_AlertIndex > 0) && fl.isDormant) + { + dormantStart = 0; + fl.hasAwakened = true; + fl.isDormant = false; + DormantEnd(); + } + + // save old origin and velocity for crashlanding + idVec3 oldOrigin = physicsObj.GetOrigin(); + idVec3 oldVelocity = physicsObj.GetLinearVelocity(); + + if (thinkFlags & TH_THINK) + { + // clear out the enemy when he dies + idActor* enemyEnt = enemy.GetEntity(); + if (enemyEnt != NULL) + { + if (enemyEnt->health <= 0) + { + EnemyDead(); + } + } + + // Calculate the new view axis based on the turning settings + current_yaw += deltaViewAngles.yaw; + ideal_yaw = idMath::AngleNormalize180(ideal_yaw + deltaViewAngles.yaw); + deltaViewAngles.Zero(); + viewAxis = idAngles(0, current_yaw, 0).ToMat3(); + + // TDM: Fake lipsync + if (m_lipSyncActive && !cv_ai_opt_nolipsync.GetBool() && GetSoundEmitter()) + { + if (gameLocal.time < m_lipSyncEndTimer && head.GetEntity() != NULL) + { + // greebo: Get the number of frames from the head animator + int numFrames = head.GetEntity()->GetAnimator()->NumFrames(m_lipSyncAnim); + + int frame = static_cast(numFrames * idMath::Sqrt16(GetSoundEmitter()->CurrentAmplitude())); + frame = idMath::ClampInt(0, numFrames, frame); + headAnim.SetFrame(m_lipSyncAnim, frame); + } + else + { + // We're done; stop the animation + StopLipSync(); + } + } + + // Check for tactile alert due to AI movement + CheckTactile(); + + if (health > 0) // grayman #1488 - only do this if you're still alive + { + UpdateAir(); // Check air ticks (is interleaved and not checked each frame) + } + + if (num_cinematics > 0) + { + // Active cinematics + if ( !IsHidden() && torsoAnim.AnimDone( 0 ) ) { + PlayCinematic(); + } + RunPhysics(); + } + else if (!allowHiddenMovement && IsHidden()) + { + // hidden monsters + UpdateScript(); + } + else + { + // clear the ik before we do anything else so the skeleton doesn't get updated twice + walkIK.ClearJointMods(); + + // Update moves, depending on move type + switch (move.moveType) + { + case MOVETYPE_DEAD : + // dead monsters + UpdateScript(); + DeadMove(); + break; + + case MOVETYPE_FLY : + // flying monsters + UpdateEnemyPosition(); + UpdateScript(); + FlyMove(); + CheckBlink(); + break; + + case MOVETYPE_STATIC : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + StaticMove(); + CheckBlink(); + break; + + case MOVETYPE_ANIM : + // animation based movement + UpdateEnemyPosition(); + UpdateScript(); + if (!cv_ai_opt_noanims.GetBool()) + { + AnimMove(); + } + CheckBlink(); + break; + + case MOVETYPE_SLIDE : + // velocity based movement + UpdateEnemyPosition(); + UpdateScript(); + SlideMove(); + CheckBlink(); + break; + + case MOVETYPE_SIT : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving not allowed, turning around sitting pivot + SittingMove(); + CheckBlink(); + break; + + case MOVETYPE_SIT_DOWN : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving and turning not allowed + NoTurnMove(); + CheckBlink(); + break; + + case MOVETYPE_SLEEP : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving and turning not allowed + NoTurnMove(); + break; + + case MOVETYPE_LAY_DOWN : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving and turning not allowed + LayDownMove(); + break; + + case MOVETYPE_GET_UP : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving not allowed + SittingMove(); + CheckBlink(); + break; + + case MOVETYPE_GET_UP_FROM_LYING : + // static monsters + UpdateEnemyPosition(); + UpdateScript(); + // moving and turning not allowed + LayDownMove(); + break; + + + default: + break; + } + } + + if (!cv_ai_opt_nomind.GetBool()) + { + // greebo: We always rely on having a mind + assert(mind); + START_SCOPED_TIMING(aiMindTimer, scopedMindTimer); + + // Let the mind do the thinking (after the move updates) + mind->Think(); + } + + // Clear DarkMod per frame vars now that the mind had time to think + AI_ALERTED = false; + m_AlertLevelThisFrame = 0; + m_AlertedByActor = NULL; + m_tactileEntity = NULL; // grayman #2345 + + // clear pain flag so that we receive any damage between now and the next time we run the script + AI_PAIN = false; + AI_SPECIAL_DAMAGE = 0; + AI_PUSHED = false; + } + else if (thinkFlags & TH_PHYSICS) + { + // Thinking not allowed, but physics are still enabled + RunPhysics(); + } + + if (m_bAFPushMoveables && !movementSubsystem->IsWaitingNonSolid()) // grayman #2345 - if you're waiting for someone to go by, you're non-solid, so you can't push anything + { + START_SCOPED_TIMING(aiPushWithAFTimer, scopedPushWithAFTimer) + PushWithAF(); + } + + if (fl.hidden && allowHiddenMovement) + { + // UpdateAnimation won't call frame commands when hidden, so call them here when we allow hidden movement + animator.ServiceAnims( gameLocal.previousTime, gameLocal.time ); + } + + UpdateMuzzleFlash(); + if (!cv_ai_opt_noanims.GetBool()) + { + START_SCOPED_TIMING(aiAnimationTimer, scopedAnimationTimer) + UpdateAnimation(); + } + UpdateParticles(); + if (!cv_ai_opt_nopresent.GetBool()) + { + Present(); + } + UpdateDamageEffects(); + LinkCombat(); + + if (health > 0) + { + idActor::CrashLand( physicsObj, oldOrigin, oldVelocity ); + } + + m_lastThinkTime = gameLocal.time; + + // Check the CVARs and print debug info, if appropriate + ShowDebugInfo(); +} + +/* +===================== +idAI::ThinkingIsAllowed +===================== +*/ +bool idAI::ThinkingIsAllowed() +{ + int frameNum = gameLocal.framenum; + if (frameNum < m_nextThinkFrame) + { + // Ragdolls think every frame to avoid physics weirdness. + if ( ( health <= 0 ) || IsKnockedOut() ) // grayman #2840 - you're also a ragdoll if you're KO'ed + { + return true; + } + + // angua: AI think every frame while sitting/laying down and getting up + // otherwise, the AI might end up in a different sleeping position + if (move.moveType == MOVETYPE_SIT_DOWN + || move.moveType == MOVETYPE_LAY_DOWN + || move.moveType == MOVETYPE_GET_UP + || move.moveType == MOVETYPE_GET_UP_FROM_LYING) + { + return true; + } + + // skips PVS check, AI will also do interleaved thinking when in player view. + bool skipPVScheck = cv_ai_opt_interleavethinkskippvscheck.GetBool(); + if (skipPVScheck) + { + return false; + } + + // PVS check: let the AI think every frame as long as the player sees them. + bool inPVS = gameLocal.InPlayerPVS(this); + if (!inPVS) + { + return false; + } + } + return true; +} + + + +/* +===================== +idAI::SetNextThinkFrame +===================== +*/ +void idAI::SetNextThinkFrame() +{ + int frameNum = gameLocal.framenum; + int thinkFrame = GetThinkInterleave(); + int thinkDelta = 1; + + if (thinkFrame > 1) + { + // Let them think for the first few frames to initialize state and tasks + if (m_earlyThinkCounter <= 0) // grayman #2654 - keep a separate counter + { + // grayman #2414 - think more often if + // + // * working on a door-handling task + // * nearing a goal position + // * handling an elevator + // + // and, for #2345 + // + // * when resolving a block + + bool thinkMore = false; + thinkDelta = thinkFrame; + ai::Memory& memory = GetMemory(); + CFrobDoor *door = memory.doorRelated.currentDoor.GetEntity(); + + if (door) + { + idVec3 origin = GetPhysics()->GetOrigin(); + idVec3 doorOrigin = door->GetPhysics()->GetOrigin(); + float distance = (doorOrigin - origin).LengthFast(); + + if (distance <= TEMP_THINK_DISTANCE) + { + thinkMore = true; // avoid obstruction & damage + } + } + else if (m_HandlingElevator) + { + thinkMore = true; // avoid death + } + else if ((move.moveCommand == MOVE_TO_POSITION) && (move.moveStatus == MOVE_STATUS_MOVING)) + { + idVec3 origin = GetPhysics()->GetOrigin(); + float distance = (move.moveDest - origin).LengthFast(); + + if (distance <= TEMP_THINK_FACTOR*thinkFrame) + { + thinkMore = true; // avoid confusion and becoming stuck + } + } + else if (!movementSubsystem->IsWaiting() && !movementSubsystem->IsNotBlocked()) + { + thinkMore = true; // avoid chaos + } + + if (thinkMore) + { + thinkDelta = (thinkFrame < TEMP_THINK_INTERLEAVE ? thinkFrame : TEMP_THINK_INTERLEAVE); + } + } + else + { + m_earlyThinkCounter--; // grayman #2654 + } + } + + m_nextThinkFrame = frameNum + thinkDelta; +} + +/* +===================== +idAI::GetThinkInterleave +===================== +*/ +int idAI::GetThinkInterleave() const // grayman 2414 - add 'const' +{ + int maxFrames = m_maxInterleaveThinkFrames; + if (cv_ai_opt_interleavethinkframes.GetInteger() > 0) + { + maxFrames = cv_ai_opt_interleavethinkframes.GetInteger(); + } + + if (maxFrames == 0) + { + return 0; + } + + float minDist = m_minInterleaveThinkDist; + float maxDist = m_maxInterleaveThinkDist; + if (cv_ai_opt_interleavethinkmindist.GetFloat() > 0) + { + minDist = cv_ai_opt_interleavethinkmindist.GetFloat(); + } + if (cv_ai_opt_interleavethinkmaxdist.GetFloat() > 0) + { + maxDist = cv_ai_opt_interleavethinkmaxdist.GetFloat(); + } + + if (maxDist < minDist) + { + gameLocal.Warning("Minimum distance for interleaved thinking is larger than maximum distance, switching optimization off."); + return 0; + } + + float playerDist = (physicsObj.GetOrigin() - gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin()).LengthFast(); + if (playerDist < minDist) + { + return 0; + } + else if (playerDist > maxDist) + { + return maxFrames; + } + else + { + float fraction = (playerDist - minDist) / (maxDist - minDist); + int thinkFrames = 1 + static_cast(fraction * maxFrames); + return thinkFrames; + } +} + +/*********************************************************************** + + AI script state management + +***********************************************************************/ + +/* +===================== +idAI::LinkScriptVariables +===================== +*/ +void idAI::LinkScriptVariables( void ) +{ + // Call the base class first + idActor::LinkScriptVariables(); + + AI_TALK.LinkTo( scriptObject, "AI_TALK" ); + AI_DAMAGE.LinkTo( scriptObject, "AI_DAMAGE" ); + AI_PAIN.LinkTo( scriptObject, "AI_PAIN" ); + AI_SPECIAL_DAMAGE.LinkTo( scriptObject, "AI_SPECIAL_DAMAGE" ); + AI_KNOCKEDOUT.LinkTo( scriptObject, "AI_KNOCKEDOUT" ); + AI_ENEMY_VISIBLE.LinkTo( scriptObject, "AI_ENEMY_VISIBLE" ); + AI_ENEMY_IN_FOV.LinkTo( scriptObject, "AI_ENEMY_IN_FOV" ); + AI_MOVE_DONE.LinkTo( scriptObject, "AI_MOVE_DONE" ); + AI_ONGROUND.LinkTo( scriptObject, "AI_ONGROUND" ); + AI_ACTIVATED.LinkTo( scriptObject, "AI_ACTIVATED" ); + AI_FORWARD.LinkTo( scriptObject, "AI_FORWARD" ); + AI_JUMP.LinkTo( scriptObject, "AI_JUMP" ); + AI_BLOCKED.LinkTo( scriptObject, "AI_BLOCKED" ); + AI_DEST_UNREACHABLE.LinkTo( scriptObject, "AI_DEST_UNREACHABLE" ); + AI_HIT_ENEMY.LinkTo( scriptObject, "AI_HIT_ENEMY" ); + AI_OBSTACLE_IN_PATH.LinkTo( scriptObject, "AI_OBSTACLE_IN_PATH" ); + AI_PUSHED.LinkTo( scriptObject, "AI_PUSHED" ); + + //this is only set in a given frame + AI_ALERTED.LinkTo( scriptObject, "AI_ALERTED" ); + + AI_AlertLevel.LinkTo( scriptObject, "AI_AlertLevel" ); + AI_AlertIndex.LinkTo( scriptObject, "AI_AlertIndex" ); + + //these are set until unset by the script + AI_HEARDSOUND.LinkTo( scriptObject, "AI_HEARDSOUND"); + AI_VISALERT.LinkTo( scriptObject, "AI_VISALERT"); + AI_TACTALERT.LinkTo( scriptObject, "AI_TACTALERT"); + + AI_CROUCH.LinkTo( scriptObject, "AI_CROUCH"); + AI_RUN.LinkTo( scriptObject, "AI_RUN"); + AI_CREEP.LinkTo( scriptObject, "AI_CREEP"); + + AI_LAY_DOWN_LEFT.LinkTo( scriptObject, "AI_LAY_DOWN_LEFT"); + AI_LAY_DOWN_FACE_DIR.LinkTo(scriptObject, "AI_LAY_DOWN_FACE_DIR"); + + AI_SIT_DOWN_ANGLE.LinkTo(scriptObject, "AI_SIT_DOWN_ANGLE"); + AI_SIT_UP_ANGLE.LinkTo(scriptObject, "AI_SIT_UP_ANGLE"); + + +} + +/* +===================== +idAI::UpdateAIScript +===================== +*/ +void idAI::UpdateScript() +{ + START_SCOPED_TIMING(aiScriptTimer, scopedScriptTimer); + + // greebo: This is overriding idActor::UpdateScript(), where all the state change stuff + // is executed, which is not needed for TDM AI + + if ( ai_debugScript.GetInteger() == entityNumber ) { + scriptThread->EnableDebugInfo(); + } else { + scriptThread->DisableDebugInfo(); + } + + // don't call script until it's done waiting + if (!scriptThread->IsWaiting()) { + scriptThread->Execute(); + } + + // clear the hit enemy flag so we catch the next time we hit someone + AI_HIT_ENEMY = false; + + if ( allowHiddenMovement || !IsHidden() ) { + // update the animstate if we're not hidden + if (!cv_ai_opt_noanims.GetBool()) + { + UpdateAnimState(); + } + } +} + +/*********************************************************************** + + navigation + +***********************************************************************/ + +/* +============ +idAI::KickObstacles +============ +*/ +void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) { + int i, numListedClipModels; + idBounds clipBounds; + idEntity *obEnt; + idClipModel *clipModel; + idClipModel *clipModelList[ MAX_GENTITIES ]; + int clipmask; + idVec3 org; + idVec3 forceVec; + idVec3 delta; + idVec2 perpendicular; + + org = physicsObj.GetOrigin(); + + // find all possible obstacles + clipBounds = physicsObj.GetAbsBounds(); + clipBounds.TranslateSelf( dir * (clipBounds[1].x - clipBounds[0].x + clipBounds[1].y - clipBounds[0].y)/2); // grayman #2667 +// clipBounds.TranslateSelf( dir * 32.0f ); // grayman #2667 - old way assumed a humanoid + clipBounds.ExpandSelf( 8.0f ); + clipBounds.AddPoint( org ); + clipmask = physicsObj.GetClipMask(); + numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds( clipBounds, clipmask, clipModelList, MAX_GENTITIES ); + for ( i = 0; i < numListedClipModels; i++ ) { + clipModel = clipModelList[i]; + obEnt = clipModel->GetEntity(); + if ( obEnt == alwaysKick ) { + // we'll kick this one outside the loop + continue; + } + + if ( !clipModel->IsTraceModel() ) { + continue; + } + + if ( obEnt->IsType( idMoveable::Type ) && obEnt->GetPhysics()->IsPushable() ) + { + delta = obEnt->GetPhysics()->GetOrigin() - org; + delta.NormalizeFast(); + perpendicular.x = -delta.y; + perpendicular.y = delta.x; + delta.z += 0.5f; + delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; + forceVec = delta * force; // grayman #2568 - remove obEnt->mass from the equation +// forceVec = delta * force * obEnt->GetPhysics()->GetMass(); // grayman #2568 - old way + obEnt->ApplyImpulse( this, 0, obEnt->GetPhysics()->GetOrigin(), forceVec ); + if (obEnt->m_SetInMotionByActor.GetEntity() == NULL) + { + obEnt->m_SetInMotionByActor = this; + obEnt->m_MovedByActor = this; + } + } + } + + if ( alwaysKick ) + { + delta = alwaysKick->GetPhysics()->GetOrigin() - org; + delta.NormalizeFast(); + perpendicular.x = -delta.y; + perpendicular.y = delta.x; + delta.z += 0.5f; + delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; + forceVec = delta * force; // grayman #2568 - remove obEnt->mass from the equation +// forceVec = delta * force * alwaysKick->GetPhysics()->GetMass(); // grayman #2568 - old way + alwaysKick->ApplyImpulse( this, 0, alwaysKick->GetPhysics()->GetOrigin(), forceVec ); + if (alwaysKick->m_SetInMotionByActor.GetEntity() == NULL) + { + alwaysKick->m_SetInMotionByActor = this; + alwaysKick->m_MovedByActor = this; + } + } +} + +bool idAI::ReEvaluateArea(int areaNum) +{ + // Remember the time + lastAreaReevaluationTime = gameLocal.time; + + // Let's see if we have a valid door info structure in our memory + ai::DoorInfoPtr doorInfo = GetMemory().GetDoorInfo(areaNum); + + if (doorInfo != NULL) + { + //if (doorInfo->lastTimeTriedToOpen + doorRetryTime < gameLocal.time) + { + // Re-try the door after some time + gameLocal.m_AreaManager.RemoveForbiddenArea(areaNum, this); + return true; + } + } + + return false; +} + +/* +============ +ValidForBounds +============ +*/ +bool ValidForBounds( const idAASSettings *settings, const idBounds &bounds ) { + int i; + + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] < settings->boundingBoxes[0][0][i] ) { + return false; + } + if ( bounds[1][i] > settings->boundingBoxes[0][1][i] ) { + return false; + } + } + return true; +} + +/* +===================== +idAI::SetAAS +===================== +*/ +void idAI::SetAAS( void ) { + idStr use_aas; + + spawnArgs.GetString( "use_aas", NULL, use_aas ); + aas = gameLocal.GetAAS( use_aas ); + if ( aas ) { + const idAASSettings *settings = aas->GetSettings(); + if ( settings ) { + if ( !ValidForBounds( settings, physicsObj.GetBounds() ) ) { + gameLocal.Error( "%s cannot use use_aas %s\n", name.c_str(), use_aas.c_str() ); + } + float height = settings->maxStepHeight; + physicsObj.SetMaxStepHeight( height ); + return; + } else { + aas = NULL; + } + } + gameLocal.Printf( "WARNING: %s has no AAS file\n", name.c_str() ); +} + +/* +===================== +idAI::DrawRoute +===================== +*/ +void idAI::DrawRoute( void ) const { + if ( aas && move.toAreaNum && move.moveCommand != MOVE_NONE && move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_FACE_ENEMY && move.moveCommand != MOVE_FACE_ENTITY && move.moveCommand != MOVE_TO_POSITION_DIRECT && move.moveCommand != MOVE_VECTOR ) + { + if ( move.moveType == MOVETYPE_FLY ) { + aas->ShowFlyPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); + } else { + aas->ShowWalkPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); + } + } +} + +/* +===================== +idAI::ReachedPos +===================== +*/ +bool idAI::ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand) const { + if ( move.moveType == MOVETYPE_SLIDE ) { + idBounds bnds( idVec3( -4, -4.0f, -8.0f ), idVec3( 4.0f, 4.0f, 64.0f ) ); + bnds.TranslateSelf( physicsObj.GetOrigin() ); + if ( bnds.ContainsPoint( pos ) ) { + return true; + } + } else { + if ( ( moveCommand == MOVE_TO_ENEMY ) || ( moveCommand == MOVE_TO_ENTITY ) ) + { + if ( physicsObj.GetAbsBounds().IntersectsBounds( idBounds( pos ).Expand( 8.0f ) ) ) { + return true; + } + } + else + { + // Use the AI bounding box check to see if we've reached the position + return ReachedPosAABBCheck(pos); + } + } + return false; +} + +bool idAI::ReachedPosAABBCheck(const idVec3& pos) const +{ + // angua: use AI bounds for checking + idBounds bnds(physicsObj.GetBounds()); + if (move.accuracy >= 0) + { + // if accuracy is set, replace x and y size of the bounds + bnds[0][0] = -move.accuracy; + bnds[0][1] = -move.accuracy; + bnds[1][0] = move.accuracy; + bnds[1][1] = move.accuracy; + } + + bnds.TranslateSelf(physicsObj.GetOrigin()); + + bnds.ExpandSelf(reachedpos_bbox_expansion); + + // angua: expand the bounds a bit downwards, so that they can actually reach target positions + // that are reported as reachable by PathToGoal. + bnds[0].z -= aas_reachability_z_tolerance; + bnds[1].z += 0.4*aas_reachability_z_tolerance; // grayman #2717 - don't look so far up + + return (bnds.ContainsPoint(pos)); +} + +/* +===================== +idAI::PointReachableAreaNum +===================== +*/ +int idAI::PointReachableAreaNum( const idVec3 &pos, const float boundsScale, const idVec3& offset) const +{ + START_SCOPED_TIMING(aiPointReachableAreaNumTimer, scopedPointReachableAreaNumTimer); + + if (aas == NULL) { + return 0; // no AAS, no area number + } + + idVec3 size = aas->GetSettings()->boundingBoxes[0][1] * boundsScale; + + // Construct the modifed bounds, based on the parameters (max.z = 32) + idBounds bounds(-size, idVec3(size.x, size.y, 32.0f)); + idVec3 newPos = pos + offset; + +/* idBounds temp(bounds); + temp.TranslateSelf(newPos); + gameRenderWorld->DebugBox(colorGreen, idBox(temp),gameLocal.msec);*/ + + int areaNum = 0; + + if (move.moveType == MOVETYPE_FLY) + { + // Flying monsters + areaNum = aas->PointReachableAreaNum( newPos, bounds, AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ); + } + else + { + // Non-flying monsters + areaNum = aas->PointReachableAreaNum( newPos, bounds, AREA_REACHABLE_WALK ); + } + + return areaNum; +} + +/* +===================== +idAI::PathToGoal +===================== +*/ +bool idAI::PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, idActor* actor ) const { + if ( !aas ) { + return false; + } + + START_SCOPED_TIMING(aiPathToGoalTimer, scopedPathToGoalTimer); + + idVec3 org = origin; + aas->PushPointIntoAreaNum( areaNum, org ); + if ( !areaNum ) { + return false; + } + + idVec3 goal = goalOrigin; + aas->PushPointIntoAreaNum( goalAreaNum, goal ); + if ( !goalAreaNum ) { + return false; + } + + // Sanity check the returned area. If the position isn't within the AI's height + aas_reachability_z_tolerance/2 + // reach, then report it as unreachable. + const idVec3& grav = physicsObj.GetGravityNormal(); + + float height = fabs((goal - aas->AreaCenter(goalAreaNum)) * grav); + + idBounds bounds = GetPhysics()->GetBounds(); + + if (height > (bounds[1][2] + reachedpos_bbox_expansion + 0.4*aas_reachability_z_tolerance)) // grayman #2717 - don't look so far up, and add reachedpos_bbox_expansion + { + goalAreaNum = 0; + return false; + } + + bool returnval; + gameLocal.m_AreaManager.DisableForbiddenAreas(this); + if ( move.moveType == MOVETYPE_FLY ) { + returnval = aas->FlyPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags ); + } else { + returnval = aas->WalkPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags, actor ); + } + gameLocal.m_AreaManager.EnableForbiddenAreas(this); + + // return returnval; + // grayman #2708 - if returnval is true, return, but if false, check whether the AAS area is above + // the AI's origin, as it might be if the AI is stuck in an AAS area next to a monster-clipped + // table top, where it will be at the plane of the table top. If that's the case, return 'true' + // to let the AI escape this type of AAS area. Normal pathfinding will never let him out. + + if (returnval) + { + return true; + } + + idVec3 myOrigin = GetPhysics()->GetOrigin(); + idBounds areaBounds = aas->GetAreaBounds(areaNum); + path.moveGoal = goal; + return (myOrigin.z < areaBounds[0].z); +} + + +/* +===================== +idAI::TravelDistance + +Returns the approximate travel distance from one position to the goal, or if no AAS, the straight line distance. + +This is feakin' slow, so it's not good to do it too many times per frame. It also is slower the further you +are from the goal, so try to break the goals up into shorter distances. +===================== +*/ +float idAI::TravelDistance( const idVec3 &start, const idVec3 &end ) { + int fromArea; + int toArea; + float dist; + idVec2 delta; + aasPath_t path; + + if ( !aas ) { + // no aas, so just take the straight line distance + delta = end.ToVec2() - start.ToVec2(); + dist = delta.LengthFast(); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); + gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); + } + + return dist; + } + + fromArea = PointReachableAreaNum( start ); + toArea = PointReachableAreaNum( end ); + + if ( !fromArea || !toArea ) { + // can't seem to get there + return -1; + } + + if ( fromArea == toArea ) { + // same area, so just take the straight line distance + delta = end.ToVec2() - start.ToVec2(); + dist = delta.LengthFast(); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); + gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); + } + + return dist; + } + + idReachability *reach; + int travelTime; + if ( !aas->RouteToGoalArea( fromArea, start, toArea, travelFlags, travelTime, &reach, NULL, this ) ) { + return -1; + } + + if ( ai_debugMove.GetBool() ) { + if ( move.moveType == MOVETYPE_FLY ) { + aas->ShowFlyPath( start, toArea, end ); + } else { + aas->ShowWalkPath( start, toArea, end ); + } + } + + return travelTime; +} + +/* +===================== +idAI::StopMove +===================== +*/ +void idAI::StopMove( moveStatus_t status ) { + AI_MOVE_DONE = true; + AI_FORWARD = false; + m_pathRank = 1000; // grayman #2345 + move.moveCommand = MOVE_NONE; + move.moveStatus = status; + move.toAreaNum = 0; + move.goalEntity = NULL; + move.moveDest = physicsObj.GetOrigin(); + AI_DEST_UNREACHABLE = (status == MOVE_STATUS_DEST_UNREACHABLE); + AI_OBSTACLE_IN_PATH = false; + AI_BLOCKED = false; + move.startTime = gameLocal.time; + move.duration = 0; + move.range = 0.0f; + move.speed = 0.0f; + move.anim = 0; + move.moveDir.Zero(); + move.lastMoveOrigin.Zero(); + move.lastMoveTime = gameLocal.time; + move.accuracy = -1; +} + +const idVec3& idAI::GetMoveDest() const +{ + return move.moveDest; +} + +idEntity* idAI::GetTactileEntity(void) // grayman #2345 +{ + return m_tactileEntity; +} + +/* +===================== +idAI::FaceEnemy + +Continually face the enemy's last known position. MoveDone is always true in this case. +===================== +*/ +bool idAI::FaceEnemy( void ) { + idActor *enemyEnt = enemy.GetEntity(); + if ( !enemyEnt ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + return false; + } + + TurnToward( lastVisibleEnemyPos ); + move.goalEntity = enemyEnt; + move.moveDest = physicsObj.GetOrigin(); + move.moveCommand = MOVE_FACE_ENEMY; + move.moveStatus = MOVE_STATUS_WAITING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + move.accuracy = -1; + AI_MOVE_DONE = true; + AI_FORWARD = false; + m_pathRank = 1000; // grayman #2345 + AI_DEST_UNREACHABLE = false; + + return true; +} + +/* +===================== +idAI::FaceEntity + +Continually face the entity position. MoveDone is always true in this case. +===================== +*/ +bool idAI::FaceEntity( idEntity *ent ) { + if ( !ent ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + return false; + } + + idVec3 entityOrg = ent->GetPhysics()->GetOrigin(); + TurnToward( entityOrg ); + move.goalEntity = ent; + move.moveDest = physicsObj.GetOrigin(); + move.moveCommand = MOVE_FACE_ENTITY; + move.moveStatus = MOVE_STATUS_WAITING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + AI_MOVE_DONE = true; + AI_FORWARD = false; + m_pathRank = 1000; // grayman #2345 + AI_DEST_UNREACHABLE = false; + + return true; +} + +/* +===================== +idAI::DirectMoveToPosition +===================== +*/ +bool idAI::DirectMoveToPosition( const idVec3 &pos ) { + if ( ReachedPos( pos, move.moveCommand ) ) { + StopMove( MOVE_STATUS_DONE ); + return true; + } + + move.moveDest = pos; + move.goalEntity = NULL; + move.moveCommand = MOVE_TO_POSITION_DIRECT; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + if ( move.moveType == MOVETYPE_FLY ) { + idVec3 dir = pos - physicsObj.GetOrigin(); + dir.Normalize(); + dir *= fly_speed; + physicsObj.SetLinearVelocity( dir ); + } + + return true; +} + +/* +===================== +idAI::MoveToEnemyHeight +===================== +*/ +bool idAI::MoveToEnemyHeight( void ) { + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt || ( move.moveType != MOVETYPE_FLY ) ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + return false; + } + + move.moveDest.z = lastVisibleEnemyPos.z + enemyEnt->EyeOffset().z + fly_offset; + move.goalEntity = enemyEnt; + move.moveCommand = MOVE_TO_ENEMYHEIGHT; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = false; + m_pathRank = 1000; // grayman #2345 + + return true; +} + +/* +===================== +idAI::MoveToEnemy +===================== +*/ +bool idAI::MoveToEnemy( void ) { + int areaNum; + aasPath_t path; + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + return false; + } + + if ( ReachedPos( lastVisibleReachableEnemyPos, MOVE_TO_ENEMY ) ) { + if ( !ReachedPos( lastVisibleEnemyPos, MOVE_TO_ENEMY ) || !AI_ENEMY_VISIBLE ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + StopMove( MOVE_STATUS_DONE ); + return true; + } + + idVec3 pos = lastVisibleReachableEnemyPos; + + move.toAreaNum = 0; + if ( aas ) { + move.toAreaNum = PointReachableAreaNum( pos ); + aas->PushPointIntoAreaNum( move.toAreaNum, pos ); + + areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); + if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos, this ) ) { + AI_DEST_UNREACHABLE = true; + return false; + } + } + + if ( !move.toAreaNum ) { + // if only trying to update the enemy position + if ( move.moveCommand == MOVE_TO_ENEMY ) { + if ( !aas ) { + // keep the move destination up to date for wandering + move.moveDest = pos; + } + return false; + } + + if ( !NewWanderDir( pos ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + } + + if ( move.moveCommand != MOVE_TO_ENEMY ) { + move.moveCommand = MOVE_TO_ENEMY; + move.startTime = gameLocal.time; + } + + move.moveDest = pos; + move.goalEntity = enemyEnt; + move.speed = fly_speed; + move.moveStatus = MOVE_STATUS_MOVING; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +/* +===================== +idAI::MoveToEntity +===================== +*/ +bool idAI::MoveToEntity( idEntity *ent ) { + int areaNum; + aasPath_t path; + idVec3 pos; + + if ( !ent ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + return false; + } + + pos = ent->GetPhysics()->GetOrigin(); + if ( ( move.moveType != MOVETYPE_FLY ) && ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntityOrigin != pos ) ) ) { + ent->GetFloorPos( 64.0f, pos ); + } + + if ( ReachedPos( pos, MOVE_TO_ENTITY ) ) { + StopMove( MOVE_STATUS_DONE ); + return true; + } + + move.toAreaNum = 0; + if ( aas ) { + move.toAreaNum = PointReachableAreaNum( pos ); + aas->PushPointIntoAreaNum( move.toAreaNum, pos ); + + areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); + if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos, this ) ) { + AI_DEST_UNREACHABLE = true; + return false; + } + } + + if ( !move.toAreaNum ) { + // if only trying to update the entity position + if ( move.moveCommand == MOVE_TO_ENTITY ) { + if ( !aas ) { + // keep the move destination up to date for wandering + move.moveDest = pos; + } + return false; + } + + if ( !NewWanderDir( pos ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + } + + if ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntity.GetEntity() != ent ) ) { + move.startTime = gameLocal.time; + move.goalEntity = ent; + move.moveCommand = MOVE_TO_ENTITY; + } + + move.moveDest = pos; + move.goalEntityOrigin = ent->GetPhysics()->GetOrigin(); + move.moveStatus = MOVE_STATUS_MOVING; + move.speed = fly_speed; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +CMultiStateMover* idAI::OnElevator(bool mustBeMoving) const +{ + idEntity* ent = physicsObj.GetGroundEntity(); + + // Return false if ground entity is not a mover + if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) return NULL; + + CMultiStateMover* mover = static_cast(ent); + if (mustBeMoving) + { + return (!mover->IsAtRest()) ? mover : NULL; + } + return mover; +} + +bool idAI::Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption) +{ + EscapePointAlgorithm algorithmType = static_cast(algorithm); + + if ( !aas || !entityToFleeFrom ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + // The current AI origin + const idVec3& org = physicsObj.GetOrigin(); + + // These two will hold the travel destination info + idVec3 moveDest; + int moveAreaNum(-1); + + if (algorithmType != FIND_AAS_AREA_FAR_FROM_THREAT) + { + // Use the EscapePointManager to locate a pathFlee entity + + // Setup the escape conditions + EscapeConditions conditions; + + conditions.fromEntity = entityToFleeFrom; + conditions.aas = aas; + conditions.fromPosition = org; + conditions.self = this; + conditions.distanceOption = static_cast(distanceOption); + conditions.algorithm = algorithmType; + conditions.minDistanceToThreat = 0.0f; + + // Request the escape goal from the manager + EscapeGoal goal = gameLocal.m_EscapePointManager->GetEscapeGoal(conditions); + + if (goal.escapePointId == -1) + { + // Invalid escape point id returned + return false; + } + + // Get the actual point (this should never be NULL) + EscapePoint* targetPoint = gameLocal.m_EscapePointManager->GetEscapePoint(goal.escapePointId); + + moveDest = targetPoint->origin; + moveAreaNum = targetPoint->areaNum; + } + else + { + // algorithm == FIND_AAS_AREA_FAR_FROM_THREAT + + int areaNum = PointReachableAreaNum(org); + + // consider the entity the monster is getting close to as an obstacle + aasObstacle_t obstacle; + obstacle.absBounds = entityToFleeFrom->GetPhysics()->GetAbsBounds(); + + idVec3 pos; + + if ( entityToFleeFrom == enemy.GetEntity() ) { + pos = lastVisibleEnemyPos; + } else { + pos = entityToFleeFrom->GetPhysics()->GetOrigin(); + } + + // Setup the evaluator class + tdmAASFindEscape findEscapeArea(pos, org, distanceOption, 100); + aasGoal_t dummy; + aas->FindNearestGoal(dummy, areaNum, org, pos, travelFlags, &obstacle, 1, findEscapeArea); + + aasGoal_t& goal = findEscapeArea.GetEscapeGoal(); + + if (goal.areaNum == -1) + { + // Invalid escape point id returned + return false; + } + + moveDest = goal.origin; + moveAreaNum = goal.areaNum; + } + + StopMove(MOVE_STATUS_DONE); + MoveToPosition(moveDest); + return true; +/* + if ( ReachedPos( moveDest, move.moveCommand ) ) { + StopMove( MOVE_STATUS_DONE ); + return true; + } + + if ( !move.toAreaNum && !NewWanderDir( moveDest ) ) + { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } +*/ +/* grayman - the section below can't be reached because + of the 'return true' above, so I'm commenting it out. + The section above this, just below the 'return', was + already commented out. + + move.moveDest = moveDest; + move.toAreaNum = moveAreaNum; + move.goalEntity = entityToFleeFrom; + move.moveCommand = MOVE_FLEE; + move.moveStatus = MOVE_STATUS_MOVING; + move.range = MAX_FLEE_DISTANCE; + move.speed = fly_speed; + move.startTime = gameLocal.time; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; + */ +} + +/* +===================== +idAI::GetPositionWithinRange +===================== +*/ +aasGoal_t idAI::GetPositionWithinRange(const idVec3& targetPos) +{ + idVec3 org = physicsObj.GetOrigin(); + idVec3 eye = GetEyePosition(); + float fireRange = spawnArgs.GetFloat("fire_range", "0"); + + PositionWithinRangeFinder findGoal(this, physicsObj.GetGravityAxis(), targetPos, eye - org, fireRange); + + aasGoal_t goal; + int areaNum = PointReachableAreaNum(org); + + aas->FindNearestGoal(goal, areaNum, org, targetPos, travelFlags, NULL, 0, findGoal); + + goal.areaNum = -1; + + float bestDistance; + findGoal.GetBestGoalResult(bestDistance, goal); + return goal; +} + + + + +/* +===================== +idAI::GetObservationPosition +===================== +*/ +idVec3 idAI::GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne) +{ + int areaNum; + aasObstacle_t obstacle; + aasGoal_t goal; + idBounds bounds; + idVec3 observeFromPos; + aasPath_t path; + + if ( !aas ) + { + observeFromPos = GetPhysics()->GetOrigin(); + AI_DEST_UNREACHABLE = true; + return observeFromPos; + } + + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( org ); + + // Raise point up just a bit so it isn't on the floor of the aas + idVec3 pointToObserve2 = pointToObserve; + pointToObserve2.z += 45.0; + + // What is the lighting along the line where the thing to be observed + // might be. + float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(pointToObserve, pointToObserve2); + + idAASFindObservationPosition findGoal + ( + this, + physicsObj.GetGravityAxis(), + pointToObserve2, + GetEyePosition() - org, // Offset of eye from origin + maxDistanceToObserve // Maximum distance from which we can observe + ); + + if (!aas->FindNearestGoal + ( + goal, + areaNum, + org, + pointToObserve2, // It is also the goal target + travelFlags, + NULL, + 0, + findGoal + ) ) + { + float bestDistance; + + // See if we can get to the point itself since noplace was good enough + // for just looking from a distance due to lighting/occlusion/reachability. + if (PathToGoal( path, areaNum, physicsObj.GetOrigin(), areaNum, org, this ) ) + { + + // Can reach the point itself, so walk right up to it + observeFromPos = pointToObserve; + + // Draw the AI Debug Graphics + if (cv_ai_search_show.GetInteger() >= 1.0) + { + idVec4 markerColor (0.0, 1.0, 1.0, 1.0); + idVec3 arrowLength (0.0, 0.0, 50.0); + + gameRenderWorld->DebugArrow + ( + markerColor, + observeFromPos + arrowLength, + observeFromPos, + 2, + cv_ai_search_show.GetInteger() + ); + } + + } + + else if (findGoal.getBestGoalResult + ( + bestDistance, + goal + )) + { + + // Use closest reachable observation point that we found + observeFromPos = goal.origin; + + // Draw the AI Debug Graphics + if (cv_ai_search_show.GetInteger() >= 1.0) + { + idVec4 markerColor (1.0, 1.0, 0.0, 1.0); + idVec3 arrowLength (0.0, 0.0, 50.0); + + gameRenderWorld->DebugArrow + ( + markerColor, + observeFromPos, + pointToObserve, + 2, + cv_ai_search_show.GetInteger() + ); + } + } + + else + { + // No choice but to try to walk up to it as much as we can + observeFromPos = pointToObserve; + + // Draw the AI Debug Graphics + if (cv_ai_search_show.GetInteger() >= 1.0) + { + idVec4 markerColor (1.0, 0.0, 0.0, 1.0); + idVec3 arrowLength (0.0, 0.0, 50.0); + + gameRenderWorld->DebugArrow + ( + markerColor, + observeFromPos + arrowLength, + observeFromPos, + 2, + cv_ai_search_show.GetInteger() + ); + } + } + return observeFromPos; + } + + else + { + observeFromPos = goal.origin; + AI_DEST_UNREACHABLE = false; + + // Draw the AI Debug Graphics + if (cv_ai_search_show.GetInteger() >= 1.0) + { + idVec4 markerColor (0.0, 1.0, 0.0, 1.0); + idVec3 arrowLength (0.0, 0.0, 50.0); + + gameRenderWorld->DebugArrow + ( + markerColor, + observeFromPos, + pointToObserve, + 2, + cv_ai_search_show.GetInteger() + ); + } + return observeFromPos; + } +} + +/* +===================== +idAI::MoveOutOfRange +===================== +*/ +bool idAI::MoveOutOfRange( idEntity *ent, float range ) { + int areaNum; + aasObstacle_t obstacle; + aasGoal_t goal; + idBounds bounds; + idVec3 pos; + + if ( !aas || !ent ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( org ); + + // consider the entity the monster is getting close to as an obstacle + obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); + + if ( ent == enemy.GetEntity() ) { + pos = lastVisibleEnemyPos; + } else { + pos = ent->GetPhysics()->GetOrigin(); + } + + idAASFindAreaOutOfRange findGoal( pos, range ); + if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Best fleeing location is: %f %f %f in area %d\r", goal.origin.x, goal.origin.y, goal.origin.z, goal.areaNum); + + if ( ReachedPos( goal.origin, move.moveCommand ) ) { + StopMove( MOVE_STATUS_DONE ); + return true; + } + + move.moveDest = goal.origin; + move.toAreaNum = goal.areaNum; + move.goalEntity = ent; + move.moveCommand = MOVE_OUT_OF_RANGE; + move.moveStatus = MOVE_STATUS_MOVING; + move.range = range; + move.speed = fly_speed; + move.startTime = gameLocal.time; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +/* +===================== +idAI::MoveToAttackPosition +===================== +*/ +bool idAI::MoveToAttackPosition( idEntity *ent, int attack_anim ) { + int areaNum; + aasObstacle_t obstacle; + aasGoal_t goal; + idBounds bounds; + idVec3 pos; + + if ( !aas || !ent ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( org ); + + // consider the entity the monster is getting close to as an obstacle + obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); + + if ( ent == enemy.GetEntity() ) { + pos = lastVisibleEnemyPos; + } else { + pos = ent->GetPhysics()->GetOrigin(); + } + + // Make sure we have a active projectile or at least the def + if (activeProjectile.info.def == NULL) + { + if (projectileInfo.Num() == 0) + { + gameLocal.Warning("AI %s has no projectile info, cannot move to attack position!", name.c_str()); + return false; + } + + // Move the def pointer of the "next" projectile info into the active one + activeProjectile.info = projectileInfo[curProjectileIndex]; + } + + idAASFindAttackPosition findGoal( this, physicsObj.GetGravityAxis(), ent, pos, missileLaunchOffset[ attack_anim ] ); + if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + move.moveDest = goal.origin; + move.toAreaNum = goal.areaNum; + move.goalEntity = ent; + move.moveCommand = MOVE_TO_ATTACK_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.speed = fly_speed; + move.startTime = gameLocal.time; + move.anim = attack_anim; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +/* +===================== +idAI::MoveToPosition +===================== +*/ +bool idAI::MoveToPosition( const idVec3 &pos, float accuracy ) +{ + // Clear the "blocked" flag in the movement subsystem + movementSubsystem->SetBlockedState(ai::MovementSubsystem::ENotBlocked); + + // Check if we already reached the position + if ( ReachedPos( pos, move.moveCommand) ) { + StopMove( MOVE_STATUS_DONE ); + return true; + } + + if (GetMoveType() == MOVETYPE_SIT + || GetMoveType() == MOVETYPE_SLEEP + || GetMoveType() == MOVETYPE_SIT_DOWN + || GetMoveType() == MOVETYPE_GET_UP + || GetMoveType()== MOVETYPE_LAY_DOWN + || GetMoveType()== MOVETYPE_GET_UP_FROM_LYING) + { + GetUp(); + return true; + } + + idVec3 org = pos; + move.toAreaNum = 0; + aasPath_t path; + if ( aas ) { + move.toAreaNum = PointReachableAreaNum( org ); + aas->PushPointIntoAreaNum( move.toAreaNum, org ); // if this point is outside this area, it will be moved to one of the area's edges + + int areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); + + if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, org, this ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + } + + if ( !move.toAreaNum && !NewWanderDir( org ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + // Valid path to goal, check if we need to use an elevator + if (path.type == PATHTYPE_ELEVATOR) + { + NeedToUseElevator(path.elevatorRoute); + } + + move.moveDest = org; + move.goalEntity = NULL; + move.moveCommand = MOVE_TO_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + move.accuracy = accuracy; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +/* +===================== +idAI::LookForCover +===================== +*/ +bool idAI::LookForCover(aasGoal_t& hideGoal,idEntity *hideFromEnt, const idVec3 &hideFromPos) +{ + if (aas == NULL) return false; + + idBounds bounds; + aasObstacle_t obstacle; + + const idVec3 &org = physicsObj.GetOrigin(); + int areaNum = PointReachableAreaNum( org ); + + // consider the entity the monster tries to hide from as an obstacle + obstacle.absBounds = hideFromEnt->GetPhysics()->GetAbsBounds(); + + idAASFindCover findCover( this, hideFromEnt, hideFromPos ); + return aas->FindNearestGoal( hideGoal, areaNum, org, hideFromPos, travelFlags, &obstacle, 1, findCover, spawnArgs.GetInt("taking_cover_max_cost") ); +} + +/* +===================== +idAI::MoveToCover +===================== +*/ +bool idAI::MoveToCover( idEntity *hideFromEnt, const idVec3 &hideFromPos ) { + //common->Printf("MoveToCover called... "); + + aasGoal_t hideGoal; + + if ( !aas || !hideFromEnt ) { + common->Printf("MoveToCover failed: null aas or entity\n"); + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + if (!LookForCover(hideGoal, hideFromEnt, hideFromPos)) { + //common->Printf("MoveToCover failed: destination unreachable\n"); + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + if ( ReachedPos( hideGoal.origin, move.moveCommand ) ) { + //common->Printf("MoveToCover succeeded: Already at hide position\n"); + StopMove( MOVE_STATUS_DONE ); + return true; + } + + move.moveDest = hideGoal.origin; + move.toAreaNum = hideGoal.areaNum; + move.goalEntity = hideFromEnt; + move.moveCommand = MOVE_TO_COVER; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + //common->Printf("MoveToCover succeeded: Now moving into cover\n"); + + return true; +} + +/* +===================== +idAI::SlideToPosition +===================== +*/ +bool idAI::SlideToPosition( const idVec3 &pos, float time ) { + StopMove( MOVE_STATUS_DONE ); + + move.moveDest = pos; + move.goalEntity = NULL; + move.moveCommand = MOVE_SLIDE_TO_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.duration = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = false; + m_pathRank = 1000; // grayman #2345 + + if ( move.duration > 0 ) { + move.moveDir = ( pos - physicsObj.GetOrigin() ) / MS2SEC( move.duration ); + if ( move.moveType != MOVETYPE_FLY ) { + move.moveDir.z = 0.0f; + } + move.speed = move.moveDir.LengthFast(); + } + + return true; +} + +/* +===================== +idAI::WanderAround +===================== +*/ +bool idAI::WanderAround( void ) { + StopMove( MOVE_STATUS_DONE ); + + move.moveDest = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 256.0f; + if ( !NewWanderDir( move.moveDest ) ) { + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + AI_DEST_UNREACHABLE = true; + return false; + } + + move.moveCommand = MOVE_WANDER; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + move.accuracy = -1; + AI_MOVE_DONE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} + +/* +===================== +idAI::MoveDone +===================== +*/ +bool idAI::MoveDone( void ) const { + return ( move.moveCommand == MOVE_NONE ); +} + +void idAI::SetMoveType( int moveType ) { + if ( ( moveType < 0 ) || ( moveType >= NUM_MOVETYPES ) ) { + gameLocal.Error( "Invalid movetype %d", moveType ); + } + + move.moveType = static_cast( moveType ); + if ( move.moveType == MOVETYPE_FLY ) { + travelFlags = TFL_WALK|TFL_AIR|TFL_FLY|TFL_DOOR; + } else { + travelFlags = TFL_WALK|TFL_AIR|TFL_DOOR; + } +} + +/* +================ +idAI::StepDirection +================ +*/ +bool idAI::StepDirection( float dir ) { + predictedPath_t path; + idVec3 org; + + move.wanderYaw = dir; + move.moveDir = idAngles( 0, move.wanderYaw, 0 ).ToForward(); + + org = physicsObj.GetOrigin(); + + idAI::PredictPath( this, aas, org, move.moveDir * 48.0f, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + if ( path.blockingEntity && ( ( move.moveCommand == MOVE_TO_ENEMY ) || ( move.moveCommand == MOVE_TO_ENTITY ) ) && ( path.blockingEntity == move.goalEntity.GetEntity() ) ) { + // don't report being blocked if we ran into our goal entity + return true; + } + + // SZ: January 7, 2006: Wandering uses this, and currently it fails the test if it would bump into another AI. + // If we are wandering, we want to make sure we can still bump into the player or enemy AIs, both of which are idActor + // based. + if (path.blockingEntity && (move.moveCommand == MOVE_WANDER)) + { + // What type of entity is it? + if + ( + (path.blockingEntity->IsType(idActor::Type) ) + ) + { + // Bump into enemies all you want while wandering + if (IsEnemy(path.blockingEntity)) + { + return true; + } + } + + } // End wandering case + + if ( ( move.moveType == MOVETYPE_FLY ) && ( path.endEvent == SE_BLOCKED ) ) { + float z; + + move.moveDir = path.endVelocity * 1.0f / 48.0f; + + // trace down to the floor and see if we can go forward + idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, -1024.0f ), 1000, 1000, SE_BLOCKED, path ); + + idVec3 floorPos = path.endPos; + idAI::PredictPath( this, aas, floorPos, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); + if ( !path.endEvent ) { + move.moveDir.z = -1.0f; + return true; + } + + // trace up to see if we can go over something and go forward + idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, 256.0f ), 1000, 1000, SE_BLOCKED, path ); + + idVec3 ceilingPos = path.endPos; + + for( z = org.z; z <= ceilingPos.z + 64.0f; z += 64.0f ) { + idVec3 start; + if ( z <= ceilingPos.z ) { + start.x = org.x; + start.y = org.y; + start.z = z; + } else { + start = ceilingPos; + } + idAI::PredictPath( this, aas, start, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); + if ( !path.endEvent ) { + move.moveDir.z = 1.0f; + return true; + } + } + return false; + } + + return ( path.endEvent == 0 ); +} +/* +================ +idAI::MoveAlongVector +================ +*/ +bool idAI::MoveAlongVector( float yaw ) +{ + StopMove( MOVE_STATUS_DONE ); + move.moveDir = idAngles( 0, yaw, 0 ).ToForward(); + move.moveDest = physicsObj.GetOrigin() + move.moveDir * 256.0f; + + move.moveCommand = MOVE_VECTOR; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + AI_MOVE_DONE = false; + AI_FORWARD = true; + m_pathRank = rank; // grayman #2345 + + return true; +} +/* +================ +idAI::NewWanderDir +================ +*/ +bool idAI::NewWanderDir( const idVec3 &dest ) { + float deltax, deltay; + float d[ 3 ]; + float tdir, olddir, turnaround; + + move.nextWanderTime = gameLocal.time + ( gameLocal.random.RandomInt(500) + 500 ); + + olddir = idMath::AngleNormalize360( ( int )( current_yaw / 45 ) * 45 ); + turnaround = idMath::AngleNormalize360( olddir - 180 ); + + idVec3 org = physicsObj.GetOrigin(); + deltax = dest.x - org.x; + deltay = dest.y - org.y; + if ( deltax > 10 ) { + d[ 1 ]= 0; + } else if ( deltax < -10 ) { + d[ 1 ] = 180; + } else { + d[ 1 ] = DI_NODIR; + } + + if ( deltay < -10 ) { + d[ 2 ] = 270; + } else if ( deltay > 10 ) { + d[ 2 ] = 90; + } else { + d[ 2 ] = DI_NODIR; + } + + // try direct route + if ( d[ 1 ] != DI_NODIR && d[ 2 ] != DI_NODIR ) { + if ( d[ 1 ] == 0 ) { + tdir = d[ 2 ] == 90 ? 45 : 315; + } else { + tdir = d[ 2 ] == 90 ? 135 : 215; + } + + if ( tdir != turnaround && StepDirection( tdir ) ) { + return true; + } + } + + // try other directions + if ( ( gameLocal.random.RandomInt() & 1 ) || fabs( deltay ) > fabs( deltax ) ) { + tdir = d[ 1 ]; + d[ 1 ] = d[ 2 ]; + d[ 2 ] = tdir; + } + + if ( d[ 1 ] != DI_NODIR && d[ 1 ] != turnaround && StepDirection( d[1] ) ) { + return true; + } + + if ( d[ 2 ] != DI_NODIR && d[ 2 ] != turnaround && StepDirection( d[ 2 ] ) ) { + return true; + } + + // there is no direct path to the player, so pick another direction + if ( olddir != DI_NODIR && StepDirection( olddir ) ) { + return true; + } + + // randomly determine direction of search + if ( gameLocal.random.RandomInt() & 1 ) { + for( tdir = 0; tdir <= 315; tdir += 45 ) { + if ( tdir != turnaround && StepDirection( tdir ) ) { + return true; + } + } + } else { + for ( tdir = 315; tdir >= 0; tdir -= 45 ) { + if ( tdir != turnaround && StepDirection( tdir ) ) { + return true; + } + } + } + + if ( turnaround != DI_NODIR && StepDirection( turnaround ) ) { + return true; + } + + // can't move + StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + return false; +} + +/* +===================== +idAI::GetMovePos +===================== +*/ +bool idAI::GetMovePos(idVec3 &seekPos) +{ + START_SCOPED_TIMING(aiGetMovePosTimer, scopedGetMovePosTimer); + + const idVec3& org = physicsObj.GetOrigin(); + seekPos = org; + + switch( move.moveCommand ) { + case MOVE_NONE : + seekPos = move.moveDest; + return false; + break; + + case MOVE_FACE_ENEMY : + case MOVE_FACE_ENTITY : + seekPos = move.moveDest; + return false; + break; + + case MOVE_TO_POSITION_DIRECT : + seekPos = move.moveDest; + if ( ReachedPos(move.moveDest, move.moveCommand)) + { + StopMove( MOVE_STATUS_DONE ); + } + return false; + break; + + case MOVE_SLIDE_TO_POSITION : + seekPos = org; + return false; + break; + + case MOVE_VECTOR : + seekPos = move.moveDest; + return true; + break; + default: + break; // Handled below (note the returns in all cases above) + // (default case added to suppress GCC warnings) + } + + if (move.moveCommand == MOVE_TO_ENTITY) { + MoveToEntity(move.goalEntity.GetEntity()); + } + + move.moveStatus = MOVE_STATUS_MOVING; + bool result = false; + + // Check if the blocking time has already expired + if (gameLocal.time > move.blockTime) + { + if (move.moveCommand == MOVE_WANDER) + { + move.moveDest = org + viewAxis[0] * physicsObj.GetGravityAxis() * 256.0f; + } + else + { + // Check if we already reached the destination position + if (ReachedPos(move.moveDest, move.moveCommand)) + { + // Yes, stop the move, move status is DONE + StopMove(MOVE_STATUS_DONE); + seekPos = org; + return false; // nothing to do, return false + } + } + + if (aas != NULL && move.toAreaNum != 0) + { + // Get the area number we're currently in. + int areaNum = PointReachableAreaNum(org); + + // Try to setup a path to the goal + aasPath_t path; + if (PathToGoal(path, areaNum, org, move.toAreaNum, move.moveDest, this)) + { + seekPos = path.moveGoal; + result = true; // We have a valid Path to the goal + move.nextWanderTime = 0; + + // angua: check whether there is a door in the path + if (path.firstDoor != NULL) + { + const idVec3& doorOrg = path.firstDoor->GetPhysics()->GetOrigin(); + const idVec3& org = GetPhysics()->GetOrigin(); + idVec3 dir = doorOrg - org; + dir.z = 0; + float dist = dir.LengthFast(); + if (dist < 500) + { + GetMind()->GetState()->OnFrobDoorEncounter(path.firstDoor); + } + } + } + else + { + AI_DEST_UNREACHABLE = true; + } + } + } + + if (!result) + { + // No path to the goal found, wander around + if (gameLocal.time > move.nextWanderTime || !StepDirection(move.wanderYaw)) + { + result = NewWanderDir(move.moveDest); + if (!result) + { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); + AI_DEST_UNREACHABLE = true; + seekPos = org; + return false; + } + } + else + { + result = true; + } + + // Set the seek position to something far away, but in the right direction + seekPos = org + move.moveDir * 2048.0f; + + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine( colorYellow, org, seekPos, gameLocal.msec, true ); + } + } + else + { + // result == true, we have a valid path + AI_DEST_UNREACHABLE = false; + } + + if (result && ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine( colorCyan, physicsObj.GetOrigin(), seekPos ); + } + + return result; +} + + +/* +===================== +The Dark Mod +idAI::CanSee virtual override +===================== +*/ +bool idAI::CanSee( idEntity *ent, bool useFOV ) const +{ + START_SCOPED_TIMING(aiCanSeeTimer, scopedCanSeeTimer); + + // Test if it is occluded, and use field of vision in the check (true as second parameter) + bool cansee = idActor::CanSee( ent, useFOV ); + + // Also consider lighting and visual acuity of AI + if (cansee) + { + cansee = !IsEntityHiddenByDarkness(ent, 0.1f); // tels: hard-coded threshold of 0.1f + } + + // Return result + return cansee; +} + +/* +===================== +The Dark Mod +idAI::CanSeeExt + +This method can ignore lighting conditions and/or field of vision. +===================== +*/ +bool idAI::CanSeeExt( idEntity *ent, const bool useFOV, const bool useLighting ) const +{ + // Test if it is occluded + bool cansee = idActor::CanSee( ent, useFOV ); + + if (cansee && useLighting) + { + cansee = !IsEntityHiddenByDarkness(ent, 0.1f); // tels: hard-coded threshold of 0.1f + } + + // Return result + return cansee; +} + +// grayman #2859 - Can the AI see a point belonging to a target (not necessarily its origin)? + +bool idAI::CanSeeTargetPoint( idVec3 point, idEntity* target ) const +{ + // Check FOV + + if ( !CheckFOV( point ) ) + { + return false; + } + + // Check visibility + + trace_t result; + idVec3 eye(GetEyePosition()); // eye position of the AI + + // Trace from eye to point, ignoring self + + gameLocal.clip.TracePoint(result, eye, point, MASK_OPAQUE, this); + if ( result.fraction < 1.0 ) + { + if ( gameLocal.GetTraceEntity(result) != target ) + { + return false; + } + } + + // Check lighting + + idVec3 topPoint = point - (physicsObj.GetGravityNormal() * 32.0); + float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(point, topPoint); + idVec3 ownOrigin = physicsObj.GetOrigin(); + + return ( ( ( point - ownOrigin).LengthSqr() ) < ( maxDistanceToObserve * maxDistanceToObserve ) ); // grayman #2866 +} + +/* +===================== +The Dark Mod +idAI::CanSeeRope + +grayman #2872 - This method takes lighting conditions and field of vision under consideration. +===================== +*/ +idVec3 idAI::CanSeeRope( idEntity *ent ) const +{ + // Find a point on the rope at the same elevation as the AI's eyes + + // ent is the projectile_result for the rope arrow. It's bound to the stuck rope arrow, + // which also has the rope bound to it. + + idEntity* bindMaster = ent->GetBindMaster(); + if ( bindMaster != NULL ) + { + idEntity* rope = bindMaster->FindMatchingTeamEntity( idAFEntity_Generic::Type ); + + if ( rope != NULL ) + { + idAFEntity_Generic* ropeAF = static_cast(rope); + const idDeclModelDef *modelDef = rope->GetAnimator()->ModelDef(); + idList jointList; + idStr jointNames = rope->spawnArgs.GetString("rope_joints"); // names of joints defined in the model file + modelDef->GetJointList(jointNames,jointList); + + // Randomly select a joint, and randomly select a point along the + // rope segmentbetween that joint and its lower neighbor + + int joint1Index = gameLocal.random.RandomInt( jointList.Num() - 1 ); + int joint2Index = joint1Index + 1; + + // safety net in case the joint names are corrupt + + if ( ( jointList[joint1Index] == INVALID_JOINT ) || ( jointList[joint2Index] == INVALID_JOINT ) ) + { + return idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); // failure + } + + idMat3 axis; + idVec3 joint1Org; + ropeAF->GetJointWorldTransform( jointList[joint1Index], gameLocal.time, joint1Org, axis ); + idVec3 joint2Org; + ropeAF->GetJointWorldTransform( jointList[joint2Index], gameLocal.time, joint2Org, axis ); + float offset = gameLocal.random.RandomFloat(); + idVec3 spot = joint1Org + ( joint2Org - joint1Org ) * offset; + if ( CanSeeTargetPoint( spot, rope ) ) + { + return spot; + } + } + } + + // Return result +// return CanSeeTargetPoint( point, ent ); // grayman #2872 - this has to move inside the part search loop above, exiting true at the first segment we can see + return idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); +} + +/* +===================== +The Dark Mod +idAI::CanSeePositionExt + +This method can ignore lighting conditions and/or field of vision. +===================== +*/ +bool idAI::CanSeePositionExt( idVec3 position, bool useFOV, bool useLighting ) +{ + if ( useFOV && !CheckFOV( position ) ) + { + return false; + } + + idVec3 ownOrigin = physicsObj.GetOrigin(); + + bool canSee = EntityCanSeePos (this, ownOrigin, position); + + if (canSee && useLighting) + { + idVec3 bottomPoint = position; + idVec3 topPoint = position - (physicsObj.GetGravityNormal() * 32.0); + + float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(bottomPoint, topPoint); + + if ((position - ownOrigin).Length() > maxDistanceToObserve) + { + canSee = false; + } + + // Draw debug graphic? + if (cv_ai_visdist_show.GetFloat() > 1.0) + { + idVec3 midPoint = bottomPoint + ((topPoint-bottomPoint) / 2.0); + idVec3 observeFrom = GetEyePosition(); + + if (!canSee) + { + idVec4 markerColor (1.0, 0.0, 0.0, 0.0); + idVec4 markerColor2 (1.0, 0.0, 1.0, 0.0); + idVec3 arrowLength = midPoint - observeFrom; + arrowLength.Normalize(); + arrowLength *= maxDistanceToObserve; + + // Distance we could see + gameRenderWorld->DebugArrow + ( + markerColor, + observeFrom, + observeFrom + arrowLength, + 2, + cv_ai_visdist_show.GetInteger() + ); + + // Gap to where we want to see + gameRenderWorld->DebugArrow + ( + markerColor2, + observeFrom + arrowLength, + midPoint, + 2, + cv_ai_visdist_show.GetInteger() + ); + } + else + { + idVec4 markerColor (0.0, 1.0, 0.0, 0.0); + + // We can see there + gameRenderWorld->DebugArrow + ( + markerColor, + observeFrom, + midPoint, + 2, + cv_ai_visdist_show.GetInteger() + ); + } + } + } + + return canSee; +} + +/* +===================== +idAI::EntityCanSeePos +===================== +*/ +bool idAI::EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos ) +{ + pvsHandle_t handle = gameLocal.pvs.SetupCurrentPVS( actor->GetPVSAreas(), actor->GetNumPVSAreas() ); + + if ( !gameLocal.pvs.InCurrentPVS( handle, GetPVSAreas(), GetNumPVSAreas() ) ) { + gameLocal.pvs.FreeCurrentPVS( handle ); + return false; + } + + gameLocal.pvs.FreeCurrentPVS( handle ); + + idVec3 eye = actorOrigin + actor->EyeOffset(); + + idVec3 point = pos; + point[2] += 1.0f; + + physicsObj.DisableClip(); + + trace_t results; + gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); + if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { + physicsObj.EnableClip(); + return true; + } + + const idBounds &bounds = physicsObj.GetBounds(); + point[2] += bounds[1][2] - bounds[0][2]; + + gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); + physicsObj.EnableClip(); + if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { + return true; + } + + return false; +} + +/* +===================== +idAI::BlockedFailSafe +===================== +*/ +void idAI::BlockedFailSafe( void ) { + if ( !ai_blockedFailSafe.GetBool() || blockedRadius < 0.0f ) { + return; + } + if ( !physicsObj.OnGround() || enemy.GetEntity() == NULL || + ( physicsObj.GetOrigin() - move.lastMoveOrigin ).LengthSqr() > Square( blockedRadius ) ) { + move.lastMoveOrigin = physicsObj.GetOrigin(); + move.lastMoveTime = gameLocal.time; + } + if ( move.lastMoveTime < gameLocal.time - blockedMoveTime ) { + if ( lastAttackTime < gameLocal.time - blockedAttackTime ) { + AI_BLOCKED = true; + move.lastMoveTime = gameLocal.time; + } + } +} + +/*********************************************************************** + + turning + +***********************************************************************/ + +/* +===================== +idAI::Turn +===================== +*/ +void idAI::Turn(const idVec3& pivotOffset) { + float diff; + float diff2; + float turnAmount; + animFlags_t animflags; + + if ( !turnRate ) { + return; + } + + // check if the animator has marked this anim as non-turning + if ( !legsAnim.Disabled() && !legsAnim.AnimDone( 0 ) ) { + animflags = legsAnim.GetAnimFlags(); + } else { + animflags = torsoAnim.GetAnimFlags(); + } + if ( animflags.ai_no_turn ) { + return; + } + + idVec3 startPos = viewAxis * pivotOffset; + + if ( anim_turn_angles && animflags.anim_turn ) { + idMat3 rotateAxis; + + // set the blend between no turn and full turn + float frac = anim_turn_amount / anim_turn_angles; + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f - frac ); + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, frac ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f - frac ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, frac ); + + // get the total rotation from the start of the anim + animator.GetDeltaRotation( 0, gameLocal.time, rotateAxis ); + current_yaw = idMath::AngleNormalize180( anim_turn_yaw + rotateAxis[ 0 ].ToYaw() ); + } else { + diff = idMath::AngleNormalize180( ideal_yaw - current_yaw ); + turnVel += AI_TURN_SCALE * diff * MS2SEC( gameLocal.msec ); + if ( turnVel > turnRate ) { + turnVel = turnRate; + } else if ( turnVel < -turnRate ) { + turnVel = -turnRate; + } + turnAmount = turnVel * MS2SEC( gameLocal.time - m_lastThinkTime ); + if ( ( diff >= 0.0f ) && ( turnAmount >= diff ) ) { + turnVel = diff / MS2SEC( gameLocal.msec ); + turnAmount = diff; + } else if ( ( diff <= 0.0f ) && ( turnAmount <= diff ) ) { + turnVel = diff / MS2SEC( gameLocal.msec ); + turnAmount = diff; + } + current_yaw += turnAmount; + current_yaw = idMath::AngleNormalize180( current_yaw ); + diff2 = idMath::AngleNormalize180( ideal_yaw - current_yaw ); + if ( idMath::Fabs( diff2 ) < 0.1f ) { + current_yaw = ideal_yaw; + } + } + + viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); + + idVec3 endPos = viewAxis * pivotOffset; + + GetPhysics()->SetOrigin(GetPhysics()->GetOrigin() - idVec3(endPos - startPos)); + + if ( ai_debugMove.GetBool() ) { + const idVec3 &org = physicsObj.GetOrigin(); + gameRenderWorld->DebugLine( colorRed, org, org + idAngles( 0, ideal_yaw, 0 ).ToForward() * 64, gameLocal.msec ); + gameRenderWorld->DebugLine( colorGreen, org, org + idAngles( 0, current_yaw, 0 ).ToForward() * 48, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org, org + idAngles( 0, current_yaw + turnVel, 0 ).ToForward() * 32, gameLocal.msec ); + } +} + +/* +===================== +idAI::FacingIdeal +===================== +*/ +bool idAI::FacingIdeal( void ) { + float diff; + + if ( !turnRate ) { + return true; + } + + diff = idMath::AngleNormalize180( current_yaw - ideal_yaw ); + if ( idMath::Fabs( diff ) < 0.01f ) { + // force it to be exact + current_yaw = ideal_yaw; + return true; + } + + return false; +} + +/* +===================== +idAI::TurnToward +===================== +*/ +bool idAI::TurnToward( float yaw ) { + ideal_yaw = idMath::AngleNormalize180( yaw ); + bool result = FacingIdeal(); + return result; +} + +/* +===================== +idAI::TurnToward +===================== +*/ +bool idAI::TurnToward( const idVec3 &pos ) { + idVec3 dir; + idVec3 local_dir; + float lengthSqr; + + dir = pos - physicsObj.GetOrigin(); + physicsObj.GetGravityAxis().ProjectVector( dir, local_dir ); + local_dir.z = 0.0f; + lengthSqr = local_dir.LengthSqr(); + if ( lengthSqr > Square( 2.0f ) || ( lengthSqr > Square( 0.1f ) && enemy.GetEntity() == NULL ) ) { + ideal_yaw = idMath::AngleNormalize180( local_dir.ToYaw() ); + } + + bool result = FacingIdeal(); + return result; +} + +/*********************************************************************** + + Movement + +***********************************************************************/ + +/* +================ +idAI::ApplyImpulse +================ +*/ +void idAI::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { + // FIXME: Jim take a look at this and see if this is a reasonable thing to do + // instead of a spawnArg flag.. Sabaoth is the only slide monster ( and should be the only one for D3 ) + // and we don't want him taking physics impulses as it can knock him off the path + if ( move.moveType != MOVETYPE_STATIC && move.moveType != MOVETYPE_SLIDE ) { + idActor::ApplyImpulse( ent, id, point, impulse ); + } +} + +/* +===================== +idAI::GetMoveDelta +===================== +*/ +void idAI::GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta ) +{ + // Get the delta from the animation system (for one frame) and transform it + // animator.GetDelta( gameLocal.time - gameLocal.msec, gameLocal.time, delta); + + // angua: distance from last thinking time + animator.GetDelta( m_lastThinkTime, gameLocal.time, delta); + + delta = axis * delta; + + if ( modelOffset != vec3_zero ) + { + // the pivot of the monster's model is around its origin, and not around the bounding + // box's origin, so we have to compensate for this when the model is offset so that + // the monster still appears to rotate around its origin. + idVec3 oldModelOrigin = modelOffset * oldaxis; + idVec3 modelOrigin = modelOffset * axis; + + delta += oldModelOrigin - modelOrigin; + } + + delta *= physicsObj.GetGravityAxis(); +} + +/* +===================== +idAI::CheckObstacleAvoidance +===================== +*/ +void idAI::CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ) +{ + START_SCOPED_TIMING(aiObstacleAvoidanceTimer, scopedObstacleAvoidanceTimer); + + newPos = goalPos; // grayman #2345 - initialize newPos in case nothing changes. + // Without this, there's a return from this function + // that leaves newPos = [0,0,0], so the AI thinks he + // has to go to the world origin, which is a bug. + + if (ignore_obstacles || cv_ai_opt_noobstacleavoidance.GetBool()) + { + move.obstacle = NULL; + return; + } + + if (cv_ai_goalpos_show.GetBool()) + { + idVec4 color(colorCyan); + color.x = gameLocal.random.RandomFloat(); + color.y = gameLocal.random.RandomFloat(); + color.z = gameLocal.random.RandomFloat(); + gameRenderWorld->DebugArrow(color, goalPos, goalPos + idVec3(0,0,15), 2, 16); + } + + const idVec3& origin = physicsObj.GetOrigin(); + + idEntity* obstacle = NULL; + obstaclePath_t path; + + AI_OBSTACLE_IN_PATH = false; + bool foundPath = FindPathAroundObstacles( &physicsObj, aas, enemy.GetEntity(), origin, goalPos, path, this ); + + if ( ai_showObstacleAvoidance.GetBool()) + { + gameRenderWorld->DebugLine( colorBlue, goalPos + idVec3( 1.0f, 1.0f, 0.0f ), goalPos + idVec3( 1.0f, 1.0f, 64.0f ), gameLocal.msec ); + gameRenderWorld->DebugLine( foundPath ? colorYellow : colorRed, path.seekPos, path.seekPos + idVec3( 0.0f, 0.0f, 64.0f ), gameLocal.msec ); + } + + if (!foundPath) + { + // couldn't get around obstacles + + if (path.doorObstacle != NULL) + { + // We have a frobmover in our way, raise a signal to the current state + mind->GetState()->OnFrobDoorEncounter(path.doorObstacle); + } + + if (path.firstObstacle) + { + AI_OBSTACLE_IN_PATH = true; + + if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.firstObstacle->GetPhysics()->GetAbsBounds() ) ) + { + // We are already touching the first obstacle + obstacle = path.firstObstacle; + } + } + else if (path.startPosObstacle) + { + AI_OBSTACLE_IN_PATH = true; + if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.startPosObstacle->GetPhysics()->GetAbsBounds() ) ) + { + // We are touching the startpos obstacle + obstacle = path.startPosObstacle; + } + } + else + { + // No firstObstacle, no startPosObstacle, must be blocked by wall + move.moveStatus = MOVE_STATUS_BLOCKED_BY_WALL; + } +#if 0 + } else if ( path.startPosObstacle ) { + // check if we're past where the our origin was pushed out of the obstacle + dir = goalPos - origin; + dir.Normalize(); + dist = ( path.seekPos - origin ) * dir; + if ( dist < 1.0f ) { + AI_OBSTACLE_IN_PATH = true; + obstacle = path.startPosObstacle; + } +#endif + } + else + { + // We found a path around obstacles + if (path.doorObstacle != NULL) // grayman #2712 - do we have to handle a door? + { + // We have a frobmover in our way, raise a signal to the current state + mind->GetState()->OnFrobDoorEncounter(path.doorObstacle); + } + + // still check for the seekPosObstacle + if (path.seekPosObstacle) + { + /* gameRenderWorld->DebugBox(foundPath ? colorGreen : colorRed, idBox(path.seekPosObstacle->GetPhysics()->GetBounds(), + path.seekPosObstacle->GetPhysics()->GetOrigin(), + path.seekPosObstacle->GetPhysics()->GetAxis()), 16); + */ + + // greebo: Check if we have a frobdoor entity at our seek position + if (path.seekPosObstacle->IsType(CFrobDoor::Type)) + { + // We have a frobmover in our way, raise a signal to the current state + mind->GetState()->OnFrobDoorEncounter(static_cast(path.seekPosObstacle)); + } + + // if the AI is very close to the path.seekPos already and path.seekPosObstacle != NULL + // then we want to push the path.seekPosObstacle entity out of the way + AI_OBSTACLE_IN_PATH = true; + + // check if we're past where the goalPos was pushed out of the obstacle + idVec3 dir = goalPos - origin; + dir.NormalizeFast(); + float dist = (path.seekPos - origin) * dir; + if (dist < 1.0f) + { + obstacle = path.seekPosObstacle; + } + } + } + + // If we don't have an obstacle, set the seekpos and return + if (obstacle == NULL) + { + newPos = path.seekPos; + move.obstacle = NULL; + return; + } + + // if we had an obstacle, set our move status based on the type, and kick it out of the way if it's a moveable + if (obstacle->IsType(idActor::Type)) + { + // monsters aren't kickable + move.moveStatus = (obstacle == enemy.GetEntity()) ? MOVE_STATUS_BLOCKED_BY_ENEMY : MOVE_STATUS_BLOCKED_BY_MONSTER; + } + else + { + // If it's a door handle, switch the obstacle to the door so we don't get all hung + // up on door handles + if (obstacle->IsType(CFrobDoorHandle::Type)) + { + // Make the obstacle the door itself + obstacle = static_cast(obstacle)->GetDoor(); + } + + // Handle doors + if (obstacle->IsType(CFrobDoor::Type)) + { + // Try to open doors + CFrobDoor* p_door = static_cast(obstacle); + + // We have a frobmover in our way, raise a signal to the current state + mind->GetState()->OnFrobDoorEncounter(p_door); + } + + // Try backing away + newPos = obstacle->GetPhysics()->GetOrigin(); + idVec3 obstacleDelta = obstacle->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); + + obstacleDelta.NormalizeFast(); + obstacleDelta *= 128.0; + + newPos = obstacle->GetPhysics()->GetOrigin() - obstacleDelta; + move.moveStatus = MOVE_STATUS_BLOCKED_BY_OBJECT; + } + + move.obstacle = obstacle; +} + +/* +===================== +idAI::CanPassThroughDoor - Is the AI allowed through this door? (grayman #2691) +===================== +*/ + +bool idAI::CanPassThroughDoor(CFrobDoor* frobDoor) +{ + // grayman #2691 - quick test for spawnarg that appears on many furniture doors + + if (frobDoor->spawnArgs.GetBool("immune_to_target_setfrobable", "0")) + { + return false; + } + + // grayman #2691 - can't pass through doors that don't rotate on the z-axis + + idVec3 rotationAxis = frobDoor->GetRotationAxis(); + if ((rotationAxis.z == 0) && ((rotationAxis.x != 0) || (rotationAxis.y != 0))) // grayman #2712 - handles sliding doors + { + return false; + } + + idBounds door1Bounds = frobDoor->GetPhysics()->GetBounds(); + idBounds myBounds = GetPhysics()->GetBounds(); + idVec3 door1Size = door1Bounds.GetSize(); + idVec3 mySize = myBounds.GetSize(); + bool canPassDoor1 = (door1Size.x > mySize.x) || (door1Size.y > mySize.y); + if (canPassDoor1) + { + return true; + } + + // The AI can't fit through the first door. Is this door part of a double door? + + CFrobDoor* doubleDoor = frobDoor->GetDoubleDoor(); + if (doubleDoor != NULL) + { + idBounds door2Bounds = doubleDoor->GetPhysics()->GetBounds(); + idVec3 door2Size = door2Bounds.GetSize(); + bool canPassDoors = ((door1Size.x + door2Size.x) > mySize.x) || ((door1Size.y + door2Size.y) > mySize.y); + if (canPassDoors) + { + return true; + } + } + + return false; +} + +/* +===================== +idAI::GetTorch - Is the AI carrying a torch? (grayman #2603) +===================== +*/ + +idEntity* idAI::GetTorch() +{ + idEntity* ent = GetAttachmentByPosition("hand_l"); + if (ent && ent->spawnArgs.GetBool("is_torch","0")) + { + return ent; // found a torch + } + + // Torches are carried in the left hand. If a torch for + // the right hand, plus accompanying animations, is ever + // created, uncomment the following section. +/* + ent = GetAttachmentByPosition("hand_r"); + if (ent && ent->spawnArgs.GetBool("is_torch","0")) + { + return ent; // found a torch + } + */ + + return NULL; // no luck +} + +/* +===================== +idAI::DeadMove +===================== +*/ +void idAI::DeadMove( void ) { + idVec3 delta; + monsterMoveResult_t moveResult; + + idVec3 org = physicsObj.GetOrigin(); + + GetMoveDelta( viewAxis, viewAxis, delta ); + physicsObj.SetDelta( delta ); + + RunPhysics(); + + moveResult = physicsObj.GetMoveResult(); + AI_ONGROUND = physicsObj.OnGround(); +} + +/* +===================== +idAI::AnimMove +===================== +*/ +void idAI::AnimMove() +{ + START_SCOPED_TIMING(aiAnimMoveTimer, scopedAnimMoveTimer); + + idVec3 goalPos; + idVec3 goalDelta; + + idVec3 oldorigin = physicsObj.GetOrigin(); + idMat3 oldaxis = viewAxis; + + AI_BLOCKED = false; + + if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ + move.lastMoveOrigin.Zero(); + move.lastMoveTime = gameLocal.time; + } + + move.obstacle = NULL; + if (move.moveCommand == MOVE_FACE_ENEMY && enemy.GetEntity()) + { + TurnToward( lastVisibleEnemyPos ); + goalPos = oldorigin; + } + else if (move.moveCommand == MOVE_FACE_ENTITY && move.goalEntity.GetEntity()) + { + TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + goalPos = oldorigin; + } + else if (GetMovePos(goalPos)) + { + // greebo: We have a valid goalposition (not reached the target yet), check for obstacles + if (move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_VECTOR) + { + idVec3 newDest; + CheckObstacleAvoidance( goalPos, newDest ); + TurnToward(newDest); + } + else // MOVE_WANDER || MOVE_VECTOR + { + TurnToward(goalPos); + } + } + + // greebo: This should take care of rats running around in circles around their goal + // due to not turning fast enough to their goalPos, sending them into a stable orbit. + float oldTurnRate = turnRate; + + if ((goalPos - physicsObj.GetOrigin()).LengthSqr() < Square(50)) + { + turnRate *= gameLocal.random.RandomFloat() + 1; + } + + // greebo: Now actually turn towards the "ideal" yaw. + Turn(); + + // Revert the turnRate changes + turnRate = oldTurnRate; + + // Determine the delta depending on the move type + idVec3 delta(0,0,0); + if (move.moveCommand == MOVE_SLIDE_TO_POSITION) + { + if ( gameLocal.time < move.startTime + move.duration ) { + goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); + delta = goalPos - oldorigin; + delta.z = 0.0f; + } else { + delta = move.moveDest - oldorigin; + delta.z = 0.0f; + StopMove(MOVE_STATUS_DONE); + } + } + else if (allowMove) + { + // Moving is allowed, get the delta + GetMoveDelta( oldaxis, viewAxis, delta ); + } + + if ( move.moveCommand == MOVE_TO_POSITION ) { + goalDelta = move.moveDest - oldorigin; + float goalDist = goalDelta.LengthFast(); + if ( goalDist < delta.LengthFast() ) { + delta = goalDelta; + } + } + + physicsObj.SetDelta( delta ); + physicsObj.ForceDeltaMove( disableGravity ); + + { + START_SCOPED_TIMING(aiPhysicsTimer, scopedPhysicsTimer); + RunPhysics(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + } + + monsterMoveResult_t moveResult = physicsObj.GetMoveResult(); + if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { + DirectDamage( attack, enemy.GetEntity() ); + } else { + idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); + if ( blockEnt) + { + if (blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) + { + KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); + } + } + } + + BlockedFailSafe(); + + AI_ONGROUND = physicsObj.OnGround(); + + const idVec3& org = physicsObj.GetOrigin(); + if (oldorigin != org) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } +} + +/* +===================== +idAI::SittingMove +===================== +*/ +void idAI::SittingMove() +{ + idVec3 goalPos; + idVec3 goalDelta; + monsterMoveResult_t moveResult; + idVec3 newDest; + + idVec3 oldorigin = physicsObj.GetOrigin(); + idMat3 oldaxis = viewAxis; + + AI_BLOCKED = false; + + RunPhysics(); + + Turn(sitting_turn_pivot); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + } + + moveResult = physicsObj.GetMoveResult(); + + AI_ONGROUND = physicsObj.OnGround(); + + const idVec3& org = physicsObj.GetOrigin(); + if (oldorigin != org) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } +} + +void idAI::NoTurnMove() +{ + idVec3 oldorigin = physicsObj.GetOrigin(); + idMat3 oldaxis = viewAxis; + + AI_BLOCKED = false; + + RunPhysics(); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + } + + + AI_ONGROUND = physicsObj.OnGround(); + + const idVec3& org = physicsObj.GetOrigin(); + if (oldorigin != org) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } + +} + + + +void idAI::LayDownMove() +{ + idVec3 oldorigin(physicsObj.GetOrigin()); + idMat3 oldaxis(viewAxis); + + AI_BLOCKED = false; + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + } + + AI_ONGROUND = physicsObj.OnGround(); + + // angua: Let the animation move the origin onto the bed + idVec3 delta; + GetMoveDelta( oldaxis, viewAxis, delta ); + + physicsObj.SetDelta( delta ); + physicsObj.ForceDeltaMove( disableGravity ); + + RunPhysics(); + + const idVec3& org = physicsObj.GetOrigin(); + if (oldorigin != org) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } +} + + +/* +===================== +Seek +===================== +*/ +idVec3 Seek( idVec3 &vel, const idVec3 &org, const idVec3 &goal, float prediction ) { + idVec3 predictedPos; + idVec3 goalDelta; + idVec3 seekVel; + + // predict our position + predictedPos = org + vel * prediction; + goalDelta = goal - predictedPos; + seekVel = goalDelta * MS2SEC( gameLocal.msec ); + + return seekVel; +} + +/* +===================== +idAI::SlideMove +===================== +*/ +void idAI::SlideMove( void ) { + idVec3 goalPos; + idVec3 delta; + idVec3 goalDelta; + float goalDist; + monsterMoveResult_t moveResult; + idVec3 newDest; + + idVec3 oldorigin = physicsObj.GetOrigin(); + idMat3 oldaxis = viewAxis; + + AI_BLOCKED = false; + + if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ + move.lastMoveOrigin.Zero(); + move.lastMoveTime = gameLocal.time; + } + + move.obstacle = NULL; + if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { + TurnToward( lastVisibleEnemyPos ); + goalPos = move.moveDest; + } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { + TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + goalPos = move.moveDest; + } else if ( GetMovePos( goalPos ) ) { + CheckObstacleAvoidance( goalPos, newDest ); + TurnToward( newDest ); + goalPos = newDest; + } + + if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) { + if ( gameLocal.time < move.startTime + move.duration ) { + goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); + } else { + goalPos = move.moveDest; + StopMove( MOVE_STATUS_DONE ); + } + } + + if ( move.moveCommand == MOVE_TO_POSITION ) { + goalDelta = move.moveDest - oldorigin; + goalDist = goalDelta.LengthFast(); + if ( goalDist < delta.LengthFast() ) { + delta = goalDelta; + } + } + + idVec3 vel = physicsObj.GetLinearVelocity(); + float z = vel.z; + idVec3 predictedPos = oldorigin + vel * AI_SEEK_PREDICTION; + + // seek the goal position + goalDelta = goalPos - predictedPos; + vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); + vel += goalDelta * MS2SEC( gameLocal.msec ); + + // cap our speed + vel.Truncate( fly_speed ); + vel.z = z; + physicsObj.SetLinearVelocity( vel ); + physicsObj.UseVelocityMove( true ); + RunPhysics(); + + if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { + TurnToward( lastVisibleEnemyPos ); + } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { + TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + } else if ( move.moveCommand != MOVE_NONE ) { + if ( vel.ToVec2().LengthSqr() > 0.1f ) { + TurnToward( vel.ToYaw() ); + } + } + + Turn(); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + } + + moveResult = physicsObj.GetMoveResult(); + if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { + DirectDamage( attack, enemy.GetEntity() ); + } else { + idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); + if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { + KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); + } + } + + BlockedFailSafe(); + + AI_ONGROUND = physicsObj.OnGround(); + + idVec3 org = physicsObj.GetOrigin(); + if ( oldorigin != org ) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } +} + +/* +===================== +idAI::AdjustFlyingAngles +===================== +*/ +void idAI::AdjustFlyingAngles( void ) { + idVec3 vel; + float speed; + float roll; + float pitch; + + vel = physicsObj.GetLinearVelocity(); + + speed = vel.Length(); + if ( speed < 5.0f ) { + roll = 0.0f; + pitch = 0.0f; + } else { + roll = vel * viewAxis[ 1 ] * -fly_roll_scale / fly_speed; + if ( roll > fly_roll_max ) { + roll = fly_roll_max; + } else if ( roll < -fly_roll_max ) { + roll = -fly_roll_max; + } + + pitch = vel * viewAxis[ 2 ] * -fly_pitch_scale / fly_speed; + if ( pitch > fly_pitch_max ) { + pitch = fly_pitch_max; + } else if ( pitch < -fly_pitch_max ) { + pitch = -fly_pitch_max; + } + } + + fly_roll = fly_roll * 0.95f + roll * 0.05f; + fly_pitch = fly_pitch * 0.95f + pitch * 0.05f; + + if ( flyTiltJoint != INVALID_JOINT ) { + animator.SetJointAxis( flyTiltJoint, JOINTMOD_WORLD, idAngles( fly_pitch, 0.0f, fly_roll ).ToMat3() ); + } else { + viewAxis = idAngles( fly_pitch, current_yaw, fly_roll ).ToMat3(); + } +} + +/* +===================== +idAI::AddFlyBob +===================== +*/ +void idAI::AddFlyBob( idVec3 &vel ) { + idVec3 fly_bob_add; + float t; + + if ( fly_bob_strength ) { + t = MS2SEC( gameLocal.time + entityNumber * 497 ); + fly_bob_add = ( viewAxis[ 1 ] * idMath::Sin16( t * fly_bob_horz ) + viewAxis[ 2 ] * idMath::Sin16( t * fly_bob_vert ) ) * fly_bob_strength; + vel += fly_bob_add * MS2SEC( gameLocal.msec ); + if ( ai_debugMove.GetBool() ) { + const idVec3 &origin = physicsObj.GetOrigin(); + gameRenderWorld->DebugArrow( colorOrange, origin, origin + fly_bob_add, 0 ); + } + } +} + +/* +===================== +idAI::AdjustFlyHeight +===================== +*/ +void idAI::AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ) { + const idVec3 &origin = physicsObj.GetOrigin(); + predictedPath_t path; + idVec3 end; + idVec3 dest; + trace_t trace; + idActor *enemyEnt; + bool goLower; + + // make sure we're not flying too high to get through doors + goLower = false; + if ( origin.z > goalPos.z ) { + dest = goalPos; + dest.z = origin.z + 128.0f; + idAI::PredictPath( this, aas, goalPos, dest - origin, 1000, 1000, SE_BLOCKED, path ); + if ( path.endPos.z < origin.z ) { + idVec3 addVel = Seek( vel, origin, path.endPos, AI_SEEK_PREDICTION ); + vel.z += addVel.z; + goLower = true; + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugBounds( goLower ? colorRed : colorGreen, physicsObj.GetBounds(), path.endPos, gameLocal.msec ); + } + } + + if ( !goLower ) { + // make sure we don't fly too low + end = origin; + + enemyEnt = enemy.GetEntity(); + if ( enemyEnt ) { + end.z = lastVisibleEnemyPos.z + lastVisibleEnemyEyeOffset.z + fly_offset; + } else { + // just use the default eye height for the player + end.z = goalPos.z + DEFAULT_FLY_OFFSET + fly_offset; + } + + gameLocal.clip.Translation( trace, origin, end, physicsObj.GetClipModel(), mat3_identity, MASK_MONSTERSOLID, this ); + vel += Seek( vel, origin, trace.endpos, AI_SEEK_PREDICTION ); + } +} + +/* +===================== +idAI::FlySeekGoal +===================== +*/ +void idAI::FlySeekGoal( idVec3 &vel, idVec3 &goalPos ) { + idVec3 seekVel; + + // seek the goal position + seekVel = Seek( vel, physicsObj.GetOrigin(), goalPos, AI_SEEK_PREDICTION ); + seekVel *= fly_seek_scale; + vel += seekVel; +} + +/* +===================== +idAI::AdjustFlySpeed +===================== +*/ +void idAI::AdjustFlySpeed( idVec3 &vel ) { + float speed; + + // apply dampening + vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); + + // gradually speed up/slow down to desired speed + speed = vel.Normalize(); + speed += ( move.speed - speed ) * MS2SEC( gameLocal.msec ); + if ( speed < 0.0f ) { + speed = 0.0f; + } else if ( move.speed && ( speed > move.speed ) ) { + speed = move.speed; + } + + vel *= speed; +} + +/* +===================== +idAI::FlyTurn +===================== +*/ +void idAI::FlyTurn( void ) { + if ( move.moveCommand == MOVE_FACE_ENEMY ) { + TurnToward( lastVisibleEnemyPos ); + } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { + TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + } else if ( move.speed > 0.0f ) { + const idVec3 &vel = physicsObj.GetLinearVelocity(); + if ( vel.ToVec2().LengthSqr() > 0.1f ) { + TurnToward( vel.ToYaw() ); + } + } + Turn(); +} + +/* +===================== +idAI::FlyMove +===================== +*/ +void idAI::FlyMove( void ) { + idVec3 goalPos; + idVec3 oldorigin; + idVec3 newDest; + + AI_BLOCKED = false; + if ( ( move.moveCommand != MOVE_NONE ) && ReachedPos( move.moveDest, move.moveCommand ) ) { + StopMove( MOVE_STATUS_DONE ); + } + + if ( ai_debugMove.GetBool() ) { + gameLocal.Printf( "%d: %s: %s, vel = %.2f, sp = %.2f, maxsp = %.2f\n", gameLocal.time, name.c_str(), moveCommandString[ move.moveCommand ], physicsObj.GetLinearVelocity().Length(), move.speed, fly_speed ); + } + + if ( move.moveCommand != MOVE_TO_POSITION_DIRECT ) { + idVec3 vel = physicsObj.GetLinearVelocity(); + + if ( GetMovePos( goalPos ) ) { + CheckObstacleAvoidance( goalPos, newDest ); + goalPos = newDest; + } + + if ( move.speed ) { + FlySeekGoal( vel, goalPos ); + } + + // add in bobbing + AddFlyBob( vel ); + + if ( enemy.GetEntity() && ( move.moveCommand != MOVE_TO_POSITION ) ) { + AdjustFlyHeight( vel, goalPos ); + } + + AdjustFlySpeed( vel ); + + physicsObj.SetLinearVelocity( vel ); + } + + // turn + FlyTurn(); + + // run the physics for this frame + oldorigin = physicsObj.GetOrigin(); + physicsObj.UseFlyMove( true ); + physicsObj.UseVelocityMove( false ); + physicsObj.SetDelta( vec3_zero ); + physicsObj.ForceDeltaMove( disableGravity ); + RunPhysics(); + + monsterMoveResult_t moveResult = physicsObj.GetMoveResult(); + if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { + DirectDamage( attack, enemy.GetEntity() ); + } else { + idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); + if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { + KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); + } else if ( moveResult == MM_BLOCKED ) { + move.blockTime = gameLocal.time + 500; + AI_BLOCKED = true; + } + } + + idVec3 org = physicsObj.GetOrigin(); + if ( oldorigin != org ) { + TouchTriggers(); + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 4000 ); + gameRenderWorld->DebugBounds( colorOrange, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); + gameRenderWorld->DebugLine( colorRed, org, org + physicsObj.GetLinearVelocity(), gameLocal.msec, true ); + gameRenderWorld->DebugLine( colorBlue, org, goalPos, gameLocal.msec, true ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + DrawRoute(); + } +} + +/* +===================== +idAI::StaticMove +===================== +*/ +void idAI::StaticMove( void ) { + idActor *enemyEnt = enemy.GetEntity(); + + if ( AI_DEAD || AI_KNOCKEDOUT ) { + return; + } + + if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemyEnt ) { + TurnToward( lastVisibleEnemyPos ); + } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { + TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + } else if ( move.moveCommand != MOVE_NONE ) { + TurnToward( move.moveDest ); + } + Turn(); + + physicsObj.ForceDeltaMove( true ); // disable gravity + RunPhysics(); + + AI_ONGROUND = false; + + if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { + DirectDamage( attack, enemyEnt ); + } + + if ( ai_debugMove.GetBool() ) { + const idVec3 &org = physicsObj.GetOrigin(); + gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); + gameRenderWorld->DebugLine( colorBlue, org, move.moveDest, gameLocal.msec, true ); + gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + } +} + +void idAI::Bark(const idStr& soundName) +{ + + // Allocate a singlebarktask with the given sound and enqueue it + commSubsystem->AddCommTask( + ai::CommunicationTaskPtr(new ai::SingleBarkTask(soundName)) + ); +} + +void idAI::PlayFootStepSound() +{ + idStr moveType, localSound, sound; + idMaterial *material = NULL; + const idSoundShader *sndShader = NULL; + + if ( !GetPhysics()->HasGroundContacts() ) { + return; + } + + // greebo: Don't play footsteps in ragdoll mode + if (!GetPhysics()->IsType(idPhysics_Actor::Type)) + { + return; + } + + // DarkMod: make the string to identify the movement speed (crouch_run, creep, etc) + // Currently only players have movement flags set up this way, not AI. We could change that later. + moveType.Clear(); + + if (AI_CROUCH) + { + moveType = "_crouch"; + } + + if (AI_RUN) + { + moveType += "_run"; + } + else if (AI_CREEP) + { + moveType += "_creep"; + } + else + { + moveType += "_walk"; + } + + // start footstep sound based on material type + material = const_cast(GetPhysics()->GetContact(0).material); + localSound = ""; // grayman #2787 + if (material != NULL) + { + g_Global.GetSurfName(material, localSound); + localSound = "snd_footstep_" + localSound; +// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 + } + + waterLevel_t waterLevel = static_cast(GetPhysics())->GetWaterLevel(); + // If player is walking in liquid, replace the bottom surface sound with water sounds + if (waterLevel == WATERLEVEL_FEET ) + { + localSound = "snd_footstep_puddle"; +// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 + } + else if (waterLevel == WATERLEVEL_WAIST) + { + localSound = "snd_footstep_wading"; +// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 + } + // greebo: Added this to disable the walking sound when completely underwater + // this should be replaced by snd_ + else if (waterLevel == WATERLEVEL_HEAD) + { + localSound = "snd_footstep_swim"; +// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 + } + + if ( localSound.IsEmpty() && ( waterLevel != WATERLEVEL_HEAD ) ) // grayman #2787 + { + localSound = "snd_footstep"; + } + + sound = spawnArgs.GetString( localSound.c_str() ); + +/* grayman #2787 - redundant + + // if a sound was not found for that specific material, use default + if ( sound.IsEmpty() && ( waterLevel != WATERLEVEL_HEAD ) ) + { + sound = spawnArgs.GetString( "snd_footstep" ); + localSound = "snd_footstep"; + } + */ + + /*** + * AI footsteps always propagate as snd_footstep for now + * If we want to add in AI soundprop based on movement speed later, + * here is the place to do it. + **/ +/* + localSound += moveType; + if( !gameLocal.m_sndProp->CheckSound( localSound.c_str(), false ) ) + localSound -= moveType; +*/ + + if ( !sound.IsEmpty() ) + { + // apply the movement type modifier to the volume + sndShader = declManager->FindSound( sound.c_str() ); + SetSoundVolume( sndShader->GetParms()->volume + GetMovementVolMod() ); + StartSoundShader( sndShader, SND_CHANNEL_BODY, 0, false, NULL ); + SetSoundVolume( 0.0f ); + + // propagate the suspicious sound to other AI + PropSoundDirect( localSound, true, false ); + } +} + +/*********************************************************************** + + Damage + +***********************************************************************/ + +/* +===================== +idAI::ReactionTo + +DarkMod : Added call to AI Relationship Manager + We don't have to hardcode this, could be done + with scripts, but for now it's hardcoded for + testing purposes. +===================== +*/ +int idAI::ReactionTo( const idEntity *ent ) +{ + if ( ent->fl.hidden ) + { + // ignore hidden entities + return ATTACK_IGNORE; + } + + if ( !ent->IsType( idActor::Type ) ) { + return ATTACK_IGNORE; + } + + const idActor *actor = static_cast( ent ); + if ( actor->IsType( idPlayer::Type ) && static_cast(actor)->noclip ) { + // ignore players in noclip mode + return ATTACK_IGNORE; + } + + // actors will always fight if their teams are enemies + if ( IsEnemy(actor) ) + { + if ( actor->fl.notarget ) + { + // don't attack on sight when attacker is notargeted + return ATTACK_ON_DAMAGE | ATTACK_ON_ACTIVATE; + } + return ATTACK_ON_SIGHT | ATTACK_ON_DAMAGE | ATTACK_ON_ACTIVATE; + } + + // monsters will fight when attacked by lower ranked monsters. rank 0 never fights back. + if ( rank && ( actor->rank < rank ) ) { + return ATTACK_ON_DAMAGE; + } + + // don't fight back + return ATTACK_IGNORE; +} + + +/* +===================== +idAI::Pain +===================== +*/ +bool idAI::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ) +{ + AI_PAIN = idActor::Pain( inflictor, attacker, damage, dir, location, damageDef ); + AI_DAMAGE = true; + + // force a blink + blink_time = 0; + + // ignore damage from self + if ( attacker != this ) + { + if ( inflictor ) + { + AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); + } else + { + AI_SPECIAL_DAMAGE = 0; + } + + // AI don't like being attacked + ChangeEntityRelation(attacker, -10); + + // Switch to pain state if idle + if (AI_AlertIndex == 0 && damage > 0 && + (damageDef == NULL || !damageDef->GetBool("no_pain_anim", "0"))) + { + GetMind()->PushState(ai::StatePtr(new ai::PainState)); + } + } + + return ( AI_PAIN != 0 ); +} + + +/* +===================== +idAI::SpawnParticles +===================== +*/ +void idAI::SpawnParticles( const char *keyName ) { + const idKeyValue *kv = spawnArgs.MatchPrefix( keyName, NULL ); + while ( kv ) { + particleEmitter_t pe; + + idStr particleName = kv->GetValue(); + + if ( particleName.Length() ) { + + idStr jointName = kv->GetValue(); + int dash = jointName.Find('-'); + if ( dash > 0 ) { + particleName = particleName.Left( dash ); + jointName = jointName.Right( jointName.Length() - dash - 1 ); + } + + SpawnParticlesOnJoint( pe, particleName, jointName ); + particles.Append( pe ); + } + + kv = spawnArgs.MatchPrefix( keyName, kv ); + } +} + +/* +===================== +idAI::SpawnParticlesOnJoint +===================== +*/ +const idDeclParticle *idAI::SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName ) { + idVec3 origin; + idMat3 axis; + + if ( *particleName == '\0' ) { + memset( &pe, 0, sizeof( pe ) ); + return pe.particle; + } + + pe.joint = animator.GetJointHandle( jointName ); + if ( pe.joint == INVALID_JOINT ) { + gameLocal.Warning( "Unknown particleJoint '%s' on '%s'", jointName, name.c_str() ); + pe.time = 0; + pe.particle = NULL; + } else { + animator.GetJointTransform( pe.joint, gameLocal.time, origin, axis ); + origin = renderEntity.origin + origin * renderEntity.axis; + + BecomeActive( TH_UPDATEPARTICLES ); + if ( !gameLocal.time ) { + // particles with time of 0 don't show, so set the time differently on the first frame + pe.time = 1; + } else { + pe.time = gameLocal.time; + } + pe.particle = static_cast( declManager->FindType( DECL_PARTICLE, particleName ) ); + gameLocal.smokeParticles->EmitSmoke( pe.particle, pe.time, gameLocal.random.CRandomFloat(), origin, axis ); + } + + return pe.particle; +} + +/* +===================== +idAI::Killed +===================== +*/ +void idAI::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) +{ + idAngles ang; + const char *modelDeath; + bool bPlayerResponsible(false); + + // make sure the monster is activated + EndAttack(); + + if ( g_debugDamage.GetBool() ) { + gameLocal.Printf( "Damage: joint: '%s', zone '%s'\n", animator.GetJointName( ( jointHandle_t )location ), + GetDamageGroup( location ) ); + } + + if ( inflictor ) { + AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); + } else { + AI_SPECIAL_DAMAGE = 0; + } + + if ( AI_DEAD ) { + AI_PAIN = true; + AI_DAMAGE = true; + return; + } + + // stop all voice sounds + StopSound( SND_CHANNEL_VOICE, false ); + if ( head.GetEntity() ) { + head.GetEntity()->StopSound( SND_CHANNEL_VOICE, false ); + head.GetEntity()->GetAnimator()->ClearAllAnims( gameLocal.time, 100 ); + } + + disableGravity = false; + move.moveType = MOVETYPE_DEAD; + m_bAFPushMoveables = false; + + physicsObj.UseFlyMove( false ); + physicsObj.ForceDeltaMove( false ); + + // end our looping ambient sound + StopSound( SND_CHANNEL_AMBIENT, false ); + + // activate targets + ActivateTargets( attacker ); + + RemoveAttachments(); + RemoveProjectile(); + StopMove( MOVE_STATUS_DONE ); + GetMemory().stopRelight = true; // grayman #2603 - abort a relight in progress + GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope + + ClearEnemy(); + AI_DEAD = true; + + // make monster nonsolid + if (spawnArgs.GetBool("nonsolid_on_ragdoll", "1")) + { + physicsObj.SetContents(0); + physicsObj.GetClipModel()->Unlink(); + } + + Unbind(); + + idStr deathSound = MouthIsUnderwater() ? "snd_death_liquid" : "snd_death"; + + StartSound( deathSound.c_str(), SND_CHANNEL_VOICE, 0, false, NULL ); + + // Go to ragdoll mode immediately, if we don't have a death anim + // If death anims are enabled, we need to wait with going to ragdoll until PostKilled() + if (!spawnArgs.GetBool("enable_death_anim", "0")) + { + StartRagdoll(); + } + + // swaps the head CM back if a different one was swapped in while conscious + SwapHeadAFCM( false ); + + if ( spawnArgs.GetString( "model_death", "", &modelDeath ) ) { + // lost soul is only case that does not use a ragdoll and has a model_death so get the death sound in here + StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + SetModel( modelDeath ); + physicsObj.SetLinearVelocity( vec3_zero ); + physicsObj.PutToRest(); + physicsObj.DisableImpact(); + } + + if (spawnArgs.GetBool("set_frobable_on_death", "1")) + { + // AI becomes frobable on death + // greebo: Add a delay before the AI becomes actually frobable + PostEventMS(&EV_SetFrobable, 750, 1); + } + + restartParticles = false; + + mind->ClearStates(); + mind->PushState(STATE_DEAD); + + // drop items + DropOnRagdoll(); + + if ( attacker && (attacker == gameLocal.GetLocalPlayer()) && inflictor ) + { + bPlayerResponsible = true; + } + else if ( attacker && attacker->m_SetInMotionByActor.GetEntity() ) + { + bPlayerResponsible = ( ( attacker != gameLocal.world ) && + ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ) ); + } + + // grayman #2908 - we need to know if the AI stepped on a player-tossed mine. + // So that we don't interfere with existing situations, check specifically + // for the mine. The previous two checked to determine player responsibility + // say the player is NOT responsible, when the inflictor is a mine. + + if ( !bPlayerResponsible ) + { + if ( inflictor && inflictor->IsType(idProjectile::Type) ) + { + idProjectile* proj = static_cast(inflictor); + if ( proj->IsMine() ) + { + bPlayerResponsible = ( inflictor->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); + } + } + } + + // Update TDM objective system + gameLocal.m_MissionData->MissionEvent( COMP_KILL, this, attacker, bPlayerResponsible ); + // Mark the body as last moved by the player + if( bPlayerResponsible ) + m_MovedByActor = gameLocal.GetLocalPlayer(); + + // greebo: Set the lipsync flag to FALSE, we're dead + m_lipSyncActive = false; + + DropBlood(inflictor); +} + +void idAI::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision) +{ + // Save the current health, to see afterwards how much damage we've been taking + int preHitHealth = health; + + idActor::Damage(inflictor, attacker, dir, damageDefName, damageScale, location, collision); + + // grayman #2478 - allowed idActor::Damage if dead, for physics reasons. + // Nothing beyond here is needed for AI that were dead when idAI::Damage() + // was called. + + if (preHitHealth <= 0) + { + return; + } + + if (inflictor != NULL && inflictor->IsType(idProjectile::Type)) + { + int damageTaken = preHitHealth - health; + + // Send a signal to the current state that we've been hit by something + GetMind()->GetState()->OnProjectileHit(static_cast(inflictor), attacker, damageTaken); + } + + if (attacker != NULL && IsEnemy(attacker)) + { + GetMemory().hasBeenAttackedByEnemy = true; + } +} + +void idAI::DropBlood(idEntity *inflictor) +{ + if ( inflictor && spawnArgs.GetBool("bleed","0") ) // grayman #2931 + { + idStr damageDefName = inflictor->spawnArgs.RandomPrefix("def_damage", gameLocal.random); + + const idDeclEntityDef *def = gameLocal.FindEntityDef(damageDefName, false); + if ( def == NULL ) + { + return; + } + + // blood splats are thrown onto nearby surfaces + idStr splat = def->dict.RandomPrefix("mtr_killed_splat", gameLocal.random); + + if (!splat.IsEmpty()) + { + SpawnBloodMarker(splat, splat + "_fading", 40); + } + } +} + + +void idAI::SpawnBloodMarker(const idStr& splat, const idStr& splatFading, float size) +{ + trace_t result; + gameLocal.clip.TracePoint(result, GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin() + 60 * idVec3(0, 0, -1), MASK_OPAQUE, this); + + idVec3 markerOrigin = result.endpos + idVec3(0, 0, 2); + + const idDict* markerDef = gameLocal.FindEntityDefDict("atdm:blood_marker", false); + + if (markerDef == NULL) + { + gameLocal.Error( "Failed to find definition of blood marker entity " ); + return; + } + + idEntity* ent; + gameLocal.SpawnEntityDef(*markerDef, &ent, false); + + if (!ent || !ent->IsType(CBloodMarker::Type)) + { + gameLocal.Error( "Failed to spawn blood marker entity" ); + return; + } + + CBloodMarker* bloodMarker = static_cast(ent); + bloodMarker->SetOrigin(markerOrigin); + bloodMarker->Init(splat, splatFading, size); + bloodMarker->Event_GenerateBloodSplat(); +} + + +/* +===================== +idAI::PostDeath +===================== +*/ +void idAI::PostDeath() +{ + // For death anims, we need to wait with going to ragdoll until here + if (spawnArgs.GetBool("enable_death_anim", "0")) + { + // Start going to ragdoll here, instead of in Killed() to enable death anims + StartRagdoll(); + } + + headAnim.StopAnim(1); + legsAnim.StopAnim(1); + torsoAnim.StopAnim(1); + + headAnim.Disable(); + legsAnim.Disable(); + torsoAnim.Disable(); +} + +/*********************************************************************** + + Targeting/Combat + +***********************************************************************/ + +/* +===================== +idAI::PlayCinematic +===================== +*/ +void idAI::PlayCinematic( void ) { + const char *animname; + + if ( current_cinematic >= num_cinematics ) { + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); + } + if ( !spawnArgs.GetBool( "cinematic_no_hide" ) ) { + Hide(); + } + current_cinematic = 0; + ActivateTargets( gameLocal.GetLocalPlayer() ); + fl.neverDormant = false; + + return; + } + + Show(); + current_cinematic++; + + allowJointMod = false; + allowEyeFocus = false; + + spawnArgs.GetString( va( "anim%d", current_cinematic ), NULL, &animname ); + if ( !animname ) { + gameLocal.Warning( "missing 'anim%d' key on %s", current_cinematic, name.c_str() ); + return; + } + + if ( g_debugCinematic.GetBool() ) { + gameLocal.Printf( "%d: '%s' start '%s'\n", gameLocal.framenum, GetName(), animname ); + } + + headAnim.animBlendFrames = 0; + headAnim.lastAnimBlendFrames = 0; + headAnim.BecomeIdle(); + + legsAnim.animBlendFrames = 0; + legsAnim.lastAnimBlendFrames = 0; + legsAnim.BecomeIdle(); + + torsoAnim.animBlendFrames = 0; + torsoAnim.lastAnimBlendFrames = 0; + ProcessEvent( &AI_PlayAnim, ANIMCHANNEL_TORSO, animname ); + + // make sure our model gets updated + animator.ForceUpdate(); + + // update the anim bounds + UpdateAnimation(); + UpdateVisuals(); + Present(); + + if ( head.GetEntity() ) { + // since the body anim was updated, we need to run physics to update the position of the head + RunPhysics(); + + // make sure our model gets updated + head.GetEntity()->GetAnimator()->ForceUpdate(); + + // update the anim bounds + head.GetEntity()->UpdateAnimation(); + head.GetEntity()->UpdateVisuals(); + head.GetEntity()->Present(); + } + + + fl.neverDormant = true; + +} + +/* +===================== +idAI::Activate + +Notifies the script that a monster has been activated by a trigger or flashlight + +DarkMod: Commented out calls to SetEnemy. We don't want the AI calling setEnemy, +only the alert state scripts. +===================== +*/ +void idAI::Activate( idEntity *activator ) +{ + // Fire the TRIGGER response + TriggerResponse(activator, ST_TRIGGER); + + if ( AI_DEAD || AI_KNOCKEDOUT ) { + // ignore it when they're dead or KO'd + return; + } + + // make sure he's not dormant + dormantStart = 0; + + if ( num_cinematics ) { + PlayCinematic(); + } else { + AI_ACTIVATED = true; + + /*idPlayer *player; + if ( !activator || !activator->IsType( idPlayer::Type ) ) { + player = gameLocal.GetLocalPlayer(); + } else { + player = static_cast( activator ); + } + + if ( ReactionTo( player ) & ATTACK_ON_ACTIVATE ) + { + //SetEnemy( player ); + }*/ + + // update the script in cinematics so that entities don't start anims or show themselves a frame late. + if ( cinematic ) { + UpdateScript(); + + // make sure our model gets updated + animator.ForceUpdate(); + + // update the anim bounds + UpdateAnimation(); + UpdateVisuals(); + Present(); + + if ( head.GetEntity() ) { + // since the body anim was updated, we need to run physics to update the position of the head + RunPhysics(); + + // make sure our model gets updated + head.GetEntity()->GetAnimator()->ForceUpdate(); + + // update the anim bounds + head.GetEntity()->UpdateAnimation(); + head.GetEntity()->UpdateVisuals(); + head.GetEntity()->Present(); + } + } + } +} + +/* +===================== +idAI::EnemyDead +===================== +*/ +void idAI::EnemyDead( void ) { + ClearEnemy(); +} + +/* +===================== +idAI::TalkTo +===================== +*/ +void idAI::TalkTo( idActor *actor ) { + if ( talk_state != TALK_OK ) { + return; + } + + talkTarget = actor; + if ( actor ) { + AI_TALK = true; + } else { + AI_TALK = false; + } +} + +/* +===================== +idAI::GetEnemy +===================== +*/ +idActor *idAI::GetEnemy( void ) const { + return enemy.GetEntity(); +} + +/* +===================== +idAI::GetTalkState +===================== +*/ +talkState_t idAI::GetTalkState( void ) const { + if ( ( talk_state != TALK_NEVER ) && AI_DEAD ) { + return TALK_DEAD; + } + if ( IsHidden() ) { + return TALK_NEVER; + } + return talk_state; +} + +/* +===================== +idAI::TouchedByFlashlight +===================== +*/ +void idAI::TouchedByFlashlight( idActor *flashlight_owner ) { + if ( wakeOnFlashlight ) { + Activate( flashlight_owner ); + } +} + +/* +===================== +idAI::ClearEnemy +===================== +*/ +void idAI::ClearEnemy( void ) { + if ( move.moveCommand == MOVE_TO_ENEMY ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + } + + // grayman #2887 - log the amount of time you saw the player. + // This is normally taken care of in UpdateEnemyPosition(), but we need + // to check here in case the AI is killed or KO'ed and doesn't + // use the normal logging code there. + + if ( AI_ENEMY_VISIBLE ) + { + if ( ( enemy.GetEntity() != NULL ) && ( enemy.GetEntity()->IsType(idPlayer::Type) ) ) + { + if ( lastTimePlayerLost < 0 ) // = -1 if the player was never seen or seen but not lost at this point + { + lastTimePlayerLost = gameLocal.time; + if ( lastTimePlayerSeen > 0 ) + { + gameLocal.m_MissionData->Add2TimePlayerSeen(lastTimePlayerLost - lastTimePlayerSeen); + } + lastTimePlayerSeen = -1; + } + } + } + + enemyNode.Remove(); + enemy = NULL; + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; +} + +/* +===================== +idAI::EnemyPositionValid +===================== +*/ +bool idAI::EnemyPositionValid( void ) const { + trace_t tr; + idVec3 muzzle; + idMat3 axis; + + if ( !enemy.GetEntity() ) { + return false; + } + + if ( AI_ENEMY_VISIBLE ) { + return true; + } + + gameLocal.clip.TracePoint( tr, GetEyePosition(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, MASK_OPAQUE, this ); + if ( tr.fraction < 1.0f ) { + // can't see the area yet, so don't know if he's there or not + return true; + } + + return false; +} + +/* +===================== +idAI::SetEnemyPosition +===================== +*/ +void idAI::SetEnemyPosition() +{ + idActor* enemyEnt = enemy.GetEntity(); + + if (enemyEnt == NULL) + { + return; + } + + int enemyAreaNum; + int areaNum; + int lastVisibleReachableEnemyAreaNum = -1; + aasPath_t path; + idVec3 pos; + bool onGround; + + lastVisibleReachableEnemyPos = lastReachableEnemyPos; + lastVisibleEnemyEyeOffset = enemyEnt->EyeOffset(); + lastVisibleEnemyPos = enemyEnt->GetPhysics()->GetOrigin(); + + if (move.moveType == MOVETYPE_FLY) + { + // Flying AI assume the enemy to be always on ground + pos = lastVisibleEnemyPos; + onGround = true; + } + else + { + // For non-flying AI, check if the enemy is on the ground + onGround = enemyEnt->GetFloorPos(64.0f, pos); + + if (enemyEnt->OnLadder()) // greebo: TODO: What about ropes? + { + onGround = false; + } + } + + // greebo: "pos" now holds the enemy position used for pathing (floor pos or visible pos) + + if (!onGround) + { + // greebo: The AI considers a non-grounded entity to be unreachable + // TODO: Check for climb height? The enemy might still be reachable? + if (move.moveCommand == MOVE_TO_ENEMY) + { + AI_DEST_UNREACHABLE = true; + } + return; + } + + if (aas != NULL) + { + // We have a valid AAS attached, try to reach the enemy + + // The default reachable area number is taken from the move command + lastVisibleReachableEnemyAreaNum = move.toAreaNum; + + // Get the area number of the point the enemy has last been seen in (== enemy origin) + enemyAreaNum = PointReachableAreaNum(lastVisibleEnemyPos, 1.0f); + + // If the area number is invalid, try to look it up again using the REACHABLE position + if (!enemyAreaNum) + { + enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); + pos = lastReachableEnemyPos; + } + + // Do we have a valid area number now? + if (enemyAreaNum) + { + // We have a valid enemy area number + + // Get the own origin and area number + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum(org); + + // Try to set up a walk/fly path to the enemy + if (PathToGoal(path, areaNum, org, enemyAreaNum, pos, this)) + { + // Succeeded, we have a visible and reachable enemy position + lastVisibleReachableEnemyPos = pos; + lastVisibleReachableEnemyAreaNum = enemyAreaNum; + + if (move.moveCommand == MOVE_TO_ENEMY) + { + // Enemy is reachable + AI_DEST_UNREACHABLE = false; + } + } + else if (move.moveCommand == MOVE_TO_ENEMY) + { + // No path to goal available, enemy is unreachable + AI_DEST_UNREACHABLE = true; + } + } + else + { + // The area number lookup failed, fallback to unreachable + if (move.moveCommand == MOVE_TO_ENEMY) + { + AI_DEST_UNREACHABLE = true; + } + areaNum = 0; + } + } + else + { + // We don't have a valid AAS, we can't tell if an enemy is reachable or not, + // so just assume that he is. + lastVisibleReachableEnemyPos = lastVisibleEnemyPos; + if (move.moveCommand == MOVE_TO_ENEMY) + { + AI_DEST_UNREACHABLE = false; + } + enemyAreaNum = 0; + areaNum = 0; + } + + // General move command update + if (move.moveCommand == MOVE_TO_ENEMY) + { + if (!aas) + { + // Invalid AAS keep the move destination up to date for wandering + move.moveDest = lastVisibleReachableEnemyPos; + } + else if (enemyAreaNum) + { + // The previous pathing attempt succeeded, update the move command + move.toAreaNum = lastVisibleReachableEnemyAreaNum; + move.moveDest = lastVisibleReachableEnemyPos; + } + + if (move.moveType == MOVETYPE_FLY) + { + predictedPath_t path; + idVec3 end = move.moveDest; + end.z += enemyEnt->EyeOffset().z + fly_offset; + idAI::PredictPath( this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path ); + move.moveDest = path.endPos; + move.toAreaNum = PointReachableAreaNum( move.moveDest, 1.0f ); + } + } +} + +bool idAI::EntityInAttackCone(idEntity* ent) +{ + float attack_cone; + idVec3 delta; + float yaw; + float relYaw; + + if ( !ent ) { + return false; + } + + delta = ent->GetPhysics()->GetOrigin() - GetEyePosition(); + + // get our gravity normal + const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); + + // infinite vertical vision, so project it onto our orientation plane + delta -= gravityDir * ( gravityDir * delta ); + + delta.Normalize(); + yaw = delta.ToYaw(); + + attack_cone = spawnArgs.GetFloat( "attack_cone", "70" ); + relYaw = idMath::AngleNormalize180( ideal_yaw - yaw ); + + return ( idMath::Fabs( relYaw ) < ( attack_cone * 0.5f ) ); +} + +bool idAI::CanHitEntity(idActor* entity, ECombatType combatType) +{ + if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0) + return false; + + if (combatType == COMBAT_MELEE) + { + return TestMelee(); + } + else if (combatType == COMBAT_RANGED) + { + return TestRanged(); + } + else + { + if (GetNumRangedWeapons() > 0) + { + return TestRanged(); + } + else if (GetNumMeleeWeapons() > 0) + { + return TestMelee(); + } + } + + return false; +} + +bool idAI::WillBeAbleToHitEntity(idActor* entity, ECombatType combatType) +{ + if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0) + return false; + + if (combatType == COMBAT_MELEE) + { + return TestMeleeFuture(); + } + else if (combatType == COMBAT_RANGED) + { + // not supported for ranged combat + return false; + } + else + { + if (GetNumRangedWeapons() > 0) + { + return false; + } + else if (GetNumMeleeWeapons() > 0) + { + return TestMeleeFuture(); + } + } + + return false; +} + +bool idAI::CanBeHitByEntity(idActor* entity, ECombatType combatType) +{ + if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0 ) + return false; + + if (combatType == COMBAT_MELEE) + { + if ( !entity->GetAttackFlag(COMBAT_MELEE) + || !entity->melee_range ) + return false; + + const idVec3& org = physicsObj.GetOrigin(); + const idBounds& bounds = physicsObj.GetBounds(); + + const idVec3& enemyOrg = entity->GetPhysics()->GetOrigin(); + const idBounds& enemyBounds = entity->GetPhysics()->GetBounds(); + + idVec3 ourVel = physicsObj.GetLinearVelocity(); + idVec3 enemyVel = entity->GetPhysics()->GetLinearVelocity(); + idVec3 relVel = enemyVel - ourVel; + float velDot = ourVel * enemyVel; + + idVec3 dir = enemyOrg - org; + dir.z = 0; + float dist = dir.LengthFast(); + + float enemyReach = entity->melee_range; + + // generic factor to increase the enemy's threat range (accounts for sudden, quick advances) + // (TODO: Make spawnwarg?) + float threatFactor = 1.5f; + // velocity-based factor to increase the enemy's threat range + float velFactor; + if( velDot > 0 ) + { + // enemy moving away + velFactor = 1.0f; + } + else + { + // TODO: Make spawnargs? + // max speed of 20 MPH + float maxVel = 352; + float maxThreatInc = 3.0; + + velFactor = idMath::ClampFloat(1.0f, maxThreatInc, 1.0f + (maxThreatInc-1.0f)*relVel.LengthFast()/maxVel); + } + + enemyReach *= threatFactor * velFactor; + + float maxdist = enemyReach + bounds[1][0]; + + if (dist < maxdist) + { + // within horizontal distance + if (((enemyOrg.z + enemyBounds[1].z + entity->melee_range_vert) > org.z) && ((org.z + bounds[1].z) > enemyOrg.z)) // grayman #2655 - use enemy's origin, not your own, and use melee_range_vert +// if (((org.z + enemyBounds[1][2] + entity->melee_range) > org.z) && (org.z + bounds[1][2]) > enemyOrg.z) // grayman #2655 - old way + { + // within height + // don't bother with trace for this test + return true; + } + } + + return false; + } + else if (combatType == COMBAT_RANGED) + { + return false; // NYI + } + else + return false; +} + +void idAI::UpdateAttachmentContents(bool makeSolid) +{ + // ishtvan: Modified to work only with AF body representing the entity + for (int i = 0; i < m_Attachments.Num(); i++) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL || !m_Attachments[i].ent.IsValid()) continue; + + if (!ent->IsType(CMeleeWeapon::Type) && !ent->m_bAttachedAlertControlsSolidity) + continue; + + // Found a melee weapon or other attachment that should become solid on alert + idAFBody *body; + if (makeSolid) + { + if( (body = AFBodyForEnt(ent)) != NULL ) + { + // TODO: Read the contents from a stored variable + // in case they are something other than these standards? + // CONTENTS_RENDERMODEL allows projectiles to hit it + body->GetClipModel()->SetContents( CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); + body->SetClipMask( CONTENTS_SOLID | CONTENTS_CORPSE ); + } + } + else + { + if( (body = AFBodyForEnt(ent)) != NULL ) + { + body->GetClipModel()->SetContents( 0 ); + body->SetClipMask( 0 ); + } + } + } +} + +/* +===================== +idAI::UpdateEnemyPosition +===================== +*/ +void idAI::UpdateEnemyPosition() +{ + // Interleave this check + if (gameLocal.time <= lastUpdateEnemyPositionTime + cv_ai_opt_update_enemypos_interleave.GetInteger()) + { + return; + } + + idActor* enemyEnt = enemy.GetEntity(); + enemyReachable = false; + + if (enemyEnt == NULL) + { + return; + } + + // Set a new time stamp + lastUpdateEnemyPositionTime = gameLocal.time; + + START_SCOPED_TIMING(aiUpdateEnemyPositionTimer, scopedUpdateEnemyPositionTimer) + + int enemyAreaNum(-1); + idVec3 enemyPos; + bool onGround; + const idVec3& org = physicsObj.GetOrigin(); + int lastVisibleReachableEnemyAreaNum = -1; + bool enemyDetectable = false; + + if ( move.moveType == MOVETYPE_FLY ) + { + enemyPos = enemyEnt->GetPhysics()->GetOrigin(); + // greebo: Flying AI always consider their enemies to be on the ground + onGround = true; + } + else + { + // non-flying AI, get the floor position of the enemy + START_TIMING(aiGetFloorPosTimer); + onGround = enemyEnt->GetFloorPos(64.0f, enemyPos); + STOP_TIMING(aiGetFloorPosTimer); + + if (enemyEnt->OnLadder()) + { + onGround = false; + } + } + + int areaNum = PointReachableAreaNum(org, 1.0f); + + if (onGround) + { + // greebo: Enemy is on ground, hence reachable, try to setup a path + if (aas != NULL) + { + // We have a valid AAS, try to get the area of the enemy (floorpos or origin) + enemyAreaNum = PointReachableAreaNum(enemyPos, 1.0f); + + if (enemyAreaNum) + { + // We have a valid enemy area number + // Get the own area number + + // Try to setup a path to the goal + aasPath_t path; + if (PathToGoal( path, areaNum, org, enemyAreaNum, enemyPos, this)) + { + // Path successfully setup, store the position as "reachable" + lastReachableEnemyPos = enemyPos; + enemyReachable = true; + } + } + else + { + // The area number lookup failed, fallback to unreachable + if (move.moveCommand == MOVE_TO_ENEMY) + { + AI_DEST_UNREACHABLE = true; + } + areaNum = 0; + } + } + else + { + // We don't have an AAS, we can't tell if an enemy is reachable or not, + // so just assume that he is. + enemyAreaNum = 0; + lastReachableEnemyPos = enemyPos; + enemyReachable = true; + } + } + + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; + + if (CanSee(enemyEnt, false)) + { + if (cv_ai_show_enemy_visibility.GetBool()) + { + // greebo: A trace to the enemy is possible (no FOV check!) and the entity is not hidden in darkness + gameRenderWorld->DebugArrow(colorGreen, GetEyePosition(), GetEyePosition() + idVec3(0,0,10), 2, 100); + } + + // Enemy is considered visible if not hidden in darkness and not obscured + AI_ENEMY_VISIBLE = true; + + + // Now perform the FOV check manually + if (CheckFOV(enemyPos)) + { + AI_ENEMY_IN_FOV = true; + // TODO: call SetEnemyPosition here only? + + // Store the last time the enemy was visible + mind->GetMemory().lastTimeEnemySeen = gameLocal.time; + } + enemyDetectable = true; + } + + else // enemy is not visible + { + // Enemy can't be seen (obscured or hidden in darkness) + if (cv_ai_show_enemy_visibility.GetBool()) + { + gameRenderWorld->DebugArrow(colorRed, GetEyePosition(), GetEyePosition() + idVec3(0,0,10), 2, 100); + } + } + + // grayman #2887 - track enemy visibility for statistics + + if ( enemyEnt->IsType(idPlayer::Type) ) + { + if ( AI_ENEMY_VISIBLE ) + { + if ( ( lastTimePlayerSeen < 0 ) && ( lastTimePlayerLost < 0 ) ) + { + // new sighting + gameLocal.m_MissionData->IncrementPlayerSeen(); + lastTimePlayerSeen = gameLocal.time; + } + else if ( lastTimePlayerLost > 0 ) + { + if ( ( gameLocal.time - lastTimePlayerLost ) > 6000 ) + { + // new sighting + gameLocal.m_MissionData->IncrementPlayerSeen(); + lastTimePlayerSeen = gameLocal.time; + lastTimePlayerLost = -1; + } + else // continuation of previous sighting + { + lastTimePlayerSeen = lastTimePlayerLost; + lastTimePlayerLost = -1; + } + } + } + else // not visible + { + // log the amount of time you saw the player + + if ( lastTimePlayerLost < 0 ) + { + lastTimePlayerLost = gameLocal.time; + if ( lastTimePlayerSeen > 0 ) + { + gameLocal.m_MissionData->Add2TimePlayerSeen(lastTimePlayerLost - lastTimePlayerSeen); + } + lastTimePlayerSeen = -1; + } + } + } + + if (enemyDetectable) + { + // angua: This was merged in from SetEnemyPosition + // to avoid doing the same reachability testing stuff twice + lastVisibleEnemyPos = enemyEnt->GetPhysics()->GetOrigin(); + lastVisibleEnemyEyeOffset = enemyEnt->EyeOffset(); + + if (aas != NULL && enemyReachable) + { + // We have a visible and reachable enemy position + lastVisibleReachableEnemyPos = enemyPos; + lastVisibleReachableEnemyAreaNum = enemyAreaNum; + } + else + { + // We don't have a valid AAS, we can't tell if an enemy is reachable or not, + // so just assume that he is. + lastVisibleReachableEnemyPos = lastVisibleEnemyPos; + enemyAreaNum = 0; + areaNum = 0; + } + + // General move command update + if (move.moveCommand == MOVE_TO_ENEMY) + { + if (!aas) + { + // Invalid AAS keep the move destination up to date for wandering + AI_DEST_UNREACHABLE = false; + move.moveDest = lastVisibleReachableEnemyPos; + } + else if (enemyAreaNum) + { + // The previous pathing attempt succeeded, update the move command + move.toAreaNum = lastVisibleReachableEnemyAreaNum; + move.moveDest = lastVisibleReachableEnemyPos; + AI_DEST_UNREACHABLE = !enemyReachable; + } + + if (move.moveType == MOVETYPE_FLY) + { + predictedPath_t path; + idVec3 end = move.moveDest; + end.z += enemyEnt->EyeOffset().z + fly_offset; + idAI::PredictPath( this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path ); + move.moveDest = path.endPos; + move.toAreaNum = PointReachableAreaNum( move.moveDest, 1.0f ); + } + + if (!onGround) + { + // greebo: The AI considers a non-grounded entity to be unreachable + // TODO: Check for climb height? The enemy might still be reachable? + AI_DEST_UNREACHABLE = true; + } + } + } + + if (ai_debugMove.GetBool()) + { + gameRenderWorld->DebugBounds( colorLtGrey, enemyEnt->GetPhysics()->GetBounds(), lastReachableEnemyPos, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorWhite, enemyEnt->GetPhysics()->GetBounds(), lastVisibleReachableEnemyPos, gameLocal.msec ); + } +} + +/* +===================== +idAI::SetEnemy +===================== +*/ +bool idAI::SetEnemy(idActor* newEnemy) +{ + // Don't continue if we're dead or knocked out + if (newEnemy == NULL || AI_DEAD || AI_KNOCKEDOUT) + { + ClearEnemy(); + return false; // not a valid enemy + } + + // greebo: Check if the new enemy is different + if (enemy.GetEntity() != newEnemy) + { + // Update the enemy pointer + enemy = newEnemy; + + enemyNode.AddToEnd(newEnemy->enemyList); + + // Check if the new enemy is dead + if (newEnemy->health <= 0) + { + EnemyDead(); + return false; // not a valid enemy + } + + int enemyAreaNum(-1); + + // greebo: Get the reachable position and area number of this enemy + newEnemy->GetAASLocation(aas, lastReachableEnemyPos, enemyAreaNum); + + // SetEnemyPosition() can now try to setup a path, + // lastVisibleReachableEnemyPosition is set in ANY CASE by this method + SetEnemyPosition(); + + // greebo: This looks suspicious. It overwrites REACHABLE and + // and VISIBLEREACHABLE with VISIBLE enemy position, + // regardless of what happened before. WTF? TODO + lastReachableEnemyPos = lastVisibleEnemyPos; + lastVisibleReachableEnemyPos = lastReachableEnemyPos; + + // Get the area number of the enemy + enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); + + if (aas != NULL && enemyAreaNum) + { + aas->PushPointIntoAreaNum( enemyAreaNum, lastReachableEnemyPos ); + lastVisibleReachableEnemyPos = lastReachableEnemyPos; + } + + ai::Memory& memory = GetMemory(); + memory.lastTimeEnemySeen = gameLocal.time; + memory.stopRelight = true; // grayman #2603 + memory.stopExaminingRope = true; // grayman #2872 - stop examining a rope + + return true; // valid enemy + } + else + { + return true; // still a valid enemy + } +} + +/* +============ +idAI::FirstVisiblePointOnPath +============ +*/ +idVec3 idAI::FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) { + int i, areaNum, targetAreaNum, curAreaNum, travelTime; + idVec3 curOrigin; + idReachability *reach; + + if ( !aas ) { + return origin; + } + + areaNum = PointReachableAreaNum( origin ); + targetAreaNum = PointReachableAreaNum( target ); + + if ( !areaNum || !targetAreaNum ) { + return origin; + } + + if ( ( areaNum == targetAreaNum ) || PointVisible( origin ) ) { + return origin; + } + + curAreaNum = areaNum; + curOrigin = origin; + + for( i = 0; i < 10; i++ ) { + + if ( !aas->RouteToGoalArea( curAreaNum, curOrigin, targetAreaNum, travelFlags, travelTime, &reach, NULL, this ) ) { + break; + } + + if ( !reach ) { + return target; + } + + curAreaNum = reach->toAreaNum; + curOrigin = reach->end; + + if ( PointVisible( curOrigin ) ) { + return curOrigin; + } + } + + return origin; +} + +/* +=================== +idAI::CalculateAttackOffsets + +calculate joint positions on attack frames so we can do proper "can hit" tests +=================== +*/ +void idAI::CalculateAttackOffsets( void ) { + const idDeclModelDef *modelDef; + int num; + int i; + int frame; + const frameCommand_t *command; + idMat3 axis; + const idAnim *anim; + jointHandle_t joint; + + modelDef = animator.ModelDef(); + if ( !modelDef ) { + return; + } + num = modelDef->NumAnims(); + + // needs to be off while getting the offsets so that we account for the distance the monster moves in the attack anim + animator.RemoveOriginOffset( false ); + + // anim number 0 is reserved for non-existant anims. to avoid off by one issues, just allocate an extra spot for + // launch offsets so that anim number can be used without subtracting 1. + missileLaunchOffset.SetGranularity( 1 ); + missileLaunchOffset.SetNum( num + 1 ); + missileLaunchOffset[ 0 ].Zero(); + + for( i = 1; i <= num; i++ ) { + missileLaunchOffset[ i ].Zero(); + anim = modelDef->GetAnim( i ); + if ( anim ) { + frame = anim->FindFrameForFrameCommand( FC_LAUNCHMISSILE, &command ); + if ( frame >= 0 ) { + joint = animator.GetJointHandle( command->string->c_str() ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Invalid joint '%s' on 'launch_missile' frame command on frame %d of model '%s'", command->string->c_str(), frame, modelDef->GetName() ); + } + GetJointTransformForAnim( joint, i, FRAME2MS( frame ), missileLaunchOffset[ i ], axis ); + } + } + } + + animator.RemoveOriginOffset( true ); +} + +/* +===================== +idAI::EnsureActiveProjectileInfo +===================== +*/ +idAI::ProjectileInfo& idAI::EnsureActiveProjectileInfo() +{ + // Ensure valid projectile clipmodel + if (activeProjectile.info.clipModel == NULL) + { + // Ensure we have a radius + if (activeProjectile.info.radius < 0) + { + // At least we should have the def + assert(activeProjectile.info.def != NULL); + + // Load values from the projectile + InitProjectileInfoFromDict(activeProjectile.info, activeProjectile.info.def); + } + + idBounds projectileBounds(vec3_origin); + projectileBounds.ExpandSelf(activeProjectile.info.radius); + + activeProjectile.info.clipModel = new idClipModel(idTraceModel(projectileBounds)); + } + + return activeProjectile.info; +} + +/* +===================== +idAI::GetAimDir +===================== +*/ +bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ) +{ + idVec3 targetPos1; + idVec3 targetPos2; + idVec3 delta; + float max_height; + bool result; + + // if no aimAtEnt or projectile set + if (aimAtEnt == NULL || projectileInfo.Num() == 0) + { + aimDir = viewAxis[ 0 ] * physicsObj.GetGravityAxis(); + return false; + } + + // Ensure we have a valid clipmodel + ProjectileInfo& info = EnsureActiveProjectileInfo(); + + if ( aimAtEnt == enemy.GetEntity() ) { + static_cast( aimAtEnt )->GetAIAimTargets( lastVisibleEnemyPos, targetPos1, targetPos2 ); + } else if ( aimAtEnt->IsType( idActor::Type ) ) { + static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), targetPos1, targetPos2 ); + } else { + targetPos1 = aimAtEnt->GetPhysics()->GetAbsBounds().GetCenter(); + targetPos2 = targetPos1; + } + + // try aiming for chest + delta = firePos - targetPos1; + max_height = delta.LengthFast() * projectile_height_to_distance_ratio; + result = PredictTrajectory( firePos, targetPos1, info.speed, info.gravity, info.clipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); + if ( result || !aimAtEnt->IsType( idActor::Type ) ) { + return result; + } + + // try aiming for head + delta = firePos - targetPos2; + max_height = delta.LengthFast() * projectile_height_to_distance_ratio; + result = PredictTrajectory( firePos, targetPos2, info.speed, info.gravity, info.clipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); + + return result; +} + +/* +===================== +idAI::BeginAttack +===================== +*/ +void idAI::BeginAttack( const char *name ) { + attack = name; + lastAttackTime = gameLocal.time; +} + +/* +===================== +idAI::EndAttack +===================== +*/ +void idAI::EndAttack( void ) { + attack = ""; +} + +/* +===================== +idAI::CreateProjectile +===================== +*/ +idProjectile* idAI::CreateProjectile(const idVec3 &pos, const idVec3 &dir, int index) +{ + if (activeProjectile.projEnt.GetEntity() == NULL) + { + assert(curProjectileIndex >= 0 && curProjectileIndex < projectileInfo.Num()); // bounds check + + // projectile pointer still NULL, create a new one + const idDict* def = projectileInfo[curProjectileIndex].def; + + // Fill the current projectile entity pointer, passing the arguments to the specialised routine + // After this call, the activeProjectile.projEnt pointer will be initialised with the new projectile. + CreateProjectileFromDict(pos, dir, def); + + // Re-roll the index for the next time + curProjectileIndex = gameLocal.random.RandomInt(projectileInfo.Num()); + } + + return activeProjectile.projEnt.GetEntity(); +} + +idProjectile* idAI::CreateProjectileFromDict(const idVec3 &pos, const idVec3 &dir, const idDict* dict) +{ + if (activeProjectile.projEnt.GetEntity() == NULL) + { + // Store the def for later use + activeProjectile.info.def = dict; + activeProjectile.info.defName = dict->GetString("classname"); + + // Fill the current projectile entity pointer + activeProjectile.projEnt = SpawnProjectile(dict); + } + + activeProjectile.projEnt.GetEntity()->Create(this, pos, dir); + + return activeProjectile.projEnt.GetEntity(); +} + +idProjectile* idAI::SpawnProjectile(const idDict* dict) const +{ + idEntity* ent; + gameLocal.SpawnEntityDef(*dict, &ent, false); + + if (ent == NULL) + { + const char* clsname = dict->GetString("classname"); + gameLocal.Error("Could not spawn entityDef '%s'", clsname); + } + + if (!ent->IsType(idProjectile::Type)) + { + const char* clsname = ent->GetClassname(); + gameLocal.Error("'%s' is not an idProjectile", clsname); + } + + return static_cast(ent); +} + +/* +===================== +idAI::RemoveProjectile +===================== +*/ +void idAI::RemoveProjectile() +{ + if (activeProjectile.projEnt.GetEntity()) + { + activeProjectile.projEnt.GetEntity()->PostEventMS(&EV_Remove, 0); + activeProjectile.projEnt = NULL; + + activeProjectile.info = ProjectileInfo(); + } +} + +/* +===================== +idAI::LaunchProjectile +===================== +*/ +idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone ) { + idVec3 muzzle; + idVec3 dir; + idVec3 start; + trace_t tr; + idBounds projBounds; + float distance; + const idClipModel *projClip; + float attack_accuracy; + float attack_cone; + float projectile_spread; + float diff; + float angle; + float spin; + idAngles ang; + int num_projectiles; + int i; + idMat3 axis; + idVec3 tmp; + + if (projectileInfo.Num() == 0) + { + gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() ); + return NULL; + } + + attack_accuracy = spawnArgs.GetFloat( "attack_accuracy", "7" ); + attack_cone = spawnArgs.GetFloat( "attack_cone", "70" ); + projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); + num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); + + GetMuzzle( jointname, muzzle, axis ); + + // Ensure we have a set up projectile + CreateProjectile(muzzle, axis[0]); + + idProjectile* lastProjectile = activeProjectile.projEnt.GetEntity(); + + if ( target != NULL ) { + tmp = target->GetPhysics()->GetAbsBounds().GetCenter() - muzzle; + tmp.Normalize(); + axis = tmp.ToMat3(); + } else { + axis = viewAxis; + } + + // rotate it because the cone points up by default + tmp = axis[2]; + axis[2] = axis[0]; + axis[0] = -tmp; + + // make sure the projectile starts inside the monster bounding box + const idBounds &ownerBounds = physicsObj.GetAbsBounds(); + projClip = lastProjectile->GetPhysics()->GetClipModel(); + projBounds = projClip->GetBounds().Rotate( axis ); + + // check if the owner bounds is bigger than the projectile bounds + if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && + ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && + ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { + if ( (ownerBounds - projBounds).RayIntersection( muzzle, viewAxis[ 0 ], distance ) ) { + start = muzzle + distance * viewAxis[ 0 ]; + } else { + start = ownerBounds.GetCenter(); + } + } else { + // projectile bounds bigger than the owner bounds, so just start it from the center + start = ownerBounds.GetCenter(); + } + + gameLocal.clip.Translation( tr, start, muzzle, projClip, axis, MASK_SHOT_RENDERMODEL, this ); + muzzle = tr.endpos; + + // set aiming direction + GetAimDir( muzzle, target, this, dir ); + ang = dir.ToAngles(); + + // adjust his aim so it's not perfect. uses sine based movement so the tracers appear less random in their spread. + float t = MS2SEC( gameLocal.time + entityNumber * 497 ); + ang.pitch += idMath::Sin16( t * 5.1 ) * attack_accuracy; + ang.yaw += idMath::Sin16( t * 6.7 ) * attack_accuracy; + + if ( clampToAttackCone ) { + // clamp the attack direction to be within monster's attack cone so he doesn't do + // things like throw the missile backwards if you're behind him + diff = idMath::AngleDelta( ang.yaw, current_yaw ); + if ( diff > attack_cone ) { + ang.yaw = current_yaw + attack_cone; + } else if ( diff < -attack_cone ) { + ang.yaw = current_yaw - attack_cone; + } + } + + axis = ang.ToMat3(); + + float spreadRad = DEG2RAD( projectile_spread ); + + for( i = 0; i < num_projectiles; i++ ) + { + // spread the projectiles out + angle = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); + spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); + dir = axis[ 0 ] + axis[ 2 ] * ( angle * idMath::Sin( spin ) ) - axis[ 1 ] * ( angle * idMath::Cos( spin ) ); + dir.Normalize(); + + // create, launch and clear the projectile + CreateProjectile( muzzle, dir ); + + lastProjectile = activeProjectile.projEnt.GetEntity(); + lastProjectile->Launch( muzzle, dir, vec3_origin ); + activeProjectile.projEnt = NULL; + } + + TriggerWeaponEffects( muzzle ); + + lastAttackTime = gameLocal.time; + + return lastProjectile; +} + +/* +================ +idAI::DamageFeedback + +callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. + +FIXME: This gets called when we call idPlayer::CalcDamagePoints from idAI::AttackMelee, which then checks for a saving throw, +possibly forcing a miss. This is harmless behavior ATM, but is not intuitive. +================ +*/ +void idAI::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { + if ( ( victim == this ) && inflictor->IsType( idProjectile::Type ) ) { + // monsters only get half damage from their own projectiles + damage = ( damage + 1 ) / 2; // round up so we don't do 0 damage + + } else if ( victim == enemy.GetEntity() ) { + AI_HIT_ENEMY = true; + } +} + +/* +===================== +idAI::DirectDamage + +Causes direct damage to an entity + +kickDir is specified in the monster's coordinate system, and gives the direction +that the view kick and knockback should go +===================== +*/ +void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) { + const idDict *meleeDef; + const char *p; + const idSoundShader *shader; + + meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); + if ( !meleeDef ) { + gameLocal.Error( "Unknown damage def '%s' on '%s'", meleeDefName, name.c_str() ); + } + + if ( !ent->fl.takedamage ) { + const idSoundShader *shader = declManager->FindSound(meleeDef->GetString( "snd_miss" )); + StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + return; + } + + // + // do the damage + // + p = meleeDef->GetString( "snd_hit" ); + if ( p && *p ) { + shader = declManager->FindSound( p ); + StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + } + + idVec3 kickDir; + meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); + + idVec3 globalKickDir; + globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; + + ent->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); + + // end the attack if we're a multiframe attack + EndAttack(); +} + +/* +===================== +idAI::TestMelee +===================== +*/ +bool idAI::TestMelee( void ) const { + trace_t trace; + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt || !melee_range ) { + return false; + } + + if (!GetAttackFlag(COMBAT_MELEE)) + { + // greebo: Cannot attack with melee weapons yet + return false; + } + + //FIXME: make work with gravity vector + const idVec3& org = physicsObj.GetOrigin(); + const idBounds& bounds = physicsObj.GetBounds(); + + const idVec3& enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); + const idBounds& enemyBounds = enemyEnt->GetPhysics()->GetBounds(); + + idVec3 dir = enemyOrg - org; + dir.z = 0; + float dist = dir.LengthFast(); + + float maxdist = melee_range + enemyBounds[1][0]; + + if (dist < maxdist) + { + // angua: within horizontal distance + if ((org.z + bounds[1][2] + melee_range_vert) > enemyOrg.z && // grayman #2655 - use melee_range_vert + (enemyOrg.z + enemyBounds[1][2]) > org.z) + { + // within height + // check if there is something in between + idVec3 start = GetEyePosition(); + idVec3 end = enemyEnt->GetEyePosition(); + + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); + if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) + { + return true; + } + } + } + + return false; +} + +/* +===================== +idAI::TestMeleeFuture +===================== +*/ +bool idAI::TestMeleeFuture( void ) const { + trace_t trace; + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt || !melee_range ) { + return false; + } + + if (!GetAttackFlag(COMBAT_MELEE)) + { + // greebo: Cannot attack with melee weapons yet + return false; + } + + //FIXME: make work with gravity vector + idVec3 org = physicsObj.GetOrigin(); + const idBounds& bounds = physicsObj.GetBounds(); + idVec3 vel = physicsObj.GetLinearVelocity(); + + + idVec3 enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); + const idBounds& enemyBounds = enemyEnt->GetPhysics()->GetBounds(); + idVec3 enemyVel = enemyEnt->GetPhysics()->GetLinearVelocity(); + + // update prediction + float dt = m_MeleePredictedAttTime; + idVec3 ds = dt * vel; + org += ds; + //bounds = bounds.TranslateSelf( ds ); + + idVec3 dsEnemy = dt * enemyVel; + enemyOrg += dsEnemy; + //enemyBounds = enemyBounds.TranslateSelf( dsEnemy ); + + // rest is the same as TestMelee + idVec3 dir = enemyOrg - org; + dir.z = 0; + float dist = dir.LengthFast(); + + float maxdist = melee_range + enemyBounds[1][0]; + + if (dist < maxdist) + { + // angua: within horizontal distance + if ((org.z + bounds[1].z + melee_range_vert) > enemyOrg.z && // grayman #2655 - use melee_range_vert + (enemyOrg.z + enemyBounds[1].z) > org.z) + { + // within height + // check if there is something in between + idVec3 start = GetEyePosition() + ds; + idVec3 end = enemyEnt->GetEyePosition() + dsEnemy; + + gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); + if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) + { + return true; + } + } + } + + return false; +} + + +/* +===================== +idAI::TestRanged +===================== +*/ +bool idAI::TestRanged() +{ + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt) + { + return false; + } + + if (!GetAttackFlag(COMBAT_RANGED)) + { + // greebo: Cannot attack with ranged weapons yet + return false; + } + + // Calculate the point on enemy AI needs to see + idVec3 enemyPoint; + // stgatilov: Look at the UNLEANED player's eye position + // to achieve this, we treat player as ordinary actor + if (enemyEnt->IsType(idPlayer::Type)) + enemyPoint = enemyEnt->idActor::GetEyePosition(); + else + enemyPoint = enemyEnt->GetEyePosition(); + + // Test if the enemy is within range, in FOV and not occluded + float dist = (GetEyePosition() - enemyPoint).LengthFast(); + return dist <= fire_range && CanSeePositionExt(enemyPoint, false, false); +} + + +/* +===================== +idAI::AttackMelee + +jointname allows the endpoint to be exactly specified in the model, +as for the commando tentacle. If not specified, it will be set to +the facing direction + melee_range. + +kickDir is specified in the monster's coordinate system, and gives the direction +that the view kick and knockback should go + +DarkMod : Took out saving throws. +===================== +*/ +bool idAI::AttackMelee( const char *meleeDefName ) { + const idDict *meleeDef; + idActor *enemyEnt = enemy.GetEntity(); + const char *p; + const idSoundShader *shader; + + meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); + if ( !meleeDef ) { + gameLocal.Error( "Unknown melee '%s'", meleeDefName ); + } + + if ( !enemyEnt ) { + p = meleeDef->GetString( "snd_miss" ); + if ( p && *p ) { + shader = declManager->FindSound( p ); + StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + } + return false; + } + + // check for the "saving throw" automatic melee miss on lethal blow + // stupid place for this. + +/** +* Saving throws removed. Uncomment the following for saving throws. +**/ + +/*** BEGIN SAVING THROWS SECTION ***** + bool forceMiss = false; + if ( enemyEnt->IsType( idPlayer::Type ) && g_skill.GetInteger() < 2 ) { + int damage, armor; + idPlayer *player = static_cast( enemyEnt ); + player->CalcDamagePoints( this, this, meleeDef, 1.0f, INVALID_JOINT, &damage, &armor ); + + if ( enemyEnt->health <= damage ) { + int t = gameLocal.time - player->lastSavingThrowTime; + if ( t > SAVING_THROW_TIME ) { + player->lastSavingThrowTime = gameLocal.time; + t = 0; + } + if ( t < 1000 ) { + gameLocal.Printf( "Saving throw.\n" ); + forceMiss = true; + } + } + } + + + // make sure the trace can actually hit the enemy + if ( forceMiss || !TestMelee() ) { +****** END SAVING THROWS SECTION *******/ + + if ( !TestMelee() ) + { + // missed + p = meleeDef->GetString( "snd_miss" ); + if ( p && *p ) { + shader = declManager->FindSound( p ); + StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + } + return false; + } + + // + // do the damage + // + p = meleeDef->GetString( "snd_hit" ); + if ( p && *p ) { + shader = declManager->FindSound( p ); + StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + } + + idVec3 kickDir; + meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); + + idVec3 globalKickDir; + globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; + + enemyEnt->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); + + // cause a LARGE tactile alert in the enemy, if it is an AI + if( enemyEnt->IsType(idAI::Type) ) + { + static_cast(enemyEnt)->TactileAlert( this, 100 ); + } + + lastAttackTime = gameLocal.time; + + return true; +} + +/* +================ +idAI::PushWithAF +================ +*/ +void idAI::PushWithAF( void ) { + int i, j; + afTouch_t touchList[ MAX_GENTITIES ]; + idEntity *pushed_ents[ MAX_GENTITIES ]; + idEntity *ent; + idVec3 vel( vec3_origin ), vGravNorm( vec3_origin ); + int num_pushed; + + num_pushed = 0; + af.ChangePose( this, gameLocal.time ); + int num = af.EntitiesTouchingAF( touchList ); + + for( i = 0; i < num; i++ ) { + if ( touchList[ i ].touchedEnt->IsType( idProjectile::Type ) ) { + // skip projectiles + continue; + } + + // make sure we havent pushed this entity already. this avoids causing double damage + for( j = 0; j < num_pushed; j++ ) { + if ( pushed_ents[ j ] == touchList[ i ].touchedEnt ) { + break; + } + } + if ( j >= num_pushed ) + { + ent = touchList[ i ].touchedEnt; + pushed_ents[num_pushed++] = ent; + vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin(); + + if ( ent->IsType(idPlayer::Type) && static_cast(ent)->noclip ) + { + // skip player when noclip is on + continue; + } + + // ishtvan: don't push our own bind children (fix AI floating away when stuff is bound to them) + if( ent->GetBindMaster() == this ) + continue; + + if( ent->IsType(idActor::Type) ) + { + + // Id code to stop from pushing the enemy back during melee + // TODO: This will change with new melee system + if ( attack.Length() ) + { + // TODO: Don't need to do this right now, but keep in mind for future melee system + ent->Damage( this, this, vel, attack, 1.0f, INVALID_JOINT ); + } else + { + // Ishtvan: Resolve velocity on to XY plane to stop from pushing AI up + vGravNorm = physicsObj.GetGravityNormal(); + vel -= (vel * vGravNorm ) * vGravNorm; + vel.Normalize(); + ent->GetPhysics()->SetLinearVelocity( 80.0f * vel, touchList[ i ].touchedClipModel->GetId() ); + } + + // Tactile Alert: + + // grayman #2345 - when an AI is non-solid, waiting for another AI + // to pass by, there's no need to register a tactile alert from another AI + + if (!movementSubsystem->IsWaitingNonSolid()) + { + if( ent->IsType(idPlayer::Type) ) + { + // aesthetics: Dont react to dead player? + if( ent->health > 0 ) + HadTactile( static_cast(ent) ); + } + else if( ent->IsType(idAI::Type) && (ent->health > 0) && !static_cast(ent)->AI_KNOCKEDOUT ) + { + if (!static_cast(ent)->movementSubsystem->IsWaitingNonSolid()) // grayman #2345 - don't call HadTactile() if the bumped AI is waiting + { + HadTactile( static_cast(ent) ); + } + } + else + { + // TODO: Touched a dead or unconscious body, should issue a body alert + // Touched dead body code goes here: found body alert + } + } + } + // Ent was not an actor: + else + { + vel.Normalize(); + ent->ApplyImpulse( this, touchList[i].touchedClipModel->GetId(), ent->GetPhysics()->GetOrigin(), cv_ai_bumpobject_impulse.GetFloat() * vel ); + if (ent->m_SetInMotionByActor.GetEntity() == NULL) + { + ent->m_SetInMotionByActor = this; + ent->m_MovedByActor = this; + } + } + } + } +} + +/*********************************************************************** + + Misc + +***********************************************************************/ + +/* +================ +idAI::GetMuzzle +================ +*/ +void idAI::GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ) { + jointHandle_t joint; + + if ( !jointname || !jointname[ 0 ] ) { + muzzle = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 14; + muzzle -= physicsObj.GetGravityNormal() * physicsObj.GetBounds()[ 1 ].z * 0.5f; + } else { + joint = animator.GetJointHandle( jointname ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); + } + GetJointWorldTransform( joint, gameLocal.time, muzzle, axis ); + } +} + +/* +================ +idAI::TriggerWeaponEffects +================ +*/ +void idAI::TriggerWeaponEffects( const idVec3 &muzzle ) { + idVec3 org; + idMat3 axis; + + if ( !g_muzzleFlash.GetBool() ) { + return; + } + + // muzzle flash + // offset the shader parms so muzzle flashes show up + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = gameLocal.random.CRandomFloat(); + + if ( flashJointWorld != INVALID_JOINT ) { + GetJointWorldTransform( flashJointWorld, gameLocal.time, org, axis ); + + if ( worldMuzzleFlash.lightRadius.x > 0.0f ) { + worldMuzzleFlash.axis = axis; + worldMuzzleFlash.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); + if ( worldMuzzleFlashHandle != - 1 ) { + gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); + } else { + worldMuzzleFlashHandle = gameRenderWorld->AddLightDef( &worldMuzzleFlash ); + } + muzzleFlashEnd = gameLocal.time + flashTime; + UpdateVisuals(); + } + } +} + +/* +================ +idAI::UpdateMuzzleFlash +================ +*/ +void idAI::UpdateMuzzleFlash( void ) { + if ( worldMuzzleFlashHandle != -1 ) { + if ( gameLocal.time >= muzzleFlashEnd ) { + gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + worldMuzzleFlashHandle = -1; + } else { + idVec3 muzzle; + animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); + animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); + muzzle = physicsObj.GetOrigin() + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); + worldMuzzleFlash.origin = muzzle; + gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); + } + } +} + +/* +================ +idAI::Hide +================ +*/ +void idAI::Hide( void ) { + idActor::Hide(); + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.GetClipModel()->Unlink(); + StopSound( SND_CHANNEL_AMBIENT, false ); + + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; + StopMove( MOVE_STATUS_DONE ); +} + +/* +================ +idAI::Show +================ +*/ +void idAI::Show( void ) +{ + idActor::Show(); + physicsObj.SetContents( m_preHideContents ); + + physicsObj.GetClipModel()->Link( gameLocal.clip ); + fl.takedamage = !spawnArgs.GetBool( "noDamage" ); + StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); +} +/* +================ +idAI::CanBecomeSolid +================ +*/ +bool idAI::CanBecomeSolid( void ) { + idClipModel* clipModels[ MAX_GENTITIES ]; + + int num = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), MASK_MONSTERSOLID, clipModels, MAX_GENTITIES ); + for ( int i = 0; i < num; i++ ) { + idClipModel* cm = clipModels[ i ]; + + // don't check render entities + if ( cm->IsRenderModel() ) { + continue; + } + + idEntity* hit = cm->GetEntity(); + if ( ( hit == this ) || !hit->fl.takedamage ) { + continue; + } + + if ( physicsObj.ClipContents( cm ) ) { + return false; + } + } + return true; + +} + +/* +===================== +idAI::UpdateParticles +===================== +*/ +void idAI::UpdateParticles( void ) { + if ( ( thinkFlags & TH_UPDATEPARTICLES) && !IsHidden() ) { + idVec3 realVector; + idMat3 realAxis; + + int particlesAlive = 0; + for ( int i = 0; i < particles.Num(); i++ ) { + if ( particles[i].particle && particles[i].time ) { + particlesAlive++; + if (af.IsActive()) { + realAxis = mat3_identity; + realVector = GetPhysics()->GetOrigin(); + } else { + animator.GetJointTransform( particles[i].joint, gameLocal.time, realVector, realAxis ); + realAxis *= renderEntity.axis; + realVector = physicsObj.GetOrigin() + ( realVector + modelOffset ) * ( viewAxis * physicsObj.GetGravityAxis() ); + } + + if ( !gameLocal.smokeParticles->EmitSmoke( particles[i].particle, particles[i].time, gameLocal.random.CRandomFloat(), realVector, realAxis )) { + if ( restartParticles ) { + particles[i].time = gameLocal.time; + } else { + particles[i].time = 0; + particlesAlive--; + } + } + } + } + if ( particlesAlive == 0 ) { + BecomeInactive( TH_UPDATEPARTICLES ); + } + } +} + +/* +===================== +idAI::TriggerParticles +===================== +*/ +void idAI::TriggerParticles( const char *jointName ) { + jointHandle_t jointNum; + + jointNum = animator.GetJointHandle( jointName ); + for ( int i = 0; i < particles.Num(); i++ ) { + if ( particles[i].joint == jointNum ) { + particles[i].time = gameLocal.time; + BecomeActive( TH_UPDATEPARTICLES ); + } + } +} + + +/*********************************************************************** + + Head & torso aiming + +***********************************************************************/ + +/* +================ +idAI::UpdateAnimationControllers +================ +*/ +bool idAI::UpdateAnimationControllers( void ) { + idVec3 local; + idVec3 focusPos; + idQuat jawQuat; + idVec3 left; + idVec3 dir; + idVec3 orientationJointPos; + idVec3 localDir; + idAngles newLookAng; + idAngles diff; + idMat3 mat; + idMat3 axis; + idMat3 orientationJointAxis; + idAFAttachment *headEnt = head.GetEntity(); + idVec3 eyepos; + idVec3 pos; + int i; + idAngles jointAng; + float orientationJointYaw; + + if ( AI_DEAD || AI_KNOCKEDOUT ) + { + return idActor::UpdateAnimationControllers(); + } + + if ( orientationJoint == INVALID_JOINT ) { + orientationJointAxis = viewAxis; + orientationJointPos = physicsObj.GetOrigin(); + orientationJointYaw = current_yaw; + } else { + GetJointWorldTransform( orientationJoint, gameLocal.time, orientationJointPos, orientationJointAxis ); + orientationJointYaw = orientationJointAxis[ 2 ].ToYaw(); + orientationJointAxis = idAngles( 0.0f, orientationJointYaw, 0.0f ).ToMat3(); + } + + if ( focusJoint != INVALID_JOINT ) { + if ( headEnt ) { + headEnt->GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); + } else { + GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); + } + eyeOffset.z = eyepos.z - physicsObj.GetOrigin().z; + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorRed, eyepos, eyepos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); + } + } else { + eyepos = GetEyePosition(); + } + + if ( headEnt ) { + CopyJointsFromBodyToHead(); + } + + // Update the IK after we've gotten all the joint positions we need, but before we set any joint positions. + // Getting the joint positions causes the joints to be updated. The IK gets joint positions itself (which + // are already up to date because of getting the joints in this function) and then sets their positions, which + // forces the heirarchy to be updated again next time we get a joint or present the model. If IK is enabled, + // or if we have a seperate head, we end up transforming the joints twice per frame. Characters with no + // head entity and no ik will only transform their joints once. Set g_debuganim to the current entity number + // in order to see how many times an entity transforms the joints per frame. + idActor::UpdateAnimationControllers(); + + idEntity *focusEnt = focusEntity.GetEntity(); + if ( !allowJointMod || !allowEyeFocus || ( gameLocal.time >= focusTime ) ) { + focusPos = GetEyePosition() + orientationJointAxis[ 0 ] * 512.0f; + } else if ( focusEnt == NULL ) { + // keep looking at last position until focusTime is up + focusPos = currentFocusPos; + } else if ( focusEnt == enemy.GetEntity() ) { + focusPos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset - eyeVerticalOffset * enemy.GetEntity()->GetPhysics()->GetGravityNormal(); + } else if ( focusEnt->IsType( idActor::Type ) ) { + focusPos = static_cast( focusEnt )->GetEyePosition() - eyeVerticalOffset * focusEnt->GetPhysics()->GetGravityNormal(); + } else { + focusPos = focusEnt->GetPhysics()->GetOrigin(); + } + + currentFocusPos = currentFocusPos + ( focusPos - currentFocusPos ) * eyeFocusRate; + + // determine yaw from origin instead of from focus joint since joint may be offset, which can cause us to bounce between two angles + dir = focusPos - orientationJointPos; + newLookAng.yaw = idMath::AngleNormalize180( dir.ToYaw() - orientationJointYaw ); + newLookAng.roll = 0.0f; + newLookAng.pitch = 0.0f; + +#if 0 + gameRenderWorld->DebugLine( colorRed, orientationJointPos, focusPos, gameLocal.msec ); + gameRenderWorld->DebugLine( colorYellow, orientationJointPos, orientationJointPos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); + gameRenderWorld->DebugLine( colorGreen, orientationJointPos, orientationJointPos + newLookAng.ToForward() * 48.0f, gameLocal.msec ); +#endif + + // determine pitch from joint position + dir = focusPos - eyepos; + dir.NormalizeFast(); + orientationJointAxis.ProjectVector( dir, localDir ); + newLookAng.pitch = -idMath::AngleNormalize180( localDir.ToPitch() ); + newLookAng.roll = 0.0f; + + diff = newLookAng - lookAng; + + if ( eyeAng != diff ) { + eyeAng = diff; + eyeAng.Clamp( eyeMin, eyeMax ); + idAngles angDelta = diff - eyeAng; + if ( !angDelta.Compare( ang_zero, 0.1f ) ) { + alignHeadTime = gameLocal.time; + } else { + alignHeadTime = gameLocal.time + static_cast(( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime); + } + } + + if ( idMath::Fabs( newLookAng.yaw ) < 0.1f ) { + alignHeadTime = gameLocal.time; + } + + if ( ( gameLocal.time >= alignHeadTime ) || ( gameLocal.time < forceAlignHeadTime ) ) { + alignHeadTime = gameLocal.time + static_cast(( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime); + destLookAng = newLookAng; + destLookAng.Clamp( lookMin, lookMax ); + } + + diff = destLookAng - lookAng; + if ( ( lookMin.pitch == -180.0f ) && ( lookMax.pitch == 180.0f ) ) { + if ( ( diff.pitch > 180.0f ) || ( diff.pitch <= -180.0f ) ) { + diff.pitch = 360.0f - diff.pitch; + } + } + if ( ( lookMin.yaw == -180.0f ) && ( lookMax.yaw == 180.0f ) ) { + if ( diff.yaw > 180.0f ) { + diff.yaw -= 360.0f; + } else if ( diff.yaw <= -180.0f ) { + diff.yaw += 360.0f; + } + } + lookAng = lookAng + diff * headFocusRate; + lookAng.Normalize180(); + + jointAng.roll = 0.0f; + + if (AI_AlertLevel >= thresh_5) + { + // use combat look joints in combat + + for( i = 0; i < lookJointsCombat.Num(); i++ ) + { + jointAng.pitch = lookAng.pitch * lookJointAnglesCombat[ i ].pitch; + jointAng.yaw = lookAng.yaw * lookJointAnglesCombat[ i ].yaw; + animator.SetJointAxis( lookJointsCombat[ i ], JOINTMOD_WORLD, jointAng.ToMat3() ); + } + } + else + { + for( i = 0; i < lookJoints.Num(); i++ ) + { + jointAng.pitch = lookAng.pitch * lookJointAngles[ i ].pitch; + jointAng.yaw = lookAng.yaw * lookJointAngles[ i ].yaw; + animator.SetJointAxis( lookJoints[ i ], JOINTMOD_WORLD, jointAng.ToMat3() ); + } + } + + if ( move.moveType == MOVETYPE_FLY ) { + // lean into turns + AdjustFlyingAngles(); + } + + if ( headEnt ) { + idAnimator *headAnimator = headEnt->GetAnimator(); + + if ( allowEyeFocus ) { + idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); + idMat3 headTranspose = headEnt->GetPhysics()->GetAxis().Transpose(); + axis = eyeAxis * orientationJointAxis; + left = axis[ 1 ] * eyeHorizontalOffset; + eyepos -= headEnt->GetPhysics()->GetOrigin(); + headAnimator->SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f + left ) * headTranspose ); + headAnimator->SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f - left ) * headTranspose ); + } else { + headAnimator->ClearJoint( leftEyeJoint ); + headAnimator->ClearJoint( rightEyeJoint ); + } + } else { + if ( allowEyeFocus ) { + idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); + axis = eyeAxis * orientationJointAxis; + left = axis[ 1 ] * eyeHorizontalOffset; + eyepos += axis[ 0 ] * 64.0f - physicsObj.GetOrigin(); + animator.SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + left ); + animator.SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos - left ); + } else { + animator.ClearJoint( leftEyeJoint ); + animator.ClearJoint( rightEyeJoint ); + } + } + + return true; +} + +/*********************************************************************** + +idCombatNode + +***********************************************************************/ + +const idEventDef EV_CombatNode_MarkUsed( "markUsed" ); + +CLASS_DECLARATION( idEntity, idCombatNode ) + EVENT( EV_CombatNode_MarkUsed, idCombatNode::Event_MarkUsed ) + EVENT( EV_Activate, idCombatNode::Event_Activate ) +END_CLASS + +/* +===================== +idCombatNode::idCombatNode +===================== +*/ +idCombatNode::idCombatNode( void ) { + min_dist = 0.0f; + max_dist = 0.0f; + cone_dist = 0.0f; + min_height = 0.0f; + max_height = 0.0f; + cone_left.Zero(); + cone_right.Zero(); + offset.Zero(); + disabled = false; +} + +/* +===================== +idCombatNode::Save +===================== +*/ +void idCombatNode::Save( idSaveGame *savefile ) const { + savefile->WriteFloat( min_dist ); + savefile->WriteFloat( max_dist ); + savefile->WriteFloat( cone_dist ); + savefile->WriteFloat( min_height ); + savefile->WriteFloat( max_height ); + savefile->WriteVec3( cone_left ); + savefile->WriteVec3( cone_right ); + savefile->WriteVec3( offset ); + savefile->WriteBool( disabled ); +} + +/* +===================== +idCombatNode::Restore +===================== +*/ +void idCombatNode::Restore( idRestoreGame *savefile ) { + savefile->ReadFloat( min_dist ); + savefile->ReadFloat( max_dist ); + savefile->ReadFloat( cone_dist ); + savefile->ReadFloat( min_height ); + savefile->ReadFloat( max_height ); + savefile->ReadVec3( cone_left ); + savefile->ReadVec3( cone_right ); + savefile->ReadVec3( offset ); + savefile->ReadBool( disabled ); +} + +/* +===================== +idCombatNode::Spawn +===================== +*/ +void idCombatNode::Spawn( void ) { + float fov; + float yaw; + float height; + + min_dist = spawnArgs.GetFloat( "min" ); + max_dist = spawnArgs.GetFloat( "max" ); + height = spawnArgs.GetFloat( "height" ); + fov = spawnArgs.GetFloat( "fov", "60" ); + offset = spawnArgs.GetVector( "offset" ); + + const idVec3 &org = GetPhysics()->GetOrigin() + offset; + min_height = org.z - height * 0.5f; + max_height = min_height + height; + + const idMat3 &axis = GetPhysics()->GetAxis(); + yaw = axis[ 0 ].ToYaw(); + + idAngles leftang( 0.0f, yaw + fov * 0.5f - 90.0f, 0.0f ); + cone_left = leftang.ToForward(); + + idAngles rightang( 0.0f, yaw - fov * 0.5f + 90.0f, 0.0f ); + cone_right = rightang.ToForward(); + + disabled = spawnArgs.GetBool( "start_off" ); +} + +/* +===================== +idCombatNode::IsDisabled +===================== +*/ +bool idCombatNode::IsDisabled( void ) const { + return disabled; +} + +/* +===================== +idCombatNode::DrawDebugInfo +===================== +*/ +void idCombatNode::DrawDebugInfo( void ) { + idEntity *ent; + idCombatNode *node; + idPlayer *player = gameLocal.GetLocalPlayer(); + idVec4 color; + idBounds bounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 0 ) ); + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( !ent->IsType( idCombatNode::Type ) ) { + continue; + } + + node = static_cast( ent ); + if ( node->disabled ) { + color = colorMdGrey; + } else if ( player && node->EntityInView( player, player->GetPhysics()->GetOrigin() ) ) { + color = colorYellow; + } else { + color = colorRed; + } + + idVec3 leftDir( -node->cone_left.y, node->cone_left.x, 0.0f ); + idVec3 rightDir( node->cone_right.y, -node->cone_right.x, 0.0f ); + idVec3 org = node->GetPhysics()->GetOrigin() + node->offset; + + bounds[ 1 ].z = node->max_height; + + leftDir.NormalizeFast(); + rightDir.NormalizeFast(); + + const idMat3 &axis = node->GetPhysics()->GetAxis(); + float cone_dot = node->cone_right * axis[ 1 ]; + if ( idMath::Fabs( cone_dot ) > 0.1 ) { + float cone_dist = node->max_dist / cone_dot; + idVec3 pos1 = org + leftDir * node->min_dist; + idVec3 pos2 = org + leftDir * cone_dist; + idVec3 pos3 = org + rightDir * node->min_dist; + idVec3 pos4 = org + rightDir * cone_dist; + + gameRenderWorld->DebugLine( color, node->GetPhysics()->GetOrigin(), ( pos1 + pos3 ) * 0.5f, gameLocal.msec ); + gameRenderWorld->DebugLine( color, pos1, pos2, gameLocal.msec ); + gameRenderWorld->DebugLine( color, pos1, pos3, gameLocal.msec ); + gameRenderWorld->DebugLine( color, pos3, pos4, gameLocal.msec ); + gameRenderWorld->DebugLine( color, pos2, pos4, gameLocal.msec ); + gameRenderWorld->DebugBounds( color, bounds, org, gameLocal.msec ); + } + } +} + +/* +===================== +idCombatNode::EntityInView +===================== +*/ +bool idCombatNode::EntityInView( idActor *actor, const idVec3 &pos ) { + if ( !actor || ( actor->health <= 0 ) ) { + return false; + } + + const idBounds &bounds = actor->GetPhysics()->GetBounds(); + if ( ( pos.z + bounds[ 1 ].z < min_height ) || ( pos.z + bounds[ 0 ].z >= max_height ) ) { + return false; + } + + const idVec3 &org = GetPhysics()->GetOrigin() + offset; + const idMat3 &axis = GetPhysics()->GetAxis(); + idVec3 dir = pos - org; + float dist = dir * axis[ 0 ]; + + if ( ( dist < min_dist ) || ( dist > max_dist ) ) { + return false; + } + + float left_dot = dir * cone_left; + if ( left_dot < 0.0f ) { + return false; + } + + float right_dot = dir * cone_right; + if ( right_dot < 0.0f ) { + return false; + } + + return true; +} + +/* +===================== +idCombatNode::Event_Activate +===================== +*/ +void idCombatNode::Event_Activate( idEntity *activator ) { + disabled = !disabled; +} + +/* +===================== +idCombatNode::Event_MarkUsed +===================== +*/ +void idCombatNode::Event_MarkUsed( void ) { + if ( spawnArgs.GetBool( "use_once" ) ) { + disabled = true; + } +} + +// DarkMod sound propagation functions + +void idAI::SPLtoLoudness( SSprParms *propParms ) +{ + // put in frequency, duration and bandwidth effects here + propParms->loudness = propParms->propVol; +} + +bool idAI::CheckHearing( SSprParms *propParms ) +{ + bool returnval(false); + + if (propParms->loudness > m_AudThreshold) + { + returnval = true; + } + + return returnval; +} + +void idAI::HearSound(SSprParms *propParms, float noise, const idVec3& origin) +{ + if (m_bIgnoreAlerts) return; + + // TODO: + // Modify loudness by propVol/noise ratio, + // looking up a selectivity spawnarg on the AI to + // see how well the AI distinguishes signal from noise + + //psychLoud = pow(2, (propParms->loudness - threshold)/10 ); + // this scale didn't make much sense for the alerts ingame + // because the numbers would have been very close together for + // very different amounts of alert. + // It is better to keep it in dB. + + // and so alert units are born! + + /** + * NOTE: an AlertLevel of 1 constitutes just barely seeing something + * out of the corner of your eye, or just barely hearing a whisper + * of a sound for a short instant. An AlertLevel of 10 is seeing/hearing twice + * as much, 20 is four times as much, etc. + **/ + + // angua: alert increase is scaled by alertFactor (defined on prpagated sound). + // This way, different sounds can result in different alert increase at the same volume + float psychLoud = 1 + (propParms->loudness - m_AudThreshold) * propParms->alertFactor; + + // angua: alert increase can not exceed alertMax (defined on propagated sound) + if (psychLoud > propParms->alertMax) + { + psychLoud = propParms->alertMax; + } + + // don't alert the AI if they're deaf, or this is not a strong enough + // alert to overwrite another alert this frame + if (GetAcuity("aud") > 0 && psychLoud > m_AlertLevelThisFrame) + { + AI_HEARDSOUND = true; + m_SoundDir = origin; + + m_AlertedByActor = NULL; // grayman #2907 - needs to be cleared, otherwise it can be leftover from a previous sound this frame + + if (propParms->maker->IsType(idActor::Type)) + { + m_AlertedByActor = static_cast(propParms->maker); + } + else + { + // greebo: Take the responsible actor for motion sound + idActor* responsibleActor = propParms->maker->m_MovedByActor.GetEntity(); + if (responsibleActor != NULL) + { + m_AlertedByActor = responsibleActor; + } + } + + psychLoud *= GetAcuity("aud"); + + // angua: the actor who produced this noise is either unknown or an enemy + // alert now + if (!m_AlertedByActor.GetEntity() || IsEnemy(m_AlertedByActor.GetEntity())) + { + AlertAI( "aud", psychLoud ); + + // greebo: Notify the currently active state + mind->GetState()->OnAudioAlert(); + } + + // Retrieve the messages from the other AI, if there are any + if (propParms->makerAI != NULL) + { + for (int i = 0; i < propParms->makerAI->m_Messages.Num(); i++) + { + mind->GetState()->OnAICommMessage(*propParms->makerAI->m_Messages[i], psychLoud); + } + } + + if( cv_spr_show.GetBool() ) + { + gameRenderWorld->DrawText( va("Alert: %.2f", psychLoud), + (GetEyePosition() - GetPhysics()->GetGravityNormal() * 55.0f), 0.25f, + colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec * 30); + } + + if ( cv_ai_debug.GetBool() ) + { + gameLocal.Printf("AI %s HEARD a sound\n", name.c_str()); + } + } +} + +void idAI::AlertAI(const char *type, float amount) +{ + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AlertAI called\r"); + + if (m_bIgnoreAlerts) + { + return; + } + + float acuity = GetAcuity(type); + // Calculate the amount the current AI_AlertLevel is about to be increased + // float alertInc = amount * acuity * 0.01f; // Acuity is defaulting to 100 (= 100%) + // angua: alert amount already includes acuity + + float alertInc = amount; + + // Ignore actors in notarget mode + idActor* actor = m_AlertedByActor.GetEntity(); + + if (actor != NULL && actor->fl.notarget) + { + // Actor is set to notarget, quit + return; + } + + if (m_AlertGraceTime) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period active, testing... \r"); + if (gameLocal.time > m_AlertGraceStart + m_AlertGraceTime) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period found to have expired. Resetting. \r"); + m_AlertGraceTime = 0; + m_AlertGraceActor = NULL; + m_AlertGraceStart = 0; + m_AlertGraceThresh = 0; + m_AlertGraceCount = 0; + m_AlertGraceCountLimit = 0; + } + else if (alertInc < m_AlertGraceThresh && + actor != NULL && + actor == m_AlertGraceActor.GetEntity() && + m_AlertGraceCount < m_AlertGraceCountLimit) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period allowed, ignoring alert. \r"); + m_AlertGraceCount++; + + // Quick hack: Large lightgem values and visual alerts override the grace period count faster + if (AI_VISALERT) + { + // greebo: Let the alert grace count increase by 12.5% of the current lightgem value + // The maximum increase is therefore 32/8 = 4 based on DARKMOD_LG_MAX at the time of writing. + if (actor->IsType(idPlayer::Type)) + { + idPlayer* player = static_cast(actor); + m_AlertGraceCount += static_cast(idMath::Rint(player->GetCurrentLightgemValue() * 0.125f)); + } + } + return; + } + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Alert %f above threshold %f, or actor is not grace period actor\r", alertInc, m_AlertGraceThresh); + } + + // set the last alert value so that simultaneous alerts only overwrite if they are greater than the value + m_AlertLevelThisFrame = amount; + + // The grace check has failed, increase the AI_AlertLevel float by the increase amount + float newAlertLevel = AI_AlertLevel + alertInc; + SetAlertLevel(newAlertLevel); + m_lastAlertLevel = newAlertLevel; + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING( "AI ALERT: AI %s alerted by alert type \"%s\", amount %f (modified by acuity %f). Total alert level now: %f\r", name.c_str(), type, amount, acuity, (float) AI_AlertLevel ); + + if( cv_ai_debug.GetBool() ) + gameLocal.Printf("[TDM AI] ALERT: AI %s alerted by alert type \"%s\", base amount %f, modified by acuity %f percent. Total alert level now: %f\n", name.c_str(), type, amount, acuity, (float) AI_AlertLevel ); + + if (gameLocal.isNewFrame) + { + // AI has been alerted, set the boolean + AI_ALERTED = true; + } + + // Objectives callback + gameLocal.m_MissionData->AlertCallback( this, m_AlertedByActor.GetEntity(), static_cast(AI_AlertIndex) ); +} + +void idAI::SetAlertLevel(float newAlertLevel) +{ + // greebo: Clamp the (log) alert number to twice the combat threshold. + if (newAlertLevel > thresh_5*2) + { + newAlertLevel = thresh_5*2; + } + else if (newAlertLevel < 0) + { + newAlertLevel = 0; + } + + bool alertRising = (newAlertLevel > AI_AlertLevel); + + if (alertRising) + { + GetMemory().lastAlertRiseTime = gameLocal.time; + } + + if (AI_DEAD || AI_KNOCKEDOUT) return; + + AI_AlertLevel = newAlertLevel; + + if (AI_AlertLevel > m_maxAlertLevel) + { + m_maxAlertLevel = AI_AlertLevel; + } + + // grace period vars + float grace_time; + float grace_frac; + int grace_count; + + // How long should this alert level last, and which alert index should we be in now? + if (newAlertLevel >= thresh_4) + { + // greebo: Only allow switching to combat if a valid enemy is set. + if (newAlertLevel >= thresh_5) + { + if (GetEnemy() != NULL) + { + // We have an enemy, raise the index + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::ECombat; + } + else + { + // No enemy, can't switch to Combat mode + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::EAgitatedSearching; + // Set the alert level back to just below combat threshold + AI_AlertLevel = thresh_5 - 0.01; + } + } + else + { + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::EAgitatedSearching; + } + grace_time = m_gracetime_4; + grace_frac = m_gracefrac_4; + grace_count = m_gracecount_4; + } + else if (newAlertLevel >= thresh_3) + { + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::EInvestigating; + grace_time = m_gracetime_3; + grace_frac = m_gracefrac_3; + grace_count = m_gracecount_3; + } + else if (newAlertLevel >= thresh_2) + { + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::ESuspicious; + grace_time = m_gracetime_2; + grace_frac = m_gracefrac_2; + grace_count = m_gracecount_2; + } + else if (newAlertLevel >= thresh_1) + { + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::EObservant; + grace_time = m_gracetime_1; + grace_frac = m_gracefrac_1; + grace_count = m_gracecount_1; + } + else + { + m_prevAlertIndex = AI_AlertIndex; + AI_AlertIndex = ai::ERelaxed; + grace_time = 0.0; + grace_frac = 0.0; + grace_count = 0; + } + + // Tels: When the AI_AlertIndex increased, detach all bound entities + // that have set "unbindonalertIndex" higher or equal: + if (m_prevAlertIndex < AI_AlertIndex) + { + DetachOnAlert( AI_AlertIndex ); + } + + // greebo: Remember the highest alert index + if (AI_AlertIndex > m_maxAlertIndex) + { + m_maxAlertIndex = AI_AlertIndex; + } + + // Begin the grace period + if (alertRising) + { + Event_SetAlertGracePeriod( grace_frac, grace_time, grace_count ); + } +} + +bool idAI::AlertIndexIncreased() +{ + return (AI_AlertIndex > m_prevAlertIndex); +} + +float idAI::GetAcuity(const char *type) const +{ + float returnval(-1); + + // Try to lookup the ID in the hashindex. This corresponds to an entry in m_acuityNames. + int ind = g_Global.m_AcuityHash.First( g_Global.m_AcuityHash.GenerateKey(type, false) ); +// DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Retrived Acuity index %d for type %s\r", ind, type); + + if (ind == -1 ) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("AI %s attempted to query nonexistant acuity type: %s", name.c_str(), type); + gameLocal.Warning("[AI] AI %s attempted to query nonexistant acuity type: %s", name.c_str(), type); + return returnval; + } + else if (ind > m_Acuities.Num()) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Acuity index %d exceed acuity array size %d!\r", ind, m_Acuities.Num()); + return returnval; + } + + // Lookup the acuity value using the index from the hashindex + returnval = m_Acuities[ind]; + + // SZ: June 10, 2007 + // Acuities are now modified by alert level + if (returnval > 0.0) + { + if (m_maxAlertLevel >= thresh_5) + { + returnval *= cv_ai_acuity_L5.GetFloat(); + } + else if (m_maxAlertLevel >= thresh_4) + { + returnval *= cv_ai_acuity_L4.GetFloat(); + } + else if (m_maxAlertLevel >= thresh_3) + { + returnval *= cv_ai_acuity_L3.GetFloat(); + } + } + + // angua: drunken AI have reduced acuity, unless they have seen evidence of intruders + if (spawnArgs.GetBool("drunk", "0") && HasSeenEvidence() == false) + { + returnval *= spawnArgs.GetFloat("drunk_acuity_factor", "1"); + } + + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Acuity %s = %f\r", type, returnval); + + return returnval; +} + +void idAI::SetAcuity( const char *type, float acuity ) +{ + int ind; + + ind = g_Global.m_AcuityHash.First( g_Global.m_AcuityHash.GenerateKey( type, false ) ); + + if (ind == -1) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Script on %s attempted to set nonexistant acuity type: %s\r",name.c_str(), type); + gameLocal.Warning("[AI] Script on %s attempted to set nonexistant acuity type: %s",name.c_str(), type); + goto Quit; + } + else if( ind > m_Acuities.Num() ) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Script on %s attempted to set acuity with an index %d greater than acuities array size %d!\r", ind, m_Acuities.Num() ); + goto Quit; + } + + m_Acuities[ind] = acuity; + +Quit: + return; +} + +idVec3 idAI::GetSndDir( void ) +{ + return m_SoundDir; +} + +idVec3 idAI::GetVisDir( void ) +{ + return m_LastSight; +} + +idEntity *idAI::GetTactEnt( void ) +{ + return m_TactAlertEnt.GetEntity(); +} + +void idAI::PerformVisualScan(float timecheck) +{ + // Only perform enemy checks if we are in the player's PVS + if (GetAcuity("vis") <= 0 || !gameLocal.InPlayerPVS(this)) + { + return; + } + + idActor* player = gameLocal.GetLocalPlayer(); + if (m_bIgnoreAlerts || player->fl.notarget) + { + // notarget + return; + } + + // Ignore dead actors or non-enemies + if (player->health <= 0 || !IsEnemy(player)) + { + return; + } + + if (!CheckFOV(player->GetEyePosition())) + { + return; + } + + // Check the candidate's visibility. + float visFrac = GetVisibility(player); + // Do the percentage check + float randFrac = gameLocal.random.RandomFloat(); + float chance = timecheck / s_VisNormtime * cv_ai_sight_prob.GetFloat() * visFrac; + if( randFrac > chance) + { + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Random number check failed: random %f > number %f\r", randFrac, (timecheck / s_VisNormtime) * visFrac ); + return; + } + + // angua: does not take lighting and FOV into account + if (!CanSeeExt(player, false, false)) + { + return; + } + + // greebo: At this point, the actor is identified as enemy and is visible + // set AI_VISALERT and the vector for last sighted position + // Store the position the enemy was visible + m_LastSight = player->GetPhysics()->GetOrigin(); + AI_VISALERT = true; + + // Get the visual alert amount caused by the CVAR setting + // float incAlert = GetPlayerVisualStimulusAmount(); + + // angua: alert increase depends on brightness, distance and acuity + float incAlert = 4 + 9 * visFrac; + + if (cv_ai_visdist_show.GetFloat() > 0) + { + gameRenderWorld->DrawText("see you!", GetEyePosition() + idVec3(0,0,70), 0.2f, idVec4( 0.5f, 0.00f, 0.00f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 60 * gameLocal.msec); + gameRenderWorld->DrawText(va("Alert increase: %.2f", incAlert), GetEyePosition() + idVec3(0,0,60), 0.2f, idVec4( 0.5f, 0.00f, 0.00f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 60 * gameLocal.msec); + } + + float newAlertLevel = AI_AlertLevel + incAlert; + if (newAlertLevel > thresh_5) + { + SetEnemy(player); + } + + // If the alert amount is larger than everything else encountered this frame + // ignore the previous alerts and remember this actor as enemy. + if (incAlert > m_AlertLevelThisFrame) + { + // Remember this actor + m_AlertedByActor = player; + AlertAI("vis", incAlert); + + // Call the visual alert handler on the current state + mind->GetState()->OnVisualAlert(player); + } + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s SAW actor %s\r", name.c_str(), player->name.c_str() ); + + return; +} + + +float idAI::GetVisibility( idEntity *ent ) const +{ + // Returns the probability that the entity will be seen within half a second + // depends on light gem brightness, visual acuity and player distance + + float returnval(0); + + // for now, only players may have their visibility checked + if (!ent->IsType( idPlayer::Type )) + { + return returnval; + } + idPlayer* player = static_cast(ent); + + // angua: probability for being seen (within half a second) + // this depends only on the brightness of the light gem and the AI's visual acuity + float clampVal = GetCalibratedLightgemValue(); + + /** + * angua: within the clampDist, the probability stays constant + * the probability decreases linearly towards 0 between clampdist and savedist + * both distances are scaled with clampVal + */ + float clampdist = cv_ai_sightmindist.GetFloat() * clampVal; + float safedist = clampdist + (cv_ai_sightmaxdist.GetFloat() - cv_ai_sightmindist.GetFloat()) * clampVal; + + idVec3 delta = GetEyePosition() - player->GetEyePosition(); + float dist = delta.Length()*s_DOOM_TO_METERS; + + if (dist < clampdist) + { + returnval = clampVal; + } + else + { + if (dist > safedist) + { + returnval = 0; + } + else + { + returnval = clampVal * (1 - (dist-clampdist)/(safedist-clampdist) ); + } + } + + if (cv_ai_visdist_show.GetFloat() > 0) + { + idStr alertText(clampVal); + alertText = "clampVal: "+ alertText; + gameRenderWorld->DrawText(alertText.c_str(), GetEyePosition() + idVec3(0,0,1), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + idStr alertText2(clampdist); + alertText2 = "clampdist: "+ alertText2; + gameRenderWorld->DrawText(alertText2.c_str(), GetEyePosition() + idVec3(0,0,10), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + gameRenderWorld->DebugCircle(idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), GetPhysics()->GetOrigin(),idVec3(0,0,1), clampdist / s_DOOM_TO_METERS, 100, gameLocal.msec); + idStr alertText3(safedist); + alertText3 = "savedist: "+ alertText3; + gameRenderWorld->DrawText(alertText3.c_str(), GetEyePosition() + idVec3(0,0,20), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + gameRenderWorld->DebugCircle(idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), GetPhysics()->GetOrigin(),idVec3(0,0,1), safedist / s_DOOM_TO_METERS, 100, gameLocal.msec); + idStr alertText4(returnval); + alertText4 = "returnval: "+ alertText4; + gameRenderWorld->DrawText(alertText4.c_str(), GetEyePosition() + idVec3(0,0,30), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + idStr alertText5(dist); + alertText5 = "distance: "+ alertText5; + gameRenderWorld->DrawText(alertText5.c_str(), GetEyePosition() + idVec3(0,0,-10), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + } + + return returnval; +} + +float idAI::GetCalibratedLightgemValue() const +{ + idPlayer* player = gameLocal.GetLocalPlayer(); + if (player == NULL) return 0.0f; + + float lgem = static_cast(player->GetCurrentLightgemValue()); + + float term0 = -0.003f; + float term1 = 0.03f * lgem; + float term2 = 0.001f * idMath::Pow16(lgem, 2); + float term3 = 0.00013f * idMath::Pow16(lgem, 3); + float term4 = - 0.000011f * idMath::Pow16(lgem, 4); + float term5 = 0.0000001892f * idMath::Pow16(lgem, 5); + + float clampVal = term0 + term1 + term2 + term3 + term4 + term5; + + clampVal *= GetAcuity("vis"); + + if (clampVal > 1) + { + clampVal = 1; + } + + // Debug output + if (cv_ai_visdist_show.GetFloat() > 0) + { + idStr alertText5(lgem); + alertText5 = "lgem: "+ alertText5; + gameRenderWorld->DrawText(alertText5.c_str(), GetEyePosition() + idVec3(0,0,40), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); + } + + return clampVal; +} + +void idAI::TactileAlert(idEntity* tactEnt, float amount) +{ + if (AI_DEAD || AI_KNOCKEDOUT || m_bIgnoreAlerts) + { + return; + } + + if (tactEnt == NULL || CheckTactileIgnore(tactEnt)) + { + return; + } + + // grayman #2872 - have we encountered a dangling rope from a rope arrow? + + if ( tactEnt->IsType(idAFEntity_Generic::Type) ) + { + if ( idStr::FindText( tactEnt->name, "env_rope" ) >= 0 ) + { + // Ignore the rope if you have an enemy. + + if ( GetEnemy() == NULL ) + { + // Find the bindMaster for this rope, then see if there's a CProjectileResult bound to it. + + idEntity* bindMaster = tactEnt->GetBindMaster(); + if ( bindMaster != NULL ) + { + idEntity* stimSource = bindMaster->FindMatchingTeamEntity( CProjectileResult::Type ); + if ( stimSource != NULL ) + { + if ( !stimSource->CheckResponseIgnore(ST_VISUAL,this) ) // only react if you haven't encountered this rope before, + // either by bumping it or receiving its stim + { + // What's the chance of noticing this rope? If it's zero, you're to ignore the rope. + // If it's greater than zero, and even if it's less than 1.0, you walked into the + // rope, so we expect you to notice it. + + float chanceToNotice = spawnArgs.GetFloat("chanceNoticeRope","0.0"); + if ( chanceToNotice > 0.0 ) + { + if ( mind->GetState()->ShouldProcessAlert(ai::EAlertTypeRope) ) + { + mind->GetState()->OnVisualStimRope(stimSource,this,GetEyePosition()); + } + } + else // This rope stim should stop sending me stims + { + stimSource->IgnoreResponse(ST_VISUAL, this); + } + } + } + } + } + } + + return; + } + + // The actor is either the touched entity or the originator of the tactile alert + idActor* responsibleActor = + (tactEnt->IsType(idActor::Type)) ? static_cast(tactEnt) : tactEnt->m_SetInMotionByActor.GetEntity(); + + if (responsibleActor == NULL) + { + return; + } + + if (IsFriend(responsibleActor)) + { + if (responsibleActor->health <= 0 || responsibleActor->IsKnockedOut()) + { + // angua: We've found a friend that is dead or unconscious + mind->GetState()->OnPersonEncounter(tactEnt, this); + } + } + if (!IsEnemy(responsibleActor)) + { + return; // not an enemy, no alert + } + + // greebo: We touched an enemy, check if it's an unconscious body or corpse + if (tactEnt->IsType(idAI::Type) && + (static_cast(tactEnt)->AI_DEAD || static_cast(tactEnt)->AI_KNOCKEDOUT)) + { + // When AI_DEAD or AI_KNOCKEDOUT ignore this alert from now on to avoid + // re-alerting us every time we touch it again and again + TactileIgnore(tactEnt); + } + + // Set the alert amount to the according tactile alert value + if (amount == -1) + { + amount = cv_ai_tactalert.GetFloat(); + } + + // If we got this far, we give the alert + // NOTE: Latest tactile alert always overrides other alerts + m_TactAlertEnt = tactEnt; + m_AlertedByActor = responsibleActor; + + amount *= GetAcuity("tact"); + AlertAI("tact", amount); + + // Notify the currently active state + mind->GetState()->OnTactileAlert(tactEnt); + + // Set last visual contact location to this location as that is used in case + // the target gets away + m_LastSight = tactEnt->GetPhysics()->GetOrigin(); + + // If no enemy set so far, set the last visible enemy position. + if (GetEnemy() == NULL) + { + lastVisibleEnemyPos = tactEnt->GetPhysics()->GetOrigin(); + } + + AI_TACTALERT = true; + + if( cv_ai_debug.GetBool() ) + { + // Note: This can spam the log a lot, so only put it in if cv_ai_debug.GetBool() is true + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s FELT entity %s\r", name.c_str(), tactEnt->name.c_str() ); + gameLocal.Printf( "[DM AI] AI %s FELT entity %s\n", name.c_str(), tactEnt->name.c_str() ); + } +} + +void idAI::TactileIgnore(idEntity* tactEnt) +{ + tactileIgnoreEntities.insert(tactEnt); +} + +bool idAI::CheckTactileIgnore(idEntity* tactEnt) +{ + TactileIgnoreList::iterator i = tactileIgnoreEntities.find(tactEnt); + if (i != tactileIgnoreEntities.end()) + { + return true; + } + return false; +} + + + + +idActor *idAI::FindEnemy(bool useFOV) +{ + // Only perform enemy checks if we are in the player's PVS + if (!gameLocal.InPlayerPVS(this)) + { + return NULL; + } + + // Go through all clients (=players) + for (int i = 0; i < gameLocal.numClients ; i++) + { + idEntity* ent = gameLocal.entities[i]; + + if (ent == NULL || ent->fl.notarget || !ent->IsType(idActor::Type)) + { + // NULL, notarget or non-Actor, continue + continue; + } + + idActor* actor = static_cast(ent); + + // Ignore dead actors or non-enemies + if (actor->health <= 0 || !IsEnemy(actor)) + { + continue; + } + + // angua: does not take lighting into account any more, + // this is done afterwards using GetVisibility + if (CanSeeExt(actor, useFOV, false)) + { + // Enemy actor found and visible, return it + return actor; + } + } + + return NULL; +} + +idActor* idAI::FindEnemyAI(bool useFOV) +{ + pvsHandle_t pvs = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); + + float bestDist = idMath::INFINITY; + idActor* bestEnemy = NULL; + + for (idEntity* ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + if ( ent->fl.hidden || ent->fl.isDormant || ent->fl.notarget || !ent->IsType( idActor::Type ) ) { + continue; + } + + idActor* actor = static_cast( ent ); + if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { + continue; + } + + if ( !gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas() ) ) { + continue; + } + + idVec3 delta = physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin(); + float dist = delta.LengthSqr(); + if ( ( dist < bestDist ) && CanSee( actor, useFOV != 0 ) ) { + bestDist = dist; + bestEnemy = actor; + } + } + + gameLocal.pvs.FreeCurrentPVS(pvs); + return bestEnemy; +} + +idActor* idAI::FindFriendlyAI(int requiredTeam) +{ +// This is our return value + idActor* candidate(NULL); + // The distance of the nearest found AI + float bestDist = idMath::INFINITY; + + // Setup the PVS areas of this entity using the PVSAreas set, this returns a handle + pvsHandle_t pvs(gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas())); + + // Iterate through all active entities and find an AI with the given team. + for (idEntity* ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + if ( ent == this || ent->fl.hidden || ent->fl.isDormant || !ent->IsType( idActor::Type ) ) { + continue; + } + + idActor* actor = static_cast(ent); + if (actor->health <= 0) { + continue; + } + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Taking actor %s into account\r", actor->name.c_str()); + + if (requiredTeam != -1 && actor->team != requiredTeam) { + // wrong team + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Taking actor %s has wrong team: %d\r", actor->name.c_str(), actor->team); + continue; + } + + if (!IsFriend(actor)) + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s is not on friendly team: %d or has specific relation that is not friendly\r", actor->name.c_str(), actor->team); + // Not friendly + continue; + } + + if (!gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas())) { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s is not in PVS\r", actor->name.c_str()); + // greebo: This actor is not in our PVS, skip it + continue; + } + + float dist = (physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin()).LengthSqr(); + if ( (dist < bestDist) && CanSee(actor, true) ) { + // Actor can be seen and is nearer than the best candidate, save it + bestDist = dist; + candidate = actor; + } + } + + gameLocal.pvs.FreeCurrentPVS(pvs); + + return candidate; + +} + + +/*---------------------------------------------------------------------------------*/ + +float idAI::GetMaximumObservationDistanceForPoints(const idVec3& p1, const idVec3& p2) const +{ + return LAS.queryLightingAlongLine(p1, p2, NULL, true) * cv_ai_sight_scale.GetFloat() * GetAcuity("vis"); +} + +float idAI::GetMaximumObservationDistance(idEntity* entity) const +{ + assert(entity != NULL); // don't accept NULL input + + float lightQuotient = entity->GetLightQuotient(); + + return lightQuotient * cv_ai_sight_scale.GetFloat() * GetAcuity("vis"); +} + +/*---------------------------------------------------------------------------------*/ + +float idAI::GetPlayerVisualStimulusAmount() const +{ + float alertAmount = 0.0; + + // Quick fix for blind AI: + if (GetAcuity("vis") > 0 ) + { + // float visFrac = GetVisibility( p_playerEntity ); + // float lgem = (float) g_Global.m_DarkModPlayer->m_LightgemValue; + // Convert to alert units ( 0.6931472 = ln(2) ) + // Old method, commented out + // alertAmount = 4*log( visFrac * lgem ) / 0.6931472; + + // The current alert number is stored in logarithmic units + float curAlertLog = AI_AlertLevel; + + // convert current alert from log to linear scale, add, then convert back + // this might not be as good for performance, but it lets us keep all alerts + // on the same scale. + if (curAlertLog > 0) + { + // greebo: Convert log to lin units by using Alin = 2^[(Alog-1)/10] + float curAlertLin = idMath::Pow16(2, (curAlertLog - 1)*0.1f); + + // Increase the linear alert number with the cvar + curAlertLin += cv_ai_sight_mag.GetFloat(); + + // greebo: Convert back to logarithmic alert units + // The 1.44269 in the equation is the 1/ln(2) used to compensate for using the natural Log16 method. + curAlertLog = 1 + 10.0f * idMath::Log16(curAlertLin) * 1.442695f; + + // Now calculate the difference in logarithmic units and return it + alertAmount = curAlertLog - AI_AlertLevel; + } + else + { + alertAmount = 1; + } + } + + return alertAmount; +} + +/*---------------------------------------------------------------------------------*/ + +bool idAI::IsEntityHiddenByDarkness(idEntity* p_entity, const float sightThreshold) const +{ + // Quick test using LAS at entity origin + idPhysics* p_physics = p_entity->GetPhysics(); + + if (p_physics == NULL) + { + return false; // Not in darkness + } + + // Use lightgem if it is the player + if (p_entity->IsType(idPlayer::Type)) + { + // Get the alert increase amount (log) caused by the CVAR tdm_ai_sight_mag + // greebo: Commented this out, this is not suitable to detect if player is hidden in darkness + //float incAlert = GetPlayerVisualStimulusAmount(); + + // greebo: Check the visibility of the player depending on lgem and distance + float visFraction = GetCalibratedLightgemValue(); // returns values in [0..1] +/* + // greebo: Debug output, comment me out + gameRenderWorld->DrawText(idStr(visFraction), GetEyePosition() + idVec3(0,0,1), 0.11f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); +*/ + // Draw debug graphic + /*if (cv_ai_visdist_show.GetFloat() > 1.0) + { + idVec4 markerColor (0.0, 0.0, 0.0, 0.0); + + float percToSeen = 1.0; + if (sightThreshold > 0 && sightThreshold > incAlert) + { + percToSeen = (sightThreshold - incAlert) / sightThreshold; + } + + // Scale red to green from not perceptable to quickly perceptable + markerColor.x = idMath::Sin (percToSeen * (idMath::PI / 2.0)); + markerColor.y = idMath::Cos (percToSeen * (idMath::PI / 2.0)); + + idVec3 observeFrom = GetEyePosition(); + + gameRenderWorld->DebugArrow(markerColor, observeFrom, p_physics->GetOrigin(), 2, cv_ai_visdist_show.GetInteger()); + }*/ + + // Very low threshold for visibility + if (visFraction < sightThreshold) + { + // Not visible, entity is hidden in darkness + return true; + } + else + { + // Visible, visual stim above threshold + return false; + } + } + else // Not the player + { + float maxDistanceToObserve = GetMaximumObservationDistance(p_entity); + + // Are we close enough to see it in the current light level? + idVec3 observeFrom = GetEyePosition(); + idVec3 midPoint = p_entity->GetPhysics()->GetAbsBounds().GetCenter(); + + if ( (observeFrom - midPoint).LengthSqr() > maxDistanceToObserve*maxDistanceToObserve ) + { + // Draw debug graphic? + if (cv_ai_visdist_show.GetFloat() > 1.0f) + { + idVec3 arrowLength = midPoint - observeFrom; + arrowLength.Normalize(); + arrowLength *= maxDistanceToObserve; + + // Distance we could see + gameRenderWorld->DebugArrow(colorRed, observeFrom, observeFrom + arrowLength, 2, cv_ai_visdist_show.GetInteger()); + + // Gap to where we want to see + gameRenderWorld->DebugArrow(colorMagenta, observeFrom + arrowLength, midPoint, 2, cv_ai_visdist_show.GetInteger()); + } + + return true; // hidden by darkness + } + else + { + // Draw debug graphic? + if (cv_ai_visdist_show.GetFloat() > 1.0f) + { + // We can see to target + gameRenderWorld->DebugArrow(colorGreen, observeFrom, midPoint, 2, cv_ai_visdist_show.GetInteger()); + } + + return false; // not hidden by darkness + } + } +} + +/*---------------------------------------------------------------------------------*/ + +idActor *idAI::FindNearestEnemy( bool useFOV ) +{ + idEntity *ent; + idActor *actor, *playerEnemy; + idActor *bestEnemy; + float bestDist; + float dist; + idVec3 delta; + pvsHandle_t pvs; + + pvs = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); + + bestDist = idMath::INFINITY; + bestEnemy = NULL; + + for ( ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { + if ( ent->fl.hidden || ent->fl.isDormant || !ent->IsType( idActor::Type ) ) + { + continue; + } + + actor = static_cast( ent ); + if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) + { + continue; + } + + if ( !gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas() ) ) + { + continue; + } + + delta = physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin(); + dist = delta.LengthSqr(); + if ( ( dist < bestDist ) && CanSee( actor, useFOV ) ) { + bestDist = dist; + bestEnemy = actor; + } + } + + playerEnemy = FindEnemy(false); + if( !playerEnemy ) + goto Quit; + + delta = physicsObj.GetOrigin() - playerEnemy->GetPhysics()->GetOrigin(); + dist = delta.LengthSqr(); + + if( dist < bestDist ) + bestEnemy = playerEnemy; + bestDist = dist; + +Quit: + gameLocal.pvs.FreeCurrentPVS( pvs ); + return bestEnemy; +} + + + +void idAI::HadTactile( idActor *actor ) +{ + if( !actor ) + goto Quit; + + if( IsEnemy( actor) ) + TactileAlert( actor ); + else + { + // TODO: FLAG BLOCKED BY FRIENDLY SO THE SCRIPT CAN DO SOMETHING ABOUT IT + + // grayman #2728 - If blocked by an AI of small mass, kick it aside immediately. If you leave it to normal + // block resolution, the larger AI will appear to be momentarily stopped by the small AI, + // which is not what you'd expect to see. + + float actorMass = actor->GetPhysics()->GetMass(); + if ((actorMass <= 5.0) && (physicsObj.GetMass() > 5.0)) + { + if (gameLocal.time >= actor->m_nextKickTime) // but only if not recently kicked + { + KickObstacles(viewAxis[0],1.25*kickForce*actorMass,actor); + actor->m_nextKickTime = gameLocal.time + 1000; // need to wait before kicking again, + // otherwise kicks can build up over adjacent frames + } + } + } + + // alert both AI if they bump into eachother + if( actor->IsEnemy(this) + && actor->IsType(idAI::Type) ) + { + static_cast(actor)->TactileAlert( this ); + } + +Quit: + return; +} + +/* +===================== +idAI::GetMovementVolMod +===================== +*/ + +float idAI::GetMovementVolMod( void ) +{ + float returnval; + bool bCrouched(false); + + if( AI_CROUCH ) + bCrouched = true; + + // figure out which of the 6 cases we have: + if( !AI_RUN && !AI_CREEP ) + { + if( !bCrouched ) + returnval = m_stepvol_walk; + else + returnval = m_stepvol_crouch_walk; + } + + // NOTE: running always has priority over creeping + else if( AI_RUN ) + { + if( !bCrouched ) + returnval = m_stepvol_run; + else + returnval = m_stepvol_crouch_run; + } + + else if( AI_CREEP ) + { + if( !bCrouched ) + returnval = m_stepvol_creep; + else + returnval = m_stepvol_crouch_creep; + } + + else + { + // something unexpected happened + returnval = 0; + } + + return returnval; +} + +/* +===================== +idAI::CheckTactile + +Modified 5/25/06 , removed trace computation, found better way of checking +===================== +*/ +void idAI::CheckTactile() +{ + // Only check tactile alerts if we aren't Dead, KO or already engaged in combat. + + // grayman #2345 - changed to handle the waiting, non-solid state for AI + + bool bumped = false; + idEntity* blockingEnt = NULL; + if (!AI_KNOCKEDOUT && !AI_DEAD && (AI_AlertLevel < thresh_5) && !movementSubsystem->IsWaitingNonSolid()) // no bump if I'm waiting + { + blockingEnt = physicsObj.GetSlideMoveEntity(); + if (blockingEnt) // grayman #2345 - note what we bumped into + { + if (blockingEnt->name != "world") // ignore bumping into the world + { + m_tactileEntity = blockingEnt; + + if ( blockingEnt->IsType(idAI::Type) ) + { + idAI* blockingAI = static_cast(blockingEnt); + + // grayman #2903 - if both AI are examining a rope, it's possible that + // they're both trying to reach the same examination spot. If one is not + // moving, he's examining, so the other has to stop where he is. This + // prevents the one standing from turning non-solid and allowing the other + // to merge with him. Looks bad. + + if ( m_ExaminingRope && blockingAI->m_ExaminingRope ) + { + if ( AI_FORWARD && !blockingAI->AI_FORWARD ) + { + StopMove(MOVE_STATUS_DONE); + } + else if ( !AI_FORWARD && blockingAI->AI_FORWARD ) + { + blockingAI->StopMove(MOVE_STATUS_DONE); + } + } + } + } + } + + if (blockingEnt && blockingEnt->IsType(idPlayer::Type)) // player has no movement subsystem + { + // aesthetics: Dont react to dead player? + if (blockingEnt->health > 0) + { + bumped = true; + } + } + else if (blockingEnt && blockingEnt->IsType(idActor::Type)) + { + idAI *e = static_cast(blockingEnt); + if (e && !e->movementSubsystem->IsWaitingNonSolid()) // no bump if other entity is waiting + { + bumped = true; + } + } + } + + if (bumped) + { + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("TACT: AI %s is bumping actor %s.\r", name.c_str(), blockingEnt->name.c_str() ); + HadTactile(static_cast(blockingEnt)); + } +} + +bool idAI::HasSeenEvidence() const +{ + ai::Memory& memory = GetMemory(); + + return memory.enemiesHaveBeenSeen + || memory.hasBeenAttackedByEnemy + || memory.itemsHaveBeenStolen + || memory.itemsHaveBeenBroken + || memory.unconsciousPeopleHaveBeenFound + || memory.deadPeopleHaveBeenFound + || spawnArgs.GetBool("alert_idle", "0"); +} + +/** +* ========================== BEGIN TDM KNOCKOUT CODE ============================= +**/ + +/* +===================== +idAI::TestKnockoutBlow +===================== +*/ + +bool idAI::TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ) +{ + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Attempted KO of AI %s\r", name.c_str()); + + if ( AI_DEAD ) + { + return false; // already dead + } + + if ( AI_KNOCKEDOUT ) + { + AI_PAIN = true; + AI_DAMAGE = true; + + return false; // already knocked out + } + + const char* locationName = GetDamageGroup( location ); + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s hit with KO object in joint %d corresponding to damage group %s\r", name.c_str(), location, locationName); + + // check if we're hitting the right zone (usually the head) + if ( idStr::Cmp(locationName, m_KoZone) != 0 ) + { + // Signal the failed KO to the current state + GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, false); + + return false; // damage zone not matching + } + + // check if we hit within the angles + if ( m_HeadJointID == INVALID_JOINT ) + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Invalid head joint for joint found on AI %s when KO attempted \r", name.c_str()); + return false; + } + + // Get the KO angles + float minDotVert = m_KoDotVert; + float minDotHoriz = m_KoDotHoriz; + + // Check if the AI is above the alert threshold for Immunity + // Defined the name of the alert threshold in the AI def for generality + +/* grayman #2930 - follow these rules to determine immunity: + + 1. Civilians can be knocked out at any time, from any angle, at any alert level. + 2. If the AI's alert level is at least m_KoAlertImmuneState, and + m_bKoAlertImmune is TRUE, the AI is immune. + 3. If the AI has a sheathed weapon or no weapon, and their alert level + is below m_KoAlertImmuneState, a KO can occur from any direction. + 4. If the AI is ready to do combat (usually a drawn weapon), and their + m_KoAlertImmuneState == 4 (helmet), they're immune, even if they're at a lower alert level. + 5. If the AI is ready to do combat (usually a drawn weapon), and their + m_KoAlertImmuneState == 5 (no helmet), and their current alert level is + below m_KoAlertImmuneState, a KO can occur only from behind. + 6. Finally, check the KO angles and determine if the blow has landed in the right place. + */ + + bool immune2KO = false; + if ( spawnArgs.GetBool("is_civilian", "0") ) + { + // Rule #1 + } + // everyone else is a combatant + else if ( AI_AlertIndex >= m_KoAlertImmuneState ) + { + // is the AI immune at high alert levels? + if ( m_bKoAlertImmune ) + { + immune2KO = true; // Rule #2 + } + else + { + // At high alert levels, use different values + minDotVert = m_KoAlertDotVert; + minDotHoriz = m_KoAlertDotHoriz; + } + } + // alert level isn't high enough for carte-blanche immunity, so check other factors + else if ( GetAttackFlag(COMBAT_MELEE) || GetAttackFlag(COMBAT_RANGED) ) + { + if ( m_KoAlertImmuneState == 4 ) // wearing helmet? + { + immune2KO = true; // Rule #4 + } + else // Rule #5 + { + // A KO can occur only from behind, when this AI is more likely to be surprised + + idVec3 aiForward = viewAxis.ToAngles().ToForward(); + if ( dir * aiForward < 0.0f ) + { + immune2KO = true; // attacked from the front + } + else + { + // Rule #5 - // attacked from behind, so not immune + + // treat a drawn weapon or an unarmed AI that can fight as a highly alerted state for KO purposes + minDotVert = m_KoAlertDotVert; + minDotHoriz = m_KoAlertDotHoriz; + } + } + } + else + { + // Rule #3 - sheathed weapon or no weapon; not immune + } + + if ( immune2KO ) + { + // Signal the failed KO to the current state + GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, true); + return false; // AI is immune, so no KO this time + } + + idVec3 KOSpot; + idMat3 headAxis; + // store head joint base position to KOSpot, axis to HeadAxis + GetJointWorldTransform( m_HeadJointID, gameLocal.time, KOSpot, headAxis ); + + KOSpot += headAxis * m_HeadCenterOffset; + idMat3 headAxisR = headAxis * m_KoRot; + + idVec3 delta = KOSpot - tr->c.point; + float lenDelta = delta.Length(); + + // First, project delta into the horizontal plane of the head + // Assume HeadAxis[1] is the up direction in head coordinates + idVec3 deltaH = delta - headAxisR[1] * (headAxisR[1] * delta); + float lenDeltaH = deltaH.Normalize(); + + float dotHoriz = headAxisR[ 0 ] * deltaH; + // cos (90-zenith) = adjacent / hypotenuse, applied to these vectors + float dotVert = idMath::Fabs( lenDeltaH / lenDelta ); + + // if hit was within the cone + if ( ( dotHoriz >= minDotHoriz ) && ( dotVert >= minDotVert) ) + { + // We just got knocked the taff out! + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s was knocked out by a blow to the head\r", name.c_str()); + Event_KO_Knockout(attacker); // grayman #2468 + + return true; + } + + // Rule #6 - blow wasn't in the right place + + // Signal the failed KO to the current state + GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, true); + + return false; // knockout angles missed +} + +void idAI::KnockoutDebugDraw( void ) +{ + float AngVert(0), AngHoriz(0), radius(0); + idVec3 KOSpot(vec3_zero), ConeDir(vec3_zero); + idMat3 HeadAxis(mat3_zero); + + const char * testZone = m_KoZone.c_str(); + if( AI_KNOCKEDOUT || AI_DEAD || testZone[0] == '\0' ) + { + return; + } + + // Check if the AI is above the alert threshold for KOing + // Defined the name of the alert threshold in the AI def for generality + if( AI_AlertIndex >= m_KoAlertState) + { + // Do not display if immune + if( m_bKoAlertImmune && AI_AlertIndex >= m_KoAlertImmuneState ) + return; + + // reduce the angle on alert, if needed + AngVert = idMath::ACos( m_KoAlertDotVert ); + AngHoriz = idMath::ACos( m_KoAlertDotHoriz ); + } + else + { + AngVert = idMath::ACos( m_KoDotVert ); + AngHoriz = idMath::ACos( m_KoDotHoriz ); + } + + if( AngVert == 0.0f ) + AngVert = 360.0f; + if( AngHoriz == 0.0f ) + AngHoriz = 360.0f; + + if( m_HeadJointID == INVALID_JOINT ) + { + return; + } + + // store head joint base position to KOSpot, axis to HeadAxis + GetJointWorldTransform( m_HeadJointID, gameLocal.time, KOSpot, HeadAxis ); + + KOSpot += HeadAxis * m_HeadCenterOffset; + idMat3 HeadAxisR = HeadAxis * m_KoRot; + + // Assumes the head joint is facing the same way as the look joint + ConeDir = -HeadAxisR[0]; + + // vertical angle in green + radius = AngVert * 0.5f * 30.0f; + gameRenderWorld->DebugCone( colorGreen, KOSpot, 30.0f * ConeDir, 0, radius, gameLocal.msec ); + // horizontal angle in red + radius = AngHoriz * 0.5f * 30.0f; + gameRenderWorld->DebugCone( colorRed, KOSpot, 30.0f * ConeDir, 0, radius, gameLocal.msec ); +} + +/* +===================== +idAI::Event_KO_Knockout +===================== +*/ + +void idAI::Event_KO_Knockout( idEntity* inflictor ) +{ + if (m_bCanBeKnockedOut) // grayman #2468 - new place to test ko immunity + { + m_koState = KO_BLACKJACK; // grayman #2604 + Knockout(inflictor); + } +} + +/* +===================== +idAI::Event_Gas_Knockout +===================== +*/ + +void idAI::Event_Gas_Knockout( idEntity* inflictor ) +{ + if (m_bCanBeGassed) // grayman #2468 - new place to test gas immunity + { + m_koState = KO_GAS; // grayman #2604 + Knockout(inflictor); + } +} + +/* +===================== +idAI::Knockout + +Based on idAI::Killed +===================== +*/ + +void idAI::Knockout( idEntity* inflictor ) +{ + idAngles ang; + +// if( !m_bCanBeKnockedOut ) // grayman #2468 - this test has been moved up a level +// return; + + if( AI_KNOCKEDOUT || AI_DEAD ) + { + AI_PAIN = true; + AI_DAMAGE = true; + + return; + } + + EndAttack(); + + // stop all voice sounds + StopSound( SND_CHANNEL_VOICE, false ); + if ( head.GetEntity() ) + { + head.GetEntity()->StopSound( SND_CHANNEL_VOICE, false ); + head.GetEntity()->GetAnimator()->ClearAllAnims( gameLocal.time, 100 ); + } + + disableGravity = false; + move.moveType = MOVETYPE_DEAD; + m_bAFPushMoveables = false; + + physicsObj.UseFlyMove( false ); + physicsObj.ForceDeltaMove( false ); + + // end our looping ambient sound + StopSound( SND_CHANNEL_AMBIENT, false ); + + RemoveAttachments(); + RemoveProjectile(); + StopMove( MOVE_STATUS_DONE ); + GetMemory().stopRelight = true; // grayman #2603 - abort a relight in progress + GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope + + ClearEnemy(); + + AI_KNOCKEDOUT = true; + + // greebo: Switch the mind to KO state, this will trigger PostKnockout() when + // the animation is done + mind->ClearStates(); + mind->PushState(STATE_KNOCKED_OUT); + + // Update TDM objective system + bool bPlayerResponsible = (inflictor != NULL && inflictor == gameLocal.GetLocalPlayer() ); + gameLocal.m_MissionData->MissionEvent(COMP_KO, this, inflictor, bPlayerResponsible); + // Mark the body as last moved by the player + if( bPlayerResponsible ) + m_MovedByActor = gameLocal.GetLocalPlayer(); + + // greebo: Stop lipsyncing now + m_lipSyncActive = false; +} + +void idAI::PostKnockOut() +{ + // greebo: Removed StopAnim() for head channel, this caused the AI to open its eyes again + //headAnim.StopAnim(1); + + legsAnim.StopAnim(1); + torsoAnim.StopAnim(1); + + headAnim.Disable(); + legsAnim.Disable(); + torsoAnim.Disable(); + // make original self nonsolid + physicsObj.SetContents( 0 ); + physicsObj.GetClipModel()->Unlink(); + + Unbind(); + + // swaps the head CM back if a different one was swapped in while conscious + SwapHeadAFCM( false ); + + if ( StartRagdoll() ) + { + // grayman #2604 - play "gassed" sound if knocked out by gas + switch (m_koState) + { + case KO_BLACKJACK: + StartSound( "snd_knockout", SND_CHANNEL_VOICE, 0, false, NULL ); + break; + case KO_GAS: + StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); + break; + case KO_NOT: + default: + break; + } + } + + const char *modelKOd; + + if ( spawnArgs.GetString( "model_knockedout", "", &modelKOd ) ) + { + // lost soul is only case that does not use a ragdoll and has a model_death so get the death sound in here + StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + SetModel( modelKOd ); + physicsObj.SetLinearVelocity( vec3_zero ); + physicsObj.PutToRest(); + physicsObj.DisableImpact(); + } + + if (spawnArgs.GetBool("set_frobable_on_knockout", "1")) + { + // AI becomes frobable on KO + // greebo: Add a delay before the AI becomes actually frobable + PostEventMS(&EV_SetFrobable, 750, 1); + } + + restartParticles = false; + + // drop items + DropOnRagdoll(); +} + +/** +* ========================== END TDM KNOCKOUT CODE ============================= +**/ + +/* +===================== +idAI::FoundBody +===================== +*/ +void idAI::FoundBody( idEntity *body ) +{ + bool bPlayerResp = false; + if( m_MovedByActor.GetEntity() && m_MovedByActor.GetEntity() == gameLocal.GetLocalPlayer() ) + bPlayerResp = true; + + gameLocal.m_MissionData->MissionEvent( COMP_AI_FIND_BODY, body, bPlayerResp ); +} + +void idAI::AddMessage(const ai::CommMessagePtr& message) +{ + assert(message != NULL); + m_Messages.Append(message); +} + +void idAI::ClearMessages() +{ + m_Messages.Clear(); +} + +/* +===================== +idAI::CheckFOV +===================== +*/ +bool idAI::CheckFOV( const idVec3 &pos ) const +{ + //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("idAI::CheckFOV called \r"); + + float dotHoriz, dotVert, lenDelta, lenDeltaH; + idVec3 delta, deltaH, deltaV, HeadCenter; + idMat3 HeadAxis; + + // ugliness + const_cast(this)->GetJointWorldTransform( m_HeadJointID, gameLocal.time, HeadCenter, HeadAxis ); + idMat3 HeadAxisR = m_FOVRot * HeadAxis; + + // Offset to get the center of the head + HeadCenter += HeadAxis * m_HeadCenterOffset; + delta = pos - HeadCenter; + lenDelta = delta.Length(); // Consider LengthFast if error is not too bad + + // First, project delta into the horizontal plane of the head + // Assume HeadAxis[1] is the up direction in head coordinates + deltaH = delta - HeadAxisR[1] * (HeadAxisR[1] * delta); + lenDeltaH = deltaH.Normalize(); // Consider NormalizeFast + + dotHoriz = HeadAxisR[ 0 ] * deltaH; + // cos (90-zenith) = adjacent / hypotenuse, applied to these vectors + // Technically this lets them see things behind them, but they won't because + // of the horizontal check. + dotVert = idMath::Fabs( lenDeltaH / lenDelta ); + + return ( dotHoriz >= m_fovDotHoriz && dotVert >= m_fovDotVert ); +} + +void idAI::FOVDebugDraw( void ) +{ + float AngVert(0), AngHoriz(0), radius(0); + idVec3 HeadCenter(vec3_zero), ConeDir(vec3_zero); + idMat3 HeadAxis(mat3_zero); + + if( AI_KNOCKEDOUT || AI_DEAD || m_HeadJointID == INVALID_JOINT ) + { + return; + } + + // probably expensive, but that's okay since this is just for debug mode + + AngVert = idMath::ACos( m_fovDotVert ); + AngHoriz = idMath::ACos( m_fovDotHoriz ); + + // store head joint base position to HeadCenter, axis to HeadAxis + GetJointWorldTransform( m_HeadJointID, gameLocal.time, HeadCenter, HeadAxis ); + idMat3 HeadAxisR = m_FOVRot * HeadAxis; + // offset from head joint position to get the true head center + HeadCenter += HeadAxis * m_HeadCenterOffset; + + ConeDir = HeadAxisR[0]; + + // Diverge to keep reasonable cone size + float coneLength; + + if (AngVert >= (idMath::PI / 4.0f)) + { + // Fix radius and calculate length + radius = 60.0f; + coneLength = radius / idMath::Tan(AngVert); + } + else + { + // Fix length and calculate radius + coneLength = 60.0f; + // SZ: FOVAng is divergence off to one side (idActor::setFOV uses COS(fov/2.0) to calculate m_fovDotHoriz) + radius = idMath::Tan(AngVert) * coneLength; + } + + gameRenderWorld->DebugCone( colorBlue, HeadCenter, coneLength * ConeDir, 0, radius, gameLocal.msec ); + + // now do the same for horizontal FOV angle, orange cone + if (AngHoriz >= (idMath::PI / 4.0f)) + { + // Fix radius and calculate length + radius = 60.0f; + coneLength = radius / idMath::Tan(AngHoriz); + } + else + { + // Fix length and calculate radius + coneLength = 60.0f; + // SZ: FOVAng is divergence off to one side (idActor::setFOV uses COS(fov/2.0) to calculate m_fovDotHoriz) + radius = idMath::Tan(AngHoriz) * coneLength; + } + + gameRenderWorld->DebugCone( colorOrange, HeadCenter, coneLength * ConeDir, 0, radius, gameLocal.msec ); +} + +moveStatus_t idAI::GetMoveStatus() const +{ + return move.moveStatus; +} + +bool idAI::CanReachEnemy() +{ + aasPath_t path; + int toAreaNum; + int areaNum; + idVec3 pos; + idActor *enemyEnt; + + enemyEnt = enemy.GetEntity(); + if ( !enemyEnt ) { + return false; + } + + if ( move.moveType != MOVETYPE_FLY ) { + if ( enemyEnt->OnLadder() ) { + return false; + } + enemyEnt->GetAASLocation( aas, pos, toAreaNum ); + } else { + pos = enemyEnt->GetPhysics()->GetOrigin(); + toAreaNum = PointReachableAreaNum( pos ); + } + + if ( !toAreaNum ) { + return false; + } + + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( org ); + return PathToGoal(path, areaNum, org, toAreaNum, pos, this); +} + +bool idAI::MouthIsUnderwater( void ) +{ + bool bReturnVal( false ); + idVec3 MouthOffset, MouthPosition; + + idEntity *headEnt = head.GetEntity(); + + // *.def file will store the coordinates of the mouth relative ("mouth_offset") to the head origin + // or relative to the eyes ("eye_height"). This should be defined by the modeler. + + // check for attached head + if( headEnt ) + { + MouthPosition = headEnt->GetPhysics()->GetOrigin(); + + // add in the mouth offset oriented by head axis + MouthPosition += headEnt->GetPhysics()->GetAxis() * m_MouthOffset; + } + else if( af.IsLoaded() && AI_KNOCKEDOUT ) + { + MouthPosition = af.GetPhysics()->GetOrigin( m_HeadBodyID ); + + // add in the mouth offset oriented by head axis + MouthPosition += af.GetPhysics()->GetAxis( m_HeadBodyID ) * m_MouthOffset; + } + else + { + MouthPosition = GetEyePosition(); + MouthPosition.z += m_MouthOffset.z; // grayman #1488 - check at the mouth, not the eyes + } + + // check if the mouth position is underwater + + int contents = gameLocal.clip.Contents( MouthPosition, NULL, mat3_identity, -1, this ); + bReturnVal = (contents & MASK_WATER) > 0; + +#if 0 + // grayman #1488 + // + // For debugging drowning deaths - indicate onscreen whether underwater or breathing, plus health level + + idStr str; + idVec4 color; + idStr healthLevel; + + if (bReturnVal) + { + str = "Drowning"; + color = colorRed; + } + else + { + str = "Breathing"; + color = colorGreen; + } + sprintf( healthLevel, " (%d)", health ); + gameRenderWorld->DrawText((str + healthLevel).c_str(),(GetEyePosition() - GetPhysics()->GetGravityNormal()*60.0f), + 0.25f, color, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 150 * gameLocal.msec); +#endif + + return bReturnVal; +} + +void idAI::UpdateAir() +{ + // Are we able to drown at all? Has the time for next air check already come? + if (!m_bCanDrown || gameLocal.time < m_AirCheckTimer) + { + return; + } + + if (MouthIsUnderwater()) + { + // don't let KO'd AI hold their breath + if (AI_KNOCKEDOUT) + { + m_AirTics = 0; + } + + m_AirTics--; + } + else + { + // regain breath twice as fast as losing + m_AirTics += 2; + + if (m_AirTics > m_AirTicksMax) + { + m_AirTics = m_AirTicksMax; + } + } + + if (m_AirTics < 0) + { + m_AirTics = 0; + + // do the damage, damage_noair is already defined for the player + Damage(NULL, NULL, vec3_origin, "damage_noair", 1.0f, 0); + } + + // set the timer for next air check + m_AirCheckTimer += m_AirCheckInterval; +} + +int idAI::getAirTicks() const { + return m_AirTics; +} + +void idAI::setAirTicks(int airTicks) { + m_AirTics = airTicks; + // Clamp to maximum value + if( m_AirTics > m_AirTicksMax ) { + m_AirTics = m_AirTicksMax; + } +} + +/* +===================== Lipsync ===================== +*/ +int idAI::PlayAndLipSync(const char *soundName, const char *animName) +{ + // Play sound + int duration; + StartSound( soundName, SND_CHANNEL_VOICE, 0, false, &duration ); + + if (cv_ai_bark_show.GetBool()) + { + gameRenderWorld->DrawText( va("%s", soundName), GetEyePosition(), 0.25f, colorBlue, + gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, duration ); + } + + // Do we want to lipsync this sound? + StopLipSync(); // Assume not + + const char *sound; + if (spawnArgs.GetString( soundName, "", &sound )) + { + const idSoundShader* shader = declManager->FindSound( sound ); + + if (shader != NULL && idStr::Cmp(shader->GetDescription(), "nolipsync") != 0) + { + // The sound exists and isn't marked "nolipsync", so start the lipsync + + // Get the default animation name if necessary + if (animName == NULL || animName[0]=='\0') + { + // Not specified; get the default from a spawnarg. + // If even the spawnarg doesn't exist, revert to talk. + animName = spawnArgs.GetString("lipsync_anim_name", "talk"); + } + + m_lipSyncActive = true; + m_lipSyncAnim = GetAnim( ANIMCHANNEL_HEAD, animName ); + m_lipSyncEndTimer = gameLocal.time + duration; + headAnim.CycleAnim( m_lipSyncAnim ); + } + } + + return duration; +} + +void idAI::Event_PlayAndLipSync( const char *soundName, const char *animName ) +{ + // grayman - might have to add drowning check here if anyone + // ever uses this function in a script. + + idThread::ReturnInt(static_cast(MS2SEC(PlayAndLipSync(soundName, animName)))); +} + +void idAI::StopLipSync() +{ + if (m_lipSyncActive) + { + // Make sure mouth is closed + headAnim.SetFrame( m_lipSyncAnim, 0 ); + // Halt animation + headAnim.SetState("Head_Idle", 4); + } + m_lipSyncActive = false; +} + +/* +===================== Sheathing/drawing weapons ===================== +*/ + +void idAI::DrawWeapon() +{ + /*const function_t* func = scriptObject.GetFunction("DrawWeapon"); + if (func) { + idThread* thread = new idThread(func); + thread->CallFunction(this, func, true); + thread->DelayedStart(0); + }*/ + // greebo: Replaced the above thread spawn with an animstate switch + SetAnimState(ANIMCHANNEL_TORSO, "Torso_DrawWeapon", 4); +} + +void idAI::SheathWeapon() +{ + /*const function_t* func = scriptObject.GetFunction("SheathWeapon"); + if (func) { + idThread* thread = new idThread(func); + thread->CallFunction(this, func, true); + thread->DelayedStart(0); + }*/ + // greebo: Replaced the above thread spawn with an animstate switch + SetAnimState(ANIMCHANNEL_TORSO, "Torso_SheathWeapon", 4); +} + +void idAI::DropOnRagdoll( void ) +{ + idEntity *ent = NULL; + int mask(0); + // Id style def_drops + const idKeyValue *kv = spawnArgs.MatchPrefix( "def_drops", NULL ); + + // old D3 code for spawning things at AI's feet when they die + while( kv ) + { + idDict args; + + args.Set( "classname", kv->GetValue() ); + args.Set( "origin", physicsObj.GetOrigin().ToString() ); + gameLocal.SpawnEntityDef( args ); + kv = spawnArgs.MatchPrefix( "def_drops", kv ); + } + + // Drop TDM style attachments + for( int i=0; iIsType(CMeleeWeapon::Type) ) + { + CMeleeWeapon *pWeap = static_cast(ent); + pWeap->DeactivateAttack(); + pWeap->DeactivateParry(); + pWeap->ClearOwner(); + } + + // greebo: Check if we should set some attachments to nonsolid + // this applies for instance to the builder guard's pauldrons which + // cause twitching and self-collisions when going down + if (ent->spawnArgs.GetBool( "drop_set_nonsolid" )) + { + int curContents = ent->GetPhysics()->GetContents(); + + // ishtvan: Also clear the CONTENTS_CORPSE flag (maybe this was a typo in original code?) + ent->GetPhysics()->SetContents(curContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE)); + + // ishtvan: If this entity was added to the AF, set the AF body nonsolid as well + idAFBody *EntBody = AFBodyForEnt( ent ); + if( EntBody != NULL ) + { + int curBodyContents = EntBody->GetClipModel()->GetContents(); + EntBody->GetClipModel()->SetContents( curBodyContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); + } + + // also have to iterate thru stuff attached to this attachment + // ishtvan: left this commentd out because I'm not sure if GetTeamChildren is bugged or not + // don't want to accidentally set all attachments to the AI to nonsolid + /* + idList AttChildren; + ent->GetTeamChildren( &AttChildren ); + gameLocal.Printf("TEST: drop_set_nonsolid, Num team children = %d", AttChildren.Num() ); + for( int i=0; i < AttChildren.Num(); i++ ) + { + idPhysics *pChildPhys = AttChildren[i]->GetPhysics(); + if( pChildPhys == NULL ) + continue; + + int childContents = pChildPhys->GetContents(); + pChildPhys->SetContents( childContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); + } + */ + } + + bool bDrop = ent->spawnArgs.GetBool( "drop_when_ragdoll" ); + + if( !bDrop ) { + continue; + } + + bool bDropWhenDrawn = ent->spawnArgs.GetBool( "drop_when_drawn" ); + bool bSetSolid = ent->spawnArgs.GetBool( "drop_add_contents_solid" ); + bool bSetCorpse = ent->spawnArgs.GetBool( "drop_add_contents_corpse" ); + bool bSetFrob = ent->spawnArgs.GetBool( "drop_set_frobable" ); + bool bExtinguish = ent->spawnArgs.GetBool("extinguish_on_drop", "0"); + + if( bDropWhenDrawn ) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Testing drop weapon %s\r", ent->name.c_str() ); + + bool bIsMelee = ent->spawnArgs.GetBool( "is_weapon_melee" ); + + if( bIsMelee && !GetAttackFlag(COMBAT_MELEE) ) + { + DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Melee weapon was not drawn\r" ); + continue; + } + + bool bIsRanged = ent->spawnArgs.GetBool( "is_weapon_ranged" ); + + if( bIsRanged && !GetAttackFlag(COMBAT_RANGED) ) + { + continue; + } + } + + // Proceed with droppage + DetachInd( i ); + + if( bSetSolid ) + mask = CONTENTS_SOLID; + if( bSetCorpse ) + mask = mask | CONTENTS_CORPSE; + + if( mask ) + ent->GetPhysics()->SetContents( ent->GetPhysics()->GetContents() | mask ); + + if( bSetFrob ) + ent->m_bFrobable = true; + + // greebo: Check if we should extinguish the attachment, like torches + if ( bExtinguish ) + { + // Get the delay in milliseconds + int delay = SEC2MS(ent->spawnArgs.GetInt("extinguish_on_drop_delay", "3")); + if (delay < 0) { + delay = 0; + } + + // Schedule the extinguish event + ent->PostEventMS(&EV_ExtinguishLights, delay); + } + + ent->GetPhysics()->Activate(); + ent->m_droppedByAI = true; // grayman #1330 + } + + // also perform some of these same operations on attachments to our head, + // because they are stored differently than attachments to us + if( head.GetEntity() ) + head.GetEntity()->DropOnRagdoll(); +} + +int idAI::StartSearchForHidingSpotsWithExclusionArea +( + const idVec3& hideFromLocation, + const idVec3& minBounds, + const idVec3& maxBounds, + const idVec3& exclusionMinBounds, + const idVec3& exclusionMaxBounds, + int hidingSpotTypesAllowed, + idEntity* p_ignoreEntity +) +{ + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("StartSearchForHidingSpots called.\r"); + + // Destroy any current search + destroyCurrentHidingSpotSearch(); + + // Make caller's search bounds + idBounds searchBounds (minBounds, maxBounds); + idBounds searchExclusionBounds (exclusionMinBounds, exclusionMaxBounds); + + // greebo: Remember the initial alert position + ai::Memory& memory = GetMemory(); + memory.alertSearchCenter = memory.alertPos; + + // Get aas + if (aas != NULL) + { + // Allocate object that handles the search + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Making finder\r"); + bool b_searchCompleted = false; + m_HidingSpotSearchHandle = CHidingSpotSearchCollection::Instance().getOrCreateSearch + ( + hideFromLocation, + aas, + HIDING_OBJECT_HEIGHT, + searchBounds, + searchExclusionBounds, + hidingSpotTypesAllowed, + p_ignoreEntity, + gameLocal.framenum, + b_searchCompleted + ); + + // Wait at least one frame for other AIs to indicate they want to share + // this search. Return result indicating search is not done yet. + return 1; + } + else + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Cannot perform Event_StartSearchForHidingSpotsWithExclusionArea if no AAS is set for the AI\r"); + + // Search is done since there is no search + return 0; + } +} + +bool idAI::IsSearching() // grayman #2603 +{ + return (AI_AlertLevel >= thresh_3); +} + +int idAI::ContinueSearchForHidingSpots() +{ + //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("ContinueSearchForHidingSpots called.\r"); + + // Get hiding spot search instance from handle + CDarkmodAASHidingSpotFinder* p_hidingSpotFinder = NULL; + if (m_HidingSpotSearchHandle != NULL_HIDING_SPOT_SEARCH_HANDLE) + { + p_hidingSpotFinder = CHidingSpotSearchCollection::Instance().getSearchByHandle( + m_HidingSpotSearchHandle + ); + } + + // Make sure search still around + if (p_hidingSpotFinder == NULL) + { + // No hiding spot search to continue + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("No current hiding spot search to continue\r"); + return 0; + } + else + { + // Call finder method to continue search + bool moreProcessingToDo = p_hidingSpotFinder->continueSearchForHidingSpots + ( + p_hidingSpotFinder->hidingSpotList, + cv_ai_max_hiding_spot_tests_per_frame.GetInteger(), + gameLocal.framenum + ); + + // Return result + if (moreProcessingToDo) + { + return 1; + } + + // No more processing to do at this point + + unsigned int refCount; + + // Get finder we just referenced + CDarkmodAASHidingSpotFinder* p_hidingSpotFinder = + CHidingSpotSearchCollection::Instance().getSearchAndReferenceCountByHandle + ( + m_HidingSpotSearchHandle, + refCount + ); + + m_hidingSpots.clear(); + // greebo: Now retrieve our share from the completed hiding spot search + // Given that three other AI are referencing this hiding spot finder, this AI draws a third. + p_hidingSpotFinder->hidingSpotList.getOneNth(refCount, m_hidingSpots); + + // Done with search object, dereference so other AIs know how many + // AIs will still be retrieving points from the search + CHidingSpotSearchCollection::Instance().dereference (m_HidingSpotSearchHandle); + m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; + + // DEBUGGING + if (cv_ai_search_show.GetInteger() >= 1.0) + { + // Clear the debug draw list and then fill with our results + p_hidingSpotFinder->debugClearHidingSpotDrawList(); + p_hidingSpotFinder->debugAppendHidingSpotsToDraw (m_hidingSpots); + p_hidingSpotFinder->debugDrawHidingSpots (cv_ai_search_show.GetInteger()); + } + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Hiding spot search completed\r"); + return 0; + } +} + +idVec3 idAI::GetNthHidingSpotLocation(int hidingSpotIndex) +{ + idVec3 outLocation(0,0,0); + + int numSpots = m_hidingSpots.getNumSpots(); + + // In bounds? + if (hidingSpotIndex >= 0 && hidingSpotIndex < numSpots) + { + idBounds areaNodeBounds; + darkModHidingSpot* p_spot = m_hidingSpots.getNthSpotWithAreaNodeBounds(hidingSpotIndex, areaNodeBounds); + if (p_spot != NULL) + { + outLocation = p_spot->goal.origin; + } + + if (cv_ai_search_show.GetInteger() >= 1.0) + { + idVec4 markerColor (1.0, 1.0, 1.0, 1.0); + idVec3 arrowLength (0.0, 0.0, 50.0); + + // Debug draw the point to be searched + gameRenderWorld->DebugArrow + ( + markerColor, + outLocation + arrowLength, + outLocation, + 2, + cv_ai_search_show.GetInteger() + ); + + // Debug draw the bounds of the area node containing the hiding spot point + // This may be smaller than the containing AAS area due to octant subdivision. + gameRenderWorld->DebugBounds + ( + markerColor, + areaNodeBounds, + vec3_origin, + cv_ai_search_show.GetInteger() + ); + } + + } + else + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Index %d is out of bounds, there are %d hiding spots\r", hidingSpotIndex, numSpots); + } + + // Return the location + return outLocation; +} + +int idAI::GetSomeOfOtherEntitiesHidingSpotList(idEntity* p_ownerOfSearch) +{ + // Test parameters + if (p_ownerOfSearch == NULL) + { + return 0; + } + + // The other entity must be an AI + idAI* p_otherAI = dynamic_cast(p_ownerOfSearch); + if (p_otherAI == NULL) + { + // Not an AI + return 0; + } + + CDarkmodHidingSpotTree& p_othersTree = p_otherAI->m_hidingSpots; + if (p_othersTree.getNumSpots() <= 1) + { + // No points + return 0; + } + + // We must clear our current hiding spot search + destroyCurrentHidingSpotSearch(); + + // Move points from their tree to ours + p_othersTree.getOneNth(2, m_hidingSpots); + + // Done + return m_hidingSpots.getNumSpots(); +} + + +float idAI::GetArmReachLength() +{ + if (idAAS* aas = GetAAS()) + { + idVec3 size = aas->GetSettings()->boundingBoxes[0][1]; + return size.z * 0.5; + } + else + { + return 41; + } +} + +void idAI::NeedToUseElevator(const eas::RouteInfoPtr& routeInfo) +{ + mind->GetState()->NeedToUseElevator(routeInfo); +} + + +bool idAI::CanUnlock(CBinaryFrobMover *frobMover) +{ + // Look through list of unlockable doors set by spawnarg + FrobMoverList::iterator i = unlockableDoors.find(frobMover); + if (i != unlockableDoors.end()) + { + return true; + } + + // Look through attachments + int n = frobMover->m_UsedByName.Num(); + for (int i = 0; i < m_Attachments.Num(); i++) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + + if (ent == NULL || !m_Attachments[i].ent.IsValid()) + { + continue; + } + + for (int j = 0; j < n; j++) + { + if (ent->name == frobMover->m_UsedByName[j]) + { + return true; + } + } + } + return false; +} + +bool idAI::ShouldCloseDoor(CBinaryFrobMover *frobMover) +{ + if (frobMover->spawnArgs.GetBool("ai_should_not_close", "0")) + { + // this door should not be closed + return false; + } + if (AI_AlertLevel >= thresh_5) + { + // don't close doors during combat + return false; + } + if (frobMover->spawnArgs.GetBool("shouldBeClosed", "0")) + { + // this door should really be closed + return true; + } + if (IsSearching()) // grayman #2603 + { + // don't close other doors while searching + return false; + } + + // in all other cases, close the door + return true; +} + +void idAI::PushMove() +{ + // Copy the current movestate structure to the stack + moveStack.push_back(move); + + if (moveStack.size() > 100) + { + gameLocal.Warning("AI MoveStack contains more than 100 moves! (%s)\n", name.c_str()); + } +} + +void idAI::PopMove() +{ + if (moveStack.empty()) + { + return; // nothing to pop from + } + + const idMoveState& saved = moveStack.back(); // Get a reference of the last element + RestoreMove(saved); + moveStack.pop_back(); // Remove the last element +} + +void idAI::RestoreMove(const idMoveState& saved) +{ + idVec3 goalPos; + idVec3 dest; + + switch( saved.moveCommand ) { + case MOVE_NONE : + StopMove( saved.moveStatus ); + break; + + case MOVE_FACE_ENEMY : + FaceEnemy(); + break; + + case MOVE_FACE_ENTITY : + FaceEntity( saved.goalEntity.GetEntity() ); + break; + + case MOVE_TO_ENEMY : + MoveToEnemy(); + break; + + case MOVE_TO_ENEMYHEIGHT : + MoveToEnemyHeight(); + break; + + case MOVE_TO_ENTITY : + MoveToEntity( saved.goalEntity.GetEntity() ); + break; + + case MOVE_OUT_OF_RANGE : + MoveOutOfRange( saved.goalEntity.GetEntity(), saved.range ); + break; + + case MOVE_TO_ATTACK_POSITION : + MoveToAttackPosition( saved.goalEntity.GetEntity(), saved.anim ); + break; + + case MOVE_TO_COVER : + MoveToCover( saved.goalEntity.GetEntity(), lastVisibleEnemyPos ); + break; + + case MOVE_TO_POSITION : + MoveToPosition( saved.moveDest ); + break; + + case MOVE_TO_POSITION_DIRECT : + DirectMoveToPosition( saved.moveDest ); + break; + + case MOVE_SLIDE_TO_POSITION : + SlideToPosition( saved.moveDest, saved.duration ); + break; + + case MOVE_WANDER : + WanderAround(); + break; + + default: break; + } + + if ( GetMovePos( goalPos ) ) { + //CheckObstacleAvoidance( goalPos, dest ); + } +} + +void idAI::ShowDebugInfo() +{ + // DarkMod: Show debug info + if( cv_ai_ko_show.GetBool() ) + { + KnockoutDebugDraw(); + } + + if( cv_ai_fov_show.GetBool() ) + { + FOVDebugDraw(); + } + + if ( cv_ai_dest_show.GetBool() ) + { + gameRenderWorld->DebugArrow(colorYellow, physicsObj.GetOrigin(), move.moveDest, 5, gameLocal.msec); + } + + if ( cv_ai_task_show.GetBool()) + { + idStr str("State: "); + str += mind->GetState()->GetName() + "\n"; + + if (GetSubsystem(ai::SubsysSenses)->IsEnabled()) str += "Senses: " + GetSubsystem(ai::SubsysSenses)->GetDebugInfo() + "\n"; + if (GetSubsystem(ai::SubsysMovement)->IsEnabled()) str += "Movement: " + GetSubsystem(ai::SubsysMovement)->GetDebugInfo() + "\n"; + if (GetSubsystem(ai::SubsysCommunication)->IsEnabled()) str += "Comm: " + GetSubsystem(ai::SubsysCommunication)->GetDebugInfo() + "\n"; + if (GetSubsystem(ai::SubsysAction)->IsEnabled()) str += "Action: " + GetSubsystem(ai::SubsysAction)->GetDebugInfo() + "\n"; + + gameRenderWorld->DrawText( str, (GetEyePosition() - physicsObj.GetGravityNormal()*35.0f), 0.25f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + } + + if( cv_ai_alertlevel_show.GetBool() ) + { + gameRenderWorld->DrawText( va("Alert: %f; Index: %d", (float) AI_AlertLevel, (int)AI_AlertIndex), (GetEyePosition() - physicsObj.GetGravityNormal()*45.0f), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + if (m_AlertGraceStart + m_AlertGraceTime - gameLocal.time > 0) + { + gameRenderWorld->DrawText( va("Grace time: %d; Alert count: %d / %d", + m_AlertGraceStart + m_AlertGraceTime - gameLocal.time, + m_AlertGraceCount, m_AlertGraceCountLimit), + GetEyePosition(), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + } + } + + if (cv_ai_animstate_show.GetBool()) + { + idStr debugText("Torso: "); + debugText += GetAnimState(ANIMCHANNEL_TORSO); + debugText += " Waitstate: "; + debugText += WaitState(ANIMCHANNEL_TORSO); + debugText += "\nLegs: "; + debugText += GetAnimState(ANIMCHANNEL_LEGS); + debugText += " Waitstate: "; + debugText += WaitState(ANIMCHANNEL_LEGS); + debugText += "\nHead: "; + debugText += GetAnimState(ANIMCHANNEL_HEAD); + debugText += " Waitstate: "; + debugText += WaitState(ANIMCHANNEL_LEGS); + debugText += "\n"; + + if (WaitState() != NULL) + { + debugText += idStr("Waitstate: ") + WaitState(); + } + gameRenderWorld->DrawText( debugText, (GetEyePosition() - physicsObj.GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + } + + if (cv_ai_aasarea_show.GetBool() && aas != NULL) + { + idVec3 org = GetPhysics()->GetOrigin(); + int areaNum = PointReachableAreaNum(org); + + idBounds areaBounds = aas->GetAreaBounds(areaNum); + idVec3 areaCenter = aas->AreaCenter(areaNum); + + idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); + + gameRenderWorld->DrawText(va("%d", areaNum), areaCenter, 0.2f, colorGreen, playerViewMatrix, 1, gameLocal.msec); + gameRenderWorld->DebugBox(colorGreen, idBox(areaBounds), gameLocal.msec); + } + + if (cv_ai_elevator_show.GetBool()) + { + idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); + + gameRenderWorld->DrawText(m_HandlingElevator ? "Elevator" : "---", physicsObj.GetOrigin(), 0.2f, m_HandlingElevator ? colorRed : colorGreen, playerViewMatrix, 1, gameLocal.msec); + } +} + +const idStr& idAI::GetNextIdleAnim() +{ + return m_NextIdleAnim; +} + +void idAI::SetNextIdleAnim(const idStr& nextIdleAnim) +{ + m_NextIdleAnim = nextIdleAnim; +} + +// grayman #2603 - delayed stim management + +void idAI::SetDelayedStimExpiration(idEntityPtr stimPtr) +{ + for (int i = 0 ; i < delayedStims.Num() ; i++) + { + if (delayedStims[i].stim == stimPtr) + { + delayedStims[i].nextTimeToConsider = gameLocal.time + 15000; + return; + } + } + + // stim not in list, so add it + + DelayedStim ds; + ds.nextTimeToConsider = gameLocal.time + 15000; + ds.stim = stimPtr; + delayedStims.Append(ds); +} + +int idAI::GetDelayedStimExpiration(idEntityPtr stimPtr) +{ + for (int i = 0 ; i < delayedStims.Num() ; i++) + { + if (delayedStims[i].stim == stimPtr) + { + return (delayedStims[i].nextTimeToConsider); + } + } + return -1; +} + +bool idAI::SwitchToConversationState(const idStr& conversationName) +{ + ai::ConversationStatePtr state = + boost::static_pointer_cast(ai::ConversationState::CreateInstance()); + + // Convert the name to an index + int convIndex = gameLocal.m_ConversationSystem->GetConversationIndex(conversationName); + + if (convIndex == -1) + { + DM_LOG(LC_CONVERSATION, LT_ERROR)LOGSTRING("Could not find conversation '%s'.\r", conversationName.c_str()); + return false; + } + + // Let the state know which conversation is about to be played + state->SetConversation(convIndex); + + // Switch to this state + GetMind()->PushState(state); + + return true; +} + +void idAI::RemoveTarget(idEntity* target) +{ + idEntity::RemoveTarget( target ); + + if (!GetMind()->IsEmpty()) + { + GetMind()->GetState()->OnChangeTarget(this); + } +} + +void idAI::AddTarget(idEntity* target) +{ + idEntity::AddTarget( target ); + + if (!GetMind()->IsEmpty()) + { + GetMind()->GetState()->OnChangeTarget(this); + } +} + +void idAI::SitDown() +{ + idStr waitState(WaitState()); + if (GetMoveType() != MOVETYPE_ANIM) + { + return; + } + SetMoveType(MOVETYPE_SIT_DOWN); + SetWaitState("sit_down"); +} + +void idAI::GetUp() +{ + moveType_t moveType = GetMoveType(); + + if (moveType == MOVETYPE_SIT) + { + SetMoveType(MOVETYPE_GET_UP); + SetWaitState("get_up"); + + } + else if (moveType == MOVETYPE_SLEEP) + { + SetMoveType(MOVETYPE_GET_UP_FROM_LYING); + SetWaitState("get_up_from_lying_down"); + + // Reset visual, hearing and tactile acuity + SetAcuity("vis", m_oldVisualAcuity); // Tels: fix #2408 + SetAcuity("aud", GetAcuity("aud") * 2); + SetAcuity("tact", GetAcuity("tact") * 2); + } +} + + +void idAI::LayDown() +{ + if (GetMoveType() != MOVETYPE_ANIM) + { + return; + } + + AI_LAY_DOWN_FACE_DIR = idAngles( 0, current_yaw, 0 ).ToForward(); + + SetMoveType(MOVETYPE_LAY_DOWN); + SetWaitState("lay_down"); + + // Tels: Sleepers are blind + m_oldVisualAcuity = GetAcuity("vis"); + SetAcuity("vis", 0); + + // Reduce hearing and tactile acuity by 50% + // TODO: use spawn args + SetAcuity("aud", GetAcuity("aud") * 0.5); + SetAcuity("tact", GetAcuity("tact") * 0.5); +} + + +float idAI::StealthDamageMult() +{ + // multiply up if unalert + // Damage to unconscious AI also considered sneak attack + if( AI_AlertLevel < m_SneakAttackThresh || IsKnockedOut() ) + return m_SneakAttackMult; + else + return 1.0; +} + +void idAI::SwapHeadAFCM(bool bUseLargerCM) +{ + if (m_HeadJointID == -1) return; // safety check for AI without head + + if (bUseLargerCM && !m_bHeadCMSwapped && spawnArgs.FindKey("blackjack_headbox_mins")) + { + idAFBody* headBody = af.GetPhysics()->GetBody(af.BodyForJoint(m_HeadJointID)); + + idClipModel *oldClip = headBody->GetClipModel(); + idVec3 CMorig = oldClip->GetOrigin(); + idMat3 CMaxis = oldClip->GetAxis(); + int CMid = oldClip->GetId(); + + oldClip->Unlink(); + // store a copy of the original cm since it will be deleted + m_OrigHeadCM = new idClipModel(oldClip); + + idBounds HeadBounds; + spawnArgs.GetVector( "blackjack_headbox_mins", NULL, HeadBounds[0] ); + spawnArgs.GetVector( "blackjack_headbox_maxs", NULL, HeadBounds[1] ); + + idTraceModel trm; + trm.SetupBox( HeadBounds ); + + idClipModel *NewClip = new idClipModel( trm ); + + // AF bodies want to have their origin at the center of mass + float MassOut; + idVec3 COM; + idMat3 inertiaTensor; + NewClip->GetMassProperties( 1.0f, MassOut, COM, inertiaTensor ); + NewClip->TranslateOrigin( -COM ); + CMorig += COM * CMaxis; + + NewClip->SetContents( oldClip->GetContents() ); + NewClip->Link( gameLocal.clip, this, CMid, CMorig, CMaxis ); + headBody->SetClipModel( NewClip ); + + m_bHeadCMSwapped = true; + } + // swap back to original CM when going unconscious, if we swapped earlier + else if( !bUseLargerCM && m_bHeadCMSwapped ) + { + idAFBody* headBody = af.GetPhysics()->GetBody(af.BodyForJoint(m_HeadJointID)); + + idClipModel *oldClip = headBody->GetClipModel(); + idVec3 CMorig = oldClip->GetOrigin(); + idMat3 CMaxis = oldClip->GetAxis(); + int CMid = oldClip->GetId(); + + m_OrigHeadCM->Link( gameLocal.clip, this, CMid, CMorig, CMaxis ); + headBody->SetClipModel( m_OrigHeadCM ); + + m_bHeadCMSwapped = false; + m_OrigHeadCM = NULL; + } +} + +void idAI::CopyHeadKOInfo( void ) +{ + idEntity *ent = head.GetEntity(); + if( !ent ) + return; + + // Change this if the list below changes: + const int numArgs = 14; + const char *copyArgs[ numArgs ] = { "ko_immune", "ko_spot_offset", "ko_zone", + "ko_alert_state", "ko_alert_immune", "ko_alert_immune_state", "ko_angle_vert", "ko_angle_horiz", + "ko_angle_alert_vert", "ko_angle_alert_horiz", "ko_rotation", "fov", + "fov_vert", "fov_rotation"}; + + const idKeyValue *tempkv; + const char *argName; + + // for each spawnarg, overwrite it if it exists on the head + for( int i=0; i < numArgs; i++ ) + { + argName = copyArgs[i]; + tempkv = ent->spawnArgs.FindKey( argName ); + if( tempkv != NULL ) + spawnArgs.Set( argName, tempkv->GetValue().c_str() ); + } +} + +void idAI::ParseKnockoutInfo() +{ + m_bCanBeKnockedOut = !( spawnArgs.GetBool("ko_immune", "0") ); + m_HeadCenterOffset = spawnArgs.GetVector("ko_spot_offset"); + m_KoZone = spawnArgs.GetString("ko_zone"); + m_KoAlertState = spawnArgs.GetInt("ko_alert_state"); + m_KoAlertImmuneState = spawnArgs.GetInt("ko_alert_immune_state"); + m_bKoAlertImmune = spawnArgs.GetBool("ko_alert_immune"); + idAngles tempAngles = spawnArgs.GetAngles("ko_rotation"); + m_KoRot = tempAngles.ToMat3(); + + float tempAng; + tempAng = spawnArgs.GetFloat("ko_angle_vert", "360"); + m_KoDotVert = (float)cos( DEG2RAD( tempAng * 0.5f ) ); + tempAng = spawnArgs.GetFloat("ko_angle_horiz", "360"); + m_KoDotHoriz = (float)cos( DEG2RAD( tempAng * 0.5f ) ); + + // Only set the alert angles if the spawnargs exist + const char *tempc1, *tempc2; + tempc1 = spawnArgs.GetString("ko_angle_alert_vert"); + tempc2 = spawnArgs.GetString("ko_angle_alert_horiz"); + if( tempc1[0] != '\0' ) + { + tempAng = atof( tempc1 ); + m_KoAlertDotVert = (float)cos( DEG2RAD( tempAng * 0.5f ) ); + } + else + m_KoAlertDotVert = m_KoDotVert; + if( tempc2[0] != '\0' ) + { + tempAng = atof( tempc2 ); + m_KoAlertDotHoriz = (float)cos( DEG2RAD( tempAng * 0.5f ) ); + } + else + m_KoAlertDotHoriz = m_KoDotHoriz; + + // ishtvan: Also set the FOV again, as this may be copied from the head + // TODO: This was done once already in idActor, do we still need it there or can we remove FOV from idActor? + float fovDegHoriz, fovDegVert; + spawnArgs.GetFloat( "fov", "150", fovDegHoriz ); + // If fov_vert is -1, it will be set the same as horizontal + spawnArgs.GetFloat( "fov_vert", "-1", fovDegVert ); + SetFOV( fovDegHoriz, fovDegVert ); + tempAngles = spawnArgs.GetAngles("fov_rotation"); + m_FOVRot = tempAngles.ToMat3(); +} diff --git a/game/ai/AI.h b/game/ai/AI.h new file mode 100644 index 000000000..cf49e6be2 --- /dev/null +++ b/game/ai/AI.h @@ -0,0 +1,2220 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_H__ +#define __AI_H__ + +#include "../Relations.h" +#include "../ai/Mind.h" +#include "../ai/CommunicationSubsystem.h" +#include "../ai/MovementSubsystem.h" +#include "../HidingSpotSearchCollection.h" +#include "../darkmodHidingSpotTree.h" +#include "MoveState.h" + +#include +#include + +/* +=============================================================================== + + idAI + +=============================================================================== +*/ + +const float SQUARE_ROOT_OF_2 = 1.414213562f; +const float AI_TURN_PREDICTION = 0.2f; +const float AI_TURN_SCALE = 60.0f; +const float AI_SEEK_PREDICTION = 0.3f; +const float AI_FLY_DAMPENING = 0.15f; +const float AI_HEARING_RANGE = 2048.0f; +const int DEFAULT_FLY_OFFSET = 68; + +// grayman 2414 - TEMP_THINK constants used with interleaved thinking +const int TEMP_THINK_INTERLEAVE = 4; // maximum interleave think frames when + // more interleaved thinking is needed +const int TEMP_THINK_DISTANCE = 200; // increase interleave think frames + // when door is closer than this +const int TEMP_THINK_FACTOR = 8; // used to determine when to increase thinking + // when moving to a goal position + + +// used to declare the Dark Mod Acuity values array. +// THIS MUST BE CHANGED if you want more than 15 acuities +static const int s_MAXACUITIES = 15; + +#define ATTACK_IGNORE 0 +#define ATTACK_ON_DAMAGE 1 +#define ATTACK_ON_ACTIVATE 2 +#define ATTACK_ON_SIGHT 4 + +typedef enum { + TALK_NEVER, + TALK_DEAD, + TALK_OK, + TALK_BUSY, + NUM_TALK_STATES +} talkState_t; + +typedef enum { // grayman #2604 - how the AI was knocked out + KO_NOT, // default - not KO'ed + KO_BLACKJACK, + KO_GAS, + NUM_KO_STATES +} koState_t; + +#define DI_NODIR -1 + +// obstacle avoidance +typedef struct obstaclePath_s { + idVec3 seekPos; // seek position avoiding obstacles + idEntity * firstObstacle; // if != NULL the first obstacle along the path + idVec3 startPosOutsideObstacles; // start position outside obstacles + idEntity * startPosObstacle; // if != NULL the obstacle containing the start position + idVec3 seekPosOutsideObstacles; // seek position outside obstacles + idEntity * seekPosObstacle; // if != NULL the obstacle containing the seek position + CFrobDoor* doorObstacle; // greebo: if != NULL, this is the door in our way +} obstaclePath_t; + +// path prediction +typedef enum { + SE_BLOCKED = BIT(0), + SE_ENTER_LEDGE_AREA = BIT(1), + SE_ENTER_OBSTACLE = BIT(2), + SE_FALL = BIT(3), + SE_LAND = BIT(4) +} stopEvent_t; + +typedef struct predictedPath_s { + idVec3 endPos; // final position + idVec3 endVelocity; // velocity at end position + idVec3 endNormal; // normal of blocking surface + int endTime; // time predicted + int endEvent; // event that stopped the prediction + const idEntity * blockingEntity; // entity that blocks the movement +} predictedPath_t; + +// +// events +// +extern const idEventDef AI_BeginAttack; +extern const idEventDef AI_EndAttack; +extern const idEventDef AI_MuzzleFlash; +extern const idEventDef AI_CreateMissile; +extern const idEventDef AI_CreateMissileFromDef; +extern const idEventDef AI_AttackMissile; +extern const idEventDef AI_FireMissileAtTarget; +extern const idEventDef AI_AttackMelee; +extern const idEventDef AI_DirectDamage; +extern const idEventDef AI_JumpFrame; +extern const idEventDef AI_EnableClip; +extern const idEventDef AI_DisableClip; +extern const idEventDef AI_EnableGravity; +extern const idEventDef AI_DisableGravity; +extern const idEventDef AI_TriggerParticles; +extern const idEventDef AI_RandomPath; + +// DarkMod Events +extern const idEventDef AI_GetRelationEnt; +extern const idEventDef AI_GetSndDir; +extern const idEventDef AI_GetVisDir; +extern const idEventDef AI_GetTactEnt; +extern const idEventDef AI_VisScan; +extern const idEventDef AI_Alert; +extern const idEventDef AI_GetAcuity; +extern const idEventDef AI_SetAcuity; +extern const idEventDef AI_SetAudThresh; +extern const idEventDef AI_ClosestReachableEnemy; +extern const idEventDef AI_ReEvaluateArea; + + +// Darkmod: Glass Houses events +extern const idEventDef AI_SpawnThrowableProjectile; + +// DarkMod hiding spot finding events +extern const idEventDef AI_StartSearchForHidingSpots; +extern const idEventDef AI_ContinueSearchForHidingSpots; +extern const idEventDef AI_CloseHidingSpotSearch; +extern const idEventDef AI_GetNumHidingSpots; +extern const idEventDef AI_GetNthHidingSpotLocation; +extern const idEventDef AI_GetNthHidingSpotType; +extern const idEventDef AI_GetSomeOfOtherEntitiesHidingSpotList; + +// Darkmod AI additions +extern const idEventDef AI_GetVariableFromOtherAI; +extern const idEventDef AI_GetAlertLevelOfOtherAI; + +// Set a grace period for alerts +extern const idEventDef AI_SetAlertGracePeriod; + +// This event is used to get a position from which a given position can be observed +extern const idEventDef AI_GetObservationPosition; + +// Darkmod communication issuing event +extern const idEventDef AI_IssueCommunication; + +class idPathCorner; + +typedef struct particleEmitter_s { + particleEmitter_s() { + particle = NULL; + time = 0; + joint = INVALID_JOINT; + }; + const idDeclParticle *particle; + int time; + jointHandle_t joint; +} particleEmitter_t; + +class idAASFindCover : public idAASCallback { +public: + idAASFindCover( const idActor* hidingActor, const idEntity* hideFromEnt, const idVec3 &hideFromPos ); + ~idAASFindCover(); + + virtual bool TestArea( const idAAS *aas, int areaNum ); + +private: + const idActor* hidingActor; + const idEntity* hideFromEnt; + idVec3 hideFromPos; +}; + +class idAASFindAreaOutOfRange : public idAASCallback { +public: + idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist ); + + virtual bool TestArea( const idAAS *aas, int areaNum ); + +private: + idVec3 targetPos; + float maxDistSqr; +}; + +class idAASFindAttackPosition : public idAASCallback { +public: + idAASFindAttackPosition(idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset); + ~idAASFindAttackPosition(); + + virtual bool TestArea( const idAAS *aas, int areaNum ); + +private: + idAI *self; + idEntity *target; + idBounds excludeBounds; + idVec3 targetPos; + idVec3 fireOffset; + idMat3 gravityAxis; + pvsHandle_t targetPVS; + int PVSAreas[ idEntity::MAX_PVS_AREAS ]; +}; + +class idAASFindObservationPosition : public idAASCallback { +public: + idAASFindObservationPosition( const idAI *self, const idMat3 &gravityAxis, const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistanceFromWhichToObserve ); + ~idAASFindObservationPosition(); + + virtual bool TestArea( const idAAS *aas, int areaNum ); + + // Gets the best goal result, even if it didn't meet the maximum distance + bool getBestGoalResult + ( + float& out_bestGoalDistance, + aasGoal_t& out_bestGoal + ); + +private: + const idAI *self; + idBounds excludeBounds; + idVec3 targetPos; + idVec3 eyeOffset; + idMat3 gravityAxis; + pvsHandle_t targetPVS; + int PVSAreas[ idEntity::MAX_PVS_AREAS ]; + float maxObservationDistance; + + // The best goal found, even if it was greater than the maxObservationDistance + float bestGoalDistance; + bool b_haveBestGoal; + aasGoal_t bestGoal; +}; + +class idAI : public idActor { +public: + CLASS_PROTOTYPE( idAI ); + + idAI(); + virtual ~idAI(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + void HeardSound( idEntity *ent, const char *action ); + idActor *GetEnemy( void ) const; + void TalkTo( idActor *actor ); + talkState_t GetTalkState( void ) const; + + bool GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ); + + void TouchedByFlashlight( idActor *flashlight_owner ); + + // Outputs a list of all monsters to the console. + static void List_f( const idCmdArgs &args ); + + // Finds a path around dynamic obstacles. + static bool FindPathAroundObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path, idActor* owner ); + // Frees any nodes used for the dynamic obstacle avoidance. + static void FreeObstacleAvoidanceNodes( void ); + // Predicts movement, returns true if a stop event was triggered. + static bool PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path ); + // Return true if the trajectory of the clip model is collision free. + static bool TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime ); + // Finds the best collision free trajectory for a clip model. + static bool PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir ); + + // Begin Dark Mod Functions: + + + /** + * Interface with Dark Mod Sound Propagation + **/ + + /** + * Convert Sound Pressure Level from sound propagation + * to psychoacoustic Loudness for the given AI + * propVol is read from propParms, and + * loudness is set in propParms for later use. + **/ + void SPLtoLoudness( SSprParms *propParms ); + + /** + * CheckHearing returns "true" if the sound is above + * AI hearing threshold, without taking env. noise into + * account. + **/ + bool CheckHearing( SSprParms *propParms ); + + /** + * Called by soundprop when AI hears a sound Assumes that CheckHearing + * has been called and that the sound is above threshold without + * considering environmental noise masking. + **/ + void HearSound( SSprParms *propParms, float noise, const idVec3& origin ); + + /** + * Return the last point at which the AI heard a sound + * Returns (0,0,0) if the AI didn't hear a sound. + * Check AI_HEARDSOUND to see if the vector is valid. + **/ + idVec3 GetSndDir( void ); + + /** + * Return the last point at which an AI glimpsed something suspicious. + * Returns (0,0,0) if the AI was not visually alerted. + * Check AI_VISALERT to see if the vector is valid. + **/ + idVec3 GetVisDir( void ); + + /** + * Returns the entity that the AI is in tactile contact with + **/ + idEntity *GetTactEnt( void ); + + /** + * Visual Alerts + **/ + + /** + * Do a visibility calculation based on 2 things: + * The lightgem value, and the distance to entity + * NYI: take velocity into account + * + * The visibility can also be integrated over a number + * of frames if we need to do that for optimization later. + **/ + float GetVisibility( idEntity *ent ) const; + + /** + * angua: The uncorrected linear light values [1..DARKMOD_LG_MAX] + * didn't produce very believable results when used + * in GetVisibility(). This function takes the linear values + * and corrects them with an "empirical" correction curve. + * + * @returns: a float between [0...1].It is fairly high at + * values above 20, fairly low below 6 and increases linearly in between. + **/ + float GetCalibratedLightgemValue() const; + + /** + * Checks enemies in the AI's FOV and calls Alert( "vis", amount ) + * The amount is calculated based on distance and the lightgem + * + * For now the check is only done on the player + **/ + void PerformVisualScan( float time = 1.0f/60.0f ); + + /** + * Checks to see if the AI is being blocked by an actor when it tries to move, + * call HadTactile this AI and if this is the case. + * + * greebo: Note: Only works if the AI is not Dead, KO or already engaged in combat. + **/ + void CheckTactile(); + + /** + * Tactile Alerts: + * + * If no amount is entered, of the alert is defined in the global AI + * settings def file, and it also gets multiplied by the AI's specific + * "acuity_tact" key in the spawnargs (defaults to 1.0) + * + * The amount is in alert units, so as usual 1 = barely noticible, + * 10 = twice as noticable, etc. + **/ + void TactileAlert(idEntity* tactEnt, float amount = -1); + + /** + * This is called in the frame if the AI bumped into another actor. + * Checks the relationship to the AI, and calls TactileAlert appropriately. + * + * If the bumped actor is an enemy of the AI, the AI calls TactileAlert on itself + * + * If the bumped actor is an AI, and if this AI is an enemy of the bumped AI, + * it calls TactileAlert on the bumped AI as well. + **/ + void HadTactile( idActor *actor ); + + // angua: ignore tactile alerts from this entity from now on + void TactileIgnore(idEntity* tactEnt); + + bool CheckTactileIgnore(idEntity* tactEnt); + + /** + * Generalized alerts and acuities + **/ + + /** + * Alert the AI. The first parameter is the alert type (same as acuity type) + * The second parameter is the alert amount. + * NOTE: For "alert units," an alert of 1 corresponds to just barely + * seeing something or just barely hearing a whisper of a sound. + **/ + void AlertAI( const char *type, float amount ); + + /** + * greebo: Sets the AI_AlertLevel of this AI and updates the AI_AlertIndex. + * + * This also updates the grace timers, alert times and checks for + * a valid agitatedsearching>combat transition. + * + * Additionally, the transition alert sounds ("snd_alertdown2") are played. + */ + void SetAlertLevel(float newAlertLevel); + + + // angua: returns true if the current alert index is higher + // than the previous one, false otherwise + bool AlertIndexIncreased(); + + /** + * Returns the float val of the specific AI's acuity + * Acuity type is a char, from the same list as alert types + * That list is defined in DarkModGlobals.cpp + **/ + float GetAcuity( const char *type ) const; + + /** + * Sets the AI acuity for a certain type of alert. + **/ + void SetAcuity( const char *type, float acuity ); + + /** + * Calls objective system when the AI finds a body + **/ + void FoundBody( idEntity *body ); + + // Adds a message to the queue + void AddMessage(const ai::CommMessagePtr& message); + + // Removes all messages + void ClearMessages(); + + /** + * Get the volume modifier for a given movement type + * Use the same function as idPlayer::GetMovementVolMod. + * Unfortunately this is exactly the same as idPlayer::GetMovementVolMod + * It's bad coding, but that's how D3 wrote the movement vars. + **/ + float GetMovementVolMod( void ); + + /** + * Returns true if AI is knocked out + **/ + bool IsKnockedOut( void ) { return (AI_KNOCKEDOUT!=0); }; + + /** + * Ishtvan: Swap the AI's head CM to a larger one + * (Used to make blackjacking easier, currently only called when a blackjack swings nearby) + * If the argument is true, the larger CM is used, otherwise, the original CM is swapped back. + **/ + void SwapHeadAFCM( bool bUseLargerCM ); + + /** + * Return a damage multiplier if a sneak attack has occurred + **/ + virtual float StealthDamageMult( void ); + + /** + * Ishtvan: Overload AI target changing to re-initialize movement tasks + **/ + virtual void RemoveTarget(idEntity* target); + virtual void AddTarget(idEntity* target); + + // angua: calls the script functions for sitting down and getting up + void SitDown(); + void LayDown(); + + // GetUp is used both for getting up from sitting or sleeping + void GetUp(); + +public: + /** + * DarkMod AI Member Vars + **/ + + /** + * Set to true if the AI has been alerted in this frame + **/ + idScriptBool AI_ALERTED; + + /** + * Stores the actor ultimately responsible for the alert. + * If they find a body, this gets set to whoever killed/KO'd the body. + * If they get hit by an item, or hear it fall, this gets set to whoever + * threw the item, and so on + **/ + idEntityPtr m_AlertedByActor; + + int alertTypeWeight[ai::EAlertTypeCount]; + /** + * Set these flags so we can tell if the AI is running or creeping + * for the purposes of playing audible sounds and propagated sounds. + **/ + idScriptBool AI_CROUCH; + idScriptBool AI_RUN; + idScriptBool AI_CREEP; + + // angua: this determines whether the AI should lay down to the left or to the right after sitting down + // gets read as spawn arg from the path_sleep entity + idScriptBool AI_LAY_DOWN_LEFT; + + // angua: the direction the AI faces before sitting and laying down + idScriptVector AI_LAY_DOWN_FACE_DIR; + + // angua: the AI will turn to this direction after sitting down (this is practical for chairs next to a table) + idScriptFloat AI_SIT_DOWN_ANGLE; + + // angua: the AI will turn to this direction before getting up from sitting + idScriptFloat AI_SIT_UP_ANGLE; + + // greebo: This is to tell the scripts which idle animation should be played next in the CustomIdleAnim state + idStr m_NextIdleAnim; + + /**************************************************************************************** + * + * Added By Rich to implement AI Falling damage + * Called from Think with saved origin and velocity from before moving + * + ****************************************************************************************/ + void CrashLand( const idVec3 &oldOrigin, const idVec3 &oldVelocity ); + + /** + * greebo: Accessor methods for the airTicks member variable. + */ + int getAirTicks() const; + void setAirTicks(int airTicks); + + // greebo: Accessor methods for the array of subsystems + ai::Subsystem* GetSubsystem(ai::SubsystemId id); + + ID_INLINE ai::MindPtr& GetMind() + { + return mind; + } + + ID_INLINE ai::Memory& GetMemory() const + { + return mind->GetMemory(); + } + + ID_INLINE idAAS* GetAAS() const + { + return aas; + } + + float GetArmReachLength(); + + // Virtual override of idActor method, routes the call into the current Mind State + virtual void NeedToUseElevator(const eas::RouteInfoPtr& routeInfo); + + // Switches this AI into conversation mode + virtual bool SwitchToConversationState(const idStr& conversationName); + + +public: + idLinkList aiNode; // for being linked into gameLocal.spawnedAI list + + // greebo: When this AI has last re-evaluated a forbidden area (game time) + int lastAreaReevaluationTime; + // The minimum time that needs to pass by before the AI re-evaluates a forbidden area (msec) + int maxAreaReevaluationInterval; + // The time that needs to pass before locked doors are enabled for another try (msec) + int doorRetryTime; + +protected: + // navigation + idAAS * aas; + int travelFlags; + + idMoveState move; + idMoveState savedMove; + + // A stack of movestates, used for saving and restoring moves in PushMove() and PopMove() + std::list moveStack; + + float kickForce; + bool ignore_obstacles; + float blockedRadius; + int blockedMoveTime; + int blockedAttackTime; + + // turning + float ideal_yaw; + float current_yaw; + float turnRate; + float turnVel; + float anim_turn_yaw; + float anim_turn_amount; + float anim_turn_angles; + + // angua: the offset of the pivot for turning while seated + idVec3 sitting_turn_pivot; + + // This expands the AABB a bit when the AI is checking for reached positions. + float reachedpos_bbox_expansion; + + // greebo: Defines the maximum vertical tolerance within wich a point above an AAS area is still considered reachable. + // This is used by PathToGoal to judge whether an area is reachable or not. + float aas_reachability_z_tolerance; + + // physics + idPhysics_Monster physicsObj; + + // flying + jointHandle_t flyTiltJoint; + float fly_speed; + float fly_bob_strength; + float fly_bob_vert; + float fly_bob_horz; + int fly_offset; // prefered offset from player's view + float fly_seek_scale; + float fly_roll_scale; + float fly_roll_max; + float fly_roll; + float fly_pitch_scale; + float fly_pitch_max; + float fly_pitch; + + bool allowMove; // disables any animation movement + bool allowHiddenMovement; // allows character to still move around while hidden + bool disableGravity; // disables gravity and allows vertical movement by the animation + + // weapon/attack vars + bool lastHitCheckResult; + int lastHitCheckTime; + int lastAttackTime; + float fire_range; + float projectile_height_to_distance_ratio; // calculates the maximum height a projectile can be thrown + idList missileLaunchOffset; + + struct ProjectileInfo + { + const idDict* def; + idStr defName; + idClipModel* clipModel; + float radius; + float speed; + idVec3 velocity; + idVec3 gravity; + + ProjectileInfo() : + def(NULL), + clipModel(NULL), + radius(-1), + speed(-1) + {} + + ~ProjectileInfo() + { + // Take care of any allocated clipmodels on destruction + delete clipModel; + } + }; + + /** + * greebo: An AI can have multiple projectile defs in their entityDef declaration. + * For some routines the properties of each projectile need to be cached, like + * radius, clipmodel and gravity, this is stored in the ProjectileInfo structure. + * + * After each CreateProjectile() call the "current projectile" index is recalculated + * and might point to a different projectile for the next round of firing. + */ + idList projectileInfo; + + // The index of the "current projectile", is recalculated each time CreateProjectile() is called. + int curProjectileIndex; + + /** + * The currently active projectile. It holds the spawned + * projectile entity, which can either be generated from the + * list of possible ProjectileInfo structures above or a custom + * one which has been spawned directly via script or frame commands. + * + * The ActiveProjectile structure is filled either by calling CreateProjectile() + * or by methods like Event_CreateThrowableProjectile() + */ + struct ActiveProjectile + { + // The projectile parameter structure + ProjectileInfo info; + + // The currently active projectile entity (might be NULL) + idEntityPtr projEnt; + }; + + // The currently active projectile, might be an empty structure + ActiveProjectile activeProjectile; + + idStr attack; + + /** + * grayman #2603 - Per-stim info for relighting lights. This allows AI to + * keep track of delays for responding to visual stims. The delays are + * determined by conditions surrounding a relight and the probabilities + * associated with relighting. + */ + struct DelayedStim + { + // The next time to consider the stim + int nextTimeToConsider; + + // The stim being delayed + idEntityPtr stim; + }; + + idList delayedStims; // grayman #2603 + + // chatter/talking + talkState_t talk_state; + idEntityPtr talkTarget; + + // cinematics + int num_cinematics; + int current_cinematic; + + bool allowJointMod; + idEntityPtr focusEntity; + idVec3 currentFocusPos; + int focusTime; + int alignHeadTime; + int forceAlignHeadTime; + idAngles eyeAng; + idAngles lookAng; + idAngles destLookAng; + idAngles lookMin; + idAngles lookMax; + idList lookJoints; + idList lookJointAngles; + idList lookJointsCombat; + idList lookJointAnglesCombat; + float eyeVerticalOffset; + float eyeHorizontalOffset; + float eyeFocusRate; + float headFocusRate; + int focusAlignTime; + + // special fx + float shrivel_rate; + int shrivel_start; + + bool restartParticles; // should smoke emissions restart + bool useBoneAxis; // use the bone vs the model axis + idList particles; // particle data + + renderLight_t worldMuzzleFlash; // positioned on world weapon bone + int worldMuzzleFlashHandle; + jointHandle_t flashJointWorld; + int muzzleFlashEnd; + int flashTime; + + // joint controllers + idAngles eyeMin; + idAngles eyeMax; + jointHandle_t focusJoint; + jointHandle_t orientationJoint; + + typedef std::set FrobMoverList; + FrobMoverList unlockableDoors; + + typedef std::set TactileIgnoreList; + TactileIgnoreList tactileIgnoreEntities; + +public: // greebo: Made these public + // enemy variables + idEntityPtr enemy; + idVec3 lastVisibleEnemyPos; + idVec3 lastVisibleEnemyEyeOffset; + idVec3 lastVisibleReachableEnemyPos; + idVec3 lastReachableEnemyPos; + bool enemyReachable; + bool wakeOnFlashlight; + int lastUpdateEnemyPositionTime; + + // grayman #2887 - next 2 are used to determine amount of "busted" time + + int lastTimePlayerSeen; + int lastTimePlayerLost; + +public: // greebo: Made these public for now, I didn't want to write an accessor for EVERYTHING + // script variables + idScriptBool AI_TALK; + idScriptBool AI_DAMAGE; + idScriptBool AI_PAIN; + idScriptFloat AI_SPECIAL_DAMAGE; + //idScriptBool AI_DEAD; // is defined on idActor now + idScriptBool AI_KNOCKEDOUT; + idScriptBool AI_ENEMY_VISIBLE; + idScriptBool AI_ENEMY_IN_FOV; + idScriptBool AI_MOVE_DONE; + idScriptBool AI_ONGROUND; + idScriptBool AI_ACTIVATED; + idScriptBool AI_FORWARD; + idScriptBool AI_JUMP; + idScriptBool AI_BLOCKED; + idScriptBool AI_OBSTACLE_IN_PATH; + idScriptBool AI_DEST_UNREACHABLE; + idScriptBool AI_HIT_ENEMY; + idScriptBool AI_PUSHED; + + /** + * The following variables are set as soon as the AI + * gets a certain type of alert, and never unset by the + * game code. They are only unset in scripting. This is + * to facilitate different script reactions to different kinds + * of alerts. + * + * It's also done this way so that the AI will know if it has been + * alerted even if it happened in a frame that the script did not check. + * + * This is to facilitate optimization by having the AI check for alerts + * every N frames rather than every frame. + **/ + + + /** + * Set to true if the AI heard a suspicious sound. + **/ + idScriptBool AI_HEARDSOUND; + + /** + * Set to true if the AI saw something suspicious. + **/ + idScriptBool AI_VISALERT; + + /** + * Set to true if the AI was pushed by or bumped into an enemy. + **/ + idScriptBool AI_TACTALERT; + + /** + * The current alert number of the AI. + * This is checked to see if the AI should + * change alert indices. This var is very important! + * NOTE: Don't change this directly. Instead, call Event_SetAlertLevel + * to change it. + **/ + idScriptFloat AI_AlertLevel; + + /** + * Current alert index of the AI. Is set based on AI_AlertLevel and the alert threshold values: + * ai::ERelaxed == 0 if AI_AlertLevel < thresh_1 + * ai::EObservant == 1 if thresh_1 <= AI_AlertLevel < thresh_2 + * ai::ESuspicious == 2 if thresh_2 <= AI_AlertLevel < thresh_3 + * ai::EInvestigating == 3 if thresh_3 <= AI_AlertLevel < thresh_4 + * ai::EAgitatedSearching == 4 if thresh_4 <= AI_AlertLevel < thresh_5 + * ai::ECombat == 5 if thresh_5 <= AI_AlertLevel (and an enemy is known) + **/ + idScriptFloat AI_AlertIndex; + + /** + * Stores the amount alerted in this frame + * Used to compare simultaneous alerts, the smaller one is ignored + * Should be cleared at the start of each frame. + **/ + float m_AlertLevelThisFrame; + + + // angua: stores the previous alert index at alert index changes + int m_prevAlertIndex; + + // angua: the highest alert level/index the AI reached already + float m_maxAlertLevel; + int m_maxAlertIndex; + + // angua: the alert level the AI had after the last alert level increase + float m_lastAlertLevel; + + /** + * If true, the AI ignores alerts during all actions + **/ + bool m_bIgnoreAlerts; + + /** + * Array containing the various AI acuities (visual, aural, tactile, etc) + **/ + idList m_Acuities; + + + float m_oldVisualAcuity; // Tels: fixes 2408 + + /** + * Audio detection threshold (in dB of Sound Pressure Level) + * Sounds heard below this volume will be ignored (default is 20 dB) + * Soundprop only goes down to 15 dB, although setting it lower than + * this will still have some effect, since alert = volume - threshold + **/ + float m_AudThreshold; + + /** + * Static visual distance cutoff that is calculated dynamically + * from the other visual acuity settings. + **/ + float m_VisDistMax; + + /** + * The loudest direction for the last suspicious sound the AI heard + * is set to NULL if the AI has not yet heard a suspicious sound + * Note suspicious sounds that are omnidirectional do not set this. + * If no sound has been propagated it will be (0,0,0). + **/ + idVec3 m_SoundDir; + + /** + * Position of the last visual alert + **/ + idVec3 m_LastSight; + + /** + * The entity that last issued a tactile alert + **/ + idEntityPtr m_TactAlertEnt; + + /** + * Alert Grace period variables : + * Actor that the alert grace period applies to: + **/ + idEntityPtr m_AlertGraceActor; + + /** + * Time of the grace period start [ms] + **/ + int m_AlertGraceStart; + + /** + * Duration of the grace period [ms] + **/ + int m_AlertGraceTime; + + /** + * Alert number below which alerts are ignored during the grace period + **/ + float m_AlertGraceThresh; + + /** + * Number of alerts ignored in this grace period + **/ + int m_AlertGraceCount; + + /** + * Number of alerts it takes to override the grace period via sheer number + * (This is needed to make AI rapidly come up to alert due to visual alert, + * because visual alerts do not increase in magnitude but just come in more rapidly + **/ + int m_AlertGraceCountLimit; + + /** + * greebo: This is the message "outbox" of an AI. During sound propagation + * the messages are traversed and delivered to the "recipient" AI. + * Once delivered, messages are automatically removed from this list. + * + * Use AddMessage() to store new messages here. + */ + ai::MessageList m_Messages; + + /** + * The current mod hiding spot search of this AI, usually -1 + */ + int m_HidingSpotSearchHandle; + + /** + * The spots resulting from the current search or gotten from + * another AI. + */ + CDarkmodHidingSpotTree m_hidingSpots; + + + /** + * Used for drowning + **/ + int m_AirCheckTimer; + + bool m_bCanDrown; + + /** + * Head body ID on the AF, used by drowning + **/ + int m_HeadBodyID; + + /** + * Head joint ID on the living AI (used by FOV and KOing) + **/ + jointHandle_t m_HeadJointID; + + /** + * Some AI have a different head CM while conscious. + * This variable stores the original head CM from the AF, + * to set it back when they die/get ko'd. + **/ + idClipModel *m_OrigHeadCM; + /** If true, head was swapped when alive and needs to be swapped back when ragdolled **/ + bool m_bHeadCMSwapped; + + /** + * Knockout Data + * Name of damage location within which a KO is possible + **/ + idStr m_KoZone; + /** + * Alert state above which their KO Immunity changes (if any) + **/ + int m_KoAlertImmuneState; + /** + * Alert state above which their KO behavior changes (if any) + **/ + int m_KoAlertState; + /** + * True if AI is completely immune to KO when alerted above the given alert state + **/ + bool m_bKoAlertImmune; + /** + * Cosines of the vertical and horizontal angles, and the same when alert + **/ + float m_KoDotVert; + float m_KoDotHoriz; + float m_KoAlertDotVert; + float m_KoAlertDotHoriz; + /** + * Rotates the KO cone relative to the head joint + **/ + idMat3 m_KoRot; + + /** + * Current number of air ticks left for drowning + **/ + int m_AirTics; + + /** + * Max number of air ticks for drowning + **/ + int m_AirTicksMax; + + /** + * number of seconds between air checks + **/ + int m_AirCheckInterval; + + /** + * Offset relative to the head origin when the head is separate, or the eye + * when the head is attached. Used to locate the mouth. + **/ + idVec3 m_MouthOffset; + + /** + * Set to true if the AI can be KO'd (defaults to true) + **/ + bool m_bCanBeKnockedOut; + + /** + * Set to true if the AI can be gassed (defaults to true) + **/ + bool m_bCanBeGassed; // grayman #2468 + + /** + * How the AI was knocked out + **/ + koState_t m_koState; // grayman #2604 + + /** + * Keep track of initial thinking frame count - important when a cinematic starts the mission + **/ + int m_earlyThinkCounter; // grayman #2654 + + /** + * grayman #2603 - if TRUE, don't allow movement extrication + **/ + + bool m_bCanExtricate; + + /** + * greebo: Is set to TRUE if the AI is able to open/close doors at all. + */ + bool m_bCanOperateDoors; + + /** + * angua: is set true while the AI is handling the door. + */ + bool m_HandlingDoor; + + /** + * grayman #2706: is set true when the move prior to door handling is saved + */ + bool m_RestoreMove; + + /** + * grayman #2603: is set true when a search needs to be set up after relighting a light + */ + bool m_LatchedSearch; + + /** + * grayman #2603: list of doused lights seen + */ + idList< idEntityPtr > m_dousedLightsSeen; + + /** + * angua: is set true while the AI is handling an elevator. + */ + bool m_HandlingElevator; + + /** + * grayman #2603: is set true while the AI is relighting a light. + */ + bool m_RelightingLight; + + /** + * grayman #2872: is set to true while the AI is examining a rope + */ + bool m_ExaminingRope; + + /** + * grayman #2603: is set true while the AI is dropping a torch. + */ + bool m_DroppingTorch; + + /** + * Head center offset in head joint coordinates, relative to head joint + * When this offset is added to the head joint, we should be at the head center + **/ + idVec3 m_HeadCenterOffset; + + /** + * Rotates the FOV cone relative to the head joint + **/ + idMat3 m_FOVRot; + + /** + * Set to true if we want this AI to push off the player when the + * player ends up standing on top of them + * Applies only when the AI is alive + **/ + bool m_bPushOffPlayer; + + /** + * Ishtvan: Flat-footedness, disallows movement while maitaining ability to turn + * Currently only implemented in melee + * The following are timers for being flat-footed in all situations + **/ + bool m_bCanBeFlatFooted; + bool m_bFlatFooted; + int m_FlatFootedTimer; + int m_FlatFootedTime; + /** + * The following apply to being flat-footed as a result of a parry only + **/ + int m_FlatFootParryNum; // runtime tracking + int m_FlatFootParryMax; // spawnarg cap + int m_FlatFootParryTimer; // runtime tracking + int m_FlatFootParryTime; // spawnarg cap [ms] + /** + * Melee: Chance to counter attack into an enemy attack instead of parrying: + **/ + float m_MeleeCounterAttChance; + /** + * Does this AI try to predict when the enemy will be close enough + * in the future and start their melee swing in advance? + **/ + bool m_bMeleePredictProximity; + + // AI_AlertLevel thresholds for each alert level + // Alert levels are: 1=slightly suspicious, 2=aroused, 3=investigating, 4=agitated investigating, 5=hunting + float thresh_1, thresh_2, thresh_3, thresh_4, thresh_5; + // Grace period info for each alert level + float m_gracetime_1, m_gracetime_2, m_gracetime_3, m_gracetime_4; + float m_gracefrac_1, m_gracefrac_2, m_gracefrac_3, m_gracefrac_4; + int m_gracecount_1, m_gracecount_2, m_gracecount_3, m_gracecount_4; + // De-alert times for each alert level + float atime1, atime2, atime3, atime4, atime_fleedone; + + float atime1_fuzzyness, atime2_fuzzyness, atime3_fuzzyness, atime4_fuzzyness, atime_fleedone_fuzzyness; + + // angua: Random head turning + int m_timeBetweenHeadTurnChecks; + float m_headTurnChanceIdle; + float m_headTurnFactorAlerted; + float m_headTurnMaxYaw; + float m_headTurnMaxPitch; + int m_headTurnMinDuration; + int m_headTurnMaxDuration; + + idEntity* m_tactileEntity; // grayman #2345 - something we bumped into this frame, not necessarily an enemy + bool m_canResolveBlock; // grayman #2345 - whether we can resolve a block if asked + bool m_leftQueue; // grayman #2345 - if we timed out waiting in a door queue + bool m_performRelight; // grayman #2603 - set to TRUE by a script function when it's time to relight a light + + // The mind of this AI + ai::MindPtr mind; + + // The array of subsystems of this AI + ai::SubsystemPtr senseSubsystem; + ai::MovementSubsystemPtr movementSubsystem; + ai::SubsystemPtr actionSubsystem; + ai::CommunicationSubsystemPtr commSubsystem; + + // greebo: The names of the backbone states, one for each alert state + // e.g. ECombat => "Combat" + typedef std::map BackboneStateMap; + BackboneStateMap backboneStates; + + /** + * This internal method destroys the current hiding spot search + * if it is not null. + */ + void destroyCurrentHidingSpotSearch(); + + /*! + * This method finds hiding spots in the bounds given by two vectors, and also excludes + * any points contained within a different pair of vectors. + * + * The first paramter is a vector which gives the location of the + * eye from which hiding is desired. + * + * The second vector gives the minimums in each dimension for the + * search space. + * + * The third and fourth vectors give the min and max bounds within which spots should be tested + * + * The fifth and sixth vectors give the min and max bounds of an area where + * spots should NOT be tested. This overrides the third and fourth parameters where they overlap + * (producing a dead zone where points are not tested) + * + * The seventh parameter gives the bit flags of the types of hiding spots + * for which the search should look. + * + * The eighth parameter indicates an entity that should be ignored in + * the visual occlusion checks. This is usually the searcher itself but + * can be NULL. + * + * This method will only start the search, if it returns 1, you should call + * continueSearchForHidingSpots every frame to do more processing until that function + * returns 0. + * + * The return value is a 0 for failure, 1 for success. + */ + int StartSearchForHidingSpotsWithExclusionArea + ( + const idVec3& hideFromLocation, + const idVec3& minBounds, + const idVec3& maxBounds, + const idVec3& exclusionMinBounds, + const idVec3& exclusionMaxBounds, + int hidingSpotTypesAllowed, + idEntity* p_ignoreEntity + ); + + /* + * This method continues searching for hiding spots. It will only find so many before + * returning so as not to cause long delays. Detected spots are added to the currently + * building hiding spot list. + * + * The return value is 0 if the end of the search was reached, or 1 if there + * is more processing to do (call this method again next AI frame) + * + */ + int ContinueSearchForHidingSpots(); + + /*! + * This method returns the Nth hiding spot location. + * Param is 0-based hiding spot index. + */ + idVec3 GetNthHidingSpotLocation(int hidingSpotIndex); + + /*! + * This event splits off half of the hiding spot list of another entity + * and sets our hiding spot list to the "taken" points. + * + * As such, it is useful for getting hiding spots from a seraching AI that this + * AI is trying to assist. + * + * @param p_otherEntity The other entity who's hiding spots we are taking + * + * @return The number of points in the list gotten + */ + int GetSomeOfOtherEntitiesHidingSpotList(idEntity* p_ownerOfSearch); + + void SetAAS( void ); + virtual void DormantBegin( void ); // called when entity becomes dormant + virtual void DormantEnd( void ); // called when entity wakes from being dormant + void Think( void ); + void Activate( idEntity *activator ); + int ReactionTo( const idEntity *ent ); + bool CheckForEnemy( void ); + void EnemyDead( void ); + + + /** + * angua: Interleaved thinking optimization + * AI will only think once in a certain number of frames + * depending on player distance and whether the AI is in the player view + * (this includes movement, pathing, physics and the states and tasks) + */ + + // This checks whether the AI should think in this frame + bool ThinkingIsAllowed(); + + // Sets the frame number when the AI should think next time + void SetNextThinkFrame(); + + // returns interleave think frames + // the AI will only think once in this number of frames + int GetThinkInterleave() const; // grayman 2414 - add 'const' + int m_nextThinkFrame; + + // Below min dist, the AI thinks normally every frame. + // Above max dist, the thinking frequency is given by max interleave think frames. + // The thinking frequency increases linearly between min and max dist. + int m_maxInterleaveThinkFrames; + float m_minInterleaveThinkDist; + float m_maxInterleaveThinkDist; + + // the last time where the AI did its thinking (used for physics) + int m_lastThinkTime; + + // grayman #2691 - this checks if a doorway is large enough to fit through when the door is fully open + bool CanPassThroughDoor(CFrobDoor* frobDoor); + + // grayman #2603 - am I carrying a torch? + idEntity* GetTorch(); + + bool IsSearching(); // grayman #2603 + + virtual void Hide( void ); + virtual void Show( void ); + virtual bool CanBecomeSolid(); + idVec3 FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ); + void CalculateAttackOffsets( void ); + void PlayCinematic( void ); + + // movement + virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); + void GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta ); + void CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ); + void DeadMove( void ); + void AnimMove( void ); + void SlideMove( void ); + void SittingMove(); + void NoTurnMove(); + void LayDownMove(); + void AdjustFlyingAngles( void ); + void AddFlyBob( idVec3 &vel ); + void AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ); + void FlySeekGoal( idVec3 &vel, idVec3 &goalPos ); + void AdjustFlySpeed( idVec3 &vel ); + void FlyTurn( void ); + void FlyMove( void ); + void StaticMove( void ); + + // greebo: Overrides idActor::PlayFootStepSound() + virtual void PlayFootStepSound(); + + // greebo: Plays the given bark sound (will override any sounds currently playing) + virtual void Bark(const idStr& soundName); + + // damage + virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ); + virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); + virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, + const char *damageDefName, const float damageScale, const int location, + trace_t *collision = NULL); + + void DropBlood(idEntity *inflictor); + void SpawnBloodMarker(const idStr& splat, const idStr& splatFading, float size); + + void PostDeath(); + + /** + * Copy knockout spawnargs from the head entity (assumes head exists) + **/ + void CopyHeadKOInfo(void); + + /** + * Parse knockout spawnargs + **/ + void ParseKnockoutInfo( void ); + + /** + * TestKnockOutBlow is called when the AI is hit with a weapon with knockout capability. + * This function tests the location hit, angle of the blow, and alert state of the AI. + * + * The "dir" vector is from the knockback of the weapon. It is not used for now. + * + * tr is the trace from the weapon collision, location is the joint handle that was hit + * bIsPowerBlow is set if the BJ was powered up + * + * Returns false if BJ attempt failed, or if already knocked out + * + * Note: overrides idActor::TestKnockoutBlow. + **/ + virtual bool TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ); + + /** + * Tells the AI to go unconscious. Called by TestKnockoutBlow if successful, + * also can be called by itself and is called by scriptevent AI_KO_Knockout. + * + * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". + **/ + void Event_KO_Knockout( idEntity* inflictor ); + + /** + * grayman #2468 - Tells the AI to go unconscious. Called by scriptevent AI_Gas_Knockout. + * + * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". + **/ + void Event_Gas_Knockout( idEntity* inflictor ); + + /** + * Tells the AI to go unconscious. + * + * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". + **/ + void Knockout( idEntity* inflictor ); + + /** + * greebo: Does a few things after the knockout animation has finished. + * This includes setting the model, dropping attachments and starting ragdoll mode. + * Note: Gets called by the Mind's KnockOutState. + */ + void PostKnockOut(); + + /** + * Drop certain attachments and def_drop items when transitioning into a ragdoll state + * Called by idActor::Killed and idActor::KnockedOut + **/ + void DropOnRagdoll( void ); + + // navigation + void KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ); + + // greebo: For Documentation, see idActor class (this is an override). + virtual bool ReEvaluateArea(int areaNum); + + /** + * greebo: ReachedPos checks whether we the AI has reached the given target position . + * The check is a bounds check ("bounds contain point?"), the bounds radius is + * depending on the given . + * + * @returns: TRUE when the position has been reached, FALSE otherwise. + */ + bool ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand) const; + + // greebo: Bounding box check to see if the AI has reached the given position. Returns TRUE if position reached. + bool ReachedPosAABBCheck(const idVec3& pos) const; + + float TravelDistance( const idVec3 &start, const idVec3 &end ); + + /** + * greebo: Returns the number of the nearest reachable area for the given point. + * Depending on the move type, the call is routed to the AAS->PointReachableAreaNum + * function. The bounds are modified before submission to the AAS function. + * + * @returns: the areanumber of the given point, 0 == no area found. + */ + int PointReachableAreaNum(const idVec3 &pos, const float boundsScale = 2.0f, const idVec3& offset = idVec3(0,0,0)) const; + + bool PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, idActor* actor ) const; + void DrawRoute( void ) const; + bool GetMovePos( idVec3 &seekPos ); + bool MoveDone( void ) const; + + ID_INLINE moveType_t GetMoveType() const + { + return move.moveType; + } + + void SetMoveType( int moveType ); + + + /** + * This is a virtual override of the idActor method. It takes lighting levels into consideration + * additional to the ordinary FOV/trace check in idActor. + */ + virtual bool CanSee( idEntity *ent, bool useFOV ) const; + + + /** + * This version can optionally use or not use lighting and fov + */ + virtual bool CanSeeExt ( idEntity* ent, const bool useFOV, const bool useLighting ) const; + + /** + * This tests if a position is visible. it can optionally use lighting and fov. + */ + virtual bool CanSeePositionExt( idVec3 position, bool useFOV, bool useLighting ); + + bool EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos ); + + bool CanSeeTargetPoint( idVec3 point, idEntity* target ) const; // grayman #2859 + + idVec3 CanSeeRope( idEntity *ent ) const; // grayman #2872 + + // angua: if the focusTime > gameLocal.time, the AI is currently looking at a specified entity or location + ID_INLINE int GetFocusTime() + { + return focusTime; + } + + void BlockedFailSafe( void ); + /** + * Overloaded idActor::CheckFOV with FOV check that depends on head joint orientation + **/ + virtual bool CheckFOV( const idVec3 &pos ) const; + + /** + * Darkmod enemy tracking: Is an entity shrouded in darkness? + * @author: SophisticatedZombie, tels + * + * The sightThreshold goes from 0.0f to 1.0f. Uses FOV, distance and lighting of the + * entity to determine visibility. + * + * @return true if the entity is in darkness + * @return false if not + */ + bool IsEntityHiddenByDarkness (idEntity* p_entity, const float sightThreshold) const; + + /** + * greebo: Returns TRUE if the entity is within the "attack_cone". + */ + bool EntityInAttackCone(idEntity* entity); + + /** + * Returns TRUE or FALSE, depending on the distance to the + * given entity and the weapons attached to this AI. + * Melee AI normally perform a bounding box expansion check, + * ranged AI implement a visual test incl. lighting. + */ + bool CanHitEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); + /** + * Will we be able to hit an enemy that is not currently in reach but coming into reach + * Similar to CanHitEntity, but uses predicted future positions based on velocity + * and a given prediction time. Only applies to melee combat + **/ + bool WillBeAbleToHitEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); + + /** + * Returns TRUE or FALSE, depending on the distance to the + * given entity and the weapons attached to it. + * May include other factors such as relative velocity + * Ranged combat NYI (may overlap with existing "take cover" algorithms) + */ + bool CanBeHitByEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); + + /** + * greebo: This updates the weapon attachment's "solid" status. + * By design, AI have solid weapons only when in searching states. + */ + void UpdateAttachmentContents(bool makeSolid); + + + // movement control + void StopMove( moveStatus_t status ); + bool FaceEnemy( void ); + bool FaceEntity( idEntity *ent ); + bool DirectMoveToPosition( const idVec3 &pos ); + bool MoveToEnemyHeight( void ); + bool MoveOutOfRange( idEntity *entity, float range ); + const idVec3& GetMoveDest() const; + idEntity* GetTactileEntity(void); // grayman #2345 + + /** + * greebo: Flee from the given entity. Pass the maximum distance this AI should search escape areas in. + */ + bool Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption); + aasGoal_t GetPositionWithinRange(const idVec3& targetPos); + idVec3 GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne); + bool MoveToAttackPosition( idEntity *ent, int attack_anim ); + bool MoveToEnemy( void ); + bool MoveToEntity( idEntity *ent ); + + // Override idActor::OnElevator. See idActor class for documentation. + virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; + + /** + * greebo: This moves the entity to the given point. + * + * @returns: FALSE, if the position is not reachable (AI_DEST_UNREACHABLE && AI_MOVE_DONE == true) + * @returns: TRUE, if the position is reachable and the AI is moving (AI_MOVE_DONE == false) + * OR the position is already reached (AI_MOVE_DONE == true). + */ + bool MoveToPosition( const idVec3 &pos, float accuracy = -1 ); + + /** + * angua: This looks for a suitable position for taking cover + * + * @returns: FALSE, if no suitable position is found + * @returns: TRUE, if the position is reachable + * The position is stored in . + */ + bool LookForCover(aasGoal_t& hideGoal, idEntity *entity, const idVec3 &pos ); + bool MoveToCover( idEntity *entity, const idVec3 &pos ); + bool SlideToPosition( const idVec3 &pos, float time ); + bool WanderAround( void ); + /** + * Ish : Move AI along a vector without worrying about AAS or obstacles + * Can be used for direct control of an AI + * Applies finite turn speed toward the direction + **/ + bool MoveAlongVector( float yaw ); + bool StepDirection( float dir ); + bool NewWanderDir( const idVec3 &dest ); + + // greebo: These two Push/Pop commands can be used to save the current move state in a stack and restore it later on + void PushMove(); + void PopMove(); + + // Local helper function, will restore the current movestate from the given saved one + void RestoreMove(const idMoveState& saved); + + // effects + const idDeclParticle *SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName ); + void SpawnParticles( const char *keyName ); + bool ParticlesActive( void ); + + // turning + bool FacingIdeal( void ); + void Turn(const idVec3& pivotOffset = idVec3(0,0,0)); + bool TurnToward( float yaw ); + bool TurnToward( const idVec3 &pos ); + ID_INLINE float GetCurrentYaw() { return current_yaw; } + ID_INLINE float GetIdealYaw() { return ideal_yaw; } // grayman #2345 + ID_INLINE float GetTurnRate() { return turnRate; } + ID_INLINE void SetTurnRate(float newTurnRate) { turnRate = newTurnRate; } + + // enemy management + void ClearEnemy( void ); + bool EnemyPositionValid( void ) const; + + /** + * greebo: SetEnemyPos() tries to determine the enemy location and to setup a path + * to the enemy, depending on the AI's move type (FLY/WALK). + * + * If this method succeeds in setting up a path to the enemy, the following members are + * set: lastVisibleReachableEnemyPos, lastVisibleReachableEnemyAreaNum + * and the movecommands move.toAreaNum and move.dest are updated, but the latter two + * ONLY if the movecommand is set to MOVE_TO_ENEMY beforehand. + * + * The AI_DEST_UNREACHABLE is updated if the movecommand is currently set to MOVE_TO_ENEMY. + * + * It is TRUE (enemy unreachable) in the following cases: + * - Enemy is not on ground (OnLadder) for non-flying AI. + * - The entity area number could not be determined. + * - PathToGoal failed, no path to the enemy could be found. + * + * Note: This overwrites a few lastVisibleReachableEnemyPos IN ANY CASE with the + * lastReachableEnemyPos, so this is kind of cheating if the enemy is not visible before calling this. + * Also, lastVisibleEnemyPos is overwritten by the enemy's origin IN ANY CASE. + * + * Basically, this method relies on "lastReachableEnemyPos" being set beforehand. + */ + void SetEnemyPosition(); + + /** + * greebo: This is pretty similar to SetEnemyPosition, but not the same. + * + * First, this tries to locate the current enemy position (disregards visibility!) and + * to set up a path to the entity's origin/floorposition. If this succeeds, + * the "lastReachableEnemyPos" member is updated, but ONLY if the enemy is on ground. + * + * Second, if the enemy is visible or heard, SetEnemyPosition is called, which updates + * the lastVisibleReachableEnemyPosition. + */ + void UpdateEnemyPosition(); + + /** + * greebo: Updates the enemy pointer and tries to set up a path to the enemy by + * using SetEnemyPosition(), but ONLY if the enemy has actually changed. + * + * AI_ENEMY_DEAD is updated at any rate. + * + * @returns: TRUE if the enemy has been set and is non-NULL, FALSE if the enemy + * is dead or has been cleared by anything else. + */ + bool SetEnemy(idActor *newEnemy); + + /** + * DarkMod: Ishtvan note: + * Before I added this, this code was only called in + * Event_FindEnemy, so it could be used by scripting, but + * not by the SDK. I just moved the code to a new function, + * and made Event_FindEnemy call this. + * + * This was because I needed to use FindEnemy in the visibility + * calculation. + **/ + idActor * FindEnemy( bool useFOV ) ; + + idActor* FindEnemyAI(bool useFOV); + + idActor* FindFriendlyAI(int requiredTeam); + + + /** + * Similarly to FindEnemy, this was previously only an Event_ scripting + * function. I moved it over to a new SDK function and had the Event_ + * call it, in case we want to use this later. It returns the closest + * AI or Player enemy. + * + * It was originally used to get tactile alerts, but is no longer used for that + * IMO we should leave it in though, as we might use it for something later, + * like determining what targets to engage with ranged weapons. + **/ + idActor * FindNearestEnemy( bool useFOV = true ); + + /** + * angua: this returns if the AI has seen evidence of an intruder already + * (the enemy, a body, missing loot...) + */ + bool HasSeenEvidence() const; + + /** + * Draw the debug cone representing valid knockout area + * Called every frame when cvar cv_ai_ko_show is set to true. + **/ + void KnockoutDebugDraw( void ); + + /** + * Draw the debug cone representing the FOV + * Called every frame when cvar cv_ai_fov_show is set to true. + **/ + void FOVDebugDraw( void ); + + /** + * This method calculates the maximum distance from a given + * line segment that the segment is visible due to current light conditions + * at the segment. Does not accept NULL pointers! + */ + float GetMaximumObservationDistanceForPoints(const idVec3& p1, const idVec3& p2) const; + + // Returns the maximum distance where this AI can still see the given entity from + float GetMaximumObservationDistance(idEntity* entity) const; + + /** + * The point of this function is to determine the visual stimulus level caused + * by addition of the CVAR tdm_ai_sight_mag. The current alert level is taken + * as reference value and the difference in logarithmic alert units is returned. + */ + float GetPlayerVisualStimulusAmount() const; + + // attacks + + // greebo: Ensures that the projectile info of the currently active projectile + // is holding a valid clipmodel and returns the info structure for convenience. + ProjectileInfo& EnsureActiveProjectileInfo(); + + // Called at spawn time to ensure valid projectile properties in the info structures (except clipmodel) + // activeProjectile.projEnt will be NULL after this call + void InitProjectileInfo(); + + // Specialised routine to initialise the given projectile info structure from the named or given dictionary + // Won't touch the activeProjectile structure, so it's safe to use that as helper. + void InitProjectileInfoFromDict(ProjectileInfo& info, const char* entityDef) const; + void InitProjectileInfoFromDict(ProjectileInfo& info, const idDict* dict) const; + + /** + * greebo: Changed this method to support multiple projectile definitions (D3 suppoerted exactly one). + * The index argument can be set to anything within [0..projectileInfo.Num()) to spawn a specific + * projectile from the list of possible ones, or leave that argument at the default of -1 to + * create a projectile using the "current projectile index". That index is re-rolled each + * time after this method has been called, so the AI will seemingly use random projectiles. + * + * Note: doesn't do anything if the currently active projectile is not NULL. + */ + idProjectile* CreateProjectile(const idVec3 &pos, const idVec3 &dir, int index = -1); + +private: + /** + * greebo: Specialised method similar to the CreateProjectile() variant taking an index. + * This method doesn't use the projectileInfo list, but spawns a new active projectile + * directly from the given dictionary. This can be used to spawn projectiles out of the usual + * loop of known projectile defs. + * + * Note: doesn't do anything if the currently active projectile is not NULL. + */ + idProjectile* CreateProjectileFromDict(const idVec3 &pos, const idVec3 &dir, const idDict* dict); + + // Helper routine to spawn an actual projectile with safety checks. Will throw gameLocal.Error on failure. + // The result will always be non-NULL + idProjectile* SpawnProjectile(const idDict* dict) const; + + void RemoveProjectile( void ); + +public: + idProjectile* LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone ); + virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); + void DirectDamage( const char *meleeDefName, idEntity *ent ); + bool TestMelee( void ) const; + /** ishtvan: test melee anticipating future positions **/ + bool TestMeleeFuture( void ) const; + bool TestRanged( void ); + bool AttackMelee( const char *meleeDefName ); + void BeginAttack( const char *name ); + void EndAttack( void ); + void PushWithAF( void ); + + // special effects + void GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ); + void InitMuzzleFlash( void ); + void TriggerWeaponEffects( const idVec3 &muzzle ); + void UpdateMuzzleFlash( void ); + virtual bool UpdateAnimationControllers( void ); + void UpdateParticles( void ); + void TriggerParticles( const char *jointName ); + + // AI script state management + virtual void LinkScriptVariables( void ); + virtual void UpdateScript(); // overrides idActor::UpdateScript + + // Returns true if the current enemy can be reached + bool CanReachEnemy(); + + // Returns the current move status (MOVE_STATUS_MOVING, for instance). + moveStatus_t GetMoveStatus() const; + + /** + * Returns true if AI's mouth is underwater + **/ + bool MouthIsUnderwater( void ); + + /** + * Checks for drowning, damages if drowning. + * + * greebo: Only enabled if the entity is able to drown and the + * interleave timer is elapsed (is not checked each frame). + **/ + void UpdateAir(); + + /** + * Halts lipsync + **/ + void StopLipSync(); + + /** + * Plays and lipsyncs the given sound name, returns the duration in msecs. + */ + int PlayAndLipSync(const char *soundName, const char *animName); + + // Lip sync stuff + bool m_lipSyncActive; /// True iff we're currently lip syncing + int m_lipSyncAnim; /// The number of the animation that we are lipsyncing to + int m_lipSyncEndTimer; /// Time at which to stop lip syncing + + /** Call the script function DrawWeapon (in a new thread) if it exists */ + void DrawWeapon(); + /** Call the script function SheathWeapon (in a new thread) if it exists */ + void SheathWeapon(); + + // angua: this is used to check whether the AI is able to unlock a specific door + bool CanUnlock(CBinaryFrobMover *frobMover); + + // angua: this checks whether the AI should close the door after passing through + bool ShouldCloseDoor(CBinaryFrobMover *frobMover); + + // greebo: Contains all the checks for CVAR-dependent debug info + void ShowDebugInfo(); + + const idStr& GetNextIdleAnim(); + void SetNextIdleAnim(const idStr& nextIdleAnim); + + // grayman #2603 - work with the list of delayed visual stims + + void SetDelayedStimExpiration(idEntityPtr stimPtr); + int GetDelayedStimExpiration(idEntityPtr stimPtr); + + // + // ai/ai_events.cpp + // + // The post-spawn event parses the spawnargs which refer to other entities + // that might not be available at spawn time. + void Event_PostSpawn(); + void Event_Activate( idEntity *activator ); + +/***** +* DarkMod: Event_Touch was modified to issue a tactile alert. +* +* Note: Event_Touch checks ReactionTo, which checks our DarkMod Relations. +* So it will only go off if the AI is bumped by an enemy that moves into it. +* This is NOT called when an AI moves into an enemy. +* +* AI bumping by inanimate objects is handled separately by CheckTactile. +****/ + void Event_Touch( idEntity *other, trace_t *trace ); + + void Event_FindEnemy( int useFOV ); + void Event_FindEnemyAI( int useFOV ); + void Event_FindEnemyInCombatNodes( void ); + + /** + * greebo: Finds the nearest friendly and visible AI. Used to look for allies. + * The argument is optional and can be used to limit the search to a given team. + * Set to -1 to disable the team search. + * + * Returns the best candidate (can be the nullentity) to the script thread. + */ + void Event_FindFriendlyAI(int requiredTeam); + + void Event_ClosestReachableEnemyOfEntity( idEntity *team_mate ); + void Event_HeardSound( int ignore_team ); + void Event_SetEnemy( idEntity *ent ); + void Event_ClearEnemy( void ); + void Event_FoundBody( idEntity *body ); + void Event_MuzzleFlash( const char *jointname ); + void Event_CreateMissile( const char *jointname ); + void Event_CreateMissileFromDef(const char* defName, const char* jointname); + void Event_AttackMissile( const char *jointname ); + void Event_FireMissileAtTarget( const char *jointname, const char *targetname ); + void Event_LaunchMissile( const idVec3 &muzzle, const idAngles &ang ); + void Event_AttackMelee( const char *meleeDefName ); + void Event_DirectDamage( idEntity *damageTarget, const char *damageDefName ); + void Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName ); + void Event_BeginAttack( const char *name ); + void Event_EndAttack( void ); + void Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName ); + void Event_RandomPath( void ); + void Event_CanBecomeSolid( void ); + void Event_BecomeSolid( void ); + void Event_BecomeNonSolid( void ); + void Event_BecomeRagdoll( void ); + void Event_StopRagdoll( void ); + void Event_AllowDamage( void ); + void Event_IgnoreDamage( void ); + void Event_GetCurrentYaw( void ); + void Event_TurnTo( float angle ); + void Event_TurnToPos( const idVec3 &pos ); + void Event_TurnToEntity( idEntity *ent ); + void Event_MoveStatus( void ); + void Event_StopMove( void ); + void Event_MoveToCover( void ); + void Event_MoveToCoverFrom( idEntity *enemyEnt ); + void Event_MoveToEnemy( void ); + void Event_MoveToEnemyHeight( void ); + void Event_MoveOutOfRange( idEntity *entity, float range ); + void Event_Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption); + void Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim ); + void Event_MoveToEntity( idEntity *ent ); + void Event_MoveToPosition( const idVec3 &pos ); + void Event_SlideTo( const idVec3 &pos, float time ); + void Event_Wander( void ); + void Event_FacingIdeal( void ); + void Event_FaceEnemy( void ); + void Event_FaceEntity( idEntity *ent ); + void Event_WaitAction( const char *waitForState ); + void Event_GetCombatNode( void ); + void Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location ); + void Event_WaitMove( void ); + void Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ); + void Event_EntityInAttackCone( idEntity *ent ); + void Event_CanSeeEntity( idEntity *ent ); + void Event_CanSeeEntityExt( idEntity *ent, const int useFOV, const int useLighting); + void Event_IsEntityHidden( idEntity *ent, const float sightThreshold); + void Event_CanSeePositionExt( const idVec3& position, int useFOV, int useLighting); + void Event_SetTalkTarget( idEntity *target ); + void Event_GetTalkTarget( void ); + void Event_SetTalkState( int state ); + void Event_EnemyRange( void ); + void Event_EnemyRange2D( void ); + void Event_GetEnemy( void ); + void Event_GetEnemyPos( void ); + void Event_GetEnemyEyePos( void ); + void Event_PredictEnemyPos( float time ); + void Event_CanHitEnemy( void ); + void Event_CanHitEnemyFromAnim( const char *animname ); + void Event_CanHitEnemyFromJoint( const char *jointname ); + void Event_EnemyPositionValid( void ); + void Event_ChargeAttack( const char *damageDef ); + void Event_TestChargeAttack( void ); + void Event_TestAnimMoveTowardEnemy( const char *animname ); + void Event_TestAnimMove( const char *animname ); + void Event_TestMoveToPosition( const idVec3 &position ); + void Event_TestMeleeAttack( void ); + void Event_TestAnimAttack( const char *animname ); + void Event_Shrivel( float shirvel_time ); + void Event_Burn( void ); + void Event_PreBurn( void ); + void Event_ClearBurn( void ); + void Event_SetSmokeVisibility( int num, int on ); + void Event_NumSmokeEmitters( void ); + void Event_StopThinking( void ); + void Event_GetTurnDelta( void ); + void Event_GetMoveType( void ); + void Event_SetMoveType( int moveType ); + void Event_SaveMove( void ); + void Event_RestoreMove( void ); + void Event_AllowMovement( float flag ); + void Event_JumpFrame( void ); + void Event_EnableClip( void ); + void Event_DisableClip( void ); + void Event_EnableGravity( void ); + void Event_DisableGravity( void ); + void Event_EnableAFPush( void ); + void Event_DisableAFPush( void ); + void Event_SetFlySpeed( float speed ); + void Event_SetFlyOffset( int offset ); + void Event_ClearFlyOffset( void ); + void Event_GetClosestHiddenTarget( const char *type ); + void Event_GetRandomTarget( const char *type ); + void Event_TravelDistanceToPoint( const idVec3 &pos ); + void Event_TravelDistanceToEntity( idEntity *ent ); + void Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest ); + void Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest ); + void Event_LookAtEntity( idEntity *ent, float duration ); + void Event_LookAtEnemy( float duration ); + void Event_LookAtPosition (const idVec3& lookAtWorldPosition, float duration); + void Event_LookAtAngles (float yawAngleClockwise, float pitchAngleUp, float rollAngle, float durationInSeconds); + void Event_SetJointMod( int allowJointMod ); + void Event_ThrowMoveable( void ); + void Event_ThrowAF( void ); + void Event_SetAngles( idAngles const &ang ); + void Event_GetAngles( void ); + void Event_RealKill( void ); + void Event_Kill( void ); + void Event_WakeOnFlashlight( int enable ); + void Event_LocateEnemy( void ); + void Event_KickObstacles( idEntity *kickEnt, float force ); + void Event_GetObstacle( void ); + void Event_PushPointIntoAAS( const idVec3 &pos ); + void Event_GetTurnRate( void ); + void Event_SetTurnRate( float rate ); + void Event_AnimTurn( float angles ); + void Event_AllowHiddenMovement( int enable ); + void Event_TriggerParticles( const char *jointName ); + void Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs ); + void Event_CanReachPosition( const idVec3 &pos ); + void Event_CanReachEntity( idEntity *ent ); + void Event_CanReachEnemy( void ); + void Event_GetReachableEntityPosition( idEntity *ent ); + void Event_ReEvaluateArea(int areanum); + + // Script interface for state manipulation + void Event_PushState(const char* state); + void Event_SwitchState(const char* state); + void Event_EndState(); + + void Event_PlayAndLipSync( const char *soundName, const char *animName ); + + /** + * Frontend scripting functions for Dark Mod Relations Manager + * See CRelations class definition for descriptions + **/ + void Event_GetRelationEnt( idEntity *ent ); + + void Event_SetAlertLevel( float newAlertLevel ); + + /** + * Script frontend for idAI::GetAcuity and idAI::SetAcuity + * and idAI::AlertAI + **/ + void Event_Alert( const char *type, float amount ); + void Event_GetAcuity( const char *type ); + void Event_SetAcuity( const char *type, float val ); + void Event_GetAudThresh( void ); + void Event_SetAudThresh( float val ); + + /** + * Get the actor that alerted the AI this frame + **/ + void Event_GetAlertActor( void ); + + /** + * Set an alert grace period + * First argument is the fraction of the current alert this frame to ignore + * Second argument is the number of SECONDS the grace period lasts. + * Third argument is the number of events it takes to override the grace period + **/ + void Event_SetAlertGracePeriod( float frac, float duration, int count ); + + /** + * Script frontend for DarkMod hiding spot detection functions + **/ + void Event_StartSearchForHidingSpots (const idVec3& hideFromLocation, const idVec3 &minBounds, const idVec3 &maxBounds, int hidingSpotTypesAllowed, idEntity* p_ignoreEntity); + void Event_StartSearchForHidingSpotsWithExclusionArea (const idVec3& hideFromLocation, const idVec3 &minBounds, const idVec3 &maxBounds, const idVec3 &exclusionMinBounds, const idVec3 &exclusionMaxBounds, int hidingSpotTypesAllowed, idEntity* p_ignoreEntity); + void Event_ContinueSearchForHidingSpots(); + void Event_CloseHidingSpotSearch (); + void Event_ResortHidingSpots ( const idVec3& searchCenter, const idVec3& searchRadius); + void Event_GetNumHidingSpots (); + void Event_GetNthHidingSpotLocation (int hidingSpotIndex); + void Event_GetNthHidingSpotType (int hidingSpotIndex); + void Event_GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne ); + void Event_GetSomeOfOtherEntitiesHidingSpotList (idEntity* p_ownerOfSearch); + + /** + * Gets the alert number of an entity that is another AI. + * Will return 0.0 to script if other entity is NULL or not an AI. + */ + void Event_GetAlertLevelOfOtherAI (idEntity* p_otherEntity); + + void Event_ProcessBlindStim(idEntity* stimSource, int skipVisibilityCheck); + /** + * greebo: Script event for processing a visual stim coming from the entity + */ + void Event_ProcessVisualStim(idEntity* stimSource); + + /*! + * Spawns a new stone projectile that the AI can throw + * + * @param pstr_projectileName Name of the projectile type to + * be spawned (as given in .def file) + * + * @param pstr_jointName Name of the model joint to which the + * stone projectile will be bound until thrown. + */ + void Event_SpawnThrowableProjectile ( const char* pstr_projectileName, const char* pstr_jointName ); + + /** + * Scan for the player in FOV, and cause a visual alert if found + * Currently only checks the player. + * Will return the entity that caused the visual alert for + * scripting purposes. + **/ + void Event_VisScan( void ); + + /** + * Return the last suspicious sound direction + **/ + void Event_GetSndDir( void ); + + /** + * Return the last visual alert position + **/ + void Event_GetVisDir( void ); + + /** + * Return the entity that the AI is in tactile contact with + **/ + void Event_GetTactEnt( void ); + + /** + * This is needed for accurate AI-AI combat + * It just calls the vanilla D3 event: + * Event_ClosestReachableEnemyToEntity( idEntity *ent ) + * with the "this" pointer. + * + * For some reason this was left out of D3. + **/ + void Event_ClosestReachableEnemy( void ); + + // Scripts query this to retrieve the name of the next idle anim + void Event_GetNextIdleAnim(); + + void Event_HasSeenEvidence(); + + // grayman #2603 - relighting lights + void Event_PerformRelight(); + + // grayman #2603 - drop torch + void Event_DropTorch(); + +#ifdef TIMING_BUILD +private: + int aiThinkTimer; + int aiMindTimer; + int aiAnimationTimer; + int aiPushWithAFTimer; + int aiUpdateEnemyPositionTimer; + int aiScriptTimer; + int aiAnimMoveTimer; + int aiObstacleAvoidanceTimer; + int aiPhysicsTimer; + int aiGetMovePosTimer; + int aiPathToGoalTimer; + int aiGetFloorPosTimer; + int aiPointReachableAreaNumTimer; + int aiCanSeeTimer; + + +#endif +}; + +class idCombatNode : public idEntity { +public: + CLASS_PROTOTYPE( idCombatNode ); + + idCombatNode(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + bool IsDisabled( void ) const; + bool EntityInView( idActor *actor, const idVec3 &pos ); + static void DrawDebugInfo( void ); + +private: + float min_dist; + float max_dist; + float cone_dist; + float min_height; + float max_height; + idVec3 cone_left; + idVec3 cone_right; + idVec3 offset; + bool disabled; + + void Event_Activate( idEntity *activator ); + void Event_MarkUsed( void ); +}; + +#endif /* !__AI_H__ */ diff --git a/game/ai/AI_events.cpp b/game/ai/AI_events.cpp new file mode 100644 index 000000000..11f2b8eff --- /dev/null +++ b/game/ai/AI_events.cpp @@ -0,0 +1,3493 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../Relations.h" +#include "../DarkModGlobals.h" +#include "../DarkmodAASHidingSpotFinder.h" +#include "../StimResponse/StimResponseCollection.h" +#include "../AbsenceMarker.h" +#include "Memory.h" +#include "States/State.h" + +#include +#include +#include +#include + +class CRelations; + +/*********************************************************************** + + AI Events + +***********************************************************************/ + +const idEventDef AI_FindEnemy( "findEnemy", "d", 'e' ); +const idEventDef AI_FindEnemyAI( "findEnemyAI", "d", 'e' ); +const idEventDef AI_FindEnemyInCombatNodes( "findEnemyInCombatNodes", NULL, 'e' ); +const idEventDef AI_ClosestReachableEnemyOfEntity( "closestReachableEnemyOfEntity", "E", 'e' ); +// greebo: TDM Event: Try to find a visible AI of the given team +const idEventDef AI_FindFriendlyAI( "findFriendlyAI", "d", 'e' ); +const idEventDef AI_ProcessBlindStim( "processBlindStim", "ed" ); +const idEventDef AI_ProcessVisualStim("processVisualStim", "e"); +const idEventDef AI_PerformRelight("performRelight"); // grayman #2603 +const idEventDef AI_DropTorch("dropTorch"); // grayman #2603 + +const idEventDef AI_SetEnemy( "setEnemy", "E" ); +const idEventDef AI_ClearEnemy( "clearEnemy" ); +const idEventDef AI_MuzzleFlash( "muzzleFlash", "s" ); +const idEventDef AI_CreateMissile( "createMissile", "s", 'e' ); +const idEventDef AI_CreateMissileFromDef( "createMissileFromDef", "ss", 'e' ); // arg1 = def name, arg2 = joint name +const idEventDef AI_AttackMissile( "attackMissile", "s", 'e' ); +const idEventDef AI_FireMissileAtTarget( "fireMissileAtTarget", "ss", 'e' ); +const idEventDef AI_LaunchMissile( "launchMissile", "vv", 'e' ); +const idEventDef AI_AttackMelee( "attackMelee", "s", 'd' ); +const idEventDef AI_DirectDamage( "directDamage", "es" ); +const idEventDef AI_RadiusDamageFromJoint( "radiusDamageFromJoint", "ss" ); +const idEventDef AI_BeginAttack( "attackBegin", "s" ); +const idEventDef AI_EndAttack( "attackEnd" ); +const idEventDef AI_MeleeAttackToJoint( "meleeAttackToJoint", "ss", 'd' ); +const idEventDef AI_RandomPath( "randomPath", NULL, 'e' ); +const idEventDef AI_CanBecomeSolid( "canBecomeSolid", NULL, 'f' ); +const idEventDef AI_BecomeSolid( "becomeSolid" ); +const idEventDef AI_BecomeRagdoll( "becomeRagdoll", NULL, 'd' ); +const idEventDef AI_StopRagdoll( "stopRagdoll" ); +const idEventDef AI_AllowDamage( "allowDamage" ); +const idEventDef AI_IgnoreDamage( "ignoreDamage" ); +const idEventDef AI_GetCurrentYaw( "getCurrentYaw", NULL, 'f' ); +const idEventDef AI_TurnTo( "turnTo", "f" ); +const idEventDef AI_TurnToPos( "turnToPos", "v" ); +const idEventDef AI_TurnToEntity( "turnToEntity", "E" ); +const idEventDef AI_MoveStatus( "moveStatus", NULL, 'd' ); +const idEventDef AI_StopMove( "stopMove" ); +const idEventDef AI_MoveToCover( "moveToCover" ); +const idEventDef AI_MoveToCoverFrom( "moveToCoverFrom", "E" ); +const idEventDef AI_MoveToEnemy( "moveToEnemy" ); +const idEventDef AI_MoveToEnemyHeight( "moveToEnemyHeight" ); +const idEventDef AI_MoveOutOfRange( "moveOutOfRange", "ef" ); +// greebo: Flee from an entity +const idEventDef AI_Flee( "flee", "edd", 'd' ); +const idEventDef AI_MoveToAttackPosition( "moveToAttackPosition", "es" ); +const idEventDef AI_Wander( "wander" ); +const idEventDef AI_MoveToEntity( "moveToEntity", "e" ); +const idEventDef AI_MoveToPosition( "moveToPosition", "v" ); +const idEventDef AI_SlideTo( "slideTo", "vf" ); +const idEventDef AI_FacingIdeal( "facingIdeal", NULL, 'd' ); +const idEventDef AI_FaceEnemy( "faceEnemy" ); +const idEventDef AI_FaceEntity( "faceEntity", "E" ); +const idEventDef AI_GetCombatNode( "getCombatNode", NULL, 'e' ); +const idEventDef AI_EnemyInCombatCone( "enemyInCombatCone", "Ed", 'd' ); +const idEventDef AI_WaitMove( "waitMove" ); +const idEventDef AI_GetJumpVelocity( "getJumpVelocity", "vff", 'v' ); +const idEventDef AI_EntityInAttackCone( "entityInAttackCone", "E", 'd' ); +const idEventDef AI_CanSeeEntity( "canSee", "E", 'd' ); +const idEventDef AI_CanSeeEntityExt( "canSeeExt", "Edd", 'd' ); +const idEventDef AI_CanSeePositionExt( "canSeePositionExt", "vdd", 'd' ); +const idEventDef AI_IsEntityHidden( "isEntityHidden", "Ed", 'd' ); +const idEventDef AI_SetTalkTarget( "setTalkTarget", "E" ); +const idEventDef AI_GetTalkTarget( "getTalkTarget", NULL, 'e' ); +const idEventDef AI_SetTalkState( "setTalkState", "d" ); +const idEventDef AI_EnemyRange( "enemyRange", NULL, 'f' ); +const idEventDef AI_EnemyRange2D( "enemyRange2D", NULL, 'f' ); +const idEventDef AI_GetEnemy( "getEnemy", NULL, 'e' ); +const idEventDef AI_GetEnemyPos( "getEnemyPos", NULL, 'v' ); +const idEventDef AI_GetEnemyEyePos( "getEnemyEyePos", NULL, 'v' ); +const idEventDef AI_PredictEnemyPos( "predictEnemyPos", "f", 'v' ); +const idEventDef AI_CanHitEnemy( "canHitEnemy", NULL, 'd' ); +const idEventDef AI_CanHitEnemyFromAnim( "canHitEnemyFromAnim", "s", 'd' ); +const idEventDef AI_CanHitEnemyFromJoint( "canHitEnemyFromJoint", "s", 'd' ); +const idEventDef AI_EnemyPositionValid( "enemyPositionValid", NULL, 'd' ); +const idEventDef AI_ChargeAttack( "chargeAttack", "s" ); +const idEventDef AI_TestChargeAttack( "testChargeAttack", NULL, 'f' ); +const idEventDef AI_TestMoveToPosition( "testMoveToPosition", "v", 'd' ); +const idEventDef AI_TestAnimMoveTowardEnemy( "testAnimMoveTowardEnemy", "s", 'd' ); +const idEventDef AI_TestAnimMove( "testAnimMove", "s", 'd' ); +const idEventDef AI_TestMeleeAttack( "testMeleeAttack", NULL, 'd' ); +const idEventDef AI_TestAnimAttack( "testAnimAttack", "s", 'd' ); +const idEventDef AI_Shrivel( "shrivel", "f" ); +const idEventDef AI_Burn( "burn" ); +const idEventDef AI_ClearBurn( "clearBurn" ); +const idEventDef AI_PreBurn( "preBurn" ); +const idEventDef AI_SetSmokeVisibility( "setSmokeVisibility", "dd" ); +const idEventDef AI_NumSmokeEmitters( "numSmokeEmitters", NULL, 'd' ); +const idEventDef AI_WaitAction( "waitAction", "s" ); +const idEventDef AI_StopThinking( "stopThinking" ); +const idEventDef AI_GetTurnDelta( "getTurnDelta", NULL, 'f' ); +const idEventDef AI_GetMoveType( "getMoveType", NULL, 'd' ); +const idEventDef AI_SetMoveType( "setMoveType", "d" ); +const idEventDef AI_SaveMove( "saveMove" ); +const idEventDef AI_RestoreMove( "restoreMove" ); +const idEventDef AI_AllowMovement( "allowMovement", "f" ); +const idEventDef AI_JumpFrame( "" ); +const idEventDef AI_EnableClip( "enableClip" ); +const idEventDef AI_DisableClip( "disableClip" ); +const idEventDef AI_EnableGravity( "enableGravity" ); +const idEventDef AI_DisableGravity( "disableGravity" ); +const idEventDef AI_EnableAFPush( "enableAFPush" ); +const idEventDef AI_DisableAFPush( "disableAFPush" ); +const idEventDef AI_SetFlySpeed( "setFlySpeed", "f" ); +const idEventDef AI_SetFlyOffset( "setFlyOffset", "d" ); +const idEventDef AI_ClearFlyOffset( "clearFlyOffset" ); +const idEventDef AI_GetClosestHiddenTarget( "getClosestHiddenTarget", "s", 'e' ); +const idEventDef AI_GetRandomTarget( "getRandomTarget", "s", 'e' ); +const idEventDef AI_TravelDistanceToPoint( "travelDistanceToPoint", "v", 'f' ); +const idEventDef AI_TravelDistanceToEntity( "travelDistanceToEntity", "e", 'f' ); +const idEventDef AI_TravelDistanceBetweenPoints( "travelDistanceBetweenPoints", "vv", 'f' ); +const idEventDef AI_TravelDistanceBetweenEntities( "travelDistanceBetweenEntities", "ee", 'f' ); +const idEventDef AI_LookAtEntity( "lookAt", "Ef" ); +const idEventDef AI_LookAtEnemy( "lookAtEnemy", "f" ); +const idEventDef AI_SetJointMod( "setBoneMod", "d" ); +const idEventDef AI_ThrowMoveable( "throwMoveable" ); +const idEventDef AI_ThrowAF( "throwAF" ); +const idEventDef AI_RealKill( "" ); +const idEventDef AI_Kill( "kill" ); +const idEventDef AI_WakeOnFlashlight( "wakeOnFlashlight", "d" ); +const idEventDef AI_LocateEnemy( "locateEnemy" ); +const idEventDef AI_KickObstacles( "kickObstacles", "Ef" ); +const idEventDef AI_GetObstacle( "getObstacle", NULL, 'e' ); +const idEventDef AI_PushPointIntoAAS( "pushPointIntoAAS", "v", 'v' ); +const idEventDef AI_GetTurnRate( "getTurnRate", NULL, 'f' ); +const idEventDef AI_SetTurnRate( "setTurnRate", "f" ); +const idEventDef AI_AnimTurn( "animTurn", "f" ); +const idEventDef AI_AllowHiddenMovement( "allowHiddenMovement", "d" ); +const idEventDef AI_TriggerParticles( "triggerParticles", "s" ); +const idEventDef AI_FindActorsInBounds( "findActorsInBounds", "vv", 'e' ); +const idEventDef AI_CanReachPosition( "canReachPosition", "v", 'd' ); +const idEventDef AI_CanReachEntity( "canReachEntity", "E", 'd' ); +const idEventDef AI_CanReachEnemy( "canReachEnemy", NULL, 'd' ); +const idEventDef AI_GetReachableEntityPosition( "getReachableEntityPosition", "e", 'v' ); +const idEventDef AI_ReEvaluateArea("reEvaluateArea", "d"); + +// TDM +const idEventDef AI_PlayAndLipSync( "playAndLipSync", "ss", 'd' ); + +const idEventDef AI_PushState("pushState", "s"); +const idEventDef AI_SwitchState("switchState", "s"); +const idEventDef AI_EndState("endState", NULL, 'd'); + +// DarkMod AI Relations Events +const idEventDef AI_GetRelationEnt( "getRelationEnt", "E", 'd' ); +const idEventDef AI_IsEnemy( "isEnemy", "E", 'd' ); +const idEventDef AI_IsFriend( "isFriend", "E", 'd' ); +const idEventDef AI_IsNeutral( "isNeutral", "E", 'd' ); + +// Alert events +const idEventDef AI_SetAlertLevel( "setAlertLevel", "f" ); +const idEventDef AI_Alert( "alert", "sf" ); +const idEventDef AI_VisScan( "visScan", NULL, 'e' ); +const idEventDef AI_GetSndDir( "getSndDir", NULL, 'v' ); +const idEventDef AI_GetVisDir( "getVisDir", NULL, 'v' ); +const idEventDef AI_GetTactEnt( "getTactEnt", NULL, 'e'); +const idEventDef AI_SetAcuity( "setAcuity", "sf" ); +const idEventDef AI_GetAcuity( "getAcuity", "s", 'f' ); +const idEventDef AI_GetAudThresh( "getAudThresh", NULL, 'f' ); +const idEventDef AI_SetAudThresh( "setAudThresh", "f" ); +const idEventDef AI_GetAlertActor( "getAlertActor", NULL, 'e' ); +const idEventDef AI_SetAlertGracePeriod( "setAlertGracePeriod", "fff" ); +const idEventDef AI_ClosestReachableEnemy( "closestReachableEnemy", NULL, 'e' ); +const idEventDef AI_FoundBody( "foundBody", "e" ); + +/*! +* A look at event that just looks at a position in space +* +* @param lookAtWorldPosition The position in space to look at +* +* @param durationInSeconds The duration to look in seconds +*/ +const idEventDef AI_LookAtPosition ("lookAtPosition", "vf"); + +/*! +* A look at event that just looks at a set of angles relative +* to the current body facing of the AI +* +* @param yawAngleClockwise Negative angles are to the left of the AIs body +* and positive angles are to the right. +* +* @param pitchAngleUp Negative values are down and positive values are up +* where down and up are defined by the body axis. +* +* @param rollAngle This is currently unused and does nothing +* +* @param durationInSeconds The duration to look in seconds +* +*/ +const idEventDef AI_LookAtAngles ("lookAtAngles", "ffff"); + + +/*! +* script callable: spawnThrowableProjectile +* +* @param projectileName The name of the projectile to spawn +* (as seen in a .def file) Must be descended from idProjectile +* +* @param pstr_attachJointName The name of the joint on the model +* to which the particle should be attached for throwing. If this +* is NULL or the empty string, then it is attached to the model center. +* +* @returns a pointer to a projectile entity that can be +* thrown by the AI. You can use AI_LaunchMissle (e* = launchMissle(v,v) ) +* to throw the stone. +* +*/ +const idEventDef AI_SpawnThrowableProjectile ("spawnThrowableProjectile", "ss", 'e'); + +// DarkMod Hiding spot detection Events +/*! +* This event finds hiding spots in the bounds given by two vectors. +* +* The first paramter is a vector which gives the location of the +* eye from which hiding is desired. +* +* The second vector gives the minimums in each dimension for the +* search space. +* +* The third and fourth vectors give the min and max bounds within which spots should be tested +* +* The fifth parameter gives the bit flags of the types of hiding spots +* for which the search should look. +* +* The sixth parameter indicates an entity that should be ignored in +* the visual occlusion checks. This is usually the searcher itself but +* can be NULL. +* +* This method will only start the search, if it returns 1, you should call +* continueSearchForHidingSpots every frame to do more processing until that function +* returns 0. +* +* The return value is a 0 for failure, 1 for success. +*/ +const idEventDef AI_StartSearchForHidingSpots ("startSearchForHidingSpots", "vvvdE", 'd'); + +// Documentation see idAI::StartSearchForHidingSpotsWithExclusionArea +const idEventDef AI_StartSearchForHidingSpotsWithExclusionArea ("startSearchForHidingSpotsWithExclusionArea", "vvvvvdE", 'd'); + +/* +* This method continues searching for hiding spots. It will only find so many before +* returning so as not to cause long delays. Detected spots are added to the currently +* building hiding spot list. +* +* The return value is 0 if the end of the search was reached, or 1 if there +* is more processing to do (call this method again next AI frame) +* +*/ +const idEventDef AI_ContinueSearchForHidingSpots ("continueSearchForHidingSpots", NULL, 'd'); + +/*! +* This should be called when the script is done with the hiding spot +* search to free up memory. +*/ +const idEventDef AI_CloseHidingSpotSearch ("closeHidingSpotSearch", ""); + +/*! +* This re-sorts an existing search based on a new search center and radius. +* +* @param newCenter The new center of the search +* +* @param newRadius The new radius of the search. Points outside the original +* search will not be added. +* +*/ +const idEventDef AI_ResortHidingSpotSearch ("resortHidingSpotSearch", "vv"); + +/*! +* This event returns the number of hiding spots by the current +* hiding spot query. If there is no current query, this returns -1 +*/ +const idEventDef AI_GetNumHidingSpots ("getNumHidingSpots", "", 'd'); + +/*! +* This event returns the Nth hiding spot location. +* Param is 0 based hiding spot index +*/ +const idEventDef AI_GetNthHidingSpotLocation ("getNthHidingSpotLocation", "d", 'v'); + +/*! +* This event returns the Nth hiding spot type. +* Param is 0 based hiding spot index +*/ +const idEventDef AI_GetNthHidingSpotType ("getNthHidingSpotType", "d", 'd'); + +/*! +* This event splits off half of the hiding spot list of another entity +* and sets our hiding spot list to the "taken" points. +* +* As such, it is useful for getting hiding spots from a seraching AI that this +* AI is trying to assist. +* +* @param p_otherEntity The other entity who's hiding spots we are taking +* +* @return The number of points in the list gotten +*/ +const idEventDef AI_GetSomeOfOtherEntitiesHidingSpotList ("getSomeOfOtherEntitiesHidingSpotList", "e", 'd'); + +/*! +* This event gets the alert number of another AI (AI_AlertLevel variable value) +* +* @param p_otherEntity The other AI entity who's alert number is being querried +* +* @return The alert number of the other AI, 0.0 if its not an AI or is NULL +*/ +const idEventDef AI_GetAlertLevelOfOtherAI ("getAlertLevelOfOtherAI", "e", 'f'); + +/*! +* This event is used to get a position that the AI can move to observe a +* given position. It is useful for looking at hiding spots that can't be reached, +* and performing other investigation functions. +*/ +const idEventDef AI_GetObservationPosition ("getObservationPosition", "vf", 'v'); + +/** +* These events handle a knockout of the AI (takes the attacker as argument) +**/ +const idEventDef AI_KO_Knockout( "KO_Knockout", "E" ); // grayman #2468 +const idEventDef AI_Gas_Knockout( "Gas_Knockout", "E" ); // grayman #2468 + +const idEventDef AI_GetNextIdleAnim( "getNextIdleAnim", NULL, 's' ); + +const idEventDef AI_HasSeenEvidence( "hasSeenEvidence", NULL, 'd' ); + +/* +* This is the AI event table class for a generic NPC actor. +* +*/ +CLASS_DECLARATION( idActor, idAI ) + EVENT( EV_PostSpawn, idAI::Event_PostSpawn ) + EVENT( EV_Activate, idAI::Event_Activate ) + EVENT( EV_Touch, idAI::Event_Touch ) + EVENT( AI_FindEnemy, idAI::Event_FindEnemy ) + EVENT( AI_FindEnemyAI, idAI::Event_FindEnemyAI ) + EVENT( AI_FindEnemyInCombatNodes, idAI::Event_FindEnemyInCombatNodes ) + EVENT( AI_ClosestReachableEnemyOfEntity, idAI::Event_ClosestReachableEnemyOfEntity ) + EVENT( AI_FindFriendlyAI, idAI::Event_FindFriendlyAI ) + EVENT( AI_ProcessBlindStim, idAI::Event_ProcessBlindStim ) + EVENT( AI_ProcessVisualStim, idAI::Event_ProcessVisualStim ) + EVENT( AI_SetEnemy, idAI::Event_SetEnemy ) + EVENT( AI_ClearEnemy, idAI::Event_ClearEnemy ) + EVENT( AI_MuzzleFlash, idAI::Event_MuzzleFlash ) + EVENT( AI_CreateMissile, idAI::Event_CreateMissile ) + EVENT( AI_CreateMissileFromDef, idAI::Event_CreateMissileFromDef ) + EVENT( AI_AttackMissile, idAI::Event_AttackMissile ) + EVENT( AI_FireMissileAtTarget, idAI::Event_FireMissileAtTarget ) + EVENT( AI_LaunchMissile, idAI::Event_LaunchMissile ) + EVENT( AI_AttackMelee, idAI::Event_AttackMelee ) + EVENT( AI_DirectDamage, idAI::Event_DirectDamage ) + EVENT( AI_RadiusDamageFromJoint, idAI::Event_RadiusDamageFromJoint ) + EVENT( AI_BeginAttack, idAI::Event_BeginAttack ) + EVENT( AI_EndAttack, idAI::Event_EndAttack ) + EVENT( AI_MeleeAttackToJoint, idAI::Event_MeleeAttackToJoint ) + EVENT( AI_RandomPath, idAI::Event_RandomPath ) + EVENT( AI_CanBecomeSolid, idAI::Event_CanBecomeSolid ) + EVENT( AI_BecomeSolid, idAI::Event_BecomeSolid ) + EVENT( EV_BecomeNonSolid, idAI::Event_BecomeNonSolid ) + EVENT( AI_BecomeRagdoll, idAI::Event_BecomeRagdoll ) + EVENT( AI_StopRagdoll, idAI::Event_StopRagdoll ) + EVENT( AI_AllowDamage, idAI::Event_AllowDamage ) + EVENT( AI_IgnoreDamage, idAI::Event_IgnoreDamage ) + EVENT( AI_GetCurrentYaw, idAI::Event_GetCurrentYaw ) + EVENT( AI_TurnTo, idAI::Event_TurnTo ) + EVENT( AI_TurnToPos, idAI::Event_TurnToPos ) + EVENT( AI_TurnToEntity, idAI::Event_TurnToEntity ) + EVENT( AI_MoveStatus, idAI::Event_MoveStatus ) + EVENT( AI_StopMove, idAI::Event_StopMove ) + EVENT( AI_MoveToCover, idAI::Event_MoveToCover ) + EVENT( AI_MoveToCoverFrom, idAI::Event_MoveToCoverFrom ) + EVENT( AI_MoveToEnemy, idAI::Event_MoveToEnemy ) + EVENT( AI_MoveToEnemyHeight, idAI::Event_MoveToEnemyHeight ) + EVENT( AI_MoveOutOfRange, idAI::Event_MoveOutOfRange ) + EVENT( AI_Flee, idAI::Event_Flee ) + EVENT( AI_MoveToAttackPosition, idAI::Event_MoveToAttackPosition ) + EVENT( AI_Wander, idAI::Event_Wander ) + EVENT( AI_MoveToEntity, idAI::Event_MoveToEntity ) + EVENT( AI_MoveToPosition, idAI::Event_MoveToPosition ) + EVENT( AI_SlideTo, idAI::Event_SlideTo ) + EVENT( AI_FacingIdeal, idAI::Event_FacingIdeal ) + EVENT( AI_FaceEnemy, idAI::Event_FaceEnemy ) + EVENT( AI_FaceEntity, idAI::Event_FaceEntity ) + EVENT( AI_WaitAction, idAI::Event_WaitAction ) + EVENT( AI_GetCombatNode, idAI::Event_GetCombatNode ) + EVENT( AI_EnemyInCombatCone, idAI::Event_EnemyInCombatCone ) + EVENT( AI_WaitMove, idAI::Event_WaitMove ) + EVENT( AI_GetJumpVelocity, idAI::Event_GetJumpVelocity ) + EVENT( AI_EntityInAttackCone, idAI::Event_EntityInAttackCone ) + EVENT( AI_CanSeeEntity, idAI::Event_CanSeeEntity ) + EVENT( AI_CanSeeEntityExt, idAI::Event_CanSeeEntityExt ) + EVENT( AI_CanSeePositionExt, idAI::Event_CanSeePositionExt ) + EVENT( AI_IsEntityHidden, idAI::Event_IsEntityHidden ) + EVENT( AI_SetTalkTarget, idAI::Event_SetTalkTarget ) + EVENT( AI_GetTalkTarget, idAI::Event_GetTalkTarget ) + EVENT( AI_SetTalkState, idAI::Event_SetTalkState ) + EVENT( AI_EnemyRange, idAI::Event_EnemyRange ) + EVENT( AI_EnemyRange2D, idAI::Event_EnemyRange2D ) + EVENT( AI_GetEnemy, idAI::Event_GetEnemy ) + EVENT( AI_GetEnemyPos, idAI::Event_GetEnemyPos ) + EVENT( AI_GetEnemyEyePos, idAI::Event_GetEnemyEyePos ) + EVENT( AI_PredictEnemyPos, idAI::Event_PredictEnemyPos ) + EVENT( AI_CanHitEnemy, idAI::Event_CanHitEnemy ) + EVENT( AI_CanHitEnemyFromAnim, idAI::Event_CanHitEnemyFromAnim ) + EVENT( AI_CanHitEnemyFromJoint, idAI::Event_CanHitEnemyFromJoint ) + EVENT( AI_EnemyPositionValid, idAI::Event_EnemyPositionValid ) + EVENT( AI_ChargeAttack, idAI::Event_ChargeAttack ) + EVENT( AI_TestChargeAttack, idAI::Event_TestChargeAttack ) + EVENT( AI_TestAnimMoveTowardEnemy, idAI::Event_TestAnimMoveTowardEnemy ) + EVENT( AI_TestAnimMove, idAI::Event_TestAnimMove ) + EVENT( AI_TestMoveToPosition, idAI::Event_TestMoveToPosition ) + EVENT( AI_TestMeleeAttack, idAI::Event_TestMeleeAttack ) + EVENT( AI_TestAnimAttack, idAI::Event_TestAnimAttack ) + EVENT( AI_Shrivel, idAI::Event_Shrivel ) + EVENT( AI_Burn, idAI::Event_Burn ) + EVENT( AI_PreBurn, idAI::Event_PreBurn ) + EVENT( AI_SetSmokeVisibility, idAI::Event_SetSmokeVisibility ) + EVENT( AI_NumSmokeEmitters, idAI::Event_NumSmokeEmitters ) + EVENT( AI_ClearBurn, idAI::Event_ClearBurn ) + EVENT( AI_StopThinking, idAI::Event_StopThinking ) + EVENT( AI_GetTurnDelta, idAI::Event_GetTurnDelta ) + EVENT( AI_GetMoveType, idAI::Event_GetMoveType ) + EVENT( AI_SetMoveType, idAI::Event_SetMoveType ) + EVENT( AI_SaveMove, idAI::Event_SaveMove ) + EVENT( AI_RestoreMove, idAI::Event_RestoreMove ) + EVENT( AI_AllowMovement, idAI::Event_AllowMovement ) + EVENT( AI_JumpFrame, idAI::Event_JumpFrame ) + EVENT( AI_EnableClip, idAI::Event_EnableClip ) + EVENT( AI_DisableClip, idAI::Event_DisableClip ) + EVENT( AI_EnableGravity, idAI::Event_EnableGravity ) + EVENT( AI_DisableGravity, idAI::Event_DisableGravity ) + EVENT( AI_EnableAFPush, idAI::Event_EnableAFPush ) + EVENT( AI_DisableAFPush, idAI::Event_DisableAFPush ) + EVENT( AI_SetFlySpeed, idAI::Event_SetFlySpeed ) + EVENT( AI_SetFlyOffset, idAI::Event_SetFlyOffset ) + EVENT( AI_ClearFlyOffset, idAI::Event_ClearFlyOffset ) + EVENT( AI_GetClosestHiddenTarget, idAI::Event_GetClosestHiddenTarget ) + EVENT( AI_GetRandomTarget, idAI::Event_GetRandomTarget ) + EVENT( AI_TravelDistanceToPoint, idAI::Event_TravelDistanceToPoint ) + EVENT( AI_TravelDistanceToEntity, idAI::Event_TravelDistanceToEntity ) + EVENT( AI_TravelDistanceBetweenPoints, idAI::Event_TravelDistanceBetweenPoints ) + EVENT( AI_TravelDistanceBetweenEntities, idAI::Event_TravelDistanceBetweenEntities ) + EVENT( AI_LookAtEntity, idAI::Event_LookAtEntity ) + EVENT( AI_LookAtEnemy, idAI::Event_LookAtEnemy ) + EVENT( AI_SetJointMod, idAI::Event_SetJointMod ) + EVENT( AI_ThrowMoveable, idAI::Event_ThrowMoveable ) + EVENT( AI_ThrowAF, idAI::Event_ThrowAF ) + EVENT( EV_GetAngles, idAI::Event_GetAngles ) + EVENT( EV_SetAngles, idAI::Event_SetAngles ) + EVENT( AI_RealKill, idAI::Event_RealKill ) + EVENT( AI_Kill, idAI::Event_Kill ) + EVENT( AI_WakeOnFlashlight, idAI::Event_WakeOnFlashlight ) + EVENT( AI_LocateEnemy, idAI::Event_LocateEnemy ) + EVENT( AI_KickObstacles, idAI::Event_KickObstacles ) + EVENT( AI_GetObstacle, idAI::Event_GetObstacle ) + EVENT( AI_PushPointIntoAAS, idAI::Event_PushPointIntoAAS ) + EVENT( AI_GetTurnRate, idAI::Event_GetTurnRate ) + EVENT( AI_SetTurnRate, idAI::Event_SetTurnRate ) + EVENT( AI_AnimTurn, idAI::Event_AnimTurn ) + EVENT( AI_AllowHiddenMovement, idAI::Event_AllowHiddenMovement ) + EVENT( AI_TriggerParticles, idAI::Event_TriggerParticles ) + EVENT( AI_FindActorsInBounds, idAI::Event_FindActorsInBounds ) + EVENT( AI_CanReachPosition, idAI::Event_CanReachPosition ) + EVENT( AI_CanReachEntity, idAI::Event_CanReachEntity ) + EVENT( AI_CanReachEnemy, idAI::Event_CanReachEnemy ) + EVENT( AI_GetReachableEntityPosition, idAI::Event_GetReachableEntityPosition ) + EVENT( AI_ReEvaluateArea, idAI::Event_ReEvaluateArea ) + + + // greebo: State manipulation interface + EVENT( AI_PushState, idAI::Event_PushState ) + EVENT( AI_SwitchState, idAI::Event_SwitchState ) + EVENT( AI_EndState, idAI::Event_EndState ) + + EVENT( AI_PlayAndLipSync, idAI::Event_PlayAndLipSync ) + EVENT( AI_GetRelationEnt, idAI::Event_GetRelationEnt ) + EVENT( AI_SetAlertLevel, idAI::Event_SetAlertLevel ) + EVENT( AI_Alert, idAI::Event_Alert ) + EVENT( AI_GetSndDir, idAI::Event_GetSndDir ) + EVENT( AI_GetVisDir, idAI::Event_GetVisDir ) + EVENT( AI_GetTactEnt, idAI::Event_GetTactEnt ) + EVENT( AI_SetAcuity, idAI::Event_SetAcuity ) + EVENT( AI_GetAcuity, idAI::Event_GetAcuity ) + EVENT( AI_GetAudThresh, idAI::Event_GetAudThresh ) + EVENT( AI_SetAudThresh, idAI::Event_SetAudThresh ) + EVENT( AI_VisScan, idAI::Event_VisScan ) + EVENT( AI_GetAlertActor, idAI::Event_GetAlertActor ) + EVENT( AI_SetAlertGracePeriod, idAI::Event_SetAlertGracePeriod ) + EVENT( AI_ClosestReachableEnemy, idAI::Event_ClosestReachableEnemy ) + EVENT( AI_FoundBody, idAI::Event_FoundBody ) + EVENT ( AI_StartSearchForHidingSpots, idAI::Event_StartSearchForHidingSpots ) + EVENT ( AI_StartSearchForHidingSpotsWithExclusionArea, idAI::Event_StartSearchForHidingSpotsWithExclusionArea ) + EVENT ( AI_ContinueSearchForHidingSpots, idAI::Event_ContinueSearchForHidingSpots ) + EVENT ( AI_CloseHidingSpotSearch, idAI::Event_CloseHidingSpotSearch ) + EVENT ( AI_ResortHidingSpotSearch, idAI::Event_ResortHidingSpots ) + EVENT ( AI_GetNumHidingSpots, idAI::Event_GetNumHidingSpots ) + EVENT ( AI_GetNthHidingSpotLocation, idAI::Event_GetNthHidingSpotLocation ) + EVENT ( AI_GetNthHidingSpotType, idAI::Event_GetNthHidingSpotType ) + EVENT ( AI_GetSomeOfOtherEntitiesHidingSpotList, idAI::Event_GetSomeOfOtherEntitiesHidingSpotList) + EVENT ( AI_GetObservationPosition, idAI::Event_GetObservationPosition) + EVENT ( AI_LookAtPosition, idAI::Event_LookAtPosition) + EVENT ( AI_LookAtAngles, idAI::Event_LookAtAngles) + EVENT ( AI_GetAlertLevelOfOtherAI, idAI::Event_GetAlertLevelOfOtherAI) + EVENT ( AI_KO_Knockout, idAI::Event_KO_Knockout) // grayman #2468 + EVENT ( AI_Gas_Knockout, idAI::Event_Gas_Knockout) // grayman #2468 + EVENT ( AI_SpawnThrowableProjectile, idAI::Event_SpawnThrowableProjectile) + EVENT ( AI_GetNextIdleAnim, idAI::Event_GetNextIdleAnim) + EVENT ( AI_HasSeenEvidence, idAI::Event_HasSeenEvidence) + + EVENT ( AI_PerformRelight, idAI::Event_PerformRelight) // grayman #2603 + EVENT ( AI_DropTorch, idAI::Event_DropTorch) // grayman #2603 + +END_CLASS + +void idAI::Event_PostSpawn() +{ + // Parse the list of doors that can be unlocked by this AI + for (const idKeyValue* kv = spawnArgs.MatchPrefix("can_unlock"); kv != NULL; kv = spawnArgs.MatchPrefix("can_unlock", kv)) + { + idEntity* door = gameLocal.FindEntity(kv->GetValue()); + if (door != NULL) + { + if (door->IsType(CBinaryFrobMover::Type)) + { + unlockableDoors.insert(static_cast(door)); + } + else + { + gameLocal.Warning("Invalid door name %s on AI %s", kv->GetValue().c_str(), name.c_str()); + } + } + } +} + +/* +===================== +idAI::Event_Activate +===================== +*/ +void idAI::Event_Activate( idEntity *activator ) { + Activate( activator ); +} + +/* +===================== +idAI::Event_Touch + +DarkMod: Modified to issue a tactile alert. + +Note: Event_Touch checks ReactionTo, which checks our DarkMod Relations +So it will only go off if the AI is bumped by an enemy that moves toward it. + +AI bumping by inanimate objects is handled separately in idMoveable::Collide. +===================== +*/ + +void idAI::Event_Touch( idEntity *other, trace_t *trace ) +{ + if ( !enemy.GetEntity() && !other->fl.notarget && ( ReactionTo( other ) & ATTACK_ON_ACTIVATE ) ) + { + Activate( other ); + } + AI_PUSHED = true; + + if( other && other->IsType(idActor::Type) ) + { + HadTactile( static_cast(other) ); + } +} + +/* +===================== +idAI::Event_FindEnemy +===================== +*/ +void idAI::Event_FindEnemy( int useFOV ) +{ + int i; + idEntity *ent; + idActor *actor; + + if ( gameLocal.InPlayerPVS( this ) ) { + for ( i = 0; i < gameLocal.numClients ; i++ ) { + ent = gameLocal.entities[ i ]; + + if ( !ent || !ent->IsType( idActor::Type ) ) { + continue; + } + + actor = static_cast( ent ); + + if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { + continue; + } + + if ( CanSee( actor, useFOV != 0 ) ) { + idThread::ReturnEntity( actor ); + return; + } + } + } + + idThread::ReturnEntity( NULL ); +} + +/* +===================== +idAI::Event_FindEnemyAI +===================== +*/ +void idAI::Event_FindEnemyAI( int useFOV ) { + idThread::ReturnEntity(FindEnemyAI(useFOV==1)); +} + +/* +===================== +idAI::Event_FindFriendlyAI +===================== +*/ +void idAI::Event_FindFriendlyAI(int requiredTeam) +{ + + idThread::ReturnEntity(FindFriendlyAI(requiredTeam)); +} + +/* +===================== +idAI::Event_FindEnemyInCombatNodes +===================== +*/ +void idAI::Event_FindEnemyInCombatNodes( void ) { + int i, j; + idCombatNode *node; + idEntity *ent; + idEntity *targetEnt; + idActor *actor; + + if ( !gameLocal.InPlayerPVS( this ) ) { + // don't locate the player when we're not in his PVS + idThread::ReturnEntity( NULL ); + return; + } + + for ( i = 0; i < gameLocal.numClients ; i++ ) { + ent = gameLocal.entities[ i ]; + + if ( !ent || !ent->IsType( idActor::Type ) ) { + continue; + } + + actor = static_cast( ent ); + if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { + continue; + } + + for( j = 0; j < targets.Num(); j++ ) { + targetEnt = targets[ j ].GetEntity(); + if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) { + continue; + } + + node = static_cast( targetEnt ); + if ( !node->IsDisabled() && node->EntityInView( actor, actor->GetPhysics()->GetOrigin() ) ) { + idThread::ReturnEntity( actor ); + return; + } + } + } + + idThread::ReturnEntity( NULL ); +} + +/* +===================== +idAI::Event_ClosestReachableEnemyOfEntity +===================== +*/ +void idAI::Event_ClosestReachableEnemyOfEntity( idEntity *team_mate ) { + idActor *actor; + idActor *ent; + idActor *bestEnt; + float bestDistSquared; + float distSquared; + idVec3 delta; + int areaNum; + int enemyAreaNum; + aasPath_t path; + + if ( !team_mate->IsType( idActor::Type ) ) { + gameLocal.Error( "Entity '%s' is not an AI character or player", team_mate->GetName() ); + } + + actor = static_cast( team_mate ); + + const idVec3 &origin = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( origin ); + + bestDistSquared = idMath::INFINITY; + bestEnt = NULL; + for( ent = actor->enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { + if ( ent->fl.hidden ) { + continue; + } + delta = ent->GetPhysics()->GetOrigin() - origin; + distSquared = delta.LengthSqr(); + if ( distSquared < bestDistSquared ) { + const idVec3 &enemyPos = ent->GetPhysics()->GetOrigin(); + enemyAreaNum = PointReachableAreaNum( enemyPos ); + if ( ( areaNum != 0 ) && PathToGoal( path, areaNum, origin, enemyAreaNum, enemyPos, this ) ) { + bestEnt = ent; + bestDistSquared = distSquared; + } + } + } + + idThread::ReturnEntity( bestEnt ); +} + +/* +===================== +idAI::Event_SetEnemy +===================== +*/ +void idAI::Event_SetEnemy( idEntity *ent ) { + if ( !ent ) { + ClearEnemy(); + } else if ( !ent->IsType( idActor::Type ) ) { + gameLocal.Error( "'%s' is not an idActor (player or ai controlled character)", ent->name.c_str() ); + } else { + SetEnemy( static_cast( ent ) ); + } +} + +/* +===================== +idAI::Event_ClearEnemy +===================== +*/ +void idAI::Event_ClearEnemy( void ) { + ClearEnemy(); +} + +/* +===================== +idAI::Event_MuzzleFlash +===================== +*/ +void idAI::Event_MuzzleFlash( const char *jointname ) +{ + idVec3 muzzle; + idMat3 axis; + + GetMuzzle( jointname, muzzle, axis ); + TriggerWeaponEffects( muzzle ); +} + +/* +===================== +idAI::Event_SpawnThrowableProjectile +===================== +*/ +void idAI::Event_SpawnThrowableProjectile(const char* projectileName, const char* jointName) +{ + // Remove the currently active projectile if necessary + RemoveProjectile(); + + // Load definition from movable.def + const idDict* projectileDef = gameLocal.FindEntityDefDict(projectileName); + + if (!projectileDef) + { + DM_LOG(LC_AI, LT_WARNING)LOGSTRING("Projectile with name '%s' was not found\r", projectileName); + idThread::ReturnEntity(NULL); + } + + // Create the projectile + idVec3 projectileDir = viewAxis[ 0 ] * physicsObj.GetGravityAxis(); + idVec3 projectileOrigin = physicsObj.GetOrigin(); + + // Spawn a new active projectile from the given dictionary (will throw gameLocal.Error on failure) + CreateProjectileFromDict(projectileOrigin, projectileDir, projectileDef); + + // Ensure that the clip model + EnsureActiveProjectileInfo(); + + // Bind to joint + if (jointName == NULL || jointName[0] == NULL) + { + // No valid joint name + activeProjectile.projEnt.GetEntity()->Bind(this, true); + } + else + { + activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointName, true); + } + + // Return to script thread + idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); +} + +/* +===================== +idAI::Event_CreateMissile +===================== +*/ +void idAI::Event_CreateMissile( const char *jointname ) +{ + if (projectileInfo.Num() == 0) + { + gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() ); + idThread::ReturnEntity( NULL ); + + return; + } + + idVec3 muzzle; + idMat3 axis; + GetMuzzle(jointname, muzzle, axis); + + // Create a new random projectile + CreateProjectile(muzzle, viewAxis[0] * physicsObj.GetGravityAxis()); + + if (activeProjectile.projEnt.GetEntity()) + { + if (!jointname || !jointname[ 0 ]) + { + activeProjectile.projEnt.GetEntity()->Bind(this, true); + } + else + { + activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointname, true); + } + } + + idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); +} + +void idAI::Event_CreateMissileFromDef(const char* defName, const char *jointname) +{ + // Remove any other projectile if we have one + RemoveProjectile(); + + // Load definition from movable.def + const idDict* projectileDef = gameLocal.FindEntityDefDict(defName); + + if (!projectileDef) + { + DM_LOG(LC_AI, LT_WARNING)LOGSTRING("Projectile with name '%s' was not found\r", defName); + idThread::ReturnEntity(NULL); + } + + idVec3 muzzle; + idMat3 axis; + GetMuzzle(jointname, muzzle, axis); + + // Create a new named projectile + CreateProjectileFromDict(muzzle, viewAxis[0] * physicsObj.GetGravityAxis(), projectileDef); + + if (activeProjectile.projEnt.GetEntity()) + { + if (!jointname || !jointname[ 0 ]) + { + activeProjectile.projEnt.GetEntity()->Bind(this, true); + } + else + { + activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointname, true); + } + } + + idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); +} + +/* +===================== +idAI::Event_AttackMissile +===================== +*/ +void idAI::Event_AttackMissile( const char *jointname ) { + idProjectile *proj; + + proj = LaunchProjectile( jointname, enemy.GetEntity(), true ); + idThread::ReturnEntity( proj ); +} + +/* +===================== +idAI::Event_FireMissileAtTarget +===================== +*/ +void idAI::Event_FireMissileAtTarget( const char *jointname, const char *targetname ) { + idEntity *aent; + idProjectile *proj; + + aent = gameLocal.FindEntity( targetname ); + if ( !aent ) { + gameLocal.Warning( "Entity '%s' not found for 'fireMissileAtTarget'", targetname ); + } + + proj = LaunchProjectile( jointname, aent, false ); + idThread::ReturnEntity( proj ); +} + +/* +===================== +idAI::Event_LaunchMissile +===================== +*/ +void idAI::Event_LaunchMissile(const idVec3& org, const idAngles& ang) +{ + if (projectileInfo.Num() == 0) + { + gameLocal.Warning("%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName()); + idThread::ReturnEntity(NULL); + return; + } + + idMat3 axis = ang.ToMat3(); + + // Ensure we have a projectile (does nothing if active projectile is non-NULL) + CreateProjectile(org, axis[0]); + + // make sure the projectile starts inside the monster bounding box + const idBounds &ownerBounds = physicsObj.GetAbsBounds(); + + const idClipModel* projClip = activeProjectile.projEnt.GetEntity()->GetPhysics()->GetClipModel(); + idBounds projBounds = projClip->GetBounds().Rotate(projClip->GetAxis()); + + idVec3 start; + float distance; + + // check if the owner bounds is bigger than the projectile bounds + if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && + ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && + ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) + { + if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) + { + start = org + distance * viewAxis[ 0 ]; + } + else + { + start = ownerBounds.GetCenter(); + } + } + else + { + // projectile bounds bigger than the owner bounds, so just start it from the center + start = ownerBounds.GetCenter(); + } + + trace_t tr; + gameLocal.clip.Translation( tr, start, org, projClip, projClip->GetAxis(), MASK_SHOT_RENDERMODEL, this ); + + // launch the projectile + idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); + + // greebo: Launch and free our projectile slot to get ready for the next round + activeProjectile.projEnt.GetEntity()->Launch( tr.endpos, axis[ 0 ], vec3_origin ); + activeProjectile.projEnt = NULL; + + TriggerWeaponEffects(tr.endpos); + + lastAttackTime = gameLocal.time; +} + +/* +===================== +idAI::Event_AttackMelee +===================== +*/ +void idAI::Event_AttackMelee( const char *meleeDefName ) { + bool hit; + + hit = AttackMelee( meleeDefName ); + idThread::ReturnInt( hit ); +} + +/* +===================== +idAI::Event_DirectDamage +===================== +*/ +void idAI::Event_DirectDamage( idEntity *damageTarget, const char *damageDefName ) { + DirectDamage( damageDefName, damageTarget ); +} + +/* +===================== +idAI::Event_RadiusDamageFromJoint +===================== +*/ +void idAI::Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName ) { + jointHandle_t joint; + idVec3 org; + idMat3 axis; + + if ( !jointname || !jointname[ 0 ] ) { + org = physicsObj.GetOrigin(); + } else { + joint = animator.GetJointHandle( jointname ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); + } + GetJointWorldTransform( joint, gameLocal.time, org, axis ); + } + + gameLocal.RadiusDamage( org, this, this, this, this, damageDefName ); +} + +/* +===================== +idAI::Event_RandomPath +===================== +*/ +void idAI::Event_RandomPath( void ) { + idPathCorner *path; + + path = idPathCorner::RandomPath( this, NULL, NULL ); + idThread::ReturnEntity( path ); +} + +/* +===================== +idAI::Event_BeginAttack +===================== +*/ +void idAI::Event_BeginAttack( const char *name ) { + BeginAttack( name ); +} + +/* +===================== +idAI::Event_EndAttack +===================== +*/ +void idAI::Event_EndAttack( void ) { + EndAttack(); +} + +/* +===================== +idAI::Event_MeleeAttackToJoint +===================== +*/ +void idAI::Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName ) { + jointHandle_t joint; + idVec3 start; + idVec3 end; + idMat3 axis; + trace_t trace; + idEntity *hitEnt; + + joint = animator.GetJointHandle( jointname ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); + } + animator.GetJointTransform( joint, gameLocal.time, end, axis ); + end = physicsObj.GetOrigin() + ( end + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); + start = GetEyePosition(); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorYellow, start, end, gameLocal.msec ); + } + + gameLocal.clip.TranslationEntities( trace, start, end, NULL, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); + if ( trace.fraction < 1.0f ) { + hitEnt = gameLocal.GetTraceEntity( trace ); + if ( hitEnt && hitEnt->IsType( idActor::Type ) ) { + DirectDamage( meleeDefName, hitEnt ); + idThread::ReturnInt( true ); + return; + } + } + + idThread::ReturnInt( false ); +} + +/* +===================== +idAI::Event_CanBecomeSolid +===================== +*/ +void idAI::Event_CanBecomeSolid( void ) { + idThread::ReturnFloat( CanBecomeSolid() ); +} + +/* +===================== +idAI::Event_BecomeSolid +===================== +*/ +void idAI::Event_BecomeSolid( void ) { + physicsObj.EnableClip(); + if ( spawnArgs.GetBool( "big_monster" ) ) { + physicsObj.SetContents( 0 ); + } else if ( use_combat_bbox ) { + physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); + } else { + physicsObj.SetContents( CONTENTS_BODY ); + } + + // SR CONTENTS_RESONSE FIX + if( m_StimResponseColl->HasResponse() ) + physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); + + physicsObj.GetClipModel()->Link( gameLocal.clip ); + fl.takedamage = !spawnArgs.GetBool( "noDamage" ); +} + +/* +===================== +idAI::Event_BecomeNonSolid +===================== +*/ +void idAI::Event_BecomeNonSolid( void ) { + fl.takedamage = false; + physicsObj.SetContents( 0 ); + physicsObj.GetClipModel()->Unlink(); +} + +/* +===================== +idAI::Event_BecomeRagdoll +===================== +*/ +void idAI::Event_BecomeRagdoll( void ) { + bool result; + + result = StartRagdoll(); + idThread::ReturnInt( result ); +} + +/* +===================== +idAI::Event_StopRagdoll +===================== +*/ +void idAI::Event_StopRagdoll( void ) { + StopRagdoll(); + + // set back the monster physics + SetPhysics( &physicsObj ); +} + +/* +===================== +idAI::Event_AllowDamage +===================== +*/ +void idAI::Event_AllowDamage( void ) { + fl.takedamage = true; +} + +/* +===================== +idAI::Event_IgnoreDamage +===================== +*/ +void idAI::Event_IgnoreDamage( void ) { + fl.takedamage = false; +} + +/* +===================== +idAI::Event_GetCurrentYaw +===================== +*/ +void idAI::Event_GetCurrentYaw( void ) { + idThread::ReturnFloat( current_yaw ); +} + +/* +===================== +idAI::Event_TurnTo +===================== +*/ +void idAI::Event_TurnTo( float angle ) { + TurnToward( angle ); +} + +/* +===================== +idAI::Event_TurnToPos +===================== +*/ +void idAI::Event_TurnToPos( const idVec3 &pos ) { + TurnToward( pos ); +} + +/* +===================== +idAI::Event_TurnToEntity +===================== +*/ +void idAI::Event_TurnToEntity( idEntity *ent ) { + if ( ent ) { + TurnToward( ent->GetPhysics()->GetOrigin() ); + } +} + +/* +===================== +idAI::Event_MoveStatus +===================== +*/ +void idAI::Event_MoveStatus( void ) { + idThread::ReturnInt( move.moveStatus ); +} + +/* +===================== +idAI::Event_StopMove +===================== +*/ +void idAI::Event_StopMove( void ) { + StopMove( MOVE_STATUS_DONE ); +} + +/* +===================== +idAI::Event_MoveToCover +===================== +*/ +void idAI::Event_MoveToCover( void ) { + idActor *enemyEnt = enemy.GetEntity(); + if (!enemyEnt) common->Printf("Warning: Entity is null\n"); + + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if ( !enemyEnt || !MoveToCover( enemyEnt, lastVisibleEnemyPos ) ) { + return; + } +} + +/* +===================== +idAI::Event_MoveToCoverFrom +===================== +*/ +void idAI::Event_MoveToCoverFrom( idEntity* enemyEnt ) { + if (!enemyEnt) enemyEnt = enemy.GetEntity(); + if (!enemyEnt) { common->Printf("Warning: Entity is null\n"); return; } + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + + // Hide from the eye position of the enemy, if the enemy is an actor; + // otherwise we have to make do with its origin plus an offset. + idVec3 hideFrom; + if (dynamic_cast (enemyEnt)) { + hideFrom = static_cast (enemyEnt)->GetEyePosition(); + } else { + hideFrom = enemyEnt->GetPhysics()->GetOrigin(); + hideFrom.z += 96.0f; // about 6 feet + } + + if (!MoveToCover( enemyEnt, hideFrom )) { + // failed + return; + } +} + +/* +===================== +idAI::Event_MoveToEnemy +===================== +*/ +void idAI::Event_MoveToEnemy( void ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if ( !enemy.GetEntity() || !MoveToEnemy() ) { + return; + } +} + +/* +===================== +idAI::Event_MoveToEnemyHeight +===================== +*/ +void idAI::Event_MoveToEnemyHeight( void ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + MoveToEnemyHeight(); +} + +/* +===================== +idAI::Event_MoveOutOfRange +===================== +*/ +void idAI::Event_MoveOutOfRange( idEntity *entity, float range ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + MoveOutOfRange( entity, range ); +} + +/* +===================== +idAI::Event_Flee +===================== +*/ +void idAI::Event_Flee(idEntity *entityToFleeFrom, int algorithm, int distanceOption) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); + idThread::ReturnInt(Flee(entityToFleeFrom, algorithm, distanceOption)); +} + +/* +===================== +idAI::Event_GetObservationPosition +by SophisticatedZobmie for The Dark Mod +This is an adaptation of the find attack position +query that is within MoveToAttackPosition +===================== +*/ +void idAI::Event_GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne) +{ + idVec3 observeFromPos = GetObservationPosition(pointToObserve, visualAcuityZeroToOne); + idThread::ReturnVector (observeFromPos); + return; +} + +/* +===================== +idAI::Event_MoveToAttackPosition +===================== +*/ +void idAI::Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim ) { + int anim; + + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + + anim = GetAnim( ANIMCHANNEL_LEGS, attack_anim ); + if ( !anim ) { + gameLocal.Error( "Unknown anim '%s'", attack_anim ); + } + + MoveToAttackPosition( entity, anim ); +} + +/* +===================== +idAI::Event_MoveToEntity +===================== +*/ +void idAI::Event_MoveToEntity( idEntity *ent ) { + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if ( ent ) { + MoveToEntity( ent ); + } +} + +/* +===================== +idAI::Event_MoveToPosition +===================== +*/ +void idAI::Event_MoveToPosition( const idVec3 &pos ) { + StopMove( MOVE_STATUS_DONE ); + MoveToPosition( pos ); +} + +/* +===================== +idAI::Event_SlideTo +===================== +*/ +void idAI::Event_SlideTo( const idVec3 &pos, float time ) { + SlideToPosition( pos, time ); +} +/* +===================== +idAI::Event_Wander +===================== +*/ +void idAI::Event_Wander( void ) { + WanderAround(); +} + +/* +===================== +idAI::Event_FacingIdeal +===================== +*/ +void idAI::Event_FacingIdeal( void ) { + bool facing = FacingIdeal(); + idThread::ReturnInt( facing ); +} + +/* +===================== +idAI::Event_FaceEnemy +===================== +*/ +void idAI::Event_FaceEnemy( void ) { + FaceEnemy(); +} + +/* +===================== +idAI::Event_FaceEntity +===================== +*/ +void idAI::Event_FaceEntity( idEntity *ent ) { + FaceEntity( ent ); +} + +/* +===================== +idAI::Event_WaitAction +===================== +*/ +void idAI::Event_WaitAction( const char *waitForState ) { + if ( idThread::BeginMultiFrameEvent( this, &AI_WaitAction ) ) { + SetWaitState( waitForState ); + } + + if ( !WaitState() ) { + idThread::EndMultiFrameEvent( this, &AI_WaitAction ); + } +} + +/* +===================== +idAI::Event_GetCombatNode +===================== +*/ +void idAI::Event_GetCombatNode( void ) { + int i; + float dist; + idEntity *targetEnt; + idCombatNode *node; + float bestDist; + idCombatNode *bestNode; + idActor *enemyEnt = enemy.GetEntity(); + + if ( !targets.Num() ) { + // no combat nodes + idThread::ReturnEntity( NULL ); + return; + } + + if ( !enemyEnt || !EnemyPositionValid() ) { + // don't return a combat node if we don't have an enemy or + // if we can see he's not in the last place we saw him + idThread::ReturnEntity( NULL ); + return; + } + + // find the closest attack node that can see our enemy and is closer than our enemy + bestNode = NULL; + const idVec3 &myPos = physicsObj.GetOrigin(); + bestDist = ( myPos - lastVisibleEnemyPos ).LengthSqr(); + for( i = 0; i < targets.Num(); i++ ) { + targetEnt = targets[ i ].GetEntity(); + if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) { + continue; + } + + node = static_cast( targetEnt ); + if ( !node->IsDisabled() && node->EntityInView( enemyEnt, lastVisibleEnemyPos ) ) { + idVec3 org = node->GetPhysics()->GetOrigin(); + dist = ( myPos - org ).LengthSqr(); + if ( dist < bestDist ) { + bestNode = node; + bestDist = dist; + } + } + } + + idThread::ReturnEntity( bestNode ); +} + +/* +===================== +idAI::Event_EnemyInCombatCone +===================== +*/ +void idAI::Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location ) { + idCombatNode *node; + bool result; + idActor *enemyEnt = enemy.GetEntity(); + + if ( !targets.Num() ) { + // no combat nodes + idThread::ReturnInt( false ); + return; + } + + if ( !enemyEnt ) { + // have to have an enemy + idThread::ReturnInt( false ); + return; + } + + if ( !ent || !ent->IsType( idCombatNode::Type ) ) { + // not a combat node + idThread::ReturnInt( false ); + return; + } + + node = static_cast( ent ); + if ( use_current_enemy_location ) { + const idVec3 &pos = enemyEnt->GetPhysics()->GetOrigin(); + result = node->EntityInView( enemyEnt, pos ); + } else { + result = node->EntityInView( enemyEnt, lastVisibleEnemyPos ); + } + + idThread::ReturnInt( result ); +} + +/* +===================== +idAI::Event_WaitMove +===================== +*/ +void idAI::Event_WaitMove( void ) { + idThread::BeginMultiFrameEvent( this, &AI_WaitMove ); + + if ( MoveDone() ) { + idThread::EndMultiFrameEvent( this, &AI_WaitMove ); + } +} + +/* +===================== +idAI::Event_GetJumpVelocity +===================== +*/ +void idAI::Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ) { + idVec3 start; + idVec3 end; + idVec3 dir; + float dist; + bool result; + idEntity *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt ) { + idThread::ReturnVector( vec3_zero ); + return; + } + + if ( speed <= 0.0f ) { + gameLocal.Error( "Invalid speed. speed must be > 0." ); + } + + start = physicsObj.GetOrigin(); + end = pos; + dir = end - start; + dist = dir.Normalize(); + if ( dist > 16.0f ) { + dist -= 16.0f; + end -= dir * 16.0f; + } + + result = PredictTrajectory( start, end, speed, physicsObj.GetGravity(), physicsObj.GetClipModel(), MASK_MONSTERSOLID, max_height, this, enemyEnt, ai_debugMove.GetBool() ? 4000 : 0, dir ); + if ( result ) { + idThread::ReturnVector( dir * speed ); + } else { + idThread::ReturnVector( vec3_zero ); + } +} + +/* +===================== +idAI::Event_EntityInAttackCone +===================== +*/ +void idAI::Event_EntityInAttackCone( idEntity *ent ) { + idThread::ReturnInt( EntityInAttackCone(ent) ); +} + +/* +===================== +idAI::Event_CanSeeEntity +===================== +*/ +void idAI::Event_CanSeeEntity( idEntity *ent ) { + if ( !ent ) { + idThread::ReturnInt( false ); + return; + } + + // Test if it is occluded, and use field of vision in the check (true as second parameter) + bool cansee = CanSee( ent, true ); + + idThread::ReturnInt( cansee ); +} + +/* +===================== +idAI::Event_CanSeeEntityExt +===================== +*/ +void idAI::Event_CanSeeEntityExt( idEntity *ent, const int bool_useFOV, const int bool_useLighting ) +{ + + if ( !ent ) + { + idThread::ReturnInt( false ); + return; + } + + // Test if it is visible + bool cansee = CanSeeExt( ent, (bool_useFOV != 0), (bool_useLighting != 0) ); + + // Return result + idThread::ReturnInt( cansee ); +} + +/* +===================== +idAI::Event_IsEntityHidden + +Tels: Returns true if the entity is in the FOV, not occluded and lit up according to the threshold. +===================== +*/ +void idAI::Event_IsEntityHidden( idEntity *ent, const float sightThreshold ) +{ + + if ( !ent ) + { + idThread::ReturnInt( false ); + return; + } + + // Test if it is occluded, and use field of vision in the check (true as second parameter) + bool cansee = idActor::CanSee( ent, true ); + + // Also consider lighting and visual acuity of AI + if (cansee) + { + cansee = !IsEntityHiddenByDarkness(ent, sightThreshold); + } + + // Return result + idThread::ReturnInt( cansee ); +} + +/* +===================== +idAI::Event_CanSeePositionExt +===================== +*/ +void idAI::Event_CanSeePositionExt( const idVec3& position, int bool_useFOV, int bool_useLighting ) +{ + bool cansee = CanSeePositionExt( position, (bool_useFOV != 0), (bool_useLighting != 0) ); + idThread::ReturnInt( cansee ); +} + + +/* +===================== +idAI::Event_SetTalkTarget +===================== +*/ +void idAI::Event_SetTalkTarget( idEntity *target ) { + if ( target && !target->IsType( idActor::Type ) ) { + gameLocal.Error( "Cannot set talk target to '%s'. Not a character or player.", target->GetName() ); + } + talkTarget = static_cast( target ); + if ( target ) { + AI_TALK = true; + } else { + AI_TALK = false; + } +} + +/* +===================== +idAI::Event_GetTalkTarget +===================== +*/ +void idAI::Event_GetTalkTarget( void ) { + idThread::ReturnEntity( talkTarget.GetEntity() ); +} + +/* +================ +idAI::Event_SetTalkState +================ +*/ +void idAI::Event_SetTalkState( int state ) { + if ( ( state < 0 ) || ( state >= NUM_TALK_STATES ) ) { + gameLocal.Error( "Invalid talk state (%d)", state ); + } + + talk_state = static_cast( state ); +} + +/* +===================== +idAI::Event_EnemyRange +===================== +*/ +void idAI::Event_EnemyRange( void ) { + float dist; + idActor *enemyEnt = enemy.GetEntity(); + + if ( enemyEnt ) { + dist = ( enemyEnt->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).Length(); + } else { + // Just some really high number + dist = idMath::INFINITY; + } + + idThread::ReturnFloat( dist ); +} + +/* +===================== +idAI::Event_EnemyRange2D +===================== +*/ +void idAI::Event_EnemyRange2D( void ) { + float dist; + idActor *enemyEnt = enemy.GetEntity(); + + if ( enemyEnt ) { + dist = ( enemyEnt->GetPhysics()->GetOrigin().ToVec2() - GetPhysics()->GetOrigin().ToVec2() ).Length(); + } else { + // Just some really high number + dist = idMath::INFINITY; + } + + idThread::ReturnFloat( dist ); +} + +/* +===================== +idAI::Event_GetEnemy +===================== +*/ +void idAI::Event_GetEnemy( void ) { + idThread::ReturnEntity( enemy.GetEntity() ); +} + +/* +===================== +idAI::Event_GetEnemyPos +===================== +*/ +void idAI::Event_GetEnemyPos( void ) { + idThread::ReturnVector( lastVisibleEnemyPos ); +} + +/* +===================== +idAI::Event_GetEnemyEyePos +===================== +*/ +void idAI::Event_GetEnemyEyePos( void ) { + idThread::ReturnVector( lastVisibleEnemyPos + lastVisibleEnemyEyeOffset ); +} + +/* +===================== +idAI::Event_PredictEnemyPos +===================== +*/ +void idAI::Event_PredictEnemyPos( float time ) { + predictedPath_t path; + idActor *enemyEnt = enemy.GetEntity(); + + // if no enemy set + if ( !enemyEnt ) { + idThread::ReturnVector( physicsObj.GetOrigin() ); + return; + } + + // predict the enemy movement + idAI::PredictPath( enemyEnt, aas, lastVisibleEnemyPos, enemyEnt->GetPhysics()->GetLinearVelocity(), SEC2MS( time ), SEC2MS( time ), ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + idThread::ReturnVector( path.endPos ); +} + +/* +===================== +idAI::Event_CanHitEnemy +===================== +*/ +void idAI::Event_CanHitEnemy( void ) { + trace_t tr; + idEntity *hit; + + idActor *enemyEnt = enemy.GetEntity(); + if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { + idThread::ReturnInt( false ); + return; + } + + // don't check twice per frame + if ( gameLocal.time == lastHitCheckTime ) { + idThread::ReturnInt( lastHitCheckResult ); + return; + } + + lastHitCheckTime = gameLocal.time; + + idVec3 toPos = enemyEnt->GetEyePosition(); + idVec3 eye = GetEyePosition(); + idVec3 dir; + + // expand the ray out as far as possible so we can detect anything behind the enemy + dir = toPos - eye; + dir.Normalize(); + toPos = eye + dir * MAX_WORLD_SIZE; + gameLocal.clip.TracePoint( tr, eye, toPos, MASK_SHOT_BOUNDINGBOX, this ); + hit = gameLocal.GetTraceEntity( tr ); + if ( tr.fraction >= 1.0f || ( hit == enemyEnt ) ) { + lastHitCheckResult = true; + } else if ( ( tr.fraction < 1.0f ) && ( hit->IsType( idAI::Type ) ) && + ( static_cast( hit )->team != team ) ) { + lastHitCheckResult = true; + } else { + lastHitCheckResult = false; + } + + idThread::ReturnInt( lastHitCheckResult ); +} + +/* +===================== +idAI::Event_CanHitEnemyFromAnim +===================== +*/ +void idAI::Event_CanHitEnemyFromAnim( const char *animname ) { + int anim; + idVec3 dir; + idVec3 local_dir; + idVec3 fromPos; + idMat3 axis; + idVec3 start; + trace_t tr; + float distance; + + idActor *enemyEnt = enemy.GetEntity(); + if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { + idThread::ReturnInt( false ); + return; + } + + anim = GetAnim( ANIMCHANNEL_LEGS, animname ); + if ( !anim ) { + idThread::ReturnInt( false ); + return; + } + + // just do a ray test if close enough + if ( enemyEnt->GetPhysics()->GetAbsBounds().IntersectsBounds( physicsObj.GetAbsBounds().Expand( 16.0f ) ) ) { + Event_CanHitEnemy(); + return; + } + + // calculate the world transform of the launch position + const idVec3 &org = physicsObj.GetOrigin(); + dir = lastVisibleEnemyPos - org; + physicsObj.GetGravityAxis().ProjectVector( dir, local_dir ); + local_dir.z = 0.0f; + local_dir.ToVec2().Normalize(); + axis = local_dir.ToMat3(); + fromPos = physicsObj.GetOrigin() + missileLaunchOffset[ anim ] * axis; + + // Ensure we have a valid clipmodel + ProjectileInfo& info = EnsureActiveProjectileInfo(); + + // check if the owner bounds is bigger than the projectile bounds + const idBounds& ownerBounds = physicsObj.GetAbsBounds(); + const idBounds& projBounds = info.clipModel->GetBounds(); + if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && + ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && + ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { + if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) { + start = org + distance * viewAxis[ 0 ]; + } else { + start = ownerBounds.GetCenter(); + } + } else { + // projectile bounds bigger than the owner bounds, so just start it from the center + start = ownerBounds.GetCenter(); + } + + gameLocal.clip.Translation( tr, start, fromPos, info.clipModel, mat3_identity, MASK_SHOT_RENDERMODEL, this ); + fromPos = tr.endpos; + + if ( GetAimDir( fromPos, enemy.GetEntity(), this, dir ) ) { + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/* +===================== +idAI::Event_CanHitEnemyFromJoint +===================== +*/ +void idAI::Event_CanHitEnemyFromJoint( const char *jointname ) { + trace_t tr; + idVec3 muzzle; + idMat3 axis; + idVec3 start; + float distance; + + idActor *enemyEnt = enemy.GetEntity(); + if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { + idThread::ReturnInt( false ); + return; + } + + // don't check twice per frame + if ( gameLocal.time == lastHitCheckTime ) { + idThread::ReturnInt( lastHitCheckResult ); + return; + } + + lastHitCheckTime = gameLocal.time; + + const idVec3 &org = physicsObj.GetOrigin(); + idVec3 toPos = enemyEnt->GetEyePosition(); + jointHandle_t joint = animator.GetJointHandle( jointname ); + if ( joint == INVALID_JOINT ) { + gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); + } + animator.GetJointTransform( joint, gameLocal.time, muzzle, axis ); + muzzle = org + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); + + // Ensure the current projectile clipmodel is valid + ProjectileInfo& curProjInfo = EnsureActiveProjectileInfo(); + + // check if the owner bounds is bigger than the projectile bounds + const idBounds &ownerBounds = physicsObj.GetAbsBounds(); + const idBounds &projBounds = curProjInfo.clipModel->GetBounds(); + if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && + ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && + ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { + if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) { + start = org + distance * viewAxis[ 0 ]; + } else { + start = ownerBounds.GetCenter(); + } + } else { + // projectile bounds bigger than the owner bounds, so just start it from the center + start = ownerBounds.GetCenter(); + } + + gameLocal.clip.Translation( tr, start, muzzle, curProjInfo.clipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); + muzzle = tr.endpos; + + gameLocal.clip.Translation( tr, muzzle, toPos, curProjInfo.clipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); + if ( tr.fraction >= 1.0f || ( gameLocal.GetTraceEntity( tr ) == enemyEnt ) ) { + lastHitCheckResult = true; + } else { + lastHitCheckResult = false; + } + + idThread::ReturnInt( lastHitCheckResult ); +} + +/* +===================== +idAI::Event_EnemyPositionValid +===================== +*/ +void idAI::Event_EnemyPositionValid( void ) { + bool result; + + result = EnemyPositionValid(); + idThread::ReturnInt( result ); +} + +/* +===================== +idAI::Event_ChargeAttack +===================== +*/ +void idAI::Event_ChargeAttack( const char *damageDef ) { + idActor *enemyEnt = enemy.GetEntity(); + + StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if ( enemyEnt ) { + idVec3 enemyOrg; + + if ( move.moveType == MOVETYPE_FLY ) { + // position destination so that we're in the enemy's view + enemyOrg = enemyEnt->GetEyePosition(); + enemyOrg -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset; + } else { + enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); + } + + BeginAttack( damageDef ); + DirectMoveToPosition( enemyOrg ); + TurnToward( enemyOrg ); + } +} + +/* +===================== +idAI::Event_TestChargeAttack +===================== +*/ +void idAI::Event_TestChargeAttack( void ) { + trace_t trace; + idActor *enemyEnt = enemy.GetEntity(); + predictedPath_t path; + idVec3 end; + + if ( !enemyEnt ) { + idThread::ReturnFloat( 0.0f ); + return; + } + + if ( move.moveType == MOVETYPE_FLY ) { + // position destination so that we're in the enemy's view + end = enemyEnt->GetEyePosition(); + end -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset; + } else { + end = enemyEnt->GetPhysics()->GetOrigin(); + } + + idAI::PredictPath( this, aas, physicsObj.GetOrigin(), end - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), end, gameLocal.msec ); + gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), end, gameLocal.msec ); + } + + if ( ( path.endEvent == 0 ) || ( path.blockingEntity == enemyEnt ) ) { + idVec3 delta = end - physicsObj.GetOrigin(); + float time = delta.LengthFast(); + idThread::ReturnFloat( time ); + } else { + idThread::ReturnFloat( 0.0f ); + } +} + +/* +===================== +idAI::Event_TestAnimMoveTowardEnemy +===================== +*/ +void idAI::Event_TestAnimMoveTowardEnemy( const char *animname ) { + int anim; + predictedPath_t path; + idVec3 moveVec; + float yaw; + idVec3 delta; + idActor *enemyEnt; + + enemyEnt = enemy.GetEntity(); + if ( !enemyEnt ) { + idThread::ReturnInt( false ); + return; + } + + anim = GetAnim( ANIMCHANNEL_LEGS, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); +#endif + + idThread::ReturnInt( false ); + return; + } + + delta = enemyEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin(); + yaw = delta.ToYaw(); + + moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis(); + idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); + gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); + } + + idThread::ReturnInt( path.endEvent == 0 ); +} + +/* +===================== +idAI::Event_TestAnimMove +===================== +*/ +void idAI::Event_TestAnimMove( const char *animname ) { + int anim; + predictedPath_t path; + idVec3 moveVec; + + anim = GetAnim( ANIMCHANNEL_LEGS, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); +#endif + + idThread::ReturnInt( false ); + return; + } + + moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, ideal_yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis(); + idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); + gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); + } + + idThread::ReturnInt( path.endEvent == 0 ); +} + +/* +===================== +idAI::Event_TestMoveToPosition +===================== +*/ +void idAI::Event_TestMoveToPosition( const idVec3 &position ) { + predictedPath_t path; + + idAI::PredictPath( this, aas, physicsObj.GetOrigin(), position - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), position, gameLocal.msec ); + gameRenderWorld->DebugBounds( colorYellow, physicsObj.GetBounds(), position, gameLocal.msec ); + if ( path.endEvent ) { + gameRenderWorld->DebugBounds( colorRed, physicsObj.GetBounds(), path.endPos, gameLocal.msec ); + } + } + + idThread::ReturnInt( path.endEvent == 0 ); +} + +/* +===================== +idAI::Event_TestMeleeAttack +===================== +*/ +void idAI::Event_TestMeleeAttack( void ) { + bool result = TestMelee(); + idThread::ReturnInt( result ); +} + +/* +===================== +idAI::Event_TestAnimAttack +===================== +*/ +void idAI::Event_TestAnimAttack( const char *animname ) { + int anim; + predictedPath_t path; + + anim = GetAnim( ANIMCHANNEL_LEGS, animname ); + if ( !anim ) { + +#ifndef SUPPRESS_CONSOLE_WARNINGS + gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); +#endif + + idThread::ReturnInt( false ); + return; + } + + idAI::PredictPath( this, aas, physicsObj.GetOrigin(), animator.TotalMovementDelta( anim ), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + + idThread::ReturnInt( path.blockingEntity && ( path.blockingEntity == enemy.GetEntity() ) ); +} + +/* +===================== +idAI::Event_Shrivel +===================== +*/ +void idAI::Event_Shrivel( float shrivel_time ) { + float t; + + if ( idThread::BeginMultiFrameEvent( this, &AI_Shrivel ) ) { + if ( shrivel_time <= 0.0f ) { + idThread::EndMultiFrameEvent( this, &AI_Shrivel ); + return; + } + + shrivel_rate = 0.001f / shrivel_time; + shrivel_start = gameLocal.time; + } + + t = ( gameLocal.time - shrivel_start ) * shrivel_rate; + if ( t > 0.25f ) { + renderEntity.noShadow = true; + } + if ( t > 1.0f ) { + t = 1.0f; + idThread::EndMultiFrameEvent( this, &AI_Shrivel ); + } + + renderEntity.shaderParms[ SHADERPARM_MD5_SKINSCALE ] = 1.0f - t * 0.5f; + UpdateVisuals(); +} + +/* +===================== +idAI::Event_PreBurn +===================== +*/ +void idAI::Event_PreBurn( void ) { + // for now this just turns shadows off + renderEntity.noShadow = true; +} + +/* +===================== +idAI::Event_Burn +===================== +*/ +void idAI::Event_Burn( void ) { + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; + SpawnParticles( "smoke_burnParticleSystem" ); + UpdateVisuals(); +} + +/* +===================== +idAI::Event_ClearBurn +===================== +*/ +void idAI::Event_ClearBurn( void ) { + renderEntity.noShadow = spawnArgs.GetBool( "noshadows" ); + renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = 0.0f; + UpdateVisuals(); +} + +/* +===================== +idAI::Event_SetSmokeVisibility +===================== +*/ +void idAI::Event_SetSmokeVisibility( int num, int on ) { + int i; + int time; + + if ( num >= particles.Num() ) { + gameLocal.Warning( "Particle #%d out of range (%d particles) on entity '%s'", num, particles.Num(), name.c_str() ); + return; + } + + if ( on != 0 ) { + time = gameLocal.time; + BecomeActive( TH_UPDATEPARTICLES ); + } else { + time = 0; + } + + if ( num >= 0 ) { + particles[ num ].time = time; + } else { + for ( i = 0; i < particles.Num(); i++ ) { + particles[ i ].time = time; + } + } + + UpdateVisuals(); +} + +/* +===================== +idAI::Event_NumSmokeEmitters +===================== +*/ +void idAI::Event_NumSmokeEmitters( void ) { + idThread::ReturnInt( particles.Num() ); +} + +/* +===================== +idAI::Event_StopThinking +===================== +*/ +void idAI::Event_StopThinking( void ) { + BecomeInactive( TH_THINK ); + idThread *thread = idThread::CurrentThread(); + if ( thread ) { + thread->DoneProcessing(); + } +} + +/* +===================== +idAI::Event_GetTurnDelta +===================== +*/ +void idAI::Event_GetTurnDelta( void ) { + float amount; + + if ( turnRate ) { + amount = idMath::AngleNormalize180( ideal_yaw - current_yaw ); + idThread::ReturnFloat( amount ); + } else { + idThread::ReturnFloat( 0.0f ); + } +} + +/* +===================== +idAI::Event_GetMoveType +===================== +*/ +void idAI::Event_GetMoveType( void ) { + idThread::ReturnInt( move.moveType ); +} + +/* +===================== +idAI::Event_SetMoveTypes +===================== +*/ +void idAI::Event_SetMoveType( int moveType ) { + SetMoveType(moveType); +} + +/* +===================== +idAI::Event_SaveMove +===================== +*/ +void idAI::Event_SaveMove( void ) { + savedMove = move; +} + +/* +===================== +idAI::Event_RestoreMove +===================== +*/ +void idAI::Event_RestoreMove( void ) { + // greebo: Call the local helper function with the previously stored as argument + RestoreMove(savedMove); +} + +/* +===================== +idAI::Event_AllowMovement +===================== +*/ +void idAI::Event_AllowMovement( float flag ) { + allowMove = ( flag != 0.0f ); +} + +/* +===================== +idAI::Event_JumpFrame +===================== +*/ +void idAI::Event_JumpFrame( void ) { + AI_JUMP = true; +} + +/* +===================== +idAI::Event_EnableClip +===================== +*/ +void idAI::Event_EnableClip( void ) { + physicsObj.SetClipMask( MASK_MONSTERSOLID ); + disableGravity = false; +} + +/* +===================== +idAI::Event_DisableClip +===================== +*/ +void idAI::Event_DisableClip( void ) { + physicsObj.SetClipMask( 0 ); + disableGravity = true; +} + +/* +===================== +idAI::Event_EnableGravity +===================== +*/ +void idAI::Event_EnableGravity( void ) { + disableGravity = false; +} + +/* +===================== +idAI::Event_DisableGravity +===================== +*/ +void idAI::Event_DisableGravity( void ) { + disableGravity = true; +} + +/* +===================== +idAI::Event_EnableAFPush +===================== +*/ +void idAI::Event_EnableAFPush( void ) { + m_bAFPushMoveables = true; +} + +/* +===================== +idAI::Event_DisableAFPush +===================== +*/ +void idAI::Event_DisableAFPush( void ) { + m_bAFPushMoveables = false; +} + +/* +===================== +idAI::Event_SetFlySpeed +===================== +*/ +void idAI::Event_SetFlySpeed( float speed ) { + if ( move.speed == fly_speed ) { + move.speed = speed; + } + fly_speed = speed; +} + +/* +================ +idAI::Event_SetFlyOffset +================ +*/ +void idAI::Event_SetFlyOffset( int offset ) { + fly_offset = offset; +} + +/* +================ +idAI::Event_ClearFlyOffset +================ +*/ +void idAI::Event_ClearFlyOffset( void ) { + spawnArgs.GetInt( "fly_offset", "0", fly_offset ); +} + +/* +===================== +idAI::Event_GetClosestHiddenTarget +===================== +*/ +void idAI::Event_GetClosestHiddenTarget( const char *type ) { + int i; + idEntity *ent; + idEntity *bestEnt; + float time; + float bestTime; + const idVec3 &org = physicsObj.GetOrigin(); + idActor *enemyEnt = enemy.GetEntity(); + + if ( !enemyEnt ) { + // no enemy to hide from + idThread::ReturnEntity( NULL ); + return; + } + + if ( targets.Num() == 1 ) { + ent = targets[ 0 ].GetEntity(); + if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { + if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, ent->GetPhysics()->GetOrigin() ) ) { + idThread::ReturnEntity( ent ); + return; + } + } + idThread::ReturnEntity( NULL ); + return; + } + + bestEnt = NULL; + bestTime = idMath::INFINITY; + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { + const idVec3 &destOrg = ent->GetPhysics()->GetOrigin(); + time = TravelDistance( org, destOrg ); + if ( ( time >= 0.0f ) && ( time < bestTime ) ) { + if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, destOrg ) ) { + bestEnt = ent; + bestTime = time; + } + } + } + } + idThread::ReturnEntity( bestEnt ); +} + +/* +===================== +idAI::Event_GetRandomTarget +===================== +*/ +void idAI::Event_GetRandomTarget( const char *type ) { + int i; + int num; + int which; + idEntity *ent; + idEntity *ents[ MAX_GENTITIES ]; + + num = 0; + for( i = 0; i < targets.Num(); i++ ) { + ent = targets[ i ].GetEntity(); + if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { + ents[ num++ ] = ent; + if ( num >= MAX_GENTITIES ) { + break; + } + } + } + + if ( !num ) { + idThread::ReturnEntity( NULL ); + return; + } + + which = gameLocal.random.RandomInt( num ); + idThread::ReturnEntity( ents[ which ] ); +} + +/* +================ +idAI::Event_TravelDistanceToPoint +================ +*/ +void idAI::Event_TravelDistanceToPoint( const idVec3 &pos ) { + float time; + + time = TravelDistance( physicsObj.GetOrigin(), pos ); + idThread::ReturnFloat( time ); +} + +/* +================ +idAI::Event_TravelDistanceToEntity +================ +*/ +void idAI::Event_TravelDistanceToEntity( idEntity *ent ) { + float time; + + time = TravelDistance( physicsObj.GetOrigin(), ent->GetPhysics()->GetOrigin() ); + idThread::ReturnFloat( time ); +} + +/* +================ +idAI::Event_TravelDistanceBetweenPoints +================ +*/ +void idAI::Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest ) { + float time; + + time = TravelDistance( source, dest ); + idThread::ReturnFloat( time ); +} + +/* +================ +idAI::Event_TravelDistanceBetweenEntities +================ +*/ +void idAI::Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest ) { + float time; + + assert( source ); + assert( dest ); + time = TravelDistance( source->GetPhysics()->GetOrigin(), dest->GetPhysics()->GetOrigin() ); + idThread::ReturnFloat( time ); +} + +/* +===================== +idAI::Event_LookAtPosition +===================== +*/ +void idAI::Event_LookAtPosition (const idVec3& lookAtWorldPosition, float duration) +{ + // angua: AI must not look at infinity + // this rips their upper body off and leads to really low frame rates + if (lookAtWorldPosition.x != idMath::INFINITY) + { + if ( ( focusEntity.GetEntity() != NULL ) || ( currentFocusPos != lookAtWorldPosition) || (gameLocal.time ) ) + { + focusEntity = NULL; + currentFocusPos = lookAtWorldPosition; + alignHeadTime = gameLocal.time; + forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); + blink_time = 0; + } + + focusTime = gameLocal.time + SEC2MS( duration ); + } +} + + +void idAI::Event_LookAtAngles (float yawAngleClockwise, float pitchAngleUp, float rollAngle, float durationInSeconds) +{ + // Get current physical angles + idAngles physicalAngles(0.0f, current_yaw, 0.0f); + + // Now rotate it by the given angles + idAngles lookAngles = idAngles(pitchAngleUp, yawAngleClockwise, rollAngle); + + lookAngles += physicalAngles; + lookAngles.Normalize180(); + + // Determine the look at world position + idVec3 lookAtPositionDelta = lookAngles.ToForward() * 15.0; + idVec3 lookAtWorldPosition = GetEyePosition() + lookAtPositionDelta; + + //gameRenderWorld->DebugArrow (idVec4(1.0,0.0,0.0,1.0), GetEyePosition(), lookAtWorldPosition, 1, 5000); + + // Update focus position + if ( ( focusEntity.GetEntity() != NULL ) || ( currentFocusPos != lookAtWorldPosition) || (gameLocal.time ) ) + { + focusEntity = NULL; + currentFocusPos = lookAtWorldPosition; + alignHeadTime = gameLocal.time; + forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); + blink_time = 0; + } + + focusTime = gameLocal.time + SEC2MS( durationInSeconds ); +} + +/* +===================== +idAI::Event_LookAtEntity +===================== +*/ +void idAI::Event_LookAtEntity( idEntity *ent, float duration ) { + if ( ent == this ) { + ent = NULL; + } + + if ( ( ent != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) { + focusEntity = ent; + alignHeadTime = gameLocal.time; + forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); + blink_time = 0; + } + + focusTime = gameLocal.time + SEC2MS( duration ); +} + +/* +===================== +idAI::Event_LookAtEnemy +===================== +*/ +void idAI::Event_LookAtEnemy( float duration ) { + idActor *enemyEnt; + + enemyEnt = enemy.GetEntity(); + if ( ( enemyEnt != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) { + focusEntity = enemyEnt; + alignHeadTime = gameLocal.time; + forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); + blink_time = 0; + } + + focusTime = gameLocal.time + SEC2MS( duration ); +} + +/* +=============== +idAI::Event_SetJointMod +=============== +*/ +void idAI::Event_SetJointMod( int allow ) { + allowJointMod = ( allow != 0 ); +} + +/* +================ +idAI::Event_ThrowMoveable +================ +*/ +void idAI::Event_ThrowMoveable( void ) { + idEntity *ent; + idEntity *moveable = NULL; + + for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) { + if ( ent->GetBindMaster() == this && ent->IsType( idMoveable::Type ) ) { + moveable = ent; + break; + } + } + if ( moveable ) { + moveable->Unbind(); + moveable->PostEventMS( &EV_SetOwner, 200, 0 ); + } +} + +/* +================ +idAI::Event_ThrowAF +================ +*/ +void idAI::Event_ThrowAF( void ) { + idEntity *ent; + idEntity *af = NULL; + + for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) { + if ( ent->GetBindMaster() == this && ent->IsType( idAFEntity_Base::Type ) ) { + af = ent; + break; + } + } + if ( af ) { + af->Unbind(); + af->PostEventMS( &EV_SetOwner, 200, 0 ); + } +} + +/* +================ +idAI::Event_SetAngles +================ +*/ +void idAI::Event_SetAngles( idAngles const &ang ) { + current_yaw = ang.yaw; + viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); +} + +/* +================ +idAI::Event_GetAngles +================ +*/ +void idAI::Event_GetAngles( void ) { + idThread::ReturnVector( idVec3( 0.0f, current_yaw, 0.0f ) ); +} + +/* +================ +idAI::Event_RealKill +================ +*/ +void idAI::Event_RealKill( void ) { + health = 0; + + if ( af.IsLoaded() ) { + // clear impacts + af.Rest(); + + // physics is turned off by calling af.Rest() + BecomeActive( TH_PHYSICS ); + } + + Killed( this, this, 0, vec3_zero, INVALID_JOINT ); +} + +/* +================ +idAI::Event_Kill +================ +*/ +void idAI::Event_Kill( void ) { + PostEventMS( &AI_RealKill, 0 ); +} + +/* +================ +idAI::Event_WakeOnFlashlight +================ +*/ +void idAI::Event_WakeOnFlashlight( int enable ) { + wakeOnFlashlight = ( enable != 0 ); +} + +/* +================ +idAI::Event_LocateEnemy +================ +*/ +void idAI::Event_LocateEnemy( void ) { + idActor *enemyEnt; + int areaNum; + + enemyEnt = enemy.GetEntity(); + if ( !enemyEnt ) { + return; + } + + enemyEnt->GetAASLocation( aas, lastReachableEnemyPos, areaNum ); + + // SZ: Why is this in here if we are unsure of where the enemy is. We have to update it first + // Update was already after SetEnemyPosition so I'm just commenting out SetEnemyPosition (which + // is called form in UpdateEnemyPosition if we can see them) + //SetEnemyPosition(); + UpdateEnemyPosition(); +} + +/* +================ +idAI::Event_KickObstacles +================ +*/ +void idAI::Event_KickObstacles( idEntity *kickEnt, float force ) { + idVec3 dir; + idEntity *obEnt; + + if ( kickEnt ) { + obEnt = kickEnt; + } else { + obEnt = move.obstacle.GetEntity(); + } + + if ( obEnt ) { + dir = obEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin(); + dir.Normalize(); + } else { + dir = viewAxis[ 0 ]; + } + KickObstacles( dir, force, obEnt ); +} + +/* +================ +idAI::Event_GetObstacle +================ +*/ +void idAI::Event_GetObstacle( void ) { + idThread::ReturnEntity( move.obstacle.GetEntity() ); +} + +/* +================ +idAI::Event_PushPointIntoAAS +================ +*/ +void idAI::Event_PushPointIntoAAS( const idVec3 &pos ) { + int areaNum; + idVec3 newPos; + + areaNum = PointReachableAreaNum( pos ); + if ( areaNum ) { + newPos = pos; + aas->PushPointIntoAreaNum( areaNum, newPos ); + idThread::ReturnVector( newPos ); + } else { + idThread::ReturnVector( pos ); + } +} + + +/* +================ +idAI::Event_GetTurnRate +================ +*/ +void idAI::Event_GetTurnRate( void ) { + idThread::ReturnFloat( turnRate ); +} + +/* +================ +idAI::Event_SetTurnRate +================ +*/ +void idAI::Event_SetTurnRate( float rate ) { + turnRate = rate; +} + +/* +================ +idAI::Event_AnimTurn +================ +*/ +void idAI::Event_AnimTurn( float angles ) { + turnVel = 0.0f; + anim_turn_angles = angles; + if ( angles ) { + anim_turn_yaw = current_yaw; + anim_turn_amount = idMath::Fabs( idMath::AngleNormalize180( current_yaw - ideal_yaw ) ); + if ( anim_turn_amount > anim_turn_angles ) { + anim_turn_amount = anim_turn_angles; + } + } else { + anim_turn_amount = 0.0f; + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f ); + animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, 0.0f ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f ); + animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, 0.0f ); + } +} + +/* +================ +idAI::Event_AllowHiddenMovement +================ +*/ +void idAI::Event_AllowHiddenMovement( int enable ) { + allowHiddenMovement = ( enable != 0 ); +} + +/* +================ +idAI::Event_TriggerParticles +================ +*/ +void idAI::Event_TriggerParticles( const char *jointName ) { + TriggerParticles( jointName ); +} + +/* +===================== +idAI::Event_FindActorsInBounds +===================== +*/ +void idAI::Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs ) { + idEntity * ent; + idEntity * entityList[ MAX_GENTITIES ]; + int numListedEntities; + int i; + + numListedEntities = gameLocal.clip.EntitiesTouchingBounds( idBounds( mins, maxs ), CONTENTS_BODY, entityList, MAX_GENTITIES ); + for( i = 0; i < numListedEntities; i++ ) { + ent = entityList[ i ]; + if ( ent != this && !ent->IsHidden() && ( ent->health > 0 ) && ent->IsType( idActor::Type ) ) { + idThread::ReturnEntity( ent ); + return; + } + } + + idThread::ReturnEntity( NULL ); +} + +/* +================ +idAI::Event_CanReachPosition +================ +*/ +void idAI::Event_CanReachPosition( const idVec3 &pos ) { + aasPath_t path; + int toAreaNum; + int areaNum; + + toAreaNum = PointReachableAreaNum( pos ); + areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); + if ( !toAreaNum || !PathToGoal( path, areaNum, physicsObj.GetOrigin(), toAreaNum, pos, this ) ) { + idThread::ReturnInt( false ); + } else { + idThread::ReturnInt( true ); + } +} + +/* +================ +idAI::Event_CanReachEntity +================ +*/ +void idAI::Event_CanReachEntity( idEntity *ent ) { + aasPath_t path; + int toAreaNum; + int areaNum; + idVec3 pos; + + if ( !ent ) { + idThread::ReturnInt( false ); + return; + } + + if ( move.moveType != MOVETYPE_FLY ) { + if ( !ent->GetFloorPos( 64.0f, pos ) ) { + idThread::ReturnInt( false ); + return; + } + if ( ent->IsType( idActor::Type ) && static_cast( ent )->OnLadder() ) { + idThread::ReturnInt( false ); + return; + } + } else { + pos = ent->GetPhysics()->GetOrigin(); + } + + toAreaNum = PointReachableAreaNum( pos ); + if ( !toAreaNum ) { + idThread::ReturnInt( false ); + return; + } + + const idVec3 &org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum( org ); + if ( !toAreaNum || !PathToGoal( path, areaNum, org, toAreaNum, pos, this ) ) { + idThread::ReturnInt( false ); + } else { + idThread::ReturnInt( true ); + } +} + +/* +================ +idAI::Event_CanReachEnemy +================ +*/ +void idAI::Event_CanReachEnemy( void ) { + idThread::ReturnInt(CanReachEnemy()); +} + +/* +================ +idAI::Event_GetReachableEntityPosition +================ +*/ +void idAI::Event_GetReachableEntityPosition( idEntity *ent ) { + int toAreaNum; + idVec3 pos; + + if ( move.moveType != MOVETYPE_FLY ) + { + if ( !ent->GetFloorPos( 64.0f, pos ) ) + { + // NOTE: not a good way to return 'false' + idThread::ReturnVector( vec3_zero ); + return; + } + + if ( ent->IsType( idActor::Type ) && static_cast( ent )->OnLadder() ) + { + // NOTE: not a good way to return 'false' + idThread::ReturnVector( vec3_zero ); + return; + } + } + else + { + pos = ent->GetPhysics()->GetOrigin(); + } + + if ( aas ) + { + toAreaNum = PointReachableAreaNum( pos ); + aas->PushPointIntoAreaNum( toAreaNum, pos ); + } + + idThread::ReturnVector( pos ); +} + + +void idAI::Event_ReEvaluateArea(int areanum) +{ + ReEvaluateArea(areanum); +} + +/** +* DarkMod: Begin Team Relationship Events. See the definitions on CRelations +* for descriptions of the Relations functions that are called. +**/ + +void idAI::Event_GetRelationEnt( idEntity *ent ) +{ + idActor *actor; + + if ( !ent->IsType( idActor::Type ) ) + { + // inanimate objects are neutral to everyone + idThread::ReturnInt( 0 ); + } + + actor = static_cast( ent ); + idThread::ReturnInt( gameLocal.m_RelationsManager->GetRelNum( team, actor->team ) ); +} + +void idAI::Event_GetAcuity( const char *type ) +{ + idThread::ReturnFloat( GetAcuity( type ) ); +} + +void idAI::Event_SetAcuity( const char *type, float val ) +{ + SetAcuity( type, val ); +} + +void idAI::Event_GetAudThresh( void ) +{ + idThread::ReturnFloat( m_AudThreshold ); +} + +void idAI::Event_SetAudThresh( float val ) +{ + m_AudThreshold = val; +} + +void idAI::Event_SetAlertLevel( float newAlertLevel) +{ + SetAlertLevel(newAlertLevel); +} + +void idAI::Event_Alert( const char *type, float amount ) +{ + AlertAI( type, amount ); +} + +void idAI::Event_GetSndDir( void ) +{ + idThread::ReturnVector( m_SoundDir ); +} + +void idAI::Event_GetVisDir( void ) +{ + idThread::ReturnVector( m_LastSight ); +} + +void idAI::Event_GetTactEnt( void ) +{ + idEntity *ent = GetTactEnt(); + + if(!ent) + idThread::ReturnEntity( NULL ); + else + idThread::ReturnEntity( ent ); +} + + +void idAI::Event_VisScan( void ) +{ + // assume we are checking over one frame + float time(1.0f/60.0f); + + PerformVisualScan(time); + + idThread::ReturnEntity(GetEnemy()); +} + +void idAI::Event_ClosestReachableEnemy( void ) +{ + Event_ClosestReachableEnemyOfEntity( static_cast(this) ); +} + +//----------------------------------------------------------------------------------------------------- + +void idAI::destroyCurrentHidingSpotSearch() +{ + // Check to see if there is one + if (m_HidingSpotSearchHandle != NULL_HIDING_SPOT_SEARCH_HANDLE) + { + // Dereference current search + CHidingSpotSearchCollection::Instance().dereference(m_HidingSpotSearchHandle); + m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Hiding spot search dereferenced\r"); + } + + // No hiding spots + m_hidingSpots.clear(); + + // greebo: Clear the initial alert position + if (mind != NULL) + { + mind->GetMemory().alertSearchCenter = idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); + } +} + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_StartSearchForHidingSpots +( + const idVec3& hideFromLocation, + const idVec3& minBounds, + const idVec3& maxBounds, + int hidingSpotTypesAllowed, + idEntity* p_ignoreEntity +) +{ + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Event_StartSearchForHidingSpots called.\r"); + + // Destroy any current search + destroyCurrentHidingSpotSearch(); + + // Make caller's search bounds + idBounds searchBounds (minBounds, maxBounds); + idBounds searchExclusionBounds; + searchExclusionBounds.Clear(); // no exclusion bounds + + // greebo: Remember the initial alert position + GetMemory().alertSearchCenter = hideFromLocation; + + // SZ: Must use same AAS that LAS used during setup + + // Get aas + if (aas != NULL) + { + // Allocate object that handles the search + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Making finder\r"); + bool b_searchCompleted = false; + m_HidingSpotSearchHandle = CHidingSpotSearchCollection::Instance().getOrCreateSearch + ( + hideFromLocation, + aas, + HIDING_OBJECT_HEIGHT, + searchBounds, + searchExclusionBounds, + hidingSpotTypesAllowed, + p_ignoreEntity, + gameLocal.framenum, + b_searchCompleted + ); + + // Wait at least one frame for other AIs to indicate they want to share + // this search. Return result indicating search is not done yet. + idThread::ReturnInt(1); + + } + else + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Cannot perform Event_StartSearchForHidingSpots if no AAS is set for the AI\r"); + + // Search is done since there is no search + idThread::ReturnInt(0); + } + + +} + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_StartSearchForHidingSpotsWithExclusionArea +( + const idVec3& hideFromLocation, + const idVec3& minBounds, + const idVec3& maxBounds, + const idVec3& exclusionMinBounds, + const idVec3& exclusionMaxBounds, + int hidingSpotTypesAllowed, + idEntity* p_ignoreEntity +) +{ + idThread::ReturnInt(StartSearchForHidingSpotsWithExclusionArea( + hideFromLocation, minBounds, maxBounds, exclusionMinBounds, + exclusionMaxBounds, hidingSpotTypesAllowed, p_ignoreEntity + )); +} + + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_ContinueSearchForHidingSpots() +{ + idThread::ReturnInt(ContinueSearchForHidingSpots()); +} + + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_CloseHidingSpotSearch () +{ + // Destroy current hiding spot search + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Closing hiding spot search\r"); + destroyCurrentHidingSpotSearch(); +} + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_ResortHidingSpots +( + const idVec3& searchCenter, + const idVec3& searchRadius +) +{ + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Resorting hiding spots for new search center\r"); + m_hidingSpots.sortForNewCenter + ( + searchCenter, + searchRadius.Length() + ); + +} + + +//----------------------------------------------------------------------------------------------------- + +void idAI::Event_GetNumHidingSpots () +{ + + + // Get the number of hiding spots + int numSpots = m_hidingSpots.getNumSpots(); + + // Return count + idThread::ReturnInt (numSpots); +} + +/*------------------------------------------------------------------------------*/ + +void idAI::Event_GetNthHidingSpotLocation (int hidingSpotIndex) +{ + idThread::ReturnVector(GetNthHidingSpotLocation(hidingSpotIndex)); +} + +/*------------------------------------------------------------------------------*/ + +void idAI::Event_GetNthHidingSpotType (int hidingSpotIndex) +{ + int outTypeFlags = 0; + + int numSpots = m_hidingSpots.getNumSpots(); + + // In bounds? + if ((hidingSpotIndex >= 0) && (hidingSpotIndex < numSpots)) + { + darkModHidingSpot* p_spot = m_hidingSpots.getNthSpot(hidingSpotIndex); + if (p_spot == NULL) + { + outTypeFlags = 0; + } + else + { + outTypeFlags = p_spot->hidingSpotTypes; + } + } + else + { + DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Index %d is out of bounds, there are %d hiding spots\r", hidingSpotIndex, numSpots); + } + + // Return the type + idThread::ReturnInt (outTypeFlags); +} + +//----------------------------------------------------------------------------------------- + +void idAI::Event_GetAlertLevelOfOtherAI (idEntity* p_otherEntity) +{ + // Test parameters + if (p_otherEntity == NULL) + { + idThread::ReturnFloat (0.0); + return; + } + + // The other entity must be an AI + idAI* p_otherAI = dynamic_cast(p_otherEntity); + if (p_otherAI == NULL) + { + // Not an AI + idThread::ReturnFloat (0.0); + return; + } + + // Return the other AI's alert num + idThread::ReturnFloat (p_otherAI->AI_AlertLevel); +} + +/*---------------------------------------------------------------------------------*/ + +void idAI::Event_GetSomeOfOtherEntitiesHidingSpotList (idEntity* p_ownerOfSearch) +{ + idThread::ReturnInt(GetSomeOfOtherEntitiesHidingSpotList(p_ownerOfSearch)); +} + +//-------------------------------------------------------------------------------- + +void idAI::Event_GetAlertActor( void ) +{ + idThread::ReturnEntity( m_AlertedByActor.GetEntity() ); +} + +//-------------------------------------------------------------------------------- + +void idAI::Event_SetAlertGracePeriod( float frac, float duration, int count ) +{ + // set the parameters + m_AlertGraceActor = m_AlertedByActor.GetEntity(); + m_AlertGraceStart = gameLocal.time; + m_AlertGraceTime = SEC2MS( duration ); + m_AlertGraceThresh = m_AlertLevelThisFrame * frac; + m_AlertGraceCountLimit = count; + m_AlertGraceCount = 0; +} + +void idAI::Event_FoundBody( idEntity *body ) +{ + FoundBody( body ); +} + +void idAI::Event_PushState(const char* state) +{ + mind->PushState(state); +} + +void idAI::Event_SwitchState(const char* state) +{ + mind->SwitchState(state); +} + +void idAI::Event_EndState() +{ + idThread::ReturnInt(static_cast(mind->EndState())); +} + +void idAI::Event_ProcessBlindStim(idEntity* stimSource, int skipVisibilityCheck) +{ + mind->GetState()->OnBlindStim(stimSource, skipVisibilityCheck != 0); +} + +void idAI::Event_ProcessVisualStim(idEntity* stimSource) +{ + mind->GetState()->OnVisualStim(stimSource); +} + +void idAI::Event_GetNextIdleAnim() +{ + idThread::ReturnString(GetNextIdleAnim()); +} + +void idAI::Event_HasSeenEvidence() +{ + idThread::ReturnInt(HasSeenEvidence()); +} + +void idAI::Event_PerformRelight() // grayman #2603 +{ + m_performRelight = true; +} + +void idAI::Event_DropTorch() // grayman #2603 +{ + for (int i = 0 ; i < m_Attachments.Num() ; i++) + { + idEntity* ent = m_Attachments[i].ent.GetEntity(); + if( !ent || !m_Attachments[i].ent.IsValid() ) + { + continue; + } + + if (ent->spawnArgs.GetBool("is_torch","0")) + { + DetachInd(i); + + // drop the torch a bit to get away from the AI's hand + + idVec3 origin = ent->GetPhysics()->GetOrigin(); + origin.z -= 20; + ent->GetPhysics()->SetOrigin( origin ); + + ent->m_droppedByAI = true; // grayman #1330 + GetMemory().stopRelight = true; // in case a relight was in progress - try again later w/o torch + GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope + m_DroppingTorch = false; + break; + } + } +} + + + diff --git a/game/ai/AI_pathing.cpp b/game/ai/AI_pathing.cpp new file mode 100644 index 000000000..855663c07 --- /dev/null +++ b/game/ai/AI_pathing.cpp @@ -0,0 +1,1917 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#include "../BinaryFrobMover.h" +#include "../FrobDoor.h" +#include "../TimerManager.h" +#include "../ai/Memory.h" + +/* +=============================================================================== + + Dynamic Obstacle Avoidance + + - assumes the AI lives inside a bounding box aligned with the gravity direction + - obstacles in proximity of the AI are gathered + - if obstacles are found the AAS walls are also considered as obstacles + - every obstacle is represented by an oriented bounding box (OBB) + - an OBB is projected onto a 2D plane orthogonal to AI's gravity direction + - the 2D windings of the projections are expanded for the AI bbox + - a path tree is build using clockwise and counter clockwise edge walks along the winding edges + - the path tree is pruned and optimized + - the shortest path is chosen for navigation + +=============================================================================== +*/ + +const float MAX_OBSTACLE_RADIUS = 128.0f; +const float OBSTACLE_HEIGHT_EXPANSION = 10.0f; +const float PUSH_OUTSIDE_OBSTACLES = 0.5f; +const float CLIP_BOUNDS_EPSILON = 10.0f; +const int MAX_AAS_WALL_EDGES = 256; +const int MAX_OBSTACLES = 256; +const int MAX_PATH_NODES = 256; +const int MAX_OBSTACLE_PATH = 64; +const int REUSE_DOOR_DELAY = 3000; // grayman #2345 - wait before using a door again. #2706 - lower from 8s to 1s to reduce circling + +typedef struct obstacle_s { + idVec2 bounds[2]; + idWinding2D winding; + idEntity * entity; +} obstacle_t; + +typedef struct pathNode_s { + int dir; + idVec2 pos; + idVec2 delta; + float dist; + int obstacle; + int edgeNum; + int numNodes; + struct pathNode_s * parent; + struct pathNode_s * children[2]; + struct pathNode_s * next; + void Init(); +} pathNode_t; + +void pathNode_s::Init() { + dir = 0; + pos.Zero(); + delta.Zero(); + obstacle = -1; + edgeNum = -1; + numNodes = 0; + parent = children[0] = children[1] = next = NULL; +} + +idBlockAlloc pathNodeAllocator; + +#if 0 +// grayman - for debugging path tree nodes +void PrintNode(pathNode_t* node,int level,obstacle_t obstacles[]) +{ + idStr pad = ""; + for (int i = 0 ; i < level ; i++) + { + pad += " "; + } + + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s ------ node -----\r",pad.c_str()); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s dir = %d (0 = left & 1 = right?)\r",pad.c_str(),node->dir); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s pos = [%s] (parent's pos + parent's delta)\r",pad.c_str(),node->pos.ToString()); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s delta = [%s] (?)\r",pad.c_str(),node->delta.ToString()); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s dist = %f (distance to seekPos)\r",pad.c_str(),sqrt(node->dist)); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = %d (blocking obstacle index)\r",pad.c_str(),node->obstacle); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s edgeNum = %d (blocking edge num)\r",pad.c_str(),node->edgeNum); + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s numNodes = %d (num nodes down from root)\r",pad.c_str(),node->numNodes); + + if (node->obstacle != -1) + { + idEntity *e = obstacles[node->obstacle].entity; + if (e) + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = %s\r",pad.c_str(),e->name.c_str()); + } + else + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = NULL\r",pad.c_str()); + } + } + else + { + DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle index = -1\r",pad.c_str()); + } +} + +void PrintNodes(pathNode_t* node,int level,obstacle_t obstacles[]) +{ + PrintNode(node,level,obstacles); + if (node->children[0]) + { + PrintNodes(node->children[0],level+1,obstacles); + } + if (node->children[1]) + { + PrintNodes(node->children[1],level+1,obstacles); + } +} +#endif + +/* +============ +LineIntersectsPath +============ +*/ +bool LineIntersectsPath( const idVec2 &start, const idVec2 &end, const pathNode_t *node ) { + float d0, d1, d2, d3; + idVec3 plane1, plane2; + + plane1 = idWinding2D::Plane2DFromPoints( start, end ); + d0 = plane1.x * node->pos.x + plane1.y * node->pos.y + plane1.z; + while( node->parent ) { + d1 = plane1.x * node->parent->pos.x + plane1.y * node->parent->pos.y + plane1.z; + if ( FLOATSIGNBITSET( d0 ) ^ FLOATSIGNBITSET( d1 ) ) { + plane2 = idWinding2D::Plane2DFromPoints( node->pos, node->parent->pos ); + d2 = plane2.x * start.x + plane2.y * start.y + plane2.z; + d3 = plane2.x * end.x + plane2.y * end.y + plane2.z; + if ( FLOATSIGNBITSET( d2 ) ^ FLOATSIGNBITSET( d3 ) ) { + return true; + } + } + d0 = d1; + node = node->parent; + } + return false; +} + +/* +============ +PointInsideObstacle +============ +*/ +int PointInsideObstacle( const obstacle_t *obstacles, const int numObstacles, const idVec2 &point ) { + int i; + + for ( i = 0; i < numObstacles; i++ ) { + + const idVec2 *bounds = obstacles[i].bounds; + if ( point.x < bounds[0].x || point.y < bounds[0].y || point.x > bounds[1].x || point.y > bounds[1].y ) { + continue; + } + + if ( !obstacles[i].winding.PointInside( point, 0.1f ) ) { + continue; + } + + return i; + } + + return -1; +} + +/* +============ +GetPointOutsideObstacles +============ +*/ +void GetPointOutsideObstacles( const obstacle_t *obstacles, const int numObstacles, idVec2 &point, int *obstacle, int *edgeNum ) { + int i, j, k, n, bestObstacle, bestEdgeNum, queueStart, queueEnd, edgeNums[2]; + float d, bestd, scale[2]; + idVec3 plane, bestPlane; + idVec2 newPoint, dir, bestPoint(0, 0); + int *queue; + bool *obstacleVisited; + idWinding2D w1, w2; + + if ( obstacle ) { + *obstacle = -1; + } + if ( edgeNum ) { + *edgeNum = -1; + } + + bestObstacle = PointInsideObstacle( obstacles, numObstacles, point ); + if ( bestObstacle == -1 ) { + return; + } + + const idWinding2D &w = obstacles[bestObstacle].winding; + bestd = idMath::INFINITY; + bestEdgeNum = 0; + for ( i = 0; i < w.GetNumPoints(); i++ ) { + plane = idWinding2D::Plane2DFromPoints( w[(i+1)%w.GetNumPoints()], w[i], true ); + d = plane.x * point.x + plane.y * point.y + plane.z; + if ( d < bestd ) { + bestd = d; + bestPlane = plane; + bestEdgeNum = i; + } + // if this is a wall always try to pop out at the first edge + if ( obstacles[bestObstacle].entity == NULL ) { + break; + } + } + + newPoint = point - ( bestd + PUSH_OUTSIDE_OBSTACLES ) * bestPlane.ToVec2(); + if ( PointInsideObstacle( obstacles, numObstacles, newPoint ) == -1 ) { + point = newPoint; + if ( obstacle ) { + *obstacle = bestObstacle; + } + if ( edgeNum ) { + *edgeNum = bestEdgeNum; + } + return; + } + + queue = (int *) _alloca( numObstacles * sizeof( queue[0] ) ); + obstacleVisited = (bool *) _alloca( numObstacles * sizeof( obstacleVisited[0] ) ); + + queueStart = 0; + queueEnd = 1; + queue[0] = bestObstacle; + + memset( obstacleVisited, 0, numObstacles * sizeof( obstacleVisited[0] ) ); + obstacleVisited[bestObstacle] = true; + + bestd = idMath::INFINITY; + for ( i = queue[0]; queueStart < queueEnd; i = queue[++queueStart] ) { + w1 = obstacles[i].winding; + w1.Expand( PUSH_OUTSIDE_OBSTACLES ); + + for ( j = 0; j < numObstacles; j++ ) { + // if the obstacle has been visited already + if ( obstacleVisited[j] ) { + continue; + } + // if the bounds do not intersect + if ( obstacles[j].bounds[0].x > obstacles[i].bounds[1].x || obstacles[j].bounds[0].y > obstacles[i].bounds[1].y || + obstacles[j].bounds[1].x < obstacles[i].bounds[0].x || obstacles[j].bounds[1].y < obstacles[i].bounds[0].y ) { + continue; + } + + queue[queueEnd++] = j; + obstacleVisited[j] = true; + + w2 = obstacles[j].winding; + w2.Expand( 0.2f ); + + for ( k = 0; k < w1.GetNumPoints(); k++ ) { + dir = w1[(k+1)%w1.GetNumPoints()] - w1[k]; + if ( !w2.RayIntersection( w1[k], dir, scale[0], scale[1], edgeNums ) ) { + continue; + } + for ( n = 0; n < 2; n++ ) { + newPoint = w1[k] + scale[n] * dir; + if ( PointInsideObstacle( obstacles, numObstacles, newPoint ) == -1 ) { + d = ( newPoint - point ).LengthSqr(); + if ( d < bestd ) { + bestd = d; + bestPoint = newPoint; + bestEdgeNum = edgeNums[n]; + bestObstacle = j; + } + } + } + } + } + + if ( bestd < idMath::INFINITY ) { + point = bestPoint; + if ( obstacle ) { + *obstacle = bestObstacle; + } + if ( edgeNum ) { + *edgeNum = bestEdgeNum; + } + return; + } + } + gameLocal.Warning( "GetPointOutsideObstacles: no valid point found" ); +} + +/* +============ +GetFirstBlockingObstacle +============ +*/ +bool GetFirstBlockingObstacle(const idPhysics *physics, const obstacle_t *obstacles, int numObstacles, int skipObstacle, const idVec2 &startPos, const idVec2 &delta, float &blockingScale, int &blockingObstacle, int &blockingEdgeNum, int &blockingDoorNum ) { // grayman #2345 + int i, edgeNums[2]; + float dist, scale1, scale2; + idVec2 bounds[2]; + + // grayman #2345 - get AI version of yourself + + idActor* self = static_cast(const_cast(physics)->GetSelf()); + idAI* selfAI = static_cast(self); + + // get bounds for the current movement delta + bounds[0] = startPos - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + bounds[1] = startPos + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + bounds[FLOATSIGNBITNOTSET(delta.x)].x += delta.x; + bounds[FLOATSIGNBITNOTSET(delta.y)].y += delta.y; + + // test for obstacles blocking the path + blockingScale = idMath::INFINITY; + float blockingScaleDoor = idMath::INFINITY; // grayman #2345 + dist = delta.Length(); + for ( i = 0; i < numObstacles; i++ ) { + if ( i == skipObstacle ) { + continue; + } + + if ( bounds[0].x > obstacles[i].bounds[1].x || bounds[0].y > obstacles[i].bounds[1].y || + bounds[1].x < obstacles[i].bounds[0].x || bounds[1].y < obstacles[i].bounds[0].y ) + { + continue; + } + if ( obstacles[i].winding.RayIntersection( startPos, delta, scale1, scale2, edgeNums ) ) + { + if ( scale1 < blockingScale && scale1 * dist > -0.01f && scale2 * dist > 0.01f ) + { + blockingScale = scale1; + blockingObstacle = i; + blockingEdgeNum = edgeNums[0]; + + // grayman #2345 - Return the index number of the closest blocking door, + // regardless of whether the door is the closest blocking obstacle. Ignore + // a door that you recently used if not alerted. This keeps you from going back and forth + // through the same door. + + // grayman #2712 - removed alert check + + idEntity* e = obstacles[i].entity; + if ((e != NULL) && e->IsType(CFrobDoor::Type)) + { + if (blockingScale < blockingScaleDoor) + { + CFrobDoor *frobDoor = static_cast(e); + int lastTimeUsed = selfAI->GetMemory().GetDoorInfo(frobDoor).lastTimeUsed; + if ((lastTimeUsed > -1) && (gameLocal.time < lastTimeUsed + REUSE_DOOR_DELAY)) + { + continue; // ignore this door + } + blockingDoorNum = i; + blockingScaleDoor = blockingScale; + } + } + } + } + } + return ( blockingScale < 1.0f ); +} + +/* +============ +GetObstacles +============ +*/ +int GetObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, int areaNum, + const idVec3 &startPos, const idVec3 &seekPos, obstacle_t *obstacles, int maxObstacles, + idBounds &clipBounds, obstaclePath_t& pathInfo ) +{ + int clipMask; + float stepHeight, headHeight, min, max; + idVec3 silVerts[32]; + idVec2 obDelta; + + /** TDM: SZ: This variable tracks if the obstacle is a binary mover or not + * If NULL its not, if non NULL it is, and the pointer is a cast to it + * as a binary mover + */ + // So far, we don't have a door + pathInfo.doorObstacle = NULL; + + // TDM: Store our team. const_cast<> is necessary due to GetSelf() not being const + idActor* self = static_cast(const_cast(physics)->GetSelf()); + //int team = self->team; + + idVec3 seekDelta = seekPos - startPos; + idVec2 expBounds[2]; + expBounds[0] = physics->GetBounds()[0].ToVec2() - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + expBounds[1] = physics->GetBounds()[1].ToVec2() + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + + physics->GetAbsBounds().AxisProjection( -physics->GetGravityNormal(), stepHeight, headHeight ); + stepHeight += aas->GetSettings()->maxStepHeight; + + // clip bounds for the obstacle search space + clipBounds[0] = clipBounds[1] = startPos; + clipBounds.AddPoint( seekPos ); + + const idBounds& bounds = physics->GetBounds(); + + idVec3 dir = seekDelta; + dir.z = 0; + dir.NormalizeFast(); + idVec3 center = 0.5 * (startPos + seekPos); + + idVec3 normal = dir.Cross(gameLocal.GetGravity()); + normal.NormalizeFast(); + clipBounds.AddPoint( center + MAX_OBSTACLE_RADIUS * normal); + clipBounds.AddPoint( center - MAX_OBSTACLE_RADIUS * normal); + + clipBounds.AddPoint(seekPos + 2 * bounds[1][0] * dir); + clipBounds.AddPoint(startPos - 2 * bounds[1][0] * dir); + + clipBounds[0][2] -= bounds[0][2] + OBSTACLE_HEIGHT_EXPANSION; + clipBounds[1][2] += bounds[1][2] + OBSTACLE_HEIGHT_EXPANSION; + + clipBounds.ExpandSelf(CLIP_BOUNDS_EPSILON); + + // clipBounds.ExpandSelf( MAX_OBSTACLE_RADIUS ); + clipMask = physics->GetClipMask(); + + if ( ai_showObstacleAvoidance.GetBool() ) { + gameRenderWorld->DebugBox(colorBlue, idBox(clipBounds), gameLocal.msec); + } + + // find all obstacles touching the clip bounds + static idClipModel* clipModelList[ MAX_GENTITIES ]; + int numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds( clipBounds, clipMask, clipModelList, MAX_GENTITIES ); + + int numObstacles = 0; // no obstacles so far + + CBinaryFrobMover* p_binaryFrobMover; // grayman #2345 + + idAI* selfAI = NULL; // grayman #2345 - for locating a func_static you're bumping into + if (self->IsType(idAI::Type)) + { + selfAI = static_cast(self); + } + + bool actorFound = false; // grayman #2345 - whether an actor was found on this pass + + for ( int i = 0; i < numListedClipModels && numObstacles < MAX_OBSTACLES; i++ ) + { + p_binaryFrobMover = NULL; // grayman #2345 + idClipModel* clipModel = clipModelList[i]; + idEntity* obEnt = clipModel->GetEntity(); + + // greebo: Immediately ignore self + if (obEnt == self) + { + continue; + } + + /* + * SZ: Oct 9, 2006: Not all binary frob movers have trace models as clip models + * so I am commenting this out. + */ + /* + if ( !clipModel->IsTraceModel() ) { + continue; + } + */ + + if (obEnt->IsType(idActor::Type)) + { + idActor* obEntActor = static_cast(obEnt); // grayman #2345 + actorFound = true; // grayman #2345 + idPhysics* obPhys = obEnt->GetPhysics(); + + // ignore myself, my enemy, and dead bodies + // TDM: Also ignore ALL enemies + // grayman #2728 - also ignore small AI + if ((obPhys == physics) || (obEnt == ignore) || (obEnt->health <= 0) || self->IsEnemy(obEnt) || (obPhys->GetMass() <= 5.0)) + { + continue; + } + + /* grayman #2345 + + Use m_pathRank to determine who will walk around the other. At init time, m_pathRank + is set to rank. A higher m_pathRank will not walk around a lower m_pathRank. A lower + m_pathRank will walk around a higher m_pathRank. If m_pathRanks are equal at first + encounter, self's m_pathRank will be bumped up. Whoever sights the other first gets + to have a higher m_pathRank. m_pathRank = 1000 for a non-moving actor, so others + will walk around him. m_pathRank is reset to rank when an AI begins moving again. + + */ + + bool sameDirection = false; // self and actor traveling in roughly the same direction? + bool actorSameFaster = false; // actor is traveling at the same speed or faster than you + const idVec3& actorVel = obPhys->GetLinearVelocity(); + float actorSpeedSqr = actorVel.LengthSqr(); + idVec3 myVel = physics->GetLinearVelocity(); + float mySpeedSqr = myVel.LengthSqr(); + // moving in about the same direction? + if (actorVel * myVel > 0.0f) + { + sameDirection = true; + } + + // actor's speed is faster or equal to self? + if (actorSpeedSqr >= mySpeedSqr) + { + actorSameFaster = true; + } + + if (self->m_pathRank > obEntActor->m_pathRank) + { + if (actorSameFaster) + { + continue; + } + else if (!sameDirection) + { + continue; + } + } + else if (self->m_pathRank == obEntActor->m_pathRank) + { + self->m_pathRank++; // increase mine and ignore the other actor + continue; // ignore + } + + // Self's path rank is lower than the actor's. If the actor is moving in the same + // direction and is traveling at the same speed or faster, ignore them. + + else if (sameDirection && actorSameFaster) + { + continue; // ignore + } + } + // SZ: Oct 9, 2006: BinaryMovers are now dynamic pathing obstacles too + else if (obEnt->IsType(CBinaryFrobMover::Type)) + { + p_binaryFrobMover = static_cast(obEnt); // grayman #2345 + } + else if (obEnt->IsType(idMoveable::Type)) + { + // grayman #2740 - ignore movables attached to the AI + + idEntity* bindMaster = obEnt->GetBindMaster(); + if (self == bindMaster) + { + continue; // ignore + } + + // all other moveables are considered obstacles + } + + // grayman #2345 - in general, ignore func_statics. but if you're bumping into one, consider it an obstacle + + else if (obEnt->IsType(idStaticEntity::Type)) + { + if (selfAI && (obEnt != selfAI->GetTactileEntity())) + { + continue; // ignore this + } + + // If we get here, this func_static is an obstacle. However, func_statics can + // have odd shapes, which means you could walk through an opening in one, or + // under one. If you're "inside" the bounding box of this func_static, ignore it. + + idPhysics* obPhys = obEnt->GetPhysics(); + idBounds obBounds = obPhys->GetAbsBounds(); + idVec3 origin = physics->GetOrigin(); + if (obBounds.ContainsPoint(origin)) + { + continue; // ignore this + } + } + else + { + // ignore everything else + + // TDM: SZ Oct 9, 2006: Comment this continue out, and the AI will path around func_statics + // and the like, even without monster-clip brushes around them. + // However, the CPU load is higher and the weapon an AI is carrying + // is an obstacle (bad). + + continue; + } + + // check if we can step over the object + clipModel->GetAbsBounds().AxisProjection( -physics->GetGravityNormal(), min, max ); + if ( max < stepHeight || min > headHeight ) { + // can step over this one + // angua: do not step over other actors + if (!obEnt->IsType(idActor::Type)) + { + continue; + } + } + + // Get the box bounding the obstacle + idBox box( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); + idBox boxClosed; // grayman #2712 + bool openDoorFound = false; // grayman #2712 + + // grayman #2345 - To get AI to queue at an open door and not cause logjams, treat an open door + // as if it's closed. This could also apply to all binary frob movers, but since many of those + // are simple wall switches, and should be ignored, we'll limit this code to doors. The door-handling + // task sorts out whether the door is actually open or closed. + + if (p_binaryFrobMover != NULL) + { + // only "see" doors + // grayman #2712 - if you can operate doors, and the door is open, include a + // second box representing the closed door. The 'open' box provides an obstacle + // presence for pathfinding, and the 'closed' box alerts the AI that the door + // needs to be handled. + + if (p_binaryFrobMover->IsType(CFrobDoor::Type)) + { + if (selfAI->m_bCanOperateDoors) // grayman #2691 + { + if (p_binaryFrobMover->IsOpen()) + { + if (!selfAI->m_HandlingDoor) // If we're already handling a door, don't include the closed door in the obstacle calculation + { + openDoorFound = true; + // grayman #720 - replace calculations with a capture of the closed box at spawn time + +// box.AddBox (p_binaryFrobMover->GetClosedBox()); + boxClosed = p_binaryFrobMover->GetClosedBox(); // create a second box; don't add to open box + } + } + } + } + } + + // project the box containing the obstacle onto the floor plane + int numVerts = box.GetParallelProjectionSilhouetteVerts( physics->GetGravityNormal(), silVerts ); + + // create a 2D winding for the obstacle; + obstacle_t& obstacle = obstacles[numObstacles++]; + obstacle.winding.Clear(); + for ( int j = 0; j < numVerts; j++ ) { + obstacle.winding.AddPoint( silVerts[j].ToVec2() ); + } + + if ( ai_showObstacleAvoidance.GetBool() ) { + for ( int j = 0; j < numVerts; j++ ) { + silVerts[j].z = startPos.z; + } + for ( int j = 0; j < numVerts; j++ ) { + gameRenderWorld->DebugArrow( colorWhite, silVerts[j], silVerts[(j+1)%numVerts], 4 ,gameLocal.msec); + } + } + + // expand the 2D winding for collision with a 2D box + obstacle.winding.ExpandForAxialBox( expBounds ); + obstacle.winding.GetBounds( obstacle.bounds ); + obstacle.entity = obEnt; + + // grayman #2712 - treat a 'closed' door box as a separate item so the door's recognized + // later when the AI is told to handle it. + + if (openDoorFound) + { + // project the box containing the obstacle onto the floor plane + int numVerts = boxClosed.GetParallelProjectionSilhouetteVerts( physics->GetGravityNormal(), silVerts ); + + // create a 2D winding for the obstacle; + obstacle_t& obstacle2 = obstacles[numObstacles++]; + obstacle2.winding.Clear(); + for ( int j = 0; j < numVerts; j++ ) { + obstacle2.winding.AddPoint( silVerts[j].ToVec2() ); + } + + // expand the 2D winding for collision with a 2D box + obstacle2.winding.ExpandForAxialBox( expBounds ); + obstacle2.winding.GetBounds( obstacle.bounds ); + obstacle2.entity = obEnt; + } + } + + // grayman #2345 - if I encountered no actors on this pass, reset my m_pathRank to my rank + + if (!actorFound) + { + self->m_pathRank = self->rank; + } + + // if there are no dynamic obstacles the path should be through valid AAS space + if ( numObstacles == 0 ) { + return 0; + } + + int blockingObstacle; // will hold the index to the first blocking obstacle + int blockingEdgeNum; // will hold the edge number of the winding which intersects the path + int blockingDoorNum = -1; // grayman #2345 - will hold the index to the first blocking door + float blockingScale; + // if the current path doesn't intersect any dynamic obstacles the path should be through valid AAS space + int startObstacleNum = PointInsideObstacle( obstacles, numObstacles, startPos.ToVec2()); + if (startObstacleNum == -1 ) + { + if (!GetFirstBlockingObstacle(physics, obstacles, numObstacles, -1, startPos.ToVec2(), seekDelta.ToVec2(), + blockingScale, blockingObstacle, blockingEdgeNum, blockingDoorNum)) // grayman #2345 + { + // grayman #1327 - return the door even if blockingScale (determined in GetFirstBlockingObstacle() ) + // was > 1. This allows AI to see doors sooner, and helps reduce the number of instances where + // they don't see the door at all. + + if ( blockingDoorNum >= 0 ) + { + idEntity* door = obstacles[blockingDoorNum].entity; // we already know this is a valid door + pathInfo.doorObstacle = static_cast(door); + } + + // No first obstacle found + return 0; + } + + // grayman #2345 - rather than test to see if the first blocking obstacle + // is a door, test to see if ANY is a door. If so, mark the first one. + + if ( blockingDoorNum >= 0 ) + { + idEntity* door = obstacles[blockingDoorNum].entity; // we already know this is a valid door + pathInfo.doorObstacle = static_cast(door); + } + } + + // create obstacles for AAS walls + + if ( aas != NULL ) + { + float halfBoundsSize = ( expBounds[ 1 ].x - expBounds[ 0 ].x ) * 0.5f; + + int wallEdges[MAX_AAS_WALL_EDGES]; + START_TIMING(self->actorGetWallEdgesTimer); + int numWallEdges = aas->GetWallEdges( areaNum, clipBounds, TFL_WALK, wallEdges, MAX_AAS_WALL_EDGES ); + STOP_TIMING(self->actorGetWallEdgesTimer); + + START_TIMING(self->actorSortWallEdgesTimer); + aas->SortWallEdges( wallEdges, numWallEdges ); + STOP_TIMING(self->actorSortWallEdgesTimer); + + int lastVerts[2] = {0,0}; + int nextVerts[2] = {0,0}; + idVec2 lastEdgeNormal(0,0); + int verts[2]; // will hold edge vertex indices + idVec2 edgeNormal, nextEdgeDir, nextEdgeNormal(0, 0); + idVec3 start, end, nextStart, nextEnd; + + for ( int i = 0; i < numWallEdges && numObstacles < MAX_OBSTACLES; i++ ) + { + aas->GetEdge( wallEdges[i], start, end ); + aas->GetEdgeVertexNumbers( wallEdges[i], verts ); + + // Get the edge direction + idVec2 edgeDir(end.ToVec2() - start.ToVec2()); + edgeDir.Normalize(); + + // Get the direction perpendicular to this edge + edgeNormal.x = edgeDir.y; + edgeNormal.y = -edgeDir.x; + + // Do we have a next edge? + if ( i < numWallEdges-1 ) + { + // Get the next edge direction plus normal + aas->GetEdge( wallEdges[i+1], nextStart, nextEnd ); + aas->GetEdgeVertexNumbers( wallEdges[i+1], nextVerts ); + + nextEdgeDir = nextEnd.ToVec2() - nextStart.ToVec2(); + nextEdgeDir.Normalize(); + + nextEdgeNormal.x = nextEdgeDir.y; + nextEdgeNormal.y = -nextEdgeDir.x; + } + + // greebo: Check if caching the AAS obstacle representations can save some CPU time. + // AAS areas never change during map runtime, so why calculate them each time? + // 15/06/2008: Did some profiling, the section below is harmless, it's the + // aas->GetWallEdges and aas->SortWallEdges() calls above which are expensive. + + // grayman: If they're expensive, can't they also be done once and cached? An AAS + // area doesn't change over time. + + // Start to fill the values in the new obstacle structure + obstacle_t& obstacle = obstacles[numObstacles++]; + + obstacle.winding.Clear(); + + // greebo: Populate the winding, this will form a trapezoid + // with the edge as one side. The longer side will be a bit away from the wall sticking into the room. + obstacle.winding.AddPoint( end.ToVec2() ); + obstacle.winding.AddPoint( start.ToVec2() ); + obstacle.winding.AddPoint( start.ToVec2() - edgeDir - edgeNormal * halfBoundsSize ); + obstacle.winding.AddPoint( end.ToVec2() + edgeDir - edgeNormal * halfBoundsSize ); + + if ( lastVerts[1] == verts[0] ) { + obstacle.winding[2] -= lastEdgeNormal * halfBoundsSize; + } else { + obstacle.winding[1] -= edgeDir; + } + if ( verts[1] == nextVerts[0] ) { + obstacle.winding[3] -= nextEdgeNormal * halfBoundsSize; + } else { + obstacle.winding[0] += edgeDir; + } + obstacle.winding.GetBounds( obstacle.bounds ); + obstacle.entity = NULL; + + lastVerts[0] = verts[0]; + lastVerts[1] = verts[1]; + lastEdgeNormal = edgeNormal; + } + } + + // show obstacles + if ( ai_showObstacleAvoidance.GetBool() ) { + for ( int i = 0; i < numObstacles; i++ ) { + obstacle_t &obstacle = obstacles[i]; + for ( int j = 0; j < obstacle.winding.GetNumPoints(); j++ ) { + silVerts[j].ToVec2() = obstacle.winding[j]; + silVerts[j].z = startPos.z; + } + for ( int j = 0; j < obstacle.winding.GetNumPoints(); j++ ) { + gameRenderWorld->DebugArrow( colorGreen, silVerts[j], silVerts[(j+1)%obstacle.winding.GetNumPoints()], 4, gameLocal.msec ); + } + } + } + + return numObstacles; +} + +/* +============ +FreePathTree_r +============ +*/ +void FreePathTree_r( pathNode_t *node ) { + if ( node->children[0] ) { + FreePathTree_r( node->children[0] ); + } + if ( node->children[1] ) { + FreePathTree_r( node->children[1] ); + } + pathNodeAllocator.Free( node ); +} + +/* +============ +DrawPathTree +============ +*/ +void DrawPathTree( const pathNode_t *root, const float height ) { + int i; + idVec3 start, end; + const pathNode_t *node; + + for ( node = root; node; node = node->next ) { + for ( i = 0; i < 2; i++ ) { + if ( node->children[i] ) { + start.ToVec2() = node->pos; + start.z = height; + end.ToVec2() = node->children[i]->pos; + end.z = height; + gameRenderWorld->DebugArrow( node->edgeNum == -1 ? colorYellow : i ? colorBlue : colorRed, start, end, 1 ); + break; + } + } + } +} + +/* +============ +GetPathNodeDelta +============ +*/ +bool GetPathNodeDelta( pathNode_t *node, const obstacle_t *obstacles, const idVec2 &seekPos, bool blocked ) { + int numPoints, edgeNum; + bool facing; + idVec2 seekDelta, dir; + pathNode_t *n; + + numPoints = obstacles[node->obstacle].winding.GetNumPoints(); + + // get delta along the current edge + while( 1 ) { + edgeNum = ( node->edgeNum + node->dir ) % numPoints; + node->delta = obstacles[node->obstacle].winding[edgeNum] - node->pos; + if ( node->delta.LengthSqr() > 0.01f ) { + break; + } + node->edgeNum = ( node->edgeNum + numPoints + ( 2 * node->dir - 1 ) ) % numPoints; + } + + // if not blocked + if ( !blocked ) { + + // test if the current edge faces the goal + seekDelta = seekPos - node->pos; + facing = ( ( 2 * node->dir - 1 ) * ( node->delta.x * seekDelta.y - node->delta.y * seekDelta.x ) ) >= 0.0f; + + // if the current edge faces goal and the line from the current + // position to the goal does not intersect the current path + if ( facing && !LineIntersectsPath( node->pos, seekPos, node->parent ) ) { + node->delta = seekPos - node->pos; + node->edgeNum = -1; + } + } + + // if the delta is along the obstacle edge + if ( node->edgeNum != -1 ) { + // if the edge is found going from this node to the root node + for ( n = node->parent; n; n = n->parent ) { + + if ( node->obstacle != n->obstacle || node->edgeNum != n->edgeNum ) { + continue; + } + + // test whether or not the edge segments actually overlap + if ( n->pos * node->delta > ( node->pos + node->delta ) * node->delta ) { + continue; + } + if ( node->pos * node->delta > ( n->pos + n->delta ) * node->delta ) { + continue; + } + + break; + } + if ( n ) { + return false; + } + } + return true; +} + +/* +============ +BuildPathTree +============ +*/ +pathNode_t *BuildPathTree( const idPhysics *physics, const obstacle_t *obstacles, int numObstacles, const idBounds &clipBounds, const idVec2 &startPos, const idVec2 &seekPos, obstaclePath_t &path ) // grayman #2345 - added 'physics' +{ + int blockingEdgeNum, blockingObstacle, obstaclePoints, bestNumNodes = MAX_OBSTACLE_PATH; + float blockingScale; + pathNode_t *root, *node, *child; + // gcc 4.0 + idQueueTemplate pathNodeQueue, treeQueue; + root = pathNodeAllocator.Alloc(); + root->Init(); + root->pos = startPos; + + root->delta = seekPos - root->pos; + root->numNodes = 0; + pathNodeQueue.Add( root ); + + for ( node = pathNodeQueue.Get(); node && pathNodeAllocator.GetAllocCount() < MAX_PATH_NODES; node = pathNodeQueue.Get() ) { + + treeQueue.Add( node ); + + // if this path has more than twice the number of nodes than the best path so far + if ( node->numNodes > bestNumNodes * 2 ) { + continue; + } + + // don't move outside of the clip bounds + idVec2 endPos = node->pos + node->delta; + if ( endPos.x - CLIP_BOUNDS_EPSILON < clipBounds[0].x || endPos.x + CLIP_BOUNDS_EPSILON > clipBounds[1].x || + endPos.y - CLIP_BOUNDS_EPSILON < clipBounds[0].y || endPos.y + CLIP_BOUNDS_EPSILON > clipBounds[1].y ) { + continue; + } + + // if an obstacle is blocking the path + + int blockingDoorNum = -1; // grayman #2345 - will hold the index to the first blocking door + + if ( GetFirstBlockingObstacle(physics, obstacles, numObstacles, node->obstacle, node->pos, node->delta, blockingScale, blockingObstacle, blockingEdgeNum, blockingDoorNum)) // grayman #2345 + { + if ( path.firstObstacle == NULL ) { + path.firstObstacle = obstacles[blockingObstacle].entity; + } + + node->delta *= blockingScale; + + if ( node->edgeNum == -1 ) { + node->children[0] = pathNodeAllocator.Alloc(); + node->children[0]->Init(); + node->children[1] = pathNodeAllocator.Alloc(); + node->children[1]->Init(); + node->children[0]->dir = 0; + node->children[1]->dir = 1; + node->children[0]->parent = node->children[1]->parent = node; + node->children[0]->pos = node->children[1]->pos = node->pos + node->delta; + node->children[0]->obstacle = node->children[1]->obstacle = blockingObstacle; + node->children[0]->edgeNum = node->children[1]->edgeNum = blockingEdgeNum; + node->children[0]->numNodes = node->children[1]->numNodes = node->numNodes + 1; + if ( GetPathNodeDelta( node->children[0], obstacles, seekPos, true ) ) { + pathNodeQueue.Add( node->children[0] ); + } + if ( GetPathNodeDelta( node->children[1], obstacles, seekPos, true ) ) { + pathNodeQueue.Add( node->children[1] ); + } + } else { + node->children[node->dir] = child = pathNodeAllocator.Alloc(); + child->Init(); + child->dir = node->dir; + child->parent = node; + child->pos = node->pos + node->delta; + child->obstacle = blockingObstacle; + child->edgeNum = blockingEdgeNum; + child->numNodes = node->numNodes + 1; + if ( GetPathNodeDelta( child, obstacles, seekPos, true ) ) { + pathNodeQueue.Add( child ); + } + } + } else { + node->children[node->dir] = child = pathNodeAllocator.Alloc(); + child->Init(); + child->dir = node->dir; + child->parent = node; + child->pos = node->pos + node->delta; + child->numNodes = node->numNodes + 1; + + // there is a free path towards goal + if ( node->edgeNum == -1 ) { + if ( node->numNodes < bestNumNodes ) { + bestNumNodes = node->numNodes; + } + continue; + } + + child->obstacle = node->obstacle; + obstaclePoints = obstacles[node->obstacle].winding.GetNumPoints(); + child->edgeNum = ( node->edgeNum + obstaclePoints + ( 2 * node->dir - 1 ) ) % obstaclePoints; + + if ( GetPathNodeDelta( child, obstacles, seekPos, false ) ) { + pathNodeQueue.Add( child ); + } + } + } + + return root; +} + +/* +============ +PrunePathTree +============ +*/ +void PrunePathTree( pathNode_t *root, const idVec2 &seekPos ) { + int i; + float bestDist; + pathNode_t *node, *lastNode, *n, *bestNode; + + node = root; + while( node ) { + node->dist = ( seekPos - node->pos ).LengthSqr(); + + if ( node->children[0] ) { + node = node->children[0]; + } else if ( node->children[1] ) { + node = node->children[1]; + } else { + + // find the node closest to the goal along this path + bestDist = idMath::INFINITY; + bestNode = node; + for ( n = node; n; n = n->parent ) { + if ( n->children[0] && n->children[1] ) { + break; + } + if ( n->dist < bestDist ) { + bestDist = n->dist; + bestNode = n; + } + } + + // free tree down from the best node + for ( i = 0; i < 2; i++ ) { + if ( bestNode->children[i] ) { + FreePathTree_r( bestNode->children[i] ); + bestNode->children[i] = NULL; + } + } + + for ( lastNode = bestNode, node = bestNode->parent; node; lastNode = node, node = node->parent ) { + if ( node->children[1] && ( node->children[1] != lastNode ) ) { + node = node->children[1]; + break; + } + } + } + } +} + +/* +============ +OptimizePath +============ +*/ +int OptimizePath( const pathNode_t *root, const pathNode_t *leafNode, const obstacle_t *obstacles, int numObstacles, idVec2 optimizedPath[MAX_OBSTACLE_PATH] ) { + int i, numPathPoints, edgeNums[2]; + const pathNode_t *curNode, *nextNode; + idVec2 curPos, curDelta, bounds[2]; + float scale1, scale2, curLength; + + optimizedPath[0] = root->pos; + numPathPoints = 1; + + for ( nextNode = curNode = root; curNode != leafNode; curNode = nextNode ) { + for ( nextNode = leafNode; nextNode->parent != curNode; nextNode = nextNode->parent ) { + + // can only take shortcuts when going from one object to another + if ( nextNode->obstacle == curNode->obstacle ) { + continue; + } + + curPos = curNode->pos; + curDelta = nextNode->pos - curPos; + curLength = curDelta.Length(); + + // get bounds for the current movement delta + bounds[0] = curPos - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + bounds[1] = curPos + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); + bounds[FLOATSIGNBITNOTSET(curDelta.x)].x += curDelta.x; + bounds[FLOATSIGNBITNOTSET(curDelta.y)].y += curDelta.y; + + // test if the shortcut intersects with any obstacles + for ( i = 0; i < numObstacles; i++ ) { + if ( bounds[0].x > obstacles[i].bounds[1].x || bounds[0].y > obstacles[i].bounds[1].y || + bounds[1].x < obstacles[i].bounds[0].x || bounds[1].y < obstacles[i].bounds[0].y ) { + continue; + } + if ( obstacles[i].winding.RayIntersection( curPos, curDelta, scale1, scale2, edgeNums ) ) { + if ( scale1 >= 0.0f && scale1 <= 1.0f && ( i != nextNode->obstacle || scale1 * curLength < curLength - 0.5f ) ) { + break; + } + if ( scale2 >= 0.0f && scale2 <= 1.0f && ( i != nextNode->obstacle || scale2 * curLength < curLength - 0.5f ) ) { + break; + } + } + } + if ( i >= numObstacles ) { + break; + } + } + + // store the next position along the optimized path + optimizedPath[numPathPoints++] = nextNode->pos; + } + + return numPathPoints; +} + +/* +============ +PathLength +============ +*/ +float PathLength( idVec2 optimizedPath[MAX_OBSTACLE_PATH], int numPathPoints, const idVec2 &curDir ) { + int i; + float pathLength; + + // calculate the path length + pathLength = 0.0f; + for ( i = 0; i < numPathPoints-1; i++ ) { + pathLength += ( optimizedPath[i+1] - optimizedPath[i] ).LengthFast(); + } + + // add penalty if this path does not go in the current direction + if ( curDir * ( optimizedPath[1] - optimizedPath[0] ) < 0.0f ) { + pathLength += 100.0f; + } + return pathLength; +} + +/* +============ +FindOptimalPath + + Returns true if there is a path all the way to the goal. +============ +*/ +bool FindOptimalPath( const pathNode_t *root, const obstacle_t *obstacles, int numObstacles, const float height, const idVec3 &curDir, idVec3 &seekPos ) { + int i, numPathPoints, bestNumPathPoints; + const pathNode_t *node, *lastNode, *bestNode; + idVec2 optimizedPath[MAX_OBSTACLE_PATH]; + float pathLength, bestPathLength; + bool pathToGoalExists, optimizedPathCalculated; + + seekPos.Zero(); + seekPos.z = height; + + pathToGoalExists = false; + optimizedPathCalculated = false; + + bestNode = root; + bestNumPathPoints = 0; + bestPathLength = idMath::INFINITY; + + node = root; + + while( node ) { + pathToGoalExists |= ( node->dist < 0.1f ); + + if ( node->dist <= bestNode->dist ) { + + if ( idMath::Fabs( node->dist - bestNode->dist ) < 0.1f ) { + + if ( !optimizedPathCalculated ) { + bestNumPathPoints = OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); + bestPathLength = PathLength( optimizedPath, bestNumPathPoints, curDir.ToVec2() ); + // grayman - A series of path points has been examined and the first one to head to is in + // optimizedPath[1]. But if bestNumPathPoints == 1 here, then optimizedPath[1] contains garbage. Does it matter? + seekPos.ToVec2() = optimizedPath[1]; + } + + numPathPoints = OptimizePath( root, node, obstacles, numObstacles, optimizedPath ); + pathLength = PathLength( optimizedPath, numPathPoints, curDir.ToVec2() ); + + if ( pathLength < bestPathLength ) { + bestNode = node; + bestNumPathPoints = numPathPoints; + bestPathLength = pathLength; + seekPos.ToVec2() = optimizedPath[1]; + } + optimizedPathCalculated = true; + + } else { + + bestNode = node; + optimizedPathCalculated = false; + } + } + + if ( node->children[0] ) { + node = node->children[0]; + } else if ( node->children[1] ) { + node = node->children[1]; + } else { + for ( lastNode = node, node = node->parent; node; lastNode = node, node = node->parent ) { + if ( node->children[1] && node->children[1] != lastNode ) { + node = node->children[1]; + break; + } + } + } + } + + if ( !pathToGoalExists ) { + if (root->children[0] != NULL) + { + seekPos.ToVec2() = root->children[0]->pos; + } + } else if ( !optimizedPathCalculated ) { + OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); + seekPos.ToVec2() = optimizedPath[1]; + } + + if ( ai_showObstacleAvoidance.GetBool() ) { + idVec3 start, end; + start.z = end.z = height + 4.0f; + numPathPoints = OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); + for ( i = 0; i < numPathPoints-1; i++ ) { + start.ToVec2() = optimizedPath[i]; + end.ToVec2() = optimizedPath[i+1]; + gameRenderWorld->DebugArrow( colorCyan, start, end, 1, gameLocal.msec); + } + } + + return pathToGoalExists; +} + +/* +============ +idAI::FindPathAroundObstacles + + Finds a path around dynamic obstacles using a path tree with clockwise and counter clockwise edge walks. +============ +*/ +bool idAI::FindPathAroundObstacles(const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path, idActor* owner ) { + // Initialise the path structure with reasonable defaults + path.seekPos = seekPos; + path.firstObstacle = NULL; + path.startPosOutsideObstacles = startPos; + path.startPosObstacle = NULL; + path.seekPosOutsideObstacles = seekPos; + path.seekPosObstacle = NULL; + path.doorObstacle = NULL; + + if (aas == NULL) { + return true; // no AAS! + } + + idBounds bounds; + bounds[1] = aas->GetSettings()->boundingBoxes[0][1]; + bounds[0] = -bounds[1]; + bounds[1].z = 32.0f; + + // get the AAS area number and a valid point inside that area + int areaNum = aas->PointReachableAreaNum( path.startPosOutsideObstacles, bounds, (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); + aas->PushPointIntoAreaNum( areaNum, path.startPosOutsideObstacles ); + + // get all the nearby obstacles + static obstacle_t obstacles[MAX_OBSTACLES]; + idBounds clipBounds; + + START_TIMING(owner->actorGetObstaclesTimer); + int numObstacles = GetObstacles( physics, aas, ignore, areaNum, path.startPosOutsideObstacles, path.seekPosOutsideObstacles, obstacles, MAX_OBSTACLES, clipBounds, path ); + STOP_TIMING(owner->actorGetObstaclesTimer); + + START_TIMING(owner->actorGetPointOutsideObstaclesTimer); + + // get a source position outside the obstacles + int insideObstacle; + GetPointOutsideObstacles( obstacles, numObstacles, path.startPosOutsideObstacles.ToVec2(), &insideObstacle, NULL ); + if ( insideObstacle != -1 ) { + path.startPosObstacle = obstacles[insideObstacle].entity; + } + + // get a goal position outside the obstacles + GetPointOutsideObstacles( obstacles, numObstacles, path.seekPosOutsideObstacles.ToVec2(), &insideObstacle, NULL ); + if ( insideObstacle != -1 ) { + path.seekPosObstacle = obstacles[insideObstacle].entity; + } + + STOP_TIMING(owner->actorGetPointOutsideObstaclesTimer); + + // if start and destination are pushed to the same point, we don't have a path around the obstacle + if ( ( path.seekPosOutsideObstacles.ToVec2() - path.startPosOutsideObstacles.ToVec2() ).LengthSqr() < Square( 1.0f ) ) { + if ( ( seekPos.ToVec2() - startPos.ToVec2() ).LengthSqr() > Square( 2.0f ) ) { + return false; + } + } + + START_TIMING(owner->actorBuildPathTreeTimer); + // build a path tree + pathNode_t* root = BuildPathTree(physics, obstacles, numObstacles, clipBounds, path.startPosOutsideObstacles.ToVec2(), path.seekPosOutsideObstacles.ToVec2(), path ); // grayman #2345 - added 'physics' + +// PrintNodes(root,0,obstacles); // grayman for debugging path trees + + STOP_TIMING(owner->actorBuildPathTreeTimer); + + // draw the path tree + if ( ai_showObstacleAvoidance.GetBool() ) { + DrawPathTree( root, physics->GetOrigin().z ); + } + + // prune the tree + START_TIMING(owner->actorPrunePathTreeTimer); + PrunePathTree( root, path.seekPosOutsideObstacles.ToVec2() ); + STOP_TIMING(owner->actorPrunePathTreeTimer); +// PrintNodes(root,0,obstacles); // grayman for debugging path trees + + // find the optimal path + START_TIMING(owner->actorFindOptimalPathTimer); + bool pathToGoalExists = FindOptimalPath( root, obstacles, numObstacles, physics->GetOrigin().z, physics->GetLinearVelocity(), path.seekPos ); + STOP_TIMING(owner->actorFindOptimalPathTimer); + + // free the tree + FreePathTree_r( root ); + + return pathToGoalExists; +} + +/* +============ +idAI::FreeObstacleAvoidanceNodes +============ +*/ +void idAI::FreeObstacleAvoidanceNodes( void ) { + pathNodeAllocator.Shutdown(); +} + + +/* +=============================================================================== + + Path Prediction + + Uses the AAS to quickly and accurately predict a path for a certain + period of time based on an initial position and velocity. + +=============================================================================== +*/ + +const float OVERCLIP = 1.001f; +const int MAX_FRAME_SLIDE = 5; + +typedef struct pathTrace_s { + float fraction; + idVec3 endPos; + idVec3 normal; + const idEntity * blockingEntity; +} pathTrace_t; + +/* +============ +PathTrace + + Returns true if a stop event was triggered. +============ +*/ +bool PathTrace( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &end, int stopEvent, struct pathTrace_s &trace, predictedPath_t &path ) { + trace_t clipTrace; + aasTrace_t aasTrace; + + memset( &trace, 0, sizeof( trace ) ); + + if ( !aas || !aas->GetSettings() ) { + + gameLocal.clip.Translation( clipTrace, start, end, ent->GetPhysics()->GetClipModel(), + ent->GetPhysics()->GetClipModel()->GetAxis(), MASK_MONSTERSOLID, ent ); + + // NOTE: could do (expensive) ledge detection here for when there is no AAS file + + trace.fraction = clipTrace.fraction; + trace.endPos = clipTrace.endpos; + trace.normal = clipTrace.c.normal; + trace.blockingEntity = gameLocal.entities[ clipTrace.c.entityNum ]; + } else { + aasTrace.getOutOfSolid = true; + if ( stopEvent & SE_ENTER_LEDGE_AREA ) { + aasTrace.flags |= AREA_LEDGE; + } + if ( stopEvent & SE_ENTER_OBSTACLE ) { + aasTrace.travelFlags |= TFL_INVALID; + } + + aas->Trace( aasTrace, start, end ); + + gameLocal.clip.TranslationEntities( clipTrace, start, aasTrace.endpos, ent->GetPhysics()->GetClipModel(), + ent->GetPhysics()->GetClipModel()->GetAxis(), MASK_MONSTERSOLID, ent ); + + if ( clipTrace.fraction >= 1.0f ) { + + trace.fraction = aasTrace.fraction; + trace.endPos = aasTrace.endpos; + trace.normal = aas->GetPlane( aasTrace.planeNum ).Normal(); + trace.blockingEntity = gameLocal.world; + + if ( aasTrace.fraction < 1.0f ) { + if ( stopEvent & SE_ENTER_LEDGE_AREA ) { + if ( aas->AreaFlags( aasTrace.blockingAreaNum ) & AREA_LEDGE ) { + path.endPos = trace.endPos; + path.endNormal = trace.normal; + path.endEvent = SE_ENTER_LEDGE_AREA; + path.blockingEntity = trace.blockingEntity; + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorRed, start, aasTrace.endpos ); + } + return true; + } + } + if ( stopEvent & SE_ENTER_OBSTACLE ) { + if ( aas->AreaTravelFlags( aasTrace.blockingAreaNum ) & TFL_INVALID ) { + path.endPos = trace.endPos; + path.endNormal = trace.normal; + path.endEvent = SE_ENTER_OBSTACLE; + path.blockingEntity = trace.blockingEntity; + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorRed, start, aasTrace.endpos ); + } + return true; + } + } + } + } else { + trace.fraction = clipTrace.fraction; + trace.endPos = clipTrace.endpos; + trace.normal = clipTrace.c.normal; + trace.blockingEntity = gameLocal.entities[ clipTrace.c.entityNum ]; + } + } + + if ( trace.fraction >= 1.0f ) { + trace.blockingEntity = NULL; + } + + return false; +} + +/* +============ +idAI::PredictPath + + Can also be used when there is no AAS file available however ledges are not detected. +============ +*/ +bool idAI::PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path ) { + int i, j, step, numFrames, curFrameTime; + idVec3 delta, curStart, curEnd, curVelocity, lastEnd, stepUp, tmpStart; + idVec3 gravity, gravityDir, invGravityDir; + float maxStepHeight, minFloorCos; + pathTrace_t trace; + + if ( aas && aas->GetSettings() ) { + gravity = aas->GetSettings()->gravity; + gravityDir = aas->GetSettings()->gravityDir; + invGravityDir = aas->GetSettings()->invGravityDir; + maxStepHeight = aas->GetSettings()->maxStepHeight; + minFloorCos = aas->GetSettings()->minFloorCos; + } else { + gravity = DEFAULT_GRAVITY_VEC3; + gravityDir = idVec3( 0, 0, -1 ); + invGravityDir = idVec3( 0, 0, 1 ); + maxStepHeight = 14.0f; + minFloorCos = 0.7f; + } + + path.endPos = start; + path.endVelocity = velocity; + path.endNormal.Zero(); + path.endEvent = 0; + path.endTime = 0; + path.blockingEntity = NULL; + + curStart = start; + curVelocity = velocity; + + numFrames = ( totalTime + frameTime - 1 ) / frameTime; + curFrameTime = frameTime; + for ( i = 0; i < numFrames; i++ ) { + + if ( i == numFrames-1 ) { + curFrameTime = totalTime - i * curFrameTime; + } + + delta = curVelocity * curFrameTime * 0.001f; + + path.endVelocity = curVelocity; + path.endTime = i * frameTime; + + // allow sliding along a few surfaces per frame + for ( j = 0; j < MAX_FRAME_SLIDE; j++ ) { + + idVec3 lineStart = curStart; + + // allow stepping up three times per frame + for ( step = 0; step < 3; step++ ) { + + curEnd = curStart + delta; + if ( PathTrace( ent, aas, curStart, curEnd, stopEvent, trace, path ) ) { + return true; + } + + if ( step ) { + + // step down at end point + tmpStart = trace.endPos; + curEnd = tmpStart - stepUp; + if ( PathTrace( ent, aas, tmpStart, curEnd, stopEvent, trace, path ) ) { + return true; + } + + // if not moved any further than without stepping up, or if not on a floor surface + if ( (lastEnd - start).LengthSqr() > (trace.endPos - start).LengthSqr() - 0.1f || + ( trace.normal * invGravityDir ) < minFloorCos ) { + if ( stopEvent & SE_BLOCKED ) { + path.endPos = lastEnd; + path.endEvent = SE_BLOCKED; + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorRed, lineStart, lastEnd ); + } + + return true; + } + + curStart = lastEnd; + break; + } + } + + path.endNormal = trace.normal; + path.blockingEntity = trace.blockingEntity; + + // if the trace is not blocked or blocked by a floor surface + if ( trace.fraction >= 1.0f || ( trace.normal * invGravityDir ) > minFloorCos ) { + curStart = trace.endPos; + break; + } + + // save last result + lastEnd = trace.endPos; + + // step up + stepUp = invGravityDir * maxStepHeight; + if ( PathTrace( ent, aas, curStart, curStart + stepUp, stopEvent, trace, path ) ) { + return true; + } + stepUp *= trace.fraction; + curStart = trace.endPos; + } + + if ( ai_debugMove.GetBool() ) { + gameRenderWorld->DebugLine( colorRed, lineStart, curStart ); + } + + if ( trace.fraction >= 1.0f ) { + break; + } + + delta.ProjectOntoPlane( trace.normal, OVERCLIP ); + curVelocity.ProjectOntoPlane( trace.normal, OVERCLIP ); + + if ( stopEvent & SE_BLOCKED ) { + // if going backwards + if ( (curVelocity - gravityDir * curVelocity * gravityDir ) * + (velocity - gravityDir * velocity * gravityDir) < 0.0f ) { + path.endPos = curStart; + path.endEvent = SE_BLOCKED; + + return true; + } + } + } + + if ( j >= MAX_FRAME_SLIDE ) { + if ( stopEvent & SE_BLOCKED ) { + path.endPos = curStart; + path.endEvent = SE_BLOCKED; + return true; + } + } + + // add gravity + curVelocity += gravity * frameTime * 0.001f; + } + + path.endTime = totalTime; + path.endVelocity = curVelocity; + path.endPos = curStart; + path.endEvent = 0; + + return false; +} + + +/* +=============================================================================== + + Trajectory Prediction + + Finds the best collision free trajectory for a clip model based on an + initial position, target position and speed. + +=============================================================================== +*/ + +/* +===================== +Ballistics + + get the ideal aim pitch angle in order to hit the target + also get the time it takes for the projectile to arrive at the target +===================== +*/ +typedef struct ballistics_s { + float angle; // angle in degrees in the range [-180, 180] + float time; // time it takes before the projectile arrives +} ballistics_t; + +static int Ballistics( const idVec3 &start, const idVec3 &end, float speed, float gravity, ballistics_t bal[2] ) { + int n, i; + float x, y, a, b, c, d, sqrtd, inva, p[2]; + + x = ( end.ToVec2() - start.ToVec2() ).Length(); + y = end[2] - start[2]; + + a = 4.0f * y * y + 4.0f * x * x; + b = -4.0f * speed * speed - 4.0f * y * gravity; + c = gravity * gravity; + + d = b * b - 4.0f * a * c; + if ( d <= 0.0f || a == 0.0f ) { + return 0; + } + sqrtd = idMath::Sqrt( d ); + inva = 0.5f / a; + p[0] = ( - b + sqrtd ) * inva; + p[1] = ( - b - sqrtd ) * inva; + n = 0; + for ( i = 0; i < 2; i++ ) { + if ( p[i] <= 0.0f ) { + continue; + } + d = idMath::Sqrt( p[i] ); + bal[n].angle = atan2( 0.5f * ( 2.0f * y * p[i] - gravity ) / d, d * x ); + bal[n].time = x / ( cos( bal[n].angle ) * speed ); + bal[n].angle = idMath::AngleNormalize180( RAD2DEG( bal[n].angle ) ); + n++; + } + + return n; +} + +/* +===================== +HeightForTrajectory + +Returns the maximum hieght of a given trajectory +===================== +*/ +static float HeightForTrajectory( const idVec3 &start, float zVel, float gravity ) { + float maxHeight, t; + + t = zVel / gravity; + // maximum height of projectile + maxHeight = start.z - 0.5f * gravity * ( t * t ); + + return maxHeight; +} + +/* +===================== +idAI::TestTrajectory +===================== +*/ +bool idAI::TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime ) { + int i, numSegments; + float maxHeight, t, t2; + idVec3 points[5]; + trace_t trace; + bool result; + + t = zVel / gravity; + // maximum height of projectile + maxHeight = start.z - 0.5f * gravity * ( t * t ); + // time it takes to fall from the top to the end height + t = idMath::Sqrt( ( maxHeight - end.z ) / ( 0.5f * -gravity ) ); + + // start of parabolic + points[0] = start; + + if ( t < time ) { + numSegments = 4; + // point in the middle between top and start + t2 = ( time - t ) * 0.5f; + points[1].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); + points[1].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; + // top of parabolic + t2 = time - t; + points[2].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); + points[2].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; + // point in the middel between top and end + t2 = time - t * 0.5f; + points[3].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); + points[3].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; + } else { + numSegments = 2; + // point halfway through + t2 = time * 0.5f; + points[1].ToVec2() = start.ToVec2() + ( end.ToVec2() - start.ToVec2() ) * 0.5f; + points[1].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; + } + + // end of parabolic + points[numSegments] = end; + + if ( drawtime ) { + for ( i = 0; i < numSegments; i++ ) { + gameRenderWorld->DebugLine( colorRed, points[i], points[i+1], drawtime ); + } + } + + // make sure projectile doesn't go higher than we want it to go + for ( i = 0; i < numSegments; i++ ) { + if ( points[i].z > max_height ) { + // goes higher than we want to allow + return false; + } + } + + result = true; + for ( i = 0; i < numSegments; i++ ) { + gameLocal.clip.Translation( trace, points[i], points[i+1], clip, mat3_identity, clipmask, ignore ); + if ( trace.fraction < 1.0f ) { + if ( gameLocal.GetTraceEntity( trace ) == targetEntity ) { + result = true; + } else { + result = false; + } + break; + } + } + + if ( drawtime ) { + if ( clip ) { + gameRenderWorld->DebugBounds( result ? colorGreen : colorYellow, clip->GetBounds().Expand( 1.0f ), trace.endpos, drawtime ); + } else { + idBounds bnds( trace.endpos ); + bnds.ExpandSelf( 1.0f ); + gameRenderWorld->DebugBounds( result ? colorGreen : colorYellow, bnds, vec3_zero, drawtime ); + } + } + + return result; +} + +/* +===================== +idAI::PredictTrajectory + + returns true if there is a collision free trajectory for the clip model + aimDir is set to the ideal aim direction in order to hit the target +===================== +*/ +bool idAI::PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir ) { + int n, i, j; + float zVel, a, t, pitch, s, c; + trace_t trace; + ballistics_t ballistics[2]; + idVec3 dir[2]; + idVec3 velocity; + idVec3 lastPos, pos; + + assert( targetEntity ); + + // check if the projectile starts inside the target + if ( targetEntity->GetPhysics()->GetAbsBounds().IntersectsBounds( clip->GetBounds().Translate( firePos ) ) ) { + aimDir = target - firePos; + aimDir.Normalize(); + return true; + } + + // if no velocity or the projectile is not affected by gravity + if ( projectileSpeed <= 0.0f || projGravity == vec3_origin ) { + + aimDir = target - firePos; + aimDir.Normalize(); + + gameLocal.clip.Translation( trace, firePos, target, clip, mat3_identity, clipmask, ignore ); + + if ( drawtime ) { + gameRenderWorld->DebugLine( colorRed, firePos, target, drawtime ); + idBounds bnds( trace.endpos ); + bnds.ExpandSelf( 1.0f ); + gameRenderWorld->DebugBounds( ( trace.fraction >= 1.0f || ( gameLocal.GetTraceEntity( trace ) == targetEntity ) ) ? colorGreen : colorYellow, bnds, vec3_zero, drawtime ); + } + + return ( trace.fraction >= 1.0f || ( gameLocal.GetTraceEntity( trace ) == targetEntity ) ); + } + + n = Ballistics( firePos, target, projectileSpeed, projGravity[2], ballistics ); + if ( n == 0 ) { + // there is no valid trajectory + aimDir = target - firePos; + aimDir.Normalize(); + return false; + } + + // make sure the first angle is the smallest + if ( n == 2 ) { + if ( ballistics[1].angle < ballistics[0].angle ) { + a = ballistics[0].angle; ballistics[0].angle = ballistics[1].angle; ballistics[1].angle = a; + t = ballistics[0].time; ballistics[0].time = ballistics[1].time; ballistics[1].time = t; + } + } + + // test if there is a collision free trajectory + for ( i = 0; i < n; i++ ) { + pitch = DEG2RAD( ballistics[i].angle ); + idMath::SinCos( pitch, s, c ); + dir[i] = target - firePos; + dir[i].z = 0.0f; + dir[i] *= c * idMath::InvSqrt( dir[i].LengthSqr() ); + dir[i].z = s; + + zVel = projectileSpeed * dir[i].z; + + if ( ai_debugTrajectory.GetBool() ) { + t = ballistics[i].time / 100.0f; + velocity = dir[i] * projectileSpeed; + lastPos = firePos; + pos = firePos; + for ( j = 1; j < 100; j++ ) { + pos += velocity * t; + velocity += projGravity * t; + gameRenderWorld->DebugLine( colorCyan, lastPos, pos ); + lastPos = pos; + } + } + + if ( TestTrajectory( firePos, target, zVel, projGravity[2], ballistics[i].time, firePos.z + max_height, clip, clipmask, ignore, targetEntity, drawtime ) ) { + aimDir = dir[i]; + return true; + } + } + + aimDir = dir[0]; + + // there is no collision free trajectory + return false; +} diff --git a/DarkMod/AI/AreaManager.cpp b/game/ai/AreaManager.cpp similarity index 79% rename from DarkMod/AI/AreaManager.cpp rename to game/ai/AreaManager.cpp index a3a17b8b2..29076db0a 100644 --- a/DarkMod/AI/AreaManager.cpp +++ b/game/ai/AreaManager.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/AreaManager.h b/game/ai/AreaManager.h new file mode 100644 index 000000000..01bd2bfb6 --- /dev/null +++ b/game/ai/AreaManager.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AREA_MANAGER_H__ +#define __AREA_MANAGER_H__ + +#include +#include + +class idAI; + +namespace ai +{ + +class AreaManager +{ +private: + // angua: Forbidden areas (e.g. areas with locked doors) are excluded from path finding + // for specific AI + // ForbiddenAreasMap: multimap of area number and the AI for which this area should be excluded + typedef std::multimap ForbiddenAreasMap; + ForbiddenAreasMap _forbiddenAreas; + + // angua: AiAreasMap: gives a set of areas for each AI (for faster lookup) + typedef std::set AreaSet; + typedef std::map AiAreasMap; + AiAreasMap _aiAreas; + +public: + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + + void AddForbiddenArea(int areanum, const idAI* ai); + bool AreaIsForbidden(int areanum, const idAI* ai) const; + void RemoveForbiddenArea(int areanum, const idAI* ai); + + void DisableForbiddenAreas(const idAI* ai); + void EnableForbiddenAreas(const idAI* ai); + + void Clear(); +}; + +} // namespace ai + +#endif /* __AREA_MANAGER_H__ */ diff --git a/DarkMod/AI/CommunicationSubsystem.cpp b/game/ai/CommunicationSubsystem.cpp similarity index 85% rename from DarkMod/AI/CommunicationSubsystem.cpp rename to game/ai/CommunicationSubsystem.cpp index 954a378d6..de1ab5e20 100644 --- a/DarkMod/AI/CommunicationSubsystem.cpp +++ b/game/ai/CommunicationSubsystem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/CommunicationSubsystem.h b/game/ai/CommunicationSubsystem.h new file mode 100644 index 000000000..a9bf4243a --- /dev/null +++ b/game/ai/CommunicationSubsystem.h @@ -0,0 +1,88 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_COMMUNICATION_SUBSYSTEM_H__ +#define __AI_COMMUNICATION_SUBSYSTEM_H__ + +#include +#include + +#include "Tasks/CommunicationTask.h" +#include "Subsystem.h" +#include "Queue.h" + +namespace ai +{ + +class CommunicationSubsystem : + public Subsystem +{ +protected: + + enum EActionTypeOnConflict + { + EDefault, // default behaviour + EOverride, // override the existing sound + EQueue, // queue after the current sound + EDiscard, // discard the new sound + EPush, // push on top of existing sound + }; + +public: + CommunicationSubsystem(SubsystemId subsystemId, idAI* owner); + + /** + * greebo: Handle a new incoming communication task and decide whether + * to push or queue it or do whatever action is defined according to the + * settings in the entityDef. + * + * Note: Does not accept NULL pointers. + * + * @returns: TRUE if the new bark has been accepted, FALSE if it has been ignored. + */ + bool AddCommTask(const CommunicationTaskPtr& communicationTask); + + // returns the priority of the currently active communication task + int GetCurrentPriority(); + + /** + * greebo: Queues a silence task at the end of the queue. The task + * gets the same priority assigned as the last one of the queue. + */ + void AddSilence(int duration); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Returns some debug text for console or renderworld display + virtual idStr GetDebugInfo(); + +protected: + // Priority difference is "new snd prio - current snd prio" + EActionTypeOnConflict GetActionTypeForSound(const CommunicationTaskPtr& communicationTask); + + // Returns the currently active commtask or NULL if no commtask is active + CommunicationTaskPtr GetCurrentCommTask(); +}; +typedef boost::shared_ptr CommunicationSubsystemPtr; + +} // namespace ai + +#endif /* __AI_COMMUNICATION_SUBSYSTEM_H__ */ diff --git a/DarkMod/AI/Conversation/Conversation.cpp b/game/ai/Conversation/Conversation.cpp similarity index 94% rename from DarkMod/AI/Conversation/Conversation.cpp rename to game/ai/Conversation/Conversation.cpp index 549e017d6..8e3aaee4a 100644 --- a/DarkMod/AI/Conversation/Conversation.cpp +++ b/game/ai/Conversation/Conversation.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/Conversation/Conversation.h b/game/ai/Conversation/Conversation.h similarity index 84% rename from DarkMod/AI/Conversation/Conversation.h rename to game/ai/Conversation/Conversation.h index b02a28df9..1dfe6d1c9 100644 --- a/DarkMod/AI/Conversation/Conversation.h +++ b/game/ai/Conversation/Conversation.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_CONVERSATION_H__ #define __AI_CONVERSATION_H__ diff --git a/DarkMod/AI/Conversation/ConversationCommand.cpp b/game/ai/Conversation/ConversationCommand.cpp similarity index 85% rename from DarkMod/AI/Conversation/ConversationCommand.cpp rename to game/ai/Conversation/ConversationCommand.cpp index 6e29e3620..6482408a0 100644 --- a/DarkMod/AI/Conversation/ConversationCommand.cpp +++ b/game/ai/Conversation/ConversationCommand.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/Conversation/ConversationCommand.h b/game/ai/Conversation/ConversationCommand.h similarity index 81% rename from DarkMod/AI/Conversation/ConversationCommand.h rename to game/ai/Conversation/ConversationCommand.h index 3a38aed25..8739d1378 100644 --- a/DarkMod/AI/Conversation/ConversationCommand.h +++ b/game/ai/Conversation/ConversationCommand.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_CONVERSATION_COMMAND_H__ #define __AI_CONVERSATION_COMMAND_H__ diff --git a/DarkMod/AI/Conversation/ConversationSystem.cpp b/game/ai/Conversation/ConversationSystem.cpp similarity index 89% rename from DarkMod/AI/Conversation/ConversationSystem.cpp rename to game/ai/Conversation/ConversationSystem.cpp index 27fa10a0e..1c8a18de9 100644 --- a/DarkMod/AI/Conversation/ConversationSystem.cpp +++ b/game/ai/Conversation/ConversationSystem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Conversation/ConversationSystem.h b/game/ai/Conversation/ConversationSystem.h new file mode 100644 index 000000000..c8d747028 --- /dev/null +++ b/game/ai/Conversation/ConversationSystem.h @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_CONVERSATION_SYSTEM_H__ +#define __AI_CONVERSATION_SYSTEM_H__ + +#include "../../../idlib/precompiled.h" + +#include "Conversation.h" + +namespace ai { + +class ConversationSystem +{ + // The indexed list of conversations + idList _conversations; + + // The indices of all active conversations + idList _activeConversations; + + // The indices of all finished conversations, ready for removal + idList _dyingConversations; + +public: + // Clears and removes all allocated data + void Clear(); + + /** + * greebo: Initialises this class. This means loading the conversation entities + * containing all conversations for this map. + */ + void Init(idMapFile* mapFile); + + /** + * greebo: Returns the conversation for the given name/index or NULL if not found. + */ + ConversationPtr GetConversation(const idStr& name); + ConversationPtr GetConversation(int index); + + /** + * Returns the numeric index for the given conversation name or -1 if not found. + */ + int GetConversationIndex(const idStr& name); + + /** + * greebo: Returns the number of available conversations in this system. + */ + int GetNumConversations(); + + /** + * greebo: This starts the conversation, after checking whether all conditions are met. + * + * @index: The conversation index. Use GetConversationIndex() to convert a conversation name to an index. + */ + void StartConversation(int index); + + /** + * greebo: Stops the given conversation. This can be called during ProcessConversations() too, + * as the index is only marked for removal next frame. + */ + void EndConversation(int index); + + /** + * greebo: This is the "thinking" routine for conversations which + * remotely controls the participating actors. + */ + void ProcessConversations(); + + // Save/Restore routines + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + +private: + // Helper to load a conversation from an entity's spawnargs + void LoadConversationEntity(idMapEntity* entity); +}; +typedef boost::shared_ptr ConversationSystemPtr; + +} // namespace ai + +#endif /* __AI_CONVERSATION_SYSTEM_H__ */ diff --git a/game/ai/DoorInfo.cpp b/game/ai/DoorInfo.cpp new file mode 100644 index 000000000..185d3be74 --- /dev/null +++ b/game/ai/DoorInfo.cpp @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "DoorInfo.h" + +namespace ai +{ + +DoorInfo::DoorInfo() : + areaNum(-1), + lastTimeSeen(-1), + lastTimeUsed(-1), // grayman #2345 + lastTimeTriedToOpen(-1), + wasOpen(false), + wasLocked(false), + wasBlocked(false) +{} + +void DoorInfo::Save(idSaveGame* savefile) const +{ + savefile->WriteInt(areaNum); + savefile->WriteInt(lastTimeSeen); + savefile->WriteInt(lastTimeTriedToOpen); + savefile->WriteBool(wasOpen); + savefile->WriteBool(wasLocked); + savefile->WriteBool(wasBlocked); + savefile->WriteInt(lastTimeUsed); // grayman #2345 +} + +void DoorInfo::Restore(idRestoreGame* savefile) +{ + savefile->ReadInt(areaNum); + savefile->ReadInt(lastTimeSeen); + savefile->ReadInt(lastTimeTriedToOpen); + savefile->ReadBool(wasOpen); + savefile->ReadBool(wasLocked); + savefile->ReadBool(wasBlocked); + savefile->ReadInt(lastTimeUsed); // grayman #2345 +} + +} // namespace ai diff --git a/game/ai/DoorInfo.h b/game/ai/DoorInfo.h new file mode 100644 index 000000000..ac1dbba62 --- /dev/null +++ b/game/ai/DoorInfo.h @@ -0,0 +1,60 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DOOR_INFO_H__ +#define __DOOR_INFO_H__ + +#include + +namespace ai +{ + +struct DoorInfo +{ + // The AAS area number + int areaNum; + + // When this door was seen the last time (-1 == never) + int lastTimeSeen; + + // When this door was used the last time (-1 == never) + int lastTimeUsed; // grayman #2345 + + // The last time this door was attempted to be opened (-1 == never) + int lastTimeTriedToOpen; + + // Whether this door was open the last time it was seen + bool wasOpen; + + // Whether this door was locked at the last open attempt + bool wasLocked; + + // Whether this door was blocked at the last open attempt + bool wasBlocked; + + DoorInfo(); + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); +}; +typedef boost::shared_ptr DoorInfoPtr; + +} // namespace ai + +#endif /* __DOOR_INFO_H__ */ diff --git a/DarkMod/AI/EAS/ClusterInfo.h b/game/ai/EAS/ClusterInfo.h similarity index 76% rename from DarkMod/AI/EAS/ClusterInfo.h rename to game/ai/EAS/ClusterInfo.h index 9ad3fe669..c6792db91 100644 --- a/DarkMod/AI/EAS/ClusterInfo.h +++ b/game/ai/EAS/ClusterInfo.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_EAS_CLUSTERINFO_H__ #define __AI_EAS_CLUSTERINFO_H__ diff --git a/DarkMod/AI/EAS/EAS.cpp b/game/ai/EAS/EAS.cpp similarity index 96% rename from DarkMod/AI/EAS/EAS.cpp rename to game/ai/EAS/EAS.cpp index b3aa0a815..cbc937d57 100644 --- a/DarkMod/AI/EAS/EAS.cpp +++ b/game/ai/EAS/EAS.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/EAS/EAS.h b/game/ai/EAS/EAS.h similarity index 83% rename from DarkMod/AI/EAS/EAS.h rename to game/ai/EAS/EAS.h index c9c6b7b56..b0d3b4a4d 100644 --- a/DarkMod/AI/EAS/EAS.h +++ b/game/ai/EAS/EAS.h @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_EAS_H__ #define __AI_EAS_H__ #include "../../../idlib/precompiled.h" #include "../../MultiStateMover.h" -#include "../../../game/ai/aas_local.h" +#include "../../../game/ai/AAS_local.h" #include #include #include diff --git a/game/ai/EAS/ElevatorStationInfo.h b/game/ai/EAS/ElevatorStationInfo.h new file mode 100644 index 000000000..af76fd28a --- /dev/null +++ b/game/ai/EAS/ElevatorStationInfo.h @@ -0,0 +1,72 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_EAS_ELEVATOR_STATION_INFO_H__ +#define __AI_EAS_ELEVATOR_STATION_INFO_H__ + +#include +#include +#include "RouteNode.h" +#include "../../Game_local.h" + +namespace eas { + +struct ElevatorStationInfo +{ + idEntityPtr elevator; // The elevator this station is belonging to + idEntityPtr elevatorPosition; // The elevator position entity + int areaNum; // The area number of this elevator station + int clusterNum; // The cluster number of this elevator station + int elevatorNum; // The elevator number this position is belonging to + + ElevatorStationInfo() : + areaNum(-1), + clusterNum(-1), + elevatorNum(-1) + { + elevator = NULL; + elevatorPosition = NULL; + } + + void Save(idSaveGame* savefile) const + { + elevator.Save(savefile); + elevatorPosition.Save(savefile); + + savefile->WriteInt(areaNum); + savefile->WriteInt(clusterNum); + savefile->WriteInt(elevatorNum); + } + + void Restore(idRestoreGame* savefile) + { + elevator.Restore(savefile); + elevatorPosition.Restore(savefile); + + savefile->ReadInt(areaNum); + savefile->ReadInt(clusterNum); + savefile->ReadInt(elevatorNum); + } +}; +typedef boost::shared_ptr ElevatorStationInfoPtr; +typedef std::list ElevatorStationInfoList; + +} // namespace eas + +#endif /* __AI_EAS_ELEVATOR_STATION_INFO_H__ */ diff --git a/game/ai/EAS/RouteInfo.cpp b/game/ai/EAS/RouteInfo.cpp new file mode 100644 index 000000000..dc2b001a7 --- /dev/null +++ b/game/ai/EAS/RouteInfo.cpp @@ -0,0 +1,106 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "RouteInfo.h" + +namespace eas { + +RouteInfo::RouteInfo() : + routeType(ROUTE_TO_CLUSTER), + target(-1) +{} + +RouteInfo::RouteInfo(RouteType type, int targetNum) : + routeType(type), + target(targetNum) +{} + +// Copy constructor +RouteInfo::RouteInfo(const RouteInfo& other) : + routeType(other.routeType), + target(other.target) +{ + // Copy the RouteNodes of the other list, one by one + for (RouteNodeList::const_iterator otherNode = other.routeNodes.begin(); + otherNode != other.routeNodes.end(); ++otherNode) + { + RouteNodePtr newNode(new RouteNode(**otherNode)); + routeNodes.push_back(newNode); + } +} + +bool RouteInfo::operator==(const RouteInfo& other) const +{ + if (routeType == other.routeType && target == other.target && routeNodes.size() == other.routeNodes.size()) + { + for (RouteNodeList::const_iterator i = routeNodes.begin(), j = other.routeNodes.begin(); i != routeNodes.end(); ++i, ++j) + { + if (*i != *j) + { + return false; // RouteNode mismatch + } + } + + return true; // everything matched + } + + return false; // routeType, routeNodes.size() or target mismatched +} + +bool RouteInfo::operator!=(const RouteInfo& other) const +{ + return !operator==(other); +} + +void RouteInfo::Save(idSaveGame* savefile) const +{ + savefile->WriteInt(static_cast(routeType)); + savefile->WriteInt(target); + + savefile->WriteInt(static_cast(routeNodes.size())); + for (RouteNodeList::const_iterator i = routeNodes.begin(); i != routeNodes.end(); ++i) + { + (*i)->Save(savefile); + } +} + +void RouteInfo::Restore(idRestoreGame* savefile) +{ + int temp; + savefile->ReadInt(temp); + routeType = static_cast(temp); + savefile->ReadInt(target); + + int num; + savefile->ReadInt(num); + routeNodes.clear(); + for (int i = 0; i < num; i++) + { + RouteNodePtr node(new RouteNode); + node->Restore(savefile); + routeNodes.push_back(node); + } +} + +} // namespace eas diff --git a/game/ai/EAS/RouteInfo.h b/game/ai/EAS/RouteInfo.h new file mode 100644 index 000000000..5ff222c06 --- /dev/null +++ b/game/ai/EAS/RouteInfo.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_EAS_ROUTEINFO_H__ +#define __AI_EAS_ROUTEINFO_H__ + +#include +#include +#include "boost/shared_ptr.hpp" +#include "RouteNode.h" + +namespace eas { + +enum RouteType { + ROUTE_DUMMY = 0, // placeholder + ROUTE_TO_AREA, // a route to an AAS area + ROUTE_TO_CLUSTER, // a route to an AAS cluster + NUM_ROUTE_TYPES, +}; + +// A route info contains information of how to get to a specific target +struct RouteInfo +{ + RouteType routeType; // ROUTE_TO_AREA or ROUTE_TO_CLUSTER, ... + int target; // either the target AREA or the target CLUSTER number, depending on routeType + RouteNodeList routeNodes; // contains the actual route node chain (WALK, USE_ELEVATOR, WALK, etc.) + + // Default constructor + RouteInfo(); + + // Specialised constructor + RouteInfo(RouteType type, int targetNum); + + // Copy constructor + RouteInfo(const RouteInfo& other); + + bool operator==(const RouteInfo& other) const; + bool operator!=(const RouteInfo& other) const; + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); +}; +typedef boost::shared_ptr RouteInfoPtr; +typedef std::list RouteInfoList; +typedef std::vector RouteInfoListVector; + +} // namespace eas + +#endif /* __AI_EAS_ROUTEINFO_H__ */ diff --git a/game/ai/EAS/RouteNode.cpp b/game/ai/EAS/RouteNode.cpp new file mode 100644 index 000000000..3f6e6a0f4 --- /dev/null +++ b/game/ai/EAS/RouteNode.cpp @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "RouteNode.h" + +namespace eas { + +RouteNode::RouteNode() : + type(ACTION_WALK), + toArea(0), + toCluster(0), + elevator(-1), + elevatorStation(-1) +{} + +RouteNode::RouteNode(ActionType t, int goalArea, int goalCluster, int elevatorNum, int elevatorStationNum) : + type(t), + toArea(goalArea), + toCluster(goalCluster), + elevator(elevatorNum), + elevatorStation(elevatorStationNum) +{} + +// Copy constructor +RouteNode::RouteNode(const RouteNode& other) : + type(other.type), + toArea(other.toArea), + toCluster(other.toCluster), + elevator(other.elevator), + elevatorStation(other.elevatorStation) +{} + +bool RouteNode::operator==(const RouteNode& other) const +{ + return (type == other.type && toArea == other.toArea && toCluster == other.toCluster && + elevator == other.elevator && elevatorStation == other.elevatorStation); +} + +bool RouteNode::operator!=(const RouteNode& other) const +{ + return !operator==(other); +} + +void RouteNode::Save(idSaveGame* savefile) const +{ + savefile->WriteInt(static_cast(type)); + savefile->WriteInt(toArea); + savefile->WriteInt(toCluster); + savefile->WriteInt(elevator); + savefile->WriteInt(elevatorStation); +} + +void RouteNode::Restore(idRestoreGame* savefile) +{ + int temp; + savefile->ReadInt(temp); + type = static_cast(temp); + savefile->ReadInt(toArea); + savefile->ReadInt(toCluster); + savefile->ReadInt(elevator); + savefile->ReadInt(elevatorStation); +} + +} // namespace eas diff --git a/game/ai/EAS/RouteNode.h b/game/ai/EAS/RouteNode.h new file mode 100644 index 000000000..22ede3032 --- /dev/null +++ b/game/ai/EAS/RouteNode.h @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_EAS_ROUTENODE_H__ +#define __AI_EAS_ROUTENODE_H__ + +#include +#include + +namespace eas { + +enum ActionType { + ACTION_WALK = 0, // AI just needs to walk to the target + ACTION_USE_ELEVATOR, // AI needs to use an elevator + NUM_ACTIONS, +}; + +struct RouteNode +{ + ActionType type; // what needs to be done in this route section (walk?, use elevator?) + int toArea; // the target AAS area number + int toCluster; // the target AAS cluster number + int elevator; // the elevator number (is -1 if no elevator to be used in this node) + int elevatorStation; // The elevator station number of this position (-1 if unused) + + // Default constructor + RouteNode(); + + // Specialised constructor + RouteNode(ActionType t, int goalArea, int goalCluster, int elevatorNum = -1, int elevatorStationNum = -1); + + // Copy constructor + RouteNode(const RouteNode& other); + + bool operator==(const RouteNode& other) const; + bool operator!=(const RouteNode& other) const; + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); +}; +typedef boost::shared_ptr RouteNodePtr; +typedef std::list RouteNodeList; + +} // namespace eas + +#endif /* __AI_EAS_ROUTENODE_H__ */ diff --git a/DarkMod/AI/Library.h b/game/ai/Library.h similarity index 81% rename from DarkMod/AI/Library.h rename to game/ai/Library.h index 0ddd4ac04..c5b86a594 100644 --- a/DarkMod/AI/Library.h +++ b/game/ai/Library.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_LIBRARY_H__ #define __AI_LIBRARY_H__ diff --git a/DarkMod/AI/Memory.cpp b/game/ai/Memory.cpp similarity index 94% rename from DarkMod/AI/Memory.cpp rename to game/ai/Memory.cpp index e34223779..7c501e29b 100644 --- a/DarkMod/AI/Memory.cpp +++ b/game/ai/Memory.cpp @@ -1,19 +1,29 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); #include "Memory.h" -#include "../../game/ai/ai.h" +#include "AI.h" namespace ai { diff --git a/DarkMod/AI/Memory.h b/game/ai/Memory.h similarity index 94% rename from DarkMod/AI/Memory.h rename to game/ai/Memory.h index bbe254099..b7b54e9c6 100644 --- a/DarkMod/AI/Memory.h +++ b/game/ai/Memory.h @@ -1,22 +1,30 @@ -/*************************************************************************** - * - * vim:ts=4:sw=4:cindent - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_MEMORY_H__ #define __AI_MEMORY_H__ -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #include "../BinaryFrobMover.h" #include "../FrobDoor.h" #include "DoorInfo.h" -#include "../../game/ai/ai.h" +#include "AI.h" namespace ai { diff --git a/DarkMod/AI/Mind.cpp b/game/ai/Mind.cpp similarity index 91% rename from DarkMod/AI/Mind.cpp rename to game/ai/Mind.cpp index f382fad79..d12eec1c9 100644 --- a/DarkMod/AI/Mind.cpp +++ b/game/ai/Mind.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/Mind.h b/game/ai/Mind.h similarity index 82% rename from DarkMod/AI/Mind.h rename to game/ai/Mind.h index 2d95281bc..b667a3fd1 100644 --- a/DarkMod/AI/Mind.h +++ b/game/ai/Mind.h @@ -1,18 +1,28 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_MIND_H__ #define __AI_MIND_H__ #include "Memory.h" #include "States/State.h" -#include "Queue.h" +#include "./Queue.h" namespace ai { diff --git a/game/ai/MoveState.cpp b/game/ai/MoveState.cpp index b9289b9fc..92bc461c4 100644 --- a/game/ai/MoveState.cpp +++ b/game/ai/MoveState.cpp @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../../idlib/precompiled.h" #include "MoveState.h" diff --git a/game/ai/MoveState.h b/game/ai/MoveState.h index 689d112c8..e48d22ceb 100644 --- a/game/ai/MoveState.h +++ b/game/ai/MoveState.h @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_MOVESTATE_H__ #define __AI_MOVESTATE_H__ diff --git a/DarkMod/AI/MovementSubsystem.cpp b/game/ai/MovementSubsystem.cpp similarity index 97% rename from DarkMod/AI/MovementSubsystem.cpp rename to game/ai/MovementSubsystem.cpp index c1bdf6268..b7758756a 100644 --- a/DarkMod/AI/MovementSubsystem.cpp +++ b/game/ai/MovementSubsystem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/MovementSubsystem.h b/game/ai/MovementSubsystem.h similarity index 82% rename from DarkMod/AI/MovementSubsystem.h rename to game/ai/MovementSubsystem.h index 78f13eb6f..d9f5c160e 100644 --- a/DarkMod/AI/MovementSubsystem.h +++ b/game/ai/MovementSubsystem.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_MOVEMENTSUBSYSTEM_H__ #define __AI_MOVEMENTSUBSYSTEM_H__ diff --git a/game/ai/Queue.h b/game/ai/Queue.h new file mode 100644 index 000000000..f780dbe62 --- /dev/null +++ b/game/ai/Queue.h @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STATEQUEUE_H__ +#define __STATEQUEUE_H__ + +#include "../DarkModGlobals.h" + +#include +#include + +#include "Library.h" + +namespace ai +{ + +/** + * greebo: Templated queue containing shared ptrs of a certain type (Tasks and States). + * + * This is not a priority queue, no sorting happens. It derives from the std::list + * class, as this implements most of the methods we need for this queue. + * + * The interface is extended by a few convenience methods. + * + * The Save/Restore methods work together with the templated Library<> class. + */ +template +class Queue : + public std::list< boost::shared_ptr > +{ + // Parent list type + typedef std::list > ListType; + + // greebo: Don't define data members in a class deriving from an STL container + // (std::list destructor is non-virtual) + + // Shortcut typedef + typedef boost::shared_ptr ElementPtr; + +public: + /** + * Returns the entire contents of this queue as a string, for debugging purposes. + * Relies on the Elements having a member method GetName() + */ + const std::string DebuggingInfo() const + { + std::stringstream debugInfo; + for (typename ListType::const_iterator i = ListType::begin(); + i != ListType::end(); + ++i) + { + debugInfo << (*i)->GetName(); + debugInfo << "\n"; + } + return debugInfo.str(); + } + + /** + * Save this data structure to a savefile + */ + void Save(idSaveGame *savefile) const + { + savefile->WriteInt(ListType::size()); + for (typename ListType::const_iterator i = ListType::begin(); + i != ListType::end(); + ++i) + { + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Saving element %s.\r", (*i)->GetName().c_str()); + savefile->WriteString((*i)->GetName().c_str()); + + // Write the Element data into the savefile + (*i)->Save(savefile); + } + } + + /** + * Restore this data structure from a savefile + */ + void Restore(idRestoreGame *savefile) + { + // Clear the queue before restoring + ListType::clear(); + + int elements; + savefile->ReadInt(elements); + for (int i = 0; i < elements; i++) + { + idStr str; + savefile->ReadString(str); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Restoring task %s.\r", str.c_str()); + + ElementPtr element = Library::Instance().CreateInstance(str.c_str()); + assert(element != NULL); // the element must be found + + // Restore the element's state + element->Restore(savefile); + + // Add the element to the queue + push_back(element); + } + } +}; + +// Convenience typedefs +class State; +typedef Queue StateQueue; + +class Task; +typedef Queue TaskQueue; + +} // namespace ai + +#endif /* !__STATEQUEUE_H__ */ diff --git a/DarkMod/AI/States/AgitatedSearchingState.cpp b/game/ai/States/AgitatedSearchingState.cpp similarity index 82% rename from DarkMod/AI/States/AgitatedSearchingState.cpp rename to game/ai/States/AgitatedSearchingState.cpp index f1bb2a269..9e34f7502 100644 --- a/DarkMod/AI/States/AgitatedSearchingState.cpp +++ b/game/ai/States/AgitatedSearchingState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/AgitatedSearchingState.h b/game/ai/States/AgitatedSearchingState.h new file mode 100644 index 000000000..8ef242c02 --- /dev/null +++ b/game/ai/States/AgitatedSearchingState.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_AGITATED_SEARCHING_STATE_H__ +#define __AI_AGITATED_SEARCHING_STATE_H__ + +#include "State.h" +#include "SearchingState.h" + +/** +* greebo: AgitatedSearchingState is one alert index above SearchingState. +* +* Apart from a few minor things this is similar to the base class SearchingState. +* +* See the base class for documentation. +*/ + +namespace ai +{ + +#define STATE_AGITATED_SEARCHING "AgitatedSearching" + +class AgitatedSearchingState : + public SearchingState +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); + +protected: + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); + + virtual void CalculateAlertDecreaseRate(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_AGITATED_SEARCHING_STATE_H__ */ diff --git a/DarkMod/AI/States/AgitatedSearchingStateLanternBot.cpp b/game/ai/States/AgitatedSearchingStateLanternBot.cpp similarity index 84% rename from DarkMod/AI/States/AgitatedSearchingStateLanternBot.cpp rename to game/ai/States/AgitatedSearchingStateLanternBot.cpp index cd5eda784..fad65b01d 100644 --- a/DarkMod/AI/States/AgitatedSearchingStateLanternBot.cpp +++ b/game/ai/States/AgitatedSearchingStateLanternBot.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/AgitatedSearchingStateLanternBot.h b/game/ai/States/AgitatedSearchingStateLanternBot.h new file mode 100644 index 000000000..c9846f059 --- /dev/null +++ b/game/ai/States/AgitatedSearchingStateLanternBot.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _AGITATED_SEARCHING_STATE_LANTERN_BOT_H_ +#define _AGITATED_SEARCHING_STATE_LANTERN_BOT_H_ + +#include "../AI.h" +#include "AgitatedSearchingState.h" + +namespace ai +{ + +#define STATE_AGITATED_SEARCHING_LANTERN_BOT "AgitatedSearchingLanternBot" + +class AgitatedSearchingStateLanternBot : + public AgitatedSearchingState +{ +protected: + idVec3 _curAlertPos; + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); + + // Override base class signal + virtual void OnMovementBlocked(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + +protected: + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); + + void MoveTowardAlertPos(idAI* owner); +}; + +} // namespace + +#endif diff --git a/DarkMod/AI/States/AlertIdleState.cpp b/game/ai/States/AlertIdleState.cpp similarity index 83% rename from DarkMod/AI/States/AlertIdleState.cpp rename to game/ai/States/AlertIdleState.cpp index 7b4b2b61e..12a51372c 100644 --- a/DarkMod/AI/States/AlertIdleState.cpp +++ b/game/ai/States/AlertIdleState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/AlertIdleState.h b/game/ai/States/AlertIdleState.h new file mode 100644 index 000000000..e6e0ea097 --- /dev/null +++ b/game/ai/States/AlertIdleState.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_ALERT_IDLE_STATE_H__ +#define __AI_ALERT_IDLE_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_ALERT_IDLE "AlertIdle" + +/** + * angua: This is a specialisation of the IdleState. If the AI + * has been highly alerted during its lifetime, it doesn't return + * into the regular IdleState, but this one. + */ +class AlertIdleState : + public IdleState +{ + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + // Note: we do not call IdleState::Init + virtual void Init(idAI* owner); + + // Think is inherited from IdleState::Think + + static StatePtr CreateInstance(); + +protected: + // Returns the initial idle bark sound, depending on the alert level + // and the current state of mind + virtual idStr GetInitialIdleBark(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_ALERT_IDLE_STATE_H__ */ diff --git a/DarkMod/AI/States/BlindedState.cpp b/game/ai/States/BlindedState.cpp similarity index 78% rename from DarkMod/AI/States/BlindedState.cpp rename to game/ai/States/BlindedState.cpp index 1307cfb1b..bfb1cf189 100644 --- a/DarkMod/AI/States/BlindedState.cpp +++ b/game/ai/States/BlindedState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/BlindedState.h b/game/ai/States/BlindedState.h new file mode 100644 index 000000000..c6b7bb946 --- /dev/null +++ b/game/ai/States/BlindedState.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_BLINDED_STATE_H__ +#define __AI_BLINDED_STATE_H__ + +#include "../AI.h" +#include "State.h" + +namespace ai +{ + +#define STATE_BLINDED "Blinded" + +class BlindedState : + public State +{ +private: + int _endTime; + float _oldAcuity; // to restore visual acuity + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_BLINDED_STATE_H__ */ diff --git a/DarkMod/AI/States/CombatState.cpp b/game/ai/States/CombatState.cpp similarity index 93% rename from DarkMod/AI/States/CombatState.cpp rename to game/ai/States/CombatState.cpp index 1614f7b45..9f48c18bf 100644 --- a/DarkMod/AI/States/CombatState.cpp +++ b/game/ai/States/CombatState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/CombatState.h b/game/ai/States/CombatState.h new file mode 100644 index 000000000..7a5f2f647 --- /dev/null +++ b/game/ai/States/CombatState.h @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_COMBAT_STATE_H__ +#define __AI_COMBAT_STATE_H__ + +#include "../AI.h" +#include "State.h" + +namespace ai +{ + +#define STATE_COMBAT "Combat" + +class CombatState : + public State +{ +protected: + // The AI's enemy + idEntityPtr _enemy; + int _criticalHealth; + bool _meleePossible; + bool _rangedPossible; + + ECombatType _combatType; + + // When end time is set, the state is just waiting to be finished + // and is not performing any routines anymore + int _endTime; + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Override the alert functions + virtual void OnTactileAlert(idEntity* tactEnt); + virtual void OnVisualAlert(idActor* enemy); + virtual void OnAudioAlert(); + + virtual void OnPersonEncounter(idEntity* stimSource, idAI* owner); + virtual void OnFailedKnockoutBlow(idEntity* attacker, const idVec3& direction, bool hitHead); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); + +protected: + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); + + // Checks enemy status (dead, visible, not an enemy anymore). + // Returns false if the enemy is not applicable anymore and the state has ended + bool CheckEnemyStatus(idActor* enemy, idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_COMBAT_STATE_H__ */ diff --git a/DarkMod/AI/States/ConversationState.cpp b/game/ai/States/ConversationState.cpp similarity index 96% rename from DarkMod/AI/States/ConversationState.cpp rename to game/ai/States/ConversationState.cpp index d8657a13e..8cc99ce1b 100644 --- a/DarkMod/AI/States/ConversationState.cpp +++ b/game/ai/States/ConversationState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -141,7 +151,7 @@ void ConversationState::Init(idAI* owner) // Gets called each time the mind is thinking void ConversationState::Think(idAI* owner) { - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); UpdateAlertLevel(); @@ -737,7 +747,7 @@ void ConversationState::OnPersonEncounter(idEntity* stimSource, idAI* owner) { assert(stimSource != NULL && owner != NULL); // must be fulfilled - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); if (!stimSource->IsType(idActor::Type)) return; // No Actor, quit diff --git a/DarkMod/AI/States/ConversationState.h b/game/ai/States/ConversationState.h similarity index 79% rename from DarkMod/AI/States/ConversationState.h rename to game/ai/States/ConversationState.h index f726a5666..aae9d2d3a 100644 --- a/DarkMod/AI/States/ConversationState.h +++ b/game/ai/States/ConversationState.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_CONVERSATION_STATE_H__ #define __AI_CONVERSATION_STATE_H__ diff --git a/DarkMod/AI/States/DeadState.cpp b/game/ai/States/DeadState.cpp similarity index 84% rename from DarkMod/AI/States/DeadState.cpp rename to game/ai/States/DeadState.cpp index ada30da93..090080cc1 100644 --- a/DarkMod/AI/States/DeadState.cpp +++ b/game/ai/States/DeadState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/DeadState.h b/game/ai/States/DeadState.h new file mode 100644 index 000000000..1603605c8 --- /dev/null +++ b/game/ai/States/DeadState.h @@ -0,0 +1,55 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_DEAD_STATE_H__ +#define __AI_DEAD_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_DEAD "Dead" + +class DeadState : + public State +{ +private: + bool _waitingForDeath; + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_DEAD_STATE_H__ */ diff --git a/game/ai/States/EmergeFromCoverState.cpp b/game/ai/States/EmergeFromCoverState.cpp new file mode 100644 index 000000000..2d5dc9cc9 --- /dev/null +++ b/game/ai/States/EmergeFromCoverState.cpp @@ -0,0 +1,102 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "EmergeFromCoverState.h" +#include "../Memory.h" +#include "../Tasks/MoveToCoverTask.h" +#include "../Tasks/WaitTask.h" +#include "../Tasks/MoveToPositionTask.h" +#include "../Tasks/RandomHeadturnTask.h" +#include "LostTrackOfEnemyState.h" +#include "../Library.h" + +namespace ai +{ + +// Get the name of this state +const idStr& EmergeFromCoverState::GetName() const +{ + static idStr _name(STATE_EMERGE_FROM_COVER); + return _name; +} + +void EmergeFromCoverState::Init(idAI* owner) +{ + // Init base class first + State::Init(owner); + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("EmergeFromCoverState initialised.\r"); + assert(owner); + + // Shortcut reference + Memory& memory = owner->GetMemory(); + + // Fill the subsystems with their tasks + owner->GetSubsystem(SubsysCommunication)->ClearTasks(); + owner->actionSubsystem->ClearTasks(); + + owner->movementSubsystem->ClearTasks(); + owner->movementSubsystem->QueueTask( + TaskPtr(new MoveToPositionTask(memory.positionBeforeTakingCover)) + ); +} + +// Gets called each time the mind is thinking +void EmergeFromCoverState::Think(idAI* owner) +{ + Memory& memory = owner->GetMemory(); + + // Let the AI check its senses + owner->PerformVisualScan(); + + if (owner->AI_MOVE_DONE + && !owner->AI_DEST_UNREACHABLE + && (owner->GetPhysics()->GetOrigin() - memory.positionBeforeTakingCover).LengthFast() < 50) + { + // Reached position before taking cover, look for enemy + // Turn to last visible enemy position + owner->TurnToward(owner->lastVisibleEnemyPos); + owner->Event_LookAtPosition(owner->lastVisibleEnemyPos,1); + + owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY); + } + else if (owner->AI_DEST_UNREACHABLE) + { + // Can't move back to position before taking cover + owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY); + } +} + +StatePtr EmergeFromCoverState::CreateInstance() +{ + return StatePtr(new EmergeFromCoverState); +} + +// Register this state with the StateLibrary +StateLibrary::Registrar emergeFromCoverStateRegistrar( + STATE_EMERGE_FROM_COVER, // Task Name + StateLibrary::CreateInstanceFunc(&EmergeFromCoverState::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/States/EmergeFromCoverState.h b/game/ai/States/EmergeFromCoverState.h new file mode 100644 index 000000000..e2530da2c --- /dev/null +++ b/game/ai/States/EmergeFromCoverState.h @@ -0,0 +1,48 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_EMERGE_FROM_COVER_STATE_H__ +#define __AI_EMERGE_FROM_COVER_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_EMERGE_FROM_COVER "EmergeFromCover" + +class EmergeFromCoverState : + public State +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_EMERGE_FROM_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/ExamineRopeState.cpp b/game/ai/States/ExamineRopeState.cpp similarity index 92% rename from DarkMod/AI/States/ExamineRopeState.cpp rename to game/ai/States/ExamineRopeState.cpp index 8b24f7cbd..ff81bdffa 100644 --- a/DarkMod/AI/States/ExamineRopeState.cpp +++ b/game/ai/States/ExamineRopeState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -50,7 +60,7 @@ void ExamineRopeState::Wrapup(idAI* owner) void ExamineRopeState::Init(idAI* owner) { - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); State::Init(owner); diff --git a/game/ai/States/ExamineRopeState.h b/game/ai/States/ExamineRopeState.h new file mode 100644 index 000000000..ff0e7a014 --- /dev/null +++ b/game/ai/States/ExamineRopeState.h @@ -0,0 +1,86 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_EXAMINE_ROPE_H__ +#define __AI_EXAMINE_ROPE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_EXAMINE_ROPE "ExamineRope" + +class ExamineRopeState : + public State +{ +private: + // Default constructor + ExamineRopeState(); + + idEntityPtr _rope; + idVec3 _point; // the interesting point on the rope + + // time to wait before proceeding with a state + int _waitEndTime; + + idVec3 _examineSpot; // where to stand to examine the rope + + enum EExamineRopeState + { + EStateSitting, + EStateStarting, + EStateApproaching, + EStateTurningToward, + EStateExamineTop, + EStateExamineBottom, + EStateFinal + } _examineRopeState; + +public: + // Constructor using rope and examination point as input + ExamineRopeState(idAFEntity_Generic* rope, idVec3 point); + + // Get the name of this state + virtual const idStr& GetName() const; + + virtual void Wrapup(idAI* owner); + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Look at top of rope + void StartExaminingTop(idAI* owner); + + // Look at bottom of rope + void StartExaminingBottom(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_EXAMINE_ROPE_H__ */ diff --git a/DarkMod/AI/States/FailedKnockoutState.cpp b/game/ai/States/FailedKnockoutState.cpp similarity index 82% rename from DarkMod/AI/States/FailedKnockoutState.cpp rename to game/ai/States/FailedKnockoutState.cpp index a5c9361a0..77953dfd3 100644 --- a/DarkMod/AI/States/FailedKnockoutState.cpp +++ b/game/ai/States/FailedKnockoutState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/FailedKnockoutState.h b/game/ai/States/FailedKnockoutState.h new file mode 100644 index 000000000..d6bacd73d --- /dev/null +++ b/game/ai/States/FailedKnockoutState.h @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_FAILED_KNOCK_OUT_STATE_H__ +#define __AI_FAILED_KNOCK_OUT_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_FAILED_KNOCKED_OUT "FailedKnockout" + +class FailedKnockoutState : + public State +{ + int _stateEndTime; + int _allowEndTime; + idEntity* _attacker; + idVec3 _attackDirection; + bool _hitHead; + + FailedKnockoutState(); + +public: + FailedKnockoutState(idEntity* attacker, const idVec3& attackDirection, bool hitHead); + + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_FAILED_KNOCK_OUT_STATE_H__ */ diff --git a/DarkMod/AI/States/FleeDoneState.cpp b/game/ai/States/FleeDoneState.cpp similarity index 86% rename from DarkMod/AI/States/FleeDoneState.cpp rename to game/ai/States/FleeDoneState.cpp index bdc0725b6..af9da0fd2 100644 --- a/DarkMod/AI/States/FleeDoneState.cpp +++ b/game/ai/States/FleeDoneState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -43,7 +53,7 @@ void FleeDoneState::Init(idAI* owner) assert(owner); // Shortcut reference - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); // greebo: At this point we should be at a presumably safe place, // start looking for allies @@ -115,7 +125,7 @@ void FleeDoneState::Think(idAI* owner) owner->SetTurnRate(_oldTurnRate); owner->TurnToward(friendlyAI->GetPhysics()->GetOrigin()); - float distanceToFriend = (friendlyAI->GetPhysics()->GetOrigin() - owner->GetPhysics()->GetOrigin()).LengthFast(); + //float distanceToFriend = (friendlyAI->GetPhysics()->GetOrigin() - owner->GetPhysics()->GetOrigin()).LengthFast(); // Cry for help // Create a new help message diff --git a/game/ai/States/FleeDoneState.h b/game/ai/States/FleeDoneState.h new file mode 100644 index 000000000..2c611fc53 --- /dev/null +++ b/game/ai/States/FleeDoneState.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_FLEE_DONE_H__ +#define __AI_FLEE_DONE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_FLEE_DONE "FleeDone" + +class FleeDoneState : + public State +{ +private: + float _oldTurnRate; + int _turnEndTime; + bool _searchForFriendDone; + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + void OnPersonEncounter(idEntity* stimSource, idAI* owner); + + virtual bool CheckAlertLevel(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_FLEE_DONE_H__ */ diff --git a/DarkMod/AI/States/FleeState.cpp b/game/ai/States/FleeState.cpp similarity index 80% rename from DarkMod/AI/States/FleeState.cpp rename to game/ai/States/FleeState.cpp index 96924bbb4..884a53534 100644 --- a/DarkMod/AI/States/FleeState.cpp +++ b/game/ai/States/FleeState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/FleeState.h b/game/ai/States/FleeState.h new file mode 100644 index 000000000..5d2d6f232 --- /dev/null +++ b/game/ai/States/FleeState.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_FLEE_H__ +#define __AI_FLEE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_FLEE "Flee" + +class FleeState : + public State +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + virtual void OnFailedKnockoutBlow(idEntity* attacker, const idVec3& direction, bool hitHead); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_FLEE_H__ */ diff --git a/DarkMod/AI/States/IdleSleepState.cpp b/game/ai/States/IdleSleepState.cpp similarity index 83% rename from DarkMod/AI/States/IdleSleepState.cpp rename to game/ai/States/IdleSleepState.cpp index 1d95fcfe4..5da34a767 100644 --- a/DarkMod/AI/States/IdleSleepState.cpp +++ b/game/ai/States/IdleSleepState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/IdleSleepState.h b/game/ai/States/IdleSleepState.h new file mode 100644 index 000000000..e7daaf84b --- /dev/null +++ b/game/ai/States/IdleSleepState.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_IDLE_SLEEP_STATE_H__ +#define __AI_IDLE_SLEEP_STATE_H__ + +#include "State.h" +#include "IdleState.h" + +namespace ai +{ + +#define STATE_IDLE_SLEEP "IdleSleep" + +class IdleSleepState : + public IdleState +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); + + /** + * ishtvan: Called when targets are changed + * Re-initializes to catch new path corners + **/ + virtual void OnChangeTarget(idAI *owner); + +protected: + + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); + +}; + +} // namespace ai + +#endif /* __AI_IDLE_SLEEP_STATE_H__ */ diff --git a/DarkMod/AI/States/IdleState.cpp b/game/ai/States/IdleState.cpp similarity index 92% rename from DarkMod/AI/States/IdleState.cpp rename to game/ai/States/IdleState.cpp index 5ee6a04a3..d44c3765d 100644 --- a/DarkMod/AI/States/IdleState.cpp +++ b/game/ai/States/IdleState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/IdleState.h b/game/ai/States/IdleState.h new file mode 100644 index 000000000..39b6d6c87 --- /dev/null +++ b/game/ai/States/IdleState.h @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_IDLE_STATE_H__ +#define __AI_IDLE_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_IDLE "Idle" + +class IdleState : + public State +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); + + /** + * ishtvan: Called when targets are changed + * Re-initializes to catch new path corners + **/ + virtual void OnChangeTarget(idAI *owner); + +protected: + + bool _startSitting; + bool _startSleeping; + + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); + + // Returns the initial idle bark sound, depending on the alert level + // and the current state of mind + virtual idStr GetInitialIdleBark(idAI* owner); + + virtual void InitialiseMovement(idAI* owner); + virtual void InitialiseCommunication(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_IDLE_STATE_H__ */ diff --git a/DarkMod/AI/States/KnockedOutState.cpp b/game/ai/States/KnockedOutState.cpp similarity index 78% rename from DarkMod/AI/States/KnockedOutState.cpp rename to game/ai/States/KnockedOutState.cpp index 1b5edd6e1..7ba105d46 100644 --- a/DarkMod/AI/States/KnockedOutState.cpp +++ b/game/ai/States/KnockedOutState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/KnockedOutState.h b/game/ai/States/KnockedOutState.h new file mode 100644 index 000000000..aa7a99490 --- /dev/null +++ b/game/ai/States/KnockedOutState.h @@ -0,0 +1,53 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_KNOCKED_OUT_STATE_H__ +#define __AI_KNOCKED_OUT_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_KNOCKED_OUT "KnockedOut" + +class KnockedOutState : + public State +{ + bool _waitingForKnockout; +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_KNOCKED_OUT_STATE_H__ */ diff --git a/game/ai/States/LostTrackOfEnemyState.cpp b/game/ai/States/LostTrackOfEnemyState.cpp new file mode 100644 index 000000000..525772f6e --- /dev/null +++ b/game/ai/States/LostTrackOfEnemyState.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "LostTrackOfEnemyState.h" +#include "../Memory.h" +#include "../Tasks/SingleBarkTask.h" +#include "../Library.h" + +namespace ai +{ + +// Get the name of this state +const idStr& LostTrackOfEnemyState::GetName() const +{ + static idStr _name(STATE_LOST_TRACK_OF_ENEMY); + return _name; +} + +void LostTrackOfEnemyState::Init(idAI* owner) +{ + // Init base class first + State::Init(owner); + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("LostTrackOfEnemyState initialised.\r"); + assert(owner); + + // Shortcut reference + Memory& memory = owner->GetMemory(); + + owner->SetAlertLevel((owner->thresh_5 + owner->thresh_4) * 0.5); + + // Draw weapon, if we haven't already + owner->DrawWeapon(); + + // Setup the search parameters + memory.alertPos = owner->lastVisibleReachableEnemyPos; + memory.alertRadius = LOST_ENEMY_ALERT_RADIUS; + memory.alertSearchVolume = LOST_ENEMY_SEARCH_VOLUME; + memory.alertSearchExclusionVolume.Zero(); + + memory.alertedDueToCommunication = false; + memory.stimulusLocationItselfShouldBeSearched = true; + + // Forget about the enemy, prevent UpdateEnemyPosition from "cheating". + owner->ClearEnemy(); + + // Enqueue a lost track of enemy bark + owner->commSubsystem->AddCommTask( + CommunicationTaskPtr(new SingleBarkTask("snd_lostTrackOfEnemy")) + ); + + // For now, clear the action tasks and movement tasks + owner->actionSubsystem->ClearTasks(); + owner->movementSubsystem->ClearTasks(); + + owner->GetMind()->EndState(); +} + +// Gets called each time the mind is thinking +void LostTrackOfEnemyState::Think(idAI* owner) +{ + +} + +StatePtr LostTrackOfEnemyState::CreateInstance() +{ + return StatePtr(new LostTrackOfEnemyState); +} + +// Register this state with the StateLibrary +StateLibrary::Registrar lostTrackOfEnemyStateRegistrar( + STATE_LOST_TRACK_OF_ENEMY, // Task Name + StateLibrary::CreateInstanceFunc(&LostTrackOfEnemyState::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/States/LostTrackOfEnemyState.h b/game/ai/States/LostTrackOfEnemyState.h new file mode 100644 index 000000000..4f099e6b0 --- /dev/null +++ b/game/ai/States/LostTrackOfEnemyState.h @@ -0,0 +1,48 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_LOST_TRACK_OF_ENEMY_STATE_H__ +#define __AI_LOST_TRACK_OF_ENEMY_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_LOST_TRACK_OF_ENEMY "LostTrackOfEnemy" + +class LostTrackOfEnemyState : + public State +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_LOST_TRACK_OF_ENEMY_STATE_H__ */ diff --git a/DarkMod/AI/States/ObservantState.cpp b/game/ai/States/ObservantState.cpp similarity index 84% rename from DarkMod/AI/States/ObservantState.cpp rename to game/ai/States/ObservantState.cpp index d4c20517f..8cb1a0701 100644 --- a/DarkMod/AI/States/ObservantState.cpp +++ b/game/ai/States/ObservantState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/ObservantState.h b/game/ai/States/ObservantState.h new file mode 100644 index 000000000..a11442ff2 --- /dev/null +++ b/game/ai/States/ObservantState.h @@ -0,0 +1,53 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_OBSERVANT_STATE_H__ +#define __AI_OBSERVANT_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_OBSERVANT "Observant" + +class ObservantState : + public State +{ + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); + +protected: + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_OBSERVANT_STATE_H__ */ diff --git a/game/ai/States/PainState.cpp b/game/ai/States/PainState.cpp new file mode 100644 index 000000000..d176d71e4 --- /dev/null +++ b/game/ai/States/PainState.cpp @@ -0,0 +1,112 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "PainState.h" +#include "../Tasks/SingleBarkTask.h" +#include "../Memory.h" +#include "../Library.h" + +namespace ai +{ + +// Get the name of this state +const idStr& PainState::GetName() const +{ + static idStr _name(STATE_PAIN); + return _name; +} + +void PainState::Init(idAI* owner) +{ + // Init base class first + State::Init(owner); + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("PainState initialised.\r"); + assert(owner); + + Memory& memory = owner->GetMemory(); + + // Play the animation + owner->SetAnimState(ANIMCHANNEL_TORSO, "Torso_Pain", 4); + owner->SetAnimState(ANIMCHANNEL_LEGS, "Legs_Pain", 4); + + owner->SetWaitState(ANIMCHANNEL_TORSO, "pain"); + owner->SetWaitState(ANIMCHANNEL_LEGS, "pain"); + + // Set end time + _stateEndTime = gameLocal.time + 5000; + + // Set the alert position 50 units in the attacking direction + memory.alertPos = owner->GetPhysics()->GetOrigin(); + + // Do a single bark and assemble an AI message + CommMessagePtr message = CommMessagePtr(new CommMessage( + CommMessage::DetectedEnemy_CommType, + owner, NULL, // from this AI to anyone + NULL, + memory.alertPos + )); + + owner->commSubsystem->AddCommTask( + CommunicationTaskPtr(new SingleBarkTask("snd_pain_large", message)) + ); +} + +// Gets called each time the mind is thinking +void PainState::Think(idAI* owner) +{ + if (gameLocal.time >= _stateEndTime || + idStr(owner->WaitState(ANIMCHANNEL_TORSO)) != "pain") + { + // End this state + owner->GetMind()->EndState(); + } +} + +// Save/Restore methods +void PainState::Save(idSaveGame* savefile) const +{ + State::Save(savefile); + + savefile->WriteInt(_stateEndTime); +} + +void PainState::Restore(idRestoreGame* savefile) +{ + State::Restore(savefile); + savefile->ReadInt(_stateEndTime); +} + +StatePtr PainState::CreateInstance() +{ + return StatePtr(new PainState); +} + +// Register this state with the StateLibrary +StateLibrary::Registrar painStateRegistrar( + STATE_PAIN, // Task Name + StateLibrary::CreateInstanceFunc(&PainState::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/States/PainState.h b/game/ai/States/PainState.h new file mode 100644 index 000000000..dbbff785e --- /dev/null +++ b/game/ai/States/PainState.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PAIN_STATE_H__ +#define __AI_PAIN_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_PAIN "Pain" + +// An intermediate state, playing the pain anim and alerting the AI afterwards +class PainState : + public State +{ + int _stateEndTime; + +public: + + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PAIN_STATE_H__ */ diff --git a/DarkMod/AI/States/SearchingState.cpp b/game/ai/States/SearchingState.cpp similarity index 95% rename from DarkMod/AI/States/SearchingState.cpp rename to game/ai/States/SearchingState.cpp index 073d7d639..949f19250 100644 --- a/DarkMod/AI/States/SearchingState.cpp +++ b/game/ai/States/SearchingState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/States/SearchingState.h b/game/ai/States/SearchingState.h similarity index 75% rename from DarkMod/AI/States/SearchingState.h rename to game/ai/States/SearchingState.h index 484a4f471..2aa0e79be 100644 --- a/DarkMod/AI/States/SearchingState.h +++ b/game/ai/States/SearchingState.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_SEARCHING_STATE_H__ #define __AI_SEARCHING_STATE_H__ diff --git a/DarkMod/AI/States/State.cpp b/game/ai/States/State.cpp similarity index 98% rename from DarkMod/AI/States/State.cpp rename to game/ai/States/State.cpp index cc550300f..a3dbae547 100644 --- a/DarkMod/AI/States/State.cpp +++ b/game/ai/States/State.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -35,7 +45,7 @@ static bool init_version = FileVersionList("$Id$", init_version); #include "../Tasks/PlayAnimationTask.h" #include "ConversationState.h" // grayman #2603 -#include "../../DarkMod/ProjectileResult.h" // grayman #2872 +#include "../../ProjectileResult.h" // grayman #2872 namespace ai { @@ -519,6 +529,15 @@ void State::OnVisualStim(idEntity* stimSource) return; } + // grayman #2905 - AI should never relight or bark about lights that were spawned off + // at map start and have a shouldBeOn value of 0. + + if ( light->GetStartedOff() ) + { + stimSource->IgnoreResponse(ST_VISUAL,owner); + return; + } + // grayman #2603 - Let's see if the AI is involved in a conversation. // FIXME: This might not be enough, if the AI has pushed other states on top of the conversation state ConversationStatePtr convState = boost::dynamic_pointer_cast(owner->GetMind()->GetState()); @@ -1110,7 +1129,7 @@ void State::OnPersonEncounter(idEntity* stimSource, idAI* owner) ( otherMemory.posEnemySeen != memory.posEnemySeen ) ) // do we know about the same enemy? { // warn about seeing an enemy - gameLocal.Printf("%s found a friend, who is warning about seeing an enemy\n",owner->name.c_str()); + //gameLocal.Printf("%s found a friend, who is warning about seeing an enemy\n",owner->name.c_str()); soundName = "snd_warnSawEnemy"; memory.enemiesHaveBeenSeen = true; memory.posEnemySeen = otherMemory.posEnemySeen; @@ -1120,7 +1139,7 @@ void State::OnPersonEncounter(idEntity* stimSource, idAI* owner) ( otherMemory.posCorpseFound == memory.posCorpseFound ) ) // do we know about the same corpse? { // warn about finding a corpse - gameLocal.Printf("%s found a friend, who is warning about finding a corpse\n",owner->name.c_str()); + //gameLocal.Printf("%s found a friend, who is warning about finding a corpse\n",owner->name.c_str()); soundName = "snd_warnFoundCorpse"; memory.deadPeopleHaveBeenFound = true; memory.posCorpseFound = otherMemory.posCorpseFound; @@ -1131,7 +1150,7 @@ void State::OnPersonEncounter(idEntity* stimSource, idAI* owner) ( memory.timeMissingItem != otherMemory.timeMissingItem ) ) // is my missing item alert different than the other's { // warn about a missing item - gameLocal.Printf("%s found a friend, who is warning about something being stolen\n",owner->name.c_str()); + //gameLocal.Printf("%s found a friend, who is warning about something being stolen\n",owner->name.c_str()); soundName = "snd_warnMissingItem"; memory.itemsHaveBeenStolen = true; memory.posMissingItem = otherMemory.posMissingItem; @@ -1141,7 +1160,7 @@ void State::OnPersonEncounter(idEntity* stimSource, idAI* owner) else if ( memory.timeEvidenceIntruders != otherMemory.timeEvidenceIntruders ) // is my evidence alert different than the other's { // warn about intruders - gameLocal.Printf("%s found a friend, who is warning about evidence of intruders\n",owner->name.c_str()); + //gameLocal.Printf("%s found a friend, who is warning about evidence of intruders\n",owner->name.c_str()); soundName = "snd_warnSawEvidence"; memory.posEvidenceIntruders = otherMemory.posEvidenceIntruders; @@ -3147,8 +3166,8 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud) void State::OnMessageDetectedSomethingSuspicious(CommMessage& message) { idEntity* issuingEntity = message.m_p_issuingEntity.GetEntity(); - idEntity* recipientEntity = message.m_p_recipientEntity.GetEntity(); - idEntity* directObjectEntity = message.m_p_directObjectEntity.GetEntity(); + //idEntity* recipientEntity = message.m_p_recipientEntity.GetEntity(); + //idEntity* directObjectEntity = message.m_p_directObjectEntity.GetEntity(); idVec3 directObjectLocation = message.m_directObjectLocation; idAI* owner = _owner.GetEntity(); diff --git a/DarkMod/AI/States/State.h b/game/ai/States/State.h similarity index 88% rename from DarkMod/AI/States/State.h rename to game/ai/States/State.h index 38b19a424..2db8fce78 100644 --- a/DarkMod/AI/States/State.h +++ b/game/ai/States/State.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_STATE_H__ #define __AI_STATE_H__ diff --git a/DarkMod/AI/States/StayInCoverState.cpp b/game/ai/States/StayInCoverState.cpp similarity index 82% rename from DarkMod/AI/States/StayInCoverState.cpp rename to game/ai/States/StayInCoverState.cpp index 05f63134e..f51c62243 100644 --- a/DarkMod/AI/States/StayInCoverState.cpp +++ b/game/ai/States/StayInCoverState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/StayInCoverState.h b/game/ai/States/StayInCoverState.h new file mode 100644 index 000000000..9a3f8ae8f --- /dev/null +++ b/game/ai/States/StayInCoverState.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_STAY_IN_COVER_STATE_H__ +#define __AI_STAY_IN_COVER_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_STAY_IN_COVER "StayInCover" + +class StayInCoverState : + public State +{ +private: + int _emergeDelay; +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); + +protected: + // Override the base class method to catch projectile hit events + virtual void OnProjectileHit(idProjectile* projectile); +}; + +} // namespace ai + +#endif /* __AI_STAY_IN_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/SuspiciousState.cpp b/game/ai/States/SuspiciousState.cpp similarity index 88% rename from DarkMod/AI/States/SuspiciousState.cpp rename to game/ai/States/SuspiciousState.cpp index 5e6274356..534f856f3 100644 --- a/DarkMod/AI/States/SuspiciousState.cpp +++ b/game/ai/States/SuspiciousState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/SuspiciousState.h b/game/ai/States/SuspiciousState.h new file mode 100644 index 000000000..667478aae --- /dev/null +++ b/game/ai/States/SuspiciousState.h @@ -0,0 +1,53 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_SUSPICIOUS_STATE_H__ +#define __AI_SUSPICIOUS_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_SUSPICIOUS "Suspicious" + +class SuspiciousState : + public State +{ + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); + +protected: + // Override base class method + virtual bool CheckAlertLevel(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_SUSPICIOUS_STATE_H__ */ diff --git a/DarkMod/AI/States/SwitchOnLightState.cpp b/game/ai/States/SwitchOnLightState.cpp similarity index 97% rename from DarkMod/AI/States/SwitchOnLightState.cpp rename to game/ai/States/SwitchOnLightState.cpp index 7efac7178..b600e58d4 100644 --- a/DarkMod/AI/States/SwitchOnLightState.cpp +++ b/game/ai/States/SwitchOnLightState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/SwitchOnLightState.h b/game/ai/States/SwitchOnLightState.h new file mode 100644 index 000000000..13c5a1be1 --- /dev/null +++ b/game/ai/States/SwitchOnLightState.h @@ -0,0 +1,89 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_SWITCH_ON_LIGHT_H__ +#define __AI_SWITCH_ON_LIGHT_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_SWITCH_ON_LIGHT "SwitchOnLight" + +class SwitchOnLightState : + public State +{ +private: + // Default constructor + SwitchOnLightState(); + + idEntityPtr _light; + + // time to wait after starting anim before the light is switched on + int _waitEndTime; + + idEntity* _goalEnt; // grayman #2603 - entity to walk toward when relighting a light + float _standOff; // grayman #2603 - get this close to relight + idVec3 _relightSpot; // grayman #2603 - where to stand to relight + + enum ERelightState // grayman #2603 + { + EStateSitting, + EStateStarting, + EStateApproaching, + EStateTurningToward, + EStateRelight, + EStatePause, + EStateFinal + } _relightState; + + bool CheckRelightPosition(idLight* light, idAI* owner, idVec3& pos); // grayman #2603 + +public: + // Constructor using light source as input parameter + SwitchOnLightState(idLight* light); + + // Get the name of this state + virtual const idStr& GetName() const; + + virtual void Wrapup(idAI* owner, idLight* light, bool ignore); // grayman #2603 + + virtual float GetMaxReach(idAI* owner, idEntity* torch, idStr lightType); // grayman #2603 + virtual bool GetSwitchGoal(idAI* owner, CBinaryFrobMover* mySwitch, idVec3 &target); // grayman #2603 + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Start switching on (stop move, start anim) + void StartSwitchOn(idAI* owner, idLight* light); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_SWITCH_ON_LIGHT_H__ */ diff --git a/DarkMod/AI/States/TakeCoverState.cpp b/game/ai/States/TakeCoverState.cpp similarity index 77% rename from DarkMod/AI/States/TakeCoverState.cpp rename to game/ai/States/TakeCoverState.cpp index 62a2e7d80..69a2b715d 100644 --- a/DarkMod/AI/States/TakeCoverState.cpp +++ b/game/ai/States/TakeCoverState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/States/TakeCoverState.h b/game/ai/States/TakeCoverState.h new file mode 100644 index 000000000..6a6b75ddb --- /dev/null +++ b/game/ai/States/TakeCoverState.h @@ -0,0 +1,48 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_TAKE_COVER_STATE_H__ +#define __AI_TAKE_COVER_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_TAKE_COVER "TakeCover" + +class TakeCoverState : + public State +{ +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_TAKE_COVER_STATE_H__ */ diff --git a/DarkMod/AI/States/UnreachableTargetState.cpp b/game/ai/States/UnreachableTargetState.cpp similarity index 90% rename from DarkMod/AI/States/UnreachableTargetState.cpp rename to game/ai/States/UnreachableTargetState.cpp index 1c63da7ff..c34ab352f 100644 --- a/DarkMod/AI/States/UnreachableTargetState.cpp +++ b/game/ai/States/UnreachableTargetState.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -58,7 +68,8 @@ void UnreachableTargetState::Init(idAI* owner) if (owner->spawnArgs.GetBool("taking_cover_enabled","0")) { aasGoal_t hideGoal; - if ( (_takingCoverPossible = owner->LookForCover(hideGoal, enemy, owner->lastVisibleEnemyPos)) ) + _takingCoverPossible = owner->LookForCover(hideGoal, enemy, owner->lastVisibleEnemyPos); + if (_takingCoverPossible) { // We should not go into TakeCoverState if we are already at a suitable position if (hideGoal.origin == owner->GetPhysics()->GetOrigin() ) diff --git a/game/ai/States/UnreachableTargetState.h b/game/ai/States/UnreachableTargetState.h new file mode 100644 index 000000000..b7921a9c1 --- /dev/null +++ b/game/ai/States/UnreachableTargetState.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_UNREACHABLE_TARGET_STATE_H__ +#define __AI_UNREACHABLE_TARGET_STATE_H__ + +#include "State.h" + +namespace ai +{ + +#define STATE_UNREACHABLE_TARGET "UnreachableTarget" + +class UnreachableTargetState : + public State +{ + // The AI's enemy + idEntityPtr _enemy; + bool _takingCoverPossible; + int _takeCoverTime; + bool _moveRequired; + int _reachEnemyCheck; + +public: + // Get the name of this state + virtual const idStr& GetName() const; + + // This is called when the state is first attached to the AI's Mind. + virtual void Init(idAI* owner); + + // Gets called each time the mind is thinking + virtual void Think(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + static StatePtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_UNREACHABLE_TARGET_STATE_H__ */ diff --git a/DarkMod/AI/Subsystem.cpp b/game/ai/Subsystem.cpp similarity index 87% rename from DarkMod/AI/Subsystem.cpp rename to game/ai/Subsystem.cpp index aeed00854..63ec22eae 100644 --- a/DarkMod/AI/Subsystem.cpp +++ b/game/ai/Subsystem.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/DarkMod/AI/Subsystem.h b/game/ai/Subsystem.h similarity index 79% rename from DarkMod/AI/Subsystem.h rename to game/ai/Subsystem.h index 7de1becc6..5bea72232 100644 --- a/DarkMod/AI/Subsystem.h +++ b/game/ai/Subsystem.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_SUBSYSTEM_H__ #define __AI_SUBSYSTEM_H__ diff --git a/DarkMod/AI/Tasks/AnimalPatrolTask.cpp b/game/ai/Tasks/AnimalPatrolTask.cpp similarity index 91% rename from DarkMod/AI/Tasks/AnimalPatrolTask.cpp rename to game/ai/Tasks/AnimalPatrolTask.cpp index f7ac856cd..bc289075a 100644 --- a/DarkMod/AI/Tasks/AnimalPatrolTask.cpp +++ b/game/ai/Tasks/AnimalPatrolTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/AnimalPatrolTask.h b/game/ai/Tasks/AnimalPatrolTask.h new file mode 100644 index 000000000..77ccd01ba --- /dev/null +++ b/game/ai/Tasks/AnimalPatrolTask.h @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_ANIMAL_PATROL_TASK_H__ +#define __AI_ANIMAL_PATROL_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_ANIMAL_PATROL "AnimalPatrol" + +class AnimalPatrolTask; +typedef boost::shared_ptr AnimalPatrolTaskPtr; + +class AnimalPatrolTask : + public Task +{ + // greebo: These are the various states the animal is in + // It's a basic set of actions, chosen randomly, repeating + enum EState + { + stateNone, + stateMovingToNextSpot, + stateMovingToNextPathCorner, + stateDoingSomething, + stateWaiting, + statePreMovingToNextSpot, // grayman #2356 - no path corners, go elsewhere + stateCount, + } _state; + + // For waiting state + int _waitEndTime; + + // grayman #2356 - for 'move to position' state + int _moveEndTime; + + // Private constructor + AnimalPatrolTask(); + +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static AnimalPatrolTaskPtr CreateInstance(); + +private: + // Helper methods, corresponding to the EState enum + void chooseNewState(idAI* owner); + + void movingToNextSpot(idAI* owner); + void movingToNextPathCorner(idAI* owner); + void waiting(idAI* owner); + + void switchToState(EState newState, idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_ANIMAL_PATROL_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ChaseEnemyRangedTask.cpp b/game/ai/Tasks/ChaseEnemyRangedTask.cpp similarity index 81% rename from DarkMod/AI/Tasks/ChaseEnemyRangedTask.cpp rename to game/ai/Tasks/ChaseEnemyRangedTask.cpp index dec2255e4..d27c5e6cd 100644 --- a/DarkMod/AI/Tasks/ChaseEnemyRangedTask.cpp +++ b/game/ai/Tasks/ChaseEnemyRangedTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/ChaseEnemyRangedTask.h b/game/ai/Tasks/ChaseEnemyRangedTask.h new file mode 100644 index 000000000..a6bd229ee --- /dev/null +++ b/game/ai/Tasks/ChaseEnemyRangedTask.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_CHASE_ENEMY_RANGED_TASK_H__ +#define __AI_CHASE_ENEMY_RANGED_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_CHASE_ENEMY_RANGED "ChaseEnemyRanged" + +class ChaseEnemyRangedTask; +typedef boost::shared_ptr ChaseEnemyRangedTaskPtr; + +class ChaseEnemyRangedTask : + public Task +{ + bool _hasGoal; + + idEntityPtr _enemy; + +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static ChaseEnemyRangedTaskPtr CreateInstance(); + + // Class-specific methods + virtual void SetEnemy(idActor* enemy); +}; + +} // namespace ai + +#endif /* __AI_CHASE_ENEMY_RANGED_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ChaseEnemyTask.cpp b/game/ai/Tasks/ChaseEnemyTask.cpp similarity index 90% rename from DarkMod/AI/Tasks/ChaseEnemyTask.cpp rename to game/ai/Tasks/ChaseEnemyTask.cpp index 0e2a244ec..fe87a6a8b 100644 --- a/DarkMod/AI/Tasks/ChaseEnemyTask.cpp +++ b/game/ai/Tasks/ChaseEnemyTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/ChaseEnemyTask.h b/game/ai/Tasks/ChaseEnemyTask.h new file mode 100644 index 000000000..8b9620b0f --- /dev/null +++ b/game/ai/Tasks/ChaseEnemyTask.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_CHASE_ENEMY_TASK_H__ +#define __AI_CHASE_ENEMY_TASK_H__ + +#include "Task.h" +#include "../../MultiStateMover.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_CHASE_ENEMY "ChaseEnemy" + +class ChaseEnemyTask; +typedef boost::shared_ptr ChaseEnemyTaskPtr; + +class ChaseEnemyTask : + public Task +{ + idEntityPtr _enemy; + int _reachEnemyCheck; + + // Private default constructor + ChaseEnemyTask(); +public: + ChaseEnemyTask(idActor* enemy); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static ChaseEnemyTaskPtr CreateInstance(); + + // Class-specific methods + virtual void SetEnemy(idActor* enemy); + +private: + CMultiStateMoverPosition* CanFetchElevator(CMultiStateMover* mover, idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_CHASE_ENEMY_TASK_H__ */ diff --git a/game/ai/Tasks/CombatTask.cpp b/game/ai/Tasks/CombatTask.cpp new file mode 100644 index 000000000..3daef4dbd --- /dev/null +++ b/game/ai/Tasks/CombatTask.cpp @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "CombatTask.h" +#include "SingleBarkTask.h" +#include "../Memory.h" +#include "../Library.h" + +namespace ai +{ + +CombatTask::CombatTask() : + _lastCombatBarkTime(-1) +{} + +void CombatTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Init the base class + Task::Init(owner, subsystem); + + _enemy = owner->GetEnemy(); +} + +void CombatTask::EmitCombatBark(idAI* owner, const idStr& sndName) +{ + // This will hold the message to be delivered with the bark, if appropriate + CommMessagePtr message; + + // Only alert the bystanders if we didn't receive the alert by message ourselves + message = CommMessagePtr(new CommMessage( + CommMessage::DetectedEnemy_CommType, + owner, NULL, // from this AI to anyone + owner->GetEnemy(), + owner->GetPhysics()->GetOrigin() + )); + + _lastCombatBarkTime = gameLocal.time; + + // The communication system + owner->commSubsystem->AddCommTask( + CommunicationTaskPtr(new SingleBarkTask(sndName, message)) + ); +} + +void CombatTask::Save(idSaveGame* savefile) const +{ + Task::Save(savefile); + + _enemy.Save(savefile); + savefile->WriteInt(_lastCombatBarkTime); +} + +void CombatTask::Restore(idRestoreGame* savefile) +{ + Task::Restore(savefile); + + _enemy.Restore(savefile); + savefile->ReadInt(_lastCombatBarkTime); +} + +} // namespace ai diff --git a/game/ai/Tasks/CombatTask.h b/game/ai/Tasks/CombatTask.h new file mode 100644 index 000000000..5d5da17e3 --- /dev/null +++ b/game/ai/Tasks/CombatTask.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_COMBAT_TASK_H__ +#define __AI_COMBAT_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +class CombatTask : + public Task +{ +protected: + idEntityPtr _enemy; + + int _lastCombatBarkTime; + + CombatTask(); + +public: + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + // This task lacks a Perform() method, this is to be implemented by subclasses + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + +protected: + + // Emits a combat bark plus an AI message to be delivered by soundprop + // about the enemy's position + void EmitCombatBark(idAI* owner, const idStr& sndName); +}; +typedef boost::shared_ptr CombatTaskPtr; + +} // namespace ai + +#endif /* __AI_RANGED_COMBAT_TASK_H__ */ diff --git a/game/ai/Tasks/CommWaitTask.cpp b/game/ai/Tasks/CommWaitTask.cpp new file mode 100644 index 000000000..6d597e6f5 --- /dev/null +++ b/game/ai/Tasks/CommWaitTask.cpp @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "CommWaitTask.h" +#include "../Memory.h" +#include "../Library.h" + +namespace ai +{ + +CommWaitTask::CommWaitTask() : + CommunicationTask(""), + _duration(0), + _endTime(-1) +{} + +CommWaitTask::CommWaitTask(int duration, int priority) : + CommunicationTask(""), + _duration(duration), + _endTime(-1) +{ + _priority = priority; +} + +// Get the name of this task +const idStr& CommWaitTask::GetName() const +{ + static idStr _name(TASK_COMM_WAIT); + return _name; +} + +void CommWaitTask::Init(idAI* owner, Subsystem& subsystem) +{ + CommunicationTask::Init(owner, subsystem); + + _endTime = gameLocal.time + _duration; +} + +bool CommWaitTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("CommWaitTask performing.\r"); + + return (gameLocal.time >= _endTime); +} + +// Save/Restore methods +void CommWaitTask::Save(idSaveGame* savefile) const +{ + CommunicationTask::Save(savefile); + + savefile->WriteInt(_duration); + savefile->WriteInt(_endTime); +} + +void CommWaitTask::Restore(idRestoreGame* savefile) +{ + CommunicationTask::Restore(savefile); + + savefile->ReadInt(_duration); + savefile->ReadInt(_endTime); +} + +CommWaitTaskPtr CommWaitTask::CreateInstance() +{ + return CommWaitTaskPtr(new CommWaitTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar commWaitTaskRegistrar( + TASK_COMM_WAIT, // Task Name + TaskLibrary::CreateInstanceFunc(&CommWaitTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/CommWaitTask.h b/game/ai/Tasks/CommWaitTask.h new file mode 100644 index 000000000..b271045ff --- /dev/null +++ b/game/ai/Tasks/CommWaitTask.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_COMM_WAIT_TASK_H__ +#define __AI_COMM_WAIT_TASK_H__ + +#include "CommunicationTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_COMM_WAIT "CommWaitTask" + +class CommWaitTask; +typedef boost::shared_ptr CommWaitTaskPtr; + +// A simple silent task, causes the AI to shut up for a while +class CommWaitTask : + public CommunicationTask +{ + int _duration; + int _endTime; + + // Default constructor + CommWaitTask(); + +public: + // Constructor: pass the duration of the silence + CommWaitTask(int duration, int priority = 0); + + // Get the name of this task + virtual const idStr& GetName() const; + + virtual void Init(idAI* owner, Subsystem& subsystem); + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static CommWaitTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_COMM_WAIT_TASK_H__ */ diff --git a/game/ai/Tasks/CommunicationTask.cpp b/game/ai/Tasks/CommunicationTask.cpp new file mode 100644 index 000000000..c16225724 --- /dev/null +++ b/game/ai/Tasks/CommunicationTask.cpp @@ -0,0 +1,111 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "CommunicationTask.h" +#include "../Library.h" + +namespace ai +{ + +CommunicationTask::CommunicationTask() +{} + +CommunicationTask::CommunicationTask(const idStr& soundName) : + _soundName(soundName) +{ + // Look up priority + const idDict* dict = gameLocal.FindEntityDefDict(BARK_PRIORITY_DEF); + + if (dict != NULL) + { + // Change "snd_blah" to "prio_blah" + idStr prioName(soundName); + prioName.StripLeadingOnce("snd_"); + prioName = "prio_" + prioName; + + // Emit a warning if priority not found, but only if sound name is empty + if (!dict->GetInt(prioName, "-1", _priority) && !soundName.IsEmpty()) + { + gameLocal.Warning("Could not find bark priority for %s", soundName.c_str()); + } + } + else + { + gameLocal.Warning("Cannot find bark priority entitydef %s", BARK_PRIORITY_DEF); + _priority = -1; + } +} + +void CommunicationTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Just init the base class + Task::Init(owner, subsystem); + + _barkStartTime = gameLocal.time; + _barkLength = 0; +} + +int CommunicationTask::GetPriority() +{ + return _priority; +} + +void CommunicationTask::SetPriority(int priority) +{ + _priority = priority; +} + +bool CommunicationTask::IsBarking() +{ + return (gameLocal.time < _barkStartTime + _barkLength); +} + +const idStr& CommunicationTask::GetSoundName() +{ + return _soundName; +} + +// Save/Restore methods +void CommunicationTask::Save(idSaveGame* savefile) const +{ + Task::Save(savefile); + + savefile->WriteString(_soundName); + savefile->WriteInt(_priority); + savefile->WriteInt(_barkStartTime); + savefile->WriteInt(_barkLength); +} + +void CommunicationTask::Restore(idRestoreGame* savefile) +{ + Task::Restore(savefile); + + savefile->ReadString(_soundName); + savefile->ReadInt(_priority); + savefile->ReadInt(_barkStartTime); + savefile->ReadInt(_barkLength); +} + +} // namespace ai diff --git a/game/ai/Tasks/CommunicationTask.h b/game/ai/Tasks/CommunicationTask.h new file mode 100644 index 000000000..1065cdbdd --- /dev/null +++ b/game/ai/Tasks/CommunicationTask.h @@ -0,0 +1,81 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_COMMUNICATION_TASK_H__ +#define __AI_COMMUNICATION_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +#define BARK_PRIORITY_DEF "atdm:ai_bark_priority" +#define VERY_HIGH_BARK_PRIORITY 9000000 + +class CommunicationTask; +typedef boost::shared_ptr CommunicationTaskPtr; + +/** + * A CommunicationTask is a more specialised task, extending + * the interface by a few methods, which facilitate the handling + * of concurrent AI barks. A bark sound always has an associated + * priority, which the CommunicationSubsystem is using to decide + * whether a new incoming bark is allowed to override an existing + * one or not. + */ +class CommunicationTask : + public Task +{ +protected: + // The sound to play + idStr _soundName; + + // The priority of this sound + int _priority; + + int _barkStartTime; + int _barkLength; + + // Private constructors + CommunicationTask(); + + CommunicationTask(const idStr& soundName); + +public: + // Returns the priority of this bark + int GetPriority(); + void SetPriority(int priority); + + // Returns TRUE if the task is still playing a bark + // (this is excluding any possible delay after the actual sound) + bool IsBarking(); + + const idStr& GetSoundName(); + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); +}; + +} // namespace ai + +#endif /* __AI_COMMUNICATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/FleeTask.cpp b/game/ai/Tasks/FleeTask.cpp similarity index 86% rename from DarkMod/AI/Tasks/FleeTask.cpp rename to game/ai/Tasks/FleeTask.cpp index 91ae8eec1..db4186ffe 100644 --- a/DarkMod/AI/Tasks/FleeTask.cpp +++ b/game/ai/Tasks/FleeTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/FleeTask.h b/game/ai/Tasks/FleeTask.h new file mode 100644 index 000000000..459ef3de5 --- /dev/null +++ b/game/ai/Tasks/FleeTask.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_FLEE_TASK_H__ +#define __AI_FLEE_TASK_H__ + +#include "Task.h" +#include "../../EscapePointManager.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_FLEE "FleeTask" + +class FleeTask; +typedef boost::shared_ptr FleeTaskPtr; + +class FleeTask : + public Task +{ + idEntityPtr _enemy; + int _escapeSearchLevel; + int _failureCount; + int _fleeStartTime; + EscapeDistanceOption _distOpt; + + FleeTask(); +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static FleeTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_FLEE_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/FollowActorTask.cpp b/game/ai/Tasks/FollowActorTask.cpp similarity index 79% rename from DarkMod/AI/Tasks/FollowActorTask.cpp rename to game/ai/Tasks/FollowActorTask.cpp index fce4ee9e2..3e7221c7a 100644 --- a/DarkMod/AI/Tasks/FollowActorTask.cpp +++ b/game/ai/Tasks/FollowActorTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/FollowActorTask.h b/game/ai/Tasks/FollowActorTask.h new file mode 100644 index 000000000..34e9afcfc --- /dev/null +++ b/game/ai/Tasks/FollowActorTask.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_FOLLOW_ACTOR_TASK_H__ +#define __AI_FOLLOW_ACTOR_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_FOLLOW_ACTOR "FollowActor" + +class FollowActorTask; +typedef boost::shared_ptr FollowActorTaskPtr; + +class FollowActorTask : + public Task +{ +private: + // The actor we're following + idEntityPtr _actor; + + FollowActorTask(); + +public: + // Construct this task by passing an actor to follow - it's safe to pass a NULL actor, + // the task will terminate after one thinking round in that case. + FollowActorTask(idActor* actorToFollow); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static FollowActorTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_FOLLOW_ACTOR_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/GreetingBarkTask.cpp b/game/ai/Tasks/GreetingBarkTask.cpp similarity index 86% rename from DarkMod/AI/Tasks/GreetingBarkTask.cpp rename to game/ai/Tasks/GreetingBarkTask.cpp index 2fd2c69b8..4f847bc7c 100644 --- a/DarkMod/AI/Tasks/GreetingBarkTask.cpp +++ b/game/ai/Tasks/GreetingBarkTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/GreetingBarkTask.h b/game/ai/Tasks/GreetingBarkTask.h new file mode 100644 index 000000000..6d1a55999 --- /dev/null +++ b/game/ai/Tasks/GreetingBarkTask.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_GREETING_BARK_TASK_H__ +#define __AI_GREETING_BARK_TASK_H__ + +#include "SingleBarkTask.h" +#include "../../AIComm_Message.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_GREETING_BARK "GreetingBark" + +class GreetingBarkTask; +typedef boost::shared_ptr GreetingBarkTaskPtr; + +class GreetingBarkTask : + public SingleBarkTask +{ +protected: + + idActor* _greetingTarget; + + // Default constructor + GreetingBarkTask(); + +public: + // Constructor taking a sound name and the target actor as argument + GreetingBarkTask(const idStr& soundName, idActor* greetingTarget); + + // Get the name of this task + virtual const idStr& GetName() const; + + virtual void Init(idAI* owner, Subsystem& subsystem); + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static GreetingBarkTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_GREETING_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/HandleDoorTask.cpp b/game/ai/Tasks/HandleDoorTask.cpp similarity index 98% rename from DarkMod/AI/Tasks/HandleDoorTask.cpp rename to game/ai/Tasks/HandleDoorTask.cpp index b6b650c21..e95433904 100644 --- a/DarkMod/AI/Tasks/HandleDoorTask.cpp +++ b/game/ai/Tasks/HandleDoorTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -267,8 +277,8 @@ bool HandleDoorTask::Perform(Subsystem& subsystem) // bounds[0][2] += 16; // old way float size = bounds[1][0]; - idEntity* frontPosEntity = _frontPosEnt.GetEntity(); - idEntity* backPosEntity = _backPosEnt.GetEntity(); + //idEntity* frontPosEntity = _frontPosEnt.GetEntity(); + //idEntity* backPosEntity = _backPosEnt.GetEntity(); if (cv_ai_door_show.GetBool()) { @@ -1504,7 +1514,7 @@ idVec3 HandleDoorTask::GetAwayPos(idAI* owner, CFrobDoor* frobDoor) dir.z = 0; idVec3 dirNorm = dir; dirNorm.NormalizeFast(); - float dist = dir.LengthFast(); + //float dist = dir.LengthFast(); idVec3 openDirNorm = openDir; openDirNorm.z = 0; @@ -1568,7 +1578,7 @@ idVec3 HandleDoorTask::GetTowardPos(idAI* owner, CFrobDoor* frobDoor) // calculate where to stand when the door swings towards us const idVec3& frobDoorOrg = frobDoor->GetPhysics()->GetOrigin(); const idVec3& openDir = frobDoor->GetOpenDir(); - const idVec3& openPos = frobDoorOrg + frobDoor->GetOpenPos(); + //const idVec3& openPos = frobDoorOrg + frobDoor->GetOpenPos(); const idVec3& closedPos = frobDoorOrg + frobDoor->GetClosedPos(); idBounds frobDoorBounds = frobDoor->GetPhysics()->GetAbsBounds(); diff --git a/DarkMod/AI/Tasks/HandleDoorTask.h b/game/ai/Tasks/HandleDoorTask.h similarity index 82% rename from DarkMod/AI/Tasks/HandleDoorTask.h rename to game/ai/Tasks/HandleDoorTask.h index 08945382a..5829d22d0 100644 --- a/DarkMod/AI/Tasks/HandleDoorTask.h +++ b/game/ai/Tasks/HandleDoorTask.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_HANDLE_DOOR_TASK_H__ #define __AI_HANDLE_DOOR_TASK_H__ diff --git a/DarkMod/AI/Tasks/HandleElevatorTask.cpp b/game/ai/Tasks/HandleElevatorTask.cpp similarity index 94% rename from DarkMod/AI/Tasks/HandleElevatorTask.cpp rename to game/ai/Tasks/HandleElevatorTask.cpp index c521dd0a3..52b93c774 100644 --- a/DarkMod/AI/Tasks/HandleElevatorTask.cpp +++ b/game/ai/Tasks/HandleElevatorTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -59,7 +69,7 @@ void HandleElevatorTask::Init(idAI* owner, Subsystem& subsystem) eas::ElevatorStationInfoPtr stationInfo = owner->GetAAS()->GetEAS()->GetElevatorStationInfo(node->elevatorStation); - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); CMultiStateMoverPosition* pos = stationInfo->elevatorPosition.GetEntity(); CMultiStateMover* elevator = stationInfo->elevator.GetEntity(); @@ -99,7 +109,7 @@ bool HandleElevatorTask::Perform(Subsystem& subsystem) DM_LOG(LC_AI, LT_INFO)LOGSTRING("HandleElevatorTask performing.\r"); idAI* owner = _owner.GetEntity(); - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); // Grab the first RouteNode const eas::RouteNodePtr& node = *_routeInfo.routeNodes.begin(); @@ -445,7 +455,7 @@ bool HandleElevatorTask::IsElevatorStationReachable(CMultiStateMoverPosition* po void HandleElevatorTask::OnFinish(idAI* owner) { - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); owner->m_HandlingElevator = false; diff --git a/game/ai/Tasks/HandleElevatorTask.h b/game/ai/Tasks/HandleElevatorTask.h new file mode 100644 index 000000000..e29cc97ff --- /dev/null +++ b/game/ai/Tasks/HandleElevatorTask.h @@ -0,0 +1,101 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_HANDLE_ELEVATOR_TASK_H__ +#define __AI_HANDLE_ELEVATOR_TASK_H__ + +#include "Task.h" +#include "../EAS/RouteInfo.h" +#include "../../BinaryFrobMover.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_HANDLE_ELEVATOR "HandleElevator" + +class HandleElevatorTask; +typedef boost::shared_ptr HandleElevatorTaskPtr; + +class HandleElevatorTask : + public Task +{ +private: + enum State + { + EMovingTowardsStation, + EInitiateMoveToFetchButton, + EMovingToFetchButton, + EPressFetchButton, + EWaitForElevator, + EMoveOntoElevator, + EInitiateMoveToRideButton, + EMovingToRideButton, + EPressRideButton, + ERideOnElevator, + EGetOffElevator, + ENumStates, + } _state; + + int _waitEndTime; + + // The actual route info structure + eas::RouteInfo _routeInfo; + + // Is TRUE if this task has finished successfully + bool _success; + + // Private constructor + HandleElevatorTask(); +public: + + HandleElevatorTask(const eas::RouteInfoPtr& routeInfo); + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + void Save(idSaveGame* savefile) const; + void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static HandleElevatorTaskPtr CreateInstance(); + +private: + // Checks if the elevator station is reachable, returns TRUE if this is the case + bool IsElevatorStationReachable(CMultiStateMoverPosition* pos); + + void DebugDraw(idAI* owner); + + // Lets the AI move towards the position entity (is slightly more complicated than just idAI::MoveToPos) + bool MoveToPositionEntity(idAI* owner, CMultiStateMoverPosition* pos); + + // Lets the Ai move to the button + bool MoveToButton(idAI* owner, CMultiStateMoverButton* button); + +}; + +} // namespace ai + +#endif /* __AI_HANDLE_ELEVATOR_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/IdleAnimationTask.cpp b/game/ai/Tasks/IdleAnimationTask.cpp similarity index 91% rename from DarkMod/AI/Tasks/IdleAnimationTask.cpp rename to game/ai/Tasks/IdleAnimationTask.cpp index 94473e49e..9e0872810 100644 --- a/DarkMod/AI/Tasks/IdleAnimationTask.cpp +++ b/game/ai/Tasks/IdleAnimationTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -42,7 +52,7 @@ void IdleAnimationTask::Init(idAI* owner, Subsystem& subsystem) // Just init the base class Task::Init(owner, subsystem); - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); // Read the animation set and interval from the owner's spawnarg _idleAnimationInterval = SEC2MS(owner->spawnArgs.GetInt("idle_animations_interval", "-1")); diff --git a/game/ai/Tasks/IdleAnimationTask.h b/game/ai/Tasks/IdleAnimationTask.h new file mode 100644 index 000000000..b60cebc67 --- /dev/null +++ b/game/ai/Tasks/IdleAnimationTask.h @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_IDLE_ANIMATION_TASK_H__ +#define __AI_IDLE_ANIMATION_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_IDLE_ANIMATION "IdleAnimation" + +class IdleAnimationTask; +typedef boost::shared_ptr IdleAnimationTaskPtr; + +class IdleAnimationTask : + public Task +{ + int _nextAnimationTime; + + idStringList _idleAnimations; + idStringList _idleAnimationsTorso; + idStringList _idleAnimationsSitting; + + int _idleAnimationInterval; + + // The index of the last anim played (to avoid duplicates) + int _lastIdleAnim; + + // Default constructor is private + IdleAnimationTask(); +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static IdleAnimationTaskPtr CreateInstance(); + +protected: + // De-serialises the comma-separated string list of animations + void ParseAnimsToList(const std::string& animStringList, idStringList& targetList); + + // Attempt to play an animation from the given list. Set torsoOnly to true if legs channel is forbidden + void AttemptToPlayAnim(idAI* owner, const idStringList& anims, bool torsoOnly); + + // Returns TRUE if the given anim has no_random_head_turning set + bool AnimHasNoHeadTurnFlag(idAI* owner, int animNum); + + // Returns a new idle anim index + virtual int GetNewIdleAnimIndex(const idStringList& anims, idAI* owner); + + // Returns true if the named anim is ok at this point + virtual bool AnimIsApplicable(idAI* owner, const idStr& animName); +}; + +} // namespace ai + +#endif /* __AI_IDLE_ANIMATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/InteractionTask.cpp b/game/ai/Tasks/InteractionTask.cpp similarity index 79% rename from DarkMod/AI/Tasks/InteractionTask.cpp rename to game/ai/Tasks/InteractionTask.cpp index 97996b78c..b54eb5860 100644 --- a/DarkMod/AI/Tasks/InteractionTask.cpp +++ b/game/ai/Tasks/InteractionTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/InteractionTask.h b/game/ai/Tasks/InteractionTask.h new file mode 100644 index 000000000..37dbdcf53 --- /dev/null +++ b/game/ai/Tasks/InteractionTask.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_INTERACTION_TASK_H__ +#define __AI_INTERACTION_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_INTERACTION "Interaction" + +class InteractionTask; +typedef boost::shared_ptr InteractionTaskPtr; + +class InteractionTask : + public Task +{ + idEntity* _interactEnt; + + int _waitEndTime; + + InteractionTask(); + +public: + InteractionTask(idEntity* interactEnt); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static InteractionTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_INTERACTION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/InvestigateSpotTask.cpp b/game/ai/Tasks/InvestigateSpotTask.cpp similarity index 92% rename from DarkMod/AI/Tasks/InvestigateSpotTask.cpp rename to game/ai/Tasks/InvestigateSpotTask.cpp index 6b6ac6223..2befe20ea 100644 --- a/DarkMod/AI/Tasks/InvestigateSpotTask.cpp +++ b/game/ai/Tasks/InvestigateSpotTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/InvestigateSpotTask.h b/game/ai/Tasks/InvestigateSpotTask.h new file mode 100644 index 000000000..6c15c839a --- /dev/null +++ b/game/ai/Tasks/InvestigateSpotTask.h @@ -0,0 +1,98 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_INVESTIGATE_SPOT_TASK_H__ +#define __AI_INVESTIGATE_SPOT_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +/** +* greebo: This task requires memory.currentSearchSpot to be valid. +* +* This task is intended to be pushed into the action Subsystem and +* performs single-handedly how the given hiding spot should be handled. +* +* Note: This Task employs the Movement Subsystem when the algorithm +* judges to walk/run over to the given search spot. +**/ + +// Define the name of this task +#define TASK_INVESTIGATE_SPOT "InvestigateSpot" + +class InvestigateSpotTask; +typedef boost::shared_ptr InvestigateSpotTaskPtr; + +class InvestigateSpotTask : + public Task +{ + // The search spot to investigate + idVec3 _searchSpot; + + // The time this task may exit + int _exitTime; + + // Set to TRUE, if the AI should investigate the spot very closely + // usually by playing the kneel_down animation. + bool _investigateClosely; + + // Whether this task has told the AI to actually move to the searchspot + bool _moveInitiated; + + // Private default constructor + InvestigateSpotTask(); +public: + // @param: see member _investigateClosely + InvestigateSpotTask(bool investigateClosely); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + /** + * greebo: Sets a new goal position for this task. + * + * @newPos: The new position + */ + virtual void SetNewGoal(const idVec3& newPos); + + /** + * greebo: Sets the "should investigate closely" flag. + */ + virtual void SetInvestigateClosely(bool closely); + + virtual void OnFinish(idAI* owner); // grayman #2560 + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static InvestigateSpotTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_INVESTIGATE_SPOT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/MeleeCombatTask.cpp b/game/ai/Tasks/MeleeCombatTask.cpp similarity index 95% rename from DarkMod/AI/Tasks/MeleeCombatTask.cpp rename to game/ai/Tasks/MeleeCombatTask.cpp index 4c7247aff..79f39c18d 100644 --- a/DarkMod/AI/Tasks/MeleeCombatTask.cpp +++ b/game/ai/Tasks/MeleeCombatTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -439,7 +449,7 @@ void MeleeCombatTask::StartParry(idAI* owner) else ParType = AttType; // match the attack - const char *suffix = idActor::MeleeTypeNames[ParType]; + //const char *suffix = idActor::MeleeTypeNames[ParType]; // update the melee status owner->Event_MeleeParryStarted( ParType ); diff --git a/DarkMod/AI/Tasks/MeleeCombatTask.h b/game/ai/Tasks/MeleeCombatTask.h similarity index 76% rename from DarkMod/AI/Tasks/MeleeCombatTask.h rename to game/ai/Tasks/MeleeCombatTask.h index be3f8295c..5320c9bba 100644 --- a/DarkMod/AI/Tasks/MeleeCombatTask.h +++ b/game/ai/Tasks/MeleeCombatTask.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_MELEE_COMBAT_TASK_H__ #define __AI_MELEE_COMBAT_TASK_H__ diff --git a/game/ai/Tasks/MoveToCoverTask.cpp b/game/ai/Tasks/MoveToCoverTask.cpp new file mode 100644 index 000000000..b287bbaa8 --- /dev/null +++ b/game/ai/Tasks/MoveToCoverTask.cpp @@ -0,0 +1,94 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "MoveToCoverTask.h" +#include "../Library.h" + +namespace ai +{ + +// Get the name of this task +const idStr& MoveToCoverTask::GetName() const +{ + static idStr _name(TASK_MOVE_TO_COVER); + return _name; +} + +void MoveToCoverTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Init the base class + Task::Init(owner, subsystem); + idActor* enemy = owner->GetEnemy(); + + //Move to cover position + owner->AI_RUN = true; + owner->AI_FORWARD = true; + owner->m_pathRank = owner->rank; // grayman #2345 + + owner->MoveToCover(enemy, owner->lastVisibleEnemyPos); +} + +bool MoveToCoverTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Move to Cover Task performing.\r"); + + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointer + assert(owner != NULL); + + if (owner->AI_DEST_UNREACHABLE) + { + //TODO + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Destination unreachable.\r"); + return true; + } + + if (owner->AI_MOVE_DONE) + { + // Move is done, + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Move is done.\r"); + owner->TurnToward(owner->lastVisibleEnemyPos); + + // finish this task + + return true; + } + + return false; // not finished yet +} + +MoveToCoverTaskPtr MoveToCoverTask::CreateInstance() +{ + return MoveToCoverTaskPtr(new MoveToCoverTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar moveToCoverTaskRegistrar( + TASK_MOVE_TO_COVER, // Task Name + TaskLibrary::CreateInstanceFunc(&MoveToCoverTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/MoveToCoverTask.h b/game/ai/Tasks/MoveToCoverTask.h new file mode 100644 index 000000000..b08d9e72d --- /dev/null +++ b/game/ai/Tasks/MoveToCoverTask.h @@ -0,0 +1,52 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_MOVE_TO_COVER_TASK_H__ +#define __AI_MOVE_TO_COVER_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_MOVE_TO_COVER "MoveToCover" + +class MoveToCoverTask; +typedef boost::shared_ptr MoveToCoverTaskPtr; + +class MoveToCoverTask : + public Task +{ +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static MoveToCoverTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_MOVE_TO_COVER_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/MoveToPositionTask.cpp b/game/ai/Tasks/MoveToPositionTask.cpp similarity index 85% rename from DarkMod/AI/Tasks/MoveToPositionTask.cpp rename to game/ai/Tasks/MoveToPositionTask.cpp index cad8624d8..9e9149faf 100644 --- a/DarkMod/AI/Tasks/MoveToPositionTask.cpp +++ b/game/ai/Tasks/MoveToPositionTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/MoveToPositionTask.h b/game/ai/Tasks/MoveToPositionTask.h new file mode 100644 index 000000000..94a834c1f --- /dev/null +++ b/game/ai/Tasks/MoveToPositionTask.h @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_MOVE_TO_POSITION_H__ +#define __AI_MOVE_TO_POSITION_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_MOVE_TO_POSITION "MoveToPosition" + +#define DEFAULT_ENTITY_REACH_DISTANCE 50.0f + +class MoveToPositionTask; +typedef boost::shared_ptr MoveToPositionTaskPtr; + +class MoveToPositionTask : + public Task +{ +private: + + // The target position + idVec3 _targetPosition; + + // The previous target position + idVec3 _prevTargetPosition; + + // Target yaw (is not INFINITY if set) + float _targetYaw; + + idEntity* _targetEntity; + + // the distance below which entities are considered "reached" + float _entityReachDistance; + + // angua: if > 0, this changes the size of the bounding box used for checking whether the AI has reached their destination + float _accuracy; + + // Default constructor + MoveToPositionTask(); + +public: + // Constructor taking the target position (and optional target yaw) as input argument + MoveToPositionTask(const idVec3& targetPosition, float targetYaw = idMath::INFINITY, float accuracy = -1); + + // Constructor taking a target entity + MoveToPositionTask(idEntity* targetEntity, float entityReachDistance = DEFAULT_ENTITY_REACH_DISTANCE, float accuracy = -1); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + void SetPosition(idVec3 targetPosition); + + // Sets the distance below which entities are considered "reached" + void SetEntityReachDistance(float distance); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static MoveToPositionTaskPtr CreateInstance(); + +private: + // Refines the goal position, if appropriate + void UpdateTargetPosition(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_MOVE_TO_POSITION_H__ */ diff --git a/DarkMod/AI/Tasks/PathAnimTask.cpp b/game/ai/Tasks/PathAnimTask.cpp similarity index 77% rename from DarkMod/AI/Tasks/PathAnimTask.cpp rename to game/ai/Tasks/PathAnimTask.cpp index 8130e5324..95311da21 100644 --- a/DarkMod/AI/Tasks/PathAnimTask.cpp +++ b/game/ai/Tasks/PathAnimTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathAnimTask.h b/game/ai/Tasks/PathAnimTask.h new file mode 100644 index 000000000..082f4cf45 --- /dev/null +++ b/game/ai/Tasks/PathAnimTask.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_ANIM_TASK_H__ +#define __AI_PATH_ANIM_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_ANIM "PathAnim" + +class PathAnimTask; +typedef boost::shared_ptr PathAnimTaskPtr; + +class PathAnimTask : + public PathTask +{ +private: + // Private constructor + PathAnimTask(); + +public: + PathAnimTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Creates a new Instance of this task + static PathAnimTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_PATH_ANIM_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathCornerTask.cpp b/game/ai/Tasks/PathCornerTask.cpp similarity index 89% rename from DarkMod/AI/Tasks/PathCornerTask.cpp rename to game/ai/Tasks/PathCornerTask.cpp index 776623254..677c36816 100644 --- a/DarkMod/AI/Tasks/PathCornerTask.cpp +++ b/game/ai/Tasks/PathCornerTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathCornerTask.h b/game/ai/Tasks/PathCornerTask.h new file mode 100644 index 000000000..ba04e1ecc --- /dev/null +++ b/game/ai/Tasks/PathCornerTask.h @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_CORNER_TASK_H__ +#define __AI_PATH_CORNER_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_CORNER "PathCorner" + +// grayman #2414 - For path prediction +const int PATH_PREDICTION_MOVES = 2; // Number of moves to look ahead +const float PATH_PREDICTION_CONSTANT = 26.0; // Empirically determined for smooth + // turns at any m_maxInterleaveThinkFrames + +class PathCornerTask; +typedef boost::shared_ptr PathCornerTaskPtr; + +class PathCornerTask : + public PathTask +{ +private: + bool _moveInitiated; + + // Position last time this task was executed, used for path prediction + idVec3 _lastPosition; + + // Frame this task was last executed + int _lastFrameNum; + + // Whether to anticipate the AI reaching path corners + bool _usePathPrediction; + + PathCornerTask(); + +public: + PathCornerTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathCornerTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_PATH_CORNER_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathCycleAnimTask.cpp b/game/ai/Tasks/PathCycleAnimTask.cpp similarity index 81% rename from DarkMod/AI/Tasks/PathCycleAnimTask.cpp rename to game/ai/Tasks/PathCycleAnimTask.cpp index 88b6d3624..3d243d6a7 100644 --- a/DarkMod/AI/Tasks/PathCycleAnimTask.cpp +++ b/game/ai/Tasks/PathCycleAnimTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathCycleAnimTask.h b/game/ai/Tasks/PathCycleAnimTask.h new file mode 100644 index 000000000..01fbf2683 --- /dev/null +++ b/game/ai/Tasks/PathCycleAnimTask.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_CYCLE_ANIM_TASK_H__ +#define __AI_PATH_CYCLE_ANIM_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_CYCLE_ANIM "PathCycleAnim" + +class PathCycleAnimTask; +typedef boost::shared_ptr PathCycleAnimTaskPtr; + +class PathCycleAnimTask : + public PathTask +{ + int _waitEndTime; + + // Private constructor + PathCycleAnimTask(); + +public: + PathCycleAnimTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathCycleAnimTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_PATH_CYCLE_ANIM_TASK_H__ */ diff --git a/game/ai/Tasks/PathHideTask.cpp b/game/ai/Tasks/PathHideTask.cpp new file mode 100644 index 000000000..0523b2540 --- /dev/null +++ b/game/ai/Tasks/PathHideTask.cpp @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathHideTask.h" +#include "../Library.h" + +namespace ai +{ + +PathHideTask::PathHideTask() : + PathTask() +{} + +PathHideTask::PathHideTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathHideTask::GetName() const +{ + static idStr _name(TASK_PATH_HIDE); + return _name; +} + +void PathHideTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Init the base class + PathTask::Init(owner, subsystem); + + // Make invisible and nonsolid + owner->Hide(); +} + +bool PathHideTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Hide task performing.\r"); + + idPathCorner* path = _path.GetEntity(); + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(path != NULL && owner != NULL); + + // Move on to next target + if (owner->IsHidden()) + { + // Trigger path targets, now that we've reached the corner + owner->ActivateTargets(owner); + + // NextPath(); + + // Move is done, fall back to PatrolTask + DM_LOG(LC_AI, LT_INFO)LOGSTRING("entity is hidden.\r"); + + return true; // finish this task + } + return false; +} + +PathHideTaskPtr PathHideTask::CreateInstance() +{ + return PathHideTaskPtr(new PathHideTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar pathHideTaskRegistrar( + TASK_PATH_HIDE, // Task Name + TaskLibrary::CreateInstanceFunc(&PathHideTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathHideTask.h b/game/ai/Tasks/PathHideTask.h new file mode 100644 index 000000000..6edb83408 --- /dev/null +++ b/game/ai/Tasks/PathHideTask.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_HIDE_TASK_H__ +#define __AI_PATH_HIDE_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_HIDE "PathHide" + +class PathHideTask; +typedef boost::shared_ptr PathHideTaskPtr; + +class PathHideTask : + public PathTask +{ +private: + PathHideTask(); + +public: + PathHideTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static PathHideTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_PATH_HIDE_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathInteractTask.cpp b/game/ai/Tasks/PathInteractTask.cpp similarity index 77% rename from DarkMod/AI/Tasks/PathInteractTask.cpp rename to game/ai/Tasks/PathInteractTask.cpp index 056e1495a..fe52835c2 100644 --- a/DarkMod/AI/Tasks/PathInteractTask.cpp +++ b/game/ai/Tasks/PathInteractTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathInteractTask.h b/game/ai/Tasks/PathInteractTask.h new file mode 100644 index 000000000..4e0f6f8d5 --- /dev/null +++ b/game/ai/Tasks/PathInteractTask.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_INTERACT_TASK_H__ +#define __AI_PATH_INTERACT_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_INTERACT "PathInteract" + +class PathInteractTask; +typedef boost::shared_ptr PathInteractTaskPtr; + +class PathInteractTask : + public PathTask +{ + idEntity* _target; + + int _waitEndTime; + + PathInteractTask(); + +public: + PathInteractTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathInteractTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_INTERACT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathLookatTask.cpp b/game/ai/Tasks/PathLookatTask.cpp similarity index 80% rename from DarkMod/AI/Tasks/PathLookatTask.cpp rename to game/ai/Tasks/PathLookatTask.cpp index f14b51093..d432d337a 100644 --- a/DarkMod/AI/Tasks/PathLookatTask.cpp +++ b/game/ai/Tasks/PathLookatTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathLookatTask.h b/game/ai/Tasks/PathLookatTask.h new file mode 100644 index 000000000..a925378fe --- /dev/null +++ b/game/ai/Tasks/PathLookatTask.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_LOOKAT_TASK_H__ +#define __AI_PATH_LOOKAT_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_LOOKAT "PathLookat" + +class PathLookatTask; +typedef boost::shared_ptr PathLookatTaskPtr; + +class PathLookatTask : + public PathTask +{ +private: + PathLookatTask(); + + idEntity* _focusEnt; + float _duration; + +public: + PathLookatTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathLookatTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_LOOKAT_TASK_H__ */ diff --git a/game/ai/Tasks/PathShowTask.cpp b/game/ai/Tasks/PathShowTask.cpp new file mode 100644 index 000000000..47ebf056f --- /dev/null +++ b/game/ai/Tasks/PathShowTask.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathShowTask.h" +#include "../Library.h" + +namespace ai +{ + +PathShowTask::PathShowTask() : + PathTask() +{} + +PathShowTask::PathShowTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathShowTask::GetName() const +{ + static idStr _name(TASK_PATH_SHOW); + return _name; +} + +void PathShowTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Just init the base class + PathTask::Init(owner, subsystem); +} + +bool PathShowTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Show task performing.\r"); + + idPathCorner* path = _path.GetEntity(); + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(path != NULL && owner != NULL); + + if (owner->CanBecomeSolid()) + { + owner->Show(); + } + + if (!owner->IsHidden()) + { + // Trigger path targets, now that we've reached the corner + owner->ActivateTargets(owner); + + // NextPath(); + + // Move is done, fall back to PatrolTask + DM_LOG(LC_AI, LT_INFO)LOGSTRING("entity is visible.\r"); + + return true; // finish this task + } + return false; +} + + +PathShowTaskPtr PathShowTask::CreateInstance() +{ + return PathShowTaskPtr(new PathShowTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar pathShowTaskRegistrar( + TASK_PATH_SHOW, // Task Name + TaskLibrary::CreateInstanceFunc(&PathShowTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathShowTask.h b/game/ai/Tasks/PathShowTask.h new file mode 100644 index 000000000..4c3964b66 --- /dev/null +++ b/game/ai/Tasks/PathShowTask.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_SHOW_TASK_H__ +#define __AI_PATH_SHOW_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_SHOW "PathShow" + +class PathShowTask; +typedef boost::shared_ptr PathShowTaskPtr; + +class PathShowTask : + public PathTask +{ +private: + PathShowTask(); +public: + PathShowTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static PathShowTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_SHOW_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PathSitTask.cpp b/game/ai/Tasks/PathSitTask.cpp similarity index 78% rename from DarkMod/AI/Tasks/PathSitTask.cpp rename to game/ai/Tasks/PathSitTask.cpp index 49840464b..e7237dcd5 100644 --- a/DarkMod/AI/Tasks/PathSitTask.cpp +++ b/game/ai/Tasks/PathSitTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PathSitTask.h b/game/ai/Tasks/PathSitTask.h new file mode 100644 index 000000000..23d5a8075 --- /dev/null +++ b/game/ai/Tasks/PathSitTask.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_SIT_TASK_H__ +#define __AI_PATH_SIT_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_SIT "PathSit" + +class PathSitTask; +typedef boost::shared_ptr PathSitTaskPtr; + +class PathSitTask : + public PathTask +{ +private: + int _waitEndTime; + + // Private constructor + PathSitTask(); + +public: + PathSitTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathSitTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_SIT_TASK_H__ */ diff --git a/game/ai/Tasks/PathSleepTask.cpp b/game/ai/Tasks/PathSleepTask.cpp new file mode 100644 index 000000000..f2d4b573f --- /dev/null +++ b/game/ai/Tasks/PathSleepTask.cpp @@ -0,0 +1,99 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathSleepTask.h" +#include "PathTurnTask.h" +#include "WaitTask.h" +#include "RepeatedBarkTask.h" +#include "../States/IdleSleepState.h" +#include "../Library.h" + +namespace ai +{ + +PathSleepTask::PathSleepTask() : + PathTask() +{} + +PathSleepTask::PathSleepTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathSleepTask::GetName() const +{ + static idStr _name(TASK_PATH_SLEEP); + return _name; +} + +void PathSleepTask::Init(idAI* owner, Subsystem& subsystem) +{ + PathTask::Init(owner, subsystem); + + if(_path.GetEntity()->spawnArgs.GetBool("lay_down_left", "1")) + { + owner->AI_LAY_DOWN_LEFT = true; + } + else + { + owner->AI_LAY_DOWN_LEFT = false; + } + + if (owner->GetMoveType() == MOVETYPE_ANIM) + { + owner->LayDown(); + } +} + +bool PathSleepTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("PathSleepTask performing.\r"); + + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with an empty owner pointer + assert(owner != NULL); + + if (owner->GetMoveType() == MOVETYPE_SLEEP) + { + return true; + } + return false; +} + +PathSleepTaskPtr PathSleepTask::CreateInstance() +{ + return PathSleepTaskPtr(new PathSleepTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar pathSleepTaskRegistrar( + TASK_PATH_SLEEP, // Task Name + TaskLibrary::CreateInstanceFunc(&PathSleepTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathSleepTask.h b/game/ai/Tasks/PathSleepTask.h new file mode 100644 index 000000000..133fff964 --- /dev/null +++ b/game/ai/Tasks/PathSleepTask.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_SLEEP_TASK_H__ +#define __AI_PATH_SLEEP_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_SLEEP "PathSleep" + +class PathSleepTask; +typedef boost::shared_ptr PathSleepTaskPtr; + +class PathSleepTask : + public PathTask +{ +private: + // Private constructor + PathSleepTask(); + +public: + PathSleepTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static PathSleepTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_PATH_SLEEP_TASK_H__ */ diff --git a/game/ai/Tasks/PathTask.cpp b/game/ai/Tasks/PathTask.cpp new file mode 100644 index 000000000..6048eab8a --- /dev/null +++ b/game/ai/Tasks/PathTask.cpp @@ -0,0 +1,80 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathTask.h" +#include "../Library.h" + +namespace ai +{ + +PathTask::PathTask() +{} + +PathTask::PathTask(idPathCorner* path) +{ + _path = path; +} + +void PathTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Just init the base class + Task::Init(owner, subsystem); + + if (_path.GetEntity() == NULL) + { + gameLocal.Error("Path Entity not set before Init()"); + } + + idPathCorner* path = _path.GetEntity(); + + _accuracy = path->spawnArgs.GetFloat("move_to_position_tolerance", "-1"); +} + + +void PathTask::SetTargetEntity(idPathCorner* path) +{ + assert(path); + _path = path; +} + +// Save/Restore methods +void PathTask::Save(idSaveGame* savefile) const +{ + Task::Save(savefile); + + _path.Save(savefile); + savefile->WriteFloat(_accuracy); +} + +void PathTask::Restore(idRestoreGame* savefile) +{ + Task::Restore(savefile); + + _path.Restore(savefile); + savefile->ReadFloat(_accuracy); +} + + +} // namespace ai diff --git a/game/ai/Tasks/PathTask.h b/game/ai/Tasks/PathTask.h new file mode 100644 index 000000000..f80d8750a --- /dev/null +++ b/game/ai/Tasks/PathTask.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_TASK_H__ +#define __AI_PATH_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH "Path" + +class PathTask; +typedef boost::shared_ptr PathTaskPtr; + +class PathTask : + public Task +{ +protected: + idEntityPtr _path; + float _accuracy; + + PathTask(); + +public: + PathTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const = 0; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem) = 0; + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + + // Class-specific methods + virtual void SetTargetEntity(idPathCorner* path); +}; + +} // namespace ai + +#endif /* __AI_PATH_TASK_H__ */ diff --git a/game/ai/Tasks/PathTurnTask.cpp b/game/ai/Tasks/PathTurnTask.cpp new file mode 100644 index 000000000..8107b733b --- /dev/null +++ b/game/ai/Tasks/PathTurnTask.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathTurnTask.h" +#include "../Library.h" + +namespace ai +{ + +PathTurnTask::PathTurnTask() : + PathTask() +{} + +PathTurnTask::PathTurnTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathTurnTask::GetName() const +{ + static idStr _name(TASK_PATH_TURN); + return _name; +} + +void PathTurnTask::Init(idAI* owner, Subsystem& subsystem) +{ + PathTask::Init(owner, subsystem); + + idPathCorner* path = _path.GetEntity(); + + //Start turning + float angle = path->spawnArgs.GetFloat("angle","0"); + owner->TurnToward(angle); +} + +bool PathTurnTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path Turn Task performing.\r"); + + idPathCorner* path = _path.GetEntity(); + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(path != NULL && owner != NULL); + + // Move on to next target when turning is done + if (owner->FacingIdeal()) + { + // Trigger path targets, now that we've reached the corner + owner->ActivateTargets(owner); + + // NextPath(); + + // Move is done, fall back to PatrolTask + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Turn is done.\r"); + + return true; // finish this task + } + return false; +} + +PathTurnTaskPtr PathTurnTask::CreateInstance() +{ + return PathTurnTaskPtr(new PathTurnTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar pathTurnTaskRegistrar( + TASK_PATH_TURN, // Task Name + TaskLibrary::CreateInstanceFunc(&PathTurnTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathTurnTask.h b/game/ai/Tasks/PathTurnTask.h new file mode 100644 index 000000000..dca48e148 --- /dev/null +++ b/game/ai/Tasks/PathTurnTask.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_TURN_TASK_H__ +#define __AI_PATH_TURN_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_TURN "PathTurn" + +class PathTurnTask; +typedef boost::shared_ptr PathTurnTaskPtr; + +class PathTurnTask : + public PathTask +{ +private: + PathTurnTask(); + +public: + PathTurnTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static PathTurnTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_TURN_TASK_H__ */ diff --git a/game/ai/Tasks/PathWaitForTriggerTask.cpp b/game/ai/Tasks/PathWaitForTriggerTask.cpp new file mode 100644 index 000000000..ff35ca937 --- /dev/null +++ b/game/ai/Tasks/PathWaitForTriggerTask.cpp @@ -0,0 +1,94 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathWaitForTriggerTask.h" +#include "../Library.h" + +namespace ai +{ + +PathWaitForTriggerTask::PathWaitForTriggerTask() : + PathTask() +{} + +PathWaitForTriggerTask::PathWaitForTriggerTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathWaitForTriggerTask::GetName() const +{ + static idStr _name(TASK_PATH_WAIT_FOR_TRIGGER); + return _name; +} + +void PathWaitForTriggerTask::Init(idAI* owner, Subsystem& subsystem) +{ + PathTask::Init(owner, subsystem); + + owner->AI_ACTIVATED = false; +} + +bool PathWaitForTriggerTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Path WaitForTrigger Task performing.\r"); + + idPathCorner* path = _path.GetEntity(); + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(path != NULL && owner != NULL); + + if (owner->AI_ACTIVATED) + { + owner->AI_ACTIVATED = false; + + // Trigger path targets, now that we've reached the corner + owner->ActivateTargets(owner); + + // NextPath(); + + // Move is done, fall back to PatrolTask + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Waiting for trigger is done.\r"); + + return true; // finish this task + } + return false; +} + +PathWaitForTriggerTaskPtr PathWaitForTriggerTask::CreateInstance() +{ + return PathWaitForTriggerTaskPtr(new PathWaitForTriggerTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar pathWaitForTriggerTaskRegistrar( + TASK_PATH_WAIT_FOR_TRIGGER, // Task Name + TaskLibrary::CreateInstanceFunc(&PathWaitForTriggerTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathWaitForTriggerTask.h b/game/ai/Tasks/PathWaitForTriggerTask.h new file mode 100644 index 000000000..5933b2a94 --- /dev/null +++ b/game/ai/Tasks/PathWaitForTriggerTask.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ +#define __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_WAIT_FOR_TRIGGER "PathWaitForTrigger" + +class PathWaitForTriggerTask; +typedef boost::shared_ptr PathWaitForTriggerTaskPtr; + +class PathWaitForTriggerTask : + public PathTask +{ +private: + PathWaitForTriggerTask(); +public: + PathWaitForTriggerTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static PathWaitForTriggerTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_WAIT_FOR_TRIGGER_TASK_H__ */ diff --git a/game/ai/Tasks/PathWaitTask.cpp b/game/ai/Tasks/PathWaitTask.cpp new file mode 100644 index 000000000..9601179b3 --- /dev/null +++ b/game/ai/Tasks/PathWaitTask.cpp @@ -0,0 +1,120 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "PathWaitTask.h" +#include "../Library.h" + +namespace ai +{ + +PathWaitTask::PathWaitTask() : + PathTask() +{} + +PathWaitTask::PathWaitTask(idPathCorner* path) : + PathTask(path) +{ + _path = path; +} + +// Get the name of this task +const idStr& PathWaitTask::GetName() const +{ + static idStr _name(TASK_PATH_WAIT); + return _name; +} + +void PathWaitTask::Init(idAI* owner, Subsystem& subsystem) +{ + PathTask::Init(owner, subsystem); + + idPathCorner* path = _path.GetEntity(); + + float waittime = path->spawnArgs.GetFloat("wait","0"); + float waitmax = path->spawnArgs.GetFloat("wait_max", "0"); + + if (waitmax > 0) + { + waittime += (waitmax - waittime) * gameLocal.random.RandomFloat(); + } + + waittime = SEC2MS(waittime); + + _endtime = waittime + gameLocal.time; +} + +bool PathWaitTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("PathWaitTask performing.\r"); + + idPathCorner* path = _path.GetEntity(); + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(path != NULL && owner != NULL); + + if (gameLocal.time >= _endtime) + { + // Trigger path targets, now that we've reached the corner + owner->ActivateTargets(owner); + + // NextPath(); + + // Wait is done, fall back to PatrolTask + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Wait is done.\r"); + + return true; // finish this task + } + return false; +} + + +// Save/Restore methods +void PathWaitTask::Save(idSaveGame* savefile) const +{ + PathTask::Save(savefile); + + savefile->WriteFloat(_endtime); +} + +void PathWaitTask::Restore(idRestoreGame* savefile) +{ + PathTask::Restore(savefile); + + savefile->ReadFloat(_endtime); +} + +PathWaitTaskPtr PathWaitTask::CreateInstance() +{ + return PathWaitTaskPtr(new PathWaitTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar PathWaitTaskRegistrar( + TASK_PATH_WAIT, // Task Name + TaskLibrary::CreateInstanceFunc(&PathWaitTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/PathWaitTask.h b/game/ai/Tasks/PathWaitTask.h new file mode 100644 index 000000000..c8154c629 --- /dev/null +++ b/game/ai/Tasks/PathWaitTask.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PATH_WAIT_TASK_H__ +#define __AI_PATH_WAIT_TASK_H__ + +#include "PathTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PATH_WAIT "PathWait" + +class PathWaitTask; +typedef boost::shared_ptr PathWaitTaskPtr; + +class PathWaitTask : + public PathTask +{ +private: + // The game time at which waiting ends in ms. + float _endtime; + + PathWaitTask(); +public: + PathWaitTask(idPathCorner* path); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PathWaitTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_PATH_WAIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/PlayAnimationTask.cpp b/game/ai/Tasks/PlayAnimationTask.cpp similarity index 80% rename from DarkMod/AI/Tasks/PlayAnimationTask.cpp rename to game/ai/Tasks/PlayAnimationTask.cpp index bc5d87024..5a9a62b29 100644 --- a/DarkMod/AI/Tasks/PlayAnimationTask.cpp +++ b/game/ai/Tasks/PlayAnimationTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/PlayAnimationTask.h b/game/ai/Tasks/PlayAnimationTask.h new file mode 100644 index 000000000..b0415d9f2 --- /dev/null +++ b/game/ai/Tasks/PlayAnimationTask.h @@ -0,0 +1,75 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_PLAY_ANIMATION_TASK_H__ +#define __AI_PLAY_ANIMATION_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_PLAY_ANIMATION "PlayAnimation" + +class PlayAnimationTask; +typedef boost::shared_ptr PlayAnimationTaskPtr; + +class PlayAnimationTask : + public Task +{ + idStr _animName; + + int _blendFrames; + + bool _playCycle; + + // Private constructor + PlayAnimationTask(); + +public: + // Pass the animation name directly here (like "idle_armwipe") + // Set playCycle to TRUE if this animation task should play continuously + PlayAnimationTask(const idStr& animName, int blendFrames, bool playCycle = false); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static PlayAnimationTaskPtr CreateInstance(); + +private: + // Private helper + void StartAnim(idAI* owner); +}; + +} // namespace ai + +#endif /* __AI_PLAY_ANIMATION_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RandomHeadturnTask.cpp b/game/ai/Tasks/RandomHeadturnTask.cpp similarity index 83% rename from DarkMod/AI/Tasks/RandomHeadturnTask.cpp rename to game/ai/Tasks/RandomHeadturnTask.cpp index a9e114616..2fd100234 100644 --- a/DarkMod/AI/Tasks/RandomHeadturnTask.cpp +++ b/game/ai/Tasks/RandomHeadturnTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/RandomHeadturnTask.h b/game/ai/Tasks/RandomHeadturnTask.h new file mode 100644 index 000000000..aa401dd0d --- /dev/null +++ b/game/ai/Tasks/RandomHeadturnTask.h @@ -0,0 +1,60 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_RANDOM_HEADTURN_TASK_H__ +#define __AI_RANDOM_HEADTURN_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_RANDOM_HEADTURN "RandomHeadturn" + +class RandomHeadturnTask; +typedef boost::shared_ptr RandomHeadturnTaskPtr; + +class RandomHeadturnTask : + public Task +{ +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static RandomHeadturnTaskPtr CreateInstance(); + +private: + /** + * SophisticatedZombie: This method handles a random chance of turning the AIs head + * (visual gaze movement) + */ + void PerformHeadTurnCheck(); + void SetNextHeadTurnCheckTime(); +}; + +} // namespace ai + +#endif /* __AI_RANDOM_HEADTURN_TASK_H__ */ diff --git a/game/ai/Tasks/RandomTurningTask.cpp b/game/ai/Tasks/RandomTurningTask.cpp new file mode 100644 index 000000000..b261d50e7 --- /dev/null +++ b/game/ai/Tasks/RandomTurningTask.cpp @@ -0,0 +1,111 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "RandomTurningTask.h" +#include "../Library.h" + +namespace ai +{ + +// Get the name of this task +const idStr& RandomTurningTask::GetName() const +{ + static idStr _name(TASK_RANDOM_TURNING); + return _name; +} + +void RandomTurningTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Just init the base class + Task::Init(owner, subsystem); + + _nextYaw = owner->GetCurrentYaw() + (gameLocal.random.RandomFloat() - 0.5) * 360; + owner->TurnToward(_nextYaw); + _turning = true; + _nextTurningTime = gameLocal.time; +} + +bool RandomTurningTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Random Turning Task performing.\r"); + + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointers + assert(owner != NULL); + + if (_turning && owner->FacingIdeal()) + { + // TODO: un-hardcode + int turnDelay = static_cast(1000 + gameLocal.random.RandomFloat() * 400); + + // Wait a bit before turning again + _nextTurningTime = gameLocal.time + turnDelay; + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Turn is done.\r"); + _turning = false; + _nextYaw = owner->GetCurrentYaw() + (gameLocal.random.RandomFloat() - 0.5) * 180; + + } + + if (!_turning && gameLocal.time >= _nextTurningTime) + { + owner->TurnToward(_nextYaw); + _turning = true; + } + + return false; +} + +// Save/Restore methods +void RandomTurningTask::Save(idSaveGame* savefile) const +{ + Task::Save(savefile); + + savefile->WriteFloat(_nextYaw); + savefile->WriteBool(_turning); + savefile->WriteInt(_nextTurningTime); +} + +void RandomTurningTask::Restore(idRestoreGame* savefile) +{ + Task::Restore(savefile); + + savefile->ReadFloat(_nextYaw); + savefile->ReadBool(_turning); + savefile->ReadInt(_nextTurningTime); +} + +RandomTurningTaskPtr RandomTurningTask::CreateInstance() +{ + return RandomTurningTaskPtr(new RandomTurningTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar randomTurningTaskRegistrar( + TASK_RANDOM_TURNING, // Task Name + TaskLibrary::CreateInstanceFunc(&RandomTurningTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/RandomTurningTask.h b/game/ai/Tasks/RandomTurningTask.h new file mode 100644 index 000000000..9310beae5 --- /dev/null +++ b/game/ai/Tasks/RandomTurningTask.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_RANDOM_TURNING_TASK_H__ +#define __AI_RANDOM_TURNING_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_RANDOM_TURNING "RandomTurning" + +class RandomTurningTask; +typedef boost::shared_ptr RandomTurningTaskPtr; + +class RandomTurningTask : + public Task +{ +private: + + float _nextYaw; + bool _turning; + int _nextTurningTime; + +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static RandomTurningTaskPtr CreateInstance(); + + // Class-specific methods +}; + +} // namespace ai + +#endif /* __AI_RANDOM_TURNING_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RangedCombatTask.cpp b/game/ai/Tasks/RangedCombatTask.cpp similarity index 77% rename from DarkMod/AI/Tasks/RangedCombatTask.cpp rename to game/ai/Tasks/RangedCombatTask.cpp index 1b79a59e6..ea6eb2bce 100644 --- a/DarkMod/AI/Tasks/RangedCombatTask.cpp +++ b/game/ai/Tasks/RangedCombatTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/RangedCombatTask.h b/game/ai/Tasks/RangedCombatTask.h new file mode 100644 index 000000000..0dc2fd2cc --- /dev/null +++ b/game/ai/Tasks/RangedCombatTask.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_RANGED_COMBAT_TASK_H__ +#define __AI_RANGED_COMBAT_TASK_H__ + +#include "CombatTask.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_RANGED_COMBAT "RangedCombat" + +class RangedCombatTask; +typedef boost::shared_ptr RangedCombatTaskPtr; + +class RangedCombatTask : + public CombatTask +{ + int _lastCombatBarkTime; +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Creates a new Instance of this task + static RangedCombatTaskPtr CreateInstance(); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); +}; + +} // namespace ai + +#endif /* __AI_RANGED_COMBAT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/RepeatedBarkTask.cpp b/game/ai/Tasks/RepeatedBarkTask.cpp similarity index 81% rename from DarkMod/AI/Tasks/RepeatedBarkTask.cpp rename to game/ai/Tasks/RepeatedBarkTask.cpp index d29eff364..0664f0779 100644 --- a/DarkMod/AI/Tasks/RepeatedBarkTask.cpp +++ b/game/ai/Tasks/RepeatedBarkTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/RepeatedBarkTask.h b/game/ai/Tasks/RepeatedBarkTask.h new file mode 100644 index 000000000..b8c26f616 --- /dev/null +++ b/game/ai/Tasks/RepeatedBarkTask.h @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_REPEATED_BARK_TASK_H__ +#define __AI_REPEATED_BARK_TASK_H__ + +#include "CommunicationTask.h" +#include "../../AIComm_Message.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_REPEATED_BARK "RepeatedBark" + +class RepeatedBarkTask; +typedef boost::shared_ptr RepeatedBarkTaskPtr; + +class RepeatedBarkTask : + public CommunicationTask +{ +private: + // times in milliseconds: + int _barkRepeatIntervalMin; + int _barkRepeatIntervalMax; + int _nextBarkTime; + + // The message which should be delivered when barking + CommMessagePtr _message; + + // Default Constructor + RepeatedBarkTask(); + +public: + /** + * greebo: Pass the sound shader name plus the interval range in milliseconds. + * The message argument is optional and can be used to let this Task emit messages + * when playing the sound. + */ + RepeatedBarkTask(const idStr& soundName, + int barkRepeatIntervalMin, int barkRepeatIntervalMax, + const CommMessagePtr& message = CommMessagePtr()); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static RepeatedBarkTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_REPEATED_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ResolveMovementBlockTask.cpp b/game/ai/Tasks/ResolveMovementBlockTask.cpp similarity index 95% rename from DarkMod/AI/Tasks/ResolveMovementBlockTask.cpp rename to game/ai/Tasks/ResolveMovementBlockTask.cpp index ec7131e19..fb47de4b4 100644 --- a/DarkMod/AI/Tasks/ResolveMovementBlockTask.cpp +++ b/game/ai/Tasks/ResolveMovementBlockTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/ResolveMovementBlockTask.h b/game/ai/Tasks/ResolveMovementBlockTask.h new file mode 100644 index 000000000..0b1313dde --- /dev/null +++ b/game/ai/Tasks/ResolveMovementBlockTask.h @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ +#define __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_RESOLVE_MOVEMENT_BLOCK "ResolveMovementBlock" +#define RESOLVE_MOVE_DIST 16 // grayman #2345 + +class ResolveMovementBlockTask; +typedef boost::shared_ptr ResolveMovementBlockTaskPtr; + +class ResolveMovementBlockTask : + public Task +{ +private: + // The entity in the way + idEntity* _blockingEnt; + + // The angles we had when starting this task + idAngles _initialAngles; + + int _preTaskContents; + + int _endTime; + + // Default constructor + ResolveMovementBlockTask(); + +public: + ResolveMovementBlockTask(idEntity* blockingEnt); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static ResolveMovementBlockTaskPtr CreateInstance(); + +private: + void InitBlockingAI(idAI* owner, Subsystem& subsystem); + void InitBlockingStatic(idAI* owner, Subsystem& subsystem); + + bool PerformBlockingAI(idAI* owner); + bool PerformBlockingStatic(idAI* owner); + bool Room2Pass(idAI* owner); // grayman #2345 + bool IsSolid(); // grayman #2345 + void BecomeNonSolid(idAI* owner); // grayman #2345 +}; + +} // namespace ai + +#endif /* __AI_RESOLVE_MOVEMENT_BLOCK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/ScriptTask.cpp b/game/ai/Tasks/ScriptTask.cpp similarity index 75% rename from DarkMod/AI/Tasks/ScriptTask.cpp rename to game/ai/Tasks/ScriptTask.cpp index 416aaa6d7..c2e0cee90 100644 --- a/DarkMod/AI/Tasks/ScriptTask.cpp +++ b/game/ai/Tasks/ScriptTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/ScriptTask.h b/game/ai/Tasks/ScriptTask.h new file mode 100644 index 000000000..1120099f1 --- /dev/null +++ b/game/ai/Tasks/ScriptTask.h @@ -0,0 +1,83 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_SCRIPT_TASK_H__ +#define __AI_SCRIPT_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_SCRIPT "ScriptTask" + +class ScriptTask; +typedef boost::shared_ptr ScriptTaskPtr; + +/** + * greebo: A ScriptTask can be plugged into any AI subsystem and + * has the only purpose to execute a script thread. The actual + * script function must be specified in the constructor and + * can bei either global or local (=defined on the AI's scriptobject). + * + * For local scripts, the function does not to take any arguments. + * For global scripts, the function needs to take an entity argument (=this owner). + * + * The Task is finishing itself when the script thread is done executing. + * + * Terminating this task will of course kill the thread. + */ +class ScriptTask : + public Task +{ + // The name of the script function to execute + idStr _functionName; + + // The script thread + idThread* _thread; + + // Private constructor + ScriptTask(); + +public: + // Optional constructor taking the function name + ScriptTask(const idStr& functionName); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Gets called when this task is finished (or gets terminated) + virtual void OnFinish(idAI* owner); + + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static ScriptTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_SCRIPT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/SingleBarkTask.cpp b/game/ai/Tasks/SingleBarkTask.cpp similarity index 81% rename from DarkMod/AI/Tasks/SingleBarkTask.cpp rename to game/ai/Tasks/SingleBarkTask.cpp index 5a948b63b..bdc3a8534 100644 --- a/DarkMod/AI/Tasks/SingleBarkTask.cpp +++ b/game/ai/Tasks/SingleBarkTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/Tasks/SingleBarkTask.h b/game/ai/Tasks/SingleBarkTask.h new file mode 100644 index 000000000..505a2523d --- /dev/null +++ b/game/ai/Tasks/SingleBarkTask.h @@ -0,0 +1,77 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_SINGLE_BARK_TASK_H__ +#define __AI_SINGLE_BARK_TASK_H__ + +#include "CommunicationTask.h" +#include "../../AIComm_Message.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_SINGLE_BARK "SingleBark" + +class SingleBarkTask; +typedef boost::shared_ptr SingleBarkTaskPtr; + +class SingleBarkTask : + public CommunicationTask +{ +protected: + int _startDelay; + + int _endTime; + + // The message which should be delivered when barking + CommMessagePtr _message; + + // Default constructor + SingleBarkTask(); + +public: + // Constructor taking a sound name as argument + // Optional arguments are the message to deliver + // and the time to pass in ms before the bark should be played + SingleBarkTask(const idStr& soundName, + const CommMessagePtr& message = CommMessagePtr(), + int startDelayMS = 0); + + // Get the name of this task + virtual const idStr& GetName() const; + + virtual void Init(idAI* owner, Subsystem& subsystem); + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static SingleBarkTaskPtr CreateInstance(); + + // Class-specific methods + virtual void SetSound(const idStr& soundName); + virtual void SetMessage(const CommMessagePtr& message); +}; + +} // namespace ai + +#endif /* __AI_SINGLE_BARK_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/Task.h b/game/ai/Tasks/Task.h similarity index 75% rename from DarkMod/AI/Tasks/Task.h rename to game/ai/Tasks/Task.h index d494f3ccb..188bd4ce0 100644 --- a/DarkMod/AI/Tasks/Task.h +++ b/game/ai/Tasks/Task.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __AI_TASK_H__ #define __AI_TASK_H__ diff --git a/DarkMod/AI/Tasks/ThrowObjectTask.cpp b/game/ai/Tasks/ThrowObjectTask.cpp similarity index 79% rename from DarkMod/AI/Tasks/ThrowObjectTask.cpp rename to game/ai/Tasks/ThrowObjectTask.cpp index f2b51f43a..fd48073f5 100644 --- a/DarkMod/AI/Tasks/ThrowObjectTask.cpp +++ b/game/ai/Tasks/ThrowObjectTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -46,7 +56,7 @@ bool ThrowObjectTask::Perform(Subsystem& subsystem) idAI* owner = _owner.GetEntity(); assert(owner != NULL); - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); idActor* enemy = owner->GetEnemy(); if (enemy == NULL) diff --git a/game/ai/Tasks/ThrowObjectTask.h b/game/ai/Tasks/ThrowObjectTask.h new file mode 100644 index 000000000..1eb3c9172 --- /dev/null +++ b/game/ai/Tasks/ThrowObjectTask.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_THROW_OBJECT_TASK_H__ +#define __AI_THROW_OBJECT_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_THROW_OBJECT "ThrowObject" + +class ThrowObjectTask; +typedef boost::shared_ptr ThrowObjectTaskPtr; + +class ThrowObjectTask : + public Task +{ + int _projectileDelayMin; + int _projectileDelayMax; + int _nextThrowObjectTime; + +public: + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + virtual void OnFinish(idAI* owner); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static ThrowObjectTaskPtr CreateInstance(); + +}; + +} // namespace ai + +#endif /* __AI_THROW_OBJECT_TASK_H__ */ diff --git a/game/ai/Tasks/WaitTask.cpp b/game/ai/Tasks/WaitTask.cpp new file mode 100644 index 000000000..8b3c43716 --- /dev/null +++ b/game/ai/Tasks/WaitTask.cpp @@ -0,0 +1,106 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Memory.h" +#include "WaitTask.h" +#include "../Library.h" + +namespace ai +{ + +WaitTask::WaitTask() : + _waitTime(0) +{} + +WaitTask::WaitTask(const int waitTime) : + _waitTime(waitTime) +{} + +// Get the name of this task +const idStr& WaitTask::GetName() const +{ + static idStr _name(TASK_WAIT); + return _name; +} + +void WaitTask::Init(idAI* owner, Subsystem& subsystem) +{ + // Just init the base class + Task::Init(owner, subsystem); + + _waitEndTime = gameLocal.time + _waitTime; +} + +bool WaitTask::Perform(Subsystem& subsystem) +{ + DM_LOG(LC_AI, LT_INFO)LOGSTRING("WaitTask performing.\r"); + + idAI* owner = _owner.GetEntity(); + + // This task may not be performed with empty entity pointer + assert(owner != NULL); + + // This task does nothing but wait until the time is over. + if (_waitEndTime <= gameLocal.time) + { + return true; + } + + return false; // not finished yet +} + +void WaitTask::SetTime(int waitTime) +{ + _waitTime = waitTime; +} + +// Save/Restore methods +void WaitTask::Save(idSaveGame* savefile) const +{ + Task::Save(savefile); + + savefile->WriteInt(_waitTime); + savefile->WriteInt(_waitEndTime); +} + +void WaitTask::Restore(idRestoreGame* savefile) +{ + Task::Restore(savefile); + + savefile->ReadInt(_waitTime); + savefile->ReadInt(_waitEndTime); +} + +WaitTaskPtr WaitTask::CreateInstance() +{ + return WaitTaskPtr(new WaitTask); +} + +// Register this task with the TaskLibrary +TaskLibrary::Registrar waitTaskRegistrar( + TASK_WAIT, // Task Name + TaskLibrary::CreateInstanceFunc(&WaitTask::CreateInstance) // Instance creation callback +); + +} // namespace ai diff --git a/game/ai/Tasks/WaitTask.h b/game/ai/Tasks/WaitTask.h new file mode 100644 index 000000000..409b1bcc3 --- /dev/null +++ b/game/ai/Tasks/WaitTask.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_WAIT_TASK_H__ +#define __AI_WAIT_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_WAIT "Wait" + +class WaitTask; +typedef boost::shared_ptr WaitTaskPtr; + +class WaitTask : + public Task +{ +private: + + int _waitTime; + int _waitEndTime; + + // Default constructor + WaitTask(); + +public: + + // Constructor with waittime (in ms) as input argument + WaitTask(const int waitTime); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + void SetTime(int waitTime); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static WaitTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_WAIT_TASK_H__ */ diff --git a/DarkMod/AI/Tasks/WanderInLocationTask.cpp b/game/ai/Tasks/WanderInLocationTask.cpp similarity index 81% rename from DarkMod/AI/Tasks/WanderInLocationTask.cpp rename to game/ai/Tasks/WanderInLocationTask.cpp index cf53a1bad..18f77d365 100644 --- a/DarkMod/AI/Tasks/WanderInLocationTask.cpp +++ b/game/ai/Tasks/WanderInLocationTask.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); @@ -101,7 +111,7 @@ bool WanderInLocationTask::Perform(Subsystem& subsystem) idAI* owner = _owner.GetEntity(); assert(owner != NULL); - Memory& memory = owner->GetMemory(); + //Memory& memory = owner->GetMemory(); if (owner->AI_MOVE_DONE) { diff --git a/game/ai/Tasks/WanderInLocationTask.h b/game/ai/Tasks/WanderInLocationTask.h new file mode 100644 index 000000000..417696152 --- /dev/null +++ b/game/ai/Tasks/WanderInLocationTask.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AI_WANDER_IN_LOCATION_TASK_H__ +#define __AI_WANDER_IN_LOCATION_TASK_H__ + +#include "Task.h" + +namespace ai +{ + +// Define the name of this task +#define TASK_WANDER_IN_LOCATION "WanderInLocation" + +class WanderInLocationTask; +typedef boost::shared_ptr WanderInLocationTaskPtr; + +class WanderInLocationTask : + public Task +{ + idVec3 _location; + + // Private default constructor + WanderInLocationTask(); +public: + // Constructor taking the target location as argument + WanderInLocationTask(const idVec3& location); + + // Get the name of this task + virtual const idStr& GetName() const; + + // Override the base Init method + virtual void Init(idAI* owner, Subsystem& subsystem); + + virtual bool Perform(Subsystem& subsystem); + + // Save/Restore methods + virtual void Save(idSaveGame* savefile) const; + virtual void Restore(idRestoreGame* savefile); + + // Creates a new Instance of this task + static WanderInLocationTaskPtr CreateInstance(); +}; + +} // namespace ai + +#endif /* __AI_WANDER_IN_LOCATION_TASK_H__ */ diff --git a/game/ai/aas.cpp b/game/ai/aas.cpp deleted file mode 100644 index 6e1276f91..000000000 --- a/game/ai/aas.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "aas_local.h" - - -/* -============ -idAAS::Alloc -============ -*/ -idAAS *idAAS::Alloc( void ) { - return new idAASLocal; -} - -/* -============ -idAAS::idAAS -============ -*/ -idAAS::~idAAS( void ) { -} - -/* -============ -idAASLocal::idAASLocal -============ -*/ -idAASLocal::idAASLocal( void ) -{ - elevatorSystem = new eas::tdmEAS(this); - file = NULL; -} - -/* -============ -idAASLocal::~idAASLocal -============ -*/ -idAASLocal::~idAASLocal( void ) { - Shutdown(); - - if (elevatorSystem != NULL) - { - delete elevatorSystem; - } -} - -/* -============ -idAASLocal::Init -============ -*/ -bool idAASLocal::Init( const idStr &mapName, unsigned int mapFileCRC ) { - // Clear the elevator system before reloading - elevatorSystem->Clear(); - - if ( file && mapName.Icmp( file->GetName() ) == 0 && mapFileCRC == file->GetCRC() ) { - common->Printf( "Keeping %s\n", file->GetName() ); - RemoveAllObstacles(); - } - else { - Shutdown(); - - file = AASFileManager->LoadAAS( mapName, mapFileCRC ); - if ( !file ) { - common->DWarning( "Couldn't load AAS file: '%s'", mapName.c_str() ); - return false; - } - mapName.ExtractFileExtension(name); - - SetupRouting(); - } - return true; -} - -/* -============ -idAASLocal::Shutdown -============ -*/ -void idAASLocal::Shutdown( void ) { - if ( file ) { - elevatorSystem->Clear(); - ShutdownRouting(); - RemoveAllObstacles(); - AASFileManager->FreeAAS( file ); - file = NULL; - } -} - -/* -============ -idAASLocal::TestIfBarrierIsolatesReachability -============ -*/ -bool idAASLocal::TestIfBarrierIsolatesReachability -( - idReachability* p_reachability, - int areaIndex, - idBounds barrierBounds -) const -{ - /* - * Test params - */ - if ( p_reachability == NULL) - { - return false; - } - - // Test the paths from the reachability to all other reachabilities leaving - // the area. If a reachability has no path to another reachability that does not - // intersect the barrier, then return true. Also if there are no other reachbilities - // return true. Otherwise return false; - - // Iterate the other reachabilities - bool b_hadPath = false; - bool b_foundClearPath = false; - idReachability* p_reach2 = GetAreaFirstReachability(areaIndex); - - while (p_reach2 != NULL) - { - if (p_reach2 != p_reachability) - { - b_hadPath = true; - - // Test if path between the reachabilities is blocked by the barrier bounds - if (barrierBounds.LineIntersection (p_reachability->start, p_reach2->start)) - { - // Blocked - return true; - } - /* - // Its not blocked - b_foundClearPath = true; - } - */ - - } // Not same reachability - - // Is it blocked? - if (b_foundClearPath) - { - // End iteration early if we already found a clear path - p_reach2 = NULL; - } - else - { - p_reach2 = p_reach2->next; - } - - } // Next other reachability on same area - - return false; - - /* - - // Return result of test - if ( (b_hadPath) && (!b_foundClearPath) ) - { - // Its isolated by the bounds given - return true; - } - else - { - // Its not isolated by the bounds given - return false; - } - */ - -} - - -/* -============ -idAASLocal::Stats -============ -*/ -void idAASLocal::Stats( void ) const { - if ( !file ) { - return; - } - common->Printf( "[%s]\n", file->GetName() ); - file->PrintInfo(); - RoutingStats(); -} - -/* -============ -idAASLocal::GetSettings -============ -*/ -const idAASSettings *idAASLocal::GetSettings( void ) const { - if ( !file ) { - return NULL; - } - return &file->GetSettings(); -} - -/* -============ -idAASLocal::PointAreaNum -============ -*/ -int idAASLocal::PointAreaNum( const idVec3 &origin ) const { - if ( !file ) { - return 0; - } - return file->PointAreaNum( origin ); -} - -/* -============ -idAASLocal::PointReachableAreaNum -============ -*/ -int idAASLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const { - if ( !file ) { - return 0; - } - - return file->PointReachableAreaNum( origin, searchBounds, areaFlags, TFL_INVALID ); -} - -/* -============ -idAASLocal::BoundsReachableAreaNum -============ -*/ -int idAASLocal::BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const { - if ( !file ) { - return 0; - } - - return file->BoundsReachableAreaNum( bounds, areaFlags, TFL_INVALID ); -} - -/* -============ -idAASLocal::PushPointIntoAreaNum -============ -*/ -void idAASLocal::PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const { - if ( !file ) { - return; - } - file->PushPointIntoAreaNum( areaNum, origin ); -} - -/* -============ -idAASLocal::AreaCenter -============ -*/ -idVec3 idAASLocal::AreaCenter( int areaNum ) const { - if ( !file ) { - return vec3_origin; - } - return file->GetArea( areaNum ).center; -} - -/* -============ -idAASLocal::AreaFlags -============ -*/ -int idAASLocal::AreaFlags( int areaNum ) const { - if ( !file ) { - return 0; - } - return file->GetArea( areaNum ).flags; -} - -/* -============ -idAASLocal::AreaTravelFlags -============ -*/ -int idAASLocal::AreaTravelFlags( int areaNum ) const { - if ( !file ) { - return 0; - } - return file->GetArea( areaNum ).travelFlags; -} - -/* -============ -idAASLocal::Trace -============ -*/ -bool idAASLocal::Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const { - if ( !file ) { - trace.fraction = 0.0f; - trace.lastAreaNum = 0; - trace.numAreas = 0; - return true; - } - return file->Trace( trace, start, end ); -} - -/* -============ -idAASLocal::GetPlane -============ -*/ -const idPlane &idAASLocal::GetPlane( int planeNum ) const { - if ( !file ) { - static idPlane dummy; - return dummy; - } - return file->GetPlane( planeNum ); -} - -/* -============ -idAASLocal::GetEdgeVertexNumbers -============ -*/ -void idAASLocal::GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const { - if ( !file ) { - verts[0] = verts[1] = 0; - return; - } - const int *v = file->GetEdge( abs(edgeNum) ).vertexNum; - verts[0] = v[INTSIGNBITSET(edgeNum)]; - verts[1] = v[INTSIGNBITNOTSET(edgeNum)]; -} - -/* -============ -idAASLocal::GetEdge -============ -*/ -void idAASLocal::GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const { - if ( !file ) { - start.Zero(); - end.Zero(); - return; - } - const int *v = file->GetEdge( abs(edgeNum) ).vertexNum; - start = file->GetVertex( v[INTSIGNBITSET(edgeNum)] ); - end = file->GetVertex( v[INTSIGNBITNOTSET(edgeNum)] ); -} - - -/* -**********************************************************8 -Added for Darkmod by SophisticatedZombie -**********************************************************8 -*/ - - -/* -============ -idAASLocal::GetAreaBounds -============ -*/ -idBounds idAASLocal::GetAreaBounds( int areaNum ) const { - if ( !file ) - { - idBounds emptyBounds; - return emptyBounds; - } - return file->AreaBounds(areaNum); -} - -/* -============ -idAASLocal::GetNumAreas -============ -*/ -int idAASLocal::GetNumAreas() const -{ - if (!file) - { - return -1; - } - else - { - return file->GetNumAreas(); - } - -} - -/* -============ -idAASLocal::GetAreaFirstReachability -============ -*/ - -idReachability* idAASLocal::GetAreaFirstReachability(int areaNum) const -{ - if ( !file ) - { - return NULL; - } - aasArea_t area = file->GetArea (areaNum); - return area.reach; - -} - -void idAASLocal::SetAreaTravelFlag( int index, int flag ) -{ - if (file != NULL) - { - file->SetAreaTravelFlag(index, flag); - } -} - -void idAASLocal::RemoveAreaTravelFlag( int index, int flag ) -{ - if (file != NULL) - { - file->RemoveAreaTravelFlag(index, flag); - } -} - -int idAASLocal::GetClusterNum(int areaNum) -{ - return file->GetArea( areaNum ).cluster; -} - -void idAASLocal::ReferenceDoor(CFrobDoor* door, int areaNum) -{ - _doors[areaNum] = door; -} - -void idAASLocal::DeReferenceDoor(CFrobDoor* door, int areaNum) -{ - DoorMap::iterator found = _doors.find(areaNum); - - if (found != _doors.end()) - { - _doors.erase(found); - } -} - -CFrobDoor* idAASLocal::GetDoor(int areaNum) const -{ - DoorMap::const_iterator found = _doors.find(areaNum); - if (found != _doors.end()) - { - return found->second; - } - return NULL; -} - -void idAASLocal::Save(idSaveGame* savefile) const -{ - elevatorSystem->Save(savefile); -} - -void idAASLocal::Restore(idRestoreGame* savefile) -{ - elevatorSystem->Restore(savefile); -} - -/* -============ -idAASLocal::BuildReachbilityImpactList -============ -*/ - -bool idAASLocal::BuildReachabilityImpactList -( - TReachabilityTrackingList& inout_reachabilityList, - idBounds impactBounds -) const -{ - - // Start with empty list - inout_reachabilityList.Clear(); - - // For each area - int numAreas = GetNumAreas(); - for (int areaIndex = 0; areaIndex < numAreas; areaIndex ++) - { - // Test this area's reachabilties - idReachability* p_reach = GetAreaFirstReachability (areaIndex); - - while (p_reach != NULL) - { - // If this reachability is isolated by the impact bounds, then ad it to the list - if (TestIfBarrierIsolatesReachability (p_reach, areaIndex, impactBounds)) - { - inout_reachabilityList.Append (p_reach); - } - - // Next reachability - p_reach = p_reach->next; - - } // Reachability intersects given bounds - - - } // Next area - - // Done - return true; - -} diff --git a/game/ai/aas.h b/game/ai/aas.h deleted file mode 100644 index e68a44519..000000000 --- a/game/ai/aas.h +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __AAS_H__ -#define __AAS_H__ - -// Need linked list -#include "../../idlib/containers/list.h" -#include "../../DarkMod/AI/EAS/RouteInfo.h" - -class CFrobDoor; - -#ifdef __linux__ -#include "tools/compilers/aas/aasfile.h" -#endif - -/* -=============================================================================== - - Area Awareness System - -=============================================================================== -*/ - -enum { - PATHTYPE_WALK, - PATHTYPE_WALKOFFLEDGE, - PATHTYPE_BARRIERJUMP, - PATHTYPE_JUMP, - PATHTYPE_DOOR, - PATHTYPE_ELEVATOR, // greebo: Added for TDM -}; - -typedef struct aasPath_s { - int type; // path type - idVec3 moveGoal; // point the AI should move towards - int moveAreaNum; // number of the area the AI should move towards - idVec3 secondaryGoal; // secondary move goal for complex navigation - const idReachability * reachability; // reachability used for navigation - eas::RouteInfoPtr elevatorRoute; // EAS reachability information (NULL if unused) - CFrobDoor* firstDoor; // angua: when a door is in the path, this is stored here (NULL otherwise) -} aasPath_t; - - -typedef struct aasGoal_s { - int areaNum; // area the goal is in - idVec3 origin; // position of goal -} aasGoal_t; - - -typedef struct aasObstacle_s { - idBounds absBounds; // absolute bounds of obstacle - idBounds expAbsBounds; // expanded absolute bounds of obstacle -} aasObstacle_t; - -class idAASCallback { -public: - virtual ~idAASCallback() {}; - virtual bool TestArea( const class idAAS *aas, int areaNum ) = 0; -}; - -typedef int aasHandle_t; - -/** -* This is the typedef for a reachability tracking list -*/ -typedef idList TReachabilityTrackingList; -namespace eas { class tdmEAS; } - -class idAAS { -public: - static idAAS * Alloc( void ); - virtual ~idAAS( void ) = 0; - // Initialize for the given map. - virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ) = 0; - // Print AAS stats. - virtual void Stats( void ) const = 0; - // Test from the given origin. - virtual void Test( const idVec3 &origin ) = 0; - // Get the AAS settings. - virtual const idAASSettings *GetSettings( void ) const = 0; - // Returns the number of the area the origin is in. - virtual int PointAreaNum( const idVec3 &origin ) const = 0; - // Returns the number of the nearest reachable area for the given point. - virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &bounds, const int areaFlags ) const = 0; - // Returns the number of the first reachable area in or touching the bounds. - virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const = 0; - - // Push the point into the area. - /** - * greebo: Copied from d3world: this is what brian from id said about PushPointIntoAreaNum: - * - * Quote: "If the point is already in the specified area, it does nothing, otherwise it 'pushes' - * the point into the area by moving it along the surface normal of all the planes that make up the area. - * Imagine if an area were a box and the point were outside the bottom right side of the box, - * it would first push the point along the right normal so it would be below the box, then it - * would push the point along the bottom normal so it would be inside the box." - * - * greebo: So basically, this alters the given idVec3 , so that it ends up being in the area box. - */ - virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const = 0; - - // Returns a reachable point inside the given area. - virtual idVec3 AreaCenter( int areaNum ) const = 0; - // Returns the area flags. - virtual int AreaFlags( int areaNum ) const = 0; - // Returns the travel flags for traveling through the area. - virtual int AreaTravelFlags( int areaNum ) const = 0; - // Trace through the areas and report the first collision. - virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0; - // Get a plane for a trace. - virtual const idPlane & GetPlane( int planeNum ) const = 0; - // Get wall edges. - virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const = 0; - // Sort the wall edges to create continuous sequences of walls. - virtual void SortWallEdges( int *edges, int numEdges ) const = 0; - // Get the vertex numbers for an edge. - virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const = 0; - // Get an edge. - virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const = 0; - // Find all areas within or touching the bounds with the given contents and disable/enable them for routing. - virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) = 0; - - // angua: disable / enable a specific area - virtual void DisableArea( int areanum ) = 0; - virtual void EnableArea( int areanum ) = 0; - - // Add an obstacle to the routing system. - virtual aasHandle_t AddObstacle( const idBounds &bounds ) = 0; - // Remove an obstacle from the routing system. - virtual void RemoveObstacle( const aasHandle_t handle ) = 0; - // Remove all obstacles from the routing system. - virtual void RemoveAllObstacles( void ) = 0; - // Returns the travel time towards the goal area in 100th of a second. - virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const = 0; - - /** - * greebo: Tries to set up a reachability between and . Uses the local routingcache. - * - * @areaNum/origin: the starting position and AAS area number. - * @goalAreaNum: The AAS area number of the destination - * @travelFlags: The allowed travelflags (used to determine which routing cache should be used). - * - * @travelTime: Will hold the total traveltime of the best reachability or 0 if no route is found. - * @reach: A reference to a idReachability* pointer. The pointer is set to NULL if no route is found, otherwise it contains the best reachability. - * @door: if there is a door in the path, this stores a pointer to in (NULL otherwise) - * @actor: the calling actor (optional). Is used to determine whether walk paths are valid (through locked doors, for instance). - * - * @returns TRUE if a route is available, FALSE otherwise. - * - * Note: A route is usually available if - * a) the goal area and the starting area are in the same cluster (no portals in between) - * b) the clusters are connected via a portal. - */ - // Get the travel time and first reachability to be used towards the goal, returns true if there is a path. - virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach, CFrobDoor** firstDoor, idActor* actor ) const = 0; - - /** - * greebo: Tries to set up a walk path from areaNum/origin to goalAreaNum/goalOrigin for the given travel flags. - * - * @path: The path structure which will contain the resulting path information. Will contain the starting point if no path is found. - * @areaNum/origin: the AAS area number and origin of the starting point. - * @goalAreaNum/goalOrigin: the AAS area number and origin of the destination. - * @travelFlags: the allowed travelflags (e.g. TFL_WALK|TFL_DOOR) - * @actor: The calling actor (optional), this is used to identify locked doors, which the actor is aware of. - * - * @returns: TRUE if a walk path could be found, FALSE otherwise. - */ - // Creates a walk path towards the goal. - virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ) = 0; - - /** - * Returns true if one can walk along a straight line from the origin to the goal origin. - * angua: actor is used to handle AI-specific pathing, such as forbidden areas (e.g. locked doors) - * actor can be NULL - */ - virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor ) const = 0; - // Creates a fly path towards the goal. - virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0; - // Returns true if one can fly along a straight line from the origin to the goal origin. - virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0; - // Show the walk path from the origin towards the area. - virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) = 0; - // Show the fly path from the origin towards the area. - virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0; - // Find the nearest goal which satisfies the callback. - virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxDistance=0 ) const = 0; - - // Find the goal cloest to the target which satisfies the callback. - virtual bool FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const = 0; - - // Added for DarkMod by SophisticatedZombie(DMH) - virtual idBounds GetAreaBounds (int areaNum) const = 0; - virtual int GetNumAreas() const = 0; - virtual idReachability* GetAreaFirstReachability(int areaNum) const = 0; - - virtual void SetAreaTravelFlag( int index, int flag ) = 0; - virtual void RemoveAreaTravelFlag( int index, int flag ) = 0; - - virtual void ReferenceDoor(CFrobDoor* door, int areaNum) = 0; - virtual void DeReferenceDoor(CFrobDoor* door, int areaNum) = 0; - - virtual CFrobDoor* GetDoor(int areaNum) const = 0; - - /** - * This function fills a reachability list - * given an aas and the bounds for which any - * intersecting reachabilities should be considered - * impacted. - * - * @param inout_reachbilityList The list which will be - * initialized to only the idReachability pointers - * which are intersected by the impactBounds parameter - * - * @param impactBounds The bounds we check against - * reachabilities for intersection to determine impact. - * - * @return true on success - * - * @return false on failure - */ - virtual bool BuildReachabilityImpactList - ( - TReachabilityTrackingList& inout_reachabilityList, - idBounds impactBounds - ) const = 0; - - /** - * This method tests if a reachability is cut off from all - * other reachabilities in the same area by the bounds - * given. Note that iff there are no other reachabilities on - * then the reachability is NOT considered isolated. - * - * @param p_reachability The reachability that we are testing - * to see if the given barrierBounds isolate it from any - * other reachabilities on the same area. - * - * @param areaIndex The index of the area to which the reachability belongs - * - * @param barrierBounds The bounds of the barrier we are considering - * - * @return true if the reachability is isolated by the given bounds - * from all other reachbailities on the same area - * - * @return false otherwise - */ - virtual bool TestIfBarrierIsolatesReachability - ( - idReachability* p_reachability, - int areaIndex, - idBounds barrierBounds - ) const = 0; - - // Accessor function for the EAS - virtual eas::tdmEAS* GetEAS() = 0; - - // Save/Restore routines - virtual void Save(idSaveGame* savefile) const = 0; - virtual void Restore(idRestoreGame* savefile) = 0; -}; - -#endif /* !__AAS_H__ */ diff --git a/game/ai/aas_debug.cpp b/game/ai/aas_debug.cpp deleted file mode 100644 index 2f425aaa5..000000000 --- a/game/ai/aas_debug.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "aas_local.h" -#include "../game_local.h" // for cvars and debug drawing - - -/* -============ -idAASLocal::DrawCone -============ -*/ -void idAASLocal::DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const { - int i; - idMat3 axis; - idVec3 center, top, p, lastp; - - axis[2] = dir; - axis[2].NormalVectors( axis[0], axis[1] ); - axis[1] = -axis[1]; - - center = origin + dir; - top = center + dir * (3.0f * radius); - lastp = center + radius * axis[1]; - - for ( i = 20; i <= 360; i += 20 ) { - p = center + sin( DEG2RAD(i) ) * radius * axis[0] + cos( DEG2RAD(i) ) * radius * axis[1]; - gameRenderWorld->DebugLine( color, lastp, p, 0 ); - gameRenderWorld->DebugLine( color, p, top, 0 ); - lastp = p; - } -} - -/* -============ -idAASLocal::DrawReachability -============ -*/ -void idAASLocal::DrawReachability( const idReachability *reach ) const -{ - idVec4 reachColor = colorCyan; - if (reach->travelType & TFL_DOOR) - { - reachColor = colorRed; - } - gameRenderWorld->DebugArrow( reachColor, reach->start, reach->end, 1, 10000 ); - - gameRenderWorld->DebugArrow( colorLtGrey, AreaCenter(reach->fromAreaNum), AreaCenter(reach->toAreaNum), 1, 10000); - - if ( gameLocal.GetLocalPlayer() ) { - gameRenderWorld->DrawText( va( "%d", reach->edgeNum ), ( reach->start + reach->end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAxis, 1, 10000 ); - } - - switch( reach->travelType ) { - case TFL_WALK: { -// const idReachability_Walk *walk = static_cast(reach); - break; - } - default: { - break; - } - } -} - -/* -============ -idAASLocal::DrawEdge -============ -*/ -void idAASLocal::DrawEdge( int edgeNum, bool arrow ) const { - const aasEdge_t *edge; - idVec4 *color; - - if ( !file ) { - return; - } - - edge = &file->GetEdge( edgeNum ); - color = &colorRed; - if ( arrow ) { - gameRenderWorld->DebugArrow( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ), 1 ); - } else { - gameRenderWorld->DebugLine( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ) ); - } - - if ( gameLocal.GetLocalPlayer() ) { - gameRenderWorld->DrawText( va( "%d", edgeNum ), ( file->GetVertex( edge->vertexNum[0] ) + file->GetVertex( edge->vertexNum[1] ) ) * 0.5f + idVec3(0,0,4), 0.1f, colorRed, gameLocal.GetLocalPlayer()->viewAxis ); - } -} - -/* -============ -idAASLocal::DrawFace -============ -*/ -void idAASLocal::DrawFace( int faceNum, bool side ) const { - int i, j, numEdges, firstEdge; - const aasFace_t *face; - idVec3 mid, end; - - if ( !file ) { - return; - } - - face = &file->GetFace( faceNum ); - numEdges = face->numEdges; - firstEdge = face->firstEdge; - - mid = vec3_origin; - for ( i = 0; i < numEdges; i++ ) { - DrawEdge( abs( file->GetEdgeIndex( firstEdge + i ) ), ( face->flags & FACE_FLOOR ) != 0 ); - j = file->GetEdgeIndex( firstEdge + i ); - mid += file->GetVertex( file->GetEdge( abs( j ) ).vertexNum[ j < 0 ] ); - } - - mid /= numEdges; - if ( side ) { - end = mid - 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal(); - } else { - end = mid + 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal(); - } - gameRenderWorld->DebugArrow( colorGreen, mid, end, 1 ); -} - -/* -============ -idAASLocal::DrawArea -============ -*/ -void idAASLocal::DrawArea( int areaNum ) const { - int i, numFaces, firstFace; - const aasArea_t *area; - idReachability *reach; - - if ( !file ) { - return; - } - - area = &file->GetArea( areaNum ); - numFaces = area->numFaces; - firstFace = area->firstFace; - - for ( i = 0; i < numFaces; i++ ) { - DrawFace( abs( file->GetFaceIndex( firstFace + i ) ), file->GetFaceIndex( firstFace + i ) < 0 ); - } - - for ( reach = area->reach; reach; reach = reach->next ) { - DrawReachability( reach ); - } -} - -/* -============ -idAASLocal::DefaultSearchBounds -============ -*/ -const idBounds &idAASLocal::DefaultSearchBounds( void ) const { - return file->GetSettings().boundingBoxes[0]; -} - -/* -============ -idAASLocal::ShowArea -============ -*/ -void idAASLocal::ShowArea( const idVec3 &origin ) const { - static int lastAreaNum; - int areaNum; - const aasArea_t *area; - idVec3 org; - - areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - org = origin; - PushPointIntoAreaNum( areaNum, org ); - - if ( aas_goalArea.GetInteger() ) { - int travelTime; - idReachability *reach; - - RouteToGoalArea( areaNum, org, aas_goalArea.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach, NULL, NULL ); - gameLocal.Printf( "\rtt = %4d", travelTime ); - if ( reach ) { - gameLocal.Printf( " to area %4d", reach->toAreaNum ); - DrawArea( reach->toAreaNum ); - } - } - - if ( areaNum != lastAreaNum ) { - area = &file->GetArea( areaNum ); - gameLocal.Printf( "area %d: ", areaNum ); - if ( area->flags & AREA_LEDGE ) { - gameLocal.Printf( "AREA_LEDGE " ); - } - if (area->flags & AREA_DOOR) - { - gameLocal.Printf( "AREA_DOOR " ); - } - if ( area->flags & AREA_REACHABLE_WALK ) { - gameLocal.Printf( "AREA_REACHABLE_WALK " ); - } - if ( area->flags & AREA_REACHABLE_FLY ) { - gameLocal.Printf( "AREA_REACHABLE_FLY " ); - } - if ( area->contents & AREACONTENTS_CLUSTERPORTAL ) { - gameLocal.Printf( "AREACONTENTS_CLUSTERPORTAL " ); - } - if ( area->contents & AREACONTENTS_OBSTACLE ) { - gameLocal.Printf( "AREACONTENTS_OBSTACLE " ); - } - gameLocal.Printf( "\n" ); - lastAreaNum = areaNum; - } - - if ( org != origin ) { - idBounds bnds = file->GetSettings().boundingBoxes[ 0 ]; - bnds[ 1 ].z = bnds[ 0 ].z; - gameRenderWorld->DebugBounds( colorYellow, bnds, org ); - } - - DrawArea( areaNum ); -} - -/* -============ -idAASLocal::ShowWalkPath -============ -*/ -void idAASLocal::ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) { - int i, areaNum, curAreaNum, travelTime; - idReachability *reach; - idVec3 org, areaCenter; - aasPath_t path; - - if ( !file ) { - return; - } - - org = origin; - areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_WALK ); - PushPointIntoAreaNum( areaNum, org ); - curAreaNum = areaNum; - - for ( i = 0; i < 100; i++ ) { - - if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_AIR, travelTime, &reach, NULL, NULL ) ) { - break; - } - - if ( !reach ) { - break; - } - - gameRenderWorld->DebugArrow( colorGreen, org, reach->start, 1, 10000 ); - DrawReachability( reach ); - - if ( reach->toAreaNum == goalAreaNum ) { - break; - } - - curAreaNum = reach->toAreaNum; - org = reach->end; - } - - if ( WalkPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_AIR, NULL ) ) { - gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 1, 10000 ); - } -} - -/* -============ -idAASLocal::ShowFlyPath -============ -*/ -void idAASLocal::ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const { - int i, areaNum, curAreaNum, travelTime; - idReachability *reach; - idVec3 org, areaCenter; - aasPath_t path; - - if ( !file ) { - return; - } - - org = origin; - areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_FLY ); - PushPointIntoAreaNum( areaNum, org ); - curAreaNum = areaNum; - - for ( i = 0; i < 100; i++ ) { - - if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_FLY|TFL_AIR, travelTime, &reach, NULL, NULL ) ) { - break; - } - - if ( !reach ) { - break; - } - - gameRenderWorld->DebugArrow( colorPurple, org, reach->start, 2 ); - DrawReachability( reach ); - - if ( reach->toAreaNum == goalAreaNum ) { - break; - } - - curAreaNum = reach->toAreaNum; - org = reach->end; - } - - if ( FlyPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_FLY|TFL_AIR ) ) { - gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 ); - } -} - -/* -============ -idAASLocal::ShowWallEdges -============ -*/ -void idAASLocal::ShowWallEdges( const idVec3 &origin ) const { - int i, areaNum, numEdges, edges[1024]; - idVec3 start, end; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - - areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 ); - for ( i = 0; i < numEdges; i++ ) { - GetEdge( edges[i], start, end ); - gameRenderWorld->DebugLine( colorRed, start, end ); - gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis ); - } -} - -/* -============ -idAASLocal::ShowHideArea -============ -*/ -void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) { - int areaNum, numObstacles; - idVec3 target; - aasGoal_t goal; - aasObstacle_t obstacles[10]; - - areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - target = AreaCenter( targetAreaNum ); - - // consider the target an obstacle - obstacles[0].absBounds = idBounds( target ).Expand( 16 ); - numObstacles = 1; - - DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow ); - - idAASFindCover findCover( NULL, NULL, target ); - if ( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK|TFL_AIR, obstacles, numObstacles, findCover ) ) { - DrawArea( goal.areaNum ); - ShowWalkPath( origin, goal.areaNum, goal.origin ); - DrawCone( goal.origin, idVec3(0,0,1), 16.0f, colorWhite ); - } -} - -/* -============ -idAASLocal::PullPlayer -============ -*/ -bool idAASLocal::PullPlayer( const idVec3 &origin, int toAreaNum ) { - int areaNum; - idVec3 areaCenter, dir, vel; - idAngles delta; - aasPath_t path; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return true; - } - - idPhysics *physics = player->GetPhysics(); - if ( !physics ) { - return true; - } - - if ( !toAreaNum ) { - return false; - } - - areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - areaCenter = AreaCenter( toAreaNum ); - if ( player->GetPhysics()->GetAbsBounds().Expand( 8 ).ContainsPoint( areaCenter ) ) { - return false; - } - if ( WalkPathToGoal( path, areaNum, origin, toAreaNum, areaCenter, TFL_WALK|TFL_AIR, NULL ) ) { - dir = path.moveGoal - origin; - dir[2] *= 0.5f; - dir.Normalize(); - delta = dir.ToAngles() - player->cmdAngles - player->GetDeltaViewAngles(); - delta.Normalize180(); - player->SetDeltaViewAngles( player->GetDeltaViewAngles() + delta * 0.1f ); - dir[2] = 0.0f; - dir.Normalize(); - dir *= 100.0f; - vel = physics->GetLinearVelocity(); - dir[2] = vel[2]; - physics->SetLinearVelocity( dir ); - return true; - } - else { - return false; - } -} - -/* -============ -idAASLocal::RandomPullPlayer -============ -*/ -void idAASLocal::RandomPullPlayer( const idVec3 &origin ) { - int rnd, i, n; - - if ( !PullPlayer( origin, aas_pullPlayer.GetInteger() ) ) { - - rnd = gameLocal.random.RandomInt(file->GetNumAreas()); - - for ( i = 0; i < file->GetNumAreas(); i++ ) { - n = (rnd + i) % file->GetNumAreas(); - if ( file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { - aas_pullPlayer.SetInteger( n ); - } - } - } else { - ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); - } -} - -/* -============ -idAASLocal::ShowPushIntoArea -============ -*/ -void idAASLocal::ShowPushIntoArea( const idVec3 &origin ) const { - int areaNum; - idVec3 target; - - target = origin; - areaNum = PointReachableAreaNum( target, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - PushPointIntoAreaNum( areaNum, target ); - gameRenderWorld->DebugArrow( colorGreen, origin, target, 1 ); -} - -/* -============ -idAASLocal::Test -============ -*/ -void idAASLocal::Test( const idVec3 &origin ) { - - if ( !file ) { - return; - } - - if ( aas_randomPullPlayer.GetBool() ) { - RandomPullPlayer( origin ); - } - if ( ( aas_pullPlayer.GetInteger() > 0 ) && ( aas_pullPlayer.GetInteger() < file->GetNumAreas() ) ) { - ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); - PullPlayer( origin, aas_pullPlayer.GetInteger() ); - } - if ( ( aas_showPath.GetInteger() > 0 ) && ( aas_showPath.GetInteger() < file->GetNumAreas() ) ) { - ShowWalkPath( origin, aas_showPath.GetInteger(), AreaCenter( aas_showPath.GetInteger() ) ); - } - if ( ( aas_showFlyPath.GetInteger() > 0 ) && ( aas_showFlyPath.GetInteger() < file->GetNumAreas() ) ) { - ShowFlyPath( origin, aas_showFlyPath.GetInteger(), AreaCenter( aas_showFlyPath.GetInteger() ) ); - } - if ( ( aas_showHideArea.GetInteger() > 0 ) && ( aas_showHideArea.GetInteger() < file->GetNumAreas() ) ) { - ShowHideArea( origin, aas_showHideArea.GetInteger() ); - } - if ( aas_showAreas.GetBool() ) { - ShowArea( origin ); - } - if ( aas_showWallEdges.GetBool() ) { - ShowWallEdges( origin ); - } - if ( aas_showPushIntoArea.GetBool() ) { - ShowPushIntoArea( origin ); - } -} - -void idAASLocal::DrawAreas(const idVec3& playerOrigin) -{ - if (file == NULL) return; - - // Get a colour for each cluster - idList colours; - for (int c = 0; c < file->GetNumClusters(); c++) - { - colours.Alloc() = idVec4(gameLocal.random.RandomFloat() + 0.1f, gameLocal.random.RandomFloat() + 0.1f, gameLocal.random.RandomFloat() + 0.1f, 1); - } - - idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); - - idList clusterNums; - - for (int i = 0; i < file->GetNumAreas(); i++) - { - idBounds areaBounds = GetAreaBounds(i); - idVec3 areaCenter = AreaCenter(i); - - int clusterNum = file->GetArea(i).cluster; - clusterNums.AddUnique(clusterNum); - - idVec4 colour = (clusterNum <= 0) ? colorWhite : colours[clusterNum]; - - // angua: only draw areas near the player, no need to see them at the other end of the map - if ((areaCenter - playerOrigin).LengthFast() < 300) - { - gameRenderWorld->DrawText(va("%d", i), areaCenter, 0.2f, colour, playerViewMatrix, 1, 1000); - gameRenderWorld->DebugBox(colour, idBox(areaBounds), 1000); - } - } - - for (int i = 0; i < clusterNums.Num(); i++) - { - int area = GetAreaInCluster(clusterNums[i]); - if (area <= 0) continue; - - idVec3 origin = file->GetArea(area).center; - if ((origin - playerOrigin).LengthFast() < 1000) - { - gameRenderWorld->DrawText(va("%d", clusterNums[i]), origin, 1, colorRed, playerViewMatrix, 1, 1000); - } - } -} - -void idAASLocal::DrawEASRoute( const idVec3& playerOrigin, int goalArea ) -{ - idVec3 origin = playerOrigin; - int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - - PushPointIntoAreaNum( areaNum, origin ); - - elevatorSystem->DrawRoute(areaNum, goalArea); -} diff --git a/game/ai/aas_local.h b/game/ai/aas_local.h deleted file mode 100644 index 0d5758e35..000000000 --- a/game/ai/aas_local.h +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __AAS_LOCAL_H__ -#define __AAS_LOCAL_H__ - -#include "aas.h" -#include "../pvs.h" -#include "../../DarkMod/AI/EAS/EAS.h" -#include - -class CFrobDoor; - -class idRoutingCache { - friend class idAASLocal; - -public: - idRoutingCache( int size ); - ~idRoutingCache( void ); - - int Size( void ) const; - -private: - int type; // portal or area cache - int size; // size of cache - int cluster; // cluster of the cache - int areaNum; // area of the cache - int travelFlags; // combinations of the travel flags - idRoutingCache * next; // next in list - idRoutingCache * prev; // previous in list - idRoutingCache * time_next; // next in time based list - idRoutingCache * time_prev; // previous in time based list - unsigned short startTravelTime; // travel time to start with - unsigned char * reachabilities; // reachabilities used for routing - unsigned short * travelTimes; // travel time for every area -}; - - -class idRoutingUpdate { - friend class idAASLocal; - -private: - int cluster; // cluster number of this update - int areaNum; // area number of this update - unsigned short tmpTravelTime; // temporary travel time - unsigned short * areaTravelTimes; // travel times within the area - idVec3 start; // start point into area - idRoutingUpdate * next; // next in list - idRoutingUpdate * prev; // prev in list - bool isInList; // true if the update is in the list -}; - - -class idRoutingObstacle { - friend class idAASLocal; - idRoutingObstacle( void ) { } - -private: - idBounds bounds; // obstacle bounds - idList areas; // areas the bounds are in -}; - - -class CMultiStateMover; -namespace eas { class tdmEAS; } - -class idAASLocal : - public idAAS -{ - friend class eas::tdmEAS; // TDM's EAS is our friend - -public: - idAASLocal( void ); - virtual ~idAASLocal( void ); - virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ); - virtual void Shutdown( void ); - - virtual void Stats( void ) const; - virtual void Test( const idVec3 &origin ); - virtual const idAASSettings *GetSettings( void ) const; - virtual int PointAreaNum( const idVec3 &origin ) const; - virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const; - virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const; - virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const; - virtual idVec3 AreaCenter( int areaNum ) const; - virtual int AreaFlags( int areaNum ) const; - virtual int AreaTravelFlags( int areaNum ) const; - virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const; - virtual const idPlane & GetPlane( int planeNum ) const; - virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const; - virtual void SortWallEdges( int *edges, int numEdges ) const; - virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const; - virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const; - virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ); - virtual aasHandle_t AddObstacle( const idBounds &bounds ); - virtual void RemoveObstacle( const aasHandle_t handle ); - virtual void RemoveAllObstacles( void ); - virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const; - virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach, CFrobDoor** firstDoor, idActor* actor ) const; - virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ); - virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor) const; - virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const; - virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const; - virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ); - virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const; - virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxTravelCost=0 ) const; - virtual bool FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const; - - // Added for DarkMod by SophisticatedZombie(DMH) - virtual idBounds GetAreaBounds (int areaNum) const; - virtual int GetNumAreas() const; - virtual idReachability* GetAreaFirstReachability(int areaNum) const; - - virtual void SetAreaTravelFlag( int index, int flag ); - - virtual void RemoveAreaTravelFlag( int index, int flag ); - - // angua: this returns the cluster number of this area - virtual int GetClusterNum(int areaNum); - - virtual void ReferenceDoor(CFrobDoor* door, int areaNum); - virtual void DeReferenceDoor(CFrobDoor* door, int areaNum); - - CFrobDoor* GetDoor(int areaNum) const; - - /*! - * See base class for interface definition - */ - virtual bool BuildReachabilityImpactList - ( - TReachabilityTrackingList& inout_reachabilityList, - idBounds impactBounds - ) const ; - - /*! - * See base class for interface definition - */ - virtual bool TestIfBarrierIsolatesReachability - ( - idReachability* p_reachability, - int areaIndex, - idBounds barrierBounds - ) const; - - /** - * greebo: Adds the given elevator to this AAS class. This will add - * additional routing possibilities for AI between clusters. - */ - virtual void AddElevator(CMultiStateMover* mover); - - /** - * greebo: Assembles the elevator routing information. - */ - virtual void CompileEAS(); - - // Accessor function for the EAS - virtual eas::tdmEAS* GetEAS() { return elevatorSystem; } - - // Save/Restore routines - void Save(idSaveGame* savefile) const; - void Restore(idRestoreGame* savefile); - -private: - idAASFile * file; - idStr name; - - typedef std::map DoorMap; - DoorMap _doors; - - -private: // routing data - idRoutingCache *** areaCacheIndex; // for each area in each cluster the travel times to all other areas in the cluster - int areaCacheIndexSize; // number of area cache entries - idRoutingCache ** portalCacheIndex; // for each area in the world the travel times from each portal - int portalCacheIndexSize; // number of portal cache entries - idRoutingUpdate * areaUpdate; // memory used to update the area routing cache - idRoutingUpdate * portalUpdate; // memory used to update the portal routing cache - unsigned short * goalAreaTravelTimes; // travel times to goal areas - unsigned short * areaTravelTimes; // travel times through the areas - int numAreaTravelTimes; // number of area travel times - mutable idRoutingCache * cacheListStart; // start of list with cache sorted from oldest to newest - mutable idRoutingCache * cacheListEnd; // end of list with cache sorted from oldest to newest - mutable int totalCacheMemory; // total cache memory used - idList obstacleList; // list with obstacles - - // greebo: This is TDM's EAS "Elevator Awareness System" :) - eas::tdmEAS* elevatorSystem; - -private: // routing - bool SetupRouting( void ); - void ShutdownRouting( void ); - unsigned short AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const; - void CalculateAreaTravelTimes( void ); - void DeleteAreaTravelTimes( void ); - void SetupRoutingCache( void ); - void DeleteClusterCache( int clusterNum ); - void DeletePortalCache( void ); - void ShutdownRoutingCache( void ); - void RoutingStats( void ) const; - void LinkCache( idRoutingCache *cache ) const; - void UnlinkCache( idRoutingCache *cache ) const; - void DeleteOldestCache( void ) const; - idReachability * GetAreaReachability( int areaNum, int reachabilityNum ) const; - int ClusterAreaNum( int clusterNum, int areaNum ) const; - void UpdateAreaRoutingCache( idRoutingCache *areaCache ) const; - idRoutingCache * GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const; - void UpdatePortalRoutingCache( idRoutingCache *portalCache ) const; - idRoutingCache * GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const; - void RemoveRoutingCacheUsingArea( int areaNum ); - -public: - void DisableArea( int areaNum ); - void EnableArea( int areaNum ); - -private: - bool SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled ); - void GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList &areas ) const; - void SetObstacleState( const idRoutingObstacle *obstacle, bool enable ); - - // returns an area within that cluster (SLOW!), returns -1 if none found - int GetAreaInCluster(int clusterNum); - -private: // pathing - bool EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const; - bool FloorEdgeSplitPoint( idVec3 &split, int areaNum, const idPlane &splitPlane, const idPlane &frontPlane, bool closest ) const; - idVec3 SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum, idActor* actor ); - idVec3 SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const; - -public: // debug - const idBounds & DefaultSearchBounds( void ) const; - void DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const; - void DrawArea( int areaNum ) const; - void DrawFace( int faceNum, bool side ) const; - void DrawEdge( int edgeNum, bool arrow ) const; - void DrawReachability( const idReachability *reach ) const; - void ShowArea( const idVec3 &origin ) const; - void ShowWallEdges( const idVec3 &origin ) const; - void ShowHideArea( const idVec3 &origin, int targerAreaNum ); - bool PullPlayer( const idVec3 &origin, int toAreaNum ); - void RandomPullPlayer( const idVec3 &origin ); - void ShowPushIntoArea( const idVec3 &origin ) const; - void DrawAreas( const idVec3& playerOrigin ); - void DrawEASRoute( const idVec3& playerOrigin, int goalArea ); -}; - -#endif /* !__AAS_LOCAL_H__ */ diff --git a/game/ai/aas_pathing.cpp b/game/ai/aas_pathing.cpp deleted file mode 100644 index 3716e33ee..000000000 --- a/game/ai/aas_pathing.cpp +++ /dev/null @@ -1,734 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Source$ $Revision$ $Date$", init_version); - -#include "aas_local.h" -#include "../../DarkMod/TimerManager.h" - - -#define SUBSAMPLE_WALK_PATH 1 -#define SUBSAMPLE_FLY_PATH 0 - -const int maxWalkPathIterations = 10; -const float maxWalkPathDistance = 500.0f; -const float walkPathSampleDistance = 8.0f; - -const int maxFlyPathIterations = 10; -const float maxFlyPathDistance = 500.0f; -const float flyPathSampleDistance = 8.0f; - - -/* -============ -idAASLocal::EdgeSplitPoint - - calculates split point of the edge with the plane - returns true if the split point is between the edge vertices -============ -*/ -bool idAASLocal::EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const { - const aasEdge_t *edge; - idVec3 v1, v2; - float d1, d2; - - edge = &file->GetEdge( edgeNum ); - v1 = file->GetVertex( edge->vertexNum[0] ); - v2 = file->GetVertex( edge->vertexNum[1] ); - d1 = v1 * plane.Normal() - plane.Dist(); - d2 = v2 * plane.Normal() - plane.Dist(); - - //if ( (d1 < CM_CLIP_EPSILON && d2 < CM_CLIP_EPSILON) || (d1 > -CM_CLIP_EPSILON && d2 > -CM_CLIP_EPSILON) ) { - if ( FLOATSIGNBITSET( d1 ) == FLOATSIGNBITSET( d2 ) ) { - return false; - } - split = v1 + (d1 / (d1 - d2)) * (v2 - v1); - return true; -} - -/* -============ -idAASLocal::FloorEdgeSplitPoint - - calculates either the closest or furthest point on the floor of the area which also lies on the pathPlane - the point has to be on the front side of the frontPlane to be valid -============ -*/ -bool idAASLocal::FloorEdgeSplitPoint( idVec3 &bestSplit, int areaNum, const idPlane &pathPlane, const idPlane &frontPlane, bool closest ) const { - int i, j, faceNum, edgeNum; - const aasArea_t *area; - const aasFace_t *face; - idVec3 split; - float dist, bestDist; - - if ( closest ) { - bestDist = maxWalkPathDistance; - } else { - bestDist = -0.1f; - } - - area = &file->GetArea( areaNum ); - - for ( i = 0; i < area->numFaces; i++ ) { - faceNum = file->GetFaceIndex( area->firstFace + i ); - face = &file->GetFace( abs(faceNum) ); - - if ( !(face->flags & FACE_FLOOR ) ) { - continue; - } - - for ( j = 0; j < face->numEdges; j++ ) { - edgeNum = file->GetEdgeIndex( face->firstEdge + j ); - - if ( !EdgeSplitPoint( split, abs( edgeNum ), pathPlane ) ) { - continue; - } - dist = frontPlane.Distance( split ); - if ( closest ) { - if ( dist >= -0.1f && dist < bestDist ) { - bestDist = dist; - bestSplit = split; - } - } else { - if ( dist > bestDist ) { - bestDist = dist; - bestSplit = split; - } - } - } - } - - if ( closest ) { - return ( bestDist < maxWalkPathDistance ); - } else { - return ( bestDist > -0.1f ); - } -} - -/* -============ -idAASLocal::WalkPathValid - - returns true if one can walk in a straight line between origin and goalOrigin -============ -*/ -bool idAASLocal::WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum, idActor* actor ) const { - - START_SCOPED_TIMING(actor->actorWalkPathValidTimer, scopedWalkPathValidTimer); - - int curAreaNum, lastAreaNum, lastAreas[4], lastAreaIndex; - idPlane pathPlane, frontPlane, farPlane; - idReachability *reach; - const aasArea_t *area; - idVec3 p, dir; - - if ( file == NULL ) { - endPos = goalOrigin; - endAreaNum = 0; - return true; - } - - lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum; - lastAreaIndex = 0; - - pathPlane.SetNormal( (goalOrigin - origin).Cross( file->GetSettings().gravityDir ) ); - pathPlane.Normalize(); - pathPlane.FitThroughPoint( origin ); - - frontPlane.SetNormal( goalOrigin - origin ); - frontPlane.Normalize(); - frontPlane.FitThroughPoint( origin ); - - farPlane.SetNormal( frontPlane.Normal() ); - farPlane.FitThroughPoint( goalOrigin ); - - curAreaNum = areaNum; - lastAreaNum = curAreaNum; - - while ( 1 ) { - - // find the furthest floor face split point on the path - if ( !FloorEdgeSplitPoint( endPos, curAreaNum, pathPlane, frontPlane, false ) ) { - endPos = origin; - } - - // if we found a point near or further than the goal we're done - if ( farPlane.Distance( endPos ) > -0.5f ) { - break; - } - - // if we reached the goal area we're done - if ( curAreaNum == goalAreaNum ) { - break; - } - - frontPlane.SetDist( frontPlane.Normal() * endPos ); - - area = &file->GetArea( curAreaNum ); - - for ( reach = area->reach; reach; reach = reach->next ) { - if ( reach->travelType != TFL_WALK ) { - continue; - } - - // if the reachability goes back to a previous area - if ( reach->toAreaNum == lastAreas[0] || reach->toAreaNum == lastAreas[1] || - reach->toAreaNum == lastAreas[2] || reach->toAreaNum == lastAreas[3] ) { - continue; - } - - // if undesired travel flags are required to travel through the area - if ( file->GetArea( reach->toAreaNum ).travelFlags & ~travelFlags ) { - continue; - } - - // don't optimize through an area near a ledge - if ( file->GetArea( reach->toAreaNum ).flags & AREA_LEDGE ) { - continue; - } - - // find the closest floor face split point on the path - if ( !FloorEdgeSplitPoint( p, reach->toAreaNum, pathPlane, frontPlane, true ) ) { - continue; - } - - // direction parallel to gravity - dir = ( file->GetSettings().gravityDir * endPos * file->GetSettings().gravityDir ) - - ( file->GetSettings().gravityDir * p * file->GetSettings().gravityDir ); - if ( dir.LengthSqr() > Square( file->GetSettings().maxStepHeight ) ) { - continue; - } - - // direction orthogonal to gravity - dir = endPos - p - dir; - if ( dir.LengthSqr() > Square( 0.2f ) ) { - continue; - } -/* - // angua: area is forbidden (e.g. locked door) - if (actor != NULL && gameLocal.m_AreaManager.AreaIsForbidden(reach->toAreaNum, actor)) - { - continue; - } -*/ - break; - } - - if ( !reach ) { - return false; - } - - lastAreas[lastAreaIndex] = curAreaNum; - lastAreaIndex = ( lastAreaIndex + 1 ) & 3; - - curAreaNum = reach->toAreaNum; - } - - endAreaNum = curAreaNum; - - return true; -} - -/* -============ -idAASLocal::SubSampleWalkPath -============ -*/ -idVec3 idAASLocal::SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum, idActor* actor ) { - - START_SCOPED_TIMING(actor->actorSubSampleWalkPathTimer, scopedSubSampleWalkPathTimer); - - int i, numSamples, curAreaNum; - idVec3 dir, point, nextPoint, endPos; - - dir = end - start; - numSamples = (int) (dir.Length() / walkPathSampleDistance) + 1; - - point = start; - for ( i = 1; i < numSamples; i++ ) { - nextPoint = start + dir * ((float) i / numSamples); - if ( (point - nextPoint).LengthSqr() > Square( maxWalkPathDistance ) ) { - return point; - } - if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum, actor ) ) { - return point; - } - point = nextPoint; - endAreaNum = curAreaNum; - } - return point; -} - -/* -============ -idAASLocal::WalkPathToGoal - - FIXME: don't stop optimizing on first failure ? -============ -*/ -bool idAASLocal::WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idActor* actor ) { - // Set the default values - path.type = PATHTYPE_WALK; - path.moveGoal = origin; - path.moveAreaNum = areaNum; - path.secondaryGoal = origin; - path.reachability = NULL; - path.elevatorRoute = eas::RouteInfoPtr(); - path.firstDoor = NULL; - - if ( file == NULL || areaNum == goalAreaNum ) { - path.moveGoal = goalOrigin; - return true; - } - - CFrobDoor* door = NULL; - - int lastAreas[4] = { areaNum, areaNum, areaNum, areaNum }; - int lastAreaIndex = 0; - - int curAreaNum = areaNum; - idReachability* reach(NULL); - idVec3 endPos; - int travelTime, endAreaNum; - - for ( int i = 0; i < maxWalkPathIterations; i++ ) - { - - if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach, &door, actor ) ) { - break; - } - - if ( !reach ) { - return false; - } - - if (door != NULL && path.firstDoor == NULL) - { - path.firstDoor = door; - } - - // no need to check through the first area - if ( areaNum != curAreaNum ) { - // only optimize a limited distance ahead - if ( (reach->start - origin).LengthSqr() > Square( maxWalkPathDistance ) ) { -#if SUBSAMPLE_WALK_PATH - path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum, actor ); -#endif - return true; - } - - if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum, actor ) ) { -#if SUBSAMPLE_WALK_PATH - path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum, actor ); -#endif - return true; - } - } - - path.moveGoal = reach->start; - path.moveAreaNum = curAreaNum; - - if ( reach->travelType != TFL_WALK ) { - break; - } - - if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum, actor ) ) { - return true; - } - - path.moveGoal = reach->end; - path.moveAreaNum = reach->toAreaNum; - - if ( reach->toAreaNum == goalAreaNum ) { - if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum, actor ) ) { -#if SUBSAMPLE_WALK_PATH - path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum, actor ); -#endif - return true; - } - path.moveGoal = goalOrigin; - path.moveAreaNum = goalAreaNum; - return true; - } - - lastAreas[lastAreaIndex] = curAreaNum; - lastAreaIndex = ( lastAreaIndex + 1 ) & 3; - - curAreaNum = reach->toAreaNum; - - if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] || - curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) { - common->Warning( "idAASLocal::WalkPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum ); - break; - } - } - - if ( !reach ) { - // No standard reachability, check if the actor can use elevators - if (actor != NULL && actor->CanUseElevators()) - { - return elevatorSystem->FindRouteToGoal(path, areaNum, origin, goalAreaNum, goalOrigin, travelFlags, actor); - } - - return false; - } - - switch( reach->travelType ) { - case TFL_WALKOFFLEDGE: - path.type = PATHTYPE_WALKOFFLEDGE; - path.secondaryGoal = reach->end; - path.reachability = reach; - break; - case TFL_BARRIERJUMP: - path.type |= PATHTYPE_BARRIERJUMP; - path.secondaryGoal = reach->end; - path.reachability = reach; - break; - case TFL_JUMP: - path.type |= PATHTYPE_JUMP; - path.secondaryGoal = reach->end; - path.reachability = reach; - break; - default: - break; - } - - return true; -} - -/* -============ -idAASLocal::FlyPathValid - - returns true if one can fly in a straight line between origin and goalOrigin -============ -*/ -bool idAASLocal::FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const { - aasTrace_t trace; - - if ( file == NULL ) { - endPos = goalOrigin; - endAreaNum = 0; - return true; - } - - file->Trace( trace, origin, goalOrigin ); - - endPos = trace.endpos; - endAreaNum = trace.lastAreaNum; - - if ( trace.fraction >= 1.0f ) { - return true; - } - - return false; -} - -/* -============ -idAASLocal::SubSampleFlyPath -============ -*/ -idVec3 idAASLocal::SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const { - int i, numSamples, curAreaNum; - idVec3 dir, point, nextPoint, endPos; - - dir = end - start; - numSamples = (int) (dir.Length() / flyPathSampleDistance) + 1; - - point = start; - for ( i = 1; i < numSamples; i++ ) { - nextPoint = start + dir * ((float) i / numSamples); - if ( (point - nextPoint).LengthSqr() > Square( maxFlyPathDistance ) ) { - return point; - } - if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) { - return point; - } - point = nextPoint; - endAreaNum = curAreaNum; - } - return point; -} - -/* -============ -idAASLocal::FlyPathToGoal - - FIXME: don't stop optimizing on first failure ? -============ -*/ -bool idAASLocal::FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const { - int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum; - idReachability *reach(NULL); - idVec3 endPos; - - path.type = PATHTYPE_WALK; - path.moveGoal = origin; - path.moveAreaNum = areaNum; - path.secondaryGoal = origin; - path.reachability = NULL; - path.elevatorRoute = eas::RouteInfoPtr(); - path.firstDoor = NULL; - - if ( file == NULL || areaNum == goalAreaNum ) { - path.moveGoal = goalOrigin; - return true; - } - - lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum; - lastAreaIndex = 0; - - curAreaNum = areaNum; - - for ( i = 0; i < maxFlyPathIterations; i++ ) { - - if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach, &path.firstDoor, NULL ) ) { - break; - } - - if ( !reach ) { - return false; - } - - // no need to check through the first area - if ( areaNum != curAreaNum ) { - if ( (reach->start - origin).LengthSqr() > Square( maxFlyPathDistance ) ) { -#if SUBSAMPLE_FLY_PATH - path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum ); -#endif - return true; - } - - if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) { -#if SUBSAMPLE_FLY_PATH - path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum ); -#endif - return true; - } - } - - path.moveGoal = reach->start; - path.moveAreaNum = curAreaNum; - - if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) { - return true; - } - - path.moveGoal = reach->end; - path.moveAreaNum = reach->toAreaNum; - - if ( reach->toAreaNum == goalAreaNum ) { - if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) { -#if SUBSAMPLE_FLY_PATH - path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum ); -#endif - return true; - } - path.moveGoal = goalOrigin; - path.moveAreaNum = goalAreaNum; - return true; - } - - lastAreas[lastAreaIndex] = curAreaNum; - lastAreaIndex = ( lastAreaIndex + 1 ) & 3; - - curAreaNum = reach->toAreaNum; - - if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] || - curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) { - common->Warning( "idAASLocal::FlyPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum ); - break; - } - } - - if ( !reach ) { - return false; - } - - return true; -} - -typedef struct wallEdge_s { - int edgeNum; - int verts[2]; - struct wallEdge_s * next; -} wallEdge_t; - -/* -============ -idAASLocal::SortWallEdges -============ -*/ -void idAASLocal::SortWallEdges( int *edges, int numEdges ) const -{ - int i, j, k, numSequences; - wallEdge_t **sequenceFirst, **sequenceLast, *wallEdges, *wallEdge; - - wallEdges = (wallEdge_t *) _alloca16( numEdges * sizeof( wallEdge_t ) ); - sequenceFirst = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) ); - sequenceLast = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) ); - - for ( i = 0; i < numEdges; i++ ) { - wallEdges[i].edgeNum = edges[i]; - GetEdgeVertexNumbers( edges[i], wallEdges[i].verts ); - wallEdges[i].next = NULL; - sequenceFirst[i] = &wallEdges[i]; - sequenceLast[i] = &wallEdges[i]; - } - - numSequences = numEdges; - for ( i = 0; i < numSequences; i++ ) { - for ( j = i+1; j < numSequences; j++ ) { - if ( sequenceFirst[i]->verts[0] == sequenceLast[j]->verts[1] ) { - sequenceLast[j]->next = sequenceFirst[i]; - sequenceFirst[i] = sequenceFirst[j]; - break; - } - if ( sequenceLast[i]->verts[1] == sequenceFirst[j]->verts[0] ) { - sequenceLast[i]->next = sequenceFirst[j]; - break; - } - } - if ( j < numSequences ) { - numSequences--; - for ( k = j; k < numSequences; k++ ) { - sequenceFirst[k] = sequenceFirst[k+1]; - sequenceLast[k] = sequenceLast[k+1]; - } - i = -1; - } - } - - k = 0; - for ( i = 0; i < numSequences; i++ ) { - for ( wallEdge = sequenceFirst[i]; wallEdge; wallEdge = wallEdge->next ) { - edges[k++] = wallEdge->edgeNum; - } - } -} - -/* -============ -idAASLocal::GetWallEdges -============ -*/ -int idAASLocal::GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const -{ - if ( !file ) - { - return 0; - } - - int numEdges = 0; - int numAreas = file->GetNumAreas(); - - byte *areasVisited = (byte *) _alloca16( numAreas); - memset( areasVisited, 0, numAreas * sizeof( byte ) ); - int *areaQueue = (int *) _alloca16( numAreas * sizeof( int ) ); - - int queueStart = -1; - int queueEnd = 0; - areaQueue[0] = areaNum; - areasVisited[areaNum] = true; - - idReachability *reach; - - for (int curArea = areaNum; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) { - - const aasArea_t *area = &file->GetArea( curArea ); - - for (int i = 0; i < area->numFaces; i++) { - int face1Num = file->GetFaceIndex(area->firstFace + i); - const aasFace_t *face1 = &file->GetFace( abs(face1Num) ); - - if ( !(face1->flags & FACE_FLOOR ) ) { - continue; - } - - for (int j = 0; j < face1->numEdges; j++ ) { - int edge1Num = file->GetEdgeIndex(face1->firstEdge + j); - int absEdge1Num = abs( edge1Num ); - - // test if the edge is shared by another floor face of this area - int k; - for (k = 0; k < area->numFaces; k++ ) { - if ( k == i ) { - continue; - } - int face2Num = file->GetFaceIndex( area->firstFace + k ); - const aasFace_t *face2 = &file->GetFace( abs(face2Num) ); - - if ( !(face2->flags & FACE_FLOOR ) ) { - continue; - } - int l; - for (l = 0; l < face2->numEdges; l++ ) { - int edge2Num = abs( file->GetEdgeIndex( face2->firstEdge + l ) ); - if ( edge2Num == absEdge1Num ) { - break; - } - } - if ( l < face2->numEdges ) { - break; - } - } - if ( k < area->numFaces ) { - continue; - } - - // test if the edge is used by a reachability - for (reach = area->reach; reach; reach = reach->next ) { - if ( reach->travelType & travelFlags ) { - if ( reach->edgeNum == absEdge1Num ) { - break; - } - } - } - if ( reach ) { - continue; - } - - // test if the edge is already in the list - for ( k = 0; k < numEdges; k++ ) { - if ( edge1Num == edges[k] ) { - break; - } - } - if ( k < numEdges ) { - continue; - } - - // add the edge to the list - edges[numEdges++] = edge1Num; - if ( numEdges >= maxEdges ) { - return numEdges; - } - } - } - - // add new areas to the queue - for ( reach = area->reach; reach; reach = reach->next ) { - if ( reach->travelType & travelFlags ) { - // if the area the reachability leads to hasn't been visited yet and the area bounds touch the search bounds - if ( !areasVisited[reach->toAreaNum] && bounds.IntersectsBounds( file->GetArea( reach->toAreaNum ).bounds ) ) { - areaQueue[queueEnd++] = reach->toAreaNum; - areasVisited[reach->toAreaNum] = true; - } - } - } - } - return numEdges; -} diff --git a/game/ai/aas_routing.cpp b/game/ai/aas_routing.cpp deleted file mode 100644 index 9ead30c18..000000000 --- a/game/ai/aas_routing.cpp +++ /dev/null @@ -1,1689 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "aas_local.h" -#include "../game_local.h" // for print and error - -#include "../../DarkMod/DarkModGlobals.h" -#include "../../DarkMod/MultiStateMover.h" -#include "../../DarkMod/MultiStateMoverPosition.h" -#include "../../DarkMod/TimerManager.h" - -#define CACHETYPE_AREA 1 -#define CACHETYPE_PORTAL 2 - -#define MAX_ROUTING_CACHE_MEMORY (2*1024*1024) - -#define LEDGE_TRAVELTIME_PANALTY 250 - -/* -============ -idRoutingCache::idRoutingCache -============ -*/ -idRoutingCache::idRoutingCache( int size ) { - areaNum = 0; - cluster = 0; - next = prev = NULL; - time_next = time_prev = NULL; - travelFlags = 0; - startTravelTime = 0; - type = 0; - this->size = size; - reachabilities = new byte[size]; - memset( reachabilities, 0, size * sizeof( reachabilities[0] ) ); - travelTimes = new unsigned short[size]; - memset( travelTimes, 0, size * sizeof( travelTimes[0] ) ); -} - -/* -============ -idRoutingCache::~idRoutingCache -============ -*/ -idRoutingCache::~idRoutingCache( void ) { - delete [] reachabilities; - delete [] travelTimes; -} - -/* -============ -idRoutingCache::Size -============ -*/ -int idRoutingCache::Size( void ) const { - return sizeof( idRoutingCache ) + size * sizeof( reachabilities[0] ) + size * sizeof( travelTimes[0] ); -} - -/* -============ -idAASLocal::AreaTravelTime -============ -*/ -unsigned short idAASLocal::AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const { - float dist; - - dist = ( end - start ).Length(); - - if ( file->GetArea( areaNum ).travelFlags & TFL_CROUCH ) { - dist *= 100.0f / 100.0f; - } else if ( file->GetArea( areaNum ).travelFlags & TFL_WATER ) { - dist *= 100.0f / 150.0f; - } else { - dist *= 100.0f / 300.0f; - } - if ( dist < 1.0f ) { - return 1; - } - return (unsigned short) idMath::FtoiFast( dist ); -} - -/* -============ -idAASLocal::CalculateAreaTravelTimes -============ -*/ -void idAASLocal::CalculateAreaTravelTimes(void) { - int n, i, j, numReach, numRevReach, t, maxt; - byte *bytePtr; - idReachability *reach, *rev_reach; - - // get total memory for all area travel times - numAreaTravelTimes = 0; - for ( n = 0; n < file->GetNumAreas(); n++ ) { - - if ( !(file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { - continue; - } - - numReach = 0; - for ( reach = file->GetArea( n ).reach; reach; reach = reach->next ) { - numReach++; - } - - numRevReach = 0; - for ( rev_reach = file->GetArea( n ).rev_reach; rev_reach; rev_reach = rev_reach->rev_next ) { - numRevReach++; - } - numAreaTravelTimes += numReach * numRevReach; - } - - areaTravelTimes = (unsigned short *) Mem_Alloc( numAreaTravelTimes * sizeof( unsigned short ) ); - bytePtr = (byte *) areaTravelTimes; - - for ( n = 0; n < file->GetNumAreas(); n++ ) { - - if ( !(file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { - continue; - } - - // for each reachability that starts in this area calculate the travel time - // towards all the reachabilities that lead towards this area - for ( maxt = i = 0, reach = file->GetArea( n ).reach; reach; reach = reach->next, i++ ) { - assert( i < MAX_REACH_PER_AREA ); - if ( i >= MAX_REACH_PER_AREA ) { - gameLocal.Error( "i >= MAX_REACH_PER_AREA" ); - } - reach->number = i; - reach->disableCount = 0; - reach->areaTravelTimes = (unsigned short *) bytePtr; - for ( j = 0, rev_reach = file->GetArea( n ).rev_reach; rev_reach; rev_reach = rev_reach->rev_next, j++ ) { - t = AreaTravelTime( n, reach->start, rev_reach->end ); - reach->areaTravelTimes[j] = t; - if ( t > maxt ) { - maxt = t; - } - } - bytePtr += j * sizeof( unsigned short ); - } - - // if this area is a portal - if ( file->GetArea( n ).cluster < 0 ) { - // set the maximum travel time through this portal - file->SetPortalMaxTravelTime( -file->GetArea( n ).cluster, maxt ); - } - } - - assert( ( (unsigned int) bytePtr - (unsigned int) areaTravelTimes ) <= numAreaTravelTimes * sizeof( unsigned short ) ); -} - -/* -============ -idAASLocal::DeleteAreaTravelTimes -============ -*/ -void idAASLocal::DeleteAreaTravelTimes( void ) { - Mem_Free( areaTravelTimes ); - areaTravelTimes = NULL; - numAreaTravelTimes = 0; -} - -/* -============ -idAASLocal::SetupRoutingCache -============ -*/ -void idAASLocal::SetupRoutingCache( void ) { - - // greebo: First, determine the number of areas in the map by adding all reachable areas of all clusters - areaCacheIndexSize = 0; - for ( int i = 0; i < file->GetNumClusters(); i++ ) { - areaCacheIndexSize += file->GetCluster(i).numReachableAreas; - } - - /** - * greebo: Next, we need to allocate the memory for the idRoutingCache* pointers (only the pointers, not the structs!) - * Take one pointer array per cluster and add one pointer for each area. The area pointers - * are grouped after their clusters. - * - * The area cache index is then looking like this (divided into two large sections). The first - * section serves as "index" for the pointers further down in memory. - * - * idRoutingCache** cluster0 (pointing to the "area0" pointer below) - * idRoutingCache** cluster1 (pointing to the "area3" pointer below) - * idRoutingCache** cluster2 (pointing to the "area5" pointer below) - * ... - * - * idRoutingCache* area0 (belonging to Cluster 0) - * idRoutingCache* area1 (belonging to Cluster 0) - * idRoutingCache* area2 (belonging to Cluster 0) - * - * idRoutingCache* area3 (belonging to Cluster 1) - * idRoutingCache* area4 (belonging to Cluster 1) - * - * idRoutingCache* area5 (belonging to Cluster 2) - * idRoutingCache* area6 (belonging to Cluster 2) - * ... - * - * This whole pointer structure is stored in a dynamically allocated area, hence the type idRoutingCache*** - */ - areaCacheIndex = (idRoutingCache***) Mem_ClearedAlloc( file->GetNumClusters() * sizeof(idRoutingCache**) + - areaCacheIndexSize * sizeof(idRoutingCache*) ); - - // Now initialise the areaCacheIndex pointers - - // skip the index part, i.e. the first pointers - byte* bytePtr = ((byte *)areaCacheIndex) + file->GetNumClusters() * sizeof(idRoutingCache**); - - // Initialise the first pointer section (the clusterN pointers), which point to the second (area) section - for ( int i = 0; i < file->GetNumClusters(); i++ ) { - // Set the i-th cluster pointer to the first area pointer (corresponding to this cluster) - areaCacheIndex[i] = (idRoutingCache**) bytePtr; - - // Set the pointer to the next array - bytePtr += file->GetCluster(i).numReachableAreas * sizeof(idRoutingCache*); - } - - // At this point, all the area idRoutingCache* pointers are NULL and the index pointers are initialised - - // greebo: Allocate an idRoutingCache pointer for each area in the world and set the pointers to 0 - portalCacheIndexSize = file->GetNumAreas(); - portalCacheIndex = (idRoutingCache**) Mem_ClearedAlloc( portalCacheIndexSize * sizeof(idRoutingCache*) ); - - // greebo: Allocate as many idRoutingUpdate structures as there are AREAS in the map, and set everything to 0 - areaUpdate = (idRoutingUpdate*) Mem_ClearedAlloc( file->GetNumAreas() * sizeof(idRoutingUpdate) ); - - // greebo: Allocate as many idRoutingUpdate structures as there are PORTALS+1 in the map, and set everything to 0 - portalUpdate = (idRoutingUpdate*) Mem_ClearedAlloc( (file->GetNumPortals()+1) * sizeof(idRoutingUpdate) ); - - // greebo: For each area in the map, allocate a traveltime integer and initialise them to 0 - goalAreaTravelTimes = (unsigned short *) Mem_ClearedAlloc( file->GetNumAreas() * sizeof(unsigned short) ); - - cacheListStart = cacheListEnd = NULL; - totalCacheMemory = 0; -} - -/* -============ -idAASLocal::DeleteClusterCache -============ -*/ -void idAASLocal::DeleteClusterCache( int clusterNum ) { - int i; - idRoutingCache *cache; - - for ( i = 0; i < file->GetCluster( clusterNum ).numReachableAreas; i++ ) { - for ( cache = areaCacheIndex[clusterNum][i]; cache; cache = areaCacheIndex[clusterNum][i] ) { - areaCacheIndex[clusterNum][i] = cache->next; - UnlinkCache( cache ); - delete cache; - } - } -} - -/* -============ -idAASLocal::DeletePortalCache -============ -*/ -void idAASLocal::DeletePortalCache( void ) { - int i; - idRoutingCache *cache; - - for ( i = 0; i < file->GetNumAreas(); i++ ) { - for ( cache = portalCacheIndex[i]; cache; cache = portalCacheIndex[i] ) { - portalCacheIndex[i] = cache->next; - UnlinkCache( cache ); - delete cache; - } - } -} - -/* -============ -idAASLocal::ShutdownRoutingCache -============ -*/ -void idAASLocal::ShutdownRoutingCache( void ) { - int i; - - for ( i = 0; i < file->GetNumClusters(); i++ ) { - DeleteClusterCache( i ); - } - - DeletePortalCache(); - - Mem_Free( areaCacheIndex ); - areaCacheIndex = NULL; - areaCacheIndexSize = 0; - Mem_Free( portalCacheIndex ); - portalCacheIndex = NULL; - portalCacheIndexSize = 0; - Mem_Free( areaUpdate ); - areaUpdate = NULL; - Mem_Free( portalUpdate ); - portalUpdate = NULL; - Mem_Free( goalAreaTravelTimes ); - goalAreaTravelTimes = NULL; - - cacheListStart = cacheListEnd = NULL; - totalCacheMemory = 0; -} - -/* -============ -idAASLocal::SetupRouting -============ -*/ -bool idAASLocal::SetupRouting( void ) { - CalculateAreaTravelTimes(); - SetupRoutingCache(); - return true; -} - -/* -============ -idAASLocal::ShutdownRouting -============ -*/ -void idAASLocal::ShutdownRouting( void ) { - DeleteAreaTravelTimes(); - ShutdownRoutingCache(); -} - -/* -============ -idAASLocal::RoutingStats -============ -*/ -void idAASLocal::RoutingStats( void ) const { - idRoutingCache *cache; - int numAreaCache, numPortalCache; - int totalAreaCacheMemory, totalPortalCacheMemory; - - numAreaCache = numPortalCache = 0; - totalAreaCacheMemory = totalPortalCacheMemory = 0; - for ( cache = cacheListStart; cache; cache = cache->time_next ) { - if ( cache->type == CACHETYPE_AREA ) { - numAreaCache++; - totalAreaCacheMemory += sizeof( idRoutingCache ) + cache->size * (sizeof( unsigned short ) + sizeof( byte )); - } else { - numPortalCache++; - totalPortalCacheMemory += sizeof( idRoutingCache ) + cache->size * (sizeof( unsigned short ) + sizeof( byte )); - } - } - - gameLocal.Printf( "%6d area cache (%d KB)\n", numAreaCache, totalAreaCacheMemory >> 10 ); - gameLocal.Printf( "%6d portal cache (%d KB)\n", numPortalCache, totalPortalCacheMemory >> 10 ); - gameLocal.Printf( "%6d total cache (%d KB)\n", numAreaCache + numPortalCache, totalCacheMemory >> 10 ); - gameLocal.Printf( "%6d area travel times (%d KB)\n", numAreaTravelTimes, ( numAreaTravelTimes * sizeof( unsigned short ) ) >> 10 ); - gameLocal.Printf( "%6d area cache entries (%d KB)\n", areaCacheIndexSize, ( areaCacheIndexSize * sizeof( idRoutingCache * ) ) >> 10 ); - gameLocal.Printf( "%6d portal cache entries (%d KB)\n", portalCacheIndexSize, ( portalCacheIndexSize * sizeof( idRoutingCache * ) ) >> 10 ); -} - -/* -============ -idAASLocal::RemoveRoutingCacheUsingArea -============ -*/ -void idAASLocal::RemoveRoutingCacheUsingArea( int areaNum ) { - int clusterNum; - - clusterNum = file->GetArea( areaNum ).cluster; - if ( clusterNum > 0 ) { - // remove all the cache in the cluster the area is in - DeleteClusterCache( clusterNum ); - } - else { - // if this is a portal remove all cache in both the front and back cluster - DeleteClusterCache( file->GetPortal( -clusterNum ).clusters[0] ); - DeleteClusterCache( file->GetPortal( -clusterNum ).clusters[1] ); - } - DeletePortalCache(); -} - -/* -============ -idAASLocal::DisableArea -============ -*/ -void idAASLocal::DisableArea( int areaNum ) { - assert( areaNum > 0 && areaNum < file->GetNumAreas() ); - - if ( file->GetArea( areaNum ).travelFlags & TFL_INVALID ) { - return; - } - - file->SetAreaTravelFlag( areaNum, TFL_INVALID ); - - RemoveRoutingCacheUsingArea( areaNum ); -} - -/* -============ -idAASLocal::EnableArea -============ -*/ -void idAASLocal::EnableArea( int areaNum ) { - assert( areaNum > 0 && areaNum < file->GetNumAreas() ); - - if ( !( file->GetArea( areaNum ).travelFlags & TFL_INVALID ) ) { - return; - } - - file->RemoveAreaTravelFlag( areaNum, TFL_INVALID ); - - RemoveRoutingCacheUsingArea( areaNum ); -} - -/* -============ -idAASLocal::SetAreaState_r -============ -*/ -bool idAASLocal::SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled ) { - int res; - const aasNode_t *node; - bool foundClusterPortal = false; - - while( nodeNum != 0 ) { - if ( nodeNum < 0 ) { - // if this area is a cluster portal - if ( file->GetArea( -nodeNum ).contents & areaContents ) { - if ( disabled ) { - DisableArea( -nodeNum ); - } else { - EnableArea( -nodeNum ); - } - foundClusterPortal |= true; - } - break; - } - node = &file->GetNode( nodeNum ); - res = bounds.PlaneSide( file->GetPlane( node->planeNum ) ); - if ( res == PLANESIDE_BACK ) { - nodeNum = node->children[1]; - } - else if ( res == PLANESIDE_FRONT ) { - nodeNum = node->children[0]; - } - else { - foundClusterPortal |= SetAreaState_r( node->children[1], bounds, areaContents, disabled ); - nodeNum = node->children[0]; - } - } - - return foundClusterPortal; -} - -/* -============ -idAASLocal::SetAreaState -============ -*/ -bool idAASLocal::SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) { - idBounds expBounds; - - if ( !file ) { - return false; - } - - expBounds[0] = bounds[0] - file->GetSettings().boundingBoxes[0][1]; - expBounds[1] = bounds[1] - file->GetSettings().boundingBoxes[0][0]; - - // find all areas within or touching the bounds with the given contents and disable/enable them for routing - return SetAreaState_r( 1, expBounds, areaContents, disabled ); -} - -/* -============ -idAASLocal::GetBoundsAreas_r -============ -*/ -void idAASLocal::GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList &areas ) const { - int res; - const aasNode_t *node; - - while( nodeNum != 0 ) { - if ( nodeNum < 0 ) { - areas.Append( -nodeNum ); - break; - } - node = &file->GetNode( nodeNum ); - res = bounds.PlaneSide( file->GetPlane( node->planeNum ) ); - if ( res == PLANESIDE_BACK ) { - nodeNum = node->children[1]; - } - else if ( res == PLANESIDE_FRONT ) { - nodeNum = node->children[0]; - } - else { - GetBoundsAreas_r( node->children[1], bounds, areas ); - nodeNum = node->children[0]; - } - } -} - -/* -============ -idAASLocal::SetObstacleState -============ -*/ -void idAASLocal::SetObstacleState( const idRoutingObstacle *obstacle, bool enable ) { - int i; - const aasArea_t *area; - idReachability *reach, *rev_reach; - bool inside; - - for ( i = 0; i < obstacle->areas.Num(); i++ ) { - - RemoveRoutingCacheUsingArea( obstacle->areas[i] ); - - area = &file->GetArea( obstacle->areas[i] ); - - for ( rev_reach = area->rev_reach; rev_reach; rev_reach = rev_reach->rev_next ) { - - - /** SZ: I'm commenting this out as it prevents disabling obstacles from making areas - * Accessible again - */ - /* - if ( rev_reach->travelType & TFL_INVALID ) { - continue; - } - */ - - inside = false; - - if ( obstacle->bounds.ContainsPoint( rev_reach->end ) ) { - inside = true; - } - else { - for ( reach = area->reach; reach; reach = reach->next ) { - if ( obstacle->bounds.LineIntersection( rev_reach->end, reach->start ) ) { - inside = true; - break; - } - } - } - - // SZ: I'm commenting out the original Doom3 code below because it is broken - // It appears as if the if ( enable ) line is supposed to be if ( !enable) - // Enable refers to the obstacle being on or off, not to the reachability being - // enabled or disabled. If the obstacle is enabled, then the reachability is - // disabled. This appears to have thus been a semantic error by Id. - if ( inside ) { - //if ( enable ) { - if (!enable) { - rev_reach->disableCount--; - if ( rev_reach->disableCount <= 0 ) { - rev_reach->travelType &= ~TFL_INVALID; - rev_reach->disableCount = 0; - } - } - else { - rev_reach->travelType |= TFL_INVALID; - rev_reach->disableCount++; - } - } - } - } -} - -/* -============ -idAASLocal::AddObstacle -============ -*/ -aasHandle_t idAASLocal::AddObstacle( const idBounds &bounds ) { - idRoutingObstacle *obstacle; - - if ( !file ) { - return -1; - } - - obstacle = new idRoutingObstacle; - obstacle->bounds[0] = bounds[0] - file->GetSettings().boundingBoxes[0][1]; - obstacle->bounds[1] = bounds[1] - file->GetSettings().boundingBoxes[0][0]; - GetBoundsAreas_r( 1, obstacle->bounds, obstacle->areas ); - SetObstacleState( obstacle, true ); - - obstacleList.Append( obstacle ); - return obstacleList.Num() - 1; -} - -/* -============ -idAASLocal::RemoveObstacle -============ -*/ -void idAASLocal::RemoveObstacle( const aasHandle_t handle ) { - if ( !file ) { - return; - } - if ( ( handle >= 0 ) && ( handle < obstacleList.Num() ) ) { - SetObstacleState( obstacleList[handle], false ); - - delete obstacleList[handle]; - obstacleList.RemoveIndex( handle ); - } -} - -/* -============ -idAASLocal::RemoveAllObstacles -============ -*/ -void idAASLocal::RemoveAllObstacles( void ) { - int i; - - if ( !file ) { - return; - } - - for ( i = 0; i < obstacleList.Num(); i++ ) { - SetObstacleState( obstacleList[i], false ); - delete obstacleList[i]; - } - obstacleList.Clear(); -} - -/* -============ -idAASLocal::LinkCache - - link the cache in the cache list sorted from oldest to newest cache -============ -*/ -void idAASLocal::LinkCache( idRoutingCache *cache ) const { - - // if the cache is already linked - if ( cache->time_next || cache->time_prev || cacheListStart == cache ) { - UnlinkCache( cache ); - } - - totalCacheMemory += cache->Size(); - - // add cache to the end of the list - cache->time_next = NULL; - cache->time_prev = cacheListEnd; - if ( cacheListEnd ) { - cacheListEnd->time_next = cache; - } - cacheListEnd = cache; - if ( !cacheListStart ) { - cacheListStart = cache; - } -} - -/* -============ -idAASLocal::UnlinkCache -============ -*/ -void idAASLocal::UnlinkCache( idRoutingCache *cache ) const { - - totalCacheMemory -= cache->Size(); - - // unlink the cache - if ( cache->time_next ) { - cache->time_next->time_prev = cache->time_prev; - } else { - cacheListEnd = cache->time_prev; - } - if ( cache->time_prev ) { - cache->time_prev->time_next = cache->time_next; - } else { - cacheListStart = cache->time_next; - } - cache->time_next = cache->time_prev = NULL; -} - -/* -============ -idAASLocal::DeleteOldestCache -============ -*/ -void idAASLocal::DeleteOldestCache( void ) const { - idRoutingCache *cache; - - assert( cacheListStart ); - - // unlink the oldest cache - cache = cacheListStart; - UnlinkCache( cache ); - - // unlink the oldest cache from the area or portal cache index - if ( cache->next ) { - cache->next->prev = cache->prev; - } - if ( cache->prev ) { - cache->prev->next = cache->next; - } - else if ( cache->type == CACHETYPE_AREA ) { - areaCacheIndex[cache->cluster][ClusterAreaNum( cache->cluster, cache->areaNum )] = cache->next; - } - else if ( cache->type == CACHETYPE_PORTAL ) { - portalCacheIndex[cache->areaNum] = cache->next; - } - - delete cache; -} - -/* -============ -idAASLocal::GetAreaReachability -============ -*/ -idReachability *idAASLocal::GetAreaReachability( int areaNum, int reachabilityNum ) const { - idReachability *reach; - - for ( reach = file->GetArea( areaNum ).reach; reach; reach = reach->next ) { - if ( --reachabilityNum < 0 ) { - return reach; - } - } - return NULL; -} - -/* -============ -idAASLocal::ClusterAreaNum -============ -*/ -ID_INLINE int idAASLocal::ClusterAreaNum( int clusterNum, int areaNum ) const { - int side, areaCluster; - - areaCluster = file->GetArea( areaNum ).cluster; - if ( areaCluster > 0 ) { - return file->GetArea( areaNum ).clusterAreaNum; - } - else { - side = file->GetPortal( -areaCluster ).clusters[0] != clusterNum; - return file->GetPortal( -areaCluster ).clusterAreaNum[side]; - } -} - -/* -============ -idAASLocal::UpdateAreaRoutingCache -============ -*/ -void idAASLocal::UpdateAreaRoutingCache( idRoutingCache *areaCache ) const { - // number of reachability areas within this cluster - int numReachableAreas = file->GetCluster(areaCache->cluster).numReachableAreas; - - // number of the start area within the cluster - int clusterAreaNum = ClusterAreaNum(areaCache->cluster, areaCache->areaNum); - - if (clusterAreaNum >= numReachableAreas) { - return; // cluster area is not a reachable area - } - - areaCache->travelTimes[clusterAreaNum] = areaCache->startTravelTime; - int badTravelFlags = ~areaCache->travelFlags; - - unsigned short startAreaTravelTimes[MAX_REACH_PER_AREA]; - memset( startAreaTravelTimes, 0, sizeof( startAreaTravelTimes ) ); - - // initialize first update - idRoutingUpdate* curUpdate = &areaUpdate[clusterAreaNum]; - - curUpdate->areaNum = areaCache->areaNum; - curUpdate->areaTravelTimes = startAreaTravelTimes; - curUpdate->tmpTravelTime = areaCache->startTravelTime; - curUpdate->next = NULL; - curUpdate->prev = NULL; - - idRoutingUpdate* updateListStart = curUpdate; - idRoutingUpdate* updateListEnd = curUpdate; - - // while there are updates in the list - while( updateListStart ) { - - curUpdate = updateListStart; - if ( curUpdate->next ) { - curUpdate->next->prev = NULL; - } - else { - updateListEnd = NULL; - } - updateListStart = curUpdate->next; - - curUpdate->isInList = false; - - idReachability* reach; - int i; - for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).rev_reach; reach; reach = reach->rev_next, i++ ) { - - // if the reachability uses an undesired travel type - if ( reach->travelType & badTravelFlags ) { - continue; - } - - // next area the reversed reachability leads to - int nextAreaNum = reach->fromAreaNum; - const aasArea_t* nextArea = &file->GetArea( nextAreaNum ); - - // if traveling through the next area requires an undesired travel flag - if ( nextArea->travelFlags & badTravelFlags ) { - continue; - } - - // get the cluster number of the area - int cluster = nextArea->cluster; - // don't leave the cluster, however do flood into cluster portals - if ( cluster > 0 && cluster != areaCache->cluster ) { - continue; - } - - // get the number of the area in the cluster - clusterAreaNum = ClusterAreaNum( areaCache->cluster, nextAreaNum ); - if ( clusterAreaNum >= numReachableAreas ) { - continue; // should never happen - } - - assert( clusterAreaNum < areaCache->size ); - - // time already travelled plus the traveltime through the current area - // plus the travel time of the reachability towards the next area - unsigned short t = curUpdate->tmpTravelTime + curUpdate->areaTravelTimes[i] + reach->travelTime; - - if ( !areaCache->travelTimes[clusterAreaNum] || t < areaCache->travelTimes[clusterAreaNum] ) { - - areaCache->travelTimes[clusterAreaNum] = t; - areaCache->reachabilities[clusterAreaNum] = reach->number; // reversed reachability used to get into this area - idRoutingUpdate* nextUpdate = &areaUpdate[clusterAreaNum]; - nextUpdate->areaNum = nextAreaNum; - nextUpdate->tmpTravelTime = t; - nextUpdate->areaTravelTimes = reach->areaTravelTimes; - - // if we are not allowed to fly - if ( badTravelFlags & TFL_FLY ) { - // avoid areas near ledges - if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) { - nextUpdate->tmpTravelTime += LEDGE_TRAVELTIME_PANALTY; - } - } - - if ( !nextUpdate->isInList ) { - nextUpdate->next = NULL; - nextUpdate->prev = updateListEnd; - if ( updateListEnd ) { - updateListEnd->next = nextUpdate; - } - else { - updateListStart = nextUpdate; - } - updateListEnd = nextUpdate; - nextUpdate->isInList = true; - } - } - } - } -} - -/* -============ -idAASLocal::GetAreaRoutingCache -============ -*/ -idRoutingCache *idAASLocal::GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const { - int clusterAreaNum; - idRoutingCache *cache, *clusterCache; - - // number of the area in the cluster - clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); - // pointer to the cache for the area in the cluster - clusterCache = areaCacheIndex[clusterNum][clusterAreaNum]; - // check if cache without undesired travel flags already exists - for ( cache = clusterCache; cache; cache = cache->next ) { - if ( cache->travelFlags == travelFlags ) { - break; - } - } - // if no cache found - if ( !cache ) { - cache = new idRoutingCache( file->GetCluster( clusterNum ).numReachableAreas ); - cache->type = CACHETYPE_AREA; - cache->cluster = clusterNum; - cache->areaNum = areaNum; - cache->startTravelTime = 1; - cache->travelFlags = travelFlags; - cache->prev = NULL; - cache->next = clusterCache; - if ( clusterCache ) { - clusterCache->prev = cache; - } - areaCacheIndex[clusterNum][clusterAreaNum] = cache; - UpdateAreaRoutingCache( cache ); - } - LinkCache( cache ); - return cache; -} - -/* -============ -idAASLocal::UpdatePortalRoutingCache -============ -*/ -void idAASLocal::UpdatePortalRoutingCache( idRoutingCache *portalCache ) const { - int i, portalNum, clusterAreaNum; - unsigned short t; - const aasPortal_t *portal; - const aasCluster_t *cluster; - idRoutingCache *cache; - idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; - - curUpdate = &portalUpdate[ file->GetNumPortals() ]; - curUpdate->cluster = portalCache->cluster; - curUpdate->areaNum = portalCache->areaNum; - curUpdate->tmpTravelTime = portalCache->startTravelTime; - - //put the area to start with in the current read list - curUpdate->next = NULL; - curUpdate->prev = NULL; - updateListStart = curUpdate; - updateListEnd = curUpdate; - - // while there are updates in the current list - while( updateListStart ) { - - curUpdate = updateListStart; - // remove the current update from the list - if ( curUpdate->next ) { - curUpdate->next->prev = NULL; - } - else { - updateListEnd = NULL; - } - updateListStart = curUpdate->next; - // current update is removed from the list - curUpdate->isInList = false; - - cluster = &file->GetCluster( curUpdate->cluster ); - cache = GetAreaRoutingCache( curUpdate->cluster, curUpdate->areaNum, portalCache->travelFlags ); - - // take all portals of the cluster - for ( i = 0; i < cluster->numPortals; i++ ) { - portalNum = file->GetPortalIndex( cluster->firstPortal + i ); - assert( portalNum < portalCache->size ); - portal = &file->GetPortal( portalNum ); - - clusterAreaNum = ClusterAreaNum( curUpdate->cluster, portal->areaNum ); - if ( clusterAreaNum >= cluster->numReachableAreas ) { - continue; - } - - t = cache->travelTimes[clusterAreaNum]; - if ( t == 0 ) { - continue; - } - t += curUpdate->tmpTravelTime; - - if ( !portalCache->travelTimes[portalNum] || t < portalCache->travelTimes[portalNum] ) { - - portalCache->travelTimes[portalNum] = t; - portalCache->reachabilities[portalNum] = cache->reachabilities[clusterAreaNum]; - nextUpdate = &portalUpdate[portalNum]; - if ( portal->clusters[0] == curUpdate->cluster ) { - nextUpdate->cluster = portal->clusters[1]; - } - else { - nextUpdate->cluster = portal->clusters[0]; - } - nextUpdate->areaNum = portal->areaNum; - // add travel time through the actual portal area for the next update - nextUpdate->tmpTravelTime = t + portal->maxAreaTravelTime; - - if ( !nextUpdate->isInList ) { - - nextUpdate->next = NULL; - nextUpdate->prev = updateListEnd; - if ( updateListEnd ) { - updateListEnd->next = nextUpdate; - } - else { - updateListStart = nextUpdate; - } - updateListEnd = nextUpdate; - nextUpdate->isInList = true; - } - } - } - } -} - -/* -============ -idAASLocal::GetPortalRoutingCache -============ -*/ -idRoutingCache *idAASLocal::GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const { - idRoutingCache *cache; - - // check if cache without undesired travel flags already exists - for ( cache = portalCacheIndex[areaNum]; cache; cache = cache->next ) { - if ( cache->travelFlags == travelFlags ) { - break; - } - } - // if no cache found - if ( !cache ) { - cache = new idRoutingCache( file->GetNumPortals() ); - cache->type = CACHETYPE_PORTAL; - cache->cluster = clusterNum; - cache->areaNum = areaNum; - cache->startTravelTime = 1; - cache->travelFlags = travelFlags; - cache->prev = NULL; - cache->next = portalCacheIndex[areaNum]; - if ( portalCacheIndex[areaNum] ) { - portalCacheIndex[areaNum]->prev = cache; - } - portalCacheIndex[areaNum] = cache; - UpdatePortalRoutingCache( cache ); - } - LinkCache( cache ); - return cache; -} - -/* -============ -idAASLocal::RouteToGoalArea -============ -*/ -bool idAASLocal::RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, - int travelFlags, int &travelTime, idReachability **reach, - CFrobDoor** firstDoor, idActor* actor ) const -{ -#ifdef TIMING_BUILD - if (actor != NULL) - { - START_SCOPED_TIMING(actor->actorRouteToGoalTimer, scopedRouteToGoalTimer); - } -#endif - - - // Set the default return values - travelTime = 0; - *reach = NULL; - - if (firstDoor != NULL) - { - *firstDoor = NULL; - } - - if ( !file ) { - return false; - } - - if ( areaNum == goalAreaNum ) { - return true; - } - - if ( areaNum <= 0 || areaNum >= file->GetNumAreas() ) { - gameLocal.Printf( "RouteToGoalArea: areaNum %d out of range\n", areaNum ); - return false; - } - if ( goalAreaNum <= 0 || goalAreaNum >= file->GetNumAreas() ) { - gameLocal.Printf( "RouteToGoalArea: goalAreaNum %d out of range\n", goalAreaNum ); - return false; - } - - while( totalCacheMemory > MAX_ROUTING_CACHE_MEMORY ) { - DeleteOldestCache(); - } - - int clusterNum = file->GetArea( areaNum ).cluster; - int goalClusterNum = file->GetArea( goalAreaNum ).cluster; - - idRoutingCache* portalCache = NULL; - const aasPortal_t* portal = NULL; - - // if the source area is a cluster portal, read directly from the portal cache - if ( clusterNum < 0 ) { - // if the goal area is a portal - if ( goalClusterNum < 0 ) { - // just assume the goal area is part of the front cluster - portal = &file->GetPortal( -goalClusterNum ); - goalClusterNum = portal->clusters[0]; - } - // get the portal routing cache - portalCache = GetPortalRoutingCache( goalClusterNum, goalAreaNum, travelFlags ); - *reach = GetAreaReachability( areaNum, portalCache->reachabilities[-clusterNum] ); - travelTime = portalCache->travelTimes[-clusterNum] + AreaTravelTime( areaNum, origin, (*reach)->start ); - return true; - } - - unsigned short int bestTime = 0; - idReachability* bestReach = NULL; - - // check if the goal area is a portal of the source area cluster - if ( goalClusterNum < 0 ) { - portal = &file->GetPortal( -goalClusterNum ); - if ( portal->clusters[0] == clusterNum || portal->clusters[1] == clusterNum) { - goalClusterNum = clusterNum; - } - } - - int clusterAreaNum = 0; - idRoutingCache* clusterCache = NULL; - - // if both areas are in the same cluster - if ( clusterNum > 0 && goalClusterNum > 0 && clusterNum == goalClusterNum ) { - clusterCache = GetAreaRoutingCache( clusterNum, goalAreaNum, travelFlags ); - clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); - - if ( clusterCache->travelTimes[clusterAreaNum] ) { - bestReach = GetAreaReachability( areaNum, clusterCache->reachabilities[clusterAreaNum] ); - bestTime = clusterCache->travelTimes[clusterAreaNum] + AreaTravelTime( areaNum, origin, bestReach->start ); - } - else { - clusterCache = NULL; - } - } - - clusterNum = file->GetArea( areaNum ).cluster; - goalClusterNum = file->GetArea( goalAreaNum ).cluster; - - // if the goal area is a portal - if ( goalClusterNum < 0 ) { - // just assume the goal area is part of the front cluster - portal = &file->GetPortal( -goalClusterNum ); - goalClusterNum = portal->clusters[0]; - } - // get the portal routing cache - portalCache = GetPortalRoutingCache( goalClusterNum, goalAreaNum, travelFlags ); - - // the cluster the area is in - const aasCluster_t* cluster = &file->GetCluster( clusterNum ); - // current area inside the current cluster - clusterAreaNum = ClusterAreaNum( clusterNum, areaNum ); - // if the area is not a reachable area - if ( clusterAreaNum >= cluster->numReachableAreas) { - return false; - } - - int bestPortalAreaNum = 0; - // find the portal of the source area cluster leading towards the goal area - for (int i = 0; i < cluster->numPortals; i++ ) { - int portalNum = file->GetPortalIndex( cluster->firstPortal + i ); - - // if the goal area isn't reachable from the portal - if ( !portalCache->travelTimes[portalNum] ) { - continue; - } - - portal = &file->GetPortal( portalNum ); - int portalAreaNum = portal->areaNum; - - // angua: area is forbidden (e.g. locked door) - if (actor != NULL && gameLocal.m_AreaManager.AreaIsForbidden(portalAreaNum, static_cast(actor))) - { - continue; - } - - // get the cache of the portal area - idRoutingCache* areaCache = GetAreaRoutingCache( clusterNum, portal->areaNum, travelFlags ); - // if the portal is not reachable from this area - if ( !areaCache->travelTimes[clusterAreaNum] ) { - continue; - } - - idReachability* r = GetAreaReachability( areaNum, areaCache->reachabilities[clusterAreaNum] ); - - if ( clusterCache ) { - // if the next reachability from the portal leads back into the cluster - idReachability* nextr = GetAreaReachability( portal->areaNum, portalCache->reachabilities[portalNum] ); - if ( file->GetArea( nextr->toAreaNum ).cluster < 0 || file->GetArea( nextr->toAreaNum ).cluster == clusterNum ) { - continue; - } - } - - // the total travel time is the travel time from the portal area to the goal area - // plus the travel time from the source area towards the portal area - unsigned short int t = portalCache->travelTimes[portalNum] + areaCache->travelTimes[clusterAreaNum]; - - // NOTE: Should add the exact travel time through the portal area. - // However we add the largest travel time through the portal area. - // We cannot directly calculate the exact travel time through the portal area - // because the reachability used to travel into the portal area is not known. - t += portal->maxAreaTravelTime; - - // if the time is better than the one already found - if ( !bestTime || t < bestTime ) { - bestPortalAreaNum = portalAreaNum; - bestReach = r; - bestTime = t; - } - } - - if (bestPortalAreaNum > 0) - { - // angua: check if there is a door in the path - aasArea_t portalArea = file->GetArea(bestPortalAreaNum); - if (portalArea.travelFlags & TFL_DOOR) - { - CFrobDoor* door = GetDoor(bestPortalAreaNum); - if (door != NULL && firstDoor != NULL) - { - *firstDoor = door; - } - } - } - - - if ( !bestReach ) { - return false; - } - - *reach = bestReach; - travelTime = bestTime; - - return true; -} - -/* -============ -idAASLocal::TravelTimeToGoalArea -============ -*/ -int idAASLocal::TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags, idActor* actor ) const { - int travelTime; - idReachability *reach; - - if ( !file ) { - return 0; - } - - if ( !RouteToGoalArea( areaNum, origin, goalAreaNum, travelFlags, travelTime, &reach, NULL, actor ) ) { - return 0; - } - return travelTime; -} - -/* -============ -idAASLocal::FindNearestGoal -maxTravelCost is optional and defaults to 0, meaning no maximum -============ -*/ -bool idAASLocal::FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback, unsigned short maxTravelCost ) const { - int i, j, k, badTravelFlags, nextAreaNum, bestAreaNum; - unsigned short t, bestTravelTime; - idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; - idReachability *reach; - const aasArea_t *nextArea; - idVec3 v1, v2, p; - float targetDist, dist; - - if ( file == NULL || areaNum <= 0 ) { - goal.areaNum = areaNum; - goal.origin = origin; - return false; - } - - // if the first area is valid goal, just return the origin - if ( callback.TestArea( this, areaNum ) ) { - goal.areaNum = areaNum; - goal.origin = origin; - return true; - } - - // setup obstacles - for ( k = 0; k < numObstacles; k++ ) { - obstacles[k].expAbsBounds[0] = obstacles[k].absBounds[0] - file->GetSettings().boundingBoxes[0][1]; - obstacles[k].expAbsBounds[1] = obstacles[k].absBounds[1] - file->GetSettings().boundingBoxes[0][0]; - } - - badTravelFlags = ~travelFlags; - SIMDProcessor->Memset( goalAreaTravelTimes, 0, file->GetNumAreas() * sizeof( unsigned short ) ); - - targetDist = (target - origin).Length(); - - // initialize first update - curUpdate = &areaUpdate[areaNum]; - curUpdate->areaNum = areaNum; - curUpdate->tmpTravelTime = 0; - curUpdate->start = origin; - curUpdate->next = NULL; - curUpdate->prev = NULL; - updateListStart = curUpdate; - updateListEnd = curUpdate; - - bestTravelTime = 0; - bestAreaNum = 0; - - // while there are updates in the list - while ( updateListStart ) { - - curUpdate = updateListStart; - if ( curUpdate->next ) { - curUpdate->next->prev = NULL; - } - else { - updateListEnd = NULL; - } - updateListStart = curUpdate->next; - - curUpdate->isInList = false; - - // if we already found a closer location - if ( bestTravelTime && curUpdate->tmpTravelTime >= bestTravelTime ) { - continue; - } - - for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).reach; reach; reach = reach->next, i++ ) { - - // if the reachability uses an undesired travel type - if ( reach->travelType & badTravelFlags ) { - continue; - } - - // next area the reversed reachability leads to - nextAreaNum = reach->toAreaNum; - nextArea = &file->GetArea( nextAreaNum ); - - // if traveling through the next area requires an undesired travel flag - if ( nextArea->travelFlags & badTravelFlags ) { - continue; - } - - t = curUpdate->tmpTravelTime + - AreaTravelTime( curUpdate->areaNum, curUpdate->start, reach->start ) + - reach->travelTime; - - // Don't travel too far - if (maxTravelCost && t >= maxTravelCost) { - continue; - } - - // project target origin onto movement vector through the area - v1 = reach->end - curUpdate->start; - v1.Normalize(); - v2 = target - curUpdate->start; - p = curUpdate->start + (v2 * v1) * v1; - - // get the point on the path closest to the target - for ( j = 0; j < 3; j++ ) { - if ( (p[j] > curUpdate->start[j] + 0.1f && p[j] > reach->end[j] + 0.1f) || - (p[j] < curUpdate->start[j] - 0.1f && p[j] < reach->end[j] - 0.1f) ) { - break; - } - } - if ( j >= 3 ) { - dist = (target - p).Length(); - } else { - dist = (target - reach->end).Length(); - } - - // avoid moving closer to the target - if ( dist < targetDist ) { - t += static_cast(( targetDist - dist ) * 10); - } - - // if we already found a closer location - if ( bestTravelTime && t >= bestTravelTime ) { - continue; - } - - // if this is not the best path towards the next area - if ( goalAreaTravelTimes[nextAreaNum] && t >= goalAreaTravelTimes[nextAreaNum] ) { - continue; - } - - // path may not go through any obstacles - for ( k = 0; k < numObstacles; k++ ) { - // if the movement vector intersects the expanded obstacle bounds - if ( obstacles[k].expAbsBounds.LineIntersection( curUpdate->start, reach->end ) ) { - break; - } - } - if ( k < numObstacles ) { - continue; - } - - goalAreaTravelTimes[nextAreaNum] = t; - nextUpdate = &areaUpdate[nextAreaNum]; - nextUpdate->areaNum = nextAreaNum; - nextUpdate->tmpTravelTime = t; - nextUpdate->start = reach->end; - - // if we are not allowed to fly - if ( badTravelFlags & TFL_FLY ) { - // avoid areas near ledges - if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) { - nextUpdate->tmpTravelTime += LEDGE_TRAVELTIME_PANALTY; - } - } - - if ( !nextUpdate->isInList ) { - nextUpdate->next = NULL; - nextUpdate->prev = updateListEnd; - if ( updateListEnd ) { - updateListEnd->next = nextUpdate; - } else { - updateListStart = nextUpdate; - } - updateListEnd = nextUpdate; - nextUpdate->isInList = true; - } - - // don't put goal near a ledge - if ( !( nextArea->flags & AREA_LEDGE ) ) { - - // add travel time through the area - t += AreaTravelTime( reach->toAreaNum, reach->end, nextArea->center ); - - if ( !bestTravelTime || t < bestTravelTime ) { - // if the area is not visible to the target - if ( callback.TestArea( this, reach->toAreaNum ) ) { - bestTravelTime = t; - bestAreaNum = reach->toAreaNum; - } - } - } - } - } - - if ( bestAreaNum ) { - goal.areaNum = bestAreaNum; - goal.origin = AreaCenter( bestAreaNum ); - return true; - } - - return false; -} - -/* -============ -idAASLocal::FindClosestTargetToGoal -============ -*/ -bool idAASLocal::FindGoalClosestToTarget( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const -{ - int i, k, badTravelFlags, nextAreaNum, bestAreaNum; - bool b_haveClosestDistance; - float closestDistanceToTarget; - float distanceToTarget; - idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate; - idReachability *reach; - const aasArea_t *nextArea; - idVec3 v1, v2, p; - float targetDist; - - if ( file == NULL || areaNum <= 0 ) - { - goal.areaNum = areaNum; - goal.origin = origin; - return false; - } - - /* - // We want closest to target, not closest to us - // if the first area is valid goal, just return the origin - if ( callback.TestArea( this, areaNum ) ) - { - goal.areaNum = areaNum; - goal.origin = origin; - return true; - } - */ - - // setup obstacles - for ( k = 0; k < numObstacles; k++ ) - { - obstacles[k].expAbsBounds[0] = obstacles[k].absBounds[0] - file->GetSettings().boundingBoxes[0][1]; - obstacles[k].expAbsBounds[1] = obstacles[k].absBounds[1] - file->GetSettings().boundingBoxes[0][0]; - } - - badTravelFlags = ~travelFlags; - SIMDProcessor->Memset( goalAreaTravelTimes, 0, file->GetNumAreas() * sizeof( unsigned short ) ); - - targetDist = (target - origin).Length(); - - // Clear the area update tmpTravelTime members, as we use those as breadcrumbs - int numAreas = file->GetNumAreas(); - for (int ai = 0; ai < numAreas; ai ++) - { - areaUpdate[ai].tmpTravelTime = 0; - } - - - // initialize first update - curUpdate = &areaUpdate[areaNum]; - curUpdate->areaNum = areaNum; - curUpdate->tmpTravelTime = 0; - curUpdate->start = origin; - curUpdate->next = NULL; - curUpdate->prev = NULL; - updateListStart = curUpdate; - updateListEnd = curUpdate; - - closestDistanceToTarget = 0.0; - b_haveClosestDistance = false; - bestAreaNum = 0; - - // while there are updates in the list - while ( updateListStart ) - { - - curUpdate = updateListStart; - if ( curUpdate->next ) - { - curUpdate->next->prev = NULL; - } - else - { - updateListEnd = NULL; - } - updateListStart = curUpdate->next; - - curUpdate->isInList = false; - - // If we already checked this area, we are done with it - // We use the tmpTravelTime as a boolean flag to indicate if we have searched an area or not - if (curUpdate->tmpTravelTime > 1.0) - { - continue; - } - else - { - // We are checking it - curUpdate->tmpTravelTime = 2; - } - - - // What is the distance to the target - distanceToTarget = (file->AreaCenter(curUpdate->areaNum) - target).Length(); - - // If is closest so far - if ( !b_haveClosestDistance || distanceToTarget < closestDistanceToTarget) - { - // if the area is not visible to the target - if ( callback.TestArea( this, curUpdate->areaNum ) ) - { - closestDistanceToTarget = distanceToTarget; - b_haveClosestDistance = true; - bestAreaNum = curUpdate->areaNum; - } - } - - // if we already found a closer location we are done - /* - if - ( - ( b_haveClosestDistance) && - ((closestDistanceToTarget * 2.0) <= distanceToTarget) - ) - { - continue; - } - */ - - for ( i = 0, reach = file->GetArea( curUpdate->areaNum ).reach; reach; reach = reach->next, i++ ) - { - // if the reachability uses an undesired travel type - if ( reach->travelType & badTravelFlags ) - { - continue; - } - - // next area the reversed reachability leads to - nextAreaNum = reach->toAreaNum; - nextArea = &file->GetArea( nextAreaNum ); - - // if traveling through the next area requires an undesired travel flag - if ( nextArea->travelFlags & badTravelFlags ) - { - continue; - } - - // path may not go through any obstacles - for ( k = 0; k < numObstacles; k++ ) - { - // if the movement vector intersects the expanded obstacle bounds - if ( obstacles[k].expAbsBounds.LineIntersection( curUpdate->start, reach->end ) ) - { - break; - } - } - if ( k < numObstacles ) - { - continue; - } - - nextUpdate = &areaUpdate[nextAreaNum]; - nextUpdate->areaNum = nextAreaNum; - nextUpdate->start = reach->end; - - - // if we are not allowed to fly - if ( badTravelFlags & TFL_FLY ) - { - // avoid areas near ledges - if ( file->GetArea( nextAreaNum ).flags & AREA_LEDGE ) - { - continue; - } - } - - if ( !nextUpdate->isInList ) - { - nextUpdate->next = NULL; - nextUpdate->prev = updateListEnd; - if ( updateListEnd ) - { - updateListEnd->next = nextUpdate; - } - else - { - updateListStart = nextUpdate; - } - updateListEnd = nextUpdate; - nextUpdate->isInList = true; - - } - - /* - // don't put goal near a ledge - distanceToTarget = (file->AreaCenter(reach->toAreaNum) - target).Length(); - if ( !( nextArea->flags & AREA_LEDGE ) ) - { - // If is closest so far - if ( !b_haveClosestDistance || distanceToTarget < closestDistanceToTarget) - { - // if the area is not visible to the target - if ( callback.TestArea( this, reach->toAreaNum ) ) - { - closestDistanceToTarget = distanceToTarget; - b_haveClosestDistance = true; - bestAreaNum = reach->toAreaNum; - } - } - } - */ - } - } - - if ( bestAreaNum ) - { - goal.areaNum = bestAreaNum; - goal.origin = AreaCenter( bestAreaNum ); - return true; - } - - return false; -} - -void idAASLocal::AddElevator(CMultiStateMover* mover) -{ - elevatorSystem->AddElevator(mover); -} - -void idAASLocal::CompileEAS() -{ - elevatorSystem->Compile(); -} - -int idAASLocal::GetAreaInCluster(int clusterNum) -{ - if (!file) return -1; - - // Find an area within that cluster - for (int i = 0; i < file->GetNumAreas(); i++) - { - const aasArea_t& area = file->GetArea(i); - if (area.cluster == clusterNum && (area.flags & AREA_REACHABLE_WALK) != 0) - { - return i; - } - } - - return -1; -} diff --git a/game/ai/ai.cpp b/game/ai/ai.cpp deleted file mode 100644 index 26ff93b1c..000000000 --- a/game/ai/ai.cpp +++ /dev/null @@ -1,11626 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/AI/Mind.h" -#include "../../DarkMod/AI/Subsystem.h" -#include "../../DarkMod/AI/MovementSubsystem.h" -#include "../../DarkMod/AI/Memory.h" -#include "../../DarkMod/AI/States/KnockedOutState.h" -#include "../../DarkMod/AI/States/DeadState.h" -#include "../../DarkMod/AI/States/ConversationState.h" -#include "../../DarkMod/AI/States/PainState.h" -#include "../../DarkMod/AI/States/IdleState.h" -#include "../../DarkMod/AI/States/ObservantState.h" -#include "../../DarkMod/AI/States/SuspiciousState.h" -#include "../../DarkMod/AI/States/SearchingState.h" -#include "../../DarkMod/AI/States/AgitatedSearchingState.h" -#include "../../DarkMod/AI/States/CombatState.h" -#include "../../DarkMod/AI/Tasks/SingleBarkTask.h" -#include "../../DarkMod/AI/Conversation/ConversationSystem.h" -#include "../../DarkMod/Relations.h" -#include "../../DarkMod/Objectives/MissionData.h" -#include "../../DarkMod/StimResponse/StimResponseCollection.h" -#include "../../DarkMod/AbsenceMarker.h" -#include "../../DarkMod/BloodMarker.h" -#include "../../DarkMod/DarkModGlobals.h" -#include "../../DarkMod/MultiStateMover.h" -#include "../../DarkMod/MeleeWeapon.h" -#include "../../DarkMod/sndProp.h" -#include "../../DarkMod/EscapePointManager.h" -#include "../../DarkMod/PositionWithinRangeFinder.h" -#include "../../DarkMod/TimerManager.h" -#include "../../DarkMod/ProjectileResult.h" // grayman #2872 - -// For handling the opening of doors and other binary Frob movers -#include "../../DarkMod/BinaryFrobMover.h" -#include "../../DarkMod/FrobDoor.h" -#include "../../DarkMod/FrobDoorHandle.h" -#include "tdmAASFindEscape.h" -#include "../../DarkMod/AI/AreaManager.h" - -#include - -//TODO: Move these to AI def: - -// Visual detection parameters - -/** -* amount of time to normalize by for the % check, in seconds -* this gets modified by 1 / the cvar dm_ai_sight. -**/ -static const float s_VisNormtime = 0.2f; - -/** -* In pitch darkness, player is invisible -**/ -// full bright minimum distance is 0 -static const float s_VisFDMin = 0.0f; - -// full bright maximum distance is zero (because probability is always zero anyway) -static const float s_VisFDMax = 0.0f; - -// TODO: Move this to def file or INI -static const float s_AITactDist = 1.0f; - -const float s_DOOM_TO_METERS = 0.0254f; - -// TDM: Maximum flee distance for any AI -const float MAX_FLEE_DISTANCE = 10000.0f; - -class CRelations; -class CsndProp; -class CDarkModPlayer; -class CMissionData; - -static const char *moveCommandString[ NUM_MOVE_COMMANDS ] = { - "MOVE_NONE", - "MOVE_FACE_ENEMY", - "MOVE_FACE_ENTITY", - "MOVE_TO_ENEMY", - "MOVE_TO_ENEMYHEIGHT", - "MOVE_TO_ENTITY", - "MOVE_OUT_OF_RANGE", - "MOVE_TO_ATTACK_POSITION", - "MOVE_TO_COVER", - "MOVE_TO_POSITION", - "MOVE_TO_POSITION_DIRECT", - "MOVE_SLIDE_TO_POSITION", - "MOVE_WANDER" -}; - -/* -============ -idAASFindCover::idAASFindCover -============ -*/ -idAASFindCover::idAASFindCover( const idActor* hidingActor, const idEntity* hideFromEnt, const idVec3 &hideFromPos ) { - this->hidingActor = hidingActor; // This should not be NULL - this->hideFromEnt = hideFromEnt; // May be NULL - this->hideFromPos = hideFromPos; -} - -/* -============ -idAASFindCover::~idAASFindCover -============ -*/ -idAASFindCover::~idAASFindCover() { -} - -/* -============ -idAASFindCover::TestArea -============ -*/ -bool idAASFindCover::TestArea( const idAAS *aas, int areaNum ) -{ - idVec3 areaCenter; - trace_t trace, trace2; - - if (areaNum == aas->PointAreaNum(hidingActor->GetPhysics()->GetOrigin())) - { - // We're in this AAS area; assume that our current position can never be cover. - // (If it was, we probably wouldn't be trying to move into cover.) - return false; - } - - // Get location of feet - // Assumes they're at the centre of the bounding box in the X and Y axes, - // but at the bottom in the Z axis. - idBounds bounds = hidingActor->GetPhysics()->GetAbsBounds(); - idVec3 feet = (bounds[0] + bounds[1]) * 0.5f; - feet.z = bounds[0].z; - - // Get location to trace to - areaCenter = aas->AreaCenter( areaNum ); - - // Adjust areaCenter to factor in height of AI, so we trace from the estimated eye position - areaCenter += hidingActor->GetEyePosition() - feet; - - gameLocal.clip.TracePoint(trace, hideFromPos, areaCenter, MASK_OPAQUE, hideFromEnt); - if (trace.fraction < 1.0f) - { - // The trace was interrupted, so this location is probably cover. - //gameRenderWorld->DebugLine( colorGreen, hideFromPos, areaCenter, 5000, true); - - // But before we say for certain, let's look at the floor as well. - areaCenter = aas->AreaCenter( areaNum ); - gameLocal.clip.TracePoint(trace2, hideFromPos, areaCenter, MASK_OPAQUE, hideFromEnt); - if (trace2.fraction < 1.0f) - { - // Yes, the feet are hidden too, so this is almost certainly cover - //gameRenderWorld->DebugLine( colorGreen, hideFromPos, areaCenter, 5000, true); - return true; - } - - // Oops; the head is hidden but the feet are not, so this isn't very good cover at all. - //gameRenderWorld->DebugLine( colorRed, hideFromPos, areaCenter, 5000, true); - return false; - } - - // The trace found a clear path, so this location is not cover. - //gameRenderWorld->DebugLine( colorRed, hideFromPos, areaCenter, 5000, true); - return false; -} - -/* -============ -idAASFindAreaOutOfRange::idAASFindAreaOutOfRange -============ -*/ -idAASFindAreaOutOfRange::idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist ) { - this->targetPos = targetPos; - this->maxDistSqr = maxDist * maxDist; -} - -/* -============ -idAASFindAreaOutOfRange::TestArea -============ -*/ -bool idAASFindAreaOutOfRange::TestArea( const idAAS *aas, int areaNum ) { - const idVec3 &areaCenter = aas->AreaCenter( areaNum ); - trace_t trace; - float dist; - - dist = ( targetPos.ToVec2() - areaCenter.ToVec2() ).LengthSqr(); - - if ( ( maxDistSqr > 0.0f ) && ( dist < maxDistSqr ) ) { - return false; - } - - gameLocal.clip.TracePoint( trace, targetPos, areaCenter + idVec3( 0.0f, 0.0f, 1.0f ), MASK_OPAQUE, NULL ); - if ( trace.fraction < 1.0f ) { - return false; - } - - return true; -} - -/* -============ -idAASFindAttackPosition::idAASFindAttackPosition -============ -*/ -idAASFindAttackPosition::idAASFindAttackPosition(idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset) -{ - int numPVSAreas; - - this->target = target; - this->targetPos = targetPos; - this->fireOffset = fireOffset; - this->self = self; - this->gravityAxis = gravityAxis; - - excludeBounds = idBounds( idVec3( -64.0, -64.0f, -8.0f ), idVec3( 64.0, 64.0f, 64.0f ) ); - excludeBounds.TranslateSelf( self->GetPhysics()->GetOrigin() ); - - // setup PVS - idBounds bounds( targetPos - idVec3( 16, 16, 0 ), targetPos + idVec3( 16, 16, 64 ) ); - numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); - targetPVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); -} - -/* -============ -idAASFindAttackPosition::~idAASFindAttackPosition -============ -*/ -idAASFindAttackPosition::~idAASFindAttackPosition() { - gameLocal.pvs.FreeCurrentPVS( targetPVS ); -} - -/* -============ -idAASFindAttackPosition::TestArea -============ -*/ -bool idAASFindAttackPosition::TestArea( const idAAS *aas, int areaNum ) { - idVec3 dir; - idVec3 local_dir; - idVec3 fromPos; - idMat3 axis; - idVec3 areaCenter; - int numPVSAreas; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; - - areaCenter = aas->AreaCenter( areaNum ); - areaCenter[ 2 ] += 1.0f; - - if ( excludeBounds.ContainsPoint( areaCenter ) ) { - // too close to where we already are - return false; - } - - numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); - if ( !gameLocal.pvs.InCurrentPVS( targetPVS, PVSAreas, numPVSAreas ) ) { - return false; - } - - // calculate the world transform of the launch position - dir = targetPos - areaCenter; - gravityAxis.ProjectVector( dir, local_dir ); - local_dir.z = 0.0f; - local_dir.ToVec2().Normalize(); - axis = local_dir.ToMat3(); - fromPos = areaCenter + fireOffset * axis; - - return self->GetAimDir( fromPos, target, self, dir ); -} - - -/* -============ -idAASFindObservationPosition::idAASFindObservationPosition -============ -*/ -idAASFindObservationPosition::idAASFindObservationPosition( const idAI *self, const idMat3 &gravityAxis, const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistanceFromWhichToObserve ) -{ - int numPVSAreas; - - this->targetPos = targetPos; - this->eyeOffset = eyeOffset; - this->self = self; - this->gravityAxis = gravityAxis; - this->maxObservationDistance = maxDistanceFromWhichToObserve; - this->b_haveBestGoal = false; - - - // setup PVS - idBounds bounds( targetPos - idVec3( 16, 16, 0 ), targetPos + idVec3( 16, 16, 64 ) ); - numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); - targetPVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); -} - -/* -============ -idAASFindObservationPosition::~idAASFindObservationPosition -============ -*/ -idAASFindObservationPosition::~idAASFindObservationPosition() { - gameLocal.pvs.FreeCurrentPVS( targetPVS ); -} - -/* -============ -idAASFindObservationPosition::TestArea -============ -*/ -bool idAASFindObservationPosition::TestArea( const idAAS *aas, int areaNum ) -{ - idVec3 dir; - idVec3 local_dir; - idVec3 fromPos; - idMat3 axis; - idVec3 areaCenter; - - areaCenter = aas->AreaCenter( areaNum ); - areaCenter[ 2 ] += 1.0f; - - /* - numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); - if ( !gameLocal.pvs.InCurrentPVS( targetPVS, PVSAreas, numPVSAreas ) ) { - return false; - } - */ - - // calculate the world transform of the view position - dir = targetPos - areaCenter; - gravityAxis.ProjectVector( dir, local_dir ); - local_dir.z = 0.0f; - local_dir.ToVec2().Normalize(); - axis = local_dir.ToMat3(); - - fromPos = areaCenter + eyeOffset * axis; - - // Run trace - trace_t results; - gameLocal.clip.TracePoint( results, fromPos, targetPos, MASK_SOLID, self ); - if ( results.fraction >= 1.0f ) - { - // What is the observation distance? - float distance = (fromPos - targetPos).Length(); - - // Remember best result, even if outside max distance allowed - if ((!b_haveBestGoal) || (distance < bestGoalDistance)) - { - b_haveBestGoal = true; - bestGoalDistance = distance; - bestGoal.areaNum = areaNum; - bestGoal.origin = areaCenter; - } - if (distance > maxObservationDistance) - { - // Can't use this point, its too far - return false; - } - return true; - } - else - { - return false; - } - -} - -//------------------------------------------------------------------------------ - -bool idAASFindObservationPosition::getBestGoalResult -( - float& out_bestGoalDistance, - aasGoal_t& out_bestGoal -) -{ - if (b_haveBestGoal) - { - out_bestGoalDistance = bestGoalDistance; - out_bestGoal = bestGoal; - return true; - } - else - { - return false; - } -} - - -/* -===================== -idAI::idAI -===================== -*/ -idAI::idAI() -{ - aiNode.SetOwner(this); - - aas = NULL; - travelFlags = TFL_WALK|TFL_AIR|TFL_DOOR; - lastAreaReevaluationTime = -1; - maxAreaReevaluationInterval = 2000; // msec - doorRetryTime = 120000; // msec - - kickForce = 60.0f; // grayman #2568 - default Doom 3 value - ignore_obstacles = false; - blockedRadius = 0.0f; - blockedMoveTime = 750; - blockedAttackTime = 750; - turnRate = 360.0f; - turnVel = 0.0f; - anim_turn_yaw = 0.0f; - anim_turn_amount = 0.0f; - anim_turn_angles = 0.0f; - reachedpos_bbox_expansion = 0.0f; - aas_reachability_z_tolerance = 75; - fly_offset = 0; - fly_seek_scale = 1.0f; - fly_roll_scale = 0.0f; - fly_roll_max = 0.0f; - fly_roll = 0.0f; - fly_pitch_scale = 0.0f; - fly_pitch_max = 0.0f; - fly_pitch = 0.0f; - allowMove = false; - allowHiddenMovement = false; - fly_speed = 0.0f; - fly_bob_strength = 0.0f; - fly_bob_vert = 0.0f; - fly_bob_horz = 0.0f; - lastHitCheckResult = false; - lastHitCheckTime = 0; - lastAttackTime = 0; - fire_range = 0.0f; - projectile_height_to_distance_ratio = 1.0f; - activeProjectile.projEnt = NULL; - curProjectileIndex = -1; - talk_state = TALK_NEVER; - talkTarget = NULL; - - particles.Clear(); - restartParticles = true; - useBoneAxis = false; - - wakeOnFlashlight = false; - lastUpdateEnemyPositionTime = -1; - - // grayman #2887 - for keeping track of the total time this AI saw the player - lastTimePlayerSeen = -1; - lastTimePlayerLost = -1; - - memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); - worldMuzzleFlashHandle = -1; - - enemy = NULL; - lastVisibleEnemyPos.Zero(); - lastVisibleEnemyEyeOffset.Zero(); - lastVisibleReachableEnemyPos.Zero(); - lastReachableEnemyPos.Zero(); - enemyReachable = false; - shrivel_rate = 0.0f; - shrivel_start = 0; - fl.neverDormant = false; // AI's can go dormant - current_yaw = 0.0f; - ideal_yaw = 0.0f; - - num_cinematics = 0; - current_cinematic = 0; - - allowEyeFocus = true; - allowPain = true; - allowJointMod = true; - focusEntity = NULL; - focusTime = 0; - alignHeadTime = 0; - forceAlignHeadTime = 0; - - currentFocusPos.Zero(); - eyeAng.Zero(); - lookAng.Zero(); - destLookAng.Zero(); - lookMin.Zero(); - lookMax.Zero(); - - eyeMin.Zero(); - eyeMax.Zero(); - muzzleFlashEnd = 0; - flashTime = 0; - flashJointWorld = INVALID_JOINT; - - focusJoint = INVALID_JOINT; - orientationJoint = INVALID_JOINT; - flyTiltJoint = INVALID_JOINT; - - eyeVerticalOffset = 0.0f; - eyeHorizontalOffset = 0.0f; - eyeFocusRate = 0.0f; - headFocusRate = 0.0f; - focusAlignTime = 0; - m_tactileEntity = NULL; // grayman #2345 - m_canResolveBlock = true; // grayman #2345 - m_leftQueue = false; // grayman #2345 - m_performRelight = false; // grayman #2603 - - m_SoundDir.Zero(); - m_LastSight.Zero(); - m_AlertLevelThisFrame = 0.0f; - m_prevAlertIndex = 0; - m_maxAlertLevel = 0; - m_maxAlertIndex = 0; - m_AlertedByActor = NULL; - - m_TactAlertEnt = NULL; - m_AlertGraceActor = NULL; - m_AlertGraceStart = 0; - m_AlertGraceTime = 0; - m_AlertGraceThresh = 0; - m_AlertGraceCount = 0; - m_AlertGraceCountLimit = 0; - m_AudThreshold = 0.0f; - m_oldVisualAcuity = 0.0f; - - /** - * Darkmod: No hiding spot search by default - */ - m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; - - m_bCanDrown = true; - m_AirCheckTimer = 0; - m_AirTics = 0; - m_AirTicksMax = 0; - m_HeadBodyID = 0; - m_HeadJointID = INVALID_JOINT; - m_OrigHeadCM = NULL; - m_bHeadCMSwapped = false; - m_MouthOffset = vec3_zero; - - m_bCanBeKnockedOut = true; - m_HeadCenterOffset = vec3_zero; - m_FOVRot = mat3_identity; - m_bKoAlertImmune = false; - m_KoDotVert = 0; - m_KoDotHoriz = 0; - m_KoAlertDotHoriz = 0; - m_KoRot = mat3_identity; - - m_bCanBeGassed = true; // grayman #2468 - m_koState = KO_NOT; // grayman #2604 - m_earlyThinkCounter = 5 + gameLocal.random.RandomInt(5); // grayman #2654 - m_bCanExtricate = true; // grayman #2603 - - m_bCanOperateDoors = false; - - m_lipSyncActive = false; - - m_bPushOffPlayer = false; - - m_bCanBeFlatFooted = false; - m_bFlatFooted = false; - m_FlatFootedTimer = 0; - m_FlatFootedTime = 0; - - m_FlatFootParryNum = 0; - m_FlatFootParryMax = 0; - m_FlatFootParryTimer = 0; - m_FlatFootParryTime = 0; - m_MeleeCounterAttChance = 0.0f; - m_bMeleePredictProximity = false; - - m_maxInterleaveThinkFrames = 0; - m_minInterleaveThinkDist = 1000; - m_maxInterleaveThinkDist = 3000; - m_lastThinkTime = 0; - m_nextThinkFrame = 0; - - INIT_TIMER_HANDLE(aiThinkTimer); - INIT_TIMER_HANDLE(aiMindTimer); - INIT_TIMER_HANDLE(aiAnimationTimer); - INIT_TIMER_HANDLE(aiPushWithAFTimer); - INIT_TIMER_HANDLE(aiUpdateEnemyPositionTimer); - INIT_TIMER_HANDLE(aiScriptTimer); - INIT_TIMER_HANDLE(aiAnimMoveTimer); - INIT_TIMER_HANDLE(aiObstacleAvoidanceTimer); - INIT_TIMER_HANDLE(aiPhysicsTimer); - INIT_TIMER_HANDLE(aiGetMovePosTimer); - INIT_TIMER_HANDLE(aiPathToGoalTimer); - INIT_TIMER_HANDLE(aiGetFloorPosTimer); - INIT_TIMER_HANDLE(aiPointReachableAreaNumTimer); - INIT_TIMER_HANDLE(aiCanSeeTimer); - -} - -/* -===================== -idAI::~idAI -===================== -*/ -idAI::~idAI() -{ - DeconstructScriptObject(); - scriptObject.Free(); - if ( worldMuzzleFlashHandle != -1 ) - { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); - worldMuzzleFlashHandle = -1; - } - - /** - * Darkmod: Get rid of current hiding spot search if there is one. - */ - destroyCurrentHidingSpotSearch(); - - aiNode.Remove(); - - if( m_OrigHeadCM ) - delete m_OrigHeadCM; -} - -/* -===================== -idAI::Save -===================== -*/ -void idAI::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( travelFlags ); - savefile->WriteInt(lastAreaReevaluationTime); - savefile->WriteInt(maxAreaReevaluationInterval); - savefile->WriteInt(doorRetryTime); - - move.Save( savefile ); - savedMove.Save( savefile ); - - // greebo: save the movestack - savefile->WriteInt(static_cast(moveStack.size())); - for (std::list::const_iterator m = moveStack.begin(); m != moveStack.end(); ++m) - { - m->Save(savefile); - } - - savefile->WriteFloat( kickForce ); - savefile->WriteBool( ignore_obstacles ); - savefile->WriteFloat( blockedRadius ); - savefile->WriteInt( blockedMoveTime ); - savefile->WriteInt( blockedAttackTime ); - - savefile->WriteFloat( ideal_yaw ); - savefile->WriteFloat( current_yaw ); - savefile->WriteFloat( turnRate ); - savefile->WriteFloat( turnVel ); - savefile->WriteFloat( anim_turn_yaw ); - savefile->WriteFloat( anim_turn_amount ); - savefile->WriteFloat( anim_turn_angles ); - savefile->WriteVec3(sitting_turn_pivot); - - savefile->WriteFloat(reachedpos_bbox_expansion); - savefile->WriteFloat(aas_reachability_z_tolerance); - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteFloat( fly_speed ); - savefile->WriteFloat( fly_bob_strength ); - savefile->WriteFloat( fly_bob_vert ); - savefile->WriteFloat( fly_bob_horz ); - savefile->WriteInt( fly_offset ); - savefile->WriteFloat( fly_seek_scale ); - savefile->WriteFloat( fly_roll_scale ); - savefile->WriteFloat( fly_roll_max ); - savefile->WriteFloat( fly_roll ); - savefile->WriteFloat( fly_pitch_scale ); - savefile->WriteFloat( fly_pitch_max ); - savefile->WriteFloat( fly_pitch ); - - savefile->WriteBool( allowMove ); - savefile->WriteBool( allowHiddenMovement ); - savefile->WriteBool( disableGravity ); - - savefile->WriteBool( lastHitCheckResult ); - savefile->WriteInt( lastHitCheckTime ); - savefile->WriteInt( lastAttackTime ); - savefile->WriteFloat( fire_range ); - savefile->WriteFloat( projectile_height_to_distance_ratio ); - - savefile->WriteInt( missileLaunchOffset.Num() ); - for( i = 0; i < missileLaunchOffset.Num(); i++ ) { - savefile->WriteVec3( missileLaunchOffset[ i ] ); - } - - savefile->WriteInt(projectileInfo.Num()); - - for (i = 0; i < projectileInfo.Num(); ++i) - { - const ProjectileInfo& info = projectileInfo[i]; - - // Save projectile def names instead of dict* pointers, will be resolved at restore time - // also leave clipmodel pointer alone, will be initialised to NULL on restore and - // reloaded on demand - savefile->WriteString(info.defName); - savefile->WriteFloat(info.radius); - savefile->WriteFloat(info.speed); - savefile->WriteVec3(info.velocity); - savefile->WriteVec3(info.gravity); - } - - savefile->WriteInt(curProjectileIndex); - - // Active Projectile - savefile->WriteString(activeProjectile.info.defName); - savefile->WriteFloat(activeProjectile.info.radius); - savefile->WriteFloat(activeProjectile.info.speed); - savefile->WriteVec3(activeProjectile.info.velocity); - savefile->WriteVec3(activeProjectile.info.gravity); - activeProjectile.projEnt.Save(savefile); - - savefile->WriteString( attack ); - - // grayman #2603 - delayed stim list - - savefile->WriteInt(delayedStims.Num()); - for (i = 0 ; i < delayedStims.Num() ; i++) - { - DelayedStim ds = delayedStims[i]; - - savefile->WriteInt(ds.nextTimeToConsider); - ds.stim.Save(savefile); - } - - savefile->WriteInt( talk_state ); - talkTarget.Save( savefile ); - - savefile->WriteInt( num_cinematics ); - savefile->WriteInt( current_cinematic ); - - savefile->WriteBool( allowJointMod ); - focusEntity.Save( savefile ); - savefile->WriteVec3( currentFocusPos ); - savefile->WriteInt( focusTime ); - savefile->WriteInt( alignHeadTime ); - savefile->WriteInt( forceAlignHeadTime ); - savefile->WriteAngles( eyeAng ); - savefile->WriteAngles( lookAng ); - savefile->WriteAngles( destLookAng ); - savefile->WriteAngles( lookMin ); - savefile->WriteAngles( lookMax ); - - savefile->WriteInt( lookJoints.Num() ); - for( i = 0; i < lookJoints.Num(); i++ ) { - savefile->WriteJoint( lookJoints[ i ] ); - savefile->WriteAngles( lookJointAngles[ i ] ); - } - savefile->WriteInt( lookJointsCombat.Num() ); - for( i = 0; i < lookJointsCombat.Num(); i++ ) { - savefile->WriteJoint( lookJointsCombat[ i ] ); - savefile->WriteAngles( lookJointAnglesCombat[ i ] ); - } - - savefile->WriteFloat( shrivel_rate ); - savefile->WriteInt( shrivel_start ); - - savefile->WriteInt( particles.Num() ); - for ( i = 0; i < particles.Num(); i++ ) { - savefile->WriteParticle( particles[i].particle ); - savefile->WriteInt( particles[i].time ); - savefile->WriteJoint( particles[i].joint ); - } - savefile->WriteBool( restartParticles ); - savefile->WriteBool( useBoneAxis ); - - enemy.Save( savefile ); - savefile->WriteVec3( lastVisibleEnemyPos ); - savefile->WriteVec3( lastVisibleEnemyEyeOffset ); - savefile->WriteVec3( lastVisibleReachableEnemyPos ); - savefile->WriteVec3( lastReachableEnemyPos ); - savefile->WriteBool( enemyReachable ); - savefile->WriteBool( wakeOnFlashlight ); - savefile->WriteInt(lastUpdateEnemyPositionTime); - - savefile->WriteInt(lastTimePlayerSeen); // grayman #2887 - savefile->WriteInt(lastTimePlayerLost); // grayman #2887 - - savefile->WriteAngles( eyeMin ); - savefile->WriteAngles( eyeMax ); - - savefile->WriteFloat( eyeVerticalOffset ); - savefile->WriteFloat( eyeHorizontalOffset ); - savefile->WriteFloat( eyeFocusRate ); - savefile->WriteFloat( headFocusRate ); - savefile->WriteInt( focusAlignTime ); - savefile->WriteObject(m_tactileEntity); // grayman #2345 - savefile->WriteBool(m_canResolveBlock); // grayman #2345 - savefile->WriteBool(m_leftQueue); // grayman #2345 - savefile->WriteBool(m_performRelight); // grayman #2603 - savefile->WriteJoint( flashJointWorld ); - savefile->WriteInt( muzzleFlashEnd ); - - savefile->WriteJoint( focusJoint ); - savefile->WriteJoint( orientationJoint ); - savefile->WriteJoint( flyTiltJoint ); - - // TDM Alerts: - savefile->WriteInt( m_Acuities.Num() ); - for( i = 0; i < m_Acuities.Num(); i++ ) - { - savefile->WriteFloat( m_Acuities[ i ] ); - } - savefile->WriteFloat(m_oldVisualAcuity); - savefile->WriteFloat( m_AudThreshold ); - savefile->WriteVec3( m_SoundDir ); - savefile->WriteVec3( m_LastSight ); - savefile->WriteFloat( m_AlertLevelThisFrame ); - savefile->WriteInt( m_prevAlertIndex ); - savefile->WriteFloat( m_maxAlertLevel); - savefile->WriteInt( m_maxAlertIndex); - savefile->WriteFloat(m_lastAlertLevel); - savefile->WriteBool( m_bIgnoreAlerts ); - - m_AlertedByActor.Save( savefile ); - - for (i = 0; i < ai::EAlertTypeCount; i++) - { - savefile->WriteInt(alertTypeWeight[i]); - } - - m_TactAlertEnt.Save( savefile ); - m_AlertGraceActor.Save( savefile ); - savefile->WriteInt( m_AlertGraceStart ); - savefile->WriteInt( m_AlertGraceTime ); - savefile->WriteFloat( m_AlertGraceThresh ); - savefile->WriteInt( m_AlertGraceCount ); - savefile->WriteInt( m_AlertGraceCountLimit ); - - savefile->WriteInt(m_Messages.Num()); - for (i = 0; i < m_Messages.Num(); i++) - { - m_Messages[i]->Save(savefile); - } - - savefile->WriteBool( GetPhysics() == static_cast(&physicsObj) ); - - savefile->WriteFloat(m_VisDistMax); - - savefile->WriteInt(m_HidingSpotSearchHandle); - m_hidingSpots.Save(savefile); - - savefile->WriteInt(m_AirCheckTimer); - savefile->WriteBool(m_bCanDrown); - savefile->WriteInt(m_HeadBodyID); - savefile->WriteJoint(m_HeadJointID); - - savefile->WriteBool( m_bHeadCMSwapped ); -// if( m_bHeadCMSwapped && m_OrigHeadCM ) -// m_OrigHeadCM->Save( savefile ); - - savefile->WriteInt(m_AirTics); - savefile->WriteInt(m_AirTicksMax); - savefile->WriteInt(m_AirCheckInterval); - - savefile->WriteVec3(m_MouthOffset); - savefile->WriteBool(m_bCanBeKnockedOut); - savefile->WriteVec3(m_HeadCenterOffset); - savefile->WriteMat3(m_FOVRot); - savefile->WriteString(m_KoZone); - savefile->WriteInt(m_KoAlertState); - savefile->WriteInt(m_KoAlertImmuneState); - savefile->WriteBool(m_bKoAlertImmune); - savefile->WriteFloat(m_KoDotVert); - savefile->WriteFloat(m_KoDotHoriz); - savefile->WriteFloat(m_KoAlertDotVert); - savefile->WriteFloat(m_KoAlertDotHoriz); - savefile->WriteMat3(m_KoRot); - - savefile->WriteBool(m_bCanBeGassed); // grayman #2468 - savefile->WriteInt( m_koState ); // grayman #2604 - savefile->WriteInt( m_earlyThinkCounter ); // grayman #2654 - savefile->WriteBool( m_bCanExtricate ); // grayman #2603 - - savefile->WriteFloat(thresh_1); - savefile->WriteFloat(thresh_2); - savefile->WriteFloat(thresh_3); - savefile->WriteFloat(thresh_4); - savefile->WriteFloat(thresh_5); - - savefile->WriteFloat(m_gracetime_1); - savefile->WriteFloat(m_gracetime_2); - savefile->WriteFloat(m_gracetime_3); - savefile->WriteFloat(m_gracetime_4); - savefile->WriteFloat(m_gracefrac_1); - savefile->WriteFloat(m_gracefrac_2); - savefile->WriteFloat(m_gracefrac_3); - savefile->WriteFloat(m_gracefrac_4); - savefile->WriteFloat(m_gracecount_1); - savefile->WriteFloat(m_gracecount_2); - savefile->WriteFloat(m_gracecount_3); - savefile->WriteFloat(m_gracecount_4); - - savefile->WriteFloat(atime1); - savefile->WriteFloat(atime2); - savefile->WriteFloat(atime3); - savefile->WriteFloat(atime4); - savefile->WriteFloat(atime_fleedone); - - savefile->WriteFloat(atime1_fuzzyness); - savefile->WriteFloat(atime2_fuzzyness); - savefile->WriteFloat(atime3_fuzzyness); - savefile->WriteFloat(atime4_fuzzyness); - savefile->WriteFloat(atime_fleedone_fuzzyness); - - savefile->WriteInt(m_timeBetweenHeadTurnChecks); - savefile->WriteFloat(m_headTurnChanceIdle); - savefile->WriteFloat(m_headTurnFactorAlerted); - savefile->WriteFloat(m_headTurnMaxYaw); - savefile->WriteFloat(m_headTurnMaxPitch); - savefile->WriteInt(m_headTurnMinDuration); - savefile->WriteInt(m_headTurnMaxDuration); - - savefile->WriteInt(static_cast(backboneStates.size())); - for (BackboneStateMap::const_iterator i = backboneStates.begin(); i != backboneStates.end(); ++i) - { - savefile->WriteInt(i->first); - savefile->WriteString(i->second); - } - - savefile->WriteInt(m_maxInterleaveThinkFrames); - savefile->WriteFloat(m_minInterleaveThinkDist); - savefile->WriteFloat(m_maxInterleaveThinkDist); - - savefile->WriteInt(m_lastThinkTime); - savefile->WriteInt(m_nextThinkFrame); - - savefile->WriteBool(m_bPushOffPlayer); - - savefile->WriteBool(m_bCanBeFlatFooted); - savefile->WriteBool(m_bFlatFooted); - savefile->WriteInt(m_FlatFootedTimer); - savefile->WriteInt(m_FlatFootedTime); - savefile->WriteInt(m_FlatFootParryNum); - savefile->WriteInt(m_FlatFootParryMax); - savefile->WriteInt(m_FlatFootParryTimer); - savefile->WriteInt(m_FlatFootParryTime); - savefile->WriteFloat(m_MeleeCounterAttChance); - savefile->WriteBool(m_bMeleePredictProximity); - - savefile->WriteBool(m_bCanOperateDoors); - savefile->WriteBool(m_HandlingDoor); - savefile->WriteBool(m_HandlingElevator); - savefile->WriteBool(m_RelightingLight); // grayman #2603 - savefile->WriteBool(m_ExaminingRope); // grayman #2872 - savefile->WriteBool(m_DroppingTorch); // grayman #2603 - savefile->WriteBool(m_RestoreMove); // grayman #2706 - savefile->WriteBool(m_LatchedSearch); // grayman #2603 - - // grayman #2603 - savefile->WriteInt( m_dousedLightsSeen.Num() ); - for (int i = 0 ; i < m_dousedLightsSeen.Num() ; i++ ) - { - m_dousedLightsSeen[i].Save(savefile); - } - - int size = unlockableDoors.size(); - savefile->WriteInt(size); - for (FrobMoverList::const_iterator i = unlockableDoors.begin(); i != unlockableDoors.end(); ++i) - { - savefile->WriteObject(*i); - } - - savefile->WriteInt(tactileIgnoreEntities.size()); - - for (TactileIgnoreList::const_iterator i = tactileIgnoreEntities.begin(); i != tactileIgnoreEntities.end(); ++i) - { - savefile->WriteObject(*i); - } - - mind->Save(savefile); - - senseSubsystem->Save(savefile); - movementSubsystem->Save(savefile); - commSubsystem->Save(savefile); - actionSubsystem->Save(savefile); - - SAVE_TIMER_HANDLE(aiThinkTimer, savefile); - SAVE_TIMER_HANDLE(aiMindTimer, savefile); - SAVE_TIMER_HANDLE(aiAnimationTimer, savefile); - SAVE_TIMER_HANDLE(aiPushWithAFTimer, savefile); - SAVE_TIMER_HANDLE(aiUpdateEnemyPositionTimer, savefile); - SAVE_TIMER_HANDLE(aiScriptTimer, savefile); - SAVE_TIMER_HANDLE(aiAnimMoveTimer, savefile); - SAVE_TIMER_HANDLE(aiObstacleAvoidanceTimer, savefile); - SAVE_TIMER_HANDLE(aiPhysicsTimer, savefile); - SAVE_TIMER_HANDLE(aiGetMovePosTimer, savefile); - SAVE_TIMER_HANDLE(aiPathToGoalTimer, savefile); - SAVE_TIMER_HANDLE(aiGetFloorPosTimer, savefile); - SAVE_TIMER_HANDLE(aiPointReachableAreaNumTimer, savefile); - SAVE_TIMER_HANDLE(aiCanSeeTimer, savefile); - -} - -/* -===================== -idAI::Restore -===================== -*/ -void idAI::Restore( idRestoreGame *savefile ) { - bool restorePhysics; - int i; - int num; - idBounds bounds; - - savefile->ReadInt( travelFlags ); - savefile->ReadInt(lastAreaReevaluationTime); - savefile->ReadInt(maxAreaReevaluationInterval); - savefile->ReadInt(doorRetryTime); - - move.Restore( savefile ); - savedMove.Restore( savefile ); - - // greebo: restore the movestack - moveStack.clear(); - savefile->ReadInt(num); - for (i = 0; i < num; i++) - { - moveStack.push_back(idMoveState()); - moveStack.back().Restore(savefile); - } - - savefile->ReadFloat( kickForce ); - savefile->ReadBool( ignore_obstacles ); - savefile->ReadFloat( blockedRadius ); - savefile->ReadInt( blockedMoveTime ); - savefile->ReadInt( blockedAttackTime ); - - savefile->ReadFloat( ideal_yaw ); - savefile->ReadFloat( current_yaw ); - savefile->ReadFloat( turnRate ); - savefile->ReadFloat( turnVel ); - savefile->ReadFloat( anim_turn_yaw ); - savefile->ReadFloat( anim_turn_amount ); - savefile->ReadFloat( anim_turn_angles ); - savefile->ReadVec3(sitting_turn_pivot); - - savefile->ReadFloat(reachedpos_bbox_expansion); - savefile->ReadFloat(aas_reachability_z_tolerance); - - savefile->ReadStaticObject( physicsObj ); - - savefile->ReadFloat( fly_speed ); - savefile->ReadFloat( fly_bob_strength ); - savefile->ReadFloat( fly_bob_vert ); - savefile->ReadFloat( fly_bob_horz ); - savefile->ReadInt( fly_offset ); - savefile->ReadFloat( fly_seek_scale ); - savefile->ReadFloat( fly_roll_scale ); - savefile->ReadFloat( fly_roll_max ); - savefile->ReadFloat( fly_roll ); - savefile->ReadFloat( fly_pitch_scale ); - savefile->ReadFloat( fly_pitch_max ); - savefile->ReadFloat( fly_pitch ); - - savefile->ReadBool( allowMove ); - savefile->ReadBool( allowHiddenMovement ); - savefile->ReadBool( disableGravity ); - - savefile->ReadBool( lastHitCheckResult ); - savefile->ReadInt( lastHitCheckTime ); - savefile->ReadInt( lastAttackTime ); - savefile->ReadFloat( fire_range ); - savefile->ReadFloat( projectile_height_to_distance_ratio ); - - savefile->ReadInt( num ); - missileLaunchOffset.SetGranularity( 1 ); - missileLaunchOffset.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadVec3( missileLaunchOffset[ i ] ); - } - - savefile->ReadInt(num); - projectileInfo.SetNum(num); - - for (i = 0; i < projectileInfo.Num(); ++i) - { - ProjectileInfo& info = projectileInfo[i]; - - savefile->ReadString(info.defName); - // Resolve projectile def pointers from names - info.def = (info.defName.Length() > 0) ? gameLocal.FindEntityDefDict(info.defName) : NULL; - - // leave clipmodel pointer alone, is already initialised to NULL - savefile->ReadFloat(info.radius); - savefile->ReadFloat(info.speed); - savefile->ReadVec3(info.velocity); - savefile->ReadVec3(info.gravity); - } - - savefile->ReadInt(curProjectileIndex); - - // Active Projectile - savefile->ReadString(activeProjectile.info.defName); - - // Resolve projectile def pointers from names - if (activeProjectile.info.defName.Length() > 0) - { - activeProjectile.info.def = gameLocal.FindEntityDefDict(activeProjectile.info.defName); - } - else - { - activeProjectile.info.def = NULL; - } - - savefile->ReadFloat(activeProjectile.info.radius); - savefile->ReadFloat(activeProjectile.info.speed); - savefile->ReadVec3(activeProjectile.info.velocity); - savefile->ReadVec3(activeProjectile.info.gravity); - activeProjectile.projEnt.Restore(savefile); - - savefile->ReadString( attack ); - - // grayman #2603 - delayed stim list - - savefile->ReadInt(num); - delayedStims.SetNum(num); - for (i = 0 ; i < num ; i++) - { - savefile->ReadInt(delayedStims[i].nextTimeToConsider); - delayedStims[i].stim.Restore(savefile); - } - - savefile->ReadInt( i ); - talk_state = static_cast( i ); - talkTarget.Restore( savefile ); - - savefile->ReadInt( num_cinematics ); - savefile->ReadInt( current_cinematic ); - - savefile->ReadBool( allowJointMod ); - focusEntity.Restore( savefile ); - savefile->ReadVec3( currentFocusPos ); - savefile->ReadInt( focusTime ); - savefile->ReadInt( alignHeadTime ); - savefile->ReadInt( forceAlignHeadTime ); - savefile->ReadAngles( eyeAng ); - savefile->ReadAngles( lookAng ); - savefile->ReadAngles( destLookAng ); - savefile->ReadAngles( lookMin ); - savefile->ReadAngles( lookMax ); - - savefile->ReadInt( num ); - lookJoints.SetGranularity( 1 ); - lookJoints.SetNum( num ); - lookJointAngles.SetGranularity( 1 ); - lookJointAngles.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadJoint( lookJoints[ i ] ); - savefile->ReadAngles( lookJointAngles[ i ] ); - } - - savefile->ReadInt( num ); - lookJointsCombat.SetGranularity( 1 ); - lookJointsCombat.SetNum( num ); - lookJointAnglesCombat.SetGranularity( 1 ); - lookJointAnglesCombat.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadJoint( lookJointsCombat[ i ] ); - savefile->ReadAngles( lookJointAnglesCombat[ i ] ); - } - - savefile->ReadFloat( shrivel_rate ); - savefile->ReadInt( shrivel_start ); - - savefile->ReadInt( num ); - particles.SetNum( num ); - for ( i = 0; i < particles.Num(); i++ ) { - savefile->ReadParticle( particles[i].particle ); - savefile->ReadInt( particles[i].time ); - savefile->ReadJoint( particles[i].joint ); - } - savefile->ReadBool( restartParticles ); - savefile->ReadBool( useBoneAxis ); - - enemy.Restore( savefile ); - savefile->ReadVec3( lastVisibleEnemyPos ); - savefile->ReadVec3( lastVisibleEnemyEyeOffset ); - savefile->ReadVec3( lastVisibleReachableEnemyPos ); - savefile->ReadVec3( lastReachableEnemyPos ); - savefile->ReadBool( enemyReachable ); - savefile->ReadBool( wakeOnFlashlight ); - savefile->ReadInt(lastUpdateEnemyPositionTime); - savefile->ReadInt(lastTimePlayerSeen); // grayman #2887 - savefile->ReadInt(lastTimePlayerLost); // grayman #2887 - - savefile->ReadAngles( eyeMin ); - savefile->ReadAngles( eyeMax ); - - savefile->ReadFloat( eyeVerticalOffset ); - savefile->ReadFloat( eyeHorizontalOffset ); - savefile->ReadFloat( eyeFocusRate ); - savefile->ReadFloat( headFocusRate ); - savefile->ReadInt( focusAlignTime ); - savefile->ReadObject(reinterpret_cast(m_tactileEntity)); // grayman #2345 - savefile->ReadBool(m_canResolveBlock); // grayman #2345 - savefile->ReadBool(m_leftQueue); // grayman #2345 - savefile->ReadBool(m_performRelight); // grayman #2603 - savefile->ReadJoint( flashJointWorld ); - savefile->ReadInt( muzzleFlashEnd ); - - savefile->ReadJoint( focusJoint ); - savefile->ReadJoint( orientationJoint ); - savefile->ReadJoint( flyTiltJoint ); - - // TDM Alerts: - savefile->ReadInt( num ); - m_Acuities.SetNum( num ); - for( i = 0; i < num; i++ ) - { - savefile->ReadFloat( m_Acuities[ i ] ); - } - savefile->ReadFloat(m_oldVisualAcuity); - savefile->ReadFloat( m_AudThreshold ); - savefile->ReadVec3( m_SoundDir ); - savefile->ReadVec3( m_LastSight ); - savefile->ReadFloat( m_AlertLevelThisFrame ); - savefile->ReadInt( m_prevAlertIndex ); - savefile->ReadFloat( m_maxAlertLevel ); - savefile->ReadInt( m_maxAlertIndex); - savefile->ReadFloat(m_lastAlertLevel); - savefile->ReadBool( m_bIgnoreAlerts ); - - m_AlertedByActor.Restore( savefile ); - for (i = 0; i < ai::EAlertTypeCount; i++) - { - savefile->ReadInt(alertTypeWeight[i]); - } - m_TactAlertEnt.Restore( savefile ); - m_AlertGraceActor.Restore( savefile ); - savefile->ReadInt( m_AlertGraceStart ); - savefile->ReadInt( m_AlertGraceTime ); - savefile->ReadFloat( m_AlertGraceThresh ); - savefile->ReadInt( m_AlertGraceCount ); - savefile->ReadInt( m_AlertGraceCountLimit ); - - savefile->ReadInt(num); - m_Messages.Clear(); - for (int i = 0; i < num; i++) - { - ai::CommMessagePtr message(new ai::CommMessage); - message->Restore(savefile); - m_Messages.Append(message); - } - - savefile->ReadBool( restorePhysics ); - - // Set the AAS if the character has the correct gravity vector - idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); - gravity *= g_gravity.GetFloat(); - if ( gravity == gameLocal.GetGravity() ) { - SetAAS(); - } - - savefile->ReadFloat(m_VisDistMax); - - savefile->ReadInt(m_HidingSpotSearchHandle); - m_hidingSpots.Restore(savefile); - - savefile->ReadInt(m_AirCheckTimer); - savefile->ReadBool(m_bCanDrown); - savefile->ReadInt(m_HeadBodyID); - savefile->ReadJoint(m_HeadJointID); - - savefile->ReadBool( m_bHeadCMSwapped ); - // Ishtvan: if the head CM was swapped at save, swap it again - // (I tried to do this more correctly, but the AF itself isn't saving its new clipmodel) - if( m_bHeadCMSwapped ) - { - m_OrigHeadCM = NULL; - m_bHeadCMSwapped = false; - SwapHeadAFCM( true ); - } - - savefile->ReadInt(m_AirTics); - savefile->ReadInt(m_AirTicksMax); - savefile->ReadInt(m_AirCheckInterval); - - savefile->ReadVec3(m_MouthOffset); - savefile->ReadBool(m_bCanBeKnockedOut); - savefile->ReadVec3(m_HeadCenterOffset); - savefile->ReadMat3(m_FOVRot); - savefile->ReadString(m_KoZone); - savefile->ReadInt(m_KoAlertState); - savefile->ReadInt(m_KoAlertImmuneState); - savefile->ReadBool(m_bKoAlertImmune); - savefile->ReadFloat(m_KoDotVert); - savefile->ReadFloat(m_KoDotHoriz); - savefile->ReadFloat(m_KoAlertDotVert); - savefile->ReadFloat(m_KoAlertDotHoriz); - savefile->ReadMat3(m_KoRot); - - savefile->ReadBool(m_bCanBeGassed); // grayman #2468 - savefile->ReadInt( i ); // grayman #2604 - m_koState = static_cast( i ); - savefile->ReadInt(m_earlyThinkCounter); // grayman #2654 - savefile->ReadBool(m_bCanExtricate); // grayman #2603 - savefile->ReadFloat(thresh_1); - savefile->ReadFloat(thresh_2); - savefile->ReadFloat(thresh_3); - savefile->ReadFloat(thresh_4); - savefile->ReadFloat(thresh_5); - - savefile->ReadFloat(m_gracetime_1); - savefile->ReadFloat(m_gracetime_2); - savefile->ReadFloat(m_gracetime_3); - savefile->ReadFloat(m_gracetime_4); - savefile->ReadFloat(m_gracefrac_1); - savefile->ReadFloat(m_gracefrac_2); - savefile->ReadFloat(m_gracefrac_3); - savefile->ReadFloat(m_gracefrac_4); - savefile->ReadInt(m_gracecount_1); - savefile->ReadInt(m_gracecount_2); - savefile->ReadInt(m_gracecount_3); - savefile->ReadInt(m_gracecount_4); - - savefile->ReadFloat(atime1); - savefile->ReadFloat(atime2); - savefile->ReadFloat(atime3); - savefile->ReadFloat(atime4); - savefile->ReadFloat(atime_fleedone); - - savefile->ReadFloat(atime1_fuzzyness); - savefile->ReadFloat(atime2_fuzzyness); - savefile->ReadFloat(atime3_fuzzyness); - savefile->ReadFloat(atime4_fuzzyness); - savefile->ReadFloat(atime_fleedone_fuzzyness); - - savefile->ReadInt(m_timeBetweenHeadTurnChecks); - savefile->ReadFloat(m_headTurnChanceIdle); - savefile->ReadFloat(m_headTurnFactorAlerted); - savefile->ReadFloat(m_headTurnMaxYaw); - savefile->ReadFloat(m_headTurnMaxPitch); - savefile->ReadInt(m_headTurnMinDuration); - savefile->ReadInt(m_headTurnMaxDuration); - - backboneStates.clear(); - savefile->ReadInt(num); - - for (int i = 0; i < num; ++i) - { - int state = 0; - savefile->ReadInt(state); - - std::pair result = backboneStates.insert( - BackboneStateMap::value_type(static_cast(state), idStr()) - ); - - savefile->ReadString(result.first->second); - } - - savefile->ReadInt(m_maxInterleaveThinkFrames); - savefile->ReadFloat(m_minInterleaveThinkDist); - savefile->ReadFloat(m_maxInterleaveThinkDist); - - savefile->ReadInt(m_lastThinkTime); - savefile->ReadInt(m_nextThinkFrame); - - savefile->ReadBool(m_bPushOffPlayer); - - savefile->ReadBool(m_bCanBeFlatFooted); - savefile->ReadBool(m_bFlatFooted); - savefile->ReadInt(m_FlatFootedTimer); - savefile->ReadInt(m_FlatFootedTime); - savefile->ReadInt(m_FlatFootParryNum); - savefile->ReadInt(m_FlatFootParryMax); - savefile->ReadInt(m_FlatFootParryTimer); - savefile->ReadInt(m_FlatFootParryTime); - savefile->ReadFloat(m_MeleeCounterAttChance); - savefile->ReadBool(m_bMeleePredictProximity); - - savefile->ReadBool(m_bCanOperateDoors); - savefile->ReadBool(m_HandlingDoor); - savefile->ReadBool(m_HandlingElevator); - savefile->ReadBool(m_RelightingLight); // grayman #2603 - savefile->ReadBool(m_ExaminingRope); // grayman #2872 - savefile->ReadBool(m_DroppingTorch); // grayman #2603 - savefile->ReadBool(m_RestoreMove); // grayman #2706 - savefile->ReadBool(m_LatchedSearch); // grayman #2603 - - // grayman #2603 - m_dousedLightsSeen.Clear(); - savefile->ReadInt( num ); - m_dousedLightsSeen.SetNum( num ); - for (int i = 0; i < num; i++) - { - m_dousedLightsSeen[i].Restore(savefile); - } - - int size; - savefile->ReadInt(size); - unlockableDoors.clear(); - for (int i = 0; i < size; i++) - { - CBinaryFrobMover* mover; - savefile->ReadObject( reinterpret_cast( mover ) ); - unlockableDoors.insert(mover); - } - - savefile->ReadInt(size); - tactileIgnoreEntities.clear(); - for (int i = 0; i < size; i++) - { - idEntity* tactEnt; - savefile->ReadObject(reinterpret_cast(tactEnt)); - tactileIgnoreEntities.insert(tactEnt); - } - - mind = ai::MindPtr(new ai::Mind(this)); - mind->Restore(savefile); - - // Allocate and install the subsystems - movementSubsystem = ai::MovementSubsystemPtr(new ai::MovementSubsystem(ai::SubsysMovement, this)); - senseSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysSenses, this)); - commSubsystem = ai::CommunicationSubsystemPtr(new ai::CommunicationSubsystem(ai::SubsysCommunication, this)); - actionSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysAction, this)); - - senseSubsystem->Restore(savefile); - movementSubsystem->Restore(savefile); - commSubsystem->Restore(savefile); - actionSubsystem->Restore(savefile); - - SetCombatModel(); - LinkCombat(); - - InitMuzzleFlash(); - - // Link the script variables back to the scriptobject - LinkScriptVariables(); - - if ( restorePhysics ) { - RestorePhysics( &physicsObj ); - } - - RESTORE_TIMER_HANDLE(aiThinkTimer, savefile); - RESTORE_TIMER_HANDLE(aiMindTimer, savefile); - RESTORE_TIMER_HANDLE(aiAnimationTimer, savefile); - RESTORE_TIMER_HANDLE(aiPushWithAFTimer, savefile); - RESTORE_TIMER_HANDLE(aiUpdateEnemyPositionTimer, savefile); - RESTORE_TIMER_HANDLE(aiScriptTimer, savefile); - RESTORE_TIMER_HANDLE(aiAnimMoveTimer, savefile); - RESTORE_TIMER_HANDLE(aiObstacleAvoidanceTimer, savefile); - RESTORE_TIMER_HANDLE(aiPhysicsTimer, savefile); - RESTORE_TIMER_HANDLE(aiGetMovePosTimer, savefile); - RESTORE_TIMER_HANDLE(aiPathToGoalTimer, savefile); - RESTORE_TIMER_HANDLE(aiGetFloorPosTimer, savefile); - RESTORE_TIMER_HANDLE(aiPointReachableAreaNumTimer, savefile); - RESTORE_TIMER_HANDLE(aiCanSeeTimer, savefile); -} - -ai::Subsystem* idAI::GetSubsystem(ai::SubsystemId id) -{ - switch (id) - { - case ai::SubsysSenses: - return senseSubsystem.get(); - case ai::SubsysMovement: - return movementSubsystem.get(); - case ai::SubsysCommunication: - return commSubsystem.get(); - case ai::SubsysAction: - return actionSubsystem.get(); - default: - gameLocal.Error("Request for unknown subsystem %d", static_cast(id)); - return NULL; - }; -} - -/* -===================== -idAI::Spawn -===================== -*/ -void idAI::Spawn( void ) -{ - const char *jointname; - const idKeyValue *kv; - idStr jointName; - idAngles jointScale; - jointHandle_t joint; - idVec3 local_dir; - bool talks; - - aiNode.AddToEnd(gameLocal.spawnedAI); - - // Allocate a new default mind - mind = ai::MindPtr(new ai::Mind(this)); - - // Allocate and install the subsystems - movementSubsystem = ai::MovementSubsystemPtr(new ai::MovementSubsystem(ai::SubsysMovement, this)); - senseSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysSenses, this)); - commSubsystem = ai::CommunicationSubsystemPtr(new ai::CommunicationSubsystem(ai::SubsysCommunication, this)); - actionSubsystem = ai::SubsystemPtr(new ai::Subsystem(ai::SubsysAction, this)); - - if ( !g_monsters.GetBool() ) { - PostEventMS( &EV_Remove, 0 ); - return; - } - - spawnArgs.GetInt( "team", "1", team ); - spawnArgs.GetInt( "rank", "0", rank ); - spawnArgs.GetInt( "fly_offset", "0", fly_offset ); - spawnArgs.GetFloat( "fly_speed", "100", fly_speed ); - spawnArgs.GetFloat( "fly_bob_strength", "50", fly_bob_strength ); - spawnArgs.GetFloat( "fly_bob_vert", "2", fly_bob_vert ); - spawnArgs.GetFloat( "fly_bob_horz", "2.7", fly_bob_horz ); - spawnArgs.GetFloat( "fly_seek_scale", "4", fly_seek_scale ); - spawnArgs.GetFloat( "fly_roll_scale", "90", fly_roll_scale ); - spawnArgs.GetFloat( "fly_roll_max", "60", fly_roll_max ); - spawnArgs.GetFloat( "fly_pitch_scale", "45", fly_pitch_scale ); - spawnArgs.GetFloat( "fly_pitch_max", "30", fly_pitch_max ); - - maxAreaReevaluationInterval = spawnArgs.GetInt( "max_area_reevaluation_interval", "2000"); - doorRetryTime = SEC2MS(spawnArgs.GetInt( "door_retry_time", "120")); - - spawnArgs.GetFloat( "fire_range", "0", fire_range ); - spawnArgs.GetFloat( "projectile_height_to_distance_ratio", "1", projectile_height_to_distance_ratio ); - - spawnArgs.GetFloat( "turn_rate", "360", turnRate ); - - spawnArgs.GetVector("sitting_turn_pivot", "-20 0 0", sitting_turn_pivot); - - reachedpos_bbox_expansion = spawnArgs.GetFloat("reachedpos_bbox_expansion", "0"); - aas_reachability_z_tolerance = spawnArgs.GetFloat("aas_reachability_z_tolerance", "75"); - - spawnArgs.GetBool( "talks", "0", talks ); - - //// DarkMod: Alert level parameters - // The default values of these spawnargs are normally set in tdm_ai_base.def, so the default values - // here are somewhat superfluous. It's better than having defaults of 0 here though. - spawnArgs.GetFloat( "alert_thresh1", "1.5", thresh_1 ); - spawnArgs.GetFloat( "alert_thresh2", "6", thresh_2 ); - spawnArgs.GetFloat( "alert_thresh3", "8", thresh_3 ); - spawnArgs.GetFloat( "alert_thresh4", "18", thresh_4 ); - spawnArgs.GetFloat( "alert_thresh5", "23", thresh_5 ); - // Grace period info for each alert level - spawnArgs.GetFloat( "alert_gracetime1", "2", m_gracetime_1 ); - spawnArgs.GetFloat( "alert_gracetime2", "2", m_gracetime_2 ); - spawnArgs.GetFloat( "alert_gracetime3", "3.5", m_gracetime_3 ); - spawnArgs.GetFloat( "alert_gracetime4", "2", m_gracetime_4 ); - spawnArgs.GetFloat( "alert_gracefrac1", "1.2", m_gracefrac_1 ); - spawnArgs.GetFloat( "alert_gracefrac2", "1.2", m_gracefrac_2 ); - spawnArgs.GetFloat( "alert_gracefrac3", "1.2", m_gracefrac_3 ); - spawnArgs.GetFloat( "alert_gracefrac4", "1.0", m_gracefrac_4 ); - spawnArgs.GetInt ( "alert_gracecount1", "5", m_gracecount_1 ); - spawnArgs.GetInt ( "alert_gracecount2", "5", m_gracecount_2 ); - spawnArgs.GetInt ( "alert_gracecount3", "5", m_gracecount_3 ); - spawnArgs.GetInt ( "alert_gracecount4", "4", m_gracecount_4 ); - // De-alert times for each alert level - spawnArgs.GetFloat( "alert_time1", "4", atime1 ); - spawnArgs.GetFloat( "alert_time2", "6", atime2 ); - spawnArgs.GetFloat( "alert_time3", "30", atime3 ); - spawnArgs.GetFloat( "alert_time4", "120", atime4 ); - spawnArgs.GetFloat( "alert_time1_fuzzyness", "4", atime1_fuzzyness ); - spawnArgs.GetFloat( "alert_time2_fuzzyness", "6", atime2_fuzzyness ); - spawnArgs.GetFloat( "alert_time3_fuzzyness", "30", atime3_fuzzyness ); - spawnArgs.GetFloat( "alert_time4_fuzzyness", "120", atime4_fuzzyness ); - - spawnArgs.GetFloat( "alert_time_fleedone", "60", atime_fleedone ); - spawnArgs.GetFloat( "alert_time_fleedone_fuzzyness", "10", atime_fleedone_fuzzyness ); - - // State setup - backboneStates.clear(); - - backboneStates[ai::ERelaxed] = spawnArgs.GetString("state_name_0", STATE_IDLE); - backboneStates[ai::EObservant] = spawnArgs.GetString("state_name_1", STATE_OBSERVANT); - backboneStates[ai::ESuspicious] = spawnArgs.GetString("state_name_2", STATE_SUSPICIOUS); - backboneStates[ai::EInvestigating] = spawnArgs.GetString("state_name_3", STATE_SEARCHING); - backboneStates[ai::EAgitatedSearching] = spawnArgs.GetString("state_name_4", STATE_AGITATED_SEARCHING); - backboneStates[ai::ECombat] = spawnArgs.GetString("state_name_5", STATE_COMBAT); - - spawnArgs.GetInt( "max_interleave_think_frames", "12", m_maxInterleaveThinkFrames ); - spawnArgs.GetFloat( "min_interleave_think_dist", "1000", m_minInterleaveThinkDist); - spawnArgs.GetFloat( "max_interleave_think_dist", "3000", m_maxInterleaveThinkDist); - - spawnArgs.GetBool( "ignore_alerts", "0", m_bIgnoreAlerts ); - - if (spawnArgs.GetBool("canOperateElevators", "0")) - { - travelFlags |= TFL_ELEVATOR; - } - - float headTurnSec; - spawnArgs.GetFloat( "headturn_delay_min", "3", headTurnSec); - m_timeBetweenHeadTurnChecks = SEC2MS(headTurnSec); - - spawnArgs.GetFloat( "headturn_chance_idle", "0.1", m_headTurnChanceIdle); - spawnArgs.GetFloat( "headturn_factor_alerted", "2", m_headTurnFactorAlerted); - spawnArgs.GetFloat( "headturn_yaw", "60", m_headTurnMaxYaw); - spawnArgs.GetFloat( "headturn_pitch", "40", m_headTurnMaxPitch); - - spawnArgs.GetFloat( "headturn_duration_min", "1", headTurnSec); - m_headTurnMinDuration = SEC2MS(headTurnSec); - - spawnArgs.GetFloat( "headturn_duration_max", "3", headTurnSec); - m_headTurnMaxDuration = SEC2MS(headTurnSec); - - alertTypeWeight[ai::EAlertTypeEnemy] = 50; - alertTypeWeight[ai::EAlertTypeDamage] = 45; - alertTypeWeight[ai::EAlertTypeDeadPerson] = 41; - alertTypeWeight[ai::EAlertTypeUnconsciousPerson] = 40; - alertTypeWeight[ai::EAlertTypeWeapon] = 35; - alertTypeWeight[ai::EAlertTypeRope] = 34; // grayman #2872 - alertTypeWeight[ai::EAlertTypeSuspiciousItem] = 33; // grayman #1327 - alertTypeWeight[ai::EAlertTypeBlood] = 30; - alertTypeWeight[ai::EAlertTypeBrokenItem] = 26; - alertTypeWeight[ai::EAlertTypeMissingItem] = 25; - alertTypeWeight[ai::EAlertTypeDoor] = 20; - alertTypeWeight[ai::EAlertTypeLightSource] = 10; - alertTypeWeight[ai::EAlertTypeSuspicious] = 5; - alertTypeWeight[ai::EAlertTypeNone] = 0; - - // DarkMod: Get the movement type audible volumes from the spawnargs - spawnArgs.GetFloat( "stepvol_walk", "0", m_stepvol_walk ); - spawnArgs.GetFloat( "stepvol_run", "0", m_stepvol_run ); - spawnArgs.GetFloat( "stepvol_creep", "0", m_stepvol_creep ); - - spawnArgs.GetFloat( "stepvol_crouch_walk", "0", m_stepvol_crouch_walk ); - spawnArgs.GetFloat( "stepvol_run", "0", m_stepvol_crouch_run ); - spawnArgs.GetFloat( "stepvol_creep", "0", m_stepvol_crouch_creep ); - - if ( spawnArgs.GetString( "npc_name", NULL ) != NULL ) { - if ( talks ) { - talk_state = TALK_OK; - } else { - talk_state = TALK_BUSY; - } - } else { - talk_state = TALK_NEVER; - } - - spawnArgs.GetBool( "animate_z", "0", disableGravity ); - spawnArgs.GetFloat( "kick_force", "60", kickForce ); // grayman #2568 - use default Doom 3 value - spawnArgs.GetBool( "ignore_obstacles", "0", ignore_obstacles ); - spawnArgs.GetFloat( "blockedRadius", "-1", blockedRadius ); - spawnArgs.GetInt( "blockedMoveTime", "750", blockedMoveTime ); - spawnArgs.GetInt( "blockedAttackTime", "750", blockedAttackTime ); - - // DarkMod: Set the AI acuities from the spawnargs. - - m_Acuities.Clear(); - for( int ind=0; ind < g_Global.m_AcuityNames.Num(); ind++) - { - float tempFloat = spawnArgs.GetFloat( va("acuity_%s", g_Global.m_AcuityNames[ind].c_str()), "100" ); - // angua: divide by 100 to transform percent into fractions - tempFloat *= 0.01f; - m_Acuities.Append( tempFloat ); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Acuities Array: index %d, name %s, value %f\r", ind, g_Global.m_AcuityNames[ind].c_str(), m_Acuities[ind]); - } - m_oldVisualAcuity = GetAcuity("vis"); // Tels fix #2408 - - spawnArgs.GetFloat("alert_aud_thresh", va("%f",gameLocal.m_sndProp->m_SndGlobals.DefaultThreshold), m_AudThreshold ); - - spawnArgs.GetInt( "num_cinematics", "0", num_cinematics ); - current_cinematic = 0; - - LinkScriptVariables(); - - /** - * Initialize Darkmod AI vars - **/ - AI_ALERTED = false; - AI_CROUCH = false; - AI_RUN = false; - AI_CREEP = false; - - AI_LAY_DOWN_LEFT = true; - - AI_HEARDSOUND = false; - AI_VISALERT = false; - AI_TACTALERT = false; - - fl.takedamage = !spawnArgs.GetBool( "noDamage" ); - enemy = NULL; - allowMove = true; - allowHiddenMovement = false; - - animator.RemoveOriginOffset( true ); - - // create combat collision hull for exact collision detection - SetCombatModel(); - - lookMin = spawnArgs.GetAngles( "look_min", "-80 -75 0" ); - lookMax = spawnArgs.GetAngles( "look_max", "80 75 0" ); - - lookJoints.SetGranularity( 1 ); - lookJointAngles.SetGranularity( 1 ); - kv = spawnArgs.MatchPrefix( "look_joint", NULL ); - while( kv ) { - jointName = kv->GetKey(); - jointName.StripLeadingOnce( "look_joint " ); - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Warning( "Unknown look_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); - } else { - jointScale = spawnArgs.GetAngles( kv->GetKey(), "0 0 0" ); - jointScale.roll = 0.0f; - - // if no scale on any component, then don't bother adding it. this may be done to - // zero out rotation from an inherited entitydef. - if ( jointScale != ang_zero ) { - lookJoints.Append( joint ); - lookJointAngles.Append( jointScale ); - } - } - kv = spawnArgs.MatchPrefix( "look_joint", kv ); - } - - lookJointsCombat.SetGranularity( 1 ); - lookJointAnglesCombat.SetGranularity( 1 ); - kv = spawnArgs.MatchPrefix( "combat_look_joint", NULL ); - while( kv ) { - jointName = kv->GetKey(); - jointName.StripLeadingOnce( "combat_look_joint " ); - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Warning( "Unknown combat_look_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); - } else { - jointScale = spawnArgs.GetAngles( kv->GetKey(), "0 0 0" ); - jointScale.roll = 0.0f; - - // if no scale on any component, then don't bother adding it. this may be done to - // zero out rotation from an inherited entitydef. - if ( jointScale != ang_zero ) { - lookJointsCombat.Append( joint ); - lookJointAnglesCombat.Append( jointScale ); - } - } - kv = spawnArgs.MatchPrefix( "combat_look_joint", kv ); - } - - // calculate joint positions on attack frames so we can do proper "can hit" tests - CalculateAttackOffsets(); - - eyeMin = spawnArgs.GetAngles( "eye_turn_min", "-10 -30 0" ); - eyeMax = spawnArgs.GetAngles( "eye_turn_max", "10 30 0" ); - eyeVerticalOffset = spawnArgs.GetFloat( "eye_verticle_offset", "5" ); - eyeHorizontalOffset = spawnArgs.GetFloat( "eye_horizontal_offset", "-8" ); - eyeFocusRate = spawnArgs.GetFloat( "eye_focus_rate", "0.5" ); - headFocusRate = spawnArgs.GetFloat( "head_focus_rate", "0.1" ); - focusAlignTime = SEC2MS( spawnArgs.GetFloat( "focus_align_time", "1" ) ); - - // DarkMod: State of mind, allow the FM author to set initial values - AI_AlertLevel = spawnArgs.GetFloat( "alert_initial", "0" ); - - flashJointWorld = animator.GetJointHandle( "flash" ); - - if ( head.GetEntity() ) - { - idAnimator *headAnimator = head.GetEntity()->GetAnimator(); - - jointname = spawnArgs.GetString( "bone_focus" ); - if ( *jointname ) - { - focusJoint = headAnimator->GetJointHandle( jointname ); - if ( focusJoint == INVALID_JOINT ) - { - gameLocal.Warning( "Joint '%s' not found on head on '%s'", jointname, name.c_str() ); - } - } - } else - { - jointname = spawnArgs.GetString( "bone_focus" ); - if ( *jointname ) - { - focusJoint = animator.GetJointHandle( jointname ); - if ( focusJoint == INVALID_JOINT ) - { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); - } - } - } - - jointname = spawnArgs.GetString( "bone_orientation" ); - if ( *jointname ) { - orientationJoint = animator.GetJointHandle( jointname ); - if ( orientationJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); - } - } - - jointname = spawnArgs.GetString( "bone_flytilt" ); - if ( *jointname ) { - flyTiltJoint = animator.GetJointHandle( jointname ); - if ( flyTiltJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); - } - } - - InitMuzzleFlash(); - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - - physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) ); - kickForce = 2*physicsObj.GetMass(); // grayman #2568 - equation arrived at empirically - - physicsObj.SetStepUpIncrease(spawnArgs.GetFloat("step_up_increase", "0")); - - if ( spawnArgs.GetBool( "big_monster" ) ) { - physicsObj.SetContents( 0 ); - physicsObj.SetClipMask( MASK_MONSTERSOLID & ~CONTENTS_BODY ); - } else { - if ( use_combat_bbox ) { - physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); - } else { - physicsObj.SetContents( CONTENTS_BODY ); - } - physicsObj.SetClipMask( MASK_MONSTERSOLID ); - } - -// SR CONTENTS_RESPONSE fix: - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - // move up to make sure the monster is at least an epsilon above the floor - physicsObj.SetOrigin( GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - - if ( num_cinematics ) { - physicsObj.SetGravity( vec3_origin ); - } else { - idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); - gravity *= g_gravity.GetFloat(); - physicsObj.SetGravity( gravity ); - } - - SetPhysics( &physicsObj ); - - physicsObj.GetGravityAxis().ProjectVector( viewAxis[ 0 ], local_dir ); - current_yaw = local_dir.ToYaw(); - ideal_yaw = idMath::AngleNormalize180( current_yaw ); - - move.blockTime = 0; - - SetAAS(); - - InitProjectileInfo(); - - delayedStims.Clear(); // grayman #2603 - - particles.Clear(); - restartParticles = true; - useBoneAxis = spawnArgs.GetBool( "useBoneAxis" ); - SpawnParticles( "smokeParticleSystem" ); - - if ( num_cinematics || spawnArgs.GetBool( "hide" ) || spawnArgs.GetBool( "teleport" ) || spawnArgs.GetBool( "trigger_anim" ) ) { - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.GetClipModel()->Unlink(); - Hide(); - } else { - // play a looping ambient sound if we have one - StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); - } - - if ( health <= 0 ) { - gameLocal.Warning( "entity '%s' doesn't have health set", name.c_str() ); - health = 1; - } - - // Dark Mod: set up drowning - m_MouthOffset = spawnArgs.GetVector("mouth_offset"); - // set up drowning timer (add a random bit to make it asynchronous w/ respect to other AI) - m_bCanDrown = spawnArgs.GetBool( "can_drown", "1" ); - m_AirCheckTimer = gameLocal.time + gameLocal.random.RandomInt( 8000 ); - m_AirTicksMax = spawnArgs.GetInt( "max_air_tics", "5" ); - m_AirTics = m_AirTicksMax; - m_AirCheckInterval = static_cast(1000.0f * spawnArgs.GetFloat( "air_check_interval", "4.0" )); - // end drowning setup - - m_bPushOffPlayer = spawnArgs.GetBool("push_off_player", "1"); - - m_bCanBeFlatFooted = spawnArgs.GetBool("can_be_flatfooted", "1"); - m_FlatFootedTime = spawnArgs.GetInt("flatfooted_time"); - m_FlatFootParryMax = spawnArgs.GetInt("flatfoot_parry_num"); - m_FlatFootParryTime = spawnArgs.GetInt("flatfoot_parry_time"); - // Convert percent chance to fractional - m_MeleeCounterAttChance = spawnArgs.GetInt("melee_chance_to_counter") / 100.0f; - m_bMeleePredictProximity = spawnArgs.GetBool("melee_predicts_proximity"); - - if (spawnArgs.GetBool("melee_attacks_enabled_at_spawn_time", "0")) - { - SetAttackFlag(COMBAT_MELEE, true); - } - - if (spawnArgs.GetBool("ranged_attacks_enabled_at_spawn_time", "0")) - { - SetAttackFlag(COMBAT_RANGED, true); - } - - m_bCanOperateDoors = spawnArgs.GetBool("canOperateDoors", "0"); - m_HandlingDoor = false; - m_RestoreMove = false; // grayman #2706 - m_LatchedSearch = false; // grayman #2603 - m_dousedLightsSeen.Clear(); // grayman #2603 - - m_HandlingElevator = false; - m_RelightingLight = false; // grayman #2603 - m_ExaminingRope = false; // grayman #2872 - m_DroppingTorch = false; // grayman #2603 - - // =============== Set up KOing and FOV ============== - const char *HeadJointName = spawnArgs.GetString("head_jointname", "Head"); - - m_HeadJointID = animator.GetJointHandle(HeadJointName); - if( m_HeadJointID == INVALID_JOINT ) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Invalid head joint for joint %s on AI %s \r", HeadJointName, name.c_str()); - m_HeadBodyID = 0; - } - else - { - m_HeadBodyID = BodyForJoint(m_HeadJointID); - } - - if( head.GetEntity() ) - { - CopyHeadKOInfo(); - } - - ParseKnockoutInfo(); - - // ================== End KO setup ==================== - - // Sneak attack setup - const char *tempc1; - tempc1 = spawnArgs.GetString("sneak_attack_alert_state"); - m_SneakAttackThresh = spawnArgs.GetFloat( va("alert_thresh%s", tempc1), va("%f",idMath::INFINITY) ); - m_SneakAttackMult = spawnArgs.GetFloat( "sneak_attack_mult", "1.0" ); - - BecomeActive( TH_THINK ); - - // init the move variables - StopMove( MOVE_STATUS_DONE ); - - // Schedule a post-spawn event to parse the rest of the spawnargs - PostEventMS( &EV_PostSpawn, 1 ); - - m_lastThinkTime = gameLocal.time; - - CREATE_TIMER(aiThinkTimer, name, "Think"); - CREATE_TIMER(aiMindTimer, name, "Mind"); - CREATE_TIMER(aiAnimationTimer, name, "Animation"); - CREATE_TIMER(aiPushWithAFTimer, name, "PushWithAF"); - CREATE_TIMER(aiUpdateEnemyPositionTimer, name, "UpdateEnemyPosition"); - CREATE_TIMER(aiScriptTimer, name, "UpdateScript"); - CREATE_TIMER(aiAnimMoveTimer, name, "AnimMove"); - CREATE_TIMER(aiObstacleAvoidanceTimer, name, "ObstacleAvoidance"); - CREATE_TIMER(aiPhysicsTimer, name, "RunPhysics"); - CREATE_TIMER(aiGetMovePosTimer, name, "GetMovePos"); - CREATE_TIMER(aiPathToGoalTimer, name, "PathToGoal"); - CREATE_TIMER(aiGetFloorPosTimer, name, "GetFloorPos"); - CREATE_TIMER(aiPointReachableAreaNumTimer, name, "PointReachableAreaNum"); - CREATE_TIMER(aiCanSeeTimer, name, "CanSee"); - - m_pathRank = rank; // grayman #2345 - rank for path-finding - - m_bCanBeGassed = !(spawnArgs.GetBool( "gas_immune", "0" )); // grayman #2468 -} - -void idAI::InitProjectileInfo() -{ - activeProjectile.projEnt = NULL; - - // greebo: Pre-cache the properties of each projectile def. - for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_projectile"); kv != NULL; kv = spawnArgs.MatchPrefix("def_projectile", kv)) - { - const idStr& projectileName = kv->GetValue(); - - if (projectileName.Length() == 0) continue; - - ProjectileInfo& info = projectileInfo.Alloc(); - - // Pass to specialised routine - InitProjectileInfoFromDict(info, projectileName); - } - - // Roll a random projectile for starters - curProjectileIndex = gameLocal.random.RandomInt(projectileInfo.Num()); -} - -void idAI::InitProjectileInfoFromDict(idAI::ProjectileInfo& info, const char* entityDef) const -{ - const idDict* dict = gameLocal.FindEntityDefDict(entityDef); - - if (dict == NULL) - { - gameLocal.Error("Cannot load projectile info for entityDef %s", entityDef); - } - - InitProjectileInfoFromDict(info, dict); -} - -void idAI::InitProjectileInfoFromDict(idAI::ProjectileInfo& info, const idDict* dict) const -{ - assert(dict != NULL); - - info.defName = dict->GetString("classname"); - info.def = dict; - - // Create a projectile of this specific type to retrieve its properties - idProjectile* proj = SpawnProjectile(info.def); - - info.radius = proj->GetPhysics()->GetClipModel()->GetBounds().GetRadius(); - info.velocity = idProjectile::GetVelocity(info.def); - info.gravity = idProjectile::GetGravity(info.def); - info.speed = info.velocity.Length(); - - // dispose after this short use - delete proj; -} - -/* -=================== -idAI::InitMuzzleFlash -=================== -*/ -void idAI::InitMuzzleFlash( void ) { - const char *shader; - idVec3 flashColor; - - spawnArgs.GetString( "mtr_flashShader", "muzzleflash", &shader ); - spawnArgs.GetVector( "flashColor", "0 0 0", flashColor ); - float flashRadius = spawnArgs.GetFloat( "flashRadius" ); - flashTime = SEC2MS( spawnArgs.GetFloat( "flashTime", "0.25" ) ); - - memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); - - worldMuzzleFlash.pointLight = true; - worldMuzzleFlash.shader = declManager->FindMaterial( shader, false ); - worldMuzzleFlash.shaderParms[ SHADERPARM_RED ] = flashColor[0]; - worldMuzzleFlash.shaderParms[ SHADERPARM_GREEN ] = flashColor[1]; - worldMuzzleFlash.shaderParms[ SHADERPARM_BLUE ] = flashColor[2]; - worldMuzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = 1.0f; - worldMuzzleFlash.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; - worldMuzzleFlash.lightRadius[0] = flashRadius; - worldMuzzleFlash.lightRadius[1] = flashRadius; - worldMuzzleFlash.lightRadius[2] = flashRadius; - - worldMuzzleFlashHandle = -1; -} - -/* -=================== -idAI::List_f -=================== -*/ -void idAI::List_f( const idCmdArgs &args ) { - int e; - idAI *check; - int count; - const char *statename; - - count = 0; - - gameLocal.Printf( "%-4s %-20s %s\n", " Num", "EntityDef", "Name" ); - gameLocal.Printf( "------------------------------------------------\n" ); - for( e = 0; e < MAX_GENTITIES; e++ ) { - check = static_cast(gameLocal.entities[ e ]); - if ( !check || !check->IsType( idAI::Type ) ) { - continue; - } - - if ( check->state ) { - statename = check->state->Name(); - } else { - statename = "NULL state"; - } - - gameLocal.Printf( "%4i: %-20s %-20s %s move: %d\n", e, check->GetEntityDefName(), check->name.c_str(), statename, check->allowMove ); - count++; - } - - gameLocal.Printf( "...%d monsters\n", count ); -} - -/* -================ -idAI::DormantBegin - -called when entity becomes dormant -================ -*/ -void idAI::DormantBegin( void ) { - // since dormant happens on a timer, we wont get to update particles to - // hidden through the think loop, but we need to hide them though. - if ( particles.Num() ) { - for ( int i = 0; i < particles.Num(); i++ ) { - particles[i].time = 0; - } - } - - if ( enemyNode.InList() ) { - // remove ourselves from the enemy's enemylist - enemyNode.Remove(); - } - idActor::DormantBegin(); -} - -/* -================ -idAI::DormantEnd - -called when entity wakes from being dormant -================ -*/ -void idAI::DormantEnd( void ) { - if ( enemy.GetEntity() && !enemyNode.InList() ) { - // let our enemy know we're back on the trail - enemyNode.AddToEnd( enemy.GetEntity()->enemyList ); - } - - if ( particles.Num() ) { - for ( int i = 0; i < particles.Num(); i++ ) { - particles[i].time = gameLocal.time; - } - } - - idActor::DormantEnd(); - m_lastThinkTime = gameLocal.time; -} - -/* -===================== -idAI::Think -===================== -*/ -void idAI::Think( void ) -{ - START_SCOPED_TIMING(aiThinkTimer, scopedThinkTimer); - if (cv_ai_opt_nothink.GetBool()) - { - return; // Thinking is disabled. - } - - // Interleaved thinking - if (!ThinkingIsAllowed()) - { - return; - } - - SetNextThinkFrame(); - - // if we are completely closed off from the player, don't do anything at all - // angua: only go dormant while in idle - // grayman #2536 - move alert check up in front - if (AI_AlertIndex < 1) - { - bool outsidePVS = CheckDormant(); - if (outsidePVS && cv_ai_opt_disable.GetBool()) - { - return; - } - } - - // grayman #2536 - if dormant and alert index > 0, wake up - - if ((AI_AlertIndex > 0) && fl.isDormant) - { - dormantStart = 0; - fl.hasAwakened = true; - fl.isDormant = false; - DormantEnd(); - } - - // save old origin and velocity for crashlanding - idVec3 oldOrigin = physicsObj.GetOrigin(); - idVec3 oldVelocity = physicsObj.GetLinearVelocity(); - - if (thinkFlags & TH_THINK) - { - // clear out the enemy when he dies - idActor* enemyEnt = enemy.GetEntity(); - if (enemyEnt != NULL) - { - if (enemyEnt->health <= 0) - { - EnemyDead(); - } - } - - // Calculate the new view axis based on the turning settings - current_yaw += deltaViewAngles.yaw; - ideal_yaw = idMath::AngleNormalize180(ideal_yaw + deltaViewAngles.yaw); - deltaViewAngles.Zero(); - viewAxis = idAngles(0, current_yaw, 0).ToMat3(); - - // TDM: Fake lipsync - if (m_lipSyncActive && !cv_ai_opt_nolipsync.GetBool() && GetSoundEmitter()) - { - if (gameLocal.time < m_lipSyncEndTimer && head.GetEntity() != NULL) - { - // greebo: Get the number of frames from the head animator - int numFrames = head.GetEntity()->GetAnimator()->NumFrames(m_lipSyncAnim); - - int frame = static_cast(numFrames * idMath::Sqrt16(GetSoundEmitter()->CurrentAmplitude())); - frame = idMath::ClampInt(0, numFrames, frame); - headAnim.SetFrame(m_lipSyncAnim, frame); - } - else - { - // We're done; stop the animation - StopLipSync(); - } - } - - // Check for tactile alert due to AI movement - CheckTactile(); - - if (health > 0) // grayman #1488 - only do this if you're still alive - { - UpdateAir(); // Check air ticks (is interleaved and not checked each frame) - } - - if (num_cinematics > 0) - { - // Active cinematics - if ( !IsHidden() && torsoAnim.AnimDone( 0 ) ) { - PlayCinematic(); - } - RunPhysics(); - } - else if (!allowHiddenMovement && IsHidden()) - { - // hidden monsters - UpdateScript(); - } - else - { - // clear the ik before we do anything else so the skeleton doesn't get updated twice - walkIK.ClearJointMods(); - - // Update moves, depending on move type - switch (move.moveType) - { - case MOVETYPE_DEAD : - // dead monsters - UpdateScript(); - DeadMove(); - break; - - case MOVETYPE_FLY : - // flying monsters - UpdateEnemyPosition(); - UpdateScript(); - FlyMove(); - CheckBlink(); - break; - - case MOVETYPE_STATIC : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - StaticMove(); - CheckBlink(); - break; - - case MOVETYPE_ANIM : - // animation based movement - UpdateEnemyPosition(); - UpdateScript(); - if (!cv_ai_opt_noanims.GetBool()) - { - AnimMove(); - } - CheckBlink(); - break; - - case MOVETYPE_SLIDE : - // velocity based movement - UpdateEnemyPosition(); - UpdateScript(); - SlideMove(); - CheckBlink(); - break; - - case MOVETYPE_SIT : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving not allowed, turning around sitting pivot - SittingMove(); - CheckBlink(); - break; - - case MOVETYPE_SIT_DOWN : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving and turning not allowed - NoTurnMove(); - CheckBlink(); - break; - - case MOVETYPE_SLEEP : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving and turning not allowed - NoTurnMove(); - break; - - case MOVETYPE_LAY_DOWN : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving and turning not allowed - LayDownMove(); - break; - - case MOVETYPE_GET_UP : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving not allowed - SittingMove(); - CheckBlink(); - break; - - case MOVETYPE_GET_UP_FROM_LYING : - // static monsters - UpdateEnemyPosition(); - UpdateScript(); - // moving and turning not allowed - LayDownMove(); - break; - - - default: - break; - } - } - - if (!cv_ai_opt_nomind.GetBool()) - { - // greebo: We always rely on having a mind - assert(mind); - START_SCOPED_TIMING(aiMindTimer, scopedMindTimer); - - // Let the mind do the thinking (after the move updates) - mind->Think(); - } - - // Clear DarkMod per frame vars now that the mind had time to think - AI_ALERTED = false; - m_AlertLevelThisFrame = 0; - m_AlertedByActor = NULL; - m_tactileEntity = NULL; // grayman #2345 - - // clear pain flag so that we receive any damage between now and the next time we run the script - AI_PAIN = false; - AI_SPECIAL_DAMAGE = 0; - AI_PUSHED = false; - } - else if (thinkFlags & TH_PHYSICS) - { - // Thinking not allowed, but physics are still enabled - RunPhysics(); - } - - if (m_bAFPushMoveables && !movementSubsystem->IsWaitingNonSolid()) // grayman #2345 - if you're waiting for someone to go by, you're non-solid, so you can't push anything - { - START_SCOPED_TIMING(aiPushWithAFTimer, scopedPushWithAFTimer) - PushWithAF(); - } - - if (fl.hidden && allowHiddenMovement) - { - // UpdateAnimation won't call frame commands when hidden, so call them here when we allow hidden movement - animator.ServiceAnims( gameLocal.previousTime, gameLocal.time ); - } - - UpdateMuzzleFlash(); - if (!cv_ai_opt_noanims.GetBool()) - { - START_SCOPED_TIMING(aiAnimationTimer, scopedAnimationTimer) - UpdateAnimation(); - } - UpdateParticles(); - if (!cv_ai_opt_nopresent.GetBool()) - { - Present(); - } - UpdateDamageEffects(); - LinkCombat(); - - if (health > 0) - { - idActor::CrashLand( physicsObj, oldOrigin, oldVelocity ); - } - - m_lastThinkTime = gameLocal.time; - - // Check the CVARs and print debug info, if appropriate - ShowDebugInfo(); -} - -/* -===================== -idAI::ThinkingIsAllowed -===================== -*/ -bool idAI::ThinkingIsAllowed() -{ - int frameNum = gameLocal.framenum; - if (frameNum < m_nextThinkFrame) - { - // Ragdolls think every frame to avoid physics weirdness. - if ( ( health <= 0 ) || IsKnockedOut() ) // grayman #2840 - you're also a ragdoll if you're KO'ed - { - return true; - } - - // angua: AI think every frame while sitting/laying down and getting up - // otherwise, the AI might end up in a different sleeping position - if (move.moveType == MOVETYPE_SIT_DOWN - || move.moveType == MOVETYPE_LAY_DOWN - || move.moveType == MOVETYPE_GET_UP - || move.moveType == MOVETYPE_GET_UP_FROM_LYING) - { - return true; - } - - // skips PVS check, AI will also do interleaved thinking when in player view. - bool skipPVScheck = cv_ai_opt_interleavethinkskippvscheck.GetBool(); - if (skipPVScheck) - { - return false; - } - - // PVS check: let the AI think every frame as long as the player sees them. - bool inPVS = gameLocal.InPlayerPVS(this); - if (!inPVS) - { - return false; - } - } - return true; -} - - - -/* -===================== -idAI::SetNextThinkFrame -===================== -*/ -void idAI::SetNextThinkFrame() -{ - int frameNum = gameLocal.framenum; - int thinkFrame = GetThinkInterleave(); - int thinkDelta = 1; - - if (thinkFrame > 1) - { - // Let them think for the first few frames to initialize state and tasks - if (m_earlyThinkCounter <= 0) // grayman #2654 - keep a separate counter - { - // grayman #2414 - think more often if - // - // * working on a door-handling task - // * nearing a goal position - // * handling an elevator - // - // and, for #2345 - // - // * when resolving a block - - bool thinkMore = false; - thinkDelta = thinkFrame; - ai::Memory& memory = GetMemory(); - CFrobDoor *door = memory.doorRelated.currentDoor.GetEntity(); - - if (door) - { - idVec3 origin = GetPhysics()->GetOrigin(); - idVec3 doorOrigin = door->GetPhysics()->GetOrigin(); - float distance = (doorOrigin - origin).LengthFast(); - - if (distance <= TEMP_THINK_DISTANCE) - { - thinkMore = true; // avoid obstruction & damage - } - } - else if (m_HandlingElevator) - { - thinkMore = true; // avoid death - } - else if ((move.moveCommand == MOVE_TO_POSITION) && (move.moveStatus == MOVE_STATUS_MOVING)) - { - idVec3 origin = GetPhysics()->GetOrigin(); - float distance = (move.moveDest - origin).LengthFast(); - - if (distance <= TEMP_THINK_FACTOR*thinkFrame) - { - thinkMore = true; // avoid confusion and becoming stuck - } - } - else if (!movementSubsystem->IsWaiting() && !movementSubsystem->IsNotBlocked()) - { - thinkMore = true; // avoid chaos - } - - if (thinkMore) - { - thinkDelta = (thinkFrame < TEMP_THINK_INTERLEAVE ? thinkFrame : TEMP_THINK_INTERLEAVE); - } - } - else - { - m_earlyThinkCounter--; // grayman #2654 - } - } - - m_nextThinkFrame = frameNum + thinkDelta; -} - -/* -===================== -idAI::GetThinkInterleave -===================== -*/ -int idAI::GetThinkInterleave() const // grayman 2414 - add 'const' -{ - int maxFrames = m_maxInterleaveThinkFrames; - if (cv_ai_opt_interleavethinkframes.GetInteger() > 0) - { - maxFrames = cv_ai_opt_interleavethinkframes.GetInteger(); - } - - if (maxFrames == 0) - { - return 0; - } - - float minDist = m_minInterleaveThinkDist; - float maxDist = m_maxInterleaveThinkDist; - if (cv_ai_opt_interleavethinkmindist.GetFloat() > 0) - { - minDist = cv_ai_opt_interleavethinkmindist.GetFloat(); - } - if (cv_ai_opt_interleavethinkmaxdist.GetFloat() > 0) - { - maxDist = cv_ai_opt_interleavethinkmaxdist.GetFloat(); - } - - if (maxDist < minDist) - { - gameLocal.Warning("Minimum distance for interleaved thinking is larger than maximum distance, switching optimization off."); - return 0; - } - - float playerDist = (physicsObj.GetOrigin() - gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin()).LengthFast(); - if (playerDist < minDist) - { - return 0; - } - else if (playerDist > maxDist) - { - return maxFrames; - } - else - { - float fraction = (playerDist - minDist) / (maxDist - minDist); - int thinkFrames = 1 + static_cast(fraction * maxFrames); - return thinkFrames; - } -} - -/*********************************************************************** - - AI script state management - -***********************************************************************/ - -/* -===================== -idAI::LinkScriptVariables -===================== -*/ -void idAI::LinkScriptVariables( void ) -{ - // Call the base class first - idActor::LinkScriptVariables(); - - AI_TALK.LinkTo( scriptObject, "AI_TALK" ); - AI_DAMAGE.LinkTo( scriptObject, "AI_DAMAGE" ); - AI_PAIN.LinkTo( scriptObject, "AI_PAIN" ); - AI_SPECIAL_DAMAGE.LinkTo( scriptObject, "AI_SPECIAL_DAMAGE" ); - AI_KNOCKEDOUT.LinkTo( scriptObject, "AI_KNOCKEDOUT" ); - AI_ENEMY_VISIBLE.LinkTo( scriptObject, "AI_ENEMY_VISIBLE" ); - AI_ENEMY_IN_FOV.LinkTo( scriptObject, "AI_ENEMY_IN_FOV" ); - AI_MOVE_DONE.LinkTo( scriptObject, "AI_MOVE_DONE" ); - AI_ONGROUND.LinkTo( scriptObject, "AI_ONGROUND" ); - AI_ACTIVATED.LinkTo( scriptObject, "AI_ACTIVATED" ); - AI_FORWARD.LinkTo( scriptObject, "AI_FORWARD" ); - AI_JUMP.LinkTo( scriptObject, "AI_JUMP" ); - AI_BLOCKED.LinkTo( scriptObject, "AI_BLOCKED" ); - AI_DEST_UNREACHABLE.LinkTo( scriptObject, "AI_DEST_UNREACHABLE" ); - AI_HIT_ENEMY.LinkTo( scriptObject, "AI_HIT_ENEMY" ); - AI_OBSTACLE_IN_PATH.LinkTo( scriptObject, "AI_OBSTACLE_IN_PATH" ); - AI_PUSHED.LinkTo( scriptObject, "AI_PUSHED" ); - - //this is only set in a given frame - AI_ALERTED.LinkTo( scriptObject, "AI_ALERTED" ); - - AI_AlertLevel.LinkTo( scriptObject, "AI_AlertLevel" ); - AI_AlertIndex.LinkTo( scriptObject, "AI_AlertIndex" ); - - //these are set until unset by the script - AI_HEARDSOUND.LinkTo( scriptObject, "AI_HEARDSOUND"); - AI_VISALERT.LinkTo( scriptObject, "AI_VISALERT"); - AI_TACTALERT.LinkTo( scriptObject, "AI_TACTALERT"); - - AI_CROUCH.LinkTo( scriptObject, "AI_CROUCH"); - AI_RUN.LinkTo( scriptObject, "AI_RUN"); - AI_CREEP.LinkTo( scriptObject, "AI_CREEP"); - - AI_LAY_DOWN_LEFT.LinkTo( scriptObject, "AI_LAY_DOWN_LEFT"); - AI_LAY_DOWN_FACE_DIR.LinkTo(scriptObject, "AI_LAY_DOWN_FACE_DIR"); - - AI_SIT_DOWN_ANGLE.LinkTo(scriptObject, "AI_SIT_DOWN_ANGLE"); - AI_SIT_UP_ANGLE.LinkTo(scriptObject, "AI_SIT_UP_ANGLE"); - - -} - -/* -===================== -idAI::UpdateAIScript -===================== -*/ -void idAI::UpdateScript() -{ - START_SCOPED_TIMING(aiScriptTimer, scopedScriptTimer); - - // greebo: This is overriding idActor::UpdateScript(), where all the state change stuff - // is executed, which is not needed for TDM AI - - if ( ai_debugScript.GetInteger() == entityNumber ) { - scriptThread->EnableDebugInfo(); - } else { - scriptThread->DisableDebugInfo(); - } - - // don't call script until it's done waiting - if (!scriptThread->IsWaiting()) { - scriptThread->Execute(); - } - - // clear the hit enemy flag so we catch the next time we hit someone - AI_HIT_ENEMY = false; - - if ( allowHiddenMovement || !IsHidden() ) { - // update the animstate if we're not hidden - if (!cv_ai_opt_noanims.GetBool()) - { - UpdateAnimState(); - } - } -} - -/*********************************************************************** - - navigation - -***********************************************************************/ - -/* -============ -idAI::KickObstacles -============ -*/ -void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) { - int i, numListedClipModels; - idBounds clipBounds; - idEntity *obEnt; - idClipModel *clipModel; - idClipModel *clipModelList[ MAX_GENTITIES ]; - int clipmask; - idVec3 org; - idVec3 forceVec; - idVec3 delta; - idVec2 perpendicular; - - org = physicsObj.GetOrigin(); - - // find all possible obstacles - clipBounds = physicsObj.GetAbsBounds(); - clipBounds.TranslateSelf( dir * (clipBounds[1].x - clipBounds[0].x + clipBounds[1].y - clipBounds[0].y)/2); // grayman #2667 -// clipBounds.TranslateSelf( dir * 32.0f ); // grayman #2667 - old way assumed a humanoid - clipBounds.ExpandSelf( 8.0f ); - clipBounds.AddPoint( org ); - clipmask = physicsObj.GetClipMask(); - numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds( clipBounds, clipmask, clipModelList, MAX_GENTITIES ); - for ( i = 0; i < numListedClipModels; i++ ) { - clipModel = clipModelList[i]; - obEnt = clipModel->GetEntity(); - if ( obEnt == alwaysKick ) { - // we'll kick this one outside the loop - continue; - } - - if ( !clipModel->IsTraceModel() ) { - continue; - } - - if ( obEnt->IsType( idMoveable::Type ) && obEnt->GetPhysics()->IsPushable() ) - { - delta = obEnt->GetPhysics()->GetOrigin() - org; - delta.NormalizeFast(); - perpendicular.x = -delta.y; - perpendicular.y = delta.x; - delta.z += 0.5f; - delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; - forceVec = delta * force; // grayman #2568 - remove obEnt->mass from the equation -// forceVec = delta * force * obEnt->GetPhysics()->GetMass(); // grayman #2568 - old way - obEnt->ApplyImpulse( this, 0, obEnt->GetPhysics()->GetOrigin(), forceVec ); - if (obEnt->m_SetInMotionByActor.GetEntity() == NULL) - { - obEnt->m_SetInMotionByActor = this; - obEnt->m_MovedByActor = this; - } - } - } - - if ( alwaysKick ) - { - delta = alwaysKick->GetPhysics()->GetOrigin() - org; - delta.NormalizeFast(); - perpendicular.x = -delta.y; - perpendicular.y = delta.x; - delta.z += 0.5f; - delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; - forceVec = delta * force; // grayman #2568 - remove obEnt->mass from the equation -// forceVec = delta * force * alwaysKick->GetPhysics()->GetMass(); // grayman #2568 - old way - alwaysKick->ApplyImpulse( this, 0, alwaysKick->GetPhysics()->GetOrigin(), forceVec ); - if (alwaysKick->m_SetInMotionByActor.GetEntity() == NULL) - { - alwaysKick->m_SetInMotionByActor = this; - alwaysKick->m_MovedByActor = this; - } - } -} - -bool idAI::ReEvaluateArea(int areaNum) -{ - // Remember the time - lastAreaReevaluationTime = gameLocal.time; - - // Let's see if we have a valid door info structure in our memory - ai::DoorInfoPtr doorInfo = GetMemory().GetDoorInfo(areaNum); - - if (doorInfo != NULL) - { - //if (doorInfo->lastTimeTriedToOpen + doorRetryTime < gameLocal.time) - { - // Re-try the door after some time - gameLocal.m_AreaManager.RemoveForbiddenArea(areaNum, this); - return true; - } - } - - return false; -} - -/* -============ -ValidForBounds -============ -*/ -bool ValidForBounds( const idAASSettings *settings, const idBounds &bounds ) { - int i; - - for ( i = 0; i < 3; i++ ) { - if ( bounds[0][i] < settings->boundingBoxes[0][0][i] ) { - return false; - } - if ( bounds[1][i] > settings->boundingBoxes[0][1][i] ) { - return false; - } - } - return true; -} - -/* -===================== -idAI::SetAAS -===================== -*/ -void idAI::SetAAS( void ) { - idStr use_aas; - - spawnArgs.GetString( "use_aas", NULL, use_aas ); - aas = gameLocal.GetAAS( use_aas ); - if ( aas ) { - const idAASSettings *settings = aas->GetSettings(); - if ( settings ) { - if ( !ValidForBounds( settings, physicsObj.GetBounds() ) ) { - gameLocal.Error( "%s cannot use use_aas %s\n", name.c_str(), use_aas.c_str() ); - } - float height = settings->maxStepHeight; - physicsObj.SetMaxStepHeight( height ); - return; - } else { - aas = NULL; - } - } - gameLocal.Printf( "WARNING: %s has no AAS file\n", name.c_str() ); -} - -/* -===================== -idAI::DrawRoute -===================== -*/ -void idAI::DrawRoute( void ) const { - if ( aas && move.toAreaNum && move.moveCommand != MOVE_NONE && move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_FACE_ENEMY && move.moveCommand != MOVE_FACE_ENTITY && move.moveCommand != MOVE_TO_POSITION_DIRECT && move.moveCommand != MOVE_VECTOR ) - { - if ( move.moveType == MOVETYPE_FLY ) { - aas->ShowFlyPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); - } else { - aas->ShowWalkPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); - } - } -} - -/* -===================== -idAI::ReachedPos -===================== -*/ -bool idAI::ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand) const { - if ( move.moveType == MOVETYPE_SLIDE ) { - idBounds bnds( idVec3( -4, -4.0f, -8.0f ), idVec3( 4.0f, 4.0f, 64.0f ) ); - bnds.TranslateSelf( physicsObj.GetOrigin() ); - if ( bnds.ContainsPoint( pos ) ) { - return true; - } - } else { - if ( ( moveCommand == MOVE_TO_ENEMY ) || ( moveCommand == MOVE_TO_ENTITY ) ) - { - if ( physicsObj.GetAbsBounds().IntersectsBounds( idBounds( pos ).Expand( 8.0f ) ) ) { - return true; - } - } - else - { - // Use the AI bounding box check to see if we've reached the position - return ReachedPosAABBCheck(pos); - } - } - return false; -} - -bool idAI::ReachedPosAABBCheck(const idVec3& pos) const -{ - // angua: use AI bounds for checking - idBounds bnds(physicsObj.GetBounds()); - if (move.accuracy >= 0) - { - // if accuracy is set, replace x and y size of the bounds - bnds[0][0] = -move.accuracy; - bnds[0][1] = -move.accuracy; - bnds[1][0] = move.accuracy; - bnds[1][1] = move.accuracy; - } - - bnds.TranslateSelf(physicsObj.GetOrigin()); - - bnds.ExpandSelf(reachedpos_bbox_expansion); - - // angua: expand the bounds a bit downwards, so that they can actually reach target positions - // that are reported as reachable by PathToGoal. - bnds[0].z -= aas_reachability_z_tolerance; - bnds[1].z += 0.4*aas_reachability_z_tolerance; // grayman #2717 - don't look so far up - - return (bnds.ContainsPoint(pos)); -} - -/* -===================== -idAI::PointReachableAreaNum -===================== -*/ -int idAI::PointReachableAreaNum( const idVec3 &pos, const float boundsScale, const idVec3& offset) const -{ - START_SCOPED_TIMING(aiPointReachableAreaNumTimer, scopedPointReachableAreaNumTimer); - - if (aas == NULL) { - return 0; // no AAS, no area number - } - - idVec3 size = aas->GetSettings()->boundingBoxes[0][1] * boundsScale; - - // Construct the modifed bounds, based on the parameters (max.z = 32) - idBounds bounds(-size, idVec3(size.x, size.y, 32.0f)); - idVec3 newPos = pos + offset; - -/* idBounds temp(bounds); - temp.TranslateSelf(newPos); - gameRenderWorld->DebugBox(colorGreen, idBox(temp),gameLocal.msec);*/ - - int areaNum = 0; - - if (move.moveType == MOVETYPE_FLY) - { - // Flying monsters - areaNum = aas->PointReachableAreaNum( newPos, bounds, AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ); - } - else - { - // Non-flying monsters - areaNum = aas->PointReachableAreaNum( newPos, bounds, AREA_REACHABLE_WALK ); - } - - return areaNum; -} - -/* -===================== -idAI::PathToGoal -===================== -*/ -bool idAI::PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, idActor* actor ) const { - if ( !aas ) { - return false; - } - - START_SCOPED_TIMING(aiPathToGoalTimer, scopedPathToGoalTimer); - - idVec3 org = origin; - aas->PushPointIntoAreaNum( areaNum, org ); - if ( !areaNum ) { - return false; - } - - idVec3 goal = goalOrigin; - aas->PushPointIntoAreaNum( goalAreaNum, goal ); - if ( !goalAreaNum ) { - return false; - } - - // Sanity check the returned area. If the position isn't within the AI's height + aas_reachability_z_tolerance/2 - // reach, then report it as unreachable. - const idVec3& grav = physicsObj.GetGravityNormal(); - - float height = fabs((goal - aas->AreaCenter(goalAreaNum)) * grav); - - idBounds bounds = GetPhysics()->GetBounds(); - - if (height > (bounds[1][2] + reachedpos_bbox_expansion + 0.4*aas_reachability_z_tolerance)) // grayman #2717 - don't look so far up, and add reachedpos_bbox_expansion - { - goalAreaNum = 0; - return false; - } - - bool returnval; - gameLocal.m_AreaManager.DisableForbiddenAreas(this); - if ( move.moveType == MOVETYPE_FLY ) { - returnval = aas->FlyPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags ); - } else { - returnval = aas->WalkPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags, actor ); - } - gameLocal.m_AreaManager.EnableForbiddenAreas(this); - - // return returnval; - // grayman #2708 - if returnval is true, return, but if false, check whether the AAS area is above - // the AI's origin, as it might be if the AI is stuck in an AAS area next to a monster-clipped - // table top, where it will be at the plane of the table top. If that's the case, return 'true' - // to let the AI escape this type of AAS area. Normal pathfinding will never let him out. - - if (returnval) - { - return true; - } - - idVec3 myOrigin = GetPhysics()->GetOrigin(); - idBounds areaBounds = aas->GetAreaBounds(areaNum); - path.moveGoal = goal; - return (myOrigin.z < areaBounds[0].z); -} - - -/* -===================== -idAI::TravelDistance - -Returns the approximate travel distance from one position to the goal, or if no AAS, the straight line distance. - -This is feakin' slow, so it's not good to do it too many times per frame. It also is slower the further you -are from the goal, so try to break the goals up into shorter distances. -===================== -*/ -float idAI::TravelDistance( const idVec3 &start, const idVec3 &end ) { - int fromArea; - int toArea; - float dist; - idVec2 delta; - aasPath_t path; - - if ( !aas ) { - // no aas, so just take the straight line distance - delta = end.ToVec2() - start.ToVec2(); - dist = delta.LengthFast(); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); - gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); - } - - return dist; - } - - fromArea = PointReachableAreaNum( start ); - toArea = PointReachableAreaNum( end ); - - if ( !fromArea || !toArea ) { - // can't seem to get there - return -1; - } - - if ( fromArea == toArea ) { - // same area, so just take the straight line distance - delta = end.ToVec2() - start.ToVec2(); - dist = delta.LengthFast(); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); - gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); - } - - return dist; - } - - idReachability *reach; - int travelTime; - if ( !aas->RouteToGoalArea( fromArea, start, toArea, travelFlags, travelTime, &reach, NULL, this ) ) { - return -1; - } - - if ( ai_debugMove.GetBool() ) { - if ( move.moveType == MOVETYPE_FLY ) { - aas->ShowFlyPath( start, toArea, end ); - } else { - aas->ShowWalkPath( start, toArea, end ); - } - } - - return travelTime; -} - -/* -===================== -idAI::StopMove -===================== -*/ -void idAI::StopMove( moveStatus_t status ) { - AI_MOVE_DONE = true; - AI_FORWARD = false; - m_pathRank = 1000; // grayman #2345 - move.moveCommand = MOVE_NONE; - move.moveStatus = status; - move.toAreaNum = 0; - move.goalEntity = NULL; - move.moveDest = physicsObj.GetOrigin(); - AI_DEST_UNREACHABLE = (status == MOVE_STATUS_DEST_UNREACHABLE); - AI_OBSTACLE_IN_PATH = false; - AI_BLOCKED = false; - move.startTime = gameLocal.time; - move.duration = 0; - move.range = 0.0f; - move.speed = 0.0f; - move.anim = 0; - move.moveDir.Zero(); - move.lastMoveOrigin.Zero(); - move.lastMoveTime = gameLocal.time; - move.accuracy = -1; -} - -const idVec3& idAI::GetMoveDest() const -{ - return move.moveDest; -} - -idEntity* idAI::GetTactileEntity(void) // grayman #2345 -{ - return m_tactileEntity; -} - -/* -===================== -idAI::FaceEnemy - -Continually face the enemy's last known position. MoveDone is always true in this case. -===================== -*/ -bool idAI::FaceEnemy( void ) { - idActor *enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - return false; - } - - TurnToward( lastVisibleEnemyPos ); - move.goalEntity = enemyEnt; - move.moveDest = physicsObj.GetOrigin(); - move.moveCommand = MOVE_FACE_ENEMY; - move.moveStatus = MOVE_STATUS_WAITING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - move.accuracy = -1; - AI_MOVE_DONE = true; - AI_FORWARD = false; - m_pathRank = 1000; // grayman #2345 - AI_DEST_UNREACHABLE = false; - - return true; -} - -/* -===================== -idAI::FaceEntity - -Continually face the entity position. MoveDone is always true in this case. -===================== -*/ -bool idAI::FaceEntity( idEntity *ent ) { - if ( !ent ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - return false; - } - - idVec3 entityOrg = ent->GetPhysics()->GetOrigin(); - TurnToward( entityOrg ); - move.goalEntity = ent; - move.moveDest = physicsObj.GetOrigin(); - move.moveCommand = MOVE_FACE_ENTITY; - move.moveStatus = MOVE_STATUS_WAITING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - AI_MOVE_DONE = true; - AI_FORWARD = false; - m_pathRank = 1000; // grayman #2345 - AI_DEST_UNREACHABLE = false; - - return true; -} - -/* -===================== -idAI::DirectMoveToPosition -===================== -*/ -bool idAI::DirectMoveToPosition( const idVec3 &pos ) { - if ( ReachedPos( pos, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); - return true; - } - - move.moveDest = pos; - move.goalEntity = NULL; - move.moveCommand = MOVE_TO_POSITION_DIRECT; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - if ( move.moveType == MOVETYPE_FLY ) { - idVec3 dir = pos - physicsObj.GetOrigin(); - dir.Normalize(); - dir *= fly_speed; - physicsObj.SetLinearVelocity( dir ); - } - - return true; -} - -/* -===================== -idAI::MoveToEnemyHeight -===================== -*/ -bool idAI::MoveToEnemyHeight( void ) { - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt || ( move.moveType != MOVETYPE_FLY ) ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - return false; - } - - move.moveDest.z = lastVisibleEnemyPos.z + enemyEnt->EyeOffset().z + fly_offset; - move.goalEntity = enemyEnt; - move.moveCommand = MOVE_TO_ENEMYHEIGHT; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = false; - m_pathRank = 1000; // grayman #2345 - - return true; -} - -/* -===================== -idAI::MoveToEnemy -===================== -*/ -bool idAI::MoveToEnemy( void ) { - int areaNum; - aasPath_t path; - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - return false; - } - - if ( ReachedPos( lastVisibleReachableEnemyPos, MOVE_TO_ENEMY ) ) { - if ( !ReachedPos( lastVisibleEnemyPos, MOVE_TO_ENEMY ) || !AI_ENEMY_VISIBLE ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - StopMove( MOVE_STATUS_DONE ); - return true; - } - - idVec3 pos = lastVisibleReachableEnemyPos; - - move.toAreaNum = 0; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( pos ); - aas->PushPointIntoAreaNum( move.toAreaNum, pos ); - - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos, this ) ) { - AI_DEST_UNREACHABLE = true; - return false; - } - } - - if ( !move.toAreaNum ) { - // if only trying to update the enemy position - if ( move.moveCommand == MOVE_TO_ENEMY ) { - if ( !aas ) { - // keep the move destination up to date for wandering - move.moveDest = pos; - } - return false; - } - - if ( !NewWanderDir( pos ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - } - - if ( move.moveCommand != MOVE_TO_ENEMY ) { - move.moveCommand = MOVE_TO_ENEMY; - move.startTime = gameLocal.time; - } - - move.moveDest = pos; - move.goalEntity = enemyEnt; - move.speed = fly_speed; - move.moveStatus = MOVE_STATUS_MOVING; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -/* -===================== -idAI::MoveToEntity -===================== -*/ -bool idAI::MoveToEntity( idEntity *ent ) { - int areaNum; - aasPath_t path; - idVec3 pos; - - if ( !ent ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - return false; - } - - pos = ent->GetPhysics()->GetOrigin(); - if ( ( move.moveType != MOVETYPE_FLY ) && ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntityOrigin != pos ) ) ) { - ent->GetFloorPos( 64.0f, pos ); - } - - if ( ReachedPos( pos, MOVE_TO_ENTITY ) ) { - StopMove( MOVE_STATUS_DONE ); - return true; - } - - move.toAreaNum = 0; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( pos ); - aas->PushPointIntoAreaNum( move.toAreaNum, pos ); - - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos, this ) ) { - AI_DEST_UNREACHABLE = true; - return false; - } - } - - if ( !move.toAreaNum ) { - // if only trying to update the entity position - if ( move.moveCommand == MOVE_TO_ENTITY ) { - if ( !aas ) { - // keep the move destination up to date for wandering - move.moveDest = pos; - } - return false; - } - - if ( !NewWanderDir( pos ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - } - - if ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntity.GetEntity() != ent ) ) { - move.startTime = gameLocal.time; - move.goalEntity = ent; - move.moveCommand = MOVE_TO_ENTITY; - } - - move.moveDest = pos; - move.goalEntityOrigin = ent->GetPhysics()->GetOrigin(); - move.moveStatus = MOVE_STATUS_MOVING; - move.speed = fly_speed; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -CMultiStateMover* idAI::OnElevator(bool mustBeMoving) const -{ - idEntity* ent = physicsObj.GetGroundEntity(); - - // Return false if ground entity is not a mover - if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) return NULL; - - CMultiStateMover* mover = static_cast(ent); - if (mustBeMoving) - { - return (!mover->IsAtRest()) ? mover : NULL; - } - return mover; -} - -bool idAI::Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption) -{ - EscapePointAlgorithm algorithmType = static_cast(algorithm); - - if ( !aas || !entityToFleeFrom ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - // The current AI origin - const idVec3& org = physicsObj.GetOrigin(); - - // These two will hold the travel destination info - idVec3 moveDest; - int moveAreaNum(-1); - - if (algorithmType != FIND_AAS_AREA_FAR_FROM_THREAT) - { - // Use the EscapePointManager to locate a pathFlee entity - - // Setup the escape conditions - EscapeConditions conditions; - - conditions.fromEntity = entityToFleeFrom; - conditions.aas = aas; - conditions.fromPosition = org; - conditions.self = this; - conditions.distanceOption = static_cast(distanceOption); - conditions.algorithm = algorithmType; - conditions.minDistanceToThreat = 0.0f; - - // Request the escape goal from the manager - EscapeGoal goal = gameLocal.m_EscapePointManager->GetEscapeGoal(conditions); - - if (goal.escapePointId == -1) - { - // Invalid escape point id returned - return false; - } - - // Get the actual point (this should never be NULL) - EscapePoint* targetPoint = gameLocal.m_EscapePointManager->GetEscapePoint(goal.escapePointId); - - moveDest = targetPoint->origin; - moveAreaNum = targetPoint->areaNum; - } - else - { - // algorithm == FIND_AAS_AREA_FAR_FROM_THREAT - - int areaNum = PointReachableAreaNum(org); - - // consider the entity the monster is getting close to as an obstacle - aasObstacle_t obstacle; - obstacle.absBounds = entityToFleeFrom->GetPhysics()->GetAbsBounds(); - - idVec3 pos; - - if ( entityToFleeFrom == enemy.GetEntity() ) { - pos = lastVisibleEnemyPos; - } else { - pos = entityToFleeFrom->GetPhysics()->GetOrigin(); - } - - // Setup the evaluator class - tdmAASFindEscape findEscapeArea(pos, org, distanceOption, 100); - aasGoal_t dummy; - aas->FindNearestGoal(dummy, areaNum, org, pos, travelFlags, &obstacle, 1, findEscapeArea); - - aasGoal_t& goal = findEscapeArea.GetEscapeGoal(); - - if (goal.areaNum == -1) - { - // Invalid escape point id returned - return false; - } - - moveDest = goal.origin; - moveAreaNum = goal.areaNum; - } - - StopMove(MOVE_STATUS_DONE); - MoveToPosition(moveDest); - return true; -/* - if ( ReachedPos( moveDest, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); - return true; - } - - if ( !move.toAreaNum && !NewWanderDir( moveDest ) ) - { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } -*/ -/* grayman - the section below can't be reached because - of the 'return true' above, so I'm commenting it out. - The section above this, just below the 'return', was - already commented out. - - move.moveDest = moveDest; - move.toAreaNum = moveAreaNum; - move.goalEntity = entityToFleeFrom; - move.moveCommand = MOVE_FLEE; - move.moveStatus = MOVE_STATUS_MOVING; - move.range = MAX_FLEE_DISTANCE; - move.speed = fly_speed; - move.startTime = gameLocal.time; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; - */ -} - -/* -===================== -idAI::GetPositionWithinRange -===================== -*/ -aasGoal_t idAI::GetPositionWithinRange(const idVec3& targetPos) -{ - idVec3 org = physicsObj.GetOrigin(); - idVec3 eye = GetEyePosition(); - float fireRange = spawnArgs.GetFloat("fire_range", "0"); - - PositionWithinRangeFinder findGoal(this, physicsObj.GetGravityAxis(), targetPos, eye - org, fireRange); - - aasGoal_t goal; - int areaNum = PointReachableAreaNum(org); - - aas->FindNearestGoal(goal, areaNum, org, targetPos, travelFlags, NULL, 0, findGoal); - - goal.areaNum = -1; - - float bestDistance; - findGoal.GetBestGoalResult(bestDistance, goal); - return goal; -} - - - - -/* -===================== -idAI::GetObservationPosition -===================== -*/ -idVec3 idAI::GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne) -{ - int areaNum; - aasObstacle_t obstacle; - aasGoal_t goal; - idBounds bounds; - idVec3 observeFromPos; - aasPath_t path; - - if ( !aas ) - { - observeFromPos = GetPhysics()->GetOrigin(); - AI_DEST_UNREACHABLE = true; - return observeFromPos; - } - - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - - // Raise point up just a bit so it isn't on the floor of the aas - idVec3 pointToObserve2 = pointToObserve; - pointToObserve2.z += 45.0; - - // What is the lighting along the line where the thing to be observed - // might be. - float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(pointToObserve, pointToObserve2); - - idAASFindObservationPosition findGoal - ( - this, - physicsObj.GetGravityAxis(), - pointToObserve2, - GetEyePosition() - org, // Offset of eye from origin - maxDistanceToObserve // Maximum distance from which we can observe - ); - - if (!aas->FindNearestGoal - ( - goal, - areaNum, - org, - pointToObserve2, // It is also the goal target - travelFlags, - NULL, - 0, - findGoal - ) ) - { - float bestDistance; - - // See if we can get to the point itself since noplace was good enough - // for just looking from a distance due to lighting/occlusion/reachability. - if (PathToGoal( path, areaNum, physicsObj.GetOrigin(), areaNum, org, this ) ) - { - - // Can reach the point itself, so walk right up to it - observeFromPos = pointToObserve; - - // Draw the AI Debug Graphics - if (cv_ai_search_show.GetInteger() >= 1.0) - { - idVec4 markerColor (0.0, 1.0, 1.0, 1.0); - idVec3 arrowLength (0.0, 0.0, 50.0); - - gameRenderWorld->DebugArrow - ( - markerColor, - observeFromPos + arrowLength, - observeFromPos, - 2, - cv_ai_search_show.GetInteger() - ); - } - - } - - else if (findGoal.getBestGoalResult - ( - bestDistance, - goal - )) - { - - // Use closest reachable observation point that we found - observeFromPos = goal.origin; - - // Draw the AI Debug Graphics - if (cv_ai_search_show.GetInteger() >= 1.0) - { - idVec4 markerColor (1.0, 1.0, 0.0, 1.0); - idVec3 arrowLength (0.0, 0.0, 50.0); - - gameRenderWorld->DebugArrow - ( - markerColor, - observeFromPos, - pointToObserve, - 2, - cv_ai_search_show.GetInteger() - ); - } - } - - else - { - // No choice but to try to walk up to it as much as we can - observeFromPos = pointToObserve; - - // Draw the AI Debug Graphics - if (cv_ai_search_show.GetInteger() >= 1.0) - { - idVec4 markerColor (1.0, 0.0, 0.0, 1.0); - idVec3 arrowLength (0.0, 0.0, 50.0); - - gameRenderWorld->DebugArrow - ( - markerColor, - observeFromPos + arrowLength, - observeFromPos, - 2, - cv_ai_search_show.GetInteger() - ); - } - } - return observeFromPos; - } - - else - { - observeFromPos = goal.origin; - AI_DEST_UNREACHABLE = false; - - // Draw the AI Debug Graphics - if (cv_ai_search_show.GetInteger() >= 1.0) - { - idVec4 markerColor (0.0, 1.0, 0.0, 1.0); - idVec3 arrowLength (0.0, 0.0, 50.0); - - gameRenderWorld->DebugArrow - ( - markerColor, - observeFromPos, - pointToObserve, - 2, - cv_ai_search_show.GetInteger() - ); - } - return observeFromPos; - } -} - -/* -===================== -idAI::MoveOutOfRange -===================== -*/ -bool idAI::MoveOutOfRange( idEntity *ent, float range ) { - int areaNum; - aasObstacle_t obstacle; - aasGoal_t goal; - idBounds bounds; - idVec3 pos; - - if ( !aas || !ent ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - - // consider the entity the monster is getting close to as an obstacle - obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); - - if ( ent == enemy.GetEntity() ) { - pos = lastVisibleEnemyPos; - } else { - pos = ent->GetPhysics()->GetOrigin(); - } - - idAASFindAreaOutOfRange findGoal( pos, range ); - if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Best fleeing location is: %f %f %f in area %d\r", goal.origin.x, goal.origin.y, goal.origin.z, goal.areaNum); - - if ( ReachedPos( goal.origin, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); - return true; - } - - move.moveDest = goal.origin; - move.toAreaNum = goal.areaNum; - move.goalEntity = ent; - move.moveCommand = MOVE_OUT_OF_RANGE; - move.moveStatus = MOVE_STATUS_MOVING; - move.range = range; - move.speed = fly_speed; - move.startTime = gameLocal.time; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -/* -===================== -idAI::MoveToAttackPosition -===================== -*/ -bool idAI::MoveToAttackPosition( idEntity *ent, int attack_anim ) { - int areaNum; - aasObstacle_t obstacle; - aasGoal_t goal; - idBounds bounds; - idVec3 pos; - - if ( !aas || !ent ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - - // consider the entity the monster is getting close to as an obstacle - obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); - - if ( ent == enemy.GetEntity() ) { - pos = lastVisibleEnemyPos; - } else { - pos = ent->GetPhysics()->GetOrigin(); - } - - // Make sure we have a active projectile or at least the def - if (activeProjectile.info.def == NULL) - { - if (projectileInfo.Num() == 0) - { - gameLocal.Warning("AI %s has no projectile info, cannot move to attack position!", name.c_str()); - return false; - } - - // Move the def pointer of the "next" projectile info into the active one - activeProjectile.info = projectileInfo[curProjectileIndex]; - } - - idAASFindAttackPosition findGoal( this, physicsObj.GetGravityAxis(), ent, pos, missileLaunchOffset[ attack_anim ] ); - if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - move.moveDest = goal.origin; - move.toAreaNum = goal.areaNum; - move.goalEntity = ent; - move.moveCommand = MOVE_TO_ATTACK_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.speed = fly_speed; - move.startTime = gameLocal.time; - move.anim = attack_anim; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -/* -===================== -idAI::MoveToPosition -===================== -*/ -bool idAI::MoveToPosition( const idVec3 &pos, float accuracy ) -{ - // Clear the "blocked" flag in the movement subsystem - movementSubsystem->SetBlockedState(ai::MovementSubsystem::ENotBlocked); - - // Check if we already reached the position - if ( ReachedPos( pos, move.moveCommand) ) { - StopMove( MOVE_STATUS_DONE ); - return true; - } - - if (GetMoveType() == MOVETYPE_SIT - || GetMoveType() == MOVETYPE_SLEEP - || GetMoveType() == MOVETYPE_SIT_DOWN - || GetMoveType() == MOVETYPE_GET_UP - || GetMoveType()== MOVETYPE_LAY_DOWN - || GetMoveType()== MOVETYPE_GET_UP_FROM_LYING) - { - GetUp(); - return true; - } - - idVec3 org = pos; - move.toAreaNum = 0; - aasPath_t path; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( org ); - aas->PushPointIntoAreaNum( move.toAreaNum, org ); // if this point is outside this area, it will be moved to one of the area's edges - - int areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, org, this ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - } - - if ( !move.toAreaNum && !NewWanderDir( org ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - // Valid path to goal, check if we need to use an elevator - if (path.type == PATHTYPE_ELEVATOR) - { - NeedToUseElevator(path.elevatorRoute); - } - - move.moveDest = org; - move.goalEntity = NULL; - move.moveCommand = MOVE_TO_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - move.accuracy = accuracy; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -/* -===================== -idAI::LookForCover -===================== -*/ -bool idAI::LookForCover(aasGoal_t& hideGoal,idEntity *hideFromEnt, const idVec3 &hideFromPos) -{ - if (aas == NULL) return false; - - idBounds bounds; - aasObstacle_t obstacle; - - const idVec3 &org = physicsObj.GetOrigin(); - int areaNum = PointReachableAreaNum( org ); - - // consider the entity the monster tries to hide from as an obstacle - obstacle.absBounds = hideFromEnt->GetPhysics()->GetAbsBounds(); - - idAASFindCover findCover( this, hideFromEnt, hideFromPos ); - return aas->FindNearestGoal( hideGoal, areaNum, org, hideFromPos, travelFlags, &obstacle, 1, findCover, spawnArgs.GetInt("taking_cover_max_cost") ); -} - -/* -===================== -idAI::MoveToCover -===================== -*/ -bool idAI::MoveToCover( idEntity *hideFromEnt, const idVec3 &hideFromPos ) { - //common->Printf("MoveToCover called... "); - - aasGoal_t hideGoal; - - if ( !aas || !hideFromEnt ) { - common->Printf("MoveToCover failed: null aas or entity\n"); - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - if (!LookForCover(hideGoal, hideFromEnt, hideFromPos)) { - //common->Printf("MoveToCover failed: destination unreachable\n"); - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - if ( ReachedPos( hideGoal.origin, move.moveCommand ) ) { - //common->Printf("MoveToCover succeeded: Already at hide position\n"); - StopMove( MOVE_STATUS_DONE ); - return true; - } - - move.moveDest = hideGoal.origin; - move.toAreaNum = hideGoal.areaNum; - move.goalEntity = hideFromEnt; - move.moveCommand = MOVE_TO_COVER; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - //common->Printf("MoveToCover succeeded: Now moving into cover\n"); - - return true; -} - -/* -===================== -idAI::SlideToPosition -===================== -*/ -bool idAI::SlideToPosition( const idVec3 &pos, float time ) { - StopMove( MOVE_STATUS_DONE ); - - move.moveDest = pos; - move.goalEntity = NULL; - move.moveCommand = MOVE_SLIDE_TO_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.duration = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = false; - m_pathRank = 1000; // grayman #2345 - - if ( move.duration > 0 ) { - move.moveDir = ( pos - physicsObj.GetOrigin() ) / MS2SEC( move.duration ); - if ( move.moveType != MOVETYPE_FLY ) { - move.moveDir.z = 0.0f; - } - move.speed = move.moveDir.LengthFast(); - } - - return true; -} - -/* -===================== -idAI::WanderAround -===================== -*/ -bool idAI::WanderAround( void ) { - StopMove( MOVE_STATUS_DONE ); - - move.moveDest = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 256.0f; - if ( !NewWanderDir( move.moveDest ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - AI_DEST_UNREACHABLE = true; - return false; - } - - move.moveCommand = MOVE_WANDER; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - move.accuracy = -1; - AI_MOVE_DONE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} - -/* -===================== -idAI::MoveDone -===================== -*/ -bool idAI::MoveDone( void ) const { - return ( move.moveCommand == MOVE_NONE ); -} - -void idAI::SetMoveType( int moveType ) { - if ( ( moveType < 0 ) || ( moveType >= NUM_MOVETYPES ) ) { - gameLocal.Error( "Invalid movetype %d", moveType ); - } - - move.moveType = static_cast( moveType ); - if ( move.moveType == MOVETYPE_FLY ) { - travelFlags = TFL_WALK|TFL_AIR|TFL_FLY|TFL_DOOR; - } else { - travelFlags = TFL_WALK|TFL_AIR|TFL_DOOR; - } -} - -/* -================ -idAI::StepDirection -================ -*/ -bool idAI::StepDirection( float dir ) { - predictedPath_t path; - idVec3 org; - - move.wanderYaw = dir; - move.moveDir = idAngles( 0, move.wanderYaw, 0 ).ToForward(); - - org = physicsObj.GetOrigin(); - - idAI::PredictPath( this, aas, org, move.moveDir * 48.0f, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - if ( path.blockingEntity && ( ( move.moveCommand == MOVE_TO_ENEMY ) || ( move.moveCommand == MOVE_TO_ENTITY ) ) && ( path.blockingEntity == move.goalEntity.GetEntity() ) ) { - // don't report being blocked if we ran into our goal entity - return true; - } - - // SZ: January 7, 2006: Wandering uses this, and currently it fails the test if it would bump into another AI. - // If we are wandering, we want to make sure we can still bump into the player or enemy AIs, both of which are idActor - // based. - if (path.blockingEntity && (move.moveCommand == MOVE_WANDER)) - { - // What type of entity is it? - if - ( - (path.blockingEntity->IsType(idActor::Type) ) - ) - { - // Bump into enemies all you want while wandering - if (IsEnemy(path.blockingEntity)) - { - return true; - } - } - - } // End wandering case - - if ( ( move.moveType == MOVETYPE_FLY ) && ( path.endEvent == SE_BLOCKED ) ) { - float z; - - move.moveDir = path.endVelocity * 1.0f / 48.0f; - - // trace down to the floor and see if we can go forward - idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, -1024.0f ), 1000, 1000, SE_BLOCKED, path ); - - idVec3 floorPos = path.endPos; - idAI::PredictPath( this, aas, floorPos, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); - if ( !path.endEvent ) { - move.moveDir.z = -1.0f; - return true; - } - - // trace up to see if we can go over something and go forward - idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, 256.0f ), 1000, 1000, SE_BLOCKED, path ); - - idVec3 ceilingPos = path.endPos; - - for( z = org.z; z <= ceilingPos.z + 64.0f; z += 64.0f ) { - idVec3 start; - if ( z <= ceilingPos.z ) { - start.x = org.x; - start.y = org.y; - start.z = z; - } else { - start = ceilingPos; - } - idAI::PredictPath( this, aas, start, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); - if ( !path.endEvent ) { - move.moveDir.z = 1.0f; - return true; - } - } - return false; - } - - return ( path.endEvent == 0 ); -} -/* -================ -idAI::MoveAlongVector -================ -*/ -bool idAI::MoveAlongVector( float yaw ) -{ - StopMove( MOVE_STATUS_DONE ); - move.moveDir = idAngles( 0, yaw, 0 ).ToForward(); - move.moveDest = physicsObj.GetOrigin() + move.moveDir * 256.0f; - - move.moveCommand = MOVE_VECTOR; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - AI_MOVE_DONE = false; - AI_FORWARD = true; - m_pathRank = rank; // grayman #2345 - - return true; -} -/* -================ -idAI::NewWanderDir -================ -*/ -bool idAI::NewWanderDir( const idVec3 &dest ) { - float deltax, deltay; - float d[ 3 ]; - float tdir, olddir, turnaround; - - move.nextWanderTime = gameLocal.time + ( gameLocal.random.RandomInt(500) + 500 ); - - olddir = idMath::AngleNormalize360( ( int )( current_yaw / 45 ) * 45 ); - turnaround = idMath::AngleNormalize360( olddir - 180 ); - - idVec3 org = physicsObj.GetOrigin(); - deltax = dest.x - org.x; - deltay = dest.y - org.y; - if ( deltax > 10 ) { - d[ 1 ]= 0; - } else if ( deltax < -10 ) { - d[ 1 ] = 180; - } else { - d[ 1 ] = DI_NODIR; - } - - if ( deltay < -10 ) { - d[ 2 ] = 270; - } else if ( deltay > 10 ) { - d[ 2 ] = 90; - } else { - d[ 2 ] = DI_NODIR; - } - - // try direct route - if ( d[ 1 ] != DI_NODIR && d[ 2 ] != DI_NODIR ) { - if ( d[ 1 ] == 0 ) { - tdir = d[ 2 ] == 90 ? 45 : 315; - } else { - tdir = d[ 2 ] == 90 ? 135 : 215; - } - - if ( tdir != turnaround && StepDirection( tdir ) ) { - return true; - } - } - - // try other directions - if ( ( gameLocal.random.RandomInt() & 1 ) || fabs( deltay ) > fabs( deltax ) ) { - tdir = d[ 1 ]; - d[ 1 ] = d[ 2 ]; - d[ 2 ] = tdir; - } - - if ( d[ 1 ] != DI_NODIR && d[ 1 ] != turnaround && StepDirection( d[1] ) ) { - return true; - } - - if ( d[ 2 ] != DI_NODIR && d[ 2 ] != turnaround && StepDirection( d[ 2 ] ) ) { - return true; - } - - // there is no direct path to the player, so pick another direction - if ( olddir != DI_NODIR && StepDirection( olddir ) ) { - return true; - } - - // randomly determine direction of search - if ( gameLocal.random.RandomInt() & 1 ) { - for( tdir = 0; tdir <= 315; tdir += 45 ) { - if ( tdir != turnaround && StepDirection( tdir ) ) { - return true; - } - } - } else { - for ( tdir = 315; tdir >= 0; tdir -= 45 ) { - if ( tdir != turnaround && StepDirection( tdir ) ) { - return true; - } - } - } - - if ( turnaround != DI_NODIR && StepDirection( turnaround ) ) { - return true; - } - - // can't move - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); - return false; -} - -/* -===================== -idAI::GetMovePos -===================== -*/ -bool idAI::GetMovePos(idVec3 &seekPos) -{ - START_SCOPED_TIMING(aiGetMovePosTimer, scopedGetMovePosTimer); - - const idVec3& org = physicsObj.GetOrigin(); - seekPos = org; - - switch( move.moveCommand ) { - case MOVE_NONE : - seekPos = move.moveDest; - return false; - break; - - case MOVE_FACE_ENEMY : - case MOVE_FACE_ENTITY : - seekPos = move.moveDest; - return false; - break; - - case MOVE_TO_POSITION_DIRECT : - seekPos = move.moveDest; - if ( ReachedPos(move.moveDest, move.moveCommand)) - { - StopMove( MOVE_STATUS_DONE ); - } - return false; - break; - - case MOVE_SLIDE_TO_POSITION : - seekPos = org; - return false; - break; - - case MOVE_VECTOR : - seekPos = move.moveDest; - return true; - break; - default: - break; // Handled below (note the returns in all cases above) - // (default case added to suppress GCC warnings) - } - - if (move.moveCommand == MOVE_TO_ENTITY) { - MoveToEntity(move.goalEntity.GetEntity()); - } - - move.moveStatus = MOVE_STATUS_MOVING; - bool result = false; - - // Check if the blocking time has already expired - if (gameLocal.time > move.blockTime) - { - if (move.moveCommand == MOVE_WANDER) - { - move.moveDest = org + viewAxis[0] * physicsObj.GetGravityAxis() * 256.0f; - } - else - { - // Check if we already reached the destination position - if (ReachedPos(move.moveDest, move.moveCommand)) - { - // Yes, stop the move, move status is DONE - StopMove(MOVE_STATUS_DONE); - seekPos = org; - return false; // nothing to do, return false - } - } - - if (aas != NULL && move.toAreaNum != 0) - { - // Get the area number we're currently in. - int areaNum = PointReachableAreaNum(org); - - // Try to setup a path to the goal - aasPath_t path; - if (PathToGoal(path, areaNum, org, move.toAreaNum, move.moveDest, this)) - { - seekPos = path.moveGoal; - result = true; // We have a valid Path to the goal - move.nextWanderTime = 0; - - // angua: check whether there is a door in the path - if (path.firstDoor != NULL) - { - const idVec3& doorOrg = path.firstDoor->GetPhysics()->GetOrigin(); - const idVec3& org = GetPhysics()->GetOrigin(); - idVec3 dir = doorOrg - org; - dir.z = 0; - float dist = dir.LengthFast(); - if (dist < 500) - { - GetMind()->GetState()->OnFrobDoorEncounter(path.firstDoor); - } - } - } - else - { - AI_DEST_UNREACHABLE = true; - } - } - } - - if (!result) - { - // No path to the goal found, wander around - if (gameLocal.time > move.nextWanderTime || !StepDirection(move.wanderYaw)) - { - result = NewWanderDir(move.moveDest); - if (!result) - { - StopMove(MOVE_STATUS_DEST_UNREACHABLE); - AI_DEST_UNREACHABLE = true; - seekPos = org; - return false; - } - } - else - { - result = true; - } - - // Set the seek position to something far away, but in the right direction - seekPos = org + move.moveDir * 2048.0f; - - if (ai_debugMove.GetBool()) { - gameRenderWorld->DebugLine( colorYellow, org, seekPos, gameLocal.msec, true ); - } - } - else - { - // result == true, we have a valid path - AI_DEST_UNREACHABLE = false; - } - - if (result && ai_debugMove.GetBool()) { - gameRenderWorld->DebugLine( colorCyan, physicsObj.GetOrigin(), seekPos ); - } - - return result; -} - - -/* -===================== -The Dark Mod -idAI::CanSee virtual override -===================== -*/ -bool idAI::CanSee( idEntity *ent, bool useFOV ) const -{ - START_SCOPED_TIMING(aiCanSeeTimer, scopedCanSeeTimer); - - // Test if it is occluded, and use field of vision in the check (true as second parameter) - bool cansee = idActor::CanSee( ent, useFOV ); - - // Also consider lighting and visual acuity of AI - if (cansee) - { - cansee = !IsEntityHiddenByDarkness(ent, 0.1f); // tels: hard-coded threshold of 0.1f - } - - // Return result - return cansee; -} - -/* -===================== -The Dark Mod -idAI::CanSeeExt - -This method can ignore lighting conditions and/or field of vision. -===================== -*/ -bool idAI::CanSeeExt( idEntity *ent, const bool useFOV, const bool useLighting ) const -{ - // Test if it is occluded - bool cansee = idActor::CanSee( ent, useFOV ); - - if (cansee && useLighting) - { - cansee = !IsEntityHiddenByDarkness(ent, 0.1f); // tels: hard-coded threshold of 0.1f - } - - // Return result - return cansee; -} - -// grayman #2859 - Can the AI see a point belonging to a target (not necessarily its origin)? - -bool idAI::CanSeeTargetPoint( idVec3 point, idEntity* target ) const -{ - // Check FOV - - if ( !CheckFOV( point ) ) - { - return false; - } - - // Check visibility - - trace_t result; - idVec3 eye(GetEyePosition()); // eye position of the AI - - // Trace from eye to point, ignoring self - - gameLocal.clip.TracePoint(result, eye, point, MASK_OPAQUE, this); - if ( result.fraction < 1.0 ) - { - if ( gameLocal.GetTraceEntity(result) != target ) - { - return false; - } - } - - // Check lighting - - idVec3 topPoint = point - (physicsObj.GetGravityNormal() * 32.0); - float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(point, topPoint); - idVec3 ownOrigin = physicsObj.GetOrigin(); - - return ( ( ( point - ownOrigin).LengthSqr() ) < ( maxDistanceToObserve * maxDistanceToObserve ) ); // grayman #2866 -} - -/* -===================== -The Dark Mod -idAI::CanSeeRope - -grayman #2872 - This method takes lighting conditions and field of vision under consideration. -===================== -*/ -idVec3 idAI::CanSeeRope( idEntity *ent ) const -{ - // Find a point on the rope at the same elevation as the AI's eyes - - // ent is the projectile_result for the rope arrow. It's bound to the stuck rope arrow, - // which also has the rope bound to it. - - idEntity* bindMaster = ent->GetBindMaster(); - if ( bindMaster != NULL ) - { - idEntity* rope = bindMaster->FindMatchingTeamEntity( idAFEntity_Generic::Type ); - - if ( rope != NULL ) - { - idAFEntity_Generic* ropeAF = static_cast(rope); - const idDeclModelDef *modelDef = rope->GetAnimator()->ModelDef(); - idList jointList; - idStr jointNames = rope->spawnArgs.GetString("rope_joints"); // names of joints defined in the model file - modelDef->GetJointList(jointNames,jointList); - - // Randomly select a joint, and randomly select a point along the - // rope segmentbetween that joint and its lower neighbor - - int joint1Index = gameLocal.random.RandomInt( jointList.Num() - 1 ); - int joint2Index = joint1Index + 1; - - // safety net in case the joint names are corrupt - - if ( ( jointList[joint1Index] == INVALID_JOINT ) || ( jointList[joint2Index] == INVALID_JOINT ) ) - { - return idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); // failure - } - - idMat3 axis; - idVec3 joint1Org; - ropeAF->GetJointWorldTransform( jointList[joint1Index], gameLocal.time, joint1Org, axis ); - idVec3 joint2Org; - ropeAF->GetJointWorldTransform( jointList[joint2Index], gameLocal.time, joint2Org, axis ); - float offset = gameLocal.random.RandomFloat(); - idVec3 spot = joint1Org + ( joint2Org - joint1Org ) * offset; - if ( CanSeeTargetPoint( spot, rope ) ) - { - return spot; - } - } - } - - // Return result -// return CanSeeTargetPoint( point, ent ); // grayman #2872 - this has to move inside the part search loop above, exiting true at the first segment we can see - return idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); -} - -/* -===================== -The Dark Mod -idAI::CanSeePositionExt - -This method can ignore lighting conditions and/or field of vision. -===================== -*/ -bool idAI::CanSeePositionExt( idVec3 position, bool useFOV, bool useLighting ) -{ - if ( useFOV && !CheckFOV( position ) ) - { - return false; - } - - idVec3 ownOrigin = physicsObj.GetOrigin(); - - bool canSee = EntityCanSeePos (this, ownOrigin, position); - - if (canSee && useLighting) - { - idVec3 bottomPoint = position; - idVec3 topPoint = position - (physicsObj.GetGravityNormal() * 32.0); - - float maxDistanceToObserve = GetMaximumObservationDistanceForPoints(bottomPoint, topPoint); - - if ((position - ownOrigin).Length() > maxDistanceToObserve) - { - canSee = false; - } - - // Draw debug graphic? - if (cv_ai_visdist_show.GetFloat() > 1.0) - { - idVec3 midPoint = bottomPoint + ((topPoint-bottomPoint) / 2.0); - idVec3 observeFrom = GetEyePosition(); - - if (!canSee) - { - idVec4 markerColor (1.0, 0.0, 0.0, 0.0); - idVec4 markerColor2 (1.0, 0.0, 1.0, 0.0); - idVec3 arrowLength = midPoint - observeFrom; - arrowLength.Normalize(); - arrowLength *= maxDistanceToObserve; - - // Distance we could see - gameRenderWorld->DebugArrow - ( - markerColor, - observeFrom, - observeFrom + arrowLength, - 2, - cv_ai_visdist_show.GetInteger() - ); - - // Gap to where we want to see - gameRenderWorld->DebugArrow - ( - markerColor2, - observeFrom + arrowLength, - midPoint, - 2, - cv_ai_visdist_show.GetInteger() - ); - } - else - { - idVec4 markerColor (0.0, 1.0, 0.0, 0.0); - - // We can see there - gameRenderWorld->DebugArrow - ( - markerColor, - observeFrom, - midPoint, - 2, - cv_ai_visdist_show.GetInteger() - ); - } - } - } - - return canSee; -} - -/* -===================== -idAI::EntityCanSeePos -===================== -*/ -bool idAI::EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos ) -{ - pvsHandle_t handle = gameLocal.pvs.SetupCurrentPVS( actor->GetPVSAreas(), actor->GetNumPVSAreas() ); - - if ( !gameLocal.pvs.InCurrentPVS( handle, GetPVSAreas(), GetNumPVSAreas() ) ) { - gameLocal.pvs.FreeCurrentPVS( handle ); - return false; - } - - gameLocal.pvs.FreeCurrentPVS( handle ); - - idVec3 eye = actorOrigin + actor->EyeOffset(); - - idVec3 point = pos; - point[2] += 1.0f; - - physicsObj.DisableClip(); - - trace_t results; - gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); - if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { - physicsObj.EnableClip(); - return true; - } - - const idBounds &bounds = physicsObj.GetBounds(); - point[2] += bounds[1][2] - bounds[0][2]; - - gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); - physicsObj.EnableClip(); - if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { - return true; - } - - return false; -} - -/* -===================== -idAI::BlockedFailSafe -===================== -*/ -void idAI::BlockedFailSafe( void ) { - if ( !ai_blockedFailSafe.GetBool() || blockedRadius < 0.0f ) { - return; - } - if ( !physicsObj.OnGround() || enemy.GetEntity() == NULL || - ( physicsObj.GetOrigin() - move.lastMoveOrigin ).LengthSqr() > Square( blockedRadius ) ) { - move.lastMoveOrigin = physicsObj.GetOrigin(); - move.lastMoveTime = gameLocal.time; - } - if ( move.lastMoveTime < gameLocal.time - blockedMoveTime ) { - if ( lastAttackTime < gameLocal.time - blockedAttackTime ) { - AI_BLOCKED = true; - move.lastMoveTime = gameLocal.time; - } - } -} - -/*********************************************************************** - - turning - -***********************************************************************/ - -/* -===================== -idAI::Turn -===================== -*/ -void idAI::Turn(const idVec3& pivotOffset) { - float diff; - float diff2; - float turnAmount; - animFlags_t animflags; - - if ( !turnRate ) { - return; - } - - // check if the animator has marked this anim as non-turning - if ( !legsAnim.Disabled() && !legsAnim.AnimDone( 0 ) ) { - animflags = legsAnim.GetAnimFlags(); - } else { - animflags = torsoAnim.GetAnimFlags(); - } - if ( animflags.ai_no_turn ) { - return; - } - - idVec3 startPos = viewAxis * pivotOffset; - - if ( anim_turn_angles && animflags.anim_turn ) { - idMat3 rotateAxis; - - // set the blend between no turn and full turn - float frac = anim_turn_amount / anim_turn_angles; - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f - frac ); - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, frac ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f - frac ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, frac ); - - // get the total rotation from the start of the anim - animator.GetDeltaRotation( 0, gameLocal.time, rotateAxis ); - current_yaw = idMath::AngleNormalize180( anim_turn_yaw + rotateAxis[ 0 ].ToYaw() ); - } else { - diff = idMath::AngleNormalize180( ideal_yaw - current_yaw ); - turnVel += AI_TURN_SCALE * diff * MS2SEC( gameLocal.msec ); - if ( turnVel > turnRate ) { - turnVel = turnRate; - } else if ( turnVel < -turnRate ) { - turnVel = -turnRate; - } - turnAmount = turnVel * MS2SEC( gameLocal.time - m_lastThinkTime ); - if ( ( diff >= 0.0f ) && ( turnAmount >= diff ) ) { - turnVel = diff / MS2SEC( gameLocal.msec ); - turnAmount = diff; - } else if ( ( diff <= 0.0f ) && ( turnAmount <= diff ) ) { - turnVel = diff / MS2SEC( gameLocal.msec ); - turnAmount = diff; - } - current_yaw += turnAmount; - current_yaw = idMath::AngleNormalize180( current_yaw ); - diff2 = idMath::AngleNormalize180( ideal_yaw - current_yaw ); - if ( idMath::Fabs( diff2 ) < 0.1f ) { - current_yaw = ideal_yaw; - } - } - - viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); - - idVec3 endPos = viewAxis * pivotOffset; - - GetPhysics()->SetOrigin(GetPhysics()->GetOrigin() - idVec3(endPos - startPos)); - - if ( ai_debugMove.GetBool() ) { - const idVec3 &org = physicsObj.GetOrigin(); - gameRenderWorld->DebugLine( colorRed, org, org + idAngles( 0, ideal_yaw, 0 ).ToForward() * 64, gameLocal.msec ); - gameRenderWorld->DebugLine( colorGreen, org, org + idAngles( 0, current_yaw, 0 ).ToForward() * 48, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org, org + idAngles( 0, current_yaw + turnVel, 0 ).ToForward() * 32, gameLocal.msec ); - } -} - -/* -===================== -idAI::FacingIdeal -===================== -*/ -bool idAI::FacingIdeal( void ) { - float diff; - - if ( !turnRate ) { - return true; - } - - diff = idMath::AngleNormalize180( current_yaw - ideal_yaw ); - if ( idMath::Fabs( diff ) < 0.01f ) { - // force it to be exact - current_yaw = ideal_yaw; - return true; - } - - return false; -} - -/* -===================== -idAI::TurnToward -===================== -*/ -bool idAI::TurnToward( float yaw ) { - ideal_yaw = idMath::AngleNormalize180( yaw ); - bool result = FacingIdeal(); - return result; -} - -/* -===================== -idAI::TurnToward -===================== -*/ -bool idAI::TurnToward( const idVec3 &pos ) { - idVec3 dir; - idVec3 local_dir; - float lengthSqr; - - dir = pos - physicsObj.GetOrigin(); - physicsObj.GetGravityAxis().ProjectVector( dir, local_dir ); - local_dir.z = 0.0f; - lengthSqr = local_dir.LengthSqr(); - if ( lengthSqr > Square( 2.0f ) || ( lengthSqr > Square( 0.1f ) && enemy.GetEntity() == NULL ) ) { - ideal_yaw = idMath::AngleNormalize180( local_dir.ToYaw() ); - } - - bool result = FacingIdeal(); - return result; -} - -/*********************************************************************** - - Movement - -***********************************************************************/ - -/* -================ -idAI::ApplyImpulse -================ -*/ -void idAI::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - // FIXME: Jim take a look at this and see if this is a reasonable thing to do - // instead of a spawnArg flag.. Sabaoth is the only slide monster ( and should be the only one for D3 ) - // and we don't want him taking physics impulses as it can knock him off the path - if ( move.moveType != MOVETYPE_STATIC && move.moveType != MOVETYPE_SLIDE ) { - idActor::ApplyImpulse( ent, id, point, impulse ); - } -} - -/* -===================== -idAI::GetMoveDelta -===================== -*/ -void idAI::GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta ) -{ - // Get the delta from the animation system (for one frame) and transform it - // animator.GetDelta( gameLocal.time - gameLocal.msec, gameLocal.time, delta); - - // angua: distance from last thinking time - animator.GetDelta( m_lastThinkTime, gameLocal.time, delta); - - delta = axis * delta; - - if ( modelOffset != vec3_zero ) - { - // the pivot of the monster's model is around its origin, and not around the bounding - // box's origin, so we have to compensate for this when the model is offset so that - // the monster still appears to rotate around its origin. - idVec3 oldModelOrigin = modelOffset * oldaxis; - idVec3 modelOrigin = modelOffset * axis; - - delta += oldModelOrigin - modelOrigin; - } - - delta *= physicsObj.GetGravityAxis(); -} - -/* -===================== -idAI::CheckObstacleAvoidance -===================== -*/ -void idAI::CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ) -{ - START_SCOPED_TIMING(aiObstacleAvoidanceTimer, scopedObstacleAvoidanceTimer); - - newPos = goalPos; // grayman #2345 - initialize newPos in case nothing changes. - // Without this, there's a return from this function - // that leaves newPos = [0,0,0], so the AI thinks he - // has to go to the world origin, which is a bug. - - if (ignore_obstacles || cv_ai_opt_noobstacleavoidance.GetBool()) - { - move.obstacle = NULL; - return; - } - - if (cv_ai_goalpos_show.GetBool()) - { - idVec4 color(colorCyan); - color.x = gameLocal.random.RandomFloat(); - color.y = gameLocal.random.RandomFloat(); - color.z = gameLocal.random.RandomFloat(); - gameRenderWorld->DebugArrow(color, goalPos, goalPos + idVec3(0,0,15), 2, 16); - } - - const idVec3& origin = physicsObj.GetOrigin(); - - idEntity* obstacle = NULL; - obstaclePath_t path; - - AI_OBSTACLE_IN_PATH = false; - bool foundPath = FindPathAroundObstacles( &physicsObj, aas, enemy.GetEntity(), origin, goalPos, path, this ); - - if ( ai_showObstacleAvoidance.GetBool()) - { - gameRenderWorld->DebugLine( colorBlue, goalPos + idVec3( 1.0f, 1.0f, 0.0f ), goalPos + idVec3( 1.0f, 1.0f, 64.0f ), gameLocal.msec ); - gameRenderWorld->DebugLine( foundPath ? colorYellow : colorRed, path.seekPos, path.seekPos + idVec3( 0.0f, 0.0f, 64.0f ), gameLocal.msec ); - } - - if (!foundPath) - { - // couldn't get around obstacles - - if (path.doorObstacle != NULL) - { - // We have a frobmover in our way, raise a signal to the current state - mind->GetState()->OnFrobDoorEncounter(path.doorObstacle); - } - - if (path.firstObstacle) - { - AI_OBSTACLE_IN_PATH = true; - - if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.firstObstacle->GetPhysics()->GetAbsBounds() ) ) - { - // We are already touching the first obstacle - obstacle = path.firstObstacle; - } - } - else if (path.startPosObstacle) - { - AI_OBSTACLE_IN_PATH = true; - if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.startPosObstacle->GetPhysics()->GetAbsBounds() ) ) - { - // We are touching the startpos obstacle - obstacle = path.startPosObstacle; - } - } - else - { - // No firstObstacle, no startPosObstacle, must be blocked by wall - move.moveStatus = MOVE_STATUS_BLOCKED_BY_WALL; - } -#if 0 - } else if ( path.startPosObstacle ) { - // check if we're past where the our origin was pushed out of the obstacle - dir = goalPos - origin; - dir.Normalize(); - dist = ( path.seekPos - origin ) * dir; - if ( dist < 1.0f ) { - AI_OBSTACLE_IN_PATH = true; - obstacle = path.startPosObstacle; - } -#endif - } - else - { - // We found a path around obstacles - if (path.doorObstacle != NULL) // grayman #2712 - do we have to handle a door? - { - // We have a frobmover in our way, raise a signal to the current state - mind->GetState()->OnFrobDoorEncounter(path.doorObstacle); - } - - // still check for the seekPosObstacle - if (path.seekPosObstacle) - { - /* gameRenderWorld->DebugBox(foundPath ? colorGreen : colorRed, idBox(path.seekPosObstacle->GetPhysics()->GetBounds(), - path.seekPosObstacle->GetPhysics()->GetOrigin(), - path.seekPosObstacle->GetPhysics()->GetAxis()), 16); - */ - - // greebo: Check if we have a frobdoor entity at our seek position - if (path.seekPosObstacle->IsType(CFrobDoor::Type)) - { - // We have a frobmover in our way, raise a signal to the current state - mind->GetState()->OnFrobDoorEncounter(static_cast(path.seekPosObstacle)); - } - - // if the AI is very close to the path.seekPos already and path.seekPosObstacle != NULL - // then we want to push the path.seekPosObstacle entity out of the way - AI_OBSTACLE_IN_PATH = true; - - // check if we're past where the goalPos was pushed out of the obstacle - idVec3 dir = goalPos - origin; - dir.NormalizeFast(); - float dist = (path.seekPos - origin) * dir; - if (dist < 1.0f) - { - obstacle = path.seekPosObstacle; - } - } - } - - // If we don't have an obstacle, set the seekpos and return - if (obstacle == NULL) - { - newPos = path.seekPos; - move.obstacle = NULL; - return; - } - - // if we had an obstacle, set our move status based on the type, and kick it out of the way if it's a moveable - if (obstacle->IsType(idActor::Type)) - { - // monsters aren't kickable - move.moveStatus = (obstacle == enemy.GetEntity()) ? MOVE_STATUS_BLOCKED_BY_ENEMY : MOVE_STATUS_BLOCKED_BY_MONSTER; - } - else - { - // If it's a door handle, switch the obstacle to the door so we don't get all hung - // up on door handles - if (obstacle->IsType(CFrobDoorHandle::Type)) - { - // Make the obstacle the door itself - obstacle = static_cast(obstacle)->GetDoor(); - } - - // Handle doors - if (obstacle->IsType(CFrobDoor::Type)) - { - // Try to open doors - CFrobDoor* p_door = static_cast(obstacle); - - // We have a frobmover in our way, raise a signal to the current state - mind->GetState()->OnFrobDoorEncounter(p_door); - } - - // Try backing away - newPos = obstacle->GetPhysics()->GetOrigin(); - idVec3 obstacleDelta = obstacle->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - - obstacleDelta.NormalizeFast(); - obstacleDelta *= 128.0; - - newPos = obstacle->GetPhysics()->GetOrigin() - obstacleDelta; - move.moveStatus = MOVE_STATUS_BLOCKED_BY_OBJECT; - } - - move.obstacle = obstacle; -} - -/* -===================== -idAI::CanPassThroughDoor - Is the AI allowed through this door? (grayman #2691) -===================== -*/ - -bool idAI::CanPassThroughDoor(CFrobDoor* frobDoor) -{ - // grayman #2691 - quick test for spawnarg that appears on many furniture doors - - if (frobDoor->spawnArgs.GetBool("immune_to_target_setfrobable", "0")) - { - return false; - } - - // grayman #2691 - can't pass through doors that don't rotate on the z-axis - - idVec3 rotationAxis = frobDoor->GetRotationAxis(); - if ((rotationAxis.z == 0) && ((rotationAxis.x != 0) || (rotationAxis.y != 0))) // grayman #2712 - handles sliding doors - { - return false; - } - - idBounds door1Bounds = frobDoor->GetPhysics()->GetBounds(); - idBounds myBounds = GetPhysics()->GetBounds(); - idVec3 door1Size = door1Bounds.GetSize(); - idVec3 mySize = myBounds.GetSize(); - bool canPassDoor1 = (door1Size.x > mySize.x) || (door1Size.y > mySize.y); - if (canPassDoor1) - { - return true; - } - - // The AI can't fit through the first door. Is this door part of a double door? - - CFrobDoor* doubleDoor = frobDoor->GetDoubleDoor(); - if (doubleDoor != NULL) - { - idBounds door2Bounds = doubleDoor->GetPhysics()->GetBounds(); - idVec3 door2Size = door2Bounds.GetSize(); - bool canPassDoors = ((door1Size.x + door2Size.x) > mySize.x) || ((door1Size.y + door2Size.y) > mySize.y); - if (canPassDoors) - { - return true; - } - } - - return false; -} - -/* -===================== -idAI::GetTorch - Is the AI carrying a torch? (grayman #2603) -===================== -*/ - -idEntity* idAI::GetTorch() -{ - idEntity* ent = GetAttachmentByPosition("hand_l"); - if (ent && ent->spawnArgs.GetBool("is_torch","0")) - { - return ent; // found a torch - } - - // Torches are carried in the left hand. If a torch for - // the right hand, plus accompanying animations, is ever - // created, uncomment the following section. -/* - ent = GetAttachmentByPosition("hand_r"); - if (ent && ent->spawnArgs.GetBool("is_torch","0")) - { - return ent; // found a torch - } - */ - - return NULL; // no luck -} - -/* -===================== -idAI::DeadMove -===================== -*/ -void idAI::DeadMove( void ) { - idVec3 delta; - monsterMoveResult_t moveResult; - - idVec3 org = physicsObj.GetOrigin(); - - GetMoveDelta( viewAxis, viewAxis, delta ); - physicsObj.SetDelta( delta ); - - RunPhysics(); - - moveResult = physicsObj.GetMoveResult(); - AI_ONGROUND = physicsObj.OnGround(); -} - -/* -===================== -idAI::AnimMove -===================== -*/ -void idAI::AnimMove() -{ - START_SCOPED_TIMING(aiAnimMoveTimer, scopedAnimMoveTimer); - - idVec3 goalPos; - idVec3 goalDelta; - - idVec3 oldorigin = physicsObj.GetOrigin(); - idMat3 oldaxis = viewAxis; - - AI_BLOCKED = false; - - if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ - move.lastMoveOrigin.Zero(); - move.lastMoveTime = gameLocal.time; - } - - move.obstacle = NULL; - if (move.moveCommand == MOVE_FACE_ENEMY && enemy.GetEntity()) - { - TurnToward( lastVisibleEnemyPos ); - goalPos = oldorigin; - } - else if (move.moveCommand == MOVE_FACE_ENTITY && move.goalEntity.GetEntity()) - { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - goalPos = oldorigin; - } - else if (GetMovePos(goalPos)) - { - // greebo: We have a valid goalposition (not reached the target yet), check for obstacles - if (move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_VECTOR) - { - idVec3 newDest; - CheckObstacleAvoidance( goalPos, newDest ); - TurnToward(newDest); - } - else // MOVE_WANDER || MOVE_VECTOR - { - TurnToward(goalPos); - } - } - - // greebo: This should take care of rats running around in circles around their goal - // due to not turning fast enough to their goalPos, sending them into a stable orbit. - float oldTurnRate = turnRate; - - if ((goalPos - physicsObj.GetOrigin()).LengthSqr() < Square(50)) - { - turnRate *= gameLocal.random.RandomFloat() + 1; - } - - // greebo: Now actually turn towards the "ideal" yaw. - Turn(); - - // Revert the turnRate changes - turnRate = oldTurnRate; - - // Determine the delta depending on the move type - idVec3 delta(0,0,0); - if (move.moveCommand == MOVE_SLIDE_TO_POSITION) - { - if ( gameLocal.time < move.startTime + move.duration ) { - goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); - delta = goalPos - oldorigin; - delta.z = 0.0f; - } else { - delta = move.moveDest - oldorigin; - delta.z = 0.0f; - StopMove(MOVE_STATUS_DONE); - } - } - else if (allowMove) - { - // Moving is allowed, get the delta - GetMoveDelta( oldaxis, viewAxis, delta ); - } - - if ( move.moveCommand == MOVE_TO_POSITION ) { - goalDelta = move.moveDest - oldorigin; - float goalDist = goalDelta.LengthFast(); - if ( goalDist < delta.LengthFast() ) { - delta = goalDelta; - } - } - - physicsObj.SetDelta( delta ); - physicsObj.ForceDeltaMove( disableGravity ); - - { - START_SCOPED_TIMING(aiPhysicsTimer, scopedPhysicsTimer); - RunPhysics(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); - } - - monsterMoveResult_t moveResult = physicsObj.GetMoveResult(); - if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt) - { - if (blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) - { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); - } - } - } - - BlockedFailSafe(); - - AI_ONGROUND = physicsObj.OnGround(); - - const idVec3& org = physicsObj.GetOrigin(); - if (oldorigin != org) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } -} - -/* -===================== -idAI::SittingMove -===================== -*/ -void idAI::SittingMove() -{ - idVec3 goalPos; - idVec3 goalDelta; - monsterMoveResult_t moveResult; - idVec3 newDest; - - idVec3 oldorigin = physicsObj.GetOrigin(); - idMat3 oldaxis = viewAxis; - - AI_BLOCKED = false; - - RunPhysics(); - - Turn(sitting_turn_pivot); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); - } - - moveResult = physicsObj.GetMoveResult(); - - AI_ONGROUND = physicsObj.OnGround(); - - const idVec3& org = physicsObj.GetOrigin(); - if (oldorigin != org) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } -} - -void idAI::NoTurnMove() -{ - idVec3 oldorigin = physicsObj.GetOrigin(); - idMat3 oldaxis = viewAxis; - - AI_BLOCKED = false; - - RunPhysics(); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); - } - - - AI_ONGROUND = physicsObj.OnGround(); - - const idVec3& org = physicsObj.GetOrigin(); - if (oldorigin != org) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } - -} - - - -void idAI::LayDownMove() -{ - idVec3 oldorigin(physicsObj.GetOrigin()); - idMat3 oldaxis(viewAxis); - - AI_BLOCKED = false; - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); - } - - AI_ONGROUND = physicsObj.OnGround(); - - // angua: Let the animation move the origin onto the bed - idVec3 delta; - GetMoveDelta( oldaxis, viewAxis, delta ); - - physicsObj.SetDelta( delta ); - physicsObj.ForceDeltaMove( disableGravity ); - - RunPhysics(); - - const idVec3& org = physicsObj.GetOrigin(); - if (oldorigin != org) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } -} - - -/* -===================== -Seek -===================== -*/ -idVec3 Seek( idVec3 &vel, const idVec3 &org, const idVec3 &goal, float prediction ) { - idVec3 predictedPos; - idVec3 goalDelta; - idVec3 seekVel; - - // predict our position - predictedPos = org + vel * prediction; - goalDelta = goal - predictedPos; - seekVel = goalDelta * MS2SEC( gameLocal.msec ); - - return seekVel; -} - -/* -===================== -idAI::SlideMove -===================== -*/ -void idAI::SlideMove( void ) { - idVec3 goalPos; - idVec3 delta; - idVec3 goalDelta; - float goalDist; - monsterMoveResult_t moveResult; - idVec3 newDest; - - idVec3 oldorigin = physicsObj.GetOrigin(); - idMat3 oldaxis = viewAxis; - - AI_BLOCKED = false; - - if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ - move.lastMoveOrigin.Zero(); - move.lastMoveTime = gameLocal.time; - } - - move.obstacle = NULL; - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { - TurnToward( lastVisibleEnemyPos ); - goalPos = move.moveDest; - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - goalPos = move.moveDest; - } else if ( GetMovePos( goalPos ) ) { - CheckObstacleAvoidance( goalPos, newDest ); - TurnToward( newDest ); - goalPos = newDest; - } - - if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) { - if ( gameLocal.time < move.startTime + move.duration ) { - goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); - } else { - goalPos = move.moveDest; - StopMove( MOVE_STATUS_DONE ); - } - } - - if ( move.moveCommand == MOVE_TO_POSITION ) { - goalDelta = move.moveDest - oldorigin; - goalDist = goalDelta.LengthFast(); - if ( goalDist < delta.LengthFast() ) { - delta = goalDelta; - } - } - - idVec3 vel = physicsObj.GetLinearVelocity(); - float z = vel.z; - idVec3 predictedPos = oldorigin + vel * AI_SEEK_PREDICTION; - - // seek the goal position - goalDelta = goalPos - predictedPos; - vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); - vel += goalDelta * MS2SEC( gameLocal.msec ); - - // cap our speed - vel.Truncate( fly_speed ); - vel.z = z; - physicsObj.SetLinearVelocity( vel ); - physicsObj.UseVelocityMove( true ); - RunPhysics(); - - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.moveCommand != MOVE_NONE ) { - if ( vel.ToVec2().LengthSqr() > 0.1f ) { - TurnToward( vel.ToYaw() ); - } - } - - Turn(); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); - } - - moveResult = physicsObj.GetMoveResult(); - if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); - } - } - - BlockedFailSafe(); - - AI_ONGROUND = physicsObj.OnGround(); - - idVec3 org = physicsObj.GetOrigin(); - if ( oldorigin != org ) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } -} - -/* -===================== -idAI::AdjustFlyingAngles -===================== -*/ -void idAI::AdjustFlyingAngles( void ) { - idVec3 vel; - float speed; - float roll; - float pitch; - - vel = physicsObj.GetLinearVelocity(); - - speed = vel.Length(); - if ( speed < 5.0f ) { - roll = 0.0f; - pitch = 0.0f; - } else { - roll = vel * viewAxis[ 1 ] * -fly_roll_scale / fly_speed; - if ( roll > fly_roll_max ) { - roll = fly_roll_max; - } else if ( roll < -fly_roll_max ) { - roll = -fly_roll_max; - } - - pitch = vel * viewAxis[ 2 ] * -fly_pitch_scale / fly_speed; - if ( pitch > fly_pitch_max ) { - pitch = fly_pitch_max; - } else if ( pitch < -fly_pitch_max ) { - pitch = -fly_pitch_max; - } - } - - fly_roll = fly_roll * 0.95f + roll * 0.05f; - fly_pitch = fly_pitch * 0.95f + pitch * 0.05f; - - if ( flyTiltJoint != INVALID_JOINT ) { - animator.SetJointAxis( flyTiltJoint, JOINTMOD_WORLD, idAngles( fly_pitch, 0.0f, fly_roll ).ToMat3() ); - } else { - viewAxis = idAngles( fly_pitch, current_yaw, fly_roll ).ToMat3(); - } -} - -/* -===================== -idAI::AddFlyBob -===================== -*/ -void idAI::AddFlyBob( idVec3 &vel ) { - idVec3 fly_bob_add; - float t; - - if ( fly_bob_strength ) { - t = MS2SEC( gameLocal.time + entityNumber * 497 ); - fly_bob_add = ( viewAxis[ 1 ] * idMath::Sin16( t * fly_bob_horz ) + viewAxis[ 2 ] * idMath::Sin16( t * fly_bob_vert ) ) * fly_bob_strength; - vel += fly_bob_add * MS2SEC( gameLocal.msec ); - if ( ai_debugMove.GetBool() ) { - const idVec3 &origin = physicsObj.GetOrigin(); - gameRenderWorld->DebugArrow( colorOrange, origin, origin + fly_bob_add, 0 ); - } - } -} - -/* -===================== -idAI::AdjustFlyHeight -===================== -*/ -void idAI::AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ) { - const idVec3 &origin = physicsObj.GetOrigin(); - predictedPath_t path; - idVec3 end; - idVec3 dest; - trace_t trace; - idActor *enemyEnt; - bool goLower; - - // make sure we're not flying too high to get through doors - goLower = false; - if ( origin.z > goalPos.z ) { - dest = goalPos; - dest.z = origin.z + 128.0f; - idAI::PredictPath( this, aas, goalPos, dest - origin, 1000, 1000, SE_BLOCKED, path ); - if ( path.endPos.z < origin.z ) { - idVec3 addVel = Seek( vel, origin, path.endPos, AI_SEEK_PREDICTION ); - vel.z += addVel.z; - goLower = true; - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( goLower ? colorRed : colorGreen, physicsObj.GetBounds(), path.endPos, gameLocal.msec ); - } - } - - if ( !goLower ) { - // make sure we don't fly too low - end = origin; - - enemyEnt = enemy.GetEntity(); - if ( enemyEnt ) { - end.z = lastVisibleEnemyPos.z + lastVisibleEnemyEyeOffset.z + fly_offset; - } else { - // just use the default eye height for the player - end.z = goalPos.z + DEFAULT_FLY_OFFSET + fly_offset; - } - - gameLocal.clip.Translation( trace, origin, end, physicsObj.GetClipModel(), mat3_identity, MASK_MONSTERSOLID, this ); - vel += Seek( vel, origin, trace.endpos, AI_SEEK_PREDICTION ); - } -} - -/* -===================== -idAI::FlySeekGoal -===================== -*/ -void idAI::FlySeekGoal( idVec3 &vel, idVec3 &goalPos ) { - idVec3 seekVel; - - // seek the goal position - seekVel = Seek( vel, physicsObj.GetOrigin(), goalPos, AI_SEEK_PREDICTION ); - seekVel *= fly_seek_scale; - vel += seekVel; -} - -/* -===================== -idAI::AdjustFlySpeed -===================== -*/ -void idAI::AdjustFlySpeed( idVec3 &vel ) { - float speed; - - // apply dampening - vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); - - // gradually speed up/slow down to desired speed - speed = vel.Normalize(); - speed += ( move.speed - speed ) * MS2SEC( gameLocal.msec ); - if ( speed < 0.0f ) { - speed = 0.0f; - } else if ( move.speed && ( speed > move.speed ) ) { - speed = move.speed; - } - - vel *= speed; -} - -/* -===================== -idAI::FlyTurn -===================== -*/ -void idAI::FlyTurn( void ) { - if ( move.moveCommand == MOVE_FACE_ENEMY ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.speed > 0.0f ) { - const idVec3 &vel = physicsObj.GetLinearVelocity(); - if ( vel.ToVec2().LengthSqr() > 0.1f ) { - TurnToward( vel.ToYaw() ); - } - } - Turn(); -} - -/* -===================== -idAI::FlyMove -===================== -*/ -void idAI::FlyMove( void ) { - idVec3 goalPos; - idVec3 oldorigin; - idVec3 newDest; - - AI_BLOCKED = false; - if ( ( move.moveCommand != MOVE_NONE ) && ReachedPos( move.moveDest, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); - } - - if ( ai_debugMove.GetBool() ) { - gameLocal.Printf( "%d: %s: %s, vel = %.2f, sp = %.2f, maxsp = %.2f\n", gameLocal.time, name.c_str(), moveCommandString[ move.moveCommand ], physicsObj.GetLinearVelocity().Length(), move.speed, fly_speed ); - } - - if ( move.moveCommand != MOVE_TO_POSITION_DIRECT ) { - idVec3 vel = physicsObj.GetLinearVelocity(); - - if ( GetMovePos( goalPos ) ) { - CheckObstacleAvoidance( goalPos, newDest ); - goalPos = newDest; - } - - if ( move.speed ) { - FlySeekGoal( vel, goalPos ); - } - - // add in bobbing - AddFlyBob( vel ); - - if ( enemy.GetEntity() && ( move.moveCommand != MOVE_TO_POSITION ) ) { - AdjustFlyHeight( vel, goalPos ); - } - - AdjustFlySpeed( vel ); - - physicsObj.SetLinearVelocity( vel ); - } - - // turn - FlyTurn(); - - // run the physics for this frame - oldorigin = physicsObj.GetOrigin(); - physicsObj.UseFlyMove( true ); - physicsObj.UseVelocityMove( false ); - physicsObj.SetDelta( vec3_zero ); - physicsObj.ForceDeltaMove( disableGravity ); - RunPhysics(); - - monsterMoveResult_t moveResult = physicsObj.GetMoveResult(); - if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); - } else if ( moveResult == MM_BLOCKED ) { - move.blockTime = gameLocal.time + 500; - AI_BLOCKED = true; - } - } - - idVec3 org = physicsObj.GetOrigin(); - if ( oldorigin != org ) { - TouchTriggers(); - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 4000 ); - gameRenderWorld->DebugBounds( colorOrange, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorRed, org, org + physicsObj.GetLinearVelocity(), gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorBlue, org, goalPos, gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - DrawRoute(); - } -} - -/* -===================== -idAI::StaticMove -===================== -*/ -void idAI::StaticMove( void ) { - idActor *enemyEnt = enemy.GetEntity(); - - if ( AI_DEAD || AI_KNOCKEDOUT ) { - return; - } - - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemyEnt ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.moveCommand != MOVE_NONE ) { - TurnToward( move.moveDest ); - } - Turn(); - - physicsObj.ForceDeltaMove( true ); // disable gravity - RunPhysics(); - - AI_ONGROUND = false; - - if ( !m_bAFPushMoveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemyEnt ); - } - - if ( ai_debugMove.GetBool() ) { - const idVec3 &org = physicsObj.GetOrigin(); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugLine( colorBlue, org, move.moveDest, gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); - } -} - -void idAI::Bark(const idStr& soundName) -{ - - // Allocate a singlebarktask with the given sound and enqueue it - commSubsystem->AddCommTask( - ai::CommunicationTaskPtr(new ai::SingleBarkTask(soundName)) - ); -} - -void idAI::PlayFootStepSound() -{ - idStr moveType, localSound, sound; - idMaterial *material = NULL; - const idSoundShader *sndShader = NULL; - - if ( !GetPhysics()->HasGroundContacts() ) { - return; - } - - // greebo: Don't play footsteps in ragdoll mode - if (!GetPhysics()->IsType(idPhysics_Actor::Type)) - { - return; - } - - // DarkMod: make the string to identify the movement speed (crouch_run, creep, etc) - // Currently only players have movement flags set up this way, not AI. We could change that later. - moveType.Clear(); - - if (AI_CROUCH) - { - moveType = "_crouch"; - } - - if (AI_RUN) - { - moveType += "_run"; - } - else if (AI_CREEP) - { - moveType += "_creep"; - } - else - { - moveType += "_walk"; - } - - // start footstep sound based on material type - material = const_cast(GetPhysics()->GetContact(0).material); - localSound = ""; // grayman #2787 - if (material != NULL) - { - g_Global.GetSurfName(material, localSound); - localSound = "snd_footstep_" + localSound; -// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 - } - - waterLevel_t waterLevel = static_cast(GetPhysics())->GetWaterLevel(); - // If player is walking in liquid, replace the bottom surface sound with water sounds - if (waterLevel == WATERLEVEL_FEET ) - { - localSound = "snd_footstep_puddle"; -// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 - } - else if (waterLevel == WATERLEVEL_WAIST) - { - localSound = "snd_footstep_wading"; -// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 - } - // greebo: Added this to disable the walking sound when completely underwater - // this should be replaced by snd_ - else if (waterLevel == WATERLEVEL_HEAD) - { - localSound = "snd_footstep_swim"; -// sound = spawnArgs.GetString( localSound.c_str() ); // grayman #2787 - } - - if ( localSound.IsEmpty() && ( waterLevel != WATERLEVEL_HEAD ) ) // grayman #2787 - { - localSound = "snd_footstep"; - } - - sound = spawnArgs.GetString( localSound.c_str() ); - -/* grayman #2787 - redundant - - // if a sound was not found for that specific material, use default - if ( sound.IsEmpty() && ( waterLevel != WATERLEVEL_HEAD ) ) - { - sound = spawnArgs.GetString( "snd_footstep" ); - localSound = "snd_footstep"; - } - */ - - /*** - * AI footsteps always propagate as snd_footstep for now - * If we want to add in AI soundprop based on movement speed later, - * here is the place to do it. - **/ -/* - localSound += moveType; - if( !gameLocal.m_sndProp->CheckSound( localSound.c_str(), false ) ) - localSound -= moveType; -*/ - - if ( !sound.IsEmpty() ) - { - // apply the movement type modifier to the volume - sndShader = declManager->FindSound( sound.c_str() ); - SetSoundVolume( sndShader->GetParms()->volume + GetMovementVolMod() ); - StartSoundShader( sndShader, SND_CHANNEL_BODY, 0, false, NULL ); - SetSoundVolume( 0.0f ); - - // propagate the suspicious sound to other AI - PropSoundDirect( localSound, true, false ); - } -} - -/*********************************************************************** - - Damage - -***********************************************************************/ - -/* -===================== -idAI::ReactionTo - -DarkMod : Added call to AI Relationship Manager - We don't have to hardcode this, could be done - with scripts, but for now it's hardcoded for - testing purposes. -===================== -*/ -int idAI::ReactionTo( const idEntity *ent ) -{ - if ( ent->fl.hidden ) - { - // ignore hidden entities - return ATTACK_IGNORE; - } - - if ( !ent->IsType( idActor::Type ) ) { - return ATTACK_IGNORE; - } - - const idActor *actor = static_cast( ent ); - if ( actor->IsType( idPlayer::Type ) && static_cast(actor)->noclip ) { - // ignore players in noclip mode - return ATTACK_IGNORE; - } - - // actors will always fight if their teams are enemies - if ( IsEnemy(actor) ) - { - if ( actor->fl.notarget ) - { - // don't attack on sight when attacker is notargeted - return ATTACK_ON_DAMAGE | ATTACK_ON_ACTIVATE; - } - return ATTACK_ON_SIGHT | ATTACK_ON_DAMAGE | ATTACK_ON_ACTIVATE; - } - - // monsters will fight when attacked by lower ranked monsters. rank 0 never fights back. - if ( rank && ( actor->rank < rank ) ) { - return ATTACK_ON_DAMAGE; - } - - // don't fight back - return ATTACK_IGNORE; -} - - -/* -===================== -idAI::Pain -===================== -*/ -bool idAI::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ) -{ - AI_PAIN = idActor::Pain( inflictor, attacker, damage, dir, location, damageDef ); - AI_DAMAGE = true; - - // force a blink - blink_time = 0; - - // ignore damage from self - if ( attacker != this ) - { - if ( inflictor ) - { - AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); - } else - { - AI_SPECIAL_DAMAGE = 0; - } - - // AI don't like being attacked - ChangeEntityRelation(attacker, -10); - - // Switch to pain state if idle - if (AI_AlertIndex == 0 && damage > 0 && - (damageDef == NULL || !damageDef->GetBool("no_pain_anim", "0"))) - { - GetMind()->PushState(ai::StatePtr(new ai::PainState)); - } - } - - return ( AI_PAIN != 0 ); -} - - -/* -===================== -idAI::SpawnParticles -===================== -*/ -void idAI::SpawnParticles( const char *keyName ) { - const idKeyValue *kv = spawnArgs.MatchPrefix( keyName, NULL ); - while ( kv ) { - particleEmitter_t pe; - - idStr particleName = kv->GetValue(); - - if ( particleName.Length() ) { - - idStr jointName = kv->GetValue(); - int dash = jointName.Find('-'); - if ( dash > 0 ) { - particleName = particleName.Left( dash ); - jointName = jointName.Right( jointName.Length() - dash - 1 ); - } - - SpawnParticlesOnJoint( pe, particleName, jointName ); - particles.Append( pe ); - } - - kv = spawnArgs.MatchPrefix( keyName, kv ); - } -} - -/* -===================== -idAI::SpawnParticlesOnJoint -===================== -*/ -const idDeclParticle *idAI::SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName ) { - idVec3 origin; - idMat3 axis; - - if ( *particleName == '\0' ) { - memset( &pe, 0, sizeof( pe ) ); - return pe.particle; - } - - pe.joint = animator.GetJointHandle( jointName ); - if ( pe.joint == INVALID_JOINT ) { - gameLocal.Warning( "Unknown particleJoint '%s' on '%s'", jointName, name.c_str() ); - pe.time = 0; - pe.particle = NULL; - } else { - animator.GetJointTransform( pe.joint, gameLocal.time, origin, axis ); - origin = renderEntity.origin + origin * renderEntity.axis; - - BecomeActive( TH_UPDATEPARTICLES ); - if ( !gameLocal.time ) { - // particles with time of 0 don't show, so set the time differently on the first frame - pe.time = 1; - } else { - pe.time = gameLocal.time; - } - pe.particle = static_cast( declManager->FindType( DECL_PARTICLE, particleName ) ); - gameLocal.smokeParticles->EmitSmoke( pe.particle, pe.time, gameLocal.random.CRandomFloat(), origin, axis ); - } - - return pe.particle; -} - -/* -===================== -idAI::Killed -===================== -*/ -void idAI::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) -{ - idAngles ang; - const char *modelDeath; - bool bPlayerResponsible(false); - - // make sure the monster is activated - EndAttack(); - - if ( g_debugDamage.GetBool() ) { - gameLocal.Printf( "Damage: joint: '%s', zone '%s'\n", animator.GetJointName( ( jointHandle_t )location ), - GetDamageGroup( location ) ); - } - - if ( inflictor ) { - AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); - } else { - AI_SPECIAL_DAMAGE = 0; - } - - if ( AI_DEAD ) { - AI_PAIN = true; - AI_DAMAGE = true; - return; - } - - // stop all voice sounds - StopSound( SND_CHANNEL_VOICE, false ); - if ( head.GetEntity() ) { - head.GetEntity()->StopSound( SND_CHANNEL_VOICE, false ); - head.GetEntity()->GetAnimator()->ClearAllAnims( gameLocal.time, 100 ); - } - - disableGravity = false; - move.moveType = MOVETYPE_DEAD; - m_bAFPushMoveables = false; - - physicsObj.UseFlyMove( false ); - physicsObj.ForceDeltaMove( false ); - - // end our looping ambient sound - StopSound( SND_CHANNEL_AMBIENT, false ); - - // activate targets - ActivateTargets( attacker ); - - RemoveAttachments(); - RemoveProjectile(); - StopMove( MOVE_STATUS_DONE ); - GetMemory().stopRelight = true; // grayman #2603 - abort a relight in progress - GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope - - ClearEnemy(); - AI_DEAD = true; - - // make monster nonsolid - if (spawnArgs.GetBool("nonsolid_on_ragdoll", "1")) - { - physicsObj.SetContents(0); - physicsObj.GetClipModel()->Unlink(); - } - - Unbind(); - - idStr deathSound = MouthIsUnderwater() ? "snd_death_liquid" : "snd_death"; - - StartSound( deathSound.c_str(), SND_CHANNEL_VOICE, 0, false, NULL ); - - // Go to ragdoll mode immediately, if we don't have a death anim - // If death anims are enabled, we need to wait with going to ragdoll until PostKilled() - if (!spawnArgs.GetBool("enable_death_anim", "0")) - { - StartRagdoll(); - } - - // swaps the head CM back if a different one was swapped in while conscious - SwapHeadAFCM( false ); - - if ( spawnArgs.GetString( "model_death", "", &modelDeath ) ) { - // lost soul is only case that does not use a ragdoll and has a model_death so get the death sound in here - StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - SetModel( modelDeath ); - physicsObj.SetLinearVelocity( vec3_zero ); - physicsObj.PutToRest(); - physicsObj.DisableImpact(); - } - - if (spawnArgs.GetBool("set_frobable_on_death", "1")) - { - // AI becomes frobable on death - // greebo: Add a delay before the AI becomes actually frobable - PostEventMS(&EV_SetFrobable, 750, 1); - } - - restartParticles = false; - - mind->ClearStates(); - mind->PushState(STATE_DEAD); - - // drop items - DropOnRagdoll(); - - if ( attacker && (attacker == gameLocal.GetLocalPlayer()) && inflictor ) - { - bPlayerResponsible = true; - } - else if ( attacker && attacker->m_SetInMotionByActor.GetEntity() ) - { - bPlayerResponsible = ( ( attacker != gameLocal.world ) && - ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ) ); - } - - // grayman #2908 - we need to know if the AI stepped on a player-tossed mine. - // So that we don't interfere with existing situations, check specifically - // for the mine. The previous two checked to determine player responsibility - // say the player is NOT responsible, when the inflictor is a mine. - - if ( !bPlayerResponsible ) - { - if ( inflictor && inflictor->IsType(idProjectile::Type) ) - { - idProjectile* proj = static_cast(inflictor); - if ( proj->IsMine() ) - { - bPlayerResponsible = ( inflictor->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); - } - } - } - - // Update TDM objective system - gameLocal.m_MissionData->MissionEvent( COMP_KILL, this, attacker, bPlayerResponsible ); - // Mark the body as last moved by the player - if( bPlayerResponsible ) - m_MovedByActor = gameLocal.GetLocalPlayer(); - - // greebo: Set the lipsync flag to FALSE, we're dead - m_lipSyncActive = false; - - DropBlood(inflictor); -} - -void idAI::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision) -{ - // Save the current health, to see afterwards how much damage we've been taking - int preHitHealth = health; - - idActor::Damage(inflictor, attacker, dir, damageDefName, damageScale, location, collision); - - // grayman #2478 - allowed idActor::Damage if dead, for physics reasons. - // Nothing beyond here is needed for AI that were dead when idAI::Damage() - // was called. - - if (preHitHealth <= 0) - { - return; - } - - if (inflictor != NULL && inflictor->IsType(idProjectile::Type)) - { - int damageTaken = preHitHealth - health; - - // Send a signal to the current state that we've been hit by something - GetMind()->GetState()->OnProjectileHit(static_cast(inflictor), attacker, damageTaken); - } - - if (attacker != NULL && IsEnemy(attacker)) - { - GetMemory().hasBeenAttackedByEnemy = true; - } -} - -void idAI::DropBlood(idEntity *inflictor) -{ - if ( inflictor && spawnArgs.GetBool("bleed","0") ) // grayman #2931 - { - idStr damageDefName = inflictor->spawnArgs.RandomPrefix("def_damage", gameLocal.random); - - const idDeclEntityDef *def = gameLocal.FindEntityDef(damageDefName, false); - if ( def == NULL ) - { - return; - } - - // blood splats are thrown onto nearby surfaces - idStr splat = def->dict.RandomPrefix("mtr_killed_splat", gameLocal.random); - - if (!splat.IsEmpty()) - { - SpawnBloodMarker(splat, splat + "_fading", 40); - } - } -} - - -void idAI::SpawnBloodMarker(const idStr& splat, const idStr& splatFading, float size) -{ - trace_t result; - gameLocal.clip.TracePoint(result, GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin() + 60 * idVec3(0, 0, -1), MASK_OPAQUE, this); - - idVec3 markerOrigin = result.endpos + idVec3(0, 0, 2); - - const idDict* markerDef = gameLocal.FindEntityDefDict("atdm:blood_marker", false); - - if (markerDef == NULL) - { - gameLocal.Error( "Failed to find definition of blood marker entity " ); - return; - } - - idEntity* ent; - gameLocal.SpawnEntityDef(*markerDef, &ent, false); - - if (!ent || !ent->IsType(CBloodMarker::Type)) - { - gameLocal.Error( "Failed to spawn blood marker entity" ); - return; - } - - CBloodMarker* bloodMarker = static_cast(ent); - bloodMarker->SetOrigin(markerOrigin); - bloodMarker->Init(splat, splatFading, size); - bloodMarker->Event_GenerateBloodSplat(); -} - - -/* -===================== -idAI::PostDeath -===================== -*/ -void idAI::PostDeath() -{ - // For death anims, we need to wait with going to ragdoll until here - if (spawnArgs.GetBool("enable_death_anim", "0")) - { - // Start going to ragdoll here, instead of in Killed() to enable death anims - StartRagdoll(); - } - - headAnim.StopAnim(1); - legsAnim.StopAnim(1); - torsoAnim.StopAnim(1); - - headAnim.Disable(); - legsAnim.Disable(); - torsoAnim.Disable(); -} - -/*********************************************************************** - - Targeting/Combat - -***********************************************************************/ - -/* -===================== -idAI::PlayCinematic -===================== -*/ -void idAI::PlayCinematic( void ) { - const char *animname; - - if ( current_cinematic >= num_cinematics ) { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); - } - if ( !spawnArgs.GetBool( "cinematic_no_hide" ) ) { - Hide(); - } - current_cinematic = 0; - ActivateTargets( gameLocal.GetLocalPlayer() ); - fl.neverDormant = false; - - return; - } - - Show(); - current_cinematic++; - - allowJointMod = false; - allowEyeFocus = false; - - spawnArgs.GetString( va( "anim%d", current_cinematic ), NULL, &animname ); - if ( !animname ) { - gameLocal.Warning( "missing 'anim%d' key on %s", current_cinematic, name.c_str() ); - return; - } - - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' start '%s'\n", gameLocal.framenum, GetName(), animname ); - } - - headAnim.animBlendFrames = 0; - headAnim.lastAnimBlendFrames = 0; - headAnim.BecomeIdle(); - - legsAnim.animBlendFrames = 0; - legsAnim.lastAnimBlendFrames = 0; - legsAnim.BecomeIdle(); - - torsoAnim.animBlendFrames = 0; - torsoAnim.lastAnimBlendFrames = 0; - ProcessEvent( &AI_PlayAnim, ANIMCHANNEL_TORSO, animname ); - - // make sure our model gets updated - animator.ForceUpdate(); - - // update the anim bounds - UpdateAnimation(); - UpdateVisuals(); - Present(); - - if ( head.GetEntity() ) { - // since the body anim was updated, we need to run physics to update the position of the head - RunPhysics(); - - // make sure our model gets updated - head.GetEntity()->GetAnimator()->ForceUpdate(); - - // update the anim bounds - head.GetEntity()->UpdateAnimation(); - head.GetEntity()->UpdateVisuals(); - head.GetEntity()->Present(); - } - - - fl.neverDormant = true; - -} - -/* -===================== -idAI::Activate - -Notifies the script that a monster has been activated by a trigger or flashlight - -DarkMod: Commented out calls to SetEnemy. We don't want the AI calling setEnemy, -only the alert state scripts. -===================== -*/ -void idAI::Activate( idEntity *activator ) -{ - // Fire the TRIGGER response - TriggerResponse(activator, ST_TRIGGER); - - if ( AI_DEAD || AI_KNOCKEDOUT ) { - // ignore it when they're dead or KO'd - return; - } - - // make sure he's not dormant - dormantStart = 0; - - if ( num_cinematics ) { - PlayCinematic(); - } else { - AI_ACTIVATED = true; - - /*idPlayer *player; - if ( !activator || !activator->IsType( idPlayer::Type ) ) { - player = gameLocal.GetLocalPlayer(); - } else { - player = static_cast( activator ); - } - - if ( ReactionTo( player ) & ATTACK_ON_ACTIVATE ) - { - //SetEnemy( player ); - }*/ - - // update the script in cinematics so that entities don't start anims or show themselves a frame late. - if ( cinematic ) { - UpdateScript(); - - // make sure our model gets updated - animator.ForceUpdate(); - - // update the anim bounds - UpdateAnimation(); - UpdateVisuals(); - Present(); - - if ( head.GetEntity() ) { - // since the body anim was updated, we need to run physics to update the position of the head - RunPhysics(); - - // make sure our model gets updated - head.GetEntity()->GetAnimator()->ForceUpdate(); - - // update the anim bounds - head.GetEntity()->UpdateAnimation(); - head.GetEntity()->UpdateVisuals(); - head.GetEntity()->Present(); - } - } - } -} - -/* -===================== -idAI::EnemyDead -===================== -*/ -void idAI::EnemyDead( void ) { - ClearEnemy(); -} - -/* -===================== -idAI::TalkTo -===================== -*/ -void idAI::TalkTo( idActor *actor ) { - if ( talk_state != TALK_OK ) { - return; - } - - talkTarget = actor; - if ( actor ) { - AI_TALK = true; - } else { - AI_TALK = false; - } -} - -/* -===================== -idAI::GetEnemy -===================== -*/ -idActor *idAI::GetEnemy( void ) const { - return enemy.GetEntity(); -} - -/* -===================== -idAI::GetTalkState -===================== -*/ -talkState_t idAI::GetTalkState( void ) const { - if ( ( talk_state != TALK_NEVER ) && AI_DEAD ) { - return TALK_DEAD; - } - if ( IsHidden() ) { - return TALK_NEVER; - } - return talk_state; -} - -/* -===================== -idAI::TouchedByFlashlight -===================== -*/ -void idAI::TouchedByFlashlight( idActor *flashlight_owner ) { - if ( wakeOnFlashlight ) { - Activate( flashlight_owner ); - } -} - -/* -===================== -idAI::ClearEnemy -===================== -*/ -void idAI::ClearEnemy( void ) { - if ( move.moveCommand == MOVE_TO_ENEMY ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - } - - // grayman #2887 - log the amount of time you saw the player. - // This is normally taken care of in UpdateEnemyPosition(), but we need - // to check here in case the AI is killed or KO'ed and doesn't - // use the normal logging code there. - - if ( AI_ENEMY_VISIBLE ) - { - if ( ( enemy.GetEntity() != NULL ) && ( enemy.GetEntity()->IsType(idPlayer::Type) ) ) - { - if ( lastTimePlayerLost < 0 ) // = -1 if the player was never seen or seen but not lost at this point - { - lastTimePlayerLost = gameLocal.time; - if ( lastTimePlayerSeen > 0 ) - { - gameLocal.m_MissionData->Add2TimePlayerSeen(lastTimePlayerLost - lastTimePlayerSeen); - } - lastTimePlayerSeen = -1; - } - } - } - - enemyNode.Remove(); - enemy = NULL; - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; -} - -/* -===================== -idAI::EnemyPositionValid -===================== -*/ -bool idAI::EnemyPositionValid( void ) const { - trace_t tr; - idVec3 muzzle; - idMat3 axis; - - if ( !enemy.GetEntity() ) { - return false; - } - - if ( AI_ENEMY_VISIBLE ) { - return true; - } - - gameLocal.clip.TracePoint( tr, GetEyePosition(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, MASK_OPAQUE, this ); - if ( tr.fraction < 1.0f ) { - // can't see the area yet, so don't know if he's there or not - return true; - } - - return false; -} - -/* -===================== -idAI::SetEnemyPosition -===================== -*/ -void idAI::SetEnemyPosition() -{ - idActor* enemyEnt = enemy.GetEntity(); - - if (enemyEnt == NULL) - { - return; - } - - int enemyAreaNum; - int areaNum; - int lastVisibleReachableEnemyAreaNum = -1; - aasPath_t path; - idVec3 pos; - bool onGround; - - lastVisibleReachableEnemyPos = lastReachableEnemyPos; - lastVisibleEnemyEyeOffset = enemyEnt->EyeOffset(); - lastVisibleEnemyPos = enemyEnt->GetPhysics()->GetOrigin(); - - if (move.moveType == MOVETYPE_FLY) - { - // Flying AI assume the enemy to be always on ground - pos = lastVisibleEnemyPos; - onGround = true; - } - else - { - // For non-flying AI, check if the enemy is on the ground - onGround = enemyEnt->GetFloorPos(64.0f, pos); - - if (enemyEnt->OnLadder()) // greebo: TODO: What about ropes? - { - onGround = false; - } - } - - // greebo: "pos" now holds the enemy position used for pathing (floor pos or visible pos) - - if (!onGround) - { - // greebo: The AI considers a non-grounded entity to be unreachable - // TODO: Check for climb height? The enemy might still be reachable? - if (move.moveCommand == MOVE_TO_ENEMY) - { - AI_DEST_UNREACHABLE = true; - } - return; - } - - if (aas != NULL) - { - // We have a valid AAS attached, try to reach the enemy - - // The default reachable area number is taken from the move command - lastVisibleReachableEnemyAreaNum = move.toAreaNum; - - // Get the area number of the point the enemy has last been seen in (== enemy origin) - enemyAreaNum = PointReachableAreaNum(lastVisibleEnemyPos, 1.0f); - - // If the area number is invalid, try to look it up again using the REACHABLE position - if (!enemyAreaNum) - { - enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); - pos = lastReachableEnemyPos; - } - - // Do we have a valid area number now? - if (enemyAreaNum) - { - // We have a valid enemy area number - - // Get the own origin and area number - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum(org); - - // Try to set up a walk/fly path to the enemy - if (PathToGoal(path, areaNum, org, enemyAreaNum, pos, this)) - { - // Succeeded, we have a visible and reachable enemy position - lastVisibleReachableEnemyPos = pos; - lastVisibleReachableEnemyAreaNum = enemyAreaNum; - - if (move.moveCommand == MOVE_TO_ENEMY) - { - // Enemy is reachable - AI_DEST_UNREACHABLE = false; - } - } - else if (move.moveCommand == MOVE_TO_ENEMY) - { - // No path to goal available, enemy is unreachable - AI_DEST_UNREACHABLE = true; - } - } - else - { - // The area number lookup failed, fallback to unreachable - if (move.moveCommand == MOVE_TO_ENEMY) - { - AI_DEST_UNREACHABLE = true; - } - areaNum = 0; - } - } - else - { - // We don't have a valid AAS, we can't tell if an enemy is reachable or not, - // so just assume that he is. - lastVisibleReachableEnemyPos = lastVisibleEnemyPos; - if (move.moveCommand == MOVE_TO_ENEMY) - { - AI_DEST_UNREACHABLE = false; - } - enemyAreaNum = 0; - areaNum = 0; - } - - // General move command update - if (move.moveCommand == MOVE_TO_ENEMY) - { - if (!aas) - { - // Invalid AAS keep the move destination up to date for wandering - move.moveDest = lastVisibleReachableEnemyPos; - } - else if (enemyAreaNum) - { - // The previous pathing attempt succeeded, update the move command - move.toAreaNum = lastVisibleReachableEnemyAreaNum; - move.moveDest = lastVisibleReachableEnemyPos; - } - - if (move.moveType == MOVETYPE_FLY) - { - predictedPath_t path; - idVec3 end = move.moveDest; - end.z += enemyEnt->EyeOffset().z + fly_offset; - idAI::PredictPath( this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path ); - move.moveDest = path.endPos; - move.toAreaNum = PointReachableAreaNum( move.moveDest, 1.0f ); - } - } -} - -bool idAI::EntityInAttackCone(idEntity* ent) -{ - float attack_cone; - idVec3 delta; - float yaw; - float relYaw; - - if ( !ent ) { - return false; - } - - delta = ent->GetPhysics()->GetOrigin() - GetEyePosition(); - - // get our gravity normal - const idVec3 &gravityDir = GetPhysics()->GetGravityNormal(); - - // infinite vertical vision, so project it onto our orientation plane - delta -= gravityDir * ( gravityDir * delta ); - - delta.Normalize(); - yaw = delta.ToYaw(); - - attack_cone = spawnArgs.GetFloat( "attack_cone", "70" ); - relYaw = idMath::AngleNormalize180( ideal_yaw - yaw ); - - return ( idMath::Fabs( relYaw ) < ( attack_cone * 0.5f ) ); -} - -bool idAI::CanHitEntity(idActor* entity, ECombatType combatType) -{ - if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0) - return false; - - if (combatType == COMBAT_MELEE) - { - return TestMelee(); - } - else if (combatType == COMBAT_RANGED) - { - return TestRanged(); - } - else - { - if (GetNumRangedWeapons() > 0) - { - return TestRanged(); - } - else if (GetNumMeleeWeapons() > 0) - { - return TestMelee(); - } - } - - return false; -} - -bool idAI::WillBeAbleToHitEntity(idActor* entity, ECombatType combatType) -{ - if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0) - return false; - - if (combatType == COMBAT_MELEE) - { - return TestMeleeFuture(); - } - else if (combatType == COMBAT_RANGED) - { - // not supported for ranged combat - return false; - } - else - { - if (GetNumRangedWeapons() > 0) - { - return false; - } - else if (GetNumMeleeWeapons() > 0) - { - return TestMeleeFuture(); - } - } - - return false; -} - -bool idAI::CanBeHitByEntity(idActor* entity, ECombatType combatType) -{ - if (entity == NULL || entity->IsKnockedOut() || entity->health <= 0 ) - return false; - - if (combatType == COMBAT_MELEE) - { - if ( !entity->GetAttackFlag(COMBAT_MELEE) - || !entity->melee_range ) - return false; - - const idVec3& org = physicsObj.GetOrigin(); - const idBounds& bounds = physicsObj.GetBounds(); - - const idVec3& enemyOrg = entity->GetPhysics()->GetOrigin(); - const idBounds& enemyBounds = entity->GetPhysics()->GetBounds(); - - idVec3 ourVel = physicsObj.GetLinearVelocity(); - idVec3 enemyVel = entity->GetPhysics()->GetLinearVelocity(); - idVec3 relVel = enemyVel - ourVel; - float velDot = ourVel * enemyVel; - - idVec3 dir = enemyOrg - org; - dir.z = 0; - float dist = dir.LengthFast(); - - float enemyReach = entity->melee_range; - - // generic factor to increase the enemy's threat range (accounts for sudden, quick advances) - // (TODO: Make spawnwarg?) - float threatFactor = 1.5f; - // velocity-based factor to increase the enemy's threat range - float velFactor; - if( velDot > 0 ) - { - // enemy moving away - velFactor = 1.0f; - } - else - { - // TODO: Make spawnargs? - // max speed of 20 MPH - float maxVel = 352; - float maxThreatInc = 3.0; - - velFactor = idMath::ClampFloat(1.0f, maxThreatInc, 1.0f + (maxThreatInc-1.0f)*relVel.LengthFast()/maxVel); - } - - enemyReach *= threatFactor * velFactor; - - float maxdist = enemyReach + bounds[1][0]; - - if (dist < maxdist) - { - // within horizontal distance - if (((enemyOrg.z + enemyBounds[1].z + entity->melee_range_vert) > org.z) && ((org.z + bounds[1].z) > enemyOrg.z)) // grayman #2655 - use enemy's origin, not your own, and use melee_range_vert -// if (((org.z + enemyBounds[1][2] + entity->melee_range) > org.z) && (org.z + bounds[1][2]) > enemyOrg.z) // grayman #2655 - old way - { - // within height - // don't bother with trace for this test - return true; - } - } - - return false; - } - else if (combatType == COMBAT_RANGED) - { - return false; // NYI - } - else - return false; -} - -void idAI::UpdateAttachmentContents(bool makeSolid) -{ - // ishtvan: Modified to work only with AF body representing the entity - for (int i = 0; i < m_Attachments.Num(); i++) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL || !m_Attachments[i].ent.IsValid()) continue; - - if (!ent->IsType(CMeleeWeapon::Type) && !ent->m_bAttachedAlertControlsSolidity) - continue; - - // Found a melee weapon or other attachment that should become solid on alert - idAFBody *body; - if (makeSolid) - { - if( (body = AFBodyForEnt(ent)) != NULL ) - { - // TODO: Read the contents from a stored variable - // in case they are something other than these standards? - // CONTENTS_RENDERMODEL allows projectiles to hit it - body->GetClipModel()->SetContents( CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); - body->SetClipMask( CONTENTS_SOLID | CONTENTS_CORPSE ); - } - } - else - { - if( (body = AFBodyForEnt(ent)) != NULL ) - { - body->GetClipModel()->SetContents( 0 ); - body->SetClipMask( 0 ); - } - } - } -} - -/* -===================== -idAI::UpdateEnemyPosition -===================== -*/ -void idAI::UpdateEnemyPosition() -{ - // Interleave this check - if (gameLocal.time <= lastUpdateEnemyPositionTime + cv_ai_opt_update_enemypos_interleave.GetInteger()) - { - return; - } - - idActor* enemyEnt = enemy.GetEntity(); - enemyReachable = false; - - if (enemyEnt == NULL) - { - return; - } - - // Set a new time stamp - lastUpdateEnemyPositionTime = gameLocal.time; - - START_SCOPED_TIMING(aiUpdateEnemyPositionTimer, scopedUpdateEnemyPositionTimer) - - int enemyAreaNum(-1); - idVec3 enemyPos; - bool onGround; - const idVec3& org = physicsObj.GetOrigin(); - int lastVisibleReachableEnemyAreaNum = -1; - bool enemyDetectable = false; - - if ( move.moveType == MOVETYPE_FLY ) - { - enemyPos = enemyEnt->GetPhysics()->GetOrigin(); - // greebo: Flying AI always consider their enemies to be on the ground - onGround = true; - } - else - { - // non-flying AI, get the floor position of the enemy - START_TIMING(aiGetFloorPosTimer); - onGround = enemyEnt->GetFloorPos(64.0f, enemyPos); - STOP_TIMING(aiGetFloorPosTimer); - - if (enemyEnt->OnLadder()) - { - onGround = false; - } - } - - int areaNum = PointReachableAreaNum(org, 1.0f); - - if (onGround) - { - // greebo: Enemy is on ground, hence reachable, try to setup a path - if (aas != NULL) - { - // We have a valid AAS, try to get the area of the enemy (floorpos or origin) - enemyAreaNum = PointReachableAreaNum(enemyPos, 1.0f); - - if (enemyAreaNum) - { - // We have a valid enemy area number - // Get the own area number - - // Try to setup a path to the goal - aasPath_t path; - if (PathToGoal( path, areaNum, org, enemyAreaNum, enemyPos, this)) - { - // Path successfully setup, store the position as "reachable" - lastReachableEnemyPos = enemyPos; - enemyReachable = true; - } - } - else - { - // The area number lookup failed, fallback to unreachable - if (move.moveCommand == MOVE_TO_ENEMY) - { - AI_DEST_UNREACHABLE = true; - } - areaNum = 0; - } - } - else - { - // We don't have an AAS, we can't tell if an enemy is reachable or not, - // so just assume that he is. - enemyAreaNum = 0; - lastReachableEnemyPos = enemyPos; - enemyReachable = true; - } - } - - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; - - if (CanSee(enemyEnt, false)) - { - if (cv_ai_show_enemy_visibility.GetBool()) - { - // greebo: A trace to the enemy is possible (no FOV check!) and the entity is not hidden in darkness - gameRenderWorld->DebugArrow(colorGreen, GetEyePosition(), GetEyePosition() + idVec3(0,0,10), 2, 100); - } - - // Enemy is considered visible if not hidden in darkness and not obscured - AI_ENEMY_VISIBLE = true; - - - // Now perform the FOV check manually - if (CheckFOV(enemyPos)) - { - AI_ENEMY_IN_FOV = true; - // TODO: call SetEnemyPosition here only? - - // Store the last time the enemy was visible - mind->GetMemory().lastTimeEnemySeen = gameLocal.time; - } - enemyDetectable = true; - } - - else // enemy is not visible - { - // Enemy can't be seen (obscured or hidden in darkness) - if (cv_ai_show_enemy_visibility.GetBool()) - { - gameRenderWorld->DebugArrow(colorRed, GetEyePosition(), GetEyePosition() + idVec3(0,0,10), 2, 100); - } - } - - // grayman #2887 - track enemy visibility for statistics - - if ( enemyEnt->IsType(idPlayer::Type) ) - { - if ( AI_ENEMY_VISIBLE ) - { - if ( ( lastTimePlayerSeen < 0 ) && ( lastTimePlayerLost < 0 ) ) - { - // new sighting - gameLocal.m_MissionData->IncrementPlayerSeen(); - lastTimePlayerSeen = gameLocal.time; - } - else if ( lastTimePlayerLost > 0 ) - { - if ( ( gameLocal.time - lastTimePlayerLost ) > 6000 ) - { - // new sighting - gameLocal.m_MissionData->IncrementPlayerSeen(); - lastTimePlayerSeen = gameLocal.time; - lastTimePlayerLost = -1; - } - else // continuation of previous sighting - { - lastTimePlayerSeen = lastTimePlayerLost; - lastTimePlayerLost = -1; - } - } - } - else // not visible - { - // log the amount of time you saw the player - - if ( lastTimePlayerLost < 0 ) - { - lastTimePlayerLost = gameLocal.time; - if ( lastTimePlayerSeen > 0 ) - { - gameLocal.m_MissionData->Add2TimePlayerSeen(lastTimePlayerLost - lastTimePlayerSeen); - } - lastTimePlayerSeen = -1; - } - } - } - - if (enemyDetectable) - { - // angua: This was merged in from SetEnemyPosition - // to avoid doing the same reachability testing stuff twice - lastVisibleEnemyPos = enemyEnt->GetPhysics()->GetOrigin(); - lastVisibleEnemyEyeOffset = enemyEnt->EyeOffset(); - - if (aas != NULL && enemyReachable) - { - // We have a visible and reachable enemy position - lastVisibleReachableEnemyPos = enemyPos; - lastVisibleReachableEnemyAreaNum = enemyAreaNum; - } - else - { - // We don't have a valid AAS, we can't tell if an enemy is reachable or not, - // so just assume that he is. - lastVisibleReachableEnemyPos = lastVisibleEnemyPos; - enemyAreaNum = 0; - areaNum = 0; - } - - // General move command update - if (move.moveCommand == MOVE_TO_ENEMY) - { - if (!aas) - { - // Invalid AAS keep the move destination up to date for wandering - AI_DEST_UNREACHABLE = false; - move.moveDest = lastVisibleReachableEnemyPos; - } - else if (enemyAreaNum) - { - // The previous pathing attempt succeeded, update the move command - move.toAreaNum = lastVisibleReachableEnemyAreaNum; - move.moveDest = lastVisibleReachableEnemyPos; - AI_DEST_UNREACHABLE = !enemyReachable; - } - - if (move.moveType == MOVETYPE_FLY) - { - predictedPath_t path; - idVec3 end = move.moveDest; - end.z += enemyEnt->EyeOffset().z + fly_offset; - idAI::PredictPath( this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path ); - move.moveDest = path.endPos; - move.toAreaNum = PointReachableAreaNum( move.moveDest, 1.0f ); - } - - if (!onGround) - { - // greebo: The AI considers a non-grounded entity to be unreachable - // TODO: Check for climb height? The enemy might still be reachable? - AI_DEST_UNREACHABLE = true; - } - } - } - - if (ai_debugMove.GetBool()) - { - gameRenderWorld->DebugBounds( colorLtGrey, enemyEnt->GetPhysics()->GetBounds(), lastReachableEnemyPos, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorWhite, enemyEnt->GetPhysics()->GetBounds(), lastVisibleReachableEnemyPos, gameLocal.msec ); - } -} - -/* -===================== -idAI::SetEnemy -===================== -*/ -bool idAI::SetEnemy(idActor* newEnemy) -{ - // Don't continue if we're dead or knocked out - if (newEnemy == NULL || AI_DEAD || AI_KNOCKEDOUT) - { - ClearEnemy(); - return false; // not a valid enemy - } - - // greebo: Check if the new enemy is different - if (enemy.GetEntity() != newEnemy) - { - // Update the enemy pointer - enemy = newEnemy; - - enemyNode.AddToEnd(newEnemy->enemyList); - - // Check if the new enemy is dead - if (newEnemy->health <= 0) - { - EnemyDead(); - return false; // not a valid enemy - } - - int enemyAreaNum(-1); - - // greebo: Get the reachable position and area number of this enemy - newEnemy->GetAASLocation(aas, lastReachableEnemyPos, enemyAreaNum); - - // SetEnemyPosition() can now try to setup a path, - // lastVisibleReachableEnemyPosition is set in ANY CASE by this method - SetEnemyPosition(); - - // greebo: This looks suspicious. It overwrites REACHABLE and - // and VISIBLEREACHABLE with VISIBLE enemy position, - // regardless of what happened before. WTF? TODO - lastReachableEnemyPos = lastVisibleEnemyPos; - lastVisibleReachableEnemyPos = lastReachableEnemyPos; - - // Get the area number of the enemy - enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); - - if (aas != NULL && enemyAreaNum) - { - aas->PushPointIntoAreaNum( enemyAreaNum, lastReachableEnemyPos ); - lastVisibleReachableEnemyPos = lastReachableEnemyPos; - } - - ai::Memory& memory = GetMemory(); - memory.lastTimeEnemySeen = gameLocal.time; - memory.stopRelight = true; // grayman #2603 - memory.stopExaminingRope = true; // grayman #2872 - stop examining a rope - - return true; // valid enemy - } - else - { - return true; // still a valid enemy - } -} - -/* -============ -idAI::FirstVisiblePointOnPath -============ -*/ -idVec3 idAI::FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) { - int i, areaNum, targetAreaNum, curAreaNum, travelTime; - idVec3 curOrigin; - idReachability *reach; - - if ( !aas ) { - return origin; - } - - areaNum = PointReachableAreaNum( origin ); - targetAreaNum = PointReachableAreaNum( target ); - - if ( !areaNum || !targetAreaNum ) { - return origin; - } - - if ( ( areaNum == targetAreaNum ) || PointVisible( origin ) ) { - return origin; - } - - curAreaNum = areaNum; - curOrigin = origin; - - for( i = 0; i < 10; i++ ) { - - if ( !aas->RouteToGoalArea( curAreaNum, curOrigin, targetAreaNum, travelFlags, travelTime, &reach, NULL, this ) ) { - break; - } - - if ( !reach ) { - return target; - } - - curAreaNum = reach->toAreaNum; - curOrigin = reach->end; - - if ( PointVisible( curOrigin ) ) { - return curOrigin; - } - } - - return origin; -} - -/* -=================== -idAI::CalculateAttackOffsets - -calculate joint positions on attack frames so we can do proper "can hit" tests -=================== -*/ -void idAI::CalculateAttackOffsets( void ) { - const idDeclModelDef *modelDef; - int num; - int i; - int frame; - const frameCommand_t *command; - idMat3 axis; - const idAnim *anim; - jointHandle_t joint; - - modelDef = animator.ModelDef(); - if ( !modelDef ) { - return; - } - num = modelDef->NumAnims(); - - // needs to be off while getting the offsets so that we account for the distance the monster moves in the attack anim - animator.RemoveOriginOffset( false ); - - // anim number 0 is reserved for non-existant anims. to avoid off by one issues, just allocate an extra spot for - // launch offsets so that anim number can be used without subtracting 1. - missileLaunchOffset.SetGranularity( 1 ); - missileLaunchOffset.SetNum( num + 1 ); - missileLaunchOffset[ 0 ].Zero(); - - for( i = 1; i <= num; i++ ) { - missileLaunchOffset[ i ].Zero(); - anim = modelDef->GetAnim( i ); - if ( anim ) { - frame = anim->FindFrameForFrameCommand( FC_LAUNCHMISSILE, &command ); - if ( frame >= 0 ) { - joint = animator.GetJointHandle( command->string->c_str() ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Invalid joint '%s' on 'launch_missile' frame command on frame %d of model '%s'", command->string->c_str(), frame, modelDef->GetName() ); - } - GetJointTransformForAnim( joint, i, FRAME2MS( frame ), missileLaunchOffset[ i ], axis ); - } - } - } - - animator.RemoveOriginOffset( true ); -} - -/* -===================== -idAI::EnsureActiveProjectileInfo -===================== -*/ -idAI::ProjectileInfo& idAI::EnsureActiveProjectileInfo() -{ - // Ensure valid projectile clipmodel - if (activeProjectile.info.clipModel == NULL) - { - // Ensure we have a radius - if (activeProjectile.info.radius < 0) - { - // At least we should have the def - assert(activeProjectile.info.def != NULL); - - // Load values from the projectile - InitProjectileInfoFromDict(activeProjectile.info, activeProjectile.info.def); - } - - idBounds projectileBounds(vec3_origin); - projectileBounds.ExpandSelf(activeProjectile.info.radius); - - activeProjectile.info.clipModel = new idClipModel(idTraceModel(projectileBounds)); - } - - return activeProjectile.info; -} - -/* -===================== -idAI::GetAimDir -===================== -*/ -bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ) -{ - idVec3 targetPos1; - idVec3 targetPos2; - idVec3 delta; - float max_height; - bool result; - - // if no aimAtEnt or projectile set - if (aimAtEnt == NULL || projectileInfo.Num() == 0) - { - aimDir = viewAxis[ 0 ] * physicsObj.GetGravityAxis(); - return false; - } - - // Ensure we have a valid clipmodel - ProjectileInfo& info = EnsureActiveProjectileInfo(); - - if ( aimAtEnt == enemy.GetEntity() ) { - static_cast( aimAtEnt )->GetAIAimTargets( lastVisibleEnemyPos, targetPos1, targetPos2 ); - } else if ( aimAtEnt->IsType( idActor::Type ) ) { - static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), targetPos1, targetPos2 ); - } else { - targetPos1 = aimAtEnt->GetPhysics()->GetAbsBounds().GetCenter(); - targetPos2 = targetPos1; - } - - // try aiming for chest - delta = firePos - targetPos1; - max_height = delta.LengthFast() * projectile_height_to_distance_ratio; - result = PredictTrajectory( firePos, targetPos1, info.speed, info.gravity, info.clipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); - if ( result || !aimAtEnt->IsType( idActor::Type ) ) { - return result; - } - - // try aiming for head - delta = firePos - targetPos2; - max_height = delta.LengthFast() * projectile_height_to_distance_ratio; - result = PredictTrajectory( firePos, targetPos2, info.speed, info.gravity, info.clipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); - - return result; -} - -/* -===================== -idAI::BeginAttack -===================== -*/ -void idAI::BeginAttack( const char *name ) { - attack = name; - lastAttackTime = gameLocal.time; -} - -/* -===================== -idAI::EndAttack -===================== -*/ -void idAI::EndAttack( void ) { - attack = ""; -} - -/* -===================== -idAI::CreateProjectile -===================== -*/ -idProjectile* idAI::CreateProjectile(const idVec3 &pos, const idVec3 &dir, int index) -{ - if (activeProjectile.projEnt.GetEntity() == NULL) - { - assert(curProjectileIndex >= 0 && curProjectileIndex < projectileInfo.Num()); // bounds check - - // projectile pointer still NULL, create a new one - const idDict* def = projectileInfo[curProjectileIndex].def; - - // Fill the current projectile entity pointer, passing the arguments to the specialised routine - // After this call, the activeProjectile.projEnt pointer will be initialised with the new projectile. - CreateProjectileFromDict(pos, dir, def); - - // Re-roll the index for the next time - curProjectileIndex = gameLocal.random.RandomInt(projectileInfo.Num()); - } - - return activeProjectile.projEnt.GetEntity(); -} - -idProjectile* idAI::CreateProjectileFromDict(const idVec3 &pos, const idVec3 &dir, const idDict* dict) -{ - if (activeProjectile.projEnt.GetEntity() == NULL) - { - // Store the def for later use - activeProjectile.info.def = dict; - activeProjectile.info.defName = dict->GetString("classname"); - - // Fill the current projectile entity pointer - activeProjectile.projEnt = SpawnProjectile(dict); - } - - activeProjectile.projEnt.GetEntity()->Create(this, pos, dir); - - return activeProjectile.projEnt.GetEntity(); -} - -idProjectile* idAI::SpawnProjectile(const idDict* dict) const -{ - idEntity* ent; - gameLocal.SpawnEntityDef(*dict, &ent, false); - - if (ent == NULL) - { - const char* clsname = dict->GetString("classname"); - gameLocal.Error("Could not spawn entityDef '%s'", clsname); - } - - if (!ent->IsType(idProjectile::Type)) - { - const char* clsname = ent->GetClassname(); - gameLocal.Error("'%s' is not an idProjectile", clsname); - } - - return static_cast(ent); -} - -/* -===================== -idAI::RemoveProjectile -===================== -*/ -void idAI::RemoveProjectile() -{ - if (activeProjectile.projEnt.GetEntity()) - { - activeProjectile.projEnt.GetEntity()->PostEventMS(&EV_Remove, 0); - activeProjectile.projEnt = NULL; - - activeProjectile.info = ProjectileInfo(); - } -} - -/* -===================== -idAI::LaunchProjectile -===================== -*/ -idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone ) { - idVec3 muzzle; - idVec3 dir; - idVec3 start; - trace_t tr; - idBounds projBounds; - float distance; - const idClipModel *projClip; - float attack_accuracy; - float attack_cone; - float projectile_spread; - float diff; - float angle; - float spin; - idAngles ang; - int num_projectiles; - int i; - idMat3 axis; - idVec3 tmp; - - if (projectileInfo.Num() == 0) - { - gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() ); - return NULL; - } - - attack_accuracy = spawnArgs.GetFloat( "attack_accuracy", "7" ); - attack_cone = spawnArgs.GetFloat( "attack_cone", "70" ); - projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); - num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); - - GetMuzzle( jointname, muzzle, axis ); - - // Ensure we have a set up projectile - CreateProjectile(muzzle, axis[0]); - - idProjectile* lastProjectile = activeProjectile.projEnt.GetEntity(); - - if ( target != NULL ) { - tmp = target->GetPhysics()->GetAbsBounds().GetCenter() - muzzle; - tmp.Normalize(); - axis = tmp.ToMat3(); - } else { - axis = viewAxis; - } - - // rotate it because the cone points up by default - tmp = axis[2]; - axis[2] = axis[0]; - axis[0] = -tmp; - - // make sure the projectile starts inside the monster bounding box - const idBounds &ownerBounds = physicsObj.GetAbsBounds(); - projClip = lastProjectile->GetPhysics()->GetClipModel(); - projBounds = projClip->GetBounds().Rotate( axis ); - - // check if the owner bounds is bigger than the projectile bounds - if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && - ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && - ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { - if ( (ownerBounds - projBounds).RayIntersection( muzzle, viewAxis[ 0 ], distance ) ) { - start = muzzle + distance * viewAxis[ 0 ]; - } else { - start = ownerBounds.GetCenter(); - } - } else { - // projectile bounds bigger than the owner bounds, so just start it from the center - start = ownerBounds.GetCenter(); - } - - gameLocal.clip.Translation( tr, start, muzzle, projClip, axis, MASK_SHOT_RENDERMODEL, this ); - muzzle = tr.endpos; - - // set aiming direction - GetAimDir( muzzle, target, this, dir ); - ang = dir.ToAngles(); - - // adjust his aim so it's not perfect. uses sine based movement so the tracers appear less random in their spread. - float t = MS2SEC( gameLocal.time + entityNumber * 497 ); - ang.pitch += idMath::Sin16( t * 5.1 ) * attack_accuracy; - ang.yaw += idMath::Sin16( t * 6.7 ) * attack_accuracy; - - if ( clampToAttackCone ) { - // clamp the attack direction to be within monster's attack cone so he doesn't do - // things like throw the missile backwards if you're behind him - diff = idMath::AngleDelta( ang.yaw, current_yaw ); - if ( diff > attack_cone ) { - ang.yaw = current_yaw + attack_cone; - } else if ( diff < -attack_cone ) { - ang.yaw = current_yaw - attack_cone; - } - } - - axis = ang.ToMat3(); - - float spreadRad = DEG2RAD( projectile_spread ); - - for( i = 0; i < num_projectiles; i++ ) - { - // spread the projectiles out - angle = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); - spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); - dir = axis[ 0 ] + axis[ 2 ] * ( angle * idMath::Sin( spin ) ) - axis[ 1 ] * ( angle * idMath::Cos( spin ) ); - dir.Normalize(); - - // create, launch and clear the projectile - CreateProjectile( muzzle, dir ); - - lastProjectile = activeProjectile.projEnt.GetEntity(); - lastProjectile->Launch( muzzle, dir, vec3_origin ); - activeProjectile.projEnt = NULL; - } - - TriggerWeaponEffects( muzzle ); - - lastAttackTime = gameLocal.time; - - return lastProjectile; -} - -/* -================ -idAI::DamageFeedback - -callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. - -FIXME: This gets called when we call idPlayer::CalcDamagePoints from idAI::AttackMelee, which then checks for a saving throw, -possibly forcing a miss. This is harmless behavior ATM, but is not intuitive. -================ -*/ -void idAI::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { - if ( ( victim == this ) && inflictor->IsType( idProjectile::Type ) ) { - // monsters only get half damage from their own projectiles - damage = ( damage + 1 ) / 2; // round up so we don't do 0 damage - - } else if ( victim == enemy.GetEntity() ) { - AI_HIT_ENEMY = true; - } -} - -/* -===================== -idAI::DirectDamage - -Causes direct damage to an entity - -kickDir is specified in the monster's coordinate system, and gives the direction -that the view kick and knockback should go -===================== -*/ -void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) { - const idDict *meleeDef; - const char *p; - const idSoundShader *shader; - - meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); - if ( !meleeDef ) { - gameLocal.Error( "Unknown damage def '%s' on '%s'", meleeDefName, name.c_str() ); - } - - if ( !ent->fl.takedamage ) { - const idSoundShader *shader = declManager->FindSound(meleeDef->GetString( "snd_miss" )); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); - return; - } - - // - // do the damage - // - p = meleeDef->GetString( "snd_hit" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); - } - - idVec3 kickDir; - meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); - - idVec3 globalKickDir; - globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; - - ent->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); - - // end the attack if we're a multiframe attack - EndAttack(); -} - -/* -===================== -idAI::TestMelee -===================== -*/ -bool idAI::TestMelee( void ) const { - trace_t trace; - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt || !melee_range ) { - return false; - } - - if (!GetAttackFlag(COMBAT_MELEE)) - { - // greebo: Cannot attack with melee weapons yet - return false; - } - - //FIXME: make work with gravity vector - const idVec3& org = physicsObj.GetOrigin(); - const idBounds& bounds = physicsObj.GetBounds(); - - const idVec3& enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); - const idBounds& enemyBounds = enemyEnt->GetPhysics()->GetBounds(); - - idVec3 dir = enemyOrg - org; - dir.z = 0; - float dist = dir.LengthFast(); - - float maxdist = melee_range + enemyBounds[1][0]; - - if (dist < maxdist) - { - // angua: within horizontal distance - if ((org.z + bounds[1][2] + melee_range_vert) > enemyOrg.z && // grayman #2655 - use melee_range_vert - (enemyOrg.z + enemyBounds[1][2]) > org.z) - { - // within height - // check if there is something in between - idVec3 start = GetEyePosition(); - idVec3 end = enemyEnt->GetEyePosition(); - - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); - if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) - { - return true; - } - } - } - - return false; -} - -/* -===================== -idAI::TestMeleeFuture -===================== -*/ -bool idAI::TestMeleeFuture( void ) const { - trace_t trace; - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt || !melee_range ) { - return false; - } - - if (!GetAttackFlag(COMBAT_MELEE)) - { - // greebo: Cannot attack with melee weapons yet - return false; - } - - //FIXME: make work with gravity vector - idVec3 org = physicsObj.GetOrigin(); - const idBounds& bounds = physicsObj.GetBounds(); - idVec3 vel = physicsObj.GetLinearVelocity(); - - - idVec3 enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); - const idBounds& enemyBounds = enemyEnt->GetPhysics()->GetBounds(); - idVec3 enemyVel = enemyEnt->GetPhysics()->GetLinearVelocity(); - - // update prediction - float dt = m_MeleePredictedAttTime; - idVec3 ds = dt * vel; - org += ds; - //bounds = bounds.TranslateSelf( ds ); - - idVec3 dsEnemy = dt * enemyVel; - enemyOrg += dsEnemy; - //enemyBounds = enemyBounds.TranslateSelf( dsEnemy ); - - // rest is the same as TestMelee - idVec3 dir = enemyOrg - org; - dir.z = 0; - float dist = dir.LengthFast(); - - float maxdist = melee_range + enemyBounds[1][0]; - - if (dist < maxdist) - { - // angua: within horizontal distance - if ((org.z + bounds[1].z + melee_range_vert) > enemyOrg.z && // grayman #2655 - use melee_range_vert - (enemyOrg.z + enemyBounds[1].z) > org.z) - { - // within height - // check if there is something in between - idVec3 start = GetEyePosition() + ds; - idVec3 end = enemyEnt->GetEyePosition() + dsEnemy; - - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); - if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) - { - return true; - } - } - } - - return false; -} - - -/* -===================== -idAI::TestRanged -===================== -*/ -bool idAI::TestRanged() -{ - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt) - { - return false; - } - - if (!GetAttackFlag(COMBAT_RANGED)) - { - // greebo: Cannot attack with ranged weapons yet - return false; - } - - // Calculate the point on enemy AI needs to see - idVec3 enemyPoint; - // stgatilov: Look at the UNLEANED player's eye position - // to achieve this, we treat player as ordinary actor - if (enemyEnt->IsType(idPlayer::Type)) - enemyPoint = enemyEnt->idActor::GetEyePosition(); - else - enemyPoint = enemyEnt->GetEyePosition(); - - // Test if the enemy is within range, in FOV and not occluded - float dist = (GetEyePosition() - enemyPoint).LengthFast(); - return dist <= fire_range && CanSeePositionExt(enemyPoint, false, false); -} - - -/* -===================== -idAI::AttackMelee - -jointname allows the endpoint to be exactly specified in the model, -as for the commando tentacle. If not specified, it will be set to -the facing direction + melee_range. - -kickDir is specified in the monster's coordinate system, and gives the direction -that the view kick and knockback should go - -DarkMod : Took out saving throws. -===================== -*/ -bool idAI::AttackMelee( const char *meleeDefName ) { - const idDict *meleeDef; - idActor *enemyEnt = enemy.GetEntity(); - const char *p; - const idSoundShader *shader; - - meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); - if ( !meleeDef ) { - gameLocal.Error( "Unknown melee '%s'", meleeDefName ); - } - - if ( !enemyEnt ) { - p = meleeDef->GetString( "snd_miss" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); - } - return false; - } - - // check for the "saving throw" automatic melee miss on lethal blow - // stupid place for this. - -/** -* Saving throws removed. Uncomment the following for saving throws. -**/ - -/*** BEGIN SAVING THROWS SECTION ***** - bool forceMiss = false; - if ( enemyEnt->IsType( idPlayer::Type ) && g_skill.GetInteger() < 2 ) { - int damage, armor; - idPlayer *player = static_cast( enemyEnt ); - player->CalcDamagePoints( this, this, meleeDef, 1.0f, INVALID_JOINT, &damage, &armor ); - - if ( enemyEnt->health <= damage ) { - int t = gameLocal.time - player->lastSavingThrowTime; - if ( t > SAVING_THROW_TIME ) { - player->lastSavingThrowTime = gameLocal.time; - t = 0; - } - if ( t < 1000 ) { - gameLocal.Printf( "Saving throw.\n" ); - forceMiss = true; - } - } - } - - - // make sure the trace can actually hit the enemy - if ( forceMiss || !TestMelee() ) { -****** END SAVING THROWS SECTION *******/ - - if ( !TestMelee() ) - { - // missed - p = meleeDef->GetString( "snd_miss" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); - } - return false; - } - - // - // do the damage - // - p = meleeDef->GetString( "snd_hit" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); - } - - idVec3 kickDir; - meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); - - idVec3 globalKickDir; - globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; - - enemyEnt->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); - - // cause a LARGE tactile alert in the enemy, if it is an AI - if( enemyEnt->IsType(idAI::Type) ) - { - static_cast(enemyEnt)->TactileAlert( this, 100 ); - } - - lastAttackTime = gameLocal.time; - - return true; -} - -/* -================ -idAI::PushWithAF -================ -*/ -void idAI::PushWithAF( void ) { - int i, j; - afTouch_t touchList[ MAX_GENTITIES ]; - idEntity *pushed_ents[ MAX_GENTITIES ]; - idEntity *ent; - idVec3 vel( vec3_origin ), vGravNorm( vec3_origin ); - int num_pushed; - - num_pushed = 0; - af.ChangePose( this, gameLocal.time ); - int num = af.EntitiesTouchingAF( touchList ); - - for( i = 0; i < num; i++ ) { - if ( touchList[ i ].touchedEnt->IsType( idProjectile::Type ) ) { - // skip projectiles - continue; - } - - // make sure we havent pushed this entity already. this avoids causing double damage - for( j = 0; j < num_pushed; j++ ) { - if ( pushed_ents[ j ] == touchList[ i ].touchedEnt ) { - break; - } - } - if ( j >= num_pushed ) - { - ent = touchList[ i ].touchedEnt; - pushed_ents[num_pushed++] = ent; - vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin(); - - if ( ent->IsType(idPlayer::Type) && static_cast(ent)->noclip ) - { - // skip player when noclip is on - continue; - } - - // ishtvan: don't push our own bind children (fix AI floating away when stuff is bound to them) - if( ent->GetBindMaster() == this ) - continue; - - if( ent->IsType(idActor::Type) ) - { - - // Id code to stop from pushing the enemy back during melee - // TODO: This will change with new melee system - if ( attack.Length() ) - { - // TODO: Don't need to do this right now, but keep in mind for future melee system - ent->Damage( this, this, vel, attack, 1.0f, INVALID_JOINT ); - } else - { - // Ishtvan: Resolve velocity on to XY plane to stop from pushing AI up - vGravNorm = physicsObj.GetGravityNormal(); - vel -= (vel * vGravNorm ) * vGravNorm; - vel.Normalize(); - ent->GetPhysics()->SetLinearVelocity( 80.0f * vel, touchList[ i ].touchedClipModel->GetId() ); - } - - // Tactile Alert: - - // grayman #2345 - when an AI is non-solid, waiting for another AI - // to pass by, there's no need to register a tactile alert from another AI - - if (!movementSubsystem->IsWaitingNonSolid()) - { - if( ent->IsType(idPlayer::Type) ) - { - // aesthetics: Dont react to dead player? - if( ent->health > 0 ) - HadTactile( static_cast(ent) ); - } - else if( ent->IsType(idAI::Type) && (ent->health > 0) && !static_cast(ent)->AI_KNOCKEDOUT ) - { - if (!static_cast(ent)->movementSubsystem->IsWaitingNonSolid()) // grayman #2345 - don't call HadTactile() if the bumped AI is waiting - { - HadTactile( static_cast(ent) ); - } - } - else - { - // TODO: Touched a dead or unconscious body, should issue a body alert - // Touched dead body code goes here: found body alert - } - } - } - // Ent was not an actor: - else - { - vel.Normalize(); - ent->ApplyImpulse( this, touchList[i].touchedClipModel->GetId(), ent->GetPhysics()->GetOrigin(), cv_ai_bumpobject_impulse.GetFloat() * vel ); - if (ent->m_SetInMotionByActor.GetEntity() == NULL) - { - ent->m_SetInMotionByActor = this; - ent->m_MovedByActor = this; - } - } - } - } -} - -/*********************************************************************** - - Misc - -***********************************************************************/ - -/* -================ -idAI::GetMuzzle -================ -*/ -void idAI::GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ) { - jointHandle_t joint; - - if ( !jointname || !jointname[ 0 ] ) { - muzzle = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 14; - muzzle -= physicsObj.GetGravityNormal() * physicsObj.GetBounds()[ 1 ].z * 0.5f; - } else { - joint = animator.GetJointHandle( jointname ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); - } - GetJointWorldTransform( joint, gameLocal.time, muzzle, axis ); - } -} - -/* -================ -idAI::TriggerWeaponEffects -================ -*/ -void idAI::TriggerWeaponEffects( const idVec3 &muzzle ) { - idVec3 org; - idMat3 axis; - - if ( !g_muzzleFlash.GetBool() ) { - return; - } - - // muzzle flash - // offset the shader parms so muzzle flashes show up - renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = gameLocal.random.CRandomFloat(); - - if ( flashJointWorld != INVALID_JOINT ) { - GetJointWorldTransform( flashJointWorld, gameLocal.time, org, axis ); - - if ( worldMuzzleFlash.lightRadius.x > 0.0f ) { - worldMuzzleFlash.axis = axis; - worldMuzzleFlash.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - if ( worldMuzzleFlashHandle != - 1 ) { - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - } else { - worldMuzzleFlashHandle = gameRenderWorld->AddLightDef( &worldMuzzleFlash ); - } - muzzleFlashEnd = gameLocal.time + flashTime; - UpdateVisuals(); - } - } -} - -/* -================ -idAI::UpdateMuzzleFlash -================ -*/ -void idAI::UpdateMuzzleFlash( void ) { - if ( worldMuzzleFlashHandle != -1 ) { - if ( gameLocal.time >= muzzleFlashEnd ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); - worldMuzzleFlashHandle = -1; - } else { - idVec3 muzzle; - animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); - animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); - muzzle = physicsObj.GetOrigin() + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); - worldMuzzleFlash.origin = muzzle; - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - } - } -} - -/* -================ -idAI::Hide -================ -*/ -void idAI::Hide( void ) { - idActor::Hide(); - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.GetClipModel()->Unlink(); - StopSound( SND_CHANNEL_AMBIENT, false ); - - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; - StopMove( MOVE_STATUS_DONE ); -} - -/* -================ -idAI::Show -================ -*/ -void idAI::Show( void ) -{ - idActor::Show(); - physicsObj.SetContents( m_preHideContents ); - - physicsObj.GetClipModel()->Link( gameLocal.clip ); - fl.takedamage = !spawnArgs.GetBool( "noDamage" ); - StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); -} -/* -================ -idAI::CanBecomeSolid -================ -*/ -bool idAI::CanBecomeSolid( void ) { - idClipModel* clipModels[ MAX_GENTITIES ]; - - int num = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), MASK_MONSTERSOLID, clipModels, MAX_GENTITIES ); - for ( int i = 0; i < num; i++ ) { - idClipModel* cm = clipModels[ i ]; - - // don't check render entities - if ( cm->IsRenderModel() ) { - continue; - } - - idEntity* hit = cm->GetEntity(); - if ( ( hit == this ) || !hit->fl.takedamage ) { - continue; - } - - if ( physicsObj.ClipContents( cm ) ) { - return false; - } - } - return true; - -} - -/* -===================== -idAI::UpdateParticles -===================== -*/ -void idAI::UpdateParticles( void ) { - if ( ( thinkFlags & TH_UPDATEPARTICLES) && !IsHidden() ) { - idVec3 realVector; - idMat3 realAxis; - - int particlesAlive = 0; - for ( int i = 0; i < particles.Num(); i++ ) { - if ( particles[i].particle && particles[i].time ) { - particlesAlive++; - if (af.IsActive()) { - realAxis = mat3_identity; - realVector = GetPhysics()->GetOrigin(); - } else { - animator.GetJointTransform( particles[i].joint, gameLocal.time, realVector, realAxis ); - realAxis *= renderEntity.axis; - realVector = physicsObj.GetOrigin() + ( realVector + modelOffset ) * ( viewAxis * physicsObj.GetGravityAxis() ); - } - - if ( !gameLocal.smokeParticles->EmitSmoke( particles[i].particle, particles[i].time, gameLocal.random.CRandomFloat(), realVector, realAxis )) { - if ( restartParticles ) { - particles[i].time = gameLocal.time; - } else { - particles[i].time = 0; - particlesAlive--; - } - } - } - } - if ( particlesAlive == 0 ) { - BecomeInactive( TH_UPDATEPARTICLES ); - } - } -} - -/* -===================== -idAI::TriggerParticles -===================== -*/ -void idAI::TriggerParticles( const char *jointName ) { - jointHandle_t jointNum; - - jointNum = animator.GetJointHandle( jointName ); - for ( int i = 0; i < particles.Num(); i++ ) { - if ( particles[i].joint == jointNum ) { - particles[i].time = gameLocal.time; - BecomeActive( TH_UPDATEPARTICLES ); - } - } -} - - -/*********************************************************************** - - Head & torso aiming - -***********************************************************************/ - -/* -================ -idAI::UpdateAnimationControllers -================ -*/ -bool idAI::UpdateAnimationControllers( void ) { - idVec3 local; - idVec3 focusPos; - idQuat jawQuat; - idVec3 left; - idVec3 dir; - idVec3 orientationJointPos; - idVec3 localDir; - idAngles newLookAng; - idAngles diff; - idMat3 mat; - idMat3 axis; - idMat3 orientationJointAxis; - idAFAttachment *headEnt = head.GetEntity(); - idVec3 eyepos; - idVec3 pos; - int i; - idAngles jointAng; - float orientationJointYaw; - - if ( AI_DEAD || AI_KNOCKEDOUT ) - { - return idActor::UpdateAnimationControllers(); - } - - if ( orientationJoint == INVALID_JOINT ) { - orientationJointAxis = viewAxis; - orientationJointPos = physicsObj.GetOrigin(); - orientationJointYaw = current_yaw; - } else { - GetJointWorldTransform( orientationJoint, gameLocal.time, orientationJointPos, orientationJointAxis ); - orientationJointYaw = orientationJointAxis[ 2 ].ToYaw(); - orientationJointAxis = idAngles( 0.0f, orientationJointYaw, 0.0f ).ToMat3(); - } - - if ( focusJoint != INVALID_JOINT ) { - if ( headEnt ) { - headEnt->GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); - } else { - GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); - } - eyeOffset.z = eyepos.z - physicsObj.GetOrigin().z; - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, eyepos, eyepos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); - } - } else { - eyepos = GetEyePosition(); - } - - if ( headEnt ) { - CopyJointsFromBodyToHead(); - } - - // Update the IK after we've gotten all the joint positions we need, but before we set any joint positions. - // Getting the joint positions causes the joints to be updated. The IK gets joint positions itself (which - // are already up to date because of getting the joints in this function) and then sets their positions, which - // forces the heirarchy to be updated again next time we get a joint or present the model. If IK is enabled, - // or if we have a seperate head, we end up transforming the joints twice per frame. Characters with no - // head entity and no ik will only transform their joints once. Set g_debuganim to the current entity number - // in order to see how many times an entity transforms the joints per frame. - idActor::UpdateAnimationControllers(); - - idEntity *focusEnt = focusEntity.GetEntity(); - if ( !allowJointMod || !allowEyeFocus || ( gameLocal.time >= focusTime ) ) { - focusPos = GetEyePosition() + orientationJointAxis[ 0 ] * 512.0f; - } else if ( focusEnt == NULL ) { - // keep looking at last position until focusTime is up - focusPos = currentFocusPos; - } else if ( focusEnt == enemy.GetEntity() ) { - focusPos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset - eyeVerticalOffset * enemy.GetEntity()->GetPhysics()->GetGravityNormal(); - } else if ( focusEnt->IsType( idActor::Type ) ) { - focusPos = static_cast( focusEnt )->GetEyePosition() - eyeVerticalOffset * focusEnt->GetPhysics()->GetGravityNormal(); - } else { - focusPos = focusEnt->GetPhysics()->GetOrigin(); - } - - currentFocusPos = currentFocusPos + ( focusPos - currentFocusPos ) * eyeFocusRate; - - // determine yaw from origin instead of from focus joint since joint may be offset, which can cause us to bounce between two angles - dir = focusPos - orientationJointPos; - newLookAng.yaw = idMath::AngleNormalize180( dir.ToYaw() - orientationJointYaw ); - newLookAng.roll = 0.0f; - newLookAng.pitch = 0.0f; - -#if 0 - gameRenderWorld->DebugLine( colorRed, orientationJointPos, focusPos, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, orientationJointPos, orientationJointPos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); - gameRenderWorld->DebugLine( colorGreen, orientationJointPos, orientationJointPos + newLookAng.ToForward() * 48.0f, gameLocal.msec ); -#endif - - // determine pitch from joint position - dir = focusPos - eyepos; - dir.NormalizeFast(); - orientationJointAxis.ProjectVector( dir, localDir ); - newLookAng.pitch = -idMath::AngleNormalize180( localDir.ToPitch() ); - newLookAng.roll = 0.0f; - - diff = newLookAng - lookAng; - - if ( eyeAng != diff ) { - eyeAng = diff; - eyeAng.Clamp( eyeMin, eyeMax ); - idAngles angDelta = diff - eyeAng; - if ( !angDelta.Compare( ang_zero, 0.1f ) ) { - alignHeadTime = gameLocal.time; - } else { - alignHeadTime = gameLocal.time + static_cast(( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime); - } - } - - if ( idMath::Fabs( newLookAng.yaw ) < 0.1f ) { - alignHeadTime = gameLocal.time; - } - - if ( ( gameLocal.time >= alignHeadTime ) || ( gameLocal.time < forceAlignHeadTime ) ) { - alignHeadTime = gameLocal.time + static_cast(( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime); - destLookAng = newLookAng; - destLookAng.Clamp( lookMin, lookMax ); - } - - diff = destLookAng - lookAng; - if ( ( lookMin.pitch == -180.0f ) && ( lookMax.pitch == 180.0f ) ) { - if ( ( diff.pitch > 180.0f ) || ( diff.pitch <= -180.0f ) ) { - diff.pitch = 360.0f - diff.pitch; - } - } - if ( ( lookMin.yaw == -180.0f ) && ( lookMax.yaw == 180.0f ) ) { - if ( diff.yaw > 180.0f ) { - diff.yaw -= 360.0f; - } else if ( diff.yaw <= -180.0f ) { - diff.yaw += 360.0f; - } - } - lookAng = lookAng + diff * headFocusRate; - lookAng.Normalize180(); - - jointAng.roll = 0.0f; - - if (AI_AlertLevel >= thresh_5) - { - // use combat look joints in combat - - for( i = 0; i < lookJointsCombat.Num(); i++ ) - { - jointAng.pitch = lookAng.pitch * lookJointAnglesCombat[ i ].pitch; - jointAng.yaw = lookAng.yaw * lookJointAnglesCombat[ i ].yaw; - animator.SetJointAxis( lookJointsCombat[ i ], JOINTMOD_WORLD, jointAng.ToMat3() ); - } - } - else - { - for( i = 0; i < lookJoints.Num(); i++ ) - { - jointAng.pitch = lookAng.pitch * lookJointAngles[ i ].pitch; - jointAng.yaw = lookAng.yaw * lookJointAngles[ i ].yaw; - animator.SetJointAxis( lookJoints[ i ], JOINTMOD_WORLD, jointAng.ToMat3() ); - } - } - - if ( move.moveType == MOVETYPE_FLY ) { - // lean into turns - AdjustFlyingAngles(); - } - - if ( headEnt ) { - idAnimator *headAnimator = headEnt->GetAnimator(); - - if ( allowEyeFocus ) { - idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); - idMat3 headTranspose = headEnt->GetPhysics()->GetAxis().Transpose(); - axis = eyeAxis * orientationJointAxis; - left = axis[ 1 ] * eyeHorizontalOffset; - eyepos -= headEnt->GetPhysics()->GetOrigin(); - headAnimator->SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f + left ) * headTranspose ); - headAnimator->SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f - left ) * headTranspose ); - } else { - headAnimator->ClearJoint( leftEyeJoint ); - headAnimator->ClearJoint( rightEyeJoint ); - } - } else { - if ( allowEyeFocus ) { - idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); - axis = eyeAxis * orientationJointAxis; - left = axis[ 1 ] * eyeHorizontalOffset; - eyepos += axis[ 0 ] * 64.0f - physicsObj.GetOrigin(); - animator.SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + left ); - animator.SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos - left ); - } else { - animator.ClearJoint( leftEyeJoint ); - animator.ClearJoint( rightEyeJoint ); - } - } - - return true; -} - -/*********************************************************************** - -idCombatNode - -***********************************************************************/ - -const idEventDef EV_CombatNode_MarkUsed( "markUsed" ); - -CLASS_DECLARATION( idEntity, idCombatNode ) - EVENT( EV_CombatNode_MarkUsed, idCombatNode::Event_MarkUsed ) - EVENT( EV_Activate, idCombatNode::Event_Activate ) -END_CLASS - -/* -===================== -idCombatNode::idCombatNode -===================== -*/ -idCombatNode::idCombatNode( void ) { - min_dist = 0.0f; - max_dist = 0.0f; - cone_dist = 0.0f; - min_height = 0.0f; - max_height = 0.0f; - cone_left.Zero(); - cone_right.Zero(); - offset.Zero(); - disabled = false; -} - -/* -===================== -idCombatNode::Save -===================== -*/ -void idCombatNode::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( min_dist ); - savefile->WriteFloat( max_dist ); - savefile->WriteFloat( cone_dist ); - savefile->WriteFloat( min_height ); - savefile->WriteFloat( max_height ); - savefile->WriteVec3( cone_left ); - savefile->WriteVec3( cone_right ); - savefile->WriteVec3( offset ); - savefile->WriteBool( disabled ); -} - -/* -===================== -idCombatNode::Restore -===================== -*/ -void idCombatNode::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( min_dist ); - savefile->ReadFloat( max_dist ); - savefile->ReadFloat( cone_dist ); - savefile->ReadFloat( min_height ); - savefile->ReadFloat( max_height ); - savefile->ReadVec3( cone_left ); - savefile->ReadVec3( cone_right ); - savefile->ReadVec3( offset ); - savefile->ReadBool( disabled ); -} - -/* -===================== -idCombatNode::Spawn -===================== -*/ -void idCombatNode::Spawn( void ) { - float fov; - float yaw; - float height; - - min_dist = spawnArgs.GetFloat( "min" ); - max_dist = spawnArgs.GetFloat( "max" ); - height = spawnArgs.GetFloat( "height" ); - fov = spawnArgs.GetFloat( "fov", "60" ); - offset = spawnArgs.GetVector( "offset" ); - - const idVec3 &org = GetPhysics()->GetOrigin() + offset; - min_height = org.z - height * 0.5f; - max_height = min_height + height; - - const idMat3 &axis = GetPhysics()->GetAxis(); - yaw = axis[ 0 ].ToYaw(); - - idAngles leftang( 0.0f, yaw + fov * 0.5f - 90.0f, 0.0f ); - cone_left = leftang.ToForward(); - - idAngles rightang( 0.0f, yaw - fov * 0.5f + 90.0f, 0.0f ); - cone_right = rightang.ToForward(); - - disabled = spawnArgs.GetBool( "start_off" ); -} - -/* -===================== -idCombatNode::IsDisabled -===================== -*/ -bool idCombatNode::IsDisabled( void ) const { - return disabled; -} - -/* -===================== -idCombatNode::DrawDebugInfo -===================== -*/ -void idCombatNode::DrawDebugInfo( void ) { - idEntity *ent; - idCombatNode *node; - idPlayer *player = gameLocal.GetLocalPlayer(); - idVec4 color; - idBounds bounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 0 ) ); - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( !ent->IsType( idCombatNode::Type ) ) { - continue; - } - - node = static_cast( ent ); - if ( node->disabled ) { - color = colorMdGrey; - } else if ( player && node->EntityInView( player, player->GetPhysics()->GetOrigin() ) ) { - color = colorYellow; - } else { - color = colorRed; - } - - idVec3 leftDir( -node->cone_left.y, node->cone_left.x, 0.0f ); - idVec3 rightDir( node->cone_right.y, -node->cone_right.x, 0.0f ); - idVec3 org = node->GetPhysics()->GetOrigin() + node->offset; - - bounds[ 1 ].z = node->max_height; - - leftDir.NormalizeFast(); - rightDir.NormalizeFast(); - - const idMat3 &axis = node->GetPhysics()->GetAxis(); - float cone_dot = node->cone_right * axis[ 1 ]; - if ( idMath::Fabs( cone_dot ) > 0.1 ) { - float cone_dist = node->max_dist / cone_dot; - idVec3 pos1 = org + leftDir * node->min_dist; - idVec3 pos2 = org + leftDir * cone_dist; - idVec3 pos3 = org + rightDir * node->min_dist; - idVec3 pos4 = org + rightDir * cone_dist; - - gameRenderWorld->DebugLine( color, node->GetPhysics()->GetOrigin(), ( pos1 + pos3 ) * 0.5f, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos1, pos2, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos1, pos3, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos3, pos4, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos2, pos4, gameLocal.msec ); - gameRenderWorld->DebugBounds( color, bounds, org, gameLocal.msec ); - } - } -} - -/* -===================== -idCombatNode::EntityInView -===================== -*/ -bool idCombatNode::EntityInView( idActor *actor, const idVec3 &pos ) { - if ( !actor || ( actor->health <= 0 ) ) { - return false; - } - - const idBounds &bounds = actor->GetPhysics()->GetBounds(); - if ( ( pos.z + bounds[ 1 ].z < min_height ) || ( pos.z + bounds[ 0 ].z >= max_height ) ) { - return false; - } - - const idVec3 &org = GetPhysics()->GetOrigin() + offset; - const idMat3 &axis = GetPhysics()->GetAxis(); - idVec3 dir = pos - org; - float dist = dir * axis[ 0 ]; - - if ( ( dist < min_dist ) || ( dist > max_dist ) ) { - return false; - } - - float left_dot = dir * cone_left; - if ( left_dot < 0.0f ) { - return false; - } - - float right_dot = dir * cone_right; - if ( right_dot < 0.0f ) { - return false; - } - - return true; -} - -/* -===================== -idCombatNode::Event_Activate -===================== -*/ -void idCombatNode::Event_Activate( idEntity *activator ) { - disabled = !disabled; -} - -/* -===================== -idCombatNode::Event_MarkUsed -===================== -*/ -void idCombatNode::Event_MarkUsed( void ) { - if ( spawnArgs.GetBool( "use_once" ) ) { - disabled = true; - } -} - -// DarkMod sound propagation functions - -void idAI::SPLtoLoudness( SSprParms *propParms ) -{ - // put in frequency, duration and bandwidth effects here - propParms->loudness = propParms->propVol; -} - -bool idAI::CheckHearing( SSprParms *propParms ) -{ - bool returnval(false); - - if (propParms->loudness > m_AudThreshold) - { - returnval = true; - } - - return returnval; -} - -void idAI::HearSound(SSprParms *propParms, float noise, const idVec3& origin) -{ - if (m_bIgnoreAlerts) return; - - // TODO: - // Modify loudness by propVol/noise ratio, - // looking up a selectivity spawnarg on the AI to - // see how well the AI distinguishes signal from noise - - //psychLoud = pow(2, (propParms->loudness - threshold)/10 ); - // this scale didn't make much sense for the alerts ingame - // because the numbers would have been very close together for - // very different amounts of alert. - // It is better to keep it in dB. - - // and so alert units are born! - - /** - * NOTE: an AlertLevel of 1 constitutes just barely seeing something - * out of the corner of your eye, or just barely hearing a whisper - * of a sound for a short instant. An AlertLevel of 10 is seeing/hearing twice - * as much, 20 is four times as much, etc. - **/ - - // angua: alert increase is scaled by alertFactor (defined on prpagated sound). - // This way, different sounds can result in different alert increase at the same volume - float psychLoud = 1 + (propParms->loudness - m_AudThreshold) * propParms->alertFactor; - - // angua: alert increase can not exceed alertMax (defined on propagated sound) - if (psychLoud > propParms->alertMax) - { - psychLoud = propParms->alertMax; - } - - // don't alert the AI if they're deaf, or this is not a strong enough - // alert to overwrite another alert this frame - if (GetAcuity("aud") > 0 && psychLoud > m_AlertLevelThisFrame) - { - AI_HEARDSOUND = true; - m_SoundDir = origin; - - m_AlertedByActor = NULL; // grayman #2907 - needs to be cleared, otherwise it can be leftover from a previous sound this frame - - if (propParms->maker->IsType(idActor::Type)) - { - m_AlertedByActor = static_cast(propParms->maker); - } - else - { - // greebo: Take the responsible actor for motion sound - idActor* responsibleActor = propParms->maker->m_MovedByActor.GetEntity(); - if (responsibleActor != NULL) - { - m_AlertedByActor = responsibleActor; - } - } - - psychLoud *= GetAcuity("aud"); - - // angua: the actor who produced this noise is either unknown or an enemy - // alert now - if (!m_AlertedByActor.GetEntity() || IsEnemy(m_AlertedByActor.GetEntity())) - { - AlertAI( "aud", psychLoud ); - - // greebo: Notify the currently active state - mind->GetState()->OnAudioAlert(); - } - - // Retrieve the messages from the other AI, if there are any - if (propParms->makerAI != NULL) - { - for (int i = 0; i < propParms->makerAI->m_Messages.Num(); i++) - { - mind->GetState()->OnAICommMessage(*propParms->makerAI->m_Messages[i], psychLoud); - } - } - - if( cv_spr_show.GetBool() ) - { - gameRenderWorld->DrawText( va("Alert: %.2f", psychLoud), - (GetEyePosition() - GetPhysics()->GetGravityNormal() * 55.0f), 0.25f, - colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec * 30); - } - - if ( cv_ai_debug.GetBool() ) - { - gameLocal.Printf("AI %s HEARD a sound\n", name.c_str()); - } - } -} - -void idAI::AlertAI(const char *type, float amount) -{ - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("AlertAI called\r"); - - if (m_bIgnoreAlerts) - { - return; - } - - float acuity = GetAcuity(type); - // Calculate the amount the current AI_AlertLevel is about to be increased - // float alertInc = amount * acuity * 0.01f; // Acuity is defaulting to 100 (= 100%) - // angua: alert amount already includes acuity - - float alertInc = amount; - - // Ignore actors in notarget mode - idActor* actor = m_AlertedByActor.GetEntity(); - - if (actor != NULL && actor->fl.notarget) - { - // Actor is set to notarget, quit - return; - } - - if (m_AlertGraceTime) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period active, testing... \r"); - if (gameLocal.time > m_AlertGraceStart + m_AlertGraceTime) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period found to have expired. Resetting. \r"); - m_AlertGraceTime = 0; - m_AlertGraceActor = NULL; - m_AlertGraceStart = 0; - m_AlertGraceThresh = 0; - m_AlertGraceCount = 0; - m_AlertGraceCountLimit = 0; - } - else if (alertInc < m_AlertGraceThresh && - actor != NULL && - actor == m_AlertGraceActor.GetEntity() && - m_AlertGraceCount < m_AlertGraceCountLimit) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Grace period allowed, ignoring alert. \r"); - m_AlertGraceCount++; - - // Quick hack: Large lightgem values and visual alerts override the grace period count faster - if (AI_VISALERT) - { - // greebo: Let the alert grace count increase by 12.5% of the current lightgem value - // The maximum increase is therefore 32/8 = 4 based on DARKMOD_LG_MAX at the time of writing. - if (actor->IsType(idPlayer::Type)) - { - idPlayer* player = static_cast(actor); - m_AlertGraceCount += static_cast(idMath::Rint(player->GetCurrentLightgemValue() * 0.125f)); - } - } - return; - } - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Alert %f above threshold %f, or actor is not grace period actor\r", alertInc, m_AlertGraceThresh); - } - - // set the last alert value so that simultaneous alerts only overwrite if they are greater than the value - m_AlertLevelThisFrame = amount; - - // The grace check has failed, increase the AI_AlertLevel float by the increase amount - float newAlertLevel = AI_AlertLevel + alertInc; - SetAlertLevel(newAlertLevel); - m_lastAlertLevel = newAlertLevel; - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING( "AI ALERT: AI %s alerted by alert type \"%s\", amount %f (modified by acuity %f). Total alert level now: %f\r", name.c_str(), type, amount, acuity, (float) AI_AlertLevel ); - - if( cv_ai_debug.GetBool() ) - gameLocal.Printf("[TDM AI] ALERT: AI %s alerted by alert type \"%s\", base amount %f, modified by acuity %f percent. Total alert level now: %f\n", name.c_str(), type, amount, acuity, (float) AI_AlertLevel ); - - if (gameLocal.isNewFrame) - { - // AI has been alerted, set the boolean - AI_ALERTED = true; - } - - // Objectives callback - gameLocal.m_MissionData->AlertCallback( this, m_AlertedByActor.GetEntity(), static_cast(AI_AlertIndex) ); -} - -void idAI::SetAlertLevel(float newAlertLevel) -{ - // greebo: Clamp the (log) alert number to twice the combat threshold. - if (newAlertLevel > thresh_5*2) - { - newAlertLevel = thresh_5*2; - } - else if (newAlertLevel < 0) - { - newAlertLevel = 0; - } - - bool alertRising = (newAlertLevel > AI_AlertLevel); - - if (alertRising) - { - GetMemory().lastAlertRiseTime = gameLocal.time; - } - - if (AI_DEAD || AI_KNOCKEDOUT) return; - - AI_AlertLevel = newAlertLevel; - - if (AI_AlertLevel > m_maxAlertLevel) - { - m_maxAlertLevel = AI_AlertLevel; - } - - // grace period vars - float grace_time; - float grace_frac; - int grace_count; - - // How long should this alert level last, and which alert index should we be in now? - if (newAlertLevel >= thresh_4) - { - // greebo: Only allow switching to combat if a valid enemy is set. - if (newAlertLevel >= thresh_5) - { - if (GetEnemy() != NULL) - { - // We have an enemy, raise the index - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::ECombat; - } - else - { - // No enemy, can't switch to Combat mode - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::EAgitatedSearching; - // Set the alert level back to just below combat threshold - AI_AlertLevel = thresh_5 - 0.01; - } - } - else - { - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::EAgitatedSearching; - } - grace_time = m_gracetime_4; - grace_frac = m_gracefrac_4; - grace_count = m_gracecount_4; - } - else if (newAlertLevel >= thresh_3) - { - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::EInvestigating; - grace_time = m_gracetime_3; - grace_frac = m_gracefrac_3; - grace_count = m_gracecount_3; - } - else if (newAlertLevel >= thresh_2) - { - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::ESuspicious; - grace_time = m_gracetime_2; - grace_frac = m_gracefrac_2; - grace_count = m_gracecount_2; - } - else if (newAlertLevel >= thresh_1) - { - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::EObservant; - grace_time = m_gracetime_1; - grace_frac = m_gracefrac_1; - grace_count = m_gracecount_1; - } - else - { - m_prevAlertIndex = AI_AlertIndex; - AI_AlertIndex = ai::ERelaxed; - grace_time = 0.0; - grace_frac = 0.0; - grace_count = 0; - } - - // Tels: When the AI_AlertIndex increased, detach all bound entities - // that have set "unbindonalertIndex" higher or equal: - if (m_prevAlertIndex < AI_AlertIndex) - { - DetachOnAlert( AI_AlertIndex ); - } - - // greebo: Remember the highest alert index - if (AI_AlertIndex > m_maxAlertIndex) - { - m_maxAlertIndex = AI_AlertIndex; - } - - // Begin the grace period - if (alertRising) - { - Event_SetAlertGracePeriod( grace_frac, grace_time, grace_count ); - } -} - -bool idAI::AlertIndexIncreased() -{ - return (AI_AlertIndex > m_prevAlertIndex); -} - -float idAI::GetAcuity(const char *type) const -{ - float returnval(-1); - - // Try to lookup the ID in the hashindex. This corresponds to an entry in m_acuityNames. - int ind = g_Global.m_AcuityHash.First( g_Global.m_AcuityHash.GenerateKey(type, false) ); -// DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Retrived Acuity index %d for type %s\r", ind, type); - - if (ind == -1 ) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("AI %s attempted to query nonexistant acuity type: %s", name.c_str(), type); - gameLocal.Warning("[AI] AI %s attempted to query nonexistant acuity type: %s", name.c_str(), type); - return returnval; - } - else if (ind > m_Acuities.Num()) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Acuity index %d exceed acuity array size %d!\r", ind, m_Acuities.Num()); - return returnval; - } - - // Lookup the acuity value using the index from the hashindex - returnval = m_Acuities[ind]; - - // SZ: June 10, 2007 - // Acuities are now modified by alert level - if (returnval > 0.0) - { - if (m_maxAlertLevel >= thresh_5) - { - returnval *= cv_ai_acuity_L5.GetFloat(); - } - else if (m_maxAlertLevel >= thresh_4) - { - returnval *= cv_ai_acuity_L4.GetFloat(); - } - else if (m_maxAlertLevel >= thresh_3) - { - returnval *= cv_ai_acuity_L3.GetFloat(); - } - } - - // angua: drunken AI have reduced acuity, unless they have seen evidence of intruders - if (spawnArgs.GetBool("drunk", "0") && HasSeenEvidence() == false) - { - returnval *= spawnArgs.GetFloat("drunk_acuity_factor", "1"); - } - - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Acuity %s = %f\r", type, returnval); - - return returnval; -} - -void idAI::SetAcuity( const char *type, float acuity ) -{ - int ind; - - ind = g_Global.m_AcuityHash.First( g_Global.m_AcuityHash.GenerateKey( type, false ) ); - - if (ind == -1) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Script on %s attempted to set nonexistant acuity type: %s\r",name.c_str(), type); - gameLocal.Warning("[AI] Script on %s attempted to set nonexistant acuity type: %s",name.c_str(), type); - goto Quit; - } - else if( ind > m_Acuities.Num() ) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Script on %s attempted to set acuity with an index %d greater than acuities array size %d!\r", ind, m_Acuities.Num() ); - goto Quit; - } - - m_Acuities[ind] = acuity; - -Quit: - return; -} - -idVec3 idAI::GetSndDir( void ) -{ - return m_SoundDir; -} - -idVec3 idAI::GetVisDir( void ) -{ - return m_LastSight; -} - -idEntity *idAI::GetTactEnt( void ) -{ - return m_TactAlertEnt.GetEntity(); -} - -void idAI::PerformVisualScan(float timecheck) -{ - // Only perform enemy checks if we are in the player's PVS - if (GetAcuity("vis") <= 0 || !gameLocal.InPlayerPVS(this)) - { - return; - } - - idActor* player = gameLocal.GetLocalPlayer(); - if (m_bIgnoreAlerts || player->fl.notarget) - { - // notarget - return; - } - - // Ignore dead actors or non-enemies - if (player->health <= 0 || !IsEnemy(player)) - { - return; - } - - if (!CheckFOV(player->GetEyePosition())) - { - return; - } - - // Check the candidate's visibility. - float visFrac = GetVisibility(player); - // Do the percentage check - float randFrac = gameLocal.random.RandomFloat(); - float chance = timecheck / s_VisNormtime * cv_ai_sight_prob.GetFloat() * visFrac; - if( randFrac > chance) - { - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Random number check failed: random %f > number %f\r", randFrac, (timecheck / s_VisNormtime) * visFrac ); - return; - } - - // angua: does not take lighting and FOV into account - if (!CanSeeExt(player, false, false)) - { - return; - } - - // greebo: At this point, the actor is identified as enemy and is visible - // set AI_VISALERT and the vector for last sighted position - // Store the position the enemy was visible - m_LastSight = player->GetPhysics()->GetOrigin(); - AI_VISALERT = true; - - // Get the visual alert amount caused by the CVAR setting - // float incAlert = GetPlayerVisualStimulusAmount(); - - // angua: alert increase depends on brightness, distance and acuity - float incAlert = 4 + 9 * visFrac; - - if (cv_ai_visdist_show.GetFloat() > 0) - { - gameRenderWorld->DrawText("see you!", GetEyePosition() + idVec3(0,0,70), 0.2f, idVec4( 0.5f, 0.00f, 0.00f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 60 * gameLocal.msec); - gameRenderWorld->DrawText(va("Alert increase: %.2f", incAlert), GetEyePosition() + idVec3(0,0,60), 0.2f, idVec4( 0.5f, 0.00f, 0.00f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 60 * gameLocal.msec); - } - - float newAlertLevel = AI_AlertLevel + incAlert; - if (newAlertLevel > thresh_5) - { - SetEnemy(player); - } - - // If the alert amount is larger than everything else encountered this frame - // ignore the previous alerts and remember this actor as enemy. - if (incAlert > m_AlertLevelThisFrame) - { - // Remember this actor - m_AlertedByActor = player; - AlertAI("vis", incAlert); - - // Call the visual alert handler on the current state - mind->GetState()->OnVisualAlert(player); - } - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s SAW actor %s\r", name.c_str(), player->name.c_str() ); - - return; -} - - -float idAI::GetVisibility( idEntity *ent ) const -{ - // Returns the probability that the entity will be seen within half a second - // depends on light gem brightness, visual acuity and player distance - - float returnval(0); - - // for now, only players may have their visibility checked - if (!ent->IsType( idPlayer::Type )) - { - return returnval; - } - idPlayer* player = static_cast(ent); - - // angua: probability for being seen (within half a second) - // this depends only on the brightness of the light gem and the AI's visual acuity - float clampVal = GetCalibratedLightgemValue(); - - /** - * angua: within the clampDist, the probability stays constant - * the probability decreases linearly towards 0 between clampdist and savedist - * both distances are scaled with clampVal - */ - float clampdist = cv_ai_sightmindist.GetFloat() * clampVal; - float safedist = clampdist + (cv_ai_sightmaxdist.GetFloat() - cv_ai_sightmindist.GetFloat()) * clampVal; - - idVec3 delta = GetEyePosition() - player->GetEyePosition(); - float dist = delta.Length()*s_DOOM_TO_METERS; - - if (dist < clampdist) - { - returnval = clampVal; - } - else - { - if (dist > safedist) - { - returnval = 0; - } - else - { - returnval = clampVal * (1 - (dist-clampdist)/(safedist-clampdist) ); - } - } - - if (cv_ai_visdist_show.GetFloat() > 0) - { - idStr alertText(clampVal); - alertText = "clampVal: "+ alertText; - gameRenderWorld->DrawText(alertText.c_str(), GetEyePosition() + idVec3(0,0,1), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - idStr alertText2(clampdist); - alertText2 = "clampdist: "+ alertText2; - gameRenderWorld->DrawText(alertText2.c_str(), GetEyePosition() + idVec3(0,0,10), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - gameRenderWorld->DebugCircle(idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), GetPhysics()->GetOrigin(),idVec3(0,0,1), clampdist / s_DOOM_TO_METERS, 100, gameLocal.msec); - idStr alertText3(safedist); - alertText3 = "savedist: "+ alertText3; - gameRenderWorld->DrawText(alertText3.c_str(), GetEyePosition() + idVec3(0,0,20), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - gameRenderWorld->DebugCircle(idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), GetPhysics()->GetOrigin(),idVec3(0,0,1), safedist / s_DOOM_TO_METERS, 100, gameLocal.msec); - idStr alertText4(returnval); - alertText4 = "returnval: "+ alertText4; - gameRenderWorld->DrawText(alertText4.c_str(), GetEyePosition() + idVec3(0,0,30), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - idStr alertText5(dist); - alertText5 = "distance: "+ alertText5; - gameRenderWorld->DrawText(alertText5.c_str(), GetEyePosition() + idVec3(0,0,-10), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - } - - return returnval; -} - -float idAI::GetCalibratedLightgemValue() const -{ - idPlayer* player = gameLocal.GetLocalPlayer(); - if (player == NULL) return 0.0f; - - float lgem = static_cast(player->GetCurrentLightgemValue()); - - float term0 = -0.003f; - float term1 = 0.03f * lgem; - float term2 = 0.001f * idMath::Pow16(lgem, 2); - float term3 = 0.00013f * idMath::Pow16(lgem, 3); - float term4 = - 0.000011f * idMath::Pow16(lgem, 4); - float term5 = 0.0000001892f * idMath::Pow16(lgem, 5); - - float clampVal = term0 + term1 + term2 + term3 + term4 + term5; - - clampVal *= GetAcuity("vis"); - - if (clampVal > 1) - { - clampVal = 1; - } - - // Debug output - if (cv_ai_visdist_show.GetFloat() > 0) - { - idStr alertText5(lgem); - alertText5 = "lgem: "+ alertText5; - gameRenderWorld->DrawText(alertText5.c_str(), GetEyePosition() + idVec3(0,0,40), 0.2f, idVec4( 0.15f, 0.15f, 0.15f, 1.00f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); - } - - return clampVal; -} - -void idAI::TactileAlert(idEntity* tactEnt, float amount) -{ - if (AI_DEAD || AI_KNOCKEDOUT || m_bIgnoreAlerts) - { - return; - } - - if (tactEnt == NULL || CheckTactileIgnore(tactEnt)) - { - return; - } - - // grayman #2872 - have we encountered a dangling rope from a rope arrow? - - if ( tactEnt->IsType(idAFEntity_Generic::Type) ) - { - if ( idStr::FindText( tactEnt->name, "env_rope" ) >= 0 ) - { - // Ignore the rope if you have an enemy. - - if ( GetEnemy() == NULL ) - { - // Find the bindMaster for this rope, then see if there's a CProjectileResult bound to it. - - idEntity* bindMaster = tactEnt->GetBindMaster(); - if ( bindMaster != NULL ) - { - idEntity* stimSource = bindMaster->FindMatchingTeamEntity( CProjectileResult::Type ); - if ( stimSource != NULL ) - { - if ( !stimSource->CheckResponseIgnore(ST_VISUAL,this) ) // only react if you haven't encountered this rope before, - // either by bumping it or receiving its stim - { - // What's the chance of noticing this rope? If it's zero, you're to ignore the rope. - // If it's greater than zero, and even if it's less than 1.0, you walked into the - // rope, so we expect you to notice it. - - float chanceToNotice = spawnArgs.GetFloat("chanceNoticeRope","0.0"); - if ( chanceToNotice > 0.0 ) - { - if ( mind->GetState()->ShouldProcessAlert(ai::EAlertTypeRope) ) - { - mind->GetState()->OnVisualStimRope(stimSource,this,GetEyePosition()); - } - } - else // This rope stim should stop sending me stims - { - stimSource->IgnoreResponse(ST_VISUAL, this); - } - } - } - } - } - } - - return; - } - - // The actor is either the touched entity or the originator of the tactile alert - idActor* responsibleActor = - (tactEnt->IsType(idActor::Type)) ? static_cast(tactEnt) : tactEnt->m_SetInMotionByActor.GetEntity(); - - if (responsibleActor == NULL) - { - return; - } - - if (IsFriend(responsibleActor)) - { - if (responsibleActor->health <= 0 || responsibleActor->IsKnockedOut()) - { - // angua: We've found a friend that is dead or unconscious - mind->GetState()->OnPersonEncounter(tactEnt, this); - } - } - if (!IsEnemy(responsibleActor)) - { - return; // not an enemy, no alert - } - - // greebo: We touched an enemy, check if it's an unconscious body or corpse - if (tactEnt->IsType(idAI::Type) && - (static_cast(tactEnt)->AI_DEAD || static_cast(tactEnt)->AI_KNOCKEDOUT)) - { - // When AI_DEAD or AI_KNOCKEDOUT ignore this alert from now on to avoid - // re-alerting us every time we touch it again and again - TactileIgnore(tactEnt); - } - - // Set the alert amount to the according tactile alert value - if (amount == -1) - { - amount = cv_ai_tactalert.GetFloat(); - } - - // If we got this far, we give the alert - // NOTE: Latest tactile alert always overrides other alerts - m_TactAlertEnt = tactEnt; - m_AlertedByActor = responsibleActor; - - amount *= GetAcuity("tact"); - AlertAI("tact", amount); - - // Notify the currently active state - mind->GetState()->OnTactileAlert(tactEnt); - - // Set last visual contact location to this location as that is used in case - // the target gets away - m_LastSight = tactEnt->GetPhysics()->GetOrigin(); - - // If no enemy set so far, set the last visible enemy position. - if (GetEnemy() == NULL) - { - lastVisibleEnemyPos = tactEnt->GetPhysics()->GetOrigin(); - } - - AI_TACTALERT = true; - - if( cv_ai_debug.GetBool() ) - { - // Note: This can spam the log a lot, so only put it in if cv_ai_debug.GetBool() is true - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s FELT entity %s\r", name.c_str(), tactEnt->name.c_str() ); - gameLocal.Printf( "[DM AI] AI %s FELT entity %s\n", name.c_str(), tactEnt->name.c_str() ); - } -} - -void idAI::TactileIgnore(idEntity* tactEnt) -{ - tactileIgnoreEntities.insert(tactEnt); -} - -bool idAI::CheckTactileIgnore(idEntity* tactEnt) -{ - TactileIgnoreList::iterator i = tactileIgnoreEntities.find(tactEnt); - if (i != tactileIgnoreEntities.end()) - { - return true; - } - return false; -} - - - - -idActor *idAI::FindEnemy(bool useFOV) -{ - // Only perform enemy checks if we are in the player's PVS - if (!gameLocal.InPlayerPVS(this)) - { - return NULL; - } - - // Go through all clients (=players) - for (int i = 0; i < gameLocal.numClients ; i++) - { - idEntity* ent = gameLocal.entities[i]; - - if (ent == NULL || ent->fl.notarget || !ent->IsType(idActor::Type)) - { - // NULL, notarget or non-Actor, continue - continue; - } - - idActor* actor = static_cast(ent); - - // Ignore dead actors or non-enemies - if (actor->health <= 0 || !IsEnemy(actor)) - { - continue; - } - - // angua: does not take lighting into account any more, - // this is done afterwards using GetVisibility - if (CanSeeExt(actor, useFOV, false)) - { - // Enemy actor found and visible, return it - return actor; - } - } - - return NULL; -} - -idActor* idAI::FindEnemyAI(bool useFOV) -{ - pvsHandle_t pvs = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); - - float bestDist = idMath::INFINITY; - idActor* bestEnemy = NULL; - - for (idEntity* ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - if ( ent->fl.hidden || ent->fl.isDormant || ent->fl.notarget || !ent->IsType( idActor::Type ) ) { - continue; - } - - idActor* actor = static_cast( ent ); - if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { - continue; - } - - if ( !gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas() ) ) { - continue; - } - - idVec3 delta = physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin(); - float dist = delta.LengthSqr(); - if ( ( dist < bestDist ) && CanSee( actor, useFOV != 0 ) ) { - bestDist = dist; - bestEnemy = actor; - } - } - - gameLocal.pvs.FreeCurrentPVS(pvs); - return bestEnemy; -} - -idActor* idAI::FindFriendlyAI(int requiredTeam) -{ -// This is our return value - idActor* candidate(NULL); - // The distance of the nearest found AI - float bestDist = idMath::INFINITY; - - // Setup the PVS areas of this entity using the PVSAreas set, this returns a handle - pvsHandle_t pvs(gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas())); - - // Iterate through all active entities and find an AI with the given team. - for (idEntity* ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - if ( ent == this || ent->fl.hidden || ent->fl.isDormant || !ent->IsType( idActor::Type ) ) { - continue; - } - - idActor* actor = static_cast(ent); - if (actor->health <= 0) { - continue; - } - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Taking actor %s into account\r", actor->name.c_str()); - - if (requiredTeam != -1 && actor->team != requiredTeam) { - // wrong team - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Taking actor %s has wrong team: %d\r", actor->name.c_str(), actor->team); - continue; - } - - if (!IsFriend(actor)) - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s is not on friendly team: %d or has specific relation that is not friendly\r", actor->name.c_str(), actor->team); - // Not friendly - continue; - } - - if (!gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas())) { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Actor %s is not in PVS\r", actor->name.c_str()); - // greebo: This actor is not in our PVS, skip it - continue; - } - - float dist = (physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin()).LengthSqr(); - if ( (dist < bestDist) && CanSee(actor, true) ) { - // Actor can be seen and is nearer than the best candidate, save it - bestDist = dist; - candidate = actor; - } - } - - gameLocal.pvs.FreeCurrentPVS(pvs); - - return candidate; - -} - - -/*---------------------------------------------------------------------------------*/ - -float idAI::GetMaximumObservationDistanceForPoints(const idVec3& p1, const idVec3& p2) const -{ - return LAS.queryLightingAlongLine(p1, p2, NULL, true) * cv_ai_sight_scale.GetFloat() * GetAcuity("vis"); -} - -float idAI::GetMaximumObservationDistance(idEntity* entity) const -{ - assert(entity != NULL); // don't accept NULL input - - float lightQuotient = entity->GetLightQuotient(); - - return lightQuotient * cv_ai_sight_scale.GetFloat() * GetAcuity("vis"); -} - -/*---------------------------------------------------------------------------------*/ - -float idAI::GetPlayerVisualStimulusAmount() const -{ - float alertAmount = 0.0; - - // Quick fix for blind AI: - if (GetAcuity("vis") > 0 ) - { - // float visFrac = GetVisibility( p_playerEntity ); - // float lgem = (float) g_Global.m_DarkModPlayer->m_LightgemValue; - // Convert to alert units ( 0.6931472 = ln(2) ) - // Old method, commented out - // alertAmount = 4*log( visFrac * lgem ) / 0.6931472; - - // The current alert number is stored in logarithmic units - float curAlertLog = AI_AlertLevel; - - // convert current alert from log to linear scale, add, then convert back - // this might not be as good for performance, but it lets us keep all alerts - // on the same scale. - if (curAlertLog > 0) - { - // greebo: Convert log to lin units by using Alin = 2^[(Alog-1)/10] - float curAlertLin = idMath::Pow16(2, (curAlertLog - 1)*0.1f); - - // Increase the linear alert number with the cvar - curAlertLin += cv_ai_sight_mag.GetFloat(); - - // greebo: Convert back to logarithmic alert units - // The 1.44269 in the equation is the 1/ln(2) used to compensate for using the natural Log16 method. - curAlertLog = 1 + 10.0f * idMath::Log16(curAlertLin) * 1.442695f; - - // Now calculate the difference in logarithmic units and return it - alertAmount = curAlertLog - AI_AlertLevel; - } - else - { - alertAmount = 1; - } - } - - return alertAmount; -} - -/*---------------------------------------------------------------------------------*/ - -bool idAI::IsEntityHiddenByDarkness(idEntity* p_entity, const float sightThreshold) const -{ - // Quick test using LAS at entity origin - idPhysics* p_physics = p_entity->GetPhysics(); - - if (p_physics == NULL) - { - return false; // Not in darkness - } - - // Use lightgem if it is the player - if (p_entity->IsType(idPlayer::Type)) - { - // Get the alert increase amount (log) caused by the CVAR tdm_ai_sight_mag - // greebo: Commented this out, this is not suitable to detect if player is hidden in darkness - //float incAlert = GetPlayerVisualStimulusAmount(); - - // greebo: Check the visibility of the player depending on lgem and distance - float visFraction = GetCalibratedLightgemValue(); // returns values in [0..1] -/* - // greebo: Debug output, comment me out - gameRenderWorld->DrawText(idStr(visFraction), GetEyePosition() + idVec3(0,0,1), 0.11f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); -*/ - // Draw debug graphic - /*if (cv_ai_visdist_show.GetFloat() > 1.0) - { - idVec4 markerColor (0.0, 0.0, 0.0, 0.0); - - float percToSeen = 1.0; - if (sightThreshold > 0 && sightThreshold > incAlert) - { - percToSeen = (sightThreshold - incAlert) / sightThreshold; - } - - // Scale red to green from not perceptable to quickly perceptable - markerColor.x = idMath::Sin (percToSeen * (idMath::PI / 2.0)); - markerColor.y = idMath::Cos (percToSeen * (idMath::PI / 2.0)); - - idVec3 observeFrom = GetEyePosition(); - - gameRenderWorld->DebugArrow(markerColor, observeFrom, p_physics->GetOrigin(), 2, cv_ai_visdist_show.GetInteger()); - }*/ - - // Very low threshold for visibility - if (visFraction < sightThreshold) - { - // Not visible, entity is hidden in darkness - return true; - } - else - { - // Visible, visual stim above threshold - return false; - } - } - else // Not the player - { - float maxDistanceToObserve = GetMaximumObservationDistance(p_entity); - - // Are we close enough to see it in the current light level? - idVec3 observeFrom = GetEyePosition(); - idVec3 midPoint = p_entity->GetPhysics()->GetAbsBounds().GetCenter(); - - if ( (observeFrom - midPoint).LengthSqr() > maxDistanceToObserve*maxDistanceToObserve ) - { - // Draw debug graphic? - if (cv_ai_visdist_show.GetFloat() > 1.0f) - { - idVec3 arrowLength = midPoint - observeFrom; - arrowLength.Normalize(); - arrowLength *= maxDistanceToObserve; - - // Distance we could see - gameRenderWorld->DebugArrow(colorRed, observeFrom, observeFrom + arrowLength, 2, cv_ai_visdist_show.GetInteger()); - - // Gap to where we want to see - gameRenderWorld->DebugArrow(colorMagenta, observeFrom + arrowLength, midPoint, 2, cv_ai_visdist_show.GetInteger()); - } - - return true; // hidden by darkness - } - else - { - // Draw debug graphic? - if (cv_ai_visdist_show.GetFloat() > 1.0f) - { - // We can see to target - gameRenderWorld->DebugArrow(colorGreen, observeFrom, midPoint, 2, cv_ai_visdist_show.GetInteger()); - } - - return false; // not hidden by darkness - } - } -} - -/*---------------------------------------------------------------------------------*/ - -idActor *idAI::FindNearestEnemy( bool useFOV ) -{ - idEntity *ent; - idActor *actor, *playerEnemy; - idActor *bestEnemy; - float bestDist; - float dist; - idVec3 delta; - pvsHandle_t pvs; - - pvs = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); - - bestDist = idMath::INFINITY; - bestEnemy = NULL; - - for ( ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - if ( ent->fl.hidden || ent->fl.isDormant || !ent->IsType( idActor::Type ) ) - { - continue; - } - - actor = static_cast( ent ); - if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) - { - continue; - } - - if ( !gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas() ) ) - { - continue; - } - - delta = physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin(); - dist = delta.LengthSqr(); - if ( ( dist < bestDist ) && CanSee( actor, useFOV ) ) { - bestDist = dist; - bestEnemy = actor; - } - } - - playerEnemy = FindEnemy(false); - if( !playerEnemy ) - goto Quit; - - delta = physicsObj.GetOrigin() - playerEnemy->GetPhysics()->GetOrigin(); - dist = delta.LengthSqr(); - - if( dist < bestDist ) - bestEnemy = playerEnemy; - bestDist = dist; - -Quit: - gameLocal.pvs.FreeCurrentPVS( pvs ); - return bestEnemy; -} - - - -void idAI::HadTactile( idActor *actor ) -{ - if( !actor ) - goto Quit; - - if( IsEnemy( actor) ) - TactileAlert( actor ); - else - { - // TODO: FLAG BLOCKED BY FRIENDLY SO THE SCRIPT CAN DO SOMETHING ABOUT IT - - // grayman #2728 - If blocked by an AI of small mass, kick it aside immediately. If you leave it to normal - // block resolution, the larger AI will appear to be momentarily stopped by the small AI, - // which is not what you'd expect to see. - - float actorMass = actor->GetPhysics()->GetMass(); - if ((actorMass <= 5.0) && (physicsObj.GetMass() > 5.0)) - { - if (gameLocal.time >= actor->m_nextKickTime) // but only if not recently kicked - { - KickObstacles(viewAxis[0],1.25*kickForce*actorMass,actor); - actor->m_nextKickTime = gameLocal.time + 1000; // need to wait before kicking again, - // otherwise kicks can build up over adjacent frames - } - } - } - - // alert both AI if they bump into eachother - if( actor->IsEnemy(this) - && actor->IsType(idAI::Type) ) - { - static_cast(actor)->TactileAlert( this ); - } - -Quit: - return; -} - -/* -===================== -idAI::GetMovementVolMod -===================== -*/ - -float idAI::GetMovementVolMod( void ) -{ - float returnval; - bool bCrouched(false); - - if( AI_CROUCH ) - bCrouched = true; - - // figure out which of the 6 cases we have: - if( !AI_RUN && !AI_CREEP ) - { - if( !bCrouched ) - returnval = m_stepvol_walk; - else - returnval = m_stepvol_crouch_walk; - } - - // NOTE: running always has priority over creeping - else if( AI_RUN ) - { - if( !bCrouched ) - returnval = m_stepvol_run; - else - returnval = m_stepvol_crouch_run; - } - - else if( AI_CREEP ) - { - if( !bCrouched ) - returnval = m_stepvol_creep; - else - returnval = m_stepvol_crouch_creep; - } - - else - { - // something unexpected happened - returnval = 0; - } - - return returnval; -} - -/* -===================== -idAI::CheckTactile - -Modified 5/25/06 , removed trace computation, found better way of checking -===================== -*/ -void idAI::CheckTactile() -{ - // Only check tactile alerts if we aren't Dead, KO or already engaged in combat. - - // grayman #2345 - changed to handle the waiting, non-solid state for AI - - bool bumped = false; - idEntity* blockingEnt = NULL; - if (!AI_KNOCKEDOUT && !AI_DEAD && (AI_AlertLevel < thresh_5) && !movementSubsystem->IsWaitingNonSolid()) // no bump if I'm waiting - { - blockingEnt = physicsObj.GetSlideMoveEntity(); - if (blockingEnt) // grayman #2345 - note what we bumped into - { - if (blockingEnt->name != "world") // ignore bumping into the world - { - m_tactileEntity = blockingEnt; - - if ( blockingEnt->IsType(idAI::Type) ) - { - idAI* blockingAI = static_cast(blockingEnt); - - // grayman #2903 - if both AI are examining a rope, it's possible that - // they're both trying to reach the same examination spot. If one is not - // moving, he's examining, so the other has to stop where he is. This - // prevents the one standing from turning non-solid and allowing the other - // to merge with him. Looks bad. - - if ( m_ExaminingRope && blockingAI->m_ExaminingRope ) - { - if ( AI_FORWARD && !blockingAI->AI_FORWARD ) - { - StopMove(MOVE_STATUS_DONE); - } - else if ( !AI_FORWARD && blockingAI->AI_FORWARD ) - { - blockingAI->StopMove(MOVE_STATUS_DONE); - } - } - } - } - } - - if (blockingEnt && blockingEnt->IsType(idPlayer::Type)) // player has no movement subsystem - { - // aesthetics: Dont react to dead player? - if (blockingEnt->health > 0) - { - bumped = true; - } - } - else if (blockingEnt && blockingEnt->IsType(idActor::Type)) - { - idAI *e = static_cast(blockingEnt); - if (e && !e->movementSubsystem->IsWaitingNonSolid()) // no bump if other entity is waiting - { - bumped = true; - } - } - } - - if (bumped) - { - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("TACT: AI %s is bumping actor %s.\r", name.c_str(), blockingEnt->name.c_str() ); - HadTactile(static_cast(blockingEnt)); - } -} - -bool idAI::HasSeenEvidence() const -{ - ai::Memory& memory = GetMemory(); - - return memory.enemiesHaveBeenSeen - || memory.hasBeenAttackedByEnemy - || memory.itemsHaveBeenStolen - || memory.itemsHaveBeenBroken - || memory.unconsciousPeopleHaveBeenFound - || memory.deadPeopleHaveBeenFound - || spawnArgs.GetBool("alert_idle", "0"); -} - -/** -* ========================== BEGIN TDM KNOCKOUT CODE ============================= -**/ - -/* -===================== -idAI::TestKnockoutBlow -===================== -*/ - -bool idAI::TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ) -{ - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Attempted KO of AI %s\r", name.c_str()); - - if ( AI_DEAD ) - { - return false; // already dead - } - - if ( AI_KNOCKEDOUT ) - { - AI_PAIN = true; - AI_DAMAGE = true; - - return false; // already knocked out - } - - const char* locationName = GetDamageGroup( location ); - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s hit with KO object in joint %d corresponding to damage group %s\r", name.c_str(), location, locationName); - - // check if we're hitting the right zone (usually the head) - if ( idStr::Cmp(locationName, m_KoZone) != 0 ) - { - // Signal the failed KO to the current state - GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, false); - - return false; // damage zone not matching - } - - // check if we hit within the angles - if ( m_HeadJointID == INVALID_JOINT ) - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Invalid head joint for joint found on AI %s when KO attempted \r", name.c_str()); - return false; - } - - // Get the KO angles - float minDotVert = m_KoDotVert; - float minDotHoriz = m_KoDotHoriz; - - // Check if the AI is above the alert threshold for Immunity - // Defined the name of the alert threshold in the AI def for generality - -/* grayman #2930 - follow these rules to determine immunity: - - 1. Civilians can be knocked out at any time, from any angle, at any alert level. - 2. If the AI's alert level is at least m_KoAlertImmuneState, and - m_bKoAlertImmune is TRUE, the AI is immune. - 3. If the AI has a sheathed weapon or no weapon, and their alert level - is below m_KoAlertImmuneState, a KO can occur from any direction. - 4. If the AI is ready to do combat (usually a drawn weapon), and their - m_KoAlertImmuneState == 4 (helmet), they're immune, even if they're at a lower alert level. - 5. If the AI is ready to do combat (usually a drawn weapon), and their - m_KoAlertImmuneState == 5 (no helmet), and their current alert level is - below m_KoAlertImmuneState, a KO can occur only from behind. - 6. Finally, check the KO angles and determine if the blow has landed in the right place. - */ - - bool immune2KO = false; - if ( spawnArgs.GetBool("is_civilian", "0") ) - { - // Rule #1 - } - // everyone else is a combatant - else if ( AI_AlertIndex >= m_KoAlertImmuneState ) - { - // is the AI immune at high alert levels? - if ( m_bKoAlertImmune ) - { - immune2KO = true; // Rule #2 - } - else - { - // At high alert levels, use different values - minDotVert = m_KoAlertDotVert; - minDotHoriz = m_KoAlertDotHoriz; - } - } - // alert level isn't high enough for carte-blanche immunity, so check other factors - else if ( GetAttackFlag(COMBAT_MELEE) || GetAttackFlag(COMBAT_RANGED) ) - { - if ( m_KoAlertImmuneState == 4 ) // wearing helmet? - { - immune2KO = true; // Rule #4 - } - else // Rule #5 - { - // A KO can occur only from behind, when this AI is more likely to be surprised - - idVec3 aiForward = viewAxis.ToAngles().ToForward(); - if ( dir * aiForward < 0.0f ) - { - immune2KO = true; // attacked from the front - } - else - { - // Rule #5 - // attacked from behind, so not immune - - // treat a drawn weapon or an unarmed AI that can fight as a highly alerted state for KO purposes - minDotVert = m_KoAlertDotVert; - minDotHoriz = m_KoAlertDotHoriz; - } - } - } - else - { - // Rule #3 - sheathed weapon or no weapon; not immune - } - - if ( immune2KO ) - { - // Signal the failed KO to the current state - GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, true); - return false; // AI is immune, so no KO this time - } - - idVec3 KOSpot; - idMat3 headAxis; - // store head joint base position to KOSpot, axis to HeadAxis - GetJointWorldTransform( m_HeadJointID, gameLocal.time, KOSpot, headAxis ); - - KOSpot += headAxis * m_HeadCenterOffset; - idMat3 headAxisR = headAxis * m_KoRot; - - idVec3 delta = KOSpot - tr->c.point; - float lenDelta = delta.Length(); - - // First, project delta into the horizontal plane of the head - // Assume HeadAxis[1] is the up direction in head coordinates - idVec3 deltaH = delta - headAxisR[1] * (headAxisR[1] * delta); - float lenDeltaH = deltaH.Normalize(); - - float dotHoriz = headAxisR[ 0 ] * deltaH; - // cos (90-zenith) = adjacent / hypotenuse, applied to these vectors - float dotVert = idMath::Fabs( lenDeltaH / lenDelta ); - - // if hit was within the cone - if ( ( dotHoriz >= minDotHoriz ) && ( dotVert >= minDotVert) ) - { - // We just got knocked the taff out! - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("AI %s was knocked out by a blow to the head\r", name.c_str()); - Event_KO_Knockout(attacker); // grayman #2468 - - return true; - } - - // Rule #6 - blow wasn't in the right place - - // Signal the failed KO to the current state - GetMind()->GetState()->OnFailedKnockoutBlow(attacker, dir, true); - - return false; // knockout angles missed -} - -void idAI::KnockoutDebugDraw( void ) -{ - float AngVert(0), AngHoriz(0), radius(0); - idVec3 KOSpot(vec3_zero), ConeDir(vec3_zero); - idMat3 HeadAxis(mat3_zero); - - const char * testZone = m_KoZone.c_str(); - if( AI_KNOCKEDOUT || AI_DEAD || testZone[0] == '\0' ) - { - return; - } - - // Check if the AI is above the alert threshold for KOing - // Defined the name of the alert threshold in the AI def for generality - if( AI_AlertIndex >= m_KoAlertState) - { - // Do not display if immune - if( m_bKoAlertImmune && AI_AlertIndex >= m_KoAlertImmuneState ) - return; - - // reduce the angle on alert, if needed - AngVert = idMath::ACos( m_KoAlertDotVert ); - AngHoriz = idMath::ACos( m_KoAlertDotHoriz ); - } - else - { - AngVert = idMath::ACos( m_KoDotVert ); - AngHoriz = idMath::ACos( m_KoDotHoriz ); - } - - if( AngVert == 0.0f ) - AngVert = 360.0f; - if( AngHoriz == 0.0f ) - AngHoriz = 360.0f; - - if( m_HeadJointID == INVALID_JOINT ) - { - return; - } - - // store head joint base position to KOSpot, axis to HeadAxis - GetJointWorldTransform( m_HeadJointID, gameLocal.time, KOSpot, HeadAxis ); - - KOSpot += HeadAxis * m_HeadCenterOffset; - idMat3 HeadAxisR = HeadAxis * m_KoRot; - - // Assumes the head joint is facing the same way as the look joint - ConeDir = -HeadAxisR[0]; - - // vertical angle in green - radius = AngVert * 0.5f * 30.0f; - gameRenderWorld->DebugCone( colorGreen, KOSpot, 30.0f * ConeDir, 0, radius, gameLocal.msec ); - // horizontal angle in red - radius = AngHoriz * 0.5f * 30.0f; - gameRenderWorld->DebugCone( colorRed, KOSpot, 30.0f * ConeDir, 0, radius, gameLocal.msec ); -} - -/* -===================== -idAI::Event_KO_Knockout -===================== -*/ - -void idAI::Event_KO_Knockout( idEntity* inflictor ) -{ - if (m_bCanBeKnockedOut) // grayman #2468 - new place to test ko immunity - { - m_koState = KO_BLACKJACK; // grayman #2604 - Knockout(inflictor); - } -} - -/* -===================== -idAI::Event_Gas_Knockout -===================== -*/ - -void idAI::Event_Gas_Knockout( idEntity* inflictor ) -{ - if (m_bCanBeGassed) // grayman #2468 - new place to test gas immunity - { - m_koState = KO_GAS; // grayman #2604 - Knockout(inflictor); - } -} - -/* -===================== -idAI::Knockout - -Based on idAI::Killed -===================== -*/ - -void idAI::Knockout( idEntity* inflictor ) -{ - idAngles ang; - -// if( !m_bCanBeKnockedOut ) // grayman #2468 - this test has been moved up a level -// return; - - if( AI_KNOCKEDOUT || AI_DEAD ) - { - AI_PAIN = true; - AI_DAMAGE = true; - - return; - } - - EndAttack(); - - // stop all voice sounds - StopSound( SND_CHANNEL_VOICE, false ); - if ( head.GetEntity() ) - { - head.GetEntity()->StopSound( SND_CHANNEL_VOICE, false ); - head.GetEntity()->GetAnimator()->ClearAllAnims( gameLocal.time, 100 ); - } - - disableGravity = false; - move.moveType = MOVETYPE_DEAD; - m_bAFPushMoveables = false; - - physicsObj.UseFlyMove( false ); - physicsObj.ForceDeltaMove( false ); - - // end our looping ambient sound - StopSound( SND_CHANNEL_AMBIENT, false ); - - RemoveAttachments(); - RemoveProjectile(); - StopMove( MOVE_STATUS_DONE ); - GetMemory().stopRelight = true; // grayman #2603 - abort a relight in progress - GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope - - ClearEnemy(); - - AI_KNOCKEDOUT = true; - - // greebo: Switch the mind to KO state, this will trigger PostKnockout() when - // the animation is done - mind->ClearStates(); - mind->PushState(STATE_KNOCKED_OUT); - - // Update TDM objective system - bool bPlayerResponsible = (inflictor != NULL && inflictor == gameLocal.GetLocalPlayer() ); - gameLocal.m_MissionData->MissionEvent(COMP_KO, this, inflictor, bPlayerResponsible); - // Mark the body as last moved by the player - if( bPlayerResponsible ) - m_MovedByActor = gameLocal.GetLocalPlayer(); - - // greebo: Stop lipsyncing now - m_lipSyncActive = false; -} - -void idAI::PostKnockOut() -{ - // greebo: Removed StopAnim() for head channel, this caused the AI to open its eyes again - //headAnim.StopAnim(1); - - legsAnim.StopAnim(1); - torsoAnim.StopAnim(1); - - headAnim.Disable(); - legsAnim.Disable(); - torsoAnim.Disable(); - // make original self nonsolid - physicsObj.SetContents( 0 ); - physicsObj.GetClipModel()->Unlink(); - - Unbind(); - - // swaps the head CM back if a different one was swapped in while conscious - SwapHeadAFCM( false ); - - if ( StartRagdoll() ) - { - // grayman #2604 - play "gassed" sound if knocked out by gas - switch (m_koState) - { - case KO_BLACKJACK: - StartSound( "snd_knockout", SND_CHANNEL_VOICE, 0, false, NULL ); - break; - case KO_GAS: - StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); - break; - case KO_NOT: - default: - break; - } - } - - const char *modelKOd; - - if ( spawnArgs.GetString( "model_knockedout", "", &modelKOd ) ) - { - // lost soul is only case that does not use a ragdoll and has a model_death so get the death sound in here - StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - SetModel( modelKOd ); - physicsObj.SetLinearVelocity( vec3_zero ); - physicsObj.PutToRest(); - physicsObj.DisableImpact(); - } - - if (spawnArgs.GetBool("set_frobable_on_knockout", "1")) - { - // AI becomes frobable on KO - // greebo: Add a delay before the AI becomes actually frobable - PostEventMS(&EV_SetFrobable, 750, 1); - } - - restartParticles = false; - - // drop items - DropOnRagdoll(); -} - -/** -* ========================== END TDM KNOCKOUT CODE ============================= -**/ - -/* -===================== -idAI::FoundBody -===================== -*/ -void idAI::FoundBody( idEntity *body ) -{ - bool bPlayerResp = false; - if( m_MovedByActor.GetEntity() && m_MovedByActor.GetEntity() == gameLocal.GetLocalPlayer() ) - bPlayerResp = true; - - gameLocal.m_MissionData->MissionEvent( COMP_AI_FIND_BODY, body, bPlayerResp ); -} - -void idAI::AddMessage(const ai::CommMessagePtr& message) -{ - assert(message != NULL); - m_Messages.Append(message); -} - -void idAI::ClearMessages() -{ - m_Messages.Clear(); -} - -/* -===================== -idAI::CheckFOV -===================== -*/ -bool idAI::CheckFOV( const idVec3 &pos ) const -{ - //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("idAI::CheckFOV called \r"); - - float dotHoriz, dotVert, lenDelta, lenDeltaH; - idVec3 delta, deltaH, deltaV, HeadCenter; - idMat3 HeadAxis; - - // ugliness - const_cast(this)->GetJointWorldTransform( m_HeadJointID, gameLocal.time, HeadCenter, HeadAxis ); - idMat3 HeadAxisR = m_FOVRot * HeadAxis; - - // Offset to get the center of the head - HeadCenter += HeadAxis * m_HeadCenterOffset; - delta = pos - HeadCenter; - lenDelta = delta.Length(); // Consider LengthFast if error is not too bad - - // First, project delta into the horizontal plane of the head - // Assume HeadAxis[1] is the up direction in head coordinates - deltaH = delta - HeadAxisR[1] * (HeadAxisR[1] * delta); - lenDeltaH = deltaH.Normalize(); // Consider NormalizeFast - - dotHoriz = HeadAxisR[ 0 ] * deltaH; - // cos (90-zenith) = adjacent / hypotenuse, applied to these vectors - // Technically this lets them see things behind them, but they won't because - // of the horizontal check. - dotVert = idMath::Fabs( lenDeltaH / lenDelta ); - - return ( dotHoriz >= m_fovDotHoriz && dotVert >= m_fovDotVert ); -} - -void idAI::FOVDebugDraw( void ) -{ - float AngVert(0), AngHoriz(0), radius(0); - idVec3 HeadCenter(vec3_zero), ConeDir(vec3_zero); - idMat3 HeadAxis(mat3_zero); - - if( AI_KNOCKEDOUT || AI_DEAD || m_HeadJointID == INVALID_JOINT ) - { - return; - } - - // probably expensive, but that's okay since this is just for debug mode - - AngVert = idMath::ACos( m_fovDotVert ); - AngHoriz = idMath::ACos( m_fovDotHoriz ); - - // store head joint base position to HeadCenter, axis to HeadAxis - GetJointWorldTransform( m_HeadJointID, gameLocal.time, HeadCenter, HeadAxis ); - idMat3 HeadAxisR = m_FOVRot * HeadAxis; - // offset from head joint position to get the true head center - HeadCenter += HeadAxis * m_HeadCenterOffset; - - ConeDir = HeadAxisR[0]; - - // Diverge to keep reasonable cone size - float coneLength; - - if (AngVert >= (idMath::PI / 4.0f)) - { - // Fix radius and calculate length - radius = 60.0f; - coneLength = radius / idMath::Tan(AngVert); - } - else - { - // Fix length and calculate radius - coneLength = 60.0f; - // SZ: FOVAng is divergence off to one side (idActor::setFOV uses COS(fov/2.0) to calculate m_fovDotHoriz) - radius = idMath::Tan(AngVert) * coneLength; - } - - gameRenderWorld->DebugCone( colorBlue, HeadCenter, coneLength * ConeDir, 0, radius, gameLocal.msec ); - - // now do the same for horizontal FOV angle, orange cone - if (AngHoriz >= (idMath::PI / 4.0f)) - { - // Fix radius and calculate length - radius = 60.0f; - coneLength = radius / idMath::Tan(AngHoriz); - } - else - { - // Fix length and calculate radius - coneLength = 60.0f; - // SZ: FOVAng is divergence off to one side (idActor::setFOV uses COS(fov/2.0) to calculate m_fovDotHoriz) - radius = idMath::Tan(AngHoriz) * coneLength; - } - - gameRenderWorld->DebugCone( colorOrange, HeadCenter, coneLength * ConeDir, 0, radius, gameLocal.msec ); -} - -moveStatus_t idAI::GetMoveStatus() const -{ - return move.moveStatus; -} - -bool idAI::CanReachEnemy() -{ - aasPath_t path; - int toAreaNum; - int areaNum; - idVec3 pos; - idActor *enemyEnt; - - enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - return false; - } - - if ( move.moveType != MOVETYPE_FLY ) { - if ( enemyEnt->OnLadder() ) { - return false; - } - enemyEnt->GetAASLocation( aas, pos, toAreaNum ); - } else { - pos = enemyEnt->GetPhysics()->GetOrigin(); - toAreaNum = PointReachableAreaNum( pos ); - } - - if ( !toAreaNum ) { - return false; - } - - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - return PathToGoal(path, areaNum, org, toAreaNum, pos, this); -} - -bool idAI::MouthIsUnderwater( void ) -{ - bool bReturnVal( false ); - idVec3 MouthOffset, MouthPosition; - - idEntity *headEnt = head.GetEntity(); - - // *.def file will store the coordinates of the mouth relative ("mouth_offset") to the head origin - // or relative to the eyes ("eye_height"). This should be defined by the modeler. - - // check for attached head - if( headEnt ) - { - MouthPosition = headEnt->GetPhysics()->GetOrigin(); - - // add in the mouth offset oriented by head axis - MouthPosition += headEnt->GetPhysics()->GetAxis() * m_MouthOffset; - } - else if( af.IsLoaded() && AI_KNOCKEDOUT ) - { - MouthPosition = af.GetPhysics()->GetOrigin( m_HeadBodyID ); - - // add in the mouth offset oriented by head axis - MouthPosition += af.GetPhysics()->GetAxis( m_HeadBodyID ) * m_MouthOffset; - } - else - { - MouthPosition = GetEyePosition(); - MouthPosition.z += m_MouthOffset.z; // grayman #1488 - check at the mouth, not the eyes - } - - // check if the mouth position is underwater - - int contents = gameLocal.clip.Contents( MouthPosition, NULL, mat3_identity, -1, this ); - bReturnVal = (contents & MASK_WATER) > 0; - -#if 0 - // grayman #1488 - // - // For debugging drowning deaths - indicate onscreen whether underwater or breathing, plus health level - - idStr str; - idVec4 color; - idStr healthLevel; - - if (bReturnVal) - { - str = "Drowning"; - color = colorRed; - } - else - { - str = "Breathing"; - color = colorGreen; - } - sprintf( healthLevel, " (%d)", health ); - gameRenderWorld->DrawText((str + healthLevel).c_str(),(GetEyePosition() - GetPhysics()->GetGravityNormal()*60.0f), - 0.25f, color, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 150 * gameLocal.msec); -#endif - - return bReturnVal; -} - -void idAI::UpdateAir() -{ - // Are we able to drown at all? Has the time for next air check already come? - if (!m_bCanDrown || gameLocal.time < m_AirCheckTimer) - { - return; - } - - if (MouthIsUnderwater()) - { - // don't let KO'd AI hold their breath - if (AI_KNOCKEDOUT) - { - m_AirTics = 0; - } - - m_AirTics--; - } - else - { - // regain breath twice as fast as losing - m_AirTics += 2; - - if (m_AirTics > m_AirTicksMax) - { - m_AirTics = m_AirTicksMax; - } - } - - if (m_AirTics < 0) - { - m_AirTics = 0; - - // do the damage, damage_noair is already defined for the player - Damage(NULL, NULL, vec3_origin, "damage_noair", 1.0f, 0); - } - - // set the timer for next air check - m_AirCheckTimer += m_AirCheckInterval; -} - -int idAI::getAirTicks() const { - return m_AirTics; -} - -void idAI::setAirTicks(int airTicks) { - m_AirTics = airTicks; - // Clamp to maximum value - if( m_AirTics > m_AirTicksMax ) { - m_AirTics = m_AirTicksMax; - } -} - -/* -===================== Lipsync ===================== -*/ -int idAI::PlayAndLipSync(const char *soundName, const char *animName) -{ - // Play sound - int duration; - StartSound( soundName, SND_CHANNEL_VOICE, 0, false, &duration ); - - if (cv_ai_bark_show.GetBool()) - { - gameRenderWorld->DrawText( va("%s", soundName), GetEyePosition(), 0.25f, colorBlue, - gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, duration ); - } - - // Do we want to lipsync this sound? - StopLipSync(); // Assume not - - const char *sound; - if (spawnArgs.GetString( soundName, "", &sound )) - { - const idSoundShader* shader = declManager->FindSound( sound ); - - if (shader != NULL && idStr::Cmp(shader->GetDescription(), "nolipsync") != 0) - { - // The sound exists and isn't marked "nolipsync", so start the lipsync - - // Get the default animation name if necessary - if (animName == NULL || animName[0]=='\0') - { - // Not specified; get the default from a spawnarg. - // If even the spawnarg doesn't exist, revert to talk. - animName = spawnArgs.GetString("lipsync_anim_name", "talk"); - } - - m_lipSyncActive = true; - m_lipSyncAnim = GetAnim( ANIMCHANNEL_HEAD, animName ); - m_lipSyncEndTimer = gameLocal.time + duration; - headAnim.CycleAnim( m_lipSyncAnim ); - } - } - - return duration; -} - -void idAI::Event_PlayAndLipSync( const char *soundName, const char *animName ) -{ - // grayman - might have to add drowning check here if anyone - // ever uses this function in a script. - - idThread::ReturnInt(static_cast(MS2SEC(PlayAndLipSync(soundName, animName)))); -} - -void idAI::StopLipSync() -{ - if (m_lipSyncActive) - { - // Make sure mouth is closed - headAnim.SetFrame( m_lipSyncAnim, 0 ); - // Halt animation - headAnim.SetState("Head_Idle", 4); - } - m_lipSyncActive = false; -} - -/* -===================== Sheathing/drawing weapons ===================== -*/ - -void idAI::DrawWeapon() -{ - /*const function_t* func = scriptObject.GetFunction("DrawWeapon"); - if (func) { - idThread* thread = new idThread(func); - thread->CallFunction(this, func, true); - thread->DelayedStart(0); - }*/ - // greebo: Replaced the above thread spawn with an animstate switch - SetAnimState(ANIMCHANNEL_TORSO, "Torso_DrawWeapon", 4); -} - -void idAI::SheathWeapon() -{ - /*const function_t* func = scriptObject.GetFunction("SheathWeapon"); - if (func) { - idThread* thread = new idThread(func); - thread->CallFunction(this, func, true); - thread->DelayedStart(0); - }*/ - // greebo: Replaced the above thread spawn with an animstate switch - SetAnimState(ANIMCHANNEL_TORSO, "Torso_SheathWeapon", 4); -} - -void idAI::DropOnRagdoll( void ) -{ - idEntity *ent = NULL; - int mask(0); - // Id style def_drops - const idKeyValue *kv = spawnArgs.MatchPrefix( "def_drops", NULL ); - - // old D3 code for spawning things at AI's feet when they die - while( kv ) - { - idDict args; - - args.Set( "classname", kv->GetValue() ); - args.Set( "origin", physicsObj.GetOrigin().ToString() ); - gameLocal.SpawnEntityDef( args ); - kv = spawnArgs.MatchPrefix( "def_drops", kv ); - } - - // Drop TDM style attachments - for( int i=0; iIsType(CMeleeWeapon::Type) ) - { - CMeleeWeapon *pWeap = static_cast(ent); - pWeap->DeactivateAttack(); - pWeap->DeactivateParry(); - pWeap->ClearOwner(); - } - - // greebo: Check if we should set some attachments to nonsolid - // this applies for instance to the builder guard's pauldrons which - // cause twitching and self-collisions when going down - if (ent->spawnArgs.GetBool( "drop_set_nonsolid" )) - { - int curContents = ent->GetPhysics()->GetContents(); - - // ishtvan: Also clear the CONTENTS_CORPSE flag (maybe this was a typo in original code?) - ent->GetPhysics()->SetContents(curContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE)); - - // ishtvan: If this entity was added to the AF, set the AF body nonsolid as well - idAFBody *EntBody = AFBodyForEnt( ent ); - if( EntBody != NULL ) - { - int curBodyContents = EntBody->GetClipModel()->GetContents(); - EntBody->GetClipModel()->SetContents( curBodyContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); - } - - // also have to iterate thru stuff attached to this attachment - // ishtvan: left this commentd out because I'm not sure if GetTeamChildren is bugged or not - // don't want to accidentally set all attachments to the AI to nonsolid - /* - idList AttChildren; - ent->GetTeamChildren( &AttChildren ); - gameLocal.Printf("TEST: drop_set_nonsolid, Num team children = %d", AttChildren.Num() ); - for( int i=0; i < AttChildren.Num(); i++ ) - { - idPhysics *pChildPhys = AttChildren[i]->GetPhysics(); - if( pChildPhys == NULL ) - continue; - - int childContents = pChildPhys->GetContents(); - pChildPhys->SetContents( childContents & ~(CONTENTS_SOLID|CONTENTS_CORPSE) ); - } - */ - } - - bool bDrop = ent->spawnArgs.GetBool( "drop_when_ragdoll" ); - - if( !bDrop ) { - continue; - } - - bool bDropWhenDrawn = ent->spawnArgs.GetBool( "drop_when_drawn" ); - bool bSetSolid = ent->spawnArgs.GetBool( "drop_add_contents_solid" ); - bool bSetCorpse = ent->spawnArgs.GetBool( "drop_add_contents_corpse" ); - bool bSetFrob = ent->spawnArgs.GetBool( "drop_set_frobable" ); - bool bExtinguish = ent->spawnArgs.GetBool("extinguish_on_drop", "0"); - - if( bDropWhenDrawn ) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Testing drop weapon %s\r", ent->name.c_str() ); - - bool bIsMelee = ent->spawnArgs.GetBool( "is_weapon_melee" ); - - if( bIsMelee && !GetAttackFlag(COMBAT_MELEE) ) - { - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Melee weapon was not drawn\r" ); - continue; - } - - bool bIsRanged = ent->spawnArgs.GetBool( "is_weapon_ranged" ); - - if( bIsRanged && !GetAttackFlag(COMBAT_RANGED) ) - { - continue; - } - } - - // Proceed with droppage - DetachInd( i ); - - if( bSetSolid ) - mask = CONTENTS_SOLID; - if( bSetCorpse ) - mask = mask | CONTENTS_CORPSE; - - if( mask ) - ent->GetPhysics()->SetContents( ent->GetPhysics()->GetContents() | mask ); - - if( bSetFrob ) - ent->m_bFrobable = true; - - // greebo: Check if we should extinguish the attachment, like torches - if ( bExtinguish ) - { - // Get the delay in milliseconds - int delay = SEC2MS(ent->spawnArgs.GetInt("extinguish_on_drop_delay", "3")); - if (delay < 0) { - delay = 0; - } - - // Schedule the extinguish event - ent->PostEventMS(&EV_ExtinguishLights, delay); - } - - ent->GetPhysics()->Activate(); - ent->m_droppedByAI = true; // grayman #1330 - } - - // also perform some of these same operations on attachments to our head, - // because they are stored differently than attachments to us - if( head.GetEntity() ) - head.GetEntity()->DropOnRagdoll(); -} - -int idAI::StartSearchForHidingSpotsWithExclusionArea -( - const idVec3& hideFromLocation, - const idVec3& minBounds, - const idVec3& maxBounds, - const idVec3& exclusionMinBounds, - const idVec3& exclusionMaxBounds, - int hidingSpotTypesAllowed, - idEntity* p_ignoreEntity -) -{ - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("StartSearchForHidingSpots called.\r"); - - // Destroy any current search - destroyCurrentHidingSpotSearch(); - - // Make caller's search bounds - idBounds searchBounds (minBounds, maxBounds); - idBounds searchExclusionBounds (exclusionMinBounds, exclusionMaxBounds); - - // greebo: Remember the initial alert position - ai::Memory& memory = GetMemory(); - memory.alertSearchCenter = memory.alertPos; - - // Get aas - if (aas != NULL) - { - // Allocate object that handles the search - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Making finder\r"); - bool b_searchCompleted = false; - m_HidingSpotSearchHandle = CHidingSpotSearchCollection::Instance().getOrCreateSearch - ( - hideFromLocation, - aas, - HIDING_OBJECT_HEIGHT, - searchBounds, - searchExclusionBounds, - hidingSpotTypesAllowed, - p_ignoreEntity, - gameLocal.framenum, - b_searchCompleted - ); - - // Wait at least one frame for other AIs to indicate they want to share - // this search. Return result indicating search is not done yet. - return 1; - } - else - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Cannot perform Event_StartSearchForHidingSpotsWithExclusionArea if no AAS is set for the AI\r"); - - // Search is done since there is no search - return 0; - } -} - -bool idAI::IsSearching() // grayman #2603 -{ - return (AI_AlertLevel >= thresh_3); -} - -int idAI::ContinueSearchForHidingSpots() -{ - //DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("ContinueSearchForHidingSpots called.\r"); - - // Get hiding spot search instance from handle - CDarkmodAASHidingSpotFinder* p_hidingSpotFinder = NULL; - if (m_HidingSpotSearchHandle != NULL_HIDING_SPOT_SEARCH_HANDLE) - { - p_hidingSpotFinder = CHidingSpotSearchCollection::Instance().getSearchByHandle( - m_HidingSpotSearchHandle - ); - } - - // Make sure search still around - if (p_hidingSpotFinder == NULL) - { - // No hiding spot search to continue - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("No current hiding spot search to continue\r"); - return 0; - } - else - { - // Call finder method to continue search - bool moreProcessingToDo = p_hidingSpotFinder->continueSearchForHidingSpots - ( - p_hidingSpotFinder->hidingSpotList, - cv_ai_max_hiding_spot_tests_per_frame.GetInteger(), - gameLocal.framenum - ); - - // Return result - if (moreProcessingToDo) - { - return 1; - } - - // No more processing to do at this point - - unsigned int refCount; - - // Get finder we just referenced - CDarkmodAASHidingSpotFinder* p_hidingSpotFinder = - CHidingSpotSearchCollection::Instance().getSearchAndReferenceCountByHandle - ( - m_HidingSpotSearchHandle, - refCount - ); - - m_hidingSpots.clear(); - // greebo: Now retrieve our share from the completed hiding spot search - // Given that three other AI are referencing this hiding spot finder, this AI draws a third. - p_hidingSpotFinder->hidingSpotList.getOneNth(refCount, m_hidingSpots); - - // Done with search object, dereference so other AIs know how many - // AIs will still be retrieving points from the search - CHidingSpotSearchCollection::Instance().dereference (m_HidingSpotSearchHandle); - m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; - - // DEBUGGING - if (cv_ai_search_show.GetInteger() >= 1.0) - { - // Clear the debug draw list and then fill with our results - p_hidingSpotFinder->debugClearHidingSpotDrawList(); - p_hidingSpotFinder->debugAppendHidingSpotsToDraw (m_hidingSpots); - p_hidingSpotFinder->debugDrawHidingSpots (cv_ai_search_show.GetInteger()); - } - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Hiding spot search completed\r"); - return 0; - } -} - -idVec3 idAI::GetNthHidingSpotLocation(int hidingSpotIndex) -{ - idVec3 outLocation(0,0,0); - - int numSpots = m_hidingSpots.getNumSpots(); - - // In bounds? - if (hidingSpotIndex >= 0 && hidingSpotIndex < numSpots) - { - idBounds areaNodeBounds; - darkModHidingSpot* p_spot = m_hidingSpots.getNthSpotWithAreaNodeBounds(hidingSpotIndex, areaNodeBounds); - if (p_spot != NULL) - { - outLocation = p_spot->goal.origin; - } - - if (cv_ai_search_show.GetInteger() >= 1.0) - { - idVec4 markerColor (1.0, 1.0, 1.0, 1.0); - idVec3 arrowLength (0.0, 0.0, 50.0); - - // Debug draw the point to be searched - gameRenderWorld->DebugArrow - ( - markerColor, - outLocation + arrowLength, - outLocation, - 2, - cv_ai_search_show.GetInteger() - ); - - // Debug draw the bounds of the area node containing the hiding spot point - // This may be smaller than the containing AAS area due to octant subdivision. - gameRenderWorld->DebugBounds - ( - markerColor, - areaNodeBounds, - vec3_origin, - cv_ai_search_show.GetInteger() - ); - } - - } - else - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Index %d is out of bounds, there are %d hiding spots\r", hidingSpotIndex, numSpots); - } - - // Return the location - return outLocation; -} - -int idAI::GetSomeOfOtherEntitiesHidingSpotList(idEntity* p_ownerOfSearch) -{ - // Test parameters - if (p_ownerOfSearch == NULL) - { - return 0; - } - - // The other entity must be an AI - idAI* p_otherAI = dynamic_cast(p_ownerOfSearch); - if (p_otherAI == NULL) - { - // Not an AI - return 0; - } - - CDarkmodHidingSpotTree& p_othersTree = p_otherAI->m_hidingSpots; - if (p_othersTree.getNumSpots() <= 1) - { - // No points - return 0; - } - - // We must clear our current hiding spot search - destroyCurrentHidingSpotSearch(); - - // Move points from their tree to ours - p_othersTree.getOneNth(2, m_hidingSpots); - - // Done - return m_hidingSpots.getNumSpots(); -} - - -float idAI::GetArmReachLength() -{ - if (idAAS* aas = GetAAS()) - { - idVec3 size = aas->GetSettings()->boundingBoxes[0][1]; - return size.z * 0.5; - } - else - { - return 41; - } -} - -void idAI::NeedToUseElevator(const eas::RouteInfoPtr& routeInfo) -{ - mind->GetState()->NeedToUseElevator(routeInfo); -} - - -bool idAI::CanUnlock(CBinaryFrobMover *frobMover) -{ - // Look through list of unlockable doors set by spawnarg - FrobMoverList::iterator i = unlockableDoors.find(frobMover); - if (i != unlockableDoors.end()) - { - return true; - } - - // Look through attachments - int n = frobMover->m_UsedByName.Num(); - for (int i = 0; i < m_Attachments.Num(); i++) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL || !m_Attachments[i].ent.IsValid()) - { - continue; - } - - for (int j = 0; j < n; j++) - { - if (ent->name == frobMover->m_UsedByName[j]) - { - return true; - } - } - } - return false; -} - -bool idAI::ShouldCloseDoor(CBinaryFrobMover *frobMover) -{ - if (frobMover->spawnArgs.GetBool("ai_should_not_close", "0")) - { - // this door should not be closed - return false; - } - if (AI_AlertLevel >= thresh_5) - { - // don't close doors during combat - return false; - } - if (frobMover->spawnArgs.GetBool("shouldBeClosed", "0")) - { - // this door should really be closed - return true; - } - if (IsSearching()) // grayman #2603 - { - // don't close other doors while searching - return false; - } - - // in all other cases, close the door - return true; -} - -void idAI::PushMove() -{ - // Copy the current movestate structure to the stack - moveStack.push_back(move); - - if (moveStack.size() > 100) - { - gameLocal.Warning("AI MoveStack contains more than 100 moves! (%s)\n", name.c_str()); - } -} - -void idAI::PopMove() -{ - if (moveStack.empty()) - { - return; // nothing to pop from - } - - const idMoveState& saved = moveStack.back(); // Get a reference of the last element - RestoreMove(saved); - moveStack.pop_back(); // Remove the last element -} - -void idAI::RestoreMove(const idMoveState& saved) -{ - idVec3 goalPos; - idVec3 dest; - - switch( saved.moveCommand ) { - case MOVE_NONE : - StopMove( saved.moveStatus ); - break; - - case MOVE_FACE_ENEMY : - FaceEnemy(); - break; - - case MOVE_FACE_ENTITY : - FaceEntity( saved.goalEntity.GetEntity() ); - break; - - case MOVE_TO_ENEMY : - MoveToEnemy(); - break; - - case MOVE_TO_ENEMYHEIGHT : - MoveToEnemyHeight(); - break; - - case MOVE_TO_ENTITY : - MoveToEntity( saved.goalEntity.GetEntity() ); - break; - - case MOVE_OUT_OF_RANGE : - MoveOutOfRange( saved.goalEntity.GetEntity(), saved.range ); - break; - - case MOVE_TO_ATTACK_POSITION : - MoveToAttackPosition( saved.goalEntity.GetEntity(), saved.anim ); - break; - - case MOVE_TO_COVER : - MoveToCover( saved.goalEntity.GetEntity(), lastVisibleEnemyPos ); - break; - - case MOVE_TO_POSITION : - MoveToPosition( saved.moveDest ); - break; - - case MOVE_TO_POSITION_DIRECT : - DirectMoveToPosition( saved.moveDest ); - break; - - case MOVE_SLIDE_TO_POSITION : - SlideToPosition( saved.moveDest, saved.duration ); - break; - - case MOVE_WANDER : - WanderAround(); - break; - - default: break; - } - - if ( GetMovePos( goalPos ) ) { - //CheckObstacleAvoidance( goalPos, dest ); - } -} - -void idAI::ShowDebugInfo() -{ - // DarkMod: Show debug info - if( cv_ai_ko_show.GetBool() ) - { - KnockoutDebugDraw(); - } - - if( cv_ai_fov_show.GetBool() ) - { - FOVDebugDraw(); - } - - if ( cv_ai_dest_show.GetBool() ) - { - gameRenderWorld->DebugArrow(colorYellow, physicsObj.GetOrigin(), move.moveDest, 5, gameLocal.msec); - } - - if ( cv_ai_task_show.GetBool()) - { - idStr str("State: "); - str += mind->GetState()->GetName() + "\n"; - - if (GetSubsystem(ai::SubsysSenses)->IsEnabled()) str += "Senses: " + GetSubsystem(ai::SubsysSenses)->GetDebugInfo() + "\n"; - if (GetSubsystem(ai::SubsysMovement)->IsEnabled()) str += "Movement: " + GetSubsystem(ai::SubsysMovement)->GetDebugInfo() + "\n"; - if (GetSubsystem(ai::SubsysCommunication)->IsEnabled()) str += "Comm: " + GetSubsystem(ai::SubsysCommunication)->GetDebugInfo() + "\n"; - if (GetSubsystem(ai::SubsysAction)->IsEnabled()) str += "Action: " + GetSubsystem(ai::SubsysAction)->GetDebugInfo() + "\n"; - - gameRenderWorld->DrawText( str, (GetEyePosition() - physicsObj.GetGravityNormal()*35.0f), 0.25f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - } - - if( cv_ai_alertlevel_show.GetBool() ) - { - gameRenderWorld->DrawText( va("Alert: %f; Index: %d", (float) AI_AlertLevel, (int)AI_AlertIndex), (GetEyePosition() - physicsObj.GetGravityNormal()*45.0f), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - if (m_AlertGraceStart + m_AlertGraceTime - gameLocal.time > 0) - { - gameRenderWorld->DrawText( va("Grace time: %d; Alert count: %d / %d", - m_AlertGraceStart + m_AlertGraceTime - gameLocal.time, - m_AlertGraceCount, m_AlertGraceCountLimit), - GetEyePosition(), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - } - } - - if (cv_ai_animstate_show.GetBool()) - { - idStr debugText("Torso: "); - debugText += GetAnimState(ANIMCHANNEL_TORSO); - debugText += " Waitstate: "; - debugText += WaitState(ANIMCHANNEL_TORSO); - debugText += "\nLegs: "; - debugText += GetAnimState(ANIMCHANNEL_LEGS); - debugText += " Waitstate: "; - debugText += WaitState(ANIMCHANNEL_LEGS); - debugText += "\nHead: "; - debugText += GetAnimState(ANIMCHANNEL_HEAD); - debugText += " Waitstate: "; - debugText += WaitState(ANIMCHANNEL_LEGS); - debugText += "\n"; - - if (WaitState() != NULL) - { - debugText += idStr("Waitstate: ") + WaitState(); - } - gameRenderWorld->DrawText( debugText, (GetEyePosition() - physicsObj.GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - } - - if (cv_ai_aasarea_show.GetBool() && aas != NULL) - { - idVec3 org = GetPhysics()->GetOrigin(); - int areaNum = PointReachableAreaNum(org); - - idBounds areaBounds = aas->GetAreaBounds(areaNum); - idVec3 areaCenter = aas->AreaCenter(areaNum); - - idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); - - gameRenderWorld->DrawText(va("%d", areaNum), areaCenter, 0.2f, colorGreen, playerViewMatrix, 1, gameLocal.msec); - gameRenderWorld->DebugBox(colorGreen, idBox(areaBounds), gameLocal.msec); - } - - if (cv_ai_elevator_show.GetBool()) - { - idMat3 playerViewMatrix(gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); - - gameRenderWorld->DrawText(m_HandlingElevator ? "Elevator" : "---", physicsObj.GetOrigin(), 0.2f, m_HandlingElevator ? colorRed : colorGreen, playerViewMatrix, 1, gameLocal.msec); - } -} - -const idStr& idAI::GetNextIdleAnim() -{ - return m_NextIdleAnim; -} - -void idAI::SetNextIdleAnim(const idStr& nextIdleAnim) -{ - m_NextIdleAnim = nextIdleAnim; -} - -// grayman #2603 - delayed stim management - -void idAI::SetDelayedStimExpiration(idEntityPtr stimPtr) -{ - for (int i = 0 ; i < delayedStims.Num() ; i++) - { - if (delayedStims[i].stim == stimPtr) - { - delayedStims[i].nextTimeToConsider = gameLocal.time + 15000; - return; - } - } - - // stim not in list, so add it - - DelayedStim ds; - ds.nextTimeToConsider = gameLocal.time + 15000; - ds.stim = stimPtr; - delayedStims.Append(ds); -} - -int idAI::GetDelayedStimExpiration(idEntityPtr stimPtr) -{ - for (int i = 0 ; i < delayedStims.Num() ; i++) - { - if (delayedStims[i].stim == stimPtr) - { - return (delayedStims[i].nextTimeToConsider); - } - } - return -1; -} - -bool idAI::SwitchToConversationState(const idStr& conversationName) -{ - ai::ConversationStatePtr state = - boost::static_pointer_cast(ai::ConversationState::CreateInstance()); - - // Convert the name to an index - int convIndex = gameLocal.m_ConversationSystem->GetConversationIndex(conversationName); - - if (convIndex == -1) - { - DM_LOG(LC_CONVERSATION, LT_ERROR)LOGSTRING("Could not find conversation '%s'.\r", conversationName.c_str()); - return false; - } - - // Let the state know which conversation is about to be played - state->SetConversation(convIndex); - - // Switch to this state - GetMind()->PushState(state); - - return true; -} - -void idAI::RemoveTarget(idEntity* target) -{ - idEntity::RemoveTarget( target ); - - if (!GetMind()->IsEmpty()) - { - GetMind()->GetState()->OnChangeTarget(this); - } -} - -void idAI::AddTarget(idEntity* target) -{ - idEntity::AddTarget( target ); - - if (!GetMind()->IsEmpty()) - { - GetMind()->GetState()->OnChangeTarget(this); - } -} - -void idAI::SitDown() -{ - idStr waitState(WaitState()); - if (GetMoveType() != MOVETYPE_ANIM) - { - return; - } - SetMoveType(MOVETYPE_SIT_DOWN); - SetWaitState("sit_down"); -} - -void idAI::GetUp() -{ - moveType_t moveType = GetMoveType(); - - if (moveType == MOVETYPE_SIT) - { - SetMoveType(MOVETYPE_GET_UP); - SetWaitState("get_up"); - - } - else if (moveType == MOVETYPE_SLEEP) - { - SetMoveType(MOVETYPE_GET_UP_FROM_LYING); - SetWaitState("get_up_from_lying_down"); - - // Reset visual, hearing and tactile acuity - SetAcuity("vis", m_oldVisualAcuity); // Tels: fix #2408 - SetAcuity("aud", GetAcuity("aud") * 2); - SetAcuity("tact", GetAcuity("tact") * 2); - } -} - - -void idAI::LayDown() -{ - if (GetMoveType() != MOVETYPE_ANIM) - { - return; - } - - AI_LAY_DOWN_FACE_DIR = idAngles( 0, current_yaw, 0 ).ToForward(); - - SetMoveType(MOVETYPE_LAY_DOWN); - SetWaitState("lay_down"); - - // Tels: Sleepers are blind - m_oldVisualAcuity = GetAcuity("vis"); - SetAcuity("vis", 0); - - // Reduce hearing and tactile acuity by 50% - // TODO: use spawn args - SetAcuity("aud", GetAcuity("aud") * 0.5); - SetAcuity("tact", GetAcuity("tact") * 0.5); -} - - -float idAI::StealthDamageMult() -{ - // multiply up if unalert - // Damage to unconscious AI also considered sneak attack - if( AI_AlertLevel < m_SneakAttackThresh || IsKnockedOut() ) - return m_SneakAttackMult; - else - return 1.0; -} - -void idAI::SwapHeadAFCM(bool bUseLargerCM) -{ - if (m_HeadJointID == -1) return; // safety check for AI without head - - if (bUseLargerCM && !m_bHeadCMSwapped && spawnArgs.FindKey("blackjack_headbox_mins")) - { - idAFBody* headBody = af.GetPhysics()->GetBody(af.BodyForJoint(m_HeadJointID)); - - idClipModel *oldClip = headBody->GetClipModel(); - idVec3 CMorig = oldClip->GetOrigin(); - idMat3 CMaxis = oldClip->GetAxis(); - int CMid = oldClip->GetId(); - - oldClip->Unlink(); - // store a copy of the original cm since it will be deleted - m_OrigHeadCM = new idClipModel(oldClip); - - idBounds HeadBounds; - spawnArgs.GetVector( "blackjack_headbox_mins", NULL, HeadBounds[0] ); - spawnArgs.GetVector( "blackjack_headbox_maxs", NULL, HeadBounds[1] ); - - idTraceModel trm; - trm.SetupBox( HeadBounds ); - - idClipModel *NewClip = new idClipModel( trm ); - - // AF bodies want to have their origin at the center of mass - float MassOut; - idVec3 COM; - idMat3 inertiaTensor; - NewClip->GetMassProperties( 1.0f, MassOut, COM, inertiaTensor ); - NewClip->TranslateOrigin( -COM ); - CMorig += COM * CMaxis; - - NewClip->SetContents( oldClip->GetContents() ); - NewClip->Link( gameLocal.clip, this, CMid, CMorig, CMaxis ); - headBody->SetClipModel( NewClip ); - - m_bHeadCMSwapped = true; - } - // swap back to original CM when going unconscious, if we swapped earlier - else if( !bUseLargerCM && m_bHeadCMSwapped ) - { - idAFBody* headBody = af.GetPhysics()->GetBody(af.BodyForJoint(m_HeadJointID)); - - idClipModel *oldClip = headBody->GetClipModel(); - idVec3 CMorig = oldClip->GetOrigin(); - idMat3 CMaxis = oldClip->GetAxis(); - int CMid = oldClip->GetId(); - - m_OrigHeadCM->Link( gameLocal.clip, this, CMid, CMorig, CMaxis ); - headBody->SetClipModel( m_OrigHeadCM ); - - m_bHeadCMSwapped = false; - m_OrigHeadCM = NULL; - } -} - -void idAI::CopyHeadKOInfo( void ) -{ - idEntity *ent = head.GetEntity(); - if( !ent ) - return; - - // Change this if the list below changes: - const int numArgs = 14; - const char *copyArgs[ numArgs ] = { "ko_immune", "ko_spot_offset", "ko_zone", - "ko_alert_state", "ko_alert_immune", "ko_alert_immune_state", "ko_angle_vert", "ko_angle_horiz", - "ko_angle_alert_vert", "ko_angle_alert_horiz", "ko_rotation", "fov", - "fov_vert", "fov_rotation"}; - - const idKeyValue *tempkv; - const char *argName; - - // for each spawnarg, overwrite it if it exists on the head - for( int i=0; i < numArgs; i++ ) - { - argName = copyArgs[i]; - tempkv = ent->spawnArgs.FindKey( argName ); - if( tempkv != NULL ) - spawnArgs.Set( argName, tempkv->GetValue().c_str() ); - } -} - -void idAI::ParseKnockoutInfo() -{ - m_bCanBeKnockedOut = !( spawnArgs.GetBool("ko_immune", "0") ); - m_HeadCenterOffset = spawnArgs.GetVector("ko_spot_offset"); - m_KoZone = spawnArgs.GetString("ko_zone"); - m_KoAlertState = spawnArgs.GetInt("ko_alert_state"); - m_KoAlertImmuneState = spawnArgs.GetInt("ko_alert_immune_state"); - m_bKoAlertImmune = spawnArgs.GetBool("ko_alert_immune"); - idAngles tempAngles = spawnArgs.GetAngles("ko_rotation"); - m_KoRot = tempAngles.ToMat3(); - - float tempAng; - tempAng = spawnArgs.GetFloat("ko_angle_vert", "360"); - m_KoDotVert = (float)cos( DEG2RAD( tempAng * 0.5f ) ); - tempAng = spawnArgs.GetFloat("ko_angle_horiz", "360"); - m_KoDotHoriz = (float)cos( DEG2RAD( tempAng * 0.5f ) ); - - // Only set the alert angles if the spawnargs exist - const char *tempc1, *tempc2; - tempc1 = spawnArgs.GetString("ko_angle_alert_vert"); - tempc2 = spawnArgs.GetString("ko_angle_alert_horiz"); - if( tempc1[0] != '\0' ) - { - tempAng = atof( tempc1 ); - m_KoAlertDotVert = (float)cos( DEG2RAD( tempAng * 0.5f ) ); - } - else - m_KoAlertDotVert = m_KoDotVert; - if( tempc2[0] != '\0' ) - { - tempAng = atof( tempc2 ); - m_KoAlertDotHoriz = (float)cos( DEG2RAD( tempAng * 0.5f ) ); - } - else - m_KoAlertDotHoriz = m_KoDotHoriz; - - // ishtvan: Also set the FOV again, as this may be copied from the head - // TODO: This was done once already in idActor, do we still need it there or can we remove FOV from idActor? - float fovDegHoriz, fovDegVert; - spawnArgs.GetFloat( "fov", "150", fovDegHoriz ); - // If fov_vert is -1, it will be set the same as horizontal - spawnArgs.GetFloat( "fov_vert", "-1", fovDegVert ); - SetFOV( fovDegHoriz, fovDegVert ); - tempAngles = spawnArgs.GetAngles("fov_rotation"); - m_FOVRot = tempAngles.ToMat3(); -} diff --git a/game/ai/ai.h b/game/ai/ai.h deleted file mode 100644 index 404183276..000000000 --- a/game/ai/ai.h +++ /dev/null @@ -1,2213 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __AI_H__ -#define __AI_H__ - -#include "../../DarkMod/Relations.h" -#include "../../DarkMod/AI/Mind.h" -#include "../../DarkMod/AI/CommunicationSubsystem.h" -#include "../../DarkMod/AI/MovementSubsystem.h" -#include "../../DarkMod/HidingSpotSearchCollection.h" -#include "../../DarkMod/darkmodHidingSpotTree.h" -#include "MoveState.h" - -#include -#include - -/* -=============================================================================== - - idAI - -=============================================================================== -*/ - -const float SQUARE_ROOT_OF_2 = 1.414213562f; -const float AI_TURN_PREDICTION = 0.2f; -const float AI_TURN_SCALE = 60.0f; -const float AI_SEEK_PREDICTION = 0.3f; -const float AI_FLY_DAMPENING = 0.15f; -const float AI_HEARING_RANGE = 2048.0f; -const int DEFAULT_FLY_OFFSET = 68; - -// grayman 2414 - TEMP_THINK constants used with interleaved thinking -const int TEMP_THINK_INTERLEAVE = 4; // maximum interleave think frames when - // more interleaved thinking is needed -const int TEMP_THINK_DISTANCE = 200; // increase interleave think frames - // when door is closer than this -const int TEMP_THINK_FACTOR = 8; // used to determine when to increase thinking - // when moving to a goal position - - -// used to declare the Dark Mod Acuity values array. -// THIS MUST BE CHANGED if you want more than 15 acuities -static const int s_MAXACUITIES = 15; - -#define ATTACK_IGNORE 0 -#define ATTACK_ON_DAMAGE 1 -#define ATTACK_ON_ACTIVATE 2 -#define ATTACK_ON_SIGHT 4 - -typedef enum { - TALK_NEVER, - TALK_DEAD, - TALK_OK, - TALK_BUSY, - NUM_TALK_STATES -} talkState_t; - -typedef enum { // grayman #2604 - how the AI was knocked out - KO_NOT, // default - not KO'ed - KO_BLACKJACK, - KO_GAS, - NUM_KO_STATES -} koState_t; - -#define DI_NODIR -1 - -// obstacle avoidance -typedef struct obstaclePath_s { - idVec3 seekPos; // seek position avoiding obstacles - idEntity * firstObstacle; // if != NULL the first obstacle along the path - idVec3 startPosOutsideObstacles; // start position outside obstacles - idEntity * startPosObstacle; // if != NULL the obstacle containing the start position - idVec3 seekPosOutsideObstacles; // seek position outside obstacles - idEntity * seekPosObstacle; // if != NULL the obstacle containing the seek position - CFrobDoor* doorObstacle; // greebo: if != NULL, this is the door in our way -} obstaclePath_t; - -// path prediction -typedef enum { - SE_BLOCKED = BIT(0), - SE_ENTER_LEDGE_AREA = BIT(1), - SE_ENTER_OBSTACLE = BIT(2), - SE_FALL = BIT(3), - SE_LAND = BIT(4) -} stopEvent_t; - -typedef struct predictedPath_s { - idVec3 endPos; // final position - idVec3 endVelocity; // velocity at end position - idVec3 endNormal; // normal of blocking surface - int endTime; // time predicted - int endEvent; // event that stopped the prediction - const idEntity * blockingEntity; // entity that blocks the movement -} predictedPath_t; - -// -// events -// -extern const idEventDef AI_BeginAttack; -extern const idEventDef AI_EndAttack; -extern const idEventDef AI_MuzzleFlash; -extern const idEventDef AI_CreateMissile; -extern const idEventDef AI_CreateMissileFromDef; -extern const idEventDef AI_AttackMissile; -extern const idEventDef AI_FireMissileAtTarget; -extern const idEventDef AI_AttackMelee; -extern const idEventDef AI_DirectDamage; -extern const idEventDef AI_JumpFrame; -extern const idEventDef AI_EnableClip; -extern const idEventDef AI_DisableClip; -extern const idEventDef AI_EnableGravity; -extern const idEventDef AI_DisableGravity; -extern const idEventDef AI_TriggerParticles; -extern const idEventDef AI_RandomPath; - -// DarkMod Events -extern const idEventDef AI_GetRelationEnt; -extern const idEventDef AI_GetSndDir; -extern const idEventDef AI_GetVisDir; -extern const idEventDef AI_GetTactEnt; -extern const idEventDef AI_VisScan; -extern const idEventDef AI_Alert; -extern const idEventDef AI_GetAcuity; -extern const idEventDef AI_SetAcuity; -extern const idEventDef AI_SetAudThresh; -extern const idEventDef AI_ClosestReachableEnemy; -extern const idEventDef AI_ReEvaluateArea; - - -// Darkmod: Glass Houses events -extern const idEventDef AI_SpawnThrowableProjectile; - -// DarkMod hiding spot finding events -extern const idEventDef AI_StartSearchForHidingSpots; -extern const idEventDef AI_ContinueSearchForHidingSpots; -extern const idEventDef AI_CloseHidingSpotSearch; -extern const idEventDef AI_GetNumHidingSpots; -extern const idEventDef AI_GetNthHidingSpotLocation; -extern const idEventDef AI_GetNthHidingSpotType; -extern const idEventDef AI_GetSomeOfOtherEntitiesHidingSpotList; - -// Darkmod AI additions -extern const idEventDef AI_GetVariableFromOtherAI; -extern const idEventDef AI_GetAlertLevelOfOtherAI; - -// Set a grace period for alerts -extern const idEventDef AI_SetAlertGracePeriod; - -// This event is used to get a position from which a given position can be observed -extern const idEventDef AI_GetObservationPosition; - -// Darkmod communication issuing event -extern const idEventDef AI_IssueCommunication; - -class idPathCorner; - -typedef struct particleEmitter_s { - particleEmitter_s() { - particle = NULL; - time = 0; - joint = INVALID_JOINT; - }; - const idDeclParticle *particle; - int time; - jointHandle_t joint; -} particleEmitter_t; - -class idAASFindCover : public idAASCallback { -public: - idAASFindCover( const idActor* hidingActor, const idEntity* hideFromEnt, const idVec3 &hideFromPos ); - ~idAASFindCover(); - - virtual bool TestArea( const idAAS *aas, int areaNum ); - -private: - const idActor* hidingActor; - const idEntity* hideFromEnt; - idVec3 hideFromPos; -}; - -class idAASFindAreaOutOfRange : public idAASCallback { -public: - idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist ); - - virtual bool TestArea( const idAAS *aas, int areaNum ); - -private: - idVec3 targetPos; - float maxDistSqr; -}; - -class idAASFindAttackPosition : public idAASCallback { -public: - idAASFindAttackPosition(idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset); - ~idAASFindAttackPosition(); - - virtual bool TestArea( const idAAS *aas, int areaNum ); - -private: - idAI *self; - idEntity *target; - idBounds excludeBounds; - idVec3 targetPos; - idVec3 fireOffset; - idMat3 gravityAxis; - pvsHandle_t targetPVS; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; -}; - -class idAASFindObservationPosition : public idAASCallback { -public: - idAASFindObservationPosition( const idAI *self, const idMat3 &gravityAxis, const idVec3 &targetPos, const idVec3 &eyeOffset, float maxDistanceFromWhichToObserve ); - ~idAASFindObservationPosition(); - - virtual bool TestArea( const idAAS *aas, int areaNum ); - - // Gets the best goal result, even if it didn't meet the maximum distance - bool getBestGoalResult - ( - float& out_bestGoalDistance, - aasGoal_t& out_bestGoal - ); - -private: - const idAI *self; - idBounds excludeBounds; - idVec3 targetPos; - idVec3 eyeOffset; - idMat3 gravityAxis; - pvsHandle_t targetPVS; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; - float maxObservationDistance; - - // The best goal found, even if it was greater than the maxObservationDistance - float bestGoalDistance; - bool b_haveBestGoal; - aasGoal_t bestGoal; -}; - -class idAI : public idActor { -public: - CLASS_PROTOTYPE( idAI ); - - idAI(); - virtual ~idAI(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - void HeardSound( idEntity *ent, const char *action ); - idActor *GetEnemy( void ) const; - void TalkTo( idActor *actor ); - talkState_t GetTalkState( void ) const; - - bool GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ); - - void TouchedByFlashlight( idActor *flashlight_owner ); - - // Outputs a list of all monsters to the console. - static void List_f( const idCmdArgs &args ); - - // Finds a path around dynamic obstacles. - static bool FindPathAroundObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path, idActor* owner ); - // Frees any nodes used for the dynamic obstacle avoidance. - static void FreeObstacleAvoidanceNodes( void ); - // Predicts movement, returns true if a stop event was triggered. - static bool PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path ); - // Return true if the trajectory of the clip model is collision free. - static bool TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime ); - // Finds the best collision free trajectory for a clip model. - static bool PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir ); - - // Begin Dark Mod Functions: - - - /** - * Interface with Dark Mod Sound Propagation - **/ - - /** - * Convert Sound Pressure Level from sound propagation - * to psychoacoustic Loudness for the given AI - * propVol is read from propParms, and - * loudness is set in propParms for later use. - **/ - void SPLtoLoudness( SSprParms *propParms ); - - /** - * CheckHearing returns "true" if the sound is above - * AI hearing threshold, without taking env. noise into - * account. - **/ - bool CheckHearing( SSprParms *propParms ); - - /** - * Called by soundprop when AI hears a sound Assumes that CheckHearing - * has been called and that the sound is above threshold without - * considering environmental noise masking. - **/ - void HearSound( SSprParms *propParms, float noise, const idVec3& origin ); - - /** - * Return the last point at which the AI heard a sound - * Returns (0,0,0) if the AI didn't hear a sound. - * Check AI_HEARDSOUND to see if the vector is valid. - **/ - idVec3 GetSndDir( void ); - - /** - * Return the last point at which an AI glimpsed something suspicious. - * Returns (0,0,0) if the AI was not visually alerted. - * Check AI_VISALERT to see if the vector is valid. - **/ - idVec3 GetVisDir( void ); - - /** - * Returns the entity that the AI is in tactile contact with - **/ - idEntity *GetTactEnt( void ); - - /** - * Visual Alerts - **/ - - /** - * Do a visibility calculation based on 2 things: - * The lightgem value, and the distance to entity - * NYI: take velocity into account - * - * The visibility can also be integrated over a number - * of frames if we need to do that for optimization later. - **/ - float GetVisibility( idEntity *ent ) const; - - /** - * angua: The uncorrected linear light values [1..DARKMOD_LG_MAX] - * didn't produce very believable results when used - * in GetVisibility(). This function takes the linear values - * and corrects them with an "empirical" correction curve. - * - * @returns: a float between [0...1].It is fairly high at - * values above 20, fairly low below 6 and increases linearly in between. - **/ - float GetCalibratedLightgemValue() const; - - /** - * Checks enemies in the AI's FOV and calls Alert( "vis", amount ) - * The amount is calculated based on distance and the lightgem - * - * For now the check is only done on the player - **/ - void PerformVisualScan( float time = 1.0f/60.0f ); - - /** - * Checks to see if the AI is being blocked by an actor when it tries to move, - * call HadTactile this AI and if this is the case. - * - * greebo: Note: Only works if the AI is not Dead, KO or already engaged in combat. - **/ - void CheckTactile(); - - /** - * Tactile Alerts: - * - * If no amount is entered, of the alert is defined in the global AI - * settings def file, and it also gets multiplied by the AI's specific - * "acuity_tact" key in the spawnargs (defaults to 1.0) - * - * The amount is in alert units, so as usual 1 = barely noticible, - * 10 = twice as noticable, etc. - **/ - void TactileAlert(idEntity* tactEnt, float amount = -1); - - /** - * This is called in the frame if the AI bumped into another actor. - * Checks the relationship to the AI, and calls TactileAlert appropriately. - * - * If the bumped actor is an enemy of the AI, the AI calls TactileAlert on itself - * - * If the bumped actor is an AI, and if this AI is an enemy of the bumped AI, - * it calls TactileAlert on the bumped AI as well. - **/ - void HadTactile( idActor *actor ); - - // angua: ignore tactile alerts from this entity from now on - void TactileIgnore(idEntity* tactEnt); - - bool CheckTactileIgnore(idEntity* tactEnt); - - /** - * Generalized alerts and acuities - **/ - - /** - * Alert the AI. The first parameter is the alert type (same as acuity type) - * The second parameter is the alert amount. - * NOTE: For "alert units," an alert of 1 corresponds to just barely - * seeing something or just barely hearing a whisper of a sound. - **/ - void AlertAI( const char *type, float amount ); - - /** - * greebo: Sets the AI_AlertLevel of this AI and updates the AI_AlertIndex. - * - * This also updates the grace timers, alert times and checks for - * a valid agitatedsearching>combat transition. - * - * Additionally, the transition alert sounds ("snd_alertdown2") are played. - */ - void SetAlertLevel(float newAlertLevel); - - - // angua: returns true if the current alert index is higher - // than the previous one, false otherwise - bool AlertIndexIncreased(); - - /** - * Returns the float val of the specific AI's acuity - * Acuity type is a char, from the same list as alert types - * That list is defined in DarkModGlobals.cpp - **/ - float GetAcuity( const char *type ) const; - - /** - * Sets the AI acuity for a certain type of alert. - **/ - void SetAcuity( const char *type, float acuity ); - - /** - * Calls objective system when the AI finds a body - **/ - void FoundBody( idEntity *body ); - - // Adds a message to the queue - void AddMessage(const ai::CommMessagePtr& message); - - // Removes all messages - void ClearMessages(); - - /** - * Get the volume modifier for a given movement type - * Use the same function as idPlayer::GetMovementVolMod. - * Unfortunately this is exactly the same as idPlayer::GetMovementVolMod - * It's bad coding, but that's how D3 wrote the movement vars. - **/ - float GetMovementVolMod( void ); - - /** - * Returns true if AI is knocked out - **/ - bool IsKnockedOut( void ) { return (AI_KNOCKEDOUT!=0); }; - - /** - * Ishtvan: Swap the AI's head CM to a larger one - * (Used to make blackjacking easier, currently only called when a blackjack swings nearby) - * If the argument is true, the larger CM is used, otherwise, the original CM is swapped back. - **/ - void SwapHeadAFCM( bool bUseLargerCM ); - - /** - * Return a damage multiplier if a sneak attack has occurred - **/ - virtual float StealthDamageMult( void ); - - /** - * Ishtvan: Overload AI target changing to re-initialize movement tasks - **/ - virtual void RemoveTarget(idEntity* target); - virtual void AddTarget(idEntity* target); - - // angua: calls the script functions for sitting down and getting up - void SitDown(); - void LayDown(); - - // GetUp is used both for getting up from sitting or sleeping - void GetUp(); - -public: - /** - * DarkMod AI Member Vars - **/ - - /** - * Set to true if the AI has been alerted in this frame - **/ - idScriptBool AI_ALERTED; - - /** - * Stores the actor ultimately responsible for the alert. - * If they find a body, this gets set to whoever killed/KO'd the body. - * If they get hit by an item, or hear it fall, this gets set to whoever - * threw the item, and so on - **/ - idEntityPtr m_AlertedByActor; - - int alertTypeWeight[ai::EAlertTypeCount]; - /** - * Set these flags so we can tell if the AI is running or creeping - * for the purposes of playing audible sounds and propagated sounds. - **/ - idScriptBool AI_CROUCH; - idScriptBool AI_RUN; - idScriptBool AI_CREEP; - - // angua: this determines whether the AI should lay down to the left or to the right after sitting down - // gets read as spawn arg from the path_sleep entity - idScriptBool AI_LAY_DOWN_LEFT; - - // angua: the direction the AI faces before sitting and laying down - idScriptVector AI_LAY_DOWN_FACE_DIR; - - // angua: the AI will turn to this direction after sitting down (this is practical for chairs next to a table) - idScriptFloat AI_SIT_DOWN_ANGLE; - - // angua: the AI will turn to this direction before getting up from sitting - idScriptFloat AI_SIT_UP_ANGLE; - - // greebo: This is to tell the scripts which idle animation should be played next in the CustomIdleAnim state - idStr m_NextIdleAnim; - - /**************************************************************************************** - * - * Added By Rich to implement AI Falling damage - * Called from Think with saved origin and velocity from before moving - * - ****************************************************************************************/ - void CrashLand( const idVec3 &oldOrigin, const idVec3 &oldVelocity ); - - /** - * greebo: Accessor methods for the airTicks member variable. - */ - int getAirTicks() const; - void setAirTicks(int airTicks); - - // greebo: Accessor methods for the array of subsystems - ai::Subsystem* GetSubsystem(ai::SubsystemId id); - - ID_INLINE ai::MindPtr& GetMind() - { - return mind; - } - - ID_INLINE ai::Memory& GetMemory() const - { - return mind->GetMemory(); - } - - ID_INLINE idAAS* GetAAS() const - { - return aas; - } - - float GetArmReachLength(); - - // Virtual override of idActor method, routes the call into the current Mind State - virtual void NeedToUseElevator(const eas::RouteInfoPtr& routeInfo); - - // Switches this AI into conversation mode - virtual bool SwitchToConversationState(const idStr& conversationName); - - -public: - idLinkList aiNode; // for being linked into gameLocal.spawnedAI list - - // greebo: When this AI has last re-evaluated a forbidden area (game time) - int lastAreaReevaluationTime; - // The minimum time that needs to pass by before the AI re-evaluates a forbidden area (msec) - int maxAreaReevaluationInterval; - // The time that needs to pass before locked doors are enabled for another try (msec) - int doorRetryTime; - -protected: - // navigation - idAAS * aas; - int travelFlags; - - idMoveState move; - idMoveState savedMove; - - // A stack of movestates, used for saving and restoring moves in PushMove() and PopMove() - std::list moveStack; - - float kickForce; - bool ignore_obstacles; - float blockedRadius; - int blockedMoveTime; - int blockedAttackTime; - - // turning - float ideal_yaw; - float current_yaw; - float turnRate; - float turnVel; - float anim_turn_yaw; - float anim_turn_amount; - float anim_turn_angles; - - // angua: the offset of the pivot for turning while seated - idVec3 sitting_turn_pivot; - - // This expands the AABB a bit when the AI is checking for reached positions. - float reachedpos_bbox_expansion; - - // greebo: Defines the maximum vertical tolerance within wich a point above an AAS area is still considered reachable. - // This is used by PathToGoal to judge whether an area is reachable or not. - float aas_reachability_z_tolerance; - - // physics - idPhysics_Monster physicsObj; - - // flying - jointHandle_t flyTiltJoint; - float fly_speed; - float fly_bob_strength; - float fly_bob_vert; - float fly_bob_horz; - int fly_offset; // prefered offset from player's view - float fly_seek_scale; - float fly_roll_scale; - float fly_roll_max; - float fly_roll; - float fly_pitch_scale; - float fly_pitch_max; - float fly_pitch; - - bool allowMove; // disables any animation movement - bool allowHiddenMovement; // allows character to still move around while hidden - bool disableGravity; // disables gravity and allows vertical movement by the animation - - // weapon/attack vars - bool lastHitCheckResult; - int lastHitCheckTime; - int lastAttackTime; - float fire_range; - float projectile_height_to_distance_ratio; // calculates the maximum height a projectile can be thrown - idList missileLaunchOffset; - - struct ProjectileInfo - { - const idDict* def; - idStr defName; - idClipModel* clipModel; - float radius; - float speed; - idVec3 velocity; - idVec3 gravity; - - ProjectileInfo() : - def(NULL), - clipModel(NULL), - radius(-1), - speed(-1) - {} - - ~ProjectileInfo() - { - // Take care of any allocated clipmodels on destruction - delete clipModel; - } - }; - - /** - * greebo: An AI can have multiple projectile defs in their entityDef declaration. - * For some routines the properties of each projectile need to be cached, like - * radius, clipmodel and gravity, this is stored in the ProjectileInfo structure. - * - * After each CreateProjectile() call the "current projectile" index is recalculated - * and might point to a different projectile for the next round of firing. - */ - idList projectileInfo; - - // The index of the "current projectile", is recalculated each time CreateProjectile() is called. - int curProjectileIndex; - - /** - * The currently active projectile. It holds the spawned - * projectile entity, which can either be generated from the - * list of possible ProjectileInfo structures above or a custom - * one which has been spawned directly via script or frame commands. - * - * The ActiveProjectile structure is filled either by calling CreateProjectile() - * or by methods like Event_CreateThrowableProjectile() - */ - struct ActiveProjectile - { - // The projectile parameter structure - ProjectileInfo info; - - // The currently active projectile entity (might be NULL) - idEntityPtr projEnt; - }; - - // The currently active projectile, might be an empty structure - ActiveProjectile activeProjectile; - - idStr attack; - - /** - * grayman #2603 - Per-stim info for relighting lights. This allows AI to - * keep track of delays for responding to visual stims. The delays are - * determined by conditions surrounding a relight and the probabilities - * associated with relighting. - */ - struct DelayedStim - { - // The next time to consider the stim - int nextTimeToConsider; - - // The stim being delayed - idEntityPtr stim; - }; - - idList delayedStims; // grayman #2603 - - // chatter/talking - talkState_t talk_state; - idEntityPtr talkTarget; - - // cinematics - int num_cinematics; - int current_cinematic; - - bool allowJointMod; - idEntityPtr focusEntity; - idVec3 currentFocusPos; - int focusTime; - int alignHeadTime; - int forceAlignHeadTime; - idAngles eyeAng; - idAngles lookAng; - idAngles destLookAng; - idAngles lookMin; - idAngles lookMax; - idList lookJoints; - idList lookJointAngles; - idList lookJointsCombat; - idList lookJointAnglesCombat; - float eyeVerticalOffset; - float eyeHorizontalOffset; - float eyeFocusRate; - float headFocusRate; - int focusAlignTime; - - // special fx - float shrivel_rate; - int shrivel_start; - - bool restartParticles; // should smoke emissions restart - bool useBoneAxis; // use the bone vs the model axis - idList particles; // particle data - - renderLight_t worldMuzzleFlash; // positioned on world weapon bone - int worldMuzzleFlashHandle; - jointHandle_t flashJointWorld; - int muzzleFlashEnd; - int flashTime; - - // joint controllers - idAngles eyeMin; - idAngles eyeMax; - jointHandle_t focusJoint; - jointHandle_t orientationJoint; - - typedef std::set FrobMoverList; - FrobMoverList unlockableDoors; - - typedef std::set TactileIgnoreList; - TactileIgnoreList tactileIgnoreEntities; - -public: // greebo: Made these public - // enemy variables - idEntityPtr enemy; - idVec3 lastVisibleEnemyPos; - idVec3 lastVisibleEnemyEyeOffset; - idVec3 lastVisibleReachableEnemyPos; - idVec3 lastReachableEnemyPos; - bool enemyReachable; - bool wakeOnFlashlight; - int lastUpdateEnemyPositionTime; - - // grayman #2887 - next 2 are used to determine amount of "busted" time - - int lastTimePlayerSeen; - int lastTimePlayerLost; - -public: // greebo: Made these public for now, I didn't want to write an accessor for EVERYTHING - // script variables - idScriptBool AI_TALK; - idScriptBool AI_DAMAGE; - idScriptBool AI_PAIN; - idScriptFloat AI_SPECIAL_DAMAGE; - //idScriptBool AI_DEAD; // is defined on idActor now - idScriptBool AI_KNOCKEDOUT; - idScriptBool AI_ENEMY_VISIBLE; - idScriptBool AI_ENEMY_IN_FOV; - idScriptBool AI_MOVE_DONE; - idScriptBool AI_ONGROUND; - idScriptBool AI_ACTIVATED; - idScriptBool AI_FORWARD; - idScriptBool AI_JUMP; - idScriptBool AI_BLOCKED; - idScriptBool AI_OBSTACLE_IN_PATH; - idScriptBool AI_DEST_UNREACHABLE; - idScriptBool AI_HIT_ENEMY; - idScriptBool AI_PUSHED; - - /** - * The following variables are set as soon as the AI - * gets a certain type of alert, and never unset by the - * game code. They are only unset in scripting. This is - * to facilitate different script reactions to different kinds - * of alerts. - * - * It's also done this way so that the AI will know if it has been - * alerted even if it happened in a frame that the script did not check. - * - * This is to facilitate optimization by having the AI check for alerts - * every N frames rather than every frame. - **/ - - - /** - * Set to true if the AI heard a suspicious sound. - **/ - idScriptBool AI_HEARDSOUND; - - /** - * Set to true if the AI saw something suspicious. - **/ - idScriptBool AI_VISALERT; - - /** - * Set to true if the AI was pushed by or bumped into an enemy. - **/ - idScriptBool AI_TACTALERT; - - /** - * The current alert number of the AI. - * This is checked to see if the AI should - * change alert indices. This var is very important! - * NOTE: Don't change this directly. Instead, call Event_SetAlertLevel - * to change it. - **/ - idScriptFloat AI_AlertLevel; - - /** - * Current alert index of the AI. Is set based on AI_AlertLevel and the alert threshold values: - * ai::ERelaxed == 0 if AI_AlertLevel < thresh_1 - * ai::EObservant == 1 if thresh_1 <= AI_AlertLevel < thresh_2 - * ai::ESuspicious == 2 if thresh_2 <= AI_AlertLevel < thresh_3 - * ai::EInvestigating == 3 if thresh_3 <= AI_AlertLevel < thresh_4 - * ai::EAgitatedSearching == 4 if thresh_4 <= AI_AlertLevel < thresh_5 - * ai::ECombat == 5 if thresh_5 <= AI_AlertLevel (and an enemy is known) - **/ - idScriptFloat AI_AlertIndex; - - /** - * Stores the amount alerted in this frame - * Used to compare simultaneous alerts, the smaller one is ignored - * Should be cleared at the start of each frame. - **/ - float m_AlertLevelThisFrame; - - - // angua: stores the previous alert index at alert index changes - int m_prevAlertIndex; - - // angua: the highest alert level/index the AI reached already - float m_maxAlertLevel; - int m_maxAlertIndex; - - // angua: the alert level the AI had after the last alert level increase - float m_lastAlertLevel; - - /** - * If true, the AI ignores alerts during all actions - **/ - bool m_bIgnoreAlerts; - - /** - * Array containing the various AI acuities (visual, aural, tactile, etc) - **/ - idList m_Acuities; - - - float m_oldVisualAcuity; // Tels: fixes 2408 - - /** - * Audio detection threshold (in dB of Sound Pressure Level) - * Sounds heard below this volume will be ignored (default is 20 dB) - * Soundprop only goes down to 15 dB, although setting it lower than - * this will still have some effect, since alert = volume - threshold - **/ - float m_AudThreshold; - - /** - * Static visual distance cutoff that is calculated dynamically - * from the other visual acuity settings. - **/ - float m_VisDistMax; - - /** - * The loudest direction for the last suspicious sound the AI heard - * is set to NULL if the AI has not yet heard a suspicious sound - * Note suspicious sounds that are omnidirectional do not set this. - * If no sound has been propagated it will be (0,0,0). - **/ - idVec3 m_SoundDir; - - /** - * Position of the last visual alert - **/ - idVec3 m_LastSight; - - /** - * The entity that last issued a tactile alert - **/ - idEntityPtr m_TactAlertEnt; - - /** - * Alert Grace period variables : - * Actor that the alert grace period applies to: - **/ - idEntityPtr m_AlertGraceActor; - - /** - * Time of the grace period start [ms] - **/ - int m_AlertGraceStart; - - /** - * Duration of the grace period [ms] - **/ - int m_AlertGraceTime; - - /** - * Alert number below which alerts are ignored during the grace period - **/ - float m_AlertGraceThresh; - - /** - * Number of alerts ignored in this grace period - **/ - int m_AlertGraceCount; - - /** - * Number of alerts it takes to override the grace period via sheer number - * (This is needed to make AI rapidly come up to alert due to visual alert, - * because visual alerts do not increase in magnitude but just come in more rapidly - **/ - int m_AlertGraceCountLimit; - - /** - * greebo: This is the message "outbox" of an AI. During sound propagation - * the messages are traversed and delivered to the "recipient" AI. - * Once delivered, messages are automatically removed from this list. - * - * Use AddMessage() to store new messages here. - */ - ai::MessageList m_Messages; - - /** - * The current mod hiding spot search of this AI, usually -1 - */ - int m_HidingSpotSearchHandle; - - /** - * The spots resulting from the current search or gotten from - * another AI. - */ - CDarkmodHidingSpotTree m_hidingSpots; - - - /** - * Used for drowning - **/ - int m_AirCheckTimer; - - bool m_bCanDrown; - - /** - * Head body ID on the AF, used by drowning - **/ - int m_HeadBodyID; - - /** - * Head joint ID on the living AI (used by FOV and KOing) - **/ - jointHandle_t m_HeadJointID; - - /** - * Some AI have a different head CM while conscious. - * This variable stores the original head CM from the AF, - * to set it back when they die/get ko'd. - **/ - idClipModel *m_OrigHeadCM; - /** If true, head was swapped when alive and needs to be swapped back when ragdolled **/ - bool m_bHeadCMSwapped; - - /** - * Knockout Data - * Name of damage location within which a KO is possible - **/ - idStr m_KoZone; - /** - * Alert state above which their KO Immunity changes (if any) - **/ - int m_KoAlertImmuneState; - /** - * Alert state above which their KO behavior changes (if any) - **/ - int m_KoAlertState; - /** - * True if AI is completely immune to KO when alerted above the given alert state - **/ - bool m_bKoAlertImmune; - /** - * Cosines of the vertical and horizontal angles, and the same when alert - **/ - float m_KoDotVert; - float m_KoDotHoriz; - float m_KoAlertDotVert; - float m_KoAlertDotHoriz; - /** - * Rotates the KO cone relative to the head joint - **/ - idMat3 m_KoRot; - - /** - * Current number of air ticks left for drowning - **/ - int m_AirTics; - - /** - * Max number of air ticks for drowning - **/ - int m_AirTicksMax; - - /** - * number of seconds between air checks - **/ - int m_AirCheckInterval; - - /** - * Offset relative to the head origin when the head is separate, or the eye - * when the head is attached. Used to locate the mouth. - **/ - idVec3 m_MouthOffset; - - /** - * Set to true if the AI can be KO'd (defaults to true) - **/ - bool m_bCanBeKnockedOut; - - /** - * Set to true if the AI can be gassed (defaults to true) - **/ - bool m_bCanBeGassed; // grayman #2468 - - /** - * How the AI was knocked out - **/ - koState_t m_koState; // grayman #2604 - - /** - * Keep track of initial thinking frame count - important when a cinematic starts the mission - **/ - int m_earlyThinkCounter; // grayman #2654 - - /** - * grayman #2603 - if TRUE, don't allow movement extrication - **/ - - bool m_bCanExtricate; - - /** - * greebo: Is set to TRUE if the AI is able to open/close doors at all. - */ - bool m_bCanOperateDoors; - - /** - * angua: is set true while the AI is handling the door. - */ - bool m_HandlingDoor; - - /** - * grayman #2706: is set true when the move prior to door handling is saved - */ - bool m_RestoreMove; - - /** - * grayman #2603: is set true when a search needs to be set up after relighting a light - */ - bool m_LatchedSearch; - - /** - * grayman #2603: list of doused lights seen - */ - idList< idEntityPtr > m_dousedLightsSeen; - - /** - * angua: is set true while the AI is handling an elevator. - */ - bool m_HandlingElevator; - - /** - * grayman #2603: is set true while the AI is relighting a light. - */ - bool m_RelightingLight; - - /** - * grayman #2872: is set to true while the AI is examining a rope - */ - bool m_ExaminingRope; - - /** - * grayman #2603: is set true while the AI is dropping a torch. - */ - bool m_DroppingTorch; - - /** - * Head center offset in head joint coordinates, relative to head joint - * When this offset is added to the head joint, we should be at the head center - **/ - idVec3 m_HeadCenterOffset; - - /** - * Rotates the FOV cone relative to the head joint - **/ - idMat3 m_FOVRot; - - /** - * Set to true if we want this AI to push off the player when the - * player ends up standing on top of them - * Applies only when the AI is alive - **/ - bool m_bPushOffPlayer; - - /** - * Ishtvan: Flat-footedness, disallows movement while maitaining ability to turn - * Currently only implemented in melee - * The following are timers for being flat-footed in all situations - **/ - bool m_bCanBeFlatFooted; - bool m_bFlatFooted; - int m_FlatFootedTimer; - int m_FlatFootedTime; - /** - * The following apply to being flat-footed as a result of a parry only - **/ - int m_FlatFootParryNum; // runtime tracking - int m_FlatFootParryMax; // spawnarg cap - int m_FlatFootParryTimer; // runtime tracking - int m_FlatFootParryTime; // spawnarg cap [ms] - /** - * Melee: Chance to counter attack into an enemy attack instead of parrying: - **/ - float m_MeleeCounterAttChance; - /** - * Does this AI try to predict when the enemy will be close enough - * in the future and start their melee swing in advance? - **/ - bool m_bMeleePredictProximity; - - // AI_AlertLevel thresholds for each alert level - // Alert levels are: 1=slightly suspicious, 2=aroused, 3=investigating, 4=agitated investigating, 5=hunting - float thresh_1, thresh_2, thresh_3, thresh_4, thresh_5; - // Grace period info for each alert level - float m_gracetime_1, m_gracetime_2, m_gracetime_3, m_gracetime_4; - float m_gracefrac_1, m_gracefrac_2, m_gracefrac_3, m_gracefrac_4; - int m_gracecount_1, m_gracecount_2, m_gracecount_3, m_gracecount_4; - // De-alert times for each alert level - float atime1, atime2, atime3, atime4, atime_fleedone; - - float atime1_fuzzyness, atime2_fuzzyness, atime3_fuzzyness, atime4_fuzzyness, atime_fleedone_fuzzyness; - - // angua: Random head turning - int m_timeBetweenHeadTurnChecks; - float m_headTurnChanceIdle; - float m_headTurnFactorAlerted; - float m_headTurnMaxYaw; - float m_headTurnMaxPitch; - int m_headTurnMinDuration; - int m_headTurnMaxDuration; - - idEntity* m_tactileEntity; // grayman #2345 - something we bumped into this frame, not necessarily an enemy - bool m_canResolveBlock; // grayman #2345 - whether we can resolve a block if asked - bool m_leftQueue; // grayman #2345 - if we timed out waiting in a door queue - bool m_performRelight; // grayman #2603 - set to TRUE by a script function when it's time to relight a light - - // The mind of this AI - ai::MindPtr mind; - - // The array of subsystems of this AI - ai::SubsystemPtr senseSubsystem; - ai::MovementSubsystemPtr movementSubsystem; - ai::SubsystemPtr actionSubsystem; - ai::CommunicationSubsystemPtr commSubsystem; - - // greebo: The names of the backbone states, one for each alert state - // e.g. ECombat => "Combat" - typedef std::map BackboneStateMap; - BackboneStateMap backboneStates; - - /** - * This internal method destroys the current hiding spot search - * if it is not null. - */ - void destroyCurrentHidingSpotSearch(); - - /*! - * This method finds hiding spots in the bounds given by two vectors, and also excludes - * any points contained within a different pair of vectors. - * - * The first paramter is a vector which gives the location of the - * eye from which hiding is desired. - * - * The second vector gives the minimums in each dimension for the - * search space. - * - * The third and fourth vectors give the min and max bounds within which spots should be tested - * - * The fifth and sixth vectors give the min and max bounds of an area where - * spots should NOT be tested. This overrides the third and fourth parameters where they overlap - * (producing a dead zone where points are not tested) - * - * The seventh parameter gives the bit flags of the types of hiding spots - * for which the search should look. - * - * The eighth parameter indicates an entity that should be ignored in - * the visual occlusion checks. This is usually the searcher itself but - * can be NULL. - * - * This method will only start the search, if it returns 1, you should call - * continueSearchForHidingSpots every frame to do more processing until that function - * returns 0. - * - * The return value is a 0 for failure, 1 for success. - */ - int StartSearchForHidingSpotsWithExclusionArea - ( - const idVec3& hideFromLocation, - const idVec3& minBounds, - const idVec3& maxBounds, - const idVec3& exclusionMinBounds, - const idVec3& exclusionMaxBounds, - int hidingSpotTypesAllowed, - idEntity* p_ignoreEntity - ); - - /* - * This method continues searching for hiding spots. It will only find so many before - * returning so as not to cause long delays. Detected spots are added to the currently - * building hiding spot list. - * - * The return value is 0 if the end of the search was reached, or 1 if there - * is more processing to do (call this method again next AI frame) - * - */ - int ContinueSearchForHidingSpots(); - - /*! - * This method returns the Nth hiding spot location. - * Param is 0-based hiding spot index. - */ - idVec3 GetNthHidingSpotLocation(int hidingSpotIndex); - - /*! - * This event splits off half of the hiding spot list of another entity - * and sets our hiding spot list to the "taken" points. - * - * As such, it is useful for getting hiding spots from a seraching AI that this - * AI is trying to assist. - * - * @param p_otherEntity The other entity who's hiding spots we are taking - * - * @return The number of points in the list gotten - */ - int GetSomeOfOtherEntitiesHidingSpotList(idEntity* p_ownerOfSearch); - - void SetAAS( void ); - virtual void DormantBegin( void ); // called when entity becomes dormant - virtual void DormantEnd( void ); // called when entity wakes from being dormant - void Think( void ); - void Activate( idEntity *activator ); - int ReactionTo( const idEntity *ent ); - bool CheckForEnemy( void ); - void EnemyDead( void ); - - - /** - * angua: Interleaved thinking optimization - * AI will only think once in a certain number of frames - * depending on player distance and whether the AI is in the player view - * (this includes movement, pathing, physics and the states and tasks) - */ - - // This checks whether the AI should think in this frame - bool ThinkingIsAllowed(); - - // Sets the frame number when the AI should think next time - void SetNextThinkFrame(); - - // returns interleave think frames - // the AI will only think once in this number of frames - int GetThinkInterleave() const; // grayman 2414 - add 'const' - int m_nextThinkFrame; - - // Below min dist, the AI thinks normally every frame. - // Above max dist, the thinking frequency is given by max interleave think frames. - // The thinking frequency increases linearly between min and max dist. - int m_maxInterleaveThinkFrames; - float m_minInterleaveThinkDist; - float m_maxInterleaveThinkDist; - - // the last time where the AI did its thinking (used for physics) - int m_lastThinkTime; - - // grayman #2691 - this checks if a doorway is large enough to fit through when the door is fully open - bool CanPassThroughDoor(CFrobDoor* frobDoor); - - // grayman #2603 - am I carrying a torch? - idEntity* GetTorch(); - - bool IsSearching(); // grayman #2603 - - virtual void Hide( void ); - virtual void Show( void ); - virtual bool CanBecomeSolid(); - idVec3 FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ); - void CalculateAttackOffsets( void ); - void PlayCinematic( void ); - - // movement - virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - void GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta ); - void CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ); - void DeadMove( void ); - void AnimMove( void ); - void SlideMove( void ); - void SittingMove(); - void NoTurnMove(); - void LayDownMove(); - void AdjustFlyingAngles( void ); - void AddFlyBob( idVec3 &vel ); - void AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ); - void FlySeekGoal( idVec3 &vel, idVec3 &goalPos ); - void AdjustFlySpeed( idVec3 &vel ); - void FlyTurn( void ); - void FlyMove( void ); - void StaticMove( void ); - - // greebo: Overrides idActor::PlayFootStepSound() - virtual void PlayFootStepSound(); - - // greebo: Plays the given bark sound (will override any sounds currently playing) - virtual void Bark(const idStr& soundName); - - // damage - virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location, const idDict* damageDef ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision = NULL); - - void DropBlood(idEntity *inflictor); - void SpawnBloodMarker(const idStr& splat, const idStr& splatFading, float size); - - void PostDeath(); - - /** - * Copy knockout spawnargs from the head entity (assumes head exists) - **/ - void CopyHeadKOInfo(void); - - /** - * Parse knockout spawnargs - **/ - void ParseKnockoutInfo( void ); - - /** - * TestKnockOutBlow is called when the AI is hit with a weapon with knockout capability. - * This function tests the location hit, angle of the blow, and alert state of the AI. - * - * The "dir" vector is from the knockback of the weapon. It is not used for now. - * - * tr is the trace from the weapon collision, location is the joint handle that was hit - * bIsPowerBlow is set if the BJ was powered up - * - * Returns false if BJ attempt failed, or if already knocked out - * - * Note: overrides idActor::TestKnockoutBlow. - **/ - virtual bool TestKnockoutBlow( idEntity* attacker, const idVec3& dir, trace_t *tr, int location, bool bIsPowerBlow ); - - /** - * Tells the AI to go unconscious. Called by TestKnockoutBlow if successful, - * also can be called by itself and is called by scriptevent AI_KO_Knockout. - * - * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". - **/ - void Event_KO_Knockout( idEntity* inflictor ); - - /** - * grayman #2468 - Tells the AI to go unconscious. Called by scriptevent AI_Gas_Knockout. - * - * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". - **/ - void Event_Gas_Knockout( idEntity* inflictor ); - - /** - * Tells the AI to go unconscious. - * - * @inflictor: This is the entity causing the knockout, can be NULL for "unknown originator". - **/ - void Knockout( idEntity* inflictor ); - - /** - * greebo: Does a few things after the knockout animation has finished. - * This includes setting the model, dropping attachments and starting ragdoll mode. - * Note: Gets called by the Mind's KnockOutState. - */ - void PostKnockOut(); - - /** - * Drop certain attachments and def_drop items when transitioning into a ragdoll state - * Called by idActor::Killed and idActor::KnockedOut - **/ - void DropOnRagdoll( void ); - - // navigation - void KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ); - - // greebo: For Documentation, see idActor class (this is an override). - virtual bool ReEvaluateArea(int areaNum); - - /** - * greebo: ReachedPos checks whether we the AI has reached the given target position . - * The check is a bounds check ("bounds contain point?"), the bounds radius is - * depending on the given . - * - * @returns: TRUE when the position has been reached, FALSE otherwise. - */ - bool ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand) const; - - // greebo: Bounding box check to see if the AI has reached the given position. Returns TRUE if position reached. - bool ReachedPosAABBCheck(const idVec3& pos) const; - - float TravelDistance( const idVec3 &start, const idVec3 &end ); - - /** - * greebo: Returns the number of the nearest reachable area for the given point. - * Depending on the move type, the call is routed to the AAS->PointReachableAreaNum - * function. The bounds are modified before submission to the AAS function. - * - * @returns: the areanumber of the given point, 0 == no area found. - */ - int PointReachableAreaNum(const idVec3 &pos, const float boundsScale = 2.0f, const idVec3& offset = idVec3(0,0,0)) const; - - bool PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, idActor* actor ) const; - void DrawRoute( void ) const; - bool GetMovePos( idVec3 &seekPos ); - bool MoveDone( void ) const; - - ID_INLINE moveType_t GetMoveType() const - { - return move.moveType; - } - - void SetMoveType( int moveType ); - - - /** - * This is a virtual override of the idActor method. It takes lighting levels into consideration - * additional to the ordinary FOV/trace check in idActor. - */ - virtual bool CanSee( idEntity *ent, bool useFOV ) const; - - - /** - * This version can optionally use or not use lighting and fov - */ - virtual bool CanSeeExt ( idEntity* ent, const bool useFOV, const bool useLighting ) const; - - /** - * This tests if a position is visible. it can optionally use lighting and fov. - */ - virtual bool CanSeePositionExt( idVec3 position, bool useFOV, bool useLighting ); - - bool EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos ); - - bool CanSeeTargetPoint( idVec3 point, idEntity* target ) const; // grayman #2859 - - idVec3 CanSeeRope( idEntity *ent ) const; // grayman #2872 - - // angua: if the focusTime > gameLocal.time, the AI is currently looking at a specified entity or location - ID_INLINE int GetFocusTime() - { - return focusTime; - } - - void BlockedFailSafe( void ); - /** - * Overloaded idActor::CheckFOV with FOV check that depends on head joint orientation - **/ - virtual bool CheckFOV( const idVec3 &pos ) const; - - /** - * Darkmod enemy tracking: Is an entity shrouded in darkness? - * @author: SophisticatedZombie, tels - * - * The sightThreshold goes from 0.0f to 1.0f. Uses FOV, distance and lighting of the - * entity to determine visibility. - * - * @return true if the entity is in darkness - * @return false if not - */ - bool IsEntityHiddenByDarkness (idEntity* p_entity, const float sightThreshold) const; - - /** - * greebo: Returns TRUE if the entity is within the "attack_cone". - */ - bool EntityInAttackCone(idEntity* entity); - - /** - * Returns TRUE or FALSE, depending on the distance to the - * given entity and the weapons attached to this AI. - * Melee AI normally perform a bounding box expansion check, - * ranged AI implement a visual test incl. lighting. - */ - bool CanHitEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); - /** - * Will we be able to hit an enemy that is not currently in reach but coming into reach - * Similar to CanHitEntity, but uses predicted future positions based on velocity - * and a given prediction time. Only applies to melee combat - **/ - bool WillBeAbleToHitEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); - - /** - * Returns TRUE or FALSE, depending on the distance to the - * given entity and the weapons attached to it. - * May include other factors such as relative velocity - * Ranged combat NYI (may overlap with existing "take cover" algorithms) - */ - bool CanBeHitByEntity(idActor* entity, ECombatType combatType = COMBAT_NONE); - - /** - * greebo: This updates the weapon attachment's "solid" status. - * By design, AI have solid weapons only when in searching states. - */ - void UpdateAttachmentContents(bool makeSolid); - - - // movement control - void StopMove( moveStatus_t status ); - bool FaceEnemy( void ); - bool FaceEntity( idEntity *ent ); - bool DirectMoveToPosition( const idVec3 &pos ); - bool MoveToEnemyHeight( void ); - bool MoveOutOfRange( idEntity *entity, float range ); - const idVec3& GetMoveDest() const; - idEntity* GetTactileEntity(void); // grayman #2345 - - /** - * greebo: Flee from the given entity. Pass the maximum distance this AI should search escape areas in. - */ - bool Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption); - aasGoal_t GetPositionWithinRange(const idVec3& targetPos); - idVec3 GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne); - bool MoveToAttackPosition( idEntity *ent, int attack_anim ); - bool MoveToEnemy( void ); - bool MoveToEntity( idEntity *ent ); - - // Override idActor::OnElevator. See idActor class for documentation. - virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; - - /** - * greebo: This moves the entity to the given point. - * - * @returns: FALSE, if the position is not reachable (AI_DEST_UNREACHABLE && AI_MOVE_DONE == true) - * @returns: TRUE, if the position is reachable and the AI is moving (AI_MOVE_DONE == false) - * OR the position is already reached (AI_MOVE_DONE == true). - */ - bool MoveToPosition( const idVec3 &pos, float accuracy = -1 ); - - /** - * angua: This looks for a suitable position for taking cover - * - * @returns: FALSE, if no suitable position is found - * @returns: TRUE, if the position is reachable - * The position is stored in . - */ - bool LookForCover(aasGoal_t& hideGoal, idEntity *entity, const idVec3 &pos ); - bool MoveToCover( idEntity *entity, const idVec3 &pos ); - bool SlideToPosition( const idVec3 &pos, float time ); - bool WanderAround( void ); - /** - * Ish : Move AI along a vector without worrying about AAS or obstacles - * Can be used for direct control of an AI - * Applies finite turn speed toward the direction - **/ - bool MoveAlongVector( float yaw ); - bool StepDirection( float dir ); - bool NewWanderDir( const idVec3 &dest ); - - // greebo: These two Push/Pop commands can be used to save the current move state in a stack and restore it later on - void PushMove(); - void PopMove(); - - // Local helper function, will restore the current movestate from the given saved one - void RestoreMove(const idMoveState& saved); - - // effects - const idDeclParticle *SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName ); - void SpawnParticles( const char *keyName ); - bool ParticlesActive( void ); - - // turning - bool FacingIdeal( void ); - void Turn(const idVec3& pivotOffset = idVec3(0,0,0)); - bool TurnToward( float yaw ); - bool TurnToward( const idVec3 &pos ); - ID_INLINE float GetCurrentYaw() { return current_yaw; } - ID_INLINE float GetIdealYaw() { return ideal_yaw; } // grayman #2345 - ID_INLINE float GetTurnRate() { return turnRate; } - ID_INLINE void SetTurnRate(float newTurnRate) { turnRate = newTurnRate; } - - // enemy management - void ClearEnemy( void ); - bool EnemyPositionValid( void ) const; - - /** - * greebo: SetEnemyPos() tries to determine the enemy location and to setup a path - * to the enemy, depending on the AI's move type (FLY/WALK). - * - * If this method succeeds in setting up a path to the enemy, the following members are - * set: lastVisibleReachableEnemyPos, lastVisibleReachableEnemyAreaNum - * and the movecommands move.toAreaNum and move.dest are updated, but the latter two - * ONLY if the movecommand is set to MOVE_TO_ENEMY beforehand. - * - * The AI_DEST_UNREACHABLE is updated if the movecommand is currently set to MOVE_TO_ENEMY. - * - * It is TRUE (enemy unreachable) in the following cases: - * - Enemy is not on ground (OnLadder) for non-flying AI. - * - The entity area number could not be determined. - * - PathToGoal failed, no path to the enemy could be found. - * - * Note: This overwrites a few lastVisibleReachableEnemyPos IN ANY CASE with the - * lastReachableEnemyPos, so this is kind of cheating if the enemy is not visible before calling this. - * Also, lastVisibleEnemyPos is overwritten by the enemy's origin IN ANY CASE. - * - * Basically, this method relies on "lastReachableEnemyPos" being set beforehand. - */ - void SetEnemyPosition(); - - /** - * greebo: This is pretty similar to SetEnemyPosition, but not the same. - * - * First, this tries to locate the current enemy position (disregards visibility!) and - * to set up a path to the entity's origin/floorposition. If this succeeds, - * the "lastReachableEnemyPos" member is updated, but ONLY if the enemy is on ground. - * - * Second, if the enemy is visible or heard, SetEnemyPosition is called, which updates - * the lastVisibleReachableEnemyPosition. - */ - void UpdateEnemyPosition(); - - /** - * greebo: Updates the enemy pointer and tries to set up a path to the enemy by - * using SetEnemyPosition(), but ONLY if the enemy has actually changed. - * - * AI_ENEMY_DEAD is updated at any rate. - * - * @returns: TRUE if the enemy has been set and is non-NULL, FALSE if the enemy - * is dead or has been cleared by anything else. - */ - bool SetEnemy(idActor *newEnemy); - - /** - * DarkMod: Ishtvan note: - * Before I added this, this code was only called in - * Event_FindEnemy, so it could be used by scripting, but - * not by the SDK. I just moved the code to a new function, - * and made Event_FindEnemy call this. - * - * This was because I needed to use FindEnemy in the visibility - * calculation. - **/ - idActor * FindEnemy( bool useFOV ) ; - - idActor* FindEnemyAI(bool useFOV); - - idActor* FindFriendlyAI(int requiredTeam); - - - /** - * Similarly to FindEnemy, this was previously only an Event_ scripting - * function. I moved it over to a new SDK function and had the Event_ - * call it, in case we want to use this later. It returns the closest - * AI or Player enemy. - * - * It was originally used to get tactile alerts, but is no longer used for that - * IMO we should leave it in though, as we might use it for something later, - * like determining what targets to engage with ranged weapons. - **/ - idActor * FindNearestEnemy( bool useFOV = true ); - - /** - * angua: this returns if the AI has seen evidence of an intruder already - * (the enemy, a body, missing loot...) - */ - bool HasSeenEvidence() const; - - /** - * Draw the debug cone representing valid knockout area - * Called every frame when cvar cv_ai_ko_show is set to true. - **/ - void KnockoutDebugDraw( void ); - - /** - * Draw the debug cone representing the FOV - * Called every frame when cvar cv_ai_fov_show is set to true. - **/ - void FOVDebugDraw( void ); - - /** - * This method calculates the maximum distance from a given - * line segment that the segment is visible due to current light conditions - * at the segment. Does not accept NULL pointers! - */ - float GetMaximumObservationDistanceForPoints(const idVec3& p1, const idVec3& p2) const; - - // Returns the maximum distance where this AI can still see the given entity from - float GetMaximumObservationDistance(idEntity* entity) const; - - /** - * The point of this function is to determine the visual stimulus level caused - * by addition of the CVAR tdm_ai_sight_mag. The current alert level is taken - * as reference value and the difference in logarithmic alert units is returned. - */ - float GetPlayerVisualStimulusAmount() const; - - // attacks - - // greebo: Ensures that the projectile info of the currently active projectile - // is holding a valid clipmodel and returns the info structure for convenience. - ProjectileInfo& EnsureActiveProjectileInfo(); - - // Called at spawn time to ensure valid projectile properties in the info structures (except clipmodel) - // activeProjectile.projEnt will be NULL after this call - void InitProjectileInfo(); - - // Specialised routine to initialise the given projectile info structure from the named or given dictionary - // Won't touch the activeProjectile structure, so it's safe to use that as helper. - void InitProjectileInfoFromDict(ProjectileInfo& info, const char* entityDef) const; - void InitProjectileInfoFromDict(ProjectileInfo& info, const idDict* dict) const; - - /** - * greebo: Changed this method to support multiple projectile definitions (D3 suppoerted exactly one). - * The index argument can be set to anything within [0..projectileInfo.Num()) to spawn a specific - * projectile from the list of possible ones, or leave that argument at the default of -1 to - * create a projectile using the "current projectile index". That index is re-rolled each - * time after this method has been called, so the AI will seemingly use random projectiles. - * - * Note: doesn't do anything if the currently active projectile is not NULL. - */ - idProjectile* CreateProjectile(const idVec3 &pos, const idVec3 &dir, int index = -1); - -private: - /** - * greebo: Specialised method similar to the CreateProjectile() variant taking an index. - * This method doesn't use the projectileInfo list, but spawns a new active projectile - * directly from the given dictionary. This can be used to spawn projectiles out of the usual - * loop of known projectile defs. - * - * Note: doesn't do anything if the currently active projectile is not NULL. - */ - idProjectile* CreateProjectileFromDict(const idVec3 &pos, const idVec3 &dir, const idDict* dict); - - // Helper routine to spawn an actual projectile with safety checks. Will throw gameLocal.Error on failure. - // The result will always be non-NULL - idProjectile* SpawnProjectile(const idDict* dict) const; - - void RemoveProjectile( void ); - -public: - idProjectile* LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone ); - virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); - void DirectDamage( const char *meleeDefName, idEntity *ent ); - bool TestMelee( void ) const; - /** ishtvan: test melee anticipating future positions **/ - bool TestMeleeFuture( void ) const; - bool TestRanged( void ); - bool AttackMelee( const char *meleeDefName ); - void BeginAttack( const char *name ); - void EndAttack( void ); - void PushWithAF( void ); - - // special effects - void GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ); - void InitMuzzleFlash( void ); - void TriggerWeaponEffects( const idVec3 &muzzle ); - void UpdateMuzzleFlash( void ); - virtual bool UpdateAnimationControllers( void ); - void UpdateParticles( void ); - void TriggerParticles( const char *jointName ); - - // AI script state management - virtual void LinkScriptVariables( void ); - virtual void UpdateScript(); // overrides idActor::UpdateScript - - // Returns true if the current enemy can be reached - bool CanReachEnemy(); - - // Returns the current move status (MOVE_STATUS_MOVING, for instance). - moveStatus_t GetMoveStatus() const; - - /** - * Returns true if AI's mouth is underwater - **/ - bool MouthIsUnderwater( void ); - - /** - * Checks for drowning, damages if drowning. - * - * greebo: Only enabled if the entity is able to drown and the - * interleave timer is elapsed (is not checked each frame). - **/ - void UpdateAir(); - - /** - * Halts lipsync - **/ - void StopLipSync(); - - /** - * Plays and lipsyncs the given sound name, returns the duration in msecs. - */ - int PlayAndLipSync(const char *soundName, const char *animName); - - // Lip sync stuff - bool m_lipSyncActive; /// True iff we're currently lip syncing - int m_lipSyncAnim; /// The number of the animation that we are lipsyncing to - int m_lipSyncEndTimer; /// Time at which to stop lip syncing - - /** Call the script function DrawWeapon (in a new thread) if it exists */ - void DrawWeapon(); - /** Call the script function SheathWeapon (in a new thread) if it exists */ - void SheathWeapon(); - - // angua: this is used to check whether the AI is able to unlock a specific door - bool CanUnlock(CBinaryFrobMover *frobMover); - - // angua: this checks whether the AI should close the door after passing through - bool ShouldCloseDoor(CBinaryFrobMover *frobMover); - - // greebo: Contains all the checks for CVAR-dependent debug info - void ShowDebugInfo(); - - const idStr& GetNextIdleAnim(); - void SetNextIdleAnim(const idStr& nextIdleAnim); - - // grayman #2603 - work with the list of delayed visual stims - - void SetDelayedStimExpiration(idEntityPtr stimPtr); - int GetDelayedStimExpiration(idEntityPtr stimPtr); - - // - // ai/ai_events.cpp - // - // The post-spawn event parses the spawnargs which refer to other entities - // that might not be available at spawn time. - void Event_PostSpawn(); - void Event_Activate( idEntity *activator ); - -/***** -* DarkMod: Event_Touch was modified to issue a tactile alert. -* -* Note: Event_Touch checks ReactionTo, which checks our DarkMod Relations. -* So it will only go off if the AI is bumped by an enemy that moves into it. -* This is NOT called when an AI moves into an enemy. -* -* AI bumping by inanimate objects is handled separately by CheckTactile. -****/ - void Event_Touch( idEntity *other, trace_t *trace ); - - void Event_FindEnemy( int useFOV ); - void Event_FindEnemyAI( int useFOV ); - void Event_FindEnemyInCombatNodes( void ); - - /** - * greebo: Finds the nearest friendly and visible AI. Used to look for allies. - * The argument is optional and can be used to limit the search to a given team. - * Set to -1 to disable the team search. - * - * Returns the best candidate (can be the nullentity) to the script thread. - */ - void Event_FindFriendlyAI(int requiredTeam); - - void Event_ClosestReachableEnemyOfEntity( idEntity *team_mate ); - void Event_HeardSound( int ignore_team ); - void Event_SetEnemy( idEntity *ent ); - void Event_ClearEnemy( void ); - void Event_FoundBody( idEntity *body ); - void Event_MuzzleFlash( const char *jointname ); - void Event_CreateMissile( const char *jointname ); - void Event_CreateMissileFromDef(const char* defName, const char* jointname); - void Event_AttackMissile( const char *jointname ); - void Event_FireMissileAtTarget( const char *jointname, const char *targetname ); - void Event_LaunchMissile( const idVec3 &muzzle, const idAngles &ang ); - void Event_AttackMelee( const char *meleeDefName ); - void Event_DirectDamage( idEntity *damageTarget, const char *damageDefName ); - void Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName ); - void Event_BeginAttack( const char *name ); - void Event_EndAttack( void ); - void Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName ); - void Event_RandomPath( void ); - void Event_CanBecomeSolid( void ); - void Event_BecomeSolid( void ); - void Event_BecomeNonSolid( void ); - void Event_BecomeRagdoll( void ); - void Event_StopRagdoll( void ); - void Event_AllowDamage( void ); - void Event_IgnoreDamage( void ); - void Event_GetCurrentYaw( void ); - void Event_TurnTo( float angle ); - void Event_TurnToPos( const idVec3 &pos ); - void Event_TurnToEntity( idEntity *ent ); - void Event_MoveStatus( void ); - void Event_StopMove( void ); - void Event_MoveToCover( void ); - void Event_MoveToCoverFrom( idEntity *enemyEnt ); - void Event_MoveToEnemy( void ); - void Event_MoveToEnemyHeight( void ); - void Event_MoveOutOfRange( idEntity *entity, float range ); - void Event_Flee(idEntity* entityToFleeFrom, int algorithm, int distanceOption); - void Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim ); - void Event_MoveToEntity( idEntity *ent ); - void Event_MoveToPosition( const idVec3 &pos ); - void Event_SlideTo( const idVec3 &pos, float time ); - void Event_Wander( void ); - void Event_FacingIdeal( void ); - void Event_FaceEnemy( void ); - void Event_FaceEntity( idEntity *ent ); - void Event_WaitAction( const char *waitForState ); - void Event_GetCombatNode( void ); - void Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location ); - void Event_WaitMove( void ); - void Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ); - void Event_EntityInAttackCone( idEntity *ent ); - void Event_CanSeeEntity( idEntity *ent ); - void Event_CanSeeEntityExt( idEntity *ent, const int useFOV, const int useLighting); - void Event_IsEntityHidden( idEntity *ent, const float sightThreshold); - void Event_CanSeePositionExt( const idVec3& position, int useFOV, int useLighting); - void Event_SetTalkTarget( idEntity *target ); - void Event_GetTalkTarget( void ); - void Event_SetTalkState( int state ); - void Event_EnemyRange( void ); - void Event_EnemyRange2D( void ); - void Event_GetEnemy( void ); - void Event_GetEnemyPos( void ); - void Event_GetEnemyEyePos( void ); - void Event_PredictEnemyPos( float time ); - void Event_CanHitEnemy( void ); - void Event_CanHitEnemyFromAnim( const char *animname ); - void Event_CanHitEnemyFromJoint( const char *jointname ); - void Event_EnemyPositionValid( void ); - void Event_ChargeAttack( const char *damageDef ); - void Event_TestChargeAttack( void ); - void Event_TestAnimMoveTowardEnemy( const char *animname ); - void Event_TestAnimMove( const char *animname ); - void Event_TestMoveToPosition( const idVec3 &position ); - void Event_TestMeleeAttack( void ); - void Event_TestAnimAttack( const char *animname ); - void Event_Shrivel( float shirvel_time ); - void Event_Burn( void ); - void Event_PreBurn( void ); - void Event_ClearBurn( void ); - void Event_SetSmokeVisibility( int num, int on ); - void Event_NumSmokeEmitters( void ); - void Event_StopThinking( void ); - void Event_GetTurnDelta( void ); - void Event_GetMoveType( void ); - void Event_SetMoveType( int moveType ); - void Event_SaveMove( void ); - void Event_RestoreMove( void ); - void Event_AllowMovement( float flag ); - void Event_JumpFrame( void ); - void Event_EnableClip( void ); - void Event_DisableClip( void ); - void Event_EnableGravity( void ); - void Event_DisableGravity( void ); - void Event_EnableAFPush( void ); - void Event_DisableAFPush( void ); - void Event_SetFlySpeed( float speed ); - void Event_SetFlyOffset( int offset ); - void Event_ClearFlyOffset( void ); - void Event_GetClosestHiddenTarget( const char *type ); - void Event_GetRandomTarget( const char *type ); - void Event_TravelDistanceToPoint( const idVec3 &pos ); - void Event_TravelDistanceToEntity( idEntity *ent ); - void Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest ); - void Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest ); - void Event_LookAtEntity( idEntity *ent, float duration ); - void Event_LookAtEnemy( float duration ); - void Event_LookAtPosition (const idVec3& lookAtWorldPosition, float duration); - void Event_LookAtAngles (float yawAngleClockwise, float pitchAngleUp, float rollAngle, float durationInSeconds); - void Event_SetJointMod( int allowJointMod ); - void Event_ThrowMoveable( void ); - void Event_ThrowAF( void ); - void Event_SetAngles( idAngles const &ang ); - void Event_GetAngles( void ); - void Event_RealKill( void ); - void Event_Kill( void ); - void Event_WakeOnFlashlight( int enable ); - void Event_LocateEnemy( void ); - void Event_KickObstacles( idEntity *kickEnt, float force ); - void Event_GetObstacle( void ); - void Event_PushPointIntoAAS( const idVec3 &pos ); - void Event_GetTurnRate( void ); - void Event_SetTurnRate( float rate ); - void Event_AnimTurn( float angles ); - void Event_AllowHiddenMovement( int enable ); - void Event_TriggerParticles( const char *jointName ); - void Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs ); - void Event_CanReachPosition( const idVec3 &pos ); - void Event_CanReachEntity( idEntity *ent ); - void Event_CanReachEnemy( void ); - void Event_GetReachableEntityPosition( idEntity *ent ); - void Event_ReEvaluateArea(int areanum); - - // Script interface for state manipulation - void Event_PushState(const char* state); - void Event_SwitchState(const char* state); - void Event_EndState(); - - void Event_PlayAndLipSync( const char *soundName, const char *animName ); - - /** - * Frontend scripting functions for Dark Mod Relations Manager - * See CRelations class definition for descriptions - **/ - void Event_GetRelationEnt( idEntity *ent ); - - void Event_SetAlertLevel( float newAlertLevel ); - - /** - * Script frontend for idAI::GetAcuity and idAI::SetAcuity - * and idAI::AlertAI - **/ - void Event_Alert( const char *type, float amount ); - void Event_GetAcuity( const char *type ); - void Event_SetAcuity( const char *type, float val ); - void Event_GetAudThresh( void ); - void Event_SetAudThresh( float val ); - - /** - * Get the actor that alerted the AI this frame - **/ - void Event_GetAlertActor( void ); - - /** - * Set an alert grace period - * First argument is the fraction of the current alert this frame to ignore - * Second argument is the number of SECONDS the grace period lasts. - * Third argument is the number of events it takes to override the grace period - **/ - void Event_SetAlertGracePeriod( float frac, float duration, int count ); - - /** - * Script frontend for DarkMod hiding spot detection functions - **/ - void Event_StartSearchForHidingSpots (const idVec3& hideFromLocation, const idVec3 &minBounds, const idVec3 &maxBounds, int hidingSpotTypesAllowed, idEntity* p_ignoreEntity); - void Event_StartSearchForHidingSpotsWithExclusionArea (const idVec3& hideFromLocation, const idVec3 &minBounds, const idVec3 &maxBounds, const idVec3 &exclusionMinBounds, const idVec3 &exclusionMaxBounds, int hidingSpotTypesAllowed, idEntity* p_ignoreEntity); - void Event_ContinueSearchForHidingSpots(); - void Event_CloseHidingSpotSearch (); - void Event_ResortHidingSpots ( const idVec3& searchCenter, const idVec3& searchRadius); - void Event_GetNumHidingSpots (); - void Event_GetNthHidingSpotLocation (int hidingSpotIndex); - void Event_GetNthHidingSpotType (int hidingSpotIndex); - void Event_GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne ); - void Event_GetSomeOfOtherEntitiesHidingSpotList (idEntity* p_ownerOfSearch); - - /** - * Gets the alert number of an entity that is another AI. - * Will return 0.0 to script if other entity is NULL or not an AI. - */ - void Event_GetAlertLevelOfOtherAI (idEntity* p_otherEntity); - - void Event_ProcessBlindStim(idEntity* stimSource, int skipVisibilityCheck); - /** - * greebo: Script event for processing a visual stim coming from the entity - */ - void Event_ProcessVisualStim(idEntity* stimSource); - - /*! - * Spawns a new stone projectile that the AI can throw - * - * @param pstr_projectileName Name of the projectile type to - * be spawned (as given in .def file) - * - * @param pstr_jointName Name of the model joint to which the - * stone projectile will be bound until thrown. - */ - void Event_SpawnThrowableProjectile ( const char* pstr_projectileName, const char* pstr_jointName ); - - /** - * Scan for the player in FOV, and cause a visual alert if found - * Currently only checks the player. - * Will return the entity that caused the visual alert for - * scripting purposes. - **/ - void Event_VisScan( void ); - - /** - * Return the last suspicious sound direction - **/ - void Event_GetSndDir( void ); - - /** - * Return the last visual alert position - **/ - void Event_GetVisDir( void ); - - /** - * Return the entity that the AI is in tactile contact with - **/ - void Event_GetTactEnt( void ); - - /** - * This is needed for accurate AI-AI combat - * It just calls the vanilla D3 event: - * Event_ClosestReachableEnemyToEntity( idEntity *ent ) - * with the "this" pointer. - * - * For some reason this was left out of D3. - **/ - void Event_ClosestReachableEnemy( void ); - - // Scripts query this to retrieve the name of the next idle anim - void Event_GetNextIdleAnim(); - - void Event_HasSeenEvidence(); - - // grayman #2603 - relighting lights - void Event_PerformRelight(); - - // grayman #2603 - drop torch - void Event_DropTorch(); - -#ifdef TIMING_BUILD -private: - int aiThinkTimer; - int aiMindTimer; - int aiAnimationTimer; - int aiPushWithAFTimer; - int aiUpdateEnemyPositionTimer; - int aiScriptTimer; - int aiAnimMoveTimer; - int aiObstacleAvoidanceTimer; - int aiPhysicsTimer; - int aiGetMovePosTimer; - int aiPathToGoalTimer; - int aiGetFloorPosTimer; - int aiPointReachableAreaNumTimer; - int aiCanSeeTimer; - - -#endif -}; - -class idCombatNode : public idEntity { -public: - CLASS_PROTOTYPE( idCombatNode ); - - idCombatNode(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - bool IsDisabled( void ) const; - bool EntityInView( idActor *actor, const idVec3 &pos ); - static void DrawDebugInfo( void ); - -private: - float min_dist; - float max_dist; - float cone_dist; - float min_height; - float max_height; - idVec3 cone_left; - idVec3 cone_right; - idVec3 offset; - bool disabled; - - void Event_Activate( idEntity *activator ); - void Event_MarkUsed( void ); -}; - -#endif /* !__AI_H__ */ diff --git a/game/ai/ai_events.cpp b/game/ai/ai_events.cpp deleted file mode 100644 index c99345bb1..000000000 --- a/game/ai/ai_events.cpp +++ /dev/null @@ -1,3486 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/Relations.h" -#include "../../DarkMod/DarkModGlobals.h" -#include "../../DarkMod/DarkmodAASHidingSpotFinder.h" -#include "../../DarkMod/StimResponse/StimResponseCollection.h" -#include "../../DarkMod/AbsenceMarker.h" -#include "../../DarkMod/AI/Memory.h" -#include "../../DarkMod/AI/States/State.h" - -#include -#include -#include -#include - -class CRelations; - -/*********************************************************************** - - AI Events - -***********************************************************************/ - -const idEventDef AI_FindEnemy( "findEnemy", "d", 'e' ); -const idEventDef AI_FindEnemyAI( "findEnemyAI", "d", 'e' ); -const idEventDef AI_FindEnemyInCombatNodes( "findEnemyInCombatNodes", NULL, 'e' ); -const idEventDef AI_ClosestReachableEnemyOfEntity( "closestReachableEnemyOfEntity", "E", 'e' ); -// greebo: TDM Event: Try to find a visible AI of the given team -const idEventDef AI_FindFriendlyAI( "findFriendlyAI", "d", 'e' ); -const idEventDef AI_ProcessBlindStim( "processBlindStim", "ed" ); -const idEventDef AI_ProcessVisualStim("processVisualStim", "e"); -const idEventDef AI_PerformRelight("performRelight"); // grayman #2603 -const idEventDef AI_DropTorch("dropTorch"); // grayman #2603 - -const idEventDef AI_SetEnemy( "setEnemy", "E" ); -const idEventDef AI_ClearEnemy( "clearEnemy" ); -const idEventDef AI_MuzzleFlash( "muzzleFlash", "s" ); -const idEventDef AI_CreateMissile( "createMissile", "s", 'e' ); -const idEventDef AI_CreateMissileFromDef( "createMissileFromDef", "ss", 'e' ); // arg1 = def name, arg2 = joint name -const idEventDef AI_AttackMissile( "attackMissile", "s", 'e' ); -const idEventDef AI_FireMissileAtTarget( "fireMissileAtTarget", "ss", 'e' ); -const idEventDef AI_LaunchMissile( "launchMissile", "vv", 'e' ); -const idEventDef AI_AttackMelee( "attackMelee", "s", 'd' ); -const idEventDef AI_DirectDamage( "directDamage", "es" ); -const idEventDef AI_RadiusDamageFromJoint( "radiusDamageFromJoint", "ss" ); -const idEventDef AI_BeginAttack( "attackBegin", "s" ); -const idEventDef AI_EndAttack( "attackEnd" ); -const idEventDef AI_MeleeAttackToJoint( "meleeAttackToJoint", "ss", 'd' ); -const idEventDef AI_RandomPath( "randomPath", NULL, 'e' ); -const idEventDef AI_CanBecomeSolid( "canBecomeSolid", NULL, 'f' ); -const idEventDef AI_BecomeSolid( "becomeSolid" ); -const idEventDef AI_BecomeRagdoll( "becomeRagdoll", NULL, 'd' ); -const idEventDef AI_StopRagdoll( "stopRagdoll" ); -const idEventDef AI_AllowDamage( "allowDamage" ); -const idEventDef AI_IgnoreDamage( "ignoreDamage" ); -const idEventDef AI_GetCurrentYaw( "getCurrentYaw", NULL, 'f' ); -const idEventDef AI_TurnTo( "turnTo", "f" ); -const idEventDef AI_TurnToPos( "turnToPos", "v" ); -const idEventDef AI_TurnToEntity( "turnToEntity", "E" ); -const idEventDef AI_MoveStatus( "moveStatus", NULL, 'd' ); -const idEventDef AI_StopMove( "stopMove" ); -const idEventDef AI_MoveToCover( "moveToCover" ); -const idEventDef AI_MoveToCoverFrom( "moveToCoverFrom", "E" ); -const idEventDef AI_MoveToEnemy( "moveToEnemy" ); -const idEventDef AI_MoveToEnemyHeight( "moveToEnemyHeight" ); -const idEventDef AI_MoveOutOfRange( "moveOutOfRange", "ef" ); -// greebo: Flee from an entity -const idEventDef AI_Flee( "flee", "edd", 'd' ); -const idEventDef AI_MoveToAttackPosition( "moveToAttackPosition", "es" ); -const idEventDef AI_Wander( "wander" ); -const idEventDef AI_MoveToEntity( "moveToEntity", "e" ); -const idEventDef AI_MoveToPosition( "moveToPosition", "v" ); -const idEventDef AI_SlideTo( "slideTo", "vf" ); -const idEventDef AI_FacingIdeal( "facingIdeal", NULL, 'd' ); -const idEventDef AI_FaceEnemy( "faceEnemy" ); -const idEventDef AI_FaceEntity( "faceEntity", "E" ); -const idEventDef AI_GetCombatNode( "getCombatNode", NULL, 'e' ); -const idEventDef AI_EnemyInCombatCone( "enemyInCombatCone", "Ed", 'd' ); -const idEventDef AI_WaitMove( "waitMove" ); -const idEventDef AI_GetJumpVelocity( "getJumpVelocity", "vff", 'v' ); -const idEventDef AI_EntityInAttackCone( "entityInAttackCone", "E", 'd' ); -const idEventDef AI_CanSeeEntity( "canSee", "E", 'd' ); -const idEventDef AI_CanSeeEntityExt( "canSeeExt", "Edd", 'd' ); -const idEventDef AI_CanSeePositionExt( "canSeePositionExt", "vdd", 'd' ); -const idEventDef AI_IsEntityHidden( "isEntityHidden", "Ed", 'd' ); -const idEventDef AI_SetTalkTarget( "setTalkTarget", "E" ); -const idEventDef AI_GetTalkTarget( "getTalkTarget", NULL, 'e' ); -const idEventDef AI_SetTalkState( "setTalkState", "d" ); -const idEventDef AI_EnemyRange( "enemyRange", NULL, 'f' ); -const idEventDef AI_EnemyRange2D( "enemyRange2D", NULL, 'f' ); -const idEventDef AI_GetEnemy( "getEnemy", NULL, 'e' ); -const idEventDef AI_GetEnemyPos( "getEnemyPos", NULL, 'v' ); -const idEventDef AI_GetEnemyEyePos( "getEnemyEyePos", NULL, 'v' ); -const idEventDef AI_PredictEnemyPos( "predictEnemyPos", "f", 'v' ); -const idEventDef AI_CanHitEnemy( "canHitEnemy", NULL, 'd' ); -const idEventDef AI_CanHitEnemyFromAnim( "canHitEnemyFromAnim", "s", 'd' ); -const idEventDef AI_CanHitEnemyFromJoint( "canHitEnemyFromJoint", "s", 'd' ); -const idEventDef AI_EnemyPositionValid( "enemyPositionValid", NULL, 'd' ); -const idEventDef AI_ChargeAttack( "chargeAttack", "s" ); -const idEventDef AI_TestChargeAttack( "testChargeAttack", NULL, 'f' ); -const idEventDef AI_TestMoveToPosition( "testMoveToPosition", "v", 'd' ); -const idEventDef AI_TestAnimMoveTowardEnemy( "testAnimMoveTowardEnemy", "s", 'd' ); -const idEventDef AI_TestAnimMove( "testAnimMove", "s", 'd' ); -const idEventDef AI_TestMeleeAttack( "testMeleeAttack", NULL, 'd' ); -const idEventDef AI_TestAnimAttack( "testAnimAttack", "s", 'd' ); -const idEventDef AI_Shrivel( "shrivel", "f" ); -const idEventDef AI_Burn( "burn" ); -const idEventDef AI_ClearBurn( "clearBurn" ); -const idEventDef AI_PreBurn( "preBurn" ); -const idEventDef AI_SetSmokeVisibility( "setSmokeVisibility", "dd" ); -const idEventDef AI_NumSmokeEmitters( "numSmokeEmitters", NULL, 'd' ); -const idEventDef AI_WaitAction( "waitAction", "s" ); -const idEventDef AI_StopThinking( "stopThinking" ); -const idEventDef AI_GetTurnDelta( "getTurnDelta", NULL, 'f' ); -const idEventDef AI_GetMoveType( "getMoveType", NULL, 'd' ); -const idEventDef AI_SetMoveType( "setMoveType", "d" ); -const idEventDef AI_SaveMove( "saveMove" ); -const idEventDef AI_RestoreMove( "restoreMove" ); -const idEventDef AI_AllowMovement( "allowMovement", "f" ); -const idEventDef AI_JumpFrame( "" ); -const idEventDef AI_EnableClip( "enableClip" ); -const idEventDef AI_DisableClip( "disableClip" ); -const idEventDef AI_EnableGravity( "enableGravity" ); -const idEventDef AI_DisableGravity( "disableGravity" ); -const idEventDef AI_EnableAFPush( "enableAFPush" ); -const idEventDef AI_DisableAFPush( "disableAFPush" ); -const idEventDef AI_SetFlySpeed( "setFlySpeed", "f" ); -const idEventDef AI_SetFlyOffset( "setFlyOffset", "d" ); -const idEventDef AI_ClearFlyOffset( "clearFlyOffset" ); -const idEventDef AI_GetClosestHiddenTarget( "getClosestHiddenTarget", "s", 'e' ); -const idEventDef AI_GetRandomTarget( "getRandomTarget", "s", 'e' ); -const idEventDef AI_TravelDistanceToPoint( "travelDistanceToPoint", "v", 'f' ); -const idEventDef AI_TravelDistanceToEntity( "travelDistanceToEntity", "e", 'f' ); -const idEventDef AI_TravelDistanceBetweenPoints( "travelDistanceBetweenPoints", "vv", 'f' ); -const idEventDef AI_TravelDistanceBetweenEntities( "travelDistanceBetweenEntities", "ee", 'f' ); -const idEventDef AI_LookAtEntity( "lookAt", "Ef" ); -const idEventDef AI_LookAtEnemy( "lookAtEnemy", "f" ); -const idEventDef AI_SetJointMod( "setBoneMod", "d" ); -const idEventDef AI_ThrowMoveable( "throwMoveable" ); -const idEventDef AI_ThrowAF( "throwAF" ); -const idEventDef AI_RealKill( "" ); -const idEventDef AI_Kill( "kill" ); -const idEventDef AI_WakeOnFlashlight( "wakeOnFlashlight", "d" ); -const idEventDef AI_LocateEnemy( "locateEnemy" ); -const idEventDef AI_KickObstacles( "kickObstacles", "Ef" ); -const idEventDef AI_GetObstacle( "getObstacle", NULL, 'e' ); -const idEventDef AI_PushPointIntoAAS( "pushPointIntoAAS", "v", 'v' ); -const idEventDef AI_GetTurnRate( "getTurnRate", NULL, 'f' ); -const idEventDef AI_SetTurnRate( "setTurnRate", "f" ); -const idEventDef AI_AnimTurn( "animTurn", "f" ); -const idEventDef AI_AllowHiddenMovement( "allowHiddenMovement", "d" ); -const idEventDef AI_TriggerParticles( "triggerParticles", "s" ); -const idEventDef AI_FindActorsInBounds( "findActorsInBounds", "vv", 'e' ); -const idEventDef AI_CanReachPosition( "canReachPosition", "v", 'd' ); -const idEventDef AI_CanReachEntity( "canReachEntity", "E", 'd' ); -const idEventDef AI_CanReachEnemy( "canReachEnemy", NULL, 'd' ); -const idEventDef AI_GetReachableEntityPosition( "getReachableEntityPosition", "e", 'v' ); -const idEventDef AI_ReEvaluateArea("reEvaluateArea", "d"); - -// TDM -const idEventDef AI_PlayAndLipSync( "playAndLipSync", "ss", 'd' ); - -const idEventDef AI_PushState("pushState", "s"); -const idEventDef AI_SwitchState("switchState", "s"); -const idEventDef AI_EndState("endState", NULL, 'd'); - -// DarkMod AI Relations Events -const idEventDef AI_GetRelationEnt( "getRelationEnt", "E", 'd' ); -const idEventDef AI_IsEnemy( "isEnemy", "E", 'd' ); -const idEventDef AI_IsFriend( "isFriend", "E", 'd' ); -const idEventDef AI_IsNeutral( "isNeutral", "E", 'd' ); - -// Alert events -const idEventDef AI_SetAlertLevel( "setAlertLevel", "f" ); -const idEventDef AI_Alert( "alert", "sf" ); -const idEventDef AI_VisScan( "visScan", NULL, 'e' ); -const idEventDef AI_GetSndDir( "getSndDir", NULL, 'v' ); -const idEventDef AI_GetVisDir( "getVisDir", NULL, 'v' ); -const idEventDef AI_GetTactEnt( "getTactEnt", NULL, 'e'); -const idEventDef AI_SetAcuity( "setAcuity", "sf" ); -const idEventDef AI_GetAcuity( "getAcuity", "s", 'f' ); -const idEventDef AI_GetAudThresh( "getAudThresh", NULL, 'f' ); -const idEventDef AI_SetAudThresh( "setAudThresh", "f" ); -const idEventDef AI_GetAlertActor( "getAlertActor", NULL, 'e' ); -const idEventDef AI_SetAlertGracePeriod( "setAlertGracePeriod", "fff" ); -const idEventDef AI_ClosestReachableEnemy( "closestReachableEnemy", NULL, 'e' ); -const idEventDef AI_FoundBody( "foundBody", "e" ); - -/*! -* A look at event that just looks at a position in space -* -* @param lookAtWorldPosition The position in space to look at -* -* @param durationInSeconds The duration to look in seconds -*/ -const idEventDef AI_LookAtPosition ("lookAtPosition", "vf"); - -/*! -* A look at event that just looks at a set of angles relative -* to the current body facing of the AI -* -* @param yawAngleClockwise Negative angles are to the left of the AIs body -* and positive angles are to the right. -* -* @param pitchAngleUp Negative values are down and positive values are up -* where down and up are defined by the body axis. -* -* @param rollAngle This is currently unused and does nothing -* -* @param durationInSeconds The duration to look in seconds -* -*/ -const idEventDef AI_LookAtAngles ("lookAtAngles", "ffff"); - - -/*! -* script callable: spawnThrowableProjectile -* -* @param projectileName The name of the projectile to spawn -* (as seen in a .def file) Must be descended from idProjectile -* -* @param pstr_attachJointName The name of the joint on the model -* to which the particle should be attached for throwing. If this -* is NULL or the empty string, then it is attached to the model center. -* -* @returns a pointer to a projectile entity that can be -* thrown by the AI. You can use AI_LaunchMissle (e* = launchMissle(v,v) ) -* to throw the stone. -* -*/ -const idEventDef AI_SpawnThrowableProjectile ("spawnThrowableProjectile", "ss", 'e'); - -// DarkMod Hiding spot detection Events -/*! -* This event finds hiding spots in the bounds given by two vectors. -* -* The first paramter is a vector which gives the location of the -* eye from which hiding is desired. -* -* The second vector gives the minimums in each dimension for the -* search space. -* -* The third and fourth vectors give the min and max bounds within which spots should be tested -* -* The fifth parameter gives the bit flags of the types of hiding spots -* for which the search should look. -* -* The sixth parameter indicates an entity that should be ignored in -* the visual occlusion checks. This is usually the searcher itself but -* can be NULL. -* -* This method will only start the search, if it returns 1, you should call -* continueSearchForHidingSpots every frame to do more processing until that function -* returns 0. -* -* The return value is a 0 for failure, 1 for success. -*/ -const idEventDef AI_StartSearchForHidingSpots ("startSearchForHidingSpots", "vvvdE", 'd'); - -// Documentation see idAI::StartSearchForHidingSpotsWithExclusionArea -const idEventDef AI_StartSearchForHidingSpotsWithExclusionArea ("startSearchForHidingSpotsWithExclusionArea", "vvvvvdE", 'd'); - -/* -* This method continues searching for hiding spots. It will only find so many before -* returning so as not to cause long delays. Detected spots are added to the currently -* building hiding spot list. -* -* The return value is 0 if the end of the search was reached, or 1 if there -* is more processing to do (call this method again next AI frame) -* -*/ -const idEventDef AI_ContinueSearchForHidingSpots ("continueSearchForHidingSpots", NULL, 'd'); - -/*! -* This should be called when the script is done with the hiding spot -* search to free up memory. -*/ -const idEventDef AI_CloseHidingSpotSearch ("closeHidingSpotSearch", ""); - -/*! -* This re-sorts an existing search based on a new search center and radius. -* -* @param newCenter The new center of the search -* -* @param newRadius The new radius of the search. Points outside the original -* search will not be added. -* -*/ -const idEventDef AI_ResortHidingSpotSearch ("resortHidingSpotSearch", "vv"); - -/*! -* This event returns the number of hiding spots by the current -* hiding spot query. If there is no current query, this returns -1 -*/ -const idEventDef AI_GetNumHidingSpots ("getNumHidingSpots", "", 'd'); - -/*! -* This event returns the Nth hiding spot location. -* Param is 0 based hiding spot index -*/ -const idEventDef AI_GetNthHidingSpotLocation ("getNthHidingSpotLocation", "d", 'v'); - -/*! -* This event returns the Nth hiding spot type. -* Param is 0 based hiding spot index -*/ -const idEventDef AI_GetNthHidingSpotType ("getNthHidingSpotType", "d", 'd'); - -/*! -* This event splits off half of the hiding spot list of another entity -* and sets our hiding spot list to the "taken" points. -* -* As such, it is useful for getting hiding spots from a seraching AI that this -* AI is trying to assist. -* -* @param p_otherEntity The other entity who's hiding spots we are taking -* -* @return The number of points in the list gotten -*/ -const idEventDef AI_GetSomeOfOtherEntitiesHidingSpotList ("getSomeOfOtherEntitiesHidingSpotList", "e", 'd'); - -/*! -* This event gets the alert number of another AI (AI_AlertLevel variable value) -* -* @param p_otherEntity The other AI entity who's alert number is being querried -* -* @return The alert number of the other AI, 0.0 if its not an AI or is NULL -*/ -const idEventDef AI_GetAlertLevelOfOtherAI ("getAlertLevelOfOtherAI", "e", 'f'); - -/*! -* This event is used to get a position that the AI can move to observe a -* given position. It is useful for looking at hiding spots that can't be reached, -* and performing other investigation functions. -*/ -const idEventDef AI_GetObservationPosition ("getObservationPosition", "vf", 'v'); - -/** -* These events handle a knockout of the AI (takes the attacker as argument) -**/ -const idEventDef AI_KO_Knockout( "KO_Knockout", "E" ); // grayman #2468 -const idEventDef AI_Gas_Knockout( "Gas_Knockout", "E" ); // grayman #2468 - -const idEventDef AI_GetNextIdleAnim( "getNextIdleAnim", NULL, 's' ); - -const idEventDef AI_HasSeenEvidence( "hasSeenEvidence", NULL, 'd' ); - -/* -* This is the AI event table class for a generic NPC actor. -* -*/ -CLASS_DECLARATION( idActor, idAI ) - EVENT( EV_PostSpawn, idAI::Event_PostSpawn ) - EVENT( EV_Activate, idAI::Event_Activate ) - EVENT( EV_Touch, idAI::Event_Touch ) - EVENT( AI_FindEnemy, idAI::Event_FindEnemy ) - EVENT( AI_FindEnemyAI, idAI::Event_FindEnemyAI ) - EVENT( AI_FindEnemyInCombatNodes, idAI::Event_FindEnemyInCombatNodes ) - EVENT( AI_ClosestReachableEnemyOfEntity, idAI::Event_ClosestReachableEnemyOfEntity ) - EVENT( AI_FindFriendlyAI, idAI::Event_FindFriendlyAI ) - EVENT( AI_ProcessBlindStim, idAI::Event_ProcessBlindStim ) - EVENT( AI_ProcessVisualStim, idAI::Event_ProcessVisualStim ) - EVENT( AI_SetEnemy, idAI::Event_SetEnemy ) - EVENT( AI_ClearEnemy, idAI::Event_ClearEnemy ) - EVENT( AI_MuzzleFlash, idAI::Event_MuzzleFlash ) - EVENT( AI_CreateMissile, idAI::Event_CreateMissile ) - EVENT( AI_CreateMissileFromDef, idAI::Event_CreateMissileFromDef ) - EVENT( AI_AttackMissile, idAI::Event_AttackMissile ) - EVENT( AI_FireMissileAtTarget, idAI::Event_FireMissileAtTarget ) - EVENT( AI_LaunchMissile, idAI::Event_LaunchMissile ) - EVENT( AI_AttackMelee, idAI::Event_AttackMelee ) - EVENT( AI_DirectDamage, idAI::Event_DirectDamage ) - EVENT( AI_RadiusDamageFromJoint, idAI::Event_RadiusDamageFromJoint ) - EVENT( AI_BeginAttack, idAI::Event_BeginAttack ) - EVENT( AI_EndAttack, idAI::Event_EndAttack ) - EVENT( AI_MeleeAttackToJoint, idAI::Event_MeleeAttackToJoint ) - EVENT( AI_RandomPath, idAI::Event_RandomPath ) - EVENT( AI_CanBecomeSolid, idAI::Event_CanBecomeSolid ) - EVENT( AI_BecomeSolid, idAI::Event_BecomeSolid ) - EVENT( EV_BecomeNonSolid, idAI::Event_BecomeNonSolid ) - EVENT( AI_BecomeRagdoll, idAI::Event_BecomeRagdoll ) - EVENT( AI_StopRagdoll, idAI::Event_StopRagdoll ) - EVENT( AI_AllowDamage, idAI::Event_AllowDamage ) - EVENT( AI_IgnoreDamage, idAI::Event_IgnoreDamage ) - EVENT( AI_GetCurrentYaw, idAI::Event_GetCurrentYaw ) - EVENT( AI_TurnTo, idAI::Event_TurnTo ) - EVENT( AI_TurnToPos, idAI::Event_TurnToPos ) - EVENT( AI_TurnToEntity, idAI::Event_TurnToEntity ) - EVENT( AI_MoveStatus, idAI::Event_MoveStatus ) - EVENT( AI_StopMove, idAI::Event_StopMove ) - EVENT( AI_MoveToCover, idAI::Event_MoveToCover ) - EVENT( AI_MoveToCoverFrom, idAI::Event_MoveToCoverFrom ) - EVENT( AI_MoveToEnemy, idAI::Event_MoveToEnemy ) - EVENT( AI_MoveToEnemyHeight, idAI::Event_MoveToEnemyHeight ) - EVENT( AI_MoveOutOfRange, idAI::Event_MoveOutOfRange ) - EVENT( AI_Flee, idAI::Event_Flee ) - EVENT( AI_MoveToAttackPosition, idAI::Event_MoveToAttackPosition ) - EVENT( AI_Wander, idAI::Event_Wander ) - EVENT( AI_MoveToEntity, idAI::Event_MoveToEntity ) - EVENT( AI_MoveToPosition, idAI::Event_MoveToPosition ) - EVENT( AI_SlideTo, idAI::Event_SlideTo ) - EVENT( AI_FacingIdeal, idAI::Event_FacingIdeal ) - EVENT( AI_FaceEnemy, idAI::Event_FaceEnemy ) - EVENT( AI_FaceEntity, idAI::Event_FaceEntity ) - EVENT( AI_WaitAction, idAI::Event_WaitAction ) - EVENT( AI_GetCombatNode, idAI::Event_GetCombatNode ) - EVENT( AI_EnemyInCombatCone, idAI::Event_EnemyInCombatCone ) - EVENT( AI_WaitMove, idAI::Event_WaitMove ) - EVENT( AI_GetJumpVelocity, idAI::Event_GetJumpVelocity ) - EVENT( AI_EntityInAttackCone, idAI::Event_EntityInAttackCone ) - EVENT( AI_CanSeeEntity, idAI::Event_CanSeeEntity ) - EVENT( AI_CanSeeEntityExt, idAI::Event_CanSeeEntityExt ) - EVENT( AI_CanSeePositionExt, idAI::Event_CanSeePositionExt ) - EVENT( AI_IsEntityHidden, idAI::Event_IsEntityHidden ) - EVENT( AI_SetTalkTarget, idAI::Event_SetTalkTarget ) - EVENT( AI_GetTalkTarget, idAI::Event_GetTalkTarget ) - EVENT( AI_SetTalkState, idAI::Event_SetTalkState ) - EVENT( AI_EnemyRange, idAI::Event_EnemyRange ) - EVENT( AI_EnemyRange2D, idAI::Event_EnemyRange2D ) - EVENT( AI_GetEnemy, idAI::Event_GetEnemy ) - EVENT( AI_GetEnemyPos, idAI::Event_GetEnemyPos ) - EVENT( AI_GetEnemyEyePos, idAI::Event_GetEnemyEyePos ) - EVENT( AI_PredictEnemyPos, idAI::Event_PredictEnemyPos ) - EVENT( AI_CanHitEnemy, idAI::Event_CanHitEnemy ) - EVENT( AI_CanHitEnemyFromAnim, idAI::Event_CanHitEnemyFromAnim ) - EVENT( AI_CanHitEnemyFromJoint, idAI::Event_CanHitEnemyFromJoint ) - EVENT( AI_EnemyPositionValid, idAI::Event_EnemyPositionValid ) - EVENT( AI_ChargeAttack, idAI::Event_ChargeAttack ) - EVENT( AI_TestChargeAttack, idAI::Event_TestChargeAttack ) - EVENT( AI_TestAnimMoveTowardEnemy, idAI::Event_TestAnimMoveTowardEnemy ) - EVENT( AI_TestAnimMove, idAI::Event_TestAnimMove ) - EVENT( AI_TestMoveToPosition, idAI::Event_TestMoveToPosition ) - EVENT( AI_TestMeleeAttack, idAI::Event_TestMeleeAttack ) - EVENT( AI_TestAnimAttack, idAI::Event_TestAnimAttack ) - EVENT( AI_Shrivel, idAI::Event_Shrivel ) - EVENT( AI_Burn, idAI::Event_Burn ) - EVENT( AI_PreBurn, idAI::Event_PreBurn ) - EVENT( AI_SetSmokeVisibility, idAI::Event_SetSmokeVisibility ) - EVENT( AI_NumSmokeEmitters, idAI::Event_NumSmokeEmitters ) - EVENT( AI_ClearBurn, idAI::Event_ClearBurn ) - EVENT( AI_StopThinking, idAI::Event_StopThinking ) - EVENT( AI_GetTurnDelta, idAI::Event_GetTurnDelta ) - EVENT( AI_GetMoveType, idAI::Event_GetMoveType ) - EVENT( AI_SetMoveType, idAI::Event_SetMoveType ) - EVENT( AI_SaveMove, idAI::Event_SaveMove ) - EVENT( AI_RestoreMove, idAI::Event_RestoreMove ) - EVENT( AI_AllowMovement, idAI::Event_AllowMovement ) - EVENT( AI_JumpFrame, idAI::Event_JumpFrame ) - EVENT( AI_EnableClip, idAI::Event_EnableClip ) - EVENT( AI_DisableClip, idAI::Event_DisableClip ) - EVENT( AI_EnableGravity, idAI::Event_EnableGravity ) - EVENT( AI_DisableGravity, idAI::Event_DisableGravity ) - EVENT( AI_EnableAFPush, idAI::Event_EnableAFPush ) - EVENT( AI_DisableAFPush, idAI::Event_DisableAFPush ) - EVENT( AI_SetFlySpeed, idAI::Event_SetFlySpeed ) - EVENT( AI_SetFlyOffset, idAI::Event_SetFlyOffset ) - EVENT( AI_ClearFlyOffset, idAI::Event_ClearFlyOffset ) - EVENT( AI_GetClosestHiddenTarget, idAI::Event_GetClosestHiddenTarget ) - EVENT( AI_GetRandomTarget, idAI::Event_GetRandomTarget ) - EVENT( AI_TravelDistanceToPoint, idAI::Event_TravelDistanceToPoint ) - EVENT( AI_TravelDistanceToEntity, idAI::Event_TravelDistanceToEntity ) - EVENT( AI_TravelDistanceBetweenPoints, idAI::Event_TravelDistanceBetweenPoints ) - EVENT( AI_TravelDistanceBetweenEntities, idAI::Event_TravelDistanceBetweenEntities ) - EVENT( AI_LookAtEntity, idAI::Event_LookAtEntity ) - EVENT( AI_LookAtEnemy, idAI::Event_LookAtEnemy ) - EVENT( AI_SetJointMod, idAI::Event_SetJointMod ) - EVENT( AI_ThrowMoveable, idAI::Event_ThrowMoveable ) - EVENT( AI_ThrowAF, idAI::Event_ThrowAF ) - EVENT( EV_GetAngles, idAI::Event_GetAngles ) - EVENT( EV_SetAngles, idAI::Event_SetAngles ) - EVENT( AI_RealKill, idAI::Event_RealKill ) - EVENT( AI_Kill, idAI::Event_Kill ) - EVENT( AI_WakeOnFlashlight, idAI::Event_WakeOnFlashlight ) - EVENT( AI_LocateEnemy, idAI::Event_LocateEnemy ) - EVENT( AI_KickObstacles, idAI::Event_KickObstacles ) - EVENT( AI_GetObstacle, idAI::Event_GetObstacle ) - EVENT( AI_PushPointIntoAAS, idAI::Event_PushPointIntoAAS ) - EVENT( AI_GetTurnRate, idAI::Event_GetTurnRate ) - EVENT( AI_SetTurnRate, idAI::Event_SetTurnRate ) - EVENT( AI_AnimTurn, idAI::Event_AnimTurn ) - EVENT( AI_AllowHiddenMovement, idAI::Event_AllowHiddenMovement ) - EVENT( AI_TriggerParticles, idAI::Event_TriggerParticles ) - EVENT( AI_FindActorsInBounds, idAI::Event_FindActorsInBounds ) - EVENT( AI_CanReachPosition, idAI::Event_CanReachPosition ) - EVENT( AI_CanReachEntity, idAI::Event_CanReachEntity ) - EVENT( AI_CanReachEnemy, idAI::Event_CanReachEnemy ) - EVENT( AI_GetReachableEntityPosition, idAI::Event_GetReachableEntityPosition ) - EVENT( AI_ReEvaluateArea, idAI::Event_ReEvaluateArea ) - - - // greebo: State manipulation interface - EVENT( AI_PushState, idAI::Event_PushState ) - EVENT( AI_SwitchState, idAI::Event_SwitchState ) - EVENT( AI_EndState, idAI::Event_EndState ) - - EVENT( AI_PlayAndLipSync, idAI::Event_PlayAndLipSync ) - EVENT( AI_GetRelationEnt, idAI::Event_GetRelationEnt ) - EVENT( AI_SetAlertLevel, idAI::Event_SetAlertLevel ) - EVENT( AI_Alert, idAI::Event_Alert ) - EVENT( AI_GetSndDir, idAI::Event_GetSndDir ) - EVENT( AI_GetVisDir, idAI::Event_GetVisDir ) - EVENT( AI_GetTactEnt, idAI::Event_GetTactEnt ) - EVENT( AI_SetAcuity, idAI::Event_SetAcuity ) - EVENT( AI_GetAcuity, idAI::Event_GetAcuity ) - EVENT( AI_GetAudThresh, idAI::Event_GetAudThresh ) - EVENT( AI_SetAudThresh, idAI::Event_SetAudThresh ) - EVENT( AI_VisScan, idAI::Event_VisScan ) - EVENT( AI_GetAlertActor, idAI::Event_GetAlertActor ) - EVENT( AI_SetAlertGracePeriod, idAI::Event_SetAlertGracePeriod ) - EVENT( AI_ClosestReachableEnemy, idAI::Event_ClosestReachableEnemy ) - EVENT( AI_FoundBody, idAI::Event_FoundBody ) - EVENT ( AI_StartSearchForHidingSpots, idAI::Event_StartSearchForHidingSpots ) - EVENT ( AI_StartSearchForHidingSpotsWithExclusionArea, idAI::Event_StartSearchForHidingSpotsWithExclusionArea ) - EVENT ( AI_ContinueSearchForHidingSpots, idAI::Event_ContinueSearchForHidingSpots ) - EVENT ( AI_CloseHidingSpotSearch, idAI::Event_CloseHidingSpotSearch ) - EVENT ( AI_ResortHidingSpotSearch, idAI::Event_ResortHidingSpots ) - EVENT ( AI_GetNumHidingSpots, idAI::Event_GetNumHidingSpots ) - EVENT ( AI_GetNthHidingSpotLocation, idAI::Event_GetNthHidingSpotLocation ) - EVENT ( AI_GetNthHidingSpotType, idAI::Event_GetNthHidingSpotType ) - EVENT ( AI_GetSomeOfOtherEntitiesHidingSpotList, idAI::Event_GetSomeOfOtherEntitiesHidingSpotList) - EVENT ( AI_GetObservationPosition, idAI::Event_GetObservationPosition) - EVENT ( AI_LookAtPosition, idAI::Event_LookAtPosition) - EVENT ( AI_LookAtAngles, idAI::Event_LookAtAngles) - EVENT ( AI_GetAlertLevelOfOtherAI, idAI::Event_GetAlertLevelOfOtherAI) - EVENT ( AI_KO_Knockout, idAI::Event_KO_Knockout) // grayman #2468 - EVENT ( AI_Gas_Knockout, idAI::Event_Gas_Knockout) // grayman #2468 - EVENT ( AI_SpawnThrowableProjectile, idAI::Event_SpawnThrowableProjectile) - EVENT ( AI_GetNextIdleAnim, idAI::Event_GetNextIdleAnim) - EVENT ( AI_HasSeenEvidence, idAI::Event_HasSeenEvidence) - - EVENT ( AI_PerformRelight, idAI::Event_PerformRelight) // grayman #2603 - EVENT ( AI_DropTorch, idAI::Event_DropTorch) // grayman #2603 - -END_CLASS - -void idAI::Event_PostSpawn() -{ - // Parse the list of doors that can be unlocked by this AI - for (const idKeyValue* kv = spawnArgs.MatchPrefix("can_unlock"); kv != NULL; kv = spawnArgs.MatchPrefix("can_unlock", kv)) - { - idEntity* door = gameLocal.FindEntity(kv->GetValue()); - if (door != NULL) - { - if (door->IsType(CBinaryFrobMover::Type)) - { - unlockableDoors.insert(static_cast(door)); - } - else - { - gameLocal.Warning("Invalid door name %s on AI %s", kv->GetValue().c_str(), name.c_str()); - } - } - } -} - -/* -===================== -idAI::Event_Activate -===================== -*/ -void idAI::Event_Activate( idEntity *activator ) { - Activate( activator ); -} - -/* -===================== -idAI::Event_Touch - -DarkMod: Modified to issue a tactile alert. - -Note: Event_Touch checks ReactionTo, which checks our DarkMod Relations -So it will only go off if the AI is bumped by an enemy that moves toward it. - -AI bumping by inanimate objects is handled separately in idMoveable::Collide. -===================== -*/ - -void idAI::Event_Touch( idEntity *other, trace_t *trace ) -{ - if ( !enemy.GetEntity() && !other->fl.notarget && ( ReactionTo( other ) & ATTACK_ON_ACTIVATE ) ) - { - Activate( other ); - } - AI_PUSHED = true; - - if( other && other->IsType(idActor::Type) ) - { - HadTactile( static_cast(other) ); - } -} - -/* -===================== -idAI::Event_FindEnemy -===================== -*/ -void idAI::Event_FindEnemy( int useFOV ) -{ - int i; - idEntity *ent; - idActor *actor; - - if ( gameLocal.InPlayerPVS( this ) ) { - for ( i = 0; i < gameLocal.numClients ; i++ ) { - ent = gameLocal.entities[ i ]; - - if ( !ent || !ent->IsType( idActor::Type ) ) { - continue; - } - - actor = static_cast( ent ); - - if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { - continue; - } - - if ( CanSee( actor, useFOV != 0 ) ) { - idThread::ReturnEntity( actor ); - return; - } - } - } - - idThread::ReturnEntity( NULL ); -} - -/* -===================== -idAI::Event_FindEnemyAI -===================== -*/ -void idAI::Event_FindEnemyAI( int useFOV ) { - idThread::ReturnEntity(FindEnemyAI(useFOV==1)); -} - -/* -===================== -idAI::Event_FindFriendlyAI -===================== -*/ -void idAI::Event_FindFriendlyAI(int requiredTeam) -{ - - idThread::ReturnEntity(FindFriendlyAI(requiredTeam)); -} - -/* -===================== -idAI::Event_FindEnemyInCombatNodes -===================== -*/ -void idAI::Event_FindEnemyInCombatNodes( void ) { - int i, j; - idCombatNode *node; - idEntity *ent; - idEntity *targetEnt; - idActor *actor; - - if ( !gameLocal.InPlayerPVS( this ) ) { - // don't locate the player when we're not in his PVS - idThread::ReturnEntity( NULL ); - return; - } - - for ( i = 0; i < gameLocal.numClients ; i++ ) { - ent = gameLocal.entities[ i ]; - - if ( !ent || !ent->IsType( idActor::Type ) ) { - continue; - } - - actor = static_cast( ent ); - if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) { - continue; - } - - for( j = 0; j < targets.Num(); j++ ) { - targetEnt = targets[ j ].GetEntity(); - if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) { - continue; - } - - node = static_cast( targetEnt ); - if ( !node->IsDisabled() && node->EntityInView( actor, actor->GetPhysics()->GetOrigin() ) ) { - idThread::ReturnEntity( actor ); - return; - } - } - } - - idThread::ReturnEntity( NULL ); -} - -/* -===================== -idAI::Event_ClosestReachableEnemyOfEntity -===================== -*/ -void idAI::Event_ClosestReachableEnemyOfEntity( idEntity *team_mate ) { - idActor *actor; - idActor *ent; - idActor *bestEnt; - float bestDistSquared; - float distSquared; - idVec3 delta; - int areaNum; - int enemyAreaNum; - aasPath_t path; - - if ( !team_mate->IsType( idActor::Type ) ) { - gameLocal.Error( "Entity '%s' is not an AI character or player", team_mate->GetName() ); - } - - actor = static_cast( team_mate ); - - const idVec3 &origin = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( origin ); - - bestDistSquared = idMath::INFINITY; - bestEnt = NULL; - for( ent = actor->enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - if ( ent->fl.hidden ) { - continue; - } - delta = ent->GetPhysics()->GetOrigin() - origin; - distSquared = delta.LengthSqr(); - if ( distSquared < bestDistSquared ) { - const idVec3 &enemyPos = ent->GetPhysics()->GetOrigin(); - enemyAreaNum = PointReachableAreaNum( enemyPos ); - if ( ( areaNum != 0 ) && PathToGoal( path, areaNum, origin, enemyAreaNum, enemyPos, this ) ) { - bestEnt = ent; - bestDistSquared = distSquared; - } - } - } - - idThread::ReturnEntity( bestEnt ); -} - -/* -===================== -idAI::Event_SetEnemy -===================== -*/ -void idAI::Event_SetEnemy( idEntity *ent ) { - if ( !ent ) { - ClearEnemy(); - } else if ( !ent->IsType( idActor::Type ) ) { - gameLocal.Error( "'%s' is not an idActor (player or ai controlled character)", ent->name.c_str() ); - } else { - SetEnemy( static_cast( ent ) ); - } -} - -/* -===================== -idAI::Event_ClearEnemy -===================== -*/ -void idAI::Event_ClearEnemy( void ) { - ClearEnemy(); -} - -/* -===================== -idAI::Event_MuzzleFlash -===================== -*/ -void idAI::Event_MuzzleFlash( const char *jointname ) -{ - idVec3 muzzle; - idMat3 axis; - - GetMuzzle( jointname, muzzle, axis ); - TriggerWeaponEffects( muzzle ); -} - -/* -===================== -idAI::Event_SpawnThrowableProjectile -===================== -*/ -void idAI::Event_SpawnThrowableProjectile(const char* projectileName, const char* jointName) -{ - // Remove the currently active projectile if necessary - RemoveProjectile(); - - // Load definition from movable.def - const idDict* projectileDef = gameLocal.FindEntityDefDict(projectileName); - - if (!projectileDef) - { - DM_LOG(LC_AI, LT_WARNING)LOGSTRING("Projectile with name '%s' was not found\r", projectileName); - idThread::ReturnEntity(NULL); - } - - // Create the projectile - idVec3 projectileDir = viewAxis[ 0 ] * physicsObj.GetGravityAxis(); - idVec3 projectileOrigin = physicsObj.GetOrigin(); - - // Spawn a new active projectile from the given dictionary (will throw gameLocal.Error on failure) - CreateProjectileFromDict(projectileOrigin, projectileDir, projectileDef); - - // Ensure that the clip model - EnsureActiveProjectileInfo(); - - // Bind to joint - if (jointName == NULL || jointName[0] == NULL) - { - // No valid joint name - activeProjectile.projEnt.GetEntity()->Bind(this, true); - } - else - { - activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointName, true); - } - - // Return to script thread - idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); -} - -/* -===================== -idAI::Event_CreateMissile -===================== -*/ -void idAI::Event_CreateMissile( const char *jointname ) -{ - if (projectileInfo.Num() == 0) - { - gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() ); - idThread::ReturnEntity( NULL ); - - return; - } - - idVec3 muzzle; - idMat3 axis; - GetMuzzle(jointname, muzzle, axis); - - // Create a new random projectile - CreateProjectile(muzzle, viewAxis[0] * physicsObj.GetGravityAxis()); - - if (activeProjectile.projEnt.GetEntity()) - { - if (!jointname || !jointname[ 0 ]) - { - activeProjectile.projEnt.GetEntity()->Bind(this, true); - } - else - { - activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointname, true); - } - } - - idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); -} - -void idAI::Event_CreateMissileFromDef(const char* defName, const char *jointname) -{ - // Remove any other projectile if we have one - RemoveProjectile(); - - // Load definition from movable.def - const idDict* projectileDef = gameLocal.FindEntityDefDict(defName); - - if (!projectileDef) - { - DM_LOG(LC_AI, LT_WARNING)LOGSTRING("Projectile with name '%s' was not found\r", defName); - idThread::ReturnEntity(NULL); - } - - idVec3 muzzle; - idMat3 axis; - GetMuzzle(jointname, muzzle, axis); - - // Create a new named projectile - CreateProjectileFromDict(muzzle, viewAxis[0] * physicsObj.GetGravityAxis(), projectileDef); - - if (activeProjectile.projEnt.GetEntity()) - { - if (!jointname || !jointname[ 0 ]) - { - activeProjectile.projEnt.GetEntity()->Bind(this, true); - } - else - { - activeProjectile.projEnt.GetEntity()->BindToJoint(this, jointname, true); - } - } - - idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); -} - -/* -===================== -idAI::Event_AttackMissile -===================== -*/ -void idAI::Event_AttackMissile( const char *jointname ) { - idProjectile *proj; - - proj = LaunchProjectile( jointname, enemy.GetEntity(), true ); - idThread::ReturnEntity( proj ); -} - -/* -===================== -idAI::Event_FireMissileAtTarget -===================== -*/ -void idAI::Event_FireMissileAtTarget( const char *jointname, const char *targetname ) { - idEntity *aent; - idProjectile *proj; - - aent = gameLocal.FindEntity( targetname ); - if ( !aent ) { - gameLocal.Warning( "Entity '%s' not found for 'fireMissileAtTarget'", targetname ); - } - - proj = LaunchProjectile( jointname, aent, false ); - idThread::ReturnEntity( proj ); -} - -/* -===================== -idAI::Event_LaunchMissile -===================== -*/ -void idAI::Event_LaunchMissile(const idVec3& org, const idAngles& ang) -{ - if (projectileInfo.Num() == 0) - { - gameLocal.Warning("%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName()); - idThread::ReturnEntity(NULL); - return; - } - - idMat3 axis = ang.ToMat3(); - - // Ensure we have a projectile (does nothing if active projectile is non-NULL) - CreateProjectile(org, axis[0]); - - // make sure the projectile starts inside the monster bounding box - const idBounds &ownerBounds = physicsObj.GetAbsBounds(); - - const idClipModel* projClip = activeProjectile.projEnt.GetEntity()->GetPhysics()->GetClipModel(); - idBounds projBounds = projClip->GetBounds().Rotate(projClip->GetAxis()); - - idVec3 start; - float distance; - - // check if the owner bounds is bigger than the projectile bounds - if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && - ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && - ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) - { - if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) - { - start = org + distance * viewAxis[ 0 ]; - } - else - { - start = ownerBounds.GetCenter(); - } - } - else - { - // projectile bounds bigger than the owner bounds, so just start it from the center - start = ownerBounds.GetCenter(); - } - - trace_t tr; - gameLocal.clip.Translation( tr, start, org, projClip, projClip->GetAxis(), MASK_SHOT_RENDERMODEL, this ); - - // launch the projectile - idThread::ReturnEntity(activeProjectile.projEnt.GetEntity()); - - // greebo: Launch and free our projectile slot to get ready for the next round - activeProjectile.projEnt.GetEntity()->Launch( tr.endpos, axis[ 0 ], vec3_origin ); - activeProjectile.projEnt = NULL; - - TriggerWeaponEffects(tr.endpos); - - lastAttackTime = gameLocal.time; -} - -/* -===================== -idAI::Event_AttackMelee -===================== -*/ -void idAI::Event_AttackMelee( const char *meleeDefName ) { - bool hit; - - hit = AttackMelee( meleeDefName ); - idThread::ReturnInt( hit ); -} - -/* -===================== -idAI::Event_DirectDamage -===================== -*/ -void idAI::Event_DirectDamage( idEntity *damageTarget, const char *damageDefName ) { - DirectDamage( damageDefName, damageTarget ); -} - -/* -===================== -idAI::Event_RadiusDamageFromJoint -===================== -*/ -void idAI::Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName ) { - jointHandle_t joint; - idVec3 org; - idMat3 axis; - - if ( !jointname || !jointname[ 0 ] ) { - org = physicsObj.GetOrigin(); - } else { - joint = animator.GetJointHandle( jointname ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); - } - GetJointWorldTransform( joint, gameLocal.time, org, axis ); - } - - gameLocal.RadiusDamage( org, this, this, this, this, damageDefName ); -} - -/* -===================== -idAI::Event_RandomPath -===================== -*/ -void idAI::Event_RandomPath( void ) { - idPathCorner *path; - - path = idPathCorner::RandomPath( this, NULL, NULL ); - idThread::ReturnEntity( path ); -} - -/* -===================== -idAI::Event_BeginAttack -===================== -*/ -void idAI::Event_BeginAttack( const char *name ) { - BeginAttack( name ); -} - -/* -===================== -idAI::Event_EndAttack -===================== -*/ -void idAI::Event_EndAttack( void ) { - EndAttack(); -} - -/* -===================== -idAI::Event_MeleeAttackToJoint -===================== -*/ -void idAI::Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName ) { - jointHandle_t joint; - idVec3 start; - idVec3 end; - idMat3 axis; - trace_t trace; - idEntity *hitEnt; - - joint = animator.GetJointHandle( jointname ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); - } - animator.GetJointTransform( joint, gameLocal.time, end, axis ); - end = physicsObj.GetOrigin() + ( end + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); - start = GetEyePosition(); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorYellow, start, end, gameLocal.msec ); - } - - gameLocal.clip.TranslationEntities( trace, start, end, NULL, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); - if ( trace.fraction < 1.0f ) { - hitEnt = gameLocal.GetTraceEntity( trace ); - if ( hitEnt && hitEnt->IsType( idActor::Type ) ) { - DirectDamage( meleeDefName, hitEnt ); - idThread::ReturnInt( true ); - return; - } - } - - idThread::ReturnInt( false ); -} - -/* -===================== -idAI::Event_CanBecomeSolid -===================== -*/ -void idAI::Event_CanBecomeSolid( void ) { - idThread::ReturnFloat( CanBecomeSolid() ); -} - -/* -===================== -idAI::Event_BecomeSolid -===================== -*/ -void idAI::Event_BecomeSolid( void ) { - physicsObj.EnableClip(); - if ( spawnArgs.GetBool( "big_monster" ) ) { - physicsObj.SetContents( 0 ); - } else if ( use_combat_bbox ) { - physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); - } else { - physicsObj.SetContents( CONTENTS_BODY ); - } - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - physicsObj.GetClipModel()->Link( gameLocal.clip ); - fl.takedamage = !spawnArgs.GetBool( "noDamage" ); -} - -/* -===================== -idAI::Event_BecomeNonSolid -===================== -*/ -void idAI::Event_BecomeNonSolid( void ) { - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.GetClipModel()->Unlink(); -} - -/* -===================== -idAI::Event_BecomeRagdoll -===================== -*/ -void idAI::Event_BecomeRagdoll( void ) { - bool result; - - result = StartRagdoll(); - idThread::ReturnInt( result ); -} - -/* -===================== -idAI::Event_StopRagdoll -===================== -*/ -void idAI::Event_StopRagdoll( void ) { - StopRagdoll(); - - // set back the monster physics - SetPhysics( &physicsObj ); -} - -/* -===================== -idAI::Event_AllowDamage -===================== -*/ -void idAI::Event_AllowDamage( void ) { - fl.takedamage = true; -} - -/* -===================== -idAI::Event_IgnoreDamage -===================== -*/ -void idAI::Event_IgnoreDamage( void ) { - fl.takedamage = false; -} - -/* -===================== -idAI::Event_GetCurrentYaw -===================== -*/ -void idAI::Event_GetCurrentYaw( void ) { - idThread::ReturnFloat( current_yaw ); -} - -/* -===================== -idAI::Event_TurnTo -===================== -*/ -void idAI::Event_TurnTo( float angle ) { - TurnToward( angle ); -} - -/* -===================== -idAI::Event_TurnToPos -===================== -*/ -void idAI::Event_TurnToPos( const idVec3 &pos ) { - TurnToward( pos ); -} - -/* -===================== -idAI::Event_TurnToEntity -===================== -*/ -void idAI::Event_TurnToEntity( idEntity *ent ) { - if ( ent ) { - TurnToward( ent->GetPhysics()->GetOrigin() ); - } -} - -/* -===================== -idAI::Event_MoveStatus -===================== -*/ -void idAI::Event_MoveStatus( void ) { - idThread::ReturnInt( move.moveStatus ); -} - -/* -===================== -idAI::Event_StopMove -===================== -*/ -void idAI::Event_StopMove( void ) { - StopMove( MOVE_STATUS_DONE ); -} - -/* -===================== -idAI::Event_MoveToCover -===================== -*/ -void idAI::Event_MoveToCover( void ) { - idActor *enemyEnt = enemy.GetEntity(); - if (!enemyEnt) common->Printf("Warning: Entity is null\n"); - - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - if ( !enemyEnt || !MoveToCover( enemyEnt, lastVisibleEnemyPos ) ) { - return; - } -} - -/* -===================== -idAI::Event_MoveToCoverFrom -===================== -*/ -void idAI::Event_MoveToCoverFrom( idEntity* enemyEnt ) { - if (!enemyEnt) enemyEnt = enemy.GetEntity(); - if (!enemyEnt) { common->Printf("Warning: Entity is null\n"); return; } - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - - // Hide from the eye position of the enemy, if the enemy is an actor; - // otherwise we have to make do with its origin plus an offset. - idVec3 hideFrom; - if (dynamic_cast (enemyEnt)) { - hideFrom = static_cast (enemyEnt)->GetEyePosition(); - } else { - hideFrom = enemyEnt->GetPhysics()->GetOrigin(); - hideFrom.z += 96.0f; // about 6 feet - } - - if (!MoveToCover( enemyEnt, hideFrom )) { - // failed - return; - } -} - -/* -===================== -idAI::Event_MoveToEnemy -===================== -*/ -void idAI::Event_MoveToEnemy( void ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - if ( !enemy.GetEntity() || !MoveToEnemy() ) { - return; - } -} - -/* -===================== -idAI::Event_MoveToEnemyHeight -===================== -*/ -void idAI::Event_MoveToEnemyHeight( void ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - MoveToEnemyHeight(); -} - -/* -===================== -idAI::Event_MoveOutOfRange -===================== -*/ -void idAI::Event_MoveOutOfRange( idEntity *entity, float range ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - MoveOutOfRange( entity, range ); -} - -/* -===================== -idAI::Event_Flee -===================== -*/ -void idAI::Event_Flee(idEntity *entityToFleeFrom, int algorithm, int distanceOption) { - StopMove(MOVE_STATUS_DEST_NOT_FOUND); - idThread::ReturnInt(Flee(entityToFleeFrom, algorithm, distanceOption)); -} - -/* -===================== -idAI::Event_GetObservationPosition -by SophisticatedZobmie for The Dark Mod -This is an adaptation of the find attack position -query that is within MoveToAttackPosition -===================== -*/ -void idAI::Event_GetObservationPosition (const idVec3& pointToObserve, const float visualAcuityZeroToOne) -{ - idVec3 observeFromPos = GetObservationPosition(pointToObserve, visualAcuityZeroToOne); - idThread::ReturnVector (observeFromPos); - return; -} - -/* -===================== -idAI::Event_MoveToAttackPosition -===================== -*/ -void idAI::Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim ) { - int anim; - - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - - anim = GetAnim( ANIMCHANNEL_LEGS, attack_anim ); - if ( !anim ) { - gameLocal.Error( "Unknown anim '%s'", attack_anim ); - } - - MoveToAttackPosition( entity, anim ); -} - -/* -===================== -idAI::Event_MoveToEntity -===================== -*/ -void idAI::Event_MoveToEntity( idEntity *ent ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - if ( ent ) { - MoveToEntity( ent ); - } -} - -/* -===================== -idAI::Event_MoveToPosition -===================== -*/ -void idAI::Event_MoveToPosition( const idVec3 &pos ) { - StopMove( MOVE_STATUS_DONE ); - MoveToPosition( pos ); -} - -/* -===================== -idAI::Event_SlideTo -===================== -*/ -void idAI::Event_SlideTo( const idVec3 &pos, float time ) { - SlideToPosition( pos, time ); -} -/* -===================== -idAI::Event_Wander -===================== -*/ -void idAI::Event_Wander( void ) { - WanderAround(); -} - -/* -===================== -idAI::Event_FacingIdeal -===================== -*/ -void idAI::Event_FacingIdeal( void ) { - bool facing = FacingIdeal(); - idThread::ReturnInt( facing ); -} - -/* -===================== -idAI::Event_FaceEnemy -===================== -*/ -void idAI::Event_FaceEnemy( void ) { - FaceEnemy(); -} - -/* -===================== -idAI::Event_FaceEntity -===================== -*/ -void idAI::Event_FaceEntity( idEntity *ent ) { - FaceEntity( ent ); -} - -/* -===================== -idAI::Event_WaitAction -===================== -*/ -void idAI::Event_WaitAction( const char *waitForState ) { - if ( idThread::BeginMultiFrameEvent( this, &AI_WaitAction ) ) { - SetWaitState( waitForState ); - } - - if ( !WaitState() ) { - idThread::EndMultiFrameEvent( this, &AI_WaitAction ); - } -} - -/* -===================== -idAI::Event_GetCombatNode -===================== -*/ -void idAI::Event_GetCombatNode( void ) { - int i; - float dist; - idEntity *targetEnt; - idCombatNode *node; - float bestDist; - idCombatNode *bestNode; - idActor *enemyEnt = enemy.GetEntity(); - - if ( !targets.Num() ) { - // no combat nodes - idThread::ReturnEntity( NULL ); - return; - } - - if ( !enemyEnt || !EnemyPositionValid() ) { - // don't return a combat node if we don't have an enemy or - // if we can see he's not in the last place we saw him - idThread::ReturnEntity( NULL ); - return; - } - - // find the closest attack node that can see our enemy and is closer than our enemy - bestNode = NULL; - const idVec3 &myPos = physicsObj.GetOrigin(); - bestDist = ( myPos - lastVisibleEnemyPos ).LengthSqr(); - for( i = 0; i < targets.Num(); i++ ) { - targetEnt = targets[ i ].GetEntity(); - if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) { - continue; - } - - node = static_cast( targetEnt ); - if ( !node->IsDisabled() && node->EntityInView( enemyEnt, lastVisibleEnemyPos ) ) { - idVec3 org = node->GetPhysics()->GetOrigin(); - dist = ( myPos - org ).LengthSqr(); - if ( dist < bestDist ) { - bestNode = node; - bestDist = dist; - } - } - } - - idThread::ReturnEntity( bestNode ); -} - -/* -===================== -idAI::Event_EnemyInCombatCone -===================== -*/ -void idAI::Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location ) { - idCombatNode *node; - bool result; - idActor *enemyEnt = enemy.GetEntity(); - - if ( !targets.Num() ) { - // no combat nodes - idThread::ReturnInt( false ); - return; - } - - if ( !enemyEnt ) { - // have to have an enemy - idThread::ReturnInt( false ); - return; - } - - if ( !ent || !ent->IsType( idCombatNode::Type ) ) { - // not a combat node - idThread::ReturnInt( false ); - return; - } - - node = static_cast( ent ); - if ( use_current_enemy_location ) { - const idVec3 &pos = enemyEnt->GetPhysics()->GetOrigin(); - result = node->EntityInView( enemyEnt, pos ); - } else { - result = node->EntityInView( enemyEnt, lastVisibleEnemyPos ); - } - - idThread::ReturnInt( result ); -} - -/* -===================== -idAI::Event_WaitMove -===================== -*/ -void idAI::Event_WaitMove( void ) { - idThread::BeginMultiFrameEvent( this, &AI_WaitMove ); - - if ( MoveDone() ) { - idThread::EndMultiFrameEvent( this, &AI_WaitMove ); - } -} - -/* -===================== -idAI::Event_GetJumpVelocity -===================== -*/ -void idAI::Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ) { - idVec3 start; - idVec3 end; - idVec3 dir; - float dist; - bool result; - idEntity *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt ) { - idThread::ReturnVector( vec3_zero ); - return; - } - - if ( speed <= 0.0f ) { - gameLocal.Error( "Invalid speed. speed must be > 0." ); - } - - start = physicsObj.GetOrigin(); - end = pos; - dir = end - start; - dist = dir.Normalize(); - if ( dist > 16.0f ) { - dist -= 16.0f; - end -= dir * 16.0f; - } - - result = PredictTrajectory( start, end, speed, physicsObj.GetGravity(), physicsObj.GetClipModel(), MASK_MONSTERSOLID, max_height, this, enemyEnt, ai_debugMove.GetBool() ? 4000 : 0, dir ); - if ( result ) { - idThread::ReturnVector( dir * speed ); - } else { - idThread::ReturnVector( vec3_zero ); - } -} - -/* -===================== -idAI::Event_EntityInAttackCone -===================== -*/ -void idAI::Event_EntityInAttackCone( idEntity *ent ) { - idThread::ReturnInt( EntityInAttackCone(ent) ); -} - -/* -===================== -idAI::Event_CanSeeEntity -===================== -*/ -void idAI::Event_CanSeeEntity( idEntity *ent ) { - if ( !ent ) { - idThread::ReturnInt( false ); - return; - } - - // Test if it is occluded, and use field of vision in the check (true as second parameter) - bool cansee = CanSee( ent, true ); - - idThread::ReturnInt( cansee ); -} - -/* -===================== -idAI::Event_CanSeeEntityExt -===================== -*/ -void idAI::Event_CanSeeEntityExt( idEntity *ent, const int bool_useFOV, const int bool_useLighting ) -{ - - if ( !ent ) - { - idThread::ReturnInt( false ); - return; - } - - // Test if it is visible - bool cansee = CanSeeExt( ent, (bool_useFOV != 0), (bool_useLighting != 0) ); - - // Return result - idThread::ReturnInt( cansee ); -} - -/* -===================== -idAI::Event_IsEntityHidden - -Tels: Returns true if the entity is in the FOV, not occluded and lit up according to the threshold. -===================== -*/ -void idAI::Event_IsEntityHidden( idEntity *ent, const float sightThreshold ) -{ - - if ( !ent ) - { - idThread::ReturnInt( false ); - return; - } - - // Test if it is occluded, and use field of vision in the check (true as second parameter) - bool cansee = idActor::CanSee( ent, true ); - - // Also consider lighting and visual acuity of AI - if (cansee) - { - cansee = !IsEntityHiddenByDarkness(ent, sightThreshold); - } - - // Return result - idThread::ReturnInt( cansee ); -} - -/* -===================== -idAI::Event_CanSeePositionExt -===================== -*/ -void idAI::Event_CanSeePositionExt( const idVec3& position, int bool_useFOV, int bool_useLighting ) -{ - bool cansee = CanSeePositionExt( position, (bool_useFOV != 0), (bool_useLighting != 0) ); - idThread::ReturnInt( cansee ); -} - - -/* -===================== -idAI::Event_SetTalkTarget -===================== -*/ -void idAI::Event_SetTalkTarget( idEntity *target ) { - if ( target && !target->IsType( idActor::Type ) ) { - gameLocal.Error( "Cannot set talk target to '%s'. Not a character or player.", target->GetName() ); - } - talkTarget = static_cast( target ); - if ( target ) { - AI_TALK = true; - } else { - AI_TALK = false; - } -} - -/* -===================== -idAI::Event_GetTalkTarget -===================== -*/ -void idAI::Event_GetTalkTarget( void ) { - idThread::ReturnEntity( talkTarget.GetEntity() ); -} - -/* -================ -idAI::Event_SetTalkState -================ -*/ -void idAI::Event_SetTalkState( int state ) { - if ( ( state < 0 ) || ( state >= NUM_TALK_STATES ) ) { - gameLocal.Error( "Invalid talk state (%d)", state ); - } - - talk_state = static_cast( state ); -} - -/* -===================== -idAI::Event_EnemyRange -===================== -*/ -void idAI::Event_EnemyRange( void ) { - float dist; - idActor *enemyEnt = enemy.GetEntity(); - - if ( enemyEnt ) { - dist = ( enemyEnt->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).Length(); - } else { - // Just some really high number - dist = idMath::INFINITY; - } - - idThread::ReturnFloat( dist ); -} - -/* -===================== -idAI::Event_EnemyRange2D -===================== -*/ -void idAI::Event_EnemyRange2D( void ) { - float dist; - idActor *enemyEnt = enemy.GetEntity(); - - if ( enemyEnt ) { - dist = ( enemyEnt->GetPhysics()->GetOrigin().ToVec2() - GetPhysics()->GetOrigin().ToVec2() ).Length(); - } else { - // Just some really high number - dist = idMath::INFINITY; - } - - idThread::ReturnFloat( dist ); -} - -/* -===================== -idAI::Event_GetEnemy -===================== -*/ -void idAI::Event_GetEnemy( void ) { - idThread::ReturnEntity( enemy.GetEntity() ); -} - -/* -===================== -idAI::Event_GetEnemyPos -===================== -*/ -void idAI::Event_GetEnemyPos( void ) { - idThread::ReturnVector( lastVisibleEnemyPos ); -} - -/* -===================== -idAI::Event_GetEnemyEyePos -===================== -*/ -void idAI::Event_GetEnemyEyePos( void ) { - idThread::ReturnVector( lastVisibleEnemyPos + lastVisibleEnemyEyeOffset ); -} - -/* -===================== -idAI::Event_PredictEnemyPos -===================== -*/ -void idAI::Event_PredictEnemyPos( float time ) { - predictedPath_t path; - idActor *enemyEnt = enemy.GetEntity(); - - // if no enemy set - if ( !enemyEnt ) { - idThread::ReturnVector( physicsObj.GetOrigin() ); - return; - } - - // predict the enemy movement - idAI::PredictPath( enemyEnt, aas, lastVisibleEnemyPos, enemyEnt->GetPhysics()->GetLinearVelocity(), SEC2MS( time ), SEC2MS( time ), ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - idThread::ReturnVector( path.endPos ); -} - -/* -===================== -idAI::Event_CanHitEnemy -===================== -*/ -void idAI::Event_CanHitEnemy( void ) { - trace_t tr; - idEntity *hit; - - idActor *enemyEnt = enemy.GetEntity(); - if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { - idThread::ReturnInt( false ); - return; - } - - // don't check twice per frame - if ( gameLocal.time == lastHitCheckTime ) { - idThread::ReturnInt( lastHitCheckResult ); - return; - } - - lastHitCheckTime = gameLocal.time; - - idVec3 toPos = enemyEnt->GetEyePosition(); - idVec3 eye = GetEyePosition(); - idVec3 dir; - - // expand the ray out as far as possible so we can detect anything behind the enemy - dir = toPos - eye; - dir.Normalize(); - toPos = eye + dir * MAX_WORLD_SIZE; - gameLocal.clip.TracePoint( tr, eye, toPos, MASK_SHOT_BOUNDINGBOX, this ); - hit = gameLocal.GetTraceEntity( tr ); - if ( tr.fraction >= 1.0f || ( hit == enemyEnt ) ) { - lastHitCheckResult = true; - } else if ( ( tr.fraction < 1.0f ) && ( hit->IsType( idAI::Type ) ) && - ( static_cast( hit )->team != team ) ) { - lastHitCheckResult = true; - } else { - lastHitCheckResult = false; - } - - idThread::ReturnInt( lastHitCheckResult ); -} - -/* -===================== -idAI::Event_CanHitEnemyFromAnim -===================== -*/ -void idAI::Event_CanHitEnemyFromAnim( const char *animname ) { - int anim; - idVec3 dir; - idVec3 local_dir; - idVec3 fromPos; - idMat3 axis; - idVec3 start; - trace_t tr; - float distance; - - idActor *enemyEnt = enemy.GetEntity(); - if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { - idThread::ReturnInt( false ); - return; - } - - anim = GetAnim( ANIMCHANNEL_LEGS, animname ); - if ( !anim ) { - idThread::ReturnInt( false ); - return; - } - - // just do a ray test if close enough - if ( enemyEnt->GetPhysics()->GetAbsBounds().IntersectsBounds( physicsObj.GetAbsBounds().Expand( 16.0f ) ) ) { - Event_CanHitEnemy(); - return; - } - - // calculate the world transform of the launch position - const idVec3 &org = physicsObj.GetOrigin(); - dir = lastVisibleEnemyPos - org; - physicsObj.GetGravityAxis().ProjectVector( dir, local_dir ); - local_dir.z = 0.0f; - local_dir.ToVec2().Normalize(); - axis = local_dir.ToMat3(); - fromPos = physicsObj.GetOrigin() + missileLaunchOffset[ anim ] * axis; - - // Ensure we have a valid clipmodel - ProjectileInfo& info = EnsureActiveProjectileInfo(); - - // check if the owner bounds is bigger than the projectile bounds - const idBounds& ownerBounds = physicsObj.GetAbsBounds(); - const idBounds& projBounds = info.clipModel->GetBounds(); - if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && - ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && - ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { - if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) { - start = org + distance * viewAxis[ 0 ]; - } else { - start = ownerBounds.GetCenter(); - } - } else { - // projectile bounds bigger than the owner bounds, so just start it from the center - start = ownerBounds.GetCenter(); - } - - gameLocal.clip.Translation( tr, start, fromPos, info.clipModel, mat3_identity, MASK_SHOT_RENDERMODEL, this ); - fromPos = tr.endpos; - - if ( GetAimDir( fromPos, enemy.GetEntity(), this, dir ) ) { - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/* -===================== -idAI::Event_CanHitEnemyFromJoint -===================== -*/ -void idAI::Event_CanHitEnemyFromJoint( const char *jointname ) { - trace_t tr; - idVec3 muzzle; - idMat3 axis; - idVec3 start; - float distance; - - idActor *enemyEnt = enemy.GetEntity(); - if ( !AI_ENEMY_VISIBLE || !enemyEnt ) { - idThread::ReturnInt( false ); - return; - } - - // don't check twice per frame - if ( gameLocal.time == lastHitCheckTime ) { - idThread::ReturnInt( lastHitCheckResult ); - return; - } - - lastHitCheckTime = gameLocal.time; - - const idVec3 &org = physicsObj.GetOrigin(); - idVec3 toPos = enemyEnt->GetEyePosition(); - jointHandle_t joint = animator.GetJointHandle( jointname ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); - } - animator.GetJointTransform( joint, gameLocal.time, muzzle, axis ); - muzzle = org + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); - - // Ensure the current projectile clipmodel is valid - ProjectileInfo& curProjInfo = EnsureActiveProjectileInfo(); - - // check if the owner bounds is bigger than the projectile bounds - const idBounds &ownerBounds = physicsObj.GetAbsBounds(); - const idBounds &projBounds = curProjInfo.clipModel->GetBounds(); - if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && - ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && - ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { - if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) { - start = org + distance * viewAxis[ 0 ]; - } else { - start = ownerBounds.GetCenter(); - } - } else { - // projectile bounds bigger than the owner bounds, so just start it from the center - start = ownerBounds.GetCenter(); - } - - gameLocal.clip.Translation( tr, start, muzzle, curProjInfo.clipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); - muzzle = tr.endpos; - - gameLocal.clip.Translation( tr, muzzle, toPos, curProjInfo.clipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this ); - if ( tr.fraction >= 1.0f || ( gameLocal.GetTraceEntity( tr ) == enemyEnt ) ) { - lastHitCheckResult = true; - } else { - lastHitCheckResult = false; - } - - idThread::ReturnInt( lastHitCheckResult ); -} - -/* -===================== -idAI::Event_EnemyPositionValid -===================== -*/ -void idAI::Event_EnemyPositionValid( void ) { - bool result; - - result = EnemyPositionValid(); - idThread::ReturnInt( result ); -} - -/* -===================== -idAI::Event_ChargeAttack -===================== -*/ -void idAI::Event_ChargeAttack( const char *damageDef ) { - idActor *enemyEnt = enemy.GetEntity(); - - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); - if ( enemyEnt ) { - idVec3 enemyOrg; - - if ( move.moveType == MOVETYPE_FLY ) { - // position destination so that we're in the enemy's view - enemyOrg = enemyEnt->GetEyePosition(); - enemyOrg -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset; - } else { - enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); - } - - BeginAttack( damageDef ); - DirectMoveToPosition( enemyOrg ); - TurnToward( enemyOrg ); - } -} - -/* -===================== -idAI::Event_TestChargeAttack -===================== -*/ -void idAI::Event_TestChargeAttack( void ) { - trace_t trace; - idActor *enemyEnt = enemy.GetEntity(); - predictedPath_t path; - idVec3 end; - - if ( !enemyEnt ) { - idThread::ReturnFloat( 0.0f ); - return; - } - - if ( move.moveType == MOVETYPE_FLY ) { - // position destination so that we're in the enemy's view - end = enemyEnt->GetEyePosition(); - end -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset; - } else { - end = enemyEnt->GetPhysics()->GetOrigin(); - } - - idAI::PredictPath( this, aas, physicsObj.GetOrigin(), end - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), end, gameLocal.msec ); - gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), end, gameLocal.msec ); - } - - if ( ( path.endEvent == 0 ) || ( path.blockingEntity == enemyEnt ) ) { - idVec3 delta = end - physicsObj.GetOrigin(); - float time = delta.LengthFast(); - idThread::ReturnFloat( time ); - } else { - idThread::ReturnFloat( 0.0f ); - } -} - -/* -===================== -idAI::Event_TestAnimMoveTowardEnemy -===================== -*/ -void idAI::Event_TestAnimMoveTowardEnemy( const char *animname ) { - int anim; - predictedPath_t path; - idVec3 moveVec; - float yaw; - idVec3 delta; - idActor *enemyEnt; - - enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - idThread::ReturnInt( false ); - return; - } - - anim = GetAnim( ANIMCHANNEL_LEGS, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); -#endif - - idThread::ReturnInt( false ); - return; - } - - delta = enemyEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin(); - yaw = delta.ToYaw(); - - moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis(); - idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); - gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); - } - - idThread::ReturnInt( path.endEvent == 0 ); -} - -/* -===================== -idAI::Event_TestAnimMove -===================== -*/ -void idAI::Event_TestAnimMove( const char *animname ) { - int anim; - predictedPath_t path; - idVec3 moveVec; - - anim = GetAnim( ANIMCHANNEL_LEGS, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); -#endif - - idThread::ReturnInt( false ); - return; - } - - moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, ideal_yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis(); - idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); - gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec ); - } - - idThread::ReturnInt( path.endEvent == 0 ); -} - -/* -===================== -idAI::Event_TestMoveToPosition -===================== -*/ -void idAI::Event_TestMoveToPosition( const idVec3 &position ) { - predictedPath_t path; - - idAI::PredictPath( this, aas, physicsObj.GetOrigin(), position - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), position, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorYellow, physicsObj.GetBounds(), position, gameLocal.msec ); - if ( path.endEvent ) { - gameRenderWorld->DebugBounds( colorRed, physicsObj.GetBounds(), path.endPos, gameLocal.msec ); - } - } - - idThread::ReturnInt( path.endEvent == 0 ); -} - -/* -===================== -idAI::Event_TestMeleeAttack -===================== -*/ -void idAI::Event_TestMeleeAttack( void ) { - bool result = TestMelee(); - idThread::ReturnInt( result ); -} - -/* -===================== -idAI::Event_TestAnimAttack -===================== -*/ -void idAI::Event_TestAnimAttack( const char *animname ) { - int anim; - predictedPath_t path; - - anim = GetAnim( ANIMCHANNEL_LEGS, animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); -#endif - - idThread::ReturnInt( false ); - return; - } - - idAI::PredictPath( this, aas, physicsObj.GetOrigin(), animator.TotalMovementDelta( anim ), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); - - idThread::ReturnInt( path.blockingEntity && ( path.blockingEntity == enemy.GetEntity() ) ); -} - -/* -===================== -idAI::Event_Shrivel -===================== -*/ -void idAI::Event_Shrivel( float shrivel_time ) { - float t; - - if ( idThread::BeginMultiFrameEvent( this, &AI_Shrivel ) ) { - if ( shrivel_time <= 0.0f ) { - idThread::EndMultiFrameEvent( this, &AI_Shrivel ); - return; - } - - shrivel_rate = 0.001f / shrivel_time; - shrivel_start = gameLocal.time; - } - - t = ( gameLocal.time - shrivel_start ) * shrivel_rate; - if ( t > 0.25f ) { - renderEntity.noShadow = true; - } - if ( t > 1.0f ) { - t = 1.0f; - idThread::EndMultiFrameEvent( this, &AI_Shrivel ); - } - - renderEntity.shaderParms[ SHADERPARM_MD5_SKINSCALE ] = 1.0f - t * 0.5f; - UpdateVisuals(); -} - -/* -===================== -idAI::Event_PreBurn -===================== -*/ -void idAI::Event_PreBurn( void ) { - // for now this just turns shadows off - renderEntity.noShadow = true; -} - -/* -===================== -idAI::Event_Burn -===================== -*/ -void idAI::Event_Burn( void ) { - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; - SpawnParticles( "smoke_burnParticleSystem" ); - UpdateVisuals(); -} - -/* -===================== -idAI::Event_ClearBurn -===================== -*/ -void idAI::Event_ClearBurn( void ) { - renderEntity.noShadow = spawnArgs.GetBool( "noshadows" ); - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = 0.0f; - UpdateVisuals(); -} - -/* -===================== -idAI::Event_SetSmokeVisibility -===================== -*/ -void idAI::Event_SetSmokeVisibility( int num, int on ) { - int i; - int time; - - if ( num >= particles.Num() ) { - gameLocal.Warning( "Particle #%d out of range (%d particles) on entity '%s'", num, particles.Num(), name.c_str() ); - return; - } - - if ( on != 0 ) { - time = gameLocal.time; - BecomeActive( TH_UPDATEPARTICLES ); - } else { - time = 0; - } - - if ( num >= 0 ) { - particles[ num ].time = time; - } else { - for ( i = 0; i < particles.Num(); i++ ) { - particles[ i ].time = time; - } - } - - UpdateVisuals(); -} - -/* -===================== -idAI::Event_NumSmokeEmitters -===================== -*/ -void idAI::Event_NumSmokeEmitters( void ) { - idThread::ReturnInt( particles.Num() ); -} - -/* -===================== -idAI::Event_StopThinking -===================== -*/ -void idAI::Event_StopThinking( void ) { - BecomeInactive( TH_THINK ); - idThread *thread = idThread::CurrentThread(); - if ( thread ) { - thread->DoneProcessing(); - } -} - -/* -===================== -idAI::Event_GetTurnDelta -===================== -*/ -void idAI::Event_GetTurnDelta( void ) { - float amount; - - if ( turnRate ) { - amount = idMath::AngleNormalize180( ideal_yaw - current_yaw ); - idThread::ReturnFloat( amount ); - } else { - idThread::ReturnFloat( 0.0f ); - } -} - -/* -===================== -idAI::Event_GetMoveType -===================== -*/ -void idAI::Event_GetMoveType( void ) { - idThread::ReturnInt( move.moveType ); -} - -/* -===================== -idAI::Event_SetMoveTypes -===================== -*/ -void idAI::Event_SetMoveType( int moveType ) { - SetMoveType(moveType); -} - -/* -===================== -idAI::Event_SaveMove -===================== -*/ -void idAI::Event_SaveMove( void ) { - savedMove = move; -} - -/* -===================== -idAI::Event_RestoreMove -===================== -*/ -void idAI::Event_RestoreMove( void ) { - // greebo: Call the local helper function with the previously stored as argument - RestoreMove(savedMove); -} - -/* -===================== -idAI::Event_AllowMovement -===================== -*/ -void idAI::Event_AllowMovement( float flag ) { - allowMove = ( flag != 0.0f ); -} - -/* -===================== -idAI::Event_JumpFrame -===================== -*/ -void idAI::Event_JumpFrame( void ) { - AI_JUMP = true; -} - -/* -===================== -idAI::Event_EnableClip -===================== -*/ -void idAI::Event_EnableClip( void ) { - physicsObj.SetClipMask( MASK_MONSTERSOLID ); - disableGravity = false; -} - -/* -===================== -idAI::Event_DisableClip -===================== -*/ -void idAI::Event_DisableClip( void ) { - physicsObj.SetClipMask( 0 ); - disableGravity = true; -} - -/* -===================== -idAI::Event_EnableGravity -===================== -*/ -void idAI::Event_EnableGravity( void ) { - disableGravity = false; -} - -/* -===================== -idAI::Event_DisableGravity -===================== -*/ -void idAI::Event_DisableGravity( void ) { - disableGravity = true; -} - -/* -===================== -idAI::Event_EnableAFPush -===================== -*/ -void idAI::Event_EnableAFPush( void ) { - m_bAFPushMoveables = true; -} - -/* -===================== -idAI::Event_DisableAFPush -===================== -*/ -void idAI::Event_DisableAFPush( void ) { - m_bAFPushMoveables = false; -} - -/* -===================== -idAI::Event_SetFlySpeed -===================== -*/ -void idAI::Event_SetFlySpeed( float speed ) { - if ( move.speed == fly_speed ) { - move.speed = speed; - } - fly_speed = speed; -} - -/* -================ -idAI::Event_SetFlyOffset -================ -*/ -void idAI::Event_SetFlyOffset( int offset ) { - fly_offset = offset; -} - -/* -================ -idAI::Event_ClearFlyOffset -================ -*/ -void idAI::Event_ClearFlyOffset( void ) { - spawnArgs.GetInt( "fly_offset", "0", fly_offset ); -} - -/* -===================== -idAI::Event_GetClosestHiddenTarget -===================== -*/ -void idAI::Event_GetClosestHiddenTarget( const char *type ) { - int i; - idEntity *ent; - idEntity *bestEnt; - float time; - float bestTime; - const idVec3 &org = physicsObj.GetOrigin(); - idActor *enemyEnt = enemy.GetEntity(); - - if ( !enemyEnt ) { - // no enemy to hide from - idThread::ReturnEntity( NULL ); - return; - } - - if ( targets.Num() == 1 ) { - ent = targets[ 0 ].GetEntity(); - if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { - if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, ent->GetPhysics()->GetOrigin() ) ) { - idThread::ReturnEntity( ent ); - return; - } - } - idThread::ReturnEntity( NULL ); - return; - } - - bestEnt = NULL; - bestTime = idMath::INFINITY; - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { - const idVec3 &destOrg = ent->GetPhysics()->GetOrigin(); - time = TravelDistance( org, destOrg ); - if ( ( time >= 0.0f ) && ( time < bestTime ) ) { - if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, destOrg ) ) { - bestEnt = ent; - bestTime = time; - } - } - } - } - idThread::ReturnEntity( bestEnt ); -} - -/* -===================== -idAI::Event_GetRandomTarget -===================== -*/ -void idAI::Event_GetRandomTarget( const char *type ) { - int i; - int num; - int which; - idEntity *ent; - idEntity *ents[ MAX_GENTITIES ]; - - num = 0; - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) { - ents[ num++ ] = ent; - if ( num >= MAX_GENTITIES ) { - break; - } - } - } - - if ( !num ) { - idThread::ReturnEntity( NULL ); - return; - } - - which = gameLocal.random.RandomInt( num ); - idThread::ReturnEntity( ents[ which ] ); -} - -/* -================ -idAI::Event_TravelDistanceToPoint -================ -*/ -void idAI::Event_TravelDistanceToPoint( const idVec3 &pos ) { - float time; - - time = TravelDistance( physicsObj.GetOrigin(), pos ); - idThread::ReturnFloat( time ); -} - -/* -================ -idAI::Event_TravelDistanceToEntity -================ -*/ -void idAI::Event_TravelDistanceToEntity( idEntity *ent ) { - float time; - - time = TravelDistance( physicsObj.GetOrigin(), ent->GetPhysics()->GetOrigin() ); - idThread::ReturnFloat( time ); -} - -/* -================ -idAI::Event_TravelDistanceBetweenPoints -================ -*/ -void idAI::Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest ) { - float time; - - time = TravelDistance( source, dest ); - idThread::ReturnFloat( time ); -} - -/* -================ -idAI::Event_TravelDistanceBetweenEntities -================ -*/ -void idAI::Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest ) { - float time; - - assert( source ); - assert( dest ); - time = TravelDistance( source->GetPhysics()->GetOrigin(), dest->GetPhysics()->GetOrigin() ); - idThread::ReturnFloat( time ); -} - -/* -===================== -idAI::Event_LookAtPosition -===================== -*/ -void idAI::Event_LookAtPosition (const idVec3& lookAtWorldPosition, float duration) -{ - // angua: AI must not look at infinity - // this rips their upper body off and leads to really low frame rates - if (lookAtWorldPosition.x != idMath::INFINITY) - { - if ( ( focusEntity.GetEntity() != NULL ) || ( currentFocusPos != lookAtWorldPosition) || (gameLocal.time ) ) - { - focusEntity = NULL; - currentFocusPos = lookAtWorldPosition; - alignHeadTime = gameLocal.time; - forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); - blink_time = 0; - } - - focusTime = gameLocal.time + SEC2MS( duration ); - } -} - - -void idAI::Event_LookAtAngles (float yawAngleClockwise, float pitchAngleUp, float rollAngle, float durationInSeconds) -{ - // Get current physical angles - idAngles physicalAngles(0.0f, current_yaw, 0.0f); - - // Now rotate it by the given angles - idAngles lookAngles = idAngles(pitchAngleUp, yawAngleClockwise, rollAngle); - - lookAngles += physicalAngles; - lookAngles.Normalize180(); - - // Determine the look at world position - idVec3 lookAtPositionDelta = lookAngles.ToForward() * 15.0; - idVec3 lookAtWorldPosition = GetEyePosition() + lookAtPositionDelta; - - //gameRenderWorld->DebugArrow (idVec4(1.0,0.0,0.0,1.0), GetEyePosition(), lookAtWorldPosition, 1, 5000); - - // Update focus position - if ( ( focusEntity.GetEntity() != NULL ) || ( currentFocusPos != lookAtWorldPosition) || (gameLocal.time ) ) - { - focusEntity = NULL; - currentFocusPos = lookAtWorldPosition; - alignHeadTime = gameLocal.time; - forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); - blink_time = 0; - } - - focusTime = gameLocal.time + SEC2MS( durationInSeconds ); -} - -/* -===================== -idAI::Event_LookAtEntity -===================== -*/ -void idAI::Event_LookAtEntity( idEntity *ent, float duration ) { - if ( ent == this ) { - ent = NULL; - } - - if ( ( ent != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) { - focusEntity = ent; - alignHeadTime = gameLocal.time; - forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); - blink_time = 0; - } - - focusTime = gameLocal.time + SEC2MS( duration ); -} - -/* -===================== -idAI::Event_LookAtEnemy -===================== -*/ -void idAI::Event_LookAtEnemy( float duration ) { - idActor *enemyEnt; - - enemyEnt = enemy.GetEntity(); - if ( ( enemyEnt != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) { - focusEntity = enemyEnt; - alignHeadTime = gameLocal.time; - forceAlignHeadTime = gameLocal.time + SEC2MS( 1 ); - blink_time = 0; - } - - focusTime = gameLocal.time + SEC2MS( duration ); -} - -/* -=============== -idAI::Event_SetJointMod -=============== -*/ -void idAI::Event_SetJointMod( int allow ) { - allowJointMod = ( allow != 0 ); -} - -/* -================ -idAI::Event_ThrowMoveable -================ -*/ -void idAI::Event_ThrowMoveable( void ) { - idEntity *ent; - idEntity *moveable = NULL; - - for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) { - if ( ent->GetBindMaster() == this && ent->IsType( idMoveable::Type ) ) { - moveable = ent; - break; - } - } - if ( moveable ) { - moveable->Unbind(); - moveable->PostEventMS( &EV_SetOwner, 200, 0 ); - } -} - -/* -================ -idAI::Event_ThrowAF -================ -*/ -void idAI::Event_ThrowAF( void ) { - idEntity *ent; - idEntity *af = NULL; - - for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) { - if ( ent->GetBindMaster() == this && ent->IsType( idAFEntity_Base::Type ) ) { - af = ent; - break; - } - } - if ( af ) { - af->Unbind(); - af->PostEventMS( &EV_SetOwner, 200, 0 ); - } -} - -/* -================ -idAI::Event_SetAngles -================ -*/ -void idAI::Event_SetAngles( idAngles const &ang ) { - current_yaw = ang.yaw; - viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); -} - -/* -================ -idAI::Event_GetAngles -================ -*/ -void idAI::Event_GetAngles( void ) { - idThread::ReturnVector( idVec3( 0.0f, current_yaw, 0.0f ) ); -} - -/* -================ -idAI::Event_RealKill -================ -*/ -void idAI::Event_RealKill( void ) { - health = 0; - - if ( af.IsLoaded() ) { - // clear impacts - af.Rest(); - - // physics is turned off by calling af.Rest() - BecomeActive( TH_PHYSICS ); - } - - Killed( this, this, 0, vec3_zero, INVALID_JOINT ); -} - -/* -================ -idAI::Event_Kill -================ -*/ -void idAI::Event_Kill( void ) { - PostEventMS( &AI_RealKill, 0 ); -} - -/* -================ -idAI::Event_WakeOnFlashlight -================ -*/ -void idAI::Event_WakeOnFlashlight( int enable ) { - wakeOnFlashlight = ( enable != 0 ); -} - -/* -================ -idAI::Event_LocateEnemy -================ -*/ -void idAI::Event_LocateEnemy( void ) { - idActor *enemyEnt; - int areaNum; - - enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - return; - } - - enemyEnt->GetAASLocation( aas, lastReachableEnemyPos, areaNum ); - - // SZ: Why is this in here if we are unsure of where the enemy is. We have to update it first - // Update was already after SetEnemyPosition so I'm just commenting out SetEnemyPosition (which - // is called form in UpdateEnemyPosition if we can see them) - //SetEnemyPosition(); - UpdateEnemyPosition(); -} - -/* -================ -idAI::Event_KickObstacles -================ -*/ -void idAI::Event_KickObstacles( idEntity *kickEnt, float force ) { - idVec3 dir; - idEntity *obEnt; - - if ( kickEnt ) { - obEnt = kickEnt; - } else { - obEnt = move.obstacle.GetEntity(); - } - - if ( obEnt ) { - dir = obEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin(); - dir.Normalize(); - } else { - dir = viewAxis[ 0 ]; - } - KickObstacles( dir, force, obEnt ); -} - -/* -================ -idAI::Event_GetObstacle -================ -*/ -void idAI::Event_GetObstacle( void ) { - idThread::ReturnEntity( move.obstacle.GetEntity() ); -} - -/* -================ -idAI::Event_PushPointIntoAAS -================ -*/ -void idAI::Event_PushPointIntoAAS( const idVec3 &pos ) { - int areaNum; - idVec3 newPos; - - areaNum = PointReachableAreaNum( pos ); - if ( areaNum ) { - newPos = pos; - aas->PushPointIntoAreaNum( areaNum, newPos ); - idThread::ReturnVector( newPos ); - } else { - idThread::ReturnVector( pos ); - } -} - - -/* -================ -idAI::Event_GetTurnRate -================ -*/ -void idAI::Event_GetTurnRate( void ) { - idThread::ReturnFloat( turnRate ); -} - -/* -================ -idAI::Event_SetTurnRate -================ -*/ -void idAI::Event_SetTurnRate( float rate ) { - turnRate = rate; -} - -/* -================ -idAI::Event_AnimTurn -================ -*/ -void idAI::Event_AnimTurn( float angles ) { - turnVel = 0.0f; - anim_turn_angles = angles; - if ( angles ) { - anim_turn_yaw = current_yaw; - anim_turn_amount = idMath::Fabs( idMath::AngleNormalize180( current_yaw - ideal_yaw ) ); - if ( anim_turn_amount > anim_turn_angles ) { - anim_turn_amount = anim_turn_angles; - } - } else { - anim_turn_amount = 0.0f; - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f ); - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, 0.0f ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, 0.0f ); - } -} - -/* -================ -idAI::Event_AllowHiddenMovement -================ -*/ -void idAI::Event_AllowHiddenMovement( int enable ) { - allowHiddenMovement = ( enable != 0 ); -} - -/* -================ -idAI::Event_TriggerParticles -================ -*/ -void idAI::Event_TriggerParticles( const char *jointName ) { - TriggerParticles( jointName ); -} - -/* -===================== -idAI::Event_FindActorsInBounds -===================== -*/ -void idAI::Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs ) { - idEntity * ent; - idEntity * entityList[ MAX_GENTITIES ]; - int numListedEntities; - int i; - - numListedEntities = gameLocal.clip.EntitiesTouchingBounds( idBounds( mins, maxs ), CONTENTS_BODY, entityList, MAX_GENTITIES ); - for( i = 0; i < numListedEntities; i++ ) { - ent = entityList[ i ]; - if ( ent != this && !ent->IsHidden() && ( ent->health > 0 ) && ent->IsType( idActor::Type ) ) { - idThread::ReturnEntity( ent ); - return; - } - } - - idThread::ReturnEntity( NULL ); -} - -/* -================ -idAI::Event_CanReachPosition -================ -*/ -void idAI::Event_CanReachPosition( const idVec3 &pos ) { - aasPath_t path; - int toAreaNum; - int areaNum; - - toAreaNum = PointReachableAreaNum( pos ); - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !toAreaNum || !PathToGoal( path, areaNum, physicsObj.GetOrigin(), toAreaNum, pos, this ) ) { - idThread::ReturnInt( false ); - } else { - idThread::ReturnInt( true ); - } -} - -/* -================ -idAI::Event_CanReachEntity -================ -*/ -void idAI::Event_CanReachEntity( idEntity *ent ) { - aasPath_t path; - int toAreaNum; - int areaNum; - idVec3 pos; - - if ( !ent ) { - idThread::ReturnInt( false ); - return; - } - - if ( move.moveType != MOVETYPE_FLY ) { - if ( !ent->GetFloorPos( 64.0f, pos ) ) { - idThread::ReturnInt( false ); - return; - } - if ( ent->IsType( idActor::Type ) && static_cast( ent )->OnLadder() ) { - idThread::ReturnInt( false ); - return; - } - } else { - pos = ent->GetPhysics()->GetOrigin(); - } - - toAreaNum = PointReachableAreaNum( pos ); - if ( !toAreaNum ) { - idThread::ReturnInt( false ); - return; - } - - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - if ( !toAreaNum || !PathToGoal( path, areaNum, org, toAreaNum, pos, this ) ) { - idThread::ReturnInt( false ); - } else { - idThread::ReturnInt( true ); - } -} - -/* -================ -idAI::Event_CanReachEnemy -================ -*/ -void idAI::Event_CanReachEnemy( void ) { - idThread::ReturnInt(CanReachEnemy()); -} - -/* -================ -idAI::Event_GetReachableEntityPosition -================ -*/ -void idAI::Event_GetReachableEntityPosition( idEntity *ent ) { - int toAreaNum; - idVec3 pos; - - if ( move.moveType != MOVETYPE_FLY ) - { - if ( !ent->GetFloorPos( 64.0f, pos ) ) - { - // NOTE: not a good way to return 'false' - idThread::ReturnVector( vec3_zero ); - return; - } - - if ( ent->IsType( idActor::Type ) && static_cast( ent )->OnLadder() ) - { - // NOTE: not a good way to return 'false' - idThread::ReturnVector( vec3_zero ); - return; - } - } - else - { - pos = ent->GetPhysics()->GetOrigin(); - } - - if ( aas ) - { - toAreaNum = PointReachableAreaNum( pos ); - aas->PushPointIntoAreaNum( toAreaNum, pos ); - } - - idThread::ReturnVector( pos ); -} - - -void idAI::Event_ReEvaluateArea(int areanum) -{ - ReEvaluateArea(areanum); -} - -/** -* DarkMod: Begin Team Relationship Events. See the definitions on CRelations -* for descriptions of the Relations functions that are called. -**/ - -void idAI::Event_GetRelationEnt( idEntity *ent ) -{ - idActor *actor; - - if ( !ent->IsType( idActor::Type ) ) - { - // inanimate objects are neutral to everyone - idThread::ReturnInt( 0 ); - } - - actor = static_cast( ent ); - idThread::ReturnInt( gameLocal.m_RelationsManager->GetRelNum( team, actor->team ) ); -} - -void idAI::Event_GetAcuity( const char *type ) -{ - idThread::ReturnFloat( GetAcuity( type ) ); -} - -void idAI::Event_SetAcuity( const char *type, float val ) -{ - SetAcuity( type, val ); -} - -void idAI::Event_GetAudThresh( void ) -{ - idThread::ReturnFloat( m_AudThreshold ); -} - -void idAI::Event_SetAudThresh( float val ) -{ - m_AudThreshold = val; -} - -void idAI::Event_SetAlertLevel( float newAlertLevel) -{ - SetAlertLevel(newAlertLevel); -} - -void idAI::Event_Alert( const char *type, float amount ) -{ - AlertAI( type, amount ); -} - -void idAI::Event_GetSndDir( void ) -{ - idThread::ReturnVector( m_SoundDir ); -} - -void idAI::Event_GetVisDir( void ) -{ - idThread::ReturnVector( m_LastSight ); -} - -void idAI::Event_GetTactEnt( void ) -{ - idEntity *ent = GetTactEnt(); - - if(!ent) - idThread::ReturnEntity( NULL ); - else - idThread::ReturnEntity( ent ); -} - - -void idAI::Event_VisScan( void ) -{ - // assume we are checking over one frame - float time(1.0f/60.0f); - - PerformVisualScan(time); - - idThread::ReturnEntity(GetEnemy()); -} - -void idAI::Event_ClosestReachableEnemy( void ) -{ - Event_ClosestReachableEnemyOfEntity( static_cast(this) ); -} - -//----------------------------------------------------------------------------------------------------- - -void idAI::destroyCurrentHidingSpotSearch() -{ - // Check to see if there is one - if (m_HidingSpotSearchHandle != NULL_HIDING_SPOT_SEARCH_HANDLE) - { - // Dereference current search - CHidingSpotSearchCollection::Instance().dereference(m_HidingSpotSearchHandle); - m_HidingSpotSearchHandle = NULL_HIDING_SPOT_SEARCH_HANDLE; - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Hiding spot search dereferenced\r"); - } - - // No hiding spots - m_hidingSpots.clear(); - - // greebo: Clear the initial alert position - if (mind != NULL) - { - mind->GetMemory().alertSearchCenter = idVec3(idMath::INFINITY, idMath::INFINITY, idMath::INFINITY); - } -} - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_StartSearchForHidingSpots -( - const idVec3& hideFromLocation, - const idVec3& minBounds, - const idVec3& maxBounds, - int hidingSpotTypesAllowed, - idEntity* p_ignoreEntity -) -{ - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Event_StartSearchForHidingSpots called.\r"); - - // Destroy any current search - destroyCurrentHidingSpotSearch(); - - // Make caller's search bounds - idBounds searchBounds (minBounds, maxBounds); - idBounds searchExclusionBounds; - searchExclusionBounds.Clear(); // no exclusion bounds - - // greebo: Remember the initial alert position - GetMemory().alertSearchCenter = hideFromLocation; - - // SZ: Must use same AAS that LAS used during setup - - // Get aas - if (aas != NULL) - { - // Allocate object that handles the search - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Making finder\r"); - bool b_searchCompleted = false; - m_HidingSpotSearchHandle = CHidingSpotSearchCollection::Instance().getOrCreateSearch - ( - hideFromLocation, - aas, - HIDING_OBJECT_HEIGHT, - searchBounds, - searchExclusionBounds, - hidingSpotTypesAllowed, - p_ignoreEntity, - gameLocal.framenum, - b_searchCompleted - ); - - // Wait at least one frame for other AIs to indicate they want to share - // this search. Return result indicating search is not done yet. - idThread::ReturnInt(1); - - } - else - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Cannot perform Event_StartSearchForHidingSpots if no AAS is set for the AI\r"); - - // Search is done since there is no search - idThread::ReturnInt(0); - } - - -} - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_StartSearchForHidingSpotsWithExclusionArea -( - const idVec3& hideFromLocation, - const idVec3& minBounds, - const idVec3& maxBounds, - const idVec3& exclusionMinBounds, - const idVec3& exclusionMaxBounds, - int hidingSpotTypesAllowed, - idEntity* p_ignoreEntity -) -{ - idThread::ReturnInt(StartSearchForHidingSpotsWithExclusionArea( - hideFromLocation, minBounds, maxBounds, exclusionMinBounds, - exclusionMaxBounds, hidingSpotTypesAllowed, p_ignoreEntity - )); -} - - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_ContinueSearchForHidingSpots() -{ - idThread::ReturnInt(ContinueSearchForHidingSpots()); -} - - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_CloseHidingSpotSearch () -{ - // Destroy current hiding spot search - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Closing hiding spot search\r"); - destroyCurrentHidingSpotSearch(); -} - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_ResortHidingSpots -( - const idVec3& searchCenter, - const idVec3& searchRadius -) -{ - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Resorting hiding spots for new search center\r"); - m_hidingSpots.sortForNewCenter - ( - searchCenter, - searchRadius.Length() - ); - -} - - -//----------------------------------------------------------------------------------------------------- - -void idAI::Event_GetNumHidingSpots () -{ - - - // Get the number of hiding spots - int numSpots = m_hidingSpots.getNumSpots(); - - // Return count - idThread::ReturnInt (numSpots); -} - -/*------------------------------------------------------------------------------*/ - -void idAI::Event_GetNthHidingSpotLocation (int hidingSpotIndex) -{ - idThread::ReturnVector(GetNthHidingSpotLocation(hidingSpotIndex)); -} - -/*------------------------------------------------------------------------------*/ - -void idAI::Event_GetNthHidingSpotType (int hidingSpotIndex) -{ - int outTypeFlags = 0; - - int numSpots = m_hidingSpots.getNumSpots(); - - // In bounds? - if ((hidingSpotIndex >= 0) && (hidingSpotIndex < numSpots)) - { - darkModHidingSpot* p_spot = m_hidingSpots.getNthSpot(hidingSpotIndex); - if (p_spot == NULL) - { - outTypeFlags = 0; - } - else - { - outTypeFlags = p_spot->hidingSpotTypes; - } - } - else - { - DM_LOG(LC_AI, LT_ERROR)LOGSTRING("Index %d is out of bounds, there are %d hiding spots\r", hidingSpotIndex, numSpots); - } - - // Return the type - idThread::ReturnInt (outTypeFlags); -} - -//----------------------------------------------------------------------------------------- - -void idAI::Event_GetAlertLevelOfOtherAI (idEntity* p_otherEntity) -{ - // Test parameters - if (p_otherEntity == NULL) - { - idThread::ReturnFloat (0.0); - return; - } - - // The other entity must be an AI - idAI* p_otherAI = dynamic_cast(p_otherEntity); - if (p_otherAI == NULL) - { - // Not an AI - idThread::ReturnFloat (0.0); - return; - } - - // Return the other AI's alert num - idThread::ReturnFloat (p_otherAI->AI_AlertLevel); -} - -/*---------------------------------------------------------------------------------*/ - -void idAI::Event_GetSomeOfOtherEntitiesHidingSpotList (idEntity* p_ownerOfSearch) -{ - idThread::ReturnInt(GetSomeOfOtherEntitiesHidingSpotList(p_ownerOfSearch)); -} - -//-------------------------------------------------------------------------------- - -void idAI::Event_GetAlertActor( void ) -{ - idThread::ReturnEntity( m_AlertedByActor.GetEntity() ); -} - -//-------------------------------------------------------------------------------- - -void idAI::Event_SetAlertGracePeriod( float frac, float duration, int count ) -{ - // set the parameters - m_AlertGraceActor = m_AlertedByActor.GetEntity(); - m_AlertGraceStart = gameLocal.time; - m_AlertGraceTime = SEC2MS( duration ); - m_AlertGraceThresh = m_AlertLevelThisFrame * frac; - m_AlertGraceCountLimit = count; - m_AlertGraceCount = 0; -} - -void idAI::Event_FoundBody( idEntity *body ) -{ - FoundBody( body ); -} - -void idAI::Event_PushState(const char* state) -{ - mind->PushState(state); -} - -void idAI::Event_SwitchState(const char* state) -{ - mind->SwitchState(state); -} - -void idAI::Event_EndState() -{ - idThread::ReturnInt(static_cast(mind->EndState())); -} - -void idAI::Event_ProcessBlindStim(idEntity* stimSource, int skipVisibilityCheck) -{ - mind->GetState()->OnBlindStim(stimSource, skipVisibilityCheck != 0); -} - -void idAI::Event_ProcessVisualStim(idEntity* stimSource) -{ - mind->GetState()->OnVisualStim(stimSource); -} - -void idAI::Event_GetNextIdleAnim() -{ - idThread::ReturnString(GetNextIdleAnim()); -} - -void idAI::Event_HasSeenEvidence() -{ - idThread::ReturnInt(HasSeenEvidence()); -} - -void idAI::Event_PerformRelight() // grayman #2603 -{ - m_performRelight = true; -} - -void idAI::Event_DropTorch() // grayman #2603 -{ - for (int i = 0 ; i < m_Attachments.Num() ; i++) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - if( !ent || !m_Attachments[i].ent.IsValid() ) - { - continue; - } - - if (ent->spawnArgs.GetBool("is_torch","0")) - { - DetachInd(i); - - // drop the torch a bit to get away from the AI's hand - - idVec3 origin = ent->GetPhysics()->GetOrigin(); - origin.z -= 20; - ent->GetPhysics()->SetOrigin( origin ); - - ent->m_droppedByAI = true; // grayman #1330 - GetMemory().stopRelight = true; // in case a relight was in progress - try again later w/o torch - GetMemory().stopExaminingRope = true; // grayman #2872 - stop examining a rope - m_DroppingTorch = false; - break; - } - } -} - - - diff --git a/game/ai/ai_pathing.cpp b/game/ai/ai_pathing.cpp deleted file mode 100644 index 6786449fa..000000000 --- a/game/ai/ai_pathing.cpp +++ /dev/null @@ -1,1910 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#include "../../DarkMod/BinaryFrobMover.h" -#include "../../DarkMod/FrobDoor.h" -#include "../../DarkMod/TimerManager.h" -#include "../../DarkMod/AI/Memory.h" - -/* -=============================================================================== - - Dynamic Obstacle Avoidance - - - assumes the AI lives inside a bounding box aligned with the gravity direction - - obstacles in proximity of the AI are gathered - - if obstacles are found the AAS walls are also considered as obstacles - - every obstacle is represented by an oriented bounding box (OBB) - - an OBB is projected onto a 2D plane orthogonal to AI's gravity direction - - the 2D windings of the projections are expanded for the AI bbox - - a path tree is build using clockwise and counter clockwise edge walks along the winding edges - - the path tree is pruned and optimized - - the shortest path is chosen for navigation - -=============================================================================== -*/ - -const float MAX_OBSTACLE_RADIUS = 128.0f; -const float OBSTACLE_HEIGHT_EXPANSION = 10.0f; -const float PUSH_OUTSIDE_OBSTACLES = 0.5f; -const float CLIP_BOUNDS_EPSILON = 10.0f; -const int MAX_AAS_WALL_EDGES = 256; -const int MAX_OBSTACLES = 256; -const int MAX_PATH_NODES = 256; -const int MAX_OBSTACLE_PATH = 64; -const int REUSE_DOOR_DELAY = 3000; // grayman #2345 - wait before using a door again. #2706 - lower from 8s to 1s to reduce circling - -typedef struct obstacle_s { - idVec2 bounds[2]; - idWinding2D winding; - idEntity * entity; -} obstacle_t; - -typedef struct pathNode_s { - int dir; - idVec2 pos; - idVec2 delta; - float dist; - int obstacle; - int edgeNum; - int numNodes; - struct pathNode_s * parent; - struct pathNode_s * children[2]; - struct pathNode_s * next; - void Init(); -} pathNode_t; - -void pathNode_s::Init() { - dir = 0; - pos.Zero(); - delta.Zero(); - obstacle = -1; - edgeNum = -1; - numNodes = 0; - parent = children[0] = children[1] = next = NULL; -} - -idBlockAlloc pathNodeAllocator; - -#if 0 -// grayman - for debugging path tree nodes -void PrintNode(pathNode_t* node,int level,obstacle_t obstacles[]) -{ - idStr pad = ""; - for (int i = 0 ; i < level ; i++) - { - pad += " "; - } - - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s ------ node -----\r",pad.c_str()); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s dir = %d (0 = left & 1 = right?)\r",pad.c_str(),node->dir); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s pos = [%s] (parent's pos + parent's delta)\r",pad.c_str(),node->pos.ToString()); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s delta = [%s] (?)\r",pad.c_str(),node->delta.ToString()); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s dist = %f (distance to seekPos)\r",pad.c_str(),sqrt(node->dist)); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = %d (blocking obstacle index)\r",pad.c_str(),node->obstacle); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s edgeNum = %d (blocking edge num)\r",pad.c_str(),node->edgeNum); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s numNodes = %d (num nodes down from root)\r",pad.c_str(),node->numNodes); - - if (node->obstacle != -1) - { - idEntity *e = obstacles[node->obstacle].entity; - if (e) - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = %s\r",pad.c_str(),e->name.c_str()); - } - else - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle = NULL\r",pad.c_str()); - } - } - else - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("%s obstacle index = -1\r",pad.c_str()); - } -} - -void PrintNodes(pathNode_t* node,int level,obstacle_t obstacles[]) -{ - PrintNode(node,level,obstacles); - if (node->children[0]) - { - PrintNodes(node->children[0],level+1,obstacles); - } - if (node->children[1]) - { - PrintNodes(node->children[1],level+1,obstacles); - } -} -#endif - -/* -============ -LineIntersectsPath -============ -*/ -bool LineIntersectsPath( const idVec2 &start, const idVec2 &end, const pathNode_t *node ) { - float d0, d1, d2, d3; - idVec3 plane1, plane2; - - plane1 = idWinding2D::Plane2DFromPoints( start, end ); - d0 = plane1.x * node->pos.x + plane1.y * node->pos.y + plane1.z; - while( node->parent ) { - d1 = plane1.x * node->parent->pos.x + plane1.y * node->parent->pos.y + plane1.z; - if ( FLOATSIGNBITSET( d0 ) ^ FLOATSIGNBITSET( d1 ) ) { - plane2 = idWinding2D::Plane2DFromPoints( node->pos, node->parent->pos ); - d2 = plane2.x * start.x + plane2.y * start.y + plane2.z; - d3 = plane2.x * end.x + plane2.y * end.y + plane2.z; - if ( FLOATSIGNBITSET( d2 ) ^ FLOATSIGNBITSET( d3 ) ) { - return true; - } - } - d0 = d1; - node = node->parent; - } - return false; -} - -/* -============ -PointInsideObstacle -============ -*/ -int PointInsideObstacle( const obstacle_t *obstacles, const int numObstacles, const idVec2 &point ) { - int i; - - for ( i = 0; i < numObstacles; i++ ) { - - const idVec2 *bounds = obstacles[i].bounds; - if ( point.x < bounds[0].x || point.y < bounds[0].y || point.x > bounds[1].x || point.y > bounds[1].y ) { - continue; - } - - if ( !obstacles[i].winding.PointInside( point, 0.1f ) ) { - continue; - } - - return i; - } - - return -1; -} - -/* -============ -GetPointOutsideObstacles -============ -*/ -void GetPointOutsideObstacles( const obstacle_t *obstacles, const int numObstacles, idVec2 &point, int *obstacle, int *edgeNum ) { - int i, j, k, n, bestObstacle, bestEdgeNum, queueStart, queueEnd, edgeNums[2]; - float d, bestd, scale[2]; - idVec3 plane, bestPlane; - idVec2 newPoint, dir, bestPoint(0, 0); - int *queue; - bool *obstacleVisited; - idWinding2D w1, w2; - - if ( obstacle ) { - *obstacle = -1; - } - if ( edgeNum ) { - *edgeNum = -1; - } - - bestObstacle = PointInsideObstacle( obstacles, numObstacles, point ); - if ( bestObstacle == -1 ) { - return; - } - - const idWinding2D &w = obstacles[bestObstacle].winding; - bestd = idMath::INFINITY; - bestEdgeNum = 0; - for ( i = 0; i < w.GetNumPoints(); i++ ) { - plane = idWinding2D::Plane2DFromPoints( w[(i+1)%w.GetNumPoints()], w[i], true ); - d = plane.x * point.x + plane.y * point.y + plane.z; - if ( d < bestd ) { - bestd = d; - bestPlane = plane; - bestEdgeNum = i; - } - // if this is a wall always try to pop out at the first edge - if ( obstacles[bestObstacle].entity == NULL ) { - break; - } - } - - newPoint = point - ( bestd + PUSH_OUTSIDE_OBSTACLES ) * bestPlane.ToVec2(); - if ( PointInsideObstacle( obstacles, numObstacles, newPoint ) == -1 ) { - point = newPoint; - if ( obstacle ) { - *obstacle = bestObstacle; - } - if ( edgeNum ) { - *edgeNum = bestEdgeNum; - } - return; - } - - queue = (int *) _alloca( numObstacles * sizeof( queue[0] ) ); - obstacleVisited = (bool *) _alloca( numObstacles * sizeof( obstacleVisited[0] ) ); - - queueStart = 0; - queueEnd = 1; - queue[0] = bestObstacle; - - memset( obstacleVisited, 0, numObstacles * sizeof( obstacleVisited[0] ) ); - obstacleVisited[bestObstacle] = true; - - bestd = idMath::INFINITY; - for ( i = queue[0]; queueStart < queueEnd; i = queue[++queueStart] ) { - w1 = obstacles[i].winding; - w1.Expand( PUSH_OUTSIDE_OBSTACLES ); - - for ( j = 0; j < numObstacles; j++ ) { - // if the obstacle has been visited already - if ( obstacleVisited[j] ) { - continue; - } - // if the bounds do not intersect - if ( obstacles[j].bounds[0].x > obstacles[i].bounds[1].x || obstacles[j].bounds[0].y > obstacles[i].bounds[1].y || - obstacles[j].bounds[1].x < obstacles[i].bounds[0].x || obstacles[j].bounds[1].y < obstacles[i].bounds[0].y ) { - continue; - } - - queue[queueEnd++] = j; - obstacleVisited[j] = true; - - w2 = obstacles[j].winding; - w2.Expand( 0.2f ); - - for ( k = 0; k < w1.GetNumPoints(); k++ ) { - dir = w1[(k+1)%w1.GetNumPoints()] - w1[k]; - if ( !w2.RayIntersection( w1[k], dir, scale[0], scale[1], edgeNums ) ) { - continue; - } - for ( n = 0; n < 2; n++ ) { - newPoint = w1[k] + scale[n] * dir; - if ( PointInsideObstacle( obstacles, numObstacles, newPoint ) == -1 ) { - d = ( newPoint - point ).LengthSqr(); - if ( d < bestd ) { - bestd = d; - bestPoint = newPoint; - bestEdgeNum = edgeNums[n]; - bestObstacle = j; - } - } - } - } - } - - if ( bestd < idMath::INFINITY ) { - point = bestPoint; - if ( obstacle ) { - *obstacle = bestObstacle; - } - if ( edgeNum ) { - *edgeNum = bestEdgeNum; - } - return; - } - } - gameLocal.Warning( "GetPointOutsideObstacles: no valid point found" ); -} - -/* -============ -GetFirstBlockingObstacle -============ -*/ -bool GetFirstBlockingObstacle(const idPhysics *physics, const obstacle_t *obstacles, int numObstacles, int skipObstacle, const idVec2 &startPos, const idVec2 &delta, float &blockingScale, int &blockingObstacle, int &blockingEdgeNum, int &blockingDoorNum ) { // grayman #2345 - int i, edgeNums[2]; - float dist, scale1, scale2; - idVec2 bounds[2]; - - // grayman #2345 - get AI version of yourself - - idActor* self = static_cast(const_cast(physics)->GetSelf()); - idAI* selfAI = static_cast(self); - - // get bounds for the current movement delta - bounds[0] = startPos - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - bounds[1] = startPos + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - bounds[FLOATSIGNBITNOTSET(delta.x)].x += delta.x; - bounds[FLOATSIGNBITNOTSET(delta.y)].y += delta.y; - - // test for obstacles blocking the path - blockingScale = idMath::INFINITY; - float blockingScaleDoor = idMath::INFINITY; // grayman #2345 - dist = delta.Length(); - for ( i = 0; i < numObstacles; i++ ) { - if ( i == skipObstacle ) { - continue; - } - - if ( bounds[0].x > obstacles[i].bounds[1].x || bounds[0].y > obstacles[i].bounds[1].y || - bounds[1].x < obstacles[i].bounds[0].x || bounds[1].y < obstacles[i].bounds[0].y ) - { - continue; - } - if ( obstacles[i].winding.RayIntersection( startPos, delta, scale1, scale2, edgeNums ) ) - { - if ( scale1 < blockingScale && scale1 * dist > -0.01f && scale2 * dist > 0.01f ) - { - blockingScale = scale1; - blockingObstacle = i; - blockingEdgeNum = edgeNums[0]; - - // grayman #2345 - Return the index number of the closest blocking door, - // regardless of whether the door is the closest blocking obstacle. Ignore - // a door that you recently used if not alerted. This keeps you from going back and forth - // through the same door. - - // grayman #2712 - removed alert check - - idEntity* e = obstacles[i].entity; - if ((e != NULL) && e->IsType(CFrobDoor::Type)) - { - if (blockingScale < blockingScaleDoor) - { - CFrobDoor *frobDoor = static_cast(e); - int lastTimeUsed = selfAI->GetMemory().GetDoorInfo(frobDoor).lastTimeUsed; - if ((lastTimeUsed > -1) && (gameLocal.time < lastTimeUsed + REUSE_DOOR_DELAY)) - { - continue; // ignore this door - } - blockingDoorNum = i; - blockingScaleDoor = blockingScale; - } - } - } - } - } - return ( blockingScale < 1.0f ); -} - -/* -============ -GetObstacles -============ -*/ -int GetObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, int areaNum, - const idVec3 &startPos, const idVec3 &seekPos, obstacle_t *obstacles, int maxObstacles, - idBounds &clipBounds, obstaclePath_t& pathInfo ) -{ - int clipMask; - float stepHeight, headHeight, min, max; - idVec3 silVerts[32]; - idVec2 obDelta; - - /** TDM: SZ: This variable tracks if the obstacle is a binary mover or not - * If NULL its not, if non NULL it is, and the pointer is a cast to it - * as a binary mover - */ - // So far, we don't have a door - pathInfo.doorObstacle = NULL; - - // TDM: Store our team. const_cast<> is necessary due to GetSelf() not being const - idActor* self = static_cast(const_cast(physics)->GetSelf()); - int team = self->team; - - idVec3 seekDelta = seekPos - startPos; - idVec2 expBounds[2]; - expBounds[0] = physics->GetBounds()[0].ToVec2() - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - expBounds[1] = physics->GetBounds()[1].ToVec2() + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - - physics->GetAbsBounds().AxisProjection( -physics->GetGravityNormal(), stepHeight, headHeight ); - stepHeight += aas->GetSettings()->maxStepHeight; - - // clip bounds for the obstacle search space - clipBounds[0] = clipBounds[1] = startPos; - clipBounds.AddPoint( seekPos ); - - const idBounds& bounds = physics->GetBounds(); - - idVec3 dir = seekDelta; - dir.z = 0; - dir.NormalizeFast(); - idVec3 center = 0.5 * (startPos + seekPos); - - idVec3 normal = dir.Cross(gameLocal.GetGravity()); - normal.NormalizeFast(); - clipBounds.AddPoint( center + MAX_OBSTACLE_RADIUS * normal); - clipBounds.AddPoint( center - MAX_OBSTACLE_RADIUS * normal); - - clipBounds.AddPoint(seekPos + 2 * bounds[1][0] * dir); - clipBounds.AddPoint(startPos - 2 * bounds[1][0] * dir); - - clipBounds[0][2] -= bounds[0][2] + OBSTACLE_HEIGHT_EXPANSION; - clipBounds[1][2] += bounds[1][2] + OBSTACLE_HEIGHT_EXPANSION; - - clipBounds.ExpandSelf(CLIP_BOUNDS_EPSILON); - - // clipBounds.ExpandSelf( MAX_OBSTACLE_RADIUS ); - clipMask = physics->GetClipMask(); - - if ( ai_showObstacleAvoidance.GetBool() ) { - gameRenderWorld->DebugBox(colorBlue, idBox(clipBounds), gameLocal.msec); - } - - // find all obstacles touching the clip bounds - static idClipModel* clipModelList[ MAX_GENTITIES ]; - int numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds( clipBounds, clipMask, clipModelList, MAX_GENTITIES ); - - int numObstacles = 0; // no obstacles so far - - CBinaryFrobMover* p_binaryFrobMover; // grayman #2345 - - idAI* selfAI = NULL; // grayman #2345 - for locating a func_static you're bumping into - if (self->IsType(idAI::Type)) - { - selfAI = static_cast(self); - } - - bool actorFound = false; // grayman #2345 - whether an actor was found on this pass - - for ( int i = 0; i < numListedClipModels && numObstacles < MAX_OBSTACLES; i++ ) - { - p_binaryFrobMover = NULL; // grayman #2345 - idClipModel* clipModel = clipModelList[i]; - idEntity* obEnt = clipModel->GetEntity(); - - // greebo: Immediately ignore self - if (obEnt == self) - { - continue; - } - - /* - * SZ: Oct 9, 2006: Not all binary frob movers have trace models as clip models - * so I am commenting this out. - */ - /* - if ( !clipModel->IsTraceModel() ) { - continue; - } - */ - - if (obEnt->IsType(idActor::Type)) - { - idActor* obEntActor = static_cast(obEnt); // grayman #2345 - actorFound = true; // grayman #2345 - idPhysics* obPhys = obEnt->GetPhysics(); - - // ignore myself, my enemy, and dead bodies - // TDM: Also ignore ALL enemies - // grayman #2728 - also ignore small AI - if ((obPhys == physics) || (obEnt == ignore) || (obEnt->health <= 0) || self->IsEnemy(obEnt) || (obPhys->GetMass() <= 5.0)) - { - continue; - } - - /* grayman #2345 - - Use m_pathRank to determine who will walk around the other. At init time, m_pathRank - is set to rank. A higher m_pathRank will not walk around a lower m_pathRank. A lower - m_pathRank will walk around a higher m_pathRank. If m_pathRanks are equal at first - encounter, self's m_pathRank will be bumped up. Whoever sights the other first gets - to have a higher m_pathRank. m_pathRank = 1000 for a non-moving actor, so others - will walk around him. m_pathRank is reset to rank when an AI begins moving again. - - */ - - bool sameDirection = false; // self and actor traveling in roughly the same direction? - bool actorSameFaster = false; // actor is traveling at the same speed or faster than you - const idVec3& actorVel = obPhys->GetLinearVelocity(); - float actorSpeedSqr = actorVel.LengthSqr(); - idVec3 myVel = physics->GetLinearVelocity(); - float mySpeedSqr = myVel.LengthSqr(); - // moving in about the same direction? - if (actorVel * myVel > 0.0f) - { - sameDirection = true; - } - - // actor's speed is faster or equal to self? - if (actorSpeedSqr >= mySpeedSqr) - { - actorSameFaster = true; - } - - if (self->m_pathRank > obEntActor->m_pathRank) - { - if (actorSameFaster) - { - continue; - } - else if (!sameDirection) - { - continue; - } - } - else if (self->m_pathRank == obEntActor->m_pathRank) - { - self->m_pathRank++; // increase mine and ignore the other actor - continue; // ignore - } - - // Self's path rank is lower than the actor's. If the actor is moving in the same - // direction and is traveling at the same speed or faster, ignore them. - - else if (sameDirection && actorSameFaster) - { - continue; // ignore - } - } - // SZ: Oct 9, 2006: BinaryMovers are now dynamic pathing obstacles too - else if (obEnt->IsType(CBinaryFrobMover::Type)) - { - p_binaryFrobMover = static_cast(obEnt); // grayman #2345 - } - else if (obEnt->IsType(idMoveable::Type)) - { - // grayman #2740 - ignore movables attached to the AI - - idEntity* bindMaster = obEnt->GetBindMaster(); - if (self == bindMaster) - { - continue; // ignore - } - - // all other moveables are considered obstacles - } - - // grayman #2345 - in general, ignore func_statics. but if you're bumping into one, consider it an obstacle - - else if (obEnt->IsType(idStaticEntity::Type)) - { - if (selfAI && (obEnt != selfAI->GetTactileEntity())) - { - continue; // ignore this - } - - // If we get here, this func_static is an obstacle. However, func_statics can - // have odd shapes, which means you could walk through an opening in one, or - // under one. If you're "inside" the bounding box of this func_static, ignore it. - - idPhysics* obPhys = obEnt->GetPhysics(); - idBounds obBounds = obPhys->GetAbsBounds(); - idVec3 origin = physics->GetOrigin(); - if (obBounds.ContainsPoint(origin)) - { - continue; // ignore this - } - } - else - { - // ignore everything else - - // TDM: SZ Oct 9, 2006: Comment this continue out, and the AI will path around func_statics - // and the like, even without monster-clip brushes around them. - // However, the CPU load is higher and the weapon an AI is carrying - // is an obstacle (bad). - - continue; - } - - // check if we can step over the object - clipModel->GetAbsBounds().AxisProjection( -physics->GetGravityNormal(), min, max ); - if ( max < stepHeight || min > headHeight ) { - // can step over this one - // angua: do not step over other actors - if (!obEnt->IsType(idActor::Type)) - { - continue; - } - } - - // Get the box bounding the obstacle - idBox box( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); - idBox boxClosed; // grayman #2712 - bool openDoorFound = false; // grayman #2712 - - // grayman #2345 - To get AI to queue at an open door and not cause logjams, treat an open door - // as if it's closed. This could also apply to all binary frob movers, but since many of those - // are simple wall switches, and should be ignored, we'll limit this code to doors. The door-handling - // task sorts out whether the door is actually open or closed. - - if (p_binaryFrobMover != NULL) - { - // only "see" doors - // grayman #2712 - if you can operate doors, and the door is open, include a - // second box representing the closed door. The 'open' box provides an obstacle - // presence for pathfinding, and the 'closed' box alerts the AI that the door - // needs to be handled. - - if (p_binaryFrobMover->IsType(CFrobDoor::Type)) - { - if (selfAI->m_bCanOperateDoors) // grayman #2691 - { - if (p_binaryFrobMover->IsOpen()) - { - if (!selfAI->m_HandlingDoor) // If we're already handling a door, don't include the closed door in the obstacle calculation - { - openDoorFound = true; - // grayman #720 - replace calculations with a capture of the closed box at spawn time - -// box.AddBox (p_binaryFrobMover->GetClosedBox()); - boxClosed = p_binaryFrobMover->GetClosedBox(); // create a second box; don't add to open box - } - } - } - } - } - - // project the box containing the obstacle onto the floor plane - int numVerts = box.GetParallelProjectionSilhouetteVerts( physics->GetGravityNormal(), silVerts ); - - // create a 2D winding for the obstacle; - obstacle_t& obstacle = obstacles[numObstacles++]; - obstacle.winding.Clear(); - for ( int j = 0; j < numVerts; j++ ) { - obstacle.winding.AddPoint( silVerts[j].ToVec2() ); - } - - if ( ai_showObstacleAvoidance.GetBool() ) { - for ( int j = 0; j < numVerts; j++ ) { - silVerts[j].z = startPos.z; - } - for ( int j = 0; j < numVerts; j++ ) { - gameRenderWorld->DebugArrow( colorWhite, silVerts[j], silVerts[(j+1)%numVerts], 4 ,gameLocal.msec); - } - } - - // expand the 2D winding for collision with a 2D box - obstacle.winding.ExpandForAxialBox( expBounds ); - obstacle.winding.GetBounds( obstacle.bounds ); - obstacle.entity = obEnt; - - // grayman #2712 - treat a 'closed' door box as a separate item so the door's recognized - // later when the AI is told to handle it. - - if (openDoorFound) - { - // project the box containing the obstacle onto the floor plane - int numVerts = boxClosed.GetParallelProjectionSilhouetteVerts( physics->GetGravityNormal(), silVerts ); - - // create a 2D winding for the obstacle; - obstacle_t& obstacle2 = obstacles[numObstacles++]; - obstacle2.winding.Clear(); - for ( int j = 0; j < numVerts; j++ ) { - obstacle2.winding.AddPoint( silVerts[j].ToVec2() ); - } - - // expand the 2D winding for collision with a 2D box - obstacle2.winding.ExpandForAxialBox( expBounds ); - obstacle2.winding.GetBounds( obstacle.bounds ); - obstacle2.entity = obEnt; - } - } - - // grayman #2345 - if I encountered no actors on this pass, reset my m_pathRank to my rank - - if (!actorFound) - { - self->m_pathRank = self->rank; - } - - // if there are no dynamic obstacles the path should be through valid AAS space - if ( numObstacles == 0 ) { - return 0; - } - - int blockingObstacle; // will hold the index to the first blocking obstacle - int blockingEdgeNum; // will hold the edge number of the winding which intersects the path - int blockingDoorNum = -1; // grayman #2345 - will hold the index to the first blocking door - float blockingScale; - // if the current path doesn't intersect any dynamic obstacles the path should be through valid AAS space - int startObstacleNum = PointInsideObstacle( obstacles, numObstacles, startPos.ToVec2()); - if (startObstacleNum == -1 ) - { - if (!GetFirstBlockingObstacle(physics, obstacles, numObstacles, -1, startPos.ToVec2(), seekDelta.ToVec2(), - blockingScale, blockingObstacle, blockingEdgeNum, blockingDoorNum)) // grayman #2345 - { - // grayman #1327 - return the door even if blockingScale (determined in GetFirstBlockingObstacle() ) - // was > 1. This allows AI to see doors sooner, and helps reduce the number of instances where - // they don't see the door at all. - - if ( blockingDoorNum >= 0 ) - { - idEntity* door = obstacles[blockingDoorNum].entity; // we already know this is a valid door - pathInfo.doorObstacle = static_cast(door); - } - - // No first obstacle found - return 0; - } - - // grayman #2345 - rather than test to see if the first blocking obstacle - // is a door, test to see if ANY is a door. If so, mark the first one. - - if ( blockingDoorNum >= 0 ) - { - idEntity* door = obstacles[blockingDoorNum].entity; // we already know this is a valid door - pathInfo.doorObstacle = static_cast(door); - } - } - - // create obstacles for AAS walls - - if ( aas != NULL ) - { - float halfBoundsSize = ( expBounds[ 1 ].x - expBounds[ 0 ].x ) * 0.5f; - - int wallEdges[MAX_AAS_WALL_EDGES]; - START_TIMING(self->actorGetWallEdgesTimer); - int numWallEdges = aas->GetWallEdges( areaNum, clipBounds, TFL_WALK, wallEdges, MAX_AAS_WALL_EDGES ); - STOP_TIMING(self->actorGetWallEdgesTimer); - - START_TIMING(self->actorSortWallEdgesTimer); - aas->SortWallEdges( wallEdges, numWallEdges ); - STOP_TIMING(self->actorSortWallEdgesTimer); - - int lastVerts[2] = {0,0}; - int nextVerts[2] = {0,0}; - idVec2 lastEdgeNormal(0,0); - int verts[2]; // will hold edge vertex indices - idVec2 edgeNormal, nextEdgeDir, nextEdgeNormal(0, 0); - idVec3 start, end, nextStart, nextEnd; - - for ( int i = 0; i < numWallEdges && numObstacles < MAX_OBSTACLES; i++ ) - { - aas->GetEdge( wallEdges[i], start, end ); - aas->GetEdgeVertexNumbers( wallEdges[i], verts ); - - // Get the edge direction - idVec2 edgeDir(end.ToVec2() - start.ToVec2()); - edgeDir.Normalize(); - - // Get the direction perpendicular to this edge - edgeNormal.x = edgeDir.y; - edgeNormal.y = -edgeDir.x; - - // Do we have a next edge? - if ( i < numWallEdges-1 ) - { - // Get the next edge direction plus normal - aas->GetEdge( wallEdges[i+1], nextStart, nextEnd ); - aas->GetEdgeVertexNumbers( wallEdges[i+1], nextVerts ); - - nextEdgeDir = nextEnd.ToVec2() - nextStart.ToVec2(); - nextEdgeDir.Normalize(); - - nextEdgeNormal.x = nextEdgeDir.y; - nextEdgeNormal.y = -nextEdgeDir.x; - } - - // greebo: Check if caching the AAS obstacle representations can save some CPU time. - // AAS areas never change during map runtime, so why calculate them each time? - // 15/06/2008: Did some profiling, the section below is harmless, it's the - // aas->GetWallEdges and aas->SortWallEdges() calls above which are expensive. - - // grayman: If they're expensive, can't they also be done once and cached? An AAS - // area doesn't change over time. - - // Start to fill the values in the new obstacle structure - obstacle_t& obstacle = obstacles[numObstacles++]; - - obstacle.winding.Clear(); - - // greebo: Populate the winding, this will form a trapezoid - // with the edge as one side. The longer side will be a bit away from the wall sticking into the room. - obstacle.winding.AddPoint( end.ToVec2() ); - obstacle.winding.AddPoint( start.ToVec2() ); - obstacle.winding.AddPoint( start.ToVec2() - edgeDir - edgeNormal * halfBoundsSize ); - obstacle.winding.AddPoint( end.ToVec2() + edgeDir - edgeNormal * halfBoundsSize ); - - if ( lastVerts[1] == verts[0] ) { - obstacle.winding[2] -= lastEdgeNormal * halfBoundsSize; - } else { - obstacle.winding[1] -= edgeDir; - } - if ( verts[1] == nextVerts[0] ) { - obstacle.winding[3] -= nextEdgeNormal * halfBoundsSize; - } else { - obstacle.winding[0] += edgeDir; - } - obstacle.winding.GetBounds( obstacle.bounds ); - obstacle.entity = NULL; - - lastVerts[0] = verts[0]; - lastVerts[1] = verts[1]; - lastEdgeNormal = edgeNormal; - } - } - - // show obstacles - if ( ai_showObstacleAvoidance.GetBool() ) { - for ( int i = 0; i < numObstacles; i++ ) { - obstacle_t &obstacle = obstacles[i]; - for ( int j = 0; j < obstacle.winding.GetNumPoints(); j++ ) { - silVerts[j].ToVec2() = obstacle.winding[j]; - silVerts[j].z = startPos.z; - } - for ( int j = 0; j < obstacle.winding.GetNumPoints(); j++ ) { - gameRenderWorld->DebugArrow( colorGreen, silVerts[j], silVerts[(j+1)%obstacle.winding.GetNumPoints()], 4, gameLocal.msec ); - } - } - } - - return numObstacles; -} - -/* -============ -FreePathTree_r -============ -*/ -void FreePathTree_r( pathNode_t *node ) { - if ( node->children[0] ) { - FreePathTree_r( node->children[0] ); - } - if ( node->children[1] ) { - FreePathTree_r( node->children[1] ); - } - pathNodeAllocator.Free( node ); -} - -/* -============ -DrawPathTree -============ -*/ -void DrawPathTree( const pathNode_t *root, const float height ) { - int i; - idVec3 start, end; - const pathNode_t *node; - - for ( node = root; node; node = node->next ) { - for ( i = 0; i < 2; i++ ) { - if ( node->children[i] ) { - start.ToVec2() = node->pos; - start.z = height; - end.ToVec2() = node->children[i]->pos; - end.z = height; - gameRenderWorld->DebugArrow( node->edgeNum == -1 ? colorYellow : i ? colorBlue : colorRed, start, end, 1 ); - break; - } - } - } -} - -/* -============ -GetPathNodeDelta -============ -*/ -bool GetPathNodeDelta( pathNode_t *node, const obstacle_t *obstacles, const idVec2 &seekPos, bool blocked ) { - int numPoints, edgeNum; - bool facing; - idVec2 seekDelta, dir; - pathNode_t *n; - - numPoints = obstacles[node->obstacle].winding.GetNumPoints(); - - // get delta along the current edge - while( 1 ) { - edgeNum = ( node->edgeNum + node->dir ) % numPoints; - node->delta = obstacles[node->obstacle].winding[edgeNum] - node->pos; - if ( node->delta.LengthSqr() > 0.01f ) { - break; - } - node->edgeNum = ( node->edgeNum + numPoints + ( 2 * node->dir - 1 ) ) % numPoints; - } - - // if not blocked - if ( !blocked ) { - - // test if the current edge faces the goal - seekDelta = seekPos - node->pos; - facing = ( ( 2 * node->dir - 1 ) * ( node->delta.x * seekDelta.y - node->delta.y * seekDelta.x ) ) >= 0.0f; - - // if the current edge faces goal and the line from the current - // position to the goal does not intersect the current path - if ( facing && !LineIntersectsPath( node->pos, seekPos, node->parent ) ) { - node->delta = seekPos - node->pos; - node->edgeNum = -1; - } - } - - // if the delta is along the obstacle edge - if ( node->edgeNum != -1 ) { - // if the edge is found going from this node to the root node - for ( n = node->parent; n; n = n->parent ) { - - if ( node->obstacle != n->obstacle || node->edgeNum != n->edgeNum ) { - continue; - } - - // test whether or not the edge segments actually overlap - if ( n->pos * node->delta > ( node->pos + node->delta ) * node->delta ) { - continue; - } - if ( node->pos * node->delta > ( n->pos + n->delta ) * node->delta ) { - continue; - } - - break; - } - if ( n ) { - return false; - } - } - return true; -} - -/* -============ -BuildPathTree -============ -*/ -pathNode_t *BuildPathTree( const idPhysics *physics, const obstacle_t *obstacles, int numObstacles, const idBounds &clipBounds, const idVec2 &startPos, const idVec2 &seekPos, obstaclePath_t &path ) // grayman #2345 - added 'physics' -{ - int blockingEdgeNum, blockingObstacle, obstaclePoints, bestNumNodes = MAX_OBSTACLE_PATH; - float blockingScale; - pathNode_t *root, *node, *child; - // gcc 4.0 - idQueueTemplate pathNodeQueue, treeQueue; - root = pathNodeAllocator.Alloc(); - root->Init(); - root->pos = startPos; - - root->delta = seekPos - root->pos; - root->numNodes = 0; - pathNodeQueue.Add( root ); - - for ( node = pathNodeQueue.Get(); node && pathNodeAllocator.GetAllocCount() < MAX_PATH_NODES; node = pathNodeQueue.Get() ) { - - treeQueue.Add( node ); - - // if this path has more than twice the number of nodes than the best path so far - if ( node->numNodes > bestNumNodes * 2 ) { - continue; - } - - // don't move outside of the clip bounds - idVec2 endPos = node->pos + node->delta; - if ( endPos.x - CLIP_BOUNDS_EPSILON < clipBounds[0].x || endPos.x + CLIP_BOUNDS_EPSILON > clipBounds[1].x || - endPos.y - CLIP_BOUNDS_EPSILON < clipBounds[0].y || endPos.y + CLIP_BOUNDS_EPSILON > clipBounds[1].y ) { - continue; - } - - // if an obstacle is blocking the path - - int blockingDoorNum = -1; // grayman #2345 - will hold the index to the first blocking door - - if ( GetFirstBlockingObstacle(physics, obstacles, numObstacles, node->obstacle, node->pos, node->delta, blockingScale, blockingObstacle, blockingEdgeNum, blockingDoorNum)) // grayman #2345 - { - if ( path.firstObstacle == NULL ) { - path.firstObstacle = obstacles[blockingObstacle].entity; - } - - node->delta *= blockingScale; - - if ( node->edgeNum == -1 ) { - node->children[0] = pathNodeAllocator.Alloc(); - node->children[0]->Init(); - node->children[1] = pathNodeAllocator.Alloc(); - node->children[1]->Init(); - node->children[0]->dir = 0; - node->children[1]->dir = 1; - node->children[0]->parent = node->children[1]->parent = node; - node->children[0]->pos = node->children[1]->pos = node->pos + node->delta; - node->children[0]->obstacle = node->children[1]->obstacle = blockingObstacle; - node->children[0]->edgeNum = node->children[1]->edgeNum = blockingEdgeNum; - node->children[0]->numNodes = node->children[1]->numNodes = node->numNodes + 1; - if ( GetPathNodeDelta( node->children[0], obstacles, seekPos, true ) ) { - pathNodeQueue.Add( node->children[0] ); - } - if ( GetPathNodeDelta( node->children[1], obstacles, seekPos, true ) ) { - pathNodeQueue.Add( node->children[1] ); - } - } else { - node->children[node->dir] = child = pathNodeAllocator.Alloc(); - child->Init(); - child->dir = node->dir; - child->parent = node; - child->pos = node->pos + node->delta; - child->obstacle = blockingObstacle; - child->edgeNum = blockingEdgeNum; - child->numNodes = node->numNodes + 1; - if ( GetPathNodeDelta( child, obstacles, seekPos, true ) ) { - pathNodeQueue.Add( child ); - } - } - } else { - node->children[node->dir] = child = pathNodeAllocator.Alloc(); - child->Init(); - child->dir = node->dir; - child->parent = node; - child->pos = node->pos + node->delta; - child->numNodes = node->numNodes + 1; - - // there is a free path towards goal - if ( node->edgeNum == -1 ) { - if ( node->numNodes < bestNumNodes ) { - bestNumNodes = node->numNodes; - } - continue; - } - - child->obstacle = node->obstacle; - obstaclePoints = obstacles[node->obstacle].winding.GetNumPoints(); - child->edgeNum = ( node->edgeNum + obstaclePoints + ( 2 * node->dir - 1 ) ) % obstaclePoints; - - if ( GetPathNodeDelta( child, obstacles, seekPos, false ) ) { - pathNodeQueue.Add( child ); - } - } - } - - return root; -} - -/* -============ -PrunePathTree -============ -*/ -void PrunePathTree( pathNode_t *root, const idVec2 &seekPos ) { - int i; - float bestDist; - pathNode_t *node, *lastNode, *n, *bestNode; - - node = root; - while( node ) { - node->dist = ( seekPos - node->pos ).LengthSqr(); - - if ( node->children[0] ) { - node = node->children[0]; - } else if ( node->children[1] ) { - node = node->children[1]; - } else { - - // find the node closest to the goal along this path - bestDist = idMath::INFINITY; - bestNode = node; - for ( n = node; n; n = n->parent ) { - if ( n->children[0] && n->children[1] ) { - break; - } - if ( n->dist < bestDist ) { - bestDist = n->dist; - bestNode = n; - } - } - - // free tree down from the best node - for ( i = 0; i < 2; i++ ) { - if ( bestNode->children[i] ) { - FreePathTree_r( bestNode->children[i] ); - bestNode->children[i] = NULL; - } - } - - for ( lastNode = bestNode, node = bestNode->parent; node; lastNode = node, node = node->parent ) { - if ( node->children[1] && ( node->children[1] != lastNode ) ) { - node = node->children[1]; - break; - } - } - } - } -} - -/* -============ -OptimizePath -============ -*/ -int OptimizePath( const pathNode_t *root, const pathNode_t *leafNode, const obstacle_t *obstacles, int numObstacles, idVec2 optimizedPath[MAX_OBSTACLE_PATH] ) { - int i, numPathPoints, edgeNums[2]; - const pathNode_t *curNode, *nextNode; - idVec2 curPos, curDelta, bounds[2]; - float scale1, scale2, curLength; - - optimizedPath[0] = root->pos; - numPathPoints = 1; - - for ( nextNode = curNode = root; curNode != leafNode; curNode = nextNode ) { - for ( nextNode = leafNode; nextNode->parent != curNode; nextNode = nextNode->parent ) { - - // can only take shortcuts when going from one object to another - if ( nextNode->obstacle == curNode->obstacle ) { - continue; - } - - curPos = curNode->pos; - curDelta = nextNode->pos - curPos; - curLength = curDelta.Length(); - - // get bounds for the current movement delta - bounds[0] = curPos - idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - bounds[1] = curPos + idVec2( CM_BOX_EPSILON, CM_BOX_EPSILON ); - bounds[FLOATSIGNBITNOTSET(curDelta.x)].x += curDelta.x; - bounds[FLOATSIGNBITNOTSET(curDelta.y)].y += curDelta.y; - - // test if the shortcut intersects with any obstacles - for ( i = 0; i < numObstacles; i++ ) { - if ( bounds[0].x > obstacles[i].bounds[1].x || bounds[0].y > obstacles[i].bounds[1].y || - bounds[1].x < obstacles[i].bounds[0].x || bounds[1].y < obstacles[i].bounds[0].y ) { - continue; - } - if ( obstacles[i].winding.RayIntersection( curPos, curDelta, scale1, scale2, edgeNums ) ) { - if ( scale1 >= 0.0f && scale1 <= 1.0f && ( i != nextNode->obstacle || scale1 * curLength < curLength - 0.5f ) ) { - break; - } - if ( scale2 >= 0.0f && scale2 <= 1.0f && ( i != nextNode->obstacle || scale2 * curLength < curLength - 0.5f ) ) { - break; - } - } - } - if ( i >= numObstacles ) { - break; - } - } - - // store the next position along the optimized path - optimizedPath[numPathPoints++] = nextNode->pos; - } - - return numPathPoints; -} - -/* -============ -PathLength -============ -*/ -float PathLength( idVec2 optimizedPath[MAX_OBSTACLE_PATH], int numPathPoints, const idVec2 &curDir ) { - int i; - float pathLength; - - // calculate the path length - pathLength = 0.0f; - for ( i = 0; i < numPathPoints-1; i++ ) { - pathLength += ( optimizedPath[i+1] - optimizedPath[i] ).LengthFast(); - } - - // add penalty if this path does not go in the current direction - if ( curDir * ( optimizedPath[1] - optimizedPath[0] ) < 0.0f ) { - pathLength += 100.0f; - } - return pathLength; -} - -/* -============ -FindOptimalPath - - Returns true if there is a path all the way to the goal. -============ -*/ -bool FindOptimalPath( const pathNode_t *root, const obstacle_t *obstacles, int numObstacles, const float height, const idVec3 &curDir, idVec3 &seekPos ) { - int i, numPathPoints, bestNumPathPoints; - const pathNode_t *node, *lastNode, *bestNode; - idVec2 optimizedPath[MAX_OBSTACLE_PATH]; - float pathLength, bestPathLength; - bool pathToGoalExists, optimizedPathCalculated; - - seekPos.Zero(); - seekPos.z = height; - - pathToGoalExists = false; - optimizedPathCalculated = false; - - bestNode = root; - bestNumPathPoints = 0; - bestPathLength = idMath::INFINITY; - - node = root; - - while( node ) { - pathToGoalExists |= ( node->dist < 0.1f ); - - if ( node->dist <= bestNode->dist ) { - - if ( idMath::Fabs( node->dist - bestNode->dist ) < 0.1f ) { - - if ( !optimizedPathCalculated ) { - bestNumPathPoints = OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); - bestPathLength = PathLength( optimizedPath, bestNumPathPoints, curDir.ToVec2() ); - // grayman - A series of path points has been examined and the first one to head to is in - // optimizedPath[1]. But if bestNumPathPoints == 1 here, then optimizedPath[1] contains garbage. Does it matter? - seekPos.ToVec2() = optimizedPath[1]; - } - - numPathPoints = OptimizePath( root, node, obstacles, numObstacles, optimizedPath ); - pathLength = PathLength( optimizedPath, numPathPoints, curDir.ToVec2() ); - - if ( pathLength < bestPathLength ) { - bestNode = node; - bestNumPathPoints = numPathPoints; - bestPathLength = pathLength; - seekPos.ToVec2() = optimizedPath[1]; - } - optimizedPathCalculated = true; - - } else { - - bestNode = node; - optimizedPathCalculated = false; - } - } - - if ( node->children[0] ) { - node = node->children[0]; - } else if ( node->children[1] ) { - node = node->children[1]; - } else { - for ( lastNode = node, node = node->parent; node; lastNode = node, node = node->parent ) { - if ( node->children[1] && node->children[1] != lastNode ) { - node = node->children[1]; - break; - } - } - } - } - - if ( !pathToGoalExists ) { - if (root->children[0] != NULL) - { - seekPos.ToVec2() = root->children[0]->pos; - } - } else if ( !optimizedPathCalculated ) { - OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); - seekPos.ToVec2() = optimizedPath[1]; - } - - if ( ai_showObstacleAvoidance.GetBool() ) { - idVec3 start, end; - start.z = end.z = height + 4.0f; - numPathPoints = OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath ); - for ( i = 0; i < numPathPoints-1; i++ ) { - start.ToVec2() = optimizedPath[i]; - end.ToVec2() = optimizedPath[i+1]; - gameRenderWorld->DebugArrow( colorCyan, start, end, 1, gameLocal.msec); - } - } - - return pathToGoalExists; -} - -/* -============ -idAI::FindPathAroundObstacles - - Finds a path around dynamic obstacles using a path tree with clockwise and counter clockwise edge walks. -============ -*/ -bool idAI::FindPathAroundObstacles(const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path, idActor* owner ) { - // Initialise the path structure with reasonable defaults - path.seekPos = seekPos; - path.firstObstacle = NULL; - path.startPosOutsideObstacles = startPos; - path.startPosObstacle = NULL; - path.seekPosOutsideObstacles = seekPos; - path.seekPosObstacle = NULL; - path.doorObstacle = NULL; - - if (aas == NULL) { - return true; // no AAS! - } - - idBounds bounds; - bounds[1] = aas->GetSettings()->boundingBoxes[0][1]; - bounds[0] = -bounds[1]; - bounds[1].z = 32.0f; - - // get the AAS area number and a valid point inside that area - int areaNum = aas->PointReachableAreaNum( path.startPosOutsideObstacles, bounds, (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ); - aas->PushPointIntoAreaNum( areaNum, path.startPosOutsideObstacles ); - - // get all the nearby obstacles - static obstacle_t obstacles[MAX_OBSTACLES]; - idBounds clipBounds; - - START_TIMING(owner->actorGetObstaclesTimer); - int numObstacles = GetObstacles( physics, aas, ignore, areaNum, path.startPosOutsideObstacles, path.seekPosOutsideObstacles, obstacles, MAX_OBSTACLES, clipBounds, path ); - STOP_TIMING(owner->actorGetObstaclesTimer); - - START_TIMING(owner->actorGetPointOutsideObstaclesTimer); - - // get a source position outside the obstacles - int insideObstacle; - GetPointOutsideObstacles( obstacles, numObstacles, path.startPosOutsideObstacles.ToVec2(), &insideObstacle, NULL ); - if ( insideObstacle != -1 ) { - path.startPosObstacle = obstacles[insideObstacle].entity; - } - - // get a goal position outside the obstacles - GetPointOutsideObstacles( obstacles, numObstacles, path.seekPosOutsideObstacles.ToVec2(), &insideObstacle, NULL ); - if ( insideObstacle != -1 ) { - path.seekPosObstacle = obstacles[insideObstacle].entity; - } - - STOP_TIMING(owner->actorGetPointOutsideObstaclesTimer); - - // if start and destination are pushed to the same point, we don't have a path around the obstacle - if ( ( path.seekPosOutsideObstacles.ToVec2() - path.startPosOutsideObstacles.ToVec2() ).LengthSqr() < Square( 1.0f ) ) { - if ( ( seekPos.ToVec2() - startPos.ToVec2() ).LengthSqr() > Square( 2.0f ) ) { - return false; - } - } - - START_TIMING(owner->actorBuildPathTreeTimer); - // build a path tree - pathNode_t* root = BuildPathTree(physics, obstacles, numObstacles, clipBounds, path.startPosOutsideObstacles.ToVec2(), path.seekPosOutsideObstacles.ToVec2(), path ); // grayman #2345 - added 'physics' - -// PrintNodes(root,0,obstacles); // grayman for debugging path trees - - STOP_TIMING(owner->actorBuildPathTreeTimer); - - // draw the path tree - if ( ai_showObstacleAvoidance.GetBool() ) { - DrawPathTree( root, physics->GetOrigin().z ); - } - - // prune the tree - START_TIMING(owner->actorPrunePathTreeTimer); - PrunePathTree( root, path.seekPosOutsideObstacles.ToVec2() ); - STOP_TIMING(owner->actorPrunePathTreeTimer); -// PrintNodes(root,0,obstacles); // grayman for debugging path trees - - // find the optimal path - START_TIMING(owner->actorFindOptimalPathTimer); - bool pathToGoalExists = FindOptimalPath( root, obstacles, numObstacles, physics->GetOrigin().z, physics->GetLinearVelocity(), path.seekPos ); - STOP_TIMING(owner->actorFindOptimalPathTimer); - - // free the tree - FreePathTree_r( root ); - - return pathToGoalExists; -} - -/* -============ -idAI::FreeObstacleAvoidanceNodes -============ -*/ -void idAI::FreeObstacleAvoidanceNodes( void ) { - pathNodeAllocator.Shutdown(); -} - - -/* -=============================================================================== - - Path Prediction - - Uses the AAS to quickly and accurately predict a path for a certain - period of time based on an initial position and velocity. - -=============================================================================== -*/ - -const float OVERCLIP = 1.001f; -const int MAX_FRAME_SLIDE = 5; - -typedef struct pathTrace_s { - float fraction; - idVec3 endPos; - idVec3 normal; - const idEntity * blockingEntity; -} pathTrace_t; - -/* -============ -PathTrace - - Returns true if a stop event was triggered. -============ -*/ -bool PathTrace( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &end, int stopEvent, struct pathTrace_s &trace, predictedPath_t &path ) { - trace_t clipTrace; - aasTrace_t aasTrace; - - memset( &trace, 0, sizeof( trace ) ); - - if ( !aas || !aas->GetSettings() ) { - - gameLocal.clip.Translation( clipTrace, start, end, ent->GetPhysics()->GetClipModel(), - ent->GetPhysics()->GetClipModel()->GetAxis(), MASK_MONSTERSOLID, ent ); - - // NOTE: could do (expensive) ledge detection here for when there is no AAS file - - trace.fraction = clipTrace.fraction; - trace.endPos = clipTrace.endpos; - trace.normal = clipTrace.c.normal; - trace.blockingEntity = gameLocal.entities[ clipTrace.c.entityNum ]; - } else { - aasTrace.getOutOfSolid = true; - if ( stopEvent & SE_ENTER_LEDGE_AREA ) { - aasTrace.flags |= AREA_LEDGE; - } - if ( stopEvent & SE_ENTER_OBSTACLE ) { - aasTrace.travelFlags |= TFL_INVALID; - } - - aas->Trace( aasTrace, start, end ); - - gameLocal.clip.TranslationEntities( clipTrace, start, aasTrace.endpos, ent->GetPhysics()->GetClipModel(), - ent->GetPhysics()->GetClipModel()->GetAxis(), MASK_MONSTERSOLID, ent ); - - if ( clipTrace.fraction >= 1.0f ) { - - trace.fraction = aasTrace.fraction; - trace.endPos = aasTrace.endpos; - trace.normal = aas->GetPlane( aasTrace.planeNum ).Normal(); - trace.blockingEntity = gameLocal.world; - - if ( aasTrace.fraction < 1.0f ) { - if ( stopEvent & SE_ENTER_LEDGE_AREA ) { - if ( aas->AreaFlags( aasTrace.blockingAreaNum ) & AREA_LEDGE ) { - path.endPos = trace.endPos; - path.endNormal = trace.normal; - path.endEvent = SE_ENTER_LEDGE_AREA; - path.blockingEntity = trace.blockingEntity; - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, start, aasTrace.endpos ); - } - return true; - } - } - if ( stopEvent & SE_ENTER_OBSTACLE ) { - if ( aas->AreaTravelFlags( aasTrace.blockingAreaNum ) & TFL_INVALID ) { - path.endPos = trace.endPos; - path.endNormal = trace.normal; - path.endEvent = SE_ENTER_OBSTACLE; - path.blockingEntity = trace.blockingEntity; - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, start, aasTrace.endpos ); - } - return true; - } - } - } - } else { - trace.fraction = clipTrace.fraction; - trace.endPos = clipTrace.endpos; - trace.normal = clipTrace.c.normal; - trace.blockingEntity = gameLocal.entities[ clipTrace.c.entityNum ]; - } - } - - if ( trace.fraction >= 1.0f ) { - trace.blockingEntity = NULL; - } - - return false; -} - -/* -============ -idAI::PredictPath - - Can also be used when there is no AAS file available however ledges are not detected. -============ -*/ -bool idAI::PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path ) { - int i, j, step, numFrames, curFrameTime; - idVec3 delta, curStart, curEnd, curVelocity, lastEnd, stepUp, tmpStart; - idVec3 gravity, gravityDir, invGravityDir; - float maxStepHeight, minFloorCos; - pathTrace_t trace; - - if ( aas && aas->GetSettings() ) { - gravity = aas->GetSettings()->gravity; - gravityDir = aas->GetSettings()->gravityDir; - invGravityDir = aas->GetSettings()->invGravityDir; - maxStepHeight = aas->GetSettings()->maxStepHeight; - minFloorCos = aas->GetSettings()->minFloorCos; - } else { - gravity = DEFAULT_GRAVITY_VEC3; - gravityDir = idVec3( 0, 0, -1 ); - invGravityDir = idVec3( 0, 0, 1 ); - maxStepHeight = 14.0f; - minFloorCos = 0.7f; - } - - path.endPos = start; - path.endVelocity = velocity; - path.endNormal.Zero(); - path.endEvent = 0; - path.endTime = 0; - path.blockingEntity = NULL; - - curStart = start; - curVelocity = velocity; - - numFrames = ( totalTime + frameTime - 1 ) / frameTime; - curFrameTime = frameTime; - for ( i = 0; i < numFrames; i++ ) { - - if ( i == numFrames-1 ) { - curFrameTime = totalTime - i * curFrameTime; - } - - delta = curVelocity * curFrameTime * 0.001f; - - path.endVelocity = curVelocity; - path.endTime = i * frameTime; - - // allow sliding along a few surfaces per frame - for ( j = 0; j < MAX_FRAME_SLIDE; j++ ) { - - idVec3 lineStart = curStart; - - // allow stepping up three times per frame - for ( step = 0; step < 3; step++ ) { - - curEnd = curStart + delta; - if ( PathTrace( ent, aas, curStart, curEnd, stopEvent, trace, path ) ) { - return true; - } - - if ( step ) { - - // step down at end point - tmpStart = trace.endPos; - curEnd = tmpStart - stepUp; - if ( PathTrace( ent, aas, tmpStart, curEnd, stopEvent, trace, path ) ) { - return true; - } - - // if not moved any further than without stepping up, or if not on a floor surface - if ( (lastEnd - start).LengthSqr() > (trace.endPos - start).LengthSqr() - 0.1f || - ( trace.normal * invGravityDir ) < minFloorCos ) { - if ( stopEvent & SE_BLOCKED ) { - path.endPos = lastEnd; - path.endEvent = SE_BLOCKED; - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, lineStart, lastEnd ); - } - - return true; - } - - curStart = lastEnd; - break; - } - } - - path.endNormal = trace.normal; - path.blockingEntity = trace.blockingEntity; - - // if the trace is not blocked or blocked by a floor surface - if ( trace.fraction >= 1.0f || ( trace.normal * invGravityDir ) > minFloorCos ) { - curStart = trace.endPos; - break; - } - - // save last result - lastEnd = trace.endPos; - - // step up - stepUp = invGravityDir * maxStepHeight; - if ( PathTrace( ent, aas, curStart, curStart + stepUp, stopEvent, trace, path ) ) { - return true; - } - stepUp *= trace.fraction; - curStart = trace.endPos; - } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, lineStart, curStart ); - } - - if ( trace.fraction >= 1.0f ) { - break; - } - - delta.ProjectOntoPlane( trace.normal, OVERCLIP ); - curVelocity.ProjectOntoPlane( trace.normal, OVERCLIP ); - - if ( stopEvent & SE_BLOCKED ) { - // if going backwards - if ( (curVelocity - gravityDir * curVelocity * gravityDir ) * - (velocity - gravityDir * velocity * gravityDir) < 0.0f ) { - path.endPos = curStart; - path.endEvent = SE_BLOCKED; - - return true; - } - } - } - - if ( j >= MAX_FRAME_SLIDE ) { - if ( stopEvent & SE_BLOCKED ) { - path.endPos = curStart; - path.endEvent = SE_BLOCKED; - return true; - } - } - - // add gravity - curVelocity += gravity * frameTime * 0.001f; - } - - path.endTime = totalTime; - path.endVelocity = curVelocity; - path.endPos = curStart; - path.endEvent = 0; - - return false; -} - - -/* -=============================================================================== - - Trajectory Prediction - - Finds the best collision free trajectory for a clip model based on an - initial position, target position and speed. - -=============================================================================== -*/ - -/* -===================== -Ballistics - - get the ideal aim pitch angle in order to hit the target - also get the time it takes for the projectile to arrive at the target -===================== -*/ -typedef struct ballistics_s { - float angle; // angle in degrees in the range [-180, 180] - float time; // time it takes before the projectile arrives -} ballistics_t; - -static int Ballistics( const idVec3 &start, const idVec3 &end, float speed, float gravity, ballistics_t bal[2] ) { - int n, i; - float x, y, a, b, c, d, sqrtd, inva, p[2]; - - x = ( end.ToVec2() - start.ToVec2() ).Length(); - y = end[2] - start[2]; - - a = 4.0f * y * y + 4.0f * x * x; - b = -4.0f * speed * speed - 4.0f * y * gravity; - c = gravity * gravity; - - d = b * b - 4.0f * a * c; - if ( d <= 0.0f || a == 0.0f ) { - return 0; - } - sqrtd = idMath::Sqrt( d ); - inva = 0.5f / a; - p[0] = ( - b + sqrtd ) * inva; - p[1] = ( - b - sqrtd ) * inva; - n = 0; - for ( i = 0; i < 2; i++ ) { - if ( p[i] <= 0.0f ) { - continue; - } - d = idMath::Sqrt( p[i] ); - bal[n].angle = atan2( 0.5f * ( 2.0f * y * p[i] - gravity ) / d, d * x ); - bal[n].time = x / ( cos( bal[n].angle ) * speed ); - bal[n].angle = idMath::AngleNormalize180( RAD2DEG( bal[n].angle ) ); - n++; - } - - return n; -} - -/* -===================== -HeightForTrajectory - -Returns the maximum hieght of a given trajectory -===================== -*/ -static float HeightForTrajectory( const idVec3 &start, float zVel, float gravity ) { - float maxHeight, t; - - t = zVel / gravity; - // maximum height of projectile - maxHeight = start.z - 0.5f * gravity * ( t * t ); - - return maxHeight; -} - -/* -===================== -idAI::TestTrajectory -===================== -*/ -bool idAI::TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime ) { - int i, numSegments; - float maxHeight, t, t2; - idVec3 points[5]; - trace_t trace; - bool result; - - t = zVel / gravity; - // maximum height of projectile - maxHeight = start.z - 0.5f * gravity * ( t * t ); - // time it takes to fall from the top to the end height - t = idMath::Sqrt( ( maxHeight - end.z ) / ( 0.5f * -gravity ) ); - - // start of parabolic - points[0] = start; - - if ( t < time ) { - numSegments = 4; - // point in the middle between top and start - t2 = ( time - t ) * 0.5f; - points[1].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); - points[1].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; - // top of parabolic - t2 = time - t; - points[2].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); - points[2].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; - // point in the middel between top and end - t2 = time - t * 0.5f; - points[3].ToVec2() = start.ToVec2() + (end.ToVec2() - start.ToVec2()) * ( t2 / time ); - points[3].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; - } else { - numSegments = 2; - // point halfway through - t2 = time * 0.5f; - points[1].ToVec2() = start.ToVec2() + ( end.ToVec2() - start.ToVec2() ) * 0.5f; - points[1].z = start.z + t2 * zVel + 0.5f * gravity * t2 * t2; - } - - // end of parabolic - points[numSegments] = end; - - if ( drawtime ) { - for ( i = 0; i < numSegments; i++ ) { - gameRenderWorld->DebugLine( colorRed, points[i], points[i+1], drawtime ); - } - } - - // make sure projectile doesn't go higher than we want it to go - for ( i = 0; i < numSegments; i++ ) { - if ( points[i].z > max_height ) { - // goes higher than we want to allow - return false; - } - } - - result = true; - for ( i = 0; i < numSegments; i++ ) { - gameLocal.clip.Translation( trace, points[i], points[i+1], clip, mat3_identity, clipmask, ignore ); - if ( trace.fraction < 1.0f ) { - if ( gameLocal.GetTraceEntity( trace ) == targetEntity ) { - result = true; - } else { - result = false; - } - break; - } - } - - if ( drawtime ) { - if ( clip ) { - gameRenderWorld->DebugBounds( result ? colorGreen : colorYellow, clip->GetBounds().Expand( 1.0f ), trace.endpos, drawtime ); - } else { - idBounds bnds( trace.endpos ); - bnds.ExpandSelf( 1.0f ); - gameRenderWorld->DebugBounds( result ? colorGreen : colorYellow, bnds, vec3_zero, drawtime ); - } - } - - return result; -} - -/* -===================== -idAI::PredictTrajectory - - returns true if there is a collision free trajectory for the clip model - aimDir is set to the ideal aim direction in order to hit the target -===================== -*/ -bool idAI::PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir ) { - int n, i, j; - float zVel, a, t, pitch, s, c; - trace_t trace; - ballistics_t ballistics[2]; - idVec3 dir[2]; - idVec3 velocity; - idVec3 lastPos, pos; - - assert( targetEntity ); - - // check if the projectile starts inside the target - if ( targetEntity->GetPhysics()->GetAbsBounds().IntersectsBounds( clip->GetBounds().Translate( firePos ) ) ) { - aimDir = target - firePos; - aimDir.Normalize(); - return true; - } - - // if no velocity or the projectile is not affected by gravity - if ( projectileSpeed <= 0.0f || projGravity == vec3_origin ) { - - aimDir = target - firePos; - aimDir.Normalize(); - - gameLocal.clip.Translation( trace, firePos, target, clip, mat3_identity, clipmask, ignore ); - - if ( drawtime ) { - gameRenderWorld->DebugLine( colorRed, firePos, target, drawtime ); - idBounds bnds( trace.endpos ); - bnds.ExpandSelf( 1.0f ); - gameRenderWorld->DebugBounds( ( trace.fraction >= 1.0f || ( gameLocal.GetTraceEntity( trace ) == targetEntity ) ) ? colorGreen : colorYellow, bnds, vec3_zero, drawtime ); - } - - return ( trace.fraction >= 1.0f || ( gameLocal.GetTraceEntity( trace ) == targetEntity ) ); - } - - n = Ballistics( firePos, target, projectileSpeed, projGravity[2], ballistics ); - if ( n == 0 ) { - // there is no valid trajectory - aimDir = target - firePos; - aimDir.Normalize(); - return false; - } - - // make sure the first angle is the smallest - if ( n == 2 ) { - if ( ballistics[1].angle < ballistics[0].angle ) { - a = ballistics[0].angle; ballistics[0].angle = ballistics[1].angle; ballistics[1].angle = a; - t = ballistics[0].time; ballistics[0].time = ballistics[1].time; ballistics[1].time = t; - } - } - - // test if there is a collision free trajectory - for ( i = 0; i < n; i++ ) { - pitch = DEG2RAD( ballistics[i].angle ); - idMath::SinCos( pitch, s, c ); - dir[i] = target - firePos; - dir[i].z = 0.0f; - dir[i] *= c * idMath::InvSqrt( dir[i].LengthSqr() ); - dir[i].z = s; - - zVel = projectileSpeed * dir[i].z; - - if ( ai_debugTrajectory.GetBool() ) { - t = ballistics[i].time / 100.0f; - velocity = dir[i] * projectileSpeed; - lastPos = firePos; - pos = firePos; - for ( j = 1; j < 100; j++ ) { - pos += velocity * t; - velocity += projGravity * t; - gameRenderWorld->DebugLine( colorCyan, lastPos, pos ); - lastPos = pos; - } - } - - if ( TestTrajectory( firePos, target, zVel, projGravity[2], ballistics[i].time, firePos.z + max_height, clip, clipmask, ignore, targetEntity, drawtime ) ) { - aimDir = dir[i]; - return true; - } - } - - aimDir = dir[0]; - - // there is no collision free trajectory - return false; -} diff --git a/game/ai/tdmAASFindEscape.cpp b/game/ai/tdmAASFindEscape.cpp index e290db4d6..1268b2b30 100644 --- a/game/ai/tdmAASFindEscape.cpp +++ b/game/ai/tdmAASFindEscape.cpp @@ -1,13 +1,23 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #pragma hdrstop static bool init_version = FileVersionList("$Id$", init_version); diff --git a/game/ai/tdmAASFindEscape.h b/game/ai/tdmAASFindEscape.h index ae5cc6466..9b7c510b1 100644 --- a/game/ai/tdmAASFindEscape.h +++ b/game/ai/tdmAASFindEscape.h @@ -1,16 +1,26 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __tdmAASFindEscape_H__ #define __tdmAASFindEscape_H__ -#include "aas.h" +#include "AAS.h" /** * greebo: This evaluator is designed to find escape routes diff --git a/game/anim/Anim.cpp b/game/anim/Anim.cpp new file mode 100644 index 000000000..ae63bc185 --- /dev/null +++ b/game/anim/Anim.cpp @@ -0,0 +1,1097 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../DarkModGlobals.h" + +bool idAnimManager::forceExport = false; + +/*********************************************************************** + + idMD5Anim + +***********************************************************************/ + +/* +==================== +idMD5Anim::idMD5Anim +==================== +*/ +idMD5Anim::idMD5Anim() { + ref_count = 0; + numFrames = 0; + numJoints = 0; + frameRate = 24; + animLength = 0; + totaldelta.Zero(); +} + +/* +==================== +idMD5Anim::idMD5Anim +==================== +*/ +idMD5Anim::~idMD5Anim() { + Free(); +} + +/* +==================== +idMD5Anim::Free +==================== +*/ +void idMD5Anim::Free( void ) { + numFrames = 0; + numJoints = 0; + frameRate = 24; + animLength = 0; + name = ""; + + totaldelta.Zero(); + + jointInfo.Clear(); + bounds.Clear(); + componentFrames.Clear(); +} + +/* +==================== +idMD5Anim::NumFrames +==================== +*/ +int idMD5Anim::NumFrames( void ) const { + return numFrames; +} + +/* +==================== +idMD5Anim::NumJoints +==================== +*/ +int idMD5Anim::NumJoints( void ) const { + return numJoints; +} + +/* +==================== +idMD5Anim::Length +==================== +*/ +int idMD5Anim::Length( void ) const { + return animLength; +} + +/* +===================== +idMD5Anim::TotalMovementDelta +===================== +*/ +const idVec3 &idMD5Anim::TotalMovementDelta( void ) const { + return totaldelta; +} + +/* +===================== +idMD5Anim::TotalMovementDelta +===================== +*/ +const char *idMD5Anim::Name( void ) const { + return name; +} + +/* +==================== +idMD5Anim::Reload +==================== +*/ +bool idMD5Anim::Reload( void ) { + idStr filename; + + filename = name; + Free(); + + return LoadAnim( filename ); +} + +/* +==================== +idMD5Anim::Allocated +==================== +*/ +size_t idMD5Anim::Allocated( void ) const { + size_t size = bounds.Allocated() + jointInfo.Allocated() + componentFrames.Allocated() + name.Allocated(); + return size; +} + +/* +==================== +idMD5Anim::LoadAnim +==================== +*/ +bool idMD5Anim::LoadAnim( const char *filename ) { + int version; + idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT ); + idToken token; + int i, j; + int num; + + if ( !parser.LoadFile( filename ) ) { + return false; + } + + Free(); + + name = filename; + + parser.ExpectTokenString( MD5_VERSION_STRING ); + version = parser.ParseInt(); + if ( version != MD5_VERSION ) { + parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); + } + + // skip the commandline + parser.ExpectTokenString( "commandline" ); + parser.ReadToken( &token ); + + // parse num frames + parser.ExpectTokenString( "numFrames" ); + numFrames = parser.ParseInt(); + if ( numFrames <= 0 ) { + parser.Error( "Invalid number of frames: %d", numFrames ); + } + + // parse num joints + parser.ExpectTokenString( "numJoints" ); + numJoints = parser.ParseInt(); + if ( numJoints <= 0 ) { + parser.Error( "Invalid number of joints: %d", numJoints ); + } + + // parse frame rate + parser.ExpectTokenString( "frameRate" ); + frameRate = parser.ParseInt(); + if ( frameRate < 0 ) { + parser.Error( "Invalid frame rate: %d", frameRate ); + } + + // parse number of animated components + parser.ExpectTokenString( "numAnimatedComponents" ); + numAnimatedComponents = parser.ParseInt(); + if ( ( numAnimatedComponents < 0 ) || ( numAnimatedComponents > numJoints * 6 ) ) { + parser.Error( "Invalid number of animated components: %d", numAnimatedComponents ); + } + + // parse the hierarchy + jointInfo.SetGranularity( 1 ); + jointInfo.SetNum( numJoints ); + parser.ExpectTokenString( "hierarchy" ); + parser.ExpectTokenString( "{" ); + for( i = 0; i < numJoints; i++ ) { + parser.ReadToken( &token ); + jointInfo[ i ].nameIndex = animationLib.JointIndex( token ); + + // parse parent num + jointInfo[ i ].parentNum = parser.ParseInt(); + if ( jointInfo[ i ].parentNum >= i ) { + parser.Error( "Invalid parent num: %d", jointInfo[ i ].parentNum ); + } + + if ( ( i != 0 ) && ( jointInfo[ i ].parentNum < 0 ) ) { + parser.Error( "Animations may have only one root joint" ); + } + + // parse anim bits + jointInfo[ i ].animBits = parser.ParseInt(); + if ( jointInfo[ i ].animBits & ~63 ) { + parser.Error( "Invalid anim bits: %d", jointInfo[ i ].animBits ); + } + + // parse first component + jointInfo[ i ].firstComponent = parser.ParseInt(); + if ( ( numAnimatedComponents > 0 ) && ( ( jointInfo[ i ].firstComponent < 0 ) || ( jointInfo[ i ].firstComponent >= numAnimatedComponents ) ) ) { + parser.Error( "Invalid first component: %d", jointInfo[ i ].firstComponent ); + } + } + + parser.ExpectTokenString( "}" ); + + // parse bounds + parser.ExpectTokenString( "bounds" ); + parser.ExpectTokenString( "{" ); + bounds.SetGranularity( 1 ); + bounds.SetNum( numFrames ); + for( i = 0; i < numFrames; i++ ) { + parser.Parse1DMatrix( 3, bounds[ i ][ 0 ].ToFloatPtr() ); + parser.Parse1DMatrix( 3, bounds[ i ][ 1 ].ToFloatPtr() ); + } + parser.ExpectTokenString( "}" ); + + // parse base frame + baseFrame.SetGranularity( 1 ); + baseFrame.SetNum( numJoints ); + parser.ExpectTokenString( "baseframe" ); + parser.ExpectTokenString( "{" ); + for( i = 0; i < numJoints; i++ ) { + idCQuat q; + parser.Parse1DMatrix( 3, baseFrame[ i ].t.ToFloatPtr() ); + parser.Parse1DMatrix( 3, q.ToFloatPtr() );//baseFrame[ i ].q.ToFloatPtr() ); + baseFrame[ i ].q = q.ToQuat();//.w = baseFrame[ i ].q.CalcW(); + } + parser.ExpectTokenString( "}" ); + + // parse frames + componentFrames.SetGranularity( 1 ); + componentFrames.SetNum( numAnimatedComponents * numFrames ); + + float *componentPtr = componentFrames.Ptr(); + for( i = 0; i < numFrames; i++ ) { + parser.ExpectTokenString( "frame" ); + num = parser.ParseInt(); + if ( num != i ) { + parser.Error( "Expected frame number %d", i ); + } + parser.ExpectTokenString( "{" ); + + for( j = 0; j < numAnimatedComponents; j++, componentPtr++ ) { + *componentPtr = parser.ParseFloat(); + } + + parser.ExpectTokenString( "}" ); + } + + // get total move delta + if ( !numAnimatedComponents ) { + totaldelta.Zero(); + } else { + componentPtr = &componentFrames[ jointInfo[ 0 ].firstComponent ]; + if ( jointInfo[ 0 ].animBits & ANIM_TX ) { + for( i = 0; i < numFrames; i++ ) { + componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.x; + } + totaldelta.x = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; + componentPtr++; + } else { + totaldelta.x = 0.0f; + } + if ( jointInfo[ 0 ].animBits & ANIM_TY ) { + for( i = 0; i < numFrames; i++ ) { + componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.y; + } + totaldelta.y = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; + componentPtr++; + } else { + totaldelta.y = 0.0f; + } + if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { + for( i = 0; i < numFrames; i++ ) { + componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.z; + } + totaldelta.z = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; + } else { + totaldelta.z = 0.0f; + } + } + baseFrame[ 0 ].t.Zero(); + + // we don't count last frame because it would cause a 1 frame pause at the end + animLength = ( ( numFrames - 1 ) * 1000 + frameRate - 1 ) / frameRate; + + // done + return true; +} + +/* +==================== +idMD5Anim::IncreaseRefs +==================== +*/ +void idMD5Anim::IncreaseRefs( void ) const { + ref_count++; +} + +/* +==================== +idMD5Anim::DecreaseRefs +==================== +*/ +void idMD5Anim::DecreaseRefs( void ) const { + ref_count--; +} + +/* +==================== +idMD5Anim::NumRefs +==================== +*/ +int idMD5Anim::NumRefs( void ) const { + return ref_count; +} + +/* +==================== +idMD5Anim::GetFrameBlend +==================== +*/ +void idMD5Anim::GetFrameBlend( int framenum, frameBlend_t &frame ) const { + frame.cycleCount = 0; + frame.backlerp = 0.0f; + frame.frontlerp = 1.0f; + + // frame 1 is first frame + framenum--; + if ( framenum < 0 ) { + framenum = 0; + } else if ( framenum >= numFrames ) { + framenum = numFrames - 1; + } + + frame.frame1 = framenum; + frame.frame2 = framenum; +} + +/* +==================== +idMD5Anim::ConvertTimeToFrame +==================== +*/ +void idMD5Anim::ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const { + int frameTime; + int frameNum; + + if ( numFrames <= 1 ) { + frame.frame1 = 0; + frame.frame2 = 0; + frame.backlerp = 0.0f; + frame.frontlerp = 1.0f; + frame.cycleCount = 0; + return; + } + + if ( time <= 0 ) { + frame.frame1 = 0; + frame.frame2 = 1; + frame.backlerp = 0.0f; + frame.frontlerp = 1.0f; + frame.cycleCount = 0; + return; + } + + frameTime = time * frameRate; + frameNum = frameTime / 1000; + frame.cycleCount = frameNum / ( numFrames - 1 ); + + if ( ( cyclecount > 0 ) && ( frame.cycleCount >= cyclecount ) ) { + frame.cycleCount = cyclecount - 1; + frame.frame1 = numFrames - 1; + frame.frame2 = frame.frame1; + frame.backlerp = 0.0f; + frame.frontlerp = 1.0f; + return; + } + + frame.frame1 = frameNum % ( numFrames - 1 ); + frame.frame2 = frame.frame1 + 1; + if ( frame.frame2 >= numFrames ) { + frame.frame2 = 0; + } + + frame.backlerp = ( frameTime % 1000 ) * 0.001f; + frame.frontlerp = 1.0f - frame.backlerp; +} + +/* +==================== +idMD5Anim::GetOrigin +==================== +*/ +void idMD5Anim::GetOrigin( idVec3 &offset, int time, int cyclecount ) const { + frameBlend_t frame; + + offset = baseFrame[ 0 ].t; + if ( !( jointInfo[ 0 ].animBits & ( ANIM_TX | ANIM_TY | ANIM_TZ ) ) ) { + // just use the baseframe + return; + } + + ConvertTimeToFrame( time, cyclecount, frame ); + + const float *componentPtr1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; + const float *componentPtr2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; + + if ( jointInfo[ 0 ].animBits & ANIM_TX ) { + offset.x = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + componentPtr1++; + componentPtr2++; + } + + if ( jointInfo[ 0 ].animBits & ANIM_TY ) { + offset.y = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + componentPtr1++; + componentPtr2++; + } + + if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { + offset.z = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + } + + if ( frame.cycleCount ) { + offset += totaldelta * ( float )frame.cycleCount; + } +} + +/* +==================== +idMD5Anim::GetOriginRotation +==================== +*/ +void idMD5Anim::GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const { + frameBlend_t frame; + int animBits; + + animBits = jointInfo[ 0 ].animBits; + if ( !( animBits & ( ANIM_QX | ANIM_QY | ANIM_QZ ) ) ) { + // just use the baseframe + rotation = baseFrame[ 0 ].q; + return; + } + + ConvertTimeToFrame( time, cyclecount, frame ); + + const float *jointframe1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; + const float *jointframe2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; + + if ( animBits & ANIM_TX ) { + jointframe1++; + jointframe2++; + } + + if ( animBits & ANIM_TY ) { + jointframe1++; + jointframe2++; + } + + if ( animBits & ANIM_TZ ) { + jointframe1++; + jointframe2++; + } + + idQuat q1; + idQuat q2; + + switch( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { + case ANIM_QX: + q1.x = jointframe1[0]; + q2.x = jointframe2[0]; + q1.y = baseFrame[ 0 ].q.y; + q2.y = q1.y; + q1.z = baseFrame[ 0 ].q.z; + q2.z = q1.z; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QY: + q1.y = jointframe1[0]; + q2.y = jointframe2[0]; + q1.x = baseFrame[ 0 ].q.x; + q2.x = q1.x; + q1.z = baseFrame[ 0 ].q.z; + q2.z = q1.z; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QZ: + q1.z = jointframe1[0]; + q2.z = jointframe2[0]; + q1.x = baseFrame[ 0 ].q.x; + q2.x = q1.x; + q1.y = baseFrame[ 0 ].q.y; + q2.y = q1.y; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QX|ANIM_QY: + q1.x = jointframe1[0]; + q1.y = jointframe1[1]; + q2.x = jointframe2[0]; + q2.y = jointframe2[1]; + q1.z = baseFrame[ 0 ].q.z; + q2.z = q1.z; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QX|ANIM_QZ: + q1.x = jointframe1[0]; + q1.z = jointframe1[1]; + q2.x = jointframe2[0]; + q2.z = jointframe2[1]; + q1.y = baseFrame[ 0 ].q.y; + q2.y = q1.y; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QY|ANIM_QZ: + q1.y = jointframe1[0]; + q1.z = jointframe1[1]; + q2.y = jointframe2[0]; + q2.z = jointframe2[1]; + q1.x = baseFrame[ 0 ].q.x; + q2.x = q1.x; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + case ANIM_QX|ANIM_QY|ANIM_QZ: + q1.x = jointframe1[0]; + q1.y = jointframe1[1]; + q1.z = jointframe1[2]; + q2.x = jointframe2[0]; + q2.y = jointframe2[1]; + q2.z = jointframe2[2]; + q1.w = q1.CalcW(); + q2.w = q2.CalcW(); + break; + } + + rotation.Slerp( q1, q2, frame.backlerp ); +} + +/* +==================== +idMD5Anim::GetBounds +==================== +*/ +void idMD5Anim::GetBounds( idBounds &bnds, int time, int cyclecount ) const { + frameBlend_t frame; + idVec3 offset; + + ConvertTimeToFrame( time, cyclecount, frame ); + + bnds = bounds[ frame.frame1 ]; + bnds.AddBounds( bounds[ frame.frame2 ] ); + + // origin position + offset = baseFrame[ 0 ].t; + if ( jointInfo[ 0 ].animBits & ( ANIM_TX | ANIM_TY | ANIM_TZ ) ) { + const float *componentPtr1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; + const float *componentPtr2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; + + if ( jointInfo[ 0 ].animBits & ANIM_TX ) { + offset.x = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + componentPtr1++; + componentPtr2++; + } + + if ( jointInfo[ 0 ].animBits & ANIM_TY ) { + offset.y = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + componentPtr1++; + componentPtr2++; + } + + if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { + offset.z = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; + } + } + + bnds[ 0 ] -= offset; + bnds[ 1 ] -= offset; +} + +/* +==================== +idMD5Anim::GetInterpolatedFrame +==================== +*/ +void idMD5Anim::GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const { + int i, numLerpJoints; + const float *frame1; + const float *frame2; + const float *jointframe1; + const float *jointframe2; + const jointAnimInfo_t *infoPtr; + int animBits; + idJointQuat *blendJoints; + idJointQuat *jointPtr; + idJointQuat *blendPtr; + int *lerpIndex; + + // copy the baseframe + SIMDProcessor->Memcpy( joints, baseFrame.Ptr(), baseFrame.Num() * sizeof( baseFrame[ 0 ] ) ); + + if ( !numAnimatedComponents ) { + // just use the base frame + return; + } + + blendJoints = (idJointQuat *)_alloca16( baseFrame.Num() * sizeof( blendPtr[ 0 ] ) ); + lerpIndex = (int *)_alloca16( baseFrame.Num() * sizeof( lerpIndex[ 0 ] ) ); + numLerpJoints = 0; + + frame1 = &componentFrames[ frame.frame1 * numAnimatedComponents ]; + frame2 = &componentFrames[ frame.frame2 * numAnimatedComponents ]; + + for ( i = 0; i < numIndexes; i++ ) { + int j = index[i]; + jointPtr = &joints[j]; + blendPtr = &blendJoints[j]; + infoPtr = &jointInfo[j]; + + animBits = infoPtr->animBits; + if ( animBits ) { + + lerpIndex[numLerpJoints++] = j; + + jointframe1 = frame1 + infoPtr->firstComponent; + jointframe2 = frame2 + infoPtr->firstComponent; + + switch( animBits & (ANIM_TX|ANIM_TY|ANIM_TZ) ) { + case 0: + blendPtr->t = jointPtr->t; + break; + case ANIM_TX: + jointPtr->t.x = jointframe1[0]; + blendPtr->t.x = jointframe2[0]; + blendPtr->t.y = jointPtr->t.y; + blendPtr->t.z = jointPtr->t.z; + jointframe1++; + jointframe2++; + break; + case ANIM_TY: + jointPtr->t.y = jointframe1[0]; + blendPtr->t.y = jointframe2[0]; + blendPtr->t.x = jointPtr->t.x; + blendPtr->t.z = jointPtr->t.z; + jointframe1++; + jointframe2++; + break; + case ANIM_TZ: + jointPtr->t.z = jointframe1[0]; + blendPtr->t.z = jointframe2[0]; + blendPtr->t.x = jointPtr->t.x; + blendPtr->t.y = jointPtr->t.y; + jointframe1++; + jointframe2++; + break; + case ANIM_TX|ANIM_TY: + jointPtr->t.x = jointframe1[0]; + jointPtr->t.y = jointframe1[1]; + blendPtr->t.x = jointframe2[0]; + blendPtr->t.y = jointframe2[1]; + blendPtr->t.z = jointPtr->t.z; + jointframe1 += 2; + jointframe2 += 2; + break; + case ANIM_TX|ANIM_TZ: + jointPtr->t.x = jointframe1[0]; + jointPtr->t.z = jointframe1[1]; + blendPtr->t.x = jointframe2[0]; + blendPtr->t.z = jointframe2[1]; + blendPtr->t.y = jointPtr->t.y; + jointframe1 += 2; + jointframe2 += 2; + break; + case ANIM_TY|ANIM_TZ: + jointPtr->t.y = jointframe1[0]; + jointPtr->t.z = jointframe1[1]; + blendPtr->t.y = jointframe2[0]; + blendPtr->t.z = jointframe2[1]; + blendPtr->t.x = jointPtr->t.x; + jointframe1 += 2; + jointframe2 += 2; + break; + case ANIM_TX|ANIM_TY|ANIM_TZ: + jointPtr->t.x = jointframe1[0]; + jointPtr->t.y = jointframe1[1]; + jointPtr->t.z = jointframe1[2]; + blendPtr->t.x = jointframe2[0]; + blendPtr->t.y = jointframe2[1]; + blendPtr->t.z = jointframe2[2]; + jointframe1 += 3; + jointframe2 += 3; + break; + } + + switch( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { + case 0: + blendPtr->q = jointPtr->q; + break; + case ANIM_QX: + jointPtr->q.x = jointframe1[0]; + blendPtr->q.x = jointframe2[0]; + blendPtr->q.y = jointPtr->q.y; + blendPtr->q.z = jointPtr->q.z; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QY: + jointPtr->q.y = jointframe1[0]; + blendPtr->q.y = jointframe2[0]; + blendPtr->q.x = jointPtr->q.x; + blendPtr->q.z = jointPtr->q.z; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QZ: + jointPtr->q.z = jointframe1[0]; + blendPtr->q.z = jointframe2[0]; + blendPtr->q.x = jointPtr->q.x; + blendPtr->q.y = jointPtr->q.y; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QX|ANIM_QY: + jointPtr->q.x = jointframe1[0]; + jointPtr->q.y = jointframe1[1]; + blendPtr->q.x = jointframe2[0]; + blendPtr->q.y = jointframe2[1]; + blendPtr->q.z = jointPtr->q.z; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QX|ANIM_QZ: + jointPtr->q.x = jointframe1[0]; + jointPtr->q.z = jointframe1[1]; + blendPtr->q.x = jointframe2[0]; + blendPtr->q.z = jointframe2[1]; + blendPtr->q.y = jointPtr->q.y; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QY|ANIM_QZ: + jointPtr->q.y = jointframe1[0]; + jointPtr->q.z = jointframe1[1]; + blendPtr->q.y = jointframe2[0]; + blendPtr->q.z = jointframe2[1]; + blendPtr->q.x = jointPtr->q.x; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + case ANIM_QX|ANIM_QY|ANIM_QZ: + jointPtr->q.x = jointframe1[0]; + jointPtr->q.y = jointframe1[1]; + jointPtr->q.z = jointframe1[2]; + blendPtr->q.x = jointframe2[0]; + blendPtr->q.y = jointframe2[1]; + blendPtr->q.z = jointframe2[2]; + jointPtr->q.w = jointPtr->q.CalcW(); + blendPtr->q.w = blendPtr->q.CalcW(); + break; + } + } + } + + SIMDProcessor->BlendJoints( joints, blendJoints, frame.backlerp, lerpIndex, numLerpJoints ); + + if ( frame.cycleCount ) { + joints[ 0 ].t += totaldelta * ( float )frame.cycleCount; + } +} + +/* +==================== +idMD5Anim::GetSingleFrame +==================== +*/ +void idMD5Anim::GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const { + int i; + const float *frame; + const float *jointframe; + int animBits; + idJointQuat *jointPtr; + const jointAnimInfo_t *infoPtr; + + // copy the baseframe + SIMDProcessor->Memcpy( joints, baseFrame.Ptr(), baseFrame.Num() * sizeof( baseFrame[ 0 ] ) ); + + if ( ( framenum == 0 ) || !numAnimatedComponents ) { + // just use the base frame + return; + } + + frame = &componentFrames[ framenum * numAnimatedComponents ]; + + for ( i = 0; i < numIndexes; i++ ) { + int j = index[i]; + jointPtr = &joints[j]; + infoPtr = &jointInfo[j]; + + animBits = infoPtr->animBits; + if ( animBits ) { + + jointframe = frame + infoPtr->firstComponent; + + if ( animBits & (ANIM_TX|ANIM_TY|ANIM_TZ) ) { + + if ( animBits & ANIM_TX ) { + jointPtr->t.x = *jointframe++; + } + + if ( animBits & ANIM_TY ) { + jointPtr->t.y = *jointframe++; + } + + if ( animBits & ANIM_TZ ) { + jointPtr->t.z = *jointframe++; + } + } + + if ( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { + + if ( animBits & ANIM_QX ) { + jointPtr->q.x = *jointframe++; + } + + if ( animBits & ANIM_QY ) { + jointPtr->q.y = *jointframe++; + } + + if ( animBits & ANIM_QZ ) { + jointPtr->q.z = *jointframe; + } + + jointPtr->q.w = jointPtr->q.CalcW(); + } + } + } +} + +/* +==================== +idMD5Anim::CheckModelHierarchy +==================== +*/ +void idMD5Anim::CheckModelHierarchy( const idRenderModel *model ) const { + int i; + int jointNum; + int parent; + + if ( jointInfo.Num() != model->NumJoints() ) { + gameLocal.Error( "Model '%s' has different # of joints than anim '%s'", model->Name(), name.c_str() ); + } + + const idMD5Joint *modelJoints = model->GetJoints(); + for( i = 0; i < jointInfo.Num(); i++ ) { + jointNum = jointInfo[ i ].nameIndex; + if ( modelJoints[ i ].name != animationLib.JointName( jointNum ) ) { + gameLocal.Error( "Model '%s''s joint names don't match anim '%s''s", model->Name(), name.c_str() ); + } + if ( modelJoints[ i ].parent ) { + parent = modelJoints[ i ].parent - modelJoints; + } else { + parent = -1; + } + if ( parent != jointInfo[ i ].parentNum ) { + gameLocal.Error( "Model '%s' has different joint hierarchy than anim '%s'", model->Name(), name.c_str() ); + } + } +} + +/* +==================== +idMD5Anim::SetFrameRate + +(DarkMod Addition) +==================== +*/ + +void idMD5Anim::SetFrameRate( int frRate ) +{ + frameRate = frRate; + DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("ChangeFrameRate: Set rate to %d\r", frameRate); + + return; +} + +/*********************************************************************** + + idAnimManager + +***********************************************************************/ + +/* +==================== +idAnimManager::idAnimManager +==================== +*/ +idAnimManager::idAnimManager() { +} + +/* +==================== +idAnimManager::~idAnimManager +==================== +*/ +idAnimManager::~idAnimManager() { + Shutdown(); +} + +/* +==================== +idAnimManager::Shutdown +==================== +*/ +void idAnimManager::Shutdown( void ) { + animations.DeleteContents(); + jointnames.Clear(); + jointnamesHash.Free(); +} + +/* +==================== +idAnimManager::GetAnim +==================== +*/ +idMD5Anim *idAnimManager::GetAnim( const char *name ) { + idMD5Anim **animptrptr; + idMD5Anim *anim; + + // see if it has been asked for before + animptrptr = NULL; + if ( animations.Get( name, &animptrptr ) ) { + anim = *animptrptr; + } else { + idStr extension; + idStr filename = name; + + filename.ExtractFileExtension( extension ); + if ( extension != MD5_ANIM_EXT ) { + return NULL; + } + + anim = new idMD5Anim(); + if ( !anim->LoadAnim( filename ) ) { + gameLocal.Warning( "Couldn't load anim: '%s'", filename.c_str() ); + delete anim; + anim = NULL; + } + animations.Set( filename, anim ); + } + + return anim; +} + +/* +================ +idAnimManager::ReloadAnims +================ +*/ +void idAnimManager::ReloadAnims( void ) { + int i; + idMD5Anim **animptr; + + for( i = 0; i < animations.Num(); i++ ) { + animptr = animations.GetIndex( i ); + if ( animptr && *animptr ) { + ( *animptr )->Reload(); + } + } +} + +/* +================ +idAnimManager::JointIndex +================ +*/ +int idAnimManager::JointIndex( const char *name ) { + int i, hash; + + hash = jointnamesHash.GenerateKey( name ); + for ( i = jointnamesHash.First( hash ); i != -1; i = jointnamesHash.Next( i ) ) { + if ( jointnames[i].Cmp( name ) == 0 ) { + return i; + } + } + + i = jointnames.Append( name ); + jointnamesHash.Add( hash, i ); + return i; +} + +/* +================ +idAnimManager::JointName +================ +*/ +const char *idAnimManager::JointName( int index ) const { + return jointnames[ index ]; +} + +/* +================ +idAnimManager::ListAnims +================ +*/ +void idAnimManager::ListAnims( void ) const { + int i; + idMD5Anim **animptr; + idMD5Anim *anim; + size_t size; + size_t s; + size_t namesize; + int num; + + num = 0; + size = 0; + for( i = 0; i < animations.Num(); i++ ) { + animptr = animations.GetIndex( i ); + if ( animptr && *animptr ) { + anim = *animptr; + s = anim->Size(); + gameLocal.Printf( "%8d bytes : %2d refs : %s\n", s, anim->NumRefs(), anim->Name() ); + size += s; + num++; + } + } + + namesize = jointnames.Size() + jointnamesHash.Size(); + for( i = 0; i < jointnames.Num(); i++ ) { + namesize += jointnames[ i ].Size(); + } + + gameLocal.Printf( "\n%d memory used in %d anims\n", size, num ); + gameLocal.Printf( "%d memory used in %d joint names\n", namesize, jointnames.Num() ); +} + +/* +================ +idAnimManager::FlushUnusedAnims +================ +*/ +void idAnimManager::FlushUnusedAnims( void ) { + int i; + idMD5Anim **animptr; + idList removeAnims; + + for( i = 0; i < animations.Num(); i++ ) { + animptr = animations.GetIndex( i ); + if ( animptr && *animptr ) { + if ( ( *animptr )->NumRefs() <= 0 ) { + removeAnims.Append( *animptr ); + } + } + } + + for( i = 0; i < removeAnims.Num(); i++ ) { + animations.Remove( removeAnims[ i ]->Name() ); + delete removeAnims[ i ]; + } +} diff --git a/game/anim/Anim.h b/game/anim/Anim.h new file mode 100644 index 000000000..18ca3b727 --- /dev/null +++ b/game/anim/Anim.h @@ -0,0 +1,702 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __ANIM_H__ +#define __ANIM_H__ + +#ifdef __linux__ +#include "../../framework/DeclManager.h" +#endif + +// +// animation channels +// these can be changed by modmakers and licensees to be whatever they need. +const int ANIM_NumAnimChannels = 5; +const int ANIM_MaxAnimsPerChannel = 3; +const int ANIM_MaxSyncedAnims = 3; + +// +// animation channels. make sure to change script/doom_defs.script if you add any channels, or change their order +// +const int ANIMCHANNEL_ALL = 0; +const int ANIMCHANNEL_TORSO = 1; +const int ANIMCHANNEL_LEGS = 2; +const int ANIMCHANNEL_HEAD = 3; +const int ANIMCHANNEL_EYELIDS = 4; + +// for converting from 24 frames per second to milliseconds +ID_INLINE int FRAME2MS( int framenum ) { + return ( framenum * 1000 ) / 24; +} + +class idRenderModel; +class idAnimator; +class idAnimBlend; +class function_t; +class idEntity; +class idSaveGame; +class idRestoreGame; + +typedef struct { + int cycleCount; // how many times the anim has wrapped to the begining (0 for clamped anims) + int frame1; + int frame2; + float frontlerp; + float backlerp; +} frameBlend_t; + +typedef struct { + int nameIndex; + int parentNum; + int animBits; + int firstComponent; +} jointAnimInfo_t; + +typedef struct { + jointHandle_t num; + jointHandle_t parentNum; + int channel; +} jointInfo_t; + +// +// joint modifier modes. make sure to change script/doom_defs.script if you add any, or change their order. +// +typedef enum { + JOINTMOD_NONE, // no modification + JOINTMOD_LOCAL, // modifies the joint's position or orientation in joint local space + JOINTMOD_LOCAL_OVERRIDE, // sets the joint's position or orientation in joint local space + JOINTMOD_WORLD, // modifies joint's position or orientation in model space + JOINTMOD_WORLD_OVERRIDE // sets the joint's position or orientation in model space +} jointModTransform_t; + +typedef struct { + jointHandle_t jointnum; + idMat3 mat; + idVec3 pos; + jointModTransform_t transform_pos; + jointModTransform_t transform_axis; +} jointMod_t; + +#define ANIM_TX BIT( 0 ) +#define ANIM_TY BIT( 1 ) +#define ANIM_TZ BIT( 2 ) +#define ANIM_QX BIT( 3 ) +#define ANIM_QY BIT( 4 ) +#define ANIM_QZ BIT( 5 ) + +typedef enum { + FC_SCRIPTFUNCTION, + FC_SCRIPTFUNCTIONOBJECT, + FC_EVENTFUNCTION, + FC_SOUND, + FC_SOUND_VOICE, + FC_SOUND_VOICE2, + FC_SOUND_BODY, + FC_SOUND_BODY2, + FC_SOUND_BODY3, + FC_SOUND_WEAPON, + FC_SOUND_ITEM, + FC_SOUND_GLOBAL, + FC_SOUND_CHATTER, + FC_SKIN, + FC_TRIGGER, + FC_TRIGGER_SMOKE_PARTICLE, + FC_MELEE, + FC_DIRECTDAMAGE, + FC_BEGINATTACK, + FC_ENDATTACK, + FC_MUZZLEFLASH, + FC_CREATEMISSILE, + FC_LAUNCHMISSILE, + FC_FIREMISSILEATTARGET, + FC_FOOTSTEP, + FC_LEFTFOOT, + FC_RIGHTFOOT, + FC_ENABLE_EYE_FOCUS, + FC_DISABLE_EYE_FOCUS, + FC_FX, + FC_DISABLE_GRAVITY, + FC_ENABLE_GRAVITY, + FC_JUMP, + FC_ENABLE_CLIP, + FC_DISABLE_CLIP, + FC_ENABLE_WALK_IK, + FC_DISABLE_WALK_IK, + FC_ENABLE_LEG_IK, + FC_DISABLE_LEG_IK, + FC_RECORDDEMO, + FC_AVIGAME, + +/** +* DarkMod: +* FC_SETRATE sets the anim rate, used for speeding up/slowing down walking +* and crouchwalking animations to get correct footstep sounds. +**/ + FC_SETRATE, +/** +* Move an attachment to a different position +**/ + FC_REATTACH, +/** +* Tels: Spawn an item (the item contains where to attach it) +**/ + FC_ATTACH, +/** +* Tels: Detach and destroy the named attachement +**/ + FC_DESTROY, +/** +* Tels: Detach and drop the named attachement +**/ + FC_DROP, +/** +* Tels: Detach and put down the named attachement (e.g. restore origin and angles to "before pickup") +**/ + FC_PUTDOWN, +/** +* Tels: Pickup an object (either the direct entity name, or the AIUSE class) +**/ + FC_PICKUP, +/** +* Tels: Activate the attached entity at the named joint +**/ + FC_ACTIVATE_AT_JOINT, +/** +* Tels: Activate the entity (either direct name or AIUSE class) +**/ + FC_ACTIVATE_NEAR, +/** +* Pause the animation at its current frame, wait for unpause from somewhere else +**/ + FC_PAUSE, +/** +* Holds a melee attack at a given point in the animation +* (e.g., at the back swing in attacks, at the parry position in parries) +* Similar to pause but also updates actor's melee status +**/ + FC_MELEE_HOLD, + FC_MELEE_ATTACK_START, + FC_MELEE_ATTACK_STOP, + FC_MELEE_PARRY_START, + FC_MELEE_PARRY_STOP, + FC_SET_ATTACK_FLAG, // greebo: enables a certain attack type + FC_CLEAR_ATTACK_FLAG, // greebo: disables a certain attack type + FC_CREATEMISSILE_FROM_DEF, // greebo: create a specific projectile def for ranged attack +} frameCommandType_t; + +typedef struct { + int num; + int firstCommand; +} frameLookup_t; + +typedef struct { + frameCommandType_t type; + idStr *string; + + union { + const idSoundShader *soundShader; + const function_t *function; + const idDeclSkin *skin; + int index; + }; +} frameCommand_t; + +typedef struct { + bool prevent_idle_override : 1; + bool random_cycle_start : 1; + bool ai_no_turn : 1; + bool anim_turn : 1; + bool no_random_headturning : 1; +} animFlags_t; + + +/* +============================================================================================== + + idModelExport + +============================================================================================== +*/ + +class idModelExport { +private: + void Reset( void ); + bool ParseOptions( idLexer &lex ); + int ParseExportSection( idParser &parser ); + + static bool CheckMayaInstall( void ); + static void LoadMayaDll( void ); + + bool ConvertMayaToMD5( void ); + static bool initialized; + +public: + idStr commandLine; + idStr src; + idStr dest; + bool force; + + idModelExport(); + + static void Shutdown( void ); + + int ExportDefFile( const char *filename ); + bool ExportModel( const char *model ); + bool ExportAnim( const char *anim ); + int ExportModels( const char *pathname, const char *extension ); +}; + +/* +============================================================================================== + + idMD5Anim + +============================================================================================== +*/ + +class idMD5Anim { +private: + int numFrames; + int frameRate; + int animLength; + int numJoints; + int numAnimatedComponents; + idList bounds; + idList jointInfo; + idList baseFrame; + idList componentFrames; + idStr name; + idVec3 totaldelta; + mutable int ref_count; + +public: + idMD5Anim(); + ~idMD5Anim(); + + void Free( void ); + bool Reload( void ); + size_t Allocated( void ) const; + size_t Size( void ) const { return sizeof( *this ) + Allocated(); }; + bool LoadAnim( const char *filename ); + + void IncreaseRefs( void ) const; + void DecreaseRefs( void ) const; + int NumRefs( void ) const; + + void CheckModelHierarchy( const idRenderModel *model ) const; + void GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const; + void GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const; + int Length( void ) const; + int NumFrames( void ) const; + int NumJoints( void ) const; + const idVec3 &TotalMovementDelta( void ) const; + const char *Name( void ) const; + + void GetFrameBlend( int framenum, frameBlend_t &frame ) const; // frame 1 is first frame + void ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const; + + void GetOrigin( idVec3 &offset, int currentTime, int cyclecount ) const; + void GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const; + void GetBounds( idBounds &bounds, int currentTime, int cyclecount ) const; + + /** + * DarkMod: Set the framerate to something different from what's in the file. + **/ + void SetFrameRate( int frRate ); +}; + +/* +============================================================================================== + + idAnim + +============================================================================================== +*/ + +class idAnim { +private: + const class idDeclModelDef *modelDef; + const idMD5Anim *anims[ ANIM_MaxSyncedAnims ]; + int numAnims; + idStr name; + idStr realname; + idList frameLookup; + idList frameCommands; + animFlags_t flags; + +public: + idAnim(); + idAnim( const idDeclModelDef *modelDef, const idAnim *anim ); + ~idAnim(); + + void SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] ); + const char *Name( void ) const; + const char *FullName( void ) const; + const idMD5Anim *MD5Anim( int num ) const; + const idDeclModelDef *ModelDef( void ) const; + int Length( void ) const; + int NumFrames( void ) const; + int NumAnims( void ) const; + const idVec3 &TotalMovementDelta( void ) const; + bool GetOrigin( idVec3 &offset, int animNum, int time, int cyclecount ) const; + bool GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const; + bool GetBounds( idBounds &bounds, int animNum, int time, int cyclecount ) const; + const char *AddFrameCommand( const class idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def ); + void CallFrameCommands( idEntity *ent, int from, int to, idAnimBlend *caller ); + bool HasFrameCommands( void ) const; + + // returns first frame (zero based) that command occurs. returns -1 if not found. + int FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const; + void SetAnimFlags( const animFlags_t &animflags ); + const animFlags_t &GetAnimFlags( void ) const; +}; + +/* +============================================================================================== + + idDeclModelDef + +============================================================================================== +*/ + +class idDeclModelDef : public idDecl { +public: + idDeclModelDef(); + ~idDeclModelDef(); + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + + void Touch( void ) const; + + const idDeclSkin * GetDefaultSkin( void ) const; + const idJointQuat * GetDefaultPose( void ) const; + void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const; + idRenderModel * ModelHandle( void ) const; + void GetJointList( const char *jointnames, idList &jointList ) const; + const jointInfo_t * FindJoint( const char *name ) const; + + int NumAnims( void ) const; + const idAnim * GetAnim( int index ) const; + int GetSpecificAnim( const char *name ) const; + int GetAnim( const char *name ) const; + bool HasAnim( const char *name ) const; + const idDeclSkin * GetSkin( void ) const; + const char * GetModelName( void ) const; + const idList & Joints( void ) const; + const int * JointParents( void ) const; + int NumJoints( void ) const; + const jointInfo_t * GetJoint( int jointHandle ) const; + const char * GetJointName( int jointHandle ) const; + int NumJointsOnChannel( int channel ) const; + const int * GetChannelJoints( int channel ) const; + + const idVec3 & GetVisualOffset( void ) const; + +private: + void CopyDecl( const idDeclModelDef *decl ); + bool ParseAnim( idLexer &src, int numDefaultAnims ); + +private: + idVec3 offset; + idList joints; + idList jointParents; + idList channelJoints[ ANIM_NumAnimChannels ]; + idRenderModel * modelHandle; + idList anims; + const idDeclSkin * skin; +}; + +/* +============================================================================================== + + idAnimBlend + +============================================================================================== +*/ + +class idAnimBlend { +private: + const class idDeclModelDef *modelDef; + int starttime; + int endtime; + int timeOffset; + float rate; + + int blendStartTime; + int blendDuration; + float blendStartValue; + float blendEndValue; + + float animWeights[ ANIM_MaxSyncedAnims ]; + short cycle; + short frame; + short animNum; + bool allowMove; + bool allowFrameCommands; + /** + * TDM: This animation is paused at the current frame + **/ + bool m_bPaused; + /** + * endtime and cycle before we paused + * The following are used for proper re-entry when unpausing + **/ + int m_PausedEndtime; + short m_PausedCycle; + /** + * Time at which we paused + **/ + int m_PausedTime; + + friend class idAnimator; + + void Reset( const idDeclModelDef *_modelDef ); + void CallFrameCommands( idEntity *ent, int fromtime, int totime ) const; + void SetFrame( const idDeclModelDef *modelDef, int animnum, int frame, int currenttime, int blendtime, const idEntity *ent ); + void CycleAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime, const idEntity *ent ); + void PlayAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime, const idEntity *ent ); + bool BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOrigin, bool overrideBlend, bool printInfo ) const; + void BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const; + void BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const; + void BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const; + bool AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const; + +public: + idAnimBlend(); + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef ); + const char *AnimName( void ) const; + const char *AnimFullName( void ) const; + float GetWeight( int currenttime ) const; + float GetFinalWeight( void ) const; + void SetWeight( float newweight, int currenttime, int blendtime ); + int NumSyncedAnims( void ) const; + bool SetSyncedAnimWeight( int num, float weight ); + void Clear( int currentTime, int clearTime ); + bool IsDone( int currentTime ) const; + bool FrameHasChanged( int currentTime ) const; + int GetCycleCount( void ) const; + void SetCycleCount( int count ); + void SetPlaybackRate( int currentTime, float newRate ); + float GetPlaybackRate( void ) const; + // Ishtvan test: Making this public + /** TDM: UpdatePlaybackRate sets the playback rate to the one given by animnum in ent->m_animRates */ + void UpdatePlaybackRate(int animnum, const idEntity *ent); + void SetStartTime( int startTime ); + int GetStartTime( void ) const; + int GetEndTime( void ) const; + int GetFrameNumber( int currenttime ) const; + int AnimTime( int currenttime ) const; + int NumFrames( void ) const; + int Length( void ) const; + int PlayLength( void ) const; + void AllowMovement( bool allow ); + void AllowFrameCommands( bool allow ); + const idAnim *Anim( void ) const; + int AnimNum( void ) const; + /** + * Pause (true) or unpause (false) the animation at the current frame + **/ + void Pause( bool bPause ); + bool IsPaused( void ); +}; + +/* +============================================================================================== + + idAFPoseJointMod + +============================================================================================== +*/ + +typedef enum { + AF_JOINTMOD_AXIS, + AF_JOINTMOD_ORIGIN, + AF_JOINTMOD_BOTH, + AF_JOINTMOD_NONE // Added for TDM +} AFJointModType_t; + +class idAFPoseJointMod { +public: + idAFPoseJointMod( void ); + + AFJointModType_t mod; + idMat3 axis; + idVec3 origin; +}; + +ID_INLINE idAFPoseJointMod::idAFPoseJointMod( void ) { + mod = AF_JOINTMOD_AXIS; + axis.Identity(); + origin.Zero(); +} + +/* +============================================================================================== + + idAnimator + +============================================================================================== +*/ + +class idAnimator { +public: + idAnimator(); + ~idAnimator(); + + size_t Allocated( void ) const; + size_t Size( void ) const; + + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void SetEntity( idEntity *ent ); + idEntity *GetEntity( void ) const ; + void RemoveOriginOffset( bool remove ); + bool RemoveOrigin( void ) const; + + void GetJointList( const char *jointnames, idList &jointList ) const; + + int NumAnims( void ) const; + const idAnim *GetAnim( int index ) const; + int GetAnim( const char *name ) const; + bool HasAnim( const char *name ) const; + + void ServiceAnims( int fromtime, int totime ); + bool IsAnimating( int currentTime ) const; + + void GetJoints( int *numJoints, idJointMat **jointsPtr ); + int NumJoints( void ) const; + jointHandle_t GetFirstChild( jointHandle_t jointnum ) const; + jointHandle_t GetFirstChild( const char *name ) const; + + idRenderModel *SetModel( const char *modelname ); + idRenderModel *ModelHandle( void ) const; + const idDeclModelDef *ModelDef( void ) const; + + void ForceUpdate( void ); + void ClearForceUpdate( void ); + bool CreateFrame( int animtime, bool force ); + bool FrameHasChanged( int animtime ) const; + void GetDelta( int fromtime, int totime, idVec3 &delta ) const; + bool GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const; + void GetOrigin( int currentTime, idVec3 &pos ) const; + bool GetBounds( int currentTime, idBounds &bounds ); + + idAnimBlend *CurrentAnim( int channelNum ); + void Clear( int channelNum, int currentTime, int cleartime ); + void SetFrame( int channelNum, int animnum, int frame, int currenttime, int blendtime ); + void CycleAnim( int channelNum, int animnum, int currenttime, int blendtime ); + void PlayAnim( int channelNum, int animnum, int currenttime, int blendTime ); + + // copies the current anim from fromChannelNum to channelNum. + // the copied anim will have frame commands disabled to avoid executing them twice. + void SyncAnimChannels( int channelNum, int fromChannelNum, int currenttime, int blendTime ); + + void SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ); + void SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat ); + void ClearJoint( jointHandle_t jointnum ); + void ClearAllJoints( void ); + + void InitAFPose( void ); + void SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin ); + void FinishAFPose( int animnum, const idBounds &bounds, const int time ); + void SetAFPoseBlendWeight( float blendWeight ); + bool BlendAFPose( idJointQuat *blendFrame ) const; + void ClearAFPose( void ); + + void ClearAllAnims( int currentTime, int cleartime ); + + jointHandle_t GetJointHandle( const char *name ) const; + const char * GetJointName( jointHandle_t handle ) const; + int GetChannelForJoint( jointHandle_t joint ) const; + bool GetJointTransform( jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis ); + bool GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ); + + const animFlags_t GetAnimFlags( int animnum ) const; + int NumFrames( int animnum ) const; + int NumSyncedAnims( int animnum ) const; + const char *AnimName( int animnum ) const; + const char *AnimFullName( int animnum ) const; + int AnimLength( int animnum ) const; + const idVec3 &TotalMovementDelta( int animnum ) const; + +private: + void FreeData( void ); + void PushAnims( int channel, int currentTime, int blendTime ); + +private: + const idDeclModelDef * modelDef; + idEntity * entity; + + idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ]; + idList jointMods; + int numJoints; + idJointMat * joints; + + mutable int lastTransformTime; // mutable because the value is updated in CreateFrame + mutable bool stoppedAnimatingUpdate; + bool removeOriginOffset; + bool forceUpdate; + + idBounds frameBounds; + + float AFPoseBlendWeight; + idList AFPoseJoints; + idList AFPoseJointMods; + idList AFPoseJointFrame; + idBounds AFPoseBounds; + int AFPoseTime; +}; + +/* +============================================================================================== + + idAnimManager + +============================================================================================== +*/ + +class idAnimManager { +public: + idAnimManager(); + ~idAnimManager(); + + static bool forceExport; + + void Shutdown( void ); + idMD5Anim * GetAnim( const char *name ); + void ReloadAnims( void ); + void ListAnims( void ) const; + int JointIndex( const char *name ); + const char * JointName( int index ) const; + + void ClearAnimsInUse( void ); + void FlushUnusedAnims( void ); + +private: + idHashTable animations; + idStrList jointnames; + idHashIndex jointnamesHash; +}; + +#endif /* !__ANIM_H__ */ diff --git a/game/anim/Anim_Blend.cpp b/game/anim/Anim_Blend.cpp new file mode 100644 index 000000000..918b96a76 --- /dev/null +++ b/game/anim/Anim_Blend.cpp @@ -0,0 +1,5888 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../DarkModGlobals.h" +#include "../MeleeWeapon.h" +#include "../ai/Tasks/SingleBarkTask.h" + +static const char *channelNames[ ANIM_NumAnimChannels ] = { + "all", "torso", "legs", "head", "eyelids" +}; + +// how many units to displace to-be-dropped entity down to avoid collision with hand +#define DROP_DOWN_ADJUSTMENT 20.0f +// max distance between joint and object we pickup, anything farther is ignored +#define MAX_PICKUP_DIST 40.0f +// max distance between joint and object we try to activate, anything farther is ignored +#define MAX_ACTIVATE_DIST 50.0f + +/*********************************************************************** + + idAnim + +***********************************************************************/ + +/* +===================== +idAnim::idAnim +===================== +*/ +idAnim::idAnim() { + modelDef = NULL; + numAnims = 0; + memset( anims, 0, sizeof( anims ) ); + memset( &flags, 0, sizeof( flags ) ); +} + +/* +===================== +idAnim::idAnim +===================== +*/ +idAnim::idAnim( const idDeclModelDef *modelDef, const idAnim *anim ) { + int i; + + this->modelDef = modelDef; + numAnims = anim->numAnims; + name = anim->name; + realname = anim->realname; + flags = anim->flags; + + memset( anims, 0, sizeof( anims ) ); + for( i = 0; i < numAnims; i++ ) { + anims[ i ] = anim->anims[ i ]; + anims[ i ]->IncreaseRefs(); + } + + frameLookup.SetNum( anim->frameLookup.Num() ); + memcpy( frameLookup.Ptr(), anim->frameLookup.Ptr(), frameLookup.MemoryUsed() ); + + frameCommands.SetNum( anim->frameCommands.Num() ); + for( i = 0; i < frameCommands.Num(); i++ ) { + frameCommands[ i ] = anim->frameCommands[ i ]; + if ( anim->frameCommands[ i ].string ) { + frameCommands[ i ].string = new idStr( *anim->frameCommands[ i ].string ); + } + } +} + +/* +===================== +idAnim::~idAnim +===================== +*/ +idAnim::~idAnim() { + int i; + + for( i = 0; i < numAnims; i++ ) { + anims[ i ]->DecreaseRefs(); + } + + for( i = 0; i < frameCommands.Num(); i++ ) { + delete frameCommands[ i ].string; + } +} + +/* +===================== +idAnim::SetAnim +===================== +*/ +void idAnim::SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] ) { + int i; + + this->modelDef = modelDef; + + for( i = 0; i < numAnims; i++ ) { + anims[ i ]->DecreaseRefs(); + anims[ i ] = NULL; + } + + assert( ( num > 0 ) && ( num <= ANIM_MaxSyncedAnims ) ); + numAnims = num; + realname = sourcename; + name = animname; + + for( i = 0; i < num; i++ ) { + anims[ i ] = md5anims[ i ]; + anims[ i ]->IncreaseRefs(); + } + + memset( &flags, 0, sizeof( flags ) ); + + for( i = 0; i < frameCommands.Num(); i++ ) { + delete frameCommands[ i ].string; + } + + frameLookup.Clear(); + frameCommands.Clear(); +} + +/* +===================== +idAnim::Name +===================== +*/ +const char *idAnim::Name( void ) const { + return name; +} + +/* +===================== +idAnim::FullName +===================== +*/ +const char *idAnim::FullName( void ) const { + return realname; +} + +/* +===================== +idAnim::MD5Anim + +index 0 will never be NULL. Any anim >= NumAnims will return NULL. +===================== +*/ +const idMD5Anim *idAnim::MD5Anim( int num ) const { + if ( anims == NULL || anims[0] == NULL ) { + return NULL; + } + return anims[ num ]; +} + +/* +===================== +idAnim::ModelDef +===================== +*/ +const idDeclModelDef *idAnim::ModelDef( void ) const { + return modelDef; +} + +/* +===================== +idAnim::Length +===================== +*/ +int idAnim::Length( void ) const { + if ( !anims[ 0 ] ) { + return 0; + } + + return anims[ 0 ]->Length(); +} + +/* +===================== +idAnim::NumFrames +===================== +*/ +int idAnim::NumFrames( void ) const { + if ( !anims[ 0 ] ) { + return 0; + } + + return anims[ 0 ]->NumFrames(); +} + +/* +===================== +idAnim::NumAnims +===================== +*/ +int idAnim::NumAnims( void ) const { + return numAnims; +} + +/* +===================== +idAnim::TotalMovementDelta +===================== +*/ +const idVec3 &idAnim::TotalMovementDelta( void ) const { + if ( !anims[ 0 ] ) { + return vec3_zero; + } + + return anims[ 0 ]->TotalMovementDelta(); +} + +/* +===================== +idAnim::GetOrigin +===================== +*/ +bool idAnim::GetOrigin( idVec3 &offset, int animNum, int currentTime, int cyclecount ) const { + if ( !anims[ animNum ] ) { + offset.Zero(); + return false; + } + + anims[ animNum ]->GetOrigin( offset, currentTime, cyclecount ); + return true; +} + +/* +===================== +idAnim::GetOriginRotation +===================== +*/ +bool idAnim::GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const { + if ( !anims[ animNum ] ) { + rotation.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + return false; + } + + anims[ animNum ]->GetOriginRotation( rotation, currentTime, cyclecount ); + return true; +} + +/* +===================== +idAnim::GetBounds +===================== +*/ +ID_INLINE bool idAnim::GetBounds( idBounds &bounds, int animNum, int currentTime, int cyclecount ) const { + if ( !anims[ animNum ] ) { + return false; + } + + anims[ animNum ]->GetBounds( bounds, currentTime, cyclecount ); + return true; +} + + +/* +===================== +idAnim::AddFrameCommand + +Returns NULL if no error. +===================== +*/ +const char *idAnim::AddFrameCommand( const idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def ) { + int i; + int index; + idStr text; + idStr funcname; + frameCommand_t fc; + idToken token; + const jointInfo_t *jointInfo; + + // make sure we're within bounds + if ( ( framenum < 1 ) || ( framenum > anims[ 0 ]->NumFrames() ) ) { + return va( "Frame %d out of range", framenum ); + } + + // frame numbers are 1 based in .def files, but 0 based internally + framenum--; + + memset( &fc, 0, sizeof( fc ) ); + + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + if ( token == "call" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SCRIPTFUNCTION; + fc.function = gameLocal.program.FindFunction( token ); + if ( !fc.function ) { + return va( "Function '%s' not found", token.c_str() ); + } + } else if ( token == "object_call" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SCRIPTFUNCTIONOBJECT; + fc.string = new idStr( token ); + } else if ( token == "event" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_EVENTFUNCTION; + const idEventDef *ev = idEventDef::FindEvent( token ); + if ( !ev ) { + return va( "Event '%s' not found", token.c_str() ); + } + if ( ev->GetNumArgs() != 0 ) { + return va( "Event '%s' has arguments", token.c_str() ); + } + fc.string = new idStr( token ); + } else if ( token == "sound" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_voice" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_VOICE; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_voice2" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_VOICE2; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_body" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_BODY; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_body2" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_BODY2; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_body3" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_BODY3; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_weapon" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_WEAPON; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_global" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_GLOBAL; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_item" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_ITEM; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "sound_chatter" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SOUND_CHATTER; + if ( !token.Cmpn( "snd_", 4 ) ) { + fc.string = new idStr( token ); + } else { + fc.soundShader = declManager->FindSound( token ); + if ( fc.soundShader->GetState() == DS_DEFAULTED ) { + gameLocal.Warning( "Sound '%s' not found", token.c_str() ); + } + } + } else if ( token == "skin" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_SKIN; + if ( token == "none" ) { + fc.skin = NULL; + } else { + fc.skin = declManager->FindSkin( token ); + if ( !fc.skin ) { + return va( "Skin '%s' not found", token.c_str() ); + } + } + } else if ( token == "fx" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_FX; + if ( !declManager->FindType( DECL_FX, token.c_str() ) ) { + return va( "fx '%s' not found", token.c_str() ); + } + fc.string = new idStr( token ); + } else if ( token == "trigger" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_TRIGGER; + fc.string = new idStr( token ); + } else if ( token == "triggerSmokeParticle" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_TRIGGER_SMOKE_PARTICLE; + fc.string = new idStr( token ); + } else if ( token == "melee" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_MELEE; + if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { + return va( "Unknown entityDef '%s'", token.c_str() ); + } + fc.string = new idStr( token ); + } else if ( token == "direct_damage" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_DIRECTDAMAGE; + if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { + return va( "Unknown entityDef '%s'", token.c_str() ); + } + fc.string = new idStr( token ); + } else if ( token == "attack_begin" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_BEGINATTACK; + if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { + return va( "Unknown entityDef '%s'", token.c_str() ); + } + fc.string = new idStr( token ); + } else if ( token == "attack_end" ) { + fc.type = FC_ENDATTACK; + } else if ( token == "muzzle_flash" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + if ( ( token != "" ) && !modelDef->FindJoint( token ) ) { + return va( "Joint '%s' not found", token.c_str() ); + } + fc.type = FC_MUZZLEFLASH; + fc.string = new idStr( token ); + } else if ( token == "muzzle_flash" ) { + fc.type = FC_MUZZLEFLASH; + fc.string = new idStr( "" ); + } else if ( token == "create_missile" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + if ( !modelDef->FindJoint( token ) ) { + return va( "Joint '%s' not found", token.c_str() ); + } + fc.type = FC_CREATEMISSILE; + fc.string = new idStr( token ); + } + else if (token == "create_missile_from_def" ) + { + // Read def name + if (!src.ReadTokenOnLine(&token)) + { + return "Unexpected end of line"; + } + + idStr projectileDefName = token; + + assert(projectileDefName.Length() > 0); + + // Read joint name + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + + if ( !modelDef->FindJoint( token ) ) { + return va( "Joint '%s' not found", token.c_str() ); + } + + fc.type = FC_CREATEMISSILE_FROM_DEF; + + // Connect the projectile def and joint name with a pipe and store that + fc.string = new idStr(projectileDefName + "|" + token); + } + else if ( token == "launch_missile" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + if ( !modelDef->FindJoint( token ) ) { + return va( "Joint '%s' not found", token.c_str() ); + } + fc.type = FC_LAUNCHMISSILE; + fc.string = new idStr( token ); + } else if ( token == "fire_missile_at_target" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + jointInfo = modelDef->FindJoint( token ); + if ( !jointInfo ) { + return va( "Joint '%s' not found", token.c_str() ); + } + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_FIREMISSILEATTARGET; + fc.string = new idStr( token ); + fc.index = jointInfo->num; + } else if ( token == "footstep" ) { + fc.type = FC_FOOTSTEP; + } else if ( token == "leftfoot" ) { + fc.type = FC_LEFTFOOT; + } else if ( token == "rightfoot" ) { + fc.type = FC_RIGHTFOOT; + } else if ( token == "enableEyeFocus" ) { + fc.type = FC_ENABLE_EYE_FOCUS; + } else if ( token == "disableEyeFocus" ) { + fc.type = FC_DISABLE_EYE_FOCUS; + } else if ( token == "disableGravity" ) { + fc.type = FC_DISABLE_GRAVITY; + } else if ( token == "enableGravity" ) { + fc.type = FC_ENABLE_GRAVITY; + } else if ( token == "jump" ) { + fc.type = FC_JUMP; + } else if ( token == "enableClip" ) { + fc.type = FC_ENABLE_CLIP; + } else if ( token == "disableClip" ) { + fc.type = FC_DISABLE_CLIP; + } else if ( token == "enableWalkIK" ) { + fc.type = FC_ENABLE_WALK_IK; + } else if ( token == "disableWalkIK" ) { + fc.type = FC_DISABLE_WALK_IK; + } else if ( token == "enableLegIK" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_ENABLE_LEG_IK; + fc.index = atoi( token ); + } else if ( token == "disableLegIK" ) { + if( !src.ReadTokenOnLine( &token ) ) { + return "Unexpected end of line"; + } + fc.type = FC_DISABLE_LEG_IK; + fc.index = atoi( token ); + } else if ( token == "recordDemo" ) { + fc.type = FC_RECORDDEMO; + if( src.ReadTokenOnLine( &token ) ) { + fc.string = new idStr( token ); + } + } else if ( token == "aviGame" ) { + fc.type = FC_AVIGAME; + if( src.ReadTokenOnLine( &token ) ) { + fc.string = new idStr( token ); + } + } else if (token == "setRate" ) + { + if( !src.ReadTokenOnLine( &token ) ) + { + DM_LOG(LC_MISC, LT_ERROR)LOGSTRING("ANIMRATE: Did not find rate, exiting\r"); + return "Unexpected end of line"; + } + + fc.type = FC_SETRATE; + fc.string = new idStr( token ); + } + else if ( token == "reattach" ) + { + // first argument (name of attachment to reattach) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_REATTACH; + fc.string = new idStr( token ); + + // second argument (attach position) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + } + // tels: spawn and attach a new entity + else if ( token == "attach" ) + { + // first argument (class of entity to spawn) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_ATTACH; + fc.string = new idStr( token ); + + // second argument (attach name, optional) + if( src.ReadTokenOnLine( &token ) ) + { + fc.string->Append(va(" %s", token.c_str() )); + } + // third argument (attach position, optional) + if( src.ReadTokenOnLine( &token ) ) + { + fc.string->Append(va(" %s", token.c_str() )); + } + + } + // tels: + else if ( token == "destroy" ) + { + // first argument (attachment name) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_DESTROY; + fc.string = new idStr( token ); + } + // tels: detach entity, put a bit down and let it fall + else if ( token == "drop" ) + { + // first argument (attachment name) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_DROP; + fc.string = new idStr( token ); + } + // tels: detach entity and set or restore it's position + else if ( token == "putdown" ) + { + // first argument (attachment name) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_PUTDOWN; + fc.string = new idStr( token ); + } + // tels: + else if ( token == "pickup" ) + { + // first argument (either entity name, or AIUSE class) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_PICKUP; + fc.string = new idStr( token ); + + // second argument (attach name) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + + // third argument (attach position) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + } + // tels: + else if ( token == "activate_at_joint" ) + { + // first argument (joint name) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_ACTIVATE_AT_JOINT; + fc.string = new idStr( token ); + } + // tels: + else if ( token == "activate_near" ) + { + // first argument (either entity name, or AIUSE class) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_ACTIVATE_NEAR; + fc.string = new idStr( token ); + + // second argument (joint name for distance check) + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + } + else if ( token == "pause" ) + { + fc.type = FC_PAUSE; + } + // Melee Combat Frame commands + else if ( token == "melee_hold" ) + { + // like FC_PAUSE but also sets melee vars on actor + fc.type = FC_MELEE_HOLD; + } + else if ( token == "melee_attack_start" ) + { + // first argument: name of the weapon attachment + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_MELEE_ATTACK_START; + fc.string = new idStr( token ); + + // second argument: name of the attack to start + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + } + else if ( token == "melee_attack_stop" ) + { + // not sure if this will have an argument, but say it will for now + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_MELEE_ATTACK_STOP; + fc.string = new idStr( token ); + } + else if ( token == "melee_parry_start" ) + { + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_MELEE_PARRY_START; + fc.string = new idStr( token ); + + // second argument: name of the parry to start + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.string->Append(va(" %s", token.c_str() )); + } + else if ( token == "melee_parry_stop" ) + { + // not sure if this will have an argument, but say it will for now + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + fc.type = FC_MELEE_PARRY_STOP; + fc.string = new idStr( token ); + } + else if ( token == "set_combat_flag" ) + { + fc.type = FC_SET_ATTACK_FLAG; + + // greebo: Parse attack flag argument + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + if (token == "melee") + { + fc.index = COMBAT_MELEE; + } + else if (token == "ranged") + { + fc.index = COMBAT_RANGED; + } + else + { + return "Unknown attack flag in framecommand."; + } + } + else if ( token == "clear_combat_flag" ) + { + fc.type = FC_CLEAR_ATTACK_FLAG; + + // greebo: Parse attack flag argument + if( !src.ReadTokenOnLine( &token ) ) + return "Unexpected end of line"; + + if (token == "melee") + { + fc.index = COMBAT_MELEE; + } + else if (token == "ranged") + { + fc.index = COMBAT_RANGED; + } + else + { + return "Unknown attack flag in framecommand."; + } + } + else + { + return va( "Unknown command '%s'", token.c_str() ); + } + + // check if we've initialized the frame loopup table + if ( !frameLookup.Num() ) { + // we haven't, so allocate the table and initialize it + frameLookup.SetGranularity( 1 ); + frameLookup.SetNum( anims[ 0 ]->NumFrames() ); + for( i = 0; i < frameLookup.Num(); i++ ) { + frameLookup[ i ].num = 0; + frameLookup[ i ].firstCommand = 0; + } + } + + // allocate space for a new command + frameCommands.Alloc(); + + // calculate the index of the new command + index = frameLookup[ framenum ].firstCommand + frameLookup[ framenum ].num; + + // move all commands from our index onward up one to give us space for our new command + for( i = frameCommands.Num() - 1; i > index; i-- ) { + frameCommands[ i ] = frameCommands[ i - 1 ]; + } + + // fix the indices of any later frames to account for the inserted command + for( i = framenum + 1; i < frameLookup.Num(); i++ ) { + frameLookup[ i ].firstCommand++; + } + + // store the new command + frameCommands[ index ] = fc; + + // increase the number of commands on this frame + frameLookup[ framenum ].num++; + + // return with no error + return NULL; +} + +/* +===================== +idAnim::CallFrameCommands +===================== +*/ +void idAnim::CallFrameCommands( idEntity *ent, int from, int to, idAnimBlend *caller ) +{ + int index; + int end; + int frame; + int numframes; + + numframes = anims[ 0 ]->NumFrames(); + + frame = from; + while( frame != to ) { + frame++; + if ( frame >= numframes ) { + frame = 0; + } + + index = frameLookup[ frame ].firstCommand; + end = index + frameLookup[ frame ].num; + while( index < end ) { + const frameCommand_t &command = frameCommands[ index++ ]; + + if (cv_ai_debug_anims.GetBool() && ent != gameLocal.GetLocalPlayer()) + { + gameLocal.Printf("Frame: %d - executing frame command %d (%s)\n", gameLocal.framenum, command.type, ent->name.c_str()); + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - executing frame command %d (%s)\r", gameLocal.framenum, command.type, ent->name.c_str()); + } + + switch( command.type ) { + case FC_SCRIPTFUNCTION: { + gameLocal.CallFrameCommand( ent, command.function ); + break; + } + case FC_SCRIPTFUNCTIONOBJECT: { + gameLocal.CallObjectFrameCommand( ent, command.string->c_str() ); + break; + } + case FC_EVENTFUNCTION: { + const idEventDef *ev = idEventDef::FindEvent( command.string->c_str() ); + ent->ProcessEvent( ev ); + break; + } + case FC_SOUND: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ANY, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_ANY, 0, false, NULL ); + } + break; + } + case FC_SOUND_VOICE: + { + if (command.soundShader == NULL) + { + // greebo: Use the communication subsystem for AI (issue #2483) + if (ent->IsType(idAI::Type)) + { + static_cast(ent)->commSubsystem->AddCommTask( + ai::CommunicationTaskPtr(new ai::SingleBarkTask(*(command.string))) + ); + } + else if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_voice' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } + else + { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE, 0, false, NULL ); + } + break; + } + case FC_SOUND_VOICE2: + { + if (command.soundShader == NULL) + { + // greebo: Use the communication subsystem for AI (issue #2483) + if (ent->IsType(idAI::Type)) + { + static_cast(ent)->commSubsystem->AddCommTask( + ai::CommunicationTaskPtr(new ai::SingleBarkTask(*(command.string))) + ); + } + else if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE2, 0, false, NULL ) ) + { + gameLocal.Warning( "Framecommand 'sound_voice2' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } + else + { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE2, 0, false, NULL ); + } + break; + } + case FC_SOUND_BODY: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_body' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY, 0, false, NULL ); + } + break; + } + case FC_SOUND_BODY2: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY2, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_body2' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY2, 0, false, NULL ); + } + break; + } + case FC_SOUND_BODY3: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY3, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_body3' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY3, 0, false, NULL ); + } + break; + } + case FC_SOUND_WEAPON: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_WEAPON, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_weapon' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_WEAPON, 0, false, NULL ); + } + break; + } + case FC_SOUND_GLOBAL: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_global' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); + } + break; + } + case FC_SOUND_ITEM: { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ITEM, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_item' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_ITEM, 0, false, NULL ); + } + break; + } + case FC_SOUND_CHATTER: { + if ( ent->CanPlayChatterSounds() ) { + if ( !command.soundShader ) { + if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE, 0, false, NULL ) ) { + gameLocal.Warning( "Framecommand 'sound_chatter' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + } else { + ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE, 0, false, NULL ); + } + } + break; + } + case FC_FX: { + idEntityFx::StartFx( command.string->c_str(), NULL, NULL, ent, true ); + break; + } + case FC_SKIN: { + ent->SetSkin( command.skin ); + break; + } + case FC_TRIGGER: { + idEntity *target; + + target = gameLocal.FindEntity( command.string->c_str() ); + if ( target ) { + target->Signal( SIG_TRIGGER ); + target->ProcessEvent( &EV_Activate, ent ); + target->TriggerGuis(); + } else { + gameLocal.Warning( "Framecommand 'trigger' on entity '%s', anim '%s', frame %d: Could not find entity '%s'", + ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); + } + break; + } + case FC_TRIGGER_SMOKE_PARTICLE: { + ent->ProcessEvent( &AI_TriggerParticles, command.string->c_str() ); + break; + } + case FC_MELEE: { + ent->ProcessEvent( &AI_AttackMelee, command.string->c_str() ); + break; + } + case FC_DIRECTDAMAGE: { + ent->ProcessEvent( &AI_DirectDamage, command.string->c_str() ); + break; + } + case FC_BEGINATTACK: { + ent->ProcessEvent( &AI_BeginAttack, command.string->c_str() ); + break; + } + case FC_ENDATTACK: { + ent->ProcessEvent( &AI_EndAttack ); + break; + } + case FC_MUZZLEFLASH: { + ent->ProcessEvent( &AI_MuzzleFlash, command.string->c_str() ); + break; + } + case FC_CREATEMISSILE: { + ent->ProcessEvent( &AI_CreateMissile, command.string->c_str() ); + break; + } + case FC_CREATEMISSILE_FROM_DEF: + { + // Split the def name and the joint name again + int pipePos = command.string->Find('|'); + + assert(pipePos != -1); + + idStr defName = command.string->Left(pipePos); + idStr jointName = command.string->Mid(pipePos+1, command.string->Length() - pipePos - 1); + + ent->ProcessEvent(&AI_CreateMissileFromDef, defName.c_str(), jointName.c_str()); + break; + } + case FC_LAUNCHMISSILE: { + ent->ProcessEvent( &AI_AttackMissile, command.string->c_str() ); + break; + } + case FC_FIREMISSILEATTARGET: { + ent->ProcessEvent( &AI_FireMissileAtTarget, modelDef->GetJointName( command.index ), command.string->c_str() ); + break; + } + case FC_FOOTSTEP : { + ent->ProcessEvent( &EV_Footstep ); + break; + } + case FC_LEFTFOOT: { + ent->ProcessEvent( &EV_FootstepLeft ); + break; + } + case FC_RIGHTFOOT: { + ent->ProcessEvent( &EV_FootstepRight ); + break; + } + case FC_ENABLE_EYE_FOCUS: { + ent->ProcessEvent( &AI_EnableEyeFocus ); + break; + } + case FC_DISABLE_EYE_FOCUS: { + ent->ProcessEvent( &AI_DisableEyeFocus ); + break; + } + case FC_DISABLE_GRAVITY: { + ent->ProcessEvent( &AI_DisableGravity ); + break; + } + case FC_ENABLE_GRAVITY: { + ent->ProcessEvent( &AI_EnableGravity ); + break; + } + case FC_JUMP: { + ent->ProcessEvent( &AI_JumpFrame ); + break; + } + case FC_ENABLE_CLIP: { + ent->ProcessEvent( &AI_EnableClip ); + break; + } + case FC_DISABLE_CLIP: { + ent->ProcessEvent( &AI_DisableClip ); + break; + } + case FC_ENABLE_WALK_IK: { + ent->ProcessEvent( &EV_EnableWalkIK ); + break; + } + case FC_DISABLE_WALK_IK: { + ent->ProcessEvent( &EV_DisableWalkIK ); + break; + } + case FC_ENABLE_LEG_IK: { + ent->ProcessEvent( &EV_EnableLegIK, command.index ); + break; + } + case FC_DISABLE_LEG_IK: { + ent->ProcessEvent( &EV_DisableLegIK, command.index ); + break; + } + case FC_RECORDDEMO: { + if ( command.string ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "recordDemo %s", command.string->c_str() ) ); + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "stoprecording" ); + } + break; + } + case FC_AVIGAME: + { + if ( command.string ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "aviGame %s", command.string->c_str() ) ); + } else { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "aviGame" ); + } + break; + } + + case FC_SETRATE: + { + float newRate = atof( command.string->c_str() ); + + for( int ind = 0; ind < numAnims; ind++ ) + { + // debug for SetRate debugging + //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("SETFRAMERATE: Setting frame rate: %d, on entity %s, channel %d\r", newRate, ent->name.c_str(), ind ); + // const_cast(anims[ ind ])->SetFrameRate( newRate ); + // Test out this method. Hope it doesn't effect all anims on the channel. + caller->SetPlaybackRate( gameLocal.time, newRate ); + } + break; + } + + case FC_REATTACH: + { + int spcind = command.string->Find(" "); + idStr AttName = command.string->Left( spcind ).c_str(); + idStr AttPos = command.string->Mid( spcind+1, command.string->Length() ); + + ent->ReAttachToPos( AttName, AttPos ); + break; + } + // tels: detach and destroy an attachment + case FC_DESTROY: + { + // get the attachment + idEntity* attEntity = ent->GetAttachment( command.string->c_str() ); + if (attEntity) + { + ent->Detach( command.string->c_str() ); + // and now remove it from the game world + // gameLocal.Warning ( "Going to remove attachment '%s' from '%s'\n", command.string->c_str(), ent->getName().c_str() ); + attEntity->PostEventMS( &EV_Remove, 0 ); + } + else + { + gameLocal.Warning ( "Cannot find attachment '%s' to destroy in animation.\n", command.string->c_str() ); + } + break; + } + // tels: drop an attachement + case FC_DROP: + { + idEntity* detachedEntity = ent->GetAttachment( command.string->c_str() ); + + if (!detachedEntity) + { + gameLocal.Printf(" Couldn't find attachment position by name %s\n", command.string->c_str()); + + // couldn't find the attached entity by attachment name, so try all attachments: + + // Tels: That does not work, as it doesn't save the joint info + // New position system: +/* CAttachInfo *info; + SAttachPosition *pos; + + if( (info = ent->GetAttachInfo( command.string->c_str() )) != NULL) + { + gameLocal.Printf(" Found attachment position %s\n", info->name.c_str() ); + detachedEntity = info->ent.GetEntity(); + if( !info->ent.IsValid() || !detachedEntity ) + { + DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Invalid attached entity at position %s on entity %s\r", info->name.c_str(), name.c_str()); + detachedEntity = NULL; + } + } + if( (pos = ent->GetAttachPosition( command.string->c_str() )) != NULL) + { + gameLocal.Printf(" Found attachment position %s\n", pos->name.c_str() ); + //detachedEntity = ent->GetAttachment( pos.name ); + //detachedEntity = pos->ent; + } + */ + } + + // avoid the entity clipping into the hand by teleporting it down half a unit + if (detachedEntity) + { + // only detach and unbind it if we have an entity + ent->Detach( command.string->c_str() ); + + idVec3 origin = detachedEntity->GetPhysics()->GetOrigin(); + origin.z -= DROP_DOWN_ADJUSTMENT; + detachedEntity->GetPhysics()->SetOrigin( origin ); + detachedEntity->m_droppedByAI = true; // grayman #1330 + } + break; + } + // tels: put down an attachement, works like drop, but restores origin and angles + case FC_PUTDOWN: + { + idEntity* detachedEntity = ent->GetAttachment( command.string->c_str() ); + + // detach and unbind it + ent->Detach( command.string->c_str() ); + + // now restore origin and angles + idVec3 origin; + idAngles angles; + const idKeyValue *tempkv = ent->spawnArgs.FindKey( "putdown_origin" ); + if( tempkv ) + { + // if the entity itself specifies where it should be put down, use this + //gameLocal.Printf(" Using putdown_origin\n"); + origin = detachedEntity->spawnArgs.GetVector( "putdown_origin", "0 0 0" ); + detachedEntity->GetPhysics()->SetOrigin( origin ); + } + else + { + // if not set on entity, restore pre-pickup values + //gameLocal.Printf(" Using pre_pickup_origin\n"); + origin = detachedEntity->spawnArgs.GetVector( "pre_pickup_origin", "0 0 0" ); + } + tempkv = ent->spawnArgs.FindKey( "putdown_angles" ); + if( tempkv ) + { + // if the entity itself specifies how it should be put down, use this + //gameLocal.Printf(" Using putdown_angles\n"); + angles = idAngles( detachedEntity->spawnArgs.GetVector( "putdown_angles", "0 0 0" ) ); + } + else + { + // if not set on entity, restore pre-pickup values + //gameLocal.Printf(" Using pre_pickup_angles\n"); + angles = idAngles( detachedEntity->spawnArgs.GetVector( "pre_pickup_angles", "0 0 0" ) ); + } + // gameLocal.Printf("Restoring origin %f %f %f and angles %f %f %f on putdown", origin.x, origin.y, origin.z, angles[0], angles[1], angles[2] ); + detachedEntity->GetPhysics()->SetOrigin( origin ); + detachedEntity->SetAngles( angles ); + break; + } + // tels: spawn an entity and attach it + case FC_ATTACH: + { + // possible formats: + // "atdm:foo_bar" + // "atdm:foo_bar book" + // "atdm:foo_bar book hip_left" + + idStr EntClass = ""; + // use these as defaults + idStr AttName = ""; + idStr AttPos = ""; + + int spcind = command.string->Find(' '); + if (spcind > 0) + { + // format of AttName is afterwards either "book" or "book hip_left" + EntClass = command.string->Left( spcind ); + AttName = command.string->Mid( spcind+1, command.string->Length() ); + spcind = AttName.Find(' '); + if (spcind > 0) + { + AttPos = AttName.Mid( spcind+1, AttName.Length() ); + AttName = AttName.Left( spcind ); + } + } + + // check that there isn't already something attached: + // idEntity* attEntity = ent->GetAttachment(AttPos.c_str()); // grayman #2603 - This was wrong. GetAttachment wants the Attach Name ('melee_weapon') not the position ('hand_l') + idEntity* attEntity = ent->GetAttachmentByPosition(AttPos.c_str()); // positions now stored in attach info + if (attEntity) + { + gameLocal.Warning("Already have an attachment at %s, skipping frame command.", AttPos.c_str()); + } + else + { + // spawn the entity + idEntity* spawnedEntity; + const idDict* entityDef = gameLocal.FindEntityDefDict( EntClass ); + + if (!entityDef) + { + gameLocal.Error("Cannot spawn %s - no such entityDef", EntClass.c_str() ); + } + gameLocal.SpawnEntityDef(*entityDef, &spawnedEntity); + // gameLocal.Printf("Attaching '%s' (%s) as '%s' to '%s'\n", EntClass.c_str(), spawnedEntity->GetName(), AttName.c_str(), AttPos.c_str() ); + + // Tels: Fix for alerted guards dropping entities spawned during animations, + // this is queried during alerted-drop (via unbindOnalertIndex), but not during animation + // drop or putdown (as we want an animation be able to create objects out of thin air and let + // a tdm_suicide script object take care of removing the object. An example is an AI eating an + // apple and dropping an apple core, which will vanish a minute later): + spawnedEntity->spawnArgs.Set("_spawned_by_anim", "1"); + + ent->Attach(spawnedEntity, AttPos, AttName); + + // and another fix for entities spawned, but then either dropped or stuck to the AI forever: + float delay = spawnedEntity->spawnArgs.GetFloat("remove_delay", "0"); + if (delay > 0) + { + // if remove_delay is set, remove that object after "remove_delay" seconds (* 1000 to get ms) + spawnedEntity->PostEventMS( &EV_Remove, delay * 1000 ); + } + } + break; + } + // tels: pick up an entity from the world + case FC_PICKUP: + { + // possible formats: + // "atdm_some_book book hand_r" + // "AIUSE_EAT food hand_l" + // "AIUSE_DRINK drink hand_l" + + int spcind = command.string->Find(" "); + // format of AttName is afterwards "food hand_r" + idStr EntityName = command.string->Left( spcind ); + idStr AttName = command.string->Mid( spcind+1, command.string->Length() ); + + idStr AttPos; + spcind = AttName.Find(" "); + if (spcind > 0) + { + AttPos = AttName.Mid( spcind+1, AttName.Length() ); + AttName = AttName.Left( spcind ); + } + + // gameLocal.Warning ( "Picking up '%s' as '%s' to '%s'", EntityName.c_str(), AttName.c_str(), AttPos.c_str()); + + idStr Spawnarg = "pickup_"; Spawnarg.Append( name ); + // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) + idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; + idEntity* attTarget = animEnt->GetEntityClosestToJoint( + AttPos.c_str(), EntityName.c_str(), Spawnarg.c_str(), MAX_PICKUP_DIST ); + + // did we find an entity to pickup? + if (attTarget) + { + // TODO: check that this entity is not attached to something/someone else + + // gameLocal.Warning ( "Found entity %s", attTarget->name.c_str() ); + + // gameLocal.Printf ( "Attaching '%s' as '%s' to '%s' (in pickup)\n", EntityName.c_str(), AttName.c_str(), AttPos.c_str()); + // first get the origin and rotation of the entity + idVec3 origin = attTarget->GetPhysics()->GetOrigin(); + idAngles ang = attTarget->GetPhysics()->GetAxis().ToAngles(); + // now store them in temp. spawnargs + attTarget->spawnArgs.SetVector( "pre_pickup_origin", origin ); + attTarget->spawnArgs.SetVector( "pre_pickup_angles", idVec3( ang[0], ang[1], ang[2] ) ); + // gameLocal.Warning ( "Saving origin %f %f %f and angles %f %f %f for %s", origin.x, origin.y, origin.z, ang[0], ang[1], ang[2], AttName.c_str() ); + // and now attach it + ent->Attach( attTarget, AttPos, AttName ); + } + else + { + // no entity found, abort animation? + gameLocal.Warning( " Could not find entity '%s' to attach", EntityName.c_str() ); + } + break; + } + // tels: activate the entity attached at the given joint + case FC_ACTIVATE_AT_JOINT: + { + // possible formats: + // "hand_r" + + // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) + idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; + idEntity* attTarget = animEnt->GetEntityClosestToJoint( + // invalid spawnarg name and entity name to disable these features (just get closest attached entity) + command.string->c_str(), "", "", 0.1f ); + + // did we find an entity to pickup? + // TODO: check that this entity is attached to ourselves + if (attTarget) + { + // TODO: check that this entity is not attached to something/someone else + gameLocal.Warning ( "%s is activating %s.", name.c_str(), attTarget->GetName() ); + attTarget->Activate( ent ); + } + else + { + gameLocal.Warning ( "%s has no entity at joint %s to activate.", name.c_str(), command.string->c_str()); + } + break; + } + // tels: activate the given entity near the given joint + case FC_ACTIVATE_NEAR: + { + // possible formats: + // "atdm_some_entity hand_r" + // "AIUSE_EAT hand_l" + + int spcind = command.string->Find(" "); + idStr EntityName = command.string->Left( spcind ); + idStr AttPos = command.string->Mid( spcind+1, command.string->Length() ); + + idStr Spawnarg = "activate_"; Spawnarg.Append( name ); + // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) + idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; + idEntity* attTarget = animEnt->GetEntityClosestToJoint( + AttPos.c_str(), EntityName.c_str(), Spawnarg.c_str(), MAX_ACTIVATE_DIST ); + + // did we find an entity to activate? + if (attTarget) + { + // gameLocal.Warning ( "Found entity %s", attTarget->name.c_str() ); + gameLocal.Warning ( "%s is activating %s near joint %s.", name.c_str(), EntityName.c_str(), AttPos.c_str()); + attTarget->Activate( ent ); + } + break; + } + case FC_PAUSE: + { + caller->Pause( true ); + break; + } + case FC_MELEE_HOLD: + { + caller->Pause( true ); + + idActor *ActOwner; + if( ent->IsType(idWeapon::Type) ) + ActOwner = static_cast(ent)->GetOwner(); + else if( ent->IsType(idActor::Type) ) + ActOwner = static_cast(ent); + else + ActOwner = NULL; + + // Update the associated actor's melee status + if( ActOwner ) + ActOwner->Event_MeleeActionHeld(); + + break; + } + case FC_MELEE_ATTACK_START: + { + const char *WeapName, *AttName; + int spcind = command.string->Find(" "); + WeapName = command.string->Left( spcind ).c_str(); + AttName = command.string->Mid( spcind+1, command.string->Length() ); + + idEntity *AttEnt = ent->GetAttachment( WeapName ); + if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) + { + idActor *ActOwner; + if( ent->IsType(idWeapon::Type) ) + ActOwner = static_cast(ent)->GetOwner(); + else if( ent->IsType(idActor::Type) ) + ActOwner = static_cast(ent); + else + ActOwner = NULL; + + static_cast(AttEnt)->ActivateAttack + ( ActOwner, AttName ); + } + + break; + } + case FC_MELEE_ATTACK_STOP: + { + idEntity *AttEnt = ent->GetAttachment( command.string->c_str() ); + if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) + { + CMeleeWeapon *WeapEnt = static_cast(AttEnt); + if( WeapEnt->GetOwner() ) + { + CMeleeStatus *pStatus = &WeapEnt->GetOwner()->m_MeleeStatus; + // if attack hasn't hit yet, this was a miss + if( pStatus->m_ActionResult == MELEERESULT_IN_PROGRESS ) + { + pStatus->m_ActionResult = MELEERESULT_AT_MISSED; + pStatus->m_ActionPhase = MELEEPHASE_RECOVERING; + } + } + WeapEnt->DeactivateAttack(); + } + + break; + } + case FC_MELEE_PARRY_START: + { + const char *WeapName, *ParName; + int spcind = command.string->Find(" "); + WeapName = command.string->Left( spcind ).c_str(); + ParName = command.string->Mid( spcind+1, command.string->Length() ); + + idEntity *AttEnt = ent->GetAttachment( WeapName ); + if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) + { + idActor *ActOwner; + if( ent->IsType(idWeapon::Type) ) + ActOwner = static_cast(ent)->GetOwner(); + else if( ent->IsType(idActor::Type) ) + ActOwner = static_cast(ent); + else + ActOwner = NULL; + + static_cast(AttEnt)->ActivateParry + ( ActOwner, ParName ); + } + + break; + } + case FC_MELEE_PARRY_STOP: + { + idEntity *AttEnt = ent->GetAttachment( command.string->c_str() ); + if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) + { + static_cast(AttEnt)->DeactivateParry(); + } + + break; + } + case FC_SET_ATTACK_FLAG: + if (ent->IsType(idActor::Type)) + { + static_cast(ent)->SetAttackFlag(static_cast(command.index), true); + } + break; + case FC_CLEAR_ATTACK_FLAG: + if (ent->IsType(idActor::Type)) + { + static_cast(ent)->SetAttackFlag(static_cast(command.index), false); + } + break; + } + } + } +} + +/* +===================== +idAnim::FindFrameForFrameCommand +===================== +*/ +int idAnim::FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const { + int frame; + int index; + int numframes; + int end; + + if ( !frameCommands.Num() ) { + return -1; + } + + numframes = anims[ 0 ]->NumFrames(); + for( frame = 0; frame < numframes; frame++ ) { + end = frameLookup[ frame ].firstCommand + frameLookup[ frame ].num; + for( index = frameLookup[ frame ].firstCommand; index < end; index++ ) { + if ( frameCommands[ index ].type == framecommand ) { + if ( command ) { + *command = &frameCommands[ index ]; + } + return frame; + } + } + } + + if ( command ) { + *command = NULL; + } + + return -1; +} + +/* +===================== +idAnim::HasFrameCommands +===================== +*/ +bool idAnim::HasFrameCommands( void ) const { + if ( !frameCommands.Num() ) { + return false; + } + return true; +} + +/* +===================== +idAnim::SetAnimFlags +===================== +*/ +void idAnim::SetAnimFlags( const animFlags_t &animflags ) { + flags = animflags; +} + +/* +===================== +idAnim::GetAnimFlags +===================== +*/ +const animFlags_t &idAnim::GetAnimFlags( void ) const { + return flags; +} + +/*********************************************************************** + + idAnimBlend + +***********************************************************************/ + +/* +===================== +idAnimBlend::idAnimBlend +===================== +*/ +idAnimBlend::idAnimBlend( void ) { + Reset( NULL ); +} + +/* +===================== +idAnimBlend::Save + +archives object for save game file +===================== +*/ +void idAnimBlend::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( starttime ); + savefile->WriteInt( endtime ); + savefile->WriteInt( timeOffset ); + savefile->WriteFloat( rate ); + + savefile->WriteInt( blendStartTime ); + savefile->WriteInt( blendDuration ); + savefile->WriteFloat( blendStartValue ); + savefile->WriteFloat( blendEndValue ); + + for( i = 0; i < ANIM_MaxSyncedAnims; i++ ) { + savefile->WriteFloat( animWeights[ i ] ); + } + savefile->WriteShort( cycle ); + savefile->WriteShort( frame ); + savefile->WriteShort( animNum ); + savefile->WriteBool( allowMove ); + savefile->WriteBool( allowFrameCommands ); + savefile->WriteBool( m_bPaused ); + savefile->WriteInt( m_PausedTime ); + savefile->WriteInt( m_PausedEndtime ); + savefile->WriteShort( m_PausedCycle ); +} + +/* +===================== +idAnimBlend::Restore + +unarchives object from save game file +===================== +*/ +void idAnimBlend::Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef ) { + int i; + + this->modelDef = modelDef; + + savefile->ReadInt( starttime ); + savefile->ReadInt( endtime ); + savefile->ReadInt( timeOffset ); + savefile->ReadFloat( rate ); + + savefile->ReadInt( blendStartTime ); + savefile->ReadInt( blendDuration ); + savefile->ReadFloat( blendStartValue ); + savefile->ReadFloat( blendEndValue ); + + for( i = 0; i < ANIM_MaxSyncedAnims; i++ ) { + savefile->ReadFloat( animWeights[ i ] ); + } + savefile->ReadShort( cycle ); + savefile->ReadShort( frame ); + savefile->ReadShort( animNum ); + if ( !modelDef ) { + animNum = 0; + } else if ( ( animNum < 0 ) || ( animNum > modelDef->NumAnims() ) ) { + gameLocal.Warning( "Anim number %d out of range for model '%s' during save game", animNum, modelDef->GetModelName() ); + animNum = 0; + } + savefile->ReadBool( allowMove ); + savefile->ReadBool( allowFrameCommands ); + savefile->ReadBool( m_bPaused ); + savefile->ReadInt( m_PausedTime ); + savefile->ReadInt( m_PausedEndtime ); + savefile->ReadShort( m_PausedCycle ); +} + +/* +===================== +idAnimBlend::Reset +===================== +*/ +void idAnimBlend::Reset( const idDeclModelDef *_modelDef ) +{ + + modelDef = _modelDef; + cycle = 1; + starttime = 0; + endtime = 0; + timeOffset = 0; + rate = 1.0f; + frame = 0; + allowMove = true; + allowFrameCommands = true; + m_bPaused = false; + m_PausedEndtime = 0; + m_PausedCycle = 1; + m_PausedTime = 0; + + animNum = 0; + + memset( animWeights, 0, sizeof( animWeights ) ); + + blendStartValue = 0.0f; + blendEndValue = 0.0f; + blendStartTime = 0; + blendDuration = 0; +} + +/* +===================== +idAnimBlend::FullName +===================== +*/ +const char *idAnimBlend::AnimFullName( void ) const { + const idAnim *anim = Anim(); + if ( !anim ) { + return ""; + } + + return anim->FullName(); +} + +/* +===================== +idAnimBlend::AnimName +===================== +*/ +const char *idAnimBlend::AnimName( void ) const { + const idAnim *anim = Anim(); + if ( !anim ) { + return ""; + } + + return anim->Name(); +} + +/* +===================== +idAnimBlend::NumFrames +===================== +*/ +int idAnimBlend::NumFrames( void ) const { + const idAnim *anim = Anim(); + if ( !anim ) { + return 0; + } + + return anim->NumFrames(); +} + +/* +===================== +idAnimBlend::Length +===================== +*/ +int idAnimBlend::Length( void ) const { + const idAnim *anim = Anim(); + if ( !anim ) { + return 0; + } + + return anim->Length(); +} + +/* +===================== +idAnimBlend::GetWeight +===================== +*/ +float idAnimBlend::GetWeight( int currentTime ) const { + int timeDelta; + float frac; + float w; + + timeDelta = currentTime - blendStartTime; + if ( timeDelta <= 0 ) { + w = blendStartValue; + } else if ( timeDelta >= blendDuration ) { + w = blendEndValue; + } else { + frac = ( float )timeDelta / ( float )blendDuration; + w = blendStartValue + ( blendEndValue - blendStartValue ) * frac; + } + + return w; +} + +/* +===================== +idAnimBlend::GetFinalWeight +===================== +*/ +float idAnimBlend::GetFinalWeight( void ) const { + return blendEndValue; +} + +/* +===================== +idAnimBlend::SetWeight +===================== +*/ +void idAnimBlend::SetWeight( float newweight, int currentTime, int blendTime ) { + blendStartValue = GetWeight( currentTime ); + blendEndValue = newweight; + blendStartTime = currentTime - 1; + blendDuration = blendTime; + + if ( !newweight ) { + endtime = currentTime + blendTime; + } +} + +/* +===================== +idAnimBlend::NumSyncedAnims +===================== +*/ +int idAnimBlend::NumSyncedAnims( void ) const { + const idAnim *anim = Anim(); + if ( !anim ) { + return 0; + } + + return anim->NumAnims(); +} + +/* +===================== +idAnimBlend::SetSyncedAnimWeight +===================== +*/ +bool idAnimBlend::SetSyncedAnimWeight( int num, float weight ) { + const idAnim *anim = Anim(); + if ( !anim ) { + return false; + } + + if ( ( num < 0 ) || ( num > anim->NumAnims() ) ) { + return false; + } + + animWeights[ num ] = weight; + return true; +} + +/* +===================== +idAnimBlend::UpdatePlaybackRate +===================== +*/ +void idAnimBlend::UpdatePlaybackRate(int _animNum, const idEntity* ent) { + if (ent != NULL && _animNum >= 0 && animNum < ent->m_animRates.Num()) { + // this->rate = ent->m_animRates[_animNum]; + SetPlaybackRate( gameLocal.time, ent->m_animRates[_animNum] ); + } +} + +/* +===================== +idAnimBlend::SetFrame +===================== +*/ +void idAnimBlend::SetFrame( const idDeclModelDef *modelDef, int _animNum, int _frame, int currentTime, int blendTime, const idEntity *ent ) { + Reset( modelDef ); + if ( !modelDef ) { + return; + } + + const idAnim *_anim = modelDef->GetAnim( _animNum ); + if ( !_anim ) { + return; + } + + UpdatePlaybackRate(_animNum, ent); + + const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); + if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { + gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); + return; + } + + animNum = _animNum; + starttime = currentTime; + endtime = -1; + cycle = -1; + animWeights[ 0 ] = 1.0f; + frame = _frame; + + // a frame of 0 means it's not a single frame blend, so we set it to frame + 1 + if ( frame <= 0 ) { + frame = 1; + } else if ( frame > _anim->NumFrames() ) { + frame = _anim->NumFrames(); + } + + // set up blend + blendEndValue = 1.0f; + blendStartTime = currentTime - 1; + blendDuration = blendTime; + blendStartValue = 0.0f; +} + +/* +===================== +idAnimBlend::CycleAnim +===================== +*/ +void idAnimBlend::CycleAnim( const idDeclModelDef *modelDef, int _animNum, int currentTime, int blendTime, const idEntity* ent ) +{ + Reset( modelDef ); + if ( !modelDef ) { + return; + } + + const idAnim *_anim = modelDef->GetAnim( _animNum ); + if ( !_anim ) { + return; + } + + const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); + if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { + gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); + return; + } + + animNum = _animNum; + animWeights[ 0 ] = 1.0f; + endtime = -1; + cycle = -1; + if ( _anim->GetAnimFlags().random_cycle_start ) { + // start the animation at a random time so that characters don't walk in sync + starttime = (int)(currentTime - gameLocal.random.RandomFloat() * _anim->Length()); + } else { + starttime = currentTime; + } + + // ishtvan: Moved this TDM call here to fix bugs + UpdatePlaybackRate(_animNum, ent); + + // set up blend + blendEndValue = 1.0f; + blendStartTime = currentTime - 1; + blendDuration = blendTime; + blendStartValue = 0.0f; +} + +/* +===================== +idAnimBlend::PlayAnim +===================== +*/ +void idAnimBlend::PlayAnim( const idDeclModelDef *modelDef, int _animNum, int currentTime, int blendTime, const idEntity *ent ) +{ + Reset( modelDef ); + if ( !modelDef ) { + return; + } + + const idAnim *_anim = modelDef->GetAnim( _animNum ); + if ( !_anim ) { + return; + } + + const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); + if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { + gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); + return; + } + + animNum = _animNum; + starttime = currentTime; + endtime = starttime + _anim->Length(); + cycle = 1; + animWeights[ 0 ] = 1.0f; + + // ishtvan: Moved this TDM call here to fix bugs + UpdatePlaybackRate(_animNum, ent); + + // set up blend + blendEndValue = 1.0f; + blendStartTime = currentTime - 1; + blendDuration = blendTime; + blendStartValue = 0.0f; +} + +/* +===================== +idAnimBlend::Clear +===================== +*/ +void idAnimBlend::Clear( int currentTime, int clearTime ) { + if ( !clearTime ) { + Reset( modelDef ); + } else { + SetWeight( 0.0f, currentTime, clearTime ); + } +} + +/* +===================== +idAnimBlend::IsDone +===================== +*/ +bool idAnimBlend::IsDone( int currentTime ) const +{ + if( m_bPaused ) + return false; + + if ( !frame && ( endtime > 0 ) && ( currentTime >= endtime ) ) { + return true; + } + + if ( ( blendEndValue <= 0.0f ) && ( currentTime >= ( blendStartTime + blendDuration ) ) ) { + return true; + } + + return false; +} + +/* +===================== +idAnimBlend::FrameHasChanged +===================== +*/ +bool idAnimBlend::FrameHasChanged( int currentTime ) const +{ + // if we don't have an anim, no change + if ( !animNum ) + return false; + + // if anim is done playing, no change + if ( ( endtime > 0 ) && ( currentTime > endtime ) ) + return false; + + // if our blend weight changes, we need to update + if ( ( currentTime < ( blendStartTime + blendDuration ) + && ( blendStartValue != blendEndValue ) ) ) + return true; + + // if we're a single frame anim and this isn't the frame we started on, we don't need to update + // Or if we are paused at a single frame? + if ( ( frame || ( NumFrames() == 1 ) /* || m_bPaused */ ) && ( currentTime != starttime ) ) + return false; + + return true; +} + +/* +===================== +idAnimBlend::GetCycleCount +===================== +*/ +int idAnimBlend::GetCycleCount( void ) const { + return cycle; +} + +/* +===================== +idAnimBlend::SetCycleCount +===================== +*/ +void idAnimBlend::SetCycleCount( int count ) { + const idAnim *anim = Anim(); + + if ( !anim ) { + cycle = -1; + endtime = 0; + } else { + cycle = count; + if ( cycle < 0 ) { + cycle = -1; + endtime = -1; + } else if ( cycle == 0 ) { + cycle = 1; + + // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion + if ( rate == 1.0f ) { + endtime = starttime - timeOffset + anim->Length(); + } else if ( rate != 0.0f ) { + endtime = (int)(starttime - timeOffset + anim->Length() / rate); + } else { + endtime = -1; + } + } else { + + // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion + if ( rate == 1.0f ) { + endtime = starttime - timeOffset + anim->Length() * cycle; + } else if ( rate != 0.0f ) { + endtime = (int)(starttime - timeOffset + ( anim->Length() * cycle ) / rate); + } else { + endtime = -1; + } + } + } +} + +/* +===================== +idAnimBlend::SetPlaybackRate +===================== +*/ +void idAnimBlend::SetPlaybackRate( int currentTime, float newRate ) { + int animTime; + + if ( rate == newRate ) { + return; + } + + animTime = AnimTime( currentTime ); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("SetPlayBackRate (Anim %s): animTime = %d, newRate = %f \r", AnimFullName(), animTime, newRate ); + if ( newRate == 1.0f ) { + timeOffset = animTime - ( currentTime - starttime ); + } else + { + timeOffset = (int)(animTime - ( currentTime - starttime ) * newRate); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("SetPlayBackRate (Anim %s): currentTime = %d, starttime = %d, calc timeOffset = %d \r", AnimFullName(), currentTime, starttime, timeOffset ); + } + + rate = newRate; + + // update the anim endtime + SetCycleCount( cycle ); +} + +/* +===================== +idAnimBlend::GetPlaybackRate +===================== +*/ +float idAnimBlend::GetPlaybackRate( void ) const { + return rate; +} + +/* +===================== +idAnimBlend::SetStartTime +===================== +*/ +void idAnimBlend::SetStartTime( int _startTime ) { + starttime = _startTime; + + // update the anim endtime + SetCycleCount( cycle ); +} + +/* +===================== +idAnimBlend::GetStartTime +===================== +*/ +int idAnimBlend::GetStartTime( void ) const { + if ( !animNum ) { + return 0; + } + + return starttime; +} + +/* +===================== +idAnimBlend::GetEndTime +===================== +*/ +int idAnimBlend::GetEndTime( void ) const { + if ( !animNum ) { + return 0; + } + + return endtime; +} + +/* +===================== +idAnimBlend::PlayLength +===================== +*/ +int idAnimBlend::PlayLength( void ) const { + if ( !animNum ) { + return 0; + } + + if ( endtime < 0 ) { + return -1; + } + + return endtime - starttime + timeOffset; +} + +/* +===================== +idAnimBlend::AllowMovement +===================== +*/ +void idAnimBlend::AllowMovement( bool allow ) { + allowMove = allow; +} + +/* +===================== +idAnimBlend::AllowFrameCommands +===================== +*/ +void idAnimBlend::AllowFrameCommands( bool allow ) { + allowFrameCommands = allow; +} + +/* +===================== +idAnimBlend::Pause +===================== +*/ +void idAnimBlend::Pause( bool bPause ) +{ + // going from unpaused to paused + if( bPause && !m_bPaused ) + { + m_PausedEndtime = endtime; + m_PausedCycle = cycle; + m_PausedTime = gameLocal.time; + +/* Uncomment for debugging + gameLocal.Printf("Animation was paused, startime %d, endtime %d, cycle %d, time remaining: %d\r", + starttime, endtime, (int) cycle, (endtime - starttime) ); +*/ + + endtime = -1; + cycle = 1; + } + // going from paused to unpaused + else if( !bPause && m_bPaused ) + { + // how long were we paused for + int deltaT = gameLocal.time - m_PausedTime; + + // advance one frame in the animation from where we left off + // equivalent to setting the start time 1 frame back + deltaT = deltaT - FRAME2MS(1)/rate; + + starttime += deltaT; + if( m_PausedEndtime > 0 ) + endtime = m_PausedEndtime + deltaT; + cycle = m_PausedCycle; + +/* Uncomment for debugging + gameLocal.Printf("Animation was unpaused after time %d, startime %d, endtime %d, cycle %d, time remaining: %d\r", + deltaT, starttime, endtime, (int) cycle, (endtime - starttime) ); +*/ + } + + m_bPaused = bPause; +} + +/* +===================== +idAnimBlend::IsPaused +===================== +*/ +bool idAnimBlend::IsPaused( void ) +{ + return m_bPaused; +} + + +/* +===================== +idAnimBlend::Anim +===================== +*/ +const idAnim *idAnimBlend::Anim( void ) const { + if ( !modelDef ) { + return NULL; + } + + const idAnim *anim = modelDef->GetAnim( animNum ); + return anim; +} + +/* +===================== +idAnimBlend::AnimNum +===================== +*/ +int idAnimBlend::AnimNum( void ) const { + return animNum; +} + +/* +===================== +idAnimBlend::AnimTime +===================== +*/ +int idAnimBlend::AnimTime( int currentTime ) const +{ + int time; + int length; + const idAnim *anim = Anim(); + + if ( anim ) + { + if ( frame ) + { + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime (anim %s): Frame was already set to %d\r", AnimFullName(), frame ); + return FRAME2MS( frame - 1 ); + } + + // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion + if ( rate == 1.0f ) { + time = currentTime - starttime + timeOffset; + } else + { + time = static_cast( ( currentTime - starttime ) * rate ) + timeOffset; + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s has adjusted rate %f\r", AnimFullName(), rate ); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: currentTime: %d , starttime: %d, timeOffset: %d, calc. time: %d\r",currentTime, starttime, timeOffset ); + } + + // given enough time, we can easily wrap time around in our frame calculations, so + // keep cycling animations' time within the length of the anim. + length = anim->Length(); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s has length %d \r", AnimFullName(), length ); + if ( ( cycle < 0 ) && ( length > 0 ) ) { + time %= length; + + // time will wrap after 24 days (oh no!), resulting in negative results for the %. + // adding the length gives us the proper result. + if ( time < 0 ) { + time += length; + } + } + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s, final time =%d \r", AnimFullName(), time ); + return time; + } else { + return 0; + } +} + +/* +===================== +idAnimBlend::GetFrameNumber +===================== +*/ +int idAnimBlend::GetFrameNumber( int currentTime ) const +{ + const idMD5Anim *md5anim; + frameBlend_t frameinfo; + int animTime; + + // ishtvan: uncomment for debugging + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("Anim %s called GetFrameNumber \r",AnimFullName() ); + + const idAnim *anim = Anim(); + if ( !anim ) + { + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: No anim found, returning 1\r" ); + return 1; + } + + if ( frame ) + { + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: Frame was set to %d, returning it\r", frame ); + return frame; + } + + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: Frame was not set, calculating it...\r" ); + md5anim = anim->MD5Anim( 0 ); + animTime = AnimTime( currentTime ); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: AnimTime returned %d ms\r", animTime ); + md5anim->ConvertTimeToFrame( animTime, cycle, frameinfo ); + // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: ConvertTimeToFrame returned frame %d\r", frameinfo.frame1 + 1 ); + + return frameinfo.frame1 + 1; +} + +/* +===================== +idAnimBlend::CallFrameCommands +===================== +*/ +void idAnimBlend::CallFrameCommands( idEntity *ent, int fromtime, int totime ) const { + const idMD5Anim *md5anim; + frameBlend_t frame1; + frameBlend_t frame2; + int fromFrameTime; + int toFrameTime; + + // ishtvan: don't play frame commands if paused + if + ( + !allowFrameCommands || !ent || + frame || ( ( endtime > 0 ) && ( fromtime > endtime ) + || m_bPaused ) + ) + return; + + const idAnim *anim = Anim(); + + if ( !anim || !anim->HasFrameCommands() ) + return; + + if ( totime <= starttime ) { + // don't play until next frame or we'll play commands twice. + // this happens on the player sometimes. + return; + } + + fromFrameTime = AnimTime( fromtime ); + toFrameTime = AnimTime( totime ); + if ( toFrameTime < fromFrameTime ) { + toFrameTime += anim->Length(); + } + + md5anim = anim->MD5Anim( 0 ); + md5anim->ConvertTimeToFrame( fromFrameTime, cycle, frame1 ); + md5anim->ConvertTimeToFrame( toFrameTime, cycle, frame2 ); + + if ( fromFrameTime <= 0 ) { + // make sure first frame is called + const_cast(anim)->CallFrameCommands( ent, -1, frame2.frame1, const_cast(this) ); + } else { + const_cast(anim)->CallFrameCommands( ent, frame1.frame1, frame2.frame1, const_cast(this) ); + } +} + +/* +===================== +idAnimBlend::BlendAnim +===================== +*/ +bool idAnimBlend::BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOriginOffset, bool overrideBlend, bool printInfo ) const { + int i; + float lerp; + float mixWeight; + const idMD5Anim *md5anim; + idJointQuat *ptr; + frameBlend_t frametime; + memset( &frametime, 0, sizeof(frameBlend_t) ); + idJointQuat *jointFrame; + idJointQuat *mixFrame; + int numAnims; + int time; + + const idAnim *anim = Anim(); + if ( !anim ) + return false; + + if( m_bPaused ) + currentTime = m_PausedTime; + + float weight = GetWeight( currentTime ); + if ( blendWeight > 0.0f ) + { + if ( ( endtime >= 0 ) && ( currentTime >= endtime ) ) + return false; + if ( !weight ) + return false; + if ( overrideBlend ) + blendWeight = 1.0f - weight; + } + + if ( ( channel == ANIMCHANNEL_ALL ) && !blendWeight ) + { + // we don't need a temporary buffer, so just store it directly in the blend frame + jointFrame = blendFrame; + } else + { + // allocate a temporary buffer to copy the joints from + jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); + } + + time = AnimTime( currentTime ); + + numAnims = anim->NumAnims(); + if ( numAnims == 1 ) + { + md5anim = anim->MD5Anim( 0 ); + if ( frame ) + { + md5anim->GetSingleFrame( frame - 1, jointFrame, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } else + { + md5anim->ConvertTimeToFrame( time, cycle, frametime ); + md5anim->GetInterpolatedFrame( frametime, jointFrame, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } + } else + { + // + // need to mix the multipoint anim together first + // + // allocate a temporary buffer to copy the joints to + mixFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); + + if ( !frame ) + anim->MD5Anim( 0 )->ConvertTimeToFrame( time, cycle, frametime ); + + ptr = jointFrame; + mixWeight = 0.0f; + for( i = 0; i < numAnims; i++ ) { + if ( animWeights[ i ] > 0.0f ) { + mixWeight += animWeights[ i ]; + lerp = animWeights[ i ] / mixWeight; + md5anim = anim->MD5Anim( i ); + if ( frame ) + { + md5anim->GetSingleFrame( frame - 1, ptr, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } else + { + md5anim->GetInterpolatedFrame( frametime, ptr, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } + + // only blend after the first anim is mixed in + if ( ptr != jointFrame ) { + SIMDProcessor->BlendJoints( jointFrame, ptr, lerp, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } + + ptr = mixFrame; + } + } + + if ( !mixWeight ) { + return false; + } + } + + if ( removeOriginOffset ) { + if ( allowMove ) { +#ifdef VELOCITY_MOVE + jointFrame[ 0 ].t.x = 0.0f; +#else + jointFrame[ 0 ].t.Zero(); +#endif + } + + if ( anim->GetAnimFlags().anim_turn ) { + jointFrame[ 0 ].q.Set( -0.70710677f, 0.0f, 0.0f, 0.70710677f ); + } + } + + if ( !blendWeight ) { + blendWeight = weight; + if ( channel != ANIMCHANNEL_ALL ) { + const int *index = modelDef->GetChannelJoints( channel ); + const int num = modelDef->NumJointsOnChannel( channel ); + for( i = 0; i < num; i++ ) { + int j = index[i]; + blendFrame[j].t = jointFrame[j].t; + blendFrame[j].q = jointFrame[j].q; + } + } + } else { + blendWeight += weight; + lerp = weight / blendWeight; + SIMDProcessor->BlendJoints( blendFrame, jointFrame, lerp, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); + } + + if ( printInfo ) { + if ( frame ) { + gameLocal.Printf( " %s: '%s', %d, %.2f%%\n", channelNames[ channel ], anim->FullName(), frame, weight * 100.0f ); + } else { + gameLocal.Printf( " %s: '%s', %.3f, %.2f%%\n", channelNames[ channel ], anim->FullName(), ( float )frametime.frame1 + frametime.backlerp, weight * 100.0f ); + } + } + + return true; +} + +/* +===================== +idAnimBlend::BlendOrigin +===================== +*/ +void idAnimBlend::BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const { + float lerp; + idVec3 animpos; + idVec3 pos; + int time; + int num; + int i; + + if ( frame || ( ( endtime > 0 ) && ( currentTime > endtime ) ) ) { + return; + } + + const idAnim *anim = Anim(); + if ( !anim ) { + return; + } + + if ( allowMove && removeOriginOffset ) { + return; + } + + float weight = GetWeight( currentTime ); + if ( !weight ) { + return; + } + + time = AnimTime( currentTime ); + + pos.Zero(); + num = anim->NumAnims(); + for( i = 0; i < num; i++ ) { + anim->GetOrigin( animpos, i, time, cycle ); + pos += animpos * animWeights[ i ]; + } + + if ( !blendWeight ) { + blendPos = pos; + blendWeight = weight; + } else { + lerp = weight / ( blendWeight + weight ); + blendPos += lerp * ( pos - blendPos ); + blendWeight += weight; + } +} + +/* +===================== +idAnimBlend::BlendDelta +===================== +*/ +void idAnimBlend::BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const { + idVec3 pos1; + idVec3 pos2; + idVec3 animpos; + idVec3 delta; + int time1; + int time2; + float lerp; + int num; + int i; + + if ( frame || !allowMove || ( ( endtime > 0 ) && ( fromtime > endtime ) ) ) { + return; + } + + const idAnim *anim = Anim(); + if ( !anim ) { + return; + } + + float weight = GetWeight( totime ); + if ( !weight ) { + return; + } + + time1 = AnimTime( fromtime ); + time2 = AnimTime( totime ); + if ( time2 < time1 ) { + time2 += anim->Length(); + } + + num = anim->NumAnims(); + + pos1.Zero(); + pos2.Zero(); + for( i = 0; i < num; i++ ) { + anim->GetOrigin( animpos, i, time1, cycle ); + pos1 += animpos * animWeights[ i ]; + + anim->GetOrigin( animpos, i, time2, cycle ); + pos2 += animpos * animWeights[ i ]; + } + + delta = pos2 - pos1; + if ( !blendWeight ) { + blendDelta = delta; + blendWeight = weight; + } else { + lerp = weight / ( blendWeight + weight ); + blendDelta += lerp * ( delta - blendDelta ); + blendWeight += weight; + } +} + +/* +===================== +idAnimBlend::BlendDeltaRotation +===================== +*/ +void idAnimBlend::BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const { + idQuat q1; + idQuat q2; + idQuat q3; + int time1; + int time2; + float lerp; + float mixWeight; + int num; + int i; + + if ( frame || !allowMove || ( ( endtime > 0 ) && ( fromtime > endtime ) ) ) { + return; + } + + const idAnim *anim = Anim(); + if ( !anim || !anim->GetAnimFlags().anim_turn ) { + return; + } + + float weight = GetWeight( totime ); + if ( !weight ) { + return; + } + + time1 = AnimTime( fromtime ); + time2 = AnimTime( totime ); + if ( time2 < time1 ) { + time2 += anim->Length(); + } + + q1.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + q2.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + + mixWeight = 0.0f; + num = anim->NumAnims(); + for( i = 0; i < num; i++ ) { + if ( animWeights[ i ] > 0.0f ) { + mixWeight += animWeights[ i ]; + if ( animWeights[ i ] == mixWeight ) { + anim->GetOriginRotation( q1, i, time1, cycle ); + anim->GetOriginRotation( q2, i, time2, cycle ); + } else { + lerp = animWeights[ i ] / mixWeight; + anim->GetOriginRotation( q3, i, time1, cycle ); + q1.Slerp( q1, q3, lerp ); + + anim->GetOriginRotation( q3, i, time2, cycle ); + q2.Slerp( q1, q3, lerp ); + } + } + } + + q3 = q1.Inverse() * q2; + if ( !blendWeight ) { + blendDelta = q3; + blendWeight = weight; + } else { + lerp = weight / ( blendWeight + weight ); + blendDelta.Slerp( blendDelta, q3, lerp ); + blendWeight += weight; + } +} + +/* +===================== +idAnimBlend::AddBounds +===================== +*/ +bool idAnimBlend::AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const { + int i; + int num; + idBounds b; + int time; + idVec3 pos; + bool addorigin; + + if ( ( endtime > 0 ) && ( currentTime > endtime ) ) { + return false; + } + + const idAnim *anim = Anim(); + if ( !anim ) { + return false; + } + + float weight = GetWeight( currentTime ); + if ( !weight ) { + return false; + } + + time = AnimTime( currentTime ); + num = anim->NumAnims(); + + addorigin = !allowMove || !removeOriginOffset; + for( i = 0; i < num; i++ ) { + if ( anim->GetBounds( b, i, time, cycle ) ) { + if ( addorigin ) { + anim->GetOrigin( pos, i, time, cycle ); + b.TranslateSelf( pos ); + } + bounds.AddBounds( b ); + } + } + + return true; +} + +/*********************************************************************** + + idDeclModelDef + +***********************************************************************/ + +/* +===================== +idDeclModelDef::idDeclModelDef +===================== +*/ +idDeclModelDef::idDeclModelDef() { + modelHandle = NULL; + skin = NULL; + offset.Zero(); + for ( int i = 0; i < ANIM_NumAnimChannels; i++ ) { + channelJoints[i].Clear(); + } +} + +/* +===================== +idDeclModelDef::~idDeclModelDef +===================== +*/ +idDeclModelDef::~idDeclModelDef() { + FreeData(); +} + +/* +================= +idDeclModelDef::Size +================= +*/ +size_t idDeclModelDef::Size( void ) const { + return sizeof( idDeclModelDef ); +} + +/* +===================== +idDeclModelDef::CopyDecl +===================== +*/ +void idDeclModelDef::CopyDecl( const idDeclModelDef *decl ) { + int i; + + FreeData(); + + offset = decl->offset; + modelHandle = decl->modelHandle; + skin = decl->skin; + + anims.SetNum( decl->anims.Num() ); + for( i = 0; i < anims.Num(); i++ ) { + anims[ i ] = new idAnim( this, decl->anims[ i ] ); + } + + joints.SetNum( decl->joints.Num() ); + memcpy( joints.Ptr(), decl->joints.Ptr(), decl->joints.Num() * sizeof( joints[0] ) ); + jointParents.SetNum( decl->jointParents.Num() ); + memcpy( jointParents.Ptr(), decl->jointParents.Ptr(), decl->jointParents.Num() * sizeof( jointParents[0] ) ); + for ( i = 0; i < ANIM_NumAnimChannels; i++ ) { + channelJoints[i] = decl->channelJoints[i]; + } +} + +/* +===================== +idDeclModelDef::FreeData +===================== +*/ +void idDeclModelDef::FreeData( void ) { + anims.DeleteContents( true ); + joints.Clear(); + jointParents.Clear(); + modelHandle = NULL; + skin = NULL; + offset.Zero(); + for ( int i = 0; i < ANIM_NumAnimChannels; i++ ) { + channelJoints[i].Clear(); + } +} + +/* +================ +idDeclModelDef::DefaultDefinition +================ +*/ +const char *idDeclModelDef::DefaultDefinition( void ) const { + return "{ }"; +} + +/* +==================== +idDeclModelDef::FindJoint +==================== +*/ +const jointInfo_t *idDeclModelDef::FindJoint( const char *name ) const { + int i; + const idMD5Joint *joint; + + if ( !modelHandle ) { + return NULL; + } + + joint = modelHandle->GetJoints(); + for( i = 0; i < joints.Num(); i++, joint++ ) { + if ( !joint->name.Icmp( name ) ) { + return &joints[ i ]; + } + } + + return NULL; +} + +/* +===================== +idDeclModelDef::ModelHandle +===================== +*/ +idRenderModel *idDeclModelDef::ModelHandle( void ) const { + return ( idRenderModel * )modelHandle; +} + +/* +===================== +idDeclModelDef::GetJointList +===================== +*/ +void idDeclModelDef::GetJointList( const char *jointnames, idList &jointList ) const { + const char *pos; + idStr jointname; + const jointInfo_t *joint; + const jointInfo_t *child; + int i; + int num; + bool getChildren; + bool subtract; + + if ( !modelHandle ) { + return; + } + + jointList.Clear(); + + num = modelHandle->NumJoints(); + + // scan through list of joints and add each to the joint list + pos = jointnames; + while( *pos ) { + // skip over whitespace + while( ( *pos != 0 ) && isspace( *pos ) ) { + pos++; + } + + if ( !*pos ) { + // no more names + break; + } + + // copy joint name + jointname = ""; + + if ( *pos == '-' ) { + subtract = true; + pos++; + } else { + subtract = false; + } + + if ( *pos == '*' ) { + getChildren = true; + pos++; + } else { + getChildren = false; + } + + while( ( *pos != 0 ) && !isspace( *pos ) ) { + jointname += *pos; + pos++; + } + + joint = FindJoint( jointname ); + if ( !joint ) { + gameLocal.Warning( "Unknown joint '%s' in '%s' for model '%s'", jointname.c_str(), jointnames, GetName() ); + continue; + } + + if ( !subtract ) { + jointList.AddUnique( joint->num ); + } else { + jointList.Remove( joint->num ); + } + + if ( getChildren ) { + // include all joint's children + child = joint + 1; + for( i = joint->num + 1; i < num; i++, child++ ) { + // all children of the joint should follow it in the list. + // once we reach a joint without a parent or with a parent + // who is earlier in the list than the specified joint, then + // we've gone through all it's children. + if ( child->parentNum < joint->num ) { + break; + } + + if ( !subtract ) { + jointList.AddUnique( child->num ); + } else { + jointList.Remove( child->num ); + } + } + } + } +} + +/* +===================== +idDeclModelDef::Touch +===================== +*/ +void idDeclModelDef::Touch( void ) const { + if ( modelHandle ) { + renderModelManager->FindModel( modelHandle->Name() ); + } +} + +/* +===================== +idDeclModelDef::GetDefaultSkin +===================== +*/ +const idDeclSkin *idDeclModelDef::GetDefaultSkin( void ) const { + return skin; +} + +/* +===================== +idDeclModelDef::GetDefaultPose +===================== +*/ +const idJointQuat *idDeclModelDef::GetDefaultPose( void ) const { + return modelHandle->GetDefaultPose(); +} + +/* +===================== +idDeclModelDef::SetupJoints +===================== +*/ +void idDeclModelDef::SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const { + int num; + const idJointQuat *pose; + idJointMat *list; + + if ( !modelHandle || modelHandle->IsDefaultModel() ) { + Mem_Free16( (*jointList) ); + (*jointList) = NULL; + frameBounds.Clear(); + return; + } + + // get the number of joints + num = modelHandle->NumJoints(); + + if ( !num ) { + gameLocal.Error( "model '%s' has no joints", modelHandle->Name() ); + } + + // set up initial pose for model (with no pose, model is just a jumbled mess) + list = (idJointMat *) Mem_Alloc16( num * sizeof( list[0] ) ); + pose = GetDefaultPose(); + + // convert the joint quaternions to joint matrices + SIMDProcessor->ConvertJointQuatsToJointMats( list, pose, joints.Num() ); + + // check if we offset the model by the origin joint + if ( removeOriginOffset ) { +#ifdef VELOCITY_MOVE + list[ 0 ].SetTranslation( idVec3( offset.x, offset.y + pose[0].t.y, offset.z + pose[0].t.z ) ); +#else + list[ 0 ].SetTranslation( offset ); +#endif + } else { + list[ 0 ].SetTranslation( pose[0].t + offset ); + } + + // transform the joint hierarchy + SIMDProcessor->TransformJoints( list, jointParents.Ptr(), 1, joints.Num() - 1 ); + + *numJoints = num; + *jointList = list; + + // get the bounds of the default pose + frameBounds = modelHandle->Bounds( NULL ); +} + +/* +===================== +idDeclModelDef::ParseAnim +===================== +*/ +bool idDeclModelDef::ParseAnim( idLexer &src, int numDefaultAnims ) { + int i; + int len; + idAnim *anim; + const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ]; + const idMD5Anim *md5anim; + idStr alias; + idToken realname; + idToken token; + int numAnims; + animFlags_t flags; + + numAnims = 0; + memset( md5anims, 0, sizeof( md5anims ) ); + + if( !src.ReadToken( &realname ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + alias = realname; + + for( i = 0; i < anims.Num(); i++ ) { + if ( !strcmp( anims[ i ]->FullName(), realname.c_str() ) ) { + break; + } + } + + if ( ( i < anims.Num() ) && ( i >= numDefaultAnims ) ) { + src.Warning( "Duplicate anim '%s'", realname.c_str() ); + MakeDefault(); + return false; + } + + if ( i < numDefaultAnims ) { + anim = anims[ i ]; + } else { + // create the alias associated with this animation + anim = new idAnim(); + anims.Append( anim ); + } + + // random anims end with a number. find the numeric suffix of the animation. + len = alias.Length(); + for( i = len - 1; i > 0; i-- ) { + if ( !isdigit( alias[ i ] ) ) { + break; + } + } + + // check for zero length name, or a purely numeric name + if ( i <= 0 ) { + src.Warning( "Invalid animation name '%s'", alias.c_str() ); + MakeDefault(); + return false; + } + + // remove the numeric suffix + alias.CapLength( i + 1 ); + + // parse the anims from the string + do { + if( !src.ReadToken( &token ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + + // lookup the animation + md5anim = animationLib.GetAnim( token ); + if ( !md5anim ) { + src.Warning( "Couldn't load anim '%s'", token.c_str() ); + MakeDefault(); + return false; + } + + md5anim->CheckModelHierarchy( modelHandle ); + + if ( numAnims > 0 ) { + // make sure it's the same length as the other anims + if ( md5anim->Length() != md5anims[ 0 ]->Length() ) { + src.Warning( "Anim '%s' does not match length of anim '%s'", md5anim->Name(), md5anims[ 0 ]->Name() ); + MakeDefault(); + return false; + } + } + + if ( numAnims >= ANIM_MaxSyncedAnims ) { + src.Warning( "Exceeded max synced anims (%d)", ANIM_MaxSyncedAnims ); + MakeDefault(); + return false; + } + + // add it to our list + md5anims[ numAnims ] = md5anim; + numAnims++; + } while ( src.CheckTokenString( "," ) ); + + if ( !numAnims ) { + src.Warning( "No animation specified" ); + MakeDefault(); + return false; + } + + anim->SetAnim( this, realname, alias, numAnims, md5anims ); + memset( &flags, 0, sizeof( flags ) ); + + // parse any frame commands or animflags + if ( src.CheckTokenString( "{" ) ) { + while( 1 ) { + if( !src.ReadToken( &token ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + if ( token == "}" ) { + break; + }else if ( token == "prevent_idle_override" ) { + flags.prevent_idle_override = true; + } else if ( token == "random_cycle_start" ) { + flags.random_cycle_start = true; + } else if ( token == "ai_no_turn" ) { + flags.ai_no_turn = true; + } else if ( token == "anim_turn" ) { + flags.anim_turn = true; + } else if ( token == "no_random_headturning" ) { + flags.no_random_headturning = true; + } else if ( token == "frame" ) { + // create a frame command + int framenum; + const char *err; + + // make sure we don't have any line breaks while reading the frame command so the error line # will be correct + if ( !src.ReadTokenOnLine( &token ) ) { + src.Warning( "Missing frame # after 'frame'" ); + MakeDefault(); + return false; + } + if ( token.type == TT_PUNCTUATION && token == "-" ) { + src.Warning( "Invalid frame # after 'frame'" ); + MakeDefault(); + return false; + } else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { + src.Error( "expected integer value, found '%s'", token.c_str() ); + } + + // get the frame number + framenum = token.GetIntValue(); + + // put the command on the specified frame of the animation + err = anim->AddFrameCommand( this, framenum, src, NULL ); + if ( err ) { + src.Warning( "%s", err ); + MakeDefault(); + return false; + } + } else { + src.Warning( "Unknown command '%s'", token.c_str() ); + MakeDefault(); + return false; + } + } + } + + // set the flags + anim->SetAnimFlags( flags ); + return true; +} + +/* +================ +idDeclModelDef::Parse +================ +*/ +bool idDeclModelDef::Parse( const char *text, const int textLength ) { + int i; + int num; + idStr filename; + idStr extension; + const idMD5Joint *md5joint; + const idMD5Joint *md5joints; + idLexer src; + idToken token; + idToken token2; + idStr jointnames; + int channel; + jointHandle_t jointnum; + idList jointList; + int numDefaultAnims; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + numDefaultAnims = 0; + while( 1 ) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + + if ( token == "inherit" ) { + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + + const idDeclModelDef *copy = static_cast( declManager->FindType( DECL_MODELDEF, token2, false ) ); + if ( !copy ) { + common->Warning( "Unknown model definition '%s'", token2.c_str() ); + } else if ( copy->GetState() == DS_DEFAULTED ) { + common->Warning( "inherited model definition '%s' defaulted", token2.c_str() ); + MakeDefault(); + return false; + } else { + CopyDecl( copy ); + numDefaultAnims = anims.Num(); + } + } else if ( token == "skin" ) { + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + skin = declManager->FindSkin( token2 ); + if ( !skin ) { + src.Warning( "Skin '%s' not found", token2.c_str() ); + MakeDefault(); + return false; + } + } else if ( token == "mesh" ) { + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + filename = token2; + filename.ExtractFileExtension( extension ); + if ( extension != MD5_MESH_EXT ) { + src.Warning( "Invalid model for MD5 mesh" ); + MakeDefault(); + return false; + } + modelHandle = renderModelManager->FindModel( filename ); + if ( !modelHandle ) { + src.Warning( "Model '%s' not found", filename.c_str() ); + MakeDefault(); + return false; + } + + if ( modelHandle->IsDefaultModel() ) { + src.Warning( "Model '%s' defaulted", filename.c_str() ); + MakeDefault(); + return false; + } + + // get the number of joints + num = modelHandle->NumJoints(); + if ( !num ) { + src.Warning( "Model '%s' has no joints", filename.c_str() ); + } + + // set up the joint hierarchy + joints.SetGranularity( 1 ); + joints.SetNum( num ); + jointParents.SetNum( num ); + channelJoints[0].SetNum( num ); + md5joints = modelHandle->GetJoints(); + md5joint = md5joints; + for( i = 0; i < num; i++, md5joint++ ) { + joints[i].channel = ANIMCHANNEL_ALL; + joints[i].num = static_cast( i ); + if ( md5joint->parent ) { + joints[i].parentNum = static_cast( md5joint->parent - md5joints ); + } else { + joints[i].parentNum = INVALID_JOINT; + } + jointParents[i] = joints[i].parentNum; + channelJoints[0][i] = i; + } + } else if ( token == "remove" ) { + // removes any anims whos name matches + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + num = 0; + for( i = 0; i < anims.Num(); i++ ) { + if ( ( token2 == anims[ i ]->Name() ) || ( token2 == anims[ i ]->FullName() ) ) { + delete anims[ i ]; + anims.RemoveIndex( i ); + if ( i >= numDefaultAnims ) { + src.Warning( "Anim '%s' was not inherited. Anim should be removed from the model def.", token2.c_str() ); + MakeDefault(); + return false; + } + i--; + numDefaultAnims--; + num++; + continue; + } + } + if ( !num ) { + src.Warning( "Couldn't find anim '%s' to remove", token2.c_str() ); + MakeDefault(); + return false; + } + } else if ( token == "anim" ) { + if ( !modelHandle ) { + src.Warning( "Must specify mesh before defining anims" ); + MakeDefault(); + return false; + } + if ( !ParseAnim( src, numDefaultAnims ) ) { + MakeDefault(); + return false; + } + } else if ( token == "offset" ) { + if ( !src.Parse1DMatrix( 3, offset.ToFloatPtr() ) ) { + src.Warning( "Expected vector following 'offset'" ); + MakeDefault(); + return false; + } + } else if ( token == "channel" ) { + if ( !modelHandle ) { + src.Warning( "Must specify mesh before defining channels" ); + MakeDefault(); + return false; + } + + // set the channel for a group of joints + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + if ( !src.CheckTokenString( "(" ) ) { + src.Warning( "Expected { after '%s'\n", token2.c_str() ); + MakeDefault(); + return false; + } + + for( i = ANIMCHANNEL_ALL + 1; i < ANIM_NumAnimChannels; i++ ) { +#if MACOS_X || __linux__ + if ( !strcasecmp( channelNames[ i ], token2.c_str() ) ) +#else + if ( !stricmp( channelNames[ i ], token2.c_str() ) ) +#endif + { + break; + } + } + + if ( i >= ANIM_NumAnimChannels ) { + src.Warning( "Unknown channel '%s'", token2.c_str() ); + MakeDefault(); + return false; + } + + channel = i; + jointnames = ""; + + while( !src.CheckTokenString( ")" ) ) { + if( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + MakeDefault(); + return false; + } + jointnames += token2; + if ( ( token2 != "*" ) && ( token2 != "-" ) ) { + jointnames += " "; + } + } + + GetJointList( jointnames, jointList ); + + channelJoints[ channel ].SetNum( jointList.Num() ); + for( num = i = 0; i < jointList.Num(); i++ ) { + jointnum = jointList[ i ]; + if ( joints[ jointnum ].channel != ANIMCHANNEL_ALL ) { + src.Warning( "Joint '%s' assigned to multiple channels", modelHandle->GetJointName( jointnum ) ); + continue; + } + joints[ jointnum ].channel = channel; + channelJoints[ channel ][ num++ ] = jointnum; + } + channelJoints[ channel ].SetNum( num ); + } else { + src.Warning( "unknown token '%s' on line %i in '%s'", token.c_str(), token.line, src.GetFileName() ); + MakeDefault(); + return false; + } + } + + // shrink the anim list down to save space + anims.SetGranularity( 1 ); + anims.SetNum( anims.Num() ); + + return true; +} + +/* +===================== +idDeclModelDef::HasAnim +===================== +*/ +bool idDeclModelDef::HasAnim( const char *name ) const { + int i; + + // find any animations with same name + for( i = 0; i < anims.Num(); i++ ) { + if ( !strcmp( anims[ i ]->Name(), name ) ) { + return true; + } + } + + return false; +} + +/* +===================== +idDeclModelDef::NumAnims +===================== +*/ +int idDeclModelDef::NumAnims( void ) const { + return anims.Num() + 1; +} + +/* +===================== +idDeclModelDef::GetSpecificAnim + +Gets the exact anim for the name, without randomization. +===================== +*/ +int idDeclModelDef::GetSpecificAnim( const char *name ) const { + int i; + + // find a specific animation + for( i = 0; i < anims.Num(); i++ ) { + if ( !strcmp( anims[ i ]->FullName(), name ) ) { + return i + 1; + } + } + + // didn't find it + return 0; +} + +/* +===================== +idDeclModelDef::GetAnim +===================== +*/ +const idAnim *idDeclModelDef::GetAnim( int index ) const { + if ( ( index < 1 ) || ( index > anims.Num() ) ) { + return NULL; + } + + return anims[ index - 1 ]; +} + +/* +===================== +idDeclModelDef::GetAnim +===================== +*/ +int idDeclModelDef::GetAnim( const char *name ) const { + int i; + int which; + const int MAX_ANIMS = 64; + int animList[ MAX_ANIMS ]; + int numAnims; + int len; + + len = strlen( name ); + if ( len && idStr::CharIsNumeric( name[ len - 1 ] ) ) { + // find a specific animation + return GetSpecificAnim( name ); + } + + // find all animations with same name + numAnims = 0; + for( i = 0; i < anims.Num(); i++ ) { + if ( !strcmp( anims[ i ]->Name(), name ) ) { + animList[ numAnims++ ] = i; + if ( numAnims >= MAX_ANIMS ) { + break; + } + } + } + + if ( !numAnims ) { + return 0; + } + + // get a random anim + //FIXME: don't access gameLocal here? + which = gameLocal.random.RandomInt( numAnims ); + return animList[ which ] + 1; +} + +/* +===================== +idDeclModelDef::GetSkin +===================== +*/ +const idDeclSkin *idDeclModelDef::GetSkin( void ) const { + return skin; +} + +/* +===================== +idDeclModelDef::GetModelName +===================== +*/ +const char *idDeclModelDef::GetModelName( void ) const { + if ( modelHandle ) { + return modelHandle->Name(); + } else { + return ""; + } +} + +/* +===================== +idDeclModelDef::Joints +===================== +*/ +const idList &idDeclModelDef::Joints( void ) const { + return joints; +} + +/* +===================== +idDeclModelDef::JointParents +===================== +*/ +const int * idDeclModelDef::JointParents( void ) const { + return jointParents.Ptr(); +} + +/* +===================== +idDeclModelDef::NumJoints +===================== +*/ +int idDeclModelDef::NumJoints( void ) const { + return joints.Num(); +} + +/* +===================== +idDeclModelDef::GetJoint +===================== +*/ +const jointInfo_t *idDeclModelDef::GetJoint( int jointHandle ) const { + if ( ( jointHandle < 0 ) || ( jointHandle > joints.Num() ) ) { + gameLocal.Error( "idDeclModelDef::GetJoint : joint handle out of range" ); + } + return &joints[ jointHandle ]; +} + +/* +==================== +idDeclModelDef::GetJointName +==================== +*/ +const char *idDeclModelDef::GetJointName( int jointHandle ) const { + const idMD5Joint *joint; + + if ( !modelHandle ) { + return NULL; + } + + if ( ( jointHandle < 0 ) || ( jointHandle > joints.Num() ) ) { + gameLocal.Error( "idDeclModelDef::GetJointName : joint handle out of range" ); + } + + joint = modelHandle->GetJoints(); + return joint[ jointHandle ].name.c_str(); +} + +/* +===================== +idDeclModelDef::NumJointsOnChannel +===================== +*/ +int idDeclModelDef::NumJointsOnChannel( int channel ) const { + if ( ( channel < 0 ) || ( channel >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idDeclModelDef::NumJointsOnChannel : channel out of range" ); + } + return channelJoints[ channel ].Num(); +} + +/* +===================== +idDeclModelDef::GetChannelJoints +===================== +*/ +const int * idDeclModelDef::GetChannelJoints( int channel ) const { + if ( ( channel < 0 ) || ( channel >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idDeclModelDef::GetChannelJoints : channel out of range" ); + } + return channelJoints[ channel ].Ptr(); +} + +/* +===================== +idDeclModelDef::GetVisualOffset +===================== +*/ +const idVec3 &idDeclModelDef::GetVisualOffset( void ) const { + return offset; +} + +/*********************************************************************** + + idAnimator + +***********************************************************************/ + +/* +===================== +idAnimator::idAnimator +===================== +*/ +idAnimator::idAnimator() { + int i, j; + + modelDef = NULL; + entity = NULL; + numJoints = 0; + joints = NULL; + lastTransformTime = -1; + stoppedAnimatingUpdate = false; + removeOriginOffset = false; + forceUpdate = false; + + frameBounds.Clear(); + + AFPoseJoints.SetGranularity( 1 ); + AFPoseJointMods.SetGranularity( 1 ); + AFPoseJointFrame.SetGranularity( 1 ); + + ClearAFPose(); + + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { + channels[ i ][ j ].Reset( NULL ); + } + } +} + +/* +===================== +idAnimator::~idAnimator +===================== +*/ +idAnimator::~idAnimator() { + FreeData(); +} + +/* +===================== +idAnimator::Allocated +===================== +*/ +size_t idAnimator::Allocated( void ) const { + size_t size; + + size = jointMods.Allocated() + numJoints * sizeof( joints[0] ) + jointMods.Num() * sizeof( jointMods[ 0 ] ) + AFPoseJointMods.Allocated() + AFPoseJointFrame.Allocated() + AFPoseJoints.Allocated(); + + return size; +} + +/* +===================== +idAnimator::Save + +archives object for save game file +===================== +*/ +void idAnimator::Save( idSaveGame *savefile ) const { + int i; + int j; + + savefile->WriteModelDef( modelDef ); + savefile->WriteObject( entity ); + + savefile->WriteInt( jointMods.Num() ); + for( i = 0; i < jointMods.Num(); i++ ) { + savefile->WriteInt( jointMods[ i ]->jointnum ); + savefile->WriteMat3( jointMods[ i ]->mat ); + savefile->WriteVec3( jointMods[ i ]->pos ); + savefile->WriteInt( (int&)jointMods[ i ]->transform_pos ); + savefile->WriteInt( (int&)jointMods[ i ]->transform_axis ); + } + + savefile->WriteInt( numJoints ); + for ( i = 0; i < numJoints; i++ ) { + float *data = joints[i].ToFloatPtr(); + for ( j = 0; j < 12; j++ ) { + savefile->WriteFloat( data[j] ); + } + } + + savefile->WriteInt( lastTransformTime ); + savefile->WriteBool( stoppedAnimatingUpdate ); + savefile->WriteBool( forceUpdate ); + savefile->WriteBounds( frameBounds ); + + savefile->WriteFloat( AFPoseBlendWeight ); + + savefile->WriteInt( AFPoseJoints.Num() ); + for ( i = 0; i < AFPoseJoints.Num(); i++ ) { + savefile->WriteInt( AFPoseJoints[i] ); + } + + savefile->WriteInt( AFPoseJointMods.Num() ); + for ( i = 0; i < AFPoseJointMods.Num(); i++ ) { + savefile->WriteInt( (int&)AFPoseJointMods[i].mod ); + savefile->WriteMat3( AFPoseJointMods[i].axis ); + savefile->WriteVec3( AFPoseJointMods[i].origin ); + } + + savefile->WriteInt( AFPoseJointFrame.Num() ); + for ( i = 0; i < AFPoseJointFrame.Num(); i++ ) { + savefile->WriteFloat( AFPoseJointFrame[i].q.x ); + savefile->WriteFloat( AFPoseJointFrame[i].q.y ); + savefile->WriteFloat( AFPoseJointFrame[i].q.z ); + savefile->WriteFloat( AFPoseJointFrame[i].q.w ); + savefile->WriteVec3( AFPoseJointFrame[i].t ); + } + + savefile->WriteBounds( AFPoseBounds ); + savefile->WriteInt( AFPoseTime ); + + savefile->WriteBool( removeOriginOffset ); + + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { + channels[ i ][ j ].Save( savefile ); + } + } +} + +/* +===================== +idAnimator::Restore + +unarchives object from save game file +===================== +*/ +void idAnimator::Restore( idRestoreGame *savefile ) { + int i; + int j; + int num; + + savefile->ReadModelDef( modelDef ); + savefile->ReadObject( reinterpret_cast( entity ) ); + + savefile->ReadInt( num ); + jointMods.SetNum( num ); + for( i = 0; i < num; i++ ) { + jointMods[ i ] = new jointMod_t; + savefile->ReadInt( (int&)jointMods[ i ]->jointnum ); + savefile->ReadMat3( jointMods[ i ]->mat ); + savefile->ReadVec3( jointMods[ i ]->pos ); + savefile->ReadInt( (int&)jointMods[ i ]->transform_pos ); + savefile->ReadInt( (int&)jointMods[ i ]->transform_axis ); + } + + savefile->ReadInt( numJoints ); + joints = (idJointMat *) Mem_Alloc16( numJoints * sizeof( joints[0] ) ); + for ( i = 0; i < numJoints; i++ ) { + float *data = joints[i].ToFloatPtr(); + for ( j = 0; j < 12; j++ ) { + savefile->ReadFloat( data[j] ); + } + } + + savefile->ReadInt( lastTransformTime ); + savefile->ReadBool( stoppedAnimatingUpdate ); + savefile->ReadBool( forceUpdate ); + savefile->ReadBounds( frameBounds ); + + savefile->ReadFloat( AFPoseBlendWeight ); + + savefile->ReadInt( num ); + AFPoseJoints.SetGranularity( 1 ); + AFPoseJoints.SetNum( num ); + for ( i = 0; i < AFPoseJoints.Num(); i++ ) { + savefile->ReadInt( AFPoseJoints[i] ); + } + + savefile->ReadInt( num ); + AFPoseJointMods.SetGranularity( 1 ); + AFPoseJointMods.SetNum( num ); + for ( i = 0; i < AFPoseJointMods.Num(); i++ ) { + savefile->ReadInt( (int&)AFPoseJointMods[i].mod ); + savefile->ReadMat3( AFPoseJointMods[i].axis ); + savefile->ReadVec3( AFPoseJointMods[i].origin ); + } + + savefile->ReadInt( num ); + AFPoseJointFrame.SetGranularity( 1 ); + AFPoseJointFrame.SetNum( num ); + for ( i = 0; i < AFPoseJointFrame.Num(); i++ ) { + savefile->ReadFloat( AFPoseJointFrame[i].q.x ); + savefile->ReadFloat( AFPoseJointFrame[i].q.y ); + savefile->ReadFloat( AFPoseJointFrame[i].q.z ); + savefile->ReadFloat( AFPoseJointFrame[i].q.w ); + savefile->ReadVec3( AFPoseJointFrame[i].t ); + } + + savefile->ReadBounds( AFPoseBounds ); + savefile->ReadInt( AFPoseTime ); + + savefile->ReadBool( removeOriginOffset ); + + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { + channels[ i ][ j ].Restore( savefile, modelDef ); + } + } +} + +/* +===================== +idAnimator::FreeData +===================== +*/ +void idAnimator::FreeData( void ) { + int i, j; + + if ( entity ) { + entity->BecomeInactive( TH_ANIMATE ); + } + + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { + channels[ i ][ j ].Reset( NULL ); + } + } + + jointMods.DeleteContents( true ); + + Mem_Free16( joints ); + joints = NULL; + numJoints = 0; + + modelDef = NULL; + + ForceUpdate(); +} + +/* +===================== +idAnimator::PushAnims +===================== +*/ +void idAnimator::PushAnims( int channelNum, int currentTime, int blendTime ) { + int i; + idAnimBlend *channel; + + channel = channels[ channelNum ]; + if ( !channel[ 0 ].GetWeight( currentTime ) || ( channel[ 0 ].starttime == currentTime ) ) { + return; + } + + for( i = ANIM_MaxAnimsPerChannel - 1; i > 0; i-- ) { + channel[ i ] = channel[ i - 1 ]; + } + + channel[ 0 ].Reset( modelDef ); + channel[ 1 ].Clear( currentTime, blendTime ); + ForceUpdate(); +} + +/* +===================== +idAnimator::SetModel +===================== +*/ +idRenderModel *idAnimator::SetModel( const char *modelname ) { + int i, j; + + FreeData(); + + // check if we're just clearing the model + if ( !modelname || !*modelname ) { + return NULL; + } + + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); + if ( !modelDef ) { + return NULL; + } + + idRenderModel *renderModel = modelDef->ModelHandle(); + if ( !renderModel ) { + modelDef = NULL; + return NULL; + } + + // make sure model hasn't been purged + modelDef->Touch(); + + modelDef->SetupJoints( &numJoints, &joints, frameBounds, removeOriginOffset ); + modelDef->ModelHandle()->Reset(); + + // set the modelDef on all channels + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { + channels[ i ][ j ].Reset( modelDef ); + } + } + + return modelDef->ModelHandle(); +} + +/* +===================== +idAnimator::Size +===================== +*/ +size_t idAnimator::Size( void ) const { + return sizeof( *this ) + Allocated(); +} + +/* +===================== +idAnimator::SetEntity +===================== +*/ +void idAnimator::SetEntity( idEntity *ent ) { + entity = ent; +} + +/* +===================== +idAnimator::GetEntity +===================== +*/ +idEntity *idAnimator::GetEntity( void ) const { + return entity; +} + +/* +===================== +idAnimator::RemoveOriginOffset +===================== +*/ +void idAnimator::RemoveOriginOffset( bool remove ) { + removeOriginOffset = remove; +} + +/* +===================== +idAnimator::RemoveOrigin +===================== +*/ +bool idAnimator::RemoveOrigin( void ) const { + return removeOriginOffset; +} + +/* +===================== +idAnimator::GetJointList +===================== +*/ +void idAnimator::GetJointList( const char *jointnames, idList &jointList ) const { + if ( modelDef ) { + modelDef->GetJointList( jointnames, jointList ); + } +} + +/* +===================== +idAnimator::NumAnims +===================== +*/ +int idAnimator::NumAnims( void ) const { + if ( !modelDef ) { + return 0; + } + + return modelDef->NumAnims(); +} + +/* +===================== +idAnimator::GetAnim +===================== +*/ +const idAnim *idAnimator::GetAnim( int index ) const { + if ( !modelDef ) { + return NULL; + } + + return modelDef->GetAnim( index ); +} + +/* +===================== +idAnimator::GetAnim +===================== +*/ +int idAnimator::GetAnim( const char *name ) const { + if ( !modelDef ) { + return 0; + } + + return modelDef->GetAnim( name ); +} + +/* +===================== +idAnimator::HasAnim +===================== +*/ +bool idAnimator::HasAnim( const char *name ) const { + if ( !modelDef ) { + return false; + } + + return modelDef->HasAnim( name ); +} + +/* +===================== +idAnimator::NumJoints +===================== +*/ +int idAnimator::NumJoints( void ) const { + return numJoints; +} + +/* +===================== +idAnimator::ModelHandle +===================== +*/ +idRenderModel *idAnimator::ModelHandle( void ) const { + if ( !modelDef ) { + return NULL; + } + + return modelDef->ModelHandle(); +} + +/* +===================== +idAnimator::ModelDef +===================== +*/ +const idDeclModelDef *idAnimator::ModelDef( void ) const { + return modelDef; +} + +/* +===================== +idAnimator::CurrentAnim +===================== +*/ +idAnimBlend *idAnimator::CurrentAnim( int channelNum ) { + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::CurrentAnim : channel out of range" ); + } + + return &channels[ channelNum ][ 0 ]; +} + +/* +===================== +idAnimator::Clear +===================== +*/ +void idAnimator::Clear( int channelNum, int currentTime, int cleartime ) { + int i; + idAnimBlend *blend; + + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::Clear : channel out of range" ); + } + + blend = channels[ channelNum ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->Clear( currentTime, cleartime ); + } + ForceUpdate(); +} + +/* +===================== +idAnimator::SetFrame +===================== +*/ +void idAnimator::SetFrame( int channelNum, int animNum, int frame, int currentTime, int blendTime ) { + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::SetFrame : channel out of range" ); + } + + if ( !modelDef || !modelDef->GetAnim( animNum ) ) { + return; + } + + PushAnims( channelNum, currentTime, blendTime ); + channels[ channelNum ][ 0 ].SetFrame( modelDef, animNum, frame, currentTime, blendTime, entity ); + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } +} + +/* +===================== +idAnimator::CycleAnim +===================== +*/ +void idAnimator::CycleAnim( int channelNum, int animNum, int currentTime, int blendTime ) { + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::CycleAnim : channel out of range" ); + } + + if ( !modelDef || !modelDef->GetAnim( animNum ) ) { + return; + } + + PushAnims( channelNum, currentTime, blendTime ); + channels[ channelNum ][ 0 ].CycleAnim( modelDef, animNum, currentTime, blendTime, entity ); + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } +} + +/* +===================== +idAnimator::PlayAnim +===================== +*/ +void idAnimator::PlayAnim( int channelNum, int animNum, int currentTime, int blendTime ) { + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::PlayAnim : channel out of range" ); + } + + if ( !modelDef || !modelDef->GetAnim( animNum ) ) { + return; + } + + PushAnims( channelNum, currentTime, blendTime ); + channels[ channelNum ][ 0 ].PlayAnim( modelDef, animNum, currentTime, blendTime, entity ); + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } +} + +/* +===================== +idAnimator::SyncAnimChannels +===================== +*/ +void idAnimator::SyncAnimChannels( int channelNum, int fromChannelNum, int currentTime, int blendTime ) { + if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) || ( fromChannelNum < 0 ) || ( fromChannelNum >= ANIM_NumAnimChannels ) ) { + gameLocal.Error( "idAnimator::SyncToChannel : channel out of range" ); + } + + idAnimBlend &fromBlend = channels[ fromChannelNum ][ 0 ]; + idAnimBlend &toBlend = channels[ channelNum ][ 0 ]; + + float weight = fromBlend.blendEndValue; + if ( ( fromBlend.Anim() != toBlend.Anim() ) || ( fromBlend.GetStartTime() != toBlend.GetStartTime() ) || ( fromBlend.GetEndTime() != toBlend.GetEndTime() ) ) { + PushAnims( channelNum, currentTime, blendTime ); + toBlend = fromBlend; + toBlend.blendStartValue = 0.0f; + toBlend.blendEndValue = 0.0f; + } + toBlend.SetWeight( weight, currentTime - 1, blendTime ); + + // disable framecommands on the current channel so that commands aren't called twice + toBlend.AllowFrameCommands( false ); + + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } +} + +/* +===================== +idAnimator::SetJointPos +===================== +*/ +void idAnimator::SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ) { + int i; + jointMod_t *jointMod; + + if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { + return; + } + + jointMod = NULL; + for( i = 0; i < jointMods.Num(); i++ ) { + if ( jointMods[ i ]->jointnum == jointnum ) { + jointMod = jointMods[ i ]; + break; + } else if ( jointMods[ i ]->jointnum > jointnum ) { + break; + } + } + + if ( !jointMod ) { + jointMod = new jointMod_t; + jointMod->jointnum = jointnum; + jointMod->mat.Identity(); + jointMod->transform_axis = JOINTMOD_NONE; + jointMods.Insert( jointMod, i ); + } + + jointMod->pos = pos; + jointMod->transform_pos = transform_type; + + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } + ForceUpdate(); +} + +/* +===================== +idAnimator::SetJointAxis +===================== +*/ +void idAnimator::SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat ) { + int i; + jointMod_t *jointMod; + + if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { + return; + } + + jointMod = NULL; + for( i = 0; i < jointMods.Num(); i++ ) { + if ( jointMods[ i ]->jointnum == jointnum ) { + jointMod = jointMods[ i ]; + break; + } else if ( jointMods[ i ]->jointnum > jointnum ) { + break; + } + } + + if ( !jointMod ) { + jointMod = new jointMod_t; + jointMod->jointnum = jointnum; + jointMod->pos.Zero(); + jointMod->transform_pos = JOINTMOD_NONE; + jointMods.Insert( jointMod, i ); + } + + jointMod->mat = mat; + jointMod->transform_axis = transform_type; + + if ( entity ) { + entity->BecomeActive( TH_ANIMATE ); + } + ForceUpdate(); +} + +/* +===================== +idAnimator::ClearJoint +===================== +*/ +void idAnimator::ClearJoint( jointHandle_t jointnum ) { + int i; + + if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { + return; + } + + for( i = 0; i < jointMods.Num(); i++ ) { + if ( jointMods[ i ]->jointnum == jointnum ) { + delete jointMods[ i ]; + jointMods.RemoveIndex( i ); + ForceUpdate(); + break; + } else if ( jointMods[ i ]->jointnum > jointnum ) { + break; + } + } +} + +/* +===================== +idAnimator::ClearAllJoints +===================== +*/ +void idAnimator::ClearAllJoints( void ) { + if ( jointMods.Num() ) { + ForceUpdate(); + } + jointMods.DeleteContents( true ); +} + +/* +===================== +idAnimator::ClearAllAnims +===================== +*/ +void idAnimator::ClearAllAnims( int currentTime, int cleartime ) { + int i; + + for( i = 0; i < ANIM_NumAnimChannels; i++ ) { + Clear( i, currentTime, cleartime ); + } + + ClearAFPose(); + ForceUpdate(); +} + +/* +==================== +idAnimator::GetDelta +==================== +*/ +void idAnimator::GetDelta( int fromtime, int totime, idVec3 &delta ) const { + int i; + const idAnimBlend *blend; + float blendWeight; + + if ( !modelDef || !modelDef->ModelHandle() || ( fromtime == totime ) ) { + delta.Zero(); + return; + } + + delta.Zero(); + blendWeight = 0.0f; + + blend = channels[ ANIMCHANNEL_ALL ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendDelta( fromtime, totime, delta, blendWeight ); + } + + if ( modelDef->Joints()[ 0 ].channel ) { + blend = channels[ modelDef->Joints()[ 0 ].channel ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendDelta( fromtime, totime, delta, blendWeight ); + } + } +} + +/* +==================== +idAnimator::GetDeltaRotation +==================== +*/ +bool idAnimator::GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const { + int i; + const idAnimBlend *blend; + float blendWeight; + idQuat q; + + if ( !modelDef || !modelDef->ModelHandle() || ( fromtime == totime ) ) { + delta.Identity(); + return false; + } + + q.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + blendWeight = 0.0f; + + blend = channels[ ANIMCHANNEL_ALL ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendDeltaRotation( fromtime, totime, q, blendWeight ); + } + + if ( modelDef->Joints()[ 0 ].channel ) { + blend = channels[ modelDef->Joints()[ 0 ].channel ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendDeltaRotation( fromtime, totime, q, blendWeight ); + } + } + + if ( blendWeight > 0.0f ) { + delta = q.ToMat3(); + return true; + } else { + delta.Identity(); + return false; + } +} + +/* +==================== +idAnimator::GetOrigin +==================== +*/ +void idAnimator::GetOrigin( int currentTime, idVec3 &pos ) const { + int i; + const idAnimBlend *blend; + float blendWeight; + + if ( !modelDef || !modelDef->ModelHandle() ) { + pos.Zero(); + return; + } + + pos.Zero(); + blendWeight = 0.0f; + + blend = channels[ ANIMCHANNEL_ALL ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendOrigin( currentTime, pos, blendWeight, removeOriginOffset ); + } + + if ( modelDef->Joints()[ 0 ].channel ) { + blend = channels[ modelDef->Joints()[ 0 ].channel ]; + for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { + blend->BlendOrigin( currentTime, pos, blendWeight, removeOriginOffset ); + } + } + + pos += modelDef->GetVisualOffset(); +} + +/* +==================== +idAnimator::GetBounds +==================== +*/ +bool idAnimator::GetBounds( int currentTime, idBounds &bounds ) { + int i, j; + const idAnimBlend *blend; + int count; + + if ( !modelDef || !modelDef->ModelHandle() ) { + return false; + } + + if ( AFPoseJoints.Num() ) { + bounds = AFPoseBounds; + count = 1; + } else { + bounds.Clear(); + count = 0; + } + + blend = channels[ 0 ]; + for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( blend->AddBounds( currentTime, bounds, removeOriginOffset ) ) { + count++; + } + } + } + + if ( !count ) { + if ( !frameBounds.IsCleared() ) { + bounds = frameBounds; + return true; + } else { + bounds.Zero(); + return false; + } + } + + bounds.TranslateSelf( modelDef->GetVisualOffset() ); + + if ( g_debugBounds.GetBool() ) { + if ( bounds[1][0] - bounds[0][0] > 2048 || bounds[1][1] - bounds[0][1] > 2048 ) { + if ( entity ) { + gameLocal.Warning( "big frameBounds on entity '%s' with model '%s': %f,%f", entity->name.c_str(), modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] ); + } else { + gameLocal.Warning( "big frameBounds on model '%s': %f,%f", modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] ); + } + } + } + + frameBounds = bounds; + + return true; +} + +/* +===================== +idAnimator::InitAFPose +===================== +*/ +void idAnimator::InitAFPose( void ) { + + if ( !modelDef ) { + return; + } + + AFPoseJoints.SetNum( modelDef->Joints().Num(), false ); + AFPoseJoints.SetNum( 0, false ); + AFPoseJointMods.SetNum( modelDef->Joints().Num(), false ); + AFPoseJointFrame.SetNum( modelDef->Joints().Num(), false ); +} + +/* +===================== +idAnimator::SetAFPoseJointMod +===================== +*/ +void idAnimator::SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin ) { + AFPoseJointMods[jointNum].mod = mod; + AFPoseJointMods[jointNum].axis = axis; + AFPoseJointMods[jointNum].origin = origin; + + int index = idBinSearch_GreaterEqual( AFPoseJoints.Ptr(), AFPoseJoints.Num(), jointNum ); + if ( index >= AFPoseJoints.Num() || jointNum != AFPoseJoints[index] ) { + AFPoseJoints.Insert( jointNum, index ); + } +} + +/* +===================== +idAnimator::FinishAFPose +===================== +*/ +void idAnimator::FinishAFPose( int animNum, const idBounds &bounds, const int time ) { + int i, j; + int numJoints; + int parentNum; + int jointMod; + int jointNum; + const int * jointParent; + + if ( !modelDef ) { + return; + } + + const idAnim *anim = modelDef->GetAnim( animNum ); + if ( !anim ) { + return; + } + + numJoints = modelDef->Joints().Num(); + if ( !numJoints ) { + return; + } + + idRenderModel *md5 = modelDef->ModelHandle(); + const idMD5Anim *md5anim = anim->MD5Anim( 0 ); + + if ( numJoints != md5anim->NumJoints() ) { + gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", md5->Name(), md5anim->Name() ); + return; + } + + idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); + md5anim->GetSingleFrame( 0, jointFrame, modelDef->GetChannelJoints( ANIMCHANNEL_ALL ), modelDef->NumJointsOnChannel( ANIMCHANNEL_ALL ) ); + + if ( removeOriginOffset ) { +#ifdef VELOCITY_MOVE + jointFrame[ 0 ].t.x = 0.0f; +#else + jointFrame[ 0 ].t.Zero(); +#endif + } + + idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( *joints ) ); + + // convert the joint quaternions to joint matrices + SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); + + // first joint is always root of entire hierarchy + if ( AFPoseJoints.Num() && AFPoseJoints[0] == 0 ) { + switch( AFPoseJointMods[0].mod ) { + case AF_JOINTMOD_AXIS: { + joints[0].SetRotation( AFPoseJointMods[0].axis ); + break; + } + case AF_JOINTMOD_ORIGIN: { + joints[0].SetTranslation( AFPoseJointMods[0].origin ); + break; + } + case AF_JOINTMOD_BOTH: { + joints[0].SetRotation( AFPoseJointMods[0].axis ); + joints[0].SetTranslation( AFPoseJointMods[0].origin ); + break; + } + default: break; + } + j = 1; + } else { + j = 0; + } + + // pointer to joint info + jointParent = modelDef->JointParents(); + + // transform the child joints + for( i = 1; j < AFPoseJoints.Num(); j++, i++ ) { + jointMod = AFPoseJoints[j]; + + // transform any joints preceding the joint modifier + SIMDProcessor->TransformJoints( joints, jointParent, i, jointMod - 1 ); + i = jointMod; + + parentNum = jointParent[i]; + + switch( AFPoseJointMods[jointMod].mod ) { + case AF_JOINTMOD_AXIS: { + joints[i].SetRotation( AFPoseJointMods[jointMod].axis ); + joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() ); + break; + } + case AF_JOINTMOD_ORIGIN: { + joints[i].SetRotation( joints[i].ToMat3() * joints[parentNum].ToMat3() ); + joints[i].SetTranslation( AFPoseJointMods[jointMod].origin ); + break; + } + case AF_JOINTMOD_BOTH: { + joints[i].SetRotation( AFPoseJointMods[jointMod].axis ); + joints[i].SetTranslation( AFPoseJointMods[jointMod].origin ); + break; + } + default: break; + } + } + + // transform the rest of the hierarchy + SIMDProcessor->TransformJoints( joints, jointParent, i, numJoints - 1 ); + + // untransform hierarchy + SIMDProcessor->UntransformJoints( joints, jointParent, 1, numJoints - 1 ); + + // convert joint matrices back to joint quaternions + SIMDProcessor->ConvertJointMatsToJointQuats( AFPoseJointFrame.Ptr(), joints, numJoints ); + + // find all modified joints and their parents + bool *blendJoints = (bool *) _alloca16( numJoints * sizeof( bool ) ); + memset( blendJoints, 0, numJoints * sizeof( bool ) ); + + // mark all modified joints and their parents + for( i = 0; i < AFPoseJoints.Num(); i++ ) { + for( jointNum = AFPoseJoints[i]; jointNum != INVALID_JOINT; jointNum = jointParent[jointNum] ) { + blendJoints[jointNum] = true; + } + } + + // lock all parents of modified joints + AFPoseJoints.SetNum( 0, false ); + for ( i = 0; i < numJoints; i++ ) { + if ( blendJoints[i] ) { + AFPoseJoints.Append( i ); + } + } + + AFPoseBounds = bounds; + AFPoseTime = time; + + ForceUpdate(); +} + +/* +===================== +idAnimator::SetAFPoseBlendWeight +===================== +*/ +void idAnimator::SetAFPoseBlendWeight( float blendWeight ) { + AFPoseBlendWeight = blendWeight; +} + +/* +===================== +idAnimator::BlendAFPose +===================== +*/ +bool idAnimator::BlendAFPose( idJointQuat *blendFrame ) const { + + if ( !AFPoseJoints.Num() ) { + return false; + } + + SIMDProcessor->BlendJoints( blendFrame, AFPoseJointFrame.Ptr(), AFPoseBlendWeight, AFPoseJoints.Ptr(), AFPoseJoints.Num() ); + + return true; +} + +/* +===================== +idAnimator::ClearAFPose +===================== +*/ +void idAnimator::ClearAFPose( void ) { + if ( AFPoseJoints.Num() ) { + ForceUpdate(); + } + AFPoseBlendWeight = 1.0f; + AFPoseJoints.SetNum( 0, false ); + AFPoseBounds.Clear(); + AFPoseTime = 0; +} + +/* +===================== +idAnimator::ServiceAnims +===================== +*/ +void idAnimator::ServiceAnims( int fromtime, int totime ) { + int i, j; + idAnimBlend *blend; + + if ( !modelDef ) { + return; + } + + if ( modelDef->ModelHandle() ) { + blend = channels[ 0 ]; + for( i = 0; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + blend->CallFrameCommands( entity, fromtime, totime ); + } + } + } + + if ( !IsAnimating( totime ) ) { + stoppedAnimatingUpdate = true; + if ( entity ) { + entity->BecomeInactive( TH_ANIMATE ); + + // present one more time with stopped animations so the renderer can properly recreate interactions + entity->BecomeActive( TH_UPDATEVISUALS ); + } + } +} + +/* +===================== +idAnimator::IsAnimating +===================== +*/ +bool idAnimator::IsAnimating( int currentTime ) const { + int i, j; + const idAnimBlend *blend; + + if ( !modelDef || !modelDef->ModelHandle() ) { + return false; + } + + // if animating with an articulated figure + if ( AFPoseJoints.Num() && currentTime <= AFPoseTime ) { + return true; + } + + blend = channels[ 0 ]; + for( i = 0; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( !blend->IsDone( currentTime ) ) { + return true; + } + } + } + + return false; +} + +/* +===================== +idAnimator::FrameHasChanged +===================== +*/ +bool idAnimator::FrameHasChanged( int currentTime ) const { + int i, j; + const idAnimBlend *blend; + + if ( !modelDef || !modelDef->ModelHandle() ) { + return false; + } + + // if animating with an articulated figure + if ( AFPoseJoints.Num() && currentTime <= AFPoseTime ) { + return true; + } + + blend = channels[ 0 ]; + for( i = 0; i < ANIM_NumAnimChannels; i++ ) { + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( blend->FrameHasChanged( currentTime ) ) { + return true; + } + } + } + + if ( forceUpdate && IsAnimating( currentTime ) ) { + return true; + } + + return false; +} + +/* +===================== +idAnimator::CreateFrame +===================== +*/ +bool idAnimator::CreateFrame( int currentTime, bool force ) { + int i, j; + int numJoints; + int parentNum; + bool hasAnim; + bool debugInfo; + float baseBlend; + float blendWeight; + const idAnimBlend * blend; + const int * jointParent; + const jointMod_t * jointMod; + const idJointQuat * defaultPose; + + static idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); + + if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { + return false; + } + + if ( !modelDef || !modelDef->ModelHandle() ) { + return false; + } + + if ( !force && !r_showSkel.GetInteger() ) { + if ( lastTransformTime == currentTime ) { + return false; + } + if ( lastTransformTime != -1 && !stoppedAnimatingUpdate && !IsAnimating( currentTime ) ) { + return false; + } + } + + // Optional optimisation: Skip animations for dormant entities + if (cv_ai_opt_noanims.GetBool() && entity->CheckDormant()) return false; + + lastTransformTime = currentTime; + stoppedAnimatingUpdate = false; + + if ( entity && ( ( g_debugAnim.GetInteger() == entity->entityNumber ) || ( g_debugAnim.GetInteger() == -2 ) ) ) { + debugInfo = true; + gameLocal.Printf( "---------------\n%d: entity '%s':\n", gameLocal.time, entity->GetName() ); + gameLocal.Printf( "model '%s':\n", modelDef->GetModelName() ); + } else { + debugInfo = false; + } + + // init the joint buffer + if ( AFPoseJoints.Num() ) { + // initialize with AF pose anim for the case where there are no other animations and no AF pose joint modifications + defaultPose = AFPoseJointFrame.Ptr(); + } else { + defaultPose = modelDef->GetDefaultPose(); + } + + if ( !defaultPose ) { + //gameLocal.Warning( "idAnimator::CreateFrame: no defaultPose on '%s'", modelDef->Name() ); + return false; + } + + numJoints = modelDef->Joints().Num(); + idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( jointFrame[0] ) ); + SIMDProcessor->Memcpy( jointFrame, defaultPose, numJoints * sizeof( jointFrame[0] ) ); + + hasAnim = false; + + // blend the all channel + baseBlend = 0.0f; + blend = channels[ ANIMCHANNEL_ALL ]; + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( blend->BlendAnim( currentTime, ANIMCHANNEL_ALL, numJoints, jointFrame, baseBlend, removeOriginOffset, false, debugInfo ) ) { + hasAnim = true; + if ( baseBlend >= 1.0f ) { + break; + } + } + } + + // only blend other channels if there's enough space to blend into + if ( baseBlend < 1.0f ) { + for( i = ANIMCHANNEL_ALL + 1; i < ANIM_NumAnimChannels; i++ ) { + if ( !modelDef->NumJointsOnChannel( i ) ) { + continue; + } + if ( i == ANIMCHANNEL_EYELIDS ) { + // eyelids blend over any previous anims, so skip it and blend it later + continue; + } + blendWeight = baseBlend; + blend = channels[ i ]; + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( blend->BlendAnim( currentTime, i, numJoints, jointFrame, blendWeight, removeOriginOffset, false, debugInfo ) ) { + hasAnim = true; + if ( blendWeight >= 1.0f ) { + // fully blended + break; + } + } + } + + if ( debugInfo && !AFPoseJoints.Num() && !blendWeight ) { + gameLocal.Printf( "%d: %s using default pose in model '%s'\n", gameLocal.time, channelNames[ i ], modelDef->GetModelName() ); + } + } + } + + // blend in the eyelids + if ( modelDef->NumJointsOnChannel( ANIMCHANNEL_EYELIDS ) ) { + blend = channels[ ANIMCHANNEL_EYELIDS ]; + blendWeight = baseBlend; + for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { + if ( blend->BlendAnim( currentTime, ANIMCHANNEL_EYELIDS, numJoints, jointFrame, blendWeight, removeOriginOffset, true, debugInfo ) ) { + hasAnim = true; + if ( blendWeight >= 1.0f ) { + // fully blended + break; + } + } + } + } + + // blend the articulated figure pose + if ( BlendAFPose( jointFrame ) ) { + hasAnim = true; + } + + if ( !hasAnim && !jointMods.Num() ) { + // no animations were updated + return false; + } + + // convert the joint quaternions to rotation matrices + SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); + + // check if we need to modify the origin + if ( jointMods.Num() && ( jointMods[0]->jointnum == 0 ) ) { + jointMod = jointMods[0]; + + switch( jointMod->transform_axis ) { + case JOINTMOD_NONE: + break; + + case JOINTMOD_LOCAL: + joints[0].SetRotation( jointMod->mat * joints[0].ToMat3() ); + break; + + case JOINTMOD_WORLD: + joints[0].SetRotation( joints[0].ToMat3() * jointMod->mat ); + break; + + case JOINTMOD_LOCAL_OVERRIDE: + case JOINTMOD_WORLD_OVERRIDE: + joints[0].SetRotation( jointMod->mat ); + break; + } + + switch( jointMod->transform_pos ) { + case JOINTMOD_NONE: + break; + + case JOINTMOD_LOCAL: + joints[0].SetTranslation( joints[0].ToVec3() + jointMod->pos ); + break; + + case JOINTMOD_LOCAL_OVERRIDE: + case JOINTMOD_WORLD: + case JOINTMOD_WORLD_OVERRIDE: + joints[0].SetTranslation( jointMod->pos ); + break; + } + j = 1; + } else { + j = 0; + } + + // add in the model offset + joints[0].SetTranslation( joints[0].ToVec3() + modelDef->GetVisualOffset() ); + + // pointer to joint info + jointParent = modelDef->JointParents(); + + // add in any joint modifications + for( i = 1; j < jointMods.Num(); j++, i++ ) { + jointMod = jointMods[j]; + + // transform any joints preceding the joint modifier + SIMDProcessor->TransformJoints( joints, jointParent, i, jointMod->jointnum - 1 ); + i = jointMod->jointnum; + + parentNum = jointParent[i]; + + // modify the axis + switch( jointMod->transform_axis ) { + case JOINTMOD_NONE: + joints[i].SetRotation( joints[i].ToMat3() * joints[ parentNum ].ToMat3() ); + break; + + case JOINTMOD_LOCAL: + joints[i].SetRotation( jointMod->mat * ( joints[i].ToMat3() * joints[parentNum].ToMat3() ) ); + break; + + case JOINTMOD_LOCAL_OVERRIDE: + joints[i].SetRotation( jointMod->mat * joints[parentNum].ToMat3() ); + break; + + case JOINTMOD_WORLD: + joints[i].SetRotation( ( joints[i].ToMat3() * joints[parentNum].ToMat3() ) * jointMod->mat ); + break; + + case JOINTMOD_WORLD_OVERRIDE: + joints[i].SetRotation( jointMod->mat ); + break; + } + + // modify the position + switch( jointMod->transform_pos ) { + case JOINTMOD_NONE: + joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() ); + break; + + case JOINTMOD_LOCAL: + joints[i].SetTranslation( joints[parentNum].ToVec3() + ( joints[i].ToVec3() + jointMod->pos ) * joints[parentNum].ToMat3() ); + break; + + case JOINTMOD_LOCAL_OVERRIDE: + joints[i].SetTranslation( joints[parentNum].ToVec3() + jointMod->pos * joints[parentNum].ToMat3() ); + break; + + case JOINTMOD_WORLD: + joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() + jointMod->pos ); + break; + + case JOINTMOD_WORLD_OVERRIDE: + joints[i].SetTranslation( jointMod->pos ); + break; + } + } + + // transform the rest of the hierarchy + SIMDProcessor->TransformJoints( joints, jointParent, i, numJoints - 1 ); + + return true; +} + +/* +===================== +idAnimator::ForceUpdate +===================== +*/ +void idAnimator::ForceUpdate( void ) { + lastTransformTime = -1; + forceUpdate = true; +} + +/* +===================== +idAnimator::ClearForceUpdate +===================== +*/ +void idAnimator::ClearForceUpdate( void ) { + forceUpdate = false; +} + +/* +===================== +idAnimator::GetJointTransform> gamex86.dll!idAnimator::ForceUpdate() Line 4268 C++ + +===================== +*/ +bool idAnimator::GetJointTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { + if ( !modelDef || ( jointHandle < 0 ) || ( jointHandle >= modelDef->NumJoints() ) ) { + return false; + } + + CreateFrame( currentTime, false ); + + offset = joints[ jointHandle ].ToVec3(); + axis = joints[ jointHandle ].ToMat3(); + + return true; +} + +/* +===================== +idAnimator::GetJointLocalTransform +===================== +*/ +bool idAnimator::GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { + if ( !modelDef ) { + return false; + } + + const idList &modelJoints = modelDef->Joints(); + + if ( ( jointHandle < 0 ) || ( jointHandle >= modelJoints.Num() ) ) { + return false; + } + + // FIXME: overkill + CreateFrame( currentTime, false ); + + if ( jointHandle > 0 ) { + idJointMat m = joints[ jointHandle ]; + m /= joints[ modelJoints[ jointHandle ].parentNum ]; + offset = m.ToVec3(); + axis = m.ToMat3(); + } else { + offset = joints[ jointHandle ].ToVec3(); + axis = joints[ jointHandle ].ToMat3(); + } + + return true; +} + +/* +===================== +idAnimator::GetJointHandle +===================== +*/ +jointHandle_t idAnimator::GetJointHandle( const char *name ) const { + if ( !modelDef || !modelDef->ModelHandle() ) { + return INVALID_JOINT; + } + + return modelDef->ModelHandle()->GetJointHandle( name ); +} + +/* +===================== +idAnimator::GetJointName +===================== +*/ +const char *idAnimator::GetJointName( jointHandle_t handle ) const { + if ( !modelDef || !modelDef->ModelHandle() ) { + return ""; + } + + return modelDef->ModelHandle()->GetJointName( handle ); +} + +/* +===================== +idAnimator::GetChannelForJoint +===================== +*/ +int idAnimator::GetChannelForJoint( jointHandle_t joint ) const { + if ( !modelDef ) { + gameLocal.Error( "idAnimator::GetChannelForJoint: NULL model" ); + } + + if ( ( joint < 0 ) || ( joint >= numJoints ) ) { + gameLocal.Error( "idAnimator::GetChannelForJoint: invalid joint num (%d)", joint ); + } + + return modelDef->GetJoint( joint )->channel; +} + +/* +===================== +idAnimator::GetFirstChild +===================== +*/ +jointHandle_t idAnimator::GetFirstChild( const char *name ) const { + return GetFirstChild( GetJointHandle( name ) ); +} + +/* +===================== +idAnimator::GetFirstChild +===================== +*/ +jointHandle_t idAnimator::GetFirstChild( jointHandle_t jointnum ) const { + int i; + int num; + const jointInfo_t *joint; + + if ( !modelDef ) { + return INVALID_JOINT; + } + + num = modelDef->NumJoints(); + if ( !num ) { + return jointnum; + } + joint = modelDef->GetJoint( 0 ); + for( i = 0; i < num; i++, joint++ ) { + if ( joint->parentNum == jointnum ) { + return ( jointHandle_t )joint->num; + } + } + return jointnum; +} + +/* +===================== +idAnimator::GetJoints +===================== +*/ +void idAnimator::GetJoints( int *numJoints, idJointMat **jointsPtr ) { + *numJoints = this->numJoints; + *jointsPtr = this->joints; +} + +/* +===================== +idAnimator::GetAnimFlags +===================== +*/ +const animFlags_t idAnimator::GetAnimFlags( int animNum ) const { + animFlags_t result; + + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->GetAnimFlags(); + } + + memset( &result, 0, sizeof( result ) ); + return result; +} + +/* +===================== +idAnimator::NumFrames +===================== +*/ +int idAnimator::NumFrames( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->NumFrames(); + } else { + return 0; + } +} + +/* +===================== +idAnimator::NumSyncedAnims +===================== +*/ +int idAnimator::NumSyncedAnims( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->NumAnims(); + } else { + return 0; + } +} + +/* +===================== +idAnimator::AnimName +===================== +*/ +const char *idAnimator::AnimName( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->Name(); + } else { + return ""; + } +} + +/* +===================== +idAnimator::AnimFullName +===================== +*/ +const char *idAnimator::AnimFullName( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->FullName(); + } else { + return ""; + } +} + +/* +===================== +idAnimator::AnimLength +===================== +*/ +int idAnimator::AnimLength( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->Length(); + } else { + return 0; + } +} + +/* +===================== +idAnimator::TotalMovementDelta +===================== +*/ +const idVec3 &idAnimator::TotalMovementDelta( int animNum ) const { + const idAnim *anim = GetAnim( animNum ); + if ( anim ) { + return anim->TotalMovementDelta(); + } else { + return vec3_origin; + } +} + +/*********************************************************************** + + Util functions + +***********************************************************************/ + +/* +===================== +ANIM_GetModelDefFromEntityDef +===================== +*/ +const idDeclModelDef *ANIM_GetModelDefFromEntityDef( const idDict *args ) { + const idDeclModelDef *modelDef; + + idStr name = args->GetString( "model" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); + if ( modelDef && modelDef->ModelHandle() ) { + return modelDef; + } + + return NULL; +} + +/* +===================== +idGameEdit::ANIM_GetModelFromEntityDef +===================== +*/ +idRenderModel *idGameEdit::ANIM_GetModelFromEntityDef( const idDict *args ) { + idRenderModel *model; + const idDeclModelDef *modelDef; + + model = NULL; + + idStr name = args->GetString( "model" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); + if ( modelDef ) { + model = modelDef->ModelHandle(); + } + + if ( !model ) { + model = renderModelManager->FindModel( name ); + } + + if ( model && model->IsDefaultModel() ) { + return NULL; + } + + return model; +} + +/* +===================== +idGameEdit::ANIM_GetModelFromEntityDef +===================== +*/ +idRenderModel *idGameEdit::ANIM_GetModelFromEntityDef( const char *classname ) { + const idDict *args; + + args = gameLocal.FindEntityDefDict( classname, false ); + if ( !args ) { + return NULL; + } + + return ANIM_GetModelFromEntityDef( args ); +} + +/* +===================== +idGameEdit::ANIM_GetModelOffsetFromEntityDef +===================== +*/ +const idVec3 &idGameEdit::ANIM_GetModelOffsetFromEntityDef( const char *classname ) { + const idDict *args; + const idDeclModelDef *modelDef; + + args = gameLocal.FindEntityDefDict( classname, false ); + if ( !args ) { + return vec3_origin; + } + + modelDef = ANIM_GetModelDefFromEntityDef( args ); + if ( !modelDef ) { + return vec3_origin; + } + + return modelDef->GetVisualOffset(); +} + +/* +===================== +idGameEdit::ANIM_GetModelFromName +===================== +*/ +idRenderModel *idGameEdit::ANIM_GetModelFromName( const char *modelName ) { + const idDeclModelDef *modelDef; + idRenderModel *model; + + model = NULL; + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelName, false ) ); + if ( modelDef ) { + model = modelDef->ModelHandle(); + } + if ( !model ) { + model = renderModelManager->FindModel( modelName ); + } + return model; +} + +/* +===================== +idGameEdit::ANIM_GetAnimFromEntityDef +===================== +*/ +const idMD5Anim *idGameEdit::ANIM_GetAnimFromEntityDef( const char *classname, const char *animname ) { + const idDict *args; + const idMD5Anim *md5anim; + const idAnim *anim; + int animNum; + const char *modelname; + const idDeclModelDef *modelDef; + + args = gameLocal.FindEntityDefDict( classname, false ); + if ( !args ) { + return NULL; + } + + md5anim = NULL; + modelname = args->GetString( "model" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); + if ( modelDef ) { + animNum = modelDef->GetAnim( animname ); + if ( animNum ) { + anim = modelDef->GetAnim( animNum ); + if ( anim ) { + md5anim = anim->MD5Anim( 0 ); + } + } + } + return md5anim; +} + +/* +===================== +idGameEdit::ANIM_GetNumAnimsFromEntityDef +===================== +*/ +int idGameEdit::ANIM_GetNumAnimsFromEntityDef( const idDict *args ) { + const char *modelname; + const idDeclModelDef *modelDef; + + modelname = args->GetString( "model" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); + if ( modelDef ) { + return modelDef->NumAnims(); + } + return 0; +} + +/* +===================== +idGameEdit::ANIM_GetAnimNameFromEntityDef +===================== +*/ +const char *idGameEdit::ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum ) { + const char *modelname; + const idDeclModelDef *modelDef; + + modelname = args->GetString( "model" ); + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); + if ( modelDef ) { + const idAnim* anim = modelDef->GetAnim( animNum ); + if ( anim ) { + return anim->FullName(); + } + } + return ""; +} + +/* +===================== +idGameEdit::ANIM_GetAnim +===================== +*/ +const idMD5Anim *idGameEdit::ANIM_GetAnim( const char *fileName ) { + return animationLib.GetAnim( fileName ); +} + +/* +===================== +idGameEdit::ANIM_GetLength +===================== +*/ +int idGameEdit::ANIM_GetLength( const idMD5Anim *anim ) { + if ( !anim ) { + return 0; + } + return anim->Length(); +} + +/* +===================== +idGameEdit::ANIM_GetNumFrames +===================== +*/ +int idGameEdit::ANIM_GetNumFrames( const idMD5Anim *anim ) { + if ( !anim ) { + return 0; + } + return anim->NumFrames(); +} + +/* +===================== +idGameEdit::ANIM_CreateAnimFrame +===================== +*/ +void idGameEdit::ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *joints, int time, const idVec3 &offset, bool remove_origin_offset ) { + int i; + frameBlend_t frame; + const idMD5Joint *md5joints; + int *index; + + if ( !model || model->IsDefaultModel() || !anim ) { + return; + } + + if ( numJoints != model->NumJoints() ) { + gameLocal.Error( "ANIM_CreateAnimFrame: different # of joints in renderEntity_t than in model (%s)", model->Name() ); + } + + if ( !model->NumJoints() ) { + // FIXME: Print out a warning? + return; + } + + if ( !joints ) { + gameLocal.Error( "ANIM_CreateAnimFrame: NULL joint frame pointer on model (%s)", model->Name() ); + } + + if ( numJoints != anim->NumJoints() ) { + gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", model->Name(), anim->Name() ); + for( i = 0; i < numJoints; i++ ) { + joints[i].SetRotation( mat3_identity ); + joints[i].SetTranslation( offset ); + } + return; + } + + // create index for all joints + index = ( int * )_alloca16( numJoints * sizeof( int ) ); + for ( i = 0; i < numJoints; i++ ) { + index[i] = i; + } + + // create the frame + anim->ConvertTimeToFrame( time, 1, frame ); + idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); + anim->GetInterpolatedFrame( frame, jointFrame, index, numJoints ); + + // convert joint quaternions to joint matrices + SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); + + // first joint is always root of entire hierarchy + if ( remove_origin_offset ) { + joints[0].SetTranslation( offset ); + } else { + joints[0].SetTranslation( joints[0].ToVec3() + offset ); + } + + // transform the children + md5joints = model->GetJoints(); + for( i = 1; i < numJoints; i++ ) { + joints[i] *= joints[ md5joints[i].parent - md5joints ]; + } +} + +/* +===================== +idGameEdit::ANIM_CreateMeshForAnim +===================== +*/ +idRenderModel *idGameEdit::ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset ) { + renderEntity_t ent; + const idDict *args; + const char *temp; + idRenderModel *newmodel; + const idMD5Anim *md5anim; + idStr filename; + idStr extension; + const idAnim *anim; + int animNum; + idVec3 offset; + const idDeclModelDef *modelDef; + + if ( !model || model->IsDefaultModel() ) { + return NULL; + } + + args = gameLocal.FindEntityDefDict( classname, false ); + if ( !args ) { + return NULL; + } + + memset( &ent, 0, sizeof( ent ) ); + + ent.bounds.Clear(); + ent.suppressSurfaceInViewID = 0; + + modelDef = ANIM_GetModelDefFromEntityDef( args ); + if ( modelDef ) { + animNum = modelDef->GetAnim( animname ); + if ( !animNum ) { + return NULL; + } + anim = modelDef->GetAnim( animNum ); + if ( !anim ) { + return NULL; + } + md5anim = anim->MD5Anim( 0 ); + ent.customSkin = modelDef->GetDefaultSkin(); + offset = modelDef->GetVisualOffset(); + } else { + filename = animname; + filename.ExtractFileExtension( extension ); + if ( !extension.Length() ) { + animname = args->GetString( va( "anim %s", animname ) ); + } + + md5anim = animationLib.GetAnim( animname ); + offset.Zero(); + } + + if ( !md5anim ) { + return NULL; + } + + temp = args->GetString( "skin", "" ); + if ( temp[ 0 ] ) { + ent.customSkin = declManager->FindSkin( temp ); + } + + ent.numJoints = model->NumJoints(); + ent.joints = ( idJointMat * )Mem_Alloc16( ent.numJoints * sizeof( *ent.joints ) ); + + ANIM_CreateAnimFrame( model, md5anim, ent.numJoints, ent.joints, FRAME2MS( frame ), offset, remove_origin_offset ); + + newmodel = model->InstantiateDynamicModel( &ent, NULL, NULL ); + + Mem_Free16( ent.joints ); + ent.joints = NULL; + + return newmodel; +} diff --git a/game/anim/Anim_Import.cpp b/game/anim/Anim_Import.cpp new file mode 100644 index 000000000..e1eea2f9f --- /dev/null +++ b/game/anim/Anim_Import.cpp @@ -0,0 +1,597 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../../MayaImport/maya_main.h" + +/*********************************************************************** + + Maya conversion functions + +***********************************************************************/ + +static idStr Maya_Error; + +static exporterInterface_t Maya_ConvertModel = NULL; +static exporterShutdown_t Maya_Shutdown = NULL; +static int importDLL = 0; + +bool idModelExport::initialized = false; + +/* +==================== +idModelExport::idModelExport +==================== +*/ +idModelExport::idModelExport() { + Reset(); +} + +/* +==================== +idModelExport::Shutdown +==================== +*/ +void idModelExport::Shutdown( void ) { + if ( Maya_Shutdown ) { + Maya_Shutdown(); + } + + if ( importDLL ) { + sys->DLL_Unload( importDLL ); + } + + importDLL = 0; + Maya_Shutdown = NULL; + Maya_ConvertModel = NULL; + Maya_Error.Clear(); + initialized = false; +} + +/* +===================== +idModelExport::CheckMayaInstall + +Determines if Maya is installed on the user's machine +===================== +*/ +bool idModelExport::CheckMayaInstall( void ) { +#ifndef _WIN32 + return false; +#elif 0 + HKEY hKey; + long lres, lType; + + lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya\\4.5\\Setup\\InstallPath", &hKey ); + + if ( lres != ERROR_SUCCESS ) { + return false; + } + + lres = RegQueryValueEx( hKey, "MAYA_INSTALL_LOCATION", NULL, (unsigned long*)&lType, (unsigned char*)NULL, (unsigned long*)NULL ); + + RegCloseKey( hKey ); + + if ( lres != ERROR_SUCCESS ) { + return false; + } + return true; +#else + HKEY hKey; + long lres; + + // only check the non-version specific key so that we only have to update the maya dll when new versions are released + lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya", &hKey ); + RegCloseKey( hKey ); + + if ( lres == ERROR_SUCCESS ) { + return true; + } + + // greebo: Could not find "Alias|WaveFront" Maya key, check for AutoDesk + lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Autodesk\\Maya", &hKey ); + RegCloseKey( hKey ); + + if ( lres == ERROR_SUCCESS ) { + return true; + } + + gameLocal.Warning("Maya key not found in registry, continuing...\n"); + + return true; // greebo: both keys failed, let the game continue anyways +#endif +} + +#ifdef WIN32 + +#define FORMAT_BUFSIZE 2048 + +// Helper method to retrieve the error when DLL load failed. +const char* FormatGetLastError() { + static char buf[FORMAT_BUFSIZE]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + buf, + FORMAT_BUFSIZE, NULL); + return buf; +} +#endif + +/* +===================== +idModelExport::LoadMayaDll + +Checks to see if we can load the Maya export dll +===================== +*/ +void idModelExport::LoadMayaDll( void ) { + exporterDLLEntry_t dllEntry; + char dllPath[ MAX_OSPATH ]; + + fileSystem->FindDLL( "MayaImport", dllPath, false ); + if ( !dllPath[ 0 ] ) { + return; + } + importDLL = sys->DLL_Load( dllPath ); + + if ( !importDLL ) { +#ifdef WIN32 + // greebo: Do another attempt in Win32 to get a better error message + idStr win32DllPath(dllPath); + win32DllPath.Replace("/", "\\"); + + HMODULE dll = LoadLibrary(win32DllPath); + + if (dll == 0) { + gameLocal.Warning("Could not load MayaImport DLL: %s ", FormatGetLastError()); + } +#endif + return; + } + + // look up the dll interface functions + dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" ); + Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" ); + Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" ); + if ( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) { + Maya_ConvertModel = NULL; + Maya_Shutdown = NULL; + sys->DLL_Unload( importDLL ); + importDLL = 0; + gameLocal.Error( "Invalid interface on export DLL." ); + return; + } + + // initialize the DLL + if ( !dllEntry( MD5_VERSION, common, sys ) ) { + // init failed + Maya_ConvertModel = NULL; + Maya_Shutdown = NULL; + sys->DLL_Unload( importDLL ); + importDLL = 0; + gameLocal.Error( "Export DLL init failed." ); + return; + } +} + +/* +===================== +idModelExport::ConvertMayaToMD5 + +Checks if a Maya model should be converted to an MD5, and converts if if the time/date or +version number has changed. +===================== +*/ +bool idModelExport::ConvertMayaToMD5( void ) { + ID_TIME_T sourceTime; + ID_TIME_T destTime; + int version; + idToken cmdLine; + idStr path; + + // check if our DLL got loaded + if ( initialized && !Maya_ConvertModel ) { + Maya_Error = "MayaImport dll not loaded."; + return false; + } + + // if idAnimManager::forceExport is set then we always reexport Maya models + if ( idAnimManager::forceExport ) { + force = true; + } + + // get the source file's time + if ( fileSystem->ReadFile( src, NULL, &sourceTime ) < 0 ) { + // source file doesn't exist + gameLocal.Warning("Source file doesn't exist: %s", src.c_str()); + return true; + } + + // get the destination file's time + if ( !force && ( fileSystem->ReadFile( dest, NULL, &destTime ) >= 0 ) ) { + idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); + + parser.LoadFile( dest ); + + // read the file version + if ( parser.CheckTokenString( MD5_VERSION_STRING ) ) { + version = parser.ParseInt(); + + // check the command line + if ( parser.CheckTokenString( "commandline" ) ) { + parser.ReadToken( &cmdLine ); + + // check the file time, scale, and version + if ( ( destTime >= sourceTime ) && ( version == MD5_VERSION ) && ( cmdLine == commandLine ) ) { + // don't convert it + return true; + } + } + } + } + + // if this is the first time we've been run, check if Maya is installed and load our DLL + if ( !initialized ) { + initialized = true; + + if ( !CheckMayaInstall() ) { + Maya_Error = "Maya not installed in registry."; + return false; + } + + LoadMayaDll(); + + // check if our DLL got loaded + if ( !Maya_ConvertModel ) { + Maya_Error = "Could not load MayaImport dll."; + return false; + } + } + + // we need to make sure we have a full path, so convert the filename to an OS path + src = fileSystem->RelativePathToOSPath( src ); + dest = fileSystem->RelativePathToOSPath( dest ); + + dest.ExtractFilePath( path ); + if ( path.Length() ) { + fileSystem->CreateOSPath( path ); + } + + // get the os path in case it needs to create one + path = fileSystem->RelativePathToOSPath( "" ); + + common->SetRefreshOnPrint( true ); + Maya_Error = Maya_ConvertModel( path, commandLine ); + common->SetRefreshOnPrint( false ); + if ( Maya_Error != "Ok" ) { + return false; + } + + // conversion succeded + return true; +} + +/* +==================== +idModelExport::Reset +==================== +*/ +void idModelExport::Reset( void ) { + force = false; + commandLine = ""; + src = ""; + dest = ""; +} + +/* +==================== +idModelExport::ExportModel +==================== +*/ +bool idModelExport::ExportModel( const char *model ) { + const char *game = cvarSystem->GetCVarString( "fs_game" ); + if ( strlen(game) == 0 ) { + game = BASE_GAMEDIR; + } + + Reset(); + src = model; + dest = model; + dest.SetFileExtension( MD5_MESH_EXT ); + + sprintf( commandLine, "mesh %s -dest %s -game %s", src.c_str(), dest.c_str(), game ); + if ( !ConvertMayaToMD5() ) { + gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); + return false; + } + + return true; +} + +/* +==================== +idModelExport::ExportAnim +==================== +*/ +bool idModelExport::ExportAnim( const char *anim ) { + const char *game = cvarSystem->GetCVarString( "fs_game" ); + if ( strlen(game) == 0 ) { + game = BASE_GAMEDIR; + } + + Reset(); + src = anim; + dest = anim; + dest.SetFileExtension( MD5_ANIM_EXT ); + + sprintf( commandLine, "anim %s -dest %s -game %s", src.c_str(), dest.c_str(), game ); + if ( !ConvertMayaToMD5() ) { + gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); + return false; + } + + return true; +} + +/* +==================== +idModelExport::ParseOptions +==================== +*/ +bool idModelExport::ParseOptions( idLexer &lex ) { + idToken token; + idStr destdir; + idStr sourcedir; + + if ( !lex.ReadToken( &token ) ) { + lex.Error( "Expected filename" ); + return false; + } + + src = token; + dest = token; + + while( lex.ReadToken( &token ) ) { + if ( token == "-" ) { + if ( !lex.ReadToken( &token ) ) { + lex.Error( "Expecting option" ); + return false; + } + if ( token == "sourcedir" ) { + if ( !lex.ReadToken( &token ) ) { + lex.Error( "Missing pathname after -sourcedir" ); + return false; + } + sourcedir = token; + } else if ( token == "destdir" ) { + if ( !lex.ReadToken( &token ) ) { + lex.Error( "Missing pathname after -destdir" ); + return false; + } + destdir = token; + } else if ( token == "dest" ) { + if ( !lex.ReadToken( &token ) ) { + lex.Error( "Missing filename after -dest" ); + return false; + } + dest = token; + } else { + commandLine += va( " -%s", token.c_str() ); + } + } else { + commandLine += va( " %s", token.c_str() ); + } + } + + if ( sourcedir.Length() ) { + src.StripPath(); + sourcedir.BackSlashesToSlashes(); + sprintf( src, "%s/%s", sourcedir.c_str(), src.c_str() ); + } + + if ( destdir.Length() ) { + dest.StripPath(); + destdir.BackSlashesToSlashes(); + sprintf( dest, "%s/%s", destdir.c_str(), dest.c_str() ); + } + + return true; +} + +/* +==================== +idModelExport::ParseExportSection +==================== +*/ +int idModelExport::ParseExportSection( idParser &parser ) { + idToken command; + idToken token; + idStr defaultCommands; + idLexer lex; + idStr temp; + idStr parms; + int count; + + // only export sections that match our export mask + if ( g_exportMask.GetString()[ 0 ] ) { + if ( parser.CheckTokenString( "{" ) ) { + parser.SkipBracedSection( false ); + return 0; + } + + parser.ReadToken( &token ); + if ( token.Icmp( g_exportMask.GetString() ) ) { + parser.SkipBracedSection(); + return 0; + } + parser.ExpectTokenString( "{" ); + } else if ( !parser.CheckTokenString( "{" ) ) { + // skip the export mask + parser.ReadToken( &token ); + parser.ExpectTokenString( "{" ); + } + + count = 0; + + lex.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + // Save the command's filename + const char* currentFileName = parser.GetFileName(); + + while( 1 ) { + + if ( !parser.ReadToken( &command ) ) { + parser.Error( "Unexpected end-of-file" ); + break; + } + + if ( command == "}" ) { + break; + } + + if ( command == "options" ) { + parser.ParseRestOfLine( defaultCommands ); + } else if ( command == "addoptions" ) { + parser.ParseRestOfLine( temp ); + defaultCommands += " "; + defaultCommands += temp; + } else if ( ( command == "mesh" ) || ( command == "anim" ) || ( command == "camera" ) ) { + if ( !parser.ReadToken( &token ) ) { + parser.Error( "Expected filename" ); + } + + temp = token; + parser.ParseRestOfLine( parms ); + + if ( defaultCommands.Length() ) { + sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() ); + } + + if ( parms.Length() ) { + sprintf( temp, "%s %s", temp.c_str(), parms.c_str() ); + } + + lex.LoadMemory( temp, temp.Length(), parser.GetFileName() ); + + Reset(); + if ( ParseOptions( lex ) ) { + const char *game = cvarSystem->GetCVarString( "fs_game" ); + if ( strlen(game) == 0 ) { + game = BASE_GAMEDIR; + } + + if ( command == "mesh" ) { + dest.SetFileExtension( MD5_MESH_EXT ); + } else if ( command == "anim" ) { + dest.SetFileExtension( MD5_ANIM_EXT ); + } else if ( command == "camera" ) { + dest.SetFileExtension( MD5_CAMERA_EXT ); + } else { + dest.SetFileExtension( command ); + } + idStr back = commandLine; + sprintf( commandLine, "%s %s -dest %s -game %s%s", command.c_str(), src.c_str(), dest.c_str(), game, commandLine.c_str() ); + if ( ConvertMayaToMD5() ) { + count++; + } else { + parser.Warning( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); + } + } + lex.FreeSource(); + } else { + parser.Error( "Unknown token: '%s' on line %i, file '%s'", command.c_str(), command.line, currentFileName ); + parser.SkipBracedSection( false ); + break; + } + } + + return count; +} + +/* +================ +idModelExport::ExportDefFile +================ +*/ +int idModelExport::ExportDefFile( const char *filename ) { + idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + idToken token; + int count; + + count = 0; + + if ( !parser.LoadFile( filename ) ) { + gameLocal.Printf( "Could not load '%s'\n", filename ); + return 0; + } + + while( parser.ReadToken( &token ) ) { + if ( token == "export" ) { + count += ParseExportSection( parser ); + } else { + parser.ReadToken( &token ); + parser.SkipBracedSection(); + } + } + + return count; +} + +/* +================ +idModelExport::ExportModels +================ +*/ +int idModelExport::ExportModels( const char *pathname, const char *extension ) { + int count; + + count = 0; + + idFileList *files; + int i; + + if ( !CheckMayaInstall() ) { + // if Maya isn't installed, don't bother checking if we have anims to export + return 0; + } + + gameLocal.Printf( "--------- Exporting models --------\n" ); + if ( !g_exportMask.GetString()[ 0 ] ) { + gameLocal.Printf( " Export mask: '%s'\n", g_exportMask.GetString() ); + } + + count = 0; + + files = fileSystem->ListFiles( pathname, extension ); + for( i = 0; i < files->GetNumFiles(); i++ ) { + count += ExportDefFile( va( "%s/%s", pathname, files->GetFile( i ) ) ); + } + fileSystem->FreeFileList( files ); + + gameLocal.Printf( "...%d models exported.\n", count ); + gameLocal.Printf( "-----------------------------------\n" ); + + return count; +} diff --git a/game/anim/Anim_Testmodel.cpp b/game/anim/Anim_Testmodel.cpp new file mode 100644 index 000000000..78685a339 --- /dev/null +++ b/game/anim/Anim_Testmodel.cpp @@ -0,0 +1,965 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* +============================================================================= + + MODEL TESTING + +Model viewing can begin with either "testmodel " + +The names must be the full pathname after the basedir, like +"models/weapons/v_launch/tris.md3" or "players/male/tris.md3" + +Extension will default to ".ase" if not specified. + +Testmodel will create a fake entity 100 units in front of the current view +position, directly facing the viewer. It will remain immobile, so you can +move around it to view it from different angles. + + g_testModelRotate + g_testModelAnimate + g_testModelBlend + +============================================================================= +*/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idAnimatedEntity, idTestModel ) + EVENT( EV_FootstepLeft, idTestModel::Event_Footstep ) + EVENT( EV_FootstepRight, idTestModel::Event_Footstep ) +END_CLASS + +/* +================ +idTestModel::idTestModel +================ +*/ +idTestModel::idTestModel() { + head = NULL; + headAnimator = NULL; + anim = 0; + headAnim = 0; + starttime = 0; + animtime = 0; + mode = 0; + frame = 0; +} + +/* +================ +idTestModel::Save +================ +*/ +void idTestModel::Save( idSaveGame *savefile ) { +} + +/* +================ +idTestModel::Restore +================ +*/ +void idTestModel::Restore( idRestoreGame *savefile ) { + // FIXME: one day we may actually want to save/restore test models, but for now we'll just delete them + delete this; +} + +/* +================ +idTestModel::Spawn +================ +*/ +void idTestModel::Spawn( void ) { + idVec3 size; + idBounds bounds; + jointHandle_t joint; + idStr jointName; + idVec3 origin, modelOffset; + idMat3 axis; + copyJoints_t copyJoint; + + if ( renderEntity.hModel && renderEntity.hModel->IsDefaultModel() && !animator.ModelDef() ) { + gameLocal.Warning( "Unable to create testmodel for '%s' : model defaulted", spawnArgs.GetString( "model" ) ); + PostEventMS( &EV_Remove, 0 ); + return; + } + + mode = g_testModelAnimate.GetInteger(); + animator.RemoveOriginOffset( g_testModelAnimate.GetInteger() == 1 ); + + physicsObj.SetSelf( this ); + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); + physicsObj.SetAxis( GetPhysics()->GetAxis() ); + + if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) ) { + spawnArgs.GetVector( "maxs", NULL, bounds[1] ); + physicsObj.SetClipBox( bounds, 1.0f ); + physicsObj.SetContents( 0 ); + } else if ( spawnArgs.GetVector( "size", NULL, size ) ) { + bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f ); + bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z ); + physicsObj.SetClipBox( bounds, 1.0f ); + physicsObj.SetContents( 0 ); + } + + spawnArgs.GetVector( "offsetModel", "0 0 0", modelOffset ); + + // add the head model if it has one + idStr headModelDefName = spawnArgs.GetString( "def_head" ); + + if ( !headModelDefName.IsEmpty() ) + { + jointName = spawnArgs.GetString( "head_joint" ); + + if (jointName.IsEmpty()) + { + // greebo: Second chance, use the CVAR, if no head_joint defined + g_testModelHeadJoint.GetString(); + } + + if (jointName.IsEmpty()) + { + jointName = "Spine2"; // fall back to hardcoded + } + + joint = animator.GetJointHandle( jointName ); + if ( joint == INVALID_JOINT ) + { + gameLocal.Warning( "Joint '%s' not found for 'head_joint'", jointName.c_str() ); + } + else + { + idDict args; + + const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); + + if (def == NULL) + { + gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); + + // Try to fallback on the default head entityDef + def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); + } + + if (def != NULL) + { + // Make a copy of the default spawnargs + args = def->dict; + } + else + { + gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); + } + + // Copy any sounds in case we have frame commands on the head + for (const idKeyValue* kv = spawnArgs.MatchPrefix("snd_", NULL); kv != NULL; kv = spawnArgs.MatchPrefix("snd_", kv)) + { + args.Set(kv->GetKey(), kv->GetValue()); + } + + head = gameLocal.SpawnEntityType( idAnimatedEntity::Type, &args ); + animator.GetJointTransform( joint, gameLocal.time, origin, axis ); + origin = GetPhysics()->GetOrigin() + ( origin + modelOffset ) * GetPhysics()->GetAxis(); + + // Retrieve the actual model from the head entityDef + idStr headModel = args.GetString("model"); + if (headModel.IsEmpty()) + { + gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); + } + + head.GetEntity()->SetModel( headModel ); + head.GetEntity()->SetOrigin( origin ); + head.GetEntity()->SetAxis( GetPhysics()->GetAxis() ); + head.GetEntity()->BindToJoint( this, animator.GetJointName( joint ), true ); + + headAnimator = head.GetEntity()->GetAnimator(); + + // set up the list of joints to copy to the head + for(const idKeyValue* kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) + { + jointName = kv->GetKey(); + + if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) { + copyJoint.mod = JOINTMOD_WORLD_OVERRIDE; + } else { + jointName.StripLeadingOnce( "copy_joint " ); + copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE; + } + + copyJoint.from = animator.GetJointHandle( jointName ); + if ( copyJoint.from == INVALID_JOINT ) { + gameLocal.Warning( "Unknown copy_joint '%s'", jointName.c_str() ); + continue; + } + + copyJoint.to = headAnimator->GetJointHandle( jointName ); + if ( copyJoint.to == INVALID_JOINT ) { + gameLocal.Warning( "Unknown copy_joint '%s' on head", jointName.c_str() ); + continue; + } + + copyJoints.Append( copyJoint ); + } + } + } + + // start any shader effects based off of the spawn time + renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); + + SetPhysics( &physicsObj ); + + gameLocal.Printf( "Added testmodel at origin = '%s', angles = '%s'\n", GetPhysics()->GetOrigin().ToString(), GetPhysics()->GetAxis().ToAngles().ToString() ); + BecomeActive( TH_THINK ); +} + +/* +================ +idTestModel::~idTestModel +================ +*/ +idTestModel::~idTestModel() { + StopSound( SND_CHANNEL_ANY, false ); + if ( renderEntity.hModel ) { + gameLocal.Printf( "Removing testmodel %s\n", renderEntity.hModel->Name() ); + } else { + gameLocal.Printf( "Removing testmodel\n" ); + } + if ( gameLocal.testmodel == this ) { + gameLocal.testmodel = NULL; + } + if ( head.GetEntity() ) { + head.GetEntity()->StopSound( SND_CHANNEL_ANY, false ); + head.GetEntity()->PostEventMS( &EV_Remove, 0 ); + } +} + +/* +=============== +idTestModel::Event_Footstep +=============== +*/ +void idTestModel::Event_Footstep( void ) { + StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL ); +} + +/* +================ +idTestModel::ShouldConstructScriptObjectAtSpawn + +Called during idEntity::Spawn to see if it should construct the script object or not. +Overridden by subclasses that need to spawn the script object themselves. +================ +*/ +bool idTestModel::ShouldConstructScriptObjectAtSpawn( void ) const { + return false; +} + +/* +================ +idTestModel::Think +================ +*/ +void idTestModel::Think( void ) { + idVec3 pos; + idMat3 axis; + idAngles ang; + int i; + + if ( thinkFlags & TH_THINK ) { + if ( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) ) { + StopSound( SND_CHANNEL_ANY, false ); + if ( head.GetEntity() ) { + head.GetEntity()->StopSound( SND_CHANNEL_ANY, false ); + } + switch( g_testModelAnimate.GetInteger() ) { + default: + case 0: + // cycle anim with origin reset + if ( animator.NumFrames( anim ) <= 1 ) { + // single frame animations end immediately, so just cycle it since it's the same result + animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + if ( headAnim ) { + headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + } else { + animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + if ( headAnim ) { + headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { + // loop the body anim when the head anim is longer + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); + } + } + } + animator.RemoveOriginOffset( false ); + break; + + case 1: + // cycle anim with fixed origin + animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + animator.RemoveOriginOffset( true ); + if ( headAnim ) { + headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + break; + + case 2: + // cycle anim with continuous origin + animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + animator.RemoveOriginOffset( false ); + if ( headAnim ) { + headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + break; + + case 3: + // frame by frame with continuous origin + animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + animator.RemoveOriginOffset( false ); + if ( headAnim ) { + headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + break; + + case 4: + // play anim once + animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + animator.RemoveOriginOffset( false ); + if ( headAnim ) { + headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + break; + + case 5: + // frame by frame with fixed origin + animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + animator.RemoveOriginOffset( true ); + if ( headAnim ) { + headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + } + break; + } + + mode = g_testModelAnimate.GetInteger(); + } + + if ( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) ) { + starttime = gameLocal.time; + StopSound( SND_CHANNEL_ANY, false ); + animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + if ( headAnim ) { + headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); + if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { + // loop the body anim when the head anim is longer + animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); + } + } + } + + if ( headAnimator ) { + // copy the animation from the body to the head + for( i = 0; i < copyJoints.Num(); i++ ) { + if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) { + idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose(); + GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); + pos -= head.GetEntity()->GetPhysics()->GetOrigin(); + headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat ); + headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat ); + } else { + animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); + headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos ); + headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis ); + } + } + } + + // update rotation + RunPhysics(); + + physicsObj.GetAngles( ang ); + physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero ); + + idClipModel *clip = physicsObj.GetClipModel(); + if ( clip && animator.ModelDef() ) { + idVec3 neworigin; + idMat3 axis; + jointHandle_t joint; + + joint = animator.GetJointHandle( "origin" ); + animator.GetJointTransform( joint, gameLocal.time, neworigin, axis ); + neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin(); + clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() ); + } + } + + UpdateAnimation(); + Present(); + + if ( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim ) { + gameLocal.Printf( "^5 Anim: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), + animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); + if ( headAnim ) { + gameLocal.Printf( "^5 Head: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), + headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); + } else { + gameLocal.Printf( "\n\n" ); + } + } +} + +/* +================ +idTestModel::NextAnim +================ +*/ +void idTestModel::NextAnim( const idCmdArgs &args ) { + if ( !animator.NumAnims() ) { + return; + } + + anim++; + if ( anim >= animator.NumAnims() ) { + // anim 0 is no anim + anim = 1; + } + + starttime = gameLocal.time; + animtime = animator.AnimLength( anim ); + animname = animator.AnimFullName( anim ); + headAnim = 0; + if ( headAnimator ) { + headAnimator->ClearAllAnims( gameLocal.time, 0 ); + headAnim = headAnimator->GetAnim( animname ); + if ( !headAnim ) { + headAnim = headAnimator->GetAnim( "idle" ); + } + + if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { + animtime = headAnimator->AnimLength( headAnim ); + } + } + + gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); + if ( headAnim ) { + gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) ); + } + + // reset the anim + mode = -1; + frame = 1; +} + +/* +================ +idTestModel::PrevAnim +================ +*/ +void idTestModel::PrevAnim( const idCmdArgs &args ) { + if ( !animator.NumAnims() ) { + return; + } + + headAnim = 0; + anim--; + if ( anim < 0 ) { + anim = animator.NumAnims() - 1; + } + + starttime = gameLocal.time; + animtime = animator.AnimLength( anim ); + animname = animator.AnimFullName( anim ); + headAnim = 0; + if ( headAnimator ) { + headAnimator->ClearAllAnims( gameLocal.time, 0 ); + headAnim = headAnimator->GetAnim( animname ); + if ( !headAnim ) { + headAnim = headAnimator->GetAnim( "idle" ); + } + + if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { + animtime = headAnimator->AnimLength( headAnim ); + } + } + + gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); + if ( headAnim ) { + gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) ); + } + + // reset the anim + mode = -1; + frame = 1; +} + +/* +================ +idTestModel::NextFrame +================ +*/ +void idTestModel::NextFrame( const idCmdArgs &args ) { + if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) { + return; + } + + frame++; + if ( frame > animator.NumFrames( anim ) ) { + frame = 1; + } + + gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) ); + + // reset the anim + mode = -1; +} + +/* +================ +idTestModel::PrevFrame +================ +*/ +void idTestModel::PrevFrame( const idCmdArgs &args ) { + if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) { + return; + } + + frame--; + if ( frame < 1 ) { + frame = animator.NumFrames( anim ); + } + + gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) ); + + // reset the anim + mode = -1; +} + +/* +================ +idTestModel::TestAnim +================ +*/ +void idTestModel::TestAnim( const idCmdArgs &args ) { + idStr name; + int animNum; + const idAnim *newanim; + + if ( args.Argc() < 2 ) { + gameLocal.Printf( "usage: testanim \n" ); + return; + } + + newanim = NULL; + + name = args.Argv( 1 ); +#if 0 + if ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) { + const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ]; + idModelExport exporter; + exporter.ExportAnim( name ); + name.SetFileExtension( MD5_ANIM_EXT ); + md5anims[ 0 ] = animationLib.GetAnim( name ); + if ( md5anims[ 0 ] ) { + customAnim.SetAnim( animator.ModelDef(), name, name, 1, md5anims ); + newanim = &customAnim; + } + } else { + animNum = animator.GetAnim( name ); + } +#else + animNum = animator.GetAnim( name ); +#endif + + if ( !animNum ) { + gameLocal.Printf( "Animation '%s' not found.\n", name.c_str() ); + return; + } + + anim = animNum; + starttime = gameLocal.time; + animtime = animator.AnimLength( anim ); + headAnim = 0; + if ( headAnimator ) { + headAnimator->ClearAllAnims( gameLocal.time, 0 ); + headAnim = headAnimator->GetAnim( animname ); + if ( !headAnim ) { + headAnim = headAnimator->GetAnim( "idle" ); + if ( !headAnim ) { + gameLocal.Printf( "Missing 'idle' anim for head.\n" ); + } + } + + if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { + animtime = headAnimator->AnimLength( headAnim ); + } + } + + animname = name; + gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); + + // reset the anim + mode = -1; +} + +/* +===================== +idTestModel::BlendAnim +===================== +*/ +void idTestModel::BlendAnim( const idCmdArgs &args ) { + int anim1; + int anim2; + + if ( args.Argc() < 4 ) { + gameLocal.Printf( "usage: testblend \n" ); + return; + } + + anim1 = gameLocal.testmodel->animator.GetAnim( args.Argv( 1 ) ); + if ( !anim1 ) { + gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 1 ) ); + return; + } + + anim2 = gameLocal.testmodel->animator.GetAnim( args.Argv( 2 ) ); + if ( !anim2 ) { + gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 2 ) ); + return; + } + + animname = args.Argv( 2 ); + animator.CycleAnim( ANIMCHANNEL_ALL, anim1, gameLocal.time, 0 ); + animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, FRAME2MS( atoi( args.Argv( 3 ) ) ) ); + + anim = anim2; + headAnim = 0; +} + +/*********************************************************************** + + Testmodel console commands + +***********************************************************************/ + +/* +================= +idTestModel::KeepTestModel_f + +Makes the current test model permanent, allowing you to place +multiple test models +================= +*/ +void idTestModel::KeepTestModel_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No active testModel.\n" ); + return; + } + + gameLocal.Printf( "modelDef %p kept\n", gameLocal.testmodel->renderEntity.hModel ); + + gameLocal.testmodel = NULL; +} + +/* +================= +idTestModel::TestSkin_f + +Sets a skin on an existing testModel +================= +*/ +void idTestModel::TestSkin_f( const idCmdArgs &args ) { + idVec3 offset; + idStr name; + idPlayer * player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + // delete the testModel if active + if ( !gameLocal.testmodel ) { + common->Printf( "No active testModel\n" ); + return; + } + + if ( args.Argc() < 2 ) { + common->Printf( "removing testSkin.\n" ); + gameLocal.testmodel->SetSkin( NULL ); + return; + } + + name = args.Argv( 1 ); + gameLocal.testmodel->SetSkin( declManager->FindSkin( name ) ); +} + +/* +================= +idTestModel::TestShaderParm_f + +Sets a shaderParm on an existing testModel +================= +*/ +void idTestModel::TestShaderParm_f( const idCmdArgs &args ) { + idVec3 offset; + idStr name; + idPlayer * player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + // delete the testModel if active + if ( !gameLocal.testmodel ) { + common->Printf( "No active testModel\n" ); + return; + } + + if ( args.Argc() != 3 ) { + common->Printf( "USAGE: testShaderParm \n" ); + return; + } + + int parm = atoi( args.Argv( 1 ) ); + if ( parm < 0 || parm >= MAX_ENTITY_SHADER_PARMS ) { + common->Printf( "parmNum %i out of range\n", parm ); + return; + } + + float value; + if ( !idStr::Icmp( args.Argv( 2 ), "time" ) ) { + value = gameLocal.time * -0.001; + } else { + value = atof( args.Argv( 2 ) ); + } + + gameLocal.testmodel->SetShaderParm( parm, value ); +} + +/* +================= +idTestModel::TestModel_f + +Creates a static modelDef in front of the current position, which +can then be moved around +================= +*/ +void idTestModel::TestModel_f( const idCmdArgs &args ) { + idVec3 offset; + idStr name; + idPlayer * player; + const idDict * entityDef; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + // delete the testModel if active + if ( gameLocal.testmodel ) { + delete gameLocal.testmodel; + gameLocal.testmodel = NULL; + } + + if ( args.Argc() < 2 ) { + return; + } + + name = args.Argv( 1 ); + + entityDef = gameLocal.FindEntityDefDict( name, false ); + if ( entityDef ) { + dict = *entityDef; + } else { + if ( declManager->FindType( DECL_MODELDEF, name, false ) ) { + dict.Set( "model", name ); + } else { + // allow map models with underscore prefixes to be tested during development + // without appending an ase + if ( name[ 0 ] != '_' ) { + name.DefaultFileExtension( ".ase" ); + } + + if ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) { + idModelExport exporter; + exporter.ExportModel( name ); + name.SetFileExtension( MD5_MESH_EXT ); + } + + if ( !renderModelManager->CheckModel( name ) ) { + gameLocal.Printf( "Can't register model\n" ); + return; + } + dict.Set( "model", name ); + } + } + + offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f; + + dict.Set( "origin", offset.ToString() ); + dict.Set( "angle", va( "%f", player->viewAngles.yaw + 180.0f ) ); + dict.Set( "def_head", g_testModelHead.GetString()); + gameLocal.testmodel = ( idTestModel * )gameLocal.SpawnEntityType( idTestModel::Type, &dict ); + gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); +} + +/* +===================== +idTestModel::ArgCompletion_TestModel +===================== +*/ +void idTestModel::ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ) { + int i, num; + + num = declManager->GetNumDecls( DECL_ENTITYDEF ); + for ( i = 0; i < num; i++ ) { + callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_ENTITYDEF, i , false )->GetName() ); + } + num = declManager->GetNumDecls( DECL_MODELDEF ); + for ( i = 0; i < num; i++ ) { + callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_MODELDEF, i , false )->GetName() ); + } + cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", ".mb", NULL ); +} + +/* +===================== +idTestModel::TestParticleStopTime_f +===================== +*/ +void idTestModel::TestParticleStopTime_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time ); + gameLocal.testmodel->UpdateVisuals(); +} + +/* +===================== +idTestModel::TestAnim_f +===================== +*/ +void idTestModel::TestAnim_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->TestAnim( args ); +} + + +/* +===================== +idTestModel::ArgCompletion_TestAnim +===================== +*/ +void idTestModel::ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ) { + if ( gameLocal.testmodel ) { + idAnimator *animator = gameLocal.testmodel->GetAnimator(); + for( int i = 0; i < animator->NumAnims(); i++ ) { + callback( va( "%s %s", args.Argv( 0 ), animator->AnimFullName( i ) ) ); + } + } +} + +/* +===================== +idTestModel::TestBlend_f +===================== +*/ +void idTestModel::TestBlend_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->BlendAnim( args ); +} + +/* +===================== +idTestModel::TestModelNextAnim_f +===================== +*/ +void idTestModel::TestModelNextAnim_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->NextAnim( args ); +} + +/* +===================== +idTestModel::TestModelPrevAnim_f +===================== +*/ +void idTestModel::TestModelPrevAnim_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->PrevAnim( args ); +} + +/* +===================== +idTestModel::TestModelNextFrame_f +===================== +*/ +void idTestModel::TestModelNextFrame_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->NextFrame( args ); +} + +/* +===================== +idTestModel::TestModelPrevFrame_f +===================== +*/ +void idTestModel::TestModelPrevFrame_f( const idCmdArgs &args ) { + if ( !gameLocal.testmodel ) { + gameLocal.Printf( "No testModel active.\n" ); + return; + } + + gameLocal.testmodel->PrevFrame( args ); +} diff --git a/game/anim/Anim_Testmodel.h b/game/anim/Anim_Testmodel.h new file mode 100644 index 000000000..239e071eb --- /dev/null +++ b/game/anim/Anim_Testmodel.h @@ -0,0 +1,86 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __ANIM_TESTMODEL_H__ +#define __ANIM_TESTMODEL_H__ + +/* +============================================================================================== + + idTestModel + +============================================================================================== +*/ + +class idTestModel : public idAnimatedEntity { +public: + CLASS_PROTOTYPE( idTestModel ); + + idTestModel(); + ~idTestModel(); + + void Save( idSaveGame *savefile ); + void Restore( idRestoreGame *savefile ); + + void Spawn( void ); + + virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; + + void NextAnim( const idCmdArgs &args ); + void PrevAnim( const idCmdArgs &args ); + void NextFrame( const idCmdArgs &args ); + void PrevFrame( const idCmdArgs &args ); + void TestAnim( const idCmdArgs &args ); + void BlendAnim( const idCmdArgs &args ); + + static void KeepTestModel_f( const idCmdArgs &args ); + static void TestModel_f( const idCmdArgs &args ); + static void ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void TestSkin_f( const idCmdArgs &args ); + static void TestShaderParm_f( const idCmdArgs &args ); + static void TestParticleStopTime_f( const idCmdArgs &args ); + static void TestAnim_f( const idCmdArgs &args ); + static void ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void TestBlend_f( const idCmdArgs &args ); + static void TestModelNextAnim_f( const idCmdArgs &args ); + static void TestModelPrevAnim_f( const idCmdArgs &args ); + static void TestModelNextFrame_f( const idCmdArgs &args ); + static void TestModelPrevFrame_f( const idCmdArgs &args ); + +private: + idEntityPtr head; + idAnimator *headAnimator; + idAnim customAnim; + idPhysics_Parametric physicsObj; + idStr animname; + int anim; + int headAnim; + int mode; + int frame; + int starttime; + int animtime; + + idList copyJoints; + + virtual void Think( void ); + + void Event_Footstep( void ); +}; + +#endif /* !__ANIM_TESTMODEL_H__*/ diff --git a/game/anim/anim.cpp b/game/anim/anim.cpp deleted file mode 100644 index fe70f574e..000000000 --- a/game/anim/anim.cpp +++ /dev/null @@ -1,1090 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/DarkModGlobals.h" - -bool idAnimManager::forceExport = false; - -/*********************************************************************** - - idMD5Anim - -***********************************************************************/ - -/* -==================== -idMD5Anim::idMD5Anim -==================== -*/ -idMD5Anim::idMD5Anim() { - ref_count = 0; - numFrames = 0; - numJoints = 0; - frameRate = 24; - animLength = 0; - totaldelta.Zero(); -} - -/* -==================== -idMD5Anim::idMD5Anim -==================== -*/ -idMD5Anim::~idMD5Anim() { - Free(); -} - -/* -==================== -idMD5Anim::Free -==================== -*/ -void idMD5Anim::Free( void ) { - numFrames = 0; - numJoints = 0; - frameRate = 24; - animLength = 0; - name = ""; - - totaldelta.Zero(); - - jointInfo.Clear(); - bounds.Clear(); - componentFrames.Clear(); -} - -/* -==================== -idMD5Anim::NumFrames -==================== -*/ -int idMD5Anim::NumFrames( void ) const { - return numFrames; -} - -/* -==================== -idMD5Anim::NumJoints -==================== -*/ -int idMD5Anim::NumJoints( void ) const { - return numJoints; -} - -/* -==================== -idMD5Anim::Length -==================== -*/ -int idMD5Anim::Length( void ) const { - return animLength; -} - -/* -===================== -idMD5Anim::TotalMovementDelta -===================== -*/ -const idVec3 &idMD5Anim::TotalMovementDelta( void ) const { - return totaldelta; -} - -/* -===================== -idMD5Anim::TotalMovementDelta -===================== -*/ -const char *idMD5Anim::Name( void ) const { - return name; -} - -/* -==================== -idMD5Anim::Reload -==================== -*/ -bool idMD5Anim::Reload( void ) { - idStr filename; - - filename = name; - Free(); - - return LoadAnim( filename ); -} - -/* -==================== -idMD5Anim::Allocated -==================== -*/ -size_t idMD5Anim::Allocated( void ) const { - size_t size = bounds.Allocated() + jointInfo.Allocated() + componentFrames.Allocated() + name.Allocated(); - return size; -} - -/* -==================== -idMD5Anim::LoadAnim -==================== -*/ -bool idMD5Anim::LoadAnim( const char *filename ) { - int version; - idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT ); - idToken token; - int i, j; - int num; - - if ( !parser.LoadFile( filename ) ) { - return false; - } - - Free(); - - name = filename; - - parser.ExpectTokenString( MD5_VERSION_STRING ); - version = parser.ParseInt(); - if ( version != MD5_VERSION ) { - parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); - } - - // skip the commandline - parser.ExpectTokenString( "commandline" ); - parser.ReadToken( &token ); - - // parse num frames - parser.ExpectTokenString( "numFrames" ); - numFrames = parser.ParseInt(); - if ( numFrames <= 0 ) { - parser.Error( "Invalid number of frames: %d", numFrames ); - } - - // parse num joints - parser.ExpectTokenString( "numJoints" ); - numJoints = parser.ParseInt(); - if ( numJoints <= 0 ) { - parser.Error( "Invalid number of joints: %d", numJoints ); - } - - // parse frame rate - parser.ExpectTokenString( "frameRate" ); - frameRate = parser.ParseInt(); - if ( frameRate < 0 ) { - parser.Error( "Invalid frame rate: %d", frameRate ); - } - - // parse number of animated components - parser.ExpectTokenString( "numAnimatedComponents" ); - numAnimatedComponents = parser.ParseInt(); - if ( ( numAnimatedComponents < 0 ) || ( numAnimatedComponents > numJoints * 6 ) ) { - parser.Error( "Invalid number of animated components: %d", numAnimatedComponents ); - } - - // parse the hierarchy - jointInfo.SetGranularity( 1 ); - jointInfo.SetNum( numJoints ); - parser.ExpectTokenString( "hierarchy" ); - parser.ExpectTokenString( "{" ); - for( i = 0; i < numJoints; i++ ) { - parser.ReadToken( &token ); - jointInfo[ i ].nameIndex = animationLib.JointIndex( token ); - - // parse parent num - jointInfo[ i ].parentNum = parser.ParseInt(); - if ( jointInfo[ i ].parentNum >= i ) { - parser.Error( "Invalid parent num: %d", jointInfo[ i ].parentNum ); - } - - if ( ( i != 0 ) && ( jointInfo[ i ].parentNum < 0 ) ) { - parser.Error( "Animations may have only one root joint" ); - } - - // parse anim bits - jointInfo[ i ].animBits = parser.ParseInt(); - if ( jointInfo[ i ].animBits & ~63 ) { - parser.Error( "Invalid anim bits: %d", jointInfo[ i ].animBits ); - } - - // parse first component - jointInfo[ i ].firstComponent = parser.ParseInt(); - if ( ( numAnimatedComponents > 0 ) && ( ( jointInfo[ i ].firstComponent < 0 ) || ( jointInfo[ i ].firstComponent >= numAnimatedComponents ) ) ) { - parser.Error( "Invalid first component: %d", jointInfo[ i ].firstComponent ); - } - } - - parser.ExpectTokenString( "}" ); - - // parse bounds - parser.ExpectTokenString( "bounds" ); - parser.ExpectTokenString( "{" ); - bounds.SetGranularity( 1 ); - bounds.SetNum( numFrames ); - for( i = 0; i < numFrames; i++ ) { - parser.Parse1DMatrix( 3, bounds[ i ][ 0 ].ToFloatPtr() ); - parser.Parse1DMatrix( 3, bounds[ i ][ 1 ].ToFloatPtr() ); - } - parser.ExpectTokenString( "}" ); - - // parse base frame - baseFrame.SetGranularity( 1 ); - baseFrame.SetNum( numJoints ); - parser.ExpectTokenString( "baseframe" ); - parser.ExpectTokenString( "{" ); - for( i = 0; i < numJoints; i++ ) { - idCQuat q; - parser.Parse1DMatrix( 3, baseFrame[ i ].t.ToFloatPtr() ); - parser.Parse1DMatrix( 3, q.ToFloatPtr() );//baseFrame[ i ].q.ToFloatPtr() ); - baseFrame[ i ].q = q.ToQuat();//.w = baseFrame[ i ].q.CalcW(); - } - parser.ExpectTokenString( "}" ); - - // parse frames - componentFrames.SetGranularity( 1 ); - componentFrames.SetNum( numAnimatedComponents * numFrames ); - - float *componentPtr = componentFrames.Ptr(); - for( i = 0; i < numFrames; i++ ) { - parser.ExpectTokenString( "frame" ); - num = parser.ParseInt(); - if ( num != i ) { - parser.Error( "Expected frame number %d", i ); - } - parser.ExpectTokenString( "{" ); - - for( j = 0; j < numAnimatedComponents; j++, componentPtr++ ) { - *componentPtr = parser.ParseFloat(); - } - - parser.ExpectTokenString( "}" ); - } - - // get total move delta - if ( !numAnimatedComponents ) { - totaldelta.Zero(); - } else { - componentPtr = &componentFrames[ jointInfo[ 0 ].firstComponent ]; - if ( jointInfo[ 0 ].animBits & ANIM_TX ) { - for( i = 0; i < numFrames; i++ ) { - componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.x; - } - totaldelta.x = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; - componentPtr++; - } else { - totaldelta.x = 0.0f; - } - if ( jointInfo[ 0 ].animBits & ANIM_TY ) { - for( i = 0; i < numFrames; i++ ) { - componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.y; - } - totaldelta.y = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; - componentPtr++; - } else { - totaldelta.y = 0.0f; - } - if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { - for( i = 0; i < numFrames; i++ ) { - componentPtr[ numAnimatedComponents * i ] -= baseFrame[ 0 ].t.z; - } - totaldelta.z = componentPtr[ numAnimatedComponents * ( numFrames - 1 ) ]; - } else { - totaldelta.z = 0.0f; - } - } - baseFrame[ 0 ].t.Zero(); - - // we don't count last frame because it would cause a 1 frame pause at the end - animLength = ( ( numFrames - 1 ) * 1000 + frameRate - 1 ) / frameRate; - - // done - return true; -} - -/* -==================== -idMD5Anim::IncreaseRefs -==================== -*/ -void idMD5Anim::IncreaseRefs( void ) const { - ref_count++; -} - -/* -==================== -idMD5Anim::DecreaseRefs -==================== -*/ -void idMD5Anim::DecreaseRefs( void ) const { - ref_count--; -} - -/* -==================== -idMD5Anim::NumRefs -==================== -*/ -int idMD5Anim::NumRefs( void ) const { - return ref_count; -} - -/* -==================== -idMD5Anim::GetFrameBlend -==================== -*/ -void idMD5Anim::GetFrameBlend( int framenum, frameBlend_t &frame ) const { - frame.cycleCount = 0; - frame.backlerp = 0.0f; - frame.frontlerp = 1.0f; - - // frame 1 is first frame - framenum--; - if ( framenum < 0 ) { - framenum = 0; - } else if ( framenum >= numFrames ) { - framenum = numFrames - 1; - } - - frame.frame1 = framenum; - frame.frame2 = framenum; -} - -/* -==================== -idMD5Anim::ConvertTimeToFrame -==================== -*/ -void idMD5Anim::ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const { - int frameTime; - int frameNum; - - if ( numFrames <= 1 ) { - frame.frame1 = 0; - frame.frame2 = 0; - frame.backlerp = 0.0f; - frame.frontlerp = 1.0f; - frame.cycleCount = 0; - return; - } - - if ( time <= 0 ) { - frame.frame1 = 0; - frame.frame2 = 1; - frame.backlerp = 0.0f; - frame.frontlerp = 1.0f; - frame.cycleCount = 0; - return; - } - - frameTime = time * frameRate; - frameNum = frameTime / 1000; - frame.cycleCount = frameNum / ( numFrames - 1 ); - - if ( ( cyclecount > 0 ) && ( frame.cycleCount >= cyclecount ) ) { - frame.cycleCount = cyclecount - 1; - frame.frame1 = numFrames - 1; - frame.frame2 = frame.frame1; - frame.backlerp = 0.0f; - frame.frontlerp = 1.0f; - return; - } - - frame.frame1 = frameNum % ( numFrames - 1 ); - frame.frame2 = frame.frame1 + 1; - if ( frame.frame2 >= numFrames ) { - frame.frame2 = 0; - } - - frame.backlerp = ( frameTime % 1000 ) * 0.001f; - frame.frontlerp = 1.0f - frame.backlerp; -} - -/* -==================== -idMD5Anim::GetOrigin -==================== -*/ -void idMD5Anim::GetOrigin( idVec3 &offset, int time, int cyclecount ) const { - frameBlend_t frame; - - offset = baseFrame[ 0 ].t; - if ( !( jointInfo[ 0 ].animBits & ( ANIM_TX | ANIM_TY | ANIM_TZ ) ) ) { - // just use the baseframe - return; - } - - ConvertTimeToFrame( time, cyclecount, frame ); - - const float *componentPtr1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; - const float *componentPtr2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; - - if ( jointInfo[ 0 ].animBits & ANIM_TX ) { - offset.x = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - componentPtr1++; - componentPtr2++; - } - - if ( jointInfo[ 0 ].animBits & ANIM_TY ) { - offset.y = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - componentPtr1++; - componentPtr2++; - } - - if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { - offset.z = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - } - - if ( frame.cycleCount ) { - offset += totaldelta * ( float )frame.cycleCount; - } -} - -/* -==================== -idMD5Anim::GetOriginRotation -==================== -*/ -void idMD5Anim::GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const { - frameBlend_t frame; - int animBits; - - animBits = jointInfo[ 0 ].animBits; - if ( !( animBits & ( ANIM_QX | ANIM_QY | ANIM_QZ ) ) ) { - // just use the baseframe - rotation = baseFrame[ 0 ].q; - return; - } - - ConvertTimeToFrame( time, cyclecount, frame ); - - const float *jointframe1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; - const float *jointframe2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; - - if ( animBits & ANIM_TX ) { - jointframe1++; - jointframe2++; - } - - if ( animBits & ANIM_TY ) { - jointframe1++; - jointframe2++; - } - - if ( animBits & ANIM_TZ ) { - jointframe1++; - jointframe2++; - } - - idQuat q1; - idQuat q2; - - switch( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { - case ANIM_QX: - q1.x = jointframe1[0]; - q2.x = jointframe2[0]; - q1.y = baseFrame[ 0 ].q.y; - q2.y = q1.y; - q1.z = baseFrame[ 0 ].q.z; - q2.z = q1.z; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QY: - q1.y = jointframe1[0]; - q2.y = jointframe2[0]; - q1.x = baseFrame[ 0 ].q.x; - q2.x = q1.x; - q1.z = baseFrame[ 0 ].q.z; - q2.z = q1.z; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QZ: - q1.z = jointframe1[0]; - q2.z = jointframe2[0]; - q1.x = baseFrame[ 0 ].q.x; - q2.x = q1.x; - q1.y = baseFrame[ 0 ].q.y; - q2.y = q1.y; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QX|ANIM_QY: - q1.x = jointframe1[0]; - q1.y = jointframe1[1]; - q2.x = jointframe2[0]; - q2.y = jointframe2[1]; - q1.z = baseFrame[ 0 ].q.z; - q2.z = q1.z; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QX|ANIM_QZ: - q1.x = jointframe1[0]; - q1.z = jointframe1[1]; - q2.x = jointframe2[0]; - q2.z = jointframe2[1]; - q1.y = baseFrame[ 0 ].q.y; - q2.y = q1.y; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QY|ANIM_QZ: - q1.y = jointframe1[0]; - q1.z = jointframe1[1]; - q2.y = jointframe2[0]; - q2.z = jointframe2[1]; - q1.x = baseFrame[ 0 ].q.x; - q2.x = q1.x; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - case ANIM_QX|ANIM_QY|ANIM_QZ: - q1.x = jointframe1[0]; - q1.y = jointframe1[1]; - q1.z = jointframe1[2]; - q2.x = jointframe2[0]; - q2.y = jointframe2[1]; - q2.z = jointframe2[2]; - q1.w = q1.CalcW(); - q2.w = q2.CalcW(); - break; - } - - rotation.Slerp( q1, q2, frame.backlerp ); -} - -/* -==================== -idMD5Anim::GetBounds -==================== -*/ -void idMD5Anim::GetBounds( idBounds &bnds, int time, int cyclecount ) const { - frameBlend_t frame; - idVec3 offset; - - ConvertTimeToFrame( time, cyclecount, frame ); - - bnds = bounds[ frame.frame1 ]; - bnds.AddBounds( bounds[ frame.frame2 ] ); - - // origin position - offset = baseFrame[ 0 ].t; - if ( jointInfo[ 0 ].animBits & ( ANIM_TX | ANIM_TY | ANIM_TZ ) ) { - const float *componentPtr1 = &componentFrames[ numAnimatedComponents * frame.frame1 + jointInfo[ 0 ].firstComponent ]; - const float *componentPtr2 = &componentFrames[ numAnimatedComponents * frame.frame2 + jointInfo[ 0 ].firstComponent ]; - - if ( jointInfo[ 0 ].animBits & ANIM_TX ) { - offset.x = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - componentPtr1++; - componentPtr2++; - } - - if ( jointInfo[ 0 ].animBits & ANIM_TY ) { - offset.y = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - componentPtr1++; - componentPtr2++; - } - - if ( jointInfo[ 0 ].animBits & ANIM_TZ ) { - offset.z = *componentPtr1 * frame.frontlerp + *componentPtr2 * frame.backlerp; - } - } - - bnds[ 0 ] -= offset; - bnds[ 1 ] -= offset; -} - -/* -==================== -idMD5Anim::GetInterpolatedFrame -==================== -*/ -void idMD5Anim::GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const { - int i, numLerpJoints; - const float *frame1; - const float *frame2; - const float *jointframe1; - const float *jointframe2; - const jointAnimInfo_t *infoPtr; - int animBits; - idJointQuat *blendJoints; - idJointQuat *jointPtr; - idJointQuat *blendPtr; - int *lerpIndex; - - // copy the baseframe - SIMDProcessor->Memcpy( joints, baseFrame.Ptr(), baseFrame.Num() * sizeof( baseFrame[ 0 ] ) ); - - if ( !numAnimatedComponents ) { - // just use the base frame - return; - } - - blendJoints = (idJointQuat *)_alloca16( baseFrame.Num() * sizeof( blendPtr[ 0 ] ) ); - lerpIndex = (int *)_alloca16( baseFrame.Num() * sizeof( lerpIndex[ 0 ] ) ); - numLerpJoints = 0; - - frame1 = &componentFrames[ frame.frame1 * numAnimatedComponents ]; - frame2 = &componentFrames[ frame.frame2 * numAnimatedComponents ]; - - for ( i = 0; i < numIndexes; i++ ) { - int j = index[i]; - jointPtr = &joints[j]; - blendPtr = &blendJoints[j]; - infoPtr = &jointInfo[j]; - - animBits = infoPtr->animBits; - if ( animBits ) { - - lerpIndex[numLerpJoints++] = j; - - jointframe1 = frame1 + infoPtr->firstComponent; - jointframe2 = frame2 + infoPtr->firstComponent; - - switch( animBits & (ANIM_TX|ANIM_TY|ANIM_TZ) ) { - case 0: - blendPtr->t = jointPtr->t; - break; - case ANIM_TX: - jointPtr->t.x = jointframe1[0]; - blendPtr->t.x = jointframe2[0]; - blendPtr->t.y = jointPtr->t.y; - blendPtr->t.z = jointPtr->t.z; - jointframe1++; - jointframe2++; - break; - case ANIM_TY: - jointPtr->t.y = jointframe1[0]; - blendPtr->t.y = jointframe2[0]; - blendPtr->t.x = jointPtr->t.x; - blendPtr->t.z = jointPtr->t.z; - jointframe1++; - jointframe2++; - break; - case ANIM_TZ: - jointPtr->t.z = jointframe1[0]; - blendPtr->t.z = jointframe2[0]; - blendPtr->t.x = jointPtr->t.x; - blendPtr->t.y = jointPtr->t.y; - jointframe1++; - jointframe2++; - break; - case ANIM_TX|ANIM_TY: - jointPtr->t.x = jointframe1[0]; - jointPtr->t.y = jointframe1[1]; - blendPtr->t.x = jointframe2[0]; - blendPtr->t.y = jointframe2[1]; - blendPtr->t.z = jointPtr->t.z; - jointframe1 += 2; - jointframe2 += 2; - break; - case ANIM_TX|ANIM_TZ: - jointPtr->t.x = jointframe1[0]; - jointPtr->t.z = jointframe1[1]; - blendPtr->t.x = jointframe2[0]; - blendPtr->t.z = jointframe2[1]; - blendPtr->t.y = jointPtr->t.y; - jointframe1 += 2; - jointframe2 += 2; - break; - case ANIM_TY|ANIM_TZ: - jointPtr->t.y = jointframe1[0]; - jointPtr->t.z = jointframe1[1]; - blendPtr->t.y = jointframe2[0]; - blendPtr->t.z = jointframe2[1]; - blendPtr->t.x = jointPtr->t.x; - jointframe1 += 2; - jointframe2 += 2; - break; - case ANIM_TX|ANIM_TY|ANIM_TZ: - jointPtr->t.x = jointframe1[0]; - jointPtr->t.y = jointframe1[1]; - jointPtr->t.z = jointframe1[2]; - blendPtr->t.x = jointframe2[0]; - blendPtr->t.y = jointframe2[1]; - blendPtr->t.z = jointframe2[2]; - jointframe1 += 3; - jointframe2 += 3; - break; - } - - switch( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { - case 0: - blendPtr->q = jointPtr->q; - break; - case ANIM_QX: - jointPtr->q.x = jointframe1[0]; - blendPtr->q.x = jointframe2[0]; - blendPtr->q.y = jointPtr->q.y; - blendPtr->q.z = jointPtr->q.z; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QY: - jointPtr->q.y = jointframe1[0]; - blendPtr->q.y = jointframe2[0]; - blendPtr->q.x = jointPtr->q.x; - blendPtr->q.z = jointPtr->q.z; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QZ: - jointPtr->q.z = jointframe1[0]; - blendPtr->q.z = jointframe2[0]; - blendPtr->q.x = jointPtr->q.x; - blendPtr->q.y = jointPtr->q.y; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QX|ANIM_QY: - jointPtr->q.x = jointframe1[0]; - jointPtr->q.y = jointframe1[1]; - blendPtr->q.x = jointframe2[0]; - blendPtr->q.y = jointframe2[1]; - blendPtr->q.z = jointPtr->q.z; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QX|ANIM_QZ: - jointPtr->q.x = jointframe1[0]; - jointPtr->q.z = jointframe1[1]; - blendPtr->q.x = jointframe2[0]; - blendPtr->q.z = jointframe2[1]; - blendPtr->q.y = jointPtr->q.y; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QY|ANIM_QZ: - jointPtr->q.y = jointframe1[0]; - jointPtr->q.z = jointframe1[1]; - blendPtr->q.y = jointframe2[0]; - blendPtr->q.z = jointframe2[1]; - blendPtr->q.x = jointPtr->q.x; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - case ANIM_QX|ANIM_QY|ANIM_QZ: - jointPtr->q.x = jointframe1[0]; - jointPtr->q.y = jointframe1[1]; - jointPtr->q.z = jointframe1[2]; - blendPtr->q.x = jointframe2[0]; - blendPtr->q.y = jointframe2[1]; - blendPtr->q.z = jointframe2[2]; - jointPtr->q.w = jointPtr->q.CalcW(); - blendPtr->q.w = blendPtr->q.CalcW(); - break; - } - } - } - - SIMDProcessor->BlendJoints( joints, blendJoints, frame.backlerp, lerpIndex, numLerpJoints ); - - if ( frame.cycleCount ) { - joints[ 0 ].t += totaldelta * ( float )frame.cycleCount; - } -} - -/* -==================== -idMD5Anim::GetSingleFrame -==================== -*/ -void idMD5Anim::GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const { - int i; - const float *frame; - const float *jointframe; - int animBits; - idJointQuat *jointPtr; - const jointAnimInfo_t *infoPtr; - - // copy the baseframe - SIMDProcessor->Memcpy( joints, baseFrame.Ptr(), baseFrame.Num() * sizeof( baseFrame[ 0 ] ) ); - - if ( ( framenum == 0 ) || !numAnimatedComponents ) { - // just use the base frame - return; - } - - frame = &componentFrames[ framenum * numAnimatedComponents ]; - - for ( i = 0; i < numIndexes; i++ ) { - int j = index[i]; - jointPtr = &joints[j]; - infoPtr = &jointInfo[j]; - - animBits = infoPtr->animBits; - if ( animBits ) { - - jointframe = frame + infoPtr->firstComponent; - - if ( animBits & (ANIM_TX|ANIM_TY|ANIM_TZ) ) { - - if ( animBits & ANIM_TX ) { - jointPtr->t.x = *jointframe++; - } - - if ( animBits & ANIM_TY ) { - jointPtr->t.y = *jointframe++; - } - - if ( animBits & ANIM_TZ ) { - jointPtr->t.z = *jointframe++; - } - } - - if ( animBits & (ANIM_QX|ANIM_QY|ANIM_QZ) ) { - - if ( animBits & ANIM_QX ) { - jointPtr->q.x = *jointframe++; - } - - if ( animBits & ANIM_QY ) { - jointPtr->q.y = *jointframe++; - } - - if ( animBits & ANIM_QZ ) { - jointPtr->q.z = *jointframe; - } - - jointPtr->q.w = jointPtr->q.CalcW(); - } - } - } -} - -/* -==================== -idMD5Anim::CheckModelHierarchy -==================== -*/ -void idMD5Anim::CheckModelHierarchy( const idRenderModel *model ) const { - int i; - int jointNum; - int parent; - - if ( jointInfo.Num() != model->NumJoints() ) { - gameLocal.Error( "Model '%s' has different # of joints than anim '%s'", model->Name(), name.c_str() ); - } - - const idMD5Joint *modelJoints = model->GetJoints(); - for( i = 0; i < jointInfo.Num(); i++ ) { - jointNum = jointInfo[ i ].nameIndex; - if ( modelJoints[ i ].name != animationLib.JointName( jointNum ) ) { - gameLocal.Error( "Model '%s''s joint names don't match anim '%s''s", model->Name(), name.c_str() ); - } - if ( modelJoints[ i ].parent ) { - parent = modelJoints[ i ].parent - modelJoints; - } else { - parent = -1; - } - if ( parent != jointInfo[ i ].parentNum ) { - gameLocal.Error( "Model '%s' has different joint hierarchy than anim '%s'", model->Name(), name.c_str() ); - } - } -} - -/* -==================== -idMD5Anim::SetFrameRate - -(DarkMod Addition) -==================== -*/ - -void idMD5Anim::SetFrameRate( int frRate ) -{ - frameRate = frRate; - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("ChangeFrameRate: Set rate to %d\r", frameRate); - - return; -} - -/*********************************************************************** - - idAnimManager - -***********************************************************************/ - -/* -==================== -idAnimManager::idAnimManager -==================== -*/ -idAnimManager::idAnimManager() { -} - -/* -==================== -idAnimManager::~idAnimManager -==================== -*/ -idAnimManager::~idAnimManager() { - Shutdown(); -} - -/* -==================== -idAnimManager::Shutdown -==================== -*/ -void idAnimManager::Shutdown( void ) { - animations.DeleteContents(); - jointnames.Clear(); - jointnamesHash.Free(); -} - -/* -==================== -idAnimManager::GetAnim -==================== -*/ -idMD5Anim *idAnimManager::GetAnim( const char *name ) { - idMD5Anim **animptrptr; - idMD5Anim *anim; - - // see if it has been asked for before - animptrptr = NULL; - if ( animations.Get( name, &animptrptr ) ) { - anim = *animptrptr; - } else { - idStr extension; - idStr filename = name; - - filename.ExtractFileExtension( extension ); - if ( extension != MD5_ANIM_EXT ) { - return NULL; - } - - anim = new idMD5Anim(); - if ( !anim->LoadAnim( filename ) ) { - gameLocal.Warning( "Couldn't load anim: '%s'", filename.c_str() ); - delete anim; - anim = NULL; - } - animations.Set( filename, anim ); - } - - return anim; -} - -/* -================ -idAnimManager::ReloadAnims -================ -*/ -void idAnimManager::ReloadAnims( void ) { - int i; - idMD5Anim **animptr; - - for( i = 0; i < animations.Num(); i++ ) { - animptr = animations.GetIndex( i ); - if ( animptr && *animptr ) { - ( *animptr )->Reload(); - } - } -} - -/* -================ -idAnimManager::JointIndex -================ -*/ -int idAnimManager::JointIndex( const char *name ) { - int i, hash; - - hash = jointnamesHash.GenerateKey( name ); - for ( i = jointnamesHash.First( hash ); i != -1; i = jointnamesHash.Next( i ) ) { - if ( jointnames[i].Cmp( name ) == 0 ) { - return i; - } - } - - i = jointnames.Append( name ); - jointnamesHash.Add( hash, i ); - return i; -} - -/* -================ -idAnimManager::JointName -================ -*/ -const char *idAnimManager::JointName( int index ) const { - return jointnames[ index ]; -} - -/* -================ -idAnimManager::ListAnims -================ -*/ -void idAnimManager::ListAnims( void ) const { - int i; - idMD5Anim **animptr; - idMD5Anim *anim; - size_t size; - size_t s; - size_t namesize; - int num; - - num = 0; - size = 0; - for( i = 0; i < animations.Num(); i++ ) { - animptr = animations.GetIndex( i ); - if ( animptr && *animptr ) { - anim = *animptr; - s = anim->Size(); - gameLocal.Printf( "%8d bytes : %2d refs : %s\n", s, anim->NumRefs(), anim->Name() ); - size += s; - num++; - } - } - - namesize = jointnames.Size() + jointnamesHash.Size(); - for( i = 0; i < jointnames.Num(); i++ ) { - namesize += jointnames[ i ].Size(); - } - - gameLocal.Printf( "\n%d memory used in %d anims\n", size, num ); - gameLocal.Printf( "%d memory used in %d joint names\n", namesize, jointnames.Num() ); -} - -/* -================ -idAnimManager::FlushUnusedAnims -================ -*/ -void idAnimManager::FlushUnusedAnims( void ) { - int i; - idMD5Anim **animptr; - idList removeAnims; - - for( i = 0; i < animations.Num(); i++ ) { - animptr = animations.GetIndex( i ); - if ( animptr && *animptr ) { - if ( ( *animptr )->NumRefs() <= 0 ) { - removeAnims.Append( *animptr ); - } - } - } - - for( i = 0; i < removeAnims.Num(); i++ ) { - animations.Remove( removeAnims[ i ]->Name() ); - delete removeAnims[ i ]; - } -} diff --git a/game/anim/anim.h b/game/anim/anim.h deleted file mode 100644 index 73bc9625f..000000000 --- a/game/anim/anim.h +++ /dev/null @@ -1,695 +0,0 @@ -/*************************************************************************** - * - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -#ifndef __ANIM_H__ -#define __ANIM_H__ - -#ifdef __linux__ -#include "framework/declmanager.h" -#endif - -// -// animation channels -// these can be changed by modmakers and licensees to be whatever they need. -const int ANIM_NumAnimChannels = 5; -const int ANIM_MaxAnimsPerChannel = 3; -const int ANIM_MaxSyncedAnims = 3; - -// -// animation channels. make sure to change script/doom_defs.script if you add any channels, or change their order -// -const int ANIMCHANNEL_ALL = 0; -const int ANIMCHANNEL_TORSO = 1; -const int ANIMCHANNEL_LEGS = 2; -const int ANIMCHANNEL_HEAD = 3; -const int ANIMCHANNEL_EYELIDS = 4; - -// for converting from 24 frames per second to milliseconds -ID_INLINE int FRAME2MS( int framenum ) { - return ( framenum * 1000 ) / 24; -} - -class idRenderModel; -class idAnimator; -class idAnimBlend; -class function_t; -class idEntity; -class idSaveGame; -class idRestoreGame; - -typedef struct { - int cycleCount; // how many times the anim has wrapped to the begining (0 for clamped anims) - int frame1; - int frame2; - float frontlerp; - float backlerp; -} frameBlend_t; - -typedef struct { - int nameIndex; - int parentNum; - int animBits; - int firstComponent; -} jointAnimInfo_t; - -typedef struct { - jointHandle_t num; - jointHandle_t parentNum; - int channel; -} jointInfo_t; - -// -// joint modifier modes. make sure to change script/doom_defs.script if you add any, or change their order. -// -typedef enum { - JOINTMOD_NONE, // no modification - JOINTMOD_LOCAL, // modifies the joint's position or orientation in joint local space - JOINTMOD_LOCAL_OVERRIDE, // sets the joint's position or orientation in joint local space - JOINTMOD_WORLD, // modifies joint's position or orientation in model space - JOINTMOD_WORLD_OVERRIDE // sets the joint's position or orientation in model space -} jointModTransform_t; - -typedef struct { - jointHandle_t jointnum; - idMat3 mat; - idVec3 pos; - jointModTransform_t transform_pos; - jointModTransform_t transform_axis; -} jointMod_t; - -#define ANIM_TX BIT( 0 ) -#define ANIM_TY BIT( 1 ) -#define ANIM_TZ BIT( 2 ) -#define ANIM_QX BIT( 3 ) -#define ANIM_QY BIT( 4 ) -#define ANIM_QZ BIT( 5 ) - -typedef enum { - FC_SCRIPTFUNCTION, - FC_SCRIPTFUNCTIONOBJECT, - FC_EVENTFUNCTION, - FC_SOUND, - FC_SOUND_VOICE, - FC_SOUND_VOICE2, - FC_SOUND_BODY, - FC_SOUND_BODY2, - FC_SOUND_BODY3, - FC_SOUND_WEAPON, - FC_SOUND_ITEM, - FC_SOUND_GLOBAL, - FC_SOUND_CHATTER, - FC_SKIN, - FC_TRIGGER, - FC_TRIGGER_SMOKE_PARTICLE, - FC_MELEE, - FC_DIRECTDAMAGE, - FC_BEGINATTACK, - FC_ENDATTACK, - FC_MUZZLEFLASH, - FC_CREATEMISSILE, - FC_LAUNCHMISSILE, - FC_FIREMISSILEATTARGET, - FC_FOOTSTEP, - FC_LEFTFOOT, - FC_RIGHTFOOT, - FC_ENABLE_EYE_FOCUS, - FC_DISABLE_EYE_FOCUS, - FC_FX, - FC_DISABLE_GRAVITY, - FC_ENABLE_GRAVITY, - FC_JUMP, - FC_ENABLE_CLIP, - FC_DISABLE_CLIP, - FC_ENABLE_WALK_IK, - FC_DISABLE_WALK_IK, - FC_ENABLE_LEG_IK, - FC_DISABLE_LEG_IK, - FC_RECORDDEMO, - FC_AVIGAME, - -/** -* DarkMod: -* FC_SETRATE sets the anim rate, used for speeding up/slowing down walking -* and crouchwalking animations to get correct footstep sounds. -**/ - FC_SETRATE, -/** -* Move an attachment to a different position -**/ - FC_REATTACH, -/** -* Tels: Spawn an item (the item contains where to attach it) -**/ - FC_ATTACH, -/** -* Tels: Detach and destroy the named attachement -**/ - FC_DESTROY, -/** -* Tels: Detach and drop the named attachement -**/ - FC_DROP, -/** -* Tels: Detach and put down the named attachement (e.g. restore origin and angles to "before pickup") -**/ - FC_PUTDOWN, -/** -* Tels: Pickup an object (either the direct entity name, or the AIUSE class) -**/ - FC_PICKUP, -/** -* Tels: Activate the attached entity at the named joint -**/ - FC_ACTIVATE_AT_JOINT, -/** -* Tels: Activate the entity (either direct name or AIUSE class) -**/ - FC_ACTIVATE_NEAR, -/** -* Pause the animation at its current frame, wait for unpause from somewhere else -**/ - FC_PAUSE, -/** -* Holds a melee attack at a given point in the animation -* (e.g., at the back swing in attacks, at the parry position in parries) -* Similar to pause but also updates actor's melee status -**/ - FC_MELEE_HOLD, - FC_MELEE_ATTACK_START, - FC_MELEE_ATTACK_STOP, - FC_MELEE_PARRY_START, - FC_MELEE_PARRY_STOP, - FC_SET_ATTACK_FLAG, // greebo: enables a certain attack type - FC_CLEAR_ATTACK_FLAG, // greebo: disables a certain attack type - FC_CREATEMISSILE_FROM_DEF, // greebo: create a specific projectile def for ranged attack -} frameCommandType_t; - -typedef struct { - int num; - int firstCommand; -} frameLookup_t; - -typedef struct { - frameCommandType_t type; - idStr *string; - - union { - const idSoundShader *soundShader; - const function_t *function; - const idDeclSkin *skin; - int index; - }; -} frameCommand_t; - -typedef struct { - bool prevent_idle_override : 1; - bool random_cycle_start : 1; - bool ai_no_turn : 1; - bool anim_turn : 1; - bool no_random_headturning : 1; -} animFlags_t; - - -/* -============================================================================================== - - idModelExport - -============================================================================================== -*/ - -class idModelExport { -private: - void Reset( void ); - bool ParseOptions( idLexer &lex ); - int ParseExportSection( idParser &parser ); - - static bool CheckMayaInstall( void ); - static void LoadMayaDll( void ); - - bool ConvertMayaToMD5( void ); - static bool initialized; - -public: - idStr commandLine; - idStr src; - idStr dest; - bool force; - - idModelExport(); - - static void Shutdown( void ); - - int ExportDefFile( const char *filename ); - bool ExportModel( const char *model ); - bool ExportAnim( const char *anim ); - int ExportModels( const char *pathname, const char *extension ); -}; - -/* -============================================================================================== - - idMD5Anim - -============================================================================================== -*/ - -class idMD5Anim { -private: - int numFrames; - int frameRate; - int animLength; - int numJoints; - int numAnimatedComponents; - idList bounds; - idList jointInfo; - idList baseFrame; - idList componentFrames; - idStr name; - idVec3 totaldelta; - mutable int ref_count; - -public: - idMD5Anim(); - ~idMD5Anim(); - - void Free( void ); - bool Reload( void ); - size_t Allocated( void ) const; - size_t Size( void ) const { return sizeof( *this ) + Allocated(); }; - bool LoadAnim( const char *filename ); - - void IncreaseRefs( void ) const; - void DecreaseRefs( void ) const; - int NumRefs( void ) const; - - void CheckModelHierarchy( const idRenderModel *model ) const; - void GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const; - void GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const; - int Length( void ) const; - int NumFrames( void ) const; - int NumJoints( void ) const; - const idVec3 &TotalMovementDelta( void ) const; - const char *Name( void ) const; - - void GetFrameBlend( int framenum, frameBlend_t &frame ) const; // frame 1 is first frame - void ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const; - - void GetOrigin( idVec3 &offset, int currentTime, int cyclecount ) const; - void GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const; - void GetBounds( idBounds &bounds, int currentTime, int cyclecount ) const; - - /** - * DarkMod: Set the framerate to something different from what's in the file. - **/ - void SetFrameRate( int frRate ); -}; - -/* -============================================================================================== - - idAnim - -============================================================================================== -*/ - -class idAnim { -private: - const class idDeclModelDef *modelDef; - const idMD5Anim *anims[ ANIM_MaxSyncedAnims ]; - int numAnims; - idStr name; - idStr realname; - idList frameLookup; - idList frameCommands; - animFlags_t flags; - -public: - idAnim(); - idAnim( const idDeclModelDef *modelDef, const idAnim *anim ); - ~idAnim(); - - void SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] ); - const char *Name( void ) const; - const char *FullName( void ) const; - const idMD5Anim *MD5Anim( int num ) const; - const idDeclModelDef *ModelDef( void ) const; - int Length( void ) const; - int NumFrames( void ) const; - int NumAnims( void ) const; - const idVec3 &TotalMovementDelta( void ) const; - bool GetOrigin( idVec3 &offset, int animNum, int time, int cyclecount ) const; - bool GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const; - bool GetBounds( idBounds &bounds, int animNum, int time, int cyclecount ) const; - const char *AddFrameCommand( const class idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def ); - void CallFrameCommands( idEntity *ent, int from, int to, idAnimBlend *caller ); - bool HasFrameCommands( void ) const; - - // returns first frame (zero based) that command occurs. returns -1 if not found. - int FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const; - void SetAnimFlags( const animFlags_t &animflags ); - const animFlags_t &GetAnimFlags( void ) const; -}; - -/* -============================================================================================== - - idDeclModelDef - -============================================================================================== -*/ - -class idDeclModelDef : public idDecl { -public: - idDeclModelDef(); - ~idDeclModelDef(); - - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - - void Touch( void ) const; - - const idDeclSkin * GetDefaultSkin( void ) const; - const idJointQuat * GetDefaultPose( void ) const; - void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const; - idRenderModel * ModelHandle( void ) const; - void GetJointList( const char *jointnames, idList &jointList ) const; - const jointInfo_t * FindJoint( const char *name ) const; - - int NumAnims( void ) const; - const idAnim * GetAnim( int index ) const; - int GetSpecificAnim( const char *name ) const; - int GetAnim( const char *name ) const; - bool HasAnim( const char *name ) const; - const idDeclSkin * GetSkin( void ) const; - const char * GetModelName( void ) const; - const idList & Joints( void ) const; - const int * JointParents( void ) const; - int NumJoints( void ) const; - const jointInfo_t * GetJoint( int jointHandle ) const; - const char * GetJointName( int jointHandle ) const; - int NumJointsOnChannel( int channel ) const; - const int * GetChannelJoints( int channel ) const; - - const idVec3 & GetVisualOffset( void ) const; - -private: - void CopyDecl( const idDeclModelDef *decl ); - bool ParseAnim( idLexer &src, int numDefaultAnims ); - -private: - idVec3 offset; - idList joints; - idList jointParents; - idList channelJoints[ ANIM_NumAnimChannels ]; - idRenderModel * modelHandle; - idList anims; - const idDeclSkin * skin; -}; - -/* -============================================================================================== - - idAnimBlend - -============================================================================================== -*/ - -class idAnimBlend { -private: - const class idDeclModelDef *modelDef; - int starttime; - int endtime; - int timeOffset; - float rate; - - int blendStartTime; - int blendDuration; - float blendStartValue; - float blendEndValue; - - float animWeights[ ANIM_MaxSyncedAnims ]; - short cycle; - short frame; - short animNum; - bool allowMove; - bool allowFrameCommands; - /** - * TDM: This animation is paused at the current frame - **/ - bool m_bPaused; - /** - * endtime and cycle before we paused - * The following are used for proper re-entry when unpausing - **/ - int m_PausedEndtime; - short m_PausedCycle; - /** - * Time at which we paused - **/ - int m_PausedTime; - - friend class idAnimator; - - void Reset( const idDeclModelDef *_modelDef ); - void CallFrameCommands( idEntity *ent, int fromtime, int totime ) const; - void SetFrame( const idDeclModelDef *modelDef, int animnum, int frame, int currenttime, int blendtime, const idEntity *ent ); - void CycleAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime, const idEntity *ent ); - void PlayAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime, const idEntity *ent ); - bool BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOrigin, bool overrideBlend, bool printInfo ) const; - void BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const; - void BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const; - void BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const; - bool AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const; - -public: - idAnimBlend(); - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef ); - const char *AnimName( void ) const; - const char *AnimFullName( void ) const; - float GetWeight( int currenttime ) const; - float GetFinalWeight( void ) const; - void SetWeight( float newweight, int currenttime, int blendtime ); - int NumSyncedAnims( void ) const; - bool SetSyncedAnimWeight( int num, float weight ); - void Clear( int currentTime, int clearTime ); - bool IsDone( int currentTime ) const; - bool FrameHasChanged( int currentTime ) const; - int GetCycleCount( void ) const; - void SetCycleCount( int count ); - void SetPlaybackRate( int currentTime, float newRate ); - float GetPlaybackRate( void ) const; - // Ishtvan test: Making this public - /** TDM: UpdatePlaybackRate sets the playback rate to the one given by animnum in ent->m_animRates */ - void UpdatePlaybackRate(int animnum, const idEntity *ent); - void SetStartTime( int startTime ); - int GetStartTime( void ) const; - int GetEndTime( void ) const; - int GetFrameNumber( int currenttime ) const; - int AnimTime( int currenttime ) const; - int NumFrames( void ) const; - int Length( void ) const; - int PlayLength( void ) const; - void AllowMovement( bool allow ); - void AllowFrameCommands( bool allow ); - const idAnim *Anim( void ) const; - int AnimNum( void ) const; - /** - * Pause (true) or unpause (false) the animation at the current frame - **/ - void Pause( bool bPause ); - bool IsPaused( void ); -}; - -/* -============================================================================================== - - idAFPoseJointMod - -============================================================================================== -*/ - -typedef enum { - AF_JOINTMOD_AXIS, - AF_JOINTMOD_ORIGIN, - AF_JOINTMOD_BOTH, - AF_JOINTMOD_NONE // Added for TDM -} AFJointModType_t; - -class idAFPoseJointMod { -public: - idAFPoseJointMod( void ); - - AFJointModType_t mod; - idMat3 axis; - idVec3 origin; -}; - -ID_INLINE idAFPoseJointMod::idAFPoseJointMod( void ) { - mod = AF_JOINTMOD_AXIS; - axis.Identity(); - origin.Zero(); -} - -/* -============================================================================================== - - idAnimator - -============================================================================================== -*/ - -class idAnimator { -public: - idAnimator(); - ~idAnimator(); - - size_t Allocated( void ) const; - size_t Size( void ) const; - - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void SetEntity( idEntity *ent ); - idEntity *GetEntity( void ) const ; - void RemoveOriginOffset( bool remove ); - bool RemoveOrigin( void ) const; - - void GetJointList( const char *jointnames, idList &jointList ) const; - - int NumAnims( void ) const; - const idAnim *GetAnim( int index ) const; - int GetAnim( const char *name ) const; - bool HasAnim( const char *name ) const; - - void ServiceAnims( int fromtime, int totime ); - bool IsAnimating( int currentTime ) const; - - void GetJoints( int *numJoints, idJointMat **jointsPtr ); - int NumJoints( void ) const; - jointHandle_t GetFirstChild( jointHandle_t jointnum ) const; - jointHandle_t GetFirstChild( const char *name ) const; - - idRenderModel *SetModel( const char *modelname ); - idRenderModel *ModelHandle( void ) const; - const idDeclModelDef *ModelDef( void ) const; - - void ForceUpdate( void ); - void ClearForceUpdate( void ); - bool CreateFrame( int animtime, bool force ); - bool FrameHasChanged( int animtime ) const; - void GetDelta( int fromtime, int totime, idVec3 &delta ) const; - bool GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const; - void GetOrigin( int currentTime, idVec3 &pos ) const; - bool GetBounds( int currentTime, idBounds &bounds ); - - idAnimBlend *CurrentAnim( int channelNum ); - void Clear( int channelNum, int currentTime, int cleartime ); - void SetFrame( int channelNum, int animnum, int frame, int currenttime, int blendtime ); - void CycleAnim( int channelNum, int animnum, int currenttime, int blendtime ); - void PlayAnim( int channelNum, int animnum, int currenttime, int blendTime ); - - // copies the current anim from fromChannelNum to channelNum. - // the copied anim will have frame commands disabled to avoid executing them twice. - void SyncAnimChannels( int channelNum, int fromChannelNum, int currenttime, int blendTime ); - - void SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ); - void SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat ); - void ClearJoint( jointHandle_t jointnum ); - void ClearAllJoints( void ); - - void InitAFPose( void ); - void SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin ); - void FinishAFPose( int animnum, const idBounds &bounds, const int time ); - void SetAFPoseBlendWeight( float blendWeight ); - bool BlendAFPose( idJointQuat *blendFrame ) const; - void ClearAFPose( void ); - - void ClearAllAnims( int currentTime, int cleartime ); - - jointHandle_t GetJointHandle( const char *name ) const; - const char * GetJointName( jointHandle_t handle ) const; - int GetChannelForJoint( jointHandle_t joint ) const; - bool GetJointTransform( jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis ); - bool GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ); - - const animFlags_t GetAnimFlags( int animnum ) const; - int NumFrames( int animnum ) const; - int NumSyncedAnims( int animnum ) const; - const char *AnimName( int animnum ) const; - const char *AnimFullName( int animnum ) const; - int AnimLength( int animnum ) const; - const idVec3 &TotalMovementDelta( int animnum ) const; - -private: - void FreeData( void ); - void PushAnims( int channel, int currentTime, int blendTime ); - -private: - const idDeclModelDef * modelDef; - idEntity * entity; - - idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ]; - idList jointMods; - int numJoints; - idJointMat * joints; - - mutable int lastTransformTime; // mutable because the value is updated in CreateFrame - mutable bool stoppedAnimatingUpdate; - bool removeOriginOffset; - bool forceUpdate; - - idBounds frameBounds; - - float AFPoseBlendWeight; - idList AFPoseJoints; - idList AFPoseJointMods; - idList AFPoseJointFrame; - idBounds AFPoseBounds; - int AFPoseTime; -}; - -/* -============================================================================================== - - idAnimManager - -============================================================================================== -*/ - -class idAnimManager { -public: - idAnimManager(); - ~idAnimManager(); - - static bool forceExport; - - void Shutdown( void ); - idMD5Anim * GetAnim( const char *name ); - void ReloadAnims( void ); - void ListAnims( void ) const; - int JointIndex( const char *name ); - const char * JointName( int index ) const; - - void ClearAnimsInUse( void ); - void FlushUnusedAnims( void ); - -private: - idHashTable animations; - idStrList jointnames; - idHashIndex jointnamesHash; -}; - -#endif /* !__ANIM_H__ */ diff --git a/game/anim/anim_blend.cpp b/game/anim/anim_blend.cpp deleted file mode 100644 index df4f0d9fc..000000000 --- a/game/anim/anim_blend.cpp +++ /dev/null @@ -1,5882 +0,0 @@ -/*************************************************************************** - * - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/DarkModGlobals.h" -#include "../../DarkMod/MeleeWeapon.h" -#include "../../DarkMod/AI/Tasks/SingleBarkTask.h" - -static const char *channelNames[ ANIM_NumAnimChannels ] = { - "all", "torso", "legs", "head", "eyelids" -}; - -// how many units to displace to-be-dropped entity down to avoid collision with hand -#define DROP_DOWN_ADJUSTMENT 20.0f -// max distance between joint and object we pickup, anything farther is ignored -#define MAX_PICKUP_DIST 40.0f -// max distance between joint and object we try to activate, anything farther is ignored -#define MAX_ACTIVATE_DIST 50.0f - -/*********************************************************************** - - idAnim - -***********************************************************************/ - -/* -===================== -idAnim::idAnim -===================== -*/ -idAnim::idAnim() { - modelDef = NULL; - numAnims = 0; - memset( anims, 0, sizeof( anims ) ); - memset( &flags, 0, sizeof( flags ) ); -} - -/* -===================== -idAnim::idAnim -===================== -*/ -idAnim::idAnim( const idDeclModelDef *modelDef, const idAnim *anim ) { - int i; - - this->modelDef = modelDef; - numAnims = anim->numAnims; - name = anim->name; - realname = anim->realname; - flags = anim->flags; - - memset( anims, 0, sizeof( anims ) ); - for( i = 0; i < numAnims; i++ ) { - anims[ i ] = anim->anims[ i ]; - anims[ i ]->IncreaseRefs(); - } - - frameLookup.SetNum( anim->frameLookup.Num() ); - memcpy( frameLookup.Ptr(), anim->frameLookup.Ptr(), frameLookup.MemoryUsed() ); - - frameCommands.SetNum( anim->frameCommands.Num() ); - for( i = 0; i < frameCommands.Num(); i++ ) { - frameCommands[ i ] = anim->frameCommands[ i ]; - if ( anim->frameCommands[ i ].string ) { - frameCommands[ i ].string = new idStr( *anim->frameCommands[ i ].string ); - } - } -} - -/* -===================== -idAnim::~idAnim -===================== -*/ -idAnim::~idAnim() { - int i; - - for( i = 0; i < numAnims; i++ ) { - anims[ i ]->DecreaseRefs(); - } - - for( i = 0; i < frameCommands.Num(); i++ ) { - delete frameCommands[ i ].string; - } -} - -/* -===================== -idAnim::SetAnim -===================== -*/ -void idAnim::SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] ) { - int i; - - this->modelDef = modelDef; - - for( i = 0; i < numAnims; i++ ) { - anims[ i ]->DecreaseRefs(); - anims[ i ] = NULL; - } - - assert( ( num > 0 ) && ( num <= ANIM_MaxSyncedAnims ) ); - numAnims = num; - realname = sourcename; - name = animname; - - for( i = 0; i < num; i++ ) { - anims[ i ] = md5anims[ i ]; - anims[ i ]->IncreaseRefs(); - } - - memset( &flags, 0, sizeof( flags ) ); - - for( i = 0; i < frameCommands.Num(); i++ ) { - delete frameCommands[ i ].string; - } - - frameLookup.Clear(); - frameCommands.Clear(); -} - -/* -===================== -idAnim::Name -===================== -*/ -const char *idAnim::Name( void ) const { - return name; -} - -/* -===================== -idAnim::FullName -===================== -*/ -const char *idAnim::FullName( void ) const { - return realname; -} - -/* -===================== -idAnim::MD5Anim - -index 0 will never be NULL. Any anim >= NumAnims will return NULL. -===================== -*/ -const idMD5Anim *idAnim::MD5Anim( int num ) const { - if ( anims == NULL || anims[0] == NULL ) { - return NULL; - } - return anims[ num ]; -} - -/* -===================== -idAnim::ModelDef -===================== -*/ -const idDeclModelDef *idAnim::ModelDef( void ) const { - return modelDef; -} - -/* -===================== -idAnim::Length -===================== -*/ -int idAnim::Length( void ) const { - if ( !anims[ 0 ] ) { - return 0; - } - - return anims[ 0 ]->Length(); -} - -/* -===================== -idAnim::NumFrames -===================== -*/ -int idAnim::NumFrames( void ) const { - if ( !anims[ 0 ] ) { - return 0; - } - - return anims[ 0 ]->NumFrames(); -} - -/* -===================== -idAnim::NumAnims -===================== -*/ -int idAnim::NumAnims( void ) const { - return numAnims; -} - -/* -===================== -idAnim::TotalMovementDelta -===================== -*/ -const idVec3 &idAnim::TotalMovementDelta( void ) const { - if ( !anims[ 0 ] ) { - return vec3_zero; - } - - return anims[ 0 ]->TotalMovementDelta(); -} - -/* -===================== -idAnim::GetOrigin -===================== -*/ -bool idAnim::GetOrigin( idVec3 &offset, int animNum, int currentTime, int cyclecount ) const { - if ( !anims[ animNum ] ) { - offset.Zero(); - return false; - } - - anims[ animNum ]->GetOrigin( offset, currentTime, cyclecount ); - return true; -} - -/* -===================== -idAnim::GetOriginRotation -===================== -*/ -bool idAnim::GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const { - if ( !anims[ animNum ] ) { - rotation.Set( 0.0f, 0.0f, 0.0f, 1.0f ); - return false; - } - - anims[ animNum ]->GetOriginRotation( rotation, currentTime, cyclecount ); - return true; -} - -/* -===================== -idAnim::GetBounds -===================== -*/ -ID_INLINE bool idAnim::GetBounds( idBounds &bounds, int animNum, int currentTime, int cyclecount ) const { - if ( !anims[ animNum ] ) { - return false; - } - - anims[ animNum ]->GetBounds( bounds, currentTime, cyclecount ); - return true; -} - - -/* -===================== -idAnim::AddFrameCommand - -Returns NULL if no error. -===================== -*/ -const char *idAnim::AddFrameCommand( const idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def ) { - int i; - int index; - idStr text; - idStr funcname; - frameCommand_t fc; - idToken token; - const jointInfo_t *jointInfo; - - // make sure we're within bounds - if ( ( framenum < 1 ) || ( framenum > anims[ 0 ]->NumFrames() ) ) { - return va( "Frame %d out of range", framenum ); - } - - // frame numbers are 1 based in .def files, but 0 based internally - framenum--; - - memset( &fc, 0, sizeof( fc ) ); - - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - if ( token == "call" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SCRIPTFUNCTION; - fc.function = gameLocal.program.FindFunction( token ); - if ( !fc.function ) { - return va( "Function '%s' not found", token.c_str() ); - } - } else if ( token == "object_call" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SCRIPTFUNCTIONOBJECT; - fc.string = new idStr( token ); - } else if ( token == "event" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_EVENTFUNCTION; - const idEventDef *ev = idEventDef::FindEvent( token ); - if ( !ev ) { - return va( "Event '%s' not found", token.c_str() ); - } - if ( ev->GetNumArgs() != 0 ) { - return va( "Event '%s' has arguments", token.c_str() ); - } - fc.string = new idStr( token ); - } else if ( token == "sound" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_voice" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_VOICE; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_voice2" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_VOICE2; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_body" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_BODY; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_body2" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_BODY2; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_body3" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_BODY3; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_weapon" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_WEAPON; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_global" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_GLOBAL; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_item" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_ITEM; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "sound_chatter" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SOUND_CHATTER; - if ( !token.Cmpn( "snd_", 4 ) ) { - fc.string = new idStr( token ); - } else { - fc.soundShader = declManager->FindSound( token ); - if ( fc.soundShader->GetState() == DS_DEFAULTED ) { - gameLocal.Warning( "Sound '%s' not found", token.c_str() ); - } - } - } else if ( token == "skin" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_SKIN; - if ( token == "none" ) { - fc.skin = NULL; - } else { - fc.skin = declManager->FindSkin( token ); - if ( !fc.skin ) { - return va( "Skin '%s' not found", token.c_str() ); - } - } - } else if ( token == "fx" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_FX; - if ( !declManager->FindType( DECL_FX, token.c_str() ) ) { - return va( "fx '%s' not found", token.c_str() ); - } - fc.string = new idStr( token ); - } else if ( token == "trigger" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_TRIGGER; - fc.string = new idStr( token ); - } else if ( token == "triggerSmokeParticle" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_TRIGGER_SMOKE_PARTICLE; - fc.string = new idStr( token ); - } else if ( token == "melee" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_MELEE; - if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { - return va( "Unknown entityDef '%s'", token.c_str() ); - } - fc.string = new idStr( token ); - } else if ( token == "direct_damage" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_DIRECTDAMAGE; - if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { - return va( "Unknown entityDef '%s'", token.c_str() ); - } - fc.string = new idStr( token ); - } else if ( token == "attack_begin" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_BEGINATTACK; - if ( !gameLocal.FindEntityDef( token.c_str(), false ) ) { - return va( "Unknown entityDef '%s'", token.c_str() ); - } - fc.string = new idStr( token ); - } else if ( token == "attack_end" ) { - fc.type = FC_ENDATTACK; - } else if ( token == "muzzle_flash" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - if ( ( token != "" ) && !modelDef->FindJoint( token ) ) { - return va( "Joint '%s' not found", token.c_str() ); - } - fc.type = FC_MUZZLEFLASH; - fc.string = new idStr( token ); - } else if ( token == "muzzle_flash" ) { - fc.type = FC_MUZZLEFLASH; - fc.string = new idStr( "" ); - } else if ( token == "create_missile" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - if ( !modelDef->FindJoint( token ) ) { - return va( "Joint '%s' not found", token.c_str() ); - } - fc.type = FC_CREATEMISSILE; - fc.string = new idStr( token ); - } - else if (token == "create_missile_from_def" ) - { - // Read def name - if (!src.ReadTokenOnLine(&token)) - { - return "Unexpected end of line"; - } - - idStr projectileDefName = token; - - assert(projectileDefName.Length() > 0); - - // Read joint name - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - - if ( !modelDef->FindJoint( token ) ) { - return va( "Joint '%s' not found", token.c_str() ); - } - - fc.type = FC_CREATEMISSILE_FROM_DEF; - - // Connect the projectile def and joint name with a pipe and store that - fc.string = new idStr(projectileDefName + "|" + token); - } - else if ( token == "launch_missile" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - if ( !modelDef->FindJoint( token ) ) { - return va( "Joint '%s' not found", token.c_str() ); - } - fc.type = FC_LAUNCHMISSILE; - fc.string = new idStr( token ); - } else if ( token == "fire_missile_at_target" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - jointInfo = modelDef->FindJoint( token ); - if ( !jointInfo ) { - return va( "Joint '%s' not found", token.c_str() ); - } - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_FIREMISSILEATTARGET; - fc.string = new idStr( token ); - fc.index = jointInfo->num; - } else if ( token == "footstep" ) { - fc.type = FC_FOOTSTEP; - } else if ( token == "leftfoot" ) { - fc.type = FC_LEFTFOOT; - } else if ( token == "rightfoot" ) { - fc.type = FC_RIGHTFOOT; - } else if ( token == "enableEyeFocus" ) { - fc.type = FC_ENABLE_EYE_FOCUS; - } else if ( token == "disableEyeFocus" ) { - fc.type = FC_DISABLE_EYE_FOCUS; - } else if ( token == "disableGravity" ) { - fc.type = FC_DISABLE_GRAVITY; - } else if ( token == "enableGravity" ) { - fc.type = FC_ENABLE_GRAVITY; - } else if ( token == "jump" ) { - fc.type = FC_JUMP; - } else if ( token == "enableClip" ) { - fc.type = FC_ENABLE_CLIP; - } else if ( token == "disableClip" ) { - fc.type = FC_DISABLE_CLIP; - } else if ( token == "enableWalkIK" ) { - fc.type = FC_ENABLE_WALK_IK; - } else if ( token == "disableWalkIK" ) { - fc.type = FC_DISABLE_WALK_IK; - } else if ( token == "enableLegIK" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_ENABLE_LEG_IK; - fc.index = atoi( token ); - } else if ( token == "disableLegIK" ) { - if( !src.ReadTokenOnLine( &token ) ) { - return "Unexpected end of line"; - } - fc.type = FC_DISABLE_LEG_IK; - fc.index = atoi( token ); - } else if ( token == "recordDemo" ) { - fc.type = FC_RECORDDEMO; - if( src.ReadTokenOnLine( &token ) ) { - fc.string = new idStr( token ); - } - } else if ( token == "aviGame" ) { - fc.type = FC_AVIGAME; - if( src.ReadTokenOnLine( &token ) ) { - fc.string = new idStr( token ); - } - } else if (token == "setRate" ) - { - if( !src.ReadTokenOnLine( &token ) ) - { - DM_LOG(LC_MISC, LT_ERROR)LOGSTRING("ANIMRATE: Did not find rate, exiting\r"); - return "Unexpected end of line"; - } - - fc.type = FC_SETRATE; - fc.string = new idStr( token ); - } - else if ( token == "reattach" ) - { - // first argument (name of attachment to reattach) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_REATTACH; - fc.string = new idStr( token ); - - // second argument (attach position) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - } - // tels: spawn and attach a new entity - else if ( token == "attach" ) - { - // first argument (class of entity to spawn) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_ATTACH; - fc.string = new idStr( token ); - - // second argument (attach name, optional) - if( src.ReadTokenOnLine( &token ) ) - { - fc.string->Append(va(" %s", token.c_str() )); - } - // third argument (attach position, optional) - if( src.ReadTokenOnLine( &token ) ) - { - fc.string->Append(va(" %s", token.c_str() )); - } - - } - // tels: - else if ( token == "destroy" ) - { - // first argument (attachment name) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_DESTROY; - fc.string = new idStr( token ); - } - // tels: detach entity, put a bit down and let it fall - else if ( token == "drop" ) - { - // first argument (attachment name) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_DROP; - fc.string = new idStr( token ); - } - // tels: detach entity and set or restore it's position - else if ( token == "putdown" ) - { - // first argument (attachment name) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_PUTDOWN; - fc.string = new idStr( token ); - } - // tels: - else if ( token == "pickup" ) - { - // first argument (either entity name, or AIUSE class) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_PICKUP; - fc.string = new idStr( token ); - - // second argument (attach name) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - - // third argument (attach position) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - } - // tels: - else if ( token == "activate_at_joint" ) - { - // first argument (joint name) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_ACTIVATE_AT_JOINT; - fc.string = new idStr( token ); - } - // tels: - else if ( token == "activate_near" ) - { - // first argument (either entity name, or AIUSE class) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_ACTIVATE_NEAR; - fc.string = new idStr( token ); - - // second argument (joint name for distance check) - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - } - else if ( token == "pause" ) - { - fc.type = FC_PAUSE; - } - // Melee Combat Frame commands - else if ( token == "melee_hold" ) - { - // like FC_PAUSE but also sets melee vars on actor - fc.type = FC_MELEE_HOLD; - } - else if ( token == "melee_attack_start" ) - { - // first argument: name of the weapon attachment - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_MELEE_ATTACK_START; - fc.string = new idStr( token ); - - // second argument: name of the attack to start - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - } - else if ( token == "melee_attack_stop" ) - { - // not sure if this will have an argument, but say it will for now - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_MELEE_ATTACK_STOP; - fc.string = new idStr( token ); - } - else if ( token == "melee_parry_start" ) - { - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_MELEE_PARRY_START; - fc.string = new idStr( token ); - - // second argument: name of the parry to start - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.string->Append(va(" %s", token.c_str() )); - } - else if ( token == "melee_parry_stop" ) - { - // not sure if this will have an argument, but say it will for now - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - fc.type = FC_MELEE_PARRY_STOP; - fc.string = new idStr( token ); - } - else if ( token == "set_combat_flag" ) - { - fc.type = FC_SET_ATTACK_FLAG; - - // greebo: Parse attack flag argument - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - if (token == "melee") - { - fc.index = COMBAT_MELEE; - } - else if (token == "ranged") - { - fc.index = COMBAT_RANGED; - } - else - { - return "Unknown attack flag in framecommand."; - } - } - else if ( token == "clear_combat_flag" ) - { - fc.type = FC_CLEAR_ATTACK_FLAG; - - // greebo: Parse attack flag argument - if( !src.ReadTokenOnLine( &token ) ) - return "Unexpected end of line"; - - if (token == "melee") - { - fc.index = COMBAT_MELEE; - } - else if (token == "ranged") - { - fc.index = COMBAT_RANGED; - } - else - { - return "Unknown attack flag in framecommand."; - } - } - else - { - return va( "Unknown command '%s'", token.c_str() ); - } - - // check if we've initialized the frame loopup table - if ( !frameLookup.Num() ) { - // we haven't, so allocate the table and initialize it - frameLookup.SetGranularity( 1 ); - frameLookup.SetNum( anims[ 0 ]->NumFrames() ); - for( i = 0; i < frameLookup.Num(); i++ ) { - frameLookup[ i ].num = 0; - frameLookup[ i ].firstCommand = 0; - } - } - - // allocate space for a new command - frameCommands.Alloc(); - - // calculate the index of the new command - index = frameLookup[ framenum ].firstCommand + frameLookup[ framenum ].num; - - // move all commands from our index onward up one to give us space for our new command - for( i = frameCommands.Num() - 1; i > index; i-- ) { - frameCommands[ i ] = frameCommands[ i - 1 ]; - } - - // fix the indices of any later frames to account for the inserted command - for( i = framenum + 1; i < frameLookup.Num(); i++ ) { - frameLookup[ i ].firstCommand++; - } - - // store the new command - frameCommands[ index ] = fc; - - // increase the number of commands on this frame - frameLookup[ framenum ].num++; - - // return with no error - return NULL; -} - -/* -===================== -idAnim::CallFrameCommands -===================== -*/ -void idAnim::CallFrameCommands( idEntity *ent, int from, int to, idAnimBlend *caller ) -{ - int index; - int end; - int frame; - int numframes; - - numframes = anims[ 0 ]->NumFrames(); - - frame = from; - while( frame != to ) { - frame++; - if ( frame >= numframes ) { - frame = 0; - } - - index = frameLookup[ frame ].firstCommand; - end = index + frameLookup[ frame ].num; - while( index < end ) { - const frameCommand_t &command = frameCommands[ index++ ]; - - if (cv_ai_debug_anims.GetBool() && ent != gameLocal.GetLocalPlayer()) - { - gameLocal.Printf("Frame: %d - executing frame command %d (%s)\n", gameLocal.framenum, command.type, ent->name.c_str()); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Frame: %d - executing frame command %d (%s)\r", gameLocal.framenum, command.type, ent->name.c_str()); - } - - switch( command.type ) { - case FC_SCRIPTFUNCTION: { - gameLocal.CallFrameCommand( ent, command.function ); - break; - } - case FC_SCRIPTFUNCTIONOBJECT: { - gameLocal.CallObjectFrameCommand( ent, command.string->c_str() ); - break; - } - case FC_EVENTFUNCTION: { - const idEventDef *ev = idEventDef::FindEvent( command.string->c_str() ); - ent->ProcessEvent( ev ); - break; - } - case FC_SOUND: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ANY, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_ANY, 0, false, NULL ); - } - break; - } - case FC_SOUND_VOICE: - { - if (command.soundShader == NULL) - { - // greebo: Use the communication subsystem for AI (issue #2483) - if (ent->IsType(idAI::Type)) - { - static_cast(ent)->commSubsystem->AddCommTask( - ai::CommunicationTaskPtr(new ai::SingleBarkTask(*(command.string))) - ); - } - else if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_voice' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } - else - { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE, 0, false, NULL ); - } - break; - } - case FC_SOUND_VOICE2: - { - if (command.soundShader == NULL) - { - // greebo: Use the communication subsystem for AI (issue #2483) - if (ent->IsType(idAI::Type)) - { - static_cast(ent)->commSubsystem->AddCommTask( - ai::CommunicationTaskPtr(new ai::SingleBarkTask(*(command.string))) - ); - } - else if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE2, 0, false, NULL ) ) - { - gameLocal.Warning( "Framecommand 'sound_voice2' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } - else - { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE2, 0, false, NULL ); - } - break; - } - case FC_SOUND_BODY: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_body' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY, 0, false, NULL ); - } - break; - } - case FC_SOUND_BODY2: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY2, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_body2' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY2, 0, false, NULL ); - } - break; - } - case FC_SOUND_BODY3: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_BODY3, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_body3' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_BODY3, 0, false, NULL ); - } - break; - } - case FC_SOUND_WEAPON: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_WEAPON, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_weapon' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_WEAPON, 0, false, NULL ); - } - break; - } - case FC_SOUND_GLOBAL: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_global' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); - } - break; - } - case FC_SOUND_ITEM: { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_ITEM, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_item' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_ITEM, 0, false, NULL ); - } - break; - } - case FC_SOUND_CHATTER: { - if ( ent->CanPlayChatterSounds() ) { - if ( !command.soundShader ) { - if ( !ent->StartSound( command.string->c_str(), SND_CHANNEL_VOICE, 0, false, NULL ) ) { - gameLocal.Warning( "Framecommand 'sound_chatter' on entity '%s', anim '%s', frame %d: Could not find sound '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - } else { - ent->StartSoundShader( command.soundShader, SND_CHANNEL_VOICE, 0, false, NULL ); - } - } - break; - } - case FC_FX: { - idEntityFx::StartFx( command.string->c_str(), NULL, NULL, ent, true ); - break; - } - case FC_SKIN: { - ent->SetSkin( command.skin ); - break; - } - case FC_TRIGGER: { - idEntity *target; - - target = gameLocal.FindEntity( command.string->c_str() ); - if ( target ) { - target->Signal( SIG_TRIGGER ); - target->ProcessEvent( &EV_Activate, ent ); - target->TriggerGuis(); - } else { - gameLocal.Warning( "Framecommand 'trigger' on entity '%s', anim '%s', frame %d: Could not find entity '%s'", - ent->name.c_str(), FullName(), frame + 1, command.string->c_str() ); - } - break; - } - case FC_TRIGGER_SMOKE_PARTICLE: { - ent->ProcessEvent( &AI_TriggerParticles, command.string->c_str() ); - break; - } - case FC_MELEE: { - ent->ProcessEvent( &AI_AttackMelee, command.string->c_str() ); - break; - } - case FC_DIRECTDAMAGE: { - ent->ProcessEvent( &AI_DirectDamage, command.string->c_str() ); - break; - } - case FC_BEGINATTACK: { - ent->ProcessEvent( &AI_BeginAttack, command.string->c_str() ); - break; - } - case FC_ENDATTACK: { - ent->ProcessEvent( &AI_EndAttack ); - break; - } - case FC_MUZZLEFLASH: { - ent->ProcessEvent( &AI_MuzzleFlash, command.string->c_str() ); - break; - } - case FC_CREATEMISSILE: { - ent->ProcessEvent( &AI_CreateMissile, command.string->c_str() ); - break; - } - case FC_CREATEMISSILE_FROM_DEF: - { - // Split the def name and the joint name again - int pipePos = command.string->Find('|'); - - assert(pipePos != -1); - - idStr defName = command.string->Left(pipePos); - idStr jointName = command.string->Mid(pipePos+1, command.string->Length() - pipePos - 1); - - ent->ProcessEvent(&AI_CreateMissileFromDef, defName.c_str(), jointName.c_str()); - break; - } - case FC_LAUNCHMISSILE: { - ent->ProcessEvent( &AI_AttackMissile, command.string->c_str() ); - break; - } - case FC_FIREMISSILEATTARGET: { - ent->ProcessEvent( &AI_FireMissileAtTarget, modelDef->GetJointName( command.index ), command.string->c_str() ); - break; - } - case FC_FOOTSTEP : { - ent->ProcessEvent( &EV_Footstep ); - break; - } - case FC_LEFTFOOT: { - ent->ProcessEvent( &EV_FootstepLeft ); - break; - } - case FC_RIGHTFOOT: { - ent->ProcessEvent( &EV_FootstepRight ); - break; - } - case FC_ENABLE_EYE_FOCUS: { - ent->ProcessEvent( &AI_EnableEyeFocus ); - break; - } - case FC_DISABLE_EYE_FOCUS: { - ent->ProcessEvent( &AI_DisableEyeFocus ); - break; - } - case FC_DISABLE_GRAVITY: { - ent->ProcessEvent( &AI_DisableGravity ); - break; - } - case FC_ENABLE_GRAVITY: { - ent->ProcessEvent( &AI_EnableGravity ); - break; - } - case FC_JUMP: { - ent->ProcessEvent( &AI_JumpFrame ); - break; - } - case FC_ENABLE_CLIP: { - ent->ProcessEvent( &AI_EnableClip ); - break; - } - case FC_DISABLE_CLIP: { - ent->ProcessEvent( &AI_DisableClip ); - break; - } - case FC_ENABLE_WALK_IK: { - ent->ProcessEvent( &EV_EnableWalkIK ); - break; - } - case FC_DISABLE_WALK_IK: { - ent->ProcessEvent( &EV_DisableWalkIK ); - break; - } - case FC_ENABLE_LEG_IK: { - ent->ProcessEvent( &EV_EnableLegIK, command.index ); - break; - } - case FC_DISABLE_LEG_IK: { - ent->ProcessEvent( &EV_DisableLegIK, command.index ); - break; - } - case FC_RECORDDEMO: { - if ( command.string ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "recordDemo %s", command.string->c_str() ) ); - } else { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "stoprecording" ); - } - break; - } - case FC_AVIGAME: - { - if ( command.string ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "aviGame %s", command.string->c_str() ) ); - } else { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "aviGame" ); - } - break; - } - - case FC_SETRATE: - { - float newRate = atof( command.string->c_str() ); - - for( int ind = 0; ind < numAnims; ind++ ) - { - // debug for SetRate debugging - //DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("SETFRAMERATE: Setting frame rate: %d, on entity %s, channel %d\r", newRate, ent->name.c_str(), ind ); - // const_cast(anims[ ind ])->SetFrameRate( newRate ); - // Test out this method. Hope it doesn't effect all anims on the channel. - caller->SetPlaybackRate( gameLocal.time, newRate ); - } - break; - } - - case FC_REATTACH: - { - int spcind = command.string->Find(" "); - idStr AttName = command.string->Left( spcind ).c_str(); - idStr AttPos = command.string->Mid( spcind+1, command.string->Length() ); - - ent->ReAttachToPos( AttName, AttPos ); - break; - } - // tels: detach and destroy an attachment - case FC_DESTROY: - { - // get the attachment - idEntity* attEntity = ent->GetAttachment( command.string->c_str() ); - if (attEntity) - { - ent->Detach( command.string->c_str() ); - // and now remove it from the game world - // gameLocal.Warning ( "Going to remove attachment '%s' from '%s'\n", command.string->c_str(), ent->getName().c_str() ); - attEntity->PostEventMS( &EV_Remove, 0 ); - } - else - { - gameLocal.Warning ( "Cannot find attachment '%s' to destroy in animation.\n", command.string->c_str() ); - } - break; - } - // tels: drop an attachement - case FC_DROP: - { - idEntity* detachedEntity = ent->GetAttachment( command.string->c_str() ); - - if (!detachedEntity) - { - gameLocal.Printf(" Couldn't find attachment position by name %s\n", command.string->c_str()); - - // couldn't find the attached entity by attachment name, so try all attachments: - - // Tels: That does not work, as it doesn't save the joint info - // New position system: -/* CAttachInfo *info; - SAttachPosition *pos; - - if( (info = ent->GetAttachInfo( command.string->c_str() )) != NULL) - { - gameLocal.Printf(" Found attachment position %s\n", info->name.c_str() ); - detachedEntity = info->ent.GetEntity(); - if( !info->ent.IsValid() || !detachedEntity ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Invalid attached entity at position %s on entity %s\r", info->name.c_str(), name.c_str()); - detachedEntity = NULL; - } - } - if( (pos = ent->GetAttachPosition( command.string->c_str() )) != NULL) - { - gameLocal.Printf(" Found attachment position %s\n", pos->name.c_str() ); - //detachedEntity = ent->GetAttachment( pos.name ); - //detachedEntity = pos->ent; - } - */ - } - - // avoid the entity clipping into the hand by teleporting it down half a unit - if (detachedEntity) - { - // only detach and unbind it if we have an entity - ent->Detach( command.string->c_str() ); - - idVec3 origin = detachedEntity->GetPhysics()->GetOrigin(); - origin.z -= DROP_DOWN_ADJUSTMENT; - detachedEntity->GetPhysics()->SetOrigin( origin ); - detachedEntity->m_droppedByAI = true; // grayman #1330 - } - break; - } - // tels: put down an attachement, works like drop, but restores origin and angles - case FC_PUTDOWN: - { - idEntity* detachedEntity = ent->GetAttachment( command.string->c_str() ); - - // detach and unbind it - ent->Detach( command.string->c_str() ); - - // now restore origin and angles - idVec3 origin; - idAngles angles; - const idKeyValue *tempkv = ent->spawnArgs.FindKey( "putdown_origin" ); - if( tempkv ) - { - // if the entity itself specifies where it should be put down, use this - //gameLocal.Printf(" Using putdown_origin\n"); - origin = detachedEntity->spawnArgs.GetVector( "putdown_origin", "0 0 0" ); - detachedEntity->GetPhysics()->SetOrigin( origin ); - } - else - { - // if not set on entity, restore pre-pickup values - //gameLocal.Printf(" Using pre_pickup_origin\n"); - origin = detachedEntity->spawnArgs.GetVector( "pre_pickup_origin", "0 0 0" ); - } - tempkv = ent->spawnArgs.FindKey( "putdown_angles" ); - if( tempkv ) - { - // if the entity itself specifies how it should be put down, use this - //gameLocal.Printf(" Using putdown_angles\n"); - angles = idAngles( detachedEntity->spawnArgs.GetVector( "putdown_angles", "0 0 0" ) ); - } - else - { - // if not set on entity, restore pre-pickup values - //gameLocal.Printf(" Using pre_pickup_angles\n"); - angles = idAngles( detachedEntity->spawnArgs.GetVector( "pre_pickup_angles", "0 0 0" ) ); - } - // gameLocal.Printf("Restoring origin %f %f %f and angles %f %f %f on putdown", origin.x, origin.y, origin.z, angles[0], angles[1], angles[2] ); - detachedEntity->GetPhysics()->SetOrigin( origin ); - detachedEntity->SetAngles( angles ); - break; - } - // tels: spawn an entity and attach it - case FC_ATTACH: - { - // possible formats: - // "atdm:foo_bar" - // "atdm:foo_bar book" - // "atdm:foo_bar book hip_left" - - idStr EntClass = ""; - // use these as defaults - idStr AttName = ""; - idStr AttPos = ""; - - int spcind = command.string->Find(' '); - if (spcind > 0) - { - // format of AttName is afterwards either "book" or "book hip_left" - EntClass = command.string->Left( spcind ); - AttName = command.string->Mid( spcind+1, command.string->Length() ); - spcind = AttName.Find(' '); - if (spcind > 0) - { - AttPos = AttName.Mid( spcind+1, AttName.Length() ); - AttName = AttName.Left( spcind ); - } - } - - // check that there isn't already something attached: - // idEntity* attEntity = ent->GetAttachment(AttPos.c_str()); // grayman #2603 - This was wrong. GetAttachment wants the Attach Name ('melee_weapon') not the position ('hand_l') - idEntity* attEntity = ent->GetAttachmentByPosition(AttPos.c_str()); // positions now stored in attach info - if (attEntity) - { - gameLocal.Warning("Already have an attachment at %s, skipping frame command.", AttPos.c_str()); - } - else - { - // spawn the entity - idEntity* spawnedEntity; - const idDict* entityDef = gameLocal.FindEntityDefDict( EntClass ); - - if (!entityDef) - { - gameLocal.Error("Cannot spawn %s - no such entityDef", EntClass.c_str() ); - } - gameLocal.SpawnEntityDef(*entityDef, &spawnedEntity); - // gameLocal.Printf("Attaching '%s' (%s) as '%s' to '%s'\n", EntClass.c_str(), spawnedEntity->GetName(), AttName.c_str(), AttPos.c_str() ); - - // Tels: Fix for alerted guards dropping entities spawned during animations, - // this is queried during alerted-drop (via unbindOnalertIndex), but not during animation - // drop or putdown (as we want an animation be able to create objects out of thin air and let - // a tdm_suicide script object take care of removing the object. An example is an AI eating an - // apple and dropping an apple core, which will vanish a minute later): - spawnedEntity->spawnArgs.Set("_spawned_by_anim", "1"); - - ent->Attach(spawnedEntity, AttPos, AttName); - - // and another fix for entities spawned, but then either dropped or stuck to the AI forever: - float delay = spawnedEntity->spawnArgs.GetFloat("remove_delay", "0"); - if (delay > 0) - { - // if remove_delay is set, remove that object after "remove_delay" seconds (* 1000 to get ms) - spawnedEntity->PostEventMS( &EV_Remove, delay * 1000 ); - } - } - break; - } - // tels: pick up an entity from the world - case FC_PICKUP: - { - // possible formats: - // "atdm_some_book book hand_r" - // "AIUSE_EAT food hand_l" - // "AIUSE_DRINK drink hand_l" - - int spcind = command.string->Find(" "); - // format of AttName is afterwards "food hand_r" - idStr EntityName = command.string->Left( spcind ); - idStr AttName = command.string->Mid( spcind+1, command.string->Length() ); - - idStr AttPos; - spcind = AttName.Find(" "); - if (spcind > 0) - { - AttPos = AttName.Mid( spcind+1, AttName.Length() ); - AttName = AttName.Left( spcind ); - } - - // gameLocal.Warning ( "Picking up '%s' as '%s' to '%s'", EntityName.c_str(), AttName.c_str(), AttPos.c_str()); - - idStr Spawnarg = "pickup_"; Spawnarg.Append( name ); - // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) - idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; - idEntity* attTarget = animEnt->GetEntityClosestToJoint( - AttPos.c_str(), EntityName.c_str(), Spawnarg.c_str(), MAX_PICKUP_DIST ); - - // did we find an entity to pickup? - if (attTarget) - { - // TODO: check that this entity is not attached to something/someone else - - // gameLocal.Warning ( "Found entity %s", attTarget->name.c_str() ); - - // gameLocal.Printf ( "Attaching '%s' as '%s' to '%s' (in pickup)\n", EntityName.c_str(), AttName.c_str(), AttPos.c_str()); - // first get the origin and rotation of the entity - idVec3 origin = attTarget->GetPhysics()->GetOrigin(); - idAngles ang = attTarget->GetPhysics()->GetAxis().ToAngles(); - // now store them in temp. spawnargs - attTarget->spawnArgs.SetVector( "pre_pickup_origin", origin ); - attTarget->spawnArgs.SetVector( "pre_pickup_angles", idVec3( ang[0], ang[1], ang[2] ) ); - // gameLocal.Warning ( "Saving origin %f %f %f and angles %f %f %f for %s", origin.x, origin.y, origin.z, ang[0], ang[1], ang[2], AttName.c_str() ); - // and now attach it - ent->Attach( attTarget, AttPos, AttName ); - } - else - { - // no entity found, abort animation? - gameLocal.Warning( " Could not find entity '%s' to attach", EntityName.c_str() ); - } - break; - } - // tels: activate the entity attached at the given joint - case FC_ACTIVATE_AT_JOINT: - { - // possible formats: - // "hand_r" - - // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) - idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; - idEntity* attTarget = animEnt->GetEntityClosestToJoint( - // invalid spawnarg name and entity name to disable these features (just get closest attached entity) - command.string->c_str(), "", "", 0.1f ); - - // did we find an entity to pickup? - // TODO: check that this entity is attached to ourselves - if (attTarget) - { - // TODO: check that this entity is not attached to something/someone else - gameLocal.Warning ( "%s is activating %s.", name.c_str(), attTarget->GetName() ); - attTarget->Activate( ent ); - } - else - { - gameLocal.Warning ( "%s has no entity at joint %s to activate.", name.c_str(), command.string->c_str()); - } - break; - } - // tels: activate the given entity near the given joint - case FC_ACTIVATE_NEAR: - { - // possible formats: - // "atdm_some_entity hand_r" - // "AIUSE_EAT hand_l" - - int spcind = command.string->Find(" "); - idStr EntityName = command.string->Left( spcind ); - idStr AttPos = command.string->Mid( spcind+1, command.string->Length() ); - - idStr Spawnarg = "activate_"; Spawnarg.Append( name ); - // ent is idEntity, but also an idAnimatedEntity (whoever came up with that distinction?) - idAnimatedEntity* animEnt = (idAnimatedEntity *)ent; - idEntity* attTarget = animEnt->GetEntityClosestToJoint( - AttPos.c_str(), EntityName.c_str(), Spawnarg.c_str(), MAX_ACTIVATE_DIST ); - - // did we find an entity to activate? - if (attTarget) - { - // gameLocal.Warning ( "Found entity %s", attTarget->name.c_str() ); - gameLocal.Warning ( "%s is activating %s near joint %s.", name.c_str(), EntityName.c_str(), AttPos.c_str()); - attTarget->Activate( ent ); - } - break; - } - case FC_PAUSE: - { - caller->Pause( true ); - break; - } - case FC_MELEE_HOLD: - { - caller->Pause( true ); - - idActor *ActOwner; - if( ent->IsType(idWeapon::Type) ) - ActOwner = static_cast(ent)->GetOwner(); - else if( ent->IsType(idActor::Type) ) - ActOwner = static_cast(ent); - else - ActOwner = NULL; - - // Update the associated actor's melee status - if( ActOwner ) - ActOwner->Event_MeleeActionHeld(); - - break; - } - case FC_MELEE_ATTACK_START: - { - const char *WeapName, *AttName; - int spcind = command.string->Find(" "); - WeapName = command.string->Left( spcind ).c_str(); - AttName = command.string->Mid( spcind+1, command.string->Length() ); - - idEntity *AttEnt = ent->GetAttachment( WeapName ); - if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) - { - idActor *ActOwner; - if( ent->IsType(idWeapon::Type) ) - ActOwner = static_cast(ent)->GetOwner(); - else if( ent->IsType(idActor::Type) ) - ActOwner = static_cast(ent); - else - ActOwner = NULL; - - static_cast(AttEnt)->ActivateAttack - ( ActOwner, AttName ); - } - - break; - } - case FC_MELEE_ATTACK_STOP: - { - idEntity *AttEnt = ent->GetAttachment( command.string->c_str() ); - if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) - { - CMeleeWeapon *WeapEnt = static_cast(AttEnt); - if( WeapEnt->GetOwner() ) - { - CMeleeStatus *pStatus = &WeapEnt->GetOwner()->m_MeleeStatus; - // if attack hasn't hit yet, this was a miss - if( pStatus->m_ActionResult == MELEERESULT_IN_PROGRESS ) - { - pStatus->m_ActionResult = MELEERESULT_AT_MISSED; - pStatus->m_ActionPhase = MELEEPHASE_RECOVERING; - } - } - WeapEnt->DeactivateAttack(); - } - - break; - } - case FC_MELEE_PARRY_START: - { - const char *WeapName, *ParName; - int spcind = command.string->Find(" "); - WeapName = command.string->Left( spcind ).c_str(); - ParName = command.string->Mid( spcind+1, command.string->Length() ); - - idEntity *AttEnt = ent->GetAttachment( WeapName ); - if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) - { - idActor *ActOwner; - if( ent->IsType(idWeapon::Type) ) - ActOwner = static_cast(ent)->GetOwner(); - else if( ent->IsType(idActor::Type) ) - ActOwner = static_cast(ent); - else - ActOwner = NULL; - - static_cast(AttEnt)->ActivateParry - ( ActOwner, ParName ); - } - - break; - } - case FC_MELEE_PARRY_STOP: - { - idEntity *AttEnt = ent->GetAttachment( command.string->c_str() ); - if( AttEnt && AttEnt->IsType(CMeleeWeapon::Type) ) - { - static_cast(AttEnt)->DeactivateParry(); - } - - break; - } - case FC_SET_ATTACK_FLAG: - if (ent->IsType(idActor::Type)) - { - static_cast(ent)->SetAttackFlag(static_cast(command.index), true); - } - break; - case FC_CLEAR_ATTACK_FLAG: - if (ent->IsType(idActor::Type)) - { - static_cast(ent)->SetAttackFlag(static_cast(command.index), false); - } - break; - } - } - } -} - -/* -===================== -idAnim::FindFrameForFrameCommand -===================== -*/ -int idAnim::FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const { - int frame; - int index; - int numframes; - int end; - - if ( !frameCommands.Num() ) { - return -1; - } - - numframes = anims[ 0 ]->NumFrames(); - for( frame = 0; frame < numframes; frame++ ) { - end = frameLookup[ frame ].firstCommand + frameLookup[ frame ].num; - for( index = frameLookup[ frame ].firstCommand; index < end; index++ ) { - if ( frameCommands[ index ].type == framecommand ) { - if ( command ) { - *command = &frameCommands[ index ]; - } - return frame; - } - } - } - - if ( command ) { - *command = NULL; - } - - return -1; -} - -/* -===================== -idAnim::HasFrameCommands -===================== -*/ -bool idAnim::HasFrameCommands( void ) const { - if ( !frameCommands.Num() ) { - return false; - } - return true; -} - -/* -===================== -idAnim::SetAnimFlags -===================== -*/ -void idAnim::SetAnimFlags( const animFlags_t &animflags ) { - flags = animflags; -} - -/* -===================== -idAnim::GetAnimFlags -===================== -*/ -const animFlags_t &idAnim::GetAnimFlags( void ) const { - return flags; -} - -/*********************************************************************** - - idAnimBlend - -***********************************************************************/ - -/* -===================== -idAnimBlend::idAnimBlend -===================== -*/ -idAnimBlend::idAnimBlend( void ) { - Reset( NULL ); -} - -/* -===================== -idAnimBlend::Save - -archives object for save game file -===================== -*/ -void idAnimBlend::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( starttime ); - savefile->WriteInt( endtime ); - savefile->WriteInt( timeOffset ); - savefile->WriteFloat( rate ); - - savefile->WriteInt( blendStartTime ); - savefile->WriteInt( blendDuration ); - savefile->WriteFloat( blendStartValue ); - savefile->WriteFloat( blendEndValue ); - - for( i = 0; i < ANIM_MaxSyncedAnims; i++ ) { - savefile->WriteFloat( animWeights[ i ] ); - } - savefile->WriteShort( cycle ); - savefile->WriteShort( frame ); - savefile->WriteShort( animNum ); - savefile->WriteBool( allowMove ); - savefile->WriteBool( allowFrameCommands ); - savefile->WriteBool( m_bPaused ); - savefile->WriteInt( m_PausedTime ); - savefile->WriteInt( m_PausedEndtime ); - savefile->WriteShort( m_PausedCycle ); -} - -/* -===================== -idAnimBlend::Restore - -unarchives object from save game file -===================== -*/ -void idAnimBlend::Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef ) { - int i; - - this->modelDef = modelDef; - - savefile->ReadInt( starttime ); - savefile->ReadInt( endtime ); - savefile->ReadInt( timeOffset ); - savefile->ReadFloat( rate ); - - savefile->ReadInt( blendStartTime ); - savefile->ReadInt( blendDuration ); - savefile->ReadFloat( blendStartValue ); - savefile->ReadFloat( blendEndValue ); - - for( i = 0; i < ANIM_MaxSyncedAnims; i++ ) { - savefile->ReadFloat( animWeights[ i ] ); - } - savefile->ReadShort( cycle ); - savefile->ReadShort( frame ); - savefile->ReadShort( animNum ); - if ( !modelDef ) { - animNum = 0; - } else if ( ( animNum < 0 ) || ( animNum > modelDef->NumAnims() ) ) { - gameLocal.Warning( "Anim number %d out of range for model '%s' during save game", animNum, modelDef->GetModelName() ); - animNum = 0; - } - savefile->ReadBool( allowMove ); - savefile->ReadBool( allowFrameCommands ); - savefile->ReadBool( m_bPaused ); - savefile->ReadInt( m_PausedTime ); - savefile->ReadInt( m_PausedEndtime ); - savefile->ReadShort( m_PausedCycle ); -} - -/* -===================== -idAnimBlend::Reset -===================== -*/ -void idAnimBlend::Reset( const idDeclModelDef *_modelDef ) -{ - - modelDef = _modelDef; - cycle = 1; - starttime = 0; - endtime = 0; - timeOffset = 0; - rate = 1.0f; - frame = 0; - allowMove = true; - allowFrameCommands = true; - m_bPaused = false; - m_PausedEndtime = 0; - m_PausedCycle = 1; - m_PausedTime = 0; - - animNum = 0; - - memset( animWeights, 0, sizeof( animWeights ) ); - - blendStartValue = 0.0f; - blendEndValue = 0.0f; - blendStartTime = 0; - blendDuration = 0; -} - -/* -===================== -idAnimBlend::FullName -===================== -*/ -const char *idAnimBlend::AnimFullName( void ) const { - const idAnim *anim = Anim(); - if ( !anim ) { - return ""; - } - - return anim->FullName(); -} - -/* -===================== -idAnimBlend::AnimName -===================== -*/ -const char *idAnimBlend::AnimName( void ) const { - const idAnim *anim = Anim(); - if ( !anim ) { - return ""; - } - - return anim->Name(); -} - -/* -===================== -idAnimBlend::NumFrames -===================== -*/ -int idAnimBlend::NumFrames( void ) const { - const idAnim *anim = Anim(); - if ( !anim ) { - return 0; - } - - return anim->NumFrames(); -} - -/* -===================== -idAnimBlend::Length -===================== -*/ -int idAnimBlend::Length( void ) const { - const idAnim *anim = Anim(); - if ( !anim ) { - return 0; - } - - return anim->Length(); -} - -/* -===================== -idAnimBlend::GetWeight -===================== -*/ -float idAnimBlend::GetWeight( int currentTime ) const { - int timeDelta; - float frac; - float w; - - timeDelta = currentTime - blendStartTime; - if ( timeDelta <= 0 ) { - w = blendStartValue; - } else if ( timeDelta >= blendDuration ) { - w = blendEndValue; - } else { - frac = ( float )timeDelta / ( float )blendDuration; - w = blendStartValue + ( blendEndValue - blendStartValue ) * frac; - } - - return w; -} - -/* -===================== -idAnimBlend::GetFinalWeight -===================== -*/ -float idAnimBlend::GetFinalWeight( void ) const { - return blendEndValue; -} - -/* -===================== -idAnimBlend::SetWeight -===================== -*/ -void idAnimBlend::SetWeight( float newweight, int currentTime, int blendTime ) { - blendStartValue = GetWeight( currentTime ); - blendEndValue = newweight; - blendStartTime = currentTime - 1; - blendDuration = blendTime; - - if ( !newweight ) { - endtime = currentTime + blendTime; - } -} - -/* -===================== -idAnimBlend::NumSyncedAnims -===================== -*/ -int idAnimBlend::NumSyncedAnims( void ) const { - const idAnim *anim = Anim(); - if ( !anim ) { - return 0; - } - - return anim->NumAnims(); -} - -/* -===================== -idAnimBlend::SetSyncedAnimWeight -===================== -*/ -bool idAnimBlend::SetSyncedAnimWeight( int num, float weight ) { - const idAnim *anim = Anim(); - if ( !anim ) { - return false; - } - - if ( ( num < 0 ) || ( num > anim->NumAnims() ) ) { - return false; - } - - animWeights[ num ] = weight; - return true; -} - -/* -===================== -idAnimBlend::UpdatePlaybackRate -===================== -*/ -void idAnimBlend::UpdatePlaybackRate(int _animNum, const idEntity* ent) { - if (ent != NULL && _animNum >= 0 && animNum < ent->m_animRates.Num()) { - // this->rate = ent->m_animRates[_animNum]; - SetPlaybackRate( gameLocal.time, ent->m_animRates[_animNum] ); - } -} - -/* -===================== -idAnimBlend::SetFrame -===================== -*/ -void idAnimBlend::SetFrame( const idDeclModelDef *modelDef, int _animNum, int _frame, int currentTime, int blendTime, const idEntity *ent ) { - Reset( modelDef ); - if ( !modelDef ) { - return; - } - - const idAnim *_anim = modelDef->GetAnim( _animNum ); - if ( !_anim ) { - return; - } - - UpdatePlaybackRate(_animNum, ent); - - const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); - if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { - gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); - return; - } - - animNum = _animNum; - starttime = currentTime; - endtime = -1; - cycle = -1; - animWeights[ 0 ] = 1.0f; - frame = _frame; - - // a frame of 0 means it's not a single frame blend, so we set it to frame + 1 - if ( frame <= 0 ) { - frame = 1; - } else if ( frame > _anim->NumFrames() ) { - frame = _anim->NumFrames(); - } - - // set up blend - blendEndValue = 1.0f; - blendStartTime = currentTime - 1; - blendDuration = blendTime; - blendStartValue = 0.0f; -} - -/* -===================== -idAnimBlend::CycleAnim -===================== -*/ -void idAnimBlend::CycleAnim( const idDeclModelDef *modelDef, int _animNum, int currentTime, int blendTime, const idEntity* ent ) -{ - Reset( modelDef ); - if ( !modelDef ) { - return; - } - - const idAnim *_anim = modelDef->GetAnim( _animNum ); - if ( !_anim ) { - return; - } - - const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); - if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { - gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); - return; - } - - animNum = _animNum; - animWeights[ 0 ] = 1.0f; - endtime = -1; - cycle = -1; - if ( _anim->GetAnimFlags().random_cycle_start ) { - // start the animation at a random time so that characters don't walk in sync - starttime = (int)(currentTime - gameLocal.random.RandomFloat() * _anim->Length()); - } else { - starttime = currentTime; - } - - // ishtvan: Moved this TDM call here to fix bugs - UpdatePlaybackRate(_animNum, ent); - - // set up blend - blendEndValue = 1.0f; - blendStartTime = currentTime - 1; - blendDuration = blendTime; - blendStartValue = 0.0f; -} - -/* -===================== -idAnimBlend::PlayAnim -===================== -*/ -void idAnimBlend::PlayAnim( const idDeclModelDef *modelDef, int _animNum, int currentTime, int blendTime, const idEntity *ent ) -{ - Reset( modelDef ); - if ( !modelDef ) { - return; - } - - const idAnim *_anim = modelDef->GetAnim( _animNum ); - if ( !_anim ) { - return; - } - - const idMD5Anim *md5anim = _anim->MD5Anim( 0 ); - if ( modelDef->Joints().Num() != md5anim->NumJoints() ) { - gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", modelDef->GetModelName(), md5anim->Name() ); - return; - } - - animNum = _animNum; - starttime = currentTime; - endtime = starttime + _anim->Length(); - cycle = 1; - animWeights[ 0 ] = 1.0f; - - // ishtvan: Moved this TDM call here to fix bugs - UpdatePlaybackRate(_animNum, ent); - - // set up blend - blendEndValue = 1.0f; - blendStartTime = currentTime - 1; - blendDuration = blendTime; - blendStartValue = 0.0f; -} - -/* -===================== -idAnimBlend::Clear -===================== -*/ -void idAnimBlend::Clear( int currentTime, int clearTime ) { - if ( !clearTime ) { - Reset( modelDef ); - } else { - SetWeight( 0.0f, currentTime, clearTime ); - } -} - -/* -===================== -idAnimBlend::IsDone -===================== -*/ -bool idAnimBlend::IsDone( int currentTime ) const -{ - if( m_bPaused ) - return false; - - if ( !frame && ( endtime > 0 ) && ( currentTime >= endtime ) ) { - return true; - } - - if ( ( blendEndValue <= 0.0f ) && ( currentTime >= ( blendStartTime + blendDuration ) ) ) { - return true; - } - - return false; -} - -/* -===================== -idAnimBlend::FrameHasChanged -===================== -*/ -bool idAnimBlend::FrameHasChanged( int currentTime ) const -{ - // if we don't have an anim, no change - if ( !animNum ) - return false; - - // if anim is done playing, no change - if ( ( endtime > 0 ) && ( currentTime > endtime ) ) - return false; - - // if our blend weight changes, we need to update - if ( ( currentTime < ( blendStartTime + blendDuration ) - && ( blendStartValue != blendEndValue ) ) ) - return true; - - // if we're a single frame anim and this isn't the frame we started on, we don't need to update - // Or if we are paused at a single frame? - if ( ( frame || ( NumFrames() == 1 ) /* || m_bPaused */ ) && ( currentTime != starttime ) ) - return false; - - return true; -} - -/* -===================== -idAnimBlend::GetCycleCount -===================== -*/ -int idAnimBlend::GetCycleCount( void ) const { - return cycle; -} - -/* -===================== -idAnimBlend::SetCycleCount -===================== -*/ -void idAnimBlend::SetCycleCount( int count ) { - const idAnim *anim = Anim(); - - if ( !anim ) { - cycle = -1; - endtime = 0; - } else { - cycle = count; - if ( cycle < 0 ) { - cycle = -1; - endtime = -1; - } else if ( cycle == 0 ) { - cycle = 1; - - // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion - if ( rate == 1.0f ) { - endtime = starttime - timeOffset + anim->Length(); - } else if ( rate != 0.0f ) { - endtime = (int)(starttime - timeOffset + anim->Length() / rate); - } else { - endtime = -1; - } - } else { - - // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion - if ( rate == 1.0f ) { - endtime = starttime - timeOffset + anim->Length() * cycle; - } else if ( rate != 0.0f ) { - endtime = (int)(starttime - timeOffset + ( anim->Length() * cycle ) / rate); - } else { - endtime = -1; - } - } - } -} - -/* -===================== -idAnimBlend::SetPlaybackRate -===================== -*/ -void idAnimBlend::SetPlaybackRate( int currentTime, float newRate ) { - int animTime; - - if ( rate == newRate ) { - return; - } - - animTime = AnimTime( currentTime ); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("SetPlayBackRate (Anim %s): animTime = %d, newRate = %f \r", AnimFullName(), animTime, newRate ); - if ( newRate == 1.0f ) { - timeOffset = animTime - ( currentTime - starttime ); - } else - { - timeOffset = (int)(animTime - ( currentTime - starttime ) * newRate); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("SetPlayBackRate (Anim %s): currentTime = %d, starttime = %d, calc timeOffset = %d \r", AnimFullName(), currentTime, starttime, timeOffset ); - } - - rate = newRate; - - // update the anim endtime - SetCycleCount( cycle ); -} - -/* -===================== -idAnimBlend::GetPlaybackRate -===================== -*/ -float idAnimBlend::GetPlaybackRate( void ) const { - return rate; -} - -/* -===================== -idAnimBlend::SetStartTime -===================== -*/ -void idAnimBlend::SetStartTime( int _startTime ) { - starttime = _startTime; - - // update the anim endtime - SetCycleCount( cycle ); -} - -/* -===================== -idAnimBlend::GetStartTime -===================== -*/ -int idAnimBlend::GetStartTime( void ) const { - if ( !animNum ) { - return 0; - } - - return starttime; -} - -/* -===================== -idAnimBlend::GetEndTime -===================== -*/ -int idAnimBlend::GetEndTime( void ) const { - if ( !animNum ) { - return 0; - } - - return endtime; -} - -/* -===================== -idAnimBlend::PlayLength -===================== -*/ -int idAnimBlend::PlayLength( void ) const { - if ( !animNum ) { - return 0; - } - - if ( endtime < 0 ) { - return -1; - } - - return endtime - starttime + timeOffset; -} - -/* -===================== -idAnimBlend::AllowMovement -===================== -*/ -void idAnimBlend::AllowMovement( bool allow ) { - allowMove = allow; -} - -/* -===================== -idAnimBlend::AllowFrameCommands -===================== -*/ -void idAnimBlend::AllowFrameCommands( bool allow ) { - allowFrameCommands = allow; -} - -/* -===================== -idAnimBlend::Pause -===================== -*/ -void idAnimBlend::Pause( bool bPause ) -{ - // going from unpaused to paused - if( bPause && !m_bPaused ) - { - m_PausedEndtime = endtime; - m_PausedCycle = cycle; - m_PausedTime = gameLocal.time; - -/* Uncomment for debugging - gameLocal.Printf("Animation was paused, startime %d, endtime %d, cycle %d, time remaining: %d\r", - starttime, endtime, (int) cycle, (endtime - starttime) ); -*/ - - endtime = -1; - cycle = 1; - } - // going from paused to unpaused - else if( !bPause && m_bPaused ) - { - // how long were we paused for - int deltaT = gameLocal.time - m_PausedTime; - - // advance one frame in the animation from where we left off - // equivalent to setting the start time 1 frame back - deltaT = deltaT - FRAME2MS(1)/rate; - - starttime += deltaT; - if( m_PausedEndtime > 0 ) - endtime = m_PausedEndtime + deltaT; - cycle = m_PausedCycle; - -/* Uncomment for debugging - gameLocal.Printf("Animation was unpaused after time %d, startime %d, endtime %d, cycle %d, time remaining: %d\r", - deltaT, starttime, endtime, (int) cycle, (endtime - starttime) ); -*/ - } - - m_bPaused = bPause; -} - -/* -===================== -idAnimBlend::IsPaused -===================== -*/ -bool idAnimBlend::IsPaused( void ) -{ - return m_bPaused; -} - - -/* -===================== -idAnimBlend::Anim -===================== -*/ -const idAnim *idAnimBlend::Anim( void ) const { - if ( !modelDef ) { - return NULL; - } - - const idAnim *anim = modelDef->GetAnim( animNum ); - return anim; -} - -/* -===================== -idAnimBlend::AnimNum -===================== -*/ -int idAnimBlend::AnimNum( void ) const { - return animNum; -} - -/* -===================== -idAnimBlend::AnimTime -===================== -*/ -int idAnimBlend::AnimTime( int currentTime ) const -{ - int time; - int length; - const idAnim *anim = Anim(); - - if ( anim ) - { - if ( frame ) - { - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime (anim %s): Frame was already set to %d\r", AnimFullName(), frame ); - return FRAME2MS( frame - 1 ); - } - - // most of the time we're running at the original frame rate, so avoid the int-to-float-to-int conversion - if ( rate == 1.0f ) { - time = currentTime - starttime + timeOffset; - } else - { - time = static_cast( ( currentTime - starttime ) * rate ) + timeOffset; - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s has adjusted rate %f\r", AnimFullName(), rate ); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: currentTime: %d , starttime: %d, timeOffset: %d, calc. time: %d\r",currentTime, starttime, timeOffset ); - } - - // given enough time, we can easily wrap time around in our frame calculations, so - // keep cycling animations' time within the length of the anim. - length = anim->Length(); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s has length %d \r", AnimFullName(), length ); - if ( ( cycle < 0 ) && ( length > 0 ) ) { - time %= length; - - // time will wrap after 24 days (oh no!), resulting in negative results for the %. - // adding the length gives us the proper result. - if ( time < 0 ) { - time += length; - } - } - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("AnimTime: Anim %s, final time =%d \r", AnimFullName(), time ); - return time; - } else { - return 0; - } -} - -/* -===================== -idAnimBlend::GetFrameNumber -===================== -*/ -int idAnimBlend::GetFrameNumber( int currentTime ) const -{ - const idMD5Anim *md5anim; - frameBlend_t frameinfo; - int animTime; - - // ishtvan: uncomment for debugging - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("Anim %s called GetFrameNumber \r",AnimFullName() ); - - const idAnim *anim = Anim(); - if ( !anim ) - { - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: No anim found, returning 1\r" ); - return 1; - } - - if ( frame ) - { - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: Frame was set to %d, returning it\r", frame ); - return frame; - } - - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: Frame was not set, calculating it...\r" ); - md5anim = anim->MD5Anim( 0 ); - animTime = AnimTime( currentTime ); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: AnimTime returned %d ms\r", animTime ); - md5anim->ConvertTimeToFrame( animTime, cycle, frameinfo ); - // DM_LOG(LC_WEAPON,LT_DEBUG)LOGSTRING("GetFrameNumber: ConvertTimeToFrame returned frame %d\r", frameinfo.frame1 + 1 ); - - return frameinfo.frame1 + 1; -} - -/* -===================== -idAnimBlend::CallFrameCommands -===================== -*/ -void idAnimBlend::CallFrameCommands( idEntity *ent, int fromtime, int totime ) const { - const idMD5Anim *md5anim; - frameBlend_t frame1; - frameBlend_t frame2; - int fromFrameTime; - int toFrameTime; - - // ishtvan: don't play frame commands if paused - if - ( - !allowFrameCommands || !ent || - frame || ( ( endtime > 0 ) && ( fromtime > endtime ) - || m_bPaused ) - ) - return; - - const idAnim *anim = Anim(); - - if ( !anim || !anim->HasFrameCommands() ) - return; - - if ( totime <= starttime ) { - // don't play until next frame or we'll play commands twice. - // this happens on the player sometimes. - return; - } - - fromFrameTime = AnimTime( fromtime ); - toFrameTime = AnimTime( totime ); - if ( toFrameTime < fromFrameTime ) { - toFrameTime += anim->Length(); - } - - md5anim = anim->MD5Anim( 0 ); - md5anim->ConvertTimeToFrame( fromFrameTime, cycle, frame1 ); - md5anim->ConvertTimeToFrame( toFrameTime, cycle, frame2 ); - - if ( fromFrameTime <= 0 ) { - // make sure first frame is called - const_cast(anim)->CallFrameCommands( ent, -1, frame2.frame1, const_cast(this) ); - } else { - const_cast(anim)->CallFrameCommands( ent, frame1.frame1, frame2.frame1, const_cast(this) ); - } -} - -/* -===================== -idAnimBlend::BlendAnim -===================== -*/ -bool idAnimBlend::BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOriginOffset, bool overrideBlend, bool printInfo ) const { - int i; - float lerp; - float mixWeight; - const idMD5Anim *md5anim; - idJointQuat *ptr; - frameBlend_t frametime; - memset( &frametime, 0, sizeof(frameBlend_t) ); - idJointQuat *jointFrame; - idJointQuat *mixFrame; - int numAnims; - int time; - - const idAnim *anim = Anim(); - if ( !anim ) - return false; - - if( m_bPaused ) - currentTime = m_PausedTime; - - float weight = GetWeight( currentTime ); - if ( blendWeight > 0.0f ) - { - if ( ( endtime >= 0 ) && ( currentTime >= endtime ) ) - return false; - if ( !weight ) - return false; - if ( overrideBlend ) - blendWeight = 1.0f - weight; - } - - if ( ( channel == ANIMCHANNEL_ALL ) && !blendWeight ) - { - // we don't need a temporary buffer, so just store it directly in the blend frame - jointFrame = blendFrame; - } else - { - // allocate a temporary buffer to copy the joints from - jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); - } - - time = AnimTime( currentTime ); - - numAnims = anim->NumAnims(); - if ( numAnims == 1 ) - { - md5anim = anim->MD5Anim( 0 ); - if ( frame ) - { - md5anim->GetSingleFrame( frame - 1, jointFrame, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } else - { - md5anim->ConvertTimeToFrame( time, cycle, frametime ); - md5anim->GetInterpolatedFrame( frametime, jointFrame, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } - } else - { - // - // need to mix the multipoint anim together first - // - // allocate a temporary buffer to copy the joints to - mixFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); - - if ( !frame ) - anim->MD5Anim( 0 )->ConvertTimeToFrame( time, cycle, frametime ); - - ptr = jointFrame; - mixWeight = 0.0f; - for( i = 0; i < numAnims; i++ ) { - if ( animWeights[ i ] > 0.0f ) { - mixWeight += animWeights[ i ]; - lerp = animWeights[ i ] / mixWeight; - md5anim = anim->MD5Anim( i ); - if ( frame ) - { - md5anim->GetSingleFrame( frame - 1, ptr, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } else - { - md5anim->GetInterpolatedFrame( frametime, ptr, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } - - // only blend after the first anim is mixed in - if ( ptr != jointFrame ) { - SIMDProcessor->BlendJoints( jointFrame, ptr, lerp, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } - - ptr = mixFrame; - } - } - - if ( !mixWeight ) { - return false; - } - } - - if ( removeOriginOffset ) { - if ( allowMove ) { -#ifdef VELOCITY_MOVE - jointFrame[ 0 ].t.x = 0.0f; -#else - jointFrame[ 0 ].t.Zero(); -#endif - } - - if ( anim->GetAnimFlags().anim_turn ) { - jointFrame[ 0 ].q.Set( -0.70710677f, 0.0f, 0.0f, 0.70710677f ); - } - } - - if ( !blendWeight ) { - blendWeight = weight; - if ( channel != ANIMCHANNEL_ALL ) { - const int *index = modelDef->GetChannelJoints( channel ); - const int num = modelDef->NumJointsOnChannel( channel ); - for( i = 0; i < num; i++ ) { - int j = index[i]; - blendFrame[j].t = jointFrame[j].t; - blendFrame[j].q = jointFrame[j].q; - } - } - } else { - blendWeight += weight; - lerp = weight / blendWeight; - SIMDProcessor->BlendJoints( blendFrame, jointFrame, lerp, modelDef->GetChannelJoints( channel ), modelDef->NumJointsOnChannel( channel ) ); - } - - if ( printInfo ) { - if ( frame ) { - gameLocal.Printf( " %s: '%s', %d, %.2f%%\n", channelNames[ channel ], anim->FullName(), frame, weight * 100.0f ); - } else { - gameLocal.Printf( " %s: '%s', %.3f, %.2f%%\n", channelNames[ channel ], anim->FullName(), ( float )frametime.frame1 + frametime.backlerp, weight * 100.0f ); - } - } - - return true; -} - -/* -===================== -idAnimBlend::BlendOrigin -===================== -*/ -void idAnimBlend::BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const { - float lerp; - idVec3 animpos; - idVec3 pos; - int time; - int num; - int i; - - if ( frame || ( ( endtime > 0 ) && ( currentTime > endtime ) ) ) { - return; - } - - const idAnim *anim = Anim(); - if ( !anim ) { - return; - } - - if ( allowMove && removeOriginOffset ) { - return; - } - - float weight = GetWeight( currentTime ); - if ( !weight ) { - return; - } - - time = AnimTime( currentTime ); - - pos.Zero(); - num = anim->NumAnims(); - for( i = 0; i < num; i++ ) { - anim->GetOrigin( animpos, i, time, cycle ); - pos += animpos * animWeights[ i ]; - } - - if ( !blendWeight ) { - blendPos = pos; - blendWeight = weight; - } else { - lerp = weight / ( blendWeight + weight ); - blendPos += lerp * ( pos - blendPos ); - blendWeight += weight; - } -} - -/* -===================== -idAnimBlend::BlendDelta -===================== -*/ -void idAnimBlend::BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const { - idVec3 pos1; - idVec3 pos2; - idVec3 animpos; - idVec3 delta; - int time1; - int time2; - float lerp; - int num; - int i; - - if ( frame || !allowMove || ( ( endtime > 0 ) && ( fromtime > endtime ) ) ) { - return; - } - - const idAnim *anim = Anim(); - if ( !anim ) { - return; - } - - float weight = GetWeight( totime ); - if ( !weight ) { - return; - } - - time1 = AnimTime( fromtime ); - time2 = AnimTime( totime ); - if ( time2 < time1 ) { - time2 += anim->Length(); - } - - num = anim->NumAnims(); - - pos1.Zero(); - pos2.Zero(); - for( i = 0; i < num; i++ ) { - anim->GetOrigin( animpos, i, time1, cycle ); - pos1 += animpos * animWeights[ i ]; - - anim->GetOrigin( animpos, i, time2, cycle ); - pos2 += animpos * animWeights[ i ]; - } - - delta = pos2 - pos1; - if ( !blendWeight ) { - blendDelta = delta; - blendWeight = weight; - } else { - lerp = weight / ( blendWeight + weight ); - blendDelta += lerp * ( delta - blendDelta ); - blendWeight += weight; - } -} - -/* -===================== -idAnimBlend::BlendDeltaRotation -===================== -*/ -void idAnimBlend::BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const { - idQuat q1; - idQuat q2; - idQuat q3; - int time1; - int time2; - float lerp; - float mixWeight; - int num; - int i; - - if ( frame || !allowMove || ( ( endtime > 0 ) && ( fromtime > endtime ) ) ) { - return; - } - - const idAnim *anim = Anim(); - if ( !anim || !anim->GetAnimFlags().anim_turn ) { - return; - } - - float weight = GetWeight( totime ); - if ( !weight ) { - return; - } - - time1 = AnimTime( fromtime ); - time2 = AnimTime( totime ); - if ( time2 < time1 ) { - time2 += anim->Length(); - } - - q1.Set( 0.0f, 0.0f, 0.0f, 1.0f ); - q2.Set( 0.0f, 0.0f, 0.0f, 1.0f ); - - mixWeight = 0.0f; - num = anim->NumAnims(); - for( i = 0; i < num; i++ ) { - if ( animWeights[ i ] > 0.0f ) { - mixWeight += animWeights[ i ]; - if ( animWeights[ i ] == mixWeight ) { - anim->GetOriginRotation( q1, i, time1, cycle ); - anim->GetOriginRotation( q2, i, time2, cycle ); - } else { - lerp = animWeights[ i ] / mixWeight; - anim->GetOriginRotation( q3, i, time1, cycle ); - q1.Slerp( q1, q3, lerp ); - - anim->GetOriginRotation( q3, i, time2, cycle ); - q2.Slerp( q1, q3, lerp ); - } - } - } - - q3 = q1.Inverse() * q2; - if ( !blendWeight ) { - blendDelta = q3; - blendWeight = weight; - } else { - lerp = weight / ( blendWeight + weight ); - blendDelta.Slerp( blendDelta, q3, lerp ); - blendWeight += weight; - } -} - -/* -===================== -idAnimBlend::AddBounds -===================== -*/ -bool idAnimBlend::AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const { - int i; - int num; - idBounds b; - int time; - idVec3 pos; - bool addorigin; - - if ( ( endtime > 0 ) && ( currentTime > endtime ) ) { - return false; - } - - const idAnim *anim = Anim(); - if ( !anim ) { - return false; - } - - float weight = GetWeight( currentTime ); - if ( !weight ) { - return false; - } - - time = AnimTime( currentTime ); - num = anim->NumAnims(); - - addorigin = !allowMove || !removeOriginOffset; - for( i = 0; i < num; i++ ) { - if ( anim->GetBounds( b, i, time, cycle ) ) { - if ( addorigin ) { - anim->GetOrigin( pos, i, time, cycle ); - b.TranslateSelf( pos ); - } - bounds.AddBounds( b ); - } - } - - return true; -} - -/*********************************************************************** - - idDeclModelDef - -***********************************************************************/ - -/* -===================== -idDeclModelDef::idDeclModelDef -===================== -*/ -idDeclModelDef::idDeclModelDef() { - modelHandle = NULL; - skin = NULL; - offset.Zero(); - for ( int i = 0; i < ANIM_NumAnimChannels; i++ ) { - channelJoints[i].Clear(); - } -} - -/* -===================== -idDeclModelDef::~idDeclModelDef -===================== -*/ -idDeclModelDef::~idDeclModelDef() { - FreeData(); -} - -/* -================= -idDeclModelDef::Size -================= -*/ -size_t idDeclModelDef::Size( void ) const { - return sizeof( idDeclModelDef ); -} - -/* -===================== -idDeclModelDef::CopyDecl -===================== -*/ -void idDeclModelDef::CopyDecl( const idDeclModelDef *decl ) { - int i; - - FreeData(); - - offset = decl->offset; - modelHandle = decl->modelHandle; - skin = decl->skin; - - anims.SetNum( decl->anims.Num() ); - for( i = 0; i < anims.Num(); i++ ) { - anims[ i ] = new idAnim( this, decl->anims[ i ] ); - } - - joints.SetNum( decl->joints.Num() ); - memcpy( joints.Ptr(), decl->joints.Ptr(), decl->joints.Num() * sizeof( joints[0] ) ); - jointParents.SetNum( decl->jointParents.Num() ); - memcpy( jointParents.Ptr(), decl->jointParents.Ptr(), decl->jointParents.Num() * sizeof( jointParents[0] ) ); - for ( i = 0; i < ANIM_NumAnimChannels; i++ ) { - channelJoints[i] = decl->channelJoints[i]; - } -} - -/* -===================== -idDeclModelDef::FreeData -===================== -*/ -void idDeclModelDef::FreeData( void ) { - anims.DeleteContents( true ); - joints.Clear(); - jointParents.Clear(); - modelHandle = NULL; - skin = NULL; - offset.Zero(); - for ( int i = 0; i < ANIM_NumAnimChannels; i++ ) { - channelJoints[i].Clear(); - } -} - -/* -================ -idDeclModelDef::DefaultDefinition -================ -*/ -const char *idDeclModelDef::DefaultDefinition( void ) const { - return "{ }"; -} - -/* -==================== -idDeclModelDef::FindJoint -==================== -*/ -const jointInfo_t *idDeclModelDef::FindJoint( const char *name ) const { - int i; - const idMD5Joint *joint; - - if ( !modelHandle ) { - return NULL; - } - - joint = modelHandle->GetJoints(); - for( i = 0; i < joints.Num(); i++, joint++ ) { - if ( !joint->name.Icmp( name ) ) { - return &joints[ i ]; - } - } - - return NULL; -} - -/* -===================== -idDeclModelDef::ModelHandle -===================== -*/ -idRenderModel *idDeclModelDef::ModelHandle( void ) const { - return ( idRenderModel * )modelHandle; -} - -/* -===================== -idDeclModelDef::GetJointList -===================== -*/ -void idDeclModelDef::GetJointList( const char *jointnames, idList &jointList ) const { - const char *pos; - idStr jointname; - const jointInfo_t *joint; - const jointInfo_t *child; - int i; - int num; - bool getChildren; - bool subtract; - - if ( !modelHandle ) { - return; - } - - jointList.Clear(); - - num = modelHandle->NumJoints(); - - // scan through list of joints and add each to the joint list - pos = jointnames; - while( *pos ) { - // skip over whitespace - while( ( *pos != 0 ) && isspace( *pos ) ) { - pos++; - } - - if ( !*pos ) { - // no more names - break; - } - - // copy joint name - jointname = ""; - - if ( *pos == '-' ) { - subtract = true; - pos++; - } else { - subtract = false; - } - - if ( *pos == '*' ) { - getChildren = true; - pos++; - } else { - getChildren = false; - } - - while( ( *pos != 0 ) && !isspace( *pos ) ) { - jointname += *pos; - pos++; - } - - joint = FindJoint( jointname ); - if ( !joint ) { - gameLocal.Warning( "Unknown joint '%s' in '%s' for model '%s'", jointname.c_str(), jointnames, GetName() ); - continue; - } - - if ( !subtract ) { - jointList.AddUnique( joint->num ); - } else { - jointList.Remove( joint->num ); - } - - if ( getChildren ) { - // include all joint's children - child = joint + 1; - for( i = joint->num + 1; i < num; i++, child++ ) { - // all children of the joint should follow it in the list. - // once we reach a joint without a parent or with a parent - // who is earlier in the list than the specified joint, then - // we've gone through all it's children. - if ( child->parentNum < joint->num ) { - break; - } - - if ( !subtract ) { - jointList.AddUnique( child->num ); - } else { - jointList.Remove( child->num ); - } - } - } - } -} - -/* -===================== -idDeclModelDef::Touch -===================== -*/ -void idDeclModelDef::Touch( void ) const { - if ( modelHandle ) { - renderModelManager->FindModel( modelHandle->Name() ); - } -} - -/* -===================== -idDeclModelDef::GetDefaultSkin -===================== -*/ -const idDeclSkin *idDeclModelDef::GetDefaultSkin( void ) const { - return skin; -} - -/* -===================== -idDeclModelDef::GetDefaultPose -===================== -*/ -const idJointQuat *idDeclModelDef::GetDefaultPose( void ) const { - return modelHandle->GetDefaultPose(); -} - -/* -===================== -idDeclModelDef::SetupJoints -===================== -*/ -void idDeclModelDef::SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const { - int num; - const idJointQuat *pose; - idJointMat *list; - - if ( !modelHandle || modelHandle->IsDefaultModel() ) { - Mem_Free16( (*jointList) ); - (*jointList) = NULL; - frameBounds.Clear(); - return; - } - - // get the number of joints - num = modelHandle->NumJoints(); - - if ( !num ) { - gameLocal.Error( "model '%s' has no joints", modelHandle->Name() ); - } - - // set up initial pose for model (with no pose, model is just a jumbled mess) - list = (idJointMat *) Mem_Alloc16( num * sizeof( list[0] ) ); - pose = GetDefaultPose(); - - // convert the joint quaternions to joint matrices - SIMDProcessor->ConvertJointQuatsToJointMats( list, pose, joints.Num() ); - - // check if we offset the model by the origin joint - if ( removeOriginOffset ) { -#ifdef VELOCITY_MOVE - list[ 0 ].SetTranslation( idVec3( offset.x, offset.y + pose[0].t.y, offset.z + pose[0].t.z ) ); -#else - list[ 0 ].SetTranslation( offset ); -#endif - } else { - list[ 0 ].SetTranslation( pose[0].t + offset ); - } - - // transform the joint hierarchy - SIMDProcessor->TransformJoints( list, jointParents.Ptr(), 1, joints.Num() - 1 ); - - *numJoints = num; - *jointList = list; - - // get the bounds of the default pose - frameBounds = modelHandle->Bounds( NULL ); -} - -/* -===================== -idDeclModelDef::ParseAnim -===================== -*/ -bool idDeclModelDef::ParseAnim( idLexer &src, int numDefaultAnims ) { - int i; - int len; - idAnim *anim; - const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ]; - const idMD5Anim *md5anim; - idStr alias; - idToken realname; - idToken token; - int numAnims; - animFlags_t flags; - - numAnims = 0; - memset( md5anims, 0, sizeof( md5anims ) ); - - if( !src.ReadToken( &realname ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - alias = realname; - - for( i = 0; i < anims.Num(); i++ ) { - if ( !strcmp( anims[ i ]->FullName(), realname.c_str() ) ) { - break; - } - } - - if ( ( i < anims.Num() ) && ( i >= numDefaultAnims ) ) { - src.Warning( "Duplicate anim '%s'", realname.c_str() ); - MakeDefault(); - return false; - } - - if ( i < numDefaultAnims ) { - anim = anims[ i ]; - } else { - // create the alias associated with this animation - anim = new idAnim(); - anims.Append( anim ); - } - - // random anims end with a number. find the numeric suffix of the animation. - len = alias.Length(); - for( i = len - 1; i > 0; i-- ) { - if ( !isdigit( alias[ i ] ) ) { - break; - } - } - - // check for zero length name, or a purely numeric name - if ( i <= 0 ) { - src.Warning( "Invalid animation name '%s'", alias.c_str() ); - MakeDefault(); - return false; - } - - // remove the numeric suffix - alias.CapLength( i + 1 ); - - // parse the anims from the string - do { - if( !src.ReadToken( &token ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - - // lookup the animation - md5anim = animationLib.GetAnim( token ); - if ( !md5anim ) { - src.Warning( "Couldn't load anim '%s'", token.c_str() ); - MakeDefault(); - return false; - } - - md5anim->CheckModelHierarchy( modelHandle ); - - if ( numAnims > 0 ) { - // make sure it's the same length as the other anims - if ( md5anim->Length() != md5anims[ 0 ]->Length() ) { - src.Warning( "Anim '%s' does not match length of anim '%s'", md5anim->Name(), md5anims[ 0 ]->Name() ); - MakeDefault(); - return false; - } - } - - if ( numAnims >= ANIM_MaxSyncedAnims ) { - src.Warning( "Exceeded max synced anims (%d)", ANIM_MaxSyncedAnims ); - MakeDefault(); - return false; - } - - // add it to our list - md5anims[ numAnims ] = md5anim; - numAnims++; - } while ( src.CheckTokenString( "," ) ); - - if ( !numAnims ) { - src.Warning( "No animation specified" ); - MakeDefault(); - return false; - } - - anim->SetAnim( this, realname, alias, numAnims, md5anims ); - memset( &flags, 0, sizeof( flags ) ); - - // parse any frame commands or animflags - if ( src.CheckTokenString( "{" ) ) { - while( 1 ) { - if( !src.ReadToken( &token ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - if ( token == "}" ) { - break; - }else if ( token == "prevent_idle_override" ) { - flags.prevent_idle_override = true; - } else if ( token == "random_cycle_start" ) { - flags.random_cycle_start = true; - } else if ( token == "ai_no_turn" ) { - flags.ai_no_turn = true; - } else if ( token == "anim_turn" ) { - flags.anim_turn = true; - } else if ( token == "no_random_headturning" ) { - flags.no_random_headturning = true; - } else if ( token == "frame" ) { - // create a frame command - int framenum; - const char *err; - - // make sure we don't have any line breaks while reading the frame command so the error line # will be correct - if ( !src.ReadTokenOnLine( &token ) ) { - src.Warning( "Missing frame # after 'frame'" ); - MakeDefault(); - return false; - } - if ( token.type == TT_PUNCTUATION && token == "-" ) { - src.Warning( "Invalid frame # after 'frame'" ); - MakeDefault(); - return false; - } else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { - src.Error( "expected integer value, found '%s'", token.c_str() ); - } - - // get the frame number - framenum = token.GetIntValue(); - - // put the command on the specified frame of the animation - err = anim->AddFrameCommand( this, framenum, src, NULL ); - if ( err ) { - src.Warning( "%s", err ); - MakeDefault(); - return false; - } - } else { - src.Warning( "Unknown command '%s'", token.c_str() ); - MakeDefault(); - return false; - } - } - } - - // set the flags - anim->SetAnimFlags( flags ); - return true; -} - -/* -================ -idDeclModelDef::Parse -================ -*/ -bool idDeclModelDef::Parse( const char *text, const int textLength ) { - int i; - int num; - idStr filename; - idStr extension; - const idMD5Joint *md5joint; - const idMD5Joint *md5joints; - idLexer src; - idToken token; - idToken token2; - idStr jointnames; - int channel; - jointHandle_t jointnum; - idList jointList; - int numDefaultAnims; - - src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); - src.SetFlags( DECL_LEXER_FLAGS ); - src.SkipUntilString( "{" ); - - numDefaultAnims = 0; - while( 1 ) { - if ( !src.ReadToken( &token ) ) { - break; - } - - if ( !token.Icmp( "}" ) ) { - break; - } - - if ( token == "inherit" ) { - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - - const idDeclModelDef *copy = static_cast( declManager->FindType( DECL_MODELDEF, token2, false ) ); - if ( !copy ) { - common->Warning( "Unknown model definition '%s'", token2.c_str() ); - } else if ( copy->GetState() == DS_DEFAULTED ) { - common->Warning( "inherited model definition '%s' defaulted", token2.c_str() ); - MakeDefault(); - return false; - } else { - CopyDecl( copy ); - numDefaultAnims = anims.Num(); - } - } else if ( token == "skin" ) { - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - skin = declManager->FindSkin( token2 ); - if ( !skin ) { - src.Warning( "Skin '%s' not found", token2.c_str() ); - MakeDefault(); - return false; - } - } else if ( token == "mesh" ) { - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - filename = token2; - filename.ExtractFileExtension( extension ); - if ( extension != MD5_MESH_EXT ) { - src.Warning( "Invalid model for MD5 mesh" ); - MakeDefault(); - return false; - } - modelHandle = renderModelManager->FindModel( filename ); - if ( !modelHandle ) { - src.Warning( "Model '%s' not found", filename.c_str() ); - MakeDefault(); - return false; - } - - if ( modelHandle->IsDefaultModel() ) { - src.Warning( "Model '%s' defaulted", filename.c_str() ); - MakeDefault(); - return false; - } - - // get the number of joints - num = modelHandle->NumJoints(); - if ( !num ) { - src.Warning( "Model '%s' has no joints", filename.c_str() ); - } - - // set up the joint hierarchy - joints.SetGranularity( 1 ); - joints.SetNum( num ); - jointParents.SetNum( num ); - channelJoints[0].SetNum( num ); - md5joints = modelHandle->GetJoints(); - md5joint = md5joints; - for( i = 0; i < num; i++, md5joint++ ) { - joints[i].channel = ANIMCHANNEL_ALL; - joints[i].num = static_cast( i ); - if ( md5joint->parent ) { - joints[i].parentNum = static_cast( md5joint->parent - md5joints ); - } else { - joints[i].parentNum = INVALID_JOINT; - } - jointParents[i] = joints[i].parentNum; - channelJoints[0][i] = i; - } - } else if ( token == "remove" ) { - // removes any anims whos name matches - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - num = 0; - for( i = 0; i < anims.Num(); i++ ) { - if ( ( token2 == anims[ i ]->Name() ) || ( token2 == anims[ i ]->FullName() ) ) { - delete anims[ i ]; - anims.RemoveIndex( i ); - if ( i >= numDefaultAnims ) { - src.Warning( "Anim '%s' was not inherited. Anim should be removed from the model def.", token2.c_str() ); - MakeDefault(); - return false; - } - i--; - numDefaultAnims--; - num++; - continue; - } - } - if ( !num ) { - src.Warning( "Couldn't find anim '%s' to remove", token2.c_str() ); - MakeDefault(); - return false; - } - } else if ( token == "anim" ) { - if ( !modelHandle ) { - src.Warning( "Must specify mesh before defining anims" ); - MakeDefault(); - return false; - } - if ( !ParseAnim( src, numDefaultAnims ) ) { - MakeDefault(); - return false; - } - } else if ( token == "offset" ) { - if ( !src.Parse1DMatrix( 3, offset.ToFloatPtr() ) ) { - src.Warning( "Expected vector following 'offset'" ); - MakeDefault(); - return false; - } - } else if ( token == "channel" ) { - if ( !modelHandle ) { - src.Warning( "Must specify mesh before defining channels" ); - MakeDefault(); - return false; - } - - // set the channel for a group of joints - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - if ( !src.CheckTokenString( "(" ) ) { - src.Warning( "Expected { after '%s'\n", token2.c_str() ); - MakeDefault(); - return false; - } - - for( i = ANIMCHANNEL_ALL + 1; i < ANIM_NumAnimChannels; i++ ) { -#if MACOS_X || __linux__ - if ( !strcasecmp( channelNames[ i ], token2.c_str() ) ) -#else - if ( !stricmp( channelNames[ i ], token2.c_str() ) ) -#endif - { - break; - } - } - - if ( i >= ANIM_NumAnimChannels ) { - src.Warning( "Unknown channel '%s'", token2.c_str() ); - MakeDefault(); - return false; - } - - channel = i; - jointnames = ""; - - while( !src.CheckTokenString( ")" ) ) { - if( !src.ReadToken( &token2 ) ) { - src.Warning( "Unexpected end of file" ); - MakeDefault(); - return false; - } - jointnames += token2; - if ( ( token2 != "*" ) && ( token2 != "-" ) ) { - jointnames += " "; - } - } - - GetJointList( jointnames, jointList ); - - channelJoints[ channel ].SetNum( jointList.Num() ); - for( num = i = 0; i < jointList.Num(); i++ ) { - jointnum = jointList[ i ]; - if ( joints[ jointnum ].channel != ANIMCHANNEL_ALL ) { - src.Warning( "Joint '%s' assigned to multiple channels", modelHandle->GetJointName( jointnum ) ); - continue; - } - joints[ jointnum ].channel = channel; - channelJoints[ channel ][ num++ ] = jointnum; - } - channelJoints[ channel ].SetNum( num ); - } else { - src.Warning( "unknown token '%s' on line %i in '%s'", token.c_str(), token.line, src.GetFileName() ); - MakeDefault(); - return false; - } - } - - // shrink the anim list down to save space - anims.SetGranularity( 1 ); - anims.SetNum( anims.Num() ); - - return true; -} - -/* -===================== -idDeclModelDef::HasAnim -===================== -*/ -bool idDeclModelDef::HasAnim( const char *name ) const { - int i; - - // find any animations with same name - for( i = 0; i < anims.Num(); i++ ) { - if ( !strcmp( anims[ i ]->Name(), name ) ) { - return true; - } - } - - return false; -} - -/* -===================== -idDeclModelDef::NumAnims -===================== -*/ -int idDeclModelDef::NumAnims( void ) const { - return anims.Num() + 1; -} - -/* -===================== -idDeclModelDef::GetSpecificAnim - -Gets the exact anim for the name, without randomization. -===================== -*/ -int idDeclModelDef::GetSpecificAnim( const char *name ) const { - int i; - - // find a specific animation - for( i = 0; i < anims.Num(); i++ ) { - if ( !strcmp( anims[ i ]->FullName(), name ) ) { - return i + 1; - } - } - - // didn't find it - return 0; -} - -/* -===================== -idDeclModelDef::GetAnim -===================== -*/ -const idAnim *idDeclModelDef::GetAnim( int index ) const { - if ( ( index < 1 ) || ( index > anims.Num() ) ) { - return NULL; - } - - return anims[ index - 1 ]; -} - -/* -===================== -idDeclModelDef::GetAnim -===================== -*/ -int idDeclModelDef::GetAnim( const char *name ) const { - int i; - int which; - const int MAX_ANIMS = 64; - int animList[ MAX_ANIMS ]; - int numAnims; - int len; - - len = strlen( name ); - if ( len && idStr::CharIsNumeric( name[ len - 1 ] ) ) { - // find a specific animation - return GetSpecificAnim( name ); - } - - // find all animations with same name - numAnims = 0; - for( i = 0; i < anims.Num(); i++ ) { - if ( !strcmp( anims[ i ]->Name(), name ) ) { - animList[ numAnims++ ] = i; - if ( numAnims >= MAX_ANIMS ) { - break; - } - } - } - - if ( !numAnims ) { - return 0; - } - - // get a random anim - //FIXME: don't access gameLocal here? - which = gameLocal.random.RandomInt( numAnims ); - return animList[ which ] + 1; -} - -/* -===================== -idDeclModelDef::GetSkin -===================== -*/ -const idDeclSkin *idDeclModelDef::GetSkin( void ) const { - return skin; -} - -/* -===================== -idDeclModelDef::GetModelName -===================== -*/ -const char *idDeclModelDef::GetModelName( void ) const { - if ( modelHandle ) { - return modelHandle->Name(); - } else { - return ""; - } -} - -/* -===================== -idDeclModelDef::Joints -===================== -*/ -const idList &idDeclModelDef::Joints( void ) const { - return joints; -} - -/* -===================== -idDeclModelDef::JointParents -===================== -*/ -const int * idDeclModelDef::JointParents( void ) const { - return jointParents.Ptr(); -} - -/* -===================== -idDeclModelDef::NumJoints -===================== -*/ -int idDeclModelDef::NumJoints( void ) const { - return joints.Num(); -} - -/* -===================== -idDeclModelDef::GetJoint -===================== -*/ -const jointInfo_t *idDeclModelDef::GetJoint( int jointHandle ) const { - if ( ( jointHandle < 0 ) || ( jointHandle > joints.Num() ) ) { - gameLocal.Error( "idDeclModelDef::GetJoint : joint handle out of range" ); - } - return &joints[ jointHandle ]; -} - -/* -==================== -idDeclModelDef::GetJointName -==================== -*/ -const char *idDeclModelDef::GetJointName( int jointHandle ) const { - const idMD5Joint *joint; - - if ( !modelHandle ) { - return NULL; - } - - if ( ( jointHandle < 0 ) || ( jointHandle > joints.Num() ) ) { - gameLocal.Error( "idDeclModelDef::GetJointName : joint handle out of range" ); - } - - joint = modelHandle->GetJoints(); - return joint[ jointHandle ].name.c_str(); -} - -/* -===================== -idDeclModelDef::NumJointsOnChannel -===================== -*/ -int idDeclModelDef::NumJointsOnChannel( int channel ) const { - if ( ( channel < 0 ) || ( channel >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idDeclModelDef::NumJointsOnChannel : channel out of range" ); - } - return channelJoints[ channel ].Num(); -} - -/* -===================== -idDeclModelDef::GetChannelJoints -===================== -*/ -const int * idDeclModelDef::GetChannelJoints( int channel ) const { - if ( ( channel < 0 ) || ( channel >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idDeclModelDef::GetChannelJoints : channel out of range" ); - } - return channelJoints[ channel ].Ptr(); -} - -/* -===================== -idDeclModelDef::GetVisualOffset -===================== -*/ -const idVec3 &idDeclModelDef::GetVisualOffset( void ) const { - return offset; -} - -/*********************************************************************** - - idAnimator - -***********************************************************************/ - -/* -===================== -idAnimator::idAnimator -===================== -*/ -idAnimator::idAnimator() { - int i, j; - - modelDef = NULL; - entity = NULL; - numJoints = 0; - joints = NULL; - lastTransformTime = -1; - stoppedAnimatingUpdate = false; - removeOriginOffset = false; - forceUpdate = false; - - frameBounds.Clear(); - - AFPoseJoints.SetGranularity( 1 ); - AFPoseJointMods.SetGranularity( 1 ); - AFPoseJointFrame.SetGranularity( 1 ); - - ClearAFPose(); - - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { - channels[ i ][ j ].Reset( NULL ); - } - } -} - -/* -===================== -idAnimator::~idAnimator -===================== -*/ -idAnimator::~idAnimator() { - FreeData(); -} - -/* -===================== -idAnimator::Allocated -===================== -*/ -size_t idAnimator::Allocated( void ) const { - size_t size; - - size = jointMods.Allocated() + numJoints * sizeof( joints[0] ) + jointMods.Num() * sizeof( jointMods[ 0 ] ) + AFPoseJointMods.Allocated() + AFPoseJointFrame.Allocated() + AFPoseJoints.Allocated(); - - return size; -} - -/* -===================== -idAnimator::Save - -archives object for save game file -===================== -*/ -void idAnimator::Save( idSaveGame *savefile ) const { - int i; - int j; - - savefile->WriteModelDef( modelDef ); - savefile->WriteObject( entity ); - - savefile->WriteInt( jointMods.Num() ); - for( i = 0; i < jointMods.Num(); i++ ) { - savefile->WriteInt( jointMods[ i ]->jointnum ); - savefile->WriteMat3( jointMods[ i ]->mat ); - savefile->WriteVec3( jointMods[ i ]->pos ); - savefile->WriteInt( (int&)jointMods[ i ]->transform_pos ); - savefile->WriteInt( (int&)jointMods[ i ]->transform_axis ); - } - - savefile->WriteInt( numJoints ); - for ( i = 0; i < numJoints; i++ ) { - float *data = joints[i].ToFloatPtr(); - for ( j = 0; j < 12; j++ ) { - savefile->WriteFloat( data[j] ); - } - } - - savefile->WriteInt( lastTransformTime ); - savefile->WriteBool( stoppedAnimatingUpdate ); - savefile->WriteBool( forceUpdate ); - savefile->WriteBounds( frameBounds ); - - savefile->WriteFloat( AFPoseBlendWeight ); - - savefile->WriteInt( AFPoseJoints.Num() ); - for ( i = 0; i < AFPoseJoints.Num(); i++ ) { - savefile->WriteInt( AFPoseJoints[i] ); - } - - savefile->WriteInt( AFPoseJointMods.Num() ); - for ( i = 0; i < AFPoseJointMods.Num(); i++ ) { - savefile->WriteInt( (int&)AFPoseJointMods[i].mod ); - savefile->WriteMat3( AFPoseJointMods[i].axis ); - savefile->WriteVec3( AFPoseJointMods[i].origin ); - } - - savefile->WriteInt( AFPoseJointFrame.Num() ); - for ( i = 0; i < AFPoseJointFrame.Num(); i++ ) { - savefile->WriteFloat( AFPoseJointFrame[i].q.x ); - savefile->WriteFloat( AFPoseJointFrame[i].q.y ); - savefile->WriteFloat( AFPoseJointFrame[i].q.z ); - savefile->WriteFloat( AFPoseJointFrame[i].q.w ); - savefile->WriteVec3( AFPoseJointFrame[i].t ); - } - - savefile->WriteBounds( AFPoseBounds ); - savefile->WriteInt( AFPoseTime ); - - savefile->WriteBool( removeOriginOffset ); - - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { - channels[ i ][ j ].Save( savefile ); - } - } -} - -/* -===================== -idAnimator::Restore - -unarchives object from save game file -===================== -*/ -void idAnimator::Restore( idRestoreGame *savefile ) { - int i; - int j; - int num; - - savefile->ReadModelDef( modelDef ); - savefile->ReadObject( reinterpret_cast( entity ) ); - - savefile->ReadInt( num ); - jointMods.SetNum( num ); - for( i = 0; i < num; i++ ) { - jointMods[ i ] = new jointMod_t; - savefile->ReadInt( (int&)jointMods[ i ]->jointnum ); - savefile->ReadMat3( jointMods[ i ]->mat ); - savefile->ReadVec3( jointMods[ i ]->pos ); - savefile->ReadInt( (int&)jointMods[ i ]->transform_pos ); - savefile->ReadInt( (int&)jointMods[ i ]->transform_axis ); - } - - savefile->ReadInt( numJoints ); - joints = (idJointMat *) Mem_Alloc16( numJoints * sizeof( joints[0] ) ); - for ( i = 0; i < numJoints; i++ ) { - float *data = joints[i].ToFloatPtr(); - for ( j = 0; j < 12; j++ ) { - savefile->ReadFloat( data[j] ); - } - } - - savefile->ReadInt( lastTransformTime ); - savefile->ReadBool( stoppedAnimatingUpdate ); - savefile->ReadBool( forceUpdate ); - savefile->ReadBounds( frameBounds ); - - savefile->ReadFloat( AFPoseBlendWeight ); - - savefile->ReadInt( num ); - AFPoseJoints.SetGranularity( 1 ); - AFPoseJoints.SetNum( num ); - for ( i = 0; i < AFPoseJoints.Num(); i++ ) { - savefile->ReadInt( AFPoseJoints[i] ); - } - - savefile->ReadInt( num ); - AFPoseJointMods.SetGranularity( 1 ); - AFPoseJointMods.SetNum( num ); - for ( i = 0; i < AFPoseJointMods.Num(); i++ ) { - savefile->ReadInt( (int&)AFPoseJointMods[i].mod ); - savefile->ReadMat3( AFPoseJointMods[i].axis ); - savefile->ReadVec3( AFPoseJointMods[i].origin ); - } - - savefile->ReadInt( num ); - AFPoseJointFrame.SetGranularity( 1 ); - AFPoseJointFrame.SetNum( num ); - for ( i = 0; i < AFPoseJointFrame.Num(); i++ ) { - savefile->ReadFloat( AFPoseJointFrame[i].q.x ); - savefile->ReadFloat( AFPoseJointFrame[i].q.y ); - savefile->ReadFloat( AFPoseJointFrame[i].q.z ); - savefile->ReadFloat( AFPoseJointFrame[i].q.w ); - savefile->ReadVec3( AFPoseJointFrame[i].t ); - } - - savefile->ReadBounds( AFPoseBounds ); - savefile->ReadInt( AFPoseTime ); - - savefile->ReadBool( removeOriginOffset ); - - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { - channels[ i ][ j ].Restore( savefile, modelDef ); - } - } -} - -/* -===================== -idAnimator::FreeData -===================== -*/ -void idAnimator::FreeData( void ) { - int i, j; - - if ( entity ) { - entity->BecomeInactive( TH_ANIMATE ); - } - - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { - channels[ i ][ j ].Reset( NULL ); - } - } - - jointMods.DeleteContents( true ); - - Mem_Free16( joints ); - joints = NULL; - numJoints = 0; - - modelDef = NULL; - - ForceUpdate(); -} - -/* -===================== -idAnimator::PushAnims -===================== -*/ -void idAnimator::PushAnims( int channelNum, int currentTime, int blendTime ) { - int i; - idAnimBlend *channel; - - channel = channels[ channelNum ]; - if ( !channel[ 0 ].GetWeight( currentTime ) || ( channel[ 0 ].starttime == currentTime ) ) { - return; - } - - for( i = ANIM_MaxAnimsPerChannel - 1; i > 0; i-- ) { - channel[ i ] = channel[ i - 1 ]; - } - - channel[ 0 ].Reset( modelDef ); - channel[ 1 ].Clear( currentTime, blendTime ); - ForceUpdate(); -} - -/* -===================== -idAnimator::SetModel -===================== -*/ -idRenderModel *idAnimator::SetModel( const char *modelname ) { - int i, j; - - FreeData(); - - // check if we're just clearing the model - if ( !modelname || !*modelname ) { - return NULL; - } - - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); - if ( !modelDef ) { - return NULL; - } - - idRenderModel *renderModel = modelDef->ModelHandle(); - if ( !renderModel ) { - modelDef = NULL; - return NULL; - } - - // make sure model hasn't been purged - modelDef->Touch(); - - modelDef->SetupJoints( &numJoints, &joints, frameBounds, removeOriginOffset ); - modelDef->ModelHandle()->Reset(); - - // set the modelDef on all channels - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++ ) { - channels[ i ][ j ].Reset( modelDef ); - } - } - - return modelDef->ModelHandle(); -} - -/* -===================== -idAnimator::Size -===================== -*/ -size_t idAnimator::Size( void ) const { - return sizeof( *this ) + Allocated(); -} - -/* -===================== -idAnimator::SetEntity -===================== -*/ -void idAnimator::SetEntity( idEntity *ent ) { - entity = ent; -} - -/* -===================== -idAnimator::GetEntity -===================== -*/ -idEntity *idAnimator::GetEntity( void ) const { - return entity; -} - -/* -===================== -idAnimator::RemoveOriginOffset -===================== -*/ -void idAnimator::RemoveOriginOffset( bool remove ) { - removeOriginOffset = remove; -} - -/* -===================== -idAnimator::RemoveOrigin -===================== -*/ -bool idAnimator::RemoveOrigin( void ) const { - return removeOriginOffset; -} - -/* -===================== -idAnimator::GetJointList -===================== -*/ -void idAnimator::GetJointList( const char *jointnames, idList &jointList ) const { - if ( modelDef ) { - modelDef->GetJointList( jointnames, jointList ); - } -} - -/* -===================== -idAnimator::NumAnims -===================== -*/ -int idAnimator::NumAnims( void ) const { - if ( !modelDef ) { - return 0; - } - - return modelDef->NumAnims(); -} - -/* -===================== -idAnimator::GetAnim -===================== -*/ -const idAnim *idAnimator::GetAnim( int index ) const { - if ( !modelDef ) { - return NULL; - } - - return modelDef->GetAnim( index ); -} - -/* -===================== -idAnimator::GetAnim -===================== -*/ -int idAnimator::GetAnim( const char *name ) const { - if ( !modelDef ) { - return 0; - } - - return modelDef->GetAnim( name ); -} - -/* -===================== -idAnimator::HasAnim -===================== -*/ -bool idAnimator::HasAnim( const char *name ) const { - if ( !modelDef ) { - return false; - } - - return modelDef->HasAnim( name ); -} - -/* -===================== -idAnimator::NumJoints -===================== -*/ -int idAnimator::NumJoints( void ) const { - return numJoints; -} - -/* -===================== -idAnimator::ModelHandle -===================== -*/ -idRenderModel *idAnimator::ModelHandle( void ) const { - if ( !modelDef ) { - return NULL; - } - - return modelDef->ModelHandle(); -} - -/* -===================== -idAnimator::ModelDef -===================== -*/ -const idDeclModelDef *idAnimator::ModelDef( void ) const { - return modelDef; -} - -/* -===================== -idAnimator::CurrentAnim -===================== -*/ -idAnimBlend *idAnimator::CurrentAnim( int channelNum ) { - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::CurrentAnim : channel out of range" ); - } - - return &channels[ channelNum ][ 0 ]; -} - -/* -===================== -idAnimator::Clear -===================== -*/ -void idAnimator::Clear( int channelNum, int currentTime, int cleartime ) { - int i; - idAnimBlend *blend; - - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::Clear : channel out of range" ); - } - - blend = channels[ channelNum ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->Clear( currentTime, cleartime ); - } - ForceUpdate(); -} - -/* -===================== -idAnimator::SetFrame -===================== -*/ -void idAnimator::SetFrame( int channelNum, int animNum, int frame, int currentTime, int blendTime ) { - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::SetFrame : channel out of range" ); - } - - if ( !modelDef || !modelDef->GetAnim( animNum ) ) { - return; - } - - PushAnims( channelNum, currentTime, blendTime ); - channels[ channelNum ][ 0 ].SetFrame( modelDef, animNum, frame, currentTime, blendTime, entity ); - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } -} - -/* -===================== -idAnimator::CycleAnim -===================== -*/ -void idAnimator::CycleAnim( int channelNum, int animNum, int currentTime, int blendTime ) { - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::CycleAnim : channel out of range" ); - } - - if ( !modelDef || !modelDef->GetAnim( animNum ) ) { - return; - } - - PushAnims( channelNum, currentTime, blendTime ); - channels[ channelNum ][ 0 ].CycleAnim( modelDef, animNum, currentTime, blendTime, entity ); - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } -} - -/* -===================== -idAnimator::PlayAnim -===================== -*/ -void idAnimator::PlayAnim( int channelNum, int animNum, int currentTime, int blendTime ) { - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::PlayAnim : channel out of range" ); - } - - if ( !modelDef || !modelDef->GetAnim( animNum ) ) { - return; - } - - PushAnims( channelNum, currentTime, blendTime ); - channels[ channelNum ][ 0 ].PlayAnim( modelDef, animNum, currentTime, blendTime, entity ); - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } -} - -/* -===================== -idAnimator::SyncAnimChannels -===================== -*/ -void idAnimator::SyncAnimChannels( int channelNum, int fromChannelNum, int currentTime, int blendTime ) { - if ( ( channelNum < 0 ) || ( channelNum >= ANIM_NumAnimChannels ) || ( fromChannelNum < 0 ) || ( fromChannelNum >= ANIM_NumAnimChannels ) ) { - gameLocal.Error( "idAnimator::SyncToChannel : channel out of range" ); - } - - idAnimBlend &fromBlend = channels[ fromChannelNum ][ 0 ]; - idAnimBlend &toBlend = channels[ channelNum ][ 0 ]; - - float weight = fromBlend.blendEndValue; - if ( ( fromBlend.Anim() != toBlend.Anim() ) || ( fromBlend.GetStartTime() != toBlend.GetStartTime() ) || ( fromBlend.GetEndTime() != toBlend.GetEndTime() ) ) { - PushAnims( channelNum, currentTime, blendTime ); - toBlend = fromBlend; - toBlend.blendStartValue = 0.0f; - toBlend.blendEndValue = 0.0f; - } - toBlend.SetWeight( weight, currentTime - 1, blendTime ); - - // disable framecommands on the current channel so that commands aren't called twice - toBlend.AllowFrameCommands( false ); - - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } -} - -/* -===================== -idAnimator::SetJointPos -===================== -*/ -void idAnimator::SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ) { - int i; - jointMod_t *jointMod; - - if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { - return; - } - - jointMod = NULL; - for( i = 0; i < jointMods.Num(); i++ ) { - if ( jointMods[ i ]->jointnum == jointnum ) { - jointMod = jointMods[ i ]; - break; - } else if ( jointMods[ i ]->jointnum > jointnum ) { - break; - } - } - - if ( !jointMod ) { - jointMod = new jointMod_t; - jointMod->jointnum = jointnum; - jointMod->mat.Identity(); - jointMod->transform_axis = JOINTMOD_NONE; - jointMods.Insert( jointMod, i ); - } - - jointMod->pos = pos; - jointMod->transform_pos = transform_type; - - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } - ForceUpdate(); -} - -/* -===================== -idAnimator::SetJointAxis -===================== -*/ -void idAnimator::SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat ) { - int i; - jointMod_t *jointMod; - - if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { - return; - } - - jointMod = NULL; - for( i = 0; i < jointMods.Num(); i++ ) { - if ( jointMods[ i ]->jointnum == jointnum ) { - jointMod = jointMods[ i ]; - break; - } else if ( jointMods[ i ]->jointnum > jointnum ) { - break; - } - } - - if ( !jointMod ) { - jointMod = new jointMod_t; - jointMod->jointnum = jointnum; - jointMod->pos.Zero(); - jointMod->transform_pos = JOINTMOD_NONE; - jointMods.Insert( jointMod, i ); - } - - jointMod->mat = mat; - jointMod->transform_axis = transform_type; - - if ( entity ) { - entity->BecomeActive( TH_ANIMATE ); - } - ForceUpdate(); -} - -/* -===================== -idAnimator::ClearJoint -===================== -*/ -void idAnimator::ClearJoint( jointHandle_t jointnum ) { - int i; - - if ( !modelDef || !modelDef->ModelHandle() || ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { - return; - } - - for( i = 0; i < jointMods.Num(); i++ ) { - if ( jointMods[ i ]->jointnum == jointnum ) { - delete jointMods[ i ]; - jointMods.RemoveIndex( i ); - ForceUpdate(); - break; - } else if ( jointMods[ i ]->jointnum > jointnum ) { - break; - } - } -} - -/* -===================== -idAnimator::ClearAllJoints -===================== -*/ -void idAnimator::ClearAllJoints( void ) { - if ( jointMods.Num() ) { - ForceUpdate(); - } - jointMods.DeleteContents( true ); -} - -/* -===================== -idAnimator::ClearAllAnims -===================== -*/ -void idAnimator::ClearAllAnims( int currentTime, int cleartime ) { - int i; - - for( i = 0; i < ANIM_NumAnimChannels; i++ ) { - Clear( i, currentTime, cleartime ); - } - - ClearAFPose(); - ForceUpdate(); -} - -/* -==================== -idAnimator::GetDelta -==================== -*/ -void idAnimator::GetDelta( int fromtime, int totime, idVec3 &delta ) const { - int i; - const idAnimBlend *blend; - float blendWeight; - - if ( !modelDef || !modelDef->ModelHandle() || ( fromtime == totime ) ) { - delta.Zero(); - return; - } - - delta.Zero(); - blendWeight = 0.0f; - - blend = channels[ ANIMCHANNEL_ALL ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendDelta( fromtime, totime, delta, blendWeight ); - } - - if ( modelDef->Joints()[ 0 ].channel ) { - blend = channels[ modelDef->Joints()[ 0 ].channel ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendDelta( fromtime, totime, delta, blendWeight ); - } - } -} - -/* -==================== -idAnimator::GetDeltaRotation -==================== -*/ -bool idAnimator::GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const { - int i; - const idAnimBlend *blend; - float blendWeight; - idQuat q; - - if ( !modelDef || !modelDef->ModelHandle() || ( fromtime == totime ) ) { - delta.Identity(); - return false; - } - - q.Set( 0.0f, 0.0f, 0.0f, 1.0f ); - blendWeight = 0.0f; - - blend = channels[ ANIMCHANNEL_ALL ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendDeltaRotation( fromtime, totime, q, blendWeight ); - } - - if ( modelDef->Joints()[ 0 ].channel ) { - blend = channels[ modelDef->Joints()[ 0 ].channel ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendDeltaRotation( fromtime, totime, q, blendWeight ); - } - } - - if ( blendWeight > 0.0f ) { - delta = q.ToMat3(); - return true; - } else { - delta.Identity(); - return false; - } -} - -/* -==================== -idAnimator::GetOrigin -==================== -*/ -void idAnimator::GetOrigin( int currentTime, idVec3 &pos ) const { - int i; - const idAnimBlend *blend; - float blendWeight; - - if ( !modelDef || !modelDef->ModelHandle() ) { - pos.Zero(); - return; - } - - pos.Zero(); - blendWeight = 0.0f; - - blend = channels[ ANIMCHANNEL_ALL ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendOrigin( currentTime, pos, blendWeight, removeOriginOffset ); - } - - if ( modelDef->Joints()[ 0 ].channel ) { - blend = channels[ modelDef->Joints()[ 0 ].channel ]; - for( i = 0; i < ANIM_MaxAnimsPerChannel; i++, blend++ ) { - blend->BlendOrigin( currentTime, pos, blendWeight, removeOriginOffset ); - } - } - - pos += modelDef->GetVisualOffset(); -} - -/* -==================== -idAnimator::GetBounds -==================== -*/ -bool idAnimator::GetBounds( int currentTime, idBounds &bounds ) { - int i, j; - const idAnimBlend *blend; - int count; - - if ( !modelDef || !modelDef->ModelHandle() ) { - return false; - } - - if ( AFPoseJoints.Num() ) { - bounds = AFPoseBounds; - count = 1; - } else { - bounds.Clear(); - count = 0; - } - - blend = channels[ 0 ]; - for( i = ANIMCHANNEL_ALL; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( blend->AddBounds( currentTime, bounds, removeOriginOffset ) ) { - count++; - } - } - } - - if ( !count ) { - if ( !frameBounds.IsCleared() ) { - bounds = frameBounds; - return true; - } else { - bounds.Zero(); - return false; - } - } - - bounds.TranslateSelf( modelDef->GetVisualOffset() ); - - if ( g_debugBounds.GetBool() ) { - if ( bounds[1][0] - bounds[0][0] > 2048 || bounds[1][1] - bounds[0][1] > 2048 ) { - if ( entity ) { - gameLocal.Warning( "big frameBounds on entity '%s' with model '%s': %f,%f", entity->name.c_str(), modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] ); - } else { - gameLocal.Warning( "big frameBounds on model '%s': %f,%f", modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] ); - } - } - } - - frameBounds = bounds; - - return true; -} - -/* -===================== -idAnimator::InitAFPose -===================== -*/ -void idAnimator::InitAFPose( void ) { - - if ( !modelDef ) { - return; - } - - AFPoseJoints.SetNum( modelDef->Joints().Num(), false ); - AFPoseJoints.SetNum( 0, false ); - AFPoseJointMods.SetNum( modelDef->Joints().Num(), false ); - AFPoseJointFrame.SetNum( modelDef->Joints().Num(), false ); -} - -/* -===================== -idAnimator::SetAFPoseJointMod -===================== -*/ -void idAnimator::SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin ) { - AFPoseJointMods[jointNum].mod = mod; - AFPoseJointMods[jointNum].axis = axis; - AFPoseJointMods[jointNum].origin = origin; - - int index = idBinSearch_GreaterEqual( AFPoseJoints.Ptr(), AFPoseJoints.Num(), jointNum ); - if ( index >= AFPoseJoints.Num() || jointNum != AFPoseJoints[index] ) { - AFPoseJoints.Insert( jointNum, index ); - } -} - -/* -===================== -idAnimator::FinishAFPose -===================== -*/ -void idAnimator::FinishAFPose( int animNum, const idBounds &bounds, const int time ) { - int i, j; - int numJoints; - int parentNum; - int jointMod; - int jointNum; - const int * jointParent; - - if ( !modelDef ) { - return; - } - - const idAnim *anim = modelDef->GetAnim( animNum ); - if ( !anim ) { - return; - } - - numJoints = modelDef->Joints().Num(); - if ( !numJoints ) { - return; - } - - idRenderModel *md5 = modelDef->ModelHandle(); - const idMD5Anim *md5anim = anim->MD5Anim( 0 ); - - if ( numJoints != md5anim->NumJoints() ) { - gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", md5->Name(), md5anim->Name() ); - return; - } - - idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); - md5anim->GetSingleFrame( 0, jointFrame, modelDef->GetChannelJoints( ANIMCHANNEL_ALL ), modelDef->NumJointsOnChannel( ANIMCHANNEL_ALL ) ); - - if ( removeOriginOffset ) { -#ifdef VELOCITY_MOVE - jointFrame[ 0 ].t.x = 0.0f; -#else - jointFrame[ 0 ].t.Zero(); -#endif - } - - idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( *joints ) ); - - // convert the joint quaternions to joint matrices - SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); - - // first joint is always root of entire hierarchy - if ( AFPoseJoints.Num() && AFPoseJoints[0] == 0 ) { - switch( AFPoseJointMods[0].mod ) { - case AF_JOINTMOD_AXIS: { - joints[0].SetRotation( AFPoseJointMods[0].axis ); - break; - } - case AF_JOINTMOD_ORIGIN: { - joints[0].SetTranslation( AFPoseJointMods[0].origin ); - break; - } - case AF_JOINTMOD_BOTH: { - joints[0].SetRotation( AFPoseJointMods[0].axis ); - joints[0].SetTranslation( AFPoseJointMods[0].origin ); - break; - } - default: break; - } - j = 1; - } else { - j = 0; - } - - // pointer to joint info - jointParent = modelDef->JointParents(); - - // transform the child joints - for( i = 1; j < AFPoseJoints.Num(); j++, i++ ) { - jointMod = AFPoseJoints[j]; - - // transform any joints preceding the joint modifier - SIMDProcessor->TransformJoints( joints, jointParent, i, jointMod - 1 ); - i = jointMod; - - parentNum = jointParent[i]; - - switch( AFPoseJointMods[jointMod].mod ) { - case AF_JOINTMOD_AXIS: { - joints[i].SetRotation( AFPoseJointMods[jointMod].axis ); - joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() ); - break; - } - case AF_JOINTMOD_ORIGIN: { - joints[i].SetRotation( joints[i].ToMat3() * joints[parentNum].ToMat3() ); - joints[i].SetTranslation( AFPoseJointMods[jointMod].origin ); - break; - } - case AF_JOINTMOD_BOTH: { - joints[i].SetRotation( AFPoseJointMods[jointMod].axis ); - joints[i].SetTranslation( AFPoseJointMods[jointMod].origin ); - break; - } - default: break; - } - } - - // transform the rest of the hierarchy - SIMDProcessor->TransformJoints( joints, jointParent, i, numJoints - 1 ); - - // untransform hierarchy - SIMDProcessor->UntransformJoints( joints, jointParent, 1, numJoints - 1 ); - - // convert joint matrices back to joint quaternions - SIMDProcessor->ConvertJointMatsToJointQuats( AFPoseJointFrame.Ptr(), joints, numJoints ); - - // find all modified joints and their parents - bool *blendJoints = (bool *) _alloca16( numJoints * sizeof( bool ) ); - memset( blendJoints, 0, numJoints * sizeof( bool ) ); - - // mark all modified joints and their parents - for( i = 0; i < AFPoseJoints.Num(); i++ ) { - for( jointNum = AFPoseJoints[i]; jointNum != INVALID_JOINT; jointNum = jointParent[jointNum] ) { - blendJoints[jointNum] = true; - } - } - - // lock all parents of modified joints - AFPoseJoints.SetNum( 0, false ); - for ( i = 0; i < numJoints; i++ ) { - if ( blendJoints[i] ) { - AFPoseJoints.Append( i ); - } - } - - AFPoseBounds = bounds; - AFPoseTime = time; - - ForceUpdate(); -} - -/* -===================== -idAnimator::SetAFPoseBlendWeight -===================== -*/ -void idAnimator::SetAFPoseBlendWeight( float blendWeight ) { - AFPoseBlendWeight = blendWeight; -} - -/* -===================== -idAnimator::BlendAFPose -===================== -*/ -bool idAnimator::BlendAFPose( idJointQuat *blendFrame ) const { - - if ( !AFPoseJoints.Num() ) { - return false; - } - - SIMDProcessor->BlendJoints( blendFrame, AFPoseJointFrame.Ptr(), AFPoseBlendWeight, AFPoseJoints.Ptr(), AFPoseJoints.Num() ); - - return true; -} - -/* -===================== -idAnimator::ClearAFPose -===================== -*/ -void idAnimator::ClearAFPose( void ) { - if ( AFPoseJoints.Num() ) { - ForceUpdate(); - } - AFPoseBlendWeight = 1.0f; - AFPoseJoints.SetNum( 0, false ); - AFPoseBounds.Clear(); - AFPoseTime = 0; -} - -/* -===================== -idAnimator::ServiceAnims -===================== -*/ -void idAnimator::ServiceAnims( int fromtime, int totime ) { - int i, j; - idAnimBlend *blend; - - if ( !modelDef ) { - return; - } - - if ( modelDef->ModelHandle() ) { - blend = channels[ 0 ]; - for( i = 0; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - blend->CallFrameCommands( entity, fromtime, totime ); - } - } - } - - if ( !IsAnimating( totime ) ) { - stoppedAnimatingUpdate = true; - if ( entity ) { - entity->BecomeInactive( TH_ANIMATE ); - - // present one more time with stopped animations so the renderer can properly recreate interactions - entity->BecomeActive( TH_UPDATEVISUALS ); - } - } -} - -/* -===================== -idAnimator::IsAnimating -===================== -*/ -bool idAnimator::IsAnimating( int currentTime ) const { - int i, j; - const idAnimBlend *blend; - - if ( !modelDef || !modelDef->ModelHandle() ) { - return false; - } - - // if animating with an articulated figure - if ( AFPoseJoints.Num() && currentTime <= AFPoseTime ) { - return true; - } - - blend = channels[ 0 ]; - for( i = 0; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( !blend->IsDone( currentTime ) ) { - return true; - } - } - } - - return false; -} - -/* -===================== -idAnimator::FrameHasChanged -===================== -*/ -bool idAnimator::FrameHasChanged( int currentTime ) const { - int i, j; - const idAnimBlend *blend; - - if ( !modelDef || !modelDef->ModelHandle() ) { - return false; - } - - // if animating with an articulated figure - if ( AFPoseJoints.Num() && currentTime <= AFPoseTime ) { - return true; - } - - blend = channels[ 0 ]; - for( i = 0; i < ANIM_NumAnimChannels; i++ ) { - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( blend->FrameHasChanged( currentTime ) ) { - return true; - } - } - } - - if ( forceUpdate && IsAnimating( currentTime ) ) { - return true; - } - - return false; -} - -/* -===================== -idAnimator::CreateFrame -===================== -*/ -bool idAnimator::CreateFrame( int currentTime, bool force ) { - int i, j; - int numJoints; - int parentNum; - bool hasAnim; - bool debugInfo; - float baseBlend; - float blendWeight; - const idAnimBlend * blend; - const int * jointParent; - const jointMod_t * jointMod; - const idJointQuat * defaultPose; - - static idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); - - if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { - return false; - } - - if ( !modelDef || !modelDef->ModelHandle() ) { - return false; - } - - if ( !force && !r_showSkel.GetInteger() ) { - if ( lastTransformTime == currentTime ) { - return false; - } - if ( lastTransformTime != -1 && !stoppedAnimatingUpdate && !IsAnimating( currentTime ) ) { - return false; - } - } - - // Optional optimisation: Skip animations for dormant entities - if (cv_ai_opt_noanims.GetBool() && entity->CheckDormant()) return false; - - lastTransformTime = currentTime; - stoppedAnimatingUpdate = false; - - if ( entity && ( ( g_debugAnim.GetInteger() == entity->entityNumber ) || ( g_debugAnim.GetInteger() == -2 ) ) ) { - debugInfo = true; - gameLocal.Printf( "---------------\n%d: entity '%s':\n", gameLocal.time, entity->GetName() ); - gameLocal.Printf( "model '%s':\n", modelDef->GetModelName() ); - } else { - debugInfo = false; - } - - // init the joint buffer - if ( AFPoseJoints.Num() ) { - // initialize with AF pose anim for the case where there are no other animations and no AF pose joint modifications - defaultPose = AFPoseJointFrame.Ptr(); - } else { - defaultPose = modelDef->GetDefaultPose(); - } - - if ( !defaultPose ) { - //gameLocal.Warning( "idAnimator::CreateFrame: no defaultPose on '%s'", modelDef->Name() ); - return false; - } - - numJoints = modelDef->Joints().Num(); - idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( jointFrame[0] ) ); - SIMDProcessor->Memcpy( jointFrame, defaultPose, numJoints * sizeof( jointFrame[0] ) ); - - hasAnim = false; - - // blend the all channel - baseBlend = 0.0f; - blend = channels[ ANIMCHANNEL_ALL ]; - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( blend->BlendAnim( currentTime, ANIMCHANNEL_ALL, numJoints, jointFrame, baseBlend, removeOriginOffset, false, debugInfo ) ) { - hasAnim = true; - if ( baseBlend >= 1.0f ) { - break; - } - } - } - - // only blend other channels if there's enough space to blend into - if ( baseBlend < 1.0f ) { - for( i = ANIMCHANNEL_ALL + 1; i < ANIM_NumAnimChannels; i++ ) { - if ( !modelDef->NumJointsOnChannel( i ) ) { - continue; - } - if ( i == ANIMCHANNEL_EYELIDS ) { - // eyelids blend over any previous anims, so skip it and blend it later - continue; - } - blendWeight = baseBlend; - blend = channels[ i ]; - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( blend->BlendAnim( currentTime, i, numJoints, jointFrame, blendWeight, removeOriginOffset, false, debugInfo ) ) { - hasAnim = true; - if ( blendWeight >= 1.0f ) { - // fully blended - break; - } - } - } - - if ( debugInfo && !AFPoseJoints.Num() && !blendWeight ) { - gameLocal.Printf( "%d: %s using default pose in model '%s'\n", gameLocal.time, channelNames[ i ], modelDef->GetModelName() ); - } - } - } - - // blend in the eyelids - if ( modelDef->NumJointsOnChannel( ANIMCHANNEL_EYELIDS ) ) { - blend = channels[ ANIMCHANNEL_EYELIDS ]; - blendWeight = baseBlend; - for( j = 0; j < ANIM_MaxAnimsPerChannel; j++, blend++ ) { - if ( blend->BlendAnim( currentTime, ANIMCHANNEL_EYELIDS, numJoints, jointFrame, blendWeight, removeOriginOffset, true, debugInfo ) ) { - hasAnim = true; - if ( blendWeight >= 1.0f ) { - // fully blended - break; - } - } - } - } - - // blend the articulated figure pose - if ( BlendAFPose( jointFrame ) ) { - hasAnim = true; - } - - if ( !hasAnim && !jointMods.Num() ) { - // no animations were updated - return false; - } - - // convert the joint quaternions to rotation matrices - SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); - - // check if we need to modify the origin - if ( jointMods.Num() && ( jointMods[0]->jointnum == 0 ) ) { - jointMod = jointMods[0]; - - switch( jointMod->transform_axis ) { - case JOINTMOD_NONE: - break; - - case JOINTMOD_LOCAL: - joints[0].SetRotation( jointMod->mat * joints[0].ToMat3() ); - break; - - case JOINTMOD_WORLD: - joints[0].SetRotation( joints[0].ToMat3() * jointMod->mat ); - break; - - case JOINTMOD_LOCAL_OVERRIDE: - case JOINTMOD_WORLD_OVERRIDE: - joints[0].SetRotation( jointMod->mat ); - break; - } - - switch( jointMod->transform_pos ) { - case JOINTMOD_NONE: - break; - - case JOINTMOD_LOCAL: - joints[0].SetTranslation( joints[0].ToVec3() + jointMod->pos ); - break; - - case JOINTMOD_LOCAL_OVERRIDE: - case JOINTMOD_WORLD: - case JOINTMOD_WORLD_OVERRIDE: - joints[0].SetTranslation( jointMod->pos ); - break; - } - j = 1; - } else { - j = 0; - } - - // add in the model offset - joints[0].SetTranslation( joints[0].ToVec3() + modelDef->GetVisualOffset() ); - - // pointer to joint info - jointParent = modelDef->JointParents(); - - // add in any joint modifications - for( i = 1; j < jointMods.Num(); j++, i++ ) { - jointMod = jointMods[j]; - - // transform any joints preceding the joint modifier - SIMDProcessor->TransformJoints( joints, jointParent, i, jointMod->jointnum - 1 ); - i = jointMod->jointnum; - - parentNum = jointParent[i]; - - // modify the axis - switch( jointMod->transform_axis ) { - case JOINTMOD_NONE: - joints[i].SetRotation( joints[i].ToMat3() * joints[ parentNum ].ToMat3() ); - break; - - case JOINTMOD_LOCAL: - joints[i].SetRotation( jointMod->mat * ( joints[i].ToMat3() * joints[parentNum].ToMat3() ) ); - break; - - case JOINTMOD_LOCAL_OVERRIDE: - joints[i].SetRotation( jointMod->mat * joints[parentNum].ToMat3() ); - break; - - case JOINTMOD_WORLD: - joints[i].SetRotation( ( joints[i].ToMat3() * joints[parentNum].ToMat3() ) * jointMod->mat ); - break; - - case JOINTMOD_WORLD_OVERRIDE: - joints[i].SetRotation( jointMod->mat ); - break; - } - - // modify the position - switch( jointMod->transform_pos ) { - case JOINTMOD_NONE: - joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() ); - break; - - case JOINTMOD_LOCAL: - joints[i].SetTranslation( joints[parentNum].ToVec3() + ( joints[i].ToVec3() + jointMod->pos ) * joints[parentNum].ToMat3() ); - break; - - case JOINTMOD_LOCAL_OVERRIDE: - joints[i].SetTranslation( joints[parentNum].ToVec3() + jointMod->pos * joints[parentNum].ToMat3() ); - break; - - case JOINTMOD_WORLD: - joints[i].SetTranslation( joints[parentNum].ToVec3() + joints[i].ToVec3() * joints[parentNum].ToMat3() + jointMod->pos ); - break; - - case JOINTMOD_WORLD_OVERRIDE: - joints[i].SetTranslation( jointMod->pos ); - break; - } - } - - // transform the rest of the hierarchy - SIMDProcessor->TransformJoints( joints, jointParent, i, numJoints - 1 ); - - return true; -} - -/* -===================== -idAnimator::ForceUpdate -===================== -*/ -void idAnimator::ForceUpdate( void ) { - lastTransformTime = -1; - forceUpdate = true; -} - -/* -===================== -idAnimator::ClearForceUpdate -===================== -*/ -void idAnimator::ClearForceUpdate( void ) { - forceUpdate = false; -} - -/* -===================== -idAnimator::GetJointTransform> gamex86.dll!idAnimator::ForceUpdate() Line 4268 C++ - -===================== -*/ -bool idAnimator::GetJointTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { - if ( !modelDef || ( jointHandle < 0 ) || ( jointHandle >= modelDef->NumJoints() ) ) { - return false; - } - - CreateFrame( currentTime, false ); - - offset = joints[ jointHandle ].ToVec3(); - axis = joints[ jointHandle ].ToMat3(); - - return true; -} - -/* -===================== -idAnimator::GetJointLocalTransform -===================== -*/ -bool idAnimator::GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { - if ( !modelDef ) { - return false; - } - - const idList &modelJoints = modelDef->Joints(); - - if ( ( jointHandle < 0 ) || ( jointHandle >= modelJoints.Num() ) ) { - return false; - } - - // FIXME: overkill - CreateFrame( currentTime, false ); - - if ( jointHandle > 0 ) { - idJointMat m = joints[ jointHandle ]; - m /= joints[ modelJoints[ jointHandle ].parentNum ]; - offset = m.ToVec3(); - axis = m.ToMat3(); - } else { - offset = joints[ jointHandle ].ToVec3(); - axis = joints[ jointHandle ].ToMat3(); - } - - return true; -} - -/* -===================== -idAnimator::GetJointHandle -===================== -*/ -jointHandle_t idAnimator::GetJointHandle( const char *name ) const { - if ( !modelDef || !modelDef->ModelHandle() ) { - return INVALID_JOINT; - } - - return modelDef->ModelHandle()->GetJointHandle( name ); -} - -/* -===================== -idAnimator::GetJointName -===================== -*/ -const char *idAnimator::GetJointName( jointHandle_t handle ) const { - if ( !modelDef || !modelDef->ModelHandle() ) { - return ""; - } - - return modelDef->ModelHandle()->GetJointName( handle ); -} - -/* -===================== -idAnimator::GetChannelForJoint -===================== -*/ -int idAnimator::GetChannelForJoint( jointHandle_t joint ) const { - if ( !modelDef ) { - gameLocal.Error( "idAnimator::GetChannelForJoint: NULL model" ); - } - - if ( ( joint < 0 ) || ( joint >= numJoints ) ) { - gameLocal.Error( "idAnimator::GetChannelForJoint: invalid joint num (%d)", joint ); - } - - return modelDef->GetJoint( joint )->channel; -} - -/* -===================== -idAnimator::GetFirstChild -===================== -*/ -jointHandle_t idAnimator::GetFirstChild( const char *name ) const { - return GetFirstChild( GetJointHandle( name ) ); -} - -/* -===================== -idAnimator::GetFirstChild -===================== -*/ -jointHandle_t idAnimator::GetFirstChild( jointHandle_t jointnum ) const { - int i; - int num; - const jointInfo_t *joint; - - if ( !modelDef ) { - return INVALID_JOINT; - } - - num = modelDef->NumJoints(); - if ( !num ) { - return jointnum; - } - joint = modelDef->GetJoint( 0 ); - for( i = 0; i < num; i++, joint++ ) { - if ( joint->parentNum == jointnum ) { - return ( jointHandle_t )joint->num; - } - } - return jointnum; -} - -/* -===================== -idAnimator::GetJoints -===================== -*/ -void idAnimator::GetJoints( int *numJoints, idJointMat **jointsPtr ) { - *numJoints = this->numJoints; - *jointsPtr = this->joints; -} - -/* -===================== -idAnimator::GetAnimFlags -===================== -*/ -const animFlags_t idAnimator::GetAnimFlags( int animNum ) const { - animFlags_t result; - - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->GetAnimFlags(); - } - - memset( &result, 0, sizeof( result ) ); - return result; -} - -/* -===================== -idAnimator::NumFrames -===================== -*/ -int idAnimator::NumFrames( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->NumFrames(); - } else { - return 0; - } -} - -/* -===================== -idAnimator::NumSyncedAnims -===================== -*/ -int idAnimator::NumSyncedAnims( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->NumAnims(); - } else { - return 0; - } -} - -/* -===================== -idAnimator::AnimName -===================== -*/ -const char *idAnimator::AnimName( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->Name(); - } else { - return ""; - } -} - -/* -===================== -idAnimator::AnimFullName -===================== -*/ -const char *idAnimator::AnimFullName( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->FullName(); - } else { - return ""; - } -} - -/* -===================== -idAnimator::AnimLength -===================== -*/ -int idAnimator::AnimLength( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->Length(); - } else { - return 0; - } -} - -/* -===================== -idAnimator::TotalMovementDelta -===================== -*/ -const idVec3 &idAnimator::TotalMovementDelta( int animNum ) const { - const idAnim *anim = GetAnim( animNum ); - if ( anim ) { - return anim->TotalMovementDelta(); - } else { - return vec3_origin; - } -} - -/*********************************************************************** - - Util functions - -***********************************************************************/ - -/* -===================== -ANIM_GetModelDefFromEntityDef -===================== -*/ -const idDeclModelDef *ANIM_GetModelDefFromEntityDef( const idDict *args ) { - const idDeclModelDef *modelDef; - - idStr name = args->GetString( "model" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); - if ( modelDef && modelDef->ModelHandle() ) { - return modelDef; - } - - return NULL; -} - -/* -===================== -idGameEdit::ANIM_GetModelFromEntityDef -===================== -*/ -idRenderModel *idGameEdit::ANIM_GetModelFromEntityDef( const idDict *args ) { - idRenderModel *model; - const idDeclModelDef *modelDef; - - model = NULL; - - idStr name = args->GetString( "model" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); - if ( modelDef ) { - model = modelDef->ModelHandle(); - } - - if ( !model ) { - model = renderModelManager->FindModel( name ); - } - - if ( model && model->IsDefaultModel() ) { - return NULL; - } - - return model; -} - -/* -===================== -idGameEdit::ANIM_GetModelFromEntityDef -===================== -*/ -idRenderModel *idGameEdit::ANIM_GetModelFromEntityDef( const char *classname ) { - const idDict *args; - - args = gameLocal.FindEntityDefDict( classname, false ); - if ( !args ) { - return NULL; - } - - return ANIM_GetModelFromEntityDef( args ); -} - -/* -===================== -idGameEdit::ANIM_GetModelOffsetFromEntityDef -===================== -*/ -const idVec3 &idGameEdit::ANIM_GetModelOffsetFromEntityDef( const char *classname ) { - const idDict *args; - const idDeclModelDef *modelDef; - - args = gameLocal.FindEntityDefDict( classname, false ); - if ( !args ) { - return vec3_origin; - } - - modelDef = ANIM_GetModelDefFromEntityDef( args ); - if ( !modelDef ) { - return vec3_origin; - } - - return modelDef->GetVisualOffset(); -} - -/* -===================== -idGameEdit::ANIM_GetModelFromName -===================== -*/ -idRenderModel *idGameEdit::ANIM_GetModelFromName( const char *modelName ) { - const idDeclModelDef *modelDef; - idRenderModel *model; - - model = NULL; - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelName, false ) ); - if ( modelDef ) { - model = modelDef->ModelHandle(); - } - if ( !model ) { - model = renderModelManager->FindModel( modelName ); - } - return model; -} - -/* -===================== -idGameEdit::ANIM_GetAnimFromEntityDef -===================== -*/ -const idMD5Anim *idGameEdit::ANIM_GetAnimFromEntityDef( const char *classname, const char *animname ) { - const idDict *args; - const idMD5Anim *md5anim; - const idAnim *anim; - int animNum; - const char *modelname; - const idDeclModelDef *modelDef; - - args = gameLocal.FindEntityDefDict( classname, false ); - if ( !args ) { - return NULL; - } - - md5anim = NULL; - modelname = args->GetString( "model" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); - if ( modelDef ) { - animNum = modelDef->GetAnim( animname ); - if ( animNum ) { - anim = modelDef->GetAnim( animNum ); - if ( anim ) { - md5anim = anim->MD5Anim( 0 ); - } - } - } - return md5anim; -} - -/* -===================== -idGameEdit::ANIM_GetNumAnimsFromEntityDef -===================== -*/ -int idGameEdit::ANIM_GetNumAnimsFromEntityDef( const idDict *args ) { - const char *modelname; - const idDeclModelDef *modelDef; - - modelname = args->GetString( "model" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); - if ( modelDef ) { - return modelDef->NumAnims(); - } - return 0; -} - -/* -===================== -idGameEdit::ANIM_GetAnimNameFromEntityDef -===================== -*/ -const char *idGameEdit::ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum ) { - const char *modelname; - const idDeclModelDef *modelDef; - - modelname = args->GetString( "model" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, modelname, false ) ); - if ( modelDef ) { - const idAnim* anim = modelDef->GetAnim( animNum ); - if ( anim ) { - return anim->FullName(); - } - } - return ""; -} - -/* -===================== -idGameEdit::ANIM_GetAnim -===================== -*/ -const idMD5Anim *idGameEdit::ANIM_GetAnim( const char *fileName ) { - return animationLib.GetAnim( fileName ); -} - -/* -===================== -idGameEdit::ANIM_GetLength -===================== -*/ -int idGameEdit::ANIM_GetLength( const idMD5Anim *anim ) { - if ( !anim ) { - return 0; - } - return anim->Length(); -} - -/* -===================== -idGameEdit::ANIM_GetNumFrames -===================== -*/ -int idGameEdit::ANIM_GetNumFrames( const idMD5Anim *anim ) { - if ( !anim ) { - return 0; - } - return anim->NumFrames(); -} - -/* -===================== -idGameEdit::ANIM_CreateAnimFrame -===================== -*/ -void idGameEdit::ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *joints, int time, const idVec3 &offset, bool remove_origin_offset ) { - int i; - frameBlend_t frame; - const idMD5Joint *md5joints; - int *index; - - if ( !model || model->IsDefaultModel() || !anim ) { - return; - } - - if ( numJoints != model->NumJoints() ) { - gameLocal.Error( "ANIM_CreateAnimFrame: different # of joints in renderEntity_t than in model (%s)", model->Name() ); - } - - if ( !model->NumJoints() ) { - // FIXME: Print out a warning? - return; - } - - if ( !joints ) { - gameLocal.Error( "ANIM_CreateAnimFrame: NULL joint frame pointer on model (%s)", model->Name() ); - } - - if ( numJoints != anim->NumJoints() ) { - gameLocal.Warning( "Model '%s' has different # of joints than anim '%s'", model->Name(), anim->Name() ); - for( i = 0; i < numJoints; i++ ) { - joints[i].SetRotation( mat3_identity ); - joints[i].SetTranslation( offset ); - } - return; - } - - // create index for all joints - index = ( int * )_alloca16( numJoints * sizeof( int ) ); - for ( i = 0; i < numJoints; i++ ) { - index[i] = i; - } - - // create the frame - anim->ConvertTimeToFrame( time, 1, frame ); - idJointQuat *jointFrame = ( idJointQuat * )_alloca16( numJoints * sizeof( *jointFrame ) ); - anim->GetInterpolatedFrame( frame, jointFrame, index, numJoints ); - - // convert joint quaternions to joint matrices - SIMDProcessor->ConvertJointQuatsToJointMats( joints, jointFrame, numJoints ); - - // first joint is always root of entire hierarchy - if ( remove_origin_offset ) { - joints[0].SetTranslation( offset ); - } else { - joints[0].SetTranslation( joints[0].ToVec3() + offset ); - } - - // transform the children - md5joints = model->GetJoints(); - for( i = 1; i < numJoints; i++ ) { - joints[i] *= joints[ md5joints[i].parent - md5joints ]; - } -} - -/* -===================== -idGameEdit::ANIM_CreateMeshForAnim -===================== -*/ -idRenderModel *idGameEdit::ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset ) { - renderEntity_t ent; - const idDict *args; - const char *temp; - idRenderModel *newmodel; - const idMD5Anim *md5anim; - idStr filename; - idStr extension; - const idAnim *anim; - int animNum; - idVec3 offset; - const idDeclModelDef *modelDef; - - if ( !model || model->IsDefaultModel() ) { - return NULL; - } - - args = gameLocal.FindEntityDefDict( classname, false ); - if ( !args ) { - return NULL; - } - - memset( &ent, 0, sizeof( ent ) ); - - ent.bounds.Clear(); - ent.suppressSurfaceInViewID = 0; - - modelDef = ANIM_GetModelDefFromEntityDef( args ); - if ( modelDef ) { - animNum = modelDef->GetAnim( animname ); - if ( !animNum ) { - return NULL; - } - anim = modelDef->GetAnim( animNum ); - if ( !anim ) { - return NULL; - } - md5anim = anim->MD5Anim( 0 ); - ent.customSkin = modelDef->GetDefaultSkin(); - offset = modelDef->GetVisualOffset(); - } else { - filename = animname; - filename.ExtractFileExtension( extension ); - if ( !extension.Length() ) { - animname = args->GetString( va( "anim %s", animname ) ); - } - - md5anim = animationLib.GetAnim( animname ); - offset.Zero(); - } - - if ( !md5anim ) { - return NULL; - } - - temp = args->GetString( "skin", "" ); - if ( temp[ 0 ] ) { - ent.customSkin = declManager->FindSkin( temp ); - } - - ent.numJoints = model->NumJoints(); - ent.joints = ( idJointMat * )Mem_Alloc16( ent.numJoints * sizeof( *ent.joints ) ); - - ANIM_CreateAnimFrame( model, md5anim, ent.numJoints, ent.joints, FRAME2MS( frame ), offset, remove_origin_offset ); - - newmodel = model->InstantiateDynamicModel( &ent, NULL, NULL ); - - Mem_Free16( ent.joints ); - ent.joints = NULL; - - return newmodel; -} diff --git a/game/anim/anim_import.cpp b/game/anim/anim_import.cpp deleted file mode 100644 index b9ad0d1ac..000000000 --- a/game/anim/anim_import.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../MayaImport/maya_main.h" - -/*********************************************************************** - - Maya conversion functions - -***********************************************************************/ - -static idStr Maya_Error; - -static exporterInterface_t Maya_ConvertModel = NULL; -static exporterShutdown_t Maya_Shutdown = NULL; -static int importDLL = 0; - -bool idModelExport::initialized = false; - -/* -==================== -idModelExport::idModelExport -==================== -*/ -idModelExport::idModelExport() { - Reset(); -} - -/* -==================== -idModelExport::Shutdown -==================== -*/ -void idModelExport::Shutdown( void ) { - if ( Maya_Shutdown ) { - Maya_Shutdown(); - } - - if ( importDLL ) { - sys->DLL_Unload( importDLL ); - } - - importDLL = 0; - Maya_Shutdown = NULL; - Maya_ConvertModel = NULL; - Maya_Error.Clear(); - initialized = false; -} - -/* -===================== -idModelExport::CheckMayaInstall - -Determines if Maya is installed on the user's machine -===================== -*/ -bool idModelExport::CheckMayaInstall( void ) { -#ifndef _WIN32 - return false; -#elif 0 - HKEY hKey; - long lres, lType; - - lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya\\4.5\\Setup\\InstallPath", &hKey ); - - if ( lres != ERROR_SUCCESS ) { - return false; - } - - lres = RegQueryValueEx( hKey, "MAYA_INSTALL_LOCATION", NULL, (unsigned long*)&lType, (unsigned char*)NULL, (unsigned long*)NULL ); - - RegCloseKey( hKey ); - - if ( lres != ERROR_SUCCESS ) { - return false; - } - return true; -#else - HKEY hKey; - long lres; - - // only check the non-version specific key so that we only have to update the maya dll when new versions are released - lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya", &hKey ); - RegCloseKey( hKey ); - - if ( lres == ERROR_SUCCESS ) { - return true; - } - - // greebo: Could not find "Alias|WaveFront" Maya key, check for AutoDesk - lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Autodesk\\Maya", &hKey ); - RegCloseKey( hKey ); - - if ( lres == ERROR_SUCCESS ) { - return true; - } - - gameLocal.Warning("Maya key not found in registry, continuing...\n"); - - return true; // greebo: both keys failed, let the game continue anyways -#endif -} - -#ifdef WIN32 - -#define FORMAT_BUFSIZE 2048 - -// Helper method to retrieve the error when DLL load failed. -const char* FormatGetLastError() { - static char buf[FORMAT_BUFSIZE]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - buf, - FORMAT_BUFSIZE, NULL); - return buf; -} -#endif - -/* -===================== -idModelExport::LoadMayaDll - -Checks to see if we can load the Maya export dll -===================== -*/ -void idModelExport::LoadMayaDll( void ) { - exporterDLLEntry_t dllEntry; - char dllPath[ MAX_OSPATH ]; - - fileSystem->FindDLL( "MayaImport", dllPath, false ); - if ( !dllPath[ 0 ] ) { - return; - } - importDLL = sys->DLL_Load( dllPath ); - - if ( !importDLL ) { -#ifdef WIN32 - // greebo: Do another attempt in Win32 to get a better error message - idStr win32DllPath(dllPath); - win32DllPath.Replace("/", "\\"); - - HMODULE dll = LoadLibrary(win32DllPath); - - if (dll == 0) { - gameLocal.Warning("Could not load MayaImport DLL: %s ", FormatGetLastError()); - } -#endif - return; - } - - // look up the dll interface functions - dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" ); - Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" ); - Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" ); - if ( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) { - Maya_ConvertModel = NULL; - Maya_Shutdown = NULL; - sys->DLL_Unload( importDLL ); - importDLL = 0; - gameLocal.Error( "Invalid interface on export DLL." ); - return; - } - - // initialize the DLL - if ( !dllEntry( MD5_VERSION, common, sys ) ) { - // init failed - Maya_ConvertModel = NULL; - Maya_Shutdown = NULL; - sys->DLL_Unload( importDLL ); - importDLL = 0; - gameLocal.Error( "Export DLL init failed." ); - return; - } -} - -/* -===================== -idModelExport::ConvertMayaToMD5 - -Checks if a Maya model should be converted to an MD5, and converts if if the time/date or -version number has changed. -===================== -*/ -bool idModelExport::ConvertMayaToMD5( void ) { - unsigned sourceTime; - unsigned destTime; - int version; - idToken cmdLine; - idStr path; - - // check if our DLL got loaded - if ( initialized && !Maya_ConvertModel ) { - Maya_Error = "MayaImport dll not loaded."; - return false; - } - - // if idAnimManager::forceExport is set then we always reexport Maya models - if ( idAnimManager::forceExport ) { - force = true; - } - - // get the source file's time - if ( fileSystem->ReadFile( src, NULL, &sourceTime ) < 0 ) { - // source file doesn't exist - gameLocal.Warning("Source file doesn't exist: %s", src.c_str()); - return true; - } - - // get the destination file's time - if ( !force && ( fileSystem->ReadFile( dest, NULL, &destTime ) >= 0 ) ) { - idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); - - parser.LoadFile( dest ); - - // read the file version - if ( parser.CheckTokenString( MD5_VERSION_STRING ) ) { - version = parser.ParseInt(); - - // check the command line - if ( parser.CheckTokenString( "commandline" ) ) { - parser.ReadToken( &cmdLine ); - - // check the file time, scale, and version - if ( ( destTime >= sourceTime ) && ( version == MD5_VERSION ) && ( cmdLine == commandLine ) ) { - // don't convert it - return true; - } - } - } - } - - // if this is the first time we've been run, check if Maya is installed and load our DLL - if ( !initialized ) { - initialized = true; - - if ( !CheckMayaInstall() ) { - Maya_Error = "Maya not installed in registry."; - return false; - } - - LoadMayaDll(); - - // check if our DLL got loaded - if ( !Maya_ConvertModel ) { - Maya_Error = "Could not load MayaImport dll."; - return false; - } - } - - // we need to make sure we have a full path, so convert the filename to an OS path - src = fileSystem->RelativePathToOSPath( src ); - dest = fileSystem->RelativePathToOSPath( dest ); - - dest.ExtractFilePath( path ); - if ( path.Length() ) { - fileSystem->CreateOSPath( path ); - } - - // get the os path in case it needs to create one - path = fileSystem->RelativePathToOSPath( "" ); - - common->SetRefreshOnPrint( true ); - Maya_Error = Maya_ConvertModel( path, commandLine ); - common->SetRefreshOnPrint( false ); - if ( Maya_Error != "Ok" ) { - return false; - } - - // conversion succeded - return true; -} - -/* -==================== -idModelExport::Reset -==================== -*/ -void idModelExport::Reset( void ) { - force = false; - commandLine = ""; - src = ""; - dest = ""; -} - -/* -==================== -idModelExport::ExportModel -==================== -*/ -bool idModelExport::ExportModel( const char *model ) { - const char *game = cvarSystem->GetCVarString( "fs_game" ); - if ( strlen(game) == 0 ) { - game = BASE_GAMEDIR; - } - - Reset(); - src = model; - dest = model; - dest.SetFileExtension( MD5_MESH_EXT ); - - sprintf( commandLine, "mesh %s -dest %s -game %s", src.c_str(), dest.c_str(), game ); - if ( !ConvertMayaToMD5() ) { - gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); - return false; - } - - return true; -} - -/* -==================== -idModelExport::ExportAnim -==================== -*/ -bool idModelExport::ExportAnim( const char *anim ) { - const char *game = cvarSystem->GetCVarString( "fs_game" ); - if ( strlen(game) == 0 ) { - game = BASE_GAMEDIR; - } - - Reset(); - src = anim; - dest = anim; - dest.SetFileExtension( MD5_ANIM_EXT ); - - sprintf( commandLine, "anim %s -dest %s -game %s", src.c_str(), dest.c_str(), game ); - if ( !ConvertMayaToMD5() ) { - gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); - return false; - } - - return true; -} - -/* -==================== -idModelExport::ParseOptions -==================== -*/ -bool idModelExport::ParseOptions( idLexer &lex ) { - idToken token; - idStr destdir; - idStr sourcedir; - - if ( !lex.ReadToken( &token ) ) { - lex.Error( "Expected filename" ); - return false; - } - - src = token; - dest = token; - - while( lex.ReadToken( &token ) ) { - if ( token == "-" ) { - if ( !lex.ReadToken( &token ) ) { - lex.Error( "Expecting option" ); - return false; - } - if ( token == "sourcedir" ) { - if ( !lex.ReadToken( &token ) ) { - lex.Error( "Missing pathname after -sourcedir" ); - return false; - } - sourcedir = token; - } else if ( token == "destdir" ) { - if ( !lex.ReadToken( &token ) ) { - lex.Error( "Missing pathname after -destdir" ); - return false; - } - destdir = token; - } else if ( token == "dest" ) { - if ( !lex.ReadToken( &token ) ) { - lex.Error( "Missing filename after -dest" ); - return false; - } - dest = token; - } else { - commandLine += va( " -%s", token.c_str() ); - } - } else { - commandLine += va( " %s", token.c_str() ); - } - } - - if ( sourcedir.Length() ) { - src.StripPath(); - sourcedir.BackSlashesToSlashes(); - sprintf( src, "%s/%s", sourcedir.c_str(), src.c_str() ); - } - - if ( destdir.Length() ) { - dest.StripPath(); - destdir.BackSlashesToSlashes(); - sprintf( dest, "%s/%s", destdir.c_str(), dest.c_str() ); - } - - return true; -} - -/* -==================== -idModelExport::ParseExportSection -==================== -*/ -int idModelExport::ParseExportSection( idParser &parser ) { - idToken command; - idToken token; - idStr defaultCommands; - idLexer lex; - idStr temp; - idStr parms; - int count; - - // only export sections that match our export mask - if ( g_exportMask.GetString()[ 0 ] ) { - if ( parser.CheckTokenString( "{" ) ) { - parser.SkipBracedSection( false ); - return 0; - } - - parser.ReadToken( &token ); - if ( token.Icmp( g_exportMask.GetString() ) ) { - parser.SkipBracedSection(); - return 0; - } - parser.ExpectTokenString( "{" ); - } else if ( !parser.CheckTokenString( "{" ) ) { - // skip the export mask - parser.ReadToken( &token ); - parser.ExpectTokenString( "{" ); - } - - count = 0; - - lex.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); - - // Save the command's filename - const char* currentFileName = parser.GetFileName(); - - while( 1 ) { - - if ( !parser.ReadToken( &command ) ) { - parser.Error( "Unexpected end-of-file" ); - break; - } - - if ( command == "}" ) { - break; - } - - if ( command == "options" ) { - parser.ParseRestOfLine( defaultCommands ); - } else if ( command == "addoptions" ) { - parser.ParseRestOfLine( temp ); - defaultCommands += " "; - defaultCommands += temp; - } else if ( ( command == "mesh" ) || ( command == "anim" ) || ( command == "camera" ) ) { - if ( !parser.ReadToken( &token ) ) { - parser.Error( "Expected filename" ); - } - - temp = token; - parser.ParseRestOfLine( parms ); - - if ( defaultCommands.Length() ) { - sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() ); - } - - if ( parms.Length() ) { - sprintf( temp, "%s %s", temp.c_str(), parms.c_str() ); - } - - lex.LoadMemory( temp, temp.Length(), parser.GetFileName() ); - - Reset(); - if ( ParseOptions( lex ) ) { - const char *game = cvarSystem->GetCVarString( "fs_game" ); - if ( strlen(game) == 0 ) { - game = BASE_GAMEDIR; - } - - if ( command == "mesh" ) { - dest.SetFileExtension( MD5_MESH_EXT ); - } else if ( command == "anim" ) { - dest.SetFileExtension( MD5_ANIM_EXT ); - } else if ( command == "camera" ) { - dest.SetFileExtension( MD5_CAMERA_EXT ); - } else { - dest.SetFileExtension( command ); - } - idStr back = commandLine; - sprintf( commandLine, "%s %s -dest %s -game %s%s", command.c_str(), src.c_str(), dest.c_str(), game, commandLine.c_str() ); - if ( ConvertMayaToMD5() ) { - count++; - } else { - parser.Warning( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); - } - } - lex.FreeSource(); - } else { - parser.Error( "Unknown token: '%s' on line %i, file '%s'", command.c_str(), command.line, currentFileName ); - parser.SkipBracedSection( false ); - break; - } - } - - return count; -} - -/* -================ -idModelExport::ExportDefFile -================ -*/ -int idModelExport::ExportDefFile( const char *filename ) { - idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); - idToken token; - int count; - - count = 0; - - if ( !parser.LoadFile( filename ) ) { - gameLocal.Printf( "Could not load '%s'\n", filename ); - return 0; - } - - while( parser.ReadToken( &token ) ) { - if ( token == "export" ) { - count += ParseExportSection( parser ); - } else { - parser.ReadToken( &token ); - parser.SkipBracedSection(); - } - } - - return count; -} - -/* -================ -idModelExport::ExportModels -================ -*/ -int idModelExport::ExportModels( const char *pathname, const char *extension ) { - int count; - - count = 0; - - idFileList *files; - int i; - - if ( !CheckMayaInstall() ) { - // if Maya isn't installed, don't bother checking if we have anims to export - return 0; - } - - gameLocal.Printf( "--------- Exporting models --------\n" ); - if ( !g_exportMask.GetString()[ 0 ] ) { - gameLocal.Printf( " Export mask: '%s'\n", g_exportMask.GetString() ); - } - - count = 0; - - files = fileSystem->ListFiles( pathname, extension ); - for( i = 0; i < files->GetNumFiles(); i++ ) { - count += ExportDefFile( va( "%s/%s", pathname, files->GetFile( i ) ) ); - } - fileSystem->FreeFileList( files ); - - gameLocal.Printf( "...%d models exported.\n", count ); - gameLocal.Printf( "-----------------------------------\n" ); - - return count; -} diff --git a/game/anim/anim_testmodel.cpp b/game/anim/anim_testmodel.cpp deleted file mode 100644 index 889df00f2..000000000 --- a/game/anim/anim_testmodel.cpp +++ /dev/null @@ -1,955 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* -============================================================================= - - MODEL TESTING - -Model viewing can begin with either "testmodel " - -The names must be the full pathname after the basedir, like -"models/weapons/v_launch/tris.md3" or "players/male/tris.md3" - -Extension will default to ".ase" if not specified. - -Testmodel will create a fake entity 100 units in front of the current view -position, directly facing the viewer. It will remain immobile, so you can -move around it to view it from different angles. - - g_testModelRotate - g_testModelAnimate - g_testModelBlend - -============================================================================= -*/ - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idAnimatedEntity, idTestModel ) - EVENT( EV_FootstepLeft, idTestModel::Event_Footstep ) - EVENT( EV_FootstepRight, idTestModel::Event_Footstep ) -END_CLASS - -/* -================ -idTestModel::idTestModel -================ -*/ -idTestModel::idTestModel() { - head = NULL; - headAnimator = NULL; - anim = 0; - headAnim = 0; - starttime = 0; - animtime = 0; - mode = 0; - frame = 0; -} - -/* -================ -idTestModel::Save -================ -*/ -void idTestModel::Save( idSaveGame *savefile ) { -} - -/* -================ -idTestModel::Restore -================ -*/ -void idTestModel::Restore( idRestoreGame *savefile ) { - // FIXME: one day we may actually want to save/restore test models, but for now we'll just delete them - delete this; -} - -/* -================ -idTestModel::Spawn -================ -*/ -void idTestModel::Spawn( void ) { - idVec3 size; - idBounds bounds; - jointHandle_t joint; - idStr jointName; - idVec3 origin, modelOffset; - idMat3 axis; - copyJoints_t copyJoint; - - if ( renderEntity.hModel && renderEntity.hModel->IsDefaultModel() && !animator.ModelDef() ) { - gameLocal.Warning( "Unable to create testmodel for '%s' : model defaulted", spawnArgs.GetString( "model" ) ); - PostEventMS( &EV_Remove, 0 ); - return; - } - - mode = g_testModelAnimate.GetInteger(); - animator.RemoveOriginOffset( g_testModelAnimate.GetInteger() == 1 ); - - physicsObj.SetSelf( this ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - - if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) ) { - spawnArgs.GetVector( "maxs", NULL, bounds[1] ); - physicsObj.SetClipBox( bounds, 1.0f ); - physicsObj.SetContents( 0 ); - } else if ( spawnArgs.GetVector( "size", NULL, size ) ) { - bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f ); - bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z ); - physicsObj.SetClipBox( bounds, 1.0f ); - physicsObj.SetContents( 0 ); - } - - spawnArgs.GetVector( "offsetModel", "0 0 0", modelOffset ); - - // add the head model if it has one - idStr headModelDefName = spawnArgs.GetString( "def_head" ); - - if ( !headModelDefName.IsEmpty() ) - { - jointName = spawnArgs.GetString( "head_joint" ); - - if (jointName.IsEmpty()) - { - // greebo: Second chance, use the CVAR, if no head_joint defined - g_testModelHeadJoint.GetString(); - } - - if (jointName.IsEmpty()) - { - jointName = "Spine2"; // fall back to hardcoded - } - - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) - { - gameLocal.Warning( "Joint '%s' not found for 'head_joint'", jointName.c_str() ); - } - else - { - idDict args; - - const idDeclEntityDef* def = gameLocal.FindEntityDef(headModelDefName, false); - - if (def == NULL) - { - gameLocal.Warning("Could not find head entityDef %s!", headModelDefName.c_str()); - - // Try to fallback on the default head entityDef - def = gameLocal.FindEntityDef(TDM_HEAD_ENTITYDEF, false); - } - - if (def != NULL) - { - // Make a copy of the default spawnargs - args = def->dict; - } - else - { - gameLocal.Warning("Could not find head entityDef %s or %s!", headModelDefName.c_str(), TDM_HEAD_ENTITYDEF); - } - - // Copy any sounds in case we have frame commands on the head - for (const idKeyValue* kv = spawnArgs.MatchPrefix("snd_", NULL); kv != NULL; kv = spawnArgs.MatchPrefix("snd_", kv)) - { - args.Set(kv->GetKey(), kv->GetValue()); - } - - head = gameLocal.SpawnEntityType( idAnimatedEntity::Type, &args ); - animator.GetJointTransform( joint, gameLocal.time, origin, axis ); - origin = GetPhysics()->GetOrigin() + ( origin + modelOffset ) * GetPhysics()->GetAxis(); - - // Retrieve the actual model from the head entityDef - idStr headModel = args.GetString("model"); - if (headModel.IsEmpty()) - { - gameLocal.Warning("No 'model' spawnarg on head entityDef: %s", headModelDefName.c_str()); - } - - head.GetEntity()->SetModel( headModel ); - head.GetEntity()->SetOrigin( origin ); - head.GetEntity()->SetAxis( GetPhysics()->GetAxis() ); - head.GetEntity()->BindToJoint( this, animator.GetJointName( joint ), true ); - - headAnimator = head.GetEntity()->GetAnimator(); - - // set up the list of joints to copy to the head - for(const idKeyValue* kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) - { - jointName = kv->GetKey(); - - if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) { - copyJoint.mod = JOINTMOD_WORLD_OVERRIDE; - } else { - jointName.StripLeadingOnce( "copy_joint " ); - copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE; - } - - copyJoint.from = animator.GetJointHandle( jointName ); - if ( copyJoint.from == INVALID_JOINT ) { - gameLocal.Warning( "Unknown copy_joint '%s'", jointName.c_str() ); - continue; - } - - copyJoint.to = headAnimator->GetJointHandle( jointName ); - if ( copyJoint.to == INVALID_JOINT ) { - gameLocal.Warning( "Unknown copy_joint '%s' on head", jointName.c_str() ); - continue; - } - - copyJoints.Append( copyJoint ); - } - } - } - - // start any shader effects based off of the spawn time - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - SetPhysics( &physicsObj ); - - gameLocal.Printf( "Added testmodel at origin = '%s', angles = '%s'\n", GetPhysics()->GetOrigin().ToString(), GetPhysics()->GetAxis().ToAngles().ToString() ); - BecomeActive( TH_THINK ); -} - -/* -================ -idTestModel::~idTestModel -================ -*/ -idTestModel::~idTestModel() { - StopSound( SND_CHANNEL_ANY, false ); - if ( renderEntity.hModel ) { - gameLocal.Printf( "Removing testmodel %s\n", renderEntity.hModel->Name() ); - } else { - gameLocal.Printf( "Removing testmodel\n" ); - } - if ( gameLocal.testmodel == this ) { - gameLocal.testmodel = NULL; - } - if ( head.GetEntity() ) { - head.GetEntity()->StopSound( SND_CHANNEL_ANY, false ); - head.GetEntity()->PostEventMS( &EV_Remove, 0 ); - } -} - -/* -=============== -idTestModel::Event_Footstep -=============== -*/ -void idTestModel::Event_Footstep( void ) { - StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL ); -} - -/* -================ -idTestModel::ShouldConstructScriptObjectAtSpawn - -Called during idEntity::Spawn to see if it should construct the script object or not. -Overridden by subclasses that need to spawn the script object themselves. -================ -*/ -bool idTestModel::ShouldConstructScriptObjectAtSpawn( void ) const { - return false; -} - -/* -================ -idTestModel::Think -================ -*/ -void idTestModel::Think( void ) { - idVec3 pos; - idMat3 axis; - idAngles ang; - int i; - - if ( thinkFlags & TH_THINK ) { - if ( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) ) { - StopSound( SND_CHANNEL_ANY, false ); - if ( head.GetEntity() ) { - head.GetEntity()->StopSound( SND_CHANNEL_ANY, false ); - } - switch( g_testModelAnimate.GetInteger() ) { - default: - case 0: - // cycle anim with origin reset - if ( animator.NumFrames( anim ) <= 1 ) { - // single frame animations end immediately, so just cycle it since it's the same result - animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - if ( headAnim ) { - headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - } else { - animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - if ( headAnim ) { - headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { - // loop the body anim when the head anim is longer - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); - } - } - } - animator.RemoveOriginOffset( false ); - break; - - case 1: - // cycle anim with fixed origin - animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - animator.RemoveOriginOffset( true ); - if ( headAnim ) { - headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - break; - - case 2: - // cycle anim with continuous origin - animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - animator.RemoveOriginOffset( false ); - if ( headAnim ) { - headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - break; - - case 3: - // frame by frame with continuous origin - animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - animator.RemoveOriginOffset( false ); - if ( headAnim ) { - headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - break; - - case 4: - // play anim once - animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - animator.RemoveOriginOffset( false ); - if ( headAnim ) { - headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - break; - - case 5: - // frame by frame with fixed origin - animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - animator.RemoveOriginOffset( true ); - if ( headAnim ) { - headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - } - break; - } - - mode = g_testModelAnimate.GetInteger(); - } - - if ( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) ) { - starttime = gameLocal.time; - StopSound( SND_CHANNEL_ANY, false ); - animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - if ( headAnim ) { - headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); - if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { - // loop the body anim when the head anim is longer - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); - } - } - } - - if ( headAnimator ) { - // copy the animation from the body to the head - for( i = 0; i < copyJoints.Num(); i++ ) { - if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) { - idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose(); - GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); - pos -= head.GetEntity()->GetPhysics()->GetOrigin(); - headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat ); - headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat ); - } else { - animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); - headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos ); - headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis ); - } - } - } - - // update rotation - RunPhysics(); - - physicsObj.GetAngles( ang ); - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero ); - - idClipModel *clip = physicsObj.GetClipModel(); - if ( clip && animator.ModelDef() ) { - idVec3 neworigin; - idMat3 axis; - jointHandle_t joint; - - joint = animator.GetJointHandle( "origin" ); - animator.GetJointTransform( joint, gameLocal.time, neworigin, axis ); - neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin(); - clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() ); - } - } - - UpdateAnimation(); - Present(); - - if ( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim ) { - gameLocal.Printf( "^5 Anim: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), - animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); - if ( headAnim ) { - gameLocal.Printf( "^5 Head: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); - } else { - gameLocal.Printf( "\n\n" ); - } - } -} - -/* -================ -idTestModel::NextAnim -================ -*/ -void idTestModel::NextAnim( const idCmdArgs &args ) { - if ( !animator.NumAnims() ) { - return; - } - - anim++; - if ( anim >= animator.NumAnims() ) { - // anim 0 is no anim - anim = 1; - } - - starttime = gameLocal.time; - animtime = animator.AnimLength( anim ); - animname = animator.AnimFullName( anim ); - headAnim = 0; - if ( headAnimator ) { - headAnimator->ClearAllAnims( gameLocal.time, 0 ); - headAnim = headAnimator->GetAnim( animname ); - if ( !headAnim ) { - headAnim = headAnimator->GetAnim( "idle" ); - } - - if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { - animtime = headAnimator->AnimLength( headAnim ); - } - } - - gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); - if ( headAnim ) { - gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) ); - } - - // reset the anim - mode = -1; - frame = 1; -} - -/* -================ -idTestModel::PrevAnim -================ -*/ -void idTestModel::PrevAnim( const idCmdArgs &args ) { - if ( !animator.NumAnims() ) { - return; - } - - headAnim = 0; - anim--; - if ( anim < 0 ) { - anim = animator.NumAnims() - 1; - } - - starttime = gameLocal.time; - animtime = animator.AnimLength( anim ); - animname = animator.AnimFullName( anim ); - headAnim = 0; - if ( headAnimator ) { - headAnimator->ClearAllAnims( gameLocal.time, 0 ); - headAnim = headAnimator->GetAnim( animname ); - if ( !headAnim ) { - headAnim = headAnimator->GetAnim( "idle" ); - } - - if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { - animtime = headAnimator->AnimLength( headAnim ); - } - } - - gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); - if ( headAnim ) { - gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) ); - } - - // reset the anim - mode = -1; - frame = 1; -} - -/* -================ -idTestModel::NextFrame -================ -*/ -void idTestModel::NextFrame( const idCmdArgs &args ) { - if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) { - return; - } - - frame++; - if ( frame > animator.NumFrames( anim ) ) { - frame = 1; - } - - gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) ); - - // reset the anim - mode = -1; -} - -/* -================ -idTestModel::PrevFrame -================ -*/ -void idTestModel::PrevFrame( const idCmdArgs &args ) { - if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) { - return; - } - - frame--; - if ( frame < 1 ) { - frame = animator.NumFrames( anim ); - } - - gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) ); - - // reset the anim - mode = -1; -} - -/* -================ -idTestModel::TestAnim -================ -*/ -void idTestModel::TestAnim( const idCmdArgs &args ) { - idStr name; - int animNum; - const idAnim *newanim; - - if ( args.Argc() < 2 ) { - gameLocal.Printf( "usage: testanim \n" ); - return; - } - - newanim = NULL; - - name = args.Argv( 1 ); -#if 0 - if ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) { - const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ]; - idModelExport exporter; - exporter.ExportAnim( name ); - name.SetFileExtension( MD5_ANIM_EXT ); - md5anims[ 0 ] = animationLib.GetAnim( name ); - if ( md5anims[ 0 ] ) { - customAnim.SetAnim( animator.ModelDef(), name, name, 1, md5anims ); - newanim = &customAnim; - } - } else { - animNum = animator.GetAnim( name ); - } -#else - animNum = animator.GetAnim( name ); -#endif - - if ( !animNum ) { - gameLocal.Printf( "Animation '%s' not found.\n", name.c_str() ); - return; - } - - anim = animNum; - starttime = gameLocal.time; - animtime = animator.AnimLength( anim ); - headAnim = 0; - if ( headAnimator ) { - headAnimator->ClearAllAnims( gameLocal.time, 0 ); - headAnim = headAnimator->GetAnim( animname ); - if ( !headAnim ) { - headAnim = headAnimator->GetAnim( "idle" ); - if ( !headAnim ) { - gameLocal.Printf( "Missing 'idle' anim for head.\n" ); - } - } - - if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) { - animtime = headAnimator->AnimLength( headAnim ); - } - } - - animname = name; - gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) ); - - // reset the anim - mode = -1; -} - -/* -===================== -idTestModel::BlendAnim -===================== -*/ -void idTestModel::BlendAnim( const idCmdArgs &args ) { - int anim1; - int anim2; - - if ( args.Argc() < 4 ) { - gameLocal.Printf( "usage: testblend \n" ); - return; - } - - anim1 = gameLocal.testmodel->animator.GetAnim( args.Argv( 1 ) ); - if ( !anim1 ) { - gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 1 ) ); - return; - } - - anim2 = gameLocal.testmodel->animator.GetAnim( args.Argv( 2 ) ); - if ( !anim2 ) { - gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 2 ) ); - return; - } - - animname = args.Argv( 2 ); - animator.CycleAnim( ANIMCHANNEL_ALL, anim1, gameLocal.time, 0 ); - animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, FRAME2MS( atoi( args.Argv( 3 ) ) ) ); - - anim = anim2; - headAnim = 0; -} - -/*********************************************************************** - - Testmodel console commands - -***********************************************************************/ - -/* -================= -idTestModel::KeepTestModel_f - -Makes the current test model permanent, allowing you to place -multiple test models -================= -*/ -void idTestModel::KeepTestModel_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No active testModel.\n" ); - return; - } - - gameLocal.Printf( "modelDef %p kept\n", gameLocal.testmodel->renderEntity.hModel ); - - gameLocal.testmodel = NULL; -} - -/* -================= -idTestModel::TestSkin_f - -Sets a skin on an existing testModel -================= -*/ -void idTestModel::TestSkin_f( const idCmdArgs &args ) { - idVec3 offset; - idStr name; - idPlayer * player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - // delete the testModel if active - if ( !gameLocal.testmodel ) { - common->Printf( "No active testModel\n" ); - return; - } - - if ( args.Argc() < 2 ) { - common->Printf( "removing testSkin.\n" ); - gameLocal.testmodel->SetSkin( NULL ); - return; - } - - name = args.Argv( 1 ); - gameLocal.testmodel->SetSkin( declManager->FindSkin( name ) ); -} - -/* -================= -idTestModel::TestShaderParm_f - -Sets a shaderParm on an existing testModel -================= -*/ -void idTestModel::TestShaderParm_f( const idCmdArgs &args ) { - idVec3 offset; - idStr name; - idPlayer * player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - // delete the testModel if active - if ( !gameLocal.testmodel ) { - common->Printf( "No active testModel\n" ); - return; - } - - if ( args.Argc() != 3 ) { - common->Printf( "USAGE: testShaderParm \n" ); - return; - } - - int parm = atoi( args.Argv( 1 ) ); - if ( parm < 0 || parm >= MAX_ENTITY_SHADER_PARMS ) { - common->Printf( "parmNum %i out of range\n", parm ); - return; - } - - float value; - if ( !idStr::Icmp( args.Argv( 2 ), "time" ) ) { - value = gameLocal.time * -0.001; - } else { - value = atof( args.Argv( 2 ) ); - } - - gameLocal.testmodel->SetShaderParm( parm, value ); -} - -/* -================= -idTestModel::TestModel_f - -Creates a static modelDef in front of the current position, which -can then be moved around -================= -*/ -void idTestModel::TestModel_f( const idCmdArgs &args ) { - idVec3 offset; - idStr name; - idPlayer * player; - const idDict * entityDef; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - // delete the testModel if active - if ( gameLocal.testmodel ) { - delete gameLocal.testmodel; - gameLocal.testmodel = NULL; - } - - if ( args.Argc() < 2 ) { - return; - } - - name = args.Argv( 1 ); - - entityDef = gameLocal.FindEntityDefDict( name, false ); - if ( entityDef ) { - dict = *entityDef; - } else { - if ( declManager->FindType( DECL_MODELDEF, name, false ) ) { - dict.Set( "model", name ); - } else { - // allow map models with underscore prefixes to be tested during development - // without appending an ase - if ( name[ 0 ] != '_' ) { - name.DefaultFileExtension( ".ase" ); - } - - if ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) { - idModelExport exporter; - exporter.ExportModel( name ); - name.SetFileExtension( MD5_MESH_EXT ); - } - - if ( !renderModelManager->CheckModel( name ) ) { - gameLocal.Printf( "Can't register model\n" ); - return; - } - dict.Set( "model", name ); - } - } - - offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f; - - dict.Set( "origin", offset.ToString() ); - dict.Set( "angle", va( "%f", player->viewAngles.yaw + 180.0f ) ); - dict.Set( "def_head", g_testModelHead.GetString()); - gameLocal.testmodel = ( idTestModel * )gameLocal.SpawnEntityType( idTestModel::Type, &dict ); - gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); -} - -/* -===================== -idTestModel::ArgCompletion_TestModel -===================== -*/ -void idTestModel::ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ) { - int i, num; - - num = declManager->GetNumDecls( DECL_ENTITYDEF ); - for ( i = 0; i < num; i++ ) { - callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_ENTITYDEF, i , false )->GetName() ); - } - num = declManager->GetNumDecls( DECL_MODELDEF ); - for ( i = 0; i < num; i++ ) { - callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_MODELDEF, i , false )->GetName() ); - } - cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", ".mb", NULL ); -} - -/* -===================== -idTestModel::TestParticleStopTime_f -===================== -*/ -void idTestModel::TestParticleStopTime_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time ); - gameLocal.testmodel->UpdateVisuals(); -} - -/* -===================== -idTestModel::TestAnim_f -===================== -*/ -void idTestModel::TestAnim_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->TestAnim( args ); -} - - -/* -===================== -idTestModel::ArgCompletion_TestAnim -===================== -*/ -void idTestModel::ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ) { - if ( gameLocal.testmodel ) { - idAnimator *animator = gameLocal.testmodel->GetAnimator(); - for( int i = 0; i < animator->NumAnims(); i++ ) { - callback( va( "%s %s", args.Argv( 0 ), animator->AnimFullName( i ) ) ); - } - } -} - -/* -===================== -idTestModel::TestBlend_f -===================== -*/ -void idTestModel::TestBlend_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->BlendAnim( args ); -} - -/* -===================== -idTestModel::TestModelNextAnim_f -===================== -*/ -void idTestModel::TestModelNextAnim_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->NextAnim( args ); -} - -/* -===================== -idTestModel::TestModelPrevAnim_f -===================== -*/ -void idTestModel::TestModelPrevAnim_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->PrevAnim( args ); -} - -/* -===================== -idTestModel::TestModelNextFrame_f -===================== -*/ -void idTestModel::TestModelNextFrame_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->NextFrame( args ); -} - -/* -===================== -idTestModel::TestModelPrevFrame_f -===================== -*/ -void idTestModel::TestModelPrevFrame_f( const idCmdArgs &args ) { - if ( !gameLocal.testmodel ) { - gameLocal.Printf( "No testModel active.\n" ); - return; - } - - gameLocal.testmodel->PrevFrame( args ); -} diff --git a/game/anim/anim_testmodel.h b/game/anim/anim_testmodel.h deleted file mode 100644 index 5cb84b46c..000000000 --- a/game/anim/anim_testmodel.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __ANIM_TESTMODEL_H__ -#define __ANIM_TESTMODEL_H__ - -/* -============================================================================================== - - idTestModel - -============================================================================================== -*/ - -class idTestModel : public idAnimatedEntity { -public: - CLASS_PROTOTYPE( idTestModel ); - - idTestModel(); - ~idTestModel(); - - void Save( idSaveGame *savefile ); - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - - virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; - - void NextAnim( const idCmdArgs &args ); - void PrevAnim( const idCmdArgs &args ); - void NextFrame( const idCmdArgs &args ); - void PrevFrame( const idCmdArgs &args ); - void TestAnim( const idCmdArgs &args ); - void BlendAnim( const idCmdArgs &args ); - - static void KeepTestModel_f( const idCmdArgs &args ); - static void TestModel_f( const idCmdArgs &args ); - static void ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void TestSkin_f( const idCmdArgs &args ); - static void TestShaderParm_f( const idCmdArgs &args ); - static void TestParticleStopTime_f( const idCmdArgs &args ); - static void TestAnim_f( const idCmdArgs &args ); - static void ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ); - static void TestBlend_f( const idCmdArgs &args ); - static void TestModelNextAnim_f( const idCmdArgs &args ); - static void TestModelPrevAnim_f( const idCmdArgs &args ); - static void TestModelNextFrame_f( const idCmdArgs &args ); - static void TestModelPrevFrame_f( const idCmdArgs &args ); - -private: - idEntityPtr head; - idAnimator *headAnimator; - idAnim customAnim; - idPhysics_Parametric physicsObj; - idStr animname; - int anim; - int headAnim; - int mode; - int frame; - int starttime; - int animtime; - - idList copyJoints; - - virtual void Think( void ); - - void Event_Footstep( void ); -}; - -#endif /* !__ANIM_TESTMODEL_H__*/ diff --git a/game/brittlefracture.cpp b/game/brittlefracture.cpp deleted file mode 100644 index dbfb98083..000000000 --- a/game/brittlefracture.cpp +++ /dev/null @@ -1,1383 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/sndProp.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -const idEventDef EV_UpdateSoundLoss( "updateSoundLoss", NULL ); -const idEventDef EV_DampenSound( "dampenSound", "d" ); - -CLASS_DECLARATION( idEntity, idBrittleFracture ) - EVENT( EV_Activate, idBrittleFracture::Event_Activate ) - EVENT( EV_Touch, idBrittleFracture::Event_Touch ) - EVENT( EV_UpdateSoundLoss, idBrittleFracture::UpdateSoundLoss ) - EVENT( EV_DampenSound, idBrittleFracture::Event_DampenSound ) -END_CLASS - -const int SHARD_ALIVE_TIME = 5000; -const int SHARD_FADE_START = 2000; - -static const char *brittleFracture_SnapshotName = "_BrittleFracture_Snapshot_"; - -/* -================ -idBrittleFracture::idBrittleFracture -================ -*/ -idBrittleFracture::idBrittleFracture( void ) { - material = NULL; - decalMaterial = NULL; - decalSize = 0.0f; - maxShardArea = 0.0f; - maxShatterRadius = 0.0f; - minShatterRadius = 0.0f; - linearVelocityScale = 0.0f; - angularVelocityScale = 0.0f; - shardMass = 0.0f; - density = 0.0f; - friction = 0.0f; - bouncyness = 0.0f; - fxFracture.Clear(); - - bounds.Clear(); - disableFracture = false; - - lastRenderEntityUpdate = -1; - changed = false; - - fl.networkSync = true; - - m_AreaPortal = 0; - m_bSoundDamped = false; -} - -/* -================ -idBrittleFracture::~idBrittleFracture -================ -*/ -idBrittleFracture::~idBrittleFracture( void ) { - int i; - - for ( i = 0; i < shards.Num(); i++ ) { - shards[i]->decals.DeleteContents( true ); - delete shards[i]; - } - - // make sure the render entity is freed before the model is freed - FreeModelDef(); - renderModelManager->FreeModel( renderEntity.hModel ); -} - -/* -================ -idBrittleFracture::Save -================ -*/ -void idBrittleFracture::Save( idSaveGame *savefile ) const { - int i, j; - - savefile->WriteInt( health ); - entityFlags_s flags = fl; - - LittleBitField( &flags, sizeof( flags ) ); - - savefile->Write( &flags, sizeof( flags ) ); - - - // setttings - savefile->WriteMaterial( material ); - savefile->WriteMaterial( decalMaterial ); - savefile->WriteFloat( decalSize ); - savefile->WriteFloat( maxShardArea ); - savefile->WriteFloat( maxShatterRadius ); - savefile->WriteFloat( minShatterRadius ); - savefile->WriteFloat( linearVelocityScale ); - savefile->WriteFloat( angularVelocityScale ); - savefile->WriteFloat( shardMass ); - savefile->WriteFloat( density ); - savefile->WriteFloat( friction ); - savefile->WriteFloat( bouncyness ); - savefile->WriteString( fxFracture ); - - // state - savefile->WriteBounds( bounds ); - savefile->WriteBool( disableFracture ); - - savefile->WriteInt( lastRenderEntityUpdate ); - savefile->WriteBool( changed ); - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteInt( shards.Num() ); - for ( i = 0; i < shards.Num(); i++ ) { - savefile->WriteWinding( shards[i]->winding ); - - savefile->WriteInt( shards[i]->decals.Num() ); - for ( j = 0; j < shards[i]->decals.Num(); j++ ) { - savefile->WriteWinding( *shards[i]->decals[j] ); - } - - savefile->WriteInt( shards[i]->neighbours.Num() ); - for ( j = 0; j < shards[i]->neighbours.Num(); j++ ) { - int index = shards.FindIndex(shards[i]->neighbours[j]); - assert(index != -1); - savefile->WriteInt( index ); - } - - savefile->WriteInt( shards[i]->edgeHasNeighbour.Num() ); - for ( j = 0; j < shards[i]->edgeHasNeighbour.Num(); j++ ) { - savefile->WriteBool( shards[i]->edgeHasNeighbour[j] ); - } - - savefile->WriteInt( shards[i]->droppedTime ); - savefile->WriteInt( shards[i]->islandNum ); - savefile->WriteBool( shards[i]->atEdge ); - savefile->WriteStaticObject( shards[i]->physicsObj ); - } - - savefile->WriteInt( m_AreaPortal ); - savefile->WriteBool( m_bSoundDamped ); -} - -/* -================ -idBrittleFracture::Restore -================ -*/ -void idBrittleFracture::Restore( idRestoreGame *savefile ) { - int i, j , num; - - renderEntity.hModel = renderModelManager->AllocModel(); - renderEntity.hModel->InitEmpty( brittleFracture_SnapshotName ); - renderEntity.callback = idBrittleFracture::ModelCallback; - renderEntity.noShadow = true; - renderEntity.noSelfShadow = true; - renderEntity.noDynamicInteractions = false; - - savefile->ReadInt( health ); - savefile->Read( &fl, sizeof( fl ) ); - - // setttings - savefile->ReadMaterial( material ); - savefile->ReadMaterial( decalMaterial ); - savefile->ReadFloat( decalSize ); - savefile->ReadFloat( maxShardArea ); - savefile->ReadFloat( maxShatterRadius ); - savefile->ReadFloat( minShatterRadius ); - savefile->ReadFloat( linearVelocityScale ); - savefile->ReadFloat( angularVelocityScale ); - savefile->ReadFloat( shardMass ); - savefile->ReadFloat( density ); - savefile->ReadFloat( friction ); - savefile->ReadFloat( bouncyness ); - savefile->ReadString( fxFracture ); - - // state - savefile->ReadBounds(bounds); - savefile->ReadBool( disableFracture ); - - savefile->ReadInt( lastRenderEntityUpdate ); - savefile->ReadBool( changed ); - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadInt( num ); - shards.SetNum( num ); - for ( i = 0; i < num; i++ ) { - shards[i] = new shard_t; - } - - for ( i = 0; i < num; i++ ) { - savefile->ReadWinding( shards[i]->winding ); - - savefile->ReadInt( j ); - shards[i]->decals.SetNum( j ); - for ( j = 0; j < shards[i]->decals.Num(); j++ ) { - shards[i]->decals[j] = new idFixedWinding; - savefile->ReadWinding( *shards[i]->decals[j] ); - } - - savefile->ReadInt( j ); - shards[i]->neighbours.SetNum( j ); - for ( j = 0; j < shards[i]->neighbours.Num(); j++ ) { - int index; - savefile->ReadInt( index ); - assert(index != -1); - shards[i]->neighbours[j] = shards[index]; - } - - savefile->ReadInt( j ); - shards[i]->edgeHasNeighbour.SetNum( j ); - for ( j = 0; j < shards[i]->edgeHasNeighbour.Num(); j++ ) { - savefile->ReadBool( shards[i]->edgeHasNeighbour[j] ); - } - - savefile->ReadInt( shards[i]->droppedTime ); - savefile->ReadInt( shards[i]->islandNum ); - savefile->ReadBool( shards[i]->atEdge ); - savefile->ReadStaticObject( shards[i]->physicsObj ); - if ( shards[i]->droppedTime < 0 ) { - shards[i]->clipModel = physicsObj.GetClipModel( i ); - } else { - shards[i]->clipModel = shards[i]->physicsObj.GetClipModel(); - } - } - - savefile->ReadInt( m_AreaPortal ); - savefile->ReadBool( m_bSoundDamped ); - - UpdateSoundLoss(); -} - -/* -================ -idBrittleFracture::Spawn -================ -*/ -void idBrittleFracture::Spawn( void ) { - - // get shard properties - decalMaterial = declManager->FindMaterial( spawnArgs.GetString( "mtr_decal" ) ); - decalSize = spawnArgs.GetFloat( "decalSize", "40" ); - maxShardArea = spawnArgs.GetFloat( "maxShardArea", "200" ); - maxShardArea = idMath::ClampFloat( 100, 10000, maxShardArea ); - maxShatterRadius = spawnArgs.GetFloat( "maxShatterRadius", "40" ); - minShatterRadius = spawnArgs.GetFloat( "minShatterRadius", "10" ); - linearVelocityScale = spawnArgs.GetFloat( "linearVelocityScale", "0.1" ); - angularVelocityScale = spawnArgs.GetFloat( "angularVelocityScale", "40" ); - fxFracture = spawnArgs.GetString( "fx" ); - - // get rigid body properties - shardMass = spawnArgs.GetFloat( "shardMass", "20" ); - shardMass = idMath::ClampFloat( 0.001f, 1000.0f, shardMass ); - spawnArgs.GetFloat( "density", "0.1", density ); - density = idMath::ClampFloat( 0.001f, 1000.0f, density ); - spawnArgs.GetFloat( "friction", "0.4", friction ); - friction = idMath::ClampFloat( 0.0f, 1.0f, friction ); - spawnArgs.GetFloat( "bouncyness", "0.01", bouncyness ); - bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); - - disableFracture = spawnArgs.GetBool( "disableFracture", "0" ); - health = spawnArgs.GetInt( "health", "40" ); - fl.takedamage = true; - - // FIXME: set "bleed" so idProjectile calls AddDamageEffect - spawnArgs.SetBool( "bleed", 1 ); - - CreateFractures( renderEntity.hModel ); - - FindNeighbours(); - - renderEntity.hModel = renderModelManager->AllocModel(); - renderEntity.hModel->InitEmpty( brittleFracture_SnapshotName ); - renderEntity.callback = idBrittleFracture::ModelCallback; - renderEntity.noShadow = true; - renderEntity.noSelfShadow = true; - renderEntity.noDynamicInteractions = false; - - // Dark Mod: see if we are on a visportal - m_AreaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); - - //schedule updating the sound loss for after soundprop gameplay has initialized - PostEventMS( &EV_UpdateSoundLoss, 0 ); -} - -/* -================ -idBrittleFracture::AddShard -================ -*/ -void idBrittleFracture::AddShard( idClipModel *clipModel, idFixedWinding &w ) { - shard_t *shard = new shard_t; - shard->clipModel = clipModel; - shard->droppedTime = -1; - shard->winding = w; - shard->decals.Clear(); - shard->edgeHasNeighbour.AssureSize( w.GetNumPoints(), false ); - shard->neighbours.Clear(); - shard->atEdge = false; - shards.Append( shard ); -} - -/* -================ -idBrittleFracture::RemoveShard -================ -*/ -void idBrittleFracture::RemoveShard( int index ) { -// int i; // grayman - commented to stop compiler complaint - - delete shards[index]; - shards.RemoveIndex( index, false ); // Tels: false => don't bother to keep shards sorted - physicsObj.RemoveIndex( index, false ); - - // Tels: When we used RemoveIndex(), that might have moved some shards - // after index, so we needed to set the correct ID back to the climodel - // again. Now the RemoveIndex(index,false) routine will *only* move the - // last index back to "index", so this is the only (if it exists) shard - // that got moved, so we only need to update it's clipModel ID: - /*for ( i = index; i < shards.Num(); i++ ) { - shards[i]->clipModel->SetId( i ); - }*/ - // [0,1,2,3,4,5] (remove index == 2) => [ 0,1,5,3,4 ] - if (index < shards.Num()) - { - shards[index]->clipModel->SetId( index ); - } -} - -/* -================ -idBrittleFracture::UpdateRenderEntity -================ -*/ -bool idBrittleFracture::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const { - int i, j, k, n, msec, numTris, numDecalTris; - float fade; - dword packedColor; - srfTriangles_t *tris, *decalTris; - modelSurface_t surface; - idDrawVert *v; - idPlane plane; - idMat3 tangents; - - // this may be triggered by a model trace or other non-view related source, - // to which we should look like an empty model - if ( !renderView ) { - return false; - } - - // don't regenerate it if it is current - if ( lastRenderEntityUpdate == gameLocal.time || !changed ) { - return false; - } - - lastRenderEntityUpdate = gameLocal.time; - changed = false; - - numTris = 0; - numDecalTris = 0; - for ( i = 0; i < shards.Num(); i++ ) { - n = shards[i]->winding.GetNumPoints(); - if ( n > 2 ) { - numTris += n - 2; - } - for ( k = 0; k < shards[i]->decals.Num(); k++ ) { - n = shards[i]->decals[k]->GetNumPoints(); - if ( n > 2 ) { - numDecalTris += n - 2; - } - } - } - - // FIXME: re-use model surfaces - renderEntity->hModel->InitEmpty( brittleFracture_SnapshotName ); - - // allocate triangle surfaces for the fractures and decals - tris = renderEntity->hModel->AllocSurfaceTriangles( numTris * 3, material->ShouldCreateBackSides() ? numTris * 6 : numTris * 3 ); - decalTris = renderEntity->hModel->AllocSurfaceTriangles( numDecalTris * 3, decalMaterial->ShouldCreateBackSides() ? numDecalTris * 6 : numDecalTris * 3 ); - - for ( i = 0; i < shards.Num(); i++ ) { - const idVec3 &origin = shards[i]->clipModel->GetOrigin(); - const idMat3 &axis = shards[i]->clipModel->GetAxis(); - - fade = 1.0f; - if ( shards[i]->droppedTime >= 0 ) { - msec = gameLocal.time - shards[i]->droppedTime - SHARD_FADE_START; - if ( msec > 0 ) { - fade = 1.0f - (float) msec / ( SHARD_ALIVE_TIME - SHARD_FADE_START ); - } - } - packedColor = PackColor( idVec4( renderEntity->shaderParms[ SHADERPARM_RED ] * fade, - renderEntity->shaderParms[ SHADERPARM_GREEN ] * fade, - renderEntity->shaderParms[ SHADERPARM_BLUE ] * fade, - fade ) ); - - const idWinding &winding = shards[i]->winding; - - winding.GetPlane( plane ); - tangents = ( plane.Normal() * axis ).ToMat3(); - - for ( j = 2; j < winding.GetNumPoints(); j++ ) { - - v = &tris->verts[tris->numVerts++]; - v->Clear(); - v->xyz = origin + winding[0].ToVec3() * axis; - v->st[0] = winding[0].s; - v->st[1] = winding[0].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - v = &tris->verts[tris->numVerts++]; - v->Clear(); - v->xyz = origin + winding[j-1].ToVec3() * axis; - v->st[0] = winding[j-1].s; - v->st[1] = winding[j-1].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - v = &tris->verts[tris->numVerts++]; - v->Clear(); - v->xyz = origin + winding[j].ToVec3() * axis; - v->st[0] = winding[j].s; - v->st[1] = winding[j].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - tris->indexes[tris->numIndexes++] = tris->numVerts - 3; - tris->indexes[tris->numIndexes++] = tris->numVerts - 2; - tris->indexes[tris->numIndexes++] = tris->numVerts - 1; - - if ( material->ShouldCreateBackSides() ) { - - tris->indexes[tris->numIndexes++] = tris->numVerts - 2; - tris->indexes[tris->numIndexes++] = tris->numVerts - 3; - tris->indexes[tris->numIndexes++] = tris->numVerts - 1; - } - } - - for ( k = 0; k < shards[i]->decals.Num(); k++ ) { - const idWinding &decalWinding = *shards[i]->decals[k]; - - for ( j = 2; j < decalWinding.GetNumPoints(); j++ ) { - - v = &decalTris->verts[decalTris->numVerts++]; - v->Clear(); - v->xyz = origin + decalWinding[0].ToVec3() * axis; - v->st[0] = decalWinding[0].s; - v->st[1] = decalWinding[0].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - v = &decalTris->verts[decalTris->numVerts++]; - v->Clear(); - v->xyz = origin + decalWinding[j-1].ToVec3() * axis; - v->st[0] = decalWinding[j-1].s; - v->st[1] = decalWinding[j-1].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - v = &decalTris->verts[decalTris->numVerts++]; - v->Clear(); - v->xyz = origin + decalWinding[j].ToVec3() * axis; - v->st[0] = decalWinding[j].s; - v->st[1] = decalWinding[j].t; - v->normal = tangents[0]; - v->tangents[0] = tangents[1]; - v->tangents[1] = tangents[2]; - v->SetColor( packedColor ); - - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; - - if ( decalMaterial->ShouldCreateBackSides() ) { - - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; - decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; - } - } - } - } - - tris->tangentsCalculated = true; - decalTris->tangentsCalculated = true; - - SIMDProcessor->MinMax( tris->bounds[0], tris->bounds[1], tris->verts, tris->numVerts ); - SIMDProcessor->MinMax( decalTris->bounds[0], decalTris->bounds[1], decalTris->verts, decalTris->numVerts ); - - memset( &surface, 0, sizeof( surface ) ); - surface.shader = material; - surface.id = 0; - surface.geometry = tris; - renderEntity->hModel->AddSurface( surface ); - - memset( &surface, 0, sizeof( surface ) ); - surface.shader = decalMaterial; - surface.id = 1; - surface.geometry = decalTris; - renderEntity->hModel->AddSurface( surface ); - - return true; -} - -/* -================ -idBrittleFracture::ModelCallback -================ -*/ -bool idBrittleFracture::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) { - const idBrittleFracture *ent; - - ent = static_cast(gameLocal.entities[ renderEntity->entityNum ]); - if ( !ent ) { - gameLocal.Error( "idBrittleFracture::ModelCallback: callback with NULL game entity" ); - } - - return ent->UpdateRenderEntity( renderEntity, renderView ); -} - -/* -================ -idBrittleFracture::Present -================ -*/ -void idBrittleFracture::Present() -{ - if( m_bFrobable ) - { - UpdateFrobState(); - UpdateFrobDisplay(); - } - - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) - { - return; - } - BecomeInactive( TH_UPDATEVISUALS ); - - renderEntity.bounds = bounds; - renderEntity.origin.Zero(); - renderEntity.axis.Identity(); - - // force an update because the bounds/origin/axis may stay the same while the model changes - renderEntity.forceUpdate = true; - - // add to refresh list - if ( modelDefHandle == -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } - - changed = true; -} - -/* -================ -idBrittleFracture::Think -================ -*/ -void idBrittleFracture::Think( void ) { - int i, startTime, endTime, droppedTime; - shard_t *shard; - bool atRest = true, fading = false; - - // remove overdue shards - for ( i = 0; i < shards.Num(); i++ ) { - droppedTime = shards[i]->droppedTime; - if ( droppedTime != -1 ) { - if ( gameLocal.time - droppedTime > SHARD_ALIVE_TIME ) { - RemoveShard( i ); - i--; - } - fading = true; - } - } - - // remove the entity when nothing is visible - if ( !shards.Num() ) { - PostEventMS( &EV_Remove, 0 ); - return; - } - - if ( thinkFlags & TH_PHYSICS ) { - - startTime = gameLocal.previousTime; - endTime = gameLocal.time; - - // run physics on shards - for ( i = 0; i < shards.Num(); i++ ) { - shard = shards[i]; - - if ( shard->droppedTime == -1 ) { - continue; - } - - shard->physicsObj.Evaluate( endTime - startTime, endTime ); - - if ( !shard->physicsObj.IsAtRest() ) { - atRest = false; - } - } - - if ( atRest ) { - BecomeInactive( TH_PHYSICS ); - } else { - BecomeActive( TH_PHYSICS ); - } - } - - if ( !atRest || bounds.IsCleared() ) { - bounds.Clear(); - for ( i = 0; i < shards.Num(); i++ ) { - bounds.AddBounds( shards[i]->clipModel->GetAbsBounds() ); - } - } - - if ( fading ) { - BecomeActive( TH_UPDATEVISUALS | TH_THINK ); - } else { - BecomeInactive( TH_THINK ); - } - - RunPhysics(); - Present(); -} - -/* -================ -idBrittleFracture::ApplyImpulse -================ -*/ -void idBrittleFracture::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - - if ( id < 0 || id >= shards.Num() ) { - return; - } - - if ( shards[id]->droppedTime != -1 ) { - shards[id]->physicsObj.ApplyImpulse( 0, point, impulse ); - } else if ( health <= 0 && !disableFracture ) { - Shatter( point, impulse, gameLocal.time ); - } -} - -/* -================ -idBrittleFracture::AddForce -================ -*/ -void idBrittleFracture::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { - - if ( id < 0 || id >= shards.Num() ) { - return; - } - - if ( shards[id]->droppedTime != -1 ) { - shards[id]->physicsObj.AddForce( 0, point, force ); - } else if ( health <= 0 && !disableFracture ) { - Shatter( point, force, gameLocal.time ); - } -} - -/* -================ -idBrittleFracture::ProjectDecal -================ -*/ -void idBrittleFracture::ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName ) { - int i, j, bits, clipBits; - float a, c, s; - idVec2 st[MAX_POINTS_ON_WINDING]; - idVec3 origin; - idMat3 axis, axistemp; - idPlane textureAxis[2]; - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteFloat( point[0] ); - msg.WriteFloat( point[1] ); - msg.WriteFloat( point[2] ); - msg.WriteFloat( dir[0] ); - msg.WriteFloat( dir[1] ); - msg.WriteFloat( dir[2] ); - ServerSendEvent( EVENT_PROJECT_DECAL, &msg, true, -1 ); - } - - if ( time >= gameLocal.time ) { - // try to get the sound from the damage def - const idDeclEntityDef *damageDef = NULL; - const idSoundShader *sndShader = NULL; - if ( damageDefName ) { - damageDef = gameLocal.FindEntityDef( damageDefName, false ); - if ( damageDef ) { - sndShader = declManager->FindSound( damageDef->dict.GetString( "snd_shatter", "" ) ); - } - } - - if ( sndShader ) { - StartSoundShader( sndShader, SND_CHANNEL_ANY, 0, false, NULL ); - } else { - StartSound( "snd_bullethole", SND_CHANNEL_ANY, 0, false, NULL ); - } - } - - a = gameLocal.random.RandomFloat() * idMath::TWO_PI; - c = cos( a ); - s = -sin( a ); - - axis[2] = -dir; - axis[2].Normalize(); - axis[2].NormalVectors( axistemp[0], axistemp[1] ); - axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s; - axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c; - - textureAxis[0] = axis[0] * ( 1.0f / decalSize ); - textureAxis[0][3] = -( point * textureAxis[0].Normal() ) + 0.5f; - - textureAxis[1] = axis[1] * ( 1.0f / decalSize ); - textureAxis[1][3] = -( point * textureAxis[1].Normal() ) + 0.5f; - - for ( i = 0; i < shards.Num(); i++ ) { - idFixedWinding &winding = shards[i]->winding; - origin = shards[i]->clipModel->GetOrigin(); - axis = shards[i]->clipModel->GetAxis(); - float d0, d1; - - clipBits = -1; - for ( j = 0; j < winding.GetNumPoints(); j++ ) { - idVec3 p = origin + winding[j].ToVec3() * axis; - - st[j].x = d0 = textureAxis[0].Distance( p ); - st[j].y = d1 = textureAxis[1].Distance( p ); - - bits = FLOATSIGNBITSET( d0 ); - d0 = 1.0f - d0; - bits |= FLOATSIGNBITSET( d1 ) << 2; - d1 = 1.0f - d1; - bits |= FLOATSIGNBITSET( d0 ) << 1; - bits |= FLOATSIGNBITSET( d1 ) << 3; - - clipBits &= bits; - } - - if ( clipBits ) { - continue; - } - - idFixedWinding *decal = new idFixedWinding; - shards[i]->decals.Append( decal ); - - decal->SetNumPoints( winding.GetNumPoints() ); - for ( j = 0; j < winding.GetNumPoints(); j++ ) { - (*decal)[j].ToVec3() = winding[j].ToVec3(); - (*decal)[j].s = st[j].x; - (*decal)[j].t = st[j].y; - } - } - - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idBrittleFracture::DropShard -================ -*/ -void idBrittleFracture::DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time ) { - int i, j, clipModelId; - float dist, f; - idVec3 dir2, origin; - idMat3 axis; - shard_t *neighbour; - - // don't display decals on dropped shards - shard->decals.DeleteContents( true ); - - // remove neighbour pointers of neighbours pointing to this shard - for ( i = 0; i < shard->neighbours.Num(); i++ ) { - neighbour = shard->neighbours[i]; - for ( j = 0; j < neighbour->neighbours.Num(); j++ ) { - if ( neighbour->neighbours[j] == shard ) { - neighbour->neighbours.RemoveIndex( j ); - break; - } - } - } - - // remove neighbour pointers - shard->neighbours.Clear(); - - // remove the clip model from the static physics object - clipModelId = shard->clipModel->GetId(); - physicsObj.SetClipModel( NULL, 1.0f, clipModelId, false ); - - origin = shard->clipModel->GetOrigin(); - axis = shard->clipModel->GetAxis(); - - // set the dropped time for fading - shard->droppedTime = time; - - dir2 = origin - point; - dist = dir2.Normalize(); - f = dist > maxShatterRadius ? 1.0f : idMath::Sqrt( dist - minShatterRadius ) * ( 1.0f / idMath::Sqrt( maxShatterRadius - minShatterRadius ) ); - - // setup the physics - shard->physicsObj.SetSelf( this ); - shard->physicsObj.SetClipModel( shard->clipModel, density ); - shard->physicsObj.SetMass( shardMass ); - shard->physicsObj.SetOrigin( origin ); - shard->physicsObj.SetAxis( axis ); - shard->physicsObj.SetBouncyness( bouncyness ); - shard->physicsObj.SetFriction( 0.6f, 0.6f, friction ); - shard->physicsObj.SetGravity( gameLocal.GetGravity() ); - shard->physicsObj.SetContents( CONTENTS_RENDERMODEL ); - shard->physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); - shard->physicsObj.ApplyImpulse( 0, origin, impulse * linearVelocityScale * dir ); - shard->physicsObj.SetAngularVelocity( dir.Cross( dir2 ) * ( f * angularVelocityScale ) ); - - shard->clipModel->SetId( clipModelId ); - - BecomeActive( TH_PHYSICS ); -} - -/* -================ -idBrittleFracture::Shatter -================ -*/ -void idBrittleFracture::Shatter( const idVec3 &point, const idVec3 &impulse, const int time ) { - int i; - idVec3 dir; - shard_t *shard; - float m; - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteFloat( point[0] ); - msg.WriteFloat( point[1] ); - msg.WriteFloat( point[2] ); - msg.WriteFloat( impulse[0] ); - msg.WriteFloat( impulse[1] ); - msg.WriteFloat( impulse[2] ); - ServerSendEvent( EVENT_SHATTER, &msg, true, -1 ); - } - - if ( time > ( gameLocal.time - SHARD_ALIVE_TIME ) ) - { - if( m_bSoundDamped ) - StartSound( "snd_shatter_damped", SND_CHANNEL_ANY, 0, false, NULL ); - else - StartSound( "snd_shatter", SND_CHANNEL_ANY, 0, false, NULL ); - } - - if ( !IsBroken() ) { - Break(); - } - - if ( fxFracture.Length() ) { - idEntityFx::StartFx( fxFracture, &point, &GetPhysics()->GetAxis(), this, true ); - } - - dir = impulse; - m = dir.Normalize(); - - for ( i = 0; i < shards.Num(); i++ ) { - shard = shards[i]; - - if ( shard->droppedTime != -1 ) { - continue; - } - - if ( ( shard->clipModel->GetOrigin() - point ).LengthSqr() > Square( maxShatterRadius ) ) { - continue; - } - - DropShard( shard, point, dir, m, time ); - } - - DropFloatingIslands( point, impulse, time ); -} - -/* -================ -idBrittleFracture::DropFloatingIslands -================ -*/ -void idBrittleFracture::DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time ) { - int i, j, numIslands; - int queueStart, queueEnd; - shard_t *curShard, *nextShard, **queue; - bool touchesEdge; - idVec3 dir; - - dir = impulse; - dir.Normalize(); - - numIslands = 0; - queue = (shard_t **) _alloca16( shards.Num() * sizeof(shard_t **) ); - for ( i = 0; i < shards.Num(); i++ ) { - shards[i]->islandNum = 0; - } - - for ( i = 0; i < shards.Num(); i++ ) { - - if ( shards[i]->droppedTime != -1 ) { - continue; - } - - if ( shards[i]->islandNum ) { - continue; - } - - queueStart = 0; - queueEnd = 1; - queue[0] = shards[i]; - shards[i]->islandNum = numIslands+1; - touchesEdge = false; - - if ( shards[i]->atEdge ) { - touchesEdge = true; - } - - for ( curShard = queue[queueStart]; queueStart < queueEnd; curShard = queue[++queueStart] ) { - - for ( j = 0; j < curShard->neighbours.Num(); j++ ) { - - nextShard = curShard->neighbours[j]; - - if ( nextShard->droppedTime != -1 ) { - continue; - } - - if ( nextShard->islandNum ) { - continue; - } - - queue[queueEnd++] = nextShard; - nextShard->islandNum = numIslands+1; - - if ( nextShard->atEdge ) { - touchesEdge = true; - } - } - } - numIslands++; - - // if the island is not connected to the world at any edges - if ( !touchesEdge ) { - for ( j = 0; j < queueEnd; j++ ) { - DropShard( queue[j], point, dir, 0.0f, time ); - } - } - } -} - -/* -================ -idBrittleFracture::Break -================ -*/ -void idBrittleFracture::Break( void ) { - fl.takedamage = false; - physicsObj.SetContents( CONTENTS_RENDERMODEL ); - - // ishtvan: overwrite with custom contents if present - if( m_CustomContents != -1 ) - physicsObj.SetContents( m_CustomContents ); - - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_TRIGGER ); - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - UpdateSoundLoss(); -} - -/* -================ -idBrittleFracture::IsBroken -================ -*/ -bool idBrittleFracture::IsBroken( void ) const { - return ( fl.takedamage == false ); -} - -/* -================ -idBrittleFracture::Killed -================ -*/ -void idBrittleFracture::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) -{ - bool bPlayerResponsible(false); - - if ( !disableFracture ) { - ActivateTargets( this ); - Break(); - } - - if ( attacker && attacker->IsType( idPlayer::Type ) ) - bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); - else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) - bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); - - gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); -} - -/* -================ -idBrittleFracture::AddDamageEffect -================ -*/ -void idBrittleFracture::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { - if ( !disableFracture ) { - ProjectDecal( collision.c.point, collision.c.normal, gameLocal.time, damageDefName ); - } -} - -/* -================ -idBrittleFracture::Fracture_r -================ -*/ -void idBrittleFracture::Fracture_r( idFixedWinding &w ) { - int i, j, bestPlane; - float a, c, s, dist, bestDist; - idVec3 origin; - idPlane windingPlane, splitPlanes[2]; - idMat3 axis, axistemp; - idFixedWinding back; - idTraceModel trm; - idClipModel *clipModel; - - while( 1 ) { - origin = w.GetCenter(); - w.GetPlane( windingPlane ); - - if ( w.GetArea() < maxShardArea ) { - break; - } - - // randomly create a split plane - a = gameLocal.random.RandomFloat() * idMath::TWO_PI; - c = cos( a ); - s = -sin( a ); - axis[2] = windingPlane.Normal(); - axis[2].NormalVectors( axistemp[0], axistemp[1] ); - axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s; - axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c; - - // get the best split plane - bestDist = 0.0f; - bestPlane = 0; - for ( i = 0; i < 2; i++ ) { - splitPlanes[i].SetNormal( axis[i] ); - splitPlanes[i].FitThroughPoint( origin ); - for ( j = 0; j < w.GetNumPoints(); j++ ) { - dist = splitPlanes[i].Distance( w[j].ToVec3() ); - if ( dist > bestDist ) { - bestDist = dist; - bestPlane = i; - } - } - } - - // split the winding - if ( !w.Split( &back, splitPlanes[bestPlane] ) ) { - break; - } - - // recursively create shards for the back winding - Fracture_r( back ); - } - - // translate the winding to it's center - origin = w.GetCenter(); - for ( j = 0; j < w.GetNumPoints(); j++ ) { - w[j].ToVec3() -= origin; - } - w.RemoveEqualPoints(); - - trm.SetupPolygon( w ); - trm.Shrink( CM_CLIP_EPSILON ); - clipModel = new idClipModel( trm ); - - physicsObj.SetClipModel( clipModel, 1.0f, shards.Num() ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() + origin, shards.Num() ); - physicsObj.SetAxis( GetPhysics()->GetAxis(), shards.Num() ); - - AddShard( clipModel, w ); -} - -/* -================ -idBrittleFracture::CreateFractures -================ -*/ -void idBrittleFracture::CreateFractures( const idRenderModel *renderModel ) { - int i, j, k; - const modelSurface_t *surf; - const idDrawVert *v; - idFixedWinding w; - - if ( !renderModel ) { - return; - } - - physicsObj.SetSelf( this ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin(), 0 ); - physicsObj.SetAxis( GetPhysics()->GetAxis(), 0 ); - - for ( i = 0; i < 1 /*renderModel->NumSurfaces()*/; i++ ) { - surf = renderModel->Surface( i ); - material = surf->shader; - - for ( j = 0; j < surf->geometry->numIndexes; j += 3 ) { - w.Clear(); - for ( k = 0; k < 3; k++ ) { - v = &surf->geometry->verts[ surf->geometry->indexes[ j + 2 - k ] ]; - w.AddPoint( v->xyz ); - w[k].s = v->st[0]; - w[k].t = v->st[1]; - } - Fracture_r( w ); - } - } - - physicsObj.SetContents( material->GetContentFlags() ); - // ishtvan: overwrite with custom contents if present - if( m_CustomContents != -1 ) - physicsObj.SetContents( m_CustomContents ); - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - SetPhysics( &physicsObj ); -} - -/* -================ -idBrittleFracture::FindNeighbours -================ -*/ -void idBrittleFracture::FindNeighbours( void ) { - int i, j, k, l; - idVec3 p1, p2, dir; - idMat3 axis; - idPlane plane[4]; - - for ( i = 0; i < shards.Num(); i++ ) { - - shard_t *shard1 = shards[i]; - const idWinding &w1 = shard1->winding; - const idVec3 &origin1 = shard1->clipModel->GetOrigin(); - const idMat3 &axis1 = shard1->clipModel->GetAxis(); - - for ( k = 0; k < w1.GetNumPoints(); k++ ) { - - p1 = origin1 + w1[k].ToVec3() * axis1; - p2 = origin1 + w1[(k+1)%w1.GetNumPoints()].ToVec3() * axis1; - dir = p2 - p1; - dir.Normalize(); - axis = dir.ToMat3(); - - plane[0].SetNormal( dir ); - plane[0].FitThroughPoint( p1 ); - plane[1].SetNormal( -dir ); - plane[1].FitThroughPoint( p2 ); - plane[2].SetNormal( axis[1] ); - plane[2].FitThroughPoint( p1 ); - plane[3].SetNormal( axis[2] ); - plane[3].FitThroughPoint( p1 ); - - for ( j = 0; j < shards.Num(); j++ ) { - - if ( i == j ) { - continue; - } - - shard_t *shard2 = shards[j]; - - for ( l = 0; l < shard1->neighbours.Num(); l++ ) { - if ( shard1->neighbours[l] == shard2 ) { - break; - } - } - if ( l < shard1->neighbours.Num() ) { - continue; - } - - const idWinding &w2 = shard2->winding; - const idVec3 &origin2 = shard2->clipModel->GetOrigin(); - const idMat3 &axis2 = shard2->clipModel->GetAxis(); - - for ( l = w2.GetNumPoints()-1; l >= 0; l-- ) { - p1 = origin2 + w2[l].ToVec3() * axis2; - p2 = origin2 + w2[(l-1+w2.GetNumPoints())%w2.GetNumPoints()].ToVec3() * axis2; - if ( plane[0].Side( p2, 0.1f ) == SIDE_FRONT && plane[1].Side( p1, 0.1f ) == SIDE_FRONT ) { - if ( plane[2].Side( p1, 0.1f ) == SIDE_ON && plane[3].Side( p1, 0.1f ) == SIDE_ON ) { - if ( plane[2].Side( p2, 0.1f ) == SIDE_ON && plane[3].Side( p2, 0.1f ) == SIDE_ON ) { - shard1->neighbours.Append( shard2 ); - shard1->edgeHasNeighbour[k] = true; - shard2->neighbours.Append( shard1 ); - shard2->edgeHasNeighbour[(l-1+w2.GetNumPoints())%w2.GetNumPoints()] = true; - break; - } - } - } - } - } - } - - for ( k = 0; k < w1.GetNumPoints(); k++ ) { - if ( !shard1->edgeHasNeighbour[k] ) { - break; - } - } - if ( k < w1.GetNumPoints() ) { - shard1->atEdge = true; - } else { - shard1->atEdge = false; - } - } -} - -/* -================ -idBrittleFracture::Event_Activate -================ -*/ -void idBrittleFracture::Event_Activate( idEntity *activator ) { - disableFracture = false; - if ( health <= 0 ) { - Break(); - } -} - -/* -================ -idBrittleFracture::Event_Touch -================ -*/ -void idBrittleFracture::Event_Touch( idEntity *other, trace_t *trace ) { - idVec3 point, impulse; - - if ( !IsBroken() ) { - return; - } - - if ( trace->c.id < 0 || trace->c.id >= shards.Num() ) { - return; - } - - point = shards[trace->c.id]->clipModel->GetOrigin(); - impulse = other->GetPhysics()->GetLinearVelocity() * other->GetPhysics()->GetMass(); - - Shatter( point, impulse, gameLocal.time ); -} - -/* -================ -idBrittleFracture::Event_DampenSound -================ -*/ -void idBrittleFracture::Event_DampenSound( bool bDampen ) -{ - m_bSoundDamped = bDampen; -} - -/* -================ -idBrittleFracture::ClientPredictionThink -================ -*/ -void idBrittleFracture::ClientPredictionThink( void ) { - // only think forward because the state is not synced through snapshots - if ( !gameLocal.isNewFrame ) { - return; - } - - Think(); -} - -/* -================ -idBrittleFracture::ClientReceiveEvent -================ -*/ -bool idBrittleFracture::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - idVec3 point, dir; - - switch( event ) { - case EVENT_PROJECT_DECAL: { - point[0] = msg.ReadFloat(); - point[1] = msg.ReadFloat(); - point[2] = msg.ReadFloat(); - dir[0] = msg.ReadFloat(); - dir[1] = msg.ReadFloat(); - dir[2] = msg.ReadFloat(); - ProjectDecal( point, dir, time, NULL ); - return true; - } - case EVENT_SHATTER: { - point[0] = msg.ReadFloat(); - point[1] = msg.ReadFloat(); - point[2] = msg.ReadFloat(); - dir[0] = msg.ReadFloat(); - dir[1] = msg.ReadFloat(); - dir[2] = msg.ReadFloat(); - Shatter( point, dir, time ); - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -================ -idBrittleFracture::UpdateSoundLoss (Dark Mod ) -================ -*/ -void idBrittleFracture::UpdateSoundLoss( void ) -{ - float SetVal(0.0f); - - if ( !m_AreaPortal ) - goto Quit; - - if( IsBroken() ) - SetVal = spawnArgs.GetFloat( "loss_broken", "0.0"); - else - SetVal = spawnArgs.GetFloat( "loss_unbroken", "15.0"); - - gameLocal.m_sndProp->SetPortalLoss( m_AreaPortal, SetVal ); - -Quit: - return; -} - diff --git a/game/brittlefracture.h b/game/brittlefracture.h deleted file mode 100644 index b8b0fa485..000000000 --- a/game/brittlefracture.h +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_BRITTLEFRACTURE_H__ -#define __GAME_BRITTLEFRACTURE_H__ - - -/* -=============================================================================== - -B-rep Brittle Fracture - Static entity using the boundary representation -of the render model which can fracture. - -=============================================================================== -*/ - -extern const idEventDef EV_UpdateSoundLoss; -extern const idEventDef EV_DampenSound; - -typedef struct shard_s { - idClipModel * clipModel; - idFixedWinding winding; - idList decals; - idList edgeHasNeighbour; - idList neighbours; - idPhysics_RigidBody physicsObj; - int droppedTime; - bool atEdge; - int islandNum; -} shard_t; - - -class idBrittleFracture : public idEntity { - -public: - CLASS_PROTOTYPE( idBrittleFracture ); - - idBrittleFracture( void ); - virtual ~idBrittleFracture( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - - virtual void Present( void ); - virtual void Think( void ); - virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); - virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - - void ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName ); - bool IsBroken( void ) const; - - enum { - EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS, - EVENT_SHATTER, - EVENT_MAXEVENTS - }; - - virtual void ClientPredictionThink( void ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - -private: - // setttings - const idMaterial * material; - const idMaterial * decalMaterial; - float decalSize; - float maxShardArea; - float maxShatterRadius; - float minShatterRadius; - float linearVelocityScale; - float angularVelocityScale; - float shardMass; - float density; - float friction; - float bouncyness; - idStr fxFracture; - - // state - idPhysics_StaticMulti physicsObj; - idList shards; - idBounds bounds; - bool disableFracture; - - /** TDM: Moss arrow dampens sound of shattering **/ - bool m_bSoundDamped; - - // for rendering - mutable int lastRenderEntityUpdate; - mutable bool changed; - - /** - * Contains the visportal handle that the breakable is touching, if portal is present - * If no portal is present, is set to 0. - **/ - qhandle_t m_AreaPortal; - - bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const; - static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); - - void AddShard( idClipModel *clipModel, idFixedWinding &w ); - void RemoveShard( int index ); - void DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time ); - void Shatter( const idVec3 &point, const idVec3 &impulse, const int time ); - void DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time ); - void Break( void ); - void Fracture_r( idFixedWinding &w ); - void CreateFractures( const idRenderModel *renderModel ); - void FindNeighbours( void ); - - void Event_Activate( idEntity *activator ); - void Event_Touch( idEntity *other, trace_t *trace ); - void Event_DampenSound( bool bDampen ); - - /** - * Update soundprop to set losses in associated portal, if portal is present - * Called on spawn and when it breaks - **/ - void UpdateSoundLoss( void ); -}; - -#endif /* !__GAME_BRITTLEFRACTURE_H__ */ diff --git a/game/camera.cpp b/game/camera.cpp deleted file mode 100644 index c503d3c0c..000000000 --- a/game/camera.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -=============================================================================== - - idCamera - - Base class for cameras - -=============================================================================== -*/ - -ABSTRACT_DECLARATION( idEntity, idCamera ) -END_CLASS - -/* -===================== -idCamera::Spawn -===================== -*/ -void idCamera::Spawn( void ) { -} - -/* -===================== -idCamera::GetRenderView -===================== -*/ -renderView_t *idCamera::GetRenderView() { - renderView_t *rv = idEntity::GetRenderView(); - GetViewParms( rv ); - return rv; -} - -/*********************************************************************** - - idCameraView - -***********************************************************************/ -const idEventDef EV_Camera_SetAttachments( "", NULL ); - -CLASS_DECLARATION( idCamera, idCameraView ) - EVENT( EV_Activate, idCameraView::Event_Activate ) - EVENT( EV_Camera_SetAttachments, idCameraView::Event_SetAttachments ) -END_CLASS - - -/* -=============== -idCameraView::idCameraView -================ -*/ -idCameraView::idCameraView() { - fov = 90.0f; - attachedTo = NULL; - attachedView = NULL; -} - -/* -=============== -idCameraView::Save -================ -*/ -void idCameraView::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( fov ); - savefile->WriteObject( attachedTo ); - savefile->WriteObject( attachedView ); -} - -/* -=============== -idCameraView::Restore -================ -*/ -void idCameraView::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( fov ); - savefile->ReadObject( reinterpret_cast( attachedTo ) ); - savefile->ReadObject( reinterpret_cast( attachedView ) ); -} - -/* -=============== -idCameraView::Event_SetAttachments -================ -*/ -void idCameraView::Event_SetAttachments( ) { - SetAttachment( &attachedTo, "attachedTo" ); - SetAttachment( &attachedView, "attachedView" ); -} - -/* -=============== -idCameraView::Event_Activate -================ -*/ -void idCameraView::Event_Activate( idEntity *activator ) { - if (spawnArgs.GetBool("trigger")) { - if (gameLocal.GetCamera() != this) { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() ); - } - - gameLocal.SetCamera(this); - } else { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); - } - gameLocal.SetCamera(NULL); - } - } -} - -/* -===================== -idCameraView::Stop -===================== -*/ -void idCameraView::Stop( void ) { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); - } - gameLocal.SetCamera(NULL); - ActivateTargets( gameLocal.GetLocalPlayer() ); -} - - -/* -===================== -idCameraView::Spawn -===================== -*/ -void idCameraView::SetAttachment( idEntity **e, const char *p ) { - const char *cam = spawnArgs.GetString( p ); - if ( strlen ( cam ) ) { - *e = gameLocal.FindEntity( cam ); - } -} - - -/* -===================== -idCameraView::Spawn -===================== -*/ -void idCameraView::Spawn( void ) { - // if no target specified use ourself - const char *cam = spawnArgs.GetString("cameraTarget"); - if ( strlen ( cam ) == 0) { - spawnArgs.Set("cameraTarget", spawnArgs.GetString("name")); - } - fov = spawnArgs.GetFloat("fov", "90"); - - PostEventMS( &EV_Camera_SetAttachments, 0 ); - - UpdateChangeableSpawnArgs(NULL); -} - -/* -===================== -idCameraView::GetViewParms -===================== -*/ -void idCameraView::GetViewParms( renderView_t *view ) { - assert( view ); - - if (view == NULL) { - return; - } - - idVec3 dir; - idEntity *ent; - - if ( attachedTo ) { - ent = attachedTo; - } else { - ent = this; - } - - view->vieworg = ent->GetPhysics()->GetOrigin(); - if ( attachedView ) { - dir = attachedView->GetPhysics()->GetOrigin() - view->vieworg; - dir.Normalize(); - view->viewaxis = dir.ToMat3(); - } else { - view->viewaxis = ent->GetPhysics()->GetAxis(); - } - - gameLocal.CalcFov( fov, view->fov_x, view->fov_y ); -} - -/* -=============================================================================== - - idCameraAnim - -=============================================================================== -*/ - -const idEventDef EV_Camera_Start( "start", NULL ); -const idEventDef EV_Camera_Stop( "stop", NULL ); - -CLASS_DECLARATION( idCamera, idCameraAnim ) - EVENT( EV_Thread_SetCallback, idCameraAnim::Event_SetCallback ) - EVENT( EV_Camera_Stop, idCameraAnim::Event_Stop ) - EVENT( EV_Camera_Start, idCameraAnim::Event_Start ) - EVENT( EV_Activate, idCameraAnim::Event_Activate ) -END_CLASS - - -/* -===================== -idCameraAnim::idCameraAnim -===================== -*/ -idCameraAnim::idCameraAnim() { - threadNum = 0; - offset.Zero(); - frameRate = 0; - cycle = 1; - starttime = 0; - activator = NULL; - -} - -/* -===================== -idCameraAnim::~idCameraAnim -===================== -*/ -idCameraAnim::~idCameraAnim() { - if ( gameLocal.GetCamera() == this ) { - gameLocal.SetCamera( NULL ); - } -} - -/* -=============== -idCameraAnim::Save -================ -*/ -void idCameraAnim::Save( idSaveGame *savefile ) const { - savefile->WriteInt( threadNum ); - savefile->WriteVec3( offset ); - savefile->WriteInt( frameRate ); - savefile->WriteInt( starttime ); - savefile->WriteInt( cycle ); - activator.Save( savefile ); -} - -/* -=============== -idCameraAnim::Restore -================ -*/ -void idCameraAnim::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( threadNum ); - savefile->ReadVec3( offset ); - savefile->ReadInt( frameRate ); - savefile->ReadInt( starttime ); - savefile->ReadInt( cycle ); - activator.Restore( savefile ); - - LoadAnim(); -} - -/* -===================== -idCameraAnim::Spawn -===================== -*/ -void idCameraAnim::Spawn( void ) { - if ( spawnArgs.GetVector( "old_origin", "0 0 0", offset ) ) { - offset = GetPhysics()->GetOrigin() - offset; - } else { - offset.Zero(); - } - - // always think during cinematics - cinematic = true; - - LoadAnim(); -} - -/* -================ -idCameraAnim::Load -================ -*/ -void idCameraAnim::LoadAnim( void ) { - int version; - idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT ); - idToken token; - int numFrames; - int numCuts; - int i; - idStr filename; - const char *key; - - key = spawnArgs.GetString( "anim" ); - if ( !key ) { - gameLocal.Error( "Missing 'anim' key on '%s'", name.c_str() ); - } - - filename = spawnArgs.GetString( va( "anim %s", key ) ); - if ( !filename.Length() ) { - gameLocal.Error( "Missing 'anim %s' key on '%s'", key, name.c_str() ); - } - - filename.SetFileExtension( MD5_CAMERA_EXT ); - if ( !parser.LoadFile( filename ) ) { - gameLocal.Error( "Unable to load '%s' on '%s'", filename.c_str(), name.c_str() ); - } - - cameraCuts.Clear(); - cameraCuts.SetGranularity( 1 ); - camera.Clear(); - camera.SetGranularity( 1 ); - - parser.ExpectTokenString( MD5_VERSION_STRING ); - version = parser.ParseInt(); - if ( version != MD5_VERSION ) { - parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); - } - - // skip the commandline - parser.ExpectTokenString( "commandline" ); - parser.ReadToken( &token ); - - // parse num frames - parser.ExpectTokenString( "numFrames" ); - numFrames = parser.ParseInt(); - if ( numFrames <= 0 ) { - parser.Error( "Invalid number of frames: %d", numFrames ); - } - - // parse framerate - parser.ExpectTokenString( "frameRate" ); - frameRate = parser.ParseInt(); - if ( frameRate <= 0 ) { - parser.Error( "Invalid framerate: %d", frameRate ); - } - - // parse num cuts - parser.ExpectTokenString( "numCuts" ); - numCuts = parser.ParseInt(); - if ( ( numCuts < 0 ) || ( numCuts > numFrames ) ) { - parser.Error( "Invalid number of camera cuts: %d", numCuts ); - } - - // parse the camera cuts - parser.ExpectTokenString( "cuts" ); - parser.ExpectTokenString( "{" ); - cameraCuts.SetNum( numCuts ); - for( i = 0; i < numCuts; i++ ) { - cameraCuts[ i ] = parser.ParseInt(); - if ( ( cameraCuts[ i ] < 1 ) || ( cameraCuts[ i ] >= numFrames ) ) { - parser.Error( "Invalid camera cut" ); - } - } - parser.ExpectTokenString( "}" ); - - // parse the camera frames - parser.ExpectTokenString( "camera" ); - parser.ExpectTokenString( "{" ); - camera.SetNum( numFrames ); - for( i = 0; i < numFrames; i++ ) { - parser.Parse1DMatrix( 3, camera[ i ].t.ToFloatPtr() ); - parser.Parse1DMatrix( 3, camera[ i ].q.ToFloatPtr() ); - camera[ i ].fov = parser.ParseFloat(); - } - parser.ExpectTokenString( "}" ); - -#if 0 - if ( !gameLocal.GetLocalPlayer() ) { - return; - } - - idDebugGraph gGraph; - idDebugGraph tGraph; - idDebugGraph qGraph; - idDebugGraph dtGraph; - idDebugGraph dqGraph; - gGraph.SetNumSamples( numFrames ); - tGraph.SetNumSamples( numFrames ); - qGraph.SetNumSamples( numFrames ); - dtGraph.SetNumSamples( numFrames ); - dqGraph.SetNumSamples( numFrames ); - - gameLocal.Printf( "\n\ndelta vec:\n" ); - float diff_t, last_t, t; - float diff_q, last_q, q; - diff_t = last_t = 0.0f; - diff_q = last_q = 0.0f; - for( i = 1; i < numFrames; i++ ) { - t = ( camera[ i ].t - camera[ i - 1 ].t ).Length(); - q = ( camera[ i ].q.ToQuat() - camera[ i - 1 ].q.ToQuat() ).Length(); - diff_t = t - last_t; - diff_q = q - last_q; - gGraph.AddValue( ( i % 10 ) == 0 ); - tGraph.AddValue( t ); - qGraph.AddValue( q ); - dtGraph.AddValue( diff_t ); - dqGraph.AddValue( diff_q ); - - gameLocal.Printf( "%d: %.8f : %.8f, %.8f : %.8f\n", i, t, diff_t, q, diff_q ); - last_t = t; - last_q = q; - } - - gGraph.Draw( colorBlue, 300.0f ); - tGraph.Draw( colorOrange, 60.0f ); - dtGraph.Draw( colorYellow, 6000.0f ); - qGraph.Draw( colorGreen, 60.0f ); - dqGraph.Draw( colorCyan, 6000.0f ); -#endif -} - -/* -=============== -idCameraAnim::Start -================ -*/ -void idCameraAnim::Start( void ) { - cycle = spawnArgs.GetInt( "cycle" ); - if ( !cycle ) { - cycle = 1; - } - - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() ); - } - - starttime = gameLocal.time; - gameLocal.SetCamera( this ); - BecomeActive( TH_THINK ); - - // if the player has already created the renderview for this frame, have him update it again so that the camera starts this frame - if ( gameLocal.GetLocalPlayer()->GetRenderView()->time == gameLocal.time ) { - gameLocal.GetLocalPlayer()->CalculateRenderView(); - } -} - -/* -===================== -idCameraAnim::Stop -===================== -*/ -void idCameraAnim::Stop( void ) { - if ( gameLocal.GetCamera() == this ) { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); - } - - BecomeInactive( TH_THINK ); - gameLocal.SetCamera( NULL ); - if ( threadNum ) { - idThread::ObjectMoveDone( threadNum, this ); - threadNum = 0; - } - ActivateTargets( activator.GetEntity() ); - } -} - -/* -===================== -idCameraAnim::Think -===================== -*/ -void idCameraAnim::Think( void ) { - int frame; - int frameTime; - - if ( thinkFlags & TH_THINK ) { - // check if we're done in the Think function when the cinematic is being skipped (idCameraAnim::GetViewParms isn't called when skipping cinematics). - if ( !gameLocal.skipCinematic ) { - return; - } - - if ( camera.Num() < 2 ) { - // 1 frame anims never end - return; - } - - if ( frameRate == USERCMD_HZ ) { - frameTime = gameLocal.time - starttime; - frame = frameTime / gameLocal.msec; - } else { - frameTime = ( gameLocal.time - starttime ) * frameRate; - frame = frameTime / 1000; - } - - if ( frame > camera.Num() + cameraCuts.Num() - 2 ) { - if ( cycle > 0 ) { - cycle--; - } - - if ( cycle != 0 ) { - // advance start time so that we loop - starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate; - } else { - Stop(); - } - } - } -} - -/* -===================== -idCameraAnim::GetViewParms -===================== -*/ -void idCameraAnim::GetViewParms( renderView_t *view ) { - int realFrame; - int frame; - int frameTime; - float lerp; - float invlerp; - cameraFrame_t *camFrame; - int i; - int cut; - idQuat q1, q2, q3; - - assert( view ); - if ( !view ) { - return; - } - - if ( camera.Num() == 0 ) { - // we most likely are in the middle of a restore - // FIXME: it would be better to fix it so this doesn't get called during a restore - return; - } - - if ( frameRate == USERCMD_HZ ) { - frameTime = gameLocal.time - starttime; - frame = frameTime / gameLocal.msec; - lerp = 0.0f; - } else { - frameTime = ( gameLocal.time - starttime ) * frameRate; - frame = frameTime / 1000; - lerp = ( frameTime % 1000 ) * 0.001f; - } - - // skip any frames where camera cuts occur - realFrame = frame; - cut = 0; - for( i = 0; i < cameraCuts.Num(); i++ ) { - if ( frame < cameraCuts[ i ] ) { - break; - } - frame++; - cut++; - } - - if ( g_debugCinematic.GetBool() ) { - int prevFrameTime = ( gameLocal.time - starttime - gameLocal.msec ) * frameRate; - int prevFrame = prevFrameTime / 1000; - int prevCut; - - prevCut = 0; - for( i = 0; i < cameraCuts.Num(); i++ ) { - if ( prevFrame < cameraCuts[ i ] ) { - break; - } - prevFrame++; - prevCut++; - } - - if ( prevCut != cut ) { - gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut ); - } - } - - // clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately, - // but since they're mainly used for static cams anyway, just stay on it infinitely. - if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) { - view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3(); - view->vieworg = camera[ 0 ].t + offset; - view->fov_x = camera[ 0 ].fov; - } else if ( frame > camera.Num() - 2 ) { - if ( cycle > 0 ) { - cycle--; - } - - if ( cycle != 0 ) { - // advance start time so that we loop - starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate; - GetViewParms( view ); - return; - } - - Stop(); - if ( gameLocal.GetCamera() != NULL ) { - // we activated another camera when we stopped, so get it's viewparms instead - gameLocal.GetCamera()->GetViewParms( view ); - return; - } else { - // just use our last frame - camFrame = &camera[ camera.Num() - 1 ]; - view->viewaxis = camFrame->q.ToQuat().ToMat3(); - view->vieworg = camFrame->t + offset; - view->fov_x = camFrame->fov; - } - } else if ( lerp == 0.0f ) { - camFrame = &camera[ frame ]; - view->viewaxis = camFrame[ 0 ].q.ToMat3(); - view->vieworg = camFrame[ 0 ].t + offset; - view->fov_x = camFrame[ 0 ].fov; - } else { - camFrame = &camera[ frame ]; - invlerp = 1.0f - lerp; - q1 = camFrame[ 0 ].q.ToQuat(); - q2 = camFrame[ 1 ].q.ToQuat(); - q3.Slerp( q1, q2, lerp ); - view->viewaxis = q3.ToMat3(); - view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset; - view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp; - } - - gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y ); - - // setup the pvs for this frame - UpdatePVSAreas( view->vieworg ); - -#if 0 - static int lastFrame = 0; - static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f ); - if ( gameLocal.time != lastFrame ) { - gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, gameLocal.msec ); - gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); - gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false ); - gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false ); - gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); - lastFrameVec = view->vieworg; - lastFrame = gameLocal.time; - } -#endif - - if ( g_showcamerainfo.GetBool() ) { - gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() ); - } -} - -/* -=============== -idCameraAnim::Event_Activate -================ -*/ -void idCameraAnim::Event_Activate( idEntity *_activator ) { - activator = _activator; - if ( thinkFlags & TH_THINK ) { - Stop(); - } else { - Start(); - } -} - -/* -=============== -idCameraAnim::Event_Start -================ -*/ -void idCameraAnim::Event_Start( void ) { - Start(); -} - -/* -=============== -idCameraAnim::Event_Stop -================ -*/ -void idCameraAnim::Event_Stop( void ) { - Stop(); -} - -/* -================ -idCameraAnim::Event_SetCallback -================ -*/ -void idCameraAnim::Event_SetCallback( void ) { - if ( ( gameLocal.GetCamera() == this ) && !threadNum ) { - threadNum = idThread::CurrentThreadNum(); - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} diff --git a/game/camera.h b/game/camera.h deleted file mode 100644 index 94b2289d2..000000000 --- a/game/camera.h +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_CAMERA_H__ -#define __GAME_CAMERA_H__ - - -/* -=============================================================================== - -Camera providing an alternative view of the level. - -=============================================================================== -*/ - -class idCamera : public idEntity { -public: - ABSTRACT_PROTOTYPE( idCamera ); - - void Spawn( void ); - virtual void GetViewParms( renderView_t *view ) = 0; - virtual renderView_t * GetRenderView(); - virtual void Stop( void ){} ; -}; - -/* -=============================================================================== - -idCameraView - -=============================================================================== -*/ - -class idCameraView : public idCamera { -public: - CLASS_PROTOTYPE( idCameraView ); - idCameraView(); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void Spawn( ); - virtual void GetViewParms( renderView_t *view ); - virtual void Stop( void ); - -protected: - void Event_Activate( idEntity *activator ); - void Event_SetAttachments(); - void SetAttachment( idEntity **e, const char *p ); - float fov; - idEntity *attachedTo; - idEntity *attachedView; -}; - - - -/* -=============================================================================== - -A camera which follows a path defined by an animation. - -=============================================================================== -*/ - -typedef struct { - idCQuat q; - idVec3 t; - float fov; -} cameraFrame_t; - -class idCameraAnim : public idCamera { -public: - CLASS_PROTOTYPE( idCameraAnim ); - - idCameraAnim(); - ~idCameraAnim(); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void Spawn( void ); - virtual void GetViewParms( renderView_t *view ); - -private: - int threadNum; - idVec3 offset; - int frameRate; - int starttime; - int cycle; - idList cameraCuts; - idList camera; - idEntityPtr activator; - - void Start( void ); - void Stop( void ); - void Think( void ); - - void LoadAnim( void ); - void Event_Start( void ); - void Event_Stop( void ); - void Event_SetCallback( void ); - void Event_Activate( idEntity *activator ); -}; - -#endif /* !__GAME_CAMERA_H__ */ diff --git a/DarkMod/darkModLAS.cpp b/game/darkModLAS.cpp similarity index 97% rename from DarkMod/darkModLAS.cpp rename to game/darkModLAS.cpp index 78da046dc..e63ac967f 100644 --- a/DarkMod/darkModLAS.cpp +++ b/game/darkModLAS.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /*! * Implementation file for the darkModLAS class * SophisticatedZombie, using SparHawk's lightgem code @@ -17,12 +27,12 @@ static bool init_version = FileVersionList("$Id$", init_version); -#include "./darkModLAS.h" -#include "../game/pvs.h" -#include "../renderer/renderworld.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Intersection.h" -#include "../DarkMod/TimerManager.h" +#include "darkModLAS.h" +#include "Pvs.h" +#include "../renderer/RenderWorld.h" +#include "DarkModGlobals.h" +#include "Intersection.h" +#include "TimerManager.h" //---------------------------------------------------------------------------- diff --git a/DarkMod/darkModLAS.h b/game/darkModLAS.h similarity index 87% rename from DarkMod/darkModLAS.h rename to game/darkModLAS.h index b8d978e89..a97e680d2 100644 --- a/DarkMod/darkModLAS.h +++ b/game/darkModLAS.h @@ -1,21 +1,31 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once //class darkModLAS; -// DarkMod globals (needed for ../game/Light.h) -#include "../DarkMod/DarkModGlobals.h" +// DarkMod globals (needed for Light.h) +#include "DarkModGlobals.h" // idLight -#include "../game/light.h" +#include "Light.h" // The PVS to AAS mapping table #include "PVSToAASMapping.h" diff --git a/DarkMod/darkmodHidingSpotTree.cpp b/game/darkmodHidingSpotTree.cpp similarity index 97% rename from DarkMod/darkmodHidingSpotTree.cpp rename to game/darkmodHidingSpotTree.cpp index 36dea0262..66de6e934 100644 --- a/DarkMod/darkmodHidingSpotTree.cpp +++ b/game/darkmodHidingSpotTree.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /*! * Implementation of the darkmod hiding spot tree. * diff --git a/DarkMod/darkmodHidingSpotTree.h b/game/darkmodHidingSpotTree.h similarity index 92% rename from DarkMod/darkmodHidingSpotTree.h rename to game/darkmodHidingSpotTree.h index 792daf68c..61049ad04 100644 --- a/DarkMod/darkmodHidingSpotTree.h +++ b/game/darkmodHidingSpotTree.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /*! * This is the interface for an n-tree structure which sorts and holds * darkmod hiding spots. diff --git a/DarkMod/decltdm_matinfo.cpp b/game/decltdm_matinfo.cpp similarity index 85% rename from DarkMod/decltdm_matinfo.cpp rename to game/decltdm_matinfo.cpp index 20d616c45..f736f4340 100644 --- a/DarkMod/decltdm_matinfo.cpp +++ b/game/decltdm_matinfo.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/game/decltdm_matinfo.h b/game/decltdm_matinfo.h new file mode 100644 index 000000000..671df3259 --- /dev/null +++ b/game/decltdm_matinfo.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DARKMOD_DECLTDM_MATINFO_H__ +#define __DARKMOD_DECLTDM_MATINFO_H__ + +/// A TDM-specific material information declaration class. +/** Currently, the only info it contains is surfacetype. + */ +class tdmDeclTDM_MatInfo : public idDecl +{ +public: + tdmDeclTDM_MatInfo(); + ~tdmDeclTDM_MatInfo(); + + virtual size_t Size( void ) const; + virtual const char * DefaultDefinition( void ) const; + virtual void FreeData( void ); + virtual bool Parse( const char *text, const int textLength ); + + /// Used to cache the TDM_MatInfos for all the materials applied to surfaces of a map. + static void precacheMap( idMapFile *map ); + static void precacheModel( idRenderModel *model ); + + /// The surface type of the material. + idStr surfaceType; +}; + +#endif /* __DARKMOD_DECLTDM_MATINFO_H__ */ diff --git a/DarkMod/declxdata.cpp b/game/declxdata.cpp similarity index 88% rename from DarkMod/declxdata.cpp rename to game/declxdata.cpp index 42f0c77c6..4bbb42b2c 100644 --- a/DarkMod/declxdata.cpp +++ b/game/declxdata.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "../idlib/precompiled.h" #pragma hdrstop diff --git a/DarkMod/declxdata.h b/game/declxdata.h similarity index 84% rename from DarkMod/declxdata.h rename to game/declxdata.h index 11434cf06..f927b30a7 100644 --- a/DarkMod/declxdata.h +++ b/game/declxdata.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __DARKMOD_DECLXDATA_H__ #define __DARKMOD_DECLXDATA_H__ diff --git a/game/emitter.cpp b/game/emitter.cpp deleted file mode 100644 index f901a207e..000000000 --- a/game/emitter.cpp +++ /dev/null @@ -1,459 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -/* - Copyright (C) 2004 Id Software, Inc. - Copyright (C) 2011 The Dark Mod - -func_emitters - have one or more particle models - -*/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -//#include "game_local.h" -#include "emitter.h" - -const idEventDef EV_EmitterAddModel( "emitterAddModel", "sv" ); -const idEventDef EV_EmitterGetNumModels( "emitterGetNumModels", NULL, 'f' ); - -CLASS_DECLARATION( idStaticEntity, idFuncEmitter ) - EVENT( EV_Activate, idFuncEmitter::Event_Activate ) - EVENT( EV_EmitterAddModel, idFuncEmitter::Event_EmitterAddModel ) - EVENT( EV_EmitterGetNumModels, idFuncEmitter::Event_EmitterGetNumModels ) -END_CLASS - -/* -=============== -idFuncEmitter::idFuncEmitter -=============== -*/ -idFuncEmitter::idFuncEmitter( void ) { - hidden = false; - m_LODHandle = 0; - - m_models.Clear(); -} - -/* -================ -idFuncEmitter::~idFuncEmitter -================ -*/ -idFuncEmitter::~idFuncEmitter( void ) { - - const int num = m_models.Num(); - for (int i = 0; i < num; i++ ) - { - if ( m_models[i].defHandle != -1 ) - { - gameRenderWorld->FreeEntityDef( m_models[i].defHandle ); - m_models[i].defHandle = -1; - } - } - m_models.Clear(); -} - -/* -================ -idFuncEmitter::SetModel for additional models -================ -*/ -void idFuncEmitter::SetModel( int id, const idStr &modelName, const idVec3 &offset ) { - - m_models.AssureSize( id+1 ); - m_models[id].defHandle = -1; - m_models[id].offset = offset; - m_models[id].flags = 0; - m_models[id].handle = renderModelManager->FindModel( modelName ); - if (spawnArgs.GetString("model") != modelName) - { - // differs - m_models[id].name = modelName; - } - else - { - // store "" to flag as "same as the original model" - m_models[id].name = ""; - } - - // need to call Present() the next time we Think(): - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idFuncEmitter::SetModel for LOD change -================ -*/ -void idFuncEmitter::SetModel( const char* modelName ) -{ - if ( modelDefHandle > 0 ) - { - gameRenderWorld->FreeEntityDef( modelDefHandle ); - } - modelDefHandle = -1; - spawnArgs.Set("model", modelName); - - idRenderModel * modelHandle = renderModelManager->FindModel( modelName ); - - // go through all other models and change them - const int num = m_models.Num(); - for (int i = 0; i < num; i++ ) { - if ( m_models[i].name.IsEmpty()) - { - // same as original model, so change it, too - if ( m_models[i].defHandle != -1 ) - { - gameRenderWorld->FreeEntityDef( m_models[0].defHandle ); - } - m_models[i].defHandle = -1; - m_models[i].handle = modelHandle; - } - // else: leave it alone - } - - // need to call Present() the next time we Think(): - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idFuncEmitter::Present -================ -*/ -void idFuncEmitter::Present( void ) -{ - if( m_bFrobable ) - { - UpdateFrobState(); - UpdateFrobDisplay(); - } - - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) - { - return; - } - BecomeInactive( TH_UPDATEVISUALS ); - - // present the first model - renderEntity.origin = GetPhysics()->GetOrigin(); - renderEntity.axis = GetPhysics()->GetAxis(); - renderEntity.hModel = renderModelManager->FindModel( spawnArgs.GetString("model") ); - - renderEntity.bodyId = 0; - // make each of them have a unique timeoffset, so they do not appear to be in sync - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time - gameLocal.random.RandomInt( 32767 ) ); - - if ( renderEntity.hModel ) { - renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); - // add to refresh list - if ( modelDefHandle == -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } - } - else { - // don't present the model if it is non-existant - renderEntity.bounds.Zero(); - } - // TODO: add to the bounds above the bounds of the other models - - // present additional models to the renderer - const int num = m_models.Num(); -// gameLocal.Printf("%s: Have %i models\n", GetName(), num + 1); - for (int i = 0; i < num; i++ ) { - - if ( !m_models[i].handle ) { - continue; - } - - if ( (m_models[i].flags & 1) != 0) - { - // is invisible, ignore it - continue; - } -// gameLocal.Printf("%s: Presenting model %i\n", GetName(), i); - renderEntity.origin = GetPhysics()->GetOrigin() + m_models[i].offset; - renderEntity.axis = GetPhysics()->GetAxis(); - renderEntity.hModel = m_models[i].handle; - renderEntity.bodyId = i + 1; - // make each of them have a unique timeoffset, so they do not appear to be in sync - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time - gameLocal.random.RandomInt( 32767 ) ); - - if ( renderEntity.hModel ) { - renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); - // add to refresh list - if ( m_models[i].defHandle == -1 ) { - m_models[i].defHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( m_models[i].defHandle, &renderEntity ); - } - } - else { - renderEntity.bounds.Zero(); - } - } -} - -/* -=============== -idFuncEmitter::Spawn -=============== -*/ -void idFuncEmitter::Spawn( void ) { - const idKeyValue *kv; - - if ( spawnArgs.GetBool( "start_off" ) ) { - hidden = true; - renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( 1 ); - UpdateVisuals(); - } else { - hidden = false; - } - - // check if we have additional models - kv = spawnArgs.MatchPrefix( "model", NULL ); - int model = 0; - while( kv ) - { - idStr suffix = kv->GetKey(); - idStr modelName = kv->GetValue(); - if ((suffix.Length() >= 9 && suffix.Cmpn("model_lod",9) == 0) || suffix == "model") - { - // ignore "model_lod_2" as well as "model" - kv = spawnArgs.MatchPrefix( "model", kv ); - continue; - } - suffix = suffix.Right( suffix.Length() - 5); // model_2 => "_2" - if (!spawnArgs.FindKey("offset" + suffix)) - { - gameLocal.Warning("FuncEmitter %s: 'offset%s' is undefined and will clash at origin.", GetName(), suffix.c_str() ); - } - idVec3 modelOffset = spawnArgs.GetVector( "offset" + suffix, "0,0,0" ); -// gameLocal.Printf( "FuncEmitter %s: Adding model %i ('%s') at offset %s (suffix %s).\n", GetName(), model, modelName.c_str(), modelOffset.ToString(), suffix.c_str() ); - SetModel( model++, modelName, modelOffset ); - kv = spawnArgs.MatchPrefix( "model", kv ); - } - if (model > 0) - { - gameLocal.Printf( "FuncEmitter %s: Added %i additional emitters.\n", GetName(), model ); - } -} - -/* -=============== -idFuncEmitter::Save -=============== -*/ -void idFuncEmitter::Save( idSaveGame *savefile ) const { - savefile->WriteBool( hidden ); - - const int num = m_models.Num(); - savefile->WriteInt( num ); - for (int i = 0; i < num; i++ ) { - savefile->WriteInt( m_models[i].defHandle ); - savefile->WriteVec3( m_models[i].offset ); - savefile->WriteString( m_models[i].name ); - savefile->WriteInt( m_models[i].flags ); - } -} - -/* -================ -idFuncEmitter::Think -================ -*/ -void idFuncEmitter::Think( void ) -{ - // will also do LOD thinking: - idEntity::Think(); - - // extra models? Do LOD thinking for them: - const int num = m_models.Num(); - // start with 1 -/* for (int i = 1; i < num; i++) - { - // TODO: - } -*/ - // did our model(s) change? - Present(); -} - -/* -=============== -idFuncEmitter::Restore -=============== -*/ -void idFuncEmitter::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( hidden ); - int num; - savefile->ReadInt( num ); - - idStr defaultModelName = spawnArgs.GetString("model"); - - m_models.Clear(); - m_models.SetNum(num); - for (int i = 0; i < num; i++ ) { - savefile->ReadInt( m_models[i].defHandle ); - savefile->ReadVec3( m_models[i].offset ); - savefile->ReadString( m_models[i].name ); - savefile->ReadInt( m_models[i].flags ); - - // find the modelHandle - idStr modelName = m_models[i].name; - if (modelName.IsEmpty()) - { - modelName = defaultModelName; - } - m_models[i].handle = renderModelManager->FindModel( modelName ); - } - BecomeActive( TH_UPDATEVISUALS ); -} - -/* - **************** Events **************************************** -*/ - -/* -================ -idFuncEmitter::Event_Activate -================ -*/ -void idFuncEmitter::Event_Activate( idEntity *activator ) { - if ( hidden || spawnArgs.GetBool( "cycleTrigger" ) ) { - renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = 0; - renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - hidden = false; - } else { - renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time ); - hidden = true; - } - UpdateVisuals(); -} - -/* -================ -idFuncEmitter::Event_EmitterGetNumModels -================ -*/ -void idFuncEmitter::Event_EmitterGetNumModels( void ) const { - idThread::ReturnFloat( m_models.Num() + 1 ); -} - -/* -================ -idFuncEmitter::Event_EmitterAddModel -================ -*/ -void idFuncEmitter::Event_EmitterAddModel( idStr const &modelName, idVec3 const &modelOffset ) { - - SetModel( m_models.Num(), modelName, modelOffset ); -} - - - -/* -================ -idFuncEmitter::WriteToSnapshot -================ -*/ -void idFuncEmitter::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteBits( hidden ? 1 : 0, 1 ); - msg.WriteFloat( renderEntity.shaderParms[ SHADERPARM_PARTICLE_STOPTIME ] ); - msg.WriteFloat( renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] ); - // TODO: additinal models -} - -/* -================ -idFuncEmitter::ReadFromSnapshot -================ -*/ -void idFuncEmitter::ReadFromSnapshot( const idBitMsgDelta &msg ) { - hidden = msg.ReadBits( 1 ) != 0; - renderEntity.shaderParms[ SHADERPARM_PARTICLE_STOPTIME ] = msg.ReadFloat(); - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = msg.ReadFloat(); - // TODO: additinal models - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - - -/* -=============================================================================== - -idFuncSplat - -=============================================================================== -*/ - - -const idEventDef EV_Splat( "" ); -CLASS_DECLARATION( idFuncEmitter, idFuncSplat ) -EVENT( EV_Activate, idFuncSplat::Event_Activate ) -EVENT( EV_Splat, idFuncSplat::Event_Splat ) -END_CLASS - -/* -=============== -idFuncSplat::idFuncSplat -=============== -*/ -idFuncSplat::idFuncSplat( void ) { -} - -/* -=============== -idFuncSplat::Spawn -=============== -*/ -void idFuncSplat::Spawn( void ) { -} - -/* -================ -idFuncSplat::Event_Splat -================ -*/ -void idFuncSplat::Event_Splat( void ) { - const char *splat = NULL; - int count = spawnArgs.GetInt( "splatCount", "1" ); - for ( int i = 0; i < count; i++ ) { - splat = spawnArgs.RandomPrefix( "mtr_splat", gameLocal.random ); - if ( splat && *splat ) { - float size = spawnArgs.GetFloat( "splatSize", "128" ); - float dist = spawnArgs.GetFloat( "splatDistance", "128" ); - float angle = spawnArgs.GetFloat( "splatAngle", "0" ); - gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[2], dist, true, size, splat, angle ); - } - } - StartSound( "snd_splat", SND_CHANNEL_ANY, 0, false, NULL ); -} - -/* -================ -idFuncSplat::Event_Activate -================ -*/ -void idFuncSplat::Event_Activate( idEntity *activator ) { - idFuncEmitter::Event_Activate( activator ); - PostEventSec( &EV_Splat, spawnArgs.GetFloat( "splatDelay", "0.25" ) ); - StartSound( "snd_spurt", SND_CHANNEL_ANY, 0, false, NULL ); -} - - diff --git a/game/emitter.h b/game/emitter.h deleted file mode 100644 index 031c0fba6..000000000 --- a/game/emitter.h +++ /dev/null @@ -1,96 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// Copyright (C) 2011 The Dark Mod - -#ifndef __GAME_TDM_EMITTER_H__ -#define __GAME_TDM_EMITTER_H__ - -#include "misc.h" - -/* -=============================================================================== - -idFuncEmitter - -=============================================================================== -*/ - -/** Defines additional data for emitters with more than one particle */ -typedef struct { - int defHandle; - idVec3 offset; - idRenderModel * handle; - idStr name; // empty when this model equals the first model - int flags; // 0 => visible, 1 => hidden -} emitter_models_t; - -class idFuncEmitter : public idStaticEntity { -public: - CLASS_PROTOTYPE( idFuncEmitter ); - - idFuncEmitter( void ); - ~idFuncEmitter( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - void Event_Activate( idEntity *activator ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - virtual void Think( void ); - virtual void Present( void ); - - // switch to a new model - virtual void SetModel( const char *modelname ); - - // public events - void Event_EmitterGetNumModels( void ) const; - void Event_EmitterAddModel( idStr const &modelName, idVec3 const &modelOffset ); - -protected: - - // add an extra model - void SetModel( int id, const idStr &modelName, const idVec3 &offset ); - -private: - bool hidden; - - idList m_models; //! struct with data for additional models -}; - -/* -=============================================================================== - -idFuncSplat - -=============================================================================== -*/ - -class idFuncSplat : public idFuncEmitter { -public: - CLASS_PROTOTYPE( idFuncSplat ); - - idFuncSplat( void ); - - void Spawn( void ); - -private: - void Event_Activate( idEntity *activator ); - void Event_Splat(); -}; - - -#endif /* !__GAME_TDM_EMITTER_H__ */ - diff --git a/game/entity.cpp b/game/entity.cpp deleted file mode 100644 index d1c2dcda6..000000000 --- a/game/entity.cpp +++ /dev/null @@ -1,12230 +0,0 @@ -/*************************************************************************** - * - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning(disable : 4533 4800) - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/declxdata.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/Objectives/ObjectiveLocation.h" -#include "../DarkMod/Grabber.h" -#include "../DarkMod/sndProp.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/Inventory/Inventory.h" -#include "../DarkMod/Inventory/Cursor.h" -#include "../DarkMod/AbsenceMarker.h" -#include "../DarkMod/Objectives/MissionData.h" - -/* -=============================================================================== - - idEntity - -=============================================================================== -*/ - -// TDM uses entity shaderparm 11 to control frob highlight state -#define FROB_SHADERPARM 11 - -// constant to disable LOD temp. Must be smaller than 1000 * (distcheckperiod + 2) -#define NOLOD -100000 - -// overridable events -const idEventDef EV_PostSpawn( "", NULL ); -const idEventDef EV_FindTargets( "", NULL ); -const idEventDef EV_Touch( "", "et" ); -const idEventDef EV_GetName( "getName", NULL, 's' ); -const idEventDef EV_SetName( "setName", "s" ); -const idEventDef EV_IsType ( "isType", "s" , 'd' ); -const idEventDef EV_Activate( "activate", "e" ); -const idEventDef EV_ActivateTargets( "activateTargets", "e" ); -const idEventDef EV_AddTarget( "addTarget", "e" ); -const idEventDef EV_RemoveTarget( "removeTarget", "e" ); -const idEventDef EV_NumTargets( "numTargets", NULL, 'f' ); -const idEventDef EV_GetTarget( "getTarget", "f", 'e' ); -const idEventDef EV_RandomTarget( "randomTarget", "s", 'e' ); -const idEventDef EV_Bind( "bind", "e" ); -const idEventDef EV_BindPosition( "bindPosition", "e" ); -const idEventDef EV_BindToJoint( "bindToJoint", "esf" ); -const idEventDef EV_BindToBody( "bindToBody", "edd" ); -const idEventDef EV_GetBindMaster( "getBindMaster", NULL, 'e' ); -const idEventDef EV_NumBindChildren( "numBindChildren", NULL, 'd' ); -const idEventDef EV_GetBindChild( "getBindChild", "d", 'e' ); -const idEventDef EV_Unbind( "unbind", NULL ); -const idEventDef EV_RemoveBinds( "removeBinds" ); -const idEventDef EV_SpawnBind( "", NULL ); -const idEventDef EV_SetOwner( "setOwner", "e" ); -const idEventDef EV_SetModel( "setModel", "s" ); -const idEventDef EV_SetSkin( "setSkin", "s" ); -const idEventDef EV_GetWorldOrigin( "getWorldOrigin", NULL, 'v' ); -const idEventDef EV_SetWorldOrigin( "setWorldOrigin", "v" ); -const idEventDef EV_GetOrigin( "getOrigin", NULL, 'v' ); -const idEventDef EV_SetOrigin( "setOrigin", "v" ); -const idEventDef EV_GetAngles( "getAngles", NULL, 'v' ); -const idEventDef EV_SetAngles( "setAngles", "v" ); -const idEventDef EV_GetLinearVelocity( "getLinearVelocity", NULL, 'v' ); -const idEventDef EV_SetLinearVelocity( "setLinearVelocity", "v" ); -const idEventDef EV_GetAngularVelocity( "getAngularVelocity", NULL, 'v' ); -const idEventDef EV_SetAngularVelocity( "setAngularVelocity", "v" ); -// greebo: Accessor events for the clipmask/contents flags -const idEventDef EV_SetContents( "setContents", "f" ); -const idEventDef EV_GetContents( "getContents", NULL, 'f' ); -const idEventDef EV_SetClipMask( "setClipMask", "d" ); -const idEventDef EV_GetClipMask( "getClipMask", NULL, 'd' ); - -const idEventDef EV_GetSize( "getSize", NULL, 'v' ); -const idEventDef EV_SetSize( "setSize", "vv" ); -const idEventDef EV_GetMins( "getMins", NULL, 'v' ); -const idEventDef EV_GetMaxs( "getMaxs", NULL, 'v' ); -const idEventDef EV_IsHidden( "isHidden", NULL, 'd' ); -const idEventDef EV_Hide( "hide", NULL ); -const idEventDef EV_Show( "show", NULL ); -const idEventDef EV_Touches( "touches", "E", 'd' ); -const idEventDef EV_ClearSignal( "clearSignal", "d" ); -const idEventDef EV_GetShaderParm( "getShaderParm", "d", 'f' ); -const idEventDef EV_SetShaderParm( "setShaderParm", "df" ); -const idEventDef EV_SetShaderParms( "setShaderParms", "ffff" ); -const idEventDef EV_SetColor( "setColor", "fff" ); -const idEventDef EV_GetColor( "getColor", NULL, 'v' ); -const idEventDef EV_CacheSoundShader( "cacheSoundShader", "s" ); -const idEventDef EV_StartSoundShader( "startSoundShader", "sd", 'f' ); -const idEventDef EV_StartSound( "startSound", "sdd", 'f' ); -const idEventDef EV_StopSound( "stopSound", "dd" ); -const idEventDef EV_FadeSound( "fadeSound", "dff" ); -const idEventDef EV_SetSoundVolume( "setSoundVolume", "f" ); -const idEventDef EV_GetNextKey( "getNextKey", "ss", 's' ); -const idEventDef EV_SetKey( "setKey", "ss" ); -const idEventDef EV_GetKey( "getKey", "s", 's' ); -const idEventDef EV_GetIntKey( "getIntKey", "s", 'f' ); -const idEventDef EV_GetFloatKey( "getFloatKey", "s", 'f' ); -const idEventDef EV_GetVectorKey( "getVectorKey", "s", 'v' ); -const idEventDef EV_GetEntityKey( "getEntityKey", "s", 'e' ); -const idEventDef EV_RemoveKey( "removeKey", "s" ); -const idEventDef EV_RestorePosition( "restorePosition" ); -const idEventDef EV_UpdateCameraTarget( "", NULL ); -const idEventDef EV_DistanceTo( "distanceTo", "E", 'f' ); -const idEventDef EV_DistanceToPoint( "distanceToPoint", "v", 'f' ); -const idEventDef EV_StartFx( "startFx", "s" ); -const idEventDef EV_HasFunction( "hasFunction", "s", 'd' ); -const idEventDef EV_CallFunction( "callFunction", "s" ); -const idEventDef EV_CallGlobalFunction( "callGlobalFunction", "sE" ); -const idEventDef EV_SetNeverDormant( "setNeverDormant", "d" ); - -// greebo: Extinguishes all lights (i.e. the entity plus all bound lights) -const idEventDef EV_ExtinguishLights("extinguishLights", NULL); - -const idEventDef EV_InPVS( "inPVS", NULL, 'd' ); -// greebo: Script event definition for dealing damage -const idEventDef EV_Damage("damage", "EEvsf"); -// greebo: Script event definition for healing -// Takes the name of the healing entity and the healing scale, returns an integer -const idEventDef EV_Heal("heal", "sf", 'd'); - -// tels: Teleport the entity to the position/orientation of the given entity -const idEventDef EV_TeleportTo("teleportTo", "e"); - -// ishtvan: Get/setd droppable on entity and associated inventory item -const idEventDef EV_IsDroppable( "isDroppable", NULL, 'd' ); -const idEventDef EV_SetDroppable( "setDroppable", "d" ); - -// tels: set noShadow on this entity to the given argument (true/false) -const idEventDef EV_NoShadows( "noShadows", "d" ); - -// tels: Find all lights in the player PVS, then returns their sum. -const idEventDef EV_GetLightInPVS("getLightInPVS", "ff", 'v'); - -const idEventDef EV_GetVinePlantLoc("getVinePlantLoc", NULL, 'v'); // grayman #2787 -const idEventDef EV_GetVinePlantNormal("getVinePlantNormal", NULL, 'v'); // grayman #2787 - -//=============================================================== -// TDM GUI interface -//=============================================================== -const idEventDef EV_SetGui( "setGui", "ds" ); -const idEventDef EV_GetGui( "getGui", "d", 's' ); -const idEventDef EV_SetGuiString( "setGuiString", "dss" ); -const idEventDef EV_GetGuiString( "getGuiString", "ds", 's' ); -const idEventDef EV_SetGuiFloat( "setGuiFloat", "dsf" ); -const idEventDef EV_GetGuiFloat( "getGuiFloat", "ds", 'f' ); -const idEventDef EV_SetGuiInt( "setGuiInt", "dsd" ); -const idEventDef EV_GetGuiInt( "getGuiInt", "ds", 'f' ); -const idEventDef EV_SetGuiStringFromKey( "setGuiStringFromKey", "dses" ); -const idEventDef EV_CallGui( "callGui", "ds" ); -const idEventDef EV_CreateOverlay( "createOverlay", "sd", 'd' ); -const idEventDef EV_DestroyOverlay( "destroyOverlay", "d" ); -const idEventDef EV_LoadExternalData( "loadExternalData", "ss", 'd' ); - - -//=============================================================== -// TDM Inventory -//=============================================================== -const idEventDef EV_GetLootAmount("getLootAmount", "d", 'd'); // returns the current value for the given group -const idEventDef EV_ChangeLootAmount("changeLootAmount", "dd", 'd'); // Changes the loot amount of the given group by the given amount, returns the new amount of that type -const idEventDef EV_AddInvItem("addInvItem", "e"); // Adds an entity to the inventory -const idEventDef EV_AddItemToInv("addItemToInv", "e"); // Adds this entity to the inventory of the given entity (reversed AddInvItem) -const idEventDef EV_ReplaceInvItem("replaceInvItem", "eE", 'd'); // olditem, newitem -> 1 if succeeded -const idEventDef EV_GetNextInvItem("getNextInvItem", "", 'e'); // switches to the next inventory item -const idEventDef EV_GetPrevInvItem("getPrevInvItem", "", 'e'); // switches to the previous inventory item -const idEventDef EV_ChangeInvItemCount("changeInvItemCount", "ssd"); // Changes the stack count (call with "inv_name", "inv_category" and amount) -const idEventDef EV_ChangeInvLightgemModifier("changeInvLightgemModifier", "ssd"); // Changes the lightgem modifier value of the given item. -const idEventDef EV_ChangeInvIcon("changeInvIcon", "sss"); // Changes the inventory icon of the given item. - -const idEventDef EV_SetCurInvCategory("setCurInvCategory", "s", 'd'); // category name -> 1 = success -const idEventDef EV_SetCurInvItem("setCurInvItem", "s", 'e'); // itemname -> entity -const idEventDef EV_GetCurInvCategory("getCurInvCategory", NULL, 's'); -const idEventDef EV_GetCurInvItemEntity("getCurInvItemEntity", NULL, 'e'); -const idEventDef EV_GetCurInvItemName("getCurInvItemName", NULL, 's'); -const idEventDef EV_GetCurInvItemId("getCurInvItemId", NULL, 's'); -const idEventDef EV_GetCurInvIcon("getCurInvIcon", NULL, 's'); - -// greebo: "Private" event which runs right after spawn time to check the inventory-related spawnargs. -const idEventDef EV_InitInventory("initInventory", "d"); - -// grayman #2478 - event which runs after spawn time to see if a mine is armed -const idEventDef EV_CheckMine("checkMine"); - -// The Dark Mod Stim/Response interface functions for scripting -// Normally I don't like names, which are "the other way around" -// but I think in this case it would be ok, because the interface -// for stims and responses are pretty much the same. -const idEventDef EV_StimAdd( "StimAdd", "df" ); -const idEventDef EV_StimRemove( "StimRemove", "d" ); -const idEventDef EV_StimEnable( "StimEnable", "dd" ); -const idEventDef EV_StimClearIgnoreList( "StimClearIgnoreList", "d" ); -const idEventDef EV_ResponseEnable( "ResponseEnable", "dd" ); -const idEventDef EV_ResponseAdd( "ResponseAdd", "d" ); -const idEventDef EV_ResponseRemove( "ResponseRemove", "d" ); -const idEventDef EV_ResponseIgnore( "ResponseIgnore", "de" ); -const idEventDef EV_ResponseAllow( "ResponseAllow", "de" ); -const idEventDef EV_ResponseSetAction( "ResponseSetAction", "ds" ); -const idEventDef EV_ResponseTrigger( "ResponseTrigger", "ed" ); -const idEventDef EV_GetResponseEntity( "GetResponseEntity", NULL, 'e' ); - -// StimType, Hours, minutes, seconds, miliseconds(?) -const idEventDef EV_TimerCreate( "CreateTimer", "ddddd" ); -const idEventDef EV_TimerStop( "StopTimer", "d" ); -const idEventDef EV_TimerStart( "StartTimer", "d" ); -const idEventDef EV_TimerRestart( "RestartTimer", "d" ); -const idEventDef EV_TimerReset( "ResetTimer", "d" ); -const idEventDef EV_TimerSetState( "SetTimerState", "dd" ); - -// soundprop event: Propagate sound directly from scripting -const idEventDef EV_TDM_PropSoundMod( "propSoundMod", "sf" ); -// I don't think scripting supports optional argument, so I must do this -const idEventDef EV_TDM_PropSound( "propSound", "s" ); - -// For detecting ranged enemies. Returns nonzero if this entity could -// potentially attack the given entity (first parameter) at range. -const idEventDef EV_TDM_RangedThreatTo( "rangedThreatTo", "e", 'f' ); - - -#ifdef MOD_WATERPHYSICS - -const idEventDef EV_GetMass( "getMass", "d" , 'f' ); - -const idEventDef EV_IsInLiquid( "isInLiquid", NULL, 'd' ); - -#endif // MOD_WATERPHYSICS - -const idEventDef EV_CopyBind( "copyBind", "e" ); -const idEventDef EV_IsFrobable( "isFrobable", NULL, 'd' ); -const idEventDef EV_SetFrobable( "setFrobable", "d" ); -const idEventDef EV_IsHilighted( "isHilighted", NULL, 'd' ); -const idEventDef EV_Frob("frob", NULL, 'd'); -const idEventDef EV_FrobHilight("frobHilight", "d" ); - -// greebo: Script event to check whether this entity can see a target entity -const idEventDef EV_CanSeeEntity("canSeeEntity", "ed", 'd'); - -const idEventDef EV_CanBeUsedBy("canBeUsedBy", "e", 'd'); - -const idEventDef EV_CheckAbsence("checkAbsence"); - -// greebo: TDM: Team accessor script events -const idEventDef EV_GetTeam("getTeam", NULL, 'd'); -const idEventDef EV_SetTeam("setTeam", "d"); - -const idEventDef EV_IsEnemy( "isEnemy", "E", 'd' ); -const idEventDef EV_IsFriend( "isFriend", "E", 'd' ); -const idEventDef EV_IsNeutral( "isNeutral", "E", 'd' ); - -const idEventDef EV_SetEntityRelation( "setEntityRelation", "Ed"); -const idEventDef EV_ChangeEntityRelation( "changeEntityRelation", "Ed"); - -ABSTRACT_DECLARATION( idClass, idEntity ) - EVENT( EV_Thread_SetRenderCallback, idEntity::Event_WaitForRender ) - - EVENT( EV_GetName, idEntity::Event_GetName ) - EVENT( EV_SetName, idEntity::Event_SetName ) - EVENT (EV_IsType, idEntity::Event_IsType ) - EVENT( EV_FindTargets, idEntity::Event_FindTargets ) - EVENT( EV_ActivateTargets, idEntity::Event_ActivateTargets ) - EVENT( EV_AddTarget, idEntity::Event_AddTarget) - EVENT( EV_RemoveTarget, idEntity::Event_RemoveTarget) - EVENT( EV_NumTargets, idEntity::Event_NumTargets ) - EVENT( EV_GetTarget, idEntity::Event_GetTarget ) - EVENT( EV_RandomTarget, idEntity::Event_RandomTarget ) - EVENT( EV_BindToJoint, idEntity::Event_BindToJoint ) - EVENT( EV_BindToBody, idEntity::Event_BindToBody ) - EVENT( EV_RemoveBinds, idEntity::Event_RemoveBinds ) - EVENT( EV_Bind, idEntity::Event_Bind ) - EVENT( EV_BindPosition, idEntity::Event_BindPosition ) - EVENT( EV_Unbind, idEntity::Event_Unbind ) - EVENT( EV_SpawnBind, idEntity::Event_SpawnBind ) - EVENT( EV_GetBindMaster, idEntity::Event_GetBindMaster ) - EVENT( EV_NumBindChildren, idEntity::Event_NumBindChildren ) - EVENT( EV_GetBindChild, idEntity::Event_GetBindChild ) - EVENT( EV_SetOwner, idEntity::Event_SetOwner ) - EVENT( EV_SetModel, idEntity::Event_SetModel ) - EVENT( EV_SetSkin, idEntity::Event_SetSkin ) - EVENT( EV_GetShaderParm, idEntity::Event_GetShaderParm ) - EVENT( EV_SetShaderParm, idEntity::Event_SetShaderParm ) - EVENT( EV_SetShaderParms, idEntity::Event_SetShaderParms ) - EVENT( EV_SetColor, idEntity::Event_SetColor ) - EVENT( EV_GetColor, idEntity::Event_GetColor ) - EVENT( EV_IsHidden, idEntity::Event_IsHidden ) - EVENT( EV_Hide, idEntity::Event_Hide ) - EVENT( EV_Show, idEntity::Event_Show ) - EVENT( EV_CacheSoundShader, idEntity::Event_CacheSoundShader ) - EVENT( EV_StartSoundShader, idEntity::Event_StartSoundShader ) - EVENT( EV_StartSound, idEntity::Event_StartSound ) - EVENT( EV_StopSound, idEntity::Event_StopSound ) - EVENT( EV_FadeSound, idEntity::Event_FadeSound ) - EVENT( EV_SetSoundVolume, idEntity::Event_SetSoundVolume ) - EVENT( EV_GetWorldOrigin, idEntity::Event_GetWorldOrigin ) - EVENT( EV_SetWorldOrigin, idEntity::Event_SetWorldOrigin ) - EVENT( EV_GetOrigin, idEntity::Event_GetOrigin ) - EVENT( EV_SetOrigin, idEntity::Event_SetOrigin ) - EVENT( EV_GetAngles, idEntity::Event_GetAngles ) - EVENT( EV_SetAngles, idEntity::Event_SetAngles ) - EVENT( EV_GetLinearVelocity, idEntity::Event_GetLinearVelocity ) - EVENT( EV_SetLinearVelocity, idEntity::Event_SetLinearVelocity ) - EVENT( EV_GetAngularVelocity, idEntity::Event_GetAngularVelocity ) - EVENT( EV_SetAngularVelocity, idEntity::Event_SetAngularVelocity ) - - EVENT( EV_SetContents, idEntity::Event_SetContents ) - EVENT( EV_GetContents, idEntity::Event_GetContents ) - EVENT( EV_SetClipMask, idEntity::Event_SetClipMask ) - EVENT( EV_GetClipMask, idEntity::Event_GetClipMask ) - - EVENT( EV_GetSize, idEntity::Event_GetSize ) - EVENT( EV_SetSize, idEntity::Event_SetSize ) - EVENT( EV_GetMins, idEntity::Event_GetMins) - EVENT( EV_GetMaxs, idEntity::Event_GetMaxs ) - EVENT( EV_Touches, idEntity::Event_Touches ) - EVENT( EV_GetNextKey, idEntity::Event_GetNextKey ) - EVENT( EV_SetKey, idEntity::Event_SetKey ) - EVENT( EV_GetKey, idEntity::Event_GetKey ) - EVENT( EV_GetIntKey, idEntity::Event_GetIntKey ) - EVENT( EV_GetFloatKey, idEntity::Event_GetFloatKey ) - EVENT( EV_GetVectorKey, idEntity::Event_GetVectorKey ) - EVENT( EV_GetEntityKey, idEntity::Event_GetEntityKey ) - EVENT( EV_RemoveKey, idEntity::Event_RemoveKey ) - EVENT( EV_RestorePosition, idEntity::Event_RestorePosition ) - EVENT( EV_UpdateCameraTarget, idEntity::Event_UpdateCameraTarget ) - EVENT( EV_DistanceTo, idEntity::Event_DistanceTo ) - EVENT( EV_DistanceToPoint, idEntity::Event_DistanceToPoint ) - EVENT( EV_StartFx, idEntity::Event_StartFx ) - EVENT( EV_Thread_WaitFrame, idEntity::Event_WaitFrame ) - EVENT( EV_Thread_Wait, idEntity::Event_Wait ) - EVENT( EV_HasFunction, idEntity::Event_HasFunction ) - EVENT( EV_CallFunction, idEntity::Event_CallFunction ) - EVENT( EV_CallGlobalFunction, idEntity::Event_CallGlobalFunction ) - EVENT( EV_SetNeverDormant, idEntity::Event_SetNeverDormant ) - - EVENT( EV_ExtinguishLights, idEntity::Event_ExtinguishLights ) - - EVENT( EV_InPVS, idEntity::Event_InPVS ) - EVENT( EV_Damage, idEntity::Event_Damage ) - EVENT( EV_Heal, idEntity::Event_Heal ) - EVENT( EV_TeleportTo, idEntity::Event_TeleportTo ) - EVENT( EV_IsDroppable, idEntity::Event_IsDroppable ) - EVENT( EV_SetDroppable, idEntity::Event_SetDroppable ) - EVENT( EV_GetLightInPVS, idEntity::Event_GetLightInPVS ) - - EVENT( EV_SetGui, idEntity::Event_SetGui ) - EVENT( EV_GetGui, idEntity::Event_GetGui ) - EVENT( EV_SetGuiString, idEntity::Event_SetGuiString ) - EVENT( EV_GetGuiString, idEntity::Event_GetGuiString ) - EVENT( EV_SetGuiFloat, idEntity::Event_SetGuiFloat ) - EVENT( EV_GetGuiFloat, idEntity::Event_GetGuiFloat ) - EVENT( EV_SetGuiInt, idEntity::Event_SetGuiInt ) - EVENT( EV_GetGuiInt, idEntity::Event_GetGuiInt ) - EVENT( EV_SetGuiStringFromKey, idEntity::Event_SetGuiStringFromKey ) - EVENT( EV_CallGui, idEntity::Event_CallGui ) - EVENT( EV_CreateOverlay, idEntity::Event_CreateOverlay ) - EVENT( EV_DestroyOverlay, idEntity::Event_DestroyOverlay ) - - EVENT( EV_LoadExternalData, idEntity::Event_LoadExternalData ) - - EVENT( EV_GetLootAmount, idEntity::Event_GetLootAmount ) - EVENT( EV_ChangeLootAmount, idEntity::Event_ChangeLootAmount ) - EVENT( EV_AddInvItem, idEntity::Event_AddInvItem ) - EVENT( EV_AddItemToInv, idEntity::Event_AddItemToInv ) - EVENT( EV_ReplaceInvItem, idEntity::Event_ReplaceInvItem ) - EVENT( EV_GetNextInvItem, idEntity::Event_GetNextInvItem ) - EVENT( EV_GetPrevInvItem, idEntity::Event_GetPrevInvItem ) - EVENT( EV_SetCurInvCategory, idEntity::Event_SetCurInvCategory ) - EVENT( EV_SetCurInvItem, idEntity::Event_SetCurInvItem ) - EVENT( EV_GetCurInvCategory, idEntity::Event_GetCurInvCategory ) - EVENT( EV_GetCurInvItemEntity, idEntity::Event_GetCurInvItemEntity ) - EVENT( EV_GetCurInvItemName, idEntity::Event_GetCurInvItemName ) - EVENT( EV_GetCurInvItemId, idEntity::Event_GetCurInvItemId ) - EVENT( EV_GetCurInvIcon, idEntity::Event_GetCurInvIcon ) - EVENT( EV_ChangeInvItemCount, idEntity::ChangeInventoryItemCount ) - EVENT( EV_ChangeInvLightgemModifier, idEntity::ChangeInventoryLightgemModifier ) - EVENT( EV_ChangeInvIcon, idEntity::ChangeInventoryIcon ) - EVENT( EV_InitInventory, idEntity::Event_InitInventory ) - - EVENT( EV_StimAdd, idEntity::Event_StimAdd) - EVENT( EV_StimRemove, idEntity::Event_StimRemove) - EVENT( EV_StimEnable, idEntity::Event_StimEnable) - EVENT( EV_StimClearIgnoreList, idEntity::Event_StimClearIgnoreList) - EVENT( EV_ResponseEnable, idEntity::Event_ResponseEnable) - EVENT( EV_ResponseAdd, idEntity::Event_ResponseAdd) - EVENT( EV_ResponseRemove, idEntity::Event_ResponseRemove) - EVENT( EV_ResponseIgnore, idEntity::Event_ResponseIgnore) - EVENT( EV_ResponseAllow, idEntity::Event_ResponseAllow) - EVENT( EV_ResponseSetAction, idEntity::Event_ResponseSetAction) - EVENT( EV_ResponseTrigger, idEntity::Event_ResponseTrigger) - EVENT( EV_GetResponseEntity, idEntity::Event_GetResponseEntity) - - EVENT( EV_TimerCreate, idEntity::Event_TimerCreate ) - EVENT( EV_TimerStop, idEntity::Event_TimerStop ) - EVENT( EV_TimerStart, idEntity::Event_TimerStart ) - EVENT( EV_TimerRestart, idEntity::Event_TimerRestart ) - EVENT( EV_TimerReset, idEntity::Event_TimerReset ) - EVENT( EV_TimerSetState, idEntity::Event_TimerSetState ) - - EVENT( EV_TDM_PropSound, idEntity::Event_PropSound ) - EVENT( EV_TDM_PropSoundMod, idEntity::Event_PropSoundMod ) - - EVENT( EV_TDM_RangedThreatTo, idEntity::Event_RangedThreatTo ) - -#ifdef MOD_WATERPHYSICS - - EVENT( EV_GetMass, idEntity::Event_GetMass ) - - EVENT( EV_IsInLiquid, idEntity::Event_IsInLiquid ) - -#endif // MOD_WATERPHYSICS - - EVENT( EV_CopyBind, idEntity::Event_CopyBind ) - EVENT( EV_IsFrobable, idEntity::Event_IsFrobable ) - EVENT( EV_SetFrobable, idEntity::Event_SetFrobable ) - EVENT( EV_IsHilighted, idEntity::Event_IsHilighted ) - EVENT( EV_Frob, idEntity::Event_Frob ) - EVENT( EV_FrobHilight, idEntity::Event_FrobHilight ) - EVENT( EV_CanSeeEntity, idEntity::Event_CanSeeEntity ) - EVENT( EV_CanBeUsedBy, idEntity::Event_CanBeUsedBy ) - - EVENT( EV_CheckAbsence, idEntity::Event_CheckAbsence ) - - EVENT (EV_GetTeam, idEntity::Event_GetTeam ) - EVENT (EV_SetTeam, idEntity::Event_SetTeam ) - - EVENT(EV_IsEnemy, idEntity::Event_IsEnemy ) - EVENT(EV_IsFriend, idEntity::Event_IsFriend ) - EVENT(EV_IsNeutral, idEntity::Event_IsNeutral ) - - EVENT(EV_SetEntityRelation, idEntity::Event_SetEntityRelation ) - EVENT(EV_ChangeEntityRelation, idEntity::Event_ChangeEntityRelation ) - - EVENT( EV_NoShadows, idEntity::Event_noShadows ) - - EVENT( EV_CheckMine, idEntity::Event_CheckMine ) // grayman #2478 - - EVENT( EV_GetVinePlantLoc, idEntity::Event_GetVinePlantLoc ) // grayman #2478 - EVENT( EV_GetVinePlantNormal, idEntity::Event_GetVinePlantNormal ) // grayman #2478 - -END_CLASS - -/* -================ -UpdateGuiParms -================ -*/ -void UpdateGuiParms( idUserInterface *gui, const idDict *args ) { - if ( gui == NULL || args == NULL ) { - return; - } - const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL ); - while( kv ) { - gui->SetStateString( kv->GetKey(), kv->GetValue() ); - kv = args->MatchPrefix( "gui_parm", kv ); - } - gui->SetStateBool( "noninteractive", args->GetBool( "gui_noninteractive" ) ) ; - gui->StateChanged( gameLocal.time ); -} - -/* -================ -AddRenderGui -================ -*/ -void AddRenderGui( const char *name, idUserInterface **gui, const idDict *args ) { - const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL ); - *gui = uiManager->FindGui( name, true, ( kv != NULL ) ); - UpdateGuiParms( *gui, args ); -} - -/* -================ -idGameEdit::ParseSpawnArgsToRenderEntity - -parse the static model parameters -this is the canonical renderEntity parm parsing, -which should be used by dmap and the editor -================ -*/ -void idGameEdit::ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity ) { - int i; - const char *temp; - idVec3 color; - float angle; - const idDeclModelDef *modelDef; - - memset( renderEntity, 0, sizeof( *renderEntity ) ); - - temp = args->GetString( "model" ); - - modelDef = NULL; - if ( temp[0] != '\0' ) { - if ( !strstr( temp, "." ) ) { - - // FIXME: temp hack to replace obsolete ips particles with prt particles - if ( !strstr( temp, ".ips" ) ) { - idStr str = temp; - str.Replace( ".ips", ".prt" ); - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, str, false ) ); - } else { - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, temp, false ) ); - } - if ( modelDef ) { - renderEntity->hModel = modelDef->ModelHandle(); - } - } - - if ( !renderEntity->hModel ) { - renderEntity->hModel = renderModelManager->FindModel( temp ); - } - } - if ( renderEntity->hModel ) { - renderEntity->bounds = renderEntity->hModel->Bounds( renderEntity ); - } else { - renderEntity->bounds.Zero(); - } - - idStr rskin = args->GetString( "random_skin", "" ); - if ( !rskin.IsEmpty() ) { - // found list, select a random skin - temp = rskin.RandomPart().c_str(); - } - else { - // else just use the "skin" spawnarg - temp = args->GetString( "skin" ); - } - - if ( temp[0] != '\0' ) { - renderEntity->customSkin = declManager->FindSkin( temp ); - } else if ( modelDef ) { - renderEntity->customSkin = modelDef->GetDefaultSkin(); - } - - temp = args->GetString( "shader" ); - if ( temp[0] != '\0' ) { - renderEntity->customShader = declManager->FindMaterial( temp ); - } - - args->GetVector( "origin", "0 0 0", renderEntity->origin ); - - // get the rotation matrix in either full form, or single angle form - if ( !args->GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", renderEntity->axis ) ) { - angle = args->GetFloat( "angle" ); - if ( angle != 0.0f ) { - renderEntity->axis = idAngles( 0.0f, angle, 0.0f ).ToMat3(); - } else { - renderEntity->axis.Identity(); - } - } - - renderEntity->referenceSound = NULL; - - // get shader parms - args->GetVector( "_color", "1 1 1", color ); - renderEntity->shaderParms[ SHADERPARM_RED ] = color[0]; - renderEntity->shaderParms[ SHADERPARM_GREEN ] = color[1]; - renderEntity->shaderParms[ SHADERPARM_BLUE ] = color[2]; - renderEntity->shaderParms[ 3 ] = args->GetFloat( "shaderParm3", "1" ); - renderEntity->shaderParms[ 4 ] = args->GetFloat( "shaderParm4", "0" ); - renderEntity->shaderParms[ 5 ] = args->GetFloat( "shaderParm5", "0" ); - renderEntity->shaderParms[ 6 ] = args->GetFloat( "shaderParm6", "0" ); - renderEntity->shaderParms[ 7 ] = args->GetFloat( "shaderParm7", "0" ); - renderEntity->shaderParms[ 8 ] = args->GetFloat( "shaderParm8", "0" ); - renderEntity->shaderParms[ 9 ] = args->GetFloat( "shaderParm9", "0" ); - renderEntity->shaderParms[ 10 ] = args->GetFloat( "shaderParm10", "0" ); - renderEntity->shaderParms[ 11 ] = args->GetFloat( "shaderParm11", "0" ); - - // check noDynamicInteractions flag - renderEntity->noDynamicInteractions = args->GetBool( "noDynamicInteractions" ); - - // check noshadows flag - renderEntity->noShadow = args->GetBool( "noshadows" ); - - // check noselfshadows flag - renderEntity->noSelfShadow = args->GetBool( "noselfshadows" ); - - // init any guis, including entity-specific states - for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - temp = args->GetString( i == 0 ? "gui" : va( "gui%d", i + 1 ) ); - if ( temp[ 0 ] != '\0' ) { - AddRenderGui( temp, &renderEntity->gui[ i ], args ); - } - } -} - -/* -================ -idGameEdit::ParseSpawnArgsToRefSound - -parse the sound parameters -this is the canonical refSound parm parsing, -which should be used by dmap and the editor -================ -*/ -void idGameEdit::ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound ) { - const char *temp; - - memset( refSound, 0, sizeof( *refSound ) ); - - refSound->parms.minDistance = args->GetFloat( "s_mindistance" ); - refSound->parms.maxDistance = args->GetFloat( "s_maxdistance" ); - refSound->parms.volume = args->GetFloat( "s_volume" ); - refSound->parms.shakes = args->GetFloat( "s_shakes" ); - - args->GetVector( "origin", "0 0 0", refSound->origin ); - - refSound->referenceSound = NULL; - - // if a diversity is not specified, every sound start will make - // a random one. Specifying diversity is usefull to make multiple - // lights all share the same buzz sound offset, for instance. - refSound->diversity = args->GetFloat( "s_diversity", "-1" ); - refSound->waitfortrigger = args->GetBool( "s_waitfortrigger" ); - - if ( args->GetBool( "s_omni" ) ) { - refSound->parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL; - } - if ( args->GetBool( "s_looping" ) ) { - refSound->parms.soundShaderFlags |= SSF_LOOPING; - } - if ( args->GetBool( "s_occlusion" ) ) { - refSound->parms.soundShaderFlags |= SSF_NO_OCCLUSION; - } - if ( args->GetBool( "s_global" ) ) { - refSound->parms.soundShaderFlags |= SSF_GLOBAL; - } - if ( args->GetBool( "s_unclamped" ) ) { - refSound->parms.soundShaderFlags |= SSF_UNCLAMPED; - } - refSound->parms.soundClass = args->GetInt( "s_soundClass" ); - - temp = args->GetString( "s_shader" ); - if ( temp[0] != '\0' ) { - refSound->shader = declManager->FindSound( temp ); - } -} - -// ---------------------------------------------------------------- - -/* -=============== -idEntity::UpdateChangeableSpawnArgs - -Any key val pair that might change during the course of the game ( via a gui or whatever ) -should be initialize here so a gui or other trigger can change something and have it updated -properly. An optional source may be provided if the values reside in an outside dictionary and -first need copied over to spawnArgs -=============== -*/ -void idEntity::UpdateChangeableSpawnArgs( const idDict *source ) { - int i; - const char *target; - - if ( !source ) { - source = &spawnArgs; - } - cameraTarget = NULL; - target = source->GetString( "cameraTarget" ); - if ( target && target[0] ) { - // update the camera taget - PostEventMS( &EV_UpdateCameraTarget, 0 ); - } - - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - UpdateGuiParms( renderEntity.gui[ i ], source ); - } -} - -/* -================ -idEntity::idEntity -================ -*/ -idEntity::idEntity() -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX %s\r", this, __FUNCTION__); - - entityNumber = ENTITYNUM_NONE; - entityDefNumber = -1; - - spawnNode.SetOwner( this ); - activeNode.SetOwner( this ); - - snapshotNode.SetOwner( this ); - snapshotSequence = -1; - snapshotBits = 0; - - thinkFlags = 0; - dormantStart = 0; - cinematic = false; - renderView = NULL; - cameraTarget = NULL; - health = 0; - maxHealth = 0; - - m_droppedByAI = false; // grayman #1330 - - m_preHideContents = -1; // greebo: initialise this to invalid values - m_preHideClipMask = -1; - m_CustomContents = -1; - - physics = NULL; - bindMaster = NULL; - bindJoint = INVALID_JOINT; - bindBody = -1; - teamMaster = NULL; - teamChain = NULL; - signals = NULL; - - memset( PVSAreas, 0, sizeof( PVSAreas ) ); - numPVSAreas = -1; - - memset( &fl, 0, sizeof( fl ) ); - fl.neverDormant = true; // most entities never go dormant - - memset( &renderEntity, 0, sizeof( renderEntity ) ); - modelDefHandle = -1; - memset( &refSound, 0, sizeof( refSound ) ); - - memset( &m_renderTrigger, 0, sizeof( m_renderTrigger ) ); - m_renderTrigger.axis.Identity(); - m_renderTriggerHandle = -1; - m_renderWaitingThread = 0; - - mpGUIState = -1; - - m_SetInMotionByActor = NULL; - m_MovedByActor = NULL; - m_bFrobable = false; - m_bFrobSimple = false; - m_FrobDistance = 0; - m_FrobBias = 1.0f; - m_FrobBox = NULL; - m_FrobActionScript = ""; - m_bFrobbed = false; - m_bFrobHighlightState = false; - m_FrobChangeTime = 0; - m_FrobActionLock = false; - m_bAttachedAlertControlsSolidity = false; - m_bIsObjective = false; - m_bIsClimbableRope = false; - m_bIsMantleable = false; - m_bIsBroken = false; - - // We give all the entities a Stim/Response collection so that we wont have to worry - // about the pointer being available all the time. The memory footprint of that - // object is rather small, so this doesn't really hurt that - // much and makes the code easier to control. - m_StimResponseColl = new CStimResponseCollection; - - // Since we have a function to return inventories/etc, and many entities won't - // have anything to do with inventories, I figure I'd better wait until - // absolutely necessary to create these. - m_Inventory = CInventoryPtr(); - m_InventoryCursor = CInventoryCursorPtr(); - - m_LightQuotient = 0; - m_LightQuotientLastEvalTime = -1; - - // by default no LOD to save memory and time - m_LODHandle = 0; - m_DistCheckTimeStamp = 0; - - // grayman #597 - for hiding arrows when nocked to the bow - m_HideUntilTime = 0; -} - -/* -================ -idEntity::FixupLocalizedStrings -================ -*/ -void idEntity::FixupLocalizedStrings() -{ - // Tels: Transform here things like "inv_category" "Maps" back to "#str_02390" so that custom - // entities in FMs with hard-coded english inventory categories or names still work even with - // the new translation code. - - int c = 2; - const char* todo[2] = { "inv_category", "inv_name" }; - - for (int i = 0; i < c; i++) - { - idStr spName = spawnArgs.GetString( todo[i], ""); - if (!spName.IsEmpty()) - { - idStr strTemplate = gameLocal.m_I18N->TemplateFromEnglish( spName ); - // "Maps" resulted in "#str_02390"? - if (spName != strTemplate) - { - gameLocal.Printf("%s: Fixing %s from %s to %s.\n", GetName(), todo[i], spName.c_str(), strTemplate.c_str() ); - spawnArgs.Set( todo[i], strTemplate ); - } - } - } -} - -/* -================ -idEntity::ParseLODSpawnargs - -Tels: Look at dist_think_interval, lod_1_distance etc. and fill the m_LOD - data. The passed in dict is usually just this->spawnArgs, but can also - be from a completely different entity def so we can parse the spawnargs - without having to actually have the entity spawned. The fRandom - value is used to selectively hide some entities when hide_probability - is set, and should be between 0 and 1.0. -================ -*/ -lod_handle idEntity::ParseLODSpawnargs( const idDict* dict, const float fRandom) -{ - lod_data_t *m_LOD = NULL; - - int d = int(1000.0f * dict->GetFloat( "dist_check_period", "0" )); - - float fHideDistance = dict->GetFloat( "hide_distance", "0.0" ); - - m_DistCheckTimeStamp = 0; - // a quick check for LOD, to avoid looking at all lod_x_distance spawnargs: - if (d == 0 && fHideDistance < 0.1f) - { - // no LOD wanted - m_DistCheckTimeStamp = NOLOD; - return 0; - } - - // distance dependent LOD from this point on: - // allocate new memory - m_LOD = new lod_data_t; - - // if interval not set, use twice per second - m_LOD->DistCheckInterval = ((d == 0) ? 500 : d); - - m_SkinLODCur = 0; - m_ModelLODCur = 0; - m_LODLevel = 0; - - m_LOD->noshadowsLOD = dict->GetBool( "noshadows", "0" ) ? 1 : 0; // the default value for level 0 - - // if > 0, if the entity is closer than this, lod_bias will be at minimum 1.0 - m_LOD->fLODNormalDistance = dict->GetFloat( "lod_normal_distance", "500" ); - if (m_LOD->fLODNormalDistance < 0.0f) - { - m_LOD->fLODNormalDistance = 0.0f; - } - - idStr temp; - m_LOD->OffsetLOD[0] = idVec3(0,0,0); // assume there is no custom per-LOD model offset - m_LOD->DistLODSq[0] = 0; - - // setup level 0 (aka "The one and only original") - m_LOD->ModelLOD[0] = dict->GetString( "model", "" ); - - // For func_statics where name == model, use "" so they can share the same LOD data - // even tho they all have different "models". (Their model spawnarg is never used.) - if ( IsType( idStaticEntity::Type ) && m_LOD->ModelLOD[0] == GetName()) - { - m_LOD->ModelLOD[0] = ""; - } - - // use whatever was set as skin, that can differ from spawnArgs.GetString("skin") due to random_skin: - if ( renderEntity.customSkin ) - { - m_LOD->SkinLOD[0] = renderEntity.customSkin->GetName(); - } - else - { - m_LOD->SkinLOD[0] = ""; - } - - // start at 1, since 0 is "the original level" setup already above - for (int i = 1; i < LOD_LEVELS; i++) - { - // set to 0,0,0 as default in case someone tries to use it - m_LOD->OffsetLOD[i] = idVec3(0,0,0); - - if (i < LOD_LEVELS - 1) - { - // for i == LOD_LEVELS - 1, we use "hide_distance" - sprintf(temp, "lod_%i_distance", i); - m_LOD->DistLODSq[i] = dict->GetFloat( temp, "0.0" ); - } - - // Tels: Fix #2635: if the LOD distance here is < fHideDistance, use hide distance-1 so the - // entity gets really hidden. - if (fHideDistance > 1.0f && m_LOD->DistLODSq[i] > fHideDistance) - { - m_LOD->DistLODSq[i] = fHideDistance - 1.0f; - } - - if (i == LOD_LEVELS - 1) - { - // last distance is named differently so you don't need to know how many levels the code supports: - m_LOD->DistLODSq[i] = fHideDistance; - - // compute a random number and check it against the hide probability spawnarg - // do this only once at setup time, so the setting is stable during runtime - float fHideProbability = dict->GetFloat( "lod_hide_probability", "1.0" ); - if (fRandom > fHideProbability) - { - // disable hiding - m_LOD->DistLODSq[i] = -1.0f; // disable - continue; - } - - // do we have a lod_fadeout_range? - m_LOD->fLODFadeOutRange = dict->GetFloat( "lod_fadeout_range", "0.0" ); - - if (m_LOD->fLODFadeOutRange < 0) - { - gameLocal.Warning (" %s: lod_fadeout_range must be >= 0 but is %f. Ignoring it.\n", GetName(), m_LOD->fLODFadeOutRange); - m_LOD->fLODFadeOutRange = 0.0f; - } - else - { - // square for easier comparisation with deltaSq - m_LOD->fLODFadeOutRange *= m_LOD->fLODFadeOutRange; - } - - // do we have a lod_fadein_range? - m_LOD->fLODFadeInRange = dict->GetFloat( "lod_fadein_range", "0.0" ); - - if (m_LOD->fLODFadeInRange < 0) - { - gameLocal.Warning (" %s: lod_fadein_range must be >= 0 but is %f. Ignoring it.\n", GetName(), m_LOD->fLODFadeInRange); - m_LOD->fLODFadeInRange = 0.0f; - } - else if (m_LOD->fLODFadeInRange > 0 && m_LOD->fLODFadeInRange > m_LOD->DistLODSq[1]) - { - gameLocal.Warning (" %s: lod_fadein_range must be <= lod_1_distance (%f) 0 but is %f. Ignoring it.\n", GetName(), m_LOD->DistLODSq[1], m_LOD->fLODFadeInRange); - m_LOD->fLODFadeOutRange = 0.0f; - } - else - { - // square for easier comparisation with deltaSq - m_LOD->fLODFadeInRange *= m_LOD->fLODFadeInRange; - } - - //gameLocal.Printf (" %s: lod_fadeout_range %0.2f lod_fadein_range %0.2f.\n", GetName(), m_LOD->fLODFadeOutRange, m_LOD->fLODFadeInRange); - } - -// gameLocal.Printf (" %s: init LOD %i m_LOD->DistLODSq=%f\n", GetName(), i, m_LOD->DistLODSq[i]); - - if (i > 0 && m_LOD->DistLODSq[i] > 0 && (m_LOD->DistLODSq[i] * m_LOD->DistLODSq[i]) < m_LOD->DistLODSq[i-1]) - { - gameLocal.Warning (" %s: LOD %i m_DistLODSq %f < LOD %i m_DistLODSq=%f (this will not work!)\n", - GetName(), i, m_LOD->DistLODSq[i] * m_LOD->DistLODSq[i], i-1, m_LOD->DistLODSq[i-1]); - } - // -1 should stay -1 to signal "don't use this level" - if (m_LOD->DistLODSq[i] > 0) - { - m_LOD->DistLODSq[i] *= m_LOD->DistLODSq[i]; - - // the last level is "hide", so we don't need a model, skin, offset or noshadows there - if (i < LOD_LEVELS - 1) - { - // not the last level - sprintf(temp, "model_lod_%i", i); - m_LOD->ModelLOD[i] = dict->GetString( temp ); - if (m_LOD->ModelLOD[i].Length() == 0) { m_LOD->ModelLOD[i] = m_LOD->ModelLOD[0]; } - - sprintf(temp, "skin_lod_%i", i); - m_LOD->SkinLOD[i] = dict->GetString( temp ); - if (m_LOD->SkinLOD[i].Length() == 0) { m_LOD->SkinLOD[i] = m_LOD->SkinLOD[0]; } - - // set the right bit for noshadows - sprintf(temp, "noshadows_lod_%i", i ); - // 1, 2, 4, 8, 16 etc - m_LOD->noshadowsLOD |= (dict->GetBool( temp, "0" ) ? 1 : 0) << i; - -// // set the right bit for "standin". "standins" are models that always rotate in -// // XY to face the player, but unlike particles, don't tilt with the view -// sprintf(temp, "standin_lod_%i", i ); -// // 1, 2, 4, 8, 16 etc -// m_LOD->standinLOD |= (dict->GetBool( temp, "0" ) ? 1 : 0) << i; - - // setup the manual offset for this LOD stage (needed to align some models) - sprintf(temp, "offset_lod_%i", i); - m_LOD->OffsetLOD[i] = dict->GetVector( temp, "0,0,0" ); - } - // else hiding needs no offset - - //gameLocal.Printf (" noshadowsLOD 0x%08x model %s skin %s\n", m_noshadowsLOD, m_ModelLOD[i].c_str(), m_SkinLOD[i].c_str() ); - } - else - { - // initialize to empty in case someone tries to access them - m_LOD->SkinLOD[i] = ""; - m_LOD->ModelLOD[i] = ""; - m_LOD->OffsetLOD[i] = idVec3(0,0,0); - } - } - - m_LOD->bDistCheckXYOnly = dict->GetBool( "dist_check_xy", "0" ); - - // add some phase diversity to the checks so that they don't all run in one frame - // make sure they all run on the first frame though, by initializing m_TimeStamp to - // be at least one interval early. - // old code, only using half the interval: - m_DistCheckTimeStamp = gameLocal.time - (int) (m_LOD->DistCheckInterval * (1.0f + gameLocal.random.RandomFloat()) ); - - // register the data with the ModelGenerator and return the handle - lod_handle h = gameLocal.m_ModelGenerator->RegisterLODData( m_LOD ); - - // free memory - delete m_LOD; - - return h; -} - -/* -================ -idEntity::Spawn -================ -*/ -void idEntity::Spawn( void ) -{ - int i; - const char *temp; - idVec3 origin; - idMat3 axis; - const idKeyValue *networkSync; - const char *classname; - const char *scriptObjectName; - - gameLocal.RegisterEntity( this ); - - spawnArgs.GetString( "classname", NULL, &classname ); - const idDeclEntityDef *def = gameLocal.FindEntityDef( classname, false ); - if ( def ) { - entityDefNumber = def->Index(); - } - - // every object will have a unique name - temp = spawnArgs.GetString( "name", va( "%s_%s_%d", GetClassname(), spawnArgs.GetString( "classname" ), entityNumber)); - SetName(temp); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("this: %08lX Name: [%s]\r", this, temp); - - FixupLocalizedStrings(); - - // parse static models the same way the editor display does - gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &renderEntity ); - - renderEntity.entityNum = entityNumber; - - // go dormant within 5 frames so that when the map starts most monsters are dormant - dormantStart = gameLocal.time - DELAY_DORMANT_TIME + gameLocal.msec * 5; - - origin = renderEntity.origin; - axis = renderEntity.axis; - - // do the audio parsing the same way dmap and the editor do - gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound ); - - // only play SCHANNEL_PRIVATE when sndworld->PlaceListener() is called with this listenerId - // don't spatialize sounds from the same entity - refSound.listenerId = entityNumber + 1; - - cameraTarget = NULL; - temp = spawnArgs.GetString( "cameraTarget" ); - if ( temp && temp[0] ) { - // update the camera taget - PostEventMS( &EV_UpdateCameraTarget, 0 ); - } - - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - UpdateGuiParms( renderEntity.gui[ i ], &spawnArgs ); - - // Add the (potentially NULL) GUI as an external GUI to our overlaysys, - // so that the script functions to interact with GUIs can interact with it. - if ( m_overlays.createOverlay( 0, OVERLAYS_MIN_HANDLE + i ) >= OVERLAYS_MIN_HANDLE ) - m_overlays.setGui( OVERLAYS_MIN_HANDLE + i, renderEntity.gui[ i ] ); - else - gameLocal.Warning( "Unable to create overlay for renderentity GUI: %d\n", OVERLAYS_MIN_HANDLE + i ); - } - - fl.solidForTeam = spawnArgs.GetBool( "solidForTeam", "0" ); - fl.neverDormant = spawnArgs.GetBool( "neverDormant", "0" ); - fl.hidden = spawnArgs.GetBool( "hide", "0" ); - if ( fl.hidden ) { - // make sure we're hidden, since a spawn function might not set it up right - PostEventMS( &EV_Hide, 0 ); - } - cinematic = spawnArgs.GetBool( "cinematic", "0" ); - - networkSync = spawnArgs.FindKey( "networkSync" ); - if ( networkSync ) { - fl.networkSync = ( atoi( networkSync->GetValue() ) != 0 ); - } - -#if 0 - if ( !gameLocal.isClient ) { - // common->DPrintf( "NET: DBG %s - %s is synced: %s\n", spawnArgs.GetString( "classname", "" ), GetType()->classname, fl.networkSync ? "true" : "false" ); - if ( spawnArgs.GetString( "classname", "" )[ 0 ] == '\0' && !fl.networkSync ) { - common->DPrintf( "NET: WRN %s entity, no classname, and no networkSync?\n", GetType()->classname ); - } - } -#endif - - bool haveTargets = false; // grayman #2603 - // if we have targets, wait until all entities are spawned to get them - if ( spawnArgs.MatchPrefix( "target" ) || spawnArgs.MatchPrefix( "guiTarget" ) ) - { - haveTargets = true; - if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { - PostEventMS( &EV_FindTargets, 0 ); - } else { - // not during spawn, so it's ok to get the targets - FindTargets(); - } - } - - // if we're attaching relight positions, they have to be added as targets, - // so we have to wait until all entities are spawned to do that - - health = spawnArgs.GetInt( "health" ); - - InitDefaultPhysics( origin, axis ); - - // TDM: Set custom contents, and store it so it doesn't get overwritten - m_CustomContents = spawnArgs.GetInt("clipmodel_contents","-1"); - if( m_CustomContents != -1 ) - GetPhysics()->SetContents( m_CustomContents ); - - SetOrigin( origin ); - SetAxis( axis ); - - // load visual model and broken model - LoadModels(); - - if ( spawnArgs.GetString( "bind", "", &temp ) ) - { - PostEventMS( &EV_SpawnBind, 0 ); - } - - //TDM: Parse list of pre-defined attachment positions from spawnargs - ParseAttachPositions(); - - //TDM: Parse and spawn and attach any attachments - ParseAttachments(); - - // grayman #2603 - if we spawned relight positions, add them to the target list - - if (spawnArgs.MatchPrefix("relight_position")) - { - if (haveTargets) - { - if (gameLocal.GameState() != GAMESTATE_STARTUP) - { - // not during spawn, so it's ok to add targets from the relight positions now - FindRelights(); - } - } - else - { - targets.Clear(); - // it's ok to create targets from the relight positions now - FindRelights(); - } - } - - // auto-start a sound on the entity - if ( refSound.shader && !refSound.waitfortrigger ) { - StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); - } - - // setup script object - if ( ShouldConstructScriptObjectAtSpawn() && spawnArgs.GetString( "scriptobject", NULL, &scriptObjectName ) ) { - if ( !scriptObject.SetType( scriptObjectName ) ) { - gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() ); - } - - ConstructScriptObject(); - } - - m_StimResponseColl->InitFromSpawnargs(spawnArgs, this); - - // greebo: Post the inventory check event. If this entity should be added - // to someone's inventory, the event takes care of that. This must happen - // after the entity has fully spawned (including subclasses), otherwise - // the clipmodel and things like that are not initialised (>> crash). - - // grayman #2820 - don't queue EV_InitInventory if it's going to - // end up doing nothing. Queuing this for every entity causes a ton - // of event posting during frame 0 that can overrun the event queue limit - // in large maps w/lots of entities. - - int lootValue = spawnArgs.GetInt( "inv_loot_value", "0" ); - int lootType = spawnArgs.GetInt( "inv_loot_type", "0" ); - bool belongsInInventory = spawnArgs.GetBool( "inv_map_start", "0" ); - - // Only post EV_InitInventory if this is loot OR it belongs in someone's inventory. - // If extra work is added to EV_InitInventory, then that must be accounted for here, to make sure it has - // a chance of getting done. - - if ( belongsInInventory || ( ( lootType > LOOT_NONE ) && ( lootType < LOOT_COUNT ) && ( lootValue != 0 ) ) ) - { - PostEventMS( &EV_InitInventory, 0, 0 ); - } - - // grayman #2478 - If this is a mine or flashmine, it can be armed - // at spawn time. Post an event to replace the mine with its - // projectile counterpart, which handles arming/disarming. Wait a - // bit before replacing so the mine has time to settle. - - if ( idStr::Cmp(spawnArgs.GetString("toolclass"), "mine") == 0 ) - { - PostEventSec(&EV_CheckMine, 1.0f); - } - - LoadTDMSettings(); - - if (m_AbsenceNoticeability > 0) - { - PostEventMS(&EV_CheckAbsence, gameLocal.random.RandomFloat() * 5000); - } - m_StartBounds = GetPhysics()->GetAbsBounds(); - m_AbsenceStatus = false; - - // parse LOD spawnargs - m_LODHandle = ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ); - - if (m_LODHandle) - { - // Have to start thinking if we're distance dependent - BecomeActive( TH_THINK ); - } - - // init most recent voice and body sound data for AI - grayman #2341 - previousVoiceShader = NULL; // shader for the most recent voice request - previousVoiceIndex = 0; // index of most recent voice sound requested (1->N, where there are N sounds) - previousBodyShader = NULL; // shader for the most recent body sound request - previousBodyIndex = 0; // index of most recent body sound requested (1->N, where there are N sounds) -} - -/* -================ -idEntity::DisableLOD - -Tels: temp. disable LOD checks by setting the next check timestamp to negative. -================ -*/ -void idEntity::DisableLOD( const bool doTeam ) -{ - // negate check interval - if (m_LODHandle && m_DistCheckTimeStamp > NOLOD) - { -// gameLocal.Printf( "%s: Temporarily disabling LOD.\n", GetName() ); - m_DistCheckTimeStamp = NOLOD; - } - - if (!doTeam) { return; } - - /* also all the bound entities in our team */ - idEntity* NextEnt = this; - idEntity* bindM = GetBindMaster(); - if ( bindM ) { NextEnt = bindM; } - - while ( NextEnt != NULL ) - { - //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); - idEntity *ent = static_cast( NextEnt ); - if (ent) - { - ent->DisableLOD( false ); - } - /* get next Team member */ - NextEnt = NextEnt->GetNextTeamEntity(); - } -} - -/* -================ -idEntity::EnableLOD - -Tels: Enable LOD checks again (after DisableLOD) by setting the check interval to positive. -================ -*/ -void idEntity::EnableLOD( const bool doTeam ) -{ - // negate check interval - if (m_LODHandle && m_DistCheckTimeStamp <= NOLOD) - { -// gameLocal.Printf( "%s: Enabling LOD again.\n", GetName() ); - m_DistCheckTimeStamp = gameLocal.time; - } - - if (!doTeam) { return; } - - /* also all the bound entities in our team */ - idEntity* NextEnt = this; - idEntity* bindM = GetBindMaster(); - if ( bindM ) { NextEnt = bindM; } - - while ( NextEnt != NULL ) - { - //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); - idEntity *ent = static_cast( NextEnt ); - if (ent) - { - ent->EnableLOD( false ); - } - /* get next Team member */ - NextEnt = NextEnt->GetNextTeamEntity(); - } -} - -/* -================ -idEntity::StopLOD - -Tels: Permanently disable LOD checks, if doTeam is true, including on all of our attachements -================ -*/ -void idEntity::StopLOD( const bool doTeam ) -{ - //BecomeInactive( TH_THINK ); - // deregister our LOD struct - if (m_LODHandle) - { - // gameLocal.Printf( "%s: Stopping LOD.\n", GetName() ); - gameLocal.m_ModelGenerator->UnregisterLODData( m_LODHandle ); - m_LODHandle = 0; - } - - if (!doTeam) { return; } - - /* also all the bound entities in our team */ - idEntity* NextEnt = this; - - idEntity* bindM = GetBindMaster(); - if ( bindM ) { NextEnt = bindM; } - - while ( NextEnt != NULL ) - { - //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); - idEntity *ent = static_cast( NextEnt ); - if (ent) - { - ent->StopLOD( false ); - } - /* get next Team member */ - NextEnt = NextEnt->GetNextTeamEntity(); - } -} - -/* -================ -idEntity::LoadModels -================ -*/ -// tels: this routine loads all the visual and collision models -void idEntity::LoadModels() -{ - idStr model; - // we only use a brokenModel if we can find one automatically - bool needBroken = false; - - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Loading models for entity %d (%s)\r", entityNumber, name.c_str() ); - - // load the normal visual model - spawnArgs.GetString( "model", "", model ); - - if ( !model.IsEmpty() ) { - SetModel( model ); - } - - // was a brokenModel requested? - spawnArgs.GetString( "broken", "", brokenModel ); - - // see if we need to create a broken model name - if ( !brokenModel.IsEmpty() ) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Need broken model '%s' for entity %d (%s)\r", brokenModel.c_str(), entityNumber, name.c_str() ); - // spawnarg "broken" was set, so we need the broken model - needBroken = true; - } - // only check for an auto-broken model if the entity could be damaged - else if ( health || spawnArgs.FindKey( "max_force" ) ) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Looking for broken models for entity %d (%s) (health: %d)\r", entityNumber, name.c_str(), health ); - - int pos = model.Find("."); - - if ( pos < 0 ) - { - pos = model.Length(); - } - - if ( pos > 0 ) - { - model.Left( pos, brokenModel ); - } - - brokenModel += "_broken"; - - if ( pos > 0 ) - { - brokenModel += &model[ pos ]; - } - } - - // greebo: Only try to cache the model if it actually exists -> otherwise tons of false warnings get emitted - bool brokenModelFileExists = (fileSystem->FindFile(brokenModel) != FIND_NO); - - if (brokenModelFileExists) - { - // check brokenModel to exist, and make sure the brokenModel gets cached - if ( !renderModelManager->CheckModel( brokenModel ) ) - { - if ( needBroken ) { - gameLocal.Error( "Broken model '%s' not loadable for entity %d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); - } - else { - // couldn't find automatically generated "model_broken.lwo", so don't use brokenModel at all - brokenModel = ""; - } - } - } - else - { - // Broken model file does not exist - if ( needBroken ) { - gameLocal.Error( "Broken model '%s' required for entity %d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); - } - // set brokenModel to empty, so we later don't try to use it - brokenModel = ""; - } - - // can we be damaged? - if ( health || spawnArgs.FindKey( "max_force" ) || !brokenModel.IsEmpty() ) - { - fl.takedamage = true; - } - - if ( brokenModelFileExists && !brokenModel.IsEmpty() ) - { - if ( model.IsEmpty() ) - { - gameLocal.Error( "Breakable entity (broken model %s) without a model set on entity #%d (%s)", brokenModel.c_str(), entityNumber, name.c_str() ); - } - - // make sure the collision model for the brokenModel gets cached - idClipModel::CheckModel( brokenModel ); - - // since we can be damaged, setup some physics -/* -* Ishtvan: Commented out, this is handled separately and this call can interfere with other places contents are set -* - GetPhysics()->SetContents( !spawnArgs.GetBool( "solid" ) ? 0 : CONTENTS_SOLID ); - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) { - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - } -**/ - - } // end of loading of broken model(s) and their CM - - -} - -/* -================ -idEntity::~idEntity -================ -*/ -idEntity::~idEntity( void ) -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); - - // Tels: #2430 - If this entity is shouldered by the player, dequip it forcefully - if (gameLocal.m_Grabber->GetEquipped() == this) - { - if ( spawnArgs.GetBool("shoulderable") ) - { - gameLocal.Printf("Grabber: Forcefully unshouldering %s because it will be removed.\n", GetName() ); - gameLocal.m_Grabber->UnShoulderBody(this); - } - gameLocal.Printf("Grabber: Forcefully dequipping %s because it will be removed.\n", GetName() ); - gameLocal.m_Grabber->Forget(this); - } - - // Let each objective entity we're currently in know about our destruction - for (int i = 0; i < m_objLocations.Num(); ++i) - { - CObjectiveLocation* locationEnt = m_objLocations[i].GetEntity(); - - if (locationEnt == NULL) continue; // probably already deleted - - locationEnt->OnEntityDestroyed(this); - } - - gameLocal.RemoveResponse(this); - gameLocal.RemoveStim(this); - - if ( gameLocal.GameState() != GAMESTATE_SHUTDOWN && !gameLocal.isClient && fl.networkSync && entityNumber >= MAX_CLIENTS ) { - idBitMsg msg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteByte( GAME_RELIABLE_MESSAGE_DELETE_ENT ); - msg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); - networkSystem->ServerSendReliableMessage( -1, msg ); - } - - DeconstructScriptObject(); - scriptObject.Free(); - - if ( thinkFlags ) { - BecomeInactive( thinkFlags ); - } - activeNode.Remove(); - - Signal( SIG_REMOVED ); - - // we have to set back the default physics object before unbinding because the entity - // specific physics object might be an entity variable and as such could already be destroyed. - SetPhysics( NULL ); - - // remove any entities that are bound to me - RemoveBinds(); - - // unbind from master - Unbind(); - QuitTeam(); - - gameLocal.RemoveEntityFromHash( name.c_str(), this ); - - delete renderView; - renderView = NULL; - - delete signals; - signals = NULL; - - // free optional LOD data - if (m_LODHandle) - { - StopLOD( false ); - } - - FreeModelDef(); - FreeSoundEmitter( false ); - - if ( m_renderTriggerHandle != -1 ) { - gameRenderWorld->FreeEntityDef( m_renderTriggerHandle ); - } - - gameLocal.UnregisterEntity( this ); - gameLocal.RemoveStim(this); - gameLocal.RemoveResponse(this); - delete m_StimResponseColl; - - if( m_FrobBox ) - delete m_FrobBox; - - m_FrobPeers.Clear(); -} - -void idEntity::AddObjectsToSaveGame(idSaveGame* savefile) -{ - // empty default implementation -} - -/* -================ -idEntity::Save -================ -*/ -void idEntity::Save( idSaveGame *savefile ) const -{ - int i, j; - - savefile->WriteInt( entityNumber ); - savefile->WriteInt( entityDefNumber ); - - // spawnNode and activeNode are restored by gameLocal - - savefile->WriteInt( snapshotSequence ); - savefile->WriteInt( snapshotBits ); - - savefile->WriteDict( &spawnArgs ); - savefile->WriteString( name ); - scriptObject.Save( savefile ); - - savefile->WriteInt( thinkFlags ); - savefile->WriteInt( dormantStart ); - savefile->WriteBool( cinematic ); - - savefile->WriteObject( cameraTarget ); - - savefile->WriteInt( health ); - savefile->WriteInt( maxHealth ); - - savefile->WriteInt( m_preHideContents ); - savefile->WriteInt( m_preHideClipMask ); - savefile->WriteInt( m_CustomContents ); - - savefile->WriteInt( targets.Num() ); - for( i = 0; i < targets.Num(); i++ ) { - targets[ i ].Save( savefile ); - } - - entityFlags_s flags = fl; - - LittleBitField( &flags, sizeof( flags ) ); - - savefile->Write( &flags, sizeof( flags ) ); - - savefile->WriteInt(m_UsedByName.Num()); - for (i = 0; i < m_UsedByName.Num(); i++) - { - savefile->WriteString(m_UsedByName[i].c_str()); - } - savefile->WriteInt(m_UsedByInvName.Num()); - for (i = 0; i < m_UsedByInvName.Num(); i++) - { - savefile->WriteString(m_UsedByInvName[i].c_str()); - } - savefile->WriteInt(m_UsedByCategory.Num()); - for (i = 0; i < m_UsedByCategory.Num(); i++) - { - savefile->WriteString(m_UsedByCategory[i].c_str()); - } - savefile->WriteInt(m_UsedByClassname.Num()); - for (i = 0; i < m_UsedByClassname.Num(); i++) - { - savefile->WriteString(m_UsedByClassname[i].c_str()); - } - - savefile->WriteBool(m_bAttachedAlertControlsSolidity); - savefile->WriteBool(m_bIsObjective); - - savefile->WriteInt(m_objLocations.Num()); - for (i = 0; i < m_objLocations.Num(); ++i) - { - m_objLocations[i].Save(savefile); - } - - savefile->WriteBool(m_bFrobable); - savefile->WriteBool(m_bFrobSimple); - savefile->WriteInt(m_FrobDistance); - savefile->WriteFloat(m_FrobBias); - savefile->WriteClipModel(m_FrobBox); - - savefile->WriteBool(m_bIsClimbableRope); - - savefile->WriteInt(m_animRates.Num()); - for (i = 0; i < m_animRates.Num(); i++) - { - savefile->WriteFloat(m_animRates[i]); - } - - m_SetInMotionByActor.Save(savefile); - m_MovedByActor.Save(savefile); - - savefile->WriteBool(m_bFrobbed); - savefile->WriteBool(m_bFrobHighlightState); - savefile->WriteInt(m_FrobChangeTime); - - savefile->WriteString(m_FrobActionScript); - - savefile->WriteInt(m_FrobPeers.Num()); - for (i = 0; i < m_FrobPeers.Num(); i++) - { - savefile->WriteString(m_FrobPeers[i]); - } - - savefile->WriteString(m_MasterFrob); - savefile->WriteBool(m_FrobActionLock); - - savefile->WriteFloat(m_AbsenceNoticeability); - savefile->WriteBounds(m_StartBounds); - savefile->WriteBool(m_AbsenceStatus); - - m_AbsenceMarker.Save(savefile); - - savefile->WriteInt(team); - - savefile->WriteInt(m_EntityRelations.size()); - for (EntityRelationsMap::const_iterator i = m_EntityRelations.begin(); i != m_EntityRelations.end(); ++i) - { - savefile->WriteObject(i->first); - savefile->WriteInt(i->second); - } - - savefile->WriteBool( m_bIsMantleable ); - - savefile->WriteBool( m_bIsBroken ); - savefile->WriteString( brokenModel ); - - m_StimResponseColl->Save(savefile); - - savefile->WriteRenderEntity( renderEntity ); - savefile->WriteInt( modelDefHandle ); - savefile->WriteRefSound( refSound ); - - savefile->WriteRenderEntity( m_renderTrigger ); - savefile->WriteInt( m_renderTriggerHandle ); - savefile->WriteInt( m_renderWaitingThread ); - - m_overlays.Save( savefile ); - - savefile->WriteObject( bindMaster ); - savefile->WriteJoint( bindJoint ); - savefile->WriteInt( bindBody ); - savefile->WriteObject( teamMaster ); - savefile->WriteObject( teamChain ); - - savefile->WriteStaticObject( defaultPhysicsObj ); - - savefile->WriteInt( numPVSAreas ); - for( i = 0; i < MAX_PVS_AREAS; i++ ) { - savefile->WriteInt( PVSAreas[ i ] ); - } - - if ( !signals ) { - savefile->WriteBool( false ); - } else { - savefile->WriteBool( true ); - for( i = 0; i < NUM_SIGNALS; i++ ) { - savefile->WriteInt( signals->signal[ i ].Num() ); - for( j = 0; j < signals->signal[ i ].Num(); j++ ) { - savefile->WriteInt( signals->signal[ i ][ j ].threadnum ); - savefile->WriteString( signals->signal[ i ][ j ].function->Name() ); - } - } - } - - savefile->WriteInt( mpGUIState ); - - savefile->WriteBool(m_Inventory != NULL); - if (m_Inventory != NULL) { - m_Inventory->Save(savefile); - } - - savefile->WriteBool(m_InventoryCursor != NULL); - if (m_InventoryCursor != NULL) { - // Save the ID of the cursor - savefile->WriteInt(m_InventoryCursor->GetId()); - } - - savefile->WriteInt( m_Attachments.Num() ); - for( int i=0; i < m_Attachments.Num(); i++ ) - m_Attachments[i].Save( savefile ); - - savefile->WriteInt( m_AttNameMap.size() ); - for ( AttNameMap::const_iterator k = m_AttNameMap.begin(); - k != m_AttNameMap.end(); ++k ) - { - savefile->WriteString( k->first.c_str() ); - savefile->WriteInt( k->second ); - } - - savefile->WriteInt( m_AttachPositions.Num() ); - for ( i = 0; i < m_AttachPositions.Num(); i++ ) - { - m_AttachPositions[i].Save( savefile ); - } - - m_userManager.Save(savefile); - - savefile->WriteFloat(m_LightQuotient); - savefile->WriteInt(m_LightQuotientLastEvalTime); - - savefile->WriteBool(m_droppedByAI); // grayman #1330 - - savefile->WriteInt(m_LODHandle); - savefile->WriteInt(m_DistCheckTimeStamp); - savefile->WriteInt(m_LODLevel); - savefile->WriteInt(m_ModelLODCur); - savefile->WriteInt(m_SkinLODCur); - - // grayman #2341 - don't save previous voice and body shaders and indices, - // since they're irrelevant across saved games - - savefile->WriteSoundShader(NULL); // previousVoiceShader - savefile->WriteInt(0); // previousVoiceIndex - savefile->WriteSoundShader(NULL); // previousBodyShader - savefile->WriteInt(0); // previousBodyIndex - - // grayman #597 - - savefile->WriteInt(m_HideUntilTime); // arrow-hiding timer - - // grayman #2787 - savefile->WriteVec3( m_VinePlantLoc ); - savefile->WriteVec3( m_VinePlantNormal ); -} - -/* -================ -idEntity::Restore -================ -*/ -void idEntity::Restore( idRestoreGame *savefile ) -{ - int i, j; - int num; - idStr funcname; - - savefile->ReadInt( entityNumber ); - savefile->ReadInt( entityDefNumber ); - - // spawnNode and activeNode are restored by gameLocal - - savefile->ReadInt( snapshotSequence ); - savefile->ReadInt( snapshotBits ); - - savefile->ReadDict( &spawnArgs ); - savefile->ReadString( name ); - SetName( name ); - - scriptObject.Restore( savefile ); - - savefile->ReadInt( thinkFlags ); - savefile->ReadInt( dormantStart ); - savefile->ReadBool( cinematic ); - - savefile->ReadObject( reinterpret_cast( cameraTarget ) ); - - savefile->ReadInt( health ); - savefile->ReadInt( maxHealth ); - - savefile->ReadInt( m_preHideContents ); - savefile->ReadInt( m_preHideClipMask ); - savefile->ReadInt( m_CustomContents ); - - targets.Clear(); - savefile->ReadInt( num ); - targets.SetNum( num ); - for( i = 0; i < num; i++ ) { - targets[ i ].Restore( savefile ); - } - - savefile->Read( &fl, sizeof( fl ) ); - LittleBitField( &fl, sizeof( fl ) ); - - savefile->ReadInt(num); - m_UsedByName.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(m_UsedByName[i]); - } - savefile->ReadInt(num); - m_UsedByInvName.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(m_UsedByInvName[i]); - } - savefile->ReadInt(num); - m_UsedByCategory.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(m_UsedByCategory[i]); - } - savefile->ReadInt(num); - m_UsedByClassname.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(m_UsedByClassname[i]); - } - - savefile->ReadBool(m_bAttachedAlertControlsSolidity); - savefile->ReadBool(m_bIsObjective); - - savefile->ReadInt(num); - m_objLocations.SetNum(num); - for (i = 0; i < num; ++i) - { - m_objLocations[i].Restore(savefile); - } - - savefile->ReadBool(m_bFrobable); - savefile->ReadBool(m_bFrobSimple); - savefile->ReadInt(m_FrobDistance); - savefile->ReadFloat(m_FrobBias); - savefile->ReadClipModel(m_FrobBox); - - savefile->ReadBool(m_bIsClimbableRope); - - savefile->ReadInt(num); - m_animRates.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadFloat(m_animRates[i]); - } - - m_SetInMotionByActor.Restore(savefile); - m_MovedByActor.Restore(savefile); - - savefile->ReadBool(m_bFrobbed); - savefile->ReadBool(m_bFrobHighlightState); - savefile->ReadInt(m_FrobChangeTime); - - savefile->ReadString(m_FrobActionScript); - - savefile->ReadInt(num); - m_FrobPeers.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(m_FrobPeers[i]); - } - - savefile->ReadString(m_MasterFrob); - savefile->ReadBool(m_FrobActionLock); - - savefile->ReadFloat(m_AbsenceNoticeability); - savefile->ReadBounds(m_StartBounds); - savefile->ReadBool(m_AbsenceStatus); - - m_AbsenceMarker.Restore(savefile); - - savefile->ReadInt(team); - - savefile->ReadInt(num); - for (int i = 0; i < num; ++i) - { - idEntity* entity; - savefile->ReadObject(reinterpret_cast(entity)); - - int relation; - savefile->ReadInt(relation); - - m_EntityRelations[entity] = relation; - } - - - savefile->ReadBool(m_bIsMantleable); - - savefile->ReadBool( m_bIsBroken ); - savefile->ReadString( brokenModel ); - - m_StimResponseColl->Restore(savefile); - - savefile->ReadRenderEntity( renderEntity ); - savefile->ReadInt( modelDefHandle ); - savefile->ReadRefSound( refSound ); - - savefile->ReadRenderEntity( m_renderTrigger ); - savefile->ReadInt( m_renderTriggerHandle ); - savefile->ReadInt( m_renderWaitingThread ); - - m_overlays.Restore( savefile ); - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - // Add the (potentially NULL) GUI as an external GUI to our overlaysys, - // so that the script functions to interact with GUIs can interact with it. - // If the overlay isn't external, then the entity inheriting us must have - // messed with the overlays, and doesn't want us to set it. If it IS - // external, then they'll be resetting it anyways, so no harm done. - if ( m_overlays.isExternal( OVERLAYS_MIN_HANDLE + i ) ) - m_overlays.setGui( OVERLAYS_MIN_HANDLE + i, renderEntity.gui[ i ] ); - } - - savefile->ReadObject( reinterpret_cast( bindMaster ) ); - savefile->ReadJoint( bindJoint ); - savefile->ReadInt( bindBody ); - savefile->ReadObject( reinterpret_cast( teamMaster ) ); - savefile->ReadObject( reinterpret_cast( teamChain ) ); - - savefile->ReadStaticObject( defaultPhysicsObj ); - RestorePhysics( &defaultPhysicsObj ); - - savefile->ReadInt( numPVSAreas ); - for( i = 0; i < MAX_PVS_AREAS; i++ ) { - savefile->ReadInt( PVSAreas[ i ] ); - } - - bool readsignals; - savefile->ReadBool( readsignals ); - if ( readsignals ) { - signals = new signalList_t; - for( i = 0; i < NUM_SIGNALS; i++ ) { - savefile->ReadInt( num ); - signals->signal[ i ].SetNum( num ); - for( j = 0; j < num; j++ ) { - savefile->ReadInt( signals->signal[ i ][ j ].threadnum ); - savefile->ReadString( funcname ); - signals->signal[ i ][ j ].function = gameLocal.program.FindFunction( funcname ); - if ( !signals->signal[ i ][ j ].function ) { - savefile->Error( "Function '%s' not found", funcname.c_str() ); - } - } - } - } - - savefile->ReadInt( mpGUIState ); - - bool hasInventory; - savefile->ReadBool(hasInventory); - if (hasInventory) { - Inventory()->Restore(savefile); - } - - bool hasInventoryCursor; - savefile->ReadBool(hasInventoryCursor); - if (hasInventoryCursor) { - // Get the ID of the cursor - int cursorId; - savefile->ReadInt(cursorId); - m_InventoryCursor = Inventory()->GetCursor(cursorId); - } - - m_Attachments.Clear(); - savefile->ReadInt( num ); - m_Attachments.SetNum( num ); - for( int i=0; i < num; i++ ) - m_Attachments[i].Restore( savefile ); - - m_AttNameMap.clear(); - savefile->ReadInt( num ); - for ( int i = 0; i < num; i++ ) - { - idStr tempStr; - savefile->ReadString(tempStr); - - int tempIndex; - savefile->ReadInt(tempIndex); - - m_AttNameMap.insert(AttNameMap::value_type(tempStr.c_str(), tempIndex)); - } - - m_AttachPositions.Clear(); - savefile->ReadInt( num ); - for ( i = 0; i < num; i++ ) - { - SAttachPosition &attachPos = m_AttachPositions.Alloc(); - attachPos.Restore( savefile ); - } - - // restore must retrieve modelDefHandle from the renderer - if ( modelDefHandle != -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } - - // restore must retrieve m_renderTriggerHandle from the renderer - if ( m_renderTriggerHandle != -1 ) { - m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); - } - - m_userManager.Restore(savefile); - - savefile->ReadFloat(m_LightQuotient); - savefile->ReadInt(m_LightQuotientLastEvalTime); - - savefile->ReadBool(m_droppedByAI); // grayman #1330 - - savefile->ReadUnsignedInt(m_LODHandle); - savefile->ReadInt(m_DistCheckTimeStamp); - savefile->ReadInt(m_LODLevel); - savefile->ReadInt(m_ModelLODCur); - savefile->ReadInt(m_SkinLODCur); - - // grayman #2341 - restore previous voice and body shaders and indices - - savefile->ReadSoundShader((const idSoundShader *&)previousVoiceShader); - savefile->ReadInt(previousVoiceIndex); - savefile->ReadSoundShader((const idSoundShader *&)previousBodyShader); - savefile->ReadInt(previousBodyIndex); - - // grayman #597 - - savefile->ReadInt(m_HideUntilTime); // arrow-hiding timer - - // grayman #2787 - - savefile->ReadVec3( m_VinePlantLoc ); - savefile->ReadVec3( m_VinePlantNormal ); - - - // Tels #2417: after Restore call RestoreScriptObject() of the scriptObject so the - // script object can restore f.i. sounds: - - const function_t *func = scriptObject.GetFunction( "RestoreScriptObject" ); - if (func) - { - idThread *thread = idThread::CurrentThread(); - if (!thread) - { - gameLocal.Printf("No running thread for RestoreScriptObject(), creating new one.\n"); - thread = new idThread(); - thread->SetThreadName( name.c_str() ); - } - // gameLocal.Warning( "Will call function '%s' in '%s'", "RestoreScriptObject", scriptObject.GetTypeName() ); - if ( func->type->NumParameters() != 1 ) { - gameLocal.Warning( "Function 'RestoreScriptObject' has the wrong number of parameters"); - } - thread->CallFunction( this, func, true ); - thread->DelayedStart( 0 ); - } -/* else - { - gameLocal.Warning("No RestoreScriptObject() function in script object for %s", GetName() ); - } -*/ - // done with calling "Restore()" on the script object -} - -/* -================ -idEntity::GetEntityDefName -================ -*/ -const char * idEntity::GetEntityDefName( void ) const -{ - if ( entityDefNumber < 0 ) { - return "*unknown*"; - } - return declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); -} - -/* -================ -idEntity::SetName -================ -*/ -void idEntity::SetName( const char *newname ) -{ - if ( name.Length() ) { - gameLocal.RemoveEntityFromHash( name.c_str(), this ); - gameLocal.program.SetEntity( name, NULL ); - } - - name = newname; - if ( name.Length() ) { - if ( ( name == "NULL" ) || ( name == "null_entity" ) ) { - gameLocal.Error( "Cannot name entity '%s'. '%s' is reserved for script.", name.c_str(), name.c_str() ); - } - gameLocal.AddEntityToHash( name.c_str(), this ); - gameLocal.program.SetEntity( name, this ); - } -} - -/* -================ -idEntity::GetName -================ -*/ -const char * idEntity::GetName( void ) const { - return name.c_str(); -} - - -/*********************************************************************** - - Thinking about LOD - - We pass a ptr to the current data, so that the SEED can let the spawned - entities think while still keeping their LOD data only once per class. - - This routine will only modify: - * m_LODLevel - * m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; - - It will also return the new alpha value for this entity, where 0.0f means - hidden and alpha > 0 means visible. - - The caller is responsible for calling SetAlpha() and Hide/Show on the - proper entity (e.g. the entity thet the m_LOD is for) as well as - switching the model and skin. - -***********************************************************************/ -float idEntity::ThinkAboutLOD( const lod_data_t *m_LOD, const float deltaSq ) -{ - // have no LOD - if (NULL == m_LOD) - { - // fully visible - return 1.0f; - } - - bool bWithinDist = false; - - // by default fully visible - float fAlpha = 1.0f; - -// gameLocal.Warning("%s: ThinkAboutLOD called with m_LOD %p deltaSq %0.2f", GetName(), m_LOD, deltaSq); - - // Tels: check in which LOD level we are - for (int i = 0; i < LOD_LEVELS; i++) - { -// gameLocal.Printf ("%s considering LOD %i (distance %f)\n", GetName(), i, m_LOD->DistLODSq[i] ); - - // skip this level (but not the first) - if (m_LOD->DistLODSq[i] <= 0 && i > 0) - { -// gameLocal.Printf ("%s skipping LOD %i (distance %f)\n", GetName(), i, m_LOD->DistLODSq[i] ); - continue; - } - - // find the next usable level - int nextLevel = i + 1; - while (nextLevel < LOD_LEVELS && m_LOD->DistLODSq[nextLevel] <= 0 ) - { - nextLevel++; - } - -// gameLocal.Printf ("%s ThinkAboutLOD deltaSq = %0.2f (this=%0.2f, nextLevel=%i, next=%0.2f, i=%i)\n", GetName(), deltaSq, m_LOD->DistLODSq[i], -// nextLevel, nextLevel < LOD_LEVELS ? m_LOD->DistLODSq[nextLevel] : -1, i ); - - // found a usable next level, or the last level is -1 (means no hide) - if (nextLevel < LOD_LEVELS) - { - bWithinDist = ((deltaSq > m_LOD->DistLODSq[i]) && (deltaSq <= m_LOD->DistLODSq[nextLevel])); - } - else - { - if (m_LOD->DistLODSq[ LOD_LEVELS - 1] < 0) - { -// gameLocal.Printf ("%s no next level (last level is -1)\n", GetName() ); - bWithinDist = (deltaSq > m_LOD->DistLODSq[ i ]); - } - else - { - if (i < LOD_LEVELS - 1) - { - bWithinDist = (deltaSq < m_LOD->DistLODSq[ LOD_LEVELS - 1]); - } - else - { - // only hide if hiding isn't disabled - // last usable level goes to infinity - bWithinDist = m_LOD->DistLODSq[i] > 0 && (deltaSq > m_LOD->DistLODSq[i]); - } - - // compute the alpha value of still inside the fade range - if (bWithinDist) - { - if (m_LOD->fLODFadeOutRange > 0) - { -// gameLocal.Printf ("%s outside hide_distance %0.2f (%0.2f) with fade %0.2f\n", GetName(), m_LOD->DistLODSq[i], deltaSq, m_LOD->fLODFadeOutRange); - if (deltaSq > (m_LOD->DistLODSq[i] + m_LOD->fLODFadeOutRange)) - { - fAlpha = 0.0f; - } - else - { - fAlpha = 1.0f - ( (deltaSq - m_LOD->DistLODSq[i]) / m_LOD->fLODFadeOutRange ); - } - // set the timestamp so we think the next frame again to get a smooth blend: - m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; - } - else - { - // just hide if outside - fAlpha = 0.0f; - } - m_LODLevel = i; - -// gameLocal.Printf (" %s returning LOD level %i, fAlpha = %0.2f", GetName(), i, fAlpha); - - // early out, we found the right level and switched - return fAlpha; - } - } - } - -// gameLocal.Printf (" %s passed LOD %i distance check %f (%f), inside?: %i (old level %i, prel. alpha %0.2f)\n", -// GetName(), i, m_LOD->DistLODSq[i], deltaSq, bWithinDist, m_LODLevel, fAlpha); - - // do this even if we are already in the same level - // && m_LODLevel != i) - if ( bWithinDist ) - { - m_LODLevel = i; - - // LOD level number i - // TODO: Hiding a LOD entity temp. completely would fail, - // as the LOD levels < LAST_LOD_LEVEL would show it again. - - if (i == 0 && m_LOD->fLODFadeInRange > 0) - { - // do we need to hide the entity, or fade it? - if (deltaSq < (m_LOD->DistLODSq[0] - m_LOD->fLODFadeInRange)) - { - fAlpha = 0.0f; // hide - } - else - { - fAlpha = (deltaSq - (m_LOD->DistLODSq[0] - m_LOD->fLODFadeInRange)) / m_LOD->fLODFadeOutRange; - // gameLocal.Printf ("%s fading in to %0.2f\n", GetName(), fAlpha); - } - // set the timestamp so we think the next frame again to get a smooth blend: - m_DistCheckTimeStamp = gameLocal.time - m_LOD->DistCheckInterval - 0.1; - } - else - { - // visible in all other levels - fAlpha = 1.0f; // show - } - -// gameLocal.Printf (" %s returning LOD level %i, fAlpha = %0.2f (step 2)", GetName(), i, fAlpha); - - // We found the right level and will switch to it - return fAlpha; - } - - // end for all LOD levels - } - -// gameLocal.Warning("%s: ThinkAboutLOD fall out of lod levels, using fAlpha = 1.0f", GetName() ); - - return fAlpha; -} - -/* Tels: - - Call ThinkAboutLOD, then do the nec. things like calling Hide()/Show(), SetAlpha() etc. -*/ -bool idEntity::SwitchLOD( const lod_data_t *m_LOD, const float deltaSq ) -{ - if (!m_LOD) - { - gameLocal.Error("SwitchLOD() with NULL called.\n"); - } - // remember the current level - int oldLODLevel = m_LODLevel; - float fAlpha = ThinkAboutLOD( m_LOD, deltaSq ); - -// gameLocal.Printf("%s: Got fAlpha %0.2f\n", GetName(), fAlpha); - - if (fAlpha < 0.0001f) - { - if (!fl.hidden) - { -// gameLocal.Printf( "%s Hiding\n", GetName() ); - Hide(); - } - } - else - { - if (fl.hidden) - { -// gameLocal.Printf("Showing %s again (%0.2f)\n", GetName(), fAlpha); - Show(); - SetAlpha( fAlpha, true ); - } - // Only set the alpha if we are actually fading, but skip if it is 1.0f - else if (renderEntity.shaderParms[ SHADERPARM_ALPHA ] != fAlpha) - { -// gameLocal.Printf("%s: Setting alpha %0.2f\n", GetName(), fAlpha); - SetAlpha( fAlpha, true ); - } - } - - if (m_LODLevel != oldLODLevel) - { -// gameLocal.Printf( "%s LOD level changed from %i to %i\n", GetName(), oldLODLevel, m_LODLevel ); - if (m_ModelLODCur != m_LODLevel) - { -// gameLocal.Printf( "%s switching to LOD %i (model %s offset %f %f %f)\n", -// GetName(), m_LODLevel, m_LOD->ModelLOD[m_LODLevel].c_str(), m_LOD->OffsetLOD[m_LODLevel].x, m_LOD->OffsetLOD[m_LODLevel].x, m_LOD->OffsetLOD[m_LODLevel].z ); - // func_statics that have map geometry do not have a model, and their LOD data gets "" - // as model name so they can all share the same data. However, we must not use "" when - // setting a new model: - if (!m_LOD->ModelLOD[m_LODLevel].IsEmpty()) - { - SetModel( m_LOD->ModelLOD[m_LODLevel] ); - } - m_ModelLODCur = m_LODLevel; - // Fix 1.04 blinking bug: - // if the old LOD level had an offset, we need to revert this. - // and if the new one has an offset, we need to add it: - idVec3 originShift = m_LOD->OffsetLOD[oldLODLevel] + m_LOD->OffsetLOD[m_LODLevel]; - // avoid SetOrigin() if there is no change (it causes a lot of behind-the-scenes calls) - if (originShift.x != 0.0f || originShift.y != 0.0f || originShift.z != 0.0f) - { - SetOrigin( renderEntity.origin - m_LOD->OffsetLOD[oldLODLevel] + m_LOD->OffsetLOD[m_LODLevel] ); - } - } - - if ( m_SkinLODCur != m_LODLevel) - { - const idDeclSkin *skinD = declManager->FindSkin( m_LOD->SkinLOD[m_LODLevel] ); - if (skinD) - { - SetSkin( skinD ); - } - m_SkinLODCur = m_LODLevel; - } - // level 0 is the default - renderEntity.noShadow = (m_LOD->noshadowsLOD & (1 << (m_LODLevel + 1))) > 0 ? 1 : 0; - - // switched LOD - return true; - } - - // no switch done - return false; -} - -/* -================ -idEntity::GetLODDistance - -Returns the distance that should be considered for LOD and hiding, depending on: - -* the distance of the entity origin to the given player origin - (TODO: this should be actualy the distance to the closest point of the entity, - to aovid that very long entities get hidden when you are far from their origin, - but close to their corner) -* the lod-bias set in the menu -* some minimum and maximum distances based on entity size/importance - -The returned value is the (virtual) distance squared, and rounded down to an integer. -================ -*/ -float idEntity::GetLODDistance( const lod_data_t *m_LOD, const idVec3 &playerOrigin, const idVec3 &entOrigin, const idVec3 &entSize, const float lod_bias ) const -{ - idVec3 delta = playerOrigin - entOrigin; - // enforce an absolute minimum of 500 units for entities w/o LOD - float minDist = 0.0f; - - if( m_LOD && m_LOD->bDistCheckXYOnly) - { - // todo: allow passing in a different gravityNormal - idVec3 vGravNorm = GetPhysics()->GetGravityNormal(); - delta -= (vGravNorm * delta) * vGravNorm; - } - - // let the mapper override it - if ( m_LOD && m_LOD->fLODNormalDistance > 0) - { - // gameLocal.Printf ("%s: Using %0.2f lod_normal_distance, delta %0.2f.\n", GetName(), m_LOD->fLODNormalDistance, deltaSq); - minDist = m_LOD->fLODNormalDistance; - } - - // multiply with the user LOD bias setting, and return the result: - // floor the value to avoid inaccurancies leading to toggling when the player stands still: - assert(lod_bias > 0.01f); - float deltaSq = delta.LengthSqr(); - - // if the entity is inside the "lod_normal_distance", simply ignore any LOD_BIAS < 1.0f - // Tels: For v1.05 use at least 1.0f for lod_bias, so that any distance the mapper sets - // acts as the absolute minimum distance. Needs fixing later. - //if (minDist > 0 && lod_bias < 1.0f && deltaSq < (minDist * minDist)) - if (lod_bias <= 1.0f) - { - deltaSq = idMath::Floor( deltaSq ); - } - else - { - deltaSq = idMath::Floor( deltaSq / (lod_bias * lod_bias) ); - } - - // TODO: enforce minimum/maximum distances based on entity size/importance - return deltaSq; -} - -/* -================ -idEntity::Think -================ -*/ -void idEntity::Think( void ) -{ - RunPhysics(); - if ( (thinkFlags & TH_PHYSICS) && m_FrobBox ) - { - // update trigger position - // TODO: Tels: What about hidden entities, these would use (0,0,0) as origin here? - m_FrobBox->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - } - - if (m_LODHandle && m_DistCheckTimeStamp > NOLOD) - { - const lod_data_t *lod = gameLocal.m_ModelGenerator->GetLODDataPtr( m_LODHandle ); - - if (lod) - { - // If this entity has LOD, let it think about it: - - // Distance dependence checks - if ( ( lod->DistCheckInterval > 0) - && ( (gameLocal.time - m_DistCheckTimeStamp) > lod->DistCheckInterval ) ) - { - m_DistCheckTimeStamp = gameLocal.time; - -// gameLocal.Warning("%s: Think called with m_LOD %p, %i, interval %i, origin %s", -// GetName(), m_LOD, m_DistCheckTimeStamp, m_LOD->DistCheckInterval, GetPhysics()->GetOrigin().ToString() ); - - SwitchLOD( lod, - GetLODDistance( lod, gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin(), renderEntity.bounds.GetSize(), cv_lod_bias.GetFloat() ) ); - } - } - } - Present(); -} - -/* -================ -idEntity::DoDormantTests - -Monsters and other expensive entities that are completely closed -off from the player can skip all of their work -================ -*/ -bool idEntity::DoDormantTests( void ) -{ - if (cv_ai_opt_forceopt.GetBool()) return true; // Everything always dormant! - if ( fl.neverDormant ) { - return false; - } - - // if the monster area is not topologically connected to a player - if ( !gameLocal.InPlayerConnectedArea( this ) ) { - if ( dormantStart == 0 ) { - dormantStart = gameLocal.time; - } - if ( gameLocal.time - dormantStart < DELAY_DORMANT_TIME ) { - // just got closed off, don't go dormant yet - return false; - } - return true; - } else { - // the monster area is topologically connected to a player, but if - // the monster hasn't been woken up before, do the more precise PVS check - // TDM: Never wake up permanently; always do PVS check. - // (This may cause bugs. I did this for AI optimisation testing.) - // --Crispy - if ( true || !fl.hasAwakened ) { - if ( !gameLocal.InPlayerPVS( this ) ) { - return true; // stay dormant - } - } - - // wake up - dormantStart = 0; - fl.hasAwakened = true; // only go dormant when area closed off now, not just out of PVS - - return false; - } - -// return false; -} - -/* -================ -idEntity::CheckDormant - -Monsters and other expensive entities that are completely closed -off from the player can skip all of their work -================ -*/ -bool idEntity::CheckDormant( void ) -{ - bool dormant; - - dormant = DoDormantTests(); - if ( dormant && !fl.isDormant ) { - fl.isDormant = true; - DormantBegin(); - } else if ( !dormant && fl.isDormant ) { - fl.isDormant = false; - DormantEnd(); - } - - return dormant; -} - -/* -================ -idEntity::DormantBegin - -called when entity becomes dormant -================ -*/ -void idEntity::DormantBegin( void ) { -} - -/* -================ -idEntity::DormantEnd - -called when entity wakes from being dormant -================ -*/ -void idEntity::DormantEnd( void ) { -} - -/* -================ -idEntity::IsBroken -================ -*/ -bool idEntity::IsBroken( void ) const { - return m_bIsBroken; -} - - -/* -================ -idEntity::SpawnFlinder spawns zero, one or more flinder objects as -described by one FlinderSpawn struct. The activator is the entity -that caused this entity to break up. - -@return: -1 for error, or the number of entities spawned - -*/ -int idEntity::SpawnFlinder( const FlinderSpawn& fs, idEntity *activator ) -{ - int spawned = 0; - - for (int i = 0; i < fs.m_Count; i++) - { - // probability 0.6 => spawn in only 60% of all cases - if (fs.m_Probability < 1.0 && - gameLocal.random.RandomFloat() >= fs.m_Probability) - { - continue; - } - - const idDict *p_entityDef = gameLocal.FindEntityDefDict( fs.m_Entity.c_str(), false ); - if( p_entityDef ) - { - idEntity *flinder; - gameLocal.SpawnEntityDef( *p_entityDef, &flinder, false ); - idPhysics *physics; - idVec3 TumbleVec(vec3_zero); - - if ( !flinder ) - { - gameLocal.Error( "Failed to spawn flinder entity %s", fs.m_Entity.c_str() ); - return -1; - } - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Spawned entity %s\r", flinder->GetName() ); - - physics = flinder->GetPhysics(); - - // move the entity to the origin (plus offset) and orientation of the original - physics->SetOrigin( GetPhysics()->GetOrigin() + fs.m_Offset ); - physics->SetAxis( GetPhysics()->GetAxis() ); - // give the flinders the same speed as the original entity (in case it breaks - // up while on the move - // tels FIXME: We would need to count how many flinders were spawned then distribute - // the impulse from the activator in equal parts to each of them. - // tels FIXME: Currently these are zero when an arrow hits a bottle. - - // for now add a small random speed so the object moves - // tels FIXME: Doesn't work. Because the flinder is inside the still solid - // entity? - TumbleVec[0] += (gameLocal.random.RandomFloat() * 20) - 10; - TumbleVec[1] += (gameLocal.random.RandomFloat() * 20) - 10; - TumbleVec[2] += (gameLocal.random.RandomFloat() * 20) - 10; - - physics->SetLinearVelocity( - GetPhysics()->GetLinearVelocity() - + activator->GetPhysics()->GetLinearVelocity() - + TumbleVec - ); - physics->SetAngularVelocity( - GetPhysics()->GetAngularVelocity() - + activator->GetPhysics()->GetAngularVelocity() - + TumbleVec - ); - - /* - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Activator is: %s\r", activator->GetName() ); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Set linear velocity to %f %f %f:\r", - physics->GetLinearVelocity().x, - physics->GetLinearVelocity().y, - physics->GetLinearVelocity().z ); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Set angular velocity to %f %f %f:\r", - physics->GetAngularVelocity().x, - physics->GetAngularVelocity().y, - physics->GetAngularVelocity().z ); - */ - - if( activator->IsType(idActor::Type) ) - { - idActor *actor = static_cast(activator); - flinder->m_SetInMotionByActor = actor; - flinder->m_MovedByActor = actor; - } - - // activate the flinder, so it falls realistically down - flinder->BecomeActive(TH_PHYSICS|TH_THINK); - // FIXME if this entity has a skin, set the same skin on the flinder - // FIXME add a small random impulse outwards from entity origin - spawned++; - } - } // end for m_Count - - return spawned; -} - -/* -================ -idEntity::BecomeBroken -================ -*/ -void idEntity::BecomeBroken( idEntity *activator ) -{ - if (m_bIsBroken) - { - // we are already broken, so do nothing - return; - } - - m_bIsBroken = true; - - // switch to the brokenModel if it was defined - if ( brokenModel.Length() ) - { - SetModel( brokenModel ); - - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Breaking entity %s (solid: %i)\r", name.c_str(), spawnArgs.GetBool( "solid" ) ); - if ( spawnArgs.GetBool( "solid" ) ) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Setting new clipmodel '%s'\r)", brokenModel.c_str() ); - - idClipModel* clipmodel = new idClipModel( brokenModel ); - - if (clipmodel && clipmodel->IsTraceModel() && GetPhysics()) - { - GetPhysics()->SetClipModel( clipmodel, 1.0f ); - } - } - } - else if ( spawnArgs.GetBool( "hideModelOnBreak" ) ) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Hiding broken entity %s\r", name.c_str() ); - SetModel( "" ); - GetPhysics()->SetContents( 0 ); - } - - // tels: if a break_up_script is defined, run it: - idStr str; - if (this->spawnArgs.GetString("break_up_script", "", str)) - { - // Call the script - idThread* thread = CallScriptFunctionArgs(str.c_str(), true, 0, "e", this); - if (thread != NULL) - { - // Run the thread at once, the script result might be needed below. - thread->Execute(); - } - } - - // tels: if we have flinders to spawn on break, do so now - Flinderize( activator ); -} - -/* -================ -idEntity::IsActive -================ -*/ -bool idEntity::IsActive( void ) const { - return activeNode.InList(); -} - -/* -================ -idEntity::BecomeActive -================ -*/ -void idEntity::BecomeActive( int flags ) -{ - if ( ( flags & TH_PHYSICS ) ) { - // enable the team master if this entity is part of a physics team - if ( teamMaster && teamMaster != this ) { - teamMaster->BecomeActive( TH_PHYSICS ); - } else if ( !( thinkFlags & TH_PHYSICS ) ) { - // if this is a pusher - if ( physics->IsType( idPhysics_Parametric::Type ) || physics->IsType( idPhysics_Actor::Type ) ) { - gameLocal.sortPushers = true; - } - } - } - - int oldFlags = thinkFlags; - thinkFlags |= flags; - - if ( thinkFlags ) { - if ( !IsActive() ) { - activeNode.AddToEnd( gameLocal.activeEntities ); - } else if ( !oldFlags ) { - // we became inactive this frame, so we have to decrease the count of entities to deactivate - gameLocal.numEntitiesToDeactivate--; - } - } -} - -/* -================ -idEntity::BecomeInactive -================ -*/ -void idEntity::BecomeInactive( int flags ) -{ - if ( ( flags & TH_PHYSICS ) ) { - // may only disable physics on a team master if no team members are running physics or bound to a joints - if ( teamMaster == this ) { - for ( idEntity *ent = teamMaster->teamChain; ent; ent = ent->teamChain ) { - if ( ( ent->thinkFlags & TH_PHYSICS ) || ( ( ent->bindMaster == this ) && ( ent->bindJoint != INVALID_JOINT ) ) ) { - flags &= ~TH_PHYSICS; - break; - } - } - } - } - - if ( thinkFlags ) { - thinkFlags &= ~flags; - if ( !thinkFlags && IsActive() ) { - gameLocal.numEntitiesToDeactivate++; - } - } - - if ( ( flags & TH_PHYSICS ) ) { - // if this entity has a team master - if ( teamMaster && teamMaster != this ) { - // if the team master is at rest - if ( teamMaster->IsAtRest() ) { - teamMaster->BecomeInactive( TH_PHYSICS ); - } - } - } -} - -/*********************************************************************** - - Visuals - -***********************************************************************/ - -/* -================ -idEntity::SetShaderParm -================ -*/ -void idEntity::SetShaderParm( int parmnum, float value ) -{ - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Warning( "shader parm index (%d) out of range", parmnum ); - return; - } - - renderEntity.shaderParms[ parmnum ] = value; - // tels: TODO: UpdateVisuals does stuff like updating the Model Transform, - // calling updating the MD5 animation, clear the PVS areas, calling updateSound() - // etc. All these things might be unnec. for just modifying a shaderParm, see if - // we can optimize this. - UpdateVisuals(); -} - -/* -================ -idEntity::SetColor -================ -*/ -void idEntity::SetColor( const float red, const float green, const float blue ) { - renderEntity.shaderParms[ SHADERPARM_RED ] = red; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = green; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = blue; - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); -} - -/* -================ -idEntity::SetColor -================ -*/ -void idEntity::SetColor( const idVec3 &color ) { - SetColor( color[ 0 ], color[ 1 ], color[ 2 ] ); - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); -} - -/* -================ -idEntity::GetColor -================ -*/ -void idEntity::GetColor( idVec3 &out ) const { - out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ]; - out[ 1 ] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; - out[ 2 ] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; -} - -/* -================ -idEntity::SetColor -================ -*/ -void idEntity::SetColor( const idVec4 &color ) { - renderEntity.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ]; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); -} - -/* -================ -idEntity::SetAlpha - -Tels: Just set the alpha value. Note: Due to the D3 engine not being - able to render faces transparently with correct lighting (you - either get 100% opaque with correct light, or 50% transparent - with correct light, or X% transparent with incorrect light), - this doesn't actually work unless you have a material - shader that takes the alpha value into account. -================ -*/ -void idEntity::SetAlpha( const float alpha ) { - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = alpha; - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); -} - -/* -================ -idEntity::SetAlpha - -Tels: Set alpha including on our children -================ -*/ -void idEntity::SetAlpha( const float alpha, const bool bound ) { - - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = alpha; - - if (!bound) - { - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); - return; - } - - // show our bind-children - idEntity *ent; - idEntity *next; - - for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) - { - next = ent->GetNextTeamEntity(); - if ( ent->GetBindMaster() == this ) - { - ent->SetAlpha( alpha ); - } - } - // tels: TODO: See note in idEntity::SetShaderParm about optimizing this. - UpdateVisuals(); -} - -/* -================ -idEntity::GetColor -================ -*/ -void idEntity::GetColor( idVec4 &out ) const { - out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ]; - out[ 1 ] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; - out[ 2 ] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; - out[ 3 ] = renderEntity.shaderParms[ SHADERPARM_ALPHA ]; -} - -/* -================ -idEntity::UpdateAnimationControllers -================ -*/ -bool idEntity::UpdateAnimationControllers( void ) { - // any ragdoll and IK animation controllers should be updated here - return false; -} - -/* -================ -idEntity::SetModel -================ -*/ -void idEntity::SetModel( const char *modelname ) { - assert( modelname ); - - FreeModelDef(); - - // FIXME: temp hack to replace obsolete ips particles with prt particles - if ( strstr( modelname, ".ips" ) != NULL ) { - idStr str = modelname; - str.Replace( ".ips", ".prt" ); - renderEntity.hModel = renderModelManager->FindModel( str ); - } else { - renderEntity.hModel = renderModelManager->FindModel( modelname ); - } - - if ( renderEntity.hModel ) { - renderEntity.hModel->Reset(); - } - - renderEntity.callback = NULL; - - renderEntity.numJoints = 0; - renderEntity.joints = NULL; - if ( renderEntity.hModel ) { - renderEntity.bounds = renderEntity.hModel->Bounds( &renderEntity ); - } else { - renderEntity.bounds.Zero(); - } - - UpdateVisuals(); -} - -/* -================ -idEntity::SetSkin -================ -*/ -void idEntity::SetSkin( const idDeclSkin *skin ) { - renderEntity.customSkin = skin; - UpdateVisuals(); -} - -/* -================ -idEntity::GetSkin -================ -*/ -const idDeclSkin *idEntity::GetSkin( void ) const { - return renderEntity.customSkin; -} - -/* -================ -idEntity::FreeModelDef -================ -*/ -void idEntity::FreeModelDef( void ) { - if ( modelDefHandle != -1 ) { - gameRenderWorld->FreeEntityDef( modelDefHandle ); - modelDefHandle = -1; - } -} - -/* -================ -idEntity::FreeLightDef -================ -*/ -void idEntity::FreeLightDef( void ) { -} - -/* -================ -idEntity::IsHidden -================ -*/ -bool idEntity::IsHidden( void ) const { - return fl.hidden; -} - -/* -================ -idEntity::SetHideUntilTime -================ -*/ -void idEntity::SetHideUntilTime(int time) // grayman #597 -{ - m_HideUntilTime = time; -} - -/* -================ -idEntity::GetHideUntilTime -================ -*/ -int idEntity::GetHideUntilTime() // grayman #597 -{ - return m_HideUntilTime; -} - -/* -================ -idEntity::Hide -================ -*/ -void idEntity::Hide( void ) -{ - if ( !IsHidden() ) - { - fl.hidden = true; - - idPhysics* p = GetPhysics(); - - m_preHideContents = p->GetContents(); - m_preHideClipMask = p->GetClipMask(); - - if( m_FrobBox ) - m_FrobBox->SetContents(0); - - FreeModelDef(); - UpdateVisuals(); - - // If we are hiding a currently frobbed entity, - // set the frob pointers to NULL to avoid stale pointers - idPlayer* player = gameLocal.GetLocalPlayer(); - - if (player != NULL) - { - if (player->m_FrobEntity.GetEntity() == this) - { - player->m_FrobEntity = NULL; - } - } - - // hide our bind-children - for (idEntity* ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity()) - { - if (ent->GetBindMaster() == this) - { - ent->Hide(); - - if (ent->IsType(idLight::Type)) - { - static_cast(ent)->Off(); - } - } - } - } -} - -/* -================ -idEntity::Show -================ -*/ -void idEntity::Show( void ) -{ - // greebo: If the pre-hide clipmask is still uninitialised on Show(), the entity - // has not been hidden before. Set this to something valid (i.e. the current clipmask) - if ( m_preHideClipMask == -1) - { - m_preHideClipMask = GetPhysics()->GetClipMask(); - } - - if ( m_preHideContents == -1) - { - m_preHideContents = GetPhysics()->GetContents(); - } - - if ( IsHidden() ) - { - fl.hidden = false; - if( m_FrobBox && m_bFrobable ) - { - m_FrobBox->SetContents( CONTENTS_FROBABLE ); - } - UpdateVisuals(); - - // show our bind-children - idEntity *ent; - idEntity *next; - - for( ent = GetNextTeamEntity(); ent != NULL; ent = next ) - { - next = ent->GetNextTeamEntity(); - if ( ent->GetBindMaster() == this ) - { - if (gameLocal.time >= ent->GetHideUntilTime()) // grayman #597 - one second needs to pass before showing - { - ent->Show(); - if ( ent->IsType( idLight::Type ) ) - { - static_cast( ent )->On(); - } - } - } - } - } -} - -float idEntity::GetLightQuotient() -{ - if (m_LightQuotientLastEvalTime < gameLocal.time) - { - idPhysics* physics = GetPhysics(); - - // Get the bounds and move it upwards a tiny bit - idBounds bounds = physics->GetAbsBounds() + physics->GetGravityNormal() * 0.1f; // Tweak to stay out of floors - - // A single point doesn't work with ellipse intersection - bounds.ExpandSelf(0.1f); - - // Update the cache - m_LightQuotientLastEvalTime = gameLocal.time; - m_LightQuotient = LAS.queryLightingAlongLine(bounds[0], bounds[1], this, true); - } - - // Return the cached result - return m_LightQuotient; -} - -/* -================ -idEntity::Event_noShadows - -tels: Turn shadows from this entity on or off. -================ -*/ -void idEntity::Event_noShadows( bool noShadow ) -{ - renderEntity.noShadow = ( noShadow ? 1 : 0 ); - UpdateVisuals(); -} - -/* -================ -idEntity::Event_CheckMine - -grayman #2478: Replace an armed mine with its projectile counterpart -================ -*/ -void idEntity::Event_CheckMine() -{ - if ( !spawnArgs.GetBool( "armed", "0" ) ) - { - return; // not armed, nothing to do - } - - const char* replaceWith = spawnArgs.GetString( "def_armed" ); // get replacement entity def - - const idDict *resultDef = gameLocal.FindEntityDefDict( replaceWith, false ); - if ( resultDef ) - { - idEntity *newMine; - gameLocal.SpawnEntityDef( *resultDef, &newMine, false ); - idProjectile* projectile = static_cast(newMine); - projectile->Launch( GetPhysics()->GetOrigin(), idVec3( 0,0,1 ), vec3_origin ); - - // Undo the launch parameters to keep the mine from flying away. - - idPhysics* projPhysics = projectile->GetPhysics(); - projPhysics->SetOrigin( GetPhysics()->GetOrigin() ); - projPhysics->SetAxis( GetPhysics()->GetAxis() ); - projPhysics->SetLinearVelocity( vec3_origin ); - projPhysics->SetAngularVelocity( vec3_origin ); - projPhysics->PutToRest(); - projectile->UpdateVisuals(); - projectile->SetReplaced(); // grayman #2908 - note that this mine replaced an author-placed armed mine - - SetFrobable(false); - PostEventMS( &EV_Remove, 1 ); // Remove the mine, which has been replaced - } -} - -/* -================ -idEntity::Event_GetVinePlantLoc - -grayman #2787: Return the planting location resulting from a trace -================ -*/ -void idEntity::Event_GetVinePlantLoc() -{ - idThread::ReturnVector( m_VinePlantLoc ); -} - -/* -================ -idEntity::Event_GetVinePlantNormal - -grayman #2787: Return the planting location surface normal resulting from a trace -================ -*/ -void idEntity::Event_GetVinePlantNormal() -{ - idThread::ReturnVector( m_VinePlantNormal ); -} - -/* -================ -idEntity::UpdateModelTransform -================ -*/ -void idEntity::UpdateModelTransform( void ) { - idVec3 origin; - idMat3 axis; - - if ( GetPhysicsToVisualTransform( origin, axis ) ) { - renderEntity.axis = axis * GetPhysics()->GetAxis(); - renderEntity.origin = GetPhysics()->GetOrigin() + origin * renderEntity.axis; - } else { - renderEntity.axis = GetPhysics()->GetAxis(); - renderEntity.origin = GetPhysics()->GetOrigin(); - } -} - -/* -================ -idEntity::UpdateModel -================ -*/ -void idEntity::UpdateModel( void ) { - UpdateModelTransform(); - - // check if the entity has an MD5 model - idAnimator *animator = GetAnimator(); - if(animator && animator->ModelHandle()) - { - // set the callback to update the joints - renderEntity.callback = idEntity::ModelCallback; - } - - // set to invalid number to force an update the next time the PVS areas are retrieved - ClearPVSAreas(); - - // ensure that we call Present this frame - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idEntity::UpdateVisuals -================ -*/ -void idEntity::UpdateVisuals( void ) { - UpdateModel(); - UpdateSound(); -} - -/* -================ -idEntity::UpdatePVSAreas -================ -*/ -void idEntity::UpdatePVSAreas( void ) { - int localNumPVSAreas, localPVSAreas[32]; - idBounds modelAbsBounds; - int i; - - modelAbsBounds.FromTransformedBounds( renderEntity.bounds, renderEntity.origin, renderEntity.axis ); - localNumPVSAreas = gameLocal.pvs.GetPVSAreas( modelAbsBounds, localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); - - // FIXME: some particle systems may have huge bounds and end up in many PVS areas - // the first MAX_PVS_AREAS may not be visible to a network client and as a result the particle system may not show up when it should - if ( localNumPVSAreas > MAX_PVS_AREAS ) { - localNumPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( modelAbsBounds.GetCenter() ).Expand( 64.0f ), localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); - } - - for ( numPVSAreas = 0; numPVSAreas < MAX_PVS_AREAS && numPVSAreas < localNumPVSAreas; numPVSAreas++ ) { - PVSAreas[numPVSAreas] = localPVSAreas[numPVSAreas]; - } - - for( i = numPVSAreas; i < MAX_PVS_AREAS; i++ ) { - PVSAreas[ i ] = 0; - } -} - -/* -================ -idEntity::UpdatePVSAreas -================ -*/ -void idEntity::UpdatePVSAreas( const idVec3 &pos ) { - int i; - - numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( pos ), PVSAreas, MAX_PVS_AREAS ); - i = numPVSAreas; - while ( i < MAX_PVS_AREAS ) { - PVSAreas[ i++ ] = 0; - } -} - -/* -================ -idEntity::GetNumPVSAreas -================ -*/ -int idEntity::GetNumPVSAreas( void ) { - if ( numPVSAreas < 0 ) { - UpdatePVSAreas(); - } - return numPVSAreas; -} - -/* -================ -idEntity::GetPVSAreas -================ -*/ -const int *idEntity::GetPVSAreas( void ) { - if ( numPVSAreas < 0 ) { - UpdatePVSAreas(); - } - return PVSAreas; -} - -/* -================ -idEntity::ClearPVSAreas -================ -*/ -void idEntity::ClearPVSAreas( void ) { - numPVSAreas = -1; -} - -/* -================ -idEntity::PhysicsTeamInPVS - - FIXME: for networking also return true if any of the entity shadows is in the PVS -================ -*/ -bool idEntity::PhysicsTeamInPVS( pvsHandle_t pvsHandle ) { - idEntity *part; - - if ( teamMaster ) { - for ( part = teamMaster; part; part = part->teamChain ) { - if ( gameLocal.pvs.InCurrentPVS( pvsHandle, part->GetPVSAreas(), part->GetNumPVSAreas() ) ) { - return true; - } - } - } else { - return gameLocal.pvs.InCurrentPVS( pvsHandle, GetPVSAreas(), GetNumPVSAreas() ); - } - return false; -} - -/* -============== -idEntity::ProjectOverlay -============== -*/ -void idEntity::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { - float s, c; - idMat3 axis, axistemp; - idVec3 localOrigin, localAxis[2]; - idPlane localPlane[2]; - - // make sure the entity has a valid model handle - if ( modelDefHandle < 0 ) { - return; - } - - // only do this on dynamic md5 models - if ( renderEntity.hModel->IsDynamicModel() != DM_CACHED ) { - return; - } - - idMath::SinCos16( gameLocal.random.RandomFloat() * idMath::TWO_PI, s, c ); - - axis[2] = -dir; - axis[2].NormalVectors( axistemp[0], axistemp[1] ); - axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; - axis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; - - renderEntity.axis.ProjectVector( origin - renderEntity.origin, localOrigin ); - renderEntity.axis.ProjectVector( axis[0], localAxis[0] ); - renderEntity.axis.ProjectVector( axis[1], localAxis[1] ); - - size = 1.0f / size; - localAxis[0] *= size; - localAxis[1] *= size; - - localPlane[0] = localAxis[0]; - localPlane[0][3] = -( localOrigin * localAxis[0] ) + 0.5f; - - localPlane[1] = localAxis[1]; - localPlane[1][3] = -( localOrigin * localAxis[1] ) + 0.5f; - - const idMaterial *mtr = declManager->FindMaterial( material ); - - // project an overlay onto the model - gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr ); - - // make sure non-animating models update their overlay - UpdateVisuals(); -} - -/* -================ -idEntity::Present - -Present is called to allow entities to generate refEntities, lights, etc for the renderer. -================ -*/ -void idEntity::Present(void) -{ -/* - if( m_bFrobable ) - { -*/ -/* - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("this: %08lX FrobDistance: %lu\r", this, m_FrobDistance); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("RenderEntity: %08lX\r", renderEntity); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("SurfaceInView: %u\r", renderEntity.allowSurfaceInViewID); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("RenderModel: %08lX\r", renderEntity.hModel); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("CustomShader: %08lX\r", renderEntity.customShader); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ReferenceShader: %08lX\r", renderEntity.referenceShader); - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ReferenceShader: %08lX\r", renderEntity.referenceShader); - - for(int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++) - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("Shaderparam[%u]: %f\r", i, renderEntity.shaderParms[i]); - - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("ForceUpdate: %u\r", renderEntity.forceUpdate); - - renderEntity.customShader = gameLocal.GetGlobalMaterial(); - } -*/ - - if(!gameLocal.isNewFrame ) - return; - - if( m_bFrobable ) - { - UpdateFrobState(); - UpdateFrobDisplay(); - } - - // don't present to the renderer if the entity hasn't changed - if(!(thinkFlags & TH_UPDATEVISUALS)) - return; - - if( !m_bFrobable ) - { - BecomeInactive( TH_UPDATEVISUALS ); - } - - // camera target for remote render views - if(cameraTarget && gameLocal.InPlayerPVS(this)) - renderEntity.remoteRenderView = cameraTarget->GetRenderView(); - - // if set to invisible, skip - if(!renderEntity.hModel || IsHidden()) - return; - - // add to refresh list - if ( modelDefHandle == -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } - - PresentRenderTrigger(); -} - -/* -================ -idEntity::GetRenderEntity -================ -*/ -renderEntity_t *idEntity::GetRenderEntity( void ) { - return &renderEntity; -} - -/* -================ -idEntity::GetModelDefHandle -================ -*/ -int idEntity::GetModelDefHandle( void ) { - return modelDefHandle; -} - -/* -================ -idEntity::UpdateRenderEntity -================ -*/ -bool idEntity::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) -{ - if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { - return false; - } - - idAnimator *animator = GetAnimator(); - if ( animator ) { - return animator->CreateFrame( gameLocal.time, false ); - } - - return false; -} - -/* -================ -idEntity::ModelCallback - - NOTE: may not change the game state whatsoever! -================ -*/ -bool idEntity::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) -{ - idEntity *ent; - - ent = gameLocal.entities[ renderEntity->entityNum ]; - - if ( !ent ) { - gameLocal.Error( "idEntity::ModelCallback: callback with NULL game entity" ); - } - - return ent->UpdateRenderEntity( renderEntity, renderView ); -} - -/* -================ -idEntity::GetAnimator - -Subclasses will be responsible for allocating animator. -================ -*/ -idAnimator *idEntity::GetAnimator( void ) { - return NULL; -} - -/* -============= -idEntity::GetRenderView - -This is used by remote camera views to look from an entity -============= -*/ -renderView_t *idEntity::GetRenderView( void ) { - if ( !renderView ) { - renderView = new renderView_t; - } - memset( renderView, 0, sizeof( *renderView ) ); - - renderView->vieworg = GetPhysics()->GetOrigin(); - renderView->fov_x = 120; - renderView->fov_y = 120; - renderView->viewaxis = GetPhysics()->GetAxis(); - - // copy global shader parms - for( int i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - renderView->shaderParms[ i ] = gameLocal.globalShaderParms[ i ]; - } - - renderView->globalMaterial = gameLocal.GetGlobalMaterial(); - - renderView->time = gameLocal.time; - - return renderView; -} - -void idEntity::Activate(idEntity* activator) -{ - // Fire the TRIGGER response - TriggerResponse(activator, ST_TRIGGER); - - if (RespondsTo(EV_Activate) || HasSignal(SIG_TRIGGER)) - { - Signal(SIG_TRIGGER); - ProcessEvent(&EV_Activate, activator); - TriggerGuis(); - } -} - -/*********************************************************************** - - Sound - -***********************************************************************/ - -/* -================ -idEntity::CanPlayChatterSounds - -Used for playing chatter sounds on monsters. -================ -*/ -bool idEntity::CanPlayChatterSounds( void ) const { - return true; -} - -/* -================ -idEntity::StartSound -================ -*/ -bool idEntity::StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length, float propVolMod) -{ - const idSoundShader *shader; - const char *sound; - - if ( length ) - *length = 0; - - // we should ALWAYS be playing sounds from the def. - // hardcoded sounds MUST be avoided at all times because they won't get precached. - assert( idStr::Icmpn( soundName, "snd_", 4 ) == 0 ); - - if ( !spawnArgs.GetString( soundName, "", &sound ) ) - return false; - - // ignore empty spawnargs - if ( sound[0] == '\0' ) - return false; - - if ( !gameLocal.isNewFrame ) - { - // don't play the sound, but don't report an error - return true; - } - - // DarkMod sound propagation: - PropSoundDirect(soundName, true, false, propVolMod); - - // play the audible sound - shader = declManager->FindSound( sound ); - - return StartSoundShader( shader, channel, soundShaderFlags, broadcast, length ); -} - -/* -================ -idEntity::StartSoundShader -================ -*/ -bool idEntity::StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length) { - float diversity; - int len; - - if ( length ) { - *length = 0; - } - - if ( !shader ) { - return false; - } - - if ( !gameLocal.isNewFrame ) { - return true; - } - - if ( gameLocal.isServer && broadcast ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_SOUND, shader->Index() ) ); - msg.WriteByte( channel ); - ServerSendEvent( EVENT_STARTSOUNDSHADER, &msg, false, -1 ); - } - - // set a random value for diversity unless one was parsed from the entity - - if ( refSound.diversity < 0.0f ) - { - diversity = gameLocal.random.RandomFloat(); - - // grayman #2341 - adjust diversity based on previous sound request, - // to eliminate consecutive sounds. This - // is necessary because sometimes the engine plays the - // wrong sound when the 'no_dup' flag is set. - - int n = shader->GetNumSounds(); - if (n > 1) // duplication is expected when there's only 1 sound choice - { - if (channel == SND_CHANNEL_VOICE) - { - if ((shader == previousVoiceShader) && (previousVoiceIndex == static_cast(diversity * n) + 1)) - { - diversity = (static_cast (previousVoiceIndex % n))/(static_cast (n)) + 0.01; // add 0.01 to move off the boundary - } - } - else if (channel == SND_CHANNEL_BODY) - { - if ((shader == previousBodyShader) && (previousBodyIndex == static_cast(diversity * n) + 1)) - { - diversity = (static_cast (previousBodyIndex % n))/(static_cast (n)) + 0.01; // add 0.01 to move off the boundary - } - } - } - } - else - { - diversity = refSound.diversity; - } - - // if we don't have a soundEmitter allocated yet, get one now - if ( !refSound.referenceSound ) { - refSound.referenceSound = gameSoundWorld->AllocSoundEmitter(); - } - - UpdateSound(); - - len = refSound.referenceSound->StartSound( shader, channel, diversity, soundShaderFlags ); - - // grayman #2341 - It's rare for the engine to not play the sound, but it can happen. If this happens, don't - // register this sound as the previous sound played. Stick with the one before that. - - if (len > 0) - { - if (channel == SND_CHANNEL_VOICE) - { - previousVoiceShader = (idSoundShader*)shader; // shader for the most recent voice request - previousVoiceIndex = static_cast(diversity * shader->GetNumSounds()) + 1; // index of most recent sound requested (1->N, where there are N sounds) - } - else if (channel == SND_CHANNEL_BODY) - { - previousBodyShader = (idSoundShader*)shader; // shader for the most recent body request - previousBodyIndex = static_cast(diversity * shader->GetNumSounds()) + 1; // index of most recent sound requested (1->N, where there are N sounds) - } - } - - if ( length ) { - *length = len; - } - - // set reference to the sound for shader synced effects - renderEntity.referenceSound = refSound.referenceSound; - - return true; -} - -/* -================ -idEntity::StopSound -================ -*/ -void idEntity::StopSound( const s_channelType channel, bool broadcast ) { - if ( !gameLocal.isNewFrame ) { - return; - } - - if ( gameLocal.isServer && broadcast ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteByte( channel ); - ServerSendEvent( EVENT_STOPSOUNDSHADER, &msg, false, -1 ); - } - - if ( refSound.referenceSound ) { - refSound.referenceSound->StopSound( channel ); - } -} - -/* -================ -idEntity::SetSoundVolume - - Must be called before starting a new sound. -================ -*/ -void idEntity::SetSoundVolume( float volume ) { - refSound.parms.volume = volume; -} - -/* -================ -idEntity::UpdateSound -================ -*/ -void idEntity::UpdateSound( void ) { - if ( refSound.referenceSound ) { - idVec3 origin; - idMat3 axis; - - if ( GetPhysicsToSoundTransform( origin, axis ) ) { - refSound.origin = GetPhysics()->GetOrigin() + origin * axis; - } else { - refSound.origin = GetPhysics()->GetOrigin(); - } - - refSound.referenceSound->UpdateEmitter( refSound.origin, refSound.listenerId, &refSound.parms ); - } -} - -/* -================ -idEntity::GetListenerId -================ -*/ -int idEntity::GetListenerId( void ) const { - return refSound.listenerId; -} - -/* -================ -idEntity::GetSoundEmitter -================ -*/ -idSoundEmitter *idEntity::GetSoundEmitter( void ) const { - return refSound.referenceSound; -} - -/* -================ -idEntity::FreeSoundEmitter -================ -*/ -void idEntity::FreeSoundEmitter( bool immediate ) { - if ( refSound.referenceSound ) { - refSound.referenceSound->Free( immediate ); - refSound.referenceSound = NULL; - } -} - -/* -================ -idEntity::PropSoundS -================ -*/ - -// note: the format for kv pair is: :volMod,durMod -// the last two values should be optional, so :volMod, -// and ,durMod also work. - -void idEntity::PropSoundS( const char *localName, const char *globalName, float VolModIn ) -{ - if (cv_sndprop_disable.GetBool()) - { - return; - } - - int start, end = -1, len; - bool bHasComma(false), bHasColon(false), bFoundSnd(false); - float volMod(0.0), durMod(1.0); - idStr gName(globalName); - - // if there is no local name, skip all the loading of local flags - // and parms. - if( localName == NULL ) - { - bFoundSnd = gameLocal.m_sndProp->CheckSound( globalName, false ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundS: Propagating global sound %s without checking local sound\r", globalName); - // note: if we are doing the global only, gName remains set to globalName - goto Quit; - } - - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundS: Found local sound %s, parsing local sound modifiers\r", localName); - - // parse the volMod and durMod if they are tacked on to the globalName - len = gName.Length(); - - // parse volMod, when durMod may or may not be present - if( (start = gName.Find(':')) != -1 ) - { - bHasColon = true; - start++; - end = gName.Find(','); - - if( end == -1 ) - end = gName.Length(); - - idStr tempstr = gName.Mid(start, (end - start)); - - if( !tempstr.IsNumeric() || start >= end ) - { - gameLocal.Warning( "[Soundprop] Bad volume multiplier for sound %s on entity %s.", localName, name.c_str() ); - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Bad volume multiplier for sound %s on entity %s.\r", localName, name.c_str() ); - } - else - { - volMod = atof( tempstr.c_str() ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local volume modifier %f \r", volMod); - } - } - - // parse durMod - if( (start = gName.Find(',')) != -1 ) - { - bHasComma = true; - start++; - end = gName.Length(); - - idStr tempstr = gName.Mid(start, (end - start)); - if( !tempstr.IsNumeric() || start >= end ) - { - gameLocal.Warning( "[Soundprop] Bad duration multiplier for sound %s on entity %s.", localName, name.c_str() ); - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Bad duration multiplier for sound %s on entity %s.\r", localName, name.c_str() ); - } - else - { - durMod = atof( tempstr.c_str() ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local duration modifier %f \r", durMod); - } - } - - // TODO: Get the extra flags, freqmod and bandwidthmod from another key/value pair - // we will need locName for this. - - // strip the durmod and volmod off of the global name - if( bHasColon ) - end = gName.Find(':'); - else if( bHasComma && !bHasColon ) - end = gName.Find(','); - else if( !bHasComma && !bHasColon ) - end = gName.Length(); - - gName = gName.Mid(0, end); - - bFoundSnd = gameLocal.m_sndProp->CheckSound( gName.c_str(), false ); - -Quit: - if( bFoundSnd ) - { - // add the input volume modifier - volMod += VolModIn; - - gameLocal.m_sndProp->Propagate( volMod, durMod, gName, - GetPhysics()->GetOrigin(), - this ); - } - - return; -} - -/* -================ -idEntity::PropSoundE -================ -*/ - -void idEntity::PropSoundE( const char *localName, const char *globalName, float VolModIn ) -{ - bool bFoundSnd(false); - float volMod(0.0); - idStr gName(globalName), locName(localName), tempstr; - - if( localName == NULL ) - { - bFoundSnd = gameLocal.m_sndProp->CheckSound( globalName, true ); - // if we are doing the global only, gName remains set to globalName - goto Quit; - } - - // do the parsing of the local vars that modify the Env. sound - - // strip gName of all modifiers at the end - - // add the input volume modifier - volMod += VolModIn; - -Quit: - - if( bFoundSnd ) - { - //TODO : Call soundprop to add env. sound to list - // have not written this sndprop functionality yet! - } - else - { - // log error, did not find sound in sound def file - } - return; -} - -/* -================ -idEntity::PropSoundDirect -================ -*/ - -void idEntity::PropSoundDirect( const char *sndName, bool bForceLocal, bool bAssumeEnv, float VolModIn ) -{ - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("PropSoundDirect: Attempting to propagate sound \"%s\" Forcelocal = %d\r", sndName, (int) bForceLocal ); - - // Cut off the "snd_" prefix from the incoming sound name - idStr sprName = sndName; - - sprName.StripLeading("snd_"); - - // Check if we have spr* definitions on the local spawnargs - idStr sprNameSG; - idStr sprNameEG; - bool bIsSusp = spawnArgs.GetString( ("sprS_" + sprName) , "", sprNameSG ); - bool bIsEnv = spawnArgs.GetString( ("sprE_" + sprName) , "", sprNameEG ); - - if (bForceLocal && - ( !(idStr::Icmpn( sndName, "snd_", 4 ) == 0) || ( !bIsSusp && !bIsEnv ) ) ) - { - DM_LOG(LC_SOUND, LT_WARNING)LOGSTRING("Attempted to propagate nonexistant local sound \"%s\" (forceLocal = true)\r", sndName ); - // gameLocal.Warning("[PropSound] Attempted to propagate nonexistant local sound \"%s\" (forceLocal = true)", sndName ); - return; - } - - if (bIsSusp) - { - PropSoundS( sprName.c_str(), sprNameSG.c_str(), VolModIn ); - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local suspicious sound def for %s on entity, attempting to propagate with global sound %s\r", sprName.c_str(), sprNameSG.c_str() ); - // exit here, because we don't want to allow playing both - // env. sound AND susp. sound for the same sound and entity - return; - } - else if (bIsEnv) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Found local environmental sound def for %s on entity, attempting to propagating with global sound %s\r", sprName.c_str(), sprNameEG.c_str() ); - PropSoundE( sprName.c_str(), sprNameEG.c_str(), VolModIn ); - return; - } - - // no environmental or suspicious sound - // play the unmodified, global sound directly - sprNameSG = sndName; - sprNameEG = sndName; - - // play the global sound directly. - if ( bAssumeEnv ) - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Did not find local def for sound %s, attempting to propagate it as global environmental\r", sprNameEG.c_str() ); - PropSoundE( NULL, sprNameEG.c_str(), VolModIn ); - return; - } - else - { - DM_LOG(LC_SOUND, LT_DEBUG)LOGSTRING("Did not find local def for sound %s, attempting to propagate it as global suspicious\r", sprNameSG.c_str() ); - PropSoundS( NULL, sprNameSG.c_str(), VolModIn ); - } -} - -/*********************************************************************** - - entity binding - -***********************************************************************/ - -/* -================ -idEntity::PreBind -================ -*/ -void idEntity::PreBind( void ) -{ -} - -/* -================ -idEntity::PostBind -================ -*/ -void idEntity::PostBind( void ) -{ -} - -/* -================ -idEntity::PreUnbind -================ -*/ -void idEntity::PreUnbind( void ) -{ -} - -/* -================ -idEntity::PostUnbind -================ -*/ -void idEntity::PostUnbind( void ) -{ -} - -/* -================ -idEntity::InitBind -================ -*/ -bool idEntity::InitBind( idEntity *master ) -{ - if ( master == this ) { - gameLocal.Error( "Tried to bind an object to itself." ); - return false; - } - - if ( this == gameLocal.world ) { - gameLocal.Error( "Tried to bind world to another entity" ); - return false; - } - - // unbind myself from my master - // angua: only do this if the entity is already bound to something - // and the new master is different from the old one - if (bindMaster != NULL && master != bindMaster) - { - Unbind(); - } - - // add any bind constraints to an articulated figure - if ( master && IsType( idAFEntity_Base::Type ) ) { - static_cast(this)->AddBindConstraints(); - } - -// TDM: Removed the inability to bind something to the world -// Might have to put it back in if something unforseen happens later because of this -// if ( !master || master == gameLocal.world ) - if ( !master ) - { - // this can happen in scripts, so safely exit out. - return false; - } - - return true; -} - -/* -================ -idEntity::FinishBind -================ -*/ -void idEntity::FinishBind( void ) -{ - // set the master on the physics object - physics->SetMaster( bindMaster, fl.bindOrientated ); - - // We are now separated from our previous team and are either - // an individual, or have a team of our own. Now we can join - // the new bindMaster's team. Bindmaster must be set before - // joining the team, or we will be placed in the wrong position - // on the team. - JoinTeam( bindMaster ); - - // if our bindMaster is enabled during a cinematic, we must be, too - cinematic = bindMaster->cinematic; - - // make sure the team master is active so that physics get run - teamMaster->BecomeActive( TH_PHYSICS ); - - // Notify bindmaster of this binding - bindMaster->BindNotify( this ); -} - -/* -================ -idEntity::Bind - - bind relative to the visual position of the master -================ -*/ -void idEntity::Bind( idEntity *master, bool orientated ) -{ - if ( !InitBind( master ) ) - return; - - // ishtvan: 30/1/2010 : Check for ragdoll adding on idAFAttachment masters when just bind is called - // (previously only done when bindToJoint or bindToBody was called) - if ( - master->IsType( idAFAttachment::Type ) - && !IsType( idAnimatedEntity::Type ) - && ( GetPhysics()->GetClipModel() != NULL ) - && ( GetPhysics()->GetClipModel()->IsTraceModel() ) - && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) - ) - { - idAFAttachment *masterAFAtt = static_cast(master); - idEntity *masterBody = masterAFAtt->GetBody(); - if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) - static_cast(masterBody)->AddEntByJoint( this, masterAFAtt->GetAttachJoint() ); - } - - - PreBind(); - - bindJoint = INVALID_JOINT; - bindBody = -1; - bindMaster = master; - fl.bindOrientated = orientated; - - FinishBind(); - - PostBind( ); -} - -/* -================ -idEntity::BindToJoint - - bind relative to a joint of the md5 model used by the master -================ -*/ -void idEntity::BindToJoint( idEntity *master, const char *jointname, bool orientated ) { - jointHandle_t jointnum; - idAnimator *masterAnimator; - - masterAnimator = master->GetAnimator(); - if ( !masterAnimator ) - { - gameLocal.Warning( "idEntity::BindToJoint: entity '%s' cannot support skeletal models.", master->GetName() ); - return; - } - - jointnum = masterAnimator->GetJointHandle( jointname ); - - if ( !InitBind( master ) ) - return; - - // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) - if ( - (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) - && !IsType( idAnimatedEntity::Type ) - && ( jointnum != INVALID_JOINT ) - && ( GetPhysics()->GetClipModel() != NULL ) - && ( GetPhysics()->GetClipModel()->IsTraceModel() ) - && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) - ) - { - if( master->IsType( idAFEntity_Base::Type ) ) - static_cast(master)->AddEntByJoint( this, jointnum ); - else if( master->IsType( idAFAttachment::Type ) ) - { - idEntity *masterBody = static_cast(master)->GetBody(); - if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) - static_cast(masterBody)->AddEntByJoint( this, jointnum ); - } - } - - if ( jointnum == INVALID_JOINT ) { - gameLocal.Warning( "idEntity::BindToJoint: joint '%s' not found on entity '%s'.", jointname, master->GetName() ); - } - - PreBind(); - - bindJoint = jointnum; - bindBody = -1; - bindMaster = master; - fl.bindOrientated = orientated; - - FinishBind(); - - PostBind(); -} - -/* -================ -idEntity::BindToJoint - - bind relative to a joint of the md5 model used by the master -================ -*/ -void idEntity::BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated ) -{ - if ( !InitBind( master ) ) - return; - - // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) - if ( - (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) - && !IsType( idAnimatedEntity::Type ) - && ( jointnum != INVALID_JOINT ) - && ( GetPhysics()->GetClipModel() != NULL ) - && ( GetPhysics()->GetClipModel()->IsTraceModel() ) - && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) - ) - { - if( master->IsType( idAFEntity_Base::Type ) ) - static_cast(master)->AddEntByJoint( this, jointnum ); - else if( master->IsType( idAFAttachment::Type ) ) - { - idEntity *masterBody = static_cast(master)->GetBody(); - if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) - static_cast(masterBody)->AddEntByJoint( this, jointnum ); - } - } - - PreBind(); - - bindJoint = jointnum; - bindBody = -1; - bindMaster = master; - fl.bindOrientated = orientated; - - FinishBind(); - - PostBind(); -} - -/* -================ -idEntity::BindToBody - - bind relative to a collision model used by the physics of the master -================ -*/ -void idEntity::BindToBody( idEntity *master, int bodyId, bool orientated ) -{ - if ( !InitBind( master ) ) - return; - - // Add the ent clipmodel to the AF if appropriate (not done if this ent is an AF) - if ( - (master->IsType( idAFEntity_Base::Type ) || master->IsType( idAFAttachment::Type )) - && !IsType( idAnimatedEntity::Type ) - && ( GetPhysics()->GetClipModel() != NULL ) - && ( GetPhysics()->GetClipModel()->IsTraceModel() ) - && ( (GetPhysics()->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) != 0 ) - ) - { - if( master->IsType( idAFEntity_Base::Type ) ) - static_cast(master)->AddEntByBody( this, bodyId ); - else if( master->IsType( idAFAttachment::Type ) ) - { - idEntity *masterBody = static_cast(master)->GetBody(); - if( masterBody && masterBody->IsType( idAFEntity_Base::Type ) ) - static_cast(masterBody)->AddEntByBody( this, bodyId ); - } - } - - if ( bodyId < 0 ) - gameLocal.Warning( "idEntity::BindToBody: body '%d' not found.", bodyId ); - - PreBind(); - - bindJoint = INVALID_JOINT; - bindBody = bodyId; - bindMaster = master; - fl.bindOrientated = orientated; - - FinishBind(); - - PostBind(); -} - -/* -================ -idEntity::Unbind -================ -*/ -void idEntity::Unbind( void ) { - idEntity * prev; - idEntity * next; - idEntity * last; - idEntity * ent; - - // remove any bind constraints from an articulated figure - if ( IsType( idAFEntity_Base::Type ) ) { - static_cast(this)->RemoveBindConstraints(); - } - - if ( !bindMaster ) { - return; - } - - // TDM: Notify bindmaster of unbinding - bindMaster->UnbindNotify( this ); - - if ( !teamMaster ) { - // Teammaster already has been freed - bindMaster = NULL; - return; - } - - PreUnbind(); - - if ( physics ) { - physics->SetMaster( NULL, fl.bindOrientated ); - } - - // We're still part of a team, so that means I have to extricate myself - // and any entities that are bound to me from the old team. - // Find the node previous to me in the team - prev = teamMaster; - for( ent = teamMaster->teamChain; ent && ( ent != this ); ent = ent->teamChain ) { - prev = ent; - } - - assert( ent == this ); // If ent is not pointing to this, then something is very wrong. - - // Find the last node in my team that is bound to me. - // Also find the first node not bound to me, if one exists. - last = this; - for( next = teamChain; next != NULL; next = next->teamChain ) { - if ( !next->IsBoundTo( this ) ) { - break; - } - - // Tell them I'm now the teamMaster - next->teamMaster = this; - last = next; - } - - // disconnect the last member of our team from the old team - last->teamChain = NULL; - - // connect up the previous member of the old team to the node that - // follow the last node bound to me (if one exists). - if ( teamMaster != this ) { - prev->teamChain = next; - if ( !next && ( teamMaster == prev ) ) { - prev->teamMaster = NULL; - } - } else if ( next ) { - // If we were the teamMaster, then the nodes that were not bound to me are now - // a disconnected chain. Make them into their own team. - for( ent = next; ent->teamChain != NULL; ent = ent->teamChain ) { - ent->teamMaster = next; - } - next->teamMaster = next; - } - - // If we don't have anyone on our team, then clear the team variables. - if ( teamChain ) { - // make myself my own team - teamMaster = this; - } else { - // no longer a team - teamMaster = NULL; - } - - bindJoint = INVALID_JOINT; - bindBody = -1; - bindMaster = NULL; - - PostUnbind(); -} - -/* -================ -idEntity::RemoveBinds -================ -*/ -void idEntity::RemoveBinds( void ) { - idEntity *ent; - idEntity *next; - - for( ent = teamChain; ent != NULL; ent = next ) { - next = ent->teamChain; - // bound to us? - if ( ent->bindMaster == this ) { - ent->Unbind(); - - if( ent->spawnArgs.GetBool( "removeWithMaster", "1" ) ) { - ent->PostEventMS( &EV_Remove, 0 ); - } - next = teamChain; - } - } -} - -/* -================ -idEntity::DetachOnAlert - -tels: Remove attached entities when the alert index reaches their "unbindonalertindex". -The attached entities will be removed from the attached list and are also unbound. -================ -*/ -void idEntity::DetachOnAlert( const int alertIndex ) -{ - idEntity *ent = NULL; - - for ( int ind = 0; ind < m_Attachments.Num(); ind ++) - { - ent = m_Attachments[ind].ent.GetEntity(); - if( ent && m_Attachments[ind].ent.IsValid() ) - { - // Crispy: 9999 = "infinity" - if( alertIndex >= ent->spawnArgs.GetInt( "unbindonalertindex", "9999" )) - { - // Tels: - if ( ent->spawnArgs.GetInt("_spawned_by_anim","0") == 1 ) - { - // gameLocal.Printf("Removing entity %s spanwed by animation\n", ent->GetName() ); - // this entity was spawned automatically by an animation, remove it - // from the game to prevent left-overs from alerted-during-animation guards - ent->PostEventMS( &EV_Remove, 0 ); - // and make inactive in the meantime - ent->BecomeInactive(TH_PHYSICS|TH_THINK); - } - DetachInd(ind); - } - } - } -} - -/* -================ -idEntity::IsBound -================ -*/ -bool idEntity::IsBound( void ) const { - if ( bindMaster ) { - return true; - } - return false; -} - -/* -================ -idEntity::IsBoundTo -================ -*/ -bool idEntity::IsBoundTo( idEntity *master ) const { - idEntity *ent; - - if ( !bindMaster ) { - return false; - } - - for ( ent = bindMaster; ent != NULL; ent = ent->bindMaster ) { - if ( ent == master ) { - return true; - } - } - - return false; -} - -/* -================ -idEntity::GetBindMaster -================ -*/ -idEntity *idEntity::GetBindMaster( void ) const { - return bindMaster; -} - -/* -================ -idEntity::GetBindJoint -================ -*/ -jointHandle_t idEntity::GetBindJoint( void ) const { - return bindJoint; -} - -/* -================ -idEntity::GetBindBody -================ -*/ -int idEntity::GetBindBody( void ) const { - return bindBody; -} - -/* -================ -idEntity::GetTeamMaster -================ -*/ -idEntity *idEntity::GetTeamMaster( void ) const { - return teamMaster; -} - -/* -================ -idEntity::GetNextTeamEntity -================ -*/ -idEntity *idEntity::GetNextTeamEntity( void ) const { - return teamChain; -} - -/* -===================== -idEntity::ConvertLocalToWorldTransform -===================== -*/ -void idEntity::ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis ) { - UpdateModelTransform(); - - offset = renderEntity.origin + offset * renderEntity.axis; - axis *= renderEntity.axis; -} - -/* -================ -idEntity::GetLocalVector - -Takes a vector in worldspace and transforms it into the parent -object's localspace. - -Note: Does not take origin into acount. Use getLocalCoordinate to -convert coordinates. -================ -*/ -idVec3 idEntity::GetLocalVector( const idVec3 &vec ) const { - idVec3 pos; - - if ( !bindMaster ) { - return vec; - } - - idVec3 masterOrigin; - idMat3 masterAxis; - - GetMasterPosition( masterOrigin, masterAxis ); - masterAxis.ProjectVector( vec, pos ); - - return pos; -} - -/* -================ -idEntity::GetLocalCoordinates - -Takes a vector in world coordinates and transforms it into the parent -object's local coordinates. -================ -*/ -idVec3 idEntity::GetLocalCoordinates( const idVec3 &vec ) const { - idVec3 pos; - - if ( !bindMaster ) { - return vec; - } - - idVec3 masterOrigin; - idMat3 masterAxis; - - GetMasterPosition( masterOrigin, masterAxis ); - masterAxis.ProjectVector( vec - masterOrigin, pos ); - - return pos; -} - -/* -================ -idEntity::GetWorldVector - -Takes a vector in the parent object's local coordinates and transforms -it into world coordinates. - -Note: Does not take origin into acount. Use getWorldCoordinate to -convert coordinates. -================ -*/ -idVec3 idEntity::GetWorldVector( const idVec3 &vec ) const { - idVec3 pos; - - if ( !bindMaster ) { - return vec; - } - - idVec3 masterOrigin; - idMat3 masterAxis; - - GetMasterPosition( masterOrigin, masterAxis ); - masterAxis.UnprojectVector( vec, pos ); - - return pos; -} - -/* -================ -idEntity::GetWorldCoordinates - -Takes a vector in the parent object's local coordinates and transforms -it into world coordinates. -================ -*/ -idVec3 idEntity::GetWorldCoordinates( const idVec3 &vec ) const { - idVec3 pos; - - if ( !bindMaster ) { - return vec; - } - - idVec3 masterOrigin; - idMat3 masterAxis; - - GetMasterPosition( masterOrigin, masterAxis ); - masterAxis.UnprojectVector( vec, pos ); - pos += masterOrigin; - - return pos; -} - -/* -================ -idEntity::GetMasterPosition -================ -*/ -bool idEntity::GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const { - idVec3 localOrigin; - idMat3 localAxis; - idAnimator *masterAnimator; - - if ( bindMaster ) - { - // if bound to a joint of an animated model - if ( bindJoint != INVALID_JOINT ) - { - masterAnimator = bindMaster->GetAnimator(); - if ( !masterAnimator ) - { - masterOrigin = vec3_origin; - masterAxis = mat3_identity; - return false; - } else - { - // Use GetGlobalJointTransform for things bound to weapons - // This takes into account the view bob, weapon bob and other factors - if( bindMaster->IsType(idWeapon::Type) ) - { - static_cast(bindMaster)->GetGlobalJointTransform( true, bindJoint, masterOrigin, masterAxis ); - } - else - { - masterAnimator->GetJointTransform( bindJoint, gameLocal.time, masterOrigin, masterAxis ); - masterAxis *= bindMaster->renderEntity.axis; - masterOrigin = bindMaster->renderEntity.origin + masterOrigin * bindMaster->renderEntity.axis; - } - } - } else if ( bindBody >= 0 && bindMaster->GetPhysics() ) { - masterOrigin = bindMaster->GetPhysics()->GetOrigin( bindBody ); - masterAxis = bindMaster->GetPhysics()->GetAxis( bindBody ); - } else { - masterOrigin = bindMaster->renderEntity.origin; - masterAxis = bindMaster->renderEntity.axis; - } - return true; - } else { - masterOrigin = vec3_origin; - masterAxis = mat3_identity; - return false; - } -} - -/* -================ -idEntity::GetWorldVelocities -================ -*/ -void idEntity::GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const { - - linearVelocity = physics->GetLinearVelocity(); - angularVelocity = physics->GetAngularVelocity(); - - if ( bindMaster ) { - idVec3 masterOrigin, masterLinearVelocity, masterAngularVelocity; - idMat3 masterAxis; - - // get position of master - GetMasterPosition( masterOrigin, masterAxis ); - - // get master velocities - bindMaster->GetWorldVelocities( masterLinearVelocity, masterAngularVelocity ); - - // linear velocity relative to master plus master linear and angular velocity - linearVelocity = linearVelocity * masterAxis + masterLinearVelocity + - masterAngularVelocity.Cross( GetPhysics()->GetOrigin() - masterOrigin ); - } -} - -/* -================ -idEntity::JoinTeam -================ -*/ -void idEntity::JoinTeam( idEntity *teammember ) { - idEntity *ent; - idEntity *master; - idEntity *prev; - idEntity *next; - - // if we're already on a team, quit it so we can join this one - if ( teamMaster && ( teamMaster != this ) ) { - QuitTeam(); - } - - assert( teammember ); - - if ( teammember == this ) { - teamMaster = this; - return; - } - - // check if our new team mate is already on a team - master = teammember->teamMaster; - if ( !master ) { - // he's not on a team, so he's the new teamMaster - master = teammember; - teammember->teamMaster = teammember; - teammember->teamChain = this; - - // make anyone who's bound to me part of the new team - for( ent = teamChain; ent != NULL; ent = ent->teamChain ) { - ent->teamMaster = master; - } - } else { - // skip past the chain members bound to the entity we're teaming up with - prev = teammember; - next = teammember->teamChain; - if ( bindMaster ) { - // if we have a bindMaster, join after any entities bound to the entity - // we're joining - while( next && next->IsBoundTo( teammember ) ) { - prev = next; - next = next->teamChain; - } - } else { - // if we're not bound to someone, then put us at the end of the team - while( next ) { - prev = next; - next = next->teamChain; - } - } - - // make anyone who's bound to me part of the new team and - // also find the last member of my team - for( ent = this; ent->teamChain != NULL; ent = ent->teamChain ) { - ent->teamChain->teamMaster = master; - } - - prev->teamChain = this; - ent->teamChain = next; - } - - teamMaster = master; - - // reorder the active entity list - gameLocal.sortTeamMasters = true; -} - -idEntity* idEntity::FindMatchingTeamEntity(const idTypeInfo& type, idEntity* lastMatch) -{ - idEntity* part; - - if (lastMatch != NULL) - { - for (part = teamChain; part != NULL; part = part->teamChain) - { - if (part == lastMatch) - { - // We've found our previous match, increase the pointer and break; - part = part->teamChain; - break; - } - } - } - else - { - // No last match specified, set the pointer to the start - part = teamChain; - } - - for (/* no initialisation */; part != NULL; part = part->teamChain) - { - if (part->IsType(type)) - { - // Found a suitable one, return it - return part; - } - } - - return NULL; -} - -/* -================ -idEntity::QuitTeam -================ -*/ -void idEntity::QuitTeam( void ) { - idEntity *ent; - - if ( !teamMaster ) { - return; - } - - // check if I'm the teamMaster - if ( teamMaster == this ) { - // do we have more than one teammate? - if ( !teamChain->teamChain ) { - // no, break up the team - teamChain->teamMaster = NULL; - } else { - // yes, so make the first teammate the teamMaster - for( ent = teamChain; ent; ent = ent->teamChain ) { - ent->teamMaster = teamChain; - } - } - } else { - assert( teamMaster ); - assert( teamMaster->teamChain ); - - // find the previous member of the teamChain - ent = teamMaster; - while( ent->teamChain != this ) { - assert( ent->teamChain ); // this should never happen - ent = ent->teamChain; - } - - // remove this from the teamChain - ent->teamChain = teamChain; - - // if no one is left on the team, break it up - if ( !teamMaster->teamChain ) { - teamMaster->teamMaster = NULL; - } - } - - teamMaster = NULL; - teamChain = NULL; -} - -/*********************************************************************** - - Physics. - -***********************************************************************/ - -/* -================ -idEntity::InitDefaultPhysics -================ -*/ -void idEntity::InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis ) -{ - const char *temp; - idClipModel *clipModel = NULL; - - DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity [%s] test for clipmodel\r", name.c_str()); - - // check if a clipmodel key/value pair is set - if ( spawnArgs.GetString( "clipmodel", "", &temp ) ) { - if ( idClipModel::CheckModel( temp ) ) { - clipModel = new idClipModel( temp ); - } - } - - if(!spawnArgs.GetBool( "noclipmodel", "0" )) - { - // check if mins/maxs or size key/value pairs are set - if ( !clipModel ) - { - idVec3 size; - idBounds bounds; - bool setClipModel = false; - - if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) && - spawnArgs.GetVector( "maxs", NULL, bounds[1] ) ) - { - setClipModel = true; - if ( bounds[0][0] > bounds[1][0] || bounds[0][1] > bounds[1][1] || bounds[0][2] > bounds[1][2] ) - { - gameLocal.Error( "Invalid bounds '%s'-'%s' on entity '%s'", bounds[0].ToString(), bounds[1].ToString(), name.c_str() ); - } - } - else - if ( spawnArgs.GetVector( "size", NULL, size ) ) - { - if ( ( size.x < 0.0f ) || ( size.y < 0.0f ) || ( size.z < 0.0f ) ) - { - gameLocal.Error( "Invalid size '%s' on entity '%s'", size.ToString(), name.c_str() ); - } - bounds[0].Set( size.x * -0.5f, size.y * -0.5f, 0.0f ); - bounds[1].Set( size.x * 0.5f, size.y * 0.5f, size.z ); - setClipModel = true; - } - - if ( setClipModel ) { - int numSides; - idTraceModel trm; - - if ( spawnArgs.GetInt( "cylinder", "0", numSides ) && numSides > 0 ) { - trm.SetupCylinder( bounds, numSides < 3 ? 3 : numSides ); - } else if ( spawnArgs.GetInt( "cone", "0", numSides ) && numSides > 0 ) { - trm.SetupCone( bounds, numSides < 3 ? 3 : numSides ); - } else { - trm.SetupBox( bounds ); - } - clipModel = new idClipModel( trm ); - } - } - - // check if the visual model can be used as collision model - if ( !clipModel ) { - temp = spawnArgs.GetString( "model" ); - if ( ( temp != NULL ) && ( *temp != 0 ) ) { - if ( idClipModel::CheckModel( temp ) ) { - clipModel = new idClipModel( temp ); - } - } - } - } - else { - DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity [%s] does not contain a clipmodel\r", name.c_str()); - } - - defaultPhysicsObj.SetSelf( this ); - defaultPhysicsObj.SetClipModel( clipModel, 1.0f ); - defaultPhysicsObj.SetOrigin( origin ); - defaultPhysicsObj.SetAxis( axis ); - - physics = &defaultPhysicsObj; - - // create a frob box separate from the collision box for easier frobbing - bool bUseFrobBox(false); - idBounds bounds, FrobBounds; - idTraceModel FrobTrm; - int numSides(0); - - - // First check if frobbox_mins and frobbox_maxs are set - if ( spawnArgs.GetVector( "frobbox_mins", NULL, FrobBounds[0] ) && - spawnArgs.GetVector( "frobbox_maxs", NULL, FrobBounds[1] ) ) - { - if ( FrobBounds[0][0] > FrobBounds[1][0] || FrobBounds[0][1] >FrobBounds[1][1] || FrobBounds[0][2] > FrobBounds[1][2] ) - { - gameLocal.Error( "Invalid frob box bounds '%s'-'%s' on entity '%s'", FrobBounds[0].ToString(), FrobBounds[1].ToString(), name.c_str() ); - } - bUseFrobBox = true; - } - else - { - float tsize; - spawnArgs.GetFloat( "frobbox_size", "0.0", tsize ); - if( tsize != 0.0f ) - { - FrobBounds.Zero(); - FrobBounds.ExpandSelf( tsize ); - bUseFrobBox = true; - } - } - - // greebo: Allow the no_frob_box spawnarg to override the settings - if (spawnArgs.GetBool("no_frob_box", "0")) - { - bUseFrobBox = false; - } - - if( bUseFrobBox ) - { - if ( spawnArgs.GetInt( "frobbox_cylinder", "0", numSides ) && numSides > 0 ) - FrobTrm.SetupCylinder( FrobBounds, numSides < 3 ? 3 : numSides ); - else if ( spawnArgs.GetInt( "frobbox_cone", "0", numSides ) && numSides > 0 ) - FrobTrm.SetupCone( FrobBounds, numSides < 3 ? 3 : numSides ); - else - FrobTrm.SetupBox( FrobBounds ); - - // Initialize frob bounds based on previous spawnarg setup - m_FrobBox = new idClipModel( FrobTrm ); - m_FrobBox->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - // don't set contents of frob box here, wait for frobbing initialization - } - else - m_FrobBox = NULL; -} - -/* -================ -idEntity::SetPhysics -================ -*/ -void idEntity::SetPhysics( idPhysics *phys ) { - // clear any contacts the current physics object has - if ( physics ) { - physics->ClearContacts(); - } - // set new physics object or set the default physics if NULL - if ( phys != NULL ) { - defaultPhysicsObj.SetClipModel( NULL, 1.0f ); - physics = phys; - physics->Activate(); - } else { - physics = &defaultPhysicsObj; - } - physics->UpdateTime( gameLocal.time ); - physics->SetMaster( bindMaster, fl.bindOrientated ); -} - -/* -================ -idEntity::RestorePhysics -================ -*/ -void idEntity::RestorePhysics( idPhysics *phys ) { - assert( phys != NULL ); - // restore physics pointer - physics = phys; -} - -/* -================ -idEntity::GetPhysics -================ -*/ -idPhysics *idEntity::GetPhysics( void ) const { - return physics; -} - -/* -================ -idEntity::RunPhysics -================ -*/ -bool idEntity::RunPhysics( void ) { - int i, reachedTime, startTime, endTime; - idEntity * part, *blockedPart, *blockingEntity(NULL); - trace_t results; - bool moved; - - // don't run physics if not enabled - if ( !( thinkFlags & TH_PHYSICS ) ) { - // however do update any animation controllers - if ( UpdateAnimationControllers() ) { - BecomeActive( TH_ANIMATE ); - } - return false; - } - - // if this entity is a team slave don't do anything because the team master will handle everything - if ( teamMaster && teamMaster != this ) { - return false; - } - - // angua: since the AI are not thinking every frame, we need to rescale - // their velocities with the corrected time length to prevent them from dying. - if (IsType(idAI::Type)) - { - startTime = static_cast(this)->m_lastThinkTime; - } - else - { - startTime = gameLocal.previousTime; - } - endTime = gameLocal.time; - - gameLocal.push.InitSavingPushedEntityPositions(); - blockedPart = NULL; - - // save the physics state of the whole team and disable the team for collision detection - for ( part = this; part != NULL; part = part->teamChain ) { - if ( part->physics ) { - if ( !part->fl.solidForTeam ) { - part->physics->DisableClip(); - } - part->physics->SaveState(); - } - } - - // move the whole team - for ( part = this; part != NULL; part = part->teamChain ) { - - if ( part->physics ) - { - // run physics - moved = part->physics->Evaluate( endTime - startTime, endTime ); - // check if the object is blocked - blockingEntity = part->physics->GetBlockingEntity(); - if ( blockingEntity ) { - blockedPart = part; - break; - } - - // if moved or forced to update the visual position and orientation from the physics - if ( moved || part->fl.forcePhysicsUpdate ) { - part->UpdateFromPhysics( false ); - } - - // update any animation controllers here so an entity bound - // to a joint of this entity gets the correct position - if ( part->UpdateAnimationControllers() ) { - part->BecomeActive( TH_ANIMATE ); - } - } - } - - // enable the whole team for collision detection - for ( part = this; part != NULL; part = part->teamChain ) { - if ( part->physics ) - { -// Ish: I think Id screwed up here, but am not positive - // if ( !part->fl.solidForTeam ) { - part->physics->EnableClip(); - // } - } - } - - // if one of the team entities is a pusher and blocked - if ( blockedPart ) { - // move the parts back to the previous position - for ( part = this; part != blockedPart; part = part->teamChain ) { - - if ( part->physics ) { - // restore the physics state - part->physics->RestoreState(); - - // move back the visual position and orientation - part->UpdateFromPhysics( true ); - } - } - for ( part = this; part != NULL; part = part->teamChain ) { - if ( part->physics ) { - // update the physics time without moving - part->physics->UpdateTime( endTime ); - } - } - - // greebo: Apply the "reactio" to the team master - if (physics->IsType(idPhysics_RigidBody::Type)) - { - idPhysics_RigidBody* rigidBodyPhysics = static_cast(physics); - - // Calculate the movement (proportional to kinetic energy) - float movement = rigidBodyPhysics->GetLinearVelocity().LengthSqr() + - rigidBodyPhysics->GetAngularVelocity().LengthSqr(); - - //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Movement is %f\r", movement); - - if (movement < 10.0f) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Putting %s to rest, velocity was %f\r", name.c_str(), physics->GetLinearVelocity().LengthFast()); - physics->PutToRest(); - } - else - { - // Create a dummy impulse vector, it gets overwritten by the CollisionImpulse method anyway - idVec3 impulse(0,0,0); - rigidBodyPhysics->CollisionImpulse(*blockedPart->GetPhysics()->GetBlockingInfo(), impulse); - - // greebo: Apply some damping due to the collision with a slave - rigidBodyPhysics->State().i.linearMomentum *= 0.95f; - rigidBodyPhysics->State().i.angularMomentum *= 0.99f; - } - } - - // restore the positions of any pushed entities - gameLocal.push.RestorePushedEntityPositions(); - - if ( gameLocal.isClient ) { - return false; - } - - // if the master pusher has a "blocked" function, call it - Signal( SIG_BLOCKED ); - ProcessEvent( &EV_TeamBlocked, blockedPart, blockingEntity ); - // call the blocked function on the blocked part - blockedPart->ProcessEvent( &EV_PartBlocked, blockingEntity ); - return false; - } - - // set pushed - for ( i = 0; i < gameLocal.push.GetNumPushedEntities(); i++ ) { - idEntity *ent = gameLocal.push.GetPushedEntity( i ); - ent->physics->SetPushed( endTime - startTime ); - } - - if ( gameLocal.isClient ) { - return true; - } - - // post reached event if the current time is at or past the end point of the motion - for ( part = this; part != NULL; part = part->teamChain ) { - - if ( part->physics ) { - - reachedTime = part->physics->GetLinearEndTime(); - if ( startTime < reachedTime && endTime >= reachedTime ) { - part->ProcessEvent( &EV_ReachedPos ); - } - reachedTime = part->physics->GetAngularEndTime(); - if ( startTime < reachedTime && endTime >= reachedTime ) { - part->ProcessEvent( &EV_ReachedAng ); - } - } - } - - return true; -} - -/* -================ -idEntity::UpdateFromPhysics -================ -*/ -void idEntity::UpdateFromPhysics( bool moveBack ) { - - if ( IsType( idActor::Type ) ) { - idActor *actor = static_cast( this ); - - // set master delta angles for actors - if ( GetBindMaster() ) { - idAngles delta = actor->GetDeltaViewAngles(); - if ( moveBack ) { - delta.yaw -= static_cast(physics)->GetMasterDeltaYaw(); - } else { - delta.yaw += static_cast(physics)->GetMasterDeltaYaw(); - } - actor->SetDeltaViewAngles( delta ); - } - } - - UpdateVisuals(); -} - -/* -================ -idEntity::SetOrigin -================ -*/ -void idEntity::SetOrigin( const idVec3 &org ) { - - GetPhysics()->SetOrigin( org ); - - UpdateVisuals(); -} - -/* -================ -idEntity::SetAxis -================ -*/ -void idEntity::SetAxis( const idMat3 &axis ) { - - if ( GetPhysics()->IsType( idPhysics_Actor::Type ) ) { - static_cast(this)->viewAxis = axis; - } else { - GetPhysics()->SetAxis( axis ); - } - - UpdateVisuals(); -} - -/* -================ -idEntity::SetAngles -================ -*/ -void idEntity::SetAngles( const idAngles &ang ) { - SetAxis( ang.ToMat3() ); -} - -/* -================ -idEntity::GetFloorPos -================ -*/ -bool idEntity::GetFloorPos( float max_dist, idVec3 &floorpos ) const { - trace_t result; - - if ( !GetPhysics()->HasGroundContacts() ) { - GetPhysics()->ClipTranslation( result, GetPhysics()->GetGravityNormal() * max_dist, NULL ); - if ( result.fraction < 1.0f ) { - floorpos = result.endpos; - return true; - } else { - floorpos = GetPhysics()->GetOrigin(); - return false; - } - } else { - floorpos = GetPhysics()->GetOrigin(); - return true; - } -} - -/* -================ -idEntity::GetPhysicsToVisualTransform -================ -*/ -bool idEntity::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { - return false; -} - -/* -================ -idEntity::GetPhysicsToSoundTransform -================ -*/ -bool idEntity::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { - // by default play the sound at the center of the bounding box of the first clip model - if ( GetPhysics()->GetNumClipModels() > 0 ) { - origin = GetPhysics()->GetBounds().GetCenter(); - axis.Identity(); - return true; - } - return false; -} - -/* -================ -idEntity::Collide -================ -*/ - -bool idEntity::Collide( const trace_t &collision, const idVec3 &velocity ) { - return false; -} -/* -================ -idEntity::GetImpactInfo -================ -*/ -void idEntity::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) { - GetPhysics()->GetImpactInfo( id, point, info ); -} - -/* -================ -idEntity::ApplyImpulse -================ -*/ -void idEntity::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { - - // grayman #2603 - disallow impulse on candles and candle holders when the candle is being relit - - bool allowImpulse = true; - - // In case the entity itself is a light (tdm_light_holder light) - - if (IsType(idLight::Type)) - { - if (static_cast(this)->IsBeingRelit()) - { - allowImpulse = false; // relighting this light; no impulse - } - } - else if (IsType(idMoveable::Type)) - { - // Are there any light entities on this team? - - idList children; - GetTeamChildren(&children); - for (int i = 0 ; i < children.Num() ; i++) - { - // Based on reading other uses of GetTeamChildren(), it's - // prudent to check for recursion back to the original entity. - - idEntity* child = children[i]; - if (this == child) - { - break; - } - if (child->IsType(idLight::Type)) - { - if (static_cast(child)->IsBeingRelit()) - { - allowImpulse = false; // relighting this light; no impulse - break; - } - } - } - } - - if (allowImpulse) - { - GetPhysics()->ApplyImpulse( id, point, impulse ); - } -} - -/* -================ -idEntity::AddForce -================ -*/ -void idEntity::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) { - GetPhysics()->AddForce( id, point, force ); -} - -/* -================ -idEntity::ActivatePhysics -================ -*/ -void idEntity::ActivatePhysics( idEntity *ent ) { - GetPhysics()->Activate(); -} - -/* -================ -idEntity::IsAtRest -================ -*/ -bool idEntity::IsAtRest( void ) const { - return GetPhysics()->IsAtRest(); -} - -/* -================ -idEntity::GetRestStartTime -================ -*/ -int idEntity::GetRestStartTime( void ) const { - return GetPhysics()->GetRestStartTime(); -} - -/* -================ -idEntity::AddContactEntity -================ -*/ -void idEntity::AddContactEntity( idEntity *ent ) { - GetPhysics()->AddContactEntity( ent ); -} - -/* -================ -idEntity::RemoveContactEntity -================ -*/ -void idEntity::RemoveContactEntity( idEntity *ent ) { - GetPhysics()->RemoveContactEntity( ent ); -} - - - -/*********************************************************************** - - Damage - -***********************************************************************/ - -/* -============ -idEntity::CanDamage - -Returns true if the inflictor can directly damage the target. Used for -explosions and melee attacks. -============ -*/ -bool idEntity::CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const { - idVec3 dest; - trace_t tr; - idVec3 midpoint; - - // use the midpoint of the bounds instead of the origin, because - // bmodels may have their origin at 0,0,0 - midpoint = ( GetPhysics()->GetAbsBounds()[0] + GetPhysics()->GetAbsBounds()[1] ) * 0.5; - - dest = midpoint; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - // this should probably check in the plane of projection, rather than in world coordinate - dest = midpoint; - dest[0] += 15.0; - dest[1] += 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - dest = midpoint; - dest[0] += 15.0; - dest[1] -= 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - dest = midpoint; - dest[0] -= 15.0; - dest[1] += 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - dest = midpoint; - dest[0] -= 15.0; - dest[1] -= 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - dest = midpoint; - dest[2] += 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - dest = midpoint; - dest[2] -= 15.0; - gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) { - damagePoint = tr.endpos; - return true; - } - - return false; -} - -/* -================ -idEntity::DamageFeedback - -callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. -================ -*/ -void idEntity::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { - // implemented in subclasses -} - -/* -============ -Damage - -this entity that is being damaged -inflictor entity that is causing the damage -attacker entity that caused the inflictor to damage targ - example: this=monster, inflictor=rocket, attacker=player - -dir direction of the attack for knockback in global space -point point at which the damage is being inflicted, used for headshots -damage amount of damage being inflicted - -inflictor, attacker, dir, and point can be NULL for environmental effects - -============ -*/ -void idEntity::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, - const int location, trace_t *tr ) -{ - if ( !fl.takedamage ) { - return; - } - - if ( !inflictor ) { - inflictor = gameLocal.world; - } - - if ( !attacker ) { - attacker = gameLocal.world; - } - - const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) { - gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); - } - - int damage = damageDef->GetInt( "damage" ); - - // inform the attacker that they hit someone - attacker->DamageFeedback( this, inflictor, damage ); - if ( damage ) { - // do the damage - health -= damage; - if ( health <= 0 ) { - if ( health < -999 ) { - health = -999; - } - - Killed( inflictor, attacker, damage, dir, location ); - } else { - Pain( inflictor, attacker, damage, dir, location ); - } - } -} - -/* -================ -idEntity::AddDamageEffect -================ -*/ -void idEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { - const char *decal, *key; - idStr surfName; - - const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false ); - if ( def == NULL ) { - return; - } - - g_Global.GetSurfName( collision.c.material, surfName ); - - // start impact sound based on material type - key = va( "snd_%s", surfName.c_str() ); - - // ishtvan: No need to play the sound here anymore, right? -/* - sound = spawnArgs.GetString( key ); - if ( *sound == '\0' ) { - sound = def->dict.GetString( key ); - } - if ( *sound != '\0' ) { - StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); - } -*/ - - if ( g_decals.GetBool() ) { - // place a wound overlay on the model - key = va( "mtr_wound_%s", surfName.c_str() ); - decal = spawnArgs.RandomPrefix( key, gameLocal.random ); - if ( *decal == '\0' ) { - decal = def->dict.RandomPrefix( key, gameLocal.random ); - } - if ( *decal != '\0' ) { - idVec3 dir = velocity; - dir.Normalize(); - ProjectOverlay( collision.c.point, dir, 20.0f, decal ); - } - } -} - -/* -============ -idEntity::Pain - -Called whenever an entity recieves damage. Returns whether the entity responds to the pain. -This is a virtual function that subclasses are expected to implement. -============ -*/ -bool idEntity::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - return false; -} - -/* -============ -idEntity::Killed - -Called whenever an entity's health is reduced to 0 or less. -This is a virtual function that subclasses are expected to implement. -============ -*/ -void idEntity::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { -} - - -/*********************************************************************** - - Script functions - -***********************************************************************/ - -/* -================ -idEntity::ShouldConstructScriptObjectAtSpawn - -Called during idEntity::Spawn to see if it should construct the script object or not. -Overridden by subclasses that need to spawn the script object themselves. -================ -*/ -bool idEntity::ShouldConstructScriptObjectAtSpawn( void ) const { - return true; -} - -/* -================ -idEntity::ConstructScriptObject - -Called during idEntity::Spawn. Calls the constructor on the script object. -Can be overridden by subclasses when a thread doesn't need to be allocated. -================ -*/ -idThread *idEntity::ConstructScriptObject( void ) { - idThread *thread; - const function_t *constructor; - - // init the script object's data - scriptObject.ClearObject(); - - // call script object's constructor (usually "init()") - constructor = scriptObject.GetConstructor(); - if ( constructor ) { - // start a thread that will initialize after Spawn is done being called - thread = new idThread(); - thread->SetThreadName( name.c_str() ); - thread->CallFunction( this, constructor, true ); - thread->DelayedStart( 0 ); - } else { - thread = NULL; - } - - // clear out the object's memory - scriptObject.ClearObject(); - - return thread; -} - -/* -================ -idEntity::DeconstructScriptObject - -Called during idEntity::~idEntity. Calls the destructor on the script object. -Can be overridden by subclasses when a thread doesn't need to be allocated. -Not called during idGameLocal::MapShutdown. -================ -*/ -void idEntity::DeconstructScriptObject( void ) { - idThread *thread; - const function_t *destructor; - - // don't bother calling the script object's destructor on map shutdown - if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) { - return; - } - - // call script object's destructor - destructor = scriptObject.GetDestructor(); - if ( destructor ) { - // start a thread that will run immediately and be destroyed - thread = new idThread(); - thread->SetThreadName( name.c_str() ); - thread->CallFunction( this, destructor, true ); - thread->Execute(); - delete thread; - } -} - -/* -================ -idEntity::HasSignal -================ -*/ -bool idEntity::HasSignal( signalNum_t signalnum ) const { - if ( !signals ) { - return false; - } - assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); - return ( signals->signal[ signalnum ].Num() > 0 ); -} - -/* -================ -idEntity::SetSignal -================ -*/ -void idEntity::SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function ) { - int i; - int num; - signal_t sig; - int threadnum; - - assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); - - if ( !signals ) { - signals = new signalList_t; - } - - assert( thread ); - threadnum = thread->GetThreadNum(); - - num = signals->signal[ signalnum ].Num(); - for( i = 0; i < num; i++ ) { - if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) { - signals->signal[ signalnum ][ i ].function = function; - return; - } - } - - if ( num >= MAX_SIGNAL_THREADS ) { - thread->Error( "Exceeded maximum number of signals per object" ); - } - - sig.threadnum = threadnum; - sig.function = function; - signals->signal[ signalnum ].Append( sig ); -} - -/* -================ -idEntity::ClearSignal -================ -*/ -void idEntity::ClearSignal( idThread *thread, signalNum_t signalnum ) { - assert( thread ); - if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { - gameLocal.Error( "Signal out of range" ); - } - - if ( !signals ) { - return; - } - - signals->signal[ signalnum ].Clear(); -} - -/* -================ -idEntity::ClearSignalThread -================ -*/ -void idEntity::ClearSignalThread( signalNum_t signalnum, idThread *thread ) { - int i; - int num; - int threadnum; - - assert( thread ); - - if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { - gameLocal.Error( "Signal out of range" ); - } - - if ( !signals ) { - return; - } - - threadnum = thread->GetThreadNum(); - - num = signals->signal[ signalnum ].Num(); - for( i = 0; i < num; i++ ) { - if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) { - signals->signal[ signalnum ].RemoveIndex( i ); - return; - } - } -} - -/* -================ -idEntity::Signal -================ -*/ -void idEntity::Signal( signalNum_t signalnum ) { - int i; - int num; - signal_t sigs[ MAX_SIGNAL_THREADS ]; - idThread *thread; - - assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) ); - - if ( !signals ) { - return; - } - - // we copy the signal list since each thread has the potential - // to end any of the threads in the list. By copying the list - // we don't have to worry about the list changing as we're - // processing it. - num = signals->signal[ signalnum ].Num(); - for( i = 0; i < num; i++ ) { - sigs[ i ] = signals->signal[ signalnum ][ i ]; - } - - // clear out the signal list so that we don't get into an infinite loop - // TDM: Removed this, signal should stay after triggering by default - // signals->signal[ signalnum ].Clear(); - - for( i = 0; i < num; i++ ) { - thread = idThread::GetThread( sigs[ i ].threadnum ); - if ( thread ) - { - thread->CallFunction( this, sigs[ i ].function, true ); - thread->Execute(); - } - // TDM: Create a new thread if the thread that added the signal is not still around - else - { - thread = new idThread(sigs[i].function); - thread->CallFunction( this, sigs[ i ].function, true ); - thread->Execute(); - } - } -} - -/* -================ -idEntity::SignalEvent -================ -*/ -void idEntity::SignalEvent( idThread *thread, signalNum_t signalnum ) { - if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) { - gameLocal.Error( "Signal out of range" ); - } - - if ( !signals ) { - return; - } - - Signal( signalnum ); -} - -/*********************************************************************** - - Guis. - -***********************************************************************/ - - -/* -================ -idEntity::TriggerGuis -================ -*/ -void idEntity::TriggerGuis( void ) { - int i; - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - if ( renderEntity.gui[ i ] ) { - renderEntity.gui[ i ]->Trigger( gameLocal.time ); - } - } -} - -/* -================ -idEntity::HandleGuiCommands -================ -*/ -bool idEntity::HandleGuiCommands( idEntity *entityGui, const char *cmds ) { - idEntity *targetEnt; - bool ret = false; - if ( entityGui && cmds && *cmds ) { - idLexer src; - idToken token, token2, token3, token4; - src.LoadMemory( cmds, strlen( cmds ), "guiCommands" ); - while( 1 ) { - - if ( !src.ReadToken( &token ) ) { - return ret; - } - - if ( token == ";" ) { - continue; - } - - if ( token.Icmp( "activate" ) == 0 ) { - bool targets = true; - if ( src.ReadToken( &token2 ) ) { - if ( token2 == ";" ) { - src.UnreadToken( &token2 ); - } else { - targets = false; - } - } - - if ( targets ) { - entityGui->ActivateTargets( this ); - } else { - idEntity *ent = gameLocal.FindEntity( token2 ); - if ( ent ) { - ent->Signal( SIG_TRIGGER ); - ent->PostEventMS( &EV_Activate, 0, this ); - } - } - - entityGui->renderEntity.shaderParms[ SHADERPARM_MODE ] = 1.0f; - continue; - } - - - if ( token.Icmp( "runScript" ) == 0 ) { - if ( src.ReadToken( &token2 ) ) { - while( src.CheckTokenString( "::" ) ) { - idToken token3; - if ( !src.ReadToken( &token3 ) ) { - gameLocal.Error( "Expecting function name following '::' in gui for entity '%s'", entityGui->name.c_str() ); - } - token2 += "::" + token3; - } - const function_t *func = gameLocal.program.FindFunction( token2 ); - if ( !func ) { - gameLocal.Error( "Can't find function '%s' for gui in entity '%s'", token2.c_str(), entityGui->name.c_str() ); - } else { - idThread *thread = new idThread( func ); - thread->DelayedStart( 0 ); - } - } - continue; - } - - if ( token.Icmp("play") == 0 ) { - if ( src.ReadToken( &token2 ) ) { - const idSoundShader *shader = declManager->FindSound(token2); - entityGui->StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL ); - } - continue; - } - - if ( token.Icmp( "setkeyval" ) == 0 ) { - if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) && src.ReadToken( &token4 ) ) { - idEntity *ent = gameLocal.FindEntity( token2 ); - if ( ent ) { - ent->spawnArgs.Set( token3, token4 ); - ent->UpdateChangeableSpawnArgs( NULL ); - ent->UpdateVisuals(); - } - } - continue; - } - - if ( token.Icmp( "setshaderparm" ) == 0 ) { - if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) ) { - entityGui->SetShaderParm( atoi( token2 ), atof( token3 ) ); - entityGui->UpdateVisuals(); - } - continue; - } - - if ( token.Icmp("close") == 0 ) { - ret = true; - continue; - } - - // handy for debugging GUI stuff - if ( !token.Icmp( "print" ) ) { - idStr msg; - while ( src.ReadToken( &token2 ) ) { - if ( token2 == ";" ) { - src.UnreadToken( &token2 ); - break; - } - msg += token2.c_str(); - } - common->Printf( "ent gui 0x%x '%s': %s\n", entityNumber, name.c_str(), msg.c_str() ); - continue; - } - - // if we get to this point we don't know how to handle it - src.UnreadToken(&token); - if ( !HandleSingleGuiCommand( entityGui, &src ) ) { - // not handled there see if entity or any of its targets can handle it - // this will only work for one target atm - if ( entityGui->HandleSingleGuiCommand( entityGui, &src ) ) { - continue; - } - - int c = entityGui->targets.Num(); - int i; - for ( i = 0; i < c; i++) { - targetEnt = entityGui->targets[ i ].GetEntity(); - if ( targetEnt && targetEnt->HandleSingleGuiCommand( entityGui, &src ) ) { - break; - } - } - - if ( i == c ) { - // not handled - common->DPrintf( "idEntity::HandleGuiCommands: '%s' not handled\n", token.c_str() ); - src.ReadToken( &token ); - } - } - - } - } - return ret; -} - -/* -================ -idEntity::HandleSingleGuiCommand -================ -*/ -bool idEntity::HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ) { - return false; -} - -/*********************************************************************** - - Targets - -***********************************************************************/ - -/* -=============== -idEntity::FindTargets - -We have to wait until all entities are spawned -Used to build lists of targets after the entity is spawned. Since not all entities -have been spawned when the entity is created at map load time, we have to wait -=============== -*/ -void idEntity::FindTargets( void ) { - int i; - - // targets can be a list of multiple names - gameLocal.GetTargets( spawnArgs, targets, "target" ); - - // grayman #2603 - add relight positions as targets - gameLocal.GetRelights(spawnArgs,targets,"relight_position"); - - // ensure that we don't target ourselves since that could cause an infinite loop when activating entities - for( i = 0; i < targets.Num(); i++ ) { - if ( targets[ i ].GetEntity() == this ) { - gameLocal.Error( "Entity '%s' is targeting itself", name.c_str() ); - } - } -} - -// grayman #2603 - convert relight_positions to targets - -void idEntity::FindRelights(void) -{ - gameLocal.GetRelights(spawnArgs,targets,"relight_position"); -} - -/* -================ -idEntity::RemoveNullTargets -================ -*/ -void idEntity::RemoveNullTargets( void ) { - int i; - - for( i = targets.Num() - 1; i >= 0; i-- ) { - if ( !targets[ i ].GetEntity() ) { - targets.RemoveIndex( i ); - } - } -} - -/* -============================== -idEntity::ActivateTargets - -"activator" should be set to the entity that initiated the firing. -============================== -*/ -void idEntity::ActivateTargets( idEntity *activator ) const -{ - for (int i = 0; i < targets.Num(); i++ ) - { - idEntity* ent = targets[i].GetEntity(); - - if (ent == NULL) continue; - - // Call the virtual function - ent->Activate(activator); - - for (int j = 0; j < MAX_RENDERENTITY_GUI; j++) - { - if ( ent->renderEntity.gui[j] ) { - ent->renderEntity.gui[j]->Trigger(gameLocal.time); - } - } - } -} - -void idEntity::RemoveTarget(idEntity* target) -{ - for (int i = 0; i < targets.Num(); i++) - { - if (targets[i].GetEntity() == target) - { - targets.RemoveIndex(i); - return; - } - } -} - -void idEntity::AddTarget(idEntity* target) -{ - idEntityPtr ptr; - ptr = target; - targets.AddUnique(ptr); -} - -/*********************************************************************** - - Misc. - -***********************************************************************/ - -/* -================ -idEntity::Teleport -================ -*/ -void idEntity::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { - - if (destination == NULL) - { - GetPhysics()->SetOrigin( origin ); - GetPhysics()->SetAxis( angles.ToMat3() ); - } - else - { - // tels: copy origin and angles from the destination, but - // use potential "teleport_offset" and "teleport_random_offset" spawnargs - idVec3 offset = spawnArgs.GetVector( "teleport_offset", "0 0 0" ); - idVec3 rand_offset = spawnArgs.GetVector( "teleport_random_offset", "0 0 0" ); - - // replace "3 0 0" with a value of "-1.5 .. 1.5, 0, 0" - rand_offset.x = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.x) - idMath::Fabs(rand_offset.x) / 2; - rand_offset.y = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.y) - idMath::Fabs(rand_offset.y) / 2; - rand_offset.z = gameLocal.random.RandomFloat() * idMath::Fabs(rand_offset.z) - idMath::Fabs(rand_offset.z) / 2; - - GetPhysics()->SetOrigin( destination->GetPhysics()->GetOrigin() + offset + rand_offset ); - GetPhysics()->SetAxis( destination->GetPhysics()->GetAxis() ); - } - - UpdateVisuals(); -} - -/* -============ -idEntity::TouchTriggers - - Activate all trigger entities touched at the current position. -============ -*/ -bool idEntity::TouchTriggers( void ) const { - int i, numClipModels, numEntities; - idClipModel * cm; - idClipModel * clipModels[ MAX_GENTITIES ]; - idEntity * ent; - trace_t trace; - - memset( &trace, 0, sizeof( trace ) ); - trace.endpos = GetPhysics()->GetOrigin(); - trace.endAxis = GetPhysics()->GetAxis(); - - numClipModels = gameLocal.clip.ClipModelsTouchingBounds( GetPhysics()->GetAbsBounds(), CONTENTS_TRIGGER, clipModels, MAX_GENTITIES ); - numEntities = 0; - - for ( i = 0; i < numClipModels; i++ ) { - cm = clipModels[ i ]; - - // don't touch it if we're the owner - if ( cm->GetOwner() == this ) { - continue; - } - - ent = cm->GetEntity(); - - if ( !ent->RespondsTo( EV_Touch ) && !ent->HasSignal( SIG_TOUCH ) ) { - continue; - } - - if ( !GetPhysics()->ClipContents( cm ) ) { - continue; - } - - numEntities++; - - trace.c.contents = cm->GetContents(); - trace.c.entityNum = cm->GetEntity()->entityNumber; - trace.c.id = cm->GetId(); - - ent->Signal( SIG_TOUCH ); - ent->ProcessEvent( &EV_Touch, this, &trace ); - - if ( !gameLocal.entities[ entityNumber ] ) { - gameLocal.Printf( "entity was removed while touching triggers\n" ); - return true; - } - } - - return ( numEntities != 0 ); -} - -/* -================ -idEntity::GetSpline -================ -*/ -idCurve_Spline *idEntity::GetSpline( void ) const { - int i, numPoints, t; - const idKeyValue *kv; - idLexer lex; - idVec3 v; - idCurve_Spline *spline; - const char *curveTag = "curve_"; - - kv = spawnArgs.MatchPrefix( curveTag ); - if ( !kv ) { - return NULL; - } - - idStr str = kv->GetKey().Right( kv->GetKey().Length() - strlen( curveTag ) ); - if ( str.Icmp( "CatmullRomSpline" ) == 0 ) { - spline = new idCurve_CatmullRomSpline(); - } else if ( str.Icmp( "nubs" ) == 0 ) { - spline = new idCurve_NonUniformBSpline(); - } else if ( str.Icmp( "nurbs" ) == 0 ) { - spline = new idCurve_NURBS(); - } else { - spline = new idCurve_BSpline(); - } - - spline->SetBoundaryType( idCurve_Spline::BT_CLAMPED ); - - lex.LoadMemory( kv->GetValue(), kv->GetValue().Length(), curveTag ); - numPoints = lex.ParseInt(); - lex.ExpectTokenString( "(" ); - for ( t = i = 0; i < numPoints; i++, t += 100 ) { - v.x = lex.ParseFloat(); - v.y = lex.ParseFloat(); - v.z = lex.ParseFloat(); - spline->AddValue( t, v ); - } - lex.ExpectTokenString( ")" ); - - return spline; -} - -/* -=============== -idEntity::ShowEditingDialog -=============== -*/ -void idEntity::ShowEditingDialog( void ) { -} - -/*********************************************************************** - - Events - -***********************************************************************/ - -/* -================ -idEntity::Event_GetName -================ -*/ -void idEntity::Event_GetName( void ) { - idThread::ReturnString( name.c_str() ); -} - -/* -================ -idEntity::Event_SetName -================ -*/ -void idEntity::Event_SetName( const char *newname ) { - SetName( newname ); -} - -/* -================ -idEntity::Event_IsType -================ -*/ -void idEntity::Event_IsType( const char *pstr_typeName ) -{ - idTypeInfo* p_namedType = GetClass (pstr_typeName); - if (p_namedType == NULL) - { - idThread::ReturnInt (0); - } - else - { - if (IsType (*p_namedType)) - { - idThread::ReturnInt (1); - } - else - { - idThread::ReturnInt (0); - } - } -} - - -/* -=============== -idEntity::Event_FindTargets -=============== -*/ -void idEntity::Event_FindTargets( void ) { - FindTargets(); -} - -/* -============ -idEntity::Event_ActivateTargets - -Activates any entities targeted by this entity. Mainly used as an -event to delay activating targets. -============ -*/ -void idEntity::Event_ActivateTargets( idEntity *activator ) { - ActivateTargets( activator ); -} - - -void idEntity::Event_AddTarget(idEntity* target) -{ - AddTarget(target); -} - - -void idEntity::Event_RemoveTarget(idEntity* target) -{ - RemoveTarget(target); -} - - -/* -================ -idEntity::Event_NumTargets -================ -*/ -void idEntity::Event_NumTargets( void ) { - idThread::ReturnFloat( targets.Num() ); -} - -/* -================ -idEntity::Event_GetTarget -================ -*/ -void idEntity::Event_GetTarget( float index ) { - int i; - - i = ( int )index; - if ( ( i < 0 ) || i >= targets.Num() ) { - idThread::ReturnEntity( NULL ); - } else { - idThread::ReturnEntity( targets[ i ].GetEntity() ); - } -} - -/* -================ -idEntity::Event_RandomTarget -================ -*/ -void idEntity::Event_RandomTarget( const char *ignore ) { - int num; - idEntity *ent; - int i; - int ignoreNum; - - RemoveNullTargets(); - if ( !targets.Num() ) { - idThread::ReturnEntity( NULL ); - return; - } - - ignoreNum = -1; - if ( ignore && ( ignore[ 0 ] != 0 ) && ( targets.Num() > 1 ) ) { - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent && ( ent->name == ignore ) ) { - ignoreNum = i; - break; - } - } - } - - if ( ignoreNum >= 0 ) { - num = gameLocal.random.RandomInt( targets.Num() - 1 ); - if ( num >= ignoreNum ) { - num++; - } - } else { - num = gameLocal.random.RandomInt( targets.Num() ); - } - - ent = targets[ num ].GetEntity(); - idThread::ReturnEntity( ent ); -} - -/* -================ -idEntity::Event_BindToJoint -================ -*/ -void idEntity::Event_BindToJoint( idEntity *master, const char *jointname, float orientated ) { - BindToJoint( master, jointname, ( orientated != 0.0f ) ); -} - -/* -================ -idEntity::Event_BindToBody -================ -*/ -void idEntity::Event_BindToBody(idEntity *master, int bodyId, bool orientated) { - BindToBody( master, bodyId, orientated ); -} - - -/* -================ -idEntity::Event_RemoveBinds -================ -*/ -void idEntity::Event_RemoveBinds( void ) { - RemoveBinds(); -} - -/* -================ -idEntity::Event_Bind -================ -*/ -void idEntity::Event_Bind( idEntity *master ) { - Bind( master, true ); -} - -/* -================ -idEntity::Event_BindPosition -================ -*/ -void idEntity::Event_BindPosition( idEntity *master ) { - Bind( master, false ); -} - -/* -================ -idEntity::Event_Unbind -================ -*/ -void idEntity::Event_Unbind( void ) { - Unbind(); -} - -/* -================ -idEntity::Event_SpawnBind -================ -*/ -void idEntity::Event_SpawnBind( void ) -{ - idEntity *parent; - const char *bind, *joint, *bindanim; - jointHandle_t bindJoint; - bool bindOrientated; - int id; - const idAnim *anim; - int animNum; - idAnimator *parentAnimator; - - if ( spawnArgs.GetString( "bind", "", &bind ) ) - { - parent = gameLocal.FindEntity( bind ); - - bindOrientated = spawnArgs.GetBool( "bindOrientated", "1" ); - if ( parent ) - { - if (spawnArgs.GetBool("is_attachment")) - { - parent->Attach(this); - } - - // bind to a joint of the skeletal model of the parent - if ( spawnArgs.GetString( "bindToJoint", "", &joint ) && *joint ) - { - parentAnimator = parent->GetAnimator(); - if ( !parentAnimator ) - gameLocal.Error( "Cannot bind to joint '%s' on '%s'. Entity does not support skeletal models.", joint, name.c_str() ); - - bindJoint = parentAnimator->GetJointHandle( joint ); - if ( bindJoint == INVALID_JOINT ) - gameLocal.Error( "Joint '%s' not found for bind on '%s'", joint, name.c_str() ); - - // bind it relative to a specific anim - if ( ( parent->spawnArgs.GetString( "bindanim", "", &bindanim ) - || parent->spawnArgs.GetString( "anim", "", &bindanim ) ) && *bindanim ) - { - animNum = parentAnimator->GetAnim( bindanim ); - if ( !animNum ) { - gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() ); - } - anim = parentAnimator->GetAnim( animNum ); - if ( !anim ) { - gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() ); - } - - // make sure parent's render origin has been set - parent->UpdateModelTransform(); - - //FIXME: need a BindToJoint that accepts a joint position - parentAnimator->CreateFrame( gameLocal.time, true ); - idJointMat *frame = parent->renderEntity.joints; - gameEdit->ANIM_CreateAnimFrame( parentAnimator->ModelHandle(), anim->MD5Anim( 0 ), parent->renderEntity.numJoints, frame, 0, parentAnimator->ModelDef()->GetVisualOffset(), parentAnimator->RemoveOrigin() ); - BindToJoint( parent, joint, bindOrientated ); - parentAnimator->ForceUpdate(); - } - else - BindToJoint( parent, joint, bindOrientated ); - } - // bind to a body of the physics object of the parent - else if ( spawnArgs.GetInt( "bindToBody", "0", id ) ) - BindToBody( parent, id, bindOrientated ); - // no joint specified, bind to the parent - else - Bind( parent, bindOrientated ); - } - } -} - -/* -================ -idEntity::Event_SetOwner -================ -*/ -void idEntity::Event_SetOwner( idEntity *owner ) { - int i; - - for ( i = 0; i < GetPhysics()->GetNumClipModels(); i++ ) { - GetPhysics()->GetClipModel( i )->SetOwner( owner ); - } -} - -/* -================ -idEntity::Event_SetModel -================ -*/ -void idEntity::Event_SetModel( const char *modelname ) { - SetModel( modelname ); -} - -/* -================ -idEntity::Event_SetSkin -================ -*/ -void idEntity::Event_SetSkin( const char *skinname ) { - renderEntity.customSkin = declManager->FindSkin( skinname ); - UpdateVisuals(); -} - -/* -================ -idEntity::Event_GetShaderParm -================ -*/ -void idEntity::Event_GetShaderParm( int parmnum ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Error( "shader parm index (%d) out of range", parmnum ); - } - - idThread::ReturnFloat( renderEntity.shaderParms[ parmnum ] ); -} - -/* -================ -idEntity::Event_SetShaderParm -================ -*/ -void idEntity::Event_SetShaderParm( int parmnum, float value ) { - SetShaderParm( parmnum, value ); -} - -/* -================ -idEntity::Event_SetShaderParms -================ -*/ -void idEntity::Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 ) { - renderEntity.shaderParms[ SHADERPARM_RED ] = parm0; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = parm1; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = parm2; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = parm3; - UpdateVisuals(); -} - - -/* -================ -idEntity::Event_SetColor -================ -*/ -void idEntity::Event_SetColor( float red, float green, float blue ) { - SetColor( red, green, blue ); -} - -/* -================ -idEntity::Event_GetColor -================ -*/ -void idEntity::Event_GetColor( void ) { - idVec3 out; - - GetColor( out ); - idThread::ReturnVector( out ); -} - -/* -================ -idEntity::Event_IsHidden -================ -*/ -void idEntity::Event_IsHidden( void ) { - idThread::ReturnInt( fl.hidden ); -} - -/* -================ -idEntity::Event_Hide -================ -*/ -void idEntity::Event_Hide( void ) { - Hide(); -} - -/* -================ -idEntity::Event_Show -================ -*/ -void idEntity::Event_Show( void ) { - Show(); -} - -/* -================ -idEntity::Event_CacheSoundShader -================ -*/ -void idEntity::Event_CacheSoundShader( const char *soundName ) { - declManager->FindSound( soundName ); -} - -/* -================ -idEntity::Event_StartSoundShader -================ -*/ -void idEntity::Event_StartSoundShader( const char *soundName, int channel ) { - int length; - - StartSoundShader( declManager->FindSound( soundName ), (s_channelType)channel, 0, false, &length ); - idThread::ReturnFloat( MS2SEC( length ) ); -} - -/* -================ -idEntity::Event_StopSound -================ -*/ -void idEntity::Event_StopSound( int channel, int netSync ) { - StopSound( channel, ( netSync != 0 ) ); -} - -/* -================ -idEntity::Event_StartSound -================ -*/ -void idEntity::Event_StartSound( const char *soundName, int channel, int netSync ) { - int time; - - StartSound( soundName, ( s_channelType )channel, 0, ( netSync != 0 ), &time ); - idThread::ReturnFloat( MS2SEC( time ) ); -} - -/* -================ -idEntity::Event_FadeSound -================ -*/ -void idEntity::Event_FadeSound( int channel, float to, float over ) { - if ( refSound.referenceSound ) { - refSound.referenceSound->FadeSound( channel, to, over ); - } -} - -/* -================ -idEntity::Event_SetSoundVolume - -tels: -================ -*/ -void idEntity::Event_SetSoundVolume( float volume ) { - refSound.parms.volume = volume; -} - -/* -================ -idEntity::Event_GetWorldOrigin -================ -*/ -void idEntity::Event_GetWorldOrigin( void ) { - idThread::ReturnVector( GetPhysics()->GetOrigin() ); -} - -/* -================ -idEntity::Event_SetWorldOrigin -================ -*/ -void idEntity::Event_SetWorldOrigin( idVec3 const &org ) { - idVec3 neworg = GetLocalCoordinates( org ); - SetOrigin( neworg ); -} - -/* -================ -idEntity::Event_SetOrigin -================ -*/ -void idEntity::Event_SetOrigin( idVec3 const &org ) { - SetOrigin( org ); -} - -/* -================ -idEntity::Event_GetOrigin -================ -*/ -void idEntity::Event_GetOrigin( void ) { - idThread::ReturnVector( GetLocalCoordinates( GetPhysics()->GetOrigin() ) ); -} - -/* -================ -idEntity::Event_SetAngles -================ -*/ -void idEntity::Event_SetAngles( idAngles const &ang ) { - SetAngles( ang ); -} - -/* -================ -idEntity::Event_GetAngles -================ -*/ -void idEntity::Event_GetAngles( void ) { - idAngles ang = GetPhysics()->GetAxis().ToAngles(); - idThread::ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); -} - -/* -================ -idEntity::Event_SetLinearVelocity -================ -*/ -void idEntity::Event_SetLinearVelocity( const idVec3 &velocity ) { - GetPhysics()->SetLinearVelocity( velocity ); -} - -/* -================ -idEntity::Event_GetLinearVelocity -================ -*/ -void idEntity::Event_GetLinearVelocity( void ) { - idThread::ReturnVector( GetPhysics()->GetLinearVelocity() ); -} - -/* -================ -idEntity::Event_SetAngularVelocity -================ -*/ -void idEntity::Event_SetAngularVelocity( const idVec3 &velocity ) { - GetPhysics()->SetAngularVelocity( velocity ); -} - -/* -================ -idEntity::Event_GetAngularVelocity -================ -*/ -void idEntity::Event_GetAngularVelocity( void ) { - idThread::ReturnVector( GetPhysics()->GetAngularVelocity() ); -} - -/* -================ -idEntity::Event_SetSize -================ -*/ -void idEntity::Event_SetSize( idVec3 const &mins, idVec3 const &maxs ) { - GetPhysics()->SetClipBox( idBounds( mins, maxs ), 1.0f ); -} - -/* -================ -idEntity::Event_GetSize -================ -*/ -void idEntity::Event_GetSize( void ) { - idBounds bounds; - - bounds = GetPhysics()->GetBounds(); - idThread::ReturnVector( bounds[1] - bounds[0] ); -} - -/* -================ -idEntity::Event_GetMins -================ -*/ -void idEntity::Event_GetMins( void ) { - idThread::ReturnVector( GetPhysics()->GetBounds()[0] ); -} - -/* -================ -idEntity::Event_GetMaxs -================ -*/ -void idEntity::Event_GetMaxs( void ) { - idThread::ReturnVector( GetPhysics()->GetBounds()[1] ); -} - -/* -================ -idEntity::Event_Touches -================ -*/ -void idEntity::Event_Touches( idEntity *ent ) { - if ( !ent ) { - idThread::ReturnInt( false ); - return; - } - - const idBounds &myBounds = GetPhysics()->GetAbsBounds(); - const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); - - idThread::ReturnInt( myBounds.IntersectsBounds( entBounds ) ); -} - -/* -================ -idEntity::Event_GetNextKey -================ -*/ -void idEntity::Event_GetNextKey( const char *prefix, const char *lastMatch ) { - const idKeyValue *kv; - const idKeyValue *previous; - - if ( *lastMatch ) { - previous = spawnArgs.FindKey( lastMatch ); - } else { - previous = NULL; - } - - kv = spawnArgs.MatchPrefix( prefix, previous ); - if ( !kv ) { - idThread::ReturnString( "" ); - } else { - idThread::ReturnString( kv->GetKey() ); - } -} - -/* -================ -idEntity::Event_SetKey -================ -*/ -void idEntity::Event_SetKey( const char *key, const char *value ) { - spawnArgs.Set( key, value ); -} - -/* -================ -idEntity::Event_GetKey -================ -*/ -void idEntity::Event_GetKey( const char *key ) { - const char *value; - - spawnArgs.GetString( key, "", &value ); - idThread::ReturnString( value ); -} - -/* -================ -idEntity::Event_GetIntKey -================ -*/ -void idEntity::Event_GetIntKey( const char *key ) { - int value; - - spawnArgs.GetInt( key, "0", value ); - - // scripts only support floats - idThread::ReturnFloat( value ); -} - -/* -================ -idEntity::Event_GetFloatKey -================ -*/ -void idEntity::Event_GetFloatKey( const char *key ) { - float value; - - spawnArgs.GetFloat( key, "0", value ); - idThread::ReturnFloat( value ); -} - -/* -================ -idEntity::Event_GetVectorKey -================ -*/ -void idEntity::Event_GetVectorKey( const char *key ) { - idVec3 value; - - spawnArgs.GetVector( key, "0 0 0", value ); - idThread::ReturnVector( value ); -} - -/* -================ -idEntity::Event_GetEntityKey -================ -*/ -void idEntity::Event_GetEntityKey( const char *key ) { - idEntity *ent; - const char *entname; - - if ( !spawnArgs.GetString( key, NULL, &entname ) ) { - idThread::ReturnEntity( NULL ); - return; - } - - ent = gameLocal.FindEntity( entname ); - if ( !ent ) { - gameLocal.Warning( "Couldn't find entity '%s' specified in '%s' key in entity '%s'", entname, key, name.c_str() ); - } - - idThread::ReturnEntity( ent ); -} - -/* -================ -idEntity::Event_RemoveKey -================ -*/ -void idEntity::Event_RemoveKey( const char *key ) { - spawnArgs.Delete( key ); -} - -/* -================ -idEntity::Event_RestorePosition -================ -*/ -void idEntity::Event_RestorePosition( void ) { - idVec3 org; - idAngles angles; - idMat3 axis; - idEntity * part; - - spawnArgs.GetVector( "origin", "0 0 0", org ); - - // get the rotation matrix in either full form, or single angle form - if ( spawnArgs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) { - angles = axis.ToAngles(); - } else { - angles[ 0 ] = 0; - angles[ 1 ] = spawnArgs.GetFloat( "angle" ); - angles[ 2 ] = 0; - } - - Teleport( org, angles, NULL ); - - for ( part = teamChain; part != NULL; part = part->teamChain ) { - if ( part->bindMaster != this ) { - continue; - } - if ( part->GetPhysics()->IsType( idPhysics_Parametric::Type ) ) { - if ( static_cast(part->GetPhysics())->IsPusher() ) { - gameLocal.Warning( "teleported '%s' which has the pushing mover '%s' bound to it\n", GetName(), part->GetName() ); - } - } else if ( part->GetPhysics()->IsType( idPhysics_AF::Type ) ) { - gameLocal.Warning( "teleported '%s' which has the articulated figure '%s' bound to it\n", GetName(), part->GetName() ); - } - } -} - -/* -================ -idEntity::Event_UpdateCameraTarget -================ -*/ -void idEntity::Event_UpdateCameraTarget( void ) { - const char *target; - const idKeyValue *kv; - idVec3 dir; - - target = spawnArgs.GetString( "cameraTarget" ); - - cameraTarget = gameLocal.FindEntity( target ); - - if ( cameraTarget ) { - kv = cameraTarget->spawnArgs.MatchPrefix( "target", NULL ); - while( kv ) { - idEntity *ent = gameLocal.FindEntity( kv->GetValue() ); - if ( ent && idStr::Icmp( ent->GetEntityDefName(), "target_null" ) == 0) { - dir = ent->GetPhysics()->GetOrigin() - cameraTarget->GetPhysics()->GetOrigin(); - dir.Normalize(); - cameraTarget->SetAxis( dir.ToMat3() ); - SetAxis(dir.ToMat3()); - break; - } - kv = cameraTarget->spawnArgs.MatchPrefix( "target", kv ); - } - } - UpdateVisuals(); -} - -/* -================ -idEntity::Event_DistanceTo -================ -*/ -void idEntity::Event_DistanceTo( idEntity *ent ) { - if ( !ent ) { - // just say it's really far away - idThread::ReturnFloat( MAX_WORLD_SIZE ); - } else { - float dist = ( GetPhysics()->GetOrigin() - ent->GetPhysics()->GetOrigin() ).LengthFast(); - idThread::ReturnFloat( dist ); - } -} - -/* -================ -idEntity::Event_DistanceToPoint -================ -*/ -void idEntity::Event_DistanceToPoint( const idVec3 &point ) { - float dist = ( GetPhysics()->GetOrigin() - point ).LengthFast(); - idThread::ReturnFloat( dist ); -} - -/* -================ -idEntity::Event_StartFx -================ -*/ -void idEntity::Event_StartFx( const char *fx ) { - idEntityFx::StartFx( fx, NULL, NULL, this, true ); -} - -/* -================ -idEntity::Event_WaitFrame -================ -*/ -void idEntity::Event_WaitFrame( void ) { - idThread *thread; - - thread = idThread::CurrentThread(); - if ( thread ) { - thread->WaitFrame(); - } -} - -/* -===================== -idEntity::Event_Wait -===================== -*/ -void idEntity::Event_Wait( float time ) { - idThread *thread = idThread::CurrentThread(); - - if ( !thread ) { - gameLocal.Error( "Event 'wait' called from outside thread" ); - } - - thread->WaitSec( time ); -} - -/* -===================== -idEntity::Event_HasFunction -===================== -*/ -void idEntity::Event_HasFunction( const char *name ) { - const function_t *func; - - func = scriptObject.GetFunction( name ); - if ( func ) { - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/* -===================== -idEntity::Event_CallFunction -===================== -*/ -void idEntity::Event_CallFunction( const char *funcname ) { - const function_t *func; - idThread *thread; - - thread = idThread::CurrentThread(); - if ( !thread ) { - gameLocal.Error( "Event 'callFunction' called from outside thread" ); - } - - func = scriptObject.GetFunction( funcname ); - if ( !func ) { - gameLocal.Error( "Unknown function '%s' in '%s'", funcname, scriptObject.GetTypeName() ); - } - - if ( func->type->NumParameters() != 1 ) { - gameLocal.Error( "Function '%s' has the wrong number of parameters for 'callFunction'", funcname ); - } - if ( !scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { - gameLocal.Error( "Function '%s' is the wrong type for 'callFunction'", funcname ); - } - - // function args will be invalid after this call - thread->CallFunction( this, func, false ); -} - -/* -===================== -idEntity::Event_CallGlobalFunction -===================== -*/ -void idEntity::Event_CallGlobalFunction( const char *funcname, idEntity *ent ) { - const function_t *func; - idThread *thread; - - thread = idThread::CurrentThread(); - if ( !thread ) { - gameLocal.Error( "Event 'callGlobalFunction' called from outside thread" ); - } - - func = gameLocal.program.FindFunction( funcname ); - if ( !func ) { - gameLocal.Error( "Unknown global function '%s'", funcname ); - } - - if ( func->type->NumParameters() != 1 ) { - gameLocal.Error( "Function '%s' has the wrong number of parameters for 'callGlobalFunction'", funcname ); - } - /* - if ( !scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { - gameLocal.Error( "Function '%s' is the wrong type for 'callGlobalFunction'", funcname ); - } */ - - // function args will be invalid after this call - thread->CallFunction( ent, func, false ); -} - -/* -================ -idEntity::Event_SetNeverDormant -================ -*/ -void idEntity::Event_SetNeverDormant( int enable ) { - fl.neverDormant = ( enable != 0 ); - dormantStart = 0; -} - -#ifdef MOD_WATERPHYSICS - -/* - -================ - -idEntity::Event_GetMass MOD_WATERPHYSICS - -================ - -*/ - -void idEntity::Event_GetMass( int id ) { - - idThread::ReturnFloat(physics->GetMass(id)); - -} - - - -/* - -================ - -idEntity::Event_IsInLiquid MOD_WATERPHYSICS - -================ - -*/ - -void idEntity::Event_IsInLiquid( void ) { - - idThread::ReturnInt(physics->GetWater() != NULL); - -} - -#endif // MOD_WATERPHYSICS - - -/* -================ -idEntity::Event_CopyBind -================ -*/ - -void idEntity::Event_CopyBind( idEntity* other ) -{ - if (other == NULL) return; - - idEntity *master = other->GetBindMaster(); - - jointHandle_t joint = other->GetBindJoint(); - - int body = other->GetBindBody(); - if( joint != INVALID_JOINT ) - { - // joint is specified so bind to that joint - BindToJoint( master, joint, true ); - } - else if( body >= 0 ) - { - // body is specified so bind to it - BindToBody( master, body, true ); - } - else - { - // no joint and no body specified, so bind to master - Bind( master, true ); - - // greebo: If the bind master is static, set the solid for team flag - if (master && master->GetPhysics()->IsType(idPhysics_Static::Type)) - { - fl.solidForTeam = true; - } - } -} - -/*********************************************************************** - - Network - -***********************************************************************/ - -/* -================ -idEntity::ClientPredictionThink -================ -*/ -void idEntity::ClientPredictionThink( void ) { - RunPhysics(); - Present(); -} - -/* -================ -idEntity::WriteBindToSnapshot -================ -*/ -void idEntity::WriteBindToSnapshot( idBitMsgDelta &msg ) const { - int bindInfo; - - if ( bindMaster ) { - bindInfo = bindMaster->entityNumber; - bindInfo |= ( fl.bindOrientated & 1 ) << GENTITYNUM_BITS; - if ( bindJoint != INVALID_JOINT ) { - bindInfo |= 1 << ( GENTITYNUM_BITS + 1 ); - bindInfo |= bindJoint << ( 3 + GENTITYNUM_BITS ); - } else if ( bindBody != -1 ) { - bindInfo |= 2 << ( GENTITYNUM_BITS + 1 ); - bindInfo |= bindBody << ( 3 + GENTITYNUM_BITS ); - } - } else { - bindInfo = ENTITYNUM_NONE; - } - msg.WriteBits( bindInfo, GENTITYNUM_BITS + 3 + 9 ); -} - -/* -================ -idEntity::ReadBindFromSnapshot -================ -*/ -void idEntity::ReadBindFromSnapshot( const idBitMsgDelta &msg ) { - int bindInfo, bindEntityNum, bindPos; - bool bindOrientated; - idEntity *master; - - bindInfo = msg.ReadBits( GENTITYNUM_BITS + 3 + 9 ); - bindEntityNum = bindInfo & ( ( 1 << GENTITYNUM_BITS ) - 1 ); - - if ( bindEntityNum != ENTITYNUM_NONE ) { - master = gameLocal.entities[ bindEntityNum ]; - - bindOrientated = ( bindInfo >> GENTITYNUM_BITS ) & 1; - bindPos = ( bindInfo >> ( GENTITYNUM_BITS + 3 ) ); - switch( ( bindInfo >> ( GENTITYNUM_BITS + 1 ) ) & 3 ) { - case 1: { - BindToJoint( master, (jointHandle_t) bindPos, bindOrientated ); - break; - } - case 2: { - BindToBody( master, bindPos, bindOrientated ); - break; - } - default: { - Bind( master, bindOrientated ); - break; - } - } - } else if ( bindMaster ) { - Unbind(); - } -} - -/* -================ -idEntity::WriteColorToSnapshot -================ -*/ -void idEntity::WriteColorToSnapshot( idBitMsgDelta &msg ) const { - idVec4 color; - - color[0] = renderEntity.shaderParms[ SHADERPARM_RED ]; - color[1] = renderEntity.shaderParms[ SHADERPARM_GREEN ]; - color[2] = renderEntity.shaderParms[ SHADERPARM_BLUE ]; - color[3] = renderEntity.shaderParms[ SHADERPARM_ALPHA ]; - msg.WriteLong( PackColor( color ) ); -} - -/* -================ -idEntity::ReadColorFromSnapshot -================ -*/ -void idEntity::ReadColorFromSnapshot( const idBitMsgDelta &msg ) { - idVec4 color; - - UnpackColor( msg.ReadLong(), color ); - renderEntity.shaderParms[ SHADERPARM_RED ] = color[0]; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[1]; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[2]; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[3]; -} - -/* -================ -idEntity::WriteGUIToSnapshot -================ -*/ -void idEntity::WriteGUIToSnapshot( idBitMsgDelta &msg ) const { - // no need to loop over MAX_RENDERENTITY_GUI at this time - if ( renderEntity.gui[ 0 ] ) { - msg.WriteByte( renderEntity.gui[ 0 ]->State().GetInt( "networkState" ) ); - } else { - msg.WriteByte( 0 ); - } -} - -/* -================ -idEntity::ReadGUIFromSnapshot -================ -*/ -void idEntity::ReadGUIFromSnapshot( const idBitMsgDelta &msg ) { - int state; - idUserInterface *gui; - state = msg.ReadByte( ); - gui = renderEntity.gui[ 0 ]; - if ( gui && state != mpGUIState ) { - mpGUIState = state; - gui->SetStateInt( "networkState", state ); - gui->HandleNamedEvent( "networkState" ); - } -} - -/* -================ -idEntity::WriteToSnapshot -================ -*/ -void idEntity::WriteToSnapshot( idBitMsgDelta &msg ) const { -} - -/* -================ -idEntity::ReadFromSnapshot -================ -*/ -void idEntity::ReadFromSnapshot( const idBitMsgDelta &msg ) { -} - -/* -================ -idEntity::ServerSendEvent - - Saved events are also sent to any client that connects late so all clients - always receive the events nomatter what time they join the game. -================ -*/ -void idEntity::ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - if ( !gameLocal.isServer ) { - return; - } - - // prevent dupe events caused by frame re-runs - if ( !gameLocal.isNewFrame ) { - return; - } - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); - outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); - outMsg.WriteByte( eventId ); - outMsg.WriteLong( gameLocal.time ); - if ( msg ) { - outMsg.WriteBits( msg->GetSize(), idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - outMsg.WriteData( msg->GetData(), msg->GetSize() ); - } else { - outMsg.WriteBits( 0, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - } - - if ( excludeClient != -1 ) { - networkSystem->ServerSendReliableMessageExcluding( excludeClient, outMsg ); - } else { - networkSystem->ServerSendReliableMessage( -1, outMsg ); - } - - if ( saveEvent ) { - gameLocal.SaveEntityNetworkEvent( this, eventId, msg ); - } - } - -/* -================ -idEntity::ClientSendEvent -================ -*/ -void idEntity::ClientSendEvent( int eventId, const idBitMsg *msg ) const { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - if ( !gameLocal.isClient ) { - return; - } - - // prevent dupe events caused by frame re-runs - if ( !gameLocal.isNewFrame ) { - return; - } - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); - outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 ); - outMsg.WriteByte( eventId ); - outMsg.WriteLong( gameLocal.time ); - if ( msg ) { - outMsg.WriteBits( msg->GetSize(), idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - outMsg.WriteData( msg->GetData(), msg->GetSize() ); - } else { - outMsg.WriteBits( 0, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - } - - networkSystem->ClientSendReliableMessage( outMsg ); -} - -/* -================ -idEntity::ServerReceiveEvent -================ -*/ -bool idEntity::ServerReceiveEvent( int event, int time, const idBitMsg &msg ) { - switch( event ) { - case 0: { - } - default: { - return false; - } - } -} - -/* -================ -idEntity::ClientReceiveEvent -================ -*/ -bool idEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - int index; - const idSoundShader *shader; - s_channelType channel; - - switch( event ) { - case EVENT_STARTSOUNDSHADER: { - // the sound stuff would early out - assert( gameLocal.isNewFrame ); - if ( time < gameLocal.realClientTime - 1000 ) { - // too old, skip it ( reliable messages don't need to be parsed in full ) - common->DPrintf( "ent 0x%x: start sound shader too old (%d ms)\n", entityNumber, gameLocal.realClientTime - time ); - return true; - } - index = gameLocal.ClientRemapDecl( DECL_SOUND, msg.ReadLong() ); - if ( index >= 0 && index < declManager->GetNumDecls( DECL_SOUND ) ) { - shader = declManager->SoundByIndex( index, false ); - channel = (s_channelType)msg.ReadByte(); - StartSoundShader( shader, channel, 0, false, NULL ); - } - return true; - } - case EVENT_STOPSOUNDSHADER: { - // the sound stuff would early out - assert( gameLocal.isNewFrame ); - channel = (s_channelType)msg.ReadByte(); - StopSound( channel, false ); - return true; - } - default: { - return false; - } - } -// return false; -} - -/* -=============================================================================== - - idAnimatedEntity - -=============================================================================== -*/ - -const idEventDef EV_GetJointHandle( "getJointHandle", "s", 'd' ); -const idEventDef EV_ClearAllJoints( "clearAllJoints" ); -const idEventDef EV_ClearJoint( "clearJoint", "d" ); -const idEventDef EV_SetJointPos( "setJointPos", "ddv" ); -const idEventDef EV_SetJointAngle( "setJointAngle", "ddv" ); -const idEventDef EV_GetJointPos( "getJointPos", "d", 'v' ); -const idEventDef EV_GetJointAngle( "getJointAngle", "d", 'v' ); - -CLASS_DECLARATION( idEntity, idAnimatedEntity ) - EVENT( EV_GetJointHandle, idAnimatedEntity::Event_GetJointHandle ) - EVENT( EV_ClearAllJoints, idAnimatedEntity::Event_ClearAllJoints ) - EVENT( EV_ClearJoint, idAnimatedEntity::Event_ClearJoint ) - EVENT( EV_SetJointPos, idAnimatedEntity::Event_SetJointPos ) - EVENT( EV_SetJointAngle, idAnimatedEntity::Event_SetJointAngle ) - EVENT( EV_GetJointPos, idAnimatedEntity::Event_GetJointPos ) - EVENT( EV_GetJointAngle, idAnimatedEntity::Event_GetJointAngle ) -END_CLASS - -/* -================ -CAttachInfo::Save -================ -*/ -void CAttachInfo::Save( idSaveGame *savefile ) const -{ - ent.Save( savefile ); - savefile->WriteInt( channel ); - savefile->WriteString( name ); - savefile->WriteInt(savedContents); - savefile->WriteString(posName); // grayman #2603 -} - -/* -================ -CAttachInfo::Restore -================ -*/ -void CAttachInfo::Restore( idRestoreGame *savefile ) -{ - ent.Restore( savefile ); - savefile->ReadInt( channel ); - savefile->ReadString( name ); - savefile->ReadInt(savedContents); - savefile->ReadString(posName); // grayman #2603 -} - -/* -================ -idAnimatedEntity::idAnimatedEntity -================ -*/ -idAnimatedEntity::idAnimatedEntity() : - lastUpdateTime(-1) -{ - animator.SetEntity( this ); - damageEffects = NULL; -} - -/* -================ -idAnimatedEntity::~idAnimatedEntity -================ -*/ -idAnimatedEntity::~idAnimatedEntity() { - damageEffect_t *de; - - for ( de = damageEffects; de; de = damageEffects ) { - damageEffects = de->next; - delete de; - } -} - -/* -=============== -idAnimatedEntity::Spawn -=============== -*/ -void idAnimatedEntity::Spawn( void ) -{ - // Cache animation rates - CacheAnimRates(); - int anims = animator.NumAnims(); - m_animRates.Clear(); - m_animRates.AssureSize(anims); - for (int i=0; iName(); - m_animRates[i] = spawnArgs.GetFloat(spawnargname, "1"); - } else - { - m_animRates[i] = 1.0f; - } - } - - lastUpdateTime = 0; -} - -/* -================ -idAnimatedEntity::Save - -archives object for save game file -================ -*/ -void idAnimatedEntity::Save( idSaveGame *savefile ) const -{ - animator.Save( savefile ); - savefile->WriteInt(lastUpdateTime); - - // Wounds are very temporary, ignored at this time - //damageEffect_t *damageEffects; -} - -/* -================ -idAnimatedEntity::Restore - -unarchives object from save game file -================ -*/ -void idAnimatedEntity::Restore( idRestoreGame *savefile ) -{ - animator.Restore( savefile ); - savefile->ReadInt(lastUpdateTime); - - // check if the entity has an MD5 model - if ( animator.ModelHandle() ) - { - // set the callback to update the joints - renderEntity.callback = idEntity::ModelCallback; - - animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); - animator.GetBounds( gameLocal.time, renderEntity.bounds ); - if ( modelDefHandle != -1 ) { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } - } -} - -/* -================ -idAnimatedEntity::ClientPredictionThink -================ -*/ -void idAnimatedEntity::ClientPredictionThink( void ) { - RunPhysics(); - UpdateAnimation(); - Present(); -} - -/* -================ -idAnimatedEntity::Think -================ -*/ -void idAnimatedEntity::Think( void ) { - RunPhysics(); - UpdateAnimation(); - Present(); - UpdateDamageEffects(); -} - -/* -================ -idAnimatedEntity::UpdateAnimation -================ -*/ -void idAnimatedEntity::UpdateAnimation( void ) { - // don't do animations if they're not enabled - if ( !( thinkFlags & TH_ANIMATE ) ) { - return; - } - - // is the model an MD5? - if ( !animator.ModelHandle() ) { - // no, so nothing to do - return; - } - - // call any frame commands that have happened since the last update - if ( !fl.hidden ) - { - animator.ServiceAnims( lastUpdateTime, gameLocal.time ); - lastUpdateTime = gameLocal.time; - } - - // if the model is animating then we have to update it - if ( !animator.FrameHasChanged( gameLocal.time ) ) { - // still fine the way it was - return; - } - - // get the latest frame bounds - animator.GetBounds( gameLocal.time, renderEntity.bounds ); - if ( renderEntity.bounds.IsCleared() && !fl.hidden ) { - gameLocal.DPrintf( "%d: inside out bounds\n", gameLocal.time ); - } - - // update the renderEntity - UpdateVisuals(); - - // the animation is updated - animator.ClearForceUpdate(); -} - -/* -================ -idAnimatedEntity::GetAnimator -================ -*/ -idAnimator *idAnimatedEntity::GetAnimator( void ) { - return &animator; -} - -/* -================ -idAnimatedEntity::SetModel -================ -*/ -void idAnimatedEntity::SetModel( const char *modelname ) { - FreeModelDef(); - - renderEntity.hModel = animator.SetModel( modelname ); - if ( !renderEntity.hModel ) { - idEntity::SetModel( modelname ); - return; - } - - if ( !renderEntity.customSkin ) { - renderEntity.customSkin = animator.ModelDef()->GetDefaultSkin(); - } - - // set the callback to update the joints - renderEntity.callback = idEntity::ModelCallback; - - animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); - animator.GetBounds( gameLocal.time, renderEntity.bounds ); - - UpdateVisuals(); -} - -/* -===================== -idAnimatedEntity::GetJointWorldTransform -===================== -*/ -bool idAnimatedEntity::GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) { - if ( !animator.GetJointTransform( jointHandle, currentTime, offset, axis ) ) { - return false; - } - - ConvertLocalToWorldTransform( offset, axis ); - return true; -} - -/* -============== -idAnimatedEntity::GetJointTransformForAnim -============== -*/ -bool idAnimatedEntity::GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int frameTime, idVec3 &offset, idMat3 &axis ) const { - const idAnim *anim; - int numJoints; - idJointMat *frame; - - anim = animator.GetAnim( animNum ); - if ( !anim ) { - assert( 0 ); - return false; - } - - numJoints = animator.NumJoints(); - if ( ( jointHandle < 0 ) || ( jointHandle >= numJoints ) ) { - assert( 0 ); - return false; - } - - frame = ( idJointMat * )_alloca16( numJoints * sizeof( idJointMat ) ); - gameEdit->ANIM_CreateAnimFrame( animator.ModelHandle(), anim->MD5Anim( 0 ), renderEntity.numJoints, frame, frameTime, animator.ModelDef()->GetVisualOffset(), animator.RemoveOrigin() ); - - offset = frame[ jointHandle ].ToVec3(); - axis = frame[ jointHandle ].ToMat3(); - - return true; -} - -/* -============== -idAnimatedEntity::AddDamageEffect - - Dammage effects track the animating impact position, spitting out particles. -============== -*/ -void idAnimatedEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) { - jointHandle_t jointNum; - idVec3 origin, dir, localDir, localOrigin, localNormal; - idMat3 axis; - - if ( !g_bloodEffects.GetBool() || renderEntity.joints == NULL ) { - return; - } - - const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false ); - if ( def == NULL ) { - return; - } - - jointNum = CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ); - if ( jointNum == INVALID_JOINT ) { - return; - } - - dir = velocity; - dir.Normalize(); - - axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis; - origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis; - - localOrigin = ( collision.c.point - origin ) * axis.Transpose(); - localNormal = collision.c.normal * axis.Transpose(); - localDir = dir * axis.Transpose(); - - AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, def, collision.c.material ); - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteShort( (int)jointNum ); - msg.WriteFloat( localOrigin[0] ); - msg.WriteFloat( localOrigin[1] ); - msg.WriteFloat( localOrigin[2] ); - msg.WriteDir( localNormal, 24 ); - msg.WriteDir( localDir, 24 ); - msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_ENTITYDEF, def->Index() ) ); - msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_MATERIAL, collision.c.material->Index() ) ); - ServerSendEvent( EVENT_ADD_DAMAGE_EFFECT, &msg, false, -1 ); - } -} - -/* -============== -idAnimatedEntity::GetDefaultSurfaceType -============== -*/ -int idAnimatedEntity::GetDefaultSurfaceType( void ) const { - return SURFTYPE_METAL; -} - -/* -============== -idAnimatedEntity::AddLocalDamageEffect -============== -*/ -void idAnimatedEntity::AddLocalDamageEffect - ( - jointHandle_t jointNum, const idVec3 &localOrigin, - const idVec3 &localNormal, const idVec3 &localDir, - const idDeclEntityDef *def, const idMaterial *collisionMaterial - ) -{ - const char *splat, *decal, *bleed, *key; - damageEffect_t *de; - idVec3 origin, dir; - idMat3 axis; - idStr surfName; - - axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis; - origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis; - - origin = origin + localOrigin * axis; - dir = localDir * axis; - - if ( !collisionMaterial || collisionMaterial->GetSurfaceType() == SURFTYPE_NONE ) - { - surfName = gameLocal.sufaceTypeNames[ GetDefaultSurfaceType() ]; - } - else - { - g_Global.GetSurfName( collisionMaterial, surfName ); - } - - // start impact sound based on material type - key = va( "snd_%s", surfName.c_str() ); - // ishtvan: Shouldn't need to play the sound here anymore, right? -/* - sound = spawnArgs.GetString( key ); - if ( *sound == '\0' ) { - sound = def->dict.GetString( key ); - } - if ( *sound != '\0' ) { - StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); - } -*/ - - // blood splats are thrown onto nearby surfaces - key = va( "mtr_splat_%s", surfName.c_str() ); - splat = spawnArgs.RandomPrefix( key, gameLocal.random ); - if ( *splat == '\0' ) { - splat = def->dict.RandomPrefix( key, gameLocal.random ); - } - if ( *splat != '\0' ) { - gameLocal.BloodSplat( origin, dir, 64.0f, splat ); - } - - // can't see wounds on the player model in single player mode - if ( !( IsType( idPlayer::Type ) && !gameLocal.isMultiplayer ) ) { - // place a wound overlay on the model - key = va( "mtr_wound_%s", surfName.c_str() ); - decal = spawnArgs.RandomPrefix( key, gameLocal.random ); - if ( *decal == '\0' ) { - decal = def->dict.RandomPrefix( key, gameLocal.random ); - } - if ( *decal != '\0' ) { - ProjectOverlay( origin, dir, 20.0f, decal ); - } - } - - // a blood spurting wound is added - key = va( "smoke_wound_%s", surfName.c_str() ); - bleed = spawnArgs.GetString( key ); - if ( *bleed == '\0' ) { - bleed = def->dict.GetString( key ); - } - if ( *bleed != '\0' ) { - de = new damageEffect_t; - de->next = this->damageEffects; - this->damageEffects = de; - - de->jointNum = jointNum; - de->localOrigin = localOrigin; - de->localNormal = localNormal; - de->type = static_cast( declManager->FindType( DECL_PARTICLE, bleed ) ); - - key = va( "smoke_chance_%s", surfName.c_str() ); - float chance; - chance = def->dict.GetFloat( va("smoke_chance_%s", surfName.c_str()), "1.0" ); - if( gameLocal.random.RandomFloat() > chance ) - de->type = NULL; - de->time = gameLocal.time; - } -} - -/* -============== -idAnimatedEntity::UpdateDamageEffects -============== -*/ -void idAnimatedEntity::UpdateDamageEffects( void ) { - damageEffect_t *de, **prev; - - // free any that have timed out - prev = &this->damageEffects; - while ( *prev ) { - de = *prev; - if ( de->time == 0 ) { // FIXME:SMOKE - *prev = de->next; - delete de; - } else { - prev = &de->next; - } - } - - if ( !g_bloodEffects.GetBool() ) { - return; - } - - // emit a particle for each bleeding wound - for ( de = this->damageEffects; de; de = de->next ) { - idVec3 origin, start; - idMat3 axis; - - animator.GetJointTransform( de->jointNum, gameLocal.time, origin, axis ); - axis *= renderEntity.axis; - origin = renderEntity.origin + origin * renderEntity.axis; - start = origin + de->localOrigin * axis; - if ( !gameLocal.smokeParticles->EmitSmoke( de->type, de->time, gameLocal.random.CRandomFloat(), start, axis ) ) { - de->time = 0; - } - } -} - -/* -================ -idAnimatedEntity::ClientReceiveEvent -================ -*/ -bool idAnimatedEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - int damageDefIndex; - int materialIndex; - jointHandle_t jointNum; - idVec3 localOrigin, localNormal, localDir; - - switch( event ) { - case EVENT_ADD_DAMAGE_EFFECT: { - jointNum = (jointHandle_t) msg.ReadShort(); - localOrigin[0] = msg.ReadFloat(); - localOrigin[1] = msg.ReadFloat(); - localOrigin[2] = msg.ReadFloat(); - localNormal = msg.ReadDir( 24 ); - localDir = msg.ReadDir( 24 ); - damageDefIndex = gameLocal.ClientRemapDecl( DECL_ENTITYDEF, msg.ReadLong() ); - materialIndex = gameLocal.ClientRemapDecl( DECL_MATERIAL, msg.ReadLong() ); - const idDeclEntityDef *damageDef = static_cast( declManager->DeclByIndex( DECL_ENTITYDEF, damageDefIndex ) ); - const idMaterial *collisionMaterial = static_cast( declManager->DeclByIndex( DECL_MATERIAL, materialIndex ) ); - AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, damageDef, collisionMaterial ); - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -================ -idAnimatedEntity::Attach -================ -*/ -void idAnimatedEntity::Attach( idEntity *ent, const char *PosName, const char *AttName ) -{ - idVec3 origin; - idMat3 axis; - jointHandle_t joint; - idStr jointName; - idAngles angleOffset, angleSubOffset(0.0f,0.0f,0.0f); - idVec3 originOffset, originSubOffset(vec3_zero); - idStr nm; - idStr ClassName; - SAttachPosition *pos; - -// New position system: - if( PosName && ((pos = GetAttachPosition(PosName)) != NULL) ) - { - joint = pos->joint; - - originOffset = pos->originOffset; - angleOffset = pos->angleOffset; - - // entity-specific offsets to a given position - // entity-specific offsets to a given position - originSubOffset = ent->spawnArgs.GetVector( va("origin_%s", PosName ) ); - angleSubOffset = ent->spawnArgs.GetAngles( va("angles_%s", PosName ) ); - } -// Old system, will be phased out - else - { - jointName = ent->spawnArgs.GetString( "joint" ); - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) - { - jointName = ent->spawnArgs.GetString("bindToJoint"); - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) - { - gameLocal.Error( "Joint '%s' not found for attaching '%s' on '%s'", jointName.c_str(), ent->GetClassname(), name.c_str() ); - } - } - - // Sparhawk's classname-specific offset system - // Will be phased out in favor of attachment positions - spawnArgs.GetString("classname", "", ClassName); - sprintf(nm, "angles_%s", ClassName.c_str()); - if(ent->spawnArgs.GetAngles(nm.c_str(), "0 0 0", angleOffset) == false) - angleOffset = ent->spawnArgs.GetAngles( "angles" ); - - sprintf(nm, "origin_%s", ClassName.c_str()); - if(ent->spawnArgs.GetVector(nm.c_str(), "0 0 0", originOffset) == false) - { - originOffset = ent->spawnArgs.GetVector( "origin" ); - } - } - - GetAttachingTransform( joint, origin, axis ); - idMat3 rotate = angleOffset.ToMat3(); - idMat3 newAxis = rotate * axis; - - // Use the local joint axis instead of the overall AI axis - if (!ent->spawnArgs.GetBool("is_attachment")) - { - // angua: don't set origin and axis for attachments added in the map - // rather than spawned dynamically, this would lead to the entity - // floating around through half of the map - ent->SetOrigin( origin + originOffset * axis + originSubOffset * newAxis ); - ent->SetAxis( angleSubOffset.ToMat3() * newAxis ); - } - - ent->BindToJoint( this, joint, true ); - ent->cinematic = cinematic; - - CAttachInfo &attach = m_Attachments.Alloc(); - attach.channel = animator.GetChannelForJoint( joint ); - attach.ent = ent; - attach.name = AttName; - attach.posName = PosName; // grayman #2603 - - // Update name->m_Attachment index mapping - int index = m_Attachments.Num() - 1; - if( AttName != NULL ) - m_AttNameMap.insert(AttNameMap::value_type(AttName, index)); -} - -/* -================ -idAnimatedEntity::GetAttachingTransform -================ -*/ -void idAnimatedEntity::GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) -{ - GetJointWorldTransform( jointHandle, gameLocal.time, offset, axis ); -} - -/* -======================== -idAnimatedEntity::ReAttachToCoords -======================== -*/ -void idAnimatedEntity::ReAttachToCoords - ( const char *AttName, idStr jointName, - const idVec3 offset, const idAngles angles ) -{ - idEntity *ent( NULL ); - idVec3 origin; - idMat3 axis, rotate, newAxis; - jointHandle_t joint; - CAttachInfo *attachment( NULL ); - - attachment = GetAttachInfo( AttName ); - if( attachment ) - ent = attachment->ent.GetEntity(); - - if( !attachment || !attachment->ent.IsValid() || !ent ) - { - // TODO: log bad attachment entity error - goto Quit; - } - - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) - { - // TODO: log error - gameLocal.Warning( "Joint '%s' not found for attaching '%s' on '%s'", jointName.c_str(), ent->GetClassname(), name.c_str() ); - goto Quit; - } - - attachment->channel = animator.GetChannelForJoint( joint ); - GetJointWorldTransform( joint, gameLocal.time, origin, axis ); - - rotate = angles.ToMat3(); - newAxis = rotate * axis; - - ent->Unbind(); - - // greebo: Note that Unbind() will invalidate the entity pointer in the attachment list - // Hence, re-assign the attachment entity pointer (the index itself is ok) - attachment->ent = ent; - - ent->SetAxis( newAxis ); - // Use the local joint axis instead of the overall AI axis - ent->SetOrigin( origin + offset * axis ); - - ent->BindToJoint( this, joint, true ); - ent->cinematic = cinematic; - - // set the spawnargs for later retrieval as well - ent->spawnArgs.Set( "joint", jointName.c_str() ); - ent->spawnArgs.SetVector( "origin", offset ); - ent->spawnArgs.SetAngles( "angles", angles ); - - attachment->posName = jointName; // grayman #2603 - -Quit: - return; -} - -/* -=============== -idAnimatedEntity::CacheAnimRates -=============== -*/ -void idAnimatedEntity::CacheAnimRates( void ) -{ - // Cache animation rates - int anims = animator.NumAnims(); - m_animRates.Clear(); - m_animRates.AssureSize(anims); - for (int i=0; iName(); - m_animRates[i] = spawnArgs.GetFloat(spawnargname, "1"); - } else - { - m_animRates[i] = 1.0f; - } - } -} - -/* -================ -idAnimatedEntity::GetJointWorldPos - -Returns the position of the joint (by joint name) in worldspace -================ -*/ -idVec3 idAnimatedEntity::GetJointWorldPos( const char *jointname ) { - idVec3 offset; - idMat3 axis; - - jointHandle_t jointnum = animator.GetJointHandle( jointname ); - if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { - gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); - } - - return offset; -} - -/* -================ -idAnimatedEntity::GetEntityFromClassClosestToJoint - -tels: Returns the entity that is nearest to the given joint, selected from all entities -that have a spawnarg "AIUse" matching AIUseType. max_dist_sqr = max_dist * max_dist -================ -*/ -idEntity* idAnimatedEntity::GetEntityFromClassClosestToJoint( const idVec3 joint_origin, const char* AIUseType, const float max_dist_sqr ) -{ - idEntity* closest = NULL; - float closest_distance = idMath::INFINITY; - - idStr aiuse = AIUseType; - aiuse = aiuse.Left(6); - - // if the selector is not "AIUSE_...", skip this step - if (aiuse != "AIUSE_") { - return NULL; - } - - // for all entities - for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - if ( ent == NULL ) { continue; } - - // does it have the proper AIUse spawnarg? - if (idStr::Cmp(ent->spawnArgs.GetString("AIUse"), AIUseType) != 0) - { - continue; - } - - //gameLocal.Warning ( " Looking at entity for AIUse spawnarg %s", tempkv->GetValue().c_str() ); - - // has the proper AIUse type, so compute distance - //gameLocal.Printf("Has %s\n", AIUseType); - - const idVec3& deb = ent->GetPhysics()->GetOrigin(); - idVec3 diff = joint_origin - deb; - - // gameLocal.Printf("Distance: %f %f %f - %f %f %f = %f %f %f\n", joint_origin.x, joint_origin.y, joint_origin.z, deb.x, deb.y, deb.z, diff.x, diff.y, diff.z); - - float distance = diff.LengthSqr(); - - //gameLocal.Printf(" Distance %f < closest %f ? < max_dist_sqr %f ?.\n", distance, closest_distance, max_dist_sqr); - - if (distance < closest_distance && distance < max_dist_sqr) - { - // use this one - //gameLocal.Printf(" Distance %f < closest %f and < max_dist_sqr %f, so will use this entity.\n", distance, closest_distance, max_dist_sqr); - closest_distance = distance; - closest = ent; - } - - // try ent - } - - return closest; -} - -/* -================ -idAnimatedEntity::GetEntityClosestToJoint - -tels: Returns the entity that is nearest to the given joint. The entitySelector is either -an entity name (like "atdm_moveable_food_apple_2" or an entity AIUSE type like "AIUSE_FOOD". - -First the code looks at the idAnimatedEntity itself for spawnargs matching the given prefix, -each entity mentioned in this spawnarg is used as the entitySelector first. -If after this round no entity could be found, we fall back to entitySelector and try again. -================ -*/ -idEntity* idAnimatedEntity::GetEntityClosestToJoint( const char* posName, const char* entitySelector, const char* prefix, const float max_dist ) { - idEntity* closest = NULL; - float closest_distance = 1000000.0f; - idVec3 joint_origin; - idMat3 joint_axis; - const float max_dist_sqr = max_dist * max_dist; - SAttachPosition *pos; - - jointHandle_t jointnum = INVALID_JOINT; - -// New position system: - if( (pos = GetAttachPosition(posName)) != NULL) { - jointnum = pos->joint; - } - if (jointnum < 0) { - gameLocal.Warning( "GetEntityClosestToJoint: Cannot find joint from attach pos %s", posName ); - return NULL; - } - if ( !GetJointWorldTransform( jointnum, gameLocal.time, joint_origin, joint_axis ) ) { - gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); - } - - // first see if the entity (the animation is running on) defines an entity - // via spawnarg: "pickup_" + "name_of_the_animation" (we get this as prefix) - - if (prefix && *prefix != 0x00) - { - const idKeyValue *kv = spawnArgs.MatchPrefix( prefix, NULL ); - while( kv ) - { - idEntity *target = gameLocal.FindEntity( kv->GetValue() ); - if (!target) { - gameLocal.Warning ( " Can't find entity by name %s, so looking for AIUSE instead.", kv->GetValue().c_str() ); - // haven't found an entity, maybe it is something like "AIUSE_FOOD"? - target = GetEntityFromClassClosestToJoint( joint_origin, kv->GetValue().c_str(), max_dist_sqr ); - } - // if we found an entity and it is not ourself: - if (target != NULL && target != this) - { - // check that it is closer than the closest match so far - idVec3 diff = joint_origin - target->GetPhysics()->GetOrigin(); - float distance = diff.LengthSqr(); - if (distance < closest_distance && distance < max_dist_sqr) { - // closer and close enough - gameLocal.Printf ( " distance %f < closest_distance %f and < max_dist_sqr %f ", distance, closest_distance, max_dist_sqr ); - closest_distance = distance; - closest = target; - } - } - // next spawnarg - kv = spawnArgs.MatchPrefix( prefix, kv ); - } - } - - if (closest == NULL) { - // couldn't find any usable entity from the the spawnargs - // so try to use the entity named in the animation - if (prefix && *prefix != 0x00) - { - gameLocal.Warning ( " Didn't find an entity from the %s spawnargs, trying %s directly.", prefix, entitySelector ); - } - closest = gameLocal.FindEntity( entitySelector ); - if (closest) { - idVec3 diff = joint_origin - closest->GetPhysics()->GetOrigin(); - float distance = diff.LengthSqr(); - if (distance > max_dist_sqr) { - // cannot use this one, too far - gameLocal.Warning ( " Direct entity %s too far away. (%f > %f).", entitySelector, distance, max_dist_sqr ); - closest = NULL; - } - } - // could not be found either or was too far away? - if (closest == NULL) { - // maybe it is a generic AIUSE class, try to find a suitable entity - gameLocal.Warning ( " Can't find entity by name %s, so looking for AIUSE class.", entitySelector ); - closest = GetEntityFromClassClosestToJoint( joint_origin, entitySelector, max_dist_sqr ); - } - } - -// gameLocal.Printf ( " End of selecting closest entity."); - - // now return the found entity or NULL - return closest; -} - -/* -================ -idAnimatedEntity::Event_GetJointHandle - -looks up the number of the specified joint. returns INVALID_JOINT if the joint is not found. -================ -*/ -void idAnimatedEntity::Event_GetJointHandle( const char *jointname ) { - - jointHandle_t jointnum = animator.GetJointHandle( jointname ); - idThread::ReturnInt( jointnum ); -} - -/* -================ -idAnimatedEntity::Event_ClearAllJoints - -removes any custom transforms on all joints -================ -*/ -void idAnimatedEntity::Event_ClearAllJoints( void ) { - animator.ClearAllJoints(); -} - -/* -================ -idAnimatedEntity::Event_ClearJoint - -removes any custom transforms on the specified joint -================ -*/ -void idAnimatedEntity::Event_ClearJoint( jointHandle_t jointnum ) { - animator.ClearJoint( jointnum ); -} - -/* -================ -idAnimatedEntity::Event_SetJointPos - -modifies the position of the joint based on the transform type -================ -*/ -void idAnimatedEntity::Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ) { - animator.SetJointPos( jointnum, transform_type, pos ); -} - -/* -================ -idAnimatedEntity::Event_SetJointAngle - -modifies the orientation of the joint based on the transform type -================ -*/ -void idAnimatedEntity::Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ) { - idMat3 mat; - - mat = angles.ToMat3(); - animator.SetJointAxis( jointnum, transform_type, mat ); -} - -/* -================ -idAnimatedEntity::Event_GetJointPos - -returns the position of the joint in worldspace -================ -*/ -void idAnimatedEntity::Event_GetJointPos( jointHandle_t jointnum ) { - idVec3 offset; - idMat3 axis; - - if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { - gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); - } - - idThread::ReturnVector( offset ); -} - -/* -================ -idAnimatedEntity::Event_GetJointAngle - -returns the orientation of the joint in worldspace -================ -*/ -void idAnimatedEntity::Event_GetJointAngle( jointHandle_t jointnum ) { - idVec3 offset; - idMat3 axis; - - if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) { - gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); - } - - idAngles ang = axis.ToAngles(); - idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); - idThread::ReturnVector( vec ); -} - -/* -=============================================================================== - - End of idAnimatedEntity - -=============================================================================== -*/ - -void idEntity::Flinderize( idEntity *activator ) -{ - // Create a new struct - FlinderSpawn fs; - // count of entities that were actually spawned - int spawned = 0; - - // tels: go through all the def_flinder spawnargs and call SpawnFlinder() for each - const idKeyValue *kv = spawnArgs.MatchPrefix( "def_flinder", NULL ); - while( kv ) - { - idStr temp = kv->GetValue(); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Loading def_flinder %s:\r", temp.c_str() ); - if( !temp.IsEmpty() ) - { - // fill in the name and some defaults - fs.m_Entity = temp; - fs.m_Offset.Zero(); - fs.m_Count = 0; - fs.m_Probability = 1.0; - - // check if we have spawnargs like count, offset or probability: - idStr index; - idStr spawnarg = kv->GetKey(); - // strlen("def_flinder") == 11 - if (spawnarg.Length() > 11) - { - index = spawnarg.Right( spawnarg.Length() - 11 ); - } - // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Index is %s:\r", index.c_str() ); - spawnArgs.GetVector("flinder_offset" + index, "", fs.m_Offset); - spawnArgs.GetInt ("flinder_count" + index, "1", fs.m_Count); - spawnArgs.GetFloat ("flinder_probability" + index, "1.0", fs.m_Probability); - - // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Offset is %f,%f,%f:\r", fs.m_Offset.x, fs.m_Offset.y, fs.m_Offset.z ); - // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Count is %i:\r", fs.m_Count ); - // DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING(" Probability is %f:\r", fs.m_Probability ); - // evaluate what we found and spawn the individual pieces - spawned += SpawnFlinder( fs, activator ); - - } - kv = spawnArgs.MatchPrefix( "def_flinder", kv ); - } // while MatchPrefix ("def_flinder") - - // if we spawned flinders, but have no broken model, remove this entity - if ( spawned > 0 && !brokenModel.Length() ) - { - Hide(); - // remove us in 0.01 seconds - PostEventMS( &EV_Remove, 10 ); - // and make inactive in the meantime - BecomeInactive(TH_PHYSICS|TH_THINK); - } -} - -void idEntity::LoadTDMSettings(void) -{ - idStr str; - - // If an item has the frobable flag set to true we will use the - // the default value. If the frobdistance is set in the item - // it will override the defaultsetting. If none of that is set - // the frobdistance will be set to 0 meaning no frobbing on that item. - // If the frobsetting is alread initialized we can skip this. - if(m_FrobDistance == 0) - { - spawnArgs.GetBool("frobable", "0", m_bFrobable); - spawnArgs.GetBool("frob_simple", "0", m_bFrobSimple); - spawnArgs.GetInt("frob_distance", "0", m_FrobDistance); - spawnArgs.GetFloat("frob_bias", "1.0", m_FrobBias); - - if( m_FrobDistance <= 0 ) - m_FrobDistance = cv_frob_distance_default.GetInteger(); - - if( m_bFrobable && m_FrobBox ) - m_FrobBox->SetContents(CONTENTS_FROBABLE); - } - - // update the max frobdistance if necessary - if( m_FrobDistance > g_Global.m_MaxFrobDistance ) - g_Global.m_MaxFrobDistance = m_FrobDistance; - - // Override the frob action script to apply custom events to - // specific entities. - if(spawnArgs.GetString("frob_action_script", "", str)) - m_FrobActionScript = str; - - // Check if this entity is associated to a master frob entity. - str = spawnArgs.GetString("frob_master"); - - // Disallow "self" to be added as same name - if (!str.IsEmpty() && str != name) - { - m_MasterFrob = str; - } - - const idKeyValue *kv = spawnArgs.MatchPrefix( "frob_peer", NULL ); - // Fill the list of frob peers - while( kv ) - { - idStr temp = kv->GetValue(); - if( !temp.IsEmpty() ) - m_FrobPeers.AddUnique(temp); - kv = spawnArgs.MatchPrefix( "frob_peer", kv ); - } - - // Check if this entity can be used by others. - for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by", kv)) - { - // argh, backwards compatibility, must keep old used_by format for used_by_name - // explicitly ignore stuff with other prefixes - idStr kn = kv->GetKey(); - if( !kn.IcmpPrefix("used_by_inv_name") || !kn.IcmpPrefix("used_by_category") || !kn.IcmpPrefix("used_by_classname") ) - continue; - - // Add each entity name to the list - m_UsedByName.AddUnique(kv->GetValue()); - } - for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_inv_name"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_inv_name", kv)) - { - m_UsedByInvName.AddUnique(kv->GetValue()); - } - for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_category"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_category", kv)) - { - m_UsedByCategory.AddUnique(kv->GetValue()); - } - for (const idKeyValue* kv = spawnArgs.MatchPrefix("used_by_classname"); kv != NULL; kv = spawnArgs.MatchPrefix("used_by_classname", kv)) - { - m_UsedByClassname.AddUnique(kv->GetValue()); - } - - m_AbsenceNoticeability = spawnArgs.GetFloat("absence_noticeability", "0"); - - team = spawnArgs.GetInt("team", "-1"); - - m_bAttachedAlertControlsSolidity = spawnArgs.GetBool("on_attach_alert_become_solid"); - - m_bIsObjective = spawnArgs.GetBool( "objective_ent", "0" ); - - m_bIsClimbableRope = spawnArgs.GetBool( "is_climbable_rope", "0" ); - - m_bIsMantleable = spawnArgs.GetBool( "is_mantleable", "1" ); - - DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("[%s] this: %08lX FrobDistance: %u\r", name.c_str(), this, m_FrobDistance); -} - -void idEntity::UpdateFrobState() -{ - // hidden objects are skipped - if (IsHidden()) - { - return; - } - - // greebo: Allow the grabbed entity to stay highlighted - if (cv_dragged_item_highlight.GetBool() && gameLocal.m_Grabber->GetSelected() == this) - { - SetFrobHighlightState(true); - return; - } - - if( !m_bFrobbed ) - { - // The m_bFrobbed variable is FALSE, hence the player is not looking at this entity - // or any of its peers. Check if we need to change our state. - if (m_bFrobHighlightState) - { - // stop highlight - SetFrobHighlightState(false); - } - - // Done, we're not frobbed, frobhighlight state is cleared - return; - } - - // The player is looking at this entity, clear m_bFrobbed for the next frame - m_bFrobbed = false; - - // Change the highlight state to TRUE - SetFrobHighlightState(true); -} - -void idEntity::SetFrobHighlightState(bool newState) -{ - if (m_bFrobHighlightState == newState) return; // Avoid unnecessary work - - // The incoming state is differing from our current one, save the timestamp - m_FrobChangeTime = gameLocal.time; - - // Update the boolean, the UpdateFrobDisplay() routine will pick it up - m_bFrobHighlightState = newState; - - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("Entity [%s] is highlighted\r", name.c_str()); -} - -void idEntity::UpdateFrobDisplay() -{ - // FIX: If we have just been set not frobable, go instantly to un-frobbed hilight state - if (!m_bFrobable) - { - m_FrobChangeTime = gameLocal.time; - SetShaderParm(FROB_SHADERPARM, 0.0f); - return; - } - - float param = renderEntity.shaderParms[ FROB_SHADERPARM ]; - - if ( (param == 0 && !m_bFrobHighlightState) || (param >= 1.0f && m_bFrobHighlightState) ) - { - // Nothing to do - return; - } - - float timePassed = static_cast(gameLocal.time - m_FrobChangeTime); - - if( m_bFrobHighlightState ) - { - param += timePassed / cv_frob_fadetime.GetFloat(); - } - else - { - param -= timePassed / cv_frob_fadetime.GetFloat(); - } - - m_FrobChangeTime = gameLocal.time; - - // clamp between 0 and 1 - param = idMath::ClampFloat(0.0, 1.0f, param); - - SetShaderParm(FROB_SHADERPARM, param); -} - -void idEntity::FrobAction(bool frobMaster, bool isFrobPeerAction) -{ - if (m_FrobActionLock) return; // prevent double-entering this function - - if (IsHidden()) return; // don't do frobactions on hidden entities - - m_FrobActionLock = true; - - // greebo: If we have a frob master, just redirect the call and skip everything else - idEntity* master = GetFrobMaster(); - - if (master != NULL) - { - master->FrobAction(frobMaster, isFrobPeerAction); - - m_FrobActionLock = false; - return; - } - - // Propagate frobactions to all peers to get them triggered as well. - if (!isFrobPeerAction) - { - for (int i = 0; i < m_FrobPeers.Num(); i++) - { - idEntity* ent = gameLocal.FindEntity(m_FrobPeers[i]); - - if (ent != NULL && ent != this) - { - // Propagate the frob action, but inhibit calls to frob_masters - ent->FrobAction(false, true); - } - } - } - - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("This: [%s] Master: %08lX (%u)\r", name.c_str(), m_MasterFrob.c_str(), frobMaster); - - // Call the frob action script, if available - if (m_FrobActionScript.Length() > 0) - { - idThread* thread = CallScriptFunctionArgs(m_FrobActionScript, true, 0, "e", this); - - if (thread != NULL) - { - // greebo: Run the thread at once, the script result might be needed below. - thread->Execute(); - } - } - else - { - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("(%08lX->[%s]) FrobAction has been triggered with empty FrobActionScript!\r", this, name.c_str()); - } - - // Play the (optional) acquire sound (greebo: What's this? Isn't this the wrong place here?) - StartSound( "snd_acquire", SND_CHANNEL_ANY, 0, false, NULL ); - - m_FrobActionLock = false; -} - -void idEntity::AttackAction(idPlayer* player) -{ - idEntity* master = GetFrobMaster(); - - if (master != NULL) - { - master->AttackAction(player); - } -} - -bool idEntity::CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse) -{ - if (item == NULL) return false; - - // Redirect the call to the master if we have one - idEntity* master = GetFrobMaster(); - if( master != NULL ) - return master->CanBeUsedBy(item, isFrobUse); - - // No frob master set - // Check entity name (if exists), inv_name, inv_category, and classname - bool bMatchName( false ), bMatchInvName( false ); - bool bMatchCategory( false ), bMatchClassname( false ); - - idEntity* ent = item->GetItemEntity(); - if( ent != NULL ) - { - bMatchName = ( m_UsedByName.FindIndex(ent->name) != -1 ); - bMatchClassname = ( m_UsedByClassname.FindIndex(ent->GetEntityDefName()) != -1 ); - } - if( bMatchName || bMatchClassname ) - return true; - - bMatchInvName = ( m_UsedByInvName.FindIndex(item->GetName()) != -1 ); - bMatchCategory = ( m_UsedByCategory.FindIndex(item->Category()->GetName()) != -1 ); - - return (bMatchInvName || bMatchCategory); -} - -bool idEntity::CanBeUsedBy(idEntity* entity, const bool isFrobUse) -{ - if (entity == NULL) return false; - - // Redirect the call to the master if we have one - idEntity* master = GetFrobMaster(); - - if (master != NULL) - return master->CanBeUsedBy(entity, isFrobUse); - - // No frob master set - // Check entity name, inv_name, inv_category, and classname - bool bMatchName( false ), bMatchInvName( false ); - bool bMatchCategory( false ), bMatchClassname( false ); - - bMatchName = ( m_UsedByName.FindIndex(entity->name) != -1 ); - bMatchClassname = ( m_UsedByClassname.FindIndex(entity->GetEntityDefName()) != -1 ); - - if( bMatchName || bMatchClassname ) - return true; - - // Tels: TODO: Try here also English names instead of "#str_12345" -// gameLocal.Printf("canUsedBy name %s category %s\n", -// entity->spawnArgs.GetString("inv_name"), -// entity->spawnArgs.GetString("inv_category") ); - - // This may be called when the entity is not in the inventory, so have to read from spawnargs - bMatchInvName = ( m_UsedByInvName.FindIndex(entity->spawnArgs.GetString("inv_name")) != -1 ); - bMatchCategory = ( m_UsedByCategory.FindIndex(entity->spawnArgs.GetString("inv_category")) != -1 ); - - return (bMatchInvName || bMatchCategory); -} - -bool idEntity::UseBy(EImpulseState impulseState, const CInventoryItemPtr& item) -{ - // Redirect the call to the master if we have one - idEntity* master = GetFrobMaster(); - - if (master != NULL) - return master->UseBy(impulseState, item); - - // no master, continue... - // Ishtvan: Call used_by script. First check for scripts with the specific name/inv_name/classname/category/ - // only call the most-specific script - idStrList suffixes; - idEntity *ent = item->GetItemEntity(); - if( ent != NULL ) - { - suffixes.Append( ent->name ); - suffixes.Append( ent->GetEntityDefName() ); - } - // inv_name comes before classname - suffixes.Insert( item->GetName(), 1 ); - suffixes.Append( item->Category()->GetName() ); - - idThread* thread = NULL; - bool bFoundKey = false; - for( int i=0; i < suffixes.Num(); i++ ) - { - idStr scriptName = "used_action_script_" + suffixes[i]; - const idKeyValue *kv = spawnArgs.FindKey( scriptName.c_str() ); - if( kv != NULL && kv->GetValue().Length() > 0 ) - { - idThread* thread = CallScriptFunctionArgs(kv->GetValue().c_str(), true, 0, "e", this); - bFoundKey = true; - break; - } - } - - // if we didn't find a specific suffix, use "used_action_script" by itself - if( !bFoundKey ) - { - const idKeyValue *kv = spawnArgs.FindKey( "used_action_script" ); - if( kv != NULL && kv->GetValue().Length() > 0 ) - { - idThread* thread = CallScriptFunctionArgs(kv->GetValue().c_str(), true, 0, "e", this); - } - } - - if (thread != NULL) - { - // greebo: Run the thread at once, the script result might be needed below. - thread->Execute(); - return true; - } - - return false; -} - -void idEntity::SetFrobbed( bool val ) -{ - if (m_bFrobbed == val) return; // avoid loopbacks and unnecessary work - - m_bFrobbed = val; - - // resolve the peer names into entities - for (int i = 0; i < m_FrobPeers.Num(); i++) - { - if (m_FrobPeers[i].Length() == 0) continue; - - idEntity* ent = gameLocal.FindEntity(m_FrobPeers[i]); - - // don't call it on self, would get stuck in a loop - if (ent != NULL && ent != this) - { - ent->SetFrobbed(m_bFrobbed); - } - } -} - -bool idEntity::IsFrobbed( void ) -{ - return m_bFrobbed; -} - -void idEntity::SetFrobable( bool bVal ) -{ - // greebo: This is to avoid infinite loops - if (m_bFrobable == bVal) return; - - m_bFrobable = bVal; - - // If this entity is currently being hilighted, make sure to un-frob it - if( !bVal ) - { - SetFrobbed(false); - SetFrobHighlightState(false); - if( m_FrobBox ) - m_FrobBox->SetContents(0); - } - else - { - if( m_FrobBox ) - m_FrobBox->SetContents(CONTENTS_FROBABLE); - } - - UpdateFrobState(); - UpdateFrobDisplay(); - - // Make sure Present gets called when we make something frobable - BecomeActive( TH_UPDATEVISUALS ); - - // greebo: Also update all frob peers - for (int i = 0; i < m_FrobPeers.Num(); i++) - { - idEntity* peer = gameLocal.FindEntity(m_FrobPeers[i]); - if (peer == NULL) continue; - - peer->SetFrobable(bVal); - } -} - -void idEntity::Event_StimAdd(int stimType, float radius) -{ - AddStim(static_cast(stimType), radius); -} - -void idEntity::Event_StimRemove(int stimType) -{ - RemoveStim(static_cast(stimType)); -} - -void idEntity::Event_StimEnable(int stimType, int enabled) -{ - SetStimEnabled(static_cast(stimType), enabled != 0); -} - -void idEntity::Event_StimClearIgnoreList(int stimType) -{ - ClearStimIgnoreList(static_cast(stimType)); -} - -void idEntity::Event_ResponseEnable(int stimType, int enabled) -{ - SetResponseEnabled(static_cast(stimType), enabled != 0); -} - -void idEntity::Event_ResponseAdd(int stimType) -{ - AddResponse(static_cast(stimType)); -} - -void idEntity::Event_ResponseTrigger(idEntity* source, int stimType) -{ - TriggerResponse(source, static_cast(stimType)); -} - -void idEntity::Event_ResponseRemove(int stimType) -{ - RemoveResponse(static_cast(stimType)); -} - -void idEntity::Event_ResponseIgnore(int stimType, idEntity *e) -{ - IgnoreResponse(static_cast(stimType), e); -} - -void idEntity::Event_ResponseAllow(int stimType, idEntity *e) -{ - AllowResponse(static_cast(stimType), e); -} - -void idEntity::Event_ResponseSetAction(int stimType, const char* action) -{ - CResponsePtr resp = m_StimResponseColl->GetResponseByType(static_cast(stimType)); - - if (resp != NULL) - { - resp->SetResponseAction(action); - } -} - -void idEntity::AllowResponse(StimType type, idEntity* fromEntity) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(type); - - if (stim != NULL) - { - stim->RemoveResponseIgnore(fromEntity); - } -} - -void idEntity::IgnoreResponse(StimType type, idEntity* fromEntity) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(type); - - if (stim != NULL) - { - stim->AddResponseIgnore(fromEntity); - } -} - -// grayman #2872 - -bool idEntity::CheckResponseIgnore(StimType type, idEntity* fromEntity) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(type); - - if (stim != NULL) - { - return ( stim->CheckResponseIgnore(fromEntity) ); - } - return true; -} - - -void idEntity::SetStimEnabled(StimType type, bool enabled) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(type); - - if (stim != NULL) - { - stim->SetEnabled(enabled); - } -} - -void idEntity::SetResponseEnabled(StimType type, bool enabled) -{ - CResponsePtr response = m_StimResponseColl->GetResponseByType(type); - - if (response != NULL) - { - response->SetEnabled(enabled); - } -} - -void idEntity::ClearStimIgnoreList(StimType type) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(type); - - if (stim != NULL) - { - stim->ClearResponseIgnoreList(); - } -} - -void idEntity::RemoveStim(StimType type) -{ - if (m_StimResponseColl->RemoveStim(type) == 0) - { - gameLocal.RemoveStim(this); - } -} - -void idEntity::RemoveResponse(StimType type) -{ - if (m_StimResponseColl->RemoveResponse(type) == 0) - { - gameLocal.RemoveResponse(this); - } -} - -CStimPtr idEntity::AddStim(StimType type, float radius, bool removable, bool isDefault) -{ - CStimPtr stim = m_StimResponseColl->AddStim(this, type, radius, removable, isDefault); - - gameLocal.AddStim(this); - - return stim; -} - -CResponsePtr idEntity::AddResponse(StimType type, bool removable, bool isDefault) -{ - CResponsePtr response = m_StimResponseColl->AddResponse(this, type, removable, isDefault); - - gameLocal.AddResponse(this); - - return response; -} - -void idEntity::TriggerResponse(idEntity* source, StimType type) -{ - // Try to lookup the response for this item - CResponsePtr resp = GetStimResponseCollection()->GetResponseByType(type); - - if (resp == NULL || resp->m_State != SS_ENABLED) - { - return; - } - - // There is an enabled response defined - // Check duration, disable if past duration - if (resp->m_Duration && (gameLocal.time - resp->m_EnabledTimeStamp) > resp->m_Duration) - { - resp->Disable(); - } - else - { - // Fire the response and pass the originating entity and no stim object - // no stim means that this is no "real" stim just a temporary or virtual one - resp->TriggerResponse(source); - } -} - - -/** Called when m_renderTrigger is rendered. - * It will resume the m_renderWaitingThread. - */ -bool idEntity::WaitForRenderTriggered( renderEntity_s* renderEntity, const renderView_s* view ) -{ - // NOTE: We must avoid changing the game state from within this function. - // However, we'll add an event to resume the suspended thread. - - idEntity* ent = gameLocal.entities[ renderEntity->entityNum ]; - if ( !ent ) - gameLocal.Error( "idEntity::WaitForRenderTriggered: callback with NULL game entity" ); - - renderEntity->callback = NULL; - - if ( ent->m_renderWaitingThread ) - { - // Fortunately, this doesn't execute the script immediately, so - // I think it's safe to call from here. - idThread::ObjectMoveDone( ent->m_renderWaitingThread, ent ); - ent->m_renderWaitingThread = 0; - } - - return false; -} - -/** Called to update m_renderTrigger after the render entity is modified. - * Only updates the render trigger if a thread is waiting for it. - */ -void idEntity::PresentRenderTrigger() -{ - if ( !m_renderWaitingThread ) - { - goto Quit; - } - - // Update the renderTrigger to match renderEntity's bounding box. - // In order to ensure that other code can easily add to the bounding - // box, we're going to pre-rotate the bounding box, and keep the axis - // unrotated. - m_renderTrigger.origin = renderEntity.origin; - m_renderTrigger.bounds = renderEntity.bounds * renderEntity.axis; - // I haven't yet figured out where renderEntity.entityNum is set... - // but it looks like we have to manually set it for m_renderTrigger. - m_renderTrigger.entityNum = entityNumber; - - // Update the renderTrigger in the render world. - if ( m_renderTriggerHandle == -1 ) - m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); - else - gameRenderWorld->UpdateEntityDef( m_renderTriggerHandle, &m_renderTrigger ); - - Quit: - return; -} - -/* -================ -idEntity::Inventory - -This returns the inventory object of this entity. If this entity doesn't -have one, it creates the inventory. -================ -*/ -const CInventoryPtr& idEntity::Inventory() -{ - if (m_Inventory == NULL ) - { - m_Inventory = CInventoryPtr(new CInventory()); - m_Inventory->SetOwner(this); - } - - return m_Inventory; -} - -/* -================ -idEntity::InventoryCursor - -This returns the inventory cursor object of this entity. If this entity -doesn't have one, it creates the inventory cursor. - -The cursor is intended for arbitrary use, and need not point to this -entity's inventory. -================ -*/ -const CInventoryCursorPtr& idEntity::InventoryCursor() -{ - if (m_InventoryCursor == NULL) - { - m_InventoryCursor = Inventory()->CreateCursor(); - } - - return m_InventoryCursor; -} - -void idEntity::OnAddToLocationEntity(CObjectiveLocation* locationEnt) -{ - idEntityPtr locationEntPtr; - locationEntPtr = locationEnt; - - // Ensure that objective locations don't add themselves twice or more times - // Tels: The assert below triggers under Debug build when loading Heart, took - // it out since it will be ignored under Release builds anyway - //assert(m_objLocations.FindIndex(locationEntPtr) == -1); - if (m_objLocations.FindIndex(locationEntPtr) != -1) - { - return; - } - - m_objLocations.Alloc() = locationEntPtr; -} - -void idEntity::OnRemoveFromLocationEntity(CObjectiveLocation* locationEnt) -{ - idEntityPtr locationEntPtr; - locationEntPtr = locationEnt; - - // Ensure that only registered location ents are removed - assert(m_objLocations.FindIndex(locationEntPtr) != -1); - - m_objLocations.Remove(locationEntPtr); -} - -void idEntity::Event_PropSound( const char *sndName ) -{ - PropSoundDirect( sndName, false, false, 0.0f ); -} - -void idEntity::Event_PropSoundMod( const char *sndName, float VolModIn ) -{ - PropSoundDirect( sndName, false, false, VolModIn ); -} - -/* -================ -idEntity::Event_InPVS - -Returns non-zero if this entity is in the player's PVS, zero otherwise. -================ -*/ -void idEntity::Event_InPVS() -{ - idThread::ReturnFloat( gameLocal.InPlayerPVS( this ) ); -} - -/* -================ -idEntity::Event_WaitForRender - -Called by sys.waitForRender(ent) to find out if it can wait for this entity to render. -================ -*/ -void idEntity::Event_WaitForRender() -{ - if ( !m_renderWaitingThread ) - { - // Give the renderTrigger an invisible model to prevent a black cube from showing up. - if ( !m_renderTrigger.hModel ) - m_renderTrigger.hModel = renderModelManager->FindModel( cv_empty_model.GetString() ); - if ( !m_renderTrigger.hModel ) - gameLocal.Error( "Unable to load model: %s\n", cv_empty_model.GetString() ); - - m_renderTrigger.callback = idEntity::WaitForRenderTriggered; - m_renderWaitingThread = idThread::CurrentThreadNum(); - - // Make sure Present() gets called. - BecomeActive( TH_UPDATEVISUALS ); - - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/* -================ -idEntity::Event_SetGui - -Changes the GUI file that's loaded by an overlay. Overlays 1, 2 and 3 are -reserved for the entity GUIs, and special code is implemented to change them. -A changed GUI does not see gui_parm spawn args. (for one thing, if there's a -script changing GUIs, then the script could easily send spawnargs to the GUI -if it wanted to.) -================ -*/ -void idEntity::Event_SetGui( int handle, const char *guiFile ) { - if ( !uiManager->CheckGui(guiFile) ) { - gameLocal.Warning( "Unable to load GUI file: %s\n", guiFile ); - goto Quit; - } - - if ( !m_overlays.exists( handle ) ) { - gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); - goto Quit; - } - - // Entity GUIs are handled differently from regular ones. - if ( handle >= 1 && handle <= MAX_RENDERENTITY_GUI ) { - - assert( m_overlays.isExternal( handle ) ); - - if ( renderEntity.gui[ handle-1 ] && renderEntity.gui[ handle-1 ]->IsUniqued() ) { - - // We're dealing with an existing unique GUI. - // We need to read a new GUI into it. - - // Clear the state. - const idDict &state = renderEntity.gui[ handle-1 ]->State(); - const idKeyValue *kv; - while ( ( kv = state.MatchPrefix( "" ) ) != NULL ) - renderEntity.gui[ handle-1 ]->DeleteStateVar( kv->GetKey() ); - - renderEntity.gui[ handle-1 ]->InitFromFile( guiFile ); - - } else { - - // We're either dealing with a non-existant GUI, or a non-unique one. - // It's safe to just set the render entity to point to a new GUI without - // bothering to deallocate the previous GUI. - renderEntity.gui[ handle-1 ] = uiManager->FindGui( guiFile, true, true ); - m_overlays.setGui( handle, renderEntity.gui[ handle - 1 ] ); - assert( renderEntity.gui[ handle-1 ] ); - - } - - } else if ( !m_overlays.isExternal( handle ) ) { - - bool result = m_overlays.setGui( handle, guiFile ); - assert( result ); - - } else { - gameLocal.Warning( "Cannot call setGui() on external handle: %d\n", handle ); - } - - Quit: - return; -} - -/* -================ -idEntity::Event_GetGui - -Returns the file loaded by a specific GUI. -================ -*/ -void idEntity::Event_GetGui( int handle ) { - idUserInterface *gui = m_overlays.getGui( handle ); - if ( gui ) - idThread::ReturnString( gui->Name() ); - else - idThread::ReturnString( "" ); -} - -void idEntity::SetGuiString(int handle, const char *key, const char *val) -{ - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui(handle); - if(gui == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - goto Quit; - } - - if(!gui->IsUniqued()) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); - goto Quit; - } - - gui->SetStateString(key, val); - gui->StateChanged(gameLocal.time); - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); - } - -Quit: - return; -} - -/* -================ -idEntity::Event_SetGuiString - -Sets a parameter for a GUI. (note that the GUI needs to be unique) -================ -*/ -void idEntity::Event_SetGuiString(int handle, const char *key, const char *val) -{ - SetGuiString(handle, key, val); -} - -const char *idEntity::GetGuiString(int handle, const char *key) -{ - const char *retStr = NULL; - - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui(handle); - if(gui) - retStr = gui->GetStateString(key); - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - - return retStr; -} - -void idEntity::Event_GetGuiString(int handle, const char *key) -{ - const char *retStr = GetGuiString(handle, key); - - if(retStr == NULL) - retStr = ""; - - idThread::ReturnString(retStr); -} - -void idEntity::SetGuiFloat( int handle, const char *key, float f) -{ - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui(handle); - if(gui == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - goto Quit; - } - - if(!gui->IsUniqued()) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); - goto Quit; - } - - gui->SetStateFloat(key, f); - gui->StateChanged(gameLocal.time); - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); - -Quit: - return; -} - -void idEntity::Event_SetGuiFloat(int handle, const char *key, float f) -{ - SetGuiFloat(handle, key, f); -} - -float idEntity::GetGuiFloat(int handle, const char *key) -{ - float retVal = 0; - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui( handle ); - if (gui) - retVal = gui->GetStateFloat(key); - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); - - return retVal; -} - -void idEntity::Event_GetGuiFloat(int handle, const char *key) -{ - idThread::ReturnFloat(GetGuiFloat(handle, key)); -} - -void idEntity::SetGuiInt( int handle, const char *key, int n) -{ - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui(handle); - if(gui == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - goto Quit; - } - - if(!gui->IsUniqued()) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, key); - goto Quit; - } - - gui->SetStateInt(key, n); - gui->StateChanged(gameLocal.time); - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); - -Quit: - return; -} - -void idEntity::Event_SetGuiInt(int handle, const char *key, int n) -{ - SetGuiInt(handle, key, n); -} - -int idEntity::GetGuiInt(int handle, const char *key) -{ - int retVal = 0; - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui(handle); - if (gui) - retVal = gui->GetStateInt(key); - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - } - else - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d\r", handle); - - return retVal; -} - -void idEntity::Event_GetGuiInt(int handle, const char *key) -{ - idThread::ReturnInt(GetGuiInt(handle, key)); -} - -/* -================ -idEntity::Event_SetGuiStringFromKey - -This is a kludge. It's hopefully temporary, but probably not. Anyway, it's -used by readables to bypass the 127 char limit on string variables in scripts. -================ -*/ -void idEntity::Event_SetGuiStringFromKey( int handle, const char *key, idEntity *src, const char *spawnArg ) -{ - if(!src) - { - gameLocal.Warning( "Unable to get key, since the source entity was NULL.\n" ); - return; - } - - if(!m_overlays.exists(handle)) - { - gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); - return; - } - - idUserInterface *gui = m_overlays.getGui( handle ); - if(!gui) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, key); - return; - } - - if(!gui->IsUniqued()) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Non-existant GUI handle: %d\r", handle); - return; - } - - gui->SetStateString( key, gameLocal.m_I18N->Translate( src->spawnArgs.GetString( spawnArg, "" ) ) ); - gui->StateChanged( gameLocal.time ); -} - -void idEntity::CallGui(int handle, const char *namedEvent) -{ - if(m_overlays.exists(handle)) - { - idUserInterface *gui = m_overlays.getGui( handle ); - if(gui == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Handle points to NULL GUI: %d [%s]\r", handle, namedEvent); - return; - } - - if(!gui->IsUniqued()) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("GUI is not unique. Handle: %d [%s]\r", handle, namedEvent); - return; - } - - gui->HandleNamedEvent( namedEvent ); - } - else - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("setGui: Non-existant GUI handle: %d [%s]\r", handle, namedEvent); - } - -} - -/* -================ -idEntity::Event_CallGui - -Calls a named event in a GUI. (note that the GUI needs to be unique) -================ -*/ -void idEntity::Event_CallGui(int handle, const char *namedEvent) -{ - CallGui(handle, namedEvent); -} - -/* -================ -idEntity::Event_LoadExternalData - -Used to load an external xdata declaration into this -object's spawn args. The prefix will be prepended to -the names of all keys in the declaration. -================ -*/ -void idEntity::Event_LoadExternalData( const char *xdFile, const char* prefix ) -{ - const tdmDeclXData *xd = static_cast< const tdmDeclXData* >( declManager->FindType( DECL_XDATA, xdFile, false ) ); - if ( xd != NULL ) { - const idDict *data = &(xd->m_data); - const idKeyValue *kv; - - int i = data->GetNumKeyVals(); - while ( i-- ) { - kv = data->GetKeyVal(i); - spawnArgs.Set( prefix + kv->GetKey(), kv->GetValue() ); - } - - idThread::ReturnInt( 1 ); - } - else - { - gameLocal.Warning("Non-existant xdata declaration: %s\n", xdFile); - idThread::ReturnInt( 0 ); - } -} - -/* -================ -idEntity::Event_GetInventory - -Returns the entity containing us. -================ -*/ -void idEntity::Event_GetInventory() -{ -/* CInventoryItem* item = InventoryItem(); - if ( item != NULL ) { - CInventory* inv = item->Inventory(); - if ( inv != NULL ) { - idThread::ReturnEntity( inv->m_owner.GetEntity() ); - } else { - idThread::ReturnEntity( NULL ); - } - } -*/ -} - -idThread *idEntity::CallScriptFunctionArgs(const char *fkt, bool ClearStack, int delay, const char *fmt, ...) -{ - idThread *pThread = NULL; - va_list argptr; - - const function_t *pScriptFkt = scriptObject.GetFunction(fkt); - if(pScriptFkt == NULL) - { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Action: %s not found in local space, checking for global namespace.\r", fkt); - pScriptFkt = gameLocal.program.FindFunction(fkt); - } - - if(pScriptFkt) - { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Running scriptfunction '%s'\r", fkt); - pThread = new idThread(pScriptFkt); - va_start(argptr, fmt); - pThread->CallFunctionArgsVN(pScriptFkt, ClearStack, fmt, argptr); - va_end(argptr); - pThread->DelayedStart(delay); - } - else - DM_LOG(LC_MISC, LT_ERROR)LOGSTRING("Scriptfunction not found! [%s]\r", fkt); - - return pThread; -} - -void idEntity::Attach( idEntity *ent, const char *PosName, const char *AttName ) -{ - idVec3 origin; - idMat3 axis; - idAngles angleOffset, angleSubOffset(0.0f,0.0f,0.0f); - idVec3 originOffset, originSubOffset(vec3_zero); - SAttachPosition *pos; - -// New position system: - if( PosName && ((pos = GetAttachPosition(PosName)) != NULL) ) - { - originOffset = pos->originOffset; - angleOffset = pos->angleOffset; - - // entity-specific offsets to a given position - originSubOffset = ent->spawnArgs.GetVector( va("origin_%s", PosName ) ); - angleSubOffset = ent->spawnArgs.GetAngles( va("angles_%s", PosName ) ); - } -// The following is the old system and will be phased out - else - { - //gameLocal.Warning("%s is attaching %s using the deprecated attachment system.\n", name.c_str(), ent->name.c_str()); - angleOffset = ent->spawnArgs.GetAngles( "angles" ); - originOffset = ent->spawnArgs.GetVector( "origin" ); - } - - origin = GetPhysics()->GetOrigin(); - axis = GetPhysics()->GetAxis(); - - idMat3 rotate = angleOffset.ToMat3(); - idMat3 newAxis = rotate * axis; - ent->SetOrigin( origin + originOffset * axis + originSubOffset * newAxis ); - ent->SetAxis( angleSubOffset.ToMat3() * newAxis ); - ent->Bind( this, true ); - ent->cinematic = cinematic; - - CAttachInfo &attach = m_Attachments.Alloc(); - attach.channel = 0; // overloaded in animated classes - attach.ent = ent; - attach.name = AttName; - idStr positionString = PosName; - attach.posName = positionString; // grayman #2603 - - // Update name->m_Attachment index mapping - int index = m_Attachments.Num() - 1; - if( AttName != NULL ) - m_AttNameMap.insert(AttNameMap::value_type(AttName, index)); -} - -void idEntity::Detach( const char *AttName ) -{ - int ind = GetAttachmentIndex( AttName ); - if (ind >= 0 && ind < m_Attachments.Num() ) - { - DetachInd( ind ); - } - else - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Detach called with invalid attachment name %s\r", AttName); - } -} - -void idEntity::DetachInd( int ind ) -{ - idEntity *ent = NULL; - - // DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Detach called for index %d\r", ind); - if( ind < 0 || ind >= m_Attachments.Num() ) - { - // TODO: log invalid index error - goto Quit; - } - - ent = m_Attachments[ind].ent.GetEntity(); - - if( !ent || !m_Attachments[ind].ent.IsValid() ) - { - // TODO: log bad attachment entity error - goto Quit; - } - - // DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("Detach: Ent %s unbound\r", ent->name.c_str()); - ent->Unbind(); - // We don't want to remove it from the list, otherwise mapping of name to index gets screwed up - m_Attachments[ind].ent = NULL; - - // remove from name->index mapping - m_AttNameMap.erase( m_Attachments[ind].name.c_str() ); - -Quit: - return; -} - -void idEntity::ReAttachToCoords - ( const char *AttName, idVec3 offset, idAngles angles ) -{ - idEntity *ent( NULL ); - idVec3 origin; - idMat3 axis, rotate, newAxis; - CAttachInfo *attachment( NULL ); - - attachment = GetAttachInfo( AttName ); - if( attachment ) - ent = attachment->ent.GetEntity(); - - if( !attachment || !attachment->ent.IsValid() || !ent ) - { - // TODO: log bad attachment entity error - goto Quit; - } - - axis = GetPhysics()->GetAxis(); - origin = GetPhysics()->GetOrigin(); - rotate = angles.ToMat3(); - newAxis = rotate * axis; - - ent->Unbind(); - - // greebo: Note that Unbind() will invalidate the entity pointer in the attachment list - // Hence, re-assign the attachment entity pointer (the index itself is ok) - attachment->ent = ent; - - ent->SetAxis( newAxis ); - ent->SetOrigin( origin + offset * axis ); - - ent->Bind( this, true ); - ent->cinematic = cinematic; - - // set the spawnargs for later retrieval as well - ent->spawnArgs.Set( "joint", "" ); - ent->spawnArgs.SetVector( "origin", offset ); - ent->spawnArgs.SetAngles( "angles", angles ); - -Quit: - return; -} - -void idEntity::ReAttachToPos - ( const char *AttName, const char *PosName ) -{ - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ReAttachToPos called with attachment name %s, positiong %s, on entity %s\r", AttName, PosName, name.c_str()); - - int ind = GetAttachmentIndex( AttName ); - if (ind == -1 ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); - return; - } - - idEntity* ent = GetAttachment( ind ); - - if( !ent ) - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ReAttachToPos called with invalid attached entity on entity %s\r", AttName, name.c_str()); - return; - } - - // Hack: Detaching leaves a null entry in the array to preserve indices - // To leverage existing Attach function, we detach and then re-insert - // into this place in the array. - - DetachInd( ind ); - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ReAttaching...\r"); - Attach( ent, PosName, AttName ); - - int indEnd = m_Attachments.Num(); - - // greebo: Decrease the end index by 1 before passing it to operator[] - indEnd--; - - DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("End index is %d\r", indEnd); - - // Copy the attachment info from the end of the list over the previous index - m_Attachments[ind] = m_Attachments[indEnd]; - - // remove the newly created end entry (is a duplicate now) - m_Attachments.RemoveIndex( indEnd ); - - // Fix the name mapping to map back to the original index - m_AttNameMap.erase( AttName ); - m_AttNameMap.insert(AttNameMap::value_type(AttName, ind)); -} - -void idEntity::ShowAttachment( const char *AttName, bool bShow ) -{ - int ind = GetAttachmentIndex( AttName ); - if (ind >= 0 ) - { - ShowAttachmentInd( ind, bShow ); - } - else - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("ShowAttachment called with invalid attachment name %s on entity %s\r", AttName, name.c_str()); - } -} - -void idEntity::ShowAttachmentInd( int ind, bool bShow ) -{ - idEntity *ent( NULL ); - - if( ind < 0 || ind >= m_Attachments.Num() ) - { - // TODO: log invalid index error - goto Quit; - } - - ent = m_Attachments[ind].ent.GetEntity(); - - if( !ent || !m_Attachments[ind].ent.IsValid() ) - { - // TODO: log bad attachment entity error - goto Quit; - } - - if( bShow ) - ent->Show(); - else - ent->Hide(); - -Quit: - return; -} - -int idEntity::GetAttachmentIndex( const char *AttName ) -{ - AttNameMap::iterator k; - k = m_AttNameMap.find(AttName); - if (k != m_AttNameMap.end() && k->second < m_Attachments.Num() ) - { - return k->second; - } - else - { - DM_LOG(LC_AI,LT_WARNING)LOGSTRING("Attempt to access invalid attachment name %s on entity %s\r", AttName, name.c_str()); - return -1; - } -} - -idEntity *idEntity::GetAttachment( const char *AttName ) -{ - /* tels: use GetAttachmentIndex() to bypass GetAttachInfo() */ - int ind = GetAttachmentIndex(AttName); - if( ind >= 0 ) - return m_Attachments[ind].ent.GetEntity(); - else - return NULL; - - /*CAttachInfo *AttInfo = GetAttachInfo( AttName ); - - if( AttInfo ) - return AttInfo->ent.GetEntity(); - else - return NULL;*/ -} - -idEntity *idEntity::GetAttachment( int ind ) -{ - idEntity *ent = NULL; - - if( ind < 0 || ind >= m_Attachments.Num() ) - { - // TODO: log invalid index error - goto Quit; - } - - ent = m_Attachments[ind].ent.GetEntity(); - - if( !ent || !m_Attachments[ind].ent.IsValid() ) - { - // TODO: log bad attachment entity error - ent = NULL; - goto Quit; - } - -Quit: - return ent; -} - -CAttachInfo *idEntity::GetAttachInfo( const char *AttName ) -{ - int ind = GetAttachmentIndex(AttName); - if( ind >= 0 ) - return &m_Attachments[ind]; - else - return NULL; -} - -// Tels: Get the entity attached at the position given by the attachment position -// grayman #2603 - resurrected and spruced up for relight work -idEntity* idEntity::GetAttachmentByPosition( idStr PosName ) -{ - int num = m_Attachments.Num(); - - for (int i = 0 ; i < num ; i++) - { - if ((m_Attachments[i].ent.GetEntity() != NULL) && m_Attachments[i].ent.IsValid()) - { - if (m_Attachments[i].posName == PosName) - { - return m_Attachments[i].ent.GetEntity(); - } - } - } - - // not found - return NULL; -} - - -idEntity *idEntity::GetAttachmentFromTeam( const char *AttName ) -{ - /* tels: Look directly at this entity for the attachment */ - int ind = GetAttachmentIndex(AttName); - if( ind >= 0 ) - { - /* we found it */ - //gameLocal.Printf(" Found entity %s at index %i\n", m_Attachments[ind].ent.GetEntity()->name.c_str(), ind); - return m_Attachments[ind].ent.GetEntity(); - } - - /* tels: not found, look at entities bound to this entity */ - idEntity* NextEnt = this; - - if ( bindMaster ) - { - NextEnt = bindMaster; - } - - while ( NextEnt != NULL ) - { - //gameLocal.Printf(" Looking at entity %s\n", NextEnt->name.c_str()); - idEntity* AttEnt = NextEnt->GetAttachment( AttName ); - if (AttEnt) - { - /* we found it */ - //gameLocal.Printf(" Found entity %s at entity %s.\n", - // AttEnt->name.c_str(), NextEnt->name.c_str()); - return AttEnt; - } - /* not found yet, get next Team member */ - NextEnt = NextEnt->GetNextTeamEntity(); - } - - /* not found at all */ - return NULL; -} - -void idEntity::BindNotify( idEntity *ent ) -{ -} - -void idEntity::UnbindNotify( idEntity *ent ) -{ - // greebo: Activate physics on "Unbind" of any slaves - physics->Activate(); -} - -void idEntity::Event_TimerCreate(int stimType, int Hour, int Minute, int Seconds, int Millisecond) -{ - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Create Timer: Stimtype %d, Hour: %d, Minute: %d, Seconds: %d, Milliseconds: %d\r", - stimType, Hour, Minute, Seconds, Millisecond); - - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - - CStimResponseTimer* timer = stim->AddTimerToGame(); - timer->SetTimer(Hour, Minute, Seconds, Millisecond); -} - -void idEntity::Event_TimerStop(int stimType) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - CStimResponseTimer *timer = (stim != NULL) ? stim->GetTimer() : NULL; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StopTimer: Stimtype %d\r", stimType); - if (timer != NULL) - { - timer->Stop(); - } -} - -void idEntity::Event_TimerStart(int stimType) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StartTimer: Stimtype %d \r", stimType); - - if (timer != NULL) - { - timer->Start(static_cast(sys->GetClockTicks())); - } -} - -void idEntity::Event_TimerRestart(int stimType) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("RestartTimer: Stimtype %d \r", stimType); - - if (timer != NULL) - { - timer->Restart(static_cast(sys->GetClockTicks())); - } -} - -void idEntity::Event_TimerReset(int stimType) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("ResetTimer: Stimtype %d \r", stimType); - - if (timer != NULL) - { - timer->Reset(); - } -} - -void idEntity::Event_TimerSetState(int stimType, int state) -{ - CStimPtr stim = m_StimResponseColl->GetStimByType(static_cast(stimType)); - - CStimResponseTimer* timer = (stim != NULL) ? stim->GetTimer() : NULL; - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("SetTimerState: Stimtype-%d State: %d\r", stimType, state); - - if (timer != NULL) - { - timer->SetState(static_cast(state)); - } -} - -void idEntity::Event_SetFrobable(bool bVal) -{ - SetFrobable( bVal ); -} - -void idEntity::Event_IsFrobable( void ) -{ - idThread::ReturnInt( (int) m_bFrobable ); -} - -void idEntity::Event_Frob() -{ - idPlayer* player = static_cast(gameLocal.entities[gameLocal.localClientNum]); - if (player != NULL) - { - // Let the player frob this entity. - player->PerformFrob(EPressed, this); - } -} - -void idEntity::Event_IsHilighted( void ) -{ - int retVal = 0; - if ( m_bFrobHighlightState ) - retVal++; - if ( m_bFrobbed ) - retVal++; - idThread::ReturnInt( retVal ); -} - - -void idEntity::Event_FrobHilight( bool bVal ) -{ - SetFrobHighlightState( bVal ); -} - -void idEntity::Event_CheckAbsence() -{ - if (m_AbsenceNoticeability > 0) - { - idBounds currentBounds = GetPhysics()->GetAbsBounds(); - float tolerance = spawnArgs.GetFloat("absence_bounds_tolerance", "0"); - - currentBounds.ExpandSelf(tolerance); - - idEntity* location(NULL); - bool isAbsent(true); - int locationsCount(0); - - for (const idKeyValue* kv = spawnArgs.MatchPrefix("absence_location"); kv != NULL; kv = spawnArgs.MatchPrefix("absence_location", kv)) - { - locationsCount++; - location = gameLocal.FindEntity(kv->GetValue()); - if (location != NULL) - { - isAbsent = !currentBounds.IntersectsBounds(location->GetPhysics()->GetAbsBounds()); - } - if (!isAbsent) - { - break; - } - } - - if (locationsCount == 0) - { - isAbsent = !currentBounds.IntersectsBounds(m_StartBounds); - } - - if (isAbsent && !m_AbsenceStatus) - { - // was there before, is absent now - SpawnAbsenceMarker(); - } - else if (!isAbsent && m_AbsenceStatus) - { - // was absent, is back - DestroyAbsenceMarker(); - } - - // set absence status - m_AbsenceStatus = isAbsent; - - PostEventMS(&EV_CheckAbsence, 5000); - } -} - -void idEntity::Event_CanBeUsedBy( idEntity *itemEnt ) -{ - idThread::ReturnInt( CanBeUsedBy( itemEnt, true ) ); -} - - -bool idEntity::SpawnAbsenceMarker() -{ - idStr absenceMarkerDefName = spawnArgs.GetString("def_absence_marker", "atdm:absence_marker"); - const idDict* markerDef = gameLocal.FindEntityDefDict(absenceMarkerDefName, false); - - if (markerDef == NULL) - { - gameLocal.Error( "Failed to find definition of absence marker entity " ); - return false; - } - - idEntity* ent; - gameLocal.SpawnEntityDef(*markerDef, &ent, false); - - if (!ent || !ent->IsType(CAbsenceMarker::Type)) - { - gameLocal.Error( "Failed to spawn absence marker entity" ); - return false; - } - - CAbsenceMarker* absenceMarker = static_cast(ent); - m_AbsenceMarker = absenceMarker; - - // absenceMarker->Init(); - if (!absenceMarker->initAbsenceReference (this, m_StartBounds)) - { - gameLocal.Error( "Failed to initialize absence reference in absence marker entity" ); - return false; - } - - // Success - return true; -} - -bool idEntity::DestroyAbsenceMarker() -{ - idEntity* absenceMarker = m_AbsenceMarker.GetEntity(); - if (absenceMarker != NULL) - { - absenceMarker->PostEventMS(&EV_Remove, 0); - m_AbsenceMarker = NULL; - } - return true; -} - -float idEntity::GetAbsenceNoticeability() -{ - return m_AbsenceNoticeability; -} - -/* -================ -idEntity::Event_RangedThreatTo -================ -*/ -void idEntity::Event_RangedThreatTo(idEntity* target) -{ - // This needs to be virtual, but I don't think events themselves - // can be virtual; so this just wraps a virtual method. - float result = this->RangedThreatTo(target); - idThread::ReturnFloat(result); -} - -/* -================ -idEntity::RangedThreatTo - -Return nonzero if this entity could potentially -attack the given (target) entity at range, or -entities in general if target is NULL. -For example, for the player this should return 1 -if the player has a bow equipped and 0 otherwise. -================ -*/ -float idEntity::RangedThreatTo(idEntity* target) -{ - // Most entities are not capable of attacking at range - return 0; -} - -void idEntity::GetTeamChildren( idList *list ) -{ -// ishtvan: TODO: I think this is WRONG and can go up and across the team hierarchy when called on bind children -// It only works as advertised when called on bindmasters - idEntity *NextEnt = NULL; - - list->Clear(); - for( NextEnt = GetNextTeamEntity(); NextEnt != NULL; NextEnt = NextEnt->GetNextTeamEntity() ) - { - if( NextEnt != this ) - list->Append( NextEnt ); - } -} - -void idEntity::Event_GetBindMaster( void ) -{ - idThread::ReturnEntity( GetBindMaster() ); -} - -void idEntity::Event_NumBindChildren( void ) -{ - idList ChildList; - GetTeamChildren( &ChildList ); - - idThread::ReturnInt( ChildList.Num() ); -} - -void idEntity::Event_GetBindChild( int ind ) -{ - idEntity *pReturnVal( NULL ); - - idList ChildList; - GetTeamChildren( &ChildList ); - - if( (ChildList.Num() - 1) >= ind ) - pReturnVal = ChildList[ ind ]; - - idThread::ReturnEntity( pReturnVal ); -} - -void idEntity::Event_GetNextInvItem() -{ - NextPrevInventoryItem(1); - - CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); - - idThread::ReturnEntity( (item != NULL) ? item->GetItemEntity() : NULL ); -} - -void idEntity::Event_GetPrevInvItem() -{ - NextPrevInventoryItem(-1); - - CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); - - idThread::ReturnEntity( (item != NULL) ? item->GetItemEntity() : NULL ); -} - -void idEntity::Event_SetCurInvCategory(const char* categoryName) -{ - CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); - - InventoryCursor()->SetCurrentCategory(categoryName); - - OnInventorySelectionChanged(prev); - - idThread::ReturnInt( InventoryCursor()->GetCurrentCategory()->GetName() == categoryName ); -} - -void idEntity::Event_SetCurInvItem(const char* itemName) -{ - CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); - - InventoryCursor()->SetCurrentItem(itemName); - - OnInventorySelectionChanged(prev); - - idThread::ReturnInt( InventoryCursor()->GetCurrentItem()->GetName() == itemName ); -} - -void idEntity::Event_GetCurInvCategory() -{ - idThread::ReturnString( InventoryCursor()->GetCurrentCategory()->GetName() ); -} - -void idEntity::Event_GetCurInvItemEntity() -{ - idThread::ReturnEntity( InventoryCursor()->GetCurrentItem()->GetItemEntity() ); -} - -void idEntity::Event_GetCurInvItemName() -{ - idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetName() ); -} - -void idEntity::Event_GetCurInvItemId() -{ - idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetItemId() ); -} - -void idEntity::Event_GetCurInvIcon() -{ - idThread::ReturnString( InventoryCursor()->GetCurrentItem()->GetIcon() ); -} - -void idEntity::Event_InitInventory(int callCount) -{ - // grayman #2820 - At the time of this writing, this routine checks - // for loot AND belonging in someone's inventory. If anything else is - // added here, the pre-check in ai.cpp that wraps around "PostEventMS( &EV_InitInventory, 0, 0 )" - // must account for that. The pre-check is needed to prevent unnecessary - // event posting that leads to doing nothing here. (I.e. the entity isn't - // loot, and it doesn't belong in someone's inventory.) - - // greebo: Check if this entity represents loot - if yes, update the total mission loot count - - // grayman #2820 - It probably never happens, but if loot is placed in the player's - // inventory at map start, it could get double-counted here if the player hasn't - // spawned yet and this routine has to call itself below. 'callCount' tracks how many - // times an attempt has been made, so we'll wrap the loot check in a callCount check - // to make sure it doesn't get done more than once. - - if ( callCount == 0 ) - { - int lootValue = spawnArgs.GetInt("inv_loot_value", "0"); - int lootType = spawnArgs.GetInt("inv_loot_type", "0"); - - // Check if the loot type is valid - if (lootType > LOOT_NONE && lootType < LOOT_COUNT && lootValue != 0) - { - gameLocal.m_MissionData->AddMissionLoot(static_cast(lootType), lootValue); - } - } - - // Check if this object should be put into the inventory of some entity - // when the object spawns. Default is no. - if (spawnArgs.GetBool("inv_map_start", "0")) - { - // Get the name of the target entity, defaults to PLAYER1 - idStr target = spawnArgs.GetString("inv_target", "player1"); - - idEntity* targetEnt = gameLocal.FindEntity(target.c_str()); - if (targetEnt != NULL) - { - // Put the item into the target entity's inventory - targetEnt->Inventory()->PutItem(this, targetEnt); - } - else - { - // Target entity not found (not spawned yet?) Postpone this event - // Check how often we've been called to avoid infinite postponing - if (callCount < 20) - { - // Try again in 250 ms. - PostEventMS(&EV_InitInventory, 250, callCount+1); - } - } - } -} - -void idEntity::Event_GetLootAmount(int lootType) -{ - int gold, jewelry, goods; - int total = Inventory()->GetLoot(gold, jewelry, goods); - - switch (lootType) - { - case LOOT_GOLD: - idThread::ReturnInt(gold); - return; - break; - - case LOOT_GOODS: - idThread::ReturnInt(goods); - return; - break; - - case LOOT_JEWELS: - idThread::ReturnInt(jewelry); - return; - break; - - default: - idThread::ReturnInt(total); - return; - break; - } - - idThread::ReturnInt(0); -} - -void idEntity::Event_ChangeLootAmount(int lootType, int amount) -{ - idThread::ReturnInt( ChangeLootAmount(lootType, amount) ); -} - -void idEntity::Event_AddInvItem(idEntity* ent) -{ - if (ent == NULL || ent->spawnArgs.FindKey("inv_name") == NULL) - { - gameLocal.Warning("Cannot add entity %s without 'inv_name' spawnarg to inventory of %s", ent->name.c_str(), name.c_str()); - return; - } - - AddToInventory(ent); -} - -void idEntity::Event_AddItemToInv(idEntity* ent) -{ - // no target, ignore - if (ent == NULL) - { - gameLocal.Warning("Cannot add entity %s to inventory of NULL target", GetName() ); - return; - } - - if (spawnArgs.FindKey("inv_name") == NULL) - { - gameLocal.Warning("Cannot add entity %s without 'inv_name' spawnarg to inventory of %s", GetName(), ent->name.c_str() ); - return; - } - - gameLocal.Printf("Adding entity %s to inventory of %s.\n", GetName(), ent->name.c_str() ); - ent->AddToInventory(this); -} - -CInventoryItemPtr idEntity::AddToInventory(idEntity *ent) -{ - // Sanity check - if (ent == NULL) return CInventoryItemPtr(); - - // Check if we have an inventory item. - idStr invName; - if (!ent->spawnArgs.GetString("inv_name", "", invName)) - { - return CInventoryItemPtr(); // not an inventory item - } - - // Get (create) the InventoryCursor of this Entity. - const CInventoryCursorPtr& crsr = InventoryCursor(); - - // Add the new item to the Inventory (with as owner) - CInventoryItemPtr item = crsr->Inventory()->PutItem(ent, this); - - if (item == NULL) - { - // not an inventory item - gameLocal.Warning("Couldn't add entity %s to inventory of %s", ent->name.c_str(), name.c_str()); - return item; - } - - // Play the (optional) acquire sound - idStr soundName = ent->spawnArgs.GetString("snd_acquire", ""); - if (! soundName.IsEmpty()) - { - StartSoundShader(declManager->FindSound(soundName), SCHANNEL_ANY, 0, false, NULL); - } - - return item; -} - -bool idEntity::ReplaceInventoryItem(idEntity* oldItem, idEntity* newItem) -{ - bool result = Inventory()->ReplaceItem(oldItem, newItem); - - // Fire the general "item changed" event - OnInventoryItemChanged(); - - return result; -} - -void idEntity::Event_ReplaceInvItem(idEntity* oldItem, idEntity* newItem) -{ - idThread::ReturnInt(ReplaceInventoryItem(oldItem, newItem) ? 1 : 0); -} - -int idEntity::ChangeLootAmount(int lootType, int amount) -{ - int groupTotal = 0; - int rc = 0; - idStr groupname; - - int gold, jewelry, goods; - int total = Inventory()->GetLoot(gold, jewelry, goods); - bool gained = (amount >= 0); - - switch(lootType) - { - case LOOT_GOLD: - gold += amount; - groupTotal = gold; - groupname = "loot_gold"; - rc = gold; - break; - - case LOOT_GOODS: - goods += amount; - groupTotal = goods; - groupname = "loot_goods"; - rc = goods; - break; - - case LOOT_JEWELS: - jewelry += amount; - groupTotal = jewelry; - groupname = "loot_jewels"; - rc = jewelry; - break; - - default: - rc = 0; - break; - } - - // Set the new values - Inventory()->SetLoot(gold, jewelry, goods); - - if (rc != 0) - { - gameLocal.m_MissionData->InventoryCallback(NULL, groupname, groupTotal, total, gained); - gameLocal.m_MissionData->ChangeFoundLoot(static_cast(lootType), amount); - } - - return rc; -} - -void idEntity::ChangeInventoryLightgemModifier(const char* invName, const char* invCategory, int value) -{ - CInventoryItemPtr item = Inventory()->GetItem(invName, invCategory); - if (item != NULL) - { - // Item found, set the value - item->SetLightgemModifier(value); - } - else - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change lightgem modifier, item %s not found\r", invName); - } -} - -void idEntity::ChangeInventoryIcon(const char* invName, const char* invCategory, const char* icon) -{ - CInventoryItemPtr item = Inventory()->GetItem(invName, invCategory); - - if (item != NULL) - { - // Item found, set the icon - item->SetIcon(icon); - } - else - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change inventory icon, item %s not found\r", invName); - } -} - -void idEntity::NextPrevInventoryItem(int direction) -{ - const CInventoryCursorPtr& cursor = InventoryCursor(); - assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() - - CInventoryItemPtr prev = cursor->GetCurrentItem(); - if (prev != NULL && prev->GetName() == TDM_DUMMY_ITEM && IsType(idPlayer::Type)) - { - // If current item is dummy then try to restore cursor to the last real item - CInventoryItemPtr lastItemRestored = Inventory()->GetItem(static_cast(this)->m_LastItemNameBeforeClear); - if (lastItemRestored != NULL) - { - cursor->SetCurrentItem(lastItemRestored); - } - static_cast(this)->m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; - } - // If the current item has not changed yet, move to the prev/next item - if (cursor->GetCurrentItem() == prev) - { - // direction parameter specifies whether next of previous item is chosen - if (direction > 0) cursor->GetNextItem(); - if (direction < 0) cursor->GetPrevItem(); - } - - // Call the selection changed event - OnInventorySelectionChanged(prev); -} - -void idEntity::NextPrevInventoryGroup(int direction) -{ - const CInventoryCursorPtr& cursor = InventoryCursor(); - - assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() - - CInventoryItemPtr prev = cursor->GetCurrentItem(); - - // direction parameter specifies whether next of previous item is chosen - if (direction > 0) cursor->GetNextCategory(); - if (direction < 0) cursor->GetPrevCategory(); - - OnInventorySelectionChanged(prev); -} - -void idEntity::CycleInventoryGroup(const idStr& groupName) -{ - const CInventoryCursorPtr& cursor = InventoryCursor(); - - assert(cursor != NULL); // all entities have a cursor after calling InventoryCursor() - - assert(cursor->GetCurrentCategory() != NULL); - - CInventoryItemPtr prev = cursor->GetCurrentItem(); - - if (cursor->GetCurrentCategory()->GetName() == groupName) - { - // We are already in the specified group - CInventoryItemPtr next = cursor->GetNextItem(); - - if (next->Category()->GetName() != groupName) - { - // We've changed groups, this means that the cursor has wrapAround set to false - // Set the cursor back to the first item - cursor->SetCurrentCategory(groupName); - } - } - else - { - // Not in the desired group yet, set the cursor to the first item in that group - cursor->SetCurrentCategory(groupName); - } - - OnInventorySelectionChanged(prev); -} - -void idEntity::OnInventoryItemChanged() -{ - // Nothing here, can be overriden by subclasses -} - -void idEntity::OnInventorySelectionChanged(const CInventoryItemPtr& prevItem) -{ - // Nothing here, can be overriden by subclasses -} - -void idEntity::ChangeInventoryItemCount(const char* invName, const char* invCategory, int amount) -{ - const CInventoryPtr& inventory = Inventory(); - bool bIsLoot( false ); - - CInventoryCategoryPtr category = inventory->GetCategory(invCategory); - if (category == NULL) - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change item count, inventory category %s not found\r", invCategory); - return; - } - - CInventoryItemPtr item = category->GetItem(invName); - if (item == NULL) - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Could not change item count, item name %s not found\r", invName); - return; - } - - // Change the counter by amount (explicitly allow negative values) - item->SetCount(item->GetCount() + amount); - - // We consider items "dropped" if the amount is negative - bool dropped = (amount < 0); - - // Assume item does not have an overall value since it's not loot - gameLocal.m_MissionData->InventoryCallback - ( - item->GetItemEntity(), - item->GetName(), - item->GetValue(), - 1, - !dropped - ); - - if (item->GetCount() <= 0) - { - // Stackable item count reached zero, remove item from category - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Removing empty item from category.\r"); - - category->RemoveItem(item); - - // Advance the cursor (after removal, otherwise we stick to an invalid id) - InventoryCursor()->GetNextItem(); - - // Call the selection changed event, passing the removed item as previously selected item - OnInventorySelectionChanged(item); - } - - // Check for empty categories after the item has been removed - if (category->IsEmpty()) - { - // Remove empty category from inventory - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Removing empty inventory category.\r"); - - inventory->RemoveCategory(category); - - // Switch the cursor to the next category (after removal) - InventoryCursor()->GetNextCategory(); - - // There shouldn't be a need to call OnInventorySelectionChanged(), as this - // has already been done by the code above. - } -} - -void idEntity::AddFrobPeer(const idStr& frobPeerName) -{ - m_FrobPeers.AddUnique(frobPeerName); -} - -void idEntity::AddFrobPeer(idEntity* peer) -{ - if (peer != NULL) - { - AddFrobPeer(peer->name); - } -} - -void idEntity::RemoveFrobPeer(const idStr& frobPeerName) -{ - m_FrobPeers.Remove(frobPeerName); -} - -void idEntity::RemoveFrobPeer(idEntity* peer) -{ - if (peer != NULL) - { - RemoveFrobPeer(peer->name); - } -} - -idEntity* idEntity::GetFrobMaster() -{ - if (m_MasterFrob.IsEmpty()) return NULL; - - idEntity* master = gameLocal.FindEntity(m_MasterFrob); - - if (master == NULL) - { - // master doesn't exist anymore - m_MasterFrob.Clear(); - return NULL; - } - - return master; -} - -void idEntity::Event_DestroyOverlay(int handle) -{ - DestroyOverlay(handle); -} - -void idEntity::DestroyOverlay(int handle) -{ - if ( handle != OVERLAYS_MIN_HANDLE ) { - idUserInterface *gui = m_overlays.getGui( handle ); - if ( gui ) - gui->Activate( false, gameLocal.time ); - m_overlays.destroyOverlay( handle ); - } else { - gameLocal.Warning( "Cannot destroy HUD.\n" ); - } -} - -void idEntity::Event_CreateOverlay( const char *guiFile, int layer ) -{ - idThread::ReturnInt(CreateOverlay(guiFile, layer)); -} - -int idEntity::CreateOverlay(const char *guiFile, int layer) -{ - int handle = OVERLAYS_INVALID_HANDLE; - - if(guiFile == NULL || guiFile[0] == 0) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Invalid GUI file name\r"); - return OVERLAYS_INVALID_HANDLE; - } - - - if(!uiManager->CheckGui(guiFile)) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load GUI file: [%s]\r", guiFile); - return OVERLAYS_INVALID_HANDLE; - } - handle = m_overlays.createOverlay( layer ); - if(handle == OVERLAYS_INVALID_HANDLE) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to create overlay for GUI [%s]\r", guiFile); - return OVERLAYS_INVALID_HANDLE; - } - - m_overlays.setGui(handle, guiFile); - idUserInterface *gui = m_overlays.getGui(handle); - if(gui == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Unable to load GUI [%s] into overlay.\r", guiFile); - // free handle, or we would leak - m_overlays.destroyOverlay(handle); - return OVERLAYS_INVALID_HANDLE; - } - - gui->SetStateInt("handle", handle); - gui->Activate(true, gameLocal.time); - // Let's set a good default value for whether or not the overlay is interactive. - m_overlays.setInteractive(handle, gui->IsInteractive()); - - // scale the GUI according to gui_Width/gui_Height/gui_CenterX/gui_CenterY - gameLocal.UpdateGUIScaling( gui ); - - return handle; -} - -idUserInterface* idEntity::GetOverlay(int handle) -{ - return m_overlays.getGui(handle); -} - -/** -* If this entity (or any entity that it is attached to) has mantling disabled, -* then this returns false. Otherwise, returns true. -**/ -bool idEntity::IsMantleable() -{ - bool returnVal = true; - idEntity* ent=this; - while (ent!=NULL) - { - if (!ent->m_bIsMantleable) - { - returnVal = false; - break; - } - ent = ent->GetBindMaster(); - } - return returnVal; -} - -int idEntity::heal(const char* healDefName, float healScale) { - const idDict* healDef = gameLocal.FindEntityDefDict( healDefName ); - if ( !healDef ) { - gameLocal.Error( "Unknown healDef '%s'\n", healDefName ); - } - - int healAmount = static_cast(healDef->GetInt( "heal_amount" ) * healScale); - int healInterval = healDef->GetInt("heal_interval", "0"); - int healStepAmount = healDef->GetInt("heal_step_amount", "5"); - float healIntervalFactor = healDef->GetInt("heal_interval_factor", "1"); - bool isAir = idStr(healDef->GetString("heal_type", "")) == "air"; - - // Check if the entity can be healed in the first place - if ( healAmount == 0 || (!isAir && health >= spawnArgs.GetInt("health")) ) { - return 0; - } - - // Check for air potions - if (isAir) { - if (!IsType(idActor::Type)) { - // Don't apply air healing to non-actors - return 0; - } - - // Try to cast this entity onto idAI or idPlayer - idAI* ai = dynamic_cast(this); - idPlayer* player = dynamic_cast(this); - - if (ai != NULL) { - // This entity is an AI - ai->setAirTicks(ai->getAirTicks() + healAmount); - return 1; - } - else if (player != NULL) { - // This entity is a player - player->setAirTicks(player->getAirTicks() + healAmount); - return 1; - } - - return 0; - } - // Is this "instant" healing? - else if (healInterval == 0) { - // Yes, heal the entity - health += healAmount; - - // It may be possible that negative healAmounts are applied and the entity dies - if ( health <= 0 ) { - if ( health < -999 ) { - health = -999; - } - - Killed( gameLocal.world, gameLocal.world, abs(healAmount), GetLocalCoordinates(GetPhysics()->GetOrigin()), 0); - } - return 1; - } - // Is this a gradual healing def? This would only apply to idPlayer - else if (healInterval > 0 && healStepAmount != 0 && IsType(idPlayer::Type)) - { - idPlayer* player = dynamic_cast(this); - - if (player != NULL) { - player->GiveHealthPool(healAmount); - // Set the parameters of the health pool - player->setHealthPoolTimeInterval(healInterval, healIntervalFactor, healStepAmount); - } - return 1; - } - else { - // Nothing suitable found in the def arguments, return 0 - return 0; - } -} - -// Deals damage to this entity, documentation: see header -void idEntity::Event_Damage( idEntity *inflictor, idEntity *attacker, - const idVec3 &dir, const char *damageDefName, - const float damageScale ) -{ - // Pass the call to the regular member method of this class - Damage(inflictor, attacker, dir, damageDefName, damageScale, 0, NULL); -} - -void idEntity::Event_Heal( const char *healDefName, const float healScale ) -{ - // Pass the call to the idEntity::heal method - idThread::ReturnInt(heal(healDefName, healScale)); -} - -// tels: -void idEntity::Event_TeleportTo(idEntity* target) -{ - Teleport( vec3_origin, idAngles( 0.0f, 0.0f, 0.0f ), target ); -} - -void idEntity::Event_IsDroppable( void ) -{ - idThread::ReturnInt( spawnArgs.GetBool("inv_droppable") ); -} - -void idEntity::Event_SetDroppable( bool Droppable ) -{ - spawnArgs.SetBool( "inv_droppable", Droppable ); - // update the item in the player's inventory, if there is one - if( spawnArgs.FindKey("inv_name") != NULL ) - { - idStr itemName = spawnArgs.GetString("inv_name"); - CInventoryItemPtr item = gameLocal.GetLocalPlayer()->Inventory()->GetItem( itemName ); - if( item != NULL ) - item->SetDroppable( Droppable ); - } -} - -// tels: -// lightFalloff == 0 - none -// lightFalloff == 0.5 - sqrt(linear) -// lightFalloff == 1 - liniear with distance (falls off already too fast) -// lightFalloff == 2 - squared with distance -// lightDistScale is a scaling factor to divide the distance. Sensible values are around 1..2 -void idEntity::Event_GetLightInPVS( const float lightFalloff, const float lightDistScale ) -{ - idVec3 sum(0,0,0); - idVec3 local_light; - idVec3 local_light_radius; - idVec3 origin; - // divide dist by this factor, so 1 as light in 500 units stays, is half in 1000 etc - float dist_scaling = 5000 * lightDistScale; - - // If this is a player, use the eye location to match what the script does - // with $player1.GetLocation() - const idPlayer* player = gameLocal.GetLocalPlayer(); - - if (player == this) - { - origin = player->GetEyePosition(); - } - else - { - origin = GetPhysics()->GetOrigin(); - } - int areaNum = gameRenderWorld->PointInArea( origin ); - - // Find all light entities, then check if they are in the same area as the player: - for( idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) - { - if ( !ent || !ent->IsType( idLight::Type ) ) { - continue; - } - - idLight* light = static_cast( ent ); - - // this makes it add all lights in the PVS, which is not good, albeit it makes leaning a bit better - //if ( gameLocal.InPlayerPVS( light ) ) { - - // light is in the same area? - idVec3 light_origin = light->GetLightOrigin(); - if ( areaNum == gameRenderWorld->PointInArea( light_origin ) ) { - light->GetColor( local_light ); - // multiple the light color by the radius to get a fake "light energy": - light->GetRadius( local_light_radius ); - // fireplace: 180+180+120/3 => 160 / 800 => 0.2 - // candle: 130+130+120/3 => 123 / 800 => 0.15 - // firearrow: 10+ 10+ 10/3 => 10 / 800 => 0.0125 - //gameLocal.Printf (" Adding light %s color %s radius %s\n", light->GetName(), local_light.ToString(), local_light_radius.ToString() ); - local_light *= (float) - (local_light_radius.x + - local_light_radius.y + - local_light_radius.z) / 2400; - // dimish light with distance? - if (lightFalloff > 0) - { - // compute distance - idVec3 dist3 = light_origin - origin; - // == 1 - float dist; - if (lightFalloff < 1) - { - dist = idMath::Sqrt( dist3.Length() ); // square root of dist - } - else if (lightFalloff > 1) - { - // squared - dist = dist3.LengthSqr(); - } - else - { - // linear - dist = dist3.Length(); - } - // divide by dist - //gameLocal.Warning(" dist %0.2f, falloff %0.0f\n", dist, lightFalloff ); - dist /= dist_scaling; - //gameLocal.Warning(" dist is now %0.2f\n", dist ); - //gameLocal.Warning(" local_light %s\n", local_light.ToString() ); - local_light /= dist; - //gameLocal.Warning(" local_light %s\n", local_light.ToString() ); - } - sum += local_light; - } - } - idThread::ReturnVector( sum ); -} - -bool idEntity::canSeeEntity(idEntity* target, int useLighting) { - // The target point is the origin of the other entity. - idVec3 toPos = target->GetPhysics()->GetOrigin(); - - trace_t tr; - // Perform a trace from the own origin to the target entity's origin - gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), toPos, MASK_OPAQUE, this ); - - if (tr.fraction >= 1.0f || gameLocal.GetTraceEntity(tr) == target) { - // Trace test passed, entity is visible - - if (useLighting) { - idBounds entityBounds = target->GetPhysics()->GetAbsBounds(); - entityBounds.ExpandSelf (0.1f); // A single point doesn't work with ellipse intersection - - idVec3 bottomPoint = entityBounds[0]; - idVec3 topPoint = entityBounds[1]; - - float lightQuotient = LAS.queryLightingAlongLine (bottomPoint, topPoint, this, true); - - // Return TRUE if the lighting exceeds the threshold. - return (lightQuotient >= VISIBILTIY_LIGHTING_THRESHOLD); - } - - // No lighting to consider, return true - return true; - } - else { - return false; - } -} - -void idEntity::Event_CanSeeEntity(idEntity* target, int useLighting) -{ - idThread::ReturnInt(canSeeEntity(target, useLighting) ? 1 : 0); -} - -void idEntity::ProcCollisionStims( idEntity *other, int body ) -{ - if (!other) - { - return; - } - - if (other->IsType(idAFEntity_Base::Type) && body >= 0) - { - idAFEntity_Base* otherAF = static_cast(other); - int bodID = otherAF->BodyForClipModelId( body ); - - //DM_LOG(LC_AI,LT_DEBUG)LOGSTRING("ProcCollisionStims called GetBody on id %d\r", bodID); - - idAFBody* struckBody = otherAF->GetAFPhysics()->GetBody(bodID); - - idEntity* reroute = struckBody->GetRerouteEnt(); - - if (reroute) - { - other = reroute; - } - } - - assert(other->GetStimResponseCollection() != NULL); // always non-NULL by design - - if (other->GetStimResponseCollection()->HasResponse()) - { - CStimResponseCollection* thisColl = GetStimResponseCollection(); - - // check each stim to see if it's a collision stim - int numStims = thisColl->GetNumStims(); - - for (int i = 0; i < numStims; ++i) - { - const CStimPtr& stim = thisColl->GetStim(i); - - if (stim->m_bCollisionBased) - { - stim->m_bCollisionFired = true; - stim->m_CollisionEnts.Append(other); - } - } - } -} - -/* tels: Parses "def_attach" spawnargs and builds a list of idDicts that - * contain the spawnargs to spawn the attachments, which is done in - * ParseAttachments() later. This is a two-phase process to allow other - * code (e.g. SEED) to just parse the attachments without spawning them. - */ -void idEntity::ParseAttachmentSpawnargs( idList *argsList, idDict *from ) -{ - const idKeyValue *kv = from->MatchPrefix( "def_attach", NULL ); - while ( kv ) - { - idDict args; - - // Read the classname of the attachment - - // Don't process keyvalues equal to "-" (empty attachment). - if (kv->GetValue() != "-") - { - args.Set( "classname", kv->GetValue().c_str() ); - - // make items non-touchable so the player can't take them out of the character's hands - args.Set( "no_touch", "1" ); - - // don't let them drop to the floor - args.Set( "dropToFloor", "0" ); - - // check for attachment position spawnarg - idStr Suffix = kv->GetKey(); - Suffix.StripLeading( "def_attach" ); - idStr PosKey = "pos_attach" + Suffix; - // String name of the attachment for later accessing - idStr AttName = "name_attach" + Suffix; - idStr AttNameValue = from->GetString(AttName); - if (! AttNameValue) - { - // fall back to the position if no name was defined - AttNameValue = from->GetString(PosKey); - } - - // store for later query - args.Set("_poskey", PosKey); - args.Set("_attnamevalue", AttNameValue ); - - // tels: parse all "set .." spawnargs - const idKeyValue *kv_set = from->MatchPrefix( "set ", NULL ); - while ( kv_set ) - { - // "set FOO on BAR" "0.5 0.5 0" - // means set "_color" "0.5 0.5 0" on the entity attached to the attachment point - // named "BAR" (defined with "name_attach" "BAR" on the original entity) - - // Get the value - // example: "0.5 0.5 0" - idStr SpawnargValue(kv_set->GetValue()); - - // "set FOO on BAR" - idStr SetAttName(kv_set->GetKey()); - // "set FOO on BAR" => "FOO on BAR" - SetAttName = SetAttName.Right( kv_set->GetKey().Length() - 4 ); - - // "FOO on BAR" - idStr SpawnargName(SetAttName); - - // find position of first ' ' - int PosSpace = SetAttName.Find( ' ', 0, -1); - - if (PosSpace == -1) - { - gameLocal.Warning( "%s: Spawnarg '%s' (value '%s') w/o attachment name. Applying to to all attachments.", - GetName(), kv_set->GetKey().c_str(), kv_set->GetValue().c_str() ); - //kv_set = from->MatchPrefix( "set ", kv_set ); - //continue; - // pretend "set _color" "0.1 0.2 0.3" means "set _color on BAR" where BAR is the - // current attachement. So it applies to all of them. - // SpawnargName is already right - SetAttName = AttNameValue; - } - else - { - // "FOO on BAR" => "FOO" - SpawnargName = SpawnargName.Left( PosSpace ); - // "FOO on BAR" => "BAR" - SetAttName = SetAttName.Right( SetAttName.Length() - (PosSpace + 4) ); - } - - // gameLocal.Printf("SetAttName '%s'\n", SetAttName.c_str()); - // gameLocal.Printf("AttNameValue '%s'\n", AttNameValue.c_str()); - // gameLocal.Printf("SpawnargName '%s'\n", SpawnargName.c_str()); - - // does this spawnarg apply to the newly spawned entity? - if (SetAttName == AttNameValue) - { - // it matches, so this spawnarg must be applied directly to this entity - //gameLocal.Printf("Match: Setting '%s' to '%s'\n", SpawnargName.c_str(), SpawnargValue.c_str() ); - args.Set( SpawnargName, SpawnargValue ); - } - else - { - // pass along the original "set ..." spawnarg, it might apply to an - // def_attached entity of the newly spawned one - //gameLocal.Printf("No match: Passing along '%s' ('%s')\n", kv_set->GetKey().c_str(), SpawnargValue.c_str() ); - args.Set( kv_set->GetKey(), SpawnargValue ); - } - - kv_set = from->MatchPrefix( "set ", kv_set ); - // end while ( kv_set ) - } - - argsList->Append (args ); - } - - kv = from->MatchPrefix( "def_attach", kv ); - } -} - -/* tels: Parses "def_attach" spawnargs and spawns and attaches all entities - * that are mentioned there. Before each entity is spawned, spawnargs of the - * format "set XYZ on ABC" are parsed and either applied to the newly spawned - * entity, so it can pass them along to its own def_attachments, or converted - * to a real spawnarg and applied to the entity before spawn. */ -void idEntity::ParseAttachments( void ) -{ - idEntity *ent = NULL; // each spawned entity - const idKeyValue *kv = NULL; - idList args; - - ParseAttachmentSpawnargs( &args, &spawnArgs ); - - for (int i = 0; i < args.Num(); i++) - { - gameLocal.SpawnEntityDef( args[i], &ent ); - - if ( ent != NULL) - { - if( args[i].FindKey( "_poskey" )) - { - Attach( ent, spawnArgs.GetString( args[i].GetString( "_poskey" ) ), args[i].GetString( "_attnamevalue") ); - //gameLocal.Printf(" Attaching '%s' at pos '%s'\n", AttNameValue.c_str(), spawnArgs.GetString( args[i].GetString("poskey") ) ); - } - else - { - Attach( ent, NULL, args[i].GetString( "_attnamevalue") ); - //gameLocal.Printf(" Attaching '%s' at pos 'Unknown'\n", AttNameValue.c_str() ); - } - - // grayman #2603 - generate a "target" spawnarg for later processing - // when attaching a relight position. - - if (ent->name.Find("relight_position") >= 0) - { - idStr name = ent->name; // start with full name - int index = name.Last('_'); // find '_nnn' entity number at the end - idStr suffix = name.Right(name.Length() - index); // suffix = '_nnn' - idStr rpString = "relight_position" + suffix; // add suffix to "relight_position" - spawnArgs.Set(rpString,name); // add new spawnarg "relight_position_nnn" "" - } - } - else - { - gameLocal.Error( "Couldn't spawn '%s' to attach to entity '%s'", args[i].GetString("name"), name.c_str() ); - } - } - - // after we have spawned all our attachments, we can parse the "add_link" spawnargs: - kv = spawnArgs.MatchPrefix( "add_link", NULL ); - while ( kv ) - { - // get the "source to target" value - idStr Link = kv->GetValue(); - - // "SOURCE to TARGET" - // find position of first " to " - int PosSpace = Link.Find( ' ', 0, -1); - if (PosSpace == -1) - { - gameLocal.Warning( "Invalid spawnarg add_link '%s' on entity '%s'", - kv->GetValue().c_str(), name.c_str() ); - kv = spawnArgs.MatchPrefix( "add_link", kv ); - continue; - } - - // "SOURCE to TARGET" => "SOURCE" - idStr Source = Link.Left( PosSpace ); - // "SOURCE to TARGET" => "TARGET" - idStr Target = Link.Right( Link.Length() - (PosSpace + 4) ); - - // gameLocal.Printf("Match: add_link '%s' to '%s'\n", Source.c_str(), Target.c_str() ); - - // If the source contains ":attached:name", split it into the base entity - // and the attachment name: - idEntity *source_ent = this; - PosSpace = Source.Find( ":attached:", 0, -1); - if (PosSpace != -1) - { - // "test:attached:flame" => "test" - // ":attached:flame" => "" - idStr Source_Entity = Source.Left( PosSpace ); - // "test:attached:flame" => "flame" - idStr Source_Att = Source.Right( Source.Length() - (PosSpace + 10) ); - - if (Source_Entity.Length() > 0) - { - // "Name:attached:flame" => entity name, so use "Name" - gameLocal.Printf(" Link source: '%s'\n", Source_Entity.c_str() ); - - Source = Source_Entity; - source_ent = gameLocal.FindEntity( Source ); - if (!source_ent) - { - gameLocal.Warning( "Cannot find entity '%s'.", Source.c_str() ); - } - } - // else: ":attached:flame" => no entity name, so use ourself - - // now find the attached entity - source_ent = source_ent->GetAttachmentFromTeam( Source_Att.c_str() ); - if (!source_ent) - { - gameLocal.Warning( "Cannot find source attachment '%s' on entity '%s'.", - Source_Att.c_str(), Source.c_str() ); - } - else - { - //gameLocal.Printf(" Link source entity (GetAttachmentFromTeam): '%s'\n", source_ent->name.c_str() ); - } - } - else - { - // source is just an entity name - source_ent = gameLocal.FindEntity( Source ); - //if (source_ent) - // gameLocal.Printf(" Link source entity (Entity): '%s'\n", source_ent->name.c_str() ); - } - - // If the target contains ":attached:name", split it into the base entity - // and the attachment name: - idEntity *target_ent = this; - PosSpace = Target.Find( ":attached:", 0, -1); - if (PosSpace != -1) - { - // "test:attached:flame" => "test" - idStr Target_Entity = Target.Left( PosSpace ); - // "test:attached:flame" => "flame" - idStr Target_Att = Target.Right( Target.Length() - (PosSpace + 10) ); - - if (Target_Entity.Length() > 0) - { - // "Name:attached:flame" => entity name, so use "Name" - gameLocal.Printf(" Link target: '%s'\n", Target_Entity.c_str() ); - - Target = Target_Entity; - target_ent = gameLocal.FindEntity( Target ); - if (!target_ent) - { - gameLocal.Warning( "Cannot find entity '%s'.", Target.c_str() ); - } - } - // else: ":attached:flame" => no entity name, so use ourself - - // now find the attached entity by the attachment pos name: - idEntity *target_ent_att = target_ent->GetAttachmentFromTeam( Target_Att.c_str() ); - if (!target_ent_att) - { - gameLocal.Warning( "Cannot find target attachment '%s' on entity '%s'.", - Target_Att.c_str(), target_ent->name.c_str() ); - } - else - { - //gameLocal.Printf(" Link target entity (GetAttachmentFromTeam): '%s'\n", target_ent->name.c_str() ); - } - target_ent = target_ent_att; - } - else - { - // target is just an entity name - target_ent = gameLocal.FindEntity( Target ); - //if (target_ent) - // gameLocal.Printf(" Link target entity (Entity): '%s'\n", target_ent->name.c_str() ); - } - - // now that we have entities for source and target, add the link - if ( source_ent && target_ent ) - { - //gameLocal.Printf(" add_link from '%s' to '%s'\n", source_ent->name.c_str(), target_ent->name.c_str() ); - source_ent->AddTarget( target_ent ); - } - else - { - // tels: TODO: post an event for later adding - if ( !target_ent ) - gameLocal.Warning( "Cannot find target entity '%s' for add_link.", Target.c_str() ); - if ( !source_ent ) - gameLocal.Warning( "Cannot find source entity '%s' for add_link.", Source.c_str() ); - } - - // do we have another one? - kv = spawnArgs.MatchPrefix( "add_link", kv ); - } -} - -/* -================ -idEntity::ParseAttachPositions -================ -*/ -void idEntity::ParseAttachPositions( void ) -{ - SAttachPosition pos; - SAttachPosition *pPos; - idStr prefix, keyname, jointname; - const idKeyValue *kv(NULL); - - m_AttachPositions.Clear(); - - // Read off basic attachment positions - // (intended to be on base class for a skeleton type, e.g., humanoid) - while( ( kv = spawnArgs.MatchPrefix("attach_pos_name_", kv) ) != NULL ) - { - keyname = kv->GetKey(); - keyname.StripLeading("attach_pos_name_"); - - pos.name = kv->GetValue().c_str(); - - // If entity has joints, find the joint handle for the joint name - if( GetAnimator() ) - { - jointname = spawnArgs.GetString( ("attach_pos_joint_" + keyname).c_str() ); - pos.joint = GetAnimator()->GetJointHandle( jointname ); - if ( pos.joint == INVALID_JOINT ) - { - // TODO: Turn this into a warning and attach relative to entity origin instead? - gameLocal.Error( "Joint '%s' not found for attachment position '%s' on entity '%s'", jointname.c_str(), pos.name.c_str(), name.c_str() ); - } - } - else - pos.joint = INVALID_JOINT; - - pos.originOffset = spawnArgs.GetVector( ("attach_pos_origin_" + keyname).c_str() ); - pos.angleOffset = spawnArgs.GetAngles( ("attach_pos_angles_" + keyname).c_str() ); - - m_AttachPositions.Append( pos ); - } - - kv = NULL; - // Read off actor-specific offsets to this position and apply them - while( (kv = spawnArgs.MatchPrefix("attach_posmod_name_", kv)) != NULL ) - { - keyname = kv->GetKey(); - keyname.StripLeading("attach_posmod_name_"); - - // Try to find the position - pPos = GetAttachPosition( kv->GetValue().c_str() ); - // If we find the position by name, apply the offsets - if( pPos != NULL ) - { - idVec3 trans = spawnArgs.GetVector( ("attach_posmod_origin_" + keyname).c_str() ); - idAngles ang = spawnArgs.GetAngles( ("attach_posmod_angles_" + keyname).c_str() ); - - pPos->originOffset += trans; - // TODO: Prove mathematically that adding the angles is the same as converting - // the angles to rotation matrices and multiplying them?? - // stgatilov: It is wrong. As soon as anyone starts using this spawnarg the proper meaning - // of this line should be worked out. - gameLocal.Error( "Using spawn attach_posmod_* with uncertain meaning: report to coders."); - pPos->angleOffset += ang; - } - } -} - -/* -================ -idEntity::GetAttachPosition -================ -*/ -SAttachPosition *idEntity::GetAttachPosition( const char *AttachName ) -{ - idStr AttName = AttachName; - SAttachPosition *returnVal = NULL; - -// TODO: Probably not worth doing a hash for this short list, linear search OK? - for( int i=0; i < m_AttachPositions.Num(); i++ ) - { - if( AttName == m_AttachPositions[i].name ) - { - returnVal = &m_AttachPositions[i]; - break; - } - } - - return returnVal; -} - -void idEntity::SaveAttachmentContents() -{ - for (int i = 0; i < m_Attachments.Num(); ++i) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL) continue; - - m_Attachments[i].savedContents = (ent != NULL) ? ent->GetPhysics()->GetContents() : -1; - } -} - -// Sets all attachment contents to the given value -void idEntity::SetAttachmentContents(int newContents) -{ - for (int i = 0; i < m_Attachments.Num(); ++i) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL) continue; - - ent->GetPhysics()->SetContents(newContents); - } -} - -// Restores all CONTENTS values, previously saved with SaveAttachmentContents() -void idEntity::RestoreAttachmentContents() -{ - for (int i = 0; i < m_Attachments.Num(); ++i) - { - idEntity* ent = m_Attachments[i].ent.GetEntity(); - - if (ent == NULL) continue; - - int savedContents = m_Attachments[i].savedContents; - - if (savedContents != -1) - { - ent->GetPhysics()->SetContents(savedContents); - } - } -} - -/* -===================== -SAttachPosition::Save -===================== -*/ -void SAttachPosition::Save( idSaveGame *savefile ) const -{ - savefile->WriteString( name ); - savefile->WriteInt( (int) joint ); - savefile->WriteAngles( angleOffset ); - savefile->WriteVec3( originOffset ); -} - -/* -===================== -SAttachPosition::Restore -===================== -*/ -void SAttachPosition::Restore( idRestoreGame *savefile ) -{ - int jointInt; - savefile->ReadString( name ); - savefile->ReadInt( jointInt ); - joint = (jointHandle_t) jointInt; - savefile->ReadAngles( angleOffset ); - savefile->ReadVec3( originOffset ); -} - -void idEntity::Event_SetContents(const int contents) -{ - GetPhysics()->SetContents(contents); -} - -void idEntity::Event_GetContents() -{ - idThread::ReturnInt(GetPhysics()->GetContents()); -} - -void idEntity::Event_SetClipMask(const int clipMask) -{ - GetPhysics()->SetClipMask(clipMask); -} - -void idEntity::Event_GetClipMask() -{ - idThread::ReturnInt(GetPhysics()->GetClipMask()); -} - -void idEntity::Event_ExtinguishLights() -{ - // greebo: First, check if we ourselves are a light - if (IsType(idLight::Type)) - { - // Call the script function to extinguish this light - CallScriptFunctionArgs("frob_extinguish", true, 0, "e", this); - } - - // Now go through the teamChain and check for lights - for (idEntity* ent = teamChain; ent != NULL; ent = ent->teamChain) - { - if (ent->IsType(idLight::Type)) - { - ent->CallScriptFunctionArgs("frob_extinguish", true, 0, "e", ent); - } - } -} - -void idEntity::Event_GetResponseEntity() -{ - idThread::ReturnEntity(GetResponseEntity()); -} - -void idEntity::Event_GetTeam() -{ - idThread::ReturnInt(team); -} - -void idEntity::Event_SetTeam(int newTeam) -{ - gameLocal.Printf("%s: Changing to team %i.\n", GetName(), newTeam); - // greebo: No validity checking so far - todo? - team = newTeam; -} - -void idEntity::SetEntityRelation(idEntity* entity, int relation) -{ - m_EntityRelations[entity] = relation; -} - - // angua: this changes the current relation to an actor by adding the new amount -void idEntity::ChangeEntityRelation(idEntity* entity, int relationChange) -{ - assert(entity); - if (entity == NULL) - { - return; - } - - EntityRelationsMap::iterator found = m_EntityRelations.find(entity); - - if (found == m_EntityRelations.end()) - { - // Sanity-check, some entities like worldspawn have team == -1 - if (entity->team == -1) return; - - // not yet set, load default from relations manager - int defaultrel = gameLocal.m_RelationsManager->GetRelNum(team, entity->team); - - std::pair result = m_EntityRelations.insert( - EntityRelationsMap::value_type(entity, defaultrel) - ); - - // set iterator to newly inserted element - found = result.first; - } - - found->second += relationChange; -} - -bool idEntity::IsFriend(const idEntity *other) -{ - if (other == NULL) - { - return false; - } - else if (other->team == -1) - { - // entities with team -1 (not set) are neutral - return false; - } - else - { - // angua: look up entity specific relation - EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); - if (found != m_EntityRelations.end()) - { - return (found->second > 0); - } - - // angua: no specific relation found, fall back to standard team relations - return gameLocal.m_RelationsManager->IsFriend(team, other->team); - } -} - -bool idEntity::IsNeutral(const idEntity *other) -{ - if (other == NULL) - { - return false; - } - else if (other->team == -1) - { - // entities with team -1 (not set) are neutral - return true; - } - else - { - // angua: look up entity specific relation - EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); - if (found != m_EntityRelations.end()) - { - return (found->second == 0); - } - - // angua: no specific relation found, fall back to standard team relations - return gameLocal.m_RelationsManager->IsNeutral(team, other->team); - } -} - -bool idEntity::IsEnemy(const idEntity *other ) -{ - if (other == NULL) - { - // The NULL pointer is not your enemy! As long as you remember to check for it to avoid crashes. - return false; - } - else if (other->team == -1) - { - // entities with team -1 (not set) are neutral - return false; - } - else if (other->fl.notarget) - { - return false; - } - else - { - // angua: look up entity specific relation - EntityRelationsMap::const_iterator found = m_EntityRelations.find(other); - if (found != m_EntityRelations.end()) - { - return (found->second < 0); - } - - // angua: no specific relation found, fall back to standard team relations - return gameLocal.m_RelationsManager->IsEnemy(team, other->team); - } -} - -void idEntity::Event_IsEnemy( idEntity *ent ) -{ - idThread::ReturnInt(static_cast(IsEnemy(ent))); -} - -void idEntity::Event_IsFriend( idEntity *ent ) -{ - idThread::ReturnInt(IsFriend(ent)); -} - -void idEntity::Event_IsNeutral( idEntity *ent ) -{ - idThread::ReturnInt(IsNeutral(ent)); -} - - -void idEntity::Event_SetEntityRelation(idEntity* entity, int relation) -{ - SetEntityRelation(entity,relation); -} - -void idEntity::Event_ChangeEntityRelation(idEntity* entity, int relationChange) -{ - ChangeEntityRelation(entity, relationChange); -} - - - diff --git a/game/entity.h b/game/entity.h deleted file mode 100644 index a395b6d43..000000000 --- a/game/entity.h +++ /dev/null @@ -1,1827 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $HeadURL$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_ENTITY_H__ -#define __GAME_ENTITY_H__ - -#include "../DarkMod/StimResponse/StimType.h" -#include "../DarkMod/overlaySys.h" -#include "../DarkMod/UserManager.h" -#include "../DarkMod/ModelGenerator.h" - -class CStimResponseCollection; -class CStim; -typedef boost::shared_ptr CStimPtr; -class CResponse; -typedef boost::shared_ptr CResponsePtr; -class CAbsenceMarker; -class CObjectiveLocation; - -class CInventory; -typedef boost::shared_ptr CInventoryPtr; -class CInventoryItem; -typedef boost::shared_ptr CInventoryItemPtr; -class CInventoryCursor; -typedef boost::shared_ptr CInventoryCursorPtr; - -/** -* This struct defines one entity with an optional offset, count and -* probability, to spawn it upon the death of another entity. -*/ -struct FlinderSpawn { - idStr m_Entity; //!< class of the entity to spawn - idVec3 m_Offset; //!< optional offset - int m_Count; //!< count (default: 1) - float m_Probability; //!< probability (0 .. 1.0) that this entity spawns -}; - -/* -=============================================================================== - - Game entity base class. - -=============================================================================== -*/ - -static const int DELAY_DORMANT_TIME = 3000; -/** -* greebo: This is the value that has to be exceeded by the lightingQuotient -* returned by the LAS routines (range 0.0 ... 1.0). -* 0.0 means no threshold - target entities are always visible -* This is used by the idEntity::canSeeEntity() member method. -*/ -static const float VISIBILTIY_LIGHTING_THRESHOLD = 0.2f; - -extern const idEventDef EV_PostSpawn; -extern const idEventDef EV_FindTargets; -extern const idEventDef EV_RemoveTarget; -extern const idEventDef EV_AddTarget; -extern const idEventDef EV_Touch; -extern const idEventDef EV_Use; -extern const idEventDef EV_Activate; -extern const idEventDef EV_ActivateTargets; -extern const idEventDef EV_Hide; -extern const idEventDef EV_Show; -extern const idEventDef EV_GetShaderParm; -extern const idEventDef EV_SetShaderParm; -extern const idEventDef EV_SetOwner; -extern const idEventDef EV_GetAngles; -extern const idEventDef EV_SetAngles; -extern const idEventDef EV_SetLinearVelocity; -extern const idEventDef EV_SetAngularVelocity; -extern const idEventDef EV_SetSkin; -extern const idEventDef EV_StartSoundShader; -extern const idEventDef EV_StopSound; -extern const idEventDef EV_CacheSoundShader; -extern const idEventDef EV_ExtinguishLights; -extern const idEventDef EV_TeleportTo; -extern const idEventDef EV_IsDroppable; -extern const idEventDef EV_SetDroppable; - -extern const idEventDef EV_IsType; - -#ifdef MOD_WATERPHYSICS - -extern const idEventDef EV_GetMass; // MOD_WATERPHYSICS - -extern const idEventDef EV_IsInLiquid; // MOD_WATERPHYSICS - -#endif // MOD_WATERPHYSICS - -extern const idEventDef EV_CopyBind; -extern const idEventDef EV_IsFrobable; -extern const idEventDef EV_SetFrobable; -extern const idEventDef EV_FrobHilight; -extern const idEventDef EV_InPVS; -extern const idEventDef EV_CanSeeEntity; -extern const idEventDef EV_CanBeUsedBy; - -// greebo: Script event definition for dealing damage -extern const idEventDef EV_Damage; -extern const idEventDef EV_Heal; - -extern const idEventDef EV_ResponseAllow; - -extern const idEventDef EV_DestroyOverlay; - -// Think flags -enum { - TH_ALL = -1, - TH_THINK = 1, // run think function each frame - TH_PHYSICS = 2, // run physics each frame - TH_ANIMATE = 4, // update animation each frame - TH_UPDATEVISUALS = 8, // update renderEntity - TH_UPDATEPARTICLES = 16, - TH_DOUSING = 32, // grayman #2603 - run think function to process latched dousing - TH_ARMED = 64 // grayman #2478 - run think function when mine is armed -}; - -// The impulse states a button can have -enum EImpulseState { - EPressed, // just pressed - ERepeat, // held down - EReleased, // just released - ENumImpulseStates, -}; - -// -// Signals -// make sure to change script/doom_defs.script if you add any, or change their order -// -typedef enum { - SIG_TOUCH, // object was touched - SIG_USE, // object was used - SIG_TRIGGER, // object was activated - SIG_REMOVED, // object was removed from the game - SIG_DAMAGE, // object was damaged - SIG_BLOCKED, // object was blocked - - SIG_MOVER_POS1, // mover at position 1 (door closed) - SIG_MOVER_POS2, // mover at position 2 (door open) - SIG_MOVER_1TO2, // mover changing from position 1 to 2 - SIG_MOVER_2TO1, // mover changing from position 2 to 1 - - NUM_SIGNALS -} signalNum_t; - -// FIXME: At some point we may want to just limit it to one thread per signal, but -// for now, I'm allowing multiple threads. We should reevaluate this later in the project -#define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16 - -struct signal_t { - int threadnum; - const function_t *function; -}; - -class signalList_t { -public: - idList signal[ NUM_SIGNALS ]; -}; - -// Inventory-related flags. -enum { - EINV_GROUP = 1, // Jump to the next/previous group. - EINV_PREV = 2, // Iterate backwards. - EINV_FAST = 4, // Don't use group histories. -}; - -/** -* Attachment system info -**/ -class CAttachInfo -{ -public: - CAttachInfo() : - channel(0), - savedContents(-1) - {} - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - idEntityPtr ent; - // Anim channel this attachment is on (if on an animated entity) - int channel; - // unique name by which the entity refers to this attachment - idStr name; - - // An additional int to save contents (used to set attachments nonsolid temporarily) - int savedContents; - - // grayman #2603 - save the position name to help find out what's in an AI's hands later - idStr posName; -}; - -/** -* Info structure for attaching things to named positions -**/ -typedef struct SAttachPosition_s -{ - idStr name; //!< name of this position - jointHandle_t joint; //!< joint it is relative to - idAngles angleOffset; //!< rotational offset relative to joint orientation - idVec3 originOffset; //!< origin offset relative to joint origin - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); -} SAttachPosition; - - -class idEntity : public idClass { -public: - static const int MAX_PVS_AREAS = 4; - - int entityNumber; // index into the entity list - int entityDefNumber; // index into the entity def list - - idLinkList spawnNode; // for being linked into spawnedEntities list - idLinkList activeNode; // for being linked into activeEntities list - - idLinkList snapshotNode; // for being linked into snapshotEntities list - int snapshotSequence; // last snapshot this entity was in - int snapshotBits; // number of bits this entity occupied in the last snapshot - - idStr name; // name of entity - idDict spawnArgs; // key/value pairs used to spawn and initialize entity - idScriptObject scriptObject; // contains all script defined data for this entity - - int thinkFlags; // TH_? flags - int dormantStart; // time that the entity was first closed off from player - bool cinematic; // during cinematics, entity will only think if cinematic is set - - renderView_t * renderView; // for camera views from this entity - idEntity * cameraTarget; // any remoteRenderMap shaders will use this - - idList< idEntityPtr > targets; // when this entity is activated these entities entity are activated - - int health; // FIXME: do all objects really need health? - int maxHealth; // greebo: Moved this from idInventory to here - - struct entityFlags_s { - bool notarget :1; // if true never attack or target this entity - bool noknockback :1; // if true no knockback from hits - bool takedamage :1; // if true this entity can be damaged - bool hidden :1; // if true this entity is not visible - bool bindOrientated :1; // if true both the master orientation is used for binding - bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities - bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not - bool selected :1; // if true the entity is selected for editing - bool neverDormant :1; // if true the entity never goes dormant - bool isDormant :1; // if true the entity is dormant - bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected - bool networkSync :1; // if true the entity is synchronized over the network - } fl; - - /** - * When an entity is hidden, these store the following information just before the hide: - * These store the clipmodel contents, clipmask and whether the clipmodel was enabled - * These variables are reset to this data when the entity is un-hidden - **/ - int m_preHideContents; - int m_preHideClipMask; - - /** - * Entity contents may be overwritten by a custom contents spawnarg - * Store it here to keep track of it, because derived classes can - * set the contents in their spawn method, and need to know to overwrite it - **/ - int m_CustomContents; - - /** - * UsedBy ist the list of entity names that this entity can be used by. - * i.e. A door can have a list of keys that can unlock it. A fountain can - * be used by a water arrow to make it holy, etc. - * The list is initialized by the key "used"_by" in the entity and contains - * the names of the entities seperated by ';'. If the first character of - * the name is a '*' the name donates a classname instead of an entity. In - * this case all entities of that class can be used by this entity. - * Example: If you have several holy fountains you would have to list all - * fountain names. Alternatively you can create a "holy_fountain" class and - * list it like this: - * "used_by" "*holy_fountain;*holy_bottle;holy_cross" - * In this example the entity can be used by any holy_fountain, any holy_bottle - * and addtionaly by the entity named holy_cross. - */ - idList m_UsedByName; - /** - * Same, but checks against inv_names - **/ - idList m_UsedByInvName; - /** - * Same, but checks against inv_categories - **/ - idList m_UsedByCategory; - /** - * Same, but checks against the entityDef name (e.g. atdm:playertools_lockpick*) - * This may be redundant sometimes, because classnames are often a part of the - * entity name. But not always, mappers can rename entities whatever they want - **/ - idList m_UsedByClassname; - - /** - * Set to true if objective locations should update the objectives system when - * this entity the objective area. - * May also determine inventory callbacks to objective system. - **/ - bool m_bIsObjective; - - /** - * greebo: The list of objective locations whose bounds this entity is currently within. - * This is needed to raise a safe mission event when this entity is destroyed, otherwise - * the objective location entity is unable to catch entity destructions. - */ - idList > m_objLocations; - - /** - * Set to true if the entity is frobable. May be dynamically changed. - **/ - bool m_bFrobable; - - /** - * Set to true if the entity is a "simple" frobable like a door, lever, button - * These items can still be frobbed while doing things like shouldering bodies - **/ - bool m_bFrobSimple; - - /** - * Frobdistance determines the distance in renderunits. If set to 0 - * the entity is not frobable. - **/ - int m_FrobDistance; - - /** - * Frob bias: Multiplies the angle deviation cosine test in idPlayer::FrobCheck - * Effectively biases the frob selection toward this object. Used for small objects - * to make them easier to frob when placed next to large objects. - **/ - float m_FrobBias; - - /** - * Controls whether this entity, when attached to an AI, will become solid when the AI - * is alerted and nonsolid when the AI is not alerted. - * Often applied in conjunction with attach_set_nonsolid spawnarg - **/ - bool m_bAttachedAlertControlsSolidity; - - /** - * Set to true if this entity is a climbable rope. This could be set on either - * static ropes or AF entities, so it makes sense to let all entities have this var - **/ - bool m_bIsClimbableRope; - - /** - * TDM: The default playback rate of each animation, indexed by the animation's - * index number. Only used by idActor; but the animation classes deal with idEntity - * directly, and it's more efficient to declare this on all entities than to do - * RTTI on every animation frame. - **/ - idList m_animRates; - - /** - * Actor who set this item in motion. Cleared when it comes to rest. - * Always NULL for non-physical items. - **/ - idEntityPtr m_SetInMotionByActor; - /** - * Actor who last moved this item. Never cleared. - * Always NULL for non-physical items. - **/ - idEntityPtr m_MovedByActor; - - // The light quotient for this entity, calculated by the LAS - float m_LightQuotient; - // The last time the above value has been calculated - int m_LightQuotientLastEvalTime; - - bool m_droppedByAI; // grayman #1330 - - /** - * Tels: Contains handle to (sharable, constant) LOD data if != 0. - */ - lod_handle m_LODHandle; - - /** - * Tels: Info for LOD, per entity. used if m_LODHandle != 0: - * Timestamp for next LOD think. If negative, LOD thinking is - * temp. disabled. - **/ - int m_DistCheckTimeStamp; - - /** - * Current LOD (0 - normal, 1,2,3,4,5 LOD, 6 hidden) - **/ - int m_LODLevel; - - /* Store the current model and skin to avoid flicker by not - * switching from one model/skin to the same model/skin when - * changing the LOD. - */ - int m_ModelLODCur; - int m_SkinLODCur; - - /* grayman #597 - hide until this timer expires. For - * hiding arrows when they're first nocked. - */ - int m_HideUntilTime; - - /* grayman #2787 - planting data needed for vines (vinearrow) - */ - idVec3 m_VinePlantLoc; - idVec3 m_VinePlantNormal; - -public: - ABSTRACT_PROTOTYPE( idEntity ); - - idEntity(); - virtual ~idEntity(); - - void Spawn( void ); - - /** - * Load and check the visual and collision model, as well as any model for - * the broken state. - */ - virtual void LoadModels( void ); - - /** - * Parse the LOD spawnargs and returns 0 if the entity has no LOD (or hide_distance), - * otherwise returns a handle registered with ModelGenerator::RegisterLODData(); - */ - lod_handle ParseLODSpawnargs( const idDict* dict, const float fRandom); - - /** - * Tels: Stop LOD changes permanently. If doTeam is true, also disables it on teammembers. - */ - void StopLOD( const bool doTeam); - - /** - * Tels: Stop LOD changes temporarily. If doTeam is true, also disables it on teammembers. - */ - void DisableLOD( const bool doTeam ); - void EnableLOD( const bool doTeam ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - /** - * greebo: This method is called before the savegame is writing its "object list" to the file, - * to give this entity an opportunity to register its subobjects (like the PickableLock class - * which is a non-spawned object of the BinaryFrobMover class). - */ - virtual void AddObjectsToSaveGame(idSaveGame* savefile); - - const char * GetEntityDefName( void ) const; - void SetName( const char *name ); - const char * GetName( void ) const; - - virtual void UpdateChangeableSpawnArgs( const idDict *source ); - - // clients generate views based on all the player specific options, - // cameras have custom code, and everything else just uses the axis orientation - virtual renderView_t * GetRenderView(); - - // greebo: Call this to trigger this entity - virtual void Activate(idEntity* activator); - - // thinking - virtual void Think( void ); - - // Tels: If LOD is enabled on this entity, compute new LOD level and new alpha value. - // We pass in a pointer to the data (so the LODE can use shared data) as well as the distance, - // so the lode can pre-compute the distance. - virtual float ThinkAboutLOD( const lod_data_t* lod_data, const float deltaSq ); - - // Tels: Returns the distance that should be considered for LOD and hiding, depending on: - // * the distance of the origin to the given player origin - // * the lod-bias set in the menu - // * some minimum and maximum distances based on entity size/importance - // The returned value is the actual distance squared, and rounded down to an integer. - float GetLODDistance( const lod_data_t *m_LOD, const idVec3 &playerOrigin, const idVec3 &entOrigin, const idVec3 &entSize, const float lod_bias ) const; - - // Tels: If LOD is enabled on this entity, call ThinkAboutLOD, computing new LOD level and new - // alpha value, then do the right things like Hide/Show, SetAlpha, switch models/skin etc. - // We pass in a pointer to the data (so the LODE can use shared data) as well as the distance, - // so the lode can pre-compute the distance. - virtual bool SwitchLOD( const lod_data_t *m_LOD, const float deltaSq ); - - bool CheckDormant( void ); //!< dormant == on the active list, but out of PVS - virtual void DormantBegin( void ); //!< called when entity becomes dormant - virtual void DormantEnd( void ); //!< called when entity wakes from being dormant - bool IsActive( void ) const; - void BecomeActive( int flags ); - void BecomeInactive( int flags ); - void BecomeBroken( idEntity *activator ); //!< Entity breaks up - void UpdatePVSAreas( const idVec3 &pos ); - - // visuals - virtual void Present( void ); - virtual renderEntity_t *GetRenderEntity( void ); - virtual int GetModelDefHandle( void ); - virtual void SetModel( const char *modelname ); - void SetSkin( const idDeclSkin *skin ); - const idDeclSkin * GetSkin( void ) const; - void SetShaderParm( int parmnum, float value ); - virtual void SetColor( const float red, const float green, const float blue ); - virtual void SetColor( const idVec3 &color ); - virtual void GetColor( idVec3 &out ) const; - virtual void SetColor( const idVec4 &color ); - virtual void GetColor( idVec4 &out ) const; - virtual void FreeModelDef( void ); - virtual void FreeLightDef( void ); - virtual void Hide( void ); - virtual void Show( void ); - bool IsHidden( void ) const; - - /** - * Tels: Only set the alpha channel to fade in/out - */ - virtual void SetAlpha( const float alpha ); - /** - * Tels: Same as SetAlpha(); but set bound children, too, if doTeam is true - */ - virtual void SetAlpha( const float alpha, const bool doTeam ); - - /** - * greebo: Returns the light quotient for this entity, a value determined by the - * number of lights hitting this entity's bounding box, determined by the LAS. - * - * AI are using this method to determine an object's visibility. The result - * is cached, to save it from being recalculated for multiple AI each frame. - */ - float GetLightQuotient(); - - // TDM: SZ: January 9, 2006 Made virtual to handle unique behavior in descendents - virtual void UpdateVisuals( void ); - - void UpdateModel( void ); - void UpdateModelTransform( void ); - virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); - int GetNumPVSAreas( void ); - const int * GetPVSAreas( void ); - void ClearPVSAreas( void ); - bool PhysicsTeamInPVS( pvsHandle_t pvsHandle ); - - // animation - virtual bool UpdateAnimationControllers( void ); - bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); - static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); - virtual idAnimator * GetAnimator( void ); // returns animator object used by this entity - - // sound - virtual bool CanPlayChatterSounds( void ) const; - - // angua: propVolMod only modifies the volume of the propagated sound - bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length, float propVolMod = 0); - bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length); - void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds - void SetSoundVolume( float volume ); - void UpdateSound( void ); - int GetListenerId( void ) const; - idSoundEmitter * GetSoundEmitter( void ) const; - void FreeSoundEmitter( bool immediate ); - - // entity binding - virtual void PreBind( void ); - virtual void PostBind( void ); - virtual void PreUnbind( void ); - virtual void PostUnbind( void ); - void JoinTeam( idEntity *teammember ); - - /** - * greebo: Returns the first team entity matching the given type. If the second - * argument is specified, it returns the next entity after that one. - * - * @returns: NULL if nothing found, the entity pointer otherwise. The entity pointer can be - * safely static_cast<> onto the given type, as the type check has already been performed in this function. - */ - idEntity* FindMatchingTeamEntity(const idTypeInfo& type, idEntity* lastMatch = NULL); - - void Bind( idEntity *master, bool orientated ); - void BindToJoint( idEntity *master, const char *jointname, bool orientated ); - void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated ); - void BindToBody( idEntity *master, int bodyId, bool orientated ); - void Unbind( void ); - bool IsBound( void ) const; - bool IsBroken( void ) const; //!< return true if model was broken - bool IsBoundTo( idEntity *master ) const; - idEntity * GetBindMaster( void ) const; - jointHandle_t GetBindJoint( void ) const; - int GetBindBody( void ) const; - idEntity * GetTeamMaster( void ) const; - idEntity * GetNextTeamEntity( void ) const; - /** - * TDM: Get a list of bound team members lower down on the chain than this one - * Populates the list in the argument argument with entity pointers - **/ - void GetTeamChildren( idList *list ); - void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis ); - idVec3 GetLocalVector( const idVec3 &vec ) const; - idVec3 GetLocalCoordinates( const idVec3 &vec ) const; - idVec3 GetWorldVector( const idVec3 &vec ) const; - idVec3 GetWorldCoordinates( const idVec3 &vec ) const; - bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const; - void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const; - int GetModelDefHandle(void) const { return modelDefHandle; }; - // physics - // set a new physics object to be used by this entity - void SetPhysics( idPhysics *phys ); - // get the physics object used by this entity - idPhysics * GetPhysics( void ) const; - // restore physics pointer for save games - void RestorePhysics( idPhysics *phys ); - // run the physics for this entity - bool RunPhysics( void ); - // set the origin of the physics object (relative to bindMaster if not NULL) - void SetOrigin( const idVec3 &org ); - // set the axis of the physics object (relative to bindMaster if not NULL) - void SetAxis( const idMat3 &axis ); - // use angles to set the axis of the physics object (relative to bindMaster if not NULL) - void SetAngles( const idAngles &ang ); - // get the floor position underneath the physics object - bool GetFloorPos( float max_dist, idVec3 &floorpos ) const; - // retrieves the transformation going from the physics origin/axis to the visual origin/axis - virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); - // retrieves the transformation going from the physics origin/axis to the sound origin/axis - virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); - // called from the physics object when colliding, should return true if the physics simulation should stop - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - /** - * TDM: Process collision stims when collisions occur - * Body is the AF body that was struck (defaults to -1) - **/ - virtual void ProcCollisionStims( idEntity *other, int body = -1 ); - // retrieves impact information, 'ent' is the entity retrieving the info - virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ); - // apply an impulse to the physics object, 'ent' is the entity applying the impulse - virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ); - // add a force to the physics object, 'ent' is the entity adding the force - virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ); - // activate the physics object, 'ent' is the entity activating this entity (and ignored in the code in entity.cpp...) - virtual void ActivatePhysics( idEntity *ent ); - // returns true if the physics object is at rest - virtual bool IsAtRest( void ) const; - // returns the time the physics object came to rest - virtual int GetRestStartTime( void ) const; - // add a contact entity - virtual void AddContactEntity( idEntity *ent ); - // remove a touching entity - virtual void RemoveContactEntity( idEntity *ent ); - - // damage - // returns true if this entity can be damaged from the given origin - virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const; - // applies damage to this entity - virtual void Damage( idEntity *inflictor, idEntity *attacker, - const idVec3 &dir, const char *damageDefName, - const float damageScale, const int location, trace_t *tr = NULL ); - // greebo: Heals this entity using the information found in the entitDef named healDefName - // returns 1 if the entity was healed, or 0 if the entity was already at full health - virtual int heal(const char* healDefName, float healScale); - // adds a damage effect like overlays, blood, sparks, debris etc. - virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); - // callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. - virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); - // notifies this entity that it is in pain - virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - // notifies this entity that is has been killed - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - - // scripting - virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; - virtual idThread * ConstructScriptObject( void ); - virtual void DeconstructScriptObject( void ); - void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function ); - void ClearSignal( idThread *thread, signalNum_t signalnum ); - void ClearSignalThread( signalNum_t signalnum, idThread *thread ); - bool HasSignal( signalNum_t signalnum ) const; - void Signal( signalNum_t signalnum ); - void SignalEvent( idThread *thread, signalNum_t signalnum ); - - // gui - void TriggerGuis( void ); - bool HandleGuiCommands( idEntity *entityGui, const char *cmds ); - virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ); - - // targets - void FindTargets( void ); - void RemoveNullTargets( void ); - void ActivateTargets( idEntity *activator ) const; - // greebo: Removes the given target ent from this entity's targets. - virtual void RemoveTarget(idEntity* target); - virtual void AddTarget(idEntity* target); - - // grayman #2603 - relight positions - void FindRelights(void); - - // misc - virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); - bool TouchTriggers( void ) const; - idCurve_Spline *GetSpline( void ) const; - virtual void ShowEditingDialog( void ); - - void SetHideUntilTime(int time); // grayman #597 - int GetHideUntilTime(void); // grayman #597 - - idEntity* GetAttachmentByPosition(idStr AttPos); // grayman #2603 - - enum { - EVENT_STARTSOUNDSHADER, - EVENT_STOPSOUNDSHADER, - EVENT_MAXEVENTS - }; - - virtual void ClientPredictionThink( void ); - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - void WriteBindToSnapshot( idBitMsgDelta &msg ) const; - void ReadBindFromSnapshot( const idBitMsgDelta &msg ); - void WriteColorToSnapshot( idBitMsgDelta &msg ) const; - void ReadColorFromSnapshot( const idBitMsgDelta &msg ); - void WriteGUIToSnapshot( idBitMsgDelta &msg ) const; - void ReadGUIFromSnapshot( const idBitMsgDelta &msg ); - - void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const; - void ClientSendEvent( int eventId, const idBitMsg *msg ) const; - - // ---===<* Darkmod functions *>===--- - - /** - * LoadTDMSettings will initialize the settings required for - * darkmod to operate. It should be called from idEntity::Spawn(), - * which will be valid for all entities. If a class needs - * to load additional settings, which are only of interest to this - * particular class it should override this virtual function but - * don't forget to call it for the base class. - */ - virtual void LoadTDMSettings(void); - - /** - * Will evaluate one def_broken flinder and find out how many of this piece - * to spawn, then spawn them. Called from Flinderize(). - * @return: Count of entities that where spawned or -1 for error. - * - */ - virtual int SpawnFlinder(const FlinderSpawn& bs, idEntity *activator); - - /** - * Evaluate def_flinder spawnargs and call SpawnFlinder() for each found. - */ - virtual void Flinderize (idEntity *activator); - - /** - * Parses spawnarg list of attachments and puts them into the list. - **/ - void ParseAttachmentSpawnargs( idList *argsList, idDict *from ); - - /** - * Frobaction will determine what a particular item should do when an entity is highlighted. - * The actual action depends on the type of the entity. - * Loot is being picked up and counted to the loot. - * Special items are transfered to the inventory. If the item is also loot it will count - * to that as well. - * Doors are tested for their state (locked/unlocked) and opened if unlocked. if the - * lockpicks or an appropriate key is equipped the door will either unlock or the - * lockpick HUD should appear. - * Windows are just smaller doors so they don't need special treatment. - * AI is tested for its state. If it is an ally some defined script should start. If - * it is unconscious or dead it is picked up and the player can carry it around. - * If it is a movable item the item is picked up and the player can carry it around. - * Switches are flipped and/or de-/activated and appropriate scripts are triggered. - * - * @frobMaster indicates whether the entity is allowed to call its master or not. - * - * @isFrobPeerAction: this is TRUE if this frob action was propagated from a peer. - */ - virtual void FrobAction(bool frobMaster, bool isFrobPeerAction = false); - - /** - * Function that is called if the player holds down the frob button on this object - * By default, does nothing - **/ - virtual void FrobHeld(bool frobMaster, bool isFrobPeerAction = false, int holdTime = 0) {}; - - /** - * Function that is called if the player holds down the frob button on this object - * By default, does nothing - **/ - virtual void FrobReleased(bool frobMaster, bool isFrobPeerAction = false, int holdTime = 0) {}; - - /** - * greebo: A frobbed entity might receive this signal if the player is hitting - * the attack button in this exact frame. (Used for lockpicking.) - * - * The player responsible for this action is passed as argument. - */ - virtual void AttackAction(idPlayer* player); - - /** - * greebo: Returns TRUE if the given inventory item matches this entity, i.e. - * if the entity can be used by the given inventory item, FALSE otherwise. - * Note: This just routes the call to the overloaded CanBeUsedBy(idEntity*); - * - * @isFrobUse: This is true if the Use action originated from a frob button hit. - */ - virtual bool CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse); - - /** - * greebo: Returns TRUE if the given entity matches this entity, i.e. - * if the entity can be used by the given entity, FALSE otherwise. - * If a frob_master was set, the call is redirected to that one. - * - * @isFrobUse: This is true if the Use action originated from a frob button hit. - * - * The standard entity returns FALSE, this method needs to be overridden - * by the subclasses. - */ - virtual bool CanBeUsedBy(idEntity* entity, const bool isFrobUse); - - /** - * greebo: Uses this entity by the given inventory item. The button state - * is needed to handle the exact user interaction, e.g. while lockpicking. - * If a frob_master was set, the call is redirected to that one. - * - * @returns: TRUE if the item could be used, FALSE otherwise. - */ - virtual bool UseBy(EImpulseState nState, const CInventoryItemPtr& item); - - /** - * Toggle whether the entity has been frobbed. Should ONLY be called by idPlayer::PerformFrobCheck - **/ - virtual void SetFrobbed( bool val ); - - /** - * Set whether this entity is frobable or not - **/ - virtual void SetFrobable( bool val ); - - /** - * Return whether the entity is currently frobbed. - * Should be false at the beginning of the frame - **/ - virtual bool IsFrobbed( void ); - - /** - * DarkMod sound prop functions (called by StartSound and StopSound) - **/ - - /** - * The following two functions propagate either a suspicious or - * an environmental sound. They are called by idEntity::StartSound. - * - * The parameters are the local sound name (ie, the name in the entity - * def file, INCLUDING the "snd_" at the beginning), and the global sound - * name (name in the soundprop def file, NOT including the prefix) - * - * (For now sounds can be suspicious or environmental, but not both. - * defining a sound as suspicious overrides any environmental def - * with the same sound name. ) - **/ - - /** - * Propagate a suspicious sound - **/ - void PropSoundS( const char *localName, const char *globalName, float VolModIn = 0.0f ); - - /** - * Propagate an environmental sound (called by PropSound) - **/ - void PropSoundE( const char *localName, const char *globalName, float VolModIn = 0.0f ); - - /** - * Propagate a sound directly, outside of StartSound - * Direct calling should be done in cases where the gamecode calls - * StartSoundShader directly, without going thru StartSound. - * - * PropSoundDirect first looks for a local definition of the sound - * on the entity, to find volume/duration modifier, extra flags - * and the "global" sound definition (in the sound def file) - * - * If the local definition is not found, it calls sound prop - * with the unmodified global definition. - * - * VolModIn is a modifier in dB added to the volume, in addition to - * any modifier that might be present in the local sound def. - **/ - void PropSoundDirect( const char *sndName, bool bForceLocal = false, - bool bAssumeEnv = false, float VolModIn = 0.0f ); - - CStimResponseCollection *GetStimResponseCollection(void) { return m_StimResponseColl; }; - - /** - * greebo: This allows an entity to "relay" the response to another entity. - * The default implementation of this virtual function returns the pointer, - * but subclasses may return any other entity (but not NULL!). - * - * Example: idAFAttachments return their "body" entity as response entity. - */ - virtual idEntity* GetResponseEntity() { return this; }; - - // Returns (and creates if necessary) this entity's inventory. - const CInventoryPtr& Inventory(); - // Returns (and creates if necessary) this entity's inventory cursor. - const CInventoryCursorPtr& InventoryCursor(); - - /** - * greebo: This is called when an objective location adds this entity - * to its list and starts tracking it. - */ - void OnAddToLocationEntity(CObjectiveLocation* locationEnt); - - /** - * greebo: This is called when an objective location removes this entity - * from its internal list and stops tracking it. - */ - void OnRemoveFromLocationEntity(CObjectiveLocation* locationEnt); - - /** - * greebo: This event gets fired right after spawn time. It checks the spawnargs - * and adds itself to someone else's inventory on demand. If the target entity - * is not found, the event postpones itself by a few hundred msec. - * The optional count argument takes care that this doesn't happen too often. - */ - void Event_InitInventory(int callCount = 0); - - /** - * CreateOverlay will create an overaly for the given entity. This is a hud element - * that displays some objects on the screen. The default is for the playerscreen - * to show the inventory items and other stats. However, each entity can have his own - * hud which allows him to add a custom display for inventory items. - */ - void Event_CreateOverlay( const char *guiFile, int layer ); - int CreateOverlay( const char *guiFile, int layer ); - - /** - * greebo: DestroyOverlay removes the overlay from this entity. Pass the handle - * as argument, it's the returned by CreateOverlay. - */ - void Event_DestroyOverlay(int handle); - void DestroyOverlay(int handle); - - // Returns the GUI with the given handle or NULL if not found - idUserInterface* GetOverlay(int handle); - - /** - * Generic function for calling a scriptfunction with arbitrary arguments. - * The the thread is returned or NULL. - */ - idThread *CallScriptFunctionArgs(const char *ScriptFunction, bool ClearStack, int Delay, const char *Format, ...); - - /** - * Attach another entity to this entity. The base version assumes single-clipmodel - * rigid body physics and simply calls idEntity::Bind. - * Will be overloaded in derived classes with joints to call BindToJoint. - * The position argument is an optional named attachment position - * Attachment name is the string name for future lookups, not actually used by idEntity - * but used in derived classes. - **/ - virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); - - /** - * Detach the attachment of that name. - * Note that to preserve the name->index mapping, the entry for - * the detached object stays in the m_Attachments list, but the entity - * field gets set to NULL so that it's skipped over in various operations - * NOTE: This could lead to memory hogging if something gets detached/attached - * many times. - **/ - virtual void Detach( const char *AttName ); - - /** - * Detach by index in the m_Attachments array. Otherwise same as above - **/ - virtual void DetachInd( int ind ); - - /** - * Reattach an existing attachment to the given offset and angles relative - * to the origin and orientatin of the entity - * - * A different version taking a joint argument exists on idAnimatedEntity - * for things with MD5 structures - **/ - virtual void ReAttachToCoords( const char *AttName, const idVec3 offset, const idAngles angles ); - - /** - * Reattach to a predefined attach position, otherwise same as above - **/ - virtual void ReAttachToPos( const char *AttName, const char *PosName ); - - /** - * Show or hide an attachment, by name or by attachment array index. - **/ - void ShowAttachment( const char *AttName, bool bShow ); - void ShowAttachmentInd( int ind, bool bShow ); - - /** - * Returns an entity pointer for a given attachment name. - * Returns NULL if no such named attachment exists on this entity. - **/ - virtual idEntity *GetAttachment( const char *AttName ); - - /** - * Returns an entity pointer for a given index of the attachment array. - * Returns NULL if no such named attachment exists directly on this entity. - **/ - virtual idEntity *GetAttachment( int ind ); - - /** - * Helper function that looks up the attachment index from the name->index map - * Returns -1 if the index is not present in the map or if it's out of bounds - * of the m_Attachments array. - **/ - virtual int GetAttachmentIndex( const char *AttName ); - - /** - * Returns an entity pointer for a given attachment name. - * Returns NULL if no such named attachment exists on this entity, - * or on any entity attached to this entity. - **/ - virtual idEntity *GetAttachmentFromTeam( const char *AttName ); - - - /** - * Returns a pointer to the attachment info structure for a given attachment. - * Returns NULL if no such named attachment exists on this entity. - **/ - virtual CAttachInfo *GetAttachInfo( const char *AttName ); - - /** - * Returns a pointer to the attachment position with this name. - * Returns NULL if no attachment position exists with this name. - **/ - virtual SAttachPosition *GetAttachPosition( const char *AttachName ); - - /** - * Store the attachment info in the argument references given. - * Returns false if the attachment index was invalid. - **/ - bool PrintAttachInfo( int ind, idStr &joint, idVec3 &offset, idAngles &angles ); - - /** - * Called when the given entity is about to attach (bind) to this entity. - * Does not actually bind it. - **/ - virtual void BindNotify( idEntity *ent ); - - /** - * Called when the given entity is about to detach (unbind) from this entity. - * Does not actually unbind it. - **/ - virtual void UnbindNotify( idEntity *ent ); - - /** - * Return nonzero if this entity could potentially attack the given (target) entity at range, - * or entities in general if target is NULL. - */ - virtual float RangedThreatTo(idEntity* target); - - /** - * AddToInventory will add an entity to the inventory. The item is only - * added if the appropriate spawnargs are set, otherwise it will be rejected - * and NULL is returned. - */ - virtual CInventoryItemPtr AddToInventory(idEntity *ent); - - // Cycles to the prev/next item in the inventory. - // direction<0 - cycles to previous, direction>0 - cycles to next - virtual void NextPrevInventoryItem(int direction); - // Cycles to the prev/next group in the inventory. - // direction<0 - cycles to previous, direction>0 - cycles to next - virtual void NextPrevInventoryGroup(int direction); - - /** - * greebo: This cycles through a specific inventory group (=category). - * If the cursor is already pointing to an item in the given group, it is advanced to the next item. - * If the cursor has reached the "end" of the group, it is set back to the first item. - * If the cursor is currently not pointing to an item of the given group, it is set to the - * first item in that group. - */ - virtual void CycleInventoryGroup(const idStr& groupName); - - // Gets called when the inventory cursor has changed its selection focus - virtual void OnInventorySelectionChanged(const CInventoryItemPtr& prevItem = CInventoryItemPtr()); - - /** - * greebo: Gets called when anything within the inventory has been altered (item count, item icon) - * This does NOT get called when the selection changes, only the inventory's contents. - */ - virtual void OnInventoryItemChanged(); - - /** - * Changes the inventory count of the given item in by - */ - void ChangeInventoryItemCount(const char* invName, const char* invCategory, int amount); - - /** - * Changes the amount of the given loot type in the inventory of this entity. - * @returns: the new amount of the affected loot type. - */ - int ChangeLootAmount(int lootType, int amount); - - /** - * greebo: This replaces the inventory item (represented by oldItem) with the - * given entity. needs to be a valid inventory item entity or NULL. - * - * is removed from the inventory and will take its position, provided - * both items share the same category name. If the categories are different, the position - * can not be guaranteed to be the same after the operation. - * - * If is NULL, will just be removed and no replacement takes place. - * - * @returns TRUE on success, FALSE otherwise. - */ - bool ReplaceInventoryItem(idEntity* oldItem, idEntity* newItem); - - /** - * Script event: Changes the lightgem modifier value of the given item in to - */ - void ChangeInventoryIcon(const char* invName, const char* invCategory, const char* icon); - - /** - * Script event: Changes the lightgem modifier value of the given item in to - */ - void ChangeInventoryLightgemModifier(const char* invName, const char* invCategory, int value); - - /** - * Return true if this entity can be mantled, false otherwise. - */ - virtual bool IsMantleable(); - - // Accessors for the frob peer list - virtual void AddFrobPeer(const idStr& frobPeerName); - virtual void AddFrobPeer(idEntity* peer); - virtual void RemoveFrobPeer(const idStr& frobPeerName); - virtual void RemoveFrobPeer(idEntity* peer); - - // Returns the frob master for this entity or NULL if not set (or not existing anymore). - idEntity* GetFrobMaster(); - - inline UserManager& GetUserManager() - { - return m_userManager; - } - - // Stim/Response methods - CStimPtr AddStim(StimType type, float radius = 0.0f, bool removable = true, bool isDefault = false); - CResponsePtr AddResponse(StimType type, bool removable = true, bool isDefault = false); - - /** - * RemoveStim/Response removes the given stim. If the entity has no - * stims/responses left, it is also removed from the global list in gameLocal. - */ - void RemoveStim(StimType type); - void RemoveResponse(StimType type); - - void IgnoreResponse(StimType type, idEntity* fromEntity); - void AllowResponse(StimType type, idEntity* fromEntity); - - void EnableResponse(StimType type) { SetResponseEnabled(type, true); } - void DisableResponse(StimType type) { SetResponseEnabled(type, false); } - - // Enables / disables the given response - void SetResponseEnabled(StimType type, bool enabled); - - void EnableStim(StimType type) { SetStimEnabled(type, true); } - void DisableStim(StimType type) { SetStimEnabled(type, false); } - - void SetStimEnabled(StimType type, bool enabled); - - void ClearStimIgnoreList(StimType type); - - bool CheckResponseIgnore(StimType type, idEntity* fromEntity); // grayman #2872 - - - /** - * This triggers a stand-alone response (without an actual Stim) on this entity. - * - * @source: The entity that caused the response. - * @stimType: the according stim index (e.g. ST_FROB) - */ - void TriggerResponse(idEntity* source, StimType type); - - // greebo: Callback invoked by the response on incoming stims to trigger custom code - // To be overridden by subclasses, default implementation is empty - virtual void OnStim(const CStimPtr& stim, idEntity* stimSource) - { } - - /** - * greebo: Script events to get/set the team of this entity. - */ - void Event_GetTeam(); - void Event_SetTeam(int newTeam); - - void Event_IsEnemy( idEntity *ent ); - void Event_IsFriend( idEntity *ent ); - void Event_IsNeutral( idEntity *ent ); - - void Event_SetEntityRelation (idEntity* entity, int relation); - void Event_ChangeEntityRelation(idEntity* entity, int relationChange); - - - int team; - - // angua: entities can have personal relationships to other entities that are used instead of the team relations. - typedef std::map EntityRelationsMap; - EntityRelationsMap m_EntityRelations; - - // angua: set a relation to another entity - // this can be friendly (>0), neutral(0) or hostile (<0) - void SetEntityRelation(idEntity* entity, int relation); - - // angua: this changes the current relation to an entity by adding the new amount - void ChangeEntityRelation(idEntity* entity, int relationChange); - - /** - * Checks with the global Relationship Manager and the personal relations to see if the - * other entity is an enemy of this entity. - **/ - bool IsEnemy(const idEntity *other); - // As above, but checks for Friend - bool IsFriend(const idEntity *other); - // As above, but checks for Neutral - bool IsNeutral(const idEntity *other); - - - float GetAbsenceNoticeability(); - - // angua: this checks whether an entity has been removed or returned to the original position - // and spawns or destroys an absence marker - void Event_CheckAbsence(); - bool SpawnAbsenceMarker(); - bool DestroyAbsenceMarker(); - - // Saves the CONTENTS values of all attachments - void SaveAttachmentContents(); - - // Sets all attachment contents to the given value - void SetAttachmentContents(int newContents); - - // Restores all CONTENTS values, previously saved with SaveAttachmentContents() - void RestoreAttachmentContents(); - -protected: - /** - * Update frob highlight state if frobbed. - * Clears highlight state if it's no longer frobbed. - * Called in idEntity::Present - **/ - void UpdateFrobState(); - - /** - * This controls the shader parms for the frob highlighting, - * according to the frob highlight state. Includes fading algorithms. - * Called in idEntity::Present(). - **/ - void UpdateFrobDisplay(); - - /** - * Activate/deactivate frob highlighting on an entity - * Also calls this on any of the entity's peers - **/ - void SetFrobHighlightState( bool bVal ); - - /** - * Call ParseAttachmentSpawnargs, spawns the attachements and binds them on to the entity. - **/ - virtual void ParseAttachments( void ); - - /** - * Parse attachment positions from the spawnargs - **/ - virtual void ParseAttachPositions( void ); - - /** - * Bind to the same object that the "other" argument is bound to - **/ - void Event_CopyBind( idEntity *other ); - - /** - * Returns the bindmaster - **/ - void Event_GetBindMaster( void ); - - /** - * Return the number of bind team members lower in the chain than this one - **/ - void Event_NumBindChildren( void ); - /** - * Return the ind_th bind team member - **/ - void Event_GetBindChild( int ind ); - -protected: - renderEntity_t renderEntity; //!< used to present a model to the renderer - int modelDefHandle; //!< handle to static renderer model - refSound_t refSound; //!< used to present sound to the audio engine - idStr brokenModel; //!< model set when health drops down to or below zero - - /** - * List storing attachment data for each attachment - **/ - idList m_Attachments; - - /** - * Maps string name of an attachment to an index in m_Attachments - **/ - typedef std::map AttNameMap; - AttNameMap m_AttNameMap; - - /** - * List of predefined attachment positions for this entity - * If the entity doesn't have joints, positions are relative to origin - **/ - idList m_AttachPositions; - - /** - * Used to keep track of the GUIs used by this entity. - **/ - COverlaySys m_overlays; - - /** - * This is set by idPlayer if the player is looking at the entity in a way - * that will frob it. - **/ - bool m_bFrobbed; - - /** - * This is separate from m_bFrobbed due to peer frob highlighting, - * to let an entity display the highlight when not frobbed. - **/ - bool m_bFrobHighlightState; - - /** - * Timestamp indicating when the frob highlight last changed - * Used for continuous fade in and fade out. - **/ - int m_FrobChangeTime; - - /** - * FrobActionScript will contain the name of the script that is to be - * exected whenever a frobaction occurs. The default should be set by - * the constructor of the respective derived class but can be overriden - * by the property "frob_action_script" in the entity definition file. - */ - idStr m_FrobActionScript; - - /** - * FrobPeers lists the names of other entites that will also be - * frobbed when this entity is frobbed. - */ - idStrList m_FrobPeers; - - /** - * This contains the name of the "master" entity. If this entity receives - * an incoming FrobAction or inventory item usage, the action is redirected - * to the frob master. - */ - idStr m_MasterFrob; - - // Is set to TRUE once the frob action function is entered on this entity. Prevents stack overflows. - bool m_FrobActionLock; - - CStimResponseCollection *m_StimResponseColl; - - float m_AbsenceNoticeability; - idBounds m_StartBounds; - bool m_AbsenceStatus; - idEntityPtr m_AbsenceMarker; - - bool m_bIsMantleable; - - /** - * Set to true when entity becomes broken (via damage) - **/ - bool m_bIsBroken; - - /** Used to implement waitForRender()... - * This merely contains a bounding box and a callback. - */ - renderEntity_t m_renderTrigger; - /// The render world handle for m_renderTrigger. - int m_renderTriggerHandle; - /// The thread that's waiting for this entity to render. (via waitForRender()) - int m_renderWaitingThread; - - /** Called when m_renderTrigger is rendered. - * It will resume the m_renderWaitingThread. - */ - static bool WaitForRenderTriggered( renderEntity_s* renderEntity, const renderView_s* view ); - /** Called to update m_renderTrigger after the render entity is modified. - * Only updates the render trigger if a thread is waiting for it. - */ - void PresentRenderTrigger(); - - /** - * Set and get whether the entity is frobable - * Note: IsFrobable is only used by scripting, since we can check public var m_bFrobable - **/ - void Event_IsFrobable( void ); - void Event_SetFrobable( bool bVal ); - void Event_IsHilighted( void ); - - // Frobs this entity. - void Event_Frob(); - // Frobhighlights this entity or turns it off - void Event_FrobHilight( bool bVal ); - - // angua: List of actors that currently use this entity - UserManager m_userManager; - -private: - idPhysics_Static defaultPhysicsObj; // default physics object - idPhysics * physics; // physics used for this entity - /** - * TDM: Clipmodel for frobbing only (used to make frobbing easier without effecting physics) - **/ - idClipModel * m_FrobBox; - idEntity * bindMaster; // entity bound to if unequal NULL - jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT - int bindBody; // body bound to if unequal -1 - idEntity * teamMaster; // master of the physics team - idEntity * teamChain; // next entity in physics team - - int numPVSAreas; // number of renderer areas the entity covers - int PVSAreas[MAX_PVS_AREAS];// numbers of the renderer areas the entity covers - - signalList_t * signals; - - int mpGUIState; // local cache to avoid systematic SetStateInt - - // A pointer to our inventory. - CInventoryPtr m_Inventory; - - // A pointer to our cursor - the cursor is for arbitrary use, and may not point to our own inventory. - CInventoryCursorPtr m_InventoryCursor; - - // Information about the most recent voice and body sound requests. grayman - #2341 - idSoundShader * previousVoiceShader; // shader for the most recent voice request (safe because shader pointers are constant, being decls) - int previousVoiceIndex; // index of most recent voice sound requested (1->N, where there are N sounds in the shader) - idSoundShader * previousBodyShader; // shader for the most recent body request (safe because shader pointers are constant, being decls) - int previousBodyIndex; // index of most recent body sound requested (1->N, where there are N sounds in the shader) -private: - void FixupLocalizedStrings(); - - bool DoDormantTests( void ); // dormant == on the active list, but out of PVS - - // physics - // initialize the default physics - void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis ); - // update visual position from the physics - void UpdateFromPhysics( bool moveBack ); - - // entity binding - bool InitBind( idEntity *master ); // initialize an entity binding - void FinishBind( void ); // finish an entity binding - void RemoveBinds( void ); // deletes any entities bound to this object - void QuitTeam( void ); // leave the current team - - void UpdatePVSAreas( void ); - -public: // Events should be public, so they can be used from other places as well. - // events - void Event_GetName( void ); - void Event_SetName( const char *name ); - void Event_IsType ( const char *pstr_typeName ); - void Event_FindTargets( void ); - void Event_ActivateTargets( idEntity *activator ); - void Event_AddTarget(idEntity* target); - void Event_RemoveTarget(idEntity* target); - void Event_NumTargets( void ); - void Event_GetTarget( float index ); - void Event_RandomTarget( const char *ignore ); - void Event_Bind( idEntity *master ); - void Event_BindPosition( idEntity *master ); - void Event_BindToJoint( idEntity *master, const char *jointname, float orientated ); - void Event_BindToBody( idEntity *master, int bodyId, bool orientated ); - void Event_Unbind( void ); - void Event_RemoveBinds( void ); - void Event_SpawnBind( void ); - void Event_SetOwner( idEntity *owner ); - void Event_SetModel( const char *modelname ); - void Event_SetSkin( const char *skinname ); - void Event_GetShaderParm( int parmnum ); - void Event_SetShaderParm( int parmnum, float value ); - void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 ); - void Event_SetColor( float red, float green, float blue ); - void Event_GetColor( void ); - void Event_IsHidden( void ); - void Event_Hide( void ); - void Event_Show( void ); - void Event_CacheSoundShader( const char *soundName ); - void Event_StartSoundShader( const char *soundName, int channel ); - void Event_StopSound( int channel, int netSync ); - void Event_StartSound( const char *soundName, int channel, int netSync ); - void Event_FadeSound( int channel, float to, float over ); - void Event_SetSoundVolume( float to ); - void Event_GetWorldOrigin( void ); - void Event_SetWorldOrigin( idVec3 const &org ); - void Event_GetOrigin( void ); - void Event_SetOrigin( const idVec3 &org ); - void Event_GetAngles( void ); - void Event_SetAngles( const idAngles &ang ); - void Event_SetLinearVelocity( const idVec3 &velocity ); - void Event_GetLinearVelocity( void ); - void Event_SetAngularVelocity( const idVec3 &velocity ); - void Event_GetAngularVelocity( void ); - - void Event_SetContents(const int contents); - void Event_GetContents(); - void Event_SetClipMask(const int clipMask); - void Event_GetClipMask(); - - void Event_SetSize( const idVec3 &mins, const idVec3 &maxs ); - void Event_GetSize( void ); - void Event_GetMins( void ); - void Event_GetMaxs( void ); - void Event_Touches( idEntity *ent ); - void Event_GetNextKey( const char *prefix, const char *lastMatch ); - void Event_SetKey( const char *key, const char *value ); - void Event_GetKey( const char *key ); - void Event_GetIntKey( const char *key ); - void Event_GetFloatKey( const char *key ); - void Event_GetVectorKey( const char *key ); - void Event_GetEntityKey( const char *key ); - void Event_RemoveKey( const char *key ); - void Event_RestorePosition( void ); - void Event_UpdateCameraTarget( void ); - void Event_DistanceTo( idEntity *ent ); - void Event_DistanceToPoint( const idVec3 &point ); - void Event_StartFx( const char *fx ); - void Event_WaitFrame( void ); - void Event_Wait( float time ); - void Event_HasFunction( const char *name ); - void Event_CallFunction( const char *name ); - void Event_CallGlobalFunction( const char *funcname, idEntity *ent ); - void Event_SetNeverDormant( int enable ); - - /** - * greebo: Extinguishes all lights in the teamchain, including self. - */ - void Event_ExtinguishLights(); - - void Event_InPVS( void ); - void Event_WaitForRender( void ); - - /** - * greebo: This is the method that can be invoked from scripts. It basically - * passes the call to the member method Damage(). - * - * This Deals damage to this entity (gets translated into the idEntity::Damage() method within the SDK). - * - * @inflictor: This is the entity causing the damage (maybe a projectile) - * @attacker: This is the "parent" entity of the inflictor, the one that is responsible for the inflictor (can be the same) - * @dir: The direction the attack is coming from. - * @damageDefName: The name of the damage entityDef to know what damage is being dealt to (e.g. "damage_lava") - * @damageScale: The scale of the damage (pass 1.0 as default, this should be ok). - */ - void Event_Damage( idEntity *inflictor, idEntity *attacker, - const idVec3 &dir, const char *damageDefName, - const float damageScale ); - /** - * greebo: This method heals this entity using the values defined in the - * the entityDef specified by . - */ - void Event_Heal( const char *healDefName, const float healScale ); - void Event_SetGui( int handle, const char *guiFile ); - void Event_GetGui( int handle ); - void Event_SetGuiString( int handle, const char *key, const char *val ); - void Event_GetGuiString( int handle, const char *key ); - void Event_SetGuiFloat( int handle, const char *key, float f ); - void Event_GetGuiFloat( int handle, const char *key ); - void Event_SetGuiInt( int handle, const char *key, int n ); - void Event_GetGuiInt( int handle, const char *key ); - void Event_SetGuiStringFromKey( int handle, const char *key, idEntity *src, const char *spawnArg ); - void Event_CallGui( int handle, const char *namedEvent ); - - /** - * Tels: Teleport the entity to the given entity's origin and orientation. - */ - void Event_TeleportTo(idEntity *target); - /** - * Get/set droppable on this entity and its inventory item if it's already in the inventory - **/ - void Event_IsDroppable(); - void Event_SetDroppable( bool Droppable ); - /** - * Tels: Return the sum of all lights in the entities PVS. - */ - void Event_GetLightInPVS( const float lightFalloff, const float lightDistScale); - - /** - * Tels: Toggle the noShadow flag on this entity. - */ - void Event_noShadows( bool noShadow ); - - void Event_CheckMine(); // grayman #2478 - - void Event_GetVinePlantLoc(); // grayman #2787 - void Event_GetVinePlantNormal(); // grayman #2787 - - void Event_LoadExternalData( const char *xdFile, const char* prefix ); - - void Event_GetInventory(); - - void Event_GetLootAmount(int lootType); - void Event_ChangeLootAmount(int lootType, int amount); - void Event_AddInvItem(idEntity* ent); - // Tels: The reverse of AddInvItem() - void Event_AddItemToInv(idEntity* ent); - void Event_ReplaceInvItem(idEntity* oldItem, idEntity* newItem); - void Event_GetNextInvItem(); - void Event_GetPrevInvItem(); - void Event_SetCurInvCategory(const char* categoryName); - void Event_SetCurInvItem(const char* itemName); - void Event_GetCurInvCategory(); - void Event_GetCurInvItemEntity(); - void Event_GetCurInvItemName(); - void Event_GetCurInvItemId(); - void Event_GetCurInvIcon(); - - // tels: remove all bound entities that have "unbindonalertlevel" higher or equal than alertlevel - void RemoveBindsOnAlert( const int alertIndex ); - void DetachOnAlert( const int alertIndex ); - - // Stim/Response Script Event Interface - void Event_StimAdd(int stimType, float radius); - void Event_StimRemove(int stimType); - void Event_StimEnable(int stimType, int state); - void Event_StimClearIgnoreList(int stimType); - void Event_ResponseAdd(int stimType); - void Event_ResponseRemove(int stimType); - void Event_ResponseEnable(int stimType, int State); - void Event_ResponseTrigger(idEntity* source, int stimType); - void Event_ResponseIgnore(int stimType, idEntity*); - void Event_ResponseAllow(int stimType, idEntity*); - void Event_ResponseSetAction(int stimType, const char* action); - void Event_GetResponseEntity(); - - void Event_TimerCreate(int StimType, int Hour, int Minute, int Seconds, int Milisecond); - void Event_TimerStop(int StimType); - void Event_TimerStart(int StimType); - void Event_TimerRestart(int StimType); - void Event_TimerReset(int StimType); - void Event_TimerSetState(int StimType, int State); - - /** - * Used to propagate a sound directly via scripting, without playing the audible sound - * VolModIn is a volume modifier added to the sound's volume. - **/ - void Event_PropSoundMod( const char *sndName, float VolModIn = 0.0 ); - - void Event_PropSound( const char *sndName ); - -#ifdef MOD_WATERPHYSICS - - void Event_GetMass( int body ); // MOD_WATERPHYSICS - - void Event_IsInLiquid( void ); // MOD_WATERPHYSICS - -#endif // MOD_WATERPHYSICS - - void Event_RangedThreatTo(idEntity*); - - /** - * greebo: Returns true if the target entity can be seen - * - * @useLighting: If set to TRUE, takes lighting into account. - */ - bool canSeeEntity(idEntity* target, int useLighting); - - /** - * greebo: script event wrapper for the above canSeeEntity() method. - */ - void Event_CanSeeEntity(idEntity* target, int useLighting); - - /** - * ishtvan: Let script acces CanBeUsedBy on this entity - **/ - void Event_CanBeUsedBy(idEntity *itemEnt); - -public: // events that need to have an accessible counterpart - void SetGuiString(int handle, const char *key, const char *val); - const char *GetGuiString(int handle, const char *key); - void SetGuiFloat(int handle, const char *key, float f); - float GetGuiFloat(int handle, const char *key); - void SetGuiInt(int handle, const char *key, int n); - int GetGuiInt(int handle, const char *key); - void CallGui(int handle, const char *namedEvent); -}; - -/* -=============================================================================== - - Animated entity base class. - -=============================================================================== -*/ - -typedef struct damageEffect_s { - jointHandle_t jointNum; - idVec3 localOrigin; - idVec3 localNormal; - int time; - const idDeclParticle* type; - struct damageEffect_s * next; -} damageEffect_t; - -class idAnimatedEntity : public idEntity -{ -public: - CLASS_PROTOTYPE( idAnimatedEntity ); - - idAnimatedEntity(); - ~idAnimatedEntity(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); //TDM: added so that we can cache anim rates - - virtual void ClientPredictionThink( void ); - virtual void Think( void ); - - void UpdateAnimation( void ); - - virtual idAnimator * GetAnimator( void ); - virtual void SetModel( const char *modelname ); - - bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ); - bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const; - - virtual int GetDefaultSurfaceType( void ) const; - virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); - void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial ); - void UpdateDamageEffects( void ); - - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - /** - * Overloads idEntity::Attach to bind to a joint - * AttName is the optional name of the attachment for indexing purposes (e.g., "melee_weapon") - * Ent is the entity being attached - * PosName is the optional position name to attach to. - **/ - virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); - - /** - * Reattach an existing attachment - * - * The next arguments are the name of the joint to attach to, the translation - * offset from that joint, and a (pitch, yaw, roll) angle vector that defines the - * rotation of the attachment relative to the joint's orientation. - **/ - virtual void ReAttachToCoords( const char *AttName, idStr jointName, idVec3 offset, idAngles angles ); - - /** - * Cache the animation rates from spawnargs - * Always called at spawn, sometimes called later if spawnargs changed and rates need recaching - **/ - virtual void CacheAnimRates( void ); - - - /** - * Tels: Return the position of the joint (by name) in world coordinates - **/ - idVec3 GetJointWorldPos( const char *jointname ); - - /** - * Tels: Return the entity closest to the given joint, excluding itself. AIUseType is something - * like "AIUSE_FOOD" and only entites that have the spawnarg "AIUse" "AIUSE_FOOD" will be - * considered. From all these entities, the one closest to the joint is returned, or NULL - * if no such entity could be found. Called from GetEntityClosestToJoint(). - **/ - idEntity* GetEntityFromClassClosestToJoint( const idVec3 joint_origin, const char* AIUseType, const float max_dist_sqr ); - - /** - * Tels: Return the entity closest to the given joint, excluding itself. entitySelector is either - * a direct entity name or something like "AIUSE_FOOD". First we look at all spawnargs with - * prefix "prefix", and if these all fail to produce an entity, fall back to entitySelector. - * Returns NULL if no suitable entity could be found. - **/ - idEntity* GetEntityClosestToJoint( const char* jointname, const char* entitySelector, const char* prefix, const float max_dist ); - - enum { - EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS, - EVENT_MAXEVENTS - }; - -protected: - /** - * Used internally by the Attach methods. - * Offset and axis are filled with the correct offset and axis - * for attaching to a particular joint. - * Calls GetJointWorldTransform on idAnimated entities. - **/ - virtual void GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); - -protected: - idAnimator animator; - damageEffect_t * damageEffects; - - // The game time UpdateAnimation() has been called the last time - int lastUpdateTime; - -private: - void Event_GetJointHandle( const char *jointname ); - void Event_ClearAllJoints( void ); - void Event_ClearJoint( jointHandle_t jointnum ); - void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ); - void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ); - void Event_GetJointPos( jointHandle_t jointnum ); - void Event_GetJointAngle( jointHandle_t jointnum ); -}; - -#endif /* !__GAME_ENTITY_H__ */ diff --git a/game/fx.cpp b/game/fx.cpp deleted file mode 100644 index cce24f5f4..000000000 --- a/game/fx.cpp +++ /dev/null @@ -1,782 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -=============================================================================== - - idEntityFx - -=============================================================================== -*/ - -const idEventDef EV_Fx_KillFx( "_killfx" ); -const idEventDef EV_Fx_Action( "_fxAction", "e" ); // implemented by subclasses - -CLASS_DECLARATION( idEntity, idEntityFx ) -EVENT( EV_Activate, idEntityFx::Event_Trigger ) -EVENT( EV_Fx_KillFx, idEntityFx::Event_ClearFx ) -END_CLASS - - -/* -================ -idEntityFx::Save -================ -*/ -void idEntityFx::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( started ); - savefile->WriteInt( nextTriggerTime ); - savefile->WriteFX( fxEffect ); - savefile->WriteString( systemName ); - - savefile->WriteInt( actions.Num() ); - - for ( i = 0; i < actions.Num(); i++ ) { - - if ( actions[i].lightDefHandle >= 0 ) { - savefile->WriteBool( true ); - savefile->WriteRenderLight( actions[i].renderLight ); - } else { - savefile->WriteBool( false ); - } - - if ( actions[i].modelDefHandle >= 0 ) { - savefile->WriteBool( true ); - savefile->WriteRenderEntity( actions[i].renderEntity ); - } else { - savefile->WriteBool( false ); - } - - savefile->WriteFloat( actions[i].delay ); - savefile->WriteInt( actions[i].start ); - savefile->WriteBool( actions[i].soundStarted ); - savefile->WriteBool( actions[i].shakeStarted ); - savefile->WriteBool( actions[i].decalDropped ); - savefile->WriteBool( actions[i].launched ); - } -} - -/* -================ -idEntityFx::Restore -================ -*/ -void idEntityFx::Restore( idRestoreGame *savefile ) { - int i; - int num; - bool hasObject; - - savefile->ReadInt( started ); - savefile->ReadInt( nextTriggerTime ); - savefile->ReadFX( fxEffect ); - savefile->ReadString( systemName ); - - savefile->ReadInt( num ); - - actions.SetNum( num ); - for ( i = 0; i < num; i++ ) { - - savefile->ReadBool( hasObject ); - if ( hasObject ) { - savefile->ReadRenderLight( actions[i].renderLight ); - actions[i].lightDefHandle = gameRenderWorld->AddLightDef( &actions[i].renderLight ); - } else { - memset( &actions[i].renderLight, 0, sizeof( renderLight_t ) ); - actions[i].lightDefHandle = -1; - } - - savefile->ReadBool( hasObject ); - if ( hasObject ) { - savefile->ReadRenderEntity( actions[i].renderEntity ); - actions[i].modelDefHandle = gameRenderWorld->AddEntityDef( &actions[i].renderEntity ); - } else { - memset( &actions[i].renderEntity, 0, sizeof( renderEntity_t ) ); - actions[i].modelDefHandle = -1; - } - - savefile->ReadFloat( actions[i].delay ); - - // let the FX regenerate the particleSystem - actions[i].particleSystem = -1; - - savefile->ReadInt( actions[i].start ); - savefile->ReadBool( actions[i].soundStarted ); - savefile->ReadBool( actions[i].shakeStarted ); - savefile->ReadBool( actions[i].decalDropped ); - savefile->ReadBool( actions[i].launched ); - } -} - -/* -================ -idEntityFx::Setup -================ -*/ -void idEntityFx::Setup( const char *fx ) { - - if ( started >= 0 ) { - return; // already started - } - - // early during MP Spawn() with no information. wait till we ReadFromSnapshot for more - if ( gameLocal.isClient && ( !fx || fx[0] == '\0' ) ) { - return; - } - - systemName = fx; - started = 0; - - fxEffect = static_cast( declManager->FindType( DECL_FX, systemName.c_str() ) ); - - if ( fxEffect ) { - idFXLocalAction localAction; - - memset( &localAction, 0, sizeof( idFXLocalAction ) ); - - actions.AssureSize( fxEffect->events.Num(), localAction ); - - for( int i = 0; ievents.Num(); i++ ) { - const idFXSingleAction& fxaction = fxEffect->events[i]; - - idFXLocalAction& laction = actions[i]; - if ( fxaction.random1 || fxaction.random2 ) { - laction.delay = fxaction.random1 + gameLocal.random.RandomFloat() * ( fxaction.random2 - fxaction.random1 ); - } else { - laction.delay = fxaction.delay; - } - laction.start = -1; - laction.lightDefHandle = -1; - laction.modelDefHandle = -1; - laction.particleSystem = -1; - laction.shakeStarted = false; - laction.decalDropped = false; - laction.launched = false; - } - } -} - -/* -================ -idEntityFx::EffectName -================ -*/ -const char *idEntityFx::EffectName( void ) { - return fxEffect ? fxEffect->GetName() : NULL; -} - -/* -================ -idEntityFx::Joint -================ -*/ -const char *idEntityFx::Joint( void ) { - return fxEffect ? fxEffect->joint.c_str() : NULL; -} - -/* -================ -idEntityFx::CleanUp -================ -*/ -void idEntityFx::CleanUp( void ) { - if ( !fxEffect ) { - return; - } - for( int i = 0; i < fxEffect->events.Num(); i++ ) { - const idFXSingleAction& fxaction = fxEffect->events[i]; - idFXLocalAction& laction = actions[i]; - CleanUpSingleAction( fxaction, laction ); - } -} - -/* -================ -idEntityFx::CleanUpSingleAction -================ -*/ -void idEntityFx::CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ) { - if ( laction.lightDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHLIGHT ) { - gameRenderWorld->FreeLightDef( laction.lightDefHandle ); - laction.lightDefHandle = -1; - } - if ( laction.modelDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHENTITY ) { - gameRenderWorld->FreeEntityDef( laction.modelDefHandle ); - laction.modelDefHandle = -1; - } - laction.start = -1; -} - -/* -================ -idEntityFx::Start -================ -*/ -void idEntityFx::Start( int time ) { - if ( !fxEffect ) { - return; - } - started = time; - for( int i = 0; i < fxEffect->events.Num(); i++ ) { - idFXLocalAction& laction = actions[i]; - laction.start = time; - laction.soundStarted = false; - laction.shakeStarted = false; - laction.particleSystem = -1; - laction.decalDropped = false; - laction.launched = false; - } -} - -/* -================ -idEntityFx::Stop -================ -*/ -void idEntityFx::Stop( void ) { - CleanUp(); - started = -1; -} - -/* -================ -idEntityFx::Duration -================ -*/ -const int idEntityFx::Duration( void ) { - int max = 0; - - if ( !fxEffect ) { - return max; - } - for( int i = 0; i < fxEffect->events.Num(); i++ ) { - const idFXSingleAction& fxaction = fxEffect->events[i]; - int d = static_cast(( fxaction.delay + fxaction.duration ) * 1000.0f); - if ( d > max ) { - max = d; - } - } - - return max; -} - - -/* -================ -idEntityFx::Done -================ -*/ -const bool idEntityFx::Done() { - if (started > 0 && gameLocal.time > started + Duration()) { - return true; - } - return false; -} - -/* -================ -idEntityFx::ApplyFade -================ -*/ -void idEntityFx::ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ) { - if ( fxaction.fadeInTime || fxaction.fadeOutTime ) { - float fadePct = (float)( time - actualStart ) / ( 1000.0f * ( ( fxaction.fadeInTime != 0 ) ? fxaction.fadeInTime : fxaction.fadeOutTime ) ); - if (fadePct > 1.0) { - fadePct = 1.0; - } - if ( laction.modelDefHandle != -1 ) { - laction.renderEntity.shaderParms[SHADERPARM_RED] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; - laction.renderEntity.shaderParms[SHADERPARM_GREEN] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; - laction.renderEntity.shaderParms[SHADERPARM_BLUE] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct; - - gameRenderWorld->UpdateEntityDef( laction.modelDefHandle, &laction.renderEntity ); - } - if ( laction.lightDefHandle != -1 ) { - laction.renderLight.shaderParms[SHADERPARM_RED] = fxaction.lightColor.x * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); - laction.renderLight.shaderParms[SHADERPARM_GREEN] = fxaction.lightColor.y * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); - laction.renderLight.shaderParms[SHADERPARM_BLUE] = fxaction.lightColor.z * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct ); - - gameRenderWorld->UpdateLightDef( laction.lightDefHandle, &laction.renderLight ); - } - } -} - -/* -================ -idEntityFx::Run -================ -*/ -void idEntityFx::Run( int time ) { - int ieff, j; - idEntity *ent = NULL; - const idDict *projectileDef = NULL; - idProjectile *projectile = NULL; - - if ( !fxEffect ) { - return; - } - - for( ieff = 0; ieff < fxEffect->events.Num(); ieff++ ) { - const idFXSingleAction& fxaction = fxEffect->events[ieff]; - idFXLocalAction& laction = actions[ieff]; - - // - // if we're currently done with this one - // - if ( laction.start == -1 ) { - continue; - } - - // - // see if it's delayed - // - if ( laction.delay ) { - if ( laction.start + (time - laction.start) < laction.start + (laction.delay * 1000) ) { - continue; - } - } - - // - // each event can have it's own delay and restart - // - int actualStart = laction.delay ? laction.start + (int)( laction.delay * 1000 ) : laction.start; - float pct = (float)( time - actualStart ) / (1000 * fxaction.duration ); - if ( pct >= 1.0f ) { - laction.start = -1; - float totalDelay = 0.0f; - if ( fxaction.restart ) { - if ( fxaction.random1 || fxaction.random2 ) { - totalDelay = fxaction.random1 + gameLocal.random.RandomFloat() * (fxaction.random2 - fxaction.random1); - } else { - totalDelay = fxaction.delay; - } - laction.delay = totalDelay; - laction.start = time; - } - continue; - } - - if ( fxaction.fire.Length() ) { - for( j = 0; j < fxEffect->events.Num(); j++ ) { - if ( fxEffect->events[j].name.Icmp( fxaction.fire ) == 0 ) { - actions[j].delay = 0; - } - } - } - - idFXLocalAction *useAction; - if ( fxaction.sibling == -1 ) { - useAction = &laction; - } else { - useAction = &actions[fxaction.sibling]; - } - assert( useAction ); - - switch( fxaction.type ) { - case FX_ATTACHLIGHT: - case FX_LIGHT: { - if ( useAction->lightDefHandle == -1 ) { - if ( fxaction.type == FX_LIGHT ) { - memset( &useAction->renderLight, 0, sizeof( renderLight_t ) ); - useAction->renderLight.origin = GetPhysics()->GetOrigin() + fxaction.offset; - useAction->renderLight.axis = GetPhysics()->GetAxis(); - useAction->renderLight.lightRadius[0] = fxaction.lightRadius; - useAction->renderLight.lightRadius[1] = fxaction.lightRadius; - useAction->renderLight.lightRadius[2] = fxaction.lightRadius; - useAction->renderLight.shader = declManager->FindMaterial( fxaction.data, false ); - useAction->renderLight.shaderParms[ SHADERPARM_RED ] = fxaction.lightColor.x; - useAction->renderLight.shaderParms[ SHADERPARM_GREEN ] = fxaction.lightColor.y; - useAction->renderLight.shaderParms[ SHADERPARM_BLUE ] = fxaction.lightColor.z; - useAction->renderLight.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; - useAction->renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time ); - useAction->renderLight.referenceSound = refSound.referenceSound; - useAction->renderLight.pointLight = true; - if ( fxaction.noshadows ) { - useAction->renderLight.noShadows = true; - } - useAction->lightDefHandle = gameRenderWorld->AddLightDef( &useAction->renderLight ); - } - if ( fxaction.noshadows ) { - for( j = 0; j < fxEffect->events.Num(); j++ ) { - idFXLocalAction& laction2 = actions[j]; - if ( laction2.modelDefHandle != -1 ) { - laction2.renderEntity.noShadow = true; - } - } - } - } - ApplyFade( fxaction, *useAction, time, actualStart ); - break; - } - case FX_SOUND: { - if ( !useAction->soundStarted ) { - useAction->soundStarted = true; - const idSoundShader *shader = declManager->FindSound(fxaction.data); - StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL ); - for( j = 0; j < fxEffect->events.Num(); j++ ) { - idFXLocalAction& laction2 = actions[j]; - if ( laction2.lightDefHandle != -1 ) { - laction2.renderLight.referenceSound = refSound.referenceSound; - gameRenderWorld->UpdateLightDef( laction2.lightDefHandle, &laction2.renderLight ); - } - } - } - break; - } - case FX_DECAL: { - if ( !useAction->decalDropped ) { - useAction->decalDropped = true; - gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 8.0f, true, fxaction.size, fxaction.data ); - } - break; - } - case FX_SHAKE: { - if ( !useAction->shakeStarted ) { - idDict args; - args.Clear(); - args.SetFloat( "kick_time", fxaction.shakeTime ); - args.SetFloat( "kick_amplitude", fxaction.shakeAmplitude ); - for ( j = 0; j < gameLocal.numClients; j++ ) { - idPlayer *player = gameLocal.GetClientByNum( j ); - if ( player && ( player->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).LengthSqr() < Square( fxaction.shakeDistance ) ) { - if ( !gameLocal.isMultiplayer || !fxaction.shakeIgnoreMaster || GetBindMaster() != player ) { - player->playerView.DamageImpulse( fxaction.offset, &args ); - } - } - } - if ( fxaction.shakeImpulse != 0.0f && fxaction.shakeDistance != 0.0f ) { - idEntity *ignore_ent = NULL; - if ( gameLocal.isMultiplayer ) { - ignore_ent = this; - if ( fxaction.shakeIgnoreMaster ) { - ignore_ent = GetBindMaster(); - } - } - // lookup the ent we are bound to? - gameLocal.RadiusPush( GetPhysics()->GetOrigin(), fxaction.shakeDistance, fxaction.shakeImpulse, this, ignore_ent, 1.0f, true ); - } - useAction->shakeStarted = true; - } - break; - } - case FX_ATTACHENTITY: - case FX_PARTICLE: - case FX_MODEL: { - if ( useAction->modelDefHandle == -1 ) { - memset( &useAction->renderEntity, 0, sizeof( renderEntity_t ) ); - useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset; - useAction->renderEntity.axis = (fxaction.explicitAxis) ? fxaction.axis : GetPhysics()->GetAxis(); - useAction->renderEntity.hModel = renderModelManager->FindModel( fxaction.data ); - useAction->renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; - useAction->renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f; - useAction->renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; - useAction->renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time ); - useAction->renderEntity.shaderParms[3] = 1.0f; - useAction->renderEntity.shaderParms[5] = 0.0f; - if ( useAction->renderEntity.hModel ) { - useAction->renderEntity.bounds = useAction->renderEntity.hModel->Bounds( &useAction->renderEntity ); - } - useAction->modelDefHandle = gameRenderWorld->AddEntityDef( &useAction->renderEntity ); - } else if ( fxaction.trackOrigin ) { - useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset; - useAction->renderEntity.axis = fxaction.explicitAxis ? fxaction.axis : GetPhysics()->GetAxis(); - } - ApplyFade( fxaction, *useAction, time, actualStart ); - break; - } - case FX_LAUNCH: { - if ( gameLocal.isClient ) { - // client never spawns entities outside of ClientReadSnapshot - useAction->launched = true; - break; - } - if ( !useAction->launched ) { - useAction->launched = true; - projectile = NULL; - // FIXME: may need to cache this if it is slow - projectileDef = gameLocal.FindEntityDefDict( fxaction.data, false ); - if ( !projectileDef ) { - gameLocal.Warning( "projectile \'%s\' not found", fxaction.data.c_str() ); - } else { - gameLocal.SpawnEntityDef( *projectileDef, &ent, false ); - if ( ent && ent->IsType( idProjectile::Type ) ) { - projectile = ( idProjectile * )ent; - projectile->Create( this, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0] ); - projectile->Launch( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0], vec3_origin ); - } - } - } - break; - } - } - } -} - -/* -================ -idEntityFx::idEntityFx -================ -*/ -idEntityFx::idEntityFx() { - fxEffect = NULL; - started = -1; - nextTriggerTime = -1; - fl.networkSync = true; -} - -/* -================ -idEntityFx::~idEntityFx -================ -*/ -idEntityFx::~idEntityFx() { - CleanUp(); - fxEffect = NULL; -} - -/* -================ -idEntityFx::Spawn -================ -*/ -void idEntityFx::Spawn( void ) { - - if ( g_skipFX.GetBool() ) { - return; - } - - const char *fx; - nextTriggerTime = 0; - fxEffect = NULL; - if ( spawnArgs.GetString( "fx", "", &fx ) ) { - systemName = fx; - } - if ( !spawnArgs.GetBool( "triggered" ) ) { - Setup( fx ); - if ( spawnArgs.GetBool( "test" ) || spawnArgs.GetBool( "start" ) || spawnArgs.GetFloat ( "restart" ) ) { - PostEventMS( &EV_Activate, 0, this ); - } - } -} - -/* -================ -idEntityFx::Think - - Clears any visual fx started when {item,mob,player} was spawned -================ -*/ -void idEntityFx::Think( void ) { - if ( g_skipFX.GetBool() ) { - return; - } - - if ( thinkFlags & TH_THINK ) { - Run( gameLocal.time ); - } - - RunPhysics(); - Present(); -} - -/* -================ -idEntityFx::Event_ClearFx - - Clears any visual fx started when item(mob) was spawned -================ -*/ -void idEntityFx::Event_ClearFx( void ) { - - if ( g_skipFX.GetBool() ) { - return; - } - - Stop(); - CleanUp(); - BecomeInactive( TH_THINK ); - - if ( spawnArgs.GetBool("test") ) { - PostEventMS( &EV_Activate, 0, this ); - } else { - if ( spawnArgs.GetFloat( "restart" ) || !spawnArgs.GetBool( "triggered")) { - float rest = spawnArgs.GetFloat( "restart", "0" ); - if ( rest == 0.0f ) { - PostEventSec( &EV_Remove, 0.1f ); - } else { - rest *= gameLocal.random.RandomFloat(); - PostEventSec( &EV_Activate, rest, this ); - } - } - } -} - -/* -================ -idEntityFx::Event_Trigger -================ -*/ -void idEntityFx::Event_Trigger( idEntity *activator ) { - - if ( g_skipFX.GetBool() ) { - return; - } - - float fxActionDelay; - const char *fx; - - if ( gameLocal.time < nextTriggerTime ) { - return; - } - - if ( spawnArgs.GetString( "fx", "", &fx) ) { - Setup( fx ); - Start( gameLocal.time ); - PostEventMS( &EV_Fx_KillFx, Duration() ); - BecomeActive( TH_THINK ); - } - - fxActionDelay = spawnArgs.GetFloat( "fxActionDelay" ); - if ( fxActionDelay != 0.0f ) { - nextTriggerTime = gameLocal.time + SEC2MS( fxActionDelay ); - } else { - // prevent multiple triggers on same frame - nextTriggerTime = gameLocal.time + 1; - } - PostEventSec( &EV_Fx_Action, fxActionDelay, activator ); -} - - -/* -================ -idEntityFx::StartFx -================ -*/ -idEntityFx *idEntityFx::StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ) { - - if ( g_skipFX.GetBool() || !fx || !*fx ) { - return NULL; - } - - idDict args; - args.SetBool( "start", true ); - args.Set( "fx", fx ); - idEntityFx *nfx = static_cast( gameLocal.SpawnEntityType( idEntityFx::Type, &args ) ); - if ( nfx->Joint() && *nfx->Joint() ) { - nfx->BindToJoint( ent, nfx->Joint(), true ); - nfx->SetOrigin( vec3_origin ); - } else { - nfx->SetOrigin( (useOrigin) ? *useOrigin : ent->GetPhysics()->GetOrigin() ); - nfx->SetAxis( (useAxis) ? *useAxis : ent->GetPhysics()->GetAxis() ); - } - - // greebo: Don't call Bind again if a we're bound to a joint - if (bind && ((nfx->Joint() == NULL) || (*nfx->Joint() == '\0'))) - { - // never bind to world spawn - if (ent != gameLocal.world) - { - nfx->Bind(ent, true); - } - } - - nfx->Show(); - return nfx; -} - -/* -================= -idEntityFx::WriteToSnapshot -================= -*/ -void idEntityFx::WriteToSnapshot( idBitMsgDelta &msg ) const { - GetPhysics()->WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); - msg.WriteLong( ( fxEffect != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_FX, fxEffect->Index() ) : -1 ); - msg.WriteLong( started ); -} - -/* -================= -idEntityFx::ReadFromSnapshot -================= -*/ -void idEntityFx::ReadFromSnapshot( const idBitMsgDelta &msg ) { - int fx_index, start_time, max_lapse; - - GetPhysics()->ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - fx_index = gameLocal.ClientRemapDecl( DECL_FX, msg.ReadLong() ); - start_time = msg.ReadLong(); - - if ( fx_index != -1 && start_time > 0 && !fxEffect && started < 0 ) { - spawnArgs.GetInt( "effect_lapse", "1000", max_lapse ); - if ( gameLocal.time - start_time > max_lapse ) { - // too late, skip the effect completely - started = 0; - return; - } - const idDeclFX *fx = static_cast( declManager->DeclByIndex( DECL_FX, fx_index ) ); - if ( !fx ) { - gameLocal.Error( "FX at index %d not found", fx_index ); - } - fxEffect = fx; - Setup( fx->GetName() ); - Start( start_time ); - } -} - -/* -================= -idEntityFx::ClientPredictionThink -================= -*/ -void idEntityFx::ClientPredictionThink( void ) { - if ( gameLocal.isNewFrame ) { - Run( gameLocal.time ); - } - RunPhysics(); - Present(); -} - -/* -=============================================================================== - - idTeleporter - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntityFx, idTeleporter ) - EVENT( EV_Fx_Action, idTeleporter::Event_DoAction ) -END_CLASS - -/* -================ -idTeleporter::Event_DoAction -================ -*/ -void idTeleporter::Event_DoAction( idEntity *activator ) { - float angle; - - angle = spawnArgs.GetFloat( "angle" ); - idAngles a( 0, spawnArgs.GetFloat( "angle" ), 0 ); - activator->Teleport( GetPhysics()->GetOrigin(), a, NULL ); -} diff --git a/game/fx.h b/game/fx.h deleted file mode 100644 index 553b05a79..000000000 --- a/game/fx.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_FX_H__ -#define __GAME_FX_H__ - -/* -=============================================================================== - - Special effects. - -=============================================================================== -*/ - -struct idFXSingleAction; - -typedef struct { - renderLight_t renderLight; // light presented to the renderer - qhandle_t lightDefHandle; // handle to renderer light def - renderEntity_t renderEntity; // used to present a model to the renderer - int modelDefHandle; // handle to static renderer model - float delay; - int particleSystem; - int start; - bool soundStarted; - bool shakeStarted; - bool decalDropped; - bool launched; -} idFXLocalAction; - -class idEntityFx : public idEntity { -public: - CLASS_PROTOTYPE( idEntityFx ); - - idEntityFx(); - virtual ~idEntityFx(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think(); - void Setup( const char *fx ); - void Run( int time ); - void Start( int time ); - void Stop( void ); - const int Duration( void ); - const char * EffectName( void ); - const char * Joint( void ); - const bool Done(); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - virtual void ClientPredictionThink( void ); - - static idEntityFx * StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ); - -protected: - void Event_Trigger( idEntity *activator ); - void Event_ClearFx( void ); - - void CleanUp( void ); - void CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ); - void ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ); - - int started; - int nextTriggerTime; - const idDeclFX * fxEffect; // GetFX() should be called before using fxEffect as a pointer - idList actions; - idStr systemName; -}; - -class idTeleporter : public idEntityFx { -public: - CLASS_PROTOTYPE( idTeleporter ); - -private: - // teleporters to this location - void Event_DoAction( idEntity *activator ); -}; - -#endif /* !__GAME_FX_H__ */ diff --git a/game/game.h b/game/game.h deleted file mode 100644 index cae91a983..000000000 --- a/game/game.h +++ /dev/null @@ -1,364 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_H__ -#define __GAME_H__ - -#if defined(__linux__) || defined(MACOS_X) -#include "idlib/lib.h" -#include "sound/sound.h" -#endif - -/* -=============================================================================== - - Public game interface with methods to run the game. - -=============================================================================== -*/ - -// default scripts -#define SCRIPT_DEFAULTDEFS "script/tdm_defs.script" -#define SCRIPT_DEFAULT "script/tdm_main.script" -#define SCRIPT_DEFAULTFUNC "tdm_main" - -typedef struct { - char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc - int consistencyHash; // used to check for network game divergence - int health; - int heartRate; - int stamina; - int combat; - bool syncNextGameFrame; // used when cinematics are skipped to prevent session from simulating several game frames to - // keep the game time in sync with real time -} gameReturn_t; - -typedef enum { - ALLOW_YES = 0, - ALLOW_BADPASS, // core will prompt for password and connect again - ALLOW_NOTYET, // core will wait with transmitted message - ALLOW_NO // core will abort with transmitted message -} allowReply_t; - -typedef enum { - ESC_IGNORE = 0, // do nothing - ESC_MAIN, // start main menu GUI - ESC_GUI // set an explicit GUI -} escReply_t; - -#define TIME_GROUP1 0 -#define TIME_GROUP2 1 - -class idRenderWorld; -class idSoundWorld; -class usercmd_t; -class idUserInterface; - -class idGame { -public: - virtual ~idGame() {} - - // Initialize the game for the first time. - virtual void Init( void ) = 0; - - // Shut down the entire game. - virtual void Shutdown( void ) = 0; - - // Set the local client number. Distinguishes listen ( == 0 ) / dedicated ( == -1 ) - virtual void SetLocalClient( int clientNum ) = 0; - - // Sets the user info for a client. - // if canModify is true, the game can modify the user info in the returned dictionary pointer, server will forward the change back - // canModify is never true on network client - virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ) = 0; - - // Retrieve the game's userInfo dict for a client. - virtual const idDict * GetUserInfo( int clientNum ) = 0; - - // The game gets a chance to alter userinfo before they are emitted to server. - virtual void ThrottleUserInfo( void ) = 0; - - // Sets the serverinfo at map loads and when it changes. - virtual void SetServerInfo( const idDict &serverInfo ) = 0; - - // The session calls this before moving the single player game to a new level. - virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0; - - // The session calls this right before a new level is loaded. - virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) = 0; - - // Loads a map and spawns all the entities. - virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) = 0; - - // Loads a map from a savegame file. - virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ) = 0; - - // Saves the current game state, the session may have written some data to the file already. - virtual void SaveGame( idFile *saveGameFile ) = 0; - - // Shut down the current map. - virtual void MapShutdown( void ) = 0; - - // Caches media referenced from in key/value pairs in the given dictionary. - virtual void CacheDictionaryMedia( const idDict *dict ) = 0; - - // Spawns the player entity to be used by the client. - virtual void SpawnPlayer( int clientNum ) = 0; - - // Runs a game frame, may return a session command for level changing, etc - virtual gameReturn_t RunFrame( const usercmd_t *clientCmds ) = 0; - - // Makes rendering and sound system calls to display for a given clientNum. - virtual bool Draw( int clientNum ) = 0; - - // Let the game do it's own UI when ESCAPE is used - virtual escReply_t HandleESC( idUserInterface **gui ) = 0; - - // get the games menu if appropriate ( multiplayer ) - virtual idUserInterface * StartMenu() = 0; - - // When the game is running it's own UI fullscreen, GUI commands are passed through here - // return NULL once the fullscreen UI mode should stop, or "main" to go to main menu - virtual const char * HandleGuiCommands( const char *menuCommand ) = 0; - - // main menu commands not caught in the engine are passed here - virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) = 0; - - // Early check to deny connect. - virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] ) = 0; - - // Connects a client. - virtual void ServerClientConnect( int clientNum, const char *guid ) = 0; - - // Spawns the player entity to be used by the client. - virtual void ServerClientBegin( int clientNum ) = 0; - - // Disconnects a client and removes the player entity from the game. - virtual void ServerClientDisconnect( int clientNum ) = 0; - - // Writes initial reliable messages a client needs to recieve when first joining the game. - virtual void ServerWriteInitialReliableMessages( int clientNum ) = 0; - - // Writes a snapshot of the server game state for the given client. - virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ) = 0; - - // Patches the network entity states at the server with a snapshot for the given client. - virtual bool ServerApplySnapshot( int clientNum, int sequence ) = 0; - - // Processes a reliable message from a client. - virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0; - - // Reads a snapshot and updates the client game state. - virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) = 0; - - // Patches the network entity states at the client with a snapshot. - virtual bool ClientApplySnapshot( int clientNum, int sequence ) = 0; - - // Processes a reliable message from the server. - virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0; - - // Runs prediction on entities at the client. - virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ) = 0; - - // Used to manage divergent time-lines - virtual void SelectTimeGroup( int timeGroup ) = 0; - virtual int GetTimeGroupTime( int timeGroup ) = 0; - - virtual void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ) = 0; - - // Returns a summary of stats for a given client - virtual void GetClientStats( int clientNum, char *data, const int len ) = 0; - - // Switch a player to a particular team - virtual void SwitchTeam( int clientNum, int team ) = 0; - - virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) = 0; - - virtual void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) = 0; -}; - -extern idGame * game; - - -/* -=============================================================================== - - Public game interface with methods for in-game editing. - -=============================================================================== -*/ - -class idSoundEmitter; -class idSoundShader; - -struct refSound_t { - idSoundEmitter * referenceSound; // this is the interface to the sound system, created - // with idSoundWorld::AllocSoundEmitter() when needed - idVec3 origin; - int listenerId; // SSF_PRIVATE_SOUND only plays if == listenerId from PlaceListener - // no spatialization will be performed if == listenerID - const idSoundShader * shader; // this really shouldn't be here, it is a holdover from single channel behavior - float diversity; // 0.0 to 1.0 value used to select which - // samples in a multi-sample list from the shader are used - bool waitfortrigger; // don't start it at spawn time - soundShaderParms_t parms; // override volume, flags, etc -}; - -enum { - TEST_PARTICLE_MODEL = 0, - TEST_PARTICLE_IMPACT, - TEST_PARTICLE_MUZZLE, - TEST_PARTICLE_FLIGHT, - TEST_PARTICLE_SELECTED -}; - -class idEntity; -class idMD5Anim; -typedef struct renderLight_s renderLight_t; -typedef struct renderEntity_s renderEntity_t; -class idRenderModel; - -// FIXME: this interface needs to be reworked but it properly separates code for the time being -class idGameEdit { -public: - virtual ~idGameEdit( void ) {} - - // These are the canonical idDict to parameter parsing routines used by both the game and tools. - virtual void ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight ); - virtual void ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity ); - virtual void ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound ); - - // Animation system calls for non-game based skeletal rendering. - virtual idRenderModel * ANIM_GetModelFromEntityDef( const char *classname ); - virtual const idVec3 &ANIM_GetModelOffsetFromEntityDef( const char *classname ); - virtual idRenderModel * ANIM_GetModelFromEntityDef( const idDict *args ); - virtual idRenderModel * ANIM_GetModelFromName( const char *modelName ); - virtual const idMD5Anim * ANIM_GetAnimFromEntityDef( const char *classname, const char *animname ); - virtual int ANIM_GetNumAnimsFromEntityDef( const idDict *args ); - virtual const char * ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum ); - virtual const idMD5Anim * ANIM_GetAnim( const char *fileName ); - virtual int ANIM_GetLength( const idMD5Anim *anim ); - virtual int ANIM_GetNumFrames( const idMD5Anim *anim ); - virtual void ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset ); - virtual idRenderModel * ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset ); - - // Articulated Figure calls for AF editor and Radiant. - virtual bool AF_SpawnEntity( const char *fileName ); - virtual void AF_UpdateEntities( const char *fileName ); - virtual void AF_UndoChanges( void ); - virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet ); - - - // Entity selection. - virtual void ClearEntitySelection( void ); - virtual int GetSelectedEntities( idEntity *list[], int max ); - virtual void AddSelectedEntity( idEntity *ent ); - - // Selection methods - virtual void TriggerSelected(); - - // Entity defs and spawning. - virtual const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const; - virtual void SpawnEntityDef( const idDict &args, idEntity **ent ); - virtual idEntity * FindEntity( const char *name ) const; - virtual const char * GetUniqueEntityName( const char *classname ) const; - - // Entity methods. - virtual void EntityGetOrigin( idEntity *ent, idVec3 &org ) const; - virtual void EntityGetAxis( idEntity *ent, idMat3 &axis ) const; - virtual void EntitySetOrigin( idEntity *ent, const idVec3 &org ); - virtual void EntitySetAxis( idEntity *ent, const idMat3 &axis ); - virtual void EntityTranslate( idEntity *ent, const idVec3 &org ); - virtual const idDict * EntityGetSpawnArgs( idEntity *ent ) const; - virtual void EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict ); - virtual void EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs ); - virtual void EntityUpdateVisuals( idEntity *ent ); - virtual void EntitySetModel( idEntity *ent, const char *val ); - virtual void EntityStopSound( idEntity *ent ); - virtual void EntityDelete( idEntity *ent ); - virtual void EntitySetColor( idEntity *ent, const idVec3 color ); - - // Player methods. - virtual bool PlayerIsValid() const; - virtual void PlayerGetOrigin( idVec3 &org ) const; - virtual void PlayerGetAxis( idMat3 &axis ) const; - virtual void PlayerGetViewAngles( idAngles &angles ) const; - virtual void PlayerGetEyePosition( idVec3 &org ) const; - - // In game map editing support. - virtual const idDict * MapGetEntityDict( const char *name ) const; - virtual void MapSave( const char *path = NULL ) const; - virtual void MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const ; - virtual void MapCopyDictToEntity( const char *name, const idDict *dict ) const; - virtual int MapGetUniqueMatchingKeyVals( const char *key, const char *list[], const int max ) const; - virtual void MapAddEntity( const idDict *dict ) const; - virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const; - virtual void MapRemoveEntity( const char *name ) const; - virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const; - -}; - -extern idGameEdit * gameEdit; - - -/* -=============================================================================== - - Game API. - -=============================================================================== -*/ - -const int GAME_API_VERSION = 8; - -class idCmdSystem; -class idNetworkSystem; -class idRenderSystem; -class idSoundSystem; -class idRenderModelManager; -class idUserInterfaceManager; -class idDeclManager; -class idAASFileManager; -class idCollisionModelManager; - -typedef struct { - - int version; // API version - idSys * sys; // non-portable system services - idCommon * common; // common - idCmdSystem * cmdSystem; // console command system - idCVarSystem * cvarSystem; // console variable system - idFileSystem * fileSystem; // file system - idNetworkSystem * networkSystem; // network system - idRenderSystem * renderSystem; // render system - idSoundSystem * soundSystem; // sound system - idRenderModelManager * renderModelManager; // render model manager - idUserInterfaceManager * uiManager; // user interface manager - idDeclManager * declManager; // declaration manager - idAASFileManager * AASFileManager; // AAS file manager - idCollisionModelManager * collisionModelManager; // collision model manager - -} gameImport_t; - -typedef struct { - - int version; // API version - idGame * game; // interface to run the game - idGameEdit * gameEdit; // interface for in-game editing - -} gameExport_t; - -extern "C" { -typedef gameExport_t * (*GetGameAPI_t)( gameImport_t *import ); -} - -#endif /* !__GAME_H__ */ diff --git a/game/game_local.cpp b/game/game_local.cpp deleted file mode 100644 index 5d1ac2748..000000000 --- a/game/game_local.cpp +++ /dev/null @@ -1,7298 +0,0 @@ -/*************************************************************************** - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#pragma warning(disable : 4127 4996 4805 4800) - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/darkModLAS.h" -#include "../DarkMod/decltdm_matinfo.h" -#include "../DarkMod/declxdata.h" -#include "../DarkMod/Grabber.h" -#include "../DarkMod/Relations.h" -#include "../DarkMod/Inventory/Inventory.h" -#include "../DarkMod/sndProp.h" -#include "ai/aas_local.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/Objectives/CampaignStatistics.h" -#include "../DarkMod/MultiStateMover.h" -#include "../DarkMod/func_shooter.h" -#include "../DarkMod/Shop/Shop.h" -#include "../DarkMod/EscapePointManager.h" -#include "../DarkMod/DownloadMenu.h" -#include "../DarkMod/TimerManager.h" -#include "../DarkMod/AI/Conversation/ConversationSystem.h" -#include "../DarkMod/RevisionTracker.h" -#include "../DarkMod/Missions/MissionManager.h" -#include "../DarkMod/Missions/DownloadManager.h" -#include "../DarkMod/Http/HttpConnection.h" -#include "../DarkMod/Http/HttpRequest.h" -#include "../DarkMod/StimResponse/StimType.h" // grayman #2721 - -#include "IL/il.h" -#include "../DarkMod/randomizer/randomc.h" -#include -#include -#include - -#include - -CGlobal g_Global; -TRandomCombined rnd(time(0)); - -extern CMissionData g_MissionData; -extern CsndPropLoader g_SoundPropLoader; -extern CsndProp g_SoundProp; - -#define BUFFER_LEN 4096 - -#ifdef GAME_DLL - -idSys * sys = NULL; -idCommon * common = NULL; -idCmdSystem * cmdSystem = NULL; -idCVarSystem * cvarSystem = NULL; -idFileSystem * fileSystem = NULL; -idNetworkSystem * networkSystem = NULL; -idRenderSystem * renderSystem = NULL; -idSoundSystem * soundSystem = NULL; -idRenderModelManager * renderModelManager = NULL; -idUserInterfaceManager * uiManager = NULL; -idDeclManager * declManager = NULL; -idAASFileManager * AASFileManager = NULL; -idCollisionModelManager * collisionModelManager = NULL; -idCVar * idCVar::staticVars = NULL; - -idCVar com_forceGenericSIMD( "com_forceGenericSIMD", "0", CVAR_BOOL|CVAR_SYSTEM, "force generic platform independent SIMD" ); - -#endif - -idRenderWorld * gameRenderWorld = NULL; // all drawing is done to this world -idSoundWorld * gameSoundWorld = NULL; // all audio goes to this world -idSoundWorld * gameSoundWorldBuf = NULL; - -static gameExport_t gameExport; - -// global animation lib -idAnimManager animationLib; - -// the rest of the engine will only reference the "game" variable, while all local aspects stay hidden -idGameLocal gameLocal; -idGame * game = &gameLocal; // statically pointed at an idGameLocal - -const char *idGameLocal::sufaceTypeNames[ MAX_SURFACE_TYPES ] = { - "none", "metal", "stone", "flesh", "wood", "cardboard", "liquid", "glass", "plastic", - "ricochet", "surftype10", "surftype11", "surftype12", "surftype13", "surftype14", "surftype15" -}; - -/* This list isn't actually used by the code, it's here just for reference. The code - accepts any first word in the description as the surface type name: */ -// grayman - #1421/1422 - added "hardwood" -const char *idGameLocal::m_NewSurfaceTypes[ MAX_SURFACE_TYPES * 2 + 1] = { - "tile", "carpet", "dirt", "gravel", "grass", "rock", "twigs", "foliage", "sand", "mud", - "brokeglass", "snow", "ice", "squeakboard", "puddle", "moss", "cloth", "ceramic", "slate", - "straw", "armor_leath", "armor_chain", "armor_plate", "climbable", "paper","hardwood" -}; - -void PrintMessage( int x, int y, const char *szMessage, idVec4 colour, fontInfoEx_t &font ) -{ - renderSystem->SetColor( colour ); - - for( const char *p = szMessage; *p; p++ ) - { - glyphInfo_t &glyph = font.fontInfoSmall.glyphs[int(*p)]; - - renderSystem->DrawStretchPic( x, y - glyph.top, - glyph.imageWidth, glyph.imageHeight, - glyph.s, glyph.t, glyph.s2, glyph.t2, - glyph.glyph ); - - x += glyph.xSkip; - } -} - -/* -=========== -GetGameAPI -============ -*/ -#if __MWERKS__ -#pragma export on -#endif -#if __GNUC__ >= 4 -#pragma GCC visibility push(default) -#endif -extern "C" gameExport_t *GetGameAPI( gameImport_t *import ) { -#if __MWERKS__ -#pragma export off -#endif - - if ( import->version == GAME_API_VERSION ) { - - // set interface pointers used by the game - sys = import->sys; - common = import->common; - cmdSystem = import->cmdSystem; - cvarSystem = import->cvarSystem; - fileSystem = import->fileSystem; - networkSystem = import->networkSystem; - renderSystem = import->renderSystem; - soundSystem = import->soundSystem; - renderModelManager = import->renderModelManager; - uiManager = import->uiManager; - declManager = import->declManager; - AASFileManager = import->AASFileManager; - collisionModelManager = import->collisionModelManager; - } - else { - // Wrong game version, throw a meaningful error rather than leaving - // stuff initialised and getting segfaults. - std::cerr << "FATAL: Incorrect game version: required " - << GAME_API_VERSION << ", got " << import->version << "\n" - << "Ensure the correct Doom 3 patches are installed." << std::endl; - abort(); - } - - // set interface pointers used by idLib - idLib::sys = sys; - idLib::common = common; - idLib::cvarSystem = cvarSystem; - idLib::fileSystem = fileSystem; - - // setup export interface - gameExport.version = GAME_API_VERSION; - gameExport.game = game; - gameExport.gameEdit = gameEdit; - - // Initialize logging and all the global stuff for darkmod - g_Global.Init(); - - return &gameExport; -} -#if __GNUC__ >= 4 -#pragma GCC visibility pop -#endif - -/* -=========== -TestGameAPI -============ -*/ -void TestGameAPI( void ) { - gameImport_t testImport; - gameExport_t testExport; - - testImport.sys = ::sys; - testImport.common = ::common; - testImport.cmdSystem = ::cmdSystem; - testImport.cvarSystem = ::cvarSystem; - testImport.fileSystem = ::fileSystem; - testImport.networkSystem = ::networkSystem; - testImport.renderSystem = ::renderSystem; - testImport.soundSystem = ::soundSystem; - testImport.renderModelManager = ::renderModelManager; - testImport.uiManager = ::uiManager; - testImport.declManager = ::declManager; - testImport.AASFileManager = ::AASFileManager; - testImport.collisionModelManager = ::collisionModelManager; - - testExport = *GetGameAPI( &testImport ); -} - -/* -=========== -idGameLocal::idGameLocal -============ -*/ -idGameLocal::idGameLocal() : - postMissionScreenActive(false), - briefingVideoInfoLoaded(false), - curBriefingVideoPart(-1), - m_MissionResult(MISSION_NOTEVENSTARTED), - m_HighestSRId(0) -{ - Clear(); -} - -/* -=========== -idGameLocal::~idGameLocal -============ -*/ -idGameLocal::~idGameLocal() -{ -} - -/* -=========== -idGameLocal::Clear -============ -*/ -void idGameLocal::Clear( void ) -{ - int i; - - m_HighestSRId = 0; - m_StimTimer.Clear(); - m_Timer.Clear(); - m_StimEntity.Clear(); - m_RespEntity.Clear(); - - m_sndPropLoader = &g_SoundPropLoader; - m_sndProp = &g_SoundProp; - m_RelationsManager = CRelationsPtr(); - m_MissionData.reset(); - - mainMenuExited = false; - briefingVideo.Clear(); - debriefingVideo.Clear(); - - m_Grabber = NULL; - m_DifficultyManager.Clear(); - - m_ModMenu.reset(); - m_DownloadMenu.reset(); - m_DownloadManager.reset(); - m_Shop.reset(); - - m_TriggerFinalSave = false; - - m_GUICommandStack.Clear(); - m_GUICommandArgs = 0; - - m_guiError.Clear(); - - m_AreaManager.Clear(); - m_ConversationSystem.reset(); - - if (m_ModelGenerator) - { - m_ModelGenerator->Clear(); - } - if (m_ImageMapManager) - { - m_ImageMapManager->Clear(); - } - if (m_LightController) - { - m_LightController->Clear(); - } - if (m_I18N) - { - m_I18N->Clear(); - } - -#ifdef TIMING_BUILD - debugtools::TimerManager::Instance().Clear(); -#endif - - m_EscapePointManager = CEscapePointManager::Instance(); - m_EscapePointManager->Clear(); - - m_Interleave = 0; - - m_lightGem.Clear(); - m_DoLightgem = true; - - m_InterMissionTriggers.Clear(); - - serverInfo.Clear(); - numClients = 0; - for ( i = 0; i < MAX_CLIENTS; i++ ) { - userInfo[i].Clear(); - persistentPlayerInfo[i].Clear(); - } - memset( usercmds, 0, sizeof( usercmds ) ); - memset( entities, 0, sizeof( entities ) ); - memset( spawnIds, -1, sizeof( spawnIds ) ); - firstFreeIndex = 0; - num_entities = 0; - spawnedEntities.Clear(); - activeEntities.Clear(); - spawnedAI.Clear(); - numEntitiesToDeactivate = 0; - sortPushers = false; - sortTeamMasters = false; - persistentLevelInfo.Clear(); - persistentPlayerInventory.reset(); - campaignInfoEntities.Clear(); - - memset( globalShaderParms, 0, sizeof( globalShaderParms ) ); - random.SetSeed( 0 ); - world = NULL; - frameCommandThread = NULL; - testmodel = NULL; - testFx = NULL; - clip.Shutdown(); - pvs.Shutdown(); - sessionCommand.Clear(); - locationEntities = NULL; - smokeParticles = NULL; - editEntities = NULL; - entityHash.Clear( 1024, MAX_GENTITIES ); - inCinematic = false; - cinematicSkipTime = 0; - cinematicStopTime = 0; - cinematicMaxSkipTime = 0; - framenum = 0; - previousTime = 0; - time = 0; - vacuumAreaNum = 0; - mapFileName.Clear(); - mapFile = NULL; - spawnCount = INITIAL_SPAWN_COUNT; - mapSpawnCount = 0; - camera = NULL; - aasList.Clear(); - aasNames.Clear(); - spawnArgs.Clear(); - gravity.Set( 0, 0, -1 ); - playerPVS.h = (unsigned int)-1; - playerConnectedAreas.h = (unsigned int)-1; - gamestate = GAMESTATE_UNINITIALIZED; - skipCinematic = false; - influenceActive = false; - - localClientNum = 0; - isMultiplayer = false; - isServer = false; - isClient = false; - realClientTime = 0; - isNewFrame = true; - clientSmoothing = 0.1f; - entityDefBits = 0; - - nextGibTime = 0; - globalMaterial = NULL; - newInfo.Clear(); - lastGUIEnt = NULL; - lastGUI = 0; - - memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); - memset( clientPVS, 0, sizeof( clientPVS ) ); - memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); - - eventQueue.Init(); - savedEventQueue.Init(); - memset( lagometer, 0, sizeof( lagometer ) ); - - portalSkyEnt = NULL; - portalSkyActive = false; - // ResetSlowTimeVars(); - - m_GamePlayTimer.Clear(); - - musicSpeakers.Clear(); -} - -/* -=========== -idGameLocal::Init - - initialize the game object, only happens once at startup, not each level load -============ -*/ -void idGameLocal::Init( void ) { - const idDict *dict; - idAAS *aas; - -#ifndef GAME_DLL - - TestGameAPI(); - -#else - // Attempt to change the D3 window title and icon - ChangeWindowTitleAndIcon(); - - // Initialize the image library, so we can use it later on. - ilInit(); - - // initialize idLib - idLib::Init(); - - // register static cvars declared in the game - idCVar::RegisterStaticVars(); - - // initialize processor specific SIMD - idSIMD::InitProcessor( "game", com_forceGenericSIMD.GetBool() ); - -#endif - - Printf( "--------- Initializing Game ----------\n" ); - Printf( "%s %d.%02d, code revision %d\n", - GAME_VERSION, - TDM_VERSION_MAJOR, TDM_VERSION_MINOR, - RevisionTracker::Instance().GetHighestRevision() - ); - Printf( "Build date: %s\n", __DATE__ ); - - // register game specific decl types - declManager->RegisterDeclType( "model", DECL_MODELDEF, idDeclAllocator ); - declManager->RegisterDeclType( "export", DECL_MODELEXPORT, idDeclAllocator ); - // TDM specific DECLs - declManager->RegisterDeclType( "xdata", DECL_XDATA, idDeclAllocator ); - declManager->RegisterDeclType( "tdm_matinfo", DECL_TDM_MATINFO, idDeclAllocator ); - - // register game specific decl folders - declManager->RegisterDeclFolder( "def", ".def", DECL_ENTITYDEF ); - declManager->RegisterDeclFolder( "fx", ".fx", DECL_FX ); - declManager->RegisterDeclFolder( "particles", ".prt", DECL_PARTICLE ); - declManager->RegisterDeclFolder( "af", ".af", DECL_AF ); - // TDM specific DECLs - declManager->RegisterDeclFolder( "xdata", ".xd", DECL_XDATA ); - declManager->RegisterDeclFolder( "materials", ".mtr", DECL_TDM_MATINFO ); - - cmdSystem->AddCommand( "listModelDefs", idListDecls_f, CMD_FL_SYSTEM|CMD_FL_GAME, "lists model defs" ); - cmdSystem->AddCommand( "printModelDefs", idPrintDecls_f, CMD_FL_SYSTEM|CMD_FL_GAME, "prints a model def", idCmdSystem::ArgCompletion_Decl ); - - Clear(); - - idEvent::Init(); - idClass::Init(); - - InitConsoleCommands(); - - // greebo: Let the proxy CVARs overwrite the closed source counter-part - cvarSystem->SetCVarInteger("s_doorDistanceAdd", cv_tdm_s_doorDistanceAdd.GetInteger()); - cvarSystem->SetCVarFloat("gui_mediumFontLimit", cv_tdm_gui_mediumFontLimit.GetFloat()); - cvarSystem->SetCVarFloat("gui_smallFontLimit", cv_tdm_gui_smallFontLimit.GetFloat()); - - if (cv_tdm_s_maxSoundsPerShader.GetInteger() != -1) - { - cvarSystem->SetCVarInteger("s_maxSoundsPerShader", cv_tdm_s_maxSoundsPerShader.GetInteger()); - } - - // load default scripts - program.Startup( SCRIPT_DEFAULT ); - - smokeParticles = new idSmokeParticles; - - // set up the aas - dict = FindEntityDefDict( "aas_types" ); - if ( !dict ) { - Error( "Unable to find entityDef for 'aas_types'" ); - } - - // allocate space for the aas - const idKeyValue *kv = dict->MatchPrefix( "type" ); - while( kv != NULL ) { - aas = idAAS::Alloc(); - aasList.Append( aas ); - aasNames.Append( kv->GetValue() ); - kv = dict->MatchPrefix( "type", kv ); - } - - gamestate = GAMESTATE_NOMAP; - - Printf( "...%d aas types\n", aasList.Num() ); - Printf( "game initialized.\n" ); - Printf( "--------------------------------------\n" ); - Printf( "Parsing material files\n" ); - - LoadLightMaterial("materials/lights.mtr", &g_Global.m_LightMaterial); - - m_MissionData = CMissionDataPtr(new CMissionData); - m_CampaignStats = CampaignStatsPtr(new CampaignStats); - m_RelationsManager = CRelationsPtr(new CRelations); - m_ModMenu = CModMenuPtr(new CModMenu); - m_DownloadMenu = CDownloadMenuPtr(new CDownloadMenu); - m_DownloadManager = CDownloadManagerPtr(new CDownloadManager); - m_ConversationSystem = ai::ConversationSystemPtr(new ai::ConversationSystem); - - // load the soundprop globals from the def file - m_sndPropLoader->GlobalsFromDef(); - - //FIX: pm_walkspeed keeps getting reset whenever a map loads. - // Copy the old value here and set it when the map starts up. - m_walkSpeed = pm_walkspeed.GetFloat(); - - // Initialize the LightGem - J.C.Denton - m_lightGem.Initialize(); - - // Initialise the I18N (internationalization) code (before the Mission Manager!) - m_I18N = CI18NPtr(new CI18N); - m_I18N->Init(); - const idStr *tdm_lang = m_I18N->GetCurrentLanguage(); - Printf("Current language: %s\n", tdm_lang->c_str() ); - - // Initialise the mission manager - m_MissionManager = CMissionManagerPtr(new CMissionManager); - m_MissionManager->Init(); - - // Initialise the model generator - m_ModelGenerator = CModelGeneratorPtr(new CModelGenerator); - m_ModelGenerator->Init(); - - // Initialise the image map manager - m_ImageMapManager = CImageMapManagerPtr(new CImageMapManager); - m_ImageMapManager->Init(); - - // Initialise the light controller - m_LightController = CLightControllerPtr(new CLightController); - m_LightController->Init(); - - // greebo: Create the persistent inventory - will be handled by game state changing code - persistentPlayerInventory.reset(new CInventory); - - m_Shop = CShopPtr(new CShop); - m_Shop->Init(); - - // Construct a new http connection object - if (cv_tdm_allow_http_access.GetBool()) - { - m_HttpConnection = CHttpConnectionPtr(new CHttpConnection); - } -} - -const idStr& idGameLocal::GetMapFileName() const -{ - return mapFileName; -} - -void idGameLocal::AddInterMissionTrigger(int missionNum, const idStr& activatorName, const idStr& targetName) -{ - InterMissionTrigger& trigger = m_InterMissionTriggers.Alloc(); - - trigger.missionNum = missionNum; - trigger.activatorName = activatorName; - trigger.targetName = targetName; -} - -void idGameLocal::CheckTDMVersion() -{ - GuiMessage msg; - msg.type = GuiMessage::MSG_OK; - msg.okCmd = "close_msg_box"; - - if (m_HttpConnection == NULL) - { - Printf("HTTP requests disabled, skipping TDM version check.\n"); - - msg.title = m_I18N->Translate( "#str_02136" ); - msg.message = m_I18N->Translate( "#str_02141" ); // HTTP Requests have been disabled,\n cannot check for updates. - - AddMainMenuMessage(msg); - return; - } - - idStr url = cv_tdm_version_check_url.GetString(); - Printf("Checking %s\n", url.c_str() ); - CHttpRequestPtr req = m_HttpConnection->CreateRequest( url.c_str() ); - - req->Perform(); - - // Check Request Status - if (req->GetStatus() != CHttpRequest::OK) - { - Printf("%s.\n", m_I18N->Translate( "#str_2002") ); // Connection Error - - msg.title = m_I18N->Translate( "#str_02136" ); // Version Check Failed - msg.message = m_I18N->Translate( "#str_02132" ); // Cannot connect to server. - - AddMainMenuMessage(msg); - return; - } - - XmlDocumentPtr doc = req->GetResultXml(); - - pugi::xpath_node node = doc->select_single_node("//tdm/currentVersion"); - - if (node) - { - int major = node.node().attribute("major").as_int(); - int minor = node.node().attribute("minor").as_int(); - - msg.title = va( m_I18N->Translate( "#str_02132" ), major, minor ); // Most recent version is: - - switch (CompareVersion(TDM_VERSION_MAJOR, TDM_VERSION_MINOR, major, minor)) - { - case EQUAL: - // "Your version %d.%02d is up to date." - msg.message = va( m_I18N->Translate( "#str_02133"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); - break; - case OLDER: - // "Your version %d.%02d needs updating." - msg.message = va( m_I18N->Translate( "#str_02134"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); - break; - case NEWER: - // "Your version %d.%02d is newer than the most recently published one." - msg.message = va( m_I18N->Translate( "#str_02135"), TDM_VERSION_MAJOR, TDM_VERSION_MINOR); - break; - }; - } - else - { - msg.title = m_I18N->Translate( "#str_02136" ); // "Version Check Failed" - msg.message = m_I18N->Translate( "#str_02137" ); // "Couldn't find current version tag." - - } - - AddMainMenuMessage(msg); -} - -void idGameLocal::AddMainMenuMessage(const GuiMessage& message) -{ - m_GuiMessages.Append(message); -} - -/* -=========== -idGameLocal::Shutdown - - shut down the entire game -============ -*/ -void idGameLocal::Shutdown( void ) { - if ( !common ) { - return; - } - - if (cv_tdm_fm_sync_config_files.GetBool()) - { - // greebo: Check if we have a game base. If yes, write the current configuration back to the - // "darkmod" game base folder, to preserve any settings made while an FM is installed. - idStr fs_game_base(cvarSystem->GetCVarString("fs_game_base")); - - if (!fs_game_base.IsEmpty()) - { - common->WriteConfigToFile("../" + fs_game_base + "/DoomConfig.cfg"); - } - } - - Printf( "------------ Game Shutdown -----------\n" ); - - m_lightGem.Deinitialize(); - mpGame.Shutdown(); - - MapShutdown(); - - // greebo: De-allocate the missiondata singleton, this is not - // done in MapShutdown() (needed for mission statistics) - m_MissionData.reset(); - m_CampaignStats.reset(); - - // Destroy the conversation system - m_ConversationSystem.reset(); - - // Destroy the mission manager - m_MissionManager.reset(); - - // Destroy the model generator - m_ModelGenerator.reset(); - - // Destroy the image map manager - m_ImageMapManager.reset(); - - // Destroy the light controller - m_LightController.reset(); - - // Destroy the I18N system - m_I18N.reset(); - - // Clear http connection - m_HttpConnection.reset(); - m_GuiMessages.Clear(); - - aasList.DeleteContents( true ); - aasNames.Clear(); - - idAI::FreeObstacleAvoidanceNodes(); - - // shutdown the model exporter - idModelExport::Shutdown(); - - idEvent::Shutdown(); - - delete[] locationEntities; - locationEntities = NULL; - - delete smokeParticles; - smokeParticles = NULL; - - idClass::Shutdown(); - - // clear list with forces - idForce::ClearForceList(); - - // free the program data - program.FreeData(); - - // delete the .map file - delete mapFile; - mapFile = NULL; - - // free the collision map - collisionModelManager->FreeMap(); - - ShutdownConsoleCommands(); - - // free memory allocated by class objects - Clear(); - - // shut down the animation manager - animationLib.Shutdown(); - - Printf( "--------------------------------------\n" ); - -#ifdef GAME_DLL - - // remove auto-completion function pointers pointing into this DLL - cvarSystem->RemoveFlaggedAutoCompletion( CVAR_GAME ); - - // enable leak test - Mem_EnableLeakTest( "game" ); - - // shutdown idLib - idLib::ShutDown(); - -#endif -} - -/* -=========== -idGameLocal::SaveGame - -save the current player state, level name, and level state -the session may have written some data to the file already -============ -*/ -void idGameLocal::SaveGame( idFile *f ) { - int i; - - idSaveGame savegame( f ); - - if (g_flushSave.GetBool( ) == true ) { - // force flushing with each write... for tracking down - // save game bugs. - f->ForceFlush(); - } - - savegame.WriteHeader(); - - // go through all entities and threads and add them to the object list - for (i = 0; i < MAX_GENTITIES; i++) - { - idEntity* ent = entities[i]; - - if (ent == NULL) continue; - - // greebo: Give all entities a chance to register sub-objects (to resolve issue #2502) - ent->AddObjectsToSaveGame(&savegame); - - if (ent->GetTeamMaster() && ent->GetTeamMaster() != ent) - { - continue; // skip bindslaves, these are added by the team master - } - - for (idEntity* link = ent; link != NULL; link = link->GetNextTeamEntity()) - { - savegame.AddObject( link ); - } - } - - idList threads; - threads = idThread::GetThreads(); - - for( i = 0; i < threads.Num(); i++ ) { - savegame.AddObject( threads[i] ); - } - - // DarkMod: Add darkmod specific objects here: - - savegame.AddObject( m_Grabber ); - - // write out complete object list - savegame.WriteObjectList(); - - program.Save( &savegame ); - - // Save the global hiding spot search collection - CHidingSpotSearchCollection::Instance().Save(&savegame); - - // Save our grabber pointer - savegame.WriteObject(m_Grabber); - - // Save whatever the model generator needs - m_ModelGenerator->Save(&savegame); - - // Save whatever the image map manager needs - m_ImageMapManager->Save(&savegame); - - // Save whatever the light controller needs - m_LightController->Save(&savegame); - - // Save whatever the I18N needs - m_I18N->Save(&savegame); - - m_DifficultyManager.Save(&savegame); - - for ( i = 0; i < NumAAS(); i++) - { - idAAS* aas = GetAAS(i); - if (aas != NULL) - { - aas->Save(&savegame); - } - } - - m_GamePlayTimer.Save(&savegame); - m_AreaManager.Save(&savegame); - m_ConversationSystem->Save(&savegame); - m_RelationsManager->Save(&savegame); - m_Shop->Save(&savegame); - LAS.Save(&savegame); - m_MissionManager->Save(&savegame); - -#ifdef TIMING_BUILD - debugtools::TimerManager::Instance().Save(&savegame); -#endif - - savegame.WriteInt( g_skill.GetInteger() ); - - savegame.WriteDict( &serverInfo ); - - savegame.WriteInt( numClients ); - for( i = 0; i < numClients; i++ ) { - savegame.WriteDict( &userInfo[ i ] ); - savegame.WriteUsercmd( usercmds[ i ] ); - savegame.WriteDict( &persistentPlayerInfo[ i ] ); - } - - for( i = 0; i < MAX_GENTITIES; i++ ) { - savegame.WriteObject( entities[ i ] ); - savegame.WriteInt( spawnIds[ i ] ); - } - - savegame.WriteInt( firstFreeIndex ); - savegame.WriteInt( num_entities ); - - // enityHash is restored by idEntity::Restore setting the entity name. - - savegame.WriteObject( world ); - - savegame.WriteInt( spawnedEntities.Num() ); - for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - savegame.WriteObject( ent ); - } - - savegame.WriteInt( activeEntities.Num() ); - for (idEntity* ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - savegame.WriteObject( ent ); - } - - // tels: save the list of music speakers - savegame.WriteInt( musicSpeakers.Num() ); - for( i = 0; i < musicSpeakers.Num(); i++ ) { - savegame.WriteInt( musicSpeakers[ i ] ); - } - - savegame.WriteInt(spawnedAI.Num()); - for (idAI* ai = spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) { - savegame.WriteObject(ai); - } - - savegame.WriteInt( numEntitiesToDeactivate ); - savegame.WriteBool( sortPushers ); - savegame.WriteBool( sortTeamMasters ); - savegame.WriteDict( &persistentLevelInfo ); - - persistentPlayerInventory->Save(&savegame); - - savegame.WriteInt(campaignInfoEntities.Num()); - for (i = 0; i < campaignInfoEntities.Num(); ++i) - { - savegame.WriteObject(campaignInfoEntities[i]); - } - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - savegame.WriteFloat( globalShaderParms[ i ] ); - } - - savegame.WriteBool(postMissionScreenActive); - - savegame.WriteInt( random.GetSeed() ); - savegame.WriteObject( frameCommandThread ); - - // clip - // push - // pvs - - testmodel = NULL; - testFx = NULL; - - savegame.WriteString( sessionCommand ); - - // FIXME: save smoke particles - - savegame.WriteInt( cinematicSkipTime ); - savegame.WriteInt( cinematicStopTime ); - savegame.WriteInt( cinematicMaxSkipTime ); - savegame.WriteBool( inCinematic ); - savegame.WriteBool( skipCinematic ); - - savegame.WriteBool( isMultiplayer ); - savegame.WriteInt( gameType ); - - savegame.WriteInt( framenum ); - savegame.WriteInt( previousTime ); - savegame.WriteInt( time ); - - savegame.WriteInt( vacuumAreaNum ); - - savegame.WriteInt( entityDefBits ); - savegame.WriteBool( isServer ); - savegame.WriteBool( isClient ); - - savegame.WriteInt( localClientNum ); - - // snapshotEntities is used for multiplayer only - - savegame.WriteInt( realClientTime ); - savegame.WriteBool( isNewFrame ); - savegame.WriteFloat( clientSmoothing ); - - portalSkyEnt.Save( &savegame ); - - savegame.WriteBool( portalSkyActive ); - - - - savegame.WriteBool( mapCycleLoaded ); - savegame.WriteInt( spawnCount ); - - if ( !locationEntities ) { - savegame.WriteInt( 0 ); - } else { - savegame.WriteInt( gameRenderWorld->NumAreas() ); - for( i = 0; i < gameRenderWorld->NumAreas(); i++ ) { - savegame.WriteObject( locationEntities[ i ] ); - } - } - - savegame.WriteObject( camera ); - - savegame.WriteMaterial( globalMaterial ); - - savegame.WriteDict( &spawnArgs ); - - savegame.WriteInt( playerPVS.i ); - savegame.WriteInt( playerPVS.h ); - savegame.WriteInt( playerConnectedAreas.i ); - savegame.WriteInt( playerConnectedAreas.h ); - - savegame.WriteVec3( gravity ); - - // gamestate - - savegame.WriteBool( influenceActive ); - savegame.WriteInt( nextGibTime ); - - //Save LightGem - J.C.Denton - m_lightGem.Save( savegame ); - - savegame.WriteInt(m_InterMissionTriggers.Num()); - for (int i = 0; i < m_InterMissionTriggers.Num(); ++i) - { - savegame.WriteInt(m_InterMissionTriggers[i].missionNum); - savegame.WriteString(m_InterMissionTriggers[i].activatorName); - savegame.WriteString(m_InterMissionTriggers[i].targetName); - } - - m_sndProp->Save(&savegame); - m_MissionData->Save(&savegame); - savegame.WriteInt(static_cast(m_MissionResult)); - - m_CampaignStats->Save(&savegame); - - savegame.WriteInt(m_HighestSRId); - - savegame.WriteInt(m_Timer.Num()); - for (int i = 0; i < m_Timer.Num(); i++) - { - m_Timer[i]->Save(&savegame); - } - - savegame.WriteInt(m_StimTimer.Num()); - for (int i = 0; i < m_StimTimer.Num(); i++) - { - savegame.WriteInt(m_StimTimer[i]->GetUniqueId()); - } - - savegame.WriteInt(m_StimEntity.Num()); - for (int i = 0; i < m_StimEntity.Num(); i++) - { - m_StimEntity[i].Save(&savegame); - } - - savegame.WriteInt(m_RespEntity.Num()); - for (int i = 0; i < m_RespEntity.Num(); i++) - { - m_RespEntity[i].Save(&savegame); - } - - m_EscapePointManager->Save(&savegame); - - // greebo: Save the maximum frob distance - savegame.WriteFloat(g_Global.m_MaxFrobDistance); - - // spawnSpots - // initialSpots - // currentInitialSpot - // newInfo - // makingBuild - // shakeSounds - - // write out pending events - idEvent::Save( &savegame ); - - // Tels: Save the GUI command stack - savegame.WriteInt( m_GUICommandArgs ); - int cmds = m_GUICommandStack.Num(); - savegame.WriteInt( cmds ); - for( i = 0; i < cmds; i++ ) { - savegame.WriteString( m_GUICommandStack[i] ); - } - - // greebo: Close the savegame, this will invoke a recursive Save on all registered objects - savegame.Close(); - - // save all accumulated cache to file - savegame.FinalizeCache(); - - // Send a message to the HUD - GetLocalPlayer()->SendHUDMessage("#str_02916"); // "Game Saved" -} - -/* -=========== -idGameLocal::GetPersistentPlayerInfo -============ -*/ -const idDict &idGameLocal::GetPersistentPlayerInfo( int clientNum ) { - idEntity *ent; - - persistentPlayerInfo[ clientNum ].Clear(); - ent = entities[ clientNum ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - static_cast(ent)->SavePersistantInfo(); - } - - return persistentPlayerInfo[ clientNum ]; -} - -/* -=========== -idGameLocal::SetPersistentPlayerInfo -============ -*/ -void idGameLocal::SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) { - persistentPlayerInfo[ clientNum ] = playerInfo; -} - -/* -============ -idGameLocal::Printf -============ -*/ -void idGameLocal::Printf( const char *fmt, ... ) const { - va_list argptr; - char text[MAX_STRING_CHARS]; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - common->Printf( "%s", text ); -} - -/* -============ -idGameLocal::DPrintf -============ -*/ -void idGameLocal::DPrintf( const char *fmt, ... ) const { - va_list argptr; - char text[MAX_STRING_CHARS]; - - if ( !developer.GetBool() ) { - return; - } - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - common->Printf( "%s", text ); -} - -/* -============ -idGameLocal::Warning -============ -*/ -void idGameLocal::Warning( const char *fmt, ... ) const { - va_list argptr; - char text[MAX_STRING_CHARS]; - idThread * thread; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - thread = idThread::CurrentThread(); - if ( thread ) { - thread->Warning( "%s", text ); - } else { - common->Warning( "%s", text ); - } -} - -/* -============ -idGameLocal::DWarning -============ -*/ -void idGameLocal::DWarning( const char *fmt, ... ) const { - va_list argptr; - char text[MAX_STRING_CHARS]; - idThread * thread; - - if ( !developer.GetBool() ) { - return; - } - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - thread = idThread::CurrentThread(); - if ( thread ) { - thread->Warning( "%s", text ); - } else { - common->DWarning( "%s", text ); - } -} - -/* -============ -idGameLocal::Error -============ -*/ -void idGameLocal::Error( const char *fmt, ... ) const { - va_list argptr; - char text[MAX_STRING_CHARS]; - idThread * thread; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - // Send this error message to the GUI queue - m_guiError = text; - - thread = idThread::CurrentThread(); - if ( thread ) { - thread->Error( "%s", text ); - } else { - common->Error( "%s", text ); - } -} - -/* -=============== -gameError -=============== -*/ -void gameError( const char *fmt, ... ) { - va_list argptr; - char text[MAX_STRING_CHARS]; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - gameLocal.Error( "%s", text ); -} - -/* -=========== -idGameLocal::SetLocalClient -============ -*/ -void idGameLocal::SetLocalClient( int clientNum ) { - localClientNum = clientNum; -} - -/* -=========== -idGameLocal::SetUserInfo -============ -*/ -const idDict* idGameLocal::SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ) { - int i; - bool modifiedInfo = false; - - this->isClient = isClient; - - if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) { - idGameLocal::userInfo[ clientNum ] = userInfo; - - // server sanity - if ( canModify ) { - - // don't let numeric nicknames, it can be exploited to go around kick and ban commands from the server - if ( idStr::IsNumeric( this->userInfo[ clientNum ].GetString( "ui_name" ) ) ) { - idGameLocal::userInfo[ clientNum ].Set( "ui_name", va( "%s_", idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ) ) ); - modifiedInfo = true; - } - - // don't allow dupe nicknames - for ( i = 0; i < numClients; i++ ) { - if ( i == clientNum ) { - continue; - } - if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { - if ( !idStr::Icmp( idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ), idGameLocal::userInfo[ i ].GetString( "ui_name" ) ) ) { - idGameLocal::userInfo[ clientNum ].Set( "ui_name", va( "%s_", idGameLocal::userInfo[ clientNum ].GetString( "ui_name" ) ) ); - modifiedInfo = true; - i = -1; // rescan - continue; - } - } - } - } - - if ( entities[ clientNum ] && entities[ clientNum ]->IsType( idPlayer::Type ) ) { - modifiedInfo |= static_cast( entities[ clientNum ] )->UserInfoChanged(canModify); - } - - if ( !isClient ) { - // now mark this client in game - mpGame.EnterGame( clientNum ); - } - } - - if ( modifiedInfo ) { - assert( canModify ); - - newInfo = idGameLocal::userInfo[ clientNum ]; - return &newInfo; - } - return NULL; -} - -/* -=========== -idGameLocal::GetUserInfo -============ -*/ -const idDict* idGameLocal::GetUserInfo( int clientNum ) { - if ( entities[ clientNum ] && entities[ clientNum ]->IsType( idPlayer::Type ) ) { - return &userInfo[ clientNum ]; - } - return NULL; -} - -/* -=========== -idGameLocal::SetServerInfo -============ -*/ -void idGameLocal::SetServerInfo( const idDict &_serverInfo ) { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - serverInfo = _serverInfo; - UpdateServerInfoFlags(); - - if ( !isClient ) { - // Let our clients know the server info changed - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SERVERINFO ); - outMsg.WriteDeltaDict( gameLocal.serverInfo, NULL ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - } -} - - -/* -=================== -idGameLocal::LoadMap - -Initializes all map variables common to both save games and spawned games. -=================== -*/ -void idGameLocal::LoadMap( const char *mapName, int randseed ) { - int i; - bool sameMap = (mapFile && idStr::Icmp(mapFileName, mapName) == 0); - - // clear the sound system - gameSoundWorld->ClearAllSoundEmitters(); - - musicSpeakers.Clear(); // Tels: Clear the list even on reload to account for dynamic changes - cv_music_volume.SetModified(); // SnoopJeDi: we want to fade on level start - - InitAsyncNetwork(); - - if ( !sameMap || ( mapFile && mapFile->NeedsReload() ) ) { - // load the .map file - if ( mapFile ) { - delete mapFile; - } - mapFile = new idMapFile; - if ( !mapFile->Parse( idStr( mapName ) + ".map" ) ) { - delete mapFile; - mapFile = NULL; - Error( "Couldn't load %s", mapName ); - } - tdmDeclTDM_MatInfo::precacheMap( mapFile ); - } - mapFileName = mapFile->GetName(); - - // load the collision map - collisionModelManager->LoadMap( mapFile ); - - numClients = 0; - - // initialize all entities for this game - memset( entities, 0, sizeof( entities ) ); - memset( usercmds, 0, sizeof( usercmds ) ); - memset( spawnIds, -1, sizeof( spawnIds ) ); - spawnCount = INITIAL_SPAWN_COUNT; - - spawnedEntities.Clear(); - activeEntities.Clear(); - spawnedAI.Clear(); - numEntitiesToDeactivate = 0; - sortTeamMasters = false; - sortPushers = false; - lastGUIEnt = NULL; - lastGUI = 0; - - globalMaterial = NULL; - - memset( globalShaderParms, 0, sizeof( globalShaderParms ) ); - - // always leave room for the max number of clients, - // even if they aren't all used, so numbers inside that - // range are NEVER anything but clients - num_entities = MAX_CLIENTS; - firstFreeIndex = MAX_CLIENTS; - - // reset the random number generator. - // Tels: use a random seed for single-player, too, otherwise map content can't be random - //random.SetSeed( isMultiplayer ? randseed : 0 ); - random.SetSeed( randseed ); - - camera = NULL; - world = NULL; - testmodel = NULL; - testFx = NULL; - - previousTime = 0; - time = 0; - framenum = 0; - sessionCommand = ""; - nextGibTime = 0; - - portalSkyEnt = NULL; - - portalSkyActive = false; - - - - vacuumAreaNum = -1; // if an info_vacuum is spawned, it will set this - - if ( !editEntities ) { - editEntities = new idEditEntities; - } - - gravity.Set( 0, 0, -g_gravity.GetFloat() ); - - spawnArgs.Clear(); - - skipCinematic = false; - inCinematic = false; - cinematicSkipTime = 0; - cinematicStopTime = 0; - cinematicMaxSkipTime = 0; - - clip.Init(); - pvs.Init(); - - - // this will always fail for now, have not yet written the map compile - m_sndPropLoader->CompileMap( mapFile ); - - playerPVS.i = -1; - playerConnectedAreas.i = -1; - - // load navigation system for all the different monster sizes - for( i = 0; i < aasNames.Num(); i++ ) { - aasList[ i ]->Init( idStr( mapFileName ).SetFileExtension( aasNames[ i ] ).c_str(), mapFile->GetGeometryCRC() ); - } - - /*! - * The Dark Mod LAS: Init the Light Awareness System - * This must occur AFTER the AAS list is loaded - */ - LAS.initialize(); - - // clear the smoke particle free list - smokeParticles->Init(); - - // cache miscellanious media references - FindEntityDef( "preCacheExtras", false ); - - if ( !sameMap ) { - mapFile->RemovePrimitiveData(); - } - - // greebo: Reset the flag. When a map is loaded, the success screen is definitely not shown anymore. - // This is meant to catch cases where the player is reloading a map from the console without clicking - // the "Continue" button on the success GUI. I can't stop him, so I need to track this here. - postMissionScreenActive = false; - - if (m_MissionData != NULL) - { - m_MissionData->ClearGUIState(); - } - - m_strMainAmbientLightName = "ambient_world"; // Default name for main ambient light. J.C.Denton. - -} - -/* -=================== -idGameLocal::LocalMapRestart -=================== -*/ -void idGameLocal::LocalMapRestart( ) { - int i, latchSpawnCount; - - Printf( "----------- Game Map Restart ------------\n" ); - - gamestate = GAMESTATE_SHUTDOWN; - - for ( i = 0; i < MAX_CLIENTS; i++ ) { - if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { - static_cast< idPlayer * >( entities[ i ] )->PrepareForRestart(); - } - } - - eventQueue.Shutdown(); - savedEventQueue.Shutdown(); - - MapClear( false ); - - // clear the smoke particle free list - smokeParticles->Init(); - - // clear the sound system - if ( gameSoundWorld ) { - gameSoundWorld->ClearAllSoundEmitters(); - } - - /*! - * The Dark Mod LAS: Init the LAS - */ - LAS.initialize(); - - // the spawnCount is reset to zero temporarily to spawn the map entities with the same spawnId - // if we don't do that, network clients are confused and don't show any map entities - latchSpawnCount = spawnCount; - spawnCount = INITIAL_SPAWN_COUNT; - - gamestate = GAMESTATE_STARTUP; - - program.Restart(); - - InitScriptForMap(); - - MapPopulate(); - - // once the map is populated, set the spawnCount back to where it was so we don't risk any collision - // (note that if there are no players in the game, we could just leave it at it's current value) - spawnCount = latchSpawnCount; - - // setup the client entities again - for ( i = 0; i < MAX_CLIENTS; i++ ) { - if ( entities[ i ] && entities[ i ]->IsType( idPlayer::Type ) ) { - static_cast< idPlayer * >( entities[ i ] )->Restart(); - } - } - - gamestate = GAMESTATE_ACTIVE; - m_MissionResult = MISSION_INPROGRESS; - - Printf( "--------------------------------------\n" ); -} - -/* -=================== -idGameLocal::MapRestart -=================== -*/ -void idGameLocal::MapRestart( ) { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - idDict newInfo; - int i; - const idKeyValue *keyval, *keyval2; - - if ( isClient ) { - LocalMapRestart(); - } else { - newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); - for ( i = 0; i < newInfo.GetNumKeyVals(); i++ ) { - keyval = newInfo.GetKeyVal( i ); - keyval2 = serverInfo.FindKey( keyval->GetKey() ); - if ( !keyval2 ) { - break; - } - // a select set of si_ changes will cause a full restart of the server - if ( keyval->GetValue().Cmp( keyval2->GetValue() ) && - ( !keyval->GetKey().Cmp( "si_pure" ) || !keyval->GetKey().Cmp( "si_map" ) ) ) { - break; - } - } - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); - if ( i != newInfo.GetNumKeyVals() ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); - } else { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_RESTART ); - outMsg.WriteBits( 1, 1 ); - outMsg.WriteDeltaDict( serverInfo, NULL ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - - LocalMapRestart(); - mpGame.MapRestart(); - } - } -} - -/* -=================== -idGameLocal::MapRestart_f -=================== -*/ -void idGameLocal::MapRestart_f( const idCmdArgs &args ) { - if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { - common->Printf( "server is not running - use spawnServer\n" ); - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "spawnServer\n" ); - return; - } - - gameLocal.MapRestart( ); -} - -/* -=================== -idGameLocal::NextMap -=================== -*/ -bool idGameLocal::NextMap( void ) { - const function_t *func; - idThread *thread; - idDict newInfo; - const idKeyValue *keyval, *keyval2; - int i; - - if ( !g_mapCycle.GetString()[0] ) { - Printf( m_I18N->Translate( "#str_04294" ) ); - return false; - } - if ( fileSystem->ReadFile( g_mapCycle.GetString(), NULL, NULL ) < 0 ) { - if ( fileSystem->ReadFile( va( "%s.scriptcfg", g_mapCycle.GetString() ), NULL, NULL ) < 0 ) { - Printf( "map cycle script '%s': not found\n", g_mapCycle.GetString() ); - return false; - } else { - g_mapCycle.SetString( va( "%s.scriptcfg", g_mapCycle.GetString() ) ); - } - } - - Printf( "map cycle script: '%s'\n", g_mapCycle.GetString() ); - func = program.FindFunction( "mapcycle::cycle" ); - if ( !func ) { - program.CompileFile( g_mapCycle.GetString() ); - func = program.FindFunction( "mapcycle::cycle" ); - } - if ( !func ) { - Printf( "Couldn't find mapcycle::cycle\n" ); - return false; - } - thread = new idThread( func ); - thread->Start(); - delete thread; - - newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); - for ( i = 0; i < newInfo.GetNumKeyVals(); i++ ) { - keyval = newInfo.GetKeyVal( i ); - keyval2 = serverInfo.FindKey( keyval->GetKey() ); - if ( !keyval2 || keyval->GetValue().Cmp( keyval2->GetValue() ) ) { - break; - } - } - return ( i != newInfo.GetNumKeyVals() ); -} - -/* -=================== -idGameLocal::NextMap_f -=================== -*/ -void idGameLocal::NextMap_f( const idCmdArgs &args ) { - if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { - common->Printf( "server is not running\n" ); - return; - } - - gameLocal.NextMap( ); - // next map was either voted for or triggered by a server command - always restart - gameLocal.MapRestart( ); -} - -/* -=================== -idGameLocal::MapPopulate -Dark Mod: Sound prop initialization added -=================== -*/ -void idGameLocal::MapPopulate( void ) { - - if ( isMultiplayer ) { - cvarSystem->SetCVarBool( "r_skipSpecular", false ); - } - - // parse the key/value pairs and spawn entities - SpawnMapEntities(); - - // mark location entities in all connected areas - SpreadLocations(); - - // prepare the list of randomized initial spawn spots - RandomizeInitialSpawns( ); - - // spawnCount - 1 is the number of entities spawned into the map, their indexes started at MAX_CLIENTS (included) - // mapSpawnCount is used as the max index of map entities, it's the first index of non-map entities - mapSpawnCount = MAX_CLIENTS + spawnCount - 1; - - // read in the soundprop data for various locations - m_sndPropLoader->FillLocationData(); - - // Transfer sound prop data from loader to gameplay object - m_sndProp->SetupFromLoader( m_sndPropLoader ); - - m_sndPropLoader->Shutdown(); - - // Initialise the escape point manager after all the entities have been spawned. - m_EscapePointManager->InitAAS(); - - // execute pending events before the very first game frame - // this makes sure the map script main() function is called - // before the physics are run so entities can bind correctly - Printf( "==== Processing events ====\n" ); - idEvent::ServiceEvents(); -} - -/* -=================== -idGameLocal::InitFromNewMap -=================== -*/ -void idGameLocal::InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) { - - this->isServer = isServer; - this->isClient = isClient; - this->isMultiplayer = isServer || isClient; - - if ( mapFileName.Length() ) { - MapShutdown(); - } - - idStr mapNameStr = mapName; - mapNameStr.StripLeadingOnce("maps/"); - mapNameStr.StripFileExtension(); - - idUserInterface* loadingGUI = uiManager->FindGui(va("guis/map/%s.gui", mapNameStr.c_str()), false, false, false); - - if (loadingGUI != NULL) - { - // Use our own randomizer, the gameLocal.random one is not yet initialised - loadingGUI->SetStateFloat("random_value", static_cast(rnd.Random())); - loadingGUI->HandleNamedEvent("OnRandomValueInitialised"); - } - - // greebo: Clear the mission data, it might have been filled during the objectives screen display - m_MissionData->Clear(); - - // Clear the persistent data if starting a new campaign - if (m_MissionManager->CurrentModIsCampaign() && m_MissionManager->GetCurrentMissionIndex() == 0) - { - ClearPersistentInfo(); - } - - Printf( "----------- Game Map Init ------------\n" ); - - gamestate = GAMESTATE_STARTUP; - - gameRenderWorld = renderWorld; - gameSoundWorld = soundWorld; - - LoadMap( mapName, randseed ); - - // Instantiate our grabber entity - m_Grabber = static_cast(CGrabber::Type.CreateInstance()); - - // greebo: Initialize the Difficulty Manager, before any entities are spawned - m_DifficultyManager.Init(mapFile); - m_ConversationSystem->Init(mapFile); - - // Immediately apply the CVAR difficulty settings - m_DifficultyManager.ApplyCVARDifficultySettings(); - - InitScriptForMap(); - - // Initialize the AI relationships - // greebo: Do this before spawning the rest of the map entities to give them a chance - // to override the default settings found on the entityDef - const idDict* defaultRelationsDict = FindEntityDefDict(cv_tdm_default_relations_def.GetString()); - - if (defaultRelationsDict != NULL) - { - m_RelationsManager->SetFromArgs(*defaultRelationsDict); - } - - MapPopulate(); - - // ishtvan: Set the player variable on the grabber - //m_Grabber->SetPlayer( GetLocalPlayer() ); // greebo: GetLocalPlayer() returns NULL, moved to idPlayer::Spawn() - - // greebo: Add the elevator reachabilities to the AAS - SetupEAS(); - - // Then, apply the worldspawn settings - m_RelationsManager->SetFromArgs( world->spawnArgs ); - - mpGame.Reset(); - - mpGame.Precache(); - - // free up any unused animations - animationLib.FlushUnusedAnims(); - - gamestate = GAMESTATE_ACTIVE; - m_MissionResult = MISSION_INPROGRESS; - - // Let the mission database know that we start playing - m_MissionManager->OnMissionStart(); - - // We need an objectives update now that we've loaded the map - m_MissionData->ClearGUIState(); - - Printf( "--------------------------------------\n" ); -} - -/* -================= -idGameLocal::InitFromSaveGame -================= -*/ -bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ) { - int i; - int num; - idEntity *ent; - idDict si; - - if ( mapFileName.Length() ) { - MapShutdown(); - } - - Printf( "------- Game Map Init SaveGame -------\n" ); - - gamestate = GAMESTATE_STARTUP; - - gameRenderWorld = renderWorld; - gameSoundWorld = soundWorld; - - idRestoreGame savegame( saveGameFile ); - - savegame.ReadHeader(); - - if (!cv_force_savegame_load.GetBool() && savegame.GetCodeRevision() != RevisionTracker::Instance().GetHighestRevision()) - { - gameLocal.Printf("Can't load this savegame, was saved with an old revision %d\n.", savegame.GetCodeRevision()); - return false; - } - - // Read and initialize cache from file - savegame.InitializeCache(); - - // Create the list of all objects in the game - savegame.CreateObjects(); - - // Load the idProgram, also checking to make sure scripting hasn't changed since the savegame - if ( program.Restore( &savegame ) == false ) { - - // Abort the load process, and let the session know so that it can restart the level - // with the player persistent data. - savegame.DeleteObjects(); - program.Restart(); - - return false; - } - - // load the map needed for this savegame - LoadMap( mapName, 0 ); - - // Restore the global hiding spot search collection - CHidingSpotSearchCollection::Instance().Restore(&savegame); - - // Restore our grabber pointer - savegame.ReadObject( reinterpret_cast(m_Grabber) ); - - m_ModelGenerator->Restore(&savegame); - m_ImageMapManager->Restore(&savegame); - m_LightController->Restore(&savegame); - m_I18N->Restore(&savegame); - - m_DifficultyManager.Restore(&savegame); - - for ( i = 0; i < NumAAS(); i++) - { - idAAS* aas = GetAAS(i); - if (aas != NULL) - { - aas->Restore(&savegame); - } - } - - m_GamePlayTimer.Restore(&savegame); - m_GamePlayTimer.SetEnabled(false); - m_AreaManager.Restore(&savegame); - m_ConversationSystem->Restore(&savegame); - m_RelationsManager->Restore(&savegame); - m_Shop->Restore(&savegame); - LAS.Restore(&savegame); - m_MissionManager->Restore(&savegame); - -#ifdef TIMING_BUILD - debugtools::TimerManager::Instance().Restore(&savegame); -#endif - - savegame.ReadInt( i ); - g_skill.SetInteger( i ); - - // precache the player - FindEntityDef( cv_player_spawnclass.GetString(), false ); - - // precache the empty model (used by idEntity::m_renderTrigger) - renderModelManager->FindModel( cv_empty_model.GetString() ); - - m_lightGem.SpawnLightGemEntity( mapFile ); - - // precache any media specified in the map - for ( i = 0; i < mapFile->GetNumEntities(); i++ ) { - idMapEntity *mapEnt = mapFile->GetEntity( i ); - - if ( !InhibitEntitySpawn( mapEnt->epairs ) ) { - CacheDictionaryMedia( &mapEnt->epairs ); - const char *classname = mapEnt->epairs.GetString( "classname" ); - if ( classname != '\0' ) { - FindEntityDef( classname, false ); - } - } - } - - savegame.ReadDict( &si ); - SetServerInfo( si ); - - savegame.ReadInt( numClients ); - for( i = 0; i < numClients; i++ ) { - savegame.ReadDict( &userInfo[ i ] ); - savegame.ReadUsercmd( usercmds[ i ] ); - savegame.ReadDict( &persistentPlayerInfo[ i ] ); - } - - for( i = 0; i < MAX_GENTITIES; i++ ) { - savegame.ReadObject( reinterpret_cast( entities[ i ] ) ); - savegame.ReadInt( spawnIds[ i ] ); - - // restore the entityNumber - if ( entities[ i ] != NULL ) { - entities[ i ]->entityNumber = i; - } - } - - savegame.ReadInt( firstFreeIndex ); - savegame.ReadInt( num_entities ); - - // enityHash is restored by idEntity::Restore setting the entity name. - - savegame.ReadObject( reinterpret_cast( world ) ); - - savegame.ReadInt( num ); - for( i = 0; i < num; i++ ) { - savegame.ReadObject( reinterpret_cast( ent ) ); - assert( ent ); - if ( ent ) { - ent->spawnNode.AddToEnd( spawnedEntities ); - } - } - - savegame.ReadInt( num ); - for( i = 0; i < num; i++ ) { - savegame.ReadObject( reinterpret_cast( ent ) ); - assert( ent ); - if ( ent ) { - ent->activeNode.AddToEnd( activeEntities ); - } - } - - // tels: restore the list of music speakers - savegame.ReadInt( num ); - musicSpeakers.Clear(); - for( i = 0; i < num; i++ ) { - int id; - savegame.ReadInt( id ); - musicSpeakers.Append( id ); - } - - savegame.ReadInt( num ); - for( i = 0; i < num; i++ ) - { - idAI* ai(NULL); - savegame.ReadObject(reinterpret_cast(ai)); - assert(ai != NULL); - - if (ai != NULL) - { - ai->aiNode.AddToEnd(spawnedAI); - } - } - - savegame.ReadInt( numEntitiesToDeactivate ); - savegame.ReadBool( sortPushers ); - savegame.ReadBool( sortTeamMasters ); - savegame.ReadDict( &persistentLevelInfo ); - - persistentPlayerInventory->Restore(&savegame); - - savegame.ReadInt(num); - campaignInfoEntities.SetNum(num); - for (i = 0; i < num; ++i) - { - savegame.ReadObject(reinterpret_cast(campaignInfoEntities[i])); - } - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - savegame.ReadFloat( globalShaderParms[ i ] ); - } - - savegame.ReadBool(postMissionScreenActive); - - savegame.ReadInt( i ); - random.SetSeed( i ); - - savegame.ReadObject( reinterpret_cast( frameCommandThread ) ); - - // clip - // push - // pvs - - // testmodel = "" - // testFx = "" - - savegame.ReadString( sessionCommand ); - - // FIXME: save smoke particles - - savegame.ReadInt( cinematicSkipTime ); - savegame.ReadInt( cinematicStopTime ); - savegame.ReadInt( cinematicMaxSkipTime ); - savegame.ReadBool( inCinematic ); - savegame.ReadBool( skipCinematic ); - - savegame.ReadBool( isMultiplayer ); - savegame.ReadInt( (int &)gameType ); - - savegame.ReadInt( framenum ); - savegame.ReadInt( previousTime ); - savegame.ReadInt( time ); - - savegame.ReadInt( vacuumAreaNum ); - - savegame.ReadInt( entityDefBits ); - savegame.ReadBool( isServer ); - savegame.ReadBool( isClient ); - - savegame.ReadInt( localClientNum ); - - // snapshotEntities is used for multiplayer only - - savegame.ReadInt( realClientTime ); - savegame.ReadBool( isNewFrame ); - savegame.ReadFloat( clientSmoothing ); - - portalSkyEnt.Restore( &savegame ); - - savegame.ReadBool( portalSkyActive ); - - - - savegame.ReadBool( mapCycleLoaded ); - savegame.ReadInt( spawnCount ); - - savegame.ReadInt( num ); - if ( num ) { - if ( num != gameRenderWorld->NumAreas() ) { - savegame.Error( "idGameLocal::InitFromSaveGame: number of areas in map differs from save game." ); - } - - locationEntities = new idLocationEntity *[ num ]; - for( i = 0; i < num; i++ ) { - savegame.ReadObject( reinterpret_cast( locationEntities[ i ] ) ); - } - } - - savegame.ReadObject( reinterpret_cast( camera ) ); - - savegame.ReadMaterial( globalMaterial ); - - savegame.ReadDict( &spawnArgs ); - - savegame.ReadInt( playerPVS.i ); - savegame.ReadInt( (int &)playerPVS.h ); - savegame.ReadInt( playerConnectedAreas.i ); - savegame.ReadInt( (int &)playerConnectedAreas.h ); - - savegame.ReadVec3( gravity ); - - // gamestate is restored after restoring everything else - - savegame.ReadBool( influenceActive ); - savegame.ReadInt( nextGibTime ); - - // Restore LightGem - J.C.Denton - m_lightGem.Restore( savegame ); - - savegame.ReadInt(num); - m_InterMissionTriggers.SetNum(num); - for (int i = 0; i < num; ++i) - { - savegame.ReadInt(m_InterMissionTriggers[i].missionNum); - savegame.ReadString(m_InterMissionTriggers[i].activatorName); - savegame.ReadString(m_InterMissionTriggers[i].targetName); - } - - m_sndProp->Restore(&savegame); - m_MissionData->Restore(&savegame); - - int missResult; - savegame.ReadInt(missResult); - m_MissionResult = static_cast(missResult); - - m_CampaignStats->Restore(&savegame); - - savegame.ReadInt(m_HighestSRId); - - savegame.ReadInt(num); - m_Timer.SetNum(num); - for (int i = 0; i < num; i++) - { - m_Timer[i] = new CStimResponseTimer; - m_Timer[i]->Restore(&savegame); - } - - // The list to take all the values, they will be restored later on - idList tempStimTimerIdList; - savegame.ReadInt(num); - tempStimTimerIdList.SetNum(num); - for (int i = 0; i < num; i++) - { - savegame.ReadInt(tempStimTimerIdList[i]); - } - - savegame.ReadInt(num); - m_StimEntity.SetNum(num); - for (int i = 0; i < num; i++) - { - m_StimEntity[i].Restore(&savegame); - } - - savegame.ReadInt(num); - m_RespEntity.SetNum(num); - for (int i = 0; i < num; i++) - { - m_RespEntity[i].Restore(&savegame); - } - - m_EscapePointManager->Restore(&savegame); - - // greebo: Restore the maximum frob distance - savegame.ReadFloat(g_Global.m_MaxFrobDistance); - - // spawnSpots - // initialSpots - // currentInitialSpot - // newInfo - // makingBuild - // shakeSounds - - // Read out pending events - idEvent::Restore( &savegame ); - - // Tels: Restore the GUI command stack - int cmds; - savegame.ReadInt( m_GUICommandArgs ); - savegame.ReadInt( cmds ); - m_GUICommandStack.Clear(); - m_GUICommandStack.SetNum( cmds ); - for( i = 0; i < cmds; i++ ) { - savegame.ReadString( m_GUICommandStack[i] ); - } - savegame.RestoreObjects(); - - mpGame.Reset(); - - mpGame.Precache(); - - // free up any unused animations - animationLib.FlushUnusedAnims(); - - gamestate = GAMESTATE_ACTIVE; - - //FIX: Set the walkspeed back to the stored value. - pm_walkspeed.SetFloat( m_walkSpeed ); - - // Restore the physics pointer in the grabber. - gameLocal.m_Grabber->SetPhysicsFromDragEntity(); - - // Restore the CStim* pointers in the m_StimTimer list - m_StimTimer.SetNum(tempStimTimerIdList.Num()); - for (int i = 0; i < tempStimTimerIdList.Num(); i++) - { - m_StimTimer[i] = static_cast(FindStimResponse(tempStimTimerIdList[i]).get()); - } - - // Let the mission database know that we start playing - m_MissionManager->OnMissionStart(); - - Printf( "--------------------------------------\n" ); - - // Restart the timer - m_GamePlayTimer.Start(); - - return true; -} - -/* -=========== -idGameLocal::MapClear -=========== -*/ -void idGameLocal::MapClear( bool clearClients ) { - int i; - - for( i = ( clearClients ? 0 : MAX_CLIENTS ); i < MAX_GENTITIES; i++ ) { - delete entities[ i ]; - // ~idEntity is in charge of setting the pointer to NULL - // it will also clear pending events for this entity - assert( !entities[ i ] ); - spawnIds[ i ] = -1; - } - - entityHash.Clear( 1024, MAX_GENTITIES ); - - if ( !clearClients ) { - // add back the hashes of the clients - for ( i = 0; i < MAX_CLIENTS; i++ ) { - if ( !entities[ i ] ) { - continue; - } - entityHash.Add( entityHash.GenerateKey( entities[ i ]->name.c_str(), true ), i ); - } - } - - delete frameCommandThread; - frameCommandThread = NULL; - - if ( editEntities ) { - delete editEntities; - editEntities = NULL; - } - - delete[] locationEntities; - locationEntities = NULL; -} - -/* -=========== -idGameLocal::MapShutdown -============ -*/ -void idGameLocal::MapShutdown( void ) { - Printf( "--------- Game Map Shutdown ----------\n" ); - - gamestate = GAMESTATE_SHUTDOWN; - - if ( gameRenderWorld ) { - // clear any debug lines, text, and polygons - gameRenderWorld->DebugClearLines( 0 ); - gameRenderWorld->DebugClearPolygons( 0 ); - } - - // clear out camera if we're in a cinematic - if ( inCinematic ) { - camera = NULL; - inCinematic = false; - } - - // Run the grabber->clear() method before the entities get deleted from the map - if (m_Grabber != NULL) - { - m_Grabber->Clear(); - } - - MapClear( true ); - - // reset the script to the state it was before the map was started - program.Restart(); - - if ( smokeParticles ) { - smokeParticles->Shutdown(); - } - - /*! - * The Dark Mod LAS: shut down the LAS - */ - LAS.shutDown(); - - pvs.Shutdown(); - - // Remove the grabber entity itself (note that it's safe to pass NULL pointers to delete) - delete m_Grabber; - m_Grabber = NULL; - - m_sndProp->Clear(); - if (m_RelationsManager != NULL) - { - m_RelationsManager->Clear(); - } - if (m_ConversationSystem != NULL) - { - m_ConversationSystem->Clear(); - } - - m_DifficultyManager.Clear(); - - if (m_ModelGenerator != NULL) - { - m_ModelGenerator->Print(); - m_ModelGenerator->Clear(); - } - if (m_ImageMapManager != NULL) - { - m_ImageMapManager->Clear(); - } - - if (m_LightController != NULL) - { - m_LightController->Clear(); - } - if (m_I18N != NULL) - { - m_I18N->Clear(); - } - - // greebo: Don't clear the shop - MapShutdown() is called right before loading a map - // m_Shop->Clear(); - - clip.Shutdown(); - idClipModel::ClearTraceModelCache(); - - ShutdownAsyncNetwork(); - - mapFileName.Clear(); - - gameRenderWorld = NULL; - gameSoundWorld = NULL; - - gamestate = GAMESTATE_NOMAP; - - // Save the current walkspeed - m_walkSpeed = pm_walkspeed.GetFloat(); - - Printf( "--------------------------------------\n" ); -} - -/* -=================== -idGameLocal::DumpOggSounds -=================== -*/ -void idGameLocal::DumpOggSounds( void ) { - int i, j, k, size, totalSize; - idFile *file; - idStrList oggSounds, weaponSounds; - const idSoundShader *soundShader; - const soundShaderParms_t *parms; - idStr soundName; - - for ( i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++ ) { - soundShader = static_cast(declManager->DeclByIndex( DECL_SOUND, i, false )); - parms = soundShader->GetParms(); - - if ( soundShader->EverReferenced() && soundShader->GetState() != DS_DEFAULTED ) { - - const_cast(soundShader)->EnsureNotPurged(); - - for ( j = 0; j < soundShader->GetNumSounds(); j++ ) { - soundName = soundShader->GetSound( j ); - soundName.BackSlashesToSlashes(); - - // don't OGG sounds that cause a shake because that would - // cause continuous seeking on the OGG file which is expensive - if ( parms->shakes != 0.0f ) { - shakeSounds.AddUnique( soundName ); - continue; - } - - // if not voice over or combat chatter - if ( soundName.Find( "/vo/", false ) == -1 && - soundName.Find( "/combat_chatter/", false ) == -1 && - soundName.Find( "/enpro/", false ) == - 1 ) { - // don't OGG weapon sounds - if ( soundName.Find( "weapon", false ) != -1 || - soundName.Find( "gun", false ) != -1 || - soundName.Find( "bullet", false ) != -1 || - soundName.Find( "plasma", false ) != -1 ) { - weaponSounds.AddUnique( soundName ); - continue; - } - } - - for ( k = 0; k < shakeSounds.Num(); k++ ) { - if ( shakeSounds[k].IcmpPath( soundName ) == 0 ) { - break; - } - } - if ( k < shakeSounds.Num() ) { - continue; - } - - oggSounds.AddUnique( soundName ); - } - } - } - - file = fileSystem->OpenFileWrite( "makeogg.bat", "fs_savepath" ); - if ( file == NULL ) { - common->Warning( "Couldn't open makeogg.bat" ); - return; - } - - // list all the shake sounds - totalSize = 0; - for ( i = 0; i < shakeSounds.Num(); i++ ) { - size = fileSystem->ReadFile( shakeSounds[i], NULL, NULL ); - totalSize += size; - shakeSounds[i].Replace( "/", "\\" ); - file->Printf( "echo \"%s\" (%d kB)\n", shakeSounds[i].c_str(), size >> 10 ); - } - file->Printf( "echo %d kB in shake sounds\n\n\n", totalSize >> 10 ); - - // list all the weapon sounds - totalSize = 0; - for ( i = 0; i < weaponSounds.Num(); i++ ) { - size = fileSystem->ReadFile( weaponSounds[i], NULL, NULL ); - totalSize += size; - weaponSounds[i].Replace( "/", "\\" ); - file->Printf( "echo \"%s\" (%d kB)\n", weaponSounds[i].c_str(), size >> 10 ); - } - file->Printf( "echo %d kB in weapon sounds\n\n\n", totalSize >> 10 ); - - // list commands to convert all other sounds to ogg - totalSize = 0; - for ( i = 0; i < oggSounds.Num(); i++ ) { - size = fileSystem->ReadFile( oggSounds[i], NULL, NULL ); - totalSize += size; - oggSounds[i].Replace( "/", "\\" ); - file->Printf( "w:\\doom\\ogg\\oggenc -q 0 \"c:\\doom\\base\\%s\"\n", oggSounds[i].c_str() ); - file->Printf( "del \"c:\\doom\\base\\%s\"\n", oggSounds[i].c_str() ); - } - file->Printf( "\n\necho %d kB in OGG sounds\n\n\n", totalSize >> 10 ); - - fileSystem->CloseFile( file ); - - shakeSounds.Clear(); -} - -/* -=================== -idGameLocal::GetShakeSounds -=================== -*/ -void idGameLocal::GetShakeSounds( const idDict *dict ) { - const idSoundShader *soundShader; - const char *soundShaderName; - idStr soundName; - - soundShaderName = dict->GetString( "s_shader" ); - if ( soundShaderName != '\0' && dict->GetFloat( "s_shakes" ) != 0.0f ) { - soundShader = declManager->FindSound( soundShaderName ); - - for ( int i = 0; i < soundShader->GetNumSounds(); i++ ) { - soundName = soundShader->GetSound( i ); - soundName.BackSlashesToSlashes(); - - shakeSounds.AddUnique( soundName ); - } - } -} - -/* -=================== -idGameLocal::CacheDictionaryMedia - -This is called after parsing an EntityDef and for each entity spawnArgs before -merging the entitydef. It could be done post-merge, but that would -avoid the fast pre-cache check associated with each entityDef -=================== -*/ -void idGameLocal::CacheDictionaryMedia( const idDict *dict ) { - const idKeyValue *kv; - - if ( dict == NULL ) { - if ( cvarSystem->GetCVarBool( "com_makingBuild") ) { - DumpOggSounds(); - } - return; - } - - if ( cvarSystem->GetCVarBool( "com_makingBuild" ) ) { - GetShakeSounds( dict ); - } - - kv = dict->MatchPrefix( "model" ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->MediaPrint( "Precaching model %s\n", kv->GetValue().c_str() ); - // precache model/animations - if ( declManager->FindType( DECL_MODELDEF, kv->GetValue(), false ) == NULL ) { - // precache the render model - renderModelManager->FindModel( kv->GetValue() ); - // precache .cm files only - collisionModelManager->LoadModel( kv->GetValue(), true ); - // load any tdm_matinfo decls for materials referenced by the model - tdmDeclTDM_MatInfo::precacheModel( renderModelManager->FindModel( kv->GetValue() ) ); - } - } - kv = dict->MatchPrefix( "model", kv ); - } - - kv = dict->FindKey( "s_shader" ); - if ( kv && kv->GetValue().Length() ) { - declManager->FindType( DECL_SOUND, kv->GetValue() ); - } - - kv = dict->MatchPrefix( "snd", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_SOUND, kv->GetValue() ); - } - kv = dict->MatchPrefix( "snd", kv ); - } - - - kv = dict->MatchPrefix( "gui", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - if ( !idStr::Icmp( kv->GetKey(), "gui_noninteractive" ) - || !idStr::Icmpn( kv->GetKey(), "gui_parm", 8 ) - || !idStr::Icmp( kv->GetKey(), "gui_inventory" ) ) { - // unfortunate flag names, they aren't actually a gui - } else { - declManager->MediaPrint( "Precaching gui %s\n", kv->GetValue().c_str() ); - idUserInterface *gui = uiManager->Alloc(); - if ( gui ) { - gui->InitFromFile( kv->GetValue() ); - uiManager->DeAlloc( gui ); - } - } - } - kv = dict->MatchPrefix( "gui", kv ); - } - - kv = dict->FindKey( "texture" ); - if ( kv && kv->GetValue().Length() ) { - declManager->FindType( DECL_MATERIAL, kv->GetValue() ); - declManager->FindType( DECL_TDM_MATINFO, kv->GetValue() ); - } - - kv = dict->MatchPrefix( "mtr", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_MATERIAL, kv->GetValue() ); - declManager->FindType( DECL_TDM_MATINFO, kv->GetValue() ); - } - kv = dict->MatchPrefix( "mtr", kv ); - } - - // handles hud icons - kv = dict->MatchPrefix( "inv_icon", NULL ); - while ( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_MATERIAL, kv->GetValue() ); - } - kv = dict->MatchPrefix( "inv_icon", kv ); - } - - // handles teleport fx.. this is not ideal but the actual decision on which fx to use - // is handled by script code based on the teleport number - kv = dict->MatchPrefix( "teleport", NULL ); - if ( kv && kv->GetValue().Length() ) { - int teleportType = atoi( kv->GetValue() ); - const char *p = ( teleportType ) ? va( "fx/teleporter%i.fx", teleportType ) : "fx/teleporter.fx"; - declManager->FindType( DECL_FX, p ); - } - - kv = dict->MatchPrefix( "fx", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->MediaPrint( "Precaching fx %s\n", kv->GetValue().c_str() ); - declManager->FindType( DECL_FX, kv->GetValue() ); - } - kv = dict->MatchPrefix( "fx", kv ); - } - - kv = dict->MatchPrefix( "smoke", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - idStr prtName = kv->GetValue(); - int dash = prtName.Find('-'); - if ( dash > 0 ) { - prtName = prtName.Left( dash ); - } - declManager->FindType( DECL_PARTICLE, prtName ); - } - kv = dict->MatchPrefix( "smoke", kv ); - } - - kv = dict->MatchPrefix( "skin", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->MediaPrint( "Precaching skin %s\n", kv->GetValue().c_str() ); - declManager->FindType( DECL_SKIN, kv->GetValue() ); - } - kv = dict->MatchPrefix( "skin", kv ); - } - - kv = dict->MatchPrefix( "def", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - FindEntityDef( kv->GetValue().c_str(), false ); - } - kv = dict->MatchPrefix( "def", kv ); - } - - kv = dict->MatchPrefix( "video", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_VIDEO, kv->GetValue().c_str(), false ); - } - kv = dict->MatchPrefix( "video", kv ); - } - - kv = dict->MatchPrefix( "audio", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_AUDIO, kv->GetValue().c_str(), false ); - } - kv = dict->MatchPrefix( "audio", kv ); - } - - kv = dict->MatchPrefix( "xdata", NULL ); - while( kv ) { - if ( kv->GetValue().Length() ) { - declManager->FindType( DECL_XDATA, kv->GetValue().c_str(), false ); - } - kv = dict->MatchPrefix( "xdata", kv ); - } -} - -/* -=========== -idGameLocal::InitScriptForMap -============ -*/ -void idGameLocal::InitScriptForMap( void ) { - // create a thread to run frame commands on - frameCommandThread = new idThread(); - frameCommandThread->ManualDelete(); - frameCommandThread->SetThreadName( "frameCommands" ); - - // run the main game script function (not the level specific main) - const function_t *func = program.FindFunction( SCRIPT_DEFAULTFUNC ); - if ( func != NULL ) { - idThread *thread = new idThread( func ); - if ( thread->Start() ) { - // thread has finished executing, so delete it - delete thread; - } - } -} - -/* -=========== -idGameLocal::SpawnPlayer -============ -*/ -void idGameLocal::SpawnPlayer( int clientNum ) -{ - // they can connect - Printf( "SpawnPlayer: %i\n", clientNum ); - - idStr playerClass = isMultiplayer ? "player_tdm_thief_mp" : cv_player_spawnclass.GetString(); - - // greebo: Allow worldspawn to specify a different player classname - if (!isMultiplayer && world != NULL && world->spawnArgs.FindKey("player_classname") != NULL) - { - playerClass = world->spawnArgs.GetString("player_classname", cv_player_spawnclass.GetString()); - } - - idDict args; - args.SetInt( "spawn_entnum", clientNum ); - args.Set( "name", va( "player%d", clientNum + 1 ) ); - args.Set( "classname", playerClass ); - - idEntity *ent; - if ( !SpawnEntityDef( args, &ent ) || !entities[ clientNum ] ) - { - Error( "Failed to spawn player as '%s'", args.GetString( "classname" ) ); - } - - // make sure it's a compatible class - if ( !ent->IsType( idPlayer::Type ) ) { - Error( "'%s' spawned the player as a '%s'. Player spawnclass must be a subclass of idPlayer.", args.GetString( "classname" ), ent->GetClassname() ); - } - - if ( clientNum >= numClients ) { - numClients = clientNum + 1; - } - - mpGame.SpawnPlayer( clientNum ); -} - -/* -================ -idGameLocal::GetClientByNum -================ -*/ -idPlayer *idGameLocal::GetClientByNum( int current ) const { - if ( current < 0 || current >= numClients ) { - current = 0; - } - if ( entities[current] ) { - return static_cast( entities[ current ] ); - } - return NULL; -} - -/* -================ -idGameLocal::GetClientByName -================ -*/ -idPlayer *idGameLocal::GetClientByName( const char *name ) const { - int i; - idEntity *ent; - for ( i = 0 ; i < numClients ; i++ ) { - ent = entities[ i ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - if ( idStr::IcmpNoColor( name, userInfo[ i ].GetString( "ui_name" ) ) == 0 ) { - return static_cast( ent ); - } - } - } - return NULL; -} - -/* -================ -idGameLocal::GetClientByCmdArgs -================ -*/ -idPlayer *idGameLocal::GetClientByCmdArgs( const idCmdArgs &args ) const { - idPlayer *player; - idStr client = args.Argv( 1 ); - if ( !client.Length() ) { - return NULL; - } - // we don't allow numeric ui_name so this can't go wrong - if ( client.IsNumeric() ) { - player = GetClientByNum( atoi( client.c_str() ) ); - } else { - player = GetClientByName( client.c_str() ); - } - if ( !player ) { - common->Printf( "Player '%s' not found\n", client.c_str() ); - } - return player; -} - -/* -================ -idGameLocal::GetNextClientNum -================ -*/ -int idGameLocal::GetNextClientNum( int _current ) const { - int i, current; - - current = 0; - for ( i = 0; i < numClients; i++) { - current = ( _current + i + 1 ) % numClients; - if ( entities[ current ] && entities[ current ]->IsType( idPlayer::Type ) ) { - return current; - } - } - - return current; -} - -/* -================ -idGameLocal::GetLocalPlayer - -Nothing in the game tic should EVER make a decision based on what the -local client number is, it shouldn't even be aware that there is a -draw phase even happening. This just returns client 0, which will -be correct for single player. -================ -*/ -idPlayer *idGameLocal::GetLocalPlayer() const { - if ( localClientNum < 0 ) { - return NULL; - } - - if ( !entities[ localClientNum ] || !entities[ localClientNum ]->IsType( idPlayer::Type ) ) { - // not fully in game yet - return NULL; - } - return static_cast( entities[ localClientNum ] ); -} - -/* -================ -idGameLocal::SetupClientPVS -================ -*/ -pvsHandle_t idGameLocal::GetClientPVS( idPlayer *player, pvsType_t type ) { - if ( player->GetPrivateCameraView() ) { - return pvs.SetupCurrentPVS( player->GetPrivateCameraView()->GetPVSAreas(), player->GetPrivateCameraView()->GetNumPVSAreas() ); - } else if ( camera ) { - return pvs.SetupCurrentPVS( camera->GetPVSAreas(), camera->GetNumPVSAreas() ); - } else { - return pvs.SetupCurrentPVS( player->GetPVSAreas(), player->GetNumPVSAreas() ); - } -} - -/* -================ -idGameLocal::SetupPlayerPVS -================ -*/ -void idGameLocal::SetupPlayerPVS( void ) { - int i; - idEntity * ent; - idPlayer * player; - pvsHandle_t otherPVS, newPVS; - - playerPVS.i = -1; - for ( i = 0; i < numClients; i++ ) { - ent = entities[i]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - - player = static_cast(ent); - - if ( playerPVS.i == -1 ) { - playerPVS = GetClientPVS( player, PVS_NORMAL ); - } else { - otherPVS = GetClientPVS( player, PVS_NORMAL ); - newPVS = pvs.MergeCurrentPVS( playerPVS, otherPVS ); - pvs.FreeCurrentPVS( playerPVS ); - pvs.FreeCurrentPVS( otherPVS ); - playerPVS = newPVS; - } - - if ( playerConnectedAreas.i == -1 ) { - playerConnectedAreas = GetClientPVS( player, PVS_CONNECTED_AREAS ); - } else { - otherPVS = GetClientPVS( player, PVS_CONNECTED_AREAS ); - newPVS = pvs.MergeCurrentPVS( playerConnectedAreas, otherPVS ); - pvs.FreeCurrentPVS( playerConnectedAreas ); - pvs.FreeCurrentPVS( otherPVS ); - playerConnectedAreas = newPVS; - } - - - // if portalSky is preset, then merge into pvs so we get rotating brushes, etc - - if ( portalSkyEnt.GetEntity() ) { - idEntity *skyEnt = portalSkyEnt.GetEntity(); - - otherPVS = pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); - newPVS = pvs.MergeCurrentPVS( playerPVS, otherPVS ); - pvs.FreeCurrentPVS( playerPVS ); - pvs.FreeCurrentPVS( otherPVS ); - playerPVS = newPVS; - - otherPVS = pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); - newPVS = pvs.MergeCurrentPVS( playerConnectedAreas, otherPVS ); - pvs.FreeCurrentPVS( playerConnectedAreas ); - pvs.FreeCurrentPVS( otherPVS ); - playerConnectedAreas = newPVS; - } - } -} - -/* -================ -idGameLocal::FreePlayerPVS -================ -*/ -void idGameLocal::FreePlayerPVS( void ) { - if ( playerPVS.i != -1 ) { - pvs.FreeCurrentPVS( playerPVS ); - playerPVS.i = -1; - } - if ( playerConnectedAreas.i != -1 ) { - pvs.FreeCurrentPVS( playerConnectedAreas ); - playerConnectedAreas.i = -1; - } -} - -/* -================ -idGameLocal::InPlayerPVS - - should only be called during entity thinking and event handling -================ -*/ -bool idGameLocal::InPlayerPVS( idEntity *ent ) const { - if ( playerPVS.i == -1 ) { - return false; - } - return pvs.InCurrentPVS( playerPVS, ent->GetPVSAreas(), ent->GetNumPVSAreas() ); -} - -/* -================ -idGameLocal::InPlayerConnectedArea - - should only be called during entity thinking and event handling -================ -*/ -bool idGameLocal::InPlayerConnectedArea( idEntity *ent ) const { - if ( playerConnectedAreas.i == -1 ) { - return false; - } - return pvs.InCurrentPVS( playerConnectedAreas, ent->GetPVSAreas(), ent->GetNumPVSAreas() ); -} - -/* -================ -idGameLocal::UpdateGravity -================ -*/ -void idGameLocal::UpdateGravity( void ) { - idEntity *ent; - - if ( g_gravity.IsModified() ) { - if ( g_gravity.GetFloat() == 0.0f ) { - g_gravity.SetFloat( 1.0f ); - } - gravity.Set( 0, 0, -g_gravity.GetFloat() ); - - // update all physics objects - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( idAFEntity_Generic::Type ) ) { - idPhysics *phys = ent->GetPhysics(); - if ( phys ) { - phys->SetGravity( gravity ); - } - } - } - g_gravity.ClearModified(); - } -} - -/* -================ -idGameLocal::GetGravity -================ -*/ -const idVec3 &idGameLocal::GetGravity( void ) const { - return gravity; -} - -/* -================ -idGameLocal::SortActiveEntityList - - Sorts the active entity list such that pushing entities come first, - actors come next and physics team slaves appear after their master. -================ -*/ -void idGameLocal::SortActiveEntityList( void ) { - idEntity *ent, *next_ent, *master, *part; - - // if the active entity list needs to be reordered to place physics team masters at the front - if ( sortTeamMasters ) { - for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { - next_ent = ent->activeNode.Next(); - master = ent->GetTeamMaster(); - if ( master && master == ent ) { - ent->activeNode.Remove(); - ent->activeNode.AddToFront( activeEntities ); - } - } - } - - // if the active entity list needs to be reordered to place pushers at the front - if ( sortPushers ) { - - for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { - next_ent = ent->activeNode.Next(); - master = ent->GetTeamMaster(); - if ( !master || master == ent ) { - // check if there is an actor on the team - for ( part = ent; part != NULL; part = part->GetNextTeamEntity() ) { - if ( part->GetPhysics()->IsType( idPhysics_Actor::Type ) ) { - break; - } - } - // if there is an actor on the team - if ( part ) { - ent->activeNode.Remove(); - ent->activeNode.AddToFront( activeEntities ); - } - } - } - - for ( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { - next_ent = ent->activeNode.Next(); - master = ent->GetTeamMaster(); - if ( !master || master == ent ) { - // check if there is an entity on the team using parametric physics - for ( part = ent; part != NULL; part = part->GetNextTeamEntity() ) { - if ( part->GetPhysics()->IsType( idPhysics_Parametric::Type ) ) { - break; - } - } - // if there is an entity on the team using parametric physics - if ( part ) { - ent->activeNode.Remove(); - ent->activeNode.AddToFront( activeEntities ); - } - } - } - } - - sortTeamMasters = false; - sortPushers = false; -} - -/* -================ -idGameLocal::RunFrame -================ -*/ -gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) { - idEntity * ent; - int num(-1); - float ms; - idTimer timer_think, timer_events, timer_singlethink; - gameReturn_t ret; - idPlayer *player; - const renderView_t *view; - int curframe = framenum; - - g_Global.m_Frame = curframe; - DM_LOG(LC_FRAME, LT_INFO)LOGSTRING("Frame start\r"); - -#ifdef _DEBUG - if ( isMultiplayer ) { - assert( !isClient ); - } -#endif - - player = GetLocalPlayer(); - - // Handle any mission downloads in progress - m_DownloadManager->ProcessDownloads(); - - if (framenum == 0 && player != NULL && !player->IsReady()) - { - // greebo: This is the first game frame, handle the "click to start GUI" - if (m_GamePlayTimer.IsEnabled()) - { - m_GamePlayTimer.Stop(); - } - - // set the user commands for this frame - memcpy(usercmds, clientCmds, numClients * sizeof(usercmds[0])); - - if (player->WaitUntilReady()) - { - // Player got ready this frame, start timer - m_GamePlayTimer.Start(); - } - } - else - { - // Update the gameplay timer - m_GamePlayTimer.Update(); - - if ( !isMultiplayer && g_stopTime.GetBool() ) { - // clear any debug lines from a previous frame - gameRenderWorld->DebugClearLines( time + 1 ); - - // set the user commands for this frame - memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); - - if ( player ) { - player->Think(); - } - } - else do - { - // update the game time - framenum++; - previousTime = time; - time += (int)(msec * g_timeModifier.GetFloat()); - realClientTime = time; - -#ifdef GAME_DLL - // allow changing SIMD usage on the fly - if ( com_forceGenericSIMD.IsModified() ) { - idSIMD::InitProcessor( "game", com_forceGenericSIMD.GetBool() ); - } -#endif - - // make sure the random number counter is used each frame so random events - // are influenced by the player's actions - random.RandomInt(); - - if ( player ) { - // update the renderview so that any gui videos play from the right frame - view = player->GetRenderView(); - if ( view ) { - gameRenderWorld->SetRenderView( view ); - } - } - - // clear any debug lines from a previous frame - gameRenderWorld->DebugClearLines( time ); - - // clear any debug polygons from a previous frame - gameRenderWorld->DebugClearPolygons( time ); - - // set the user commands for this frame - memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); - - // free old smoke particles - smokeParticles->FreeSmokes(); - - // process events on the server - ServerProcessEntityNetworkEventQueue(); - - // update our gravity vector if needed. - UpdateGravity(); - - // create a merged pvs for all players - SetupPlayerPVS(); - - idTimer lasTimer; - lasTimer.Clear(); - lasTimer.Start(); - // The Dark Mod - // 10/9/2005: SophisticatedZombie - // Update the Light Awareness System - LAS.updateLASState(); - lasTimer.Stop(); - DM_LOG(LC_LIGHT, LT_INFO)LOGSTRING("Time to update LAS: %lf\r", lasTimer.Milliseconds()); - - unsigned long ticks = static_cast(sys->GetClockTicks()); - - // Tick the timers. Should be done before stim/response, just to be safe. :) - ProcessTimer(ticks); - - // TDM: Work through the active stims/responses - ProcessStimResponse(ticks); - - // TDM: Update objective system - m_MissionData->UpdateObjectives(); - - // sort the active entity list - SortActiveEntityList(); - - timer_think.Clear(); - timer_think.Start(); - - // let entities think - if ( g_timeentities.GetFloat() ) { - num = 0; - for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - if ( g_cinematic.GetBool() && inCinematic && !ent->cinematic ) { - ent->GetPhysics()->UpdateTime( time ); - if (ent->IsType(idAI::Type)) // grayman #2654 - update m_lastThinkTime to keep non-cinematic AI from dying at CrashLand() - { - static_cast(ent)->m_lastThinkTime = time; - } - continue; - } - timer_singlethink.Clear(); - timer_singlethink.Start(); - ent->Think(); - timer_singlethink.Stop(); - ms = timer_singlethink.Milliseconds(); - if ( ms >= g_timeentities.GetFloat() ) { - Printf( "%d: entity '%s': %.1f ms\n", time, ent->name.c_str(), ms ); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("%d: entity '%s': %.3f ms\r", time, ent->name.c_str(), ms ); - } - num++; - } - } else { - if ( inCinematic ) { - num = 0; - for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - if ( g_cinematic.GetBool() && !ent->cinematic ) { - ent->GetPhysics()->UpdateTime( time ); - if (ent->IsType(idAI::Type)) // grayman #2654 - update m_lastThinkTime to keep non-cinematic AI from dying at CrashLand() - { - static_cast(ent)->m_lastThinkTime = time; - } - continue; - } - ent->Think(); - num++; - } - } else { - num = 0; - for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - ent->Think(); - num++; - } - } - } - - // remove any entities that have stopped thinking - if ( numEntitiesToDeactivate ) { - idEntity *next_ent; - int c = 0; - for( ent = activeEntities.Next(); ent != NULL; ent = next_ent ) { - next_ent = ent->activeNode.Next(); - if ( !ent->thinkFlags ) { - ent->activeNode.Remove(); - c++; - } - } - //assert( numEntitiesToDeactivate == c ); - numEntitiesToDeactivate = 0; - } - - timer_think.Stop(); - - //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Thinking timer: %lfms\r", timer_think.Milliseconds()); - - timer_events.Clear(); - timer_events.Start(); - - // service any pending events - idEvent::ServiceEvents(); - - timer_events.Stop(); - - // Process the active AI conversations - m_ConversationSystem->ProcessConversations(); - - // free the player pvs - FreePlayerPVS(); - - // do multiplayer related stuff - if ( isMultiplayer ) { - mpGame.Run(); - } - - if ( cv_music_volume.IsModified() ) { //SnoopJeDi, fade that sound! - float music_vol = cv_music_volume.GetFloat(); - for ( int i = 0; i < musicSpeakers.Num(); i++ ) { - idSound* ent = static_cast(entities[ musicSpeakers[ i ] ]); - // Printf( " Fading speaker %s (index %i) to %f\n", ent->name.c_str(), i, music_vol); - if (ent) - ent->Event_FadeSound( 0, music_vol, 0.5 ); - } - cv_music_volume.ClearModified(); - } - - // display how long it took to calculate the current game frame - if ( g_frametime.GetBool() ) { - Printf( "game %d: all:%.1f th:%.1f ev:%.1f %d ents \n", - time, timer_think.Milliseconds() + timer_events.Milliseconds(), - timer_think.Milliseconds(), timer_events.Milliseconds(), num ); - } - - // build the return value - ret.consistencyHash = 0; - ret.sessionCommand[0] = 0; - - if ( !isMultiplayer && player ) { - ret.health = player->health; - ret.heartRate = player->heartRate; - ret.stamina = idMath::FtoiFast( player->stamina ); - // combat is a 0-100 value based on lastHitTime and lastDmgTime - // each make up 50% of the time spread over 10 seconds - ret.combat = 0; - if ( player->lastDmgTime > 0 && time < player->lastDmgTime + 10000 ) { - ret.combat += int(50.0f * (float) ( time - player->lastDmgTime ) / 10000); - } - if ( player->lastHitTime > 0 && time < player->lastHitTime + 10000 ) { - ret.combat += int(50.0f * (float) ( time - player->lastHitTime ) / 10000); - } - } - - // Check for final save trigger - the player PVS is freed at this point, so we can go ahead and save the game - if (m_TriggerFinalSave) - { - m_TriggerFinalSave = false; - - idStr savegameName = va("Mission %d Final Save", m_MissionManager->GetCurrentMissionIndex() + 1); - cmdSystem->BufferCommandText(CMD_EXEC_NOW, va("savegame '%s'", savegameName.c_str())); - } - - // see if a target_sessionCommand has forced a changelevel - if ( sessionCommand.Length() ) { - strncpy( ret.sessionCommand, sessionCommand, sizeof( ret.sessionCommand ) ); - break; - } - - // make sure we don't loop forever when skipping a cinematic - if ( skipCinematic && ( time > cinematicMaxSkipTime ) ) { - Warning( "Exceeded maximum cinematic skip length. Cinematic may be looping infinitely." ); - skipCinematic = false; - break; - } - - if (m_DoLightgem) - { - player->ProcessLightgem(cv_lg_hud.GetInteger() == 0); - m_DoLightgem = false; - } - - } while( ( inCinematic || ( time < cinematicStopTime ) ) && skipCinematic ); - } - - ret.syncNextGameFrame = skipCinematic; - if ( skipCinematic ) { - soundSystem->SetMute( false ); - skipCinematic = false; - } - - // show any debug info for this frame - RunDebugInfo(); - D_DrawDebugLines(); - - DM_LOG(LC_FRAME, LT_INFO)LOGSTRING("Frame end %d - %d: all:%.1f th:%.1f ev:%.1f %d ents \r", - time, timer_think.Milliseconds() + timer_events.Milliseconds(), - timer_think.Milliseconds(), timer_events.Milliseconds(), num ); - - g_Global.m_Frame = 0; - - return ret; -} - - -/* -====================================================================== - - Game view drawing - -====================================================================== -*/ - -/* -==================== -idGameLocal::CalcFov - -Calculates the horizontal and vertical field of view based on a horizontal field of view and custom aspect ratio -==================== -*/ -void idGameLocal::CalcFov( float base_fov, float &fov_x, float &fov_y ) const { - float x; - float y; - float ratio_x; - float ratio_y; - float ratio_fov; - - if ( !sys->FPU_StackIsEmpty() ) { - Printf( sys->FPU_GetState() ); - Error( "idGameLocal::CalcFov: FPU stack not empty" ); - } - - // first, calculate the vertical fov based on a 640x480 view - x = 640.0f / tan( base_fov / 360.0f * idMath::PI ); - y = atan2( 480.0f, x ); - fov_y = y * 360.0f / idMath::PI; - - // FIXME: somehow, this is happening occasionally - assert( fov_y > 0 ); - if ( fov_y <= 0 ) { - Printf( sys->FPU_GetState() ); - Error( "idGameLocal::CalcFov: bad result" ); - } - - // if r_fovRatio != 0, use it directly: - ratio_fov = cv_r_fovRatio.GetFloat(); - - if (ratio_fov > 0.01) - { - ratio_x = ratio_fov; - ratio_y = 1.0f; - } - else - { - // old code, use r_aspectRatio - switch( r_aspectRatio.GetInteger() ) { - default : - case 0 : - // 4:3 - fov_x = base_fov; - return; - break; - case 1 : - // 16:9 - case 4 : - // TV 16:9 - ratio_x = 16.0f; - ratio_y = 9.0f; - break; - case 2 : - // 16:10 - ratio_x = 16.0f; - ratio_y = 10.0f; - break; - case 3 : - // 5:4 - ratio_x = 5.0f; - ratio_y = 4.0f; - break; - } - } - -// Printf( "Using FOV ratio %0.3f:%0.0f\n", ratio_x, ratio_y ); - - y = ratio_y / tan( fov_y / 360.0f * idMath::PI ); - fov_x = atan2( ratio_x, y ) * 360.0f / idMath::PI; - - if ( fov_x < base_fov ) { - fov_x = base_fov; - x = ratio_x / tan( fov_x / 360.0f * idMath::PI ); - fov_y = atan2( ratio_y, x ) * 360.0f / idMath::PI; - } - - // FIXME: somehow, this is happening occasionally - assert( ( fov_x > 0 ) && ( fov_y > 0 ) ); - if ( ( fov_y <= 0 ) || ( fov_x <= 0 ) ) { - Printf( sys->FPU_GetState() ); - Error( "idGameLocal::CalcFov: bad result" ); - } -} - -/* -================ -idGameLocal::Draw - -makes rendering and sound system calls -================ -*/ -bool idGameLocal::Draw( int clientNum ) -{ - if ( isMultiplayer ) { - return mpGame.Draw( clientNum ); - } - - idPlayer *player = static_cast(entities[ clientNum ]); - - if ( !player ) { - return false; - } - - // render the scene - player->playerView.RenderPlayerView(player->hud); - - // Make the rendershot appear on the hud - if (cv_lg_hud.GetInteger() != 0) - { - player->ProcessLightgem(true); - } - - m_DoLightgem = true; - return true; -} - -/* -================ -idGameLocal::HandleESC -================ -*/ -escReply_t idGameLocal::HandleESC( idUserInterface **gui ) { - - if ( isMultiplayer ) { - *gui = StartMenu(); - // we may set the gui back to NULL to hide it - return ESC_GUI; - } - - // If we're in the process of ending the mission, ignore all ESC keys. - if (GameState() == GAMESTATE_COMPLETED) { - return ESC_IGNORE; - } - - // greebo: Hitting the ESC key means that the main menu is about to be entered => stop the timer - m_GamePlayTimer.Stop(); - - idPlayer *player = GetLocalPlayer(); - if ( player ) { - if ( player->HandleESC() ) { - m_GamePlayTimer.SetEnabled(true); - return ESC_IGNORE; - } else { - return ESC_MAIN; - } - } - return ESC_MAIN; -} - -/* -================ -idGameLocal::StartMenu -================ -*/ -idUserInterface* idGameLocal::StartMenu( void ) { - if ( !isMultiplayer ) { - return NULL; - } - return mpGame.StartMenu(); -} - -/* -================ -idGameLocal::HandleGuiCommands -================ -*/ -const char* idGameLocal::HandleGuiCommands( const char *menuCommand ) { - if ( !isMultiplayer ) { - return NULL; - } - return mpGame.HandleGuiCommands( menuCommand ); -} - -int idGameLocal::LoadVideosFromString(const char* videosStr, const char* lengthStr, idList& targetList) -{ - targetList.Clear(); - - std::string videos = videosStr; - std::string lengths = lengthStr; - - // Remove leading and trailing semicolons - boost::algorithm::trim_if(videos, boost::algorithm::is_any_of(";")); - boost::algorithm::trim_if(lengths, boost::algorithm::is_any_of(";")); - - // Split strings into parts - std::vector vidParts; - std::vector lengthParts; - - boost::algorithm::split(vidParts, videos, boost::algorithm::is_any_of(";")); - boost::algorithm::split(lengthParts, lengths, boost::algorithm::is_any_of(";")); - - if (vidParts.size() != lengthParts.size()) - { - gameLocal.Warning("The video string array '%s' does not have the same number of elements as the length array '%s'!", videosStr, lengthStr); - return 0; - } - - if (vidParts.size() == 0) - { - return 0; - } - - int totalLength = 0; - - for (std::size_t i = 0; i < vidParts.size(); ++i) - { - BriefingVideoPart& part = targetList.Alloc(); - - part.material = vidParts[i].c_str(); - part.lengthMsec = atoi(lengthParts[i].c_str()); - - if (part.lengthMsec <= 0) - { - gameLocal.Warning("The video length %s is invalid or not numeric, must be an integer > 0", lengthParts[i].c_str()); - part.lengthMsec = 0; - } - - totalLength += part.lengthMsec; - } - - return totalLength; -} - -void idGameLocal::UpdateScreenResolutionFromGUI(idUserInterface* gui) -{ - if (cvarSystem->GetCVarInteger("r_aspectRatio") > 0) - { - // Wide-screen resolution selected in the GUI, set the mode to "custom" - cvarSystem->SetCVarInteger("r_mode", -1); - - // Set the custom height and width - int mode = cv_tdm_widescreenmode.GetInteger(); - - int width = 1024; - int height = 600; - - switch (mode) - { - case 0: - width = 1024; - height = 600; - break; - case 1: - width = 1280; - height = 800; - break; - case 2: - width = 1440; - height = 900; - break; - case 3: - width = 1680; - height = 1050; - break; - case 4: - width = 1920; - height = 1200; - break; - case 5: - width = 1366; - height = 768; - break; - case 6: - width = 1280; - height = 720; - break; - case 7: - width = 1920; - height = 1080; - break; - case 8: - width = 2560; - height = 1440; - break; - case 9: - width = 2560; - height = 1600; - break; - case 10: - width = 1280; - height = 1024; - break; - case 11: - width = 1800; - height = 1440; - break; - case 12: - width = 2560; - height = 2048; - break; - case 13: - width = 1360; - height = 768; - break; - case 14: - width = 1600; - height = 900; - break; - case 15: - width = 3280; - height = 2048; - break; - case 16: - width = 3360; - height = 2100; - break; - case 17: - width = 3840; - height = 2160; - break; - case 18: - width = 3840; - height = 2400; - break; - default: - break; - }; - - Printf("Widesreenmode %i, setting r_customWidth=%i, r_customHeight=%i\n", mode, width, height); - cvarSystem->SetCVarInteger("r_customWidth", width); - cvarSystem->SetCVarInteger("r_customHeight", height); - } - else - { - // Not widescreen, set r_mode to something reasonable (1024x768) - cvarSystem->SetCVarInteger("r_mode", 5); - } -} - -void idGameLocal::HandleGuiMessages(idUserInterface* ui) -{ - if (m_GuiMessages.Num() == 0) return; - - const GuiMessage& msg = m_GuiMessages[0]; - - ui->SetStateBool("MsgBoxVisible", true); - - ui->SetStateString("MsgBoxTitle", msg.title); - ui->SetStateString("MsgBoxText", msg.message); - - switch (msg.type) - { - case GuiMessage::MSG_OK: - ui->SetStateBool("MsgBoxLeftButtonVisible", false); - ui->SetStateBool("MsgBoxRightButtonVisible", false); - ui->SetStateBool("MsgBoxMiddleButtonVisible", true); - ui->SetStateString("MsgBoxMiddleButtonText", m_I18N->Translate("#str_04339")); // OK - break; - case GuiMessage::MSG_OK_CANCEL: - ui->SetStateBool("MsgBoxLeftButtonVisible", true); - ui->SetStateBool("MsgBoxRightButtonVisible", true); - ui->SetStateBool("MsgBoxMiddleButtonVisible", false); - - ui->SetStateString("MsgBoxLeftButtonText", m_I18N->Translate("#str_04339")); // OK - ui->SetStateString("MsgBoxRightButtonText", m_I18N->Translate("#str_07203")); // Cancel - break; - case GuiMessage::MSG_YES_NO: - ui->SetStateBool("MsgBoxLeftButtonVisible", true); - ui->SetStateBool("MsgBoxRightButtonVisible", true); - ui->SetStateBool("MsgBoxMiddleButtonVisible", false); - - ui->SetStateString("MsgBoxLeftButtonText", m_I18N->Translate("#str_02501")); // Yes - ui->SetStateString("MsgBoxRightButtonText", m_I18N->Translate("#str_02502")); // No - break; - }; - - ui->SetStateString("MsgBoxRightButtonCmd", msg.negativeCmd); - ui->SetStateString("MsgBoxLeftButtonCmd", msg.positiveCmd); - ui->SetStateString("MsgBoxMiddleButtonCmd", msg.okCmd); - - m_GuiMessages.RemoveIndex(0); -} - -/* -================ -idGameLocal::UpdateGUIScaling -================ -*/ -void idGameLocal::UpdateGUIScaling( idUserInterface *gui ) -{ - float wobble = 1.0f; - // this could be turned into a warble-wobble effect f.i. for player poisoned etc. - //float wobble = random.RandomFloat() * 0.02 + 0.98; - - float x_mul = cvarSystem->GetCVarFloat("gui_Width") * wobble; - if (x_mul < 0.1f) { x_mul = 0.1f; } - if (x_mul > 2.0f) { x_mul = 2.0f; } - float y_mul = cvarSystem->GetCVarFloat("gui_Height") * wobble; - if (y_mul < 0.1f) { y_mul = 0.1f; } - if (y_mul > 2.0f) { y_mul = 2.0f; } - float x_shift = cvarSystem->GetCVarFloat("gui_CenterX") * 640 * wobble; - float y_shift = cvarSystem->GetCVarFloat("gui_CenterY") * 480 * wobble; -// Printf("UpdateGUIScaling: width %0.2f height %0.2f centerX %0.02ff centerY %0.02f\n (%p)", x_mul, y_mul, x_shift, y_shift, gui); - gui->SetStateFloat("LEFT", x_shift - x_mul * 320); - gui->SetStateFloat("CENTERX", x_shift); - gui->SetStateFloat("TOP", y_shift - y_mul * 240); - gui->SetStateFloat("CENTERY", y_shift); - gui->SetStateFloat("WIDTH", x_mul); - gui->SetStateFloat("HEIGHT", y_mul); - // We have only one scaling factor to scale text, so use the average of X and Y - // This will have odd effects if W and H differ greatly, but is better than to not scale the text - gui->SetStateFloat("SCALE", (y_mul + x_mul) / 2); -} - -/* -================ -idGameLocal::initChoice - -Init a GUI or CVAR variable (including GUI text) from a list of choices and values. -================ -*/ -bool idGameLocal::InitGUIChoice( idUserInterface *gui, const char *varName, const char *inChoices, const char *inValues, const bool step) -{ - idStr cvarName = varName; - std::string choices = gameLocal.m_I18N->Translate( inChoices ); - std::string values = inValues; - - // figure out the current setting - idCVar *cvar = NULL; - - // special case: use this gui variable - if (cvarName.Left(5) != "gui::") - { - cvar = cvarSystem->Find( cvarName.c_str() ); - if (!cvar) - { - // ignore, the GUI command buffer was probably just overrun - Warning("initChoice: Cannot find CVAR '%s'.", cvarName.c_str() ); - return false; - } - } - // split the choices into a listt - std::vector choiceParts; - std::vector valuesParts; - boost::algorithm::split(choiceParts, choices, boost::algorithm::is_any_of(";")); - boost::algorithm::split(valuesParts, values, boost::algorithm::is_any_of(";")); - - if (choiceParts.size() != valuesParts.size()) - { - gameLocal.Warning("The choices string array '%s' does not have the same number of elements as the values array '%s' for %s!", - choices.c_str(), values.c_str(), cvarName.c_str() ); //gameLocal.m_I18N->Translate( m_GUICommandStack[2] ), m_GUICommandStack[3].c_str(), cvarName.c_str() ); - return false; - } - if (choiceParts.size() <= 0) - { - gameLocal.Warning("The choices and values string arrays are empty for %s.", cvarName.c_str()); - return false; - } - - // read out the current setting (this also works with boolean CVARs, as these are simply "0", "1") - idStr curValue; - if (cvar) - { - curValue = cvar->GetString(); - } - else - { - curValue = gui->GetStateString( cvarName.Right( cvarName.Length() -5 ).c_str(), "0" ); - } - - // Figure out the index of the selected choice/value pair by looking at all the values - int iSelected = -1; - for (unsigned int i = 0; i < valuesParts.size(); i++) - { - if (curValue == idStr( valuesParts[i].c_str() )) - { - // found it - iSelected = i; - i = valuesParts.size(); - break; - } - } - - // Printf("Current value: %s (index: %i)\n", curValue.c_str(), iSelected); - if (iSelected < 0) - { - gameLocal.Warning("The current value for %s (%s) is not in the list of valid choices '%s'.", cvarName.c_str(), curValue.c_str(), values.c_str()); - return false; - } - - // should we advance the setting? - if ( step ) - { - iSelected ++; - if ( (unsigned int)iSelected >= valuesParts.size()) - { - // wrap around - iSelected = 0; - } - // set the new value - Printf("Setting %s to %s (index: %i)\n", cvarName.c_str(), valuesParts[ iSelected ].c_str(), iSelected); - if (cvar) - { - cvar->SetString( valuesParts[ iSelected ].c_str() ); - } - } - - // Printf( "Setting %s to %s\n", GUIVar.c_str(), choiceParts[iSelected].c_str() ); - if (!cvar) - { - cvarName = cvarName.Right( cvarName.Length() -5 ); // remove "gui::" prefix - } - // store the value in "gui::cvarname", so the GUI can access it (important f.i. for the bloom slider visibility) - // Printf( "Setting %s to %s\n", cvarName.c_str(), valuesParts[iSelected].c_str() ); - gui->SetStateString( cvarName.c_str(), valuesParts[iSelected].c_str() ); - // and set it as text label - idStr GUIVar = cvarName + "_text"; // f.i.: tdm_menu_music_text - gui->SetStateString( GUIVar.c_str(), choiceParts[iSelected].c_str() ); - - return true; -} - -/* -================ -idGameLocal::HandleMainMenuCommands -================ -*/ -void idGameLocal::HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) -{ - /* Tels: This routine here is called for every "command" in the menu GUI. Unfortunately, - the interpretation of what is a command works a bit strange (as almost everything - else does in idTech4 :) - - In the following examples, there is usually another call to this routine with ";" - as the "menuCommand" param. But sometimes it does not appear, depending on whoknows. - - The following will cause this routine called twice (!), once with "mainmenu_heartbeat" - and once with ";" as command (if you add ";" before the last double quote, it will - still be called only twice): - - set "cmd" "mainmenu_heartbeat"; - - This will call it twice (or three times counting ";") with "mycommand" "myarg" and ";": - - set "cmd" "mycommand 'test'"; - - This calls it only once (!) (two times counting ";"), with "play": - - Set "play mymusic"; - - This calls it twice (three times counting ";"), with "notime" and then "1": - - Set "noTime" "1"; - - Note that the command buffer has only a certain, unknown length, and if too many - commands are issued in the same timeframe (onTime X..), then the buffer will overflow, - and certain commands might get cut-off. Usually this means that you see a ";" instead - of an expected argument, or that commands run together like "initChoicelog". When this - happens, the GUI must be adjusted to issue less commands (or issue them later). - To work around this issue, we call ExecuteCommandBuffer( void ) whenever we see an - initChoice command, in the hopes that the buffer won't overflow until the next one. - - The old code simply watched for certain words, and then issued the command. It was not - able to distinguish between commands and arguments. - - This routine now watches for the first command, ignoring any stray ";". If it sees - a command, it deduces the number of following arguments, and then collects them until - it has all of them, warning if there is a ";" coming unexpectedly. - - Once all arguments are collected, the command is finally handled, or silently ignored. - */ - if (!menuCommand || menuCommand[0] == 0x00) - { - // silently ignore - Warning("Seen NULL MainMenu cmd."); - return; - } - - int numArgs = m_GUICommandStack.Num(); - - if (numArgs == 0) - { - if ( menuCommand[0] == ';' && menuCommand[1] == 0x0 ) - { - // ignore stray any ";" - return; - } - - // have not seen anything? - idStr cmd = menuCommand; - // commands can appear in any case (like "notime", "noTime" etc) - cmd.ToLower(); - m_GUICommandStack.Append(cmd); - - // set the number of wanted args, default is none - m_GUICommandArgs = 0; - - // "log" and "notime" take one argument - if ( cmd == "log" || cmd == "notime") { m_GUICommandArgs = 1; } - // these two take 3 arguments each - if ( cmd == "initchoice" || cmd == "stepchoice") { m_GUICommandArgs = 3; } - // this takes one argument - if ( cmd == "setlang") { m_GUICommandArgs = 1; } - - if ( cmd != "log" && cmd != "mainmenu_heartbeat") - { -// Printf("Seen command '%s' ('%s'), takes %i args.\n", menuCommand, cmd.c_str(), m_GUICommandArgs ); - } - } - else - { - // append the current argument to the stack (but not if it is ";") - if ( menuCommand[0] != ';' || menuCommand[1] != 0x0 ) - { - m_GUICommandStack.Alloc() = menuCommand; -// Printf(" Seen argument '%s' for '%s'\n", menuCommand, m_GUICommandStack[0].c_str() ); - } - else - { - // seen a ";" even tho we have not yet as many arguments as we wanted? - if (numArgs - 1 < m_GUICommandArgs) - { - //Warning("MainMenu command %s takes %i arguments, but has only %i (last arg %s).\n", m_GUICommandStack[0].c_str(), m_GUICommandArgs, numArgs - 1, menuCommand); - Warning("Seen stray ';' - command %s takes %i arguments, but has only %i (last arg %s).\n", m_GUICommandStack[0].c_str(), m_GUICommandArgs, numArgs - 1, menuCommand); - // Ignore any stray ";" as they can be injected anywhere :( - numArgs = m_GUICommandArgs; - return; - } - } - } - - // Printf(" have %i vs wanted %i\n", numArgs, m_GUICommandArgs); - // do we have already as much arguments as we want? - if (numArgs < m_GUICommandArgs) - { - // no, wait for the next argument - return; - } - - // the command - const idStr& cmd = m_GUICommandStack[0]; - - // seen the command and its arguments, now handle it -/* if (cmd != "mainmenu_heartbeat" && cmd != "log") - { - // debug output, but ignore the frequent ones - Printf("MainMenu cmd: %s (%i args)\n", cmd.c_str(), numArgs); - } -*/ - - // Watch out for objectives GUI-related commands - // TODO: Handle here commands with arguments, too. - m_MissionData->HandleMainMenuCommands(cmd, gui); - - if (cmd == "mainmenu_heartbeat") - { - // greebo: Stop the timer, this is already done in HandleESC, but just to make sure... - m_GamePlayTimer.Stop(); - - if (GetMissionResult() == MISSION_COMPLETE) - { - // Check if we should show the success screen (also check the member variable - // to catch cases where the player reloaded the map via the console) - if (!gui->GetStateBool("PostMissionScreenActive") || !postMissionScreenActive) - { - // Check if this mission has a debriefing video - int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; // GUI mission numbers are 1-based - - const char* videoMaterials = gui->GetStateString(va("DebriefingVideoMaterials%d", missionNum)); - const char* videoLengths = gui->GetStateString(va("DebriefingVideoLengths%d", missionNum)); - const char* videoSoundCmd = gui->GetStateString(va("DebriefingVideoSoundCmd%d", missionNum)); - - // Calculate the total length of the video - int videoLengthMsec = LoadVideosFromString(videoMaterials, videoLengths, debriefingVideo); - - gui->SetStateInt("DebriefingVideoLength", videoLengthMsec); - gui->SetStateString("DebriefingVideoSoundCmd", videoSoundCmd); - - // Let the GUI know whether we have a debriefing video - gui->SetStateBool("HasDebriefingVideo", debriefingVideo.Num() > 0); - - // Show the post-mission GUI (might be a debriefing video or just the success screen) - gui->HandleNamedEvent("ShowPostMissionScreen"); - - // Avoid duplicate triggering - gui->SetStateBool("PostMissionScreenActive", true); - postMissionScreenActive = true; - } - - // tels: We handled this command, so clear the command stack - m_GUICommandStack.Clear(); - m_GUICommandArgs = 0; - return; - } - - // Check if any errors are in the queue - if (!m_guiError.IsEmpty()) - { - // Send the error to the GUI - gui->SetStateString("gameErrorMsg", m_guiError); - gui->HandleNamedEvent("OnGameError"); - - // Clear the string again - m_guiError.Empty(); - } - - // Check messages - if (m_GuiMessages.Num() > 0) - { - HandleGuiMessages(gui); - } - - // Make sure we have a valid mission number in the GUI, the first mission is always 1 - int curMissionNum = gui->GetStateInt("CurrentMission"); - - if (curMissionNum <= 0) - { - gui->SetStateInt("CurrentMission", 1); - } - - // Handle downloads in progress - m_DownloadManager->ProcessDownloads(); - - // Propagate the video CVARs to the GUI - gui->SetStateInt("video_aspectratio", cvarSystem->GetCVarInteger("r_aspectRatio")); - gui->SetStateBool("confirmQuit", cv_mainmenu_confirmquit.GetBool()); - gui->SetStateBool("menu_bg_music", cv_tdm_menu_music.GetBool()); - - if (cv_tdm_menu_music.IsModified()) - { - gui->HandleNamedEvent("OnMenuMusicSettingChanged"); - - cv_tdm_menu_music.ClearModified(); - } - } - else if (cmd == "setvideoreswidescreen") - { - // Called when widescreen size selection changes - UpdateScreenResolutionFromGUI(gui); - UpdateGUIScaling(gui); - } - else if (cmd == "aspectratiochanged") - { - UpdateScreenResolutionFromGUI(gui); - UpdateGUIScaling(gui); - } - else if (cmd == "loadcustomvideoresolution") - { - if (cvarSystem->GetCVarInteger("r_mode") == -1) - { - // Just set the state variable based on width - int width = cvarSystem->GetCVarInteger("r_customWidth"); - int height = cvarSystem->GetCVarInteger("r_customHeight"); - - switch (width) - { - case 1024: cv_tdm_widescreenmode.SetInteger(0); break; - // 1280 x 800 => 1 - // 1280 x 720 => 6 - // 1280 x 1024 => 10 - case 1280: cv_tdm_widescreenmode.SetInteger(height == 800 ? 1 : (height == 720 ? 6 : 10) ); break; - case 1360: cv_tdm_widescreenmode.SetInteger(13); break; - case 1366: cv_tdm_widescreenmode.SetInteger(5); break; - case 1440: cv_tdm_widescreenmode.SetInteger(2); break; - // 1600 x 900 - case 1600: cv_tdm_widescreenmode.SetInteger(14); break; - case 1680: cv_tdm_widescreenmode.SetInteger(3); break; - // 1800 x 1440 - case 1800: cv_tdm_widescreenmode.SetInteger(11); break; - case 1920: cv_tdm_widescreenmode.SetInteger(height == 1200 ? 4 : 7); break; - // 2560 x 1440 => 8 - // 2560 x 1600 => 9 - // 2560 x 2048 => 12 - case 2560: cv_tdm_widescreenmode.SetInteger(height == 1440 ? 8 : height == 1600 ? 9 : 12); break; - // 3280 x 2048 - case 3280: cv_tdm_widescreenmode.SetInteger(15); break; - // 3360 x 2100 - case 3360: cv_tdm_widescreenmode.SetInteger(16); break; - // 3840 x 2160 => 17 - // 3840 x 2400 => 18 - case 3840: cv_tdm_widescreenmode.SetInteger( height == 2160 ? 17 : 18); break; - default: cv_tdm_widescreenmode.SetInteger(0); break; - } - Printf("Widescreenmode was set to: %i (%ix%i)\n", cv_tdm_widescreenmode.GetInteger(), width, height ); - } - UpdateGUIScaling(gui); - } - // greebo: the "log" command is used to write stuff to the console - else if (cmd == "log") - { - // We should log the given argument - if (cv_debug_mainmenu.GetBool()) - { - Printf("MainMenu: %s\n", m_GUICommandStack[1].c_str() ); - } - - DM_LOG(LC_MAINMENU, LT_INFO)LOGSTRING("%s\r", m_GUICommandStack[1].c_str() ); - } - else if (cmd == "close") - { - // Solarsplace: fix for #2424: - mainMenuExited = true; - - // Start the timer again, we're closing the menu - m_GamePlayTimer.Start(); - } - else if (cmd == "loadvideodefinitions") - { - // Check if we've set up the briefing video - if (!briefingVideoInfoLoaded) - { - briefingVideoInfoLoaded = true; - - // Tell the briefing video GUI to load all video materials into the state dict - gui->HandleNamedEvent("LoadVideoDefinitions"); - gui->HandleNamedEvent("LoadDebriefingVideoDefinitions"); - } - } - else if (cmd == "preparebriefingvideo") - { - // Ensure we've set up the briefing video (should already be done in "loadVideoDefinitions") - assert(briefingVideoInfoLoaded); - - // Check the video defs - int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; - - const char* videoMaterials = gui->GetStateString(va("BriefingVideoMaterials%d", missionNum)); - const char* videoLengths = gui->GetStateString(va("BriefingVideoLengths%d", missionNum)); - const char* videoSoundCmd = gui->GetStateString(va("BriefingVideoSoundCmd%d", missionNum)); - - // Calculate the total length of the video - int videoLengthMsec = LoadVideosFromString(videoMaterials, videoLengths, briefingVideo); - - gui->SetStateInt("BriefingVideoLength", videoLengthMsec); - gui->SetStateString("BriefingVideoSoundCmd", videoSoundCmd); - - // We start with the first part - curBriefingVideoPart = 0; - } - else if (cmd == "startbriefingvideo") - { - if (curBriefingVideoPart >= 0 && curBriefingVideoPart < briefingVideo.Num()) - { - gui->SetStateString("BriefingVideoMaterial", briefingVideo[curBriefingVideoPart].material); - - // Let the video windowDef reset its cinematics - gui->HandleNamedEvent("OnBriefingVideoPartChanged"); - } - else - { - // No video - gui->HandleNamedEvent("OnBriefingVideoFinished"); - } - } - else if (cmd == "briefingvideoheartbeat") - { - if (curBriefingVideoPart >= 0 && curBriefingVideoPart < briefingVideo.Num()) - { - int videoTime = gui->GetStateInt("briefingVideoTime"); - - videoTime += 16; - - if (videoTime >= briefingVideo[curBriefingVideoPart].lengthMsec) - { - curBriefingVideoPart++; - - // Briefing video part time exceeded - if (curBriefingVideoPart < briefingVideo.Num()) - { - // Switch to the next - gui->SetStateString("BriefingVideoMaterial", briefingVideo[curBriefingVideoPart].material); - gui->HandleNamedEvent("OnBriefingVideoPartChanged"); - - // Each part starts at 0 again - videoTime = 0; - } - else - { - // We're done with the video - gui->HandleNamedEvent("OnBriefingVideoFinished"); - } - } - - gui->SetStateInt("briefingVideoTime", videoTime); - } - } - else if (cmd == "preparedebriefingvideo") - { - // Ensure we've set up the debriefing video (should already be done in "loadVideoDefinitions") - assert(briefingVideoInfoLoaded); - - // We start with the first part - curDebriefingVideoPart = 0; - } - else if (cmd == "startdebriefingvideo") - { - if (curDebriefingVideoPart >= 0 && curDebriefingVideoPart < debriefingVideo.Num()) - { - gui->SetStateString("DebriefingVideoMaterial", debriefingVideo[curDebriefingVideoPart].material); - - // Let the video windowDef reset its cinematics - gui->HandleNamedEvent("OnDebriefingVideoPartChanged"); - } - else - { - // No video - gui->HandleNamedEvent("OnDebriefingVideoFinished"); - } - } - else if (cmd == "debriefingvideoheartbeat") - { - if (curDebriefingVideoPart >= 0 && curDebriefingVideoPart < debriefingVideo.Num()) - { - int videoTime = gui->GetStateInt("debriefingVideoTime"); - - videoTime += 16; - - if (videoTime >= debriefingVideo[curDebriefingVideoPart].lengthMsec) - { - curDebriefingVideoPart++; - - // Briefing video part time exceeded - if (curDebriefingVideoPart < debriefingVideo.Num()) - { - // Switch to the next - gui->SetStateString("DebriefingVideoMaterial", debriefingVideo[curDebriefingVideoPart].material); - gui->HandleNamedEvent("OnDebriefingVideoPartChanged"); - - // Each part starts at 0 again - videoTime = 0; - } - else - { - // We're done with the video - gui->HandleNamedEvent("OnDebriefingVideoFinished"); - } - } - - gui->SetStateInt("debriefingVideoTime", videoTime); - } - } - else if (cmd == "onsuccessscreencontinueclicked") - { - // Clear the mission result flag - SetMissionResult(MISSION_NOTEVENSTARTED); - - // Set the boolean back to false for the next map start - gui->SetStateBool("PostMissionScreenActive", false); - postMissionScreenActive = false; - - // Switch to the next mission if there is one - if (m_MissionManager->NextMissionAvailable()) - { - m_MissionManager->ProceedToNextMission(); - - // Store the new mission number into the GUI state - int missionNum = m_MissionManager->GetCurrentMissionIndex() + 1; - gui->SetStateInt("CurrentMission", missionNum); - - // Go to the next briefing / video - gui->HandleNamedEvent("SuccessProceedToNextMission"); - } - else - { - // Switch back to the main menu - gui->HandleNamedEvent("SuccessGoBackToMainMenu"); - } - } - else if (cmd == "setlpdifficulty") - { - // Lockpicking difficulty setting changed, update CVARs - int setting = gui->GetStateInt("lp_difficulty", "-1"); - - switch (setting) - { - case 0: // Trainer - cv_lp_auto_pick.SetBool(false); - cv_lp_pick_timeout.SetInteger(750); - break; - case 1: // Average - cv_lp_auto_pick.SetBool(false); - cv_lp_pick_timeout.SetInteger(500); - break; - case 2: // Hard - cv_lp_auto_pick.SetBool(false); - cv_lp_pick_timeout.SetInteger(400); - break; - case 3: // Expert - cv_lp_auto_pick.SetBool(false); - cv_lp_pick_timeout.SetInteger(300); - break; - case 4: // Automatic - cv_lp_auto_pick.SetBool(true); - cv_lp_pick_timeout.SetInteger(500); // auto-LP is using average timeout - break; - default: - gameLocal.Warning("Unknown value for lockpicking difficulty encountered!"); - }; - } - // load various game play settings, and update the GUI strings in one go - else if (cmd == "loadsettings") - { - int setting = 0; - if (cv_lp_auto_pick.GetBool()) - { - setting = 4; // automatic - } - else // auto-pick is false - { - if (cv_lp_pick_timeout.GetInteger() >= 750) - { - setting = 0; // Trainer - } - else if (cv_lp_pick_timeout.GetInteger() >= 500) - { - setting = 1; // Average - } - else if (cv_lp_pick_timeout.GetInteger() >= 400) - { - setting = 2; // Hard - } - else // if (cv_lp_pick_timeout.GetInteger() >= 300) - { - setting = 3; // Expert (default) - } - } - gui->SetStateInt("lp_difficulty", setting); - - idStr diffString = cv_melee_difficulty.GetString(); - bool bForbidAuto = cv_melee_forbid_auto_parry.GetBool(); - - if( diffString == "hard" ) - { - setting = 1; // Hard - } - else if( diffString == "expert" && !bForbidAuto ) - { - setting = 2; // Expert - } - else if( diffString == "expert" && bForbidAuto ) - { - setting = 3; // Master - } - else - { - setting = 0; // Normal by default - } - gui->SetStateInt("melee_difficulty", setting); - - // init various GUI variables - InitGUIChoice( gui, "gui::lp_difficulty", "#str_07318", "0;1;2;3;4" ); - InitGUIChoice( gui, "gui::melee_difficulty", "#str_07319", "0;1;2;3" ); - InitGUIChoice( gui, "tdm_door_auto_open_on_unlock", "#str_04221", "0;1" ); - InitGUIChoice( gui, "tdm_inv_use_on_frob", "#str_07300", "0;1" ); - InitGUIChoice( gui, "tdm_inv_hud_pickupmessages", "#str_04221", "0;1" ); - InitGUIChoice( gui, "tdm_inv_use_visual_feedback", "#str_07300", "0;1" ); - InitGUIChoice( gui, "tdm_dragged_item_highlight", "#str_07300", "0;1" ); - InitGUIChoice( gui, "tdm_hud_hide_lightgem", "#str_04221", "0;1" ); - - // Have the gui enable/disable auto parry - gui->HandleNamedEvent("UpdateAutoParryOption"); - } - else if (cmd == "updatemeleedifficulty") - { - // Melee difficulty setting changed, update CVARs - int setting = gui->GetStateInt("melee_difficulty", "-1"); - - switch (setting) - { - case 0: // Normal - cv_melee_difficulty.SetString("normal"); - cv_melee_forbid_auto_parry.SetBool(false); - break; - case 1: // Hard - cv_melee_difficulty.SetString("hard"); - cv_melee_forbid_auto_parry.SetBool(false); - break; - case 2: // Expert - cv_melee_difficulty.SetString("expert"); - cv_melee_forbid_auto_parry.SetBool(false); - break; - case 3: // Master, same as expert but forces manual parry to be enabled - cv_melee_difficulty.SetString("expert"); - cv_melee_auto_parry.SetBool(false); - cv_melee_forbid_auto_parry.SetBool(true); - break; - default: - gameLocal.Warning("Unknown value for melee difficulty encountered!"); - }; - - // Trigger an update for the auto-parry option when melee difficulty changes - gui->HandleNamedEvent("UpdateAutoParryOption"); - } - else if (cmd == "mainmenu_init") - { - gui->SetStateString("tdmversiontext", va("TDM %d.%02d", TDM_VERSION_MAJOR, TDM_VERSION_MINOR)); - UpdateGUIScaling(gui); - gui->SetStateString( "tdm_lang", m_I18N->GetCurrentLanguage()->c_str() ); - idStr gui_lang = "lang_"; gui_lang += m_I18N->GetCurrentLanguage()->c_str(); - gui->SetStateInt( gui_lang, 1 ); - } - else if (cmd == "check_tdm_version") - { - CheckTDMVersion(); - } - else if (cmd == "close_msg_box") - { - gui->SetStateBool("MsgBoxVisible", false); - } - else if (cmd == "updatecookedmathdata") // Adding a way to update cooked data from menu - J.C.Denton - { - // Add the command to buffer, but no need to issue it immediately. - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "tdm_updateCookedMathData" ); - } - else if (cmd == "resetbrightness") - { - idCVar * cvar = cvarSystem->Find( "r_brightness" ); - cvar ? cvar->SetFloat( 1.0f ) : Warning("Cannot find CVAR r_brightness."); - } - else if (cmd == "resetgamma") - { - idCVar * cvar = cvarSystem->Find( "r_gamma" ); - cvar ? cvar->SetFloat( 1.2f ) : Warning("Cannot find CVAR r_gamma."); - } - else if (cmd == "onstartmissionclicked") - { - // First mission to be started, reset index - m_MissionManager->SetCurrentMissionIndex(0); - gui->SetStateInt("CurrentMission", 1); - - ClearPersistentInfo(); - } - else if (cmd == "setlang") - { - const idStr *oldLang = m_I18N->GetCurrentLanguage(); - idStr newLang = m_GUICommandStack[1]; - - // reset lang_oldname and enable lang_newname - idStr gui_lang = "lang_"; gui_lang += newLang; -// Printf ("Setting %s to 1.\n", gui_lang.c_str() ); - gui->SetStateInt( gui_lang, 1 ); - gui_lang = "lang_"; gui_lang += oldLang->c_str(); -// Printf ("Setting %s to 0.\n", gui_lang.c_str() ); - gui->SetStateInt( gui_lang, 0 ); - - // do this after the step above, or oldLang will be incorrect: - Printf("GUI: Language changed to %s.\n", newLang.c_str() ); - // set the new language and store it, will also reload the GUI - gameLocal.m_I18N->SetLanguage( newLang.c_str() ); - - // store it, so the GUI can access it - gui->SetStateString( "tdm_lang", m_I18N->GetCurrentLanguage()->c_str() ); - } - // tels: #2796 build our own "choicedef" as integer/boolean option. - else if (cmd == "initchoice" || cmd == "stepchoice") - { - // DEBUG -// Printf("GUI: %s\n", cmd.c_str()); -// for (int i = 0; i < numArgs; i++) -// { -// Printf( "'%s' ", m_GUICommandStack[i+1].c_str() ); -// } - // arguments are: cvar-name choices values - InitGUIChoice( gui, m_GUICommandStack[1].c_str(), m_GUICommandStack[2].c_str(), m_GUICommandStack[3].c_str(), cmd == "stepchoice" ? true : false ); - } -// else -// { -// Warning("Unknown main menu command '%s'.\n", cmd.c_str()); -// } - - // TODO: These routines might want to handle arguments to commands, too, so - // add support for this here. E.g. instead of passing ("SomeCommand", gui), pass - // (m_GUICommandStack, gui) to them: - if (cmd != "log") - { - m_Shop->HandleCommands( menuCommand, gui); - m_ModMenu->HandleCommands( menuCommand, gui); - m_DownloadMenu->HandleCommands( cmd, gui); // expects commands in lowercase - } - - /*if (cv_debug_mainmenu.GetBool()) - { - const idDict& state = gui->State(); - - for (int i = 0; i < state.GetNumKeyVals(); ++i) - { - const idKeyValue* kv = state.GetKeyVal(i); - - const idStr key = kv->GetKey(); - const idStr value = kv->GetValue(); - - // Force the log file to write its stuff - g_Global.m_ClassArray[LC_MISC] = true; - g_Global.m_LogArray[LT_INFO] = true; - - DM_LOG(LC_MISC, LT_INFO)LOGSTRING("Mainmenu GUI State %s = %s\r", key.c_str(), value.c_str()); - } - }*/ - - // tels: We handled (or ignored) this command, so clear the command stack - m_GUICommandStack.Clear(); - m_GUICommandArgs = 0; -} - -/* -================ -idGameLocal::GetLevelMap - - should only be used for in-game level editing -================ -*/ -idMapFile *idGameLocal::GetLevelMap( void ) { - if ( mapFile && mapFile->HasPrimitiveData()) { - return mapFile; - } - if ( !mapFileName.Length() ) { - return NULL; - } - - if ( mapFile ) { - delete mapFile; - } - - mapFile = new idMapFile; - if ( !mapFile->Parse( mapFileName ) ) { - delete mapFile; - mapFile = NULL; - } - - return mapFile; -} - -/* -================ -idGameLocal::GetMapName -================ -*/ -const char *idGameLocal::GetMapName( void ) const { - return mapFileName.c_str(); -} - -/* -================ -idGameLocal::CallFrameCommand -================ -*/ -void idGameLocal::CallFrameCommand( idEntity *ent, const function_t *frameCommand ) { - frameCommandThread->CallFunction( ent, frameCommand, true ); - frameCommandThread->Execute(); -} - -/* -================ -idGameLocal::CallObjectFrameCommand -================ -*/ -void idGameLocal::CallObjectFrameCommand( idEntity *ent, const char *frameCommand ) { - const function_t *func; - - func = ent->scriptObject.GetFunction( frameCommand ); - if ( !func ) { - if ( !ent->IsType( idTestModel::Type ) ) { - Error( "Unknown function '%s' called for frame command on entity '%s'", frameCommand, ent->name.c_str() ); - } - } else { - frameCommandThread->CallFunction( ent, func, true ); - frameCommandThread->Execute(); - } -} - -/* -================ -idGameLocal::ShowTargets -================ -*/ -void idGameLocal::ShowTargets( void ) { - idMat3 axis = GetLocalPlayer()->viewAngles.ToMat3(); - idVec3 up = axis[ 2 ] * 5.0f; - const idVec3 &viewPos = GetLocalPlayer()->GetPhysics()->GetOrigin(); - idBounds viewTextBounds( viewPos ); - idBounds viewBounds( viewPos ); - idBounds box( idVec3( -4.0f, -4.0f, -4.0f ), idVec3( 4.0f, 4.0f, 4.0f ) ); - idEntity *ent; - idEntity *target; - int i; - idBounds totalBounds; - - viewTextBounds.ExpandSelf( 128.0f ); - viewBounds.ExpandSelf( 512.0f ); - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - totalBounds = ent->GetPhysics()->GetAbsBounds(); - for( i = 0; i < ent->targets.Num(); i++ ) { - target = ent->targets[ i ].GetEntity(); - if ( target ) { - totalBounds.AddBounds( target->GetPhysics()->GetAbsBounds() ); - } - } - - if ( !viewBounds.IntersectsBounds( totalBounds ) ) { - continue; - } - - float dist; - idVec3 dir = totalBounds.GetCenter() - viewPos; - dir.NormalizeFast(); - totalBounds.RayIntersection( viewPos, dir, dist ); - float frac = ( 512.0f - dist ) / 512.0f; - if ( frac < 0.0f ) { - continue; - } - - gameRenderWorld->DebugBounds( ( ent->IsHidden() ? colorLtGrey : colorOrange ) * frac, ent->GetPhysics()->GetAbsBounds() ); - if ( viewTextBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { - idVec3 center = ent->GetPhysics()->GetAbsBounds().GetCenter(); - gameRenderWorld->DrawText( ent->name.c_str(), center - up, 0.1f, colorWhite * frac, axis, 1 ); - gameRenderWorld->DrawText( ent->GetEntityDefName(), center, 0.1f, colorWhite * frac, axis, 1 ); - gameRenderWorld->DrawText( va( "#%d", ent->entityNumber ), center + up, 0.1f, colorWhite * frac, axis, 1 ); - } - - for( i = 0; i < ent->targets.Num(); i++ ) { - target = ent->targets[ i ].GetEntity(); - if ( target ) { - gameRenderWorld->DebugArrow( colorYellow * frac, ent->GetPhysics()->GetAbsBounds().GetCenter(), target->GetPhysics()->GetOrigin(), 10, 0 ); - gameRenderWorld->DebugBounds( colorGreen * frac, box, target->GetPhysics()->GetOrigin() ); - } - } - } -} - -/* -================ -idGameLocal::RunDebugInfo -================ -*/ -void idGameLocal::RunDebugInfo( void ) { - idEntity *ent; - idPlayer *player; - - player = GetLocalPlayer(); - if ( !player ) { - return; - } - - const idVec3 &origin = player->GetPhysics()->GetOrigin(); - - if ( g_showEntityInfo.GetBool() ) { - idMat3 axis = player->viewAngles.ToMat3(); - idVec3 up = axis[ 2 ] * 5.0f; - idBounds viewTextBounds( origin ); - idBounds viewBounds( origin ); - - viewTextBounds.ExpandSelf( 128.0f ); - viewBounds.ExpandSelf( 512.0f ); - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - // don't draw the worldspawn - if ( ent == world ) { - continue; - } - - // skip if the entity is very far away - if ( !viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { - continue; - } - - const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); - int contents = ent->GetPhysics()->GetContents(); - if ( contents & CONTENTS_BODY ) { - gameRenderWorld->DebugBounds( colorCyan, entBounds ); - } else if ( contents & CONTENTS_TRIGGER ) { - gameRenderWorld->DebugBounds( colorOrange, entBounds ); - } else if ( contents & CONTENTS_SOLID ) { - gameRenderWorld->DebugBounds( colorGreen, entBounds ); - } else { - if ( !entBounds.GetVolume() ) { - gameRenderWorld->DebugBounds( colorMdGrey, entBounds.Expand( 8.0f ) ); - } else { - gameRenderWorld->DebugBounds( colorMdGrey, entBounds ); - } - } - if ( viewTextBounds.IntersectsBounds( entBounds ) ) { - gameRenderWorld->DrawText( ent->name.c_str(), entBounds.GetCenter(), 0.1f, colorWhite, axis, 1 ); - gameRenderWorld->DrawText( va( "#%d", ent->entityNumber ), entBounds.GetCenter() + up, 0.1f, colorWhite, axis, 1 ); - gameRenderWorld->DrawText( - va( "%d / %d", ent->GetPhysics()->GetContents(), ent->GetPhysics()->GetClipMask() ), - entBounds.GetCenter() - up, 0.1f, - colorWhite, - axis, 1 - ); - } - } - } - - // debug tool to draw bounding boxes around active entities - if ( g_showActiveEntities.GetBool() ) { - for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) { - idBounds b = ent->GetPhysics()->GetBounds(); - if ( b.GetVolume() <= 0 ) { - b[0][0] = b[0][1] = b[0][2] = -8; - b[1][0] = b[1][1] = b[1][2] = 8; - } - if ( ent->fl.isDormant ) { - gameRenderWorld->DebugBounds( colorYellow, b, ent->GetPhysics()->GetOrigin() ); - } else { - gameRenderWorld->DebugBounds( colorGreen, b, ent->GetPhysics()->GetOrigin() ); - } - } - } - - if ( g_showTargets.GetBool() ) { - ShowTargets(); - } - - if ( g_showTriggers.GetBool() ) { - idTrigger::DrawDebugInfo(); - } - - if ( cv_show_health.GetBool() ) { - idMat3 axis = player->viewAngles.ToMat3(); - idBounds viewBounds( origin ); - viewBounds.ExpandSelf( 512.0f ); - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - // don't draw the worldspawn or "dead" entities - if ( ent == world || !ent->health) { - continue; - } - - // skip if the entity is very far away - if ( !viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { - continue; - } - - gameRenderWorld->DrawText(va("Health: %d", ent->health), ent->GetPhysics()->GetOrigin(), 0.2f, colorGreen, axis); - } - } - - if ( ai_showCombatNodes.GetBool() ) { - idCombatNode::DrawDebugInfo(); - } - - if ( ai_showPaths.GetBool() ) { - idPathCorner::DrawDebugInfo(); - } - - if ( g_editEntityMode.GetBool() ) { - editEntities->DisplayEntities(); - } - - if ( g_showCollisionWorld.GetBool() ) { - collisionModelManager->DrawModel( 0, vec3_origin, mat3_identity, origin, 128.0f ); - } - - if ( g_showCollisionModels.GetBool() ) { - clip.DrawClipModels( player->GetEyePosition(), g_maxShowDistance.GetFloat(), pm_thirdPerson.GetBool() ? NULL : player ); - } - - if ( g_showCollisionTraces.GetBool() ) { - clip.PrintStatistics(); - } - - if ( g_showPVS.GetInteger() ) { - pvs.DrawPVS( origin, ( g_showPVS.GetInteger() == 2 ) ? PVS_ALL_PORTALS_OPEN : PVS_NORMAL ); - } - - if ( aas_test.GetInteger() >= 0 ) { - idAAS *aas = GetAAS( aas_test.GetInteger() ); - if ( aas ) { - aas->Test( origin ); - if ( ai_testPredictPath.GetBool() ) { - idVec3 velocity; - predictedPath_t path; - - velocity.x = cos( DEG2RAD( player->viewAngles.yaw ) ) * 100.0f; - velocity.y = sin( DEG2RAD( player->viewAngles.yaw ) ) * 100.0f; - velocity.z = 0.0f; - idAI::PredictPath( player, aas, origin, velocity, 1000, 100, SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA, path ); - } - } - } - - if ( ai_showObstacleAvoidance.GetInteger() == 2 ) { - idAAS *aas = GetAAS("aas32"); - if ( aas ) { - idVec3 seekPos; - obstaclePath_t path; - - seekPos = player->GetPhysics()->GetOrigin() + player->viewAxis[0] * 200.0f; - idAI::FindPathAroundObstacles( player->GetPhysics(), aas, NULL, player->GetPhysics()->GetOrigin(), seekPos, path, player ); - } - } - - // collision map debug output - collisionModelManager->DebugOutput( player->GetEyePosition() ); -} - -/* -================== -idGameLocal::NumAAS -================== -*/ -int idGameLocal::NumAAS( void ) const { - return aasList.Num(); -} - -/* -================== -idGameLocal::GetAASId (TDM) -================== -*/ -int idGameLocal::GetAASId( idAAS* aas ) const -{ - // Do a reverse lookup in the aasList array - return aasList.FindIndex(aas); -} - -/* -================== -idGameLocal::GetAAS -================== -*/ -idAAS *idGameLocal::GetAAS( int num ) const { - if ( ( num >= 0 ) && ( num < aasList.Num() ) ) { - if ( aasList[ num ] && aasList[ num ]->GetSettings() ) { - return aasList[ num ]; - } - } - return NULL; -} - -/* -================== -idGameLocal::GetAAS -================== -*/ -idAAS *idGameLocal::GetAAS( const char *name ) const { - int i; - - for ( i = 0; i < aasNames.Num(); i++ ) { - if ( aasNames[ i ] == name ) { - if ( !aasList[ i ]->GetSettings() ) { - return NULL; - } else { - return aasList[ i ]; - } - } - } - return NULL; -} - -/* -================== -idGameLocal::SetAASAreaState -================== -*/ -void idGameLocal::SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed ) { - int i; - - for( i = 0; i < aasList.Num(); i++ ) { - aasList[ i ]->SetAreaState( bounds, areaContents, closed ); - } -} - -/* -================== -idGameLocal::AddAASObstacle -================== -*/ -aasHandle_t idGameLocal::AddAASObstacle( const idBounds &bounds ) { - int i; - aasHandle_t obstacle; - aasHandle_t check; - - if ( !aasList.Num() ) { - return -1; - } - - obstacle = aasList[ 0 ]->AddObstacle( bounds ); - for( i = 1; i < aasList.Num(); i++ ) { - check = aasList[ i ]->AddObstacle( bounds ); - assert( check == obstacle ); - } - - return obstacle; -} - -/* -================== -idGameLocal::RemoveAASObstacle -================== -*/ -void idGameLocal::RemoveAASObstacle( const aasHandle_t handle ) { - int i; - - for( i = 0; i < aasList.Num(); i++ ) { - aasList[ i ]->RemoveObstacle( handle ); - } -} - -/* -================== -idGameLocal::RemoveAllAASObstacles -================== -*/ -void idGameLocal::RemoveAllAASObstacles( void ) { - int i; - - for( i = 0; i < aasList.Num(); i++ ) { - aasList[ i ]->RemoveAllObstacles(); - } -} - -void idGameLocal::SetupEAS() -{ - // Cycle through the entities and find all elevators - for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - if (!ent->IsType(CMultiStateMover::Type)) - { - continue; - } - - // Get all position entities of that mover - CMultiStateMover* mover = static_cast(ent); - - for (int aasNum = 0; aasNum < NumAAS(); aasNum++) - { - idAASLocal* aas = dynamic_cast(GetAAS(aasNum)); - if (aas == NULL) continue; - - aas->AddElevator(mover); - } - } - - // All elevators registered, compile the routing information - for (int aasNum = 0; aasNum < NumAAS(); aasNum++) - { - idAASLocal* aas = dynamic_cast(GetAAS(aasNum)); - if (aas == NULL) continue; - - aas->CompileEAS(); - } -} - -/* -================== -idGameLocal::CheatsOk -================== -*/ -bool idGameLocal::CheatsOk( bool requirePlayer ) { - idPlayer *player; - - if ( isMultiplayer && !cvarSystem->GetCVarBool( "net_allowCheats" ) ) { - Printf( "Not allowed in multiplayer.\n" ); - return false; - } - - if ( developer.GetBool() ) { - return true; - } - - player = GetLocalPlayer(); - if ( !requirePlayer || ( player && ( player->health > 0 ) ) ) { - return true; - } - - Printf( "You must be alive to use this command.\n" ); - - return false; -} - -/* -=================== -idGameLocal::RegisterEntity -=================== -*/ -void idGameLocal::RegisterEntity( idEntity *ent ) { - int spawn_entnum; - - if ( spawnCount >= ( 1 << ( 32 - GENTITYNUM_BITS ) ) ) { - Error( "idGameLocal::RegisterEntity: spawn count overflow" ); - } - - if ( !spawnArgs.GetInt( "spawn_entnum", "0", spawn_entnum ) ) { - while( entities[firstFreeIndex] && firstFreeIndex < ENTITYNUM_MAX_NORMAL ) { - firstFreeIndex++; - } - if ( firstFreeIndex >= ENTITYNUM_MAX_NORMAL ) { - Error( "no free entities" ); - } - spawn_entnum = firstFreeIndex++; - } - - entities[ spawn_entnum ] = ent; - spawnIds[ spawn_entnum ] = spawnCount++; - ent->entityNumber = spawn_entnum; - ent->spawnNode.AddToEnd( spawnedEntities ); - - // this will also have the effect of spawnArgs.Clear() at the same time: - ent->spawnArgs.TransferKeyValues( spawnArgs ); - - if ( spawn_entnum >= num_entities ) { - num_entities++; - } -} - -/* -=================== -idGameLocal::UnregisterEntity -=================== -*/ -void idGameLocal::UnregisterEntity( idEntity *ent ) { - assert( ent ); - - if ( editEntities ) { - editEntities->RemoveSelectedEntity( ent ); - } - - if ( ( ent->entityNumber != ENTITYNUM_NONE ) && ( entities[ ent->entityNumber ] == ent ) ) { - ent->spawnNode.Remove(); - entities[ ent->entityNumber ] = NULL; - spawnIds[ ent->entityNumber ] = -1; - if ( ent->entityNumber >= MAX_CLIENTS && ent->entityNumber < firstFreeIndex ) { - firstFreeIndex = ent->entityNumber; - } - ent->entityNumber = ENTITYNUM_NONE; - } -} - -/* -================ -idGameLocal::SpawnEntityType -================ -*/ -idEntity *idGameLocal::SpawnEntityType( const idTypeInfo &classdef, const idDict *args, bool bIsClientReadSnapshot ) { - idClass *obj; - -#if _DEBUG - if ( isClient ) { - assert( bIsClientReadSnapshot ); - } -#endif - - if ( !classdef.IsType( idEntity::Type ) ) { - Error( "Attempted to spawn non-entity class '%s'", classdef.classname ); - } - - try { - if ( args ) { - spawnArgs = *args; - } else { - spawnArgs.Clear(); - } - obj = classdef.CreateInstance(); - obj->CallSpawn(); - } - - catch( idAllocError & ) { - obj = NULL; - } - spawnArgs.Clear(); - - return static_cast(obj); -} - -/* -=================== -idGameLocal::SpawnEntityDef - -Finds the spawn function for the entity and calls it, -returning false if not found -=================== -*/ -bool idGameLocal::SpawnEntityDef( const idDict &args, idEntity **ent, bool setDefaults ) { - const char *classname; - const char *spawn; - idTypeInfo *cls; - idClass *obj; - idStr error; - const char *name; - - if ( ent ) { - *ent = NULL; - } - - spawnArgs = args; - - if ( spawnArgs.GetString( "name", "", &name ) ) { - sprintf( error, " on '%s'", name); - } - - spawnArgs.GetString( "classname", NULL, &classname ); - const idDeclEntityDef *def = FindEntityDef( classname, false ); - - if ( !def ) { - Warning( "Unknown classname '%s'%s.\n", classname, error.c_str() ); - return false; - } - - // Tels: SetDefaults(), but without the "editor_" spawnargs - spawnArgs.SetDefaults( &def->dict, idStr("editor_") ); - - // greebo: Apply the difficulty settings before any values get filled from the spawnarg data - m_DifficultyManager.ApplyDifficultySettings(spawnArgs); - - // check if we should spawn a class object - spawnArgs.GetString( "spawnclass", NULL, &spawn ); - if ( spawn ) { - - cls = idClass::GetClass( spawn ); - if ( !cls ) { - Warning( "Could not spawn '%s'. Class '%s' not found%s.", classname, spawn, error.c_str() ); - return false; - } - - obj = cls->CreateInstance(); - if ( !obj ) { - Warning( "Could not spawn '%s'. Instance could not be created%s.", classname, error.c_str() ); - return false; - } - - obj->CallSpawn(); - - if ( ent && obj->IsType( idEntity::Type ) ) { - *ent = static_cast(obj); - } - - // Check for campaign info ents - if (idStr::Cmp(classname, "atdm:campaign_info") == 0) - { - assert(obj->IsType(idEntity::Type)); - campaignInfoEntities.Append(static_cast(obj)); - } - - return true; - } - - // check if we should call a script function to spawn - spawnArgs.GetString( "spawnfunc", NULL, &spawn ); - if ( spawn ) { - const function_t *func = program.FindFunction( spawn ); - if ( !func ) { - Warning( "Could not spawn '%s'. Script function '%s' not found%s.", classname, spawn, error.c_str() ); - return false; - } - idThread *thread = new idThread( func ); - thread->DelayedStart( 0 ); - return true; - } - - Warning( "%s doesn't include a spawnfunc or spawnclass%s.", classname, error.c_str() ); - return false; -} - -/* -================ -idGameLocal::FindEntityDef -================ -*/ -const idDeclEntityDef *idGameLocal::FindEntityDef( const char *name, bool makeDefault ) const { - const idDecl *decl = NULL; - if ( isMultiplayer ) { - decl = declManager->FindType( DECL_ENTITYDEF, va( "%s_mp", name ), false ); - } - if ( !decl ) { - decl = declManager->FindType( DECL_ENTITYDEF, name, makeDefault ); - } - return static_cast( decl ); -} - -/* -================ -idGameLocal::FindEntityDefDict -================ -*/ -const idDict *idGameLocal::FindEntityDefDict( const char *name, bool makeDefault ) const { - const idDeclEntityDef *decl = FindEntityDef( name, makeDefault ); - return decl ? &decl->dict : NULL; -} - -/* -================ -idGameLocal::InhibitEntitySpawn -================ -*/ -bool idGameLocal::InhibitEntitySpawn( idDict &spawnArgs ) { - - bool result = false; - - /* greebo: Disabled vanilla D3 stuff, will be handled by our DifficultyManager - if ( isMultiplayer ) { - spawnArgs.GetBool( "not_multiplayer", "0", result ); - } else if ( g_skill.GetInteger() == 0 ) { - spawnArgs.GetBool( "not_easy", "0", result ); - } else if ( g_skill.GetInteger() == 1 ) { - spawnArgs.GetBool( "not_medium", "0", result ); - } else { - spawnArgs.GetBool( "not_hard", "0", result ); - } - - const char *name; -#ifndef ID_DEMO_BUILD - if ( g_skill.GetInteger() == 3 ) { - name = spawnArgs.GetString( "classname" ); - if ( idStr::Icmp( name, "item_medkit" ) == 0 || idStr::Icmp( name, "item_medkit_small" ) == 0 ) { - result = true; - } - } -#endif - - }*/ - - // Consult the difficulty manager, whether this entity should be prevented from being spawned. - result = m_DifficultyManager.InhibitEntitySpawn(spawnArgs); - - return result; -} - -/* -================ -idGameLocal::SetSkill -================ -*/ -void idGameLocal::SetSkill( int value ) { - int skill_level; - - if ( value < 0 ) { - skill_level = 0; - } else if ( value > 3 ) { - skill_level = 3; - } else { - skill_level = value; - } - - g_skill.SetInteger( skill_level ); -} - -/* -============== -idGameLocal::GameState - -Used to allow entities to know if they're being spawned during the initial spawn. -============== -*/ -gameState_t idGameLocal::GameState( void ) const { - return gamestate; -} - -void idGameLocal::PrepareForMissionEnd() -{ - // Raise the gamestate to "Completed" - gamestate = GAMESTATE_COMPLETED; - - // Remove mission triggers now that we're done here - for (int i = 0; i < m_InterMissionTriggers.Num(); ) - { - if (m_InterMissionTriggers[i].missionNum == m_MissionManager->GetCurrentMissionIndex()) - { - m_InterMissionTriggers.RemoveIndex(i); - } - else - { - ++i; - } - } -} - -/* -============== -idGameLocal::SpawnMapEntities - -Parses textual entity definitions out of an entstring and spawns gentities. -============== -*/ -void idGameLocal::SpawnMapEntities( void ) { - int i; - int num; - int inhibit; - idMapEntity *mapEnt; - int numEntities; - idDict args; - - Printf( "Spawning entities\n" ); - - if ( mapFile == NULL ) { - Printf("No mapfile present\n"); - return; - } - - SetSkill( g_skill.GetInteger() ); - - // Add the lightgem to the map before anything else happened - // so it will be included as if it were a regular map entity. - m_lightGem.SpawnLightGemEntity( mapFile ); - - numEntities = mapFile->GetNumEntities(); - if ( numEntities == 0 ) { - Error( "...no entities" ); - } - - // the worldspawn is a special that performs any global setup - // needed by a level - mapEnt = mapFile->GetEntity( 0 ); - args = mapEnt->epairs; - args.SetInt( "spawn_entnum", ENTITYNUM_WORLD ); - if ( !SpawnEntityDef( args ) || !entities[ ENTITYNUM_WORLD ] || !entities[ ENTITYNUM_WORLD ]->IsType( idWorldspawn::Type ) ) { - Error( "Problem spawning world entity" ); - } - - num = 1; - inhibit = 0; - - // Clear out the campaign info cache - campaignInfoEntities.Clear(); - - for ( i = 1 ; i < numEntities ; i++ ) { - mapEnt = mapFile->GetEntity( i ); - args = mapEnt->epairs; - -#ifdef LOGBUILD - // Tels: This might need a lot of time, even when the logging is disabled, so make - // sure we execute this loop only if we need to log: - if(g_Global.m_ClassArray[LC_ENTITY] == true && g_Global.m_LogArray[LT_DEBUG] == true) - { - int n = args.GetNumKeyVals(); - for(int x = 0; x < n; x++) - { - const idKeyValue *p = args.GetKeyVal(x); - const idStr k = p->GetKey(); - const idStr v = p->GetValue(); - DM_LOG(LC_ENTITY, LT_DEBUG)LOGSTRING("Entity[%u] Key:[%s] = [%s]\r", i, k.c_str(), v.c_str()); - } - } -#endif - - if (!InhibitEntitySpawn(args)) - { - // precache any media specified in the map entity - CacheDictionaryMedia(&args); - - SpawnEntityDef(args); - num++; - } else { - inhibit++; - } - } - - m_lightGem.InitializeLightGemEntity(); - - Printf( "...%i entities spawned, %i inhibited\n\n", num, inhibit ); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("... %i entities spawned, %i inhibited\r", num, inhibit); -} - -/* -================ -idGameLocal::AddEntityToHash -================ -*/ -void idGameLocal::AddEntityToHash( const char *name, idEntity *ent ) { - if ( FindEntity( name ) ) { - Error( "Multiple entities named '%s'", name ); - } - entityHash.Add( entityHash.GenerateKey( name, true ), ent->entityNumber ); -} - -/* -================ -idGameLocal::RemoveEntityFromHash -================ -*/ -bool idGameLocal::RemoveEntityFromHash( const char *name, idEntity *ent ) { - int hash, i; - - hash = entityHash.GenerateKey( name, true ); - for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { - if ( entities[i] && entities[i] == ent && entities[i]->name.Icmp( name ) == 0 ) { - entityHash.Remove( hash, i ); - return true; - } - } - return false; -} - -/* -================ -idGameLocal::GetTargets -================ -*/ -int idGameLocal::GetTargets( const idDict &args, idList< idEntityPtr > &list, const char *ref ) const { - int i, num, refLength; - const idKeyValue *arg; - idEntity *ent; - - list.Clear(); - - refLength = strlen( ref ); - num = args.GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - - arg = args.GetKeyVal( i ); - if ( arg->GetKey().Icmpn( ref, refLength ) == 0 ) { - - ent = FindEntity( arg->GetValue() ); - if ( ent ) { - idEntityPtr &entityPtr = list.Alloc(); - entityPtr = ent; - } - } - } - - return list.Num(); -} - -/* -================ -idGameLocal::GetRelights - grayman #2603 - retrieve relight entities and add them to the target list -================ -*/ -int idGameLocal::GetRelights( const idDict &args, idList< idEntityPtr > &list, const char *ref ) const -{ - int i,num,refLength; - const idKeyValue *arg; - idEntity *ent; - - refLength = strlen(ref); - num = args.GetNumKeyVals(); - for (i = 0 ; i < num ; i++) - { - arg = args.GetKeyVal(i); - if (arg->GetKey().Icmpn(ref,refLength) == 0) - { - const idStr name = arg->GetValue(); - ent = FindEntity(name); - if (ent) - { - idEntityPtr &entityPtr = list.Alloc(); - entityPtr = ent; - } - } - } - - return list.Num(); -} - -/* -============= -idGameLocal::GetTraceEntity - -returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player. -============= -*/ -idEntity *idGameLocal::GetTraceEntity( const trace_t &trace ) const { - idEntity *master; - - if ( !entities[ trace.c.entityNum ] ) { - return NULL; - } - master = entities[ trace.c.entityNum ]->GetBindMaster(); - if ( master ) { - return master; - } - return entities[ trace.c.entityNum ]; -} - -/* -============= -idGameLocal::ArgCompletion_EntityName - -Argument completion for entity names -============= -*/ -void idGameLocal::ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) ) { - int i; - - for( i = 0; i < gameLocal.num_entities; i++ ) { - if ( gameLocal.entities[ i ] ) { - callback( va( "%s %s", args.Argv( 0 ), gameLocal.entities[ i ]->name.c_str() ) ); - } - } -} - -/* -============= -idGameLocal::FindEntity - -Returns the entity whose name matches the specified string. -============= -*/ -idEntity *idGameLocal::FindEntity( const char *name ) const { - int hash, i; - - hash = entityHash.GenerateKey( name, true ); - for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { - if ( entities[i] && entities[i]->name.Icmp( name ) == 0 ) { - return entities[i]; - } - } - - return NULL; -} - -/* -============= -idGameLocal::FindEntityUsingDef - -Searches all active entities for the next one using the specified entityDef. - -Searches beginning at the entity after from, or the beginning if NULL -NULL will be returned if the end of the list is reached. -============= -*/ -idEntity *idGameLocal::FindEntityUsingDef( idEntity *from, const char *match ) const { - idEntity *ent; - - if ( !from ) { - ent = spawnedEntities.Next(); - } else { - ent = from->spawnNode.Next(); - } - - for ( ; ent != NULL; ent = ent->spawnNode.Next() ) { - assert( ent ); - if ( idStr::Icmp( ent->GetEntityDefName(), match ) == 0 ) { - return ent; - } - } - - return NULL; -} - -/* -============= -idGameLocal::FindTraceEntity - -Searches all active entities for the closest ( to start ) match that intersects -the line start,end -============= -*/ -idEntity *idGameLocal::FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const { - idEntity *ent; - idEntity *bestEnt; - float scale; - float bestScale; - idBounds b; - - bestEnt = NULL; - bestScale = 1.0f; - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( c ) && ent != skip ) { - b = ent->GetPhysics()->GetAbsBounds().Expand( 16 ); - if ( b.RayIntersection( start, end-start, scale ) ) { - if ( scale >= 0.0f && scale < bestScale ) { - bestEnt = ent; - bestScale = scale; - } - } - } - } - - return bestEnt; -} - -/* -================ -idGameLocal::EntitiesWithinRadius -================ -*/ -int idGameLocal::EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const { - idEntity *ent; - idBounds bo( org ); - int entCount = 0; - - bo.ExpandSelf( radius ); - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->GetPhysics()->GetAbsBounds().IntersectsBounds( bo ) ) { - entityList[entCount++] = ent; - } - } - - return entCount; -} - -/* -================= -idGameLocal::KillBox - -Kills all entities that would touch the proposed new positioning of ent. The ent itself will not being killed. -Checks if player entities are in the teleporter, and marks them to die at teleport exit instead of immediately. -If catch_teleport, this only marks teleport players for death on exit -================= -*/ -void idGameLocal::KillBox( idEntity *ent, bool catch_teleport ) { - int i; - int num; - idEntity * hit; - idClipModel *cm; - idClipModel *clipModels[ MAX_GENTITIES ]; - idPhysics *phys; - - phys = ent->GetPhysics(); - if ( !phys->GetNumClipModels() ) { - return; - } - - num = clip.ClipModelsTouchingBounds( phys->GetAbsBounds(), phys->GetClipMask(), clipModels, MAX_GENTITIES ); - for ( i = 0; i < num; i++ ) { - cm = clipModels[ i ]; - - // don't check render entities - if ( cm->IsRenderModel() ) { - continue; - } - - hit = cm->GetEntity(); - if ( ( hit == ent ) || !hit->fl.takedamage ) { - continue; - } - - if ( !phys->ClipContents( cm ) ) { - continue; - } - - // nail it - if ( hit->IsType( idPlayer::Type ) && static_cast< idPlayer * >( hit )->IsInTeleport() ) { - static_cast< idPlayer * >( hit )->TeleportDeath( ent->entityNumber ); - } else if ( !catch_teleport ) { - hit->Damage( ent, ent, vec3_origin, "damage_telefrag", 1.0f, INVALID_JOINT ); - } - - if ( !gameLocal.isMultiplayer ) { - // let the mapper know about it - Warning( "'%s' telefragged '%s'", ent->name.c_str(), hit->name.c_str() ); - } - } -} - -/* -================ -idGameLocal::RequirementMet -================ -*/ -bool idGameLocal::RequirementMet( idEntity *activator, const idStr &requires, int removeItem ) { - if ( requires.Length() ) { - if ( activator->IsType( idPlayer::Type ) ) { - idPlayer *player = static_cast(activator); - idDict *item = NULL;//player->FindInventoryItem( requires ); - if ( item ) { - if ( removeItem ) { - //player->RemoveInventoryItem( item ); - } - return true; - } else { - return false; - } - } - } - - return true; -} - -/* -============ -idGameLocal::RadiusDamage -============ -*/ -void idGameLocal::RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower ) { - float dist, damageScale, attackerDamageScale, attackerPushScale; - idEntity * ent; - idEntity * entityList[ MAX_GENTITIES ]; - int numListedEntities; - idBounds bounds; - idVec3 v, damagePoint, dir; - int i, e, damage, radius, push; - - const idDict *damageDef = FindEntityDefDict( damageDefName, false ); - if ( !damageDef ) { - Warning( "Unknown damageDef '%s'", damageDefName ); - return; - } - - damageDef->GetInt( "damage", "20", damage ); - damageDef->GetInt( "radius", "50", radius ); - damageDef->GetInt( "push", va( "%d", damage * 100 ), push ); - damageDef->GetFloat( "attackerDamageScale", "0.5", attackerDamageScale ); - damageDef->GetFloat( "attackerPushScale", "0", attackerPushScale ); - - if ( radius < 1 ) { - radius = 1; - } - - bounds = idBounds( origin ).Expand( radius ); - // get all entities touching the bounds - numListedEntities = clip.EntitiesTouchingBounds( bounds, -1, entityList, MAX_GENTITIES ); - - if ( inflictor && inflictor->IsType( idAFAttachment::Type ) ) { - inflictor = static_cast(inflictor)->GetBody(); - } - if ( attacker && attacker->IsType( idAFAttachment::Type ) ) { - attacker = static_cast(attacker)->GetBody(); - } - if ( ignoreDamage && ignoreDamage->IsType( idAFAttachment::Type ) ) { - ignoreDamage = static_cast(ignoreDamage)->GetBody(); - } - - // apply damage to the entities - for ( e = 0; e < numListedEntities; e++ ) { - ent = entityList[ e ]; - assert( ent ); - - if ( !ent->fl.takedamage ) { - continue; - } - - if ( ent == inflictor || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == inflictor ) ) { - continue; - } - - if ( ent == ignoreDamage || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == ignoreDamage ) ) { - continue; - } - - // don't damage a dead player - if ( isMultiplayer && ent->entityNumber < MAX_CLIENTS && ent->IsType( idPlayer::Type ) && static_cast< idPlayer * >( ent )->health < 0 ) { - continue; - } - - // find the distance from the edge of the bounding box - for ( i = 0; i < 3; i++ ) { - if ( origin[ i ] < ent->GetPhysics()->GetAbsBounds()[0][ i ] ) { - v[ i ] = ent->GetPhysics()->GetAbsBounds()[0][ i ] - origin[ i ]; - } else if ( origin[ i ] > ent->GetPhysics()->GetAbsBounds()[1][ i ] ) { - v[ i ] = origin[ i ] - ent->GetPhysics()->GetAbsBounds()[1][ i ]; - } else { - v[ i ] = 0; - } - } - - dist = v.Length(); - if ( dist >= radius ) { - continue; - } - - if ( ent->CanDamage( origin, damagePoint ) ) { - // push the center of mass higher than the origin so players - // get knocked into the air more - dir = ent->GetPhysics()->GetOrigin() - origin; - dir[ 2 ] += 24; - - // get the damage scale - damageScale = dmgPower * ( 1.0f - dist / radius ); - if ( ent == attacker || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == attacker ) ) { - damageScale *= attackerDamageScale; - } - - ent->Damage( inflictor, attacker, dir, damageDefName, damageScale, INVALID_JOINT ); - } - } - - // push physics objects - if ( push ) { - RadiusPush( origin, radius, push * dmgPower, attacker, ignorePush, attackerPushScale, false ); - } -} - -/* -============== -idGameLocal::RadiusPush -============== -*/ -void idGameLocal::RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake ) { - int i, numListedClipModels; - idClipModel *clipModel; - idClipModel *clipModelList[ MAX_GENTITIES ]; - idVec3 dir; - idBounds bounds; - modelTrace_t result; - idEntity *ent; - float scale; - - dir.Set( 0.0f, 0.0f, 1.0f ); - - bounds = idBounds( origin ).Expand( radius ); - - // get all clip models touching the bounds - numListedClipModels = clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); - - if ( inflictor && inflictor->IsType( idAFAttachment::Type ) ) { - inflictor = static_cast(inflictor)->GetBody(); - } - if ( ignore && ignore->IsType( idAFAttachment::Type ) ) { - ignore = static_cast(ignore)->GetBody(); - } - - // apply impact to all the clip models through their associated physics objects - for ( i = 0; i < numListedClipModels; i++ ) { - - clipModel = clipModelList[i]; - - // never push render models - if ( clipModel->IsRenderModel() ) { - continue; - } - - ent = clipModel->GetEntity(); - - // never push projectiles - if ( ent->IsType( idProjectile::Type ) ) { - continue; - } - - // players use "knockback" in idPlayer::Damage - if ( ent->IsType( idPlayer::Type ) && !quake ) { - continue; - } - - // don't push the ignore entity - if ( ent == ignore || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == ignore ) ) { - continue; - } - - if ( gameRenderWorld->FastWorldTrace( result, origin, clipModel->GetOrigin() ) ) { - continue; - } - - // scale the push for the inflictor - if ( ent == inflictor || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody() == inflictor ) ) { - scale = inflictorScale; - } else { - scale = 1.0f; - } - - if ( quake ) { - clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), clipModel->GetOrigin(), scale * push * dir ); - } else { - RadiusPushClipModel( origin, scale * push, clipModel ); - } - } -} - -/* -============== -idGameLocal::RadiusPushClipModel -============== -*/ -void idGameLocal::RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel ) { - int i, j; - float dot, dist, area; - const idTraceModel *trm; - const traceModelPoly_t *poly; - idFixedWinding w; - idVec3 v, localOrigin, center, impulse; - - trm = clipModel->GetTraceModel(); - if ( !trm || 1 ) { - impulse = clipModel->GetAbsBounds().GetCenter() - origin; - impulse.Normalize(); - impulse.z += 1.0f; - clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), clipModel->GetOrigin(), push * impulse ); - return; - } - - localOrigin = ( origin - clipModel->GetOrigin() ) * clipModel->GetAxis().Transpose(); - for ( i = 0; i < trm->numPolys; i++ ) { - poly = &trm->polys[i]; - - center.Zero(); - for ( j = 0; j < poly->numEdges; j++ ) { - v = trm->verts[ trm->edges[ abs(poly->edges[j]) ].v[ INTSIGNBITSET( poly->edges[j] ) ] ]; - center += v; - v -= localOrigin; - v.NormalizeFast(); // project point on a unit sphere - w.AddPoint( v ); - } - center /= poly->numEdges; - v = center - localOrigin; - dist = v.NormalizeFast(); - dot = v * poly->normal; - if ( dot > 0.0f ) { - continue; - } - area = w.GetArea(); - // impulse in polygon normal direction - impulse = poly->normal * clipModel->GetAxis(); - // always push up for nicer effect - impulse.z -= 1.0f; - // scale impulse based on visible surface area and polygon angle - impulse *= push * ( dot * area * ( 1.0f / ( 4.0f * idMath::PI ) ) ); - // scale away distance for nicer effect - impulse *= ( dist * 2.0f ); - // impulse is applied to the center of the polygon - center = clipModel->GetOrigin() + center * clipModel->GetAxis(); - - clipModel->GetEntity()->ApplyImpulse( world, clipModel->GetId(), center, impulse ); - } -} - -/* -=============== -idGameLocal::ProjectDecal -=============== -*/ -void idGameLocal::ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle ) { - float s, c; - idMat3 axis, axistemp; - idFixedWinding winding; - idVec3 windingOrigin, projectionOrigin; - - static idVec3 decalWinding[4] = { - idVec3( 1.0f, 1.0f, 0.0f ), - idVec3( -1.0f, 1.0f, 0.0f ), - idVec3( -1.0f, -1.0f, 0.0f ), - idVec3( 1.0f, -1.0f, 0.0f ) - }; - - if ( !g_decals.GetBool() ) { - return; - } - - // randomly rotate the decal winding - idMath::SinCos16( ( angle ) ? angle : random.RandomFloat() * idMath::TWO_PI, s, c ); - - // winding orientation - axis[2] = dir; - axis[2].Normalize(); - axis[2].NormalVectors( axistemp[0], axistemp[1] ); - axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; - axis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; - - windingOrigin = origin + depth * axis[2]; - if ( parallel ) { - projectionOrigin = origin - depth * axis[2]; - } else { - projectionOrigin = origin; - } - - size *= 0.5f; - - winding.Clear(); - winding += idVec5( windingOrigin + ( axis * decalWinding[0] ) * size, idVec2( 1, 1 ) ); - winding += idVec5( windingOrigin + ( axis * decalWinding[1] ) * size, idVec2( 0, 1 ) ); - winding += idVec5( windingOrigin + ( axis * decalWinding[2] ) * size, idVec2( 0, 0 ) ); - winding += idVec5( windingOrigin + ( axis * decalWinding[3] ) * size, idVec2( 1, 0 ) ); - gameRenderWorld->ProjectDecalOntoWorld( winding, projectionOrigin, parallel, depth * 0.5f, declManager->FindMaterial( material ), time ); -} - -/* -============== -idGameLocal::BloodSplat -============== -*/ -void idGameLocal::BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) { - float halfSize = size * 0.5f; - idVec3 verts[] = { idVec3( 0.0f, +halfSize, +halfSize ), - idVec3( 0.0f, +halfSize, -halfSize ), - idVec3( 0.0f, -halfSize, -halfSize ), - idVec3( 0.0f, -halfSize, +halfSize ) }; - idTraceModel trm; - idClipModel mdl; - trace_t results; - - // FIXME: get from damage def - if ( !g_bloodEffects.GetBool() ) { - return; - } - - size = halfSize + random.RandomFloat() * halfSize; - trm.SetupPolygon( verts, 4 ); - mdl.LoadModel( trm ); - clip.Translation( results, origin, origin + dir * 64.0f, &mdl, mat3_identity, CONTENTS_SOLID, NULL ); - ProjectDecal( results.endpos, dir, 2.0f * size, true, size, material ); -} - -/* -============= -idGameLocal::SetCamera -============= -*/ -void idGameLocal::SetCamera( idCamera *cam ) { - int i; - idEntity *ent; - idAI *ai; - - // this should fix going into a cinematic when dead.. rare but happens - idPlayer *client = GetLocalPlayer(); - if ( client->health <= 0 || client->AI_DEAD ) { - return; - } - - camera = cam; - if ( camera ) { - inCinematic = true; - - if ( skipCinematic && camera->spawnArgs.GetBool( "disconnect" ) ) { - camera->spawnArgs.SetBool( "disconnect", false ); - cvarSystem->SetCVarFloat( "r_znear", 3.0f ); - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); - skipCinematic = false; - return; - } - - if ( time > cinematicStopTime ) { - cinematicSkipTime = time + CINEMATIC_SKIP_DELAY; - } - - // set r_znear so that transitioning into/out of the player's head doesn't clip through the view - cvarSystem->SetCVarFloat( "r_znear", 1.0f ); - - // hide all the player models - for( i = 0; i < numClients; i++ ) { - if ( entities[ i ] ) { - client = static_cast< idPlayer* >( entities[ i ] ); - client->EnterCinematic(); - } - } - - if ( !cam->spawnArgs.GetBool( "ignore_enemies" ) ) { - // kill any active monsters that are enemies of the player - for ( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->cinematic || ent->fl.isDormant ) { - // only kill entities that aren't needed for cinematics and aren't dormant - continue; - } - - if ( ent->IsType( idAI::Type ) ) { - ai = static_cast( ent ); - if ( !ai->GetEnemy() || !ai->IsActive() ) { - // no enemy, or inactive, so probably safe to ignore - continue; - } - } else if ( ent->IsType( idProjectile::Type ) ) { - // remove all projectiles - } else if ( ent->spawnArgs.GetBool( "cinematic_remove" ) ) { - // remove anything marked to be removed during cinematics - } else { - // ignore everything else - continue; - } - - // remove it - DPrintf( "removing '%s' for cinematic\n", ent->GetName() ); - ent->PostEventMS( &EV_Remove, 0 ); - } - } - - } else { - inCinematic = false; - cinematicStopTime = time + msec; - - // restore r_znear - cvarSystem->SetCVarFloat( "r_znear", 3.0f ); - - // show all the player models - for( i = 0; i < numClients; i++ ) { - if ( entities[ i ] ) { - idPlayer *client = static_cast< idPlayer* >( entities[ i ] ); - client->ExitCinematic(); - } - } - } -} - -/* -============= -idGameLocal::GetCamera -============= -*/ -idCamera *idGameLocal::GetCamera( void ) const { - return camera; -} - -/* -============= -idGameLocal::SkipCinematic -============= -*/ -bool idGameLocal::SkipCinematic( void ) { - if ( camera ) { - if ( camera->spawnArgs.GetBool( "disconnect" ) ) { - camera->spawnArgs.SetBool( "disconnect", false ); - cvarSystem->SetCVarFloat( "r_znear", 3.0f ); - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); - skipCinematic = false; - return false; - } - - if ( camera->spawnArgs.GetBool( "instantSkip" ) ) { - camera->Stop(); - return false; - } - } - - soundSystem->SetMute( true ); - if ( !skipCinematic ) { - skipCinematic = true; - cinematicMaxSkipTime = gameLocal.time + SEC2MS( g_cinematicMaxSkipTime.GetFloat() ); - } - - return true; -} - - -/* -====================== -idGameLocal::SpreadLocations - -Now that everything has been spawned, associate areas with location entities -====================== -*/ -void idGameLocal::SpreadLocations() { - idEntity *ent; - - // allocate the area table - int numAreas = gameRenderWorld->NumAreas(); - locationEntities = new idLocationEntity *[ numAreas ]; - memset( locationEntities, 0, numAreas * sizeof( *locationEntities ) ); - - // for each location entity, make pointers from every area it touches - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( !ent->IsType( idLocationEntity::Type ) ) { - continue; - } - idVec3 point = ent->spawnArgs.GetVector( "origin" ); - int areaNum = gameRenderWorld->PointInArea( point ); - if ( areaNum < 0 ) { - Printf( "SpreadLocations: location '%s' is not in a valid area\n", ent->spawnArgs.GetString( "name" ) ); - continue; - } - if ( areaNum >= numAreas ) { - Error( "idGameLocal::SpreadLocations: areaNum >= gameRenderWorld->NumAreas()" ); - } - if ( locationEntities[areaNum] ) { - Warning( "location entity '%s' overlaps '%s'", ent->spawnArgs.GetString( "name" ), - locationEntities[areaNum]->spawnArgs.GetString( "name" ) ); - continue; - } - locationEntities[areaNum] = static_cast(ent); - - // spread to all other connected areas - for ( int i = 0 ; i < numAreas ; i++ ) { - if ( i == areaNum ) { - continue; - } - if ( gameRenderWorld->AreasAreConnected( areaNum, i, PS_BLOCK_LOCATION ) ) { - locationEntities[i] = static_cast(ent); - } - } - } -} - -/* -=================== -idGameLocal::LocationForPoint - -The player checks the location each frame to update the HUD text display -May return NULL -=================== -*/ -idLocationEntity *idGameLocal::LocationForPoint( const idVec3 &point ) { - if ( !locationEntities ) { - // before SpreadLocations() has been called - return NULL; - } - - int areaNum = gameRenderWorld->PointInArea( point ); - if ( areaNum < 0 ) { - return NULL; - } - if ( areaNum >= gameRenderWorld->NumAreas() ) { - Error( "idGameLocal::LocationForPoint: areaNum >= gameRenderWorld->NumAreas()" ); - } - - return locationEntities[ areaNum ]; -} - -/* -============ -idGameLocal::SetPortalState -============ -*/ -void idGameLocal::SetPortalState( qhandle_t portal, int blockingBits ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - if ( !gameLocal.isClient ) { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_PORTAL ); - outMsg.WriteLong( portal ); - outMsg.WriteBits( blockingBits, NUM_RENDER_PORTAL_BITS ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - } - gameRenderWorld->SetPortalState( portal, blockingBits ); -} - -/* -============ -idGameLocal::sortSpawnPoints -============ -*/ -int idGameLocal::sortSpawnPoints( const void *ptr1, const void *ptr2 ) { - const spawnSpot_t *spot1 = static_cast( ptr1 ); - const spawnSpot_t *spot2 = static_cast( ptr2 ); - float diff; - - diff = spot1->dist - spot2->dist; - if ( diff < 0.0f ) { - return 1; - } else if ( diff > 0.0f ) { - return -1; - } else { - return 0; - } -} - -/* -=========== -idGameLocal::RandomizeInitialSpawns -randomize the order of the initial spawns -prepare for a sequence of initial player spawns -============ -*/ -void idGameLocal::RandomizeInitialSpawns( void ) { - spawnSpot_t spot; - int i, j; - idEntity *ent; - - if ( !isMultiplayer || isClient ) { - return; - } - spawnSpots.Clear(); - initialSpots.Clear(); - spot.dist = 0; - spot.ent = FindEntityUsingDef( NULL, "info_player_deathmatch" ); - while( spot.ent ) { - spawnSpots.Append( spot ); - if ( spot.ent->spawnArgs.GetBool( "initial" ) ) { - initialSpots.Append( spot.ent ); - } - spot.ent = FindEntityUsingDef( spot.ent, "info_player_deathmatch" ); - } - if ( !spawnSpots.Num() ) { - common->Warning( "no info_player_deathmatch in map" ); - return; - } - common->Printf( "%d spawns (%d initials)\n", spawnSpots.Num(), initialSpots.Num() ); - // if there are no initial spots in the map, consider they can all be used as initial - if ( !initialSpots.Num() ) { - common->Warning( "no info_player_deathmatch entities marked initial in map" ); - for ( i = 0; i < spawnSpots.Num(); i++ ) { - initialSpots.Append( spawnSpots[ i ].ent ); - } - } - for ( i = 0; i < initialSpots.Num(); i++ ) { - j = random.RandomInt( initialSpots.Num() ); - ent = initialSpots[ i ]; - initialSpots[ i ] = initialSpots[ j ]; - initialSpots[ j ] = ent; - } - // reset the counter - currentInitialSpot = 0; -} - -/* -=========== -idGameLocal::SelectInitialSpawnPoint -spectators are spawned randomly anywhere -in-game clients are spawned based on distance to active players (randomized on the first half) -upon map restart, initial spawns are used (randomized ordered list of spawns flagged "initial") - if there are more players than initial spots, overflow to regular spawning -============ -*/ -idEntity *idGameLocal::SelectInitialSpawnPoint( idPlayer *player ) { - int i, j, which; - spawnSpot_t spot; - idVec3 pos; - float dist; - bool alone; - - if ( !isMultiplayer || !spawnSpots.Num() ) { - spot.ent = FindEntityUsingDef( NULL, "info_player_start" ); - if ( !spot.ent ) { - Error( "No info_player_start on map.\n" ); - } - return spot.ent; - } - if ( player->spectating ) { - // plain random spot, don't bother - return spawnSpots[ random.RandomInt( spawnSpots.Num() ) ].ent; - } else if ( player->useInitialSpawns && currentInitialSpot < initialSpots.Num() ) { - return initialSpots[ currentInitialSpot++ ]; - } else { - // check if we are alone in map - alone = true; - for ( j = 0; j < MAX_CLIENTS; j++ ) { - if ( entities[ j ] && entities[ j ] != player ) { - alone = false; - break; - } - } - if ( alone ) { - // don't do distance-based - return spawnSpots[ random.RandomInt( spawnSpots.Num() ) ].ent; - } - - // find the distance to the closest active player for each spawn spot - for( i = 0; i < spawnSpots.Num(); i++ ) { - pos = spawnSpots[ i ].ent->GetPhysics()->GetOrigin(); - spawnSpots[ i ].dist = 0x7fffffff; - for( j = 0; j < MAX_CLIENTS; j++ ) { - if ( !entities[ j ] || !entities[ j ]->IsType( idPlayer::Type ) - || entities[ j ] == player - || static_cast< idPlayer * >( entities[ j ] )->spectating ) { - continue; - } - - dist = ( pos - entities[ j ]->GetPhysics()->GetOrigin() ).LengthSqr(); - if ( dist < spawnSpots[ i ].dist ) { - spawnSpots[ i ].dist = int(dist); - } - } - } - - // sort the list - qsort( ( void * )spawnSpots.Ptr(), spawnSpots.Num(), sizeof( spawnSpot_t ), ( int (*)(const void *, const void *) )sortSpawnPoints ); - - // choose a random one in the top half - which = random.RandomInt( spawnSpots.Num() / 2 ); - spot = spawnSpots[ which ]; - } - return spot.ent; -} - -/* -================ -idGameLocal::UpdateServerInfoFlags -================ -*/ -void idGameLocal::UpdateServerInfoFlags() { - gameType = GAME_SP; - if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "deathmatch" ) == 0 ) ) { - gameType = GAME_DM; - } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Tourney" ) == 0 ) ) { - gameType = GAME_TOURNEY; - } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Team DM" ) == 0 ) ) { - gameType = GAME_TDM; - } else if ( ( idStr::Icmp( serverInfo.GetString( "si_gameType" ), "Last Man" ) == 0 ) ) { - gameType = GAME_LASTMAN; - } - if ( gameType == GAME_LASTMAN ) { - if ( !serverInfo.GetInt( "si_warmup" ) ) { - common->Warning( "Last Man Standing - forcing warmup on" ); - serverInfo.SetInt( "si_warmup", 1 ); - } - if ( serverInfo.GetInt( "si_fraglimit" ) <= 0 ) { - common->Warning( "Last Man Standing - setting fraglimit 1" ); - serverInfo.SetInt( "si_fraglimit", 1 ); - } - } -} - - -/* -================ -idGameLocal::SetGlobalMaterial -================ -*/ -void idGameLocal::SetGlobalMaterial( const idMaterial *mat ) { - globalMaterial = mat; -} - -/* -================ -idGameLocal::GetGlobalMaterial -================ -*/ -const idMaterial *idGameLocal::GetGlobalMaterial() { - return globalMaterial; -} - -/* -================ -idGameLocal::GetSpawnId -================ -*/ -int idGameLocal::GetSpawnId( const idEntity* ent ) const { - return ( gameLocal.spawnIds[ ent->entityNumber ] << GENTITYNUM_BITS ) | ent->entityNumber; -} - -/* -================ -idGameLocal::ThrottleUserInfo -================ -*/ -void idGameLocal::ThrottleUserInfo( void ) { - mpGame.ThrottleUserInfo(); -} - -/* - -================= - -idPlayer::SetPortalSkyEnt - -================= - -*/ - -void idGameLocal::SetPortalSkyEnt( idEntity *ent ) { - portalSkyEnt = ent; -} - - - -/* -================= -idPlayer::IsPortalSkyAcive -================= -*/ -bool idGameLocal::IsPortalSkyAcive() { - return portalSkyActive; -} - - - -/* -=========== -idGameLocal::SelectTimeGroup -============ -*/ - -void idGameLocal::SelectTimeGroup( int timeGroup ) { } - - - -/* -=========== -idGameLocal::GetTimeGroupTime -============ -*/ -int idGameLocal::GetTimeGroupTime( int timeGroup ) { - return gameLocal.time; -} - - - -/* -=========== -idGameLocal::GetBestGameType -============ -*/ -void idGameLocal::GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ) { - strncpy( buf, gametype, MAX_STRING_CHARS ); - buf[ MAX_STRING_CHARS - 1 ] = '\0'; -} - -/* -=========== -idGameLocal::NeedRestart -============ -*/ -bool idGameLocal::NeedRestart() { - idDict newInfo; - const idKeyValue *keyval, *keyval2; - - newInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); - - for ( int i = 0; i < newInfo.GetNumKeyVals(); i++ ) { - keyval = newInfo.GetKeyVal( i ); - keyval2 = serverInfo.FindKey( keyval->GetKey() ); - if ( !keyval2 ) { - return true; - } - - // a select set of si_ changes will cause a full restart of the server - if ( keyval->GetValue().Cmp( keyval2->GetValue() ) && ( !keyval->GetKey().Cmp( "si_pure" ) || !keyval->GetKey().Cmp( "si_map" ) ) ) { - return true; - } - } - return false; -} - - - -/* -================ -idGameLocal::GetClientStats -================ -*/ - -void idGameLocal::GetClientStats( int clientNum, char *data, const int len ) { - - mpGame.PlayerStats( clientNum, data, len ); -} - -void idGameLocal::SwitchTeam( int clientNum, int team ) -{ - idPlayer * player; - - player = clientNum >= 0 ? static_cast( gameLocal.entities[ clientNum ] ) : NULL; - if ( !player ) - return; - int oldTeam = player->team; - - // Put in spectator mode - if ( team == -1 ) { - static_cast< idPlayer * >( entities[ clientNum ] )->Spectate( true ); - } - - // Switch to a team - else { - mpGame.SwitchToTeam ( clientNum, oldTeam, team ); - } -} - -void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) -{ -} - -void idGameLocal::LoadLightMaterial(const char *pFN, idList *ml) -{ - idToken token; - idLexer src; - idStr Material, FallOff, Map, *add; - int level; // Nestinglevel for brackets - bool bAmbient; - CLightMaterial *mat; - - if(pFN == NULL || ml == NULL) - goto Quit; - - src.LoadFile(pFN); - - level = 0; - add = NULL; - bAmbient = false; - - while(1) - { - if(!src.ReadToken(&token)) - goto Quit; - -// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Token: [%s]\r", token.c_str()); - - if(token == "table") - { - src.SkipBracedSection(true); - continue; - } - - if(token == "lights") - { - Material = token; - while(src.ReadTokenOnLine(&token) == true) - { - Material += token; -// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Material: [%s]\r", token.c_str()); - } - - continue; - } - else if(level == 1 && token == "ambientLight") - { - bAmbient = true; - continue; - } - else if(token == "{") - { - level++; - if(level == 1) - bAmbient = false; - - continue; - } - else if(token == "}") - { - level--; - if(level == 0) - { - if(FallOff.Length() == 0 && Map.Length() == 0) - continue; - - mat = new CLightMaterial(Material, FallOff, Map); - mat->m_AmbientLight = bAmbient; - ml->Append(mat); - DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("Texture: [%s] - [%s]/[%s] - Ambient: %u\r", Material.c_str(), FallOff.c_str(), Map.c_str(), bAmbient); - } - continue; - } - else if(token == "map") - { - Map = ""; - while(src.ReadTokenOnLine(&token) == true) - { - if(token == "makeintensity") - continue; - else if(token == "(") - continue; - else if(token == ")") - break; - else - Map += token; -// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Map: [%s]\r", token.c_str()); - } - continue; - } - else if(token == "lightFalloffImage") - { - FallOff = ""; - - while(1) - { - if(!src.ReadToken(&token)) - { - DM_LOG(LC_SYSTEM, LT_ERROR)LOGSTRING("Invalid material file structure on line %u\r", src.GetLineNum()); - goto Quit; - } - - // Ignore makeintensity tag - if(token == "makeintensity") - continue; - else if(token == "(") - continue; - else if(token == ")") - break; - else - { - do - { - if(token == ")") - break; - - FallOff += token; -// DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("FallOff: [%s]\r", token.c_str()); - } - while(src.ReadTokenOnLine(&token) == true); - break; - } - } - continue; - } - } - -Quit: - return; -} - -int idGameLocal::CheckStimResponse(idList< idEntityPtr > &list, idEntity *e) -{ - // Construct an idEntityPtr with the given entity - idEntityPtr entPtr; - entPtr = e; - - return list.FindIndex(entPtr); -} - -void idGameLocal::LinkStimEntity(idEntity* ent) -{ - if (ent != NULL && ent->GetStimResponseCollection()->HasStim()) - { - AddStim(ent); - } -} - -void idGameLocal::UnlinkStimEntity(idEntity* ent) -{ - RemoveStim(ent); -} - -bool idGameLocal::AddStim(idEntity *e) -{ - bool rc = true; - - if (CheckStimResponse(m_StimEntity, e) == -1) - { - idEntityPtr entPtr; - entPtr = e; - m_StimEntity.Append(entPtr); - } - - return rc; -} - -void idGameLocal::RemoveStim(idEntity *e) -{ - int i = CheckStimResponse(m_StimEntity, e); - - if (i != -1) - { - m_StimEntity.RemoveIndex(i); - } -} - -bool idGameLocal::AddResponse(idEntity *e) -{ - bool rc = true; - - if(CheckStimResponse(m_RespEntity, e) == -1) - { - idEntityPtr entPtr; - entPtr = e; - m_RespEntity.Append(entPtr); - } - - return rc; -} - - -void idGameLocal::RemoveResponse(idEntity *e) -{ - int i = CheckStimResponse(m_RespEntity, e); - - if (i != -1) - { - m_RespEntity.RemoveIndex(i); - } -} - -int idGameLocal::DoResponseAction(const CStimPtr& stim, int numEntities, idEntity* originator, const idVec3& stimOrigin) -{ - int numResponses = 0; - for (int i = 0; i < numEntities; i++) - { - // ignore the original entity because an entity shouldn't respond - // to its own stims. - if (srEntities[i] == originator || srEntities[i]->GetResponseEntity() == originator) - continue; - - // Check if the radius is really fitting. EntitiesTouchingBounds is using a rectangular volume - // greebo: Be sure to use this check only if "use bounds" is set to false - if (!stim->m_bCollisionBased && !stim->m_bUseEntBounds) - { - // take the square radius, is faster - float radiusSqr = stim->GetRadius(); - radiusSqr *= radiusSqr; - - // grayman #2468 - handle AI with no separate head entities - - idEntity *ent = srEntities[i]; - idVec3 entitySpot = ent->GetPhysics()->GetOrigin(); - - if (stim->m_StimTypeId == ST_GAS) // grayman #2721 - only need the mouth location if this is a gas stim - { - if (!ent->IsType(idAFAttachment::Type)) // is this an attached head? - { - // no separate head entity, so find the mouth - - if (ent->IsType(idAI::Type)) - { - idAI* entAI = static_cast(ent); - - entitySpot = entAI->GetEyePosition(); - entitySpot.z += entAI->m_MouthOffset.z; - } - } - } - - if ((entitySpot - stimOrigin).LengthSqr() > radiusSqr) - { - // Too far away - continue; - } - } - - // Check for a shooter entity, these don't need to have a response - if (srEntities[i]->IsType(tdmFuncShooter::Type)) - { - static_cast(srEntities[i])->stimulate(static_cast(stim->m_StimTypeId)); - } - - CResponsePtr response = srEntities[i]->GetStimResponseCollection()->GetResponseByType(stim->m_StimTypeId); - - if (response != NULL) - { - if (response->m_State == SS_ENABLED && stim->CheckResponseIgnore(srEntities[i]) == false) - { - // Check duration, disable if past duration - if (response->m_Duration && (gameLocal.time - response->m_EnabledTimeStamp) > response->m_Duration ) - { - response->Disable(); - continue; - } - - if (cv_sr_show.GetInteger() > 0) - { - // Show successful S/R - gameRenderWorld->DebugArrow(colorGreen, stimOrigin, srEntities[i]->GetPhysics()->GetOrigin(), 1, 4 * gameLocal.msec); - } - - // Fire the response and pass the originating entity plus the stim object itself - // The stim object can be queried for values like magnitude, falloff and such. - response->TriggerResponse(originator, stim); - numResponses++; - } - } - } - - // Return number of responses triggered - return numResponses; -} - -void idGameLocal::ProcessTimer(unsigned long ticks) -{ - int i, n; - CStimResponseTimer *t; - - n = m_Timer.Num(); - for(i = 0; i < n; i++) - { - t = m_Timer[i]; - - // We just let the timers tick. Querying them must be done by the respective owner, - // because we can not know from where it was called, and it doesn't make sense - // to use a callback, because the timer user still has to wait until it is expired. - // So the owner has to check it from time to time anyway. - if(t->GetState() == CStimResponseTimer::SRTS_RUNNING) - { - t = m_Timer[i]; - t->Tick(ticks); - } - } -} - -CStimResponsePtr idGameLocal::FindStimResponse(int uniqueId) -{ - for (idEntity* ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - if (ent->GetStimResponseCollection() != NULL) - { - CStimResponsePtr candidate = ent->GetStimResponseCollection()->FindStimResponse(uniqueId); - - if (candidate != NULL) - { - // We found the stim/response, return it - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("StimResponse with Id %d found.\r", uniqueId); - return candidate; - } - } - } - - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("Warning: StimResponse with Id %d NOT found.\r", uniqueId); - - // Search did not produce any results - return CStimResponsePtr(); -} - -void idGameLocal::ProcessStimResponse(unsigned long ticks) -{ - if (cv_sr_disable.GetBool()) - { - return; // S/R disabled, skip this - } - - idTimer srTimer; - srTimer.Clear(); - srTimer.Start(); - - // Check the timed stims first. - for (int i = 0; i < m_StimTimer.Num(); i++) - { - CStim* stim = m_StimTimer[i]; - - if (stim == NULL) continue; - - // Only advance the timer if the stim can be fired in the first place - if (stim->m_MaxFireCount > 0 || stim->m_MaxFireCount == -1) - { - // Advance the timer - CStimResponseTimer* timer = stim->GetTimer(); - - if (timer->GetState() == CStimResponseTimer::SRTS_RUNNING) - { - if (timer->Tick(ticks)) - { - //gameLocal.Printf("Stim timer elapsed! ProcessStimResponse - firing stim\n"); - // Enable the stim when the timer has expired - - stim->Enable(); - } - } - } - } - - int n; - idBounds bounds; - - // Now check the rest of the stims. - for (int i = 0; i < m_StimEntity.Num(); i++) - { - idEntity* entity = m_StimEntity[i].GetEntity(); - - if (entity == NULL) continue; - - // greebo: Get the S/R collection, this is always non-NULL - CStimResponseCollection* srColl = entity->GetStimResponseCollection(); - assert(srColl != NULL); - - idVec3 origin(entity->GetPhysics()->GetOrigin()); - - int numStims = srColl->GetNumStims(); - - // Traverse through all the stims on this entity - for (int stimIdx = 0; stimIdx < numStims; ++stimIdx) - { - const CStimPtr& stim = srColl->GetStim(stimIdx); - - if (stim->m_MaxFireCount == 0) - // Maximum number of firings reached, do not process this stim - continue; - - if (stim->m_State != SS_ENABLED) - continue; // Stim is not enabled - - if (stim->m_bCollisionBased && !stim->m_bCollisionFired) - continue; // Collision-based stim that did not fire with ::Collide this frame - - // Check the interleaving timer and don't eval stim if it's not up yet - if (gameLocal.time - stim->m_TimeInterleaveStamp < stim->m_TimeInterleave) - continue; - - // If stim has a finite duration, check if it expired. If so, disable the stim. - if (stim->m_Duration != 0 && (gameLocal.time - stim->m_EnabledTimeStamp) > stim->m_Duration ) - { - stim->Disable(); - continue; - } - - // Initial checks passed, decrease the fire count - if (stim->m_MaxFireCount > 0) - { - stim->m_MaxFireCount--; - } - - // Check if a stim velocity has been specified - if (stim->m_Velocity != idVec3(0,0,0)) { - // The velocity mutliplied by the time gives the translation - // Updates the location of this stim relative to the time it last fired. - origin += stim->m_Velocity * (gameLocal.time - stim->m_EnabledTimeStamp)/1000; - } - - // Save the current timestamp into the stim, so that we know when it was last fired - stim->m_TimeInterleaveStamp = gameLocal.time; - - // greebo: Check if the stim passes the "chance" test - // Do this AFTER the m_TimeInterleaveStamp has been set to avoid the stim - // from being re-evaluated in the very next frame in case it failed the test. - if (!stim->CheckChance()) - { - continue; - } - - // If stim is not disabled - if (stim->m_State == SS_DISABLED) - continue; - - float radius = stim->GetRadius(); - - if (radius != 0.0 || stim->m_bCollisionBased || - stim->m_bUseEntBounds || stim->m_Bounds.GetVolume() > 0) - { - int numResponses = 0; - - // Check if we have fixed bounds to work with (sr_bounds_mins & maxs set) - if (stim->m_Bounds.GetVolume() > 0) { - bounds = idBounds(stim->m_Bounds[0] + origin, stim->m_Bounds[1] + origin); - } - else { - // No bounds set, check for radius and useBounds - - // Find entities in the radius of the stim - if (stim->m_bUseEntBounds ) - { - bounds = entity->GetPhysics()->GetAbsBounds(); - } - else - { - bounds = idBounds(origin); - } - - bounds.ExpandSelf(radius); - } - - // Collision-based stims - if (stim->m_bCollisionBased) - { - n = stim->m_CollisionEnts.Num(); - - for (int n2 = 0; n2 < n; n2++) - { - srEntities[n2] = stim->m_CollisionEnts[n2]; - } - - // clear the collision vars for the next frame - stim->m_bCollisionFired = false; - stim->m_CollisionEnts.Clear(); - } - else - { - // Radius based stims - n = clip.EntitiesTouchingBounds(bounds, CONTENTS_RESPONSE, srEntities, MAX_GENTITIES); - //DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Entities touching bounds: %d\r", n); - } - - if (n > 0) - { - if (cv_sr_show.GetInteger() > 1) - { - for (int n2 = 0; n2 < n; ++n2) - { - // Show failed S/R - gameRenderWorld->DebugArrow(colorRed, bounds.GetCenter(), srEntities[n2]->GetPhysics()->GetOrigin(), 1, 4 * gameLocal.msec); - } - } - - // Do responses for entities within the radius of the stim - numResponses = DoResponseAction(stim, n, entity, origin); - } - - // The stim has fired, let it do any post-firing activity it may have - stim->PostFired(numResponses); - } - } - } - - srTimer.Stop(); - DM_LOG(LC_STIM_RESPONSE, LT_INFO)LOGSTRING("Processing S/R took %lf\r", srTimer.Milliseconds()); -} - -/* -=================== -Dark Mod: -idGameLocal::LocationForArea -=================== -*/ -idLocationEntity *idGameLocal::LocationForArea( const int areaNum ) -{ - idLocationEntity *pReturnval( NULL ); - - if ( !locationEntities || areaNum < 0 || areaNum >= gameRenderWorld->NumAreas() ) - { - pReturnval = NULL; - goto Quit; - } - - pReturnval = locationEntities[ areaNum ]; - -Quit: - return pReturnval; -} - -/* -=================== -Dark Mod: -idGameLocal::PlayerTraceEntity -=================== -*/ -idEntity *idGameLocal::PlayerTraceEntity( void ) -{ - idVec3 start, end; - idEntity *returnEnt = NULL; - idPlayer *player = NULL; - trace_t trace; - int cm = 0; - - player = gameLocal.GetLocalPlayer(); - if( ! player ) - goto Quit; - - start = player->GetEyePosition(); - // do a trace 512 doom units ahead - end = start + 512.0f * (player->viewAngles.ToForward()); - - cm = CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_TRIGGER; - gameLocal.clip.TracePoint( trace, start, end, cm, player ); - if( trace.fraction < 1.0f ) - { - returnEnt = gameLocal.entities[ trace.c.entityNum ]; - // don't return the world - if( returnEnt == gameLocal.world ) - returnEnt = NULL; - } - -Quit: - return returnEnt; -} - -void idGameLocal::PauseGame( bool bPauseState ) -{ - if( bPauseState ) - { - gameSoundWorldBuf = soundSystem->GetPlayingSoundWorld(); - gameSoundWorldBuf->Pause(); - soundSystem->SetPlayingSoundWorld( NULL ); - - g_stopTime.SetBool( true ); - } - else - { - soundSystem->SetPlayingSoundWorld( gameSoundWorldBuf ); - soundSystem->GetPlayingSoundWorld()->UnPause(); - - g_stopTime.SetBool( false ); - } -} - -void idGameLocal::SetMissionResult(EMissionResult result) -{ - m_MissionResult = result; -} - -EMissionResult idGameLocal::GetMissionResult() const -{ - return m_MissionResult; -} - -float idGameLocal::CalcLightgem( idPlayer *a_pPlayer ) -{ - return m_lightGem.Calculate( a_pPlayer ); -} -/* -=================== -Dark Mod: -idGameLocal::FindMainAmbientLight -Author: J.C.Denton -Usage: Finds main ambient light by the name "ambient_world". - If it can't be found, finds ambient light with largest radius and rename it to ambient_world before returning pointer to it. -=================== -*/ - -idLight * idGameLocal::FindMainAmbientLight( bool a_bCreateNewIfNotFound /*= false */ ) -{ - int hash, i; - idEntity *pEntMainAmbientLight = NULL; - - hash = entityHash.GenerateKey( m_strMainAmbientLightName, true ); - for ( i = entityHash.First( hash ); i != -1; i = entityHash.Next( i ) ) { - if ( entities[i] && entities[i]->name.Icmp( m_strMainAmbientLightName ) == 0 ) { - pEntMainAmbientLight = entities[i]; - break; - } - } - - if ( NULL != pEntMainAmbientLight && pEntMainAmbientLight->IsType(idLight::Type) ) - return static_cast( pEntMainAmbientLight ); - else if( !a_bCreateNewIfNotFound ) - return NULL; - - gameLocal.Printf( "Ambient light by name of 'ambient_world' not found, attempting to create a new one. \n"); - - idLight *pLightEntMainAmbient = NULL; - float fMaxRadius = 0.0f; - int j=1; - for (int i = 0; i < MAX_GENTITIES; i++) - { - // Find the ambient light with greatest radius. - if( NULL != entities[i] && entities[i]->IsType(idLight::Type) ) - { - idVec3 vec3LightRadius; - idLight *pLight = static_cast( entities[i] ); -// gameLocal.Printf( "Light found %i \n", j++ ); - - if (!pLight->IsAmbient()) - continue; - - pLight->GetRadius( vec3LightRadius ); - - float fRadius = vec3LightRadius.Length(); - //gameLocal.Printf( "The Light is ambient, max radius: %f current radius: %f \n", fMaxRadius, fRadius ); - - if( fRadius > fMaxRadius ) - { - fMaxRadius = fRadius; - pLightEntMainAmbient = pLight; - } - } - } - - if( pLightEntMainAmbient ) - { - m_strMainAmbientLightName = pLightEntMainAmbient->GetName(); - gameLocal.Printf( "Found light %s and now is set as the main ambient light. \n", m_strMainAmbientLightName.c_str() ); - } - - return pLightEntMainAmbient; - -} - -#ifdef WIN32 -namespace -{ - // greebo: This little snippet is changing the window title to something more appropriate. - BOOL CALLBACK ChangeD3WindowTitle(HWND hwnd,LPARAM lParam) - { - // Find the window of our process - DWORD procId; - if (GetWindowThreadProcessId(hwnd, &procId) && procId == GetCurrentProcessId()) - { - if (!GetWindow(hwnd, GW_OWNER)) - { - char title[256]; - GetWindowText(hwnd, title, 255); - - if (std::string(title) == "DOOM 3") - { - std::string newTitle = va("%s %d.%02d", GAME_VERSION, TDM_VERSION_MAJOR, TDM_VERSION_MINOR); - SetWindowText(hwnd, newTitle.c_str()); - - fs::path darkmodPath = g_Global.GetDarkmodPath(); - darkmodPath /= "darkmod.ico"; - - HICON hIcon = (HICON)LoadImage(NULL, darkmodPath.file_string().c_str(), IMAGE_ICON, 32, 32, LR_LOADFROMFILE); - - if (hIcon) - { - SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); - } - - return false; - } - } - } - - return true; - } -} -#endif - -void idGameLocal::ChangeWindowTitleAndIcon() -{ -#ifdef WIN32 - EnumWindows((WNDENUMPROC)ChangeD3WindowTitle, 0); -#endif -} - -void idGameLocal::ClearPersistentInfo() -{ - persistentPlayerInventory->Clear(); - persistentLevelInfo.Clear(); - m_CampaignStats.reset(new CampaignStats); - m_InterMissionTriggers.Clear(); -} - -void idGameLocal::ProcessInterMissionTriggers() -{ - for (int i = 0; i < m_InterMissionTriggers.Num(); ++i) - { - const InterMissionTrigger& trigger = m_InterMissionTriggers[i]; - - if (trigger.missionNum == m_MissionManager->GetCurrentMissionIndex()) - { - idEntity* target = FindEntity(trigger.targetName); - idEntity* activator = !trigger.activatorName.IsEmpty() ? FindEntity(trigger.activatorName) : GetLocalPlayer(); - - if (target != NULL) - { - target->Activate(activator); - } - else - { - gameLocal.Warning("Cannot find intermission trigger target entity %s", trigger.targetName.c_str()); - } - - // Don't remove the triggers yet, we might need them again when restarting the map - } - } -} diff --git a/game/game_local.h b/game/game_local.h deleted file mode 100644 index f725c552d..000000000 --- a/game/game_local.h +++ /dev/null @@ -1,1287 +0,0 @@ -/*************************************************************************** - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. - -#ifndef __GAME_LOCAL_H__ -#define __GAME_LOCAL_H__ - -#include "game.h" - -#ifdef __linux__ -#include "framework/usercmdgen.h" -#endif - -#pragma warning(disable : 4996) -/** -* Message pragma so we can show file and line info in comments easily -* Same principle as the one below but simpler to implement and use. -* Been using it for about 8 or 9 years not sure where I found it -* but I did have a subscription to windows developer journal so maybe thats where. -* Usage: #pragma Message( "your message goes here") -* -* Submitted by Thelvyn -* -* Here since I cannot include the globals file here. -*/ -#ifndef MacroStr2 -#define MacroStr(x) #x -#define MacroStr2(x) MacroStr(x) -#define Message(desc) message(__FILE__ "(" MacroStr2(__LINE__) ") :" #desc) -#endif - - -/** - * Global function to keep track of the files and it's version. - */ -bool FileVersionList(const char *str, bool state); - -// enables water physics -#define MOD_WATERPHYSICS - -/* -=============================================================================== - - Local implementation of the public game interface. - -=============================================================================== -*/ - -#define LAGO_IMG_WIDTH 64 -#define LAGO_IMG_HEIGHT 64 -#define LAGO_WIDTH 64 -#define LAGO_HEIGHT 44 -#define LAGO_MATERIAL "textures/sfx/lagometer" -#define LAGO_IMAGE "textures/sfx/lagometer.tga" - -// if set to 1 the server sends the client PVS with snapshots and the client compares against what it sees -#ifndef ASYNC_WRITE_PVS - #define ASYNC_WRITE_PVS 0 -#endif - -#ifdef ID_DEBUG_UNINITIALIZED_MEMORY -// This is real evil but allows the code to inspect arbitrary class variables. -#define private public -#define protected public -#endif - -class idLight; // J.C.Denton: Required for the declaration of FindMainAmbientLight - -class idRenderWorld; -extern idRenderWorld * gameRenderWorld; - -class idSoundWorld; -extern idSoundWorld * gameSoundWorld; -/** -* place to store the sound world pointer when we temporarily set it to NULL -**/ -extern idSoundWorld * gameSoundWorldBuf; - -// the "gameversion" client command will print this plus compile date -#define GAME_VERSION "The Dark Mod" - -// classes used by idGameLocal -class idEntity; -class idActor; -class idPlayer; -class idCamera; -class idWorldspawn; -class idTestModel; -class idAAS; -class idAI; -class idSmokeParticles; -class idEntityFx; -class idTypeInfo; -class idProgram; -class idThread; -class idEditEntities; -class idLocationEntity; - -#define MAX_CLIENTS 32 -#define GENTITYNUM_BITS 13 -#define MAX_GENTITIES (1< - -#ifdef __linux__ -#include "renderer/renderworld.h" -#endif - -//============================================================================ - -class CLightMaterial; -class CsndPropLoader; -class CsndProp; -class CRelations; -typedef boost::shared_ptr CRelationsPtr; -class CMissionData; -typedef boost::shared_ptr CMissionDataPtr; -class CampaignStats; -typedef boost::shared_ptr CampaignStatsPtr; -class CStimResponse; -typedef boost::shared_ptr CStimResponsePtr; -class CStim; -typedef boost::shared_ptr CStimPtr; -class CStimResponseTimer; -class CGrabber; -class CEscapePointManager; -class CMissionManager; -typedef boost::shared_ptr CMissionManagerPtr; -class CHttpConnection; -typedef boost::shared_ptr CHttpConnectionPtr; -class CInventory; -typedef boost::shared_ptr CInventoryPtr; - -class CModMenu; -typedef boost::shared_ptr CModMenuPtr; - -class CModelGenerator; -typedef boost::shared_ptr CModelGeneratorPtr; -class CImageMapManager; -typedef boost::shared_ptr CImageMapManagerPtr; -class CLightController; -typedef boost::shared_ptr CLightControllerPtr; -class CI18N; -typedef boost::shared_ptr CI18NPtr; - -// Forward declare the Conversation System -namespace ai { - class ConversationSystem; - typedef boost::shared_ptr ConversationSystemPtr; -} // namespace - -class CDownloadMenu; -typedef boost::shared_ptr CDownloadMenuPtr; -class CDownloadManager; -typedef boost::shared_ptr CDownloadManagerPtr; - -class CShop; -typedef boost::shared_ptr CShopPtr; - -const int MAX_GAME_MESSAGE_SIZE = 8192; -const int MAX_ENTITY_STATE_SIZE = 512; -const int ENTITY_PVS_SIZE = ((MAX_GENTITIES+31)>>5); -const int NUM_RENDER_PORTAL_BITS = idMath::BitsForInteger( PS_BLOCK_ALL ); - -typedef struct entityState_s { - int entityNumber; - idBitMsg state; - byte stateBuf[MAX_ENTITY_STATE_SIZE]; - struct entityState_s * next; -} entityState_t; - -typedef struct snapshot_s { - int sequence; - entityState_t * firstEntityState; - int pvs[ENTITY_PVS_SIZE]; - struct snapshot_s * next; -} snapshot_t; - -const int MAX_EVENT_PARAM_SIZE = 128; - -typedef struct entityNetEvent_s { - int spawnId; - int event; - int time; - int paramsSize; - byte paramsBuf[MAX_EVENT_PARAM_SIZE]; - struct entityNetEvent_s *next; - struct entityNetEvent_s *prev; -} entityNetEvent_t; - -enum { - GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP, - GAME_RELIABLE_MESSAGE_REMAP_DECL, - GAME_RELIABLE_MESSAGE_SPAWN_PLAYER, - GAME_RELIABLE_MESSAGE_DELETE_ENT, - GAME_RELIABLE_MESSAGE_CHAT, - GAME_RELIABLE_MESSAGE_TCHAT, - GAME_RELIABLE_MESSAGE_SOUND_EVENT, - GAME_RELIABLE_MESSAGE_SOUND_INDEX, - GAME_RELIABLE_MESSAGE_DB, - GAME_RELIABLE_MESSAGE_KILL, - GAME_RELIABLE_MESSAGE_DROPWEAPON, - GAME_RELIABLE_MESSAGE_RESTART, - GAME_RELIABLE_MESSAGE_SERVERINFO, - GAME_RELIABLE_MESSAGE_TOURNEYLINE, - GAME_RELIABLE_MESSAGE_CALLVOTE, - GAME_RELIABLE_MESSAGE_CASTVOTE, - GAME_RELIABLE_MESSAGE_STARTVOTE, - GAME_RELIABLE_MESSAGE_UPDATEVOTE, - GAME_RELIABLE_MESSAGE_PORTALSTATES, - GAME_RELIABLE_MESSAGE_PORTAL, - GAME_RELIABLE_MESSAGE_VCHAT, - GAME_RELIABLE_MESSAGE_STARTSTATE, - GAME_RELIABLE_MESSAGE_MENU, - GAME_RELIABLE_MESSAGE_WARMUPTIME, - GAME_RELIABLE_MESSAGE_EVENT -}; - -typedef enum { - GAMESTATE_UNINITIALIZED, // prior to Init being called - GAMESTATE_NOMAP, // no map loaded - GAMESTATE_STARTUP, // inside InitFromNewMap(). spawning map entities. - GAMESTATE_ACTIVE, // normal gameplay - GAMESTATE_COMPLETED, // greebo: Active during "Mission Complete" (TDM) - GAMESTATE_SHUTDOWN // inside MapShutdown(). clearing memory. -} gameState_t; - -// Message type for user interaction in the main menu -struct GuiMessage -{ - idStr title; - idStr message; - - enum Type - { - MSG_OK, - MSG_YES_NO, - MSG_OK_CANCEL, - }; - - Type type; - - idStr positiveCmd; // which "cmd" to execute on OK / Yes - idStr negativeCmd; // which "cmd" to execute on Cancel / No - idStr okCmd; // which "cmd" to execute on OK (only for MSG_OK) -}; - -typedef struct { - idEntity *ent; - int dist; -} spawnSpot_t; - -/** -* Sound prop. flags are used by many classes (Actor, soundprop, entity, etc) -* Therefore they are global. -* See sound prop doc file for definitions of these flags. -**/ - -typedef struct SSprFlagBits_s -{ - // team alert flags - unsigned int friendly : 1; - unsigned int neutral : 1; - unsigned int enemy : 1; - unsigned int same : 1; - - // propagation flags - unsigned int omni_dir : 1; // omnidirectional - unsigned int unique_loc : 1; // sound comes from a unique location - unsigned int urgent : 1; // urgent (AI tries to respond ASAP) - unsigned int global_vol : 1; // sound has same volume over whole map - unsigned int check_touched : 1; // for non-AI, check who last touched the entity -} SSprFlagBits; - -typedef union USprFlags_s -{ - unsigned int m_field; - SSprFlagBits m_bits; -} USprFlags; - -/** -* Sound propagation parameters: needed for function arguments -**/ - -struct SSprParms -{ - USprFlags flags; - - idStr name; // sound name - float propVol; // propagated volume - - // Apparent direction of the sound, determined by the path point on the portal - idVec3 direction; - // actual origin of the sound, used for some localization simulation - idVec3 origin; - float duration; // duration - int frequency; // int representing the octave of the sound - float bandwidth; // sound bandwidth - - float loudness; // this is set by AI hearing response - float alertFactor; // angua: alert increase is scaled by this factor - float alertMax; // angua: alert increase can not become higher than this - - bool bSameArea; // true if the sound came from same portal area - bool bDetailedPath; // true if detailed path minimization was used to obtain the sound path - int floods; // number of portals the sound travelled thru before it hit the AI - - idEntity* maker; // it turns out the AI needs to know who made the sound to avoid bugs in some cases - idAI* makerAI; // a shorthand of the above. If this is non NULL the entity is an AI. -}; - -//============================================================================ - -class idEventQueue { -public: - typedef enum { - OUTOFORDER_IGNORE, - OUTOFORDER_DROP, - OUTOFORDER_SORT - } outOfOrderBehaviour_t; - - idEventQueue() : start( NULL ), end( NULL ) {} - - entityNetEvent_t * Alloc(); - void Free( entityNetEvent_t *event ); - void Shutdown(); - - void Init(); - void Enqueue( entityNetEvent_t* event, outOfOrderBehaviour_t oooBehaviour ); - entityNetEvent_t * Dequeue( void ); - entityNetEvent_t * RemoveLast( void ); - - entityNetEvent_t * Start( void ) { return start; } - -private: - entityNetEvent_t * start; - entityNetEvent_t * end; - idBlockAlloc eventAllocator; -}; - -//============================================================================ - -template< class type > -class idEntityPtr { -public: - idEntityPtr(); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - idEntityPtr & operator=( type *ent ); - bool operator==(const idEntityPtr& other) const; - - // synchronize entity pointers over the network - int GetSpawnId( void ) const { return spawnId; } - bool SetSpawnId( int id ); - bool UpdateSpawnId( void ); - - bool IsValid( void ) const; - type * GetEntity( void ) const; - int GetEntityNum( void ) const; - -private: - int spawnId; -}; - -// Note: Because lightgem.h uses idEntityPr, the file should be included here or -// idEntityPtr Definition should be moved to lightgem.h. - J.C.Denton - -#include "../DarkMod/lightgem.h" -//============================================================================ - -class idDeclEntityDef; - -class idGameLocal : public idGame { -public: - idDict serverInfo; // all the tunable parameters, like numclients, etc - int numClients; // pulled from serverInfo and verified - idDict userInfo[MAX_CLIENTS]; // client specific settings - usercmd_t usercmds[MAX_CLIENTS]; // client input commands - idDict persistentPlayerInfo[MAX_CLIENTS]; - idEntity * entities[MAX_GENTITIES];// index to entities - int spawnIds[MAX_GENTITIES];// for use in idEntityPtr - - // greebo: For use in Stim/Response system (gets invalidated each frame) - idEntity* srEntities[MAX_GENTITIES]; - - int firstFreeIndex; // first free index in the entities array - int num_entities; // current number <= MAX_GENTITIES - idHashIndex entityHash; // hash table to quickly find entities by name - idWorldspawn * world; // world entity - idLinkList spawnedEntities; // all spawned entities - idLinkList activeEntities; // all thinking entities (idEntity::thinkFlags != 0) - idLinkList spawnedAI; // greebo: all spawned AI - int numEntitiesToDeactivate;// number of entities that became inactive in current frame - bool sortPushers; // true if active lists needs to be reordered to place pushers at the front - bool sortTeamMasters; // true if active lists needs to be reordered to place physics team masters before their slaves - idDict persistentLevelInfo; // contains args that are kept around between levels - - // The inventory class which keeps items safe between maps - CInventoryPtr persistentPlayerInventory; - - // The list of campaign info entities in this map - idList campaignInfoEntities; - - // greebo: Is set to TRUE if the post-mission screen (debriefing or success screen) is currently active. - // (Usually these state variables should be kept in the GUI, but in this case I need it to be accessible - // when the player loads a new map via the console.) - bool postMissionScreenActive; - - // Toggle to keep track whether the GUI state variables have been set up - bool briefingVideoInfoLoaded; - - // Hold information about a single video piece - struct BriefingVideoPart - { - idStr material; // name of the material - int lengthMsec; // length in msecs - }; - - // The list of briefing videos for the current mission - idList briefingVideo; - - // Index into the above list - int curBriefingVideoPart; - - // The list of DE-briefing videos for the current mission - idList debriefingVideo; - - // Index into the above list - int curDebriefingVideoPart; - - bool mainMenuExited; // Solarsplace 19th Nov 2010 - Bug tracker id 0002424 - - // can be used to automatically effect every material in the world that references globalParms - float globalShaderParms[ MAX_GLOBAL_SHADER_PARMS ]; - - idRandom random; // random number generator used throughout the game - - idProgram program; // currently loaded script and data space - idThread * frameCommandThread; - - idClip clip; // collision detection - idPush push; // geometric pushing - idPVS pvs; // potential visible set - - idTestModel * testmodel; // for development testing of models - idEntityFx * testFx; // for development testing of fx - - idStr sessionCommand; // a target_sessionCommand can set this to return something to the session - - idMultiplayerGame mpGame; // handles rules for standard dm - - idSmokeParticles * smokeParticles; // global smoke trails - idEditEntities * editEntities; // in game editing - - // Darkmod's grabber to help with object manipulation - CGrabber* m_Grabber; - - // The object handling the difficulty settings - difficulty::DifficultyManager m_DifficultyManager; - - // The manager for handling AI => Area mappings (needed for AI to remember locked doors, for instance) - ai::AreaManager m_AreaManager; - - // The manager class for all map conversations - ai::ConversationSystemPtr m_ConversationSystem; - - /** - * greebo: The fan-mission-handling class. Also contains GUI handling code. - */ - CModMenuPtr m_ModMenu; - - // The download menu handler - CDownloadMenuPtr m_DownloadMenu; - - // The download manager - CDownloadManagerPtr m_DownloadManager; - - /** - * greebo: The mission manager instance, for manipulating mission PK4s and saving play info. - */ - CMissionManagerPtr m_MissionManager; - - /** - * tels: The model generator instance, for manipulating/generating models on the fly. - */ - CModelGeneratorPtr m_ModelGenerator; - - /** - * tels: The image mapmanager instance, for loading/sharing image maps for the SEED system. - */ - CImageMapManagerPtr m_ImageMapManager; - - /** - * tels: The light controller instance, used to control local ambient lights. - */ - CLightControllerPtr m_LightController; - - /** - * tels: The I18N object (for translation etc.) - */ - CI18NPtr m_I18N; - - /** - * greebo: The class handling the main menu's shop GUI. - */ - CShopPtr m_Shop; - - /** - * This list is some sort of queue of error messages collected by - * gameLocal.Error(). The messages here will be sent - * to the main menu GUI once it is displayed again after the error. - */ - mutable idStr m_guiError; - - mutable idList m_GuiMessages; - - /** - * Pointer to global AI Relations object - **/ - CRelationsPtr m_RelationsManager; - - /** - * Pointer to global Mission Data object (objectives & stats) - **/ - CMissionDataPtr m_MissionData; - EMissionResult m_MissionResult; // holds the global mission state - - // Campaign statistics - CampaignStatsPtr m_CampaignStats; - - /** - * Pointer to global sound prop loader object - **/ - CsndPropLoader * m_sndPropLoader; - - /** - * Pointer to global sound prop gameplay object - **/ - CsndProp * m_sndProp; - - /** - * greebo: The escape point manager which is keeping track - * of all the tdmPathFlee entities. - */ - CEscapePointManager* m_EscapePointManager; - - /** - * greebo: This timer keeps track of the actual gameplay time. - */ - GamePlayTimer m_GamePlayTimer; - - // The singleton connection object - CHttpConnectionPtr m_HttpConnection; - - /** - * Temporary storage of the walkspeed. This is a workaround - * because the walkspeed keeps getting reset. - **/ - float m_walkSpeed; - - // The highest used unique stim/response id - int m_HighestSRId; - - idList m_Timer; // generic timer used for other purposes than stims. - idList m_StimTimer; // All stims that have a timer associated. - idList< idEntityPtr > m_StimEntity; // all entities that currently have a stim regardless of it's state - idList< idEntityPtr > m_RespEntity; // all entities that currently have a response regardless of it's state - - int cinematicSkipTime; // don't allow skipping cinemetics until this time has passed so player doesn't skip out accidently from a firefight - int cinematicStopTime; // cinematics have several camera changes, so keep track of when we stop them so that we don't reset cinematicSkipTime unnecessarily - int cinematicMaxSkipTime; // time to end cinematic when skipping. there's a possibility of an infinite loop if the map isn't set up right. - bool inCinematic; // game is playing cinematic (player controls frozen) - bool skipCinematic; - - // are kept up to date with changes to serverInfo - int framenum; - int previousTime; // time in msec of last frame - int time; // in msec - int m_Interleave; // How often should the lightgem calculation be skipped? - static const int msec = USERCMD_MSEC; // time since last update in milliseconds - - int vacuumAreaNum; // -1 if level doesn't have any outside areas - - gameType_t gameType; - bool isMultiplayer; // set if the game is run in multiplayer mode - bool isServer; // set if the game is run for a dedicated or listen server - bool isClient; // set if the game is run for a client - // discriminates between the RunFrame path and the ClientPrediction path - // NOTE: on a listen server, isClient is false - int localClientNum; // number of the local client. MP: -1 on a dedicated - idLinkList snapshotEntities; // entities from the last snapshot - int realClientTime; // real client time - bool isNewFrame; // true if this is a new game frame, not a rerun due to prediction - float clientSmoothing; // smoothing of other clients in the view - int entityDefBits; // bits required to store an entity def number - - static const char * sufaceTypeNames[ MAX_SURFACE_TYPES ]; // text names for surface types - /** - * DarkMod: text names for new surface types - **/ - static const char * m_NewSurfaceTypes[ MAX_SURFACE_TYPES*2 + 1]; - - idEntityPtr lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f - int lastGUI; // last GUI on the lastGUIEnt - - idEntityPtr portalSkyEnt; - bool portalSkyActive; - - void SetPortalSkyEnt( idEntity *ent ); - bool IsPortalSkyAcive(); - - // tels: a list of all speaker entities with s_music set, these are affected by s_vol_music: - idList musicSpeakers; - - // A flag set by the player to fire a "final save" which must occur at the end of this frame - bool m_TriggerFinalSave; - - // ---------------------- Public idGame Interface ------------------- - - idGameLocal(); - ~idGameLocal(); - - virtual void Init( void ); - virtual void Shutdown( void ); - virtual void SetLocalClient( int clientNum ); - virtual void ThrottleUserInfo( void ); - virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ); - virtual const idDict * GetUserInfo( int clientNum ); - virtual void SetServerInfo( const idDict &serverInfo ); - - virtual const idDict & GetPersistentPlayerInfo( int clientNum ); - virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ); - virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed ); - virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ); - virtual void SaveGame( idFile *saveGameFile ); - virtual void MapShutdown( void ); - virtual void CacheDictionaryMedia( const idDict *dict ); - virtual void SpawnPlayer( int clientNum ); - virtual gameReturn_t RunFrame( const usercmd_t *clientCmds ); - - /** - * TDM: Pause/Unpause game - **/ - virtual void PauseGame( bool bPauseState ); - virtual bool Draw( int clientNum ); - virtual escReply_t HandleESC( idUserInterface **gui ); - virtual idUserInterface *StartMenu( void ); - virtual const char * HandleGuiCommands( const char *menuCommand ); - virtual bool InitGUIChoice( idUserInterface *gui, const char *varName, const char *inChoices, const char *inValues, const bool step = false ); - virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ); - /** - * Adjusts the size of GUI variables to support stretching/scaling of the GUI. - */ - virtual void UpdateGUIScaling( idUserInterface *gui ); - virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] ); - virtual void ServerClientConnect( int clientNum, const char *guid ); - virtual void ServerClientBegin( int clientNum ); - virtual void ServerClientDisconnect( int clientNum ); - virtual void ServerWriteInitialReliableMessages( int clientNum ); - virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ); - virtual bool ServerApplySnapshot( int clientNum, int sequence ); - virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ); - virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ); - virtual bool ClientApplySnapshot( int clientNum, int sequence ); - virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ); - virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ); - - virtual void GetClientStats( int clientNum, char *data, const int len ); - virtual void SwitchTeam( int clientNum, int team ); - - virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ); - - // ---------------------- Public idGameLocal Interface ------------------- - - void Printf( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void DPrintf( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void DWarning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - - // Initializes all map variables common to both save games and spawned games - void LoadMap( const char *mapName, int randseed ); - - void LocalMapRestart( void ); - void MapRestart( void ); - static void MapRestart_f( const idCmdArgs &args ); - bool NextMap( void ); // returns whether serverinfo settings have been modified - static void NextMap_f( const idCmdArgs &args ); - - idMapFile * GetLevelMap( void ); - const char * GetMapName( void ) const; - - int NumAAS( void ) const; - int GetAASId( idAAS* aas ) const; // greebo: Returns the ID for the given pointer (-1 for invalid pointers) - idAAS * GetAAS( int num ) const; - idAAS * GetAAS( const char *name ) const; - void SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed ); - aasHandle_t AddAASObstacle( const idBounds &bounds ); - void RemoveAASObstacle( const aasHandle_t handle ); - void RemoveAllAASObstacles( void ); - - // greebo: Initialises the EAS (routing system for elevators) - void SetupEAS(); - - bool CheatsOk( bool requirePlayer = true ); - void SetSkill( int value ); - gameState_t GameState( void ) const; - - /** - * greebo: Prepares the running map for mission end. Does nothing if the current gamestate - * is lower than GAMESTATE_ACTIVE. Removes all entities of certain types from the - * world and sets all moveables to rest. - */ - void PrepareForMissionEnd(); - - void SetMissionResult(EMissionResult result); - ID_INLINE EMissionResult GetMissionResult() const; - - idEntity * SpawnEntityType( const idTypeInfo &classdef, const idDict *args = NULL, bool bIsClientReadSnapshot = false ); - bool SpawnEntityDef( const idDict &args, idEntity **ent = NULL, bool setDefaults = true ); - int GetSpawnId( const idEntity *ent ) const; - - const idDeclEntityDef * FindEntityDef( const char *name, bool makeDefault = true ) const; - const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const; - - void RegisterEntity( idEntity *ent ); - void UnregisterEntity( idEntity *ent ); - - bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem ); - - bool InPlayerPVS( idEntity *ent ) const; - bool InPlayerConnectedArea( idEntity *ent ) const; - - pvsHandle_t GetPlayerPVS() { return playerPVS; }; - - void SetCamera( idCamera *cam ); - idCamera * GetCamera( void ) const; - bool SkipCinematic( void ); - void CalcFov( float base_fov, float &fov_x, float &fov_y ) const; - - void AddEntityToHash( const char *name, idEntity *ent ); - bool RemoveEntityFromHash( const char *name, idEntity *ent ); - int GetTargets( const idDict &args, idList< idEntityPtr >& list, const char *ref ) const; - int GetRelights(const idDict &args, idList >& list, const char *ref) const; // grayman #2603 - - // returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player. - idEntity * GetTraceEntity( const trace_t &trace ) const; - - static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) ); - idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const; - idEntity * FindEntity( const char *name ) const; - idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const; - int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const; - - /** - * Get the entity that the player is looking at - * Currently called by console commands, does a long trace so should not be - * called every frame. - **/ - idEntity * PlayerTraceEntity( void ); - - void KillBox( idEntity *ent, bool catch_teleport = false ); - void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f ); - void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake ); - void RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel ); - - void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 ); - void BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material ); - - void CallFrameCommand( idEntity *ent, const function_t *frameCommand ); - void CallObjectFrameCommand( idEntity *ent, const char *frameCommand ); - - const idVec3 & GetGravity( void ) const; - - // added the following to assist licensees with merge issues - int GetFrameNum() const { return framenum; }; - int GetTime() const { return time; }; - int GetMSec() const { return msec; }; - - int GetNextClientNum( int current ) const; - idPlayer * GetClientByNum( int current ) const; - idPlayer * GetClientByName( const char *name ) const; - idPlayer * GetClientByCmdArgs( const idCmdArgs &args ) const; - - idPlayer * GetLocalPlayer() const; - - void SpreadLocations(); - idLocationEntity * LocationForPoint( const idVec3 &point ); // May return NULL - /** - * LocationForArea returns a pointer to the location entity for the given area number - * Returns NULL if the area number is out of bounds, or if locations haven't sprad yet - **/ - idLocationEntity * LocationForArea( const int areaNum ); - - idEntity * SelectInitialSpawnPoint( idPlayer *player ); - - void SetPortalState( qhandle_t portal, int blockingBits ); - void SaveEntityNetworkEvent( const idEntity *ent, int event, const idBitMsg *msg ); - void ServerSendChatMessage( int to, const char *name, const char *text ); - int ServerRemapDecl( int clientNum, declType_t type, int index ); - int ClientRemapDecl( declType_t type, int index ); - - void SetGlobalMaterial( const idMaterial *mat ); - const idMaterial * GetGlobalMaterial(); - - void SetGibTime( int _time ) { nextGibTime = _time; }; - int GetGibTime() { return nextGibTime; }; - - bool NeedRestart(); - - /** - * LoadLightMaterial loads the falloff textures from the light materials. The appropriate - * textures are only loaded when the light is spawned and requests the texture. - */ - void LoadLightMaterial(const char *Filename, idList *); - - /** - * CalcLightgem will do the rendersnapshot and analyze the snaphost image in order - * to determine the lightvalue for the lightgem. - */ - float CalcLightgem(idPlayer*); - - ID_INLINE idList &GetLightgemRenderBuffer(void) - { - return m_lightGem.GetLightgemRenderBuffer(); - } - - bool AddStim(idEntity *); - void RemoveStim(idEntity *); - bool AddResponse(idEntity *); - void RemoveResponse(idEntity *); - - /************************************************************************/ - /* J.C.Denton: Finds the main ambient light and creates a new one if */ - /* the main ambient is not found */ - /************************************************************************/ - idLight * FindMainAmbientLight( bool a_bCreateNewIfNotFound = false ); - - /** - * greebo: Links the given entity into the list of Stim entities, such that - * it gets considered each frame as potential stim emitter. - */ - void LinkStimEntity(idEntity* ent); - - /** - * greebo: Removes the given entity from the global list of stimming entities. - * Although it might have active stims, it is no longer considered each frame. - */ - void UnlinkStimEntity(idEntity* ent); - - /** - * Checks whether the entity is in the given list named . - * @returns: the list index or -1 if the entity is not in the list. - */ - int CheckStimResponse(idList< idEntityPtr > &list, idEntity *); - - /** - * Fires off all the enabled responses to this stim of the entities in the given entites list. - * If the trigger is coming from a timer, is set to true. - * - * @return The number of responses triggered - * - */ - int DoResponseAction(const CStimPtr& stim, int numEntities, idEntity* originator, const idVec3& stimOrigin); - - /** - * Process the timer ticks for all timers that are used for other purposes than stim/responses. - */ - void ProcessTimer(unsigned long ticks); - - /** - * ProcessStimResponse will check whether stims are in reach of a response and if so activate them. - */ - void ProcessStimResponse(unsigned long ticks); - - /** - * greebo: Traverses the entities and tries to find the Stim/Response with the given ID. - * This is expensive, so don't call this during map runtime, only in between maps. - * - * @returns: the pointer to the class, or NULL if the uniqueId couldn't be found. - */ - CStimResponsePtr FindStimResponse(int uniqueId); - - // Checks the TDM version - void CheckTDMVersion(); - - void AddMainMenuMessage(const GuiMessage& message); - void HandleGuiMessages(idUserInterface* ui); - - // Tels: Return mapFileName as it is private - const idStr& GetMapFileName() const; - - /** - * greebo: Register a trigger that is to be fired when the mission is loaded. - * The activatorName is stored along with the name of the target to be triggered. When the target map - * has been loaded and all entities have been spawned the game will try to resolve these names - * and issue the activation event. - * If the activator's name is empty, the local player will be used as activator. - */ - void AddInterMissionTrigger(int missionNum, const idStr& activatorName, const idStr& targetName); - - // For internal use, is public to be callable by the event system - void ProcessInterMissionTriggers(); - - // Remove any persistent inventory items, clear inter-mission triggers, etc. - void ClearPersistentInfo(); - -private: - const static int INITIAL_SPAWN_COUNT = 1; - - idStr m_strMainAmbientLightName; // The name of main ambient light, default is: "ambient_world". - J.C.Denton - idStr mapFileName; // name of the map, empty string if no map loaded - idMapFile * mapFile; // will be NULL during the game unless in-game editing is used - bool mapCycleLoaded; - - int spawnCount; - int mapSpawnCount; // it's handy to know which entities are part of the map - - idLocationEntity ** locationEntities; // for location names, etc - - idCamera * camera; - const idMaterial * globalMaterial; // for overriding everything - - idList aasList; // area system - idStrList aasNames; - - idDict spawnArgs; // spawn args used during entity spawning FIXME: shouldn't be necessary anymore - - pvsHandle_t playerPVS; // merged pvs of all players - pvsHandle_t playerConnectedAreas; // all areas connected to any player area - - idVec3 gravity; // global gravity vector - gameState_t gamestate; // keeps track of whether we're spawning, shutting down, or normal gameplay - bool influenceActive; // true when a phantasm is happening - int nextGibTime; - - idList clientDeclRemap[MAX_CLIENTS][DECL_MAX_TYPES]; - - entityState_t * clientEntityStates[MAX_CLIENTS][MAX_GENTITIES]; - int clientPVS[MAX_CLIENTS][ENTITY_PVS_SIZE]; - snapshot_t * clientSnapshots[MAX_CLIENTS]; - idBlockAllocentityStateAllocator; - idBlockAllocsnapshotAllocator; - - idEventQueue eventQueue; - idEventQueue savedEventQueue; - - idStaticList spawnSpots; - idStaticList initialSpots; - int currentInitialSpot; - - idDict newInfo; - - idStrList shakeSounds; - - byte lagometer[ LAGO_IMG_HEIGHT ][ LAGO_IMG_WIDTH ][ 4 ]; - - bool m_DoLightgem; // Signal when the lightgem may be processed. - LightGem m_lightGem; - - // A container for keeping the inter-mission trigger information - struct InterMissionTrigger - { - // The number of the mission this trigger applies to - int missionNum; - - // The name of the entity that should be used as activator. Is resolved immediately after spawn time. - // If empty, the player will be used. - idStr activatorName; - - // The name of the target entity to be triggered. Is resolved immediately after spawn time. - idStr targetName; - }; - - idList m_InterMissionTriggers; - - // Tels: For each part in a GUI command in 'set "cmd" "command arg1 arg2;" the game will - // call HandleMainMenuCommand(), sometimes with a final call with the ";". - // This list here keeps all these parts so we can execute the command - // and have all the arguments, too. - idList m_GUICommandStack; - // how many arguments do we expect for the current command (m_GUICommandStack[0]): - int m_GUICommandArgs; - - void Clear( void ); - // returns true if the entity shouldn't be spawned at all in this game type or difficulty level - bool InhibitEntitySpawn( idDict &spawnArgs ); - // spawn entities from the map file - void SpawnMapEntities( void ); - // commons used by init, shutdown, and restart - void MapPopulate( void ); - void MapClear( bool clearClients ); - - pvsHandle_t GetClientPVS( idPlayer *player, pvsType_t type ); - void SetupPlayerPVS( void ); - void FreePlayerPVS( void ); - void UpdateGravity( void ); - void SortActiveEntityList( void ); - void ShowTargets( void ); - void RunDebugInfo( void ); - - void InitScriptForMap( void ); - - void InitConsoleCommands( void ); - void ShutdownConsoleCommands( void ); - - void InitAsyncNetwork( void ); - void ShutdownAsyncNetwork( void ); - void InitLocalClient( int clientNum ); - void InitClientDeclRemap( int clientNum ); - void ServerSendDeclRemapToClient( int clientNum, declType_t type, int index ); - void FreeSnapshotsOlderThanSequence( int clientNum, int sequence ); - bool ApplySnapshot( int clientNum, int sequence ); - void WriteGameStateToSnapshot( idBitMsgDelta &msg ) const; - void ReadGameStateFromSnapshot( const idBitMsgDelta &msg ); - void NetworkEventWarning( const entityNetEvent_t *event, const char *fmt, ... ) id_attribute((format(printf,3,4))); - void ServerProcessEntityNetworkEventQueue( void ); - void ClientProcessEntityNetworkEventQueue( void ); - void ClientShowSnapshot( int clientNum ) const; - // call after any change to serverInfo. Will update various quick-access flags - void UpdateServerInfoFlags( void ); - void RandomizeInitialSpawns( void ); - static int sortSpawnPoints( const void *ptr1, const void *ptr2 ); - - void DumpOggSounds( void ); - void GetShakeSounds( const idDict *dict ); - void SelectTimeGroup( int timeGroup ); - int GetTimeGroupTime( int timeGroup ); - void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ); - - void Tokenize( idStrList &out, const char *in ); - - void UpdateLagometer( int aheadOfServer, int dupeUsercmds ); - - void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ); - - // Sets the video CVARs according to the settings in the given GUI - void UpdateScreenResolutionFromGUI(idUserInterface* gui); - - // Splits the given string and stores the found video materials in the target list. - // Calculates the length of the ROQ videos as defined in the string (each material - // is separated by a semicolon) Returns the total length in milliseconds, or -1 on failure. - // The lengthStr corresponds to the videosStr, but contains the lengths of the clips - static int LoadVideosFromString(const char* videosStr, const char* lengthStr, - idList& targetList); - - // Platform-specific implementation to change the D3's title and icon - void ChangeWindowTitleAndIcon(); -}; - -//============================================================================ - -extern idGameLocal gameLocal; -extern idAnimManager animationLib; - -//============================================================================ - -template< class type > -ID_INLINE idEntityPtr::idEntityPtr() { - spawnId = 0; -} - -template< class type > -ID_INLINE void idEntityPtr::Save( idSaveGame *savefile ) const { - savefile->WriteInt( spawnId ); -} - -template< class type > -ID_INLINE void idEntityPtr::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( spawnId ); -} - -template< class type > -ID_INLINE idEntityPtr &idEntityPtr::operator=( type *ent ) { - if ( ent == NULL ) { - spawnId = 0; - } else { - spawnId = ( gameLocal.spawnIds[ent->entityNumber] << GENTITYNUM_BITS ) | ent->entityNumber; - } - return *this; -} - -template< class type > -ID_INLINE bool idEntityPtr::operator==(const idEntityPtr& other) const -{ - return spawnId == other.spawnId; -} - -template< class type > -ID_INLINE bool idEntityPtr::SetSpawnId( int id ) { - // the reason for this first check is unclear: - // the function returning false may mean the spawnId is already set right, or the entity is missing - if ( id == spawnId ) { - return false; - } - if ( ( id >> GENTITYNUM_BITS ) == gameLocal.spawnIds[ id & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) { - spawnId = id; - return true; - } - return false; -} - -template< class type > -ID_INLINE bool idEntityPtr::IsValid( void ) const { - return ( gameLocal.spawnIds[ spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] == ( spawnId >> GENTITYNUM_BITS ) ); -} - -template< class type > -ID_INLINE type *idEntityPtr::GetEntity( void ) const { - int entityNum = spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ); - if ( ( gameLocal.spawnIds[ entityNum ] == ( spawnId >> GENTITYNUM_BITS ) ) ) { - return static_cast( gameLocal.entities[ entityNum ] ); - } - return NULL; -} - -template< class type > -ID_INLINE int idEntityPtr::GetEntityNum( void ) const { - return ( spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ); -} - -//============================================================================ - -class idGameError : public idException { -public: - idGameError( const char *text ) : idException( text ) {} -}; - -//============================================================================ - - -// -// these defines work for all startsounds from all entity types -// make sure to change script/tdm_defs.script if you add any channels, or change their order -// -typedef enum { - SND_CHANNEL_ANY = SCHANNEL_ANY, - SND_CHANNEL_VOICE = SCHANNEL_ONE, - SND_CHANNEL_VOICE2, - SND_CHANNEL_BODY, - SND_CHANNEL_BODY2, - SND_CHANNEL_BODY3, - SND_CHANNEL_WEAPON, - SND_CHANNEL_ITEM, - SND_CHANNEL_HEART, - SND_CHANNEL_UNUSED, - SND_CHANNEL_DEMONIC, - SND_CHANNEL_UNUSED_2, - - // internal use only. not exposed to script or framecommands. - // tels: Have now been exposed to script and framecommands. Why were they internal only? - SND_CHANNEL_AMBIENT, - SND_CHANNEL_DAMAGE -} gameSoundChannel_t; - -// content masks -#define MASK_ALL (-1) -#define MASK_SOLID (CONTENTS_SOLID) -#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_BODY) -#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY) -#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP) -#define MASK_WATER (CONTENTS_WATER) -#define MASK_OPAQUE (CONTENTS_OPAQUE) -#define MASK_SHOT_RENDERMODEL (CONTENTS_SOLID|CONTENTS_RENDERMODEL) -#define MASK_SHOT_BOUNDINGBOX (CONTENTS_SOLID|CONTENTS_BODY) - -const float DEFAULT_GRAVITY = 1066.0f; -#define DEFAULT_GRAVITY_STRING "1066" -const idVec3 DEFAULT_GRAVITY_VEC3( 0, 0, -DEFAULT_GRAVITY ); - -const int CINEMATIC_SKIP_DELAY = SEC2MS( 2.0f ); - -//============================================================================ - -#include "physics/force.h" -#include "physics/force_constant.h" -#include "physics/force_drag.h" -#include "physics/force_field.h" -#include "physics/force_spring.h" -#include "physics/physics.h" -#include "physics/physics_static.h" -#include "physics/physics_staticmulti.h" -#include "physics/physics_base.h" -#include "physics/physics_actor.h" -#include "physics/physics_monster.h" -#include "physics/physics_player.h" -#include "physics/physics_parametric.h" -#include "physics/physics_rigidbody.h" -#include "physics/physics_af.h" -#include "physics/physics_liquid.h" - -#include "smokeparticles.h" - -#include "entity.h" -#include "gameedit.h" -#include "af.h" -#include "ik.h" -#include "afentity.h" -#include "misc.h" -#include "actor.h" -#include "projectile.h" -#include "weapon.h" -#include "light.h" -#include "worldspawn.h" -#include "item.h" -#include "playerview.h" -#include "playericon.h" -#include "player.h" -#include "mover.h" -#include "camera.h" -#include "moveable.h" -#include "target.h" -#include "trigger.h" -#include "sound.h" -#include "fx.h" -#include "securitycamera.h" -#include "brittlefracture.h" -#include "../DarkMod/liquid.h" - -#include "ai/ai.h" -#include "anim/anim_testmodel.h" - -#include "script/script_compiler.h" -#include "script/script_interpreter.h" -#include "script/script_thread.h" - -const float RB_VELOCITY_MAX = 16000; -const int RB_VELOCITY_TOTAL_BITS = 16; -const int RB_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_VELOCITY_MAX ) ) + 1; -const int RB_VELOCITY_MANTISSA_BITS = RB_VELOCITY_TOTAL_BITS - 1 - RB_VELOCITY_EXPONENT_BITS; -const float RB_MOMENTUM_MAX = 1e20f; -const int RB_MOMENTUM_TOTAL_BITS = 16; -const int RB_MOMENTUM_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_MOMENTUM_MAX ) ) + 1; -const int RB_MOMENTUM_MANTISSA_BITS = RB_MOMENTUM_TOTAL_BITS - 1 - RB_MOMENTUM_EXPONENT_BITS; -const float RB_FORCE_MAX = 1e20f; -const int RB_FORCE_TOTAL_BITS = 16; -const int RB_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( RB_FORCE_MAX ) ) + 1; -const int RB_FORCE_MANTISSA_BITS = RB_FORCE_TOTAL_BITS - 1 - RB_FORCE_EXPONENT_BITS; - -#endif /* !__GAME_LOCAL_H__ */ diff --git a/game/game_network.cpp b/game/game_network.cpp deleted file mode 100644 index 515b9c693..000000000 --- a/game/game_network.cpp +++ /dev/null @@ -1,1751 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -=============================================================================== - - Client running game code: - - entity events don't work and should not be issued - - entities should never be spawned outside idGameLocal::ClientReadSnapshot - -=============================================================================== -*/ - -// adds tags to the network protocol to detect when things go bad ( internal consistency ) -// NOTE: this changes the network protocol -#ifndef ASYNC_WRITE_TAGS - #define ASYNC_WRITE_TAGS 0 -#endif - -idCVar net_clientShowSnapshot( "net_clientShowSnapshot", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); -idCVar net_clientShowSnapshotRadius( "net_clientShowSnapshotRadius", "128", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar net_clientSmoothing( "net_clientSmoothing", "0.8", CVAR_GAME | CVAR_FLOAT, "smooth other clients angles and position.", 0.0f, 0.95f ); -idCVar net_clientSelfSmoothing( "net_clientSelfSmoothing", "0.6", CVAR_GAME | CVAR_FLOAT, "smooth self position if network causes prediction error.", 0.0f, 0.95f ); -idCVar net_clientMaxPrediction( "net_clientMaxPrediction", "1000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of milliseconds a client can predict ahead of server." ); -idCVar net_clientLagOMeter( "net_clientLagOMeter", "1", CVAR_GAME | CVAR_BOOL | CVAR_NOCHEAT | CVAR_ARCHIVE, "draw prediction graph" ); - -/* -================ -idGameLocal::InitAsyncNetwork -================ -*/ -void idGameLocal::InitAsyncNetwork( void ) { - int i, type; - - for ( i = 0; i < MAX_CLIENTS; i++ ) { - for ( type = 0; type < declManager->GetNumDeclTypes(); type++ ) { - clientDeclRemap[i][type].Clear(); - } - } - - memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); - memset( clientPVS, 0, sizeof( clientPVS ) ); - memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); - - eventQueue.Init(); - savedEventQueue.Init(); - - entityDefBits = -( idMath::BitsForInteger( declManager->GetNumDecls( DECL_ENTITYDEF ) ) + 1 ); - localClientNum = 0; // on a listen server SetLocalUser will set this right - realClientTime = 0; - isNewFrame = true; - clientSmoothing = net_clientSmoothing.GetFloat(); -} - -/* -================ -idGameLocal::ShutdownAsyncNetwork -================ -*/ -void idGameLocal::ShutdownAsyncNetwork( void ) { - entityStateAllocator.Shutdown(); - snapshotAllocator.Shutdown(); - eventQueue.Shutdown(); - savedEventQueue.Shutdown(); - memset( clientEntityStates, 0, sizeof( clientEntityStates ) ); - memset( clientPVS, 0, sizeof( clientPVS ) ); - memset( clientSnapshots, 0, sizeof( clientSnapshots ) ); -} - -/* -================ -idGameLocal::InitLocalClient -================ -*/ -void idGameLocal::InitLocalClient( int clientNum ) { - isServer = false; - isClient = true; - localClientNum = clientNum; - clientSmoothing = net_clientSmoothing.GetFloat(); -} - -/* -================ -idGameLocal::InitClientDeclRemap -================ -*/ -void idGameLocal::InitClientDeclRemap( int clientNum ) { - int type, i, num; - - for ( type = 0; type < declManager->GetNumDeclTypes(); type++ ) { - - // only implicit materials and sound shaders decls are used - if ( type != DECL_MATERIAL && type != DECL_SOUND ) { - continue; - } - - num = declManager->GetNumDecls( (declType_t) type ); - clientDeclRemap[clientNum][type].Clear(); - clientDeclRemap[clientNum][type].AssureSize( num, -1 ); - - // pre-initialize the remap with non-implicit decls, all non-implicit decls are always going - // to be in order and in sync between server and client because of the decl manager checksum - for ( i = 0; i < num; i++ ) { - const idDecl *decl = declManager->DeclByIndex( (declType_t) type, i, false ); - if ( decl->IsImplicit() ) { - // once the first implicit decl is found all remaining decls are considered implicit as well - break; - } - clientDeclRemap[clientNum][type][i] = i; - } - } -} - -/* -================ -idGameLocal::ServerSendDeclRemapToClient -================ -*/ -void idGameLocal::ServerSendDeclRemapToClient( int clientNum, declType_t type, int index ) { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - // if no client connected for this spot - if ( entities[clientNum] == NULL ) { - return; - } - // increase size of list if required - if ( index >= clientDeclRemap[clientNum][type].Num() ) { - clientDeclRemap[clientNum][(int)type].AssureSize( index + 1, -1 ); - } - // if already remapped - if ( clientDeclRemap[clientNum][(int)type][index] != -1 ) { - return; - } - - const idDecl *decl = declManager->DeclByIndex( type, index, false ); - if ( decl == NULL ) { - gameLocal.Error( "server tried to remap bad %s decl index %d", declManager->GetDeclNameFromType( type ), index ); - return; - } - - // set the index at the server - clientDeclRemap[clientNum][(int)type][index] = index; - - // write update to client - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_REMAP_DECL ); - outMsg.WriteByte( type ); - outMsg.WriteLong( index ); - outMsg.WriteString( decl->GetName() ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); -} - -/* -================ -idGameLocal::ServerRemapDecl -================ -*/ -int idGameLocal::ServerRemapDecl( int clientNum, declType_t type, int index ) { - - // only implicit materials and sound shaders decls are used - if ( type != DECL_MATERIAL && type != DECL_SOUND ) { - return index; - } - - if ( clientNum == -1 ) { - for ( int i = 0; i < MAX_CLIENTS; i++ ) { - ServerSendDeclRemapToClient( i, type, index ); - } - } else { - ServerSendDeclRemapToClient( clientNum, type, index ); - } - return index; -} - -/* -================ -idGameLocal::ClientRemapDecl -================ -*/ -int idGameLocal::ClientRemapDecl( declType_t type, int index ) { - - // only implicit materials and sound shaders decls are used - if ( type != DECL_MATERIAL && type != DECL_SOUND ) { - return index; - } - - // negative indexes are sometimes used for NULL decls - if ( index < 0 ) { - return index; - } - - // make sure the index is valid - if ( clientDeclRemap[localClientNum][(int)type].Num() == 0 ) { - gameLocal.Error( "client received decl index %d before %s decl remap was initialized", index, declManager->GetDeclNameFromType( type ) ); - return -1; - } - if ( index >= clientDeclRemap[localClientNum][(int)type].Num() ) { - gameLocal.Error( "client received unmapped %s decl index %d from server", declManager->GetDeclNameFromType( type ), index ); - return -1; - } - if ( clientDeclRemap[localClientNum][(int)type][index] == -1 ) { - gameLocal.Error( "client received unmapped %s decl index %d from server", declManager->GetDeclNameFromType( type ), index ); - return -1; - } - return clientDeclRemap[localClientNum][type][index]; -} - -/* -================ -idGameLocal::ServerAllowClient -================ -*/ -allowReply_t idGameLocal::ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[ MAX_STRING_CHARS ] ) { - reason[0] = '\0'; - - if ( serverInfo.GetInt( "si_pure" ) && !mpGame.IsPureReady() ) { - idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07139" ); - return ALLOW_NOTYET; - } - - if ( !serverInfo.GetInt( "si_maxPlayers" ) ) { - idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07140" ); - return ALLOW_NOTYET; - } - - if ( numClients >= serverInfo.GetInt( "si_maxPlayers" ) ) { - idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07141" ); - return ALLOW_NOTYET; - } - - if ( !cvarSystem->GetCVarBool( "si_usepass" ) ) { - return ALLOW_YES; - } - - const char *pass = cvarSystem->GetCVarString( "g_password" ); - if ( pass[ 0 ] == '\0' ) { - common->Warning( "si_usepass is set but g_password is empty" ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "say si_usepass is set but g_password is empty" ); - // avoids silent misconfigured state - idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07142" ); - return ALLOW_NOTYET; - } - - if ( !idStr::Cmp( pass, password ) ) { - return ALLOW_YES; - } - - idStr::snPrintf( reason, MAX_STRING_CHARS, "#str_07143" ); - Printf( "Rejecting client %s from IP %s: invalid password\n", guid, IP ); - return ALLOW_BADPASS; -} - -/* -================ -idGameLocal::ServerClientConnect -================ -*/ -void idGameLocal::ServerClientConnect( int clientNum, const char *guid ) { - // make sure no parasite entity is left - if ( entities[ clientNum ] ) { - common->DPrintf( "ServerClientConnect: remove old player entity\n" ); - delete entities[ clientNum ]; - } - userInfo[ clientNum ].Clear(); - mpGame.ServerClientConnect( clientNum ); - Printf( "client %d connected.\n", clientNum ); -} - -/* -================ -idGameLocal::ServerClientBegin -================ -*/ -void idGameLocal::ServerClientBegin( int clientNum ) { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - // initialize the decl remap - InitClientDeclRemap( clientNum ); - - // send message to initialize decl remap at the client (this is always the very first reliable game message) - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - - // spawn the player - SpawnPlayer( clientNum ); - if ( clientNum == localClientNum ) { - mpGame.EnterGame( clientNum ); - } - - // send message to spawn the player at the clients - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SPAWN_PLAYER ); - outMsg.WriteByte( clientNum ); - outMsg.WriteLong( spawnIds[ clientNum ] ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); -} - -/* -================ -idGameLocal::ServerClientDisconnect -================ -*/ -void idGameLocal::ServerClientDisconnect( int clientNum ) { - int i; - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DELETE_ENT ); - outMsg.WriteBits( ( spawnIds[ clientNum ] << GENTITYNUM_BITS ) | clientNum, 32 ); // see GetSpawnId - networkSystem->ServerSendReliableMessage( -1, outMsg ); - - // free snapshots stored for this client - FreeSnapshotsOlderThanSequence( clientNum, 0x7FFFFFFF ); - - // free entity states stored for this client - for ( i = 0; i < MAX_GENTITIES; i++ ) { - if ( clientEntityStates[ clientNum ][ i ] ) { - entityStateAllocator.Free( clientEntityStates[ clientNum ][ i ] ); - clientEntityStates[ clientNum ][ i ] = NULL; - } - } - - // clear the client PVS - memset( clientPVS[ clientNum ], 0, sizeof( clientPVS[ clientNum ] ) ); - - // delete the player entity - delete entities[ clientNum ]; - - mpGame.DisconnectClient( clientNum ); - -} - -/* -================ -idGameLocal::ServerWriteInitialReliableMessages - - Send reliable messages to initialize the client game up to a certain initial state. -================ -*/ -void idGameLocal::ServerWriteInitialReliableMessages( int clientNum ) { - int i; - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - entityNetEvent_t *event; - - // spawn players - for ( i = 0; i < MAX_CLIENTS; i++ ) { - if ( entities[i] == NULL || i == clientNum ) { - continue; - } - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting( ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SPAWN_PLAYER ); - outMsg.WriteByte( i ); - outMsg.WriteLong( spawnIds[ i ] ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - } - - // send all saved events - for ( event = savedEventQueue.Start(); event; event = event->next ) { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_EVENT ); - outMsg.WriteBits( event->spawnId, 32 ); - outMsg.WriteByte( event->event ); - outMsg.WriteLong( event->time ); - outMsg.WriteBits( event->paramsSize, idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - if ( event->paramsSize ) { - outMsg.WriteData( event->paramsBuf, event->paramsSize ); - } - - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - } - - // update portals for opened doors - int numPortals = gameRenderWorld->NumPortals(); - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_PORTALSTATES ); - outMsg.WriteLong( numPortals ); - for ( i = 0; i < numPortals; i++ ) { - outMsg.WriteBits( gameRenderWorld->GetPortalState( (qhandle_t) (i+1) ) , NUM_RENDER_PORTAL_BITS ); - } - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - - mpGame.ServerWriteInitialReliableMessages( clientNum ); -} - -/* -================ -idGameLocal::SaveEntityNetworkEvent -================ -*/ -void idGameLocal::SaveEntityNetworkEvent( const idEntity *ent, int eventId, const idBitMsg *msg ) { - entityNetEvent_t *event; - - event = savedEventQueue.Alloc(); - event->spawnId = GetSpawnId( ent ); - event->event = eventId; - event->time = time; - if ( msg ) { - event->paramsSize = msg->GetSize(); - memcpy( event->paramsBuf, msg->GetData(), msg->GetSize() ); - } else { - event->paramsSize = 0; - } - - savedEventQueue.Enqueue( event, idEventQueue::OUTOFORDER_IGNORE ); -} - -/* -================ -idGameLocal::FreeSnapshotsOlderThanSequence -================ -*/ -void idGameLocal::FreeSnapshotsOlderThanSequence( int clientNum, int sequence ) { - snapshot_t *snapshot, *lastSnapshot, *nextSnapshot; - entityState_t *state; - - for ( lastSnapshot = NULL, snapshot = clientSnapshots[clientNum]; snapshot; snapshot = nextSnapshot ) { - nextSnapshot = snapshot->next; - if ( snapshot->sequence < sequence ) { - for ( state = snapshot->firstEntityState; state; state = snapshot->firstEntityState ) { - snapshot->firstEntityState = snapshot->firstEntityState->next; - entityStateAllocator.Free( state ); - } - if ( lastSnapshot ) { - lastSnapshot->next = snapshot->next; - } else { - clientSnapshots[clientNum] = snapshot->next; - } - snapshotAllocator.Free( snapshot ); - } else { - lastSnapshot = snapshot; - } - } -} - -/* -================ -idGameLocal::ApplySnapshot -================ -*/ -bool idGameLocal::ApplySnapshot( int clientNum, int sequence ) { - snapshot_t *snapshot, *lastSnapshot, *nextSnapshot; - entityState_t *state; - - FreeSnapshotsOlderThanSequence( clientNum, sequence ); - - for ( lastSnapshot = NULL, snapshot = clientSnapshots[clientNum]; snapshot; snapshot = nextSnapshot ) { - nextSnapshot = snapshot->next; - if ( snapshot->sequence == sequence ) { - for ( state = snapshot->firstEntityState; state; state = state->next ) { - if ( clientEntityStates[clientNum][state->entityNumber] ) { - entityStateAllocator.Free( clientEntityStates[clientNum][state->entityNumber] ); - } - clientEntityStates[clientNum][state->entityNumber] = state; - } - memcpy( clientPVS[clientNum], snapshot->pvs, sizeof( snapshot->pvs ) ); - if ( lastSnapshot ) { - lastSnapshot->next = nextSnapshot; - } else { - clientSnapshots[clientNum] = nextSnapshot; - } - snapshotAllocator.Free( snapshot ); - return true; - } else { - lastSnapshot = snapshot; - } - } - - return false; -} - -/* -================ -idGameLocal::WriteGameStateToSnapshot -================ -*/ -void idGameLocal::WriteGameStateToSnapshot( idBitMsgDelta &msg ) const { - int i; - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - msg.WriteFloat( globalShaderParms[i] ); - } - - mpGame.WriteToSnapshot( msg ); -} - -/* -================ -idGameLocal::ReadGameStateFromSnapshot -================ -*/ -void idGameLocal::ReadGameStateFromSnapshot( const idBitMsgDelta &msg ) { - int i; - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - globalShaderParms[i] = msg.ReadFloat(); - } - - mpGame.ReadFromSnapshot( msg ); -} - -/* -================ -idGameLocal::ServerWriteSnapshot - - Write a snapshot of the current game state for the given client. -================ -*/ -void idGameLocal::ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ) { - int i, msgSize, msgWriteBit; - idPlayer *player, *spectated = NULL; - idEntity *ent; - pvsHandle_t pvsHandle; - idBitMsgDelta deltaMsg; - snapshot_t *snapshot; - entityState_t *base, *newBase; - int numSourceAreas, sourceAreas[ idEntity::MAX_PVS_AREAS ]; - - player = static_cast( entities[ clientNum ] ); - if ( !player ) { - return; - } - if ( player->spectating && player->spectator != clientNum && entities[ player->spectator ] ) { - spectated = static_cast< idPlayer * >( entities[ player->spectator ] ); - } else { - spectated = player; - } - - // free too old snapshots - FreeSnapshotsOlderThanSequence( clientNum, sequence - 64 ); - - // allocate new snapshot - snapshot = snapshotAllocator.Alloc(); - snapshot->sequence = sequence; - snapshot->firstEntityState = NULL; - snapshot->next = clientSnapshots[clientNum]; - clientSnapshots[clientNum] = snapshot; - memset( snapshot->pvs, 0, sizeof( snapshot->pvs ) ); - - // get PVS for this player - // don't use PVSAreas for networking - PVSAreas depends on animations (and md5 bounds), which are not synchronized - numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS ); - pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL ); - - // Add portalSky areas to PVS - if ( portalSkyEnt.GetEntity() ) { - pvsHandle_t otherPVS, newPVS; - idEntity *skyEnt = portalSkyEnt.GetEntity(); - - otherPVS = gameLocal.pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() ); - newPVS = gameLocal.pvs.MergeCurrentPVS( pvsHandle, otherPVS ); - pvs.FreeCurrentPVS( pvsHandle ); - pvs.FreeCurrentPVS( otherPVS ); - pvsHandle = newPVS; - } - -#if ASYNC_WRITE_TAGS - idRandom tagRandom; - tagRandom.SetSeed( random.RandomInt() ); - msg.WriteLong( tagRandom.GetSeed() ); -#endif - - // create the snapshot - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - - // if the entity is not in the player PVS - if ( !ent->PhysicsTeamInPVS( pvsHandle ) && ent->entityNumber != clientNum ) { - continue; - } - - // add the entity to the snapshot pvs - snapshot->pvs[ ent->entityNumber >> 5 ] |= 1 << ( ent->entityNumber & 31 ); - - // if that entity is not marked for network synchronization - if ( !ent->fl.networkSync ) { - continue; - } - - // save the write state to which we can revert when the entity didn't change at all - msg.SaveWriteState( msgSize, msgWriteBit ); - - // write the entity to the snapshot - msg.WriteBits( ent->entityNumber, GENTITYNUM_BITS ); - - base = clientEntityStates[clientNum][ent->entityNumber]; - if ( base ) { - base->state.BeginReading(); - } - newBase = entityStateAllocator.Alloc(); - newBase->entityNumber = ent->entityNumber; - newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); - newBase->state.BeginWriting(); - - deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); - - deltaMsg.WriteBits( spawnIds[ ent->entityNumber ], 32 - GENTITYNUM_BITS ); - deltaMsg.WriteBits( ent->GetType()->typeNum, idClass::GetTypeNumBits() ); - deltaMsg.WriteBits( ServerRemapDecl( -1, DECL_ENTITYDEF, ent->entityDefNumber ), entityDefBits ); - - // write the class specific data to the snapshot - ent->WriteToSnapshot( deltaMsg ); - - if ( !deltaMsg.HasChanged() ) { - msg.RestoreWriteState( msgSize, msgWriteBit ); - entityStateAllocator.Free( newBase ); - } else { - newBase->next = snapshot->firstEntityState; - snapshot->firstEntityState = newBase; - -#if ASYNC_WRITE_TAGS - msg.WriteLong( tagRandom.RandomInt() ); -#endif - } - } - - msg.WriteBits( ENTITYNUM_NONE, GENTITYNUM_BITS ); - - // write the PVS to the snapshot -#if ASYNC_WRITE_PVS - for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { - if ( i < numSourceAreas ) { - msg.WriteLong( sourceAreas[ i ] ); - } else { - msg.WriteLong( 0 ); - } - } - gameLocal.pvs.WritePVS( pvsHandle, msg ); -#endif - for ( i = 0; i < ENTITY_PVS_SIZE; i++ ) { - msg.WriteDeltaLong( clientPVS[clientNum][i], snapshot->pvs[i] ); - } - - // free the PVS - pvs.FreeCurrentPVS( pvsHandle ); - - // write the game and player state to the snapshot - base = clientEntityStates[clientNum][ENTITYNUM_NONE]; // ENTITYNUM_NONE is used for the game and player state - if ( base ) { - base->state.BeginReading(); - } - newBase = entityStateAllocator.Alloc(); - newBase->entityNumber = ENTITYNUM_NONE; - newBase->next = snapshot->firstEntityState; - snapshot->firstEntityState = newBase; - newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); - newBase->state.BeginWriting(); - deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); - if ( player->spectating && player->spectator != player->entityNumber && gameLocal.entities[ player->spectator ] && gameLocal.entities[ player->spectator ]->IsType( idPlayer::Type ) ) { - static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->WritePlayerStateToSnapshot( deltaMsg ); - } else { - player->WritePlayerStateToSnapshot( deltaMsg ); - } - WriteGameStateToSnapshot( deltaMsg ); - - // copy the client PVS string - memcpy( clientInPVS, snapshot->pvs, ( numPVSClients + 7 ) >> 3 ); - LittleRevBytes( clientInPVS, sizeof( int ), sizeof( clientInPVS ) / sizeof ( int ) ); -} - -/* -================ -idGameLocal::ServerApplySnapshot -================ -*/ -bool idGameLocal::ServerApplySnapshot( int clientNum, int sequence ) { - return ApplySnapshot( clientNum, sequence ); -} - -/* -================ -idGameLocal::NetworkEventWarning -================ -*/ -void idGameLocal::NetworkEventWarning( const entityNetEvent_t *event, const char *fmt, ... ) { - char buf[1024]; - int length = 0; - va_list argptr; - - int entityNum = event->spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ); - int id = event->spawnId >> GENTITYNUM_BITS; - - length += idStr::snPrintf( buf+length, sizeof(buf)-1-length, "event %d for entity %d %d: ", event->event, entityNum, id ); - va_start( argptr, fmt ); - length = idStr::vsnPrintf( buf+length, sizeof(buf)-1-length, fmt, argptr ); - va_end( argptr ); - idStr::Append( buf, sizeof(buf), "\n" ); - - common->DWarning( buf ); -} - -/* -================ -idGameLocal::ServerProcessEntityNetworkEventQueue -================ -*/ -void idGameLocal::ServerProcessEntityNetworkEventQueue( void ) { - idEntity *ent; - entityNetEvent_t *event; - idBitMsg eventMsg; - - while ( eventQueue.Start() ) { - event = eventQueue.Start(); - - if ( event->time > time ) { - break; - } - - idEntityPtr< idEntity > entPtr; - - if( !entPtr.SetSpawnId( event->spawnId ) ) { - NetworkEventWarning( event, "Entity does not exist any longer, or has not been spawned yet." ); - } else { - ent = entPtr.GetEntity(); - assert( ent ); - - eventMsg.Init( event->paramsBuf, sizeof( event->paramsBuf ) ); - eventMsg.SetSize( event->paramsSize ); - eventMsg.BeginReading(); - if ( !ent->ServerReceiveEvent( event->event, event->time, eventMsg ) ) { - NetworkEventWarning( event, "unknown event" ); - } - } - - entityNetEvent_t* freedEvent = eventQueue.Dequeue(); - assert( freedEvent == event ); - eventQueue.Free( event ); - } -} - -/* -================ -idGameLocal::ServerSendChatMessage -================ -*/ -void idGameLocal::ServerSendChatMessage( int to, const char *name, const char *text ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CHAT ); - outMsg.WriteString( name ); - outMsg.WriteString( text, -1, false ); - networkSystem->ServerSendReliableMessage( to, outMsg ); - - if ( to == -1 || to == localClientNum ) { - mpGame.AddChatLine( "%s^0: %s\n", name, text ); - } -} - -/* -================ -idGameLocal::ServerProcessReliableMessage -================ -*/ -void idGameLocal::ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) { - int id; - - id = msg.ReadByte(); - switch( id ) { - case GAME_RELIABLE_MESSAGE_CHAT: - case GAME_RELIABLE_MESSAGE_TCHAT: { - char name[128]; - char text[128]; - - msg.ReadString( name, sizeof( name ) ); - msg.ReadString( text, sizeof( text ) ); - - mpGame.ProcessChatMessage( clientNum, id == GAME_RELIABLE_MESSAGE_TCHAT, name, text, NULL ); - - break; - } - case GAME_RELIABLE_MESSAGE_VCHAT: { - int index = msg.ReadLong(); - bool team = msg.ReadBits( 1 ) != 0; - mpGame.ProcessVoiceChat( clientNum, team, index ); - break; - } - case GAME_RELIABLE_MESSAGE_KILL: { - mpGame.WantKilled( clientNum ); - break; - } - case GAME_RELIABLE_MESSAGE_DROPWEAPON: { - mpGame.DropWeapon( clientNum ); - break; - } - case GAME_RELIABLE_MESSAGE_CALLVOTE: { - mpGame.ServerCallVote( clientNum, msg ); - break; - } - case GAME_RELIABLE_MESSAGE_CASTVOTE: { - bool vote = ( msg.ReadByte() != 0 ); - mpGame.CastVote( clientNum, vote ); - break; - } -#if 0 - // uncomment this if you want to track when players are in a menu - case GAME_RELIABLE_MESSAGE_MENU: { - bool menuUp = ( msg.ReadBits( 1 ) != 0 ); - break; - } -#endif - case GAME_RELIABLE_MESSAGE_EVENT: { - entityNetEvent_t *event; - - // allocate new event - event = eventQueue.Alloc(); - eventQueue.Enqueue( event, idEventQueue::OUTOFORDER_DROP ); - - event->spawnId = msg.ReadBits( 32 ); - event->event = msg.ReadByte(); - event->time = msg.ReadLong(); - - event->paramsSize = msg.ReadBits( idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - if ( event->paramsSize ) { - if ( event->paramsSize > MAX_EVENT_PARAM_SIZE ) { - NetworkEventWarning( event, "invalid param size" ); - return; - } - msg.ReadByteAlign(); - msg.ReadData( event->paramsBuf, event->paramsSize ); - } - break; - } - default: { - Warning( "Unknown client->server reliable message: %d", id ); - break; - } - } -} - -/* -================ -idGameLocal::ClientShowSnapshot -================ -*/ -void idGameLocal::ClientShowSnapshot( int clientNum ) const { - int baseBits; - idEntity *ent; - idPlayer *player; - idMat3 viewAxis; - idBounds viewBounds; - entityState_t *base; - - if ( !net_clientShowSnapshot.GetInteger() ) { - return; - } - - player = static_cast( entities[clientNum] ); - if ( !player ) { - return; - } - - viewAxis = player->viewAngles.ToMat3(); - viewBounds = player->GetPhysics()->GetAbsBounds().Expand( net_clientShowSnapshotRadius.GetFloat() ); - - for( ent = snapshotEntities.Next(); ent != NULL; ent = ent->snapshotNode.Next() ) { - - if ( net_clientShowSnapshot.GetInteger() == 1 && ent->snapshotBits == 0 ) { - continue; - } - - const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds(); - - if ( !entBounds.IntersectsBounds( viewBounds ) ) { - continue; - } - - base = clientEntityStates[clientNum][ent->entityNumber]; - if ( base ) { - baseBits = base->state.GetNumBitsWritten(); - } else { - baseBits = 0; - } - - if ( net_clientShowSnapshot.GetInteger() == 2 && baseBits == 0 ) { - continue; - } - - gameRenderWorld->DebugBounds( colorGreen, entBounds ); - gameRenderWorld->DrawText( va( "%d: %s (%d,%d bytes of %d,%d)\n", ent->entityNumber, - ent->name.c_str(), ent->snapshotBits >> 3, ent->snapshotBits & 7, baseBits >> 3, baseBits & 7 ), - entBounds.GetCenter(), 0.1f, colorWhite, viewAxis, 1 ); - } -} - -/* -================ -idGameLocal::UpdateLagometer -================ -*/ -void idGameLocal::UpdateLagometer( int aheadOfServer, int dupeUsercmds ) { - int i, j, ahead; - for ( i = 0; i < LAGO_HEIGHT; i++ ) { - memmove( (byte *)lagometer + LAGO_WIDTH * 4 * i, (byte *)lagometer + LAGO_WIDTH * 4 * i + 4, ( LAGO_WIDTH - 1 ) * 4 ); - } - j = LAGO_WIDTH - 1; - for ( i = 0; i < LAGO_HEIGHT; i++ ) { - lagometer[i][j][0] = lagometer[i][j][1] = lagometer[i][j][2] = lagometer[i][j][3] = 0; - } - ahead = static_cast(idMath::Rint( (float)aheadOfServer / 16.0f )); - if ( ahead >= 0 ) { - for ( i = 2 * Max( 0, 5 - ahead ); i < 2 * 5; i++ ) { - lagometer[i][j][1] = 255; - lagometer[i][j][3] = 255; - } - } else { - for ( i = 2 * 5; i < 2 * ( 5 + Min( 10, -ahead ) ); i++ ) { - lagometer[i][j][0] = 255; - lagometer[i][j][1] = 255; - lagometer[i][j][3] = 255; - } - } - for ( i = LAGO_HEIGHT - 2 * Min( 6, dupeUsercmds ); i < LAGO_HEIGHT; i++ ) { - lagometer[i][j][0] = 255; - if ( dupeUsercmds <= 2 ) { - lagometer[i][j][1] = 255; - } - lagometer[i][j][3] = 255; - } -} - -/* -================ -idGameLocal::ClientReadSnapshot -================ -*/ -void idGameLocal::ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) { - int i, typeNum, entityDefNumber, numBitsRead; - idTypeInfo *typeInfo; - idEntity *ent; - idPlayer *player, *spectated; - pvsHandle_t pvsHandle; - idDict args; - const char *classname; - idBitMsgDelta deltaMsg; - snapshot_t *snapshot; - entityState_t *base, *newBase; - int spawnId; - int numSourceAreas, sourceAreas[ idEntity::MAX_PVS_AREAS ]; - idWeapon *weap; - - if ( net_clientLagOMeter.GetBool() && renderSystem ) { - UpdateLagometer( aheadOfServer, dupeUsercmds ); - if ( !renderSystem->UploadImage( LAGO_IMAGE, (byte *)lagometer, LAGO_IMG_WIDTH, LAGO_IMG_HEIGHT ) ) { - common->Printf( "lagometer: UploadImage failed. turning off net_clientLagOMeter\n" ); - net_clientLagOMeter.SetBool( false ); - } - } - - InitLocalClient( clientNum ); - - // clear any debug lines from a previous frame - gameRenderWorld->DebugClearLines( time ); - - // clear any debug polygons from a previous frame - gameRenderWorld->DebugClearPolygons( time ); - - // update the game time - framenum = gameFrame; - time = gameTime; - previousTime = time - msec; - - // so that StartSound/StopSound doesn't risk skipping - isNewFrame = true; - - // clear the snapshot entity list - snapshotEntities.Clear(); - - // allocate new snapshot - snapshot = snapshotAllocator.Alloc(); - snapshot->sequence = sequence; - snapshot->firstEntityState = NULL; - snapshot->next = clientSnapshots[clientNum]; - clientSnapshots[clientNum] = snapshot; - -#if ASYNC_WRITE_TAGS - idRandom tagRandom; - tagRandom.SetSeed( msg.ReadLong() ); -#endif - - // read all entities from the snapshot - for ( i = msg.ReadBits( GENTITYNUM_BITS ); i != ENTITYNUM_NONE; i = msg.ReadBits( GENTITYNUM_BITS ) ) { - - base = clientEntityStates[clientNum][i]; - if ( base ) { - base->state.BeginReading(); - } - newBase = entityStateAllocator.Alloc(); - newBase->entityNumber = i; - newBase->next = snapshot->firstEntityState; - snapshot->firstEntityState = newBase; - newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); - newBase->state.BeginWriting(); - - numBitsRead = msg.GetNumBitsRead(); - - deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); - - spawnId = deltaMsg.ReadBits( 32 - GENTITYNUM_BITS ); - typeNum = deltaMsg.ReadBits( idClass::GetTypeNumBits() ); - entityDefNumber = ClientRemapDecl( DECL_ENTITYDEF, deltaMsg.ReadBits( entityDefBits ) ); - - typeInfo = idClass::GetType( typeNum ); - if ( !typeInfo ) { - Error( "Unknown type number %d for entity %d with class number %d", typeNum, i, entityDefNumber ); - } - - ent = entities[i]; - - // if there is no entity or an entity of the wrong type - if ( !ent || ent->GetType()->typeNum != typeNum || ent->entityDefNumber != entityDefNumber || spawnId != spawnIds[ i ] ) { - - if ( i < MAX_CLIENTS && ent ) { - // SPAWN_PLAYER should be taking care of spawning the entity with the right spawnId - common->Warning( "ClientReadSnapshot: recycling client entity %d\n", i ); - } - - delete ent; - - spawnCount = spawnId; - - args.Clear(); - args.SetInt( "spawn_entnum", i ); - args.Set( "name", va( "entity%d", i ) ); - - if ( entityDefNumber >= 0 ) { - if ( entityDefNumber >= declManager->GetNumDecls( DECL_ENTITYDEF ) ) { - Error( "server has %d entityDefs instead of %d", entityDefNumber, declManager->GetNumDecls( DECL_ENTITYDEF ) ); - } - classname = declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); - args.Set( "classname", classname ); - if ( !SpawnEntityDef( args, &ent ) || !entities[i] || entities[i]->GetType()->typeNum != typeNum ) { - Error( "Failed to spawn entity with classname '%s' of type '%s'", classname, typeInfo->classname ); - } - } else { - ent = SpawnEntityType( *typeInfo, &args, true ); - if ( !entities[i] || entities[i]->GetType()->typeNum != typeNum ) { - Error( "Failed to spawn entity of type '%s'", typeInfo->classname ); - } - } - if ( i < MAX_CLIENTS && i >= numClients ) { - numClients = i + 1; - } - } - - // add the entity to the snapshot list - ent->snapshotNode.AddToEnd( snapshotEntities ); - ent->snapshotSequence = sequence; - - // read the class specific data from the snapshot - ent->ReadFromSnapshot( deltaMsg ); - - ent->snapshotBits = msg.GetNumBitsRead() - numBitsRead; - -#if ASYNC_WRITE_TAGS - if ( msg.ReadLong() != tagRandom.RandomInt() ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "writeGameState" ); - if ( entityDefNumber >= 0 && entityDefNumber < declManager->GetNumDecls( DECL_ENTITYDEF ) ) { - classname = declManager->DeclByIndex( DECL_ENTITYDEF, entityDefNumber, false )->GetName(); - Error( "write to and read from snapshot out of sync for classname '%s' of type '%s'", classname, typeInfo->classname ); - } else { - Error( "write to and read from snapshot out of sync for type '%s'", typeInfo->classname ); - } - } -#endif - } - - player = static_cast( entities[clientNum] ); - if ( !player ) { - return; - } - - // if prediction is off, enable local client smoothing - player->SetSelfSmooth( dupeUsercmds > 2 ); - - if ( player->spectating && player->spectator != clientNum && entities[ player->spectator ] ) { - spectated = static_cast< idPlayer * >( entities[ player->spectator ] ); - } else { - spectated = player; - } - - // get PVS for this player - // don't use PVSAreas for networking - PVSAreas depends on animations (and md5 bounds), which are not synchronized - numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS ); - pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL ); - - // read the PVS from the snapshot -#if ASYNC_WRITE_PVS - int serverPVS[idEntity::MAX_PVS_AREAS]; - i = numSourceAreas; - while ( i < idEntity::MAX_PVS_AREAS ) { - sourceAreas[ i++ ] = 0; - } - for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { - serverPVS[ i ] = msg.ReadLong(); - } - if ( memcmp( sourceAreas, serverPVS, idEntity::MAX_PVS_AREAS * sizeof( int ) ) ) { - common->Warning( "client PVS areas != server PVS areas, sequence 0x%x", sequence ); - for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { - common->DPrintf( "%3d ", sourceAreas[ i ] ); - } - common->DPrintf( "\n" ); - for ( i = 0; i < idEntity::MAX_PVS_AREAS; i++ ) { - common->DPrintf( "%3d ", serverPVS[ i ] ); - } - common->DPrintf( "\n" ); - } - gameLocal.pvs.ReadPVS( pvsHandle, msg ); -#endif - for ( i = 0; i < ENTITY_PVS_SIZE; i++ ) { - snapshot->pvs[i] = msg.ReadDeltaLong( clientPVS[clientNum][i] ); - } - - // add entities in the PVS that haven't changed since the last applied snapshot - for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - - // if the entity is already in the snapshot - if ( ent->snapshotSequence == sequence ) { - continue; - } - - // if the entity is not in the snapshot PVS - if ( !( snapshot->pvs[ent->entityNumber >> 5] & ( 1 << ( ent->entityNumber & 31 ) ) ) ) { - if ( ent->PhysicsTeamInPVS( pvsHandle ) ) { - if ( ent->entityNumber >= MAX_CLIENTS && ent->entityNumber < mapSpawnCount ) { - // server says it's not in PVS, client says it's in PVS - // if that happens on map entities, most likely something is wrong - // I can see that moving pieces along several PVS could be a legit situation though - // this is a band aid, which means something is not done right elsewhere - common->DWarning( "client thinks map entity 0x%x (%s) is stale, sequence 0x%x", ent->entityNumber, ent->name.c_str(), sequence ); - } else { - ent->FreeModelDef(); - ent->UpdateVisuals(); - ent->GetPhysics()->UnlinkClip(); - } - } - continue; - } - - // add the entity to the snapshot list - ent->snapshotNode.AddToEnd( snapshotEntities ); - ent->snapshotSequence = sequence; - ent->snapshotBits = 0; - - base = clientEntityStates[clientNum][ent->entityNumber]; - if ( !base ) { - // entity has probably fl.networkSync set to false - continue; - } - - base->state.BeginReading(); - - deltaMsg.Init( &base->state, NULL, (const idBitMsg *)NULL ); - - spawnId = deltaMsg.ReadBits( 32 - GENTITYNUM_BITS ); - typeNum = deltaMsg.ReadBits( idClass::GetTypeNumBits() ); - entityDefNumber = deltaMsg.ReadBits( entityDefBits ); - - typeInfo = idClass::GetType( typeNum ); - - // if the entity is not the right type - if ( !typeInfo || ent->GetType()->typeNum != typeNum || ent->entityDefNumber != entityDefNumber ) { - // should never happen - it does though. with != entityDefNumber only? - common->DWarning( "entity '%s' is not the right type %p 0x%d 0x%x 0x%x 0x%x", ent->GetName(), typeInfo, ent->GetType()->typeNum, typeNum, ent->entityDefNumber, entityDefNumber ); - continue; - } - - // read the class specific data from the base state - ent->ReadFromSnapshot( deltaMsg ); - } - - // free the PVS - pvs.FreeCurrentPVS( pvsHandle ); - - // read the game and player state from the snapshot - base = clientEntityStates[clientNum][ENTITYNUM_NONE]; // ENTITYNUM_NONE is used for the game and player state - if ( base ) { - base->state.BeginReading(); - } - newBase = entityStateAllocator.Alloc(); - newBase->entityNumber = ENTITYNUM_NONE; - newBase->next = snapshot->firstEntityState; - snapshot->firstEntityState = newBase; - newBase->state.Init( newBase->stateBuf, sizeof( newBase->stateBuf ) ); - newBase->state.BeginWriting(); - deltaMsg.Init( base ? &base->state : NULL, &newBase->state, &msg ); - if ( player->spectating && player->spectator != player->entityNumber && gameLocal.entities[ player->spectator ] && gameLocal.entities[ player->spectator ]->IsType( idPlayer::Type ) ) { - static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->ReadPlayerStateFromSnapshot( deltaMsg ); - weap = static_cast< idPlayer * >( gameLocal.entities[ player->spectator ] )->weapon.GetEntity(); - if ( weap && ( weap->GetRenderEntity()->bounds[0] == weap->GetRenderEntity()->bounds[1] ) ) { - // update the weapon's viewmodel bounds so that the model doesn't flicker in the spectator's view - weap->GetAnimator()->GetBounds( gameLocal.time, weap->GetRenderEntity()->bounds ); - weap->UpdateVisuals(); - } - } else { - player->ReadPlayerStateFromSnapshot( deltaMsg ); - } - ReadGameStateFromSnapshot( deltaMsg ); - - // visualize the snapshot - ClientShowSnapshot( clientNum ); - - // process entity events - ClientProcessEntityNetworkEventQueue(); -} - -/* -================ -idGameLocal::ClientApplySnapshot -================ -*/ -bool idGameLocal::ClientApplySnapshot( int clientNum, int sequence ) { - return ApplySnapshot( clientNum, sequence ); -} - -/* -================ -idGameLocal::ClientProcessEntityNetworkEventQueue -================ -*/ -void idGameLocal::ClientProcessEntityNetworkEventQueue( void ) { - idEntity *ent; - entityNetEvent_t *event; - idBitMsg eventMsg; - - while( eventQueue.Start() ) { - event = eventQueue.Start(); - - // only process forward, in order - if ( event->time > time ) { - break; - } - - idEntityPtr< idEntity > entPtr; - - if( !entPtr.SetSpawnId( event->spawnId ) ) { - if( !gameLocal.entities[ event->spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) { - // if new entity exists in this position, silently ignore - NetworkEventWarning( event, "Entity does not exist any longer, or has not been spawned yet." ); - } - } else { - ent = entPtr.GetEntity(); - assert( ent ); - - eventMsg.Init( event->paramsBuf, sizeof( event->paramsBuf ) ); - eventMsg.SetSize( event->paramsSize ); - eventMsg.BeginReading(); - if ( !ent->ClientReceiveEvent( event->event, event->time, eventMsg ) ) { - NetworkEventWarning( event, "unknown event" ); - } - } - - entityNetEvent_t* freedEvent = eventQueue.Dequeue(); - assert( freedEvent == event ); - eventQueue.Free( event ); - } -} - -/* -================ -idGameLocal::ClientProcessReliableMessage -================ -*/ -void idGameLocal::ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) { - int id, line; - idPlayer *p; - idDict backupSI; - - InitLocalClient( clientNum ); - - id = msg.ReadByte(); - switch( id ) { - case GAME_RELIABLE_MESSAGE_INIT_DECL_REMAP: { - InitClientDeclRemap( clientNum ); - break; - } - case GAME_RELIABLE_MESSAGE_REMAP_DECL: { - int type, index; - char name[MAX_STRING_CHARS]; - - type = msg.ReadByte(); - index = msg.ReadLong(); - msg.ReadString( name, sizeof( name ) ); - - const idDecl *decl = declManager->FindType( (declType_t)type, name, false ); - if ( decl != NULL ) { - if ( index >= clientDeclRemap[clientNum][type].Num() ) { - clientDeclRemap[clientNum][type].AssureSize( index + 1, -1 ); - } - clientDeclRemap[clientNum][type][index] = decl->Index(); - } - break; - } - case GAME_RELIABLE_MESSAGE_SPAWN_PLAYER: { - int client = msg.ReadByte(); - int spawnId = msg.ReadLong(); - if ( !entities[ client ] ) { - SpawnPlayer( client ); - entities[ client ]->FreeModelDef(); - } - // fix up the spawnId to match what the server says - // otherwise there is going to be a bogus delete/new of the client entity in the first ClientReadFromSnapshot - spawnIds[ client ] = spawnId; - break; - } - case GAME_RELIABLE_MESSAGE_DELETE_ENT: { - int spawnId = msg.ReadBits( 32 ); - idEntityPtr< idEntity > entPtr; - if( !entPtr.SetSpawnId( spawnId ) ) { - break; - } - delete entPtr.GetEntity(); - break; - } - case GAME_RELIABLE_MESSAGE_CHAT: - case GAME_RELIABLE_MESSAGE_TCHAT: { // (client should never get a TCHAT though) - char name[128]; - char text[128]; - msg.ReadString( name, sizeof( name ) ); - msg.ReadString( text, sizeof( text ) ); - mpGame.AddChatLine( "%s^0: %s\n", name, text ); - break; - } - case GAME_RELIABLE_MESSAGE_SOUND_EVENT: { - snd_evt_t snd_evt = (snd_evt_t)msg.ReadByte(); - mpGame.PlayGlobalSound( -1, snd_evt ); - break; - } - case GAME_RELIABLE_MESSAGE_SOUND_INDEX: { - int index = gameLocal.ClientRemapDecl( DECL_SOUND, msg.ReadLong() ); - if ( index >= 0 && index < declManager->GetNumDecls( DECL_SOUND ) ) { - const idSoundShader *shader = declManager->SoundByIndex( index ); - mpGame.PlayGlobalSound( -1, SND_COUNT, shader->GetName() ); - } - break; - } - case GAME_RELIABLE_MESSAGE_DB: { - idMultiplayerGame::msg_evt_t msg_evt = (idMultiplayerGame::msg_evt_t)msg.ReadByte(); - int parm1, parm2; - parm1 = msg.ReadByte( ); - parm2 = msg.ReadByte( ); - mpGame.PrintMessageEvent( -1, msg_evt, parm1, parm2 ); - break; - } - case GAME_RELIABLE_MESSAGE_EVENT: { - entityNetEvent_t *event; - - // allocate new event - event = eventQueue.Alloc(); - eventQueue.Enqueue( event, idEventQueue::OUTOFORDER_IGNORE ); - - event->spawnId = msg.ReadBits( 32 ); - event->event = msg.ReadByte(); - event->time = msg.ReadLong(); - - event->paramsSize = msg.ReadBits( idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); - if ( event->paramsSize ) { - if ( event->paramsSize > MAX_EVENT_PARAM_SIZE ) { - NetworkEventWarning( event, "invalid param size" ); - return; - } - msg.ReadByteAlign(); - msg.ReadData( event->paramsBuf, event->paramsSize ); - } - break; - } - case GAME_RELIABLE_MESSAGE_SERVERINFO: { - idDict info; - msg.ReadDeltaDict( info, NULL ); - gameLocal.SetServerInfo( info ); - break; - } - case GAME_RELIABLE_MESSAGE_RESTART: { - MapRestart(); - break; - } - case GAME_RELIABLE_MESSAGE_TOURNEYLINE: { - line = msg.ReadByte( ); - p = static_cast< idPlayer * >( entities[ clientNum ] ); - if ( !p ) { - break; - } - p->tourneyLine = line; - break; - } - case GAME_RELIABLE_MESSAGE_STARTVOTE: { - char voteString[ MAX_STRING_CHARS ]; - int clientNum = msg.ReadByte( ); - msg.ReadString( voteString, sizeof( voteString ) ); - mpGame.ClientStartVote( clientNum, voteString ); - break; - } - case GAME_RELIABLE_MESSAGE_UPDATEVOTE: { - int result = msg.ReadByte( ); - int yesCount = msg.ReadByte( ); - int noCount = msg.ReadByte( ); - mpGame.ClientUpdateVote( (idMultiplayerGame::vote_result_t)result, yesCount, noCount ); - break; - } - case GAME_RELIABLE_MESSAGE_PORTALSTATES: { - int numPortals = msg.ReadLong(); - assert( numPortals == gameRenderWorld->NumPortals() ); - for ( int i = 0; i < numPortals; i++ ) { - gameRenderWorld->SetPortalState( (qhandle_t) (i+1), msg.ReadBits( NUM_RENDER_PORTAL_BITS ) ); - } - break; - } - case GAME_RELIABLE_MESSAGE_PORTAL: { - qhandle_t portal = msg.ReadLong(); - int blockingBits = msg.ReadBits( NUM_RENDER_PORTAL_BITS ); - assert( portal > 0 && portal <= gameRenderWorld->NumPortals() ); - gameRenderWorld->SetPortalState( portal, blockingBits ); - break; - } - case GAME_RELIABLE_MESSAGE_STARTSTATE: { - mpGame.ClientReadStartState( msg ); - break; - } - case GAME_RELIABLE_MESSAGE_WARMUPTIME: { - mpGame.ClientReadWarmupTime( msg ); - break; - } - default: { - Error( "Unknown server->client reliable message: %d", id ); - break; - } - } -} - -/* -================ -idGameLocal::ClientPrediction -================ -*/ -gameReturn_t idGameLocal::ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ) { - idEntity *ent; - idPlayer *player; - gameReturn_t ret; - - ret.sessionCommand[ 0 ] = '\0'; - - player = static_cast( entities[clientNum] ); - if ( !player ) { - return ret; - } - - // check for local client lag - if ( networkSystem->ClientGetTimeSinceLastPacket() >= net_clientMaxPrediction.GetInteger() ) { - player->isLagged = true; - } else { - player->isLagged = false; - } - - InitLocalClient( clientNum ); - - // update the game time - framenum++; - previousTime = time; - time += msec; - - // update the real client time and the new frame flag - if ( time > realClientTime ) { - realClientTime = time; - isNewFrame = true; - } else { - isNewFrame = false; - } - - // set the user commands for this frame - memcpy( usercmds, clientCmds, numClients * sizeof( usercmds[ 0 ] ) ); - - // run prediction on all entities from the last snapshot - for( ent = snapshotEntities.Next(); ent != NULL; ent = ent->snapshotNode.Next() ) { - ent->thinkFlags |= TH_PHYSICS; - ent->ClientPredictionThink(); - } - - // service any pending events - idEvent::ServiceEvents(); - - // show any debug info for this frame - if ( isNewFrame ) { - RunDebugInfo(); - D_DrawDebugLines(); - } - - if ( sessionCommand.Length() ) { - strncpy( ret.sessionCommand, sessionCommand, sizeof( ret.sessionCommand ) ); - } - return ret; -} - -/* -=============== -idGameLocal::Tokenize -=============== -*/ -void idGameLocal::Tokenize( idStrList &out, const char *in ) { - char buf[ MAX_STRING_CHARS ]; - char *token, *next; - - idStr::Copynz( buf, in, MAX_STRING_CHARS ); - token = buf; - next = strchr( token, ';' ); - while ( token ) { - if ( next ) { - *next = '\0'; - } - idStr::ToLower( token ); - out.Append( token ); - if ( next ) { - token = next + 1; - next = strchr( token, ';' ); - } else { - token = NULL; - } - } -} - -/* -=============== -idGameLocal::DownloadRequest -=============== -*/ -bool idGameLocal::DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) { - if ( !cvarSystem->GetCVarInteger( "net_serverDownload" ) ) { - return false; - } - if ( cvarSystem->GetCVarInteger( "net_serverDownload" ) == 1 ) { - // 1: single URL redirect - if ( !strlen( cvarSystem->GetCVarString( "si_serverURL" ) ) ) { - common->Warning( "si_serverURL not set" ); - return false; - } - idStr::snPrintf( urls, MAX_STRING_CHARS, "1;%s", cvarSystem->GetCVarString( "si_serverURL" ) ); - return true; - } else { - // 2: table of pak URLs - // first token is the game pak if request, empty if not requested by the client - // there may be empty tokens for paks the server couldn't pinpoint - the order matters - idStr reply = "2;"; - idStrList dlTable, pakList; - int i, j; - - Tokenize( dlTable, cvarSystem->GetCVarString( "net_serverDlTable" ) ); - Tokenize( pakList, paks ); - - for ( i = 0; i < pakList.Num(); i++ ) { - if ( i > 0 ) { - reply += ";"; - } - if ( pakList[ i ][ 0 ] == '\0' ) { - if ( i == 0 ) { - // pak 0 will always miss when client doesn't ask for game bin - common->DPrintf( "no game pak request\n" ); - } else { - common->DPrintf( "no pak %d\n", i ); - } - continue; - } - for ( j = 0; j < dlTable.Num(); j++ ) { - if ( !fileSystem->FilenameCompare( pakList[ i ], dlTable[ j ] ) ) { - break; - } - } - if ( j == dlTable.Num() ) { - common->Printf( "download for %s: pak not matched: %s\n", IP, pakList[ i ].c_str() ); - } else { - idStr url = cvarSystem->GetCVarString( "net_serverDlBaseURL" ); - url.AppendPath( dlTable[ j ] ); - reply += url; - common->DPrintf( "download for %s: %s\n", IP, url.c_str() ); - } - } - - idStr::Copynz( urls, reply, MAX_STRING_CHARS ); - return true; - } -// return false; -} - -/* -=============== -idEventQueue::Alloc -=============== -*/ -entityNetEvent_t* idEventQueue::Alloc() { - entityNetEvent_t* event = eventAllocator.Alloc(); - event->prev = NULL; - event->next = NULL; - return event; -} - -/* -=============== -idEventQueue::Free -=============== -*/ -void idEventQueue::Free( entityNetEvent_t *event ) { - // should only be called on an unlinked event! - assert( !event->next && !event->prev ); - eventAllocator.Free( event ); -} - -/* -=============== -idEventQueue::Shutdown -=============== -*/ -void idEventQueue::Shutdown() { - eventAllocator.Shutdown(); - this->Init(); -} - -/* -=============== -idEventQueue::Init -=============== -*/ -void idEventQueue::Init( void ) { - start = NULL; - end = NULL; -} - -/* -=============== -idEventQueue::Dequeue -=============== -*/ -entityNetEvent_t* idEventQueue::Dequeue( void ) { - entityNetEvent_t* event = start; - if ( !event ) { - return NULL; - } - - start = start->next; - - if ( !start ) { - end = NULL; - } else { - start->prev = NULL; - } - - event->next = NULL; - event->prev = NULL; - - return event; -} - -/* -=============== -idEventQueue::RemoveLast -=============== -*/ -entityNetEvent_t* idEventQueue::RemoveLast( void ) { - entityNetEvent_t *event = end; - if ( !event ) { - return NULL; - } - - end = event->prev; - - if ( !end ) { - start = NULL; - } else { - end->next = NULL; - } - - event->next = NULL; - event->prev = NULL; - - return event; -} - -/* -=============== -idEventQueue::Enqueue -=============== -*/ -void idEventQueue::Enqueue( entityNetEvent_t *event, outOfOrderBehaviour_t behaviour ) { - if ( behaviour == OUTOFORDER_DROP ) { - // go backwards through the queue and determine if there are - // any out-of-order events - while ( end && end->time > event->time ) { - entityNetEvent_t *outOfOrder = RemoveLast(); - common->DPrintf( "WARNING: new event with id %d ( time %d ) caused removal of event with id %d ( time %d ), game time = %d.\n", event->event, event->time, outOfOrder->event, outOfOrder->time, gameLocal.time ); - Free( outOfOrder ); - } - } else if ( behaviour == OUTOFORDER_SORT && end ) { - // NOT TESTED -- sorting out of order packets hasn't been - // tested yet... wasn't strictly necessary for - // the patch fix. - entityNetEvent_t *cur = end; - // iterate until we find a time < the new event's - while ( cur && cur->time > event->time ) { - cur = cur->prev; - } - if ( !cur ) { - // add to start - event->next = start; - event->prev = NULL; - start = event; - } else { - // insert - event->prev = cur; - event->next = cur->next; - cur->next = event; - } - return; - } - - // add the new event - event->next = NULL; - event->prev = NULL; - - if ( end ) { - end->next = event; - event->prev = end; - } else { - start = event; - } - end = event; -} diff --git a/game/gameedit.cpp b/game/gameedit.cpp deleted file mode 100644 index e4370d804..000000000 --- a/game/gameedit.cpp +++ /dev/null @@ -1,1133 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "emitter.h" - -/* -=============================================================================== - - Ingame cursor. - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idCursor3D ) -END_CLASS - -/* -=============== -idCursor3D::idCursor3D -=============== -*/ -idCursor3D::idCursor3D( void ) { - draggedPosition.Zero(); -} - -/* -=============== -idCursor3D::~idCursor3D -=============== -*/ -idCursor3D::~idCursor3D( void ) { -} - -/* -=============== -idCursor3D::Spawn -=============== -*/ -void idCursor3D::Spawn( void ) { -} - -/* -=============== -idCursor3D::Present -=============== -*/ -void idCursor3D::Present( void ) { - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { - return; - } - BecomeInactive( TH_UPDATEVISUALS ); - - const idVec3 &origin = GetPhysics()->GetOrigin(); - const idMat3 &axis = GetPhysics()->GetAxis(); - - gameRenderWorld->DebugArrow( colorYellow, origin + axis[1] * -5.0f + axis[2] * 5.0f, origin, 2 ); - gameRenderWorld->DebugArrow( colorRed, origin, draggedPosition, 2 ); -} - -/* -=============== -idCursor3D::Think -=============== -*/ -void idCursor3D::Think( void ) { - if ( thinkFlags & TH_THINK ) { - drag.Evaluate( gameLocal.time ); - } - Present(); -} - - -/* -=============================================================================== - - Allows entities to be dragged through the world with physics. - -=============================================================================== -*/ - -#define MAX_DRAG_TRACE_DISTANCE 2048.0f - -/* -============== -idDragEntity::idDragEntity -============== -*/ -idDragEntity::idDragEntity( void ) { - cursor = NULL; - Clear(); -} - -/* -============== -idDragEntity::~idDragEntity -============== -*/ -idDragEntity::~idDragEntity( void ) { - StopDrag(); - selected = NULL; - delete cursor; - cursor = NULL; -} - - -/* -============== -idDragEntity::Clear -============== -*/ -void idDragEntity::Clear() { - dragEnt = NULL; - joint = INVALID_JOINT; - id = 0; - localEntityPoint.Zero(); - localPlayerPoint.Zero(); - bodyName.Clear(); - selected = NULL; -} - -/* -============== -idDragEntity::StopDrag -============== -*/ -void idDragEntity::StopDrag( void ) { - dragEnt = NULL; - if ( cursor ) { - cursor->BecomeInactive( TH_THINK ); - } -} - -/* -============== -idDragEntity::Update -============== -*/ -void idDragEntity::Update( idPlayer *player ) { - idVec3 viewPoint, origin; - idMat3 viewAxis, axis; - trace_t trace; - idEntity *newEnt; - idAngles angles; - jointHandle_t newJoint(INVALID_JOINT); - idStr newBodyName; - - player->GetViewPos( viewPoint, viewAxis ); - - // if no entity selected for dragging - if ( !dragEnt.GetEntity() ) { - - if ( player->usercmd.buttons & BUTTON_ATTACK ) { - - gameLocal.clip.TracePoint( trace, viewPoint, viewPoint + viewAxis[0] * MAX_DRAG_TRACE_DISTANCE, (CONTENTS_SOLID|CONTENTS_RENDERMODEL|CONTENTS_BODY), player ); - if ( trace.fraction < 1.0f ) { - - newEnt = gameLocal.entities[ trace.c.entityNum ]; - if ( newEnt ) { - - // Ish: We sometimes want to select things that are bound - /* - if ( newEnt->GetBindMaster() ) { - if ( newEnt->GetBindJoint() ) { - trace.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( newEnt->GetBindJoint() ); - } else { - trace.c.id = newEnt->GetBindBody(); - } - newEnt = newEnt->GetBindMaster(); - } - */ - - if ( newEnt->IsType( idAFEntity_Base::Type ) && static_cast(newEnt)->IsActiveAF() ) { - idAFEntity_Base *af = static_cast(newEnt); - - // joint being dragged - newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ); - // get the body id from the trace model id which might be a joint handle - trace.c.id = af->BodyForClipModelId( trace.c.id ); - // get the name of the body being dragged - newBodyName = af->GetAFPhysics()->GetBody( trace.c.id )->GetName(); - - } else if ( !newEnt->IsType( idWorldspawn::Type ) ) { - - if ( trace.c.id < 0 ) { - newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ); - } else { - newJoint = INVALID_JOINT; - } - newBodyName = ""; - - } else { - - newJoint = INVALID_JOINT; - newEnt = NULL; - } - } - if ( newEnt ) { - dragEnt = newEnt; - selected = newEnt; - joint = newJoint; - id = trace.c.id; - bodyName = newBodyName; - - if ( !cursor ) { - cursor = ( idCursor3D * )gameLocal.SpawnEntityType( idCursor3D::Type ); - } - - idPhysics *phys = dragEnt.GetEntity()->GetPhysics(); - localPlayerPoint = ( trace.c.point - viewPoint ) * viewAxis.Transpose(); - origin = phys->GetOrigin( id ); - axis = phys->GetAxis( id ); - localEntityPoint = ( trace.c.point - origin ) * axis.Transpose(); - - cursor->drag.Init( g_dragDamping.GetFloat() ); - cursor->drag.SetPhysics( phys, id, localEntityPoint ); - cursor->Show(); - - if ( phys->IsType( idPhysics_AF::Type ) || - phys->IsType( idPhysics_RigidBody::Type ) || - phys->IsType( idPhysics_Monster::Type ) ) { - cursor->BecomeActive( TH_THINK ); - } - } - } - } - } - - // if there is an entity selected for dragging - idEntity *drag = dragEnt.GetEntity(); - if ( drag ) { - - if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) { - StopDrag(); - return; - } - - cursor->SetOrigin( viewPoint + localPlayerPoint * viewAxis ); - cursor->SetAxis( viewAxis ); - - cursor->drag.SetDragPosition( cursor->GetPhysics()->GetOrigin() ); - - renderEntity_t *renderEntity = drag->GetRenderEntity(); - idAnimator *dragAnimator = drag->GetAnimator(); - - if ( joint != INVALID_JOINT && renderEntity && dragAnimator ) { - dragAnimator->GetJointTransform( joint, gameLocal.time, cursor->draggedPosition, axis ); - cursor->draggedPosition = renderEntity->origin + cursor->draggedPosition * renderEntity->axis; - gameRenderWorld->DrawText( va( "%s\n%s\n%s, %s", drag->GetName(), drag->GetType()->classname, dragAnimator->GetJointName( joint ), bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 ); - } else { - cursor->draggedPosition = cursor->GetPhysics()->GetOrigin(); - gameRenderWorld->DrawText( va( "%s\n%s\n%s", drag->GetName(), drag->GetType()->classname, bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 ); - } - } - - // if there is a selected entity - if ( selected.GetEntity() && g_dragShowSelection.GetBool() ) { - // draw the bbox of the selected entity - renderEntity_t *renderEntity = selected.GetEntity()->GetRenderEntity(); - if ( renderEntity ) { - gameRenderWorld->DebugBox( colorYellow, idBox( renderEntity->bounds, renderEntity->origin, renderEntity->axis ) ); - } - } -} - -/* -============== -idDragEntity::SetSelected -============== -*/ -void idDragEntity::SetSelected( idEntity *ent ) { - selected = ent; - StopDrag(); -} - -/* -============== -idDragEntity::DeleteSelected -============== -*/ -void idDragEntity::DeleteSelected( void ) { - delete selected.GetEntity(); - selected = NULL; - StopDrag(); -} - -/* -============== -idDragEntity::BindSelected -============== -*/ -void idDragEntity::BindSelected( void ) { - int num, largestNum; - idLexer lexer; - idToken type, bodyName; - idStr key, value, bindBodyName; - const idKeyValue *kv; - idAFEntity_Base *af; - - af = static_cast(dragEnt.GetEntity()); - - if ( !af || !af->IsType( idAFEntity_Base::Type ) || !af->IsActiveAF() ) { - return; - } - - bindBodyName = af->GetAFPhysics()->GetBody( id )->GetName(); - largestNum = 1; - - // parse all the bind constraints - kv = af->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); - while ( kv ) { - key = kv->GetKey(); - key.Strip( "bindConstraint " ); - if ( sscanf( key, "bind%d", &num ) ) { - if ( num >= largestNum ) { - largestNum = num + 1; - } - } - - lexer.LoadMemory( kv->GetValue(), kv->GetValue().Length(), kv->GetKey() ); - lexer.ReadToken( &type ); - lexer.ReadToken( &bodyName ); - lexer.FreeSource(); - - // if there already exists a bind constraint for this body - if ( bodyName.Icmp( bindBodyName ) == 0 ) { - // delete the bind constraint - af->spawnArgs.Delete( kv->GetKey() ); - kv = NULL; - } - - kv = af->spawnArgs.MatchPrefix( "bindConstraint ", kv ); - } - - sprintf( key, "bindConstraint bind%d", largestNum ); - sprintf( value, "ballAndSocket %s %s", bindBodyName.c_str(), af->GetAnimator()->GetJointName( joint ) ); - - af->spawnArgs.Set( key, value ); - af->spawnArgs.Set( "bind", "worldspawn" ); - af->Bind( gameLocal.world, true ); -} - -/* -============== -idDragEntity::UnbindSelected -============== -*/ -void idDragEntity::UnbindSelected( void ) { - const idKeyValue *kv; - idAFEntity_Base *af; - - af = static_cast(selected.GetEntity()); - - if ( !af || !af->IsType( idAFEntity_Base::Type ) || !af->IsActiveAF() ) { - return; - } - - // unbind the selected entity - af->Unbind(); - - // delete all the bind constraints - kv = selected.GetEntity()->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); - while ( kv ) { - selected.GetEntity()->spawnArgs.Delete( kv->GetKey() ); - kv = selected.GetEntity()->spawnArgs.MatchPrefix( "bindConstraint ", NULL ); - } - - // delete any bind information - af->spawnArgs.Delete( "bind" ); - af->spawnArgs.Delete( "bindToJoint" ); - af->spawnArgs.Delete( "bindToBody" ); -} - - -/* -=============================================================================== - - Handles ingame entity editing. - -=============================================================================== -*/ - -/* -============== -idEditEntities::idEditEntities -============== -*/ -idEditEntities::idEditEntities( void ) { - selectableEntityClasses.Clear(); - nextSelectTime = 0; -} - -/* -============= -idEditEntities::SelectEntity -============= -*/ -bool idEditEntities::SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip ) { - idVec3 end; - idEntity *ent; - - if ( !g_editEntityMode.GetInteger() || selectableEntityClasses.Num() == 0 ) { - return false; - } - - if ( gameLocal.time < nextSelectTime ) { - return true; - } - nextSelectTime = gameLocal.time + 300; - - end = origin + dir * 4096.0f; - - ent = NULL; - for ( int i = 0; i < selectableEntityClasses.Num(); i++ ) { - ent = gameLocal.FindTraceEntity( origin, end, *selectableEntityClasses[i].typeInfo, skip ); - if ( ent ) { - break; - } - } - if ( ent ) { - ClearSelectedEntities(); - if ( EntityIsSelectable( ent ) ) { - AddSelectedEntity( ent ); - gameLocal.Printf( "entity #%d: %s '%s'\n", ent->entityNumber, ent->GetClassname(), ent->name.c_str() ); - ent->ShowEditingDialog(); - return true; - } - } - return false; -} - -/* -============= -idEditEntities::AddSelectedEntity -============= -*/ -void idEditEntities::AddSelectedEntity(idEntity *ent) { - ent->fl.selected = true; - selectedEntities.AddUnique(ent); -} - -/* -============== -idEditEntities::RemoveSelectedEntity -============== -*/ -void idEditEntities::RemoveSelectedEntity( idEntity *ent ) { - if ( selectedEntities.Find( ent ) ) { - selectedEntities.Remove( ent ); - } -} - -/* -============= -idEditEntities::ClearSelectedEntities -============= -*/ -void idEditEntities::ClearSelectedEntities() { - int i, count; - - count = selectedEntities.Num(); - for ( i = 0; i < count; i++ ) { - selectedEntities[i]->fl.selected = false; - } - selectedEntities.Clear(); -} - - -/* -============= -idEditEntities::EntityIsSelectable -============= -*/ -bool idEditEntities::EntityIsSelectable( idEntity *ent, idVec4 *color, idStr *text ) { - for ( int i = 0; i < selectableEntityClasses.Num(); i++ ) { - if ( ent->GetType() == selectableEntityClasses[i].typeInfo ) { - if ( text ) { - *text = selectableEntityClasses[i].textKey; - } - if ( color ) { - if ( ent->fl.selected ) { - *color = colorRed; - } else { - switch( i ) { - case 1 : - *color = colorYellow; - break; - case 2 : - *color = colorBlue; - break; - default: - *color = colorGreen; - } - } - } - return true; - } - } - return false; -} - -/* -============= -idEditEntities::DisplayEntities -============= -*/ -void idEditEntities::DisplayEntities( void ) { - idEntity *ent; - - if ( !gameLocal.GetLocalPlayer() ) { - return; - } - - selectableEntityClasses.Clear(); - selectedTypeInfo_t sit; - - switch( g_editEntityMode.GetInteger() ) { - case 1: - sit.typeInfo = &idLight::Type; - sit.textKey = "texture"; - selectableEntityClasses.Append( sit ); - break; - case 2: - sit.typeInfo = &idSound::Type; - sit.textKey = "s_shader"; - selectableEntityClasses.Append( sit ); - sit.typeInfo = &idLight::Type; - sit.textKey = "texture"; - selectableEntityClasses.Append( sit ); - break; - case 3: - sit.typeInfo = &idAFEntity_Base::Type; - sit.textKey = "articulatedFigure"; - selectableEntityClasses.Append( sit ); - break; - case 4: - sit.typeInfo = &idFuncEmitter::Type; - sit.textKey = "model"; - selectableEntityClasses.Append( sit ); - break; - case 5: - sit.typeInfo = &idAI::Type; - sit.textKey = "name"; - selectableEntityClasses.Append( sit ); - break; - case 6: - sit.typeInfo = &idEntity::Type; - sit.textKey = "name"; - selectableEntityClasses.Append( sit ); - break; - case 7: - sit.typeInfo = &idEntity::Type; - sit.textKey = "model"; - selectableEntityClasses.Append( sit ); - break; - default: - return; - } - - idBounds viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); - idBounds viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); - idMat3 axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); - - viewBounds.ExpandSelf( 512 ); - viewTextBounds.ExpandSelf( 128 ); - - idStr textKey; - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - - idVec4 color; - - textKey = ""; - if ( !EntityIsSelectable( ent, &color, &textKey ) ) { - continue; - } - - bool drawArrows = false; - if ( ent->GetType() == &idAFEntity_Base::Type ) { - if ( !static_cast(ent)->IsActiveAF() ) { - continue; - } - } else if ( ent->GetType() == &idSound::Type ) { - if ( ent->fl.selected ) { - drawArrows = true; - } - const idSoundShader * ss = declManager->FindSound( ent->spawnArgs.GetString( textKey ) ); - if ( ss->HasDefaultSound() || ss->base->GetState() == DS_DEFAULTED ) { - color.Set( 1.0f, 0.0f, 1.0f, 1.0f ); - } - } else if ( ent->GetType() == &idFuncEmitter::Type ) { - if ( ent->fl.selected ) { - drawArrows = true; - } - } - - if ( !viewBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { - continue; - } - - gameRenderWorld->DebugBounds( color, idBounds( ent->GetPhysics()->GetOrigin() ).Expand( 8 ) ); - if ( drawArrows ) { - idVec3 start = ent->GetPhysics()->GetOrigin(); - idVec3 end = start + idVec3( 1, 0, 0 ) * 20.0f; - gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); - gameRenderWorld->DrawText( "x+", end + idVec3( 4, 0, 0 ), 0.15f, colorWhite, axis ); - end = start + idVec3( 1, 0, 0 ) * -20.0f; - gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); - gameRenderWorld->DrawText( "x-", end + idVec3( -4, 0, 0 ), 0.15f, colorWhite, axis ); - end = start + idVec3( 0, 1, 0 ) * +20.0f; - gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); - gameRenderWorld->DrawText( "y+", end + idVec3( 0, 4, 0 ), 0.15f, colorWhite, axis ); - end = start + idVec3( 0, 1, 0 ) * -20.0f; - gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); - gameRenderWorld->DrawText( "y-", end + idVec3( 0, -4, 0 ), 0.15f, colorWhite, axis ); - end = start + idVec3( 0, 0, 1 ) * +20.0f; - gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); - gameRenderWorld->DrawText( "z+", end + idVec3( 0, 0, 4 ), 0.15f, colorWhite, axis ); - end = start + idVec3( 0, 0, 1 ) * -20.0f; - gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); - gameRenderWorld->DrawText( "z-", end + idVec3( 0, 0, -4 ), 0.15f, colorWhite, axis ); - } - - if ( textKey.Length() ) { - const char *text = ent->spawnArgs.GetString( textKey ); - if ( viewTextBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { - gameRenderWorld->DrawText( text, ent->GetPhysics()->GetOrigin() + idVec3(0, 0, 12), 0.25, colorWhite, axis, 1 ); - } - } - } -} - - -/* -=============================================================================== - - idGameEdit - -=============================================================================== -*/ - -idGameEdit gameEditLocal; -idGameEdit * gameEdit = &gameEditLocal; - - -/* -============= -idGameEdit::GetSelectedEntities -============= -*/ -int idGameEdit::GetSelectedEntities( idEntity *list[], int max ) { - int num = 0; - idEntity *ent; - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->fl.selected ) { - list[num++] = ent; - if ( num >= max ) { - break; - } - } - } - return num; -} - -/* -============= -idGameEdit::TriggerSelected -============= -*/ -void idGameEdit::TriggerSelected() { - idEntity *ent; - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->fl.selected ) { - ent->ProcessEvent( &EV_Activate, gameLocal.GetLocalPlayer() ); - } - } -} - -/* -================ -idGameEdit::ClearEntitySelection -================ -*/ -void idGameEdit::ClearEntitySelection() { - idEntity *ent; - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - ent->fl.selected = false; - } - gameLocal.editEntities->ClearSelectedEntities(); -} - -/* -================ -idGameEdit::AddSelectedEntity -================ -*/ -void idGameEdit::AddSelectedEntity( idEntity *ent ) { - if ( ent ) { - gameLocal.editEntities->AddSelectedEntity( ent ); - } -} - -/* -================ -idGameEdit::FindEntityDefDict -================ -*/ -const idDict *idGameEdit::FindEntityDefDict( const char *name, bool makeDefault ) const { - return gameLocal.FindEntityDefDict( name, makeDefault ); -} - -/* -================ -idGameEdit::SpawnEntityDef -================ -*/ -void idGameEdit::SpawnEntityDef( const idDict &args, idEntity **ent ) { - gameLocal.SpawnEntityDef( args, ent ); -} - -/* -================ -idGameEdit::FindEntity -================ -*/ -idEntity *idGameEdit::FindEntity( const char *name ) const { - return gameLocal.FindEntity( name ); -} - -/* -============= -idGameEdit::GetUniqueEntityName - -generates a unique name for a given classname -============= -*/ -const char *idGameEdit::GetUniqueEntityName( const char *classname ) const { - int id; - static char name[1024]; - - // can only have MAX_GENTITIES, so if we have a spot available, we're guaranteed to find one - for( id = 0; id < MAX_GENTITIES; id++ ) { - idStr::snPrintf( name, sizeof( name ), "%s_%d", classname, id ); - if ( !gameLocal.FindEntity( name ) ) { - return name; - } - } - - // id == MAX_GENTITIES + 1, which can't be in use if we get here - idStr::snPrintf( name, sizeof( name ), "%s_%d", classname, id ); - return name; -} - -/* -================ -idGameEdit::EntityGetOrigin -================ -*/ -void idGameEdit::EntityGetOrigin( idEntity *ent, idVec3 &org ) const { - if ( ent ) { - org = ent->GetPhysics()->GetOrigin(); - } -} - -/* -================ -idGameEdit::EntityGetAxis -================ -*/ -void idGameEdit::EntityGetAxis( idEntity *ent, idMat3 &axis ) const { - if ( ent ) { - axis = ent->GetPhysics()->GetAxis(); - } -} - -/* -================ -idGameEdit::EntitySetOrigin -================ -*/ -void idGameEdit::EntitySetOrigin( idEntity *ent, const idVec3 &org ) { - if ( ent ) { - ent->SetOrigin( org ); - } -} - -/* -================ -idGameEdit::EntitySetAxis -================ -*/ -void idGameEdit::EntitySetAxis( idEntity *ent, const idMat3 &axis ) { - if ( ent ) { - ent->SetAxis( axis ); - } -} - -/* -================ -idGameEdit::EntitySetColor -================ -*/ -void idGameEdit::EntitySetColor( idEntity *ent, const idVec3 color ) { - if ( ent ) { - ent->SetColor( color ); - } -} - -/* -================ -idGameEdit::EntityTranslate -================ -*/ -void idGameEdit::EntityTranslate( idEntity *ent, const idVec3 &org ) { - if ( ent ) { - ent->GetPhysics()->Translate( org ); - } -} - -/* -================ -idGameEdit::EntityGetSpawnArgs -================ -*/ -const idDict *idGameEdit::EntityGetSpawnArgs( idEntity *ent ) const { - if ( ent ) { - return &ent->spawnArgs; - } - return NULL; -} - -/* -================ -idGameEdit::EntityUpdateChangeableSpawnArgs -================ -*/ -void idGameEdit::EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict ) { - if ( ent ) { - ent->UpdateChangeableSpawnArgs( dict ); - } -} - -/* -================ -idGameEdit::EntityChangeSpawnArgs -================ -*/ -void idGameEdit::EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs ) { - if ( ent ) { - for ( int i = 0 ; i < newArgs->GetNumKeyVals () ; i ++ ) { - const idKeyValue *kv = newArgs->GetKeyVal( i ); - - if ( kv->GetValue().Length() > 0 ) { - ent->spawnArgs.Set ( kv->GetKey() ,kv->GetValue() ); - } else { - ent->spawnArgs.Delete ( kv->GetKey() ); - } - } - } -} - -/* -================ -idGameEdit::EntityUpdateVisuals -================ -*/ -void idGameEdit::EntityUpdateVisuals( idEntity *ent ) { - if ( ent ) { - ent->UpdateVisuals(); - } -} - -/* -================ -idGameEdit::EntitySetModel -================ -*/ -void idGameEdit::EntitySetModel( idEntity *ent, const char *val ) { - if ( ent ) { - ent->spawnArgs.Set( "model", val ); - ent->SetModel( val ); - } -} - -/* -================ -idGameEdit::EntityStopSound -================ -*/ -void idGameEdit::EntityStopSound( idEntity *ent ) { - if ( ent ) { - ent->StopSound( SND_CHANNEL_ANY, false ); - } -} - -/* -================ -idGameEdit::EntityDelete -================ -*/ -void idGameEdit::EntityDelete( idEntity *ent ) { - delete ent; -} - -/* -================ -idGameEdit::PlayerIsValid -================ -*/ -bool idGameEdit::PlayerIsValid() const { - return ( gameLocal.GetLocalPlayer() != NULL ); -} - -/* -================ -idGameEdit::PlayerGetOrigin -================ -*/ -void idGameEdit::PlayerGetOrigin( idVec3 &org ) const { - org = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(); -} - -/* -================ -idGameEdit::PlayerGetAxis -================ -*/ -void idGameEdit::PlayerGetAxis( idMat3 &axis ) const { - axis = gameLocal.GetLocalPlayer()->GetPhysics()->GetAxis(); -} - -/* -================ -idGameEdit::PlayerGetViewAngles -================ -*/ -void idGameEdit::PlayerGetViewAngles( idAngles &angles ) const { - angles = gameLocal.GetLocalPlayer()->viewAngles; -} - -/* -================ -idGameEdit::PlayerGetEyePosition -================ -*/ -void idGameEdit::PlayerGetEyePosition( idVec3 &org ) const { - org = gameLocal.GetLocalPlayer()->GetEyePosition(); -} - - -/* -================ -idGameEdit::MapGetEntityDict -================ -*/ -const idDict *idGameEdit::MapGetEntityDict( const char *name ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile && name && *name ) { - idMapEntity *mapent = mapFile->FindEntity( name ); - if ( mapent ) { - return &mapent->epairs; - } - } - return NULL; -} - -/* -================ -idGameEdit::MapSave -================ -*/ -void idGameEdit::MapSave( const char *path ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if (mapFile) { - mapFile->Write( (path) ? path : mapFile->GetName(), ".map"); - } -} - -/* -================ -idGameEdit::MapSetEntityKeyVal -================ -*/ -void idGameEdit::MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile && name && *name ) { - idMapEntity *mapent = mapFile->FindEntity( name ); - if ( mapent ) { - mapent->epairs.Set( key, val ); - } - } -} - -/* -================ -idGameEdit::MapCopyDictToEntity -================ -*/ -void idGameEdit::MapCopyDictToEntity( const char *name, const idDict *dict ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile && name && *name ) { - idMapEntity *mapent = mapFile->FindEntity( name ); - if ( mapent ) { - for ( int i = 0; i < dict->GetNumKeyVals(); i++ ) { - const idKeyValue *kv = dict->GetKeyVal( i ); - const char *key = kv->GetKey(); - const char *val = kv->GetValue(); - mapent->epairs.Set( key, val ); - } - } - } -} - - - -/* -================ -idGameEdit::MapGetUniqueMatchingKeyVals -================ -*/ -int idGameEdit::MapGetUniqueMatchingKeyVals( const char *key, const char *list[], int max ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - int count = 0; - if ( mapFile ) { - for ( int i = 0; i < mapFile->GetNumEntities(); i++ ) { - idMapEntity *ent = mapFile->GetEntity( i ); - if ( ent ) { - const char *k = ent->epairs.GetString( key ); - if ( k && *k && count < max ) { - list[count++] = k; - } - } - } - } - return count; -} - -/* -================ -idGameEdit::MapAddEntity -================ -*/ -void idGameEdit::MapAddEntity( const idDict *dict ) const -{ - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile ) { - idMapEntity *ent = new idMapEntity(); - ent->epairs = *dict; - mapFile->AddEntity( ent ); - } -} - -/* -================ -idGameEdit::MapRemoveEntity -================ -*/ -void idGameEdit::MapRemoveEntity( const char *name ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile ) { - idMapEntity *ent = mapFile->FindEntity( name ); - if ( ent ) { - mapFile->RemoveEntity( ent ); - } - } -} - - -/* -================ -idGameEdit::MapGetEntitiesMatchignClassWithString -================ -*/ -int idGameEdit::MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - int count = 0; - if ( mapFile ) { - int entCount = mapFile->GetNumEntities(); - for ( int i = 0 ; i < entCount; i++ ) { - idMapEntity *ent = mapFile->GetEntity(i); - if (ent) { - idStr work = ent->epairs.GetString("classname"); - if ( work.Icmp( classname ) == 0 ) { - if ( match && *match ) { - work = ent->epairs.GetString( "soundgroup" ); - if ( count < max && work.Icmp( match ) == 0 ) { - list[count++] = ent->epairs.GetString( "name" ); - } - } else if ( count < max ) { - list[count++] = ent->epairs.GetString( "name" ); - } - } - } - } - } - return count; -} - - -/* -================ -idGameEdit::MapEntityTranslate -================ -*/ -void idGameEdit::MapEntityTranslate( const char *name, const idVec3 &v ) const { - idMapFile *mapFile = gameLocal.GetLevelMap(); - if ( mapFile && name && *name ) { - idMapEntity *mapent = mapFile->FindEntity( name ); - if ( mapent ) { - idVec3 origin; - mapent->epairs.GetVector( "origin", "", origin ); - origin += v; - mapent->epairs.SetVector( "origin", origin ); - } - } -} diff --git a/game/gameedit.h b/game/gameedit.h deleted file mode 100644 index 067e86d63..000000000 --- a/game/gameedit.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_EDIT_H__ -#define __GAME_EDIT_H__ - - -/* -=============================================================================== - - Ingame cursor. - -=============================================================================== -*/ - -class idCursor3D : public idEntity { -public: - CLASS_PROTOTYPE( idCursor3D ); - - idCursor3D( void ); - ~idCursor3D( void ); - - void Spawn( void ); - void Present( void ); - void Think( void ); - - idForce_Drag drag; - idVec3 draggedPosition; -}; - - -/* -=============================================================================== - - Allows entities to be dragged through the world with physics. - -=============================================================================== -*/ - -class idDragEntity { -public: - idDragEntity( void ); - ~idDragEntity( void ); - - void Clear(); - void Update( idPlayer *player ); - void SetSelected( idEntity *ent ); - idEntity * GetSelected( void ) const { return selected.GetEntity(); } - void DeleteSelected( void ); - void BindSelected( void ); - void UnbindSelected( void ); - -private: - idEntityPtr dragEnt; // entity being dragged - jointHandle_t joint; // joint being dragged - int id; // id of body being dragged - idVec3 localEntityPoint; // dragged point in entity space - idVec3 localPlayerPoint; // dragged point in player space - idStr bodyName; // name of the body being dragged - idCursor3D * cursor; // cursor entity - idEntityPtr selected; // last dragged entity - - void StopDrag( void ); -}; - - -/* -=============================================================================== - - Handles ingame entity editing. - -=============================================================================== -*/ -typedef struct selectedTypeInfo_s { - idTypeInfo *typeInfo; - idStr textKey; -} selectedTypeInfo_t; - -class idEditEntities { -public: - idEditEntities( void ); - bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip ); - void AddSelectedEntity( idEntity *ent ); - void RemoveSelectedEntity( idEntity *ent ); - void ClearSelectedEntities( void ); - void DisplayEntities( void ); - bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL ); -private: - int nextSelectTime; - idList selectableEntityClasses; - idList selectedEntities; -}; - -#endif /* !__GAME_EDIT_H__ */ diff --git a/game/gamesys/Callbacks.cpp b/game/gamesys/Callbacks.cpp new file mode 100644 index 000000000..53eaf8906 --- /dev/null +++ b/game/gamesys/Callbacks.cpp @@ -0,0 +1,2619 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// generated file - see CREATE_EVENT_CODE + + /******************************************************* + + 1 args + + *******************************************************/ + + case 512 : + typedef void ( idClass::*eventCallback_i_t )( const int ); + ( this->*( eventCallback_i_t )callback )( data[ 0 ] ); + break; + + case 513 : + typedef void ( idClass::*eventCallback_f_t )( const float ); + ( this->*( eventCallback_f_t )callback )( *( float * )&data[ 0 ] ); + break; + + /******************************************************* + + 2 args + + *******************************************************/ + + case 1024 : + typedef void ( idClass::*eventCallback_ii_t )( const int, const int ); + ( this->*( eventCallback_ii_t )callback )( data[ 0 ], data[ 1 ] ); + break; + + case 1025 : + typedef void ( idClass::*eventCallback_fi_t )( const float, const int ); + ( this->*( eventCallback_fi_t )callback )( *( float * )&data[ 0 ], data[ 1 ] ); + break; + + case 1026 : + typedef void ( idClass::*eventCallback_if_t )( const int, const float ); + ( this->*( eventCallback_if_t )callback )( data[ 0 ], *( float * )&data[ 1 ] ); + break; + + case 1027 : + typedef void ( idClass::*eventCallback_ff_t )( const float, const float ); + ( this->*( eventCallback_ff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ] ); + break; + + /******************************************************* + + 3 args + + *******************************************************/ + + case 2048 : + typedef void ( idClass::*eventCallback_iii_t )( const int, const int, const int ); + ( this->*( eventCallback_iii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ] ); + break; + + case 2049 : + typedef void ( idClass::*eventCallback_fii_t )( const float, const int, const int ); + ( this->*( eventCallback_fii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ] ); + break; + + case 2050 : + typedef void ( idClass::*eventCallback_ifi_t )( const int, const float, const int ); + ( this->*( eventCallback_ifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ] ); + break; + + case 2051 : + typedef void ( idClass::*eventCallback_ffi_t )( const float, const float, const int ); + ( this->*( eventCallback_ffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ] ); + break; + + case 2052 : + typedef void ( idClass::*eventCallback_iif_t )( const int, const int, const float ); + ( this->*( eventCallback_iif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ] ); + break; + + case 2053 : + typedef void ( idClass::*eventCallback_fif_t )( const float, const int, const float ); + ( this->*( eventCallback_fif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ] ); + break; + + case 2054 : + typedef void ( idClass::*eventCallback_iff_t )( const int, const float, const float ); + ( this->*( eventCallback_iff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ] ); + break; + + case 2055 : + typedef void ( idClass::*eventCallback_fff_t )( const float, const float, const float ); + ( this->*( eventCallback_fff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ] ); + break; + + /******************************************************* + + 4 args + + *******************************************************/ + + case 4096 : + typedef void ( idClass::*eventCallback_iiii_t )( const int, const int, const int, const int ); + ( this->*( eventCallback_iiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); + break; + + case 4097 : + typedef void ( idClass::*eventCallback_fiii_t )( const float, const int, const int, const int ); + ( this->*( eventCallback_fiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); + break; + + case 4098 : + typedef void ( idClass::*eventCallback_ifii_t )( const int, const float, const int, const int ); + ( this->*( eventCallback_ifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ] ); + break; + + case 4099 : + typedef void ( idClass::*eventCallback_ffii_t )( const float, const float, const int, const int ); + ( this->*( eventCallback_ffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ] ); + break; + + case 4100 : + typedef void ( idClass::*eventCallback_iifi_t )( const int, const int, const float, const int ); + ( this->*( eventCallback_iifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); + break; + + case 4101 : + typedef void ( idClass::*eventCallback_fifi_t )( const float, const int, const float, const int ); + ( this->*( eventCallback_fifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); + break; + + case 4102 : + typedef void ( idClass::*eventCallback_iffi_t )( const int, const float, const float, const int ); + ( this->*( eventCallback_iffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); + break; + + case 4103 : + typedef void ( idClass::*eventCallback_fffi_t )( const float, const float, const float, const int ); + ( this->*( eventCallback_fffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); + break; + + case 4104 : + typedef void ( idClass::*eventCallback_iiif_t )( const int, const int, const int, const float ); + ( this->*( eventCallback_iiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4105 : + typedef void ( idClass::*eventCallback_fiif_t )( const float, const int, const int, const float ); + ( this->*( eventCallback_fiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4106 : + typedef void ( idClass::*eventCallback_ifif_t )( const int, const float, const int, const float ); + ( this->*( eventCallback_ifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4107 : + typedef void ( idClass::*eventCallback_ffif_t )( const float, const float, const int, const float ); + ( this->*( eventCallback_ffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4108 : + typedef void ( idClass::*eventCallback_iiff_t )( const int, const int, const float, const float ); + ( this->*( eventCallback_iiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4109 : + typedef void ( idClass::*eventCallback_fiff_t )( const float, const int, const float, const float ); + ( this->*( eventCallback_fiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4110 : + typedef void ( idClass::*eventCallback_ifff_t )( const int, const float, const float, const float ); + ( this->*( eventCallback_ifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); + break; + + case 4111 : + typedef void ( idClass::*eventCallback_ffff_t )( const float, const float, const float, const float ); + ( this->*( eventCallback_ffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); + break; + + /******************************************************* + + 5 args + + *******************************************************/ + + case 8192 : + typedef void ( idClass::*eventCallback_iiiii_t )( const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8193 : + typedef void ( idClass::*eventCallback_fiiii_t )( const float, const int, const int, const int, const int ); + ( this->*( eventCallback_fiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8194 : + typedef void ( idClass::*eventCallback_ifiii_t )( const int, const float, const int, const int, const int ); + ( this->*( eventCallback_ifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8195 : + typedef void ( idClass::*eventCallback_ffiii_t )( const float, const float, const int, const int, const int ); + ( this->*( eventCallback_ffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8196 : + typedef void ( idClass::*eventCallback_iifii_t )( const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8197 : + typedef void ( idClass::*eventCallback_fifii_t )( const float, const int, const float, const int, const int ); + ( this->*( eventCallback_fifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8198 : + typedef void ( idClass::*eventCallback_iffii_t )( const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8199 : + typedef void ( idClass::*eventCallback_fffii_t )( const float, const float, const float, const int, const int ); + ( this->*( eventCallback_fffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 8200 : + typedef void ( idClass::*eventCallback_iiifi_t )( const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8201 : + typedef void ( idClass::*eventCallback_fiifi_t )( const float, const int, const int, const float, const int ); + ( this->*( eventCallback_fiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8202 : + typedef void ( idClass::*eventCallback_ififi_t )( const int, const float, const int, const float, const int ); + ( this->*( eventCallback_ififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8203 : + typedef void ( idClass::*eventCallback_ffifi_t )( const float, const float, const int, const float, const int ); + ( this->*( eventCallback_ffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8204 : + typedef void ( idClass::*eventCallback_iiffi_t )( const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8205 : + typedef void ( idClass::*eventCallback_fiffi_t )( const float, const int, const float, const float, const int ); + ( this->*( eventCallback_fiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8206 : + typedef void ( idClass::*eventCallback_ifffi_t )( const int, const float, const float, const float, const int ); + ( this->*( eventCallback_ifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8207 : + typedef void ( idClass::*eventCallback_ffffi_t )( const float, const float, const float, const float, const int ); + ( this->*( eventCallback_ffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); + break; + + case 8208 : + typedef void ( idClass::*eventCallback_iiiif_t )( const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8209 : + typedef void ( idClass::*eventCallback_fiiif_t )( const float, const int, const int, const int, const float ); + ( this->*( eventCallback_fiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8210 : + typedef void ( idClass::*eventCallback_ifiif_t )( const int, const float, const int, const int, const float ); + ( this->*( eventCallback_ifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8211 : + typedef void ( idClass::*eventCallback_ffiif_t )( const float, const float, const int, const int, const float ); + ( this->*( eventCallback_ffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8212 : + typedef void ( idClass::*eventCallback_iifif_t )( const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8213 : + typedef void ( idClass::*eventCallback_fifif_t )( const float, const int, const float, const int, const float ); + ( this->*( eventCallback_fifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8214 : + typedef void ( idClass::*eventCallback_iffif_t )( const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8215 : + typedef void ( idClass::*eventCallback_fffif_t )( const float, const float, const float, const int, const float ); + ( this->*( eventCallback_fffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8216 : + typedef void ( idClass::*eventCallback_iiiff_t )( const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8217 : + typedef void ( idClass::*eventCallback_fiiff_t )( const float, const int, const int, const float, const float ); + ( this->*( eventCallback_fiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8218 : + typedef void ( idClass::*eventCallback_ififf_t )( const int, const float, const int, const float, const float ); + ( this->*( eventCallback_ififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8219 : + typedef void ( idClass::*eventCallback_ffiff_t )( const float, const float, const int, const float, const float ); + ( this->*( eventCallback_ffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8220 : + typedef void ( idClass::*eventCallback_iifff_t )( const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8221 : + typedef void ( idClass::*eventCallback_fifff_t )( const float, const int, const float, const float, const float ); + ( this->*( eventCallback_fifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8222 : + typedef void ( idClass::*eventCallback_iffff_t )( const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + case 8223 : + typedef void ( idClass::*eventCallback_fffff_t )( const float, const float, const float, const float, const float ); + ( this->*( eventCallback_fffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); + break; + + /******************************************************* + + 6 args + + *******************************************************/ + + case 16384 : + typedef void ( idClass::*eventCallback_iiiiii_t )( const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16385 : + typedef void ( idClass::*eventCallback_fiiiii_t )( const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_fiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16386 : + typedef void ( idClass::*eventCallback_ifiiii_t )( const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ifiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16387 : + typedef void ( idClass::*eventCallback_ffiiii_t )( const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16388 : + typedef void ( idClass::*eventCallback_iifiii_t )( const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_iifiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16389 : + typedef void ( idClass::*eventCallback_fifiii_t )( const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_fifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16390 : + typedef void ( idClass::*eventCallback_iffiii_t )( const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_iffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16391 : + typedef void ( idClass::*eventCallback_fffiii_t )( const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_fffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16392 : + typedef void ( idClass::*eventCallback_iiifii_t )( const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16393 : + typedef void ( idClass::*eventCallback_fiifii_t )( const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_fiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16394 : + typedef void ( idClass::*eventCallback_ififii_t )( const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ififii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16395 : + typedef void ( idClass::*eventCallback_ffifii_t )( const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16396 : + typedef void ( idClass::*eventCallback_iiffii_t )( const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iiffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16397 : + typedef void ( idClass::*eventCallback_fiffii_t )( const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_fiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16398 : + typedef void ( idClass::*eventCallback_ifffii_t )( const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ifffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16399 : + typedef void ( idClass::*eventCallback_ffffii_t )( const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 16400 : + typedef void ( idClass::*eventCallback_iiiifi_t )( const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16401 : + typedef void ( idClass::*eventCallback_fiiifi_t )( const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_fiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16402 : + typedef void ( idClass::*eventCallback_ifiifi_t )( const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ifiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16403 : + typedef void ( idClass::*eventCallback_ffiifi_t )( const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16404 : + typedef void ( idClass::*eventCallback_iififi_t )( const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_iififi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16405 : + typedef void ( idClass::*eventCallback_fififi_t )( const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_fififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16406 : + typedef void ( idClass::*eventCallback_iffifi_t )( const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_iffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16407 : + typedef void ( idClass::*eventCallback_fffifi_t )( const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_fffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16408 : + typedef void ( idClass::*eventCallback_iiiffi_t )( const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16409 : + typedef void ( idClass::*eventCallback_fiiffi_t )( const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_fiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16410 : + typedef void ( idClass::*eventCallback_ififfi_t )( const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ififfi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16411 : + typedef void ( idClass::*eventCallback_ffiffi_t )( const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16412 : + typedef void ( idClass::*eventCallback_iifffi_t )( const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_iifffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16413 : + typedef void ( idClass::*eventCallback_fifffi_t )( const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_fifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16414 : + typedef void ( idClass::*eventCallback_iffffi_t )( const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_iffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16415 : + typedef void ( idClass::*eventCallback_fffffi_t )( const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_fffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); + break; + + case 16416 : + typedef void ( idClass::*eventCallback_iiiiif_t )( const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16417 : + typedef void ( idClass::*eventCallback_fiiiif_t )( const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_fiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16418 : + typedef void ( idClass::*eventCallback_ifiiif_t )( const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ifiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16419 : + typedef void ( idClass::*eventCallback_ffiiif_t )( const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16420 : + typedef void ( idClass::*eventCallback_iifiif_t )( const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_iifiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16421 : + typedef void ( idClass::*eventCallback_fifiif_t )( const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_fifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16422 : + typedef void ( idClass::*eventCallback_iffiif_t )( const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_iffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16423 : + typedef void ( idClass::*eventCallback_fffiif_t )( const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_fffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16424 : + typedef void ( idClass::*eventCallback_iiifif_t )( const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16425 : + typedef void ( idClass::*eventCallback_fiifif_t )( const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_fiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16426 : + typedef void ( idClass::*eventCallback_ififif_t )( const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ififif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16427 : + typedef void ( idClass::*eventCallback_ffifif_t )( const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16428 : + typedef void ( idClass::*eventCallback_iiffif_t )( const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iiffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16429 : + typedef void ( idClass::*eventCallback_fiffif_t )( const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_fiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16430 : + typedef void ( idClass::*eventCallback_ifffif_t )( const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ifffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16431 : + typedef void ( idClass::*eventCallback_ffffif_t )( const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16432 : + typedef void ( idClass::*eventCallback_iiiiff_t )( const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16433 : + typedef void ( idClass::*eventCallback_fiiiff_t )( const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_fiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16434 : + typedef void ( idClass::*eventCallback_ifiiff_t )( const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ifiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16435 : + typedef void ( idClass::*eventCallback_ffiiff_t )( const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16436 : + typedef void ( idClass::*eventCallback_iififf_t )( const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_iififf_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16437 : + typedef void ( idClass::*eventCallback_fififf_t )( const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_fififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16438 : + typedef void ( idClass::*eventCallback_iffiff_t )( const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_iffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16439 : + typedef void ( idClass::*eventCallback_fffiff_t )( const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_fffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16440 : + typedef void ( idClass::*eventCallback_iiifff_t )( const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16441 : + typedef void ( idClass::*eventCallback_fiifff_t )( const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_fiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16442 : + typedef void ( idClass::*eventCallback_ififff_t )( const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ififff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16443 : + typedef void ( idClass::*eventCallback_ffifff_t )( const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16444 : + typedef void ( idClass::*eventCallback_iiffff_t )( const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iiffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16445 : + typedef void ( idClass::*eventCallback_fiffff_t )( const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_fiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16446 : + typedef void ( idClass::*eventCallback_ifffff_t )( const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ifffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + case 16447 : + typedef void ( idClass::*eventCallback_ffffff_t )( const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); + break; + + /******************************************************* + + 7 args + + *******************************************************/ + + case 32768 : + typedef void ( idClass::*eventCallback_iiiiiii_t )( const int, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iiiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32769 : + typedef void ( idClass::*eventCallback_fiiiiii_t )( const float, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_fiiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32770 : + typedef void ( idClass::*eventCallback_ifiiiii_t )( const int, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_ifiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32771 : + typedef void ( idClass::*eventCallback_ffiiiii_t )( const float, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_ffiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32772 : + typedef void ( idClass::*eventCallback_iifiiii_t )( const int, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_iifiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32773 : + typedef void ( idClass::*eventCallback_fifiiii_t )( const float, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_fifiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32774 : + typedef void ( idClass::*eventCallback_iffiiii_t )( const int, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_iffiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32775 : + typedef void ( idClass::*eventCallback_fffiiii_t )( const float, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_fffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32776 : + typedef void ( idClass::*eventCallback_iiifiii_t )( const int, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_iiifiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32777 : + typedef void ( idClass::*eventCallback_fiifiii_t )( const float, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_fiifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32778 : + typedef void ( idClass::*eventCallback_ififiii_t )( const int, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_ififiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32779 : + typedef void ( idClass::*eventCallback_ffifiii_t )( const float, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_ffifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32780 : + typedef void ( idClass::*eventCallback_iiffiii_t )( const int, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_iiffiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32781 : + typedef void ( idClass::*eventCallback_fiffiii_t )( const float, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_fiffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32782 : + typedef void ( idClass::*eventCallback_ifffiii_t )( const int, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_ifffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32783 : + typedef void ( idClass::*eventCallback_ffffiii_t )( const float, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_ffffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32784 : + typedef void ( idClass::*eventCallback_iiiifii_t )( const int, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iiiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32785 : + typedef void ( idClass::*eventCallback_fiiifii_t )( const float, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_fiiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32786 : + typedef void ( idClass::*eventCallback_ifiifii_t )( const int, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_ifiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32787 : + typedef void ( idClass::*eventCallback_ffiifii_t )( const float, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_ffiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32788 : + typedef void ( idClass::*eventCallback_iififii_t )( const int, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_iififii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32789 : + typedef void ( idClass::*eventCallback_fififii_t )( const float, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_fififii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32790 : + typedef void ( idClass::*eventCallback_iffifii_t )( const int, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_iffifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32791 : + typedef void ( idClass::*eventCallback_fffifii_t )( const float, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_fffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32792 : + typedef void ( idClass::*eventCallback_iiiffii_t )( const int, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iiiffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32793 : + typedef void ( idClass::*eventCallback_fiiffii_t )( const float, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_fiiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32794 : + typedef void ( idClass::*eventCallback_ififfii_t )( const int, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_ififfii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32795 : + typedef void ( idClass::*eventCallback_ffiffii_t )( const float, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_ffiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32796 : + typedef void ( idClass::*eventCallback_iifffii_t )( const int, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_iifffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32797 : + typedef void ( idClass::*eventCallback_fifffii_t )( const float, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_fifffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32798 : + typedef void ( idClass::*eventCallback_iffffii_t )( const int, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_iffffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32799 : + typedef void ( idClass::*eventCallback_fffffii_t )( const float, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_fffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 32800 : + typedef void ( idClass::*eventCallback_iiiiifi_t )( const int, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iiiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32801 : + typedef void ( idClass::*eventCallback_fiiiifi_t )( const float, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_fiiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32802 : + typedef void ( idClass::*eventCallback_ifiiifi_t )( const int, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_ifiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32803 : + typedef void ( idClass::*eventCallback_ffiiifi_t )( const float, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_ffiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32804 : + typedef void ( idClass::*eventCallback_iifiifi_t )( const int, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_iifiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32805 : + typedef void ( idClass::*eventCallback_fifiifi_t )( const float, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_fifiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32806 : + typedef void ( idClass::*eventCallback_iffiifi_t )( const int, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_iffiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32807 : + typedef void ( idClass::*eventCallback_fffiifi_t )( const float, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_fffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32808 : + typedef void ( idClass::*eventCallback_iiififi_t )( const int, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_iiififi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32809 : + typedef void ( idClass::*eventCallback_fiififi_t )( const float, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_fiififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32810 : + typedef void ( idClass::*eventCallback_ifififi_t )( const int, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_ifififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32811 : + typedef void ( idClass::*eventCallback_ffififi_t )( const float, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_ffififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32812 : + typedef void ( idClass::*eventCallback_iiffifi_t )( const int, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_iiffifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32813 : + typedef void ( idClass::*eventCallback_fiffifi_t )( const float, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_fiffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32814 : + typedef void ( idClass::*eventCallback_ifffifi_t )( const int, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_ifffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32815 : + typedef void ( idClass::*eventCallback_ffffifi_t )( const float, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_ffffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32816 : + typedef void ( idClass::*eventCallback_iiiiffi_t )( const int, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iiiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32817 : + typedef void ( idClass::*eventCallback_fiiiffi_t )( const float, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_fiiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32818 : + typedef void ( idClass::*eventCallback_ifiiffi_t )( const int, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_ifiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32819 : + typedef void ( idClass::*eventCallback_ffiiffi_t )( const float, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_ffiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32820 : + typedef void ( idClass::*eventCallback_iififfi_t )( const int, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_iififfi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32821 : + typedef void ( idClass::*eventCallback_fififfi_t )( const float, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_fififfi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32822 : + typedef void ( idClass::*eventCallback_iffiffi_t )( const int, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_iffiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32823 : + typedef void ( idClass::*eventCallback_fffiffi_t )( const float, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_fffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32824 : + typedef void ( idClass::*eventCallback_iiifffi_t )( const int, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_iiifffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32825 : + typedef void ( idClass::*eventCallback_fiifffi_t )( const float, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_fiifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32826 : + typedef void ( idClass::*eventCallback_ififffi_t )( const int, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_ififffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32827 : + typedef void ( idClass::*eventCallback_ffifffi_t )( const float, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_ffifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32828 : + typedef void ( idClass::*eventCallback_iiffffi_t )( const int, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_iiffffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32829 : + typedef void ( idClass::*eventCallback_fiffffi_t )( const float, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_fiffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32830 : + typedef void ( idClass::*eventCallback_ifffffi_t )( const int, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_ifffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32831 : + typedef void ( idClass::*eventCallback_ffffffi_t )( const float, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_ffffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); + break; + + case 32832 : + typedef void ( idClass::*eventCallback_iiiiiif_t )( const int, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iiiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32833 : + typedef void ( idClass::*eventCallback_fiiiiif_t )( const float, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_fiiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32834 : + typedef void ( idClass::*eventCallback_ifiiiif_t )( const int, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_ifiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32835 : + typedef void ( idClass::*eventCallback_ffiiiif_t )( const float, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_ffiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32836 : + typedef void ( idClass::*eventCallback_iifiiif_t )( const int, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_iifiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32837 : + typedef void ( idClass::*eventCallback_fifiiif_t )( const float, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_fifiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32838 : + typedef void ( idClass::*eventCallback_iffiiif_t )( const int, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_iffiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32839 : + typedef void ( idClass::*eventCallback_fffiiif_t )( const float, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_fffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32840 : + typedef void ( idClass::*eventCallback_iiifiif_t )( const int, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_iiifiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32841 : + typedef void ( idClass::*eventCallback_fiifiif_t )( const float, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_fiifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32842 : + typedef void ( idClass::*eventCallback_ififiif_t )( const int, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_ififiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32843 : + typedef void ( idClass::*eventCallback_ffifiif_t )( const float, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_ffifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32844 : + typedef void ( idClass::*eventCallback_iiffiif_t )( const int, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_iiffiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32845 : + typedef void ( idClass::*eventCallback_fiffiif_t )( const float, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_fiffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32846 : + typedef void ( idClass::*eventCallback_ifffiif_t )( const int, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_ifffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32847 : + typedef void ( idClass::*eventCallback_ffffiif_t )( const float, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_ffffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32848 : + typedef void ( idClass::*eventCallback_iiiifif_t )( const int, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iiiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32849 : + typedef void ( idClass::*eventCallback_fiiifif_t )( const float, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_fiiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32850 : + typedef void ( idClass::*eventCallback_ifiifif_t )( const int, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_ifiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32851 : + typedef void ( idClass::*eventCallback_ffiifif_t )( const float, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_ffiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32852 : + typedef void ( idClass::*eventCallback_iififif_t )( const int, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_iififif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32853 : + typedef void ( idClass::*eventCallback_fififif_t )( const float, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_fififif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32854 : + typedef void ( idClass::*eventCallback_iffifif_t )( const int, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_iffifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32855 : + typedef void ( idClass::*eventCallback_fffifif_t )( const float, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_fffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32856 : + typedef void ( idClass::*eventCallback_iiiffif_t )( const int, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iiiffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32857 : + typedef void ( idClass::*eventCallback_fiiffif_t )( const float, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_fiiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32858 : + typedef void ( idClass::*eventCallback_ififfif_t )( const int, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_ififfif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32859 : + typedef void ( idClass::*eventCallback_ffiffif_t )( const float, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_ffiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32860 : + typedef void ( idClass::*eventCallback_iifffif_t )( const int, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_iifffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32861 : + typedef void ( idClass::*eventCallback_fifffif_t )( const float, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_fifffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32862 : + typedef void ( idClass::*eventCallback_iffffif_t )( const int, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_iffffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32863 : + typedef void ( idClass::*eventCallback_fffffif_t )( const float, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_fffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32864 : + typedef void ( idClass::*eventCallback_iiiiiff_t )( const int, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iiiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32865 : + typedef void ( idClass::*eventCallback_fiiiiff_t )( const float, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_fiiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32866 : + typedef void ( idClass::*eventCallback_ifiiiff_t )( const int, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_ifiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32867 : + typedef void ( idClass::*eventCallback_ffiiiff_t )( const float, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_ffiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32868 : + typedef void ( idClass::*eventCallback_iifiiff_t )( const int, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_iifiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32869 : + typedef void ( idClass::*eventCallback_fifiiff_t )( const float, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_fifiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32870 : + typedef void ( idClass::*eventCallback_iffiiff_t )( const int, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_iffiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32871 : + typedef void ( idClass::*eventCallback_fffiiff_t )( const float, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_fffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32872 : + typedef void ( idClass::*eventCallback_iiififf_t )( const int, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_iiififf_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32873 : + typedef void ( idClass::*eventCallback_fiififf_t )( const float, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_fiififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32874 : + typedef void ( idClass::*eventCallback_ifififf_t )( const int, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_ifififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32875 : + typedef void ( idClass::*eventCallback_ffififf_t )( const float, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_ffififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32876 : + typedef void ( idClass::*eventCallback_iiffiff_t )( const int, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_iiffiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32877 : + typedef void ( idClass::*eventCallback_fiffiff_t )( const float, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_fiffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32878 : + typedef void ( idClass::*eventCallback_ifffiff_t )( const int, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_ifffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32879 : + typedef void ( idClass::*eventCallback_ffffiff_t )( const float, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_ffffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32880 : + typedef void ( idClass::*eventCallback_iiiifff_t )( const int, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iiiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32881 : + typedef void ( idClass::*eventCallback_fiiifff_t )( const float, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_fiiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32882 : + typedef void ( idClass::*eventCallback_ifiifff_t )( const int, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_ifiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32883 : + typedef void ( idClass::*eventCallback_ffiifff_t )( const float, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_ffiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32884 : + typedef void ( idClass::*eventCallback_iififff_t )( const int, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_iififff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32885 : + typedef void ( idClass::*eventCallback_fififff_t )( const float, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_fififff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32886 : + typedef void ( idClass::*eventCallback_iffifff_t )( const int, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_iffifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32887 : + typedef void ( idClass::*eventCallback_fffifff_t )( const float, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_fffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32888 : + typedef void ( idClass::*eventCallback_iiiffff_t )( const int, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iiiffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32889 : + typedef void ( idClass::*eventCallback_fiiffff_t )( const float, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_fiiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32890 : + typedef void ( idClass::*eventCallback_ififfff_t )( const int, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_ififfff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32891 : + typedef void ( idClass::*eventCallback_ffiffff_t )( const float, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_ffiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32892 : + typedef void ( idClass::*eventCallback_iifffff_t )( const int, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_iifffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32893 : + typedef void ( idClass::*eventCallback_fifffff_t )( const float, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_fifffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32894 : + typedef void ( idClass::*eventCallback_iffffff_t )( const int, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_iffffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + case 32895 : + typedef void ( idClass::*eventCallback_fffffff_t )( const float, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_fffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); + break; + + /******************************************************* + + 8 args + + *******************************************************/ + + case 65536 : + typedef void ( idClass::*eventCallback_iiiiiiii_t )( const int, const int, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iiiiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65537 : + typedef void ( idClass::*eventCallback_fiiiiiii_t )( const float, const int, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_fiiiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65538 : + typedef void ( idClass::*eventCallback_ifiiiiii_t )( const int, const float, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_ifiiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65539 : + typedef void ( idClass::*eventCallback_ffiiiiii_t )( const float, const float, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_ffiiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65540 : + typedef void ( idClass::*eventCallback_iifiiiii_t )( const int, const int, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iifiiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65541 : + typedef void ( idClass::*eventCallback_fifiiiii_t )( const float, const int, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_fifiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65542 : + typedef void ( idClass::*eventCallback_iffiiiii_t )( const int, const float, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_iffiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65543 : + typedef void ( idClass::*eventCallback_fffiiiii_t )( const float, const float, const float, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_fffiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65544 : + typedef void ( idClass::*eventCallback_iiifiiii_t )( const int, const int, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_iiifiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65545 : + typedef void ( idClass::*eventCallback_fiifiiii_t )( const float, const int, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_fiifiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65546 : + typedef void ( idClass::*eventCallback_ififiiii_t )( const int, const float, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ififiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65547 : + typedef void ( idClass::*eventCallback_ffifiiii_t )( const float, const float, const int, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ffifiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65548 : + typedef void ( idClass::*eventCallback_iiffiiii_t )( const int, const int, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_iiffiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65549 : + typedef void ( idClass::*eventCallback_fiffiiii_t )( const float, const int, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_fiffiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65550 : + typedef void ( idClass::*eventCallback_ifffiiii_t )( const int, const float, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ifffiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65551 : + typedef void ( idClass::*eventCallback_ffffiiii_t )( const float, const float, const float, const float, const int, const int, const int, const int ); + ( this->*( eventCallback_ffffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65552 : + typedef void ( idClass::*eventCallback_iiiifiii_t )( const int, const int, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_iiiifiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65553 : + typedef void ( idClass::*eventCallback_fiiifiii_t )( const float, const int, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_fiiifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65554 : + typedef void ( idClass::*eventCallback_ifiifiii_t )( const int, const float, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_ifiifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65555 : + typedef void ( idClass::*eventCallback_ffiifiii_t )( const float, const float, const int, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_ffiifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65556 : + typedef void ( idClass::*eventCallback_iififiii_t )( const int, const int, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_iififiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65557 : + typedef void ( idClass::*eventCallback_fififiii_t )( const float, const int, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_fififiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65558 : + typedef void ( idClass::*eventCallback_iffifiii_t )( const int, const float, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_iffifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65559 : + typedef void ( idClass::*eventCallback_fffifiii_t )( const float, const float, const float, const int, const float, const int, const int, const int ); + ( this->*( eventCallback_fffifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65560 : + typedef void ( idClass::*eventCallback_iiiffiii_t )( const int, const int, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_iiiffiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65561 : + typedef void ( idClass::*eventCallback_fiiffiii_t )( const float, const int, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_fiiffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65562 : + typedef void ( idClass::*eventCallback_ififfiii_t )( const int, const float, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_ififfiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65563 : + typedef void ( idClass::*eventCallback_ffiffiii_t )( const float, const float, const int, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_ffiffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65564 : + typedef void ( idClass::*eventCallback_iifffiii_t )( const int, const int, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_iifffiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65565 : + typedef void ( idClass::*eventCallback_fifffiii_t )( const float, const int, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_fifffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65566 : + typedef void ( idClass::*eventCallback_iffffiii_t )( const int, const float, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_iffffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65567 : + typedef void ( idClass::*eventCallback_fffffiii_t )( const float, const float, const float, const float, const float, const int, const int, const int ); + ( this->*( eventCallback_fffffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65568 : + typedef void ( idClass::*eventCallback_iiiiifii_t )( const int, const int, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iiiiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65569 : + typedef void ( idClass::*eventCallback_fiiiifii_t )( const float, const int, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_fiiiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65570 : + typedef void ( idClass::*eventCallback_ifiiifii_t )( const int, const float, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_ifiiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65571 : + typedef void ( idClass::*eventCallback_ffiiifii_t )( const float, const float, const int, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_ffiiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65572 : + typedef void ( idClass::*eventCallback_iifiifii_t )( const int, const int, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iifiifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65573 : + typedef void ( idClass::*eventCallback_fifiifii_t )( const float, const int, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_fifiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65574 : + typedef void ( idClass::*eventCallback_iffiifii_t )( const int, const float, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_iffiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65575 : + typedef void ( idClass::*eventCallback_fffiifii_t )( const float, const float, const float, const int, const int, const float, const int, const int ); + ( this->*( eventCallback_fffiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65576 : + typedef void ( idClass::*eventCallback_iiififii_t )( const int, const int, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_iiififii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65577 : + typedef void ( idClass::*eventCallback_fiififii_t )( const float, const int, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_fiififii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65578 : + typedef void ( idClass::*eventCallback_ifififii_t )( const int, const float, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ifififii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65579 : + typedef void ( idClass::*eventCallback_ffififii_t )( const float, const float, const int, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ffififii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65580 : + typedef void ( idClass::*eventCallback_iiffifii_t )( const int, const int, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_iiffifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65581 : + typedef void ( idClass::*eventCallback_fiffifii_t )( const float, const int, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_fiffifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65582 : + typedef void ( idClass::*eventCallback_ifffifii_t )( const int, const float, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ifffifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65583 : + typedef void ( idClass::*eventCallback_ffffifii_t )( const float, const float, const float, const float, const int, const float, const int, const int ); + ( this->*( eventCallback_ffffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65584 : + typedef void ( idClass::*eventCallback_iiiiffii_t )( const int, const int, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iiiiffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65585 : + typedef void ( idClass::*eventCallback_fiiiffii_t )( const float, const int, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_fiiiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65586 : + typedef void ( idClass::*eventCallback_ifiiffii_t )( const int, const float, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_ifiiffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65587 : + typedef void ( idClass::*eventCallback_ffiiffii_t )( const float, const float, const int, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_ffiiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65588 : + typedef void ( idClass::*eventCallback_iififfii_t )( const int, const int, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iififfii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65589 : + typedef void ( idClass::*eventCallback_fififfii_t )( const float, const int, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_fififfii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65590 : + typedef void ( idClass::*eventCallback_iffiffii_t )( const int, const float, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_iffiffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65591 : + typedef void ( idClass::*eventCallback_fffiffii_t )( const float, const float, const float, const int, const float, const float, const int, const int ); + ( this->*( eventCallback_fffiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65592 : + typedef void ( idClass::*eventCallback_iiifffii_t )( const int, const int, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_iiifffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65593 : + typedef void ( idClass::*eventCallback_fiifffii_t )( const float, const int, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_fiifffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65594 : + typedef void ( idClass::*eventCallback_ififffii_t )( const int, const float, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ififffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65595 : + typedef void ( idClass::*eventCallback_ffifffii_t )( const float, const float, const int, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ffifffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65596 : + typedef void ( idClass::*eventCallback_iiffffii_t )( const int, const int, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_iiffffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65597 : + typedef void ( idClass::*eventCallback_fiffffii_t )( const float, const int, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_fiffffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65598 : + typedef void ( idClass::*eventCallback_ifffffii_t )( const int, const float, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ifffffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65599 : + typedef void ( idClass::*eventCallback_ffffffii_t )( const float, const float, const float, const float, const float, const float, const int, const int ); + ( this->*( eventCallback_ffffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + case 65600 : + typedef void ( idClass::*eventCallback_iiiiiifi_t )( const int, const int, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iiiiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65601 : + typedef void ( idClass::*eventCallback_fiiiiifi_t )( const float, const int, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_fiiiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65602 : + typedef void ( idClass::*eventCallback_ifiiiifi_t )( const int, const float, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_ifiiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65603 : + typedef void ( idClass::*eventCallback_ffiiiifi_t )( const float, const float, const int, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_ffiiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65604 : + typedef void ( idClass::*eventCallback_iifiiifi_t )( const int, const int, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iifiiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65605 : + typedef void ( idClass::*eventCallback_fifiiifi_t )( const float, const int, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_fifiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65606 : + typedef void ( idClass::*eventCallback_iffiiifi_t )( const int, const float, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_iffiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65607 : + typedef void ( idClass::*eventCallback_fffiiifi_t )( const float, const float, const float, const int, const int, const int, const float, const int ); + ( this->*( eventCallback_fffiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65608 : + typedef void ( idClass::*eventCallback_iiifiifi_t )( const int, const int, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_iiifiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65609 : + typedef void ( idClass::*eventCallback_fiifiifi_t )( const float, const int, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_fiifiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65610 : + typedef void ( idClass::*eventCallback_ififiifi_t )( const int, const float, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ififiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65611 : + typedef void ( idClass::*eventCallback_ffifiifi_t )( const float, const float, const int, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ffifiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65612 : + typedef void ( idClass::*eventCallback_iiffiifi_t )( const int, const int, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_iiffiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65613 : + typedef void ( idClass::*eventCallback_fiffiifi_t )( const float, const int, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_fiffiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65614 : + typedef void ( idClass::*eventCallback_ifffiifi_t )( const int, const float, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ifffiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65615 : + typedef void ( idClass::*eventCallback_ffffiifi_t )( const float, const float, const float, const float, const int, const int, const float, const int ); + ( this->*( eventCallback_ffffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65616 : + typedef void ( idClass::*eventCallback_iiiififi_t )( const int, const int, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_iiiififi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65617 : + typedef void ( idClass::*eventCallback_fiiififi_t )( const float, const int, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_fiiififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65618 : + typedef void ( idClass::*eventCallback_ifiififi_t )( const int, const float, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_ifiififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65619 : + typedef void ( idClass::*eventCallback_ffiififi_t )( const float, const float, const int, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_ffiififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65620 : + typedef void ( idClass::*eventCallback_iifififi_t )( const int, const int, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_iifififi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65621 : + typedef void ( idClass::*eventCallback_fifififi_t )( const float, const int, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_fifififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65622 : + typedef void ( idClass::*eventCallback_iffififi_t )( const int, const float, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_iffififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65623 : + typedef void ( idClass::*eventCallback_fffififi_t )( const float, const float, const float, const int, const float, const int, const float, const int ); + ( this->*( eventCallback_fffififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65624 : + typedef void ( idClass::*eventCallback_iiiffifi_t )( const int, const int, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_iiiffifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65625 : + typedef void ( idClass::*eventCallback_fiiffifi_t )( const float, const int, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_fiiffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65626 : + typedef void ( idClass::*eventCallback_ififfifi_t )( const int, const float, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_ififfifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65627 : + typedef void ( idClass::*eventCallback_ffiffifi_t )( const float, const float, const int, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_ffiffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65628 : + typedef void ( idClass::*eventCallback_iifffifi_t )( const int, const int, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_iifffifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65629 : + typedef void ( idClass::*eventCallback_fifffifi_t )( const float, const int, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_fifffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65630 : + typedef void ( idClass::*eventCallback_iffffifi_t )( const int, const float, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_iffffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65631 : + typedef void ( idClass::*eventCallback_fffffifi_t )( const float, const float, const float, const float, const float, const int, const float, const int ); + ( this->*( eventCallback_fffffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65632 : + typedef void ( idClass::*eventCallback_iiiiiffi_t )( const int, const int, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iiiiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65633 : + typedef void ( idClass::*eventCallback_fiiiiffi_t )( const float, const int, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_fiiiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65634 : + typedef void ( idClass::*eventCallback_ifiiiffi_t )( const int, const float, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_ifiiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65635 : + typedef void ( idClass::*eventCallback_ffiiiffi_t )( const float, const float, const int, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_ffiiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65636 : + typedef void ( idClass::*eventCallback_iifiiffi_t )( const int, const int, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iifiiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65637 : + typedef void ( idClass::*eventCallback_fifiiffi_t )( const float, const int, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_fifiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65638 : + typedef void ( idClass::*eventCallback_iffiiffi_t )( const int, const float, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_iffiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65639 : + typedef void ( idClass::*eventCallback_fffiiffi_t )( const float, const float, const float, const int, const int, const float, const float, const int ); + ( this->*( eventCallback_fffiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65640 : + typedef void ( idClass::*eventCallback_iiififfi_t )( const int, const int, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_iiififfi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65641 : + typedef void ( idClass::*eventCallback_fiififfi_t )( const float, const int, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_fiififfi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65642 : + typedef void ( idClass::*eventCallback_ifififfi_t )( const int, const float, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ifififfi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65643 : + typedef void ( idClass::*eventCallback_ffififfi_t )( const float, const float, const int, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ffififfi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65644 : + typedef void ( idClass::*eventCallback_iiffiffi_t )( const int, const int, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_iiffiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65645 : + typedef void ( idClass::*eventCallback_fiffiffi_t )( const float, const int, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_fiffiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65646 : + typedef void ( idClass::*eventCallback_ifffiffi_t )( const int, const float, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ifffiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65647 : + typedef void ( idClass::*eventCallback_ffffiffi_t )( const float, const float, const float, const float, const int, const float, const float, const int ); + ( this->*( eventCallback_ffffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65648 : + typedef void ( idClass::*eventCallback_iiiifffi_t )( const int, const int, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_iiiifffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65649 : + typedef void ( idClass::*eventCallback_fiiifffi_t )( const float, const int, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_fiiifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65650 : + typedef void ( idClass::*eventCallback_ifiifffi_t )( const int, const float, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_ifiifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65651 : + typedef void ( idClass::*eventCallback_ffiifffi_t )( const float, const float, const int, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_ffiifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65652 : + typedef void ( idClass::*eventCallback_iififffi_t )( const int, const int, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_iififffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65653 : + typedef void ( idClass::*eventCallback_fififffi_t )( const float, const int, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_fififffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65654 : + typedef void ( idClass::*eventCallback_iffifffi_t )( const int, const float, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_iffifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65655 : + typedef void ( idClass::*eventCallback_fffifffi_t )( const float, const float, const float, const int, const float, const float, const float, const int ); + ( this->*( eventCallback_fffifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65656 : + typedef void ( idClass::*eventCallback_iiiffffi_t )( const int, const int, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_iiiffffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65657 : + typedef void ( idClass::*eventCallback_fiiffffi_t )( const float, const int, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_fiiffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65658 : + typedef void ( idClass::*eventCallback_ififfffi_t )( const int, const float, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_ififfffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65659 : + typedef void ( idClass::*eventCallback_ffiffffi_t )( const float, const float, const int, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_ffiffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65660 : + typedef void ( idClass::*eventCallback_iifffffi_t )( const int, const int, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_iifffffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65661 : + typedef void ( idClass::*eventCallback_fifffffi_t )( const float, const int, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_fifffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65662 : + typedef void ( idClass::*eventCallback_iffffffi_t )( const int, const float, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_iffffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65663 : + typedef void ( idClass::*eventCallback_fffffffi_t )( const float, const float, const float, const float, const float, const float, const float, const int ); + ( this->*( eventCallback_fffffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); + break; + + case 65664 : + typedef void ( idClass::*eventCallback_iiiiiiif_t )( const int, const int, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iiiiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65665 : + typedef void ( idClass::*eventCallback_fiiiiiif_t )( const float, const int, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_fiiiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65666 : + typedef void ( idClass::*eventCallback_ifiiiiif_t )( const int, const float, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_ifiiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65667 : + typedef void ( idClass::*eventCallback_ffiiiiif_t )( const float, const float, const int, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_ffiiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65668 : + typedef void ( idClass::*eventCallback_iifiiiif_t )( const int, const int, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iifiiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65669 : + typedef void ( idClass::*eventCallback_fifiiiif_t )( const float, const int, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_fifiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65670 : + typedef void ( idClass::*eventCallback_iffiiiif_t )( const int, const float, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_iffiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65671 : + typedef void ( idClass::*eventCallback_fffiiiif_t )( const float, const float, const float, const int, const int, const int, const int, const float ); + ( this->*( eventCallback_fffiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65672 : + typedef void ( idClass::*eventCallback_iiifiiif_t )( const int, const int, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_iiifiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65673 : + typedef void ( idClass::*eventCallback_fiifiiif_t )( const float, const int, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_fiifiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65674 : + typedef void ( idClass::*eventCallback_ififiiif_t )( const int, const float, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ififiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65675 : + typedef void ( idClass::*eventCallback_ffifiiif_t )( const float, const float, const int, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ffifiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65676 : + typedef void ( idClass::*eventCallback_iiffiiif_t )( const int, const int, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_iiffiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65677 : + typedef void ( idClass::*eventCallback_fiffiiif_t )( const float, const int, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_fiffiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65678 : + typedef void ( idClass::*eventCallback_ifffiiif_t )( const int, const float, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ifffiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65679 : + typedef void ( idClass::*eventCallback_ffffiiif_t )( const float, const float, const float, const float, const int, const int, const int, const float ); + ( this->*( eventCallback_ffffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65680 : + typedef void ( idClass::*eventCallback_iiiifiif_t )( const int, const int, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_iiiifiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65681 : + typedef void ( idClass::*eventCallback_fiiifiif_t )( const float, const int, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_fiiifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65682 : + typedef void ( idClass::*eventCallback_ifiifiif_t )( const int, const float, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_ifiifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65683 : + typedef void ( idClass::*eventCallback_ffiifiif_t )( const float, const float, const int, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_ffiifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65684 : + typedef void ( idClass::*eventCallback_iififiif_t )( const int, const int, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_iififiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65685 : + typedef void ( idClass::*eventCallback_fififiif_t )( const float, const int, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_fififiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65686 : + typedef void ( idClass::*eventCallback_iffifiif_t )( const int, const float, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_iffifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65687 : + typedef void ( idClass::*eventCallback_fffifiif_t )( const float, const float, const float, const int, const float, const int, const int, const float ); + ( this->*( eventCallback_fffifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65688 : + typedef void ( idClass::*eventCallback_iiiffiif_t )( const int, const int, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_iiiffiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65689 : + typedef void ( idClass::*eventCallback_fiiffiif_t )( const float, const int, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_fiiffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65690 : + typedef void ( idClass::*eventCallback_ififfiif_t )( const int, const float, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_ififfiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65691 : + typedef void ( idClass::*eventCallback_ffiffiif_t )( const float, const float, const int, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_ffiffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65692 : + typedef void ( idClass::*eventCallback_iifffiif_t )( const int, const int, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_iifffiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65693 : + typedef void ( idClass::*eventCallback_fifffiif_t )( const float, const int, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_fifffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65694 : + typedef void ( idClass::*eventCallback_iffffiif_t )( const int, const float, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_iffffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65695 : + typedef void ( idClass::*eventCallback_fffffiif_t )( const float, const float, const float, const float, const float, const int, const int, const float ); + ( this->*( eventCallback_fffffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65696 : + typedef void ( idClass::*eventCallback_iiiiifif_t )( const int, const int, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iiiiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65697 : + typedef void ( idClass::*eventCallback_fiiiifif_t )( const float, const int, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_fiiiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65698 : + typedef void ( idClass::*eventCallback_ifiiifif_t )( const int, const float, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_ifiiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65699 : + typedef void ( idClass::*eventCallback_ffiiifif_t )( const float, const float, const int, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_ffiiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65700 : + typedef void ( idClass::*eventCallback_iifiifif_t )( const int, const int, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iifiifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65701 : + typedef void ( idClass::*eventCallback_fifiifif_t )( const float, const int, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_fifiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65702 : + typedef void ( idClass::*eventCallback_iffiifif_t )( const int, const float, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_iffiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65703 : + typedef void ( idClass::*eventCallback_fffiifif_t )( const float, const float, const float, const int, const int, const float, const int, const float ); + ( this->*( eventCallback_fffiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65704 : + typedef void ( idClass::*eventCallback_iiififif_t )( const int, const int, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_iiififif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65705 : + typedef void ( idClass::*eventCallback_fiififif_t )( const float, const int, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_fiififif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65706 : + typedef void ( idClass::*eventCallback_ifififif_t )( const int, const float, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ifififif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65707 : + typedef void ( idClass::*eventCallback_ffififif_t )( const float, const float, const int, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ffififif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65708 : + typedef void ( idClass::*eventCallback_iiffifif_t )( const int, const int, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_iiffifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65709 : + typedef void ( idClass::*eventCallback_fiffifif_t )( const float, const int, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_fiffifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65710 : + typedef void ( idClass::*eventCallback_ifffifif_t )( const int, const float, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ifffifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65711 : + typedef void ( idClass::*eventCallback_ffffifif_t )( const float, const float, const float, const float, const int, const float, const int, const float ); + ( this->*( eventCallback_ffffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65712 : + typedef void ( idClass::*eventCallback_iiiiffif_t )( const int, const int, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iiiiffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65713 : + typedef void ( idClass::*eventCallback_fiiiffif_t )( const float, const int, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_fiiiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65714 : + typedef void ( idClass::*eventCallback_ifiiffif_t )( const int, const float, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_ifiiffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65715 : + typedef void ( idClass::*eventCallback_ffiiffif_t )( const float, const float, const int, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_ffiiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65716 : + typedef void ( idClass::*eventCallback_iififfif_t )( const int, const int, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iififfif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65717 : + typedef void ( idClass::*eventCallback_fififfif_t )( const float, const int, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_fififfif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65718 : + typedef void ( idClass::*eventCallback_iffiffif_t )( const int, const float, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_iffiffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65719 : + typedef void ( idClass::*eventCallback_fffiffif_t )( const float, const float, const float, const int, const float, const float, const int, const float ); + ( this->*( eventCallback_fffiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65720 : + typedef void ( idClass::*eventCallback_iiifffif_t )( const int, const int, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_iiifffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65721 : + typedef void ( idClass::*eventCallback_fiifffif_t )( const float, const int, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_fiifffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65722 : + typedef void ( idClass::*eventCallback_ififffif_t )( const int, const float, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ififffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65723 : + typedef void ( idClass::*eventCallback_ffifffif_t )( const float, const float, const int, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ffifffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65724 : + typedef void ( idClass::*eventCallback_iiffffif_t )( const int, const int, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_iiffffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65725 : + typedef void ( idClass::*eventCallback_fiffffif_t )( const float, const int, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_fiffffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65726 : + typedef void ( idClass::*eventCallback_ifffffif_t )( const int, const float, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ifffffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65727 : + typedef void ( idClass::*eventCallback_ffffffif_t )( const float, const float, const float, const float, const float, const float, const int, const float ); + ( this->*( eventCallback_ffffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65728 : + typedef void ( idClass::*eventCallback_iiiiiiff_t )( const int, const int, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iiiiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65729 : + typedef void ( idClass::*eventCallback_fiiiiiff_t )( const float, const int, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_fiiiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65730 : + typedef void ( idClass::*eventCallback_ifiiiiff_t )( const int, const float, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_ifiiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65731 : + typedef void ( idClass::*eventCallback_ffiiiiff_t )( const float, const float, const int, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_ffiiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65732 : + typedef void ( idClass::*eventCallback_iifiiiff_t )( const int, const int, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iifiiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65733 : + typedef void ( idClass::*eventCallback_fifiiiff_t )( const float, const int, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_fifiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65734 : + typedef void ( idClass::*eventCallback_iffiiiff_t )( const int, const float, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_iffiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65735 : + typedef void ( idClass::*eventCallback_fffiiiff_t )( const float, const float, const float, const int, const int, const int, const float, const float ); + ( this->*( eventCallback_fffiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65736 : + typedef void ( idClass::*eventCallback_iiifiiff_t )( const int, const int, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_iiifiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65737 : + typedef void ( idClass::*eventCallback_fiifiiff_t )( const float, const int, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_fiifiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65738 : + typedef void ( idClass::*eventCallback_ififiiff_t )( const int, const float, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ififiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65739 : + typedef void ( idClass::*eventCallback_ffifiiff_t )( const float, const float, const int, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ffifiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65740 : + typedef void ( idClass::*eventCallback_iiffiiff_t )( const int, const int, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_iiffiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65741 : + typedef void ( idClass::*eventCallback_fiffiiff_t )( const float, const int, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_fiffiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65742 : + typedef void ( idClass::*eventCallback_ifffiiff_t )( const int, const float, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ifffiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65743 : + typedef void ( idClass::*eventCallback_ffffiiff_t )( const float, const float, const float, const float, const int, const int, const float, const float ); + ( this->*( eventCallback_ffffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65744 : + typedef void ( idClass::*eventCallback_iiiififf_t )( const int, const int, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_iiiififf_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65745 : + typedef void ( idClass::*eventCallback_fiiififf_t )( const float, const int, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_fiiififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65746 : + typedef void ( idClass::*eventCallback_ifiififf_t )( const int, const float, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_ifiififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65747 : + typedef void ( idClass::*eventCallback_ffiififf_t )( const float, const float, const int, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_ffiififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65748 : + typedef void ( idClass::*eventCallback_iifififf_t )( const int, const int, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_iifififf_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65749 : + typedef void ( idClass::*eventCallback_fifififf_t )( const float, const int, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_fifififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65750 : + typedef void ( idClass::*eventCallback_iffififf_t )( const int, const float, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_iffififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65751 : + typedef void ( idClass::*eventCallback_fffififf_t )( const float, const float, const float, const int, const float, const int, const float, const float ); + ( this->*( eventCallback_fffififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65752 : + typedef void ( idClass::*eventCallback_iiiffiff_t )( const int, const int, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_iiiffiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65753 : + typedef void ( idClass::*eventCallback_fiiffiff_t )( const float, const int, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_fiiffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65754 : + typedef void ( idClass::*eventCallback_ififfiff_t )( const int, const float, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_ififfiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65755 : + typedef void ( idClass::*eventCallback_ffiffiff_t )( const float, const float, const int, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_ffiffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65756 : + typedef void ( idClass::*eventCallback_iifffiff_t )( const int, const int, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_iifffiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65757 : + typedef void ( idClass::*eventCallback_fifffiff_t )( const float, const int, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_fifffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65758 : + typedef void ( idClass::*eventCallback_iffffiff_t )( const int, const float, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_iffffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65759 : + typedef void ( idClass::*eventCallback_fffffiff_t )( const float, const float, const float, const float, const float, const int, const float, const float ); + ( this->*( eventCallback_fffffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65760 : + typedef void ( idClass::*eventCallback_iiiiifff_t )( const int, const int, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iiiiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65761 : + typedef void ( idClass::*eventCallback_fiiiifff_t )( const float, const int, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_fiiiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65762 : + typedef void ( idClass::*eventCallback_ifiiifff_t )( const int, const float, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_ifiiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65763 : + typedef void ( idClass::*eventCallback_ffiiifff_t )( const float, const float, const int, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_ffiiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65764 : + typedef void ( idClass::*eventCallback_iifiifff_t )( const int, const int, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iifiifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65765 : + typedef void ( idClass::*eventCallback_fifiifff_t )( const float, const int, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_fifiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65766 : + typedef void ( idClass::*eventCallback_iffiifff_t )( const int, const float, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_iffiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65767 : + typedef void ( idClass::*eventCallback_fffiifff_t )( const float, const float, const float, const int, const int, const float, const float, const float ); + ( this->*( eventCallback_fffiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65768 : + typedef void ( idClass::*eventCallback_iiififff_t )( const int, const int, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_iiififff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65769 : + typedef void ( idClass::*eventCallback_fiififff_t )( const float, const int, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_fiififff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65770 : + typedef void ( idClass::*eventCallback_ifififff_t )( const int, const float, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ifififff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65771 : + typedef void ( idClass::*eventCallback_ffififff_t )( const float, const float, const int, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ffififff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65772 : + typedef void ( idClass::*eventCallback_iiffifff_t )( const int, const int, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_iiffifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65773 : + typedef void ( idClass::*eventCallback_fiffifff_t )( const float, const int, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_fiffifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65774 : + typedef void ( idClass::*eventCallback_ifffifff_t )( const int, const float, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ifffifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65775 : + typedef void ( idClass::*eventCallback_ffffifff_t )( const float, const float, const float, const float, const int, const float, const float, const float ); + ( this->*( eventCallback_ffffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65776 : + typedef void ( idClass::*eventCallback_iiiiffff_t )( const int, const int, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iiiiffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65777 : + typedef void ( idClass::*eventCallback_fiiiffff_t )( const float, const int, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_fiiiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65778 : + typedef void ( idClass::*eventCallback_ifiiffff_t )( const int, const float, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_ifiiffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65779 : + typedef void ( idClass::*eventCallback_ffiiffff_t )( const float, const float, const int, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_ffiiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65780 : + typedef void ( idClass::*eventCallback_iififfff_t )( const int, const int, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iififfff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65781 : + typedef void ( idClass::*eventCallback_fififfff_t )( const float, const int, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_fififfff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65782 : + typedef void ( idClass::*eventCallback_iffiffff_t )( const int, const float, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_iffiffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65783 : + typedef void ( idClass::*eventCallback_fffiffff_t )( const float, const float, const float, const int, const float, const float, const float, const float ); + ( this->*( eventCallback_fffiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65784 : + typedef void ( idClass::*eventCallback_iiifffff_t )( const int, const int, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_iiifffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65785 : + typedef void ( idClass::*eventCallback_fiifffff_t )( const float, const int, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_fiifffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65786 : + typedef void ( idClass::*eventCallback_ififffff_t )( const int, const float, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ififffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65787 : + typedef void ( idClass::*eventCallback_ffifffff_t )( const float, const float, const int, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ffifffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65788 : + typedef void ( idClass::*eventCallback_iiffffff_t )( const int, const int, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_iiffffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65789 : + typedef void ( idClass::*eventCallback_fiffffff_t )( const float, const int, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_fiffffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65790 : + typedef void ( idClass::*eventCallback_ifffffff_t )( const int, const float, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ifffffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + + case 65791 : + typedef void ( idClass::*eventCallback_ffffffff_t )( const float, const float, const float, const float, const float, const float, const float, const float ); + ( this->*( eventCallback_ffffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); + break; + diff --git a/game/gamesys/Class.cpp b/game/gamesys/Class.cpp new file mode 100644 index 000000000..d2191dae1 --- /dev/null +++ b/game/gamesys/Class.cpp @@ -0,0 +1,1081 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* + +Base class for all C++ objects. Provides fast run-time type checking and run-time +instancing of objects. + +*/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../Grabber.h" + +#include "TypeInfo.h" + + +/*********************************************************************** + + idTypeInfo + +***********************************************************************/ + +// this is the head of a singly linked list of all the idTypes +static idTypeInfo *typelist = NULL; +static idHierarchy classHierarchy; +static int eventCallbackMemory = 0; + +/* +================ +idTypeInfo::idClassType() + +Constructor for class. Should only be called from CLASS_DECLARATION macro. +Handles linking class definition into class hierarchy. This should only happen +at startup as idTypeInfos are statically defined. Since static variables can be +initialized in any order, the constructor must handle the case that subclasses +are initialized before superclasses. +================ +*/ +idTypeInfo::idTypeInfo( const char *classname, const char *superclass, idEventFunc *eventCallbacks, idClass *( *CreateInstance )( void ), + void ( idClass::*Spawn )( void ), void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) ) { + + idTypeInfo *type; + idTypeInfo **insert; + + this->classname = classname; + this->superclass = superclass; + this->eventCallbacks = eventCallbacks; + this->eventMap = NULL; + this->Spawn = Spawn; + this->Save = Save; + this->Restore = Restore; + this->CreateInstance = CreateInstance; + this->super = idClass::GetClass( superclass ); + this->freeEventMap = false; + typeNum = 0; + lastChild = 0; + + // Check if any subclasses were initialized before their superclass + for( type = typelist; type != NULL; type = type->next ) { + if ( ( type->super == NULL ) && !idStr::Cmp( type->superclass, this->classname ) && + idStr::Cmp( type->classname, "idClass" ) ) { + type->super = this; + } + } + + // Insert sorted + for ( insert = &typelist; *insert; insert = &(*insert)->next ) { + assert( idStr::Cmp( classname, (*insert)->classname ) ); + if ( idStr::Cmp( classname, (*insert)->classname ) < 0 ) { + next = *insert; + *insert = this; + break; + } + } + if ( !*insert ) { + *insert = this; + next = NULL; + } +} + +/* +================ +idTypeInfo::~idTypeInfo +================ +*/ +idTypeInfo::~idTypeInfo() { + Shutdown(); +} + +/* +================ +idTypeInfo::Init + +Initializes the event callback table for the class. Creates a +table for fast lookups of event functions. Should only be called once. +================ +*/ +void idTypeInfo::Init( void ) { + idTypeInfo *c; + idEventFunc *def; + int ev; + int i; + bool *set; + int num; + + if ( eventMap ) { + // we've already been initialized by a subclass + return; + } + + // make sure our superclass is initialized first + if ( super && !super->eventMap ) { + super->Init(); + } + + // add to our node hierarchy + if ( super ) { + node.ParentTo( super->node ); + } else { + node.ParentTo( classHierarchy ); + } + node.SetOwner( this ); + + // keep track of the number of children below each class + for( c = super; c != NULL; c = c->super ) { + c->lastChild++; + } + + // if we're not adding any new event callbacks, we can just use our superclass's table + if ( ( !eventCallbacks || !eventCallbacks->event ) && super ) { + eventMap = super->eventMap; + return; + } + + // set a flag so we know to delete the eventMap table + freeEventMap = true; + + // Allocate our new table. It has to have as many entries as there + // are events. NOTE: could save some space by keeping track of the maximum + // event that the class responds to and doing range checking. + num = idEventDef::NumEventCommands(); + eventMap = new eventCallback_t[ num ]; + memset( eventMap, 0, sizeof( eventCallback_t ) * num ); + eventCallbackMemory += sizeof( eventCallback_t ) * num; + + // allocate temporary memory for flags so that the subclass's event callbacks + // override the superclass's event callback + set = new bool[ num ]; + memset( set, 0, sizeof( bool ) * num ); + + // go through the inheritence order and copies the event callback function into + // a list indexed by the event number. This allows fast lookups of + // event functions. + for( c = this; c != NULL; c = c->super ) { + def = c->eventCallbacks; + if ( !def ) { + continue; + } + + // go through each entry until we hit the NULL terminator + for( i = 0; def[ i ].event != NULL; i++ ) { + ev = def[ i ].event->GetEventNum(); + + if ( set[ ev ] ) { + continue; + } + set[ ev ] = true; + eventMap[ ev ] = def[ i ].function; + } + } + + delete[] set; +} + +/* +================ +idTypeInfo::Shutdown + +Should only be called when DLL or EXE is being shutdown. +Although it cleans up any allocated memory, it doesn't bother to remove itself +from the class list since the program is shutting down. +================ +*/ +void idTypeInfo::Shutdown() { + // free up the memory used for event lookups + if ( eventMap ) { + if ( freeEventMap ) { + delete[] eventMap; + } + eventMap = NULL; + } + typeNum = 0; + lastChild = 0; +} + + +/*********************************************************************** + + idClass + +***********************************************************************/ + +const idEventDef EV_Remove( "", NULL ); +const idEventDef EV_SafeRemove( "remove", NULL ); + +ABSTRACT_DECLARATION( NULL, idClass ) + EVENT( EV_Remove, idClass::Event_Remove ) + EVENT( EV_SafeRemove, idClass::Event_SafeRemove ) +END_CLASS + +// alphabetical order +idList idClass::types; +// typenum order +idList idClass::typenums; + +bool idClass::initialized = false; +int idClass::typeNumBits = 0; +int idClass::memused = 0; +int idClass::numobjects = 0; + +/* +================ +idClass::CallSpawn +================ +*/ +void idClass::CallSpawn( void ) { + idTypeInfo *type; + + type = GetType(); + CallSpawnFunc( type ); +} + +/* +================ +idClass::CallSpawnFunc +================ +*/ +classSpawnFunc_t idClass::CallSpawnFunc( idTypeInfo *cls ) { + classSpawnFunc_t func; + + if ( cls->super ) { + func = CallSpawnFunc( cls->super ); + if ( func == cls->Spawn ) { + // don't call the same function twice in a row. + // this can happen when subclasses don't have their own spawn function. + return func; + } + } + + ( this->*cls->Spawn )(); + + return cls->Spawn; +} + +/* +================ +idClass::FindUninitializedMemory +================ +*/ +void idClass::FindUninitializedMemory( void ) { +#ifdef ID_DEBUG_UNINITIALIZED_MEMORY + unsigned long *ptr = ( ( unsigned long * )this ) - 1; + int size = *ptr; + assert( ( size & 3 ) == 0 ); + size >>= 2; + for ( int i = 0; i < size; i++ ) { + if ( ptr[i] == 0xcdcdcdcd ) { + const char *varName = GetTypeVariableName( GetClassname(), i << 2 ); + gameLocal.Warning( "type '%s' has uninitialized variable %s (offset %d)", GetClassname(), varName, i << 2 ); + } + } +#endif +} + +/* +================ +idClass::Spawn +================ +*/ +void idClass::Spawn( void ) { +} + +/* +================ +idClass::~idClass + +Destructor for object. Cancels any events that depend on this object. +================ +*/ +idClass::~idClass() { + idEvent::CancelEvents( this ); +} + +/* +================ +idClass::DisplayInfo_f +================ +*/ +void idClass::DisplayInfo_f( const idCmdArgs &args ) { + gameLocal.Printf( "Class memory status: %i bytes allocated in %i objects\n", memused, numobjects ); +} + +/* +================ +idClass::ListClasses_f +================ +*/ +void idClass::ListClasses_f( const idCmdArgs &args ) { + int i; + idTypeInfo *type; + + gameLocal.Printf( "%-24s %-24s %-6s %-6s\n", "Classname", "Superclass", "Type", "Subclasses" ); + gameLocal.Printf( "----------------------------------------------------------------------\n" ); + + for( i = 0; i < types.Num(); i++ ) { + type = types[ i ]; + gameLocal.Printf( "%-24s %-24s %6d %6d\n", type->classname, type->superclass, type->typeNum, type->lastChild - type->typeNum ); + } + + gameLocal.Printf( "...%d classes", types.Num() ); +} + +/* +================ +idClass::CreateInstance +================ +*/ +idClass *idClass::CreateInstance( const char *name ) { + const idTypeInfo *type; + idClass *obj; + + type = idClass::GetClass( name ); + if ( !type ) { + return NULL; + } + + obj = type->CreateInstance(); + return obj; +} + +/* +================ +idClass::Init + +Should be called after all idTypeInfos are initialized, so must be called +manually upon game code initialization. Tells all the idTypeInfos to initialize +their event callback table for the associated class. This should only be called +once during the execution of the program or DLL. +================ +*/ +void idClass::Init( void ) { + idTypeInfo *c; + int num; + + gameLocal.Printf( "Initializing class hierarchy\n" ); + + if ( initialized ) { + gameLocal.Printf( "...already initialized\n" ); + return; + } + + // init the event callback tables for all the classes + for( c = typelist; c != NULL; c = c->next ) { + c->Init(); + } + + // number the types according to the class hierarchy so we can quickly determine if a class + // is a subclass of another + num = 0; + for( c = classHierarchy.GetNext(); c != NULL; c = c->node.GetNext(), num++ ) { + c->typeNum = num; + c->lastChild += num; + } + + // number of bits needed to send types over network + typeNumBits = idMath::BitsForInteger( num ); + + // create a list of the types so we can do quick lookups + // one list in alphabetical order, one in typenum order + types.SetGranularity( 1 ); + types.SetNum( num ); + typenums.SetGranularity( 1 ); + typenums.SetNum( num ); + num = 0; + for( c = typelist; c != NULL; c = c->next, num++ ) { + types[ num ] = c; + typenums[ c->typeNum ] = c; + } + + initialized = true; + + gameLocal.Printf( "...%i classes, %i bytes for event callbacks\n", types.Num(), eventCallbackMemory ); +} + +/* +================ +idClass::Shutdown +================ +*/ +void idClass::Shutdown( void ) { + idTypeInfo *c; + + for( c = typelist; c != NULL; c = c->next ) { + c->Shutdown(); + } + types.Clear(); + typenums.Clear(); + + initialized = false; +} + +/* +================ +idClass::new +================ +*/ +#ifdef ID_DEBUG_MEMORY +#undef new +#endif + +void * idClass::operator new( size_t s ) { + int *p; + + s += sizeof( int ); + p = (int *)Mem_Alloc( s ); + *p = s; + memused += s; + numobjects++; + +#ifdef ID_DEBUG_UNINITIALIZED_MEMORY + unsigned long *ptr = (unsigned long *)p; + int size = s; + assert( ( size & 3 ) == 0 ); + size >>= 3; + for ( int i = 1; i < size; i++ ) { + ptr[i] = 0xcdcdcdcd; + } +#endif + + return p + 1; +} + +void * idClass::operator new( size_t s, int, int, char *, int ) { + int *p; + + s += sizeof( int ); + p = (int *)Mem_Alloc( s ); + *p = s; + memused += s; + numobjects++; + +#ifdef ID_DEBUG_UNINITIALIZED_MEMORY + unsigned long *ptr = (unsigned long *)p; + int size = s; + assert( ( size & 3 ) == 0 ); + size >>= 3; + for ( int i = 1; i < size; i++ ) { + ptr[i] = 0xcdcdcdcd; + } +#endif + + return p + 1; +} + +#ifdef ID_DEBUG_MEMORY +#define new ID_DEBUG_NEW +#endif + +/* +================ +idClass::delete +================ +*/ +void idClass::operator delete( void *ptr ) { + int *p; + + if ( ptr ) { + p = ( ( int * )ptr ) - 1; + memused -= *p; + numobjects--; + Mem_Free( p ); + } +} + +void idClass::operator delete( void *ptr, int, int, char *, int ) { + int *p; + + if ( ptr ) { + p = ( ( int * )ptr ) - 1; + memused -= *p; + numobjects--; + Mem_Free( p ); + } +} + +/* +================ +idClass::GetClass + +Returns the idTypeInfo for the name of the class passed in. This is a static function +so it must be called as idClass::GetClass( classname ) +================ +*/ +idTypeInfo *idClass::GetClass( const char *name ) { + idTypeInfo *c; + int order; + int mid; + int min; + int max; + + if ( !initialized ) { + // idClass::Init hasn't been called yet, so do a slow lookup + for( c = typelist; c != NULL; c = c->next ) { + if ( !idStr::Cmp( c->classname, name ) ) { + return c; + } + } + } else { + // do a binary search through the list of types + min = 0; + max = types.Num() - 1; + while( min <= max ) { + mid = ( min + max ) / 2; + c = types[ mid ]; + order = idStr::Cmp( c->classname, name ); + if ( !order ) { + return c; + } else if ( order > 0 ) { + max = mid - 1; + } else { + min = mid + 1; + } + } + } + + return NULL; +} + +/* +================ +idClass::GetType +================ +*/ +idTypeInfo *idClass::GetType( const int typeNum ) { + idTypeInfo *c; + + if ( !initialized ) { + for( c = typelist; c != NULL; c = c->next ) { + if ( c->typeNum == typeNum ) { + return c; + } + } + } else if ( ( typeNum >= 0 ) && ( typeNum < types.Num() ) ) { + return typenums[ typeNum ]; + } + + return NULL; +} + +/* +================ +idClass::GetClassname + +Returns the text classname of the object. +================ +*/ +const char *idClass::GetClassname( void ) const { + idTypeInfo *type; + + type = GetType(); + return type->classname; +} + +/* +================ +idClass::GetSuperclass + +Returns the text classname of the superclass. +================ +*/ +const char *idClass::GetSuperclass( void ) const { + idTypeInfo *cls; + + cls = GetType(); + return cls->superclass; +} + +/* +================ +idClass::CancelEvents +================ +*/ +void idClass::CancelEvents( const idEventDef *ev ) { + idEvent::CancelEvents( this, ev ); +} + +/* +================ +idClass::PostEventArgs +================ +*/ +bool idClass::PostEventArgs( const idEventDef *ev, int time, int numargs, ... ) { + idTypeInfo *c; + idEvent *event; + va_list args; + + assert( ev ); + + if ( !idEvent::initialized ) { + return false; + } + + c = GetType(); + if ( !c->eventMap[ ev->GetEventNum() ] ) { + // we don't respond to this event, so ignore it + return false; + } + + // we service events on the client to avoid any bad code filling up the event pool + // we don't want them processed usually, unless when the map is (re)loading. + // we allow threads to run fine, though. + if ( gameLocal.isClient && ( gameLocal.GameState() != GAMESTATE_STARTUP ) && !IsType( idThread::Type ) ) { + return true; + } + + va_start( args, numargs ); + event = idEvent::Alloc( ev, numargs, args ); + va_end( args ); + + event->Schedule( this, c, time ); + + return true; +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time ) { + return PostEventArgs( ev, time, 0 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1 ) { + return PostEventArgs( ev, time, 1, &arg1 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 ) { + return PostEventArgs( ev, time, 2, &arg1, &arg2 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { + return PostEventArgs( ev, time, 3, &arg1, &arg2, &arg3 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { + return PostEventArgs( ev, time, 4, &arg1, &arg2, &arg3, &arg4 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { + return PostEventArgs( ev, time, 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { + return PostEventArgs( ev, time, 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { + return PostEventArgs( ev, time, 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); +} + +/* +================ +idClass::PostEventMS +================ +*/ +bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { + return PostEventArgs( ev, time, 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time ) { + return PostEventArgs( ev, SEC2MS( time ), 0 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1 ) { + return PostEventArgs( ev, SEC2MS( time ), 1, &arg1 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 ) { + return PostEventArgs( ev, SEC2MS( time ), 2, &arg1, &arg2 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { + return PostEventArgs( ev, SEC2MS( time ), 3, &arg1, &arg2, &arg3 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { + return PostEventArgs( ev, SEC2MS( time ), 4, &arg1, &arg2, &arg3, &arg4 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { + return PostEventArgs( ev, SEC2MS( time ), 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { + return PostEventArgs( ev, SEC2MS( time ), 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { + return PostEventArgs( ev, SEC2MS( time ), 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); +} + +/* +================ +idClass::PostEventSec +================ +*/ +bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { + return PostEventArgs( ev, SEC2MS( time ), 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); +} + +/* +================ +idClass::ProcessEventArgs +================ +*/ +bool idClass::ProcessEventArgs( const idEventDef *ev, int numargs, ... ) { + idTypeInfo *c; + int num; + int data[ D_EVENT_MAXARGS ]; + va_list args; + + assert( ev ); + assert( idEvent::initialized ); + + c = GetType(); + num = ev->GetEventNum(); + if ( !c->eventMap[ num ] ) { + // we don't respond to this event, so ignore it + return false; + } + + va_start( args, numargs ); + idEvent::CopyArgs( ev, numargs, args, data ); + va_end( args ); + + ProcessEventArgPtr( ev, data ); + + return true; +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev ) { + return ProcessEventArgs( ev, 0 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1 ) { + return ProcessEventArgs( ev, 1, &arg1 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 ) { + return ProcessEventArgs( ev, 2, &arg1, &arg2 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { + return ProcessEventArgs( ev, 3, &arg1, &arg2, &arg3 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { + return ProcessEventArgs( ev, 4, &arg1, &arg2, &arg3, &arg4 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { + return ProcessEventArgs( ev, 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { + return ProcessEventArgs( ev, 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { + return ProcessEventArgs( ev, 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); +} + +/* +================ +idClass::ProcessEvent +================ +*/ +bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { + return ProcessEventArgs( ev, 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); +} + +/* +================ +idClass::ProcessEventArgPtr +================ +*/ +bool idClass::ProcessEventArgPtr( const idEventDef *ev, int *data ) { + idTypeInfo *c; + int num; + eventCallback_t callback; + + assert( ev ); + assert( idEvent::initialized ); + + if ( g_debugTriggers.GetBool() && ( ev == &EV_Activate ) && IsType( idEntity::Type ) ) { + const idEntity *ent = *reinterpret_cast( data ); + gameLocal.Printf( "%d: '%s' activated by '%s'\n", gameLocal.framenum, static_cast( this )->GetName(), ent ? ent->GetName() : "NULL" ); + } + + c = GetType(); + num = ev->GetEventNum(); + if ( !c->eventMap[ num ] ) { + // we don't respond to this event, so ignore it + return false; + } + + callback = c->eventMap[ num ]; + +#if !CPU_EASYARGS + +/* +on ppc architecture, floats are passed in a seperate set of registers +the function prototypes must have matching float declaration + +http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/2rt_powerpc_abi/chapter_9_section_5.html +*/ + + switch( ev->GetFormatspecIndex() ) { + case 1 << D_EVENT_MAXARGS : + ( this->*callback )(); + break; + +// generated file - see CREATE_EVENT_CODE +#include "Callbacks.cpp" + + default: + gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() ); + break; + } + +#else + + assert( D_EVENT_MAXARGS == 8 ); + + switch( ev->GetNumArgs() ) { + case 0 : + ( this->*callback )(); + break; + + case 1 : + typedef void ( idClass::*eventCallback_1_t )( const int ); + ( this->*( eventCallback_1_t )callback )( data[ 0 ] ); + break; + + case 2 : + typedef void ( idClass::*eventCallback_2_t )( const int, const int ); + ( this->*( eventCallback_2_t )callback )( data[ 0 ], data[ 1 ] ); + break; + + case 3 : + typedef void ( idClass::*eventCallback_3_t )( const int, const int, const int ); + ( this->*( eventCallback_3_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ] ); + break; + + case 4 : + typedef void ( idClass::*eventCallback_4_t )( const int, const int, const int, const int ); + ( this->*( eventCallback_4_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); + break; + + case 5 : + typedef void ( idClass::*eventCallback_5_t )( const int, const int, const int, const int, const int ); + ( this->*( eventCallback_5_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); + break; + + case 6 : + typedef void ( idClass::*eventCallback_6_t )( const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_6_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); + break; + + case 7 : + typedef void ( idClass::*eventCallback_7_t )( const int, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_7_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); + break; + + case 8 : + typedef void ( idClass::*eventCallback_8_t )( const int, const int, const int, const int, const int, const int, const int, const int ); + ( this->*( eventCallback_8_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); + break; + + default: + gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() ); + break; + } + +#endif + + return true; +} + +/* +================ +idClass::Event_Remove +================ +*/ +void idClass::Event_Remove( void ) +{ + // If we are removing a currently frobbed entity, + // set the frob pointers to NULL to avoid stale pointers + idPlayer* player = gameLocal.GetLocalPlayer(); + + if (player != NULL) + { + if (player->m_FrobEntity.GetEntity() == this) + { + player->m_FrobEntity = NULL; + } + } + + CGrabber* grabber = gameLocal.m_Grabber; + if (grabber) + { + // tels: If we remove a currently grabbed entity, + // force the grabber to forget it + idEntity *ent = grabber->GetSelected(); + if (ent == this) + { + grabber->Forget( ent ); + } + } + + delete this; +} + +/* +================ +idClass::Event_SafeRemove +================ +*/ +void idClass::Event_SafeRemove( void ) { + // Forces the remove to be done at a safe time + PostEventMS( &EV_Remove, 0 ); +} diff --git a/game/gamesys/Class.h b/game/gamesys/Class.h new file mode 100644 index 000000000..9aa49f648 --- /dev/null +++ b/game/gamesys/Class.h @@ -0,0 +1,355 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* + +Base class for all game objects. Provides fast run-time type checking and run-time +instancing of objects. + +*/ + +#ifndef __SYS_CLASS_H__ +#define __SYS_CLASS_H__ + +#ifdef __linux__ +#include +#endif + +class idClass; +class idTypeInfo; + +extern const idEventDef EV_Remove; +extern const idEventDef EV_SafeRemove; + +typedef void ( idClass::*eventCallback_t )( void ); + +template< class Type > +struct idEventFunc { + const idEventDef *event; + eventCallback_t function; +}; + +// added & so gcc could compile this +#define EVENT( event, function ) { &( event ), ( void ( idClass::* )( void ) )( &function ) }, +#define END_CLASS { NULL, NULL } }; + + +class idEventArg { +public: + int type; + int value; + + idEventArg() { type = D_EVENT_INTEGER; value = 0; }; + idEventArg( int data ) { type = D_EVENT_INTEGER; value = data; }; + idEventArg( float data ) { type = D_EVENT_FLOAT; value = *reinterpret_cast( &data ); }; + idEventArg( idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast( &data ); }; + idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast( data.c_str() ); }; + idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast( data ); }; + idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast( data ); }; + idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast( data ); }; +}; + +class idAllocError : public idException { +public: + idAllocError( const char *text = "" ) : idException( text ) {} +}; + +/*********************************************************************** + + idClass + +***********************************************************************/ + +/* +================ +CLASS_PROTOTYPE + +This macro must be included in the definition of any subclass of idClass. +It prototypes variables used in class instanciation and type checking. +Use this on single inheritance concrete classes only. +================ +*/ +#define CLASS_PROTOTYPE( nameofclass ) \ +public: \ + static idTypeInfo Type; \ + static idClass *CreateInstance( void ); \ + virtual idTypeInfo *GetType( void ) const; \ + static idEventFunc eventCallbacks[] + +/* +================ +CLASS_DECLARATION + +This macro must be included in the code to properly initialize variables +used in type checking and run-time instanciation. It also defines the list +of events that the class responds to. Take special care to ensure that the +proper superclass is indicated or the run-time type information will be +incorrect. Use this on concrete classes only. +================ +*/ +#define CLASS_DECLARATION( nameofsuperclass, nameofclass ) \ + idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \ + ( idEventFunc * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn, \ + ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \ + idClass *nameofclass::CreateInstance( void ) { \ + try { \ + nameofclass *ptr = new nameofclass; \ + ptr->FindUninitializedMemory(); \ + return ptr; \ + } \ + catch( idAllocError & ) { \ + return NULL; \ + } \ + } \ + idTypeInfo *nameofclass::GetType( void ) const { \ + return &( nameofclass::Type ); \ + } \ +idEventFunc nameofclass::eventCallbacks[] = { + +/* +================ +ABSTRACT_PROTOTYPE + +This macro must be included in the definition of any abstract subclass of idClass. +It prototypes variables used in class instanciation and type checking. +Use this on single inheritance abstract classes only. +================ +*/ +#define ABSTRACT_PROTOTYPE( nameofclass ) \ +public: \ + static idTypeInfo Type; \ + static idClass *CreateInstance( void ); \ + virtual idTypeInfo *GetType( void ) const; \ + static idEventFunc eventCallbacks[] + +/* +================ +ABSTRACT_DECLARATION + +This macro must be included in the code to properly initialize variables +used in type checking. It also defines the list of events that the class +responds to. Take special care to ensure that the proper superclass is +indicated or the run-time tyep information will be incorrect. Use this +on abstract classes only. +================ +*/ +#define ABSTRACT_DECLARATION( nameofsuperclass, nameofclass ) \ + idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \ + ( idEventFunc * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn, \ + ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \ + idClass *nameofclass::CreateInstance( void ) { \ + gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass ); \ + return NULL; \ + } \ + idTypeInfo *nameofclass::GetType( void ) const { \ + return &( nameofclass::Type ); \ + } \ + idEventFunc nameofclass::eventCallbacks[] = { + +typedef void ( idClass::*classSpawnFunc_t )( void ); + +class idSaveGame; +class idRestoreGame; + +class idClass { +public: + ABSTRACT_PROTOTYPE( idClass ); + +#ifdef ID_REDIRECT_NEWDELETE +#undef new +#endif + void * operator new( size_t ); + void * operator new( size_t s, int, int, char *, int ); + void operator delete( void * ); + void operator delete( void *, int, int, char *, int ); +#ifdef ID_REDIRECT_NEWDELETE +#define new ID_DEBUG_NEW +#endif + + virtual ~idClass(); + + void Spawn( void ); + void CallSpawn( void ); + bool IsType( const idTypeInfo &c ) const; + const char * GetClassname( void ) const; + const char * GetSuperclass( void ) const; + void FindUninitializedMemory( void ); + + void Save( idSaveGame *savefile ) const {}; + void Restore( idRestoreGame *savefile ) {}; + + bool RespondsTo( const idEventDef &ev ) const; + + bool PostEventMS( const idEventDef *ev, int time ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); + bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); + + bool PostEventSec( const idEventDef *ev, float time ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); + bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); + + bool ProcessEvent( const idEventDef *ev ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); + bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); + + bool ProcessEventArgPtr( const idEventDef *ev, int *data ); + void CancelEvents( const idEventDef *ev ); + + void Event_Remove( void ); + + // Static functions + static void Init( void ); + static void Shutdown( void ); + static idTypeInfo * GetClass( const char *name ); + static void DisplayInfo_f( const idCmdArgs &args ); + static void ListClasses_f( const idCmdArgs &args ); + static idClass * CreateInstance( const char *name ); + static int GetNumTypes( void ) { return types.Num(); } + static int GetTypeNumBits( void ) { return typeNumBits; } + static idTypeInfo * GetType( int num ); + +private: + classSpawnFunc_t CallSpawnFunc( idTypeInfo *cls ); + + bool PostEventArgs( const idEventDef *ev, int time, int numargs, ... ); + bool ProcessEventArgs( const idEventDef *ev, int numargs, ... ); + + void Event_SafeRemove( void ); + + static bool initialized; + static idList types; + static idList typenums; + static int typeNumBits; + static int memused; + static int numobjects; +}; + +/*********************************************************************** + + idTypeInfo + +***********************************************************************/ + +class idTypeInfo { +public: + const char * classname; + const char * superclass; + idClass * ( *CreateInstance )( void ); + void ( idClass::*Spawn )( void ); + void ( idClass::*Save )( idSaveGame *savefile ) const; + void ( idClass::*Restore )( idRestoreGame *savefile ); + + idEventFunc * eventCallbacks; + eventCallback_t * eventMap; + idTypeInfo * super; + idTypeInfo * next; + bool freeEventMap; + int typeNum; + int lastChild; + + idHierarchy node; + + idTypeInfo( const char *classname, const char *superclass, + idEventFunc *eventCallbacks, idClass *( *CreateInstance )( void ), void ( idClass::*Spawn )( void ), + void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) ); + ~idTypeInfo(); + + void Init( void ); + void Shutdown( void ); + + bool IsType( const idTypeInfo &superclass ) const; + bool RespondsTo( const idEventDef &ev ) const; +}; + +/* +================ +idTypeInfo::IsType + +Checks if the object's class is a subclass of the class defined by the +passed in idTypeInfo. +================ +*/ +ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const { + return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) ); +} + +/* +================ +idTypeInfo::RespondsTo +================ +*/ +ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const { + assert( idEvent::initialized ); + if ( !eventMap[ ev.GetEventNum() ] ) { + // we don't respond to this event + return false; + } + + return true; +} + +/* +================ +idClass::IsType + +Checks if the object's class is a subclass of the class defined by the +passed in idTypeInfo. +================ +*/ +ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const { + idTypeInfo *subclass; + + subclass = GetType(); + return subclass->IsType( superclass ); +} + +/* +================ +idClass::RespondsTo +================ +*/ +ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const { + const idTypeInfo *c; + + assert( idEvent::initialized ); + c = GetType(); + return c->RespondsTo( ev ); +} + +#endif /* !__SYS_CLASS_H__ */ diff --git a/game/gamesys/DebugGraph.cpp b/game/gamesys/DebugGraph.cpp new file mode 100644 index 000000000..c41985f67 --- /dev/null +++ b/game/gamesys/DebugGraph.cpp @@ -0,0 +1,88 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +/* +================ +idDebugGraph::idDebugGraph +================ +*/ +idDebugGraph::idDebugGraph() { + index = 0; +} + +/* +================ +idDebugGraph::SetNumSamples +================ +*/ +void idDebugGraph::SetNumSamples( int num ) { + index = 0; + samples.Clear(); + samples.SetNum( num ); + memset( samples.Ptr(), 0, samples.MemoryUsed() ); +} + +/* +================ +idDebugGraph::AddValue +================ +*/ +void idDebugGraph::AddValue( float value ) { + samples[ index ] = value; + index++; + if ( index >= samples.Num() ) { + index = 0; + } +} + +/* +================ +idDebugGraph::Draw +================ +*/ +void idDebugGraph::Draw( const idVec4 &color, float scale ) const { + int i; + float value1; + float value2; + idVec3 vec1; + idVec3 vec2; + + const idMat3 &axis = gameLocal.GetLocalPlayer()->viewAxis; + const idVec3 pos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + axis[ 1 ] * samples.Num() * 0.5f; + + value1 = samples[ index ] * scale; + for( i = 1; i < samples.Num(); i++ ) { + value2 = samples[ ( i + index ) % samples.Num() ] * scale; + + vec1 = pos + axis[ 2 ] * value1 - axis[ 1 ] * ( i - 1 ) + axis[ 0 ] * samples.Num(); + vec2 = pos + axis[ 2 ] * value2 - axis[ 1 ] * i + axis[ 0 ] * samples.Num(); + + gameRenderWorld->DebugLine( color, vec1, vec2, gameLocal.msec, false ); + value1 = value2; + } +} diff --git a/game/gamesys/DebugGraph.h b/game/gamesys/DebugGraph.h new file mode 100644 index 000000000..d5184310b --- /dev/null +++ b/game/gamesys/DebugGraph.h @@ -0,0 +1,34 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +// DebugGraph.h + +class idDebugGraph { +public: + idDebugGraph(); + void SetNumSamples( int num ); + void AddValue( float value ); + void Draw( const idVec4 &color, float scale ) const; + +private: + idList samples; + int index; +}; diff --git a/game/gamesys/Event.cpp b/game/gamesys/Event.cpp new file mode 100644 index 000000000..295e473c2 --- /dev/null +++ b/game/gamesys/Event.cpp @@ -0,0 +1,870 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* +sys_event.cpp + +Event are used for scheduling tasks and for linking script commands. + +*/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Event.h" +#include "../Game_local.h" + +#define MAX_EVENTSPERFRAME 8192 +//#define CREATE_EVENT_CODE + +/*********************************************************************** + + idEventDef + +***********************************************************************/ + +idEventDef *idEventDef::eventDefList[MAX_EVENTS]; +int idEventDef::numEventDefs = 0; + +static bool eventError = false; +static char eventErrorMsg[ 128 ]; + +/* +================ +idEventDef::idEventDef +================ +*/ +idEventDef::idEventDef( const char *command, const char *formatspec, char returnType ) { + idEventDef *ev; + int i; + unsigned int bits; + + assert( command ); + assert( !idEvent::initialized ); + + // Allow NULL to indicate no args, but always store it as "" + // so we don't have to check for it. + if ( !formatspec ) { + formatspec = ""; + } + + this->name = command; + this->formatspec = formatspec; + this->returnType = returnType; + + numargs = strlen( formatspec ); + assert( numargs <= D_EVENT_MAXARGS ); + if ( numargs > D_EVENT_MAXARGS ) { + eventError = true; + sprintf( eventErrorMsg, "idEventDef::idEventDef : Too many args for '%s' event.", name ); + return; + } + + // make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg + bits = 0; + argsize = 0; + memset( argOffset, 0, sizeof( argOffset ) ); + for( i = 0; i < numargs; i++ ) { + argOffset[ i ] = argsize; + switch( formatspec[ i ] ) { + case D_EVENT_FLOAT : + bits |= 1 << i; + argsize += sizeof( float ); + break; + + case D_EVENT_INTEGER : + argsize += sizeof( int ); + break; + + case D_EVENT_VECTOR : + argsize += sizeof( idVec3 ); + break; + + case D_EVENT_STRING : + argsize += MAX_STRING_LEN; + break; + + case D_EVENT_ENTITY : + argsize += sizeof( idEntityPtr ); + break; + + case D_EVENT_ENTITY_NULL : + argsize += sizeof( idEntityPtr ); + break; + + case D_EVENT_TRACE : + argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool ); + break; + + default : + eventError = true; + sprintf( eventErrorMsg, "idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event.", formatspec, name ); + return; + break; + } + } + + // calculate the formatspecindex + formatspecIndex = ( 1 << ( numargs + D_EVENT_MAXARGS ) ) | bits; + + // go through the list of defined events and check for duplicates + // and mismatched format strings + eventnum = numEventDefs; + for( i = 0; i < eventnum; i++ ) { + ev = eventDefList[ i ]; + if ( strcmp( command, ev->name ) == 0 ) { + if ( strcmp( formatspec, ev->formatspec ) != 0 ) { + eventError = true; + sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s').", + command, formatspec, ev->formatspec ); + return; + } + + if ( ev->returnType != returnType ) { + eventError = true; + sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing return types ('%c'!='%c').", + command, returnType, ev->returnType ); + return; + } + // Don't bother putting the duplicate event in list. + eventnum = ev->eventnum; + return; + } + } + + ev = this; + + if ( numEventDefs >= MAX_EVENTS ) { + eventError = true; + sprintf( eventErrorMsg, "numEventDefs >= MAX_EVENTS" ); + return; + } + eventDefList[numEventDefs] = ev; + numEventDefs++; +} + +/* +================ +idEventDef::NumEventCommands +================ +*/ +int idEventDef::NumEventCommands( void ) { + return numEventDefs; +} + +/* +================ +idEventDef::GetEventCommand +================ +*/ +const idEventDef *idEventDef::GetEventCommand( int eventnum ) { + return eventDefList[ eventnum ]; +} + +/* +================ +idEventDef::FindEvent +================ +*/ +const idEventDef *idEventDef::FindEvent( const char *name ) { + idEventDef *ev; + int num; + int i; + + assert( name ); + + num = numEventDefs; + for( i = 0; i < num; i++ ) { + ev = eventDefList[ i ]; + if ( strcmp( name, ev->name ) == 0 ) { + return ev; + } + } + + return NULL; +} + +/*********************************************************************** + + idEvent + +***********************************************************************/ + +static idLinkList FreeEvents; +static idLinkList EventQueue; +static idEvent EventPool[ MAX_EVENTS ]; + +bool idEvent::initialized = false; + +idDynamicBlockAlloc idEvent::eventDataAllocator; + +/* +================ +idEvent::~idEvent() +================ +*/ +idEvent::~idEvent() { + Free(); +} + +/* +================ +idEvent::Alloc +================ +*/ +idEvent *idEvent::Alloc( const idEventDef *evdef, int numargs, va_list args ) { + idEvent *ev; + size_t size; + const char *format; + idEventArg *arg; + byte *dataPtr; + int i; + const char *materialName; + + if ( FreeEvents.IsListEmpty() ) { + gameLocal.Error( "idEvent::Alloc : No more free events" ); + } + + ev = FreeEvents.Next(); + ev->eventNode.Remove(); + + ev->eventdef = evdef; + + if ( numargs != evdef->GetNumArgs() ) { + gameLocal.Error( "idEvent::Alloc : Wrong number of args for '%s' event.", evdef->GetName() ); + } + + size = evdef->GetArgSize(); + if ( size ) { + ev->data = eventDataAllocator.Alloc( size ); + memset( ev->data, 0, size ); + } else { + ev->data = NULL; + } + + format = evdef->GetArgFormat(); + for( i = 0; i < numargs; i++ ) { + arg = va_arg( args, idEventArg * ); + if ( format[ i ] != arg->type ) { + // when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens + if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) { + gameLocal.Error( "idEvent::Alloc : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() ); + } + } + + dataPtr = &ev->data[ evdef->GetArgOffset( i ) ]; + + switch( format[ i ] ) { + case D_EVENT_FLOAT : + case D_EVENT_INTEGER : + *reinterpret_cast( dataPtr ) = arg->value; + break; + + case D_EVENT_VECTOR : + if ( arg->value ) { + *reinterpret_cast( dataPtr ) = *reinterpret_cast( arg->value ); + } + break; + + case D_EVENT_STRING : + if ( arg->value ) { + idStr::Copynz( reinterpret_cast( dataPtr ), reinterpret_cast( arg->value ), MAX_STRING_LEN ); + } + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + *reinterpret_cast< idEntityPtr * >( dataPtr ) = reinterpret_cast( arg->value ); + break; + + case D_EVENT_TRACE : + if ( arg->value ) { + *reinterpret_cast( dataPtr ) = true; + *reinterpret_cast( dataPtr + sizeof( bool ) ) = *reinterpret_cast( arg->value ); + + // save off the material as a string since the pointer won't be valid in save games. + // since we save off the entire trace_t structure, if the material is NULL here, + // it will be NULL when we process it, so we don't need to save off anything in that case. + if ( reinterpret_cast( arg->value )->c.material ) { + materialName = reinterpret_cast( arg->value )->c.material->GetName(); + idStr::Copynz( reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ), materialName, MAX_STRING_LEN ); + } + } else { + *reinterpret_cast( dataPtr ) = false; + } + break; + + default : + gameLocal.Error( "idEvent::Alloc : Invalid arg format '%s' string for '%s' event.", format, evdef->GetName() ); + break; + } + } + + return ev; +} + +/* +================ +idEvent::CopyArgs +================ +*/ +void idEvent::CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ) { + int i; + const char *format; + idEventArg *arg; + + format = evdef->GetArgFormat(); + if ( numargs != evdef->GetNumArgs() ) { + gameLocal.Error( "idEvent::CopyArgs : Wrong number of args for '%s' event.", evdef->GetName() ); + } + + for( i = 0; i < numargs; i++ ) { + arg = va_arg( args, idEventArg * ); + if ( format[ i ] != arg->type ) { + // when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens + if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) { + gameLocal.Error( "idEvent::CopyArgs : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() ); + } + } + + data[ i ] = arg->value; + } +} + +/* +================ +idEvent::Free +================ +*/ +void idEvent::Free( void ) { + if ( data ) { + eventDataAllocator.Free( data ); + data = NULL; + } + + eventdef = NULL; + time = 0; + object = NULL; + typeinfo = NULL; + + eventNode.SetOwner( this ); + eventNode.AddToEnd( FreeEvents ); +} + +/* +================ +idEvent::Schedule +================ +*/ +void idEvent::Schedule( idClass *obj, const idTypeInfo *type, int time ) { + idEvent *event; + + assert( initialized ); + if ( !initialized ) { + return; + } + + object = obj; + typeinfo = type; + + // wraps after 24 days...like I care. ;) + this->time = gameLocal.time + time; + + eventNode.Remove(); + + event = EventQueue.Next(); + while( ( event != NULL ) && ( this->time >= event->time ) ) { + event = event->eventNode.Next(); + } + + if ( event ) { + eventNode.InsertBefore( event->eventNode ); + } else { + eventNode.AddToEnd( EventQueue ); + } +} + +/* +================ +idEvent::CancelEvents +================ +*/ +void idEvent::CancelEvents( const idClass *obj, const idEventDef *evdef ) { + idEvent *event; + idEvent *next; + + if ( !initialized ) { + return; + } + + for( event = EventQueue.Next(); event != NULL; event = next ) { + next = event->eventNode.Next(); + if ( event->object == obj ) { + if ( !evdef || ( evdef == event->eventdef ) ) { + event->Free(); + } + } + } +} + +/* +================ +idEvent::ClearEventList +================ +*/ +void idEvent::ClearEventList( void ) { + int i; + + // + // initialize lists + // + FreeEvents.Clear(); + EventQueue.Clear(); + + // + // add the events to the free list + // + for( i = 0; i < MAX_EVENTS; i++ ) { + EventPool[ i ].Free(); + } +} + +/* +================ +idEvent::ServiceEvents +================ +*/ +void idEvent::ServiceEvents( void ) { + idEvent *event; + int num; + int args[ D_EVENT_MAXARGS ]; + int offset; + int i; + int numargs; + const char *formatspec; + trace_t **tracePtr; + const idEventDef *ev; + byte *data; + const char *materialName; + + num = 0; + while( !EventQueue.IsListEmpty() ) { + event = EventQueue.Next(); + assert( event ); + + if ( event->time > gameLocal.time ) { + break; + } + + // copy the data into the local args array and set up pointers + ev = event->eventdef; + formatspec = ev->GetArgFormat(); + numargs = ev->GetNumArgs(); + for( i = 0; i < numargs; i++ ) { + offset = ev->GetArgOffset( i ); + data = event->data; + switch( formatspec[ i ] ) { + case D_EVENT_FLOAT : + case D_EVENT_INTEGER : + args[ i ] = *reinterpret_cast( &data[ offset ] ); + break; + + case D_EVENT_VECTOR : + *reinterpret_cast( &args[ i ] ) = reinterpret_cast( &data[ offset ] ); + break; + + case D_EVENT_STRING : + *reinterpret_cast( &args[ i ] ) = reinterpret_cast( &data[ offset ] ); + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + *reinterpret_cast( &args[ i ] ) = reinterpret_cast< idEntityPtr * >( &data[ offset ] )->GetEntity(); + break; + + case D_EVENT_TRACE : + tracePtr = reinterpret_cast( &args[ i ] ); + if ( *reinterpret_cast( &data[ offset ] ) ) { + *tracePtr = reinterpret_cast( &data[ offset + sizeof( bool ) ] ); + + if ( ( *tracePtr )->c.material != NULL ) { + // look up the material name to get the material pointer + materialName = reinterpret_cast( &data[ offset + sizeof( bool ) + sizeof( trace_t ) ] ); + ( *tracePtr )->c.material = declManager->FindMaterial( materialName, true ); + } + } else { + *tracePtr = NULL; + } + break; + + default: + gameLocal.Error( "idEvent::ServiceEvents : Invalid arg format '%s' string for '%s' event.", formatspec, ev->GetName() ); + } + } + + // the event is removed from its list so that if then object + // is deleted, the event won't be freed twice + event->eventNode.Remove(); + assert( event->object ); + event->object->ProcessEventArgPtr( ev, args ); + +#if 0 + // event functions may never leave return values on the FPU stack + // enable this code to check if any event call left values on the FPU stack + if ( !sys->FPU_StackIsEmpty() ) { + gameLocal.Error( "idEvent::ServiceEvents %d: %s left a value on the FPU stack\n", num, ev->GetName() ); + } +#endif + + // return the event to the free list + event->Free(); + + // Don't allow ourselves to stay in here too long. An abnormally high number + // of events being processed is evidence of an infinite loop of events. + num++; + if ( num > MAX_EVENTSPERFRAME ) { + gameLocal.Error( "Event overflow. Possible infinite loop in script." ); + } + } +} + +/* +================ +idEvent::Init +================ +*/ +void idEvent::Init( void ) { + gameLocal.Printf( "Initializing event system\n" ); + + if ( eventError ) { + gameLocal.Error( "%s", eventErrorMsg ); + } + +#ifdef CREATE_EVENT_CODE + void CreateEventCallbackHandler(); + CreateEventCallbackHandler(); + gameLocal.Error( "Wrote event callback handler" ); +#endif + + if ( initialized ) { + gameLocal.Printf( "...already initialized\n" ); + ClearEventList(); + return; + } + + ClearEventList(); + + eventDataAllocator.Init(); + + gameLocal.Printf( "...%i event definitions\n", idEventDef::NumEventCommands() ); + + // the event system has started + initialized = true; +} + +/* +================ +idEvent::Shutdown +================ +*/ +void idEvent::Shutdown( void ) { + gameLocal.Printf( "Shutdown event system\n" ); + + if ( !initialized ) { + gameLocal.Printf( "...not started\n" ); + return; + } + + ClearEventList(); + + eventDataAllocator.Shutdown(); + + // say it is now shut down + initialized = false; +} + +/* +================ +idEvent::Save +================ +*/ +void idEvent::Save( idSaveGame *savefile ) { + char *str; + int i; + size_t size; + idEvent *event; + byte *dataPtr; + bool validTrace; + const char *format; + + savefile->WriteInt( EventQueue.Num() ); + + event = EventQueue.Next(); + while( event != NULL ) { + savefile->WriteInt( event->time ); + savefile->WriteString( event->eventdef->GetName() ); + savefile->WriteString( event->typeinfo->classname ); + savefile->WriteObject( event->object ); + savefile->WriteInt( event->eventdef->GetArgSize() ); + format = event->eventdef->GetArgFormat(); + for ( i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i) { + dataPtr = &event->data[ event->eventdef->GetArgOffset( i ) ]; + switch( format[ i ] ) { + case D_EVENT_FLOAT : + savefile->WriteFloat( *reinterpret_cast( dataPtr ) ); + size += sizeof( float ); + break; + case D_EVENT_INTEGER : + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + savefile->WriteInt( *reinterpret_cast( dataPtr ) ); + size += sizeof( int ); + break; + case D_EVENT_VECTOR : + savefile->WriteVec3( *reinterpret_cast( dataPtr ) ); + size += sizeof( idVec3 ); + break; + case D_EVENT_TRACE : + validTrace = *reinterpret_cast( dataPtr ); + savefile->WriteBool( validTrace ); + size += sizeof( bool ); + if ( validTrace ) { + size += sizeof( trace_t ); + const trace_t &t = *reinterpret_cast( dataPtr + sizeof( bool ) ); + SaveTrace( savefile, t ); + if ( t.c.material ) { + size += MAX_STRING_LEN; + str = reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ); + savefile->Write( str, MAX_STRING_LEN ); + } + } + break; + default: + break; + } + } + assert( size == event->eventdef->GetArgSize() ); + event = event->eventNode.Next(); + } +} + +/* +================ +idEvent::Restore +================ +*/ +void idEvent::Restore( idRestoreGame *savefile ) { + char *str; + int num, i, j, size, argsize = 0; + idStr name; + byte *dataPtr; + idEvent *event; + const char *format; + + savefile->ReadInt( num ); + + for ( i = 0; i < num; i++ ) { + if ( FreeEvents.IsListEmpty() ) { + gameLocal.Error( "idEvent::Restore : No more free events" ); + } + + event = FreeEvents.Next(); + event->eventNode.Remove(); + event->eventNode.AddToEnd( EventQueue ); + + savefile->ReadInt( event->time ); + + // read the event name + savefile->ReadString( name ); + event->eventdef = idEventDef::FindEvent( name ); + if ( !event->eventdef ) { + savefile->Error( "idEvent::Restore: unknown event '%s'", name.c_str() ); + } + + // read the classtype + savefile->ReadString( name ); + event->typeinfo = idClass::GetClass( name ); + if ( !event->typeinfo ) { + savefile->Error( "idEvent::Restore: unknown class '%s' on event '%s'", name.c_str(), event->eventdef->GetName() ); + } + + savefile->ReadObject( event->object ); + + // read the args + savefile->ReadInt( argsize ); + if ( argsize != (int)event->eventdef->GetArgSize() ) { + savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() ); + } + if ( argsize ) { + event->data = eventDataAllocator.Alloc( argsize ); + format = event->eventdef->GetArgFormat(); + assert( format ); + for ( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j) { + dataPtr = &event->data[ event->eventdef->GetArgOffset( j ) ]; + switch( format[ j ] ) { + case D_EVENT_FLOAT : + savefile->ReadFloat( *reinterpret_cast( dataPtr ) ); + size += sizeof( float ); + break; + case D_EVENT_INTEGER : + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + savefile->ReadInt( *reinterpret_cast( dataPtr ) ); + size += sizeof( int ); + break; + case D_EVENT_VECTOR : + savefile->ReadVec3( *reinterpret_cast( dataPtr ) ); + size += sizeof( idVec3 ); + break; + case D_EVENT_TRACE : + savefile->ReadBool( *reinterpret_cast( dataPtr ) ); + size += sizeof( bool ); + if ( *reinterpret_cast( dataPtr ) ) { + size += sizeof( trace_t ); + trace_t &t = *reinterpret_cast( dataPtr + sizeof( bool ) ); + RestoreTrace( savefile, t) ; + if ( t.c.material ) { + size += MAX_STRING_LEN; + str = reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ); + savefile->Read( str, MAX_STRING_LEN ); + } + } + break; + default: + break; + } + } + assert( size == (int)event->eventdef->GetArgSize() ); + } else { + event->data = NULL; + } + } +} + +/* + ================ + idEvent::ReadTrace + + idRestoreGame has a ReadTrace procedure, but unfortunately idEvent wants the material + string name at the of the data structure rather than in the middle + ================ + */ +void idEvent::RestoreTrace( idRestoreGame *savefile, trace_t &trace ) { + savefile->ReadFloat( trace.fraction ); + savefile->ReadVec3( trace.endpos ); + savefile->ReadMat3( trace.endAxis ); + savefile->ReadInt( (int&)trace.c.type ); + savefile->ReadVec3( trace.c.point ); + savefile->ReadVec3( trace.c.normal ); + savefile->ReadFloat( trace.c.dist ); + savefile->ReadInt( trace.c.contents ); + savefile->ReadInt( (int&)trace.c.material ); + savefile->ReadInt( trace.c.contents ); + savefile->ReadInt( trace.c.modelFeature ); + savefile->ReadInt( trace.c.trmFeature ); + savefile->ReadInt( trace.c.id ); +} + +/* + ================ + idEvent::WriteTrace + + idSaveGame has a WriteTrace procedure, but unfortunately idEvent wants the material + string name at the of the data structure rather than in the middle +================ + */ +void idEvent::SaveTrace( idSaveGame *savefile, const trace_t &trace ) { + savefile->WriteFloat( trace.fraction ); + savefile->WriteVec3( trace.endpos ); + savefile->WriteMat3( trace.endAxis ); + savefile->WriteInt( trace.c.type ); + savefile->WriteVec3( trace.c.point ); + savefile->WriteVec3( trace.c.normal ); + savefile->WriteFloat( trace.c.dist ); + savefile->WriteInt( trace.c.contents ); + savefile->WriteInt( (int&)trace.c.material ); + savefile->WriteInt( trace.c.contents ); + savefile->WriteInt( trace.c.modelFeature ); + savefile->WriteInt( trace.c.trmFeature ); + savefile->WriteInt( trace.c.id ); +} + + + +#ifdef CREATE_EVENT_CODE +/* +================ +CreateEventCallbackHandler +================ +*/ +void CreateEventCallbackHandler( void ) { + int num; + int count; + int i, j, k; + char argString[ D_EVENT_MAXARGS + 1 ]; + idStr string1; + idStr string2; + idFile *file; + + file = fileSystem->OpenFileWrite( "Callbacks.cpp" ); + + file->Printf( "// generated file - see CREATE_EVENT_CODE\n\n" ); + + for( i = 1; i <= D_EVENT_MAXARGS; i++ ) { + + file->Printf( "\t/*******************************************************\n\n\t\t%d args\n\n\t*******************************************************/\n\n", i ); + + for ( j = 0; j < ( 1 << i ); j++ ) { + for ( k = 0; k < i; k++ ) { + argString[ k ] = j & ( 1 << k ) ? 'f' : 'i'; + } + argString[ i ] = '\0'; + + string1.Empty(); + string2.Empty(); + + for( k = 0; k < i; k++ ) { + if ( j & ( 1 << k ) ) { + string1 += "const float"; + string2 += va( "*( float * )&data[ %d ]", k ); + } else { + string1 += "const int"; + string2 += va( "data[ %d ]", k ); + } + + if ( k < i - 1 ) { + string1 += ", "; + string2 += ", "; + } + } + + file->Printf( "\tcase %d :\n\t\ttypedef void ( idClass::*eventCallback_%s_t )( %s );\n", ( 1 << ( i + D_EVENT_MAXARGS ) ) + j, argString, string1.c_str() ); + file->Printf( "\t\t( this->*( eventCallback_%s_t )callback )( %s );\n\t\tbreak;\n\n", argString, string2.c_str() ); + + } + } + + fileSystem->CloseFile( file ); +} + +#endif diff --git a/game/gamesys/Event.h b/game/gamesys/Event.h new file mode 100644 index 000000000..6c63e1a11 --- /dev/null +++ b/game/gamesys/Event.h @@ -0,0 +1,212 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +/* +sys_event.h + +Event are used for scheduling tasks and for linking script commands. +*/ +#ifndef __SYS_EVENT_H__ +#define __SYS_EVENT_H__ + +#ifdef __linux__ +#include +#endif + +#include "../../idlib/Lib.h" +#include + +#define D_EVENT_MAXARGS 8 // if changed, enable the CREATE_EVENT_CODE define in Event.cpp to generate switch statement for idClass::ProcessEventArgPtr. + // running the game will then generate c:\doom\base\events.txt, the contents of which should be copied into the switch statement. + +#define D_EVENT_VOID ( ( char )0 ) +#define D_EVENT_INTEGER 'd' +#define D_EVENT_FLOAT 'f' +#define D_EVENT_VECTOR 'v' +#define D_EVENT_STRING 's' +#define D_EVENT_ENTITY 'e' +#define D_EVENT_ENTITY_NULL 'E' // event can handle NULL entity pointers +#define D_EVENT_TRACE 't' + +#define MAX_EVENTS 8192 + +class idClass; +class idTypeInfo; + +class idEventDef { +private: + const char *name; + const char *formatspec; + unsigned int formatspecIndex; + int returnType; + int numargs; + size_t argsize; + int argOffset[ D_EVENT_MAXARGS ]; + int eventnum; + const idEventDef * next; + + static idEventDef * eventDefList[MAX_EVENTS]; + static int numEventDefs; + +public: + idEventDef( const char *command, const char *formatspec = NULL, char returnType = 0 ); + + const char *GetName( void ) const; + const char *GetArgFormat( void ) const; + unsigned int GetFormatspecIndex( void ) const; + char GetReturnType( void ) const; + int GetEventNum( void ) const; + int GetNumArgs( void ) const; + size_t GetArgSize( void ) const; + int GetArgOffset( int arg ) const; + + static int NumEventCommands( void ); + static const idEventDef *GetEventCommand( int eventnum ); + static const idEventDef *FindEvent( const char *name ); +}; + +class idSaveGame; +class idRestoreGame; +typedef struct trace_s trace_t; + +class idEvent { +private: + const idEventDef *eventdef; + byte *data; + int time; + idClass *object; + const idTypeInfo *typeinfo; + + idLinkList eventNode; + + static idDynamicBlockAlloc eventDataAllocator; + + +public: + static bool initialized; + + ~idEvent(); + + static idEvent *Alloc( const idEventDef *evdef, int numargs, va_list args ); + static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ); + + void Free( void ); + void Schedule( idClass *object, const idTypeInfo *cls, int time ); + byte *GetData( void ); + + static void CancelEvents( const idClass *obj, const idEventDef *evdef = NULL ); + static void ClearEventList( void ); + static void ServiceEvents( void ); + static void Init( void ); + static void Shutdown( void ); + + // save games + static void Save( idSaveGame *savefile ); // archives object for save game file + static void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + static void SaveTrace( idSaveGame *savefile, const trace_t &trace ); + static void RestoreTrace( idRestoreGame *savefile, trace_t &trace ); + +}; + +/* +================ +idEvent::GetData +================ +*/ +ID_INLINE byte *idEvent::GetData( void ) { + return data; +} + +/* +================ +idEventDef::GetName +================ +*/ +ID_INLINE const char *idEventDef::GetName( void ) const { + return name; +} + +/* +================ +idEventDef::GetArgFormat +================ +*/ +ID_INLINE const char *idEventDef::GetArgFormat( void ) const { + return formatspec; +} + +/* +================ +idEventDef::GetFormatspecIndex +================ +*/ +ID_INLINE unsigned int idEventDef::GetFormatspecIndex( void ) const { + return formatspecIndex; +} + +/* +================ +idEventDef::GetReturnType +================ +*/ +ID_INLINE char idEventDef::GetReturnType( void ) const { + return returnType; +} + +/* +================ +idEventDef::GetNumArgs +================ +*/ +ID_INLINE int idEventDef::GetNumArgs( void ) const { + return numargs; +} + +/* +================ +idEventDef::GetArgSize +================ +*/ +ID_INLINE size_t idEventDef::GetArgSize( void ) const { + return argsize; +} + +/* +================ +idEventDef::GetArgOffset +================ +*/ +ID_INLINE int idEventDef::GetArgOffset( int arg ) const { + assert( ( arg >= 0 ) && ( arg < D_EVENT_MAXARGS ) ); + return argOffset[ arg ]; +} + +/* +================ +idEventDef::GetEventNum +================ +*/ +ID_INLINE int idEventDef::GetEventNum( void ) const { + return eventnum; +} + +#endif /* !__SYS_EVENT_H__ */ diff --git a/game/gamesys/NoGameTypeInfo.h b/game/gamesys/NoGameTypeInfo.h new file mode 100644 index 000000000..205cf8cd0 --- /dev/null +++ b/game/gamesys/NoGameTypeInfo.h @@ -0,0 +1,74 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAMETYPEINFO_H__ +#define __GAMETYPEINFO_H__ + +/* +=================================================================================== + + This file has been generated with the Type Info Generator v1.0 (c) 2004 id Software + +=================================================================================== +*/ + +typedef struct { + const char * name; + const char * type; + const char * value; +} constantInfo_t; + +typedef struct { + const char * name; + int value; +} enumValueInfo_t; + +typedef struct { + const char * typeName; + const enumValueInfo_t * values; +} enumTypeInfo_t; + +typedef struct { + const char * type; + const char * name; + int offset; + int size; +} classVariableInfo_t; + +typedef struct { + const char * typeName; + const char * superType; + int size; + const classVariableInfo_t * variables; +} classTypeInfo_t; + + +static constantInfo_t constantInfo[] = { + { NULL, NULL, NULL } +}; + +static enumTypeInfo_t enumTypeInfo[] = { + { NULL, NULL } +}; + +static classTypeInfo_t classTypeInfo[] = { + { NULL, NULL, 0, NULL } +}; + +#endif /* !__GAMETYPEINFO_H__ */ diff --git a/game/gamesys/SaveGame.cpp b/game/gamesys/SaveGame.cpp new file mode 100644 index 000000000..56d37cf37 --- /dev/null +++ b/game/gamesys/SaveGame.cpp @@ -0,0 +1,1184 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../RevisionTracker.h" + +#include "TypeInfo.h" + +#include "zlib.h" + +/* +Save game related helper classes. + +Save games are implemented in two classes, idSaveGame and idRestoreGame, that implement write/read functions for +common types. They're passed in to each entity and object for them to archive themselves. Each class +implements save/restore functions for it's own data. When restoring, all the objects are instantiated, +then the restore function is called on each, superclass first, then subclasses. + +Pointers are restored by saving out an object index for each unique object pointer and adding them to a list of +objects that are to be saved. Restore instantiates all the objects in the list before calling the Restore function +on each object so that the pointers returned are valid. No object's restore function should rely on any other objects +being fully instantiated until after the restore process is complete. Post restore fixup should be done by posting +events with 0 delay. + +The savegame header will have the Game Name, Version, Map Name, and Player Persistent Info. + +Changes in version make savegames incompatible, and the game will start from the beginning of the level with +the player's persistent info. + +Changes to classes that don't need to break compatibility can use the build number as the savegame version. +Later versions are responsible for restoring from previous versions by ignoring any unused data and initializing +variables that weren't in previous versions with safe information. + +At the head of the save game is enough information to restore the player to the beginning of the level should the +file be unloadable in some way (for example, due to script changes). + +Note: the caching works only if the compresion is enabled. +The caching mechanism works in the following way. On game saving, there are two types of data: + 1. Ordinary data (almost all the data) + This type of data is pushed into the "cache" buffer. + 2. Special data which is now: + // ui->WriteToSaveGame( file ) - closed source + // gameSoundWorld->WriteToSaveGame( file ) - closed source + // WriteBuildNumber() and WriteCodeRevision() - vital, should not be compressed + This data is written directly to the file. +After all the data has been passed to idSaveGame, FinalizeCache must be called. +Depending on the settings it may compress the cache. Then it is finally dumped to idFile. +After that the last 4 bytes are written to the file - offset to cache start from the end of file. +The final file layout is then: + 1. Doom3 header (level info, we cannot change it) + 2. Special data (including version numbers) + 3. Cache image, maybe compressed (consists of ordinary data) + 4. Offset from EOF to cache image (is negative) +Restoring works almost the same way, but the cache must be retrieved at the very beginning. +The InitializeCache must be called before any ordinary data is read from the file. +It uses fseek to get offset to cache image, then reads it, probably decompresses it. +Afterwards it fseeks to the file position on the moment of call. +Then all the Read* happens which reads ordinary data from cache and special data from file. +*/ + +idSaveGame::idSaveGame( idFile *savefile ) { + + file = savefile; + + // Put NULL at the start of the list so we can skip over it. + objects.Clear(); + objects.Append( NULL ); +} + +idSaveGame::~idSaveGame() { + if ( objects.Num() ) { + Close(); + } +} + +void idSaveGame::Close( void ) { + int i; + + WriteSoundCommands(); + + // read trace models + idClipModel::SaveTraceModels( this ); + + for( i = 1; i < objects.Num(); i++ ) { + CallSave_r( objects[ i ]->GetType(), objects[ i ] ); + } + + objects.Clear(); + +#ifdef ID_DEBUG_MEMORY + idStr gameState = file->GetName(); + gameState.StripFileExtension(); + WriteGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ), false ) ); +#endif +} + +void idSaveGame::FinalizeCache( void ) { + if (!isCompressed) return; + + int offset = sizeof(int); + + //resize destination buffer + CRawVector zipped; + int zipsize = compressBound(cache.size()); + zipped.resize(zipsize); + + //compress the cache + int err = compress((Bytef *)&zipped[0], (uLongf*)&zipsize, + (const Bytef *)&cache[0], cache.size()); + if (err != Z_OK) + gameLocal.Error("idSaveGame::FinalizeCache: compress failed with code %d", err); + zipped.resize(zipsize); + + //write compressed size and uncompressed size + file->WriteInt(zipped.size()); offset += sizeof(int); + file->WriteInt(cache.size()); offset += sizeof(int); + //write compressed data + file->Write(&zipped[0], zipped.size()); offset += zipped.size(); + //write offset from EOF to cache start + file->WriteInt(-offset); + + cache.clear(); +} + +void idSaveGame::WriteObjectList( void ) { + int i; + + WriteInt( objects.Num() - 1 ); + for( i = 1; i < objects.Num(); i++ ) { + WriteString( objects[ i ]->GetClassname() ); + } +} + +void idSaveGame::CallSave_r( const idTypeInfo *cls, const idClass *obj ) { + if ( cls->super ) { + CallSave_r( cls->super, obj ); + if ( cls->super->Save == cls->Save ) { + // don't call save on this inheritance level since the function was called in the super class + return; + } + } + + ( obj->*cls->Save )( this ); +} + +void idSaveGame::AddObject( const idClass *obj ) { + objects.AddUnique( obj ); +} + +void idSaveGame::Write( const void *buffer, int len ) { + if (len == 0) return; + if (isCompressed) { + int sz = cache.size(); + cache.resize(sz + len); + memcpy(&cache[sz], buffer, len); + } + else + file->Write(buffer, len); +} + +void idSaveGame::WriteJoint( const jointHandle_t value ) { + WriteInt( (int)value ); +} + + +void idSaveGame::WriteByte( const byte value ) { + WriteUnsignedChar(value); +} + +void idSaveGame::WriteSignedChar( const signed char value ) { + WriteChar(value); +} + +void idSaveGame::WriteString( const char *string ) { + int len; + + len = strlen( string ); + WriteInt( len ); + Write( string, len ); +} + +void idSaveGame::WriteBounds( const idBounds &bounds ) { + WriteVec3(bounds[0]); + WriteVec3(bounds[1]); +} + +void idSaveGame::WriteBox( const idBox &box ) { + WriteVec3(box.GetCenter()); + WriteVec3(box.GetExtents()); + WriteMat3(box.GetAxis()); +} + +void idSaveGame::WriteWinding( const idWinding &w ) { + int i, num; + num = w.GetNumPoints(); + WriteInt( num ); + for ( i = 0; i < num; i++ ) + WriteVec5(w[i]); +} + +void idSaveGame::WriteObject( const idClass *obj ) { + int index; + + index = objects.FindIndex( obj ); + if ( index < 0 ) { + gameLocal.Warning( "idSaveGame::WriteObject - WriteObject FindIndex failed\n" ); + + // Use the NULL index + index = 0; + } + + WriteInt( index ); +} + +void idSaveGame::WriteStaticObject( const idClass &obj ) { + CallSave_r( obj.GetType(), &obj ); +} + +void idSaveGame::WriteDict( const idDict *dict ) { + int num; + int i; + const idKeyValue *kv; + + if ( !dict ) { + WriteInt( -1 ); + } else { + num = dict->GetNumKeyVals(); + WriteInt( num ); + for( i = 0; i < num; i++ ) { + kv = dict->GetKeyVal( i ); + WriteString( kv->GetKey() ); + WriteString( kv->GetValue() ); + } + } +} + +void idSaveGame::WriteMaterial( const idMaterial *material ) { + if ( !material ) { + WriteString( "" ); + } else { + WriteString( material->GetName() ); + } +} + +void idSaveGame::WriteSkin( const idDeclSkin *skin ) { + if ( !skin ) { + WriteString( "" ); + } else { + WriteString( skin->GetName() ); + } +} + +void idSaveGame::WriteParticle( const idDeclParticle *particle ) { + if ( !particle ) { + WriteString( "" ); + } else { + WriteString( particle->GetName() ); + } +} + +void idSaveGame::WriteFX( const idDeclFX *fx ) { + if ( !fx ) { + WriteString( "" ); + } else { + WriteString( fx->GetName() ); + } +} + +void idSaveGame::WriteModelDef( const idDeclModelDef *modelDef ) { + if ( !modelDef ) { + WriteString( "" ); + } else { + WriteString( modelDef->GetName() ); + } +} + +void idSaveGame::WriteSoundShader( const idSoundShader *shader ) { + const char *name; + + if ( !shader ) { + WriteString( "" ); + } else { + name = shader->GetName(); + WriteString( name ); + } +} + +void idSaveGame::WriteModel( const idRenderModel *model ) { + const char *name; + + if ( !model ) { + WriteString( "" ); + } else { + name = model->Name(); + WriteString( name ); + } +} + +void idSaveGame::WriteRenderEntity( const renderEntity_t &renderEntity ) { + int i; + + WriteModel( renderEntity.hModel ); + + WriteInt( renderEntity.entityNum ); + WriteInt( renderEntity.bodyId ); + + WriteBounds( renderEntity.bounds ); + + // callback is set by class's Restore function + + WriteInt( renderEntity.suppressSurfaceInViewID ); + WriteInt( renderEntity.suppressShadowInViewID ); + WriteInt( renderEntity.suppressShadowInLightID ); + WriteInt( renderEntity.allowSurfaceInViewID ); + + WriteVec3( renderEntity.origin ); + WriteMat3( renderEntity.axis ); + + WriteMaterial( renderEntity.customShader ); + WriteMaterial( renderEntity.referenceShader ); + WriteSkin( renderEntity.customSkin ); + + if ( renderEntity.referenceSound != NULL ) { + WriteInt( renderEntity.referenceSound->Index() ); + } else { + WriteInt( 0 ); + } + + for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + WriteFloat( renderEntity.shaderParms[ i ] ); + } + + for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + WriteUserInterface( renderEntity.gui[ i ], renderEntity.gui[ i ] ? renderEntity.gui[ i ]->IsUniqued() : false ); + } + + WriteFloat( renderEntity.modelDepthHack ); + + WriteBool( renderEntity.noSelfShadow ); + WriteBool( renderEntity.noShadow ); + WriteBool( renderEntity.noDynamicInteractions ); + WriteBool( renderEntity.weaponDepthHack ); + + WriteInt( renderEntity.forceUpdate ); +} + +void idSaveGame::WriteRenderLight( const renderLight_t &renderLight ) { + int i; + + WriteMat3( renderLight.axis ); + WriteVec3( renderLight.origin ); + + WriteInt( renderLight.suppressLightInViewID ); + WriteInt( renderLight.allowLightInViewID ); + WriteBool( renderLight.noShadows ); + WriteBool( renderLight.noSpecular ); + WriteBool( renderLight.pointLight ); + WriteBool( renderLight.parallel ); + + WriteVec3( renderLight.lightRadius ); + WriteVec3( renderLight.lightCenter ); + + WriteVec3( renderLight.target ); + WriteVec3( renderLight.right ); + WriteVec3( renderLight.up ); + WriteVec3( renderLight.start ); + WriteVec3( renderLight.end ); + + // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there + // WriteModel( renderLight.prelightModel ); + + WriteInt( renderLight.lightId ); + + WriteMaterial( renderLight.shader ); + + for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + WriteFloat( renderLight.shaderParms[ i ] ); + } + + if ( renderLight.referenceSound != NULL ) { + WriteInt( renderLight.referenceSound->Index() ); + } else { + WriteInt( 0 ); + } +} + +void idSaveGame::WriteRefSound( const refSound_t &refSound ) { + if ( refSound.referenceSound ) { + WriteInt( refSound.referenceSound->Index() ); + } else { + WriteInt( 0 ); + } + WriteVec3( refSound.origin ); + WriteInt( refSound.listenerId ); + WriteSoundShader( refSound.shader ); + WriteFloat( refSound.diversity ); + WriteBool( refSound.waitfortrigger ); + + WriteFloat( refSound.parms.minDistance ); + WriteFloat( refSound.parms.maxDistance ); + WriteFloat( refSound.parms.volume ); + WriteFloat( refSound.parms.shakes ); + WriteInt( refSound.parms.soundShaderFlags ); + WriteInt( refSound.parms.soundClass ); +} + +void idSaveGame::WriteRenderView( const renderView_t &view ) { + int i; + + WriteInt( view.viewID ); + WriteInt( view.x ); + WriteInt( view.y ); + WriteInt( view.width ); + WriteInt( view.height ); + + WriteFloat( view.fov_x ); + WriteFloat( view.fov_y ); + WriteVec3( view.vieworg ); + WriteMat3( view.viewaxis ); + + WriteBool( view.cramZNear ); + + WriteInt( view.time ); + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + WriteFloat( view.shaderParms[ i ] ); + } +} + +void idSaveGame::WriteUsercmd( const usercmd_t &usercmd ) { + WriteInt( usercmd.gameFrame ); + WriteInt( usercmd.gameTime ); + WriteInt( usercmd.duplicateCount ); + WriteByte( usercmd.buttons ); + WriteSignedChar( usercmd.forwardmove ); + WriteSignedChar( usercmd.rightmove ); + WriteSignedChar( usercmd.upmove ); + WriteShort( usercmd.angles[0] ); + WriteShort( usercmd.angles[1] ); + WriteShort( usercmd.angles[2] ); + WriteShort( usercmd.mx ); + WriteShort( usercmd.my ); + WriteSignedChar( usercmd.impulse ); + WriteByte( usercmd.flags ); + WriteInt( usercmd.sequence ); +} + +void idSaveGame::WriteContactInfo( const contactInfo_t &contactInfo ) { + WriteInt( (int)contactInfo.type ); + WriteVec3( contactInfo.point ); + WriteVec3( contactInfo.normal ); + WriteFloat( contactInfo.dist ); + WriteInt( contactInfo.contents ); + WriteMaterial( contactInfo.material ); + WriteInt( contactInfo.modelFeature ); + WriteInt( contactInfo.trmFeature ); + WriteInt( contactInfo.entityNum ); + WriteInt( contactInfo.id ); +} + +void idSaveGame::WriteTrace( const trace_t &trace ) { + WriteFloat( trace.fraction ); + WriteVec3( trace.endpos ); + WriteMat3( trace.endAxis ); + WriteContactInfo( trace.c ); +} + +void idSaveGame::WriteTraceModel( const idTraceModel &trace ) { + int j, k; + + WriteInt( (int&)trace.type ); + WriteInt( trace.numVerts ); + for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) { + WriteVec3( trace.verts[j] ); + } + WriteInt( trace.numEdges ); + for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) { + WriteInt( trace.edges[j].v[0] ); + WriteInt( trace.edges[j].v[1] ); + WriteVec3( trace.edges[j].normal ); + } + WriteInt( trace.numPolys ); + for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) { + WriteVec3( trace.polys[j].normal ); + WriteFloat( trace.polys[j].dist ); + WriteBounds( trace.polys[j].bounds ); + WriteInt( trace.polys[j].numEdges ); + for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) { + WriteInt( trace.polys[j].edges[k] ); + } + } + WriteVec3( trace.offset ); + WriteBounds( trace.bounds ); + WriteBool( trace.isConvex ); + // padding win32 native structs + char tmp[3]; + memset( tmp, 0, sizeof( tmp ) ); + Write( tmp, 3 ); +} + +void idSaveGame::WriteClipModel( const idClipModel *clipModel ) { + if ( clipModel != NULL ) { + WriteBool( true ); + clipModel->Save( this ); + } else { + WriteBool( false ); + } +} + +void idSaveGame::WriteUserInterface( const idUserInterface *ui, bool unique ) { + const char *name; + + if ( !ui ) { + WriteString( "" ); + } else { + name = ui->Name(); + WriteString( name ); + WriteBool( unique ); + if ( ui->WriteToSaveGame( file ) == false ) { + gameLocal.Error( "idSaveGame::WriteUserInterface: ui failed to write properly\n" ); + } + } +} + +void idSaveGame::WriteSoundCommands( void ) { + gameSoundWorld->WriteToSaveGame( file ); +} + +void idSaveGame::WriteHeader() { + file->WriteInt( BUILD_NUMBER ); + file->WriteInt(RevisionTracker::Instance().GetHighestRevision()); + isCompressed = cv_savegame_compress.GetBool(); + file->WriteBool(isCompressed); +} + +/*********************************************************************** + + idRestoreGame + +***********************************************************************/ + +idRestoreGame::idRestoreGame( idFile *savefile ) { + file = savefile; +} + +idRestoreGame::~idRestoreGame() { +} + +void idRestoreGame::InitializeCache() { + if (!isCompressed) return; + + //move to end of file + int position = file->Tell(); + file->Seek(-4, FS_SEEK_END); + if (file->Tell() == position) + Error( "idRestoreGame::InitializeCache: file->Seek failed"); + + //read offset to cache and rollback + int offset = 666; + file->ReadInt(offset); + if (offset >= 0) + Error( "idRestoreGame::InitializeCache: bad cache offset (%d)", offset); + file->Seek(offset, FS_SEEK_CUR); + + //read compressed cache size + int zipSize = -1; + file->ReadInt(zipSize); + if (zipSize <= 0) + Error("idRestoreGame::InitializeCache: bad compressed cache size (%d)", zipSize); + + //read decompressed cache size + int cacheSize = -1; + file->ReadInt(cacheSize); + if (cacheSize <= 0) + Error("idRestoreGame::InitializeCache: bad uncompressed cache size (%d)", cacheSize); + + //read compressed data + CRawVector zipped; + zipped.resize(zipSize); + cache.resize(cacheSize); + file->Read(&zipped[0], zipped.size()); + + //decompress data + int err = uncompress( + (Bytef *)&cache[0], (uLongf*)&cacheSize, + (const Bytef *)&zipped[0], zipped.size()); + if (err != Z_OK) + Error("idRestoreGame::InitializeCache: uncompress failed with code %d", err); + if (cacheSize != cache.size()) + Error("idRestoreGame::InitializeCache: uncompressed size is %d instead of %d", cacheSize, cache.size()); + + //set cache pointer + cachePointer = 0; + //return file pointer + file->Seek(position, FS_SEEK_SET); +} + +void idRestoreGame::CreateObjects( void ) { + int i, num; + idStr classname; + idTypeInfo *type; + + ReadInt( num ); + + // create all the objects + objects.SetNum( num + 1 ); + memset( objects.Ptr(), 0, sizeof( objects[ 0 ] ) * objects.Num() ); + + for( i = 1; i < objects.Num(); i++ ) { + ReadString( classname ); + type = idClass::GetClass( classname ); + if ( !type ) { + Error( "idRestoreGame::CreateObjects: Unknown class '%s'", classname.c_str() ); + } + objects[ i ] = type->CreateInstance(); + +#ifdef ID_DEBUG_MEMORY + InitTypeVariables( objects[i], type->classname, 0xce ); +#endif + } +} + +void idRestoreGame::RestoreObjects( void ) { + int i; + + ReadSoundCommands(); + + // read trace models + idClipModel::RestoreTraceModels( this ); + + // restore all the objects + for( i = 1; i < objects.Num(); i++ ) { + CallRestore_r( objects[ i ]->GetType(), objects[ i ] ); + } + + // regenerate render entities and render lights because are not saved + for( i = 1; i < objects.Num(); i++ ) { + if ( objects[ i ]->IsType( idEntity::Type ) ) { + idEntity *ent = static_cast( objects[ i ] ); + ent->UpdateVisuals(); + ent->Present(); + } + } + +#ifdef ID_DEBUG_MEMORY + idStr gameState = file->GetName(); + gameState.StripFileExtension(); + WriteGameState_f( idCmdArgs( va( "test %s_restore", gameState.c_str() ), false ) ); + //CompareGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ) ) ); + gameLocal.Error( "dumped game states" ); +#endif +} + +void idRestoreGame::DeleteObjects( void ) { + + // Remove the NULL object before deleting + objects.RemoveIndex( 0 ); + + objects.DeleteContents( true ); +} + +void idRestoreGame::Error( const char *fmt, ... ) { + va_list argptr; + char text[ 1024 ]; + + va_start( argptr, fmt ); + vsprintf( text, fmt, argptr ); + va_end( argptr ); + + objects.DeleteContents( true ); + + gameLocal.Error( "%s", text ); +} + +void idRestoreGame::CallRestore_r( const idTypeInfo *cls, idClass *obj ) { + if ( cls->super ) { + CallRestore_r( cls->super, obj ); + if ( cls->super->Restore == cls->Restore ) { + // don't call save on this inheritance level since the function was called in the super class + return; + } + } + + ( obj->*cls->Restore )( this ); +} + +void idRestoreGame::Read( void *buffer, int len ) { + if (len == 0) return; + if (isCompressed) { + assert(cachePointer + len <= int(cache.size())); + memcpy(buffer, &cache[cachePointer], len); + cachePointer += len; + } + else + file->Read(buffer, len); +} + +void idRestoreGame::ReadJoint( jointHandle_t &value ) { + ReadInt( (int&)value ); +} + +void idRestoreGame::ReadByte( byte &value ) { + ReadUnsignedChar(value); +} + +void idRestoreGame::ReadSignedChar( signed char &value ) { + ReadChar( (char&)value ); +} + +void idRestoreGame::ReadString( idStr &string ) { + int len; + + ReadInt( len ); + if ( len < 0 ) { + Error( "idRestoreGame::ReadString: invalid length (%d)", len ); + } + + string.Fill( ' ', len ); + Read( &string[ 0 ], len ); +} + +void idRestoreGame::ReadBounds( idBounds &bounds ) { + ReadVec3(bounds[0]); + ReadVec3(bounds[1]); +} + +void idRestoreGame::ReadBox( idBox &box ) { + idVec3 center, extents; + idMat3 axis; + ReadVec3(center); + ReadVec3(extents); + ReadMat3(axis); + box = idBox(center, extents, axis); +} + +void idRestoreGame::ReadWinding( idWinding &w ) { + int i, num; + ReadInt( num ); + if (num < 0) + Error("idRestoreGame::ReadWinding: negative number of points (%d)", num); + w.SetNumPoints( num ); + for ( i = 0; i < num; i++ ) + ReadVec5(w[i]); +} + +void idRestoreGame::ReadObject( idClass *&obj ) { + int index; + + ReadInt( index ); + if ( ( index < 0 ) || ( index >= objects.Num() ) ) { + Error( "idRestoreGame::ReadObject: invalid object index" ); + } + obj = objects[ index ]; +} + +void idRestoreGame::ReadStaticObject( idClass &obj ) { + CallRestore_r( obj.GetType(), &obj ); +} + +void idRestoreGame::ReadDict( idDict *dict ) { + int num; + int i; + idStr key; + idStr value; + + ReadInt( num ); + + if ( num < 0 ) { + dict = NULL; + } else { + dict->Clear(); + for( i = 0; i < num; i++ ) { + ReadString( key ); + ReadString( value ); + dict->Set( key, value ); + } + } +} + +void idRestoreGame::ReadMaterial( const idMaterial *&material ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + material = NULL; + } else { + material = declManager->FindMaterial( name ); + } +} + +void idRestoreGame::ReadSkin( const idDeclSkin *&skin ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + skin = NULL; + } else { + skin = declManager->FindSkin( name ); + } +} + +void idRestoreGame::ReadParticle( const idDeclParticle *&particle ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + particle = NULL; + } else { + particle = static_cast( declManager->FindType( DECL_PARTICLE, name ) ); + } +} + +void idRestoreGame::ReadFX( const idDeclFX *&fx ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + fx = NULL; + } else { + fx = static_cast( declManager->FindType( DECL_FX, name ) ); + } +} + +void idRestoreGame::ReadSoundShader( const idSoundShader *&shader ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + shader = NULL; + } else { + shader = declManager->FindSound( name ); + } +} + +void idRestoreGame::ReadModelDef( const idDeclModelDef *&modelDef ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + modelDef = NULL; + } else { + modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); + } +} + +void idRestoreGame::ReadModel( idRenderModel *&model ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + model = NULL; + } else { + model = renderModelManager->FindModel( name ); + } +} + +void idRestoreGame::ReadUserInterface( idUserInterface *&ui ) { + idStr name; + + ReadString( name ); + if ( !name.Length() ) { + ui = NULL; + } else { + bool unique; + ReadBool( unique ); + ui = uiManager->FindGui( name, true, unique ); + if ( ui ) { + if ( ui->ReadFromSaveGame( file ) == false ) { + Error( "idSaveGame::ReadUserInterface: ui failed to read properly\n" ); + } else { + ui->StateChanged( gameLocal.time ); + } + } + } +} + +void idRestoreGame::ReadRenderEntity( renderEntity_t &renderEntity ) { + int i; + int index; + + ReadModel( renderEntity.hModel ); + + ReadInt( renderEntity.entityNum ); + ReadInt( renderEntity.bodyId ); + + ReadBounds( renderEntity.bounds ); + + // callback is set by class's Restore function + renderEntity.callback = NULL; + renderEntity.callbackData = NULL; + + ReadInt( renderEntity.suppressSurfaceInViewID ); + ReadInt( renderEntity.suppressShadowInViewID ); + ReadInt( renderEntity.suppressShadowInLightID ); + ReadInt( renderEntity.allowSurfaceInViewID ); + + ReadVec3( renderEntity.origin ); + ReadMat3( renderEntity.axis ); + + ReadMaterial( renderEntity.customShader ); + ReadMaterial( renderEntity.referenceShader ); + ReadSkin( renderEntity.customSkin ); + + ReadInt( index ); + renderEntity.referenceSound = gameSoundWorld->EmitterForIndex( index ); + + for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + ReadFloat( renderEntity.shaderParms[ i ] ); + } + + for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + ReadUserInterface( renderEntity.gui[ i ] ); + } + + // idEntity will restore "cameraTarget", which will be used in idEntity::Present to restore the remoteRenderView + renderEntity.remoteRenderView = NULL; + + renderEntity.joints = NULL; + renderEntity.numJoints = 0; + + ReadFloat( renderEntity.modelDepthHack ); + + ReadBool( renderEntity.noSelfShadow ); + ReadBool( renderEntity.noShadow ); + ReadBool( renderEntity.noDynamicInteractions ); + ReadBool( renderEntity.weaponDepthHack ); + + ReadInt( renderEntity.forceUpdate ); +} + +void idRestoreGame::ReadRenderLight( renderLight_t &renderLight ) { + int index; + int i; + + ReadMat3( renderLight.axis ); + ReadVec3( renderLight.origin ); + + ReadInt( renderLight.suppressLightInViewID ); + ReadInt( renderLight.allowLightInViewID ); + ReadBool( renderLight.noShadows ); + ReadBool( renderLight.noSpecular ); + ReadBool( renderLight.pointLight ); + ReadBool( renderLight.parallel ); + + ReadVec3( renderLight.lightRadius ); + ReadVec3( renderLight.lightCenter ); + + ReadVec3( renderLight.target ); + ReadVec3( renderLight.right ); + ReadVec3( renderLight.up ); + ReadVec3( renderLight.start ); + ReadVec3( renderLight.end ); + + // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there + // ReadModel( renderLight.prelightModel ); + renderLight.prelightModel = NULL; + + ReadInt( renderLight.lightId ); + + ReadMaterial( renderLight.shader ); + + for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + ReadFloat( renderLight.shaderParms[ i ] ); + } + + ReadInt( index ); + renderLight.referenceSound = gameSoundWorld->EmitterForIndex( index ); +} + +void idRestoreGame::ReadRefSound( refSound_t &refSound ) { + int index; + ReadInt( index ); + + refSound.referenceSound = gameSoundWorld->EmitterForIndex( index ); + ReadVec3( refSound.origin ); + ReadInt( refSound.listenerId ); + ReadSoundShader( refSound.shader ); + ReadFloat( refSound.diversity ); + ReadBool( refSound.waitfortrigger ); + + ReadFloat( refSound.parms.minDistance ); + ReadFloat( refSound.parms.maxDistance ); + ReadFloat( refSound.parms.volume ); + ReadFloat( refSound.parms.shakes ); + ReadInt( refSound.parms.soundShaderFlags ); + ReadInt( refSound.parms.soundClass ); +} + +void idRestoreGame::ReadRenderView( renderView_t &view ) { + int i; + + ReadInt( view.viewID ); + ReadInt( view.x ); + ReadInt( view.y ); + ReadInt( view.width ); + ReadInt( view.height ); + + ReadFloat( view.fov_x ); + ReadFloat( view.fov_y ); + ReadVec3( view.vieworg ); + ReadMat3( view.viewaxis ); + + ReadBool( view.cramZNear ); + + ReadInt( view.time ); + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + ReadFloat( view.shaderParms[ i ] ); + } +} + +void idRestoreGame::ReadUsercmd( usercmd_t &usercmd ) { + ReadInt( usercmd.gameFrame ); + ReadInt( usercmd.gameTime ); + ReadInt( usercmd.duplicateCount ); + ReadByte( usercmd.buttons ); + ReadSignedChar( usercmd.forwardmove ); + ReadSignedChar( usercmd.rightmove ); + ReadSignedChar( usercmd.upmove ); + ReadShort( usercmd.angles[0] ); + ReadShort( usercmd.angles[1] ); + ReadShort( usercmd.angles[2] ); + ReadShort( usercmd.mx ); + ReadShort( usercmd.my ); + ReadSignedChar( usercmd.impulse ); + ReadByte( usercmd.flags ); + ReadInt( usercmd.sequence ); +} + +void idRestoreGame::ReadContactInfo( contactInfo_t &contactInfo ) { + ReadInt( (int &)contactInfo.type ); + ReadVec3( contactInfo.point ); + ReadVec3( contactInfo.normal ); + ReadFloat( contactInfo.dist ); + ReadInt( contactInfo.contents ); + ReadMaterial( contactInfo.material ); + ReadInt( contactInfo.modelFeature ); + ReadInt( contactInfo.trmFeature ); + ReadInt( contactInfo.entityNum ); + ReadInt( contactInfo.id ); +} + +void idRestoreGame::ReadTrace( trace_t &trace ) { + ReadFloat( trace.fraction ); + ReadVec3( trace.endpos ); + ReadMat3( trace.endAxis ); + ReadContactInfo( trace.c ); +} + +void idRestoreGame::ReadTraceModel( idTraceModel &trace ) { + int j, k; + + ReadInt( (int&)trace.type ); + ReadInt( trace.numVerts ); + for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) { + ReadVec3( trace.verts[j] ); + } + ReadInt( trace.numEdges ); + for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) { + ReadInt( trace.edges[j].v[0] ); + ReadInt( trace.edges[j].v[1] ); + ReadVec3( trace.edges[j].normal ); + } + ReadInt( trace.numPolys ); + for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) { + ReadVec3( trace.polys[j].normal ); + ReadFloat( trace.polys[j].dist ); + ReadBounds( trace.polys[j].bounds ); + ReadInt( trace.polys[j].numEdges ); + for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) { + ReadInt( trace.polys[j].edges[k] ); + } + } + ReadVec3( trace.offset ); + ReadBounds( trace.bounds ); + ReadBool( trace.isConvex ); + // padding win32 native structs + char tmp[3]; + Read( tmp, 3 ); +} + +void idRestoreGame::ReadClipModel( idClipModel *&clipModel ) { + bool restoreClipModel; + + ReadBool( restoreClipModel ); + if ( restoreClipModel ) { + clipModel = new idClipModel(); + clipModel->Restore( this ); + } else { + clipModel = NULL; + } +} + +void idRestoreGame::ReadSoundCommands( void ) { + gameSoundWorld->StopAllSounds(); + gameSoundWorld->ReadFromSaveGame( file ); +} + +void idRestoreGame::ReadHeader( void ) { + file->ReadInt( buildNumber ); + file->ReadInt( codeRevision ); + file->ReadBool(isCompressed); +} + +/*********************************************************************** + + Read/write for common types + +***********************************************************************/ + +#define LittleChar(x) x + +#define DEFINE_READWRITE_PRIMITIVE(cpp_type, name_type, conv_type) \ +void idRestoreGame::Read##name_type (cpp_type &value) \ +{ \ + if (isCompressed) { \ + const cpp_type *value_ptr = (const cpp_type*)&cache[cachePointer]; \ + value = Little##conv_type (*value_ptr); \ + cachePointer += sizeof(cpp_type); \ + } \ + else \ + file->Read##name_type(value); \ +} \ +void idSaveGame::Write##name_type (const cpp_type value) \ +{ \ + if (isCompressed) { \ + int sz = cache.size(); \ + cache.resize(sz + sizeof(cpp_type)); \ + cpp_type *value_ptr = (cpp_type*)&cache[sz]; \ + *value_ptr = Little##conv_type (value); \ + } \ + else \ + file->Write##name_type(value); \ +} + +DEFINE_READWRITE_PRIMITIVE(int, Int, Long) +DEFINE_READWRITE_PRIMITIVE(unsigned int, UnsignedInt, Long) +DEFINE_READWRITE_PRIMITIVE(short, Short, Short) +DEFINE_READWRITE_PRIMITIVE(char, Char, Char) +DEFINE_READWRITE_PRIMITIVE(unsigned char, UnsignedChar, Char) +DEFINE_READWRITE_PRIMITIVE(float, Float, Float) +DEFINE_READWRITE_PRIMITIVE(bool, Bool, Char) + +#define DEFINE_READWRITE_VECMAT(cpp_type, name_type) \ +void idRestoreGame::Read##name_type (cpp_type &vec) \ +{ \ + for (int i = 0; i objects; + + bool isCompressed; + CRawVector cache; + + void CallSave_r( const idTypeInfo *cls, const idClass *obj ); +}; + +class idRestoreGame { +public: + idRestoreGame( idFile *savefile ); + ~idRestoreGame(); + + void CreateObjects( void ); + void RestoreObjects( void ); + void DeleteObjects( void ); + + void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))); + + void Read( void *buffer, int len ); + + void ReadInt( int &value ); + void ReadUnsignedInt( unsigned int &value ); + void ReadShort( short &value ); + void ReadUnsignedShort( unsigned short &value ); + void ReadChar( char &value ); + void ReadUnsignedChar( unsigned char &value ); + void ReadFloat( float &value ); + void ReadBool( bool &value ); + void ReadString( idStr &string ); + + void ReadJoint( jointHandle_t &value ); + void ReadByte( byte &value ); + void ReadSignedChar( signed char &value ); + + void ReadVec2( idVec2 &vec ); + void ReadVec3( idVec3 &vec ); + void ReadVec4( idVec4 &vec ); + void ReadVec5( idVec5 &vec ); + void ReadVec6( idVec6 &vec ); + void ReadMat3( idMat3 &mat ); + + void ReadWinding( idWinding &winding ); + void ReadBounds( idBounds &bounds ); + void ReadBox( idBox &box ); + void ReadAngles( idAngles &angles ); + void ReadObject( idClass *&obj ); + void ReadStaticObject( idClass &obj ); + void ReadDict( idDict *dict ); + void ReadMaterial( const idMaterial *&material ); + void ReadSkin( const idDeclSkin *&skin ); + void ReadParticle( const idDeclParticle *&particle ); + void ReadFX( const idDeclFX *&fx ); + void ReadSoundShader( const idSoundShader *&shader ); + void ReadModelDef( const idDeclModelDef *&modelDef ); + void ReadModel( idRenderModel *&model ); + void ReadUserInterface( idUserInterface *&ui ); + void ReadRenderEntity( renderEntity_t &renderEntity ); + void ReadRenderLight( renderLight_t &renderLight ); + void ReadRefSound( refSound_t &refSound ); + void ReadRenderView( renderView_t &view ); + void ReadUsercmd( usercmd_t &usercmd ); + void ReadContactInfo( contactInfo_t &contactInfo ); + void ReadTrace( trace_t &trace ); + void ReadTraceModel( idTraceModel &trace ); + void ReadClipModel( idClipModel *&clipModel ); + void ReadSoundCommands( void ); + + // Read all the data necessary to determine the save format + void ReadHeader(); + + // Read the contents of cache buffer before restoring + void InitializeCache(); + + inline int GetBuildNumber() { return buildNumber; } + inline int GetCodeRevision() { return codeRevision; } + +private: + idFile * file; + + int buildNumber; + int codeRevision; + + idList objects; + + bool isCompressed; + CRawVector cache; + int cachePointer; + + void CallRestore_r( const idTypeInfo *cls, idClass *obj ); +}; + +#endif /* !__SAVEGAME_H__*/ diff --git a/game/gamesys/SysCmds.cpp b/game/gamesys/SysCmds.cpp new file mode 100644 index 000000000..bed24a1ce --- /dev/null +++ b/game/gamesys/SysCmds.cpp @@ -0,0 +1,3859 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" + +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../ai/AAS_local.h" +#include "../SndPropLoader.h" +#include "../Relations.h" +#include "../Objectives/MissionData.h" +#include "../Inventory/Inventory.h" +#include "../Inventory/InventoryItem.h" +#include "../TimerManager.h" +#include "../ai/Conversation/ConversationSystem.h" +#include "../Missions/MissionManager.h" +#include "../Missions/ModInfo.h" + +#include "TypeInfo.h" + +/* +================== +Cmd_TestSndIO_f +================== +*/ +void Cmd_TestSndIO_f( const idCmdArgs &args ) +{ + idStr inFN; + + if ( args.Argc() < 2 ) { + gameLocal.Printf( "usage: dm_spr_testIO \n" ); + goto Quit; + } + inFN = args.Args(); + + if ( inFN.Length() == 0 ) + { + goto Quit; + } + +// New file IO not yet implemented +// gameLocal.Printf( "Testing sound prop. IO for file %s\n", inFN.c_str() ); + gameLocal.Printf( "New soundprop file IO not yet implemented\n"); +Quit: + return; +} + +/* +================== +Cmd_PrintAIRelations_f +================== +*/ +void Cmd_PrintAIRelations_f( const idCmdArgs &args ) +{ + gameLocal.m_RelationsManager->DebugPrintMat(); + return; +} + +/** + * greebo: This is a helper command, used by the restart.gui + */ +void Cmd_RestartGuiCmd_UpdateObjectives_f(const idCmdArgs &args) +{ + idUserInterface* gui = uiManager->FindGui("guis/restart.gui", false, true, true); + + if (gui == NULL) + { + gameLocal.Warning("Could not find restart.gui"); + return; + } + + gameLocal.m_MissionData->UpdateGUIState(gui); +} + +void Cmd_ListMissions_f(const idCmdArgs& args) +{ + gameLocal.Printf("%d missions registered:\n", gameLocal.m_MissionManager->GetNumMods()); + + for (int i = 0; i < gameLocal.m_MissionManager->GetNumMods(); ++i) + { + CModInfoPtr missionInfo = gameLocal.m_MissionManager->GetModInfo(i); + + if (missionInfo == NULL) continue; + + gameLocal.Printf("%02d: %s = %s\n", i, missionInfo->modName.c_str(), missionInfo->displayName.c_str()); + } +} + +void Cmd_SetMissionCompleted_f(const idCmdArgs& args) +{ + if (args.Argc() < 2) + { + gameLocal.Printf("Usage: tdm_set_mission_completed [-c]\n"); + gameLocal.Printf("The -c argument is optional, can be used to clear the 'completed' flag, such that the mission isn't listed as completed in the mission menu.\n\n"); + gameLocal.Printf("Example: 'tdm_set_mission_completed heart'\n"); + return; + } + + bool clearFlag = false; + idStr missionName; + + for (int i = 1; i < args.Argc(); ++i) + { + idStr arg = args.Argv(i); + + if (arg == "-") + { + if (++i < args.Argc() && idStr::Cmp(args.Argv(i), "c") == 0) + { + clearFlag = true; + } + } + else + { + missionName = arg; + } + } + + if (missionName.IsEmpty()) + { + return; + } + + CModInfoPtr missionInfo = gameLocal.m_MissionManager->GetModInfo(missionName); + + if (missionInfo == NULL) + { + gameLocal.Printf("Mission %s not found.\n", missionName.c_str()); + return; + } + + if (clearFlag) + { + // Remove completed flags + missionInfo->RemoveKeyValuesMatchingPrefix("mission_completed_"); + } + else + { + // Mark mission as completed on all difficulties + for (int i = 0; i < DIFFICULTY_COUNT; ++i) + { + missionInfo->SetKeyValue(va("mission_completed_%d", i), "1"); + } + } + + gameLocal.Printf("OK"); +} + +void Cmd_EndMission_f(const idCmdArgs& args) +{ + if (gameLocal.GameState() != GAMESTATE_ACTIVE) + { + gameLocal.Printf("No map running\n"); + return; + } + + if (gameLocal.GetLocalPlayer() != NULL) + { + gameLocal.Printf("=== Triggering mission end ===\n"); + gameLocal.GetLocalPlayer()->PostEventMS(&EV_TriggerMissionEnd, 0); + } +} + +/* +================== +Cmd_AttachmentOffset_f +================== +*/ +void Cmd_AttachmentOffset_f( const idCmdArgs &args ) +{ + idVec3 offset(vec3_zero); + + if( args.Argc() != 6 ) + { + gameLocal.Printf( "usage: tdm_attach_offset \n" ); + return; + } + + idEntity* lookedAt = gameLocal.PlayerTraceEntity(); + if (lookedAt == NULL || !(lookedAt->IsType(idActor::Type)) ) + { + gameLocal.Printf( "tdm_attach_offset must be called when looking at an AI\n" ); + return; + } + + idActor* actor = static_cast(lookedAt); + + idStr attName = args.Argv(1); + idStr attPosName = args.Argv(2); + + int attIndex = actor->GetAttachmentIndex(attName); + + SAttachPosition* pos = actor->GetAttachPosition(attPosName); + if (pos == NULL) + { + gameLocal.Printf( "tdm_attach_offset could not find position attPosName %s\n", attPosName.c_str() ); + return; + } + + idStr joint = actor->GetAnimator()->GetJointName(pos->joint); + + // overwrite the attachment with our new attachment + offset.x = atof(args.Argv( 3 )); + offset.y = atof(args.Argv( 4 )); + offset.z = atof(args.Argv( 5 )); + + actor->ReAttachToCoords( attName, joint, offset, pos->angleOffset ); +} + +/* +================== +Cmd_AttachmentRot_f +================== +*/ +void Cmd_AttachmentRot_f( const idCmdArgs &args ) +{ + idVec3 offset(vec3_zero); + + if( args.Argc() != 6 ) + { + gameLocal.Printf( "usage: tdm_attach_rot \n" ); + return; + } + + idEntity* lookedAt = gameLocal.PlayerTraceEntity(); + if (lookedAt == NULL || !(lookedAt->IsType(idActor::Type)) ) + { + gameLocal.Printf( "tdm_attach_rot must be called when looking at an AI\n" ); + return; + } + + idActor* actor = static_cast(lookedAt); + + idStr attName = args.Argv(1); + idStr attPosName = args.Argv(2); + + int attIndex = actor->GetAttachmentIndex(attName); + + SAttachPosition* pos = actor->GetAttachPosition(attPosName); + if (pos == NULL) + { + gameLocal.Printf( "tdm_attach_rot could not find position attPosName %s\n", attPosName.c_str() ); + return; + } + + idStr joint = actor->GetAnimator()->GetJointName(pos->joint); + + // overwrite the attachment rotation with our new one + idAngles angles; + angles.pitch = atof(args.Argv( 3 )); + angles.yaw = atof(args.Argv( 4 )); + angles.roll = atof(args.Argv( 5 )); + + actor->ReAttachToCoords( attName, joint, pos->originOffset, angles ); +} + +/* +================== +Cmd_InventoryHotkey_f +================== +*/ +void Cmd_InventoryHotkey_f( const idCmdArgs &args ) +{ + if ( 0 > args.Argc() || args.Argc() > 2 ) { + gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); + return; + } + + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player == NULL ) { + gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); + return; + } + + if( player->GetImmobilization() & EIM_ITEM_SELECT ) + return; + + CInventoryCursorPtr cursor = player->InventoryCursor(); + CInventory* inventory = cursor->Inventory(); + + if (inventory == NULL) + { + gameLocal.Printf( "%s: Could not find player inventory.\n", args.Argv(0) ); + return; + } + + if( args.Argc() == 2) + { + // support either "#str_02395" or "Lantern" as input + idStr itemName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); + player->SelectInventoryItem( itemName ); + } + else if (args.Argc() == 1) + { + // greebo: Clear the item if no argument is set + player->SelectInventoryItem(""); + } +} + +/* +================== +Cmd_InventoryUse_f +================== +*/ +void Cmd_InventoryUse_f( const idCmdArgs &args ) +{ + if ( 0 > args.Argc() || args.Argc() > 2 ) { + gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); + return; + } + + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player == NULL ) { + gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); + return; + } + + if( player->GetImmobilization() & EIM_ITEM_USE ) + return; + + CInventoryCursorPtr cursor = player->InventoryCursor(); + CInventory* inventory = cursor->Inventory(); + + if (inventory == NULL) + { + gameLocal.Printf( "%s: Could not find player inventory.\n", args.Argv(0) ); + return; + } + + if( args.Argc() == 2) + { + // support either "#str_02395" or "Lantern" as input + idStr itemName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); + + // Try to lookup the item in the inventory + CInventoryItemPtr item = inventory->GetItem( itemName ); + + if (item != NULL) + { + // Item found, set the cursor to it + player->UseInventoryItem(EPressed, item, 0, false); // false => no frob action + } + else + { + gameLocal.Printf( "%s: Can't find item in player inventory: %s (%s)\n", args.Argv(0), args.Argv(1), gameLocal.m_I18N->Translate(itemName) ); + } + } +} + +/* +================== +Cmd_InventoryCycleMaps_f +================== +*/ +void Cmd_InventoryCycleMaps_f( const idCmdArgs &args ) +{ + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player == NULL ) { + gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); + return; + } + + if( (player->GetImmobilization() & EIM_ITEM_SELECT) || (player->GetImmobilization() & EIM_ITEM_USE) ) + return; + + // Pass the call to the specialised method + player->NextInventoryMap(); +} + +/* +================== +Cmd_InventoryCycleGroup_f +================== +*/ +void Cmd_InventoryCycleGroup_f( const idCmdArgs &args ) +{ + if ( 0 > args.Argc() || args.Argc() > 2 ) + { + gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); + return; + } + + idPlayer *player = gameLocal.GetLocalPlayer(); + if ( player == NULL ) + { + gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); + return; + } + + if( (player->GetImmobilization() & EIM_ITEM_SELECT) || (player->GetImmobilization() & EIM_ITEM_USE) ) + { + return; + } + + if( args.Argc() == 2) + { + // support either "#str_02391" or "Readables" as input + idStr categoryName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); + + // Pass the call to the specialised method + player->CycleInventoryGroup( categoryName ); + } +} + +/* +================== +Cmd_GetFloatArg +================== +*/ +float Cmd_GetFloatArg( const idCmdArgs &args, int &argNum ) { + const char *value; + + value = args.Argv( argNum++ ); + return atof( value ); +} + +/* +=================== +Cmd_EntityList_f +=================== +*/ +void Cmd_EntityList_f( const idCmdArgs &args ) { + int e; + idEntity *check; + int count; + size_t size; + idStr match; + + if ( args.Argc() > 1 ) { + match = args.Args(); + match.Replace( " ", "" ); + } else { + match = ""; + } + + count = 0; + size = 0; + + gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" ); + gameLocal.Printf( "--------------------------------------------------------------------\n" ); + for( e = 0; e < MAX_GENTITIES; e++ ) { + check = gameLocal.entities[ e ]; + + if ( !check ) { + continue; + } + + if ( !check->name.Filter( match, true ) ) { + continue; + } + + gameLocal.Printf( "%4i: %-20s %-20s %s\n", e, + check->GetEntityDefName(), check->GetClassname(), check->name.c_str() ); + + count++; + size += check->spawnArgs.Allocated(); + } + + gameLocal.Printf( "...%d entities\n...%d bytes of spawnargs\n", count, size ); +} + +/* +=================== +Cmd_ActiveEntityList_f +=================== +*/ +void Cmd_ActiveEntityList_f( const idCmdArgs &args ) { + idEntity *check; + int count; + + count = 0; + + gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" ); + gameLocal.Printf( "--------------------------------------------------------------------\n" ); + for( check = gameLocal.activeEntities.Next(); check != NULL; check = check->activeNode.Next() ) { + char dormant = check->fl.isDormant ? '-' : ' '; + gameLocal.Printf( "%4i:%c%-20s %-20s %s\n", check->entityNumber, dormant, check->GetEntityDefName(), check->GetClassname(), check->name.c_str() ); + count++; + } + + gameLocal.Printf( "...%d active entities\n", count ); +} + +/* +=================== +Cmd_ListSpawnArgs_f +=================== +*/ +void Cmd_ListSpawnArgs_f( const idCmdArgs &args ) { + int i; + idEntity *ent; + + ent = gameLocal.FindEntity( args.Argv( 1 ) ); + if ( !ent ) { + gameLocal.Printf( "entity not found\n" ); + return; + } + + for ( i = 0; i < ent->spawnArgs.GetNumKeyVals(); i++ ) { + const idKeyValue *kv = ent->spawnArgs.GetKeyVal( i ); + gameLocal.Printf( "\"%s\" "S_COLOR_WHITE"\"%s\"\n", kv->GetKey().c_str(), kv->GetValue().c_str() ); + } +} + +/* +=================== +Cmd_ReloadScript_f +=================== +*/ +void Cmd_ReloadScript_f( const idCmdArgs &args ) { + // shutdown the map because entities may point to script objects + gameLocal.MapShutdown(); + + // recompile the scripts + gameLocal.program.Startup( SCRIPT_DEFAULT ); + + // error out so that the user can rerun the scripts + gameLocal.Error( "Exiting map to reload scripts" ); +} + +/* +=================== +Cmd_Script_f +=================== +*/ +void Cmd_Script_f( const idCmdArgs &args ) { + const char * script; + idStr text; + idStr funcname; + static int funccount = 0; + idThread * thread; + const function_t *func; + idEntity *ent; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + sprintf( funcname, "ConsoleFunction_%d", funccount++ ); + + script = args.Args(); + sprintf( text, "void %s() {%s;}\n", funcname.c_str(), script ); + if ( gameLocal.program.CompileText( "console", text, true ) ) { + func = gameLocal.program.FindFunction( funcname ); + if ( func ) { + // set all the entity names in case the user named one in the script that wasn't referenced in the default script + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + gameLocal.program.SetEntity( ent->name, ent ); + } + + thread = new idThread( func ); + thread->Start(); + } + } +} + +/* +================== +KillEntities + +Kills all the entities of the given class in a level. +================== +*/ +void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) { + idEntity *ent; + idStrList ignore; + const char *name; + int i; + + if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { + return; + } + + for( i = 1; i < args.Argc(); i++ ) { + name = args.Argv( i ); + ignore.Append( name ); + } + + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->IsType( superClass ) ) { + for( i = 0; i < ignore.Num(); i++ ) { + if ( ignore[ i ] == ent->name ) { + break; + } + } + + if ( i >= ignore.Num() ) { + ent->PostEventMS( &EV_Remove, 0 ); + } + } + } +} + +/* +================== +Cmd_KillMonsters_f + +Kills all the monsters in a level. +================== +*/ +void Cmd_KillMonsters_f( const idCmdArgs &args ) { + KillEntities( args, idAI::Type ); + + // kill any projectiles as well since they have pointers to the monster that created them + KillEntities( args, idProjectile::Type ); +} + +/* +================== +Cmd_KillMovables_f + +Kills all the moveables in a level. +================== +*/ +void Cmd_KillMovables_f( const idCmdArgs &args ) { + if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { + return; + } + KillEntities( args, idMoveable::Type ); +} + +/* +================== +Cmd_KillRagdolls_f + +Kills all the ragdolls in a level. +================== +*/ +void Cmd_KillRagdolls_f( const idCmdArgs &args ) { + if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { + return; + } + KillEntities( args, idAFEntity_Generic::Type ); + KillEntities( args, idAFEntity_WithAttachedHead::Type ); +} + +/* +================== +Cmd_Give_f + +Give items to a client +================== +*/ +void Cmd_Give_f( const idCmdArgs &args ) { + const char *name; + int i; + bool give_all; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + name = args.Argv( 1 ); + + if ( idStr::Icmp( name, "all" ) == 0 ) { + give_all = true; + } else { + give_all = false; + } + + if ( give_all || ( idStr::Cmpn( name, "weapon", 6 ) == 0 ) ) { + if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { + gameLocal.world->spawnArgs.SetBool( "no_Weapons", false ); + for( i = 0; i < gameLocal.numClients; i++ ) { + if ( gameLocal.entities[ i ] ) { + gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, gameLocal.entities[ i ]->spawnArgs.GetString( "def_weapon1" ) ); + } + } + } + } + + if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) { + player->GiveItem( name ); + return; + } + + if ( give_all || idStr::Icmp( name, "health" ) == 0 ) { + player->health = player->maxHealth; + if ( !give_all ) { + return; + } + } + + if ( idStr::Icmp( name, "berserk" ) == 0 ) { + player->GivePowerUp( BERSERK, SEC2MS( 30.0f ) ); + return; + } + + if ( idStr::Icmp( name, "invis" ) == 0 ) { + player->GivePowerUp( INVISIBILITY, SEC2MS( 30.0f ) ); + return; + } + + if ( !give_all && !player->Give( args.Argv(1), args.Argv(2) ) ) { + gameLocal.Printf( "unknown item\n" ); + } +} + +/* +================== +Cmd_CenterView_f + +Centers the players pitch +================== +*/ +void Cmd_CenterView_f( const idCmdArgs &args ) { + idPlayer *player; + idAngles ang; + + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + + ang = player->viewAngles; + ang.pitch = 0.0f; + player->SetViewAngles( ang ); +} + +/* +================== +Cmd_God_f + +Sets client to godmode + +argv(0) god +================== +*/ +void Cmd_God_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player->godmode ) { + player->godmode = false; + gameLocal.Printf( "godmode OFF\n" ); + } else { + player->godmode = true; + gameLocal.Printf( "godmode ON\n" ); + } + +} + +/* +================== +Cmd_Notarget_f + +Sets client to notarget + +argv(0) notarget +================== +*/ +void Cmd_Notarget_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player->fl.notarget ) { + player->fl.notarget = false; + gameLocal.Printf( "notarget OFF\n" ); + } else { + player->fl.notarget = true; + gameLocal.Printf( "notarget ON\n" ); + } + +} + +/* +================== +Cmd_Noclip_f + +argv(0) noclip +================== +*/ +void Cmd_Noclip_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player->noclip ) { + player->noclip = false; + gameLocal.Printf( "noclip OFF\n" ); + } else { + player->noclip = true; + gameLocal.Printf( "noclip ON\n" ); + } +} + +/* +================= +Cmd_Kill_f +================= +*/ +void Cmd_Kill_f( const idCmdArgs &args ) { + idPlayer *player; + + if ( gameLocal.isMultiplayer ) { + if ( gameLocal.isClient ) { + idBitMsg outMsg; + byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL ); + networkSystem->ClientSendReliableMessage( outMsg ); + } else { + player = gameLocal.GetClientByCmdArgs( args ); + if ( !player ) { + common->Printf( "kill or kill \n" ); + return; + } + player->Kill( false, false ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) ); + } + } else { + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + player->Kill( false, false ); + } +} + +/* +================= +Cmd_PlayerModel_f +================= +*/ +void Cmd_PlayerModel_f( const idCmdArgs &args ) { + idPlayer *player; + const char *name; + idVec3 pos; + idAngles ang; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() < 2 ) { + gameLocal.Printf( "usage: playerModel \n" ); + return; + } + + name = args.Argv( 1 ); + player->spawnArgs.Set( "model", name ); + + pos = player->GetPhysics()->GetOrigin(); + ang = player->viewAngles; + player->SpawnToPoint( pos, ang ); +} + +/* +================== +Cmd_Say +================== +*/ +static void Cmd_Say( bool team, const idCmdArgs &args ) { + const char *name; + idStr text; + const char *cmd = team ? "sayTeam" : "say" ; + + if ( !gameLocal.isMultiplayer ) { + gameLocal.Printf( "%s can only be used in a multiplayer game\n", cmd ); + return; + } + + if ( args.Argc() < 2 ) { + gameLocal.Printf( "usage: %s \n", cmd ); + return; + } + + text = args.Args(); + if ( text.Length() == 0 ) { + return; + } + + if ( text[ text.Length() - 1 ] == '\n' ) { + text[ text.Length() - 1 ] = '\0'; + } + name = "player"; + + idPlayer * player; + + // here we need to special case a listen server to use the real client name instead of "server" + // "server" will only appear on a dedicated server + if ( gameLocal.isClient || cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 0 ) { + player = gameLocal.localClientNum >= 0 ? static_cast( gameLocal.entities[ gameLocal.localClientNum ] ) : NULL; + if ( player ) { + name = player->GetUserInfo()->GetString( "ui_name", "player" ); + } + } else { + name = "server"; + } + + if ( gameLocal.isClient ) { + idBitMsg outMsg; + byte msgBuf[ 256 ]; + outMsg.Init( msgBuf, sizeof( msgBuf ) ); + outMsg.WriteByte( team ? GAME_RELIABLE_MESSAGE_TCHAT : GAME_RELIABLE_MESSAGE_CHAT ); + outMsg.WriteString( name ); + outMsg.WriteString( text, -1, false ); + networkSystem->ClientSendReliableMessage( outMsg ); + } else { + gameLocal.mpGame.ProcessChatMessage( gameLocal.localClientNum, team, name, text, NULL ); + } +} + +/* +================== +Cmd_Say_f +================== +*/ +static void Cmd_Say_f( const idCmdArgs &args ) { + Cmd_Say( false, args ); +} + +/* +================== +Cmd_SayTeam_f +================== +*/ +static void Cmd_SayTeam_f( const idCmdArgs &args ) { + Cmd_Say( true, args ); +} + +/* +================== +Cmd_AddChatLine_f +================== +*/ +static void Cmd_AddChatLine_f( const idCmdArgs &args ) { + gameLocal.mpGame.AddChatLine( args.Argv( 1 ) ); +} + +/* +================== +Cmd_Kick_f +================== +*/ +static void Cmd_Kick_f( const idCmdArgs &args ) { + idPlayer *player; + + if ( !gameLocal.isMultiplayer ) { + gameLocal.Printf( "kick can only be used in a multiplayer game\n" ); + return; + } + + if ( gameLocal.isClient ) { + gameLocal.Printf( "You have no such power. This is a server command\n" ); + return; + } + + player = gameLocal.GetClientByCmdArgs( args ); + if ( !player ) { + gameLocal.Printf( "usage: kick or kick \n" ); + return; + } + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say kicking out client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %d\n", player->entityNumber ) ); +} + +/* +================== +Cmd_GetViewpos_f +================== +*/ +void Cmd_GetViewpos_f( const idCmdArgs &args ) { + idPlayer *player; + idVec3 origin; + idMat3 axis; + + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + + const renderView_t *view = player->GetRenderView(); + if ( view ) { + gameLocal.Printf( "(%s) %.1f\n", view->vieworg.ToString(), view->viewaxis[0].ToYaw() ); + } else { + player->GetViewPos( origin, axis ); + gameLocal.Printf( "(%s) %.1f\n", origin.ToString(), axis[0].ToYaw() ); + } +} + +/* +================= +Cmd_SetViewpos_f +================= +*/ +void Cmd_SetViewpos_f( const idCmdArgs &args ) { + idVec3 origin; + idAngles angles; + int i; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( ( args.Argc() != 4 ) && ( args.Argc() != 5 ) ) { + gameLocal.Printf( "usage: setviewpos \n" ); + return; + } + + angles.Zero(); + if ( args.Argc() == 5 ) { + angles.yaw = atof( args.Argv( 4 ) ); + } + + for ( i = 0 ; i < 3 ; i++ ) { + origin[i] = atof( args.Argv( i + 1 ) ); + } + origin.z -= pm_normalviewheight.GetFloat() - 0.25f; + + player->Teleport( origin, angles, NULL ); +} + +/* +================= +Cmd_Teleport_f +================= +*/ +void Cmd_Teleport_f( const idCmdArgs &args ) { + idVec3 origin; + idAngles angles; + idPlayer *player; + idEntity *ent; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() != 2 ) { + gameLocal.Printf( "usage: teleport \n" ); + return; + } + + ent = gameLocal.FindEntity( args.Argv( 1 ) ); + if ( !ent ) { + gameLocal.Printf( "entity not found\n" ); + return; + } + + angles.Zero(); + angles.yaw = ent->GetPhysics()->GetAxis()[ 0 ].ToYaw(); + origin = ent->GetPhysics()->GetOrigin(); + + player->Teleport( origin, angles, ent ); +} + +/* +================= +Cmd_Trigger_f +================= +*/ +void Cmd_Trigger_f( const idCmdArgs &args ) { + idVec3 origin; + idAngles angles; + idPlayer *player; + idEntity *ent; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() != 2 ) { + gameLocal.Printf( "usage: trigger \n" ); + return; + } + + ent = gameLocal.FindEntity( args.Argv( 1 ) ); + if ( !ent ) { + gameLocal.Printf( "entity not found\n" ); + return; + } + + ent->Signal( SIG_TRIGGER ); + ent->ProcessEvent( &EV_Activate, player ); + ent->TriggerGuis(); +} + +/* +=================== +Cmd_Spawn_f +=================== +*/ +void Cmd_Spawn_f( const idCmdArgs &args ) { + const char *key, *value; + int i; + float yaw; + idVec3 org; + idPlayer *player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk( false ) ) { + return; + } + + if ( args.Argc() & 1 ) { // must always have an even number of arguments + gameLocal.Printf( "usage: spawn classname [key/value pairs]\n" ); + return; + } + + yaw = player->viewAngles.yaw; + + value = args.Argv( 1 ); + dict.Set( "classname", value ); + dict.Set( "angle", va( "%f", yaw + 180 ) ); + + org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); + dict.Set( "origin", org.ToString() ); + + for( i = 2; i < args.Argc() - 1; i += 2 ) { + + key = args.Argv( i ); + value = args.Argv( i + 1 ); + + dict.Set( key, value ); + } + + gameLocal.SpawnEntityDef( dict ); +} + +/* +================== +Cmd_Damage_f + +Damages the specified entity +================== +*/ +void Cmd_Damage_f( const idCmdArgs &args ) { + if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { + return; + } + if ( args.Argc() != 3 ) { + gameLocal.Printf( "usage: damage \n" ); + return; + } + + idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) ); + if ( !ent ) { + gameLocal.Printf( "entity not found\n" ); + return; + } + + ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT ); +} + + +/* +================== +Cmd_Remove_f + +Removes the specified entity +================== +*/ +void Cmd_Remove_f( const idCmdArgs &args ) { + if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { + return; + } + if ( args.Argc() != 2 ) { + gameLocal.Printf( "usage: remove \n" ); + return; + } + + idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) ); + if ( !ent ) { + gameLocal.Printf( "entity not found\n" ); + return; + } + + delete ent; +} + +/* +=================== +Cmd_TestLight_f +=================== +*/ +void Cmd_TestLight_f( const idCmdArgs &args ) { + int i; + idStr filename; + const char *key, *value, *name(NULL); + idPlayer * player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk( false ) ) { + return; + } + + renderView_t *rv = player->GetRenderView(); + + float fov = tan( idMath::M_DEG2RAD * rv->fov_x / 2 ); + + + dict.SetMatrix( "rotation", mat3_default ); + dict.SetVector( "origin", rv->vieworg ); + dict.SetVector( "light_target", rv->viewaxis[0] ); + dict.SetVector( "light_right", rv->viewaxis[1] * -fov ); + dict.SetVector( "light_up", rv->viewaxis[2] * fov ); + dict.SetVector( "light_start", rv->viewaxis[0] * 16 ); + dict.SetVector( "light_end", rv->viewaxis[0] * 1000 ); + + if ( args.Argc() >= 2 ) { + value = args.Argv( 1 ); + filename = args.Argv(1); + filename.DefaultFileExtension( ".tga" ); + dict.Set( "texture", filename ); + } + + dict.Set( "classname", "light" ); + for( i = 2; i < args.Argc() - 1; i += 2 ) { + + key = args.Argv( i ); + value = args.Argv( i + 1 ); + + dict.Set( key, value ); + } + + for ( i = 0; i < MAX_GENTITIES; i++ ) { + name = va( "spawned_light_%d", i ); // not just light_, or it might pick up a prelight shadow + if ( !gameLocal.FindEntity( name ) ) { + break; + } + } + dict.Set( "name", name ); + + gameLocal.SpawnEntityDef( dict ); + + gameLocal.Printf( "Created new light\n"); +} + +/* +=================== +Cmd_TestPointLight_f +=================== +*/ +void Cmd_TestPointLight_f( const idCmdArgs &args ) { + const char *key, *value, *name(NULL); + int i; + idPlayer *player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk( false ) ) { + return; + } + + dict.SetVector("origin", player->GetRenderView()->vieworg); + + if ( args.Argc() >= 2 ) { + value = args.Argv( 1 ); + dict.Set("light", value); + } else { + dict.Set("light", "300"); + } + + dict.Set( "classname", "light" ); + for( i = 2; i < args.Argc() - 1; i += 2 ) { + + key = args.Argv( i ); + value = args.Argv( i + 1 ); + + dict.Set( key, value ); + } + + for ( i = 0; i < MAX_GENTITIES; i++ ) { + name = va( "light_%d", i ); + if ( !gameLocal.FindEntity( name ) ) { + break; + } + } + dict.Set( "name", name ); + + gameLocal.SpawnEntityDef( dict ); + + gameLocal.Printf( "Created new point light\n"); +} + +/* +================== +Cmd_PopLight_f +================== +*/ +void Cmd_PopLight_f( const idCmdArgs &args ) { + idEntity *ent; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idLight *lastLight; + int last; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + bool removeFromMap = ( args.Argc() > 1 ); + + lastLight = NULL; + last = -1; + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + if ( !ent->IsType( idLight::Type ) ) { + continue; + } + + if ( gameLocal.spawnIds[ ent->entityNumber ] > last ) { + last = gameLocal.spawnIds[ ent->entityNumber ]; + lastLight = static_cast( ent ); + } + } + + if ( lastLight ) { + // find map file entity + mapEnt = mapFile->FindEntity( lastLight->name ); + + if ( removeFromMap && mapEnt ) { + mapFile->RemoveEntity( mapEnt ); + } + gameLocal.Printf( "Removing light %i\n", lastLight->GetLightDefHandle() ); + delete lastLight; + } else { + gameLocal.Printf( "No lights to clear.\n" ); + } + +} + +/* +==================== +Cmd_ClearLights_f +==================== +*/ +void Cmd_ClearLights_f( const idCmdArgs &args ) { + idEntity *ent; + idEntity *next; + idLight *light; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + + bool removeFromMap = ( args.Argc() > 1 ); + + gameLocal.Printf( "Clearing all lights.\n" ); + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = next ) { + next = ent->spawnNode.Next(); + if ( !ent->IsType( idLight::Type ) ) { + continue; + } + + light = static_cast( ent ); + mapEnt = mapFile->FindEntity( light->name ); + + if ( removeFromMap && mapEnt ) { + mapFile->RemoveEntity( mapEnt ); + } + + delete light; + } +} + +/* +================== +Cmd_TestFx_f +================== +*/ +void Cmd_TestFx_f( const idCmdArgs &args ) { + idVec3 offset; + const char *name; + idPlayer * player; + idDict dict; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + // delete the testModel if active + if ( gameLocal.testFx ) { + delete gameLocal.testFx; + gameLocal.testFx = NULL; + } + + if ( args.Argc() < 2 ) { + return; + } + + name = args.Argv( 1 ); + + offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f; + + dict.Set( "origin", offset.ToString() ); + dict.Set( "test", "1"); + dict.Set( "fx", name ); + gameLocal.testFx = ( idEntityFx * )gameLocal.SpawnEntityType( idEntityFx::Type, &dict ); +} + +#define MAX_DEBUGLINES 128 + +typedef struct { + bool used; + idVec3 start, end; + int color; + bool blink; + bool arrow; +} gameDebugLine_t; + +gameDebugLine_t debugLines[MAX_DEBUGLINES]; + +/* +================== +Cmd_AddDebugLine_f +================== +*/ +static void Cmd_AddDebugLine_f( const idCmdArgs &args ) { + int i, argNum; + const char *value; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc () < 7 ) { + gameLocal.Printf( "usage: addline \n" ); + return; + } + for ( i = 0; i < MAX_DEBUGLINES; i++ ) { + if ( !debugLines[i].used ) { + break; + } + } + if ( i >= MAX_DEBUGLINES ) { + gameLocal.Printf( "no free debug lines\n" ); + return; + } + value = args.Argv( 0 ); + if ( !idStr::Icmp( value, "addarrow" ) ) { + debugLines[i].arrow = true; + } else { + debugLines[i].arrow = false; + } + debugLines[i].used = true; + debugLines[i].blink = false; + argNum = 1; + debugLines[i].start.x = Cmd_GetFloatArg( args, argNum ); + debugLines[i].start.y = Cmd_GetFloatArg( args, argNum ); + debugLines[i].start.z = Cmd_GetFloatArg( args, argNum ); + debugLines[i].end.x = Cmd_GetFloatArg( args, argNum ); + debugLines[i].end.y = Cmd_GetFloatArg( args, argNum ); + debugLines[i].end.z = Cmd_GetFloatArg( args, argNum ); + debugLines[i].color = static_cast(Cmd_GetFloatArg( args, argNum )); +} + +/* +================== +Cmd_RemoveDebugLine_f +================== +*/ +static void Cmd_RemoveDebugLine_f( const idCmdArgs &args ) { + int i, num; + const char *value; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc () < 2 ) { + gameLocal.Printf( "usage: removeline \n" ); + return; + } + value = args.Argv( 1 ); + num = atoi(value); + for ( i = 0; i < MAX_DEBUGLINES; i++ ) { + if ( debugLines[i].used ) { + if ( --num < 0 ) { + break; + } + } + } + if ( i >= MAX_DEBUGLINES ) { + gameLocal.Printf( "line not found\n" ); + return; + } + debugLines[i].used = false; +} + +/* +================== +Cmd_BlinkDebugLine_f +================== +*/ +static void Cmd_BlinkDebugLine_f( const idCmdArgs &args ) { + int i, num; + const char *value; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc () < 2 ) { + gameLocal.Printf( "usage: blinkline \n" ); + return; + } + value = args.Argv( 1 ); + num = atoi( value ); + for ( i = 0; i < MAX_DEBUGLINES; i++ ) { + if ( debugLines[i].used ) { + if ( --num < 0 ) { + break; + } + } + } + if ( i >= MAX_DEBUGLINES ) { + gameLocal.Printf( "line not found\n" ); + return; + } + debugLines[i].blink = !debugLines[i].blink; +} + +/* +================== +PrintFloat +================== +*/ +static void PrintFloat( float f ) { + char buf[128]; + int i; + + for (i = sprintf( buf, "%3.2f", f ); i < 7; i++) { + buf[i] = ' '; + } + buf[i] = '\0'; + gameLocal.Printf( buf ); +} + +/* +================== +Cmd_ListDebugLines_f +================== +*/ +static void Cmd_ListDebugLines_f( const idCmdArgs &args ) { + int i, num; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + num = 0; + gameLocal.Printf( "line num: x1 y1 z1 x2 y2 z2 c b a\n" ); + for ( i = 0; i < MAX_DEBUGLINES; i++ ) { + if ( debugLines[i].used ) { + gameLocal.Printf( "line %3d: ", num ); + PrintFloat( debugLines[i].start.x ); + PrintFloat( debugLines[i].start.y ); + PrintFloat( debugLines[i].start.z ); + PrintFloat( debugLines[i].end.x ); + PrintFloat( debugLines[i].end.y ); + PrintFloat( debugLines[i].end.z ); + gameLocal.Printf( "%d %d %d\n", debugLines[i].color, debugLines[i].blink, debugLines[i].arrow ); + num++; + } + } + if ( !num ) { + gameLocal.Printf( "no debug lines\n" ); + } +} + +/* +================== +D_DrawDebugLines +================== +*/ +void D_DrawDebugLines( void ) { + int i; + idVec3 forward, right, up, p1, p2; + idVec4 color; + float l; + + for ( i = 0; i < MAX_DEBUGLINES; i++ ) { + if ( debugLines[i].used ) { + if ( !debugLines[i].blink || (gameLocal.time & (1<<9)) ) { + color = idVec4( debugLines[i].color&1, (debugLines[i].color>>1)&1, (debugLines[i].color>>2)&1, 1 ); + gameRenderWorld->DebugLine( color, debugLines[i].start, debugLines[i].end ); + // + if ( debugLines[i].arrow ) { + // draw a nice arrow + forward = debugLines[i].end - debugLines[i].start; + l = forward.Normalize() * 0.2f; + forward.NormalVectors( right, up); + + if ( l > 3.0f ) { + l = 3.0f; + } + p1 = debugLines[i].end - l * forward + (l * 0.4f) * right; + p2 = debugLines[i].end - l * forward - (l * 0.4f) * right; + gameRenderWorld->DebugLine( color, debugLines[i].end, p1 ); + gameRenderWorld->DebugLine( color, debugLines[i].end, p2 ); + gameRenderWorld->DebugLine( color, p1, p2 ); + } + } + } + } +} + +/* +================== +Cmd_ListCollisionModels_f +================== +*/ +static void Cmd_ListCollisionModels_f( const idCmdArgs &args ) { + if ( !gameLocal.CheatsOk() ) { + return; + } + + collisionModelManager->ListModels(); +} + +/* +================== +Cmd_CollisionModelInfo_f +================== +*/ +static void Cmd_CollisionModelInfo_f( const idCmdArgs &args ) { + const char *value; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc () < 2 ) { + gameLocal.Printf( "usage: collisionModelInfo \n" + "use 'all' instead of the model number for accumulated info\n" ); + return; + } + + value = args.Argv( 1 ); + if ( !idStr::Icmp( value, "all" ) ) { + collisionModelManager->ModelInfo( -1 ); + } else { + collisionModelManager->ModelInfo( atoi(value) ); + } +} + +/* +================== +Cmd_ExportModels_f +================== +*/ +static void Cmd_ExportModels_f( const idCmdArgs &args ) { + idModelExport exporter; + idStr name; + + // don't allow exporting models when cheats are disabled, + // but if we're not in the game, it's ok + if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { + return; + } + + if ( args.Argc() < 2 ) { + exporter.ExportModels( "def", ".def" ); + } else { + name = args.Argv( 1 ); + name = "def/" + name; + name.DefaultFileExtension( ".def" ); + exporter.ExportDefFile( name ); + } +} + +/* +================== +Cmd_ReexportModels_f +================== +*/ +static void Cmd_ReexportModels_f( const idCmdArgs &args ) { + idModelExport exporter; + idStr name; + + // don't allow exporting models when cheats are disabled, + // but if we're not in the game, it's ok + if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { + return; + } + + idAnimManager::forceExport = true; + if ( args.Argc() < 2 ) { + exporter.ExportModels( "def", ".def" ); + } else { + name = args.Argv( 1 ); + name = "def/" + name; + name.DefaultFileExtension( ".def" ); + exporter.ExportDefFile( name ); + } + idAnimManager::forceExport = false; +} + +/* +================== +Cmd_ReloadAnims_f +================== +*/ +static void Cmd_ReloadAnims_f( const idCmdArgs &args ) { + // don't allow reloading anims when cheats are disabled, + // but if we're not in the game, it's ok + if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { + return; + } + + animationLib.ReloadAnims(); +} + +/* +================== +Cmd_ListAnims_f +================== +*/ +static void Cmd_ListAnims_f( const idCmdArgs &args ) { + idEntity * ent; + int num; + size_t size; + size_t alloced; + idAnimator * animator; + const char * classname; + const idDict * dict; + int i; + + if ( args.Argc() > 1 ) { + idAnimator animator; + + classname = args.Argv( 1 ); + + dict = gameLocal.FindEntityDefDict( classname, false ); + if ( !dict ) { + gameLocal.Printf( "Entitydef '%s' not found\n", classname ); + return; + } + animator.SetModel( dict->GetString( "model" ) ); + + gameLocal.Printf( "----------------\n" ); + num = animator.NumAnims(); + for( i = 0; i < num; i++ ) { + gameLocal.Printf( "%s\n", animator.AnimFullName( i ) ); + } + gameLocal.Printf( "%d anims\n", num ); + } else { + animationLib.ListAnims(); + + size = 0; + num = 0; + for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { + animator = ent->GetAnimator(); + if ( animator ) { + alloced = animator->Allocated(); + size += alloced; + num++; + } + } + + gameLocal.Printf( "%d memory used in %d entity animators\n", size, num ); + } +} + +// greebo: Reload the xdata declarations by forcing the declaration manager to perform a reload +static void Cmd_ReloadXData_f( const idCmdArgs &args ) +{ + // Reload the declarations, this triggers a re-parse of all xdata files (and all other files on that matter) + declManager->Reload(true); + // greebo: This is called twice on purpose. For some reason, the first reload doesn't reload the xdata files. + declManager->Reload(true); + + // Now cycle through all active entities and call "refreshReadables" on them + for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + idThread* thread = ent->CallScriptFunctionArgs("reloadXData", true, 0, "e", ent); + + if (thread != NULL) + { + thread->Execute(); + } + } +} + +/* +================== +Cmd_AASStats_f +================== +*/ +static void Cmd_AASStats_f( const idCmdArgs &args ) { + int aasNum; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + aasNum = aas_test.GetInteger(); + idAAS *aas = gameLocal.GetAAS( aasNum ); + if ( !aas ) { + gameLocal.Printf( "No aas #%d loaded\n", aasNum ); + } else { + aas->Stats(); + } +} + +/* +================== +Cmd_TestDamage_f +================== +*/ +static void Cmd_TestDamage_f( const idCmdArgs &args ) { + idPlayer *player; + const char *damageDefName; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() < 2 || args.Argc() > 3 ) { + gameLocal.Printf( "usage: testDamage [angle]\n" ); + return; + } + + damageDefName = args.Argv( 1 ); + + idVec3 dir; + if ( args.Argc() == 3 ) { + float angle = atof( args.Argv( 2 ) ); + + idMath::SinCos( DEG2RAD( angle ), dir[1], dir[0] ); + dir[2] = 0; + } else { + dir.Zero(); + } + + // give the player full health before and after + // running the damage + player->health = player->maxHealth; + player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT ); + player->health = player->maxHealth; +} + +/* +================== +Cmd_TestBoneFx_f +================== +*/ +static void Cmd_TestBoneFx_f( const idCmdArgs &args ) { + idPlayer *player; + const char *bone, *fx; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() < 3 || args.Argc() > 4 ) { + gameLocal.Printf( "usage: testBoneFx \n" ); + return; + } + + fx = args.Argv( 1 ); + bone = args.Argv( 2 ); + + player->StartFxOnBone( fx, bone ); +} + +/* +================== +Cmd_TestDamage_f +================== +*/ +static void Cmd_TestDeath_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + idVec3 dir; + idMath::SinCos( DEG2RAD( 45.0f ), dir[1], dir[0] ); + dir[2] = 0; + + g_testDeath.SetBool( 1 ); + player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT ); + if ( args.Argc() >= 2) { + player->SpawnGibs( dir, "damage_triggerhurt_1000" ); + } + +} + +/* +================== +Cmd_WeaponSplat_f +================== +*/ +static void Cmd_WeaponSplat_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + player->weapon.GetEntity()->BloodSplat( 2.0f ); +} + +/* +================== +Cmd_SaveSelected_f +================== +*/ +static void Cmd_SaveSelected_f( const idCmdArgs &args ) { + int i; + idPlayer *player; + idEntity *s; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idDict dict; + idStr mapName; + const char *name(NULL); + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + s = player->dragEntity.GetSelected(); + if ( !s ) { + gameLocal.Printf( "no entity selected, set g_dragShowSelection 1 to show the current selection\n" ); + return; + } + + if ( args.Argc() > 1 ) { + mapName = args.Argv( 1 ); + mapName = "maps/" + mapName; + } + else { + mapName = mapFile->GetName(); + } + + // find map file entity + mapEnt = mapFile->FindEntity( s->name ); + // create new map file entity if there isn't one for this articulated figure + if ( !mapEnt ) { + mapEnt = new idMapEntity(); + mapFile->AddEntity( mapEnt ); + for ( i = 0; i < 9999; i++ ) { + name = va( "%s_%d", s->GetEntityDefName(), i ); + if ( !mapFile->FindEntity( name ) ) + break; + } + s->name = name; + mapEnt->epairs.Set( "classname", s->GetEntityDefName() ); + mapEnt->epairs.Set( "name", s->name ); + } + + if ( s->IsType( idMoveable::Type ) ) { + // save the moveable state + mapEnt->epairs.Set( "origin", s->GetPhysics()->GetOrigin().ToString( 8 ) ); + mapEnt->epairs.Set( "rotation", s->GetPhysics()->GetAxis().ToString( 8 ) ); + } + else if ( s->IsType( idAFEntity_Generic::Type ) || s->IsType( idAFEntity_WithAttachedHead::Type ) ) { + // save the articulated figure state + dict.Clear(); + static_cast(s)->SaveState( dict ); + mapEnt->epairs.Copy( dict ); + } + + // write out the map file + mapFile->Write( mapName, ".map" ); +} + +/* +================== +Cmd_DeleteSelected_f +================== +*/ +static void Cmd_DeleteSelected_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player ) { + player->dragEntity.DeleteSelected(); + } +} + +/* +================== +Cmd_SaveMoveables_f +================== +*/ +static void Cmd_SaveMoveables_f( const idCmdArgs &args ) { + int e, i; + idMoveable *m; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idStr mapName; + const char *name(NULL); + + if ( !gameLocal.CheatsOk() ) { + return; + } + + for( e = 0; e < MAX_GENTITIES; e++ ) { + m = static_cast(gameLocal.entities[ e ]); + + if ( !m || !m->IsType( idMoveable::Type ) ) { + continue; + } + + if ( m->IsBound() ) { + continue; + } + + if ( !m->IsAtRest() ) { + break; + } + } + + if ( e < MAX_GENTITIES ) { + gameLocal.Warning( "map not saved because the moveable entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() ); + return; + } + + if ( args.Argc() > 1 ) { + mapName = args.Argv( 1 ); + mapName = "maps/" + mapName; + } + else { + mapName = mapFile->GetName(); + } + + for( e = 0; e < MAX_GENTITIES; e++ ) { + m = static_cast(gameLocal.entities[ e ]); + + if ( !m || !m->IsType( idMoveable::Type ) ) { + continue; + } + + if ( m->IsBound() ) { + continue; + } + + // find map file entity + mapEnt = mapFile->FindEntity( m->name ); + // create new map file entity if there isn't one for this articulated figure + if ( !mapEnt ) { + mapEnt = new idMapEntity(); + mapFile->AddEntity( mapEnt ); + for ( i = 0; i < 9999; i++ ) { + name = va( "%s_%d", m->GetEntityDefName(), i ); + if ( !mapFile->FindEntity( name ) ) + break; + } + m->name = name; + mapEnt->epairs.Set( "classname", m->GetEntityDefName() ); + mapEnt->epairs.Set( "name", m->name ); + } + // save the moveable state + mapEnt->epairs.Set( "origin", m->GetPhysics()->GetOrigin().ToString( 8 ) ); + mapEnt->epairs.Set( "rotation", m->GetPhysics()->GetAxis().ToString( 8 ) ); + } + + // write out the map file + mapFile->Write( mapName, ".map" ); +} + +/* +================== +Cmd_SaveRagdolls_f +================== +*/ +static void Cmd_SaveRagdolls_f( const idCmdArgs &args ) { + int e, i; + idAFEntity_Base *af; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idDict dict; + idStr mapName; + const char *name(NULL); + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() > 1 ) { + mapName = args.Argv( 1 ); + mapName = "maps/" + mapName; + } + else { + mapName = mapFile->GetName(); + } + + for( e = 0; e < MAX_GENTITIES; e++ ) { + af = static_cast(gameLocal.entities[ e ]); + + if ( !af ) { + continue; + } + + if ( !af->IsType( idAFEntity_WithAttachedHead::Type ) && !af->IsType( idAFEntity_Generic::Type ) ) { + continue; + } + + // Ish: Not sure why they did this + /* + if ( af->IsBound() ) { + continue; + } + */ + + if ( !af->IsAtRest() ) { + gameLocal.Warning( "the articulated figure for entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() ); + } + + dict.Clear(); + af->SaveState( dict ); + + // find map file entity + mapEnt = mapFile->FindEntity( af->name ); + // create new map file entity if there isn't one for this articulated figure + if ( !mapEnt ) { + mapEnt = new idMapEntity(); + mapFile->AddEntity( mapEnt ); + for ( i = 0; i < 9999; i++ ) { + name = va( "%s_%d", af->GetEntityDefName(), i ); + if ( !mapFile->FindEntity( name ) ) + break; + } + af->name = name; + mapEnt->epairs.Set( "classname", af->GetEntityDefName() ); + mapEnt->epairs.Set( "name", af->name ); + } + // save the articulated figure state + mapEnt->epairs.Copy( dict ); + } + + // write out the map file + mapFile->Write( mapName, ".map" ); +} + +/* +================== +Cmd_BindRagdoll_f +================== +*/ +static void Cmd_BindRagdoll_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player ) { + player->dragEntity.BindSelected(); + } +} + +/* +================== +Cmd_UnbindRagdoll_f +================== +*/ +static void Cmd_UnbindRagdoll_f( const idCmdArgs &args ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( player ) { + player->dragEntity.UnbindSelected(); + } +} + +/* +================== +Cmd_GameError_f +================== +*/ +static void Cmd_GameError_f( const idCmdArgs &args ) { + gameLocal.Error( "game error" ); +} + +/* +================== +Cmd_SaveLights_f +================== +*/ +static void Cmd_SaveLights_f( const idCmdArgs &args ) { + int e, i; + idLight *light; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idDict dict; + idStr mapName; + const char *name(NULL); + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() > 1 ) { + mapName = args.Argv( 1 ); + mapName = "maps/" + mapName; + } + else { + mapName = mapFile->GetName(); + } + + for( e = 0; e < MAX_GENTITIES; e++ ) { + light = static_cast(gameLocal.entities[ e ]); + + if ( !light || !light->IsType( idLight::Type ) ) { + continue; + } + + dict.Clear(); + light->SaveState( &dict ); + + // find map file entity + mapEnt = mapFile->FindEntity( light->name ); + // create new map file entity if there isn't one for this light + if ( !mapEnt ) { + mapEnt = new idMapEntity(); + mapFile->AddEntity( mapEnt ); + for ( i = 0; i < 9999; i++ ) { + name = va( "%s_%d", light->GetEntityDefName(), i ); + if ( !mapFile->FindEntity( name ) ) + break; + } + light->name = name; + mapEnt->epairs.Set( "classname", light->GetEntityDefName() ); + mapEnt->epairs.Set( "name", light->name ); + } + // save the light state + mapEnt->epairs.Copy( dict ); + } + + // write out the map file + mapFile->Write( mapName, ".map" ); +} + + +/* +================== +Cmd_SaveParticles_f +================== +*/ +static void Cmd_SaveParticles_f( const idCmdArgs &args ) { + int e; + idEntity *ent; + idMapEntity *mapEnt; + idMapFile *mapFile = gameLocal.GetLevelMap(); + idDict dict; + idStr mapName, strModel; + + if ( !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() > 1 ) { + mapName = args.Argv( 1 ); + mapName = "maps/" + mapName; + } + else { + mapName = mapFile->GetName(); + } + + for( e = 0; e < MAX_GENTITIES; e++ ) { + + ent = static_cast ( gameLocal.entities[ e ] ); + + if ( !ent ) { + continue; + } + + strModel = ent->spawnArgs.GetString( "model" ); + if ( strModel.Length() && strModel.Find( ".prt") > 0 ) { + dict.Clear(); + dict.Set( "model", ent->spawnArgs.GetString( "model" ) ); + dict.SetVector( "origin", ent->GetPhysics()->GetOrigin() ); + + // find map file entity + mapEnt = mapFile->FindEntity( ent->name ); + // create new map file entity if there isn't one for this entity + if ( !mapEnt ) { + continue; + } + // save the particle state + mapEnt->epairs.Copy( dict ); + } + } + + // write out the map file + mapFile->Write( mapName, ".map" ); +} + + +/* +================== +Cmd_DisasmScript_f +================== +*/ +static void Cmd_DisasmScript_f( const idCmdArgs &args ) { + gameLocal.program.Disassemble(); +} + +/* +================== +Cmd_TestSave_f +================== +*/ +static void Cmd_TestSave_f( const idCmdArgs &args ) { + idFile *f; + + f = fileSystem->OpenFileWrite( "test.sav" ); + gameLocal.SaveGame( f ); + fileSystem->CloseFile( f ); +} + +/* +================== +Cmd_RecordViewNotes_f +================== +*/ +static void Cmd_RecordViewNotes_f( const idCmdArgs &args ) { + idPlayer *player; + idVec3 origin; + idMat3 axis; + + if ( args.Argc() <= 3 ) { + return; + } + + player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + + player->GetViewPos( origin, axis ); + + // Argv(1) = filename for map (viewnotes/mapname/person) + // Argv(2) = note number (person0001) + // Argv(3) = comments + + idStr str = args.Argv(1); + str.SetFileExtension( ".txt" ); + idFile *file = fileSystem->OpenFileAppend( str ); + if ( file ) { + file->WriteFloatString( "\"view\"\t( %s )\t( %s )\r\n", origin.ToString(), axis.ToString() ); + file->WriteFloatString( "\"comments\"\t\"%s: %s\"\r\n\r\n", args.Argv(2), args.Argv(3) ); + fileSystem->CloseFile( file ); + } + + idStr viewComments = args.Argv(1); + viewComments.StripLeading("viewnotes/"); + viewComments += " -- Loc: "; + viewComments += origin.ToString(); + viewComments += "\n"; + viewComments += args.Argv(3); + player->hud->SetStateString( "viewcomments", viewComments ); + player->hud->HandleNamedEvent( "showViewComments" ); +} + +/* +================== +Cmd_CloseViewNotes_f +================== +*/ +static void Cmd_CloseViewNotes_f( const idCmdArgs &args ) { + idPlayer *player = gameLocal.GetLocalPlayer(); + + if ( !player ) { + return; + } + + player->hud->SetStateString( "viewcomments", "" ); + player->hud->HandleNamedEvent( "hideViewComments" ); +} + +/* +================== +Cmd_ShowViewNotes_f +================== +*/ +static void Cmd_ShowViewNotes_f( const idCmdArgs &args ) { + static idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS ); + idToken token; + idPlayer *player; + idVec3 origin; + idMat3 axis; + + player = gameLocal.GetLocalPlayer(); + + if ( !player ) { + return; + } + + if ( !parser.IsLoaded() ) { + idStr str = "viewnotes/"; + str += gameLocal.GetMapName(); + str.StripFileExtension(); + str += "/"; + if ( args.Argc() > 1 ) { + str += args.Argv( 1 ); + } else { + str += "comments"; + } + str.SetFileExtension( ".txt" ); + if ( !parser.LoadFile( str ) ) { + gameLocal.Printf( "No view notes for %s\n", gameLocal.GetMapName() ); + return; + } + } + + if ( parser.ExpectTokenString( "view" ) && parser.Parse1DMatrix( 3, origin.ToFloatPtr() ) && + parser.Parse1DMatrix( 9, axis.ToFloatPtr() ) && parser.ExpectTokenString( "comments" ) && parser.ReadToken( &token ) ) { + player->hud->SetStateString( "viewcomments", token ); + player->hud->HandleNamedEvent( "showViewComments" ); + player->Teleport( origin, axis.ToAngles(), NULL ); + } else { + parser.FreeSource(); + player->hud->HandleNamedEvent( "hideViewComments" ); + return; + } +} + +/* +================= +FindEntityGUIs + +helper function for Cmd_NextGUI_f. Checks the passed entity to determine if it +has any valid gui surfaces. +================= +*/ +bool FindEntityGUIs( idEntity *ent, const modelSurface_t ** surfaces, int maxSurfs, int &guiSurfaces ) { + renderEntity_t *renderEnt; + idRenderModel *renderModel; + const modelSurface_t *surf; + const idMaterial *shader; + int i; + + assert( surfaces != NULL ); + assert( ent != NULL ); + + memset( surfaces, 0x00, sizeof( modelSurface_t *) * maxSurfs ); + guiSurfaces = 0; + + renderEnt = ent->GetRenderEntity(); + renderModel = renderEnt->hModel; + if ( renderModel == NULL ) { + return false; + } + + for( i = 0; i < renderModel->NumSurfaces(); i++ ) { + surf = renderModel->Surface( i ); + if ( surf == NULL ) { + continue; + } + shader = surf->shader; + if ( shader == NULL ) { + continue; + } + if ( shader->GetEntityGui() > 0 ) { + surfaces[ guiSurfaces++ ] = surf; + } + } + + return ( guiSurfaces != 0 ); +} + +/* +================= +Cmd_NextGUI_f +================= +*/ +void Cmd_NextGUI_f( const idCmdArgs &args ) { + idVec3 origin; + idAngles angles; + idPlayer *player; + idEntity *ent; + int guiSurfaces; + bool newEnt; + renderEntity_t *renderEnt; + int surfIndex; + srfTriangles_t *geom; + idMat4 modelMatrix; + idVec3 normal; + idVec3 center; + const modelSurface_t *surfaces[ MAX_RENDERENTITY_GUI ]; + + player = gameLocal.GetLocalPlayer(); + if ( !player || !gameLocal.CheatsOk() ) { + return; + } + + if ( args.Argc() != 1 ) { + gameLocal.Printf( "usage: nextgui\n" ); + return; + } + + // start at the last entity + ent = gameLocal.lastGUIEnt.GetEntity(); + + // see if we have any gui surfaces left to go to on the current entity. + guiSurfaces = 0; + newEnt = false; + if ( ent == NULL ) { + newEnt = true; + } else if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == true ) { + if ( gameLocal.lastGUI >= guiSurfaces ) { + newEnt = true; + } + } else { + // no actual gui surfaces on this ent, so skip it + newEnt = true; + } + + if ( newEnt == true ) { + // go ahead and skip to the next entity with a gui... + if ( ent == NULL ) { + ent = gameLocal.spawnedEntities.Next(); + } else { + ent = ent->spawnNode.Next(); + } + + for ( ; ent != NULL; ent = ent->spawnNode.Next() ) { + if ( ent->spawnArgs.GetString( "gui", NULL ) != NULL ) { + break; + } + + if ( ent->spawnArgs.GetString( "gui2", NULL ) != NULL ) { + break; + } + + if ( ent->spawnArgs.GetString( "gui3", NULL ) != NULL ) { + break; + } + + // try the next entity + gameLocal.lastGUIEnt = ent; + } + + gameLocal.lastGUIEnt = ent; + gameLocal.lastGUI = 0; + + if ( !ent ) { + gameLocal.Printf( "No more gui entities. Starting over...\n" ); + return; + } + } + + if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == false ) { + gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces.\n", ent->name.c_str() ); + } + + if ( guiSurfaces == 0 ) { + gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces!\n", ent->name.c_str() ); + return; + } + + gameLocal.Printf( "Teleporting to gui entity \"%s\", gui #%d.\n" , ent->name.c_str (), gameLocal.lastGUI ); + + renderEnt = ent->GetRenderEntity(); + surfIndex = gameLocal.lastGUI++; + geom = surfaces[ surfIndex ]->geometry; + if ( geom == NULL ) { + gameLocal.Printf( "Entity \"%s\" has gui surface %d without geometry!\n", ent->name.c_str(), surfIndex ); + return; + } + + assert( geom->facePlanes != NULL ); + + modelMatrix = idMat4( renderEnt->axis, renderEnt->origin ); + normal = geom->facePlanes[ 0 ].Normal() * renderEnt->axis; + center = geom->bounds.GetCenter() * modelMatrix; + + origin = center + (normal * 32.0f); + origin.z -= player->EyeHeight(); + normal *= -1.0f; + angles = normal.ToAngles (); + + // make sure the player is in noclip + player->noclip = true; + player->Teleport( origin, angles, NULL ); +} + +static void ArgCompletion_DefFile( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "def/", true, ".def", NULL ); +} + +/* +=============== +Cmd_TestId_f +outputs a string from the string table for the specified id +=============== +*/ +void Cmd_TestId_f( const idCmdArgs &args ) { + idStr id; + int i; + if ( args.Argc() == 1 ) { + common->Printf( "usage: testid \n" ); + return; + } + + for ( i = 1; i < args.Argc(); i++ ) { + id += args.Argv( i ); + } + if ( idStr::Cmpn( id, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) { + id = STRTABLE_ID + id; + } + gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( id ), "", "", "" ); +} + +void Cmd_SetClipMask(const idCmdArgs& args) +{ + if (args.Argc() != 3) + { + common->Printf( "usage: setClipMask \n" ); + return; + } + + idStr targetEntity = args.Argv(1); + int clipMask = atoi(args.Argv(2)); + + idEntity* ent = gameLocal.FindEntity(targetEntity.c_str()); + + if (ent != NULL && ent->GetPhysics() != NULL) + { + ent->GetPhysics()->SetClipMask(clipMask); + common->Printf("Clipmask of entity %s set to %d\n", ent->name.c_str(), clipMask); + } +} + +void Cmd_SetClipContents(const idCmdArgs& args) +{ + if (args.Argc() != 3) + { + common->Printf( "usage: setClipContents \n" ); + return; + } + + idStr targetEntity = args.Argv(1); + int contents = atoi(args.Argv(2)); + + idEntity* ent = gameLocal.FindEntity(targetEntity.c_str()); + + if (ent != NULL && ent->GetPhysics() != NULL) + { + ent->GetPhysics()->SetContents(contents); + common->Printf("Contents of entity %s set to %d\n", ent->name.c_str(), contents); + } +} + +void Cmd_ShowWalkPath_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + common->Printf( "usage: aas_showWalkPath \n" ); + return; + } + + idPlayer* player = gameLocal.GetLocalPlayer(); + if ( !player ) { + return; + } + + idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); + if (aas != NULL) + { + aas->ShowWalkPath(player->GetPhysics()->GetOrigin(), atoi(args.Argv(1)), aas->AreaCenter(atoi(args.Argv(1)))); + } +} + +void Cmd_ShowReachabilities_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + common->Printf( "usage: aas_showReachabilities \n" ); + return; + } + + idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); + if (aas != NULL) + { + idReachability* reach = aas->GetAreaFirstReachability(atoi(args.Argv(1))); + + while (reach != NULL) + { + aas->DrawReachability(reach); + reach = reach->next; + } + } +} + +void Cmd_ShowAASStats_f(const idCmdArgs& args) +{ + for (int i = 0; i < gameLocal.NumAAS(); i++) + { + idAAS* aas = dynamic_cast(gameLocal.GetAAS(i)); + if (aas != NULL) + { + aas->Stats(); + } + } +} + +void Cmd_ShowEASRoute_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + common->Printf( "usage: eas_showRoute \n" ); + return; + } + + idPlayer* player = gameLocal.GetLocalPlayer(); + if (player == NULL) + { + common->Printf( "no player found\n" ); + return; + } + + idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); + if (aas != NULL) + { + int areaNum = atoi(args.Argv(1)); + + aas->DrawEASRoute(player->GetPhysics()->GetOrigin(), areaNum); + } +} + +void Cmd_StartConversation_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + gameLocal.Printf("Usage: tdm_start_conversation . Use tdm_list_conversations to get a list of names.\n" ); + return; + } + + if (gameLocal.GameState() != GAMESTATE_ACTIVE) + { + gameLocal.Printf("No map running\n"); + return; + } + + int idx = gameLocal.m_ConversationSystem->GetConversationIndex(args.Argv(1)); + if (idx != -1) + { + gameLocal.m_ConversationSystem->StartConversation(idx); + } + else + { + gameLocal.Printf("No conversation with name: %s\n", args.Argv(1)); + } +} + +void Cmd_ListConversations_f(const idCmdArgs& args) +{ + if (gameLocal.GameState() != GAMESTATE_ACTIVE) + { + gameLocal.Printf("No map running\n"); + return; + } + + for (int i = 0; i < gameLocal.m_ConversationSystem->GetNumConversations(); i++) + { + ai::ConversationPtr conversation = gameLocal.m_ConversationSystem->GetConversation(i); + + if (conversation == NULL) continue; + + gameLocal.Printf("%d: %s (%d commands)\n", i, conversation->GetName().c_str(), conversation->GetNumCommands()); + } +} + +void Cmd_ShowLoot_f(const idCmdArgs& args) +{ + if (gameLocal.GameState() != GAMESTATE_ACTIVE) + { + gameLocal.Printf("No map running\n"); + return; + } + + int items = 0; + int gold = 0; + int jewels = 0; + int goods = 0; + + for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) + { + if (ent == NULL) continue; + + int value = ent->spawnArgs.GetInt("inv_loot_value", "-1"); + + if (value <= 0) continue; // no loot item + + items++; + + LootType lootType = CInventoryItem::GetLootTypeFromSpawnargs(ent->spawnArgs); + + idVec4 colour(colorWhite); + + switch(lootType) + { + case LOOT_GOLD: + gold += value; + colour = idVec4(0.97f, 0.93f, 0.58f, 1); + break; + + case LOOT_GOODS: + goods += value; + colour = idVec4(0.3f, 0.91f, 0.3f, 1); + break; + + case LOOT_JEWELS: + jewels += value; + colour = idVec4(0.96f, 0.2f, 0.2f, 1); + break; + + default: break; + } + + gameRenderWorld->DebugBox(colour, idBox(ent->GetPhysics()->GetAbsBounds()), 5000); + } + + gameLocal.Printf("Highlighing loot items for 5 seconds...\n"); + gameLocal.Printf("Loot items remaining: %d\n", items); + gameLocal.Printf("Gold: %d, Jewels: %d, Goods: %d\n", gold, jewels, goods); +} + +void Cmd_ActivateLog_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + gameLocal.Printf("Usage: tdm_activatelogclass . Use the TAB to get auto-complete logclasses.\n" ); + return; + } + + LC_LogClass logclassIndex = CGlobal::GetLogClassForString(args.Argv(1)); + + if (logclassIndex != LC_COUNT) + { + // Log class found + g_Global.m_ClassArray[logclassIndex] = true; + + // activate all types too + g_Global.m_LogArray[LT_WARNING] = true; + g_Global.m_LogArray[LT_ERROR] = true; + g_Global.m_LogArray[LT_INFO] = true; + g_Global.m_LogArray[LT_DEBUG] = true; + + gameLocal.Printf("Logclass %d activated.", static_cast(logclassIndex)); + } +} + +void Cmd_DeactivateLog_f(const idCmdArgs& args) +{ + if (args.Argc() != 2) + { + gameLocal.Printf("Usage: tdm_deactivatelogclass . Use the TAB to get auto-complete logclasses.\n" ); + return; + } + + LC_LogClass logclassIndex = CGlobal::GetLogClassForString(args.Argv(1)); + + if (logclassIndex != LC_COUNT) + { + // Log class found + g_Global.m_ClassArray[logclassIndex] = false; + + // activate all types too + g_Global.m_LogArray[LT_WARNING] = true; + g_Global.m_LogArray[LT_ERROR] = true; + g_Global.m_LogArray[LT_INFO] = true; + g_Global.m_LogArray[LT_DEBUG] = true; + + gameLocal.Printf("Logclass %d deactivated.", static_cast(logclassIndex)); + } +} + +//------------------------------------------------------------- +// Do not account for centerScale or Scroll for now. +typedef struct _ImageInfo{ + idStr m_strImageName; + idStr m_strUVScale; + + _ImageInfo() : + m_strImageName(), + m_strUVScale("1, 1") + { + } +}ImageInfo_s; + +enum eVertexBlendType { + eVertexBlendType_None, + eVertexBlendType_VertexColored, + eVertexBlendType_InvVertexColored +}; +//------------------------------------------------------------------ +typedef std::multimap< eVertexBlendType, ImageInfo_s > ImageInfoMap; +//------------------------------------------------------------------ + +//------------------------------------------------------------- +// GetValidStageTextureName +// +// Description: Obtains a valid texture name with trailing white spaces and curly brackets (if found any) removed. +// A check for valid number of opening and closing brackets performed. +//------------------------------------------------------------- +bool GetValidStageExpression( idLexer &a_lexSource, idStr & a_strStageTextureName ) +{ + int iOffset, nBrackets; + a_strStageTextureName.Empty(); + + std::vector< idStr > arrStrInvalidTokens; + + arrStrInvalidTokens.push_back( "bumpmap" ); + arrStrInvalidTokens.push_back( "diffusemap" ); + arrStrInvalidTokens.push_back( "specularmap" ); + arrStrInvalidTokens.push_back( "map" ); + +// gameLocal.Printf("Entering loop. \n" ); + + idToken tknParsedLine; + int i=0; + for( nBrackets = 0 ; !a_lexSource.EndOfFile() ; ) + { + while(a_lexSource.ReadToken( &tknParsedLine )) + { + if ( tknParsedLine.linesCrossed ) { +// gameLocal.Printf("End of the line reached. \n" ); + break; + } + if ( a_strStageTextureName.Length() ) { + a_strStageTextureName += " "; + } + bool bIsValidToken = true; + for( std::vector::iterator iter = arrStrInvalidTokens.begin() ; arrStrInvalidTokens.end() != iter; iter ++ ) + { + if( 0 != tknParsedLine.Icmp( *iter ) ) + continue; + + bIsValidToken = false; +// gameLocal.Printf("Invalid token found. \n" ); + break; + } + if( bIsValidToken ) + { + a_strStageTextureName += tknParsedLine; +// gameLocal.Printf("constructing \"%s\" with a valid token. \n", a_strStageTextureName.c_str() ); + } + else + { +// gameLocal.Printf("%s is an invalid token. \n", tknParsedLine.c_str() ); + break; + } + } + + a_strStageTextureName.Strip('\n'); + a_strStageTextureName.Strip('\t'); + a_strStageTextureName.Strip('\r'); + a_strStageTextureName.Strip(' '); + + // Make sure that we have equal number of opening bracket and closing brackets. + for(iOffset = 0, nBrackets = 0; 0 <= (iOffset = a_strStageTextureName.Find( '(', iOffset )); nBrackets ++, iOffset ++ ); + for(iOffset = 0; 0 <= (iOffset = a_strStageTextureName.Find( ')', iOffset )); nBrackets --, iOffset ++ ); + + if ( 0 == nBrackets ) + { + // We have gone one token ahead than needed in the lexer so offset it back again. +// gameLocal.Printf("Unreading token %s. \n", tknParsedLine.c_str() ); + a_lexSource.UnreadToken( &tknParsedLine ); + + a_strStageTextureName.Strip('}'); + a_strStageTextureName.Strip('{'); + if( a_strStageTextureName.Length() <= 0 ) + return false; + + gameLocal.Printf(" Found valid expression: %s \n ", a_strStageTextureName.c_str() ); + return true; + } + + // Append the first token of the newly read line. + a_strStageTextureName += tknParsedLine; + } + + return false; +} + +//------------------------------------------------------------- +// GetMaterialStageInfo +// +// Description: For a given material stage (any one of "diffusemap", "bumpmap" & specular map ) finds out number of +// textures (pathnames) being used along with their UV scales. +//------------------------------------------------------------- +void GetMaterialStageInfo ( const char* a_strMatStageName, idLexer &a_lexSource, ImageInfoMap & a_arrMatStageInfo ) +{ + a_lexSource.Reset(); +// gameLocal.Printf( "Looking for valid %s stage information (w/o blend). \n", a_strMatStageName ); + while ( 1 == a_lexSource.SkipUntilString( a_strMatStageName ) ) + { + ImageInfo_s currentImageInfo ; + + if( true == GetValidStageExpression( a_lexSource, currentImageInfo.m_strImageName ) ) + { +// gameLocal.Printf( "Found valid %s stage information (w/o blend). \n", a_strMatStageName ); + a_arrMatStageInfo.insert( ImageInfoMap::value_type( eVertexBlendType_None, currentImageInfo ) ); + } + } +// if( a_arrMatStageInfo.size() == 0 ) +// gameLocal.Printf( "Could not find valid %s stage information w/o blend. \n", a_strMatStageName); + + a_lexSource.Reset(); + +// gameLocal.Printf( "Looking for %s stage information with blend. \n", a_strMatStageName ); + while ( 1 == a_lexSource.SkipUntilString( "blend" ) ) + { + idToken tknMatStage; + if( 1 == a_lexSource.ReadToken( &tknMatStage ) && 0 == tknMatStage.Icmp(a_strMatStageName) ) + { + idToken tknMap; + if( 0 != a_lexSource.ReadToken( &tknMap ) && 0 == tknMap.Icmp("map") ) + { + ImageInfo_s currentImageInfo; + eVertexBlendType vertBlendType = eVertexBlendType_None; + + if( true == GetValidStageExpression( a_lexSource, currentImageInfo.m_strImageName ) ) + { + bool bIsScaleFound = false; + while( "}" != tknMatStage ) + { + if( !a_lexSource.ReadToken( &tknMatStage ) ) + { + gameLocal.Warning( "Unexpected end of material when trying to obtain scale. \n"); + break; + } + // Not using expectTokenString anymore since "Map" is treated as different token than "map". + // So doing a manual non-case sensitive checks instead. + if( !bIsScaleFound && 0 == tknMatStage.Icmp("scale") ) + { + idStr strScale; + if( true == GetValidStageExpression( a_lexSource, strScale ) ) + currentImageInfo.m_strUVScale = strScale; + + gameLocal.Printf(" Scale: %s \n ", strScale.c_str() ); + bIsScaleFound = true; + } + + if( eVertexBlendType_None == vertBlendType ) + { + if( 0 == tknMatStage.Icmp("vertexColor") ) + { + gameLocal.Printf(" The stage is vertex-colored \n " ); + vertBlendType = eVertexBlendType_VertexColored; + } + else if( 0 == tknMatStage.Icmp("inverseVertexColor") ) + { + gameLocal.Printf(" The stage is inverse vertex-colored \n " ); + vertBlendType = eVertexBlendType_InvVertexColored; + } + } + else if( bIsScaleFound ) + break; + + } + a_arrMatStageInfo.insert( ImageInfoMap::value_type( vertBlendType, currentImageInfo ) ); + + } + } + } + + } +} + + +//------------------------------------------------------------- +// FindBlockContainingWords +// +// Description: Inside a specified material shader block, finds the character offsets for start & end of the block +// that contains the words (specified by vector of strings) in their exact order. +// Return value: True if the block is found. +//------------------------------------------------------------- + +bool FindBlockContainingWords( const char *a_text, std::vector& a_arrSearchWords, unsigned int & a_uiStartOffset, unsigned int & a_uiEndOffset, + const char a_cBlockStart = '{', const char a_cBlockEnd = '}' ) +{ + int uiSearchIndex; + unsigned int uiSearchOffset = 0; + unsigned int iTextLength = idStr::Length(a_text); + bool bAreAllWordsFound = false; + + for(std::vector::iterator iter = a_arrSearchWords.begin(); ; ) + { + + uiSearchIndex = idStr::FindText( a_text, (*iter).c_str(), false, uiSearchOffset ); + // gameLocal.Printf( " Searched %s from offset %d and found index %d \n", (*iter).c_str(),uiSearchOffset, uiSearchIndex ); + + if( uiSearchIndex < 0 ) + { + // gameLocal.Warning( " Could not find search word %s\n", (*iter).c_str() ); + return false; + } + + bAreAllWordsFound = true; + + // Make sure that, this is not the first word we have found. + if( a_arrSearchWords.begin() != iter ) + { + if( uiSearchIndex != uiSearchOffset ) + { + // gameLocal.Warning( " Could not find search word %s in the expected order\n", (*iter).c_str() ); + + //Start the search from the first word again, since all of the search words are important. + bAreAllWordsFound = false; + iter = a_arrSearchWords.begin(); + continue; + } + } + + // Increment the iterator. + iter ++; + + if( a_arrSearchWords.end() == iter ) + break; + + //Read white spaces and adjust the search offset accordingly for the next search. + for( uiSearchOffset = uiSearchIndex + (*(iter-1)).Length(); uiSearchOffset < iTextLength; uiSearchOffset++ ) + { + if( ' ' == a_text[ uiSearchOffset ] || '\t' == a_text[ uiSearchOffset ] || '\r' == a_text[ uiSearchOffset ] ) + continue; + + break; + } + } + + if( bAreAllWordsFound ) + { + // gameLocal.Printf( " Total %d word(s) found \n", a_arrSearchWords.size() ); + + if( a_arrSearchWords.size() == 1 ) + { + uiSearchOffset = uiSearchIndex; + } + + // Start tracking offsets to the opening and closing of the block from the last search-Index. + bool bIsStartOffsetFound = false; + bool bIsEndOffsetFound = false; + for( a_uiStartOffset = a_uiEndOffset = uiSearchOffset ; a_uiStartOffset > 0 && a_uiEndOffset < iTextLength ; ) + { + if( a_cBlockStart == a_text[ a_uiStartOffset ] ) + bIsStartOffsetFound = true; + else + a_uiStartOffset --; + + if( a_cBlockEnd == a_text[ a_uiEndOffset ] ) + bIsEndOffsetFound = true; + else + a_uiEndOffset ++; + + if( bIsStartOffsetFound && bIsEndOffsetFound ) + { + // Adjust end offset by one extra character to make sure that we account the closing block. + a_uiEndOffset ++; + // idStr myBlock( a_text, a_uiStartOffset, a_uiEndOffset ); + // gameLocal.Printf( "Found block from %d to %d, search offset is %d\n", a_uiStartOffset, a_uiEndOffset, uiSearchOffset ); + // gameLocal.Printf( "%s \n", myBlock.c_str() ); + return true; + } + } + // gameLocal.Warning( " Block start found:%d Block End Found:%d, Returning false.\n", (int)bIsStartOffsetFound, (int)bIsEndOffsetFound ); + } + + // if( !bAreAllWordsFound ) + // gameLocal.Warning( " Returning false since given words can't be found in the exact given order.\n" ); + return false; +} + +void CreateNewAmbientBlock( const ImageInfoMap& a_arrDiffusemapInfo, const ImageInfoMap& a_arrBumpmapInfo, const ImageInfoMap& a_arrSpecularmapInfo, std::vector& a_arrCharNewAmbientBlock ) +{ + static const char newAmbientBlock[] = { + "\n { \n" + " if (global5 == 1) \n" + " blend add \n" + " map %s \n" + " scale %s \n" + " red global2 \n" + " green global3 \n" + " blue global4 \n" + " } \n" + " { \n" + " if (global5 == 2) \n" + " blend add \n" + " program ambientEnvironment.vfp \n" + " vertexParm 0 %s, %s // UV Scales for Diffuse and Bump \n" + " vertexParm 1 %s, 1, 1 // (X,Y) UV Scale for specular \n" + " vertexParm 2 global2, global3, global4, 1 \n" + " \n" + " fragmentMap 0 cubeMap env/gen1 \n" + " fragmentMap 1 %s // Bump \n" + " fragmentMap 2 %s // Diffuse \n" + " fragmentMap 3 %s // Specular \n" + " }" + }; + + static const char newAmbientBlockVertColorBlended[] = { + "\n { \n" + " if (global5 == 1) \n" + " blend add \n" + " map %s \n" + " scale %s \n" + " red global2 \n" + " green global3 \n" + " blue global4 \n" + " vertexColor \n" + " } \n" + " { \n" + " if (global5 == 1) \n" + " blend add \n" + " map %s \n" + " scale %s \n" + " red global2 \n" + " green global3 \n" + " blue global4 \n" + " inverseVertexColor \n" + " } \n" + " { \n" + " if (global5 == 2) \n" + " blend add \n" + " program ambientEnvVertexBlend.vfp \n" + " vertexParm 0 %s, %s // UV Scales for Diffuse1 and Bump1 resp. \n" + " vertexParm 1 %s, %s // UV Scale for specular1 and Diffuse2 resp.\n" + " vertexParm 2 %s, %s // UV Scale for Bump2 and specular2 resp. \n" + " vertexParm 3 global2, global3, global4, 1 \n" + " //----------- VertexColored ------------------- \n" + " fragmentMap 0 cubeMap env/gen1 \n" + " fragmentMap 1 %s // Bump1 \n" + " fragmentMap 2 %s // Diffuse1 \n" + " fragmentMap 3 %s // Specular1 \n" + " //----------- InverseVertexColored ------------ \n" + " fragmentMap 4 %s // Bump2 \n" + " fragmentMap 5 %s // Diffuse2 \n" + " fragmentMap 6 %s // Specular2 \n" + " }" + }; + + + + ImageInfoMap::const_iterator itrDiffusemapInfoVertexColored = a_arrDiffusemapInfo.find( eVertexBlendType_VertexColored ); + ImageInfoMap::const_iterator itrBumpmapInfoVertexColored = a_arrBumpmapInfo.find( eVertexBlendType_VertexColored ); + ImageInfoMap::const_iterator itrSpecularmapInfoVertexColored = a_arrSpecularmapInfo.find( eVertexBlendType_VertexColored ); + + ImageInfoMap::const_iterator itrDiffusemapInfoInvVertexColored = a_arrDiffusemapInfo.find( eVertexBlendType_InvVertexColored ); + ImageInfoMap::const_iterator itrBumpmapInfoInvVertexColored = a_arrBumpmapInfo.find( eVertexBlendType_InvVertexColored ); + ImageInfoMap::const_iterator itrSpecularmapInfoInvVertexColored = a_arrSpecularmapInfo.find( eVertexBlendType_InvVertexColored ); + + bool bIsVertexColorBlended = ( ( a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored || a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored || + a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ) && + (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored || a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored || + a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ) ); + + ImageInfoMap::const_iterator itrDiffusemapInfo = a_arrDiffusemapInfo.find( eVertexBlendType_None ); + ImageInfoMap::const_iterator itrBumpmapInfo = a_arrBumpmapInfo.find( eVertexBlendType_None ); + ImageInfoMap::const_iterator itrSpecularmapInfo = a_arrSpecularmapInfo.find( eVertexBlendType_None ); + + + if ( bIsVertexColorBlended ) + { + gameLocal.Printf("This material is vertex-color blended. \n"); + + // Find out normal maps for vertex blending. + + // Handle cases where vertexColor is not used for bumpmaps + if ( a_arrBumpmapInfo.end() == itrBumpmapInfoVertexColored ) + itrBumpmapInfoVertexColored = itrBumpmapInfo; + + if ( a_arrBumpmapInfo.end() == itrBumpmapInfoInvVertexColored ) + { + ImageInfoMap::const_iterator itrBumpmapInfo2 = itrBumpmapInfo; + if( a_arrBumpmapInfo.end() != itrBumpmapInfo2 ) + { + // Try and see if there's a second bumpmap with no vertex-color blend. + ++itrBumpmapInfo2; + itrBumpmapInfoInvVertexColored = a_arrBumpmapInfo.end() != itrBumpmapInfo2 ? ( eVertexBlendType_None == (*itrBumpmapInfo2).first ? itrBumpmapInfo2 : itrBumpmapInfo ) : itrBumpmapInfo; + } + } + unsigned int uiBlockSize = idStr::Length( newAmbientBlockVertColorBlended ) + 1 + + //------------------ For vertexColor ---------------- + (a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + + (a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + + ( a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_flat") ) + + ( a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + + //------------------ For inverseVertexColor --------- + (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + + (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + + ( a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_flat") ) + + ( a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ); + + + a_arrCharNewAmbientBlock.resize( uiBlockSize, 0 ); + + idStr::snPrintf( &a_arrCharNewAmbientBlock[0], uiBlockSize, newAmbientBlockVertColorBlended, + //------------------ For vertexColor ---------------- + a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.c_str() : "_black", + a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", + //------------------ For inverseVertexColor --------- + a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.c_str() : "_black", + a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", + //--------------------------------------------------- + + //------------------ For vertexColor ---------------- + a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", + a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", + a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", + //------------------ For inverseVertexColor --------- + a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", + a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", + a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", + //--------------------------------------------------- + + //------------------ For vertexColor ---------------- + a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strImageName.c_str() : "_flat", + a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.c_str() : "_black", + a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strImageName.c_str() : "_black", + //------------------ For inverseVertexColor --------- + a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strImageName.c_str() : "_flat", + a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.c_str() : "_black", + a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strImageName.c_str() : "_black" + //--------------------------------------------------- + ); + } + else + { + gameLocal.Printf("This material is vertex-color blended. \n"); + unsigned int uiBlockSize = idStr::Length( newAmbientBlock ) + 1 + + (a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + + (a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + + ( a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strImageName.Length() : idStr::Length("_flat") ) + + ( a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strImageName.Length() : idStr::Length("_black") ) + + (a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ); + + a_arrCharNewAmbientBlock.resize( uiBlockSize, 0 ); + + idStr::snPrintf( &a_arrCharNewAmbientBlock[0], uiBlockSize, newAmbientBlock, + a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.c_str() : "_black", + a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.c_str() : "1, 1", + a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.c_str() : "1, 1", + a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strUVScale.c_str() : "1, 1", + a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strUVScale.c_str() : "1, 1", + a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strImageName.c_str() : "_flat", + a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.c_str() : "_black", + a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strImageName.c_str() : "_black" + ); + } + +} + +void Cmd_BatchConvertMaterials_f( const idCmdArgs& args ) +{ + + if( args.Argc() < 3 ) + { + gameLocal.Printf( "Usage: tdm_batchConvertMaterials [forceUpdateAll] \n" ); + return; + } + + bool bForceUpdateAllMaterials = false; + if( args.Argc() > 3 ) + { + bForceUpdateAllMaterials = (0 == idStr::Icmp( args.Argv(3), "forceupdateall" )); + } + + const unsigned int uiStartIndex = atoi(args.Argv(1)); + const unsigned int uiMaterialsToProcess = atoi(args.Argv(2)); + + const unsigned long uiTotalMats = declManager->GetNumDecls( DECL_MATERIAL ); + + gameLocal.Printf("Parsing %d materials, this may take few minutes...\n", uiTotalMats ); + + unsigned long ulMaterialsProcessed = 0; + unsigned long i = uiStartIndex > (uiTotalMats - 1) ? uiTotalMats : uiStartIndex; + const unsigned uiMaxMaterialsToProcess = i + uiMaterialsToProcess; + for ( ; i < uiTotalMats && i < uiMaxMaterialsToProcess; i++ ) + { + + idMaterial *mat = const_cast(declManager->MaterialByIndex( i )); + + // for testing + //idMaterial *mat = const_cast(declManager->FindMaterial( "textures/base_wall/xiantex3_dark_burn" )); + + if( NULL == mat ) + continue; + + gameLocal.Printf("Material %s loaded. \n", mat->GetName() ); + + std::vector< char > charBuffer; + + ImageInfoMap arrDiffusemapInfo; + ImageInfoMap arrBumpMapInfo; + ImageInfoMap arrSpecularmapInfo; + + charBuffer.resize( mat->GetTextLength() + 1, 0 ); + mat->GetText( &charBuffer[0] ); + + idLexer lexSource( &charBuffer[0], charBuffer.size(), mat->GetName(), LEXFL_NOFATALERRORS | LEXFL_ALLOWPATHNAMES ); + + gameLocal.Printf("Finding out shader stages... \n" ); + + bool bAreBumpmapsExtracted =false; + bool bAreDiffusemapsExtracted =false; + bool bAreSpecularmapsExtracted =false; + for ( int j=0; j < mat->GetNumStages(); j++ ) + { + const shaderStage_t *pShaderStage = mat->GetStage(j); + + if( NULL == pShaderStage ) + { +// mat->Invalidate(); +// mat->FreeData(); + continue; + } + + //GetMaterialStageInfo extracts all the stages in material of given type so don't loop again for multiple similar stages. + if ( bAreBumpmapsExtracted && bAreDiffusemapsExtracted && bAreSpecularmapsExtracted ) + break; + + + switch( pShaderStage->lighting ) + { + case SL_BUMP: + if( bAreBumpmapsExtracted ) + continue; + + gameLocal.Printf("Bumpmap stage found, extracting bumpmap information... \n" ); + GetMaterialStageInfo( "bumpmap", lexSource, arrBumpMapInfo ); + bAreBumpmapsExtracted = true; + break; + case SL_DIFFUSE: + if( bAreDiffusemapsExtracted ) + continue; + + gameLocal.Printf("Diffusemap stage found, extracting diffusemap information... \n" ); + GetMaterialStageInfo( "diffusemap", lexSource, arrDiffusemapInfo ); + bAreDiffusemapsExtracted = true; + break; + case SL_SPECULAR: + if( bAreSpecularmapsExtracted ) + continue; + + gameLocal.Printf("Specularmap stage found, extracting specularmap information... \n" ); + GetMaterialStageInfo( "specularmap", lexSource, arrSpecularmapInfo ); + bAreSpecularmapsExtracted = true; + break; + default: + continue; + } + } + gameLocal.Printf("Done. \n" ); +// break; // remove me!!! + + if( arrBumpMapInfo.size() == 0 && arrDiffusemapInfo.size() == 0 && arrSpecularmapInfo.size() == 0 ) + { +// mat->Invalidate(); +// mat->FreeData(); + continue; + } + unsigned int uiBlockStartOffset, uiBlockEndOffset; + std::vector< idStr >arrSearchWords; + bool bIsAmbientBlockFound = false; + + // Note that, the spaces in the string:"if (global5 == 1)" and an externally modified material may not match. + // So avoid changing new ambient lighting blocks by hand, at least "if (global5 == 1)" part. + arrSearchWords.clear(); + arrSearchWords.push_back("if (global5 == 1)"); + bIsAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); + + gameLocal.Printf( "ForceUpdate is: %s\n", bForceUpdateAllMaterials? "true": "false" ); + if( bIsAmbientBlockFound ) + { + gameLocal.Printf( "Found new ambient block\n" ); + + gameLocal.Printf( "Removing new ambient block\n" ); + charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); + + // Try the search again with global5 == 1 in case the material is vertex color blended. + bool bIsSecondAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); + + if( bIsSecondAmbientBlockFound ) + charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); + + arrSearchWords.clear(); + arrSearchWords.push_back("if (global5 == 2)"); + bIsAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); + if( bIsAmbientBlockFound ) + charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); + } + + //Some materials may have old ambient block along with the new one. So remove it if found. + { + bool bIsOldAmbientBlockFound; + arrSearchWords.clear(); + arrSearchWords.push_back("red"); + arrSearchWords.push_back("global2"); + bIsOldAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); + if( bIsOldAmbientBlockFound ) + { + gameLocal.Printf( "Found old ambient block\n" ); + gameLocal.Printf( "Removing old ambient block\n" ); + charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); + bIsAmbientBlockFound = true; + } + + // Try the search again, in case the material is vertex color blended and there is second inverse-vertex-colored ambient block. + bIsOldAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); + + if( bIsOldAmbientBlockFound ) + charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); + + // If we couldn't find old ambient block and we have new ambient block in place, + // then we can safely skip this material. + else if( !bForceUpdateAllMaterials && bIsAmbientBlockFound ) + continue; + } + + + unsigned int uiOffset = 0; + + if( bIsAmbientBlockFound ) + { + //Remove the old comment. + unsigned int uiCommentStart, uiCommentEnd; + arrSearchWords.clear(); + + arrSearchWords.push_back("TDM"); + arrSearchWords.push_back("Ambient"); + arrSearchWords.push_back("Method"); + arrSearchWords.push_back("Related"); + if ( FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiCommentStart, uiCommentEnd, '\n', '\n' ) ) + { + charBuffer.erase( charBuffer.begin() + uiCommentStart, charBuffer.begin() + uiCommentEnd ); + gameLocal.Printf( " Ambient method related comment found and removed. \n" ); + } + } + //------------------------------------ + int i; + unsigned int uiEndoftheBlock = 0; + for( i= charBuffer.size() - 1; i > 0; i-- ) + { + if( '}' == charBuffer[i] ) + { + uiEndoftheBlock = i--; + // Find additional white spaces and new line characters before end of the block. + while( '\n' == charBuffer[i] || ' ' == charBuffer[i] || '\t' == charBuffer[i] || '\r' == charBuffer[i] ) + { + if(0 >= i) + break; + + i--; + } + // Remove white spaces and new line characters that are found before end of the block. + if( unsigned(i + 1) <= uiEndoftheBlock - 1 ) + { + charBuffer.erase( charBuffer.begin() + i + 1 , charBuffer.begin() + uiEndoftheBlock - 1 ); + gameLocal.Printf( "%d trailing white spaces found at end of the block and are removed. %d, %d, %c \n", uiEndoftheBlock - i - 1, uiEndoftheBlock, i + 1, charBuffer[i+2] ); + // Update end of the block's position. + uiEndoftheBlock = i + 2; + } + else + { + gameLocal.Printf( "No trailing white spaces found at end of the block. %c\n", charBuffer[i] ); + } + break; + } + } + + idStr strMatTextWithNewBlock( &charBuffer[0] ); + + if( i > 1 ) + { + strMatTextWithNewBlock.Insert( "\n\n // TDM Ambient Method Related ", uiEndoftheBlock - 1 ); + uiOffset = uiEndoftheBlock - 1 + idStr::Length( "\n\n // TDM Ambient Method Related " ); + //strMatTextWithNewBlock.Insert( '\n', uiOffset ); + } + else + { + gameLocal.Warning( "Could not determine end of the material block. Skipping this material.\n" ); + // mat->Invalidate(); + // mat->FreeData(); + continue; + } + + + gameLocal.Printf( "Processing Material %s \n", mat->GetName() ); + + std::vector arrCharNewAmbientBlock; + + CreateNewAmbientBlock( arrDiffusemapInfo, arrBumpMapInfo, arrSpecularmapInfo, arrCharNewAmbientBlock ); + + strMatTextWithNewBlock.Insert( &arrCharNewAmbientBlock[0], uiOffset ); + + ulMaterialsProcessed ++; + + // Update the material text and save to the file. + mat->SetText( strMatTextWithNewBlock.c_str() ); + + if( !mat->Parse( strMatTextWithNewBlock.c_str(), strMatTextWithNewBlock.Length() ) ) + { + gameLocal.Warning( "Material %s had error in the newly inserted text %s. \n Aborting.\n", mat->GetName(), &arrCharNewAmbientBlock[0] ); + break; + } + mat->ReplaceSourceFileText(); + mat->Invalidate(); + mat->FreeData(); + } + gameLocal.Printf(" %d Materials processed and changed in total.\n", ulMaterialsProcessed ); +} + + +void Cmd_updateCookedMathData_f( const idCmdArgs& args ) +{ + r_postprocess_colorCurveBias.SetModified(); +} + +#ifdef TIMING_BUILD +void Cmd_ListTimers_f(const idCmdArgs& args) +{ + PRINT_TIMERS; +} + +void Cmd_WriteTimerCSV_f(const idCmdArgs& args) +{ + if (args.Argc() == 2) // Only separator + { + debugtools::TimerManager::Instance().DumpTimerResults(args.Argv(1)); + return; + } + + if (args.Argc() == 3) // separator + comma + { + debugtools::TimerManager::Instance().DumpTimerResults(args.Argv(1), args.Argv(2)); + return; + } + + // No arguments, call default + debugtools::TimerManager::Instance().DumpTimerResults(); +} + +void Cmd_ResetTimers_f(const idCmdArgs& args) +{ + debugtools::TimerManager::Instance().ResetTimers(); +} +#endif // TIMING_BUILD + +/* +================= +idGameLocal::InitConsoleCommands + +Let the system know about all of our commands +so it can perform tab completion +================= +*/ +void idGameLocal::InitConsoleCommands( void ) { + cmdSystem->AddCommand( "listTypeInfo", ListTypeInfo_f, CMD_FL_GAME, "list type info" ); + cmdSystem->AddCommand( "writeGameState", WriteGameState_f, CMD_FL_GAME, "write game state" ); + cmdSystem->AddCommand( "testSaveGame", TestSaveGame_f, CMD_FL_GAME|CMD_FL_CHEAT, "test a save game for a level" ); + cmdSystem->AddCommand( "game_memory", idClass::DisplayInfo_f, CMD_FL_GAME, "displays game class info" ); + cmdSystem->AddCommand( "listClasses", idClass::ListClasses_f, CMD_FL_GAME, "lists game classes" ); + cmdSystem->AddCommand( "listThreads", idThread::ListThreads_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists script threads" ); + cmdSystem->AddCommand( "listEntities", Cmd_EntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists game entities" ); + cmdSystem->AddCommand( "listActiveEntities", Cmd_ActiveEntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists active game entities" ); + cmdSystem->AddCommand( "listMonsters", idAI::List_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists monsters" ); + cmdSystem->AddCommand( "listSpawnArgs", Cmd_ListSpawnArgs_f, CMD_FL_GAME|CMD_FL_CHEAT, "list the spawn args of an entity", idGameLocal::ArgCompletion_EntityName ); + cmdSystem->AddCommand( "say", Cmd_Say_f, CMD_FL_GAME, "text chat" ); + cmdSystem->AddCommand( "sayTeam", Cmd_SayTeam_f, CMD_FL_GAME, "team text chat" ); + cmdSystem->AddCommand( "addChatLine", Cmd_AddChatLine_f, CMD_FL_GAME, "internal use - core to game chat lines" ); + cmdSystem->AddCommand( "gameKick", Cmd_Kick_f, CMD_FL_GAME, "same as kick, but recognizes player names" ); + cmdSystem->AddCommand( "give", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" ); + cmdSystem->AddCommand( "centerview", Cmd_CenterView_f, CMD_FL_GAME, "centers the view" ); + cmdSystem->AddCommand( "god", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" ); + cmdSystem->AddCommand( "notarget", Cmd_Notarget_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables the player as a target" ); + cmdSystem->AddCommand( "noclip", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" ); + cmdSystem->AddCommand( "kill", Cmd_Kill_f, CMD_FL_GAME, "kills the player" ); + cmdSystem->AddCommand( "where", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" ); + cmdSystem->AddCommand( "getviewpos", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" ); + cmdSystem->AddCommand( "setviewpos", Cmd_SetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the current view position" ); + cmdSystem->AddCommand( "teleport", Cmd_Teleport_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleports the player to an entity location", idGameLocal::ArgCompletion_EntityName ); + cmdSystem->AddCommand( "trigger", Cmd_Trigger_f, CMD_FL_GAME|CMD_FL_CHEAT, "triggers an entity", idGameLocal::ArgCompletion_EntityName ); + cmdSystem->AddCommand( "spawn", Cmd_Spawn_f, CMD_FL_GAME|CMD_FL_CHEAT, "spawns a game entity", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "damage", Cmd_Damage_f, CMD_FL_GAME|CMD_FL_CHEAT, "apply damage to an entity", idGameLocal::ArgCompletion_EntityName ); + cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName ); + cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" ); + cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" ); + cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" ); + cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" ); + cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" ); + cmdSystem->AddCommand( "removeline", Cmd_RemoveDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes a debug line" ); + cmdSystem->AddCommand( "blinkline", Cmd_BlinkDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "blinks a debug line" ); + cmdSystem->AddCommand( "listLines", Cmd_ListDebugLines_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists all debug lines" ); + cmdSystem->AddCommand( "playerModel", Cmd_PlayerModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the given model on the player", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "testFx", Cmd_TestFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "testBoneFx", Cmd_TestBoneFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system bound to a joint", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "testLight", Cmd_TestLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a light" ); + cmdSystem->AddCommand( "testPointLight", Cmd_TestPointLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a point light" ); + cmdSystem->AddCommand( "popLight", Cmd_PopLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes the last created light" ); + cmdSystem->AddCommand( "testDeath", Cmd_TestDeath_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests death" ); + cmdSystem->AddCommand( "testSave", Cmd_TestSave_f, CMD_FL_GAME|CMD_FL_CHEAT, "writes out a test savegame" ); + cmdSystem->AddCommand( "testModel", idTestModel::TestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a model", idTestModel::ArgCompletion_TestModel ); + cmdSystem->AddCommand( "testSkin", idTestModel::TestSkin_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a skin on an existing testModel", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "testShaderParm", idTestModel::TestShaderParm_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets a shaderParm on an existing testModel" ); + cmdSystem->AddCommand( "keepTestModel", idTestModel::KeepTestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "keeps the last test model in the game" ); + cmdSystem->AddCommand( "testAnim", idTestModel::TestAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an animation", idTestModel::ArgCompletion_TestAnim ); + cmdSystem->AddCommand( "testParticleStopTime", idTestModel::TestParticleStopTime_f,CMD_FL_GAME|CMD_FL_CHEAT, "tests particle stop time on a test model" ); + cmdSystem->AddCommand( "nextAnim", idTestModel::TestModelNextAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation on test model" ); + cmdSystem->AddCommand( "prevAnim", idTestModel::TestModelPrevAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation on test model" ); + cmdSystem->AddCommand( "nextFrame", idTestModel::TestModelNextFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation frame on test model" ); + cmdSystem->AddCommand( "prevFrame", idTestModel::TestModelPrevFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation frame on test model" ); + cmdSystem->AddCommand( "testBlend", idTestModel::TestBlend_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests animation blending" ); + cmdSystem->AddCommand( "reloadScript", Cmd_ReloadScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads scripts" ); + + cmdSystem->AddCommand( "tdm_updateCookedMathData", Cmd_updateCookedMathData_f, CMD_FL_RENDERER, "Updates lookup textures" ); + + cmdSystem->AddCommand( "script", Cmd_Script_f, CMD_FL_GAME|CMD_FL_CHEAT, "executes a line of script" ); + cmdSystem->AddCommand( "listCollisionModels", Cmd_ListCollisionModels_f, CMD_FL_GAME, "lists collision models" ); + cmdSystem->AddCommand( "collisionModelInfo", Cmd_CollisionModelInfo_f, CMD_FL_GAME, "shows collision model info" ); + cmdSystem->AddCommand( "reexportmodels", Cmd_ReexportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "reexports models", ArgCompletion_DefFile ); + cmdSystem->AddCommand( "reloadanims", Cmd_ReloadAnims_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads animations" ); + cmdSystem->AddCommand( "listAnims", Cmd_ListAnims_f, CMD_FL_GAME, "lists all animations" ); + cmdSystem->AddCommand( "aasStats", Cmd_AASStats_f, CMD_FL_GAME, "shows AAS stats" ); + cmdSystem->AddCommand( "testDamage", Cmd_TestDamage_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a damage def", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand( "weaponSplat", Cmd_WeaponSplat_f, CMD_FL_GAME|CMD_FL_CHEAT, "projects a blood splat on the player weapon" ); + cmdSystem->AddCommand( "saveSelected", Cmd_SaveSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves the selected entity to the .map file" ); + cmdSystem->AddCommand( "deleteSelected", Cmd_DeleteSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "deletes selected entity" ); + cmdSystem->AddCommand( "saveMoveables", Cmd_SaveMoveables_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all moveables to the .map file" ); + cmdSystem->AddCommand( "saveRagdolls", Cmd_SaveRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all ragdoll poses to the .map file" ); + cmdSystem->AddCommand( "bindRagdoll", Cmd_BindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "binds ragdoll at the current drag position" ); + cmdSystem->AddCommand( "unbindRagdoll", Cmd_UnbindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "unbinds the selected ragdoll" ); + cmdSystem->AddCommand( "saveLights", Cmd_SaveLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" ); + cmdSystem->AddCommand( "saveParticles", Cmd_SaveParticles_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" ); + cmdSystem->AddCommand( "clearLights", Cmd_ClearLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "clears all lights" ); + cmdSystem->AddCommand( "gameError", Cmd_GameError_f, CMD_FL_GAME|CMD_FL_CHEAT, "causes a game error" ); + + cmdSystem->AddCommand( "tdm_spr_testIO", Cmd_TestSndIO_f, CMD_FL_GAME, "test soundprop file IO (needs a .spr file)" ); + cmdSystem->AddCommand( "tdm_ai_rel_print", Cmd_PrintAIRelations_f, CMD_FL_GAME, "print the relationship matrix determining relations between AI teams." ); + + cmdSystem->AddCommand( "tdm_attach_offset", Cmd_AttachmentOffset_f, CMD_FL_GAME, "Set the vector offset (x y z) for an attachment on an AI you are looking at. Usage: tdm_attach_offset " ); + cmdSystem->AddCommand( "tdm_attach_rot", Cmd_AttachmentRot_f, CMD_FL_GAME, "Set the rotation (pitch yaw roll) for an attachment on an AI you are looking at. Usage: tdm_attach_rot (NOTE: Rotation is applied before translation, angles are relative to the joint orientation)" ); + + cmdSystem->AddCommand( "inventory_hotkey", Cmd_InventoryHotkey_f, CMD_FL_GAME, "Usage: inventory_hotkey [item]\nSelects an item from the currently available inventory. If 'item' is omitted, it will return the current item's hotkey name, if any." ); + cmdSystem->AddCommand( "inventory_use", Cmd_InventoryUse_f, CMD_FL_GAME, "Usage: inventory_use [item]\nUses an item in the currently available inventory without selectign it. If 'item' is omitted, it will use the currently selected item." ); + cmdSystem->AddCommand( "inventory_cycle_maps", Cmd_InventoryCycleMaps_f, CMD_FL_GAME, "Usage: Bind a key to this command to cycle through the inventory maps." ); + cmdSystem->AddCommand( "inventory_cycle_group", Cmd_InventoryCycleGroup_f, CMD_FL_GAME, "Usage: Bind a key to this command to cycle through the specified inventory group." ); + + cmdSystem->AddCommand( "reloadXData", Cmd_ReloadXData_f, CMD_FL_GAME, "Reloads the xdata declarations and refreshes all readables." ); + + cmdSystem->AddCommand( "aas_showWalkPath", Cmd_ShowWalkPath_f, CMD_FL_GAME, "Shows the walk path from the player to the given area number (AAS32)." ); + cmdSystem->AddCommand( "aas_showReachabilities",Cmd_ShowReachabilities_f, CMD_FL_GAME, "Shows the reachabilities for the given area number (AAS32)." ); + cmdSystem->AddCommand( "aas_showStats", Cmd_ShowAASStats_f, CMD_FL_GAME, "Shows the AAS statistics." ); + cmdSystem->AddCommand( "eas_showRoute", Cmd_ShowEASRoute_f, CMD_FL_GAME, "Shows the EAS route to the goal area." ); + + cmdSystem->AddCommand( "tdm_start_conversation", Cmd_StartConversation_f, CMD_FL_GAME, "Starts the conversation with the given name." ); + cmdSystem->AddCommand( "tdm_list_conversations", Cmd_ListConversations_f, CMD_FL_GAME, "List all available conversations by name." ); + + cmdSystem->AddCommand( "tdm_show_loot", Cmd_ShowLoot_f, CMD_FL_GAME|CMD_FL_CHEAT, "Highlight all loot items in the map." ); + + cmdSystem->AddCommand( "tdm_activatelogclass", Cmd_ActivateLog_f, CMD_FL_GAME, "Activates a specific log class during run-time (as defined in darkmod.ini)", CGlobal::ArgCompletion_LogClasses ); + cmdSystem->AddCommand( "tdm_deactivatelogclass", Cmd_DeactivateLog_f, CMD_FL_GAME, "De-activates a specific log class during run-time (as defined in darkmod.ini)", CGlobal::ArgCompletion_LogClasses ); + cmdSystem->AddCommand( "tdm_batchConvertMaterials", Cmd_BatchConvertMaterials_f, CMD_FL_GAME, "Converts specified number of materials to support new ambient lighting" ); + + cmdSystem->AddCommand( "tdm_restart_gui_update_objectives", Cmd_RestartGuiCmd_UpdateObjectives_f, CMD_FL_GAME, "Don't use. Reserved for internal use to dispatch restart GUI commands to the local game instance."); + + cmdSystem->AddCommand( "tdm_list_missions", Cmd_ListMissions_f, CMD_FL_GAME, "Lists all available missions."); + cmdSystem->AddCommand( "tdm_set_mission_completed", Cmd_SetMissionCompleted_f, CMD_FL_GAME, "Sets or clears the 'completed' flag of a named mission."); + + cmdSystem->AddCommand( "tdm_end_mission", Cmd_EndMission_f, CMD_FL_GAME, "Ends this mission and proceeds to the next."); + +#ifndef ID_DEMO_BUILD + cmdSystem->AddCommand( "disasmScript", Cmd_DisasmScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "disassembles script" ); + cmdSystem->AddCommand( "recordViewNotes", Cmd_RecordViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "record the current view position with notes" ); + cmdSystem->AddCommand( "showViewNotes", Cmd_ShowViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "show any view notes for the current map, successive calls will cycle to the next note" ); + cmdSystem->AddCommand( "closeViewNotes", Cmd_CloseViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "close the view showing any notes for this map" ); + cmdSystem->AddCommand( "exportmodels", Cmd_ExportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "exports models", ArgCompletion_DefFile ); + + // multiplayer client commands ( replaces old impulses stuff ) + cmdSystem->AddCommand( "clientDropWeapon", idMultiplayerGame::DropWeapon_f, CMD_FL_GAME, "drop current weapon" ); + cmdSystem->AddCommand( "clientMessageMode", idMultiplayerGame::MessageMode_f, CMD_FL_GAME, "ingame gui message mode" ); + // FIXME: implement +// cmdSystem->AddCommand( "clientVote", idMultiplayerGame::Vote_f, CMD_FL_GAME, "cast your vote: clientVote yes | no" ); +// cmdSystem->AddCommand( "clientCallVote", idMultiplayerGame::CallVote_f, CMD_FL_GAME, "call a vote: clientCallVote si_.. proposed_value" ); + cmdSystem->AddCommand( "clientVoiceChat", idMultiplayerGame::VoiceChat_f, CMD_FL_GAME, "voice chats: clientVoiceChat " ); + cmdSystem->AddCommand( "clientVoiceChatTeam", idMultiplayerGame::VoiceChatTeam_f, CMD_FL_GAME, "team voice chats: clientVoiceChat " ); + + // multiplayer server commands + cmdSystem->AddCommand( "serverMapRestart", idGameLocal::MapRestart_f, CMD_FL_GAME, "restart the current game" ); + cmdSystem->AddCommand( "serverForceReady", idMultiplayerGame::ForceReady_f,CMD_FL_GAME, "force all players ready" ); + cmdSystem->AddCommand( "serverNextMap", idGameLocal::NextMap_f, CMD_FL_GAME, "change to the next map" ); +#endif + + // greebo: Added commands to alter the clipmask/contents of entities. + cmdSystem->AddCommand( "setClipMask", Cmd_SetClipMask, CMD_FL_GAME, "Set the clipmask of the target entity, usage: 'setClipMask crate01 1313'", idGameLocal::ArgCompletion_EntityName); + cmdSystem->AddCommand( "setClipContents", Cmd_SetClipContents, CMD_FL_GAME, "Set the contents flags of the target entity, usage: 'setClipContents crate01 1313'", idGameLocal::ArgCompletion_EntityName); + + // localization help commands + cmdSystem->AddCommand( "nextGUI", Cmd_NextGUI_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleport the player to the next func_static with a gui" ); + cmdSystem->AddCommand( "testid", Cmd_TestId_f, CMD_FL_GAME|CMD_FL_CHEAT, "output the string for the specified id." ); +#ifdef TIMING_BUILD + cmdSystem->AddCommand( "listTimers", Cmd_ListTimers_f, CMD_FL_GAME, "Shows total run time and max time of timers (TIMING_BUILD only)." ); + cmdSystem->AddCommand( "writeTimerCSV", Cmd_WriteTimerCSV_f, CMD_FL_GAME, "Writes the timer data to a csv file (usage: writeTimerCSV ). The default separator is ';', the default comma is '.'"); + cmdSystem->AddCommand( "resetTimers", Cmd_ResetTimers_f, CMD_FL_GAME, "Resets the timer data so far."); +#endif +} + +/* +================= +idGameLocal::ShutdownConsoleCommands +================= +*/ +void idGameLocal::ShutdownConsoleCommands( void ) { + cmdSystem->RemoveFlaggedCommands( CMD_FL_GAME ); +} diff --git a/game/gamesys/SysCmds.h b/game/gamesys/SysCmds.h new file mode 100644 index 000000000..1f12172c6 --- /dev/null +++ b/game/gamesys/SysCmds.h @@ -0,0 +1,25 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SYS_CMDS_H__ +#define __SYS_CMDS_H__ + +void D_DrawDebugLines( void ); + +#endif /* !__SYS_CMDS_H__ */ diff --git a/game/gamesys/SysCvar.cpp b/game/gamesys/SysCvar.cpp new file mode 100644 index 000000000..593f399ad --- /dev/null +++ b/game/gamesys/SysCvar.cpp @@ -0,0 +1,779 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#if defined( _DEBUG ) + #define BUILD_DEBUG "-debug" +#else + #define BUILD_DEBUG "-release" +#endif + +/* + +All game cvars should be defined here. + +*/ + +const char *si_gameTypeArgs[] = { "singleplayer", "deathmatch", "Tourney", "Team DM", "Last Man", NULL }; +const char *si_readyArgs[] = { "Not Ready", "Ready", NULL }; +const char *si_spectateArgs[] = { "Play", "Spectate", NULL }; + +const char *ui_skinArgs[] = { "skins/characters/player/marine_mp", "skins/characters/player/marine_mp_red", "skins/characters/player/marine_mp_blue", "skins/characters/player/marine_mp_green", "skins/characters/player/marine_mp_yellow", NULL }; +const char *ui_teamArgs[] = { "Red", "Blue", NULL }; + +struct gameVersion_s { + gameVersion_s( void ) { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } + char string[256]; +} gameVersion; + +idCVar g_version( "g_version", gameVersion.string, CVAR_GAME | CVAR_ROM, "game version" ); + +/** +* DarkMod Cvars - see text description in declaration below for descriptions +**/ +idCVar cv_player_spawnclass( "tdm_player_spawnclass", "atdm:player_thief", CVAR_GAME, "The player's classname." ); +idCVar cv_player_waituntilready( "tdm_player_wait_until_ready", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 (default), the player must be ready before the map is started."); + +idCVar cv_default_mission_info_file("tdm_default_mission_info_file", "fms/missions.tdminfo", CVAR_GAME, "The filename relative to darkmod/fms/ where all the persistent mission data is stored." ); + +idCVar cv_ai_sndvol( "tdm_ai_sndvol", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifier to the volume of suspcious sounds that AI's hear. Defaults to 0.0 dB" ); +idCVar cv_ai_bark_show( "tdm_ai_showbark", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Displays the current sound when the AI starts barking" ); +idCVar cv_ai_sight_prob( "tdm_ai_sight_prob", "0.7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifies the AI's chance of seeing you. Small changes may have a large effect." ); +idCVar cv_ai_sight_mag( "tdm_ai_sight_mag", "1.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifies the amount of visual alert that gets added on when the sight probability check succeeds and the AI do see you (default 1.0)." ); +idCVar cv_ai_sightmaxdist( "tdm_ai_sightmax", "60.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The distance (in meters) above which an AI will not see you even with a fullbright lightgem. Defaults to 60m. Effects visibility in a complicated way." ); +idCVar cv_ai_sightmindist( "tdm_ai_sightmin", "11.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The distance (in meters) below which an AI has a 100% chance of seeing you with a fullbright lightgem. Defaults to 11m (~36 ft). Effects visibility in a complicated way." ); +idCVar cv_ai_tactalert( "tdm_ai_tact", "20.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The default tactile alert if an AI bumps an enemy or an enemy bumps an AI. Default value is 20 alert units (pretty much full alert)." ); +idCVar cv_ai_bumpobject_impulse( "tdm_ai_bumpobject_impulse", "250", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Impulse applied when an AI bumps into an object with its AF when animating. Different from the kick force it applies to an object blocking its path." ); // grayman #2568? - 1500->250 +idCVar cv_ai_debug( "tdm_ai_debug", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, AI alert events will be sent to the console for debugging purposes." ); +idCVar cv_ai_fov_show ( "tdm_ai_showfov", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, a debug graphic showing the field of vision of the AI will be drawn. Blue cone represents the vertical FOV, orange cone represents the horizontal."); +idCVar cv_ai_ko_show ( "tdm_ai_showko", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, a debug graphic showing the knockout region of the AI will be drawn. The green cone shows the vertical admittance angle, the red cone shows the horizontal angle."); +idCVar cv_ai_animstate_show ( "tdm_ai_showanimstate", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the name of the AI's current animation state will be shown."); +idCVar cv_ai_task_show ( "tdm_ai_showtasks", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the name of the AI's current tasks will be shown."); +idCVar cv_ai_alertlevel_show ( "tdm_ai_showalert", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the AI's current total alert units is shown (Note: This is not the alert state, use tdm_ai_showtasks for that)."); +idCVar cv_ai_dest_show ( "tdm_ai_showdest", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, an arrow is drawn from every AI to its intended pathing destination."); +idCVar cv_ai_goalpos_show ( "tdm_ai_showgoalpos", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the current goalpos (seekpos) is drawn in the world (!= move destination)."); +idCVar cv_ai_aasarea_show ( "tdm_ai_showAASarea", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the current AAS area of the AI is drawn in the world."); +idCVar cv_ai_debug_blocked ( "tdm_ai_debug_blocked", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug drawings of the movement subsystem are shown."); +idCVar cv_ai_door_show( "tdm_ai_showdoor", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the desired positions for opening and closing the door are shown."); +idCVar cv_ai_elevator_show( "tdm_ai_showelevator", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the debug drawings for AI handling elevators are shown."); + +idCVar cv_ai_sight_thresh ( "tdm_ai_sight_thresh", "1.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the minimum light per-AI-frame gem generated visual stimulus amount required for an AI to be able to see the player or another entity directly when searching."); +idCVar cv_ai_sight_scale ( "tdm_ai_sight_scale", "1000.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the distance that is multiplied by the lightQuotient from the LAS and visual acuity of the AI scaled from 0 to 1, that indicates how far away the AI can be and see a location."); +idCVar cv_ai_show_enemy_visibility ("tdm_ai_show_enemy_visibility", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, the visibility of the AI's enemy is drawn (red = obscured or hidden in darkness, green = the opposite)."); +idCVar cv_ai_show_conversationstate("tdm_ai_show_conversationstate", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, the AI will draw debug output with regard to their conversation state."); + +idCVar cv_ai_acuity_L3 ( "tdm_ai_acuity_L3", "1.1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 3 but not yet 4"); +idCVar cv_ai_acuity_L4 ( "tdm_ai_acuity_L4", "1.3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 4 but not yet 5"); +idCVar cv_ai_acuity_L5 ( "tdm_ai_acuity_L5", "1.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 5"); +idCVar cv_ai_acuity_susp( "tdm_ai_acuity_susp", "1.2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is suspicious due to evidence. It is in addition to the other modifiers."); + +idCVar cv_sndprop_disable( "tdm_sndprop_disable", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation will not be calculated." ); +idCVar cv_spr_debug( "tdm_spr_debug", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation debugging information will be sent to the console, and the log information will become more detailed." ); +idCVar cv_spr_show( "tdm_showsprop", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation paths to nearby AI will be shown as lines. The volume of the sound heard by the AI and the alert increase will be displayed." ); +idCVar cv_spr_radius_show( "tdm_showsprop_radius", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound ranges are drawn." ); + +idCVar cv_ko_show( "tdm_showko", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, knockout zones will be shown for debugging." ); +idCVar cv_ai_search_show ( "tdm_ai_search_show", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If >= 1.0, this is the number of milliseconds for which a graphic showing search activity targets will be shown. If < 1.0 then the graphics will not be drawn. For debugging."); +idCVar cv_ai_visdist_show ( "tdm_ai_visdist_show", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If >= 1.0, this is the number of milliseconds for which a graphic showing vision distance test results. Green arrows indicate within range, Red indicate out of range, purple indicate gap between range and target. For debugging."); + +idCVar cv_ai_opt_disable ( "tdm_ai_opt_disable", "1", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs not in the Potentially Visible Set will be completely disabled if they have neverdormant set to 0."); +idCVar cv_ai_opt_noanims ( "tdm_ai_opt_noanims", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs will not animate."); +idCVar cv_ai_opt_novisualscan ( "tdm_ai_opt_novisualscan", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs not in the Potentially Visible Set will not look for enemies, not even enemy AIs."); +idCVar cv_ai_opt_forceopt ( "tdm_ai_opt_forceopt", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs will always be treated as being outside the PVS for the purposes of the other tdm_ai_opt_* spawnargs." ); +idCVar cv_ai_opt_nothink ( "tdm_ai_opt_nothink", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not perform their regular thinking routine (including Mind)." ); +idCVar cv_ai_opt_interleavethinkmindist ( "tdm_ai_opt_interleavethinkmindist", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If true (nonzero), the AI will start interleaved thinking if the distance to the player is greater than the set value." ); +idCVar cv_ai_opt_interleavethinkmaxdist ( "tdm_ai_opt_interleavethinkmaxdist", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If true (nonzero), this is the distance where interleave frame will reach its maximum value." ); +idCVar cv_ai_opt_interleavethinkskippvscheck ( "tdm_ai_opt_interleavethinkskipPVS", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If true (nonzero), the player PVS check for interleaved thinking will be skipped, so that the AI can also do interleaved thinking while in view." ); +idCVar cv_ai_opt_interleavethinkframes ( "tdm_ai_opt_interleavethinkframes", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "If true (nonzero), this is the maximum interleaved thinking frame number." ); +idCVar cv_ai_opt_update_enemypos_interleave ( "tdm_ai_opt_update_enemypos_interleave", "48", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time to pass between enemy position updates. Set this to 0 for updates each frame." ); + +idCVar cv_ai_opt_nomind ( "tdm_ai_opt_nomind", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI has its Mind thinking routines disabled." ); +idCVar cv_ai_opt_novisualstim ( "tdm_ai_opt_novisualstim", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not process any incoming visual stimuli." ); +idCVar cv_ai_opt_nolipsync ( "tdm_ai_opt_nolipsync", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not play lipsync animations." ); +idCVar cv_ai_opt_nopresent ( "tdm_ai_opt_nopresent", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not be presented." ); +idCVar cv_ai_opt_noobstacleavoidance ( "tdm_ai_opt_noobstacleavoidance", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not check for obstacles." ); +idCVar cv_ai_hiding_spot_max_light_quotient( "tdm_ai_hiding_spot_max_light_quotient", "2.0", CVAR_GAME | CVAR_FLOAT, "Hiding spot search light quotient." ); +idCVar cv_ai_max_hiding_spot_tests_per_frame( "tdm_ai_max_hiding_spot_tests_per_frame", "10", CVAR_GAME | CVAR_INTEGER, "This is the maximum number of hiding spot point tests to do in a single AI frame." ); + +idCVar cv_ai_debug_anims ( "tdm_ai_debug_anims", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), show debug info about AI anims in the console and log file." ); + +idCVar cv_show_health ( "tdm_show_health", "0", CVAR_ARCHIVE | CVAR_GAME | CVAR_BOOL, "If true (nonzero), show health of entities for debugging." ); + +idCVar cv_ai_show_aasfuncobstacle_state("tdm_ai_show_aasfuncobstacle_state", "0", CVAR_ARCHIVE | CVAR_GAME | CVAR_BOOL, "If true (nonzero), idFuncAASObstacles will show their state at spawn time and during changes." ); + +idCVar cv_interaction_vfp_type("tdm_interaction_vfp_type", "1", CVAR_ARCHIVE | CVAR_BOOL, "If 1, the new enhanced interaction are used. Set to 0 to use default interaction shader." ); +idCVar cv_tdm_widescreenmode("tdm_wideScreenMode", "0", CVAR_ARCHIVE | CVAR_INTEGER, "The widescreen mode selected in the main menu (for internal use)." ); +idCVar cv_tdm_menu_music("tdm_menu_music", "1", CVAR_ARCHIVE | CVAR_BOOL, "Whether to play background music in the main menu (for internal use)." ); + +idCVar cv_tdm_show_trainer_messages("tdm_show_trainer_messages", "1", CVAR_BOOL | CVAR_ARCHIVE, "Whether TDM trainer maps should display pop-ups with helpful gameplay information." ); + +idCVar cv_tdm_default_relations_def( "tdm_default_relations_def", "atdm:team_relations_default", CVAR_GAME | CVAR_ARCHIVE, "The name of the entityDef holding the TDM default team relationships." ); + +/** +* DarkMod GUI CVARs +**/ +// Tels: can be removed when D3 is open source and we can access sys_lang properly +idCVar cv_tdm_lang("tdm_lang", "english", CVAR_GUI | CVAR_ARCHIVE, "The current used language. Possible values are 'english', 'german', 'russian' etc." ); + +idCVar cv_tdm_fm_path( "tdm_fm_path", "fms/", CVAR_GUI, "(internal) The path where the fan mission packages are stored."); +idCVar cv_tdm_fm_desc_file( "tdm_fm_desc_file", "darkmod.txt", CVAR_GUI, "(internal) The description file name of FM packages."); +idCVar cv_tdm_fm_notes_file( "tdm_fm_notes_file", "readme.txt", CVAR_GUI, "(internal) The readme file name of FM packages."); +idCVar cv_tdm_fm_current_file( "tdm_fm_current_file", "currentfm.txt", CVAR_GUI, "(internal) The file where the name of the currently installed FM is stored."); +idCVar cv_tdm_fm_startingmap_file( "tdm_fm_startingmap_file", "startingmap.txt", CVAR_GUI, "(internal) The file where the name of the starting map of an FM is stored."); +idCVar cv_tdm_fm_mapsequence_file( "tdm_fm_mapsequence_file", "tdm_mapsequence.txt", CVAR_GUI, "(internal) The file where the sequence of the map files is stored."); +idCVar cv_tdm_fm_splashimage_file( "tdm_fm_splashimage_file", "install_splash.tga", CVAR_GUI, "(internal) The file to be used as splash screen for the installation GUI."); +idCVar cv_tdm_fm_sync_config_files("tdm_fm_sync_config_files", "1", CVAR_BOOL | CVAR_ARCHIVE, "If true (1) the FM loader will sync DoomConfig.cfg files from the darkmod folder to the FM directory and back."); +idCVar cv_tdm_fm_restart_delay("tdm_fm_restart_delay", "0", CVAR_ARCHIVE | CVAR_INTEGER, "If non-zero, this is the timespan in milliseconds to wait between D3 restarts (to let the previous D3 process fully release all resources)." ); + +/** +* DarkMod HTTP related CVARs +**/ +idCVar cv_tdm_proxy("tdm_proxy", "", CVAR_ARCHIVE, "The proxy to use when connecting to the internet, format: hostname:port" ); +idCVar cv_tdm_proxy_user("tdm_proxy_user", "", CVAR_ARCHIVE, "The proxy user to use when connecting to the internet via proxy." ); +idCVar cv_tdm_proxy_pass("tdm_proxy_pass", "", CVAR_ARCHIVE, "The proxy password to use when connecting to the internet via proxy." ); +idCVar cv_tdm_allow_http_access("tdm_allow_http_access", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If true (nonzero), TDM is allowed to send HTTP request to the TDM servers to check for updates, missions, etc. Setting this to false disables all web functionality." ); +idCVar cv_tdm_mission_list_urls("tdm_mission_list_urls", "http://www.thedarkmod.com/missiondb/get_available_missions.php;http://www.thedarkmod.com/missiondb/available_missions.xml", CVAR_GAME, "The URLs to check for the mission list XML." ); +idCVar cv_tdm_mission_details_url("tdm_mission_details_url", "http://www.thedarkmod.com/missiondb/get_mission_details.php?id=%d", CVAR_GAME, "The URLs to check for the mission details XML." ); +idCVar cv_tdm_mission_screenshot_url("tdm_mission_screenshot_url", "http://www.thedarkmod.com/%s", CVAR_GAME, "The URL template to download the mission screenshots." ); +idCVar cv_tdm_version_check_url("tdm_version_check_url", "http://www.thedarkmod.com/update/tdm_version.xml", CVAR_GAME, "The URL to check for the current TDM version." ); + +/** +* DarkMod DEBUG related CVARs +**/ +idCVar cv_tdm_http_base_url( "tdm_http_base_url", "", CVAR_GAME, "If set, this URL will be used instead of the actual download URL when downloading FMs. Useful for testing downloading FMs from temp. servers." ); + +idCVar cv_debug_aastype( "tdm_debug_aastype", "aas32", CVAR_GAME | CVAR_ARCHIVE, "Sets the AAS type used for visualisation with impulse 27"); + +idCVar cv_las_showtraces( "tdm_las_showtraces", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), traces from light origin to testpoints used for visibility testiung are drawn." ); + +idCVar cv_show_gameplay_time( "tdm_show_gameplaytime", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), the gameplay time is shown in the player HUD." ); + +idCVar cv_tdm_difficulty( "tdm_difficulty", "-1", CVAR_GAME | CVAR_INTEGER, "Set this to 0, 1 or 2 to override the difficulty setting of any map (for testing purposes). Set this back to -1 to disable the setting (which is the default). This setting isn't saved between session." ); + +idCVar cv_sr_disable ( "tdm_sr_disable", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to disable all stim/response processing." ); +idCVar cv_sr_show( "tdm_show_stimresponse", "0", CVAR_GAME | CVAR_INTEGER, "Set to 1 to show all successful stims, set to 2 to show all including failed ones." ); + +idCVar cv_debug_mainmenu( "tdm_debug_mainmenu", "0", CVAR_BOOL, "Set to 1 to enable main menu GUI debugging in the console." ); +idCVar cv_mainmenu_confirmquit( "tdm_mainmenu_confirmquit", "1", CVAR_ARCHIVE | CVAR_BOOL, "Set to 0 to disable the 'Quit Game' confirmation dialog when exiting the game." ); + +idCVar cv_force_savegame_load( "tdm_force_savegame_load", "0", CVAR_BOOL|CVAR_ARCHIVE, "Set to 1 to skip code revision check on savegame load." ); +idCVar cv_savegame_compress( "tdm_savegame_compress", "1", CVAR_BOOL|CVAR_ARCHIVE, "Set to 0 to disable savegame file compression." ); + +idCVar cv_screenshot_format( "tdm_screenshot_format", "jpg", CVAR_ARCHIVE, "Image format used to store ingame screenshots: png/tga/jpg/bmp." ); +/** +* Dark Mod player movement +* Use multipliers instead of setting a speed for each +**/ +idCVar cv_pm_runmod( "pm_runmod", "2.12", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain run speed from pm_walkspeed." ); +idCVar cv_pm_run_backmod( "pm_run_backmod", "0.7", CVAR_GAME | CVAR_FLOAT , "The multiplier applied to existing run speed when the player is running backwards." ); +idCVar cv_pm_creepmod( "pm_creepmod", "0.44", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain creep speed from pm_walkspeed." ); +idCVar cv_pm_crouchmod( "pm_crouchmod", "0.54", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain crouch speed from walk speed." ); +idCVar cv_pm_max_swimspeed_mod( "pm_max_swimspeed_mod", "1.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum speed of the player when moving in >= waist deep water, relative to player walkspeed." ); +idCVar cv_pm_pushmod( "pm_pushmod", "0.15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Alters the impulse applied when the player runs into an object. Fractional modifier that multiplies the default D3 impulse. ONLY APPLIES TO OBJECTS BEING KICKED. Default is 0.15" ); +idCVar cv_pm_push_maximpulse( "pm_push_maximpulse", "300", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the maximum impulse that is allowed to be propagated by the player to moveables just by kicking them. Only applies for 'lightweight' moveables below playermass*pm_push_heavy_threshold. Default is 300 units*kg per second." ); +idCVar cv_pm_push_start_delay( "pm_push_start_delay", "1000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the delay in msecs before heavy things get pushed by the player. Default is 1000 msecs." ); +idCVar cv_pm_push_accel_time( "pm_push_accel_time", "1000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the acceleration time in msecs when the player is starting to push things. After this time has passed, the pushed object has reached its maximum possible velocity. Default is 1000 msecs." ); +idCVar cv_pm_push_heavy_threshold( "pm_push_heavy_threshold", "0.15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the fraction of the player mass, above which pushable things are considered as 'heavy'. Default is 0.75." ); +idCVar cv_pm_push_max_mass( "pm_push_max_mass", "200", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the maximum mass in kg a moveable can have to be pushable at all. Default is 200 kg."); + +idCVar cv_pm_weightmod( "pm_weightmod", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Gets multiplied to the force applied to objects below the player model. Defaults to 1." ); + +idCVar cv_pm_mantle_reach( "pm_mantle_reach", "0.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Horizontal reach of mantle ability, as fraction of player height. Default is 0.5" ); +idCVar cv_pm_mantle_height( "pm_mantle_height", "0.2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Vertical reach of mantle ability, as fraction of player height. Default is 0.2" ); +idCVar cv_pm_mantle_minflatness( "pm_mantle_minflatness", "0.707", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Cannot mantle on top of surfaces whose angle's cosine is smaller than this value. e.g. >1.0 means nothing can be mantled; 1.0 means only perfectly flat floors (0 degrees) can be mantled on top of; ~0.707 means no surfaces steeper than 45 degrees can be mantled on top of; 0.5 means no surfaces steeper than 60 degrees can be mantled on top of; a large negative value (like -10) means all surfaces can be mantled regardless of steepness. Default is 0.707." ); + +idCVar cv_pm_mantle_jump_hold_trigger( "pm_mantle_jump_hold_trigger", "100", CVAR_GAME | CVAR_INTEGER , "Default length of time for holding down jump key to start mantling." ); +idCVar cv_pm_mantle_min_velocity_for_damage( "pm_mantle_min_velocity_for_damage", "15", CVAR_GAME | CVAR_FLOAT , "Default damage scale for mantling at high velocities." ); +idCVar cv_pm_mantle_damage_per_velocity_over_minimum( "pm_mantle_damage_per_velocity_over_minimum", "0.5", CVAR_GAME | CVAR_FLOAT , "The meters per second of relative velocity beyond which the player takes damage when trying to mantle a target." ); +idCVar cv_pm_mantle_hang_msecs( "pm_mantle_hang_msecs", "750", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time that player hangs if mantle begins with the player's feet of the ground." ); +idCVar cv_pm_mantle_pull_msecs( "pm_mantle_pull_msecs", "750", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to pull themselves up to shoulder level with the mantle surface." ); +idCVar cv_pm_mantle_shift_hands_msecs( "pm_mantle_shift_hands_msecs", "500", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to shift their hands from pulling to pushing." ); +idCVar cv_pm_mantle_push_msecs( "pm_mantle_push_msecs", "800", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to push themselves up onto the mantle surface." ); + +/** +* Dark Mod Jumping +**/ +idCVar cv_tdm_walk_jump_vel( "tdm_walk_jump_vel", "2.2", CVAR_FLOAT, "Jump velocity multiplier when walking" ); +idCVar cv_tdm_run_jump_vel( "tdm_run_jump_vel", "2.5", CVAR_FLOAT, "Jump velocity multiplier when running" ); +idCVar cv_tdm_crouch_jump_vel( "tdm_crouch_jump_vel", "0.5", CVAR_FLOAT, "Jump velocity multiplier when crouching" ); +idCVar cv_tdm_min_vel_jump( "tdm_min_vel_jump", "0.0", CVAR_FLOAT, "The minimum speed before cv_tdm_run_jump_vel is used" ); +idCVar cv_tdm_fwd_jump_vel( "tdm_fwd_jump_vel", "50.0", CVAR_FLOAT, "Forward vector multiple for jumping" ); +idCVar cv_tdm_backwards_jump_modifier( "tdm_back_jump_factor", "0.5", CVAR_FLOAT, "Backwards multiplier for jumping, relative to forward jumping. A factor of 1 means that the player gains as much speed through backwards jumping as through forward jumping." ); +idCVar cv_tdm_jump_relaxation_time( "tdm_jump_relaxation_time", "4", CVAR_FLOAT, "Time in seconds needed to regain full jump strength again." ); + +idCVar cv_tdm_footfalls_movetype_specific( "tdm_footfall_sounds_movetype_specific", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to use move-type dependent foot fall sounds." ); + +// Dark Mod crouching +idCVar cv_tdm_crouch_toggle( "tdm_toggle_crouch", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make crouching toggleable." ); +idCVar cv_tdm_crouch_toggle_hold_time( "tdm_crouch_toggle_hold_time", "400", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The time to hold crouch while on a rope/ladder for starting to slide down." ); +idCVar cv_tdm_reattach_delay( "tdm_reattach_delay", "100", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Delay (in ms) for reattaching to ropes/ladders after detaching using crouch." ); + + +/** +* Dark Mod Leaning +**/ +idCVar cv_pm_lean_angle( "pm_lean_angle", "15.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The tilt angle that the player can lean to at a full lean, in degrees." ); +idCVar cv_pm_lean_time( "pm_lean_time", "400.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Time it takes to get to a full lean, in milliseconds." ); +idCVar cv_pm_lean_height( "pm_lean_height", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Height of the fulcrum about which the player leans, as a fraction of the player's eye height." ); +idCVar cv_pm_lean_stretch( "pm_lean_stretch", "2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The amount the player stretches out at a full lean, written as a fraction of the player's un-stretched height." ); +idCVar cv_pm_lean_forward_angle( "pm_lean_forward_angle", "2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: The tilt angle that the player can lean to at a full lean, in degrees." ); +idCVar cv_pm_lean_forward_time( "pm_lean_forward_time", "400.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: Time it takes to get to a full lean, in milliseconds." ); +idCVar cv_pm_lean_forward_height( "pm_lean_forward_height", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: Height of the fulcrum about which the player leans, as a fraction of the player's eye height." ); +idCVar cv_pm_lean_forward_stretch( "pm_lean_forward_stretch", "15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: The amount the player stretches out at a full lean, written as a fraction of the player's un-stretched height." ); +idCVar cv_pm_lean_to_valid_increments( "pm_lean_to_valid_increments", "25", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Integer number of increments used for testing when leaning back to a valid position after a leaned clipping problem. The higher the number, the smoother the un-lean will feel, but the higher the computation time." ); +idCVar cv_pm_lean_door_increments( "pm_lean_door_increments", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Integer number of increments used for testing when extending a lean through a door acoustically." ); +idCVar cv_pm_lean_door_max( "pm_lean_door_max", "40", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Max distance of door that may be listened through at normal incidence, in doom units." ); +idCVar cv_pm_lean_door_bounds_exp( "pm_lean_door_bounds_exp", "8.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Amount to expand the camera view bounds by when testing if the player is still pressed against a door for listening purposes (default 8.0)."); +idCVar cv_pm_lean_toggle( "pm_lean_toggle", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make leaning toggleable." ); + +/** +* Dark Mod Frobbing +* Frob expansion radius for easier frobbing, time it takes for frob highlight to fade in and out +**/ +idCVar cv_frob_distance_default( "tdm_frob_distance_default", "63", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Default frob distance for all items in doom units. For developer use only, will break game if set wrong! Default is 63."); +idCVar cv_frob_width( "tdm_frob_width", "10.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "When frobbing, a cube of this dimension is created at the point the frob hit, and things within are frob candidates. Makes frobbing easier but can go thru solid objects if set too high. Default is 10."); +idCVar cv_frob_fadetime( "tdm_frob_fadetime", "100", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time it takes for frob highlight effect to fade in and out." ); +idCVar cv_frob_debug_bounds( "tdm_frob_debug_bounds", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to see a visualization of the bounds that are used to check for frobable items within them." ); +idCVar cv_frob_weapon_selects_weapon( "tdm_frob_weapon_selects_weapon", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to have weapons automatically selected when the respective item is picked up." ); +idCVar cv_frob_debug_hud( "tdm_frob_debug_hud", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to show some frobbing info." ); + +/** +* Dark Mod Misc. Control Options +**/ +idCVar cv_weapon_next_on_empty( "tdm_weapon_next_on_empty", "0", CVAR_GAME | CVAR_BOOL, "If set to 1, when you run out of a particular type of arrows, you will auto-switch to the next available weapon. (This can get you in trouble if it switches to a fire arrow)." ); + +/** +* Physics +**/ +idCVar cv_collision_damage_scale_vert( "tdm_collision_damage_scale_vert", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This globally scales the damage AI take from vertical collisions/decelerations. This multiplies delta-velocity squared." ); +idCVar cv_collision_damage_scale_horiz( "tdm_collision_damage_scale_horiz", "0.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This globally scales the damage AI take from horizontal collisions/decelerations. This multiplies delta-velocity squared." ); +idCVar cv_drag_limit_force( "tdm_drag_limit_force", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Cheat: Set to 0 to disable finite acceleration while grabbing objects." ); +idCVar cv_drag_force_max( "tdm_drag_force_max", "100000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum force the player can apply to a dragged object [kg * doom units / second^2]" ); +idCVar cv_drag_stuck_dist( "tdm_drag_stuck_dist", "38.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Distance from the grab point at which object is determined to be 'stuck' and possibly auto-dropped." ); +idCVar cv_drag_damping( "tdm_drag_damping", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Damping applied to objects being grabbed by the player" ); +idCVar cv_drag_damping_AF( "tdm_drag_damping_af", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Damping applied to ragdolls being grabbed by the player" ); +idCVar cv_drag_AF_ground_timer( "tdm_drag_af_ground_timer", "800", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time in milliseconds that it takes to ramp up to full vertical velocity after a ground-restricted body has come back to ground contact." ); +idCVar cv_drag_AF_free( "tdm_drag_af_free", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "This is a cheat that allows lifting all AI bodies completely off the ground when dragging them. Useful for mappers who want to set up ragdolls ingame." ); +idCVar cv_drag_jump_masslimit( "tdm_drag_jump_masslimit", "20", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "When the player is holding something above this mass, jumping becomes impossible." ); +idCVar cv_drag_encumber_minmass( "tdm_drag_encumber_minmass", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Minimum carried mass that starts to effect movement speed." ); +idCVar cv_drag_encumber_maxmass( "tdm_drag_encumber_maxmass", "55", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Carried mass at which movement speed clamps to the lowest value." ); +idCVar cv_drag_encumber_max( "tdm_drag_encumber_max", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum encumbrance when carrying heavy things (expressed as a fraction of maximum unencumbered movement speed)." ); +idCVar cv_dragged_item_highlight( "tdm_dragged_item_highlight", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set this to 1 (=TRUE) if the grabbed item should always be highlighted." ); +idCVar cv_drag_debug( "tdm_drag_debug", "0", CVAR_GAME | CVAR_BOOL, "Shows debug arrows for desired velocity and contact plane normals when moving objects with the grabber." ); + +idCVar cv_melee_debug( "tdm_melee_debug", "0", CVAR_GAME | CVAR_BOOL, "Enable to show debug melee combat graphics." ); +idCVar cv_melee_state_debug( "tdm_melee_debug_state", "0", CVAR_GAME | CVAR_BOOL, "Enable to display debug text representing AI melee status." ); +// ishtvan: Renamed these with a _ after the name to force their new default settings to take effect in release 1.01 +idCVar cv_melee_mouse_thresh( "tdm_melee_mouse_thresh_", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "In manual control mode, sets the mouse movement threshold needed to decide on which attack/parry to make" ); +idCVar cv_melee_mouse_decision_time( "tdm_melee_mouse_decision_time_", "100", CVAR_GAME | CVAR_INTEGER, "In manual control mode, holding the button for this many milliseconds, an attack/parry decision is made based on mouse motion, even if it is below threshold mouse motion." ); +idCVar cv_melee_mouse_dead_time( "tdm_melee_mouse_dead_time_", "120", CVAR_GAME | CVAR_INTEGER, "Controls how long after the button press that mouse motion is damped by the fraction in tdm_mouse_slowview. In milliseconds." ); +idCVar cv_melee_mouse_slowview( "tdm_melee_mouse_slowview_", "0.0", CVAR_GAME | CVAR_FLOAT, "In manual control mode, when attack/parry button is held down, the view turn rate is decreased to this fraction while the mouse motion is determining which attack/parry to make." ); +idCVar cv_melee_invert_attack( "tdm_melee_invert_attack", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, mouse motions are inverted when controlling which attack to make." ); +idCVar cv_melee_invert_parry( "tdm_melee_invert_parry", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, mouse motions are inverted when controlling which parry to make." ); +idCVar cv_melee_auto_parry( "tdm_melee_auto_parry", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, melee parries are chosen automatically to match the enemy's attack (manual parry mode is much harder)." ); +idCVar cv_melee_forbid_auto_parry( "tdm_melee_forbid_auto_parry", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1, auto parry is forced to be off. Only manual allowed. Works in conjunction with the main menu, do not adjust by hand." ); +idCVar cv_melee_max_particles( "tdm_melee_max_particles", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Max number of particles a single melee swing can generate (eye candy setting)." ); +idCVar cv_melee_difficulty( "tdm_melee_difficulty", "normal", CVAR_GAME | CVAR_ARCHIVE, "Melee difficulty as set by the menu (Do not adjust ingame, cheater!!)" ); + +idCVar cv_phys_show_momentum( "tdm_phys_show_momentum", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set this to 1 (=TRUE) to draw the linear impulse of (some) entities." ); + +/** +* DarkMod Item Manipulation +* Throw_min and throw_max are the min and max impulses applied to items thrown +**/ +idCVar cv_throw_min( "tdm_throw_min", "600", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Minimum impulse applied to a thrown object." ); +idCVar cv_throw_max( "tdm_throw_max", "3500", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum impulse applied to a thrown object." ); +idCVar cv_throw_time( "tdm_throw_time", "1200", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "When throwing an object, time it takes to charge up to the max throw force in milliseconds." ); +idCVar cv_throw_max_vel( "tdm_throw_max_vel", "900", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Velocity of thrown objects is clamped to this value (in doomunits / second). Needed to balance throwing of very light objects." ); + +idCVar cv_bounce_sound_max_vel( "tdm_bounce_sound_max_vel", "400", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "At this velocity moveable collision sounds reach their maximum volume." ); +idCVar cv_bounce_sound_min_vel( "tdm_bounce_sound_min_vel", "80", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the minimum velocity at which moveable collision sounds can be heard at all." ); + + +idCVar cv_reverse_grab_control( "tdm_grabber_reverse_control", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Set to 1 to reverse the direction when using next/prev weapon to increase/decrease the distance of the grabbed item." ); + +/** +* DarkMod Inventory +**/ +idCVar cv_tdm_inv_gui_file( "tdm_inv_hud_file", "guis/tdm_inv.gui", CVAR_GAME, "The name of the gui file that represents the hud for the inventory."); +idCVar cv_tdm_inv_loot_item_def("tdm_inv_loot_item_def", "atdm:inv_loot_info_item", CVAR_GAME, "The name of the entityDef that defines the player's inventory loot item."); + +idCVar cv_tdm_obj_gui_file( "tdm_obj_hud_file", "guis/tdm_objectives.gui", CVAR_GAME, "The name of the gui file that defines the in-game objectives."); +idCVar cv_tdm_waituntilready_gui_file( "tdm_waituntilready_gui_file", "guis/tdm_waituntilready.gui", CVAR_GAME, "The name of the gui file that is displayed after loading a map and before starting the gameplay action."); + +idCVar cv_tdm_hud_opacity( "tdm_hud_opacity", "0.7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The opacity of the HUD GUIs. [0..1]", 0, 1 ); +idCVar cv_tdm_hud_hide_lightgem( "tdm_hud_hide_lightgem", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If set to true (=1), the lightgem will be hidden.", 0, 1 ); +idCVar cv_tdm_inv_hud_pickupmessages( "tdm_inv_hud_pickupmessages", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If set to 1, the HUD is displaying the item the player has just picked up."); +idCVar cv_tdm_inv_loot_sound("tdm_inv_loot_sound", "frob_loot", CVAR_GAME | CVAR_ARCHIVE, "The name of the sound that is to be played when loot has been acquired."); +idCVar cv_tdm_inv_use_on_frob("tdm_inv_use_on_frob", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "When set to '1' currently selected inventory items will be used on frob."); +idCVar cv_tdm_door_control("tdm_door_control", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Acivates experimental door control. When active, hold down frob and move mouse to fine-control a door."); +idCVar cv_tdm_door_control_sensitivity( "tdm_door_control_sensitivity", "0.01", CVAR_GAME | CVAR_FLOAT, "Sets fine door control mouse sensitivity." ); +idCVar cv_tdm_inv_use_visual_feedback("tdm_inv_use_visual_feedback", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "When set to '1' the HUD is giving visual feedback when the currently selected item is used on the highlighted one."); + + +idCVar cv_tdm_rope_pull_force_factor("tdm_rope_pull_force_factor", "140", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The factor by which the pulling force when jumping on a rope gets multiplied."); + +idCVar cv_tdm_underwater_blur("tdm_underwater_blur", "3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The strength of the blur effect when the player is underwater."); + +/** +* DarkMod movement volumes. Walking volume is zero dB, other volumes are added to that +**/ +idCVar cv_pm_stepvol_walk( "pm_stepvol_walk", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for walking footsteps (should be 0.0)" ); +idCVar cv_pm_stepvol_run( "pm_stepvol_run", "8", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible modifier for running footsteps." ); +idCVar cv_pm_stepvol_creep( "pm_stepvol_creep", "-5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible modifier for creeping footsteps." ); + +idCVar cv_pm_stepvol_crouch_walk( "pm_stepvol_crouch_walk", "-2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch walking footsteps" ); +idCVar cv_pm_stepvol_crouch_run( "pm_stepvol_crouch_run", "4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch running footsteps" ); +idCVar cv_pm_stepvol_crouch_creep( "pm_stepvol_crouch_creep", "-7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch creeping footsteps" ); +idCVar cv_pm_min_stepsound_interval("pm_min_stepsound_interval", "200", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The minimum time in msec which has to pass before the next player footstep sound is allowed to be played." ); +idCVar cv_pm_rope_snd_rep_dist( "pm_rope_snd_rep_dist", "32", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "When climbing a rope, this sets the vertical distance in doomunits between repeats of the rope climbing sound (default 32 [du])." ); +idCVar cv_pm_rope_velocity_letgo( "pm_rope_velocity_letgo", "100", CVAR_GAME | CVAR_FLOAT, "Maximum allowed velocity of the rope before the player lets go." ); +idCVar cv_pm_rope_swing_impulse( "pm_rope_swing_impulse", "360000", CVAR_GAME | CVAR_FLOAT, "Impulse applied to rope when the player 'kicks their legs' to swing on the rope. (Warning: Setting too high can damage player)" ); +idCVar cv_pm_rope_swing_reptime( "pm_rope_swing_reptime", "500", CVAR_GAME | CVAR_INTEGER, "How often you can kick to swing on the rope, in milliseconds." ); +idCVar cv_pm_rope_swing_kickdist( "pm_rope_swing_kickdist", "36", CVAR_GAME | CVAR_FLOAT, "When kicking on a rope, check this far ahead of the player's anchor point in the kick direction, to see if they are kicking off of something." ); +idCVar cv_pm_water_downwards_velocity( "pm_water_downwards_velocity", "-4", CVAR_GAME | CVAR_FLOAT, "The factor which the gravity vector gets scaled with to calculate the standard downwards velocity in water volumes. Negative values will let the player float upwards." ); +idCVar cv_pm_water_z_friction( "pm_water_z_friction", "0.995", CVAR_GAME | CVAR_FLOAT , "When the player is underwater and has really small z-velocities, this factor gets applied each frame, so that the player stops floating upwards when reaching the surface." ); +idCVar cv_pm_show_waterlevel( "pm_show_waterlevel", "0", CVAR_GAME | CVAR_BOOL , "Shows the waterlevel of the player." ); +idCVar cv_pm_climb_distance( "pm_climb_distance", "10", CVAR_GAME | CVAR_FLOAT , "How far away the edge of the player clipbox is from climbed surfaces (e.g. ladders)" ); + +/** + * Darkmod lightgem variables. These are only for debuggingpurpose to tweak the lightgem + * in a release version they should be disabled. + */ +idCVar cv_lg_distance("tdm_lg_distance", "0", CVAR_GAME | CVAR_FLOAT, "Sets the distance for camera of the lightgem testmodel." ); +idCVar cv_lg_xoffs("tdm_lg_xoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the x adjustment value for the camera on the testmodel" ); +idCVar cv_lg_yoffs("tdm_lg_yoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the y adjustment value for the camera on the testmodel" ); +idCVar cv_lg_zoffs("tdm_lg_zoffs", "17", CVAR_GAME | CVAR_FLOAT, "Sets the z adjustment value for the camera on the testmodel" ); +idCVar cv_lg_oxoffs("tdm_lg_oxoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the x adjustment value for the testmodels object position" ); +idCVar cv_lg_oyoffs("tdm_lg_oyoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the y adjustment value for the testmodels object position" ); +idCVar cv_lg_ozoffs("tdm_lg_ozoffs", "-20", CVAR_GAME | CVAR_FLOAT, "Sets the z adjustment value for the testmodels object position" ); +idCVar cv_lg_fov("tdm_lg_fov", "70", CVAR_GAME | CVAR_INTEGER, "Sets the y value for the field of view on the lightgem testmodel." ); +idCVar cv_lg_interleave("tdm_lg_interleave", "1", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "If set to 0 no lightgem processing is done. Any other values determines how often the lightgem should be processed.\n1 (default) means to process every frame." ); +idCVar cv_lg_hud("tdm_lg_hud", "0", CVAR_GAME | CVAR_INTEGER, "Shows the rendersnaphost n = <1..6> of the lightgem on-screen. If 0 none is shown." ); +idCVar cv_lg_weak("tdm_lg_weak", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Switches to the weaker algorithm, but may be faster." ); + +idCVar cv_lg_player("tdm_lg_player", "0", CVAR_GAME | CVAR_BOOL, "Shows the lightem testmodel in the gamescreen if set to 1." ); +idCVar cv_lg_renderpasses("tdm_lg_renderpasses", "2", CVAR_GAME | CVAR_INTEGER, "Set number of renderpasses used for the lightgem calculation (1..2)" ); +idCVar cv_lg_debug("tdm_lg_debug", "0", CVAR_GAME | CVAR_BOOL, "switch on debug prints." ); +idCVar cv_lg_model("tdm_lg_model", "models/darkmod/misc/system/lightgem.lwo", CVAR_GAME | CVAR_ARCHIVE, "Set the lightgem model file. Map has to be restarted to take effect." ); +idCVar cv_lg_adjust("tdm_lg_adjust", "0", CVAR_GAME | CVAR_FLOAT, "Adds a constant value to the lightgem." ); +idCVar cv_lg_split("tdm_lg_split", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Lightgem is always fully calculated (no splitting between interleaves). Warning! This can cause particle flickering if set to 1." ); +idCVar cv_lg_path("tdm_lg_path", "", CVAR_GAME, "Dump the rendersnapshot to the filepath specified here." ); +idCVar cv_lg_crouch_modifier("tdm_lg_crouch_modifier", "-2", CVAR_GAME | CVAR_INTEGER, "The value the lightgem is adjusted by when the player is crouching." ); +idCVar cv_lg_image_width("tdm_lg_image_width", "64", CVAR_GAME | CVAR_INTEGER, "Defines the pixel width of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); +idCVar cv_lg_screen_width("tdm_lg_screen_width", "640", CVAR_GAME | CVAR_INTEGER, "Defines the screen width of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); +idCVar cv_lg_screen_height("tdm_lg_screen_height", "480", CVAR_GAME | CVAR_INTEGER, "Defines the screen height of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); +idCVar cv_lg_velocity_mod_min_velocity("tdm_lg_velocity_mod_min_velocity", "0", CVAR_GAME | CVAR_FLOAT, "The minimum velocity the player must be at to make the lightgem level increase."); +idCVar cv_lg_velocity_mod_max_velocity("tdm_lg_velocity_mod_max_velocity", "300", CVAR_GAME | CVAR_FLOAT, "The maximum player speed taken into account for the lightgem."); +idCVar cv_lg_velocity_mod_amount("tdm_lg_velocity_mod_amount", "1", CVAR_GAME | CVAR_FLOAT, "The maximum light level increase factor due to player velocity (this will be multiplied when the player velocity is >= tdm_lg_player_velocity_mod_max)."); + +idCVar cv_lg_fade_delay ("tdm_lg_fade_delay", "0.09", CVAR_GAME | CVAR_FLOAT, "lightgem fade time from previous value to new value in seconds." ); // J.C.Denton + +idCVar cv_empty_model("tdm_empty_model", "models/darkmod/misc/system/empty.lwo", CVAR_GAME | CVAR_ARCHIVE, "The empty model referenced by the 'waitForRender' script event."); + +// Proxy CVARs +idCVar cv_tdm_s_doorDistanceAdd("tdm_s_doorDistanceAdd", "450", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite s_doorDistanceAdd at game startup."); +idCVar cv_tdm_gui_smallFontLimit("tdm_gui_smallFontLimit", "0.15", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite gui_smallFontLimit at game startup."); +idCVar cv_tdm_gui_mediumFontLimit("tdm_gui_mediumFontLimit", "0.30", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite gui_mediumFontLimit at game startup."); +idCVar cv_tdm_s_maxSoundsPerShader("tdm_s_maxSoundsPerShader", "0", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite s_maxSoundsPerShader at game startup (unless this set to -1)."); + +/** + * Variables needed for lockpicking. + */ +idCVar cv_lp_pin_base_count("tdm_lp_base_count", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Base number of clicks per pin. This number will be added to the pinpattern." ); +idCVar cv_lp_sample_delay("tdm_lp_sample_delay", "10", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Time in ms added to each pin sample to create a small pause between each pinsample." ); +idCVar cv_lp_pick_timeout("tdm_lp_pick_timeout", "500", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Timeout that defines the maximum reaction time before the pin is to be considered unpicked and started over." ); +idCVar cv_lp_max_pick_attempts("tdm_lp_autopick_attempts", "3", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "How many pick attemps before it automatically gets picked? 0 = unlimited (you must solve it yourself)" ); +idCVar cv_lp_auto_pick("tdm_lp_auto_pick", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Determines if auto picking is enabled (see tdm_lp_max_pick_attempts)" ); +idCVar cv_lp_randomize("tdm_lp_randomize", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1, the jiggling, while lockpicking, will be randomized, otherwise it is linear." ); +idCVar cv_lp_pawlow("tdm_lp_pawlow", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 the sweetspot sound will play at the end of the pattern instead of at the beginning. Thus making it into a reaction game." ); +idCVar cv_lp_debug_hud("tdm_lp_debug_hud", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 the lockpicking debug HUD is shown during lockpicking." ); + +/** + * Variable for bow aimer. -- Dram + */ +idCVar cv_bow_aimer("tdm_bow_aimer", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Whether the bow has an aimer. 0 = False, 1 = True." ); + +idCVar cv_door_auto_open_on_unlock("tdm_door_auto_open_on_unlock", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 doors and chests will start to open after being unlocked." ); + +idCVar cv_dm_distance("tdm_distance", "", CVAR_GAME, "Shows the distance from the player to the entity" ); + +/** + * Ambient light method variable + */ +idCVar cv_ambient_method("tdm_ambient_method", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Method used for ambient light rendering.\n\n0 = Ambient Light method (uses the ambient light for the ambient brightness) \n1 = Texture Brightness method (uses texture brightness instead of light. This is faster but looks worse)" ); + +/** + * Volume of speakers with s_music set + */ +idCVar cv_music_volume("tdm_music_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for speakers with s_music set. Goes from -40 to 0." ); + +// Tels: +idCVar cv_voice_player_volume("tdm_voice_player_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for the player voice speaker. Goes from 0 .. 60." ); +idCVar cv_voice_from_off_volume("tdm_voice_from_off_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for the voice-over speaker. Goes from 0 .. 60." ); + +idCVar cv_moveable_collision("tdm_show_moveable_collision", "0", CVAR_GAME | CVAR_BOOL, "If set to 1, shows the velocity at which the moveable collides and the volume of the resulting sound." ); + +/** +* DarkMod LOD system +**/ +idCVar cv_lod_bias("tdm_lod_bias", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "A factor to multiply the LOD (level of detail) distance with. Default is 1.0 (meaning no change). Values < 1.0 make the distances smaller, reducing detail and increasing framerate, values > 1 increase the distance and thus detail at the expense of framerate." ); + +/** +* End DarkMod cvars +**/ + +// noset vars +idCVar gamename( "gamename", GAME_VERSION, CVAR_GAME | CVAR_SERVERINFO | CVAR_ROM, "" ); +idCVar gamedate( "gamedate", __DATE__, CVAR_GAME | CVAR_ROM, "" ); + +// server info +idCVar si_name( "si_name", "DOOM Server", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "name of the server" ); +idCVar si_gameType( "si_gameType", si_gameTypeArgs[ 0 ], CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "game type - singleplayer, deathmatch, Tourney, Team DM or Last Man", si_gameTypeArgs, idCmdSystem::ArgCompletion_String ); +idCVar si_map( "si_map", "game/mp/d3dm1",CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "map to be played next on server", idCmdSystem::ArgCompletion_MapName ); +idCVar si_maxPlayers( "si_maxPlayers", "4", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "max number of players allowed on the server", 1, 4 ); +idCVar si_fragLimit( "si_fragLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "frag limit", 1, MP_PLAYER_MAXFRAGS ); +idCVar si_timeLimit( "si_timeLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "time limit in minutes", 0, 60 ); +idCVar si_teamDamage( "si_teamDamage", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable team damage" ); +idCVar si_warmup( "si_warmup", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "do pre-game warmup" ); +idCVar si_usePass( "si_usePass", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable client password checking" ); +idCVar si_pure( "si_pure", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_BOOL, "server is pure and does not allow modified data" ); +idCVar si_spectators( "si_spectators", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "allow spectators or require all clients to play" ); +idCVar si_serverURL( "si_serverURL", "", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "where to reach the server admins and get information about the server" ); + + +// user info +idCVar ui_name( "ui_name", "Player", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player name" ); +idCVar ui_skin( "ui_skin", ui_skinArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player skin", ui_skinArgs, idCmdSystem::ArgCompletion_String ); +idCVar ui_team( "ui_team", ui_teamArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player team", ui_teamArgs, idCmdSystem::ArgCompletion_String ); +idCVar ui_autoSwitch( "ui_autoSwitch", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto switch weapon" ); +idCVar ui_autoReload( "ui_autoReload", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto reload weapon" ); +idCVar ui_showGun( "ui_showGun", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "show gun" ); +idCVar ui_ready( "ui_ready", si_readyArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "player is ready to start playing", idCmdSystem::ArgCompletion_String ); +idCVar ui_spectate( "ui_spectate", si_spectateArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "play or spectate", idCmdSystem::ArgCompletion_String ); +idCVar ui_chat( "ui_chat", "0", CVAR_GAME | CVAR_USERINFO | CVAR_BOOL | CVAR_ROM | CVAR_CHEAT, "player is chatting" ); + +// change anytime vars +idCVar developer( "developer", "0", CVAR_GAME | CVAR_BOOL, "" ); + +idCVar r_aspectRatio( "r_aspectRatio", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE, "Aspect ratio of view, determines the ratio between FOV for x and y. Only used if r_fovRatio is 0:\n0 = 4:3\n1 = 16:9\n2 = 16:10\n3 = 5:4\n16:9 TV", 0, 4 ); + +idCVar cv_r_fovRatio( "r_fovRatio", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Aspect ratio of view, if set to greater than 0, determines the ratio between FOV for x and y directly, and r_aspectRatio is ignored. The value should closely match r_customWidth / r_customHeight." ); + +idCVar cv_gui_Width( "gui_Width", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Size of the GUI as factor of the screen width. Default is 1.0 and stretches the GUI over the entire screen." ); +idCVar cv_gui_Height( "gui_Height", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Size of the GUI as factor of the screen height. Default is 1.0 and stretches the GUI over the entire screen." ); +idCVar cv_gui_CenterX( "gui_CenterX", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Position of the center of the GUI as percentage of the whole screen width. Default is 0.5 (half of the screen width)." ); +idCVar cv_gui_CenterY( "gui_CenterY", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Position of the center of the GUI as percentage of the whole screen height. Default is 0.5 (half of the screen height)." ); + +idCVar g_cinematic( "g_cinematic", "1", CVAR_GAME | CVAR_BOOL, "skips updating entities that aren't marked 'cinematic' '1' during cinematics" ); +idCVar g_cinematicMaxSkipTime( "g_cinematicMaxSkipTime", "600", CVAR_GAME | CVAR_FLOAT, "# of seconds to allow game to run when skipping cinematic. prevents lock-up when cinematic doesn't end.", 0, 3600 ); + +idCVar g_muzzleFlash( "g_muzzleFlash", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show muzzle flashes" ); +idCVar g_projectileLights( "g_projectileLights", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show dynamic lights on projectiles" ); +idCVar g_bloodEffects( "g_bloodEffects", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show blood splats, sprays and gibs" ); +idCVar g_doubleVision( "g_doubleVision", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show double vision when taking damage" ); +idCVar g_monsters( "g_monsters", "1", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_decals( "g_decals", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show decals such as bullet holes" ); +idCVar g_knockback( "g_knockback", "1000", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar g_skill( "g_skill", "1", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar g_nightmare( "g_nightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed" ); +idCVar g_gravity( "g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_skipFX( "g_skipFX", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_skipParticles( "g_skipParticles", "0", CVAR_GAME | CVAR_BOOL, "" ); + +idCVar g_disasm( "g_disasm", "0", CVAR_GAME | CVAR_BOOL, "disassemble script into base/script/disasm.txt on the local drive when script is compiled" ); +idCVar g_debugBounds( "g_debugBounds", "0", CVAR_GAME | CVAR_BOOL, "checks for models with bounds > 2048" ); +idCVar g_debugAnim( "g_debugAnim", "-1", CVAR_GAME | CVAR_INTEGER, "displays information on which animations are playing on the specified entity number. set to -1 to disable." ); +idCVar g_debugMove( "g_debugMove", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugDamage( "g_debugDamage", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugWeapon( "g_debugWeapon", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugScript( "g_debugScript", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugMover( "g_debugMover", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugTriggers( "g_debugTriggers", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_debugCinematic( "g_debugCinematic", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_stopTime( "g_stopTime", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_damageScale( "g_damageScale", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "scale final damage on player by this factor" ); +idCVar g_armorProtection( "g_armorProtection", "0.3", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" ); +idCVar g_armorProtectionMP( "g_armorProtectionMP", "0.6", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" ); +idCVar g_useDynamicProtection( "g_useDynamicProtection", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "scale damage and armor dynamically to keep the player alive more often" ); +idCVar g_healthTakeTime( "g_healthTakeTime", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how often to take health in nightmare mode" ); +idCVar g_healthTakeAmt( "g_healthTakeAmt", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how much health to take in nightmare mode" ); +idCVar g_healthTakeLimit( "g_healthTakeLimit", "25", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how low can health get taken in nightmare mode" ); + + + +idCVar g_showPVS( "g_showPVS", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 2 ); +idCVar g_showTargets( "g_showTargets", "0", CVAR_GAME | CVAR_BOOL, "draws entities and thier targets. hidden entities are drawn grey." ); +idCVar g_showTriggers( "g_showTriggers", "0", CVAR_GAME | CVAR_BOOL, "draws trigger entities (orange) and thier targets (green). disabled triggers are drawn grey." ); +idCVar g_showCollisionWorld( "g_showCollisionWorld", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_showCollisionModels( "g_showCollisionModels", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_showCollisionTraces( "g_showCollisionTraces", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_maxShowDistance( "g_maxShowDistance", "128", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_showEntityInfo( "g_showEntityInfo", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_showviewpos( "g_showviewpos", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_showcamerainfo( "g_showcamerainfo", "0", CVAR_GAME | CVAR_ARCHIVE, "displays the current frame # for the camera when playing cinematics" ); +idCVar g_showTestModelFrame( "g_showTestModelFrame", "0", CVAR_GAME | CVAR_BOOL, "displays the current animation and frame # for testmodels" ); +idCVar g_showActiveEntities( "g_showActiveEntities", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around thinking entities. dormant entities (outside of pvs) are drawn yellow. non-dormant are green." ); +idCVar g_showEnemies( "g_showEnemies", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around monsters that have targeted the the player" ); + +idCVar g_frametime( "g_frametime", "0", CVAR_GAME | CVAR_BOOL, "displays timing information for each game frame" ); + +// TDM: greebo: Use this to stretch the hardcoded 16 msec each frame takes. This can be used to let the game run ultra-slow. +idCVar g_timeModifier( "g_timeModifier", "1", CVAR_GAME | CVAR_FLOAT, "Use this to stretch the hardcoded 16 msec each frame takes. This can be used to let the game run ultra-slow." ); +idCVar g_timeentities( "g_timeEntities", "0", CVAR_GAME | CVAR_FLOAT, "when non-zero, shows entities whose think functions exceeded the # of milliseconds specified" ); + + +idCVar g_enablePortalSky( "g_enablePortalSky", "1", CVAR_GAME | CVAR_BOOL, "enables the portal sky" ); + + +idCVar ai_debugScript( "ai_debugScript", "-1", CVAR_GAME | CVAR_INTEGER, "displays script calls for the specified monster entity number" ); +idCVar ai_debugMove( "ai_debugMove", "0", CVAR_GAME | CVAR_BOOL, "draws movement information for monsters" ); +idCVar ai_debugTrajectory( "ai_debugTrajectory", "0", CVAR_GAME | CVAR_BOOL, "draws trajectory tests for monsters" ); +idCVar ai_testPredictPath( "ai_testPredictPath", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar ai_showCombatNodes( "ai_showCombatNodes", "0", CVAR_GAME | CVAR_BOOL, "draws attack cones for monsters" ); +idCVar ai_showPaths( "ai_showPaths", "0", CVAR_GAME | CVAR_BOOL, "draws path_* entities" ); +idCVar ai_showObstacleAvoidance( "ai_showObstacleAvoidance", "0", CVAR_GAME | CVAR_INTEGER, "draws obstacle avoidance information for monsters. if 2, draws obstacles for player, as well", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar ai_blockedFailSafe( "ai_blockedFailSafe", "1", CVAR_GAME | CVAR_BOOL, "enable blocked fail safe handling" ); + +idCVar g_dvTime( "g_dvTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_dvAmplitude( "g_dvAmplitude", "0.001", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_dvFrequency( "g_dvFrequency", "0.5", CVAR_GAME | CVAR_FLOAT, "" ); + +idCVar g_kickTime( "g_kickTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_kickAmplitude( "g_kickAmplitude", "0.0001", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_blobTime( "g_blobTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_blobSize( "g_blobSize", "1", CVAR_GAME | CVAR_FLOAT, "" ); + +idCVar g_testHealthVision( "g_testHealthVision", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_editEntityMode( "g_editEntityMode", "0", CVAR_GAME | CVAR_INTEGER, "0 = off\n" + "1 = lights\n" + "2 = sounds\n" + "3 = articulated figures\n" + "4 = particle systems\n" + "5 = monsters\n" + "6 = entity names\n" + "7 = entity models", 0, 7, idCmdSystem::ArgCompletion_Integer<0,7> ); +idCVar g_dragEntity( "g_dragEntity", "0", CVAR_GAME | CVAR_BOOL, "allows dragging physics objects around by placing the crosshair over them and holding the fire button" ); +idCVar g_dragDamping( "g_dragDamping", "0.5", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_dragShowSelection( "g_dragShowSelection", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_dropItemRotation( "g_dropItemRotation", "", CVAR_GAME, "" ); + +idCVar g_vehicleVelocity( "g_vehicleVelocity", "1000", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleForce( "g_vehicleForce", "50000", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleSuspensionUp( "g_vehicleSuspensionUp", "32", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleSuspensionDown( "g_vehicleSuspensionDown", "20", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleSuspensionKCompress("g_vehicleSuspensionKCompress","200", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleSuspensionDamping( "g_vehicleSuspensionDamping","400", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_vehicleTireFriction( "g_vehicleTireFriction", "0.8", CVAR_GAME | CVAR_FLOAT, "" ); + +idCVar ik_enable( "ik_enable", "1", CVAR_GAME | CVAR_BOOL, "enable IK" ); +idCVar ik_debug( "ik_debug", "0", CVAR_GAME | CVAR_BOOL, "show IK debug lines" ); + +idCVar af_useLinearTime( "af_useLinearTime", "1", CVAR_GAME | CVAR_BOOL, "use linear time algorithm for tree-like structures" ); +idCVar af_useImpulseFriction( "af_useImpulseFriction", "0", CVAR_GAME | CVAR_BOOL, "use impulse based contact friction" ); +idCVar af_useJointImpulseFriction( "af_useJointImpulseFriction","0", CVAR_GAME | CVAR_BOOL, "use impulse based joint friction" ); +idCVar af_useSymmetry( "af_useSymmetry", "1", CVAR_GAME | CVAR_BOOL, "use constraint matrix symmetry" ); +#ifdef MOD_WATERPHYSICS + +idCVar af_useBodyDensityBuoyancy( "af_useBodyDensityBuoyancy","0", CVAR_GAME | CVAR_BOOL, "uses density of each body to calculate buoyancy"); // MOD_WATERPHYSICS + +idCVar af_useFixedDensityBuoyancy( "af_useFixedDensityBuoyancy","1", CVAR_GAME | CVAR_BOOL, "if set, use liquidDensity as a fixed density for each body when calculating buoyancy. If clear, bodies are floated uniformly by a scalar liquidDensity as defined in the decls." ); // MOD_WATERPHYSICS + +#endif // MOD_WATERPHYSICS + +idCVar af_skipSelfCollision( "af_skipSelfCollision", "0", CVAR_GAME | CVAR_BOOL, "skip self collision detection" ); +idCVar af_skipLimits( "af_skipLimits", "0", CVAR_GAME | CVAR_BOOL, "skip joint limits" ); +idCVar af_skipFriction( "af_skipFriction", "0", CVAR_GAME | CVAR_BOOL, "skip friction" ); +idCVar af_forceFriction( "af_forceFriction", "-1", CVAR_GAME | CVAR_FLOAT, "force the given friction value" ); +idCVar af_maxLinearVelocity( "af_maxLinearVelocity", "128", CVAR_GAME | CVAR_FLOAT, "maximum linear velocity" ); +idCVar af_maxAngularVelocity( "af_maxAngularVelocity", "1.57", CVAR_GAME | CVAR_FLOAT, "maximum angular velocity" ); +idCVar af_timeScale( "af_timeScale", "1", CVAR_GAME | CVAR_FLOAT, "scales the time" ); +idCVar af_jointFrictionScale( "af_jointFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the joint friction" ); +idCVar af_contactFrictionScale( "af_contactFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the contact friction" ); +idCVar af_highlightBody( "af_highlightBody", "", CVAR_GAME, "name of the body to highlight" ); +idCVar af_highlightConstraint( "af_highlightConstraint", "", CVAR_GAME, "name of the constraint to highlight" ); +idCVar af_showTimings( "af_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show articulated figure cpu usage" ); +idCVar af_showConstraints( "af_showConstraints", "0", CVAR_GAME | CVAR_BOOL, "show constraints" ); +idCVar af_showConstraintNames( "af_showConstraintNames", "0", CVAR_GAME | CVAR_BOOL, "show constraint names" ); +idCVar af_showConstrainedBodies( "af_showConstrainedBodies", "0", CVAR_GAME | CVAR_BOOL, "show the two bodies contrained by the highlighted constraint" ); +idCVar af_showPrimaryOnly( "af_showPrimaryOnly", "0", CVAR_GAME | CVAR_BOOL, "show primary constraints only" ); +idCVar af_showTrees( "af_showTrees", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures" ); +idCVar af_showLimits( "af_showLimits", "0", CVAR_GAME | CVAR_BOOL, "show joint limits" ); +idCVar af_showBodies( "af_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show bodies" ); +idCVar af_showBodyNames( "af_showBodyNames", "0", CVAR_GAME | CVAR_BOOL, "show body names" ); +idCVar af_showMass( "af_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each body" ); +idCVar af_showTotalMass( "af_showTotalMass", "0", CVAR_GAME | CVAR_BOOL, "show the total mass of each articulated figure" ); +idCVar af_showInertia( "af_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each body" ); +idCVar af_showVelocity( "af_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each body" ); +idCVar af_showActive( "af_showActive", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures of articulated figures not at rest" ); +idCVar af_testSolid( "af_testSolid", "1", CVAR_GAME | CVAR_BOOL, "test for bodies initially stuck in solid" ); + +idCVar rb_showTimings( "rb_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show rigid body cpu usage" ); +idCVar rb_showBodies( "rb_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies" ); +idCVar rb_showMass( "rb_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each rigid body" ); +idCVar rb_showInertia( "rb_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each rigid body" ); +idCVar rb_showVelocity( "rb_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each rigid body" ); +idCVar rb_showActive( "rb_showActive", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies that are not at rest" ); +#ifdef MOD_WATERPHYSICS + +idCVar rb_showBuoyancy( "rb_showBuoyancy", "0", CVAR_GAME | CVAR_BOOL, "show rigid body buoyancy information" ); // MOD_WATERPHYSICS + +#endif // MOD_WATERPHYSICS + + +// The default values for player movement cvars are set in def/player.def +idCVar pm_jumpheight( "pm_jumpheight", "48", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "approximate hieght the player can jump" ); +idCVar pm_stepsize( "pm_stepsize", "16", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "maximum height the player can step up without jumping" ); +// replaced by crouch multiplier +//idCVar pm_crouchspeed( "pm_crouchspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while crouched" ); +idCVar pm_walkspeed( "pm_walkspeed", "70", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "speed the player can move while walking" ); +// also replaced by multiplier +//idCVar pm_runspeed( "pm_runspeed", "220", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while running" ); +idCVar pm_noclipspeed( "pm_noclipspeed", "200", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while in noclip" ); +idCVar pm_spectatespeed( "pm_spectatespeed", "450", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while spectating" ); +idCVar pm_spectatebbox( "pm_spectatebbox", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "size of the spectator bounding box" ); +idCVar pm_usecylinder( "pm_usecylinder", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "use a cylinder approximation instead of a bounding box for player collision detection" ); +idCVar pm_minviewpitch( "pm_minviewpitch", "-89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look up (negative values are up)" ); +idCVar pm_maxviewpitch( "pm_maxviewpitch", "89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look down" ); +// Commented out by Dram. Not needed as TDM does not use stamina +//idCVar pm_stamina( "pm_stamina", "24", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "length of time player can run" ); +//idCVar pm_staminathreshold( "pm_staminathreshold", "45", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "when stamina drops below this value, player gradually slows to a walk" ); +//idCVar pm_staminarate( "pm_staminarate", "0.75", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "rate that player regains stamina. divide pm_stamina by this value to determine how long it takes to fully recharge." ); +idCVar pm_crouchheight( "pm_crouchheight", "38", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while crouched" ); +idCVar pm_crouchviewheight( "pm_crouchviewheight", "34", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while crouched" ); +idCVar pm_normalheight( "pm_normalheight", "74", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while standing" ); +idCVar pm_normalviewheight( "pm_normalviewheight", "68", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while standing" ); +idCVar pm_deadheight( "pm_deadheight", "20", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while dead" ); +idCVar pm_deadviewheight( "pm_deadviewheight", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while dead" ); +idCVar pm_crouchrate( "pm_crouchrate", "0.87", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "time it takes for player's view to change from standing to crouching" ); +idCVar pm_bboxwidth( "pm_bboxwidth", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "x/y size of player's bounding box" ); +idCVar pm_crouchbob( "pm_crouchbob", "0.2", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob much faster when crouched" ); +idCVar pm_walkbob( "pm_walkbob", "0.3", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking" ); +idCVar pm_runbob( "pm_runbob", "0.35", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob faster when running" ); +idCVar pm_runpitch( "pm_runpitch", "0.001", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); +idCVar pm_runroll( "pm_runroll", "0.003", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); +idCVar pm_bobup( "pm_bobup", "0.035", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); +idCVar pm_bobpitch( "pm_bobpitch", "0.001", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); +idCVar pm_bobroll( "pm_bobroll", "0.0015", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); +idCVar pm_thirdPersonRange( "pm_thirdPersonRange", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "camera distance from player in 3rd person" ); +idCVar pm_thirdPersonHeight( "pm_thirdPersonHeight", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of camera from normal view height in 3rd person" ); +idCVar pm_thirdPersonAngle( "pm_thirdPersonAngle", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "direction of camera from player in 3rd person in degrees (0 = behind player, 180 = in front)" ); +idCVar pm_thirdPersonClip( "pm_thirdPersonClip", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "clip third person view into world space" ); +idCVar pm_thirdPerson( "pm_thirdPerson", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view" ); +idCVar pm_thirdPersonDeath( "pm_thirdPersonDeath", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view when player dies" ); +idCVar pm_modelView( "pm_modelView", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "draws camera from POV of player model (1 = always, 2 = when dead)", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar pm_airTics( "pm_air", "1800", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "how long in milliseconds the player can go without air before he starts taking damage" ); + +idCVar g_showPlayerShadow( "g_showPlayerShadow", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables shadow of player model" ); +idCVar g_showHud( "g_showHud", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "" ); +idCVar g_showProjectilePct( "g_showProjectilePct", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables display of player hit percentage" ); +idCVar g_showBrass( "g_showBrass", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables ejected shells from weapon" ); +idCVar g_gun_x( "g_gunX", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_viewNodalX( "g_viewNodalX", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_viewNodalZ( "g_viewNodalZ", "0", CVAR_GAME | CVAR_FLOAT, "" ); +idCVar g_fov( "g_fov", "90", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "" ); +idCVar g_skipViewEffects( "g_skipViewEffects", "0", CVAR_GAME | CVAR_BOOL, "skip damage and other view effects" ); +idCVar g_mpWeaponAngleScale( "g_mpWeaponAngleScale", "0", CVAR_GAME | CVAR_FLOAT, "Control the weapon sway in MP" ); + +idCVar g_testParticle( "g_testParticle", "0", CVAR_GAME | CVAR_INTEGER, "test particle visualation, set by the particle editor" ); +idCVar g_testParticleName( "g_testParticleName", "", CVAR_GAME, "name of the particle being tested by the particle editor" ); +idCVar g_testModelHead( "g_testModelHead", "atdm:ai_head_citywatch", CVAR_GAME | CVAR_ARCHIVE, "test model head entityDef" ); +idCVar g_testModelHeadJoint( "g_testModelHeadJoint", "Spine2", CVAR_GAME | CVAR_ARCHIVE, "test model head joint" ); +idCVar g_testModelRotate( "g_testModelRotate", "0", CVAR_GAME, "test model rotation speed" ); +idCVar g_testPostProcess( "g_testPostProcess", "", CVAR_GAME, "name of material to draw over screen" ); +idCVar g_testModelAnimate( "g_testModelAnimate", "0", CVAR_GAME | CVAR_INTEGER, "test model animation,\n" + "0 = cycle anim with origin reset\n" + "1 = cycle anim with fixed origin\n" + "2 = cycle anim with continuous origin\n" + "3 = frame by frame with continuous origin\n" + "4 = play anim once", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> ); +idCVar g_testModelBlend( "g_testModelBlend", "0", CVAR_GAME | CVAR_INTEGER, "number of frames to blend" ); +idCVar g_testDeath( "g_testDeath", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar g_exportMask( "g_exportMask", "", CVAR_GAME, "" ); +idCVar g_flushSave( "g_flushSave", "0", CVAR_GAME | CVAR_BOOL, "1 = don't buffer file writing for save games." ); + +idCVar g_rotoscope( "g_rotoscope", "0", CVAR_GAME | CVAR_BOOL, "Noir cartoon-like rendering" ); + +idCVar aas_test( "aas_test", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_showAreas( "aas_showAreas", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar aas_showPath( "aas_showPath", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_showFlyPath( "aas_showFlyPath", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_showWallEdges( "aas_showWallEdges", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar aas_showHideArea( "aas_showHideArea", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_pullPlayer( "aas_pullPlayer", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_randomPullPlayer( "aas_randomPullPlayer", "0", CVAR_GAME | CVAR_BOOL, "" ); +idCVar aas_goalArea( "aas_goalArea", "0", CVAR_GAME | CVAR_INTEGER, "" ); +idCVar aas_showPushIntoArea( "aas_showPushIntoArea", "0", CVAR_GAME | CVAR_BOOL, "" ); + +idCVar g_password( "g_password", "", CVAR_GAME | CVAR_ARCHIVE, "game password" ); +idCVar password( "password", "", CVAR_GAME | CVAR_NOCHEAT, "client password used when connecting" ); + +idCVar g_countDown( "g_countDown", "10", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "pregame countdown in seconds", 4, 3600 ); +idCVar g_gameReviewPause( "g_gameReviewPause", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "scores review time in seconds (at end game)", 2, 3600 ); +idCVar g_TDMArrows( "g_TDMArrows", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "draw arrows over teammates in team deathmatch" ); +idCVar g_balanceTDM( "g_balanceTDM", "1", CVAR_GAME | CVAR_BOOL, "maintain even teams" ); + +idCVar net_clientPredictGUI( "net_clientPredictGUI", "1", CVAR_GAME | CVAR_BOOL, "test guis in networking without prediction" ); + +idCVar g_voteFlags( "g_voteFlags", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "vote flags. bit mask of votes not allowed on this server\n" + "bit 0 (+1) restart now\n" + "bit 1 (+2) time limit\n" + "bit 2 (+4) frag limit\n" + "bit 3 (+8) game type\n" + "bit 4 (+16) kick player\n" + "bit 5 (+32) change map\n" + "bit 6 (+64) spectators\n" + "bit 7 (+128) next map" ); +idCVar g_mapCycle( "g_mapCycle", "mapcycle", CVAR_GAME | CVAR_ARCHIVE, "map cycling script for multiplayer games - see mapcycle.scriptcfg" ); + +idCVar mod_validSkins( "mod_validSkins", "skins/characters/player/marine_mp;skins/characters/player/marine_mp_green;skins/characters/player/marine_mp_blue;skins/characters/player/marine_mp_red;skins/characters/player/marine_mp_yellow", CVAR_GAME | CVAR_ARCHIVE, "valid skins for the game" ); +idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" ); + +idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" ); + +idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, seperated by ;" ); + +// bloom related - J.C.Denton + +idCVar r_postprocess_debugMode ( "r_postprocess_debugMode", "0", CVAR_GAME | CVAR_INTEGER, " Shows all the textures generated for postprocessing effects. \n 1: Shows currentRender \n 2: Shows bloom Images \n 3: Shows Cooked Math Data."); +idCVar r_postprocess ( "r_postprocess", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, " Activates bloom ( Requires DX9 compliant Hardware )"); +idCVar r_postprocess_brightPassThreshold ( "r_postprocess_brightPassThreshold", "0.2", CVAR_GAME | CVAR_FLOAT, " Intensities of this value are subtracted from scene render to extract bloom image"); +idCVar r_postprocess_brightPassOffset ( "r_postprocess_brightPassOffset", "2", CVAR_GAME | CVAR_FLOAT, " Bloom image receives smooth fade along a curve from bright to very bright areas based on this variable's value"); +idCVar r_postprocess_colorCurveBias ( "r_postprocess_colorCurveBias", "0.8", CVAR_GAME | CVAR_FLOAT, " Applies Exponential Color Curve to final pass (range 0 to 1), 1 = color curve fully applied , 0= No color curve"); +idCVar r_postprocess_colorCorrection ( "r_postprocess_colorCorrection", "5", CVAR_GAME | CVAR_FLOAT, " Applies an exponential color correction function to final scene "); +idCVar r_postprocess_colorCorrectBias ( "r_postprocess_colorCorrectBias", "0.1", CVAR_GAME | CVAR_FLOAT, " Applies an exponential color correction function to final scene with this bias. \n E.g. value ranges between 0-1. A blend is performed between scene render and color corrected image based on this value "); +idCVar r_postprocess_desaturation ( "r_postprocess_desaturation", "0.05", CVAR_GAME | CVAR_FLOAT, " Desaturates the scene "); +idCVar r_postprocess_sceneExposure ( "r_postprocess_sceneExposure", "0.9", CVAR_GAME | CVAR_FLOAT, " Scene render is linearly scaled up. Try values lower or greater than 1.0"); +idCVar r_postprocess_sceneGamma ( "r_postprocess_sceneGamma", "0.82", CVAR_GAME | CVAR_FLOAT, " Gamma Correction."); +idCVar r_postprocess_bloomIntensity ( "r_postprocess_bloomIntensity", "0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, " Adjusts the Bloom intensity. 0.0 disables the bloom but other postprocessing effects remain unaffected."); +idCVar r_postprocess_bloomKernelSize ( "r_postprocess_bloomKernelSize", "2", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, " Sets Bloom's Kernel size. Smaller is faster, takes less memory. Also, smaller kernel means larger bloom spread. \n 1. Large (2x smaller than current resolution) \n 2. Small (4x smaller than current resolution) " ); +//---------------------------------- + +#ifndef __linux__ +idCVar s_driver("s_driver", "0", CVAR_GUI, "Dummy CVAR introduced by TDM to fix a console warning in Windows. Seems to be missing, but D3's mpmain.gui references this."); +#endif + diff --git a/game/gamesys/SysCvar.h b/game/gamesys/SysCvar.h new file mode 100644 index 000000000..075371c1a --- /dev/null +++ b/game/gamesys/SysCvar.h @@ -0,0 +1,651 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SYS_CVAR_H__ +#define __SYS_CVAR_H__ + +#ifdef __linux__ +#include "../../framework/CVarSystem.h" +#endif + +/** +* DarkMod cvars - See text description in syscvar.cpp for descriptions +**/ +extern idCVar cv_player_spawnclass; +extern idCVar cv_player_waituntilready; + +extern idCVar cv_default_mission_info_file; + +extern idCVar cv_ai_sndvol; +extern idCVar cv_ai_bark_show; +extern idCVar cv_ai_bumpobject_impulse; +extern idCVar cv_ai_sight_prob; +extern idCVar cv_ai_sight_mag; +extern idCVar cv_ai_sightmaxdist; +extern idCVar cv_ai_sightmindist; +extern idCVar cv_ai_tactalert; +extern idCVar cv_ai_task_show; +extern idCVar cv_ai_alertlevel_show; +extern idCVar cv_ai_dest_show; +extern idCVar cv_ai_goalpos_show; +extern idCVar cv_ai_aasarea_show; +extern idCVar cv_ai_debug_blocked; +extern idCVar cv_ai_door_show; +extern idCVar cv_ai_elevator_show; +extern idCVar cv_ai_debug; +extern idCVar cv_ai_sight_thresh; +extern idCVar cv_ai_sight_scale; +extern idCVar cv_ai_show_enemy_visibility; +extern idCVar cv_ai_show_conversationstate; +extern idCVar cv_ai_acuity_L3; +extern idCVar cv_ai_acuity_L4; +extern idCVar cv_ai_acuity_L5; +extern idCVar cv_ai_acuity_susp; +extern idCVar cv_ai_visdist_show; +extern idCVar cv_ai_opt_disable; +extern idCVar cv_ai_opt_noanims; +extern idCVar cv_ai_opt_novisualscan; +extern idCVar cv_ai_opt_forceopt; +extern idCVar cv_ai_opt_nothink; +extern idCVar cv_ai_opt_interleavethinkmindist; +extern idCVar cv_ai_opt_interleavethinkmaxdist; +extern idCVar cv_ai_opt_interleavethinkskippvscheck; +extern idCVar cv_ai_opt_interleavethinkframes; +extern idCVar cv_ai_opt_update_enemypos_interleave; +extern idCVar cv_ai_opt_nomind; +extern idCVar cv_ai_opt_novisualstim; +extern idCVar cv_ai_opt_nolipsync; +extern idCVar cv_ai_opt_nopresent; +extern idCVar cv_ai_opt_noobstacleavoidance; +extern idCVar cv_ai_hiding_spot_max_light_quotient; +extern idCVar cv_ai_max_hiding_spot_tests_per_frame; +extern idCVar cv_ai_debug_anims; + +extern idCVar cv_show_health; + +extern idCVar cv_ai_show_aasfuncobstacle_state; + +extern idCVar cv_interaction_vfp_type; +extern idCVar cv_tdm_widescreenmode; +extern idCVar cv_tdm_menu_music; + +extern idCVar cv_tdm_show_trainer_messages; + +extern idCVar cv_tdm_default_relations_def; +extern idCVar cv_tdm_lang; +extern idCVar cv_tdm_fm_path; +extern idCVar cv_tdm_fm_desc_file; +extern idCVar cv_tdm_fm_current_file; +extern idCVar cv_tdm_fm_notes_file; +extern idCVar cv_tdm_fm_startingmap_file; +extern idCVar cv_tdm_fm_mapsequence_file; +extern idCVar cv_tdm_fm_splashimage_file; +extern idCVar cv_tdm_fm_sync_config_files; +extern idCVar cv_tdm_fm_restart_delay; + +extern idCVar cv_tdm_proxy; +extern idCVar cv_tdm_proxy_user; +extern idCVar cv_tdm_proxy_pass; +extern idCVar cv_tdm_allow_http_access; +extern idCVar cv_tdm_mission_list_urls; +extern idCVar cv_tdm_mission_details_url; +extern idCVar cv_tdm_mission_screenshot_url; +extern idCVar cv_tdm_version_check_url; +extern idCVar cv_tdm_http_base_url; + +extern idCVar cv_debug_aastype; + +extern idCVar cv_las_showtraces; +extern idCVar cv_show_gameplay_time; + +extern idCVar cv_tdm_difficulty; + +extern idCVar cv_sr_disable; +extern idCVar cv_sr_show; + +extern idCVar cv_sndprop_disable; +extern idCVar cv_spr_debug; +extern idCVar cv_spr_show; +extern idCVar cv_spr_radius_show; +extern idCVar cv_ko_show; +extern idCVar cv_ai_animstate_show; + +extern idCVar cv_debug_mainmenu; +extern idCVar cv_mainmenu_confirmquit; + +extern idCVar cv_pm_runmod; +extern idCVar cv_pm_run_backmod; +extern idCVar cv_pm_crouchmod; +extern idCVar cv_pm_max_swimspeed_mod; +extern idCVar cv_pm_creepmod; +extern idCVar cv_pm_pushmod; +extern idCVar cv_pm_push_maximpulse; +extern idCVar cv_pm_push_start_delay; +extern idCVar cv_pm_push_accel_time; +extern idCVar cv_pm_push_heavy_threshold; +extern idCVar cv_pm_push_max_mass; + + +/** +* TDM CVARs for controlling jumping +*/ +extern idCVar cv_tdm_walk_jump_vel; +extern idCVar cv_tdm_run_jump_vel; +extern idCVar cv_tdm_crouch_jump_vel; +extern idCVar cv_tdm_min_vel_jump; +extern idCVar cv_tdm_fwd_jump_vel; +extern idCVar cv_tdm_backwards_jump_modifier; +extern idCVar cv_tdm_jump_relaxation_time; + +extern idCVar cv_tdm_footfalls_movetype_specific; + +extern idCVar cv_pm_weightmod; + +extern idCVar cv_pm_mantle_height; +extern idCVar cv_pm_mantle_reach; +extern idCVar cv_pm_mantle_minflatness; +extern idCVar cv_pm_mantle_jump_hold_trigger; +extern idCVar cv_pm_mantle_min_velocity_for_damage; +extern idCVar cv_pm_mantle_damage_per_velocity_over_minimum; +extern idCVar cv_pm_mantle_hang_msecs; +extern idCVar cv_pm_mantle_pull_msecs; +extern idCVar cv_pm_mantle_shift_hands_msecs; +extern idCVar cv_pm_mantle_push_msecs; + +extern idCVar cv_pm_rope_snd_rep_dist; +extern idCVar cv_pm_rope_velocity_letgo; +extern idCVar cv_pm_rope_swing_impulse; +extern idCVar cv_pm_rope_swing_reptime; +extern idCVar cv_pm_rope_swing_kickdist; +extern idCVar cv_pm_water_downwards_velocity; +extern idCVar cv_pm_water_z_friction; +extern idCVar cv_pm_show_waterlevel; +extern idCVar cv_pm_climb_distance; + +/** +* This cvar controls if ai hiding spot search debug graphics are drawn +* If it is 0, then the graphics are not drawn. If it is >= 1.0 then it +* is the number of milliseconds for which each graphic should persist. +* For example 3000.0 would mean 3 seconds +*/ +extern idCVar cv_ai_search_show; + +extern idCVar cv_force_savegame_load; +extern idCVar cv_savegame_compress; + +extern idCVar cv_screenshot_format; + +// angua: TDM toggle crouch +extern idCVar cv_tdm_crouch_toggle; +extern idCVar cv_tdm_crouch_toggle_hold_time; +extern idCVar cv_tdm_reattach_delay; + + +/** +* TDM Leaning vars: +**/ +extern idCVar cv_pm_lean_angle; +extern idCVar cv_pm_lean_time; +extern idCVar cv_pm_lean_height; +extern idCVar cv_pm_lean_stretch; +extern idCVar cv_pm_lean_forward_angle; +extern idCVar cv_pm_lean_forward_time; +extern idCVar cv_pm_lean_forward_height; +extern idCVar cv_pm_lean_forward_stretch; +extern idCVar cv_pm_lean_to_valid_increments; +extern idCVar cv_pm_lean_door_increments; +extern idCVar cv_pm_lean_door_max; +extern idCVar cv_pm_lean_door_bounds_exp; +extern idCVar cv_pm_lean_toggle; + +extern idCVar cv_frob_distance_default; +extern idCVar cv_frob_width; +extern idCVar cv_frob_debug_bounds; +extern idCVar cv_frob_fadetime; +extern idCVar cv_frob_weapon_selects_weapon; +extern idCVar cv_frob_debug_hud; + +extern idCVar cv_weapon_next_on_empty; + +// physics +extern idCVar cv_collision_damage_scale_vert; +extern idCVar cv_collision_damage_scale_horiz; +extern idCVar cv_drag_limit_force; +extern idCVar cv_drag_force_max; +extern idCVar cv_drag_stuck_dist; +extern idCVar cv_drag_damping; +extern idCVar cv_drag_damping_AF; +extern idCVar cv_drag_AF_ground_timer; +extern idCVar cv_drag_AF_free; +extern idCVar cv_drag_jump_masslimit; +extern idCVar cv_drag_encumber_minmass; +extern idCVar cv_drag_encumber_minmass; +extern idCVar cv_drag_encumber_maxmass; +extern idCVar cv_drag_encumber_max; +extern idCVar cv_dragged_item_highlight; +extern idCVar cv_drag_debug; +extern idCVar cv_melee_debug; +extern idCVar cv_melee_state_debug; +extern idCVar cv_melee_mouse_thresh; +extern idCVar cv_melee_mouse_decision_time; +extern idCVar cv_melee_mouse_dead_time; +extern idCVar cv_melee_mouse_slowview; +extern idCVar cv_melee_invert_attack; +extern idCVar cv_melee_invert_parry; +extern idCVar cv_melee_auto_parry; +extern idCVar cv_melee_forbid_auto_parry; +extern idCVar cv_melee_max_particles; +extern idCVar cv_phys_show_momentum; + +extern idCVar cv_throw_min; +extern idCVar cv_throw_max; +extern idCVar cv_throw_time; +extern idCVar cv_throw_max_vel; + +extern idCVar cv_bounce_sound_max_vel; +extern idCVar cv_bounce_sound_min_vel; + +extern idCVar cv_reverse_grab_control; + +extern idCVar cv_tdm_rope_pull_force_factor; + +extern idCVar cv_tdm_obj_gui_file; +extern idCVar cv_tdm_waituntilready_gui_file; + +extern idCVar cv_tdm_hud_opacity; +extern idCVar cv_tdm_hud_hide_lightgem; +extern idCVar cv_tdm_underwater_blur; + +extern idCVar cv_tdm_inv_loot_item_def; +extern idCVar cv_tdm_inv_gui_file; +extern idCVar cv_tdm_inv_hud_pickupmessages; +extern idCVar cv_tdm_inv_loot_sound; +extern idCVar cv_tdm_inv_use_on_frob; +extern idCVar cv_tdm_inv_use_visual_feedback; + +extern idCVar cv_tdm_door_control; +extern idCVar cv_tdm_door_control_sensitivity; + +extern idCVar cv_pm_stepvol_walk; +extern idCVar cv_pm_stepvol_run; +extern idCVar cv_pm_stepvol_creep; +extern idCVar cv_pm_stepvol_crouch_walk; +extern idCVar cv_pm_stepvol_crouch_creep; +extern idCVar cv_pm_stepvol_crouch_run; +extern idCVar cv_pm_min_stepsound_interval; + +// Lightgem +extern idCVar cv_lg_distance; +extern idCVar cv_lg_xoffs; +extern idCVar cv_lg_yoffs; +extern idCVar cv_lg_zoffs; +extern idCVar cv_lg_oxoffs; +extern idCVar cv_lg_oyoffs; +extern idCVar cv_lg_ozoffs; +extern idCVar cv_lg_fov; +extern idCVar cv_lg_interleave; +extern idCVar cv_lg_hud; +extern idCVar cv_lg_weak; +extern idCVar cv_lg_player; +extern idCVar cv_lg_renderpasses; +extern idCVar cv_lg_debug; +extern idCVar cv_lg_model; +extern idCVar cv_lg_adjust; +extern idCVar cv_lg_split; +extern idCVar cv_lg_path; +extern idCVar cv_lg_crouch_modifier; +extern idCVar cv_lg_image_width; +extern idCVar cv_lg_screen_width; +extern idCVar cv_lg_screen_height; +extern idCVar cv_lg_velocity_mod_min_velocity; +extern idCVar cv_lg_velocity_mod_max_velocity; +extern idCVar cv_lg_velocity_mod_amount; + +extern idCVar cv_lg_fade_delay; // Added by J.C.Denton + +extern idCVar cv_empty_model; + +extern idCVar cv_tdm_s_doorDistanceAdd; +extern idCVar cv_tdm_gui_smallFontLimit; +extern idCVar cv_tdm_gui_mediumFontLimit; +extern idCVar cv_tdm_s_maxSoundsPerShader; + +// Lockpicking +extern idCVar cv_lp_pin_base_count; +extern idCVar cv_lp_sample_delay; +extern idCVar cv_lp_pick_timeout; +extern idCVar cv_lp_max_pick_attempts; +extern idCVar cv_lp_auto_pick; +extern idCVar cv_lp_randomize; +extern idCVar cv_lp_pawlow; +extern idCVar cv_lp_debug_hud; + +// Bow type +extern idCVar cv_bow_aimer; +// melee difficulty +extern idCVar cv_melee_difficulty; + +extern idCVar cv_door_auto_open_on_unlock; + +extern idCVar cv_dm_distance; + +// Ambient light method CVar +extern idCVar cv_ambient_method; + +// Volume of music speakers +extern idCVar cv_music_volume; + +// Tels: Volume of the "player voice" speaker +extern idCVar cv_voice_player_volume; +// Tels: Volume of the "speaker-from-off voice" speaker +extern idCVar cv_voice_from_off_volume; + +// angua: Velocity and sound volume of collisions +extern idCVar cv_moveable_collision; + +// Tels: LOD system: multiplier for the LOD distance to be used +extern idCVar cv_lod_bias; + +/** +* CVars added for Darkmod knockout and field of vision changes +*/ +extern idCVar cv_ai_fov_show; +extern idCVar cv_ai_ko_show; + +/** +* If != 0, use this ratio between FOV X and Y and ignore r_aspectRatio. +*/ +extern idCVar cv_r_fovRatio; + +/** Screen width * gui_Width = GUI width */ +extern idCVar cv_gui_Width; +/** Screen height * gui_Height = GUI height */ +extern idCVar cv_gui_Height; +/** Screen width * gui_CenterX = GUI center X */ +extern idCVar cv_gui_CenterX; +/** Screen height * gui_CenterY = GUI center Y */ +extern idCVar cv_gui_CenterY; + +/** +* End DarkMod cvars +**/ + +extern idCVar developer; + +extern idCVar g_cinematic; +extern idCVar g_cinematicMaxSkipTime; + +extern idCVar r_aspectRatio; + +extern idCVar g_monsters; +extern idCVar g_decals; +extern idCVar g_knockback; +extern idCVar g_skill; +extern idCVar g_gravity; +extern idCVar g_skipFX; +extern idCVar g_skipParticles; +extern idCVar g_bloodEffects; +extern idCVar g_projectileLights; +extern idCVar g_doubleVision; +extern idCVar g_muzzleFlash; + +extern idCVar g_disasm; +extern idCVar g_debugBounds; +extern idCVar g_debugAnim; +extern idCVar g_debugMove; +extern idCVar g_debugDamage; +extern idCVar g_debugWeapon; +extern idCVar g_debugScript; +extern idCVar g_debugMover; +extern idCVar g_debugTriggers; +extern idCVar g_debugCinematic; +extern idCVar g_stopTime; +extern idCVar g_armorProtection; +extern idCVar g_armorProtectionMP; +extern idCVar g_damageScale; +extern idCVar g_useDynamicProtection; +extern idCVar g_healthTakeTime; +extern idCVar g_healthTakeAmt; +extern idCVar g_healthTakeLimit; + +extern idCVar g_showPVS; +extern idCVar g_showTargets; +extern idCVar g_showTriggers; +extern idCVar g_showCollisionWorld; +extern idCVar g_showCollisionModels; +extern idCVar g_showCollisionTraces; +extern idCVar g_maxShowDistance; +extern idCVar g_showEntityInfo; +extern idCVar g_showviewpos; +extern idCVar g_showcamerainfo; +extern idCVar g_showTestModelFrame; +extern idCVar g_showActiveEntities; +extern idCVar g_showEnemies; + +extern idCVar g_frametime; +extern idCVar g_timeentities; + +extern idCVar g_timeModifier; + +extern idCVar ai_debugScript; +extern idCVar ai_debugMove; +extern idCVar ai_debugTrajectory; +extern idCVar ai_testPredictPath; +extern idCVar ai_showCombatNodes; +extern idCVar ai_showPaths; +extern idCVar ai_showObstacleAvoidance; +extern idCVar ai_blockedFailSafe; + +extern idCVar g_dvTime; +extern idCVar g_dvAmplitude; +extern idCVar g_dvFrequency; + +extern idCVar g_kickTime; +extern idCVar g_kickAmplitude; +extern idCVar g_blobTime; +extern idCVar g_blobSize; + +extern idCVar g_testHealthVision; +extern idCVar g_editEntityMode; +extern idCVar g_dragEntity; +extern idCVar g_dragDamping; +extern idCVar g_dragShowSelection; +extern idCVar g_dropItemRotation; + +extern idCVar g_vehicleVelocity; +extern idCVar g_vehicleForce; +extern idCVar g_vehicleSuspensionUp; +extern idCVar g_vehicleSuspensionDown; +extern idCVar g_vehicleSuspensionKCompress; +extern idCVar g_vehicleSuspensionDamping; +extern idCVar g_vehicleTireFriction; + +extern idCVar g_enablePortalSky; + + + +extern idCVar ik_enable; +extern idCVar ik_debug; + +extern idCVar af_useLinearTime; +extern idCVar af_useImpulseFriction; +extern idCVar af_useJointImpulseFriction; +extern idCVar af_useSymmetry; +extern idCVar af_skipSelfCollision; +extern idCVar af_skipLimits; +extern idCVar af_skipFriction; +extern idCVar af_forceFriction; +extern idCVar af_maxLinearVelocity; +extern idCVar af_maxAngularVelocity; +extern idCVar af_timeScale; +extern idCVar af_jointFrictionScale; +extern idCVar af_contactFrictionScale; +extern idCVar af_highlightBody; +extern idCVar af_highlightConstraint; +extern idCVar af_showTimings; +extern idCVar af_showConstraints; +extern idCVar af_showConstraintNames; +extern idCVar af_showConstrainedBodies; +extern idCVar af_showPrimaryOnly; +extern idCVar af_showTrees; +extern idCVar af_showLimits; +extern idCVar af_showBodies; +extern idCVar af_showBodyNames; +extern idCVar af_showMass; +extern idCVar af_showTotalMass; +extern idCVar af_showInertia; +extern idCVar af_showVelocity; +extern idCVar af_showActive; +extern idCVar af_testSolid; + +extern idCVar rb_showTimings; +extern idCVar rb_showBodies; +extern idCVar rb_showMass; +extern idCVar rb_showInertia; +extern idCVar rb_showVelocity; +extern idCVar rb_showActive; + +extern idCVar pm_jumpheight; +extern idCVar pm_stepsize; +//extern idCVar pm_crouchspeed; +extern idCVar pm_walkspeed; +//extern idCVar pm_runspeed; +extern idCVar pm_noclipspeed; +extern idCVar pm_spectatespeed; +extern idCVar pm_spectatebbox; +extern idCVar pm_usecylinder; +extern idCVar pm_minviewpitch; +extern idCVar pm_maxviewpitch; +// Commented out by Dram. Not needed as TDM does not use stamina +//extern idCVar pm_stamina; +//extern idCVar pm_staminathreshold; +//extern idCVar pm_staminarate; +extern idCVar pm_crouchheight; +extern idCVar pm_crouchviewheight; +extern idCVar pm_normalheight; +extern idCVar pm_normalviewheight; +extern idCVar pm_deadheight; +extern idCVar pm_deadviewheight; +extern idCVar pm_crouchrate; +extern idCVar pm_bboxwidth; +extern idCVar pm_crouchbob; +extern idCVar pm_walkbob; +extern idCVar pm_runbob; +extern idCVar pm_runpitch; +extern idCVar pm_runroll; +extern idCVar pm_bobup; +extern idCVar pm_bobpitch; +extern idCVar pm_bobroll; +extern idCVar pm_thirdPersonRange; +extern idCVar pm_thirdPersonHeight; +extern idCVar pm_thirdPersonAngle; +extern idCVar pm_thirdPersonClip; +extern idCVar pm_thirdPerson; +extern idCVar pm_thirdPersonDeath; +extern idCVar pm_modelView; +extern idCVar pm_airTics; + +extern idCVar g_showPlayerShadow; +extern idCVar g_showHud; +extern idCVar g_showProjectilePct; +extern idCVar g_showBrass; +extern idCVar g_gun_x; +extern idCVar g_gun_y; +extern idCVar g_gun_z; +extern idCVar g_viewNodalX; +extern idCVar g_viewNodalZ; +extern idCVar g_fov; +extern idCVar g_testDeath; +extern idCVar g_skipViewEffects; +extern idCVar g_mpWeaponAngleScale; + +extern idCVar g_testParticle; +extern idCVar g_testParticleName; + +extern idCVar g_testPostProcess; +extern idCVar g_rotoscope; + +extern idCVar g_testModelHead; +extern idCVar g_testModelHeadJoint; +extern idCVar g_testModelRotate; +extern idCVar g_testModelAnimate; +extern idCVar g_testModelBlend; +extern idCVar g_exportMask; +extern idCVar g_flushSave; + +extern idCVar aas_test; +extern idCVar aas_showAreas; +extern idCVar aas_showPath; +extern idCVar aas_showFlyPath; +extern idCVar aas_showWallEdges; +extern idCVar aas_showHideArea; +extern idCVar aas_pullPlayer; +extern idCVar aas_randomPullPlayer; +extern idCVar aas_goalArea; +extern idCVar aas_showPushIntoArea; + +extern idCVar net_clientPredictGUI; + +extern idCVar g_voteFlags; +extern idCVar g_mapCycle; +extern idCVar g_balanceTDM; + +extern idCVar si_timeLimit; +extern idCVar si_fragLimit; +extern idCVar si_gameType; +extern idCVar si_map; +extern idCVar si_spectators; + +extern idCVar net_clientSelfSmoothing; + +extern idCVar net_clientLagOMeter; + + +extern const char *si_gameTypeArgs[]; + + +extern const char *ui_skinArgs[]; + + +#ifdef MOD_WATERPHYSICS + +extern idCVar af_useBodyDensityBuoyancy; // MOD_WATERPHYSICS + +extern idCVar af_useFixedDensityBuoyancy; // MOD_WATERPHYSICS + +extern idCVar rb_showBuoyancy; // MOD_WATERPHYSICS + +#endif + +// HDR related - J.C.Denton + +extern idCVar r_postprocess; +extern idCVar r_postprocess_brightPassThreshold; +extern idCVar r_postprocess_brightPassOffset; +extern idCVar r_postprocess_colorCurveBias; +extern idCVar r_postprocess_colorCorrection; +extern idCVar r_postprocess_colorCorrectBias; +extern idCVar r_postprocess_sceneExposure; +extern idCVar r_postprocess_sceneGamma; +extern idCVar r_postprocess_debugMode; +extern idCVar r_postprocess_bloomKernelSize; +extern idCVar r_postprocess_bloomIntensity; +extern idCVar r_postprocess_desaturation; + +#endif /* !__SYS_CVAR_H__ */ diff --git a/game/gamesys/TypeInfo.cpp b/game/gamesys/TypeInfo.cpp new file mode 100644 index 000000000..386ac9d56 --- /dev/null +++ b/game/gamesys/TypeInfo.cpp @@ -0,0 +1,1420 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// This is real evil but allows the code to inspect arbitrary class variables. +#define private public +#define protected public + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#ifdef ID_DEBUG_MEMORY +#include "GameTypeInfo.h" // Make sure this is up to date! +#else +#include "NoGameTypeInfo.h" +#endif + +// disabled because it's adds about 64MB to state dumps and takes a really long time +//#define DUMP_GAMELOCAL + + +typedef void (*WriteVariableType_t)( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + + +class idTypeInfoTools { +public: + static const classTypeInfo_t * FindClassInfo( const char *typeName ); + static const enumTypeInfo_t * FindEnumInfo( const char *typeName ); + static bool IsSubclassOf( const char *typeName, const char *superType ); + static void PrintType( const void *typePtr, const char *typeName ); + static void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ); + static void InitTypeVariables( const void *typePtr, const char *typeName, int value ); + static void WriteGameState( const char *fileName ); + static void CompareGameState( const char *fileName ); + +private: + static idFile * fp; + static int initValue; + static WriteVariableType_t Write; + static idLexer * src; + static bool typeError; + + static const char * OutputString( const char *string ); + static bool ParseTemplateArguments( idLexer &src, idStr &arguments ); + static void PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + static void WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + static void WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + static void InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + static void VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); + static int WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ); + static void WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ); +}; + +idFile * idTypeInfoTools::fp = NULL; +int idTypeInfoTools::initValue = 0; +WriteVariableType_t idTypeInfoTools::Write = NULL; +idLexer * idTypeInfoTools::src = NULL; +bool idTypeInfoTools::typeError = false; + + +/* +================ +GetTypeVariableName +================ +*/ +const char *GetTypeVariableName( const char *typeName, int offset ) { + static char varName[1024]; + int i; + + for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { + if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { + if ( classTypeInfo[i].variables[0].name != NULL && offset >= classTypeInfo[i].variables[0].offset ) { + break; + } + typeName = classTypeInfo[i].superType; + if ( *typeName == '\0' ) { + return ""; + } + i = -1; + } + } + + const classTypeInfo_t &classInfo = classTypeInfo[i]; + + for ( i = 0; classInfo.variables[i].name != NULL; i++ ) { + if ( offset <= classInfo.variables[i].offset ) { + break; + } + } + if ( i == 0 ) { + idStr::snPrintf( varName, sizeof( varName ), "%s::", classInfo.typeName ); + } else { + idStr::snPrintf( varName, sizeof( varName ), "%s::%s", classInfo.typeName, classInfo.variables[i-1].name ); + } + return varName; +} + +/* +================ +idTypeInfoTools::FindClassInfo +================ +*/ +const classTypeInfo_t *idTypeInfoTools::FindClassInfo( const char *typeName ) { + int i; + + for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { + if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { + return &classTypeInfo[i]; + } + } + return NULL; +} + +/* +================ +idTypeInfoTools::FindEnumInfo +================ +*/ +const enumTypeInfo_t *idTypeInfoTools::FindEnumInfo( const char *typeName ) { + int i; + + for ( i = 0; enumTypeInfo[i].typeName != NULL; i++ ) { + if ( idStr::Cmp( typeName, enumTypeInfo[i].typeName ) == 0 ) { + return &enumTypeInfo[i]; + } + } + return NULL; +} + +/* +================ +idTypeInfoTools::IsSubclassOf +================ +*/ +bool idTypeInfoTools::IsSubclassOf( const char *typeName, const char *superType ) { + int i; + + while( *typeName != '\0' ) { + if ( idStr::Cmp( typeName, superType ) == 0 ) { + return true; + } + for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { + if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { + typeName = classTypeInfo[i].superType; + break; + } + } + if ( classTypeInfo[i].typeName == NULL ) { + common->Warning( "super class %s not found", typeName ); + break; + } + } + return false; +} + +/* +================ +idTypeInfoTools::OutputString +================ +*/ +const char *idTypeInfoTools::OutputString( const char *string ) { + static int index = 0; + static char buffers[4][16384]; + char *out; + int i, c; + + out = buffers[index]; + index = ( index + 1 ) & 3; + + if ( string == NULL ) { + return NULL; + } + + for ( i = 0; i < sizeof( buffers[0] ) - 2; i++ ) { + c = *string++; + switch( c ) { + case '\0': out[i] = '\0'; return out; + case '\\': out[i++] = '\\'; out[i] = '\\'; break; + case '\n': out[i++] = '\\'; out[i] = 'n'; break; + case '\r': out[i++] = '\\'; out[i] = 'r'; break; + case '\t': out[i++] = '\\'; out[i] = 't'; break; + case '\v': out[i++] = '\\'; out[i] = 'v'; break; + default: out[i] = c; break; + } + } + out[i] = '\0'; + return out; +} + +/* +================ +idTypeInfoTools::ParseTemplateArguments +================ +*/ +bool idTypeInfoTools::ParseTemplateArguments( idLexer &src, idStr &arguments ) { + int indent; + idToken token; + + arguments = ""; + + if ( !src.ExpectTokenString( "<" ) ) { + return false; + } + + indent = 1; + while( indent ) { + if ( !src.ReadToken( &token ) ) { + break; + } + if ( token == "<" ) { + indent++; + } else if ( token == ">" ) { + indent--; + } else { + if ( arguments.Length() ) { + arguments += " "; + } + arguments += token; + } + } + return true; +} + +/* +================ +idTypeInfoTools::PrintType +================ +*/ +void idTypeInfoTools::PrintType( const void *typePtr, const char *typeName ) { + idTypeInfoTools::fp = NULL; + idTypeInfoTools::initValue = 0; + idTypeInfoTools::Write = PrintVariable; + WriteClass_r( typePtr, "", typeName, "", "", 0 ); +} + +/* +================ +idTypeInfoTools::WriteTypeToFile +================ +*/ +void idTypeInfoTools::WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) { + idTypeInfoTools::fp = fp; + idTypeInfoTools::initValue = 0; + idTypeInfoTools::Write = WriteVariable; + WriteClass_r( typePtr, "", typeName, "", "", 0 ); +} + +/* +================ +idTypeInfoTools::InitTypeVariables +================ +*/ +void idTypeInfoTools::InitTypeVariables( const void *typePtr, const char *typeName, int value ) { + idTypeInfoTools::fp = NULL; + idTypeInfoTools::initValue = value; + idTypeInfoTools::Write = InitVariable; + WriteClass_r( typePtr, "", typeName, "", "", 0 ); +} + +/* +================ +IsAllowedToChangedFromSaveGames +================ +*/ +bool IsAllowedToChangedFromSaveGames( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) { + if ( idStr::Icmp( scope, "idAnimator" ) == 0 ) { + if ( idStr::Icmp( varName, "forceUpdate" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "lastTransformTime" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "AFPoseTime" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "frameBounds" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) { + if ( idStr::Icmp( varName, "touchCount" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) { + if ( idStr::Icmp( varName, "numPVSAreas" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "renderView" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idBrittleFracture" ) == 0 ) { + if ( idStr::Icmp( varName, "changed" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idPhysics_AF" ) == 0 ) { + return true; + } else if ( idStr::Icmp( scope, "renderEntity_t" ) == 0 ) { + // These get fixed up when UpdateVisuals is called + if ( idStr::Icmp( varName, "origin" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "axis" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "bounds" ) == 0 ) { + return true; + } + } + + if ( idStr::Icmpn( prefix, "idAFEntity_Base::af.idAF::physicsObj.idPhysics_AF", 49) == 0 ) { + return true; + } + + return false; +} + +/* +================ +IsRenderHandleVariable +================ +*/ +bool IsRenderHandleVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) { + if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) { + if ( idStr::Icmp( varName, "renderModelHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idFXLocalAction" ) == 0 ) { + if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) { + if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idLight" ) == 0 ) { + if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idAFEntity_Gibbable" ) == 0 ) { + if ( idStr::Icmp( varName, "skeletonModelDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idAFEntity_SteamPipe" ) == 0 ) { + if ( idStr::Icmp( varName, "steamModelHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idItem" ) == 0 ) { + if ( idStr::Icmp( varName, "itemShellHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idExplodingBarrel" ) == 0 ) { + if ( idStr::Icmp( varName, "particleModelDefHandle" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idProjectile" ) == 0 ) { + if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idSmokeParticles" ) == 0 ) { + if ( idStr::Icmp( varName, "renderEntityHandle" ) == 0 ) { + return true; + } + } else if ( idStr::Icmp( scope, "idWeapon" ) == 0 ) { + if ( idStr::Icmp( varName, "muzzleFlashHandle" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "worldMuzzleFlashHandle" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "guiLightHandle" ) == 0 ) { + return true; + } + if ( idStr::Icmp( varName, "nozzleGlowHandle" ) == 0 ) { + return true; + } + } + return false; +} + +/* +================ +idTypeInfoTools::PrintVariable +================ +*/ +void idTypeInfoTools::PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { + common->Printf( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); +} + +/* +================ +idTypeInfoTools::WriteVariable +================ +*/ +void idTypeInfoTools::WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { + + for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) { + if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 || + idStr::Icmpn( value+i+1, "IND", 3 ) == 0 || + idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 || + idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 || + idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) { + common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value ); + break; + } + } + fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); +} + +/* +================ +idTypeInfoTools::WriteGameStateVariable +================ +*/ +void idTypeInfoTools::WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { + + for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) { + if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 || + idStr::Icmpn( value+i+1, "IND", 3 ) == 0 || + idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 || + idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 || + idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) { + common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value ); + break; + } + } + + if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { + return; + } + + if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) { + return; + } + + fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); +} + +/* +================ +idTypeInfoTools::InitVariable +================ +*/ +void idTypeInfoTools::InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { + if ( varPtr != NULL && varSize > 0 ) { + // NOTE: skip renderer handles + if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { + return; + } + memset( const_cast(varPtr), initValue, varSize ); + } +} + +/* +================ +idTypeInfoTools::VerifyVariable +================ +*/ +void idTypeInfoTools::VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { + idToken token; + + if ( typeError ) { + return; + } + + src->SkipUntilString( "=" ); + src->ExpectTokenType( TT_STRING, 0, &token ); + if ( token.Cmp( value ) != 0 ) { + + // NOTE: skip several things + + if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { + return; + } + + if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) { + return; + } + + src->Warning( "state diff for %s%s::%s%s\n%s\n%s", prefix, scope, varName, postfix, token.c_str(), value ); + typeError = true; + } +} + +/* +================ +idTypeInfoTools::WriteVariable_r +================ +*/ +int idTypeInfoTools::WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ) { + int i, isPointer, typeSize; + idLexer typeSrc; + idToken token; + idStr typeString, templateArgs; + + isPointer = 0; + typeSize = -1; + + // create a type string without 'const', 'mutable', 'class', 'struct', 'union' + typeSrc.LoadMemory( varType, idStr::Length( varType ), varName ); + while( typeSrc.ReadToken( &token ) ) { + if ( token != "const" && token != "mutable" && token != "class" && token != "struct" && token != "union" ) { + typeString += token + " "; + } + } + typeString.StripTrailing( ' ' ); + typeSrc.FreeSource(); + + // if this is an array + if ( typeString[typeString.Length() - 1] == ']' ) { + for ( i = typeString.Length(); i > 0 && typeString[i - 1] != '['; i-- ) { + } + int num = atoi( &typeString[i] ); + idStr listVarType = typeString; + listVarType.CapLength( i - 1 ); + typeSize = 0; + for ( i = 0; i < num; i++ ) { + idStr listVarName = va( "%s[%d]", varName, i ); + int size = WriteVariable_r( varPtr, listVarName, listVarType, scope, prefix, pointerDepth ); + typeSize += size; + if ( size == -1 ) { + break; + } + varPtr = (void *)( ( (byte *) varPtr ) + size ); + } + return typeSize; + } + + // if this is a pointer + isPointer = 0; + for ( i = typeString.Length(); i > 0 && typeString[i - 1] == '*'; i -= 2 ) { + if ( varPtr == (void *)0xcdcdcdcd || ( varPtr != NULL && *((unsigned long *)varPtr) == 0xcdcdcdcd ) ) { + common->Warning( "%s%s::%s%s references uninitialized memory", prefix, scope, varName, "" ); + return typeSize; + } + if ( varPtr != NULL ) { + varPtr = *((void **)varPtr); + } + isPointer++; + } + + if ( varPtr == NULL ) { + Write( varName, varType, scope, prefix, "", "", varPtr, 0 ); + return sizeof( void * ); + } + + typeSrc.LoadMemory( typeString, typeString.Length(), varName ); + + if ( !typeSrc.ReadToken( &token ) ) { + Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); + return -1; + } + + // get full type + while( typeSrc.CheckTokenString( "::" ) ) { + idToken newToken; + typeSrc.ExpectTokenType( TT_NAME, 0, &newToken ); + token += "::" + newToken; + } + + if ( token == "signed" ) { + + if ( !typeSrc.ReadToken( &token ) ) { + Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); + return -1; + } + if ( token == "char" ) { + + typeSize = sizeof( signed char ); + Write( varName, varType, scope, prefix, "", va( "%d", *((signed char *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "short" ) { + + typeSize = sizeof( signed short ); + Write( varName, varType, scope, prefix, "", va( "%d", *((signed short *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "int" ) { + + typeSize = sizeof( signed int ); + Write( varName, varType, scope, prefix, "", va( "%d", *((signed int *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "long" ) { + + typeSize = sizeof( signed long ); + Write( varName, varType, scope, prefix, "", va( "%ld", *((signed long *)varPtr) ), varPtr, typeSize ); + + } else { + + Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); + return -1; + } + + } else if ( token == "unsigned" ) { + + if ( !typeSrc.ReadToken( &token ) ) { + Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); + return -1; + } + if ( token == "char" ) { + + typeSize = sizeof( unsigned char ); + Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned char *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "short" ) { + + typeSize = sizeof( unsigned short ); + Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned short *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "int" ) { + + typeSize = sizeof( unsigned int ); + Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned int *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "long" ) { + + typeSize = sizeof( unsigned long ); + Write( varName, varType, scope, prefix, "", va( "%lu", *((unsigned long *)varPtr) ), varPtr, typeSize ); + + } else { + + Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); + return -1; + } + + } else if ( token == "byte" ) { + + typeSize = sizeof( byte ); + Write( varName, varType, scope, prefix, "", va( "%d", *((byte *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "word" ) { + + typeSize = sizeof( word ); + Write( varName, varType, scope, prefix, "", va( "%d", *((word *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "dword" ) { + + typeSize = sizeof( dword ); + Write( varName, varType, scope, prefix, "", va( "%d", *((dword *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "bool" ) { + + typeSize = sizeof( bool ); + Write( varName, varType, scope, prefix, "", va( "%d", *((bool *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "char" ) { + + typeSize = sizeof( char ); + Write( varName, varType, scope, prefix, "", va( "%d", *((char *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "short" ) { + + typeSize = sizeof( short ); + Write( varName, varType, scope, prefix, "", va( "%d", *((short *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "int" ) { + + typeSize = sizeof( int ); + Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "long" ) { + + typeSize = sizeof( long ); + Write( varName, varType, scope, prefix, "", va( "%ld", *((long *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "float" ) { + + typeSize = sizeof( float ); + Write( varName, varType, scope, prefix, "", idStr( *((float *)varPtr) ).c_str(), varPtr, typeSize ); + + } else if ( token == "double" ) { + + typeSize = sizeof( double ); + Write( varName, varType, scope, prefix, "", idStr( (float)*((double *)varPtr) ).c_str(), varPtr, typeSize ); + + } else if ( token == "idVec2" ) { + + typeSize = sizeof( idVec2 ); + Write( varName, varType, scope, prefix, "", ((idVec2 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idVec3" ) { + + typeSize = sizeof( idVec3 ); + Write( varName, varType, scope, prefix, "", ((idVec3 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idVec4" ) { + + typeSize = sizeof( idVec4 ); + Write( varName, varType, scope, prefix, "", ((idVec4 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idVec5" ) { + + typeSize = sizeof( idVec5 ); + Write( varName, varType, scope, prefix, "", ((idVec5 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idVec6" ) { + + typeSize = sizeof( idVec6 ); + Write( varName, varType, scope, prefix, "", ((idVec6 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idVecX" ) { + + const idVecX *vec = ((idVecX *)varPtr); + if ( vec->ToFloatPtr() != NULL ) { + Write( varName, varType, scope, prefix, "", vec->ToString( 8 ), vec->ToFloatPtr(), vec->GetSize() * sizeof( float ) ); + } else { + Write( varName, varType, scope, prefix, "", "", varPtr, 0 ); + } + typeSize = sizeof( idVecX ); + + } else if ( token == "idMat2" ) { + + typeSize = sizeof( idMat2 ); + Write( varName, varType, scope, prefix, "", ((idMat2 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idMat3" ) { + + typeSize = sizeof( idMat3 ); + Write( varName, varType, scope, prefix, "", ((idMat3 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idMat4" ) { + + typeSize = sizeof( idMat4 ); + Write( varName, varType, scope, prefix, "", ((idMat4 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idMat5" ) { + + typeSize = sizeof( idMat5 ); + Write( varName, varType, scope, prefix, "", ((idMat5 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idMat6" ) { + + typeSize = sizeof( idMat6 ); + Write( varName, varType, scope, prefix, "", ((idMat6 *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idMatX" ) { + + typeSize = sizeof( idMatX ); + const idMatX *mat = ((idMatX *)varPtr); + if ( mat->ToFloatPtr() != NULL ) { + Write( varName, varType, scope, prefix, "", mat->ToString( 8 ), mat->ToFloatPtr(), mat->GetNumColumns() * mat->GetNumRows() * sizeof( float ) ); + } else { + Write( varName, varType, scope, prefix, "", "", NULL, 0 ); + } + + } else if ( token == "idAngles" ) { + + typeSize = sizeof( idAngles ); + Write( varName, varType, scope, prefix, "", ((idAngles *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idQuat" ) { + + typeSize = sizeof( idQuat ); + Write( varName, varType, scope, prefix, "", ((idQuat *)varPtr)->ToString( 8 ), varPtr, typeSize ); + + } else if ( token == "idBounds" ) { + + typeSize = sizeof( idBounds ); + const idBounds *bounds = ((idBounds *)varPtr); + if ( bounds->IsCleared() ) { + Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); + } else { + Write( varName, varType, scope, prefix, "", va( "(%s)-(%s)", (*bounds)[0].ToString( 8 ), (*bounds)[1].ToString( 8 ) ), varPtr, typeSize ); + } + + } else if ( token == "idList" ) { + + idList *list = ((idList *)varPtr); + Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 ); + // NOTE: we don't care about the amount of memory allocated + //Write( varName, varType, scope, prefix, ".size", va( "%d", list->Size() ), NULL, 0 ); + Write( varName, varType, scope, prefix, ".granularity", va( "%d", list->GetGranularity() ), NULL, 0 ); + + if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) { + void *listVarPtr = list->Ptr(); + for ( i = 0; i < list->Num(); i++ ) { + idStr listVarName = va( "%s[%d]", varName, i ); + int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth ); + if ( size == -1 ) { + break; + } + listVarPtr = (void *)( ( (byte *) listVarPtr ) + size ); + } + } + + typeSize = sizeof( idList ); + + } else if ( token == "idStaticList" ) { + + idStaticList *list = ((idStaticList *)varPtr); + Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 ); + + int totalSize = 0; + if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) { + void *listVarPtr = list->Ptr(); + for ( i = 0; i < list->Num(); i++ ) { + idStr listVarName = va( "%s[%d]", varName, i ); + int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth ); + if ( size == -1 ) { + break; + } + totalSize += size; + listVarPtr = (void *)( ( (byte *) listVarPtr ) + size ); + } + } + + typeSize = sizeof( int ) + totalSize; + + } else if ( token == "idLinkList" ) { + + // FIXME: implement + typeSize = sizeof( idLinkList ); + Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); + + } else if ( token == "idStr" ) { + + typeSize = sizeof( idStr ); + + const idStr *str = ((idStr *)varPtr); + Write( varName, varType, scope, prefix, "", OutputString( str->c_str() ), str->c_str(), str->Length() ); + + } else if ( token == "idStrList" ) { + + typeSize = sizeof( idStrList ); + + const idStrList *list = ((idStrList *)varPtr); + if ( list->Num() ) { + for ( i = 0; i < list->Num(); i++ ) { + Write( varName, varType, scope, prefix, va("[%d]", i ), OutputString( (*list)[i].c_str() ), (*list)[i].c_str(), (*list)[i].Length() ); + } + } else { + Write( varName, varType, scope, prefix, "", "", NULL, 0 ); + } + + } else if ( token == "idDict" ) { + + typeSize = sizeof( idDict ); + + const idDict *dict = ((idDict *)varPtr); + if ( dict->GetNumKeyVals() ) { + for ( i = 0; i < dict->GetNumKeyVals(); i++ ) { + const idKeyValue *kv = dict->GetKeyVal( i ); + Write( varName, varType, scope, prefix, va("[%d]", i ), va( "\'%s\' \'%s\'", OutputString( kv->GetKey().c_str() ), OutputString( kv->GetValue().c_str() ) ), NULL, 0 ); + } + } else { + Write( varName, varType, scope, prefix, "", "", NULL, 0 ); + } + + } else if ( token == "idExtrapolate" ) { + + const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); + Write( varName, varType, scope, prefix, ".extrapolationType", idStr( interpolate->GetExtrapolationType() ).c_str(), &interpolate->extrapolationType, sizeof( interpolate->extrapolationType ) ); + Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); + Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) ); + + if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { + if ( templateArgs == "int" ) { + const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); + Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) ); + typeSize = sizeof( idExtrapolate ); + } else if ( templateArgs == "float" ) { + const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); + Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) ); + typeSize = sizeof( idExtrapolate ); + } else if ( templateArgs == "idVec3" ) { + const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); + Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) ); + typeSize = sizeof( idExtrapolate ); + } else if ( templateArgs == "idAngles" ) { + const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); + Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) ); + typeSize = sizeof( idExtrapolate ); + } else { + Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); + } + } + + } else if ( token == "idInterpolate" ) { + + const idInterpolate *interpolate = ((idInterpolate *)varPtr); + Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); + Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) ); + + if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { + if ( templateArgs == "int" ) { + const idInterpolate *interpolate = ((idInterpolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolate ); + } else if ( templateArgs == "float" ) { + const idInterpolate *interpolate = ((idInterpolate *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolate ); + } else { + Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); + } + } + + } else if ( token == "idInterpolateAccelDecelLinear" ) { + + const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); + Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); + Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) ); + Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) ); + Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) ); + + if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { + if ( templateArgs == "int" ) { + const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolateAccelDecelLinear ); + } else if ( templateArgs == "float" ) { + const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolateAccelDecelLinear ); + } else { + Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); + } + } + + } else if ( token == "idInterpolateAccelDecelSine" ) { + + const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); + Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); + Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) ); + Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) ); + Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) ); + + if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { + if ( templateArgs == "int" ) { + const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolateAccelDecelSine ); + } else if ( templateArgs == "float" ) { + const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); + Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); + Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); + typeSize = sizeof( idInterpolateAccelDecelSine ); + } else { + Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); + } + } + + } else if ( token == "idUserInterface" ) { + + typeSize = sizeof( idUserInterface ); + const idUserInterface *gui = ((idUserInterface *)varPtr); + Write( varName, varType, scope, prefix, "", gui->Name(), varPtr, sizeof( varPtr ) ); + + } else if ( token == "idRenderModel" ) { + + typeSize = sizeof( idRenderModel ); + const idRenderModel *model = ((idRenderModel *)varPtr); + Write( varName, varType, scope, prefix, "", model->Name(), varPtr, sizeof( varPtr ) ); + + } else if ( token == "qhandle_t" ) { + + typeSize = sizeof( int ); + Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "cmHandle_t" ) { + + typeSize = sizeof( int ); + Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); + + } else if ( token == "idEntityPtr" ) { + + typeSize = sizeof( idEntityPtr ); + + const idEntityPtr *entPtr = ((idEntityPtr *)varPtr); + if ( entPtr->GetEntity() ) { + idEntity *entity = entPtr->GetEntity(); + Write( varName, varType, scope, prefix, ".", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), varPtr, typeSize ); + } else { + Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); + } + + } else if ( token == "idEntity::entityFlags_s" ) { + + const idEntity::entityFlags_s *flags = ((idEntity::entityFlags_s *)varPtr); + Write( varName, varType, scope, prefix, ".notarget", flags->notarget ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".noknockback", flags->noknockback ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".takedamage", flags->takedamage ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".hidden", flags->hidden ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".bindOrientated", flags->bindOrientated ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".solidForTeam", flags->solidForTeam ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".forcePhysicsUpdate", flags->forcePhysicsUpdate ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".selected", flags->selected ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".neverDormant", flags->neverDormant ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".isDormant", flags->isDormant ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".hasAwakened", flags->hasAwakened ? "true" : "false", NULL, 0 ); + Write( varName, varType, scope, prefix, ".networkSync", flags->networkSync ? "true" : "false", NULL, 0 ); + typeSize = sizeof( idEntity::entityFlags_s ); + + } else if ( token == "idScriptBool" ) { + + typeSize = sizeof( idScriptBool ); + + const idScriptBool *scriptBool = ((idScriptBool *)varPtr); + if ( scriptBool->IsLinked() ) { + Write( varName, varType, scope, prefix, "", ( *scriptBool != 0 ) ? "true" : "false", varPtr, typeSize ); + } else { + Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); + } + + } else { + + const classTypeInfo_t *classTypeInfo = FindClassInfo( scope + ( "::" + token ) ); + if ( classTypeInfo == NULL ) { + classTypeInfo = FindClassInfo( token ); + } + if ( classTypeInfo != NULL ) { + + typeSize = classTypeInfo->size; + + if ( !isPointer ) { + + char newPrefix[1024]; + idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s.", prefix, scope, varName ); + WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth ); + + } else if ( token == "idAnim" ) { + + const idAnim *anim = ((idAnim*)varPtr); + Write( varName, varType, scope, prefix, "", anim->Name(), NULL, 0 ); + + } else if ( token == "idPhysics" ) { + + const idPhysics *physics = ((idPhysics*)varPtr); + Write( varName, varType, scope, prefix, "", physics->GetType()->classname, NULL, 0 ); + + } else if ( IsSubclassOf( token, "idEntity" ) ) { + + const idEntity *entity = ((idEntity*)varPtr); + Write( varName, varType, scope, prefix, "", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), NULL, 0 ); + + } else if ( IsSubclassOf( token, "idDecl" ) ) { + + const idDecl *decl = ((idDecl *)varPtr); + Write( varName, varType, scope, prefix, "", decl->GetName(), NULL, 0 ); + + } else if ( pointerDepth == 0 && ( + token == "idAFBody" || + token == "idAFTree" || + token == "idClipModel" || + IsSubclassOf( token, "idAFConstraint" ) + ) ) { + + char newPrefix[1024]; + idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s->", prefix, scope, varName ); + WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth + 1 ); + + } else { + + Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); + return -1; + } + } else { + const enumTypeInfo_t *enumTypeInfo = FindEnumInfo( scope + ( "::" + token ) ); + if ( enumTypeInfo == NULL ) { + enumTypeInfo = FindEnumInfo( token ); + } + if ( enumTypeInfo != NULL ) { + + typeSize = sizeof( int ); // NOTE: assuming sizeof( enum ) is sizeof( int ) + + for ( i = 0; enumTypeInfo->values[i].name != NULL; i++ ) { + if ( *((int *)varPtr) == enumTypeInfo->values[i].value ) { + break; + } + } + if ( enumTypeInfo->values[i].name != NULL ) { + Write( varName, varType, scope, prefix, "", enumTypeInfo->values[i].name, NULL, 0 ); + } else { + Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), NULL, 0 ); + } + + } else { + Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); + return -1; + } + } + } + + i = 0; + do { + if ( *((unsigned long *)varPtr) == 0xcdcdcdcd ) { + common->Warning( "%s%s::%s%s uses uninitialized memory", prefix, scope, varName, "" ); + break; + } + } while( ++i < typeSize ); + + if ( isPointer ) { + return sizeof( void * ); + } + return typeSize; +} + +/* +================ +idTypeInfoTools::WriteClass_r +================ +*/ +void idTypeInfoTools::WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ) { + int i; + + const classTypeInfo_t *classInfo = FindClassInfo( classType ); + if ( !classInfo ) { + return; + } + if ( *classInfo->superType != '\0' ) { + WriteClass_r( classPtr, className, classInfo->superType, scope, prefix, pointerDepth ); + } + + for ( i = 0; classInfo->variables[i].name != NULL; i++ ) { + const classVariableInfo_t &classVar = classInfo->variables[i]; + + void *varPtr = (void *) (((byte *)classPtr) + classVar.offset); + + WriteVariable_r( varPtr, classVar.name, classVar.type, classType, prefix, pointerDepth ); + } +} + +/* +================ +idTypeInfoTools::WriteGameState +================ +*/ +void idTypeInfoTools::WriteGameState( const char *fileName ) { + int i, num; + idFile *file; + + file = fileSystem->OpenFileWrite( fileName ); + if ( !file ) { + common->Warning( "couldn't open %s", fileName ); + return; + } + + fp = file; + Write = WriteGameStateVariable; //WriteVariable; + +#ifdef DUMP_GAMELOCAL + + file->WriteFloatString( "\ngameLocal {\n" ); + WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 ); + file->WriteFloatString( "}\n" ); + +#endif + + for ( num = i = 0; i < gameLocal.num_entities; i++ ) { + idEntity *ent = gameLocal.entities[i]; + if ( ent == NULL ) { + continue; + } + file->WriteFloatString( "\nentity %d %s {\n", i, ent->GetType()->classname ); + WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 ); + file->WriteFloatString( "}\n" ); + num++; + } + + fileSystem->CloseFile( file ); + + common->Printf( "%d entities written\n", num ); +} + +/* +================ +idTypeInfoTools::CompareGameState +================ +*/ +void idTypeInfoTools::CompareGameState( const char *fileName ) { + int entityNum; + idToken token; + + src = new idLexer(); + src->SetFlags( LEXFL_NOSTRINGESCAPECHARS ); + + if ( !src->LoadFile( fileName ) ) { + common->Warning( "couldn't load %s", fileName ); + delete src; + src = NULL; + return; + } + + fp = NULL; + Write = VerifyVariable; + +#ifdef DUMP_GAMELOCAL + + if ( !src->ExpectTokenString( "gameLocal" ) || !src->ExpectTokenString( "{" ) ) { + delete src; + src = NULL; + return; + } + + WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 ); + + if ( !src->ExpectTokenString( "}" ) ) { + delete src; + src = NULL; + return; + } + +#endif + + while( src->ReadToken( &token ) ) { + if ( token != "entity" ) { + break; + } + if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) { + break; + } + + entityNum = token.GetIntValue(); + + if ( entityNum < 0 || entityNum >= gameLocal.num_entities ) { + src->Warning( "entity number %d out of range", entityNum ); + break; + } + + typeError = false; + + idEntity *ent = gameLocal.entities[entityNum]; + if ( !ent ) { + src->Warning( "entity %d is not spawned", entityNum ); + src->SkipBracedSection( true ); + continue; + } + + if ( !src->ExpectTokenType( TT_NAME, 0, &token ) ) { + break; + } + + if ( token.Cmp( ent->GetType()->classname ) != 0 ) { + src->Warning( "entity %d has wrong type", entityNum ); + src->SkipBracedSection( true ); + continue; + } + + if ( !src->ExpectTokenString( "{" ) ) { + src->Warning( "entity %d missing leading {", entityNum ); + break; + } + + WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 ); + + if ( !src->SkipBracedSection( false ) ) { + src->Warning( "entity %d missing trailing }", entityNum ); + break; + } + } + + delete src; + src = NULL; +} + +/* +================ +WriteGameState_f +================ +*/ +void WriteGameState_f( const idCmdArgs &args ) { + idStr fileName; + + if ( args.Argc() > 1 ) { + fileName = args.Argv(1); + } else { + fileName = "GameState.txt"; + } + fileName.SetFileExtension( "gameState.txt" ); + + idTypeInfoTools::WriteGameState( fileName ); +} + +/* +================ +CompareGameState_f +================ +*/ +void CompareGameState_f( const idCmdArgs &args ) { + idStr fileName; + + if ( args.Argc() > 1 ) { + fileName = args.Argv(1); + } else { + fileName = "GameState.txt"; + } + fileName.SetFileExtension( "gameState.txt" ); + + idTypeInfoTools::CompareGameState( fileName ); +} + +/* +================ +TestSaveGame_f +================ +*/ +void TestSaveGame_f( const idCmdArgs &args ) { + idStr name; + + if ( args.Argc() <= 1 ) { + gameLocal.Printf( "testSaveGame \n" ); + return; + } + + name = args.Argv( 1 ); + + try { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "map %s", name.c_str() ) ); + name.Replace( "\\", "_" ); + name.Replace( "/", "_" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "saveGame test_%s", name.c_str() ) ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "loadGame test_%s", name.c_str() ) ); + } + catch( idException & ) { + // an ERR_DROP was thrown + } + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "quit" ); +} + +/* +================ +WriteTypeToFile +================ +*/ +void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) { + idTypeInfoTools::WriteTypeToFile( fp, typePtr, typeName ); +} + +/* +================ +PrintType +================ +*/ +void PrintType( const void *typePtr, const char *typeName ) { + idTypeInfoTools::PrintType( typePtr, typeName ); +} + +/* +================ +InitTypeVariables +================ +*/ +void InitTypeVariables( const void *typePtr, const char *typeName, int value ) { + idTypeInfoTools::InitTypeVariables( typePtr, typeName, value ); +} + +/* +================ +ListTypeInfo_f +================ +*/ +int SortTypeInfoByName( const int *a, const int *b ) { + return idStr::Icmp( classTypeInfo[*a].typeName, classTypeInfo[*b].typeName ); +} + +int SortTypeInfoBySize( const int *a, const int *b ) { + if ( classTypeInfo[*a].size < classTypeInfo[*b].size ) { + return -1; + } + if ( classTypeInfo[*a].size > classTypeInfo[*b].size ) { + return 1; + } + return 0; +} + +void ListTypeInfo_f( const idCmdArgs &args ) { + int i, j; + idList index; + + common->Printf( "%-32s : %-32s size (B)\n", "type name", "super type name" ); + for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { + index.Append( i ); + } + + if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "size" ) == 0 ) { + index.Sort( SortTypeInfoBySize ); + } else { + index.Sort( SortTypeInfoByName ); + } + + for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { + j = index[i]; + common->Printf( "%-32s : %-32s %d\n", classTypeInfo[j].typeName, classTypeInfo[j].superType, classTypeInfo[j].size ); + } +} diff --git a/game/gamesys/TypeInfo.h b/game/gamesys/TypeInfo.h new file mode 100644 index 000000000..45d5d0e2e --- /dev/null +++ b/game/gamesys/TypeInfo.h @@ -0,0 +1,43 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SYS_TYPEINFO_H__ +#define __SYS_TYPEINFO_H__ + +/* +=================================================================================== + + Game Type Info + +=================================================================================== +*/ + +const char * GetTypeVariableName( const char *typeName, int offset ); + +void PrintType( const void *typePtr, const char *typeName ); +void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ); +void InitTypeVariables( const void *typePtr, const char *typeName, int value ); + +void ListTypeInfo_f( const idCmdArgs &args ); + +void WriteGameState_f( const idCmdArgs &args ); +void CompareGameState_f( const idCmdArgs &args ); +void TestSaveGame_f( const idCmdArgs &args ); + +#endif /* !__SYS_TYPEINFO_H__ */ diff --git a/game/gamesys/callbacks.cpp b/game/gamesys/callbacks.cpp deleted file mode 100644 index 1ef6e4ed7..000000000 --- a/game/gamesys/callbacks.cpp +++ /dev/null @@ -1,2614 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2004/10/30 15:52:33 sparhawk - * Initial revision - * - ***************************************************************************/ - -// generated file - see CREATE_EVENT_CODE - - /******************************************************* - - 1 args - - *******************************************************/ - - case 512 : - typedef void ( idClass::*eventCallback_i_t )( const int ); - ( this->*( eventCallback_i_t )callback )( data[ 0 ] ); - break; - - case 513 : - typedef void ( idClass::*eventCallback_f_t )( const float ); - ( this->*( eventCallback_f_t )callback )( *( float * )&data[ 0 ] ); - break; - - /******************************************************* - - 2 args - - *******************************************************/ - - case 1024 : - typedef void ( idClass::*eventCallback_ii_t )( const int, const int ); - ( this->*( eventCallback_ii_t )callback )( data[ 0 ], data[ 1 ] ); - break; - - case 1025 : - typedef void ( idClass::*eventCallback_fi_t )( const float, const int ); - ( this->*( eventCallback_fi_t )callback )( *( float * )&data[ 0 ], data[ 1 ] ); - break; - - case 1026 : - typedef void ( idClass::*eventCallback_if_t )( const int, const float ); - ( this->*( eventCallback_if_t )callback )( data[ 0 ], *( float * )&data[ 1 ] ); - break; - - case 1027 : - typedef void ( idClass::*eventCallback_ff_t )( const float, const float ); - ( this->*( eventCallback_ff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ] ); - break; - - /******************************************************* - - 3 args - - *******************************************************/ - - case 2048 : - typedef void ( idClass::*eventCallback_iii_t )( const int, const int, const int ); - ( this->*( eventCallback_iii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ] ); - break; - - case 2049 : - typedef void ( idClass::*eventCallback_fii_t )( const float, const int, const int ); - ( this->*( eventCallback_fii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ] ); - break; - - case 2050 : - typedef void ( idClass::*eventCallback_ifi_t )( const int, const float, const int ); - ( this->*( eventCallback_ifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ] ); - break; - - case 2051 : - typedef void ( idClass::*eventCallback_ffi_t )( const float, const float, const int ); - ( this->*( eventCallback_ffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ] ); - break; - - case 2052 : - typedef void ( idClass::*eventCallback_iif_t )( const int, const int, const float ); - ( this->*( eventCallback_iif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ] ); - break; - - case 2053 : - typedef void ( idClass::*eventCallback_fif_t )( const float, const int, const float ); - ( this->*( eventCallback_fif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ] ); - break; - - case 2054 : - typedef void ( idClass::*eventCallback_iff_t )( const int, const float, const float ); - ( this->*( eventCallback_iff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ] ); - break; - - case 2055 : - typedef void ( idClass::*eventCallback_fff_t )( const float, const float, const float ); - ( this->*( eventCallback_fff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ] ); - break; - - /******************************************************* - - 4 args - - *******************************************************/ - - case 4096 : - typedef void ( idClass::*eventCallback_iiii_t )( const int, const int, const int, const int ); - ( this->*( eventCallback_iiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); - break; - - case 4097 : - typedef void ( idClass::*eventCallback_fiii_t )( const float, const int, const int, const int ); - ( this->*( eventCallback_fiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); - break; - - case 4098 : - typedef void ( idClass::*eventCallback_ifii_t )( const int, const float, const int, const int ); - ( this->*( eventCallback_ifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ] ); - break; - - case 4099 : - typedef void ( idClass::*eventCallback_ffii_t )( const float, const float, const int, const int ); - ( this->*( eventCallback_ffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ] ); - break; - - case 4100 : - typedef void ( idClass::*eventCallback_iifi_t )( const int, const int, const float, const int ); - ( this->*( eventCallback_iifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); - break; - - case 4101 : - typedef void ( idClass::*eventCallback_fifi_t )( const float, const int, const float, const int ); - ( this->*( eventCallback_fifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); - break; - - case 4102 : - typedef void ( idClass::*eventCallback_iffi_t )( const int, const float, const float, const int ); - ( this->*( eventCallback_iffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); - break; - - case 4103 : - typedef void ( idClass::*eventCallback_fffi_t )( const float, const float, const float, const int ); - ( this->*( eventCallback_fffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ] ); - break; - - case 4104 : - typedef void ( idClass::*eventCallback_iiif_t )( const int, const int, const int, const float ); - ( this->*( eventCallback_iiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4105 : - typedef void ( idClass::*eventCallback_fiif_t )( const float, const int, const int, const float ); - ( this->*( eventCallback_fiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4106 : - typedef void ( idClass::*eventCallback_ifif_t )( const int, const float, const int, const float ); - ( this->*( eventCallback_ifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4107 : - typedef void ( idClass::*eventCallback_ffif_t )( const float, const float, const int, const float ); - ( this->*( eventCallback_ffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4108 : - typedef void ( idClass::*eventCallback_iiff_t )( const int, const int, const float, const float ); - ( this->*( eventCallback_iiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4109 : - typedef void ( idClass::*eventCallback_fiff_t )( const float, const int, const float, const float ); - ( this->*( eventCallback_fiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4110 : - typedef void ( idClass::*eventCallback_ifff_t )( const int, const float, const float, const float ); - ( this->*( eventCallback_ifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); - break; - - case 4111 : - typedef void ( idClass::*eventCallback_ffff_t )( const float, const float, const float, const float ); - ( this->*( eventCallback_ffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ] ); - break; - - /******************************************************* - - 5 args - - *******************************************************/ - - case 8192 : - typedef void ( idClass::*eventCallback_iiiii_t )( const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8193 : - typedef void ( idClass::*eventCallback_fiiii_t )( const float, const int, const int, const int, const int ); - ( this->*( eventCallback_fiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8194 : - typedef void ( idClass::*eventCallback_ifiii_t )( const int, const float, const int, const int, const int ); - ( this->*( eventCallback_ifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8195 : - typedef void ( idClass::*eventCallback_ffiii_t )( const float, const float, const int, const int, const int ); - ( this->*( eventCallback_ffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8196 : - typedef void ( idClass::*eventCallback_iifii_t )( const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8197 : - typedef void ( idClass::*eventCallback_fifii_t )( const float, const int, const float, const int, const int ); - ( this->*( eventCallback_fifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8198 : - typedef void ( idClass::*eventCallback_iffii_t )( const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8199 : - typedef void ( idClass::*eventCallback_fffii_t )( const float, const float, const float, const int, const int ); - ( this->*( eventCallback_fffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 8200 : - typedef void ( idClass::*eventCallback_iiifi_t )( const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8201 : - typedef void ( idClass::*eventCallback_fiifi_t )( const float, const int, const int, const float, const int ); - ( this->*( eventCallback_fiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8202 : - typedef void ( idClass::*eventCallback_ififi_t )( const int, const float, const int, const float, const int ); - ( this->*( eventCallback_ififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8203 : - typedef void ( idClass::*eventCallback_ffifi_t )( const float, const float, const int, const float, const int ); - ( this->*( eventCallback_ffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8204 : - typedef void ( idClass::*eventCallback_iiffi_t )( const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8205 : - typedef void ( idClass::*eventCallback_fiffi_t )( const float, const int, const float, const float, const int ); - ( this->*( eventCallback_fiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8206 : - typedef void ( idClass::*eventCallback_ifffi_t )( const int, const float, const float, const float, const int ); - ( this->*( eventCallback_ifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8207 : - typedef void ( idClass::*eventCallback_ffffi_t )( const float, const float, const float, const float, const int ); - ( this->*( eventCallback_ffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ] ); - break; - - case 8208 : - typedef void ( idClass::*eventCallback_iiiif_t )( const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8209 : - typedef void ( idClass::*eventCallback_fiiif_t )( const float, const int, const int, const int, const float ); - ( this->*( eventCallback_fiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8210 : - typedef void ( idClass::*eventCallback_ifiif_t )( const int, const float, const int, const int, const float ); - ( this->*( eventCallback_ifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8211 : - typedef void ( idClass::*eventCallback_ffiif_t )( const float, const float, const int, const int, const float ); - ( this->*( eventCallback_ffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8212 : - typedef void ( idClass::*eventCallback_iifif_t )( const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8213 : - typedef void ( idClass::*eventCallback_fifif_t )( const float, const int, const float, const int, const float ); - ( this->*( eventCallback_fifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8214 : - typedef void ( idClass::*eventCallback_iffif_t )( const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8215 : - typedef void ( idClass::*eventCallback_fffif_t )( const float, const float, const float, const int, const float ); - ( this->*( eventCallback_fffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8216 : - typedef void ( idClass::*eventCallback_iiiff_t )( const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8217 : - typedef void ( idClass::*eventCallback_fiiff_t )( const float, const int, const int, const float, const float ); - ( this->*( eventCallback_fiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8218 : - typedef void ( idClass::*eventCallback_ififf_t )( const int, const float, const int, const float, const float ); - ( this->*( eventCallback_ififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8219 : - typedef void ( idClass::*eventCallback_ffiff_t )( const float, const float, const int, const float, const float ); - ( this->*( eventCallback_ffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8220 : - typedef void ( idClass::*eventCallback_iifff_t )( const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8221 : - typedef void ( idClass::*eventCallback_fifff_t )( const float, const int, const float, const float, const float ); - ( this->*( eventCallback_fifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8222 : - typedef void ( idClass::*eventCallback_iffff_t )( const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - case 8223 : - typedef void ( idClass::*eventCallback_fffff_t )( const float, const float, const float, const float, const float ); - ( this->*( eventCallback_fffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ] ); - break; - - /******************************************************* - - 6 args - - *******************************************************/ - - case 16384 : - typedef void ( idClass::*eventCallback_iiiiii_t )( const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16385 : - typedef void ( idClass::*eventCallback_fiiiii_t )( const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_fiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16386 : - typedef void ( idClass::*eventCallback_ifiiii_t )( const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ifiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16387 : - typedef void ( idClass::*eventCallback_ffiiii_t )( const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16388 : - typedef void ( idClass::*eventCallback_iifiii_t )( const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_iifiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16389 : - typedef void ( idClass::*eventCallback_fifiii_t )( const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_fifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16390 : - typedef void ( idClass::*eventCallback_iffiii_t )( const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_iffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16391 : - typedef void ( idClass::*eventCallback_fffiii_t )( const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_fffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16392 : - typedef void ( idClass::*eventCallback_iiifii_t )( const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16393 : - typedef void ( idClass::*eventCallback_fiifii_t )( const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_fiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16394 : - typedef void ( idClass::*eventCallback_ififii_t )( const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ififii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16395 : - typedef void ( idClass::*eventCallback_ffifii_t )( const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16396 : - typedef void ( idClass::*eventCallback_iiffii_t )( const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iiffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16397 : - typedef void ( idClass::*eventCallback_fiffii_t )( const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_fiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16398 : - typedef void ( idClass::*eventCallback_ifffii_t )( const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ifffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16399 : - typedef void ( idClass::*eventCallback_ffffii_t )( const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 16400 : - typedef void ( idClass::*eventCallback_iiiifi_t )( const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16401 : - typedef void ( idClass::*eventCallback_fiiifi_t )( const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_fiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16402 : - typedef void ( idClass::*eventCallback_ifiifi_t )( const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ifiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16403 : - typedef void ( idClass::*eventCallback_ffiifi_t )( const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16404 : - typedef void ( idClass::*eventCallback_iififi_t )( const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_iififi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16405 : - typedef void ( idClass::*eventCallback_fififi_t )( const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_fififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16406 : - typedef void ( idClass::*eventCallback_iffifi_t )( const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_iffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16407 : - typedef void ( idClass::*eventCallback_fffifi_t )( const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_fffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16408 : - typedef void ( idClass::*eventCallback_iiiffi_t )( const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16409 : - typedef void ( idClass::*eventCallback_fiiffi_t )( const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_fiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16410 : - typedef void ( idClass::*eventCallback_ififfi_t )( const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ififfi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16411 : - typedef void ( idClass::*eventCallback_ffiffi_t )( const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16412 : - typedef void ( idClass::*eventCallback_iifffi_t )( const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_iifffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16413 : - typedef void ( idClass::*eventCallback_fifffi_t )( const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_fifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16414 : - typedef void ( idClass::*eventCallback_iffffi_t )( const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_iffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16415 : - typedef void ( idClass::*eventCallback_fffffi_t )( const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_fffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ] ); - break; - - case 16416 : - typedef void ( idClass::*eventCallback_iiiiif_t )( const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16417 : - typedef void ( idClass::*eventCallback_fiiiif_t )( const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_fiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16418 : - typedef void ( idClass::*eventCallback_ifiiif_t )( const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ifiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16419 : - typedef void ( idClass::*eventCallback_ffiiif_t )( const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16420 : - typedef void ( idClass::*eventCallback_iifiif_t )( const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_iifiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16421 : - typedef void ( idClass::*eventCallback_fifiif_t )( const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_fifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16422 : - typedef void ( idClass::*eventCallback_iffiif_t )( const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_iffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16423 : - typedef void ( idClass::*eventCallback_fffiif_t )( const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_fffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16424 : - typedef void ( idClass::*eventCallback_iiifif_t )( const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16425 : - typedef void ( idClass::*eventCallback_fiifif_t )( const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_fiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16426 : - typedef void ( idClass::*eventCallback_ififif_t )( const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ififif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16427 : - typedef void ( idClass::*eventCallback_ffifif_t )( const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16428 : - typedef void ( idClass::*eventCallback_iiffif_t )( const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iiffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16429 : - typedef void ( idClass::*eventCallback_fiffif_t )( const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_fiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16430 : - typedef void ( idClass::*eventCallback_ifffif_t )( const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ifffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16431 : - typedef void ( idClass::*eventCallback_ffffif_t )( const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16432 : - typedef void ( idClass::*eventCallback_iiiiff_t )( const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16433 : - typedef void ( idClass::*eventCallback_fiiiff_t )( const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_fiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16434 : - typedef void ( idClass::*eventCallback_ifiiff_t )( const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ifiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16435 : - typedef void ( idClass::*eventCallback_ffiiff_t )( const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16436 : - typedef void ( idClass::*eventCallback_iififf_t )( const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_iififf_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16437 : - typedef void ( idClass::*eventCallback_fififf_t )( const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_fififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16438 : - typedef void ( idClass::*eventCallback_iffiff_t )( const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_iffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16439 : - typedef void ( idClass::*eventCallback_fffiff_t )( const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_fffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16440 : - typedef void ( idClass::*eventCallback_iiifff_t )( const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16441 : - typedef void ( idClass::*eventCallback_fiifff_t )( const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_fiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16442 : - typedef void ( idClass::*eventCallback_ififff_t )( const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ififff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16443 : - typedef void ( idClass::*eventCallback_ffifff_t )( const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16444 : - typedef void ( idClass::*eventCallback_iiffff_t )( const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iiffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16445 : - typedef void ( idClass::*eventCallback_fiffff_t )( const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_fiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16446 : - typedef void ( idClass::*eventCallback_ifffff_t )( const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ifffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - case 16447 : - typedef void ( idClass::*eventCallback_ffffff_t )( const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ] ); - break; - - /******************************************************* - - 7 args - - *******************************************************/ - - case 32768 : - typedef void ( idClass::*eventCallback_iiiiiii_t )( const int, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iiiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32769 : - typedef void ( idClass::*eventCallback_fiiiiii_t )( const float, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_fiiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32770 : - typedef void ( idClass::*eventCallback_ifiiiii_t )( const int, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_ifiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32771 : - typedef void ( idClass::*eventCallback_ffiiiii_t )( const float, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_ffiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32772 : - typedef void ( idClass::*eventCallback_iifiiii_t )( const int, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_iifiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32773 : - typedef void ( idClass::*eventCallback_fifiiii_t )( const float, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_fifiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32774 : - typedef void ( idClass::*eventCallback_iffiiii_t )( const int, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_iffiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32775 : - typedef void ( idClass::*eventCallback_fffiiii_t )( const float, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_fffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32776 : - typedef void ( idClass::*eventCallback_iiifiii_t )( const int, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_iiifiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32777 : - typedef void ( idClass::*eventCallback_fiifiii_t )( const float, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_fiifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32778 : - typedef void ( idClass::*eventCallback_ififiii_t )( const int, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_ififiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32779 : - typedef void ( idClass::*eventCallback_ffifiii_t )( const float, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_ffifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32780 : - typedef void ( idClass::*eventCallback_iiffiii_t )( const int, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_iiffiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32781 : - typedef void ( idClass::*eventCallback_fiffiii_t )( const float, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_fiffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32782 : - typedef void ( idClass::*eventCallback_ifffiii_t )( const int, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_ifffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32783 : - typedef void ( idClass::*eventCallback_ffffiii_t )( const float, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_ffffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32784 : - typedef void ( idClass::*eventCallback_iiiifii_t )( const int, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iiiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32785 : - typedef void ( idClass::*eventCallback_fiiifii_t )( const float, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_fiiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32786 : - typedef void ( idClass::*eventCallback_ifiifii_t )( const int, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_ifiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32787 : - typedef void ( idClass::*eventCallback_ffiifii_t )( const float, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_ffiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32788 : - typedef void ( idClass::*eventCallback_iififii_t )( const int, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_iififii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32789 : - typedef void ( idClass::*eventCallback_fififii_t )( const float, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_fififii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32790 : - typedef void ( idClass::*eventCallback_iffifii_t )( const int, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_iffifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32791 : - typedef void ( idClass::*eventCallback_fffifii_t )( const float, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_fffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32792 : - typedef void ( idClass::*eventCallback_iiiffii_t )( const int, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iiiffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32793 : - typedef void ( idClass::*eventCallback_fiiffii_t )( const float, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_fiiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32794 : - typedef void ( idClass::*eventCallback_ififfii_t )( const int, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_ififfii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32795 : - typedef void ( idClass::*eventCallback_ffiffii_t )( const float, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_ffiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32796 : - typedef void ( idClass::*eventCallback_iifffii_t )( const int, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_iifffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32797 : - typedef void ( idClass::*eventCallback_fifffii_t )( const float, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_fifffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32798 : - typedef void ( idClass::*eventCallback_iffffii_t )( const int, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_iffffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32799 : - typedef void ( idClass::*eventCallback_fffffii_t )( const float, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_fffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 32800 : - typedef void ( idClass::*eventCallback_iiiiifi_t )( const int, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iiiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32801 : - typedef void ( idClass::*eventCallback_fiiiifi_t )( const float, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_fiiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32802 : - typedef void ( idClass::*eventCallback_ifiiifi_t )( const int, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_ifiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32803 : - typedef void ( idClass::*eventCallback_ffiiifi_t )( const float, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_ffiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32804 : - typedef void ( idClass::*eventCallback_iifiifi_t )( const int, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_iifiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32805 : - typedef void ( idClass::*eventCallback_fifiifi_t )( const float, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_fifiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32806 : - typedef void ( idClass::*eventCallback_iffiifi_t )( const int, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_iffiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32807 : - typedef void ( idClass::*eventCallback_fffiifi_t )( const float, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_fffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32808 : - typedef void ( idClass::*eventCallback_iiififi_t )( const int, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_iiififi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32809 : - typedef void ( idClass::*eventCallback_fiififi_t )( const float, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_fiififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32810 : - typedef void ( idClass::*eventCallback_ifififi_t )( const int, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_ifififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32811 : - typedef void ( idClass::*eventCallback_ffififi_t )( const float, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_ffififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32812 : - typedef void ( idClass::*eventCallback_iiffifi_t )( const int, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_iiffifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32813 : - typedef void ( idClass::*eventCallback_fiffifi_t )( const float, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_fiffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32814 : - typedef void ( idClass::*eventCallback_ifffifi_t )( const int, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_ifffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32815 : - typedef void ( idClass::*eventCallback_ffffifi_t )( const float, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_ffffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32816 : - typedef void ( idClass::*eventCallback_iiiiffi_t )( const int, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iiiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32817 : - typedef void ( idClass::*eventCallback_fiiiffi_t )( const float, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_fiiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32818 : - typedef void ( idClass::*eventCallback_ifiiffi_t )( const int, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_ifiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32819 : - typedef void ( idClass::*eventCallback_ffiiffi_t )( const float, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_ffiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32820 : - typedef void ( idClass::*eventCallback_iififfi_t )( const int, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_iififfi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32821 : - typedef void ( idClass::*eventCallback_fififfi_t )( const float, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_fififfi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32822 : - typedef void ( idClass::*eventCallback_iffiffi_t )( const int, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_iffiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32823 : - typedef void ( idClass::*eventCallback_fffiffi_t )( const float, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_fffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32824 : - typedef void ( idClass::*eventCallback_iiifffi_t )( const int, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_iiifffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32825 : - typedef void ( idClass::*eventCallback_fiifffi_t )( const float, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_fiifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32826 : - typedef void ( idClass::*eventCallback_ififffi_t )( const int, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_ififffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32827 : - typedef void ( idClass::*eventCallback_ffifffi_t )( const float, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_ffifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32828 : - typedef void ( idClass::*eventCallback_iiffffi_t )( const int, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_iiffffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32829 : - typedef void ( idClass::*eventCallback_fiffffi_t )( const float, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_fiffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32830 : - typedef void ( idClass::*eventCallback_ifffffi_t )( const int, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_ifffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32831 : - typedef void ( idClass::*eventCallback_ffffffi_t )( const float, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_ffffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ] ); - break; - - case 32832 : - typedef void ( idClass::*eventCallback_iiiiiif_t )( const int, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iiiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32833 : - typedef void ( idClass::*eventCallback_fiiiiif_t )( const float, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_fiiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32834 : - typedef void ( idClass::*eventCallback_ifiiiif_t )( const int, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_ifiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32835 : - typedef void ( idClass::*eventCallback_ffiiiif_t )( const float, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_ffiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32836 : - typedef void ( idClass::*eventCallback_iifiiif_t )( const int, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_iifiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32837 : - typedef void ( idClass::*eventCallback_fifiiif_t )( const float, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_fifiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32838 : - typedef void ( idClass::*eventCallback_iffiiif_t )( const int, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_iffiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32839 : - typedef void ( idClass::*eventCallback_fffiiif_t )( const float, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_fffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32840 : - typedef void ( idClass::*eventCallback_iiifiif_t )( const int, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_iiifiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32841 : - typedef void ( idClass::*eventCallback_fiifiif_t )( const float, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_fiifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32842 : - typedef void ( idClass::*eventCallback_ififiif_t )( const int, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_ififiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32843 : - typedef void ( idClass::*eventCallback_ffifiif_t )( const float, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_ffifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32844 : - typedef void ( idClass::*eventCallback_iiffiif_t )( const int, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_iiffiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32845 : - typedef void ( idClass::*eventCallback_fiffiif_t )( const float, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_fiffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32846 : - typedef void ( idClass::*eventCallback_ifffiif_t )( const int, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_ifffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32847 : - typedef void ( idClass::*eventCallback_ffffiif_t )( const float, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_ffffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32848 : - typedef void ( idClass::*eventCallback_iiiifif_t )( const int, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iiiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32849 : - typedef void ( idClass::*eventCallback_fiiifif_t )( const float, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_fiiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32850 : - typedef void ( idClass::*eventCallback_ifiifif_t )( const int, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_ifiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32851 : - typedef void ( idClass::*eventCallback_ffiifif_t )( const float, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_ffiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32852 : - typedef void ( idClass::*eventCallback_iififif_t )( const int, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_iififif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32853 : - typedef void ( idClass::*eventCallback_fififif_t )( const float, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_fififif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32854 : - typedef void ( idClass::*eventCallback_iffifif_t )( const int, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_iffifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32855 : - typedef void ( idClass::*eventCallback_fffifif_t )( const float, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_fffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32856 : - typedef void ( idClass::*eventCallback_iiiffif_t )( const int, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iiiffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32857 : - typedef void ( idClass::*eventCallback_fiiffif_t )( const float, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_fiiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32858 : - typedef void ( idClass::*eventCallback_ififfif_t )( const int, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_ififfif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32859 : - typedef void ( idClass::*eventCallback_ffiffif_t )( const float, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_ffiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32860 : - typedef void ( idClass::*eventCallback_iifffif_t )( const int, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_iifffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32861 : - typedef void ( idClass::*eventCallback_fifffif_t )( const float, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_fifffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32862 : - typedef void ( idClass::*eventCallback_iffffif_t )( const int, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_iffffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32863 : - typedef void ( idClass::*eventCallback_fffffif_t )( const float, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_fffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32864 : - typedef void ( idClass::*eventCallback_iiiiiff_t )( const int, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iiiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32865 : - typedef void ( idClass::*eventCallback_fiiiiff_t )( const float, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_fiiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32866 : - typedef void ( idClass::*eventCallback_ifiiiff_t )( const int, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_ifiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32867 : - typedef void ( idClass::*eventCallback_ffiiiff_t )( const float, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_ffiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32868 : - typedef void ( idClass::*eventCallback_iifiiff_t )( const int, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_iifiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32869 : - typedef void ( idClass::*eventCallback_fifiiff_t )( const float, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_fifiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32870 : - typedef void ( idClass::*eventCallback_iffiiff_t )( const int, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_iffiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32871 : - typedef void ( idClass::*eventCallback_fffiiff_t )( const float, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_fffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32872 : - typedef void ( idClass::*eventCallback_iiififf_t )( const int, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_iiififf_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32873 : - typedef void ( idClass::*eventCallback_fiififf_t )( const float, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_fiififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32874 : - typedef void ( idClass::*eventCallback_ifififf_t )( const int, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_ifififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32875 : - typedef void ( idClass::*eventCallback_ffififf_t )( const float, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_ffififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32876 : - typedef void ( idClass::*eventCallback_iiffiff_t )( const int, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_iiffiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32877 : - typedef void ( idClass::*eventCallback_fiffiff_t )( const float, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_fiffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32878 : - typedef void ( idClass::*eventCallback_ifffiff_t )( const int, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_ifffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32879 : - typedef void ( idClass::*eventCallback_ffffiff_t )( const float, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_ffffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32880 : - typedef void ( idClass::*eventCallback_iiiifff_t )( const int, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iiiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32881 : - typedef void ( idClass::*eventCallback_fiiifff_t )( const float, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_fiiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32882 : - typedef void ( idClass::*eventCallback_ifiifff_t )( const int, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_ifiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32883 : - typedef void ( idClass::*eventCallback_ffiifff_t )( const float, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_ffiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32884 : - typedef void ( idClass::*eventCallback_iififff_t )( const int, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_iififff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32885 : - typedef void ( idClass::*eventCallback_fififff_t )( const float, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_fififff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32886 : - typedef void ( idClass::*eventCallback_iffifff_t )( const int, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_iffifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32887 : - typedef void ( idClass::*eventCallback_fffifff_t )( const float, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_fffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32888 : - typedef void ( idClass::*eventCallback_iiiffff_t )( const int, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iiiffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32889 : - typedef void ( idClass::*eventCallback_fiiffff_t )( const float, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_fiiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32890 : - typedef void ( idClass::*eventCallback_ififfff_t )( const int, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_ififfff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32891 : - typedef void ( idClass::*eventCallback_ffiffff_t )( const float, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_ffiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32892 : - typedef void ( idClass::*eventCallback_iifffff_t )( const int, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_iifffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32893 : - typedef void ( idClass::*eventCallback_fifffff_t )( const float, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_fifffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32894 : - typedef void ( idClass::*eventCallback_iffffff_t )( const int, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_iffffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - case 32895 : - typedef void ( idClass::*eventCallback_fffffff_t )( const float, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_fffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ] ); - break; - - /******************************************************* - - 8 args - - *******************************************************/ - - case 65536 : - typedef void ( idClass::*eventCallback_iiiiiiii_t )( const int, const int, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iiiiiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65537 : - typedef void ( idClass::*eventCallback_fiiiiiii_t )( const float, const int, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_fiiiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65538 : - typedef void ( idClass::*eventCallback_ifiiiiii_t )( const int, const float, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_ifiiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65539 : - typedef void ( idClass::*eventCallback_ffiiiiii_t )( const float, const float, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_ffiiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65540 : - typedef void ( idClass::*eventCallback_iifiiiii_t )( const int, const int, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iifiiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65541 : - typedef void ( idClass::*eventCallback_fifiiiii_t )( const float, const int, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_fifiiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65542 : - typedef void ( idClass::*eventCallback_iffiiiii_t )( const int, const float, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_iffiiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65543 : - typedef void ( idClass::*eventCallback_fffiiiii_t )( const float, const float, const float, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_fffiiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65544 : - typedef void ( idClass::*eventCallback_iiifiiii_t )( const int, const int, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_iiifiiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65545 : - typedef void ( idClass::*eventCallback_fiifiiii_t )( const float, const int, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_fiifiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65546 : - typedef void ( idClass::*eventCallback_ififiiii_t )( const int, const float, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ififiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65547 : - typedef void ( idClass::*eventCallback_ffifiiii_t )( const float, const float, const int, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ffifiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65548 : - typedef void ( idClass::*eventCallback_iiffiiii_t )( const int, const int, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_iiffiiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65549 : - typedef void ( idClass::*eventCallback_fiffiiii_t )( const float, const int, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_fiffiiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65550 : - typedef void ( idClass::*eventCallback_ifffiiii_t )( const int, const float, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ifffiiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65551 : - typedef void ( idClass::*eventCallback_ffffiiii_t )( const float, const float, const float, const float, const int, const int, const int, const int ); - ( this->*( eventCallback_ffffiiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65552 : - typedef void ( idClass::*eventCallback_iiiifiii_t )( const int, const int, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_iiiifiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65553 : - typedef void ( idClass::*eventCallback_fiiifiii_t )( const float, const int, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_fiiifiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65554 : - typedef void ( idClass::*eventCallback_ifiifiii_t )( const int, const float, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_ifiifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65555 : - typedef void ( idClass::*eventCallback_ffiifiii_t )( const float, const float, const int, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_ffiifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65556 : - typedef void ( idClass::*eventCallback_iififiii_t )( const int, const int, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_iififiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65557 : - typedef void ( idClass::*eventCallback_fififiii_t )( const float, const int, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_fififiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65558 : - typedef void ( idClass::*eventCallback_iffifiii_t )( const int, const float, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_iffifiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65559 : - typedef void ( idClass::*eventCallback_fffifiii_t )( const float, const float, const float, const int, const float, const int, const int, const int ); - ( this->*( eventCallback_fffifiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65560 : - typedef void ( idClass::*eventCallback_iiiffiii_t )( const int, const int, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_iiiffiii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65561 : - typedef void ( idClass::*eventCallback_fiiffiii_t )( const float, const int, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_fiiffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65562 : - typedef void ( idClass::*eventCallback_ififfiii_t )( const int, const float, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_ififfiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65563 : - typedef void ( idClass::*eventCallback_ffiffiii_t )( const float, const float, const int, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_ffiffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65564 : - typedef void ( idClass::*eventCallback_iifffiii_t )( const int, const int, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_iifffiii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65565 : - typedef void ( idClass::*eventCallback_fifffiii_t )( const float, const int, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_fifffiii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65566 : - typedef void ( idClass::*eventCallback_iffffiii_t )( const int, const float, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_iffffiii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65567 : - typedef void ( idClass::*eventCallback_fffffiii_t )( const float, const float, const float, const float, const float, const int, const int, const int ); - ( this->*( eventCallback_fffffiii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65568 : - typedef void ( idClass::*eventCallback_iiiiifii_t )( const int, const int, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iiiiifii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65569 : - typedef void ( idClass::*eventCallback_fiiiifii_t )( const float, const int, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_fiiiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65570 : - typedef void ( idClass::*eventCallback_ifiiifii_t )( const int, const float, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_ifiiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65571 : - typedef void ( idClass::*eventCallback_ffiiifii_t )( const float, const float, const int, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_ffiiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65572 : - typedef void ( idClass::*eventCallback_iifiifii_t )( const int, const int, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iifiifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65573 : - typedef void ( idClass::*eventCallback_fifiifii_t )( const float, const int, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_fifiifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65574 : - typedef void ( idClass::*eventCallback_iffiifii_t )( const int, const float, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_iffiifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65575 : - typedef void ( idClass::*eventCallback_fffiifii_t )( const float, const float, const float, const int, const int, const float, const int, const int ); - ( this->*( eventCallback_fffiifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65576 : - typedef void ( idClass::*eventCallback_iiififii_t )( const int, const int, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_iiififii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65577 : - typedef void ( idClass::*eventCallback_fiififii_t )( const float, const int, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_fiififii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65578 : - typedef void ( idClass::*eventCallback_ifififii_t )( const int, const float, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ifififii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65579 : - typedef void ( idClass::*eventCallback_ffififii_t )( const float, const float, const int, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ffififii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65580 : - typedef void ( idClass::*eventCallback_iiffifii_t )( const int, const int, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_iiffifii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65581 : - typedef void ( idClass::*eventCallback_fiffifii_t )( const float, const int, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_fiffifii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65582 : - typedef void ( idClass::*eventCallback_ifffifii_t )( const int, const float, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ifffifii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65583 : - typedef void ( idClass::*eventCallback_ffffifii_t )( const float, const float, const float, const float, const int, const float, const int, const int ); - ( this->*( eventCallback_ffffifii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65584 : - typedef void ( idClass::*eventCallback_iiiiffii_t )( const int, const int, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iiiiffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65585 : - typedef void ( idClass::*eventCallback_fiiiffii_t )( const float, const int, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_fiiiffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65586 : - typedef void ( idClass::*eventCallback_ifiiffii_t )( const int, const float, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_ifiiffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65587 : - typedef void ( idClass::*eventCallback_ffiiffii_t )( const float, const float, const int, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_ffiiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65588 : - typedef void ( idClass::*eventCallback_iififfii_t )( const int, const int, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iififfii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65589 : - typedef void ( idClass::*eventCallback_fififfii_t )( const float, const int, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_fififfii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65590 : - typedef void ( idClass::*eventCallback_iffiffii_t )( const int, const float, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_iffiffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65591 : - typedef void ( idClass::*eventCallback_fffiffii_t )( const float, const float, const float, const int, const float, const float, const int, const int ); - ( this->*( eventCallback_fffiffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65592 : - typedef void ( idClass::*eventCallback_iiifffii_t )( const int, const int, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_iiifffii_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65593 : - typedef void ( idClass::*eventCallback_fiifffii_t )( const float, const int, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_fiifffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65594 : - typedef void ( idClass::*eventCallback_ififffii_t )( const int, const float, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ififffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65595 : - typedef void ( idClass::*eventCallback_ffifffii_t )( const float, const float, const int, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ffifffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65596 : - typedef void ( idClass::*eventCallback_iiffffii_t )( const int, const int, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_iiffffii_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65597 : - typedef void ( idClass::*eventCallback_fiffffii_t )( const float, const int, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_fiffffii_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65598 : - typedef void ( idClass::*eventCallback_ifffffii_t )( const int, const float, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ifffffii_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65599 : - typedef void ( idClass::*eventCallback_ffffffii_t )( const float, const float, const float, const float, const float, const float, const int, const int ); - ( this->*( eventCallback_ffffffii_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - case 65600 : - typedef void ( idClass::*eventCallback_iiiiiifi_t )( const int, const int, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iiiiiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65601 : - typedef void ( idClass::*eventCallback_fiiiiifi_t )( const float, const int, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_fiiiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65602 : - typedef void ( idClass::*eventCallback_ifiiiifi_t )( const int, const float, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_ifiiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65603 : - typedef void ( idClass::*eventCallback_ffiiiifi_t )( const float, const float, const int, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_ffiiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65604 : - typedef void ( idClass::*eventCallback_iifiiifi_t )( const int, const int, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iifiiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65605 : - typedef void ( idClass::*eventCallback_fifiiifi_t )( const float, const int, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_fifiiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65606 : - typedef void ( idClass::*eventCallback_iffiiifi_t )( const int, const float, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_iffiiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65607 : - typedef void ( idClass::*eventCallback_fffiiifi_t )( const float, const float, const float, const int, const int, const int, const float, const int ); - ( this->*( eventCallback_fffiiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65608 : - typedef void ( idClass::*eventCallback_iiifiifi_t )( const int, const int, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_iiifiifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65609 : - typedef void ( idClass::*eventCallback_fiifiifi_t )( const float, const int, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_fiifiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65610 : - typedef void ( idClass::*eventCallback_ififiifi_t )( const int, const float, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ififiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65611 : - typedef void ( idClass::*eventCallback_ffifiifi_t )( const float, const float, const int, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ffifiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65612 : - typedef void ( idClass::*eventCallback_iiffiifi_t )( const int, const int, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_iiffiifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65613 : - typedef void ( idClass::*eventCallback_fiffiifi_t )( const float, const int, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_fiffiifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65614 : - typedef void ( idClass::*eventCallback_ifffiifi_t )( const int, const float, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ifffiifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65615 : - typedef void ( idClass::*eventCallback_ffffiifi_t )( const float, const float, const float, const float, const int, const int, const float, const int ); - ( this->*( eventCallback_ffffiifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65616 : - typedef void ( idClass::*eventCallback_iiiififi_t )( const int, const int, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_iiiififi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65617 : - typedef void ( idClass::*eventCallback_fiiififi_t )( const float, const int, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_fiiififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65618 : - typedef void ( idClass::*eventCallback_ifiififi_t )( const int, const float, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_ifiififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65619 : - typedef void ( idClass::*eventCallback_ffiififi_t )( const float, const float, const int, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_ffiififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65620 : - typedef void ( idClass::*eventCallback_iifififi_t )( const int, const int, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_iifififi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65621 : - typedef void ( idClass::*eventCallback_fifififi_t )( const float, const int, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_fifififi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65622 : - typedef void ( idClass::*eventCallback_iffififi_t )( const int, const float, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_iffififi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65623 : - typedef void ( idClass::*eventCallback_fffififi_t )( const float, const float, const float, const int, const float, const int, const float, const int ); - ( this->*( eventCallback_fffififi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65624 : - typedef void ( idClass::*eventCallback_iiiffifi_t )( const int, const int, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_iiiffifi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65625 : - typedef void ( idClass::*eventCallback_fiiffifi_t )( const float, const int, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_fiiffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65626 : - typedef void ( idClass::*eventCallback_ififfifi_t )( const int, const float, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_ififfifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65627 : - typedef void ( idClass::*eventCallback_ffiffifi_t )( const float, const float, const int, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_ffiffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65628 : - typedef void ( idClass::*eventCallback_iifffifi_t )( const int, const int, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_iifffifi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65629 : - typedef void ( idClass::*eventCallback_fifffifi_t )( const float, const int, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_fifffifi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65630 : - typedef void ( idClass::*eventCallback_iffffifi_t )( const int, const float, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_iffffifi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65631 : - typedef void ( idClass::*eventCallback_fffffifi_t )( const float, const float, const float, const float, const float, const int, const float, const int ); - ( this->*( eventCallback_fffffifi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65632 : - typedef void ( idClass::*eventCallback_iiiiiffi_t )( const int, const int, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iiiiiffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65633 : - typedef void ( idClass::*eventCallback_fiiiiffi_t )( const float, const int, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_fiiiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65634 : - typedef void ( idClass::*eventCallback_ifiiiffi_t )( const int, const float, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_ifiiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65635 : - typedef void ( idClass::*eventCallback_ffiiiffi_t )( const float, const float, const int, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_ffiiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65636 : - typedef void ( idClass::*eventCallback_iifiiffi_t )( const int, const int, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iifiiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65637 : - typedef void ( idClass::*eventCallback_fifiiffi_t )( const float, const int, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_fifiiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65638 : - typedef void ( idClass::*eventCallback_iffiiffi_t )( const int, const float, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_iffiiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65639 : - typedef void ( idClass::*eventCallback_fffiiffi_t )( const float, const float, const float, const int, const int, const float, const float, const int ); - ( this->*( eventCallback_fffiiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65640 : - typedef void ( idClass::*eventCallback_iiififfi_t )( const int, const int, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_iiififfi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65641 : - typedef void ( idClass::*eventCallback_fiififfi_t )( const float, const int, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_fiififfi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65642 : - typedef void ( idClass::*eventCallback_ifififfi_t )( const int, const float, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ifififfi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65643 : - typedef void ( idClass::*eventCallback_ffififfi_t )( const float, const float, const int, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ffififfi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65644 : - typedef void ( idClass::*eventCallback_iiffiffi_t )( const int, const int, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_iiffiffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65645 : - typedef void ( idClass::*eventCallback_fiffiffi_t )( const float, const int, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_fiffiffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65646 : - typedef void ( idClass::*eventCallback_ifffiffi_t )( const int, const float, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ifffiffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65647 : - typedef void ( idClass::*eventCallback_ffffiffi_t )( const float, const float, const float, const float, const int, const float, const float, const int ); - ( this->*( eventCallback_ffffiffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65648 : - typedef void ( idClass::*eventCallback_iiiifffi_t )( const int, const int, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_iiiifffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65649 : - typedef void ( idClass::*eventCallback_fiiifffi_t )( const float, const int, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_fiiifffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65650 : - typedef void ( idClass::*eventCallback_ifiifffi_t )( const int, const float, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_ifiifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65651 : - typedef void ( idClass::*eventCallback_ffiifffi_t )( const float, const float, const int, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_ffiifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65652 : - typedef void ( idClass::*eventCallback_iififffi_t )( const int, const int, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_iififffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65653 : - typedef void ( idClass::*eventCallback_fififffi_t )( const float, const int, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_fififffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65654 : - typedef void ( idClass::*eventCallback_iffifffi_t )( const int, const float, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_iffifffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65655 : - typedef void ( idClass::*eventCallback_fffifffi_t )( const float, const float, const float, const int, const float, const float, const float, const int ); - ( this->*( eventCallback_fffifffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65656 : - typedef void ( idClass::*eventCallback_iiiffffi_t )( const int, const int, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_iiiffffi_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65657 : - typedef void ( idClass::*eventCallback_fiiffffi_t )( const float, const int, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_fiiffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65658 : - typedef void ( idClass::*eventCallback_ififfffi_t )( const int, const float, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_ififfffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65659 : - typedef void ( idClass::*eventCallback_ffiffffi_t )( const float, const float, const int, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_ffiffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65660 : - typedef void ( idClass::*eventCallback_iifffffi_t )( const int, const int, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_iifffffi_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65661 : - typedef void ( idClass::*eventCallback_fifffffi_t )( const float, const int, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_fifffffi_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65662 : - typedef void ( idClass::*eventCallback_iffffffi_t )( const int, const float, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_iffffffi_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65663 : - typedef void ( idClass::*eventCallback_fffffffi_t )( const float, const float, const float, const float, const float, const float, const float, const int ); - ( this->*( eventCallback_fffffffi_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], data[ 7 ] ); - break; - - case 65664 : - typedef void ( idClass::*eventCallback_iiiiiiif_t )( const int, const int, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iiiiiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65665 : - typedef void ( idClass::*eventCallback_fiiiiiif_t )( const float, const int, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_fiiiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65666 : - typedef void ( idClass::*eventCallback_ifiiiiif_t )( const int, const float, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_ifiiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65667 : - typedef void ( idClass::*eventCallback_ffiiiiif_t )( const float, const float, const int, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_ffiiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65668 : - typedef void ( idClass::*eventCallback_iifiiiif_t )( const int, const int, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iifiiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65669 : - typedef void ( idClass::*eventCallback_fifiiiif_t )( const float, const int, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_fifiiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65670 : - typedef void ( idClass::*eventCallback_iffiiiif_t )( const int, const float, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_iffiiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65671 : - typedef void ( idClass::*eventCallback_fffiiiif_t )( const float, const float, const float, const int, const int, const int, const int, const float ); - ( this->*( eventCallback_fffiiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65672 : - typedef void ( idClass::*eventCallback_iiifiiif_t )( const int, const int, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_iiifiiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65673 : - typedef void ( idClass::*eventCallback_fiifiiif_t )( const float, const int, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_fiifiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65674 : - typedef void ( idClass::*eventCallback_ififiiif_t )( const int, const float, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ififiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65675 : - typedef void ( idClass::*eventCallback_ffifiiif_t )( const float, const float, const int, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ffifiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65676 : - typedef void ( idClass::*eventCallback_iiffiiif_t )( const int, const int, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_iiffiiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65677 : - typedef void ( idClass::*eventCallback_fiffiiif_t )( const float, const int, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_fiffiiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65678 : - typedef void ( idClass::*eventCallback_ifffiiif_t )( const int, const float, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ifffiiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65679 : - typedef void ( idClass::*eventCallback_ffffiiif_t )( const float, const float, const float, const float, const int, const int, const int, const float ); - ( this->*( eventCallback_ffffiiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65680 : - typedef void ( idClass::*eventCallback_iiiifiif_t )( const int, const int, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_iiiifiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65681 : - typedef void ( idClass::*eventCallback_fiiifiif_t )( const float, const int, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_fiiifiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65682 : - typedef void ( idClass::*eventCallback_ifiifiif_t )( const int, const float, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_ifiifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65683 : - typedef void ( idClass::*eventCallback_ffiifiif_t )( const float, const float, const int, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_ffiifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65684 : - typedef void ( idClass::*eventCallback_iififiif_t )( const int, const int, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_iififiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65685 : - typedef void ( idClass::*eventCallback_fififiif_t )( const float, const int, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_fififiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65686 : - typedef void ( idClass::*eventCallback_iffifiif_t )( const int, const float, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_iffifiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65687 : - typedef void ( idClass::*eventCallback_fffifiif_t )( const float, const float, const float, const int, const float, const int, const int, const float ); - ( this->*( eventCallback_fffifiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65688 : - typedef void ( idClass::*eventCallback_iiiffiif_t )( const int, const int, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_iiiffiif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65689 : - typedef void ( idClass::*eventCallback_fiiffiif_t )( const float, const int, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_fiiffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65690 : - typedef void ( idClass::*eventCallback_ififfiif_t )( const int, const float, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_ififfiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65691 : - typedef void ( idClass::*eventCallback_ffiffiif_t )( const float, const float, const int, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_ffiffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65692 : - typedef void ( idClass::*eventCallback_iifffiif_t )( const int, const int, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_iifffiif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65693 : - typedef void ( idClass::*eventCallback_fifffiif_t )( const float, const int, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_fifffiif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65694 : - typedef void ( idClass::*eventCallback_iffffiif_t )( const int, const float, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_iffffiif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65695 : - typedef void ( idClass::*eventCallback_fffffiif_t )( const float, const float, const float, const float, const float, const int, const int, const float ); - ( this->*( eventCallback_fffffiif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65696 : - typedef void ( idClass::*eventCallback_iiiiifif_t )( const int, const int, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iiiiifif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65697 : - typedef void ( idClass::*eventCallback_fiiiifif_t )( const float, const int, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_fiiiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65698 : - typedef void ( idClass::*eventCallback_ifiiifif_t )( const int, const float, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_ifiiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65699 : - typedef void ( idClass::*eventCallback_ffiiifif_t )( const float, const float, const int, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_ffiiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65700 : - typedef void ( idClass::*eventCallback_iifiifif_t )( const int, const int, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iifiifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65701 : - typedef void ( idClass::*eventCallback_fifiifif_t )( const float, const int, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_fifiifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65702 : - typedef void ( idClass::*eventCallback_iffiifif_t )( const int, const float, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_iffiifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65703 : - typedef void ( idClass::*eventCallback_fffiifif_t )( const float, const float, const float, const int, const int, const float, const int, const float ); - ( this->*( eventCallback_fffiifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65704 : - typedef void ( idClass::*eventCallback_iiififif_t )( const int, const int, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_iiififif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65705 : - typedef void ( idClass::*eventCallback_fiififif_t )( const float, const int, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_fiififif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65706 : - typedef void ( idClass::*eventCallback_ifififif_t )( const int, const float, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ifififif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65707 : - typedef void ( idClass::*eventCallback_ffififif_t )( const float, const float, const int, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ffififif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65708 : - typedef void ( idClass::*eventCallback_iiffifif_t )( const int, const int, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_iiffifif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65709 : - typedef void ( idClass::*eventCallback_fiffifif_t )( const float, const int, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_fiffifif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65710 : - typedef void ( idClass::*eventCallback_ifffifif_t )( const int, const float, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ifffifif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65711 : - typedef void ( idClass::*eventCallback_ffffifif_t )( const float, const float, const float, const float, const int, const float, const int, const float ); - ( this->*( eventCallback_ffffifif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65712 : - typedef void ( idClass::*eventCallback_iiiiffif_t )( const int, const int, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iiiiffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65713 : - typedef void ( idClass::*eventCallback_fiiiffif_t )( const float, const int, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_fiiiffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65714 : - typedef void ( idClass::*eventCallback_ifiiffif_t )( const int, const float, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_ifiiffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65715 : - typedef void ( idClass::*eventCallback_ffiiffif_t )( const float, const float, const int, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_ffiiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65716 : - typedef void ( idClass::*eventCallback_iififfif_t )( const int, const int, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iififfif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65717 : - typedef void ( idClass::*eventCallback_fififfif_t )( const float, const int, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_fififfif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65718 : - typedef void ( idClass::*eventCallback_iffiffif_t )( const int, const float, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_iffiffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65719 : - typedef void ( idClass::*eventCallback_fffiffif_t )( const float, const float, const float, const int, const float, const float, const int, const float ); - ( this->*( eventCallback_fffiffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65720 : - typedef void ( idClass::*eventCallback_iiifffif_t )( const int, const int, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_iiifffif_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65721 : - typedef void ( idClass::*eventCallback_fiifffif_t )( const float, const int, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_fiifffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65722 : - typedef void ( idClass::*eventCallback_ififffif_t )( const int, const float, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ififffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65723 : - typedef void ( idClass::*eventCallback_ffifffif_t )( const float, const float, const int, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ffifffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65724 : - typedef void ( idClass::*eventCallback_iiffffif_t )( const int, const int, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_iiffffif_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65725 : - typedef void ( idClass::*eventCallback_fiffffif_t )( const float, const int, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_fiffffif_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65726 : - typedef void ( idClass::*eventCallback_ifffffif_t )( const int, const float, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ifffffif_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65727 : - typedef void ( idClass::*eventCallback_ffffffif_t )( const float, const float, const float, const float, const float, const float, const int, const float ); - ( this->*( eventCallback_ffffffif_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65728 : - typedef void ( idClass::*eventCallback_iiiiiiff_t )( const int, const int, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iiiiiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65729 : - typedef void ( idClass::*eventCallback_fiiiiiff_t )( const float, const int, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_fiiiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65730 : - typedef void ( idClass::*eventCallback_ifiiiiff_t )( const int, const float, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_ifiiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65731 : - typedef void ( idClass::*eventCallback_ffiiiiff_t )( const float, const float, const int, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_ffiiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65732 : - typedef void ( idClass::*eventCallback_iifiiiff_t )( const int, const int, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iifiiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65733 : - typedef void ( idClass::*eventCallback_fifiiiff_t )( const float, const int, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_fifiiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65734 : - typedef void ( idClass::*eventCallback_iffiiiff_t )( const int, const float, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_iffiiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65735 : - typedef void ( idClass::*eventCallback_fffiiiff_t )( const float, const float, const float, const int, const int, const int, const float, const float ); - ( this->*( eventCallback_fffiiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65736 : - typedef void ( idClass::*eventCallback_iiifiiff_t )( const int, const int, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_iiifiiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65737 : - typedef void ( idClass::*eventCallback_fiifiiff_t )( const float, const int, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_fiifiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65738 : - typedef void ( idClass::*eventCallback_ififiiff_t )( const int, const float, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ififiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65739 : - typedef void ( idClass::*eventCallback_ffifiiff_t )( const float, const float, const int, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ffifiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65740 : - typedef void ( idClass::*eventCallback_iiffiiff_t )( const int, const int, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_iiffiiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65741 : - typedef void ( idClass::*eventCallback_fiffiiff_t )( const float, const int, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_fiffiiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65742 : - typedef void ( idClass::*eventCallback_ifffiiff_t )( const int, const float, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ifffiiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65743 : - typedef void ( idClass::*eventCallback_ffffiiff_t )( const float, const float, const float, const float, const int, const int, const float, const float ); - ( this->*( eventCallback_ffffiiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65744 : - typedef void ( idClass::*eventCallback_iiiififf_t )( const int, const int, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_iiiififf_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65745 : - typedef void ( idClass::*eventCallback_fiiififf_t )( const float, const int, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_fiiififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65746 : - typedef void ( idClass::*eventCallback_ifiififf_t )( const int, const float, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_ifiififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65747 : - typedef void ( idClass::*eventCallback_ffiififf_t )( const float, const float, const int, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_ffiififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65748 : - typedef void ( idClass::*eventCallback_iifififf_t )( const int, const int, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_iifififf_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65749 : - typedef void ( idClass::*eventCallback_fifififf_t )( const float, const int, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_fifififf_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65750 : - typedef void ( idClass::*eventCallback_iffififf_t )( const int, const float, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_iffififf_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65751 : - typedef void ( idClass::*eventCallback_fffififf_t )( const float, const float, const float, const int, const float, const int, const float, const float ); - ( this->*( eventCallback_fffififf_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65752 : - typedef void ( idClass::*eventCallback_iiiffiff_t )( const int, const int, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_iiiffiff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65753 : - typedef void ( idClass::*eventCallback_fiiffiff_t )( const float, const int, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_fiiffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65754 : - typedef void ( idClass::*eventCallback_ififfiff_t )( const int, const float, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_ififfiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65755 : - typedef void ( idClass::*eventCallback_ffiffiff_t )( const float, const float, const int, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_ffiffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65756 : - typedef void ( idClass::*eventCallback_iifffiff_t )( const int, const int, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_iifffiff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65757 : - typedef void ( idClass::*eventCallback_fifffiff_t )( const float, const int, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_fifffiff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65758 : - typedef void ( idClass::*eventCallback_iffffiff_t )( const int, const float, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_iffffiff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65759 : - typedef void ( idClass::*eventCallback_fffffiff_t )( const float, const float, const float, const float, const float, const int, const float, const float ); - ( this->*( eventCallback_fffffiff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65760 : - typedef void ( idClass::*eventCallback_iiiiifff_t )( const int, const int, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iiiiifff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65761 : - typedef void ( idClass::*eventCallback_fiiiifff_t )( const float, const int, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_fiiiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65762 : - typedef void ( idClass::*eventCallback_ifiiifff_t )( const int, const float, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_ifiiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65763 : - typedef void ( idClass::*eventCallback_ffiiifff_t )( const float, const float, const int, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_ffiiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65764 : - typedef void ( idClass::*eventCallback_iifiifff_t )( const int, const int, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iifiifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65765 : - typedef void ( idClass::*eventCallback_fifiifff_t )( const float, const int, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_fifiifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65766 : - typedef void ( idClass::*eventCallback_iffiifff_t )( const int, const float, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_iffiifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65767 : - typedef void ( idClass::*eventCallback_fffiifff_t )( const float, const float, const float, const int, const int, const float, const float, const float ); - ( this->*( eventCallback_fffiifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65768 : - typedef void ( idClass::*eventCallback_iiififff_t )( const int, const int, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_iiififff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65769 : - typedef void ( idClass::*eventCallback_fiififff_t )( const float, const int, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_fiififff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65770 : - typedef void ( idClass::*eventCallback_ifififff_t )( const int, const float, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ifififff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65771 : - typedef void ( idClass::*eventCallback_ffififff_t )( const float, const float, const int, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ffififff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65772 : - typedef void ( idClass::*eventCallback_iiffifff_t )( const int, const int, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_iiffifff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65773 : - typedef void ( idClass::*eventCallback_fiffifff_t )( const float, const int, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_fiffifff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65774 : - typedef void ( idClass::*eventCallback_ifffifff_t )( const int, const float, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ifffifff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65775 : - typedef void ( idClass::*eventCallback_ffffifff_t )( const float, const float, const float, const float, const int, const float, const float, const float ); - ( this->*( eventCallback_ffffifff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65776 : - typedef void ( idClass::*eventCallback_iiiiffff_t )( const int, const int, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iiiiffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65777 : - typedef void ( idClass::*eventCallback_fiiiffff_t )( const float, const int, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_fiiiffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65778 : - typedef void ( idClass::*eventCallback_ifiiffff_t )( const int, const float, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_ifiiffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65779 : - typedef void ( idClass::*eventCallback_ffiiffff_t )( const float, const float, const int, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_ffiiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65780 : - typedef void ( idClass::*eventCallback_iififfff_t )( const int, const int, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iififfff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65781 : - typedef void ( idClass::*eventCallback_fififfff_t )( const float, const int, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_fififfff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65782 : - typedef void ( idClass::*eventCallback_iffiffff_t )( const int, const float, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_iffiffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65783 : - typedef void ( idClass::*eventCallback_fffiffff_t )( const float, const float, const float, const int, const float, const float, const float, const float ); - ( this->*( eventCallback_fffiffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65784 : - typedef void ( idClass::*eventCallback_iiifffff_t )( const int, const int, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_iiifffff_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65785 : - typedef void ( idClass::*eventCallback_fiifffff_t )( const float, const int, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_fiifffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65786 : - typedef void ( idClass::*eventCallback_ififffff_t )( const int, const float, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ififffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65787 : - typedef void ( idClass::*eventCallback_ffifffff_t )( const float, const float, const int, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ffifffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65788 : - typedef void ( idClass::*eventCallback_iiffffff_t )( const int, const int, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_iiffffff_t )callback )( data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65789 : - typedef void ( idClass::*eventCallback_fiffffff_t )( const float, const int, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_fiffffff_t )callback )( *( float * )&data[ 0 ], data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65790 : - typedef void ( idClass::*eventCallback_ifffffff_t )( const int, const float, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ifffffff_t )callback )( data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - - case 65791 : - typedef void ( idClass::*eventCallback_ffffffff_t )( const float, const float, const float, const float, const float, const float, const float, const float ); - ( this->*( eventCallback_ffffffff_t )callback )( *( float * )&data[ 0 ], *( float * )&data[ 1 ], *( float * )&data[ 2 ], *( float * )&data[ 3 ], *( float * )&data[ 4 ], *( float * )&data[ 5 ], *( float * )&data[ 6 ], *( float * )&data[ 7 ] ); - break; - diff --git a/game/gamesys/class.cpp b/game/gamesys/class.cpp deleted file mode 100644 index e7d918d12..000000000 --- a/game/gamesys/class.cpp +++ /dev/null @@ -1,1071 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* - -Base class for all C++ objects. Provides fast run-time type checking and run-time -instancing of objects. - -*/ - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../DarkMod/Grabber.h" - -#include "typeinfo.h" - - -/*********************************************************************** - - idTypeInfo - -***********************************************************************/ - -// this is the head of a singly linked list of all the idTypes -static idTypeInfo *typelist = NULL; -static idHierarchy classHierarchy; -static int eventCallbackMemory = 0; - -/* -================ -idTypeInfo::idClassType() - -Constructor for class. Should only be called from CLASS_DECLARATION macro. -Handles linking class definition into class hierarchy. This should only happen -at startup as idTypeInfos are statically defined. Since static variables can be -initialized in any order, the constructor must handle the case that subclasses -are initialized before superclasses. -================ -*/ -idTypeInfo::idTypeInfo( const char *classname, const char *superclass, idEventFunc *eventCallbacks, idClass *( *CreateInstance )( void ), - void ( idClass::*Spawn )( void ), void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) ) { - - idTypeInfo *type; - idTypeInfo **insert; - - this->classname = classname; - this->superclass = superclass; - this->eventCallbacks = eventCallbacks; - this->eventMap = NULL; - this->Spawn = Spawn; - this->Save = Save; - this->Restore = Restore; - this->CreateInstance = CreateInstance; - this->super = idClass::GetClass( superclass ); - this->freeEventMap = false; - typeNum = 0; - lastChild = 0; - - // Check if any subclasses were initialized before their superclass - for( type = typelist; type != NULL; type = type->next ) { - if ( ( type->super == NULL ) && !idStr::Cmp( type->superclass, this->classname ) && - idStr::Cmp( type->classname, "idClass" ) ) { - type->super = this; - } - } - - // Insert sorted - for ( insert = &typelist; *insert; insert = &(*insert)->next ) { - assert( idStr::Cmp( classname, (*insert)->classname ) ); - if ( idStr::Cmp( classname, (*insert)->classname ) < 0 ) { - next = *insert; - *insert = this; - break; - } - } - if ( !*insert ) { - *insert = this; - next = NULL; - } -} - -/* -================ -idTypeInfo::~idTypeInfo -================ -*/ -idTypeInfo::~idTypeInfo() { - Shutdown(); -} - -/* -================ -idTypeInfo::Init - -Initializes the event callback table for the class. Creates a -table for fast lookups of event functions. Should only be called once. -================ -*/ -void idTypeInfo::Init( void ) { - idTypeInfo *c; - idEventFunc *def; - int ev; - int i; - bool *set; - int num; - - if ( eventMap ) { - // we've already been initialized by a subclass - return; - } - - // make sure our superclass is initialized first - if ( super && !super->eventMap ) { - super->Init(); - } - - // add to our node hierarchy - if ( super ) { - node.ParentTo( super->node ); - } else { - node.ParentTo( classHierarchy ); - } - node.SetOwner( this ); - - // keep track of the number of children below each class - for( c = super; c != NULL; c = c->super ) { - c->lastChild++; - } - - // if we're not adding any new event callbacks, we can just use our superclass's table - if ( ( !eventCallbacks || !eventCallbacks->event ) && super ) { - eventMap = super->eventMap; - return; - } - - // set a flag so we know to delete the eventMap table - freeEventMap = true; - - // Allocate our new table. It has to have as many entries as there - // are events. NOTE: could save some space by keeping track of the maximum - // event that the class responds to and doing range checking. - num = idEventDef::NumEventCommands(); - eventMap = new eventCallback_t[ num ]; - memset( eventMap, 0, sizeof( eventCallback_t ) * num ); - eventCallbackMemory += sizeof( eventCallback_t ) * num; - - // allocate temporary memory for flags so that the subclass's event callbacks - // override the superclass's event callback - set = new bool[ num ]; - memset( set, 0, sizeof( bool ) * num ); - - // go through the inheritence order and copies the event callback function into - // a list indexed by the event number. This allows fast lookups of - // event functions. - for( c = this; c != NULL; c = c->super ) { - def = c->eventCallbacks; - if ( !def ) { - continue; - } - - // go through each entry until we hit the NULL terminator - for( i = 0; def[ i ].event != NULL; i++ ) { - ev = def[ i ].event->GetEventNum(); - - if ( set[ ev ] ) { - continue; - } - set[ ev ] = true; - eventMap[ ev ] = def[ i ].function; - } - } - - delete[] set; -} - -/* -================ -idTypeInfo::Shutdown - -Should only be called when DLL or EXE is being shutdown. -Although it cleans up any allocated memory, it doesn't bother to remove itself -from the class list since the program is shutting down. -================ -*/ -void idTypeInfo::Shutdown() { - // free up the memory used for event lookups - if ( eventMap ) { - if ( freeEventMap ) { - delete[] eventMap; - } - eventMap = NULL; - } - typeNum = 0; - lastChild = 0; -} - - -/*********************************************************************** - - idClass - -***********************************************************************/ - -const idEventDef EV_Remove( "", NULL ); -const idEventDef EV_SafeRemove( "remove", NULL ); - -ABSTRACT_DECLARATION( NULL, idClass ) - EVENT( EV_Remove, idClass::Event_Remove ) - EVENT( EV_SafeRemove, idClass::Event_SafeRemove ) -END_CLASS - -// alphabetical order -idList idClass::types; -// typenum order -idList idClass::typenums; - -bool idClass::initialized = false; -int idClass::typeNumBits = 0; -int idClass::memused = 0; -int idClass::numobjects = 0; - -/* -================ -idClass::CallSpawn -================ -*/ -void idClass::CallSpawn( void ) { - idTypeInfo *type; - - type = GetType(); - CallSpawnFunc( type ); -} - -/* -================ -idClass::CallSpawnFunc -================ -*/ -classSpawnFunc_t idClass::CallSpawnFunc( idTypeInfo *cls ) { - classSpawnFunc_t func; - - if ( cls->super ) { - func = CallSpawnFunc( cls->super ); - if ( func == cls->Spawn ) { - // don't call the same function twice in a row. - // this can happen when subclasses don't have their own spawn function. - return func; - } - } - - ( this->*cls->Spawn )(); - - return cls->Spawn; -} - -/* -================ -idClass::FindUninitializedMemory -================ -*/ -void idClass::FindUninitializedMemory( void ) { -#ifdef ID_DEBUG_UNINITIALIZED_MEMORY - unsigned long *ptr = ( ( unsigned long * )this ) - 1; - int size = *ptr; - assert( ( size & 3 ) == 0 ); - size >>= 2; - for ( int i = 0; i < size; i++ ) { - if ( ptr[i] == 0xcdcdcdcd ) { - const char *varName = GetTypeVariableName( GetClassname(), i << 2 ); - gameLocal.Warning( "type '%s' has uninitialized variable %s (offset %d)", GetClassname(), varName, i << 2 ); - } - } -#endif -} - -/* -================ -idClass::Spawn -================ -*/ -void idClass::Spawn( void ) { -} - -/* -================ -idClass::~idClass - -Destructor for object. Cancels any events that depend on this object. -================ -*/ -idClass::~idClass() { - idEvent::CancelEvents( this ); -} - -/* -================ -idClass::DisplayInfo_f -================ -*/ -void idClass::DisplayInfo_f( const idCmdArgs &args ) { - gameLocal.Printf( "Class memory status: %i bytes allocated in %i objects\n", memused, numobjects ); -} - -/* -================ -idClass::ListClasses_f -================ -*/ -void idClass::ListClasses_f( const idCmdArgs &args ) { - int i; - idTypeInfo *type; - - gameLocal.Printf( "%-24s %-24s %-6s %-6s\n", "Classname", "Superclass", "Type", "Subclasses" ); - gameLocal.Printf( "----------------------------------------------------------------------\n" ); - - for( i = 0; i < types.Num(); i++ ) { - type = types[ i ]; - gameLocal.Printf( "%-24s %-24s %6d %6d\n", type->classname, type->superclass, type->typeNum, type->lastChild - type->typeNum ); - } - - gameLocal.Printf( "...%d classes", types.Num() ); -} - -/* -================ -idClass::CreateInstance -================ -*/ -idClass *idClass::CreateInstance( const char *name ) { - const idTypeInfo *type; - idClass *obj; - - type = idClass::GetClass( name ); - if ( !type ) { - return NULL; - } - - obj = type->CreateInstance(); - return obj; -} - -/* -================ -idClass::Init - -Should be called after all idTypeInfos are initialized, so must be called -manually upon game code initialization. Tells all the idTypeInfos to initialize -their event callback table for the associated class. This should only be called -once during the execution of the program or DLL. -================ -*/ -void idClass::Init( void ) { - idTypeInfo *c; - int num; - - gameLocal.Printf( "Initializing class hierarchy\n" ); - - if ( initialized ) { - gameLocal.Printf( "...already initialized\n" ); - return; - } - - // init the event callback tables for all the classes - for( c = typelist; c != NULL; c = c->next ) { - c->Init(); - } - - // number the types according to the class hierarchy so we can quickly determine if a class - // is a subclass of another - num = 0; - for( c = classHierarchy.GetNext(); c != NULL; c = c->node.GetNext(), num++ ) { - c->typeNum = num; - c->lastChild += num; - } - - // number of bits needed to send types over network - typeNumBits = idMath::BitsForInteger( num ); - - // create a list of the types so we can do quick lookups - // one list in alphabetical order, one in typenum order - types.SetGranularity( 1 ); - types.SetNum( num ); - typenums.SetGranularity( 1 ); - typenums.SetNum( num ); - num = 0; - for( c = typelist; c != NULL; c = c->next, num++ ) { - types[ num ] = c; - typenums[ c->typeNum ] = c; - } - - initialized = true; - - gameLocal.Printf( "...%i classes, %i bytes for event callbacks\n", types.Num(), eventCallbackMemory ); -} - -/* -================ -idClass::Shutdown -================ -*/ -void idClass::Shutdown( void ) { - idTypeInfo *c; - - for( c = typelist; c != NULL; c = c->next ) { - c->Shutdown(); - } - types.Clear(); - typenums.Clear(); - - initialized = false; -} - -/* -================ -idClass::new -================ -*/ -#ifdef ID_DEBUG_MEMORY -#undef new -#endif - -void * idClass::operator new( size_t s ) { - int *p; - - s += sizeof( int ); - p = (int *)Mem_Alloc( s ); - *p = s; - memused += s; - numobjects++; - -#ifdef ID_DEBUG_UNINITIALIZED_MEMORY - unsigned long *ptr = (unsigned long *)p; - int size = s; - assert( ( size & 3 ) == 0 ); - size >>= 3; - for ( int i = 1; i < size; i++ ) { - ptr[i] = 0xcdcdcdcd; - } -#endif - - return p + 1; -} - -void * idClass::operator new( size_t s, int, int, char *, int ) { - int *p; - - s += sizeof( int ); - p = (int *)Mem_Alloc( s ); - *p = s; - memused += s; - numobjects++; - -#ifdef ID_DEBUG_UNINITIALIZED_MEMORY - unsigned long *ptr = (unsigned long *)p; - int size = s; - assert( ( size & 3 ) == 0 ); - size >>= 3; - for ( int i = 1; i < size; i++ ) { - ptr[i] = 0xcdcdcdcd; - } -#endif - - return p + 1; -} - -#ifdef ID_DEBUG_MEMORY -#define new ID_DEBUG_NEW -#endif - -/* -================ -idClass::delete -================ -*/ -void idClass::operator delete( void *ptr ) { - int *p; - - if ( ptr ) { - p = ( ( int * )ptr ) - 1; - memused -= *p; - numobjects--; - Mem_Free( p ); - } -} - -void idClass::operator delete( void *ptr, int, int, char *, int ) { - int *p; - - if ( ptr ) { - p = ( ( int * )ptr ) - 1; - memused -= *p; - numobjects--; - Mem_Free( p ); - } -} - -/* -================ -idClass::GetClass - -Returns the idTypeInfo for the name of the class passed in. This is a static function -so it must be called as idClass::GetClass( classname ) -================ -*/ -idTypeInfo *idClass::GetClass( const char *name ) { - idTypeInfo *c; - int order; - int mid; - int min; - int max; - - if ( !initialized ) { - // idClass::Init hasn't been called yet, so do a slow lookup - for( c = typelist; c != NULL; c = c->next ) { - if ( !idStr::Cmp( c->classname, name ) ) { - return c; - } - } - } else { - // do a binary search through the list of types - min = 0; - max = types.Num() - 1; - while( min <= max ) { - mid = ( min + max ) / 2; - c = types[ mid ]; - order = idStr::Cmp( c->classname, name ); - if ( !order ) { - return c; - } else if ( order > 0 ) { - max = mid - 1; - } else { - min = mid + 1; - } - } - } - - return NULL; -} - -/* -================ -idClass::GetType -================ -*/ -idTypeInfo *idClass::GetType( const int typeNum ) { - idTypeInfo *c; - - if ( !initialized ) { - for( c = typelist; c != NULL; c = c->next ) { - if ( c->typeNum == typeNum ) { - return c; - } - } - } else if ( ( typeNum >= 0 ) && ( typeNum < types.Num() ) ) { - return typenums[ typeNum ]; - } - - return NULL; -} - -/* -================ -idClass::GetClassname - -Returns the text classname of the object. -================ -*/ -const char *idClass::GetClassname( void ) const { - idTypeInfo *type; - - type = GetType(); - return type->classname; -} - -/* -================ -idClass::GetSuperclass - -Returns the text classname of the superclass. -================ -*/ -const char *idClass::GetSuperclass( void ) const { - idTypeInfo *cls; - - cls = GetType(); - return cls->superclass; -} - -/* -================ -idClass::CancelEvents -================ -*/ -void idClass::CancelEvents( const idEventDef *ev ) { - idEvent::CancelEvents( this, ev ); -} - -/* -================ -idClass::PostEventArgs -================ -*/ -bool idClass::PostEventArgs( const idEventDef *ev, int time, int numargs, ... ) { - idTypeInfo *c; - idEvent *event; - va_list args; - - assert( ev ); - - if ( !idEvent::initialized ) { - return false; - } - - c = GetType(); - if ( !c->eventMap[ ev->GetEventNum() ] ) { - // we don't respond to this event, so ignore it - return false; - } - - // we service events on the client to avoid any bad code filling up the event pool - // we don't want them processed usually, unless when the map is (re)loading. - // we allow threads to run fine, though. - if ( gameLocal.isClient && ( gameLocal.GameState() != GAMESTATE_STARTUP ) && !IsType( idThread::Type ) ) { - return true; - } - - va_start( args, numargs ); - event = idEvent::Alloc( ev, numargs, args ); - va_end( args ); - - event->Schedule( this, c, time ); - - return true; -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time ) { - return PostEventArgs( ev, time, 0 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1 ) { - return PostEventArgs( ev, time, 1, &arg1 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 ) { - return PostEventArgs( ev, time, 2, &arg1, &arg2 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { - return PostEventArgs( ev, time, 3, &arg1, &arg2, &arg3 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { - return PostEventArgs( ev, time, 4, &arg1, &arg2, &arg3, &arg4 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { - return PostEventArgs( ev, time, 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { - return PostEventArgs( ev, time, 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { - return PostEventArgs( ev, time, 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); -} - -/* -================ -idClass::PostEventMS -================ -*/ -bool idClass::PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { - return PostEventArgs( ev, time, 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time ) { - return PostEventArgs( ev, SEC2MS( time ), 0 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1 ) { - return PostEventArgs( ev, SEC2MS( time ), 1, &arg1 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 ) { - return PostEventArgs( ev, SEC2MS( time ), 2, &arg1, &arg2 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { - return PostEventArgs( ev, SEC2MS( time ), 3, &arg1, &arg2, &arg3 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { - return PostEventArgs( ev, SEC2MS( time ), 4, &arg1, &arg2, &arg3, &arg4 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { - return PostEventArgs( ev, SEC2MS( time ), 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { - return PostEventArgs( ev, SEC2MS( time ), 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { - return PostEventArgs( ev, SEC2MS( time ), 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); -} - -/* -================ -idClass::PostEventSec -================ -*/ -bool idClass::PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { - return PostEventArgs( ev, SEC2MS( time ), 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); -} - -/* -================ -idClass::ProcessEventArgs -================ -*/ -bool idClass::ProcessEventArgs( const idEventDef *ev, int numargs, ... ) { - idTypeInfo *c; - int num; - int data[ D_EVENT_MAXARGS ]; - va_list args; - - assert( ev ); - assert( idEvent::initialized ); - - c = GetType(); - num = ev->GetEventNum(); - if ( !c->eventMap[ num ] ) { - // we don't respond to this event, so ignore it - return false; - } - - va_start( args, numargs ); - idEvent::CopyArgs( ev, numargs, args, data ); - va_end( args ); - - ProcessEventArgPtr( ev, data ); - - return true; -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev ) { - return ProcessEventArgs( ev, 0 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1 ) { - return ProcessEventArgs( ev, 1, &arg1 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 ) { - return ProcessEventArgs( ev, 2, &arg1, &arg2 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 ) { - return ProcessEventArgs( ev, 3, &arg1, &arg2, &arg3 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ) { - return ProcessEventArgs( ev, 4, &arg1, &arg2, &arg3, &arg4 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ) { - return ProcessEventArgs( ev, 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ) { - return ProcessEventArgs( ev, 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ) { - return ProcessEventArgs( ev, 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7 ); -} - -/* -================ -idClass::ProcessEvent -================ -*/ -bool idClass::ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ) { - return ProcessEventArgs( ev, 8, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8 ); -} - -/* -================ -idClass::ProcessEventArgPtr -================ -*/ -bool idClass::ProcessEventArgPtr( const idEventDef *ev, int *data ) { - idTypeInfo *c; - int num; - eventCallback_t callback; - - assert( ev ); - assert( idEvent::initialized ); - - if ( g_debugTriggers.GetBool() && ( ev == &EV_Activate ) && IsType( idEntity::Type ) ) { - const idEntity *ent = *reinterpret_cast( data ); - gameLocal.Printf( "%d: '%s' activated by '%s'\n", gameLocal.framenum, static_cast( this )->GetName(), ent ? ent->GetName() : "NULL" ); - } - - c = GetType(); - num = ev->GetEventNum(); - if ( !c->eventMap[ num ] ) { - // we don't respond to this event, so ignore it - return false; - } - - callback = c->eventMap[ num ]; - -#if !CPU_EASYARGS - -/* -on ppc architecture, floats are passed in a seperate set of registers -the function prototypes must have matching float declaration - -http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/2rt_powerpc_abi/chapter_9_section_5.html -*/ - - switch( ev->GetFormatspecIndex() ) { - case 1 << D_EVENT_MAXARGS : - ( this->*callback )(); - break; - -// generated file - see CREATE_EVENT_CODE -#include "Callbacks.cpp" - - default: - gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() ); - break; - } - -#else - - assert( D_EVENT_MAXARGS == 8 ); - - switch( ev->GetNumArgs() ) { - case 0 : - ( this->*callback )(); - break; - - case 1 : - typedef void ( idClass::*eventCallback_1_t )( const int ); - ( this->*( eventCallback_1_t )callback )( data[ 0 ] ); - break; - - case 2 : - typedef void ( idClass::*eventCallback_2_t )( const int, const int ); - ( this->*( eventCallback_2_t )callback )( data[ 0 ], data[ 1 ] ); - break; - - case 3 : - typedef void ( idClass::*eventCallback_3_t )( const int, const int, const int ); - ( this->*( eventCallback_3_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ] ); - break; - - case 4 : - typedef void ( idClass::*eventCallback_4_t )( const int, const int, const int, const int ); - ( this->*( eventCallback_4_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ] ); - break; - - case 5 : - typedef void ( idClass::*eventCallback_5_t )( const int, const int, const int, const int, const int ); - ( this->*( eventCallback_5_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ] ); - break; - - case 6 : - typedef void ( idClass::*eventCallback_6_t )( const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_6_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] ); - break; - - case 7 : - typedef void ( idClass::*eventCallback_7_t )( const int, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_7_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ] ); - break; - - case 8 : - typedef void ( idClass::*eventCallback_8_t )( const int, const int, const int, const int, const int, const int, const int, const int ); - ( this->*( eventCallback_8_t )callback )( data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ] ); - break; - - default: - gameLocal.Warning( "Invalid formatspec on event '%s'", ev->GetName() ); - break; - } - -#endif - - return true; -} - -/* -================ -idClass::Event_Remove -================ -*/ -void idClass::Event_Remove( void ) -{ - // If we are removing a currently frobbed entity, - // set the frob pointers to NULL to avoid stale pointers - idPlayer* player = gameLocal.GetLocalPlayer(); - - if (player != NULL) - { - if (player->m_FrobEntity.GetEntity() == this) - { - player->m_FrobEntity = NULL; - } - } - - CGrabber* grabber = gameLocal.m_Grabber; - if (grabber) - { - // tels: If we remove a currently grabbed entity, - // force the grabber to forget it - idEntity *ent = grabber->GetSelected(); - if (ent == this) - { - grabber->Forget( ent ); - } - } - - delete this; -} - -/* -================ -idClass::Event_SafeRemove -================ -*/ -void idClass::Event_SafeRemove( void ) { - // Forces the remove to be done at a safe time - PostEventMS( &EV_Remove, 0 ); -} diff --git a/game/gamesys/class.h b/game/gamesys/class.h deleted file mode 100644 index 07541207d..000000000 --- a/game/gamesys/class.h +++ /dev/null @@ -1,345 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* - -Base class for all game objects. Provides fast run-time type checking and run-time -instancing of objects. - -*/ - -#ifndef __SYS_CLASS_H__ -#define __SYS_CLASS_H__ - -#ifdef __linux__ -#include -#endif - -class idClass; -class idTypeInfo; - -extern const idEventDef EV_Remove; -extern const idEventDef EV_SafeRemove; - -typedef void ( idClass::*eventCallback_t )( void ); - -template< class Type > -struct idEventFunc { - const idEventDef *event; - eventCallback_t function; -}; - -// added & so gcc could compile this -#define EVENT( event, function ) { &( event ), ( void ( idClass::* )( void ) )( &function ) }, -#define END_CLASS { NULL, NULL } }; - - -class idEventArg { -public: - int type; - int value; - - idEventArg() { type = D_EVENT_INTEGER; value = 0; }; - idEventArg( int data ) { type = D_EVENT_INTEGER; value = data; }; - idEventArg( float data ) { type = D_EVENT_FLOAT; value = *reinterpret_cast( &data ); }; - idEventArg( idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast( &data ); }; - idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast( data.c_str() ); }; - idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast( data ); }; - idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast( data ); }; - idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast( data ); }; -}; - -class idAllocError : public idException { -public: - idAllocError( const char *text = "" ) : idException( text ) {} -}; - -/*********************************************************************** - - idClass - -***********************************************************************/ - -/* -================ -CLASS_PROTOTYPE - -This macro must be included in the definition of any subclass of idClass. -It prototypes variables used in class instanciation and type checking. -Use this on single inheritance concrete classes only. -================ -*/ -#define CLASS_PROTOTYPE( nameofclass ) \ -public: \ - static idTypeInfo Type; \ - static idClass *CreateInstance( void ); \ - virtual idTypeInfo *GetType( void ) const; \ - static idEventFunc eventCallbacks[] - -/* -================ -CLASS_DECLARATION - -This macro must be included in the code to properly initialize variables -used in type checking and run-time instanciation. It also defines the list -of events that the class responds to. Take special care to ensure that the -proper superclass is indicated or the run-time type information will be -incorrect. Use this on concrete classes only. -================ -*/ -#define CLASS_DECLARATION( nameofsuperclass, nameofclass ) \ - idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \ - ( idEventFunc * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn, \ - ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \ - idClass *nameofclass::CreateInstance( void ) { \ - try { \ - nameofclass *ptr = new nameofclass; \ - ptr->FindUninitializedMemory(); \ - return ptr; \ - } \ - catch( idAllocError & ) { \ - return NULL; \ - } \ - } \ - idTypeInfo *nameofclass::GetType( void ) const { \ - return &( nameofclass::Type ); \ - } \ -idEventFunc nameofclass::eventCallbacks[] = { - -/* -================ -ABSTRACT_PROTOTYPE - -This macro must be included in the definition of any abstract subclass of idClass. -It prototypes variables used in class instanciation and type checking. -Use this on single inheritance abstract classes only. -================ -*/ -#define ABSTRACT_PROTOTYPE( nameofclass ) \ -public: \ - static idTypeInfo Type; \ - static idClass *CreateInstance( void ); \ - virtual idTypeInfo *GetType( void ) const; \ - static idEventFunc eventCallbacks[] - -/* -================ -ABSTRACT_DECLARATION - -This macro must be included in the code to properly initialize variables -used in type checking. It also defines the list of events that the class -responds to. Take special care to ensure that the proper superclass is -indicated or the run-time tyep information will be incorrect. Use this -on abstract classes only. -================ -*/ -#define ABSTRACT_DECLARATION( nameofsuperclass, nameofclass ) \ - idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \ - ( idEventFunc * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn, \ - ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \ - idClass *nameofclass::CreateInstance( void ) { \ - gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass ); \ - return NULL; \ - } \ - idTypeInfo *nameofclass::GetType( void ) const { \ - return &( nameofclass::Type ); \ - } \ - idEventFunc nameofclass::eventCallbacks[] = { - -typedef void ( idClass::*classSpawnFunc_t )( void ); - -class idSaveGame; -class idRestoreGame; - -class idClass { -public: - ABSTRACT_PROTOTYPE( idClass ); - -#ifdef ID_REDIRECT_NEWDELETE -#undef new -#endif - void * operator new( size_t ); - void * operator new( size_t s, int, int, char *, int ); - void operator delete( void * ); - void operator delete( void *, int, int, char *, int ); -#ifdef ID_REDIRECT_NEWDELETE -#define new ID_DEBUG_NEW -#endif - - virtual ~idClass(); - - void Spawn( void ); - void CallSpawn( void ); - bool IsType( const idTypeInfo &c ) const; - const char * GetClassname( void ) const; - const char * GetSuperclass( void ) const; - void FindUninitializedMemory( void ); - - void Save( idSaveGame *savefile ) const {}; - void Restore( idRestoreGame *savefile ) {}; - - bool RespondsTo( const idEventDef &ev ) const; - - bool PostEventMS( const idEventDef *ev, int time ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); - bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); - - bool PostEventSec( const idEventDef *ev, float time ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); - bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); - - bool ProcessEvent( const idEventDef *ev ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 ); - bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 ); - - bool ProcessEventArgPtr( const idEventDef *ev, int *data ); - void CancelEvents( const idEventDef *ev ); - - void Event_Remove( void ); - - // Static functions - static void Init( void ); - static void Shutdown( void ); - static idTypeInfo * GetClass( const char *name ); - static void DisplayInfo_f( const idCmdArgs &args ); - static void ListClasses_f( const idCmdArgs &args ); - static idClass * CreateInstance( const char *name ); - static int GetNumTypes( void ) { return types.Num(); } - static int GetTypeNumBits( void ) { return typeNumBits; } - static idTypeInfo * GetType( int num ); - -private: - classSpawnFunc_t CallSpawnFunc( idTypeInfo *cls ); - - bool PostEventArgs( const idEventDef *ev, int time, int numargs, ... ); - bool ProcessEventArgs( const idEventDef *ev, int numargs, ... ); - - void Event_SafeRemove( void ); - - static bool initialized; - static idList types; - static idList typenums; - static int typeNumBits; - static int memused; - static int numobjects; -}; - -/*********************************************************************** - - idTypeInfo - -***********************************************************************/ - -class idTypeInfo { -public: - const char * classname; - const char * superclass; - idClass * ( *CreateInstance )( void ); - void ( idClass::*Spawn )( void ); - void ( idClass::*Save )( idSaveGame *savefile ) const; - void ( idClass::*Restore )( idRestoreGame *savefile ); - - idEventFunc * eventCallbacks; - eventCallback_t * eventMap; - idTypeInfo * super; - idTypeInfo * next; - bool freeEventMap; - int typeNum; - int lastChild; - - idHierarchy node; - - idTypeInfo( const char *classname, const char *superclass, - idEventFunc *eventCallbacks, idClass *( *CreateInstance )( void ), void ( idClass::*Spawn )( void ), - void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) ); - ~idTypeInfo(); - - void Init( void ); - void Shutdown( void ); - - bool IsType( const idTypeInfo &superclass ) const; - bool RespondsTo( const idEventDef &ev ) const; -}; - -/* -================ -idTypeInfo::IsType - -Checks if the object's class is a subclass of the class defined by the -passed in idTypeInfo. -================ -*/ -ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const { - return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) ); -} - -/* -================ -idTypeInfo::RespondsTo -================ -*/ -ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const { - assert( idEvent::initialized ); - if ( !eventMap[ ev.GetEventNum() ] ) { - // we don't respond to this event - return false; - } - - return true; -} - -/* -================ -idClass::IsType - -Checks if the object's class is a subclass of the class defined by the -passed in idTypeInfo. -================ -*/ -ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const { - idTypeInfo *subclass; - - subclass = GetType(); - return subclass->IsType( superclass ); -} - -/* -================ -idClass::RespondsTo -================ -*/ -ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const { - const idTypeInfo *c; - - assert( idEvent::initialized ); - c = GetType(); - return c->RespondsTo( ev ); -} - -#endif /* !__SYS_CLASS_H__ */ diff --git a/game/gamesys/debuggraph.cpp b/game/gamesys/debuggraph.cpp deleted file mode 100644 index 4d56ef1f4..000000000 --- a/game/gamesys/debuggraph.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -/* -================ -idDebugGraph::idDebugGraph -================ -*/ -idDebugGraph::idDebugGraph() { - index = 0; -} - -/* -================ -idDebugGraph::SetNumSamples -================ -*/ -void idDebugGraph::SetNumSamples( int num ) { - index = 0; - samples.Clear(); - samples.SetNum( num ); - memset( samples.Ptr(), 0, samples.MemoryUsed() ); -} - -/* -================ -idDebugGraph::AddValue -================ -*/ -void idDebugGraph::AddValue( float value ) { - samples[ index ] = value; - index++; - if ( index >= samples.Num() ) { - index = 0; - } -} - -/* -================ -idDebugGraph::Draw -================ -*/ -void idDebugGraph::Draw( const idVec4 &color, float scale ) const { - int i; - float value1; - float value2; - idVec3 vec1; - idVec3 vec2; - - const idMat3 &axis = gameLocal.GetLocalPlayer()->viewAxis; - const idVec3 pos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + axis[ 1 ] * samples.Num() * 0.5f; - - value1 = samples[ index ] * scale; - for( i = 1; i < samples.Num(); i++ ) { - value2 = samples[ ( i + index ) % samples.Num() ] * scale; - - vec1 = pos + axis[ 2 ] * value1 - axis[ 1 ] * ( i - 1 ) + axis[ 0 ] * samples.Num(); - vec2 = pos + axis[ 2 ] * value2 - axis[ 1 ] * i + axis[ 0 ] * samples.Num(); - - gameRenderWorld->DebugLine( color, vec1, vec2, gameLocal.msec, false ); - value1 = value2; - } -} diff --git a/game/gamesys/debuggraph.h b/game/gamesys/debuggraph.h deleted file mode 100644 index 49bbd4f0a..000000000 --- a/game/gamesys/debuggraph.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -// DebugGraph.h - -class idDebugGraph { -public: - idDebugGraph(); - void SetNumSamples( int num ); - void AddValue( float value ); - void Draw( const idVec4 &color, float scale ) const; - -private: - idList samples; - int index; -}; diff --git a/game/gamesys/event.cpp b/game/gamesys/event.cpp deleted file mode 100644 index 43202924a..000000000 --- a/game/gamesys/event.cpp +++ /dev/null @@ -1,860 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* -sys_event.cpp - -Event are used for scheduling tasks and for linking script commands. - -*/ - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "event.h" -#include "../game_local.h" - -#define MAX_EVENTSPERFRAME 8192 -//#define CREATE_EVENT_CODE - -/*********************************************************************** - - idEventDef - -***********************************************************************/ - -idEventDef *idEventDef::eventDefList[MAX_EVENTS]; -int idEventDef::numEventDefs = 0; - -static bool eventError = false; -static char eventErrorMsg[ 128 ]; - -/* -================ -idEventDef::idEventDef -================ -*/ -idEventDef::idEventDef( const char *command, const char *formatspec, char returnType ) { - idEventDef *ev; - int i; - unsigned int bits; - - assert( command ); - assert( !idEvent::initialized ); - - // Allow NULL to indicate no args, but always store it as "" - // so we don't have to check for it. - if ( !formatspec ) { - formatspec = ""; - } - - this->name = command; - this->formatspec = formatspec; - this->returnType = returnType; - - numargs = strlen( formatspec ); - assert( numargs <= D_EVENT_MAXARGS ); - if ( numargs > D_EVENT_MAXARGS ) { - eventError = true; - sprintf( eventErrorMsg, "idEventDef::idEventDef : Too many args for '%s' event.", name ); - return; - } - - // make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg - bits = 0; - argsize = 0; - memset( argOffset, 0, sizeof( argOffset ) ); - for( i = 0; i < numargs; i++ ) { - argOffset[ i ] = argsize; - switch( formatspec[ i ] ) { - case D_EVENT_FLOAT : - bits |= 1 << i; - argsize += sizeof( float ); - break; - - case D_EVENT_INTEGER : - argsize += sizeof( int ); - break; - - case D_EVENT_VECTOR : - argsize += sizeof( idVec3 ); - break; - - case D_EVENT_STRING : - argsize += MAX_STRING_LEN; - break; - - case D_EVENT_ENTITY : - argsize += sizeof( idEntityPtr ); - break; - - case D_EVENT_ENTITY_NULL : - argsize += sizeof( idEntityPtr ); - break; - - case D_EVENT_TRACE : - argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool ); - break; - - default : - eventError = true; - sprintf( eventErrorMsg, "idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event.", formatspec, name ); - return; - break; - } - } - - // calculate the formatspecindex - formatspecIndex = ( 1 << ( numargs + D_EVENT_MAXARGS ) ) | bits; - - // go through the list of defined events and check for duplicates - // and mismatched format strings - eventnum = numEventDefs; - for( i = 0; i < eventnum; i++ ) { - ev = eventDefList[ i ]; - if ( strcmp( command, ev->name ) == 0 ) { - if ( strcmp( formatspec, ev->formatspec ) != 0 ) { - eventError = true; - sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s').", - command, formatspec, ev->formatspec ); - return; - } - - if ( ev->returnType != returnType ) { - eventError = true; - sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing return types ('%c'!='%c').", - command, returnType, ev->returnType ); - return; - } - // Don't bother putting the duplicate event in list. - eventnum = ev->eventnum; - return; - } - } - - ev = this; - - if ( numEventDefs >= MAX_EVENTS ) { - eventError = true; - sprintf( eventErrorMsg, "numEventDefs >= MAX_EVENTS" ); - return; - } - eventDefList[numEventDefs] = ev; - numEventDefs++; -} - -/* -================ -idEventDef::NumEventCommands -================ -*/ -int idEventDef::NumEventCommands( void ) { - return numEventDefs; -} - -/* -================ -idEventDef::GetEventCommand -================ -*/ -const idEventDef *idEventDef::GetEventCommand( int eventnum ) { - return eventDefList[ eventnum ]; -} - -/* -================ -idEventDef::FindEvent -================ -*/ -const idEventDef *idEventDef::FindEvent( const char *name ) { - idEventDef *ev; - int num; - int i; - - assert( name ); - - num = numEventDefs; - for( i = 0; i < num; i++ ) { - ev = eventDefList[ i ]; - if ( strcmp( name, ev->name ) == 0 ) { - return ev; - } - } - - return NULL; -} - -/*********************************************************************** - - idEvent - -***********************************************************************/ - -static idLinkList FreeEvents; -static idLinkList EventQueue; -static idEvent EventPool[ MAX_EVENTS ]; - -bool idEvent::initialized = false; - -idDynamicBlockAlloc idEvent::eventDataAllocator; - -/* -================ -idEvent::~idEvent() -================ -*/ -idEvent::~idEvent() { - Free(); -} - -/* -================ -idEvent::Alloc -================ -*/ -idEvent *idEvent::Alloc( const idEventDef *evdef, int numargs, va_list args ) { - idEvent *ev; - size_t size; - const char *format; - idEventArg *arg; - byte *dataPtr; - int i; - const char *materialName; - - if ( FreeEvents.IsListEmpty() ) { - gameLocal.Error( "idEvent::Alloc : No more free events" ); - } - - ev = FreeEvents.Next(); - ev->eventNode.Remove(); - - ev->eventdef = evdef; - - if ( numargs != evdef->GetNumArgs() ) { - gameLocal.Error( "idEvent::Alloc : Wrong number of args for '%s' event.", evdef->GetName() ); - } - - size = evdef->GetArgSize(); - if ( size ) { - ev->data = eventDataAllocator.Alloc( size ); - memset( ev->data, 0, size ); - } else { - ev->data = NULL; - } - - format = evdef->GetArgFormat(); - for( i = 0; i < numargs; i++ ) { - arg = va_arg( args, idEventArg * ); - if ( format[ i ] != arg->type ) { - // when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens - if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) { - gameLocal.Error( "idEvent::Alloc : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() ); - } - } - - dataPtr = &ev->data[ evdef->GetArgOffset( i ) ]; - - switch( format[ i ] ) { - case D_EVENT_FLOAT : - case D_EVENT_INTEGER : - *reinterpret_cast( dataPtr ) = arg->value; - break; - - case D_EVENT_VECTOR : - if ( arg->value ) { - *reinterpret_cast( dataPtr ) = *reinterpret_cast( arg->value ); - } - break; - - case D_EVENT_STRING : - if ( arg->value ) { - idStr::Copynz( reinterpret_cast( dataPtr ), reinterpret_cast( arg->value ), MAX_STRING_LEN ); - } - break; - - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - *reinterpret_cast< idEntityPtr * >( dataPtr ) = reinterpret_cast( arg->value ); - break; - - case D_EVENT_TRACE : - if ( arg->value ) { - *reinterpret_cast( dataPtr ) = true; - *reinterpret_cast( dataPtr + sizeof( bool ) ) = *reinterpret_cast( arg->value ); - - // save off the material as a string since the pointer won't be valid in save games. - // since we save off the entire trace_t structure, if the material is NULL here, - // it will be NULL when we process it, so we don't need to save off anything in that case. - if ( reinterpret_cast( arg->value )->c.material ) { - materialName = reinterpret_cast( arg->value )->c.material->GetName(); - idStr::Copynz( reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ), materialName, MAX_STRING_LEN ); - } - } else { - *reinterpret_cast( dataPtr ) = false; - } - break; - - default : - gameLocal.Error( "idEvent::Alloc : Invalid arg format '%s' string for '%s' event.", format, evdef->GetName() ); - break; - } - } - - return ev; -} - -/* -================ -idEvent::CopyArgs -================ -*/ -void idEvent::CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ) { - int i; - const char *format; - idEventArg *arg; - - format = evdef->GetArgFormat(); - if ( numargs != evdef->GetNumArgs() ) { - gameLocal.Error( "idEvent::CopyArgs : Wrong number of args for '%s' event.", evdef->GetName() ); - } - - for( i = 0; i < numargs; i++ ) { - arg = va_arg( args, idEventArg * ); - if ( format[ i ] != arg->type ) { - // when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens - if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) { - gameLocal.Error( "idEvent::CopyArgs : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() ); - } - } - - data[ i ] = arg->value; - } -} - -/* -================ -idEvent::Free -================ -*/ -void idEvent::Free( void ) { - if ( data ) { - eventDataAllocator.Free( data ); - data = NULL; - } - - eventdef = NULL; - time = 0; - object = NULL; - typeinfo = NULL; - - eventNode.SetOwner( this ); - eventNode.AddToEnd( FreeEvents ); -} - -/* -================ -idEvent::Schedule -================ -*/ -void idEvent::Schedule( idClass *obj, const idTypeInfo *type, int time ) { - idEvent *event; - - assert( initialized ); - if ( !initialized ) { - return; - } - - object = obj; - typeinfo = type; - - // wraps after 24 days...like I care. ;) - this->time = gameLocal.time + time; - - eventNode.Remove(); - - event = EventQueue.Next(); - while( ( event != NULL ) && ( this->time >= event->time ) ) { - event = event->eventNode.Next(); - } - - if ( event ) { - eventNode.InsertBefore( event->eventNode ); - } else { - eventNode.AddToEnd( EventQueue ); - } -} - -/* -================ -idEvent::CancelEvents -================ -*/ -void idEvent::CancelEvents( const idClass *obj, const idEventDef *evdef ) { - idEvent *event; - idEvent *next; - - if ( !initialized ) { - return; - } - - for( event = EventQueue.Next(); event != NULL; event = next ) { - next = event->eventNode.Next(); - if ( event->object == obj ) { - if ( !evdef || ( evdef == event->eventdef ) ) { - event->Free(); - } - } - } -} - -/* -================ -idEvent::ClearEventList -================ -*/ -void idEvent::ClearEventList( void ) { - int i; - - // - // initialize lists - // - FreeEvents.Clear(); - EventQueue.Clear(); - - // - // add the events to the free list - // - for( i = 0; i < MAX_EVENTS; i++ ) { - EventPool[ i ].Free(); - } -} - -/* -================ -idEvent::ServiceEvents -================ -*/ -void idEvent::ServiceEvents( void ) { - idEvent *event; - int num; - int args[ D_EVENT_MAXARGS ]; - int offset; - int i; - int numargs; - const char *formatspec; - trace_t **tracePtr; - const idEventDef *ev; - byte *data; - const char *materialName; - - num = 0; - while( !EventQueue.IsListEmpty() ) { - event = EventQueue.Next(); - assert( event ); - - if ( event->time > gameLocal.time ) { - break; - } - - // copy the data into the local args array and set up pointers - ev = event->eventdef; - formatspec = ev->GetArgFormat(); - numargs = ev->GetNumArgs(); - for( i = 0; i < numargs; i++ ) { - offset = ev->GetArgOffset( i ); - data = event->data; - switch( formatspec[ i ] ) { - case D_EVENT_FLOAT : - case D_EVENT_INTEGER : - args[ i ] = *reinterpret_cast( &data[ offset ] ); - break; - - case D_EVENT_VECTOR : - *reinterpret_cast( &args[ i ] ) = reinterpret_cast( &data[ offset ] ); - break; - - case D_EVENT_STRING : - *reinterpret_cast( &args[ i ] ) = reinterpret_cast( &data[ offset ] ); - break; - - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - *reinterpret_cast( &args[ i ] ) = reinterpret_cast< idEntityPtr * >( &data[ offset ] )->GetEntity(); - break; - - case D_EVENT_TRACE : - tracePtr = reinterpret_cast( &args[ i ] ); - if ( *reinterpret_cast( &data[ offset ] ) ) { - *tracePtr = reinterpret_cast( &data[ offset + sizeof( bool ) ] ); - - if ( ( *tracePtr )->c.material != NULL ) { - // look up the material name to get the material pointer - materialName = reinterpret_cast( &data[ offset + sizeof( bool ) + sizeof( trace_t ) ] ); - ( *tracePtr )->c.material = declManager->FindMaterial( materialName, true ); - } - } else { - *tracePtr = NULL; - } - break; - - default: - gameLocal.Error( "idEvent::ServiceEvents : Invalid arg format '%s' string for '%s' event.", formatspec, ev->GetName() ); - } - } - - // the event is removed from its list so that if then object - // is deleted, the event won't be freed twice - event->eventNode.Remove(); - assert( event->object ); - event->object->ProcessEventArgPtr( ev, args ); - -#if 0 - // event functions may never leave return values on the FPU stack - // enable this code to check if any event call left values on the FPU stack - if ( !sys->FPU_StackIsEmpty() ) { - gameLocal.Error( "idEvent::ServiceEvents %d: %s left a value on the FPU stack\n", num, ev->GetName() ); - } -#endif - - // return the event to the free list - event->Free(); - - // Don't allow ourselves to stay in here too long. An abnormally high number - // of events being processed is evidence of an infinite loop of events. - num++; - if ( num > MAX_EVENTSPERFRAME ) { - gameLocal.Error( "Event overflow. Possible infinite loop in script." ); - } - } -} - -/* -================ -idEvent::Init -================ -*/ -void idEvent::Init( void ) { - gameLocal.Printf( "Initializing event system\n" ); - - if ( eventError ) { - gameLocal.Error( "%s", eventErrorMsg ); - } - -#ifdef CREATE_EVENT_CODE - void CreateEventCallbackHandler(); - CreateEventCallbackHandler(); - gameLocal.Error( "Wrote event callback handler" ); -#endif - - if ( initialized ) { - gameLocal.Printf( "...already initialized\n" ); - ClearEventList(); - return; - } - - ClearEventList(); - - eventDataAllocator.Init(); - - gameLocal.Printf( "...%i event definitions\n", idEventDef::NumEventCommands() ); - - // the event system has started - initialized = true; -} - -/* -================ -idEvent::Shutdown -================ -*/ -void idEvent::Shutdown( void ) { - gameLocal.Printf( "Shutdown event system\n" ); - - if ( !initialized ) { - gameLocal.Printf( "...not started\n" ); - return; - } - - ClearEventList(); - - eventDataAllocator.Shutdown(); - - // say it is now shut down - initialized = false; -} - -/* -================ -idEvent::Save -================ -*/ -void idEvent::Save( idSaveGame *savefile ) { - char *str; - int i; - size_t size; - idEvent *event; - byte *dataPtr; - bool validTrace; - const char *format; - - savefile->WriteInt( EventQueue.Num() ); - - event = EventQueue.Next(); - while( event != NULL ) { - savefile->WriteInt( event->time ); - savefile->WriteString( event->eventdef->GetName() ); - savefile->WriteString( event->typeinfo->classname ); - savefile->WriteObject( event->object ); - savefile->WriteInt( event->eventdef->GetArgSize() ); - format = event->eventdef->GetArgFormat(); - for ( i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i) { - dataPtr = &event->data[ event->eventdef->GetArgOffset( i ) ]; - switch( format[ i ] ) { - case D_EVENT_FLOAT : - savefile->WriteFloat( *reinterpret_cast( dataPtr ) ); - size += sizeof( float ); - break; - case D_EVENT_INTEGER : - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - savefile->WriteInt( *reinterpret_cast( dataPtr ) ); - size += sizeof( int ); - break; - case D_EVENT_VECTOR : - savefile->WriteVec3( *reinterpret_cast( dataPtr ) ); - size += sizeof( idVec3 ); - break; - case D_EVENT_TRACE : - validTrace = *reinterpret_cast( dataPtr ); - savefile->WriteBool( validTrace ); - size += sizeof( bool ); - if ( validTrace ) { - size += sizeof( trace_t ); - const trace_t &t = *reinterpret_cast( dataPtr + sizeof( bool ) ); - SaveTrace( savefile, t ); - if ( t.c.material ) { - size += MAX_STRING_LEN; - str = reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ); - savefile->Write( str, MAX_STRING_LEN ); - } - } - break; - default: - break; - } - } - assert( size == event->eventdef->GetArgSize() ); - event = event->eventNode.Next(); - } -} - -/* -================ -idEvent::Restore -================ -*/ -void idEvent::Restore( idRestoreGame *savefile ) { - char *str; - int num, i, j, size, argsize = 0; - idStr name; - byte *dataPtr; - idEvent *event; - const char *format; - - savefile->ReadInt( num ); - - for ( i = 0; i < num; i++ ) { - if ( FreeEvents.IsListEmpty() ) { - gameLocal.Error( "idEvent::Restore : No more free events" ); - } - - event = FreeEvents.Next(); - event->eventNode.Remove(); - event->eventNode.AddToEnd( EventQueue ); - - savefile->ReadInt( event->time ); - - // read the event name - savefile->ReadString( name ); - event->eventdef = idEventDef::FindEvent( name ); - if ( !event->eventdef ) { - savefile->Error( "idEvent::Restore: unknown event '%s'", name.c_str() ); - } - - // read the classtype - savefile->ReadString( name ); - event->typeinfo = idClass::GetClass( name ); - if ( !event->typeinfo ) { - savefile->Error( "idEvent::Restore: unknown class '%s' on event '%s'", name.c_str(), event->eventdef->GetName() ); - } - - savefile->ReadObject( event->object ); - - // read the args - savefile->ReadInt( argsize ); - if ( argsize != (int)event->eventdef->GetArgSize() ) { - savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() ); - } - if ( argsize ) { - event->data = eventDataAllocator.Alloc( argsize ); - format = event->eventdef->GetArgFormat(); - assert( format ); - for ( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j) { - dataPtr = &event->data[ event->eventdef->GetArgOffset( j ) ]; - switch( format[ j ] ) { - case D_EVENT_FLOAT : - savefile->ReadFloat( *reinterpret_cast( dataPtr ) ); - size += sizeof( float ); - break; - case D_EVENT_INTEGER : - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - savefile->ReadInt( *reinterpret_cast( dataPtr ) ); - size += sizeof( int ); - break; - case D_EVENT_VECTOR : - savefile->ReadVec3( *reinterpret_cast( dataPtr ) ); - size += sizeof( idVec3 ); - break; - case D_EVENT_TRACE : - savefile->ReadBool( *reinterpret_cast( dataPtr ) ); - size += sizeof( bool ); - if ( *reinterpret_cast( dataPtr ) ) { - size += sizeof( trace_t ); - trace_t &t = *reinterpret_cast( dataPtr + sizeof( bool ) ); - RestoreTrace( savefile, t) ; - if ( t.c.material ) { - size += MAX_STRING_LEN; - str = reinterpret_cast( dataPtr + sizeof( bool ) + sizeof( trace_t ) ); - savefile->Read( str, MAX_STRING_LEN ); - } - } - break; - default: - break; - } - } - assert( size == (int)event->eventdef->GetArgSize() ); - } else { - event->data = NULL; - } - } -} - -/* - ================ - idEvent::ReadTrace - - idRestoreGame has a ReadTrace procedure, but unfortunately idEvent wants the material - string name at the of the data structure rather than in the middle - ================ - */ -void idEvent::RestoreTrace( idRestoreGame *savefile, trace_t &trace ) { - savefile->ReadFloat( trace.fraction ); - savefile->ReadVec3( trace.endpos ); - savefile->ReadMat3( trace.endAxis ); - savefile->ReadInt( (int&)trace.c.type ); - savefile->ReadVec3( trace.c.point ); - savefile->ReadVec3( trace.c.normal ); - savefile->ReadFloat( trace.c.dist ); - savefile->ReadInt( trace.c.contents ); - savefile->ReadInt( (int&)trace.c.material ); - savefile->ReadInt( trace.c.contents ); - savefile->ReadInt( trace.c.modelFeature ); - savefile->ReadInt( trace.c.trmFeature ); - savefile->ReadInt( trace.c.id ); -} - -/* - ================ - idEvent::WriteTrace - - idSaveGame has a WriteTrace procedure, but unfortunately idEvent wants the material - string name at the of the data structure rather than in the middle -================ - */ -void idEvent::SaveTrace( idSaveGame *savefile, const trace_t &trace ) { - savefile->WriteFloat( trace.fraction ); - savefile->WriteVec3( trace.endpos ); - savefile->WriteMat3( trace.endAxis ); - savefile->WriteInt( trace.c.type ); - savefile->WriteVec3( trace.c.point ); - savefile->WriteVec3( trace.c.normal ); - savefile->WriteFloat( trace.c.dist ); - savefile->WriteInt( trace.c.contents ); - savefile->WriteInt( (int&)trace.c.material ); - savefile->WriteInt( trace.c.contents ); - savefile->WriteInt( trace.c.modelFeature ); - savefile->WriteInt( trace.c.trmFeature ); - savefile->WriteInt( trace.c.id ); -} - - - -#ifdef CREATE_EVENT_CODE -/* -================ -CreateEventCallbackHandler -================ -*/ -void CreateEventCallbackHandler( void ) { - int num; - int count; - int i, j, k; - char argString[ D_EVENT_MAXARGS + 1 ]; - idStr string1; - idStr string2; - idFile *file; - - file = fileSystem->OpenFileWrite( "Callbacks.cpp" ); - - file->Printf( "// generated file - see CREATE_EVENT_CODE\n\n" ); - - for( i = 1; i <= D_EVENT_MAXARGS; i++ ) { - - file->Printf( "\t/*******************************************************\n\n\t\t%d args\n\n\t*******************************************************/\n\n", i ); - - for ( j = 0; j < ( 1 << i ); j++ ) { - for ( k = 0; k < i; k++ ) { - argString[ k ] = j & ( 1 << k ) ? 'f' : 'i'; - } - argString[ i ] = '\0'; - - string1.Empty(); - string2.Empty(); - - for( k = 0; k < i; k++ ) { - if ( j & ( 1 << k ) ) { - string1 += "const float"; - string2 += va( "*( float * )&data[ %d ]", k ); - } else { - string1 += "const int"; - string2 += va( "data[ %d ]", k ); - } - - if ( k < i - 1 ) { - string1 += ", "; - string2 += ", "; - } - } - - file->Printf( "\tcase %d :\n\t\ttypedef void ( idClass::*eventCallback_%s_t )( %s );\n", ( 1 << ( i + D_EVENT_MAXARGS ) ) + j, argString, string1.c_str() ); - file->Printf( "\t\t( this->*( eventCallback_%s_t )callback )( %s );\n\t\tbreak;\n\n", argString, string2.c_str() ); - - } - } - - fileSystem->CloseFile( file ); -} - -#endif diff --git a/game/gamesys/event.h b/game/gamesys/event.h deleted file mode 100644 index e98375922..000000000 --- a/game/gamesys/event.h +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* -sys_event.h - -Event are used for scheduling tasks and for linking script commands. -*/ -#ifndef __SYS_EVENT_H__ -#define __SYS_EVENT_H__ - -#ifdef __linux__ -#include -#endif - -#include "../../idlib/lib.h" -#include - -#define D_EVENT_MAXARGS 8 // if changed, enable the CREATE_EVENT_CODE define in Event.cpp to generate switch statement for idClass::ProcessEventArgPtr. - // running the game will then generate c:\doom\base\events.txt, the contents of which should be copied into the switch statement. - -#define D_EVENT_VOID ( ( char )0 ) -#define D_EVENT_INTEGER 'd' -#define D_EVENT_FLOAT 'f' -#define D_EVENT_VECTOR 'v' -#define D_EVENT_STRING 's' -#define D_EVENT_ENTITY 'e' -#define D_EVENT_ENTITY_NULL 'E' // event can handle NULL entity pointers -#define D_EVENT_TRACE 't' - -#define MAX_EVENTS 8192 - -class idClass; -class idTypeInfo; - -class idEventDef { -private: - const char *name; - const char *formatspec; - unsigned int formatspecIndex; - int returnType; - int numargs; - size_t argsize; - int argOffset[ D_EVENT_MAXARGS ]; - int eventnum; - const idEventDef * next; - - static idEventDef * eventDefList[MAX_EVENTS]; - static int numEventDefs; - -public: - idEventDef( const char *command, const char *formatspec = NULL, char returnType = 0 ); - - const char *GetName( void ) const; - const char *GetArgFormat( void ) const; - unsigned int GetFormatspecIndex( void ) const; - char GetReturnType( void ) const; - int GetEventNum( void ) const; - int GetNumArgs( void ) const; - size_t GetArgSize( void ) const; - int GetArgOffset( int arg ) const; - - static int NumEventCommands( void ); - static const idEventDef *GetEventCommand( int eventnum ); - static const idEventDef *FindEvent( const char *name ); -}; - -class idSaveGame; -class idRestoreGame; -typedef struct trace_s trace_t; - -class idEvent { -private: - const idEventDef *eventdef; - byte *data; - int time; - idClass *object; - const idTypeInfo *typeinfo; - - idLinkList eventNode; - - static idDynamicBlockAlloc eventDataAllocator; - - -public: - static bool initialized; - - ~idEvent(); - - static idEvent *Alloc( const idEventDef *evdef, int numargs, va_list args ); - static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ); - - void Free( void ); - void Schedule( idClass *object, const idTypeInfo *cls, int time ); - byte *GetData( void ); - - static void CancelEvents( const idClass *obj, const idEventDef *evdef = NULL ); - static void ClearEventList( void ); - static void ServiceEvents( void ); - static void Init( void ); - static void Shutdown( void ); - - // save games - static void Save( idSaveGame *savefile ); // archives object for save game file - static void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - static void SaveTrace( idSaveGame *savefile, const trace_t &trace ); - static void RestoreTrace( idRestoreGame *savefile, trace_t &trace ); - -}; - -/* -================ -idEvent::GetData -================ -*/ -ID_INLINE byte *idEvent::GetData( void ) { - return data; -} - -/* -================ -idEventDef::GetName -================ -*/ -ID_INLINE const char *idEventDef::GetName( void ) const { - return name; -} - -/* -================ -idEventDef::GetArgFormat -================ -*/ -ID_INLINE const char *idEventDef::GetArgFormat( void ) const { - return formatspec; -} - -/* -================ -idEventDef::GetFormatspecIndex -================ -*/ -ID_INLINE unsigned int idEventDef::GetFormatspecIndex( void ) const { - return formatspecIndex; -} - -/* -================ -idEventDef::GetReturnType -================ -*/ -ID_INLINE char idEventDef::GetReturnType( void ) const { - return returnType; -} - -/* -================ -idEventDef::GetNumArgs -================ -*/ -ID_INLINE int idEventDef::GetNumArgs( void ) const { - return numargs; -} - -/* -================ -idEventDef::GetArgSize -================ -*/ -ID_INLINE size_t idEventDef::GetArgSize( void ) const { - return argsize; -} - -/* -================ -idEventDef::GetArgOffset -================ -*/ -ID_INLINE int idEventDef::GetArgOffset( int arg ) const { - assert( ( arg >= 0 ) && ( arg < D_EVENT_MAXARGS ) ); - return argOffset[ arg ]; -} - -/* -================ -idEventDef::GetEventNum -================ -*/ -ID_INLINE int idEventDef::GetEventNum( void ) const { - return eventnum; -} - -#endif /* !__SYS_EVENT_H__ */ diff --git a/game/gamesys/nogametypeinfo.h b/game/gamesys/nogametypeinfo.h deleted file mode 100644 index 211d26b2a..000000000 --- a/game/gamesys/nogametypeinfo.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAMETYPEINFO_H__ -#define __GAMETYPEINFO_H__ - -/* -=================================================================================== - - This file has been generated with the Type Info Generator v1.0 (c) 2004 id Software - -=================================================================================== -*/ - -typedef struct { - const char * name; - const char * type; - const char * value; -} constantInfo_t; - -typedef struct { - const char * name; - int value; -} enumValueInfo_t; - -typedef struct { - const char * typeName; - const enumValueInfo_t * values; -} enumTypeInfo_t; - -typedef struct { - const char * type; - const char * name; - int offset; - int size; -} classVariableInfo_t; - -typedef struct { - const char * typeName; - const char * superType; - int size; - const classVariableInfo_t * variables; -} classTypeInfo_t; - - -static constantInfo_t constantInfo[] = { - { NULL, NULL, NULL } -}; - -static enumTypeInfo_t enumTypeInfo[] = { - { NULL, NULL } -}; - -static classTypeInfo_t classTypeInfo[] = { - { NULL, NULL, 0, NULL } -}; - -#endif /* !__GAMETYPEINFO_H__ */ diff --git a/game/gamesys/savegame.cpp b/game/gamesys/savegame.cpp deleted file mode 100644 index b35015a15..000000000 --- a/game/gamesys/savegame.cpp +++ /dev/null @@ -1,1177 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/RevisionTracker.h" - -#include "typeinfo.h" - -#include "zlib.h" - -/* -Save game related helper classes. - -Save games are implemented in two classes, idSaveGame and idRestoreGame, that implement write/read functions for -common types. They're passed in to each entity and object for them to archive themselves. Each class -implements save/restore functions for it's own data. When restoring, all the objects are instantiated, -then the restore function is called on each, superclass first, then subclasses. - -Pointers are restored by saving out an object index for each unique object pointer and adding them to a list of -objects that are to be saved. Restore instantiates all the objects in the list before calling the Restore function -on each object so that the pointers returned are valid. No object's restore function should rely on any other objects -being fully instantiated until after the restore process is complete. Post restore fixup should be done by posting -events with 0 delay. - -The savegame header will have the Game Name, Version, Map Name, and Player Persistent Info. - -Changes in version make savegames incompatible, and the game will start from the beginning of the level with -the player's persistent info. - -Changes to classes that don't need to break compatibility can use the build number as the savegame version. -Later versions are responsible for restoring from previous versions by ignoring any unused data and initializing -variables that weren't in previous versions with safe information. - -At the head of the save game is enough information to restore the player to the beginning of the level should the -file be unloadable in some way (for example, due to script changes). - -Note: the caching works only if the compresion is enabled. -The caching mechanism works in the following way. On game saving, there are two types of data: - 1. Ordinary data (almost all the data) - This type of data is pushed into the "cache" buffer. - 2. Special data which is now: - // ui->WriteToSaveGame( file ) - closed source - // gameSoundWorld->WriteToSaveGame( file ) - closed source - // WriteBuildNumber() and WriteCodeRevision() - vital, should not be compressed - This data is written directly to the file. -After all the data has been passed to idSaveGame, FinalizeCache must be called. -Depending on the settings it may compress the cache. Then it is finally dumped to idFile. -After that the last 4 bytes are written to the file - offset to cache start from the end of file. -The final file layout is then: - 1. Doom3 header (level info, we cannot change it) - 2. Special data (including version numbers) - 3. Cache image, maybe compressed (consists of ordinary data) - 4. Offset from EOF to cache image (is negative) -Restoring works almost the same way, but the cache must be retrieved at the very beginning. -The InitializeCache must be called before any ordinary data is read from the file. -It uses fseek to get offset to cache image, then reads it, probably decompresses it. -Afterwards it fseeks to the file position on the moment of call. -Then all the Read* happens which reads ordinary data from cache and special data from file. -*/ - -idSaveGame::idSaveGame( idFile *savefile ) { - - file = savefile; - - // Put NULL at the start of the list so we can skip over it. - objects.Clear(); - objects.Append( NULL ); -} - -idSaveGame::~idSaveGame() { - if ( objects.Num() ) { - Close(); - } -} - -void idSaveGame::Close( void ) { - int i; - - WriteSoundCommands(); - - // read trace models - idClipModel::SaveTraceModels( this ); - - for( i = 1; i < objects.Num(); i++ ) { - CallSave_r( objects[ i ]->GetType(), objects[ i ] ); - } - - objects.Clear(); - -#ifdef ID_DEBUG_MEMORY - idStr gameState = file->GetName(); - gameState.StripFileExtension(); - WriteGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ), false ) ); -#endif -} - -void idSaveGame::FinalizeCache( void ) { - if (!isCompressed) return; - - int offset = sizeof(int); - - //resize destination buffer - CRawVector zipped; - int zipsize = compressBound(cache.size()); - zipped.resize(zipsize); - - //compress the cache - int err = compress((Bytef *)&zipped[0], (uLongf*)&zipsize, - (const Bytef *)&cache[0], cache.size()); - if (err != Z_OK) - gameLocal.Error("idSaveGame::FinalizeCache: compress failed with code %d", err); - zipped.resize(zipsize); - - //write compressed size and uncompressed size - file->WriteInt(zipped.size()); offset += sizeof(int); - file->WriteInt(cache.size()); offset += sizeof(int); - //write compressed data - file->Write(&zipped[0], zipped.size()); offset += zipped.size(); - //write offset from EOF to cache start - file->WriteInt(-offset); - - cache.clear(); -} - -void idSaveGame::WriteObjectList( void ) { - int i; - - WriteInt( objects.Num() - 1 ); - for( i = 1; i < objects.Num(); i++ ) { - WriteString( objects[ i ]->GetClassname() ); - } -} - -void idSaveGame::CallSave_r( const idTypeInfo *cls, const idClass *obj ) { - if ( cls->super ) { - CallSave_r( cls->super, obj ); - if ( cls->super->Save == cls->Save ) { - // don't call save on this inheritance level since the function was called in the super class - return; - } - } - - ( obj->*cls->Save )( this ); -} - -void idSaveGame::AddObject( const idClass *obj ) { - objects.AddUnique( obj ); -} - -void idSaveGame::Write( const void *buffer, int len ) { - if (len == 0) return; - if (isCompressed) { - int sz = cache.size(); - cache.resize(sz + len); - memcpy(&cache[sz], buffer, len); - } - else - file->Write(buffer, len); -} - -void idSaveGame::WriteJoint( const jointHandle_t value ) { - WriteInt( (int)value ); -} - - -void idSaveGame::WriteByte( const byte value ) { - WriteUnsignedChar(value); -} - -void idSaveGame::WriteSignedChar( const signed char value ) { - WriteChar(value); -} - -void idSaveGame::WriteString( const char *string ) { - int len; - - len = strlen( string ); - WriteInt( len ); - Write( string, len ); -} - -void idSaveGame::WriteBounds( const idBounds &bounds ) { - WriteVec3(bounds[0]); - WriteVec3(bounds[1]); -} - -void idSaveGame::WriteBox( const idBox &box ) { - WriteVec3(box.GetCenter()); - WriteVec3(box.GetExtents()); - WriteMat3(box.GetAxis()); -} - -void idSaveGame::WriteWinding( const idWinding &w ) { - int i, num; - num = w.GetNumPoints(); - WriteInt( num ); - for ( i = 0; i < num; i++ ) - WriteVec5(w[i]); -} - -void idSaveGame::WriteObject( const idClass *obj ) { - int index; - - index = objects.FindIndex( obj ); - if ( index < 0 ) { - gameLocal.Warning( "idSaveGame::WriteObject - WriteObject FindIndex failed\n" ); - - // Use the NULL index - index = 0; - } - - WriteInt( index ); -} - -void idSaveGame::WriteStaticObject( const idClass &obj ) { - CallSave_r( obj.GetType(), &obj ); -} - -void idSaveGame::WriteDict( const idDict *dict ) { - int num; - int i; - const idKeyValue *kv; - - if ( !dict ) { - WriteInt( -1 ); - } else { - num = dict->GetNumKeyVals(); - WriteInt( num ); - for( i = 0; i < num; i++ ) { - kv = dict->GetKeyVal( i ); - WriteString( kv->GetKey() ); - WriteString( kv->GetValue() ); - } - } -} - -void idSaveGame::WriteMaterial( const idMaterial *material ) { - if ( !material ) { - WriteString( "" ); - } else { - WriteString( material->GetName() ); - } -} - -void idSaveGame::WriteSkin( const idDeclSkin *skin ) { - if ( !skin ) { - WriteString( "" ); - } else { - WriteString( skin->GetName() ); - } -} - -void idSaveGame::WriteParticle( const idDeclParticle *particle ) { - if ( !particle ) { - WriteString( "" ); - } else { - WriteString( particle->GetName() ); - } -} - -void idSaveGame::WriteFX( const idDeclFX *fx ) { - if ( !fx ) { - WriteString( "" ); - } else { - WriteString( fx->GetName() ); - } -} - -void idSaveGame::WriteModelDef( const idDeclModelDef *modelDef ) { - if ( !modelDef ) { - WriteString( "" ); - } else { - WriteString( modelDef->GetName() ); - } -} - -void idSaveGame::WriteSoundShader( const idSoundShader *shader ) { - const char *name; - - if ( !shader ) { - WriteString( "" ); - } else { - name = shader->GetName(); - WriteString( name ); - } -} - -void idSaveGame::WriteModel( const idRenderModel *model ) { - const char *name; - - if ( !model ) { - WriteString( "" ); - } else { - name = model->Name(); - WriteString( name ); - } -} - -void idSaveGame::WriteRenderEntity( const renderEntity_t &renderEntity ) { - int i; - - WriteModel( renderEntity.hModel ); - - WriteInt( renderEntity.entityNum ); - WriteInt( renderEntity.bodyId ); - - WriteBounds( renderEntity.bounds ); - - // callback is set by class's Restore function - - WriteInt( renderEntity.suppressSurfaceInViewID ); - WriteInt( renderEntity.suppressShadowInViewID ); - WriteInt( renderEntity.suppressShadowInLightID ); - WriteInt( renderEntity.allowSurfaceInViewID ); - - WriteVec3( renderEntity.origin ); - WriteMat3( renderEntity.axis ); - - WriteMaterial( renderEntity.customShader ); - WriteMaterial( renderEntity.referenceShader ); - WriteSkin( renderEntity.customSkin ); - - if ( renderEntity.referenceSound != NULL ) { - WriteInt( renderEntity.referenceSound->Index() ); - } else { - WriteInt( 0 ); - } - - for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { - WriteFloat( renderEntity.shaderParms[ i ] ); - } - - for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - WriteUserInterface( renderEntity.gui[ i ], renderEntity.gui[ i ] ? renderEntity.gui[ i ]->IsUniqued() : false ); - } - - WriteFloat( renderEntity.modelDepthHack ); - - WriteBool( renderEntity.noSelfShadow ); - WriteBool( renderEntity.noShadow ); - WriteBool( renderEntity.noDynamicInteractions ); - WriteBool( renderEntity.weaponDepthHack ); - - WriteInt( renderEntity.forceUpdate ); -} - -void idSaveGame::WriteRenderLight( const renderLight_t &renderLight ) { - int i; - - WriteMat3( renderLight.axis ); - WriteVec3( renderLight.origin ); - - WriteInt( renderLight.suppressLightInViewID ); - WriteInt( renderLight.allowLightInViewID ); - WriteBool( renderLight.noShadows ); - WriteBool( renderLight.noSpecular ); - WriteBool( renderLight.pointLight ); - WriteBool( renderLight.parallel ); - - WriteVec3( renderLight.lightRadius ); - WriteVec3( renderLight.lightCenter ); - - WriteVec3( renderLight.target ); - WriteVec3( renderLight.right ); - WriteVec3( renderLight.up ); - WriteVec3( renderLight.start ); - WriteVec3( renderLight.end ); - - // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there - // WriteModel( renderLight.prelightModel ); - - WriteInt( renderLight.lightId ); - - WriteMaterial( renderLight.shader ); - - for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { - WriteFloat( renderLight.shaderParms[ i ] ); - } - - if ( renderLight.referenceSound != NULL ) { - WriteInt( renderLight.referenceSound->Index() ); - } else { - WriteInt( 0 ); - } -} - -void idSaveGame::WriteRefSound( const refSound_t &refSound ) { - if ( refSound.referenceSound ) { - WriteInt( refSound.referenceSound->Index() ); - } else { - WriteInt( 0 ); - } - WriteVec3( refSound.origin ); - WriteInt( refSound.listenerId ); - WriteSoundShader( refSound.shader ); - WriteFloat( refSound.diversity ); - WriteBool( refSound.waitfortrigger ); - - WriteFloat( refSound.parms.minDistance ); - WriteFloat( refSound.parms.maxDistance ); - WriteFloat( refSound.parms.volume ); - WriteFloat( refSound.parms.shakes ); - WriteInt( refSound.parms.soundShaderFlags ); - WriteInt( refSound.parms.soundClass ); -} - -void idSaveGame::WriteRenderView( const renderView_t &view ) { - int i; - - WriteInt( view.viewID ); - WriteInt( view.x ); - WriteInt( view.y ); - WriteInt( view.width ); - WriteInt( view.height ); - - WriteFloat( view.fov_x ); - WriteFloat( view.fov_y ); - WriteVec3( view.vieworg ); - WriteMat3( view.viewaxis ); - - WriteBool( view.cramZNear ); - - WriteInt( view.time ); - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - WriteFloat( view.shaderParms[ i ] ); - } -} - -void idSaveGame::WriteUsercmd( const usercmd_t &usercmd ) { - WriteInt( usercmd.gameFrame ); - WriteInt( usercmd.gameTime ); - WriteInt( usercmd.duplicateCount ); - WriteByte( usercmd.buttons ); - WriteSignedChar( usercmd.forwardmove ); - WriteSignedChar( usercmd.rightmove ); - WriteSignedChar( usercmd.upmove ); - WriteShort( usercmd.angles[0] ); - WriteShort( usercmd.angles[1] ); - WriteShort( usercmd.angles[2] ); - WriteShort( usercmd.mx ); - WriteShort( usercmd.my ); - WriteSignedChar( usercmd.impulse ); - WriteByte( usercmd.flags ); - WriteInt( usercmd.sequence ); -} - -void idSaveGame::WriteContactInfo( const contactInfo_t &contactInfo ) { - WriteInt( (int)contactInfo.type ); - WriteVec3( contactInfo.point ); - WriteVec3( contactInfo.normal ); - WriteFloat( contactInfo.dist ); - WriteInt( contactInfo.contents ); - WriteMaterial( contactInfo.material ); - WriteInt( contactInfo.modelFeature ); - WriteInt( contactInfo.trmFeature ); - WriteInt( contactInfo.entityNum ); - WriteInt( contactInfo.id ); -} - -void idSaveGame::WriteTrace( const trace_t &trace ) { - WriteFloat( trace.fraction ); - WriteVec3( trace.endpos ); - WriteMat3( trace.endAxis ); - WriteContactInfo( trace.c ); -} - -void idSaveGame::WriteTraceModel( const idTraceModel &trace ) { - int j, k; - - WriteInt( (int&)trace.type ); - WriteInt( trace.numVerts ); - for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) { - WriteVec3( trace.verts[j] ); - } - WriteInt( trace.numEdges ); - for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) { - WriteInt( trace.edges[j].v[0] ); - WriteInt( trace.edges[j].v[1] ); - WriteVec3( trace.edges[j].normal ); - } - WriteInt( trace.numPolys ); - for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) { - WriteVec3( trace.polys[j].normal ); - WriteFloat( trace.polys[j].dist ); - WriteBounds( trace.polys[j].bounds ); - WriteInt( trace.polys[j].numEdges ); - for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) { - WriteInt( trace.polys[j].edges[k] ); - } - } - WriteVec3( trace.offset ); - WriteBounds( trace.bounds ); - WriteBool( trace.isConvex ); - // padding win32 native structs - char tmp[3]; - memset( tmp, 0, sizeof( tmp ) ); - Write( tmp, 3 ); -} - -void idSaveGame::WriteClipModel( const idClipModel *clipModel ) { - if ( clipModel != NULL ) { - WriteBool( true ); - clipModel->Save( this ); - } else { - WriteBool( false ); - } -} - -void idSaveGame::WriteUserInterface( const idUserInterface *ui, bool unique ) { - const char *name; - - if ( !ui ) { - WriteString( "" ); - } else { - name = ui->Name(); - WriteString( name ); - WriteBool( unique ); - if ( ui->WriteToSaveGame( file ) == false ) { - gameLocal.Error( "idSaveGame::WriteUserInterface: ui failed to write properly\n" ); - } - } -} - -void idSaveGame::WriteSoundCommands( void ) { - gameSoundWorld->WriteToSaveGame( file ); -} - -void idSaveGame::WriteHeader() { - file->WriteInt( BUILD_NUMBER ); - file->WriteInt(RevisionTracker::Instance().GetHighestRevision()); - isCompressed = cv_savegame_compress.GetBool(); - file->WriteBool(isCompressed); -} - -/*********************************************************************** - - idRestoreGame - -***********************************************************************/ - -idRestoreGame::idRestoreGame( idFile *savefile ) { - file = savefile; -} - -idRestoreGame::~idRestoreGame() { -} - -void idRestoreGame::InitializeCache() { - if (!isCompressed) return; - - //move to end of file - int position = file->Tell(); - file->Seek(-4, FS_SEEK_END); - if (file->Tell() == position) - Error( "idRestoreGame::InitializeCache: file->Seek failed"); - - //read offset to cache and rollback - int offset = 666; - file->ReadInt(offset); - if (offset >= 0) - Error( "idRestoreGame::InitializeCache: bad cache offset (%d)", offset); - file->Seek(offset, FS_SEEK_CUR); - - //read compressed cache size - int zipSize = -1; - file->ReadInt(zipSize); - if (zipSize <= 0) - Error("idRestoreGame::InitializeCache: bad compressed cache size (%d)", zipSize); - - //read decompressed cache size - int cacheSize = -1; - file->ReadInt(cacheSize); - if (cacheSize <= 0) - Error("idRestoreGame::InitializeCache: bad uncompressed cache size (%d)", cacheSize); - - //read compressed data - CRawVector zipped; - zipped.resize(zipSize); - cache.resize(cacheSize); - file->Read(&zipped[0], zipped.size()); - - //decompress data - int err = uncompress( - (Bytef *)&cache[0], (uLongf*)&cacheSize, - (const Bytef *)&zipped[0], zipped.size()); - if (err != Z_OK) - Error("idRestoreGame::InitializeCache: uncompress failed with code %d", err); - if (cacheSize != cache.size()) - Error("idRestoreGame::InitializeCache: uncompressed size is %d instead of %d", cacheSize, cache.size()); - - //set cache pointer - cachePointer = 0; - //return file pointer - file->Seek(position, FS_SEEK_SET); -} - -void idRestoreGame::CreateObjects( void ) { - int i, num; - idStr classname; - idTypeInfo *type; - - ReadInt( num ); - - // create all the objects - objects.SetNum( num + 1 ); - memset( objects.Ptr(), 0, sizeof( objects[ 0 ] ) * objects.Num() ); - - for( i = 1; i < objects.Num(); i++ ) { - ReadString( classname ); - type = idClass::GetClass( classname ); - if ( !type ) { - Error( "idRestoreGame::CreateObjects: Unknown class '%s'", classname.c_str() ); - } - objects[ i ] = type->CreateInstance(); - -#ifdef ID_DEBUG_MEMORY - InitTypeVariables( objects[i], type->classname, 0xce ); -#endif - } -} - -void idRestoreGame::RestoreObjects( void ) { - int i; - - ReadSoundCommands(); - - // read trace models - idClipModel::RestoreTraceModels( this ); - - // restore all the objects - for( i = 1; i < objects.Num(); i++ ) { - CallRestore_r( objects[ i ]->GetType(), objects[ i ] ); - } - - // regenerate render entities and render lights because are not saved - for( i = 1; i < objects.Num(); i++ ) { - if ( objects[ i ]->IsType( idEntity::Type ) ) { - idEntity *ent = static_cast( objects[ i ] ); - ent->UpdateVisuals(); - ent->Present(); - } - } - -#ifdef ID_DEBUG_MEMORY - idStr gameState = file->GetName(); - gameState.StripFileExtension(); - WriteGameState_f( idCmdArgs( va( "test %s_restore", gameState.c_str() ), false ) ); - //CompareGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ) ) ); - gameLocal.Error( "dumped game states" ); -#endif -} - -void idRestoreGame::DeleteObjects( void ) { - - // Remove the NULL object before deleting - objects.RemoveIndex( 0 ); - - objects.DeleteContents( true ); -} - -void idRestoreGame::Error( const char *fmt, ... ) { - va_list argptr; - char text[ 1024 ]; - - va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); - va_end( argptr ); - - objects.DeleteContents( true ); - - gameLocal.Error( "%s", text ); -} - -void idRestoreGame::CallRestore_r( const idTypeInfo *cls, idClass *obj ) { - if ( cls->super ) { - CallRestore_r( cls->super, obj ); - if ( cls->super->Restore == cls->Restore ) { - // don't call save on this inheritance level since the function was called in the super class - return; - } - } - - ( obj->*cls->Restore )( this ); -} - -void idRestoreGame::Read( void *buffer, int len ) { - if (len == 0) return; - if (isCompressed) { - assert(cachePointer + len <= int(cache.size())); - memcpy(buffer, &cache[cachePointer], len); - cachePointer += len; - } - else - file->Read(buffer, len); -} - -void idRestoreGame::ReadJoint( jointHandle_t &value ) { - ReadInt( (int&)value ); -} - -void idRestoreGame::ReadByte( byte &value ) { - ReadUnsignedChar(value); -} - -void idRestoreGame::ReadSignedChar( signed char &value ) { - ReadChar( (char&)value ); -} - -void idRestoreGame::ReadString( idStr &string ) { - int len; - - ReadInt( len ); - if ( len < 0 ) { - Error( "idRestoreGame::ReadString: invalid length (%d)", len ); - } - - string.Fill( ' ', len ); - Read( &string[ 0 ], len ); -} - -void idRestoreGame::ReadBounds( idBounds &bounds ) { - ReadVec3(bounds[0]); - ReadVec3(bounds[1]); -} - -void idRestoreGame::ReadBox( idBox &box ) { - idVec3 center, extents; - idMat3 axis; - ReadVec3(center); - ReadVec3(extents); - ReadMat3(axis); - box = idBox(center, extents, axis); -} - -void idRestoreGame::ReadWinding( idWinding &w ) { - int i, num; - ReadInt( num ); - if (num < 0) - Error("idRestoreGame::ReadWinding: negative number of points (%d)", num); - w.SetNumPoints( num ); - for ( i = 0; i < num; i++ ) - ReadVec5(w[i]); -} - -void idRestoreGame::ReadObject( idClass *&obj ) { - int index; - - ReadInt( index ); - if ( ( index < 0 ) || ( index >= objects.Num() ) ) { - Error( "idRestoreGame::ReadObject: invalid object index" ); - } - obj = objects[ index ]; -} - -void idRestoreGame::ReadStaticObject( idClass &obj ) { - CallRestore_r( obj.GetType(), &obj ); -} - -void idRestoreGame::ReadDict( idDict *dict ) { - int num; - int i; - idStr key; - idStr value; - - ReadInt( num ); - - if ( num < 0 ) { - dict = NULL; - } else { - dict->Clear(); - for( i = 0; i < num; i++ ) { - ReadString( key ); - ReadString( value ); - dict->Set( key, value ); - } - } -} - -void idRestoreGame::ReadMaterial( const idMaterial *&material ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - material = NULL; - } else { - material = declManager->FindMaterial( name ); - } -} - -void idRestoreGame::ReadSkin( const idDeclSkin *&skin ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - skin = NULL; - } else { - skin = declManager->FindSkin( name ); - } -} - -void idRestoreGame::ReadParticle( const idDeclParticle *&particle ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - particle = NULL; - } else { - particle = static_cast( declManager->FindType( DECL_PARTICLE, name ) ); - } -} - -void idRestoreGame::ReadFX( const idDeclFX *&fx ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - fx = NULL; - } else { - fx = static_cast( declManager->FindType( DECL_FX, name ) ); - } -} - -void idRestoreGame::ReadSoundShader( const idSoundShader *&shader ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - shader = NULL; - } else { - shader = declManager->FindSound( name ); - } -} - -void idRestoreGame::ReadModelDef( const idDeclModelDef *&modelDef ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - modelDef = NULL; - } else { - modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name, false ) ); - } -} - -void idRestoreGame::ReadModel( idRenderModel *&model ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - model = NULL; - } else { - model = renderModelManager->FindModel( name ); - } -} - -void idRestoreGame::ReadUserInterface( idUserInterface *&ui ) { - idStr name; - - ReadString( name ); - if ( !name.Length() ) { - ui = NULL; - } else { - bool unique; - ReadBool( unique ); - ui = uiManager->FindGui( name, true, unique ); - if ( ui ) { - if ( ui->ReadFromSaveGame( file ) == false ) { - Error( "idSaveGame::ReadUserInterface: ui failed to read properly\n" ); - } else { - ui->StateChanged( gameLocal.time ); - } - } - } -} - -void idRestoreGame::ReadRenderEntity( renderEntity_t &renderEntity ) { - int i; - int index; - - ReadModel( renderEntity.hModel ); - - ReadInt( renderEntity.entityNum ); - ReadInt( renderEntity.bodyId ); - - ReadBounds( renderEntity.bounds ); - - // callback is set by class's Restore function - renderEntity.callback = NULL; - renderEntity.callbackData = NULL; - - ReadInt( renderEntity.suppressSurfaceInViewID ); - ReadInt( renderEntity.suppressShadowInViewID ); - ReadInt( renderEntity.suppressShadowInLightID ); - ReadInt( renderEntity.allowSurfaceInViewID ); - - ReadVec3( renderEntity.origin ); - ReadMat3( renderEntity.axis ); - - ReadMaterial( renderEntity.customShader ); - ReadMaterial( renderEntity.referenceShader ); - ReadSkin( renderEntity.customSkin ); - - ReadInt( index ); - renderEntity.referenceSound = gameSoundWorld->EmitterForIndex( index ); - - for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { - ReadFloat( renderEntity.shaderParms[ i ] ); - } - - for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - ReadUserInterface( renderEntity.gui[ i ] ); - } - - // idEntity will restore "cameraTarget", which will be used in idEntity::Present to restore the remoteRenderView - renderEntity.remoteRenderView = NULL; - - renderEntity.joints = NULL; - renderEntity.numJoints = 0; - - ReadFloat( renderEntity.modelDepthHack ); - - ReadBool( renderEntity.noSelfShadow ); - ReadBool( renderEntity.noShadow ); - ReadBool( renderEntity.noDynamicInteractions ); - ReadBool( renderEntity.weaponDepthHack ); - - ReadInt( renderEntity.forceUpdate ); -} - -void idRestoreGame::ReadRenderLight( renderLight_t &renderLight ) { - int index; - int i; - - ReadMat3( renderLight.axis ); - ReadVec3( renderLight.origin ); - - ReadInt( renderLight.suppressLightInViewID ); - ReadInt( renderLight.allowLightInViewID ); - ReadBool( renderLight.noShadows ); - ReadBool( renderLight.noSpecular ); - ReadBool( renderLight.pointLight ); - ReadBool( renderLight.parallel ); - - ReadVec3( renderLight.lightRadius ); - ReadVec3( renderLight.lightCenter ); - - ReadVec3( renderLight.target ); - ReadVec3( renderLight.right ); - ReadVec3( renderLight.up ); - ReadVec3( renderLight.start ); - ReadVec3( renderLight.end ); - - // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there - // ReadModel( renderLight.prelightModel ); - renderLight.prelightModel = NULL; - - ReadInt( renderLight.lightId ); - - ReadMaterial( renderLight.shader ); - - for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { - ReadFloat( renderLight.shaderParms[ i ] ); - } - - ReadInt( index ); - renderLight.referenceSound = gameSoundWorld->EmitterForIndex( index ); -} - -void idRestoreGame::ReadRefSound( refSound_t &refSound ) { - int index; - ReadInt( index ); - - refSound.referenceSound = gameSoundWorld->EmitterForIndex( index ); - ReadVec3( refSound.origin ); - ReadInt( refSound.listenerId ); - ReadSoundShader( refSound.shader ); - ReadFloat( refSound.diversity ); - ReadBool( refSound.waitfortrigger ); - - ReadFloat( refSound.parms.minDistance ); - ReadFloat( refSound.parms.maxDistance ); - ReadFloat( refSound.parms.volume ); - ReadFloat( refSound.parms.shakes ); - ReadInt( refSound.parms.soundShaderFlags ); - ReadInt( refSound.parms.soundClass ); -} - -void idRestoreGame::ReadRenderView( renderView_t &view ) { - int i; - - ReadInt( view.viewID ); - ReadInt( view.x ); - ReadInt( view.y ); - ReadInt( view.width ); - ReadInt( view.height ); - - ReadFloat( view.fov_x ); - ReadFloat( view.fov_y ); - ReadVec3( view.vieworg ); - ReadMat3( view.viewaxis ); - - ReadBool( view.cramZNear ); - - ReadInt( view.time ); - - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - ReadFloat( view.shaderParms[ i ] ); - } -} - -void idRestoreGame::ReadUsercmd( usercmd_t &usercmd ) { - ReadInt( usercmd.gameFrame ); - ReadInt( usercmd.gameTime ); - ReadInt( usercmd.duplicateCount ); - ReadByte( usercmd.buttons ); - ReadSignedChar( usercmd.forwardmove ); - ReadSignedChar( usercmd.rightmove ); - ReadSignedChar( usercmd.upmove ); - ReadShort( usercmd.angles[0] ); - ReadShort( usercmd.angles[1] ); - ReadShort( usercmd.angles[2] ); - ReadShort( usercmd.mx ); - ReadShort( usercmd.my ); - ReadSignedChar( usercmd.impulse ); - ReadByte( usercmd.flags ); - ReadInt( usercmd.sequence ); -} - -void idRestoreGame::ReadContactInfo( contactInfo_t &contactInfo ) { - ReadInt( (int &)contactInfo.type ); - ReadVec3( contactInfo.point ); - ReadVec3( contactInfo.normal ); - ReadFloat( contactInfo.dist ); - ReadInt( contactInfo.contents ); - ReadMaterial( contactInfo.material ); - ReadInt( contactInfo.modelFeature ); - ReadInt( contactInfo.trmFeature ); - ReadInt( contactInfo.entityNum ); - ReadInt( contactInfo.id ); -} - -void idRestoreGame::ReadTrace( trace_t &trace ) { - ReadFloat( trace.fraction ); - ReadVec3( trace.endpos ); - ReadMat3( trace.endAxis ); - ReadContactInfo( trace.c ); -} - -void idRestoreGame::ReadTraceModel( idTraceModel &trace ) { - int j, k; - - ReadInt( (int&)trace.type ); - ReadInt( trace.numVerts ); - for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) { - ReadVec3( trace.verts[j] ); - } - ReadInt( trace.numEdges ); - for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) { - ReadInt( trace.edges[j].v[0] ); - ReadInt( trace.edges[j].v[1] ); - ReadVec3( trace.edges[j].normal ); - } - ReadInt( trace.numPolys ); - for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) { - ReadVec3( trace.polys[j].normal ); - ReadFloat( trace.polys[j].dist ); - ReadBounds( trace.polys[j].bounds ); - ReadInt( trace.polys[j].numEdges ); - for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) { - ReadInt( trace.polys[j].edges[k] ); - } - } - ReadVec3( trace.offset ); - ReadBounds( trace.bounds ); - ReadBool( trace.isConvex ); - // padding win32 native structs - char tmp[3]; - Read( tmp, 3 ); -} - -void idRestoreGame::ReadClipModel( idClipModel *&clipModel ) { - bool restoreClipModel; - - ReadBool( restoreClipModel ); - if ( restoreClipModel ) { - clipModel = new idClipModel(); - clipModel->Restore( this ); - } else { - clipModel = NULL; - } -} - -void idRestoreGame::ReadSoundCommands( void ) { - gameSoundWorld->StopAllSounds(); - gameSoundWorld->ReadFromSaveGame( file ); -} - -void idRestoreGame::ReadHeader( void ) { - file->ReadInt( buildNumber ); - file->ReadInt( codeRevision ); - file->ReadBool(isCompressed); -} - -/*********************************************************************** - - Read/write for common types - -***********************************************************************/ - -#define LittleChar(x) x - -#define DEFINE_READWRITE_PRIMITIVE(cpp_type, name_type, conv_type) \ -void idRestoreGame::Read##name_type (cpp_type &value) \ -{ \ - if (isCompressed) { \ - const cpp_type *value_ptr = (const cpp_type*)&cache[cachePointer]; \ - value = Little##conv_type (*value_ptr); \ - cachePointer += sizeof(cpp_type); \ - } \ - else \ - file->Read##name_type(value); \ -} \ -void idSaveGame::Write##name_type (const cpp_type value) \ -{ \ - if (isCompressed) { \ - int sz = cache.size(); \ - cache.resize(sz + sizeof(cpp_type)); \ - cpp_type *value_ptr = (cpp_type*)&cache[sz]; \ - *value_ptr = Little##conv_type (value); \ - } \ - else \ - file->Write##name_type(value); \ -} - -DEFINE_READWRITE_PRIMITIVE(int, Int, Long) -DEFINE_READWRITE_PRIMITIVE(unsigned int, UnsignedInt, Long) -DEFINE_READWRITE_PRIMITIVE(short, Short, Short) -DEFINE_READWRITE_PRIMITIVE(char, Char, Char) -DEFINE_READWRITE_PRIMITIVE(unsigned char, UnsignedChar, Char) -DEFINE_READWRITE_PRIMITIVE(float, Float, Float) -DEFINE_READWRITE_PRIMITIVE(bool, Bool, Char) - -#define DEFINE_READWRITE_VECMAT(cpp_type, name_type) \ -void idRestoreGame::Read##name_type (cpp_type &vec) \ -{ \ - for (int i = 0; i objects; - - bool isCompressed; - CRawVector cache; - - void CallSave_r( const idTypeInfo *cls, const idClass *obj ); -}; - -class idRestoreGame { -public: - idRestoreGame( idFile *savefile ); - ~idRestoreGame(); - - void CreateObjects( void ); - void RestoreObjects( void ); - void DeleteObjects( void ); - - void Error( const char *fmt, ... ) id_attribute((format(printf,2,3))); - - void Read( void *buffer, int len ); - - void ReadInt( int &value ); - void ReadUnsignedInt( unsigned int &value ); - void ReadShort( short &value ); - void ReadUnsignedShort( unsigned short &value ); - void ReadChar( char &value ); - void ReadUnsignedChar( unsigned char &value ); - void ReadFloat( float &value ); - void ReadBool( bool &value ); - void ReadString( idStr &string ); - - void ReadJoint( jointHandle_t &value ); - void ReadByte( byte &value ); - void ReadSignedChar( signed char &value ); - - void ReadVec2( idVec2 &vec ); - void ReadVec3( idVec3 &vec ); - void ReadVec4( idVec4 &vec ); - void ReadVec5( idVec5 &vec ); - void ReadVec6( idVec6 &vec ); - void ReadMat3( idMat3 &mat ); - - void ReadWinding( idWinding &winding ); - void ReadBounds( idBounds &bounds ); - void ReadBox( idBox &box ); - void ReadAngles( idAngles &angles ); - void ReadObject( idClass *&obj ); - void ReadStaticObject( idClass &obj ); - void ReadDict( idDict *dict ); - void ReadMaterial( const idMaterial *&material ); - void ReadSkin( const idDeclSkin *&skin ); - void ReadParticle( const idDeclParticle *&particle ); - void ReadFX( const idDeclFX *&fx ); - void ReadSoundShader( const idSoundShader *&shader ); - void ReadModelDef( const idDeclModelDef *&modelDef ); - void ReadModel( idRenderModel *&model ); - void ReadUserInterface( idUserInterface *&ui ); - void ReadRenderEntity( renderEntity_t &renderEntity ); - void ReadRenderLight( renderLight_t &renderLight ); - void ReadRefSound( refSound_t &refSound ); - void ReadRenderView( renderView_t &view ); - void ReadUsercmd( usercmd_t &usercmd ); - void ReadContactInfo( contactInfo_t &contactInfo ); - void ReadTrace( trace_t &trace ); - void ReadTraceModel( idTraceModel &trace ); - void ReadClipModel( idClipModel *&clipModel ); - void ReadSoundCommands( void ); - - // Read all the data necessary to determine the save format - void ReadHeader(); - - // Read the contents of cache buffer before restoring - void InitializeCache(); - - inline int GetBuildNumber() { return buildNumber; } - inline int GetCodeRevision() { return codeRevision; } - -private: - idFile * file; - - int buildNumber; - int codeRevision; - - idList objects; - - bool isCompressed; - CRawVector cache; - int cachePointer; - - void CallRestore_r( const idTypeInfo *cls, idClass *obj ); -}; - -#endif /* !__SAVEGAME_H__*/ diff --git a/game/gamesys/syscmds.cpp b/game/gamesys/syscmds.cpp deleted file mode 100644 index 2bd56333e..000000000 --- a/game/gamesys/syscmds.cpp +++ /dev/null @@ -1,3852 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" - -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../ai/aas_local.h" -#include "../../DarkMod/sndPropLoader.h" -#include "../../DarkMod/Relations.h" -#include "../../DarkMod/Objectives/MissionData.h" -#include "../../DarkMod/Inventory/Inventory.h" -#include "../../DarkMod/Inventory/Item.h" -#include "../../DarkMod/TimerManager.h" -#include "../../DarkMod/AI/Conversation/ConversationSystem.h" -#include "../../DarkMod/Missions/MissionManager.h" -#include "../../DarkMod/Missions/ModInfo.h" - -#include "typeinfo.h" - -/* -================== -Cmd_TestSndIO_f -================== -*/ -void Cmd_TestSndIO_f( const idCmdArgs &args ) -{ - idStr inFN; - - if ( args.Argc() < 2 ) { - gameLocal.Printf( "usage: dm_spr_testIO \n" ); - goto Quit; - } - inFN = args.Args(); - - if ( inFN.Length() == 0 ) - { - goto Quit; - } - -// New file IO not yet implemented -// gameLocal.Printf( "Testing sound prop. IO for file %s\n", inFN.c_str() ); - gameLocal.Printf( "New soundprop file IO not yet implemented\n"); -Quit: - return; -} - -/* -================== -Cmd_PrintAIRelations_f -================== -*/ -void Cmd_PrintAIRelations_f( const idCmdArgs &args ) -{ - gameLocal.m_RelationsManager->DebugPrintMat(); - return; -} - -/** - * greebo: This is a helper command, used by the restart.gui - */ -void Cmd_RestartGuiCmd_UpdateObjectives_f(const idCmdArgs &args) -{ - idUserInterface* gui = uiManager->FindGui("guis/restart.gui", false, true, true); - - if (gui == NULL) - { - gameLocal.Warning("Could not find restart.gui"); - return; - } - - gameLocal.m_MissionData->UpdateGUIState(gui); -} - -void Cmd_ListMissions_f(const idCmdArgs& args) -{ - gameLocal.Printf("%d missions registered:\n", gameLocal.m_MissionManager->GetNumMods()); - - for (int i = 0; i < gameLocal.m_MissionManager->GetNumMods(); ++i) - { - CModInfoPtr missionInfo = gameLocal.m_MissionManager->GetModInfo(i); - - if (missionInfo == NULL) continue; - - gameLocal.Printf("%02d: %s = %s\n", i, missionInfo->modName.c_str(), missionInfo->displayName.c_str()); - } -} - -void Cmd_SetMissionCompleted_f(const idCmdArgs& args) -{ - if (args.Argc() < 2) - { - gameLocal.Printf("Usage: tdm_set_mission_completed [-c]\n"); - gameLocal.Printf("The -c argument is optional, can be used to clear the 'completed' flag, such that the mission isn't listed as completed in the mission menu.\n\n"); - gameLocal.Printf("Example: 'tdm_set_mission_completed heart'\n"); - return; - } - - bool clearFlag = false; - idStr missionName; - - for (int i = 1; i < args.Argc(); ++i) - { - idStr arg = args.Argv(i); - - if (arg == "-") - { - if (++i < args.Argc() && idStr::Cmp(args.Argv(i), "c") == 0) - { - clearFlag = true; - } - } - else - { - missionName = arg; - } - } - - if (missionName.IsEmpty()) - { - return; - } - - CModInfoPtr missionInfo = gameLocal.m_MissionManager->GetModInfo(missionName); - - if (missionInfo == NULL) - { - gameLocal.Printf("Mission %s not found.\n", missionName.c_str()); - return; - } - - if (clearFlag) - { - // Remove completed flags - missionInfo->RemoveKeyValuesMatchingPrefix("mission_completed_"); - } - else - { - // Mark mission as completed on all difficulties - for (int i = 0; i < DIFFICULTY_COUNT; ++i) - { - missionInfo->SetKeyValue(va("mission_completed_%d", i), "1"); - } - } - - gameLocal.Printf("OK"); -} - -void Cmd_EndMission_f(const idCmdArgs& args) -{ - if (gameLocal.GameState() != GAMESTATE_ACTIVE) - { - gameLocal.Printf("No map running\n"); - return; - } - - if (gameLocal.GetLocalPlayer() != NULL) - { - gameLocal.Printf("=== Triggering mission end ===\n"); - gameLocal.GetLocalPlayer()->PostEventMS(&EV_TriggerMissionEnd, 0); - } -} - -/* -================== -Cmd_AttachmentOffset_f -================== -*/ -void Cmd_AttachmentOffset_f( const idCmdArgs &args ) -{ - idVec3 offset(vec3_zero); - - if( args.Argc() != 6 ) - { - gameLocal.Printf( "usage: tdm_attach_offset \n" ); - return; - } - - idEntity* lookedAt = gameLocal.PlayerTraceEntity(); - if (lookedAt == NULL || !(lookedAt->IsType(idActor::Type)) ) - { - gameLocal.Printf( "tdm_attach_offset must be called when looking at an AI\n" ); - return; - } - - idActor* actor = static_cast(lookedAt); - - idStr attName = args.Argv(1); - idStr attPosName = args.Argv(2); - - int attIndex = actor->GetAttachmentIndex(attName); - - SAttachPosition* pos = actor->GetAttachPosition(attPosName); - if (pos == NULL) - { - gameLocal.Printf( "tdm_attach_offset could not find position attPosName %s\n", attPosName.c_str() ); - return; - } - - idStr joint = actor->GetAnimator()->GetJointName(pos->joint); - - // overwrite the attachment with our new attachment - offset.x = atof(args.Argv( 3 )); - offset.y = atof(args.Argv( 4 )); - offset.z = atof(args.Argv( 5 )); - - actor->ReAttachToCoords( attName, joint, offset, pos->angleOffset ); -} - -/* -================== -Cmd_AttachmentRot_f -================== -*/ -void Cmd_AttachmentRot_f( const idCmdArgs &args ) -{ - idVec3 offset(vec3_zero); - - if( args.Argc() != 6 ) - { - gameLocal.Printf( "usage: tdm_attach_rot \n" ); - return; - } - - idEntity* lookedAt = gameLocal.PlayerTraceEntity(); - if (lookedAt == NULL || !(lookedAt->IsType(idActor::Type)) ) - { - gameLocal.Printf( "tdm_attach_rot must be called when looking at an AI\n" ); - return; - } - - idActor* actor = static_cast(lookedAt); - - idStr attName = args.Argv(1); - idStr attPosName = args.Argv(2); - - int attIndex = actor->GetAttachmentIndex(attName); - - SAttachPosition* pos = actor->GetAttachPosition(attPosName); - if (pos == NULL) - { - gameLocal.Printf( "tdm_attach_rot could not find position attPosName %s\n", attPosName.c_str() ); - return; - } - - idStr joint = actor->GetAnimator()->GetJointName(pos->joint); - - // overwrite the attachment rotation with our new one - idAngles angles; - angles.pitch = atof(args.Argv( 3 )); - angles.yaw = atof(args.Argv( 4 )); - angles.roll = atof(args.Argv( 5 )); - - actor->ReAttachToCoords( attName, joint, pos->originOffset, angles ); -} - -/* -================== -Cmd_InventoryHotkey_f -================== -*/ -void Cmd_InventoryHotkey_f( const idCmdArgs &args ) -{ - if ( 0 > args.Argc() || args.Argc() > 2 ) { - gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); - return; - } - - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player == NULL ) { - gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); - return; - } - - if( player->GetImmobilization() & EIM_ITEM_SELECT ) - return; - - CInventoryCursorPtr cursor = player->InventoryCursor(); - CInventory* inventory = cursor->Inventory(); - - if (inventory == NULL) - { - gameLocal.Printf( "%s: Could not find player inventory.\n", args.Argv(0) ); - return; - } - - if( args.Argc() == 2) - { - // support either "#str_02395" or "Lantern" as input - idStr itemName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); - player->SelectInventoryItem( itemName ); - } - else if (args.Argc() == 1) - { - // greebo: Clear the item if no argument is set - player->SelectInventoryItem(""); - } -} - -/* -================== -Cmd_InventoryUse_f -================== -*/ -void Cmd_InventoryUse_f( const idCmdArgs &args ) -{ - if ( 0 > args.Argc() || args.Argc() > 2 ) { - gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); - return; - } - - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player == NULL ) { - gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); - return; - } - - if( player->GetImmobilization() & EIM_ITEM_USE ) - return; - - CInventoryCursorPtr cursor = player->InventoryCursor(); - CInventory* inventory = cursor->Inventory(); - - if (inventory == NULL) - { - gameLocal.Printf( "%s: Could not find player inventory.\n", args.Argv(0) ); - return; - } - - if( args.Argc() == 2) - { - // support either "#str_02395" or "Lantern" as input - idStr itemName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); - - // Try to lookup the item in the inventory - CInventoryItemPtr item = inventory->GetItem( itemName ); - - if (item != NULL) - { - // Item found, set the cursor to it - player->UseInventoryItem(EPressed, item, 0, false); // false => no frob action - } - else - { - gameLocal.Printf( "%s: Can't find item in player inventory: %s (%s)\n", args.Argv(0), args.Argv(1), gameLocal.m_I18N->Translate(itemName) ); - } - } -} - -/* -================== -Cmd_InventoryCycleMaps_f -================== -*/ -void Cmd_InventoryCycleMaps_f( const idCmdArgs &args ) -{ - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player == NULL ) { - gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); - return; - } - - if( (player->GetImmobilization() & EIM_ITEM_SELECT) || (player->GetImmobilization() & EIM_ITEM_USE) ) - return; - - // Pass the call to the specialised method - player->NextInventoryMap(); -} - -/* -================== -Cmd_InventoryCycleGroup_f -================== -*/ -void Cmd_InventoryCycleGroup_f( const idCmdArgs &args ) -{ - if ( 0 > args.Argc() || args.Argc() > 2 ) - { - gameLocal.Printf( "Usage: %s [item]\n", args.Argv(0) ); - return; - } - - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player == NULL ) - { - gameLocal.Printf( "%s: No player exists.\n", args.Argv(0) ); - return; - } - - if( (player->GetImmobilization() & EIM_ITEM_SELECT) || (player->GetImmobilization() & EIM_ITEM_USE) ) - { - return; - } - - if( args.Argc() == 2) - { - // support either "#str_02391" or "Readables" as input - idStr categoryName = gameLocal.m_I18N->TemplateFromEnglish( args.Argv(1) ); - - // Pass the call to the specialised method - player->CycleInventoryGroup( categoryName ); - } -} - -/* -================== -Cmd_GetFloatArg -================== -*/ -float Cmd_GetFloatArg( const idCmdArgs &args, int &argNum ) { - const char *value; - - value = args.Argv( argNum++ ); - return atof( value ); -} - -/* -=================== -Cmd_EntityList_f -=================== -*/ -void Cmd_EntityList_f( const idCmdArgs &args ) { - int e; - idEntity *check; - int count; - size_t size; - idStr match; - - if ( args.Argc() > 1 ) { - match = args.Args(); - match.Replace( " ", "" ); - } else { - match = ""; - } - - count = 0; - size = 0; - - gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" ); - gameLocal.Printf( "--------------------------------------------------------------------\n" ); - for( e = 0; e < MAX_GENTITIES; e++ ) { - check = gameLocal.entities[ e ]; - - if ( !check ) { - continue; - } - - if ( !check->name.Filter( match, true ) ) { - continue; - } - - gameLocal.Printf( "%4i: %-20s %-20s %s\n", e, - check->GetEntityDefName(), check->GetClassname(), check->name.c_str() ); - - count++; - size += check->spawnArgs.Allocated(); - } - - gameLocal.Printf( "...%d entities\n...%d bytes of spawnargs\n", count, size ); -} - -/* -=================== -Cmd_ActiveEntityList_f -=================== -*/ -void Cmd_ActiveEntityList_f( const idCmdArgs &args ) { - idEntity *check; - int count; - - count = 0; - - gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" ); - gameLocal.Printf( "--------------------------------------------------------------------\n" ); - for( check = gameLocal.activeEntities.Next(); check != NULL; check = check->activeNode.Next() ) { - char dormant = check->fl.isDormant ? '-' : ' '; - gameLocal.Printf( "%4i:%c%-20s %-20s %s\n", check->entityNumber, dormant, check->GetEntityDefName(), check->GetClassname(), check->name.c_str() ); - count++; - } - - gameLocal.Printf( "...%d active entities\n", count ); -} - -/* -=================== -Cmd_ListSpawnArgs_f -=================== -*/ -void Cmd_ListSpawnArgs_f( const idCmdArgs &args ) { - int i; - idEntity *ent; - - ent = gameLocal.FindEntity( args.Argv( 1 ) ); - if ( !ent ) { - gameLocal.Printf( "entity not found\n" ); - return; - } - - for ( i = 0; i < ent->spawnArgs.GetNumKeyVals(); i++ ) { - const idKeyValue *kv = ent->spawnArgs.GetKeyVal( i ); - gameLocal.Printf( "\"%s\" "S_COLOR_WHITE"\"%s\"\n", kv->GetKey().c_str(), kv->GetValue().c_str() ); - } -} - -/* -=================== -Cmd_ReloadScript_f -=================== -*/ -void Cmd_ReloadScript_f( const idCmdArgs &args ) { - // shutdown the map because entities may point to script objects - gameLocal.MapShutdown(); - - // recompile the scripts - gameLocal.program.Startup( SCRIPT_DEFAULT ); - - // error out so that the user can rerun the scripts - gameLocal.Error( "Exiting map to reload scripts" ); -} - -/* -=================== -Cmd_Script_f -=================== -*/ -void Cmd_Script_f( const idCmdArgs &args ) { - const char * script; - idStr text; - idStr funcname; - static int funccount = 0; - idThread * thread; - const function_t *func; - idEntity *ent; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - sprintf( funcname, "ConsoleFunction_%d", funccount++ ); - - script = args.Args(); - sprintf( text, "void %s() {%s;}\n", funcname.c_str(), script ); - if ( gameLocal.program.CompileText( "console", text, true ) ) { - func = gameLocal.program.FindFunction( funcname ); - if ( func ) { - // set all the entity names in case the user named one in the script that wasn't referenced in the default script - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - gameLocal.program.SetEntity( ent->name, ent ); - } - - thread = new idThread( func ); - thread->Start(); - } - } -} - -/* -================== -KillEntities - -Kills all the entities of the given class in a level. -================== -*/ -void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) { - idEntity *ent; - idStrList ignore; - const char *name; - int i; - - if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { - return; - } - - for( i = 1; i < args.Argc(); i++ ) { - name = args.Argv( i ); - ignore.Append( name ); - } - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( superClass ) ) { - for( i = 0; i < ignore.Num(); i++ ) { - if ( ignore[ i ] == ent->name ) { - break; - } - } - - if ( i >= ignore.Num() ) { - ent->PostEventMS( &EV_Remove, 0 ); - } - } - } -} - -/* -================== -Cmd_KillMonsters_f - -Kills all the monsters in a level. -================== -*/ -void Cmd_KillMonsters_f( const idCmdArgs &args ) { - KillEntities( args, idAI::Type ); - - // kill any projectiles as well since they have pointers to the monster that created them - KillEntities( args, idProjectile::Type ); -} - -/* -================== -Cmd_KillMovables_f - -Kills all the moveables in a level. -================== -*/ -void Cmd_KillMovables_f( const idCmdArgs &args ) { - if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { - return; - } - KillEntities( args, idMoveable::Type ); -} - -/* -================== -Cmd_KillRagdolls_f - -Kills all the ragdolls in a level. -================== -*/ -void Cmd_KillRagdolls_f( const idCmdArgs &args ) { - if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { - return; - } - KillEntities( args, idAFEntity_Generic::Type ); - KillEntities( args, idAFEntity_WithAttachedHead::Type ); -} - -/* -================== -Cmd_Give_f - -Give items to a client -================== -*/ -void Cmd_Give_f( const idCmdArgs &args ) { - const char *name; - int i; - bool give_all; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - name = args.Argv( 1 ); - - if ( idStr::Icmp( name, "all" ) == 0 ) { - give_all = true; - } else { - give_all = false; - } - - if ( give_all || ( idStr::Cmpn( name, "weapon", 6 ) == 0 ) ) { - if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { - gameLocal.world->spawnArgs.SetBool( "no_Weapons", false ); - for( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] ) { - gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, gameLocal.entities[ i ]->spawnArgs.GetString( "def_weapon1" ) ); - } - } - } - } - - if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) { - player->GiveItem( name ); - return; - } - - if ( give_all || idStr::Icmp( name, "health" ) == 0 ) { - player->health = player->maxHealth; - if ( !give_all ) { - return; - } - } - - if ( idStr::Icmp( name, "berserk" ) == 0 ) { - player->GivePowerUp( BERSERK, SEC2MS( 30.0f ) ); - return; - } - - if ( idStr::Icmp( name, "invis" ) == 0 ) { - player->GivePowerUp( INVISIBILITY, SEC2MS( 30.0f ) ); - return; - } - - if ( !give_all && !player->Give( args.Argv(1), args.Argv(2) ) ) { - gameLocal.Printf( "unknown item\n" ); - } -} - -/* -================== -Cmd_CenterView_f - -Centers the players pitch -================== -*/ -void Cmd_CenterView_f( const idCmdArgs &args ) { - idPlayer *player; - idAngles ang; - - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - - ang = player->viewAngles; - ang.pitch = 0.0f; - player->SetViewAngles( ang ); -} - -/* -================== -Cmd_God_f - -Sets client to godmode - -argv(0) god -================== -*/ -void Cmd_God_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player->godmode ) { - player->godmode = false; - gameLocal.Printf( "godmode OFF\n" ); - } else { - player->godmode = true; - gameLocal.Printf( "godmode ON\n" ); - } - -} - -/* -================== -Cmd_Notarget_f - -Sets client to notarget - -argv(0) notarget -================== -*/ -void Cmd_Notarget_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player->fl.notarget ) { - player->fl.notarget = false; - gameLocal.Printf( "notarget OFF\n" ); - } else { - player->fl.notarget = true; - gameLocal.Printf( "notarget ON\n" ); - } - -} - -/* -================== -Cmd_Noclip_f - -argv(0) noclip -================== -*/ -void Cmd_Noclip_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player->noclip ) { - player->noclip = false; - gameLocal.Printf( "noclip OFF\n" ); - } else { - player->noclip = true; - gameLocal.Printf( "noclip ON\n" ); - } -} - -/* -================= -Cmd_Kill_f -================= -*/ -void Cmd_Kill_f( const idCmdArgs &args ) { - idPlayer *player; - - if ( gameLocal.isMultiplayer ) { - if ( gameLocal.isClient ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL ); - networkSystem->ClientSendReliableMessage( outMsg ); - } else { - player = gameLocal.GetClientByCmdArgs( args ); - if ( !player ) { - common->Printf( "kill or kill \n" ); - return; - } - player->Kill( false, false ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) ); - } - } else { - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - player->Kill( false, false ); - } -} - -/* -================= -Cmd_PlayerModel_f -================= -*/ -void Cmd_PlayerModel_f( const idCmdArgs &args ) { - idPlayer *player; - const char *name; - idVec3 pos; - idAngles ang; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() < 2 ) { - gameLocal.Printf( "usage: playerModel \n" ); - return; - } - - name = args.Argv( 1 ); - player->spawnArgs.Set( "model", name ); - - pos = player->GetPhysics()->GetOrigin(); - ang = player->viewAngles; - player->SpawnToPoint( pos, ang ); -} - -/* -================== -Cmd_Say -================== -*/ -static void Cmd_Say( bool team, const idCmdArgs &args ) { - const char *name; - idStr text; - const char *cmd = team ? "sayTeam" : "say" ; - - if ( !gameLocal.isMultiplayer ) { - gameLocal.Printf( "%s can only be used in a multiplayer game\n", cmd ); - return; - } - - if ( args.Argc() < 2 ) { - gameLocal.Printf( "usage: %s \n", cmd ); - return; - } - - text = args.Args(); - if ( text.Length() == 0 ) { - return; - } - - if ( text[ text.Length() - 1 ] == '\n' ) { - text[ text.Length() - 1 ] = '\0'; - } - name = "player"; - - idPlayer * player; - - // here we need to special case a listen server to use the real client name instead of "server" - // "server" will only appear on a dedicated server - if ( gameLocal.isClient || cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 0 ) { - player = gameLocal.localClientNum >= 0 ? static_cast( gameLocal.entities[ gameLocal.localClientNum ] ) : NULL; - if ( player ) { - name = player->GetUserInfo()->GetString( "ui_name", "player" ); - } - } else { - name = "server"; - } - - if ( gameLocal.isClient ) { - idBitMsg outMsg; - byte msgBuf[ 256 ]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( team ? GAME_RELIABLE_MESSAGE_TCHAT : GAME_RELIABLE_MESSAGE_CHAT ); - outMsg.WriteString( name ); - outMsg.WriteString( text, -1, false ); - networkSystem->ClientSendReliableMessage( outMsg ); - } else { - gameLocal.mpGame.ProcessChatMessage( gameLocal.localClientNum, team, name, text, NULL ); - } -} - -/* -================== -Cmd_Say_f -================== -*/ -static void Cmd_Say_f( const idCmdArgs &args ) { - Cmd_Say( false, args ); -} - -/* -================== -Cmd_SayTeam_f -================== -*/ -static void Cmd_SayTeam_f( const idCmdArgs &args ) { - Cmd_Say( true, args ); -} - -/* -================== -Cmd_AddChatLine_f -================== -*/ -static void Cmd_AddChatLine_f( const idCmdArgs &args ) { - gameLocal.mpGame.AddChatLine( args.Argv( 1 ) ); -} - -/* -================== -Cmd_Kick_f -================== -*/ -static void Cmd_Kick_f( const idCmdArgs &args ) { - idPlayer *player; - - if ( !gameLocal.isMultiplayer ) { - gameLocal.Printf( "kick can only be used in a multiplayer game\n" ); - return; - } - - if ( gameLocal.isClient ) { - gameLocal.Printf( "You have no such power. This is a server command\n" ); - return; - } - - player = gameLocal.GetClientByCmdArgs( args ); - if ( !player ) { - gameLocal.Printf( "usage: kick or kick \n" ); - return; - } - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say kicking out client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %d\n", player->entityNumber ) ); -} - -/* -================== -Cmd_GetViewpos_f -================== -*/ -void Cmd_GetViewpos_f( const idCmdArgs &args ) { - idPlayer *player; - idVec3 origin; - idMat3 axis; - - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - - const renderView_t *view = player->GetRenderView(); - if ( view ) { - gameLocal.Printf( "(%s) %.1f\n", view->vieworg.ToString(), view->viewaxis[0].ToYaw() ); - } else { - player->GetViewPos( origin, axis ); - gameLocal.Printf( "(%s) %.1f\n", origin.ToString(), axis[0].ToYaw() ); - } -} - -/* -================= -Cmd_SetViewpos_f -================= -*/ -void Cmd_SetViewpos_f( const idCmdArgs &args ) { - idVec3 origin; - idAngles angles; - int i; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( ( args.Argc() != 4 ) && ( args.Argc() != 5 ) ) { - gameLocal.Printf( "usage: setviewpos \n" ); - return; - } - - angles.Zero(); - if ( args.Argc() == 5 ) { - angles.yaw = atof( args.Argv( 4 ) ); - } - - for ( i = 0 ; i < 3 ; i++ ) { - origin[i] = atof( args.Argv( i + 1 ) ); - } - origin.z -= pm_normalviewheight.GetFloat() - 0.25f; - - player->Teleport( origin, angles, NULL ); -} - -/* -================= -Cmd_Teleport_f -================= -*/ -void Cmd_Teleport_f( const idCmdArgs &args ) { - idVec3 origin; - idAngles angles; - idPlayer *player; - idEntity *ent; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() != 2 ) { - gameLocal.Printf( "usage: teleport \n" ); - return; - } - - ent = gameLocal.FindEntity( args.Argv( 1 ) ); - if ( !ent ) { - gameLocal.Printf( "entity not found\n" ); - return; - } - - angles.Zero(); - angles.yaw = ent->GetPhysics()->GetAxis()[ 0 ].ToYaw(); - origin = ent->GetPhysics()->GetOrigin(); - - player->Teleport( origin, angles, ent ); -} - -/* -================= -Cmd_Trigger_f -================= -*/ -void Cmd_Trigger_f( const idCmdArgs &args ) { - idVec3 origin; - idAngles angles; - idPlayer *player; - idEntity *ent; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() != 2 ) { - gameLocal.Printf( "usage: trigger \n" ); - return; - } - - ent = gameLocal.FindEntity( args.Argv( 1 ) ); - if ( !ent ) { - gameLocal.Printf( "entity not found\n" ); - return; - } - - ent->Signal( SIG_TRIGGER ); - ent->ProcessEvent( &EV_Activate, player ); - ent->TriggerGuis(); -} - -/* -=================== -Cmd_Spawn_f -=================== -*/ -void Cmd_Spawn_f( const idCmdArgs &args ) { - const char *key, *value; - int i; - float yaw; - idVec3 org; - idPlayer *player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk( false ) ) { - return; - } - - if ( args.Argc() & 1 ) { // must always have an even number of arguments - gameLocal.Printf( "usage: spawn classname [key/value pairs]\n" ); - return; - } - - yaw = player->viewAngles.yaw; - - value = args.Argv( 1 ); - dict.Set( "classname", value ); - dict.Set( "angle", va( "%f", yaw + 180 ) ); - - org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); - dict.Set( "origin", org.ToString() ); - - for( i = 2; i < args.Argc() - 1; i += 2 ) { - - key = args.Argv( i ); - value = args.Argv( i + 1 ); - - dict.Set( key, value ); - } - - gameLocal.SpawnEntityDef( dict ); -} - -/* -================== -Cmd_Damage_f - -Damages the specified entity -================== -*/ -void Cmd_Damage_f( const idCmdArgs &args ) { - if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { - return; - } - if ( args.Argc() != 3 ) { - gameLocal.Printf( "usage: damage \n" ); - return; - } - - idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) ); - if ( !ent ) { - gameLocal.Printf( "entity not found\n" ); - return; - } - - ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT ); -} - - -/* -================== -Cmd_Remove_f - -Removes the specified entity -================== -*/ -void Cmd_Remove_f( const idCmdArgs &args ) { - if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) { - return; - } - if ( args.Argc() != 2 ) { - gameLocal.Printf( "usage: remove \n" ); - return; - } - - idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) ); - if ( !ent ) { - gameLocal.Printf( "entity not found\n" ); - return; - } - - delete ent; -} - -/* -=================== -Cmd_TestLight_f -=================== -*/ -void Cmd_TestLight_f( const idCmdArgs &args ) { - int i; - idStr filename; - const char *key, *value, *name(NULL); - idPlayer * player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk( false ) ) { - return; - } - - renderView_t *rv = player->GetRenderView(); - - float fov = tan( idMath::M_DEG2RAD * rv->fov_x / 2 ); - - - dict.SetMatrix( "rotation", mat3_default ); - dict.SetVector( "origin", rv->vieworg ); - dict.SetVector( "light_target", rv->viewaxis[0] ); - dict.SetVector( "light_right", rv->viewaxis[1] * -fov ); - dict.SetVector( "light_up", rv->viewaxis[2] * fov ); - dict.SetVector( "light_start", rv->viewaxis[0] * 16 ); - dict.SetVector( "light_end", rv->viewaxis[0] * 1000 ); - - if ( args.Argc() >= 2 ) { - value = args.Argv( 1 ); - filename = args.Argv(1); - filename.DefaultFileExtension( ".tga" ); - dict.Set( "texture", filename ); - } - - dict.Set( "classname", "light" ); - for( i = 2; i < args.Argc() - 1; i += 2 ) { - - key = args.Argv( i ); - value = args.Argv( i + 1 ); - - dict.Set( key, value ); - } - - for ( i = 0; i < MAX_GENTITIES; i++ ) { - name = va( "spawned_light_%d", i ); // not just light_, or it might pick up a prelight shadow - if ( !gameLocal.FindEntity( name ) ) { - break; - } - } - dict.Set( "name", name ); - - gameLocal.SpawnEntityDef( dict ); - - gameLocal.Printf( "Created new light\n"); -} - -/* -=================== -Cmd_TestPointLight_f -=================== -*/ -void Cmd_TestPointLight_f( const idCmdArgs &args ) { - const char *key, *value, *name(NULL); - int i; - idPlayer *player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk( false ) ) { - return; - } - - dict.SetVector("origin", player->GetRenderView()->vieworg); - - if ( args.Argc() >= 2 ) { - value = args.Argv( 1 ); - dict.Set("light", value); - } else { - dict.Set("light", "300"); - } - - dict.Set( "classname", "light" ); - for( i = 2; i < args.Argc() - 1; i += 2 ) { - - key = args.Argv( i ); - value = args.Argv( i + 1 ); - - dict.Set( key, value ); - } - - for ( i = 0; i < MAX_GENTITIES; i++ ) { - name = va( "light_%d", i ); - if ( !gameLocal.FindEntity( name ) ) { - break; - } - } - dict.Set( "name", name ); - - gameLocal.SpawnEntityDef( dict ); - - gameLocal.Printf( "Created new point light\n"); -} - -/* -================== -Cmd_PopLight_f -================== -*/ -void Cmd_PopLight_f( const idCmdArgs &args ) { - idEntity *ent; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idLight *lastLight; - int last; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - bool removeFromMap = ( args.Argc() > 1 ); - - lastLight = NULL; - last = -1; - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( !ent->IsType( idLight::Type ) ) { - continue; - } - - if ( gameLocal.spawnIds[ ent->entityNumber ] > last ) { - last = gameLocal.spawnIds[ ent->entityNumber ]; - lastLight = static_cast( ent ); - } - } - - if ( lastLight ) { - // find map file entity - mapEnt = mapFile->FindEntity( lastLight->name ); - - if ( removeFromMap && mapEnt ) { - mapFile->RemoveEntity( mapEnt ); - } - gameLocal.Printf( "Removing light %i\n", lastLight->GetLightDefHandle() ); - delete lastLight; - } else { - gameLocal.Printf( "No lights to clear.\n" ); - } - -} - -/* -==================== -Cmd_ClearLights_f -==================== -*/ -void Cmd_ClearLights_f( const idCmdArgs &args ) { - idEntity *ent; - idEntity *next; - idLight *light; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - - bool removeFromMap = ( args.Argc() > 1 ); - - gameLocal.Printf( "Clearing all lights.\n" ); - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = next ) { - next = ent->spawnNode.Next(); - if ( !ent->IsType( idLight::Type ) ) { - continue; - } - - light = static_cast( ent ); - mapEnt = mapFile->FindEntity( light->name ); - - if ( removeFromMap && mapEnt ) { - mapFile->RemoveEntity( mapEnt ); - } - - delete light; - } -} - -/* -================== -Cmd_TestFx_f -================== -*/ -void Cmd_TestFx_f( const idCmdArgs &args ) { - idVec3 offset; - const char *name; - idPlayer * player; - idDict dict; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - // delete the testModel if active - if ( gameLocal.testFx ) { - delete gameLocal.testFx; - gameLocal.testFx = NULL; - } - - if ( args.Argc() < 2 ) { - return; - } - - name = args.Argv( 1 ); - - offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f; - - dict.Set( "origin", offset.ToString() ); - dict.Set( "test", "1"); - dict.Set( "fx", name ); - gameLocal.testFx = ( idEntityFx * )gameLocal.SpawnEntityType( idEntityFx::Type, &dict ); -} - -#define MAX_DEBUGLINES 128 - -typedef struct { - bool used; - idVec3 start, end; - int color; - bool blink; - bool arrow; -} gameDebugLine_t; - -gameDebugLine_t debugLines[MAX_DEBUGLINES]; - -/* -================== -Cmd_AddDebugLine_f -================== -*/ -static void Cmd_AddDebugLine_f( const idCmdArgs &args ) { - int i, argNum; - const char *value; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc () < 7 ) { - gameLocal.Printf( "usage: addline \n" ); - return; - } - for ( i = 0; i < MAX_DEBUGLINES; i++ ) { - if ( !debugLines[i].used ) { - break; - } - } - if ( i >= MAX_DEBUGLINES ) { - gameLocal.Printf( "no free debug lines\n" ); - return; - } - value = args.Argv( 0 ); - if ( !idStr::Icmp( value, "addarrow" ) ) { - debugLines[i].arrow = true; - } else { - debugLines[i].arrow = false; - } - debugLines[i].used = true; - debugLines[i].blink = false; - argNum = 1; - debugLines[i].start.x = Cmd_GetFloatArg( args, argNum ); - debugLines[i].start.y = Cmd_GetFloatArg( args, argNum ); - debugLines[i].start.z = Cmd_GetFloatArg( args, argNum ); - debugLines[i].end.x = Cmd_GetFloatArg( args, argNum ); - debugLines[i].end.y = Cmd_GetFloatArg( args, argNum ); - debugLines[i].end.z = Cmd_GetFloatArg( args, argNum ); - debugLines[i].color = static_cast(Cmd_GetFloatArg( args, argNum )); -} - -/* -================== -Cmd_RemoveDebugLine_f -================== -*/ -static void Cmd_RemoveDebugLine_f( const idCmdArgs &args ) { - int i, num; - const char *value; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc () < 2 ) { - gameLocal.Printf( "usage: removeline \n" ); - return; - } - value = args.Argv( 1 ); - num = atoi(value); - for ( i = 0; i < MAX_DEBUGLINES; i++ ) { - if ( debugLines[i].used ) { - if ( --num < 0 ) { - break; - } - } - } - if ( i >= MAX_DEBUGLINES ) { - gameLocal.Printf( "line not found\n" ); - return; - } - debugLines[i].used = false; -} - -/* -================== -Cmd_BlinkDebugLine_f -================== -*/ -static void Cmd_BlinkDebugLine_f( const idCmdArgs &args ) { - int i, num; - const char *value; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc () < 2 ) { - gameLocal.Printf( "usage: blinkline \n" ); - return; - } - value = args.Argv( 1 ); - num = atoi( value ); - for ( i = 0; i < MAX_DEBUGLINES; i++ ) { - if ( debugLines[i].used ) { - if ( --num < 0 ) { - break; - } - } - } - if ( i >= MAX_DEBUGLINES ) { - gameLocal.Printf( "line not found\n" ); - return; - } - debugLines[i].blink = !debugLines[i].blink; -} - -/* -================== -PrintFloat -================== -*/ -static void PrintFloat( float f ) { - char buf[128]; - int i; - - for (i = sprintf( buf, "%3.2f", f ); i < 7; i++) { - buf[i] = ' '; - } - buf[i] = '\0'; - gameLocal.Printf( buf ); -} - -/* -================== -Cmd_ListDebugLines_f -================== -*/ -static void Cmd_ListDebugLines_f( const idCmdArgs &args ) { - int i, num; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - num = 0; - gameLocal.Printf( "line num: x1 y1 z1 x2 y2 z2 c b a\n" ); - for ( i = 0; i < MAX_DEBUGLINES; i++ ) { - if ( debugLines[i].used ) { - gameLocal.Printf( "line %3d: ", num ); - PrintFloat( debugLines[i].start.x ); - PrintFloat( debugLines[i].start.y ); - PrintFloat( debugLines[i].start.z ); - PrintFloat( debugLines[i].end.x ); - PrintFloat( debugLines[i].end.y ); - PrintFloat( debugLines[i].end.z ); - gameLocal.Printf( "%d %d %d\n", debugLines[i].color, debugLines[i].blink, debugLines[i].arrow ); - num++; - } - } - if ( !num ) { - gameLocal.Printf( "no debug lines\n" ); - } -} - -/* -================== -D_DrawDebugLines -================== -*/ -void D_DrawDebugLines( void ) { - int i; - idVec3 forward, right, up, p1, p2; - idVec4 color; - float l; - - for ( i = 0; i < MAX_DEBUGLINES; i++ ) { - if ( debugLines[i].used ) { - if ( !debugLines[i].blink || (gameLocal.time & (1<<9)) ) { - color = idVec4( debugLines[i].color&1, (debugLines[i].color>>1)&1, (debugLines[i].color>>2)&1, 1 ); - gameRenderWorld->DebugLine( color, debugLines[i].start, debugLines[i].end ); - // - if ( debugLines[i].arrow ) { - // draw a nice arrow - forward = debugLines[i].end - debugLines[i].start; - l = forward.Normalize() * 0.2f; - forward.NormalVectors( right, up); - - if ( l > 3.0f ) { - l = 3.0f; - } - p1 = debugLines[i].end - l * forward + (l * 0.4f) * right; - p2 = debugLines[i].end - l * forward - (l * 0.4f) * right; - gameRenderWorld->DebugLine( color, debugLines[i].end, p1 ); - gameRenderWorld->DebugLine( color, debugLines[i].end, p2 ); - gameRenderWorld->DebugLine( color, p1, p2 ); - } - } - } - } -} - -/* -================== -Cmd_ListCollisionModels_f -================== -*/ -static void Cmd_ListCollisionModels_f( const idCmdArgs &args ) { - if ( !gameLocal.CheatsOk() ) { - return; - } - - collisionModelManager->ListModels(); -} - -/* -================== -Cmd_CollisionModelInfo_f -================== -*/ -static void Cmd_CollisionModelInfo_f( const idCmdArgs &args ) { - const char *value; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc () < 2 ) { - gameLocal.Printf( "usage: collisionModelInfo \n" - "use 'all' instead of the model number for accumulated info\n" ); - return; - } - - value = args.Argv( 1 ); - if ( !idStr::Icmp( value, "all" ) ) { - collisionModelManager->ModelInfo( -1 ); - } else { - collisionModelManager->ModelInfo( atoi(value) ); - } -} - -/* -================== -Cmd_ExportModels_f -================== -*/ -static void Cmd_ExportModels_f( const idCmdArgs &args ) { - idModelExport exporter; - idStr name; - - // don't allow exporting models when cheats are disabled, - // but if we're not in the game, it's ok - if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { - return; - } - - if ( args.Argc() < 2 ) { - exporter.ExportModels( "def", ".def" ); - } else { - name = args.Argv( 1 ); - name = "def/" + name; - name.DefaultFileExtension( ".def" ); - exporter.ExportDefFile( name ); - } -} - -/* -================== -Cmd_ReexportModels_f -================== -*/ -static void Cmd_ReexportModels_f( const idCmdArgs &args ) { - idModelExport exporter; - idStr name; - - // don't allow exporting models when cheats are disabled, - // but if we're not in the game, it's ok - if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { - return; - } - - idAnimManager::forceExport = true; - if ( args.Argc() < 2 ) { - exporter.ExportModels( "def", ".def" ); - } else { - name = args.Argv( 1 ); - name = "def/" + name; - name.DefaultFileExtension( ".def" ); - exporter.ExportDefFile( name ); - } - idAnimManager::forceExport = false; -} - -/* -================== -Cmd_ReloadAnims_f -================== -*/ -static void Cmd_ReloadAnims_f( const idCmdArgs &args ) { - // don't allow reloading anims when cheats are disabled, - // but if we're not in the game, it's ok - if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) { - return; - } - - animationLib.ReloadAnims(); -} - -/* -================== -Cmd_ListAnims_f -================== -*/ -static void Cmd_ListAnims_f( const idCmdArgs &args ) { - idEntity * ent; - int num; - size_t size; - size_t alloced; - idAnimator * animator; - const char * classname; - const idDict * dict; - int i; - - if ( args.Argc() > 1 ) { - idAnimator animator; - - classname = args.Argv( 1 ); - - dict = gameLocal.FindEntityDefDict( classname, false ); - if ( !dict ) { - gameLocal.Printf( "Entitydef '%s' not found\n", classname ); - return; - } - animator.SetModel( dict->GetString( "model" ) ); - - gameLocal.Printf( "----------------\n" ); - num = animator.NumAnims(); - for( i = 0; i < num; i++ ) { - gameLocal.Printf( "%s\n", animator.AnimFullName( i ) ); - } - gameLocal.Printf( "%d anims\n", num ); - } else { - animationLib.ListAnims(); - - size = 0; - num = 0; - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - animator = ent->GetAnimator(); - if ( animator ) { - alloced = animator->Allocated(); - size += alloced; - num++; - } - } - - gameLocal.Printf( "%d memory used in %d entity animators\n", size, num ); - } -} - -// greebo: Reload the xdata declarations by forcing the declaration manager to perform a reload -static void Cmd_ReloadXData_f( const idCmdArgs &args ) -{ - // Reload the declarations, this triggers a re-parse of all xdata files (and all other files on that matter) - declManager->Reload(true); - // greebo: This is called twice on purpose. For some reason, the first reload doesn't reload the xdata files. - declManager->Reload(true); - - // Now cycle through all active entities and call "refreshReadables" on them - for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - idThread* thread = ent->CallScriptFunctionArgs("reloadXData", true, 0, "e", ent); - - if (thread != NULL) - { - thread->Execute(); - } - } -} - -/* -================== -Cmd_AASStats_f -================== -*/ -static void Cmd_AASStats_f( const idCmdArgs &args ) { - int aasNum; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - aasNum = aas_test.GetInteger(); - idAAS *aas = gameLocal.GetAAS( aasNum ); - if ( !aas ) { - gameLocal.Printf( "No aas #%d loaded\n", aasNum ); - } else { - aas->Stats(); - } -} - -/* -================== -Cmd_TestDamage_f -================== -*/ -static void Cmd_TestDamage_f( const idCmdArgs &args ) { - idPlayer *player; - const char *damageDefName; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() < 2 || args.Argc() > 3 ) { - gameLocal.Printf( "usage: testDamage [angle]\n" ); - return; - } - - damageDefName = args.Argv( 1 ); - - idVec3 dir; - if ( args.Argc() == 3 ) { - float angle = atof( args.Argv( 2 ) ); - - idMath::SinCos( DEG2RAD( angle ), dir[1], dir[0] ); - dir[2] = 0; - } else { - dir.Zero(); - } - - // give the player full health before and after - // running the damage - player->health = player->maxHealth; - player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT ); - player->health = player->maxHealth; -} - -/* -================== -Cmd_TestBoneFx_f -================== -*/ -static void Cmd_TestBoneFx_f( const idCmdArgs &args ) { - idPlayer *player; - const char *bone, *fx; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() < 3 || args.Argc() > 4 ) { - gameLocal.Printf( "usage: testBoneFx \n" ); - return; - } - - fx = args.Argv( 1 ); - bone = args.Argv( 2 ); - - player->StartFxOnBone( fx, bone ); -} - -/* -================== -Cmd_TestDamage_f -================== -*/ -static void Cmd_TestDeath_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - idVec3 dir; - idMath::SinCos( DEG2RAD( 45.0f ), dir[1], dir[0] ); - dir[2] = 0; - - g_testDeath.SetBool( 1 ); - player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT ); - if ( args.Argc() >= 2) { - player->SpawnGibs( dir, "damage_triggerhurt_1000" ); - } - -} - -/* -================== -Cmd_WeaponSplat_f -================== -*/ -static void Cmd_WeaponSplat_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - player->weapon.GetEntity()->BloodSplat( 2.0f ); -} - -/* -================== -Cmd_SaveSelected_f -================== -*/ -static void Cmd_SaveSelected_f( const idCmdArgs &args ) { - int i; - idPlayer *player; - idEntity *s; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idDict dict; - idStr mapName; - const char *name(NULL); - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - s = player->dragEntity.GetSelected(); - if ( !s ) { - gameLocal.Printf( "no entity selected, set g_dragShowSelection 1 to show the current selection\n" ); - return; - } - - if ( args.Argc() > 1 ) { - mapName = args.Argv( 1 ); - mapName = "maps/" + mapName; - } - else { - mapName = mapFile->GetName(); - } - - // find map file entity - mapEnt = mapFile->FindEntity( s->name ); - // create new map file entity if there isn't one for this articulated figure - if ( !mapEnt ) { - mapEnt = new idMapEntity(); - mapFile->AddEntity( mapEnt ); - for ( i = 0; i < 9999; i++ ) { - name = va( "%s_%d", s->GetEntityDefName(), i ); - if ( !mapFile->FindEntity( name ) ) - break; - } - s->name = name; - mapEnt->epairs.Set( "classname", s->GetEntityDefName() ); - mapEnt->epairs.Set( "name", s->name ); - } - - if ( s->IsType( idMoveable::Type ) ) { - // save the moveable state - mapEnt->epairs.Set( "origin", s->GetPhysics()->GetOrigin().ToString( 8 ) ); - mapEnt->epairs.Set( "rotation", s->GetPhysics()->GetAxis().ToString( 8 ) ); - } - else if ( s->IsType( idAFEntity_Generic::Type ) || s->IsType( idAFEntity_WithAttachedHead::Type ) ) { - // save the articulated figure state - dict.Clear(); - static_cast(s)->SaveState( dict ); - mapEnt->epairs.Copy( dict ); - } - - // write out the map file - mapFile->Write( mapName, ".map" ); -} - -/* -================== -Cmd_DeleteSelected_f -================== -*/ -static void Cmd_DeleteSelected_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player ) { - player->dragEntity.DeleteSelected(); - } -} - -/* -================== -Cmd_SaveMoveables_f -================== -*/ -static void Cmd_SaveMoveables_f( const idCmdArgs &args ) { - int e, i; - idMoveable *m; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idStr mapName; - const char *name(NULL); - - if ( !gameLocal.CheatsOk() ) { - return; - } - - for( e = 0; e < MAX_GENTITIES; e++ ) { - m = static_cast(gameLocal.entities[ e ]); - - if ( !m || !m->IsType( idMoveable::Type ) ) { - continue; - } - - if ( m->IsBound() ) { - continue; - } - - if ( !m->IsAtRest() ) { - break; - } - } - - if ( e < MAX_GENTITIES ) { - gameLocal.Warning( "map not saved because the moveable entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() ); - return; - } - - if ( args.Argc() > 1 ) { - mapName = args.Argv( 1 ); - mapName = "maps/" + mapName; - } - else { - mapName = mapFile->GetName(); - } - - for( e = 0; e < MAX_GENTITIES; e++ ) { - m = static_cast(gameLocal.entities[ e ]); - - if ( !m || !m->IsType( idMoveable::Type ) ) { - continue; - } - - if ( m->IsBound() ) { - continue; - } - - // find map file entity - mapEnt = mapFile->FindEntity( m->name ); - // create new map file entity if there isn't one for this articulated figure - if ( !mapEnt ) { - mapEnt = new idMapEntity(); - mapFile->AddEntity( mapEnt ); - for ( i = 0; i < 9999; i++ ) { - name = va( "%s_%d", m->GetEntityDefName(), i ); - if ( !mapFile->FindEntity( name ) ) - break; - } - m->name = name; - mapEnt->epairs.Set( "classname", m->GetEntityDefName() ); - mapEnt->epairs.Set( "name", m->name ); - } - // save the moveable state - mapEnt->epairs.Set( "origin", m->GetPhysics()->GetOrigin().ToString( 8 ) ); - mapEnt->epairs.Set( "rotation", m->GetPhysics()->GetAxis().ToString( 8 ) ); - } - - // write out the map file - mapFile->Write( mapName, ".map" ); -} - -/* -================== -Cmd_SaveRagdolls_f -================== -*/ -static void Cmd_SaveRagdolls_f( const idCmdArgs &args ) { - int e, i; - idAFEntity_Base *af; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idDict dict; - idStr mapName; - const char *name(NULL); - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() > 1 ) { - mapName = args.Argv( 1 ); - mapName = "maps/" + mapName; - } - else { - mapName = mapFile->GetName(); - } - - for( e = 0; e < MAX_GENTITIES; e++ ) { - af = static_cast(gameLocal.entities[ e ]); - - if ( !af ) { - continue; - } - - if ( !af->IsType( idAFEntity_WithAttachedHead::Type ) && !af->IsType( idAFEntity_Generic::Type ) ) { - continue; - } - - // Ish: Not sure why they did this - /* - if ( af->IsBound() ) { - continue; - } - */ - - if ( !af->IsAtRest() ) { - gameLocal.Warning( "the articulated figure for entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() ); - } - - dict.Clear(); - af->SaveState( dict ); - - // find map file entity - mapEnt = mapFile->FindEntity( af->name ); - // create new map file entity if there isn't one for this articulated figure - if ( !mapEnt ) { - mapEnt = new idMapEntity(); - mapFile->AddEntity( mapEnt ); - for ( i = 0; i < 9999; i++ ) { - name = va( "%s_%d", af->GetEntityDefName(), i ); - if ( !mapFile->FindEntity( name ) ) - break; - } - af->name = name; - mapEnt->epairs.Set( "classname", af->GetEntityDefName() ); - mapEnt->epairs.Set( "name", af->name ); - } - // save the articulated figure state - mapEnt->epairs.Copy( dict ); - } - - // write out the map file - mapFile->Write( mapName, ".map" ); -} - -/* -================== -Cmd_BindRagdoll_f -================== -*/ -static void Cmd_BindRagdoll_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player ) { - player->dragEntity.BindSelected(); - } -} - -/* -================== -Cmd_UnbindRagdoll_f -================== -*/ -static void Cmd_UnbindRagdoll_f( const idCmdArgs &args ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( player ) { - player->dragEntity.UnbindSelected(); - } -} - -/* -================== -Cmd_GameError_f -================== -*/ -static void Cmd_GameError_f( const idCmdArgs &args ) { - gameLocal.Error( "game error" ); -} - -/* -================== -Cmd_SaveLights_f -================== -*/ -static void Cmd_SaveLights_f( const idCmdArgs &args ) { - int e, i; - idLight *light; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idDict dict; - idStr mapName; - const char *name(NULL); - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() > 1 ) { - mapName = args.Argv( 1 ); - mapName = "maps/" + mapName; - } - else { - mapName = mapFile->GetName(); - } - - for( e = 0; e < MAX_GENTITIES; e++ ) { - light = static_cast(gameLocal.entities[ e ]); - - if ( !light || !light->IsType( idLight::Type ) ) { - continue; - } - - dict.Clear(); - light->SaveState( &dict ); - - // find map file entity - mapEnt = mapFile->FindEntity( light->name ); - // create new map file entity if there isn't one for this light - if ( !mapEnt ) { - mapEnt = new idMapEntity(); - mapFile->AddEntity( mapEnt ); - for ( i = 0; i < 9999; i++ ) { - name = va( "%s_%d", light->GetEntityDefName(), i ); - if ( !mapFile->FindEntity( name ) ) - break; - } - light->name = name; - mapEnt->epairs.Set( "classname", light->GetEntityDefName() ); - mapEnt->epairs.Set( "name", light->name ); - } - // save the light state - mapEnt->epairs.Copy( dict ); - } - - // write out the map file - mapFile->Write( mapName, ".map" ); -} - - -/* -================== -Cmd_SaveParticles_f -================== -*/ -static void Cmd_SaveParticles_f( const idCmdArgs &args ) { - int e; - idEntity *ent; - idMapEntity *mapEnt; - idMapFile *mapFile = gameLocal.GetLevelMap(); - idDict dict; - idStr mapName, strModel; - - if ( !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() > 1 ) { - mapName = args.Argv( 1 ); - mapName = "maps/" + mapName; - } - else { - mapName = mapFile->GetName(); - } - - for( e = 0; e < MAX_GENTITIES; e++ ) { - - ent = static_cast ( gameLocal.entities[ e ] ); - - if ( !ent ) { - continue; - } - - strModel = ent->spawnArgs.GetString( "model" ); - if ( strModel.Length() && strModel.Find( ".prt") > 0 ) { - dict.Clear(); - dict.Set( "model", ent->spawnArgs.GetString( "model" ) ); - dict.SetVector( "origin", ent->GetPhysics()->GetOrigin() ); - - // find map file entity - mapEnt = mapFile->FindEntity( ent->name ); - // create new map file entity if there isn't one for this entity - if ( !mapEnt ) { - continue; - } - // save the particle state - mapEnt->epairs.Copy( dict ); - } - } - - // write out the map file - mapFile->Write( mapName, ".map" ); -} - - -/* -================== -Cmd_DisasmScript_f -================== -*/ -static void Cmd_DisasmScript_f( const idCmdArgs &args ) { - gameLocal.program.Disassemble(); -} - -/* -================== -Cmd_TestSave_f -================== -*/ -static void Cmd_TestSave_f( const idCmdArgs &args ) { - idFile *f; - - f = fileSystem->OpenFileWrite( "test.sav" ); - gameLocal.SaveGame( f ); - fileSystem->CloseFile( f ); -} - -/* -================== -Cmd_RecordViewNotes_f -================== -*/ -static void Cmd_RecordViewNotes_f( const idCmdArgs &args ) { - idPlayer *player; - idVec3 origin; - idMat3 axis; - - if ( args.Argc() <= 3 ) { - return; - } - - player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - - player->GetViewPos( origin, axis ); - - // Argv(1) = filename for map (viewnotes/mapname/person) - // Argv(2) = note number (person0001) - // Argv(3) = comments - - idStr str = args.Argv(1); - str.SetFileExtension( ".txt" ); - idFile *file = fileSystem->OpenFileAppend( str ); - if ( file ) { - file->WriteFloatString( "\"view\"\t( %s )\t( %s )\r\n", origin.ToString(), axis.ToString() ); - file->WriteFloatString( "\"comments\"\t\"%s: %s\"\r\n\r\n", args.Argv(2), args.Argv(3) ); - fileSystem->CloseFile( file ); - } - - idStr viewComments = args.Argv(1); - viewComments.StripLeading("viewnotes/"); - viewComments += " -- Loc: "; - viewComments += origin.ToString(); - viewComments += "\n"; - viewComments += args.Argv(3); - player->hud->SetStateString( "viewcomments", viewComments ); - player->hud->HandleNamedEvent( "showViewComments" ); -} - -/* -================== -Cmd_CloseViewNotes_f -================== -*/ -static void Cmd_CloseViewNotes_f( const idCmdArgs &args ) { - idPlayer *player = gameLocal.GetLocalPlayer(); - - if ( !player ) { - return; - } - - player->hud->SetStateString( "viewcomments", "" ); - player->hud->HandleNamedEvent( "hideViewComments" ); -} - -/* -================== -Cmd_ShowViewNotes_f -================== -*/ -static void Cmd_ShowViewNotes_f( const idCmdArgs &args ) { - static idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS ); - idToken token; - idPlayer *player; - idVec3 origin; - idMat3 axis; - - player = gameLocal.GetLocalPlayer(); - - if ( !player ) { - return; - } - - if ( !parser.IsLoaded() ) { - idStr str = "viewnotes/"; - str += gameLocal.GetMapName(); - str.StripFileExtension(); - str += "/"; - if ( args.Argc() > 1 ) { - str += args.Argv( 1 ); - } else { - str += "comments"; - } - str.SetFileExtension( ".txt" ); - if ( !parser.LoadFile( str ) ) { - gameLocal.Printf( "No view notes for %s\n", gameLocal.GetMapName() ); - return; - } - } - - if ( parser.ExpectTokenString( "view" ) && parser.Parse1DMatrix( 3, origin.ToFloatPtr() ) && - parser.Parse1DMatrix( 9, axis.ToFloatPtr() ) && parser.ExpectTokenString( "comments" ) && parser.ReadToken( &token ) ) { - player->hud->SetStateString( "viewcomments", token ); - player->hud->HandleNamedEvent( "showViewComments" ); - player->Teleport( origin, axis.ToAngles(), NULL ); - } else { - parser.FreeSource(); - player->hud->HandleNamedEvent( "hideViewComments" ); - return; - } -} - -/* -================= -FindEntityGUIs - -helper function for Cmd_NextGUI_f. Checks the passed entity to determine if it -has any valid gui surfaces. -================= -*/ -bool FindEntityGUIs( idEntity *ent, const modelSurface_t ** surfaces, int maxSurfs, int &guiSurfaces ) { - renderEntity_t *renderEnt; - idRenderModel *renderModel; - const modelSurface_t *surf; - const idMaterial *shader; - int i; - - assert( surfaces != NULL ); - assert( ent != NULL ); - - memset( surfaces, 0x00, sizeof( modelSurface_t *) * maxSurfs ); - guiSurfaces = 0; - - renderEnt = ent->GetRenderEntity(); - renderModel = renderEnt->hModel; - if ( renderModel == NULL ) { - return false; - } - - for( i = 0; i < renderModel->NumSurfaces(); i++ ) { - surf = renderModel->Surface( i ); - if ( surf == NULL ) { - continue; - } - shader = surf->shader; - if ( shader == NULL ) { - continue; - } - if ( shader->GetEntityGui() > 0 ) { - surfaces[ guiSurfaces++ ] = surf; - } - } - - return ( guiSurfaces != 0 ); -} - -/* -================= -Cmd_NextGUI_f -================= -*/ -void Cmd_NextGUI_f( const idCmdArgs &args ) { - idVec3 origin; - idAngles angles; - idPlayer *player; - idEntity *ent; - int guiSurfaces; - bool newEnt; - renderEntity_t *renderEnt; - int surfIndex; - srfTriangles_t *geom; - idMat4 modelMatrix; - idVec3 normal; - idVec3 center; - const modelSurface_t *surfaces[ MAX_RENDERENTITY_GUI ]; - - player = gameLocal.GetLocalPlayer(); - if ( !player || !gameLocal.CheatsOk() ) { - return; - } - - if ( args.Argc() != 1 ) { - gameLocal.Printf( "usage: nextgui\n" ); - return; - } - - // start at the last entity - ent = gameLocal.lastGUIEnt.GetEntity(); - - // see if we have any gui surfaces left to go to on the current entity. - guiSurfaces = 0; - newEnt = false; - if ( ent == NULL ) { - newEnt = true; - } else if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == true ) { - if ( gameLocal.lastGUI >= guiSurfaces ) { - newEnt = true; - } - } else { - // no actual gui surfaces on this ent, so skip it - newEnt = true; - } - - if ( newEnt == true ) { - // go ahead and skip to the next entity with a gui... - if ( ent == NULL ) { - ent = gameLocal.spawnedEntities.Next(); - } else { - ent = ent->spawnNode.Next(); - } - - for ( ; ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->spawnArgs.GetString( "gui", NULL ) != NULL ) { - break; - } - - if ( ent->spawnArgs.GetString( "gui2", NULL ) != NULL ) { - break; - } - - if ( ent->spawnArgs.GetString( "gui3", NULL ) != NULL ) { - break; - } - - // try the next entity - gameLocal.lastGUIEnt = ent; - } - - gameLocal.lastGUIEnt = ent; - gameLocal.lastGUI = 0; - - if ( !ent ) { - gameLocal.Printf( "No more gui entities. Starting over...\n" ); - return; - } - } - - if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == false ) { - gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces.\n", ent->name.c_str() ); - } - - if ( guiSurfaces == 0 ) { - gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces!\n", ent->name.c_str() ); - return; - } - - gameLocal.Printf( "Teleporting to gui entity \"%s\", gui #%d.\n" , ent->name.c_str (), gameLocal.lastGUI ); - - renderEnt = ent->GetRenderEntity(); - surfIndex = gameLocal.lastGUI++; - geom = surfaces[ surfIndex ]->geometry; - if ( geom == NULL ) { - gameLocal.Printf( "Entity \"%s\" has gui surface %d without geometry!\n", ent->name.c_str(), surfIndex ); - return; - } - - assert( geom->facePlanes != NULL ); - - modelMatrix = idMat4( renderEnt->axis, renderEnt->origin ); - normal = geom->facePlanes[ 0 ].Normal() * renderEnt->axis; - center = geom->bounds.GetCenter() * modelMatrix; - - origin = center + (normal * 32.0f); - origin.z -= player->EyeHeight(); - normal *= -1.0f; - angles = normal.ToAngles (); - - // make sure the player is in noclip - player->noclip = true; - player->Teleport( origin, angles, NULL ); -} - -static void ArgCompletion_DefFile( const idCmdArgs &args, void(*callback)( const char *s ) ) { - cmdSystem->ArgCompletion_FolderExtension( args, callback, "def/", true, ".def", NULL ); -} - -/* -=============== -Cmd_TestId_f -outputs a string from the string table for the specified id -=============== -*/ -void Cmd_TestId_f( const idCmdArgs &args ) { - idStr id; - int i; - if ( args.Argc() == 1 ) { - common->Printf( "usage: testid \n" ); - return; - } - - for ( i = 1; i < args.Argc(); i++ ) { - id += args.Argv( i ); - } - if ( idStr::Cmpn( id, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) { - id = STRTABLE_ID + id; - } - gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( id ), "", "", "" ); -} - -void Cmd_SetClipMask(const idCmdArgs& args) -{ - if (args.Argc() != 3) - { - common->Printf( "usage: setClipMask \n" ); - return; - } - - idStr targetEntity = args.Argv(1); - int clipMask = atoi(args.Argv(2)); - - idEntity* ent = gameLocal.FindEntity(targetEntity.c_str()); - - if (ent != NULL && ent->GetPhysics() != NULL) - { - ent->GetPhysics()->SetClipMask(clipMask); - common->Printf("Clipmask of entity %s set to %d\n", ent->name.c_str(), clipMask); - } -} - -void Cmd_SetClipContents(const idCmdArgs& args) -{ - if (args.Argc() != 3) - { - common->Printf( "usage: setClipContents \n" ); - return; - } - - idStr targetEntity = args.Argv(1); - int contents = atoi(args.Argv(2)); - - idEntity* ent = gameLocal.FindEntity(targetEntity.c_str()); - - if (ent != NULL && ent->GetPhysics() != NULL) - { - ent->GetPhysics()->SetContents(contents); - common->Printf("Contents of entity %s set to %d\n", ent->name.c_str(), contents); - } -} - -void Cmd_ShowWalkPath_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - common->Printf( "usage: aas_showWalkPath \n" ); - return; - } - - idPlayer* player = gameLocal.GetLocalPlayer(); - if ( !player ) { - return; - } - - idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); - if (aas != NULL) - { - aas->ShowWalkPath(player->GetPhysics()->GetOrigin(), atoi(args.Argv(1)), aas->AreaCenter(atoi(args.Argv(1)))); - } -} - -void Cmd_ShowReachabilities_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - common->Printf( "usage: aas_showReachabilities \n" ); - return; - } - - idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); - if (aas != NULL) - { - idReachability* reach = aas->GetAreaFirstReachability(atoi(args.Argv(1))); - - while (reach != NULL) - { - aas->DrawReachability(reach); - reach = reach->next; - } - } -} - -void Cmd_ShowAASStats_f(const idCmdArgs& args) -{ - for (int i = 0; i < gameLocal.NumAAS(); i++) - { - idAAS* aas = dynamic_cast(gameLocal.GetAAS(i)); - if (aas != NULL) - { - aas->Stats(); - } - } -} - -void Cmd_ShowEASRoute_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - common->Printf( "usage: eas_showRoute \n" ); - return; - } - - idPlayer* player = gameLocal.GetLocalPlayer(); - if (player == NULL) - { - common->Printf( "no player found\n" ); - return; - } - - idAASLocal* aas = dynamic_cast(gameLocal.GetAAS("aas32")); - if (aas != NULL) - { - int areaNum = atoi(args.Argv(1)); - - aas->DrawEASRoute(player->GetPhysics()->GetOrigin(), areaNum); - } -} - -void Cmd_StartConversation_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - gameLocal.Printf("Usage: tdm_start_conversation . Use tdm_list_conversations to get a list of names.\n" ); - return; - } - - if (gameLocal.GameState() != GAMESTATE_ACTIVE) - { - gameLocal.Printf("No map running\n"); - return; - } - - int idx = gameLocal.m_ConversationSystem->GetConversationIndex(args.Argv(1)); - if (idx != -1) - { - gameLocal.m_ConversationSystem->StartConversation(idx); - } - else - { - gameLocal.Printf("No conversation with name: %s\n", args.Argv(1)); - } -} - -void Cmd_ListConversations_f(const idCmdArgs& args) -{ - if (gameLocal.GameState() != GAMESTATE_ACTIVE) - { - gameLocal.Printf("No map running\n"); - return; - } - - for (int i = 0; i < gameLocal.m_ConversationSystem->GetNumConversations(); i++) - { - ai::ConversationPtr conversation = gameLocal.m_ConversationSystem->GetConversation(i); - - if (conversation == NULL) continue; - - gameLocal.Printf("%d: %s (%d commands)\n", i, conversation->GetName().c_str(), conversation->GetNumCommands()); - } -} - -void Cmd_ShowLoot_f(const idCmdArgs& args) -{ - if (gameLocal.GameState() != GAMESTATE_ACTIVE) - { - gameLocal.Printf("No map running\n"); - return; - } - - int items = 0; - int gold = 0; - int jewels = 0; - int goods = 0; - - for (idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) - { - if (ent == NULL) continue; - - int value = ent->spawnArgs.GetInt("inv_loot_value", "-1"); - - if (value <= 0) continue; // no loot item - - items++; - - LootType lootType = CInventoryItem::GetLootTypeFromSpawnargs(ent->spawnArgs); - - idVec4 colour(colorWhite); - - switch(lootType) - { - case LOOT_GOLD: - gold += value; - colour = idVec4(0.97f, 0.93f, 0.58f, 1); - break; - - case LOOT_GOODS: - goods += value; - colour = idVec4(0.3f, 0.91f, 0.3f, 1); - break; - - case LOOT_JEWELS: - jewels += value; - colour = idVec4(0.96f, 0.2f, 0.2f, 1); - break; - - default: break; - } - - gameRenderWorld->DebugBox(colour, idBox(ent->GetPhysics()->GetAbsBounds()), 5000); - } - - gameLocal.Printf("Highlighing loot items for 5 seconds...\n"); - gameLocal.Printf("Loot items remaining: %d\n", items); - gameLocal.Printf("Gold: %d, Jewels: %d, Goods: %d\n", gold, jewels, goods); -} - -void Cmd_ActivateLog_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - gameLocal.Printf("Usage: tdm_activatelogclass . Use the TAB to get auto-complete logclasses.\n" ); - return; - } - - LC_LogClass logclassIndex = CGlobal::GetLogClassForString(args.Argv(1)); - - if (logclassIndex != LC_COUNT) - { - // Log class found - g_Global.m_ClassArray[logclassIndex] = true; - - // activate all types too - g_Global.m_LogArray[LT_WARNING] = true; - g_Global.m_LogArray[LT_ERROR] = true; - g_Global.m_LogArray[LT_INFO] = true; - g_Global.m_LogArray[LT_DEBUG] = true; - - gameLocal.Printf("Logclass %d activated.", static_cast(logclassIndex)); - } -} - -void Cmd_DeactivateLog_f(const idCmdArgs& args) -{ - if (args.Argc() != 2) - { - gameLocal.Printf("Usage: tdm_deactivatelogclass . Use the TAB to get auto-complete logclasses.\n" ); - return; - } - - LC_LogClass logclassIndex = CGlobal::GetLogClassForString(args.Argv(1)); - - if (logclassIndex != LC_COUNT) - { - // Log class found - g_Global.m_ClassArray[logclassIndex] = false; - - // activate all types too - g_Global.m_LogArray[LT_WARNING] = true; - g_Global.m_LogArray[LT_ERROR] = true; - g_Global.m_LogArray[LT_INFO] = true; - g_Global.m_LogArray[LT_DEBUG] = true; - - gameLocal.Printf("Logclass %d deactivated.", static_cast(logclassIndex)); - } -} - -//------------------------------------------------------------- -// Do not account for centerScale or Scroll for now. -typedef struct _ImageInfo{ - idStr m_strImageName; - idStr m_strUVScale; - - _ImageInfo() : - m_strImageName(), - m_strUVScale("1, 1") - { - } -}ImageInfo_s; - -enum eVertexBlendType { - eVertexBlendType_None, - eVertexBlendType_VertexColored, - eVertexBlendType_InvVertexColored -}; -//------------------------------------------------------------------ -typedef std::multimap< eVertexBlendType, ImageInfo_s > ImageInfoMap; -//------------------------------------------------------------------ - -//------------------------------------------------------------- -// GetValidStageTextureName -// -// Description: Obtains a valid texture name with trailing white spaces and curly brackets (if found any) removed. -// A check for valid number of opening and closing brackets performed. -//------------------------------------------------------------- -bool GetValidStageExpression( idLexer &a_lexSource, idStr & a_strStageTextureName ) -{ - int iOffset, nBrackets; - a_strStageTextureName.Empty(); - - std::vector< idStr > arrStrInvalidTokens; - - arrStrInvalidTokens.push_back( "bumpmap" ); - arrStrInvalidTokens.push_back( "diffusemap" ); - arrStrInvalidTokens.push_back( "specularmap" ); - arrStrInvalidTokens.push_back( "map" ); - -// gameLocal.Printf("Entering loop. \n" ); - - idToken tknParsedLine; - int i=0; - for( nBrackets = 0 ; !a_lexSource.EndOfFile() ; ) - { - while(a_lexSource.ReadToken( &tknParsedLine )) - { - if ( tknParsedLine.linesCrossed ) { -// gameLocal.Printf("End of the line reached. \n" ); - break; - } - if ( a_strStageTextureName.Length() ) { - a_strStageTextureName += " "; - } - bool bIsValidToken = true; - for( std::vector::iterator iter = arrStrInvalidTokens.begin() ; arrStrInvalidTokens.end() != iter; iter ++ ) - { - if( 0 != tknParsedLine.Icmp( *iter ) ) - continue; - - bIsValidToken = false; -// gameLocal.Printf("Invalid token found. \n" ); - break; - } - if( bIsValidToken ) - { - a_strStageTextureName += tknParsedLine; -// gameLocal.Printf("constructing \"%s\" with a valid token. \n", a_strStageTextureName.c_str() ); - } - else - { -// gameLocal.Printf("%s is an invalid token. \n", tknParsedLine.c_str() ); - break; - } - } - - a_strStageTextureName.Strip('\n'); - a_strStageTextureName.Strip('\t'); - a_strStageTextureName.Strip('\r'); - a_strStageTextureName.Strip(' '); - - // Make sure that we have equal number of opening bracket and closing brackets. - for(iOffset = 0, nBrackets = 0; 0 <= (iOffset = a_strStageTextureName.Find( '(', iOffset )); nBrackets ++, iOffset ++ ); - for(iOffset = 0; 0 <= (iOffset = a_strStageTextureName.Find( ')', iOffset )); nBrackets --, iOffset ++ ); - - if ( 0 == nBrackets ) - { - // We have gone one token ahead than needed in the lexer so offset it back again. -// gameLocal.Printf("Unreading token %s. \n", tknParsedLine.c_str() ); - a_lexSource.UnreadToken( &tknParsedLine ); - - a_strStageTextureName.Strip('}'); - a_strStageTextureName.Strip('{'); - if( a_strStageTextureName.Length() <= 0 ) - return false; - - gameLocal.Printf(" Found valid expression: %s \n ", a_strStageTextureName.c_str() ); - return true; - } - - // Append the first token of the newly read line. - a_strStageTextureName += tknParsedLine; - } - - return false; -} - -//------------------------------------------------------------- -// GetMaterialStageInfo -// -// Description: For a given material stage (any one of "diffusemap", "bumpmap" & specular map ) finds out number of -// textures (pathnames) being used along with their UV scales. -//------------------------------------------------------------- -void GetMaterialStageInfo ( const char* a_strMatStageName, idLexer &a_lexSource, ImageInfoMap & a_arrMatStageInfo ) -{ - a_lexSource.Reset(); -// gameLocal.Printf( "Looking for valid %s stage information (w/o blend). \n", a_strMatStageName ); - while ( 1 == a_lexSource.SkipUntilString( a_strMatStageName ) ) - { - ImageInfo_s currentImageInfo ; - - if( true == GetValidStageExpression( a_lexSource, currentImageInfo.m_strImageName ) ) - { -// gameLocal.Printf( "Found valid %s stage information (w/o blend). \n", a_strMatStageName ); - a_arrMatStageInfo.insert( ImageInfoMap::value_type( eVertexBlendType_None, currentImageInfo ) ); - } - } -// if( a_arrMatStageInfo.size() == 0 ) -// gameLocal.Printf( "Could not find valid %s stage information w/o blend. \n", a_strMatStageName); - - a_lexSource.Reset(); - -// gameLocal.Printf( "Looking for %s stage information with blend. \n", a_strMatStageName ); - while ( 1 == a_lexSource.SkipUntilString( "blend" ) ) - { - idToken tknMatStage; - if( 1 == a_lexSource.ReadToken( &tknMatStage ) && 0 == tknMatStage.Icmp(a_strMatStageName) ) - { - idToken tknMap; - if( 0 != a_lexSource.ReadToken( &tknMap ) && 0 == tknMap.Icmp("map") ) - { - ImageInfo_s currentImageInfo; - eVertexBlendType vertBlendType = eVertexBlendType_None; - - if( true == GetValidStageExpression( a_lexSource, currentImageInfo.m_strImageName ) ) - { - bool bIsScaleFound = false; - while( "}" != tknMatStage ) - { - if( !a_lexSource.ReadToken( &tknMatStage ) ) - { - gameLocal.Warning( "Unexpected end of material when trying to obtain scale. \n"); - break; - } - // Not using expectTokenString anymore since "Map" is treated as different token than "map". - // So doing a manual non-case sensitive checks instead. - if( !bIsScaleFound && 0 == tknMatStage.Icmp("scale") ) - { - idStr strScale; - if( true == GetValidStageExpression( a_lexSource, strScale ) ) - currentImageInfo.m_strUVScale = strScale; - - gameLocal.Printf(" Scale: %s \n ", strScale.c_str() ); - bIsScaleFound = true; - } - - if( eVertexBlendType_None == vertBlendType ) - { - if( 0 == tknMatStage.Icmp("vertexColor") ) - { - gameLocal.Printf(" The stage is vertex-colored \n " ); - vertBlendType = eVertexBlendType_VertexColored; - } - else if( 0 == tknMatStage.Icmp("inverseVertexColor") ) - { - gameLocal.Printf(" The stage is inverse vertex-colored \n " ); - vertBlendType = eVertexBlendType_InvVertexColored; - } - } - else if( bIsScaleFound ) - break; - - } - a_arrMatStageInfo.insert( ImageInfoMap::value_type( vertBlendType, currentImageInfo ) ); - - } - } - } - - } -} - - -//------------------------------------------------------------- -// FindBlockContainingWords -// -// Description: Inside a specified material shader block, finds the character offsets for start & end of the block -// that contains the words (specified by vector of strings) in their exact order. -// Return value: True if the block is found. -//------------------------------------------------------------- - -bool FindBlockContainingWords( const char *a_text, std::vector& a_arrSearchWords, unsigned int & a_uiStartOffset, unsigned int & a_uiEndOffset, - const char a_cBlockStart = '{', const char a_cBlockEnd = '}' ) -{ - int uiSearchIndex; - unsigned int uiSearchOffset = 0; - unsigned int iTextLength = idStr::Length(a_text); - bool bAreAllWordsFound = false; - - for(std::vector::iterator iter = a_arrSearchWords.begin(); ; ) - { - - uiSearchIndex = idStr::FindText( a_text, (*iter).c_str(), false, uiSearchOffset ); - // gameLocal.Printf( " Searched %s from offset %d and found index %d \n", (*iter).c_str(),uiSearchOffset, uiSearchIndex ); - - if( uiSearchIndex < 0 ) - { - // gameLocal.Warning( " Could not find search word %s\n", (*iter).c_str() ); - return false; - } - - bAreAllWordsFound = true; - - // Make sure that, this is not the first word we have found. - if( a_arrSearchWords.begin() != iter ) - { - if( uiSearchIndex != uiSearchOffset ) - { - // gameLocal.Warning( " Could not find search word %s in the expected order\n", (*iter).c_str() ); - - //Start the search from the first word again, since all of the search words are important. - bAreAllWordsFound = false; - iter = a_arrSearchWords.begin(); - continue; - } - } - - // Increment the iterator. - iter ++; - - if( a_arrSearchWords.end() == iter ) - break; - - //Read white spaces and adjust the search offset accordingly for the next search. - for( uiSearchOffset = uiSearchIndex + (*(iter-1)).Length(); uiSearchOffset < iTextLength; uiSearchOffset++ ) - { - if( ' ' == a_text[ uiSearchOffset ] || '\t' == a_text[ uiSearchOffset ] || '\r' == a_text[ uiSearchOffset ] ) - continue; - - break; - } - } - - if( bAreAllWordsFound ) - { - // gameLocal.Printf( " Total %d word(s) found \n", a_arrSearchWords.size() ); - - if( a_arrSearchWords.size() == 1 ) - { - uiSearchOffset = uiSearchIndex; - } - - // Start tracking offsets to the opening and closing of the block from the last search-Index. - bool bIsStartOffsetFound = false; - bool bIsEndOffsetFound = false; - for( a_uiStartOffset = a_uiEndOffset = uiSearchOffset ; a_uiStartOffset > 0 && a_uiEndOffset < iTextLength ; ) - { - if( a_cBlockStart == a_text[ a_uiStartOffset ] ) - bIsStartOffsetFound = true; - else - a_uiStartOffset --; - - if( a_cBlockEnd == a_text[ a_uiEndOffset ] ) - bIsEndOffsetFound = true; - else - a_uiEndOffset ++; - - if( bIsStartOffsetFound && bIsEndOffsetFound ) - { - // Adjust end offset by one extra character to make sure that we account the closing block. - a_uiEndOffset ++; - // idStr myBlock( a_text, a_uiStartOffset, a_uiEndOffset ); - // gameLocal.Printf( "Found block from %d to %d, search offset is %d\n", a_uiStartOffset, a_uiEndOffset, uiSearchOffset ); - // gameLocal.Printf( "%s \n", myBlock.c_str() ); - return true; - } - } - // gameLocal.Warning( " Block start found:%d Block End Found:%d, Returning false.\n", (int)bIsStartOffsetFound, (int)bIsEndOffsetFound ); - } - - // if( !bAreAllWordsFound ) - // gameLocal.Warning( " Returning false since given words can't be found in the exact given order.\n" ); - return false; -} - -void CreateNewAmbientBlock( const ImageInfoMap& a_arrDiffusemapInfo, const ImageInfoMap& a_arrBumpmapInfo, const ImageInfoMap& a_arrSpecularmapInfo, std::vector& a_arrCharNewAmbientBlock ) -{ - static const char newAmbientBlock[] = { - "\n { \n" - " if (global5 == 1) \n" - " blend add \n" - " map %s \n" - " scale %s \n" - " red global2 \n" - " green global3 \n" - " blue global4 \n" - " } \n" - " { \n" - " if (global5 == 2) \n" - " blend add \n" - " program ambientEnvironment.vfp \n" - " vertexParm 0 %s, %s // UV Scales for Diffuse and Bump \n" - " vertexParm 1 %s, 1, 1 // (X,Y) UV Scale for specular \n" - " vertexParm 2 global2, global3, global4, 1 \n" - " \n" - " fragmentMap 0 cubeMap env/gen1 \n" - " fragmentMap 1 %s // Bump \n" - " fragmentMap 2 %s // Diffuse \n" - " fragmentMap 3 %s // Specular \n" - " }" - }; - - static const char newAmbientBlockVertColorBlended[] = { - "\n { \n" - " if (global5 == 1) \n" - " blend add \n" - " map %s \n" - " scale %s \n" - " red global2 \n" - " green global3 \n" - " blue global4 \n" - " vertexColor \n" - " } \n" - " { \n" - " if (global5 == 1) \n" - " blend add \n" - " map %s \n" - " scale %s \n" - " red global2 \n" - " green global3 \n" - " blue global4 \n" - " inverseVertexColor \n" - " } \n" - " { \n" - " if (global5 == 2) \n" - " blend add \n" - " program ambientEnvVertexBlend.vfp \n" - " vertexParm 0 %s, %s // UV Scales for Diffuse1 and Bump1 resp. \n" - " vertexParm 1 %s, %s // UV Scale for specular1 and Diffuse2 resp.\n" - " vertexParm 2 %s, %s // UV Scale for Bump2 and specular2 resp. \n" - " vertexParm 3 global2, global3, global4, 1 \n" - " //----------- VertexColored ------------------- \n" - " fragmentMap 0 cubeMap env/gen1 \n" - " fragmentMap 1 %s // Bump1 \n" - " fragmentMap 2 %s // Diffuse1 \n" - " fragmentMap 3 %s // Specular1 \n" - " //----------- InverseVertexColored ------------ \n" - " fragmentMap 4 %s // Bump2 \n" - " fragmentMap 5 %s // Diffuse2 \n" - " fragmentMap 6 %s // Specular2 \n" - " }" - }; - - - - ImageInfoMap::const_iterator itrDiffusemapInfoVertexColored = a_arrDiffusemapInfo.find( eVertexBlendType_VertexColored ); - ImageInfoMap::const_iterator itrBumpmapInfoVertexColored = a_arrBumpmapInfo.find( eVertexBlendType_VertexColored ); - ImageInfoMap::const_iterator itrSpecularmapInfoVertexColored = a_arrSpecularmapInfo.find( eVertexBlendType_VertexColored ); - - ImageInfoMap::const_iterator itrDiffusemapInfoInvVertexColored = a_arrDiffusemapInfo.find( eVertexBlendType_InvVertexColored ); - ImageInfoMap::const_iterator itrBumpmapInfoInvVertexColored = a_arrBumpmapInfo.find( eVertexBlendType_InvVertexColored ); - ImageInfoMap::const_iterator itrSpecularmapInfoInvVertexColored = a_arrSpecularmapInfo.find( eVertexBlendType_InvVertexColored ); - - bool bIsVertexColorBlended = ( ( a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored || a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored || - a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ) && - (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored || a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored || - a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ) ); - - ImageInfoMap::const_iterator itrDiffusemapInfo = a_arrDiffusemapInfo.find( eVertexBlendType_None ); - ImageInfoMap::const_iterator itrBumpmapInfo = a_arrBumpmapInfo.find( eVertexBlendType_None ); - ImageInfoMap::const_iterator itrSpecularmapInfo = a_arrSpecularmapInfo.find( eVertexBlendType_None ); - - - if ( bIsVertexColorBlended ) - { - gameLocal.Printf("This material is vertex-color blended. \n"); - - // Find out normal maps for vertex blending. - - // Handle cases where vertexColor is not used for bumpmaps - if ( a_arrBumpmapInfo.end() == itrBumpmapInfoVertexColored ) - itrBumpmapInfoVertexColored = itrBumpmapInfo; - - if ( a_arrBumpmapInfo.end() == itrBumpmapInfoInvVertexColored ) - { - ImageInfoMap::const_iterator itrBumpmapInfo2 = itrBumpmapInfo; - if( a_arrBumpmapInfo.end() != itrBumpmapInfo2 ) - { - // Try and see if there's a second bumpmap with no vertex-color blend. - ++itrBumpmapInfo2; - itrBumpmapInfoInvVertexColored = a_arrBumpmapInfo.end() != itrBumpmapInfo2 ? ( eVertexBlendType_None == (*itrBumpmapInfo2).first ? itrBumpmapInfo2 : itrBumpmapInfo ) : itrBumpmapInfo; - } - } - unsigned int uiBlockSize = idStr::Length( newAmbientBlockVertColorBlended ) + 1 + - //------------------ For vertexColor ---------------- - (a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + - (a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + - ( a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_flat") ) + - ( a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + - //------------------ For inverseVertexColor --------- - (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + - (a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + - ( a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_flat") ) + - ( a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strImageName.Length() : idStr::Length("_black") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strUVScale.Length() : idStr::Length("1, 1") ); - - - a_arrCharNewAmbientBlock.resize( uiBlockSize, 0 ); - - idStr::snPrintf( &a_arrCharNewAmbientBlock[0], uiBlockSize, newAmbientBlockVertColorBlended, - //------------------ For vertexColor ---------------- - a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.c_str() : "_black", - a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", - //------------------ For inverseVertexColor --------- - a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.c_str() : "_black", - a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", - //--------------------------------------------------- - - //------------------ For vertexColor ---------------- - a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", - a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", - a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strUVScale.c_str() : "1, 1", - //------------------ For inverseVertexColor --------- - a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", - a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", - a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strUVScale.c_str() : "1, 1", - //--------------------------------------------------- - - //------------------ For vertexColor ---------------- - a_arrBumpmapInfo.end() != itrBumpmapInfoVertexColored ? (*itrBumpmapInfoVertexColored).second.m_strImageName.c_str() : "_flat", - a_arrDiffusemapInfo.end() != itrDiffusemapInfoVertexColored ? (*itrDiffusemapInfoVertexColored).second.m_strImageName.c_str() : "_black", - a_arrSpecularmapInfo.end() != itrSpecularmapInfoVertexColored ? (*itrSpecularmapInfoVertexColored).second.m_strImageName.c_str() : "_black", - //------------------ For inverseVertexColor --------- - a_arrBumpmapInfo.end() != itrBumpmapInfoInvVertexColored ? (*itrBumpmapInfoInvVertexColored).second.m_strImageName.c_str() : "_flat", - a_arrDiffusemapInfo.end() != itrDiffusemapInfoInvVertexColored ? (*itrDiffusemapInfoInvVertexColored).second.m_strImageName.c_str() : "_black", - a_arrSpecularmapInfo.end() != itrSpecularmapInfoInvVertexColored ? (*itrSpecularmapInfoInvVertexColored).second.m_strImageName.c_str() : "_black" - //--------------------------------------------------- - ); - } - else - { - gameLocal.Printf("This material is vertex-color blended. \n"); - unsigned int uiBlockSize = idStr::Length( newAmbientBlock ) + 1 + - (a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.Length() : idStr::Length("_black") ) * 2 + - (a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ) * 2 + - ( a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strImageName.Length() : idStr::Length("_flat") ) + - ( a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strImageName.Length() : idStr::Length("_black") ) + - (a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strUVScale.Length() : idStr::Length("1, 1") ); - - a_arrCharNewAmbientBlock.resize( uiBlockSize, 0 ); - - idStr::snPrintf( &a_arrCharNewAmbientBlock[0], uiBlockSize, newAmbientBlock, - a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.c_str() : "_black", - a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.c_str() : "1, 1", - a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strUVScale.c_str() : "1, 1", - a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strUVScale.c_str() : "1, 1", - a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strUVScale.c_str() : "1, 1", - a_arrBumpmapInfo.end() != itrBumpmapInfo ? (*itrBumpmapInfo).second.m_strImageName.c_str() : "_flat", - a_arrDiffusemapInfo.end() != itrDiffusemapInfo ? (*itrDiffusemapInfo).second.m_strImageName.c_str() : "_black", - a_arrSpecularmapInfo.end() != itrSpecularmapInfo ? (*itrSpecularmapInfo).second.m_strImageName.c_str() : "_black" - ); - } - -} - -void Cmd_BatchConvertMaterials_f( const idCmdArgs& args ) -{ - - if( args.Argc() < 3 ) - { - gameLocal.Printf( "Usage: tdm_batchConvertMaterials [forceUpdateAll] \n" ); - return; - } - - bool bForceUpdateAllMaterials = false; - if( args.Argc() > 3 ) - { - bForceUpdateAllMaterials = (0 == idStr::Icmp( args.Argv(3), "forceupdateall" )); - } - - const unsigned int uiStartIndex = atoi(args.Argv(1)); - const unsigned int uiMaterialsToProcess = atoi(args.Argv(2)); - - const unsigned long uiTotalMats = declManager->GetNumDecls( DECL_MATERIAL ); - - gameLocal.Printf("Parsing %d materials, this may take few minutes...\n", uiTotalMats ); - - unsigned long ulMaterialsProcessed = 0; - unsigned long i = uiStartIndex > (uiTotalMats - 1) ? uiTotalMats : uiStartIndex; - const unsigned uiMaxMaterialsToProcess = i + uiMaterialsToProcess; - for ( ; i < uiTotalMats && i < uiMaxMaterialsToProcess; i++ ) - { - - idMaterial *mat = const_cast(declManager->MaterialByIndex( i )); - - // for testing - //idMaterial *mat = const_cast(declManager->FindMaterial( "textures/base_wall/xiantex3_dark_burn" )); - - if( NULL == mat ) - continue; - - gameLocal.Printf("Material %s loaded. \n", mat->GetName() ); - - std::vector< char > charBuffer; - - ImageInfoMap arrDiffusemapInfo; - ImageInfoMap arrBumpMapInfo; - ImageInfoMap arrSpecularmapInfo; - - charBuffer.resize( mat->GetTextLength() + 1, 0 ); - mat->GetText( &charBuffer[0] ); - - idLexer lexSource( &charBuffer[0], charBuffer.size(), mat->GetName(), LEXFL_NOFATALERRORS | LEXFL_ALLOWPATHNAMES ); - - gameLocal.Printf("Finding out shader stages... \n" ); - - bool bAreBumpmapsExtracted =false; - bool bAreDiffusemapsExtracted =false; - bool bAreSpecularmapsExtracted =false; - for ( int j=0; j < mat->GetNumStages(); j++ ) - { - const shaderStage_t *pShaderStage = mat->GetStage(j); - - if( NULL == pShaderStage ) - { -// mat->Invalidate(); -// mat->FreeData(); - continue; - } - - //GetMaterialStageInfo extracts all the stages in material of given type so don't loop again for multiple similar stages. - if ( bAreBumpmapsExtracted && bAreDiffusemapsExtracted && bAreSpecularmapsExtracted ) - break; - - - switch( pShaderStage->lighting ) - { - case SL_BUMP: - if( bAreBumpmapsExtracted ) - continue; - - gameLocal.Printf("Bumpmap stage found, extracting bumpmap information... \n" ); - GetMaterialStageInfo( "bumpmap", lexSource, arrBumpMapInfo ); - bAreBumpmapsExtracted = true; - break; - case SL_DIFFUSE: - if( bAreDiffusemapsExtracted ) - continue; - - gameLocal.Printf("Diffusemap stage found, extracting diffusemap information... \n" ); - GetMaterialStageInfo( "diffusemap", lexSource, arrDiffusemapInfo ); - bAreDiffusemapsExtracted = true; - break; - case SL_SPECULAR: - if( bAreSpecularmapsExtracted ) - continue; - - gameLocal.Printf("Specularmap stage found, extracting specularmap information... \n" ); - GetMaterialStageInfo( "specularmap", lexSource, arrSpecularmapInfo ); - bAreSpecularmapsExtracted = true; - break; - default: - continue; - } - } - gameLocal.Printf("Done. \n" ); -// break; // remove me!!! - - if( arrBumpMapInfo.size() == 0 && arrDiffusemapInfo.size() == 0 && arrSpecularmapInfo.size() == 0 ) - { -// mat->Invalidate(); -// mat->FreeData(); - continue; - } - unsigned int uiBlockStartOffset, uiBlockEndOffset; - std::vector< idStr >arrSearchWords; - bool bIsAmbientBlockFound = false; - - // Note that, the spaces in the string:"if (global5 == 1)" and an externally modified material may not match. - // So avoid changing new ambient lighting blocks by hand, at least "if (global5 == 1)" part. - arrSearchWords.clear(); - arrSearchWords.push_back("if (global5 == 1)"); - bIsAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); - - gameLocal.Printf( "ForceUpdate is: %s\n", bForceUpdateAllMaterials? "true": "false" ); - if( bIsAmbientBlockFound ) - { - gameLocal.Printf( "Found new ambient block\n" ); - - gameLocal.Printf( "Removing new ambient block\n" ); - charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); - - // Try the search again with global5 == 1 in case the material is vertex color blended. - bool bIsSecondAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); - - if( bIsSecondAmbientBlockFound ) - charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); - - arrSearchWords.clear(); - arrSearchWords.push_back("if (global5 == 2)"); - bIsAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); - if( bIsAmbientBlockFound ) - charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); - } - - //Some materials may have old ambient block along with the new one. So remove it if found. - { - bool bIsOldAmbientBlockFound; - arrSearchWords.clear(); - arrSearchWords.push_back("red"); - arrSearchWords.push_back("global2"); - bIsOldAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); - if( bIsOldAmbientBlockFound ) - { - gameLocal.Printf( "Found old ambient block\n" ); - gameLocal.Printf( "Removing old ambient block\n" ); - charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); - bIsAmbientBlockFound = true; - } - - // Try the search again, in case the material is vertex color blended and there is second inverse-vertex-colored ambient block. - bIsOldAmbientBlockFound = FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiBlockStartOffset, uiBlockEndOffset ); - - if( bIsOldAmbientBlockFound ) - charBuffer.erase( charBuffer.begin() + uiBlockStartOffset, charBuffer.begin() + uiBlockEndOffset ); - - // If we couldn't find old ambient block and we have new ambient block in place, - // then we can safely skip this material. - else if( !bForceUpdateAllMaterials && bIsAmbientBlockFound ) - continue; - } - - - unsigned int uiOffset = 0; - - if( bIsAmbientBlockFound ) - { - //Remove the old comment. - unsigned int uiCommentStart, uiCommentEnd; - arrSearchWords.clear(); - - arrSearchWords.push_back("TDM"); - arrSearchWords.push_back("Ambient"); - arrSearchWords.push_back("Method"); - arrSearchWords.push_back("Related"); - if ( FindBlockContainingWords( &charBuffer[0], arrSearchWords, uiCommentStart, uiCommentEnd, '\n', '\n' ) ) - { - charBuffer.erase( charBuffer.begin() + uiCommentStart, charBuffer.begin() + uiCommentEnd ); - gameLocal.Printf( " Ambient method related comment found and removed. \n" ); - } - } - //------------------------------------ - int i; - unsigned int uiEndoftheBlock = 0; - for( i= charBuffer.size() - 1; i > 0; i-- ) - { - if( '}' == charBuffer[i] ) - { - uiEndoftheBlock = i--; - // Find additional white spaces and new line characters before end of the block. - while( '\n' == charBuffer[i] || ' ' == charBuffer[i] || '\t' == charBuffer[i] || '\r' == charBuffer[i] ) - { - if(0 >= i) - break; - - i--; - } - // Remove white spaces and new line characters that are found before end of the block. - if( unsigned(i + 1) <= uiEndoftheBlock - 1 ) - { - charBuffer.erase( charBuffer.begin() + i + 1 , charBuffer.begin() + uiEndoftheBlock - 1 ); - gameLocal.Printf( "%d trailing white spaces found at end of the block and are removed. %d, %d, %c \n", uiEndoftheBlock - i - 1, uiEndoftheBlock, i + 1, charBuffer[i+2] ); - // Update end of the block's position. - uiEndoftheBlock = i + 2; - } - else - { - gameLocal.Printf( "No trailing white spaces found at end of the block. %c\n", charBuffer[i] ); - } - break; - } - } - - idStr strMatTextWithNewBlock( &charBuffer[0] ); - - if( i > 1 ) - { - strMatTextWithNewBlock.Insert( "\n\n // TDM Ambient Method Related ", uiEndoftheBlock - 1 ); - uiOffset = uiEndoftheBlock - 1 + idStr::Length( "\n\n // TDM Ambient Method Related " ); - //strMatTextWithNewBlock.Insert( '\n', uiOffset ); - } - else - { - gameLocal.Warning( "Could not determine end of the material block. Skipping this material.\n" ); - // mat->Invalidate(); - // mat->FreeData(); - continue; - } - - - gameLocal.Printf( "Processing Material %s \n", mat->GetName() ); - - std::vector arrCharNewAmbientBlock; - - CreateNewAmbientBlock( arrDiffusemapInfo, arrBumpMapInfo, arrSpecularmapInfo, arrCharNewAmbientBlock ); - - strMatTextWithNewBlock.Insert( &arrCharNewAmbientBlock[0], uiOffset ); - - ulMaterialsProcessed ++; - - // Update the material text and save to the file. - mat->SetText( strMatTextWithNewBlock.c_str() ); - - if( !mat->Parse( strMatTextWithNewBlock.c_str(), strMatTextWithNewBlock.Length() ) ) - { - gameLocal.Warning( "Material %s had error in the newly inserted text %s. \n Aborting.\n", mat->GetName(), &arrCharNewAmbientBlock[0] ); - break; - } - mat->ReplaceSourceFileText(); - mat->Invalidate(); - mat->FreeData(); - } - gameLocal.Printf(" %d Materials processed and changed in total.\n", ulMaterialsProcessed ); -} - - -void Cmd_updateCookedMathData_f( const idCmdArgs& args ) -{ - r_postprocess_colorCurveBias.SetModified(); -} - -#ifdef TIMING_BUILD -void Cmd_ListTimers_f(const idCmdArgs& args) -{ - PRINT_TIMERS; -} - -void Cmd_WriteTimerCSV_f(const idCmdArgs& args) -{ - if (args.Argc() == 2) // Only separator - { - debugtools::TimerManager::Instance().DumpTimerResults(args.Argv(1)); - return; - } - - if (args.Argc() == 3) // separator + comma - { - debugtools::TimerManager::Instance().DumpTimerResults(args.Argv(1), args.Argv(2)); - return; - } - - // No arguments, call default - debugtools::TimerManager::Instance().DumpTimerResults(); -} - -void Cmd_ResetTimers_f(const idCmdArgs& args) -{ - debugtools::TimerManager::Instance().ResetTimers(); -} -#endif // TIMING_BUILD - -/* -================= -idGameLocal::InitConsoleCommands - -Let the system know about all of our commands -so it can perform tab completion -================= -*/ -void idGameLocal::InitConsoleCommands( void ) { - cmdSystem->AddCommand( "listTypeInfo", ListTypeInfo_f, CMD_FL_GAME, "list type info" ); - cmdSystem->AddCommand( "writeGameState", WriteGameState_f, CMD_FL_GAME, "write game state" ); - cmdSystem->AddCommand( "testSaveGame", TestSaveGame_f, CMD_FL_GAME|CMD_FL_CHEAT, "test a save game for a level" ); - cmdSystem->AddCommand( "game_memory", idClass::DisplayInfo_f, CMD_FL_GAME, "displays game class info" ); - cmdSystem->AddCommand( "listClasses", idClass::ListClasses_f, CMD_FL_GAME, "lists game classes" ); - cmdSystem->AddCommand( "listThreads", idThread::ListThreads_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists script threads" ); - cmdSystem->AddCommand( "listEntities", Cmd_EntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists game entities" ); - cmdSystem->AddCommand( "listActiveEntities", Cmd_ActiveEntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists active game entities" ); - cmdSystem->AddCommand( "listMonsters", idAI::List_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists monsters" ); - cmdSystem->AddCommand( "listSpawnArgs", Cmd_ListSpawnArgs_f, CMD_FL_GAME|CMD_FL_CHEAT, "list the spawn args of an entity", idGameLocal::ArgCompletion_EntityName ); - cmdSystem->AddCommand( "say", Cmd_Say_f, CMD_FL_GAME, "text chat" ); - cmdSystem->AddCommand( "sayTeam", Cmd_SayTeam_f, CMD_FL_GAME, "team text chat" ); - cmdSystem->AddCommand( "addChatLine", Cmd_AddChatLine_f, CMD_FL_GAME, "internal use - core to game chat lines" ); - cmdSystem->AddCommand( "gameKick", Cmd_Kick_f, CMD_FL_GAME, "same as kick, but recognizes player names" ); - cmdSystem->AddCommand( "give", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" ); - cmdSystem->AddCommand( "centerview", Cmd_CenterView_f, CMD_FL_GAME, "centers the view" ); - cmdSystem->AddCommand( "god", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" ); - cmdSystem->AddCommand( "notarget", Cmd_Notarget_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables the player as a target" ); - cmdSystem->AddCommand( "noclip", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" ); - cmdSystem->AddCommand( "kill", Cmd_Kill_f, CMD_FL_GAME, "kills the player" ); - cmdSystem->AddCommand( "where", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" ); - cmdSystem->AddCommand( "getviewpos", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" ); - cmdSystem->AddCommand( "setviewpos", Cmd_SetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the current view position" ); - cmdSystem->AddCommand( "teleport", Cmd_Teleport_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleports the player to an entity location", idGameLocal::ArgCompletion_EntityName ); - cmdSystem->AddCommand( "trigger", Cmd_Trigger_f, CMD_FL_GAME|CMD_FL_CHEAT, "triggers an entity", idGameLocal::ArgCompletion_EntityName ); - cmdSystem->AddCommand( "spawn", Cmd_Spawn_f, CMD_FL_GAME|CMD_FL_CHEAT, "spawns a game entity", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "damage", Cmd_Damage_f, CMD_FL_GAME|CMD_FL_CHEAT, "apply damage to an entity", idGameLocal::ArgCompletion_EntityName ); - cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName ); - cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" ); - cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" ); - cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" ); - cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" ); - cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" ); - cmdSystem->AddCommand( "removeline", Cmd_RemoveDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes a debug line" ); - cmdSystem->AddCommand( "blinkline", Cmd_BlinkDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "blinks a debug line" ); - cmdSystem->AddCommand( "listLines", Cmd_ListDebugLines_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists all debug lines" ); - cmdSystem->AddCommand( "playerModel", Cmd_PlayerModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the given model on the player", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "testFx", Cmd_TestFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "testBoneFx", Cmd_TestBoneFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system bound to a joint", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "testLight", Cmd_TestLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a light" ); - cmdSystem->AddCommand( "testPointLight", Cmd_TestPointLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a point light" ); - cmdSystem->AddCommand( "popLight", Cmd_PopLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes the last created light" ); - cmdSystem->AddCommand( "testDeath", Cmd_TestDeath_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests death" ); - cmdSystem->AddCommand( "testSave", Cmd_TestSave_f, CMD_FL_GAME|CMD_FL_CHEAT, "writes out a test savegame" ); - cmdSystem->AddCommand( "testModel", idTestModel::TestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a model", idTestModel::ArgCompletion_TestModel ); - cmdSystem->AddCommand( "testSkin", idTestModel::TestSkin_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a skin on an existing testModel", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "testShaderParm", idTestModel::TestShaderParm_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets a shaderParm on an existing testModel" ); - cmdSystem->AddCommand( "keepTestModel", idTestModel::KeepTestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "keeps the last test model in the game" ); - cmdSystem->AddCommand( "testAnim", idTestModel::TestAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an animation", idTestModel::ArgCompletion_TestAnim ); - cmdSystem->AddCommand( "testParticleStopTime", idTestModel::TestParticleStopTime_f,CMD_FL_GAME|CMD_FL_CHEAT, "tests particle stop time on a test model" ); - cmdSystem->AddCommand( "nextAnim", idTestModel::TestModelNextAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation on test model" ); - cmdSystem->AddCommand( "prevAnim", idTestModel::TestModelPrevAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation on test model" ); - cmdSystem->AddCommand( "nextFrame", idTestModel::TestModelNextFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation frame on test model" ); - cmdSystem->AddCommand( "prevFrame", idTestModel::TestModelPrevFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation frame on test model" ); - cmdSystem->AddCommand( "testBlend", idTestModel::TestBlend_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests animation blending" ); - cmdSystem->AddCommand( "reloadScript", Cmd_ReloadScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads scripts" ); - - cmdSystem->AddCommand( "tdm_updateCookedMathData", Cmd_updateCookedMathData_f, CMD_FL_RENDERER, "Updates lookup textures" ); - - cmdSystem->AddCommand( "script", Cmd_Script_f, CMD_FL_GAME|CMD_FL_CHEAT, "executes a line of script" ); - cmdSystem->AddCommand( "listCollisionModels", Cmd_ListCollisionModels_f, CMD_FL_GAME, "lists collision models" ); - cmdSystem->AddCommand( "collisionModelInfo", Cmd_CollisionModelInfo_f, CMD_FL_GAME, "shows collision model info" ); - cmdSystem->AddCommand( "reexportmodels", Cmd_ReexportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "reexports models", ArgCompletion_DefFile ); - cmdSystem->AddCommand( "reloadanims", Cmd_ReloadAnims_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads animations" ); - cmdSystem->AddCommand( "listAnims", Cmd_ListAnims_f, CMD_FL_GAME, "lists all animations" ); - cmdSystem->AddCommand( "aasStats", Cmd_AASStats_f, CMD_FL_GAME, "shows AAS stats" ); - cmdSystem->AddCommand( "testDamage", Cmd_TestDamage_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a damage def", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "weaponSplat", Cmd_WeaponSplat_f, CMD_FL_GAME|CMD_FL_CHEAT, "projects a blood splat on the player weapon" ); - cmdSystem->AddCommand( "saveSelected", Cmd_SaveSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves the selected entity to the .map file" ); - cmdSystem->AddCommand( "deleteSelected", Cmd_DeleteSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "deletes selected entity" ); - cmdSystem->AddCommand( "saveMoveables", Cmd_SaveMoveables_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all moveables to the .map file" ); - cmdSystem->AddCommand( "saveRagdolls", Cmd_SaveRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all ragdoll poses to the .map file" ); - cmdSystem->AddCommand( "bindRagdoll", Cmd_BindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "binds ragdoll at the current drag position" ); - cmdSystem->AddCommand( "unbindRagdoll", Cmd_UnbindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "unbinds the selected ragdoll" ); - cmdSystem->AddCommand( "saveLights", Cmd_SaveLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" ); - cmdSystem->AddCommand( "saveParticles", Cmd_SaveParticles_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" ); - cmdSystem->AddCommand( "clearLights", Cmd_ClearLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "clears all lights" ); - cmdSystem->AddCommand( "gameError", Cmd_GameError_f, CMD_FL_GAME|CMD_FL_CHEAT, "causes a game error" ); - - cmdSystem->AddCommand( "tdm_spr_testIO", Cmd_TestSndIO_f, CMD_FL_GAME, "test soundprop file IO (needs a .spr file)" ); - cmdSystem->AddCommand( "tdm_ai_rel_print", Cmd_PrintAIRelations_f, CMD_FL_GAME, "print the relationship matrix determining relations between AI teams." ); - - cmdSystem->AddCommand( "tdm_attach_offset", Cmd_AttachmentOffset_f, CMD_FL_GAME, "Set the vector offset (x y z) for an attachment on an AI you are looking at. Usage: tdm_attach_offset " ); - cmdSystem->AddCommand( "tdm_attach_rot", Cmd_AttachmentRot_f, CMD_FL_GAME, "Set the rotation (pitch yaw roll) for an attachment on an AI you are looking at. Usage: tdm_attach_rot (NOTE: Rotation is applied before translation, angles are relative to the joint orientation)" ); - - cmdSystem->AddCommand( "inventory_hotkey", Cmd_InventoryHotkey_f, CMD_FL_GAME, "Usage: inventory_hotkey [item]\nSelects an item from the currently available inventory. If 'item' is omitted, it will return the current item's hotkey name, if any." ); - cmdSystem->AddCommand( "inventory_use", Cmd_InventoryUse_f, CMD_FL_GAME, "Usage: inventory_use [item]\nUses an item in the currently available inventory without selectign it. If 'item' is omitted, it will use the currently selected item." ); - cmdSystem->AddCommand( "inventory_cycle_maps", Cmd_InventoryCycleMaps_f, CMD_FL_GAME, "Usage: Bind a key to this command to cycle through the inventory maps." ); - cmdSystem->AddCommand( "inventory_cycle_group", Cmd_InventoryCycleGroup_f, CMD_FL_GAME, "Usage: Bind a key to this command to cycle through the specified inventory group." ); - - cmdSystem->AddCommand( "reloadXData", Cmd_ReloadXData_f, CMD_FL_GAME, "Reloads the xdata declarations and refreshes all readables." ); - - cmdSystem->AddCommand( "aas_showWalkPath", Cmd_ShowWalkPath_f, CMD_FL_GAME, "Shows the walk path from the player to the given area number (AAS32)." ); - cmdSystem->AddCommand( "aas_showReachabilities",Cmd_ShowReachabilities_f, CMD_FL_GAME, "Shows the reachabilities for the given area number (AAS32)." ); - cmdSystem->AddCommand( "aas_showStats", Cmd_ShowAASStats_f, CMD_FL_GAME, "Shows the AAS statistics." ); - cmdSystem->AddCommand( "eas_showRoute", Cmd_ShowEASRoute_f, CMD_FL_GAME, "Shows the EAS route to the goal area." ); - - cmdSystem->AddCommand( "tdm_start_conversation", Cmd_StartConversation_f, CMD_FL_GAME, "Starts the conversation with the given name." ); - cmdSystem->AddCommand( "tdm_list_conversations", Cmd_ListConversations_f, CMD_FL_GAME, "List all available conversations by name." ); - - cmdSystem->AddCommand( "tdm_show_loot", Cmd_ShowLoot_f, CMD_FL_GAME|CMD_FL_CHEAT, "Highlight all loot items in the map." ); - - cmdSystem->AddCommand( "tdm_activatelogclass", Cmd_ActivateLog_f, CMD_FL_GAME, "Activates a specific log class during run-time (as defined in darkmod.ini)", CGlobal::ArgCompletion_LogClasses ); - cmdSystem->AddCommand( "tdm_deactivatelogclass", Cmd_DeactivateLog_f, CMD_FL_GAME, "De-activates a specific log class during run-time (as defined in darkmod.ini)", CGlobal::ArgCompletion_LogClasses ); - cmdSystem->AddCommand( "tdm_batchConvertMaterials", Cmd_BatchConvertMaterials_f, CMD_FL_GAME, "Converts specified number of materials to support new ambient lighting" ); - - cmdSystem->AddCommand( "tdm_restart_gui_update_objectives", Cmd_RestartGuiCmd_UpdateObjectives_f, CMD_FL_GAME, "Don't use. Reserved for internal use to dispatch restart GUI commands to the local game instance."); - - cmdSystem->AddCommand( "tdm_list_missions", Cmd_ListMissions_f, CMD_FL_GAME, "Lists all available missions."); - cmdSystem->AddCommand( "tdm_set_mission_completed", Cmd_SetMissionCompleted_f, CMD_FL_GAME, "Sets or clears the 'completed' flag of a named mission."); - - cmdSystem->AddCommand( "tdm_end_mission", Cmd_EndMission_f, CMD_FL_GAME, "Ends this mission and proceeds to the next."); - -#ifndef ID_DEMO_BUILD - cmdSystem->AddCommand( "disasmScript", Cmd_DisasmScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "disassembles script" ); - cmdSystem->AddCommand( "recordViewNotes", Cmd_RecordViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "record the current view position with notes" ); - cmdSystem->AddCommand( "showViewNotes", Cmd_ShowViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "show any view notes for the current map, successive calls will cycle to the next note" ); - cmdSystem->AddCommand( "closeViewNotes", Cmd_CloseViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "close the view showing any notes for this map" ); - cmdSystem->AddCommand( "exportmodels", Cmd_ExportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "exports models", ArgCompletion_DefFile ); - - // multiplayer client commands ( replaces old impulses stuff ) - cmdSystem->AddCommand( "clientDropWeapon", idMultiplayerGame::DropWeapon_f, CMD_FL_GAME, "drop current weapon" ); - cmdSystem->AddCommand( "clientMessageMode", idMultiplayerGame::MessageMode_f, CMD_FL_GAME, "ingame gui message mode" ); - // FIXME: implement -// cmdSystem->AddCommand( "clientVote", idMultiplayerGame::Vote_f, CMD_FL_GAME, "cast your vote: clientVote yes | no" ); -// cmdSystem->AddCommand( "clientCallVote", idMultiplayerGame::CallVote_f, CMD_FL_GAME, "call a vote: clientCallVote si_.. proposed_value" ); - cmdSystem->AddCommand( "clientVoiceChat", idMultiplayerGame::VoiceChat_f, CMD_FL_GAME, "voice chats: clientVoiceChat " ); - cmdSystem->AddCommand( "clientVoiceChatTeam", idMultiplayerGame::VoiceChatTeam_f, CMD_FL_GAME, "team voice chats: clientVoiceChat " ); - - // multiplayer server commands - cmdSystem->AddCommand( "serverMapRestart", idGameLocal::MapRestart_f, CMD_FL_GAME, "restart the current game" ); - cmdSystem->AddCommand( "serverForceReady", idMultiplayerGame::ForceReady_f,CMD_FL_GAME, "force all players ready" ); - cmdSystem->AddCommand( "serverNextMap", idGameLocal::NextMap_f, CMD_FL_GAME, "change to the next map" ); -#endif - - // greebo: Added commands to alter the clipmask/contents of entities. - cmdSystem->AddCommand( "setClipMask", Cmd_SetClipMask, CMD_FL_GAME, "Set the clipmask of the target entity, usage: 'setClipMask crate01 1313'", idGameLocal::ArgCompletion_EntityName); - cmdSystem->AddCommand( "setClipContents", Cmd_SetClipContents, CMD_FL_GAME, "Set the contents flags of the target entity, usage: 'setClipContents crate01 1313'", idGameLocal::ArgCompletion_EntityName); - - // localization help commands - cmdSystem->AddCommand( "nextGUI", Cmd_NextGUI_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleport the player to the next func_static with a gui" ); - cmdSystem->AddCommand( "testid", Cmd_TestId_f, CMD_FL_GAME|CMD_FL_CHEAT, "output the string for the specified id." ); -#ifdef TIMING_BUILD - cmdSystem->AddCommand( "listTimers", Cmd_ListTimers_f, CMD_FL_GAME, "Shows total run time and max time of timers (TIMING_BUILD only)." ); - cmdSystem->AddCommand( "writeTimerCSV", Cmd_WriteTimerCSV_f, CMD_FL_GAME, "Writes the timer data to a csv file (usage: writeTimerCSV ). The default separator is ';', the default comma is '.'"); - cmdSystem->AddCommand( "resetTimers", Cmd_ResetTimers_f, CMD_FL_GAME, "Resets the timer data so far."); -#endif -} - -/* -================= -idGameLocal::ShutdownConsoleCommands -================= -*/ -void idGameLocal::ShutdownConsoleCommands( void ) { - cmdSystem->RemoveFlaggedCommands( CMD_FL_GAME ); -} diff --git a/game/gamesys/syscmds.h b/game/gamesys/syscmds.h deleted file mode 100644 index afc6062cb..000000000 --- a/game/gamesys/syscmds.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SYS_CMDS_H__ -#define __SYS_CMDS_H__ - -void D_DrawDebugLines( void ); - -#endif /* !__SYS_CMDS_H__ */ diff --git a/game/gamesys/syscvar.cpp b/game/gamesys/syscvar.cpp deleted file mode 100644 index d9bfa7ccb..000000000 --- a/game/gamesys/syscvar.cpp +++ /dev/null @@ -1,772 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#if defined( _DEBUG ) - #define BUILD_DEBUG "-debug" -#else - #define BUILD_DEBUG "-release" -#endif - -/* - -All game cvars should be defined here. - -*/ - -const char *si_gameTypeArgs[] = { "singleplayer", "deathmatch", "Tourney", "Team DM", "Last Man", NULL }; -const char *si_readyArgs[] = { "Not Ready", "Ready", NULL }; -const char *si_spectateArgs[] = { "Play", "Spectate", NULL }; - -const char *ui_skinArgs[] = { "skins/characters/player/marine_mp", "skins/characters/player/marine_mp_red", "skins/characters/player/marine_mp_blue", "skins/characters/player/marine_mp_green", "skins/characters/player/marine_mp_yellow", NULL }; -const char *ui_teamArgs[] = { "Red", "Blue", NULL }; - -struct gameVersion_s { - gameVersion_s( void ) { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } - char string[256]; -} gameVersion; - -idCVar g_version( "g_version", gameVersion.string, CVAR_GAME | CVAR_ROM, "game version" ); - -/** -* DarkMod Cvars - see text description in declaration below for descriptions -**/ -idCVar cv_player_spawnclass( "tdm_player_spawnclass", "atdm:player_thief", CVAR_GAME, "The player's classname." ); -idCVar cv_player_waituntilready( "tdm_player_wait_until_ready", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 (default), the player must be ready before the map is started."); - -idCVar cv_default_mission_info_file("tdm_default_mission_info_file", "fms/missions.tdminfo", CVAR_GAME, "The filename relative to darkmod/fms/ where all the persistent mission data is stored." ); - -idCVar cv_ai_sndvol( "tdm_ai_sndvol", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifier to the volume of suspcious sounds that AI's hear. Defaults to 0.0 dB" ); -idCVar cv_ai_bark_show( "tdm_ai_showbark", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Displays the current sound when the AI starts barking" ); -idCVar cv_ai_sight_prob( "tdm_ai_sight_prob", "0.7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifies the AI's chance of seeing you. Small changes may have a large effect." ); -idCVar cv_ai_sight_mag( "tdm_ai_sight_mag", "1.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Modifies the amount of visual alert that gets added on when the sight probability check succeeds and the AI do see you (default 1.0)." ); -idCVar cv_ai_sightmaxdist( "tdm_ai_sightmax", "60.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The distance (in meters) above which an AI will not see you even with a fullbright lightgem. Defaults to 60m. Effects visibility in a complicated way." ); -idCVar cv_ai_sightmindist( "tdm_ai_sightmin", "11.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The distance (in meters) below which an AI has a 100% chance of seeing you with a fullbright lightgem. Defaults to 11m (~36 ft). Effects visibility in a complicated way." ); -idCVar cv_ai_tactalert( "tdm_ai_tact", "20.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The default tactile alert if an AI bumps an enemy or an enemy bumps an AI. Default value is 20 alert units (pretty much full alert)." ); -idCVar cv_ai_bumpobject_impulse( "tdm_ai_bumpobject_impulse", "250", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Impulse applied when an AI bumps into an object with its AF when animating. Different from the kick force it applies to an object blocking its path." ); // grayman #2568? - 1500->250 -idCVar cv_ai_debug( "tdm_ai_debug", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, AI alert events will be sent to the console for debugging purposes." ); -idCVar cv_ai_fov_show ( "tdm_ai_showfov", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, a debug graphic showing the field of vision of the AI will be drawn. Blue cone represents the vertical FOV, orange cone represents the horizontal."); -idCVar cv_ai_ko_show ( "tdm_ai_showko", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, a debug graphic showing the knockout region of the AI will be drawn. The green cone shows the vertical admittance angle, the red cone shows the horizontal angle."); -idCVar cv_ai_animstate_show ( "tdm_ai_showanimstate", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the name of the AI's current animation state will be shown."); -idCVar cv_ai_task_show ( "tdm_ai_showtasks", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the name of the AI's current tasks will be shown."); -idCVar cv_ai_alertlevel_show ( "tdm_ai_showalert", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug text showing the AI's current total alert units is shown (Note: This is not the alert state, use tdm_ai_showtasks for that)."); -idCVar cv_ai_dest_show ( "tdm_ai_showdest", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, an arrow is drawn from every AI to its intended pathing destination."); -idCVar cv_ai_goalpos_show ( "tdm_ai_showgoalpos", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the current goalpos (seekpos) is drawn in the world (!= move destination)."); -idCVar cv_ai_aasarea_show ( "tdm_ai_showAASarea", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the current AAS area of the AI is drawn in the world."); -idCVar cv_ai_debug_blocked ( "tdm_ai_debug_blocked", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, debug drawings of the movement subsystem are shown."); -idCVar cv_ai_door_show( "tdm_ai_showdoor", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the desired positions for opening and closing the door are shown."); -idCVar cv_ai_elevator_show( "tdm_ai_showelevator", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, the debug drawings for AI handling elevators are shown."); - -idCVar cv_ai_sight_thresh ( "tdm_ai_sight_thresh", "1.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the minimum light per-AI-frame gem generated visual stimulus amount required for an AI to be able to see the player or another entity directly when searching."); -idCVar cv_ai_sight_scale ( "tdm_ai_sight_scale", "1000.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the distance that is multiplied by the lightQuotient from the LAS and visual acuity of the AI scaled from 0 to 1, that indicates how far away the AI can be and see a location."); -idCVar cv_ai_show_enemy_visibility ("tdm_ai_show_enemy_visibility", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, the visibility of the AI's enemy is drawn (red = obscured or hidden in darkness, green = the opposite)."); -idCVar cv_ai_show_conversationstate("tdm_ai_show_conversationstate", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, the AI will draw debug output with regard to their conversation state."); - -idCVar cv_ai_acuity_L3 ( "tdm_ai_acuity_L3", "1.1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 3 but not yet 4"); -idCVar cv_ai_acuity_L4 ( "tdm_ai_acuity_L4", "1.3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 4 but not yet 5"); -idCVar cv_ai_acuity_L5 ( "tdm_ai_acuity_L5", "1.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is at alert level 5"); -idCVar cv_ai_acuity_susp( "tdm_ai_acuity_susp", "1.2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the amount by which the acutities of an AI is multiplied if the AI is suspicious due to evidence. It is in addition to the other modifiers."); - -idCVar cv_sndprop_disable( "tdm_sndprop_disable", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation will not be calculated." ); -idCVar cv_spr_debug( "tdm_spr_debug", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation debugging information will be sent to the console, and the log information will become more detailed." ); -idCVar cv_spr_show( "tdm_showsprop", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound propagation paths to nearby AI will be shown as lines. The volume of the sound heard by the AI and the alert increase will be displayed." ); -idCVar cv_spr_radius_show( "tdm_showsprop_radius", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, sound ranges are drawn." ); - -idCVar cv_ko_show( "tdm_showko", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to true, knockout zones will be shown for debugging." ); -idCVar cv_ai_search_show ( "tdm_ai_search_show", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If >= 1.0, this is the number of milliseconds for which a graphic showing search activity targets will be shown. If < 1.0 then the graphics will not be drawn. For debugging."); -idCVar cv_ai_visdist_show ( "tdm_ai_visdist_show", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If >= 1.0, this is the number of milliseconds for which a graphic showing vision distance test results. Green arrows indicate within range, Red indicate out of range, purple indicate gap between range and target. For debugging."); - -idCVar cv_ai_opt_disable ( "tdm_ai_opt_disable", "1", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs not in the Potentially Visible Set will be completely disabled if they have neverdormant set to 0."); -idCVar cv_ai_opt_noanims ( "tdm_ai_opt_noanims", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs will not animate."); -idCVar cv_ai_opt_novisualscan ( "tdm_ai_opt_novisualscan", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs not in the Potentially Visible Set will not look for enemies, not even enemy AIs."); -idCVar cv_ai_opt_forceopt ( "tdm_ai_opt_forceopt", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AIs will always be treated as being outside the PVS for the purposes of the other tdm_ai_opt_* spawnargs." ); -idCVar cv_ai_opt_nothink ( "tdm_ai_opt_nothink", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not perform their regular thinking routine (including Mind)." ); -idCVar cv_ai_opt_interleavethinkmindist ( "tdm_ai_opt_interleavethinkmindist", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If true (nonzero), the AI will start interleaved thinking if the distance to the player is greater than the set value." ); -idCVar cv_ai_opt_interleavethinkmaxdist ( "tdm_ai_opt_interleavethinkmaxdist", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If true (nonzero), this is the distance where interleave frame will reach its maximum value." ); -idCVar cv_ai_opt_interleavethinkskippvscheck ( "tdm_ai_opt_interleavethinkskipPVS", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If true (nonzero), the player PVS check for interleaved thinking will be skipped, so that the AI can also do interleaved thinking while in view." ); -idCVar cv_ai_opt_interleavethinkframes ( "tdm_ai_opt_interleavethinkframes", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "If true (nonzero), this is the maximum interleaved thinking frame number." ); -idCVar cv_ai_opt_update_enemypos_interleave ( "tdm_ai_opt_update_enemypos_interleave", "48", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time to pass between enemy position updates. Set this to 0 for updates each frame." ); - -idCVar cv_ai_opt_nomind ( "tdm_ai_opt_nomind", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI has its Mind thinking routines disabled." ); -idCVar cv_ai_opt_novisualstim ( "tdm_ai_opt_novisualstim", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not process any incoming visual stimuli." ); -idCVar cv_ai_opt_nolipsync ( "tdm_ai_opt_nolipsync", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not play lipsync animations." ); -idCVar cv_ai_opt_nopresent ( "tdm_ai_opt_nopresent", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not be presented." ); -idCVar cv_ai_opt_noobstacleavoidance ( "tdm_ai_opt_noobstacleavoidance", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), AI will not check for obstacles." ); -idCVar cv_ai_hiding_spot_max_light_quotient( "tdm_ai_hiding_spot_max_light_quotient", "2.0", CVAR_GAME | CVAR_FLOAT, "Hiding spot search light quotient." ); -idCVar cv_ai_max_hiding_spot_tests_per_frame( "tdm_ai_max_hiding_spot_tests_per_frame", "10", CVAR_GAME | CVAR_INTEGER, "This is the maximum number of hiding spot point tests to do in a single AI frame." ); - -idCVar cv_ai_debug_anims ( "tdm_ai_debug_anims", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), show debug info about AI anims in the console and log file." ); - -idCVar cv_show_health ( "tdm_show_health", "0", CVAR_ARCHIVE | CVAR_GAME | CVAR_BOOL, "If true (nonzero), show health of entities for debugging." ); - -idCVar cv_ai_show_aasfuncobstacle_state("tdm_ai_show_aasfuncobstacle_state", "0", CVAR_ARCHIVE | CVAR_GAME | CVAR_BOOL, "If true (nonzero), idFuncAASObstacles will show their state at spawn time and during changes." ); - -idCVar cv_interaction_vfp_type("tdm_interaction_vfp_type", "1", CVAR_ARCHIVE | CVAR_BOOL, "If 1, the new enhanced interaction are used. Set to 0 to use default interaction shader." ); -idCVar cv_tdm_widescreenmode("tdm_wideScreenMode", "0", CVAR_ARCHIVE | CVAR_INTEGER, "The widescreen mode selected in the main menu (for internal use)." ); -idCVar cv_tdm_menu_music("tdm_menu_music", "1", CVAR_ARCHIVE | CVAR_BOOL, "Whether to play background music in the main menu (for internal use)." ); - -idCVar cv_tdm_show_trainer_messages("tdm_show_trainer_messages", "1", CVAR_BOOL | CVAR_ARCHIVE, "Whether TDM trainer maps should display pop-ups with helpful gameplay information." ); - -idCVar cv_tdm_default_relations_def( "tdm_default_relations_def", "atdm:team_relations_default", CVAR_GAME | CVAR_ARCHIVE, "The name of the entityDef holding the TDM default team relationships." ); - -/** -* DarkMod GUI CVARs -**/ -// Tels: can be removed when D3 is open source and we can access sys_lang properly -idCVar cv_tdm_lang("tdm_lang", "english", CVAR_GUI | CVAR_ARCHIVE, "The current used language. Possible values are 'english', 'german', 'russian' etc." ); - -idCVar cv_tdm_fm_path( "tdm_fm_path", "fms/", CVAR_GUI, "(internal) The path where the fan mission packages are stored."); -idCVar cv_tdm_fm_desc_file( "tdm_fm_desc_file", "darkmod.txt", CVAR_GUI, "(internal) The description file name of FM packages."); -idCVar cv_tdm_fm_notes_file( "tdm_fm_notes_file", "readme.txt", CVAR_GUI, "(internal) The readme file name of FM packages."); -idCVar cv_tdm_fm_current_file( "tdm_fm_current_file", "currentfm.txt", CVAR_GUI, "(internal) The file where the name of the currently installed FM is stored."); -idCVar cv_tdm_fm_startingmap_file( "tdm_fm_startingmap_file", "startingmap.txt", CVAR_GUI, "(internal) The file where the name of the starting map of an FM is stored."); -idCVar cv_tdm_fm_mapsequence_file( "tdm_fm_mapsequence_file", "tdm_mapsequence.txt", CVAR_GUI, "(internal) The file where the sequence of the map files is stored."); -idCVar cv_tdm_fm_splashimage_file( "tdm_fm_splashimage_file", "install_splash.tga", CVAR_GUI, "(internal) The file to be used as splash screen for the installation GUI."); -idCVar cv_tdm_fm_sync_config_files("tdm_fm_sync_config_files", "1", CVAR_BOOL | CVAR_ARCHIVE, "If true (1) the FM loader will sync DoomConfig.cfg files from the darkmod folder to the FM directory and back."); -idCVar cv_tdm_fm_restart_delay("tdm_fm_restart_delay", "0", CVAR_ARCHIVE | CVAR_INTEGER, "If non-zero, this is the timespan in milliseconds to wait between D3 restarts (to let the previous D3 process fully release all resources)." ); - -/** -* DarkMod HTTP related CVARs -**/ -idCVar cv_tdm_proxy("tdm_proxy", "", CVAR_ARCHIVE, "The proxy to use when connecting to the internet, format: hostname:port" ); -idCVar cv_tdm_proxy_user("tdm_proxy_user", "", CVAR_ARCHIVE, "The proxy user to use when connecting to the internet via proxy." ); -idCVar cv_tdm_proxy_pass("tdm_proxy_pass", "", CVAR_ARCHIVE, "The proxy password to use when connecting to the internet via proxy." ); -idCVar cv_tdm_allow_http_access("tdm_allow_http_access", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If true (nonzero), TDM is allowed to send HTTP request to the TDM servers to check for updates, missions, etc. Setting this to false disables all web functionality." ); -idCVar cv_tdm_mission_list_urls("tdm_mission_list_urls", "http://www.thedarkmod.com/missiondb/get_available_missions.php;http://www.thedarkmod.com/missiondb/available_missions.xml", CVAR_GAME, "The URLs to check for the mission list XML." ); -idCVar cv_tdm_mission_details_url("tdm_mission_details_url", "http://www.thedarkmod.com/missiondb/get_mission_details.php?id=%d", CVAR_GAME, "The URLs to check for the mission details XML." ); -idCVar cv_tdm_mission_screenshot_url("tdm_mission_screenshot_url", "http://www.thedarkmod.com/%s", CVAR_GAME, "The URL template to download the mission screenshots." ); -idCVar cv_tdm_version_check_url("tdm_version_check_url", "http://www.thedarkmod.com/update/tdm_version.xml", CVAR_GAME, "The URL to check for the current TDM version." ); - -/** -* DarkMod DEBUG related CVARs -**/ -idCVar cv_tdm_http_base_url( "tdm_http_base_url", "", CVAR_GAME, "If set, this URL will be used instead of the actual download URL when downloading FMs. Useful for testing downloading FMs from temp. servers." ); - -idCVar cv_debug_aastype( "tdm_debug_aastype", "aas32", CVAR_GAME | CVAR_ARCHIVE, "Sets the AAS type used for visualisation with impulse 27"); - -idCVar cv_las_showtraces( "tdm_las_showtraces", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), traces from light origin to testpoints used for visibility testiung are drawn." ); - -idCVar cv_show_gameplay_time( "tdm_show_gameplaytime", "0", CVAR_GAME | CVAR_BOOL, "If true (nonzero), the gameplay time is shown in the player HUD." ); - -idCVar cv_tdm_difficulty( "tdm_difficulty", "-1", CVAR_GAME | CVAR_INTEGER, "Set this to 0, 1 or 2 to override the difficulty setting of any map (for testing purposes). Set this back to -1 to disable the setting (which is the default). This setting isn't saved between session." ); - -idCVar cv_sr_disable ( "tdm_sr_disable", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to disable all stim/response processing." ); -idCVar cv_sr_show( "tdm_show_stimresponse", "0", CVAR_GAME | CVAR_INTEGER, "Set to 1 to show all successful stims, set to 2 to show all including failed ones." ); - -idCVar cv_debug_mainmenu( "tdm_debug_mainmenu", "0", CVAR_BOOL, "Set to 1 to enable main menu GUI debugging in the console." ); -idCVar cv_mainmenu_confirmquit( "tdm_mainmenu_confirmquit", "1", CVAR_ARCHIVE | CVAR_BOOL, "Set to 0 to disable the 'Quit Game' confirmation dialog when exiting the game." ); - -idCVar cv_force_savegame_load( "tdm_force_savegame_load", "0", CVAR_BOOL|CVAR_ARCHIVE, "Set to 1 to skip code revision check on savegame load." ); -idCVar cv_savegame_compress( "tdm_savegame_compress", "1", CVAR_BOOL|CVAR_ARCHIVE, "Set to 0 to disable savegame file compression." ); - -idCVar cv_screenshot_format( "tdm_screenshot_format", "jpg", CVAR_ARCHIVE, "Image format used to store ingame screenshots: png/tga/jpg/bmp." ); -/** -* Dark Mod player movement -* Use multipliers instead of setting a speed for each -**/ -idCVar cv_pm_runmod( "pm_runmod", "2.12", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain run speed from pm_walkspeed." ); -idCVar cv_pm_run_backmod( "pm_run_backmod", "0.7", CVAR_GAME | CVAR_FLOAT , "The multiplier applied to existing run speed when the player is running backwards." ); -idCVar cv_pm_creepmod( "pm_creepmod", "0.44", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain creep speed from pm_walkspeed." ); -idCVar cv_pm_crouchmod( "pm_crouchmod", "0.54", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The multiplier used to obtain crouch speed from walk speed." ); -idCVar cv_pm_max_swimspeed_mod( "pm_max_swimspeed_mod", "1.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum speed of the player when moving in >= waist deep water, relative to player walkspeed." ); -idCVar cv_pm_pushmod( "pm_pushmod", "0.15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Alters the impulse applied when the player runs into an object. Fractional modifier that multiplies the default D3 impulse. ONLY APPLIES TO OBJECTS BEING KICKED. Default is 0.15" ); -idCVar cv_pm_push_maximpulse( "pm_push_maximpulse", "300", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the maximum impulse that is allowed to be propagated by the player to moveables just by kicking them. Only applies for 'lightweight' moveables below playermass*pm_push_heavy_threshold. Default is 300 units*kg per second." ); -idCVar cv_pm_push_start_delay( "pm_push_start_delay", "1000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the delay in msecs before heavy things get pushed by the player. Default is 1000 msecs." ); -idCVar cv_pm_push_accel_time( "pm_push_accel_time", "1000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the acceleration time in msecs when the player is starting to push things. After this time has passed, the pushed object has reached its maximum possible velocity. Default is 1000 msecs." ); -idCVar cv_pm_push_heavy_threshold( "pm_push_heavy_threshold", "0.15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the fraction of the player mass, above which pushable things are considered as 'heavy'. Default is 0.75." ); -idCVar cv_pm_push_max_mass( "pm_push_max_mass", "200", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Defines the maximum mass in kg a moveable can have to be pushable at all. Default is 200 kg."); - -idCVar cv_pm_weightmod( "pm_weightmod", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Gets multiplied to the force applied to objects below the player model. Defaults to 1." ); - -idCVar cv_pm_mantle_reach( "pm_mantle_reach", "0.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Horizontal reach of mantle ability, as fraction of player height. Default is 0.5" ); -idCVar cv_pm_mantle_height( "pm_mantle_height", "0.2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Vertical reach of mantle ability, as fraction of player height. Default is 0.2" ); -idCVar cv_pm_mantle_minflatness( "pm_mantle_minflatness", "0.707", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Cannot mantle on top of surfaces whose angle's cosine is smaller than this value. e.g. >1.0 means nothing can be mantled; 1.0 means only perfectly flat floors (0 degrees) can be mantled on top of; ~0.707 means no surfaces steeper than 45 degrees can be mantled on top of; 0.5 means no surfaces steeper than 60 degrees can be mantled on top of; a large negative value (like -10) means all surfaces can be mantled regardless of steepness. Default is 0.707." ); - -idCVar cv_pm_mantle_jump_hold_trigger( "pm_mantle_jump_hold_trigger", "100", CVAR_GAME | CVAR_INTEGER , "Default length of time for holding down jump key to start mantling." ); -idCVar cv_pm_mantle_min_velocity_for_damage( "pm_mantle_min_velocity_for_damage", "15", CVAR_GAME | CVAR_FLOAT , "Default damage scale for mantling at high velocities." ); -idCVar cv_pm_mantle_damage_per_velocity_over_minimum( "pm_mantle_damage_per_velocity_over_minimum", "0.5", CVAR_GAME | CVAR_FLOAT , "The meters per second of relative velocity beyond which the player takes damage when trying to mantle a target." ); -idCVar cv_pm_mantle_hang_msecs( "pm_mantle_hang_msecs", "750", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time that player hangs if mantle begins with the player's feet of the ground." ); -idCVar cv_pm_mantle_pull_msecs( "pm_mantle_pull_msecs", "750", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to pull themselves up to shoulder level with the mantle surface." ); -idCVar cv_pm_mantle_shift_hands_msecs( "pm_mantle_shift_hands_msecs", "500", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to shift their hands from pulling to pushing." ); -idCVar cv_pm_mantle_push_msecs( "pm_mantle_push_msecs", "800", CVAR_GAME | CVAR_INTEGER , "Milliseconds of time it takes for the player to push themselves up onto the mantle surface." ); - -/** -* Dark Mod Jumping -**/ -idCVar cv_tdm_walk_jump_vel( "tdm_walk_jump_vel", "2.2", CVAR_FLOAT, "Jump velocity multiplier when walking" ); -idCVar cv_tdm_run_jump_vel( "tdm_run_jump_vel", "2.5", CVAR_FLOAT, "Jump velocity multiplier when running" ); -idCVar cv_tdm_crouch_jump_vel( "tdm_crouch_jump_vel", "0.5", CVAR_FLOAT, "Jump velocity multiplier when crouching" ); -idCVar cv_tdm_min_vel_jump( "tdm_min_vel_jump", "0.0", CVAR_FLOAT, "The minimum speed before cv_tdm_run_jump_vel is used" ); -idCVar cv_tdm_fwd_jump_vel( "tdm_fwd_jump_vel", "50.0", CVAR_FLOAT, "Forward vector multiple for jumping" ); -idCVar cv_tdm_backwards_jump_modifier( "tdm_back_jump_factor", "0.5", CVAR_FLOAT, "Backwards multiplier for jumping, relative to forward jumping. A factor of 1 means that the player gains as much speed through backwards jumping as through forward jumping." ); -idCVar cv_tdm_jump_relaxation_time( "tdm_jump_relaxation_time", "4", CVAR_FLOAT, "Time in seconds needed to regain full jump strength again." ); - -idCVar cv_tdm_footfalls_movetype_specific( "tdm_footfall_sounds_movetype_specific", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to use move-type dependent foot fall sounds." ); - -// Dark Mod crouching -idCVar cv_tdm_crouch_toggle( "tdm_toggle_crouch", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make crouching toggleable." ); -idCVar cv_tdm_crouch_toggle_hold_time( "tdm_crouch_toggle_hold_time", "400", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The time to hold crouch while on a rope/ladder for starting to slide down." ); -idCVar cv_tdm_reattach_delay( "tdm_reattach_delay", "100", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Delay (in ms) for reattaching to ropes/ladders after detaching using crouch." ); - - -/** -* Dark Mod Leaning -**/ -idCVar cv_pm_lean_angle( "pm_lean_angle", "15.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The tilt angle that the player can lean to at a full lean, in degrees." ); -idCVar cv_pm_lean_time( "pm_lean_time", "400.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Time it takes to get to a full lean, in milliseconds." ); -idCVar cv_pm_lean_height( "pm_lean_height", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Height of the fulcrum about which the player leans, as a fraction of the player's eye height." ); -idCVar cv_pm_lean_stretch( "pm_lean_stretch", "2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The amount the player stretches out at a full lean, written as a fraction of the player's un-stretched height." ); -idCVar cv_pm_lean_forward_angle( "pm_lean_forward_angle", "2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: The tilt angle that the player can lean to at a full lean, in degrees." ); -idCVar cv_pm_lean_forward_time( "pm_lean_forward_time", "400.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: Time it takes to get to a full lean, in milliseconds." ); -idCVar cv_pm_lean_forward_height( "pm_lean_forward_height", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: Height of the fulcrum about which the player leans, as a fraction of the player's eye height." ); -idCVar cv_pm_lean_forward_stretch( "pm_lean_forward_stretch", "15", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Forward lean: The amount the player stretches out at a full lean, written as a fraction of the player's un-stretched height." ); -idCVar cv_pm_lean_to_valid_increments( "pm_lean_to_valid_increments", "25", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Integer number of increments used for testing when leaning back to a valid position after a leaned clipping problem. The higher the number, the smoother the un-lean will feel, but the higher the computation time." ); -idCVar cv_pm_lean_door_increments( "pm_lean_door_increments", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Integer number of increments used for testing when extending a lean through a door acoustically." ); -idCVar cv_pm_lean_door_max( "pm_lean_door_max", "40", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Max distance of door that may be listened through at normal incidence, in doom units." ); -idCVar cv_pm_lean_door_bounds_exp( "pm_lean_door_bounds_exp", "8.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Amount to expand the camera view bounds by when testing if the player is still pressed against a door for listening purposes (default 8.0)."); -idCVar cv_pm_lean_toggle( "pm_lean_toggle", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make leaning toggleable." ); - -/** -* Dark Mod Frobbing -* Frob expansion radius for easier frobbing, time it takes for frob highlight to fade in and out -**/ -idCVar cv_frob_distance_default( "tdm_frob_distance_default", "63", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Default frob distance for all items in doom units. For developer use only, will break game if set wrong! Default is 63."); -idCVar cv_frob_width( "tdm_frob_width", "10.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "When frobbing, a cube of this dimension is created at the point the frob hit, and things within are frob candidates. Makes frobbing easier but can go thru solid objects if set too high. Default is 10."); -idCVar cv_frob_fadetime( "tdm_frob_fadetime", "100", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time it takes for frob highlight effect to fade in and out." ); -idCVar cv_frob_debug_bounds( "tdm_frob_debug_bounds", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to see a visualization of the bounds that are used to check for frobable items within them." ); -idCVar cv_frob_weapon_selects_weapon( "tdm_frob_weapon_selects_weapon", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to have weapons automatically selected when the respective item is picked up." ); -idCVar cv_frob_debug_hud( "tdm_frob_debug_hud", "0", CVAR_GAME | CVAR_BOOL, "Set to 1 to show some frobbing info." ); - -/** -* Dark Mod Misc. Control Options -**/ -idCVar cv_weapon_next_on_empty( "tdm_weapon_next_on_empty", "0", CVAR_GAME | CVAR_BOOL, "If set to 1, when you run out of a particular type of arrows, you will auto-switch to the next available weapon. (This can get you in trouble if it switches to a fire arrow)." ); - -/** -* Physics -**/ -idCVar cv_collision_damage_scale_vert( "tdm_collision_damage_scale_vert", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This globally scales the damage AI take from vertical collisions/decelerations. This multiplies delta-velocity squared." ); -idCVar cv_collision_damage_scale_horiz( "tdm_collision_damage_scale_horiz", "0.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This globally scales the damage AI take from horizontal collisions/decelerations. This multiplies delta-velocity squared." ); -idCVar cv_drag_limit_force( "tdm_drag_limit_force", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Cheat: Set to 0 to disable finite acceleration while grabbing objects." ); -idCVar cv_drag_force_max( "tdm_drag_force_max", "100000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum force the player can apply to a dragged object [kg * doom units / second^2]" ); -idCVar cv_drag_stuck_dist( "tdm_drag_stuck_dist", "38.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Distance from the grab point at which object is determined to be 'stuck' and possibly auto-dropped." ); -idCVar cv_drag_damping( "tdm_drag_damping", "0.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Damping applied to objects being grabbed by the player" ); -idCVar cv_drag_damping_AF( "tdm_drag_damping_af", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Damping applied to ragdolls being grabbed by the player" ); -idCVar cv_drag_AF_ground_timer( "tdm_drag_af_ground_timer", "800", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Time in milliseconds that it takes to ramp up to full vertical velocity after a ground-restricted body has come back to ground contact." ); -idCVar cv_drag_AF_free( "tdm_drag_af_free", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "This is a cheat that allows lifting all AI bodies completely off the ground when dragging them. Useful for mappers who want to set up ragdolls ingame." ); -idCVar cv_drag_jump_masslimit( "tdm_drag_jump_masslimit", "20", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "When the player is holding something above this mass, jumping becomes impossible." ); -idCVar cv_drag_encumber_minmass( "tdm_drag_encumber_minmass", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Minimum carried mass that starts to effect movement speed." ); -idCVar cv_drag_encumber_maxmass( "tdm_drag_encumber_maxmass", "55", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Carried mass at which movement speed clamps to the lowest value." ); -idCVar cv_drag_encumber_max( "tdm_drag_encumber_max", "0.4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum encumbrance when carrying heavy things (expressed as a fraction of maximum unencumbered movement speed)." ); -idCVar cv_dragged_item_highlight( "tdm_dragged_item_highlight", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set this to 1 (=TRUE) if the grabbed item should always be highlighted." ); -idCVar cv_drag_debug( "tdm_drag_debug", "0", CVAR_GAME | CVAR_BOOL, "Shows debug arrows for desired velocity and contact plane normals when moving objects with the grabber." ); - -idCVar cv_melee_debug( "tdm_melee_debug", "0", CVAR_GAME | CVAR_BOOL, "Enable to show debug melee combat graphics." ); -idCVar cv_melee_state_debug( "tdm_melee_debug_state", "0", CVAR_GAME | CVAR_BOOL, "Enable to display debug text representing AI melee status." ); -// ishtvan: Renamed these with a _ after the name to force their new default settings to take effect in release 1.01 -idCVar cv_melee_mouse_thresh( "tdm_melee_mouse_thresh_", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "In manual control mode, sets the mouse movement threshold needed to decide on which attack/parry to make" ); -idCVar cv_melee_mouse_decision_time( "tdm_melee_mouse_decision_time_", "100", CVAR_GAME | CVAR_INTEGER, "In manual control mode, holding the button for this many milliseconds, an attack/parry decision is made based on mouse motion, even if it is below threshold mouse motion." ); -idCVar cv_melee_mouse_dead_time( "tdm_melee_mouse_dead_time_", "120", CVAR_GAME | CVAR_INTEGER, "Controls how long after the button press that mouse motion is damped by the fraction in tdm_mouse_slowview. In milliseconds." ); -idCVar cv_melee_mouse_slowview( "tdm_melee_mouse_slowview_", "0.0", CVAR_GAME | CVAR_FLOAT, "In manual control mode, when attack/parry button is held down, the view turn rate is decreased to this fraction while the mouse motion is determining which attack/parry to make." ); -idCVar cv_melee_invert_attack( "tdm_melee_invert_attack", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, mouse motions are inverted when controlling which attack to make." ); -idCVar cv_melee_invert_parry( "tdm_melee_invert_parry", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, mouse motions are inverted when controlling which parry to make." ); -idCVar cv_melee_auto_parry( "tdm_melee_auto_parry", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, melee parries are chosen automatically to match the enemy's attack (manual parry mode is much harder)." ); -idCVar cv_melee_forbid_auto_parry( "tdm_melee_forbid_auto_parry", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1, auto parry is forced to be off. Only manual allowed. Works in conjunction with the main menu, do not adjust by hand." ); -idCVar cv_melee_max_particles( "tdm_melee_max_particles", "10", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Max number of particles a single melee swing can generate (eye candy setting)." ); -idCVar cv_melee_difficulty( "tdm_melee_difficulty", "normal", CVAR_GAME | CVAR_ARCHIVE, "Melee difficulty as set by the menu (Do not adjust ingame, cheater!!)" ); - -idCVar cv_phys_show_momentum( "tdm_phys_show_momentum", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set this to 1 (=TRUE) to draw the linear impulse of (some) entities." ); - -/** -* DarkMod Item Manipulation -* Throw_min and throw_max are the min and max impulses applied to items thrown -**/ -idCVar cv_throw_min( "tdm_throw_min", "600", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Minimum impulse applied to a thrown object." ); -idCVar cv_throw_max( "tdm_throw_max", "3500", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Maximum impulse applied to a thrown object." ); -idCVar cv_throw_time( "tdm_throw_time", "1200", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "When throwing an object, time it takes to charge up to the max throw force in milliseconds." ); -idCVar cv_throw_max_vel( "tdm_throw_max_vel", "900", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Velocity of thrown objects is clamped to this value (in doomunits / second). Needed to balance throwing of very light objects." ); - -idCVar cv_bounce_sound_max_vel( "tdm_bounce_sound_max_vel", "400", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "At this velocity moveable collision sounds reach their maximum volume." ); -idCVar cv_bounce_sound_min_vel( "tdm_bounce_sound_min_vel", "80", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "This is the minimum velocity at which moveable collision sounds can be heard at all." ); - - -idCVar cv_reverse_grab_control( "tdm_grabber_reverse_control", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "Set to 1 to reverse the direction when using next/prev weapon to increase/decrease the distance of the grabbed item." ); - -/** -* DarkMod Inventory -**/ -idCVar cv_tdm_inv_gui_file( "tdm_inv_hud_file", "guis/tdm_inv.gui", CVAR_GAME, "The name of the gui file that represents the hud for the inventory."); -idCVar cv_tdm_inv_loot_item_def("tdm_inv_loot_item_def", "atdm:inv_loot_info_item", CVAR_GAME, "The name of the entityDef that defines the player's inventory loot item."); - -idCVar cv_tdm_obj_gui_file( "tdm_obj_hud_file", "guis/tdm_objectives.gui", CVAR_GAME, "The name of the gui file that defines the in-game objectives."); -idCVar cv_tdm_waituntilready_gui_file( "tdm_waituntilready_gui_file", "guis/tdm_waituntilready.gui", CVAR_GAME, "The name of the gui file that is displayed after loading a map and before starting the gameplay action."); - -idCVar cv_tdm_hud_opacity( "tdm_hud_opacity", "0.7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The opacity of the HUD GUIs. [0..1]", 0, 1 ); -idCVar cv_tdm_hud_hide_lightgem( "tdm_hud_hide_lightgem", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If set to true (=1), the lightgem will be hidden.", 0, 1 ); -idCVar cv_tdm_inv_hud_pickupmessages( "tdm_inv_hud_pickupmessages", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "If set to 1, the HUD is displaying the item the player has just picked up."); -idCVar cv_tdm_inv_loot_sound("tdm_inv_loot_sound", "frob_loot", CVAR_GAME | CVAR_ARCHIVE, "The name of the sound that is to be played when loot has been acquired."); -idCVar cv_tdm_inv_use_on_frob("tdm_inv_use_on_frob", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "When set to '1' currently selected inventory items will be used on frob."); -idCVar cv_tdm_door_control("tdm_door_control", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Acivates experimental door control. When active, hold down frob and move mouse to fine-control a door."); -idCVar cv_tdm_door_control_sensitivity( "tdm_door_control_sensitivity", "0.01", CVAR_GAME | CVAR_FLOAT, "Sets fine door control mouse sensitivity." ); -idCVar cv_tdm_inv_use_visual_feedback("tdm_inv_use_visual_feedback", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "When set to '1' the HUD is giving visual feedback when the currently selected item is used on the highlighted one."); - - -idCVar cv_tdm_rope_pull_force_factor("tdm_rope_pull_force_factor", "140", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The factor by which the pulling force when jumping on a rope gets multiplied."); - -idCVar cv_tdm_underwater_blur("tdm_underwater_blur", "3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The strength of the blur effect when the player is underwater."); - -/** -* DarkMod movement volumes. Walking volume is zero dB, other volumes are added to that -**/ -idCVar cv_pm_stepvol_walk( "pm_stepvol_walk", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for walking footsteps (should be 0.0)" ); -idCVar cv_pm_stepvol_run( "pm_stepvol_run", "8", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible modifier for running footsteps." ); -idCVar cv_pm_stepvol_creep( "pm_stepvol_creep", "-5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible modifier for creeping footsteps." ); - -idCVar cv_pm_stepvol_crouch_walk( "pm_stepvol_crouch_walk", "-2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch walking footsteps" ); -idCVar cv_pm_stepvol_crouch_run( "pm_stepvol_crouch_run", "4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch running footsteps" ); -idCVar cv_pm_stepvol_crouch_creep( "pm_stepvol_crouch_creep", "-7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Audible volume modifier for crouch creeping footsteps" ); -idCVar cv_pm_min_stepsound_interval("pm_min_stepsound_interval", "200", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The minimum time in msec which has to pass before the next player footstep sound is allowed to be played." ); -idCVar cv_pm_rope_snd_rep_dist( "pm_rope_snd_rep_dist", "32", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "When climbing a rope, this sets the vertical distance in doomunits between repeats of the rope climbing sound (default 32 [du])." ); -idCVar cv_pm_rope_velocity_letgo( "pm_rope_velocity_letgo", "100", CVAR_GAME | CVAR_FLOAT, "Maximum allowed velocity of the rope before the player lets go." ); -idCVar cv_pm_rope_swing_impulse( "pm_rope_swing_impulse", "360000", CVAR_GAME | CVAR_FLOAT, "Impulse applied to rope when the player 'kicks their legs' to swing on the rope. (Warning: Setting too high can damage player)" ); -idCVar cv_pm_rope_swing_reptime( "pm_rope_swing_reptime", "500", CVAR_GAME | CVAR_INTEGER, "How often you can kick to swing on the rope, in milliseconds." ); -idCVar cv_pm_rope_swing_kickdist( "pm_rope_swing_kickdist", "36", CVAR_GAME | CVAR_FLOAT, "When kicking on a rope, check this far ahead of the player's anchor point in the kick direction, to see if they are kicking off of something." ); -idCVar cv_pm_water_downwards_velocity( "pm_water_downwards_velocity", "-4", CVAR_GAME | CVAR_FLOAT, "The factor which the gravity vector gets scaled with to calculate the standard downwards velocity in water volumes. Negative values will let the player float upwards." ); -idCVar cv_pm_water_z_friction( "pm_water_z_friction", "0.995", CVAR_GAME | CVAR_FLOAT , "When the player is underwater and has really small z-velocities, this factor gets applied each frame, so that the player stops floating upwards when reaching the surface." ); -idCVar cv_pm_show_waterlevel( "pm_show_waterlevel", "0", CVAR_GAME | CVAR_BOOL , "Shows the waterlevel of the player." ); -idCVar cv_pm_climb_distance( "pm_climb_distance", "10", CVAR_GAME | CVAR_FLOAT , "How far away the edge of the player clipbox is from climbed surfaces (e.g. ladders)" ); - -/** - * Darkmod lightgem variables. These are only for debuggingpurpose to tweak the lightgem - * in a release version they should be disabled. - */ -idCVar cv_lg_distance("tdm_lg_distance", "0", CVAR_GAME | CVAR_FLOAT, "Sets the distance for camera of the lightgem testmodel." ); -idCVar cv_lg_xoffs("tdm_lg_xoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the x adjustment value for the camera on the testmodel" ); -idCVar cv_lg_yoffs("tdm_lg_yoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the y adjustment value for the camera on the testmodel" ); -idCVar cv_lg_zoffs("tdm_lg_zoffs", "17", CVAR_GAME | CVAR_FLOAT, "Sets the z adjustment value for the camera on the testmodel" ); -idCVar cv_lg_oxoffs("tdm_lg_oxoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the x adjustment value for the testmodels object position" ); -idCVar cv_lg_oyoffs("tdm_lg_oyoffs", "0", CVAR_GAME | CVAR_FLOAT, "Sets the y adjustment value for the testmodels object position" ); -idCVar cv_lg_ozoffs("tdm_lg_ozoffs", "-20", CVAR_GAME | CVAR_FLOAT, "Sets the z adjustment value for the testmodels object position" ); -idCVar cv_lg_fov("tdm_lg_fov", "70", CVAR_GAME | CVAR_INTEGER, "Sets the y value for the field of view on the lightgem testmodel." ); -idCVar cv_lg_interleave("tdm_lg_interleave", "1", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "If set to 0 no lightgem processing is done. Any other values determines how often the lightgem should be processed.\n1 (default) means to process every frame." ); -idCVar cv_lg_hud("tdm_lg_hud", "0", CVAR_GAME | CVAR_INTEGER, "Shows the rendersnaphost n = <1..6> of the lightgem on-screen. If 0 none is shown." ); -idCVar cv_lg_weak("tdm_lg_weak", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Switches to the weaker algorithm, but may be faster." ); - -idCVar cv_lg_player("tdm_lg_player", "0", CVAR_GAME | CVAR_BOOL, "Shows the lightem testmodel in the gamescreen if set to 1." ); -idCVar cv_lg_renderpasses("tdm_lg_renderpasses", "2", CVAR_GAME | CVAR_INTEGER, "Set number of renderpasses used for the lightgem calculation (1..2)" ); -idCVar cv_lg_debug("tdm_lg_debug", "0", CVAR_GAME | CVAR_BOOL, "switch on debug prints." ); -idCVar cv_lg_model("tdm_lg_model", "models/darkmod/misc/system/lightgem.lwo", CVAR_GAME | CVAR_ARCHIVE, "Set the lightgem model file. Map has to be restarted to take effect." ); -idCVar cv_lg_adjust("tdm_lg_adjust", "0", CVAR_GAME | CVAR_FLOAT, "Adds a constant value to the lightgem." ); -idCVar cv_lg_split("tdm_lg_split", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Lightgem is always fully calculated (no splitting between interleaves). Warning! This can cause particle flickering if set to 1." ); -idCVar cv_lg_path("tdm_lg_path", "", CVAR_GAME, "Dump the rendersnapshot to the filepath specified here." ); -idCVar cv_lg_crouch_modifier("tdm_lg_crouch_modifier", "-2", CVAR_GAME | CVAR_INTEGER, "The value the lightgem is adjusted by when the player is crouching." ); -idCVar cv_lg_image_width("tdm_lg_image_width", "64", CVAR_GAME | CVAR_INTEGER, "Defines the pixel width of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); -idCVar cv_lg_screen_width("tdm_lg_screen_width", "640", CVAR_GAME | CVAR_INTEGER, "Defines the screen width of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); -idCVar cv_lg_screen_height("tdm_lg_screen_height", "480", CVAR_GAME | CVAR_INTEGER, "Defines the screen height of the lightem rendering. WARNING!!! Increasing this severly affects performance!" ); -idCVar cv_lg_velocity_mod_min_velocity("tdm_lg_velocity_mod_min_velocity", "0", CVAR_GAME | CVAR_FLOAT, "The minimum velocity the player must be at to make the lightgem level increase."); -idCVar cv_lg_velocity_mod_max_velocity("tdm_lg_velocity_mod_max_velocity", "300", CVAR_GAME | CVAR_FLOAT, "The maximum player speed taken into account for the lightgem."); -idCVar cv_lg_velocity_mod_amount("tdm_lg_velocity_mod_amount", "1", CVAR_GAME | CVAR_FLOAT, "The maximum light level increase factor due to player velocity (this will be multiplied when the player velocity is >= tdm_lg_player_velocity_mod_max)."); - -idCVar cv_lg_fade_delay ("tdm_lg_fade_delay", "0.09", CVAR_GAME | CVAR_FLOAT, "lightgem fade time from previous value to new value in seconds." ); // J.C.Denton - -idCVar cv_empty_model("tdm_empty_model", "models/darkmod/misc/system/empty.lwo", CVAR_GAME | CVAR_ARCHIVE, "The empty model referenced by the 'waitForRender' script event."); - -// Proxy CVARs -idCVar cv_tdm_s_doorDistanceAdd("tdm_s_doorDistanceAdd", "450", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite s_doorDistanceAdd at game startup."); -idCVar cv_tdm_gui_smallFontLimit("tdm_gui_smallFontLimit", "0.15", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite gui_smallFontLimit at game startup."); -idCVar cv_tdm_gui_mediumFontLimit("tdm_gui_mediumFontLimit", "0.30", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite gui_mediumFontLimit at game startup."); -idCVar cv_tdm_s_maxSoundsPerShader("tdm_s_maxSoundsPerShader", "0", CVAR_GAME | CVAR_ARCHIVE, "This value will overwrite s_maxSoundsPerShader at game startup (unless this set to -1)."); - -/** - * Variables needed for lockpicking. - */ -idCVar cv_lp_pin_base_count("tdm_lp_base_count", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Base number of clicks per pin. This number will be added to the pinpattern." ); -idCVar cv_lp_sample_delay("tdm_lp_sample_delay", "10", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Time in ms added to each pin sample to create a small pause between each pinsample." ); -idCVar cv_lp_pick_timeout("tdm_lp_pick_timeout", "500", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Timeout that defines the maximum reaction time before the pin is to be considered unpicked and started over." ); -idCVar cv_lp_max_pick_attempts("tdm_lp_autopick_attempts", "3", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "How many pick attemps before it automatically gets picked? 0 = unlimited (you must solve it yourself)" ); -idCVar cv_lp_auto_pick("tdm_lp_auto_pick", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Determines if auto picking is enabled (see tdm_lp_max_pick_attempts)" ); -idCVar cv_lp_randomize("tdm_lp_randomize", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1, the jiggling, while lockpicking, will be randomized, otherwise it is linear." ); -idCVar cv_lp_pawlow("tdm_lp_pawlow", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 the sweetspot sound will play at the end of the pattern instead of at the beginning. Thus making it into a reaction game." ); -idCVar cv_lp_debug_hud("tdm_lp_debug_hud", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 the lockpicking debug HUD is shown during lockpicking." ); - -/** - * Variable for bow aimer. -- Dram - */ -idCVar cv_bow_aimer("tdm_bow_aimer", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Whether the bow has an aimer. 0 = False, 1 = True." ); - -idCVar cv_door_auto_open_on_unlock("tdm_door_auto_open_on_unlock", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "If set to 1 doors and chests will start to open after being unlocked." ); - -idCVar cv_dm_distance("tdm_distance", "", CVAR_GAME, "Shows the distance from the player to the entity" ); - -/** - * Ambient light method variable - */ -idCVar cv_ambient_method("tdm_ambient_method", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "Method used for ambient light rendering.\n\n0 = Ambient Light method (uses the ambient light for the ambient brightness) \n1 = Texture Brightness method (uses texture brightness instead of light. This is faster but looks worse)" ); - -/** - * Volume of speakers with s_music set - */ -idCVar cv_music_volume("tdm_music_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for speakers with s_music set. Goes from -40 to 0." ); - -// Tels: -idCVar cv_voice_player_volume("tdm_voice_player_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for the player voice speaker. Goes from 0 .. 60." ); -idCVar cv_voice_from_off_volume("tdm_voice_from_off_volume", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "Volume in dB for the voice-over speaker. Goes from 0 .. 60." ); - -idCVar cv_moveable_collision("tdm_show_moveable_collision", "0", CVAR_GAME | CVAR_BOOL, "If set to 1, shows the velocity at which the moveable collides and the volume of the resulting sound." ); - -/** -* DarkMod LOD system -**/ -idCVar cv_lod_bias("tdm_lod_bias", "1.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "A factor to multiply the LOD (level of detail) distance with. Default is 1.0 (meaning no change). Values < 1.0 make the distances smaller, reducing detail and increasing framerate, values > 1 increase the distance and thus detail at the expense of framerate." ); - -/** -* End DarkMod cvars -**/ - -// noset vars -idCVar gamename( "gamename", GAME_VERSION, CVAR_GAME | CVAR_SERVERINFO | CVAR_ROM, "" ); -idCVar gamedate( "gamedate", __DATE__, CVAR_GAME | CVAR_ROM, "" ); - -// server info -idCVar si_name( "si_name", "DOOM Server", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "name of the server" ); -idCVar si_gameType( "si_gameType", si_gameTypeArgs[ 0 ], CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "game type - singleplayer, deathmatch, Tourney, Team DM or Last Man", si_gameTypeArgs, idCmdSystem::ArgCompletion_String ); -idCVar si_map( "si_map", "game/mp/d3dm1",CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "map to be played next on server", idCmdSystem::ArgCompletion_MapName ); -idCVar si_maxPlayers( "si_maxPlayers", "4", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "max number of players allowed on the server", 1, 4 ); -idCVar si_fragLimit( "si_fragLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "frag limit", 1, MP_PLAYER_MAXFRAGS ); -idCVar si_timeLimit( "si_timeLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "time limit in minutes", 0, 60 ); -idCVar si_teamDamage( "si_teamDamage", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable team damage" ); -idCVar si_warmup( "si_warmup", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "do pre-game warmup" ); -idCVar si_usePass( "si_usePass", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable client password checking" ); -idCVar si_pure( "si_pure", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_BOOL, "server is pure and does not allow modified data" ); -idCVar si_spectators( "si_spectators", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "allow spectators or require all clients to play" ); -idCVar si_serverURL( "si_serverURL", "", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "where to reach the server admins and get information about the server" ); - - -// user info -idCVar ui_name( "ui_name", "Player", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player name" ); -idCVar ui_skin( "ui_skin", ui_skinArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player skin", ui_skinArgs, idCmdSystem::ArgCompletion_String ); -idCVar ui_team( "ui_team", ui_teamArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player team", ui_teamArgs, idCmdSystem::ArgCompletion_String ); -idCVar ui_autoSwitch( "ui_autoSwitch", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto switch weapon" ); -idCVar ui_autoReload( "ui_autoReload", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto reload weapon" ); -idCVar ui_showGun( "ui_showGun", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "show gun" ); -idCVar ui_ready( "ui_ready", si_readyArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "player is ready to start playing", idCmdSystem::ArgCompletion_String ); -idCVar ui_spectate( "ui_spectate", si_spectateArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "play or spectate", idCmdSystem::ArgCompletion_String ); -idCVar ui_chat( "ui_chat", "0", CVAR_GAME | CVAR_USERINFO | CVAR_BOOL | CVAR_ROM | CVAR_CHEAT, "player is chatting" ); - -// change anytime vars -idCVar developer( "developer", "0", CVAR_GAME | CVAR_BOOL, "" ); - -idCVar r_aspectRatio( "r_aspectRatio", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE, "Aspect ratio of view, determines the ratio between FOV for x and y. Only used if r_fovRatio is 0:\n0 = 4:3\n1 = 16:9\n2 = 16:10\n3 = 5:4\n16:9 TV", 0, 4 ); - -idCVar cv_r_fovRatio( "r_fovRatio", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Aspect ratio of view, if set to greater than 0, determines the ratio between FOV for x and y directly, and r_aspectRatio is ignored. The value should closely match r_customWidth / r_customHeight." ); - -idCVar cv_gui_Width( "gui_Width", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Size of the GUI as factor of the screen width. Default is 1.0 and stretches the GUI over the entire screen." ); -idCVar cv_gui_Height( "gui_Height", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Size of the GUI as factor of the screen height. Default is 1.0 and stretches the GUI over the entire screen." ); -idCVar cv_gui_CenterX( "gui_CenterX", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Position of the center of the GUI as percentage of the whole screen width. Default is 0.5 (half of the screen width)." ); -idCVar cv_gui_CenterY( "gui_CenterY", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "Position of the center of the GUI as percentage of the whole screen height. Default is 0.5 (half of the screen height)." ); - -idCVar g_cinematic( "g_cinematic", "1", CVAR_GAME | CVAR_BOOL, "skips updating entities that aren't marked 'cinematic' '1' during cinematics" ); -idCVar g_cinematicMaxSkipTime( "g_cinematicMaxSkipTime", "600", CVAR_GAME | CVAR_FLOAT, "# of seconds to allow game to run when skipping cinematic. prevents lock-up when cinematic doesn't end.", 0, 3600 ); - -idCVar g_muzzleFlash( "g_muzzleFlash", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show muzzle flashes" ); -idCVar g_projectileLights( "g_projectileLights", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show dynamic lights on projectiles" ); -idCVar g_bloodEffects( "g_bloodEffects", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show blood splats, sprays and gibs" ); -idCVar g_doubleVision( "g_doubleVision", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show double vision when taking damage" ); -idCVar g_monsters( "g_monsters", "1", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_decals( "g_decals", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show decals such as bullet holes" ); -idCVar g_knockback( "g_knockback", "1000", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar g_skill( "g_skill", "1", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar g_nightmare( "g_nightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed" ); -idCVar g_gravity( "g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_skipFX( "g_skipFX", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_skipParticles( "g_skipParticles", "0", CVAR_GAME | CVAR_BOOL, "" ); - -idCVar g_disasm( "g_disasm", "0", CVAR_GAME | CVAR_BOOL, "disassemble script into base/script/disasm.txt on the local drive when script is compiled" ); -idCVar g_debugBounds( "g_debugBounds", "0", CVAR_GAME | CVAR_BOOL, "checks for models with bounds > 2048" ); -idCVar g_debugAnim( "g_debugAnim", "-1", CVAR_GAME | CVAR_INTEGER, "displays information on which animations are playing on the specified entity number. set to -1 to disable." ); -idCVar g_debugMove( "g_debugMove", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugDamage( "g_debugDamage", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugWeapon( "g_debugWeapon", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugScript( "g_debugScript", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugMover( "g_debugMover", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugTriggers( "g_debugTriggers", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_debugCinematic( "g_debugCinematic", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_stopTime( "g_stopTime", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_damageScale( "g_damageScale", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "scale final damage on player by this factor" ); -idCVar g_armorProtection( "g_armorProtection", "0.3", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" ); -idCVar g_armorProtectionMP( "g_armorProtectionMP", "0.6", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" ); -idCVar g_useDynamicProtection( "g_useDynamicProtection", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "scale damage and armor dynamically to keep the player alive more often" ); -idCVar g_healthTakeTime( "g_healthTakeTime", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how often to take health in nightmare mode" ); -idCVar g_healthTakeAmt( "g_healthTakeAmt", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how much health to take in nightmare mode" ); -idCVar g_healthTakeLimit( "g_healthTakeLimit", "25", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how low can health get taken in nightmare mode" ); - - - -idCVar g_showPVS( "g_showPVS", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 2 ); -idCVar g_showTargets( "g_showTargets", "0", CVAR_GAME | CVAR_BOOL, "draws entities and thier targets. hidden entities are drawn grey." ); -idCVar g_showTriggers( "g_showTriggers", "0", CVAR_GAME | CVAR_BOOL, "draws trigger entities (orange) and thier targets (green). disabled triggers are drawn grey." ); -idCVar g_showCollisionWorld( "g_showCollisionWorld", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_showCollisionModels( "g_showCollisionModels", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_showCollisionTraces( "g_showCollisionTraces", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_maxShowDistance( "g_maxShowDistance", "128", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_showEntityInfo( "g_showEntityInfo", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_showviewpos( "g_showviewpos", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_showcamerainfo( "g_showcamerainfo", "0", CVAR_GAME | CVAR_ARCHIVE, "displays the current frame # for the camera when playing cinematics" ); -idCVar g_showTestModelFrame( "g_showTestModelFrame", "0", CVAR_GAME | CVAR_BOOL, "displays the current animation and frame # for testmodels" ); -idCVar g_showActiveEntities( "g_showActiveEntities", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around thinking entities. dormant entities (outside of pvs) are drawn yellow. non-dormant are green." ); -idCVar g_showEnemies( "g_showEnemies", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around monsters that have targeted the the player" ); - -idCVar g_frametime( "g_frametime", "0", CVAR_GAME | CVAR_BOOL, "displays timing information for each game frame" ); - -// TDM: greebo: Use this to stretch the hardcoded 16 msec each frame takes. This can be used to let the game run ultra-slow. -idCVar g_timeModifier( "g_timeModifier", "1", CVAR_GAME | CVAR_FLOAT, "Use this to stretch the hardcoded 16 msec each frame takes. This can be used to let the game run ultra-slow." ); -idCVar g_timeentities( "g_timeEntities", "0", CVAR_GAME | CVAR_FLOAT, "when non-zero, shows entities whose think functions exceeded the # of milliseconds specified" ); - - -idCVar g_enablePortalSky( "g_enablePortalSky", "1", CVAR_GAME | CVAR_BOOL, "enables the portal sky" ); - - -idCVar ai_debugScript( "ai_debugScript", "-1", CVAR_GAME | CVAR_INTEGER, "displays script calls for the specified monster entity number" ); -idCVar ai_debugMove( "ai_debugMove", "0", CVAR_GAME | CVAR_BOOL, "draws movement information for monsters" ); -idCVar ai_debugTrajectory( "ai_debugTrajectory", "0", CVAR_GAME | CVAR_BOOL, "draws trajectory tests for monsters" ); -idCVar ai_testPredictPath( "ai_testPredictPath", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar ai_showCombatNodes( "ai_showCombatNodes", "0", CVAR_GAME | CVAR_BOOL, "draws attack cones for monsters" ); -idCVar ai_showPaths( "ai_showPaths", "0", CVAR_GAME | CVAR_BOOL, "draws path_* entities" ); -idCVar ai_showObstacleAvoidance( "ai_showObstacleAvoidance", "0", CVAR_GAME | CVAR_INTEGER, "draws obstacle avoidance information for monsters. if 2, draws obstacles for player, as well", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); -idCVar ai_blockedFailSafe( "ai_blockedFailSafe", "1", CVAR_GAME | CVAR_BOOL, "enable blocked fail safe handling" ); - -idCVar g_dvTime( "g_dvTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_dvAmplitude( "g_dvAmplitude", "0.001", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_dvFrequency( "g_dvFrequency", "0.5", CVAR_GAME | CVAR_FLOAT, "" ); - -idCVar g_kickTime( "g_kickTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_kickAmplitude( "g_kickAmplitude", "0.0001", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_blobTime( "g_blobTime", "1", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_blobSize( "g_blobSize", "1", CVAR_GAME | CVAR_FLOAT, "" ); - -idCVar g_testHealthVision( "g_testHealthVision", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_editEntityMode( "g_editEntityMode", "0", CVAR_GAME | CVAR_INTEGER, "0 = off\n" - "1 = lights\n" - "2 = sounds\n" - "3 = articulated figures\n" - "4 = particle systems\n" - "5 = monsters\n" - "6 = entity names\n" - "7 = entity models", 0, 7, idCmdSystem::ArgCompletion_Integer<0,7> ); -idCVar g_dragEntity( "g_dragEntity", "0", CVAR_GAME | CVAR_BOOL, "allows dragging physics objects around by placing the crosshair over them and holding the fire button" ); -idCVar g_dragDamping( "g_dragDamping", "0.5", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_dragShowSelection( "g_dragShowSelection", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_dropItemRotation( "g_dropItemRotation", "", CVAR_GAME, "" ); - -idCVar g_vehicleVelocity( "g_vehicleVelocity", "1000", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleForce( "g_vehicleForce", "50000", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleSuspensionUp( "g_vehicleSuspensionUp", "32", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleSuspensionDown( "g_vehicleSuspensionDown", "20", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleSuspensionKCompress("g_vehicleSuspensionKCompress","200", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleSuspensionDamping( "g_vehicleSuspensionDamping","400", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_vehicleTireFriction( "g_vehicleTireFriction", "0.8", CVAR_GAME | CVAR_FLOAT, "" ); - -idCVar ik_enable( "ik_enable", "1", CVAR_GAME | CVAR_BOOL, "enable IK" ); -idCVar ik_debug( "ik_debug", "0", CVAR_GAME | CVAR_BOOL, "show IK debug lines" ); - -idCVar af_useLinearTime( "af_useLinearTime", "1", CVAR_GAME | CVAR_BOOL, "use linear time algorithm for tree-like structures" ); -idCVar af_useImpulseFriction( "af_useImpulseFriction", "0", CVAR_GAME | CVAR_BOOL, "use impulse based contact friction" ); -idCVar af_useJointImpulseFriction( "af_useJointImpulseFriction","0", CVAR_GAME | CVAR_BOOL, "use impulse based joint friction" ); -idCVar af_useSymmetry( "af_useSymmetry", "1", CVAR_GAME | CVAR_BOOL, "use constraint matrix symmetry" ); -#ifdef MOD_WATERPHYSICS - -idCVar af_useBodyDensityBuoyancy( "af_useBodyDensityBuoyancy","0", CVAR_GAME | CVAR_BOOL, "uses density of each body to calculate buoyancy"); // MOD_WATERPHYSICS - -idCVar af_useFixedDensityBuoyancy( "af_useFixedDensityBuoyancy","1", CVAR_GAME | CVAR_BOOL, "if set, use liquidDensity as a fixed density for each body when calculating buoyancy. If clear, bodies are floated uniformly by a scalar liquidDensity as defined in the decls." ); // MOD_WATERPHYSICS - -#endif // MOD_WATERPHYSICS - -idCVar af_skipSelfCollision( "af_skipSelfCollision", "0", CVAR_GAME | CVAR_BOOL, "skip self collision detection" ); -idCVar af_skipLimits( "af_skipLimits", "0", CVAR_GAME | CVAR_BOOL, "skip joint limits" ); -idCVar af_skipFriction( "af_skipFriction", "0", CVAR_GAME | CVAR_BOOL, "skip friction" ); -idCVar af_forceFriction( "af_forceFriction", "-1", CVAR_GAME | CVAR_FLOAT, "force the given friction value" ); -idCVar af_maxLinearVelocity( "af_maxLinearVelocity", "128", CVAR_GAME | CVAR_FLOAT, "maximum linear velocity" ); -idCVar af_maxAngularVelocity( "af_maxAngularVelocity", "1.57", CVAR_GAME | CVAR_FLOAT, "maximum angular velocity" ); -idCVar af_timeScale( "af_timeScale", "1", CVAR_GAME | CVAR_FLOAT, "scales the time" ); -idCVar af_jointFrictionScale( "af_jointFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the joint friction" ); -idCVar af_contactFrictionScale( "af_contactFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the contact friction" ); -idCVar af_highlightBody( "af_highlightBody", "", CVAR_GAME, "name of the body to highlight" ); -idCVar af_highlightConstraint( "af_highlightConstraint", "", CVAR_GAME, "name of the constraint to highlight" ); -idCVar af_showTimings( "af_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show articulated figure cpu usage" ); -idCVar af_showConstraints( "af_showConstraints", "0", CVAR_GAME | CVAR_BOOL, "show constraints" ); -idCVar af_showConstraintNames( "af_showConstraintNames", "0", CVAR_GAME | CVAR_BOOL, "show constraint names" ); -idCVar af_showConstrainedBodies( "af_showConstrainedBodies", "0", CVAR_GAME | CVAR_BOOL, "show the two bodies contrained by the highlighted constraint" ); -idCVar af_showPrimaryOnly( "af_showPrimaryOnly", "0", CVAR_GAME | CVAR_BOOL, "show primary constraints only" ); -idCVar af_showTrees( "af_showTrees", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures" ); -idCVar af_showLimits( "af_showLimits", "0", CVAR_GAME | CVAR_BOOL, "show joint limits" ); -idCVar af_showBodies( "af_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show bodies" ); -idCVar af_showBodyNames( "af_showBodyNames", "0", CVAR_GAME | CVAR_BOOL, "show body names" ); -idCVar af_showMass( "af_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each body" ); -idCVar af_showTotalMass( "af_showTotalMass", "0", CVAR_GAME | CVAR_BOOL, "show the total mass of each articulated figure" ); -idCVar af_showInertia( "af_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each body" ); -idCVar af_showVelocity( "af_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each body" ); -idCVar af_showActive( "af_showActive", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures of articulated figures not at rest" ); -idCVar af_testSolid( "af_testSolid", "1", CVAR_GAME | CVAR_BOOL, "test for bodies initially stuck in solid" ); - -idCVar rb_showTimings( "rb_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show rigid body cpu usage" ); -idCVar rb_showBodies( "rb_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies" ); -idCVar rb_showMass( "rb_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each rigid body" ); -idCVar rb_showInertia( "rb_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each rigid body" ); -idCVar rb_showVelocity( "rb_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each rigid body" ); -idCVar rb_showActive( "rb_showActive", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies that are not at rest" ); -#ifdef MOD_WATERPHYSICS - -idCVar rb_showBuoyancy( "rb_showBuoyancy", "0", CVAR_GAME | CVAR_BOOL, "show rigid body buoyancy information" ); // MOD_WATERPHYSICS - -#endif // MOD_WATERPHYSICS - - -// The default values for player movement cvars are set in def/player.def -idCVar pm_jumpheight( "pm_jumpheight", "48", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "approximate hieght the player can jump" ); -idCVar pm_stepsize( "pm_stepsize", "16", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "maximum height the player can step up without jumping" ); -// replaced by crouch multiplier -//idCVar pm_crouchspeed( "pm_crouchspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while crouched" ); -idCVar pm_walkspeed( "pm_walkspeed", "70", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "speed the player can move while walking" ); -// also replaced by multiplier -//idCVar pm_runspeed( "pm_runspeed", "220", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while running" ); -idCVar pm_noclipspeed( "pm_noclipspeed", "200", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while in noclip" ); -idCVar pm_spectatespeed( "pm_spectatespeed", "450", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while spectating" ); -idCVar pm_spectatebbox( "pm_spectatebbox", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "size of the spectator bounding box" ); -idCVar pm_usecylinder( "pm_usecylinder", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "use a cylinder approximation instead of a bounding box for player collision detection" ); -idCVar pm_minviewpitch( "pm_minviewpitch", "-89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look up (negative values are up)" ); -idCVar pm_maxviewpitch( "pm_maxviewpitch", "89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look down" ); -// Commented out by Dram. Not needed as TDM does not use stamina -//idCVar pm_stamina( "pm_stamina", "24", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "length of time player can run" ); -//idCVar pm_staminathreshold( "pm_staminathreshold", "45", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "when stamina drops below this value, player gradually slows to a walk" ); -//idCVar pm_staminarate( "pm_staminarate", "0.75", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "rate that player regains stamina. divide pm_stamina by this value to determine how long it takes to fully recharge." ); -idCVar pm_crouchheight( "pm_crouchheight", "38", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while crouched" ); -idCVar pm_crouchviewheight( "pm_crouchviewheight", "34", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while crouched" ); -idCVar pm_normalheight( "pm_normalheight", "74", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while standing" ); -idCVar pm_normalviewheight( "pm_normalviewheight", "68", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while standing" ); -idCVar pm_deadheight( "pm_deadheight", "20", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while dead" ); -idCVar pm_deadviewheight( "pm_deadviewheight", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while dead" ); -idCVar pm_crouchrate( "pm_crouchrate", "0.87", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "time it takes for player's view to change from standing to crouching" ); -idCVar pm_bboxwidth( "pm_bboxwidth", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "x/y size of player's bounding box" ); -idCVar pm_crouchbob( "pm_crouchbob", "0.2", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob much faster when crouched" ); -idCVar pm_walkbob( "pm_walkbob", "0.3", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking" ); -idCVar pm_runbob( "pm_runbob", "0.35", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob faster when running" ); -idCVar pm_runpitch( "pm_runpitch", "0.001", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); -idCVar pm_runroll( "pm_runroll", "0.003", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); -idCVar pm_bobup( "pm_bobup", "0.035", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); -idCVar pm_bobpitch( "pm_bobpitch", "0.001", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); -idCVar pm_bobroll( "pm_bobroll", "0.0015", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" ); -idCVar pm_thirdPersonRange( "pm_thirdPersonRange", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "camera distance from player in 3rd person" ); -idCVar pm_thirdPersonHeight( "pm_thirdPersonHeight", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of camera from normal view height in 3rd person" ); -idCVar pm_thirdPersonAngle( "pm_thirdPersonAngle", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "direction of camera from player in 3rd person in degrees (0 = behind player, 180 = in front)" ); -idCVar pm_thirdPersonClip( "pm_thirdPersonClip", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "clip third person view into world space" ); -idCVar pm_thirdPerson( "pm_thirdPerson", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view" ); -idCVar pm_thirdPersonDeath( "pm_thirdPersonDeath", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view when player dies" ); -idCVar pm_modelView( "pm_modelView", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "draws camera from POV of player model (1 = always, 2 = when dead)", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); -idCVar pm_airTics( "pm_air", "1800", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "how long in milliseconds the player can go without air before he starts taking damage" ); - -idCVar g_showPlayerShadow( "g_showPlayerShadow", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables shadow of player model" ); -idCVar g_showHud( "g_showHud", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "" ); -idCVar g_showProjectilePct( "g_showProjectilePct", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables display of player hit percentage" ); -idCVar g_showBrass( "g_showBrass", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables ejected shells from weapon" ); -idCVar g_gun_x( "g_gunX", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_viewNodalX( "g_viewNodalX", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_viewNodalZ( "g_viewNodalZ", "0", CVAR_GAME | CVAR_FLOAT, "" ); -idCVar g_fov( "g_fov", "90", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "" ); -idCVar g_skipViewEffects( "g_skipViewEffects", "0", CVAR_GAME | CVAR_BOOL, "skip damage and other view effects" ); -idCVar g_mpWeaponAngleScale( "g_mpWeaponAngleScale", "0", CVAR_GAME | CVAR_FLOAT, "Control the weapon sway in MP" ); - -idCVar g_testParticle( "g_testParticle", "0", CVAR_GAME | CVAR_INTEGER, "test particle visualation, set by the particle editor" ); -idCVar g_testParticleName( "g_testParticleName", "", CVAR_GAME, "name of the particle being tested by the particle editor" ); -idCVar g_testModelHead( "g_testModelHead", "atdm:ai_head_citywatch", CVAR_GAME | CVAR_ARCHIVE, "test model head entityDef" ); -idCVar g_testModelHeadJoint( "g_testModelHeadJoint", "Spine2", CVAR_GAME | CVAR_ARCHIVE, "test model head joint" ); -idCVar g_testModelRotate( "g_testModelRotate", "0", CVAR_GAME, "test model rotation speed" ); -idCVar g_testPostProcess( "g_testPostProcess", "", CVAR_GAME, "name of material to draw over screen" ); -idCVar g_testModelAnimate( "g_testModelAnimate", "0", CVAR_GAME | CVAR_INTEGER, "test model animation,\n" - "0 = cycle anim with origin reset\n" - "1 = cycle anim with fixed origin\n" - "2 = cycle anim with continuous origin\n" - "3 = frame by frame with continuous origin\n" - "4 = play anim once", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> ); -idCVar g_testModelBlend( "g_testModelBlend", "0", CVAR_GAME | CVAR_INTEGER, "number of frames to blend" ); -idCVar g_testDeath( "g_testDeath", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar g_exportMask( "g_exportMask", "", CVAR_GAME, "" ); -idCVar g_flushSave( "g_flushSave", "0", CVAR_GAME | CVAR_BOOL, "1 = don't buffer file writing for save games." ); - -idCVar g_rotoscope( "g_rotoscope", "0", CVAR_GAME | CVAR_BOOL, "Noir cartoon-like rendering" ); - -idCVar aas_test( "aas_test", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_showAreas( "aas_showAreas", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar aas_showPath( "aas_showPath", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_showFlyPath( "aas_showFlyPath", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_showWallEdges( "aas_showWallEdges", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar aas_showHideArea( "aas_showHideArea", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_pullPlayer( "aas_pullPlayer", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_randomPullPlayer( "aas_randomPullPlayer", "0", CVAR_GAME | CVAR_BOOL, "" ); -idCVar aas_goalArea( "aas_goalArea", "0", CVAR_GAME | CVAR_INTEGER, "" ); -idCVar aas_showPushIntoArea( "aas_showPushIntoArea", "0", CVAR_GAME | CVAR_BOOL, "" ); - -idCVar g_password( "g_password", "", CVAR_GAME | CVAR_ARCHIVE, "game password" ); -idCVar password( "password", "", CVAR_GAME | CVAR_NOCHEAT, "client password used when connecting" ); - -idCVar g_countDown( "g_countDown", "10", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "pregame countdown in seconds", 4, 3600 ); -idCVar g_gameReviewPause( "g_gameReviewPause", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "scores review time in seconds (at end game)", 2, 3600 ); -idCVar g_TDMArrows( "g_TDMArrows", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "draw arrows over teammates in team deathmatch" ); -idCVar g_balanceTDM( "g_balanceTDM", "1", CVAR_GAME | CVAR_BOOL, "maintain even teams" ); - -idCVar net_clientPredictGUI( "net_clientPredictGUI", "1", CVAR_GAME | CVAR_BOOL, "test guis in networking without prediction" ); - -idCVar g_voteFlags( "g_voteFlags", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "vote flags. bit mask of votes not allowed on this server\n" - "bit 0 (+1) restart now\n" - "bit 1 (+2) time limit\n" - "bit 2 (+4) frag limit\n" - "bit 3 (+8) game type\n" - "bit 4 (+16) kick player\n" - "bit 5 (+32) change map\n" - "bit 6 (+64) spectators\n" - "bit 7 (+128) next map" ); -idCVar g_mapCycle( "g_mapCycle", "mapcycle", CVAR_GAME | CVAR_ARCHIVE, "map cycling script for multiplayer games - see mapcycle.scriptcfg" ); - -idCVar mod_validSkins( "mod_validSkins", "skins/characters/player/marine_mp;skins/characters/player/marine_mp_green;skins/characters/player/marine_mp_blue;skins/characters/player/marine_mp_red;skins/characters/player/marine_mp_yellow", CVAR_GAME | CVAR_ARCHIVE, "valid skins for the game" ); -idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" ); - -idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" ); - -idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, seperated by ;" ); - -// bloom related - J.C.Denton - -idCVar r_postprocess_debugMode ( "r_postprocess_debugMode", "0", CVAR_GAME | CVAR_INTEGER, " Shows all the textures generated for postprocessing effects. \n 1: Shows currentRender \n 2: Shows bloom Images \n 3: Shows Cooked Math Data."); -idCVar r_postprocess ( "r_postprocess", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, " Activates bloom ( Requires DX9 compliant Hardware )"); -idCVar r_postprocess_brightPassThreshold ( "r_postprocess_brightPassThreshold", "0.2", CVAR_GAME | CVAR_FLOAT, " Intensities of this value are subtracted from scene render to extract bloom image"); -idCVar r_postprocess_brightPassOffset ( "r_postprocess_brightPassOffset", "2", CVAR_GAME | CVAR_FLOAT, " Bloom image receives smooth fade along a curve from bright to very bright areas based on this variable's value"); -idCVar r_postprocess_colorCurveBias ( "r_postprocess_colorCurveBias", "0.8", CVAR_GAME | CVAR_FLOAT, " Applies Exponential Color Curve to final pass (range 0 to 1), 1 = color curve fully applied , 0= No color curve"); -idCVar r_postprocess_colorCorrection ( "r_postprocess_colorCorrection", "5", CVAR_GAME | CVAR_FLOAT, " Applies an exponential color correction function to final scene "); -idCVar r_postprocess_colorCorrectBias ( "r_postprocess_colorCorrectBias", "0.1", CVAR_GAME | CVAR_FLOAT, " Applies an exponential color correction function to final scene with this bias. \n E.g. value ranges between 0-1. A blend is performed between scene render and color corrected image based on this value "); -idCVar r_postprocess_desaturation ( "r_postprocess_desaturation", "0.05", CVAR_GAME | CVAR_FLOAT, " Desaturates the scene "); -idCVar r_postprocess_sceneExposure ( "r_postprocess_sceneExposure", "0.9", CVAR_GAME | CVAR_FLOAT, " Scene render is linearly scaled up. Try values lower or greater than 1.0"); -idCVar r_postprocess_sceneGamma ( "r_postprocess_sceneGamma", "0.82", CVAR_GAME | CVAR_FLOAT, " Gamma Correction."); -idCVar r_postprocess_bloomIntensity ( "r_postprocess_bloomIntensity", "0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, " Adjusts the Bloom intensity. 0.0 disables the bloom but other postprocessing effects remain unaffected."); -idCVar r_postprocess_bloomKernelSize ( "r_postprocess_bloomKernelSize", "2", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, " Sets Bloom's Kernel size. Smaller is faster, takes less memory. Also, smaller kernel means larger bloom spread. \n 1. Large (2x smaller than current resolution) \n 2. Small (4x smaller than current resolution) " ); -//---------------------------------- - -#ifndef __linux__ -idCVar s_driver("s_driver", "0", CVAR_GUI, "Dummy CVAR introduced by TDM to fix a console warning in Windows. Seems to be missing, but D3's mpmain.gui references this."); -#endif - diff --git a/game/gamesys/syscvar.h b/game/gamesys/syscvar.h deleted file mode 100644 index b56cb9158..000000000 --- a/game/gamesys/syscvar.h +++ /dev/null @@ -1,644 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SYS_CVAR_H__ -#define __SYS_CVAR_H__ - -#ifdef __linux__ -#include "framework/cvarsystem.h" -#endif - -/** -* DarkMod cvars - See text description in syscvar.cpp for descriptions -**/ -extern idCVar cv_player_spawnclass; -extern idCVar cv_player_waituntilready; - -extern idCVar cv_default_mission_info_file; - -extern idCVar cv_ai_sndvol; -extern idCVar cv_ai_bark_show; -extern idCVar cv_ai_bumpobject_impulse; -extern idCVar cv_ai_sight_prob; -extern idCVar cv_ai_sight_mag; -extern idCVar cv_ai_sightmaxdist; -extern idCVar cv_ai_sightmindist; -extern idCVar cv_ai_tactalert; -extern idCVar cv_ai_task_show; -extern idCVar cv_ai_alertlevel_show; -extern idCVar cv_ai_dest_show; -extern idCVar cv_ai_goalpos_show; -extern idCVar cv_ai_aasarea_show; -extern idCVar cv_ai_debug_blocked; -extern idCVar cv_ai_door_show; -extern idCVar cv_ai_elevator_show; -extern idCVar cv_ai_debug; -extern idCVar cv_ai_sight_thresh; -extern idCVar cv_ai_sight_scale; -extern idCVar cv_ai_show_enemy_visibility; -extern idCVar cv_ai_show_conversationstate; -extern idCVar cv_ai_acuity_L3; -extern idCVar cv_ai_acuity_L4; -extern idCVar cv_ai_acuity_L5; -extern idCVar cv_ai_acuity_susp; -extern idCVar cv_ai_visdist_show; -extern idCVar cv_ai_opt_disable; -extern idCVar cv_ai_opt_noanims; -extern idCVar cv_ai_opt_novisualscan; -extern idCVar cv_ai_opt_forceopt; -extern idCVar cv_ai_opt_nothink; -extern idCVar cv_ai_opt_interleavethinkmindist; -extern idCVar cv_ai_opt_interleavethinkmaxdist; -extern idCVar cv_ai_opt_interleavethinkskippvscheck; -extern idCVar cv_ai_opt_interleavethinkframes; -extern idCVar cv_ai_opt_update_enemypos_interleave; -extern idCVar cv_ai_opt_nomind; -extern idCVar cv_ai_opt_novisualstim; -extern idCVar cv_ai_opt_nolipsync; -extern idCVar cv_ai_opt_nopresent; -extern idCVar cv_ai_opt_noobstacleavoidance; -extern idCVar cv_ai_hiding_spot_max_light_quotient; -extern idCVar cv_ai_max_hiding_spot_tests_per_frame; -extern idCVar cv_ai_debug_anims; - -extern idCVar cv_show_health; - -extern idCVar cv_ai_show_aasfuncobstacle_state; - -extern idCVar cv_interaction_vfp_type; -extern idCVar cv_tdm_widescreenmode; -extern idCVar cv_tdm_menu_music; - -extern idCVar cv_tdm_show_trainer_messages; - -extern idCVar cv_tdm_default_relations_def; -extern idCVar cv_tdm_lang; -extern idCVar cv_tdm_fm_path; -extern idCVar cv_tdm_fm_desc_file; -extern idCVar cv_tdm_fm_current_file; -extern idCVar cv_tdm_fm_notes_file; -extern idCVar cv_tdm_fm_startingmap_file; -extern idCVar cv_tdm_fm_mapsequence_file; -extern idCVar cv_tdm_fm_splashimage_file; -extern idCVar cv_tdm_fm_sync_config_files; -extern idCVar cv_tdm_fm_restart_delay; - -extern idCVar cv_tdm_proxy; -extern idCVar cv_tdm_proxy_user; -extern idCVar cv_tdm_proxy_pass; -extern idCVar cv_tdm_allow_http_access; -extern idCVar cv_tdm_mission_list_urls; -extern idCVar cv_tdm_mission_details_url; -extern idCVar cv_tdm_mission_screenshot_url; -extern idCVar cv_tdm_version_check_url; -extern idCVar cv_tdm_http_base_url; - -extern idCVar cv_debug_aastype; - -extern idCVar cv_las_showtraces; -extern idCVar cv_show_gameplay_time; - -extern idCVar cv_tdm_difficulty; - -extern idCVar cv_sr_disable; -extern idCVar cv_sr_show; - -extern idCVar cv_sndprop_disable; -extern idCVar cv_spr_debug; -extern idCVar cv_spr_show; -extern idCVar cv_spr_radius_show; -extern idCVar cv_ko_show; -extern idCVar cv_ai_animstate_show; - -extern idCVar cv_debug_mainmenu; -extern idCVar cv_mainmenu_confirmquit; - -extern idCVar cv_pm_runmod; -extern idCVar cv_pm_run_backmod; -extern idCVar cv_pm_crouchmod; -extern idCVar cv_pm_max_swimspeed_mod; -extern idCVar cv_pm_creepmod; -extern idCVar cv_pm_pushmod; -extern idCVar cv_pm_push_maximpulse; -extern idCVar cv_pm_push_start_delay; -extern idCVar cv_pm_push_accel_time; -extern idCVar cv_pm_push_heavy_threshold; -extern idCVar cv_pm_push_max_mass; - - -/** -* TDM CVARs for controlling jumping -*/ -extern idCVar cv_tdm_walk_jump_vel; -extern idCVar cv_tdm_run_jump_vel; -extern idCVar cv_tdm_crouch_jump_vel; -extern idCVar cv_tdm_min_vel_jump; -extern idCVar cv_tdm_fwd_jump_vel; -extern idCVar cv_tdm_backwards_jump_modifier; -extern idCVar cv_tdm_jump_relaxation_time; - -extern idCVar cv_tdm_footfalls_movetype_specific; - -extern idCVar cv_pm_weightmod; - -extern idCVar cv_pm_mantle_height; -extern idCVar cv_pm_mantle_reach; -extern idCVar cv_pm_mantle_minflatness; -extern idCVar cv_pm_mantle_jump_hold_trigger; -extern idCVar cv_pm_mantle_min_velocity_for_damage; -extern idCVar cv_pm_mantle_damage_per_velocity_over_minimum; -extern idCVar cv_pm_mantle_hang_msecs; -extern idCVar cv_pm_mantle_pull_msecs; -extern idCVar cv_pm_mantle_shift_hands_msecs; -extern idCVar cv_pm_mantle_push_msecs; - -extern idCVar cv_pm_rope_snd_rep_dist; -extern idCVar cv_pm_rope_velocity_letgo; -extern idCVar cv_pm_rope_swing_impulse; -extern idCVar cv_pm_rope_swing_reptime; -extern idCVar cv_pm_rope_swing_kickdist; -extern idCVar cv_pm_water_downwards_velocity; -extern idCVar cv_pm_water_z_friction; -extern idCVar cv_pm_show_waterlevel; -extern idCVar cv_pm_climb_distance; - -/** -* This cvar controls if ai hiding spot search debug graphics are drawn -* If it is 0, then the graphics are not drawn. If it is >= 1.0 then it -* is the number of milliseconds for which each graphic should persist. -* For example 3000.0 would mean 3 seconds -*/ -extern idCVar cv_ai_search_show; - -extern idCVar cv_force_savegame_load; -extern idCVar cv_savegame_compress; - -extern idCVar cv_screenshot_format; - -// angua: TDM toggle crouch -extern idCVar cv_tdm_crouch_toggle; -extern idCVar cv_tdm_crouch_toggle_hold_time; -extern idCVar cv_tdm_reattach_delay; - - -/** -* TDM Leaning vars: -**/ -extern idCVar cv_pm_lean_angle; -extern idCVar cv_pm_lean_time; -extern idCVar cv_pm_lean_height; -extern idCVar cv_pm_lean_stretch; -extern idCVar cv_pm_lean_forward_angle; -extern idCVar cv_pm_lean_forward_time; -extern idCVar cv_pm_lean_forward_height; -extern idCVar cv_pm_lean_forward_stretch; -extern idCVar cv_pm_lean_to_valid_increments; -extern idCVar cv_pm_lean_door_increments; -extern idCVar cv_pm_lean_door_max; -extern idCVar cv_pm_lean_door_bounds_exp; -extern idCVar cv_pm_lean_toggle; - -extern idCVar cv_frob_distance_default; -extern idCVar cv_frob_width; -extern idCVar cv_frob_debug_bounds; -extern idCVar cv_frob_fadetime; -extern idCVar cv_frob_weapon_selects_weapon; -extern idCVar cv_frob_debug_hud; - -extern idCVar cv_weapon_next_on_empty; - -// physics -extern idCVar cv_collision_damage_scale_vert; -extern idCVar cv_collision_damage_scale_horiz; -extern idCVar cv_drag_limit_force; -extern idCVar cv_drag_force_max; -extern idCVar cv_drag_stuck_dist; -extern idCVar cv_drag_damping; -extern idCVar cv_drag_damping_AF; -extern idCVar cv_drag_AF_ground_timer; -extern idCVar cv_drag_AF_free; -extern idCVar cv_drag_jump_masslimit; -extern idCVar cv_drag_encumber_minmass; -extern idCVar cv_drag_encumber_minmass; -extern idCVar cv_drag_encumber_maxmass; -extern idCVar cv_drag_encumber_max; -extern idCVar cv_dragged_item_highlight; -extern idCVar cv_drag_debug; -extern idCVar cv_melee_debug; -extern idCVar cv_melee_state_debug; -extern idCVar cv_melee_mouse_thresh; -extern idCVar cv_melee_mouse_decision_time; -extern idCVar cv_melee_mouse_dead_time; -extern idCVar cv_melee_mouse_slowview; -extern idCVar cv_melee_invert_attack; -extern idCVar cv_melee_invert_parry; -extern idCVar cv_melee_auto_parry; -extern idCVar cv_melee_forbid_auto_parry; -extern idCVar cv_melee_max_particles; -extern idCVar cv_phys_show_momentum; - -extern idCVar cv_throw_min; -extern idCVar cv_throw_max; -extern idCVar cv_throw_time; -extern idCVar cv_throw_max_vel; - -extern idCVar cv_bounce_sound_max_vel; -extern idCVar cv_bounce_sound_min_vel; - -extern idCVar cv_reverse_grab_control; - -extern idCVar cv_tdm_rope_pull_force_factor; - -extern idCVar cv_tdm_obj_gui_file; -extern idCVar cv_tdm_waituntilready_gui_file; - -extern idCVar cv_tdm_hud_opacity; -extern idCVar cv_tdm_hud_hide_lightgem; -extern idCVar cv_tdm_underwater_blur; - -extern idCVar cv_tdm_inv_loot_item_def; -extern idCVar cv_tdm_inv_gui_file; -extern idCVar cv_tdm_inv_hud_pickupmessages; -extern idCVar cv_tdm_inv_loot_sound; -extern idCVar cv_tdm_inv_use_on_frob; -extern idCVar cv_tdm_inv_use_visual_feedback; - -extern idCVar cv_tdm_door_control; -extern idCVar cv_tdm_door_control_sensitivity; - -extern idCVar cv_pm_stepvol_walk; -extern idCVar cv_pm_stepvol_run; -extern idCVar cv_pm_stepvol_creep; -extern idCVar cv_pm_stepvol_crouch_walk; -extern idCVar cv_pm_stepvol_crouch_creep; -extern idCVar cv_pm_stepvol_crouch_run; -extern idCVar cv_pm_min_stepsound_interval; - -// Lightgem -extern idCVar cv_lg_distance; -extern idCVar cv_lg_xoffs; -extern idCVar cv_lg_yoffs; -extern idCVar cv_lg_zoffs; -extern idCVar cv_lg_oxoffs; -extern idCVar cv_lg_oyoffs; -extern idCVar cv_lg_ozoffs; -extern idCVar cv_lg_fov; -extern idCVar cv_lg_interleave; -extern idCVar cv_lg_hud; -extern idCVar cv_lg_weak; -extern idCVar cv_lg_player; -extern idCVar cv_lg_renderpasses; -extern idCVar cv_lg_debug; -extern idCVar cv_lg_model; -extern idCVar cv_lg_adjust; -extern idCVar cv_lg_split; -extern idCVar cv_lg_path; -extern idCVar cv_lg_crouch_modifier; -extern idCVar cv_lg_image_width; -extern idCVar cv_lg_screen_width; -extern idCVar cv_lg_screen_height; -extern idCVar cv_lg_velocity_mod_min_velocity; -extern idCVar cv_lg_velocity_mod_max_velocity; -extern idCVar cv_lg_velocity_mod_amount; - -extern idCVar cv_lg_fade_delay; // Added by J.C.Denton - -extern idCVar cv_empty_model; - -extern idCVar cv_tdm_s_doorDistanceAdd; -extern idCVar cv_tdm_gui_smallFontLimit; -extern idCVar cv_tdm_gui_mediumFontLimit; -extern idCVar cv_tdm_s_maxSoundsPerShader; - -// Lockpicking -extern idCVar cv_lp_pin_base_count; -extern idCVar cv_lp_sample_delay; -extern idCVar cv_lp_pick_timeout; -extern idCVar cv_lp_max_pick_attempts; -extern idCVar cv_lp_auto_pick; -extern idCVar cv_lp_randomize; -extern idCVar cv_lp_pawlow; -extern idCVar cv_lp_debug_hud; - -// Bow type -extern idCVar cv_bow_aimer; -// melee difficulty -extern idCVar cv_melee_difficulty; - -extern idCVar cv_door_auto_open_on_unlock; - -extern idCVar cv_dm_distance; - -// Ambient light method CVar -extern idCVar cv_ambient_method; - -// Volume of music speakers -extern idCVar cv_music_volume; - -// Tels: Volume of the "player voice" speaker -extern idCVar cv_voice_player_volume; -// Tels: Volume of the "speaker-from-off voice" speaker -extern idCVar cv_voice_from_off_volume; - -// angua: Velocity and sound volume of collisions -extern idCVar cv_moveable_collision; - -// Tels: LOD system: multiplier for the LOD distance to be used -extern idCVar cv_lod_bias; - -/** -* CVars added for Darkmod knockout and field of vision changes -*/ -extern idCVar cv_ai_fov_show; -extern idCVar cv_ai_ko_show; - -/** -* If != 0, use this ratio between FOV X and Y and ignore r_aspectRatio. -*/ -extern idCVar cv_r_fovRatio; - -/** Screen width * gui_Width = GUI width */ -extern idCVar cv_gui_Width; -/** Screen height * gui_Height = GUI height */ -extern idCVar cv_gui_Height; -/** Screen width * gui_CenterX = GUI center X */ -extern idCVar cv_gui_CenterX; -/** Screen height * gui_CenterY = GUI center Y */ -extern idCVar cv_gui_CenterY; - -/** -* End DarkMod cvars -**/ - -extern idCVar developer; - -extern idCVar g_cinematic; -extern idCVar g_cinematicMaxSkipTime; - -extern idCVar r_aspectRatio; - -extern idCVar g_monsters; -extern idCVar g_decals; -extern idCVar g_knockback; -extern idCVar g_skill; -extern idCVar g_gravity; -extern idCVar g_skipFX; -extern idCVar g_skipParticles; -extern idCVar g_bloodEffects; -extern idCVar g_projectileLights; -extern idCVar g_doubleVision; -extern idCVar g_muzzleFlash; - -extern idCVar g_disasm; -extern idCVar g_debugBounds; -extern idCVar g_debugAnim; -extern idCVar g_debugMove; -extern idCVar g_debugDamage; -extern idCVar g_debugWeapon; -extern idCVar g_debugScript; -extern idCVar g_debugMover; -extern idCVar g_debugTriggers; -extern idCVar g_debugCinematic; -extern idCVar g_stopTime; -extern idCVar g_armorProtection; -extern idCVar g_armorProtectionMP; -extern idCVar g_damageScale; -extern idCVar g_useDynamicProtection; -extern idCVar g_healthTakeTime; -extern idCVar g_healthTakeAmt; -extern idCVar g_healthTakeLimit; - -extern idCVar g_showPVS; -extern idCVar g_showTargets; -extern idCVar g_showTriggers; -extern idCVar g_showCollisionWorld; -extern idCVar g_showCollisionModels; -extern idCVar g_showCollisionTraces; -extern idCVar g_maxShowDistance; -extern idCVar g_showEntityInfo; -extern idCVar g_showviewpos; -extern idCVar g_showcamerainfo; -extern idCVar g_showTestModelFrame; -extern idCVar g_showActiveEntities; -extern idCVar g_showEnemies; - -extern idCVar g_frametime; -extern idCVar g_timeentities; - -extern idCVar g_timeModifier; - -extern idCVar ai_debugScript; -extern idCVar ai_debugMove; -extern idCVar ai_debugTrajectory; -extern idCVar ai_testPredictPath; -extern idCVar ai_showCombatNodes; -extern idCVar ai_showPaths; -extern idCVar ai_showObstacleAvoidance; -extern idCVar ai_blockedFailSafe; - -extern idCVar g_dvTime; -extern idCVar g_dvAmplitude; -extern idCVar g_dvFrequency; - -extern idCVar g_kickTime; -extern idCVar g_kickAmplitude; -extern idCVar g_blobTime; -extern idCVar g_blobSize; - -extern idCVar g_testHealthVision; -extern idCVar g_editEntityMode; -extern idCVar g_dragEntity; -extern idCVar g_dragDamping; -extern idCVar g_dragShowSelection; -extern idCVar g_dropItemRotation; - -extern idCVar g_vehicleVelocity; -extern idCVar g_vehicleForce; -extern idCVar g_vehicleSuspensionUp; -extern idCVar g_vehicleSuspensionDown; -extern idCVar g_vehicleSuspensionKCompress; -extern idCVar g_vehicleSuspensionDamping; -extern idCVar g_vehicleTireFriction; - -extern idCVar g_enablePortalSky; - - - -extern idCVar ik_enable; -extern idCVar ik_debug; - -extern idCVar af_useLinearTime; -extern idCVar af_useImpulseFriction; -extern idCVar af_useJointImpulseFriction; -extern idCVar af_useSymmetry; -extern idCVar af_skipSelfCollision; -extern idCVar af_skipLimits; -extern idCVar af_skipFriction; -extern idCVar af_forceFriction; -extern idCVar af_maxLinearVelocity; -extern idCVar af_maxAngularVelocity; -extern idCVar af_timeScale; -extern idCVar af_jointFrictionScale; -extern idCVar af_contactFrictionScale; -extern idCVar af_highlightBody; -extern idCVar af_highlightConstraint; -extern idCVar af_showTimings; -extern idCVar af_showConstraints; -extern idCVar af_showConstraintNames; -extern idCVar af_showConstrainedBodies; -extern idCVar af_showPrimaryOnly; -extern idCVar af_showTrees; -extern idCVar af_showLimits; -extern idCVar af_showBodies; -extern idCVar af_showBodyNames; -extern idCVar af_showMass; -extern idCVar af_showTotalMass; -extern idCVar af_showInertia; -extern idCVar af_showVelocity; -extern idCVar af_showActive; -extern idCVar af_testSolid; - -extern idCVar rb_showTimings; -extern idCVar rb_showBodies; -extern idCVar rb_showMass; -extern idCVar rb_showInertia; -extern idCVar rb_showVelocity; -extern idCVar rb_showActive; - -extern idCVar pm_jumpheight; -extern idCVar pm_stepsize; -//extern idCVar pm_crouchspeed; -extern idCVar pm_walkspeed; -//extern idCVar pm_runspeed; -extern idCVar pm_noclipspeed; -extern idCVar pm_spectatespeed; -extern idCVar pm_spectatebbox; -extern idCVar pm_usecylinder; -extern idCVar pm_minviewpitch; -extern idCVar pm_maxviewpitch; -// Commented out by Dram. Not needed as TDM does not use stamina -//extern idCVar pm_stamina; -//extern idCVar pm_staminathreshold; -//extern idCVar pm_staminarate; -extern idCVar pm_crouchheight; -extern idCVar pm_crouchviewheight; -extern idCVar pm_normalheight; -extern idCVar pm_normalviewheight; -extern idCVar pm_deadheight; -extern idCVar pm_deadviewheight; -extern idCVar pm_crouchrate; -extern idCVar pm_bboxwidth; -extern idCVar pm_crouchbob; -extern idCVar pm_walkbob; -extern idCVar pm_runbob; -extern idCVar pm_runpitch; -extern idCVar pm_runroll; -extern idCVar pm_bobup; -extern idCVar pm_bobpitch; -extern idCVar pm_bobroll; -extern idCVar pm_thirdPersonRange; -extern idCVar pm_thirdPersonHeight; -extern idCVar pm_thirdPersonAngle; -extern idCVar pm_thirdPersonClip; -extern idCVar pm_thirdPerson; -extern idCVar pm_thirdPersonDeath; -extern idCVar pm_modelView; -extern idCVar pm_airTics; - -extern idCVar g_showPlayerShadow; -extern idCVar g_showHud; -extern idCVar g_showProjectilePct; -extern idCVar g_showBrass; -extern idCVar g_gun_x; -extern idCVar g_gun_y; -extern idCVar g_gun_z; -extern idCVar g_viewNodalX; -extern idCVar g_viewNodalZ; -extern idCVar g_fov; -extern idCVar g_testDeath; -extern idCVar g_skipViewEffects; -extern idCVar g_mpWeaponAngleScale; - -extern idCVar g_testParticle; -extern idCVar g_testParticleName; - -extern idCVar g_testPostProcess; -extern idCVar g_rotoscope; - -extern idCVar g_testModelHead; -extern idCVar g_testModelHeadJoint; -extern idCVar g_testModelRotate; -extern idCVar g_testModelAnimate; -extern idCVar g_testModelBlend; -extern idCVar g_exportMask; -extern idCVar g_flushSave; - -extern idCVar aas_test; -extern idCVar aas_showAreas; -extern idCVar aas_showPath; -extern idCVar aas_showFlyPath; -extern idCVar aas_showWallEdges; -extern idCVar aas_showHideArea; -extern idCVar aas_pullPlayer; -extern idCVar aas_randomPullPlayer; -extern idCVar aas_goalArea; -extern idCVar aas_showPushIntoArea; - -extern idCVar net_clientPredictGUI; - -extern idCVar g_voteFlags; -extern idCVar g_mapCycle; -extern idCVar g_balanceTDM; - -extern idCVar si_timeLimit; -extern idCVar si_fragLimit; -extern idCVar si_gameType; -extern idCVar si_map; -extern idCVar si_spectators; - -extern idCVar net_clientSelfSmoothing; - -extern idCVar net_clientLagOMeter; - - -extern const char *si_gameTypeArgs[]; - - -extern const char *ui_skinArgs[]; - - -#ifdef MOD_WATERPHYSICS - -extern idCVar af_useBodyDensityBuoyancy; // MOD_WATERPHYSICS - -extern idCVar af_useFixedDensityBuoyancy; // MOD_WATERPHYSICS - -extern idCVar rb_showBuoyancy; // MOD_WATERPHYSICS - -#endif - -// HDR related - J.C.Denton - -extern idCVar r_postprocess; -extern idCVar r_postprocess_brightPassThreshold; -extern idCVar r_postprocess_brightPassOffset; -extern idCVar r_postprocess_colorCurveBias; -extern idCVar r_postprocess_colorCorrection; -extern idCVar r_postprocess_colorCorrectBias; -extern idCVar r_postprocess_sceneExposure; -extern idCVar r_postprocess_sceneGamma; -extern idCVar r_postprocess_debugMode; -extern idCVar r_postprocess_bloomKernelSize; -extern idCVar r_postprocess_bloomIntensity; -extern idCVar r_postprocess_desaturation; - -#endif /* !__SYS_CVAR_H__ */ diff --git a/game/gamesys/typeinfo.cpp b/game/gamesys/typeinfo.cpp deleted file mode 100644 index 4dcadd386..000000000 --- a/game/gamesys/typeinfo.cpp +++ /dev/null @@ -1,1413 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -// This is real evil but allows the code to inspect arbitrary class variables. -#define private public -#define protected public - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#ifdef ID_DEBUG_MEMORY -#include "GameTypeInfo.h" // Make sure this is up to date! -#else -#include "nogametypeinfo.h" -#endif - -// disabled because it's adds about 64MB to state dumps and takes a really long time -//#define DUMP_GAMELOCAL - - -typedef void (*WriteVariableType_t)( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - - -class idTypeInfoTools { -public: - static const classTypeInfo_t * FindClassInfo( const char *typeName ); - static const enumTypeInfo_t * FindEnumInfo( const char *typeName ); - static bool IsSubclassOf( const char *typeName, const char *superType ); - static void PrintType( const void *typePtr, const char *typeName ); - static void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ); - static void InitTypeVariables( const void *typePtr, const char *typeName, int value ); - static void WriteGameState( const char *fileName ); - static void CompareGameState( const char *fileName ); - -private: - static idFile * fp; - static int initValue; - static WriteVariableType_t Write; - static idLexer * src; - static bool typeError; - - static const char * OutputString( const char *string ); - static bool ParseTemplateArguments( idLexer &src, idStr &arguments ); - static void PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - static void WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - static void WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - static void InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - static void VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ); - static int WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ); - static void WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ); -}; - -idFile * idTypeInfoTools::fp = NULL; -int idTypeInfoTools::initValue = 0; -WriteVariableType_t idTypeInfoTools::Write = NULL; -idLexer * idTypeInfoTools::src = NULL; -bool idTypeInfoTools::typeError = false; - - -/* -================ -GetTypeVariableName -================ -*/ -const char *GetTypeVariableName( const char *typeName, int offset ) { - static char varName[1024]; - int i; - - for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { - if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { - if ( classTypeInfo[i].variables[0].name != NULL && offset >= classTypeInfo[i].variables[0].offset ) { - break; - } - typeName = classTypeInfo[i].superType; - if ( *typeName == '\0' ) { - return ""; - } - i = -1; - } - } - - const classTypeInfo_t &classInfo = classTypeInfo[i]; - - for ( i = 0; classInfo.variables[i].name != NULL; i++ ) { - if ( offset <= classInfo.variables[i].offset ) { - break; - } - } - if ( i == 0 ) { - idStr::snPrintf( varName, sizeof( varName ), "%s::", classInfo.typeName ); - } else { - idStr::snPrintf( varName, sizeof( varName ), "%s::%s", classInfo.typeName, classInfo.variables[i-1].name ); - } - return varName; -} - -/* -================ -idTypeInfoTools::FindClassInfo -================ -*/ -const classTypeInfo_t *idTypeInfoTools::FindClassInfo( const char *typeName ) { - int i; - - for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { - if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { - return &classTypeInfo[i]; - } - } - return NULL; -} - -/* -================ -idTypeInfoTools::FindEnumInfo -================ -*/ -const enumTypeInfo_t *idTypeInfoTools::FindEnumInfo( const char *typeName ) { - int i; - - for ( i = 0; enumTypeInfo[i].typeName != NULL; i++ ) { - if ( idStr::Cmp( typeName, enumTypeInfo[i].typeName ) == 0 ) { - return &enumTypeInfo[i]; - } - } - return NULL; -} - -/* -================ -idTypeInfoTools::IsSubclassOf -================ -*/ -bool idTypeInfoTools::IsSubclassOf( const char *typeName, const char *superType ) { - int i; - - while( *typeName != '\0' ) { - if ( idStr::Cmp( typeName, superType ) == 0 ) { - return true; - } - for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { - if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) { - typeName = classTypeInfo[i].superType; - break; - } - } - if ( classTypeInfo[i].typeName == NULL ) { - common->Warning( "super class %s not found", typeName ); - break; - } - } - return false; -} - -/* -================ -idTypeInfoTools::OutputString -================ -*/ -const char *idTypeInfoTools::OutputString( const char *string ) { - static int index = 0; - static char buffers[4][16384]; - char *out; - int i, c; - - out = buffers[index]; - index = ( index + 1 ) & 3; - - if ( string == NULL ) { - return NULL; - } - - for ( i = 0; i < sizeof( buffers[0] ) - 2; i++ ) { - c = *string++; - switch( c ) { - case '\0': out[i] = '\0'; return out; - case '\\': out[i++] = '\\'; out[i] = '\\'; break; - case '\n': out[i++] = '\\'; out[i] = 'n'; break; - case '\r': out[i++] = '\\'; out[i] = 'r'; break; - case '\t': out[i++] = '\\'; out[i] = 't'; break; - case '\v': out[i++] = '\\'; out[i] = 'v'; break; - default: out[i] = c; break; - } - } - out[i] = '\0'; - return out; -} - -/* -================ -idTypeInfoTools::ParseTemplateArguments -================ -*/ -bool idTypeInfoTools::ParseTemplateArguments( idLexer &src, idStr &arguments ) { - int indent; - idToken token; - - arguments = ""; - - if ( !src.ExpectTokenString( "<" ) ) { - return false; - } - - indent = 1; - while( indent ) { - if ( !src.ReadToken( &token ) ) { - break; - } - if ( token == "<" ) { - indent++; - } else if ( token == ">" ) { - indent--; - } else { - if ( arguments.Length() ) { - arguments += " "; - } - arguments += token; - } - } - return true; -} - -/* -================ -idTypeInfoTools::PrintType -================ -*/ -void idTypeInfoTools::PrintType( const void *typePtr, const char *typeName ) { - idTypeInfoTools::fp = NULL; - idTypeInfoTools::initValue = 0; - idTypeInfoTools::Write = PrintVariable; - WriteClass_r( typePtr, "", typeName, "", "", 0 ); -} - -/* -================ -idTypeInfoTools::WriteTypeToFile -================ -*/ -void idTypeInfoTools::WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) { - idTypeInfoTools::fp = fp; - idTypeInfoTools::initValue = 0; - idTypeInfoTools::Write = WriteVariable; - WriteClass_r( typePtr, "", typeName, "", "", 0 ); -} - -/* -================ -idTypeInfoTools::InitTypeVariables -================ -*/ -void idTypeInfoTools::InitTypeVariables( const void *typePtr, const char *typeName, int value ) { - idTypeInfoTools::fp = NULL; - idTypeInfoTools::initValue = value; - idTypeInfoTools::Write = InitVariable; - WriteClass_r( typePtr, "", typeName, "", "", 0 ); -} - -/* -================ -IsAllowedToChangedFromSaveGames -================ -*/ -bool IsAllowedToChangedFromSaveGames( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) { - if ( idStr::Icmp( scope, "idAnimator" ) == 0 ) { - if ( idStr::Icmp( varName, "forceUpdate" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "lastTransformTime" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "AFPoseTime" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "frameBounds" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) { - if ( idStr::Icmp( varName, "touchCount" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) { - if ( idStr::Icmp( varName, "numPVSAreas" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "renderView" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idBrittleFracture" ) == 0 ) { - if ( idStr::Icmp( varName, "changed" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idPhysics_AF" ) == 0 ) { - return true; - } else if ( idStr::Icmp( scope, "renderEntity_t" ) == 0 ) { - // These get fixed up when UpdateVisuals is called - if ( idStr::Icmp( varName, "origin" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "axis" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "bounds" ) == 0 ) { - return true; - } - } - - if ( idStr::Icmpn( prefix, "idAFEntity_Base::af.idAF::physicsObj.idPhysics_AF", 49) == 0 ) { - return true; - } - - return false; -} - -/* -================ -IsRenderHandleVariable -================ -*/ -bool IsRenderHandleVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) { - if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) { - if ( idStr::Icmp( varName, "renderModelHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idFXLocalAction" ) == 0 ) { - if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) { - if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idLight" ) == 0 ) { - if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idAFEntity_Gibbable" ) == 0 ) { - if ( idStr::Icmp( varName, "skeletonModelDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idAFEntity_SteamPipe" ) == 0 ) { - if ( idStr::Icmp( varName, "steamModelHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idItem" ) == 0 ) { - if ( idStr::Icmp( varName, "itemShellHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idExplodingBarrel" ) == 0 ) { - if ( idStr::Icmp( varName, "particleModelDefHandle" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idProjectile" ) == 0 ) { - if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idSmokeParticles" ) == 0 ) { - if ( idStr::Icmp( varName, "renderEntityHandle" ) == 0 ) { - return true; - } - } else if ( idStr::Icmp( scope, "idWeapon" ) == 0 ) { - if ( idStr::Icmp( varName, "muzzleFlashHandle" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "worldMuzzleFlashHandle" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "guiLightHandle" ) == 0 ) { - return true; - } - if ( idStr::Icmp( varName, "nozzleGlowHandle" ) == 0 ) { - return true; - } - } - return false; -} - -/* -================ -idTypeInfoTools::PrintVariable -================ -*/ -void idTypeInfoTools::PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { - common->Printf( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); -} - -/* -================ -idTypeInfoTools::WriteVariable -================ -*/ -void idTypeInfoTools::WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { - - for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) { - if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 || - idStr::Icmpn( value+i+1, "IND", 3 ) == 0 || - idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 || - idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 || - idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) { - common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value ); - break; - } - } - fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); -} - -/* -================ -idTypeInfoTools::WriteGameStateVariable -================ -*/ -void idTypeInfoTools::WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { - - for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) { - if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 || - idStr::Icmpn( value+i+1, "IND", 3 ) == 0 || - idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 || - idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 || - idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) { - common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value ); - break; - } - } - - if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { - return; - } - - if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) { - return; - } - - fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value ); -} - -/* -================ -idTypeInfoTools::InitVariable -================ -*/ -void idTypeInfoTools::InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { - if ( varPtr != NULL && varSize > 0 ) { - // NOTE: skip renderer handles - if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { - return; - } - memset( const_cast(varPtr), initValue, varSize ); - } -} - -/* -================ -idTypeInfoTools::VerifyVariable -================ -*/ -void idTypeInfoTools::VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) { - idToken token; - - if ( typeError ) { - return; - } - - src->SkipUntilString( "=" ); - src->ExpectTokenType( TT_STRING, 0, &token ); - if ( token.Cmp( value ) != 0 ) { - - // NOTE: skip several things - - if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) { - return; - } - - if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) { - return; - } - - src->Warning( "state diff for %s%s::%s%s\n%s\n%s", prefix, scope, varName, postfix, token.c_str(), value ); - typeError = true; - } -} - -/* -================ -idTypeInfoTools::WriteVariable_r -================ -*/ -int idTypeInfoTools::WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ) { - int i, isPointer, typeSize; - idLexer typeSrc; - idToken token; - idStr typeString, templateArgs; - - isPointer = 0; - typeSize = -1; - - // create a type string without 'const', 'mutable', 'class', 'struct', 'union' - typeSrc.LoadMemory( varType, idStr::Length( varType ), varName ); - while( typeSrc.ReadToken( &token ) ) { - if ( token != "const" && token != "mutable" && token != "class" && token != "struct" && token != "union" ) { - typeString += token + " "; - } - } - typeString.StripTrailing( ' ' ); - typeSrc.FreeSource(); - - // if this is an array - if ( typeString[typeString.Length() - 1] == ']' ) { - for ( i = typeString.Length(); i > 0 && typeString[i - 1] != '['; i-- ) { - } - int num = atoi( &typeString[i] ); - idStr listVarType = typeString; - listVarType.CapLength( i - 1 ); - typeSize = 0; - for ( i = 0; i < num; i++ ) { - idStr listVarName = va( "%s[%d]", varName, i ); - int size = WriteVariable_r( varPtr, listVarName, listVarType, scope, prefix, pointerDepth ); - typeSize += size; - if ( size == -1 ) { - break; - } - varPtr = (void *)( ( (byte *) varPtr ) + size ); - } - return typeSize; - } - - // if this is a pointer - isPointer = 0; - for ( i = typeString.Length(); i > 0 && typeString[i - 1] == '*'; i -= 2 ) { - if ( varPtr == (void *)0xcdcdcdcd || ( varPtr != NULL && *((unsigned long *)varPtr) == 0xcdcdcdcd ) ) { - common->Warning( "%s%s::%s%s references uninitialized memory", prefix, scope, varName, "" ); - return typeSize; - } - if ( varPtr != NULL ) { - varPtr = *((void **)varPtr); - } - isPointer++; - } - - if ( varPtr == NULL ) { - Write( varName, varType, scope, prefix, "", "", varPtr, 0 ); - return sizeof( void * ); - } - - typeSrc.LoadMemory( typeString, typeString.Length(), varName ); - - if ( !typeSrc.ReadToken( &token ) ) { - Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); - return -1; - } - - // get full type - while( typeSrc.CheckTokenString( "::" ) ) { - idToken newToken; - typeSrc.ExpectTokenType( TT_NAME, 0, &newToken ); - token += "::" + newToken; - } - - if ( token == "signed" ) { - - if ( !typeSrc.ReadToken( &token ) ) { - Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); - return -1; - } - if ( token == "char" ) { - - typeSize = sizeof( signed char ); - Write( varName, varType, scope, prefix, "", va( "%d", *((signed char *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "short" ) { - - typeSize = sizeof( signed short ); - Write( varName, varType, scope, prefix, "", va( "%d", *((signed short *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "int" ) { - - typeSize = sizeof( signed int ); - Write( varName, varType, scope, prefix, "", va( "%d", *((signed int *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "long" ) { - - typeSize = sizeof( signed long ); - Write( varName, varType, scope, prefix, "", va( "%ld", *((signed long *)varPtr) ), varPtr, typeSize ); - - } else { - - Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); - return -1; - } - - } else if ( token == "unsigned" ) { - - if ( !typeSrc.ReadToken( &token ) ) { - Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); - return -1; - } - if ( token == "char" ) { - - typeSize = sizeof( unsigned char ); - Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned char *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "short" ) { - - typeSize = sizeof( unsigned short ); - Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned short *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "int" ) { - - typeSize = sizeof( unsigned int ); - Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned int *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "long" ) { - - typeSize = sizeof( unsigned long ); - Write( varName, varType, scope, prefix, "", va( "%lu", *((unsigned long *)varPtr) ), varPtr, typeSize ); - - } else { - - Write( varName, varType, scope, prefix, "", va( "", varType ), varPtr, 0 ); - return -1; - } - - } else if ( token == "byte" ) { - - typeSize = sizeof( byte ); - Write( varName, varType, scope, prefix, "", va( "%d", *((byte *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "word" ) { - - typeSize = sizeof( word ); - Write( varName, varType, scope, prefix, "", va( "%d", *((word *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "dword" ) { - - typeSize = sizeof( dword ); - Write( varName, varType, scope, prefix, "", va( "%d", *((dword *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "bool" ) { - - typeSize = sizeof( bool ); - Write( varName, varType, scope, prefix, "", va( "%d", *((bool *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "char" ) { - - typeSize = sizeof( char ); - Write( varName, varType, scope, prefix, "", va( "%d", *((char *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "short" ) { - - typeSize = sizeof( short ); - Write( varName, varType, scope, prefix, "", va( "%d", *((short *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "int" ) { - - typeSize = sizeof( int ); - Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "long" ) { - - typeSize = sizeof( long ); - Write( varName, varType, scope, prefix, "", va( "%ld", *((long *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "float" ) { - - typeSize = sizeof( float ); - Write( varName, varType, scope, prefix, "", idStr( *((float *)varPtr) ).c_str(), varPtr, typeSize ); - - } else if ( token == "double" ) { - - typeSize = sizeof( double ); - Write( varName, varType, scope, prefix, "", idStr( (float)*((double *)varPtr) ).c_str(), varPtr, typeSize ); - - } else if ( token == "idVec2" ) { - - typeSize = sizeof( idVec2 ); - Write( varName, varType, scope, prefix, "", ((idVec2 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idVec3" ) { - - typeSize = sizeof( idVec3 ); - Write( varName, varType, scope, prefix, "", ((idVec3 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idVec4" ) { - - typeSize = sizeof( idVec4 ); - Write( varName, varType, scope, prefix, "", ((idVec4 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idVec5" ) { - - typeSize = sizeof( idVec5 ); - Write( varName, varType, scope, prefix, "", ((idVec5 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idVec6" ) { - - typeSize = sizeof( idVec6 ); - Write( varName, varType, scope, prefix, "", ((idVec6 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idVecX" ) { - - const idVecX *vec = ((idVecX *)varPtr); - if ( vec->ToFloatPtr() != NULL ) { - Write( varName, varType, scope, prefix, "", vec->ToString( 8 ), vec->ToFloatPtr(), vec->GetSize() * sizeof( float ) ); - } else { - Write( varName, varType, scope, prefix, "", "", varPtr, 0 ); - } - typeSize = sizeof( idVecX ); - - } else if ( token == "idMat2" ) { - - typeSize = sizeof( idMat2 ); - Write( varName, varType, scope, prefix, "", ((idMat2 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idMat3" ) { - - typeSize = sizeof( idMat3 ); - Write( varName, varType, scope, prefix, "", ((idMat3 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idMat4" ) { - - typeSize = sizeof( idMat4 ); - Write( varName, varType, scope, prefix, "", ((idMat4 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idMat5" ) { - - typeSize = sizeof( idMat5 ); - Write( varName, varType, scope, prefix, "", ((idMat5 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idMat6" ) { - - typeSize = sizeof( idMat6 ); - Write( varName, varType, scope, prefix, "", ((idMat6 *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idMatX" ) { - - typeSize = sizeof( idMatX ); - const idMatX *mat = ((idMatX *)varPtr); - if ( mat->ToFloatPtr() != NULL ) { - Write( varName, varType, scope, prefix, "", mat->ToString( 8 ), mat->ToFloatPtr(), mat->GetNumColumns() * mat->GetNumRows() * sizeof( float ) ); - } else { - Write( varName, varType, scope, prefix, "", "", NULL, 0 ); - } - - } else if ( token == "idAngles" ) { - - typeSize = sizeof( idAngles ); - Write( varName, varType, scope, prefix, "", ((idAngles *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idQuat" ) { - - typeSize = sizeof( idQuat ); - Write( varName, varType, scope, prefix, "", ((idQuat *)varPtr)->ToString( 8 ), varPtr, typeSize ); - - } else if ( token == "idBounds" ) { - - typeSize = sizeof( idBounds ); - const idBounds *bounds = ((idBounds *)varPtr); - if ( bounds->IsCleared() ) { - Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); - } else { - Write( varName, varType, scope, prefix, "", va( "(%s)-(%s)", (*bounds)[0].ToString( 8 ), (*bounds)[1].ToString( 8 ) ), varPtr, typeSize ); - } - - } else if ( token == "idList" ) { - - idList *list = ((idList *)varPtr); - Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 ); - // NOTE: we don't care about the amount of memory allocated - //Write( varName, varType, scope, prefix, ".size", va( "%d", list->Size() ), NULL, 0 ); - Write( varName, varType, scope, prefix, ".granularity", va( "%d", list->GetGranularity() ), NULL, 0 ); - - if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) { - void *listVarPtr = list->Ptr(); - for ( i = 0; i < list->Num(); i++ ) { - idStr listVarName = va( "%s[%d]", varName, i ); - int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth ); - if ( size == -1 ) { - break; - } - listVarPtr = (void *)( ( (byte *) listVarPtr ) + size ); - } - } - - typeSize = sizeof( idList ); - - } else if ( token == "idStaticList" ) { - - idStaticList *list = ((idStaticList *)varPtr); - Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 ); - - int totalSize = 0; - if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) { - void *listVarPtr = list->Ptr(); - for ( i = 0; i < list->Num(); i++ ) { - idStr listVarName = va( "%s[%d]", varName, i ); - int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth ); - if ( size == -1 ) { - break; - } - totalSize += size; - listVarPtr = (void *)( ( (byte *) listVarPtr ) + size ); - } - } - - typeSize = sizeof( int ) + totalSize; - - } else if ( token == "idLinkList" ) { - - // FIXME: implement - typeSize = sizeof( idLinkList ); - Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); - - } else if ( token == "idStr" ) { - - typeSize = sizeof( idStr ); - - const idStr *str = ((idStr *)varPtr); - Write( varName, varType, scope, prefix, "", OutputString( str->c_str() ), str->c_str(), str->Length() ); - - } else if ( token == "idStrList" ) { - - typeSize = sizeof( idStrList ); - - const idStrList *list = ((idStrList *)varPtr); - if ( list->Num() ) { - for ( i = 0; i < list->Num(); i++ ) { - Write( varName, varType, scope, prefix, va("[%d]", i ), OutputString( (*list)[i].c_str() ), (*list)[i].c_str(), (*list)[i].Length() ); - } - } else { - Write( varName, varType, scope, prefix, "", "", NULL, 0 ); - } - - } else if ( token == "idDict" ) { - - typeSize = sizeof( idDict ); - - const idDict *dict = ((idDict *)varPtr); - if ( dict->GetNumKeyVals() ) { - for ( i = 0; i < dict->GetNumKeyVals(); i++ ) { - const idKeyValue *kv = dict->GetKeyVal( i ); - Write( varName, varType, scope, prefix, va("[%d]", i ), va( "\'%s\' \'%s\'", OutputString( kv->GetKey().c_str() ), OutputString( kv->GetValue().c_str() ) ), NULL, 0 ); - } - } else { - Write( varName, varType, scope, prefix, "", "", NULL, 0 ); - } - - } else if ( token == "idExtrapolate" ) { - - const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); - Write( varName, varType, scope, prefix, ".extrapolationType", idStr( interpolate->GetExtrapolationType() ).c_str(), &interpolate->extrapolationType, sizeof( interpolate->extrapolationType ) ); - Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); - Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) ); - - if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { - if ( templateArgs == "int" ) { - const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); - Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) ); - typeSize = sizeof( idExtrapolate ); - } else if ( templateArgs == "float" ) { - const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); - Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) ); - typeSize = sizeof( idExtrapolate ); - } else if ( templateArgs == "idVec3" ) { - const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); - Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) ); - typeSize = sizeof( idExtrapolate ); - } else if ( templateArgs == "idAngles" ) { - const idExtrapolate *interpolate = ((idExtrapolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) ); - Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) ); - typeSize = sizeof( idExtrapolate ); - } else { - Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); - } - } - - } else if ( token == "idInterpolate" ) { - - const idInterpolate *interpolate = ((idInterpolate *)varPtr); - Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); - Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) ); - - if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { - if ( templateArgs == "int" ) { - const idInterpolate *interpolate = ((idInterpolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolate ); - } else if ( templateArgs == "float" ) { - const idInterpolate *interpolate = ((idInterpolate *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolate ); - } else { - Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); - } - } - - } else if ( token == "idInterpolateAccelDecelLinear" ) { - - const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); - Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); - Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) ); - Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) ); - Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) ); - - if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { - if ( templateArgs == "int" ) { - const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolateAccelDecelLinear ); - } else if ( templateArgs == "float" ) { - const idInterpolateAccelDecelLinear *interpolate = ((idInterpolateAccelDecelLinear *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolateAccelDecelLinear ); - } else { - Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); - } - } - - } else if ( token == "idInterpolateAccelDecelSine" ) { - - const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); - Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) ); - Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) ); - Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) ); - Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) ); - - if ( ParseTemplateArguments( typeSrc, templateArgs ) ) { - if ( templateArgs == "int" ) { - const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolateAccelDecelSine ); - } else if ( templateArgs == "float" ) { - const idInterpolateAccelDecelSine *interpolate = ((idInterpolateAccelDecelSine *)varPtr); - Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) ); - Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) ); - typeSize = sizeof( idInterpolateAccelDecelSine ); - } else { - Write( varName, varType, scope, prefix, "", va( "", templateArgs.c_str() ), NULL, 0 ); - } - } - - } else if ( token == "idUserInterface" ) { - - typeSize = sizeof( idUserInterface ); - const idUserInterface *gui = ((idUserInterface *)varPtr); - Write( varName, varType, scope, prefix, "", gui->Name(), varPtr, sizeof( varPtr ) ); - - } else if ( token == "idRenderModel" ) { - - typeSize = sizeof( idRenderModel ); - const idRenderModel *model = ((idRenderModel *)varPtr); - Write( varName, varType, scope, prefix, "", model->Name(), varPtr, sizeof( varPtr ) ); - - } else if ( token == "qhandle_t" ) { - - typeSize = sizeof( int ); - Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "cmHandle_t" ) { - - typeSize = sizeof( int ); - Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize ); - - } else if ( token == "idEntityPtr" ) { - - typeSize = sizeof( idEntityPtr ); - - const idEntityPtr *entPtr = ((idEntityPtr *)varPtr); - if ( entPtr->GetEntity() ) { - idEntity *entity = entPtr->GetEntity(); - Write( varName, varType, scope, prefix, ".", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), varPtr, typeSize ); - } else { - Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); - } - - } else if ( token == "idEntity::entityFlags_s" ) { - - const idEntity::entityFlags_s *flags = ((idEntity::entityFlags_s *)varPtr); - Write( varName, varType, scope, prefix, ".notarget", flags->notarget ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".noknockback", flags->noknockback ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".takedamage", flags->takedamage ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".hidden", flags->hidden ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".bindOrientated", flags->bindOrientated ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".solidForTeam", flags->solidForTeam ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".forcePhysicsUpdate", flags->forcePhysicsUpdate ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".selected", flags->selected ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".neverDormant", flags->neverDormant ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".isDormant", flags->isDormant ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".hasAwakened", flags->hasAwakened ? "true" : "false", NULL, 0 ); - Write( varName, varType, scope, prefix, ".networkSync", flags->networkSync ? "true" : "false", NULL, 0 ); - typeSize = sizeof( idEntity::entityFlags_s ); - - } else if ( token == "idScriptBool" ) { - - typeSize = sizeof( idScriptBool ); - - const idScriptBool *scriptBool = ((idScriptBool *)varPtr); - if ( scriptBool->IsLinked() ) { - Write( varName, varType, scope, prefix, "", ( *scriptBool != 0 ) ? "true" : "false", varPtr, typeSize ); - } else { - Write( varName, varType, scope, prefix, "", "", varPtr, typeSize ); - } - - } else { - - const classTypeInfo_t *classTypeInfo = FindClassInfo( scope + ( "::" + token ) ); - if ( classTypeInfo == NULL ) { - classTypeInfo = FindClassInfo( token ); - } - if ( classTypeInfo != NULL ) { - - typeSize = classTypeInfo->size; - - if ( !isPointer ) { - - char newPrefix[1024]; - idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s.", prefix, scope, varName ); - WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth ); - - } else if ( token == "idAnim" ) { - - const idAnim *anim = ((idAnim*)varPtr); - Write( varName, varType, scope, prefix, "", anim->Name(), NULL, 0 ); - - } else if ( token == "idPhysics" ) { - - const idPhysics *physics = ((idPhysics*)varPtr); - Write( varName, varType, scope, prefix, "", physics->GetType()->classname, NULL, 0 ); - - } else if ( IsSubclassOf( token, "idEntity" ) ) { - - const idEntity *entity = ((idEntity*)varPtr); - Write( varName, varType, scope, prefix, "", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), NULL, 0 ); - - } else if ( IsSubclassOf( token, "idDecl" ) ) { - - const idDecl *decl = ((idDecl *)varPtr); - Write( varName, varType, scope, prefix, "", decl->GetName(), NULL, 0 ); - - } else if ( pointerDepth == 0 && ( - token == "idAFBody" || - token == "idAFTree" || - token == "idClipModel" || - IsSubclassOf( token, "idAFConstraint" ) - ) ) { - - char newPrefix[1024]; - idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s->", prefix, scope, varName ); - WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth + 1 ); - - } else { - - Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); - return -1; - } - } else { - const enumTypeInfo_t *enumTypeInfo = FindEnumInfo( scope + ( "::" + token ) ); - if ( enumTypeInfo == NULL ) { - enumTypeInfo = FindEnumInfo( token ); - } - if ( enumTypeInfo != NULL ) { - - typeSize = sizeof( int ); // NOTE: assuming sizeof( enum ) is sizeof( int ) - - for ( i = 0; enumTypeInfo->values[i].name != NULL; i++ ) { - if ( *((int *)varPtr) == enumTypeInfo->values[i].value ) { - break; - } - } - if ( enumTypeInfo->values[i].name != NULL ) { - Write( varName, varType, scope, prefix, "", enumTypeInfo->values[i].name, NULL, 0 ); - } else { - Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), NULL, 0 ); - } - - } else { - Write( varName, varType, scope, prefix, "", va( "", varType ), NULL, 0 ); - return -1; - } - } - } - - i = 0; - do { - if ( *((unsigned long *)varPtr) == 0xcdcdcdcd ) { - common->Warning( "%s%s::%s%s uses uninitialized memory", prefix, scope, varName, "" ); - break; - } - } while( ++i < typeSize ); - - if ( isPointer ) { - return sizeof( void * ); - } - return typeSize; -} - -/* -================ -idTypeInfoTools::WriteClass_r -================ -*/ -void idTypeInfoTools::WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ) { - int i; - - const classTypeInfo_t *classInfo = FindClassInfo( classType ); - if ( !classInfo ) { - return; - } - if ( *classInfo->superType != '\0' ) { - WriteClass_r( classPtr, className, classInfo->superType, scope, prefix, pointerDepth ); - } - - for ( i = 0; classInfo->variables[i].name != NULL; i++ ) { - const classVariableInfo_t &classVar = classInfo->variables[i]; - - void *varPtr = (void *) (((byte *)classPtr) + classVar.offset); - - WriteVariable_r( varPtr, classVar.name, classVar.type, classType, prefix, pointerDepth ); - } -} - -/* -================ -idTypeInfoTools::WriteGameState -================ -*/ -void idTypeInfoTools::WriteGameState( const char *fileName ) { - int i, num; - idFile *file; - - file = fileSystem->OpenFileWrite( fileName ); - if ( !file ) { - common->Warning( "couldn't open %s", fileName ); - return; - } - - fp = file; - Write = WriteGameStateVariable; //WriteVariable; - -#ifdef DUMP_GAMELOCAL - - file->WriteFloatString( "\ngameLocal {\n" ); - WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 ); - file->WriteFloatString( "}\n" ); - -#endif - - for ( num = i = 0; i < gameLocal.num_entities; i++ ) { - idEntity *ent = gameLocal.entities[i]; - if ( ent == NULL ) { - continue; - } - file->WriteFloatString( "\nentity %d %s {\n", i, ent->GetType()->classname ); - WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 ); - file->WriteFloatString( "}\n" ); - num++; - } - - fileSystem->CloseFile( file ); - - common->Printf( "%d entities written\n", num ); -} - -/* -================ -idTypeInfoTools::CompareGameState -================ -*/ -void idTypeInfoTools::CompareGameState( const char *fileName ) { - int entityNum; - idToken token; - - src = new idLexer(); - src->SetFlags( LEXFL_NOSTRINGESCAPECHARS ); - - if ( !src->LoadFile( fileName ) ) { - common->Warning( "couldn't load %s", fileName ); - delete src; - src = NULL; - return; - } - - fp = NULL; - Write = VerifyVariable; - -#ifdef DUMP_GAMELOCAL - - if ( !src->ExpectTokenString( "gameLocal" ) || !src->ExpectTokenString( "{" ) ) { - delete src; - src = NULL; - return; - } - - WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 ); - - if ( !src->ExpectTokenString( "}" ) ) { - delete src; - src = NULL; - return; - } - -#endif - - while( src->ReadToken( &token ) ) { - if ( token != "entity" ) { - break; - } - if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) { - break; - } - - entityNum = token.GetIntValue(); - - if ( entityNum < 0 || entityNum >= gameLocal.num_entities ) { - src->Warning( "entity number %d out of range", entityNum ); - break; - } - - typeError = false; - - idEntity *ent = gameLocal.entities[entityNum]; - if ( !ent ) { - src->Warning( "entity %d is not spawned", entityNum ); - src->SkipBracedSection( true ); - continue; - } - - if ( !src->ExpectTokenType( TT_NAME, 0, &token ) ) { - break; - } - - if ( token.Cmp( ent->GetType()->classname ) != 0 ) { - src->Warning( "entity %d has wrong type", entityNum ); - src->SkipBracedSection( true ); - continue; - } - - if ( !src->ExpectTokenString( "{" ) ) { - src->Warning( "entity %d missing leading {", entityNum ); - break; - } - - WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 ); - - if ( !src->SkipBracedSection( false ) ) { - src->Warning( "entity %d missing trailing }", entityNum ); - break; - } - } - - delete src; - src = NULL; -} - -/* -================ -WriteGameState_f -================ -*/ -void WriteGameState_f( const idCmdArgs &args ) { - idStr fileName; - - if ( args.Argc() > 1 ) { - fileName = args.Argv(1); - } else { - fileName = "GameState.txt"; - } - fileName.SetFileExtension( "gameState.txt" ); - - idTypeInfoTools::WriteGameState( fileName ); -} - -/* -================ -CompareGameState_f -================ -*/ -void CompareGameState_f( const idCmdArgs &args ) { - idStr fileName; - - if ( args.Argc() > 1 ) { - fileName = args.Argv(1); - } else { - fileName = "GameState.txt"; - } - fileName.SetFileExtension( "gameState.txt" ); - - idTypeInfoTools::CompareGameState( fileName ); -} - -/* -================ -TestSaveGame_f -================ -*/ -void TestSaveGame_f( const idCmdArgs &args ) { - idStr name; - - if ( args.Argc() <= 1 ) { - gameLocal.Printf( "testSaveGame \n" ); - return; - } - - name = args.Argv( 1 ); - - try { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "map %s", name.c_str() ) ); - name.Replace( "\\", "_" ); - name.Replace( "/", "_" ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "saveGame test_%s", name.c_str() ) ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "loadGame test_%s", name.c_str() ) ); - } - catch( idException & ) { - // an ERR_DROP was thrown - } - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "quit" ); -} - -/* -================ -WriteTypeToFile -================ -*/ -void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) { - idTypeInfoTools::WriteTypeToFile( fp, typePtr, typeName ); -} - -/* -================ -PrintType -================ -*/ -void PrintType( const void *typePtr, const char *typeName ) { - idTypeInfoTools::PrintType( typePtr, typeName ); -} - -/* -================ -InitTypeVariables -================ -*/ -void InitTypeVariables( const void *typePtr, const char *typeName, int value ) { - idTypeInfoTools::InitTypeVariables( typePtr, typeName, value ); -} - -/* -================ -ListTypeInfo_f -================ -*/ -int SortTypeInfoByName( const int *a, const int *b ) { - return idStr::Icmp( classTypeInfo[*a].typeName, classTypeInfo[*b].typeName ); -} - -int SortTypeInfoBySize( const int *a, const int *b ) { - if ( classTypeInfo[*a].size < classTypeInfo[*b].size ) { - return -1; - } - if ( classTypeInfo[*a].size > classTypeInfo[*b].size ) { - return 1; - } - return 0; -} - -void ListTypeInfo_f( const idCmdArgs &args ) { - int i, j; - idList index; - - common->Printf( "%-32s : %-32s size (B)\n", "type name", "super type name" ); - for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { - index.Append( i ); - } - - if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "size" ) == 0 ) { - index.Sort( SortTypeInfoBySize ); - } else { - index.Sort( SortTypeInfoByName ); - } - - for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) { - j = index[i]; - common->Printf( "%-32s : %-32s %d\n", classTypeInfo[j].typeName, classTypeInfo[j].superType, classTypeInfo[j].size ); - } -} diff --git a/game/gamesys/typeinfo.h b/game/gamesys/typeinfo.h deleted file mode 100644 index 17c902e49..000000000 --- a/game/gamesys/typeinfo.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SYS_TYPEINFO_H__ -#define __SYS_TYPEINFO_H__ - -/* -=================================================================================== - - Game Type Info - -=================================================================================== -*/ - -const char * GetTypeVariableName( const char *typeName, int offset ); - -void PrintType( const void *typePtr, const char *typeName ); -void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ); -void InitTypeVariables( const void *typePtr, const char *typeName, int value ); - -void ListTypeInfo_f( const idCmdArgs &args ); - -void WriteGameState_f( const idCmdArgs &args ); -void CompareGameState_f( const idCmdArgs &args ); -void TestSaveGame_f( const idCmdArgs &args ); - -#endif /* !__SYS_TYPEINFO_H__ */ diff --git a/game/ik.cpp b/game/ik.cpp deleted file mode 100644 index 360383cd3..000000000 --- a/game/ik.cpp +++ /dev/null @@ -1,1114 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -=============================================================================== - - idIK - -=============================================================================== -*/ - -/* -================ -idIK::idIK -================ -*/ -idIK::idIK( void ) { - ik_activate = false; - initialized = false; - self = NULL; - animator = NULL; - modifiedAnim = 0; - modelOffset.Zero(); -} - -/* -================ -idIK::~idIK -================ -*/ -idIK::~idIK( void ) { -} - -/* -================ -idIK::Save -================ -*/ -void idIK::Save( idSaveGame *savefile ) const { - savefile->WriteBool( initialized ); - savefile->WriteBool( ik_activate ); - savefile->WriteObject( self ); - savefile->WriteString( animator != NULL && animator->GetAnim( modifiedAnim ) ? animator->GetAnim( modifiedAnim )->Name() : "" ); - savefile->WriteVec3( modelOffset ); -} - -/* -================ -idIK::Restore -================ -*/ -void idIK::Restore( idRestoreGame *savefile ) { - idStr anim; - - savefile->ReadBool( initialized ); - savefile->ReadBool( ik_activate ); - savefile->ReadObject( reinterpret_cast( self ) ); - savefile->ReadString( anim ); - savefile->ReadVec3( modelOffset ); - - if ( self ) { - animator = self->GetAnimator(); - if ( animator == NULL || animator->ModelDef() == NULL ) { - gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no model set.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - } - modifiedAnim = animator->GetAnim( anim ); - if ( modifiedAnim == 0 ) { - gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no modified animation.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - } - } else { - animator = NULL; - modifiedAnim = 0; - } -} - -/* -================ -idIK::IsInitialized -================ -*/ -bool idIK::IsInitialized( void ) const { - return initialized && ik_enable.GetBool(); -} - -/* -================ -idIK::Init -================ -*/ -bool idIK::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { - idRenderModel *model; - - if ( self == NULL ) { - return false; - } - - this->self = self; - - animator = self->GetAnimator(); - if ( animator == NULL || animator->ModelDef() == NULL ) { - gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - if ( animator->ModelDef()->ModelHandle() == NULL ) { - gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) uses default model.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - model = animator->ModelHandle(); - if ( model == NULL ) { - gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - modifiedAnim = animator->GetAnim( anim ); - if ( modifiedAnim == 0 ) { - gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no modified animation.", - self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) ); - return false; - } - - this->modelOffset = modelOffset; - - return true; -} - -/* -================ -idIK::Evaluate -================ -*/ -void idIK::Evaluate( void ) { -} - -/* -================ -idIK::ClearJointMods -================ -*/ -void idIK::ClearJointMods( void ) { - ik_activate = false; -} - -/* -================ -idIK::SolveTwoBones -================ -*/ -bool idIK::SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos ) { - float length, lengthSqr, lengthInv, x, y; - idVec3 vec0, vec1; - - vec0 = endPos - startPos; - lengthSqr = vec0.LengthSqr(); - lengthInv = idMath::InvSqrt( lengthSqr ); - length = lengthInv * lengthSqr; - - // if the start and end position are too far out or too close to each other - if ( length > len0 + len1 || length < idMath::Fabs( len0 - len1 ) ) { - jointPos = startPos + 0.5f * vec0; - return false; - } - - vec0 *= lengthInv; - vec1 = dir - vec0 * dir * vec0; - vec1.Normalize(); - - x = ( length * length + len0 * len0 - len1 * len1 ) * ( 0.5f * lengthInv ); - y = idMath::Sqrt( len0 * len0 - x * x ); - - jointPos = startPos + x * vec0 + y * vec1; - - return true; -} - -/* -================ -idIK::GetBoneAxis -================ -*/ -float idIK::GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis ) { - float length; - axis[0] = endPos - startPos; - length = axis[0].Normalize(); - axis[1] = dir - axis[0] * dir * axis[0]; - axis[1].Normalize(); - axis[2].Cross( axis[1], axis[0] ); - return length; -} - - -/* -=============================================================================== - - idIK_Walk - -=============================================================================== -*/ - -/* -================ -idIK_Walk::idIK_Walk -================ -*/ -idIK_Walk::idIK_Walk() { - int i; - - initialized = false; - footModel = NULL; - numLegs = 0; - enabledLegs = 0; - for ( i = 0; i < MAX_LEGS; i++ ) { - footJoints[i] = INVALID_JOINT; - ankleJoints[i] = INVALID_JOINT; - kneeJoints[i] = INVALID_JOINT; - hipJoints[i] = INVALID_JOINT; - dirJoints[i] = INVALID_JOINT; - hipForward[i].Zero(); - kneeForward[i].Zero(); - upperLegLength[i] = 0.0f; - lowerLegLength[i] = 0.0f; - upperLegToHipJoint[i].Identity(); - lowerLegToKneeJoint[i].Identity(); - oldAnkleHeights[i] = 0.0f; - } - waistJoint = INVALID_JOINT; - - smoothing = 0.75f; - waistSmoothing = 0.5f; - footShift = 0.0f; - waistShift = 0.0f; - minWaistFloorDist = 0.0f; - minWaistAnkleDist = 0.0f; - footUpTrace = 32.0f; - footDownTrace = 32.0f; - tiltWaist = false; - usePivot = false; - - pivotFoot = -1; - pivotYaw = 0.0f; - pivotPos.Zero(); - - oldHeightsValid = false; - oldWaistHeight = 0.0f; - waistOffset.Zero(); -} - -/* -================ -idIK_Walk::~idIK_Walk -================ -*/ -idIK_Walk::~idIK_Walk() { - if ( footModel ) { - delete footModel; - } -} - -/* -================ -idIK_Walk::Save -================ -*/ -void idIK_Walk::Save( idSaveGame *savefile ) const { - int i; - - idIK::Save( savefile ); - - savefile->WriteClipModel( footModel ); - - savefile->WriteInt( numLegs ); - savefile->WriteInt( enabledLegs ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteInt( footJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteInt( ankleJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteInt( kneeJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteInt( hipJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteInt( dirJoints[i] ); - savefile->WriteInt( waistJoint ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteVec3( hipForward[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteVec3( kneeForward[i] ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteFloat( upperLegLength[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteFloat( lowerLegLength[i] ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteMat3( upperLegToHipJoint[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->WriteMat3( lowerLegToKneeJoint[i] ); - - savefile->WriteFloat( smoothing ); - savefile->WriteFloat( waistSmoothing ); - savefile->WriteFloat( footShift ); - savefile->WriteFloat( waistShift ); - savefile->WriteFloat( minWaistFloorDist ); - savefile->WriteFloat( minWaistAnkleDist ); - savefile->WriteFloat( footUpTrace ); - savefile->WriteFloat( footDownTrace ); - savefile->WriteBool( tiltWaist ); - savefile->WriteBool( usePivot ); - - savefile->WriteInt( pivotFoot ); - savefile->WriteFloat( pivotYaw ); - savefile->WriteVec3( pivotPos ); - savefile->WriteBool( oldHeightsValid ); - savefile->WriteFloat( oldWaistHeight ); - for ( i = 0; i < MAX_LEGS; i++ ) { - savefile->WriteFloat( oldAnkleHeights[i] ); - } - savefile->WriteVec3( waistOffset ); -} - -/* -================ -idIK_Walk::Restore -================ -*/ -void idIK_Walk::Restore( idRestoreGame *savefile ) { - int i; - - idIK::Restore( savefile ); - - savefile->ReadClipModel( footModel ); - - savefile->ReadInt( numLegs ); - savefile->ReadInt( enabledLegs ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadInt( (int&)footJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadInt( (int&)ankleJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadInt( (int&)kneeJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadInt( (int&)hipJoints[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadInt( (int&)dirJoints[i] ); - savefile->ReadInt( (int&)waistJoint ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadVec3( hipForward[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadVec3( kneeForward[i] ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadFloat( upperLegLength[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadFloat( lowerLegLength[i] ); - - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadMat3( upperLegToHipJoint[i] ); - for ( i = 0; i < MAX_LEGS; i++ ) - savefile->ReadMat3( lowerLegToKneeJoint[i] ); - - savefile->ReadFloat( smoothing ); - savefile->ReadFloat( waistSmoothing ); - savefile->ReadFloat( footShift ); - savefile->ReadFloat( waistShift ); - savefile->ReadFloat( minWaistFloorDist ); - savefile->ReadFloat( minWaistAnkleDist ); - savefile->ReadFloat( footUpTrace ); - savefile->ReadFloat( footDownTrace ); - savefile->ReadBool( tiltWaist ); - savefile->ReadBool( usePivot ); - - savefile->ReadInt( pivotFoot ); - savefile->ReadFloat( pivotYaw ); - savefile->ReadVec3( pivotPos ); - savefile->ReadBool( oldHeightsValid ); - savefile->ReadFloat( oldWaistHeight ); - for ( i = 0; i < MAX_LEGS; i++ ) { - savefile->ReadFloat( oldAnkleHeights[i] ); - } - savefile->ReadVec3( waistOffset ); -} - -/* -================ -idIK_Walk::Init -================ -*/ -bool idIK_Walk::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { - int i; - float footSize; - idVec3 verts[4]; - idTraceModel trm; - const char *jointName; - idVec3 dir, ankleOrigin, kneeOrigin, hipOrigin, dirOrigin; - idMat3 axis, ankleAxis, kneeAxis, hipAxis; - - static idVec3 footWinding[4] = { - idVec3( 1.0f, 1.0f, 0.0f ), - idVec3( -1.0f, 1.0f, 0.0f ), - idVec3( -1.0f, -1.0f, 0.0f ), - idVec3( 1.0f, -1.0f, 0.0f ) - }; - - if ( !self ) { - return false; - } - - numLegs = Min( self->spawnArgs.GetInt( "ik_numLegs", "0" ), MAX_LEGS ); - if ( numLegs == 0 ) { - return true; - } - - if ( !idIK::Init( self, anim, modelOffset ) ) { - return false; - } - - int numJoints = animator->NumJoints(); - idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); - - // create the animation frame used to setup the IK - gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() ); - - enabledLegs = 0; - - // get all the joints - for ( i = 0; i < numLegs; i++ ) { - - jointName = self->spawnArgs.GetString( va( "ik_foot%d", i+1 ) ); - footJoints[i] = animator->GetJointHandle( jointName ); - if ( footJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Walk::Init: invalid foot joint '%s'", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_ankle%d", i+1 ) ); - ankleJoints[i] = animator->GetJointHandle( jointName ); - if ( ankleJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Walk::Init: invalid ankle joint '%s'", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_knee%d", i+1 ) ); - kneeJoints[i] = animator->GetJointHandle( jointName ); - if ( kneeJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Walk::Init: invalid knee joint '%s'\n", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_hip%d", i+1 ) ); - hipJoints[i] = animator->GetJointHandle( jointName ); - if ( hipJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Walk::Init: invalid hip joint '%s'\n", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_dir%d", i+1 ) ); - dirJoints[i] = animator->GetJointHandle( jointName ); - - enabledLegs |= 1 << i; - } - - jointName = self->spawnArgs.GetString( "ik_waist" ); - waistJoint = animator->GetJointHandle( jointName ); - if ( waistJoint == INVALID_JOINT ) { - gameLocal.Error( "idIK_Walk::Init: invalid waist joint '%s'\n", jointName ); - } - - // get the leg bone lengths and rotation matrices - for ( i = 0; i < numLegs; i++ ) { - oldAnkleHeights[i] = 0.0f; - - ankleAxis = joints[ ankleJoints[ i ] ].ToMat3(); - ankleOrigin = joints[ ankleJoints[ i ] ].ToVec3(); - - kneeAxis = joints[ kneeJoints[ i ] ].ToMat3(); - kneeOrigin = joints[ kneeJoints[ i ] ].ToVec3(); - - hipAxis = joints[ hipJoints[ i ] ].ToMat3(); - hipOrigin = joints[ hipJoints[ i ] ].ToVec3(); - - // get the IK direction - if ( dirJoints[i] != INVALID_JOINT ) { - dirOrigin = joints[ dirJoints[ i ] ].ToVec3(); - dir = dirOrigin - kneeOrigin; - } else { - dir.Set( 1.0f, 0.0f, 0.0f ); - } - - hipForward[i] = dir * hipAxis.Transpose(); - kneeForward[i] = dir * kneeAxis.Transpose(); - - // conversion from upper leg bone axis to hip joint axis - upperLegLength[i] = GetBoneAxis( hipOrigin, kneeOrigin, dir, axis ); - upperLegToHipJoint[i] = hipAxis * axis.Transpose(); - - // conversion from lower leg bone axis to knee joint axis - lowerLegLength[i] = GetBoneAxis( kneeOrigin, ankleOrigin, dir, axis ); - lowerLegToKneeJoint[i] = kneeAxis * axis.Transpose(); - } - - smoothing = self->spawnArgs.GetFloat( "ik_smoothing", "0.75" ); - waistSmoothing = self->spawnArgs.GetFloat( "ik_waistSmoothing", "0.75" ); - footShift = self->spawnArgs.GetFloat( "ik_footShift", "0" ); - waistShift = self->spawnArgs.GetFloat( "ik_waistShift", "0" ); - minWaistFloorDist = self->spawnArgs.GetFloat( "ik_minWaistFloorDist", "0" ); - minWaistAnkleDist = self->spawnArgs.GetFloat( "ik_minWaistAnkleDist", "0" ); - footUpTrace = self->spawnArgs.GetFloat( "ik_footUpTrace", "32" ); - footDownTrace = self->spawnArgs.GetFloat( "ik_footDownTrace", "32" ); - tiltWaist = self->spawnArgs.GetBool( "ik_tiltWaist", "0" ); - usePivot = self->spawnArgs.GetBool( "ik_usePivot", "0" ); - - // setup a clip model for the feet - footSize = self->spawnArgs.GetFloat( "ik_footSize", "4" ) * 0.5f; - if ( footSize > 0.0f ) { - for ( i = 0; i < 4; i++ ) { - verts[i] = footWinding[i] * footSize; - } - trm.SetupPolygon( verts, 4 ); - footModel = new idClipModel( trm ); - } - - initialized = true; - - return true; -} - -/* -================ -idIK_Walk::Evaluate -================ -*/ -void idIK_Walk::Evaluate( void ) { - int i; - int newPivotFoot = 0; - float modelHeight, jointHeight, lowestHeight, floorHeights[MAX_LEGS]; - float shift, smallestShift, newHeight, step, newPivotYaw, height, largestAnkleHeight; - idVec3 modelOrigin, normal, hipDir, kneeDir, start, end, jointOrigins[MAX_LEGS]; - idVec3 footOrigin, ankleOrigin, kneeOrigin, hipOrigin, waistOrigin; - idMat3 modelAxis, waistAxis, axis; - idMat3 hipAxis[MAX_LEGS], kneeAxis[MAX_LEGS], ankleAxis[MAX_LEGS]; - trace_t results; - - if ( !self || !gameLocal.isNewFrame ) { - return; - } - - // if no IK enabled on any legs - if ( !enabledLegs ) { - return; - } - - normal = - self->GetPhysics()->GetGravityNormal(); - modelOrigin = self->GetPhysics()->GetOrigin(); - modelAxis = self->GetRenderEntity()->axis; - modelHeight = modelOrigin * normal; - - modelOrigin += modelOffset * modelAxis; - - // create frame without joint mods - animator->CreateFrame( gameLocal.time, false ); - - // get the joint positions for the feet - lowestHeight = idMath::INFINITY; - for ( i = 0; i < numLegs; i++ ) { - animator->GetJointTransform( footJoints[i], gameLocal.time, footOrigin, axis ); - jointOrigins[i] = modelOrigin + footOrigin * modelAxis; - jointHeight = jointOrigins[i] * normal; - if ( jointHeight < lowestHeight ) { - lowestHeight = jointHeight; - newPivotFoot = i; - } - } - - if ( usePivot ) { - - newPivotYaw = modelAxis[0].ToYaw(); - - // change pivot foot - if ( newPivotFoot != pivotFoot || idMath::Fabs( idMath::AngleNormalize180( newPivotYaw - pivotYaw ) ) > 30.0f ) { - pivotFoot = newPivotFoot; - pivotYaw = newPivotYaw; - animator->GetJointTransform( footJoints[pivotFoot], gameLocal.time, footOrigin, axis ); - pivotPos = modelOrigin + footOrigin * modelAxis; - } - - // keep pivot foot in place - jointOrigins[pivotFoot] = pivotPos; - } - - // get the floor heights for the feet - for ( i = 0; i < numLegs; i++ ) { - - if ( !( enabledLegs & ( 1 << i ) ) ) { - continue; - } - - start = jointOrigins[i] + normal * footUpTrace; - end = jointOrigins[i] - normal * footDownTrace; - gameLocal.clip.Translation( results, start, end, footModel, mat3_identity, CONTENTS_SOLID|CONTENTS_IKCLIP, self ); - floorHeights[i] = results.endpos * normal; - - if ( ik_debug.GetBool() && footModel ) { - idFixedWinding w; - for ( int j = 0; j < footModel->GetTraceModel()->numVerts; j++ ) { - w += footModel->GetTraceModel()->verts[j]; - } - gameRenderWorld->DebugWinding( colorRed, w, results.endpos, results.endAxis ); - } - } - - const idPhysics *phys = self->GetPhysics(); - - // test whether or not the character standing on the ground - bool onGround = phys->HasGroundContacts(); - - // test whether or not the character is standing on a plat - bool onPlat = false; - for ( i = 0; i < phys->GetNumContacts(); i++ ) { - idEntity *ent = gameLocal.entities[ phys->GetContact( i ).entityNum ]; - if ( ent != NULL && ent->IsType( idPlat::Type ) ) { - onPlat = true; - break; - } - } - - // adjust heights of the ankles - smallestShift = idMath::INFINITY; - largestAnkleHeight = -idMath::INFINITY; - for ( i = 0; i < numLegs; i++ ) { - - if ( onGround && ( enabledLegs & ( 1 << i ) ) ) { - shift = floorHeights[i] - modelHeight + footShift; - } else { - shift = 0.0f; - } - - if ( shift < smallestShift ) { - smallestShift = shift; - } - - animator->GetJointTransform( ankleJoints[i], gameLocal.time, ankleOrigin, ankleAxis[i] ); - jointOrigins[i] = modelOrigin + ankleOrigin * modelAxis; - - height = jointOrigins[i] * normal; - - if ( oldHeightsValid && !onPlat ) { - step = height + shift - oldAnkleHeights[i]; - shift -= smoothing * step; - } - - newHeight = height + shift; - if ( newHeight > largestAnkleHeight ) { - largestAnkleHeight = newHeight; - } - - oldAnkleHeights[i] = newHeight; - - jointOrigins[i] += shift * normal; - } - - animator->GetJointTransform( waistJoint, gameLocal.time, waistOrigin, waistAxis ); - waistOrigin = modelOrigin + waistOrigin * modelAxis; - - // adjust position of the waist - waistOffset = ( smallestShift + waistShift ) * normal; - - // if the waist should be at least a certain distance above the floor - if ( minWaistFloorDist > 0.0f && waistOffset * normal < 0.0f ) { - start = waistOrigin; - end = waistOrigin + waistOffset - normal * minWaistFloorDist; - gameLocal.clip.Translation( results, start, end, footModel, modelAxis, CONTENTS_SOLID|CONTENTS_IKCLIP, self ); - height = ( waistOrigin + waistOffset - results.endpos ) * normal; - if ( height < minWaistFloorDist ) { - waistOffset += ( minWaistFloorDist - height ) * normal; - } - } - - // if the waist should be at least a certain distance above the ankles - if ( minWaistAnkleDist > 0.0f ) { - height = ( waistOrigin + waistOffset ) * normal; - if ( height - largestAnkleHeight < minWaistAnkleDist ) { - waistOffset += ( minWaistAnkleDist - ( height - largestAnkleHeight ) ) * normal; - } - } - - if ( oldHeightsValid ) { - // smoothly adjust height of waist - newHeight = ( waistOrigin + waistOffset ) * normal; - step = newHeight - oldWaistHeight; - waistOffset -= waistSmoothing * step * normal; - } - - // save height of waist for smoothing - oldWaistHeight = ( waistOrigin + waistOffset ) * normal; - - if ( !oldHeightsValid ) { - oldHeightsValid = true; - return; - } - - // solve IK - for ( i = 0; i < numLegs; i++ ) { - - // get the position of the hip in world space - animator->GetJointTransform( hipJoints[i], gameLocal.time, hipOrigin, axis ); - hipOrigin = modelOrigin + waistOffset + hipOrigin * modelAxis; - hipDir = hipForward[i] * axis * modelAxis; - - // get the IK bend direction - animator->GetJointTransform( kneeJoints[i], gameLocal.time, kneeOrigin, axis ); - kneeDir = kneeForward[i] * axis * modelAxis; - - // solve IK and calculate knee position - SolveTwoBones( hipOrigin, jointOrigins[i], kneeDir, upperLegLength[i], lowerLegLength[i], kneeOrigin ); - - if ( ik_debug.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, hipOrigin, kneeOrigin ); - gameRenderWorld->DebugLine( colorRed, kneeOrigin, jointOrigins[i] ); - gameRenderWorld->DebugLine( colorYellow, kneeOrigin, kneeOrigin + hipDir ); - gameRenderWorld->DebugLine( colorGreen, kneeOrigin, kneeOrigin + kneeDir ); - } - - // get the axis for the hip joint - GetBoneAxis( hipOrigin, kneeOrigin, hipDir, axis ); - hipAxis[i] = upperLegToHipJoint[i] * ( axis * modelAxis.Transpose() ); - - // get the axis for the knee joint - GetBoneAxis( kneeOrigin, jointOrigins[i], kneeDir, axis ); - kneeAxis[i] = lowerLegToKneeJoint[i] * ( axis * modelAxis.Transpose() ); - } - - // set the joint mods - animator->SetJointAxis( waistJoint, JOINTMOD_WORLD_OVERRIDE, waistAxis ); - animator->SetJointPos( waistJoint, JOINTMOD_WORLD_OVERRIDE, ( waistOrigin + waistOffset - modelOrigin ) * modelAxis.Transpose() ); - for ( i = 0; i < numLegs; i++ ) { - animator->SetJointAxis( hipJoints[i], JOINTMOD_WORLD_OVERRIDE, hipAxis[i] ); - animator->SetJointAxis( kneeJoints[i], JOINTMOD_WORLD_OVERRIDE, kneeAxis[i] ); - animator->SetJointAxis( ankleJoints[i], JOINTMOD_WORLD_OVERRIDE, ankleAxis[i] ); - } - - ik_activate = true; -} - -/* -================ -idIK_Walk::ClearJointMods -================ -*/ -void idIK_Walk::ClearJointMods( void ) { - int i; - - if ( !self || !ik_activate ) { - return; - } - - animator->SetJointAxis( waistJoint, JOINTMOD_NONE, mat3_identity ); - animator->SetJointPos( waistJoint, JOINTMOD_NONE, vec3_origin ); - for ( i = 0; i < numLegs; i++ ) { - animator->SetJointAxis( hipJoints[i], JOINTMOD_NONE, mat3_identity ); - animator->SetJointAxis( kneeJoints[i], JOINTMOD_NONE, mat3_identity ); - animator->SetJointAxis( ankleJoints[i], JOINTMOD_NONE, mat3_identity ); - } - - ik_activate = false; -} - -/* -================ -idIK_Walk::EnableAll -================ -*/ -void idIK_Walk::EnableAll( void ) { - enabledLegs = ( 1 << numLegs ) - 1; - oldHeightsValid = false; -} - -/* -================ -idIK_Walk::DisableAll -================ -*/ -void idIK_Walk::DisableAll( void ) { - enabledLegs = 0; - oldHeightsValid = false; -} - -/* -================ -idIK_Walk::EnableLeg -================ -*/ -void idIK_Walk::EnableLeg( int num ) { - enabledLegs |= 1 << num; -} - -/* -================ -idIK_Walk::DisableLeg -================ -*/ -void idIK_Walk::DisableLeg( int num ) { - enabledLegs &= ~( 1 << num ); -} - - -/* -=============================================================================== - - idIK_Reach - -=============================================================================== -*/ - -/* -================ -idIK_Reach::idIK_Reach -================ -*/ -idIK_Reach::idIK_Reach() { - int i; - - initialized = false; - numArms = 0; - enabledArms = 0; - for ( i = 0; i < MAX_ARMS; i++ ) { - handJoints[i] = INVALID_JOINT; - elbowJoints[i] = INVALID_JOINT; - shoulderJoints[i] = INVALID_JOINT; - dirJoints[i] = INVALID_JOINT; - shoulderForward[i].Zero(); - elbowForward[i].Zero(); - upperArmLength[i] = 0.0f; - lowerArmLength[i] = 0.0f; - upperArmToShoulderJoint[i].Identity(); - lowerArmToElbowJoint[i].Identity(); - } -} - -/* -================ -idIK_Reach::~idIK_Reach -================ -*/ -idIK_Reach::~idIK_Reach() { -} - -/* -================ -idIK_Reach::Save -================ -*/ -void idIK_Reach::Save( idSaveGame *savefile ) const { - int i; - idIK::Save( savefile ); - - savefile->WriteInt( numArms ); - savefile->WriteInt( enabledArms ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteInt( handJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteInt( elbowJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteInt( shoulderJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteInt( dirJoints[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteVec3( shoulderForward[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteVec3( elbowForward[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteFloat( upperArmLength[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteFloat( lowerArmLength[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteMat3( upperArmToShoulderJoint[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->WriteMat3( lowerArmToElbowJoint[i] ); -} - -/* -================ -idIK_Reach::Restore -================ -*/ -void idIK_Reach::Restore( idRestoreGame *savefile ) { - int i; - idIK::Restore( savefile ); - - savefile->ReadInt( numArms ); - savefile->ReadInt( enabledArms ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadInt( (int&)handJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadInt( (int&)elbowJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadInt( (int&)shoulderJoints[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadInt( (int&)dirJoints[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadVec3( shoulderForward[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadVec3( elbowForward[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadFloat( upperArmLength[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadFloat( lowerArmLength[i] ); - - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadMat3( upperArmToShoulderJoint[i] ); - for ( i = 0; i < MAX_ARMS; i++ ) - savefile->ReadMat3( lowerArmToElbowJoint[i] ); -} - -/* -================ -idIK_Reach::Init -================ -*/ -bool idIK_Reach::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) { - int i; - const char *jointName; - idTraceModel trm; - idVec3 dir, handOrigin, elbowOrigin, shoulderOrigin, dirOrigin; - idMat3 axis, handAxis, elbowAxis, shoulderAxis; - - if ( !self ) { - return false; - } - - numArms = Min( self->spawnArgs.GetInt( "ik_numArms", "0" ), MAX_ARMS ); - if ( numArms == 0 ) { - return true; - } - - if ( !idIK::Init( self, anim, modelOffset ) ) { - return false; - } - - int numJoints = animator->NumJoints(); - idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) ); - - // create the animation frame used to setup the IK - gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() ); - - enabledArms = 0; - - // get all the joints - for ( i = 0; i < numArms; i++ ) { - - jointName = self->spawnArgs.GetString( va( "ik_hand%d", i+1 ) ); - handJoints[i] = animator->GetJointHandle( jointName ); - if ( handJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Reach::Init: invalid hand joint '%s'", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_elbow%d", i+1 ) ); - elbowJoints[i] = animator->GetJointHandle( jointName ); - if ( elbowJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Reach::Init: invalid elbow joint '%s'\n", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_shoulder%d", i+1 ) ); - shoulderJoints[i] = animator->GetJointHandle( jointName ); - if ( shoulderJoints[i] == INVALID_JOINT ) { - gameLocal.Error( "idIK_Reach::Init: invalid shoulder joint '%s'\n", jointName ); - } - - jointName = self->spawnArgs.GetString( va( "ik_elbowDir%d", i+1 ) ); - dirJoints[i] = animator->GetJointHandle( jointName ); - - enabledArms |= 1 << i; - } - - // get the arm bone lengths and rotation matrices - for ( i = 0; i < numArms; i++ ) { - - handAxis = joints[ handJoints[ i ] ].ToMat3(); - handOrigin = joints[ handJoints[ i ] ].ToVec3(); - - elbowAxis = joints[ elbowJoints[ i ] ].ToMat3(); - elbowOrigin = joints[ elbowJoints[ i ] ].ToVec3(); - - shoulderAxis = joints[ shoulderJoints[ i ] ].ToMat3(); - shoulderOrigin = joints[ shoulderJoints[ i ] ].ToVec3(); - - // get the IK direction - if ( dirJoints[i] != INVALID_JOINT ) { - dirOrigin = joints[ dirJoints[ i ] ].ToVec3(); - dir = dirOrigin - elbowOrigin; - } else { - dir.Set( -1.0f, 0.0f, 0.0f ); - } - - shoulderForward[i] = dir * shoulderAxis.Transpose(); - elbowForward[i] = dir * elbowAxis.Transpose(); - - // conversion from upper arm bone axis to should joint axis - upperArmLength[i] = GetBoneAxis( shoulderOrigin, elbowOrigin, dir, axis ); - upperArmToShoulderJoint[i] = shoulderAxis * axis.Transpose(); - - // conversion from lower arm bone axis to elbow joint axis - lowerArmLength[i] = GetBoneAxis( elbowOrigin, handOrigin, dir, axis ); - lowerArmToElbowJoint[i] = elbowAxis * axis.Transpose(); - } - - initialized = true; - - return true; -} - -/* -================ -idIK_Reach::Evaluate -================ -*/ -void idIK_Reach::Evaluate( void ) { - int i; - idVec3 modelOrigin, shoulderOrigin, elbowOrigin, handOrigin, shoulderDir, elbowDir; - idMat3 modelAxis, axis; - idMat3 shoulderAxis[MAX_ARMS], elbowAxis[MAX_ARMS]; - trace_t trace; - - modelOrigin = self->GetRenderEntity()->origin; - modelAxis = self->GetRenderEntity()->axis; - - // solve IK - for ( i = 0; i < numArms; i++ ) { - - // get the position of the shoulder in world space - animator->GetJointTransform( shoulderJoints[i], gameLocal.time, shoulderOrigin, axis ); - shoulderOrigin = modelOrigin + shoulderOrigin * modelAxis; - shoulderDir = shoulderForward[i] * axis * modelAxis; - - // get the position of the hand in world space - animator->GetJointTransform( handJoints[i], gameLocal.time, handOrigin, axis ); - handOrigin = modelOrigin + handOrigin * modelAxis; - - // get first collision going from shoulder to hand - gameLocal.clip.TracePoint( trace, shoulderOrigin, handOrigin, CONTENTS_SOLID, self ); - handOrigin = trace.endpos; - - // get the IK bend direction - animator->GetJointTransform( elbowJoints[i], gameLocal.time, elbowOrigin, axis ); - elbowDir = elbowForward[i] * axis * modelAxis; - - // solve IK and calculate elbow position - SolveTwoBones( shoulderOrigin, handOrigin, elbowDir, upperArmLength[i], lowerArmLength[i], elbowOrigin ); - - if ( ik_debug.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, shoulderOrigin, elbowOrigin ); - gameRenderWorld->DebugLine( colorRed, elbowOrigin, handOrigin ); - gameRenderWorld->DebugLine( colorYellow, elbowOrigin, elbowOrigin + elbowDir ); - gameRenderWorld->DebugLine( colorGreen, elbowOrigin, elbowOrigin + shoulderDir ); - } - - // get the axis for the shoulder joint - GetBoneAxis( shoulderOrigin, elbowOrigin, shoulderDir, axis ); - shoulderAxis[i] = upperArmToShoulderJoint[i] * ( axis * modelAxis.Transpose() ); - - // get the axis for the elbow joint - GetBoneAxis( elbowOrigin, handOrigin, elbowDir, axis ); - elbowAxis[i] = lowerArmToElbowJoint[i] * ( axis * modelAxis.Transpose() ); - } - - for ( i = 0; i < numArms; i++ ) { - animator->SetJointAxis( shoulderJoints[i], JOINTMOD_WORLD_OVERRIDE, shoulderAxis[i] ); - animator->SetJointAxis( elbowJoints[i], JOINTMOD_WORLD_OVERRIDE, elbowAxis[i] ); - } - - ik_activate = true; -} - -/* -================ -idIK_Reach::ClearJointMods -================ -*/ -void idIK_Reach::ClearJointMods( void ) { - int i; - - if ( !self || !ik_activate ) { - return; - } - - for ( i = 0; i < numArms; i++ ) { - animator->SetJointAxis( shoulderJoints[i], JOINTMOD_NONE, mat3_identity ); - animator->SetJointAxis( elbowJoints[i], JOINTMOD_NONE, mat3_identity ); - animator->SetJointAxis( handJoints[i], JOINTMOD_NONE, mat3_identity ); - } - - ik_activate = false; -} diff --git a/game/ik.h b/game/ik.h deleted file mode 100644 index 9028b5f82..000000000 --- a/game/ik.h +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_IK_H__ -#define __GAME_IK_H__ - -/* -=============================================================================== - - IK base class with a simple fast two bone solver. - -=============================================================================== -*/ - -#define IK_ANIM "ik_pose" - -class idIK { -public: - idIK( void ); - virtual ~idIK( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - bool IsInitialized( void ) const; - - virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); - virtual void Evaluate( void ); - virtual void ClearJointMods( void ); - - bool SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos ); - float GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis ); - -protected: - bool initialized; - bool ik_activate; - idEntity * self; // entity using the animated model - idAnimator * animator; // animator on entity - int modifiedAnim; // animation modified by the IK - idVec3 modelOffset; -}; - - -/* -=============================================================================== - - IK controller for a walking character with an arbitrary number of legs. - -=============================================================================== -*/ - -class idIK_Walk : public idIK { -public: - - idIK_Walk( void ); - virtual ~idIK_Walk( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); - virtual void Evaluate( void ); - virtual void ClearJointMods( void ); - - void EnableAll( void ); - void DisableAll( void ); - void EnableLeg( int num ); - void DisableLeg( int num ); - -private: - static const int MAX_LEGS = 8; - - idClipModel * footModel; - - int numLegs; - int enabledLegs; - jointHandle_t footJoints[MAX_LEGS]; - jointHandle_t ankleJoints[MAX_LEGS]; - jointHandle_t kneeJoints[MAX_LEGS]; - jointHandle_t hipJoints[MAX_LEGS]; - jointHandle_t dirJoints[MAX_LEGS]; - jointHandle_t waistJoint; - - idVec3 hipForward[MAX_LEGS]; - idVec3 kneeForward[MAX_LEGS]; - - float upperLegLength[MAX_LEGS]; - float lowerLegLength[MAX_LEGS]; - - idMat3 upperLegToHipJoint[MAX_LEGS]; - idMat3 lowerLegToKneeJoint[MAX_LEGS]; - - float smoothing; - float waistSmoothing; - float footShift; - float waistShift; - float minWaistFloorDist; - float minWaistAnkleDist; - float footUpTrace; - float footDownTrace; - bool tiltWaist; - bool usePivot; - - // state - int pivotFoot; - float pivotYaw; - idVec3 pivotPos; - bool oldHeightsValid; - float oldWaistHeight; - float oldAnkleHeights[MAX_LEGS]; - idVec3 waistOffset; -}; - - -/* -=============================================================================== - - IK controller for reaching a position with an arm or leg. - -=============================================================================== -*/ - -class idIK_Reach : public idIK { -public: - - idIK_Reach( void ); - virtual ~idIK_Reach( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset ); - virtual void Evaluate( void ); - virtual void ClearJointMods( void ); - -private: - - static const int MAX_ARMS = 2; - - int numArms; - int enabledArms; - jointHandle_t handJoints[MAX_ARMS]; - jointHandle_t elbowJoints[MAX_ARMS]; - jointHandle_t shoulderJoints[MAX_ARMS]; - jointHandle_t dirJoints[MAX_ARMS]; - - idVec3 shoulderForward[MAX_ARMS]; - idVec3 elbowForward[MAX_ARMS]; - - float upperArmLength[MAX_ARMS]; - float lowerArmLength[MAX_ARMS]; - - idMat3 upperArmToShoulderJoint[MAX_ARMS]; - idMat3 lowerArmToElbowJoint[MAX_ARMS]; -}; - -#endif /* !__GAME_IK_H__ */ diff --git a/game/item.cpp b/game/item.cpp deleted file mode 100644 index 712aaa9b9..000000000 --- a/game/item.cpp +++ /dev/null @@ -1,1144 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -/** -* TDM: There is absolutely no reason to use this class any more!!! -* All inventory and frob functionality has been moved to idEntity -**/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning(disable : 4996) - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/AbsenceMarker.h" - -/* -=============================================================================== - - idItem - -=============================================================================== -*/ - -const idEventDef EV_DropToFloor( "" ); -const idEventDef EV_RespawnItem( "respawn" ); -const idEventDef EV_RespawnFx( "" ); -const idEventDef EV_GetPlayerPos( "" ); -const idEventDef EV_HideObjective( "", "e" ); -const idEventDef EV_CamShot( "" ); - -CLASS_DECLARATION( idEntity, idItem ) - EVENT( EV_DropToFloor, idItem::Event_DropToFloor ) - EVENT( EV_Touch, idItem::Event_Touch ) - EVENT( EV_Activate, idItem::Event_Trigger ) - EVENT( EV_RespawnItem, idItem::Event_Respawn ) - EVENT( EV_RespawnFx, idItem::Event_RespawnFx ) -END_CLASS - - -/* -================ -idItem::idItem -================ -*/ -idItem::idItem() -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); - - spin = false; - inView = false; - inViewTime = 0; - lastCycle = 0; - lastRenderViewTime = -1; - itemShellHandle = -1; - shellMaterial = NULL; - orgOrigin.Zero(); - canPickUp = true; - fl.networkSync = true; - - m_FrobActionScript = "frob_item"; - - noticeabilityIfAbsent = 0.0; - b_orgOriginSet = false; - - -} - -/* -================ -idItem::~idItem -================ -*/ -idItem::~idItem() { - // remove the highlight shell - if ( itemShellHandle != -1 ) { - gameRenderWorld->FreeEntityDef( itemShellHandle ); - } -} - -/* -================ -idItem::Save -================ -*/ -void idItem::Save( idSaveGame *savefile ) const { - - savefile->WriteVec3( orgOrigin ); - savefile->WriteBool( spin ); - savefile->WriteBool( pulse ); - savefile->WriteBool( canPickUp ); - - savefile->WriteMaterial( shellMaterial ); - - savefile->WriteBool( inView ); - savefile->WriteInt( inViewTime ); - savefile->WriteInt( lastCycle ); - savefile->WriteInt( lastRenderViewTime ); - savefile->WriteFloat (noticeabilityIfAbsent); - absenceEntityPtr.Save (savefile); -} - -/* -================ -idItem::Restore -================ -*/ -void idItem::Restore( idRestoreGame *savefile ) { - - savefile->ReadVec3( orgOrigin ); - savefile->ReadBool( spin ); - savefile->ReadBool( pulse ); - savefile->ReadBool( canPickUp ); - - savefile->ReadMaterial( shellMaterial ); - - savefile->ReadBool( inView ); - savefile->ReadInt( inViewTime ); - savefile->ReadInt( lastCycle ); - savefile->ReadInt( lastRenderViewTime ); - savefile->ReadFloat (noticeabilityIfAbsent); - absenceEntityPtr.Restore (savefile); - - itemShellHandle = -1; -} - -/* -================ -idItem::UpdateRenderEntity -================ -*/ -bool idItem::UpdateRenderEntity(renderEntity_s *renderEntity, const renderView_t *renderView) -{ - bool bRc = true; - - if(pulse) - { - if(lastRenderViewTime == renderView->time) - return false; - - lastRenderViewTime = renderView->time; - - // check for glow highlighting if near the center of the view - idVec3 dir = renderEntity->origin - renderView->vieworg; - dir.Normalize(); - float d = dir * renderView->viewaxis[0]; - - // two second pulse cycle - float cycle = ( renderView->time - inViewTime ) / 2000.0f; - - if(d > 0.94f) - { - if(!inView) - { - inView = true; - if(cycle > lastCycle) - { - // restart at the beginning - inViewTime = renderView->time; - cycle = 0.0f; - } - } - } - else - { - if(inView) - { - inView = false; - lastCycle = static_cast(ceil(cycle)); - } - } - - if(!inView && cycle > lastCycle) - { - renderEntity->shaderParms[4] = 0.0f; - } - else - { - // pulse up in 1/4 second - cycle -= (int)cycle; - if ( cycle < 0.1f ) { - renderEntity->shaderParms[4] = cycle * 10.0f; - } else if ( cycle < 0.2f ) { - renderEntity->shaderParms[4] = 1.0f; - } else if ( cycle < 0.3f ) { - renderEntity->shaderParms[4] = 1.0f - ( cycle - 0.2f ) * 10.0f; - } else { - // stay off between pulses - renderEntity->shaderParms[4] = 0.0f; - } - } - } - - // update every single time this is in view - return bRc; -} - - - -/* -================ -idItem::ModelCallback -================ -*/ -bool idItem::ModelCallback( renderEntity_t *renderEntity, const renderView_t *renderView ) -{ - idItem *ent; - - // this may be triggered by a model trace or other non-view related source - if ( !renderView ) - { - return false; - } - - ent = static_cast(gameLocal.entities[ renderEntity->entityNum ]); - if(!ent) - { - gameLocal.Error( "idItem::ModelCallback: callback with NULL game entity" ); - } - - return ent->UpdateRenderEntity( renderEntity, renderView ); -} - -/* -================ -idItem::Think -================ -*/ -void idItem::Think( void ) -{ - if ( thinkFlags & TH_THINK ) - { - if(spin) - { - idAngles ang; - idVec3 org; - - ang.pitch = ang.roll = 0.0f; - ang.yaw = ( gameLocal.time & 4095 ) * 360.0f / -4096.0f; - SetAngles( ang ); - - float scale = 0.005f + entityNumber * 0.00001f; - - org = orgOrigin; - org.z += 4.0f + cos( ( gameLocal.time + 2000 ) * scale ) * 4.0f; - SetOrigin( org ); - } - } - - Present(); -} - -/* -================ -idItem::Present -================ -*/ -void idItem::Present( void ) -{ - idEntity::Present(); - - if(!fl.hidden && pulse) - { - // also add a highlight shell model - renderEntity_t shell; - - shell = renderEntity; - - // we will mess with shader parms when the item is in view - // to give the "item pulse" effect - shell.callback = idItem::ModelCallback; - - shell.entityNum = entityNumber; - shell.customShader = shellMaterial; - if ( itemShellHandle == -1 ) - { - itemShellHandle = gameRenderWorld->AddEntityDef( &shell ); - } - else - { - gameRenderWorld->UpdateEntityDef( itemShellHandle, &shell ); - } - } -} - -/* -================ -idItem::Spawn -================ -*/ -void idItem::Spawn( void ) -{ - idStr giveTo; - idEntity * ent; - float tsize; - - if ( spawnArgs.GetBool( "dropToFloor" ) ) - { - PostEventMS( &EV_DropToFloor, 0 ); - } - - if ( spawnArgs.GetFloat( "triggersize", "0", tsize ) ) { - GetPhysics()->GetClipModel()->LoadModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) ); - GetPhysics()->GetClipModel()->Link( gameLocal.clip ); - } - - if ( spawnArgs.GetBool( "start_off" ) ) - { - GetPhysics()->SetContents( 0 ); - Hide(); - } else - { - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - } - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - giveTo = spawnArgs.GetString( "owner" ); - if ( giveTo.Length() ) - { - ent = gameLocal.FindEntity( giveTo ); - if ( !ent ) - { - gameLocal.Error( "Item couldn't find owner '%s'", giveTo.c_str() ); - } - PostEventMS( &EV_Touch, 0, ent, 0 ); - } - - if ( spawnArgs.GetBool( "spin" ) || gameLocal.isMultiplayer ) - { - spin = true; - BecomeActive( TH_THINK ); - } - - //pulse = !spawnArgs.GetBool( "nopulse" ); - //temp hack for tim - pulse = false; - orgOrigin = GetPhysics()->GetOrigin(); - b_orgOriginSet = true; - - noticeabilityIfAbsent = spawnArgs.GetFloat("noticeabilityIfAbsent"); - - - canPickUp = !( spawnArgs.GetBool( "triggerFirst" ) || spawnArgs.GetBool( "no_touch" ) ); - - inViewTime = -1000; - lastCycle = -1; - itemShellHandle = -1; - shellMaterial = declManager->FindMaterial( "itemHighlightShell" ); - - // What team owns it? - spawnArgs.GetInt ("ownerTeam", "0", ownerTeam); -} - -/* -================ -idItem::GetAttributes -================ -*/ -void idItem::GetAttributes( idDict &attributes ) -{ - int i; - const idKeyValue *arg; - - int num = spawnArgs.GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - arg = spawnArgs.GetKeyVal( i ); - if ( arg->GetKey().Cmpn( "inv_", 4 ) ) { - attributes.Set( arg->GetKey().Right( arg->GetKey().Length() - 4 ), arg->GetValue() ); - } - } -} - -/* -================ -idItem::GiveToPlayer -================ -*/ -bool idItem::GiveToPlayer( idPlayer *player ) -{ - if ( player == NULL ) - { - return false; - } - - // greebo: Inventory Items are not handled here. InvItems should be added to the inventory - // by calling AddToInventory(). - - /*if ( spawnArgs.GetBool( "inv_carry" ) ) - { - return player->GiveInventoryItem( &spawnArgs ); - }*/ - - return false;//player->GiveItem( this ); -} - - -/* -================ -TDM: Darkmod spawns an absence marker entity -================ - -bool idItem::spawnAbsenceMarkerEntity() -{ - const char* pstr_markerDefName = "atdm:absence_marker"; - const idDict *p_markerDef = gameLocal.FindEntityDefDict( pstr_markerDefName, false ); - if( p_markerDef ) - { - idEntity *ent2; - gameLocal.SpawnEntityDef( *p_markerDef, &ent2, false ); - - if ( !ent2 || !ent2->IsType( AbsenceMarker::Type ) ) - { - gameLocal.Error( "Failed to spawn absence marker entity" ); - return false; - } - - AbsenceMarker* p_absenceMarker = static_cast( ent2 ); - - // The absence marker has been created - absenceEntityPtr = p_absenceMarker; - - // Initialize it - idEntityPtr thisPtr; - thisPtr = ((idEntity*) this); - idMat3 orgOrientation; - orgOrientation.Identity(); - - p_absenceMarker->Init(); - if (!p_absenceMarker->initAbsenceReference (thisPtr, orgOrigin, orgOrientation)) - { - gameLocal.Error( "Failed to initialize absence reference in absence marker entity" ); - return false; - } - } - else - { - gameLocal.Error( "Failed to find definition of absence marker entity " ); - return false; - } - - // Success - return true; - -} -*/ -/* -================ -TDM: Darkmod destroys an absence marker entity -================ - -void idItem::destroyAbsenceMarkerEntity() -{ - if (absenceEntityPtr.IsValid()) - { - AbsenceMarker* p_absenceMarker = static_cast( absenceEntityPtr.GetEntity() ); - delete p_absenceMarker; - absenceEntityPtr = NULL; - } -} -*/ -/* -================ -TDM: Darkmod checks if origin changed to create absence marker entity -idItem::UpdateVisuals -================ -*/ -void idItem::UpdateVisuals() -{ - // Call base class version - idEntity::UpdateVisuals(); - - // If we have not already spawned our absence entity and we are interested in spawning - // one if the item moves - if - ( - (noticeabilityIfAbsent > 0.0) && - (!absenceEntityPtr.IsValid()) - ) - if - ( - ( (b_orgOriginSet) && (GetPhysics()->GetOrigin() != orgOrigin) ) || - ( IsHidden() ) - ) - { - // Spawn an absence entity - // spawnAbsenceMarkerEntity(); - - } - // End has been moved, should be noticed, no absence marker spawned yet - else if - ( - (noticeabilityIfAbsent > 0.0) && - (absenceEntityPtr.IsValid()) && - (b_orgOriginSet) && - ((GetPhysics()->GetOrigin() -orgOrigin).LengthFast() < 256.0) - ) // End should be noticed, absence marker spawned, it was put back - { - // Destroy the absence marker entity - // destroyAbsenceMarkerEntity(); - } - - -} - -/* -================ -idItem::Pickup -================ -*/ -bool idItem::Pickup( idPlayer *player ) -{ - if ( !GiveToPlayer( player ) ) - { - return false; - } - - if ( gameLocal.isServer ) - { - ServerSendEvent( EVENT_PICKUP, NULL, false, -1 ); - } - - // play pickup sound - StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL ); - - // trigger our targets - ActivateTargets( player ); - - // clear our contents so the object isn't picked up twice - GetPhysics()->SetContents( 0 ); - - // hide the model - Hide(); - - // add the highlight shell - if ( itemShellHandle != -1 ) - { - gameRenderWorld->FreeEntityDef( itemShellHandle ); - itemShellHandle = -1; - } - - // Spawn an absence marker entity - // spawnAbsenceMarkerEntity(); - - float respawn = spawnArgs.GetFloat( "respawn" ); - bool dropped = spawnArgs.GetBool( "dropped" ); - bool no_respawn = spawnArgs.GetBool( "no_respawn" ); - - if ( gameLocal.isMultiplayer && respawn == 0.0f ) { - respawn = 20.0f; - } - - if ( respawn && !dropped && !no_respawn ) { - const char *sfx = spawnArgs.GetString( "fxRespawn" ); - if ( sfx && *sfx ) { - PostEventSec( &EV_RespawnFx, respawn - 0.5f ); - } - PostEventSec( &EV_RespawnItem, respawn ); - } else if ( !spawnArgs.GetBool( "inv_objective" ) && !no_respawn ) { - // give some time for the pickup sound to play - // FIXME: Play on the owner - if ( !spawnArgs.GetBool( "inv_carry" ) ) { - PostEventMS( &EV_Remove, 5000 ); - } - } - - BecomeInactive( TH_THINK ); - return true; -} - -/* -================ -idItem::ClientPredictionThink -================ -*/ -void idItem::ClientPredictionThink( void ) { - // only think forward because the state is not synced through snapshots - if ( !gameLocal.isNewFrame ) { - return; - } - Think(); -} - -/* -================ -idItem::WriteFromSnapshot -================ -*/ -void idItem::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteBits( IsHidden(), 1 ); -} - -/* -================ -idItem::ReadFromSnapshot -================ -*/ -void idItem::ReadFromSnapshot( const idBitMsgDelta &msg ) { - if ( msg.ReadBits( 1 ) ) { - Hide(); - } else { - Show(); - } -} - -/* -================ -idItem::ClientReceiveEvent -================ -*/ -bool idItem::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - - switch( event ) { - case EVENT_PICKUP: { - - // play pickup sound - StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL ); - - // hide the model - Hide(); - - // remove the highlight shell - if ( itemShellHandle != -1 ) { - gameRenderWorld->FreeEntityDef( itemShellHandle ); - itemShellHandle = -1; - } - return true; - } - case EVENT_RESPAWN: { - Event_Respawn(); - return true; - } - case EVENT_RESPAWNFX: { - Event_RespawnFx(); - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -================ -idItem::Event_DropToFloor -================ -*/ -void idItem::Event_DropToFloor( void ) { - trace_t trace; - - // don't drop the floor if bound to another entity - if ( GetBindMaster() != NULL && GetBindMaster() != this ) { - return; - } - - gameLocal.clip.TraceBounds( trace, renderEntity.origin, renderEntity.origin - idVec3( 0, 0, 64 ), renderEntity.bounds, MASK_SOLID | CONTENTS_CORPSE, this ); - SetOrigin( trace.endpos ); -} - -/* -================ -idItem::Event_Touch -================ -*/ -void idItem::Event_Touch( idEntity *other, trace_t *trace ) { - // only allow touches from the player - if ( !other->IsType( idPlayer::Type ) ) { - return; - } - - if ( !canPickUp ) { - return; - } - - Pickup( static_cast(other) ); -} - -/* -================ -idItem::Event_Trigger -================ -*/ -void idItem::Event_Trigger( idEntity *activator ) { - - if ( !canPickUp && spawnArgs.GetBool( "triggerFirst" ) ) { - canPickUp = true; - return; - } - - if ( activator && activator->IsType( idPlayer::Type ) ) { - Pickup( static_cast( activator ) ); - } -} - -/* -================ -idItem::Event_Respawn -================ -*/ -void idItem::Event_Respawn( void ) { - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_RESPAWN, NULL, false, -1 ); - } - BecomeActive( TH_THINK ); - Show(); - inViewTime = -1000; - lastCycle = -1; - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - SetOrigin( orgOrigin ); - StartSound( "snd_respawn", SND_CHANNEL_ITEM, 0, false, NULL ); - CancelEvents( &EV_RespawnItem ); // don't double respawn -} - -/* -================ -idItem::Event_RespawnFx -================ -*/ -void idItem::Event_RespawnFx( void ) { - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_RESPAWNFX, NULL, false, -1 ); - } - const char *sfx = spawnArgs.GetString( "fxRespawn" ); - if ( sfx && *sfx ) { - idEntityFx::StartFx( sfx, NULL, NULL, this, true ); - } -} - -/* -=============================================================================== - - idMoveableItem - -=============================================================================== -*/ - -CLASS_DECLARATION( idItem, idMoveableItem ) - EVENT( EV_DropToFloor, idMoveableItem::Event_DropToFloor ) - EVENT( EV_Gib, idMoveableItem::Event_Gib ) -END_CLASS - -/* -================ -idMoveableItem::idMoveableItem -================ -*/ -idMoveableItem::idMoveableItem() { - trigger = NULL; - smoke = NULL; - smokeTime = 0; -} - -/* -================ -idMoveableItem::~idMoveableItem -================ -*/ -idMoveableItem::~idMoveableItem() { - if ( trigger ) { - delete trigger; - } -} - -/* -================ -idMoveableItem::Save -================ -*/ -void idMoveableItem::Save( idSaveGame *savefile ) const { - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteClipModel( trigger ); - - savefile->WriteParticle( smoke ); - savefile->WriteInt( smokeTime ); -} - -/* -================ -idMoveableItem::Restore -================ -*/ -void idMoveableItem::Restore( idRestoreGame *savefile ) { - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadClipModel( trigger ); - - savefile->ReadParticle( smoke ); - savefile->ReadInt( smokeTime ); -} - -/* -================ -idMoveableItem::Spawn -================ -*/ -void idMoveableItem::Spawn( void ) -{ - idTraceModel trm; - float density, friction, air_friction_linear, air_friction_angular, bouncyness, tsize; - idStr clipModelName; - idBounds bounds, FrobBounds; - idTraceModel FrobTrm; - int numSides(0); - - // create a frob box separate from the collision box for easier frobbing - // First check if frobbox_mins and frobbox_maxs are set - if ( spawnArgs.GetVector( "frobbox_mins", NULL, FrobBounds[0] ) && - spawnArgs.GetVector( "frobbox_maxs", NULL, FrobBounds[1] ) ) - { - if ( FrobBounds[0][0] > FrobBounds[1][0] || FrobBounds[0][1] >FrobBounds[1][1] || FrobBounds[0][2] > FrobBounds[1][2] ) - { - gameLocal.Error( "Invalid frob box bounds '%s'-'%s' on entity '%s'", FrobBounds[0].ToString(), FrobBounds[1].ToString(), name.c_str() ); - } - } - else - { - spawnArgs.GetFloat( "frobbox_size", "10.0", tsize ); - FrobBounds.Zero(); - FrobBounds.ExpandSelf( tsize ); - } - - if ( spawnArgs.GetInt( "frobbox_cylinder", "0", numSides ) && numSides > 0 ) { - FrobTrm.SetupCylinder( FrobBounds, numSides < 3 ? 3 : numSides ); - } else if ( spawnArgs.GetInt( "frobbox_cone", "0", numSides ) && numSides > 0 ) { - FrobTrm.SetupCone( FrobBounds, numSides < 3 ? 3 : numSides ); - } else { - FrobTrm.SetupBox( FrobBounds ); - } - - // Initialize frob bounds based on previous spawnarg setup - trigger = new idClipModel( FrobTrm ); - trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - trigger->SetContents( CONTENTS_FROBABLE ); - - // check if a clip model is set - spawnArgs.GetString( "clipmodel", "", clipModelName ); - if ( !clipModelName[0] ) { - clipModelName = spawnArgs.GetString( "model" ); // use the visual model - } - - // load the trace model - if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { - gameLocal.Error( "idMoveableItem '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() ); - return; - } - - // if the model should be shrinked - if ( spawnArgs.GetBool( "clipshrink" ) ) { - trm.Shrink( CM_CLIP_EPSILON ); - } - - // get rigid body properties - spawnArgs.GetFloat( "density", "0.5", density ); - density = idMath::ClampFloat( 0.001f, 1000.0f, density ); - spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness ); - bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); - - spawnArgs.GetFloat( "friction", "0.05", friction ); - // reverse compatibility, new contact_friction key replaces friction only if present - if( spawnArgs.FindKey("contact_friction") ) - { - spawnArgs.GetFloat( "contact_friction", "0.05", friction ); - } - spawnArgs.GetFloat( "linear_friction", "0.6", air_friction_linear ); - spawnArgs.GetFloat( "angular_friction", "0.6", air_friction_angular ); - - // setup the physics - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( trm ), density ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetBouncyness( bouncyness ); - physicsObj.SetFriction( air_friction_linear, air_friction_angular, friction ); - physicsObj.SetGravity( gameLocal.GetGravity() ); - physicsObj.SetContents( CONTENTS_RENDERMODEL ); - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); - - // greebo: Allow the entityDef to override the clipmodel contents - if( spawnArgs.FindKey( "clipmodel_contents" ) ) - { - physicsObj.SetContents( spawnArgs.GetInt("clipmodel_contents") ); - } - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - SetPhysics( &physicsObj ); - - smoke = NULL; - smokeTime = 0; - const char *smokeName = spawnArgs.GetString( "smoke_trail" ); - if ( *smokeName != '\0' ) { - smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - smokeTime = gameLocal.time; - BecomeActive( TH_UPDATEPARTICLES ); - } -} - -/* -================ -idMoveableItem::Think -================ -*/ -void idMoveableItem::Think( void ) { - - RunPhysics(); - - if ( thinkFlags & TH_PHYSICS ) { - // update trigger position - trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity ); - } - - if ( thinkFlags & TH_UPDATEPARTICLES ) { - if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { - smokeTime = 0; - BecomeInactive( TH_UPDATEPARTICLES ); - } - } - - Present(); -} - -/* -================ -idMoveableItem::Pickup -================ -*/ -bool idMoveableItem::Pickup( idPlayer *player ) { - bool ret = idItem::Pickup( player ); - if ( ret ) { - trigger->SetContents( 0 ); - } - return ret; -} - -/* -================ -idMoveableItem::DropItem -================ -*/ -idEntity *idMoveableItem::DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay ) { - idDict args; - idEntity *item; - - args.Set( "classname", classname ); - args.Set( "dropped", "1" ); - - // we sometimes drop idMoveables here, so set 'nodrop' to 1 so that it doesn't get put on the floor - args.Set( "nodrop", "1" ); - - if ( activateDelay ) { - args.SetBool( "triggerFirst", true ); - } - - gameLocal.SpawnEntityDef( args, &item ); - if ( item ) { - // set item position - item->GetPhysics()->SetOrigin( origin ); - item->GetPhysics()->SetAxis( axis ); - item->GetPhysics()->SetLinearVelocity( velocity ); - item->UpdateVisuals(); - if ( activateDelay ) { - item->PostEventMS( &EV_Activate, activateDelay, item ); - } - -/** -* TDM: Do not automatically remove dropped items -* (Original Id code automatically removed it after 5 minutes) -**/ - if ( removeDelay ) - { - item->PostEventMS( &EV_Remove, removeDelay ); - } - } - return item; -} - -/* -================ -idMoveableItem::DropItems - - The entity should have the following key/value pairs set: - "def_dropItem" "item def" - "dropItemJoint" "joint name" - "dropItemRotation" "pitch yaw roll" - "dropItemOffset" "x y z" - "skin_drop" "skin name" - To drop multiple items the following key/value pairs can be used: - "def_dropItem" "item def" - "dropItemJoint" "joint name" - "dropItemRotation" "pitch yaw roll" - "dropItemOffset" "x y z" - where is an aribtrary string. -================ -*/ -void idMoveableItem::DropItems( idAnimatedEntity *ent, const char *type, idList *list ) { - const idKeyValue *kv; - const char *skinName, *c, *jointName; - idStr key, key2; - idVec3 origin; - idMat3 axis; - idAngles angles; - const idDeclSkin *skin; - jointHandle_t joint; - idEntity *item; - - // drop all items - kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), NULL ); - while ( kv ) { - - c = kv->GetKey().c_str() + kv->GetKey().Length(); - if ( idStr::Icmp( c - 5, "Joint" ) != 0 && idStr::Icmp( c - 8, "Rotation" ) != 0 ) { - - key = kv->GetKey().c_str() + 4; - key2 = key; - key += "Joint"; - key2 += "Offset"; - jointName = ent->spawnArgs.GetString( key ); - joint = ent->GetAnimator()->GetJointHandle( jointName ); - if ( !ent->GetJointWorldTransform( joint, gameLocal.time, origin, axis ) ) { - gameLocal.Warning( "%s refers to invalid joint '%s' on entity '%s'\n", key.c_str(), jointName, ent->name.c_str() ); - origin = ent->GetPhysics()->GetOrigin(); - axis = ent->GetPhysics()->GetAxis(); - } - if ( g_dropItemRotation.GetString()[0] ) { - angles.Zero(); - sscanf( g_dropItemRotation.GetString(), "%f %f %f", &angles.pitch, &angles.yaw, &angles.roll ); - } else { - key = kv->GetKey().c_str() + 4; - key += "Rotation"; - ent->spawnArgs.GetAngles( key, "0 0 0", angles ); - } - axis = angles.ToMat3() * axis; - - origin += ent->spawnArgs.GetVector( key2, "0 0 0" ); - - item = DropItem( kv->GetValue(), origin, axis, vec3_origin, 0, 0 ); - if ( list && item ) { - list->Append( item ); - } - } - - kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), kv ); - } - - // change the skin to hide all items - skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) ); - if ( skinName[0] ) { - skin = declManager->FindSkin( skinName ); - ent->SetSkin( skin ); - } -} - -/* -====================== -idMoveableItem::WriteToSnapshot -====================== -*/ -void idMoveableItem::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); -} - -/* -====================== -idMoveableItem::ReadFromSnapshot -====================== -*/ -void idMoveableItem::ReadFromSnapshot( const idBitMsgDelta &msg ) { - physicsObj.ReadFromSnapshot( msg ); - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - -/* -============ -idMoveableItem::Gib -============ -*/ -void idMoveableItem::Gib( const idVec3 &dir, const char *damageDefName ) { - // spawn smoke puff - const char *smokeName = spawnArgs.GetString( "smoke_gib" ); - if ( *smokeName != '\0' ) { - const idDeclParticle *smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - gameLocal.smokeParticles->EmitSmoke( smoke, gameLocal.time, gameLocal.random.CRandomFloat(), renderEntity.origin, renderEntity.axis ); - } - // remove the entity - PostEventMS( &EV_Remove, 0 ); -} - -/* -================ -idMoveableItem::Event_DropToFloor -================ -*/ -void idMoveableItem::Event_DropToFloor( void ) { - // the physics will drop the moveable to the floor -} - -/* -============ -idMoveableItem::Event_Gib -============ -*/ -void idMoveableItem::Event_Gib( const char *damageDefName ) { - Gib( idVec3( 0, 0, 1 ), damageDefName ); -} - -void idMoveableItem::Hide( void ) -{ - idEntity::Hide(); - physicsObj.SetContents( 0 ); - trigger->SetContents( 0 ); -} - -void idMoveableItem::Show( void ) -{ - idEntity::Show(); - physicsObj.SetContents( m_preHideContents ); - - trigger->SetContents( CONTENTS_FROBABLE ); -} - diff --git a/game/item.h b/game/item.h deleted file mode 100644 index 8ef00a88e..000000000 --- a/game/item.h +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_ITEM_H__ -#define __GAME_ITEM_H__ - - -/* -=============================================================================== - - Items the player can pick up or use. - -=============================================================================== -*/ - -class idItem : public idEntity { -public: - CLASS_PROTOTYPE( idItem ); - - idItem(); - virtual ~idItem(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - void GetAttributes( idDict &attributes ); - virtual bool GiveToPlayer( idPlayer *player ); - virtual bool Pickup( idPlayer *player ); - virtual void Think( void ); - virtual void Present(); - - - enum { - EVENT_PICKUP = idEntity::EVENT_MAXEVENTS, - EVENT_RESPAWN, - EVENT_RESPAWNFX, - EVENT_MAXEVENTS - }; - - virtual void ClientPredictionThink( void ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - // networking - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - // TDM: SZ: UpdateVisuals is overridden to check if the object moved in case - // we have to spawn an absence entity - virtual void UpdateVisuals( void ); - - // This indicates which team owns the item (or thinks it does :P ) - int ownerTeam; - -private: - idVec3 orgOrigin; - bool spin; - bool pulse; - bool canPickUp; - - // This should scale from 0.0 (none) to 1.0 (hard to miss) - float noticeabilityIfAbsent; - - - // Has the original origin been set? - bool b_orgOriginSet; - idEntityPtr absenceEntityPtr; - - // for item pulse effect - int itemShellHandle; - const idMaterial * shellMaterial; - - // used to update the item pulse effect - mutable bool inView; - mutable int inViewTime; - mutable int lastCycle; - mutable int lastRenderViewTime; - - bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); - static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); - - void Event_DropToFloor( void ); - void Event_Touch( idEntity *other, trace_t *trace ); - void Event_Trigger( idEntity *activator ); - void Event_Respawn( void ); - void Event_RespawnFx( void ); -}; - - -class idMoveableItem : public idItem { -public: - CLASS_PROTOTYPE( idMoveableItem ); - - idMoveableItem(); - virtual ~idMoveableItem(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - virtual void Think( void ); - virtual bool Pickup( idPlayer *player ); - - static void DropItems( idAnimatedEntity *ent, const char *type, idList *list ); - static idEntity * DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - -protected: - void Hide(); - void Show(); - -private: - idPhysics_RigidBody physicsObj; - idClipModel * trigger; - const idDeclParticle * smoke; - int smokeTime; - - void Gib( const idVec3 &dir, const char *damageDefName ); - - void Event_DropToFloor( void ); - void Event_Gib( const char *damageDefName ); -}; - -#endif /* !__GAME_ITEM_H__ */ diff --git a/game/light.cpp b/game/light.cpp deleted file mode 100644 index 276b1bfb5..000000000 --- a/game/light.cpp +++ /dev/null @@ -1,2017 +0,0 @@ -/*************************************************************************** - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/Grabber.h" - -/* -=============================================================================== - - idLight - -=============================================================================== -*/ - -const idEventDef EV_Light_SetShader( "setShader", "s" ); -const idEventDef EV_Light_GetLightParm( "getLightParm", "d", 'f' ); -const idEventDef EV_Light_SetLightParm( "setLightParm", "df" ); -const idEventDef EV_Light_SetLightParms( "setLightParms", "ffff" ); -const idEventDef EV_Light_SetRadiusXYZ( "setRadiusXYZ", "fff" ); -const idEventDef EV_Light_SetRadius( "setRadius", "f" ); -const idEventDef EV_Light_On( "On", NULL ); -const idEventDef EV_Light_Off( "Off", NULL ); -const idEventDef EV_Light_FadeOut( "fadeOutLight", "f" ); -const idEventDef EV_Light_FadeIn( "fadeInLight", "f" ); - -// TDM Additions: -const idEventDef EV_Light_GetLightOrigin( "getLightOrigin", NULL, 'v' ); -const idEventDef EV_Light_SetLightOrigin( "setLightOrigin", "v" ); -const idEventDef EV_Light_GetLightLevel ("getLightLevel", NULL, 'f'); -const idEventDef EV_Light_AddToLAS("addToLAS", NULL); -const idEventDef EV_Light_FadeToLight( "fadeToLight", "vf" ); -const idEventDef EV_Smoking("smoking", "d"); - - -CLASS_DECLARATION( idEntity, idLight ) - EVENT( EV_Light_SetShader, idLight::Event_SetShader ) - EVENT( EV_Light_GetLightParm, idLight::Event_GetLightParm ) - EVENT( EV_Light_SetLightParm, idLight::Event_SetLightParm ) - EVENT( EV_Light_SetLightParms, idLight::Event_SetLightParms ) - EVENT( EV_Light_SetRadiusXYZ, idLight::Event_SetRadiusXYZ ) - EVENT( EV_Light_SetRadius, idLight::Event_SetRadius ) - EVENT( EV_Hide, idLight::Event_Hide ) - EVENT( EV_Show, idLight::Event_Show ) - EVENT( EV_Light_On, idLight::Event_On ) - EVENT( EV_Light_Off, idLight::Event_Off ) - EVENT( EV_Activate, idLight::Event_ToggleOnOff ) - EVENT( EV_PostSpawn, idLight::Event_SetSoundHandles ) - EVENT( EV_Light_FadeOut, idLight::Event_FadeOut ) - EVENT( EV_Light_FadeIn, idLight::Event_FadeIn ) - - EVENT( EV_Light_SetLightOrigin, idLight::Event_SetLightOrigin ) - EVENT( EV_Light_GetLightOrigin, idLight::Event_GetLightOrigin ) - EVENT( EV_Light_GetLightLevel, idLight::Event_GetLightLevel ) - EVENT( EV_Light_AddToLAS, idLight::Event_AddToLAS ) - EVENT( EV_InPVS, idLight::Event_InPVS ) - EVENT( EV_Light_FadeToLight, idLight::Event_FadeToLight ) - EVENT( EV_Smoking, idLight::Event_Smoking ) // grayman #2603 -END_CLASS - - -/* -================ -idGameEdit::ParseSpawnArgsToRenderLight - -parse the light parameters -this is the canonical renderLight parm parsing, -which should be used by dmap and the editor -================ -*/ -void idGameEdit::ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight ) { - bool gotTarget, gotUp, gotRight; - const char *texture; - idVec3 color; - - memset( renderLight, 0, sizeof( *renderLight ) ); - - if (!args->GetVector("light_origin", "", renderLight->origin)) { - args->GetVector( "origin", "", renderLight->origin ); - } - - gotTarget = args->GetVector( "light_target", "", renderLight->target ); - gotUp = args->GetVector( "light_up", "", renderLight->up ); - gotRight = args->GetVector( "light_right", "", renderLight->right ); - args->GetVector( "light_start", "0 0 0", renderLight->start ); - if ( !args->GetVector( "light_end", "", renderLight->end ) ) { - renderLight->end = renderLight->target; - } - - // we should have all of the target/right/up or none of them - if ( ( gotTarget || gotUp || gotRight ) != ( gotTarget && gotUp && gotRight ) ) { - gameLocal.Printf( "Light at (%f,%f,%f) has bad target info\n", - renderLight->origin[0], renderLight->origin[1], renderLight->origin[2] ); - return; - } - - if ( !gotTarget ) { - renderLight->pointLight = true; - - // allow an optional relative center of light and shadow offset - args->GetVector( "light_center", "0 0 0", renderLight->lightCenter ); - - // create a point light - if (!args->GetVector( "light_radius", "300 300 300", renderLight->lightRadius ) ) { - float radius; - - args->GetFloat( "light", "300", radius ); - renderLight->lightRadius[0] = renderLight->lightRadius[1] = renderLight->lightRadius[2] = radius; - } - } - - // get the rotation matrix in either full form, or single angle form - idAngles angles; - idMat3 mat; - if ( !args->GetMatrix( "light_rotation", "1 0 0 0 1 0 0 0 1", mat ) ) { - if ( !args->GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", mat ) ) { - args->GetFloat( "angle", "0", angles[ 1 ] ); - angles[ 0 ] = 0; - angles[ 1 ] = idMath::AngleNormalize360( angles[ 1 ] ); - angles[ 2 ] = 0; - mat = angles.ToMat3(); - } - } - - // fix degenerate identity matrices - mat[0].FixDegenerateNormal(); - mat[1].FixDegenerateNormal(); - mat[2].FixDegenerateNormal(); - - renderLight->axis = mat; - - // check for other attributes - args->GetVector( "_color", "1 1 1", color ); - renderLight->shaderParms[ SHADERPARM_RED ] = color[0]; - renderLight->shaderParms[ SHADERPARM_GREEN ] = color[1]; - renderLight->shaderParms[ SHADERPARM_BLUE ] = color[2]; - args->GetFloat( "shaderParm3", "1", renderLight->shaderParms[ SHADERPARM_TIMESCALE ] ); - if ( !args->GetFloat( "shaderParm4", "0", renderLight->shaderParms[ SHADERPARM_TIMEOFFSET ] ) ) { - // offset the start time of the shader to sync it to the game time - renderLight->shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - } - - args->GetFloat( "shaderParm5", "0", renderLight->shaderParms[5] ); - args->GetFloat( "shaderParm6", "0", renderLight->shaderParms[6] ); - args->GetFloat( "shaderParm7", "0", renderLight->shaderParms[ SHADERPARM_MODE ] ); - args->GetBool( "noshadows", "0", renderLight->noShadows ); - args->GetBool( "nospecular", "0", renderLight->noSpecular ); - args->GetBool( "parallel", "0", renderLight->parallel ); - - args->GetString( "texture", "lights/squarelight1", &texture ); - // allow this to be NULL - renderLight->shader = declManager->FindMaterial( texture, false ); -} - -/* -================ -idLight::UpdateChangeableSpawnArgs -================ -*/ -void idLight::UpdateChangeableSpawnArgs( const idDict *source ) { - - idEntity::UpdateChangeableSpawnArgs( source ); - - if ( source ) { - source->Print(); - } - FreeSoundEmitter( true ); - gameEdit->ParseSpawnArgsToRefSound( source ? source : &spawnArgs, &refSound ); - if ( refSound.shader && !refSound.waitfortrigger ) { - StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); - } - - gameEdit->ParseSpawnArgsToRenderLight( source ? source : &spawnArgs, &renderLight ); - - UpdateVisuals(); -} - -/* -================ -idLight::idLight -================ -*/ -idLight::idLight() -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX %s\r", this, __FUNCTION__); - - memset( &renderLight, 0, sizeof( renderLight ) ); - localLightOrigin = vec3_zero; - localLightAxis = mat3_identity; - lightDefHandle = -1; - levels = 0; - currentLevel = 0; - baseColor = vec3_zero; - breakOnTrigger = false; - count = 0; - triggercount = 0; - lightParent = NULL; - switchList.Clear(); // grayman #2603 - list of my switches - beingRelit = false; // grayman #2603 - chanceNegativeBark = 1.0f; // grayman #2603 - whenTurnedOff = 0; // grayman #2603 - nextTimeLightOutBark = 0; // grayman #2603 - relightAfter = 0; // grayman #2603 - aiBarks.Clear(); // grayman #2603 - - fadeFrom.Set( 1, 1, 1, 1 ); - fadeTo.Set( 1, 1, 1, 1 ); - fadeStart = 0; - fadeEnd = 0; - soundWasPlaying = false; - m_MaxLightRadius = 0.0f; - m_LightMaterial = NULL; - - /*! - Darkmod LAS - */ - LASAreaIndex = -1; - -} - -/* -================ -idLight::~idLight -================ -*/ -idLight::~idLight() -{ - if ( lightDefHandle != -1 ) { - gameRenderWorld->FreeLightDef( lightDefHandle ); - } - - /*! - * Darkmod LAS - */ - // Remove light from LAS - if (LASAreaIndex != -1) - { - LAS.removeLight(this); - } - - /*! - Darkmod player lighting - */ - idPlayer* player = gameLocal.GetLocalPlayer(); - if (player != NULL) - { - player->RemoveLight(this); - } -} - -/* -================ -idLight::Save - -archives object for save game file -================ -*/ -void idLight::Save( idSaveGame *savefile ) const { - savefile->WriteRenderLight( renderLight ); - - savefile->WriteBool( renderLight.prelightModel != NULL ); - - savefile->WriteVec3( localLightOrigin ); - savefile->WriteMat3( localLightAxis ); - - savefile->WriteInt( levels ); - savefile->WriteInt( currentLevel ); - - savefile->WriteVec3( baseColor ); - savefile->WriteBool( breakOnTrigger ); - savefile->WriteInt( count ); - savefile->WriteInt( triggercount ); - savefile->WriteObject( lightParent ); - savefile->WriteBool(beingRelit); // grayman #2603 - savefile->WriteFloat(chanceNegativeBark); // grayman #2603 - savefile->WriteInt(whenTurnedOff); // grayman #2603 - savefile->WriteInt(nextTimeLightOutBark); // grayman #2603 - savefile->WriteInt(relightAfter); // grayman #2603 - savefile->WriteFloat(nextTimeVerticalCheck); // grayman #2603 - savefile->WriteBool(smoking); // grayman #2603 - savefile->WriteInt(whenToDouse); // grayman #2603 - - savefile->WriteInt(switchList.Num()); // grayman #2603 - for (int i = 0; i < switchList.Num(); i++) - { - switchList[i].Save(savefile); - } - - savefile->WriteVec4( fadeFrom ); - savefile->WriteVec4( fadeTo ); - savefile->WriteInt( fadeStart ); - savefile->WriteInt( fadeEnd ); - savefile->WriteBool( soundWasPlaying ); - - // grayman #2603 - ai bark counts - - savefile->WriteInt(aiBarks.Num()); - for (int i = 0 ; i < aiBarks.Num() ; i++) - { - AIBarks barks = aiBarks[i]; - - savefile->WriteInt(barks.count); - barks.ai.Save(savefile); - } - - savefile->WriteFloat(m_MaxLightRadius); - savefile->WriteInt(LASAreaIndex); - - // Don't save m_LightMaterial -} - -/* -================ -idLight::Restore - -unarchives object from save game file -================ -*/ -void idLight::Restore( idRestoreGame *savefile ) { - bool hadPrelightModel; - - savefile->ReadRenderLight( renderLight ); - - savefile->ReadBool( hadPrelightModel ); - renderLight.prelightModel = renderModelManager->CheckModel( va( "_prelight_%s", name.c_str() ) ); - if ( ( renderLight.prelightModel == NULL ) && hadPrelightModel ) { - assert( 0 ); - if ( developer.GetBool() ) { - // we really want to know if this happens - gameLocal.Error( "idLight::Restore: prelightModel '_prelight_%s' not found", name.c_str() ); - } else { - // but let it slide after release - gameLocal.Warning( "idLight::Restore: prelightModel '_prelight_%s' not found", name.c_str() ); - } - } - - savefile->ReadVec3( localLightOrigin ); - savefile->ReadMat3( localLightAxis ); - - savefile->ReadInt( levels ); - savefile->ReadInt( currentLevel ); - - savefile->ReadVec3( baseColor ); - savefile->ReadBool( breakOnTrigger ); - savefile->ReadInt( count ); - savefile->ReadInt( triggercount ); - savefile->ReadObject( reinterpret_cast( lightParent ) ); - savefile->ReadBool( beingRelit ); // grayman #2603 - savefile->ReadFloat( chanceNegativeBark ); // grayman #2603 - savefile->ReadInt( whenTurnedOff ); // grayman #2603 - savefile->ReadInt( nextTimeLightOutBark ); // grayman #2603 - savefile->ReadInt( relightAfter ); // grayman #2603 - savefile->ReadFloat(nextTimeVerticalCheck); // grayman #2603 - savefile->ReadBool(smoking); // grayman #2603 - savefile->ReadInt(whenToDouse); // grayman #2603 - - // grayman #2603 - switchList.Clear(); - int num; - savefile->ReadInt(num); - switchList.SetNum(num); - for (int i = 0; i < num; i++) - { - switchList[i].Restore(savefile); - } - - savefile->ReadVec4( fadeFrom ); - savefile->ReadVec4( fadeTo ); - savefile->ReadInt( fadeStart ); - savefile->ReadInt( fadeEnd ); - savefile->ReadBool( soundWasPlaying ); - - // grayman #2603 - ai bark counts - - savefile->ReadInt(num); - aiBarks.SetNum(num); - for (int i = 0 ; i < num ; i++) - { - savefile->ReadInt(aiBarks[i].count); - aiBarks[i].ai.Restore(savefile); - } - - savefile->ReadFloat(m_MaxLightRadius); - savefile->ReadInt(LASAreaIndex); - - lightDefHandle = -1; - - SetLightLevel(); - - m_MaterialName = NULL; - spawnArgs.GetString( "texture", "lights/squarelight1", &m_MaterialName); - - // Re-acquire light material, now that the material name is known - m_LightMaterial = g_Global.GetMaterial(m_MaterialName); -} - -/* -================ -idLight::Spawn -================ -*/ -void idLight::Spawn( void ) -{ - bool start_off; - const char *demonic_shader; - - // do the parsing the same way dmap and the editor do - gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &renderLight ); - - // we need the origin and axis relative to the physics origin/axis - localLightOrigin = ( renderLight.origin - GetPhysics()->GetOrigin() ) * GetPhysics()->GetAxis().Transpose(); - localLightAxis = renderLight.axis * GetPhysics()->GetAxis().Transpose(); - - // set the base color from the shader parms - baseColor.Set( renderLight.shaderParms[ SHADERPARM_RED ], renderLight.shaderParms[ SHADERPARM_GREEN ], renderLight.shaderParms[ SHADERPARM_BLUE ] ); - - // set the number of light levels - spawnArgs.GetInt( "levels", "1", levels ); - currentLevel = levels; - if ( levels <= 0 ) { - gameLocal.Error( "Invalid light level set on entity #%d(%s)", entityNumber, name.c_str() ); - } - - // make sure the demonic shader is cached - if ( spawnArgs.GetString( "mat_demonic", NULL, &demonic_shader ) ) { - declManager->FindType( DECL_MATERIAL, demonic_shader ); - } - - // game specific functionality, not mirrored in - // editor or dmap light parsing - - // also put the light texture on the model, so light flares - // can get the current intensity of the light - renderEntity.referenceShader = renderLight.shader; - - lightDefHandle = -1; // no static version yet - - // see if an optimized shadow volume exists - // the renderer will ignore this value after a light has been moved, - // but there may still be a chance to get it wrong if the game moves - // a light before the first present, and doesn't clear the prelight - renderLight.prelightModel = 0; - if ( name[ 0 ] ) { - // this will return 0 if not found - renderLight.prelightModel = renderModelManager->CheckModel( va( "_prelight_%s", name.c_str() ) ); - } - - spawnArgs.GetBool( "start_off", "0", start_off ); - if ( start_off ) { - Off(); - } - - health = spawnArgs.GetInt( "health", "0" ); - spawnArgs.GetBool( "break", "0", breakOnTrigger ); - spawnArgs.GetInt( "count", "1", count ); - - triggercount = 0; - - fadeFrom.Set( 1, 1, 1, 1 ); - fadeTo.Set( 1, 1, 1, 1 ); - fadeStart = 0; - fadeEnd = 0; - - // load visual and collision models - LoadModels(); - - PostEventMS( &EV_PostSpawn, 0 ); - - UpdateVisuals(); - - if(renderLight.pointLight == true) - m_MaxLightRadius = renderLight.lightRadius.Length(); - else - { - idVec3 pos = GetPhysics()->GetOrigin(); - idVec3 max = renderLight.target + renderLight.right + renderLight.up; - m_MaxLightRadius = max.Length(); - } - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("this: %08lX [%s] MaxLightRadius: %f\r", this, name.c_str(), m_MaxLightRadius); - - m_MaterialName = NULL; - spawnArgs.GetString( "texture", "lights/squarelight1", &m_MaterialName); - if(m_MaterialName != NULL) - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light has an image: %s\r", m_MaterialName); - - idImage *pImage; - if(renderLight.shader != NULL && (pImage = renderLight.shader->LightFalloffImage()) != NULL) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light has an image: %08lX\r", pImage); - } - - // grayman #2603 - set up flames for vertical check - - idStr lightType = spawnArgs.GetString(AIUSE_LIGHTTYPE_KEY); - if (lightType == AIUSE_LIGHTTYPE_TORCH) - { - if (!spawnArgs.GetBool("should_be_vert","0")) // don't check verticality if it doesn't matter - { - nextTimeVerticalCheck = idMath::INFINITY; // never - } - else - { - nextTimeVerticalCheck = gameLocal.time + 3000 + gameLocal.random.RandomFloat()*3000; // randomize so checks are done at different times - } - } - else // non-flames - { - nextTimeVerticalCheck = idMath::INFINITY; // never - } - - smoking = false; // grayman #2603 - - whenToDouse = -1; // grayman #2603 - - // Sophisiticated Zombie (DMH) - // Darkmod Light Awareness System: Also need to add light to LAS - - PostEventMS(&EV_Light_AddToLAS, 40); - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("this: %08lX [%s] noShadows: %u noSpecular: %u pointLight: %u parallel: %u\r", - this, name.c_str(), - renderLight.noShadows, - renderLight.noSpecular, - renderLight.pointLight, - renderLight.parallel); - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Red: %f Green: %f Blue: %f\r", baseColor.x, baseColor.y, baseColor.z); - - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Origin", GetPhysics()->GetOrigin()); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Radius", renderLight.lightRadius); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Center", renderLight.lightCenter); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Target", renderLight.target); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Right", renderLight.right); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Up", renderLight.up); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "Start", renderLight.start); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "End", renderLight.end); -} - -/* -================ -idLight::SetLightLevel -================ -*/ -void idLight::SetLightLevel( void ) { - idVec3 color; - float intensity; - - intensity = ( float )currentLevel / ( float )levels; - color = baseColor * intensity; - renderLight.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; - renderLight.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ]; - renderLight.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; - renderEntity.shaderParms[ SHADERPARM_RED ] = color[ 0 ]; - renderEntity.shaderParms[ SHADERPARM_GREEN ]= color[ 1 ]; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ]; - PresentLightDefChange(); - PresentModelDefChange(); -} - -/* -================ -tels: idLight::GetLightOrigin returns the origin of the light in the world. This -is different from the physics origin, since the light can be offset. -================ -void idLight::GetLightOrigin( idVec3 &out ) const { - out[0] = renderLight.origin[0]; - out[1] = renderLight.origin[1]; - out[2] = renderLight.origin[2]; -} -*/ - -/* -================ -idLight::GetColor -================ -*/ -void idLight::GetColor( idVec3 &out ) const { - out[ 0 ] = renderLight.shaderParms[ SHADERPARM_RED ]; - out[ 1 ] = renderLight.shaderParms[ SHADERPARM_GREEN ]; - out[ 2 ] = renderLight.shaderParms[ SHADERPARM_BLUE ]; -} - -/* -================ -idLight::GetColor -================ -*/ -void idLight::GetColor( idVec4 &out ) const { - out[ 0 ] = renderLight.shaderParms[ SHADERPARM_RED ]; - out[ 1 ] = renderLight.shaderParms[ SHADERPARM_GREEN ]; - out[ 2 ] = renderLight.shaderParms[ SHADERPARM_BLUE ]; - out[ 3 ] = renderLight.shaderParms[ SHADERPARM_ALPHA ]; -} - -/* -================ -idLight::SetColor -================ -*/ -void idLight::SetColor( const float red, const float green, const float blue ) -{ - // Tels: If the light is currently fading, stop this: - fadeEnd = 0; - BecomeInactive( TH_THINK ); - baseColor.Set( red, green, blue ); - SetLightLevel(); -} - -/* -================ -idLight::SetColor -================ -*/ -void idLight::SetColor( const idVec4 &color ) { - // Tels: If the light is currently fading, stop this: - fadeEnd = 0; - BecomeInactive( TH_THINK ); - baseColor = color.ToVec3(); - renderLight.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; - SetLightLevel(); -} - -/* -================ -idLight::SetShader -================ -*/ -void idLight::SetShader( const char *shadername ) { - // allow this to be NULL - renderLight.shader = declManager->FindMaterial( shadername, false ); - PresentLightDefChange(); -} - -/* -================ -idLight::SetLightParm -================ -*/ -void idLight::SetLightParm( int parmnum, float value ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Error( "shader parm index (%d) out of range", parmnum ); - } - - renderLight.shaderParms[ parmnum ] = value; - PresentLightDefChange(); -} - -/* -================ -idLight::SetLightParms -================ -*/ -void idLight::SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { - renderLight.shaderParms[ SHADERPARM_RED ] = parm0; - renderLight.shaderParms[ SHADERPARM_GREEN ] = parm1; - renderLight.shaderParms[ SHADERPARM_BLUE ] = parm2; - renderLight.shaderParms[ SHADERPARM_ALPHA ] = parm3; - renderEntity.shaderParms[ SHADERPARM_RED ] = parm0; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = parm1; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = parm2; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = parm3; - PresentLightDefChange(); - PresentModelDefChange(); -} - -/* -================ -idLight::SetRadiusXYZ -================ -*/ -void idLight::SetRadiusXYZ( const float x, const float y, const float z ) { - renderLight.lightRadius[0] = x; - renderLight.lightRadius[1] = y; - renderLight.lightRadius[2] = z; - PresentLightDefChange(); -} - -/* -================ -idLight::SetRadius -================ -*/ -void idLight::SetRadius( const float radius ) { - renderLight.lightRadius[0] = renderLight.lightRadius[1] = renderLight.lightRadius[2] = radius; - PresentLightDefChange(); -} - -/* - * ================ - * Tels: idLight:GetRadius - * ================ - * */ -void idLight::GetRadius( idVec3 &out ) const { - out.x = renderLight.lightRadius[0]; - out.y = renderLight.lightRadius[1]; - out.z = renderLight.lightRadius[2]; -} - -/* -================ -idLight::On -================ -*/ -void idLight::On( void ) { - - currentLevel = levels; - // offset the start time of the shader to sync it to the game time - renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - if ( ( soundWasPlaying || refSound.waitfortrigger ) && refSound.shader ) { - StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL ); - soundWasPlaying = false; - } - - const function_t* func = scriptObject.GetFunction("LightsOn"); - if (func == NULL) - { - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::On: 'LightsOn' not found in local space, checking for global.\r"); - func = gameLocal.program.FindFunction("LightsOn"); - } - - if (func != NULL) - { - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::On: turning light on\r"); - idThread *pThread = new idThread(func); - pThread->CallFunction(this,func, true); - pThread->DelayedStart(0); - } - else - { - DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("idLight::On: 'LightsOn' not found!\r"); - } - - aiBarks.Clear(); // grayman #2603 - let the AI comment again - - -// grayman #2603 - let script change skins, plus set the vis stim. - -/* const char *skinName; - const idDeclSkin *skin; - - // Tels: set "skin_lit" if it is defined - spawnArgs.GetString( "skin_lit", "", &skinName ); - skin = declManager->FindSkin( skinName ); - if (skin) { - SetSkin( skin ); - // set the spawnarg to the current active skin - spawnArgs.Set( "skin", skinName ); - } - */ - SetLightLevel(); - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idLight::Off -================ -*/ -void idLight::Off( const bool stopSound ) { - - currentLevel = 0; - - if ( stopSound && refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) { - StopSound( SND_CHANNEL_ANY, false ); - soundWasPlaying = true; - } - - const function_t* func = scriptObject.GetFunction("LightsOff"); - if (func == NULL) - { - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::Off: 'LightsOff' not found in local space, checking for global.\r"); - func = gameLocal.program.FindFunction("LightsOff"); - } - - if (func != NULL) - { - DM_LOG(LC_STIM_RESPONSE, LT_DEBUG)LOGSTRING("idLight::Off: turning light off\r"); - idThread *pThread = new idThread(func); - pThread->CallFunction(this,func,true); - pThread->DelayedStart(0); - whenTurnedOff = gameLocal.time; // grayman #2603 - } - else - { - DM_LOG(LC_STIM_RESPONSE, LT_ERROR)LOGSTRING("idLight::Off: 'LightsOff' not found!\r"); - } - -// grayman #2603 - let script change skins, plus set the vis stim. - -/* // Tels: set "skin_unlit" if it is defined - const char *skinName; - const idDeclSkin *skin; - spawnArgs.GetString( "skin_unlit", "", &skinName ); - skin = declManager->FindSkin( skinName ); - if (skin) { - SetSkin( skin ); - // set the spawnarg to the current active skin - spawnArgs.Set( "skin", skinName ); - } - */ - SetLightLevel(); - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idLight::Fade -================ -*/ -void idLight::Fade( const idVec4 &to, float fadeTime ) { - GetColor( fadeFrom ); - // Tels: we already have the same color we should become, so we can skip this - if (fadeFrom == to) - { - return; - } - // Tels: If the fade time is shorter than 1/60 (e.g. one frame), just set the color directly - if (fadeTime < 0.0167f) - { - if (to == colorBlack) - { - // The fade does not happen (time too short), so Off() would not be called so do it now (#2440) - // avoid the sound stopping, because this might be snd_extinguished - Off( false ); - } - else - { - SetColor(to); - } - return; - } - fadeTo = to; - fadeStart = gameLocal.time; - fadeEnd = gameLocal.time + SEC2MS( fadeTime ); - BecomeActive( TH_THINK ); -} - -/* -================ -idLight::FadeOut -================ -*/ -void idLight::FadeOut( float time ) { - if (baseColor.x == 0 && baseColor.y == 0 && baseColor.z == 0) - { - // The fade would not happen, so Off() would not be called, so do it now (#2440) - // avoid the sound stopping, because this might be snd_extinguished - Off( false ); - } - else - { - // Tels: Think() will call Off() once the fade is done, since we use colorBlack as fade target - Fade( colorBlack, time ); - } -} - -/* -================ -idLight::FadeIn -================ -*/ -void idLight::FadeIn( float time ) { - idVec3 color; - idVec4 color4; - - currentLevel = levels; - // restore the original light color - spawnArgs.GetVector( "_color", "1 1 1", color ); - color4.Set( color.x, color.y, color.z, 1.0f ); - Fade( color4, time ); -} - -/* -================ -idLight::FadeTo -================ -*/ -void idLight::FadeTo( idVec3 color, float time ) { - - idVec4 color4; - - // tels: TODO: this step sets the intensity of the light to the maximum, - // do we really want this? - currentLevel = levels; - color4.Set( color.x, color.y, color.z, 1.0f ); - Fade( color4, time ); -} - -/* -================ -idLight::Killed -================ -*/ -void idLight::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - BecomeBroken( attacker ); -} - -int idLight::GetLightLevel() const -{ - return currentLevel; -} - -/* -================ -idLight::BecomeBroken -================ -*/ -void idLight::BecomeBroken( idEntity *activator ) { - const char *damageDefName; - - idEntity::BecomeBroken ( activator ); - - if ( gameLocal.isServer ) { - - ServerSendEvent( EVENT_BECOMEBROKEN, NULL, true, -1 ); - - if ( spawnArgs.GetString( "def_damage", "", &damageDefName ) ) { - idVec3 origin = renderEntity.origin + renderEntity.bounds.GetCenter() * renderEntity.axis; - gameLocal.RadiusDamage( origin, activator, activator, this, this, damageDefName ); - } - - } - - ActivateTargets( activator ); - - // offset the start time of the shader to sync it to the game time - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - // set the state parm - renderEntity.shaderParms[ SHADERPARM_MODE ] = 1; - renderLight.shaderParms[ SHADERPARM_MODE ] = 1; - - // if the light has a sound, either start the alternate (broken) sound, or stop the sound - const char *parm = spawnArgs.GetString( "snd_broken" ); - if ( refSound.shader || ( parm && *parm ) ) { - StopSound( SND_CHANNEL_ANY, false ); - const idSoundShader *alternate = refSound.shader ? refSound.shader->GetAltSound() : declManager->FindSound( parm ); - if ( alternate ) { - // start it with no diversity, so the leadin break sound plays - refSound.referenceSound->StartSound( alternate, SND_CHANNEL_ANY, 0.0, 0 ); - } - } - - parm = spawnArgs.GetString( "mtr_broken" ); - if ( parm && *parm ) { - SetShader( parm ); - } - - UpdateVisuals(); -} - -/* -================ -idLight::PresentLightDefChange -================ -*/ -void idLight::PresentLightDefChange( void ) -{ -/* -DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s] Radius ( %0.3f / %0.3f / %03f )\r", this, name.c_str(), - renderLight.lightRadius[0], // x - renderLight.lightRadius[1], // y - renderLight.lightRadius[2]); // z -*/ - - // let the renderer apply it to the world - if ( ( lightDefHandle != -1 ) ) { - gameRenderWorld->UpdateLightDef( lightDefHandle, &renderLight ); - } else { - lightDefHandle = gameRenderWorld->AddLightDef( &renderLight ); - } -} - -/* -================ -idLight::PresentModelDefChange -================ -*/ -void idLight::PresentModelDefChange( void ) { - - if ( !renderEntity.hModel || IsHidden() ) { - return; - } - - // add to refresh list - if ( modelDefHandle == -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } -} - -/* -================ -idLight::Present -================ -*/ -void idLight::Present( void ) { - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { - return; - } - - // Clear the bounds, so idLight::PresentRenderTrigger() has a way to know - // if idEntity::PresentRenderTrigger() added anything. - m_renderTrigger.bounds.Clear(); - - // add the model - idEntity::Present(); - - // current transformation - renderLight.axis = localLightAxis * GetPhysics()->GetAxis(); - renderLight.origin = GetPhysics()->GetOrigin() + GetPhysics()->GetAxis() * localLightOrigin; - - // reference the sound for shader synced effects - if ( lightParent ) { - renderLight.referenceSound = lightParent->GetSoundEmitter(); - renderEntity.referenceSound = lightParent->GetSoundEmitter(); - } - else { - renderLight.referenceSound = refSound.referenceSound; - renderEntity.referenceSound = refSound.referenceSound; - } - - // update the renderLight and renderEntity to render the light and flare - PresentLightDefChange(); - PresentModelDefChange(); - PresentRenderTrigger(); -} - -/* -================ -idLight::IsVertical -*/ - -bool idLight::IsVertical(float degreesFromVertical) -{ - idStr lightType = spawnArgs.GetString(AIUSE_LIGHTTYPE_KEY); - bool shouldBeVert = spawnArgs.GetBool("should_be_vert","0"); - - // Only makes sense for flames with the "douse_horiz" spawnarg - - if ((lightType == AIUSE_LIGHTTYPE_TORCH) && shouldBeVert) - { - const idVec3& gravityNormal = GetPhysics()->GetGravityNormal(); - idMat3 axis = GetPhysics()->GetAxis(); - idVec3 result(0,0,0); - axis.ProjectVector(-gravityNormal,result); - float verticality = result * (-gravityNormal); - if (verticality < idMath::Cos(DEG2RAD(degreesFromVertical))) // > 10 degrees from vertical - { - return false; - } - } - return true; -} - -/* -================ -idLight::Think -================ -*/ -void idLight::Think( void ) { - idVec4 color; - - if ( thinkFlags & TH_THINK ) { - if ( fadeEnd > 0 ) { - if ( gameLocal.time < fadeEnd ) { - color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) ); - } else { - color = fadeTo; - fadeEnd = 0; - // Tels: Fix issues like 2440: FadeOff() does not switch the light to the off state - if (color[0] == 0 && color[1] == 0 && color[2] == 0) - { - // avoid the sound stopping, because this might be snd_extinguished - Off( false ); - } - BecomeInactive( TH_THINK ); - } - // don't call SetColor(), as it stops the fade, instead inline the second part of it: - baseColor = color.ToVec3(); - renderLight.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; - renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ]; - SetLightLevel(); - } - } - - // grayman #2603 - every so often, check if a lit flame not being held by an AI is non-vertical (> 45 degrees from vertical). if so, douse it - - if (gameLocal.time >= nextTimeVerticalCheck) - { - nextTimeVerticalCheck = gameLocal.time + 1000; - - if (GetLightLevel() > 0) // is it on? - { - bool isVertical = IsVertical(45); // w/in 45 degrees of vertical? - if (!isVertical) - { - // is an AI holding this light? - - bool isHeld = false; - idEntity* bindMaster = GetBindMaster(); - while (bindMaster != NULL) // not held when bindMaster == NULL - { - if (bindMaster->IsType(idAI::Type)) - { - isHeld = true; - break; - } - bindMaster = bindMaster->GetBindMaster(); // go up the hierarchy - } - - if (!isHeld) - { - // Is the player holding this light? - - CGrabber* grabber = gameLocal.m_Grabber; - if (grabber) - { - idEntity* heldEnt = grabber->GetSelected(); - if (heldEnt) - { - bindMaster = GetBindMaster(); - while (bindMaster != NULL) // not held when bindMaster == NULL - { - if (heldEnt == bindMaster) - { - isHeld = true; - break; - } - bindMaster = bindMaster->GetBindMaster(); - } - } - } - } - - if (!isHeld) - { - if (whenToDouse == -1) - { - whenToDouse = gameLocal.time + 5000; // douse this later if still non-vertical - BecomeActive(TH_DOUSING); // set this so you can continue thinking after coming to rest and TH_PHYSICS shuts off - } - else if (gameLocal.time >= whenToDouse) - { - CallScriptFunctionArgs("frob_extinguish", true, 0, "e", this); - whenToDouse = -1; // reset - BecomeInactive(TH_DOUSING); // reset - } - } - else - { - whenToDouse = -1; // non-vertical, but it's being held, so turn off any latched non-vertical douse - BecomeInactive(TH_DOUSING); // reset - } - } - else - { - whenToDouse = -1; // vertical, so turn off any latched non-vertical douse - BecomeInactive(TH_DOUSING); // reset - } - } - } - - RunPhysics(); - Present(); -} - -/* -================ -idLight::GetPhysicsToSoundTransform -================ -*/ -bool idLight::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { - origin = localLightOrigin + renderLight.lightCenter; - axis = localLightAxis * GetPhysics()->GetAxis(); - return true; -} - -/* -================ -idLight::FreeLightDef -================ -*/ -void idLight::FreeLightDef( void ) { - if ( lightDefHandle != -1 ) { - gameRenderWorld->FreeLightDef( lightDefHandle ); - lightDefHandle = -1; - } -} - -/* -================ -idLight::SaveState -================ -*/ -void idLight::SaveState( idDict *args ) { - int i, c = spawnArgs.GetNumKeyVals(); - for ( i = 0; i < c; i++ ) { - const idKeyValue *pv = spawnArgs.GetKeyVal(i); - if ( pv->GetKey().Find( "editor_", false ) >= 0 || pv->GetKey().Find( "parse_", false ) >= 0 ) { - continue; - } - args->Set( pv->GetKey(), pv->GetValue() ); - } -} - -/* -=============== -idLight::ShowEditingDialog -=============== -*/ -void idLight::ShowEditingDialog( void ) { - if ( g_editEntityMode.GetInteger() == 1 ) { - common->InitTool( EDITOR_LIGHT, &spawnArgs ); - } else { - common->InitTool( EDITOR_SOUND, &spawnArgs ); - } -} - -/* -================ -idLight::Event_SetShader -================ -*/ -void idLight::Event_SetShader( const char *shadername ) { - SetShader( shadername ); -} - -/* -================ -idLight::Event_GetLightParm -================ -*/ -void idLight::Event_GetLightParm( int parmnum ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Error( "shader parm index (%d) out of range", parmnum ); - } - - idThread::ReturnFloat( renderLight.shaderParms[ parmnum ] ); -} - -/* -================ -idLight::Event_SetLightParm -================ -*/ -void idLight::Event_SetLightParm( int parmnum, float value ) { - SetLightParm( parmnum, value ); -} - -/* -================ -idLight::Event_SetLightParms -================ -*/ -void idLight::Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { - SetLightParms( parm0, parm1, parm2, parm3 ); -} - -/* -================ -idLight::Event_SetRadiusXYZ -================ -*/ -void idLight::Event_SetRadiusXYZ( float x, float y, float z ) { - SetRadiusXYZ( x, y, z ); -} - -/* -================ -idLight::Event_SetRadius -================ -*/ -void idLight::Event_SetRadius( float radius ) { - SetRadius( radius ); -} - -/* -================ -idLight::Event_Hide -================ -*/ -void idLight::Event_Hide( void ) { - Hide(); - smoking = false; // grayman #2603 - PresentModelDefChange(); - Off(); -} - -/* -================ -idLight::Event_Show -================ -*/ -void idLight::Event_Show( void ) { - Show(); - PresentModelDefChange(); - On(); -} - -/* -================ -idLight::Event_On -================ -*/ -void idLight::Event_On( void ) { - On(); -} - -/* -================ -idLight::Event_Off -================ -*/ -void idLight::Event_Off( void ) { - Off(); -} - -/* -================ -idLight::Event_ToggleOnOff -================ -*/ -void idLight::Event_ToggleOnOff( idEntity *activator ) { - triggercount++; - if ( triggercount < count ) { - return; - } - - // reset trigger count - triggercount = 0; - - if ( breakOnTrigger ) { - BecomeBroken( activator ); - breakOnTrigger = false; - return; - } - - if ( !currentLevel ) { - On(); - } - else { - currentLevel--; - if ( !currentLevel ) { - Off(); - } - else { - SetLightLevel(); - } - } -} - -/* -================ -idLight::Event_SetSoundHandles - - set the same sound def handle on all targeted lights -================ -*/ -void idLight::Event_SetSoundHandles( void ) { - - int i; - idEntity *targetEnt; - - if ( !refSound.referenceSound ) { - return; - } - - for ( i = 0; i < targets.Num(); i++ ) { - targetEnt = targets[ i ].GetEntity(); - if ( targetEnt && targetEnt->IsType( idLight::Type ) ) { - idLight *light = static_cast(targetEnt); - light->lightParent = this; - - // explicitly delete any sounds on the entity - light->FreeSoundEmitter( true ); - - // manually set the refSound to this light's refSound - light->renderEntity.referenceSound = renderEntity.referenceSound; - - // update the renderEntity to the renderer - light->UpdateVisuals(); - } - } -} - -/* -================ -idLight::Event_FadeOut -================ -*/ -void idLight::Event_FadeOut( float time ) { - FadeOut( time ); -} - -/* -================ -idLight::Event_FadeIn -================ -*/ -void idLight::Event_FadeIn( float time ) { - FadeIn( time ); -} - -/* -================ -idLight::Event_FadeToLight -================ -*/ -void idLight::Event_FadeToLight( idVec3 &color, float time ) { - FadeTo( color, time ); -} - -/* -================ -idLight::ClientPredictionThink -================ -*/ -void idLight::ClientPredictionThink( void ) { - Think(); -} - -/* -================ -idLight::WriteToSnapshot -================ -*/ -void idLight::WriteToSnapshot( idBitMsgDelta &msg ) const { - - GetPhysics()->WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); - - msg.WriteByte( currentLevel ); - msg.WriteLong( PackColor( baseColor ) ); - // msg.WriteBits( lightParent.GetEntityNum(), GENTITYNUM_BITS ); - -/* // only helps prediction - msg.WriteLong( PackColor( fadeFrom ) ); - msg.WriteLong( PackColor( fadeTo ) ); - msg.WriteLong( fadeStart ); - msg.WriteLong( fadeEnd ); -*/ - - // FIXME: send renderLight.shader - msg.WriteFloat( renderLight.lightRadius[0], 5, 10 ); - msg.WriteFloat( renderLight.lightRadius[1], 5, 10 ); - msg.WriteFloat( renderLight.lightRadius[2], 5, 10 ); - - msg.WriteLong( PackColor( idVec4( renderLight.shaderParms[SHADERPARM_RED], - renderLight.shaderParms[SHADERPARM_GREEN], - renderLight.shaderParms[SHADERPARM_BLUE], - renderLight.shaderParms[SHADERPARM_ALPHA] ) ) ); - - msg.WriteFloat( renderLight.shaderParms[SHADERPARM_TIMESCALE], 5, 10 ); - msg.WriteLong( renderLight.shaderParms[SHADERPARM_TIMEOFFSET] ); - //msg.WriteByte( renderLight.shaderParms[SHADERPARM_DIVERSITY] ); - msg.WriteShort( renderLight.shaderParms[SHADERPARM_MODE] ); - - WriteColorToSnapshot( msg ); -} - -/* -================ -idLight::ReadFromSnapshot -================ -*/ -void idLight::ReadFromSnapshot( const idBitMsgDelta &msg ) { - idVec4 shaderColor; - int oldCurrentLevel = currentLevel; - idVec3 oldBaseColor = baseColor; - - GetPhysics()->ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - - currentLevel = msg.ReadByte(); - if ( currentLevel != oldCurrentLevel ) { - // need to call On/Off for flickering lights to start/stop the sound - // while doing it this way rather than through events, the flickering is out of sync between clients - // but at least there is no question about saving the event and having them happening globally in the world - if ( currentLevel ) { - On(); - } else { - Off(); - } - } - UnpackColor( msg.ReadLong(), baseColor ); - // lightParentEntityNum = msg.ReadBits( GENTITYNUM_BITS ); - -/* // only helps prediction - UnpackColor( msg.ReadLong(), fadeFrom ); - UnpackColor( msg.ReadLong(), fadeTo ); - fadeStart = msg.ReadLong(); - fadeEnd = msg.ReadLong(); -*/ - - // FIXME: read renderLight.shader - renderLight.lightRadius[0] = msg.ReadFloat( 5, 10 ); - renderLight.lightRadius[1] = msg.ReadFloat( 5, 10 ); - renderLight.lightRadius[2] = msg.ReadFloat( 5, 10 ); - - UnpackColor( msg.ReadLong(), shaderColor ); - renderLight.shaderParms[SHADERPARM_RED] = shaderColor[0]; - renderLight.shaderParms[SHADERPARM_GREEN] = shaderColor[1]; - renderLight.shaderParms[SHADERPARM_BLUE] = shaderColor[2]; - renderLight.shaderParms[SHADERPARM_ALPHA] = shaderColor[3]; - - renderLight.shaderParms[SHADERPARM_TIMESCALE] = msg.ReadFloat( 5, 10 ); - renderLight.shaderParms[SHADERPARM_TIMEOFFSET] = msg.ReadLong(); - //renderLight.shaderParms[SHADERPARM_DIVERSITY] = msg.ReadFloat(); - renderLight.shaderParms[SHADERPARM_MODE] = msg.ReadShort(); - - ReadColorFromSnapshot( msg ); - - if ( msg.HasChanged() ) { - if ( ( currentLevel != oldCurrentLevel ) || ( baseColor != oldBaseColor ) ) { - SetLightLevel(); - } else { - PresentLightDefChange(); - PresentModelDefChange(); - } - } -} - -/* -================ -idLight::ClientReceiveEvent -================ -*/ -bool idLight::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - - switch( event ) { - case EVENT_BECOMEBROKEN: { - BecomeBroken( NULL ); - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - - -/** Returns a bounding box surrounding the light. - */ -idBounds idLight::GetBounds() -{ - // NOTE: I need to add caching. - - idBounds b; - - if ( renderLight.pointLight ) - { - b = idBounds( -renderLight.lightRadius, renderLight.lightRadius ); - } else { - gameLocal.Warning("idLight::GetBounds() not correctly implemented for projected lights."); - // Fake a set of bounds. This might work ok for squarish spotlights with no start/stop specified. - // FIXME: These bounds are incorrect. - b.Zero(); - b.AddPoint( renderLight.target ); - b.AddPoint( renderLight.target + renderLight.up + renderLight.right ); - b.AddPoint( renderLight.target + renderLight.up - renderLight.right ); - b.AddPoint( renderLight.target - renderLight.up + renderLight.right ); - b.AddPoint( renderLight.target - renderLight.up - renderLight.right ); - } - - return b; -} - - -/** Called to update m_renderTrigger after the render entity is modified. - * Only updates the render trigger if a thread is waiting for it. - */ -void idLight::PresentRenderTrigger() -{ - if ( !m_renderWaitingThread ) { - goto Quit; - } - - // Have the bounds been set yet? - if ( m_renderTrigger.bounds.IsCleared() ) - { - // No. - - // Pre-rotate our bounds and give them to m_renderTrigger. - m_renderTrigger.origin = renderLight.origin; - m_renderTrigger.bounds = GetBounds() * renderLight.axis; - - } else { - // Yes. - - // Convert our light's bounds to be relative to m_renderTrigger, - // and add them to what already exists. - m_renderTrigger.bounds += GetBounds() * renderLight.axis + ( renderLight.origin - m_renderTrigger.origin ); - } - - // I haven't yet figured out where renderEntity.entityNum is set... - m_renderTrigger.entityNum = entityNumber; - - // Update the renderTrigger in the render world. - if ( m_renderTriggerHandle == -1 ) - m_renderTriggerHandle = gameRenderWorld->AddEntityDef( &m_renderTrigger ); - else - gameRenderWorld->UpdateEntityDef( m_renderTriggerHandle, &m_renderTrigger ); - - Quit: - return; -} - - -int idLight::GetTextureIndex(float x, float y, int w, int h, int bpp) -{ - int rc = 0; - float w2, h2; - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Calculating texture index: x/y: %f/%f w/h: %u/%u\r", x, y, w, h); - - w2 = ((float)w)/2.0; - h2 = ((float)h)/2.0; - - if(renderLight.pointLight) - { - // The lighttextures are spread out over the range of the axis. The z axis - // can be ignored for this and we assume that the x/y is already properly - // calculated. - x = w2 - (w2/renderLight.lightRadius.x) * x; - y = h2 - (h2/renderLight.lightRadius.y) * y; - } - else - { - // TODO: Just for now until the projected lights are implemented to not cause any crash. - // x = right - // y = up -//#pragma message(DARKMOD_NOTE "-------------------------------------------------idLight::GetTextureIndex") -//#pragma message(DARKMOD_NOTE "For projected lights this is likely not enough. As long as the light will") -//#pragma message(DARKMOD_NOTE "be straight up or down it should work, but if the cone is angled it might") -//#pragma message(DARKMOD_NOTE "give wrong results. greebo: See DarkRadiant code for starters.") -//#pragma message(DARKMOD_NOTE "-------------------------------------------------idLight::GetTextureIndex") - x = w2 - (w2/renderLight.right.x) * x; - y = h2 - (h2/renderLight.up.y) * y; - } - - if(y > h) - y = h; - if(x > w) - x = w; - - if(x < 0) - x = 0; - if(y < 0) - y = 0; - - rc = ((int)y * (w*bpp)) + ((int)x*bpp); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Index result: %u x/y: %f/%f\r", rc, x, y); - - return rc; -} - - -float idLight::GetDistanceColor(float fDistance, float fx, float fy) -{ - float fColVal(0), fImgVal(0); - int fw(0), fh(0), iw(0), ih(0), i(0), fbpp(0), ibpp(0); - const unsigned char *img = NULL; - const unsigned char *fot = NULL; - - if(m_LightMaterial == NULL) - { - if((m_LightMaterial = g_Global.GetMaterial(m_MaterialName)) != NULL) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Material found for [%s]\r", name.c_str()); - fot = m_LightMaterial->GetFallOffTexture(fw, fh, fbpp); - img = m_LightMaterial->GetImage(iw, ih, ibpp); - } - } - else - { - fot = m_LightMaterial->GetFallOffTexture(fw, fh, fbpp); - img = m_LightMaterial->GetImage(iw, ih, ibpp); - } - - fColVal = (baseColor.x * DARKMOD_LG_RED + baseColor.y * DARKMOD_LG_GREEN + baseColor.z * DARKMOD_LG_BLUE); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Pointlight: %u Red: %f/%f Green: %f/%f Blue: %f/%f ColVal: %f\r", renderLight.pointLight, - baseColor.x, baseColor.x * DARKMOD_LG_RED, - baseColor.y, baseColor.y * DARKMOD_LG_GREEN, - baseColor.z, baseColor.z * DARKMOD_LG_BLUE, - fColVal); - - // If we have neither falloff texture nor a projection image, we do a - // simple linear falloff - if(fot == NULL && img == NULL) - { - // TODO: Light falloff calculation -//#pragma message(DARKMOD_NOTE "------------------------------------------------idLight::GetDistanceColor") -//#pragma message(DARKMOD_NOTE "The lightfalloff should be calculated for ellipsoids instead of spheres") -//#pragma message(DARKMOD_NOTE "when no textures are defined. The current code will give wrong results") -//#pragma message(DARKMOD_NOTE "when a light is defined as an ellipsoid.") -//#pragma message(DARKMOD_NOTE "------------------------------------------------idLight::GetDistanceColor") - fColVal = (fColVal / m_MaxLightRadius) * (m_MaxLightRadius - fDistance); - fImgVal = 1; - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("No textures defined using distance: [%f]\r", fDistance); - } - else - { - // If we have a falloff texture ... - if(fot != NULL) - { - i = GetTextureIndex((float)fabs(fx), (float)fabs(fy), fw, fh, fbpp); - fColVal = fColVal * (fot[i] * DARKMOD_LG_SCALE); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Falloff: Index: %u Value: %u [%f]\r", i, (int)fot[i], (float)(fot[i] * DARKMOD_LG_SCALE)); - } - else - fColVal = 1; - - // ... or a projection image. - if(img != NULL) - { - i = GetTextureIndex((float)fabs(fx), (float)fabs(fy), iw, ih, ibpp); - fImgVal = img[i] * DARKMOD_LG_SCALE; - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Map: Index: %u Value: %u [%f]\r", i, (int)img[i], (float)(img[i] * DARKMOD_LG_SCALE)); - } - else - fImgVal = 1; - } - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Final ColVal: %f ImgVal: %f\r", fColVal, fImgVal); - - return (fColVal*fImgVal); -} - -bool idLight::CastsShadow(void) -{ - if(m_LightMaterial == NULL) - m_LightMaterial = g_Global.GetMaterial(m_MaterialName); - - if(m_LightMaterial != NULL) - { - if(m_LightMaterial->m_AmbientLight == true) - return false; - } - - return !renderLight.noShadows; -} - -bool idLight::GetLightCone(idVec3 &Origin, idVec3 &Target, idVec3 &Right, idVec3 &Up, idVec3 &Start, idVec3 &End) -{ - bool rc = false; - - Origin = GetPhysics()->GetOrigin(); - Target = renderLight.target; - Right = renderLight.right; - Up = renderLight.up; - - Start = renderLight.start; - End = renderLight.end; - - return rc; -} - -bool idLight::GetLightCone(idVec3 &Origin, idVec3 &Axis, idVec3 &Center) -{ - bool rc = false; - - Origin = GetPhysics()->GetOrigin(); - Axis = renderLight.lightRadius; - Center = renderLight.lightCenter; - - return rc; -} - -void idLight::Event_SetLightOrigin( idVec3 &pos ) -{ - localLightOrigin = pos; - BecomeActive( TH_UPDATEVISUALS ); -} - -void idLight::Event_GetLightOrigin( void ) -{ - idThread::ReturnVector( localLightOrigin ); -} - -void idLight::Event_GetLightLevel ( void ) -{ - idThread::ReturnFloat( currentLevel ); -} - -void idLight::Event_AddToLAS() -{ - LAS.addLight(this); - - // Also register this light with the local player - idPlayer* player = gameLocal.GetLocalPlayer(); - if (player != NULL) - { - player->AddLight(this); - } -} - -/** Returns 1 if the light is in PVS. - * Doesn't take into account vis-area optimizations for shadowcasting lights. - */ -void idLight::Event_InPVS() -// NOTE: Current extremely inefficent. -// Caching needs to be done. -{ - int localNumPVSAreas, localPVSAreas[32]; - idBounds modelAbsBounds; - - m_renderTrigger.bounds = GetBounds(); // currently too innefficient but I'll worry about caching later - m_renderTrigger.origin = renderLight.origin; - m_renderTrigger.axis = renderLight.axis; - - modelAbsBounds.FromTransformedBounds( m_renderTrigger.bounds, m_renderTrigger.origin, m_renderTrigger.axis ); - localNumPVSAreas = gameLocal.pvs.GetPVSAreas( modelAbsBounds, localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) ); - - idThread::ReturnFloat( gameLocal.pvs.InCurrentPVS( gameLocal.GetPlayerPVS(), localPVSAreas, localNumPVSAreas ) ); -} - -// Returns true if this is an ambient light. - J.C.Denton -bool idLight::IsAmbient(void) -{ - if( renderLight.shader ) - return renderLight.shader->IsAmbientLight(); - - return false; -} - -// grayman #2603 - keep a list of switches for this light -void idLight::AddSwitch(idEntity* newSwitch) -{ - idEntityPtr switchPtr; - switchPtr = newSwitch; - switchList.Append(switchPtr); -} - -// grayman #2603 - If there are switches, return the closest one to the calling user -idEntity* idLight::GetSwitch(idAI* user) -{ - if (switchList.Num() == 0) // quick check - { - return NULL; - } - - idEntity* closestSwitch = NULL; - float shortestDistSqr = idMath::INFINITY; - idVec3 userOrg = user->GetPhysics()->GetOrigin(); - for (int i = 0 ; i < switchList.Num() ; i++) - { - idEntity* e = switchList[i].GetEntity(); - if (e) - { - float distSqr = (e->GetPhysics()->GetOrigin() - userOrg).LengthSqr(); - if (distSqr < shortestDistSqr) - { - shortestDistSqr = distSqr; - closestSwitch = e; - } - } - } - return closestSwitch; -} - - -// grayman #2603 - Change the flag that says if this light is being relit. - -void idLight::SetBeingRelit(bool relighting) -{ - beingRelit = relighting; -} - -// grayman #2603 - Is an AI in the process or relighting this light? - -bool idLight::IsBeingRelit() -{ - return beingRelit; -} - -// grayman #2603 - Set the chance that this light can be barked about negatively - -void idLight::SetChanceNegativeBark(float newChance) -{ - chanceNegativeBark = newChance; -} - -// grayman #2603 - Time when this light was turned off - -int idLight::GetWhenTurnedOff() -{ - return whenTurnedOff; -} - - // grayman #2603 - when can this light be relit - -int idLight::GetRelightAfter() -{ - return relightAfter; -} - -void idLight::SetRelightAfter() -{ - relightAfter = gameLocal.time + 15000; -} - - // grayman #2603 - Set when an AI can next emit a "light's out" or "won't relight" bark - -int idLight::GetNextTimeLightOutBark() -{ - return nextTimeLightOutBark; -} - -void idLight::SetNextTimeLightOutBark(int newNextTimeLightOutBark) -{ - nextTimeLightOutBark = newNextTimeLightOutBark; -} - -// grayman #2603 - can an AI make a negative bark about this light (found off, or won't relight) - -bool idLight::NegativeBark(idAI* ai) -{ - idEntityPtr aiPtr; - aiPtr = ai; - int aiBarksIndex = -1; // index of this ai in the aiBarks list - bool barking = false; - - // Don't allow barks if the Alert Level is above 1. - - if (ai->AI_AlertLevel >= ai->thresh_1) - { - return false; - } - - // Check the number of times this AI has negatively barked about this light. - // Once they reach a certain number, the barks are disallowed until the - // light is relit. - - for (int i = 0 ; i < aiBarks.Num() ; i++) - { - if (aiBarks[i].ai == aiPtr) - { - aiBarksIndex = i; // note for use below - if (aiBarks[i].count > 1) - { - return false; - } - break; - } - } - - if ((gameLocal.time >= ai->GetMemory().nextTimeLightStimBark) && (gameLocal.time >= nextTimeLightOutBark)) - { - if (gameLocal.random.RandomFloat() < chanceNegativeBark) - { - ai->GetMemory().lastTimeVisualStimBark = gameLocal.time; - ai->GetMemory().nextTimeLightStimBark = gameLocal.time + REBARK_DELAY; - nextTimeLightOutBark = gameLocal.time + REBARK_DELAY + 5*gameLocal.random.RandomFloat(); - - // As a light receives negative barks ("light out" and "won't relight light"), the odds of emitting - // this type of bark go down. When the light is relit, the odds are reset to 100%. This should reduce - // the number of such barks, which can get tiresome. - - chanceNegativeBark -= 0.2f; // reduce next chance of a negative bark - if (chanceNegativeBark < 0.0f) - { - chanceNegativeBark = 0.0f; - } - barking = true; - - // Bump the number of times this AI has negatively barked about this light. - - if (aiBarksIndex >= 0) - { - aiBarks[aiBarksIndex].count++; - } - else // create a new entry for this AI - { - AIBarks barks; - barks.count = 1; - barks.ai = aiPtr; - aiBarks.Append(barks); - } - } - } - - return barking; -} - -void idLight::Event_Smoking( int state ) // grayman #2603 -{ - smoking = (state == 1); // true: smoking, false: not smoking -} - -bool idLight::IsSmoking() // grayman #2603 -{ - return smoking; -} - - diff --git a/game/light.h b/game/light.h deleted file mode 100644 index d831d09d0..000000000 --- a/game/light.h +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_LIGHT_H__ -#define __GAME_LIGHT_H__ - -/* -=============================================================================== - - Generic light. - -=============================================================================== -*/ -class CLightMaterial; - -extern const idEventDef EV_Light_GetLightParm; -extern const idEventDef EV_Light_SetLightParm; -extern const idEventDef EV_Light_SetLightParms; - -class idLight : public idEntity { -public: - CLASS_PROTOTYPE( idLight ); - - idLight(); - virtual ~idLight(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - virtual void UpdateChangeableSpawnArgs( const idDict *source ); - virtual void Think( void ); - virtual void FreeLightDef( void ); - virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); - void Present( void ); - - void SaveState( idDict *args ); - virtual void SetColor( const float red, const float green, const float blue ); - virtual void SetColor( const idVec4 &color ); - virtual void GetColor( idVec3 &out ) const; - virtual void GetColor( idVec4 &out ) const; - - /** - * Tels: idLight::GetLightOrigin returns the origin of the light in the world. This - * is different from the physics origin, since the light can be offset. - */ - const idVec3 & GetLightOrigin( void ) const { return renderLight.origin; } - - const idVec3 & GetBaseColor( void ) const { return baseColor; } - void SetShader( const char *shadername ); - void SetLightParm( int parmnum, float value ); - void SetLightParms( float parm0, float parm1, float parm2, float parm3 ); - void SetRadiusXYZ( const float x, const float y, const float z ); - void SetRadius( const float radius ); - void On( void ); - void Off( const bool stopSound = true ); - void Fade( const idVec4 &to, float fadeTime ); - void FadeOut( float time ); - void FadeIn( float time ); - void FadeTo( idVec3 color, float time ); - void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - void BecomeBroken( idEntity *activator ); - qhandle_t GetLightDefHandle( void ) const { return lightDefHandle; } - void SetLightParent( idEntity *lparent ) { lightParent = lparent; } - void SetLightLevel( void ); - - /** - * greebo: Returns the current lightlevel (currentlevel). - */ - int GetLightLevel() const; - - /** - * Tels: return the current light radius. - */ - void GetRadius( idVec3 &out ) const; - - virtual void ShowEditingDialog( void ); - - enum { - EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS, - EVENT_MAXEVENTS - }; - - virtual void ClientPredictionThink( void ); - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - /** Returns a bounding box surrounding the light. - */ - idBounds GetBounds(); - /** Called to update m_renderTrigger after the render light is modified. - * Only updates the render trigger if a thread is waiting for it. - */ - void PresentRenderTrigger(); - - /** - * This will return a grayscale value dependent on the value from the light. - * X and Y are the coordinates returned by calculating the position from the - * player related to the light. The Z coordinate can be ignored. The distance - * is required when the light has no textures to calculate a falloff. - */ - float GetDistanceColor(float distance, float x, float y); - - /** - * GetTextureIndex calculates the index into the texture based on the x/y coordinates - * given and returns the index. - */ - int GetTextureIndex(float x, float y, int TextureWidth, int TextureHeight, int BytesPerPixel); - - /** - * Returns true if the light is a parallel light. - */ - inline bool IsParallel(void) { return renderLight.parallel; }; - inline bool IsPointlight(void) { return renderLight.pointLight; }; - bool CastsShadow(void); - bool IsAmbient(void); // Returns true if this is an ambient light. - J.C.Denton - - /** - * GetLightCone returns the lightdata. - * If the light is a pointlight it will return an ellipsoid defining the light. - * In case of a projected light, the returned data is a cone. - * If the light is a projected light and uses the additional vectors for - * cut off cones, it will return true. - */ - bool GetLightCone(idVec3 &Origin, idVec3 &Axis, idVec3 &Center); - bool GetLightCone(idVec3 &Origin, idVec3 &Target, idVec3 &Right, idVec3 &Up, idVec3 &Start, idVec3 &End); - - /** - * grayman #2603 - add a switch to the switch list - */ - - void AddSwitch(idEntity* newSwitch); - - /** - * grayman #2603 - If there are switches, returns the closest one to the calling user - */ - - idEntity* GetSwitch(idAI* user); - - /** - * grayman #2603 - Change the flag that says if this light is being relit. - */ - - void SetBeingRelit(bool relighting); - - /** - * grayman #2603 - Is an AI in the process or relighting this light? - */ - - bool IsBeingRelit(); - - /** - * grayman #2603 - Set the chance that this light can be barked about negatively - */ - - void SetChanceNegativeBark(float newChance); - - /** - * grayman #2603 - can an AI make a negative bark about this light (found off, or won't relight) - */ - - bool NegativeBark(idAI* ai); - - /** - * grayman #2603 - Get when the light was turned off - */ - - int GetWhenTurnedOff(); - - /** - * grayman #2603 - Get when can this light be relit - */ - - int GetRelightAfter(); - - /** - * grayman #2603 - Set when can this light be relit - */ - - void SetRelightAfter(); - - /* - * grayman #2603 - Get when an AI can next emit a "light's out" or "won't relight" bark - */ - - int GetNextTimeLightOutBark(); - - /* - * grayman #2603 - Set when an AI can next emit a "light's out" or "won't relight" bark - */ - - void SetNextTimeLightOutBark(int newNextTimeLightOutBark); - - /* - * grayman #2603 - Is a flame vertical? - */ - - bool IsVertical(float degreesFromVertical); - - /* - * grayman #2603 - flame is out and smoking? - */ - - bool IsSmoking(); - -private: - renderLight_t renderLight; // light presented to the renderer - idVec3 localLightOrigin; // light origin relative to the physics origin - idMat3 localLightAxis; // light axis relative to physics axis - qhandle_t lightDefHandle; // handle to renderer light def - int levels; - int currentLevel; - idVec3 baseColor; - bool breakOnTrigger; - int count; - int triggercount; - idEntity * lightParent; - bool beingRelit; // grayman #2603 - true if being relit - idList< idEntityPtr > switchList; // grayman #2603 - list of my switches - float chanceNegativeBark; // grayman #2603 - chance of negative barks ("light's out" and "won't relight") - int whenTurnedOff; // grayman #2603 - when this light was turned off - int nextTimeLightOutBark; // grayman #2603 - the next time an AI can bark about a light that's out, or a decision not to relight it - int relightAfter; // grayman #2603 - when a light can be relit - float nextTimeVerticalCheck; // grayman #2603 - the next time to check if a lit flame is vertical - bool smoking; // grayman #2603 - the flame model has changed to a smoke partical model; considered "out" - int whenToDouse; // grayman #2603 - when a non-vertical flame can be doused - - idVec4 fadeFrom; - idVec4 fadeTo; - int fadeStart; - int fadeEnd; - bool soundWasPlaying; - - /** - * grayman #2603 - Per-AI info for counting negative barks. This allows - * lights to keep track of the number of negative barks it elicits from - * passing AI. AI are only allowed 2 negative barks per light. The list - * is cleared when the light is relit, allowing AI to once again make - * negative barks. - */ - struct AIBarks - { - // The number of negative barks for this AI - int count; - - // The AI who made them - idEntityPtr ai; - }; - - idList aiBarks; // grayman #2603 - - -private: - void PresentLightDefChange( void ); - void PresentModelDefChange( void ); - - void Event_SetShader( const char *shadername ); - void Event_GetLightParm( int parmnum ); - void Event_SetLightParm( int parmnum, float value ); - void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ); - void Event_SetRadiusXYZ( float x, float y, float z ); - void Event_SetRadius( float radius ); - void Event_Hide( void ); - void Event_Show( void ); - void Event_On( void ); - void Event_Off( void ); - void Event_ToggleOnOff( idEntity *activator ); - void Event_SetSoundHandles( void ); - void Event_FadeOut( float time ); - void Event_FadeIn( float time ); - /** - * Tels: Allows the color of the light to fade over to a new value over a time period. - */ - void Event_FadeToLight( idVec3 &color, float time ); - /** - * Allows script to get and set the light origin separate from model origin. - * Used to achieve moving lights with a stationary model - **/ - void Event_GetLightOrigin( void ); - void Event_SetLightOrigin( idVec3 &pos ); - - /** - * Allows us to get the light level, and tell if the light is on or off. - * "On" light levels are > 0.0 - */ - void Event_GetLightLevel(); - - - /* - * Add the light to the appropriate LAS area - */ - void Event_AddToLAS(); - - /** Returns 1 if the light is in PVS. - * Doesn't take into account vis-area optimizations for shadowcasting lights. - */ - void Event_InPVS(); - - /** - * grayman #2603 - */ - - void Event_Smoking(int state); - - /** - * Texturename for the falloff image - */ - const char *m_MaterialName; - - /** - * Pointer to the material that is used for this light. This pointer - * is only loaded once. If the material needs to change dynamically - * for a light, the m_FalloffImage must be set to the new material name - * and m_LightMaterial must be set to NULL, to force the reload, next - * time the light should use a new material. - */ - CLightMaterial *m_LightMaterial; - -public: - - /** - * Each light also gets the maxlightradius, which determines which value - * is the maximum radius for that particular light, - */ - float m_MaxLightRadius; - - /*! - * Darkmod LAS - * The area the light is in, assigned by The Dark Mod Lighting Awareness System (LAS) - */ - int LASAreaIndex; - -}; - -#endif /* !__GAME_LIGHT_H__ */ diff --git a/game/misc.cpp b/game/misc.cpp deleted file mode 100644 index 18d8cfdb0..000000000 --- a/game/misc.cpp +++ /dev/null @@ -1,3426 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* - -Various utility objects and functions. - -*/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/sndProp.h" -#include "../DarkMod/EscapePointManager.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -/* -=============================================================================== - -idSpawnableEntity - -A simple, spawnable entity with a model and no functionable ability of it's own. -For example, it can be used as a placeholder during development, for marking -locations on maps for script, or for simple placed models without any behavior -that can be bound to other entities. Should not be subclassed. -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idSpawnableEntity ) -END_CLASS - -/* -====================== -idSpawnableEntity::Spawn -====================== -*/ -void idSpawnableEntity::Spawn() { - // this just holds dict information -} - -/* -=============================================================================== - - idPlayerStart - -=============================================================================== -*/ - -const idEventDef EV_TeleportStage( "", "e" ); - -CLASS_DECLARATION( idEntity, idPlayerStart ) - EVENT( EV_Activate, idPlayerStart::Event_TeleportPlayer ) - EVENT( EV_TeleportStage, idPlayerStart::Event_TeleportStage ) -END_CLASS - -/* -=============== -idPlayerStart::idPlayerStart -================ -*/ -idPlayerStart::idPlayerStart( void ) { - teleportStage = 0; -} - -/* -=============== -idPlayerStart::Spawn -================ -*/ -void idPlayerStart::Spawn( void ) { - teleportStage = 0; -} - -/* -================ -idPlayerStart::Save -================ -*/ -void idPlayerStart::Save( idSaveGame *savefile ) const { - savefile->WriteInt( teleportStage ); -} - -/* -================ -idPlayerStart::Restore -================ -*/ -void idPlayerStart::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( teleportStage ); -} - -/* -================ -idPlayerStart::ClientReceiveEvent -================ -*/ -bool idPlayerStart::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - int entityNumber; - - switch( event ) { - case EVENT_TELEPORTPLAYER: { - entityNumber = msg.ReadBits( GENTITYNUM_BITS ); - idPlayer *player = static_cast( gameLocal.entities[entityNumber] ); - if ( player != NULL && player->IsType( idPlayer::Type ) ) { - Event_TeleportPlayer( player ); - } - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -=============== -idPlayerStart::Event_TeleportStage - -FIXME: add functionality to fx system ( could be done with player scripting too ) -================ -*/ -void idPlayerStart::Event_TeleportStage( idEntity *_player ) { - idPlayer *player; - - if ( !_player->IsType( idPlayer::Type ) ) { - - common->Warning( "idPlayerStart::Event_TeleportStage: entity is not an idPlayer\n" ); - - return; - - } - - player = static_cast(_player); - - float teleportDelay = spawnArgs.GetFloat( "teleportDelay" ); - switch ( teleportStage ) { - case 0: - player->playerView.Flash( colorWhite, 125 ); - player->SetInfluenceLevel( INFLUENCE_LEVEL3 ); - player->SetInfluenceView( spawnArgs.GetString( "mtr_teleportFx" ), NULL, 0.0f, NULL ); - gameSoundWorld->FadeSoundClasses( 0, -20.0f, teleportDelay ); - player->StartSound( "snd_teleport_start", SND_CHANNEL_BODY2, 0, false, NULL ); - teleportStage++; - PostEventSec( &EV_TeleportStage, teleportDelay, player ); - break; - case 1: - gameSoundWorld->FadeSoundClasses( 0, 0.0f, 0.25f ); - teleportStage++; - PostEventSec( &EV_TeleportStage, 0.25f, player ); - break; - case 2: - player->SetInfluenceView( NULL, NULL, 0.0f, NULL ); - TeleportPlayer( player ); - player->StopSound( SND_CHANNEL_BODY2, false ); - player->SetInfluenceLevel( INFLUENCE_NONE ); - teleportStage = 0; - break; - default: - break; - } -} - -/* -=============== -idPlayerStart::TeleportPlayer -================ -*/ -void idPlayerStart::TeleportPlayer( idPlayer *player ) { - float pushVel = spawnArgs.GetFloat( "push", "300" ); - float f = spawnArgs.GetFloat( "visualEffect", "0" ); - const char *viewName = spawnArgs.GetString( "visualView", "" ); - idEntity *ent = viewName ? gameLocal.FindEntity( viewName ) : NULL; - - if ( f && ent ) { - // place in private camera view for some time - // the entity needs to teleport to where the camera view is to have the PVS right - player->Teleport( ent->GetPhysics()->GetOrigin(), ang_zero, this ); - player->StartSound( "snd_teleport_enter", SND_CHANNEL_ANY, 0, false, NULL ); - player->SetPrivateCameraView( static_cast(ent) ); - // the player entity knows where to spawn from the previous Teleport call - if ( !gameLocal.isClient ) { - player->PostEventSec( &EV_Player_ExitTeleporter, f ); - } - } else { - // direct to exit, Teleport will take care of the killbox - player->Teleport( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis().ToAngles(), NULL ); - - // multiplayer hijacked this entity, so only push the player in multiplayer - if ( gameLocal.isMultiplayer ) { - player->GetPhysics()->SetLinearVelocity( GetPhysics()->GetAxis()[0] * pushVel ); - } - } -} - -/* -=============== -idPlayerStart::Event_TeleportPlayer -================ -*/ -void idPlayerStart::Event_TeleportPlayer( idEntity *activator ) { - idPlayer *player; - - if ( activator->IsType( idPlayer::Type ) ) { - player = static_cast( activator ); - } else { - player = gameLocal.GetLocalPlayer(); - } - if ( player ) { - if ( spawnArgs.GetBool( "visualFx" ) ) { - - teleportStage = 0; - Event_TeleportStage( player ); - - } else { - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteBits( player->entityNumber, GENTITYNUM_BITS ); - ServerSendEvent( EVENT_TELEPORTPLAYER, &msg, false, -1 ); - } - - TeleportPlayer( player ); - } - } -} - -/* -=============================================================================== - - idActivator - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idActivator ) - EVENT( EV_Activate, idActivator::Event_Activate ) -END_CLASS - -/* -=============== -idActivator::Save -================ -*/ -void idActivator::Save( idSaveGame *savefile ) const { - savefile->WriteBool( stay_on ); -} - -/* -=============== -idActivator::Restore -================ -*/ -void idActivator::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( stay_on ); - - if ( stay_on ) { - BecomeActive( TH_THINK ); - } -} - -/* -=============== -idActivator::Spawn -================ -*/ -void idActivator::Spawn( void ) { - bool start_off; - - spawnArgs.GetBool( "stay_on", "0", stay_on ); - spawnArgs.GetBool( "start_off", "0", start_off ); - - GetPhysics()->SetClipBox( idBounds( vec3_origin ).Expand( 4 ), 1.0f ); - GetPhysics()->SetContents( 0 ); - - if ( !start_off ) { - BecomeActive( TH_THINK ); - } -} - -/* -=============== -idActivator::Think -================ -*/ -void idActivator::Think( void ) { - RunPhysics(); - if ( thinkFlags & TH_THINK ) { - if ( TouchTriggers() ) { - if ( !stay_on ) { - BecomeInactive( TH_THINK ); - } - } - } - Present(); -} - -/* -=============== -idActivator::Activate -================ -*/ -void idActivator::Event_Activate( idEntity *activator ) { - if ( thinkFlags & TH_THINK ) { - BecomeInactive( TH_THINK ); - } else { - BecomeActive( TH_THINK ); - } -} - - -/* -=============================================================================== - -idPathCorner - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idPathCorner ) - EVENT( AI_RandomPath, idPathCorner::Event_RandomPath ) -END_CLASS - -/* -===================== -idPathCorner::Spawn -===================== -*/ -void idPathCorner::Spawn( void ) { -} - -/* -===================== -idPathCorner::DrawDebugInfo -===================== -*/ -void idPathCorner::DrawDebugInfo( void ) { - idEntity *ent; - idBounds bnds( idVec3( -4.0, -4.0f, -8.0f ), idVec3( 4.0, 4.0f, 64.0f ) ); - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( !ent->IsType( idPathCorner::Type ) ) { - continue; - } - - idVec3 org = ent->GetPhysics()->GetOrigin(); - gameRenderWorld->DebugBounds( colorRed, bnds, org, 0 ); - } -} - -/* -============ -idPathCorner::RandomPath -============ -*/ -idPathCorner *idPathCorner::RandomPath( const idEntity *source, const idEntity *ignore, idAI* owner ) { - idPathCorner *path[ MAX_GENTITIES ]; - - int num(0); - float rand(gameLocal.random.RandomFloat()); - float accumulatedChance(0); - float maxChance(0); - - idEntity* candidate(NULL); - - for (int i = 0; i < source->targets.Num(); i++ ) { - idEntity* ent = source->targets[ i ].GetEntity(); - if ( ent && ( ent != ignore ) && ent->IsType( idPathCorner::Type ) ) - { - - if (owner) - { - if (owner->HasSeenEvidence() && ent->spawnArgs.GetBool("idle_only", "0")) - { - continue; - } - else if (!owner->HasSeenEvidence() && ent->spawnArgs.GetBool("alert_idle_only", "0")) - { - continue; - } - } - - float chance = ent->spawnArgs.GetFloat("chance", "0"); - if (chance) - { - // angua: path has chance spawn arg set - // sum of the probability of this path and of the previous ones - accumulatedChance += chance; - - // if the random number is between the current and the previous sum, this is our next path - if (rand < accumulatedChance) - { - return static_cast( ent ); - } - - // store the path with the highest chance - if (chance > maxChance) - { - maxChance = chance; - candidate = ent; - } - } - else - { - // path doesn't have chance spawn arg set - // add to list - path[ num++ ] = static_cast( ent ); - if ( num >= MAX_GENTITIES ) { - break; - } - } - } - } - - // probability comparison didn't return a path - - // no path without chance spawn arg (chance sum is < 1) - if ( !num ) { - if (candidate) - { - // return the path with the highest chance - return static_cast(candidate); - } - return NULL; - } - - // choose one from the list - int which = gameLocal.random.RandomInt( num ); - return path[ which ]; -} - -/* -===================== -idPathCorner::Event_RandomPath -===================== -*/ -void idPathCorner::Event_RandomPath( void ) { - idPathCorner *path; - - path = RandomPath( this, NULL, NULL ); - idThread::ReturnEntity( path ); -} - -/* -=============================================================================== - -tdmPathFlee - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, tdmPathFlee ) -END_CLASS - -tdmPathFlee::~tdmPathFlee() -{ - // Unregister self with the escape point manager - gameLocal.m_EscapePointManager->RemoveEscapePoint(this); -} - -/* -===================== -tdmPathFlee::Spawn -===================== -*/ -void tdmPathFlee::Spawn( void ) { - - // Get the location of this entity within the AAS - - - // Register this class with the escape point manager - gameLocal.m_EscapePointManager->AddEscapePoint(this); -} - -/* -=============================================================================== - - idDamagable - -=============================================================================== -*/ - -const idEventDef EV_RestoreDamagable( "" ); - -CLASS_DECLARATION( idEntity, idDamagable ) - EVENT( EV_Activate, idDamagable::Event_BecomeBroken ) - EVENT( EV_RestoreDamagable, idDamagable::Event_RestoreDamagable ) -END_CLASS - -/* -================ -idDamagable::idDamagable -================ -*/ -idDamagable::idDamagable( void ) { - count = 0; - nextTriggerTime = 0; -} - -/* -================ -idDamagable::Save -================ -*/ -void idDamagable::Save( idSaveGame *savefile ) const { - savefile->WriteInt( count ); - savefile->WriteInt( nextTriggerTime ); -} - -/* -================ -idDamagable::Restore -================ -*/ -void idDamagable::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( count ); - savefile->ReadInt( nextTriggerTime ); -} - -/* -================ -idDamagable::Spawn -================ -*/ -void idDamagable::Spawn( void ) -{ - idStr broken; - - health = spawnArgs.GetInt( "health", "5" ); - spawnArgs.GetInt( "count", "1", count ); - nextTriggerTime = 0; - - // make sure the model gets cached - spawnArgs.GetString( "broken", "", broken ); - if ( broken.Length() && !renderModelManager->CheckModel( broken ) ) { - gameLocal.Error( "idDamagable '%s' at (%s): cannot load broken model '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), broken.c_str() ); - } - - fl.takedamage = true; - GetPhysics()->SetContents( CONTENTS_SOLID ); - if( m_CustomContents != -1 ) - GetPhysics()->SetContents( m_CustomContents ); - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); -} - -/* -================ -idDamagable::BecomeBroken -================ -*/ -void idDamagable::BecomeBroken( idEntity *activator ) { - float forceState; - int numStates; - int cycle; - float wait; - - if ( gameLocal.time < nextTriggerTime ) { - return; - } - - spawnArgs.GetFloat( "wait", "0.1", wait ); - nextTriggerTime = gameLocal.time + SEC2MS( wait ); - if ( count > 0 ) { - count--; - if ( !count ) { - fl.takedamage = false; - } else { - health = spawnArgs.GetInt( "health", "5" ); - } - } - - idStr broken; - - spawnArgs.GetString( "broken", "", broken ); - if ( broken.Length() ) { - SetModel( broken ); - } - - // offset the start time of the shader to sync it to the gameLocal time - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - spawnArgs.GetInt( "numstates", "1", numStates ); - spawnArgs.GetInt( "cycle", "0", cycle ); - spawnArgs.GetFloat( "forcestate", "0", forceState ); - - // set the state parm - if ( cycle ) { - renderEntity.shaderParms[ SHADERPARM_MODE ]++; - if ( renderEntity.shaderParms[ SHADERPARM_MODE ] > numStates ) { - renderEntity.shaderParms[ SHADERPARM_MODE ] = 0; - } - } else if ( forceState ) { - renderEntity.shaderParms[ SHADERPARM_MODE ] = forceState; - } else { - renderEntity.shaderParms[ SHADERPARM_MODE ] = gameLocal.random.RandomInt( numStates ) + 1; - } - - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - ActivateTargets( activator ); - - if ( spawnArgs.GetBool( "hideWhenBroken" ) ) { - Hide(); - PostEventMS( &EV_RestoreDamagable, nextTriggerTime - gameLocal.time ); - BecomeActive( TH_THINK ); - } -} - -/* -================ -idDamagable::Killed -================ -*/ -void idDamagable::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) -{ - bool bPlayerResponsible(false); - - if ( gameLocal.time < nextTriggerTime ) - { - health += damage; - return; - } - - if ( attacker && attacker->IsType( idPlayer::Type ) ) - bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); - else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) - bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); - - gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); - BecomeBroken( attacker ); -} - -/* -================ -idDamagable::Event_BecomeBroken -================ -*/ -void idDamagable::Event_BecomeBroken( idEntity *activator ) { - BecomeBroken( activator ); -} - -/* -================ -idDamagable::Event_RestoreDamagable -================ -*/ -void idDamagable::Event_RestoreDamagable( void ) { - health = spawnArgs.GetInt( "health", "5" ); - Show(); -} - - -/* -=============================================================================== - - idExplodable - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idExplodable ) - EVENT( EV_Activate, idExplodable::Event_Explode ) -END_CLASS - -/* -================ -idExplodable::Spawn -================ -*/ -void idExplodable::Spawn( void ) { - Hide(); -} - -/* -================ -idExplodable::Event_Explode -================ -*/ -void idExplodable::Event_Explode( idEntity *activator ) { - const char *temp; - - if ( spawnArgs.GetString( "def_damage", "damage_explosion", &temp ) ) { - gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), activator, activator, this, this, temp ); - } - - StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL ); - - // Show() calls UpdateVisuals, so we don't need to call it ourselves after setting the shaderParms - renderEntity.shaderParms[SHADERPARM_RED] = 1.0f; - renderEntity.shaderParms[SHADERPARM_GREEN] = 1.0f; - renderEntity.shaderParms[SHADERPARM_BLUE] = 1.0f; - renderEntity.shaderParms[SHADERPARM_ALPHA] = 1.0f; - renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - renderEntity.shaderParms[SHADERPARM_DIVERSITY] = 0.0f; - Show(); - - PostEventMS( &EV_Remove, 2000 ); - - ActivateTargets( activator ); -} - - -/* -=============================================================================== - - idSpring - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idSpring ) - EVENT( EV_PostSpawn, idSpring::Event_LinkSpring ) -END_CLASS - -/* -================ -idSpring::Think -================ -*/ -void idSpring::Think( void ) { - idVec3 start, end, origin; - idMat3 axis; - - // run physics - RunPhysics(); - - if ( thinkFlags & TH_THINK ) { - // evaluate force - spring.Evaluate( gameLocal.time ); - - start = p1; - if ( ent1->GetPhysics() ) { - axis = ent1->GetPhysics()->GetAxis(); - origin = ent1->GetPhysics()->GetOrigin(); - start = origin + start * axis; - } - - end = p2; - if ( ent2->GetPhysics() ) { - axis = ent2->GetPhysics()->GetAxis(); - origin = ent2->GetPhysics()->GetOrigin(); - end = origin + p2 * axis; - } - - gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true ); - } - - Present(); -} - -/* -================ -idSpring::Event_LinkSpring -================ -*/ -void idSpring::Event_LinkSpring( void ) { - idStr name1, name2; - - spawnArgs.GetString( "ent1", "", name1 ); - spawnArgs.GetString( "ent2", "", name2 ); - - if ( name1.Length() ) { - ent1 = gameLocal.FindEntity( name1 ); - if ( !ent1 ) { - gameLocal.Error( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() ); - } - } - else { - ent1 = gameLocal.entities[ENTITYNUM_WORLD]; - } - - if ( name2.Length() ) { - ent2 = gameLocal.FindEntity( name2 ); - if ( !ent2 ) { - gameLocal.Error( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() ); - } - } - else { - ent2 = gameLocal.entities[ENTITYNUM_WORLD]; - } - spring.SetPosition( ent1->GetPhysics(), id1, p1, ent2->GetPhysics(), id2, p2 ); - BecomeActive( TH_THINK ); -} - -/* -================ -idSpring::Spawn -================ -*/ -void idSpring::Spawn( void ) { - float Kstretch, damping, restLength; - - spawnArgs.GetInt( "id1", "0", id1 ); - spawnArgs.GetInt( "id2", "0", id2 ); - spawnArgs.GetVector( "point1", "0 0 0", p1 ); - spawnArgs.GetVector( "point2", "0 0 0", p2 ); - spawnArgs.GetFloat( "constant", "100.0f", Kstretch ); - spawnArgs.GetFloat( "damping", "10.0f", damping ); - spawnArgs.GetFloat( "restlength", "0.0f", restLength ); - - spring.InitSpring( Kstretch, 0.0f, damping, restLength ); - - ent1 = ent2 = NULL; - - PostEventMS( &EV_PostSpawn, 0 ); -} - -/* -=============================================================================== - - idForceField - -=============================================================================== -*/ - -const idEventDef EV_Toggle( "Toggle", NULL ); - -CLASS_DECLARATION( idEntity, idForceField ) - EVENT( EV_Activate, idForceField::Event_Activate ) - EVENT( EV_Toggle, idForceField::Event_Toggle ) - EVENT( EV_FindTargets, idForceField::Event_FindTargets ) -END_CLASS - -/* -=============== -idForceField::Toggle -================ -*/ -void idForceField::Toggle( void ) { - if ( thinkFlags & TH_THINK ) { - BecomeInactive( TH_THINK ); - } else { - BecomeActive( TH_THINK ); - } -} - -/* -================ -idForceField::Think -================ -*/ -void idForceField::Think( void ) { - if ( thinkFlags & TH_THINK ) { - // evaluate force - forceField.Evaluate( gameLocal.time ); - } - Present(); -} - -/* -================ -idForceField::Save -================ -*/ -void idForceField::Save( idSaveGame *savefile ) const { - savefile->WriteStaticObject( forceField ); -} - -/* -================ -idForceField::Restore -================ -*/ -void idForceField::Restore( idRestoreGame *savefile ) { - savefile->ReadStaticObject( forceField ); -} - -/* -================ -idForceField::Spawn -================ -*/ -void idForceField::Spawn( void ) { - idVec3 uniform; - float explosion, implosion, randomTorque; - - if ( spawnArgs.GetVector( "uniform", "0 0 0", uniform ) ) { - forceField.Uniform( uniform ); - } else if ( spawnArgs.GetFloat( "explosion", "0", explosion ) ) { - forceField.Explosion( explosion ); - } else if ( spawnArgs.GetFloat( "implosion", "0", implosion ) ) { - forceField.Implosion( implosion ); - } - - if ( spawnArgs.GetFloat( "randomTorque", "0", randomTorque ) ) { - forceField.RandomTorque( randomTorque ); - } - - if ( spawnArgs.GetBool( "applyForce", "0" ) ) { - forceField.SetApplyType( FORCEFIELD_APPLY_FORCE ); - } else if ( spawnArgs.GetBool( "applyImpulse", "0" ) ) { - forceField.SetApplyType( FORCEFIELD_APPLY_IMPULSE ); - } else { - forceField.SetApplyType( FORCEFIELD_APPLY_VELOCITY ); - } - - forceField.SetPlayerOnly( spawnArgs.GetBool( "playerOnly", "0" ) ); - forceField.SetMonsterOnly( spawnArgs.GetBool( "monsterOnly", "0" ) ); - - // set the collision model on the force field - forceField.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ) ); - - // remove the collision model from the physics object - GetPhysics()->SetClipModel( NULL, 1.0f ); - - if ( spawnArgs.GetBool( "start_on" ) ) { - BecomeActive( TH_THINK ); - } -} - -/* -=============== -idForceField::Event_Toggle -================ -*/ -void idForceField::Event_Toggle( void ) { - Toggle(); -} - -/* -================ -idForceField::Event_Activate -================ -*/ -void idForceField::Event_Activate( idEntity *activator ) { - float wait; - - Toggle(); - if ( spawnArgs.GetFloat( "wait", "0.01", wait ) ) { - PostEventSec( &EV_Toggle, wait ); - } -} - -/* -================ -idForceField::Event_FindTargets -================ -*/ -void idForceField::Event_FindTargets( void ) { - FindTargets(); - RemoveNullTargets(); - if ( targets.Num() ) { - forceField.Uniform( targets[0].GetEntity()->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ); - } -} - - -/* -=============================================================================== - - idAnimated - -=============================================================================== -*/ - -const idEventDef EV_Animated_Start( "" ); -const idEventDef EV_LaunchMissiles( "launchMissiles", "ssssdf" ); -const idEventDef EV_LaunchMissilesUpdate( "", "dddd" ); -const idEventDef EV_AnimDone( "", "d" ); -const idEventDef EV_StartRagdoll( "startRagdoll" ); - -CLASS_DECLARATION( idAFEntity_Gibbable, idAnimated ) - EVENT( EV_Activate, idAnimated::Event_Activate ) - EVENT( EV_Animated_Start, idAnimated::Event_Start ) - EVENT( EV_StartRagdoll, idAnimated::Event_StartRagdoll ) - EVENT( EV_AnimDone, idAnimated::Event_AnimDone ) - EVENT( EV_Footstep, idAnimated::Event_Footstep ) - EVENT( EV_FootstepLeft, idAnimated::Event_Footstep ) - EVENT( EV_FootstepRight, idAnimated::Event_Footstep ) - EVENT( EV_LaunchMissiles, idAnimated::Event_LaunchMissiles ) - EVENT( EV_LaunchMissilesUpdate, idAnimated::Event_LaunchMissilesUpdate ) -END_CLASS - -/* -=============== -idAnimated::idAnimated -================ -*/ -idAnimated::idAnimated() { - anim = 0; - blendFrames = 0; - soundJoint = INVALID_JOINT; - activated = false; - combatModel = NULL; - activator = NULL; - current_anim_index = 0; - num_anims = 0; - -} - -/* -=============== -idAnimated::idAnimated -================ -*/ -idAnimated::~idAnimated() { - delete combatModel; - combatModel = NULL; -} - -/* -=============== -idAnimated::Save -================ -*/ -void idAnimated::Save( idSaveGame *savefile ) const { - savefile->WriteInt( current_anim_index ); - savefile->WriteInt( num_anims ); - savefile->WriteInt( anim ); - savefile->WriteInt( blendFrames ); - savefile->WriteJoint( soundJoint ); - activator.Save( savefile ); - savefile->WriteBool( activated ); -} - -/* -=============== -idAnimated::Restore -================ -*/ -void idAnimated::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( current_anim_index ); - savefile->ReadInt( num_anims ); - savefile->ReadInt( anim ); - savefile->ReadInt( blendFrames ); - savefile->ReadJoint( soundJoint ); - activator.Restore( savefile ); - savefile->ReadBool( activated ); -} - -/* -=============== -idAnimated::Spawn -================ -*/ -void idAnimated::Spawn( void ) { - idStr animname; - int anim2; - float wait; - const char *joint; - - joint = spawnArgs.GetString( "sound_bone", "origin" ); - soundJoint = animator.GetJointHandle( joint ); - if ( soundJoint == INVALID_JOINT ) { - gameLocal.Warning( "idAnimated '%s' at (%s): cannot find joint '%s' for sound playback", name.c_str(), GetPhysics()->GetOrigin().ToString(0), joint ); - } - - LoadAF(); - - // allow bullets to collide with a combat model - if ( spawnArgs.GetBool( "combatModel", "0" ) ) { - combatModel = new idClipModel( modelDefHandle ); - } - - // allow the entity to take damage - if ( spawnArgs.GetBool( "takeDamage", "0" ) ) { - fl.takedamage = true; - } - - blendFrames = 0; - - current_anim_index = 0; - spawnArgs.GetInt( "num_anims", "0", num_anims ); - - blendFrames = spawnArgs.GetInt( "blend_in" ); - - animname = spawnArgs.GetString( num_anims ? "anim1" : "anim" ); - if ( !animname.Length() ) { - anim = 0; - } else { - anim = animator.GetAnim( animname ); - if ( !anim ) { - gameLocal.Error( "idAnimated '%s' at (%s): cannot find anim '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), animname.c_str() ); - } - } - - if ( spawnArgs.GetBool( "hide" ) ) { - Hide(); - - if ( !num_anims ) { - blendFrames = 0; - } - } else if ( spawnArgs.GetString( "start_anim", "", animname ) ) { - anim2 = animator.GetAnim( animname ); - if ( !anim2 ) { - gameLocal.Error( "idAnimated '%s' at (%s): cannot find anim '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), animname.c_str() ); - } - animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, 0 ); - } else if ( anim ) { - // init joints to the first frame of the animation - animator.SetFrame( ANIMCHANNEL_ALL, anim, 1, gameLocal.time, 0 ); - - if ( !num_anims ) { - blendFrames = 0; - } - } - - spawnArgs.GetFloat( "wait", "-1", wait ); - - if ( wait >= 0 ) { - PostEventSec( &EV_Activate, wait, this ); - } -} - -/* -=============== -idAnimated::LoadAF -=============== -*/ -bool idAnimated::LoadAF( void ) -{ - bool bReturnVal = false; - idStr fileName; - - if ( !spawnArgs.GetString( "ragdoll", "*unknown*", fileName ) ) - { - goto Quit; - } - af.SetAnimator( GetAnimator() ); - bReturnVal = af.Load( this, fileName ); - SetUpGroundingVars(); - - if( m_bAFPushMoveables ) - { - af.SetupPose( this, gameLocal.time ); - af.GetPhysics()->EnableClip(); - } - -Quit: - return bReturnVal; -} - -/* -=============== -idAnimated::GetPhysicsToSoundTransform -=============== -*/ -bool idAnimated::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { - animator.GetJointTransform( soundJoint, gameLocal.time, origin, axis ); - axis = renderEntity.axis; - return true; -} - -/* -================ -idAnimated::StartRagdoll -================ -*/ -bool idAnimated::StartRagdoll( void ) { - // if no AF loaded - if ( !af.IsLoaded() ) { - return false; - } - - // if the AF is already active - if ( af.IsActive() ) { - return true; - } - - // disable any collision model used - GetPhysics()->DisableClip(); - - // start using the AF - af.StartFromCurrentPose( spawnArgs.GetInt( "velocityTime", "0" ) ); - - return true; -} - -/* -===================== -idAnimated::PlayNextAnim -===================== -*/ -void idAnimated::PlayNextAnim( void ) { - const char *animname; - int len; - int cycle; - - if ( current_anim_index >= num_anims ) { - Hide(); - if ( spawnArgs.GetBool( "remove" ) ) { - PostEventMS( &EV_Remove, 0 ); - } else { - current_anim_index = 0; - } - return; - } - - Show(); - current_anim_index++; - - spawnArgs.GetString( va( "anim%d", current_anim_index ), NULL, &animname ); - if ( !animname ) { - anim = 0; - animator.Clear( ANIMCHANNEL_ALL, gameLocal.time, FRAME2MS( blendFrames ) ); - return; - } - - anim = animator.GetAnim( animname ); - if ( !anim ) { - gameLocal.Warning( "missing anim '%s' on %s", animname, name.c_str() ); - return; - } - - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' start anim '%s'\n", gameLocal.framenum, GetName(), animname ); - } - - spawnArgs.GetInt( "cycle", "1", cycle ); - if ( ( current_anim_index == num_anims ) && spawnArgs.GetBool( "loop_last_anim" ) ) { - cycle = -1; - } - - animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( blendFrames ) ); - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); - - len = animator.CurrentAnim( ANIMCHANNEL_ALL )->PlayLength(); - if ( len >= 0 ) { - PostEventMS( &EV_AnimDone, len, current_anim_index ); - } - - // offset the start time of the shader to sync it to the game time - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - animator.ForceUpdate(); - UpdateAnimation(); - UpdateVisuals(); - Present(); -} - -/* -=============== -idAnimated::Event_StartRagdoll -================ -*/ -void idAnimated::Event_StartRagdoll( void ) { - StartRagdoll(); -} - -/* -=============== -idAnimated::Event_AnimDone -================ -*/ -void idAnimated::Event_AnimDone( int animindex ) { - if ( g_debugCinematic.GetBool() ) { - const idAnim *animPtr = animator.GetAnim( anim ); - gameLocal.Printf( "%d: '%s' end anim '%s'\n", gameLocal.framenum, GetName(), animPtr ? animPtr->Name() : "" ); - } - - if ( ( animindex >= num_anims ) && spawnArgs.GetBool( "remove" ) ) { - Hide(); - PostEventMS( &EV_Remove, 0 ); - } else if ( spawnArgs.GetBool( "auto_advance" ) ) { - PlayNextAnim(); - } else { - activated = false; - } - - ActivateTargets( activator.GetEntity() ); -} - -/* -=============== -idAnimated::Event_Activate -================ -*/ -void idAnimated::Event_Activate( idEntity *_activator ) { - if ( num_anims ) { - PlayNextAnim(); - activator = _activator; - return; - } - - if ( activated ) { - // already activated - return; - } - - activated = true; - activator = _activator; - ProcessEvent( &EV_Animated_Start ); -} - -/* -=============== -idAnimated::Event_Start -================ -*/ -void idAnimated::Event_Start( void ) { - int cycle; - int len; - - Show(); - - if ( num_anims ) { - PlayNextAnim(); - return; - } - - if ( anim ) { - if ( g_debugCinematic.GetBool() ) { - const idAnim *animPtr = animator.GetAnim( anim ); - gameLocal.Printf( "%d: '%s' start anim '%s'\n", gameLocal.framenum, GetName(), animPtr ? animPtr->Name() : "" ); - } - spawnArgs.GetInt( "cycle", "1", cycle ); - animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( blendFrames ) ); - animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( cycle ); - - len = animator.CurrentAnim( ANIMCHANNEL_ALL )->PlayLength(); - if ( len >= 0 ) { - PostEventMS( &EV_AnimDone, len, 1 ); - } - } - - // offset the start time of the shader to sync it to the game time - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - animator.ForceUpdate(); - UpdateAnimation(); - UpdateVisuals(); - Present(); -} - -/* -=============== -idAnimated::Event_Footstep -=============== -*/ -void idAnimated::Event_Footstep( void ) { - StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL ); -} - -/* -===================== -idAnimated::Event_LaunchMissilesUpdate -===================== -*/ -void idAnimated::Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay ) { - idVec3 launchPos; - idVec3 targetPos; - idMat3 axis; - idVec3 dir; - idEntity * ent; - idProjectile * projectile; - const idDict * projectileDef; - const char * projectilename; - - projectilename = spawnArgs.GetString( "projectilename" ); - projectileDef = gameLocal.FindEntityDefDict( projectilename, false ); - if ( !projectileDef ) { - gameLocal.Warning( "idAnimated '%s' at (%s): 'launchMissiles' called with unknown projectile '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); - return; - } - - StartSound( "snd_missile", SND_CHANNEL_WEAPON, 0, false, NULL ); - - animator.GetJointTransform( ( jointHandle_t )launchjoint, gameLocal.time, launchPos, axis ); - launchPos = renderEntity.origin + launchPos * renderEntity.axis; - - animator.GetJointTransform( ( jointHandle_t )targetjoint, gameLocal.time, targetPos, axis ); - targetPos = renderEntity.origin + targetPos * renderEntity.axis; - - dir = targetPos - launchPos; - dir.Normalize(); - - gameLocal.SpawnEntityDef( *projectileDef, &ent, false ); - if ( !ent || !ent->IsType( idProjectile::Type ) ) { - gameLocal.Error( "idAnimated '%s' at (%s): in 'launchMissiles' call '%s' is not an idProjectile", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); - } - projectile = ( idProjectile * )ent; - projectile->Create( this, launchPos, dir ); - projectile->Launch( launchPos, dir, vec3_origin ); - - if ( numshots > 0 ) { - PostEventMS( &EV_LaunchMissilesUpdate, FRAME2MS( framedelay ), launchjoint, targetjoint, numshots - 1, framedelay ); - } -} - -/* -===================== -idAnimated::Event_LaunchMissiles -===================== -*/ -void idAnimated::Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay ) { - const idDict * projectileDef; - jointHandle_t launch; - jointHandle_t target; - - projectileDef = gameLocal.FindEntityDefDict( projectilename, false ); - if ( !projectileDef ) { - gameLocal.Warning( "idAnimated '%s' at (%s): unknown projectile '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), projectilename ); - return; - } - - launch = animator.GetJointHandle( launchjoint ); - if ( launch == INVALID_JOINT ) { - gameLocal.Warning( "idAnimated '%s' at (%s): unknown launch joint '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), launchjoint ); - gameLocal.Error( "Unknown joint '%s'", launchjoint ); - } - - target = animator.GetJointHandle( targetjoint ); - if ( target == INVALID_JOINT ) { - gameLocal.Warning( "idAnimated '%s' at (%s): unknown target joint '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), targetjoint ); - } - - spawnArgs.Set( "projectilename", projectilename ); - spawnArgs.Set( "missilesound", sound ); - - CancelEvents( &EV_LaunchMissilesUpdate ); - ProcessEvent( &EV_LaunchMissilesUpdate, launch, target, numshots - 1, framedelay ); -} - - -/* -=============================================================================== - - idStaticEntity - - Some static entities may be optimized into inline geometry by dmap - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idStaticEntity ) - EVENT( EV_Activate, idStaticEntity::Event_Activate ) -END_CLASS - -/* -=============== -idStaticEntity::idStaticEntity -=============== -*/ -idStaticEntity::idStaticEntity( void ) { - spawnTime = 0; - active = false; - fadeFrom.Set( 1, 1, 1, 1 ); - fadeTo.Set( 1, 1, 1, 1 ); - fadeStart = 0; - fadeEnd = 0; - runGui = false; - - m_LODHandle = 0; -} - -/* -=============== -idStaticEntity::Save -=============== -*/ -void idStaticEntity::Save( idSaveGame *savefile ) const { - savefile->WriteInt( spawnTime ); - savefile->WriteBool( active ); - savefile->WriteVec4( fadeFrom ); - savefile->WriteVec4( fadeTo ); - savefile->WriteInt( fadeStart ); - savefile->WriteInt( fadeEnd ); - savefile->WriteBool( runGui ); -} - -/* -=============== -idStaticEntity::Restore -=============== -*/ -void idStaticEntity::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( spawnTime ); - savefile->ReadBool( active ); - savefile->ReadVec4( fadeFrom ); - savefile->ReadVec4( fadeTo ); - savefile->ReadInt( fadeStart ); - savefile->ReadInt( fadeEnd ); - savefile->ReadBool( runGui ); -} - -/* -=============== -idStaticEntity::Spawn -=============== -*/ -void idStaticEntity::Spawn( void ) { - bool solid; - - // an inline static model will not do anything at all - if ( spawnArgs.GetBool( "inline" ) || gameLocal.world->spawnArgs.GetBool( "inlineAllStatics" ) ) { - Hide(); - return; - } - - solid = spawnArgs.GetBool( "solid" ); - - // ishtvan fix : Let clearing contents happen naturally on Hide instead of - // checking hidden here and clearing contents prematurely - if ( solid ) - { - GetPhysics()->SetContents( CONTENTS_SOLID | CONTENTS_OPAQUE ); - if( m_CustomContents != -1 ) - GetPhysics()->SetContents( m_CustomContents ); - } - else - { - GetPhysics()->SetContents( 0 ); - } - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - spawnTime = gameLocal.time; - active = false; - - idStr model = spawnArgs.GetString( "model" ); - if ( model.Find( ".prt" ) >= 0 ) { - - // we want the parametric particles out of sync with each other - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = gameLocal.random.RandomInt( 32767 ); - } - - fadeFrom.Set( 1, 1, 1, 1 ); - fadeTo.Set( 1, 1, 1, 1 ); - fadeStart = 0; - fadeEnd = 0; - - // NOTE: this should be used very rarely because it is expensive - runGui = spawnArgs.GetBool( "runGui" ); - if ( runGui ) { - BecomeActive( TH_THINK ); - } - - if (ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ) ) - { - // Have to start thinking if we're distance dependent - BecomeActive( TH_THINK ); - } -} - -/* -================ -idStaticEntity::ShowEditingDialog -================ -*/ -void idStaticEntity::ShowEditingDialog( void ) { - common->InitTool( EDITOR_PARTICLE, &spawnArgs ); -} - -/* -================ -idStaticEntity::Think -================ -*/ -void idStaticEntity::Think( void ) -{ - // will also do LOD thinking: - idEntity::Think(); - - if ( thinkFlags & TH_THINK ) - { - if ( runGui && renderEntity.gui[0] ) - { - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player ) - { - renderEntity.gui[0]->StateChanged( gameLocal.time, true ); - if ( renderEntity.gui[1] ) { - renderEntity.gui[1]->StateChanged( gameLocal.time, true ); - } - if ( renderEntity.gui[2] ) { - renderEntity.gui[2]->StateChanged( gameLocal.time, true ); - } - } - } - if ( fadeEnd > 0 ) - { - idVec4 color; - if ( gameLocal.time < fadeEnd ) { - color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) ); - } else { - color = fadeTo; - fadeEnd = 0; - - // TDM: Don't deactivate if we have to keep doing distance checks - if (m_DistCheckTimeStamp == 0) - BecomeInactive( TH_THINK ); - } - SetColor( color ); - } - } -} - -/* -================ -idStaticEntity::Fade -================ -*/ -void idStaticEntity::Fade( const idVec4 &to, float fadeTime ) { - GetColor( fadeFrom ); - fadeTo = to; - fadeStart = gameLocal.time; - fadeEnd = gameLocal.time + SEC2MS( fadeTime ); - BecomeActive( TH_THINK ); -} - -/* -================ -idStaticEntity::Hide -================ -*/ -void idStaticEntity::Hide( void ) { - idEntity::Hide(); - GetPhysics()->SetContents( 0 ); -} - -/* -================ -idStaticEntity::Show -================ -*/ -void idStaticEntity::Show( void ) { - idEntity::Show(); - GetPhysics()->SetContents( m_preHideContents ); -} - -/* -================ -idStaticEntity::Event_Activate -================ -*/ -void idStaticEntity::Event_Activate( idEntity *activator ) { - - spawnTime = gameLocal.time; - active = !active; - - const idKeyValue *kv = spawnArgs.FindKey( "hide" ); - if ( kv ) { - if ( IsHidden() ) { - Show(); - } else { - Hide(); - } - } - - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( spawnTime ); - renderEntity.shaderParms[5] = active; - // this change should be a good thing, it will automatically turn on - // lights etc.. when triggered so that does not have to be specifically done - // with trigger parms.. it MIGHT break things so need to keep an eye on it - renderEntity.shaderParms[ SHADERPARM_MODE ] = ( renderEntity.shaderParms[ SHADERPARM_MODE ] ) ? 0.0f : 1.0f; - BecomeActive( TH_UPDATEVISUALS ); -} - -/* -================ -idStaticEntity::WriteToSnapshot -================ -*/ -void idStaticEntity::WriteToSnapshot( idBitMsgDelta &msg ) const { - GetPhysics()->WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); - WriteColorToSnapshot( msg ); - WriteGUIToSnapshot( msg ); - msg.WriteBits( IsHidden()?1:0, 1 ); -} - -/* -================ -idStaticEntity::ReadFromSnapshot -================ -*/ -void idStaticEntity::ReadFromSnapshot( const idBitMsgDelta &msg ) { - bool hidden; - - GetPhysics()->ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - ReadColorFromSnapshot( msg ); - ReadGUIFromSnapshot( msg ); - hidden = msg.ReadBits( 1 ) == 1; - if ( hidden != IsHidden() ) { - if ( hidden ) { - Hide(); - } else { - Show(); - } - } - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - - -/* -=============================================================================== - -idFuncSmoke - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idFuncSmoke ) -EVENT( EV_Activate, idFuncSmoke::Event_Activate ) -END_CLASS - -/* -=============== -idFuncSmoke::idFuncSmoke -=============== -*/ -idFuncSmoke::idFuncSmoke() { - smokeTime = 0; - smoke = NULL; - restart = false; - m_LODHandle = 0; -} - -/* -=============== -idFuncSmoke::Save -=============== -*/ -void idFuncSmoke::Save( idSaveGame *savefile ) const { - savefile->WriteInt( smokeTime ); - savefile->WriteParticle( smoke ); - savefile->WriteBool( restart ); -} - -/* -=============== -idFuncSmoke::Restore -=============== -*/ -void idFuncSmoke::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( smokeTime ); - savefile->ReadParticle( smoke ); - savefile->ReadBool( restart ); -} - -/* -=============== -idFuncSmoke::Spawn -=============== -*/ -void idFuncSmoke::Spawn( void ) { - const char *smokeName = spawnArgs.GetString( "smoke" ); - if ( *smokeName != '\0' ) { - smoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } else { - smoke = NULL; - } - if ( spawnArgs.GetBool( "start_off" ) ) { - smokeTime = 0; - restart = false; - } else if ( smoke ) { - smokeTime = gameLocal.time; - BecomeActive( TH_UPDATEPARTICLES ); - restart = true; - } - GetPhysics()->SetContents( 0 ); -} - -/* -================ -idFuncSmoke::Event_Activate -================ -*/ -void idFuncSmoke::Event_Activate( idEntity *activator ) { - if ( thinkFlags & TH_UPDATEPARTICLES ) { - restart = false; - return; - } else { - BecomeActive( TH_UPDATEPARTICLES ); - restart = true; - smokeTime = gameLocal.time; - } -} - -/* -=============== -idFuncSmoke::Think -================ -*/ -void idFuncSmoke::Think( void ) { - - // if we are completely closed off from the player, don't do anything at all - if ( CheckDormant() || smoke == NULL || smokeTime == -1 ) { - return; - } - - if ( ( thinkFlags & TH_UPDATEPARTICLES) && !fl.hidden ) { - if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { - if ( restart ) { - smokeTime = gameLocal.time; - } else { - smokeTime = 0; - BecomeInactive( TH_UPDATEPARTICLES ); - } - } - } - - if (m_LODHandle) - { - // If this entity has LOD, let it think about it: - // Distance dependence checks - const lod_data_t *lod = gameLocal.m_ModelGenerator->GetLODDataPtr( m_LODHandle ); - if (lod) - { - if ( ( lod->DistCheckInterval > 0) - && ( (gameLocal.time - m_DistCheckTimeStamp) > lod->DistCheckInterval ) ) - { - m_DistCheckTimeStamp = gameLocal.time; -// gameLocal.Warning("%s: Think called with m_LOD %p, %i, interval %i, origin %s", -// GetName(), lod, m_DistCheckTimeStamp, m_LOD->DistCheckInterval, GetPhysics()->GetOrigin().ToString() ); - SwitchLOD( lod, - GetLODDistance( lod, gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(), GetPhysics()->GetOrigin(), renderEntity.bounds.GetSize(), cv_lod_bias.GetFloat() ) ); - } - } - } -} - - -/* -=============================================================================== - - idTextEntity - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idTextEntity ) -END_CLASS - -/* -================ -idTextEntity::Spawn -================ -*/ -void idTextEntity::Spawn( void ) { - // these are cached as the are used each frame - text = spawnArgs.GetString( "text" ); - playerOriented = spawnArgs.GetBool( "playerOriented" ); - bool force = spawnArgs.GetBool( "force" ); - if ( developer.GetBool() || force ) { - BecomeActive(TH_THINK); - } -} - -/* -================ -idTextEntity::Save -================ -*/ -void idTextEntity::Save( idSaveGame *savefile ) const { - savefile->WriteString( text ); - savefile->WriteBool( playerOriented ); -} - -/* -================ -idTextEntity::Restore -================ -*/ -void idTextEntity::Restore( idRestoreGame *savefile ) { - savefile->ReadString( text ); - savefile->ReadBool( playerOriented ); -} - -/* -================ -idTextEntity::Think -================ -*/ -void idTextEntity::Think( void ) { - if ( thinkFlags & TH_THINK ) { - gameRenderWorld->DrawText( text, GetPhysics()->GetOrigin(), 0.25, colorWhite, playerOriented ? gameLocal.GetLocalPlayer()->viewAngles.ToMat3() : GetPhysics()->GetAxis().Transpose(), 1 ); - for ( int i = 0; i < targets.Num(); i++ ) { - if ( targets[i].GetEntity() ) { - gameRenderWorld->DebugArrow( colorBlue, GetPhysics()->GetOrigin(), targets[i].GetEntity()->GetPhysics()->GetOrigin(), 1 ); - } - } - } else { - BecomeInactive( TH_ALL ); - } -} - - -/* -=============================================================================== - - idVacuumSeperatorEntity - - Can be triggered to let vacuum through a portal (blown out window) - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idVacuumSeparatorEntity ) - EVENT( EV_Activate, idVacuumSeparatorEntity::Event_Activate ) -END_CLASS - - -/* -================ -idVacuumSeparatorEntity::idVacuumSeparatorEntity -================ -*/ -idVacuumSeparatorEntity::idVacuumSeparatorEntity( void ) { - portal = 0; -} - -/* -================ -idVacuumSeparatorEntity::Save -================ -*/ -void idVacuumSeparatorEntity::Save( idSaveGame *savefile ) const { - savefile->WriteInt( (int)portal ); - savefile->WriteInt( gameRenderWorld->GetPortalState( portal ) ); -} - -/* -================ -idVacuumSeparatorEntity::Restore -================ -*/ -void idVacuumSeparatorEntity::Restore( idRestoreGame *savefile ) { - int state; - - savefile->ReadInt( (int &)portal ); - savefile->ReadInt( state ); - - gameLocal.SetPortalState( portal, state ); -} - -/* -================ -idVacuumSeparatorEntity::Spawn -================ -*/ -void idVacuumSeparatorEntity::Spawn() { - idBounds b; - - b = idBounds( spawnArgs.GetVector( "origin" ) ).Expand( 16 ); - portal = gameRenderWorld->FindPortal( b ); - if ( !portal ) { - gameLocal.Warning( "VacuumSeparator '%s' didn't contact a portal", spawnArgs.GetString( "name" ) ); - return; - } - gameLocal.SetPortalState( portal, PS_BLOCK_AIR | PS_BLOCK_LOCATION ); -} - -/* -================ -idVacuumSeparatorEntity::Event_Activate -================ -*/ -void idVacuumSeparatorEntity::Event_Activate( idEntity *activator ) { - if ( !portal ) { - return; - } - gameLocal.SetPortalState( portal, PS_BLOCK_NONE ); -} - - -/* -=============================================================================== - -idLocationSeparatorEntity - -=============================================================================== -*/ - -const idEventDef EV_GetPortalHandle( "getPortalHandle", NULL, 'f' ); - -CLASS_DECLARATION( idEntity, idLocationSeparatorEntity ) - EVENT( EV_GetPortalHandle, idLocationSeparatorEntity::Event_GetPortalHandle ) -END_CLASS - -/* -================ -idLocationSeparatorEntity::Spawn -================ -*/ -void idLocationSeparatorEntity::Spawn() -{ - idBounds b; - - // Tels: TODO: keep the portal handle as member, add Save/Restore - // and a script event to return the portal handle, so getPortalSoundLoss() - // and setPortalSoundLoss() can use it. - b = idBounds( spawnArgs.GetVector( "origin" ) ).Expand( 16 ); - m_Portal = gameRenderWorld->FindPortal( b ); - - if ( !m_Portal ) - { - gameLocal.Warning( "LocationSeparator '%s' didn't contact a portal", GetName() ); - return; - } - gameLocal.SetPortalState( m_Portal, PS_BLOCK_LOCATION ); - - // update the sound loss for the associated portal (Note sound loss must be positive) - m_SoundLoss = spawnArgs.GetFloat("sound_loss", "0.0"); - gameLocal.m_sndPropLoader->SetPortalLoss( m_Portal, idMath::Fabs(m_SoundLoss) ); - - // store the light loss factor for this portal - m_LightLoss = spawnArgs.GetFloat("light_loss", "0.0"); - -} - -/* -================ -idLocationSeparatorEntity::Save - -Tels: Each idLocationSeparatorEntity contains the handle of the portal it - is connected to, so we can let it return the handle. -================ -*/ -void idLocationSeparatorEntity::Save( idSaveGame *savefile ) const -{ - savefile->WriteFloat( m_SoundLoss ); - savefile->WriteFloat( m_LightLoss ); - savefile->WriteInt( m_Portal ); -} - -void idLocationSeparatorEntity::Restore( idRestoreGame *savefile ) -{ - savefile->ReadFloat( m_SoundLoss ); - savefile->ReadFloat( m_LightLoss ); - savefile->ReadInt( m_Portal ); -} - -void idLocationSeparatorEntity::Event_GetPortalHandle( void ) -{ - if ( !m_Portal ) { - return idThread::ReturnFloat( -1.0f ); - } - idThread::ReturnFloat( (float) m_Portal ); -} - -qhandle_t idLocationSeparatorEntity::GetPortalHandle( void ) const -{ - return m_Portal; -} - -float idLocationSeparatorEntity::GetLightLoss( void ) const -{ - return m_LightLoss; -} - -/* -=============================================================================== - - idVacuumEntity - - Levels should only have a single vacuum entity. - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idVacuumEntity ) -END_CLASS - -/* -================ -idVacuumEntity::Spawn -================ -*/ -void idVacuumEntity::Spawn() { - if ( gameLocal.vacuumAreaNum != -1 ) { - gameLocal.Warning( "idVacuumEntity::Spawn: multiple idVacuumEntity in level" ); - return; - } - - idVec3 org = spawnArgs.GetVector( "origin" ); - - gameLocal.vacuumAreaNum = gameRenderWorld->PointInArea( org ); -} - - -/* -=============================================================================== - -idLocationEntity - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idLocationEntity ) -END_CLASS - -/* -====================== -idLocationEntity::idLocationEntity -====================== -*/ -idLocationEntity::idLocationEntity( void ) -{ - m_SndLossMult = 1.0; - m_SndVolMod = 0.0; - m_ObjectiveGroup.Clear(); -} - -/* -====================== -idLocationEntity::Spawn -====================== -*/ -void idLocationEntity::Spawn() -{ - idStr realName; - - // this just holds dict information - - // if "location" not already set, use the entity name. - if ( !spawnArgs.GetString( "location", "", realName ) ) - { - spawnArgs.Set( "location", name ); - } - - m_SndLossMult = idMath::Fabs( spawnArgs.GetFloat("sound_loss_mult", "1.0") ); - m_SndVolMod = spawnArgs.GetFloat( "sound_vol_offset", "0.0" ); - m_ObjectiveGroup = spawnArgs.GetString( "objective_group", "" ); -} - -/* -====================== -idLocationEntity::Save -====================== -*/ -void idLocationEntity::Save( idSaveGame *savefile ) const -{ - savefile->WriteFloat( m_SndLossMult ); - savefile->WriteFloat( m_SndVolMod ); - savefile->WriteString( m_ObjectiveGroup ); -} - -/* -====================== -idLocationEntity::Restore -====================== -*/ -void idLocationEntity::Restore( idRestoreGame *savefile ) -{ - savefile->ReadFloat( m_SndLossMult ); - savefile->ReadFloat( m_SndVolMod ); - savefile->ReadString( m_ObjectiveGroup ); -} - -/* -====================== -idLocationEntity::GetLocation -====================== -*/ -const char *idLocationEntity::GetLocation( void ) const { - return spawnArgs.GetString( "location" ); -} - -/* -=============================================================================== - - idBeam - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idBeam ) - EVENT( EV_PostSpawn, idBeam::Event_MatchTarget ) - EVENT( EV_Activate, idBeam::Event_Activate ) -END_CLASS - -/* -=============== -idBeam::idBeam -=============== -*/ -idBeam::idBeam() { - target = NULL; - master = NULL; -} - -/* -=============== -idBeam::Save -=============== -*/ -void idBeam::Save( idSaveGame *savefile ) const { - target.Save( savefile ); - master.Save( savefile ); -} - -/* -=============== -idBeam::Restore -=============== -*/ -void idBeam::Restore( idRestoreGame *savefile ) { - target.Restore( savefile ); - master.Restore( savefile ); -} - -/* -=============== -idBeam::Spawn -=============== -*/ -void idBeam::Spawn( void ) { - float width; - - if ( spawnArgs.GetFloat( "width", "0", width ) ) { - renderEntity.shaderParms[ SHADERPARM_BEAM_WIDTH ] = width; - } - - SetModel( "_BEAM" ); - Hide(); - PostEventMS( &EV_PostSpawn, 0 ); -} - -/* -================ -idBeam::Think -================ -*/ -void idBeam::Think( void ) { - idBeam *masterEnt; - - if ( !IsHidden() && !target.GetEntity() ) { - // hide if our target is removed - Hide(); - } - - RunPhysics(); - - masterEnt = master.GetEntity(); - if ( masterEnt ) { - const idVec3 &origin = GetPhysics()->GetOrigin(); - masterEnt->SetBeamTarget( origin ); - } - Present(); -} - -/* -================ -idBeam::SetMaster -================ -*/ -void idBeam::SetMaster( idBeam *masterbeam ) { - master = masterbeam; -} - -/* -================ -idBeam::SetBeamTarget -================ -*/ -void idBeam::SetBeamTarget( const idVec3 &origin ) { - if ( ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_X ] != origin.x ) || ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_Y ] != origin.y ) || ( renderEntity.shaderParms[ SHADERPARM_BEAM_END_Z ] != origin.z ) ) { - renderEntity.shaderParms[ SHADERPARM_BEAM_END_X ] = origin.x; - renderEntity.shaderParms[ SHADERPARM_BEAM_END_Y ] = origin.y; - renderEntity.shaderParms[ SHADERPARM_BEAM_END_Z ] = origin.z; - UpdateVisuals(); - } -} - -/* -================ -idBeam::Show -================ -*/ -void idBeam::Show( void ) { - idBeam *targetEnt; - - idEntity::Show(); - - targetEnt = target.GetEntity(); - if ( targetEnt ) { - const idVec3 &origin = targetEnt->GetPhysics()->GetOrigin(); - SetBeamTarget( origin ); - } -} - -/* -================ -idBeam::Event_MatchTarget -================ -*/ -void idBeam::Event_MatchTarget( void ) { - int i; - idEntity *targetEnt; - idBeam *targetBeam; - - if ( !targets.Num() ) { - return; - } - - targetBeam = NULL; - for( i = 0; i < targets.Num(); i++ ) { - targetEnt = targets[ i ].GetEntity(); - if ( targetEnt && targetEnt->IsType( idBeam::Type ) ) { - targetBeam = static_cast( targetEnt ); - break; - } - } - - if ( !targetBeam ) { - gameLocal.Error( "Could not find valid beam target for '%s'", name.c_str() ); - } - - target = targetBeam; - targetBeam->SetMaster( this ); - if ( !spawnArgs.GetBool( "start_off" ) ) { - Show(); - } -} - -/* -================ -idBeam::Event_Activate -================ -*/ -void idBeam::Event_Activate( idEntity *activator ) { - if ( IsHidden() ) { - Show(); - } else { - Hide(); - } -} - -/* -================ -idBeam::WriteToSnapshot -================ -*/ -void idBeam::WriteToSnapshot( idBitMsgDelta &msg ) const { - GetPhysics()->WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); - WriteColorToSnapshot( msg ); - msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_X] ); - msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_Y] ); - msg.WriteFloat( renderEntity.shaderParms[SHADERPARM_BEAM_END_Z] ); -} - -/* -================ -idBeam::ReadFromSnapshot -================ -*/ -void idBeam::ReadFromSnapshot( const idBitMsgDelta &msg ) { - GetPhysics()->ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - ReadColorFromSnapshot( msg ); - renderEntity.shaderParms[SHADERPARM_BEAM_END_X] = msg.ReadFloat(); - renderEntity.shaderParms[SHADERPARM_BEAM_END_Y] = msg.ReadFloat(); - renderEntity.shaderParms[SHADERPARM_BEAM_END_Z] = msg.ReadFloat(); - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - - -/* -=============================================================================== - - idLiquid - -=============================================================================== -*/ - -#ifndef MOD_WATERPHYSICS -CLASS_DECLARATION( idEntity, idLiquid ) - EVENT( EV_Touch, idLiquid::Event_Touch ) -END_CLASS - -/* -================ -idLiquid::Save -================ -*/ -void idLiquid::Save( idSaveGame *savefile ) const { - // Nothing to save -} - -/* -================ -idLiquid::Restore -================ -*/ -void idLiquid::Restore( idRestoreGame *savefile ) { - //FIXME: NO! - Spawn(); -} - -/* -================ -idLiquid::Spawn -================ -*/ -void idLiquid::Spawn() { -/* - model = dynamic_cast( renderEntity.hModel ); - if ( !model ) { - gameLocal.Error( "Entity '%s' must have liquid model", name.c_str() ); - } - model->Reset(); - GetPhysics()->SetContents( CONTENTS_TRIGGER ); -*/ -} - -/* -================ -idLiquid::Event_Touch -================ -*/ -void idLiquid::Event_Touch( idEntity *other, trace_t *trace ) { - // FIXME: for QuakeCon -/* - idVec3 pos; - - pos = other->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - model->IntersectBounds( other->GetPhysics()->GetBounds().Translate( pos ), -10.0f ); -*/ -} -#endif - -/* -=============================================================================== - - idShaking - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idShaking ) - EVENT( EV_Activate, idShaking::Event_Activate ) -END_CLASS - -/* -=============== -idShaking::idShaking -=============== -*/ -idShaking::idShaking() { - active = false; -} - -/* -=============== -idShaking::Save -=============== -*/ -void idShaking::Save( idSaveGame *savefile ) const { - savefile->WriteBool( active ); - savefile->WriteStaticObject( physicsObj ); -} - -/* -=============== -idShaking::Restore -=============== -*/ -void idShaking::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( active ); - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); -} - -/* -=============== -idShaking::Spawn -=============== -*/ -void idShaking::Spawn( void ) { - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - SetPhysics( &physicsObj ); - - active = false; - if ( !spawnArgs.GetBool( "start_off" ) ) { - BeginShaking(); - } -} - -/* -================ -idShaking::BeginShaking -================ -*/ -void idShaking::BeginShaking( void ) { - int phase; - idAngles shake; - int period; - - active = true; - phase = gameLocal.random.RandomInt( 1000 ); - shake = spawnArgs.GetAngles( "shake", "0.5 0.5 0.5" ); - period = static_cast(spawnArgs.GetFloat( "period", "0.05" ) * 1000); - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), phase, static_cast(period * 0.25f), GetPhysics()->GetAxis().ToAngles(), shake, ang_zero ); -} - -/* -================ -idShaking::Event_Activate -================ -*/ -void idShaking::Event_Activate( idEntity *activator ) { - if ( !active ) { - BeginShaking(); - } else { - active = false; - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, physicsObj.GetAxis().ToAngles(), ang_zero, ang_zero ); - } -} - -/* -=============================================================================== - - idEarthQuake - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idEarthQuake ) - EVENT( EV_Activate, idEarthQuake::Event_Activate ) -END_CLASS - -/* -=============== -idEarthQuake::idEarthQuake -=============== -*/ -idEarthQuake::idEarthQuake() { - wait = 0.0f; - random = 0.0f; - nextTriggerTime = 0; - shakeStopTime = 0; - triggered = false; - playerOriented = false; - disabled = false; - shakeTime = 0.0f; -} - -/* -=============== -idEarthQuake::Save -=============== -*/ -void idEarthQuake::Save( idSaveGame *savefile ) const { - savefile->WriteInt( nextTriggerTime ); - savefile->WriteInt( shakeStopTime ); - savefile->WriteFloat( wait ); - savefile->WriteFloat( random ); - savefile->WriteBool( triggered ); - savefile->WriteBool( playerOriented ); - savefile->WriteBool( disabled ); - savefile->WriteFloat( shakeTime ); -} - -/* -=============== -idEarthQuake::Restore -=============== -*/ -void idEarthQuake::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( nextTriggerTime ); - savefile->ReadInt( shakeStopTime ); - savefile->ReadFloat( wait ); - savefile->ReadFloat( random ); - savefile->ReadBool( triggered ); - savefile->ReadBool( playerOriented ); - savefile->ReadBool( disabled ); - savefile->ReadFloat( shakeTime ); - - if ( shakeStopTime > gameLocal.time ) { - BecomeActive( TH_THINK ); - } -} - -/* -=============== -idEarthQuake::Spawn -=============== -*/ -void idEarthQuake::Spawn( void ) { - nextTriggerTime = 0; - shakeStopTime = 0; - wait = spawnArgs.GetFloat( "wait", "15" ); - random = spawnArgs.GetFloat( "random", "5" ); - triggered = spawnArgs.GetBool( "triggered" ); - playerOriented = spawnArgs.GetBool( "playerOriented" ); - disabled = false; - shakeTime = spawnArgs.GetFloat( "shakeTime", "0" ); - - if ( !triggered ){ - PostEventSec( &EV_Activate, spawnArgs.GetFloat( "wait" ), this ); - } - BecomeInactive( TH_THINK ); -} - -/* -================ -idEarthQuake::Event_Activate -================ -*/ -void idEarthQuake::Event_Activate( idEntity *activator ) { - - if ( nextTriggerTime > gameLocal.time ) { - return; - } - - if ( disabled && activator == this ) { - return; - } - - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player == NULL ) { - return; - } - - nextTriggerTime = 0; - - if ( !triggered && activator != this ){ - // if we are not triggered ( i.e. random ), disable or enable - disabled ^= 1; - if (disabled) { - return; - } else { - PostEventSec( &EV_Activate, wait + random * gameLocal.random.CRandomFloat(), this ); - } - } - - ActivateTargets( activator ); - - const idSoundShader *shader = declManager->FindSound( spawnArgs.GetString( "snd_quake" ) ); - if ( playerOriented ) { - player->StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); - } else { - StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); - } - - if ( shakeTime > 0.0f ) { - shakeStopTime = gameLocal.time + SEC2MS( shakeTime ); - BecomeActive( TH_THINK ); - } - - if ( wait > 0.0f ) { - if ( !triggered ) { - PostEventSec( &EV_Activate, wait + random * gameLocal.random.CRandomFloat(), this ); - } else { - nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); - } - } else if ( shakeTime == 0.0f ) { - PostEventMS( &EV_Remove, 0 ); - } -} - - -/* -=============== -idEarthQuake::Think -================ -*/ -void idEarthQuake::Think( void ) { - if ( thinkFlags & TH_THINK ) { - if ( gameLocal.time > shakeStopTime ) { - BecomeInactive( TH_THINK ); - if ( wait <= 0.0f ) { - PostEventMS( &EV_Remove, 0 ); - } - return; - } - float shakeVolume = gameSoundWorld->CurrentShakeAmplitudeForPosition( gameLocal.time, gameLocal.GetLocalPlayer()->firstPersonViewOrigin ); - gameLocal.RadiusPush( GetPhysics()->GetOrigin(), 256, 1500 * shakeVolume, this, this, 1.0f, true ); - } - BecomeInactive( TH_UPDATEVISUALS ); -} - -/* -=============================================================================== - - idFuncPortal - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idFuncPortal ) - EVENT( EV_Activate, idFuncPortal::Event_Activate ) -END_CLASS - -/* -=============== -idFuncPortal::idFuncPortal -=============== -*/ -idFuncPortal::idFuncPortal() -{ - portal = 0; - state = false; - m_bDistDependent = false; - m_Distance = 0; - - m_TimeStamp = 0; - m_Interval = 1000; -} - -/* -=============== -idFuncPortal::Save -=============== -*/ -void idFuncPortal::Save( idSaveGame *savefile ) const -{ - savefile->WriteInt( (int)portal ); - savefile->WriteBool( state ); - - savefile->WriteBool( m_bDistDependent ); - savefile->WriteFloat( m_Distance ); - savefile->WriteInt( m_TimeStamp ); - savefile->WriteInt( m_Interval ); -} - -/* -=============== -idFuncPortal::Restore -=============== -*/ -void idFuncPortal::Restore( idRestoreGame *savefile ) -{ - savefile->ReadInt( (int &)portal ); - savefile->ReadBool( state ); - gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); - - savefile->ReadBool( m_bDistDependent ); - savefile->ReadFloat( m_Distance ); - savefile->ReadInt( m_TimeStamp ); - savefile->ReadInt( m_Interval ); -} - -/* -=============== -idFuncPortal::Spawn -=============== -*/ -void idFuncPortal::Spawn( void ) -{ - portal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds().Expand( 32.0f ) ); - if ( portal > 0 ) - { - state = spawnArgs.GetBool( "start_on" ); - gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); - } - - if( (m_Distance = spawnArgs.GetFloat( "portal_dist", "0.0" )) <= 0 ) - goto Quit; - - // distance dependent portals from this point on: - m_bDistDependent = true; - m_Distance *= m_Distance; - m_Interval = (int) (1000.0f * spawnArgs.GetFloat( "distcheck_period", "1.0" )); - - // add some phase diversity to the checks so that they don't all run in one frame - // make sure they all run on the first frame though, by initializing m_TimeStamp to - // be at least one interval early. - m_TimeStamp = gameLocal.time - (int) (m_Interval * (1.0f + 0.5f*gameLocal.random.RandomFloat()) ); - - // only start thinking if it's distance dependent. - BecomeActive( TH_THINK ); - -Quit: - return; -} - -/* -================ -idFuncPortal::Event_Activate -================ -*/ -void idFuncPortal::Event_Activate( idEntity *activator ) -{ - if ( portal > 0 ) - { - state = !state; - gameLocal.SetPortalState( portal, state ? PS_BLOCK_ALL : PS_BLOCK_NONE ); - } - - // activate our targets - PostEventMS( &EV_ActivateTargets, 0, activator ); -} - -void idFuncPortal::Think( void ) -{ - idVec3 delta; - bool bWithinDist; - - if( !m_bDistDependent ) - goto Quit; - - if( (gameLocal.time - m_TimeStamp) < m_Interval ) - goto Quit; - - m_TimeStamp = gameLocal.time; - bWithinDist = false; - - delta = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin(); - delta -= GetPhysics()->GetOrigin(); - - bWithinDist = (delta.LengthSqr() < m_Distance); - - if( (!state && !bWithinDist) || (state && bWithinDist) ) - { - // toggle portal and trigger targets - Event_Activate( gameLocal.GetLocalPlayer() ); - } - -Quit: - idEntity::Think(); - return; -} - -/* -=============================================================================== - - idFuncAASPortal - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idFuncAASPortal ) - EVENT( EV_Activate, idFuncAASPortal::Event_Activate ) -END_CLASS - -/* -=============== -idFuncAASPortal::idFuncAASPortal -=============== -*/ -idFuncAASPortal::idFuncAASPortal() { - state = false; -} - -/* -=============== -idFuncAASPortal::Save -=============== -*/ -void idFuncAASPortal::Save( idSaveGame *savefile ) const { - savefile->WriteBool( state ); -} - -/* -=============== -idFuncAASPortal::Restore -=============== -*/ -void idFuncAASPortal::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( state ); - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); -} - -/* -=============== -idFuncAASPortal::Spawn -=============== -*/ -void idFuncAASPortal::Spawn( void ) { - state = spawnArgs.GetBool( "start_on" ); - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); -} - -/* -================ -idFuncAASPortal::Event_Activate -================ -*/ -void idFuncAASPortal::Event_Activate( idEntity *activator ) { - state ^= 1; - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, state ); -} - -/* -=============================================================================== - - idFuncAASObstacle - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idFuncAASObstacle ) - EVENT( EV_Activate, idFuncAASObstacle::Event_Activate ) -END_CLASS - -/* -=============== -idFuncAASObstacle::idFuncAASObstacle -=============== -*/ -idFuncAASObstacle::idFuncAASObstacle() { - state = false; -} - -/* -=============== -idFuncAASObstacle::Save -=============== -*/ -void idFuncAASObstacle::Save( idSaveGame *savefile ) const { - savefile->WriteBool( state ); -} - -/* -=============== -idFuncAASObstacle::Restore -=============== -*/ -void idFuncAASObstacle::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( state ); - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); -} - -/* -=============== -idFuncAASObstacle::Spawn -=============== -*/ -void idFuncAASObstacle::Spawn( void ) { - state = spawnArgs.GetBool( "start_on" ); - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); - if (cv_ai_show_aasfuncobstacle_state.GetBool()) - { - gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 15000); - } -} - -/* -================ -idFuncAASObstacle::Event_Activate -================ -*/ -void idFuncAASObstacle::Event_Activate( idEntity *activator ) { - state ^= 1; - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); - if (cv_ai_show_aasfuncobstacle_state.GetBool()) - { - gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 2000); - } -} - -void idFuncAASObstacle::SetAASState(bool newState) -{ - state = newState; - gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_OBSTACLE, state ); - if (cv_ai_show_aasfuncobstacle_state.GetBool()) - { - gameRenderWorld->DebugBounds(state ? colorRed : colorGreen, GetPhysics()->GetBounds(), GetPhysics()->GetOrigin(), 2000); - } -} - - -/* -=============================================================================== - - idPhantomObjects - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idPhantomObjects ) - EVENT( EV_Activate, idPhantomObjects::Event_Activate ) -END_CLASS - -/* -=============== -idPhantomObjects::idPhantomObjects -=============== -*/ -idPhantomObjects::idPhantomObjects() { - target = NULL; - end_time = 0; - throw_time = 0.0f; - shake_time = 0.0f; - shake_ang.Zero(); - speed = 0.0f; - min_wait = 0; - max_wait = 0; - fl.neverDormant = false; -} - -/* -=============== -idPhantomObjects::Save -=============== -*/ -void idPhantomObjects::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( end_time ); - savefile->WriteFloat( throw_time ); - savefile->WriteFloat( shake_time ); - savefile->WriteVec3( shake_ang ); - savefile->WriteFloat( speed ); - savefile->WriteInt( min_wait ); - savefile->WriteInt( max_wait ); - target.Save( savefile ); - savefile->WriteInt( targetTime.Num() ); - for( i = 0; i < targetTime.Num(); i++ ) { - savefile->WriteInt( targetTime[ i ] ); - } - - for( i = 0; i < lastTargetPos.Num(); i++ ) { - savefile->WriteVec3( lastTargetPos[ i ] ); - } -} - -/* -=============== -idPhantomObjects::Restore -=============== -*/ -void idPhantomObjects::Restore( idRestoreGame *savefile ) { - int num; - int i; - - savefile->ReadInt( end_time ); - savefile->ReadFloat( throw_time ); - savefile->ReadFloat( shake_time ); - savefile->ReadVec3( shake_ang ); - savefile->ReadFloat( speed ); - savefile->ReadInt( min_wait ); - savefile->ReadInt( max_wait ); - target.Restore( savefile ); - - savefile->ReadInt( num ); - targetTime.SetGranularity( 1 ); - targetTime.SetNum( num ); - lastTargetPos.SetGranularity( 1 ); - lastTargetPos.SetNum( num ); - - for( i = 0; i < num; i++ ) { - savefile->ReadInt( targetTime[ i ] ); - } - - if ( savefile->GetBuildNumber() == INITIAL_RELEASE_BUILD_NUMBER ) { - // these weren't saved out in the first release - for( i = 0; i < num; i++ ) { - lastTargetPos[ i ].Zero(); - } - } else { - for( i = 0; i < num; i++ ) { - savefile->ReadVec3( lastTargetPos[ i ] ); - } - } -} - -/* -=============== -idPhantomObjects::Spawn -=============== -*/ -void idPhantomObjects::Spawn( void ) { - throw_time = spawnArgs.GetFloat( "time", "5" ); - speed = spawnArgs.GetFloat( "speed", "1200" ); - shake_time = spawnArgs.GetFloat( "shake_time", "1" ); - throw_time -= shake_time; - if ( throw_time < 0.0f ) { - throw_time = 0.0f; - } - min_wait = SEC2MS( spawnArgs.GetFloat( "min_wait", "1" ) ); - max_wait = SEC2MS( spawnArgs.GetFloat( "max_wait", "3" ) ); - - shake_ang = spawnArgs.GetVector( "shake_ang", "65 65 65" ); - Hide(); - GetPhysics()->SetContents( 0 ); -} - -/* -================ -idPhantomObjects::Event_Activate -================ -*/ -void idPhantomObjects::Event_Activate( idEntity *activator ) { - int i; - float time; - float frac; - float scale; - - if ( thinkFlags & TH_THINK ) { - BecomeInactive( TH_THINK ); - return; - } - - RemoveNullTargets(); - if ( !targets.Num() ) { - return; - } - - if ( !activator || !activator->IsType( idActor::Type ) ) { - target = gameLocal.GetLocalPlayer(); - } else { - target = static_cast( activator ); - } - - end_time = gameLocal.time + SEC2MS( spawnArgs.GetFloat( "end_time", "0" ) ); - - targetTime.SetNum( targets.Num() ); - lastTargetPos.SetNum( targets.Num() ); - - const idVec3 &toPos = target.GetEntity()->GetEyePosition(); - - // calculate the relative times of all the objects - time = 0.0f; - for( i = 0; i < targetTime.Num(); i++ ) { - targetTime[ i ] = SEC2MS( time ); - lastTargetPos[ i ] = toPos; - - frac = 1.0f - ( float )i / ( float )targetTime.Num(); - time += ( gameLocal.random.RandomFloat() + 1.0f ) * 0.5f * frac + 0.1f; - } - - // scale up the times to fit within throw_time - scale = throw_time / time; - for( i = 0; i < targetTime.Num(); i++ ) { - targetTime[ i ] = static_cast(gameLocal.time + SEC2MS( shake_time )+ targetTime[ i ] * scale); - } - - BecomeActive( TH_THINK ); -} - -/* -=============== -idPhantomObjects::Think -================ -*/ -void idPhantomObjects::Think( void ) { - int i; - int num; - float time; - idVec3 vel; - idVec3 ang; - idEntity *ent; - idActor *targetEnt; - idPhysics *entPhys; - trace_t tr; - - // if we are completely closed off from the player, don't do anything at all - if ( CheckDormant() ) { - return; - } - - if ( !( thinkFlags & TH_THINK ) ) { - BecomeInactive( thinkFlags & ~TH_THINK ); - return; - } - - targetEnt = target.GetEntity(); - if ( !targetEnt || ( targetEnt->health <= 0 ) || ( end_time && ( gameLocal.time > end_time ) ) || gameLocal.inCinematic ) { - BecomeInactive( TH_THINK ); - } - - const idVec3 &toPos = targetEnt->GetEyePosition(); - - num = 0; - for ( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( !ent ) { - continue; - } - - if ( ent->fl.hidden ) { - // don't throw hidden objects - continue; - } - - if ( !targetTime[ i ] ) { - // already threw this object - continue; - } - - num++; - - time = MS2SEC( targetTime[ i ] - gameLocal.time ); - if ( time > shake_time ) { - continue; - } - - entPhys = ent->GetPhysics(); - const idVec3 &entOrg = entPhys->GetOrigin(); - - gameLocal.clip.TracePoint( tr, entOrg, toPos, MASK_OPAQUE, ent ); - if ( tr.fraction >= 1.0f || ( gameLocal.GetTraceEntity( tr ) == targetEnt ) ) { - lastTargetPos[ i ] = toPos; - } - - if ( time < 0.0f ) { - idAI::PredictTrajectory( entPhys->GetOrigin(), lastTargetPos[ i ], speed, entPhys->GetGravity(), - entPhys->GetClipModel(), entPhys->GetClipMask(), 256.0f, ent, targetEnt, ai_debugTrajectory.GetBool() ? 1 : 0, vel ); - vel *= speed; - entPhys->SetLinearVelocity( vel ); - if ( !end_time ) { - targetTime[ i ] = 0; - } else { - targetTime[ i ] = gameLocal.time + gameLocal.random.RandomInt( max_wait - min_wait ) + min_wait; - } - if ( ent->IsType( idMoveable::Type ) ) { - idMoveable *ment = static_cast( ent ); - ment->EnableDamage( true, 2.5f ); - } - } else { - // this is not the right way to set the angular velocity, but the effect is nice, so I'm keeping it. :) - ang.Set( gameLocal.random.CRandomFloat() * shake_ang.x, gameLocal.random.CRandomFloat() * shake_ang.y, gameLocal.random.CRandomFloat() * shake_ang.z ); - ang *= ( 1.0f - time / shake_time ); - entPhys->SetAngularVelocity( ang ); - } - } - - if ( !num ) { - BecomeInactive( TH_THINK ); - } -} - -/* -=============================================================================== -idPortalSky -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idPortalSky ) - - EVENT( EV_PostSpawn, idPortalSky::Event_PostSpawn ) - EVENT( EV_Activate, idPortalSky::Event_Activate ) - -END_CLASS - -/* -=============== -idPortalSky::idPortalSky -=============== -*/ - -idPortalSky::idPortalSky( void ) { -} - -/* -=============== -idPortalSky::~idPortalSky -=============== -*/ - -idPortalSky::~idPortalSky( void ) { -} - -/* -=============== -idPortalSky::Spawn -=============== -*/ - -void idPortalSky::Spawn( void ) { - if ( !spawnArgs.GetBool( "triggered" ) ) { - PostEventMS( &EV_PostSpawn, 1 ); - } -} - -/* -================ -idPortalSky::Event_PostSpawn -================ - -*/ - -void idPortalSky::Event_PostSpawn() { - - gameLocal.SetPortalSkyEnt( this ); - -} - -/* -================ -idPortalSky::Event_Activate -================ -*/ - -void idPortalSky::Event_Activate( idEntity *activator ) { - gameLocal.SetPortalSkyEnt( this ); -} - - -/* -=============================================================================== - - tdmVine - climbable vine piece (grayman #2787) - -=============================================================================== -*/ - -const idEventDef EV_Vine_SetPrime( "setPrime", "e", 0 ); -const idEventDef EV_Vine_GetPrime( "getPrime", NULL, 'e' ); -const idEventDef EV_Vine_AddDescendant( "addDescendant", "e", 0 ); -const idEventDef EV_Vine_CanWater( "canWater", NULL, 'f' ); -const idEventDef EV_Vine_SetWatered( "setWatered", NULL, 0 ); -const idEventDef EV_Vine_ClearWatered( "clearWatered", NULL, 0 ); -const idEventDef EV_Vine_ScaleVine( "scaleVine", "f", 0 ); - -CLASS_DECLARATION( idStaticEntity, tdmVine ) - EVENT( EV_Vine_SetPrime, tdmVine::Event_SetPrime) - EVENT( EV_Vine_GetPrime, tdmVine::Event_GetPrime) - EVENT( EV_Vine_AddDescendant, tdmVine::Event_AddDescendant) - EVENT( EV_Vine_CanWater, tdmVine::Event_CanWater) - EVENT( EV_Vine_SetWatered, tdmVine::Event_SetWatered) - EVENT( EV_Vine_ClearWatered, tdmVine::Event_ClearWatered ) - EVENT( EV_Vine_ScaleVine, tdmVine::Event_ScaleVine ) -END_CLASS - -tdmVine::tdmVine( void ) -{ - _watered = false; - _prime = NULL; - _descendants.Clear(); -} - -void tdmVine::Save( idSaveGame *savefile ) const -{ - savefile->WriteBool( _watered ); - savefile->WriteObject( _prime ); - savefile->WriteInt( _descendants.Num() ); - for ( int i = 0 ; i < _descendants.Num() ; i++) - { - _descendants[i].Save( savefile ); - } -} - -void tdmVine::Restore( idRestoreGame *savefile ) -{ - savefile->ReadBool( _watered ); - savefile->ReadObject( reinterpret_cast( _prime ) ); - int num; - savefile->ReadInt( num ); - _descendants.SetNum( num ); - for ( int i = 0 ; i < num ; i++ ) - { - _descendants[i].Restore( savefile ); - } -} - -void tdmVine::Spawn() -{ -} - -void tdmVine::Event_SetPrime( tdmVine* newPrime ) -{ - _prime = newPrime; -} - -void tdmVine::Event_GetPrime() -{ - idThread::ReturnEntity( _prime ); -} - -void tdmVine::Event_AddDescendant( tdmVine* descendant ) -{ - idEntityPtr< tdmVine > tdmVinePtr; - tdmVinePtr = descendant; - _descendants.Append( tdmVinePtr ); -} - -void tdmVine::Event_ClearWatered() -{ - _watered = false; -} - -void tdmVine::Event_SetWatered() -{ - _watered = true; -} - -void tdmVine::Event_CanWater() -{ - // For a given vine family, only allow two pieces to be - // watered by a water stim. Otherwise, growth can be - // rampant as the stim falls through the family. - - float canWater = 1; - int wateredCount = 0; - if ( _watered ) // the prime vine should check itself first - { - wateredCount++; - } - for ( int i = 0 ; i < _descendants.Num() ; i++ ) - { - idEntityPtr< tdmVine > tdmVinePtr = _descendants[i]; - tdmVine* vine = tdmVinePtr.GetEntity(); - if ( vine && vine->_watered ) - { - if ( ++wateredCount >= 2 ) - { - canWater = 0; - break; - } - } - } - idThread::ReturnFloat( canWater ); -} - -void tdmVine::Event_ScaleVine(float factor) -{ - idMat3 axis = GetPhysics()->GetAxis(); - axis *= factor; - GetPhysics()->SetAxis( axis ); - UpdateVisuals(); -} diff --git a/game/misc.h b/game/misc.h deleted file mode 100644 index 82e9e5b8d..000000000 --- a/game/misc.h +++ /dev/null @@ -1,815 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_MISC_H__ -#define __GAME_MISC_H__ - -/* -=============================================================================== - -idSpawnableEntity - -A simple, spawnable entity with a model and no functionable ability of it's own. -For example, it can be used as a placeholder during development, for marking -locations on maps for script, or for simple placed models without any behavior -that can be bound to other entities. Should not be subclassed. -=============================================================================== -*/ - -class idSpawnableEntity : public idEntity { -public: - CLASS_PROTOTYPE( idSpawnableEntity ); - - void Spawn( void ); - -private: -}; - -/* -=============================================================================== - - Potential spawning position for players. - The first time a player enters the game, they will be at an 'initial' spot. - Targets will be fired when someone spawns in on them. - - When triggered, will cause player to be teleported to spawn spot. - -=============================================================================== -*/ - -class idPlayerStart : public idEntity { -public: - CLASS_PROTOTYPE( idPlayerStart ); - - enum { - EVENT_TELEPORTPLAYER = idEntity::EVENT_MAXEVENTS, - EVENT_MAXEVENTS - }; - - idPlayerStart( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - -private: - int teleportStage; - - void Event_TeleportPlayer( idEntity *activator ); - void Event_TeleportStage( idEntity *player ); - void TeleportPlayer( idPlayer *player ); -}; - - -/* -=============================================================================== - - Non-displayed entity used to activate triggers when it touches them. - Bind to a mover to have the mover activate a trigger as it moves. - When target by triggers, activating the trigger will toggle the - activator on and off. Check "start_off" to have it spawn disabled. - -=============================================================================== -*/ - -class idActivator : public idEntity { -public: - CLASS_PROTOTYPE( idActivator ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - -private: - bool stay_on; - - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - - Path entities for monsters to follow. - -=============================================================================== -*/ -class idPathCorner : public idEntity { -public: - CLASS_PROTOTYPE( idPathCorner ); - - void Spawn( void ); - - static void DrawDebugInfo( void ); - - static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore, idAI* owner ); - -private: - void Event_RandomPath( void ); -}; - -/* -=============================================================================== - - Path entities for AI to flee to. - -=============================================================================== -*/ -class tdmPathFlee : public idEntity { -public: - CLASS_PROTOTYPE( tdmPathFlee ); - - virtual ~tdmPathFlee(); - - void Spawn( void ); - - static void DrawDebugInfo( void ); -}; - -/* -=============================================================================== - - Object that fires targets and changes shader parms when damaged. - -=============================================================================== -*/ - -class idDamagable : public idEntity { -public: - CLASS_PROTOTYPE( idDamagable ); - - idDamagable( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - -private: - int count; - int nextTriggerTime; - - void BecomeBroken( idEntity *activator ); - void Event_BecomeBroken( idEntity *activator ); - void Event_RestoreDamagable( void ); -}; - - -/* -=============================================================================== - - Hidden object that explodes when activated - -=============================================================================== -*/ - -class idExplodable : public idEntity { -public: - CLASS_PROTOTYPE( idExplodable ); - - void Spawn( void ); - -private: - void Event_Explode( idEntity *activator ); -}; - - -/* -=============================================================================== - - idSpring - -=============================================================================== -*/ - -class idSpring : public idEntity { -public: - CLASS_PROTOTYPE( idSpring ); - - void Spawn( void ); - - virtual void Think( void ); - -private: - idEntity * ent1; - idEntity * ent2; - int id1; - int id2; - idVec3 p1; - idVec3 p2; - idForce_Spring spring; - - void Event_LinkSpring( void ); -}; - - -/* -=============================================================================== - - idForceField - -=============================================================================== -*/ - -class idForceField : public idEntity { -public: - CLASS_PROTOTYPE( idForceField ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - - virtual void Think( void ); - -private: - idForce_Field forceField; - - void Toggle( void ); - - void Event_Activate( idEntity *activator ); - void Event_Toggle( void ); - void Event_FindTargets( void ); -}; - - -/* -=============================================================================== - - idAnimated - -=============================================================================== -*/ - -class idAnimated : public idAFEntity_Gibbable { -public: - CLASS_PROTOTYPE( idAnimated ); - - idAnimated(); - virtual ~idAnimated(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - virtual bool LoadAF( void ); - bool StartRagdoll( void ); - virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); - -private: - int num_anims; - int current_anim_index; - int anim; - int blendFrames; - jointHandle_t soundJoint; - idEntityPtr activator; - bool activated; - - void PlayNextAnim( void ); - - void Event_Activate( idEntity *activator ); - void Event_Start( void ); - void Event_StartRagdoll( void ); - void Event_AnimDone( int animIndex ); - void Event_Footstep( void ); - void Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay ); - void Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay ); -}; - - -/* -=============================================================================== - - idStaticEntity - -=============================================================================== -*/ - -class idStaticEntity : public idEntity { -public: - CLASS_PROTOTYPE( idStaticEntity ); - - idStaticEntity( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - void ShowEditingDialog( void ); - virtual void Hide( void ); - virtual void Show( void ); - void Fade( const idVec4 &to, float fadeTime ); - virtual void Think( void ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - -private: - void Event_Activate( idEntity *activator ); - - int spawnTime; - bool active; - idVec4 fadeFrom; - idVec4 fadeTo; - int fadeStart; - int fadeEnd; - bool runGui; -}; - - -/* -=============================================================================== - -idFuncSmoke - -=============================================================================== -*/ - -class idFuncSmoke : public idEntity { -public: - CLASS_PROTOTYPE( idFuncSmoke ); - - idFuncSmoke(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - void Event_Activate( idEntity *activator ); - -private: - int smokeTime; - const idDeclParticle * smoke; - bool restart; -}; - - -/* -=============================================================================== - -idTextEntity - -=============================================================================== -*/ - -class idTextEntity : public idEntity { -public: - CLASS_PROTOTYPE( idTextEntity ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - -private: - idStr text; - bool playerOriented; -}; - - -/* -=============================================================================== - -idLocationEntity - -=============================================================================== -*/ - -class idLocationEntity : public idEntity { -public: - CLASS_PROTOTYPE( idLocationEntity ); - - idLocationEntity( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - const char * GetLocation( void ) const; - -public: - /** - * Soundprop: Loss multiplier for atmospheric attenuation - **/ - float m_SndLossMult; - /** - * Soundprop: Volume offset for sounds originating in location - **/ - float m_SndVolMod; - /** - * Objective system: Location's objective group name for objective checks - **/ - idStr m_ObjectiveGroup; - -private: -}; - -class idLocationSeparatorEntity : public idEntity { -public: - CLASS_PROTOTYPE( idLocationSeparatorEntity ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - qhandle_t GetPortalHandle( void ) const; - // Returns a factor (0..1.0) that says how much light the portal lets through - float GetLightLoss( void ) const; - void Event_GetPortalHandle( void ); - -private: - - /** - * Soundprop: Volume loss for sounds traveling through this portal, in - * addition to a potential door on this portal. - **/ - float m_SoundLoss; - - /** - * Tels: Lightprop: Volume loss for sounds traveling through this portal - **/ - float m_LightLoss; - - /** - * Tels: Handle of the portal this entity touches. - **/ - qhandle_t m_Portal; -}; - -class idVacuumSeparatorEntity : public idEntity { -public: - CLASS_PROTOTYPE( idVacuumSeparatorEntity ); - - idVacuumSeparatorEntity( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Event_Activate( idEntity *activator ); - -private: - qhandle_t portal; -}; - -class idVacuumEntity : public idEntity { -public: - CLASS_PROTOTYPE( idVacuumEntity ); - - void Spawn( void ); - -private: -}; - - -/* -=============================================================================== - - idBeam - -=============================================================================== -*/ - -class idBeam : public idEntity { -public: - CLASS_PROTOTYPE( idBeam ); - - idBeam(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - - void SetMaster( idBeam *masterbeam ); - void SetBeamTarget( const idVec3 &origin ); - - virtual void Show( void ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - -private: - void Event_MatchTarget( void ); - void Event_Activate( idEntity *activator ); - - idEntityPtr target; - idEntityPtr master; -}; - - -/* -=============================================================================== - - idLiquid - -=============================================================================== -*/ - -#ifndef MOD_WATERPHYSICS -class idRenderModelLiquid; - -class idLiquid : public idEntity { -public: - CLASS_PROTOTYPE( idLiquid ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - void Event_Touch( idEntity *other, trace_t *trace ); - - - idRenderModelLiquid *model; -}; -#endif - -/* -=============================================================================== - - idShaking - -=============================================================================== -*/ - -class idShaking : public idEntity { -public: - CLASS_PROTOTYPE( idShaking ); - - idShaking(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - idPhysics_Parametric physicsObj; - bool active; - - void BeginShaking( void ); - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - - idEarthQuake - -=============================================================================== -*/ - -class idEarthQuake : public idEntity { -public: - CLASS_PROTOTYPE( idEarthQuake ); - - idEarthQuake(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - -private: - int nextTriggerTime; - int shakeStopTime; - float wait; - float random; - bool triggered; - bool playerOriented; - bool disabled; - float shakeTime; - - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - - idFuncPortal - -=============================================================================== -*/ - -class idFuncPortal : public idEntity { -public: - CLASS_PROTOTYPE( idFuncPortal ); - - idFuncPortal(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - void Think( void ); - -private: - qhandle_t portal; - bool state; - - /** - * Set to true if the portal state depends on distance from player - **/ - bool m_bDistDependent; - - /** - * Timestamp and interval between checks, in milliseconds - **/ - int m_TimeStamp; - int m_Interval; - /** - * Distance at which the portal shuts off, if it is distance dependent - **/ - float m_Distance; - - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - - idFuncAASPortal - -=============================================================================== -*/ - -class idFuncAASPortal : public idEntity { -public: - CLASS_PROTOTYPE( idFuncAASPortal ); - - idFuncAASPortal(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - bool state; - - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - - idFuncAASObstacle - -=============================================================================== -*/ - -class idFuncAASObstacle : public idEntity { -public: - CLASS_PROTOTYPE( idFuncAASObstacle ); - - idFuncAASObstacle(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // greebo: Public function to set the state directly - // Note: Passing TRUE means that the AAS area is DISABLED - void SetAASState(bool newState); - -private: - bool state; - - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - - idPhantomObjects - -=============================================================================== -*/ - -class idPhantomObjects : public idEntity { -public: - CLASS_PROTOTYPE( idPhantomObjects ); - - idPhantomObjects(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - -private: - void Event_Activate( idEntity *activator ); - void Event_Throw( void ); - void Event_ShakeObject( idEntity *object, int starttime ); - - int end_time; - float throw_time; - float shake_time; - idVec3 shake_ang; - float speed; - int min_wait; - int max_wait; - idEntityPtrtarget; - idList targetTime; - idList lastTargetPos; -}; - -/* -=============================================================================== - -idPortalSky - -=============================================================================== -*/ - -class idPortalSky : public idEntity { - -public: - - CLASS_PROTOTYPE( idPortalSky ); - - idPortalSky(); - - virtual ~idPortalSky(); - - void Spawn( void ); - void Event_PostSpawn(); - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - - CVine - -=============================================================================== -*/ - -class tdmVine: public idStaticEntity -{ -public: - CLASS_PROTOTYPE( tdmVine); - // Constructor - tdmVine(); - - // Needed on game save/load - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // Gets called when this entity is actually being spawned - void Spawn(); - -private: - bool _watered; // true if a vine piece was watered during this watering event - tdmVine* _prime; // initial, or prime, vine piece - idList< idEntityPtr >_descendants; // a list of all descendants (kept by prime only) - -protected: - void Event_SetPrime( tdmVine* newPrime ); - void Event_GetPrime(); - void Event_AddDescendant( tdmVine* descendant ); - void Event_ClearWatered(); - void Event_SetWatered(); - void Event_CanWater(); - void Event_ScaleVine(float factor); -}; - - -#endif /* !__GAME_MISC_H__ */ - diff --git a/game/moveable.cpp b/game/moveable.cpp deleted file mode 100644 index 8560ea3d8..000000000 --- a/game/moveable.cpp +++ /dev/null @@ -1,1518 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -/* -=============================================================================== - - idMoveable - -=============================================================================== -*/ - -const idEventDef EV_BecomeNonSolid( "becomeNonSolid" ); -const idEventDef EV_SetOwnerFromSpawnArgs( "" ); -const idEventDef EV_IsAtRest( "isAtRest", NULL, 'd' ); -const idEventDef EV_EnableDamage( "enableDamage", "f" ); - -CLASS_DECLARATION( idEntity, idMoveable ) - EVENT( EV_Activate, idMoveable::Event_Activate ) - EVENT( EV_BecomeNonSolid, idMoveable::Event_BecomeNonSolid ) - EVENT( EV_SetOwnerFromSpawnArgs, idMoveable::Event_SetOwnerFromSpawnArgs ) - EVENT( EV_IsAtRest, idMoveable::Event_IsAtRest ) - EVENT( EV_EnableDamage, idMoveable::Event_EnableDamage ) -END_CLASS - - -static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f; -static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f; -static const float SLIDING_VELOCITY_THRESHOLD = 5.0f; - -/* -================ -idMoveable::idMoveable -================ -*/ -idMoveable::idMoveable( void ) { - minDamageVelocity = 100.0f; - maxDamageVelocity = 200.0f; - nextCollideFxTime = 0; - nextDamageTime = 0; - nextSoundTime = 0; - m_nextCollideScriptTime = 0; - // 0 => never, -1 => always, positive number X => X times - m_collideScriptCounter = 0; - m_minScriptVelocity = 0.0f; - initialSpline = NULL; - initialSplineDir = vec3_zero; - explode = false; - unbindOnDeath = false; - allowStep = false; - canDamage = false; - - // greebo: A fraction of -1 is considered to be an invalid trace here - memset(&lastCollision, 0, sizeof(lastCollision)); - lastCollision.fraction = -1; - - isPushed = false; - wasPushedLastFrame = false; - pushDirection = vec3_zero; - lastPushOrigin = vec3_zero; - - // by default no LOD - m_LODHandle = 0; - m_DistCheckTimeStamp = 0; -} - -/* -================ -idMoveable::~idMoveable -================ -*/ -idMoveable::~idMoveable( void ) { - delete initialSpline; - initialSpline = NULL; -} - -/* -================ -idMoveable::Spawn -================ -*/ -void idMoveable::Spawn( void ) { - idTraceModel trm; - float density, friction, bouncyness, mass, air_friction_linear, air_friction_angular; - int clipShrink; - idStr clipModelName; - idVec3 maxForce, maxTorque; - - // check if a clip model is set - spawnArgs.GetString( "clipmodel", "", clipModelName ); - if ( !clipModelName[0] ) { - clipModelName = spawnArgs.GetString( "model" ); // use the visual model - } - - // tels: support "model" "" with "noclipmodel" "0" - do not attempt to load - // the clipmodel from the non-existing model name in this case: - if (clipModelName.Length()) { - if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { - gameLocal.Error( "idMoveable '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() ); - return; - } - - // angua: check if the cm is valid - if (idMath::Fabs(trm.bounds[0].x) == idMath::INFINITY) - { - gameLocal.Error( "idMoveable '%s': invalid collision model %s", name.c_str(), clipModelName.c_str() ); - } - - // if the model should be shrunk - clipShrink = spawnArgs.GetInt( "clipshrink" ); - if ( clipShrink != 0 ) { - trm.Shrink( clipShrink * CM_CLIP_EPSILON ); - } - } - - // get rigid body properties - spawnArgs.GetFloat( "density", "0.5", density ); - density = idMath::ClampFloat( 0.001f, 1000.0f, density ); - spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness ); - bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); - explode = spawnArgs.GetBool( "explode" ); - unbindOnDeath = spawnArgs.GetBool( "unbindondeath" ); - - spawnArgs.GetFloat( "friction", "0.05", friction ); - // reverse compatibility, new contact_friction key replaces friction only if present - if( spawnArgs.FindKey("contact_friction") ) - { - spawnArgs.GetFloat( "contact_friction", "0.05", friction ); - } - spawnArgs.GetFloat( "linear_friction", "0.6", air_friction_linear ); - spawnArgs.GetFloat( "angular_friction", "0.6", air_friction_angular ); - - fxCollide = spawnArgs.GetString( "fx_collide" ); - nextCollideFxTime = 0; - - // tels: - m_scriptCollide = spawnArgs.GetString( "script_collide" ); - m_nextCollideScriptTime = 0; - m_collideScriptCounter = spawnArgs.GetInt( "collide_script_counter", "1" ); - // override the default of 1 with 0 if no script is defined - if (m_scriptCollide == "") - { - m_collideScriptCounter = 0; - } - m_minScriptVelocity = spawnArgs.GetFloat( "min_script_velocity", "5.0" ); - - damage = spawnArgs.GetString( "def_damage", "" ); - canDamage = spawnArgs.GetBool( "damageWhenActive" ) ? false : true; - minDamageVelocity = spawnArgs.GetFloat( "minDamageVelocity", "100" ); - maxDamageVelocity = spawnArgs.GetFloat( "maxDamageVelocity", "200" ); - nextDamageTime = 0; - nextSoundTime = 0; - - health = spawnArgs.GetInt( "health", "0" ); - - // tels: load a visual model, as well as an optional brokenModel - LoadModels(); - - // setup the physics - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( trm ), density ); - physicsObj.GetClipModel()->SetMaterial( GetRenderModelMaterial() ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetBouncyness( bouncyness ); - physicsObj.SetFriction( air_friction_linear, air_friction_angular, friction ); - physicsObj.SetGravity( gameLocal.GetGravity() ); - - int contents = CONTENTS_SOLID | CONTENTS_OPAQUE; - // ishtvan: overwrite with custom contents, if present - if( m_CustomContents != -1 ) - contents = m_CustomContents; - - // greebo: Set the frobable contents flag if the spawnarg says so - if (spawnArgs.GetBool("frobable", "0")) - { - contents |= CONTENTS_FROBABLE; - } - - physicsObj.SetContents( contents ); - - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); - SetPhysics( &physicsObj ); - - if ( spawnArgs.GetFloat( "mass", "10", mass ) ) { - physicsObj.SetMass( mass ); - } - - // tels - if ( spawnArgs.GetVector( "max_force", "", maxForce ) ) { - physicsObj.SetMaxForce( maxForce ); - } - if ( spawnArgs.GetVector( "max_torque", "", maxTorque ) ) { - physicsObj.SetMaxTorque( maxTorque ); - } - - if ( spawnArgs.GetBool( "nodrop" ) ) { - physicsObj.PutToRest(); - } else { - physicsObj.DropToFloor(); - } - - if ( spawnArgs.GetBool( "noimpact" ) || spawnArgs.GetBool( "notpushable" ) ) { - physicsObj.DisableImpact(); - } - - if (!spawnArgs.GetBool( "solid" ) ) { - BecomeNonSolid(); - } - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - { - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - } - - m_preHideContents = physicsObj.GetContents(); - m_preHideClipMask = physicsObj.GetClipMask(); - - allowStep = spawnArgs.GetBool( "allowStep", "1" ); - - // parse LOD spawnargs - if (ParseLODSpawnargs( &spawnArgs, gameLocal.random.RandomFloat() ) ) - { - // Have to start thinking if we're distance dependent - BecomeActive( TH_THINK ); - } - - // grayman #2820 - don't queue EV_SetOwnerFromSpawnArgs if it's going to - // end up doing nothing. Queuing this for every moveable causes a lot - // of event posting during frame 0. If extra work is added to - // EV_SetOwnerFromSpawnArgs, then that must be accounted for here, to - // make sure it has a chance of getting done. - - idStr owner; - if ( spawnArgs.GetString( "owner", "", owner ) ) - { - PostEventMS( &EV_SetOwnerFromSpawnArgs, 0 ); - } -} - -/* -================ -idMoveable::Save -================ -*/ -void idMoveable::Save( idSaveGame *savefile ) const { - - savefile->WriteString( brokenModel ); - savefile->WriteString( damage ); - savefile->WriteString( m_scriptCollide ); - savefile->WriteInt( m_collideScriptCounter ); - savefile->WriteInt( m_nextCollideScriptTime ); - savefile->WriteFloat( m_minScriptVelocity ); - savefile->WriteString( fxCollide ); - savefile->WriteInt( nextCollideFxTime ); - savefile->WriteFloat( minDamageVelocity ); - savefile->WriteFloat( maxDamageVelocity ); - savefile->WriteBool( explode ); - savefile->WriteBool( unbindOnDeath ); - savefile->WriteBool( allowStep ); - savefile->WriteBool( canDamage ); - savefile->WriteInt( nextDamageTime ); - savefile->WriteInt( nextSoundTime ); - savefile->WriteInt( initialSpline != NULL ? (int)initialSpline->GetTime( 0 ) : -1 ); - savefile->WriteVec3( initialSplineDir ); - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteTrace(lastCollision); - savefile->WriteBool(isPushed); - savefile->WriteBool(wasPushedLastFrame); - savefile->WriteVec3(pushDirection); - savefile->WriteVec3(lastPushOrigin); -} - -/* -================ -idMoveable::Restore -================ -*/ -void idMoveable::Restore( idRestoreGame *savefile ) { - int initialSplineTime; - - savefile->ReadString( brokenModel ); - savefile->ReadString( damage ); - savefile->ReadString( m_scriptCollide ); - savefile->ReadInt( m_collideScriptCounter ); - savefile->ReadInt( m_nextCollideScriptTime ); - savefile->ReadFloat( m_minScriptVelocity ); - savefile->ReadString( fxCollide ); - savefile->ReadInt( nextCollideFxTime ); - savefile->ReadFloat( minDamageVelocity ); - savefile->ReadFloat( maxDamageVelocity ); - savefile->ReadBool( explode ); - savefile->ReadBool( unbindOnDeath ); - savefile->ReadBool( allowStep ); - savefile->ReadBool( canDamage ); - savefile->ReadInt( nextDamageTime ); - savefile->ReadInt( nextSoundTime ); - savefile->ReadInt( initialSplineTime ); - savefile->ReadVec3( initialSplineDir ); - - if ( initialSplineTime != -1 ) { - InitInitialSpline( initialSplineTime ); - } else { - initialSpline = NULL; - } - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadTrace(lastCollision); - savefile->ReadBool(isPushed); - savefile->ReadBool(wasPushedLastFrame); - savefile->ReadVec3(pushDirection); - savefile->ReadVec3(lastPushOrigin); -} - -/* -================ -idMoveable::Hide -================ -*/ -void idMoveable::Hide( void ) { - idEntity::Hide(); - physicsObj.SetContents( 0 ); -} - -/* -================ -idMoveable::Show -================ -*/ -void idMoveable::Show( void ) -{ - idEntity::Show(); - physicsObj.SetContents( m_preHideContents ); -} - -/* -================= -idMoveable::Collide -================= -*/ - -bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) -{ - // greebo: Check whether we are colliding with the nearly exact same point again - bool sameCollisionAgain = (lastCollision.fraction != -1 && lastCollision.c.point.Compare(collision.c.point, 0.05f)); - - // greebo: Save the collision info for the next call - lastCollision = collision; - - float v = -( velocity * collision.c.normal ); - - if ( !sameCollisionAgain ) - { - float bounceSoundMinVelocity = cv_bounce_sound_min_vel.GetFloat(); - float bounceSoundMaxVelocity = cv_bounce_sound_max_vel.GetFloat(); - - if ( v > bounceSoundMinVelocity && gameLocal.time > nextSoundTime ) - { - const idMaterial *material = collision.c.material; - - idStr sndNameLocal; - idStr surfaceName; // "tile", "glass", etc. - - if (material != NULL) - { - surfaceName = g_Global.GetSurfName(material); - - // Prepend the snd_bounce_ prefix to check for a surface-specific sound - idStr sndNameWithSurface = "snd_bounce_" + surfaceName; - - if (spawnArgs.FindKey(sndNameWithSurface) != NULL) - { - sndNameLocal = sndNameWithSurface; - } - else - { - sndNameLocal = "snd_bounce"; - } - } - - const char* sound = spawnArgs.GetString(sndNameLocal); - const idSoundShader* sndShader = declManager->FindSound(sound); - - //f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ); - - // angua: modify the volume set in the def instead of setting a fixed value. - // At minimum velocity, the volume should be "min_velocity_volume_decrease" lower (in db) than the one specified in the def - float f = v > bounceSoundMaxVelocity ? 0.0f : spawnArgs.GetFloat("min_velocity_volume_decrease", "0") * ( idMath::Sqrt(v - bounceSoundMinVelocity) * (1.0f / idMath::Sqrt( bounceSoundMaxVelocity - bounceSoundMinVelocity)) - 1 ); - - float volume = sndShader->GetParms()->volume + f; - - if (cv_moveable_collision.GetBool()) - { - gameRenderWorld->DrawText( va("Velocity: %f", v), (physicsObj.GetOrigin() + idVec3(0, 0, 20)), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); - gameRenderWorld->DrawText( va("Volume: %f", volume), (physicsObj.GetOrigin() + idVec3(0, 0, 10)), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec ); - gameRenderWorld->DebugArrow( colorMagenta, collision.c.point, (collision.c.point + 30 * collision.c.normal), 4.0f, 1); - } - - SetSoundVolume(volume); - - // greebo: We don't use StartSound() here, we want to do the sound propagation call manually - StartSoundShader(sndShader, SND_CHANNEL_ANY, 0, false, NULL); - - // grayman #2603 - don't propagate a sound if this is a doused torch dropped by an AI - - if (!spawnArgs.GetBool("is_torch","0")) - { - idStr sndPropName = GetSoundPropNameForMaterial(surfaceName); - - // Propagate a suspicious sound, using the "group" convention (soft, hard, small, med, etc.) - PropSoundS( NULL, sndPropName, f ); - } - - SetSoundVolume(0.0f); - - nextSoundTime = gameLocal.time + 500; - } - - // tels: - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Moveable %s might call script_collide %s because m_collideScriptCounter=%i and v=%f and time=%f > m_nextCollideScriptTime=%f.\r", - name.c_str(), m_scriptCollide.c_str(), m_collideScriptCounter, v, gameLocal.time, m_nextCollideScriptTime ); - if ( m_collideScriptCounter != 0 && v > m_minScriptVelocity && gameLocal.time > m_nextCollideScriptTime ) - { - if ( m_collideScriptCounter > 0) - { - // if positive, decrement it, so -1 stays as it is (for 0, we never come here) - m_collideScriptCounter --; - } - - // call the script - const function_t* pScriptFun = scriptObject.GetFunction( m_scriptCollide.c_str() ); - if (pScriptFun == NULL) - { - // Local function not found, check in global namespace - pScriptFun = gameLocal.program.FindFunction( m_scriptCollide.c_str() ); - } - if (pScriptFun != NULL) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Moveable %s calling script_collide %s.\r", - name.c_str(), m_scriptCollide.c_str()); - idThread *pThread = new idThread( pScriptFun ); - pThread->CallFunctionArgs( pScriptFun, true, "e", this ); - pThread->DelayedStart( 0 ); - } - else - { - // script function not found! - DM_LOG(LC_ENTITY, LT_ERROR)LOGSTRING("Moveable %s could not find script_collide %s.\r", - name.c_str(), m_scriptCollide.c_str()); - m_collideScriptCounter = 0; - } - - m_nextCollideScriptTime = gameLocal.time + 300; - } - - } - - idEntity* ent = gameLocal.entities[ collision.c.entityNum ]; - - if ( canDamage && damage.Length() && gameLocal.time > nextDamageTime ) - { - if ( ent && v > minDamageVelocity ) - { - float f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( v - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) ); - idVec3 dir = velocity; - dir.NormalizeFast(); - ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, CLIPMODEL_ID_TO_JOINT_HANDLE(collision.c.id), const_cast(&collision) ); - nextDamageTime = gameLocal.time + 1000; - } - } - - // Darkmod: Collision stims and a tactile alert if it collides with an AI - if ( ent ) - { - ProcCollisionStims( ent, collision.c.id ); - - if( ent->IsType( idAI::Type ) ) - { - idAI *alertee = static_cast(ent); - alertee->TactileAlert( this ); - } - } - - if ( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) { - idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false ); - nextCollideFxTime = gameLocal.time + 3500; - } - - return false; -} - -idStr idMoveable::GetSoundPropNameForMaterial(const idStr& materialName) -{ - // Object type defaults to "medium" and "hard" - return idStr("bounce_") + spawnArgs.GetString("spr_object_size", "medium") + - "_" + spawnArgs.GetString("spr_object_hardness", "hard") + - "_on_" + g_Global.GetSurfaceHardness(materialName); -} - -/* -============ -idMoveable::Killed -============ -*/ -void idMoveable::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) -{ - bool bPlayerResponsible(false); - - if ( unbindOnDeath ) { - Unbind(); - } - - // tels: call base class method to switch to broken model - idEntity::BecomeBroken( inflictor ); - - if ( explode ) { - if ( brokenModel == "" ) { - PostEventMS( &EV_Remove, 1000 ); - } - } - - if ( renderEntity.gui[ 0 ] ) { - renderEntity.gui[ 0 ] = NULL; - } - - ActivateTargets( this ); - - fl.takedamage = false; - - if ( attacker && attacker->IsType( idPlayer::Type ) ) - bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); - else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) - bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); - - gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); -} - -/* -================ -idMoveable::AllowStep -================ -*/ -bool idMoveable::AllowStep( void ) const { - return allowStep; -} - -/* -================ -idMoveable::BecomeNonSolid -================ -*/ -void idMoveable::BecomeNonSolid( void ) { - // set CONTENTS_RENDERMODEL so bullets still collide with the moveable - physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_RENDERMODEL ); - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); - - // SR CONTENTS_RESPONSE FIX: - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); -} - -/* -================ -idMoveable::EnableDamage -================ -*/ -void idMoveable::EnableDamage( bool enable, float duration ) { - canDamage = enable; - if ( duration ) { - PostEventSec( &EV_EnableDamage, duration, ( !enable ) ? 0.0f : 1.0f ); - } -} - -/* -================ -idMoveable::InitInitialSpline -================ -*/ -void idMoveable::InitInitialSpline( int startTime ) { - int initialSplineTime; - - initialSpline = GetSpline(); - initialSplineTime = spawnArgs.GetInt( "initialSplineTime", "300" ); - - if ( initialSpline != NULL ) { - initialSpline->MakeUniform( initialSplineTime ); - initialSpline->ShiftTime( startTime - initialSpline->GetTime( 0 ) ); - initialSplineDir = initialSpline->GetCurrentFirstDerivative( startTime ); - initialSplineDir *= physicsObj.GetAxis().Transpose(); - initialSplineDir.Normalize(); - BecomeActive( TH_THINK ); - } -} - -/* -================ -idMoveable::FollowInitialSplinePath -================ -*/ -bool idMoveable::FollowInitialSplinePath( void ) { - if ( initialSpline != NULL ) { - if ( gameLocal.time < initialSpline->GetTime( initialSpline->GetNumValues() - 1 ) ) { - idVec3 splinePos = initialSpline->GetCurrentValue( gameLocal.time ); - idVec3 linearVelocity = ( splinePos - physicsObj.GetOrigin() ) * USERCMD_HZ; - physicsObj.SetLinearVelocity( linearVelocity ); - - idVec3 splineDir = initialSpline->GetCurrentFirstDerivative( gameLocal.time ); - idVec3 dir = initialSplineDir * physicsObj.GetAxis(); - idVec3 angularVelocity = dir.Cross( splineDir ); - angularVelocity.Normalize(); - angularVelocity *= idMath::ACos16( dir * splineDir / splineDir.Length() ) * USERCMD_HZ; - physicsObj.SetAngularVelocity( angularVelocity ); - return true; - } else { - delete initialSpline; - initialSpline = NULL; - } - } - return false; -} - -/* -================ -idMoveable::Think -================ -*/ -void idMoveable::Think( void ) { - if ( thinkFlags & TH_THINK ) { - if ( !FollowInitialSplinePath() && !isPushed && !m_LODHandle) { - BecomeInactive( TH_THINK ); - } - } - - // will also handle LOD thinking - idEntity::Think(); - - UpdateSlidingSounds(); -} - -/* -================ -idMoveable::GetRenderModelMaterial -================ -*/ -const idMaterial *idMoveable::GetRenderModelMaterial( void ) const { - if ( renderEntity.customShader ) { - return renderEntity.customShader; - } - if ( renderEntity.hModel && renderEntity.hModel->NumSurfaces() ) { - return renderEntity.hModel->Surface( 0 )->shader; - } - return NULL; -} - -/* -================ -idMoveable::WriteToSnapshot -================ -*/ -void idMoveable::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); -} - -/* -================ -idMoveable::ReadFromSnapshot -================ -*/ -void idMoveable::ReadFromSnapshot( const idBitMsgDelta &msg ) { - physicsObj.ReadFromSnapshot( msg ); - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - -void idMoveable::SetIsPushed(bool isNowPushed, const idVec3& pushDirection) -{ - isPushed = isNowPushed; - this->pushDirection = pushDirection; - lastPushOrigin = GetPhysics()->GetOrigin(); - - // Update our think flags to allow UpdateMoveables to be called. - if (isPushed) - { - BecomeActive(TH_THINK); - } -} - -bool idMoveable::IsPushed() -{ - return isPushed; -} - -void idMoveable::UpdateSlidingSounds() -{ - if (isPushed) - { - const idVec3& curVelocity = GetPhysics()->GetLinearVelocity(); - const idVec3& gravityNorm = GetPhysics()->GetGravityNormal(); - - idVec3 xyVelocity = curVelocity - (curVelocity * gravityNorm) * gravityNorm; - - // Only consider the xyspeed if the velocity is in pointing in the same direction as we're being pushed - float xySpeed = (idMath::Fabs(xyVelocity * pushDirection) > 0.2f) ? xyVelocity.NormalizeFast() : 0; - - //gameRenderWorld->DrawText( idStr(xySpeed), GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - //gameRenderWorld->DebugArrow(colorWhite, GetPhysics()->GetAbsBounds().GetCenter(), GetPhysics()->GetAbsBounds().GetCenter() + xyVelocity, 1, gameLocal.msec ); - - if (wasPushedLastFrame && xySpeed <= SLIDING_VELOCITY_THRESHOLD) - { - // We are still being pushed, but we are not fast enough - StopSound(SND_CHANNEL_BODY3, false); - BecomeInactive(TH_THINK); - - isPushed = false; - wasPushedLastFrame = false; - } - else if (!wasPushedLastFrame && xySpeed > SLIDING_VELOCITY_THRESHOLD) - { - if (lastPushOrigin.Compare(GetPhysics()->GetOrigin(), 0.05f)) - { - // We did not really move, despite what the velocity says - StopSound(SND_CHANNEL_BODY3, false); - BecomeInactive(TH_THINK); - isPushed = false; - } - else - { - // We just got into pushed state and are fast enough - StartSound("snd_sliding", SND_CHANNEL_BODY3, 0, false, NULL); - - // Update the state flag for the next round - wasPushedLastFrame = true; - } - } - - lastPushOrigin = GetPhysics()->GetOrigin(); - } - else if (wasPushedLastFrame) - { - // We are not pushed anymore - StopSound(SND_CHANNEL_BODY3, false); - BecomeInactive(TH_THINK); - - // Update the state flag for the next round - wasPushedLastFrame = false; - } -} - -/* -================ -idMoveable::Event_BecomeNonSolid -================ -*/ -void idMoveable::Event_BecomeNonSolid( void ) { - BecomeNonSolid(); -} - -/* -================ -idMoveable::Event_Activate -================ -*/ -void idMoveable::Event_Activate( idEntity *activator ) { - float delay; - idVec3 init_velocity, init_avelocity; - - Show(); - - if ( !spawnArgs.GetInt( "notpushable" ) ) { - physicsObj.EnableImpact(); - } - - physicsObj.Activate(); - - spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity ); - spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity ); - - delay = spawnArgs.GetFloat( "init_velocityDelay", "0" ); - if ( delay == 0.0f ) { - physicsObj.SetLinearVelocity( init_velocity ); - } else { - PostEventSec( &EV_SetLinearVelocity, delay, init_velocity ); - } - - delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" ); - if ( delay == 0.0f ) { - physicsObj.SetAngularVelocity( init_avelocity ); - } else { - PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity ); - } - - InitInitialSpline( gameLocal.time ); -} - -/* -================ -idMoveable::Event_SetOwnerFromSpawnArgs -================ -*/ -void idMoveable::Event_SetOwnerFromSpawnArgs( void ) -{ - // grayman #2820 - At the time of this writing, this routine ONLY checks - // whether this moveable has its 'owner' spawnarg set. If anything else is - // added here, the pre-check in moveable.cpp that wraps around "PostEventMS( &EV_SetOwnerFromSpawnArgs, 0 )" - // must account for that. That pre-check is needed to prevent unnecessary - // event posting that leads to doing nothing here. (I.e. the moveable has no owner.) - - idStr owner; - if ( spawnArgs.GetString( "owner", "", owner ) ) - { - ProcessEvent( &EV_SetOwner, gameLocal.FindEntity( owner ) ); - } -} - -/* -================ -idMoveable::Event_IsAtRest -================ -*/ -void idMoveable::Event_IsAtRest( void ) { - idThread::ReturnInt( physicsObj.IsAtRest() ); -} - -/* -================ -idMoveable::Event_EnableDamage -================ -*/ -void idMoveable::Event_EnableDamage( float enable ) { - canDamage = ( enable != 0.0f ); -} - - -/* -=============================================================================== - - idBarrel - -=============================================================================== -*/ - -CLASS_DECLARATION( idMoveable, idBarrel ) -END_CLASS - -/* -================ -idBarrel::idBarrel -================ -*/ -idBarrel::idBarrel() { - radius = 1.0f; - barrelAxis = 0; - lastOrigin.Zero(); - lastAxis.Identity(); - additionalRotation = 0.0f; - additionalAxis.Identity(); - fl.networkSync = true; -} - -/* -================ -idBarrel::Save -================ -*/ -void idBarrel::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( radius ); - savefile->WriteInt( barrelAxis ); - savefile->WriteVec3( lastOrigin ); - savefile->WriteMat3( lastAxis ); - savefile->WriteFloat( additionalRotation ); - savefile->WriteMat3( additionalAxis ); -} - -/* -================ -idBarrel::Restore -================ -*/ -void idBarrel::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( radius ); - savefile->ReadInt( barrelAxis ); - savefile->ReadVec3( lastOrigin ); - savefile->ReadMat3( lastAxis ); - savefile->ReadFloat( additionalRotation ); - savefile->ReadMat3( additionalAxis ); -} - -/* -================ -idBarrel::BarrelThink -================ -*/ -void idBarrel::BarrelThink( void ) { - bool wasAtRest, onGround; - float movedDistance, rotatedDistance, angle; - idVec3 curOrigin, gravityNormal, dir; - idMat3 curAxis, axis; - - wasAtRest = IsAtRest(); - - // run physics - RunPhysics(); - - // only need to give the visual model an additional rotation if the physics were run - if ( !wasAtRest ) { - - // current physics state - onGround = GetPhysics()->HasGroundContacts(); - curOrigin = GetPhysics()->GetOrigin(); - curAxis = GetPhysics()->GetAxis(); - - // if the barrel is on the ground - if ( onGround ) { - gravityNormal = GetPhysics()->GetGravityNormal(); - - dir = curOrigin - lastOrigin; - dir -= gravityNormal * dir * gravityNormal; - movedDistance = dir.LengthSqr(); - - // if the barrel moved and the barrel is not aligned with the gravity direction - if ( movedDistance > 0.0f && idMath::Fabs( gravityNormal * curAxis[barrelAxis] ) < 0.7f ) { - - // barrel movement since last think frame orthogonal to the barrel axis - movedDistance = idMath::Sqrt( movedDistance ); - dir *= 1.0f / movedDistance; - movedDistance = ( 1.0f - idMath::Fabs( dir * curAxis[barrelAxis] ) ) * movedDistance; - - // get rotation about barrel axis since last think frame - angle = lastAxis[(barrelAxis+1)%3] * curAxis[(barrelAxis+1)%3]; - angle = idMath::ACos( angle ); - // distance along cylinder hull - rotatedDistance = angle * radius; - - // if the barrel moved further than it rotated about it's axis - if ( movedDistance > rotatedDistance ) { - - // additional rotation of the visual model to make it look - // like the barrel rolls instead of slides - angle = 180.0f * (movedDistance - rotatedDistance) / (radius * idMath::PI); - if ( gravityNormal.Cross( curAxis[barrelAxis] ) * dir < 0.0f ) { - additionalRotation += angle; - } else { - additionalRotation -= angle; - } - dir = vec3_origin; - dir[barrelAxis] = 1.0f; - additionalAxis = idRotation( vec3_origin, dir, additionalRotation ).ToMat3(); - } - } - } - - // save state for next think - lastOrigin = curOrigin; - lastAxis = curAxis; - } - - Present(); -} - -/* -================ -idBarrel::Think -================ -*/ -void idBarrel::Think( void ) { - if ( thinkFlags & TH_THINK ) { - if ( !FollowInitialSplinePath() ) { - BecomeInactive( TH_THINK ); - } - } - - BarrelThink(); -} - -/* -================ -idBarrel::GetPhysicsToVisualTransform -================ -*/ -bool idBarrel::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { - origin = vec3_origin; - axis = additionalAxis; - return true; -} - -/* -================ -idBarrel::Spawn -================ -*/ -void idBarrel::Spawn( void ) { - const idBounds &bounds = GetPhysics()->GetBounds(); - - // radius of the barrel cylinder - radius = ( bounds[1][0] - bounds[0][0] ) * 0.5f; - - // always a vertical barrel with cylinder axis parallel to the z-axis - barrelAxis = 2; - - lastOrigin = GetPhysics()->GetOrigin(); - lastAxis = GetPhysics()->GetAxis(); - - additionalRotation = 0.0f; - additionalAxis.Identity(); -} - -/* -================ -idBarrel::ClientPredictionThink -================ -*/ -void idBarrel::ClientPredictionThink( void ) { - Think(); -} - - -/* -=============================================================================== - -idExplodingBarrel - -=============================================================================== -*/ -const idEventDef EV_Respawn( "" ); -const idEventDef EV_TriggerTargets( "" ); - -CLASS_DECLARATION( idBarrel, idExplodingBarrel ) - EVENT( EV_Activate, idExplodingBarrel::Event_Activate ) - EVENT( EV_Respawn, idExplodingBarrel::Event_Respawn ) - EVENT( EV_Explode, idExplodingBarrel::Event_Explode ) - EVENT( EV_TriggerTargets, idExplodingBarrel::Event_TriggerTargets ) -END_CLASS - -/* -================ -idExplodingBarrel::idExplodingBarrel -================ -*/ -idExplodingBarrel::idExplodingBarrel() { - spawnOrigin.Zero(); - spawnAxis.Zero(); - state = NORMAL; - particleModelDefHandle = -1; - lightDefHandle = -1; - memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) ); - memset( &light, 0, sizeof( light ) ); - particleTime = 0; - lightTime = 0; - time = 0.0f; -} - -/* -================ -idExplodingBarrel::~idExplodingBarrel -================ -*/ -idExplodingBarrel::~idExplodingBarrel() { - if ( particleModelDefHandle >= 0 ){ - gameRenderWorld->FreeEntityDef( particleModelDefHandle ); - } - if ( lightDefHandle >= 0 ) { - gameRenderWorld->FreeLightDef( lightDefHandle ); - } -} - -/* -================ -idExplodingBarrel::Save -================ -*/ -void idExplodingBarrel::Save( idSaveGame *savefile ) const { - savefile->WriteVec3( spawnOrigin ); - savefile->WriteMat3( spawnAxis ); - - savefile->WriteInt( state ); - savefile->WriteInt( particleModelDefHandle ); - savefile->WriteInt( lightDefHandle ); - - savefile->WriteRenderEntity( particleRenderEntity ); - savefile->WriteRenderLight( light ); - - savefile->WriteInt( particleTime ); - savefile->WriteInt( lightTime ); - savefile->WriteFloat( time ); -} - -/* -================ -idExplodingBarrel::Restore -================ -*/ -void idExplodingBarrel::Restore( idRestoreGame *savefile ) { - savefile->ReadVec3( spawnOrigin ); - savefile->ReadMat3( spawnAxis ); - - savefile->ReadInt( (int &)state ); - savefile->ReadInt( (int &)particleModelDefHandle ); - savefile->ReadInt( (int &)lightDefHandle ); - - savefile->ReadRenderEntity( particleRenderEntity ); - savefile->ReadRenderLight( light ); - - savefile->ReadInt( particleTime ); - savefile->ReadInt( lightTime ); - savefile->ReadFloat( time ); -} - -/* -================ -idExplodingBarrel::Spawn -================ -*/ -void idExplodingBarrel::Spawn( void ) { - health = spawnArgs.GetInt( "health", "5" ); - fl.takedamage = true; - spawnOrigin = GetPhysics()->GetOrigin(); - spawnAxis = GetPhysics()->GetAxis(); - state = NORMAL; - particleModelDefHandle = -1; - lightDefHandle = -1; - lightTime = 0; - particleTime = 0; - time = spawnArgs.GetFloat( "time" ); - memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) ); - memset( &light, 0, sizeof( light ) ); -} - -/* -================ -idExplodingBarrel::Think -================ -*/ -void idExplodingBarrel::Think( void ) { - idBarrel::BarrelThink(); - - if ( lightDefHandle >= 0 ){ - if ( state == BURNING ) { - // ramp the color up over 250 ms - float pct = (gameLocal.time - lightTime) / 250.f; - if ( pct > 1.0f ) { - pct = 1.0f; - } - light.origin = physicsObj.GetAbsBounds().GetCenter(); - light.axis = mat3_identity; - light.shaderParms[ SHADERPARM_RED ] = pct; - light.shaderParms[ SHADERPARM_GREEN ] = pct; - light.shaderParms[ SHADERPARM_BLUE ] = pct; - light.shaderParms[ SHADERPARM_ALPHA ] = pct; - gameRenderWorld->UpdateLightDef( lightDefHandle, &light ); - } else { - if ( gameLocal.time - lightTime > 250 ) { - gameRenderWorld->FreeLightDef( lightDefHandle ); - lightDefHandle = -1; - } - return; - } - } - - if ( !gameLocal.isClient && state != BURNING && state != EXPLODING ) { - BecomeInactive( TH_THINK ); - return; - } - - if ( particleModelDefHandle >= 0 ){ - particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter(); - particleRenderEntity.axis = mat3_identity; - gameRenderWorld->UpdateEntityDef( particleModelDefHandle, &particleRenderEntity ); - } -} - -/* -================ -idExplodingBarrel::AddParticles -================ -*/ -void idExplodingBarrel::AddParticles( const char *name, bool burn ) { - if ( name && *name ) { - if ( particleModelDefHandle >= 0 ){ - gameRenderWorld->FreeEntityDef( particleModelDefHandle ); - } - memset( &particleRenderEntity, 0, sizeof ( particleRenderEntity ) ); - const idDeclModelDef *modelDef = static_cast( declManager->FindType( DECL_MODELDEF, name ) ); - if ( modelDef ) { - particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter(); - particleRenderEntity.axis = mat3_identity; - particleRenderEntity.hModel = modelDef->ModelHandle(); - float rgb = ( burn ) ? 0.0f : 1.0f; - particleRenderEntity.shaderParms[ SHADERPARM_RED ] = rgb; - particleRenderEntity.shaderParms[ SHADERPARM_GREEN ] = rgb; - particleRenderEntity.shaderParms[ SHADERPARM_BLUE ] = rgb; - particleRenderEntity.shaderParms[ SHADERPARM_ALPHA ] = rgb; - particleRenderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.realClientTime ); - particleRenderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = ( burn ) ? 1.0f : gameLocal.random.RandomInt( 90 ); - if ( !particleRenderEntity.hModel ) { - particleRenderEntity.hModel = renderModelManager->FindModel( name ); - } - particleModelDefHandle = gameRenderWorld->AddEntityDef( &particleRenderEntity ); - if ( burn ) { - BecomeActive( TH_THINK ); - } - particleTime = gameLocal.realClientTime; - } - } -} - -/* -================ -idExplodingBarrel::AddLight -================ -*/ -void idExplodingBarrel::AddLight( const char *name, bool burn ) { - if ( lightDefHandle >= 0 ){ - gameRenderWorld->FreeLightDef( lightDefHandle ); - } - memset( &light, 0, sizeof ( light ) ); - light.axis = mat3_identity; - light.lightRadius.x = spawnArgs.GetFloat( "light_radius" ); - light.lightRadius.y = light.lightRadius.z = light.lightRadius.x; - light.origin = physicsObj.GetOrigin(); - light.origin.z += 128; - light.pointLight = true; - light.shader = declManager->FindMaterial( name ); - light.shaderParms[ SHADERPARM_RED ] = 2.0f; - light.shaderParms[ SHADERPARM_GREEN ] = 2.0f; - light.shaderParms[ SHADERPARM_BLUE ] = 2.0f; - light.shaderParms[ SHADERPARM_ALPHA ] = 2.0f; - lightDefHandle = gameRenderWorld->AddLightDef( &light ); - lightTime = gameLocal.realClientTime; - BecomeActive( TH_THINK ); -} - -/* -================ -idExplodingBarrel::ExplodingEffects -================ -*/ -void idExplodingBarrel::ExplodingEffects( void ) { - const char *temp; - - StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL ); - - temp = spawnArgs.GetString( "model_damage" ); - if ( *temp != '\0' ) { - SetModel( temp ); - Show(); - } - - temp = spawnArgs.GetString( "model_detonate" ); - if ( *temp != '\0' ) { - AddParticles( temp, false ); - } - - temp = spawnArgs.GetString( "mtr_lightexplode" ); - if ( *temp != '\0' ) { - AddLight( temp, false ); - } - - temp = spawnArgs.GetString( "mtr_burnmark" ); - if ( *temp != '\0' ) { - gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 128.0f, true, 96.0f, temp ); - } -} - -/* -================ -idExplodingBarrel::Killed -================ -*/ -void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - - if ( IsHidden() || state == EXPLODING || state == BURNING ) { - return; - } - - float f = spawnArgs.GetFloat( "burn" ); - if ( f > 0.0f && state == NORMAL ) { - state = BURNING; - PostEventSec( &EV_Explode, f ); - StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL ); - AddParticles( spawnArgs.GetString ( "model_burn", "" ), true ); - return; - } else { - state = EXPLODING; - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteLong( gameLocal.time ); - ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 ); - } - } - - // do this before applying radius damage so the ent can trace to any damagable ents nearby - Hide(); - physicsObj.SetContents( 0 ); - - const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" ); - if ( splash && *splash ) { - gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash ); - } - - ExplodingEffects( ); - - //FIXME: need to precache all the debris stuff here and in the projectiles - const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" ); - // bool first = true; - while ( kv ) { - const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false ); - if ( debris_args ) { - idEntity *ent; - idVec3 dir; - idDebris *debris; - //if ( first ) { - dir = physicsObj.GetAxis()[1]; - // first = false; - //} else { - dir.x += gameLocal.random.CRandomFloat() * 4.0f; - dir.y += gameLocal.random.CRandomFloat() * 4.0f; - //dir.z = gameLocal.random.RandomFloat() * 8.0f; - //} - dir.Normalize(); - - gameLocal.SpawnEntityDef( *debris_args, &ent, false ); - if ( !ent || !ent->IsType( idDebris::Type ) ) { - gameLocal.Error( "'projectile_debris' is not an idDebris" ); - } - - debris = static_cast(ent); - debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() ); - debris->Launch(); - debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f; - debris->UpdateVisuals(); - - } - kv = spawnArgs.MatchPrefix( "def_debris", kv ); - } - - physicsObj.PutToRest(); - CancelEvents( &EV_Explode ); - CancelEvents( &EV_Activate ); - - f = spawnArgs.GetFloat( "respawn" ); - if ( f > 0.0f ) { - PostEventSec( &EV_Respawn, f ); - } else { - PostEventMS( &EV_Remove, 5000 ); - } - - if ( spawnArgs.GetBool( "triggerTargets" ) ) { - ActivateTargets( this ); - } -} - -/* -================ -idExplodingBarrel::Damage -================ -*/ -void idExplodingBarrel::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, trace_t *tr ) -{ - - const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) { - gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); - } - if ( damageDef->FindKey( "radius" ) && GetPhysics()->GetContents() != 0 && GetBindMaster() == NULL ) { - PostEventMS( &EV_Explode, 400 ); - } else { - idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, tr ); - } -} - -/* -================ -idExplodingBarrel::Event_TriggerTargets -================ -*/ -void idExplodingBarrel::Event_TriggerTargets() { - ActivateTargets( this ); -} - -/* -================ -idExplodingBarrel::Event_Explode -================ -*/ -void idExplodingBarrel::Event_Explode() { - if ( state == NORMAL || state == BURNING ) { - state = BURNEXPIRED; - Killed( NULL, NULL, 0, vec3_zero, 0 ); - } -} - -/* -================ -idExplodingBarrel::Event_Respawn -================ -*/ -void idExplodingBarrel::Event_Respawn() { - int i; - int minRespawnDist = spawnArgs.GetInt( "respawn_range", "256" ); - if ( minRespawnDist ) { - float minDist = -1; - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { - continue; - } - idVec3 v = gameLocal.entities[ i ]->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - float dist = v.Length(); - if ( minDist < 0 || dist < minDist ) { - minDist = dist; - } - } - if ( minDist < minRespawnDist ) { - PostEventSec( &EV_Respawn, spawnArgs.GetInt( "respawn_again", "10" ) ); - return; - } - } - const char *temp = spawnArgs.GetString( "model" ); - if ( temp && *temp ) { - SetModel( temp ); - } - health = spawnArgs.GetInt( "health", "5" ); - fl.takedamage = true; - physicsObj.SetOrigin( spawnOrigin ); - physicsObj.SetAxis( spawnAxis ); - physicsObj.SetContents( CONTENTS_SOLID ); - // override with custom contents if present - if( m_CustomContents != -1 ) - physicsObj.SetContents( m_CustomContents ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - physicsObj.DropToFloor(); - state = NORMAL; - Show(); - UpdateVisuals(); -} - -/* -================ -idMoveable::Event_Activate -================ -*/ -void idExplodingBarrel::Event_Activate( idEntity *activator ) { - Killed( activator, activator, 0, vec3_origin, 0 ); -} - -/* -================ -idMoveable::WriteToSnapshot -================ -*/ -void idExplodingBarrel::WriteToSnapshot( idBitMsgDelta &msg ) const { - idMoveable::WriteToSnapshot( msg ); - msg.WriteBits( IsHidden(), 1 ); -} - -/* -================ -idMoveable::ReadFromSnapshot -================ -*/ -void idExplodingBarrel::ReadFromSnapshot( const idBitMsgDelta &msg ) { - - idMoveable::ReadFromSnapshot( msg ); - if ( msg.ReadBits( 1 ) ) { - Hide(); - } else { - Show(); - } -} - -/* -================ -idExplodingBarrel::ClientReceiveEvent -================ -*/ -bool idExplodingBarrel::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - - switch( event ) { - case EVENT_EXPLODE: { - if ( gameLocal.realClientTime - msg.ReadLong() < spawnArgs.GetInt( "explode_lapse", "1000" ) ) { - ExplodingEffects( ); - } - return true; - } - default: { - return idBarrel::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} diff --git a/game/moveable.h b/game/moveable.h deleted file mode 100644 index 6f958cc91..000000000 --- a/game/moveable.h +++ /dev/null @@ -1,211 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_MOVEABLE_H__ -#define __GAME_MOVEABLE_H__ - -/* -=============================================================================== - - Entity using rigid body physics. - -=============================================================================== -*/ - -extern const idEventDef EV_BecomeNonSolid; -extern const idEventDef EV_IsAtRest; - -class idMoveable : public idEntity { -public: - CLASS_PROTOTYPE( idMoveable ); - - idMoveable( void ); - virtual ~idMoveable( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - - virtual void Hide( void ); - virtual void Show( void ); - - bool AllowStep( void ) const; - void EnableDamage( bool enable, float duration ); - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - // Update the "pushed" state of this entity - virtual void SetIsPushed(bool isPushed, const idVec3& pushDirection); - - // Returns true if the entity is pushed by something or someone - virtual bool IsPushed(); - -protected: - idPhysics_RigidBody physicsObj; // physics object - idStr damage; // if > 0 apply damage to hit entities - idStr fxCollide; // fx system to start when collides with something - int nextCollideFxTime; // next time it is ok to spawn collision fx - - /** - * TDM Collision scripts - **/ - idStr m_scriptCollide; // script function to call when collides with something - int m_nextCollideScriptTime;// next time it is ok to call collision script - int m_collideScriptCounter; // how often to call the collision script - // 0 => never, -1 => always, +X => X times - float m_minScriptVelocity; // minimum velocity before calling collide script - - float minDamageVelocity; // minimum velocity before moveable applies damage - float maxDamageVelocity; // velocity at which the maximum damage is applied - idCurve_Spline *initialSpline; // initial spline path the moveable follows - idVec3 initialSplineDir; // initial relative direction along the spline path - bool explode; // entity explodes when health drops down to or below zero - bool unbindOnDeath; // unbind from master when health drops down to or below zero - bool allowStep; // allow monsters to step on the object - bool canDamage; // only apply damage when this is set - int nextDamageTime; // next time the movable can hurt the player - int nextSoundTime; // next time the moveable can make a sound - - // greebo: Stores the last collision info to avoid constant playing of the collision sound when stuck - trace_t lastCollision; - - bool isPushed; // true if the entity is pushed by something/someone - bool wasPushedLastFrame; // true if the entity was pushed the last frame - idVec3 pushDirection; // the direction the moveable is pushed in - idVec3 lastPushOrigin; // the old origin during pushing to compare whether we have actually moved somewhere - - const idMaterial * GetRenderModelMaterial( void ) const; - void BecomeNonSolid( void ); - void InitInitialSpline( int startTime ); - bool FollowInitialSplinePath( void ); - - // greebo: Returns the soundprop name for the given material (e.g. "sprS_bounce_small_hard_on_soft") - idStr GetSoundPropNameForMaterial(const idStr& materialName); - - // greebo: Updates the sliding sounds according to the "pushed" state - void UpdateSlidingSounds(); - - void Event_Activate( idEntity *activator ); - void Event_BecomeNonSolid( void ); - void Event_SetOwnerFromSpawnArgs( void ); - void Event_IsAtRest( void ); - void Event_EnableDamage( float enable ); -}; - - -/* -=============================================================================== - - A barrel using rigid body physics. The barrel has special handling of - the view model orientation to make it look like it rolls instead of slides. - -=============================================================================== -*/ - -class idBarrel : public idMoveable { - -public: - CLASS_PROTOTYPE( idBarrel ); - idBarrel(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void BarrelThink( void ); - virtual void Think( void ); - virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); - virtual void ClientPredictionThink( void ); - -private: - float radius; // radius of barrel - int barrelAxis; // one of the coordinate axes the barrel cylinder is parallel to - idVec3 lastOrigin; // origin of the barrel the last think frame - idMat3 lastAxis; // axis of the barrel the last think frame - float additionalRotation; // additional rotation of the barrel about it's axis - idMat3 additionalAxis; // additional rotation axis -}; - - -/* -=============================================================================== - - A barrel using rigid body physics and special handling of the view model - orientation to make it look like it rolls instead of slides. The barrel - can burn and explode when damaged. - -=============================================================================== -*/ - -class idExplodingBarrel : public idBarrel { -public: - CLASS_PROTOTYPE( idExplodingBarrel ); - - idExplodingBarrel(); - virtual ~idExplodingBarrel(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName,const float damageScale, - const int location, trace_t *tr = NULL ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - enum { - EVENT_EXPLODE = idEntity::EVENT_MAXEVENTS, - EVENT_MAXEVENTS - }; - -private: - typedef enum { - NORMAL = 0, - BURNING, - BURNEXPIRED, - EXPLODING - } explode_state_t; - explode_state_t state; - - idVec3 spawnOrigin; - idMat3 spawnAxis; - qhandle_t particleModelDefHandle; - qhandle_t lightDefHandle; - renderEntity_t particleRenderEntity; - renderLight_t light; - int particleTime; - int lightTime; - float time; - - void AddParticles( const char *name, bool burn ); - void AddLight( const char *name , bool burn ); - void ExplodingEffects( void ); - - void Event_Activate( idEntity *activator ); - void Event_Respawn(); - void Event_Explode(); - void Event_TriggerTargets(); -}; - -#endif /* !__GAME_MOVEABLE_H__ */ diff --git a/game/mover.cpp b/game/mover.cpp deleted file mode 100644 index e99bf647f..000000000 --- a/game/mover.cpp +++ /dev/null @@ -1,3365 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -// a mover will update any gui entities in its target list with -// a key/val pair of "mover" "state" from below.. guis can represent -// realtime info like this -// binary only -static const char *guiBinaryMoverStates[] = { - "1", // pos 1 - "2", // pos 2 - "3", // moving 1 to 2 - "4" // moving 2 to 1 -}; - - -/* -=============================================================================== - -idMover - -=============================================================================== -*/ - -const idEventDef EV_FindGuiTargets( "", NULL ); -const idEventDef EV_TeamBlocked( "", "ee" ); -const idEventDef EV_PartBlocked( "", "e" ); -const idEventDef EV_ReachedPos( "", NULL ); -const idEventDef EV_ReachedAng( "", NULL ); -const idEventDef EV_PostRestore( "", "ddddd" ); -const idEventDef EV_StopMoving( "stopMoving", NULL ); -const idEventDef EV_StopRotating( "stopRotating", NULL ); -const idEventDef EV_Speed( "speed", "f" ); -const idEventDef EV_Time( "time", "f" ); -const idEventDef EV_AccelTime( "accelTime", "f" ); -const idEventDef EV_DecelTime( "decelTime", "f" ); -const idEventDef EV_MoveTo( "moveTo", "e" ); -const idEventDef EV_MoveToPos( "moveToPos", "v" ); -const idEventDef EV_Move( "move", "ff" ); -const idEventDef EV_MoveAccelerateTo( "accelTo", "ff" ); -const idEventDef EV_MoveDecelerateTo( "decelTo", "ff" ); -const idEventDef EV_RotateDownTo( "rotateDownTo", "df" ); -const idEventDef EV_RotateUpTo( "rotateUpTo", "df" ); -const idEventDef EV_RotateTo( "rotateTo", "v" ); -const idEventDef EV_Rotate( "rotate", "v" ); -const idEventDef EV_RotateOnce( "rotateOnce", "v" ); -const idEventDef EV_Bob( "bob", "ffv" ); -const idEventDef EV_Sway( "sway", "ffv" ); -const idEventDef EV_Mover_OpenPortal( "openPortal" ); -const idEventDef EV_Mover_ClosePortal( "closePortal" ); -const idEventDef EV_AccelSound( "accelSound", "s" ); -const idEventDef EV_DecelSound( "decelSound", "s" ); -const idEventDef EV_MoveSound( "moveSound", "s" ); -const idEventDef EV_Mover_InitGuiTargets( "", NULL ); -const idEventDef EV_EnableSplineAngles( "enableSplineAngles", NULL ); -const idEventDef EV_DisableSplineAngles( "disableSplineAngles", NULL ); -const idEventDef EV_RemoveInitialSplineAngles( "removeInitialSplineAngles", NULL ); -const idEventDef EV_StartSpline( "startSpline", "e" ); -const idEventDef EV_StopSpline( "stopSpline", NULL ); -const idEventDef EV_IsMoving( "isMoving", NULL, 'd' ); -const idEventDef EV_IsRotating( "isRotating", NULL, 'd' ); - -CLASS_DECLARATION( idEntity, idMover ) - EVENT( EV_FindGuiTargets, idMover::Event_FindGuiTargets ) - EVENT( EV_Thread_SetCallback, idMover::Event_SetCallback ) - EVENT( EV_TeamBlocked, idMover::Event_TeamBlocked ) - EVENT( EV_PartBlocked, idMover::Event_PartBlocked ) - EVENT( EV_ReachedPos, idMover::Event_UpdateMove ) - EVENT( EV_ReachedAng, idMover::Event_UpdateRotation ) - EVENT( EV_PostRestore, idMover::Event_PostRestore ) - EVENT( EV_StopMoving, idMover::Event_StopMoving ) - EVENT( EV_StopRotating, idMover::Event_StopRotating ) - EVENT( EV_Speed, idMover::Event_SetMoveSpeed ) - EVENT( EV_Time, idMover::Event_SetMoveTime ) - EVENT( EV_AccelTime, idMover::Event_SetAccellerationTime ) - EVENT( EV_DecelTime, idMover::Event_SetDecelerationTime ) - EVENT( EV_MoveTo, idMover::Event_MoveTo ) - EVENT( EV_MoveToPos, idMover::Event_MoveToPos ) - EVENT( EV_Move, idMover::Event_MoveDir ) - EVENT( EV_MoveAccelerateTo, idMover::Event_MoveAccelerateTo ) - EVENT( EV_MoveDecelerateTo, idMover::Event_MoveDecelerateTo ) - EVENT( EV_RotateDownTo, idMover::Event_RotateDownTo ) - EVENT( EV_RotateUpTo, idMover::Event_RotateUpTo ) - EVENT( EV_RotateTo, idMover::Event_RotateTo ) - EVENT( EV_Rotate, idMover::Event_Rotate ) - EVENT( EV_RotateOnce, idMover::Event_RotateOnce ) - EVENT( EV_Bob, idMover::Event_Bob ) - EVENT( EV_Sway, idMover::Event_Sway ) - EVENT( EV_Mover_OpenPortal, idMover::Event_OpenPortal ) - EVENT( EV_Mover_ClosePortal, idMover::Event_ClosePortal ) - EVENT( EV_AccelSound, idMover::Event_SetAccelSound ) - EVENT( EV_DecelSound, idMover::Event_SetDecelSound ) - EVENT( EV_MoveSound, idMover::Event_SetMoveSound ) - EVENT( EV_Mover_InitGuiTargets, idMover::Event_InitGuiTargets ) - EVENT( EV_EnableSplineAngles, idMover::Event_EnableSplineAngles ) - EVENT( EV_DisableSplineAngles, idMover::Event_DisableSplineAngles ) - EVENT( EV_RemoveInitialSplineAngles, idMover::Event_RemoveInitialSplineAngles ) - EVENT( EV_StartSpline, idMover::Event_StartSpline ) - EVENT( EV_StopSpline, idMover::Event_StopSpline ) - EVENT( EV_Activate, idMover::Event_Activate ) - EVENT( EV_IsMoving, idMover::Event_IsMoving ) - EVENT( EV_IsRotating, idMover::Event_IsRotating ) -END_CLASS - -/* -================ -idMover::idMover -================ -*/ -idMover::idMover(void) -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); - - memset( &move, 0, sizeof( move ) ); - memset( &rot, 0, sizeof( rot ) ); - move_thread = 0; - rotate_thread = 0; - dest_angles.Zero(); - angle_delta.Zero(); - dest_position.Zero(); - move_delta.Zero(); - move_speed = 0.0f; - move_time = 0; - deceltime = 0; - acceltime = 0; - stopRotation = false; - useSplineAngles = true; - lastCommand = MOVER_NONE; - damage = 0.0f; - areaPortal = 0; - fl.networkSync = true; - m_FrobActionScript = "frob_mover"; -} - -/* -================ -idMover::Save -================ -*/ -void idMover::Save( idSaveGame *savefile ) const -{ - int i; - - savefile->WriteStaticObject( physicsObj ); - savefile->WriteInt( move.stage ); - savefile->WriteInt( move.acceleration ); - savefile->WriteInt( move.movetime ); - - savefile->WriteInt( move.deceleration ); - savefile->WriteVec3( move.dir ); - - savefile->WriteInt( rot.stage ); - savefile->WriteInt( rot.acceleration ); - savefile->WriteInt( rot.movetime ); - savefile->WriteInt( rot.deceleration ); - savefile->WriteAngles( rot.rot ); - - savefile->WriteInt( move_thread ); - savefile->WriteInt( rotate_thread ); - - savefile->WriteAngles( dest_angles ); - savefile->WriteAngles( angle_delta ); - savefile->WriteVec3( dest_position ); - savefile->WriteVec3( move_delta ); - - savefile->WriteFloat( move_speed ); - savefile->WriteInt( move_time ); - savefile->WriteInt( deceltime ); - savefile->WriteInt( acceltime ); - savefile->WriteBool( stopRotation ); - savefile->WriteBool( useSplineAngles ); - savefile->WriteInt( lastCommand ); - savefile->WriteFloat( damage ); - - savefile->WriteInt( areaPortal ); - if ( areaPortal > 0 ) { - savefile->WriteInt( gameRenderWorld->GetPortalState( areaPortal ) ); - } - - savefile->WriteInt( guiTargets.Num() ); - for( i = 0; i < guiTargets.Num(); i++ ) { - guiTargets[ i ].Save( savefile ); - } - - if ( splineEnt.GetEntity() && splineEnt.GetEntity()->GetSpline() ) { - idCurve_Spline *spline = physicsObj.GetSpline(); - - savefile->WriteBool( true ); - splineEnt.Save( savefile ); - savefile->WriteInt( static_cast(spline->GetTime( 0 )) ); - savefile->WriteInt( static_cast(spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 )) ); - savefile->WriteInt( physicsObj.GetSplineAcceleration() ); - savefile->WriteInt( physicsObj.GetSplineDeceleration() ); - savefile->WriteInt( (int)physicsObj.UsingSplineAngles() ); - - } else { - savefile->WriteBool( false ); - } -} - -/* -================ -idMover::Restore -================ -*/ -void idMover::Restore( idRestoreGame *savefile ) { - int i, num; - bool hasSpline = false; - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadInt( (int&)move.stage ); - savefile->ReadInt( move.acceleration ); - savefile->ReadInt( move.movetime ); - savefile->ReadInt( move.deceleration ); - savefile->ReadVec3( move.dir ); - - savefile->ReadInt( (int&)rot.stage ); - savefile->ReadInt( rot.acceleration ); - savefile->ReadInt( rot.movetime ); - savefile->ReadInt( rot.deceleration ); - - savefile->ReadAngles( rot.rot ); - - savefile->ReadInt( move_thread ); - savefile->ReadInt( rotate_thread ); - - savefile->ReadAngles( dest_angles ); - savefile->ReadAngles( angle_delta ); - savefile->ReadVec3( dest_position ); - savefile->ReadVec3( move_delta ); - - savefile->ReadFloat( move_speed ); - savefile->ReadInt( move_time ); - savefile->ReadInt( deceltime ); - savefile->ReadInt( acceltime ); - savefile->ReadBool( stopRotation ); - savefile->ReadBool( useSplineAngles ); - savefile->ReadInt( (int &)lastCommand ); - savefile->ReadFloat( damage ); - - savefile->ReadInt( areaPortal ); - if ( areaPortal > 0 ) { - int portalState = 0; - savefile->ReadInt( portalState ); - gameLocal.SetPortalState( areaPortal, portalState ); - } - - guiTargets.Clear(); - savefile->ReadInt( num ); - guiTargets.SetNum( num ); - for( i = 0; i < num; i++ ) { - guiTargets[ i ].Restore( savefile ); - } - - savefile->ReadBool( hasSpline ); - if ( hasSpline ) { - int starttime; - int totaltime; - int accel; - int decel; - int useAngles; - - splineEnt.Restore( savefile ); - savefile->ReadInt( starttime ); - savefile->ReadInt( totaltime ); - savefile->ReadInt( accel ); - savefile->ReadInt( decel ); - savefile->ReadInt( useAngles ); - - PostEventMS( &EV_PostRestore, 0, starttime, totaltime, accel, decel, useAngles ); - } -} - -/* -================ -idMover::Event_PostRestore -================ -*/ -void idMover::Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng ) { - idCurve_Spline *spline; - - idEntity *splineEntity = splineEnt.GetEntity(); - if ( !splineEntity ) { - // We should never get this event if splineEnt is invalid - common->Warning( "Invalid spline entity during restore\n" ); - return; - } - - spline = splineEntity->GetSpline(); - - spline->MakeUniform( total ); - spline->ShiftTime( start - spline->GetTime( 0 ) ); - - physicsObj.SetSpline( spline, accel, decel, ( useSplineAng != 0 ) ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); -} - -/* -================ -idMover::Spawn -================ -*/ -void idMover::Spawn( void ) -{ - move_thread = 0; - rotate_thread = 0; - stopRotation = false; - lastCommand = MOVER_NONE; - - acceltime = static_cast(1000.0f * spawnArgs.GetFloat( "accel_time", "0" )); - deceltime = static_cast(1000.0f * spawnArgs.GetFloat( "decel_time", "0" )); - move_time = static_cast(1000.0f * spawnArgs.GetFloat( "move_time", "1" )); // safe default value - move_speed = spawnArgs.GetFloat( "move_speed", "0" ); - - spawnArgs.GetFloat( "damage" , "0", damage ); - - dest_position = GetPhysics()->GetOrigin(); - dest_angles = GetPhysics()->GetAxis().ToAngles(); - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "solid", "1" ) ) { - physicsObj.SetContents( 0 ); - } - if ( !renderEntity.hModel || !spawnArgs.GetBool( "nopush" ) ) { - // greebo: Check if we should be able to push the player (default is yes) - if (spawnArgs.GetBool("push_player", "1")) { - physicsObj.SetPusher(0); - } - else { - physicsObj.SetPusher(PUSHFL_NOPLAYER); - } - } - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); - SetPhysics( &physicsObj ); - - // see if we are on an areaportal - areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); - - if ( spawnArgs.MatchPrefix( "guiTarget" ) ) { - if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { - PostEventMS( &EV_FindGuiTargets, 0 ); - } else { - // not during spawn, so it's ok to get the targets - FindGuiTargets(); - } - } - - health = spawnArgs.GetInt( "health" ); - if ( health ) { - fl.takedamage = true; - } -} - -/* -================ -idMover::Hide -================ -*/ -void idMover::Hide( void ) { - idEntity::Hide(); - physicsObj.SetContents( 0 ); -} - -/* -================ -idMover::Show -================ -*/ -void idMover::Show( void ) { - idEntity::Show(); - physicsObj.SetContents( m_preHideContents ); - SetPhysics( &physicsObj ); -} - -/* -============ -idMover::Killed -============ -*/ -void idMover::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) -{ - bool bPlayerResponsible(false); - - fl.takedamage = false; - ActivateTargets( this ); - - if ( attacker && attacker->IsType( idPlayer::Type ) ) - bPlayerResponsible = ( attacker == gameLocal.GetLocalPlayer() ); - else if( attacker && attacker->m_SetInMotionByActor.GetEntity() ) - bPlayerResponsible = ( attacker->m_SetInMotionByActor.GetEntity() == gameLocal.GetLocalPlayer() ); - - gameLocal.m_MissionData->MissionEvent( COMP_DESTROY, this, bPlayerResponsible ); -} - - -/* -================ -idMover::Event_SetCallback -================ -*/ -void idMover::Event_SetCallback( void ) { - if ( ( lastCommand == MOVER_ROTATING ) && !rotate_thread ) { - lastCommand = MOVER_NONE; - rotate_thread = idThread::CurrentThreadNum(); - idThread::ReturnInt( true ); - } else if ( ( lastCommand == MOVER_MOVING || lastCommand == MOVER_SPLINE ) && !move_thread ) { - lastCommand = MOVER_NONE; - move_thread = idThread::CurrentThreadNum(); - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/* -================ -idMover::VectorForDir -================ -*/ -void idMover::VectorForDir( float angle, idVec3 &vec ) { - idAngles ang; - - switch( ( int )angle ) { - case DIR_UP : - vec.Set( 0, 0, 1 ); - break; - - case DIR_DOWN : - vec.Set( 0, 0, -1 ); - break; - - case DIR_LEFT : - physicsObj.GetLocalAngles( ang ); - ang.pitch = 0; - ang.roll = 0; - ang.yaw += 90; - vec = ang.ToForward(); - break; - - case DIR_RIGHT : - physicsObj.GetLocalAngles( ang ); - ang.pitch = 0; - ang.roll = 0; - ang.yaw -= 90; - vec = ang.ToForward(); - break; - - case DIR_FORWARD : - physicsObj.GetLocalAngles( ang ); - ang.pitch = 0; - ang.roll = 0; - vec = ang.ToForward(); - break; - - case DIR_BACK : - physicsObj.GetLocalAngles( ang ); - ang.pitch = 0; - ang.roll = 0; - ang.yaw += 180; - vec = ang.ToForward(); - break; - - case DIR_REL_UP : - vec.Set( 0, 0, 1 ); - break; - - case DIR_REL_DOWN : - vec.Set( 0, 0, -1 ); - break; - - case DIR_REL_LEFT : - physicsObj.GetLocalAngles( ang ); - ang.ToVectors( NULL, &vec ); - vec *= -1; - break; - - case DIR_REL_RIGHT : - physicsObj.GetLocalAngles( ang ); - ang.ToVectors( NULL, &vec ); - break; - - case DIR_REL_FORWARD : - physicsObj.GetLocalAngles( ang ); - vec = ang.ToForward(); - break; - - case DIR_REL_BACK : - physicsObj.GetLocalAngles( ang ); - vec = ang.ToForward() * -1; - break; - - default: - ang.Set( 0, angle, 0 ); - vec = GetWorldVector( ang.ToForward() ); - break; - } -} - -/* -================ -idMover::FindGuiTargets -================ -*/ -void idMover::FindGuiTargets( void ) { - gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" ); -} - -/* -============================== -idMover::SetGuiState - -key/val will be set to any renderEntity->gui's on the list -============================== -*/ -void idMover::SetGuiState( const char *key, const char *val ) const { - gameLocal.Printf( "Setting %s to %s\n", key, val ); - for( int i = 0; i < guiTargets.Num(); i++ ) { - idEntity *ent = guiTargets[ i ].GetEntity(); - if ( ent ) { - for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { - if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) { - ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); - ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time, true ); - } - } - ent->UpdateVisuals(); - } - } -} - -/* -================ -idMover::Event_InitGuiTargets -================ -*/ -void idMover::Event_FindGuiTargets( void ) { - FindGuiTargets(); -} - -/* -================ -idMover::SetGuiStates -================ -*/ -void idMover::SetGuiStates( const char *state ) { - int i; - if ( guiTargets.Num() ) { - SetGuiState( "movestate", state ); - } - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { - if ( renderEntity.gui[ i ] ) { - renderEntity.gui[ i ]->SetStateString( "movestate", state ); - renderEntity.gui[ i ]->StateChanged( gameLocal.time, true ); - } - } -} - -/* -================ -idMover::Event_InitGuiTargets -================ -*/ -void idMover::Event_InitGuiTargets( void ) { - SetGuiStates( guiBinaryMoverStates[MOVER_POS1] ); -} - -/*********************************************************************** - - Translation control functions - -***********************************************************************/ - -/* -================ -idMover::Event_StopMoving -================ -*/ -void idMover::Event_StopMoving( void ) { - physicsObj.GetLocalOrigin( dest_position ); - DoneMoving(); -} - -/* -================ -idMover::DoneMoving -================ -*/ -void idMover::DoneMoving( void ) { - - if ( lastCommand != MOVER_SPLINE ) { - // set our final position so that we get rid of any numerical inaccuracy - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); - } - - lastCommand = MOVER_NONE; - idThread::ObjectMoveDone( move_thread, this ); - move_thread = 0; - - StopSound( SND_CHANNEL_BODY, false ); -} - -/* -================ -idMover::UpdateMoveSound -================ -*/ -void idMover::UpdateMoveSound( moveStage_t stage ) { - switch( stage ) { - case ACCELERATION_STAGE: { - StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - break; - } - case LINEAR_STAGE: { - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - break; - } - case DECELERATION_STAGE: { - StopSound( SND_CHANNEL_BODY, false ); - StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); - break; - } - case FINISHED_STAGE: { - StopSound( SND_CHANNEL_BODY, false ); - break; - } - } -} - -/* -================ -idMover::Event_UpdateMove -================ -*/ -void idMover::Event_UpdateMove( void ) { - idVec3 org; - - physicsObj.GetLocalOrigin( org ); - - UpdateMoveSound( move.stage ); - - switch( move.stage ) { - case ACCELERATION_STAGE: { - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, move.acceleration, org, move.dir, vec3_origin ); - if ( move.movetime > 0 ) { - move.stage = LINEAR_STAGE; - } else if ( move.deceleration > 0 ) { - move.stage = DECELERATION_STAGE; - } else { - move.stage = FINISHED_STAGE; - } - break; - } - case LINEAR_STAGE: { - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, move.movetime, org, move.dir, vec3_origin ); - if ( move.deceleration ) { - move.stage = DECELERATION_STAGE; - } else { - move.stage = FINISHED_STAGE; - } - break; - } - case DECELERATION_STAGE: { - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, move.deceleration, org, move.dir, vec3_origin ); - move.stage = FINISHED_STAGE; - break; - } - case FINISHED_STAGE: { - if ( g_debugMover.GetBool() ) { - gameLocal.Printf( "%d: '%s' move done\n", gameLocal.time, name.c_str() ); - } - DoneMoving(); - break; - } - } -} - -/* -================ -idMover::BeginMove -================ -*/ -void idMover::BeginMove( idThread *thread ) { - moveStage_t stage; - idVec3 org; - float dist; - float acceldist; - int totalacceltime; - int at; - int dt; - - lastCommand = MOVER_MOVING; - move_thread = 0; - - physicsObj.GetLocalOrigin( org ); - - move_delta = dest_position - org; - if ( move_delta.Compare( vec3_zero ) ) { - DoneMoving(); - return; - } - - // scale times up to whole physics frames - at = idPhysics::SnapTimeToPhysicsFrame( acceltime ); - move_time += at - acceltime; - acceltime = at; - dt = idPhysics::SnapTimeToPhysicsFrame( deceltime ); - move_time += dt - deceltime; - deceltime = dt; - - // if we're moving at a specific speed, we need to calculate the move time - if ( move_speed ) { - dist = move_delta.Length(); - - totalacceltime = acceltime + deceltime; - - // calculate the distance we'll move during acceleration and deceleration - acceldist = totalacceltime * 0.5f * 0.001f * move_speed; - if ( acceldist >= dist ) { - // going too slow for this distance to move at a constant speed - move_time = totalacceltime; - } else { - // calculate move time taking acceleration into account - move_time = static_cast(totalacceltime + 1000.0f * ( dist - acceldist ) / move_speed); - } - } - - // scale time up to a whole physics frames - move_time = idPhysics::SnapTimeToPhysicsFrame( move_time ); - - if ( acceltime ) { - stage = ACCELERATION_STAGE; - } else if ( move_time <= deceltime ) { - stage = DECELERATION_STAGE; - } else { - stage = LINEAR_STAGE; - } - - at = acceltime; - dt = deceltime; - - if ( at + dt > move_time ) { - // there's no real correct way to handle this, so we just scale - // the times to fit into the move time in the same proportions - at = idPhysics::SnapTimeToPhysicsFrame( at * move_time / ( at + dt ) ); - dt = move_time - at; - } - - move_delta = move_delta * ( 1000.0f / ( (float) move_time - ( at + dt ) * 0.5f ) ); - - move.stage = stage; - move.acceleration = at; - move.movetime = move_time - at - dt; - move.deceleration = dt; - move.dir = move_delta; - - ProcessEvent( &EV_ReachedPos ); -} - -/*********************************************************************** - - Rotation control functions - -***********************************************************************/ - -/* -================ -idMover::Event_StopRotating -================ -*/ -void idMover::Event_StopRotating( void ) { - physicsObj.GetLocalAngles( dest_angles ); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); - DoneRotating(); -} - -/* -================ -idMover::DoneRotating -================ -*/ -void idMover::DoneRotating( void ) { - lastCommand = MOVER_NONE; - idThread::ObjectMoveDone( rotate_thread, this ); - rotate_thread = 0; - - StopSound( SND_CHANNEL_BODY, false ); -} - -/* -================ -idMover::UpdateRotationSound -================ -*/ -void idMover::UpdateRotationSound( moveStage_t stage ) { - switch( stage ) { - case ACCELERATION_STAGE: { - StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - break; - } - case LINEAR_STAGE: { - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - break; - } - case DECELERATION_STAGE: { - StopSound( SND_CHANNEL_BODY, false ); - StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); - break; - } - case FINISHED_STAGE: { - StopSound( SND_CHANNEL_BODY, false ); - break; - } - } -} - -/* -================ -idMover::Event_UpdateRotation -================ -*/ -void idMover::Event_UpdateRotation( void ) { - idAngles ang; - - physicsObj.GetLocalAngles( ang ); - - UpdateRotationSound( rot.stage ); - - switch( rot.stage ) { - case ACCELERATION_STAGE: { - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, rot.acceleration, ang, rot.rot, ang_zero ); - if ( rot.movetime > 0 ) { - rot.stage = LINEAR_STAGE; - } else if ( rot.deceleration > 0 ) { - rot.stage = DECELERATION_STAGE; - } else { - rot.stage = FINISHED_STAGE; - } - break; - } - case LINEAR_STAGE: { - if ( !stopRotation && !rot.deceleration ) { - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, rot.movetime, ang, rot.rot, ang_zero ); - } else { - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, rot.movetime, ang, rot.rot, ang_zero ); - } - - if ( rot.deceleration ) { - rot.stage = DECELERATION_STAGE; - } else { - rot.stage = FINISHED_STAGE; - } - break; - } - case DECELERATION_STAGE: { - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, rot.deceleration, ang, rot.rot, ang_zero ); - rot.stage = FINISHED_STAGE; - break; - } - case FINISHED_STAGE: { - lastCommand = MOVER_NONE; - if ( stopRotation ) { - // set our final angles so that we get rid of any numerical inaccuracy - dest_angles.Normalize360(); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); - stopRotation = false; - } else if ( physicsObj.GetAngularExtrapolationType() == EXTRAPOLATION_ACCELLINEAR ) { - // keep our angular velocity constant - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, rot.rot, ang_zero ); - } - - if ( g_debugMover.GetBool() ) { - gameLocal.Printf( "%d: '%s' rotation done\n", gameLocal.time, name.c_str() ); - } - - DoneRotating(); - break; - } - } -} - -float idMover::GetMoveTimeFraction() -{ - return 1.0f; -} - -/* -================ -idMover::BeginRotation -================ -*/ -void idMover::BeginRotation( idThread *thread, bool stopwhendone ) { - moveStage_t stage; - idAngles ang; - int at; - int dt; - - lastCommand = MOVER_ROTATING; - rotate_thread = 0; - - int moveTime = move_time; - - // rotation always uses moveTime so that if a move was started before the rotation, - // the rotation will take the same amount of time as the move. If no move has been - // started and no time is set, the rotation takes 1 second. - if ( !moveTime ) { - moveTime = 1; - } - - physicsObj.GetLocalAngles( ang ); - angle_delta = dest_angles - ang; - if ( angle_delta.Compare(ang_zero, VECTOR_EPSILON) ) { - // set our final angles so that we get rid of any numerical inaccuracy - dest_angles.Normalize360(); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_angles, ang_zero, ang_zero ); - stopRotation = false; - DoneRotating(); - return; - } - - // greebo: Calculate the moveTime fraction according to the current rotation state - // this is overridden by BinaryFrobMovers to achieve a flexible rotation move time. - float moveTimeFraction = GetMoveTimeFraction(); - - moveTime = static_cast(moveTime*moveTimeFraction); - - // scale times up to whole physics frames - at = idPhysics::SnapTimeToPhysicsFrame( acceltime ); - moveTime += at - acceltime; - acceltime = at; - dt = idPhysics::SnapTimeToPhysicsFrame( deceltime ); - moveTime += dt - deceltime; - deceltime = dt; - moveTime = idPhysics::SnapTimeToPhysicsFrame( moveTime ); - - if ( acceltime ) { - stage = ACCELERATION_STAGE; - } else if ( moveTime <= deceltime ) { - stage = DECELERATION_STAGE; - } else { - stage = LINEAR_STAGE; - } - - at = acceltime; - dt = deceltime; - - if ( at + dt > moveTime ) { - // there's no real correct way to handle this, so we just scale - // the times to fit into the move time in the same proportions - at = idPhysics::SnapTimeToPhysicsFrame( at * moveTime / ( at + dt ) ); - dt = moveTime - at; - } - - angle_delta = angle_delta * ( 1000.0f / ( (float) moveTime - ( at + dt ) * 0.5f ) ); - - stopRotation = stopwhendone || ( dt != 0 ); - - rot.stage = stage; - rot.acceleration = at; - rot.movetime = moveTime - at - dt; - rot.deceleration = dt; - rot.rot = angle_delta; - - ProcessEvent( &EV_ReachedAng ); -} - -void idMover::OnTeamBlocked(idEntity* blockedEntity, idEntity* blockingEntity) -{ - // empty default implementation, overridden by subclasses -} - -/*********************************************************************** - - Script callable routines - -***********************************************************************/ - -/* -=============== -idMover::Event_TeamBlocked -=============== -*/ -void idMover::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { - if ( g_debugMover.GetBool() ) { - gameLocal.Printf( "%d: '%s' stopped due to team member '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockedEntity->name.c_str(), blockingEntity->name.c_str() ); - } - - // greebo: Pass the call to the virtual function - OnTeamBlocked(blockedEntity, blockingEntity); -} - -/* -=============== -idMover::Event_PartBlocked -=============== -*/ -void idMover::Event_PartBlocked( idEntity *blockingEntity ) { - if ( damage > 0.0f ) { - blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); - } - if ( g_debugMover.GetBool() ) { - gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockingEntity->name.c_str() ); - } -} - -/* -================ -idMover::Event_SetMoveSpeed -================ -*/ -void idMover::Event_SetMoveSpeed( float speed ) { - if ( speed <= 0 ) { - gameLocal.Error( "Cannot set speed less than or equal to 0." ); - } - - move_speed = speed; - move_time = 0; // move_time is calculated for each move when move_speed is non-0 -} - -/* -================ -idMover::Event_SetMoveTime -================ -*/ -void idMover::Event_SetMoveTime( float time ) { - if ( time <= 0 ) { - gameLocal.Error( "Cannot set time less than or equal to 0." ); - } - - move_speed = 0; - move_time = SEC2MS( time ); -} - -/* -================ -idMover::Event_SetAccellerationTime -================ -*/ -void idMover::Event_SetAccellerationTime( float time ) { - if ( time < 0 ) { - gameLocal.Error( "Cannot set acceleration time less than 0." ); - } - - acceltime = SEC2MS( time ); -} - -/* -================ -idMover::Event_SetDecelerationTime -================ -*/ -void idMover::Event_SetDecelerationTime( float time ) { - if ( time < 0 ) { - gameLocal.Error( "Cannot set deceleration time less than 0." ); - } - - deceltime = SEC2MS( time ); -} - -/* -================ -idMover::Event_MoveTo -================ -*/ -void idMover::Event_MoveTo( idEntity *ent ) { - if ( !ent ) { - gameLocal.Warning( "Entity not found" ); - } - - dest_position = GetLocalCoordinates( ent->GetPhysics()->GetOrigin() ); - BeginMove( idThread::CurrentThread() ); -} - -/* -================ -idMover::MoveToPos -================ -*/ -void idMover::MoveToPos( const idVec3 &pos ) { - dest_position = GetLocalCoordinates( pos ); - BeginMove( NULL ); -} - -/* -================ -idMover::MoveToLocalPos -================ -*/ -void idMover::MoveToLocalPos( const idVec3 &pos ) { - dest_position = pos; - BeginMove( NULL ); -} -/* -================ -idMover::Event_MoveToPos -================ -*/ -void idMover::Event_MoveToPos( idVec3 &pos ) { - MoveToPos( pos ); -} - -/* -================ -idMover::Event_MoveDir -================ -*/ -void idMover::Event_MoveDir( float angle, float distance ) { - idVec3 dir; - idVec3 org; - - physicsObj.GetLocalOrigin( org ); - VectorForDir( angle, dir ); - dest_position = org + dir * distance; - - BeginMove( idThread::CurrentThread() ); -} - -/* -================ -idMover::Event_MoveAccelerateTo -================ -*/ -void idMover::Event_MoveAccelerateTo( float speed, float time ) { - float v; - idVec3 org, dir; - int at; - - if ( time < 0 ) { - gameLocal.Error( "idMover::Event_MoveAccelerateTo: cannot set acceleration time less than 0." ); - } - - dir = physicsObj.GetLinearVelocity(); - v = dir.Normalize(); - - // if not moving already - if ( v == 0.0f ) { - gameLocal.Error( "idMover::Event_MoveAccelerateTo: not moving." ); - } - - // if already moving faster than the desired speed - if ( v >= speed ) { - return; - } - - at = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); - - lastCommand = MOVER_MOVING; - - physicsObj.GetLocalOrigin( org ); - - move.stage = ACCELERATION_STAGE; - move.acceleration = at; - move.movetime = 0; - move.deceleration = 0; - - StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL ); - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.time, move.acceleration, org, dir * ( speed - v ), dir * v ); -} - -/* -================ -idMover::Event_MoveDecelerateTo -================ -*/ -void idMover::Event_MoveDecelerateTo( float speed, float time ) { - float v; - idVec3 org, dir; - int dt; - - if ( time < 0 ) { - gameLocal.Error( "idMover::Event_MoveDecelerateTo: cannot set deceleration time less than 0." ); - } - - dir = physicsObj.GetLinearVelocity(); - v = dir.Normalize(); - - // if not moving already - if ( v == 0.0f ) { - gameLocal.Error( "idMover::Event_MoveDecelerateTo: not moving." ); - } - - // if already moving slower than the desired speed - if ( v <= speed ) { - return; - } - - dt = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); - - lastCommand = MOVER_MOVING; - - physicsObj.GetLocalOrigin( org ); - - move.stage = DECELERATION_STAGE; - move.acceleration = 0; - move.movetime = 0; - move.deceleration = dt; - - StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL ); - StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.time, move.deceleration, org, dir * ( v - speed ), dir * speed ); -} - -/* -================ -idMover::Event_RotateDownTo -================ -*/ -void idMover::Event_RotateDownTo( int axis, float angle ) { - idAngles ang; - - if ( ( axis < 0 ) || ( axis > 2 ) ) { - gameLocal.Error( "Invalid axis" ); - } - - physicsObj.GetLocalAngles( ang ); - - dest_angles[ axis ] = angle; - if ( dest_angles[ axis ] > ang[ axis ] ) { - dest_angles[ axis ] -= 360; - } - - BeginRotation( idThread::CurrentThread(), true ); -} - -/* -================ -idMover::Event_RotateUpTo -================ -*/ -void idMover::Event_RotateUpTo( int axis, float angle ) { - idAngles ang; - - if ( ( axis < 0 ) || ( axis > 2 ) ) { - gameLocal.Error( "Invalid axis" ); - } - - physicsObj.GetLocalAngles( ang ); - - dest_angles[ axis ] = angle; - if ( dest_angles[ axis ] < ang[ axis ] ) { - dest_angles[ axis ] += 360; - } - - BeginRotation( idThread::CurrentThread(), true ); -} - -/* -================ -idMover::Event_RotateTo -================ -*/ -void idMover::Event_RotateTo( idAngles &angles ) { - dest_angles = angles; - BeginRotation( idThread::CurrentThread(), true ); -} - -/* -================ -idMover::Event_Rotate -================ -*/ -void idMover::Event_Rotate( idAngles &angles ) { - if ( rotate_thread ) { - DoneRotating(); - } - - dest_angles = physicsObj.GetLocalAngles() + angles * ( move_time - ( acceltime + deceltime ) / 2 ) * 0.001f; - - BeginRotation( idThread::CurrentThread(), false ); -} - -/* -================ -idMover::Event_RotateOnce -================ -*/ -void idMover::Event_RotateOnce( idAngles &angles ) { - if ( rotate_thread ) { - DoneRotating(); - } - - dest_angles = physicsObj.GetLocalAngles() + angles; - - BeginRotation( idThread::CurrentThread(), true ); -} - -/* -================ -idMover::Event_Bob -================ -*/ -void idMover::Event_Bob( float speed, float phase, idVec3 &depth ) { - idVec3 org; - - physicsObj.GetLocalOrigin( org ); - physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(speed * 1000 * phase), static_cast(speed * 500), org, depth * 2.0f, vec3_origin ); -} - -/* -================ -idMover::Event_Sway -================ -*/ -void idMover::Event_Sway( float speed, float phase, idAngles &depth ) { - idAngles ang, angSpeed; - float duration; - - physicsObj.GetLocalAngles( ang ); - assert ( speed > 0.0f ); - duration = idMath::Sqrt( depth[0] * depth[0] + depth[1] * depth[1] + depth[2] * depth[2] ) / speed; - angSpeed = depth / ( duration * idMath::SQRT_1OVER2 ); - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(duration * 1000.0f * phase), static_cast(duration * 1000.0f), ang, angSpeed, ang_zero ); -} - -/* -================ -idMover::Event_OpenPortal - -Sets the portal associtated with this mover to be open -================ -*/ -void idMover::Event_OpenPortal( void ) -{ - // angua: call the virtual function - OpenPortal(); -} - -/* -================ -idMover::Event_ClosePortal - -Sets the portal associtated with this mover to be closed -================ -*/ -void idMover::Event_ClosePortal( void ) -{ - // angua: call the virtual function - ClosePortal(); -} - - -/* -================ -idMover::OpenPortal - -Sets the portal associtated with this mover to be open -================ -*/ -void idMover::OpenPortal() { - if ( areaPortal ) { - SetPortalState( true ); - } -} - -/* -================ -idMover::ClosePortal - -Sets the portal associtated with this mover to be closed -================ -*/ -void idMover::ClosePortal() { - if ( areaPortal ) { - SetPortalState( false ); - } -} - - - - -/* -================ -idMover::Event_SetAccelSound -================ -*/ -void idMover::Event_SetAccelSound( const char *sound ) { -// refSound.SetSound( "accel", sound ); -} - -/* -================ -idMover::Event_SetDecelSound -================ -*/ -void idMover::Event_SetDecelSound( const char *sound ) { -// refSound.SetSound( "decel", sound ); -} - -/* -================ -idMover::Event_SetMoveSound -================ -*/ -void idMover::Event_SetMoveSound( const char *sound ) { -// refSound.SetSound( "move", sound ); -} - -/* -================ -idMover::Event_EnableSplineAngles -================ -*/ -void idMover::Event_EnableSplineAngles( void ) { - useSplineAngles = true; -} - -/* -================ -idMover::Event_DisableSplineAngles -================ -*/ -void idMover::Event_DisableSplineAngles( void ) { - useSplineAngles = false; -} - -/* -================ -idMover::Event_RemoveInitialSplineAngles -================ -*/ -void idMover::Event_RemoveInitialSplineAngles( void ) { - idCurve_Spline *spline; - idAngles ang; - - spline = physicsObj.GetSpline(); - if ( !spline ) { - return; - } - ang = spline->GetCurrentFirstDerivative( 0 ).ToAngles(); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, -ang, ang_zero, ang_zero ); -} - -/* -================ -idMover::Event_StartSpline -================ -*/ -void idMover::Event_StartSpline( idEntity *splineEntity ) { - idCurve_Spline *spline; - - if ( !splineEntity ) { - return; - } - - // Needed for savegames - splineEnt = splineEntity; - - spline = splineEntity->GetSpline(); - if ( !spline ) { - return; - } - - lastCommand = MOVER_SPLINE; - move_thread = 0; - - if ( acceltime + deceltime > move_time ) { - acceltime = move_time / 2; - deceltime = move_time - acceltime; - } - move.stage = FINISHED_STAGE; - move.acceleration = acceltime; - move.movetime = move_time; - move.deceleration = deceltime; - - spline->MakeUniform( move_time ); - spline->ShiftTime( gameLocal.time - spline->GetTime( 0 ) ); - - physicsObj.SetSpline( spline, move.acceleration, move.deceleration, useSplineAngles ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, dest_position, vec3_origin, vec3_origin ); -} - -/* -================ -idMover::Event_StopSpline -================ -*/ -void idMover::Event_StopSpline( void ) { - physicsObj.SetSpline( NULL, 0, 0, useSplineAngles ); - splineEnt = NULL; -} - -/* -================ -idMover::Event_Activate -================ -*/ -void idMover::Event_Activate( idEntity *activator ) { - Show(); - Event_StartSpline( this ); -} - -/* -================ -idMover::Event_IsMoving -================ -*/ -void idMover::Event_IsMoving( void ) { - if ( physicsObj.GetLinearExtrapolationType() == EXTRAPOLATION_NONE ) { - idThread::ReturnInt( false ); - } else { - idThread::ReturnInt( true ); - } -} - -/* -================ -idMover::Event_IsRotating -================ -*/ -void idMover::Event_IsRotating( void ) { - if ( physicsObj.GetAngularExtrapolationType() == EXTRAPOLATION_NONE ) { - idThread::ReturnInt( false ); - } else { - idThread::ReturnInt( true ); - } -} - -/* -================ -idMover::WriteToSnapshot -================ -*/ -void idMover::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); - msg.WriteBits( move.stage, 3 ); - msg.WriteBits( rot.stage, 3 ); - WriteBindToSnapshot( msg ); - WriteGUIToSnapshot( msg ); -} - -/* -================ -idMover::ReadFromSnapshot -================ -*/ -void idMover::ReadFromSnapshot( const idBitMsgDelta &msg ) { - moveStage_t oldMoveStage = move.stage; - moveStage_t oldRotStage = rot.stage; - - physicsObj.ReadFromSnapshot( msg ); - move.stage = (moveStage_t) msg.ReadBits( 3 ); - rot.stage = (moveStage_t) msg.ReadBits( 3 ); - ReadBindFromSnapshot( msg ); - ReadGUIFromSnapshot( msg ); - - if ( msg.HasChanged() ) { - if ( move.stage != oldMoveStage ) { - UpdateMoveSound( oldMoveStage ); - } - if ( rot.stage != oldRotStage ) { - UpdateRotationSound( oldRotStage ); - } - UpdateVisuals(); - } -} - -/* -================ -idMover::SetPortalState -================ -*/ -void idMover::SetPortalState( bool open ) { - assert( areaPortal ); - gameLocal.SetPortalState( areaPortal, open ? PS_BLOCK_NONE : PS_BLOCK_ALL ); -} - -/* -================ -idMover::IsBlocked -================ -*/ -bool idMover::IsBlocked( void ) -{ - const trace_t* trace = physicsObj.GetBlockingInfo(); - return (trace != NULL); -} - - -/* -=============================================================================== - - idSplinePath, holds a spline path to be used by an idMover - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idSplinePath ) -END_CLASS - -/* -================ -idSplinePath::idSplinePath -================ -*/ -idSplinePath::idSplinePath() { -} - -/* -================ -idSplinePath::Spawn -================ -*/ -void idSplinePath::Spawn( void ) { -} - - -/* -=============================================================================== - -idMover_Binary - -Doors, plats, and buttons are all binary (two position) movers -Pos1 is "at rest", pos2 is "activated" - -=============================================================================== -*/ - -const idEventDef EV_Mover_ReturnToPos1( "", NULL ); -const idEventDef EV_Mover_MatchTeam( "", "dd" ); -const idEventDef EV_Mover_Enable( "enable", NULL ); -const idEventDef EV_Mover_Disable( "disable", NULL ); - -CLASS_DECLARATION( idEntity, idMover_Binary ) - EVENT( EV_FindGuiTargets, idMover_Binary::Event_FindGuiTargets ) - EVENT( EV_Thread_SetCallback, idMover_Binary::Event_SetCallback ) - EVENT( EV_Mover_ReturnToPos1, idMover_Binary::Event_ReturnToPos1 ) - EVENT( EV_Activate, idMover_Binary::Event_Use_BinaryMover ) - EVENT( EV_ReachedPos, idMover_Binary::Event_Reached_BinaryMover ) - EVENT( EV_Mover_MatchTeam, idMover_Binary::Event_MatchActivateTeam ) - EVENT( EV_Mover_Enable, idMover_Binary::Event_Enable ) - EVENT( EV_Mover_Disable, idMover_Binary::Event_Disable ) - EVENT( EV_Mover_OpenPortal, idMover_Binary::Event_OpenPortal ) - EVENT( EV_Mover_ClosePortal, idMover_Binary::Event_ClosePortal ) - EVENT( EV_Mover_InitGuiTargets, idMover_Binary::Event_InitGuiTargets ) -END_CLASS - -/* -================ -idMover_Binary::idMover_Binary() -================ -*/ -idMover_Binary::idMover_Binary() -{ - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("this: %08lX [%s]\r", this, __FUNCTION__); - - pos1.Zero(); - pos2.Zero(); - moverState = MOVER_POS1; - moveMaster = NULL; - activateChain = NULL; - soundPos1 = 0; - sound1to2 = 0; - sound2to1 = 0; - soundPos2 = 0; - soundLoop = 0; - wait = 0.0f; - damage = 0.0f; - duration = 0; - accelTime = 0; - decelTime = 0; - activatedBy = this; - stateStartTime = 0; - team.Clear(); - enabled = false; - move_thread = 0; - updateStatus = 0; - areaPortal = 0; - blocked = false; - fl.networkSync = true; - m_FrobActionScript = "frob_binary_mover"; -} - -/* -================ -idMover_Binary::~idMover_Binary -================ -*/ -idMover_Binary::~idMover_Binary() -{ - idMover_Binary *mover; - - // if this is the mover master - if ( this == moveMaster ) { - // make the next mover in the chain the move master - for ( mover = moveMaster; mover; mover = mover->activateChain ) { - mover->moveMaster = this->activateChain; - } - } - else { - // remove mover from the activate chain - for ( mover = moveMaster; mover; mover = mover->activateChain ) { - if ( mover->activateChain == this ) { - mover->activateChain = this->activateChain; - break; - } - } - } -} - -/* -================ -idMover_Binary::Save -================ -*/ -void idMover_Binary::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteVec3( pos1 ); - savefile->WriteVec3( pos2 ); - savefile->WriteInt( (moverState_t)moverState ); - - savefile->WriteObject( moveMaster ); - savefile->WriteObject( activateChain ); - - savefile->WriteInt( soundPos1 ); - savefile->WriteInt( sound1to2 ); - savefile->WriteInt( sound2to1 ); - savefile->WriteInt( soundPos2 ); - savefile->WriteInt( soundLoop ); - - savefile->WriteFloat( wait ); - savefile->WriteFloat( damage ); - - savefile->WriteInt( duration ); - savefile->WriteInt( accelTime ); - savefile->WriteInt( decelTime ); - - activatedBy.Save( savefile ); - - savefile->WriteInt( stateStartTime ); - savefile->WriteString( team ); - savefile->WriteBool( enabled ); - - savefile->WriteInt( move_thread ); - savefile->WriteInt( updateStatus ); - - savefile->WriteInt( buddies.Num() ); - for ( i = 0; i < buddies.Num(); i++ ) { - savefile->WriteString( buddies[ i ] ); - } - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteInt( areaPortal ); - if ( areaPortal ) { - savefile->WriteInt( gameRenderWorld->GetPortalState( areaPortal ) ); - } - savefile->WriteBool( blocked ); - - savefile->WriteInt( guiTargets.Num() ); - for( i = 0; i < guiTargets.Num(); i++ ) { - guiTargets[ i ].Save( savefile ); - } -} - -/* -================ -idMover_Binary::Restore -================ -*/ -void idMover_Binary::Restore( idRestoreGame *savefile ) { - int i, num, portalState; - idStr temp; - - savefile->ReadVec3( pos1 ); - savefile->ReadVec3( pos2 ); - savefile->ReadInt( (int &)moverState ); - - savefile->ReadObject( reinterpret_cast( moveMaster ) ); - savefile->ReadObject( reinterpret_cast( activateChain ) ); - - savefile->ReadInt( soundPos1 ); - savefile->ReadInt( sound1to2 ); - savefile->ReadInt( sound2to1 ); - savefile->ReadInt( soundPos2 ); - savefile->ReadInt( soundLoop ); - - savefile->ReadFloat( wait ); - savefile->ReadFloat( damage ); - - savefile->ReadInt( duration ); - savefile->ReadInt( accelTime ); - savefile->ReadInt( decelTime ); - - activatedBy.Restore( savefile ); - - savefile->ReadInt( stateStartTime ); - - savefile->ReadString( team ); - savefile->ReadBool( enabled ); - - savefile->ReadInt( move_thread ); - savefile->ReadInt( updateStatus ); - - savefile->ReadInt( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadString( temp ); - buddies.Append( temp ); - } - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadInt( areaPortal ); - if ( areaPortal ) { - savefile->ReadInt( portalState ); - gameLocal.SetPortalState( areaPortal, portalState ); - } - savefile->ReadBool( blocked ); - - guiTargets.Clear(); - savefile->ReadInt( num ); - guiTargets.SetNum( num ); - for( i = 0; i < num; i++ ) { - guiTargets[ i ].Restore( savefile ); - } -} - -/* -================ -idMover_Binary::Spawn - -Base class for all movers. - -"wait" wait before returning (3 default, -1 = never return) -"speed" movement speed -================ -*/ -void idMover_Binary::Spawn( void ) -{ - idEntity *ent; - const char *temp; - - move_thread = 0; - enabled = true; - areaPortal = 0; - - activateChain = NULL; - - spawnArgs.GetFloat( "wait", "0", wait ); - - spawnArgs.GetInt( "updateStatus", "0", updateStatus ); - - const idKeyValue *kv = spawnArgs.MatchPrefix( "buddy", NULL ); - while( kv ) { - buddies.Append( kv->GetValue() ); - kv = spawnArgs.MatchPrefix( "buddy", kv ); - } - - spawnArgs.GetString( "team", "", &temp ); - team = temp; - - if ( !team.Length() ) { - ent = this; - } else { - // find the first entity spawned on this team (which could be us) - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( idMover_Binary::Type ) && !idStr::Icmp( static_cast(ent)->team.c_str(), temp ) ) { - break; - } - } - if ( !ent ) { - ent = this; - } - } - moveMaster = static_cast(ent); - - // create a physics team for the binary mover parts - if ( ent != this ) { - JoinTeam( ent ); - } - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "solid", "1" ) ) { - physicsObj.SetContents( 0 ); - } - if ( !spawnArgs.GetBool( "nopush" ) ) { - physicsObj.SetPusher( 0 ); - } - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); - physicsObj.SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetAxis().ToAngles(), ang_zero, ang_zero ); - SetPhysics( &physicsObj ); - - if ( moveMaster != this ) { - JoinActivateTeam( moveMaster ); - } - - idBounds soundOrigin; - idMover_Binary *slave; - - soundOrigin.Clear(); - for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - soundOrigin += slave->GetPhysics()->GetAbsBounds(); - } - moveMaster->refSound.origin = soundOrigin.GetCenter(); - - if ( spawnArgs.MatchPrefix( "guiTarget" ) ) { - if ( gameLocal.GameState() == GAMESTATE_STARTUP ) { - PostEventMS( &EV_FindGuiTargets, 0 ); - } else { - // not during spawn, so it's ok to get the targets - FindGuiTargets(); - } - } -} - -/* -=============== -idMover_Binary::GetMovedir - -The editor only specifies a single value for angles (yaw), -but we have special constants to generate an up or down direction. -Angles will be cleared, because it is being used to represent a direction -instead of an orientation. -=============== -*/ -void idMover_Binary::GetMovedir( float angle, idVec3 &movedir ) { - if ( angle == -1 ) { - movedir.Set( 0, 0, 1 ); - } else if ( angle == -2 ) { - movedir.Set( 0, 0, -1 ); - } else { - movedir = idAngles( 0, angle, 0 ).ToForward(); - } -} - -/* -================ -idMover_Binary::Event_SetCallback -================ -*/ -void idMover_Binary::Event_SetCallback( void ) { - if ( ( moverState == MOVER_1TO2 ) || ( moverState == MOVER_2TO1 ) ) { - move_thread = idThread::CurrentThreadNum(); - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/* -=============== -idMover_Binary::UpdateMoverSound -=============== -*/ -void idMover_Binary::UpdateMoverSound( moverState_t state ) { - if ( moveMaster == this ) { - switch( state ) { - case MOVER_POS1: - break; - case MOVER_POS2: - break; - case MOVER_1TO2: - StartSound( "snd_open", SND_CHANNEL_ANY, 0, false, NULL ); - break; - case MOVER_2TO1: - StartSound( "snd_close", SND_CHANNEL_ANY, 0, false, NULL ); - break; - } - } -} - -/* -=============== -idMover_Binary::SetMoverState -=============== -*/ -void idMover_Binary::SetMoverState( moverState_t newstate, int time ) { - idVec3 delta; - - moverState = newstate; - move_thread = 0; - - UpdateMoverSound( newstate ); - - stateStartTime = time; - switch( moverState ) { - case MOVER_POS1: { - Signal( SIG_MOVER_POS1 ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, time, 0, pos1, vec3_origin, vec3_origin ); - break; - } - case MOVER_POS2: { - Signal( SIG_MOVER_POS2 ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, time, 0, pos2, vec3_origin, vec3_origin ); - break; - } - case MOVER_1TO2: { - Signal( SIG_MOVER_1TO2 ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, time, duration, pos1, ( pos2 - pos1 ) * 1000.0f / duration, vec3_origin ); - if ( accelTime != 0 || decelTime != 0 ) { - physicsObj.SetLinearInterpolation( time, accelTime, decelTime, duration, pos1, pos2 ); - } else { - physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 ); - } - break; - } - case MOVER_2TO1: { - Signal( SIG_MOVER_2TO1 ); - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, time, duration, pos2, ( pos1 - pos2 ) * 1000.0f / duration, vec3_origin ); - if ( accelTime != 0 || decelTime != 0 ) { - physicsObj.SetLinearInterpolation( time, accelTime, decelTime, duration, pos2, pos1 ); - } else { - physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 ); - } - break; - } - } -} - -/* -================ -idMover_Binary::MatchActivateTeam - -All entities in a mover team will move from pos1 to pos2 -in the same amount of time -================ -*/ -void idMover_Binary::MatchActivateTeam( moverState_t newstate, int time ) { - idMover_Binary *slave; - - for ( slave = this; slave != NULL; slave = slave->activateChain ) { - slave->SetMoverState( newstate, time ); - } -} - -/* -================ -idMover_Binary::Enable -================ -*/ -void idMover_Binary::Enable( bool b ) { - enabled = b; -} - -/* -================ -idMover_Binary::Event_MatchActivateTeam -================ -*/ -void idMover_Binary::Event_MatchActivateTeam( moverState_t newstate, int time ) { - MatchActivateTeam( newstate, time ); -} - -/* -================ -idMover_Binary::BindTeam - -All entities in a mover team will be bound -================ -*/ -void idMover_Binary::BindTeam( idEntity *bindTo ) { - idMover_Binary *slave; - - for ( slave = this; slave != NULL; slave = slave->activateChain ) { - slave->Bind( bindTo, true ); - } -} - -/* -================ -idMover_Binary::JoinActivateTeam - -Set all entities in a mover team to be enabled -================ -*/ -void idMover_Binary::JoinActivateTeam( idMover_Binary *master ) { - this->activateChain = master->activateChain; - master->activateChain = this; -} - -/* -================ -idMover_Binary::Event_Enable - -Set all entities in a mover team to be enabled -================ -*/ -void idMover_Binary::Event_Enable( void ) { - idMover_Binary *slave; - - for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - slave->Enable( false ); - } -} - -/* -================ -idMover_Binary::Event_Disable - -Set all entities in a mover team to be disabled -================ -*/ -void idMover_Binary::Event_Disable( void ) { - idMover_Binary *slave; - - for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - slave->Enable( false ); - } -} - -/* -================ -idMover_Binary::Event_OpenPortal - -Sets the portal associtated with this mover to be open -================ -*/ -void idMover_Binary::Event_OpenPortal( void ) { - idMover_Binary *slave; - - for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - if ( slave->areaPortal ) { - slave->SetPortalState( true ); - } - } -} - -/* -================ -idMover_Binary::Event_ClosePortal - -Sets the portal associtated with this mover to be closed -================ -*/ -void idMover_Binary::Event_ClosePortal( void ) { - idMover_Binary *slave; - - for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - if ( !slave->IsHidden() ) { - if ( slave->areaPortal ) { - slave->SetPortalState( false ); - } - } - } -} - -/* -================ -idMover_Binary::Event_ReturnToPos1 -================ -*/ -void idMover_Binary::Event_ReturnToPos1( void ) { - MatchActivateTeam( MOVER_2TO1, gameLocal.time ); -} - -/* -================ -idMover_Binary::Event_Reached_BinaryMover -================ -*/ -void idMover_Binary::Event_Reached_BinaryMover( void ) { - - if ( moverState == MOVER_1TO2 ) { - // reached pos2 - idThread::ObjectMoveDone( move_thread, this ); - move_thread = 0; - - if ( moveMaster == this ) { - StartSound( "snd_opened", SND_CHANNEL_ANY, 0, false, NULL ); - } - - SetMoverState( MOVER_POS2, gameLocal.time ); - - SetGuiStates( guiBinaryMoverStates[MOVER_POS2] ); - - UpdateBuddies( 1 ); - - if ( enabled && wait >= 0 && !spawnArgs.GetBool( "toggle" ) ) { - // return to pos1 after a delay - PostEventSec( &EV_Mover_ReturnToPos1, wait ); - } - - // fire targets - ActivateTargets( moveMaster->GetActivator() ); - - - SetBlocked(false); - - } else if ( moverState == MOVER_2TO1 ) { - // reached pos1 - idThread::ObjectMoveDone( move_thread, this ); - move_thread = 0; - - SetMoverState( MOVER_POS1, gameLocal.time ); - - SetGuiStates( guiBinaryMoverStates[MOVER_POS1] ); - - UpdateBuddies( 0 ); - - // close areaportals - if ( moveMaster == this ) { - ProcessEvent( &EV_Mover_ClosePortal ); - } - - if ( enabled && wait >= 0 && spawnArgs.GetBool( "continuous" ) ) { - PostEventSec( &EV_Activate, wait, this ); - } - - - SetBlocked(false); - - } else { - gameLocal.Error( "Event_Reached_BinaryMover: bad moverState" ); - } -} - -/* -================ -idMover_Binary::GotoPosition1 -================ -*/ -void idMover_Binary::GotoPosition1( void ) { - idMover_Binary *slave; - int partial; - - // only the master should control this - if ( moveMaster != this ) { - moveMaster->GotoPosition1(); - return; - } - - SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] ); - - if ( ( moverState == MOVER_POS1 ) || ( moverState == MOVER_2TO1 ) ) { - // already there, or on the way - return; - } - - if ( moverState == MOVER_POS2 ) { - for ( slave = this; slave != NULL; slave = slave->activateChain ) { - slave->CancelEvents( &EV_Mover_ReturnToPos1 ); - } - if ( !spawnArgs.GetBool( "toggle" ) ) { - ProcessEvent( &EV_Mover_ReturnToPos1 ); - } - return; - } - - // only partway up before reversing - if ( moverState == MOVER_1TO2 ) { - // use the physics times because this might be executed during the physics simulation - partial = physicsObj.GetLinearEndTime() - physicsObj.GetTime(); - assert( partial >= 0 ); - if ( partial < 0 ) { - partial = 0; - } - MatchActivateTeam( MOVER_2TO1, physicsObj.GetTime() - partial ); - // if already at at position 1 (partial == duration) execute the reached event - if ( partial >= duration ) { - Event_Reached_BinaryMover(); - } - } -} - -/* -================ -idMover_Binary::GotoPosition2 -================ -*/ -void idMover_Binary::GotoPosition2( void ) { - int partial; - - // only the master should control this - if ( moveMaster != this ) { - moveMaster->GotoPosition2(); - return; - } - - SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] ); - - if ( ( moverState == MOVER_POS2 ) || ( moverState == MOVER_1TO2 ) ) { - // already there, or on the way - return; - } - - if ( moverState == MOVER_POS1 ) { - MatchActivateTeam( MOVER_1TO2, gameLocal.time ); - - // open areaportal - ProcessEvent( &EV_Mover_OpenPortal ); - return; - } - - - // only partway up before reversing - if ( moverState == MOVER_2TO1 ) { - // use the physics times because this might be executed during the physics simulation - partial = physicsObj.GetLinearEndTime() - physicsObj.GetTime(); - assert( partial >= 0 ); - if ( partial < 0 ) { - partial = 0; - } - MatchActivateTeam( MOVER_1TO2, physicsObj.GetTime() - partial ); - // if already at at position 2 (partial == duration) execute the reached event - if ( partial >= duration ) { - Event_Reached_BinaryMover(); - } - } -} - -/* -================ -idMover_Binary::UpdateBuddies -================ -*/ -void idMover_Binary::UpdateBuddies( int val ) { - int i, c; - - if ( updateStatus == 2 ) { - c = buddies.Num(); - for ( i = 0; i < c; i++ ) { - idEntity *buddy = gameLocal.FindEntity( buddies[i] ); - if ( buddy ) { - buddy->SetShaderParm( SHADERPARM_MODE, val ); - buddy->UpdateVisuals(); - } - } - } -} - -/* -================ -idMover_Binary::SetGuiStates -================ -*/ -void idMover_Binary::SetGuiStates( const char *state ) { - if ( guiTargets.Num() ) { - SetGuiState( "movestate", state ); - } - - idMover_Binary *mb = activateChain; - while( mb ) { - if ( mb->guiTargets.Num() ) { - mb->SetGuiState( "movestate", state ); - } - mb = mb->activateChain; - } -} - -/* -================ -idMover_Binary::Use_BinaryMover -================ -*/ -void idMover_Binary::Use_BinaryMover( idEntity *activator ) { - // only the master should be used - if ( moveMaster != this ) { - moveMaster->Use_BinaryMover( activator ); - return; - } - - if ( !enabled ) { - return; - } - - activatedBy = activator; - - if ( moverState == MOVER_POS1 ) { - // FIXME: start moving USERCMD_MSEC later, because if this was player - // triggered, gameLocal.time hasn't been advanced yet - MatchActivateTeam( MOVER_1TO2, gameLocal.time + USERCMD_MSEC ); - - SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] ); - // open areaportal - ProcessEvent( &EV_Mover_OpenPortal ); - return; - } - - // if all the way up, just delay before coming down - if ( moverState == MOVER_POS2 ) { - idMover_Binary *slave; - - if ( wait == -1 ) { - return; - } - - SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] ); - - for ( slave = this; slave != NULL; slave = slave->activateChain ) { - slave->CancelEvents( &EV_Mover_ReturnToPos1 ); - slave->PostEventSec( &EV_Mover_ReturnToPos1, spawnArgs.GetBool( "toggle" ) ? 0 : wait ); - } - return; - } - - // only partway down before reversing - if ( moverState == MOVER_2TO1 ) { - GotoPosition2(); - return; - } - - // only partway up before reversing - if ( moverState == MOVER_1TO2 ) { - GotoPosition1(); - return; - } -} - -/* -================ -idMover_Binary::Event_Use_BinaryMover -================ -*/ -void idMover_Binary::Event_Use_BinaryMover( idEntity *activator ) { - Use_BinaryMover( activator ); -} - -/* -================ -idMover_Binary::PreBind -================ -*/ -void idMover_Binary::PreBind( void ) { - pos1 = GetWorldCoordinates( pos1 ); - pos2 = GetWorldCoordinates( pos2 ); -} - -/* -================ -idMover_Binary::PostBind -================ -*/ -void idMover_Binary::PostBind( void ) { - pos1 = GetLocalCoordinates( pos1 ); - pos2 = GetLocalCoordinates( pos2 ); -} - -/* -================ -idMover_Binary::FindGuiTargets -================ -*/ -void idMover_Binary::FindGuiTargets( void ) { - gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" ); -} - -/* -============================== -idMover_Binary::SetGuiState - -key/val will be set to any renderEntity->gui's on the list -============================== -*/ -void idMover_Binary::SetGuiState( const char *key, const char *val ) const { - int i; - - for( i = 0; i < guiTargets.Num(); i++ ) { - idEntity *ent = guiTargets[ i ].GetEntity(); - if ( ent ) { - for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { - if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) { - ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); - ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time, true ); - } - } - ent->UpdateVisuals(); - } - } -} - -/* -================ -idMover_Binary::Event_InitGuiTargets -================ -*/ -void idMover_Binary::Event_FindGuiTargets( void ) { - FindGuiTargets(); -} - -/* -================ -idMover_Binary::Event_InitGuiTargets -================ -*/ -void idMover_Binary::Event_InitGuiTargets( void ) { - if ( guiTargets.Num() ) { - SetGuiState( "movestate", guiBinaryMoverStates[MOVER_POS1] ); - } -} - -/* -================ -idMover_Binary::InitSpeed - -pos1, pos2, and speed are passed in so the movement delta can be calculated -================ -*/ -void idMover_Binary::InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime ) { - idVec3 move; - float distance; - float speed; - - pos1 = mpos1; - pos2 = mpos2; - - accelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( maccelTime ) ); - decelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mdecelTime ) ); - - speed = mspeed ? mspeed : 100; - - // calculate time to reach second position from speed - move = pos2 - pos1; - distance = move.Length(); - duration = idPhysics::SnapTimeToPhysicsFrame( static_cast(distance * 1000 / speed) ); - if ( duration <= 0 ) { - duration = 1; - } - - moverState = MOVER_POS1; - - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, pos1, vec3_origin, vec3_origin ); - physicsObj.SetLinearInterpolation( 0, 0, 0, 0, vec3_origin, vec3_origin ); - SetOrigin( pos1 ); - - PostEventMS( &EV_Mover_InitGuiTargets, 0 ); -} - -/* -================ -idMover_Binary::InitTime - -pos1, pos2, and time are passed in so the movement delta can be calculated -================ -*/ -void idMover_Binary::InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime ) { - - pos1 = mpos1; - pos2 = mpos2; - - accelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( maccelTime ) ); - decelTime = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mdecelTime ) ); - - duration = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( mtime ) ); - if ( duration <= 0 ) { - duration = 1; - } - - moverState = MOVER_POS1; - - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, pos1, vec3_origin, vec3_origin ); - physicsObj.SetLinearInterpolation( 0, 0, 0, 0, vec3_origin, vec3_origin ); - SetOrigin( pos1 ); - - PostEventMS( &EV_Mover_InitGuiTargets, 0 ); -} - -/* -================ -idMover_Binary::SetBlocked -================ -*/ -void idMover_Binary::SetBlocked( bool b ) { - for ( idMover_Binary *slave = moveMaster; slave != NULL; slave = slave->activateChain ) { - slave->blocked = b; - if ( b ) { - const idKeyValue *kv = slave->spawnArgs.MatchPrefix( "triggerBlocked" ); - while( kv ) { - idEntity *ent = gameLocal.FindEntity( kv->GetValue() ); - if ( ent ) { - ent->PostEventMS( &EV_Activate, 0, moveMaster->GetActivator() ); - } - kv = slave->spawnArgs.MatchPrefix( "triggerBlocked", kv ); - } - } - } -} - -/* -================ -idMover_Binary::IsBlocked -================ -*/ -bool idMover_Binary::IsBlocked( void ) { - return blocked; -} - -/* -================ -idMover_Binary::GetActivator -================ -*/ -idEntity *idMover_Binary::GetActivator( void ) const { - return activatedBy.GetEntity(); -} - -/* -================ -idMover_Binary::WriteToSnapshot -================ -*/ -void idMover_Binary::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); - msg.WriteBits( moverState, 3 ); - WriteBindToSnapshot( msg ); -} - -/* -================ -idMover_Binary::ReadFromSnapshot -================ -*/ -void idMover_Binary::ReadFromSnapshot( const idBitMsgDelta &msg ) { - moverState_t oldMoverState = moverState; - - physicsObj.ReadFromSnapshot( msg ); - moverState = (moverState_t) msg.ReadBits( 3 ); - ReadBindFromSnapshot( msg ); - - if ( msg.HasChanged() ) { - if ( moverState != oldMoverState ) { - UpdateMoverSound( moverState ); - } - UpdateVisuals(); - } -} - -/* -================ -idMover_Binary::SetPortalState -================ -*/ -void idMover_Binary::SetPortalState( bool open ) { - assert( areaPortal ); - gameLocal.SetPortalState( areaPortal, open ? PS_BLOCK_NONE : PS_BLOCK_ALL ); -} - -/* -=============================================================================== - -idPlat - -=============================================================================== -*/ - -CLASS_DECLARATION( idMover_Binary, idPlat ) - EVENT( EV_Touch, idPlat::Event_Touch ) - EVENT( EV_TeamBlocked, idPlat::Event_TeamBlocked ) - EVENT( EV_PartBlocked, idPlat::Event_PartBlocked ) -END_CLASS - -/* -=============== -idPlat::idPlat -=============== -*/ -idPlat::idPlat( void ) { - trigger = NULL; - localTriggerOrigin.Zero(); - localTriggerAxis.Identity(); -} - -/* -=============== -idPlat::~idPlat -=============== -*/ -idPlat::~idPlat( void ) { - if ( trigger ) { - delete trigger; - } -} - -/* -=============== -idPlat::Save -=============== -*/ -void idPlat::Save( idSaveGame *savefile ) const { - savefile->WriteClipModel( trigger ); - savefile->WriteVec3( localTriggerOrigin ); - savefile->WriteMat3( localTriggerAxis ); -} - -/* -=============== -idPlat::Restore -=============== -*/ -void idPlat::Restore( idRestoreGame *savefile ) { - savefile->ReadClipModel( trigger ); - savefile->ReadVec3( localTriggerOrigin ); - savefile->ReadMat3( localTriggerAxis ); -} - -/* -=============== -idPlat::Spawn -=============== -*/ -void idPlat::Spawn( void ) -{ - float lip; - float height; - float time; - float speed; - float accel; - float decel; - bool noTouch; - - spawnArgs.GetFloat( "speed", "100", speed ); - spawnArgs.GetFloat( "damage", "0", damage ); - spawnArgs.GetFloat( "wait", "1", wait ); - spawnArgs.GetFloat( "lip", "8", lip ); - spawnArgs.GetFloat( "accel_time", "0.25", accel ); - spawnArgs.GetFloat( "decel_time", "0.25", decel ); - - // create second position - if ( !spawnArgs.GetFloat( "height", "0", height ) ) { - height = ( GetPhysics()->GetBounds()[1][2] - GetPhysics()->GetBounds()[0][2] ) - lip; - } - - spawnArgs.GetBool( "no_touch", "0", noTouch ); - - // pos1 is the rest (bottom) position, pos2 is the top - pos2 = GetPhysics()->GetOrigin(); - pos1 = pos2; - pos1[2] -= height; - - if ( spawnArgs.GetFloat( "time", "1", time ) ) { - InitTime( pos1, pos2, time, accel, decel ); - } else { - InitSpeed( pos1, pos2, speed, accel, decel ); - } - - SetMoverState( MOVER_POS1, gameLocal.time ); - UpdateVisuals(); - - // spawn the trigger if one hasn't been custom made - if ( !noTouch ) { - // spawn trigger - SpawnPlatTrigger( pos1 ); - } -} - -/* -================ -idPlat::Think -================ -*/ -void idPlat::Think( void ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - idMover_Binary::Think(); - - if ( thinkFlags & TH_PHYSICS ) { - // update trigger position - if ( GetMasterPosition( masterOrigin, masterAxis ) ) { - if ( trigger ) { - trigger->Link( gameLocal.clip, this, 0, masterOrigin + localTriggerOrigin * masterAxis, localTriggerAxis * masterAxis ); - } - } - } -} - -/* -================ -idPlat::PreBind -================ -*/ -void idPlat::PreBind( void ) { - idMover_Binary::PreBind(); -} - -/* -================ -idPlat::PostBind -================ -*/ -void idPlat::PostBind( void ) { - idMover_Binary::PostBind(); - GetLocalTriggerPosition( trigger ); -} - -/* -================ -idPlat::GetLocalTriggerPosition -================ -*/ -void idPlat::GetLocalTriggerPosition( const idClipModel *trigger ) { - idVec3 origin; - idMat3 axis; - - if ( !trigger ) { - return; - } - - GetMasterPosition( origin, axis ); - localTriggerOrigin = ( trigger->GetOrigin() - origin ) * axis.Transpose(); - localTriggerAxis = trigger->GetAxis() * axis.Transpose(); -} - -/* -============== -idPlat::SpawnPlatTrigger -=============== -*/ -void idPlat::SpawnPlatTrigger( idVec3 &pos ) { - idBounds bounds; - idVec3 tmin; - idVec3 tmax; - - // the middle trigger will be a thin trigger just - // above the starting position - - bounds = GetPhysics()->GetBounds(); - - tmin[0] = bounds[0][0] + 33; - tmin[1] = bounds[0][1] + 33; - tmin[2] = bounds[0][2]; - - tmax[0] = bounds[1][0] - 33; - tmax[1] = bounds[1][1] - 33; - tmax[2] = bounds[1][2] + 8; - - if ( tmax[0] <= tmin[0] ) { - tmin[0] = ( bounds[0][0] + bounds[1][0] ) * 0.5f; - tmax[0] = tmin[0] + 1; - } - if ( tmax[1] <= tmin[1] ) { - tmin[1] = ( bounds[0][1] + bounds[1][1] ) * 0.5f; - tmax[1] = tmin[1] + 1; - } - - trigger = new idClipModel( idTraceModel( idBounds( tmin, tmax ) ) ); - trigger->Link( gameLocal.clip, this, 255, GetPhysics()->GetOrigin(), mat3_identity ); - trigger->SetContents( CONTENTS_TRIGGER ); -} - -/* -============== -idPlat::Event_Touch -=============== -*/ -void idPlat::Event_Touch( idEntity *other, trace_t *trace ) { - if ( !other->IsType( idPlayer::Type ) ) { - return; - } - - if ( ( GetMoverState() == MOVER_POS1 ) && trigger && ( trace->c.id == trigger->GetId() ) && ( other->health > 0 ) ) { - Use_BinaryMover( other ); - } -} - -/* -================ -idPlat::Event_TeamBlocked -================ -*/ -void idPlat::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { - // reverse direction - Use_BinaryMover( activatedBy.GetEntity() ); -} - -/* -=============== -idPlat::Event_PartBlocked -=============== -*/ -void idPlat::Event_PartBlocked( idEntity *blockingEntity ) { - if ( damage > 0.0f ) { - blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); - } -} - - -/* -=============================================================================== - -idMover_Periodic - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idMover_Periodic ) - EVENT( EV_TeamBlocked, idMover_Periodic::Event_TeamBlocked ) - EVENT( EV_PartBlocked, idMover_Periodic::Event_PartBlocked ) -END_CLASS - -/* -=============== -idMover_Periodic::idMover_Periodic -=============== -*/ -idMover_Periodic::idMover_Periodic( void ) { - damage = 0.0f; - fl.neverDormant = false; -} - -/* -=============== -idMover_Periodic::Spawn -=============== -*/ -void idMover_Periodic::Spawn( void ) { - spawnArgs.GetFloat( "damage", "0", damage ); - if ( !spawnArgs.GetBool( "solid", "1" ) ) { - GetPhysics()->SetContents( 0 ); - } -} - -/* -=============== -idMover_Periodic::Save -=============== -*/ -void idMover_Periodic::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( damage ); - savefile->WriteStaticObject( physicsObj ); -} - -/* -=============== -idMover_Periodic::Restore -=============== -*/ -void idMover_Periodic::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( damage ); - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); -} - -/* -================ -idMover_Periodic::Think -================ -*/ -void idMover_Periodic::Think( void ) { - // if we are completely closed off from the player, don't do anything at all - if ( CheckDormant() ) { - return; - } - - RunPhysics(); - Present(); -} - -/* -=============== -idMover_Periodic::Event_TeamBlocked -=============== -*/ -void idMover_Periodic::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) { -} - -/* -=============== -idMover_Periodic::Event_PartBlocked -=============== -*/ -void idMover_Periodic::Event_PartBlocked( idEntity *blockingEntity ) { - if ( damage > 0.0f ) { - blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT ); - } -} - -/* -================ -idMover_Periodic::WriteToSnapshot -================ -*/ -void idMover_Periodic::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); -} - -/* -================ -idMover_Periodic::ReadFromSnapshot -================ -*/ -void idMover_Periodic::ReadFromSnapshot( const idBitMsgDelta &msg ) { - physicsObj.ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - - -/* -=============================================================================== - -idRotater - -=============================================================================== -*/ - -CLASS_DECLARATION( idMover_Periodic, idRotater ) - EVENT( EV_Activate, idRotater::Event_Activate ) -END_CLASS - -/* -=============== -idRotater::idRotater -=============== -*/ -idRotater::idRotater( void ) : - nextTriggerDirectionIsForward(true) -{ - activatedBy = this; -} - -/* -=============== -idRotater::Spawn -=============== -*/ -void idRotater::Spawn( void ) -{ - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "nopush" ) ) { - physicsObj.SetPusher( 0 ); - } - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, gameLocal.time, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, GetPhysics()->GetAxis().ToAngles(), ang_zero, ang_zero ); - SetPhysics( &physicsObj ); - - if ( spawnArgs.GetBool( "start_on" ) ) { - ProcessEvent( &EV_Activate, this ); - } -} - -/* -=============== -idRotater::Save -=============== -*/ -void idRotater::Save( idSaveGame *savefile ) const -{ - activatedBy.Save( savefile ); - savefile->WriteBool(nextTriggerDirectionIsForward); -} - -/* -=============== -idRotater::Restore -=============== -*/ -void idRotater::Restore( idRestoreGame *savefile ) -{ - activatedBy.Restore( savefile ); - savefile->ReadBool(nextTriggerDirectionIsForward); -} - -/* -=============== -idRotater::Event_Activate -=============== -*/ -void idRotater::Event_Activate( idEntity *activator ) -{ - activatedBy = activator; - - bool isRotating = spawnArgs.GetBool("rotate"); - - // greebo: If rotate direction inversion is activated, toggle the boolean, else leave it alone - if (!isRotating && spawnArgs.GetBool("invert_on_trigger", "0")) - { - nextTriggerDirectionIsForward = !nextTriggerDirectionIsForward; - } - - // greebo: Invert the "rotate" spawnarg, this toggles the rotation itself - spawnArgs.Set("rotate", isRotating ? "0" : "1"); - - // Start or stop the rotation, based on the spawnargs (forward direction) - SetRotationFromSpawnargs(nextTriggerDirectionIsForward); -} - -void idRotater::SetRotationFromSpawnargs(bool forward) -{ - idAngles delta(0,0,0); - - if (spawnArgs.GetBool("rotate")) - { - // We should be rotating, read the parameters - float speed = spawnArgs.GetFloat("speed", "100"); - bool x_axis = spawnArgs.GetBool("x_axis", "0"); - bool y_axis = spawnArgs.GetBool("y_axis", "0"); - bool z_axis = !x_axis && !y_axis; - bool applyDirectionFix = spawnArgs.GetBool("apply_direction_fix", "0"); - - // Invert the speed if the direction boolean is false - if (!forward) - { - speed *= -1; - } - - if (applyDirectionFix) - { - idAngles curAngles = physicsObj.GetAxis().ToAngles().Normalize360(); - idAngles spawnAngles = spawnArgs.GetMatrix("rotation", "1 0 0 0 1 0 0 0 1").ToAngles().Normalize360(); - - // greebo: Euler angles are ambiguous - it might happen that a positive speed value - // applied to "roll" means something different than it would have meant at spawn time - // To yield the same orientation with a different set of angles one usually has - // to employ two 180 degree rotations - check this. If anybody has a more elegant way of checking that, let me know! - if (x_axis && fabs(spawnAngles[1] - curAngles[1]) == 180 && fabs(spawnAngles[0] - curAngles[0]) == 180) - { - speed *= -1; - } - else if (y_axis && fabs(spawnAngles[1] - curAngles[1]) == 180 && fabs(spawnAngles[2] - curAngles[2]) == 180) - { - speed *= -1; - } - else if (z_axis && fabs(spawnAngles[0] - curAngles[0]) == 180 && fabs(spawnAngles[2] - curAngles[2]) == 180) - { - speed *= -1; - } - } - - // Set the axis of rotation - if (x_axis) // roll - { - delta[2] = speed; - } - else if (y_axis) // pitch - { - delta[0] = speed; - } - else // z_axis == yaw - { - delta[1] = speed; - } - } - - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, physicsObj.GetAxis().ToAngles().Normalize360(), delta, ang_zero ); -} - -void idRotater::SetDirection(bool forward) -{ - // Read the rotation parameters again, but consider the direction - SetRotationFromSpawnargs(forward); -} - -/* -=============================================================================== - -idBobber - -=============================================================================== -*/ - -CLASS_DECLARATION( idMover_Periodic, idBobber ) -END_CLASS - -/* -=============== -idBobber::idBobber -=============== -*/ -idBobber::idBobber( void ) { -} - -/* -=============== -idBobber::Spawn -=============== -*/ -void idBobber::Spawn( void ) -{ - float speed; - float height; - float phase; - bool x_axis; - bool y_axis; - idVec3 delta; - - spawnArgs.GetFloat( "speed", "4", speed ); - spawnArgs.GetFloat( "height", "32", height ); - spawnArgs.GetFloat( "phase", "0", phase ); - spawnArgs.GetBool( "x_axis", "0", x_axis ); - spawnArgs.GetBool( "y_axis", "0", y_axis ); - - // set the axis of bobbing - delta = vec3_origin; - if ( x_axis ) { - delta[ 0 ] = height; - } else if ( y_axis ) { - delta[ 1 ] = height; - } else { - delta[ 2 ] = height; - } - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "nopush" ) ) { - physicsObj.SetPusher( 0 ); - } - physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(phase * 1000), static_cast(speed * 500), GetPhysics()->GetOrigin(), delta * 2.0f, vec3_origin ); - SetPhysics( &physicsObj ); -} - - -/* -=============================================================================== - -idPendulum - -=============================================================================== -*/ - -CLASS_DECLARATION( idMover_Periodic, idPendulum ) -END_CLASS - -/* -=============== -idPendulum::idPendulum -=============== -*/ -idPendulum::idPendulum( void ) { -} - -/* -=============== -idPendulum::Spawn -=============== -*/ -void idPendulum::Spawn( void ) -{ - float speed; - float freq; - float length; - float phase; - - spawnArgs.GetFloat( "speed", "30", speed ); - spawnArgs.GetFloat( "phase", "0", phase ); - - if ( spawnArgs.GetFloat( "freq", "", freq ) ) { - if ( freq <= 0.0f ) { - gameLocal.Error( "Invalid frequency on entity '%s'", GetName() ); - } - } else { - // find pendulum length - length = idMath::Fabs( GetPhysics()->GetBounds()[0][2] ); - if ( length < 8 ) { - length = 8; - } - - freq = 1 / ( idMath::TWO_PI ) * idMath::Sqrt( g_gravity.GetFloat() / ( 3 * length ) ); - } - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "nopush" ) ) { - physicsObj.SetPusher( 0 ); - } - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); - physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), static_cast(phase * 1000), static_cast(500/freq), GetPhysics()->GetAxis().ToAngles(), idAngles( 0, 0, speed * 2.0f ), ang_zero ); - SetPhysics( &physicsObj ); -} - - -/* -=============================================================================== - -idBobber - -=============================================================================== -*/ - -CLASS_DECLARATION( idMover_Periodic, idRiser ) -EVENT( EV_Activate, idRiser::Event_Activate ) -END_CLASS - -/* -=============== -idRiser::idRiser -=============== -*/ -idRiser::idRiser( void ) { -} - -/* -=============== -idRiser::Spawn -=============== -*/ -void idRiser::Spawn( void ) -{ - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - - physicsObj.SetClipMask( MASK_SOLID ); - if ( !spawnArgs.GetBool( "solid", "1" ) ) { - physicsObj.SetContents( 0 ); - } - if ( !spawnArgs.GetBool( "nopush" ) ) { - physicsObj.SetPusher( 0 ); - } - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, GetPhysics()->GetOrigin(), vec3_origin, vec3_origin ); - SetPhysics( &physicsObj ); -} - -/* -================ -idRiser::Event_Activate -================ -*/ -void idRiser::Event_Activate( idEntity *activator ) { - - if ( !IsHidden() && spawnArgs.GetBool("hide") ) { - Hide(); - } else { - Show(); - float time; - float height; - idVec3 delta; - - spawnArgs.GetFloat( "time", "4", time ); - spawnArgs.GetFloat( "height", "32", height ); - - delta = vec3_origin; - delta[ 2 ] = height; - - physicsObj.SetLinearExtrapolation( EXTRAPOLATION_LINEAR, gameLocal.time, static_cast(time * 1000), physicsObj.GetOrigin(), delta, vec3_origin ); - } -} - - diff --git a/game/mover.h b/game/mover.h deleted file mode 100644 index 3407cccb1..000000000 --- a/game/mover.h +++ /dev/null @@ -1,448 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_MOVER_H__ -#define __GAME_MOVER_H__ - -extern const idEventDef EV_TeamBlocked; -extern const idEventDef EV_PartBlocked; -extern const idEventDef EV_ReachedPos; -extern const idEventDef EV_ReachedAng; - -/* -=============================================================================== - - General movers. - -=============================================================================== -*/ - -class idMover : public idEntity { -public: - CLASS_PROTOTYPE( idMover ); - - idMover( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - virtual void Hide( void ); - virtual void Show( void ); - - void SetPortalState( bool open ); - - bool IsBlocked( void ); - - ID_INLINE idPhysics_Parametric* GetMoverPhysics() - { - return &physicsObj; - } - - -protected: - typedef enum { - ACCELERATION_STAGE, - LINEAR_STAGE, - DECELERATION_STAGE, - FINISHED_STAGE - } moveStage_t; - - typedef enum { - MOVER_NONE, - MOVER_ROTATING, - MOVER_MOVING, - MOVER_SPLINE - } moverCommand_t; - - // - // mover directions. make sure to change script/doom_defs.script if you add any, or change their order - // - typedef enum { - DIR_UP = -1, - DIR_DOWN = -2, - DIR_LEFT = -3, - DIR_RIGHT = -4, - DIR_FORWARD = -5, - DIR_BACK = -6, - DIR_REL_UP = -7, - DIR_REL_DOWN = -8, - DIR_REL_LEFT = -9, - DIR_REL_RIGHT = -10, - DIR_REL_FORWARD = -11, - DIR_REL_BACK = -12 - } moverDir_t; - - typedef struct { - moveStage_t stage; - int acceleration; - int movetime; - int deceleration; - idVec3 dir; - } moveState_t; - - typedef struct { - moveStage_t stage; - int acceleration; - int movetime; - int deceleration; - idAngles rot; - } rotationState_t; - - idPhysics_Parametric physicsObj; - - void Event_OpenPortal( void ); - void Event_ClosePortal( void ); - virtual void OpenPortal(); - virtual void ClosePortal(); - void Event_PartBlocked( idEntity *blockingEntity ); - virtual void OnTeamBlocked(idEntity* blockedEntity, idEntity* blockingEntity); - - void MoveToPos( const idVec3 &pos); - void MoveToLocalPos( const idVec3 &pos ); - - void UpdateMoveSound( moveStage_t stage ); - void UpdateRotationSound( moveStage_t stage ); - void SetGuiStates( const char *state ); - void FindGuiTargets( void ); - void SetGuiState( const char *key, const char *val ) const; - - virtual void DoneMoving( void ); - virtual void DoneRotating( void ); - virtual void BeginMove( idThread *thread = NULL ); - virtual void BeginRotation( idThread *thread, bool stopwhendone ); - - /** - * greebo: Calculates the fraction of the move_time (the time it takes to complete the whole - * movement) based on the current state. For standard-movers, this does nothing (returns 1), - * but subclasses might do more complicated things based on the current rotation state, - * like BinaryFrobMovers do. - * - * Note: This is an internal function used by BeginRotation() only - */ - virtual float GetMoveTimeFraction(); - - moveState_t move; - -protected: - rotationState_t rot; - - int move_thread; - int rotate_thread; - idAngles dest_angles; - idAngles angle_delta; - idVec3 dest_position; - idVec3 move_delta; - float move_speed; - int move_time; - int deceltime; - int acceltime; - bool stopRotation; - bool useSplineAngles; - idEntityPtr splineEnt; - moverCommand_t lastCommand; - float damage; - - qhandle_t areaPortal; // 0 = no portal - - idList< idEntityPtr > guiTargets; - - void VectorForDir( float dir, idVec3 &vec ); - idCurve_Spline *GetSpline( idEntity *splineEntity ) const; - -public: - void Event_SetCallback( void ); - void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity ); - void Event_StopMoving( void ); - void Event_StopRotating( void ); - void Event_UpdateMove( void ); - void Event_UpdateRotation( void ); - void Event_SetMoveSpeed( float speed ); - void Event_SetMoveTime( float time ); - void Event_SetDecelerationTime( float time ); - void Event_SetAccellerationTime( float time ); - void Event_MoveTo( idEntity *ent ); - void Event_MoveToPos( idVec3 &pos ); - void Event_MoveDir( float angle, float distance ); - void Event_MoveAccelerateTo( float speed, float time ); - void Event_MoveDecelerateTo( float speed, float time ); - void Event_RotateDownTo( int axis, float angle ); - void Event_RotateUpTo( int axis, float angle ); - void Event_RotateTo( idAngles &angles ); - void Event_Rotate( idAngles &angles ); - void Event_RotateOnce( idAngles &angles ); - void Event_Bob( float speed, float phase, idVec3 &depth ); - void Event_Sway( float speed, float phase, idAngles &depth ); - void Event_SetAccelSound( const char *sound ); - void Event_SetDecelSound( const char *sound ); - void Event_SetMoveSound( const char *sound ); - void Event_FindGuiTargets( void ); - void Event_InitGuiTargets( void ); - void Event_EnableSplineAngles( void ); - void Event_DisableSplineAngles( void ); - void Event_RemoveInitialSplineAngles( void ); - void Event_StartSpline( idEntity *splineEntity ); - void Event_StopSpline( void ); - void Event_Activate( idEntity *activator ); - void Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng ); - void Event_IsMoving( void ); - void Event_IsRotating( void ); -}; - -class idSplinePath : public idEntity { -public: - CLASS_PROTOTYPE( idSplinePath ); - - idSplinePath(); - - void Spawn( void ); -}; - - -struct floorInfo_s { - idVec3 pos; - idStr door; - int floor; -}; - -/* -=============================================================================== - - Binary movers. - -=============================================================================== -*/ - -typedef enum { - MOVER_POS1, - MOVER_POS2, - MOVER_1TO2, - MOVER_2TO1 -} moverState_t; - -class idMover_Binary : public idEntity { -public: - CLASS_PROTOTYPE( idMover_Binary ); - - idMover_Binary(); - ~idMover_Binary(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void PreBind( void ); - virtual void PostBind( void ); - - void Enable( bool b ); - void InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime ); - void InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime ); - void GotoPosition1( void ); - void GotoPosition2( void ); - void Use_BinaryMover( idEntity *activator ); - void SetGuiStates( const char *state ); - void UpdateBuddies( int val ); - idMover_Binary * GetActivateChain( void ) const { return activateChain; } - idMover_Binary * GetMoveMaster( void ) const { return moveMaster; } - void BindTeam( idEntity *bindTo ); - void SetBlocked( bool b ); - bool IsBlocked( void ); - idEntity * GetActivator( void ) const; - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - void SetPortalState( bool open ); - -protected: - idVec3 pos1; - idVec3 pos2; - moverState_t moverState; - idMover_Binary * moveMaster; - idMover_Binary * activateChain; - int soundPos1; - int sound1to2; - int sound2to1; - int soundPos2; - int soundLoop; - float wait; - float damage; - int duration; - int accelTime; - int decelTime; - idEntityPtr activatedBy; - int stateStartTime; - idStr team; - bool enabled; - int move_thread; - int updateStatus; // 1 = lock behaviour, 2 = open close status - idStrList buddies; - idPhysics_Parametric physicsObj; - qhandle_t areaPortal; // 0 = no portal - bool blocked; - idList< idEntityPtr > guiTargets; - - void MatchActivateTeam( moverState_t newstate, int time ); - void JoinActivateTeam( idMover_Binary *master ); - - void UpdateMoverSound( moverState_t state ); - void SetMoverState( moverState_t newstate, int time ); - moverState_t GetMoverState( void ) const { return moverState; } - void FindGuiTargets( void ); - void SetGuiState( const char *key, const char *val ) const; - - void Event_SetCallback( void ); - void Event_ReturnToPos1( void ); - void Event_Use_BinaryMover( idEntity *activator ); - void Event_Reached_BinaryMover( void ); - void Event_MatchActivateTeam( moverState_t newstate, int time ); - void Event_Enable( void ); - void Event_Disable( void ); - void Event_OpenPortal( void ); - void Event_ClosePortal( void ); - void Event_FindGuiTargets( void ); - void Event_InitGuiTargets( void ); - - static void GetMovedir( float dir, idVec3 &movedir ); -}; - -class idPlat : public idMover_Binary { -public: - CLASS_PROTOTYPE( idPlat ); - - idPlat( void ); - ~idPlat( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - virtual void PreBind( void ); - virtual void PostBind( void ); - -private: - idClipModel * trigger; - idVec3 localTriggerOrigin; - idMat3 localTriggerAxis; - - void GetLocalTriggerPosition( const idClipModel *trigger ); - void SpawnPlatTrigger( idVec3 &pos ); - - void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ); - void Event_PartBlocked( idEntity *blockingEntity ); - void Event_Touch( idEntity *other, trace_t *trace ); -}; - - -/* -=============================================================================== - - Special periodic movers. - -=============================================================================== -*/ - -class idMover_Periodic : public idEntity { -public: - CLASS_PROTOTYPE( idMover_Periodic ); - - idMover_Periodic( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - -protected: - idPhysics_Parametric physicsObj; - float damage; - - void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ); - void Event_PartBlocked( idEntity *blockingEntity ); -}; - -class idRotater : public idMover_Periodic { -public: - CLASS_PROTOTYPE( idRotater ); - - idRotater( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // greebo: Allows callers to invert the rotation direction - void SetDirection(bool forward); - -private: - // Reads the rotation axis and speed from the spawnargs and starts/stops to rotate - void SetRotationFromSpawnargs(bool forward); - - idEntityPtr activatedBy; - - // If true, the next activation will let the mover rotate in forward direction - // this is only used when "invert_on_trigger" is set to "1" - bool nextTriggerDirectionIsForward; - - void Event_Activate( idEntity *activator ); -}; - -class idBobber : public idMover_Periodic { -public: - CLASS_PROTOTYPE( idBobber ); - - idBobber( void ); - - void Spawn( void ); - -private: -}; - -class idPendulum : public idMover_Periodic { -public: - CLASS_PROTOTYPE( idPendulum ); - - idPendulum( void ); - - void Spawn( void ); - -private: -}; - -class idRiser : public idMover_Periodic { -public: - CLASS_PROTOTYPE( idRiser ); - - idRiser( void ); - - void Spawn( void ); - -private: - void Event_Activate( idEntity *activator ); -}; - -#endif /* !__GAME_MOVER_H__ */ diff --git a/game/multiplayergame.cpp b/game/multiplayergame.cpp deleted file mode 100644 index 42043f69a..000000000 --- a/game/multiplayergame.cpp +++ /dev/null @@ -1,3399 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -// could be a problem if players manage to go down sudden deaths till this .. oh well -#define LASTMAN_NOLIVES -20 - -idCVar g_spectatorChat( "g_spectatorChat", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "let spectators talk to everyone during game" ); - -// global sounds transmitted by index - 0 .. SND_COUNT -// sounds in this list get precached on MP start -const char *idMultiplayerGame::GlobalSoundStrings[] = { - "sound/feedback/voc_youwin.wav", - "sound/feedback/voc_youlose.wav", - "sound/feedback/fight.wav", - "sound/feedback/vote_now.wav", - "sound/feedback/vote_passed.wav", - "sound/feedback/vote_failed.wav", - "sound/feedback/three.wav", - "sound/feedback/two.wav", - "sound/feedback/one.wav", - "sound/feedback/sudden_death.wav", -}; - -// handy verbose -const char *idMultiplayerGame::GameStateStrings[] = { - "INACTIVE", - "WARMUP", - "COUNTDOWN", - "GAMEON", - "SUDDENDEATH", - "GAMEREVIEW", - "NEXTGAME" -}; - -const char *idMultiplayerGame::MPGuis[] = { - "guis/mphud.gui", - "guis/mpmain.gui", - "guis/mpmsgmode.gui", - "guis/netmenu.gui", - NULL -}; - -const char *idMultiplayerGame::ThrottleVars[] = { - "ui_spectate", - "ui_ready", - "ui_team", - NULL -}; - -const char *idMultiplayerGame::ThrottleVarsInEnglish[] = { - "#str_06738", - "#str_06737", - "#str_01991", - NULL -}; - -const int idMultiplayerGame::ThrottleDelay[] = { - 8, - 5, - 5 -}; - -/* -================ -idMultiplayerGame::idMultiplayerGame -================ -*/ -idMultiplayerGame::idMultiplayerGame() { - scoreBoard = NULL; - spectateGui = NULL; - guiChat = NULL; - mainGui = NULL; - mapList = NULL; - msgmodeGui = NULL; - lastGameType = GAME_SP; - Clear(); -} - -/* -================ -idMultiplayerGame::Shutdown -================ -*/ -void idMultiplayerGame::Shutdown( void ) { - Clear(); -} - -/* -================ -idMultiplayerGame::SetMenuSkin -================ -*/ -void idMultiplayerGame::SetMenuSkin( void ) { - // skins - idStr str = cvarSystem->GetCVarString( "mod_validSkins" ); - idStr uiSkin = cvarSystem->GetCVarString( "ui_skin" ); - idStr skin; - int skinId = 1; - int count = 1; - while ( str.Length() ) { - int n = str.Find( ";" ); - if ( n >= 0 ) { - skin = str.Left( n ); - str = str.Right( str.Length() - n - 1 ); - } else { - skin = str; - str = ""; - } - if ( skin.Icmp( uiSkin ) == 0 ) { - skinId = count; - } - count++; - } - - for ( int i = 0; i < count; i++ ) { - mainGui->SetStateInt( va( "skin%i", i+1 ), 0 ); - } - mainGui->SetStateInt( va( "skin%i", skinId ), 1 ); -} - -/* -================ -idMultiplayerGame::Reset -================ -*/ -void idMultiplayerGame::Reset() { - Clear(); - assert( !scoreBoard && !spectateGui && !guiChat && !mainGui && !mapList ); - scoreBoard = uiManager->FindGui( "guis/scoreboard.gui", true, false, true ); - spectateGui = uiManager->FindGui( "guis/spectate.gui", true, false, true ); - guiChat = uiManager->FindGui( "guis/chat.gui", true, false, true ); - mainGui = uiManager->FindGui( "guis/mpmain.gui", true, false, true ); - mapList = uiManager->AllocListGUI( ); - mapList->Config( mainGui, "mapList" ); - // set this GUI so that our Draw function is still called when it becomes the active/fullscreen GUI - mainGui->SetStateBool( "gameDraw", true ); - mainGui->SetKeyBindingNames(); - mainGui->SetStateInt( "com_machineSpec", cvarSystem->GetCVarInteger( "com_machineSpec" ) ); - SetMenuSkin(); - msgmodeGui = uiManager->FindGui( "guis/mpmsgmode.gui", true, false, true ); - msgmodeGui->SetStateBool( "gameDraw", true ); - ClearGuis(); - ClearChatData(); - warmupEndTime = 0; -} - -/* -================ -idMultiplayerGame::ServerClientConnect -================ -*/ -void idMultiplayerGame::ServerClientConnect( int clientNum ) { - memset( &playerState[ clientNum ], 0, sizeof( playerState[ clientNum ] ) ); -} - -/* -================ -idMultiplayerGame::SpawnPlayer -================ -*/ -void idMultiplayerGame::SpawnPlayer( int clientNum ) { - - bool ingame = playerState[ clientNum ].ingame; - - memset( &playerState[ clientNum ], 0, sizeof( playerState[ clientNum ] ) ); - if ( !gameLocal.isClient ) { - idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); - p->spawnedTime = gameLocal.time; - if ( gameLocal.gameType == GAME_TDM ) { - SwitchToTeam( clientNum, -1, p->team ); - } - p->tourneyRank = 0; - if ( gameLocal.gameType == GAME_TOURNEY && gameState == GAMEON ) { - p->tourneyRank++; - } - playerState[ clientNum ].ingame = ingame; - } -} - -/* -================ -idMultiplayerGame::Clear -================ -*/ -void idMultiplayerGame::Clear() { - int i; - - gameState = INACTIVE; - nextState = INACTIVE; - pingUpdateTime = 0; - vote = VOTE_NONE; - voteTimeOut = 0; - voteExecTime = 0; - nextStateSwitch = 0; - matchStartedTime = 0; - currentTourneyPlayer[ 0 ] = -1; - currentTourneyPlayer[ 1 ] = -1; - one = two = three = false; - memset( &playerState, 0 , sizeof( playerState ) ); - lastWinner = -1; - currentMenu = 0; - bCurrentMenuMsg = false; - nextMenu = 0; - pureReady = false; - scoreBoard = NULL; - spectateGui = NULL; - guiChat = NULL; - mainGui = NULL; - msgmodeGui = NULL; - if ( mapList ) { - uiManager->FreeListGUI( mapList ); - mapList = NULL; - } - fragLimitTimeout = 0; - memset( &switchThrottle, 0, sizeof( switchThrottle ) ); - voiceChatThrottle = 0; - for ( i = 0; i < NUM_CHAT_NOTIFY; i++ ) { - chatHistory[ i ].line.Clear(); - } - warmupText.Clear(); - voteValue.Clear(); - voteString.Clear(); - startFragLimit = -1; -} - -/* -================ -idMultiplayerGame::ClearGuis -================ -*/ -void idMultiplayerGame::ClearGuis() { - int i; - - for ( i = 0; i < MAX_CLIENTS; i++ ) { - scoreBoard->SetStateString( va( "player%i",i+1 ), "" ); - scoreBoard->SetStateString( va( "player%i_score", i+1 ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_tscore", i+1 ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_score", i+1 ), "" ); - scoreBoard->SetStateString( va( "player%i_wins", i+1 ), "" ); - scoreBoard->SetStateString( va( "player%i_status", i+1 ), "" ); - scoreBoard->SetStateInt( va( "rank%i", i+1 ), 0 ); - scoreBoard->SetStateInt( "rank_self", 0 ); - - idPlayer *player = static_cast( gameLocal.entities[ i ] ); - if ( !player || !player->hud ) { - continue; - } - player->hud->SetStateString( va( "player%i",i+1 ), "" ); - player->hud->SetStateString( va( "player%i_score", i+1 ), "" ); - player->hud->SetStateString( va( "player%i_ready", i+1 ), "" ); - scoreBoard->SetStateInt( va( "rank%i", i+1 ), 0 ); - player->hud->SetStateInt( "rank_self", 0 ); - } -} - -/* -================ -idMultiplayerGame::UpdatePlayerRanks -================ -*/ -void idMultiplayerGame::UpdatePlayerRanks() { - int i, j, k; - idPlayer *players[MAX_CLIENTS]; - idEntity *ent; - idPlayer *player; - - memset( players, 0, sizeof( players ) ); - numRankedPlayers = 0; - - for ( i = 0; i < gameLocal.numClients; i++ ) { - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - player = static_cast< idPlayer * >( ent ); - if ( !CanPlay( player ) ) { - continue; - } - if ( gameLocal.gameType == GAME_TOURNEY ) { - if ( i != currentTourneyPlayer[ 0 ] && i != currentTourneyPlayer[ 1 ] ) { - continue; - } - } - if ( gameLocal.gameType == GAME_LASTMAN && playerState[ i ].fragCount == LASTMAN_NOLIVES ) { - continue; - } - for ( j = 0; j < numRankedPlayers; j++ ) { - bool insert = false; - if ( gameLocal.gameType == GAME_TDM ) { - if ( player->team != players[ j ]->team ) { - if ( playerState[ i ].teamFragCount > playerState[ players[ j ]->entityNumber ].teamFragCount ) { - // team scores - insert = true; - } else if ( playerState[ i ].teamFragCount == playerState[ players[ j ]->entityNumber ].teamFragCount && player->team < players[ j ]->team ) { - // at equal scores, sort by team number - insert = true; - } - } else if ( playerState[ i ].fragCount > playerState[ players[ j ]->entityNumber ].fragCount ) { - // in the same team, sort by frag count - insert = true; - } - } else { - insert = ( playerState[ i ].fragCount > playerState[ players[ j ]->entityNumber ].fragCount ); - } - if ( insert ) { - for ( k = numRankedPlayers; k > j; k-- ) { - players[ k ] = players[ k-1 ]; - } - players[ j ] = player; - break; - } - } - if ( j == numRankedPlayers ) { - players[ numRankedPlayers ] = player; - } - numRankedPlayers++; - } - - memcpy( rankedPlayers, players, sizeof( players ) ); -} - - -/* -================ -idMultiplayerGame::UpdateRankColor -================ -*/ -void idMultiplayerGame::UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec ) { - for ( int j = 1; j < 4; j++ ) { - gui->SetStateFloat( va( mask, i, j ), vec[ j - 1 ] ); - } -} - -/* -================ -idMultiplayerGame::UpdateScoreboard -================ -*/ -void idMultiplayerGame::UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player ) { - int i, j, iline, k; - idStr gameinfo; - idStr livesinfo; - idStr timeinfo; - idEntity *ent; - idPlayer *p; - int value; - - scoreBoard->SetStateString( "scoretext", gameLocal.gameType == GAME_LASTMAN ? gameLocal.m_I18N->Translate( "#str_04242" ) : gameLocal.m_I18N->Translate( "#str_04243" ) ); - - iline = 0; // the display lines - if ( gameState != WARMUP ) { - for ( i = 0; i < numRankedPlayers; i++ ) { - // ranked player - iline++; - scoreBoard->SetStateString( va( "player%i", iline ), rankedPlayers[ i ]->GetUserInfo()->GetString( "ui_name" ) ); - if ( gameLocal.gameType == GAME_TDM ) { - value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); - scoreBoard->SetStateInt( va( "player%i_tdm_score", iline ), value ); - value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].teamFragCount ); - scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), va( "/ %i", value ) ); - scoreBoard->SetStateString( va( "player%i_score", iline ), "" ); - } else { - value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); - scoreBoard->SetStateInt( va( "player%i_score", iline ), value ); - scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); - } - value = idMath::ClampInt( 0, MP_PLAYER_MAXWINS, playerState[ rankedPlayers[ i ]->entityNumber ].wins ); - scoreBoard->SetStateInt( va( "player%i_wins", iline ), value ); - scoreBoard->SetStateInt( va( "player%i_ping", iline ), playerState[ rankedPlayers[ i ]->entityNumber ].ping ); - // set the color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); - UpdateRankColor( scoreBoard, "rank%i_color%i", iline, rankedPlayers[ i ]->colorBar ); - if ( rankedPlayers[ i ] == player ) { - // highlight who we are - scoreBoard->SetStateInt( "rank_self", iline ); - } - } - } - - // if warmup, this draws everyone, otherwise it goes over spectators only - // when doing warmup we loop twice to draw ready/not ready first *then* spectators - // NOTE: in tourney, shows spectators according to their playing rank order? - for ( k = 0; k < ( gameState == WARMUP ? 2 : 1 ); k++ ) { - for ( i = 0; i < MAX_CLIENTS; i++ ) { - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( gameState != WARMUP ) { - // check he's not covered by ranks already - for ( j = 0; j < numRankedPlayers; j++ ) { - if ( ent == rankedPlayers[ j ] ) { - break; - } - } - if ( j != numRankedPlayers ) { - continue; - } - } - p = static_cast< idPlayer * >( ent ); - if ( gameState == WARMUP ) { - if ( k == 0 && p->spectating ) { - continue; - } - if ( k == 1 && !p->spectating ) { - continue; - } - } - - iline++; - if ( !playerState[ i ].ingame ) { - scoreBoard->SetStateString( va( "player%i", iline ), gameLocal.m_I18N->Translate( "#str_04244" ) ); - scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04245" ) ); - // no color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); - } else { - scoreBoard->SetStateString( va( "player%i", iline ), gameLocal.userInfo[ i ].GetString( "ui_name" ) ); - if ( gameState == WARMUP ) { - if ( p->spectating ) { - scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04246" ) ); - // no color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); - } else { - scoreBoard->SetStateString( va( "player%i_score", iline ), p->IsReady() ? gameLocal.m_I18N->Translate( "#str_04247" ) : gameLocal.m_I18N->Translate( "#str_04248" ) ); - // set the color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); - UpdateRankColor( scoreBoard, "rank%i_color%i", iline, p->colorBar ); - } - } else { - if ( gameLocal.gameType == GAME_LASTMAN && playerState[ i ].fragCount == LASTMAN_NOLIVES ) { - scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_06736" ) ); - // set the color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 1 ); - UpdateRankColor( scoreBoard, "rank%i_color%i", iline, p->colorBar ); - } else { - scoreBoard->SetStateString( va( "player%i_score", iline ), gameLocal.m_I18N->Translate( "#str_04246" ) ); - // no color band - scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); - } - } - } - scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_wins", iline ), "" ); - scoreBoard->SetStateInt( va( "player%i_ping", iline ), playerState[ i ].ping ); - if ( i == player->entityNumber ) { - // highlight who we are - scoreBoard->SetStateInt( "rank_self", iline ); - } - } - } - - // clear remaining lines (empty slots) - iline++; - while ( iline < 5 ) { - scoreBoard->SetStateString( va( "player%i", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_score", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_tscore", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_tdm_score", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_wins", iline ), "" ); - scoreBoard->SetStateString( va( "player%i_ping", iline ), "" ); - scoreBoard->SetStateInt( va( "rank%i", iline ), 0 ); - iline++; - } - - gameinfo = va( "%s: %s", gameLocal.m_I18N->Translate( "#str_02376" ), gameLocal.serverInfo.GetString( "si_gameType" ) ); - if ( gameLocal.gameType == GAME_LASTMAN ) { - if ( gameState == GAMEON || gameState == SUDDENDEATH ) { - livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_04264" ), startFragLimit ); - } else { - livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_04264" ), gameLocal.serverInfo.GetInt( "si_fragLimit" ) ); - } - - } else { - livesinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_01982" ), gameLocal.serverInfo.GetInt( "si_fragLimit" ) ); - } - if ( gameLocal.serverInfo.GetInt( "si_timeLimit" ) > 0 ) { - timeinfo = va( "%s: %i", gameLocal.m_I18N->Translate( "#str_01983" ), gameLocal.serverInfo.GetInt( "si_timeLimit" ) ); - } else { - timeinfo = va("%s", gameLocal.m_I18N->Translate( "#str_07209" )); - } - scoreBoard->SetStateString( "gameinfo", gameinfo ); - scoreBoard->SetStateString( "livesinfo", livesinfo ); - scoreBoard->SetStateString( "timeinfo", timeinfo ); - - scoreBoard->Redraw( gameLocal.time ); -} - -/* -================ -idMultiplayerGame::GameTime -================ -*/ -const char *idMultiplayerGame::GameTime() { - static char buff[16]; - int m, s, t, ms; - - if ( gameState == COUNTDOWN ) { - ms = warmupEndTime - gameLocal.realClientTime; - s = ms / 1000 + 1; - if ( ms <= 0 ) { - strcpy( buff, "WMP --" ); - } else { - sprintf( buff, "WMP %i", s ); - } - } else { - int timeLimit = gameLocal.serverInfo.GetInt( "si_timeLimit" ); - if ( timeLimit ) { - ms = ( timeLimit * 60000 ) - ( gameLocal.time - matchStartedTime ); - } else { - ms = gameLocal.time - matchStartedTime; - } - if ( ms < 0 ) { - ms = 0; - } - - s = ms / 1000; - m = s / 60; - s -= m * 60; - t = s / 10; - s -= t * 10; - - sprintf( buff, "%i:%i%i", m, t, s ); - } - return &buff[0]; -} - -/* -================ -idMultiplayerGame::NumActualClients -================ -*/ -int idMultiplayerGame::NumActualClients( bool countSpectators, int *teamcounts ) { - idPlayer *p; - int c = 0; - - if ( teamcounts ) { - teamcounts[ 0 ] = teamcounts[ 1 ] = 0; - } - for( int i = 0 ; i < gameLocal.numClients ; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - p = static_cast< idPlayer * >( ent ); - if ( countSpectators || CanPlay( p ) ) { - c++; - } - if ( teamcounts && CanPlay( p ) ) { - teamcounts[ p->team ]++; - } - } - return c; -} - -/* -================ -idMultiplayerGame::EnoughClientsToPlay -================ -*/ -bool idMultiplayerGame::EnoughClientsToPlay() { - int team[ 2 ]; - int clients = NumActualClients( false, &team[ 0 ] ); - if ( gameLocal.gameType == GAME_TDM ) { - return clients >= 2 && team[ 0 ] && team[ 1 ]; - } else { - return clients >= 2; - } -} - -/* -================ -idMultiplayerGame::AllPlayersReady -================ -*/ -bool idMultiplayerGame::AllPlayersReady() { - int i; - idEntity *ent; - idPlayer *p; - int team[ 2 ]; - - if ( NumActualClients( false, &team[ 0 ] ) <= 1 ) { - return false; - } - - if ( gameLocal.gameType == GAME_TDM ) { - if ( !team[ 0 ] || !team[ 1 ] ) { - return false; - } - } - - if ( !gameLocal.serverInfo.GetBool( "si_warmup" ) ) { - return true; - } - - for( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.gameType == GAME_TOURNEY && i != currentTourneyPlayer[ 0 ] && i != currentTourneyPlayer[ 1 ] ) { - continue; - } - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - p = static_cast< idPlayer * >( ent ); - if ( CanPlay( p ) && !p->IsReady() ) { - return false; - } - team[ p->team ]++; - } - - return true; -} - -/* -================ -idMultiplayerGame::FragLimitHit -return the winning player (team player) -if there is no FragLeader(), the game is tied and we return NULL -================ -*/ -idPlayer *idMultiplayerGame::FragLimitHit() { - int i; - int fragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); - idPlayer *leader; - - leader = FragLeader(); - if ( !leader ) { - return NULL; - } - - if ( fragLimit <= 0 ) { - fragLimit = MP_PLAYER_MAXFRAGS; - } - - if ( gameLocal.gameType == GAME_LASTMAN ) { - // we have a leader, check if any other players have frags left - assert( !static_cast< idPlayer * >( leader )->lastManOver ); - for( i = 0 ; i < gameLocal.numClients ; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( !CanPlay( static_cast< idPlayer * >( ent ) ) ) { - continue; - } - if ( ent == leader ) { - continue; - } - if ( playerState[ ent->entityNumber ].fragCount > 0 ) { - return NULL; - } - } - // there is a leader, his score may even be negative, but no one else has frags left or is !lastManOver - return leader; - } else if ( gameLocal.gameType == GAME_TDM ) { - if ( playerState[ leader->entityNumber ].teamFragCount >= fragLimit ) { - return leader; - } - } else { - if ( playerState[ leader->entityNumber ].fragCount >= fragLimit ) { - return leader; - } - } - - return NULL; -} - -/* -================ -idMultiplayerGame::TimeLimitHit -================ -*/ -bool idMultiplayerGame::TimeLimitHit() { - int timeLimit = gameLocal.serverInfo.GetInt( "si_timeLimit" ); - if ( timeLimit ) { - if ( gameLocal.time >= matchStartedTime + timeLimit * 60000 ) { - return true; - } - } - return false; -} - -/* -================ -idMultiplayerGame::FragLeader -return the current winner ( or a player from the winning team ) -NULL if even -================ -*/ -idPlayer *idMultiplayerGame::FragLeader( void ) { - int i; - int frags[ MAX_CLIENTS ]; - idPlayer *leader = NULL; - idEntity *ent; - idPlayer *p; - int high = -9999; - int count = 0; - bool teamLead[ 2 ] = { false, false }; - - for ( i = 0 ; i < gameLocal.numClients ; i++ ) { - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( !CanPlay( static_cast< idPlayer * >( ent ) ) ) { - continue; - } - if ( gameLocal.gameType == GAME_TOURNEY && ent->entityNumber != currentTourneyPlayer[ 0 ] && ent->entityNumber != currentTourneyPlayer[ 1 ] ) { - continue; - } - if ( static_cast< idPlayer * >( ent )->lastManOver ) { - continue; - } - - int fragc = ( gameLocal.gameType == GAME_TDM ) ? playerState[i].teamFragCount : playerState[i].fragCount; - if ( fragc > high ) { - high = fragc; - } - - frags[ i ] = fragc; - } - - for ( i = 0; i < gameLocal.numClients; i++ ) { - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - p = static_cast< idPlayer * >( ent ); - p->SetLeader( false ); - - if ( !CanPlay( p ) ) { - continue; - } - if ( gameLocal.gameType == GAME_TOURNEY && ent->entityNumber != currentTourneyPlayer[ 0 ] && ent->entityNumber != currentTourneyPlayer[ 1 ] ) { - continue; - } - if ( p->lastManOver ) { - continue; - } - if ( p->spectating ) { - continue; - } - - if ( frags[ i ] >= high ) { - leader = p; - count++; - p->SetLeader( true ); - if ( gameLocal.gameType == GAME_TDM ) { - teamLead[ p->team ] = true; - } - } - } - - if ( gameLocal.gameType != GAME_TDM ) { - // more than one player at the highest frags - if ( count > 1 ) { - return NULL; - } else { - return leader; - } - } else { - if ( teamLead[ 0 ] && teamLead[ 1 ] ) { - // even game in team play - return NULL; - } - return leader; - } -} - -/* -================ -idGameLocal::UpdateWinsLosses -================ -*/ -void idMultiplayerGame::UpdateWinsLosses( idPlayer *winner ) { - if ( winner ) { - // run back through and update win/loss count - for( int i = 0; i < gameLocal.numClients; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - idPlayer *player = static_cast(ent); - if ( gameLocal.gameType == GAME_TDM ) { - if ( player == winner || ( player != winner && player->team == winner->team ) ) { - playerState[ i ].wins++; - PlayGlobalSound( player->entityNumber, SND_YOUWIN ); - } else { - PlayGlobalSound( player->entityNumber, SND_YOULOSE ); - } - } else if ( gameLocal.gameType == GAME_LASTMAN ) { - if ( player == winner ) { - playerState[ i ].wins++; - PlayGlobalSound( player->entityNumber, SND_YOUWIN ); - } else if ( !player->wantSpectate ) { - PlayGlobalSound( player->entityNumber, SND_YOULOSE ); - } - } else if ( gameLocal.gameType == GAME_TOURNEY ) { - if ( player == winner ) { - playerState[ i ].wins++; - PlayGlobalSound( player->entityNumber, SND_YOUWIN ); - } else if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { - PlayGlobalSound( player->entityNumber, SND_YOULOSE ); - } - } else { - if ( player == winner ) { - playerState[i].wins++; - PlayGlobalSound( player->entityNumber, SND_YOUWIN ); - } else if ( !player->wantSpectate ) { - PlayGlobalSound( player->entityNumber, SND_YOULOSE ); - } - } - } - } - if ( winner ) { - lastWinner = winner->entityNumber; - } else { - lastWinner = -1; - } -} - -/* -================ -idMultiplayerGame::TeamScore -================ -*/ -void idMultiplayerGame::TeamScore( int entityNumber, int team, int delta ) { - playerState[ entityNumber ].fragCount += delta; - for( int i = 0 ; i < gameLocal.numClients ; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - idPlayer *player = static_cast(ent); - if ( player->team == team ) { - playerState[ player->entityNumber ].teamFragCount += delta; - } - } -} - -/* -================ -idMultiplayerGame::PlayerDeath -================ -*/ -void idMultiplayerGame::PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag ) { - - // don't do PrintMessageEvent and shit - assert( !gameLocal.isClient ); - - if ( killer ) { - if ( gameLocal.gameType == GAME_LASTMAN ) { - playerState[ dead->entityNumber ].fragCount--; - } else if ( gameLocal.gameType == GAME_TDM ) { - if ( killer == dead || killer->team == dead->team ) { - // suicide or teamkill - TeamScore( killer->entityNumber, killer->team, -1 ); - } else { - TeamScore( killer->entityNumber, killer->team, +1 ); - } - } else { - playerState[ killer->entityNumber ].fragCount += ( killer == dead ) ? -1 : 1; - } - } - - if ( killer && killer == dead ) { - PrintMessageEvent( -1, MSG_SUICIDE, dead->entityNumber ); - } else if ( killer ) { - if ( telefrag ) { - PrintMessageEvent( -1, MSG_TELEFRAGGED, dead->entityNumber, killer->entityNumber ); - } else if ( gameLocal.gameType == GAME_TDM && dead->team == killer->team ) { - PrintMessageEvent( -1, MSG_KILLEDTEAM, dead->entityNumber, killer->entityNumber ); - } else { - PrintMessageEvent( -1, MSG_KILLED, dead->entityNumber, killer->entityNumber ); - } - } else { - PrintMessageEvent( -1, MSG_DIED, dead->entityNumber ); - playerState[ dead->entityNumber ].fragCount--; - } -} - -/* -================ -idMultiplayerGame::PlayerStats -================ -*/ -void idMultiplayerGame::PlayerStats( int clientNum, char *data, const int len ) { - - idEntity *ent; - int team; - - *data = 0; - - // make sure we don't exceed the client list - if ( clientNum < 0 || clientNum > gameLocal.numClients ) { - return; - } - - // find which team this player is on - ent = gameLocal.entities[ clientNum ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - team = static_cast< idPlayer * >(ent)->team; - } else { - return; - } - - idStr::snPrintf( data, len, "team=%d score=%d tks=%d", team, playerState[ clientNum ].fragCount, playerState[ clientNum ].teamFragCount ); - - return; - -} - -/* -================ -idMultiplayerGame::PlayerVote -================ -*/ -void idMultiplayerGame::PlayerVote( int clientNum, playerVote_t vote ) { - playerState[ clientNum ].vote = vote; -} - -/* -================ -idMultiplayerGame::DumpTourneyLine -================ -*/ -void idMultiplayerGame::DumpTourneyLine( void ) { - int i; - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { - common->Printf( "client %d: rank %d\n", i, static_cast< idPlayer * >( gameLocal.entities[ i ] )->tourneyRank ); - } - } -} - -/* -================ -idMultiplayerGame::NewState -================ -*/ -void idMultiplayerGame::NewState( gameState_t news, idPlayer *player ) { - idBitMsg outMsg; - byte msgBuf[MAX_GAME_MESSAGE_SIZE]; - int i; - - assert( news != gameState ); - assert( !gameLocal.isClient ); - gameLocal.DPrintf( "%s -> %s\n", GameStateStrings[ gameState ], GameStateStrings[ news ] ); - switch( news ) { - case GAMEON: { - gameLocal.LocalMapRestart(); - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_RESTART ); - outMsg.WriteBits( 0, 1 ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - - PlayGlobalSound( -1, SND_FIGHT ); - matchStartedTime = gameLocal.time; - fragLimitTimeout = 0; - for( i = 0; i < gameLocal.numClients; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - idPlayer *p = static_cast( ent ); - p->SetLeader( false ); // don't carry the flag from previous games - if ( gameLocal.gameType == GAME_TOURNEY && currentTourneyPlayer[ 0 ] != i && currentTourneyPlayer[ 1 ] != i ) { - p->ServerSpectate( true ); - p->tourneyRank++; - } else { - int fragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); - int startingCount = ( gameLocal.gameType == GAME_LASTMAN ) ? fragLimit : 0; - playerState[ i ].fragCount = startingCount; - playerState[ i ].teamFragCount = startingCount; - if ( !static_cast(ent)->wantSpectate ) { - static_cast(ent)->ServerSpectate( false ); - if ( gameLocal.gameType == GAME_TOURNEY ) { - p->tourneyRank = 0; - } - } - } - if ( CanPlay( p ) ) { - p->lastManPresent = true; - } else { - p->lastManPresent = false; - } - } - cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); - switchThrottle[ 1 ] = 0; // passby the throttle - startFragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); - break; - } - case GAMEREVIEW: { - nextState = INACTIVE; // used to abort a game. cancel out any upcoming state change - // set all players not ready and spectating - for( i = 0; i < gameLocal.numClients; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - static_cast< idPlayer *>( ent )->forcedReady = false; - static_cast(ent)->ServerSpectate( true ); - } - UpdateWinsLosses( player ); - break; - } - case SUDDENDEATH: { - PrintMessageEvent( -1, MSG_SUDDENDEATH ); - PlayGlobalSound( -1, SND_SUDDENDEATH ); - break; - } - case COUNTDOWN: { - idBitMsg outMsg; - byte msgBuf[ 128 ]; - - warmupEndTime = gameLocal.time + 1000*cvarSystem->GetCVarInteger( "g_countDown" ); - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_WARMUPTIME ); - outMsg.WriteLong( warmupEndTime ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - - break; - } - default: - break; - } - - gameState = news; -} - -/* -================ -idMultiplayerGame::FillTourneySlots -NOTE: called each frame during warmup to keep the tourney slots filled -================ -*/ -void idMultiplayerGame::FillTourneySlots( ) { - int i, j, rankmax, rankmaxindex; - idEntity *ent; - idPlayer *p; - - // fill up the slots based on tourney ranks - for ( i = 0; i < 2; i++ ) { - if ( currentTourneyPlayer[ i ] != -1 ) { - continue; - } - rankmax = -1; - rankmaxindex = -1; - for ( j = 0; j < gameLocal.numClients; j++ ) { - ent = gameLocal.entities[ j ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( currentTourneyPlayer[ 0 ] == j || currentTourneyPlayer[ 1 ] == j ) { - continue; - } - p = static_cast< idPlayer * >( ent ); - if ( p->wantSpectate ) { - continue; - } - if ( p->tourneyRank >= rankmax ) { - // when ranks are equal, use time in game - if ( p->tourneyRank == rankmax ) { - assert( rankmaxindex >= 0 ); - if ( p->spawnedTime > static_cast< idPlayer * >( gameLocal.entities[ rankmaxindex ] )->spawnedTime ) { - continue; - } - } - rankmax = static_cast< idPlayer * >( ent )->tourneyRank; - rankmaxindex = j; - } - } - currentTourneyPlayer[ i ] = rankmaxindex; // may be -1 if we found nothing - } -} - -/* -================ -idMultiplayerGame::UpdateTourneyLine -we manipulate tourneyRank on player entities for internal ranking. it's easier to deal with. -but we need a real wait list to be synced down to clients for GUI -ignore current players, ignore wantSpectate -================ -*/ -void idMultiplayerGame::UpdateTourneyLine( void ) { - int i, j, imax, max, globalmax = -1; - idPlayer *p; - - assert( !gameLocal.isClient ); - if ( gameLocal.gameType != GAME_TOURNEY ) { - return; - } - - for ( j = 1; j <= gameLocal.numClients; j++ ) { - max = -1; imax = -1; - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( currentTourneyPlayer[ 0 ] == i || currentTourneyPlayer[ 1 ] == i ) { - continue; - } - p = static_cast< idPlayer * >( gameLocal.entities[ i ] ); - if ( !p || p->wantSpectate ) { - continue; - } - if ( p->tourneyRank > max && ( globalmax == -1 || p->tourneyRank < globalmax ) ) { - imax = i; - max = p->tourneyRank; - } - } - if ( imax == -1 ) { - break; - } - - idBitMsg outMsg; - byte msgBuf[1024]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_TOURNEYLINE ); - outMsg.WriteByte( j ); - networkSystem->ServerSendReliableMessage( imax, outMsg ); - - globalmax = max; - } -} - -/* -================ -idMultiplayerGame::CycleTourneyPlayers -================ -*/ -void idMultiplayerGame::CycleTourneyPlayers( ) { - int i; - idEntity *ent; - idPlayer *player; - - currentTourneyPlayer[ 0 ] = -1; - currentTourneyPlayer[ 1 ] = -1; - // if any, winner from last round will play again - if ( lastWinner != -1 ) { - idEntity *ent = gameLocal.entities[ lastWinner ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - currentTourneyPlayer[ 0 ] = lastWinner; - } - } - FillTourneySlots( ); - // force selected players in/out of the game and update the ranks - for ( i = 0 ; i < gameLocal.numClients ; i++ ) { - if ( currentTourneyPlayer[ 0 ] == i || currentTourneyPlayer[ 1 ] == i ) { - player = static_cast( gameLocal.entities[ i ] ); - player->ServerSpectate( false ); - } else { - ent = gameLocal.entities[ i ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - player = static_cast( gameLocal.entities[ i ] ); - player->ServerSpectate( true ); - } - } - } - UpdateTourneyLine(); -} - -/* -================ -idMultiplayerGame::ExecuteVote -the votes are checked for validity/relevance before they are started -we assume that they are still legit when reaching here -================ -*/ -void idMultiplayerGame::ExecuteVote( void ) { - bool needRestart; - switch ( vote ) { - case VOTE_RESTART: - gameLocal.MapRestart(); - break; - case VOTE_TIMELIMIT: - si_timeLimit.SetInteger( atoi( voteValue ) ); - needRestart = gameLocal.NeedRestart(); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); - if ( needRestart ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); - } - break; - case VOTE_FRAGLIMIT: - si_fragLimit.SetInteger( atoi( voteValue ) ); - needRestart = gameLocal.NeedRestart(); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); - if ( needRestart ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); - } - break; - case VOTE_GAMETYPE: - si_gameType.SetString( voteValue ); - gameLocal.MapRestart(); - break; - case VOTE_KICK: - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %s", voteValue.c_str() ) ); - break; - case VOTE_MAP: - si_map.SetString( voteValue ); - gameLocal.MapRestart(); - break; - case VOTE_SPECTATORS: - si_spectators.SetBool( !si_spectators.GetBool() ); - needRestart = gameLocal.NeedRestart(); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "rescanSI" ); - if ( needRestart ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "nextMap" ); - } - break; - case VOTE_NEXTMAP: - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "serverNextMap\n" ); - break; - default: - break; - } -} - -/* -================ -idMultiplayerGame::CheckVote -================ -*/ -void idMultiplayerGame::CheckVote( void ) { - int numVoters, i; - - if ( vote == VOTE_NONE ) { - return; - } - - if ( voteExecTime ) { - if ( gameLocal.time > voteExecTime ) { - voteExecTime = 0; - ClientUpdateVote( VOTE_RESET, 0, 0 ); - ExecuteVote(); - vote = VOTE_NONE; - } - return; - } - - // count voting players - numVoters = 0; - for ( i = 0; i < gameLocal.numClients; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( playerState[ i ].vote != PLAYER_VOTE_NONE ) { - numVoters++; - } - } - if ( !numVoters ) { - // abort - vote = VOTE_NONE; - ClientUpdateVote( VOTE_ABORTED, static_cast(yesVotes), static_cast(noVotes) ); - return; - } - if ( yesVotes / numVoters > 0.5f ) { - ClientUpdateVote( VOTE_PASSED, static_cast(yesVotes), static_cast(noVotes) ); - voteExecTime = gameLocal.time + 2000; - return; - } - if ( gameLocal.time > voteTimeOut || noVotes / numVoters >= 0.5f ) { - ClientUpdateVote( VOTE_FAILED, static_cast(yesVotes), static_cast(noVotes) ); - vote = VOTE_NONE; - return; - } -} - -/* -================ -idMultiplayerGame::Warmup -================ -*/ -bool idMultiplayerGame::Warmup() { - return ( gameState == WARMUP ); -} - -/* -================ -idMultiplayerGame::Run -================ -*/ -void idMultiplayerGame::Run() { - int i, timeLeft; - idPlayer *player; - int gameReviewPause; - - assert( gameLocal.isMultiplayer ); - assert( !gameLocal.isClient ); - - pureReady = true; - - if ( gameState == INACTIVE ) { - lastGameType = gameLocal.gameType; - NewState( WARMUP ); - } - - CheckVote(); - - CheckRespawns(); - - if ( nextState != INACTIVE && gameLocal.time > nextStateSwitch ) { - NewState( nextState ); - nextState = INACTIVE; - } - - // don't update the ping every frame to save bandwidth - if ( gameLocal.time > pingUpdateTime ) { - for ( i = 0; i < gameLocal.numClients; i++ ) { - playerState[i].ping = networkSystem->ServerGetClientPing( i ); - } - pingUpdateTime = gameLocal.time + 1000; - } - - warmupText = ""; - - switch( gameState ) { - case GAMEREVIEW: { - if ( nextState == INACTIVE ) { - gameReviewPause = cvarSystem->GetCVarInteger( "g_gameReviewPause" ); - nextState = NEXTGAME; - nextStateSwitch = gameLocal.time + 1000 * gameReviewPause; - } - break; - } - case NEXTGAME: { - if ( nextState == INACTIVE ) { - // game rotation, new map, gametype etc. - if ( gameLocal.NextMap() ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "serverMapRestart\n" ); - return; - } - NewState( WARMUP ); - if ( gameLocal.gameType == GAME_TOURNEY ) { - CycleTourneyPlayers(); - } - // put everyone back in from endgame spectate - for ( i = 0; i < gameLocal.numClients; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - if ( !static_cast< idPlayer * >( ent )->wantSpectate ) { - CheckRespawns( static_cast( ent ) ); - } - } - } - } - break; - } - case WARMUP: { - if ( AllPlayersReady() ) { - NewState( COUNTDOWN ); - nextState = GAMEON; - nextStateSwitch = gameLocal.time + 1000 * cvarSystem->GetCVarInteger( "g_countDown" ); - } - warmupText = "Warming up.. waiting for players to get ready"; - one = two = three = false; - break; - } - case COUNTDOWN: { - timeLeft = ( nextStateSwitch - gameLocal.time ) / 1000 + 1; - if ( timeLeft == 3 && !three ) { - PlayGlobalSound( -1, SND_THREE ); - three = true; - } else if ( timeLeft == 2 && !two ) { - PlayGlobalSound( -1, SND_TWO ); - two = true; - } else if ( timeLeft == 1 && !one ) { - PlayGlobalSound( -1, SND_ONE ); - one = true; - } - warmupText = va( "Match starts in %i", timeLeft ); - break; - } - case GAMEON: { - player = FragLimitHit(); - if ( player ) { - // delay between detecting frag limit and ending game. let the death anims play - if ( !fragLimitTimeout ) { - common->DPrintf( "enter FragLimit timeout, player %d is leader\n", player->entityNumber ); - fragLimitTimeout = gameLocal.time + FRAGLIMIT_DELAY; - } - if ( gameLocal.time > fragLimitTimeout ) { - NewState( GAMEREVIEW, player ); - PrintMessageEvent( -1, MSG_FRAGLIMIT, player->entityNumber ); - } - } else { - if ( fragLimitTimeout ) { - // frag limit was hit and cancelled. means the two teams got even during FRAGLIMIT_DELAY - // enter sudden death, the next frag leader will win - SuddenRespawn(); - PrintMessageEvent( -1, MSG_HOLYSHIT ); - fragLimitTimeout = 0; - NewState( SUDDENDEATH ); - } else if ( TimeLimitHit() ) { - player = FragLeader(); - if ( !player ) { - NewState( SUDDENDEATH ); - } else { - NewState( GAMEREVIEW, player ); - PrintMessageEvent( -1, MSG_TIMELIMIT ); - } - } - } - break; - } - case SUDDENDEATH: { - player = FragLeader(); - if ( player ) { - if ( !fragLimitTimeout ) { - common->DPrintf( "enter sudden death FragLeader timeout, player %d is leader\n", player->entityNumber ); - fragLimitTimeout = gameLocal.time + FRAGLIMIT_DELAY; - } - if ( gameLocal.time > fragLimitTimeout ) { - NewState( GAMEREVIEW, player ); - PrintMessageEvent( -1, MSG_FRAGLIMIT, player->entityNumber ); - } - } else if ( fragLimitTimeout ) { - SuddenRespawn(); - PrintMessageEvent( -1, MSG_HOLYSHIT ); - fragLimitTimeout = 0; - } - break; - } - default: break; - } -} - -/* -================ -idMultiplayerGame::UpdateMainGui -================ -*/ -void idMultiplayerGame::UpdateMainGui( void ) { - int i; - mainGui->SetStateInt( "readyon", gameState == WARMUP ? 1 : 0 ); - mainGui->SetStateInt( "readyoff", gameState != WARMUP ? 1 : 0 ); - idStr strReady = cvarSystem->GetCVarString( "ui_ready" ); - if ( strReady.Icmp( "ready") == 0 ){ - strReady = gameLocal.m_I18N->Translate( "#str_04248" ); - } else { - strReady = gameLocal.m_I18N->Translate( "#str_04247" ); - } - mainGui->SetStateString( "ui_ready", strReady ); - mainGui->SetStateInt( "teamon", gameLocal.gameType == GAME_TDM ? 1 : 0 ); - mainGui->SetStateInt( "teamoff", gameLocal.gameType != GAME_TDM ? 1 : 0 ); - if ( gameLocal.gameType == GAME_TDM ) { - idPlayer *p = gameLocal.GetClientByNum( gameLocal.localClientNum ); - mainGui->SetStateInt( "team", p->team ); - } - // setup vote - mainGui->SetStateInt( "voteon", ( vote != VOTE_NONE && !voted ) ? 1 : 0 ); - mainGui->SetStateInt( "voteoff", ( vote != VOTE_NONE && !voted ) ? 0 : 1 ); - // last man hack - mainGui->SetStateInt( "isLastMan", gameLocal.gameType == GAME_LASTMAN ? 1 : 0 ); - // send the current serverinfo values - for ( i = 0; i < gameLocal.serverInfo.GetNumKeyVals(); i++ ) { - const idKeyValue *keyval = gameLocal.serverInfo.GetKeyVal( i ); - mainGui->SetStateString( keyval->GetKey(), keyval->GetValue() ); - } - mainGui->StateChanged( gameLocal.time ); -#if defined( __linux__ ) - // replacing the oh-so-useful s_reverse with sound backend prompt - mainGui->SetStateString( "driver_prompt", "1" ); -#else - mainGui->SetStateString( "driver_prompt", "0" ); -#endif -} - -/* -================ -idMultiplayerGame::StartMenu -================ -*/ -idUserInterface* idMultiplayerGame::StartMenu( void ) { - - if ( mainGui == NULL ) { - return NULL; - } - - int i, j; - if ( currentMenu ) { - currentMenu = 0; - cvarSystem->SetCVarBool( "ui_chat", false ); - } else { - if ( nextMenu >= 2 ) { - currentMenu = nextMenu; - } else { - // for default and explicit - currentMenu = 1; - } - cvarSystem->SetCVarBool( "ui_chat", true ); - } - nextMenu = 0; - gameLocal.sessionCommand = ""; // in case we used "game_startMenu" to trigger the menu - if ( currentMenu == 1 ) { - UpdateMainGui(); - - // UpdateMainGui sets most things, but it doesn't set these because - // it'd be pointless and/or harmful to set them every frame (for various reasons) - // Currenty the gui doesn't update properly if they change anyway, so we'll leave it like this. - - // setup callvote - if ( vote == VOTE_NONE ) { - bool callvote_ok = false; - for ( i = 0; i < VOTE_COUNT; i++ ) { - // flag on means vote is denied, so default value 0 means all votes and -1 disables - mainGui->SetStateInt( va( "vote%d", i ), g_voteFlags.GetInteger() & ( 1 << i ) ? 0 : 1 ); - if ( !( g_voteFlags.GetInteger() & ( 1 << i ) ) ) { - callvote_ok = true; - } - } - mainGui->SetStateInt( "callvote", callvote_ok ); - } else { - mainGui->SetStateInt( "callvote", 2 ); - } - - // player kick data - idStr kickList; - j = 0; - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { - if ( kickList.Length() ) { - kickList += ";"; - } - kickList += va( "\"%d - %s\"", i, gameLocal.userInfo[ i ].GetString( "ui_name" ) ); - kickVoteMap[ j ] = i; - j++; - } - } - mainGui->SetStateString( "kickChoices", kickList ); - - mainGui->SetStateString( "chattext", "" ); - mainGui->Activate( true, gameLocal.time ); - return mainGui; - } else if ( currentMenu == 2 ) { - // the setup is done in MessageMode - msgmodeGui->Activate( true, gameLocal.time ); - cvarSystem->SetCVarBool( "ui_chat", true ); - return msgmodeGui; - } - return NULL; -} - -/* -================ -idMultiplayerGame::DisableMenu -================ -*/ -void idMultiplayerGame::DisableMenu( void ) { - gameLocal.sessionCommand = ""; // in case we used "game_startMenu" to trigger the menu - if ( currentMenu == 1 ) { - mainGui->Activate( false, gameLocal.time ); - } else if ( currentMenu == 2 ) { - msgmodeGui->Activate( false, gameLocal.time ); - } - currentMenu = 0; - nextMenu = 0; - cvarSystem->SetCVarBool( "ui_chat", false ); -} - -/* -================ -idMultiplayerGame::SetMapShot -================ -*/ -void idMultiplayerGame::SetMapShot( void ) { - char screenshot[ MAX_STRING_CHARS ]; - int mapNum = mapList->GetSelection( NULL, 0 ); - const idDict *dict = NULL; - if ( mapNum >= 0 ) { - dict = fileSystem->GetMapDecl( mapNum ); - } - fileSystem->FindMapScreenshot( dict ? dict->GetString( "path" ) : "", screenshot, MAX_STRING_CHARS ); - mainGui->SetStateString( "current_levelshot", screenshot ); -} - -/* -================ -idMultiplayerGame::HandleGuiCommands -================ -*/ -const char* idMultiplayerGame::HandleGuiCommands( const char *_menuCommand ) { - idUserInterface *currentGui; - const char *voteValue; - int vote_clientNum; - int icmd; - idCmdArgs args; - - if ( !_menuCommand[ 0 ] ) { - common->Printf( "idMultiplayerGame::HandleGuiCommands: empty command\n" ); - return "continue"; - } - assert( currentMenu ); - if ( currentMenu == 1 ) { - currentGui = mainGui; - } else { - currentGui = msgmodeGui; - } - - args.TokenizeString( _menuCommand, false ); - - for( icmd = 0; icmd < args.Argc(); ) { - const char *cmd = args.Argv( icmd++ ); - - if ( !idStr::Icmp( cmd, ";" ) ) { - continue; - } else if ( !idStr::Icmp( cmd, "video" ) ) { - idStr vcmd; - if ( args.Argc() - icmd >= 1 ) { - vcmd = args.Argv( icmd++ ); - } - - int oldSpec = cvarSystem->GetCVarInteger( "com_machineSpec" ); - - if ( idStr::Icmp( vcmd, "low" ) == 0 ) { - cvarSystem->SetCVarInteger( "com_machineSpec", 0 ); - } else if ( idStr::Icmp( vcmd, "medium" ) == 0 ) { - cvarSystem->SetCVarInteger( "com_machineSpec", 1 ); - } else if ( idStr::Icmp( vcmd, "high" ) == 0 ) { - cvarSystem->SetCVarInteger( "com_machineSpec", 2 ); - } else if ( idStr::Icmp( vcmd, "ultra" ) == 0 ) { - cvarSystem->SetCVarInteger( "com_machineSpec", 3 ); - } else if ( idStr::Icmp( vcmd, "recommended" ) == 0 ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" ); - } - - if ( oldSpec != cvarSystem->GetCVarInteger( "com_machineSpec" ) ) { - currentGui->SetStateInt( "com_machineSpec", cvarSystem->GetCVarInteger( "com_machineSpec" ) ); - currentGui->StateChanged( gameLocal.realClientTime ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, "execMachineSpec\n" ); - } - - if ( idStr::Icmp( vcmd, "restart" ) == 0) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" ); - } - - continue; - } else if ( !idStr::Icmp( cmd, "play" ) ) { - if ( args.Argc() - icmd >= 1 ) { - idStr snd = args.Argv( icmd++ ); - int channel = 1; - if ( snd.Length() == 1 ) { - channel = atoi( snd ); - snd = args.Argv( icmd++ ); - } - gameSoundWorld->PlayShaderDirectly( snd, channel ); - } - continue; - } else if ( !idStr::Icmp( cmd, "mpSkin" ) ) { - idStr skin; - if ( args.Argc() - icmd >= 1 ) { - skin = args.Argv( icmd++ ); - cvarSystem->SetCVarString( "ui_skin", skin ); - } - SetMenuSkin(); - continue; - } else if ( !idStr::Icmp( cmd, "quit" ) ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); - return NULL; - } else if ( !idStr::Icmp( cmd, "disconnect" ) ) { - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); - return NULL; - } else if ( !idStr::Icmp( cmd, "close" ) ) { - DisableMenu( ); - return NULL; - } else if ( !idStr::Icmp( cmd, "spectate" ) ) { - ToggleSpectate(); - DisableMenu( ); - return NULL; - } else if ( !idStr::Icmp( cmd, "chatmessage" ) ) { - int mode = currentGui->State().GetInt( "messagemode" ); - if ( mode ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "sayTeam \"%s\"", currentGui->State().GetString( "chattext" ) ) ); - } else { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", currentGui->State().GetString( "chattext" ) ) ); - } - currentGui->SetStateString( "chattext", "" ); - if ( currentMenu == 1 ) { - return "continue"; - } else { - DisableMenu(); - return NULL; - } - } else if ( !idStr::Icmp( cmd, "readytoggle" ) ) { - ToggleReady( ); - DisableMenu( ); - return NULL; - } else if ( !idStr::Icmp( cmd, "teamtoggle" ) ) { - ToggleTeam( ); - DisableMenu( ); - return NULL; - } else if ( !idStr::Icmp( cmd, "callVote" ) ) { - vote_flags_t voteIndex = (vote_flags_t)mainGui->State().GetInt( "voteIndex" ); - if ( voteIndex == VOTE_MAP ) { - int mapNum = mapList->GetSelection( NULL, 0 ); - if ( mapNum >= 0 ) { - const idDict *dict = fileSystem->GetMapDecl( mapNum ); - if ( dict ) { - ClientCallVote( VOTE_MAP, dict->GetString( "path" ) ); - } - } - } else { - voteValue = mainGui->State().GetString( "str_voteValue" ); - if ( voteIndex == VOTE_KICK ) { - vote_clientNum = kickVoteMap[ atoi( voteValue ) ]; - ClientCallVote( voteIndex, va( "%d", vote_clientNum ) ); - } else { - ClientCallVote( voteIndex, voteValue ); - } - } - DisableMenu(); - return NULL; - } else if ( !idStr::Icmp( cmd, "voteyes" ) ) { - CastVote( gameLocal.localClientNum, true ); - DisableMenu(); - return NULL; - } else if ( !idStr::Icmp( cmd, "voteno" ) ) { - CastVote( gameLocal.localClientNum, false ); - DisableMenu(); - return NULL; - } else if ( !idStr::Icmp( cmd, "bind" ) ) { - if ( args.Argc() - icmd >= 2 ) { - idStr key = args.Argv( icmd++ ); - idStr bind = args.Argv( icmd++ ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "bindunbindtwo \"%s\" \"%s\"", key.c_str(), bind.c_str() ) ); - mainGui->SetKeyBindingNames(); - } - continue; - } else if ( !idStr::Icmp( cmd, "clearbind" ) ) { - if ( args.Argc() - icmd >= 1 ) { - idStr bind = args.Argv( icmd++ ); - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "unbind \"%s\"", bind.c_str() ) ); - mainGui->SetKeyBindingNames(); - } - continue; - } else if ( !idStr::Icmp( cmd, "MAPScan" ) ) { - const char *gametype = gameLocal.serverInfo.GetString( "si_gameType" ); - if ( gametype == NULL || *gametype == 0 || idStr::Icmp( gametype, "singleplayer" ) == 0 ) { - gametype = "Deathmatch"; - } - - int i, num; - idStr si_map = gameLocal.serverInfo.GetString("si_map"); - const idDict *dict; - - mapList->Clear(); - mapList->SetSelection( -1 ); - num = fileSystem->GetNumMaps(); - for ( i = 0; i < num; i++ ) { - dict = fileSystem->GetMapDecl( i ); - if ( dict ) { - // any MP gametype supported - bool isMP = false; - int igt = GAME_SP + 1; - while ( si_gameTypeArgs[ igt ] ) { - if ( dict->GetBool( si_gameTypeArgs[ igt ] ) ) { - isMP = true; - break; - } - igt++; - } - if ( isMP ) { - const char *mapName = dict->GetString( "name" ); - if ( mapName[0] == '\0' ) { - mapName = dict->GetString( "path" ); - } - mapName = gameLocal.m_I18N->Translate( mapName ); - mapList->Add( i, mapName ); - if ( !si_map.Icmp( dict->GetString( "path" ) ) ) { - mapList->SetSelection( mapList->Num() - 1 ); - } - } - } - } - // set the current level shot - SetMapShot( ); - return "continue"; - } else if ( !idStr::Icmp( cmd, "click_maplist" ) ) { - SetMapShot( ); - return "continue"; - } else if ( strstr( cmd, "sound" ) == cmd ) { - // pass that back to the core, will know what to do with it - return _menuCommand; - } - common->Printf( "idMultiplayerGame::HandleGuiCommands: '%s' unknown\n", cmd ); - - } - return "continue"; -} - -/* -================ -idMultiplayerGame::Draw -================ -*/ -bool idMultiplayerGame::Draw( int clientNum ) { - idPlayer *player, *viewPlayer; - - // clear the render entities for any players that don't need - // icons and which might not be thinking because they weren't in - // the last snapshot. - for ( int i = 0; i < gameLocal.numClients; i++ ) { - player = static_cast( gameLocal.entities[ i ] ); - if ( player && !player->NeedsIcon() ) { - player->HidePlayerIcons(); - } - } - - player = viewPlayer = static_cast( gameLocal.entities[ clientNum ] ); - - if ( player == NULL ) { - return false; - } - - if ( player->spectating ) { - viewPlayer = static_cast( gameLocal.entities[ player->spectator ] ); - if ( viewPlayer == NULL ) { - return false; - } - } - - UpdatePlayerRanks(); - UpdateHud( viewPlayer, player->hud ); - // use the hud of the local player - viewPlayer->playerView.RenderPlayerView( player->hud ); - - if ( currentMenu ) { -#if 0 - // uncomment this if you want to track when players are in a menu - if ( !bCurrentMenuMsg ) { - idBitMsg outMsg; - byte msgBuf[ 128 ]; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_MENU ); - outMsg.WriteBits( 1, 1 ); - networkSystem->ClientSendReliableMessage( outMsg ); - - bCurrentMenuMsg = true; - } -#endif - if ( player->wantSpectate ) { - mainGui->SetStateString( "spectext", gameLocal.m_I18N->Translate( "#str_04249" ) ); - } else { - mainGui->SetStateString( "spectext", gameLocal.m_I18N->Translate( "#str_04250" ) ); - } - DrawChat(); - if ( currentMenu == 1 ) { - UpdateMainGui(); - mainGui->Redraw( gameLocal.time ); - } else { - msgmodeGui->Redraw( gameLocal.time ); - } - } else { -#if 0 - // uncomment this if you want to track when players are in a menu - if ( bCurrentMenuMsg ) { - idBitMsg outMsg; - byte msgBuf[ 128 ]; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_MENU ); - outMsg.WriteBits( 0, 1 ); - networkSystem->ClientSendReliableMessage( outMsg ); - - bCurrentMenuMsg = false; - } -#endif - if ( player->spectating ) { - idStr spectatetext[ 2 ]; - int ispecline = 0; - if ( gameLocal.gameType == GAME_TOURNEY ) { - if ( !player->wantSpectate ) { - spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_04246" ); - switch ( player->tourneyLine ) { - case 0: - spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07003" ); - break; - case 1: - spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07004" ); - break; - case 2: - spectatetext[ 0 ] += gameLocal.m_I18N->Translate( "#str_07005" ); - break; - default: - spectatetext[ 0 ] += va( gameLocal.m_I18N->Translate( "#str_07006" ), player->tourneyLine ); - break; - } - ispecline++; - } - } else if ( gameLocal.gameType == GAME_LASTMAN ) { - if ( !player->wantSpectate ) { - spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_07007" ); - ispecline++; - } - } - if ( player->spectator != player->entityNumber ) { - spectatetext[ ispecline ] = va( gameLocal.m_I18N->Translate( "#str_07008" ), viewPlayer->GetUserInfo()->GetString( "ui_name" ) ); - } else if ( !ispecline ) { - spectatetext[ 0 ] = gameLocal.m_I18N->Translate( "#str_04246" ); - } - spectateGui->SetStateString( "spectatetext0", spectatetext[0].c_str() ); - spectateGui->SetStateString( "spectatetext1", spectatetext[1].c_str() ); - if ( vote != VOTE_NONE ) { - spectateGui->SetStateString( "vote", va( "%s (y: %d n: %d)", voteString.c_str(), (int)yesVotes, (int)noVotes ) ); - } else { - spectateGui->SetStateString( "vote", "" ); - } - spectateGui->Redraw( gameLocal.time ); - } - DrawChat(); - DrawScoreBoard( player ); - } - - return true; -} - -/* -================ -idMultiplayerGame::UpdateHud -================ -*/ -void idMultiplayerGame::UpdateHud( idPlayer *player, idUserInterface *hud ) { - int i; - - if ( !hud ) { - return; - } - - hud->SetStateBool( "warmup", Warmup() ); - - if ( gameState == WARMUP ) { - if ( player->IsReady() ) { - hud->SetStateString( "warmuptext", gameLocal.m_I18N->Translate( "#str_04251" ) ); - } else { - hud->SetStateString( "warmuptext", gameLocal.m_I18N->Translate( "#str_07002" ) ); - } - } - - hud->SetStateString( "timer", ( Warmup() ) ? gameLocal.m_I18N->Translate( "#str_04251" ) : ( gameState == SUDDENDEATH ) ? gameLocal.m_I18N->Translate( "#str_04252" ) : GameTime() ); - if ( vote != VOTE_NONE ) { - hud->SetStateString( "vote", va( "%s (y: %d n: %d)", voteString.c_str(), (int)yesVotes, (int)noVotes ) ); - } else { - hud->SetStateString( "vote", "" ); - } - - hud->SetStateInt( "rank_self", 0 ); - if ( gameState == GAMEON ) { - for ( i = 0; i < numRankedPlayers; i++ ) { - if ( gameLocal.gameType == GAME_TDM ) { - hud->SetStateInt( va( "player%i_score", i+1 ), playerState[ rankedPlayers[ i ]->entityNumber ].teamFragCount ); - } else { - hud->SetStateInt( va( "player%i_score", i+1 ), playerState[ rankedPlayers[ i ]->entityNumber ].fragCount ); - } - hud->SetStateInt( va( "rank%i", i+1 ), 1 ); - UpdateRankColor( hud, "rank%i_color%i", i+1, rankedPlayers[ i ]->colorBar ); - if ( rankedPlayers[ i ] == player ) { - hud->SetStateInt( "rank_self", i+1 ); - } - } - } - for ( i = ( gameState == GAMEON ? numRankedPlayers : 0 ) ; i < 5; i++ ) { - hud->SetStateString( va( "player%i", i+1 ), "" ); - hud->SetStateString( va( "player%i_score", i+1 ), "" ); - hud->SetStateInt( va( "rank%i", i+1 ), 0 ); - } -} - -/* -================ -idMultiplayerGame::DrawScoreBoard -================ -*/ -void idMultiplayerGame::DrawScoreBoard( idPlayer *player ) { - if ( player->scoreBoardOpen || gameState == GAMEREVIEW ) { - if ( !playerState[ player->entityNumber ].scoreBoardUp ) { - scoreBoard->Activate( true, gameLocal.time ); - playerState[ player->entityNumber ].scoreBoardUp = true; - } - UpdateScoreboard( scoreBoard, player ); - } else { - if ( playerState[ player->entityNumber ].scoreBoardUp ) { - scoreBoard->Activate( false, gameLocal.time ); - playerState[ player->entityNumber ].scoreBoardUp = false; - } - } -} - -/* -=============== -idMultiplayerGame::ClearChatData -=============== -*/ -void idMultiplayerGame::ClearChatData() { - chatHistoryIndex = 0; - chatHistorySize = 0; - chatDataUpdated = true; -} - -/* -=============== -idMultiplayerGame::AddChatLine -=============== -*/ -void idMultiplayerGame::AddChatLine( const char *fmt, ... ) { - idStr temp; - va_list argptr; - - va_start( argptr, fmt ); - vsprintf( temp, fmt, argptr ); - va_end( argptr ); - - gameLocal.Printf( "%s\n", temp.c_str() ); - - chatHistory[ chatHistoryIndex % NUM_CHAT_NOTIFY ].line = temp; - chatHistory[ chatHistoryIndex % NUM_CHAT_NOTIFY ].fade = 6; - - chatHistoryIndex++; - if ( chatHistorySize < NUM_CHAT_NOTIFY ) { - chatHistorySize++; - } - chatDataUpdated = true; - lastChatLineTime = gameLocal.time; -} - -/* -=============== -idMultiplayerGame::DrawChat -=============== -*/ -void idMultiplayerGame::DrawChat() { - int i, j; - if ( guiChat ) { - if ( gameLocal.time - lastChatLineTime > CHAT_FADE_TIME ) { - if ( chatHistorySize > 0 ) { - for ( i = chatHistoryIndex - chatHistorySize; i < chatHistoryIndex; i++ ) { - chatHistory[ i % NUM_CHAT_NOTIFY ].fade--; - if ( chatHistory[ i % NUM_CHAT_NOTIFY ].fade < 0 ) { - chatHistorySize--; // this assumes the removals are always at the beginning - } - } - chatDataUpdated = true; - } - lastChatLineTime = gameLocal.time; - } - if ( chatDataUpdated ) { - j = 0; - i = chatHistoryIndex - chatHistorySize; - while ( i < chatHistoryIndex ) { - guiChat->SetStateString( va( "chat%i", j ), chatHistory[ i % NUM_CHAT_NOTIFY ].line ); - // don't set alpha above 4, the gui only knows that - guiChat->SetStateInt( va( "alpha%i", j ), Min( 4, (int)chatHistory[ i % NUM_CHAT_NOTIFY ].fade ) ); - j++; i++; - } - while ( j < NUM_CHAT_NOTIFY ) { - guiChat->SetStateString( va( "chat%i", j ), "" ); - j++; - } - guiChat->Activate( true, gameLocal.time ); - chatDataUpdated = false; - } - guiChat->Redraw( gameLocal.time ); - } -} - -const int ASYNC_PLAYER_FRAG_BITS = -idMath::BitsForInteger( MP_PLAYER_MAXFRAGS - MP_PLAYER_MINFRAGS ); // player can have negative frags -const int ASYNC_PLAYER_WINS_BITS = idMath::BitsForInteger( MP_PLAYER_MAXWINS ); -const int ASYNC_PLAYER_PING_BITS = idMath::BitsForInteger( MP_PLAYER_MAXPING ); - -/* -================ -idMultiplayerGame::WriteToSnapshot -================ -*/ -void idMultiplayerGame::WriteToSnapshot( idBitMsgDelta &msg ) const { - int i; - int value; - - msg.WriteByte( gameState ); - msg.WriteShort( currentTourneyPlayer[ 0 ] ); - msg.WriteShort( currentTourneyPlayer[ 1 ] ); - for ( i = 0; i < MAX_CLIENTS; i++ ) { - // clamp all values to min/max possible value that we can send over - value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[i].fragCount ); - msg.WriteBits( value, ASYNC_PLAYER_FRAG_BITS ); - value = idMath::ClampInt( MP_PLAYER_MINFRAGS, MP_PLAYER_MAXFRAGS, playerState[i].teamFragCount ); - msg.WriteBits( value, ASYNC_PLAYER_FRAG_BITS ); - value = idMath::ClampInt( 0, MP_PLAYER_MAXWINS, playerState[i].wins ); - msg.WriteBits( value, ASYNC_PLAYER_WINS_BITS ); - value = idMath::ClampInt( 0, MP_PLAYER_MAXPING, playerState[i].ping ); - msg.WriteBits( value, ASYNC_PLAYER_PING_BITS ); - msg.WriteBits( playerState[i].ingame, 1 ); - } -} - -/* -================ -idMultiplayerGame::ReadFromSnapshot -================ -*/ -void idMultiplayerGame::ReadFromSnapshot( const idBitMsgDelta &msg ) { - int i; - gameState_t newState; - - newState = (idMultiplayerGame::gameState_t)msg.ReadByte(); - if ( newState != gameState ) { - gameLocal.DPrintf( "%s -> %s\n", GameStateStrings[ gameState ], GameStateStrings[ newState ] ); - gameState = newState; - // these could be gathered in a BGNewState() kind of thing, as we have to do them in NewState as well - if ( gameState == GAMEON ) { - matchStartedTime = gameLocal.time; - cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); - switchThrottle[ 1 ] = 0; // passby the throttle - startFragLimit = gameLocal.serverInfo.GetInt( "si_fragLimit" ); - } - } - currentTourneyPlayer[ 0 ] = msg.ReadShort(); - currentTourneyPlayer[ 1 ] = msg.ReadShort(); - for ( i = 0; i < MAX_CLIENTS; i++ ) { - playerState[i].fragCount = msg.ReadBits( ASYNC_PLAYER_FRAG_BITS ); - playerState[i].teamFragCount = msg.ReadBits( ASYNC_PLAYER_FRAG_BITS ); - playerState[i].wins = msg.ReadBits( ASYNC_PLAYER_WINS_BITS ); - playerState[i].ping = msg.ReadBits( ASYNC_PLAYER_PING_BITS ); - playerState[i].ingame = msg.ReadBits( 1 ) != 0; - } -} - -/* -================ -idMultiplayerGame::PlayGlobalSound -================ -*/ -void idMultiplayerGame::PlayGlobalSound( int to, snd_evt_t evt, const char *shader ) { - const idSoundShader *shaderDecl; - - if ( to == -1 || to == gameLocal.localClientNum ) { - if ( shader ) { - gameSoundWorld->PlayShaderDirectly( shader ); - } else { - gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ evt ] ); - } - } - - if ( !gameLocal.isClient ) { - idBitMsg outMsg; - byte msgBuf[1024]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - - if ( shader ) { - shaderDecl = declManager->FindSound( shader ); - if ( !shaderDecl ) { - return; - } - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SOUND_INDEX ); - outMsg.WriteLong( gameLocal.ServerRemapDecl( to, DECL_SOUND, shaderDecl->Index() ) ); - } else { - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SOUND_EVENT ); - outMsg.WriteByte( evt ); - } - - networkSystem->ServerSendReliableMessage( to, outMsg ); - } -} - -/* -================ -idMultiplayerGame::PrintMessageEvent -================ -*/ -void idMultiplayerGame::PrintMessageEvent( int to, msg_evt_t evt, int parm1, int parm2 ) { - switch ( evt ) { - case MSG_SUICIDE: - assert( parm1 >= 0 ); - AddChatLine( gameLocal.m_I18N->Translate( "#str_04293" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - break; - case MSG_KILLED: - assert( parm1 >= 0 && parm2 >= 0 ); - AddChatLine( gameLocal.m_I18N->Translate( "#str_04292" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); - break; - case MSG_KILLEDTEAM: - assert( parm1 >= 0 && parm2 >= 0 ); - AddChatLine( gameLocal.m_I18N->Translate( "#str_04291" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); - break; - case MSG_TELEFRAGGED: - assert( parm1 >= 0 && parm2 >= 0 ); - AddChatLine( gameLocal.m_I18N->Translate( "#str_04290" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), gameLocal.userInfo[ parm2 ].GetString( "ui_name" ) ); - break; - case MSG_DIED: - assert( parm1 >= 0 ); - AddChatLine( gameLocal.m_I18N->Translate( "#str_04289" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - break; - case MSG_VOTE: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04288" ) ); - break; - case MSG_SUDDENDEATH: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04287" ) ); - break; - case MSG_FORCEREADY: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04286" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - if ( gameLocal.entities[ parm1 ] && gameLocal.entities[ parm1 ]->IsType( idPlayer::Type ) ) { - static_cast< idPlayer * >( gameLocal.entities[ parm1 ] )->forcedReady = true; - } - break; - case MSG_JOINEDSPEC: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04285" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - break; - case MSG_TIMELIMIT: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04284" ) ); - break; - case MSG_FRAGLIMIT: - if ( gameLocal.gameType == GAME_LASTMAN ) { - AddChatLine( gameLocal.m_I18N->Translate( "#str_04283" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - } else if ( gameLocal.gameType == GAME_TDM ) { - AddChatLine( gameLocal.m_I18N->Translate( "#str_04282" ), gameLocal.userInfo[ parm1 ].GetString( "ui_team" ) ); - } else { - AddChatLine( gameLocal.m_I18N->Translate( "#str_04281" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ) ); - } - break; - case MSG_JOINTEAM: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04280" ), gameLocal.userInfo[ parm1 ].GetString( "ui_name" ), parm2 ? gameLocal.m_I18N->Translate( "#str_02500" ) : gameLocal.m_I18N->Translate( "#str_02499" ) ); - break; - case MSG_HOLYSHIT: - AddChatLine( gameLocal.m_I18N->Translate( "#str_06732" ) ); - break; - default: - gameLocal.DPrintf( "PrintMessageEvent: unknown message type %d\n", evt ); - return; - } - if ( !gameLocal.isClient ) { - idBitMsg outMsg; - byte msgBuf[1024]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DB ); - outMsg.WriteByte( evt ); - outMsg.WriteByte( parm1 ); - outMsg.WriteByte( parm2 ); - networkSystem->ServerSendReliableMessage( to, outMsg ); - } -} - -/* -================ -idMultiplayerGame::SuddenRespawns -solely for LMN if an end game ( fragLimitTimeout ) was entered and aborted before expiration -LMN players which still have lives left need to be respawned without being marked lastManOver -================ -*/ -void idMultiplayerGame::SuddenRespawn( void ) { - int i; - - if ( gameLocal.gameType != GAME_LASTMAN ) { - return; - } - - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { - continue; - } - if ( !CanPlay( static_cast< idPlayer * >( gameLocal.entities[ i ] ) ) ) { - continue; - } - if ( static_cast< idPlayer * >( gameLocal.entities[ i ] )->lastManOver ) { - continue; - } - static_cast< idPlayer * >( gameLocal.entities[ i ] )->lastManPlayAgain = true; - } -} - -/* -================ -idMultiplayerGame::CheckSpawns -================ -*/ -void idMultiplayerGame::CheckRespawns( idPlayer *spectator ) { - for( int i = 0 ; i < gameLocal.numClients ; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - idPlayer *p = static_cast(ent); - // once we hit sudden death, nobody respawns till game has ended - if ( WantRespawn( p ) || p == spectator ) { - if ( gameState == SUDDENDEATH && gameLocal.gameType != GAME_LASTMAN ) { - // respawn rules while sudden death are different - // sudden death may trigger while a player is dead, so there are still cases where we need to respawn - // don't do any respawns while we are in end game delay though - if ( !fragLimitTimeout ) { - if ( gameLocal.gameType == GAME_TDM || p->IsLeader() ) { -#ifdef _DEBUG - if ( gameLocal.gameType == GAME_TOURNEY ) { - assert( p->entityNumber == currentTourneyPlayer[ 0 ] || p->entityNumber == currentTourneyPlayer[ 1 ] ); - } -#endif - p->ServerSpectate( false ); - } else if ( !p->IsLeader() ) { - // sudden death is rolling, this player is not a leader, have him spectate - p->ServerSpectate( true ); - CheckAbortGame(); - } - } - } else { - if ( gameLocal.gameType == GAME_DM || - gameLocal.gameType == GAME_TDM ) { - if ( gameState == WARMUP || gameState == COUNTDOWN || gameState == GAMEON ) { - p->ServerSpectate( false ); - } - } else if ( gameLocal.gameType == GAME_TOURNEY ) { - if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { - if ( gameState == WARMUP || gameState == COUNTDOWN || gameState == GAMEON ) { - p->ServerSpectate( false ); - } - } else if ( gameState == WARMUP ) { - // make sure empty tourney slots get filled first - FillTourneySlots( ); - if ( i == currentTourneyPlayer[ 0 ] || i == currentTourneyPlayer[ 1 ] ) { - p->ServerSpectate( false ); - } - } - } else if ( gameLocal.gameType == GAME_LASTMAN ) { - if ( gameState == WARMUP || gameState == COUNTDOWN ) { - p->ServerSpectate( false ); - } else if ( gameState == GAMEON || gameState == SUDDENDEATH ) { - if ( gameState == GAMEON && playerState[ i ].fragCount > 0 && p->lastManPresent ) { - assert( !p->lastManOver ); - p->ServerSpectate( false ); - } else if ( p->lastManPlayAgain && p->lastManPresent ) { - assert( gameState == SUDDENDEATH ); - p->ServerSpectate( false ); - } else { - // if a fragLimitTimeout was engaged, do NOT mark lastManOver as that could mean - // everyone ends up spectator and game is stalled with no end - // if the frag limit delay is engaged and cancels out before expiring, LMN players are - // respawned to play the tie again ( through SuddenRespawn and lastManPlayAgain ) - if ( !fragLimitTimeout && !p->lastManOver ) { - common->DPrintf( "client %d has lost all last man lives\n", i ); - // end of the game for this guy, send him to spectators - p->lastManOver = true; - // clients don't have access to lastManOver - // so set the fragCount to something silly ( used in scoreboard and player ranking ) - playerState[ i ].fragCount = LASTMAN_NOLIVES; - p->ServerSpectate( true ); - - //Check for a situation where the last two player dies at the same time and don't - //try to respawn manually...This was causing all players to go into spectate mode - //and the server got stuck - { - int j; - for ( j = 0; j < gameLocal.numClients; j++ ) { - if ( !gameLocal.entities[ j ] ) { - continue; - } - if ( !CanPlay( static_cast< idPlayer * >( gameLocal.entities[ j ] ) ) ) { - continue; - } - if ( !static_cast< idPlayer * >( gameLocal.entities[ j ] )->lastManOver ) { - break; - } - } - if( j == gameLocal.numClients) { - //Everyone is dead so don't allow this player to spectate - //so the match will end - p->ServerSpectate( false ); - } - } - } - } - } - } - } - } else if ( p->wantSpectate && !p->spectating ) { - playerState[ i ].fragCount = 0; // whenever you willingly go spectate during game, your score resets - p->ServerSpectate( true ); - UpdateTourneyLine(); - CheckAbortGame(); - } - } -} - -/* -================ -idMultiplayerGame::ForceReady -================ -*/ -void idMultiplayerGame::ForceReady( ) { - - for( int i = 0 ; i < gameLocal.numClients ; i++ ) { - idEntity *ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - idPlayer *p = static_cast( ent ); - if ( !p->IsReady() ) { - PrintMessageEvent( -1, MSG_FORCEREADY, i ); - p->forcedReady = true; - } - } -} - -/* -================ -idMultiplayerGame::ForceReady_f -================ -*/ -void idMultiplayerGame::ForceReady_f( const idCmdArgs &args ) { - if ( !gameLocal.isMultiplayer || gameLocal.isClient ) { - common->Printf( "forceReady: multiplayer server only\n" ); - return; - } - gameLocal.mpGame.ForceReady(); -} - -/* -================ -idMultiplayerGame::DropWeapon -================ -*/ -void idMultiplayerGame::DropWeapon( int clientNum ) { - assert( !gameLocal.isClient ); - idEntity *ent = gameLocal.entities[ clientNum ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - return; - } - static_cast< idPlayer* >( ent )->DropWeapon( false ); -} - -/* -================ -idMultiplayerGame::DropWeapon_f -================ -*/ -void idMultiplayerGame::DropWeapon_f( const idCmdArgs &args ) { - if ( !gameLocal.isMultiplayer ) { - common->Printf( "clientDropWeapon: only valid in multiplayer\n" ); - return; - } - idBitMsg outMsg; - byte msgBuf[128]; - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_DROPWEAPON ); - networkSystem->ClientSendReliableMessage( outMsg ); -} - -/* -================ -idMultiplayerGame::MessageMode_f -================ -*/ -void idMultiplayerGame::MessageMode_f( const idCmdArgs &args ) { - gameLocal.mpGame.MessageMode( args ); -} - -/* -================ -idMultiplayerGame::MessageMode -================ -*/ -void idMultiplayerGame::MessageMode( const idCmdArgs &args ) { - const char *mode; - int imode; - - if ( !gameLocal.isMultiplayer ) { - common->Printf( "clientMessageMode: only valid in multiplayer\n" ); - return; - } - if ( !mainGui ) { - common->Printf( "no local client\n" ); - return; - } - mode = args.Argv( 1 ); - if ( !mode[ 0 ] ) { - imode = 0; - } else { - imode = atoi( mode ); - } - msgmodeGui->SetStateString( "messagemode", imode ? "1" : "0" ); - msgmodeGui->SetStateString( "chattext", "" ); - nextMenu = 2; - // let the session know that we want our ingame main menu opened - gameLocal.sessionCommand = "game_startmenu"; -} - -/* -================ -idMultiplayerGame::Vote_f -FIXME: voting from console -================ -*/ -void idMultiplayerGame::Vote_f( const idCmdArgs &args ) { } - -/* -================ -idMultiplayerGame::CallVote_f -FIXME: voting from console -================ -*/ -void idMultiplayerGame::CallVote_f( const idCmdArgs &args ) { } - -/* -================ -idMultiplayerGame::ServerStartVote -================ -*/ -void idMultiplayerGame::ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *value ) { - int i; - - assert( vote == VOTE_NONE ); - - // setup - yesVotes = 1; - noVotes = 0; - vote = voteIndex; - voteValue = value; - voteTimeOut = gameLocal.time + 20000; - // mark players allowed to vote - only current ingame players, players joining during vote will be ignored - for ( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) { - playerState[ i ].vote = ( i == clientNum ) ? PLAYER_VOTE_YES : PLAYER_VOTE_WAIT; - } else { - playerState[i].vote = PLAYER_VOTE_NONE; - } - } -} - -/* -================ -idMultiplayerGame::ClientStartVote -================ -*/ -void idMultiplayerGame::ClientStartVote( int clientNum, const char *_voteString ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - if ( !gameLocal.isClient ) { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_STARTVOTE ); - outMsg.WriteByte( clientNum ); - outMsg.WriteString( _voteString ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - } - - voteString = _voteString; - AddChatLine( va( gameLocal.m_I18N->Translate( "#str_04279" ), gameLocal.userInfo[ clientNum ].GetString( "ui_name" ) ) ); - gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE ] ); - if ( clientNum == gameLocal.localClientNum ) { - voted = true; - } else { - voted = false; - } - if ( gameLocal.isClient ) { - // the the vote value to something so the vote line is displayed - vote = VOTE_RESTART; - yesVotes = 1; - noVotes = 0; - } -} - -/* -================ -idMultiplayerGame::ClientUpdateVote -================ -*/ -void idMultiplayerGame::ClientUpdateVote( vote_result_t status, int yesCount, int noCount ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - if ( !gameLocal.isClient ) { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_UPDATEVOTE ); - outMsg.WriteByte( status ); - outMsg.WriteByte( yesCount ); - outMsg.WriteByte( noCount ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - } - - if ( vote == VOTE_NONE ) { - // clients coming in late don't get the vote start and are not allowed to vote - return; - } - - switch ( status ) { - case VOTE_FAILED: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04278" ) ); - gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE_FAILED ] ); - if ( gameLocal.isClient ) { - vote = VOTE_NONE; - } - break; - case VOTE_PASSED: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04277" ) ); - gameSoundWorld->PlayShaderDirectly( GlobalSoundStrings[ SND_VOTE_PASSED ] ); - break; - case VOTE_RESET: - if ( gameLocal.isClient ) { - vote = VOTE_NONE; - } - break; - case VOTE_ABORTED: - AddChatLine( gameLocal.m_I18N->Translate( "#str_04276" ) ); - if ( gameLocal.isClient ) { - vote = VOTE_NONE; - } - break; - default: - break; - } - if ( gameLocal.isClient ) { - yesVotes = yesCount; - noVotes = noCount; - } -} - -/* -================ -idMultiplayerGame::ClientCallVote -================ -*/ -void idMultiplayerGame::ClientCallVote( vote_flags_t voteIndex, const char *voteValue ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - - // send - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CALLVOTE ); - outMsg.WriteByte( voteIndex ); - outMsg.WriteString( voteValue ); - networkSystem->ClientSendReliableMessage( outMsg ); -} - -/* -================ -idMultiplayerGame::CastVote -================ -*/ -void idMultiplayerGame::CastVote( int clientNum, bool castVote ) { - idBitMsg outMsg; - byte msgBuf[ 128 ]; - - if ( clientNum == gameLocal.localClientNum ) { - voted = true; - } - - if ( gameLocal.isClient ) { - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CASTVOTE ); - outMsg.WriteByte( castVote ); - networkSystem->ClientSendReliableMessage( outMsg ); - return; - } - - // sanity - if ( vote == VOTE_NONE ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04275" ) ); - common->DPrintf( "client %d: cast vote while no vote in progress\n", clientNum ); - return; - } - if ( playerState[ clientNum ].vote != PLAYER_VOTE_WAIT ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04274" ) ); - common->DPrintf( "client %d: cast vote - vote %d != PLAYER_VOTE_WAIT\n", clientNum, playerState[ clientNum ].vote ); - return; - } - - if ( castVote ) { - playerState[ clientNum ].vote = PLAYER_VOTE_YES; - yesVotes++; - } else { - playerState[ clientNum ].vote = PLAYER_VOTE_NO; - noVotes++; - } - - ClientUpdateVote( VOTE_UPDATE, static_cast(yesVotes), static_cast(noVotes) ); -} - -/* -================ -idMultiplayerGame::ServerCallVote -================ -*/ -void idMultiplayerGame::ServerCallVote( int clientNum, const idBitMsg &msg ) { - vote_flags_t voteIndex; - int vote_timeLimit, vote_fragLimit, vote_clientNum, vote_gameTypeIndex; //, vote_kickIndex; - char value[ MAX_STRING_CHARS ]; - - assert( clientNum != -1 ); - assert( !gameLocal.isClient ); - - voteIndex = (vote_flags_t)msg.ReadByte( ); - msg.ReadString( value, sizeof( value ) ); - - // sanity checks - setup the vote - if ( vote != VOTE_NONE ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04273" ) ); - common->DPrintf( "client %d: called vote while voting already in progress - ignored\n", clientNum ); - return; - } - switch ( voteIndex ) { - case VOTE_RESTART: - ServerStartVote( clientNum, voteIndex, "" ); - ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04271" ) ); - break; - case VOTE_NEXTMAP: - ServerStartVote( clientNum, voteIndex, "" ); - ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04272" ) ); - break; - case VOTE_TIMELIMIT: - vote_timeLimit = strtol( value, NULL, 10 ); - if ( vote_timeLimit == gameLocal.serverInfo.GetInt( "si_timeLimit" ) ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04270" ) ); - common->DPrintf( "client %d: already at the voted Time Limit\n", clientNum ); - return; - } - if ( vote_timeLimit < si_timeLimit.GetMinValue() || vote_timeLimit > si_timeLimit.GetMaxValue() ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04269" ) ); - common->DPrintf( "client %d: timelimit value out of range for vote: %s\n", clientNum, value ); - return; - } - ServerStartVote( clientNum, voteIndex, value ); - ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04268" ), vote_timeLimit ) ); - break; - case VOTE_FRAGLIMIT: - vote_fragLimit = strtol( value, NULL, 10 ); - if ( vote_fragLimit == gameLocal.serverInfo.GetInt( "si_fragLimit" ) ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04267" ) ); - common->DPrintf( "client %d: already at the voted Frag Limit\n", clientNum ); - return; - } - if ( vote_fragLimit < si_fragLimit.GetMinValue() || vote_fragLimit > si_fragLimit.GetMaxValue() ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04266" ) ); - common->DPrintf( "client %d: fraglimit value out of range for vote: %s\n", clientNum, value ); - return; - } - ServerStartVote( clientNum, voteIndex, value ); - ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04303" ), gameLocal.gameType == GAME_LASTMAN ? gameLocal.m_I18N->Translate( "#str_04264" ) : gameLocal.m_I18N->Translate( "#str_04265" ), vote_fragLimit ) ); - break; - case VOTE_GAMETYPE: - vote_gameTypeIndex = strtol( value, NULL, 10 ); - assert( vote_gameTypeIndex >= 0 && vote_gameTypeIndex <= 3 ); - switch ( vote_gameTypeIndex ) { - case 0: - strcpy( value, "Deathmatch" ); - break; - case 1: - strcpy( value, "Tourney" ); - break; - case 2: - strcpy( value, "Team DM" ); - break; - case 3: - strcpy( value, "Last Man" ); - break; - } - if ( !idStr::Icmp( value, gameLocal.serverInfo.GetString( "si_gameType" ) ) ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04259" ) ); - common->DPrintf( "client %d: already at the voted Game Type\n", clientNum ); - return; - } - ServerStartVote( clientNum, voteIndex, value ); - ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04258" ), value ) ); - break; - case VOTE_KICK: - vote_clientNum = strtol( value, NULL, 10 ); - if ( vote_clientNum == gameLocal.localClientNum ) { - gameLocal.ServerSendChatMessage( clientNum, "server", gameLocal.m_I18N->Translate( "#str_04257" ) ); - common->DPrintf( "client %d: called kick for the server host\n", clientNum ); - return; - } - ServerStartVote( clientNum, voteIndex, va( "%d", vote_clientNum ) ); - ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04302" ), vote_clientNum, gameLocal.userInfo[ vote_clientNum ].GetString( "ui_name" ) ) ); - break; - case VOTE_MAP: { - if ( idStr::FindText( gameLocal.serverInfo.GetString( "si_map" ), value ) != -1 ) { - gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04295" ), value ) ); - common->DPrintf( "client %d: already running the voted map: %s\n", clientNum, value ); - return; - } - int num = fileSystem->GetNumMaps(); - int i; - const idDict *dict; - bool haveMap = false; - for ( i = 0; i < num; i++ ) { - dict = fileSystem->GetMapDecl( i ); - if ( dict && !idStr::Icmp( dict->GetString( "path" ), value ) ) { - haveMap = true; - break; - } - } - if ( !haveMap ) { - gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04296" ), value ) ); - common->Printf( "client %d: map not found: %s\n", clientNum, value ); - return; - } - ServerStartVote( clientNum, voteIndex, value ); - ClientStartVote( clientNum, va( gameLocal.m_I18N->Translate( "#str_04256" ), gameLocal.m_I18N->Translate( dict ? dict->GetString( "name" ) : value ) ) ); - break; - } - case VOTE_SPECTATORS: - if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { - ServerStartVote( clientNum, voteIndex, "" ); - ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04255" ) ); - } else { - ServerStartVote( clientNum, voteIndex, "" ); - ClientStartVote( clientNum, gameLocal.m_I18N->Translate( "#str_04254" ) ); - } - break; - default: - gameLocal.ServerSendChatMessage( clientNum, "server", va( gameLocal.m_I18N->Translate( "#str_04297" ), (int)voteIndex ) ); - common->DPrintf( "client %d: unknown vote index %d\n", clientNum, voteIndex ); - } -} - -/* -================ -idMultiplayerGame::DisconnectClient -================ -*/ -void idMultiplayerGame::DisconnectClient( int clientNum ) { - if ( lastWinner == clientNum ) { - lastWinner = -1; - } - UpdatePlayerRanks(); - CheckAbortGame(); -} - -/* -================ -idMultiplayerGame::CheckAbortGame -================ -*/ -void idMultiplayerGame::CheckAbortGame( void ) { - int i; - if ( gameLocal.gameType == GAME_TOURNEY && gameState == WARMUP ) { - // if a tourney player joined spectators, let someone else have his spot - for ( i = 0; i < 2; i++ ) { - if ( !gameLocal.entities[ currentTourneyPlayer[ i ] ] || static_cast< idPlayer * >( gameLocal.entities[ currentTourneyPlayer[ i ] ] )->spectating ) { - currentTourneyPlayer[ i ] = -1; - } - } - } - // only checks for aborts -> game review below - if ( gameState != COUNTDOWN && gameState != GAMEON && gameState != SUDDENDEATH ) { - return; - } - switch ( gameLocal.gameType ) { - case GAME_TOURNEY: - for ( i = 0; i < 2; i++ ) { - if ( !gameLocal.entities[ currentTourneyPlayer[ i ] ] || static_cast< idPlayer * >( gameLocal.entities[ currentTourneyPlayer[ i ] ] )->spectating ) { - NewState( GAMEREVIEW ); - return; - } - } - break; - default: - if ( !EnoughClientsToPlay() ) { - NewState( GAMEREVIEW ); - } - break; - } -} - -/* -================ -idMultiplayerGame::WantKilled -================ -*/ -void idMultiplayerGame::WantKilled( int clientNum ) { - idEntity *ent = gameLocal.entities[ clientNum ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - static_cast( ent )->Kill( false, false ); - } -} - -/* -================ -idMultiplayerGame::MapRestart -================ -*/ -void idMultiplayerGame::MapRestart( void ) { - int clientNum; - - assert( !gameLocal.isClient ); - if ( gameState != WARMUP ) { - NewState( WARMUP ); - nextState = INACTIVE; - nextStateSwitch = 0; - } - if ( g_balanceTDM.GetBool() && lastGameType != GAME_TDM && gameLocal.gameType == GAME_TDM ) { - for ( clientNum = 0; clientNum < gameLocal.numClients; clientNum++ ) { - if ( gameLocal.entities[ clientNum ] && gameLocal.entities[ clientNum ]->IsType( idPlayer::Type ) ) { - if ( static_cast< idPlayer* >( gameLocal.entities[ clientNum ] )->BalanceTDM() ) { - // core is in charge of syncing down userinfo changes - // it will also call back game through SetUserInfo with the current info for update - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "updateUI %d\n", clientNum ) ); - } - } - } - } - lastGameType = gameLocal.gameType; -} - -/* -================ -idMultiplayerGame::SwitchToTeam -================ -*/ -void idMultiplayerGame::SwitchToTeam( int clientNum, int oldteam, int newteam ) { - idEntity *ent; - int i; - - assert( gameLocal.gameType == GAME_TDM ); - assert( oldteam != newteam ); - assert( !gameLocal.isClient ); - - if ( !gameLocal.isClient && newteam >= 0 && IsInGame( clientNum ) ) { - PrintMessageEvent( -1, MSG_JOINTEAM, clientNum, newteam ); - } - // assign the right teamFragCount - for( i = 0; i < gameLocal.numClients; i++ ) { - if ( i == clientNum ) { - continue; - } - ent = gameLocal.entities[ i ]; - if ( ent && ent->IsType( idPlayer::Type ) && static_cast< idPlayer * >(ent)->team == newteam ) { - playerState[ clientNum ].teamFragCount = playerState[ i ].teamFragCount; - break; - } - } - if ( i == gameLocal.numClients ) { - // alone on this team - playerState[ clientNum ].teamFragCount = 0; - } - if ( gameState == GAMEON && oldteam != -1 ) { - // when changing teams during game, kill and respawn - idPlayer *p = static_cast( gameLocal.entities[ clientNum ] ); - if ( p->IsInTeleport() ) { - p->ServerSendEvent( idPlayer::EVENT_ABORT_TELEPORTER, NULL, false, -1 ); - p->SetPrivateCameraView( NULL ); - } - p->Kill( true, true ); - CheckAbortGame(); - } -} - -/* -================ -idMultiplayerGame::ProcessChatMessage -================ -*/ -void idMultiplayerGame::ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound ) { - idBitMsg outMsg; - byte msgBuf[ 256 ]; - const char *prefix = NULL; - int send_to; // 0 - all, 1 - specs, 2 - team - int i; - idEntity *ent; - idPlayer *p; - idStr prefixed_name; - - assert( !gameLocal.isClient ); - - if ( clientNum >= 0 ) { - p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); - if ( !( p && p->IsType( idPlayer::Type ) ) ) { - return; - } - - if ( p->spectating ) { - prefix = "spectating"; - if ( team || ( !g_spectatorChat.GetBool() && ( gameState == GAMEON || gameState == SUDDENDEATH ) ) ) { - // to specs - send_to = 1; - } else { - // to all - send_to = 0; - } - } else if ( team ) { - prefix = "team"; - // to team - send_to = 2; - } else { - // to all - send_to = 0; - } - } else { - p = NULL; - send_to = 0; - } - // put the message together - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_CHAT ); - if ( prefix ) { - prefixed_name = va( "(%s) %s", prefix, name ); - } else { - prefixed_name = name; - } - outMsg.WriteString( prefixed_name ); - outMsg.WriteString( text, -1, false ); - if ( !send_to ) { - AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); - networkSystem->ServerSendReliableMessage( -1, outMsg ); - if ( sound ) { - PlayGlobalSound( -1, SND_COUNT, sound ); - } - } else { - for ( i = 0; i < gameLocal.numClients; i++ ) { - ent = gameLocal.entities[ i ]; - if ( !ent || !ent->IsType( idPlayer::Type ) ) { - continue; - } - if ( send_to == 1 && static_cast< idPlayer * >( ent )->spectating ) { - if ( sound ) { - PlayGlobalSound( i, SND_COUNT, sound ); - } - if ( i == gameLocal.localClientNum ) { - AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); - } else { - networkSystem->ServerSendReliableMessage( i, outMsg ); - } - } else if ( send_to == 2 && static_cast< idPlayer * >( ent )->team == p->team ) { - if ( sound ) { - PlayGlobalSound( i, SND_COUNT, sound ); - } - if ( i == gameLocal.localClientNum ) { - AddChatLine( "%s^0: %s\n", prefixed_name.c_str(), text ); - } else { - networkSystem->ServerSendReliableMessage( i, outMsg ); - } - } - } - } -} - -/* -================ -idMultiplayerGame::Precache -================ -*/ -void idMultiplayerGame::Precache( void ) { - int i; - idFile *f; - - if ( !gameLocal.isMultiplayer ) { - return; - } - gameLocal.FindEntityDefDict( cv_player_spawnclass.GetString(), false );; - - // skins - idStr str = cvarSystem->GetCVarString( "mod_validSkins" ); - idStr skin; - while ( str.Length() ) { - int n = str.Find( ";" ); - if ( n >= 0 ) { - skin = str.Left( n ); - str = str.Right( str.Length() - n - 1 ); - } else { - skin = str; - str = ""; - } - declManager->FindSkin( skin, false ); - } - - for ( i = 0; ui_skinArgs[ i ]; i++ ) { - declManager->FindSkin( ui_skinArgs[ i ], false ); - } - // MP game sounds - for ( i = 0; i < SND_COUNT; i++ ) { - f = fileSystem->OpenFileRead( GlobalSoundStrings[ i ] ); - fileSystem->CloseFile( f ); - } - // MP guis. just make sure we hit all of them - i = 0; - while ( MPGuis[ i ] ) { - uiManager->FindGui( MPGuis[ i ], true ); - i++; - } -} - -/* -================ -idMultiplayerGame::ToggleSpectate -================ -*/ -void idMultiplayerGame::ToggleSpectate( void ) { - bool spectating; - assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); - - spectating = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_spectate" ), "Spectate" ) == 0 ); - if ( spectating ) { - // always allow toggling to play - cvarSystem->SetCVarString( "ui_spectate", "Play" ); - } else { - // only allow toggling to spectate if spectators are enabled. - if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { - cvarSystem->SetCVarString( "ui_spectate", "Spectate" ); - } else { - gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( "#str_06747" ) ); - } - } -} - -/* -================ -idMultiplayerGame::ToggleReady -================ -*/ -void idMultiplayerGame::ToggleReady( void ) { - bool ready; - assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); - - ready = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_ready" ), "Ready" ) == 0 ); - if ( ready ) { - cvarSystem->SetCVarString( "ui_ready", "Not Ready" ); - } else { - cvarSystem->SetCVarString( "ui_ready", "Ready" ); - } -} - -/* -================ -idMultiplayerGame::ToggleTeam -================ -*/ -void idMultiplayerGame::ToggleTeam( void ) { - bool team; - assert( gameLocal.isClient || gameLocal.localClientNum == 0 ); - - team = ( idStr::Icmp( cvarSystem->GetCVarString( "ui_team" ), "Red" ) == 0 ); - if ( team ) { - cvarSystem->SetCVarString( "ui_team", "Blue" ); - } else { - cvarSystem->SetCVarString( "ui_team", "Red" ); - } -} - -/* -================ -idMultiplayerGame::ToggleUserInfo -================ -*/ -void idMultiplayerGame::ThrottleUserInfo( void ) { - int i; - - assert( gameLocal.localClientNum >= 0 ); - - i = 0; - while ( ThrottleVars[ i ] ) { - if ( idStr::Icmp( gameLocal.userInfo[ gameLocal.localClientNum ].GetString( ThrottleVars[ i ] ), - cvarSystem->GetCVarString( ThrottleVars[ i ] ) ) ) { - if ( gameLocal.realClientTime < switchThrottle[ i ] ) { - AddChatLine( gameLocal.m_I18N->Translate( "#str_04299" ), gameLocal.m_I18N->Translate( ThrottleVarsInEnglish[ i ] ), ( switchThrottle[ i ] - gameLocal.time ) / 1000 + 1 ); - cvarSystem->SetCVarString( ThrottleVars[ i ], gameLocal.userInfo[ gameLocal.localClientNum ].GetString( ThrottleVars[ i ] ) ); - } else { - switchThrottle[ i ] = gameLocal.time + ThrottleDelay[ i ] * 1000; - } - } - i++; - } -} - -/* -================ -idMultiplayerGame::CanPlay -================ -*/ -bool idMultiplayerGame::CanPlay( idPlayer *p ) { - return !p->wantSpectate && playerState[ p->entityNumber ].ingame; -} - -/* -================ -idMultiplayerGame::EnterGame -================ -*/ -void idMultiplayerGame::EnterGame( int clientNum ) { - assert( !gameLocal.isClient ); - - if ( !playerState[ clientNum ].ingame ) { - playerState[ clientNum ].ingame = true; - if ( gameLocal.isMultiplayer ) { - // can't use PrintMessageEvent as clients don't know the nickname yet - gameLocal.ServerSendChatMessage( -1, gameLocal.m_I18N->Translate( "#str_02047" ), va( gameLocal.m_I18N->Translate( "#str_07177" ), gameLocal.userInfo[ clientNum ].GetString( "ui_name" ) ) ); - } - } -} - -/* -================ -idMultiplayerGame::WantRespawn -================ -*/ -bool idMultiplayerGame::WantRespawn( idPlayer *p ) { - return p->forceRespawn && !p->wantSpectate && playerState[ p->entityNumber ].ingame; -} - -/* -================ -idMultiplayerGame::VoiceChat -================ -*/ -void idMultiplayerGame::VoiceChat_f( const idCmdArgs &args ) { - gameLocal.mpGame.VoiceChat( args, false ); -} - -/* -================ -idMultiplayerGame::VoiceChatTeam -================ -*/ -void idMultiplayerGame::VoiceChatTeam_f( const idCmdArgs &args ) { - gameLocal.mpGame.VoiceChat( args, true ); -} - -/* -================ -idMultiplayerGame::VoiceChat -================ -*/ -void idMultiplayerGame::VoiceChat( const idCmdArgs &args, bool team ) { - idBitMsg outMsg; - byte msgBuf[128]; - const char *voc; - const idDict *spawnArgs; - const idKeyValue *keyval; - int index; - - if ( !gameLocal.isMultiplayer ) { - common->Printf( "clientVoiceChat: only valid in multiplayer\n" ); - return; - } - if ( args.Argc() != 2 ) { - common->Printf( "clientVoiceChat: bad args\n" ); - return; - } - // throttle - if ( gameLocal.realClientTime < voiceChatThrottle ) { - return; - } - - voc = args.Argv( 1 ); - spawnArgs = gameLocal.FindEntityDefDict( "player_doommarine", false ); - keyval = spawnArgs->MatchPrefix( "snd_voc_", NULL ); - index = 0; - while ( keyval ) { - if ( !keyval->GetValue().Icmp( voc ) ) { - break; - } - keyval = spawnArgs->MatchPrefix( "snd_voc_", keyval ); - index++; - } - if ( !keyval ) { - common->Printf( "Voice command not found: %s\n", voc ); - return; - } - voiceChatThrottle = gameLocal.realClientTime + 1000; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_VCHAT ); - outMsg.WriteLong( index ); - outMsg.WriteBits( team ? 1 : 0, 1 ); - networkSystem->ClientSendReliableMessage( outMsg ); -} - -/* -================ -idMultiplayerGame::ProcessVoiceChat -================ -*/ -void idMultiplayerGame::ProcessVoiceChat( int clientNum, bool team, int index ) { - const idDict *spawnArgs; - const idKeyValue *keyval; - idStr name; - idStr snd_key; - idStr text_key; - idPlayer *p; - - p = static_cast< idPlayer * >( gameLocal.entities[ clientNum ] ); - if ( !( p && p->IsType( idPlayer::Type ) ) ) { - return; - } - - if ( p->spectating ) { - return; - } - - // lookup the sound def - spawnArgs = gameLocal.FindEntityDefDict( "player_doommarine", false ); - keyval = spawnArgs->MatchPrefix( "snd_voc_", NULL ); - while ( index > 0 && keyval ) { - keyval = spawnArgs->MatchPrefix( "snd_voc_", keyval ); - index--; - } - if ( !keyval ) { - common->DPrintf( "ProcessVoiceChat: unknown chat index %d\n", index ); - return; - } - snd_key = keyval->GetKey(); - name = gameLocal.userInfo[ clientNum ].GetString( "ui_name" ); - sprintf( text_key, "txt_%s", snd_key.Right( snd_key.Length() - 4 ).c_str() ); - if ( team || gameState == COUNTDOWN || gameState == GAMEREVIEW ) { - ProcessChatMessage( clientNum, team, name, spawnArgs->GetString( text_key ), spawnArgs->GetString( snd_key ) ); - } else { - p->StartSound( snd_key, SND_CHANNEL_ANY, 0, true, NULL ); - ProcessChatMessage( clientNum, team, name, spawnArgs->GetString( text_key ), NULL ); - } -} - -/* -================ -idMultiplayerGame::ServerWriteInitialReliableMessages -================ -*/ -void idMultiplayerGame::ServerWriteInitialReliableMessages( int clientNum ) { - idBitMsg outMsg; - byte msgBuf[ MAX_GAME_MESSAGE_SIZE ]; - int i; - idEntity *ent; - - outMsg.Init( msgBuf, sizeof( msgBuf ) ); - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_STARTSTATE ); - // send the game state and start time - outMsg.WriteByte( gameState ); - outMsg.WriteLong( matchStartedTime ); - outMsg.WriteShort( startFragLimit ); - // send the powerup states and the spectate states - for( i = 0; i < gameLocal.numClients; i++ ) { - ent = gameLocal.entities[ i ]; - if ( i != clientNum && ent && ent->IsType( idPlayer::Type ) ) { - outMsg.WriteShort( i ); -// outMsg.WriteShort( static_cast< idPlayer * >( ent )->inventory.powerups ); - outMsg.WriteBits( static_cast< idPlayer * >( ent )->spectating, 1 ); - } - } - outMsg.WriteShort( MAX_CLIENTS ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - - // we send SI in connectResponse messages, but it may have been modified already - outMsg.BeginWriting( ); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_SERVERINFO ); - outMsg.WriteDeltaDict( gameLocal.serverInfo, NULL ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - - // warmup time - if ( gameState == COUNTDOWN ) { - outMsg.BeginWriting(); - outMsg.WriteByte( GAME_RELIABLE_MESSAGE_WARMUPTIME ); - outMsg.WriteLong( warmupEndTime ); - networkSystem->ServerSendReliableMessage( clientNum, outMsg ); - } -} - -/* -================ -idMultiplayerGame::ClientReadStartState -================ -*/ -void idMultiplayerGame::ClientReadStartState( const idBitMsg &msg ) { - int i, client, powerup; - - // read the state in preparation for reading snapshot updates - gameState = (idMultiplayerGame::gameState_t)msg.ReadByte(); - matchStartedTime = msg.ReadLong( ); - startFragLimit = msg.ReadShort( ); - while ( ( client = msg.ReadShort() ) != MAX_CLIENTS ) { - assert( gameLocal.entities[ client ] && gameLocal.entities[ client ]->IsType( idPlayer::Type ) ); - powerup = msg.ReadShort(); - for ( i = 0; i < MAX_POWERUPS; i++ ) { - if ( powerup & ( 1 << i ) ) { - static_cast< idPlayer * >( gameLocal.entities[ client ] )->GivePowerUp( i, 0 ); - } - } - bool spectate = ( msg.ReadBits( 1 ) != 0 ); - static_cast< idPlayer * >( gameLocal.entities[ client ] )->Spectate( spectate ); - } -} - -/* -================ -idMultiplayerGame::ClientReadWarmupTime -================ -*/ -void idMultiplayerGame::ClientReadWarmupTime( const idBitMsg &msg ) { - warmupEndTime = msg.ReadLong(); -} - diff --git a/game/multiplayergame.h b/game/multiplayergame.h deleted file mode 100644 index 91b0f5370..000000000 --- a/game/multiplayergame.h +++ /dev/null @@ -1,359 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MULTIPLAYERGAME_H__ -#define __MULTIPLAYERGAME_H__ - -#ifdef __linux__ -#include "ui/listgui.h" -#endif - -/* -=============================================================================== - - Basic DOOM multiplayer - -=============================================================================== -*/ - -class idPlayer; - -typedef enum { - GAME_SP, - GAME_DM, - GAME_TOURNEY, - GAME_TDM, - GAME_LASTMAN -} gameType_t; - -typedef enum { - PLAYER_VOTE_NONE, - PLAYER_VOTE_NO, - PLAYER_VOTE_YES, - PLAYER_VOTE_WAIT // mark a player allowed to vote -} playerVote_t; - -typedef struct mpPlayerState_s { - int ping; // player ping - int fragCount; // kills - int teamFragCount; // team kills - int wins; // wins - playerVote_t vote; // player's vote - bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui - bool ingame; -} mpPlayerState_t; - -const int NUM_CHAT_NOTIFY = 5; -const int CHAT_FADE_TIME = 400; -const int FRAGLIMIT_DELAY = 2000; - -const int MP_PLAYER_MINFRAGS = -100; -const int MP_PLAYER_MAXFRAGS = 100; -const int MP_PLAYER_MAXWINS = 100; -const int MP_PLAYER_MAXPING = 999; - -typedef struct mpChatLine_s { - idStr line; - short fade; // starts high and decreases, line is removed once reached 0 -} mpChatLine_t; - -typedef enum { - SND_YOUWIN = 0, - SND_YOULOSE, - SND_FIGHT, - SND_VOTE, - SND_VOTE_PASSED, - SND_VOTE_FAILED, - SND_THREE, - SND_TWO, - SND_ONE, - SND_SUDDENDEATH, - SND_COUNT -} snd_evt_t; - -class idMultiplayerGame { -public: - - idMultiplayerGame(); - - void Shutdown( void ); - - // resets everything and prepares for a match - void Reset( void ); - - // setup local data for a new player - void SpawnPlayer( int clientNum ); - - // checks rules and updates state of the mp game - void Run( void ); - - // draws mp hud, scoredboard, etc.. - bool Draw( int clientNum ); - - // updates a player vote - void PlayerVote( int clientNum, playerVote_t vote ); - - // updates frag counts and potentially ends the match in sudden death - void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag ); - - void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3))); - - void UpdateMainGui( void ); - idUserInterface*StartMenu( void ); - const char* HandleGuiCommands( const char *menuCommand ); - void SetMenuSkin( void ); - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - - // game state - typedef enum { - INACTIVE = 0, // not running - WARMUP, // warming up - COUNTDOWN, // post warmup pre-game - GAMEON, // game is on - SUDDENDEATH, // game is on but in sudden death, first frag wins - GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value) - NEXTGAME, - STATE_COUNT - } gameState_t; - static const char *GameStateStrings[ STATE_COUNT ]; - idMultiplayerGame::gameState_t GetGameState( void ) const; - - static const char *GlobalSoundStrings[ SND_COUNT ]; - void PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL ); - - // more compact than a chat line - typedef enum { - MSG_SUICIDE = 0, - MSG_KILLED, - MSG_KILLEDTEAM, - MSG_DIED, - MSG_VOTE, - MSG_VOTEPASSED, - MSG_VOTEFAILED, - MSG_SUDDENDEATH, - MSG_FORCEREADY, - MSG_JOINEDSPEC, - MSG_TIMELIMIT, - MSG_FRAGLIMIT, - MSG_TELEFRAGGED, - MSG_JOINTEAM, - MSG_HOLYSHIT, - MSG_COUNT - } msg_evt_t; - void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 ); - - void DisconnectClient( int clientNum ); - static void ForceReady_f( const idCmdArgs &args ); - static void DropWeapon_f( const idCmdArgs &args ); - static void MessageMode_f( const idCmdArgs &args ); - static void VoiceChat_f( const idCmdArgs &args ); - static void VoiceChatTeam_f( const idCmdArgs &args ); - - typedef enum { - VOTE_RESTART = 0, - VOTE_TIMELIMIT, - VOTE_FRAGLIMIT, - VOTE_GAMETYPE, - VOTE_KICK, - VOTE_MAP, - VOTE_SPECTATORS, - VOTE_NEXTMAP, - VOTE_COUNT, - VOTE_NONE - } vote_flags_t; - - typedef enum { - VOTE_UPDATE, - VOTE_FAILED, - VOTE_PASSED, // passed, but no reset yet - VOTE_ABORTED, - VOTE_RESET // tell clients to reset vote state - } vote_result_t; - - static void Vote_f( const idCmdArgs &args ); - static void CallVote_f( const idCmdArgs &args ); - void ClientCallVote( vote_flags_t voteIndex, const char *voteValue ); - void ServerCallVote( int clientNum, const idBitMsg &msg ); - void ClientStartVote( int clientNum, const char *voteString ); - void ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue ); - void ClientUpdateVote( vote_result_t result, int yesCount, int noCount ); - void CastVote( int clientNum, bool vote ); - void ExecuteVote( void ); - - void WantKilled( int clientNum ); - int NumActualClients( bool countSpectators, int *teamcount = NULL ); - void DropWeapon( int clientNum ); - void MapRestart( void ); - // called by idPlayer whenever it detects a team change (init or switch) - void SwitchToTeam( int clientNum, int oldteam, int newteam ); - bool IsPureReady( void ) const; - void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound ); - void ProcessVoiceChat( int clientNum, bool team, int index ); - - void Precache( void ); - - // throttle UI switch rates - void ThrottleUserInfo( void ); - void ToggleSpectate( void ); - void ToggleReady( void ); - void ToggleTeam( void ); - - void ClearFrags( int clientNum ); - - void EnterGame( int clientNum ); - bool CanPlay( idPlayer *p ); - bool IsInGame( int clientNum ); - bool WantRespawn( idPlayer *p ); - - void ServerWriteInitialReliableMessages( int clientNum ); - void ClientReadStartState( const idBitMsg &msg ); - void ClientReadWarmupTime( const idBitMsg &msg ); - - void ServerClientConnect( int clientNum ); - - void PlayerStats( int clientNum, char *data, const int len ); - -private: - static const char *MPGuis[]; - static const char *ThrottleVars[]; - static const char *ThrottleVarsInEnglish[]; - static const int ThrottleDelay[]; - - // state vars - gameState_t gameState; // what state the current game is in - gameState_t nextState; // state to switch to when nextStateSwitch is hit - int pingUpdateTime; // time to update ping - - mpPlayerState_t playerState[ MAX_CLIENTS ]; - - // keep track of clients which are willingly in spectator mode - - // vote vars - vote_flags_t vote; // active vote or VOTE_NONE - int voteTimeOut; // when the current vote expires - int voteExecTime; // delay between vote passed msg and execute - float yesVotes; // counter for yes votes - float noVotes; // and for no votes - idStr voteValue; // the data voted upon ( server ) - idStr voteString; // the vote string ( client ) - bool voted; // hide vote box ( client ) - int kickVoteMap[ MAX_CLIENTS ]; - - // time related - int nextStateSwitch; // time next state switch - int warmupEndTime; // warmup till.. - int matchStartedTime; // time current match started - - // tourney - int currentTourneyPlayer[2];// our current set of players - int lastWinner; // plays again - - // warmup - idStr warmupText; // text shown in warmup area of screen - bool one, two, three; // keeps count down voice from repeating - - // guis - idUserInterface *scoreBoard; // scoreboard - idUserInterface *spectateGui; // spectate info - idUserInterface *guiChat; // chat text - idUserInterface *mainGui; // ready / nick / votes etc. - idListGUI *mapList; - idUserInterface *msgmodeGui; // message mode - int currentMenu; // 0 - none, 1 - mainGui, 2 - msgmodeGui - int nextMenu; // if 0, will do mainGui - bool bCurrentMenuMsg; // send menu state updates to server - - // chat data - mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ]; - int chatHistoryIndex; - int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY - bool chatDataUpdated; - int lastChatLineTime; - - // rankings are used by UpdateScoreboard and UpdateHud - int numRankedPlayers; // ranked players, others may be empty slots or spectators - idPlayer * rankedPlayers[MAX_CLIENTS]; - - bool pureReady; // defaults to false, set to true once server game is running with pure checksums - int fragLimitTimeout; - - int switchThrottle[ 3 ]; - int voiceChatThrottle; - - gameType_t lastGameType; // for restarts - int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON - -private: - void UpdatePlayerRanks(); - - // updates the passed gui with current score information - void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec ); - void UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player ); - - void ClearGuis( void ); - void DrawScoreBoard( idPlayer *player ); - void UpdateHud( idPlayer *player, idUserInterface *hud ); - bool Warmup( void ); - void CheckVote( void ); - bool AllPlayersReady( void ); - idPlayer * FragLimitHit( void ); - idPlayer * FragLeader( void ); - bool TimeLimitHit( void ); - void NewState( gameState_t news, idPlayer *player = NULL ); - void UpdateWinsLosses( idPlayer *winner ); - // fill any empty tourney slots based on the current tourney ranks - void FillTourneySlots( void ); - void CycleTourneyPlayers( void ); - // walk through the tourneyRank to build a wait list for the clients - void UpdateTourneyLine( void ); - const char * GameTime( void ); - void Clear( void ); - bool EnoughClientsToPlay( void ); - void ClearChatData( void ); - void DrawChat( void ); - // go through the clients, and see if they want to be respawned, and if the game allows it - // called during normal gameplay for death -> respawn cycles - // and for a spectator who want back in the game (see param) - void CheckRespawns( idPlayer *spectator = NULL ); - void ForceReady(); - // when clients disconnect or join spectate during game, check if we need to end the game - void CheckAbortGame( void ); - void MessageMode( const idCmdArgs &args ); - void DisableMenu( void ); - void SetMapShot( void ); - // scores in TDM - void TeamScore( int entityNumber, int team, int delta ); - void VoiceChat( const idCmdArgs &args, bool team ); - void DumpTourneyLine( void ); - void SuddenRespawn( void ); -}; - -ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const { - return gameState; -} - -ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const { - return pureReady; -} - -ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) { - playerState[ clientNum ].fragCount = 0; -} - -ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) { - return playerState[ clientNum ].ingame; -} - -#endif /* !__MULTIPLAYERGAME_H__ */ - diff --git a/game/physics/Clip.cpp b/game/physics/Clip.cpp new file mode 100644 index 000000000..62c18f6af --- /dev/null +++ b/game/physics/Clip.cpp @@ -0,0 +1,1678 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#define MAX_SECTOR_DEPTH 12 +#define MAX_SECTORS ((1<<(MAX_SECTOR_DEPTH+1))-1) + +typedef struct clipSector_s { + int axis; // -1 = leaf node + float dist; + struct clipSector_s * children[2]; + struct clipLink_s * clipLinks; +} clipSector_t; + +typedef struct clipLink_s { + idClipModel * clipModel; + struct clipSector_s * sector; + struct clipLink_s * prevInSector; + struct clipLink_s * nextInSector; + struct clipLink_s * nextLink; +} clipLink_t; + +typedef struct trmCache_s { + idTraceModel trm; + int refCount; + float volume; + idVec3 centerOfMass; + idMat3 inertiaTensor; +} trmCache_t; + +idVec3 vec3_boxEpsilon( CM_BOX_EPSILON, CM_BOX_EPSILON, CM_BOX_EPSILON ); + +idBlockAlloc clipLinkAllocator; + + +/* +=============================================================== + + idClipModel trace model cache + +=============================================================== +*/ + +static idList traceModelCache; +static idHashIndex traceModelHash; + +/* +=============== +idClipModel::ClearTraceModelCache +=============== +*/ +void idClipModel::ClearTraceModelCache( void ) { + traceModelCache.DeleteContents( true ); + traceModelHash.Free(); +} + +/* +=============== +idClipModel::TraceModelCacheSize +=============== +*/ +int idClipModel::TraceModelCacheSize( void ) { + return traceModelCache.Num() * sizeof( idTraceModel ); +} + +/* +=============== +idClipModel::AllocTraceModel +=============== +*/ +int idClipModel::AllocTraceModel( const idTraceModel &trm ) { + int i, hashKey, traceModelIndex; + trmCache_t *entry; + + hashKey = GetTraceModelHashKey( trm ); + for ( i = traceModelHash.First( hashKey ); i >= 0; i = traceModelHash.Next( i ) ) { + if ( traceModelCache[i]->trm == trm ) { + traceModelCache[i]->refCount++; + return i; + } + } + + entry = new trmCache_t; + entry->trm = trm; + + // If density is 1 the volume has the same size as the mass (m = d*v). The calling code wants to know the volume, + // and with density equal to 1 it's allowed to use the mass value returned by idTraceModel::GetMassProperties(). + // That's what's happening here. + entry->trm.GetMassProperties( 1.0f, entry->volume, entry->centerOfMass, entry->inertiaTensor ); + entry->refCount = 1; + + traceModelIndex = traceModelCache.Append( entry ); + traceModelHash.Add( hashKey, traceModelIndex ); + return traceModelIndex; +} + +/* +=============== +idClipModel::FreeTraceModel +=============== +*/ +void idClipModel::FreeTraceModel( const int traceModelIndex ) { + if ( traceModelIndex < 0 || traceModelIndex >= traceModelCache.Num() ) { + gameLocal.Warning( "idClipModel::FreeTraceModel: traceModelIndex %i out of range (0..%i)", traceModelIndex, traceModelCache.Num() ); + return; + } + if ( traceModelCache[traceModelIndex]->refCount <= 0 ) { + gameLocal.Warning( "idClipModel::FreeTraceModel: tried to free uncached trace model (index=%i)", traceModelIndex ); + return; + } + traceModelCache[traceModelIndex]->refCount--; +} + +/* +=============== +idClipModel::GetCachedTraceModel +=============== +*/ +idTraceModel *idClipModel::GetCachedTraceModel( int traceModelIndex ) { + return &traceModelCache[traceModelIndex]->trm; +} + +/* +=============== +idClipModel::GetTraceModelHashKey +=============== +*/ +int idClipModel::GetTraceModelHashKey( const idTraceModel &trm ) { + const idVec3 &v = trm.bounds[0]; + return ( trm.type << 8 ) ^ ( trm.numVerts << 4 ) ^ ( trm.numEdges << 2 ) ^ ( trm.numPolys << 0 ) ^ idMath::FloatHash( v.ToFloatPtr(), v.GetDimension() ); +} + +/* +=============== +idClipModel::SaveTraceModels +=============== +*/ +void idClipModel::SaveTraceModels( idSaveGame *savefile ) { + int i; + + savefile->WriteInt( traceModelCache.Num() ); + for ( i = 0; i < traceModelCache.Num(); i++ ) { + trmCache_t *entry = traceModelCache[i]; + + savefile->WriteTraceModel( entry->trm ); + savefile->WriteFloat( entry->volume ); + savefile->WriteVec3( entry->centerOfMass ); + savefile->WriteMat3( entry->inertiaTensor ); + } +} + +/* +=============== +idClipModel::RestoreTraceModels +=============== +*/ +void idClipModel::RestoreTraceModels( idRestoreGame *savefile ) { + int i, num; + + ClearTraceModelCache(); + + savefile->ReadInt( num ); + traceModelCache.SetNum( num ); + + for ( i = 0; i < num; i++ ) { + trmCache_t *entry = new trmCache_t; + + savefile->ReadTraceModel( entry->trm ); + + savefile->ReadFloat( entry->volume ); + savefile->ReadVec3( entry->centerOfMass ); + savefile->ReadMat3( entry->inertiaTensor ); + entry->refCount = 0; + + traceModelCache[i] = entry; + traceModelHash.Add( GetTraceModelHashKey( entry->trm ), i ); + } +} + + +/* +=============================================================== + + idClipModel + +=============================================================== +*/ + +/* +================ +idClipModel::LoadModel +================ +*/ +bool idClipModel::LoadModel( const char *name ) { + renderModelHandle = -1; + if ( traceModelIndex != -1 ) { + FreeTraceModel( traceModelIndex ); + traceModelIndex = -1; + } + collisionModelHandle = collisionModelManager->LoadModel( name, false ); + if ( collisionModelHandle ) { + collisionModelManager->GetModelBounds( collisionModelHandle, bounds ); + collisionModelManager->GetModelContents( collisionModelHandle, contents ); + return true; + } else { + bounds.Zero(); + return false; + } +} + +/* +================ +idClipModel::LoadModel +================ +*/ +void idClipModel::LoadModel( const idTraceModel &trm ) { + collisionModelHandle = 0; + renderModelHandle = -1; + if ( traceModelIndex != -1 ) { + FreeTraceModel( traceModelIndex ); + } + traceModelIndex = AllocTraceModel( trm ); + bounds = trm.bounds; +} + +/* +================ +idClipModel::LoadModel +================ +*/ +void idClipModel::LoadModel( const int renderModelHandle ) { + collisionModelHandle = 0; + this->renderModelHandle = renderModelHandle; + if ( renderModelHandle != -1 ) { + const renderEntity_t *renderEntity = gameRenderWorld->GetRenderEntity( renderModelHandle ); + if ( renderEntity ) { + bounds = renderEntity->bounds; + } + } + if ( traceModelIndex != -1 ) { + FreeTraceModel( traceModelIndex ); + traceModelIndex = -1; + } +} + +/* +================ +idClipModel::Init +================ +*/ +void idClipModel::Init( void ) { + enabled = true; + entity = NULL; + id = 0; + owner = NULL; + origin.Zero(); + axis.Identity(); + bounds.Zero(); + absBounds.Zero(); + material = NULL; + contents = CONTENTS_BODY; + collisionModelHandle = 0; + renderModelHandle = -1; + traceModelIndex = -1; + clipLinks = NULL; + touchCount = -1; +} + +/* +================ +idClipModel::idClipModel +================ +*/ +idClipModel::idClipModel( void ) { + Init(); +} + +/* +================ +idClipModel::idClipModel +================ +*/ +idClipModel::idClipModel( const char *name ) { + Init(); + LoadModel( name ); +} + +/* +================ +idClipModel::idClipModel +================ +*/ +idClipModel::idClipModel( const idTraceModel &trm ) { + Init(); + LoadModel( trm ); +} + +/* +================ +idClipModel::idClipModel +================ +*/ +idClipModel::idClipModel( const int renderModelHandle ) { + Init(); + contents = CONTENTS_RENDERMODEL; + LoadModel( renderModelHandle ); +} + +/* +================ +idClipModel::idClipModel +================ +*/ +idClipModel::idClipModel( const idClipModel *model ) { + enabled = model->enabled; + entity = model->entity; + id = model->id; + owner = model->owner; + origin = model->origin; + axis = model->axis; + bounds = model->bounds; + absBounds = model->absBounds; + material = model->material; + contents = model->contents; + collisionModelHandle = model->collisionModelHandle; + traceModelIndex = -1; + if ( model->traceModelIndex != -1 ) { + LoadModel( *GetCachedTraceModel( model->traceModelIndex ) ); + } + renderModelHandle = model->renderModelHandle; + clipLinks = NULL; + touchCount = -1; +} + +/* +================ +idClipModel::~idClipModel +================ +*/ +idClipModel::~idClipModel( void ) { + // make sure the clip model is no longer linked + Unlink(); + if ( traceModelIndex != -1 ) { + FreeTraceModel( traceModelIndex ); + } +} + +/* +================ +idClipModel::Save +================ +*/ +void idClipModel::Save( idSaveGame *savefile ) const { + savefile->WriteBool( enabled ); + savefile->WriteObject( entity ); + savefile->WriteInt( id ); + savefile->WriteObject( owner ); + savefile->WriteVec3( origin ); + savefile->WriteMat3( axis ); + savefile->WriteBounds( bounds ); + savefile->WriteBounds( absBounds ); + savefile->WriteMaterial( material ); + savefile->WriteInt( contents ); + if ( collisionModelHandle >= 0 ) { + savefile->WriteString( collisionModelManager->GetModelName( collisionModelHandle ) ); + } else { + savefile->WriteString( "" ); + } + savefile->WriteInt( traceModelIndex ); + savefile->WriteBool( clipLinks != NULL ); + savefile->WriteInt( touchCount ); +} + +/* +================ +idClipModel::Restore +================ +*/ +void idClipModel::Restore( idRestoreGame *savefile ) { + idStr collisionModelName; + bool linked; + + savefile->ReadBool( enabled ); + savefile->ReadObject( reinterpret_cast( entity ) ); + savefile->ReadInt( id ); + savefile->ReadObject( reinterpret_cast( owner ) ); + savefile->ReadVec3( origin ); + savefile->ReadMat3( axis ); + savefile->ReadBounds( bounds ); + savefile->ReadBounds( absBounds ); + savefile->ReadMaterial( material ); + savefile->ReadInt( contents ); + savefile->ReadString( collisionModelName ); + if ( collisionModelName.Length() ) { + collisionModelHandle = collisionModelManager->LoadModel( collisionModelName, false ); + } else { + collisionModelHandle = -1; + } + savefile->ReadInt( traceModelIndex ); + if ( traceModelIndex >= 0 ) { + traceModelCache[traceModelIndex]->refCount++; + } + savefile->ReadBool( linked ); + savefile->ReadInt( touchCount ); + + // the render model will be set when the clip model is linked, so do not restore it + renderModelHandle = -1; + clipLinks = NULL; + touchCount = -1; + + if ( linked ) { + Link( gameLocal.clip, entity, id, origin, axis, renderModelHandle ); + } +} + +/* +================ +idClipModel::SetPosition +================ +*/ +void idClipModel::SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ) { + if ( clipLinks ) { + Unlink(); // unlink from old position + } + origin = newOrigin; + axis = newAxis; +} + +/* +================ +idClipModel::Handle +================ +*/ +cmHandle_t idClipModel::Handle( void ) const { + assert( renderModelHandle == -1 ); + if ( collisionModelHandle ) { + return collisionModelHandle; + } else if ( traceModelIndex != -1 ) { + return collisionModelManager->SetupTrmModel( *GetCachedTraceModel( traceModelIndex ), material ); + } else { + // this happens in multiplayer on the combat models + gameLocal.Warning( "idClipModel::Handle: clip model %d on '%s' (%x) is not a collision or trace model", id, entity->name.c_str(), entity->entityNumber ); + return 0; + } +} + +/* +================ +idClipModel::GetMassProperties +================ +*/ +void idClipModel::GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const { + if ( traceModelIndex == -1 ) { + gameLocal.Error( "idClipModel::GetMassProperties: clip model %d on '%s' is not a trace model\n", id, entity->name.c_str() ); + } + + trmCache_t *entry = traceModelCache[traceModelIndex]; + mass = entry->volume * density; + centerOfMass = entry->centerOfMass; + inertiaTensor = density * entry->inertiaTensor; +} + +/* +=============== +idClipModel::Unlink +=============== +*/ +void idClipModel::Unlink( void ) { + clipLink_t *link; + + for ( link = clipLinks; link; link = clipLinks ) { + clipLinks = link->nextLink; + if ( link->prevInSector ) { + link->prevInSector->nextInSector = link->nextInSector; + } else { + link->sector->clipLinks = link->nextInSector; + } + if ( link->nextInSector ) { + link->nextInSector->prevInSector = link->prevInSector; + } + clipLinkAllocator.Free( link ); + } +} + +/* +=============== +idClipModel::Link_r +=============== +*/ +void idClipModel::Link_r( struct clipSector_s *node ) { + clipLink_t *link; + + while( node->axis != -1 ) { + if ( absBounds[0][node->axis] > node->dist ) { + node = node->children[0]; + } else if ( absBounds[1][node->axis] < node->dist ) { + node = node->children[1]; + } else { + Link_r( node->children[0] ); + node = node->children[1]; + } + } + + link = clipLinkAllocator.Alloc(); + link->clipModel = this; + link->sector = node; + link->nextInSector = node->clipLinks; + link->prevInSector = NULL; + if ( node->clipLinks ) { + node->clipLinks->prevInSector = link; + } + node->clipLinks = link; + link->nextLink = clipLinks; + clipLinks = link; +} + +/* +=============== +idClipModel::Link +=============== +*/ +void idClipModel::Link( idClip &clp ) { + + assert( idClipModel::entity ); + if ( !idClipModel::entity ) { + return; + } + + if ( clipLinks ) { + Unlink(); // unlink from old position + } + + if ( bounds.IsCleared() ) { + return; + } + + // set the abs box + if ( axis.IsRotated() ) { + // expand for rotation + absBounds.FromTransformedBounds( bounds, origin, axis ); + } else { + // normal + absBounds[0] = bounds[0] + origin; + absBounds[1] = bounds[1] + origin; + } + + // because movement is clipped an epsilon away from an actual edge, + // we must fully check even when bounding boxes don't quite touch + absBounds[0] -= vec3_boxEpsilon; + absBounds[1] += vec3_boxEpsilon; + + Link_r( clp.clipSectors ); +} + +/* +=============== +idClipModel::Link +=============== +*/ +void idClipModel::Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle ) { + + this->entity = ent; + this->id = newId; + this->origin = newOrigin; + this->axis = newAxis; + if ( renderModelHandle != -1 ) { + this->renderModelHandle = renderModelHandle; + const renderEntity_t *renderEntity = gameRenderWorld->GetRenderEntity( renderModelHandle ); + if ( renderEntity ) { + this->bounds = renderEntity->bounds; + } + } + this->Link( clp ); +} + +/* +============ +idClipModel::CheckModel +============ +*/ +cmHandle_t idClipModel::CheckModel( const char *name ) { + return collisionModelManager->LoadModel( name, false ); +} + + +/* +=============================================================== + + idClip + +=============================================================== +*/ + +/* +=============== +idClip::idClip +=============== +*/ +idClip::idClip( void ) { + numClipSectors = 0; + clipSectors = NULL; + worldBounds.Zero(); + numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; +} + +/* +=============== +idClip::CreateClipSectors_r + +Builds a uniformly subdivided tree for the given world size +=============== +*/ +clipSector_t *idClip::CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector ) { + int i; + clipSector_t *anode; + idVec3 size; + idBounds front, back; + + anode = &clipSectors[idClip::numClipSectors]; + idClip::numClipSectors++; + + if ( depth == MAX_SECTOR_DEPTH ) { + anode->axis = -1; + anode->children[0] = anode->children[1] = NULL; + + for ( i = 0; i < 3; i++ ) { + if ( bounds[1][i] - bounds[0][i] > maxSector[i] ) { + maxSector[i] = bounds[1][i] - bounds[0][i]; + } + } + return anode; + } + + size = bounds[1] - bounds[0]; + if ( size[0] >= size[1] && size[0] >= size[2] ) { + anode->axis = 0; + } else if ( size[1] >= size[0] && size[1] >= size[2] ) { + anode->axis = 1; + } else { + anode->axis = 2; + } + + anode->dist = 0.5f * ( bounds[1][anode->axis] + bounds[0][anode->axis] ); + + front = bounds; + back = bounds; + + front[0][anode->axis] = back[1][anode->axis] = anode->dist; + + anode->children[0] = CreateClipSectors_r( depth+1, front, maxSector ); + anode->children[1] = CreateClipSectors_r( depth+1, back, maxSector ); + + return anode; +} + +/* +=============== +idClip::Init +=============== +*/ +void idClip::Init( void ) { + cmHandle_t h; + idVec3 size, maxSector = vec3_origin; + + // clear clip sectors + clipSectors = new clipSector_t[MAX_SECTORS]; + memset( clipSectors, 0, MAX_SECTORS * sizeof( clipSector_t ) ); + numClipSectors = 0; + touchCount = -1; + // get world map bounds + h = collisionModelManager->LoadModel( "worldMap", false ); + collisionModelManager->GetModelBounds( h, worldBounds ); + // create world sectors + CreateClipSectors_r( 0, worldBounds, maxSector ); + + size = worldBounds[1] - worldBounds[0]; + gameLocal.Printf( "map bounds are (%1.1f, %1.1f, %1.1f)\n", size[0], size[1], size[2] ); + gameLocal.Printf( "max clip sector is (%1.1f, %1.1f, %1.1f)\n", maxSector[0], maxSector[1], maxSector[2] ); + + // initialize a default clip model + defaultClipModel.LoadModel( idTraceModel( idBounds( idVec3( 0, 0, 0 ) ).Expand( 8 ) ) ); + + // set counters to zero + numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; +} + +/* +=============== +idClip::Shutdown +=============== +*/ +void idClip::Shutdown( void ) { + delete[] clipSectors; + clipSectors = NULL; + + // free the trace model used for the temporaryClipModel + if ( temporaryClipModel.traceModelIndex != -1 ) { + idClipModel::FreeTraceModel( temporaryClipModel.traceModelIndex ); + temporaryClipModel.traceModelIndex = -1; + } + + // free the trace model used for the defaultClipModel + if ( defaultClipModel.traceModelIndex != -1 ) { + idClipModel::FreeTraceModel( defaultClipModel.traceModelIndex ); + defaultClipModel.traceModelIndex = -1; + } + + clipLinkAllocator.Shutdown(); +} + +/* +==================== +idClip::ClipModelsTouchingBounds_r +==================== +*/ +typedef struct listParms_s { + idBounds bounds; + int contentMask; + idClipModel ** list; + int count; + int maxCount; +} listParms_t; + +void idClip::ClipModelsTouchingBounds_r( const struct clipSector_s *node, listParms_t &parms ) const { + + while( node->axis != -1 ) { + if ( parms.bounds[0][node->axis] > node->dist ) { + node = node->children[0]; + } else if ( parms.bounds[1][node->axis] < node->dist ) { + node = node->children[1]; + } else { + ClipModelsTouchingBounds_r( node->children[0], parms ); + node = node->children[1]; + } + } + + for ( clipLink_t *link = node->clipLinks; link; link = link->nextInSector ) { + idClipModel *check = link->clipModel; + + // if the clip model is enabled + if ( !check->enabled ) { + continue; + } + + // avoid duplicates in the list + if ( check->touchCount == touchCount ) { + continue; + } + + // if the clip model does not have any contents we are looking for + if ( !( check->contents & parms.contentMask ) ) { + continue; + } + + // if the bounds really do overlap + if ( check->absBounds[0][0] > parms.bounds[1][0] || + check->absBounds[1][0] < parms.bounds[0][0] || + check->absBounds[0][1] > parms.bounds[1][1] || + check->absBounds[1][1] < parms.bounds[0][1] || + check->absBounds[0][2] > parms.bounds[1][2] || + check->absBounds[1][2] < parms.bounds[0][2] ) { + continue; + } + + if ( parms.count >= parms.maxCount ) { + gameLocal.Warning( "idClip::ClipModelsTouchingBounds_r: max count (%i) reached", parms.maxCount ); + return; + } + + check->touchCount = touchCount; + parms.list[parms.count] = check; + parms.count++; + } +} + +/* +================ +idClip::ClipModelsTouchingBounds +================ +*/ +int idClip::ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const { + listParms_t parms; + + if ( bounds[0][0] > bounds[1][0] || + bounds[0][1] > bounds[1][1] || + bounds[0][2] > bounds[1][2] ) { + // we should not go through the tree for degenerate or backwards bounds + assert( false ); + return 0; + } + + parms.bounds[0] = bounds[0] - vec3_boxEpsilon; + parms.bounds[1] = bounds[1] + vec3_boxEpsilon; + parms.contentMask = contentMask; + parms.list = clipModelList; + parms.count = 0; + parms.maxCount = maxCount; + + touchCount++; + ClipModelsTouchingBounds_r( clipSectors, parms ); + + return parms.count; +} + +/* +================ +idClip::EntitiesTouchingBounds +================ +*/ +int idClip::EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const { + idClipModel *clipModelList[MAX_GENTITIES]; + int i, j, count, entCount; + + count = idClip::ClipModelsTouchingBounds( bounds, contentMask, clipModelList, MAX_GENTITIES ); + entCount = 0; + for ( i = 0; i < count; i++ ) { + // entity could already be in the list because an entity can use multiple clip models + for ( j = 0; j < entCount; j++ ) { + if ( entityList[j] == clipModelList[i]->entity ) { + break; + } + } + if ( j >= entCount ) { + if ( entCount >= maxCount ) { + gameLocal.Warning( "idClip::EntitiesTouchingBounds: max count (%i) reached.", maxCount ); + return entCount; + } + entityList[entCount] = clipModelList[i]->entity; + entCount++; + } + } + + return entCount; +} + +/* +==================== +idClip::GetTraceClipModels + + an ent will be excluded from testing if: + cm->entity == passEntity ( don't clip against the pass entity ) + cm->entity == passOwner ( missiles don't clip with owner ) + cm->owner == passEntity ( don't interact with your own missiles ) + cm->owner == passOwner ( don't interact with other missiles from same owner ) +==================== +*/ +int idClip::GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const { + int i, num; + idClipModel *cm; + idEntity *passOwner; + + num = ClipModelsTouchingBounds( bounds, contentMask, clipModelList, MAX_GENTITIES ); + + if ( !passEntity ) { + return num; + } + + if ( passEntity->GetPhysics()->GetNumClipModels() > 0 ) { + passOwner = passEntity->GetPhysics()->GetClipModel()->GetOwner(); + } else { + passOwner = NULL; + } + + for ( i = 0; i < num; i++ ) { + + cm = clipModelList[i]; + + // check if we should ignore this entity + if ( cm->entity == passEntity ) { + clipModelList[i] = NULL; // don't clip against the pass entity + } else if ( cm->entity == passOwner ) { + clipModelList[i] = NULL; // missiles don't clip with their owner + } else if ( cm->owner ) { + if ( cm->owner == passEntity ) { + clipModelList[i] = NULL; // don't clip against own missiles + } else if ( cm->owner == passOwner ) { + clipModelList[i] = NULL; // don't clip against other missiles from same owner + } + } + } + + return num; +} + +/* +============ +idClip::TraceRenderModel +============ +*/ +void idClip::TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const { + trace.fraction = 1.0f; + + // if the trace is passing through the bounds + if ( touch->absBounds.Expand( radius ).LineIntersection( start, end ) ) { + modelTrace_t modelTrace; + + // test with exact render model and modify trace_t structure accordingly + if ( gameRenderWorld->ModelTrace( modelTrace, touch->renderModelHandle, start, end, radius ) ) { + trace.fraction = modelTrace.fraction; + trace.endAxis = axis; + trace.endpos = modelTrace.point; + trace.c.normal = modelTrace.normal; + trace.c.dist = modelTrace.point * modelTrace.normal; + trace.c.point = modelTrace.point; + trace.c.type = CONTACT_TRMVERTEX; + trace.c.modelFeature = 0; + trace.c.trmFeature = 0; + trace.c.contents = modelTrace.material->GetContentFlags(); + trace.c.material = modelTrace.material; + // NOTE: trace.c.id will be the joint number + touch->id = JOINT_HANDLE_TO_CLIPMODEL_ID( modelTrace.jointNumber ); + } + } +} + +/* +============ +idClip::TraceModelForClipModel +============ +*/ +const idTraceModel *idClip::TraceModelForClipModel( const idClipModel *mdl ) const { + if ( !mdl ) { + return NULL; + } else { + if ( !mdl->IsTraceModel() ) { + if ( mdl->GetEntity() ) { + gameLocal.Error( "TraceModelForClipModel: clip model %d on '%s' is not a trace model\n", mdl->GetId(), mdl->GetEntity()->name.c_str() ); + } else { + gameLocal.Error( "TraceModelForClipModel: clip model %d is not a trace model\n", mdl->GetId() ); + } + } + return idClipModel::GetCachedTraceModel( mdl->traceModelIndex ); + } +} + +/* +============ +idClip::TestHugeTranslation +============ +*/ +ID_INLINE bool TestHugeTranslation( trace_t &results, const idClipModel *mdl, const idVec3 &start, const idVec3 &end, const idMat3 &trmAxis ) { + if ( mdl != NULL && ( end - start ).LengthSqr() > Square( CM_MAX_TRACE_DIST ) ) { +// assert( 0 ); + + results.fraction = 0.0f; + results.endpos = start; + results.endAxis = trmAxis; + memset( &results.c, 0, sizeof( results.c ) ); + results.c.point = start; + results.c.entityNum = ENTITYNUM_WORLD; + + if ( mdl->GetEntity() ) { + gameLocal.Printf( "huge translation for clip model %d on entity %d '%s'\n", mdl->GetId(), mdl->GetEntity()->entityNumber, mdl->GetEntity()->GetName() ); + } else { + gameLocal.Printf( "huge translation for clip model %d\n", mdl->GetId() ); + } + return true; + } + return false; +} + +/* +============ +idClip::TranslationEntities +============ +*/ +void idClip::TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, num; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idBounds traceBounds; + float radius; + trace_t trace; + const idTraceModel *trm; + + if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { + return; + } + + trm = TraceModelForClipModel( mdl ); + + results.fraction = 1.0f; + results.endpos = end; + results.endAxis = trmAxis; + + if ( !trm ) { + traceBounds.FromPointTranslation( start, end - start ); + radius = 0.0f; + } else { + traceBounds.FromBoundsTranslation( trm->bounds, start, trmAxis, end - start ); + radius = trm->bounds.GetRadius(); + } + + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + if ( touch->renderModelHandle != -1 ) { + idClip::numRenderModelTraces++; + TraceRenderModel( trace, start, end, radius, trmAxis, touch ); + } else { + idClip::numTranslations++; + collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + } + + if ( trace.fraction < results.fraction ) { + results = trace; + results.c.entityNum = touch->entity->entityNumber; + results.c.id = touch->id; + if ( results.fraction == 0.0f ) { + break; + } + } + } +} + +/* +============ +idClip::Translation +============ +*/ +bool idClip::Translation( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, num; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idBounds traceBounds; + float radius; + trace_t trace; + const idTraceModel *trm; + + if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { + return true; + } + + trm = TraceModelForClipModel( mdl ); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // test world + idClip::numTranslations++; + collisionModelManager->Translation( &results, start, end, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + results.c.entityNum = results.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; + if ( results.fraction == 0.0f ) { + return true; // blocked immediately by the world + } + } else { + memset( &results, 0, sizeof( results ) ); + results.fraction = 1.0f; + results.endpos = end; + results.endAxis = trmAxis; + } + + if ( !trm ) { + traceBounds.FromPointTranslation( start, results.endpos - start ); + radius = 0.0f; + } else { + traceBounds.FromBoundsTranslation( trm->bounds, start, trmAxis, results.endpos - start ); + radius = trm->bounds.GetRadius(); + } + + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + if ( touch->renderModelHandle != -1 ) { + idClip::numRenderModelTraces++; + TraceRenderModel( trace, start, end, radius, trmAxis, touch ); + } else { + idClip::numTranslations++; + collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + } + + if ( trace.fraction < results.fraction ) { + results = trace; + results.c.entityNum = touch->entity->entityNumber; + results.c.id = touch->id; + if ( results.fraction == 0.0f ) { + break; + } + } + } + + return ( results.fraction < 1.0f ); +} + +/* +============ +idClip::Rotation +============ +*/ +bool idClip::Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, num; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idBounds traceBounds; + trace_t trace; + const idTraceModel *trm; + + trm = TraceModelForClipModel( mdl ); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // test world + idClip::numRotations++; + collisionModelManager->Rotation( &results, start, rotation, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + results.c.entityNum = results.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; + if ( results.fraction == 0.0f ) { + return true; // blocked immediately by the world + } + } else { + memset( &results, 0, sizeof( results ) ); + results.fraction = 1.0f; + results.endpos = start; + results.endAxis = trmAxis * rotation.ToMat3(); + } + + if ( !trm ) { + traceBounds.FromPointRotation( start, rotation ); + } else { + traceBounds.FromBoundsRotation( trm->bounds, start, trmAxis, rotation ); + } + + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + // no rotational collision with render models + if ( touch->renderModelHandle != -1 ) { + continue; + } + + idClip::numRotations++; + collisionModelManager->Rotation( &trace, start, rotation, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + + if ( trace.fraction < results.fraction ) { + results = trace; + results.c.entityNum = touch->entity->entityNumber; + results.c.id = touch->id; + if ( results.fraction == 0.0f ) { + break; + } + } + } + + return ( results.fraction < 1.0f ); +} + +/* +============ +idClip::Motion +============ +*/ +bool idClip::Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, num; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idVec3 dir, endPosition; + idBounds traceBounds; + float radius; + trace_t translationalTrace, rotationalTrace, trace; + idRotation endRotation; + const idTraceModel *trm; + + assert( rotation.GetOrigin() == start ); + + if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { + return true; + } + + if ( mdl != NULL && rotation.GetAngle() != 0.0f && rotation.GetVec() != vec3_origin ) { + // if no translation + if ( start == end ) { + // pure rotation + return Rotation( results, start, rotation, mdl, trmAxis, contentMask, passEntity ); + } + } else if ( start != end ) { + // pure translation + return Translation( results, start, end, mdl, trmAxis, contentMask, passEntity ); + } else { + // no motion + results.fraction = 1.0f; + results.endpos = start; + results.endAxis = trmAxis; + return false; + } + + trm = TraceModelForClipModel( mdl ); + + radius = trm->bounds.GetRadius(); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // translational collision with world + idClip::numTranslations++; + collisionModelManager->Translation( &translationalTrace, start, end, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + translationalTrace.c.entityNum = translationalTrace.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; + } else { + memset( &translationalTrace, 0, sizeof( translationalTrace ) ); + translationalTrace.fraction = 1.0f; + translationalTrace.endpos = end; + translationalTrace.endAxis = trmAxis; + } + + if ( translationalTrace.fraction != 0.0f ) { + + traceBounds.FromBoundsRotation( trm->bounds, start, trmAxis, rotation ); + dir = translationalTrace.endpos - start; + for ( i = 0; i < 3; i++ ) { + if ( dir[i] < 0.0f ) { + traceBounds[0][i] += dir[i]; + } + else { + traceBounds[1][i] += dir[i]; + } + } + + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + if ( touch->renderModelHandle != -1 ) { + idClip::numRenderModelTraces++; + TraceRenderModel( trace, start, end, radius, trmAxis, touch ); + } else { + idClip::numTranslations++; + collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + } + + if ( trace.fraction < translationalTrace.fraction ) { + translationalTrace = trace; + translationalTrace.c.entityNum = touch->entity->entityNumber; + translationalTrace.c.id = touch->id; + if ( translationalTrace.fraction == 0.0f ) { + break; + } + } + } + } else { + num = -1; + } + + endPosition = translationalTrace.endpos; + endRotation = rotation; + endRotation.SetOrigin( endPosition ); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // rotational collision with world + idClip::numRotations++; + collisionModelManager->Rotation( &rotationalTrace, endPosition, endRotation, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + rotationalTrace.c.entityNum = rotationalTrace.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; + } else { + memset( &rotationalTrace, 0, sizeof( rotationalTrace ) ); + rotationalTrace.fraction = 1.0f; + rotationalTrace.endpos = endPosition; + rotationalTrace.endAxis = trmAxis * rotation.ToMat3(); + } + + if ( rotationalTrace.fraction != 0.0f ) { + + if ( num == -1 ) { + traceBounds.FromBoundsRotation( trm->bounds, endPosition, trmAxis, endRotation ); + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + } + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + // no rotational collision detection with render models + if ( touch->renderModelHandle != -1 ) { + continue; + } + + idClip::numRotations++; + collisionModelManager->Rotation( &trace, endPosition, endRotation, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + + if ( trace.fraction < rotationalTrace.fraction ) { + rotationalTrace = trace; + rotationalTrace.c.entityNum = touch->entity->entityNumber; + rotationalTrace.c.id = touch->id; + if ( rotationalTrace.fraction == 0.0f ) { + break; + } + } + } + } + + if ( rotationalTrace.fraction < 1.0f ) { + results = rotationalTrace; + } else { + results = translationalTrace; + results.endAxis = rotationalTrace.endAxis; + } + + results.fraction = Max( translationalTrace.fraction, rotationalTrace.fraction ); + + return ( translationalTrace.fraction < 1.0f || rotationalTrace.fraction < 1.0f ); +} + +/* +============ +idClip::Contacts +============ +*/ +int idClip::Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, j, num, n, numContacts; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idBounds traceBounds; + const idTraceModel *trm; + + trm = TraceModelForClipModel( mdl ); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // test world + idClip::numContacts++; + numContacts = collisionModelManager->Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + } else { + numContacts = 0; + } + + for ( i = 0; i < numContacts; i++ ) { + contacts[i].entityNum = ENTITYNUM_WORLD; + contacts[i].id = 0; + } + + if ( numContacts >= maxContacts ) { + return numContacts; + } + + if ( !trm ) { + traceBounds = idBounds( start ).Expand( depth ); + } else { + traceBounds.FromTransformedBounds( trm->bounds, start, trmAxis ); + traceBounds.ExpandSelf( depth ); + } + + num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + // no contacts with render models + if ( touch->renderModelHandle != -1 ) { + continue; + } + + idClip::numContacts++; + n = collisionModelManager->Contacts( contacts + numContacts, maxContacts - numContacts, + start, dir, depth, trm, trmAxis, contentMask, + touch->Handle(), touch->origin, touch->axis ); + + for ( j = 0; j < n; j++ ) { + contacts[numContacts].entityNum = touch->entity->entityNumber; + contacts[numContacts].id = touch->id; + numContacts++; + } + + if ( numContacts >= maxContacts ) { + break; + } + } + + return numContacts; +} + +/* +============ +idClip::Contents +============ +*/ +int idClip::Contents( const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { + int i, num, contents; + idClipModel *touch, *clipModelList[MAX_GENTITIES]; + idBounds traceBounds; + const idTraceModel *trm; + + trm = TraceModelForClipModel( mdl ); + + if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { + // test world + idClip::numContents++; + contents = collisionModelManager->Contents( start, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); + } else { + contents = 0; + } + + if ( !trm ) { + traceBounds[0] = start; + traceBounds[1] = start; + } else if ( trmAxis.IsRotated() ) { + traceBounds.FromTransformedBounds( trm->bounds, start, trmAxis ); + } else { + traceBounds[0] = trm->bounds[0] + start; + traceBounds[1] = trm->bounds[1] + start; + } + + num = GetTraceClipModels( traceBounds, -1, passEntity, clipModelList ); + + for ( i = 0; i < num; i++ ) { + touch = clipModelList[i]; + + if ( !touch ) { + continue; + } + + // no contents test with render models + if ( touch->renderModelHandle != -1 ) { + continue; + } + + // if the entity does not have any contents we are looking for + if ( ( touch->contents & contentMask ) == 0 ) { + continue; + } + + // if the entity has no new contents flags + if ( ( touch->contents & contents ) == touch->contents ) { + continue; + } + + idClip::numContents++; + if ( collisionModelManager->Contents( start, trm, trmAxis, contentMask, touch->Handle(), touch->origin, touch->axis ) ) { + contents |= ( touch->contents & contentMask ); + } + } + + return contents; +} + +/* +============ +idClip::TranslationModel +============ +*/ +void idClip::TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + const idTraceModel *trm = TraceModelForClipModel( mdl ); + idClip::numTranslations++; + collisionModelManager->Translation( &results, start, end, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); +} + +/* +============ +idClip::RotationModel +============ +*/ +void idClip::RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + const idTraceModel *trm = TraceModelForClipModel( mdl ); + idClip::numRotations++; + collisionModelManager->Rotation( &results, start, rotation, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); +} + +/* +============ +idClip::ContactsModel +============ +*/ +int idClip::ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + const idTraceModel *trm = TraceModelForClipModel( mdl ); + idClip::numContacts++; + return collisionModelManager->Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); +} + +/* +============ +idClip::ContentsModel +============ +*/ +int idClip::ContentsModel( const idVec3 &start, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { + const idTraceModel *trm = TraceModelForClipModel( mdl ); + idClip::numContents++; + return collisionModelManager->Contents( start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); +} + +/* +============ +idClip::GetModelContactFeature +============ +*/ +bool idClip::GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const { + int i; + cmHandle_t handle; + idVec3 start, end; + + handle = -1; + winding.Clear(); + + if ( clipModel == NULL ) { + handle = 0; + } else { + if ( clipModel->renderModelHandle != -1 ) { + winding += contact.point; + return true; + } else if ( clipModel->traceModelIndex != -1 ) { + handle = collisionModelManager->SetupTrmModel( *idClipModel::GetCachedTraceModel( clipModel->traceModelIndex ), clipModel->material ); + } else { + handle = clipModel->collisionModelHandle; + } + } + + // if contact with a collision model + if ( handle != -1 ) { + switch( contact.type ) { + case CONTACT_EDGE: { + // the model contact feature is a collision model edge + collisionModelManager->GetModelEdge( handle, contact.modelFeature, start, end ); + winding += start; + winding += end; + break; + } + case CONTACT_MODELVERTEX: { + // the model contact feature is a collision model vertex + collisionModelManager->GetModelVertex( handle, contact.modelFeature, start ); + winding += start; + break; + } + case CONTACT_TRMVERTEX: { + // the model contact feature is a collision model polygon + collisionModelManager->GetModelPolygon( handle, contact.modelFeature, winding ); + break; + } + default: break; + } + } + + // transform the winding to world space + if ( clipModel ) { + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + winding[i].ToVec3() *= clipModel->axis; + winding[i].ToVec3() += clipModel->origin; + } + } + + return true; +} + +/* +============ +idClip::PrintStatistics +============ +*/ +void idClip::PrintStatistics( void ) { + gameLocal.Printf( "t = %-3d, r = %-3d, m = %-3d, render = %-3d, contents = %-3d, contacts = %-3d\n", + numTranslations, numRotations, numMotions, numRenderModelTraces, numContents, numContacts ); + numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; +} + +/* +============ +idClip::DrawClipModels +============ +*/ +void idClip::DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity ) { + int i, num; + idBounds bounds; + idClipModel *clipModelList[MAX_GENTITIES]; + idClipModel *clipModel; + + bounds = idBounds( eye ).Expand( radius ); + + num = idClip::ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); + + for ( i = 0; i < num; i++ ) { + clipModel = clipModelList[i]; + if ( clipModel->GetEntity() == passEntity ) { + continue; + } + if ( clipModel->renderModelHandle != -1 ) { + gameRenderWorld->DebugBounds( colorCyan, clipModel->GetAbsBounds() ); + } else { + collisionModelManager->DrawModel( clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis(), eye, radius ); + } + } +} + +/* +============ +idClip::DrawModelContactFeature +============ +*/ +bool idClip::DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const { + int i; + idMat3 axis; + idFixedWinding winding; + + if ( !GetModelContactFeature( contact, clipModel, winding ) ) { + return false; + } + + axis = contact.normal.ToMat3(); + + if ( winding.GetNumPoints() == 1 ) { + gameRenderWorld->DebugLine( colorCyan, winding[0].ToVec3(), winding[0].ToVec3() + 2.0f * axis[0], lifetime ); + gameRenderWorld->DebugLine( colorWhite, winding[0].ToVec3() - 1.0f * axis[1], winding[0].ToVec3() + 1.0f * axis[1], lifetime ); + gameRenderWorld->DebugLine( colorWhite, winding[0].ToVec3() - 1.0f * axis[2], winding[0].ToVec3() + 1.0f * axis[2], lifetime ); + } else { + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + gameRenderWorld->DebugLine( colorCyan, winding[i].ToVec3(), winding[(i+1)%winding.GetNumPoints()].ToVec3(), lifetime ); + } + } + + axis[0] = -axis[0]; + axis[2] = -axis[2]; + gameRenderWorld->DrawText( contact.material->GetName(), winding.GetCenter() - 4.0f * axis[2], 0.1f, colorWhite, axis, 1, 5000 ); + + return true; +} + +void idClipModel::TranslateOrigin( const idVec3 &translation ) +{ + if( IsTraceModel() ) + { + // Copy the tracemodel + idTraceModel trm = *(idClipModel::GetCachedTraceModel( traceModelIndex )); + trm.Translate( translation ); + + LoadModel( trm ); + } +} diff --git a/game/physics/Clip.h b/game/physics/Clip.h new file mode 100644 index 000000000..50302ecf8 --- /dev/null +++ b/game/physics/Clip.h @@ -0,0 +1,365 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CLIP_H__ +#define __CLIP_H__ + +#ifdef __linux__ +#include "cm/CollisionModel.h" +#endif + +/* +=============================================================================== + + Handles collision detection with the world and between physics objects. + +=============================================================================== +*/ + +#define CLIPMODEL_ID_TO_JOINT_HANDLE( id ) ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) ) +#define JOINT_HANDLE_TO_CLIPMODEL_ID( id ) ( -1 - id ) + +class idClip; +class idClipModel; +class idEntity; + + +//=============================================================== +// +// idClipModel +// +//=============================================================== + +class idClipModel { + + friend class idClip; + +public: + idClipModel( void ); + explicit idClipModel( const char *name ); + explicit idClipModel( const idTraceModel &trm ); + explicit idClipModel( const int renderModelHandle ); + explicit idClipModel( const idClipModel *model ); + ~idClipModel( void ); + + bool LoadModel( const char *name ); + void LoadModel( const idTraceModel &trm ); + void LoadModel( const int renderModelHandle ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Link( idClip &clp ); // must have been linked with an entity and id before + void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 ); + void Unlink( void ); // unlink from sectors + void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model + /** + * Translates the origin of the clip model relative to the clipmodel itself + * Unlinks the clip model + **/ + void TranslateOrigin( const idVec3 &translation ); + void Translate( const idVec3 &translation ); // unlinks the clip model + void Scale( const idVec3 &scale ); // unlinks the clip model + void Rotate( const idRotation &rotation ); // unlinks the clip model + void Enable( void ); // enable for clipping + void Disable( void ); // keep linked but disable for clipping + void SetMaterial( const idMaterial *m ); + const idMaterial * GetMaterial( void ) const; + void SetContents( int newContents ); // override contents + int GetContents( void ) const; + void SetEntity( idEntity *newEntity ); + idEntity * GetEntity( void ) const; + void SetId( int newId ); + int GetId( void ) const; + void SetOwner( idEntity *newOwner ); + idEntity * GetOwner( void ) const; + const idBounds & GetBounds( void ) const; + const idBounds & GetAbsBounds( void ) const; + const idVec3 & GetOrigin( void ) const; + const idMat3 & GetAxis( void ) const; + bool IsTraceModel( void ) const; // returns true if this is a trace model + bool IsRenderModel( void ) const; // returns true if this is a render model + bool IsLinked( void ) const; // returns true if the clip model is linked + bool IsEnabled( void ) const; // returns true if enabled for collision detection + bool IsEqual( const idTraceModel &trm ) const; + cmHandle_t Handle( void ) const; // returns handle used to collide vs this model + const idTraceModel * GetTraceModel( void ) const; + void GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const; + + static cmHandle_t CheckModel( const char *name ); + static void ClearTraceModelCache( void ); + static int TraceModelCacheSize( void ); + + static void SaveTraceModels( idSaveGame *savefile ); + static void RestoreTraceModels( idRestoreGame *savefile ); + +private: + bool enabled; // true if this clip model is used for clipping + idEntity * entity; // entity using this clip model + int id; // id for entities that use multiple clip models + idEntity * owner; // owner of the entity that owns this clip model + idVec3 origin; // origin of clip model + idMat3 axis; // orientation of clip model + idBounds bounds; // bounds + idBounds absBounds; // absolute bounds + const idMaterial * material; // material for trace models + int contents; // all contents ored together + cmHandle_t collisionModelHandle; // handle to collision model + int traceModelIndex; // trace model used for collision detection + int renderModelHandle; // render model def handle + + struct clipLink_s * clipLinks; // links into sectors + int touchCount; + + void Init( void ); // initialize + void Link_r( struct clipSector_s *node ); + + static int AllocTraceModel( const idTraceModel &trm ); + static void FreeTraceModel( const int traceModelIndex ); + static idTraceModel * GetCachedTraceModel( int traceModelIndex ); + static int GetTraceModelHashKey( const idTraceModel &trm ); +}; + + +ID_INLINE void idClipModel::Translate( const idVec3 &translation ) { + Unlink(); + origin += translation; +} + +ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) { + Unlink(); + origin *= rotation; + axis *= rotation.ToMat3(); +} + +ID_INLINE void idClipModel::Scale( const idVec3 &scale ) { + if( IsTraceModel() ) + { + // copy & scale the tracemodel + // Tels: Is the copy nec.? + idTraceModel trm = *(idClipModel::GetCachedTraceModel( traceModelIndex )); + trm.Scale( scale ); + + LoadModel( trm ); + } +} + +ID_INLINE void idClipModel::Enable( void ) { + enabled = true; +} + +ID_INLINE void idClipModel::Disable( void ) { + enabled = false; +} + +ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) { + material = m; +} + +ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const { + return material; +} + +ID_INLINE void idClipModel::SetContents( int newContents ) { + contents = newContents; +} + +ID_INLINE int idClipModel::GetContents( void ) const { + return contents; +} + +ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) { + entity = newEntity; +} + +ID_INLINE idEntity *idClipModel::GetEntity( void ) const { + return entity; +} + +ID_INLINE void idClipModel::SetId( int newId ) { + id = newId; +} + +ID_INLINE int idClipModel::GetId( void ) const { + return id; +} + +ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) { + owner = newOwner; +} + +ID_INLINE idEntity *idClipModel::GetOwner( void ) const { + return owner; +} + +ID_INLINE const idBounds &idClipModel::GetBounds( void ) const { + return bounds; +} + +ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const { + return absBounds; +} + +ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const { + return origin; +} + +ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const { + return axis; +} + +ID_INLINE bool idClipModel::IsRenderModel( void ) const { + return ( renderModelHandle != -1 ); +} + +ID_INLINE bool idClipModel::IsTraceModel( void ) const { + return ( traceModelIndex != -1 ); +} + +ID_INLINE bool idClipModel::IsLinked( void ) const { + return ( clipLinks != NULL ); +} + +ID_INLINE bool idClipModel::IsEnabled( void ) const { + return enabled; +} + +ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const { + return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm ); +} + +ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const { + if ( !IsTraceModel() ) { + return NULL; + } + return idClipModel::GetCachedTraceModel( traceModelIndex ); +} + + +//=============================================================== +// +// idClip +// +//=============================================================== + +class idClip { + + friend class idClipModel; + +public: + idClip( void ); + + void Init( void ); + void Shutdown( void ); + + // clip versus the rest of the world + bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + int Contents( const idVec3 &start, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + + // special case translations versus the rest of the world + bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, + int contentMask, const idEntity *passEntity ); + bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, + int contentMask, const idEntity *passEntity ); + + // clip versus a specific model + void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + int ContentsModel( const idVec3 &start, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, + cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); + + // clip versus all entities but not the world + void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end, + const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); + + // get a contact feature + bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const; + + // get entities/clip models within or touching the given bounds + int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const; + int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const; + + const idBounds & GetWorldBounds( void ) const; + idClipModel * DefaultClipModel( void ); + + // stats and debug drawing + void PrintStatistics( void ); + void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity ); + bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const; + +private: + int numClipSectors; + struct clipSector_s * clipSectors; + idBounds worldBounds; + idClipModel temporaryClipModel; + idClipModel defaultClipModel; + mutable int touchCount; + // statistics + int numTranslations; + int numRotations; + int numMotions; + int numRenderModelTraces; + int numContents; + int numContacts; + +private: + struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector ); + void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const; + const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const; + int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const; + void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const; +}; + + +ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) { + Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity ); + return ( results.fraction < 1.0f ); +} + +ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) { + temporaryClipModel.LoadModel( idTraceModel( bounds ) ); + Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity ); + return ( results.fraction < 1.0f ); +} + +ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const { + return worldBounds; +} + +ID_INLINE idClipModel *idClip::DefaultClipModel( void ) { + return &defaultClipModel; +} + +#endif /* !__CLIP_H__ */ diff --git a/game/physics/Force.cpp b/game/physics/Force.cpp new file mode 100644 index 000000000..2c1e2117f --- /dev/null +++ b/game/physics/Force.cpp @@ -0,0 +1,86 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idClass, idForce ) +END_CLASS + +idList idForce::forceList; + +/* +================ +idForce::idForce +================ +*/ +idForce::idForce( void ) { + forceList.Append( this ); +} + +/* +================ +idForce::~idForce +================ +*/ +idForce::~idForce( void ) { + forceList.Remove( this ); +} + +/* +================ +idForce::DeletePhysics +================ +*/ +void idForce::DeletePhysics( const idPhysics *phys ) { + int i; + + for ( i = 0; i < forceList.Num(); i++ ) { + forceList[i]->RemovePhysics( phys ); + } +} + +/* +================ +idForce::ClearForceList +================ +*/ +void idForce::ClearForceList( void ) { + forceList.Clear(); +} + +/* +================ +idForce::Evaluate +================ +*/ +void idForce::Evaluate( int time ) { +} + +/* +================ +idForce::RemovePhysics +================ +*/ +void idForce::RemovePhysics( const idPhysics *phys ) { +} diff --git a/game/physics/Force.h b/game/physics/Force.h new file mode 100644 index 000000000..cf9309b89 --- /dev/null +++ b/game/physics/Force.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_H__ +#define __FORCE_H__ + +/* +=============================================================================== + + Force base class + + A force object applies a force to a physics object. + +=============================================================================== +*/ + +class idEntity; +class idPhysics; + +class idForce : public idClass { + +public: + CLASS_PROTOTYPE( idForce ); + + idForce( void ); + virtual ~idForce( void ); + static void DeletePhysics( const idPhysics *phys ); + static void ClearForceList( void ); + +public: // common force interface + // evalulate the force up to the given time + virtual void Evaluate( int time ); + // removes any pointers to the physics object + virtual void RemovePhysics( const idPhysics *phys ); + +private: + + static idList forceList; +}; + +#endif /* !__FORCE_H__ */ diff --git a/game/physics/Force_Constant.cpp b/game/physics/Force_Constant.cpp new file mode 100644 index 000000000..08f250a69 --- /dev/null +++ b/game/physics/Force_Constant.cpp @@ -0,0 +1,128 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idForce, idForce_Constant ) +END_CLASS + +/* +================ +idForce_Constant::idForce_Constant +================ +*/ +idForce_Constant::idForce_Constant( void ) { + force = vec3_zero; + physics = NULL; + id = 0; + point = vec3_zero; +} + +/* +================ +idForce_Constant::~idForce_Constant +================ +*/ +idForce_Constant::~idForce_Constant( void ) { +} + +/* +================ +idForce_Constant::Save +================ +*/ +void idForce_Constant::Save( idSaveGame *savefile ) const { + savefile->WriteVec3( force ); + savefile->WriteInt( id ); + savefile->WriteVec3( point ); +} + +/* +================ +idForce_Constant::Restore +================ +*/ +void idForce_Constant::Restore( idRestoreGame *savefile ) { + // Owner needs to call SetPhysics!! + savefile->ReadVec3( force ); + savefile->ReadInt( id ); + savefile->ReadVec3( point ); +} + +/* +================ +idForce_Constant::SetPosition +================ +*/ +void idForce_Constant::SetPosition( idPhysics *physics, int id, const idVec3 &point ) { + this->physics = physics; + this->id = id; + this->point = point; +} + +/* +================ +idForce_Constant::SetForce +================ +*/ +void idForce_Constant::SetForce( const idVec3 &force ) { + this->force = force; +} + +/* +================ +idForce_Constant::SetPhysics +================ +*/ +void idForce_Constant::SetPhysics( idPhysics *physics ) { + this->physics = physics; +} + +/* +================ +idForce_Constant::Evaluate +================ +*/ +void idForce_Constant::Evaluate( int time ) { + idVec3 p; + + if ( !physics ) { + return; + } + + p = physics->GetOrigin( id ) + point * physics->GetAxis( id ); + + physics->AddForce( id, p, force ); +} + +/* +================ +idForce_Constant::RemovePhysics +================ +*/ +void idForce_Constant::RemovePhysics( const idPhysics *phys ) { + if ( physics == phys ) { + physics = NULL; + } +} diff --git a/game/physics/Force_Constant.h b/game/physics/Force_Constant.h new file mode 100644 index 000000000..30ab32feb --- /dev/null +++ b/game/physics/Force_Constant.h @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_CONSTANT_H__ +#define __FORCE_CONSTANT_H__ + +/* +=============================================================================== + + Constant force + +=============================================================================== +*/ + +class idForce_Constant : public idForce { + +public: + CLASS_PROTOTYPE( idForce_Constant ); + + idForce_Constant( void ); + virtual ~idForce_Constant( void ); + + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // constant force + void SetForce( const idVec3 &force ); + // set force position + void SetPosition( idPhysics *physics, int id, const idVec3 &point ); + + void SetPhysics( idPhysics *physics ); + +public: // common force interface + virtual void Evaluate( int time ); + virtual void RemovePhysics( const idPhysics *phys ); + +private: + // force properties + idVec3 force; + idPhysics * physics; + int id; + idVec3 point; +}; + +#endif /* !__FORCE_CONSTANT_H__ */ diff --git a/game/physics/Force_Drag.cpp b/game/physics/Force_Drag.cpp new file mode 100644 index 000000000..48f616814 --- /dev/null +++ b/game/physics/Force_Drag.cpp @@ -0,0 +1,148 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idForce, idForce_Drag ) +END_CLASS + +/* +================ +idForce_Drag::idForce_Drag +================ +*/ +idForce_Drag::idForce_Drag( void ) { + damping = 0.5f; + dragPosition = vec3_zero; + physics = NULL; + id = 0; + p = vec3_zero; + dragPosition = vec3_zero; +} + +/* +================ +idForce_Drag::~idForce_Drag +================ +*/ +idForce_Drag::~idForce_Drag( void ) { +} + +/* +================ +idForce_Drag::Init +================ +*/ +void idForce_Drag::Init( float damping ) { + if ( damping >= 0.0f && damping < 1.0f ) { + this->damping = damping; + } +} + +/* +================ +idForce_Drag::SetPhysics +================ +*/ +void idForce_Drag::SetPhysics( idPhysics *phys, int id, const idVec3 &p ) { + this->physics = phys; + this->id = id; + this->p = p; +} + +/* +================ +idForce_Drag::SetDragPosition +================ +*/ +void idForce_Drag::SetDragPosition( const idVec3 &pos ) { + this->dragPosition = pos; +} + +/* +================ +idForce_Drag::GetDragPosition +================ +*/ +const idVec3 &idForce_Drag::GetDragPosition( void ) const { + return this->dragPosition; +} + +/* +================ +idForce_Drag::GetDraggedPosition +================ +*/ +const idVec3 idForce_Drag::GetDraggedPosition( void ) const { + return ( physics->GetOrigin( id ) + p * physics->GetAxis( id ) ); +} + +/* +================ +idForce_Drag::Evaluate +================ +*/ +void idForce_Drag::Evaluate( int time ) { + float l1, l2, mass; + idVec3 dragOrigin, dir1, dir2, velocity, centerOfMass; + idMat3 inertiaTensor; + idRotation rotation; + idClipModel *clipModel; + + if ( !physics ) { + return; + } + + clipModel = physics->GetClipModel( id ); + if ( clipModel != NULL && clipModel->IsTraceModel() ) { + clipModel->GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor ); + } else { + centerOfMass.Zero(); + } + + centerOfMass = physics->GetOrigin( id ) + centerOfMass * physics->GetAxis( id ); + dragOrigin = physics->GetOrigin( id ) + p * physics->GetAxis( id ); + + dir1 = dragPosition - centerOfMass; + dir2 = dragOrigin - centerOfMass; + l1 = dir1.Normalize(); + l2 = dir2.Normalize(); + + rotation.Set( centerOfMass, dir2.Cross( dir1 ), RAD2DEG( idMath::ACos( dir1 * dir2 ) ) ); + physics->SetAngularVelocity( rotation.ToAngularVelocity() / MS2SEC( USERCMD_MSEC ), id ); + + velocity = physics->GetLinearVelocity( id ) * damping + dir1 * ( ( l1 - l2 ) * ( 1.0f - damping ) / MS2SEC( USERCMD_MSEC ) ); + physics->SetLinearVelocity( velocity, id ); +} + +/* +================ +idForce_Drag::RemovePhysics +================ +*/ +void idForce_Drag::RemovePhysics( const idPhysics *phys ) { + if ( physics == phys ) { + physics = NULL; + } +} diff --git a/game/physics/Force_Drag.h b/game/physics/Force_Drag.h new file mode 100644 index 000000000..4d64f80f7 --- /dev/null +++ b/game/physics/Force_Drag.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_DRAG_H__ +#define __FORCE_DRAG_H__ + +/* +=============================================================================== + + Drag force + +=============================================================================== +*/ + +class idForce_Drag : public idForce { + +public: + CLASS_PROTOTYPE( idForce_Drag ); + + idForce_Drag( void ); + virtual ~idForce_Drag( void ); + // initialize the drag force + void Init( float damping ); + // set physics object being dragged + void SetPhysics( idPhysics *physics, int id, const idVec3 &p ); + // set position to drag towards + void SetDragPosition( const idVec3 &pos ); + // get the position dragged towards + const idVec3 & GetDragPosition( void ) const; + // get the position on the dragged physics object + const idVec3 GetDraggedPosition( void ) const; + +public: // common force interface + virtual void Evaluate( int time ); + virtual void RemovePhysics( const idPhysics *phys ); + +private: + + // properties + float damping; + + // positioning + idPhysics * physics; // physics object + int id; // clip model id of physics object + idVec3 p; // position on clip model + idVec3 dragPosition; // drag towards this position +}; + +#endif /* !__FORCE_DRAG_H__ */ diff --git a/game/physics/Force_Field.cpp b/game/physics/Force_Field.cpp new file mode 100644 index 000000000..016096ea0 --- /dev/null +++ b/game/physics/Force_Field.cpp @@ -0,0 +1,250 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idForce, idForce_Field ) +END_CLASS + +/* +================ +idForce_Field::idForce_Field +================ +*/ +idForce_Field::idForce_Field( void ) { + type = FORCEFIELD_UNIFORM; + applyType = FORCEFIELD_APPLY_FORCE; + magnitude = 0.0f; + dir.Set( 0, 0, 1 ); + randomTorque = 0.0f; + playerOnly = false; + monsterOnly = false; + clipModel = NULL; +} + +/* +================ +idForce_Field::~idForce_Field +================ +*/ +idForce_Field::~idForce_Field( void ) { + if ( this->clipModel ) { + delete this->clipModel; + } +} + +/* +================ +idForce_Field::Save +================ +*/ +void idForce_Field::Save( idSaveGame *savefile ) const { + savefile->WriteInt( type ); + savefile->WriteInt( applyType); + savefile->WriteFloat( magnitude ); + savefile->WriteVec3( dir ); + savefile->WriteFloat( randomTorque ); + savefile->WriteBool( playerOnly ); + savefile->WriteBool( monsterOnly ); + savefile->WriteClipModel( clipModel ); +} + +/* +================ +idForce_Field::Restore +================ +*/ +void idForce_Field::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( (int &)type ); + savefile->ReadInt( (int &)applyType); + savefile->ReadFloat( magnitude ); + savefile->ReadVec3( dir ); + savefile->ReadFloat( randomTorque ); + savefile->ReadBool( playerOnly ); + savefile->ReadBool( monsterOnly ); + savefile->ReadClipModel( clipModel ); +} + +/* +================ +idForce_Field::SetClipModel +================ +*/ +void idForce_Field::SetClipModel( idClipModel *clipModel ) { + if ( this->clipModel && clipModel != this->clipModel ) { + delete this->clipModel; + } + this->clipModel = clipModel; +} + +/* +================ +idForce_Field::Uniform +================ +*/ +void idForce_Field::Uniform( const idVec3 &force ) { + dir = force; + magnitude = dir.Normalize(); + type = FORCEFIELD_UNIFORM; +} + +/* +================ +idForce_Field::Explosion +================ +*/ +void idForce_Field::Explosion( float force ) { + magnitude = force; + type = FORCEFIELD_EXPLOSION; +} + +/* +================ +idForce_Field::Implosion +================ +*/ +void idForce_Field::Implosion( float force ) { + magnitude = force; + type = FORCEFIELD_IMPLOSION; +} + +/* +================ +idForce_Field::RandomTorque +================ +*/ +void idForce_Field::RandomTorque( float force ) { + randomTorque = force; +} + +/* +================ +idForce_Field::Evaluate +================ +*/ +void idForce_Field::Evaluate( int time ) { + int numClipModels, i; + idBounds bounds; + idVec3 force, torque, angularVelocity; + idClipModel *cm, *clipModelList[ MAX_GENTITIES ]; + + assert( clipModel ); + + bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); + numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); + + for ( i = 0; i < numClipModels; i++ ) { + cm = clipModelList[ i ]; + + if ( !cm->IsTraceModel() ) { + continue; + } + + idEntity *entity = cm->GetEntity(); + + if ( !entity ) { + continue; + } + + idPhysics *physics = entity->GetPhysics(); + + if ( playerOnly ) { + if ( !physics->IsType( idPhysics_Player::Type ) ) { + continue; + } + } else if ( monsterOnly ) { + if ( !physics->IsType( idPhysics_Monster::Type ) ) { + continue; + } + } + + if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1, + clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) { + continue; + } + + switch( type ) { + case FORCEFIELD_UNIFORM: { + force = dir; + break; + } + case FORCEFIELD_EXPLOSION: { + force = cm->GetOrigin() - clipModel->GetOrigin(); + force.Normalize(); + break; + } + case FORCEFIELD_IMPLOSION: { + force = clipModel->GetOrigin() - cm->GetOrigin(); + force.Normalize(); + break; + } + default: { + gameLocal.Error( "idForce_Field: invalid type" ); + break; + } + } + + if ( randomTorque != 0.0f ) { + torque[0] = gameLocal.random.CRandomFloat(); + torque[1] = gameLocal.random.CRandomFloat(); + torque[2] = gameLocal.random.CRandomFloat(); + if ( torque.Normalize() == 0.0f ) { + torque[2] = 1.0f; + } + } + + switch( applyType ) { + case FORCEFIELD_APPLY_FORCE: { + if ( randomTorque != 0.0f ) { + entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude ); + } + else { + entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude ); + } + break; + } + case FORCEFIELD_APPLY_VELOCITY: { + physics->SetLinearVelocity( force * magnitude, cm->GetId() ); + if ( randomTorque != 0.0f ) { + angularVelocity = physics->GetAngularVelocity( cm->GetId() ); + physics->SetAngularVelocity( 0.5f * (angularVelocity + torque * randomTorque), cm->GetId() ); + } + break; + } + case FORCEFIELD_APPLY_IMPULSE: { + if ( randomTorque != 0.0f ) { + entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude ); + } + else { + entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude ); + } + break; + } + default: { + gameLocal.Error( "idForce_Field: invalid apply type" ); + break; + } + } + } +} diff --git a/game/physics/Force_Field.h b/game/physics/Force_Field.h new file mode 100644 index 000000000..f2070f9d5 --- /dev/null +++ b/game/physics/Force_Field.h @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_FIELD_H__ +#define __FORCE_FIELD_H__ + +/* +=============================================================================== + + Force field + +=============================================================================== +*/ + +enum forceFieldType { + FORCEFIELD_UNIFORM, + FORCEFIELD_EXPLOSION, + FORCEFIELD_IMPLOSION +}; + +enum forceFieldApplyType { + FORCEFIELD_APPLY_FORCE, + FORCEFIELD_APPLY_VELOCITY, + FORCEFIELD_APPLY_IMPULSE +}; + +class idForce_Field : public idForce { + +public: + CLASS_PROTOTYPE( idForce_Field ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + idForce_Field( void ); + virtual ~idForce_Field( void ); + // uniform constant force + void Uniform( const idVec3 &force ); + // explosion from clip model origin + void Explosion( float force ); + // implosion towards clip model origin + void Implosion( float force ); + // add random torque + void RandomTorque( float force ); + // should the force field apply a force, velocity or impulse + void SetApplyType( const forceFieldApplyType type ) { applyType = type; } + // make the force field only push players + void SetPlayerOnly( bool set ) { playerOnly = set; } + // make the force field only push monsters + void SetMonsterOnly( bool set ) { monsterOnly = set; } + // clip model describing the extents of the force field + void SetClipModel( idClipModel *clipModel ); + +public: // common force interface + virtual void Evaluate( int time ); + +private: + // force properties + forceFieldType type; + forceFieldApplyType applyType; + float magnitude; + idVec3 dir; + float randomTorque; + bool playerOnly; + bool monsterOnly; + idClipModel * clipModel; +}; + +#endif /* !__FORCE_FIELD_H__ */ diff --git a/game/physics/Force_Push.cpp b/game/physics/Force_Push.cpp new file mode 100644 index 000000000..8046036e9 --- /dev/null +++ b/game/physics/Force_Push.cpp @@ -0,0 +1,266 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "Force_Push.h" +#include "../Game_local.h" + +CLASS_DECLARATION( idForce, CForcePush ) +END_CLASS + +CForcePush::CForcePush() : + pushEnt(NULL), + id(0), + impactVelocity(vec3_zero), + startPushTime(-1), + owner(NULL) +{ + lastPushEnt = NULL; + memset(&contactInfo, 0, sizeof(contactInfo)); +} + +void CForcePush::SetOwner(idEntity* ownerEnt) +{ + owner = ownerEnt; +} + +void CForcePush::SetPushEntity(idEntity* pushEnt, int id) +{ + idEntity* lastPushEntity = lastPushEnt.GetEntity(); + + if (pushEnt != lastPushEntity) + { + // entity has changed, reset the timer + startPushTime = gameLocal.time; + } + + // Check if we are pushing anything + if (pushEnt == NULL) + { + // No, update the owning actor's push state + if (owner != NULL) + { + SetOwnerIsPushing(false); + } + + // Did we push anything the frame before? + if (lastPushEntity != NULL && lastPushEntity->IsType(idMoveable::Type)) + { + // Let the pushed entity know that it is not being pushed anymore + static_cast(lastPushEntity)->SetIsPushed(false, vec3_zero); + } + } + + this->pushEnt = pushEnt; + this->id = id; +} + +void CForcePush::SetContactInfo(const trace_t& contactInfo, const idVec3& impactVelocity) +{ + this->contactInfo = contactInfo; + this->impactVelocity = impactVelocity; +} + +void CForcePush::Evaluate( int time ) +{ + if (owner == NULL) return; + + if (pushEnt == NULL) + { + // nothing to do, but update the owning actor's push state + SetOwnerIsPushing(false); + return; + } + + // Do not push static entity or non-pushable ones + if (pushEnt->IsType(idStaticEntity::Type) || pushEnt->spawnArgs.GetBool("notpushable", "0")) + { + return; + } + + idPhysics* physics = pushEnt->GetPhysics(); + //gameRenderWorld->DebugBox(colorRed, idBox(physics->GetBounds(), physics->GetOrigin(), physics->GetAxis()), 16); + + if (physics == NULL) return; // fix crash for entites not having physics + + float mass = physics->GetMass(); + float ownerMass = owner->GetPhysics()->GetMass(); + + // This is the maximum mass an object can have to be kickable + float massThresholdHeavy = ownerMass * cv_pm_push_heavy_threshold.GetFloat(); + + bool isPushing = false; + + if (mass < massThresholdHeavy) + { + // Get the owner's velocity and project it on the impact normal + float normalVelocity = -contactInfo.c.normal * impactVelocity; + + // Clamp to positive values + if (normalVelocity < 0) + { + normalVelocity = 0; + } + + float maxPlayerSpeed = pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat(); + float speedFraction = idMath::ClampFloat(0, 1, normalVelocity / maxPlayerSpeed); + + // Maximum resulting velocity in m/s + const float vmax = 1.0f; + + // Calculate the resulting velocity of the kicked object, linearly scaled and clamped to [0..vmax] m/s + float resultingVelocity = vmax * (1.02f - physics->GetMass()/49); + resultingVelocity = METERS_TO_DOOM * idMath::ClampFloat(0, vmax, resultingVelocity); + + // This is the scale of our impulse, based on the maximum allowed kick velocity + float scale = physics->GetMass() * resultingVelocity * speedFraction; + + // The pushed entity is not a heavy one, kick it + //float scale = (-contactInfo.c.normal * impactVelocity) * ownerMass * cv_pm_pushmod.GetFloat(); + + // Clamp the value to the maximum impulse we're allowed to give + scale = idMath::ClampFloat(0, cv_pm_push_maximpulse.GetFloat(), scale); + + // greebo: Nullify the z-component of the impact impulse, we're always kicking horizontally + idVec3 pushDirection(impactVelocity.x, impactVelocity.y, 0); + pushDirection.NormalizeFast(); + + // Check if the moveable has already a large impulse in that direction + float currentDirectionalImpulse = (physics->GetLinearVelocity()*pushDirection) * physics->GetMass(); + + if (currentDirectionalImpulse < cv_pm_push_maximpulse.GetFloat()) + { + idVec3 pushImpulse = pushDirection * scale; + + //gameRenderWorld->DrawText( idStr(pushImpulse.LengthFast()), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec*10 ); + //gameRenderWorld->DebugArrow( colorWhite, physics->GetAbsBounds().GetCenter(), physics->GetAbsBounds().GetCenter() - contactInfo.c.normal*100, 1, gameLocal.msec*10 ); + + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking impulse = %f,%f,%f, scale was %f\r", pushImpulse.x, pushImpulse.y, pushImpulse.z, scale); + + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, velocity BEFORE is %f,%f,%f\r", pushEnt->name.c_str(), + physics->GetLinearVelocity().x, physics->GetLinearVelocity().y, physics->GetLinearVelocity().z); + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, angular velocity BEFORE is %f,%f,%f\r", pushEnt->name.c_str(), + physics->GetAngularVelocity().x, physics->GetAngularVelocity().y, physics->GetAngularVelocity().z); + + physics->PropagateImpulse(id, contactInfo.c.point, pushImpulse); + + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, velocity AFTER is %f,%f,%f\r", pushEnt->name.c_str(), + physics->GetLinearVelocity().x, physics->GetLinearVelocity().y, physics->GetLinearVelocity().z); + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, angular velocity AFTER is %f,%f,%f\r", pushEnt->name.c_str(), + physics->GetAngularVelocity().x, physics->GetAngularVelocity().y, physics->GetAngularVelocity().z); + } + } + // The pushed entity is considered heavy + else if (pushEnt == lastPushEnt.GetEntity()) + { + int pushTime = gameLocal.time - startPushTime; + //gameRenderWorld->DrawText( idStr(pushTime), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + + int pushStartDelay = cv_pm_push_start_delay.GetInteger(); + + // If we've been pushing long enough, start moving the obstacle + if (pushTime > pushStartDelay) + { + // greebo: Scale the velocity during the acceleration phase + float accelScale = idMath::ClampFloat(0, 1, (pushTime - pushStartDelay)/cv_pm_push_accel_time.GetFloat()); + + // Let the entity itself modify its pushing behaviour + float entityScale = pushEnt->spawnArgs.GetFloat("push_mod", "1"); + + // Scale the movement velocity according to the object's mass + // At maxPushMass, the velocity is zero, at the minimum push mass threshold below it's about 0.75 + float maxPushableMass = entityScale*cv_pm_push_max_mass.GetFloat(); + float massScale = idMath::ClampFloat(0.0f, 1.0f, 1.0f - (mass / maxPushableMass)); + + // Project the impactVelocity onto the contact normal + idVec3 pushVelocity = (impactVelocity * -contactInfo.c.normal) * (-contactInfo.c.normal); + + //gameRenderWorld->DebugArrow( colorRed, physics->GetAbsBounds().GetCenter(), physics->GetAbsBounds().GetCenter() + pushVelocity, 1, gameLocal.msec ); + + // Finally, apply a maximum cap, based on the player's normal walkspeed + float velocity = idMath::ClampFloat(0, pm_walkspeed.GetFloat()*0.8f, pushVelocity.NormalizeFast()); + + //gameRenderWorld->DrawText( idStr(velocity * accelScale * massScale), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + + // Apply the mass scale and the acceleration scale to the capped velocity + physics->SetLinearVelocity(pushVelocity * velocity * accelScale * massScale * entityScale); + + DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Pushing obstacle %s\r", pushEnt->name.c_str()); + + isPushing = true; + + // Update the pushed status if this entity is a moveable + if (pushEnt->IsType(idMoveable::Type)) + { + // Pass the pushDirection to the moveable + static_cast(pushEnt)->SetIsPushed(true, impactVelocity); + } + } + } + + // Update the owning actor's push state if it has changed + SetOwnerIsPushing(isPushing); + + // Remember the last push entity + lastPushEnt = pushEnt; + + // Clear the push entity again + pushEnt = NULL; +} + +void CForcePush::SetOwnerIsPushing(bool isPushing) +{ + // Update the owning actor's push state if it has changed + if (owner->IsType(idActor::Type)) + { + idActor* owningActor = static_cast(owner); + + if (owningActor->IsPushing() != isPushing) + { + owningActor->SetIsPushing(isPushing); + } + } +} + +void CForcePush::Save( idSaveGame *savefile ) const +{ + // Store the entity pointer behind the physics object + savefile->WriteObject(pushEnt); + lastPushEnt.Save(savefile); + savefile->WriteInt(id); + savefile->WriteTrace(contactInfo); + savefile->WriteVec3(impactVelocity); + savefile->WriteInt(startPushTime); + savefile->WriteObject(owner); +} + +void CForcePush::Restore( idRestoreGame *savefile ) +{ + savefile->ReadObject(reinterpret_cast(pushEnt)); + lastPushEnt.Restore(savefile); + savefile->ReadInt(id); + savefile->ReadTrace(contactInfo); + savefile->ReadVec3(impactVelocity); + savefile->ReadInt(startPushTime); + savefile->ReadObject(reinterpret_cast(owner)); +} diff --git a/game/physics/Force_Push.h b/game/physics/Force_Push.h new file mode 100644 index 000000000..4b41f8df4 --- /dev/null +++ b/game/physics/Force_Push.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __FORCE_PUSH_H__ +#define __FORCE_PUSH_H__ + +#include "Force.h" +#include + +/** + * greebo: This class should represent the push force as applied by the player + * to large game world objects. + */ +class CForcePush : + public idForce +{ +public: + CLASS_PROTOTYPE( CForcePush ); + + CForcePush(); + + void SetOwner(idEntity* ownerEnt); + + // Set physics object which is about to be pushed + void SetPushEntity(idEntity* pushEnt, int id = -1); + + // Set the push parameters for the next evaluation frame + void SetContactInfo(const trace_t& contactInfo, const idVec3& impactVelocity); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +public: // common force interface + virtual void Evaluate( int time ); + +private: + void SetOwnerIsPushing(bool isPushing); + +private: + idEntity* pushEnt; // entity being pushed + idEntityPtr lastPushEnt; // the entity we pushed last frame + + int id; // clip model id of physics object + trace_t contactInfo; // the contact info of the object we're pushing + idVec3 impactVelocity; // the velocity the owner had at impact time + int startPushTime; // the time we started to push the physics object + + idEntity* owner; // the owning entity +}; +typedef boost::shared_ptr CForcePushPtr; + +#endif /* __FORCE_PUSH_H__ */ diff --git a/game/physics/Force_Spring.cpp b/game/physics/Force_Spring.cpp new file mode 100644 index 000000000..bed96968b --- /dev/null +++ b/game/physics/Force_Spring.cpp @@ -0,0 +1,158 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idForce, idForce_Spring ) +END_CLASS + +/* +================ +idForce_Spring::idForce_Spring +================ +*/ +idForce_Spring::idForce_Spring( void ) { + Kstretch = 100.0f; + Kcompress = 100.0f; + damping = 0.0f; + restLength = 0.0f; + physics1 = NULL; + id1 = 0; + p1 = vec3_zero; + physics2 = NULL; + id2 = 0; + p2 = vec3_zero; +} + +/* +================ +idForce_Spring::~idForce_Spring +================ +*/ +idForce_Spring::~idForce_Spring( void ) { +} + +/* +================ +idForce_Spring::InitSpring +================ +*/ +void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength ) { + this->Kstretch = Kstretch; + this->Kcompress = Kcompress; + this->damping = damping; + this->restLength = restLength; +} + +/* +================ +idForce_Spring::SetPosition +================ +*/ +void idForce_Spring::SetPosition( idPhysics *physics1, int id1, const idVec3 &p1, idPhysics *physics2, int id2, const idVec3 &p2 ) { + this->physics1 = physics1; + this->id1 = id1; + this->p1 = p1; + this->physics2 = physics2; + this->id2 = id2; + this->p2 = p2; +} + +/* +================ +idForce_Spring::Evaluate +================ +*/ +void idForce_Spring::Evaluate( int time ) { + float length; + idMat3 axis; + idVec3 pos1, pos2, velocity1, velocity2, force, dampingForce; + impactInfo_t info; + + pos1 = p1; + pos2 = p2; + velocity1 = velocity2 = vec3_origin; + + if ( physics1 ) { + axis = physics1->GetAxis( id1 ); + pos1 = physics1->GetOrigin( id1 ); + pos1 += p1 * axis; + if ( damping > 0.0f ) { + physics1->GetImpactInfo( id1, pos1, &info ); + velocity1 = info.velocity; + } + } + + if ( physics2 ) { + axis = physics2->GetAxis( id2 ); + pos2 = physics2->GetOrigin( id2 ); + pos2 += p2 * axis; + if ( damping > 0.0f ) { + physics2->GetImpactInfo( id2, pos2, &info ); + velocity2 = info.velocity; + } + } + + force = pos2 - pos1; + dampingForce = ( damping * ( ((velocity2 - velocity1) * force) / (force * force) ) ) * force; + length = force.Normalize(); + + // if the spring is stretched + if ( length > restLength ) { + if ( Kstretch > 0.0f ) { + force = ( Square( length - restLength ) * Kstretch ) * force - dampingForce; + if ( physics1 ) { + physics1->AddForce( id1, pos1, force ); + } + if ( physics2 ) { + physics2->AddForce( id2, pos2, -force ); + } + } + } + else { + if ( Kcompress > 0.0f ) { + force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce; + if ( physics1 ) { + physics1->AddForce( id1, pos1, -force ); + } + if ( physics2 ) { + physics2->AddForce( id2, pos2, force ); + } + } + } +} + +/* +================ +idForce_Spring::RemovePhysics +================ +*/ +void idForce_Spring::RemovePhysics( const idPhysics *phys ) { + if ( physics1 == phys ) { + physics1 = NULL; + } + if ( physics2 == phys ) { + physics2 = NULL; + } +} diff --git a/game/physics/Force_Spring.h b/game/physics/Force_Spring.h new file mode 100644 index 000000000..65ad08015 --- /dev/null +++ b/game/physics/Force_Spring.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __FORCE_SPRING_H__ +#define __FORCE_SPRING_H__ + +/* +=============================================================================== + + Spring force + +=============================================================================== +*/ + +class idForce_Spring : public idForce { + +public: + CLASS_PROTOTYPE( idForce_Spring ); + + idForce_Spring( void ); + virtual ~idForce_Spring( void ); + // initialize the spring + void InitSpring( float Kstretch, float Kcompress, float damping, float restLength ); + // set the entities and positions on these entities the spring is attached to + void SetPosition( idPhysics *physics1, int id1, const idVec3 &p1, + idPhysics *physics2, int id2, const idVec3 &p2 ); + +public: // common force interface + virtual void Evaluate( int time ); + virtual void RemovePhysics( const idPhysics *phys ); + +private: + + // spring properties + float Kstretch; + float Kcompress; + float damping; + float restLength; + + // positioning + idPhysics * physics1; // first physics object + int id1; // clip model id of first physics object + idVec3 p1; // position on clip model + idPhysics * physics2; // second physics object + int id2; // clip model id of second physics object + idVec3 p2; // position on clip model + +}; + +#endif /* !__FORCE_SPRING_H__ */ diff --git a/game/physics/Physics.cpp b/game/physics/Physics.cpp new file mode 100644 index 000000000..54c2e6137 --- /dev/null +++ b/game/physics/Physics.cpp @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +ABSTRACT_DECLARATION( idClass, idPhysics ) +END_CLASS + + +/* +================ +idPhysics::~idPhysics +================ +*/ +idPhysics::~idPhysics( void ) { +} + +/* +================ +idPhysics::Save +================ +*/ +void idPhysics::Save( idSaveGame *savefile ) const { +} + +/* +================ +idPhysics::Restore +================ +*/ +void idPhysics::Restore( idRestoreGame *savefile ) { +} + +/* +================ +idPhysics::SetClipBox +================ +*/ +void idPhysics::SetClipBox( const idBounds &bounds, float density ) { + SetClipModel( new idClipModel( idTraceModel( bounds ) ), density ); +} + +/* +================ +idPhysics::SnapTimeToPhysicsFrame +================ +*/ +int idPhysics::SnapTimeToPhysicsFrame( int t ) { + int s; + s = t + USERCMD_MSEC - 1; + return ( s - s % USERCMD_MSEC ); +} diff --git a/game/physics/Physics.h b/game/physics/Physics.h new file mode 100644 index 000000000..d2da87dda --- /dev/null +++ b/game/physics/Physics.h @@ -0,0 +1,198 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_H__ +#define __PHYSICS_H__ + +/* +=============================================================================== + + Physics abstract class + + A physics object is a tool to manipulate the position and orientation of + an entity. The physics object is a container for idClipModels used for + collision detection. The physics deals with moving these collision models + through the world according to the laws of physics or other rules. + + The mass of a clip model is the volume of the clip model times the density. + An arbitrary mass can however be set for specific clip models or the + whole physics object. The contents of a clip model is a set of bit flags + that define the contents. The clip mask defines the contents a clip model + collides with. + + The linear velocity of a physics object is a vector that defines the + translation of the center of mass in units per second. The angular velocity + of a physics object is a vector that passes through the center of mass. The + direction of this vector defines the axis of rotation and the magnitude + defines the rate of rotation about the axis in radians per second. + The gravity is the change in velocity per second due to gravitational force. + + Entities update their visual position and orientation from the physics + using GetOrigin() and GetAxis(). Direct origin and axis changes of + entities should go through the physics. In other words the physics origin + and axis are updated first and the entity updates its visual position + from the physics. + +=============================================================================== +*/ + +#define CONTACT_EPSILON 0.25f // maximum contact seperation distance + +class idEntity; +#ifdef MOD_WATERPHYSICS + +class idPhysics_Liquid; // MOD_WATERPHYSICS + +#endif + + +typedef struct impactInfo_s { + float invMass; // inverse mass + idMat3 invInertiaTensor; // inverse inertia tensor + idVec3 position; // impact position relative to center of mass + idVec3 velocity; // velocity at the impact position +} impactInfo_t; + + +class idPhysics : public idClass { + +public: + ABSTRACT_PROTOTYPE( idPhysics ); + + virtual ~idPhysics( void ); + static int SnapTimeToPhysicsFrame( int t ); + + // Must not be virtual + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +public: // common physics interface + // set pointer to entity using physics + virtual void SetSelf( idEntity *e ) = 0; + virtual idEntity * GetSelf( void ) { return NULL; } + // clip models + virtual void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ) = 0; + virtual void SetClipBox( const idBounds &bounds, float density ); + virtual idClipModel * GetClipModel( int id = 0 ) const = 0; + virtual int GetNumClipModels( void ) const = 0; + // get/set the mass of a specific clip model or the whole physics object + virtual void SetMass( float mass, int id = -1 ) = 0; + virtual float GetMass( int id = -1 ) const = 0; + // get/set the contents of a specific clip model or the whole physics object + virtual void SetContents( int contents, int id = -1 ) = 0; + virtual int GetContents( int id = -1 ) const = 0; + // get/set the contents a specific clip model or the whole physics object collides with + virtual void SetClipMask( int mask, int id = -1 ) = 0; + virtual int GetClipMask( int id = -1 ) const = 0; + // get the bounds of a specific clip model or the whole physics object + virtual const idBounds & GetBounds( int id = -1 ) const = 0; + virtual const idBounds & GetAbsBounds( int id = -1 ) const = 0; + // evaluate the physics with the given time step, returns true if the object moved + virtual bool Evaluate( int timeStepMSec, int endTimeMSec ) = 0; + // update the time without moving + virtual void UpdateTime( int endTimeMSec ) = 0; + // get the last physics update time + virtual int GetTime( void ) const = 0; + // collision interaction between different physics objects + virtual void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const = 0; + virtual void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) = 0; + + // greebo: Applies the impulse to this entity and lets it propagate to other contacts + // (not supported by all entities, works good in rigid body physics) + // returns true if the impulse has been applied to any neighbours + virtual bool PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ) = 0; + + virtual void AddForce( const int id, const idVec3 &point, const idVec3 &force ) = 0; + virtual void Activate( void ) = 0; + virtual void PutToRest( void ) = 0; + virtual bool IsAtRest( void ) const = 0; + virtual int GetRestStartTime( void ) const = 0; + virtual bool IsPushable( void ) const = 0; + // save and restore the physics state + virtual void SaveState( void ) = 0; + virtual void RestoreState( void ) = 0; + // set the position and orientation in master space or world space if no master set + virtual void SetOrigin( const idVec3 &newOrigin, int id = -1 ) = 0; + virtual void SetAxis( const idMat3 &newAxis, int id = -1 ) = 0; + // translate or rotate the physics object in world space + virtual void Translate( const idVec3 &translation, int id = -1 ) = 0; + virtual void Rotate( const idRotation &rotation, int id = -1 ) = 0; + // get the position and orientation in world space + virtual const idVec3 & GetOrigin( int id = 0 ) const = 0; + virtual const idMat3 & GetAxis( int id = 0 ) const = 0; + // set linear and angular velocity + virtual void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ) = 0; + virtual void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ) = 0; + // get linear and angular velocity + virtual const idVec3 & GetLinearVelocity( int id = 0 ) const = 0; + virtual const idVec3 & GetAngularVelocity( int id = 0 ) const = 0; + // gravity + virtual void SetGravity( const idVec3 &newGravity ) = 0; + virtual const idVec3 & GetGravity( void ) const = 0; + virtual const idVec3 & GetGravityNormal( void ) const = 0; + // get first collision when translating or rotating this physics object + virtual void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const = 0; + virtual void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const = 0; + virtual int ClipContents( const idClipModel *model ) const = 0; + // disable/enable the clip models contained by this physics object + virtual void DisableClip( void ) = 0; + virtual void EnableClip( void ) = 0; + // link/unlink the clip models contained by this physics object + virtual void UnlinkClip( void ) = 0; + virtual void LinkClip( void ) = 0; + // contacts + virtual bool EvaluateContacts( void ) = 0; + virtual int GetNumContacts( void ) const = 0; + virtual const contactInfo_t &GetContact( int num ) const = 0; + virtual void ClearContacts( void ) = 0; + virtual void AddContactEntity( idEntity *e ) = 0; + virtual void RemoveContactEntity( idEntity *e ) = 0; + // ground contacts + virtual bool HasGroundContacts( void ) const = 0; + virtual bool IsGroundEntity( int entityNum ) const = 0; + virtual bool IsGroundClipModel( int entityNum, int id ) const = 0; + // set the master entity for objects bound to a master + virtual void SetMaster( idEntity *master, const bool orientated = true ) = 0; + // set pushed state + virtual void SetPushed( int deltaTime ) = 0; + virtual const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const = 0; + virtual const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const = 0; + // get blocking info, returns NULL if the object is not blocked + virtual const trace_t * GetBlockingInfo( void ) const = 0; + virtual idEntity * GetBlockingEntity( void ) const = 0; + // movement end times in msec for reached events at the end of predefined motion + virtual int GetLinearEndTime( void ) const = 0; + virtual int GetAngularEndTime( void ) const = 0; + // networking + virtual void WriteToSnapshot( idBitMsgDelta &msg ) const = 0; + virtual void ReadFromSnapshot( const idBitMsgDelta &msg ) = 0; + +#ifdef MOD_WATERPHYSICS + + // gets/sets the water + + virtual idPhysics_Liquid *GetWater() = 0; // MOD_WATERPHYSICS + + virtual void SetWater( idPhysics_Liquid *e, const float murkiness) = 0; // MOD_WATERPHYSICS + +#endif + +}; + +#endif /* !__PHYSICS_H__ */ diff --git a/game/physics/Physics_AF.cpp b/game/physics/Physics_AF.cpp new file mode 100644 index 000000000..fe2227720 --- /dev/null +++ b/game/physics/Physics_AF.cpp @@ -0,0 +1,8558 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../Grabber.h" + +CLASS_DECLARATION( idPhysics_Base, idPhysics_AF ) +END_CLASS + +const float ERROR_REDUCTION = 0.5f; +const float ERROR_REDUCTION_MAX = 256.0f; +const float LIMIT_ERROR_REDUCTION = 0.3f; +const float LCP_EPSILON = 1e-7f; +const float LIMIT_LCP_EPSILON = 1e-4f; +const float CONTACT_LCP_EPSILON = 1e-6f; +const float CENTER_OF_MASS_EPSILON = 1e-2f; +#ifdef MOD_WATERPHYSICS +const float NO_MOVE_TIME = 2.0f; +// ishtvan test: move impulse threshold back to D3 default or below +// const float IMPULSE_THRESHOLD = 1500.0f; +const float IMPULSE_THRESHOLD = 250.0f; +const float WATER_FRICTION = 0.0f; // we need AF friction to be a little bigger than RB water friction, we add this value +const float DEFAULT_LIQUID_SCALAR = -0.28f; +const float DEFAULT_LIQUID_DENSITY = 0.005f; +const float LIQUID_MASS_MUL = 3.0f; // I'm not sure how to explain this, without it body bob way too quickly +#else +const float NO_MOVE_TIME = 1.0f; +const float IMPULSE_THRESHOLD = 500.0f; +#endif +const float NO_MOVE_TRANSLATION_TOLERANCE = 10.0f; +const float NO_MOVE_ROTATION_TOLERANCE = 10.0f; +const float MIN_MOVE_TIME = -1.0f; +const float MAX_MOVE_TIME = -1.0f; +const float SUSPEND_LINEAR_VELOCITY = 10.0f; +const float SUSPEND_ANGULAR_VELOCITY = 15.0f; +const float SUSPEND_LINEAR_ACCELERATION = 20.0f; +const float SUSPEND_ANGULAR_ACCELERATION = 30.0f; +const idVec6 vec6_lcp_epsilon = idVec6( LCP_EPSILON, LCP_EPSILON, LCP_EPSILON, + LCP_EPSILON, LCP_EPSILON, LCP_EPSILON ); + +static const float MAX_GRABBER_EXT_VELOCITY = 120.0f; +static const float MAX_GRABBER_EXT_ANGVEL = 5.0f; + +#define AF_TIMINGS + +#ifdef AF_TIMINGS +static int lastTimerReset = 0; +static int numArticulatedFigures = 0; +static idTimer timer_total, timer_pc, timer_ac, timer_collision, timer_lcp; +#endif + + + +//=============================================================== +// +// idAFConstraint +// +//=============================================================== + +/* +================ +idAFConstraint::idAFConstraint +================ +*/ +idAFConstraint::idAFConstraint( void ) { + type = CONSTRAINT_INVALID; + name = "noname"; + body1 = NULL; + body2 = NULL; + physics = NULL; + + lo.Zero( 6 ); + lo.SubVec6(0) = -vec6_infinity; + hi.Zero( 6 ); + hi.SubVec6(0) = vec6_infinity; + e.SetSize( 6 ); + e.SubVec6(0) = vec6_lcp_epsilon; + + boxConstraint = NULL; + boxIndex[0] = -1; + boxIndex[1] = -1; + boxIndex[2] = -1; + boxIndex[3] = -1; + boxIndex[4] = -1; + boxIndex[5] = -1; + + firstIndex = 0; + + memset( &fl, 0, sizeof( fl ) ); +} + +/* +================ +idAFConstraint::~idAFConstraint +================ +*/ +idAFConstraint::~idAFConstraint( void ) { +} + +/* +================ +idAFConstraint::SetBody1 +================ +*/ +void idAFConstraint::SetBody1( idAFBody *body ) { + if ( body1 != body) { + body1 = body; + if ( physics ) { + physics->SetChanged(); + } + } +} + +/* +================ +idAFConstraint::SetBody2 +================ +*/ +void idAFConstraint::SetBody2( idAFBody *body ) { + if ( body2 != body ) { + body2 = body; + if ( physics ) { + physics->SetChanged(); + } + } +} + +/* +================ +idAFConstraint::GetMultiplier +================ +*/ +const idVecX &idAFConstraint::GetMultiplier( void ) { + return lm; +} + +/* +================ +idAFConstraint::Evaluate +================ +*/ +void idAFConstraint::Evaluate( float invTimeStep ) { + assert( 0 ); +} + +/* +================ +idAFConstraint::ApplyFriction +================ +*/ +void idAFConstraint::ApplyFriction( float invTimeStep ) { +} + +/* +================ +idAFConstraint::GetForce +================ +*/ +void idAFConstraint::GetForce( idAFBody *body, idVec6 &force ) { + idVecX v; + + v.SetData( 6, VECX_ALLOCA( 6 ) ); + if ( body == body1 ) { + J1.TransposeMultiply( v, lm ); + } + else if ( body == body2 ) { + J2.TransposeMultiply( v, lm ); + } + else { + v.Zero(); + } + force[0] = v[0]; force[1] = v[1]; force[2] = v[2]; force[3] = v[3]; force[4] = v[4]; force[5] = v[5]; +} + +/* +================ +idAFConstraint::Translate +================ +*/ +void idAFConstraint::Translate( const idVec3 &translation ) { + assert( 0 ); +} + +/* +================ +idAFConstraint::Rotate +================ +*/ +void idAFConstraint::Rotate( const idRotation &rotation ) { + assert( 0 ); +} + +/* +================ +idAFConstraint::GetCenter +================ +*/ +void idAFConstraint::GetCenter( idVec3 ¢er ) { + center.Zero(); +} + +/* +================ +idAFConstraint::DebugDraw +================ +*/ +void idAFConstraint::DebugDraw( void ) { +} + +/* +================ +idAFConstraint::InitSize +================ +*/ +void idAFConstraint::InitSize( int size ) { + J1.Zero( size, 6 ); + J2.Zero( size, 6 ); + c1.Zero( size ); + c2.Zero( size ); + s.Zero( size ); + lm.Zero( size ); +} + +/* +================ +idAFConstraint::Save +================ +*/ +void idAFConstraint::Save( idSaveGame *saveFile ) const { + saveFile->WriteInt( type ); +} + +/* +================ +idAFConstraint::Restore +================ +*/ +void idAFConstraint::Restore( idRestoreGame *saveFile ) { + constraintType_t t; + saveFile->ReadInt( (int &)t ); + assert( t == type ); +} + + +//=============================================================== +// +// idAFConstraint_Fixed +// +//=============================================================== + +/* +================ +idAFConstraint_Fixed::idAFConstraint_Fixed +================ +*/ +idAFConstraint_Fixed::idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_FIXED; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 6 ); + fl.allowPrimary = true; + fl.noCollision = true; + + InitOffset(); +} + +/* +================ +idAFConstraint_Fixed::InitOffset +================ +*/ +void idAFConstraint_Fixed::InitOffset( void ) { + if ( body2 ) { + offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose(); + } + else { + offset = body1->GetWorldOrigin(); + relAxis = body1->GetWorldAxis(); + } +} + +/* +================ +idAFConstraint_Fixed::SetBody1 +================ +*/ +void idAFConstraint_Fixed::SetBody1( idAFBody *body ) { + if ( body1 != body) { + body1 = body; + InitOffset(); + if ( physics ) { + physics->SetChanged(); + } + } +} + +/* +================ +idAFConstraint_Fixed::SetBody2 +================ +*/ +void idAFConstraint_Fixed::SetBody2( idAFBody *body ) { + if ( body2 != body ) { + body2 = body; + InitOffset(); + if ( physics ) { + physics->SetChanged(); + } + } +} + +/* +================ +idAFConstraint_Fixed::Evaluate +================ +*/ +void idAFConstraint_Fixed::Evaluate( float invTimeStep ) { + idVec3 ofs, a2; + idMat3 ax; + idRotation r; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + a2 = offset * master->GetWorldAxis(); + ofs = a2 + master->GetWorldOrigin(); + ax = relAxis * master->GetWorldAxis(); + } + else { + a2.Zero(); + ofs = offset; + ax = relAxis; + } + + J1.Set( mat3_identity, mat3_zero, + mat3_zero, mat3_identity ); + + if ( body2 ) { + J2.Set( -mat3_identity, SkewSymmetric( a2 ), + mat3_zero, -mat3_identity ); + } + else { + J2.Zero( 6, 6 ); + } + + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( ofs - body1->GetWorldOrigin() ); + r = ( body1->GetWorldAxis().Transpose() * ax ).ToRotation(); + c1.SubVec3(1) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * -(float) DEG2RAD( r.GetAngle() ) ); + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); +} + +/* +================ +idAFConstraint_Fixed::ApplyFriction +================ +*/ +void idAFConstraint_Fixed::ApplyFriction( float invTimeStep ) { + // no friction +} + +/* +================ +idAFConstraint_Fixed::Translate +================ +*/ +void idAFConstraint_Fixed::Translate( const idVec3 &translation ) { + if ( !body2 ) { + offset += translation; + } +} + +/* +================ +idAFConstraint_Fixed::Rotate +================ +*/ +void idAFConstraint_Fixed::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + offset *= rotation; + relAxis *= rotation.ToMat3(); + } +} + +/* +================ +idAFConstraint_Fixed::GetCenter +================ +*/ +void idAFConstraint_Fixed::GetCenter( idVec3 ¢er ) { + center = body1->GetWorldOrigin(); +} + +/* +================ +idAFConstraint_Fixed::DebugDraw +================ +*/ +void idAFConstraint_Fixed::DebugDraw( void ) { + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + if ( master ) { + gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), master->GetWorldOrigin() ); + } + else { + gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), vec3_origin ); + } +} + +/* +================ +idAFConstraint_Fixed::Save +================ +*/ +void idAFConstraint_Fixed::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( offset ); + saveFile->WriteMat3( relAxis ); +} + +/* +================ +idAFConstraint_Fixed::Restore +================ +*/ +void idAFConstraint_Fixed::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( offset ); + saveFile->ReadMat3( relAxis ); +} + + +//=============================================================== +// +// idAFConstraint_BallAndSocketJoint +// +//=============================================================== + +/* +================ +idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint +================ +*/ +idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_BALLANDSOCKETJOINT; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 3 ); + coneLimit = NULL; + pyramidLimit = NULL; + friction = 0.0f; + fc = NULL; + fl.allowPrimary = true; + fl.noCollision = true; +} + +/* +================ +idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint +================ +*/ +idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint( void ) { + if ( coneLimit ) { + delete coneLimit; + } + if ( pyramidLimit ) { + delete pyramidLimit; + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::SetAnchor +================ +*/ +void idAFConstraint_BallAndSocketJoint::SetAnchor( const idVec3 &worldPosition ) { + + // get anchor relative to center of mass of body1 + anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get anchor relative to center of mass of body2 + anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + } + else { + anchor2 = worldPosition; + } + + if ( coneLimit ) { + coneLimit->SetAnchor( anchor2 ); + } + if ( pyramidLimit ) { + pyramidLimit->SetAnchor( anchor2 ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::GetAnchor +================ +*/ +idVec3 idAFConstraint_BallAndSocketJoint::GetAnchor( void ) const { + if ( body2 ) { + return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; + } + return anchor2; +} + +/* +================ +idAFConstraint_BallAndSocketJoint::SetNoLimit +================ +*/ +void idAFConstraint_BallAndSocketJoint::SetNoLimit( void ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } + if ( pyramidLimit ) { + delete pyramidLimit; + pyramidLimit = NULL; + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::SetConeLimit +================ +*/ +void idAFConstraint_BallAndSocketJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) { + if ( pyramidLimit ) { + delete pyramidLimit; + pyramidLimit = NULL; + } + if ( !coneLimit ) { + coneLimit = new idAFConstraint_ConeLimit; + coneLimit->SetPhysics( physics ); + } + if ( body2 ) { + coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, body1Axis * body1->GetWorldAxis().Transpose() ); + } + else { + coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, body1Axis * body1->GetWorldAxis().Transpose() ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::SetPyramidLimit +================ +*/ +void idAFConstraint_BallAndSocketJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float angle1, const float angle2, const idVec3 &body1Axis ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } + if ( !pyramidLimit ) { + pyramidLimit = new idAFConstraint_PyramidLimit; + pyramidLimit->SetPhysics( physics ); + } + if ( body2 ) { + pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(), + baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2, + body1Axis * body1->GetWorldAxis().Transpose() ); + } + else { + pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2, + body1Axis * body1->GetWorldAxis().Transpose() ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::SetLimitEpsilon +================ +*/ +void idAFConstraint_BallAndSocketJoint::SetLimitEpsilon( const float e ) { + if ( coneLimit ) { + coneLimit->SetEpsilon( e ); + } + if ( pyramidLimit ) { + pyramidLimit->SetEpsilon( e ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::GetFriction +================ +*/ +float idAFConstraint_BallAndSocketJoint::GetFriction( void ) const { + if ( af_forceFriction.GetFloat() > 0.0f ) { + return af_forceFriction.GetFloat(); + } + return friction * physics->GetJointFrictionScale(); +} + +/* +================ +idAFConstraint_BallAndSocketJoint::Evaluate +================ +*/ +void idAFConstraint_BallAndSocketJoint::Evaluate( float invTimeStep ) { + idVec3 a1, a2; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = anchor1 * body1->GetWorldAxis(); + + if ( master ) { + a2 = anchor2 * master->GetWorldAxis(); + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); + } + else { + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( anchor2 - ( a1 + body1->GetWorldOrigin() ) ); + } + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); + + J1.Set( mat3_identity, -SkewSymmetric( a1 ) ); + + if ( body2 ) { + J2.Set( -mat3_identity, SkewSymmetric( a2 ) ); + } + else { + J2.Zero( 3, 6 ); + } + + if ( coneLimit ) { + coneLimit->Add( physics, invTimeStep ); + } + else if ( pyramidLimit ) { + pyramidLimit->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::ApplyFriction +================ +*/ +void idAFConstraint_BallAndSocketJoint::ApplyFriction( float invTimeStep ) { + idVec3 angular; + float invMass, currentFriction; + + currentFriction = GetFriction(); + + if ( currentFriction <= 0.0f ) { + return; + } + + if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { + + angular = body1->GetAngularVelocity(); + invMass = body1->GetInverseMass(); + if ( body2 ) { + angular -= body2->GetAngularVelocity(); + invMass += body2->GetInverseMass(); + } + + angular *= currentFriction / invMass; + + body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); + if ( body2 ) { + body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); + } + } + else { + if ( !fc ) { + fc = new idAFConstraint_BallAndSocketJointFriction; + fc->Setup( this ); + } + + fc->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::GetForce +================ +*/ +void idAFConstraint_BallAndSocketJoint::GetForce( idAFBody *body, idVec6 &force ) { + idAFConstraint::GetForce( body, force ); + // FIXME: add limit force +} + +/* +================ +idAFConstraint_BallAndSocketJoint::Translate +================ +*/ +void idAFConstraint_BallAndSocketJoint::Translate( const idVec3 &translation ) { + if ( !body2 ) { + anchor2 += translation; + } + if ( coneLimit ) { + coneLimit->Translate( translation ); + } + else if ( pyramidLimit ) { + pyramidLimit->Translate( translation ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::Rotate +================ +*/ +void idAFConstraint_BallAndSocketJoint::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + anchor2 *= rotation; + } + if ( coneLimit ) { + coneLimit->Rotate( rotation ); + } + else if ( pyramidLimit ) { + pyramidLimit->Rotate( rotation ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::GetCenter +================ +*/ +void idAFConstraint_BallAndSocketJoint::GetCenter( idVec3 ¢er ) { + center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); +} + +/* +================ +idAFConstraint_BallAndSocketJoint::DebugDraw +================ +*/ +void idAFConstraint_BallAndSocketJoint::DebugDraw( void ) { + idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 5, 0, 0 ), a1 + idVec3( 5, 0, 0 ) ); + gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 5, 0 ), a1 + idVec3( 0, 5, 0 ) ); + gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 0, 5 ), a1 + idVec3( 0, 0, 5 ) ); + + if ( af_showLimits.GetBool() ) { + if ( coneLimit ) { + coneLimit->DebugDraw(); + } + if ( pyramidLimit ) { + pyramidLimit->DebugDraw(); + } + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::Save +================ +*/ +void idAFConstraint_BallAndSocketJoint::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( anchor1 ); + saveFile->WriteVec3( anchor2 ); + saveFile->WriteFloat( friction ); + if ( coneLimit ) { + coneLimit->Save( saveFile ); + } + if ( pyramidLimit ) { + pyramidLimit->Save( saveFile ); + } +} + +/* +================ +idAFConstraint_BallAndSocketJoint::Restore +================ +*/ +void idAFConstraint_BallAndSocketJoint::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( anchor1 ); + saveFile->ReadVec3( anchor2 ); + saveFile->ReadFloat( friction ); + if ( coneLimit ) { + coneLimit->Restore( saveFile ); + } + if ( pyramidLimit ) { + pyramidLimit->Restore( saveFile ); + } +} + + +//=============================================================== +// +// idAFConstraint_BallAndSocketJointFriction +// +//=============================================================== + +/* +================ +idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction +================ +*/ +idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction( void ) { + type = CONSTRAINT_FRICTION; + name = "ballAndSocketJointFriction"; + InitSize( 3 ); + joint = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::Setup +================ +*/ +void idAFConstraint_BallAndSocketJointFriction::Setup( idAFConstraint_BallAndSocketJoint *bsj ) { + this->joint = bsj; + body1 = bsj->GetBody1(); + body2 = bsj->GetBody2(); +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::Evaluate +================ +*/ +void idAFConstraint_BallAndSocketJointFriction::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::ApplyFriction +================ +*/ +void idAFConstraint_BallAndSocketJointFriction::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::Add +================ +*/ +bool idAFConstraint_BallAndSocketJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) { + float f; + + physics = phys; + + f = joint->GetFriction() * joint->GetMultiplier().Length(); + if ( f == 0.0f ) { + return false; + } + + lo[0] = lo[1] = lo[2] = -f; + hi[0] = hi[1] = hi[2] = f; + + J1.Zero( 3, 6 ); + J1[0][3] = J1[1][4] = J1[2][5] = 1.0f; + + if ( body2 ) { + + J2.Zero( 3, 6 ); + J2[0][3] = J2[1][4] = J2[2][5] = 1.0f; + } + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::Translate +================ +*/ +void idAFConstraint_BallAndSocketJointFriction::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_BallAndSocketJointFriction::Rotate +================ +*/ +void idAFConstraint_BallAndSocketJointFriction::Rotate( const idRotation &rotation ) { +} + + +//=============================================================== +// +// idAFConstraint_UniversalJoint +// +//=============================================================== + +/* +================ +idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint +================ +*/ +idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_UNIVERSALJOINT; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 4 ); + coneLimit = NULL; + pyramidLimit = NULL; + friction = 0.0f; + fc = NULL; + fl.allowPrimary = true; + fl.noCollision = true; +} + +/* +================ +idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint +================ +*/ +idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint( void ) { + if ( coneLimit ) { + delete coneLimit; + } + if ( pyramidLimit ) { + delete pyramidLimit; + } + if ( fc ) { + delete fc; + } +} + +/* +================ +idAFConstraint_UniversalJoint::SetAnchor +================ +*/ +void idAFConstraint_UniversalJoint::SetAnchor( const idVec3 &worldPosition ) { + + // get anchor relative to center of mass of body1 + anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get anchor relative to center of mass of body2 + anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + } + else { + anchor2 = worldPosition; + } + + if ( coneLimit ) { + coneLimit->SetAnchor( anchor2 ); + } + if ( pyramidLimit ) { + pyramidLimit->SetAnchor( anchor2 ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::GetAnchor +================ +*/ +idVec3 idAFConstraint_UniversalJoint::GetAnchor( void ) const { + if ( body2 ) { + return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; + } + return anchor2; +} + +/* +================ +idAFConstraint_UniversalJoint::SetShafts +================ +*/ +void idAFConstraint_UniversalJoint::SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 ) { + idVec3 cardanAxis; + float l; + + shaft1 = cardanShaft1; + l = shaft1.Normalize(); + assert( l != 0.0f ); + shaft2 = cardanShaft2; + l = shaft2.Normalize(); + assert( l != 0.0f ); + + // the cardan axis is a vector orthogonal to both cardan shafts + cardanAxis = shaft1.Cross( shaft2 ); + if ( cardanAxis.Normalize() == 0.0f ) { + idVec3 vecY; + shaft1.OrthogonalBasis( cardanAxis, vecY ); + cardanAxis.Normalize(); + } + + shaft1 *= body1->GetWorldAxis().Transpose(); + axis1 = cardanAxis * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + shaft2 *= body2->GetWorldAxis().Transpose(); + axis2 = cardanAxis * body2->GetWorldAxis().Transpose(); + } + else { + axis2 = cardanAxis; + } + + if ( coneLimit ) { + coneLimit->SetBody1Axis( shaft1 ); + } + if ( pyramidLimit ) { + pyramidLimit->SetBody1Axis( shaft1 ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::SetNoLimit +================ +*/ +void idAFConstraint_UniversalJoint::SetNoLimit( void ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } + if ( pyramidLimit ) { + delete pyramidLimit; + pyramidLimit = NULL; + } +} + +/* +================ +idAFConstraint_UniversalJoint::SetConeLimit +================ +*/ +void idAFConstraint_UniversalJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle ) { + if ( pyramidLimit ) { + delete pyramidLimit; + pyramidLimit = NULL; + } + if ( !coneLimit ) { + coneLimit = new idAFConstraint_ConeLimit; + coneLimit->SetPhysics( physics ); + } + if ( body2 ) { + coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, shaft1 ); + } + else { + coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, shaft1 ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::SetPyramidLimit +================ +*/ +void idAFConstraint_UniversalJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float angle1, const float angle2 ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } + if ( !pyramidLimit ) { + pyramidLimit = new idAFConstraint_PyramidLimit; + pyramidLimit->SetPhysics( physics ); + } + if ( body2 ) { + pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(), + baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2, shaft1 ); + } + else { + pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2, shaft1 ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::SetLimitEpsilon +================ +*/ +void idAFConstraint_UniversalJoint::SetLimitEpsilon( const float e ) { + if ( coneLimit ) { + coneLimit->SetEpsilon( e ); + } + if ( pyramidLimit ) { + pyramidLimit->SetEpsilon( e ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::GetFriction +================ +*/ +float idAFConstraint_UniversalJoint::GetFriction( void ) const { + if ( af_forceFriction.GetFloat() > 0.0f ) { + return af_forceFriction.GetFloat(); + } + return friction * physics->GetJointFrictionScale(); +} + +/* +================ +idAFConstraint_UniversalJoint::Evaluate + + NOTE: this joint is homokinetic +================ +*/ +void idAFConstraint_UniversalJoint::Evaluate( float invTimeStep ) { + idVec3 a1, a2, s1, s2, d1, d2, v; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = anchor1 * body1->GetWorldAxis(); + s1 = shaft1 * body1->GetWorldAxis(); + d1 = s1.Cross( axis1 * body1->GetWorldAxis() ); + + if ( master ) { + a2 = anchor2 * master->GetWorldAxis(); + s2 = shaft2 * master->GetWorldAxis(); + d2 = axis2 * master->GetWorldAxis(); + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); + } + else { + a2 = anchor2; + s2 = shaft2; + d2 = axis2; + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) ); + } + + J1.Set( mat3_identity, -SkewSymmetric( a1 ), + mat3_zero, idMat3( s1[0], s1[1], s1[2], + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f ) ); + J1.SetSize( 4, 6 ); + + if ( body2 ) { + J2.Set( -mat3_identity, SkewSymmetric( a2 ), + mat3_zero, idMat3( s2[0], s2[1], s2[2], + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f ) ); + J2.SetSize( 4, 6 ); + } + else { + J2.Zero( 4, 6 ); + } + + v = s1.Cross( s2 ); + if ( v.Normalize() != 0.0f ) { + idMat3 m1, m2; + + m1[0] = s1; + m1[1] = v; + m1[2] = v.Cross( m1[0] ); + + m2[0] = -s2; + m2[1] = v; + m2[2] = v.Cross( m2[0] ); + + d2 *= m2.Transpose() * m1; + } + + c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( d1 * d2 ); + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); + + if ( coneLimit ) { + coneLimit->Add( physics, invTimeStep ); + } + else if ( pyramidLimit ) { + pyramidLimit->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::ApplyFriction +================ +*/ +void idAFConstraint_UniversalJoint::ApplyFriction( float invTimeStep ) { + idVec3 angular; + float invMass, currentFriction; + + currentFriction = GetFriction(); + + if ( currentFriction <= 0.0f ) { + return; + } + + if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { + + angular = body1->GetAngularVelocity(); + invMass = body1->GetInverseMass(); + if ( body2 ) { + angular -= body2->GetAngularVelocity(); + invMass += body2->GetInverseMass(); + } + + angular *= currentFriction / invMass; + + body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); + if ( body2 ) { + body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); + } + } + else { + if ( !fc ) { + fc = new idAFConstraint_UniversalJointFriction; + fc->Setup( this ); + } + + fc->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::GetForce +================ +*/ +void idAFConstraint_UniversalJoint::GetForce( idAFBody *body, idVec6 &force ) { + idAFConstraint::GetForce( body, force ); + // FIXME: add limit force +} + +/* +================ +idAFConstraint_UniversalJoint::Translate +================ +*/ +void idAFConstraint_UniversalJoint::Translate( const idVec3 &translation ) { + if ( !body2 ) { + anchor2 += translation; + } + if ( coneLimit ) { + coneLimit->Translate( translation ); + } + else if ( pyramidLimit ) { + pyramidLimit->Translate( translation ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::Rotate +================ +*/ +void idAFConstraint_UniversalJoint::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + anchor2 *= rotation; + shaft2 *= rotation.ToMat3(); + axis2 *= rotation.ToMat3(); + } + if ( coneLimit ) { + coneLimit->Rotate( rotation ); + } + else if ( pyramidLimit ) { + pyramidLimit->Rotate( rotation ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::GetCenter +================ +*/ +void idAFConstraint_UniversalJoint::GetCenter( idVec3 ¢er ) { + center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); +} + +/* +================ +idAFConstraint_UniversalJoint::DebugDraw +================ +*/ +void idAFConstraint_UniversalJoint::DebugDraw( void ) { + idVec3 a1, a2, s1, s2, d1, d2, v; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + s1 = shaft1 * body1->GetWorldAxis(); + d1 = axis1 * body1->GetWorldAxis(); + + if ( master ) { + a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); + s2 = shaft2 * master->GetWorldAxis(); + d2 = axis2 * master->GetWorldAxis(); + } + else { + a2 = anchor2; + s2 = shaft2; + d2 = axis2; + } + + v = s1.Cross( s2 ); + if ( v.Normalize() != 0.0f ) { + idMat3 m1, m2; + + m1[0] = s1; + m1[1] = v; + m1[2] = v.Cross( m1[0] ); + + m2[0] = -s2; + m2[1] = v; + m2[2] = v.Cross( m2[0] ); + + d2 *= m2.Transpose() * m1; + } + + gameRenderWorld->DebugArrow( colorCyan, a1, a1 + s1 * 5.0f, 1 ); + gameRenderWorld->DebugArrow( colorBlue, a2, a2 + s2 * 5.0f, 1 ); + gameRenderWorld->DebugLine( colorGreen, a1, a1 + d1 * 5.0f ); + gameRenderWorld->DebugLine( colorGreen, a2, a2 + d2 * 5.0f ); + + if ( af_showLimits.GetBool() ) { + if ( coneLimit ) { + coneLimit->DebugDraw(); + } + if ( pyramidLimit ) { + pyramidLimit->DebugDraw(); + } + } +} + +/* +================ +idAFConstraint_UniversalJoint::Save +================ +*/ +void idAFConstraint_UniversalJoint::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( anchor1 ); + saveFile->WriteVec3( anchor2 ); + saveFile->WriteVec3( shaft1 ); + saveFile->WriteVec3( shaft2 ); + saveFile->WriteVec3( axis1 ); + saveFile->WriteVec3( axis2 ); + saveFile->WriteFloat( friction ); + if ( coneLimit ) { + coneLimit->Save( saveFile ); + } + if ( pyramidLimit ) { + pyramidLimit->Save( saveFile ); + } +} + +/* +================ +idAFConstraint_UniversalJoint::Restore +================ +*/ +void idAFConstraint_UniversalJoint::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( anchor1 ); + saveFile->ReadVec3( anchor2 ); + saveFile->ReadVec3( shaft1 ); + saveFile->ReadVec3( shaft2 ); + saveFile->ReadVec3( axis1 ); + saveFile->ReadVec3( axis2 ); + saveFile->ReadFloat( friction ); + if ( coneLimit ) { + coneLimit->Restore( saveFile ); + } + if ( pyramidLimit ) { + pyramidLimit->Restore( saveFile ); + } +} + + +//=============================================================== +// +// idAFConstraint_UniversalJointFriction +// +//=============================================================== + +/* +================ +idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction +================ +*/ +idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction( void ) { + type = CONSTRAINT_FRICTION; + name = "universalJointFriction"; + InitSize( 2 ); + joint = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_UniversalJointFriction::Setup +================ +*/ +void idAFConstraint_UniversalJointFriction::Setup( idAFConstraint_UniversalJoint *uj ) { + this->joint = uj; + body1 = uj->GetBody1(); + body2 = uj->GetBody2(); +} + +/* +================ +idAFConstraint_UniversalJointFriction::Evaluate +================ +*/ +void idAFConstraint_UniversalJointFriction::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_UniversalJointFriction::ApplyFriction +================ +*/ +void idAFConstraint_UniversalJointFriction::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_UniversalJointFriction::Add +================ +*/ +bool idAFConstraint_UniversalJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) { + idVec3 s1, s2, dir1, dir2; + float f; + + physics = phys; + + f = joint->GetFriction() * joint->GetMultiplier().Length(); + if ( f == 0.0f ) { + return false; + } + + lo[0] = lo[1] = -f; + hi[0] = hi[1] = f; + + joint->GetShafts( s1, s2 ); + + s1 *= body1->GetWorldAxis(); + s1.NormalVectors( dir1, dir2 ); + + J1.SetSize( 2, 6 ); + J1.SubVec6(0).SubVec3(0).Zero(); + J1.SubVec6(0).SubVec3(1) = dir1; + J1.SubVec6(1).SubVec3(0).Zero(); + J1.SubVec6(1).SubVec3(1) = dir2; + + if ( body2 ) { + + J2.SetSize( 2, 6 ); + J2.SubVec6(0).SubVec3(0).Zero(); + J2.SubVec6(0).SubVec3(1) = -dir1; + J2.SubVec6(1).SubVec3(0).Zero(); + J2.SubVec6(1).SubVec3(1) = -dir2; + } + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_UniversalJointFriction::Translate +================ +*/ +void idAFConstraint_UniversalJointFriction::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_UniversalJointFriction::Rotate +================ +*/ +void idAFConstraint_UniversalJointFriction::Rotate( const idRotation &rotation ) { +} + + +//=============================================================== +// +// idAFConstraint_CylindricalJoint +// +//=============================================================== + +/* +================ +idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint +================ +*/ +idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_CylindricalJoint::Evaluate +================ +*/ +void idAFConstraint_CylindricalJoint::Evaluate( float invTimeStep ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_CylindricalJoint::ApplyFriction +================ +*/ +void idAFConstraint_CylindricalJoint::ApplyFriction( float invTimeStep ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_CylindricalJoint::Translate +================ +*/ +void idAFConstraint_CylindricalJoint::Translate( const idVec3 &translation ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_CylindricalJoint::Rotate +================ +*/ +void idAFConstraint_CylindricalJoint::Rotate( const idRotation &rotation ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_CylindricalJoint::DebugDraw +================ +*/ +void idAFConstraint_CylindricalJoint::DebugDraw( void ) { + assert( 0 ); // FIXME: implement +} + + +//=============================================================== +// +// idAFConstraint_Hinge +// +//=============================================================== + +/* +================ +idAFConstraint_Hinge::idAFConstraint_Hinge +================ +*/ +idAFConstraint_Hinge::idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_HINGE; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 5 ); + coneLimit = NULL; + steering = NULL; + friction = 0.0f; + fc = NULL; + fl.allowPrimary = true; + fl.noCollision = true; + initialAxis = body1->GetWorldAxis(); + if ( body2 ) { + initialAxis *= body2->GetWorldAxis().Transpose(); + } +} + +/* +================ +idAFConstraint_Hinge::~idAFConstraint_Hinge +================ +*/ +idAFConstraint_Hinge::~idAFConstraint_Hinge( void ) { + if ( coneLimit ) { + delete coneLimit; + } + if ( fc ) { + delete fc; + } + if ( steering ) { + delete steering; + } +} + +/* +================ +idAFConstraint_Hinge::SetAnchor +================ +*/ +void idAFConstraint_Hinge::SetAnchor( const idVec3 &worldPosition ) { + // get anchor relative to center of mass of body1 + anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get anchor relative to center of mass of body2 + anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + } + else { + anchor2 = worldPosition; + } + + if ( coneLimit ) { + coneLimit->SetAnchor( anchor2 ); + } +} + +/* +================ +idAFConstraint_Hinge::GetAnchor +================ +*/ +idVec3 idAFConstraint_Hinge::GetAnchor( void ) const { + if ( body2 ) { + return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; + } + return anchor2; +} + +/* +================ +idAFConstraint_Hinge::SetAxis +================ +*/ +void idAFConstraint_Hinge::SetAxis( const idVec3 &axis ) { + idVec3 normAxis; + + normAxis = axis; + normAxis.Normalize(); + + // get axis relative to body1 + axis1 = normAxis * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get axis relative to body2 + axis2 = normAxis * body2->GetWorldAxis().Transpose(); + } + else { + axis2 = normAxis; + } +} + +/* +================ +idAFConstraint_Hinge::GetAxis +================ +*/ +idVec3 idAFConstraint_Hinge::GetAxis( void ) const { + if ( body2 ) { + return axis2 * body2->GetWorldAxis(); + } + return axis2; +} + +/* +================ +idAFConstraint_Hinge::SetNoLimit +================ +*/ +void idAFConstraint_Hinge::SetNoLimit( void ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } +} + +/* +================ +idAFConstraint_Hinge::SetLimit +================ +*/ +void idAFConstraint_Hinge::SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis ) { + if ( !coneLimit ) { + coneLimit = new idAFConstraint_ConeLimit; + coneLimit->SetPhysics( physics ); + } + if ( body2 ) { + coneLimit->Setup( body1, body2, anchor2, axis * body2->GetWorldAxis().Transpose(), angle, body1Axis * body1->GetWorldAxis().Transpose() ); + } + else { + coneLimit->Setup( body1, body2, anchor2, axis, angle, body1Axis * body1->GetWorldAxis().Transpose() ); + } +} + +/* +================ +idAFConstraint_Hinge::SetLimitEpsilon +================ +*/ +void idAFConstraint_Hinge::SetLimitEpsilon( const float e ) { + if ( coneLimit ) { + coneLimit->SetEpsilon( e ); + } +} + +/* +================ +idAFConstraint_Hinge::GetFriction +================ +*/ +float idAFConstraint_Hinge::GetFriction( void ) const { + if ( af_forceFriction.GetFloat() > 0.0f ) { + return af_forceFriction.GetFloat(); + } + return friction * physics->GetJointFrictionScale(); +} + +/* +================ +idAFConstraint_Hinge::GetAngle +================ +*/ +float idAFConstraint_Hinge::GetAngle( void ) const { + idMat3 axis; + idRotation rotation; + float angle; + + axis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose() * initialAxis.Transpose(); + rotation = axis.ToRotation(); + angle = rotation.GetAngle(); + if ( rotation.GetVec() * axis1 < 0.0f ) { + return -angle; + } + return angle; +} + +/* +================ +idAFConstraint_Hinge::SetSteerAngle +================ +*/ +void idAFConstraint_Hinge::SetSteerAngle( const float degrees ) { + if ( coneLimit ) { + delete coneLimit; + coneLimit = NULL; + } + if ( !steering ) { + steering = new idAFConstraint_HingeSteering(); + steering->Setup( this ); + } + steering->SetSteerAngle( degrees ); +} + +/* +================ +idAFConstraint_Hinge::SetSteerSpeed +================ +*/ +void idAFConstraint_Hinge::SetSteerSpeed( const float speed ) { + if ( steering ) { + steering->SetSteerSpeed( speed ); + } +} + +/* +================ +idAFConstraint_Hinge::Evaluate +================ +*/ +void idAFConstraint_Hinge::Evaluate( float invTimeStep ) { + idVec3 a1, a2; + idVec3 x1, x2, cross; + idVec3 vecX, vecY; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + x1 = axis1 * body1->GetWorldAxis(); // axis in body1 space + x1.OrthogonalBasis( vecX, vecY ); // basis for axis in body1 space + + a1 = anchor1 * body1->GetWorldAxis(); // anchor in body1 space + + if ( master ) { + a2 = anchor2 * master->GetWorldAxis(); // anchor in master space + x2 = axis2 * master->GetWorldAxis(); + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); + } + else { + a2 = anchor2; + x2 = axis2; + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) ); + } + + J1.Set( mat3_identity, -SkewSymmetric( a1 ), + mat3_zero, idMat3( vecX[0], vecX[1], vecX[2], + vecY[0], vecY[1], vecY[2], + 0.0f, 0.0f, 0.0f ) ); + J1.SetSize( 5, 6 ); + + if ( body2 ) { + J2.Set( -mat3_identity, SkewSymmetric( a2 ), + mat3_zero, idMat3( -vecX[0], -vecX[1], -vecX[2], + -vecY[0], -vecY[1], -vecY[2], + 0.0f, 0.0f, 0.0f ) ); + J2.SetSize( 5, 6 ); + } + else { + J2.Zero( 5, 6 ); + } + + cross = x1.Cross( x2 ); + + c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecX ); + c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecY ); + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); + + if ( steering ) { + steering->Add( physics, invTimeStep ); + } + else if ( coneLimit ) { + coneLimit->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_Hinge::ApplyFriction +================ +*/ +void idAFConstraint_Hinge::ApplyFriction( float invTimeStep ) { + idVec3 angular; + float invMass, currentFriction; + + currentFriction = GetFriction(); + + if ( currentFriction <= 0.0f ) { + return; + } + + if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { + + angular = body1->GetAngularVelocity(); + invMass = body1->GetInverseMass(); + if ( body2 ) { + angular -= body2->GetAngularVelocity(); + invMass += body2->GetInverseMass(); + } + + angular *= currentFriction / invMass; + + body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); + if ( body2 ) { + body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); + } + } + else { + if ( !fc ) { + fc = new idAFConstraint_HingeFriction; + fc->Setup( this ); + } + + fc->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_Hinge::GetForce +================ +*/ +void idAFConstraint_Hinge::GetForce( idAFBody *body, idVec6 &force ) { + idAFConstraint::GetForce( body, force ); + // FIXME: add limit force +} + +/* +================ +idAFConstraint_Hinge::Translate +================ +*/ +void idAFConstraint_Hinge::Translate( const idVec3 &translation ) { + if ( !body2 ) { + anchor2 += translation; + } + if ( coneLimit ) { + coneLimit->Translate( translation ); + } +} + +/* +================ +idAFConstraint_Hinge::Rotate +================ +*/ +void idAFConstraint_Hinge::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + anchor2 *= rotation; + axis2 *= rotation.ToMat3(); + } + if ( coneLimit ) { + coneLimit->Rotate( rotation ); + } +} + +/* +================ +idAFConstraint_Hinge::GetCenter +================ +*/ +void idAFConstraint_Hinge::GetCenter( idVec3 ¢er ) { + center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); +} + +/* +================ +idAFConstraint_Hinge::DebugDraw +================ +*/ +void idAFConstraint_Hinge::DebugDraw( void ) { + idVec3 vecX, vecY; + idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + idVec3 x1 = axis1 * body1->GetWorldAxis(); + x1.OrthogonalBasis( vecX, vecY ); + + gameRenderWorld->DebugArrow( colorBlue, a1 - 4.0f * x1, a1 + 4.0f * x1, 1 ); + gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecX, a1 + 2.0f * vecX ); + gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecY, a1 + 2.0f * vecY ); + + if ( af_showLimits.GetBool() ) { + if ( coneLimit ) { + coneLimit->DebugDraw(); + } + } +} + +/* +================ +idAFConstraint_Hinge::Save +================ +*/ +void idAFConstraint_Hinge::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( anchor1 ); + saveFile->WriteVec3( anchor2 ); + saveFile->WriteVec3( axis1 ); + saveFile->WriteVec3( axis2 ); + saveFile->WriteMat3( initialAxis ); + saveFile->WriteFloat( friction ); + if ( coneLimit ) { + saveFile->WriteBool( true ); + coneLimit->Save( saveFile ); + } else { + saveFile->WriteBool( false ); + } + if ( steering ) { + saveFile->WriteBool( true ); + steering->Save( saveFile ); + } else { + saveFile->WriteBool( false ); + } + if ( fc ) { + saveFile->WriteBool( true ); + fc->Save( saveFile ); + } else { + saveFile->WriteBool( false ); + } +} + +/* +================ +idAFConstraint_Hinge::Restore +================ +*/ +void idAFConstraint_Hinge::Restore( idRestoreGame *saveFile ) { + bool b; + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( anchor1 ); + saveFile->ReadVec3( anchor2 ); + saveFile->ReadVec3( axis1 ); + saveFile->ReadVec3( axis2 ); + saveFile->ReadMat3( initialAxis ); + saveFile->ReadFloat( friction ); + + saveFile->ReadBool( b ); + if ( b ) { + if ( !coneLimit ) { + coneLimit = new idAFConstraint_ConeLimit; + } + coneLimit->SetPhysics( physics ); + coneLimit->Restore( saveFile ); + } + saveFile->ReadBool( b ); + if ( b ) { + if ( !steering ) { + steering = new idAFConstraint_HingeSteering; + } + steering->Setup( this ); + steering->Restore( saveFile ); + } + saveFile->ReadBool( b ); + if ( b ) { + if ( !fc ) { + fc = new idAFConstraint_HingeFriction; + } + fc->Setup( this ); + fc->Restore( saveFile ); + } +} + + +//=============================================================== +// +// idAFConstraint_HingeFriction +// +//=============================================================== + +/* +================ +idAFConstraint_HingeFriction::idAFConstraint_HingeFriction +================ +*/ +idAFConstraint_HingeFriction::idAFConstraint_HingeFriction( void ) { + type = CONSTRAINT_FRICTION; + name = "hingeFriction"; + InitSize( 1 ); + hinge = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_HingeFriction::Setup +================ +*/ +void idAFConstraint_HingeFriction::Setup( idAFConstraint_Hinge *h ) { + this->hinge = h; + body1 = h->GetBody1(); + body2 = h->GetBody2(); +} + +/* +================ +idAFConstraint_HingeFriction::Evaluate +================ +*/ +void idAFConstraint_HingeFriction::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_HingeFriction::ApplyFriction +================ +*/ +void idAFConstraint_HingeFriction::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_HingeFriction::Add +================ +*/ +bool idAFConstraint_HingeFriction::Add( idPhysics_AF *phys, float invTimeStep ) { + idVec3 a1, a2; + float f; + + physics = phys; + + f = hinge->GetFriction() * hinge->GetMultiplier().Length(); + if ( f == 0.0f ) { + return false; + } + + lo[0] = -f; + hi[0] = f; + + hinge->GetAxis( a1, a2 ); + + a1 *= body1->GetWorldAxis(); + + J1.SetSize( 1, 6 ); + J1.SubVec6(0).SubVec3(0).Zero(); + J1.SubVec6(0).SubVec3(1) = a1; + + if ( body2 ) { + a2 *= body2->GetWorldAxis(); + + J2.SetSize( 1, 6 ); + J2.SubVec6(0).SubVec3(0).Zero(); + J2.SubVec6(0).SubVec3(1) = -a2; + } + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_HingeFriction::Translate +================ +*/ +void idAFConstraint_HingeFriction::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_HingeFriction::Rotate +================ +*/ +void idAFConstraint_HingeFriction::Rotate( const idRotation &rotation ) { +} + + +//=============================================================== +// +// idAFConstraint_HingeSteering +// +//=============================================================== + +/* +================ +idAFConstraint_HingeSteering::idAFConstraint_HingeSteering +================ +*/ +idAFConstraint_HingeSteering::idAFConstraint_HingeSteering( void ) { + type = CONSTRAINT_HINGESTEERING; + name = "hingeFriction"; + InitSize( 1 ); + hinge = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; + steerSpeed = 0.0f; + epsilon = LCP_EPSILON; +} + +/* +================ +idAFConstraint_HingeSteering::Save +================ +*/ +void idAFConstraint_HingeSteering::Save( idSaveGame *saveFile ) const { + saveFile->WriteFloat(steerAngle); + saveFile->WriteFloat(steerSpeed); + saveFile->WriteFloat(epsilon); +} + +/* +================ +idAFConstraint_HingeSteering::Restore +================ +*/ +void idAFConstraint_HingeSteering::Restore( idRestoreGame *saveFile ) { + saveFile->ReadFloat(steerAngle); + saveFile->ReadFloat(steerSpeed); + saveFile->ReadFloat(epsilon); +} + +/* +================ +idAFConstraint_HingeSteering::Setup +================ +*/ +void idAFConstraint_HingeSteering::Setup( idAFConstraint_Hinge *h ) { + this->hinge = h; + body1 = h->GetBody1(); + body2 = h->GetBody2(); +} + +/* +================ +idAFConstraint_HingeSteering::Evaluate +================ +*/ +void idAFConstraint_HingeSteering::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_HingeSteering::ApplyFriction +================ +*/ +void idAFConstraint_HingeSteering::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_HingeSteering::Add +================ +*/ +bool idAFConstraint_HingeSteering::Add( idPhysics_AF *phys, float invTimeStep ) { + float angle, speed; + idVec3 a1, a2; + + physics = phys; + + hinge->GetAxis( a1, a2 ); + angle = hinge->GetAngle(); + + a1 *= body1->GetWorldAxis(); + + J1.SetSize( 1, 6 ); + J1.SubVec6(0).SubVec3(0).Zero(); + J1.SubVec6(0).SubVec3(1) = a1; + + if ( body2 ) { + a2 *= body2->GetWorldAxis(); + + J2.SetSize( 1, 6 ); + J2.SubVec6(0).SubVec3(0).Zero(); + J2.SubVec6(0).SubVec3(1) = -a2; + } + + speed = steerAngle - angle; + if ( steerSpeed != 0.0f ) { + if ( speed > steerSpeed ) { + speed = steerSpeed; + } + else if ( speed < -steerSpeed ) { + speed = -steerSpeed; + } + } + + c1[0] = DEG2RAD( speed ) * invTimeStep; + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_HingeSteering::Translate +================ +*/ +void idAFConstraint_HingeSteering::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_HingeSteering::Rotate +================ +*/ +void idAFConstraint_HingeSteering::Rotate( const idRotation &rotation ) { +} + + +//=============================================================== +// +// idAFConstraint_Slider +// +//=============================================================== + +/* +================ +idAFConstraint_Slider::idAFConstraint_Slider +================ +*/ +idAFConstraint_Slider::idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_SLIDER; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 5 ); + fl.allowPrimary = true; + fl.noCollision = true; + + if ( body2 ) { + offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose(); + } + else { + offset = body1->GetWorldOrigin(); + relAxis = body1->GetWorldAxis(); + } +} + +/* +================ +idAFConstraint_Slider::SetAxis +================ +*/ +void idAFConstraint_Slider::SetAxis( const idVec3 &ax ) { + idVec3 normAxis; + + // get normalized axis relative to body1 + normAxis = ax; + normAxis.Normalize(); + if ( body2 ) { + axis = normAxis * body2->GetWorldAxis().Transpose(); + } + else { + axis = normAxis; + } +} + +/* +================ +idAFConstraint_Slider::Evaluate +================ +*/ +void idAFConstraint_Slider::Evaluate( float invTimeStep ) { + idVec3 vecX, vecY, ofs; + idRotation r; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + (axis * master->GetWorldAxis()).OrthogonalBasis( vecX, vecY ); + ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); + r = ( body1->GetWorldAxis().Transpose() * (relAxis * master->GetWorldAxis()) ).ToRotation(); + } + else { + axis.OrthogonalBasis( vecX, vecY ); + ofs = offset - body1->GetWorldOrigin(); + r = ( body1->GetWorldAxis().Transpose() * relAxis ).ToRotation(); + } + + J1.Set( mat3_zero, mat3_identity, + idMat3( vecX, vecY, vec3_origin ), mat3_zero ); + J1.SetSize( 5, 6 ); + + if ( body2 ) { + + J2.Set( mat3_zero, -mat3_identity, + idMat3( -vecX, -vecY, vec3_origin ), mat3_zero ); + J2.SetSize( 5, 6 ); + } + else { + J2.Zero( 5, 6 ); + } + + c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * - (float) DEG2RAD( r.GetAngle() ) ); + + c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( vecX * ofs ); + c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( vecY * ofs ); + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); +} + +/* +================ +idAFConstraint_Slider::ApplyFriction +================ +*/ +void idAFConstraint_Slider::ApplyFriction( float invTimeStep ) { + // no friction +} + +/* +================ +idAFConstraint_Slider::Translate +================ +*/ +void idAFConstraint_Slider::Translate( const idVec3 &translation ) { + if ( !body2 ) { + offset += translation; + } +} + +/* +================ +idAFConstraint_Slider::Rotate +================ +*/ +void idAFConstraint_Slider::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + offset *= rotation; + } +} + +/* +================ +idAFConstraint_Slider::GetCenter +================ +*/ +void idAFConstraint_Slider::GetCenter( idVec3 ¢er ) { + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + if ( master ) { + center = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); + } + else { + center = offset - body1->GetWorldOrigin(); + } +} + +/* +================ +idAFConstraint_Slider::DebugDraw +================ +*/ +void idAFConstraint_Slider::DebugDraw( void ) { + idVec3 ofs; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + if ( master ) { + ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); + } + else { + ofs = offset - body1->GetWorldOrigin(); + } + gameRenderWorld->DebugLine( colorGreen, ofs, ofs + axis * body1->GetWorldAxis() ); +} + +/* +================ +idAFConstraint_Slider::Save +================ +*/ +void idAFConstraint_Slider::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( axis ); + saveFile->WriteVec3( offset ); + saveFile->WriteMat3( relAxis ); +} + +/* +================ +idAFConstraint_Slider::Restore +================ +*/ +void idAFConstraint_Slider::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( axis ); + saveFile->ReadVec3( offset ); + saveFile->ReadMat3( relAxis ); +} + + +//=============================================================== +// +// idAFConstraint_Line +// +//=============================================================== + +/* +================ +idAFConstraint_Line::idAFConstraint_Line +================ +*/ +idAFConstraint_Line::idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_Line::Evaluate +================ +*/ +void idAFConstraint_Line::Evaluate( float invTimeStep ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_Line::ApplyFriction +================ +*/ +void idAFConstraint_Line::ApplyFriction( float invTimeStep ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_Line::Translate +================ +*/ +void idAFConstraint_Line::Translate( const idVec3 &translation ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_Line::Rotate +================ +*/ +void idAFConstraint_Line::Rotate( const idRotation &rotation ) { + assert( 0 ); // FIXME: implement +} + +/* +================ +idAFConstraint_Line::DebugDraw +================ +*/ +void idAFConstraint_Line::DebugDraw( void ) { + assert( 0 ); // FIXME: implement +} + + +//=============================================================== +// +// idAFConstraint_Plane +// +//=============================================================== + +/* +================ +idAFConstraint_Plane::idAFConstraint_Plane +================ +*/ +idAFConstraint_Plane::idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_PLANE; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 1 ); + fl.allowPrimary = true; + fl.noCollision = true; +} + +/* +================ +idAFConstraint_Plane::SetPlane +================ +*/ +void idAFConstraint_Plane::SetPlane( const idVec3 &normal, const idVec3 &anchor ) { + // get anchor relative to center of mass of body1 + anchor1 = ( anchor - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get anchor relative to center of mass of body2 + anchor2 = ( anchor - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + planeNormal = normal * body2->GetWorldAxis().Transpose(); + } + else { + anchor2 = anchor; + planeNormal = normal; + } +} + +/* +================ +idAFConstraint_Plane::Evaluate +================ +*/ +void idAFConstraint_Plane::Evaluate( float invTimeStep ) { + idVec3 a1, a2, normal, p; + idVec6 v; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + if ( master ) { + a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); + normal = planeNormal * master->GetWorldAxis(); + } + else { + a2 = anchor2; + normal = planeNormal; + } + + p = a1 - body1->GetWorldOrigin(); + v.SubVec3(0) = normal; + v.SubVec3(1) = p.Cross( normal ); + J1.Set( 1, 6, v.ToFloatPtr() ); + + if ( body2 ) { + p = a1 - body2->GetWorldOrigin(); + v.SubVec3(0) = -normal; + v.SubVec3(1) = p.Cross( -normal ); + J2.Set( 1, 6, v.ToFloatPtr() ); + } + + c1[0] = -( invTimeStep * ERROR_REDUCTION ) * (a1 * normal - a2 * normal); + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); +} + +/* +================ +idAFConstraint_Plane::ApplyFriction +================ +*/ +void idAFConstraint_Plane::ApplyFriction( float invTimeStep ) { + // no friction +} + +/* +================ +idAFConstraint_Plane::Translate +================ +*/ +void idAFConstraint_Plane::Translate( const idVec3 &translation ) { + if ( !body2 ) { + anchor2 += translation; + } +} + +/* +================ +idAFConstraint_Plane::Rotate +================ +*/ +void idAFConstraint_Plane::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + anchor2 *= rotation; + planeNormal *= rotation.ToMat3(); + } +} + +/* +================ +idAFConstraint_Plane::DebugDraw +================ +*/ +void idAFConstraint_Plane::DebugDraw( void ) { + idVec3 a1, normal, right, up; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + if ( master ) { + normal = planeNormal * master->GetWorldAxis(); + } + else { + normal = planeNormal; + } + normal.NormalVectors( right, up ); + normal *= 4.0f; + right *= 4.0f; + up *= 4.0f; + + gameRenderWorld->DebugLine( colorCyan, a1 - right, a1 + right ); + gameRenderWorld->DebugLine( colorCyan, a1 - up, a1 + up ); + gameRenderWorld->DebugArrow( colorCyan, a1, a1 + normal, 1 ); +} + +/* +================ +idAFConstraint_Plane::Save +================ +*/ +void idAFConstraint_Plane::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( anchor1 ); + saveFile->WriteVec3( anchor2 ); + saveFile->WriteVec3( planeNormal ); +} + +/* +================ +idAFConstraint_Plane::Restore +================ +*/ +void idAFConstraint_Plane::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( anchor1 ); + saveFile->ReadVec3( anchor2 ); + saveFile->ReadVec3( planeNormal ); +} + + +//=============================================================== +// +// idAFConstraint_Spring +// +//=============================================================== + +/* +================ +idAFConstraint_Spring::idAFConstraint_Spring +================ +*/ +idAFConstraint_Spring::idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 ) { + assert( body1 ); + type = CONSTRAINT_SPRING; + this->name = name; + this->body1 = body1; + this->body2 = body2; + InitSize( 1 ); + fl.allowPrimary = false; + kstretch = kcompress = damping = 1.0f; + minLength = maxLength = restLength = 0.0f; +} + +/* +================ +idAFConstraint_Spring::SetAnchor +================ +*/ +void idAFConstraint_Spring::SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 ) { + // get anchor relative to center of mass of body1 + anchor1 = ( worldAnchor1 - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + if ( body2 ) { + // get anchor relative to center of mass of body2 + anchor2 = ( worldAnchor2 - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); + } + else { + anchor2 = worldAnchor2; + } +} + +/* +================ +idAFConstraint_Spring::SetSpring +================ +*/ +void idAFConstraint_Spring::SetSpring( const float stretch, const float compress, const float damping, const float restLength ) { + assert( stretch >= 0.0f && compress >= 0.0f && restLength >= 0.0f ); + this->kstretch = stretch; + this->kcompress = compress; + this->damping = damping; + this->restLength = restLength; +} + +/* +================ +idAFConstraint_Spring::SetLimit +================ +*/ +void idAFConstraint_Spring::SetLimit( const float minLength, const float maxLength ) { + assert( minLength >= 0.0f && maxLength >= 0.0f && maxLength >= minLength ); + this->minLength = minLength; + this->maxLength = maxLength; +} + +/* +================ +idAFConstraint_Spring::Evaluate +================ +*/ +void idAFConstraint_Spring::Evaluate( float invTimeStep ) { + idVec3 a1, a2, velocity1, velocity2, force; + idVec6 v1, v2; + float d, dampingForce, length, error; + bool limit; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + velocity1 = body1->GetPointVelocity( a1 ); + + if ( master ) { + a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); + velocity2 = master->GetPointVelocity( a2 ); + } + else { + a2 = anchor2; + velocity2.Zero(); + } + + force = a2 - a1; + d = force * force; + if ( d != 0.0f ) { + dampingForce = damping * idMath::Fabs( (velocity2 - velocity1) * force ) / d; + } + else { + dampingForce = 0.0f; + } + length = force.Normalize(); + + if ( length > restLength ) { + if ( kstretch > 0.0f ) { + idVec3 springForce = force * ( Square( length - restLength ) * kstretch - dampingForce ); + body1->AddForce( a1, springForce ); + if ( master ) { + master->AddForce( a2, -springForce ); + } + } + } + else { + if ( kcompress > 0.0f ) { + idVec3 springForce = force * -( Square( restLength - length ) * kcompress - dampingForce ); + body1->AddForce( a1, springForce ); + if ( master ) { + master->AddForce( a2, -springForce ); + } + } + } + + // check for spring limits + if ( length < minLength ) { + force = -force; + error = minLength - length; + limit = true; + } + else if ( maxLength > 0.0f && length > maxLength ) { + error = length - maxLength; + limit = true; + } + else { + error = 0.0f; + limit = false; + } + + if ( limit ) { + a1 -= body1->GetWorldOrigin(); + v1.SubVec3(0) = force; + v1.SubVec3(1) = a1.Cross( force ); + J1.Set( 1, 6, v1.ToFloatPtr() ); + if ( body2 ) { + a2 -= body2->GetWorldOrigin(); + v2.SubVec3(0) = -force; + v2.SubVec3(1) = a2.Cross( -force ); + J2.Set( 1, 6, v2.ToFloatPtr() ); + } + c1[0] = -( invTimeStep * ERROR_REDUCTION ) * error; + lo[0] = 0.0f; + } + else { + J1.Zero( 0, 0 ); + J2.Zero( 0, 0 ); + } + + c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); +} + +/* +================ +idAFConstraint_Spring::ApplyFriction +================ +*/ +void idAFConstraint_Spring::ApplyFriction( float invTimeStep ) { + // no friction +} + +/* +================ +idAFConstraint_Spring::Translate +================ +*/ +void idAFConstraint_Spring::Translate( const idVec3 &translation ) { + if ( !body2 ) { + anchor2 += translation; + } +} + +/* +================ +idAFConstraint_Spring::Rotate +================ +*/ +void idAFConstraint_Spring::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + anchor2 *= rotation; + } +} + +/* +================ +idAFConstraint_Spring::GetCenter +================ +*/ +void idAFConstraint_Spring::GetCenter( idVec3 ¢er ) { + idAFBody *master; + idVec3 a1, a2; + + master = body2 ? body2 : physics->GetMasterBody(); + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + if ( master ) { + a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); + } + else { + a2 = anchor2; + } + center = ( a1 + a2 ) * 0.5f; +} + +/* +================ +idAFConstraint_Spring::DebugDraw +================ +*/ +void idAFConstraint_Spring::DebugDraw( void ) { + idAFBody *master; + float length; + idVec3 a1, a2, dir, mid, p; + + master = body2 ? body2 : physics->GetMasterBody(); + a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); + if ( master ) { + a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); + } + else { + a2 = anchor2; + } + dir = a2 - a1; + mid = a1 + 0.5f * dir; + length = dir.Normalize(); + + // draw spring + gameRenderWorld->DebugLine( colorGreen, a1, a2 ); + + // draw rest length + p = restLength * 0.5f * dir; + gameRenderWorld->DebugCircle( colorWhite, mid + p, dir, 1.0f, 10 ); + gameRenderWorld->DebugCircle( colorWhite, mid - p, dir, 1.0f, 10 ); + if ( restLength > length ) { + gameRenderWorld->DebugLine( colorWhite, a2, mid + p ); + gameRenderWorld->DebugLine( colorWhite, a1, mid - p ); + } + + if ( minLength > 0.0f ) { + // draw min length + gameRenderWorld->DebugCircle( colorBlue, mid + minLength * 0.5f * dir, dir, 2.0f, 10 ); + gameRenderWorld->DebugCircle( colorBlue, mid - minLength * 0.5f * dir, dir, 2.0f, 10 ); + } + + if ( maxLength > 0.0f ) { + // draw max length + gameRenderWorld->DebugCircle( colorRed, mid + maxLength * 0.5f * dir, dir, 2.0f, 10 ); + gameRenderWorld->DebugCircle( colorRed, mid - maxLength * 0.5f * dir, dir, 2.0f, 10 ); + } +} + +/* +================ +idAFConstraint_Spring::Save +================ +*/ +void idAFConstraint_Spring::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( anchor1 ); + saveFile->WriteVec3( anchor2 ); + saveFile->WriteFloat( kstretch ); + saveFile->WriteFloat( kcompress ); + saveFile->WriteFloat( damping ); + saveFile->WriteFloat( restLength ); + saveFile->WriteFloat( minLength ); + saveFile->WriteFloat( maxLength ); +} + +/* +================ +idAFConstraint_Spring::Restore +================ +*/ +void idAFConstraint_Spring::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( anchor1 ); + saveFile->ReadVec3( anchor2 ); + saveFile->ReadFloat( kstretch ); + saveFile->ReadFloat( kcompress ); + saveFile->ReadFloat( damping ); + saveFile->ReadFloat( restLength ); + saveFile->ReadFloat( minLength ); + saveFile->ReadFloat( maxLength ); +} + + +//=============================================================== +// +// idAFConstraint_Contact +// +//=============================================================== + +/* +================ +idAFConstraint_Contact::idAFConstraint_Contact +================ +*/ +idAFConstraint_Contact::idAFConstraint_Contact( void ) { + name = "contact"; + type = CONSTRAINT_CONTACT; + InitSize( 1 ); + fc = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_Contact::~idAFConstraint_Contact +================ +*/ +idAFConstraint_Contact::~idAFConstraint_Contact( void ) { + if ( fc ) { + delete fc; + } +} + +/* +================ +idAFConstraint_Contact::Setup +================ +*/ +void idAFConstraint_Contact::Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c ) { + idVec3 p; + idVec6 v; + float vel; + float minBounceVelocity = 2.0f; + + assert( b1 ); + + body1 = b1; + body2 = b2; + contact = c; + + p = c.point - body1->GetWorldOrigin(); + v.SubVec3(0) = c.normal; + v.SubVec3(1) = p.Cross( c.normal ); + J1.Set( 1, 6, v.ToFloatPtr() ); + vel = v.SubVec3(0) * body1->GetLinearVelocity() + v.SubVec3(1) * body1->GetAngularVelocity(); + + if ( body2 ) { + p = c.point - body2->GetWorldOrigin(); + v.SubVec3(0) = -c.normal; + v.SubVec3(1) = p.Cross( -c.normal ); + J2.Set( 1, 6, v.ToFloatPtr() ); + vel += v.SubVec3(0) * body2->GetLinearVelocity() + v.SubVec3(1) * body2->GetAngularVelocity(); + c2[0] = 0.0f; + } + + if ( body1->GetBouncyness() > 0.0f && -vel > minBounceVelocity ) { + c1[0] = body1->GetBouncyness() * vel; + } else { + c1[0] = 0.0f; + } + + e[0] = CONTACT_LCP_EPSILON; + lo[0] = 0.0f; + hi[0] = idMath::INFINITY; + boxConstraint = NULL; + boxIndex[0] = -1; +} + +/* +================ +idAFConstraint_Contact::Evaluate +================ +*/ +void idAFConstraint_Contact::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_Contact::ApplyFriction +================ +*/ +void idAFConstraint_Contact::ApplyFriction( float invTimeStep ) { + idVec3 r, velocity, normal, dir1, dir2; + float friction, magnitude, forceNumerator, forceDenominator; + idVecX impulse, dv; + + friction = body1->GetContactFriction(); + if ( body2 && body2->GetContactFriction() < friction ) { + friction = body2->GetContactFriction(); + } + + friction *= physics->GetContactFrictionScale(); + + if ( friction <= 0.0f ) { + return; + } + + // seperate friction per contact is silly but it's fast and often looks close enough + if ( af_useImpulseFriction.GetBool() ) { + + impulse.SetData( 6, VECX_ALLOCA( 6 ) ); + dv.SetData( 6, VECX_ALLOCA( 6 ) ); + + // calculate velocity in the contact plane + r = contact.point - body1->GetWorldOrigin(); + velocity = body1->GetLinearVelocity() + body1->GetAngularVelocity().Cross( r ); + velocity -= contact.normal * velocity * contact.normal; + + // get normalized direction of friction and magnitude of velocity + normal = -velocity; + magnitude = normal.Normalize(); + + forceNumerator = friction * magnitude; + forceDenominator = body1->GetInverseMass() + ( ( body1->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal ); + impulse.SubVec3(0) = (forceNumerator / forceDenominator) * normal; + impulse.SubVec3(1) = r.Cross( impulse.SubVec3(0) ); + body1->InverseWorldSpatialInertiaMultiply( dv, impulse.ToFloatPtr() ); + + // modify velocity with friction force + body1->SetLinearVelocity( body1->GetLinearVelocity() + dv.SubVec3(0) ); + body1->SetAngularVelocity( body1->GetAngularVelocity() + dv.SubVec3(1) ); + } + else { + + if ( !fc ) { + fc = new idAFConstraint_ContactFriction; + } + // call setup each frame because contact constraints are re-used for different bodies + fc->Setup( this ); + fc->Add( physics, invTimeStep ); + } +} + +/* +================ +idAFConstraint_Contact::Translate +================ +*/ +void idAFConstraint_Contact::Translate( const idVec3 &translation ) { + assert( 0 ); // contact should never be translated +} + +/* +================ +idAFConstraint_Contact::Rotate +================ +*/ +void idAFConstraint_Contact::Rotate( const idRotation &rotation ) { + assert( 0 ); // contact should never be rotated +} + +/* +================ +idAFConstraint_Contact::GetCenter +================ +*/ +void idAFConstraint_Contact::GetCenter( idVec3 ¢er ) { + center = contact.point; +} + +/* +================ +idAFConstraint_Contact::DebugDraw +================ +*/ +void idAFConstraint_Contact::DebugDraw( void ) { + idVec3 x, y; + contact.normal.NormalVectors( x, y ); + gameRenderWorld->DebugLine( colorWhite, contact.point, contact.point + 6.0f * contact.normal ); + gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * x, contact.point + 2.0f * x ); + gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * y, contact.point + 2.0f * y ); +} + + +//=============================================================== +// +// idAFConstraint_ContactFriction +// +//=============================================================== + +/* +================ +idAFConstraint_ContactFriction::idAFConstraint_ContactFriction +================ +*/ +idAFConstraint_ContactFriction::idAFConstraint_ContactFriction( void ) { + type = CONSTRAINT_FRICTION; + name = "contactFriction"; + InitSize( 2 ); + cc = NULL; + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_ContactFriction::Setup +================ +*/ +void idAFConstraint_ContactFriction::Setup( idAFConstraint_Contact *cc ) { + this->cc = cc; + body1 = cc->GetBody1(); + body2 = cc->GetBody2(); +} + +/* +================ +idAFConstraint_ContactFriction::Evaluate +================ +*/ +void idAFConstraint_ContactFriction::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_ContactFriction::ApplyFriction +================ +*/ +void idAFConstraint_ContactFriction::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_ContactFriction::Add +================ +*/ +bool idAFConstraint_ContactFriction::Add( idPhysics_AF *phys, float invTimeStep ) { + idVec3 r, dir1, dir2; + float friction; + int newRow; + + physics = phys; + + friction = body1->GetContactFriction() * physics->GetContactFrictionScale(); + + // if the body only has friction in one direction + if ( body1->GetFrictionDirection( dir1 ) ) { + // project the friction direction into the contact plane + dir1 -= dir1 * cc->GetContact().normal * dir1; + dir1.Normalize(); + + r = cc->GetContact().point - body1->GetWorldOrigin(); + + J1.SetSize( 1, 6 ); + J1.SubVec6(0).SubVec3(0) = dir1; + J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 ); + c1.SetSize( 1 ); + c1[0] = 0.0f; + + if ( body2 ) { + r = cc->GetContact().point - body2->GetWorldOrigin(); + + J2.SetSize( 1, 6 ); + J2.SubVec6(0).SubVec3(0) = -dir1; + J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 ); + c2.SetSize( 1 ); + c2[0] = 0.0f; + } + + lo[0] = -friction; + hi[0] = friction; + boxConstraint = cc; + boxIndex[0] = 0; + } + else { + // get two friction directions orthogonal to contact normal + cc->GetContact().normal.NormalVectors( dir1, dir2 ); + + r = cc->GetContact().point - body1->GetWorldOrigin(); + + J1.SetSize( 2, 6 ); + J1.SubVec6(0).SubVec3(0) = dir1; + J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 ); + J1.SubVec6(1).SubVec3(0) = dir2; + J1.SubVec6(1).SubVec3(1) = r.Cross( dir2 ); + c1.SetSize( 2 ); + c1[0] = c1[1] = 0.0f; + + if ( body2 ) { + r = cc->GetContact().point - body2->GetWorldOrigin(); + + J2.SetSize( 2, 6 ); + J2.SubVec6(0).SubVec3(0) = -dir1; + J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 ); + J2.SubVec6(1).SubVec3(0) = -dir2; + J2.SubVec6(1).SubVec3(1) = r.Cross( -dir2 ); + c2.SetSize( 2 ); + c2[0] = c2[1] = 0.0f; + + if ( body2->GetContactFriction() < friction ) { + friction = body2->GetContactFriction(); + } + } + + lo[0] = -friction; + hi[0] = friction; + boxConstraint = cc; + boxIndex[0] = 0; + lo[1] = -friction; + hi[1] = friction; + boxIndex[1] = 0; + } + + if ( body1->GetContactMotorDirection( dir1 ) && body1->GetContactMotorForce() > 0.0f ) { + // project the motor force direction into the contact plane + dir1 -= dir1 * cc->GetContact().normal * dir1; + dir1.Normalize(); + + r = cc->GetContact().point - body1->GetWorldOrigin(); + + newRow = J1.GetNumRows(); + J1.ChangeSize( newRow+1, J1.GetNumColumns() ); + J1.SubVec6(newRow).SubVec3(0) = -dir1; + J1.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 ); + c1.ChangeSize( newRow+1 ); + c1[newRow] = body1->GetContactMotorVelocity(); + + if ( body2 ) { + r = cc->GetContact().point - body2->GetWorldOrigin(); + + J2.ChangeSize( newRow+1, J2.GetNumColumns() ); + J2.SubVec6(newRow).SubVec3(0) = -dir1; + J2.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 ); + c2.ChangeSize( newRow+1 ); + c2[newRow] = 0.0f; + } + + lo[newRow] = -body1->GetContactMotorForce(); + hi[newRow] = body1->GetContactMotorForce(); + boxIndex[newRow] = -1; + } + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_ContactFriction::Translate +================ +*/ +void idAFConstraint_ContactFriction::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_ContactFriction::Rotate +================ +*/ +void idAFConstraint_ContactFriction::Rotate( const idRotation &rotation ) { +} + +/* +================ +idAFConstraint_ContactFriction::DebugDraw +================ +*/ +void idAFConstraint_ContactFriction::DebugDraw( void ) { +} + + +//=============================================================== +// +// idAFConstraint_ConeLimit +// +//=============================================================== + +/* +================ +idAFConstraint_ConeLimit::idAFConstraint_ConeLimit +================ +*/ +idAFConstraint_ConeLimit::idAFConstraint_ConeLimit( void ) { + type = CONSTRAINT_CONELIMIT; + name = "coneLimit"; + InitSize( 1 ); + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_ConeLimit::Setup + + the coneAnchor is the top of the cone in body2 space + the coneAxis is the axis of the cone in body2 space + the coneAngle is the angle the cone hull makes at the top + the body1Axis is the axis in body1 space that should stay within the cone +================ +*/ +void idAFConstraint_ConeLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) { + this->body1 = b1; + this->body2 = b2; + this->coneAxis = coneAxis; + this->coneAxis.Normalize(); + this->coneAnchor = coneAnchor; + this->body1Axis = body1Axis; + this->body1Axis.Normalize(); + this->cosAngle = (float) cos( DEG2RAD( coneAngle * 0.5f ) ); + this->sinHalfAngle = (float) sin( DEG2RAD( coneAngle * 0.25f ) ); + this->cosHalfAngle = (float) cos( DEG2RAD( coneAngle * 0.25f ) ); +} + +/* +================ +idAFConstraint_ConeLimit::SetAnchor +================ +*/ +void idAFConstraint_ConeLimit::SetAnchor( const idVec3 &coneAnchor ) { + this->coneAnchor = coneAnchor; +} + +/* +================ +idAFConstraint_ConeLimit::SetBody1Axis +================ +*/ +void idAFConstraint_ConeLimit::SetBody1Axis( const idVec3 &body1Axis ) { + this->body1Axis = body1Axis; +} + +/* +================ +idAFConstraint_ConeLimit::Evaluate +================ +*/ +void idAFConstraint_ConeLimit::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_ConeLimit::ApplyFriction +================ +*/ +void idAFConstraint_ConeLimit::ApplyFriction( float invTimeStep ) { +} + +/* +================ +idAFConstraint_ConeLimit::Add +================ +*/ +bool idAFConstraint_ConeLimit::Add( idPhysics_AF *phys, float invTimeStep ) { + float a; + idVec6 J1row, J2row; + idVec3 ax, anchor, body1ax, normal, coneVector, p1, p2; + idQuat q; + idAFBody *master; + + if ( af_skipLimits.GetBool() ) { + lm.Zero(); // constraint exerts no force + return false; + } + + physics = phys; + + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + ax = coneAxis * master->GetWorldAxis(); + anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis(); + } + else { + ax = coneAxis; + anchor = coneAnchor; + } + + body1ax = body1Axis * body1->GetWorldAxis(); + + a = ax * body1ax; + + // if the body1 axis is inside the cone + if ( a > cosAngle ) { + lm.Zero(); // constraint exerts no force + return false; + } + + // calculate the inward cone normal for the position the body1 axis went outside the cone + normal = body1ax.Cross( ax ); + normal.Normalize(); + q.x = normal.x * sinHalfAngle; + q.y = normal.y * sinHalfAngle; + q.z = normal.z * sinHalfAngle; + q.w = cosHalfAngle; + coneVector = ax * q.ToMat3(); + normal = coneVector.Cross( ax ).Cross( coneVector ); + normal.Normalize(); + + p1 = anchor + 32.0f * coneVector - body1->GetWorldOrigin(); + + J1row.SubVec3(0) = normal; + J1row.SubVec3(1) = p1.Cross( normal ); + J1.Set( 1, 6, J1row.ToFloatPtr() ); + + c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) ); + + if ( body2 ) { + + p2 = anchor + 32.0f * coneVector - master->GetWorldOrigin(); + + J2row.SubVec3(0) = -normal; + J2row.SubVec3(1) = p2.Cross( -normal ); + J2.Set( 1, 6, J2row.ToFloatPtr() ); + + c2[0] = 0.0f; + } + + lo[0] = 0.0f; + e[0] = LIMIT_LCP_EPSILON; + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_ConeLimit::Translate +================ +*/ +void idAFConstraint_ConeLimit::Translate( const idVec3 &translation ) { + if ( !body2 ) { + coneAnchor += translation; + } +} + +/* +================ +idAFConstraint_ConeLimit::Rotate +================ +*/ +void idAFConstraint_ConeLimit::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + coneAnchor *= rotation; + coneAxis *= rotation.ToMat3(); + } +} + +/* +================ +idAFConstraint_ConeLimit::DebugDraw +================ +*/ +void idAFConstraint_ConeLimit::DebugDraw( void ) { + idVec3 ax, anchor, x, y, z, start, end; + float sinAngle, a, size = 10.0f; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + ax = coneAxis * master->GetWorldAxis(); + anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis(); + } + else { + ax = coneAxis; + anchor = coneAnchor; + } + + // draw body1 axis + gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) ); + + // draw cone + ax.NormalVectors( x, y ); + sinAngle = idMath::Sqrt( 1.0f - cosAngle * cosAngle ); + x *= size * sinAngle; + y *= size * sinAngle; + z = anchor + ax * size * cosAngle; + start = x + z; + for ( a = 0.0f; a < 360.0f; a += 45.0f ) { + end = x * (float) cos( DEG2RAD(a + 45.0f) ) + y * (float) sin( DEG2RAD(a + 45.0f) ) + z; + gameRenderWorld->DebugLine( colorMagenta, anchor, start ); + gameRenderWorld->DebugLine( colorMagenta, start, end ); + start = end; + } +} + +/* +================ +idAFConstraint_ConeLimit::Save +================ +*/ +void idAFConstraint_ConeLimit::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( coneAnchor ); + saveFile->WriteVec3( coneAxis ); + saveFile->WriteVec3( body1Axis ); + saveFile->WriteFloat( cosAngle ); + saveFile->WriteFloat( sinHalfAngle ); + saveFile->WriteFloat( cosHalfAngle ); + saveFile->WriteFloat( epsilon ); +} + +/* +================ +idAFConstraint_ConeLimit::Restore +================ +*/ +void idAFConstraint_ConeLimit::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( coneAnchor ); + saveFile->ReadVec3( coneAxis ); + saveFile->ReadVec3( body1Axis ); + saveFile->ReadFloat( cosAngle ); + saveFile->ReadFloat( sinHalfAngle ); + saveFile->ReadFloat( cosHalfAngle ); + saveFile->ReadFloat( epsilon ); +} + + +//=============================================================== +// +// idAFConstraint_PyramidLimit +// +//=============================================================== + +/* +================ +idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit +================ +*/ +idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit( void ) { + type = CONSTRAINT_PYRAMIDLIMIT; + name = "pyramidLimit"; + InitSize( 1 ); + fl.allowPrimary = false; + fl.frameConstraint = true; +} + +/* +================ +idAFConstraint_PyramidLimit::Setup +================ +*/ +void idAFConstraint_PyramidLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor, + const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis ) { + body1 = b1; + body2 = b2; + // setup the base and make sure the basis is orthonormal + pyramidBasis[2] = pyramidAxis; + pyramidBasis[2].Normalize(); + pyramidBasis[0] = baseAxis; + pyramidBasis[0] -= pyramidBasis[2] * baseAxis * pyramidBasis[2]; + pyramidBasis[0].Normalize(); + pyramidBasis[1] = pyramidBasis[0].Cross( pyramidBasis[2] ); + // pyramid top + this->pyramidAnchor = pyramidAnchor; + // angles + cosAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.5f ) ); + cosAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.5f ) ); + sinHalfAngle[0] = (float) sin( DEG2RAD( pyramidAngle1 * 0.25f ) ); + sinHalfAngle[1] = (float) sin( DEG2RAD( pyramidAngle2 * 0.25f ) ); + cosHalfAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.25f ) ); + cosHalfAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.25f ) ); + + this->body1Axis = body1Axis; +} + +/* +================ +idAFConstraint_PyramidLimit::SetAnchor +================ +*/ +void idAFConstraint_PyramidLimit::SetAnchor( const idVec3 &pyramidAnchor ) { + this->pyramidAnchor = pyramidAnchor; +} + +/* +================ +idAFConstraint_PyramidLimit::SetBody1Axis +================ +*/ +void idAFConstraint_PyramidLimit::SetBody1Axis( const idVec3 &body1Axis ) { + this->body1Axis = body1Axis; +} + +/* +================ +idAFConstraint_PyramidLimit::Evaluate +================ +*/ +void idAFConstraint_PyramidLimit::Evaluate( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_PyramidLimit::ApplyFriction +================ +*/ +void idAFConstraint_PyramidLimit::ApplyFriction( float invTimeStep ) { +} + +/* +================ +idAFConstraint_PyramidLimit::Add +================ +*/ +bool idAFConstraint_PyramidLimit::Add( idPhysics_AF *phys, float invTimeStep ) { + int i; + float a[2]; + idVec6 J1row, J2row; + idMat3 worldBase; + idVec3 anchor, body1ax, ax[2], v, normal, pyramidVector, p1, p2; + idQuat q; + idAFBody *master; + + if ( af_skipLimits.GetBool() ) { + lm.Zero(); // constraint exerts no force + return false; + } + + physics = phys; + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + worldBase[0] = pyramidBasis[0] * master->GetWorldAxis(); + worldBase[1] = pyramidBasis[1] * master->GetWorldAxis(); + worldBase[2] = pyramidBasis[2] * master->GetWorldAxis(); + anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis(); + } + else { + worldBase = pyramidBasis; + anchor = pyramidAnchor; + } + + body1ax = body1Axis * body1->GetWorldAxis(); + + for ( i = 0; i < 2; i++ ) { + ax[i] = body1ax - worldBase[!i] * body1ax * worldBase[!i]; + ax[i].Normalize(); + a[i] = worldBase[2] * ax[i]; + } + + // if the body1 axis is inside the pyramid + if ( a[0] > cosAngle[0] && a[1] > cosAngle[1] ) { + lm.Zero(); // constraint exerts no force + return false; + } + + // calculate the inward pyramid normal for the position the body1 axis went outside the pyramid + pyramidVector = worldBase[2]; + for ( i = 0; i < 2; i++ ) { + if ( a[i] <= cosAngle[i] ) { + v = ax[i].Cross( worldBase[2] ); + v.Normalize(); + q.x = v.x * sinHalfAngle[i]; + q.y = v.y * sinHalfAngle[i]; + q.z = v.z * sinHalfAngle[i]; + q.w = cosHalfAngle[i]; + pyramidVector *= q.ToMat3(); + } + } + normal = pyramidVector.Cross( worldBase[2] ).Cross( pyramidVector ); + normal.Normalize(); + + p1 = anchor + 32.0f * pyramidVector - body1->GetWorldOrigin(); + + J1row.SubVec3(0) = normal; + J1row.SubVec3(1) = p1.Cross( normal ); + J1.Set( 1, 6, J1row.ToFloatPtr() ); + + c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) ); + + if ( body2 ) { + + p2 = anchor + 32.0f * pyramidVector - master->GetWorldOrigin(); + + J2row.SubVec3(0) = -normal; + J2row.SubVec3(1) = p2.Cross( -normal ); + J2.Set( 1, 6, J2row.ToFloatPtr() ); + + c2[0] = 0.0f; + } + + lo[0] = 0.0f; + e[0] = LIMIT_LCP_EPSILON; + + physics->AddFrameConstraint( this ); + + return true; +} + +/* +================ +idAFConstraint_PyramidLimit::Translate +================ +*/ +void idAFConstraint_PyramidLimit::Translate( const idVec3 &translation ) { + if ( !body2 ) { + pyramidAnchor += translation; + } +} + +/* +================ +idAFConstraint_PyramidLimit::Rotate +================ +*/ +void idAFConstraint_PyramidLimit::Rotate( const idRotation &rotation ) { + if ( !body2 ) { + pyramidAnchor *= rotation; + pyramidBasis[0] *= rotation.ToMat3(); + pyramidBasis[1] *= rotation.ToMat3(); + pyramidBasis[2] *= rotation.ToMat3(); + } +} + +/* +================ +idAFConstraint_PyramidLimit::DebugDraw +================ +*/ +void idAFConstraint_PyramidLimit::DebugDraw( void ) { + int i; + float size = 10.0f; + idVec3 anchor, dir, p[4]; + idMat3 worldBase, m[2]; + idQuat q; + idAFBody *master; + + master = body2 ? body2 : physics->GetMasterBody(); + + if ( master ) { + worldBase[0] = pyramidBasis[0] * master->GetWorldAxis(); + worldBase[1] = pyramidBasis[1] * master->GetWorldAxis(); + worldBase[2] = pyramidBasis[2] * master->GetWorldAxis(); + anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis(); + } + else { + worldBase = pyramidBasis; + anchor = pyramidAnchor; + } + + // draw body1 axis + gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) ); + + // draw the pyramid + for ( i = 0; i < 2; i++ ) { + q.x = worldBase[!i].x * sinHalfAngle[i]; + q.y = worldBase[!i].y * sinHalfAngle[i]; + q.z = worldBase[!i].z * sinHalfAngle[i]; + q.w = cosHalfAngle[i]; + m[i] = q.ToMat3(); + } + + dir = worldBase[2] * size; + p[0] = anchor + m[0] * (m[1] * dir); + p[1] = anchor + m[0] * (m[1].Transpose() * dir); + p[2] = anchor + m[0].Transpose() * (m[1].Transpose() * dir); + p[3] = anchor + m[0].Transpose() * (m[1] * dir); + + for ( i = 0; i < 4; i++ ) { + gameRenderWorld->DebugLine( colorMagenta, anchor, p[i] ); + gameRenderWorld->DebugLine( colorMagenta, p[i], p[(i+1)&3] ); + } +} + +/* +================ +idAFConstraint_PyramidLimit::Save +================ +*/ +void idAFConstraint_PyramidLimit::Save( idSaveGame *saveFile ) const { + idAFConstraint::Save( saveFile ); + saveFile->WriteVec3( pyramidAnchor ); + saveFile->WriteMat3( pyramidBasis ); + saveFile->WriteVec3( body1Axis ); + saveFile->WriteFloat( cosAngle[0] ); + saveFile->WriteFloat( cosAngle[1] ); + saveFile->WriteFloat( sinHalfAngle[0] ); + saveFile->WriteFloat( sinHalfAngle[1] ); + saveFile->WriteFloat( cosHalfAngle[0] ); + saveFile->WriteFloat( cosHalfAngle[1] ); + saveFile->WriteFloat( epsilon ); +} + +/* +================ +idAFConstraint_PyramidLimit::Restore +================ +*/ +void idAFConstraint_PyramidLimit::Restore( idRestoreGame *saveFile ) { + idAFConstraint::Restore( saveFile ); + saveFile->ReadVec3( pyramidAnchor ); + saveFile->ReadMat3( pyramidBasis ); + saveFile->ReadVec3( body1Axis ); + saveFile->ReadFloat( cosAngle[0] ); + saveFile->ReadFloat( cosAngle[1] ); + saveFile->ReadFloat( sinHalfAngle[0] ); + saveFile->ReadFloat( sinHalfAngle[1] ); + saveFile->ReadFloat( cosHalfAngle[0] ); + saveFile->ReadFloat( cosHalfAngle[1] ); + saveFile->ReadFloat( epsilon ); +} + + +//=============================================================== +// +// idAFConstraint_Suspension +// +//=============================================================== + +/* +================ +idAFConstraint_Suspension::idAFConstraint_Suspension +================ +*/ +idAFConstraint_Suspension::idAFConstraint_Suspension( void ) { + type = CONSTRAINT_SUSPENSION; + name = "suspension"; + InitSize( 3 ); + fl.allowPrimary = false; + fl.frameConstraint = true; + + localOrigin.Zero(); + localAxis.Identity(); + suspensionUp = 0.0f; + suspensionDown = 0.0f; + suspensionKCompress = 0.0f; + suspensionDamping = 0.0f; + steerAngle = 0.0f; + friction = 2.0f; + motorEnabled = false; + motorForce = 0.0f; + motorVelocity = 0.0f; + wheelModel = NULL; + memset( &trace, 0, sizeof( trace ) ); + epsilon = LCP_EPSILON; +} + +/* +================ +idAFConstraint_Suspension::Setup +================ +*/ +void idAFConstraint_Suspension::Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel ) { + this->name = name; + body1 = body; + body2 = NULL; + localOrigin = ( origin - body->GetWorldOrigin() ) * body->GetWorldAxis().Transpose(); + localAxis = axis * body->GetWorldAxis().Transpose(); + wheelModel = clipModel; +} + +/* +================ +idAFConstraint_Suspension::SetSuspension +================ +*/ +void idAFConstraint_Suspension::SetSuspension( const float up, const float down, const float k, const float d, const float f ) { + suspensionUp = up; + suspensionDown = down; + suspensionKCompress = k; + suspensionDamping = d; + friction = f; +} + +/* +================ +idAFConstraint_Suspension::GetWheelOrigin +================ +*/ +const idVec3 idAFConstraint_Suspension::GetWheelOrigin( void ) const { + return body1->GetWorldOrigin() + wheelOffset * body1->GetWorldAxis(); +} + +/* +================ +idAFConstraint_Suspension::Evaluate +================ +*/ +void idAFConstraint_Suspension::Evaluate( float invTimeStep ) { + float velocity, suspensionLength, springLength, compression, dampingForce, springForce; + idVec3 origin, start, end, vel1, vel2, springDir, r, frictionDir, motorDir; + idMat3 axis; + idRotation rotation; + + axis = localAxis * body1->GetWorldAxis(); + origin = body1->GetWorldOrigin() + localOrigin * body1->GetWorldAxis(); + start = origin + suspensionUp * axis[2]; + end = origin - suspensionDown * axis[2]; + + rotation.SetVec( axis[2] ); + rotation.SetAngle( steerAngle ); + + axis *= rotation.ToMat3(); + + gameLocal.clip.Translation( trace, start, end, wheelModel, axis, MASK_SOLID, NULL ); + + wheelOffset = ( trace.endpos - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); + + if ( trace.fraction >= 1.0f ) { + J1.SetSize( 0, 6 ); + if ( body2 ) { + J2.SetSize( 0, 6 ); + } + return; + } + + // calculate and add spring force + vel1 = body1->GetPointVelocity( start ); + if ( body2 ) { + vel2 = body2->GetPointVelocity( trace.c.point ); + } else { + vel2.Zero(); + } + + suspensionLength = suspensionUp + suspensionDown; + springDir = trace.endpos - start; + springLength = trace.fraction * suspensionLength; + dampingForce = suspensionDamping * idMath::Fabs( ( vel2 - vel1 ) * springDir ) / ( 1.0f + springLength * springLength ); + compression = suspensionLength - springLength; + springForce = compression * compression * suspensionKCompress - dampingForce; + + r = trace.c.point - body1->GetWorldOrigin(); + J1.SetSize( 2, 6 ); + J1.SubVec6(0).SubVec3(0) = trace.c.normal; + J1.SubVec6(0).SubVec3(1) = r.Cross( trace.c.normal ); + c1.SetSize( 2 ); + c1[0] = 0.0f; + velocity = J1.SubVec6(0).SubVec3(0) * body1->GetLinearVelocity() + J1.SubVec6(0).SubVec3(1) * body1->GetAngularVelocity(); + + if ( body2 ) { + r = trace.c.point - body2->GetWorldOrigin(); + J2.SetSize( 2, 6 ); + J2.SubVec6(0).SubVec3(0) = -trace.c.normal; + J2.SubVec6(0).SubVec3(1) = r.Cross( -trace.c.normal ); + c2.SetSize( 2 ); + c2[0] = 0.0f; + velocity += J2.SubVec6(0).SubVec3(0) * body2->GetLinearVelocity() + J2.SubVec6(0).SubVec3(1) * body2->GetAngularVelocity(); + } + + c1[0] = -compression; // + 0.5f * -velocity; + + e[0] = 1e-4f; + lo[0] = 0.0f; + hi[0] = springForce; + boxConstraint = NULL; + boxIndex[0] = -1; + + // project the friction direction into the contact plane + frictionDir = axis[1] - axis[1] * trace.c.normal * axis[1]; + frictionDir.Normalize(); + + r = trace.c.point - body1->GetWorldOrigin(); + + J1.SubVec6(1).SubVec3(0) = frictionDir; + J1.SubVec6(1).SubVec3(1) = r.Cross( frictionDir ); + c1[1] = 0.0f; + + if ( body2 ) { + r = trace.c.point - body2->GetWorldOrigin(); + + J2.SubVec6(1).SubVec3(0) = -frictionDir; + J2.SubVec6(1).SubVec3(1) = r.Cross( -frictionDir ); + c2[1] = 0.0f; + } + + lo[1] = -friction * physics->GetContactFrictionScale(); + hi[1] = friction * physics->GetContactFrictionScale(); + + boxConstraint = this; + boxIndex[1] = 0; + + + if ( motorEnabled ) { + // project the motor force direction into the contact plane + motorDir = axis[0] - axis[0] * trace.c.normal * axis[0]; + motorDir.Normalize(); + + r = trace.c.point - body1->GetWorldOrigin(); + + J1.ChangeSize( 3, J1.GetNumColumns() ); + J1.SubVec6(2).SubVec3(0) = -motorDir; + J1.SubVec6(2).SubVec3(1) = r.Cross( -motorDir ); + c1.ChangeSize( 3 ); + c1[2] = motorVelocity; + + if ( body2 ) { + r = trace.c.point - body2->GetWorldOrigin(); + + J2.ChangeSize( 3, J2.GetNumColumns() ); + J2.SubVec6(2).SubVec3(0) = -motorDir; + J2.SubVec6(2).SubVec3(1) = r.Cross( -motorDir ); + c2.ChangeSize( 3 ); + c2[2] = 0.0f; + } + + lo[2] = -motorForce; + hi[2] = motorForce; + boxIndex[2] = -1; + } +} + +/* +================ +idAFConstraint_Suspension::ApplyFriction +================ +*/ +void idAFConstraint_Suspension::ApplyFriction( float invTimeStep ) { + // do nothing +} + +/* +================ +idAFConstraint_Suspension::Translate +================ +*/ +void idAFConstraint_Suspension::Translate( const idVec3 &translation ) { +} + +/* +================ +idAFConstraint_Suspension::Rotate +================ +*/ +void idAFConstraint_Suspension::Rotate( const idRotation &rotation ) { +} + +/* +================ +idAFConstraint_Suspension::DebugDraw +================ +*/ +void idAFConstraint_Suspension::DebugDraw( void ) { + idVec3 origin; + idMat3 axis; + idRotation rotation; + + axis = localAxis * body1->GetWorldAxis(); + + rotation.SetVec( axis[2] ); + rotation.SetAngle( steerAngle ); + + axis *= rotation.ToMat3(); + + if ( trace.fraction < 1.0f ) { + origin = trace.c.point; + + gameRenderWorld->DebugLine( colorWhite, origin, origin + 6.0f * axis[2] ); + gameRenderWorld->DebugLine( colorWhite, origin - 4.0f * axis[0], origin + 4.0f * axis[0] ); + gameRenderWorld->DebugLine( colorWhite, origin - 2.0f * axis[1], origin + 2.0f * axis[1] ); + } +} + + +//=============================================================== +// +// idAFBody +// +//=============================================================== + +/* +================ +idAFBody::idAFBody +================ +*/ +idAFBody::idAFBody( void ) { + Init(); +} + +/* +================ +idAFBody::idAFBody +================ +*/ +idAFBody::idAFBody( const idStr &name, idClipModel *clipModel, float density ) { + + assert( clipModel ); + assert( clipModel->IsTraceModel() ); + + Init(); + + this->name = name; + this->clipModel = NULL; + + SetClipModel( clipModel ); + SetDensity( density ); + + current->worldOrigin = clipModel->GetOrigin(); + current->worldAxis = clipModel->GetAxis(); + *next = *current; + +} + +/* +================ +idAFBody::~idAFBody +================ +*/ +idAFBody::~idAFBody( void ) { + delete clipModel; +} + +/* +================ +idAFBody::Init +================ +*/ +void idAFBody::Init( void ) { + name = "noname"; + parent = NULL; + clipModel = NULL; + primaryConstraint = NULL; + tree = NULL; + + linearFriction = -1.0f; + angularFriction = -1.0f; + contactFriction = -1.0f; + bouncyness = -1.0f; + clipMask = 0; + + frictionDir = vec3_zero; + contactMotorDir = vec3_zero; + contactMotorVelocity = 0.0f; + contactMotorForce = 0.0f; + + mass = 1.0f; + invMass = 1.0f; + centerOfMass = vec3_zero; + inertiaTensor = mat3_identity; + inverseInertiaTensor = mat3_identity; +#ifdef MOD_WATERPHYSICS + this->volume = 1.0f; + this->liquidMass = 1.0f; + this->invLiquidMass = 1.0f; + this->waterLevel = 0.0f; +#endif + + current = &state[0]; + next = &state[1]; + current->worldOrigin = vec3_zero; + current->worldAxis = mat3_identity; + current->spatialVelocity = vec6_zero; + current->externalForce = vec6_zero; + *next = *current; + saved = *current; + atRestOrigin = vec3_zero; + atRestAxis = mat3_identity; + + s.Zero( 6 ); + totalForce.Zero( 6 ); + auxForce.Zero( 6 ); + acceleration.Zero( 6 ); + + response = NULL; + responseIndex = NULL; + numResponses = 0; + maxAuxiliaryIndex = 0; + maxSubTreeAuxiliaryIndex = 0; + + memset( &fl, 0, sizeof( fl ) ); + + fl.selfCollision = true; + fl.isZero = true; + + m_RerouteEnt = NULL; +} + +/* +================ +idAFBody::SetClipModel +================ +*/ +void idAFBody::SetClipModel( idClipModel *clipModel ) { + if ( this->clipModel && this->clipModel != clipModel ) { + delete this->clipModel; + } + this->clipModel = clipModel; +} + +/* +================ +idAFBody::SetFriction +================ +*/ +void idAFBody::SetFriction( float linear, float angular, float contact ) { + if ( linear < 0.0f || linear > 1.0f || + angular < 0.0f || angular > 1.0f || + contact < 0.0f ) { + gameLocal.Warning( "idAFBody::SetFriction: friction out of range, linear = %.1f, angular = %.1f, contact = %.1f", linear, angular, contact ); + return; + } + linearFriction = linear; + angularFriction = angular; + contactFriction = contact; +} + +/* +================ +idAFBody::SetBouncyness +================ +*/ +void idAFBody::SetBouncyness( float bounce ) { + if ( bounce < 0.0f || bounce > 1.0f ) { + gameLocal.Warning( "idAFBody::SetBouncyness: bouncyness out of range, bounce = %.1f", bounce ); + return; + } + bouncyness = bounce; +} + +/* +================ +idAFBody::SetDensity +================ +*/ +void idAFBody::SetDensity( float density, const idMat3 &inertiaScale ) { + + // get the body mass properties + clipModel->GetMassProperties( density, mass, centerOfMass, inertiaTensor ); + + // make sure we have a valid mass + if ( mass <= 0.0f || FLOAT_IS_NAN( mass ) ) { + gameLocal.Warning( "idAFBody::SetDensity: invalid mass for body '%s'", name.c_str() ); + mass = 1.0f; + centerOfMass.Zero(); + inertiaTensor.Identity(); + } + + // make sure the center of mass is at the body origin + if ( !centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) { + gameLocal.Warning( "idAFBody::SetDensity: center of mass (%f, %f, %f) not at origin (%f, %f, %f) for body '%s'", + vec3_origin.x, vec3_origin.y, vec3_origin.z, + centerOfMass.x, centerOfMass.y, centerOfMass.z, name.c_str() ); + } + centerOfMass.Zero(); + + // calculate the inverse mass and inverse inertia tensor + invMass = 1.0f / mass; + if ( inertiaScale != mat3_identity ) { + inertiaTensor *= inertiaScale; + } + if ( inertiaTensor.IsDiagonal( 1e-3f ) ) { + inertiaTensor[0][1] = inertiaTensor[0][2] = 0.0f; + inertiaTensor[1][0] = inertiaTensor[1][2] = 0.0f; + inertiaTensor[2][0] = inertiaTensor[2][1] = 0.0f; + inverseInertiaTensor.Identity(); + inverseInertiaTensor[0][0] = 1.0f / inertiaTensor[0][0]; + inverseInertiaTensor[1][1] = 1.0f / inertiaTensor[1][1]; + inverseInertiaTensor[2][2] = 1.0f / inertiaTensor[2][2]; + } + else { + inverseInertiaTensor = inertiaTensor.Inverse(); + } +#ifdef MOD_WATERPHYSICS + this->volume = mass / density; + this->liquidMass = this->mass; + this->invLiquidMass = this->invMass; +#endif +} + +/* +================ +idAFBody::SetFrictionDirection +================ +*/ +void idAFBody::SetFrictionDirection( const idVec3 &dir ) { + frictionDir = dir * current->worldAxis.Transpose(); + fl.useFrictionDir = true; +} + +/* +================ +idAFBody::GetFrictionDirection +================ +*/ +bool idAFBody::GetFrictionDirection( idVec3 &dir ) const { + if ( fl.useFrictionDir ) { + dir = frictionDir * current->worldAxis; + return true; + } + return false; +} + +/* +================ +idAFBody::SetContactMotorDirection +================ +*/ +void idAFBody::SetContactMotorDirection( const idVec3 &dir ) { + contactMotorDir = dir * current->worldAxis.Transpose(); + fl.useContactMotorDir = true; +} + +/* +================ +idAFBody::GetContactMotorDirection +================ +*/ +bool idAFBody::GetContactMotorDirection( idVec3 &dir ) const { + if ( fl.useContactMotorDir ) { + dir = contactMotorDir * current->worldAxis; + return true; + } + return false; +} + +/* +================ +idAFBody::GetPointVelocity +================ +*/ +idVec3 idAFBody::GetPointVelocity( const idVec3 &point ) const { + idVec3 r = point - current->worldOrigin; + return current->spatialVelocity.SubVec3(0) + current->spatialVelocity.SubVec3(1).Cross( r ); +} + +/* +================ +idAFBody::AddForce +================ +*/ +void idAFBody::AddForce( const idVec3 &point, const idVec3 &force ) { + current->externalForce.SubVec3(0) += force; + current->externalForce.SubVec3(1) += (point - current->worldOrigin).Cross( force ); +} + +/* +================ +idAFBody::InverseWorldSpatialInertiaMultiply + + dst = this->inverseWorldSpatialInertia * v; +================ +*/ +ID_INLINE void idAFBody::InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const { + const float *mPtr = inverseWorldSpatialInertia.ToFloatPtr(); + const float *vPtr = v; + float *dstPtr = dst.ToFloatPtr(); + + if ( fl.spatialInertiaSparse ) { + dstPtr[0] = mPtr[0*6+0] * vPtr[0]; + dstPtr[1] = mPtr[1*6+1] * vPtr[1]; + dstPtr[2] = mPtr[2*6+2] * vPtr[2]; + dstPtr[3] = mPtr[3*6+3] * vPtr[3] + mPtr[3*6+4] * vPtr[4] + mPtr[3*6+5] * vPtr[5]; + dstPtr[4] = mPtr[4*6+3] * vPtr[3] + mPtr[4*6+4] * vPtr[4] + mPtr[4*6+5] * vPtr[5]; + dstPtr[5] = mPtr[5*6+3] * vPtr[3] + mPtr[5*6+4] * vPtr[4] + mPtr[5*6+5] * vPtr[5]; + } else { + gameLocal.Warning( "spatial inertia is not sparse for body %s", name.c_str() ); + } +} + +/* +================ +idAFBody::Save +================ +*/ +void idAFBody::Save( idSaveGame *saveFile ) { + saveFile->WriteFloat( linearFriction ); + saveFile->WriteFloat( angularFriction ); + saveFile->WriteFloat( contactFriction ); + saveFile->WriteFloat( bouncyness ); + saveFile->WriteInt( clipMask ); + saveFile->WriteVec3( frictionDir ); + saveFile->WriteVec3( contactMotorDir ); + saveFile->WriteFloat( contactMotorVelocity ); + saveFile->WriteFloat( contactMotorForce ); + +#ifdef MOD_WATERPHYSICS + saveFile->WriteFloat( volume ); + saveFile->WriteFloat( liquidMass ); + saveFile->WriteFloat( invLiquidMass ); +#endif + saveFile->WriteFloat( mass ); + saveFile->WriteFloat( invMass ); + saveFile->WriteVec3( centerOfMass ); + saveFile->WriteMat3( inertiaTensor ); + saveFile->WriteMat3( inverseInertiaTensor ); + + saveFile->WriteVec3( current->worldOrigin ); + saveFile->WriteMat3( current->worldAxis ); + saveFile->WriteVec6( current->spatialVelocity ); + saveFile->WriteVec6( current->externalForce ); + saveFile->WriteVec3( atRestOrigin ); + saveFile->WriteMat3( atRestAxis ); + m_RerouteEnt.Save( saveFile ); +} + +/* +================ +idAFBody::Restore +================ +*/ +void idAFBody::Restore( idRestoreGame *saveFile ) { + saveFile->ReadFloat( linearFriction ); + saveFile->ReadFloat( angularFriction ); + saveFile->ReadFloat( contactFriction ); + saveFile->ReadFloat( bouncyness ); + saveFile->ReadInt( clipMask ); + saveFile->ReadVec3( frictionDir ); + saveFile->ReadVec3( contactMotorDir ); + saveFile->ReadFloat( contactMotorVelocity ); + saveFile->ReadFloat( contactMotorForce ); + +#ifdef MOD_WATERPHYSICS + saveFile->ReadFloat( volume ); + saveFile->ReadFloat( liquidMass ); + saveFile->ReadFloat( invLiquidMass ); +#endif + + saveFile->ReadFloat( mass ); + saveFile->ReadFloat( invMass ); + saveFile->ReadVec3( centerOfMass ); + saveFile->ReadMat3( inertiaTensor ); + saveFile->ReadMat3( inverseInertiaTensor ); + + saveFile->ReadVec3( current->worldOrigin ); + saveFile->ReadMat3( current->worldAxis ); + saveFile->ReadVec6( current->spatialVelocity ); + saveFile->ReadVec6( current->externalForce ); + saveFile->ReadVec3( atRestOrigin ); + saveFile->ReadMat3( atRestAxis ); + m_RerouteEnt.Restore( saveFile ); +} + +idEntity *idAFBody::GetRerouteEnt( void ) +{ + return m_RerouteEnt.GetEntity(); +} + +void idAFBody::SetRerouteEnt( idEntity *ent ) +{ + m_RerouteEnt = ent; +} + +#ifdef MOD_WATERPHYSICS +/* +================ +idAFBody::GetWaterLevel + returns the percent of the body in water (set by SetWaterLevel) +================ +*/ +float idAFBody::GetWaterLevel() const { + return this->waterLevel; +} + +/* +================ +idAFBody::SetWaterLevel + returns the percent of the body in water + 0.0f if out of water + + Note we use the liquid's gravity normal for + floating because the idPhysics_AF gravity normal + is really hard to get a hold of! +================ +*/ +float idAFBody::SetWaterLevel( idPhysics_Liquid *l, const idVec3 &gravityNormal, bool fixedDensityBuoyancy ) { + if( l == NULL ) { + this->waterLevel = 0.0f; + this->m_fWaterMurkiness = 0.0f; + return 0.0f; + } + + if( !fixedDensityBuoyancy ) { + const idBounds &bounds = this->clipModel->GetBounds(); + idVec3 depth,point; + float height, d; + + // + // check if physics object is under water + // and return the percentage of the object under water + // + point = this->GetWorldOrigin(); + + depth = l->GetDepth(point); + // height = abs( (bounds[0] - bounds[1]) * gravityNormal ) * 0.5f; + // d = abs( depth * gravityNormal ); + height = fabs( bounds[0].z - bounds[1].z ) * 0.5f; + d = depth.z; + + if( d < 0 ) + this->waterLevel = 0.0f; + else if( d > height ) + this->waterLevel = 1.0f; + else + this->waterLevel = d / height; + } + else { + idVec3 depth,bottom(this->current->worldOrigin); + idBounds bounds = this->clipModel->GetBounds(); + float height,d; + + // offset and rotate the bounding box + bounds += -centerOfMass; + bounds *= this->current->worldAxis.Transpose(); + + // gets the position of the object relative to the surface of the water + height = fabs(bounds[1] * gravityNormal * 2); + + // calculates the depth of the bottom of the object + bottom += (height * 0.5f) * gravityNormal; + depth = l->GetDepth(bottom); + d = fabs(depth * gravityNormal); + + if( d > height ) { + // the body is totally submerged + this->waterLevel = 1.0f; + } + else if( depth.x == -1 && depth.y == -1 && depth.z == -1 ) { + this->waterLevel = 0.0f; + } + else { + // the body is partly submerged + this->waterLevel = d / height; + } + } + return this->waterLevel; +} + +#endif + +//=============================================================== +// M +// idAFTree MrE +// E +//=============================================================== + +/* +================ +idAFTree::Factor + + factor matrix for the primary constraints in the tree +================ +*/ +void idAFTree::Factor( void ) const { + int i, j; + idAFBody *body; + idAFConstraint *child(NULL); + idMatX childI; + + childI.SetData( 6, 6, MATX_ALLOCA( 6 * 6 ) ); + + // from the leaves up towards the root + for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { + body = sortedBodies[i]; + + if ( body->children.Num() ) { + + for ( j = 0; j < body->children.Num(); j++ ) { + + child = body->children[j]->primaryConstraint; + + // child->I = - child->body1->J.Transpose() * child->body1->I * child->body1->J; + childI.SetSize( child->J1.GetNumRows(), child->J1.GetNumRows() ); + child->body1->J.TransposeMultiply( child->body1->I ).Multiply( childI, child->body1->J ); + childI.Negate(); + + child->invI = childI; + if ( !child->invI.InverseFastSelf() ) { + gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for constraint '%s'", + child->invI.GetNumRows(), child->invI.GetNumColumns(), child->GetName().c_str() ); + } + child->J = child->invI * child->J; + + body->I -= child->J.TransposeMultiply( childI ) * child->J; + } + + body->invI = body->I; + if ( !body->invI.InverseFastSelf() ) { + gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for body %s", + child->invI.GetNumRows(), child->invI.GetNumColumns(), body->GetName().c_str() ); + } + if ( body->primaryConstraint ) { + body->J = body->invI * body->J; + } + } + else if ( body->primaryConstraint ) { + body->J = body->inverseWorldSpatialInertia * body->J; + } + } +} + +/* +================ +idAFTree::Solve + + solve for primary constraints in the tree +================ +*/ +void idAFTree::Solve( int auxiliaryIndex ) const { + int i, j; + idAFBody *body, *child; + idAFConstraint *primaryConstraint; + + // from the leaves up towards the root + for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { + body = sortedBodies[i]; + + for ( j = 0; j < body->children.Num(); j++ ) { + child = body->children[j]; + primaryConstraint = child->primaryConstraint; + + if ( !child->fl.isZero ) { + child->J.TransposeMultiplySub( primaryConstraint->s, child->s ); + primaryConstraint->fl.isZero = false; + } + if ( !primaryConstraint->fl.isZero ) { + primaryConstraint->J.TransposeMultiplySub( body->s, primaryConstraint->s ); + body->fl.isZero = false; + } + } + } + + bool useSymmetry = af_useSymmetry.GetBool(); + + // from the root down towards the leaves + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + primaryConstraint = body->primaryConstraint; + + if ( primaryConstraint ) { + + if ( useSymmetry && body->parent->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) { + continue; + } + + if ( !primaryConstraint->fl.isZero ) { + primaryConstraint->s = primaryConstraint->invI * primaryConstraint->s; + } + primaryConstraint->J.MultiplySub( primaryConstraint->s, primaryConstraint->body2->s ); + + primaryConstraint->lm = primaryConstraint->s; + + if ( useSymmetry && body->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) { + continue; + } + + if ( body->children.Num() ) { + if ( !body->fl.isZero ) { + body->s = body->invI * body->s; + } + body->J.MultiplySub( body->s, primaryConstraint->s ); + } + } else if ( body->children.Num() ) { + body->s = body->invI * body->s; + } + } +} + +/* +================ +idAFTree::Response + + calculate body forces in the tree in response to a constraint force +================ +*/ +void idAFTree::Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const { + int i, j; + idAFBody *body; + idAFConstraint *child, *primaryConstraint; + idVecX v; + + // if a single body don't waste time because there aren't any primary constraints + if ( sortedBodies.Num() == 1 ) { + body = constraint->body1; + if ( body->tree == this ) { + body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row ); + body->responseIndex[body->numResponses++] = auxiliaryIndex; + } + else { + body = constraint->body2; + body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row ); + body->responseIndex[body->numResponses++] = auxiliaryIndex; + } + return; + } + + v.SetData( 6, VECX_ALLOCA( 6 ) ); + + // initialize right hand side to zero + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + primaryConstraint->s.Zero(); + primaryConstraint->fl.isZero = true; + } + body->s.Zero(); + body->fl.isZero = true; + body->GetResponseForce( body->numResponses ).Zero(); + } + + // set right hand side for first constrained body + body = constraint->body1; + if ( body->tree == this ) { + body->InverseWorldSpatialInertiaMultiply( v, constraint->J1[row] ); + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + primaryConstraint->J1.Multiply( primaryConstraint->s, v ); + primaryConstraint->fl.isZero = false; + } + for ( i = 0; i < body->children.Num(); i++ ) { + child = body->children[i]->primaryConstraint; + child->J2.Multiply( child->s, v ); + child->fl.isZero = false; + } + body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row ); + } + + // set right hand side for second constrained body + body = constraint->body2; + if ( body && body->tree == this ) { + body->InverseWorldSpatialInertiaMultiply( v, constraint->J2[row] ); + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + primaryConstraint->J1.MultiplyAdd( primaryConstraint->s, v ); + primaryConstraint->fl.isZero = false; + } + for ( i = 0; i < body->children.Num(); i++ ) { + child = body->children[i]->primaryConstraint; + child->J2.MultiplyAdd( child->s, v ); + child->fl.isZero = false; + } + body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row ); + } + + + // solve for primary constraints + Solve( auxiliaryIndex ); + + bool useSymmetry = af_useSymmetry.GetBool(); + + // store body forces in response to the constraint force + idVecX force; + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + + if ( useSymmetry && body->maxAuxiliaryIndex < auxiliaryIndex ) { + continue; + } + + force.SetData( 6, body->response + body->numResponses * 8 ); + + // add forces of all primary constraints acting on this body + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + primaryConstraint->J1.TransposeMultiplyAdd( force, primaryConstraint->lm ); + } + for ( j = 0; j < body->children.Num(); j++ ) { + child = body->children[j]->primaryConstraint; + child->J2.TransposeMultiplyAdd( force, child->lm ); + } + + body->responseIndex[body->numResponses++] = auxiliaryIndex; + } +} + +/* +================ +idAFTree::CalculateForces + + calculate forces on the bodies in the tree +================ +*/ +void idAFTree::CalculateForces( float timeStep ) const { + int i, j; + float invStep; + idAFBody *body; + idAFConstraint *child, *c, *primaryConstraint; + + // forces on bodies + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + + body->totalForce.SubVec6(0) = body->current->externalForce + body->auxForce.SubVec6(0); + } + + // if a single body don't waste time because there aren't any primary constraints + if ( sortedBodies.Num() == 1 ) { + return; + } + + invStep = 1.0f / timeStep; + + // initialize right hand side + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + + body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); + body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep; + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + // b = ( J * acc + c ) + c = primaryConstraint; + c->s = c->J1 * c->body1->acceleration + c->J2 * c->body2->acceleration + invStep * ( c->c1 + c->c2 ); + c->fl.isZero = false; + } + body->s.Zero(); + body->fl.isZero = true; + } + + // solve for primary constraints + Solve(); + + // calculate forces on bodies after applying primary constraints + for ( i = 0; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + + // add forces of all primary constraints acting on this body + primaryConstraint = body->primaryConstraint; + if ( primaryConstraint ) { + primaryConstraint->J1.TransposeMultiplyAdd( body->totalForce, primaryConstraint->lm ); + } + for ( j = 0; j < body->children.Num(); j++ ) { + child = body->children[j]->primaryConstraint; + child->J2.TransposeMultiplyAdd( body->totalForce, child->lm ); + } + } +} + +/* +================ +idAFTree::SetMaxSubTreeAuxiliaryIndex +================ +*/ +void idAFTree::SetMaxSubTreeAuxiliaryIndex( void ) { + int i, j; + idAFBody *body, *child; + + // from the leaves up towards the root + for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { + body = sortedBodies[i]; + + body->maxSubTreeAuxiliaryIndex = body->maxAuxiliaryIndex; + for ( j = 0; j < body->children.Num(); j++ ) { + child = body->children[j]; + if ( child->maxSubTreeAuxiliaryIndex > body->maxSubTreeAuxiliaryIndex ) { + body->maxSubTreeAuxiliaryIndex = child->maxSubTreeAuxiliaryIndex; + } + } + } +} + +/* +================ +idAFTree::SortBodies_r +================ +*/ +void idAFTree::SortBodies_r( idList&sortedList, idAFBody *body ) { + int i; + + for ( i = 0; i < body->children.Num(); i++ ) { + sortedList.Append( body->children[i] ); + } + for ( i = 0; i < body->children.Num(); i++ ) { + SortBodies_r( sortedList, body->children[i] ); + } +} + +/* +================ +idAFTree::SortBodies + + sort body list to make sure parents come first +================ +*/ +void idAFTree::SortBodies( void ) { + int i; + idAFBody *body; + + // find the root + for ( i = 0; i < sortedBodies.Num(); i++ ) { + if ( !sortedBodies[i]->parent ) { + break; + } + } + + if ( i >= sortedBodies.Num() ) { + gameLocal.Error( "Articulated figure tree has no root." ); + } + + body = sortedBodies[i]; + sortedBodies.Clear(); + sortedBodies.Append( body ); + SortBodies_r( sortedBodies, body ); +} + +/* +================ +idAFTree::DebugDraw +================ +*/ +void idAFTree::DebugDraw( const idVec4 &color ) const { + int i; + idAFBody *body; + + for ( i = 1; i < sortedBodies.Num(); i++ ) { + body = sortedBodies[i]; + gameRenderWorld->DebugArrow( color, body->parent->current->worldOrigin, body->current->worldOrigin, 1 ); + } +} + + +//=============================================================== +// M +// idPhysics_AF MrE +// E +//=============================================================== + +/* +================ +idPhysics_AF::EvaluateConstraints +================ +*/ +void idPhysics_AF::EvaluateConstraints( float timeStep ) { + int i; + float invTimeStep; + idAFBody *body; + idAFConstraint *c; + + invTimeStep = 1.0f / timeStep; + + // setup the constraint equations for the current position and orientation of the bodies + for ( i = 0; i < primaryConstraints.Num(); i++ ) { + c = primaryConstraints[i]; + c->Evaluate( invTimeStep ); + c->J = c->J2; + } + for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { + auxiliaryConstraints[i]->Evaluate( invTimeStep ); + } + + // add contact constraints to the list with frame constraints + for ( i = 0; i < contactConstraints.Num(); i++ ) { + AddFrameConstraint( contactConstraints[i] ); + } + + // setup body primary constraint matrix + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->primaryConstraint ) { + body->J = body->primaryConstraint->J1.Transpose(); + } + } +} + +/* +================ +idPhysics_AF::EvaluateBodies +================ +*/ +void idPhysics_AF::EvaluateBodies( float timeStep ) { + int i; + idAFBody *body; +#ifdef MOD_WATERPHYSICS + float bMass, invbMass; +#endif + idMat3 axis; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; +#ifdef MOD_WATERPHYSICS + if( this->water != NULL && body->GetWaterLevel() > 0.0f ) { + bMass = body->liquidMass; + invbMass = body->invLiquidMass; + } + else { + bMass = body->mass; + invbMass = body->invMass; + } +#endif + // we transpose the axis before using it because idMat3 is column-major + axis = body->current->worldAxis.Transpose(); + + // if the center of mass is at the body point of reference + if ( body->centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) { + + // spatial inertia in world space +#ifdef MOD_WATERPHYSICS + body->I.Set( bMass * mat3_identity, mat3_zero, + mat3_zero, axis * body->inertiaTensor * axis.Transpose() ); + body->inverseWorldSpatialInertia.Set( invbMass * mat3_identity, mat3_zero, +#else + body->I.Set( body->mass * mat3_identity, mat3_zero, + mat3_zero, axis * body->inertiaTensor * axis.Transpose() ); + // inverse spatial inertia in world space + body->inverseWorldSpatialInertia.Set( body->invMass * mat3_identity, mat3_zero, +#endif + mat3_zero, axis * body->inverseInertiaTensor * axis.Transpose() ); + + body->fl.spatialInertiaSparse = true; + } + else { +#ifdef MOD_WATERPHYSICS + idMat3 massMoment =bMass * SkewSymmetric( body->centerOfMass ); + body->I.Set( bMass * mat3_identity, massMoment, +#else + idMat3 massMoment = body->mass * SkewSymmetric( body->centerOfMass ); + // spatial inertia in world space + body->I.Set( body->mass * mat3_identity, massMoment, +#endif + massMoment.Transpose(), axis * body->inertiaTensor * axis.Transpose() ); + + // inverse spatial inertia in world space + body->inverseWorldSpatialInertia = body->I.InverseFast(); + + body->fl.spatialInertiaSparse = false; + } + + // initialize auxiliary constraint force to zero + body->auxForce.Zero(); + } +} + +/* +================ +idPhysics_AF::AddFrameConstraints +================ +*/ +void idPhysics_AF::AddFrameConstraints( void ) { + int i; + + // add frame constraints to auxiliary constraints + for ( i = 0; i < frameConstraints.Num(); i++ ) { + auxiliaryConstraints.Append( frameConstraints[i] ); + } +} + +/* +================ +idPhysics_AF::RemoveFrameConstraints +================ +*/ +void idPhysics_AF::RemoveFrameConstraints( void ) { + // remove all the frame constraints from the auxiliary constraints + auxiliaryConstraints.SetNum( auxiliaryConstraints.Num() - frameConstraints.Num(), false ); + frameConstraints.SetNum( 0, false ); +} + +/* +================ +idPhysics_AF::ApplyFriction +================ +*/ +void idPhysics_AF::ApplyFriction( float timeStep, float endTimeMSec ) { + int i; + float invTimeStep; + + if ( af_skipFriction.GetBool() ) { + return; + } + + if ( jointFrictionDentStart < MS2SEC( endTimeMSec ) && jointFrictionDentEnd > MS2SEC( endTimeMSec ) ) { + float halfTime = ( jointFrictionDentEnd - jointFrictionDentStart ) * 0.5f; + if ( jointFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) { + jointFrictionDentScale = 1.0f - ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart ) / halfTime; + } else { + jointFrictionDentScale = jointFrictionDent + ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart - halfTime ) / halfTime; + } + } else { + jointFrictionDentScale = 0.0f; + } + + if ( contactFrictionDentStart < MS2SEC( endTimeMSec ) && contactFrictionDentEnd > MS2SEC( endTimeMSec ) ) { + float halfTime = ( contactFrictionDentEnd - contactFrictionDentStart ) * 0.5f; + if ( contactFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) { + contactFrictionDentScale = 1.0f - ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart ) / halfTime; + } else { + contactFrictionDentScale = contactFrictionDent + ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart - halfTime ) / halfTime; + } + } else { + contactFrictionDentScale = 0.0f; + } + + invTimeStep = 1.0f / timeStep; + + for ( i = 0; i < primaryConstraints.Num(); i++ ) { + primaryConstraints[i]->ApplyFriction( invTimeStep ); + } + for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { + auxiliaryConstraints[i]->ApplyFriction( invTimeStep ); + } + for ( i = 0; i < frameConstraints.Num(); i++ ) { + frameConstraints[i]->ApplyFriction( invTimeStep ); + } +} + +/* +================ +idPhysics_AF::PrimaryFactor +================ +*/ +void idPhysics_AF::PrimaryFactor( void ) { + int i; + + for ( i = 0; i < trees.Num(); i++ ) { + trees[i]->Factor(); + } +} + +/* +================ +idPhysics_AF::PrimaryForces +================ +*/ +void idPhysics_AF::PrimaryForces( float timeStep ) { + int i; + + for ( i = 0; i < trees.Num(); i++ ) { + trees[i]->CalculateForces( timeStep ); + } +} + +/* +================ +idPhysics_AF::AuxiliaryForces +================ +*/ +void idPhysics_AF::AuxiliaryForces( float timeStep ) { + int i, j, k, l, n, m, s, numAuxConstraints, *index, *boxIndex; + float *ptr, *j1, *j2, *dstPtr, *forcePtr; + float invStep, u; + idAFBody *body; + idAFConstraint *constraint; + idVecX tmp; + idMatX jmk; + idVecX rhs, w, lm, lo, hi; + + // get the number of one dimensional auxiliary constraints + for ( numAuxConstraints = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + numAuxConstraints += auxiliaryConstraints[i]->J1.GetNumRows(); + } + + if ( numAuxConstraints == 0 ) { + return; + } + + // allocate memory to store the body response to auxiliary constraint forces + forcePtr = (float *) _alloca16( bodies.Num() * numAuxConstraints * 8 * sizeof( float ) ); + index = (int *) _alloca16( bodies.Num() * numAuxConstraints * sizeof( int ) ); + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->response = forcePtr; + body->responseIndex = index; + body->numResponses = 0; + body->maxAuxiliaryIndex = 0; + forcePtr += numAuxConstraints * 8; + index += numAuxConstraints; + } + + // set on each body the largest index of an auxiliary constraint constraining the body + if ( af_useSymmetry.GetBool() ) { + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { + if ( k > constraint->body1->maxAuxiliaryIndex ) { + constraint->body1->maxAuxiliaryIndex = k; + } + if ( constraint->body2 && k > constraint->body2->maxAuxiliaryIndex ) { + constraint->body2->maxAuxiliaryIndex = k; + } + } + } + for ( i = 0; i < trees.Num(); i++ ) { + trees[i]->SetMaxSubTreeAuxiliaryIndex(); + } + } + + // calculate forces of primary constraints in response to the auxiliary constraint forces + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + + for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { + + // calculate body forces in the tree in response to the constraint force + constraint->body1->tree->Response( constraint, j, k ); + // if there is a second body which is part of a different tree + if ( constraint->body2 && constraint->body2->tree != constraint->body1->tree ) { + // calculate body forces in the second tree in response to the constraint force + constraint->body2->tree->Response( constraint, j, k ); + } + } + } + + // NOTE: the rows are 16 byte padded + jmk.SetData( numAuxConstraints, ((numAuxConstraints+3)&~3), MATX_ALLOCA( numAuxConstraints * ((numAuxConstraints+3)&~3) ) ); + tmp.SetData( 6, VECX_ALLOCA( 6 ) ); + + // create constraint matrix for auxiliary constraints using a mass matrix adjusted for the primary constraints + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + + for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { + constraint->body1->InverseWorldSpatialInertiaMultiply( tmp, constraint->J1[j] ); + j1 = tmp.ToFloatPtr(); + ptr = constraint->body1->response; + index = constraint->body1->responseIndex; + dstPtr = jmk[k]; + s = af_useSymmetry.GetBool() ? k + 1 : numAuxConstraints; + for ( l = n = 0, m = index[n]; n < constraint->body1->numResponses && m < s; n++, m = index[n] ) { + while( l < m ) { + dstPtr[l++] = 0.0f; + } + dstPtr[l++] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] + + j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5]; + ptr += 8; + } + + while( l < s ) { + dstPtr[l++] = 0.0f; + } + + if ( constraint->body2 ) { + constraint->body2->InverseWorldSpatialInertiaMultiply( tmp, constraint->J2[j] ); + j2 = tmp.ToFloatPtr(); + ptr = constraint->body2->response; + index = constraint->body2->responseIndex; + for ( n = 0, m = index[n]; n < constraint->body2->numResponses && m < s; n++, m = index[n] ) { + dstPtr[m] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] + + j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5]; + ptr += 8; + } + } + } + } + + if ( af_useSymmetry.GetBool() ) { + n = jmk.GetNumColumns(); + for ( i = 0; i < numAuxConstraints; i++ ) { + ptr = jmk.ToFloatPtr() + ( i + 1 ) * n + i; + dstPtr = jmk.ToFloatPtr() + i * n + i + 1; + for ( j = i+1; j < numAuxConstraints; j++ ) { + *dstPtr++ = *ptr; + ptr += n; + } + } + } + + invStep = 1.0f / timeStep; + + // calculate body acceleration + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); + body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep; + } + + rhs.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); + lo.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); + hi.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); + lm.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); + boxIndex = (int *) _alloca16( numAuxConstraints * sizeof( int ) ); + + // set first index for special box constrained variables + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + auxiliaryConstraints[i]->firstIndex = k; + k += auxiliaryConstraints[i]->J1.GetNumRows(); + } + + // initialize right hand side and low and high bounds for auxiliary constraints + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + n = k; + + for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { + + j1 = constraint->J1[j]; + ptr = constraint->body1->acceleration.ToFloatPtr(); + rhs[k] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] + j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5]; + rhs[k] += constraint->c1[j] * invStep; + + if ( constraint->body2 ) { + j2 = constraint->J2[j]; + ptr = constraint->body2->acceleration.ToFloatPtr(); + rhs[k] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] + j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5]; + rhs[k] += constraint->c2[j] * invStep; + } + + rhs[k] = -rhs[k]; + lo[k] = constraint->lo[j]; + hi[k] = constraint->hi[j]; + + if ( constraint->boxIndex[j] >= 0 ) { + if ( constraint->boxConstraint->fl.isPrimary ) { + gameLocal.Error( "cannot reference primary constraints for the box index" ); + } + boxIndex[k] = constraint->boxConstraint->firstIndex + constraint->boxIndex[j]; + } + else { + boxIndex[k] = -1; + } + jmk[k][k] += constraint->e[j] * invStep; + } + } + +#ifdef AF_TIMINGS + timer_lcp.Start(); +#endif + + // calculate lagrange multipliers for auxiliary constraints + if ( !lcp->Solve( jmk, lm, rhs, lo, hi, boxIndex ) ) { + return; // bad monkey! + } + +#ifdef AF_TIMINGS + timer_lcp.Stop(); +#endif + + // calculate auxiliary constraint forces + for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + + for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { + constraint->lm[j] = u = lm[k]; + + j1 = constraint->J1[j]; + ptr = constraint->body1->auxForce.ToFloatPtr(); + ptr[0] += j1[0] * u; ptr[1] += j1[1] * u; ptr[2] += j1[2] * u; + ptr[3] += j1[3] * u; ptr[4] += j1[4] * u; ptr[5] += j1[5] * u; + + if ( constraint->body2 ) { + j2 = constraint->J2[j]; + ptr = constraint->body2->auxForce.ToFloatPtr(); + ptr[0] += j2[0] * u; ptr[1] += j2[1] * u; ptr[2] += j2[2] * u; + ptr[3] += j2[3] * u; ptr[4] += j2[4] * u; ptr[5] += j2[5] * u; + } + } + } + + // recalculate primary constraint forces in response to auxiliary constraint forces + PrimaryForces( timeStep ); + + // clear pointers pointing to stack space so tools don't get confused + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->response = NULL; + body->responseIndex = NULL; + } +} + +/* +================ +idPhysics_AF::VerifyContactConstraints +================ +*/ +void idPhysics_AF::VerifyContactConstraints( void ) { +#if 0 + int i; + float impulseNumerator, impulseDenominator; + idVec3 r, velocity, normalVelocity, normal, impulse; + idAFBody *body; + + for ( i = 0; i < contactConstraints.Num(); i++ ) { + body = contactConstraints[i]->body1; + const contactInfo_t &contact = contactConstraints[i]->GetContact(); + + r = contact.point - body->GetCenterOfMass(); + + // calculate velocity at contact point + velocity = body->GetLinearVelocity() + body->GetAngularVelocity().Cross( r ); + + // velocity along normal vector + normalVelocity = ( velocity * contact.normal ) * contact.normal; + + // if moving towards the surface at the contact point + if ( normalVelocity * contact.normal < 0.0f ) { + // calculate impulse + normal = -normalVelocity; + impulseNumerator = normal.Normalize(); + impulseDenominator = body->GetInverseMass() + ( ( body->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal ); + impulse = (impulseNumerator / impulseDenominator) * normal * 1.0001f; + + // apply impulse + body->SetLinearVelocity( body->GetLinearVelocity() + impulse ); + body->SetAngularVelocity( body->GetAngularVelocity() + r.Cross( impulse ) ); + } + } +#else + int i; + idAFBody *body; + idVec3 normal; + + for ( i = 0; i < contactConstraints.Num(); i++ ) { + body = contactConstraints[i]->body1; + normal = contactConstraints[i]->GetContact().normal; + if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) { + body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal; + } + body = contactConstraints[i]->body2; + if ( !body ) { + continue; + } + normal = -normal; + if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) { + body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal; + } + } +#endif +} + +/* +================ +idPhysics_AF::Evolve +================ +*/ +void idPhysics_AF::Evolve( float timeStep ) { + int i; + float angle; +#ifdef MOD_WATERPHYSICS + float waterLevel; +#endif + idVec3 vec; + idAFBody *body; + idVec6 force; + idRotation rotation; + float vSqr, maxLinearVelocity, maxAngularVelocity; + + maxLinearVelocity = af_maxLinearVelocity.GetFloat() / timeStep; + maxAngularVelocity = af_maxAngularVelocity.GetFloat() / timeStep; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + // calculate the spatial velocity for the next physics state + body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); + body->next->spatialVelocity = body->current->spatialVelocity + timeStep * body->acceleration.SubVec6(0); + + if ( maxLinearVelocity > 0.0f ) { + // cap the linear velocity + vSqr = body->next->spatialVelocity.SubVec3(0).LengthSqr(); + if ( vSqr > Square( maxLinearVelocity ) ) { + body->next->spatialVelocity.SubVec3(0) *= idMath::InvSqrt( vSqr ) * maxLinearVelocity; + } + } + + if ( maxAngularVelocity > 0.0f ) { + // cap the angular velocity + vSqr = body->next->spatialVelocity.SubVec3(1).LengthSqr(); + if ( vSqr > Square( maxAngularVelocity ) ) { + body->next->spatialVelocity.SubVec3(1) *= idMath::InvSqrt( vSqr ) * maxAngularVelocity; + } + } + } + + // make absolutely sure all contact constraints are satisfied + VerifyContactConstraints(); + + // calculate the position of the bodies for the next physics state + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + // translate world origin + body->next->worldOrigin = body->current->worldOrigin + timeStep * body->next->spatialVelocity.SubVec3( 0 ); + + // convert angular velocity to a rotation matrix + vec = body->next->spatialVelocity.SubVec3( 1 ); + angle = -timeStep * (float) RAD2DEG( vec.Normalize() ); + rotation = idRotation( vec3_origin, vec, angle ); + rotation.Normalize180(); + + // rotate world axis + body->next->worldAxis = body->current->worldAxis * rotation.ToMat3(); + body->next->worldAxis.OrthoNormalizeSelf(); + + // linear and angular friction +#ifdef MOD_WATERPHYSICS + // apply a higher friction value if the AF is underwater + waterLevel = body->GetWaterLevel(); + if( waterLevel == 0.0f || this->water == NULL ) { + body->next->spatialVelocity.SubVec3(0) -= body->linearFriction * body->next->spatialVelocity.SubVec3(0); + } + else { + body->next->spatialVelocity.SubVec3(0) -= (body->linearFriction * (this->water->GetViscosity()+WATER_FRICTION) * waterLevel) * body->next->spatialVelocity.SubVec3(0); + } +#else + body->next->spatialVelocity.SubVec3(0) -= body->linearFriction * body->next->spatialVelocity.SubVec3(0); +#endif + body->next->spatialVelocity.SubVec3(1) -= body->angularFriction * body->next->spatialVelocity.SubVec3(1); + } +} + +/* +================ +idPhysics_AF::CollisionImpulse + + apply impulse to the colliding bodies + the current state of the body should be set to the moment of impact + this is silly as it doesn't take the AF structure into account +================ +*/ +bool idPhysics_AF::CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision ) { + idVec3 r, velocity, impulse; + idMat3 inverseWorldInertiaTensor; + float impulseNumerator, impulseDenominator; +#ifdef MOD_WATERPHYSICS + float invMass; +#endif + impactInfo_t info; + idEntity *ent; + + ent = gameLocal.entities[collision.c.entityNum]; + if ( ent == self ) { + return false; + } + +#ifdef MOD_WATERPHYSICS + if( this->water != NULL ) { + invMass = body->invLiquidMass; + } else { + invMass = body->invMass; + } +#endif + + // get info from other entity involved + ent->GetImpactInfo( self, collision.c.id, collision.c.point, &info ); + + // Update moved by and set in motion by actor + if( self->m_SetInMotionByActor.GetEntity() ) + { + ent->m_SetInMotionByActor = self->m_SetInMotionByActor.GetEntity(); + ent->m_MovedByActor = self->m_MovedByActor.GetEntity(); + } + // Note: Actors should not overwrite the moved by other actors when they are hit with something + // So only overwrite if MovedByActor is NULL + if( ent->IsType(idActor::Type) + && self->m_SetInMotionByActor.GetEntity() == NULL + && !(static_cast(ent)->IsKnockedOut() || ent->health < 0) ) + { + self->m_SetInMotionByActor = (idActor *) ent; + self->m_MovedByActor = (idActor *) ent; + } + if( self->IsType(idActor::Type) + && ent->m_SetInMotionByActor.GetEntity() == NULL + && !(static_cast(self)->IsKnockedOut() || self->health < 0) ) + { + ent->m_SetInMotionByActor = (idActor *) self; + ent->m_MovedByActor = (idActor *) self; + } + + + // collision point relative to the body center of mass + r = collision.c.point - (body->current->worldOrigin + body->centerOfMass * body->current->worldAxis); + // the velocity at the collision point + velocity = body->current->spatialVelocity.SubVec3(0) + body->current->spatialVelocity.SubVec3(1).Cross(r); + // subtract velocity of other entity + velocity -= info.velocity; + // never stick + if ( velocity * collision.c.normal > 0.0f ) { + velocity = collision.c.normal; + } + inverseWorldInertiaTensor = body->current->worldAxis.Transpose() * body->inverseInertiaTensor * body->current->worldAxis; + impulseNumerator = -( 1.0f + body->bouncyness ) * ( velocity * collision.c.normal ); +#ifdef MOD_WATERPHYSICS + impulseDenominator = invMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); +#else + impulseDenominator = body->invMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); +#endif + if ( info.invMass ) { + impulseDenominator += info.invMass + ( ( info.invInertiaTensor * info.position.Cross( collision.c.normal ) ).Cross( info.position ) * collision.c.normal ); + } + impulse = (impulseNumerator / impulseDenominator) * collision.c.normal; + + // apply impact to other entity + ent->ApplyImpulse( self, collision.c.id, collision.c.point, -impulse ); + + // callback to self to let the entity know about the impact + return self->Collide( collision, velocity ); +} + +/* +================ +idPhysics_AF::ApplyCollisions +================ +*/ +bool idPhysics_AF::ApplyCollisions( float timeStep ) { + int i; + + for ( i = 0; i < collisions.Num(); i++ ) { + if ( CollisionImpulse( timeStep, collisions[i].body, collisions[i].trace ) ) { + return true; + } + } + return false; +} + +/* +================ +idPhysics_AF::SetupCollisionForBody +================ +*/ +idEntity *idPhysics_AF::SetupCollisionForBody( idAFBody *body ) const { + int i; + idAFBody *b; + idEntity *passEntity; + + passEntity = NULL; + + if ( !selfCollision || !body->fl.selfCollision || af_skipSelfCollision.GetBool() ) { + + // disable all bodies + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->clipModel->Disable(); + } + + // don't collide with world collision model if attached to the world + for ( i = 0; i < body->constraints.Num(); i++ ) { + if ( !body->constraints[i]->fl.noCollision ) { + continue; + } + // if this constraint attaches the body to the world + if ( body->constraints[i]->body2 == NULL ) { + // don't collide with the world collision model + passEntity = gameLocal.world; + } + } + + } else { + + // enable all bodies that have self collision + for ( i = 0; i < bodies.Num(); i++ ) { + if ( bodies[i]->fl.selfCollision ) { + bodies[i]->clipModel->Enable(); + } else { + bodies[i]->clipModel->Disable(); + } + } + + // don't let the body collide with itself + body->clipModel->Disable(); + + // disable any bodies attached with constraints + for ( i = 0; i < body->constraints.Num(); i++ ) { + if ( !body->constraints[i]->fl.noCollision ) { + continue; + } + // if this constraint attaches the body to the world + if ( body->constraints[i]->body2 == NULL ) { + // don't collide with the world collision model + passEntity = gameLocal.world; + } else { + if ( body->constraints[i]->body1 == body ) { + b = body->constraints[i]->body2; + } else if ( body->constraints[i]->body2 == body ) { + b = body->constraints[i]->body1; + } else { + continue; + } + // don't collide with this body + b->clipModel->Disable(); + } + } + } + + return passEntity; +} + +/* +================ +idPhysics_AF::CheckForCollisions + + check for collisions between the current and next state + if there is a collision the next state is set to the state at the moment of impact + assumes all bodies are linked for collision detection and relinks all bodies after moving them +================ +*/ +void idPhysics_AF::CheckForCollisions( float timeStep ) { +// #define TEST_COLLISION_DETECTION + int i, index; + idAFBody *body; + idMat3 axis; + idRotation rotation; + trace_t collision; + idEntity *passEntity; +#ifdef MOD_WATERPHYSICS + impactInfo_t info; +#endif + + // clear list with collisions + collisions.SetNum( 0, false ); + + if ( !enableCollision ) { + return; + } + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->clipMask != 0 ) { + + passEntity = SetupCollisionForBody( body ); + +#ifdef TEST_COLLISION_DETECTION + bool startsolid = false; + if ( gameLocal.clip.Contents( body->current->worldOrigin, body->clipModel, + body->current->worldAxis, body->clipMask, passEntity ) ) { + startsolid = true; + } +#endif + + TransposeMultiply( body->current->worldAxis, body->next->worldAxis, axis ); + rotation = axis.ToRotation(); + rotation.SetOrigin( body->current->worldOrigin ); + + // if there was a collision + if ( gameLocal.clip.Motion( collision, body->current->worldOrigin, body->next->worldOrigin, rotation, + body->clipModel, body->current->worldAxis, body->clipMask, passEntity ) ) { + + // set the next state to the state at the moment of impact + body->next->worldOrigin = collision.endpos; + body->next->worldAxis = collision.endAxis; + + // add collision to the list + index = collisions.Num(); + collisions.SetNum( index + 1, false ); + collisions[index].trace = collision; + collisions[index].body = body; + } + +#ifdef MOD_WATERPHYSICS + // Check for water collision + // ideally we could do this check in one step but if a body moves quickly in shallow water + // they will occasionally clip through a solid entity (ie. fall through the floor) + if ( gameLocal.clip.Motion( collision, body->current->worldOrigin, body->next->worldOrigin, rotation, + body->clipModel, body->current->worldAxis, MASK_WATER, passEntity ) ) { + idEntity *ent = gameLocal.entities[collision.c.entityNum]; + + // if the object collides with something with a physics_liquid + if( ent->GetPhysics()->IsType( idPhysics_Liquid::Type ) ) { + idPhysics_Liquid *liquid = static_cast(ent->GetPhysics()); + impactInfo_t info; + + this->self->GetImpactInfo(ent,collision.c.id,collision.c.point,&info); + + this->SetWater(liquid, ent->spawnArgs.GetFloat("murkiness", "0") ); + this->water->Splash(this->self,body->GetVolume(),info,collision); + } + } +#endif + + +#ifdef TEST_COLLISION_DETECTION + if ( gameLocal.clip.Contents( body->next->worldOrigin, body->clipModel, + body->next->worldAxis, body->clipMask, passEntity ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + } + + body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->next->worldOrigin, body->next->worldAxis ); + } +} + +/* +================ +idPhysics_AF::EvaluateContacts +================ +*/ +bool idPhysics_AF::EvaluateContacts( void ) { + int i, j, k, numContacts, numBodyContacts; + idAFBody *body; + contactInfo_t contactInfo[10]; + idEntity *passEntity; + idVecX dir( 6, VECX_ALLOCA( 6 ) ); + + // evaluate bodies + EvaluateBodies( current.lastTimeStep ); + + // remove all existing contacts + ClearContacts(); + + contactBodies.SetNum( 0, false ); + + if ( !enableCollision ) { + return false; + } + + // find all the contacts + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->clipMask == 0 ) { + continue; + } + + passEntity = SetupCollisionForBody( body ); + + body->InverseWorldSpatialInertiaMultiply( dir, body->current->externalForce.ToFloatPtr() ); + dir.SubVec6(0) = body->current->spatialVelocity + current.lastTimeStep * dir.SubVec6(0); + dir.SubVec3(0).Normalize(); + dir.SubVec3(1).Normalize(); + + numContacts = gameLocal.clip.Contacts( contactInfo, 10, body->current->worldOrigin, dir.SubVec6(0), 2.0f, //CONTACT_EPSILON, + body->clipModel, body->current->worldAxis, body->clipMask, passEntity ); + +#if 1 + // merge nearby contacts between the same bodies + // and assure there are at most three planar contacts between any pair of bodies + for ( j = 0; j < numContacts; j++ ) { + + numBodyContacts = 0; + for ( k = 0; k < contacts.Num(); k++ ) { + if ( contacts[k].entityNum == contactInfo[j].entityNum ) { + if ( ( contacts[k].id == i && contactInfo[j].id == contactBodies[k] ) || + ( contactBodies[k] == i && contacts[k].id == contactInfo[j].id ) ) { + + if ( ( contacts[k].point - contactInfo[j].point ).LengthSqr() < Square( 2.0f ) ) { + break; + } + if ( idMath::Fabs( contacts[k].normal * contactInfo[j].normal ) > 0.9f ) { + numBodyContacts++; + } + } + } + } + + if ( k >= contacts.Num() && numBodyContacts < 3 ) { + contacts.Append( contactInfo[j] ); + contactBodies.Append( i ); + } + } + +#else + + for ( j = 0; j < numContacts; j++ ) { + contacts.Append( contactInfo[j] ); + contactBodies.Append( i ); + } +#endif + + } + + AddContactEntitiesForContacts(); + + return ( contacts.Num() != 0 ); +} + +/* +================ +idPhysics_AF::SetupContactConstraints +================ +*/ +void idPhysics_AF::SetupContactConstraints( void ) { + int i; + + // make sure enough contact constraints are allocated + contactConstraints.AssureSizeAlloc( contacts.Num(), idListNewElement ); + contactConstraints.SetNum( contacts.Num(), false ); + + // setup contact constraints + for ( i = 0; i < contacts.Num(); i++ ) { + // add contact constraint + contactConstraints[i]->physics = this; + if ( contacts[i].entityNum == self->entityNumber ) { + contactConstraints[i]->Setup( bodies[contactBodies[i]], bodies[ contacts[i].id ], contacts[i] ); + } + else { + contactConstraints[i]->Setup( bodies[contactBodies[i]], NULL, contacts[i] ); + } + } +} + +/* +================ +idPhysics_AF::ApplyContactForces +================ +*/ +void idPhysics_AF::ApplyContactForces( void ) { +#if 0 + int i; + idEntity *ent; + idVec3 force; + + for ( i = 0; i < contactConstraints.Num(); i++ ) { + if ( contactConstraints[i]->body2 != NULL ) { + continue; + } + const contactInfo_t &contact = contactConstraints[i]->GetContact(); + ent = gameLocal.entities[contact.entityNum]; + if ( !ent ) { + continue; + } + force.Zero(); + ent->AddForce( self, contact.id, contact.point, force ); + } +#endif +} + +/* +================ +idPhysics_AF::ClearExternalForce +================ +*/ +void idPhysics_AF::ClearExternalForce( void ) { + int i; + idAFBody *body; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + // clear external force + body->current->externalForce.Zero(); + body->next->externalForce.Zero(); + } +} + +/* +================ +idPhysics_AF::AddGravity +================ +*/ +void idPhysics_AF::AddGravity( void ) { + int i; + idAFBody *body; +#ifdef MOD_WATERPHYSICS + idVec3 grav( this->liquidDensity * this->gravityVector ); + float waterLevel,wDensity = 0; + bool inWater,bodyBuoyancy = 0; + + if( this->SetWaterLevelf() == 1.0f ) { + wDensity = this->water->GetDensity(); + bodyBuoyancy = af_useBodyDensityBuoyancy.GetBool(); + } + + inWater = false; +#endif + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; +#ifdef MOD_WATERPHYSICS + // add gravitational force + waterLevel = body->SetWaterLevel(this->water,this->gravityNormal,this->fixedDensityBuoyancy); + if( waterLevel > 0.0f ) { + if( !this->fixedDensityBuoyancy && !bodyBuoyancy ) + { + body->liquidMass = body->mass; + body->invLiquidMass = body->invMass; + } + else { + body->liquidMass = body->volume * this->liquidDensity * LIQUID_MASS_MUL; + body->invLiquidMass = 1 / body->liquidMass; + } + + // we float the body in water + if( bodyBuoyancy ) + body->current->externalForce.SubVec3( 0 ) += (body->mass - (body->volume * wDensity * waterLevel)) * gravityVector; + else if( this->fixedDensityBuoyancy ) + body->current->externalForce.SubVec3( 0 ) += body->volume * ( this->liquidDensity - (wDensity * waterLevel) ) * gravityVector; + else + body->current->externalForce.SubVec3( 0 ) += body->mass * grav * waterLevel; + + inWater = true; + } + else { + body->current->externalForce.SubVec3( 0 ) += body->mass * gravityVector; + } +#else + // add gravitational force + body->current->externalForce.SubVec3( 0 ) += body->mass * gravityVector; +#endif + } + +#ifdef MOD_WATERPHYSICS +// if all AFBodies are not in the water, we assume the whole entity is not in water so +// we clear the water flag + if( !inWater ) + { + this->water = NULL; + this->m_fWaterMurkiness = 0.0f; + } +#endif +} + +/* +================ +idPhysics_AF::SwapStates +================ +*/ +void idPhysics_AF::SwapStates( void ) { + int i; + idAFBody *body; + AFBodyPState_t *swap; + + for ( i = 0; i < bodies.Num(); i++ ) { + + body = bodies[i]; + + // swap the current and next state for next simulation step + swap = body->current; + body->current = body->next; + body->next = swap; + } +} + +/* +================ +idPhysics_AF::UpdateClipModels +================ +*/ +void idPhysics_AF::UpdateClipModels( void ) { + int i; + idAFBody *body; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->current->worldOrigin, body->current->worldAxis ); + } +} + +/* +================ +idPhysics_AF::SetSuspendSpeed +================ +*/ +void idPhysics_AF::SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration ) { + this->suspendVelocity = velocity; + this->suspendAcceleration = acceleration; +} + +/* +================ +idPhysics_AF::SetSuspendTime +================ +*/ +void idPhysics_AF::SetSuspendTime( const float minTime, const float maxTime ) { + this->minMoveTime = minTime; + this->maxMoveTime = maxTime; +} + +/* +================ +idPhysics_AF::SetSuspendTolerance +================ +*/ +void idPhysics_AF::SetSuspendTolerance( const float noMoveTime, const float noMoveTranslation, const float noMoveRotation ) { + this->noMoveTime = noMoveTime; + this->noMoveTranslation = noMoveTranslation; + this->noMoveRotation = noMoveRotation; +} + +/* +================ +idPhysics_AF::SetTimeScaleRamp +================ +*/ +void idPhysics_AF::SetTimeScaleRamp( const float start, const float end ) { + timeScaleRampStart = start; + timeScaleRampEnd = end; +} + +/* +================ +idPhysics_AF::SetJointFrictionDent +================ +*/ +void idPhysics_AF::SetJointFrictionDent( const float dent, const float start, const float end ) { + jointFrictionDent = dent; + jointFrictionDentStart = start; + jointFrictionDentEnd = end; +} + +/* +================ +idPhysics_AF::GetJointFrictionScale +================ +*/ +float idPhysics_AF::GetJointFrictionScale( void ) const { + if ( jointFrictionDentScale > 0.0f ) { + return jointFrictionDentScale; + } else if ( jointFrictionScale > 0.0f ) { + return jointFrictionScale; + } else if ( af_jointFrictionScale.GetFloat() > 0.0f ) { + return af_jointFrictionScale.GetFloat(); + } + return 1.0f; +} + +/* +================ +idPhysics_AF::SetContactFrictionDent +================ +*/ +void idPhysics_AF::SetContactFrictionDent( const float dent, const float start, const float end ) { + contactFrictionDent = dent; + contactFrictionDentStart = start; + contactFrictionDentEnd = end; +} + +/* +================ +idPhysics_AF::GetContactFrictionScale +================ +*/ +float idPhysics_AF::GetContactFrictionScale( void ) const { + if ( contactFrictionDentScale > 0.0f ) { + return contactFrictionDentScale; + } else if ( contactFrictionScale > 0.0f ) { + return contactFrictionScale; + } else if ( af_contactFrictionScale.GetFloat() > 0.0f ) { + return af_contactFrictionScale.GetFloat(); + } + return 1.0f; +} + +/* +================ +idPhysics_AF::TestIfAtRest +================ +*/ +bool idPhysics_AF::TestIfAtRest( float timeStep ) { + int i; + float translationSqr, maxTranslationSqr, rotation, maxRotation; + idAFBody *body; + + if ( current.atRest >= 0 ) { + return true; + } + +#ifdef MOD_WATERPHYSICS +// prevent bodies from going in active after floating. You don't really want bodies to +// go inactive if they're in water (sometimes they just have a long way to go before surfacing) + if( this->water != NULL ) current.activateTime = 0.0f; +#endif + + current.activateTime += timeStep; + + // if the simulation should never be suspended before a certaint amount of time passed + if ( minMoveTime > 0.0f && current.activateTime < minMoveTime ) { + return false; + } + + // if the simulation should always be suspended after a certain amount time passed + if ( maxMoveTime > 0.0f && current.activateTime > maxMoveTime ) { + return true; + } + + // test if all bodies hardly moved over a period of time + if ( current.noMoveTime == 0.0f ) { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->atRestOrigin = body->current->worldOrigin; + body->atRestAxis = body->current->worldAxis; + } + current.noMoveTime += timeStep; + } + else if ( current.noMoveTime > noMoveTime ) { + current.noMoveTime = 0.0f; + maxTranslationSqr = 0.0f; + maxRotation = 0.0f; + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + translationSqr = ( body->current->worldOrigin - body->atRestOrigin ).LengthSqr(); + if ( translationSqr > maxTranslationSqr ) { + maxTranslationSqr = translationSqr; + } + rotation = ( body->atRestAxis.Transpose() * body->current->worldAxis ).ToRotation().GetAngle(); + if ( rotation > maxRotation ) { + maxRotation = rotation; + } + } + + if ( maxTranslationSqr < Square( noMoveTranslation ) && maxRotation < noMoveRotation ) { + // hardly moved over a period of time so the articulated figure may come to rest + return true; + } + } else { + current.noMoveTime += timeStep; + } + + // test if the velocity or acceleration of any body is still too large to come to rest +#ifdef MOD_WATERPHYSICS + if( this->water == NULL ) { +#endif + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->current->spatialVelocity.SubVec3(0).LengthSqr() > Square( suspendVelocity[0] ) ) { + return false; + } + if ( body->current->spatialVelocity.SubVec3(1).LengthSqr() > Square( suspendVelocity[1] ) ) { + return false; + } + if ( body->acceleration.SubVec3(0).LengthSqr() > Square( suspendAcceleration[0] ) ) { + return false; + } + if ( body->acceleration.SubVec3(1).LengthSqr() > Square( suspendAcceleration[1] ) ) { + return false; + } + } +#ifdef MOD_WATERPHYSICS + } else { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->current->spatialVelocity.SubVec3(0).LengthSqr() > Square( suspendVelocity[0] ) ) { + return false; + } + if ( body->current->spatialVelocity.SubVec3(1).LengthSqr() > Square( suspendVelocity[1] ) ) { + return false; + } + if ( body->acceleration.SubVec3(0).LengthSqr() > Square( suspendAcceleration[0] ) ) { + return false; + } + if ( body->acceleration.SubVec3(1).LengthSqr() > Square( suspendAcceleration[1] ) ) { + return false; + } + } + } +#endif + + // all bodies have a velocity and acceleration small enough to come to rest + return true; +} + +/* +================ +idPhysics_AF::Rest +================ +*/ +void idPhysics_AF::Rest( void ) { + int i; + + current.atRest = gameLocal.time; + + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->current->spatialVelocity.Zero(); + bodies[i]->current->externalForce.Zero(); + } + + self->BecomeInactive( TH_PHYSICS ); + self->m_SetInMotionByActor = NULL; + self->m_droppedByAI = false; // grayman #1330 +} + +/* +================ +idPhysics_AF::Activate +================ +*/ +void idPhysics_AF::Activate( void ) { + // if the articulated figure was at rest + if ( current.atRest >= 0 ) { + // normally gravity is added at the end of a simulation frame + // if the figure was at rest add gravity here so it is applied this simulation frame + AddGravity(); + // reset the active time for the max move time + current.activateTime = 0.0f; + } + current.atRest = -1; + current.noMoveTime = 0.0f; + self->BecomeActive( TH_PHYSICS ); +} + +/* +================ +idPhysics_AF::PutToRest + + put to rest untill something collides with this physics object +================ +*/ +void idPhysics_AF::PutToRest( void ) { + Rest(); +} + +/* +================ +idPhysics_AF::EnableImpact +================ +*/ +void idPhysics_AF::EnableImpact( void ) { + noImpact = false; +} + +/* +================ +idPhysics_AF::DisableImpact +================ +*/ +void idPhysics_AF::DisableImpact( void ) { + noImpact = true; +} + +/* +================ +idPhysics_AF::AddPushVelocity +================ +*/ +void idPhysics_AF::AddPushVelocity( const idVec6 &pushVelocity ) { + int i; + + if ( pushVelocity != vec6_origin ) { + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->current->spatialVelocity += pushVelocity; + } + } +} + +/* +================ +idPhysics_AF::SetClipModel +================ +*/ +void idPhysics_AF::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { +} + +/* +================ +idPhysics_AF::GetClipModel +================ +*/ +idClipModel *idPhysics_AF::GetClipModel( int id ) const { + if ( id >= 0 && id < bodies.Num() ) { + return bodies[id]->GetClipModel(); + } + return NULL; +} + +/* +================ +idPhysics_AF::GetNumClipModels +================ +*/ +int idPhysics_AF::GetNumClipModels( void ) const { + return bodies.Num(); +} + +/* +================ +idPhysics_AF::SetMass +================ +*/ +void idPhysics_AF::SetMass( float mass, int id ) { + if ( id >= 0 && id < bodies.Num() ) { + } + else { + forceTotalMass = mass; + } + SetChanged(); +} + +/* +================ +idPhysics_AF::GetMass +================ +*/ +float idPhysics_AF::GetMass( int id ) const { + if ( id >= 0 && id < bodies.Num() ) { +#ifdef MOD_WATERPHYSICS + if ( bodies[id]->GetWaterLevel() > 0.0f ) + return bodies[id]->liquidMass; + else +#endif + return bodies[id]->mass; + } + +#ifdef MOD_WATERPHYSICS + // if body in water, we have to recompute the total mass + if( this->water != NULL ) { + int i; + float waterMass = 0.0f; + + for( i = 0; i < this->bodies.Num(); i++ ) { + waterMass += this->bodies[i]->liquidMass; + } + + return waterMass; + } +#endif + + return totalMass; +} + +/* +================ +idPhysics_AF::SetContents +================ +*/ +void idPhysics_AF::SetContents( int contents, int id ) { + int i; + + if ( id >= 0 && id < bodies.Num() ) { + bodies[id]->GetClipModel()->SetContents( contents ); + } + else { + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->GetClipModel()->SetContents( contents ); + } + } +} + +/* +================ +idPhysics_AF::GetContents +================ +*/ +int idPhysics_AF::GetContents( int id ) const { + int i, contents; + + if ( id >= 0 && id < bodies.Num() ) { + return bodies[id]->GetClipModel()->GetContents(); + } + else { + contents = 0; + for ( i = 0; i < bodies.Num(); i++ ) { + contents |= bodies[i]->GetClipModel()->GetContents(); + } + return contents; + } +} + +/* +================ +idPhysics_AF::GetBounds +================ +*/ +const idBounds &idPhysics_AF::GetBounds( int id ) const { + int i; + static idBounds relBounds; + + if ( id >= 0 && id < bodies.Num() ) { + return bodies[id]->GetClipModel()->GetBounds(); + } + else if ( !bodies.Num() ) { + relBounds.Zero(); + return relBounds; + } + else { + relBounds = bodies[0]->GetClipModel()->GetBounds(); + for ( i = 1; i < bodies.Num(); i++ ) { + idBounds bounds; + idVec3 origin = ( bodies[i]->GetWorldOrigin() - bodies[0]->GetWorldOrigin() ) * bodies[0]->GetWorldAxis().Transpose(); + idMat3 axis = bodies[i]->GetWorldAxis() * bodies[0]->GetWorldAxis().Transpose(); + bounds.FromTransformedBounds( bodies[i]->GetClipModel()->GetBounds(), origin, axis ); + relBounds += bounds; + } + return relBounds; + } +} + +/* +================ +idPhysics_AF::GetAbsBounds +================ +*/ +const idBounds &idPhysics_AF::GetAbsBounds( int id ) const { + int i; + static idBounds absBounds; + + if ( id >= 0 && id < bodies.Num() ) { + return bodies[id]->GetClipModel()->GetAbsBounds(); + } + else if ( !bodies.Num() ) { + absBounds.Zero(); + return absBounds; + } + else { + absBounds = bodies[0]->GetClipModel()->GetAbsBounds(); + for ( i = 1; i < bodies.Num(); i++ ) { + absBounds += bodies[i]->GetClipModel()->GetAbsBounds(); + } + return absBounds; + } +} + +/* +================ +idPhysics_AF::Evaluate +================ +*/ +bool idPhysics_AF::Evaluate( int timeStepMSec, int endTimeMSec ) +{ + float timeStep; + + if ( timeScaleRampStart < MS2SEC( endTimeMSec ) && timeScaleRampEnd > MS2SEC( endTimeMSec ) ) { + timeStep = MS2SEC( timeStepMSec ) * ( MS2SEC( endTimeMSec ) - timeScaleRampStart ) / ( timeScaleRampEnd - timeScaleRampStart ); + } else if ( af_timeScale.GetFloat() != 1.0f ) { + timeStep = MS2SEC( timeStepMSec ) * af_timeScale.GetFloat(); + } else { + timeStep = MS2SEC( timeStepMSec ) * timeScale; + } + current.lastTimeStep = timeStep; + + + // if the articulated figure changed + if ( changedAF || ( linearTime != af_useLinearTime.GetBool() ) ) { + BuildTrees(); + changedAF = false; + linearTime = af_useLinearTime.GetBool(); + } + + // get the new master position + if ( masterBody ) { + idVec3 masterOrigin; + idMat3 masterAxis; + self->GetMasterPosition( masterOrigin, masterAxis ); + if ( current.atRest >= 0 && ( masterBody->current->worldOrigin != masterOrigin || masterBody->current->worldAxis != masterAxis ) ) { + Activate(); + } + masterBody->current->worldOrigin = masterOrigin; + masterBody->current->worldAxis = masterAxis; + } + + // if the simulation is suspended because the figure is at rest + if ( current.atRest >= 0 || timeStep <= 0.0f ) { + DebugDraw(); + return false; + } + + // move the af velocity into the frame of a pusher + AddPushVelocity( -current.pushVelocity ); + + // TDM: Enable the clipmodels of all team members for collisions + idEntity *part = NULL; + + idList InitClipStates; + bool PartClipState = false; + + if( ((idAFEntity_Base *) self )->CollidesWithTeam() ) + { + for ( part = self->GetTeamMaster(); part != NULL; part = part->GetNextTeamEntity() ) + { + if ( part != self && part->GetPhysics() ) + { + PartClipState = part->GetPhysics()->GetClipModel()->IsEnabled(); + InitClipStates.Append( PartClipState ); + + part->GetPhysics()->EnableClip(); + } + } + } + +#ifdef AF_TIMINGS + timer_total.Start(); +#endif + +#ifdef AF_TIMINGS + timer_collision.Start(); +#endif + + // evaluate contacts + EvaluateContacts(); + + // setup contact constraints + SetupContactConstraints(); + +#ifdef AF_TIMINGS + timer_collision.Stop(); +#endif + + // evaluate constraint equations + EvaluateConstraints( timeStep ); + + // apply friction + ApplyFriction( timeStep, endTimeMSec ); + + // add frame constraints + AddFrameConstraints(); + +#ifdef AF_TIMINGS + int i, numPrimary = 0, numAuxiliary = 0; + for ( i = 0; i < primaryConstraints.Num(); i++ ) { + numPrimary += primaryConstraints[i]->J1.GetNumRows(); + } + for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { + numAuxiliary += auxiliaryConstraints[i]->J1.GetNumRows(); + } + timer_pc.Start(); +#endif + + // factor matrices for primary constraints + PrimaryFactor(); + + // calculate forces on bodies after applying primary constraints + PrimaryForces( timeStep ); + +#ifdef AF_TIMINGS + timer_pc.Stop(); + timer_ac.Start(); +#endif + + // calculate and apply auxiliary constraint forces + AuxiliaryForces( timeStep ); + +#ifdef AF_TIMINGS + timer_ac.Stop(); +#endif + + // evolve current state to next state + Evolve( timeStep ); + + // debug graphics + DebugDraw(); + + // clear external forces on all bodies + ClearExternalForce(); + + // apply contact force to other entities + ApplyContactForces(); + + // remove all frame constraints + RemoveFrameConstraints(); + +#ifdef AF_TIMINGS + timer_collision.Start(); +#endif + + // check for collisions between current and next state + CheckForCollisions( timeStep ); + +#ifdef AF_TIMINGS + timer_collision.Stop(); +#endif + + // swap the current and next state + SwapStates(); + + // make sure all clip models are disabled in case they were enabled for self collision + if ( selfCollision && !af_skipSelfCollision.GetBool() ) { + DisableClip(); + } + + // apply collision impulses + if ( ApplyCollisions( timeStep ) ) { + current.atRest = gameLocal.time; + comeToRest = true; + } + + // test if the simulation can be suspended because the whole figure is at rest + if ( comeToRest && TestIfAtRest( timeStep ) ) { + Rest(); + } else { + ActivateContactEntities(); + } + + // add gravitational force + AddGravity(); + + // move the af velocity back into the world frame + AddPushVelocity( current.pushVelocity ); + current.pushVelocity.Zero(); + + if ( IsOutsideWorld() ) { + gameLocal.Warning( "articulated figure moved outside world bounds for entity '%s' type '%s' at (%s)", + self->name.c_str(), self->GetType()->classname, bodies[0]->current->worldOrigin.ToString(0) ); + Rest(); + } + +#ifdef AF_TIMINGS + timer_total.Stop(); + + if ( af_showTimings.GetInteger() == 1 ) { + gameLocal.Printf( "%12s: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n", + self->name.c_str(), + timer_total.Milliseconds(), + numPrimary, timer_pc.Milliseconds(), + numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(), + timer_lcp.Milliseconds(), timer_collision.Milliseconds() ); + } + else if ( af_showTimings.GetInteger() == 2 ) { + numArticulatedFigures++; + if ( endTimeMSec > lastTimerReset ) { + gameLocal.Printf( "af %d: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n", + numArticulatedFigures, + timer_total.Milliseconds(), + numPrimary, timer_pc.Milliseconds(), + numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(), + timer_lcp.Milliseconds(), timer_collision.Milliseconds() ); + } + } + + if ( endTimeMSec > lastTimerReset ) { + lastTimerReset = endTimeMSec; + numArticulatedFigures = 0; + timer_total.Clear(); + timer_pc.Clear(); + timer_ac.Clear(); + timer_collision.Clear(); + timer_lcp.Clear(); + } +#endif + + + // TDM: Disable the clipmodels that we enabled above + int count = 0; + + if( ((idAFEntity_Base *) self )->CollidesWithTeam() ) + { + for ( part = self->GetTeamMaster(); part != NULL; part = part->GetNextTeamEntity() ) + { + if ( part != self && part->GetPhysics() ) + { + if( !InitClipStates[count] ) + part->GetPhysics()->DisableClip(); + + count++; + } + } + } + + return true; +} + +/* +================ +idPhysics_AF::UpdateTime +================ +*/ +void idPhysics_AF::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_AF::GetTime +================ +*/ +int idPhysics_AF::GetTime( void ) const { + return gameLocal.time; +} + +/* +================ +DrawTraceModelSilhouette +================ +*/ +void DrawTraceModelSilhouette( const idVec3 &projectionOrigin, const idClipModel *clipModel ) { + int i, numSilEdges; + int silEdges[MAX_TRACEMODEL_EDGES]; + idVec3 v1, v2; + const idTraceModel *trm = clipModel->GetTraceModel(); + const idVec3 &origin = clipModel->GetOrigin(); + const idMat3 &axis = clipModel->GetAxis(); + + numSilEdges = trm->GetProjectionSilhouetteEdges( ( projectionOrigin - origin ) * axis.Transpose(), silEdges ); + for ( i = 0; i < numSilEdges; i++ ) { + v1 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INTSIGNBITSET( silEdges[i] ) ] ]; + v2 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INTSIGNBITNOTSET( silEdges[i] ) ] ]; + gameRenderWorld->DebugArrow( colorRed, origin + v1 * axis, origin + v2 * axis, 1 ); + } +} + +/* +================ +idPhysics_AF::DebugDraw +================ +*/ +void idPhysics_AF::DebugDraw( void ) { + int i; + idAFBody *body, *highlightBody = NULL, *constrainedBody1 = NULL, *constrainedBody2 = NULL; + idAFConstraint *constraint; + idVec3 center; + idMat3 axis; + + if ( af_highlightConstraint.GetString()[0] ) { + constraint = GetConstraint( af_highlightConstraint.GetString() ); + if ( constraint ) { + constraint->GetCenter( center ); + axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); + gameRenderWorld->DebugCone( colorYellow, center, (axis[2] - axis[1]) * 4.0f, 0.0f, 1.0f, 0 ); + + if ( af_showConstrainedBodies.GetBool() ) { + cvarSystem->SetCVarString( "cm_drawColor", colorCyan.ToString( 0 ) ); + constrainedBody1 = constraint->body1; + if ( constrainedBody1 ) { + collisionModelManager->DrawModel( constrainedBody1->clipModel->Handle(), constrainedBody1->clipModel->GetOrigin(), + constrainedBody1->clipModel->GetAxis(), vec3_origin, 0.0f ); + } + cvarSystem->SetCVarString( "cm_drawColor", colorBlue.ToString( 0 ) ); + constrainedBody2 = constraint->body2; + if ( constrainedBody2 ) { + collisionModelManager->DrawModel( constrainedBody2->clipModel->Handle(), constrainedBody2->clipModel->GetOrigin(), + constrainedBody2->clipModel->GetAxis(), vec3_origin, 0.0f ); + } + cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) ); + } + } + } + + if ( af_highlightBody.GetString()[0] ) { + highlightBody = GetBody( af_highlightBody.GetString() ); + if ( highlightBody ) { + cvarSystem->SetCVarString( "cm_drawColor", colorYellow.ToString( 0 ) ); + collisionModelManager->DrawModel( highlightBody->clipModel->Handle(), highlightBody->clipModel->GetOrigin(), + highlightBody->clipModel->GetAxis(), vec3_origin, 0.0f ); + cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) ); + } + } + + if ( af_showBodies.GetBool() ) { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + if ( body == constrainedBody1 || body == constrainedBody2 ) { + continue; + } + if ( body == highlightBody ) { + continue; + } + collisionModelManager->DrawModel( body->clipModel->Handle(), body->clipModel->GetOrigin(), + body->clipModel->GetAxis(), vec3_origin, 0.0f ); + //DrawTraceModelSilhouette( gameLocal.GetLocalPlayer()->GetEyePosition(), body->clipModel ); + } + } + + if ( af_showBodyNames.GetBool() ) { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + gameRenderWorld->DrawText( body->GetName().c_str(), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + } + + if ( af_showMass.GetBool() ) { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; +#ifdef MOD_WATERPHYSICS + if( body->GetWaterLevel() > 0.0f ) + gameRenderWorld->DrawText( va( "\n%1.2f", body->liquidMass ), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + else +#endif + gameRenderWorld->DrawText( va( "\n%1.2f", 1.0f / body->GetInverseMass() ), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + } + + if ( af_showTotalMass.GetBool() ) { + axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); +#ifdef MOD_WATERPHYSICS + gameRenderWorld->DrawText( va( "\n%1.2f", this->GetMass() ), bodies[0]->GetWorldOrigin() + axis[2] * 8.0f, 0.15f, colorCyan, axis, 1 ); +#else + gameRenderWorld->DrawText( va( "\n%1.2f", totalMass ), bodies[0]->GetWorldOrigin() + axis[2] * 8.0f, 0.15f, colorCyan, axis, 1 ); +#endif + } + + if ( af_showInertia.GetBool() ) { + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + idMat3 &I = body->inertiaTensor; + gameRenderWorld->DrawText( va( "\n\n\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )", + I[0].x, I[0].y, I[0].z, + I[1].x, I[1].y, I[1].z, + I[2].x, I[2].y, I[2].z ), + body->GetWorldOrigin(), 0.05f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + } + + if ( af_showVelocity.GetBool() ) { + for ( i = 0; i < bodies.Num(); i++ ) { + DrawVelocity( bodies[i]->clipModel->GetId(), 0.1f, 4.0f ); + } + } + + if ( af_showConstraints.GetBool() ) { + for ( i = 0; i < primaryConstraints.Num(); i++ ) { + constraint = primaryConstraints[i]; + constraint->DebugDraw(); + } + if ( !af_showPrimaryOnly.GetBool() ) { + for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + constraint->DebugDraw(); + } + } + } + + if ( af_showConstraintNames.GetBool() ) { + for ( i = 0; i < primaryConstraints.Num(); i++ ) { + constraint = primaryConstraints[i]; + constraint->GetCenter( center ); + gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + if ( !af_showPrimaryOnly.GetBool() ) { + for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { + constraint = auxiliaryConstraints[i]; + constraint->GetCenter( center ); + gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + } + } + + if ( af_showTrees.GetBool() || ( af_showActive.GetBool() && current.atRest < 0 ) ) { + for ( i = 0; i < trees.Num(); i++ ) { + trees[i]->DebugDraw( idStr::ColorForIndex( i+3 ) ); + } + } +} + +/* +================ +idPhysics_AF::idPhysics_AF +================ +*/ +idPhysics_AF::idPhysics_AF( void ) { + trees.Clear(); + bodies.Clear(); + constraints.Clear(); + primaryConstraints.Clear(); + auxiliaryConstraints.Clear(); + frameConstraints.Clear(); + contacts.Clear(); + collisions.Clear(); + changedAF = true; + masterBody = NULL; + + lcp = idLCP::AllocSymmetric(); + + memset( ¤t, 0, sizeof( current ) ); + current.atRest = -1; + current.lastTimeStep = USERCMD_MSEC; + saved = current; + + linearFriction = 0.005f; + angularFriction = 0.005f; + contactFriction = 0.8f; + bouncyness = 0.4f; + totalMass = 0.0f; + forceTotalMass = -1.0f; + +#ifdef MOD_WATERPHYSICS + // sets default buoyancy property based on CVar + if( af_useFixedDensityBuoyancy.GetBool() ) { + this->fixedDensityBuoyancy = true; + this->liquidDensity = DEFAULT_LIQUID_DENSITY; + } + else { + this->fixedDensityBuoyancy = false; + this->liquidDensity = DEFAULT_LIQUID_SCALAR; + } + this->water = NULL; + this->m_fWaterMurkiness = 0.0f; +#endif + + suspendVelocity.Set( SUSPEND_LINEAR_VELOCITY, SUSPEND_ANGULAR_VELOCITY ); + suspendAcceleration.Set( SUSPEND_LINEAR_ACCELERATION, SUSPEND_LINEAR_ACCELERATION ); + noMoveTime = NO_MOVE_TIME; + noMoveTranslation = NO_MOVE_TRANSLATION_TOLERANCE; + noMoveRotation = NO_MOVE_ROTATION_TOLERANCE; + minMoveTime = MIN_MOVE_TIME; + maxMoveTime = MAX_MOVE_TIME; + impulseThreshold = IMPULSE_THRESHOLD; + + timeScale = 1.0f; + timeScaleRampStart = 0.0f; + timeScaleRampEnd = 0.0f; + + jointFrictionScale = 0.0f; + jointFrictionDent = 0.0f; + jointFrictionDentStart = 0.0f; + jointFrictionDentEnd = 0.0f; + jointFrictionDentScale = 0.0f; + + contactFrictionScale = 0.0f; + contactFrictionDent = 0.0f; + contactFrictionDentStart = 0.0f; + contactFrictionDentEnd = 0.0f; + contactFrictionDentScale = 0.0f; + + enableCollision = true; + selfCollision = true; + comeToRest = true; + linearTime = true; + noImpact = false; + worldConstraintsLocked = false; + forcePushable = false; + + // Init these to -1, if they are still -1 on save time, + // save just uses the actual numbers in the lists + m_NumOrigBodies = -1; + m_NumOrigConstraints = -1; + +#ifdef AF_TIMINGS + lastTimerReset = 0; +#endif +} + +/* +================ +idPhysics_AF::~idPhysics_AF +================ +*/ +idPhysics_AF::~idPhysics_AF( void ) { + int i; + + trees.DeleteContents( true ); + + for ( i = 0; i < bodies.Num(); i++ ) { + delete bodies[i]; + } + + for ( i = 0; i < constraints.Num(); i++ ) { + delete constraints[i]; + } + + contactConstraints.SetNum( contactConstraints.NumAllocated(), false ); + for ( i = 0; i < contactConstraints.NumAllocated(); i++ ) { + delete contactConstraints[i]; + } + + delete lcp; + + if ( masterBody ) { + delete masterBody; + } +} + +/* +================ +idPhysics_AF_SavePState +================ +*/ +void idPhysics_AF_SavePState( idSaveGame *saveFile, const AFPState_t &state ) { + saveFile->WriteInt( state.atRest ); + saveFile->WriteFloat( state.noMoveTime ); + saveFile->WriteFloat( state.activateTime ); + saveFile->WriteFloat( state.lastTimeStep ); + saveFile->WriteVec6( state.pushVelocity ); +} + +/* +================ +idPhysics_AF_RestorePState +================ +*/ +void idPhysics_AF_RestorePState( idRestoreGame *saveFile, AFPState_t &state ) { + saveFile->ReadInt( state.atRest ); + saveFile->ReadFloat( state.noMoveTime ); + saveFile->ReadFloat( state.activateTime ); + saveFile->ReadFloat( state.lastTimeStep ); + saveFile->ReadVec6( state.pushVelocity ); +} + +/* +================ +idPhysics_AF::Save +================ +*/ +void idPhysics_AF::Save( idSaveGame *saveFile ) const +{ + int i, num; + + // the articulated figure structure is handled by the owner + + idPhysics_AF_SavePState( saveFile, current ); + idPhysics_AF_SavePState( saveFile, saved ); + + if( m_NumOrigBodies < 0 ) + num = bodies.Num(); + else + num = m_NumOrigBodies; + + saveFile->WriteInt( num ); + for ( i = 0; i < num; i++ ) { + bodies[i]->Save( saveFile ); + } + if ( masterBody ) { + saveFile->WriteBool( true ); + masterBody->Save( saveFile ); + } else { + saveFile->WriteBool( false ); + } + + if( m_NumOrigConstraints < 0 ) + num = constraints.Num(); + else + num = m_NumOrigConstraints; + + saveFile->WriteInt( num ); + for ( i = 0; i < num; i++ ) { + constraints[i]->Save( saveFile ); + } + + saveFile->WriteBool( changedAF ); + + saveFile->WriteFloat( linearFriction ); + saveFile->WriteFloat( angularFriction ); + saveFile->WriteFloat( contactFriction ); + saveFile->WriteFloat( bouncyness ); + saveFile->WriteFloat( totalMass ); + saveFile->WriteFloat( forceTotalMass ); + +#ifdef MOD_WATERPHYSICS + saveFile->WriteBool( this->fixedDensityBuoyancy ); + saveFile->WriteFloat( this->liquidDensity ); +#endif + + saveFile->WriteVec2( suspendVelocity ); + saveFile->WriteVec2( suspendAcceleration ); + saveFile->WriteFloat( noMoveTime ); + saveFile->WriteFloat( noMoveTranslation ); + saveFile->WriteFloat( noMoveRotation ); + saveFile->WriteFloat( minMoveTime ); + saveFile->WriteFloat( maxMoveTime ); + saveFile->WriteFloat( impulseThreshold ); + + saveFile->WriteFloat( timeScale ); + saveFile->WriteFloat( timeScaleRampStart ); + saveFile->WriteFloat( timeScaleRampEnd ); + + saveFile->WriteFloat( jointFrictionScale ); + saveFile->WriteFloat( jointFrictionDent ); + saveFile->WriteFloat( jointFrictionDentStart ); + saveFile->WriteFloat( jointFrictionDentEnd ); + saveFile->WriteFloat( jointFrictionDentScale ); + + saveFile->WriteFloat( contactFrictionScale ); + saveFile->WriteFloat( contactFrictionDent ); + saveFile->WriteFloat( contactFrictionDentStart ); + saveFile->WriteFloat( contactFrictionDentEnd ); + saveFile->WriteFloat( contactFrictionDentScale ); + + saveFile->WriteBool( enableCollision ); + saveFile->WriteBool( selfCollision ); + saveFile->WriteBool( comeToRest ); + saveFile->WriteBool( linearTime ); + saveFile->WriteBool( noImpact ); + saveFile->WriteBool( worldConstraintsLocked ); + saveFile->WriteBool( forcePushable ); +} + +/* +================ +idPhysics_AF::Restore +================ +*/ +void idPhysics_AF::Restore( idRestoreGame *saveFile ) { + int i, num; + bool hasMaster; + + // the articulated figure structure should have already been restored + + idPhysics_AF_RestorePState( saveFile, current ); + idPhysics_AF_RestorePState( saveFile, saved ); + + saveFile->ReadInt( num ); + assert( num == bodies.Num() ); + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->Restore( saveFile ); + } + saveFile->ReadBool( hasMaster ); + if ( hasMaster ) { + masterBody = new idAFBody(); + masterBody->Restore( saveFile ); + } + + saveFile->ReadInt( num ); + assert( num == constraints.Num() ); + for ( i = 0; i < constraints.Num(); i++ ) { + constraints[i]->Restore( saveFile ); + } + + saveFile->ReadBool( changedAF ); + + saveFile->ReadFloat( linearFriction ); + saveFile->ReadFloat( angularFriction ); + saveFile->ReadFloat( contactFriction ); + saveFile->ReadFloat( bouncyness ); + saveFile->ReadFloat( totalMass ); + saveFile->ReadFloat( forceTotalMass ); + +#ifdef MOD_WATERPHYSICS + saveFile->ReadBool( this->fixedDensityBuoyancy ); + saveFile->ReadFloat( this->liquidDensity ); +#endif + + saveFile->ReadVec2( suspendVelocity ); + saveFile->ReadVec2( suspendAcceleration ); + saveFile->ReadFloat( noMoveTime ); + saveFile->ReadFloat( noMoveTranslation ); + saveFile->ReadFloat( noMoveRotation ); + saveFile->ReadFloat( minMoveTime ); + saveFile->ReadFloat( maxMoveTime ); + saveFile->ReadFloat( impulseThreshold ); + + saveFile->ReadFloat( timeScale ); + saveFile->ReadFloat( timeScaleRampStart ); + saveFile->ReadFloat( timeScaleRampEnd ); + + saveFile->ReadFloat( jointFrictionScale ); + saveFile->ReadFloat( jointFrictionDent ); + saveFile->ReadFloat( jointFrictionDentStart ); + saveFile->ReadFloat( jointFrictionDentEnd ); + saveFile->ReadFloat( jointFrictionDentScale ); + + saveFile->ReadFloat( contactFrictionScale ); + saveFile->ReadFloat( contactFrictionDent ); + saveFile->ReadFloat( contactFrictionDentStart ); + saveFile->ReadFloat( contactFrictionDentEnd ); + saveFile->ReadFloat( contactFrictionDentScale ); + + saveFile->ReadBool( enableCollision ); + saveFile->ReadBool( selfCollision ); + saveFile->ReadBool( comeToRest ); + saveFile->ReadBool( linearTime ); + saveFile->ReadBool( noImpact ); + saveFile->ReadBool( worldConstraintsLocked ); + saveFile->ReadBool( forcePushable ); + + changedAF = true; + + UpdateClipModels(); +} + +/* +================ +idPhysics_AF::IsClosedLoop +================ +*/ +bool idPhysics_AF::IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const { + const idAFBody *b1, *b2; + + for ( b1 = body1; b1->parent; b1 = b1->parent ) { + } + for ( b2 = body2; b2->parent; b2 = b2->parent ) { + } + return ( b1 == b2 ); +} + +/* +================ +idPhysics_AF::BuildTrees +================ +*/ +void idPhysics_AF::BuildTrees( void ) { + int i; + float scale; + idAFBody *b; + idAFConstraint *c; + idAFTree *tree; + + primaryConstraints.Clear(); + auxiliaryConstraints.Clear(); + trees.DeleteContents( true ); + + totalMass = 0.0f; + for ( i = 0; i < bodies.Num(); i++ ) { + b = bodies[i]; + b->parent = NULL; + b->primaryConstraint = NULL; + b->constraints.SetNum( 0, false ); + b->children.Clear(); + b->tree = NULL; + totalMass += b->mass; + } + + if ( forceTotalMass > 0.0f ) { + scale = forceTotalMass / totalMass; + for ( i = 0; i < bodies.Num(); i++ ) { + b = bodies[i]; + b->mass *= scale; + b->invMass = 1.0f / b->mass; + b->inertiaTensor *= scale; + b->inverseInertiaTensor = b->inertiaTensor.Inverse(); + } + totalMass = forceTotalMass; + } + + if ( af_useLinearTime.GetBool() ) { + + for ( i = 0; i < constraints.Num(); i++ ) { + c = constraints[i]; + + c->body1->constraints.Append( c ); + if ( c->body2 ) { + c->body2->constraints.Append( c ); + } + + // only bilateral constraints between two non-world bodies that do not + // create loops can be used as primary constraints + if ( !c->body1->primaryConstraint && c->fl.allowPrimary && c->body2 != NULL && !IsClosedLoop( c->body1, c->body2 ) ) { + c->body1->primaryConstraint = c; + c->body1->parent = c->body2; + c->body2->children.Append( c->body1 ); + c->fl.isPrimary = true; + c->firstIndex = 0; + primaryConstraints.Append( c ); + } else { + c->fl.isPrimary = false; + auxiliaryConstraints.Append( c ); + } + } + + // create trees for all parent bodies + for ( i = 0; i < bodies.Num(); i++ ) { + if ( !bodies[i]->parent ) { + tree = new idAFTree(); + tree->sortedBodies.Clear(); + tree->sortedBodies.Append( bodies[i] ); + bodies[i]->tree = tree; + trees.Append( tree ); + } + } + + // add each child body to the appropriate tree + for ( i = 0; i < bodies.Num(); i++ ) { + if ( bodies[i]->parent ) { + for ( b = bodies[i]->parent; !b->tree; b = b->parent ) { + } + b->tree->sortedBodies.Append( bodies[i] ); + bodies[i]->tree = b->tree; + } + } + + if ( trees.Num() > 1 ) { + gameLocal.Warning( "Articulated figure has multiple seperate tree structures for entity '%s' type '%s'.", + self->name.c_str(), self->GetType()->classname ); + } + + // sort bodies in each tree to make sure parents come first + for ( i = 0; i < trees.Num(); i++ ) { + trees[i]->SortBodies(); + } + + } else { + + // create a tree for each body + for ( i = 0; i < bodies.Num(); i++ ) { + tree = new idAFTree(); + tree->sortedBodies.Clear(); + tree->sortedBodies.Append( bodies[i] ); + bodies[i]->tree = tree; + trees.Append( tree ); + } + + for ( i = 0; i < constraints.Num(); i++ ) { + c = constraints[i]; + + c->body1->constraints.Append( c ); + if ( c->body2 ) { + c->body2->constraints.Append( c ); + } + + c->fl.isPrimary = false; + auxiliaryConstraints.Append( c ); + } + } +} + +/* +================ +idPhysics_AF::AddBody + + bodies get an id in the order they are added starting at zero + as such the first body added will get id zero +================ +*/ +int idPhysics_AF::AddBody( idAFBody *body ) { + int id = 0; + + if ( !body->clipModel ) { + gameLocal.Error( "idPhysics_AF::AddBody: body '%s' has no clip model.", body->name.c_str() ); + } + + if ( bodies.Find( body ) ) { + gameLocal.Error( "idPhysics_AF::AddBody: body '%s' added twice.", body->name.c_str() ); + } + + if ( GetBody( body->name ) ) { + gameLocal.Error( "idPhysics_AF::AddBody: a body with the name '%s' already exists.", body->name.c_str() ); + } + + id = bodies.Num(); + body->clipModel->SetId( id ); + if ( body->linearFriction < 0.0f ) { + body->linearFriction = linearFriction; + body->angularFriction = angularFriction; + body->contactFriction = contactFriction; + } + if ( body->bouncyness < 0.0f ) { + body->bouncyness = bouncyness; + } + if ( !body->fl.clipMaskSet ) { + body->clipMask = clipMask; + } + + bodies.Append( body ); + + changedAF = true; + + return id; +} + +/* +================ +idPhysics_AF::AddConstraint +================ +*/ +void idPhysics_AF::AddConstraint( idAFConstraint *constraint ) { + + if ( constraints.Find( constraint ) ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: constraint '%s' added twice.", constraint->name.c_str() ); + } + if ( GetConstraint( constraint->name ) ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: a constraint with the name '%s' already exists.", constraint->name.c_str() ); + } + if ( !constraint->body1 ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: body1 == NULL on constraint '%s'.", constraint->name.c_str() ); + } + if ( !bodies.Find( constraint->body1 ) ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: body1 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() ); + } + if ( constraint->body2 && !bodies.Find( constraint->body2 ) ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: body2 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() ); + } + if ( constraint->body1 == constraint->body2 ) { + gameLocal.Error( "idPhysics_AF::AddConstraint: body1 and body2 of constraint '%s' are the same.", constraint->name.c_str() ); + } + + constraints.Append( constraint ); + constraint->physics = this; + + changedAF = true; +} + +/* +================ +idPhysics_AF::AddFrameConstraint +================ +*/ +void idPhysics_AF::AddFrameConstraint( idAFConstraint *constraint ) { + frameConstraints.Append( constraint ); + constraint->physics = this; +} + +/* +================ +idPhysics_AF::ForceBodyId +================ +*/ +void idPhysics_AF::ForceBodyId( idAFBody *body, int newId ) { + int id; + + id = bodies.FindIndex( body ); + if ( id == -1 ) { + gameLocal.Error( "ForceBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() ); + } + if ( id != newId ) { + idAFBody *b = bodies[newId]; + bodies[newId] = bodies[id]; + bodies[id] = b; + changedAF = true; + } +} + +/* +================ +idPhysics_AF::GetBodyId +================ +*/ +int idPhysics_AF::GetBodyId( idAFBody *body ) const { + int id; + + id = bodies.FindIndex( body ); + if ( id == -1 && body ) { + gameLocal.Error( "GetBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() ); + } + return id; +} + +/* +================ +idPhysics_AF::GetBodyId +================ +*/ +int idPhysics_AF::GetBodyId( const char *bodyName ) const { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + if ( !bodies[i]->name.Icmp( bodyName ) ) { + return i; + } + } + gameLocal.Error( "GetBodyId: no body with the name '%s' is not part of the articulated figure.\n", bodyName ); + return 0; +} + +/* +================ +idPhysics_AF::GetConstraintId +================ +*/ +int idPhysics_AF::GetConstraintId( idAFConstraint *constraint ) const { + int id; + + id = constraints.FindIndex( constraint ); + if ( id == -1 && constraint ) { + gameLocal.Error( "GetConstraintId: constraint '%s' is not part of the articulated figure.\n", constraint->name.c_str() ); + } + return id; +} + +/* +================ +idPhysics_AF::GetConstraintId +================ +*/ +int idPhysics_AF::GetConstraintId( const char *constraintName ) const { + int i; + + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->name.Icmp( constraintName ) == 0 ) { + return i; + } + } + gameLocal.Error( "GetConstraintId: no constraint with the name '%s' is not part of the articulated figure.\n", constraintName ); + return 0; +} + +/* +================ +idPhysics_AF::GetNumBodies +================ +*/ +int idPhysics_AF::GetNumBodies( void ) const { + return bodies.Num(); +} + +/* +================ +idPhysics_AF::GetNumConstraints +================ +*/ +int idPhysics_AF::GetNumConstraints( void ) const { + return constraints.Num(); +} + +/* +================ +idPhysics_AF::GetBody +================ +*/ +idAFBody *idPhysics_AF::GetBody( const char *bodyName ) const { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + if ( !bodies[i]->name.Icmp( bodyName ) ) { + return bodies[i]; + } + } + + return NULL; +} + +/* +================ +idPhysics_AF::GetBody +================ +*/ +idAFBody *idPhysics_AF::GetBody( const int id ) const { + if ( id < 0 || id >= bodies.Num() ) { + gameLocal.Error( "GetBody: no body with id %d exists on ent %s\n", id, self->name.c_str() ); + return NULL; + } + return bodies[id]; +} + +/* +================ +idPhysics_AF::GetConstraint +================ +*/ +idAFConstraint *idPhysics_AF::GetConstraint( const char *constraintName ) const { + int i; + + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->name.Icmp( constraintName ) == 0 ) { + return constraints[i]; + } + } + + return NULL; +} + +/* +================ +idPhysics_AF::GetConstraint +================ +*/ +idAFConstraint *idPhysics_AF::GetConstraint( const int id ) const { + if ( id < 0 || id >= constraints.Num() ) { + gameLocal.Error( "GetConstraint: no constraint with id %d exists\n", id ); + return NULL; + } + return constraints[id]; +} + +/* +================ +idPhysics_AF::DeleteBody +================ +*/ +void idPhysics_AF::DeleteBody( const char *bodyName ) { + int i; + + // find the body with the given name + for ( i = 0; i < bodies.Num(); i++ ) { + if ( !bodies[i]->name.Icmp( bodyName ) ) { + break; + } + } + + if ( i >= bodies.Num() ) { + gameLocal.Warning( "DeleteBody: no body found in the articulated figure with the name '%s' for entity '%s' type '%s'.", + bodyName, self->name.c_str(), self->GetType()->classname ); + return; + } + + DeleteBody( i ); +} + +/* +================ +idPhysics_AF::DeleteBody +================ +*/ +void idPhysics_AF::DeleteBody( const int id ) { + int j; + + if ( id < 0 || id > bodies.Num() ) { + gameLocal.Error( "DeleteBody: no body with id %d.", id ); + return; + } + + // remove any constraints attached to this body + for ( j = 0; j < constraints.Num(); j++ ) { + if ( constraints[j]->body1 == bodies[id] || constraints[j]->body2 == bodies[id] ) { + delete constraints[j]; + constraints.RemoveIndex( j ); + j--; + } + } + + // remove the body + delete bodies[id]; + bodies.RemoveIndex( id ); + + // set new body ids + for ( j = 0; j < bodies.Num(); j++ ) { + bodies[j]->clipModel->SetId( j ); + } + + changedAF = true; +} + +/* +================ +idPhysics_AF::DeleteConstraint +================ +*/ +void idPhysics_AF::DeleteConstraint( const char *constraintName ) { + int i; + + // find the constraint with the given name + for ( i = 0; i < constraints.Num(); i++ ) { + if ( !constraints[i]->name.Icmp( constraintName ) ) { + break; + } + } + + if ( i >= constraints.Num() ) { + gameLocal.Warning( "DeleteConstraint: no constriant found in the articulated figure with the name '%s' for entity '%s' type '%s'.", + constraintName, self->name.c_str(), self->GetType()->classname ); + return; + } + + DeleteConstraint( i ); +} + +/* +================ +idPhysics_AF::DeleteConstraint +================ +*/ +void idPhysics_AF::DeleteConstraint( const int id ) { + + if ( id < 0 || id >= constraints.Num() ) { + gameLocal.Error( "DeleteConstraint: no constraint with id %d.", id ); + return; + } + + // remove the constraint + delete constraints[id]; + constraints.RemoveIndex( id ); + + changedAF = true; +} + +/* +================ +idPhysics_AF::GetBodyContactConstraints +================ +*/ +int idPhysics_AF::GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const { + int i, numContacts; + idAFBody *body; + idAFConstraint_Contact *contact; + + if ( id < 0 || id >= bodies.Num() || maxContacts <= 0 ) { + return 0; + } + + numContacts = 0; + body = bodies[id]; + for ( i = 0; i < contactConstraints.Num(); i++ ) { + contact = contactConstraints[i]; + if ( contact->body1 == body || contact->body2 == body ) { + contacts[numContacts++] = contact; + if ( numContacts >= maxContacts ) { + return numContacts; + } + } + } + return numContacts; +} + +/* +================ +idPhysics_AF::SetDefaultFriction +================ +*/ +void idPhysics_AF::SetDefaultFriction( float linear, float angular, float contact ) { + if ( linear < 0.0f || linear > 1.0f || + angular < 0.0f || angular > 1.0f || + contact < 0.0f || contact > 1.0f ) { + return; + } + linearFriction = linear; + angularFriction = angular; + contactFriction = contact; +} + +/* +================ +idPhysics_AF::GetImpactInfo +================ +*/ +void idPhysics_AF::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + if ( id < 0 || id >= bodies.Num() ) { + memset( info, 0, sizeof( *info ) ); + return; + } +#ifdef MOD_WATERPHYSICS + if( this->water != NULL ) + info->invMass = bodies[id]->invLiquidMass; + else + info->invMass = bodies[id]->invMass; +#else + info->invMass = 1.0f / bodies[id]->mass; +#endif + info->invInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis; + info->position = point - bodies[id]->current->worldOrigin; + info->velocity = bodies[id]->current->spatialVelocity.SubVec3(0) + bodies[id]->current->spatialVelocity.SubVec3(1).Cross( info->position ); +} + +/* +================ +idPhysics_AF::ApplyImpulse +================ +*/ +void idPhysics_AF::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + + if ( id < 0 || id >= bodies.Num() ) { + return; + } + if ( noImpact || impulse.LengthSqr() < Square( impulseThreshold ) ) { + return; + } + idMat3 invWorldInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis; +#ifdef MOD_WATERPHYSICS + if( this->water != NULL ) + bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invLiquidMass * impulse; + else + bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invMass * impulse; +#else + bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invMass * impulse; +#endif + bodies[id]->current->spatialVelocity.SubVec3(1) += invWorldInertiaTensor * (point - bodies[id]->current->worldOrigin).Cross( impulse ); + Activate(); +} + +/* +================ +idPhysics_AF::AddForce +================ +*/ +void idPhysics_AF::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { + if ( noImpact ) { + return; + } + if ( id < 0 || id >= bodies.Num() ) { + return; + } + bodies[id]->current->externalForce.SubVec3( 0 ) += force; + bodies[id]->current->externalForce.SubVec3( 1 ) += (point - bodies[id]->current->worldOrigin).Cross( force ); + Activate(); +} + +/* +================ +idPhysics_AF::IsAtRest +================ +*/ +bool idPhysics_AF::IsAtRest( void ) const { + return current.atRest >= 0; +} + +/* +================ +idPhysics_AF::GetRestStartTime +================ +*/ +int idPhysics_AF::GetRestStartTime( void ) const { + return current.atRest; +} + +/* +================ +idPhysics_AF::IsPushable +================ +*/ +bool idPhysics_AF::IsPushable( void ) const { + return ( !noImpact && ( masterBody == NULL || forcePushable ) ); +} + +/* +================ +idPhysics_AF::SaveState +================ +*/ +void idPhysics_AF::SaveState( void ) { + int i; + + saved = current; + + for ( i = 0; i < bodies.Num(); i++ ) { + memcpy( &bodies[i]->saved, bodies[i]->current, sizeof( AFBodyPState_t ) ); + } +} + +/* +================ +idPhysics_AF::RestoreState +================ +*/ +void idPhysics_AF::RestoreState( void ) { + int i; + + current = saved; + + for ( i = 0; i < bodies.Num(); i++ ) { + *(bodies[i]->current) = bodies[i]->saved; + } + + EvaluateContacts(); +} + +/* +================ +idPhysics_AF::SetOrigin +================ +*/ +void idPhysics_AF::SetOrigin( const idVec3 &newOrigin, int id ) { + if ( masterBody ) { + Translate( masterBody->current->worldOrigin + masterBody->current->worldAxis * newOrigin - bodies[0]->current->worldOrigin ); + } else { + Translate( newOrigin - bodies[0]->current->worldOrigin ); + } +} + +/* +================ +idPhysics_AF::SetAxis +================ +*/ +void idPhysics_AF::SetAxis( const idMat3 &newAxis, int id ) { + idMat3 axis; + idRotation rotation; + + if ( masterBody ) { + axis = bodies[0]->current->worldAxis.Transpose() * ( newAxis * masterBody->current->worldAxis ); + } else { + axis = bodies[0]->current->worldAxis.Transpose() * newAxis; + } + rotation = axis.ToRotation(); + rotation.SetOrigin( bodies[0]->current->worldOrigin ); + + Rotate( rotation ); +} + +/* +================ +idPhysics_AF::Translate +================ +*/ +void idPhysics_AF::Translate( const idVec3 &translation, int id ) { + int i; + idAFBody *body; + + if ( !worldConstraintsLocked ) { + // translate constraints attached to the world + for ( i = 0; i < constraints.Num(); i++ ) { + constraints[i]->Translate( translation ); + } + } + + // translate all the bodies + for ( i = 0; i < bodies.Num(); i++ ) { + + body = bodies[i]; + body->current->worldOrigin += translation; + } + + Activate(); + + UpdateClipModels(); +} + +/* +================ +idPhysics_AF::Rotate +================ +*/ +void idPhysics_AF::Rotate( const idRotation &rotation, int id ) { + int i; + idAFBody *body; + + // ishtvan: Stop the stretching error due to too many + // mat3 to rotation to mat3 conversions + idRotation rotationC = rotation; + rotationC.ReCalculateMatrix(); + + if ( !worldConstraintsLocked ) { + // rotate constraints attached to the world + for ( i = 0; i < constraints.Num(); i++ ) { + constraints[i]->Rotate( rotationC ); + } + } + + // rotate all the bodies + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + body->current->worldOrigin *= rotationC; + body->current->worldAxis *= rotationC.ToMat3(); + } + + Activate(); + + UpdateClipModels(); +} + +/* +================ +idPhysics_AF::GetOrigin +================ +*/ +const idVec3 &idPhysics_AF::GetOrigin( int id ) const { + if ( id < 0 || id >= bodies.Num() ) { + return vec3_origin; + } + else { + return bodies[id]->current->worldOrigin; + } +} + +/* +================ +idPhysics_AF::GetAxis +================ +*/ +const idMat3 &idPhysics_AF::GetAxis( int id ) const { + if ( id < 0 || id >= bodies.Num() ) { + return mat3_identity; + } + else { + return bodies[id]->current->worldAxis; + } +} + +/* +================ +idPhysics_AF::SetLinearVelocity +================ +*/ +void idPhysics_AF::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { + if ( id < 0 || id >= bodies.Num() ) { + return; + } + bodies[id]->current->spatialVelocity.SubVec3( 0 ) = newLinearVelocity; + Activate(); +} + +/* +================ +idPhysics_AF::SetAngularVelocity +================ +*/ +void idPhysics_AF::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { + if ( id < 0 || id >= bodies.Num() ) { + return; + } + bodies[id]->current->spatialVelocity.SubVec3( 1 ) = newAngularVelocity; + Activate(); +} + +/* +================ +idPhysics_AF::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_AF::GetLinearVelocity( int id ) const { + if ( id < 0 || id >= bodies.Num() ) { + return vec3_origin; + } + else { + return bodies[id]->current->spatialVelocity.SubVec3( 0 ); + } +} + +/* +================ +idPhysics_AF::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_AF::GetAngularVelocity( int id ) const { + if ( id < 0 || id >= bodies.Num() ) { + return vec3_origin; + } + else { + return bodies[id]->current->spatialVelocity.SubVec3( 1 ); + } +} + +/* +================ +idPhysics_AF::ClipTranslation +================ +*/ +void idPhysics_AF::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + int i; + idAFBody *body; + trace_t bodyResults; + + results.fraction = 1.0f; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->clipModel->IsTraceModel() ) { + if ( model ) { + gameLocal.clip.TranslationModel( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation, + body->clipModel, body->current->worldAxis, body->clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Translation( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation, + body->clipModel, body->current->worldAxis, body->clipMask, self ); + } + if ( bodyResults.fraction < results.fraction ) { + results = bodyResults; + } + } + } + + results.endpos = bodies[0]->current->worldOrigin + results.fraction * translation; + results.endAxis = bodies[0]->current->worldAxis; +} + +/* +================ +idPhysics_AF::ClipRotation +================ +*/ +void idPhysics_AF::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + int i; + idAFBody *body; + trace_t bodyResults; + idRotation partialRotation; + + results.fraction = 1.0f; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->clipModel->IsTraceModel() ) { + if ( model ) { + gameLocal.clip.RotationModel( bodyResults, body->current->worldOrigin, rotation, + body->clipModel, body->current->worldAxis, body->clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Rotation( bodyResults, body->current->worldOrigin, rotation, + body->clipModel, body->current->worldAxis, body->clipMask, self ); + } + if ( bodyResults.fraction < results.fraction ) { + results = bodyResults; + } + } + } + + partialRotation = rotation * results.fraction; + results.endpos = bodies[0]->current->worldOrigin * partialRotation; + results.endAxis = bodies[0]->current->worldAxis * partialRotation.ToMat3(); +} + +/* +================ +idPhysics_AF::ClipContents +================ +*/ +int idPhysics_AF::ClipContents( const idClipModel *model ) const { + int i, contents; + idAFBody *body; + + contents = 0; + + for ( i = 0; i < bodies.Num(); i++ ) { + body = bodies[i]; + + if ( body->clipModel->IsTraceModel() ) { + if ( model ) { + contents |= gameLocal.clip.ContentsModel( body->current->worldOrigin, + body->clipModel, body->current->worldAxis, -1, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + contents |= gameLocal.clip.Contents( body->current->worldOrigin, + body->clipModel, body->current->worldAxis, -1, NULL ); + } + } + } + + return contents; +} + +/* +================ +idPhysics_AF::DisableClip +================ +*/ +void idPhysics_AF::DisableClip( void ) { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->clipModel->Disable(); + } +} + +/* +================ +idPhysics_AF::EnableClip +================ +*/ +void idPhysics_AF::EnableClip( void ) { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->clipModel->Enable(); + } +} + +/* +================ +idPhysics_AF::UnlinkClip +================ +*/ +void idPhysics_AF::UnlinkClip( void ) { + int i; + + for ( i = 0; i < bodies.Num(); i++ ) { + bodies[i]->clipModel->Unlink(); + } +} + +/* +================ +idPhysics_AF::LinkClip +================ +*/ +void idPhysics_AF::LinkClip( void ) { + UpdateClipModels(); +} + +/* +================ +idPhysics_AF::SetPushed +================ +*/ +void idPhysics_AF::SetPushed( int deltaTime ) { + idAFBody *body; + idRotation rotation; + + if ( bodies.Num() ) { + body = bodies[0]; + rotation = ( body->saved.worldAxis.Transpose() * body->current->worldAxis ).ToRotation(); + + // velocity with which the af is pushed + current.pushVelocity.SubVec3(0) += ( body->current->worldOrigin - body->saved.worldOrigin ) / ( deltaTime * idMath::M_MS2SEC ); + current.pushVelocity.SubVec3(1) += rotation.GetVec() * -DEG2RAD( rotation.GetAngle() ) / ( deltaTime * idMath::M_MS2SEC ); + } +} + +/* +================ +idPhysics_AF::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_AF::GetPushedLinearVelocity( const int id ) const { + return current.pushVelocity.SubVec3(0); +} + +/* +================ +idPhysics_AF::GetPushedAngularVelocity +================ +*/ +const idVec3 &idPhysics_AF::GetPushedAngularVelocity( const int id ) const { + return current.pushVelocity.SubVec3(1); +} + +/* +================ +idPhysics_AF::SetMaster + + the binding is orientated based on the constraints being used +================ +*/ +void idPhysics_AF::SetMaster( idEntity *master, const bool orientated ) { + int i; + idVec3 masterOrigin; + idMat3 masterAxis; + idRotation rotation; + + if ( master ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + if ( !masterBody ) { + masterBody = new idAFBody(); + // translate and rotate all the constraints with body2 == NULL from world space to master space + rotation = masterAxis.Transpose().ToRotation(); + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->GetBody2() == NULL ) { + constraints[i]->Translate( -masterOrigin ); + constraints[i]->Rotate( rotation ); + } + } + Activate(); + } + masterBody->current->worldOrigin = masterOrigin; + masterBody->current->worldAxis = masterAxis; + } + else { + if ( masterBody ) { + // translate and rotate all the constraints with body2 == NULL from master space to world space + rotation = masterBody->current->worldAxis.ToRotation(); + for ( i = 0; i < constraints.Num(); i++ ) { + if ( constraints[i]->GetBody2() == NULL ) { + constraints[i]->Rotate( rotation ); + constraints[i]->Translate( masterBody->current->worldOrigin ); + } + } + delete masterBody; + masterBody = NULL; + Activate(); + } + } +} + + +const float AF_VELOCITY_MAX = 16000; +const int AF_VELOCITY_TOTAL_BITS = 16; +const int AF_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_VELOCITY_MAX ) ) + 1; +const int AF_VELOCITY_MANTISSA_BITS = AF_VELOCITY_TOTAL_BITS - 1 - AF_VELOCITY_EXPONENT_BITS; +const float AF_FORCE_MAX = 1e20f; +const int AF_FORCE_TOTAL_BITS = 16; +const int AF_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_FORCE_MAX ) ) + 1; +const int AF_FORCE_MANTISSA_BITS = AF_FORCE_TOTAL_BITS - 1 - AF_FORCE_EXPONENT_BITS; + +/* +================ +idPhysics_AF::WriteToSnapshot +================ +*/ +void idPhysics_AF::WriteToSnapshot( idBitMsgDelta &msg ) const { + int i; + idCQuat quat; + + msg.WriteLong( current.atRest ); + msg.WriteFloat( current.noMoveTime ); + msg.WriteFloat( current.activateTime ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + + msg.WriteByte( bodies.Num() ); + + for ( i = 0; i < bodies.Num(); i++ ) { + AFBodyPState_t *state = bodies[i]->current; + quat = state->worldAxis.ToCQuat(); + + msg.WriteFloat( state->worldOrigin[0] ); + msg.WriteFloat( state->worldOrigin[1] ); + msg.WriteFloat( state->worldOrigin[2] ); + msg.WriteFloat( quat.x ); + msg.WriteFloat( quat.y ); + msg.WriteFloat( quat.z ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); +/* msg.WriteDeltaFloat( 0.0f, state->externalForce[0], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->externalForce[1], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->externalForce[2], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->externalForce[3], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->externalForce[4], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, state->externalForce[5], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); +*/ + } +} + +/* +================ +idPhysics_AF::ReadFromSnapshot +================ +*/ +void idPhysics_AF::ReadFromSnapshot( const idBitMsgDelta &msg ) { + int i, num; + idCQuat quat; + + current.atRest = msg.ReadLong(); + current.noMoveTime = msg.ReadFloat(); + current.activateTime = msg.ReadFloat(); + current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + + num = msg.ReadByte(); + assert( num == bodies.Num() ); + + for ( i = 0; i < bodies.Num(); i++ ) { + AFBodyPState_t *state = bodies[i]->current; + + state->worldOrigin[0] = msg.ReadFloat(); + state->worldOrigin[1] = msg.ReadFloat(); + state->worldOrigin[2] = msg.ReadFloat(); + quat.x = msg.ReadFloat(); + quat.y = msg.ReadFloat(); + quat.z = msg.ReadFloat(); + state->spatialVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + state->spatialVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + state->spatialVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + state->spatialVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + state->spatialVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); + state->spatialVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); +/* state->externalForce[0] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + state->externalForce[1] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + state->externalForce[2] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + state->externalForce[3] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + state->externalForce[4] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); + state->externalForce[5] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); +*/ + state->worldAxis = quat.ToMat3(); + } + + UpdateClipModels(); +} +/* +================ +idPhysics_AF::NearestBodyOrig + +Linear search to find the body origin nearest to the given point +================ +*/ +idVec3 idPhysics_AF::NearestBodyOrig( idVec3 point, int *bodyID ) +{ + idVec3 bodyOrigin, delta, returnVec; + float tempDist; + float minDist = idMath::INFINITY; + int numBods(0), returnBody(-1); + + // return (0,0,0) if something unexpected happens + returnVec.Zero(); + + numBods = GetNumBodies(); + for( int i = 0; i < numBods; i++ ) + { + if( GetBody( i ) ) + { + bodyOrigin = GetBody( i )->GetWorldOrigin(); + delta = bodyOrigin - point; + + tempDist = delta.LengthSqr(); + if (tempDist < minDist) + { + minDist = tempDist; + returnVec = bodyOrigin; + returnBody = i; + } + } + } + + if( bodyID ) + *bodyID = returnBody; + + return returnVec; +} + +bool idPhysics_AF::HasGroundContacts( int id ) +{ + int numContacts; + idAFConstraint_Contact *contacts[5]; + bool bReturnVal(false); + idEntity *contactEnt(NULL); + + numContacts = GetBodyContactConstraints( id, contacts, 5 ); + + for ( int i = 0; i < numContacts; i++ ) + { + contactEnt = gameLocal.entities[ contacts[i]->GetContact().entityNum ]; + + if( contacts[i]->GetContact().normal * -gravityNormal > 0.0f + && contactEnt && contactEnt != self ) + { + bReturnVal = true; + goto Quit; + } + } + +Quit: + return bReturnVal; +} + +#ifdef MOD_WATERPHYSICS +/* +================ +idPhysics_AF::SetLiquidDensity +================ +*/ +void idPhysics_AF::SetLiquidDensity( float density ) +{ + this->liquidDensity = density; +} + +/* +================ +idPhysics_AF::GetLiquidDensity +================ +*/ +float idPhysics_AF::GetLiquidDensity() const +{ + return this->liquidDensity; +} + +/* +================ +idPhysics_AF::SetFixedDensityBuoyancy + This will reset the liquid density to the default value depending on the mode. +================ +*/ +void idPhysics_AF::SetFixedDensityBuoyancy( bool fixed ) +{ + this->fixedDensityBuoyancy = fixed; + if( this->fixedDensityBuoyancy ) + this->liquidDensity = DEFAULT_LIQUID_DENSITY; + else + this->liquidDensity = DEFAULT_LIQUID_SCALAR; +} + +/* +================ +idPhysics_AF::GetFixedDensityBuoyancy +================ +*/ +bool idPhysics_AF::GetFixedDensityBuoyancy() const +{ + return this->fixedDensityBuoyancy; +} +#endif diff --git a/game/physics/Physics_AF.h b/game/physics/Physics_AF.h new file mode 100644 index 000000000..a1cb46a81 --- /dev/null +++ b/game/physics/Physics_AF.h @@ -0,0 +1,1118 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_AF_H__ +#define __PHYSICS_AF_H__ + +/* +=================================================================================== + + Articulated Figure physics + + Employs a constraint force based dynamic simulation using a lagrangian + multiplier method to solve for the constraint forces. + +=================================================================================== +*/ + +class idAFConstraint; +class idAFConstraint_Fixed; +class idAFConstraint_BallAndSocketJoint; +class idAFConstraint_BallAndSocketJointFriction; +class idAFConstraint_UniversalJoint; +class idAFConstraint_UniversalJointFriction; +class idAFConstraint_CylindricalJoint; +class idAFConstraint_Hinge; +class idAFConstraint_HingeFriction; +class idAFConstraint_HingeSteering; +class idAFConstraint_Slider; +class idAFConstraint_Line; +class idAFConstraint_Plane; +class idAFConstraint_Spring; +class idAFConstraint_Contact; +class idAFConstraint_ContactFriction; +class idAFConstraint_ConeLimit; +class idAFConstraint_PyramidLimit; +class idAFConstraint_Suspension; +class idAFBody; +class idAFTree; +class idPhysics_AF; + +typedef enum { + CONSTRAINT_INVALID, + CONSTRAINT_FIXED, + CONSTRAINT_BALLANDSOCKETJOINT, + CONSTRAINT_UNIVERSALJOINT, + CONSTRAINT_HINGE, + CONSTRAINT_HINGESTEERING, + CONSTRAINT_SLIDER, + CONSTRAINT_CYLINDRICALJOINT, + CONSTRAINT_LINE, + CONSTRAINT_PLANE, + CONSTRAINT_SPRING, + CONSTRAINT_CONTACT, + CONSTRAINT_FRICTION, + CONSTRAINT_CONELIMIT, + CONSTRAINT_PYRAMIDLIMIT, + CONSTRAINT_SUSPENSION +} constraintType_t; + + +//=============================================================== +// +// idAFConstraint +// +//=============================================================== + +// base class for all constraints +class idAFConstraint { + + friend class idPhysics_AF; + friend class idAFTree; + +public: + idAFConstraint( void ); + virtual ~idAFConstraint( void ); + constraintType_t GetType( void ) const { return type; } + const idStr & GetName( void ) const { return name; } + idAFBody * GetBody1( void ) const { return body1; } + idAFBody * GetBody2( void ) const { return body2; } + void SetPhysics( idPhysics_AF *p ) { physics = p; } + const idVecX & GetMultiplier( void ); + virtual void SetBody1( idAFBody *body ); + virtual void SetBody2( idAFBody *body ); + virtual void DebugDraw( void ); + virtual void GetForce( idAFBody *body, idVec6 &force ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + constraintType_t type; // constraint type + idStr name; // name of constraint + idAFBody * body1; // first constrained body + idAFBody * body2; // second constrained body, NULL for world + idPhysics_AF * physics; // for adding additional constraints like limits + + // simulation variables set by Evaluate + idMatX J1, J2; // matrix with left hand side of constraint equations + idVecX c1, c2; // right hand side of constraint equations + idVecX lo, hi, e; // low and high bounds and lcp epsilon + idAFConstraint * boxConstraint; // constraint the boxIndex refers to + int boxIndex[6]; // indexes for special box constrained variables + + // simulation variables used during calculations + idMatX invI; // transformed inertia + idMatX J; // transformed constraint matrix + idVecX s; // temp solution + idVecX lm; // lagrange multipliers + int firstIndex; // index of the first constraint row in the lcp matrix + + struct constraintFlags_s { + bool allowPrimary : 1; // true if the constraint can be used as a primary constraint + bool frameConstraint : 1; // true if this constraint is added to the frame constraints + bool noCollision : 1; // true if body1 and body2 never collide with each other + bool isPrimary : 1; // true if this is a primary constraint + bool isZero : 1; // true if 's' is zero during calculations + } fl; + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); + void InitSize( int size ); +}; + +// fixed or rigid joint which allows zero degrees of freedom +// constrains body1 to have a fixed position and orientation relative to body2 +class idAFConstraint_Fixed : public idAFConstraint { + +public: + idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 ); + void SetRelativeOrigin( const idVec3 &origin ) { this->offset = origin; } + void SetRelativeAxis( const idMat3 &axis ) { this->relAxis = axis; } + virtual void SetBody1( idAFBody *body ); + virtual void SetBody2( idAFBody *body ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 offset; // offset of body1 relative to body2 in body2 space + idMat3 relAxis; // rotation of body1 relative to body2 + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); + void InitOffset( void ); +}; + +// ball and socket or spherical joint which allows 3 degrees of freedom +// constrains body1 relative to body2 with a ball and socket joint +class idAFConstraint_BallAndSocketJoint : public idAFConstraint { + +public: + idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); + ~idAFConstraint_BallAndSocketJoint( void ); + void SetAnchor( const idVec3 &worldPosition ); + idVec3 GetAnchor( void ) const; + void SetNoLimit( void ); + void SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ); + void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float angle1, const float angle2, const idVec3 &body1Axis ); + void SetLimitEpsilon( const float e ); + void SetFriction( const float f ) { friction = f; } + float GetFriction( void ) const; + virtual void DebugDraw( void ); + virtual void GetForce( idAFBody *body, idVec6 &force ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 anchor1; // anchor in body1 space + idVec3 anchor2; // anchor in body2 space + float friction; // joint friction + idAFConstraint_ConeLimit *coneLimit; // cone shaped limit + idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit + idAFConstraint_BallAndSocketJointFriction *fc; // friction constraint + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// ball and socket joint friction +class idAFConstraint_BallAndSocketJointFriction : public idAFConstraint { + +public: + idAFConstraint_BallAndSocketJointFriction( void ); + void Setup( idAFConstraint_BallAndSocketJoint *cc ); + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + idAFConstraint_BallAndSocketJoint *joint; + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// universal, Cardan or Hooke joint which allows 2 degrees of freedom +// like a ball and socket joint but also constrains the rotation about the cardan shafts +class idAFConstraint_UniversalJoint : public idAFConstraint { + +public: + idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); + ~idAFConstraint_UniversalJoint( void ); + void SetAnchor( const idVec3 &worldPosition ); + idVec3 GetAnchor( void ) const; + void SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 ); + void GetShafts( idVec3 &cardanShaft1, idVec3 &cardanShaft2 ) { cardanShaft1 = shaft1; cardanShaft2 = shaft2; } + void SetNoLimit( void ); + void SetConeLimit( const idVec3 &coneAxis, const float coneAngle ); + void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float angle1, const float angle2 ); + void SetLimitEpsilon( const float e ); + void SetFriction( const float f ) { friction = f; } + float GetFriction( void ) const; + virtual void DebugDraw( void ); + virtual void GetForce( idAFBody *body, idVec6 &force ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 anchor1; // anchor in body1 space + idVec3 anchor2; // anchor in body2 space + idVec3 shaft1; // body1 cardan shaft in body1 space + idVec3 shaft2; // body2 cardan shaft in body2 space + idVec3 axis1; // cardan axis in body1 space + idVec3 axis2; // cardan axis in body2 space + float friction; // joint friction + idAFConstraint_ConeLimit *coneLimit; // cone shaped limit + idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit + idAFConstraint_UniversalJointFriction *fc; // friction constraint + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// universal joint friction +class idAFConstraint_UniversalJointFriction : public idAFConstraint { + +public: + idAFConstraint_UniversalJointFriction( void ); + void Setup( idAFConstraint_UniversalJoint *cc ); + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + idAFConstraint_UniversalJoint *joint; // universal joint + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// cylindrical joint which allows 2 degrees of freedom +// constrains body1 to lie on a line relative to body2 and allows only translation along and rotation about the line +class idAFConstraint_CylindricalJoint : public idAFConstraint { + +public: + idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// hinge, revolute or pin joint which allows 1 degree of freedom +// constrains all motion of body1 relative to body2 except the rotation about the hinge axis +class idAFConstraint_Hinge : public idAFConstraint { + +public: + idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 ); + ~idAFConstraint_Hinge( void ); + void SetAnchor( const idVec3 &worldPosition ); + idVec3 GetAnchor( void ) const; + void SetAxis( const idVec3 &axis ); + void GetAxis( idVec3 &a1, idVec3 &a2 ) const { a1 = axis1; a2 = axis2; } + idVec3 GetAxis( void ) const; + void SetNoLimit( void ); + void SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis ); + void SetLimitEpsilon( const float e ); + float GetAngle( void ) const; + void SetSteerAngle( const float degrees ); + void SetSteerSpeed( const float speed ); + void SetFriction( const float f ) { friction = f; } + float GetFriction( void ) const; + virtual void DebugDraw( void ); + virtual void GetForce( idAFBody *body, idVec6 &force ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 anchor1; // anchor in body1 space + idVec3 anchor2; // anchor in body2 space + idVec3 axis1; // axis in body1 space + idVec3 axis2; // axis in body2 space + idMat3 initialAxis; // initial axis of body1 relative to body2 + float friction; // hinge friction + idAFConstraint_ConeLimit *coneLimit; // cone limit + idAFConstraint_HingeSteering *steering; // steering + idAFConstraint_HingeFriction *fc; // friction constraint + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// hinge joint friction +class idAFConstraint_HingeFriction : public idAFConstraint { + +public: + idAFConstraint_HingeFriction( void ); + void Setup( idAFConstraint_Hinge *cc ); + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + idAFConstraint_Hinge * hinge; // hinge + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// constrains two bodies attached to each other with a hinge to get a specified relative orientation +class idAFConstraint_HingeSteering : public idAFConstraint { + +public: + idAFConstraint_HingeSteering( void ); + void Setup( idAFConstraint_Hinge *cc ); + void SetSteerAngle( const float degrees ) { steerAngle = degrees; } + void SetSteerSpeed( const float speed ) { steerSpeed = speed; } + void SetEpsilon( const float e ) { epsilon = e; } + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idAFConstraint_Hinge * hinge; // hinge + float steerAngle; // desired steer angle in degrees + float steerSpeed; // steer speed + float epsilon; // lcp epsilon + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// slider, prismatic or translational constraint which allows 1 degree of freedom +// constrains body1 to lie on a line relative to body2, the orientation is also fixed relative to body2 +class idAFConstraint_Slider : public idAFConstraint { + +public: + idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 ); + void SetAxis( const idVec3 &ax ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 axis; // axis along which body1 slides in body2 space + idVec3 offset; // offset of body1 relative to body2 + idMat3 relAxis; // rotation of body1 relative to body2 + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// line constraint which allows 4 degrees of freedom +// constrains body1 to lie on a line relative to body2, does not constrain the orientation. +class idAFConstraint_Line : public idAFConstraint { + +public: + idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// plane constraint which allows 5 degrees of freedom +// constrains body1 to lie in a plane relative to body2, does not constrain the orientation. +class idAFConstraint_Plane : public idAFConstraint { + +public: + idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 ); + void SetPlane( const idVec3 &normal, const idVec3 &anchor ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 anchor1; // anchor in body1 space + idVec3 anchor2; // anchor in body2 space + idVec3 planeNormal; // plane normal in body2 space + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// spring constraint which allows 6 or 5 degrees of freedom based on the spring limits +// constrains body1 relative to body2 with a spring +class idAFConstraint_Spring : public idAFConstraint { + +public: + idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 ); + void SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 ); + void SetSpring( const float stretch, const float compress, const float damping, const float restLength ); + void SetLimit( const float minLength, const float maxLength ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 anchor1; // anchor in body1 space + idVec3 anchor2; // anchor in body2 space + float kstretch; // spring constant when stretched + float kcompress; // spring constant when compressed + float damping; // spring damping + float restLength; // rest length of spring + float minLength; // minimum spring length + float maxLength; // maximum spring length + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// constrains body1 to either be in contact with or move away from body2 +class idAFConstraint_Contact : public idAFConstraint { + +public: + idAFConstraint_Contact( void ); + ~idAFConstraint_Contact( void ); + void Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c ); + const contactInfo_t & GetContact( void ) const { return contact; } + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void GetCenter( idVec3 ¢er ); + +protected: + contactInfo_t contact; // contact information + idAFConstraint_ContactFriction *fc; // contact friction + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// contact friction +class idAFConstraint_ContactFriction : public idAFConstraint { + +public: + idAFConstraint_ContactFriction( void ); + void Setup( idAFConstraint_Contact *cc ); + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + idAFConstraint_Contact *cc; // contact constraint + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// constrains an axis attached to body1 to be inside a cone relative to body2 +class idAFConstraint_ConeLimit : public idAFConstraint { + +public: + idAFConstraint_ConeLimit( void ); + void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis, + const float coneAngle, const idVec3 &body1Axis ); + void SetAnchor( const idVec3 &coneAnchor ); + void SetBody1Axis( const idVec3 &body1Axis ); + void SetEpsilon( const float e ) { epsilon = e; } + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 coneAnchor; // top of the cone in body2 space + idVec3 coneAxis; // cone axis in body2 space + idVec3 body1Axis; // axis in body1 space that should stay within the cone + float cosAngle; // cos( coneAngle / 2 ) + float sinHalfAngle; // sin( coneAngle / 4 ) + float cosHalfAngle; // cos( coneAngle / 4 ) + float epsilon; // lcp epsilon + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// constrains an axis attached to body1 to be inside a pyramid relative to body2 +class idAFConstraint_PyramidLimit : public idAFConstraint { + +public: + idAFConstraint_PyramidLimit( void ); + void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor, + const idVec3 &pyramidAxis, const idVec3 &baseAxis, + const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis ); + void SetAnchor( const idVec3 &pyramidAxis ); + void SetBody1Axis( const idVec3 &body1Axis ); + void SetEpsilon( const float e ) { epsilon = e; } + bool Add( idPhysics_AF *phys, float invTimeStep ); + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + virtual void Save( idSaveGame *saveFile ) const; + virtual void Restore( idRestoreGame *saveFile ); + +protected: + idVec3 pyramidAnchor; // top of the pyramid in body2 space + idMat3 pyramidBasis; // pyramid basis in body2 space with base[2] being the pyramid axis + idVec3 body1Axis; // axis in body1 space that should stay within the cone + float cosAngle[2]; // cos( pyramidAngle / 2 ) + float sinHalfAngle[2]; // sin( pyramidAngle / 4 ) + float cosHalfAngle[2]; // cos( pyramidAngle / 4 ) + float epsilon; // lcp epsilon + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + +// vehicle suspension +class idAFConstraint_Suspension : public idAFConstraint { + +public: + idAFConstraint_Suspension( void ); + + void Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel ); + void SetSuspension( const float up, const float down, const float k, const float d, const float f ); + + void SetSteerAngle( const float degrees ) { steerAngle = degrees; } + void EnableMotor( const bool enable ) { motorEnabled = enable; } + void SetMotorForce( const float force ) { motorForce = force; } + void SetMotorVelocity( const float vel ) { motorVelocity = vel; } + void SetEpsilon( const float e ) { epsilon = e; } + const idVec3 GetWheelOrigin( void ) const; + + virtual void DebugDraw( void ); + virtual void Translate( const idVec3 &translation ); + virtual void Rotate( const idRotation &rotation ); + +protected: + idVec3 localOrigin; // position of suspension relative to body1 + idMat3 localAxis; // orientation of suspension relative to body1 + float suspensionUp; // suspension up movement + float suspensionDown; // suspension down movement + float suspensionKCompress; // spring compress constant + float suspensionDamping; // spring damping + float steerAngle; // desired steer angle in degrees + float friction; // friction + bool motorEnabled; // whether the motor is enabled or not + float motorForce; // motor force + float motorVelocity; // desired velocity + idClipModel * wheelModel; // wheel model + idVec3 wheelOffset; // wheel position relative to body1 + trace_t trace; // contact point with the ground + float epsilon; // lcp epsilon + +protected: + virtual void Evaluate( float invTimeStep ); + virtual void ApplyFriction( float invTimeStep ); +}; + + +//=============================================================== +// +// idAFBody +// +//=============================================================== + +typedef struct AFBodyPState_s { + idVec3 worldOrigin; // position in world space + idMat3 worldAxis; // axis at worldOrigin + idVec6 spatialVelocity; // linear and rotational velocity of body + idVec6 externalForce; // external force and torque applied to body +} AFBodyPState_t; + + +class idAFBody { + + friend class idPhysics_AF; + friend class idAFTree; + +public: + idAFBody( void ); + idAFBody( const idStr &name, idClipModel *clipModel, float density ); + ~idAFBody( void ); + + void Init( void ); + const idStr & GetName( void ) const { return name; } + const idVec3 & GetWorldOrigin( void ) const { return current->worldOrigin; } + const idMat3 & GetWorldAxis( void ) const { return current->worldAxis; } + const idVec3 & GetLinearVelocity( void ) const { return current->spatialVelocity.SubVec3(0); } + const idVec3 & GetAngularVelocity( void ) const { return current->spatialVelocity.SubVec3(1); } + idVec3 GetPointVelocity( const idVec3 &point ) const; + const idVec3 & GetCenterOfMass( void ) const { return centerOfMass; } + void SetClipModel( idClipModel *clipModel ); + idClipModel * GetClipModel( void ) const { return clipModel; } + void SetClipMask( const int mask ) { clipMask = mask; fl.clipMaskSet = true; } + int GetClipMask( void ) const { return clipMask; } + void SetSelfCollision( const bool enable ) { fl.selfCollision = enable; } + void SetWorldOrigin( const idVec3 &origin ) { current->worldOrigin = origin; } + void SetWorldAxis( const idMat3 &axis ) { current->worldAxis = axis; } + void SetLinearVelocity( const idVec3 &linear ) const { current->spatialVelocity.SubVec3(0) = linear; } + void SetAngularVelocity( const idVec3 &angular ) const { current->spatialVelocity.SubVec3(1) = angular; } + void SetFriction( float linear, float angular, float contact ); + float GetContactFriction( void ) const { return contactFriction; } + void SetBouncyness( float bounce ); + float GetBouncyness( void ) const { return bouncyness; } + void SetDensity( float density, const idMat3 &inertiaScale = mat3_identity ); + float GetInverseMass( void ) const { return invMass; } + idMat3 GetInverseWorldInertia( void ) const { return current->worldAxis.Transpose() * inverseInertiaTensor * current->worldAxis; } + void SetFrictionDirection( const idVec3 &dir ); + bool GetFrictionDirection( idVec3 &dir ) const; + +#ifdef MOD_WATERPHYSICS + float GetVolume( void ) const { return volume; } + // returns the depth of the object in the water + // 0.0f if out of water + float GetWaterLevel() const; // MOD_WATERPHYSICS + float SetWaterLevel( idPhysics_Liquid *l, const idVec3 &gravityNormal, bool fixedDensityBuoyancy ); // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS` + + void SetContactMotorDirection( const idVec3 &dir ); + bool GetContactMotorDirection( idVec3 &dir ) const; + void SetContactMotorVelocity( float vel ) { contactMotorVelocity = vel; } + float GetContactMotorVelocity( void ) const { return contactMotorVelocity; } + void SetContactMotorForce( float force ) { contactMotorForce = force; } + float GetContactMotorForce( void ) const { return contactMotorForce; } + + void AddForce( const idVec3 &point, const idVec3 &force ); + void InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const; + idVec6 & GetResponseForce( int index ) { return reinterpret_cast(response[ index * 8 ]); } + + /** + * Get or set the entity that stims and damage are routed to + **/ + void SetRerouteEnt( idEntity *ent ); + idEntity * GetRerouteEnt( void ); + + void Save( idSaveGame *saveFile ); + void Restore( idRestoreGame *saveFile ); + +private: + // properties + idStr name; // name of body + idAFBody * parent; // parent of this body + idList children; // children of this body + idClipModel * clipModel; // model used for collision detection + /** + * Entity to reroute damage and stims to, used when dynamically adding ents to an AF + * Defaults to NULL + **/ + idEntityPtr m_RerouteEnt; + idAFConstraint * primaryConstraint; // primary constraint (this->constraint->body1 = this) + idListconstraints; // all constraints attached to this body + idAFTree * tree; // tree structure this body is part of + float linearFriction; // translational friction + float angularFriction; // rotational friction + float contactFriction; // friction with contact surfaces + float bouncyness; // bounce +#ifdef MOD_WATERPHYSICS + float volume; // volume of body MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + int clipMask; // contents this body collides with + idVec3 frictionDir; // specifies a single direction of friction in body space + idVec3 contactMotorDir; // contact motor direction + float contactMotorVelocity; // contact motor velocity + float contactMotorForce; // maximum force applied to reach the motor velocity + + // derived properties + float mass; // mass of body + float invMass; // inverse mass +#ifdef MOD_WATERPHYSICS + float liquidMass; // mass of object in a liquid MOD_WATERPHYSICS + float invLiquidMass; // inverse liquid mass MOD_WATERPHYSICS + float waterLevel; // percent of body in water MOD_WATERPHYSICS + float m_fWaterMurkiness; // Tels: murkiness of the water body this entity is in +#endif // MOD_WATERPHYSICS + idVec3 centerOfMass; // center of mass of body + idMat3 inertiaTensor; // inertia tensor + idMat3 inverseInertiaTensor; // inverse inertia tensor + + // physics state + AFBodyPState_t state[2]; + AFBodyPState_t * current; // current physics state + AFBodyPState_t * next; // next physics state + AFBodyPState_t saved; // saved physics state + idVec3 atRestOrigin; // origin at rest + idMat3 atRestAxis; // axis at rest + + // simulation variables used during calculations + idMatX inverseWorldSpatialInertia; // inverse spatial inertia in world space + idMatX I, invI; // transformed inertia + idMatX J; // transformed constraint matrix + idVecX s; // temp solution + idVecX totalForce; // total force acting on body + idVecX auxForce; // force from auxiliary constraints + idVecX acceleration; // acceleration + float * response; // forces on body in response to auxiliary constraint forces + int * responseIndex; // index to response forces + int numResponses; // number of response forces + int maxAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body + int maxSubTreeAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body or one of it's children + + struct bodyFlags_s { + bool clipMaskSet : 1; // true if this body has a clip mask set + bool selfCollision : 1; // true if this body can collide with other bodies of this AF + bool spatialInertiaSparse: 1; // true if the spatial inertia matrix is sparse + bool useFrictionDir : 1; // true if a single friction direction should be used + bool useContactMotorDir : 1; // true if a contact motor should be used + bool isZero : 1; // true if 's' is zero during calculations + } fl; +}; + + +//=============================================================== +// +// idAFTree +// +//=============================================================== + +class idAFTree { + friend class idPhysics_AF; + +public: + void Factor( void ) const; + void Solve( int auxiliaryIndex = 0 ) const; + void Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const; + void CalculateForces( float timeStep ) const; + void SetMaxSubTreeAuxiliaryIndex( void ); + void SortBodies( void ); + void SortBodies_r( idList&sortedList, idAFBody *body ); + void DebugDraw( const idVec4 &color ) const; + +private: + idList sortedBodies; +}; + + +//=============================================================== +// +// idPhysics_AF +// +//=============================================================== + +typedef struct AFPState_s { + int atRest; // >= 0 if articulated figure is at rest + float noMoveTime; // time the articulated figure is hardly moving + float activateTime; // time since last activation + float lastTimeStep; // last time step + idVec6 pushVelocity; // velocity with which the af is pushed +} AFPState_t; + +typedef struct AFCollision_s { + trace_t trace; + idAFBody * body; +} AFCollision_t; + + +class idPhysics_AF : public idPhysics_Base { + +public: + CLASS_PROTOTYPE( idPhysics_AF ); + + idPhysics_AF( void ); + ~idPhysics_AF( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // initialisation + int AddBody( idAFBody *body ); // returns body id + void AddConstraint( idAFConstraint *constraint ); + void AddFrameConstraint( idAFConstraint *constraint ); + // force a body to have a certain id + void ForceBodyId( idAFBody *body, int newId ); + // get body or constraint id + int GetBodyId( idAFBody *body ) const; + int GetBodyId( const char *bodyName ) const; + int GetConstraintId( idAFConstraint *constraint ) const; + int GetConstraintId( const char *constraintName ) const; + // number of bodies and constraints + int GetNumBodies( void ) const; + int GetNumConstraints( void ) const; + // retrieve body or constraint + idAFBody * GetBody( const char *bodyName ) const; + idAFBody * GetBody( const int id ) const; + idAFBody * GetMasterBody( void ) const { return masterBody; } + idAFConstraint * GetConstraint( const char *constraintName ) const; + idAFConstraint * GetConstraint( const int id ) const; + // delete body or constraint + void DeleteBody( const char *bodyName ); + void DeleteBody( const int id ); + void DeleteConstraint( const char *constraintName ); + void DeleteConstraint( const int id ); + // get all the contact constraints acting on the body + int GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const; + // set the default friction for bodies + void SetDefaultFriction( float linear, float angular, float contact ); + // suspend settings + void SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration ); + // set the time and tolerances used to determine if the simulation can be suspended when the figure hardly moves for a while + void SetSuspendTolerance( const float noMoveTime, const float translationTolerance, const float rotationTolerance ); + // set minimum and maximum simulation time in seconds + void SetSuspendTime( const float minTime, const float maxTime ); + // set the time scale value + void SetTimeScale( const float ts ) { timeScale = ts; } + // set time scale ramp + void SetTimeScaleRamp( const float start, const float end ); + // set the joint friction scale + void SetJointFrictionScale( const float scale ) { jointFrictionScale = scale; } + // set joint friction dent + void SetJointFrictionDent( const float dent, const float start, const float end ); + // get the current joint friction scale + float GetJointFrictionScale( void ) const; + // set the contact friction scale + void SetContactFrictionScale( const float scale ) { contactFrictionScale = scale; } + // set contact friction dent + void SetContactFrictionDent( const float dent, const float start, const float end ); + // get the current contact friction scale + float GetContactFrictionScale( void ) const; + // enable or disable collision detection + void SetCollision( const bool enable ) { enableCollision = enable; } + // enable or disable self collision + void SetSelfCollision( const bool enable ) { selfCollision = enable; } + // enable or disable coming to a dead stop + void SetComeToRest( bool enable ) { comeToRest = enable; } + // call when structure of articulated figure changes + void SetChanged( void ) { changedAF = true; } + // enable/disable activation by impact + void EnableImpact( void ); + void DisableImpact( void ); + // lock of unlock the world constraints + void LockWorldConstraints( const bool lock ) { worldConstraintsLocked = lock; } + // set force pushable + void SetForcePushable( const bool enable ) { forcePushable = enable; } + // update the clip model positions + void UpdateClipModels( void ); + /** +* DarkMod: +* Returns the origin of the AF body nearest to the given point +* +* If int pointer body is non-NULL, the body Id of the nearest body is written +* to this pointer. Will be set to -1 if no body was found. +**/ +idVec3 NearestBodyOrig( idVec3 point, int *bodyID = NULL ); + /** +* Returns true if the specified body is in contact with the ground +* (Called by the rope climbing code) +**/ +bool HasGroundContacts( int id ); +#ifdef MOD_WATERPHYSICS + // buoyancy stuff + void SetLiquidDensity( float density ); // MOD_WATERPHYSICS + float GetLiquidDensity() const; // MOD_WATERPHYSICS + // this will reset liquidDensity so be careful when using it + void SetFixedDensityBuoyancy( bool fixed ); // MOD_WATERPHYSICS + bool GetFixedDensityBuoyancy() const; // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + + +public: // common physics interface + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + void AddForce( const int id, const idVec3 &point, const idVec3 &force ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + void Activate( void ); + void PutToRest( void ); + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated = true ); + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + /** + * TDM: Had to make this public so we could call it earlier than intended + **/ + void BuildTrees( void ); + + /** + * Get/Set the number of original bodies or constraints + * These are constraints that are added by this entity's AF only, not ones that are attached later + **/ + int GetNumOrigBodies( void ) { return m_NumOrigBodies; }; + void SetNumOrigBodies( int num ) { m_NumOrigBodies = num; }; + int GetNumOrigConstraints( void ) { return m_NumOrigConstraints; }; + void SetNumOrigConstraints( int num ) { m_NumOrigConstraints = num; }; + +private: + // articulated figure + idList trees; // tree structures + idList bodies; // all bodies + idListconstraints; // all frame independent constraints + idListprimaryConstraints; // list with primary constraints + idListauxiliaryConstraints; // list with auxiliary constraints + idListframeConstraints; // constraints that only live one frame + idListcontactConstraints; // contact constraints + idList contactBodies; // body id for each contact + idList collisions; // collisions + bool changedAF; // true when the articulated figure just changed + + /** + * TDM: Number of _original_ bodies from the loaded AF file + * We need this to implement a hack where added bodies aren't saved/loaded, + * because they will be added again from scratch on restore. + * We must do this because Id chose to re-load the AFs instead of restore them + **/ + int m_NumOrigBodies; + /** + * Number of original constraints loaded from this entity's AF file + **/ + int m_NumOrigConstraints; + + // properties + float linearFriction; // default translational friction + float angularFriction; // default rotational friction + float contactFriction; // default friction with contact surfaces + float bouncyness; // default bouncyness + float totalMass; // total mass of articulated figure + float forceTotalMass; // force this total mass + + idVec2 suspendVelocity; // simulation may not be suspended if a body has more velocity + idVec2 suspendAcceleration; // simulation may not be suspended if a body has more acceleration + float noMoveTime; // suspend simulation if hardly any movement for this many seconds + float noMoveTranslation; // maximum translation considered no movement + float noMoveRotation; // maximum rotation considered no movement + float minMoveTime; // if > 0 the simulation is never suspended before running this many seconds + float maxMoveTime; // if > 0 the simulation is always suspeded after running this many seconds + float impulseThreshold; // threshold below which impulses are ignored to avoid continuous activation + + float timeScale; // the time is scaled with this value for slow motion effects + float timeScaleRampStart; // start of time scale change + float timeScaleRampEnd; // end of time scale change + + float jointFrictionScale; // joint friction scale + float jointFrictionDent; // joint friction dives from 1 to this value and goes up again + float jointFrictionDentStart; // start time of joint friction dent + float jointFrictionDentEnd; // end time of joint friction dent + float jointFrictionDentScale; // dent scale + + float contactFrictionScale; // contact friction scale + float contactFrictionDent; // contact friction dives from 1 to this value and goes up again + float contactFrictionDentStart; // start time of contact friction dent + float contactFrictionDentEnd; // end time of contact friction dent + float contactFrictionDentScale; // dent scale + + bool enableCollision; // if true collision detection is enabled + bool selfCollision; // if true the self collision is allowed + bool comeToRest; // if true the figure can come to rest + bool linearTime; // if true use the linear time algorithm + bool noImpact; // if true do not activate when another object collides + bool worldConstraintsLocked; // if true world constraints cannot be moved + bool forcePushable; // if true can be pushed even when bound to a master + + // physics state + AFPState_t current; + AFPState_t saved; +#ifdef MOD_WATERPHYSICS +// treats liquid Density as THE density for each body when the AF is in liquid. +// otherwise liquidDensity is just a gravity scalar for the AF in any liquid. + bool fixedDensityBuoyancy; // MOD_WATERPHYSICS + float liquidDensity; // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + + idAFBody * masterBody; // master body + idLCP * lcp; // linear complementarity problem solver + +private: + bool IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const; + void PrimaryFactor( void ); + void EvaluateBodies( float timeStep ); + void EvaluateConstraints( float timeStep ); + void AddFrameConstraints( void ); + void RemoveFrameConstraints( void ); + void ApplyFriction( float timeStep, float endTimeMSec ); + void PrimaryForces( float timeStep ); + void AuxiliaryForces( float timeStep ); + void VerifyContactConstraints( void ); + void SetupContactConstraints( void ); + void ApplyContactForces( void ); + void Evolve( float timeStep ); + idEntity * SetupCollisionForBody( idAFBody *body ) const; + bool CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision ); + bool ApplyCollisions( float timeStep ); + void CheckForCollisions( float timeStep ); + void ClearExternalForce( void ); + void AddGravity( void ); + void SwapStates( void ); + bool TestIfAtRest( float timeStep ); + void Rest( void ); + void AddPushVelocity( const idVec6 &pushVelocity ); + void DebugDraw( void ); +}; + +#endif /* !__PHYSICS_AF_H__ */ diff --git a/game/physics/Physics_Actor.cpp b/game/physics/Physics_Actor.cpp new file mode 100644 index 000000000..2dc245f8f --- /dev/null +++ b/game/physics/Physics_Actor.cpp @@ -0,0 +1,491 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics_Base, idPhysics_Actor ) +END_CLASS + +/* +================ +idPhysics_Actor::idPhysics_Actor +================ +*/ +idPhysics_Actor::idPhysics_Actor( void ) { + clipModel = NULL; + SetClipModelAxis(); + mass = 100.0f; + invMass = 1.0f / mass; + masterEntity = NULL; + masterYaw = 0.0f; + masterDeltaYaw = 0.0f; + groundEntityPtr = NULL; + +#ifdef MOD_WATERPHYSICS + waterLevel = WATERLEVEL_NONE; // MOD_WATERPHYSICS + waterType = 0; // MOD_WATERPHYSICS + waterLevelChanged = true; + submerseFrame = 0; + submerseTime = -1; +#endif // MOD_WATERPHYSICS +} + +/* +================ +idPhysics_Actor::~idPhysics_Actor +================ +*/ +idPhysics_Actor::~idPhysics_Actor( void ) { + if ( clipModel ) { + delete clipModel; + clipModel = NULL; + } +} + +/* +================ +idPhysics_Actor::Save +================ +*/ +void idPhysics_Actor::Save( idSaveGame *savefile ) const { + + savefile->WriteClipModel( clipModel ); + savefile->WriteMat3( clipModelAxis ); + + savefile->WriteFloat( mass ); + savefile->WriteFloat( invMass ); + + savefile->WriteObject( masterEntity ); + savefile->WriteFloat( masterYaw ); + savefile->WriteFloat( masterDeltaYaw ); + +#ifdef MOD_WATERPHYSICS + savefile->WriteInt( (int)waterLevel ); // MOD_WATERPHYSICS + savefile->WriteInt((int)previousWaterLevel); + savefile->WriteInt( waterType ); // MOD_WATERPHYSICS + savefile->WriteBool(waterLevelChanged); + savefile->WriteInt(submerseFrame); + savefile->WriteInt(submerseTime); +#endif // MOD_WATERPHYSICS + + groundEntityPtr.Save( savefile ); +} + +/* +================ +idPhysics_Actor::Restore +================ +*/ +void idPhysics_Actor::Restore( idRestoreGame *savefile ) { + + savefile->ReadClipModel( clipModel ); + savefile->ReadMat3( clipModelAxis ); + + savefile->ReadFloat( mass ); + savefile->ReadFloat( invMass ); + + savefile->ReadObject( reinterpret_cast( masterEntity ) ); + savefile->ReadFloat( masterYaw ); + savefile->ReadFloat( masterDeltaYaw ); + +#ifdef MOD_WATERPHYSICS + savefile->ReadInt( (int &)waterLevel ); // MOD_WATERPHYSICS + savefile->ReadInt( (int &)previousWaterLevel ); + savefile->ReadInt( waterType ); // MOD_WATERPHYSICS + savefile->ReadBool(waterLevelChanged); + savefile->ReadInt(submerseFrame); + savefile->ReadInt(submerseTime); +#endif // MOD_WATERPHYSICS + + groundEntityPtr.Restore( savefile ); +} + +/* +================ +idPhysics_Actor::SetClipModelAxis +================ +*/ +void idPhysics_Actor::SetClipModelAxis( void ) { + // align clip model to gravity direction + if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) { + clipModelAxis.Identity(); + } + else { + clipModelAxis[2] = -gravityNormal; + clipModelAxis[2].NormalVectors( clipModelAxis[0], clipModelAxis[1] ); + clipModelAxis[1] = -clipModelAxis[1]; + } + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); + } +} + +/* +================ +idPhysics_Actor::GetGravityAxis +================ +*/ +const idMat3 &idPhysics_Actor::GetGravityAxis( void ) const { + return clipModelAxis; +} + +/* +================ +idPhysics_Actor::GetMasterDeltaYaw +================ +*/ +float idPhysics_Actor::GetMasterDeltaYaw( void ) const { + return masterDeltaYaw; +} + +/* +================ +idPhysics_Actor::GetGroundEntity +================ +*/ +idEntity *idPhysics_Actor::GetGroundEntity( void ) const { + return groundEntityPtr.GetEntity(); +} + +/* +================ +idPhysics_Actor::SetClipModel +================ +*/ +void idPhysics_Actor::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) { + assert( self ); + assert( model ); // a clip model is required + assert( model->IsTraceModel() ); // and it should be a trace model + assert( density > 0.0f ); // density should be valid + + if ( clipModel && clipModel != model && freeOld ) { + delete clipModel; + } + clipModel = model; + clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); +} + +/* +================ +idPhysics_Actor::GetClipModel +================ +*/ +idClipModel *idPhysics_Actor::GetClipModel( int id ) const { + return clipModel; +} + +/* +================ +idPhysics_Actor::GetNumClipModels +================ +*/ +int idPhysics_Actor::GetNumClipModels( void ) const { + return 1; +} + +/* +================ +idPhysics_Actor::SetMass +================ +*/ +void idPhysics_Actor::SetMass( float _mass, int id ) { + assert( _mass > 0.0f ); + mass = _mass; + invMass = 1.0f / _mass; +} + +/* +================ +idPhysics_Actor::GetMass +================ +*/ +float idPhysics_Actor::GetMass( int id ) const { + return mass; +} + +/* +================ +idPhysics_Actor::SetClipMask +================ +*/ +void idPhysics_Actor::SetContents( int contents, int id ) { + clipModel->SetContents( contents ); +} + +/* +================ +idPhysics_Actor::SetClipMask +================ +*/ +int idPhysics_Actor::GetContents( int id ) const { + return clipModel->GetContents(); +} + +/* +================ +idPhysics_Actor::GetBounds +================ +*/ +const idBounds &idPhysics_Actor::GetBounds( int id ) const { + return clipModel->GetBounds(); +} + +/* +================ +idPhysics_Actor::GetAbsBounds +================ +*/ +const idBounds &idPhysics_Actor::GetAbsBounds( int id ) const { + return clipModel->GetAbsBounds(); +} + +/* +================ +idPhysics_Actor::IsPushable +================ +*/ +bool idPhysics_Actor::IsPushable( void ) const { + return ( masterEntity == NULL ); +} + +/* +================ +idPhysics_Actor::GetOrigin +================ +*/ +const idVec3 &idPhysics_Actor::GetOrigin( int id ) const { + return clipModel->GetOrigin(); +} + +/* +================ +idPhysics_Player::GetAxis +================ +*/ +const idMat3 &idPhysics_Actor::GetAxis( int id ) const { + return clipModel->GetAxis(); +} + +/* +================ +idPhysics_Actor::SetGravity +================ +*/ +void idPhysics_Actor::SetGravity( const idVec3 &newGravity ) { + if ( newGravity != gravityVector ) { + idPhysics_Base::SetGravity( newGravity ); + SetClipModelAxis(); + } +} + +/* +================ +idPhysics_Actor::ClipTranslation +================ +*/ +void idPhysics_Actor::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, + clipModel, clipModel->GetAxis(), clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, + clipModel, clipModel->GetAxis(), clipMask, self ); + } +} + +/* +================ +idPhysics_Actor::ClipRotation +================ +*/ +void idPhysics_Actor::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation, + clipModel, clipModel->GetAxis(), clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, + clipModel, clipModel->GetAxis(), clipMask, self ); + } +} + +/* +================ +idPhysics_Actor::ClipContents +================ +*/ +int idPhysics_Actor::ClipContents( const idClipModel *model ) const { + if ( model ) { + return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); + } +} + +/* +================ +idPhysics_Actor::DisableClip +================ +*/ +void idPhysics_Actor::DisableClip( void ) { + clipModel->Disable(); +} + +/* +================ +idPhysics_Actor::EnableClip +================ +*/ +void idPhysics_Actor::EnableClip( void ) { + clipModel->Enable(); +} + +/* +================ +idPhysics_Actor::UnlinkClip +================ +*/ +void idPhysics_Actor::UnlinkClip( void ) { + clipModel->Unlink(); +} + +/* +================ +idPhysics_Actor::LinkClip +================ +*/ +void idPhysics_Actor::LinkClip( void ) { + clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModel->GetAxis() ); +} + +/* +================ +idPhysics_Actor::EvaluateContacts +================ +*/ +bool idPhysics_Actor::EvaluateContacts( void ) { + + // get all the ground contacts + ClearContacts(); + AddGroundContacts( clipModel ); + AddContactEntitiesForContacts(); + + return ( contacts.Num() != 0 ); +} + +#ifdef MOD_WATERPHYSICS +/* +============= +idPhysics_Actor::SetWaterLevel +============= +*/ +void idPhysics_Actor::SetWaterLevel( bool updateWaterLevelChanged ) { + // + // get waterlevel, accounting for ducking + // + // Remember the current water level + previousWaterLevel = waterLevel; + + waterLevel = WATERLEVEL_NONE; + waterType = 0; + + const idVec3& origin = this->GetOrigin(); + const idBounds& bounds = clipModel->GetBounds(); + + // check at feet level + idVec3 point = origin - ( bounds[0][2] + 1.0f ) * gravityNormal; + int contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + // sets water entity + this->SetWaterLevelf(); + + waterType = contents; + waterLevel = WATERLEVEL_FEET; + + // check at waist level + point = origin - ( bounds[1][2] - bounds[0][2] ) * 0.5f * gravityNormal; + contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + + waterLevel = WATERLEVEL_WAIST; + + // check at head level + // point = origin - ( bounds[1][2] - 1.0f ) * gravityNormal; + + // greebo: Changed the check for head level to test the eyeheight. This is enough + // for letting AI drown or for the player to "feel" underwater. + point = static_cast(self)->GetEyePosition(); + + contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + waterLevel = WATERLEVEL_HEAD; + } + } + } + else + this->SetWater(NULL, 0.0f); + + if (updateWaterLevelChanged) + { + // Set the changed flag + waterLevelChanged = (previousWaterLevel != waterLevel); + + if (waterLevel == WATERLEVEL_HEAD && waterLevelChanged) + { + submerseFrame = gameLocal.framenum; + submerseTime = gameLocal.time; + } + } +} + +/* +================ +idPhysics_Actor::GetWaterLevel +================ +*/ +waterLevel_t idPhysics_Actor::GetWaterLevel( void ) const { + return waterLevel; +} + +/* +================ +idPhysics_Actor::GetWaterType +================ +*/ +int idPhysics_Actor::GetWaterType( void ) const { + return waterType; +} + +int idPhysics_Actor::GetSubmerseTime() const +{ + return submerseTime; +} + +#endif // MOD_WATERPHYSICS diff --git a/game/physics/Physics_Actor.h b/game/physics/Physics_Actor.h new file mode 100644 index 000000000..9bee15682 --- /dev/null +++ b/game/physics/Physics_Actor.h @@ -0,0 +1,133 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_ACTOR_H__ +#define __PHYSICS_ACTOR_H__ + +/* +=================================================================================== + + Actor physics base class + + An actor typically uses one collision model which is aligned with the gravity + direction. The collision model is usually a simple box with the origin at the + bottom center. + +=================================================================================== +*/ + +#ifdef MOD_WATERPHYSICS +typedef enum { // MOD_WATERPHYSICS + WATERLEVEL_NONE, // MOD_WATERPHYSICS + WATERLEVEL_FEET, // MOD_WATERPHYSICS + WATERLEVEL_WAIST, // MOD_WATERPHYSICS + WATERLEVEL_HEAD // MOD_WATERPHYSICS +} waterLevel_t; // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + +class idPhysics_Actor : public idPhysics_Base { + +public: + CLASS_PROTOTYPE( idPhysics_Actor ); + + idPhysics_Actor( void ); + ~idPhysics_Actor( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // get delta yaw of master + float GetMasterDeltaYaw( void ) const; + // returns the ground entity + idEntity * GetGroundEntity( void ) const; + // align the clip model with the gravity direction + void SetClipModelAxis( void ); + +#ifdef MOD_WATERPHYSICS + virtual waterLevel_t GetWaterLevel( void ) const; // MOD_WATERPHYSICS + virtual int GetWaterType( void ) const; // MOD_WATERPHYSICS + + // greebo: returns the time we (last) submersed into water (above HEAD) + int GetSubmerseTime() const; +#endif + +public: // common physics interface + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool IsPushable( void ) const; + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetGravity( const idVec3 &newGravity ); + const idMat3 & GetGravityAxis( void ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + +protected: +#ifdef MOD_WATERPHYSICS + virtual void SetWaterLevel( bool updateWaterLevelChanged ); // MOD_WATERPHYSICS + waterLevel_t waterLevel; // MOD_WATERPHYSICS + waterLevel_t previousWaterLevel; // greebo: The water level of the previous frame + int waterType; // MOD_WATERPHYSICS + int submerseFrame; // greebo: The frame in which we submersed (above WATERLEVEL_HEAD) + int submerseTime; // greebo: The time we submersed (above WATERLEVEL_HEAD) + + // greebo: This is TRUE if the water level has changed since the last physics evaluation (frame) + bool waterLevelChanged; +#endif + + idClipModel * clipModel; // clip model used for collision detection + idMat3 clipModelAxis; // axis of clip model aligned with gravity direction + + // derived properties + float mass; + float invMass; + + // master + idEntity * masterEntity; + float masterYaw; + float masterDeltaYaw; + + // results of last evaluate + idEntityPtr groundEntityPtr; +}; + +#endif /* !__PHYSICS_ACTOR_H__ */ diff --git a/game/physics/Physics_Base.cpp b/game/physics/Physics_Base.cpp new file mode 100644 index 000000000..ec848a329 --- /dev/null +++ b/game/physics/Physics_Base.cpp @@ -0,0 +1,942 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics, idPhysics_Base ) +END_CLASS + +/* +================ +idPhysics_Base::idPhysics_Base +================ +*/ +idPhysics_Base::idPhysics_Base( void ) { + self = NULL; +#ifdef MOD_WATERPHYSICS + water = NULL; // MOD_WATERPHYSICS + m_fWaterMurkiness = 0.0f; +#endif // MOD_WATERPHYSICS + + clipMask = 0; + SetGravity( gameLocal.GetGravity() ); + ClearContacts(); +} + +/* +================ +idPhysics_Base::~idPhysics_Base +================ +*/ +idPhysics_Base::~idPhysics_Base( void ) { + if ( self && self->GetPhysics() == this ) { + self->SetPhysics( NULL ); + } + idForce::DeletePhysics( this ); + ClearContacts(); +} + +/* +================ +idPhysics_Base::Save +================ +*/ +void idPhysics_Base::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteObject( self ); + savefile->WriteInt( clipMask ); + savefile->WriteVec3( gravityVector ); + savefile->WriteVec3( gravityNormal ); + + savefile->WriteInt( contacts.Num() ); + for ( i = 0; i < contacts.Num(); i++ ) { + savefile->WriteContactInfo( contacts[i] ); + } + + savefile->WriteInt( contactEntities.Num() ); + for ( i = 0; i < contactEntities.Num(); i++ ) { + contactEntities[i].Save( savefile ); + } +} + +/* +================ +idPhysics_Base::Restore +================ +*/ +void idPhysics_Base::Restore( idRestoreGame *savefile ) { + int i, num; + + savefile->ReadObject( reinterpret_cast( self ) ); + savefile->ReadInt( clipMask ); + savefile->ReadVec3( gravityVector ); + savefile->ReadVec3( gravityNormal ); + + savefile->ReadInt( num ); + contacts.SetNum( num ); + for ( i = 0; i < contacts.Num(); i++ ) { + savefile->ReadContactInfo( contacts[i] ); + } + + savefile->ReadInt( num ); + contactEntities.SetNum( num ); + for ( i = 0; i < contactEntities.Num(); i++ ) { + contactEntities[i].Restore( savefile ); + } +} + +/* +================ +idPhysics_Base::SetSelf +================ +*/ +void idPhysics_Base::SetSelf( idEntity *e ) { + assert( e ); + self = e; +} + +/* +================ +idPhysics_Base::SetClipModel +================ +*/ +void idPhysics_Base::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { +} + +/* +================ +idPhysics_Base::GetClipModel +================ +*/ +idClipModel *idPhysics_Base::GetClipModel( int id ) const { + return NULL; +} + +/* +================ +idPhysics_Base::GetNumClipModels +================ +*/ +int idPhysics_Base::GetNumClipModels( void ) const { + return 0; +} + +/* +================ +idPhysics_Base::SetMass +================ +*/ +void idPhysics_Base::SetMass( float mass, int id ) { +} + +/* +================ +idPhysics_Base::GetMass +================ +*/ +float idPhysics_Base::GetMass( int id ) const { + return 0.0f; +} + +/* +================ +idPhysics_Base::SetContents +================ +*/ +void idPhysics_Base::SetContents( int contents, int id ) { +} + +/* +================ +idPhysics_Base::SetClipMask +================ +*/ +int idPhysics_Base::GetContents( int id ) const { + return 0; +} + +/* +================ +idPhysics_Base::SetClipMask +================ +*/ +void idPhysics_Base::SetClipMask( int mask, int id ) { + clipMask = mask; +} + +/* +================ +idPhysics_Base::GetClipMask +================ +*/ +int idPhysics_Base::GetClipMask( int id ) const { + return clipMask; +} + +/* +================ +idPhysics_Base::GetBounds +================ +*/ +const idBounds &idPhysics_Base::GetBounds( int id ) const { + return bounds_zero; +} + +/* +================ +idPhysics_Base::GetAbsBounds +================ +*/ +const idBounds &idPhysics_Base::GetAbsBounds( int id ) const { + return bounds_zero; +} + +/* +================ +idPhysics_Base::Evaluate +================ +*/ +bool idPhysics_Base::Evaluate( int timeStepMSec, int endTimeMSec ) { + return false; +} + +/* +================ +idPhysics_Base::UpdateTime +================ +*/ +void idPhysics_Base::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_Base::GetTime +================ +*/ +int idPhysics_Base::GetTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Base::GetImpactInfo +================ +*/ +void idPhysics_Base::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + memset( info, 0, sizeof( *info ) ); +} + +/* +================ +idPhysics_Base::ApplyImpulse +================ +*/ +void idPhysics_Base::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { +} + +// greebo: The default implementation of PropagateImpulse just applies the impulse +bool idPhysics_Base::PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ) { + ApplyImpulse(id, point, impulse); + return false; +} + +/* +================ +idPhysics_Base::AddForce +================ +*/ +void idPhysics_Base::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { +} + +/* +================ +idPhysics_Base::Activate +================ +*/ +void idPhysics_Base::Activate( void ) { +} + +/* +================ +idPhysics_Base::PutToRest +================ +*/ +void idPhysics_Base::PutToRest( void ) { +} + +/* +================ +idPhysics_Base::IsAtRest +================ +*/ +bool idPhysics_Base::IsAtRest( void ) const { + return true; +} + +/* +================ +idPhysics_Base::GetRestStartTime +================ +*/ +int idPhysics_Base::GetRestStartTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Base::IsPushable +================ +*/ +bool idPhysics_Base::IsPushable( void ) const { + return true; +} + +/* +================ +idPhysics_Base::SaveState +================ +*/ +void idPhysics_Base::SaveState( void ) { +} + +/* +================ +idPhysics_Base::RestoreState +================ +*/ +void idPhysics_Base::RestoreState( void ) { +} + +/* +================ +idPhysics_Base::SetOrigin +================ +*/ +void idPhysics_Base::SetOrigin( const idVec3 &newOrigin, int id ) { +} + +/* +================ +idPhysics_Base::SetAxis +================ +*/ +void idPhysics_Base::SetAxis( const idMat3 &newAxis, int id ) { +} + +/* +================ +idPhysics_Base::Translate +================ +*/ +void idPhysics_Base::Translate( const idVec3 &translation, int id ) { +} + +/* +================ +idPhysics_Base::Rotate +================ +*/ +void idPhysics_Base::Rotate( const idRotation &rotation, int id ) { +} + +/* +================ +idPhysics_Base::GetOrigin +================ +*/ +const idVec3 &idPhysics_Base::GetOrigin( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Base::GetAxis +================ +*/ +const idMat3 &idPhysics_Base::GetAxis( int id ) const { + return mat3_identity; +} + +/* +================ +idPhysics_Base::SetLinearVelocity +================ +*/ +void idPhysics_Base::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { +} + +/* +================ +idPhysics_Base::SetAngularVelocity +================ +*/ +void idPhysics_Base::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { +} + +/* +================ +idPhysics_Base::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_Base::GetLinearVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Base::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_Base::GetAngularVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Base::SetGravity +================ +*/ +void idPhysics_Base::SetGravity( const idVec3 &newGravity ) { + gravityVector = newGravity; + gravityNormal = newGravity; + gravityNormal.Normalize(); +} + +/* +================ +idPhysics_Base::GetGravity +================ +*/ +const idVec3 &idPhysics_Base::GetGravity( void ) const { + return gravityVector; +} + +/* +================ +idPhysics_Base::GetGravityNormal +================ +*/ +const idVec3 &idPhysics_Base::GetGravityNormal( void ) const { + return gravityNormal; +} + +/* +================ +idPhysics_Base::ClipTranslation +================ +*/ +void idPhysics_Base::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + memset( &results, 0, sizeof( trace_t ) ); +} + +/* +================ +idPhysics_Base::ClipRotation +================ +*/ +void idPhysics_Base::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + memset( &results, 0, sizeof( trace_t ) ); +} + +/* +================ +idPhysics_Base::ClipContents +================ +*/ +int idPhysics_Base::ClipContents( const idClipModel *model ) const { + return 0; +} + +/* +================ +idPhysics_Base::DisableClip +================ +*/ +void idPhysics_Base::DisableClip( void ) { +} + +/* +================ +idPhysics_Base::EnableClip +================ +*/ +void idPhysics_Base::EnableClip( void ) { +} + +/* +================ +idPhysics_Base::UnlinkClip +================ +*/ +void idPhysics_Base::UnlinkClip( void ) { +} + +/* +================ +idPhysics_Base::LinkClip +================ +*/ +void idPhysics_Base::LinkClip( void ) { +} + +/* +================ +idPhysics_Base::EvaluateContacts +================ +*/ +bool idPhysics_Base::EvaluateContacts( void ) { + return false; +} + +/* +================ +idPhysics_Base::GetNumContacts +================ +*/ +int idPhysics_Base::GetNumContacts( void ) const { + return contacts.Num(); +} + +/* +================ +idPhysics_Base::GetContact +================ +*/ +const contactInfo_t &idPhysics_Base::GetContact( int num ) const { + return contacts[num]; +} + +/* +================ +idPhysics_Base::ClearContacts +================ +*/ +void idPhysics_Base::ClearContacts( void ) { + int i; + idEntity *ent; + + for ( i = 0; i < contacts.Num(); i++ ) { + ent = gameLocal.entities[ contacts[i].entityNum ]; + if ( ent ) { + ent->RemoveContactEntity( self ); + } + } + contacts.SetNum( 0, false ); +} + +/* +================ +idPhysics_Base::AddContactEntity +================ +*/ +void idPhysics_Base::AddContactEntity( idEntity *e ) { + int i; + idEntity *ent; + bool found = false; + + for ( i = 0; i < contactEntities.Num(); i++ ) { + ent = contactEntities[i].GetEntity(); + if ( ent == NULL ) { + contactEntities.RemoveIndex( i-- ); + } + if ( ent == e ) { + found = true; + } + } + if ( !found ) { + contactEntities.Alloc() = e; + } +} + +/* +================ +idPhysics_Base::RemoveContactEntity +================ +*/ +void idPhysics_Base::RemoveContactEntity( idEntity *e ) { + int i; + idEntity *ent; + + for ( i = 0; i < contactEntities.Num(); i++ ) { + ent = contactEntities[i].GetEntity(); + if ( !ent ) { + contactEntities.RemoveIndex( i-- ); + continue; + } + if ( ent == e ) { + contactEntities.RemoveIndex( i-- ); + return; + } + } +} + +/* +================ +idPhysics_Base::HasGroundContacts +================ +*/ +bool idPhysics_Base::HasGroundContacts( void ) const { + int i; + + for ( i = 0; i < contacts.Num(); i++ ) { + if ( contacts[i].normal * -gravityNormal > 0.0f ) { + return true; + } + } + return false; +} + +/* +================ +idPhysics_Base::IsGroundEntity +================ +*/ +bool idPhysics_Base::IsGroundEntity( int entityNum ) const { + int i; + + for ( i = 0; i < contacts.Num(); i++ ) { + if ( contacts[i].entityNum == entityNum && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { + return true; + } + } + return false; +} + +/* +================ +idPhysics_Base::IsGroundClipModel +================ +*/ +bool idPhysics_Base::IsGroundClipModel( int entityNum, int id ) const { + int i; + + for ( i = 0; i < contacts.Num(); i++ ) { + if ( contacts[i].entityNum == entityNum && contacts[i].id == id && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { + return true; + } + } + return false; +} + +/* +================ +idPhysics_Base::SetPushed +================ +*/ +void idPhysics_Base::SetPushed( int deltaTime ) { +} + +/* +================ +idPhysics_Base::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_Base::GetPushedLinearVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Base::GetPushedAngularVelocity +================ +*/ +const idVec3 &idPhysics_Base::GetPushedAngularVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Base::SetMaster +================ +*/ +void idPhysics_Base::SetMaster( idEntity *master, const bool orientated ) { +} + +/* +================ +idPhysics_Base::GetBlockingInfo +================ +*/ +const trace_t *idPhysics_Base::GetBlockingInfo( void ) const { + return NULL; +} + +/* +================ +idPhysics_Base::GetBlockingEntity +================ +*/ +idEntity *idPhysics_Base::GetBlockingEntity( void ) const { + return NULL; +} + +/* +================ +idPhysics_Base::GetLinearEndTime +================ +*/ +int idPhysics_Base::GetLinearEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Base::GetAngularEndTime +================ +*/ +int idPhysics_Base::GetAngularEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Base::AddGroundContacts +================ +*/ +void idPhysics_Base::AddGroundContacts( const idClipModel *clipModel ) { + idVec6 dir; + int index, num; + + index = contacts.Num(); + contacts.SetNum( index + 10, false ); + + dir.SubVec3(0) = gravityNormal; + dir.SubVec3(1) = vec3_origin; + num = gameLocal.clip.Contacts( &contacts[index], 10, clipModel->GetOrigin(), + dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self ); + contacts.SetNum( index + num, false ); +} + +/* +================ +idPhysics_Base::AddContactEntitiesForContacts +================ +*/ +void idPhysics_Base::AddContactEntitiesForContacts( void ) { + int i; + idEntity *ent; + + for ( i = 0; i < contacts.Num(); i++ ) { + ent = gameLocal.entities[ contacts[i].entityNum ]; + if ( ent && ent != self ) { + ent->AddContactEntity( self ); + } + } +} + +/* +================ +idPhysics_Base::ActivateContactEntities +================ +*/ +void idPhysics_Base::ActivateContactEntities( void ) { + int i; + idEntity *ent; + + for ( i = 0; i < contactEntities.Num(); i++ ) { + ent = contactEntities[i].GetEntity(); + if ( ent ) { + ent->ActivatePhysics( self ); + } else { + contactEntities.RemoveIndex( i-- ); + } + } +} + +/* +================ +idPhysics_Base::IsOutsideWorld +================ +*/ +bool idPhysics_Base::IsOutsideWorld( void ) const { + if ( !gameLocal.clip.GetWorldBounds().Expand( 128.0f ).IntersectsBounds( GetAbsBounds() ) ) { + return true; + } + return false; +} + +/* +================ +idPhysics_Base::DrawVelocity +================ +*/ +void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const { + idVec3 dir, org, vec, start, end; + idMat3 axis; + float length, a; + + dir = GetLinearVelocity( id ); + dir *= linearScale; + if ( dir.LengthSqr() > Square( 0.1f ) ) { + dir.Truncate( 10.0f ); + org = GetOrigin( id ); + gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 ); + } + + dir = GetAngularVelocity( id ); + length = dir.Normalize(); + length *= angularScale; + if ( length > 0.1f ) { + if ( length < 60.0f ) { + length = 60.0f; + } + else if ( length > 360.0f ) { + length = 360.0f; + } + axis = GetAxis( id ); + vec = axis[2]; + if ( idMath::Fabs( dir * vec ) > 0.99f ) { + vec = axis[0]; + } + vec -= vec * dir * vec; + vec.Normalize(); + vec *= 4.0f; + start = org + vec; + for ( a = 20.0f; a < length; a += 20.0f ) { + end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec; + gameRenderWorld->DebugLine( colorBlue, start, end, 1 ); + start = end; + } + end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec; + gameRenderWorld->DebugArrow( colorBlue, start, end, 1 ); + } +} + +/* +================ +idPhysics_Base::WriteToSnapshot +================ +*/ +void idPhysics_Base::WriteToSnapshot( idBitMsgDelta &msg ) const { +} + +/* +================ +idPhysics_Base::ReadFromSnapshot +================ +*/ +void idPhysics_Base::ReadFromSnapshot( const idBitMsgDelta &msg ) { +} + +#ifdef MOD_WATERPHYSICS +/* +================ +idPhysics_Base::SetWater +================ +*/ +void idPhysics_Base::SetWater( idPhysics_Liquid *e, const float m ) { +/* + if (e != this->water) + { + if (NULL != e) + { + gameLocal.Printf("Entered water with murkiness %f.\n", m ); + } + else + { + gameLocal.Printf("Leaving water.\n"); + } + } +*/ + this->water = e; + this->m_fWaterMurkiness = m; +} + +/* +================ +idPhysics_Base::GetWater +================ +*/ +idPhysics_Liquid *idPhysics_Base::GetWater() +{ + return this->water; +} + +/* +================ +idPhysics_Base::GetWaterMurkiness +================ +*/ +float idPhysics_Base::GetWaterMurkiness() const +{ + return this->m_fWaterMurkiness; +} + +/* +================ +idPhysics_Base::SetWaterLevelf + + Returns 1.0f if the object is in a liquid, 0.0f otherwise. + + If the object's not in a liquid it double checks to make sure it's really not. + Normally we only set this->water when an object collides with a water material but + what happens if an object spawns inside a liquid or something? Nothing, it'll just sit + there. This function sets the water level for an object that's already inside the water. + + This was most noticeable when I had monsters walking into the water and of course, they'd + sink to the bottom. After I'd kill them they'd die normally and not float. After adding + this function they float after they're killed. + +================ +*/ +float idPhysics_Base::SetWaterLevelf() { + if( this->water == NULL ) { + idEntity *e[2]; + trace_t result; + idBounds bounds = this->GetBounds(); + + bounds += this->GetOrigin(); + + // trace for a water contact + // Tels: TODO This additional trace might be expensive because it is done every frame + if( gameLocal.clip.EntitiesTouchingBounds(bounds,MASK_WATER,e,2) ) { + if( e[0]->GetPhysics()->IsType(idPhysics_Liquid::Type) ) { + SetWater( static_cast(e[0]->GetPhysics()), e[0]->spawnArgs.GetFloat("murkiness", "0") ); + return 1.0f; + } + } + + this->m_fWaterMurkiness = 0.0f; + return 0.0f; + } + else + return 1.0f; +} + +/* +================ +idPhysics_Base::GetWaterLevelf + + The water level for this object, 0.0f if not in the water, 1.0f if in water +================ +*/ +float idPhysics_Base::GetWaterLevelf() const { + if( this->water == NULL ) + return 0.0f; + else + return 1.0f; +} + +#endif // MOD_WATERPHYSICS diff --git a/game/physics/Physics_Base.h b/game/physics/Physics_Base.h new file mode 100644 index 000000000..2834a8aab --- /dev/null +++ b/game/physics/Physics_Base.h @@ -0,0 +1,177 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_BASE_H__ +#define __PHYSICS_BASE_H__ + +/* +=============================================================================== + + Physics base for a moving object using one or more collision models. + +=============================================================================== +*/ + +#define contactEntity_t idEntityPtr + +class idPhysics_Base : public idPhysics { + +public: + CLASS_PROTOTYPE( idPhysics_Base ); + + idPhysics_Base( void ); + ~idPhysics_Base( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +public: // common physics interface + + virtual void SetSelf( idEntity *e ); +#ifdef MOD_WATERPHYSICS + idEntity *GetSelf() { return self; } // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + void SetClipMask( int mask, int id = -1 ); + int GetClipMask( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + bool PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ); + + void AddForce( const int id, const idVec3 &point, const idVec3 &force ); + void Activate( void ); + void PutToRest( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + void SetGravity( const idVec3 &newGravity ); + const idVec3 & GetGravity( void ) const; + const idVec3 & GetGravityNormal( void ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + int GetNumContacts( void ) const; + const contactInfo_t & GetContact( int num ) const; + void ClearContacts( void ); + void AddContactEntity( idEntity *e ); + void RemoveContactEntity( idEntity *e ); + + bool HasGroundContacts( void ) const; + bool IsGroundEntity( int entityNum ) const; + bool IsGroundClipModel( int entityNum, int id ) const; + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated = true ); + + const trace_t * GetBlockingInfo( void ) const; + idEntity * GetBlockingEntity( void ) const; + + int GetLinearEndTime( void ) const; + int GetAngularEndTime( void ) const; + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +#ifdef MOD_WATERPHYSICS + idPhysics_Liquid * GetWater(); // MOD_WATERPHYSICS + float GetWaterMurkiness() const; // TDM Tels + void SetWater( idPhysics_Liquid *e, const float murkiness ); // MOD_WATERPHYSICS + float SetWaterLevelf(); // MOD_WATERPHYSICS + float GetWaterLevelf() const; // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + +protected: + idEntity * self; // entity using this physics object + int clipMask; // contents the physics object collides with + idVec3 gravityVector; // direction and magnitude of gravity + idVec3 gravityNormal; // normalized direction of gravity + idList contacts; // contacts with other physics objects + idList contactEntities; // entities touching this physics object + +#ifdef MOD_WATERPHYSICS +// the water object the object is in, we use this to check density/viscosity + idPhysics_Liquid *water; // MOD_WATERPHYSICS +// TDM Tels: The murkiness of this water, 0 => clear as crystal, 1 => opaque + float m_fWaterMurkiness; +#endif + +protected: + // add ground contacts for the clip model + void AddGroundContacts( const idClipModel *clipModel ); + // add contact entity links to contact entities + void AddContactEntitiesForContacts( void ); + // active all contact entities + void ActivateContactEntities( void ); + // returns true if the whole physics object is outside the world bounds + bool IsOutsideWorld( void ) const; + // draw linear and angular velocity + void DrawVelocity( int id, float linearScale, float angularScale ) const; +}; + +#endif /* !__PHYSICS_BASE_H__ */ diff --git a/game/physics/Physics_Liquid.cpp b/game/physics/Physics_Liquid.cpp new file mode 100755 index 000000000..c12271b70 --- /dev/null +++ b/game/physics/Physics_Liquid.cpp @@ -0,0 +1,219 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#ifdef MOD_WATERPHYSICS + +CLASS_DECLARATION( idPhysics_Static, idPhysics_Liquid ) +END_CLASS + +/* +=============================================================================== + + idPhysics_Liquid + +=============================================================================== +*/ + +/* +================ +idPhysics_Liquid::idPhysics_Liquid +================ +*/ +idPhysics_Liquid::idPhysics_Liquid() { + + // initializes to a water-like liquid + this->density = 0.001043f; + this->viscosity = 3.0f; +} + +/* +================ +idPhysics_Liquid::~idPhysics_Liquid +================ +*/ +idPhysics_Liquid::~idPhysics_Liquid() { +} + +/* +================ +idPhysics_Liquid::Save +================ +*/ +void idPhysics_Liquid::Save( idSaveGame *savefile ) const +{ + savefile->WriteFloat(this->density); + savefile->WriteFloat(this->viscosity); + savefile->WriteVec3(this->minSplashVelocity); + savefile->WriteVec3(this->minWaveVelocity); +} + +/* +================ +idPhysics_Liquid::Restore +================ +*/ +void idPhysics_Liquid::Restore( idRestoreGame *savefile ) +{ + savefile->ReadFloat(this->density); + savefile->ReadFloat(this->viscosity); + savefile->ReadVec3(this->minSplashVelocity); + savefile->ReadVec3(this->minWaveVelocity); +} + +/* +================ +idPhysics_Liquid::GetDepth + Gets the depth of a point in the liquid. Returns -1 -1 -1 if the object is not in the liquid +================ +*/ +idVec3 idPhysics_Liquid::GetDepth( const idVec3 &point ) const { + const idBounds &bounds = this->GetBounds(); + idVec3 gravityNormal = this->GetGravityNormal(); + idVec3 depth(-1.0f,-1.0f,-1.0f); + + if( !this->isInLiquid(point) ) + return depth; + depth = (((bounds[1] + this->GetOrigin()) - point) * gravityNormal) * gravityNormal; + + return depth; +} + +/* +================ +idPhysics_Liquid::Splash + Causes the liquid to splash but only if the velocity is greater than minSplashVelocity +================ +*/ +void idPhysics_Liquid::Splash( idEntity *other, float volume, impactInfo_t &info, trace_t &collision ) { + collision.c.entityNum = other->entityNumber; + self->Collide(collision,info.velocity); +} + +/* +================ +idPhysics_Liquid::isInLiquid + Returns true if a point is in the liquid +================ +*/ +bool idPhysics_Liquid::isInLiquid( const idVec3 &point ) const { + bool result; + + result = (gameLocal.clip.Contents(point,NULL,mat3_identity,MASK_WATER,NULL) != 0); + return result; +} + +/* +================ +idPhysics_Liquid::GetPressure + Returns the amount of pressure the liquid applies to the given point +================ +*/ +idVec3 idPhysics_Liquid::GetPressure( const idVec3 &point ) const { + idVec3 pressure; + idVec3 depth = this->GetDepth(point); +//NJM idVec3 &depth = this->GetDepth(point); + + pressure = depth * this->density; + + return pressure; +} + +/* +================ +idPhysics_Liquid::GetDensity +================ +*/ +float idPhysics_Liquid::GetDensity() const { + return this->density; +} + +/* +================ +idPhysics_Liquid::SetDensity +================ +*/ +void idPhysics_Liquid::SetDensity( float density ) { + if( density > 0.0f ) + this->density = density; +} + +/* +================ +idPhysics_Liquid::GetViscosity +================ +*/ +float idPhysics_Liquid::GetViscosity() const { + return this->viscosity; +} + +/* +================ +idPhysics_Liquid::SetViscosity +================ +*/ +void idPhysics_Liquid::SetViscosity( float viscosity ) { + if( viscosity >= 0.0f ) + this->viscosity = viscosity; +} + +/* +================ +idPhysics_Liquid::GetMinSplashVelocity +================ +*/ +const idVec3 &idPhysics_Liquid::GetMinSplashVelocity() const { + return this->minSplashVelocity; +} + +/* +================ +idPhysics_Liquid::SetMinSplashVelocity +================ +*/ +void idPhysics_Liquid::SetMinSplashVelocity( const idVec3 &m ) { + this->minSplashVelocity = m; +} + +/* +================ +idPhysics_Liquid::GetMinWaveVelocity +================ +*/ +const idVec3 &idPhysics_Liquid::GetMinWaveVelocity() const { + return this->minWaveVelocity; +} + +/* +================ +idPhysics_Liquid::SetMinWaveVelocity +================ +*/ +void idPhysics_Liquid::SetMinWaveVelocity( const idVec3 &w ) { + this->minWaveVelocity = w; +} + +#endif + diff --git a/game/physics/Physics_Liquid.h b/game/physics/Physics_Liquid.h new file mode 100755 index 000000000..b40818527 --- /dev/null +++ b/game/physics/Physics_Liquid.h @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +=============================================================================== + + Physics object for a liquid. This class contains physics properties for a + given liquid. Note: Liquid does not necessarily imply water. + + This class does very little functionally as it relies on the other physics + classes to do the bouoyancy calculations. It simply holds information and + allows the other object to deal with that information however they please. + + As a side note, the difference between minSplashVelocity and + minWaveVelocity is that min splash is the minimum amount of velocity + before the liquid spawns a splash particle. minWaveVelocity is to generate + a wave on the surface, not a splash. It should be lower than min splash + velocity. It's the reason some things won't splash but will still cause + ripples in the water (especially when surfacing) +=============================================================================== +*/ + +#ifdef MOD_WATERPHYSICS + +class idPhysics_Liquid : public idPhysics_Static { +public: + CLASS_PROTOTYPE( idPhysics_Liquid ); + + idPhysics_Liquid( void ); + ~idPhysics_Liquid( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +public: + // Creates a splash on the liquid + virtual void Splash( idEntity *other, float volume, impactInfo_t &info, trace_t &collision ); + + // Derived information + virtual bool isInLiquid( const idVec3 &point ) const; + virtual idVec3 GetDepth( const idVec3 &point ) const; + virtual idVec3 GetPressure( const idVec3 &point ) const; + + // Physical properties + virtual float GetDensity() const; + virtual void SetDensity( float density ); + + virtual float GetViscosity() const; + virtual void SetViscosity( float viscosity ); + + virtual const idVec3 &GetMinSplashVelocity() const; + virtual void SetMinSplashVelocity( const idVec3 &m ); + + virtual const idVec3 &GetMinWaveVelocity() const; + virtual void SetMinWaveVelocity( const idVec3 &w ); + +private: + // STATE + float density; + float viscosity; + + idVec3 minWaveVelocity; + idVec3 minSplashVelocity; +}; + +#endif diff --git a/game/physics/Physics_Monster.cpp b/game/physics/Physics_Monster.cpp new file mode 100644 index 000000000..400bd12f3 --- /dev/null +++ b/game/physics/Physics_Monster.cpp @@ -0,0 +1,884 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics_Actor, idPhysics_Monster ) +END_CLASS + +const float OVERCLIP = 1.001f; + +/* +===================== +idPhysics_Monster::CheckGround +===================== +*/ +void idPhysics_Monster::CheckGround( monsterPState_t &state ) { + trace_t groundTrace; + idVec3 down; + + if ( gravityNormal == vec3_zero ) { + state.onGround = false; + groundEntityPtr = NULL; + return; + } + + down = state.origin + gravityNormal * CONTACT_EPSILON; + gameLocal.clip.Translation( groundTrace, state.origin, down, clipModel, clipModel->GetAxis(), clipMask, self ); + + if ( groundTrace.fraction == 1.0f ) { + state.onGround = false; + groundEntityPtr = NULL; + return; + } + + groundEntityPtr = gameLocal.entities[ groundTrace.c.entityNum ]; + + if ( ( groundTrace.c.normal * -gravityNormal ) < minFloorCosine ) + { + // grayman #2356 - assumed to be sliding down an incline > 45 degrees, but could also + // be sitting on an angled piece of a func_static, so check current origin.z against + // previous origin.z to see if you're really sliding. This prevents excessive buildup + // of gravity-induced vertical velocity, which leads to death once you get free and + // fall to the ground, where Crashland() thinks you fell from a great height. + + idVec3 prevMove = static_cast(self)->movementSubsystem->GetLastMove(); + if (prevMove.z < 0) // are you truly falling? + { + state.onGround = false; + return; + } + } + + state.onGround = true; + + // let the entity know about the collision + self->Collide( groundTrace, state.velocity ); + + idEntity* groundEnt = groundEntityPtr.GetEntity(); + + // greebo: Apply force/impulse to entities below the clipmodel + if ( groundTrace.c.entityNum != ENTITYNUM_WORLD && groundEnt != NULL ) + { + idPhysics* groundPhysics = groundEnt->GetPhysics(); + + impactInfo_t info; + groundEnt->GetImpactInfo( self, groundTrace.c.id, groundTrace.c.point, &info ); + + // greebo: Don't push entities that already have a velocity towards the ground. + if ( groundPhysics && info.invMass != 0.0f ) + { + // grayman #2478 - is this a mine? if so, blow it up now instead of waiting + // for the Collide() code to blow it up. Waiting allows the physics engine + // to sink the mine into the floor before it blows. If the mine is not + // armed yet, nothing happens, but at least the mine isn't pushed into the floor. + + if ( groundEnt->IsType(idProjectile::Type) && static_cast(groundEnt)->IsMine() ) + { + static_cast(groundEnt)->MineExplode( self->entityNumber ); + } + else + { + // greebo: Apply a force to the entity below the player + //gameRenderWorld->DebugArrow(colorCyan, current.origin, current.origin + gravityNormal*20, 1, 16); + + // grayman TODO: When an AI steps on something and applies this force, it's + // possible that physics will cause the thing to fall through the floor. + // gameLocal.clip.Motion() might have a problem with something sitting flat + // on a world brush. + + groundPhysics->AddForce(0, current.origin, gravityNormal); + groundPhysics->Activate(); + } + } + } +} + +/* +===================== +idPhysics_Monster::SlideMove +===================== +*/ +monsterMoveResult_t idPhysics_Monster::SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) { + int i; + trace_t tr; + idVec3 move; + + blockingEntity = NULL; + move = delta; + for( i = 0; i < 3; i++ ) { + gameLocal.clip.Translation( tr, start, start + move, clipModel, clipModel->GetAxis(), clipMask, self ); + //gameRenderWorld->DebugArrow(colorWhite, start, tr.endpos, 2, 5000); + + start = tr.endpos; + + if ( tr.fraction == 1.0f ) { + if ( i > 0 ) { + return MM_SLIDING; + } + return MM_OK; + } + + if ( tr.c.entityNum != ENTITYNUM_NONE ) { + blockingEntity = gameLocal.entities[ tr.c.entityNum ]; + } + + // clip the movement delta and velocity + move.ProjectOntoPlane( tr.c.normal, OVERCLIP ); + velocity.ProjectOntoPlane( tr.c.normal, OVERCLIP ); + } + + return MM_BLOCKED; +} + +/* +===================== +idPhysics_Monster::StepMove + + move start into the delta direction + the velocity is clipped conform any collisions +===================== +*/ +monsterMoveResult_t idPhysics_Monster::StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) { + trace_t tr; + idVec3 up, down, noStepPos, noStepVel, stepPos, stepVel; + monsterMoveResult_t result1, result2; + float stepdist; + float nostepdist; + + if ( delta == vec3_origin ) { + return MM_OK; + } + + // try to move without stepping up + noStepPos = start; + noStepVel = velocity; + result1 = SlideMove( noStepPos, noStepVel, delta ); + if ( result1 == MM_OK ) { + velocity = noStepVel; + if ( gravityNormal == vec3_zero ) { + start = noStepPos; + return MM_OK; + } + + // try to step down so that we walk down slopes and stairs at a normal rate + down = noStepPos + gravityNormal * maxStepHeight; + gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); + if ( tr.fraction < 1.0f ) { + start = tr.endpos; + return MM_STEPPED; + } else { + start = noStepPos; + return MM_OK; + } + } + + if ( blockingEntity && blockingEntity->IsType( idActor::Type ) ) { + // try to step down in case walking into an actor while going down steps + down = noStepPos + gravityNormal * maxStepHeight; + gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); + start = tr.endpos; + velocity = noStepVel; + return MM_BLOCKED; + } + + if ( gravityNormal == vec3_zero ) { + return result1; + } + + // try to step up + up = start - gravityNormal * maxStepHeight; + gameLocal.clip.Translation( tr, start, up, clipModel, clipModel->GetAxis(), clipMask, self ); + //gameRenderWorld->DebugArrow(colorRed, start, up, 2, 5000); + if ( tr.fraction == 0.0f ) { + start = noStepPos; + velocity = noStepVel; + return result1; + } + + // try to move at the stepped up position + stepPos = tr.endpos; + stepVel = velocity; + result2 = SlideMove( stepPos, stepVel, delta ); + if ( result2 == MM_BLOCKED ) { + start = noStepPos; + velocity = noStepVel; + return result1; + } + + // step down again + down = stepPos + gravityNormal * maxStepHeight; + gameLocal.clip.Translation( tr, stepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); + //gameRenderWorld->DebugArrow(colorGreen, stepPos, down, 2, 5000); + //gameRenderWorld->DebugArrow(colorBlue, tr.c.point, tr.c.point + 5 * tr.c.normal, 2, 5000); + + float projection = tr.c.normal * -gravityNormal; + + // greebo: We have collided with a steep slope in front of us + if (projection < minFloorCosine && projection > 0.06f) + { + // greebo: Set the endposition a bit more upwards than necessary to prevent gravity from pulling us down immediately again + stepPos = tr.endpos - gravityNormal * stepUpIncrease; + } + else + { + // No slope, just use the step position + stepPos = tr.endpos; + } + + // if the move is further without stepping up, or the slope is too steep, don't step up + nostepdist = ( noStepPos - start ).LengthSqr(); + stepdist = ( stepPos - start ).LengthSqr(); + + // Use the position that brought us the largest forward movement + if (nostepdist >= stepdist) + { + start = noStepPos; + velocity = noStepVel; + return MM_SLIDING; + } + + + start = stepPos; + velocity = stepVel; + + return MM_STEPPED; +} + +/* +================ +idPhysics_Monster::Activate +================ +*/ +void idPhysics_Monster::Activate( void ) { + current.atRest = -1; + self->BecomeActive( TH_PHYSICS ); +} + +/* +================ +idPhysics_Monster::Rest +================ +*/ +void idPhysics_Monster::Rest( void ) { + current.atRest = gameLocal.time; + current.velocity.Zero(); + self->BecomeInactive( TH_PHYSICS ); +} + +/* +================ +idPhysics_Monster::PutToRest +================ +*/ +void idPhysics_Monster::PutToRest( void ) { + Rest(); +} + +/* +================ +idPhysics_Monster::idPhysics_Monster +================ +*/ +idPhysics_Monster::idPhysics_Monster( void ) { + + memset( ¤t, 0, sizeof( current ) ); + current.atRest = -1; + saved = current; + + delta.Zero(); + maxStepHeight = 18.0f; + stepUpIncrease = 10.0f; + minFloorCosine = 0.7f; + moveResult = MM_OK; + forceDeltaMove = false; + fly = false; + useVelocityMove = false; + noImpact = false; + blockingEntity = NULL; +} + +/* +================ +idPhysics_Monster_SavePState +================ +*/ +void idPhysics_Monster_SavePState( idSaveGame *savefile, const monsterPState_t &state ) { + savefile->WriteVec3( state.origin ); + savefile->WriteVec3( state.velocity ); + savefile->WriteVec3( state.localOrigin ); + savefile->WriteVec3( state.pushVelocity ); + savefile->WriteBool( state.onGround ); + savefile->WriteInt( state.atRest ); +} + +/* +================ +idPhysics_Monster_RestorePState +================ +*/ +void idPhysics_Monster_RestorePState( idRestoreGame *savefile, monsterPState_t &state ) { + savefile->ReadVec3( state.origin ); + savefile->ReadVec3( state.velocity ); + savefile->ReadVec3( state.localOrigin ); + savefile->ReadVec3( state.pushVelocity ); + savefile->ReadBool( state.onGround ); + savefile->ReadInt( state.atRest ); +} + +/* +================ +idPhysics_Monster::Save +================ +*/ +void idPhysics_Monster::Save( idSaveGame *savefile ) const { + + idPhysics_Monster_SavePState( savefile, current ); + idPhysics_Monster_SavePState( savefile, saved ); + + savefile->WriteFloat( maxStepHeight ); + savefile->WriteFloat(stepUpIncrease); + savefile->WriteFloat( minFloorCosine ); + savefile->WriteVec3( delta ); + + savefile->WriteBool( forceDeltaMove ); + savefile->WriteBool( fly ); + savefile->WriteBool( useVelocityMove ); + savefile->WriteBool( noImpact ); + + savefile->WriteInt( (int)moveResult ); + savefile->WriteObject( blockingEntity ); +} + +/* +================ +idPhysics_Monster::Restore +================ +*/ +void idPhysics_Monster::Restore( idRestoreGame *savefile ) { + + idPhysics_Monster_RestorePState( savefile, current ); + idPhysics_Monster_RestorePState( savefile, saved ); + + savefile->ReadFloat( maxStepHeight ); + savefile->ReadFloat(stepUpIncrease); + savefile->ReadFloat( minFloorCosine ); + savefile->ReadVec3( delta ); + + savefile->ReadBool( forceDeltaMove ); + savefile->ReadBool( fly ); + savefile->ReadBool( useVelocityMove ); + savefile->ReadBool( noImpact ); + + savefile->ReadInt( (int &)moveResult ); + savefile->ReadObject( reinterpret_cast( blockingEntity ) ); +} + +/* +================ +idPhysics_Monster::SetDelta +================ +*/ +void idPhysics_Monster::SetDelta( const idVec3 &d ) { + delta = d; + if ( delta != vec3_origin ) { + Activate(); + } +} + +/* +================ +idPhysics_Monster::SetMaxStepHeight +================ +*/ +void idPhysics_Monster::SetMaxStepHeight( const float newMaxStepHeight ) { + maxStepHeight = newMaxStepHeight; +} + +/* +================ +idPhysics_Monster::GetMaxStepHeight +================ +*/ +float idPhysics_Monster::GetMaxStepHeight( void ) const { + return maxStepHeight; +} + +void idPhysics_Monster::SetStepUpIncrease(float incr) { + stepUpIncrease = incr; +} + +/* +================ +idPhysics_Monster::OnGround +================ +*/ +bool idPhysics_Monster::OnGround( void ) const { + return current.onGround; +} + +/* +================ +idPhysics_Monster::GetSlideMoveEntity +================ +*/ +idEntity *idPhysics_Monster::GetSlideMoveEntity( void ) const { + return blockingEntity; +} + +/* +================ +idPhysics_Monster::GetMoveResult +================ +*/ +monsterMoveResult_t idPhysics_Monster::GetMoveResult( void ) const { + return moveResult; +} + +/* +================ +idPhysics_Monster::ForceDeltaMove +================ +*/ +void idPhysics_Monster::ForceDeltaMove( bool force ) { + forceDeltaMove = force; +} + +/* +================ +idPhysics_Monster::UseFlyMove +================ +*/ +void idPhysics_Monster::UseFlyMove( bool force ) { + fly = force; +} + +/* +================ +idPhysics_Monster::UseVelocityMove +================ +*/ +void idPhysics_Monster::UseVelocityMove( bool force ) { + useVelocityMove = force; +} + +/* +================ +idPhysics_Monster::EnableImpact +================ +*/ +void idPhysics_Monster::EnableImpact( void ) { + noImpact = false; +} + +/* +================ +idPhysics_Monster::DisableImpact +================ +*/ +void idPhysics_Monster::DisableImpact( void ) { + noImpact = true; +} + +/* +================ +idPhysics_Monster::Evaluate +================ +*/ +bool idPhysics_Monster::Evaluate( int timeStepMSec, int endTimeMSec ) { + + if (timeStepMSec == 0) + { + // angua: time step can be zero when the AI comes back from being dormant + return false; + } + + idVec3 masterOrigin, oldOrigin; + idMat3 masterAxis; + float timeStep; + +#ifdef MOD_WATERPHYSICS + waterLevel = WATERLEVEL_NONE; // MOD_WATERPHYSICS + waterType = 0; // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + + timeStep = MS2SEC( timeStepMSec ); + + moveResult = MM_OK; + blockingEntity = NULL; + oldOrigin = current.origin; + + // if bound to a master + if ( masterEntity ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + current.localOrigin * masterAxis; + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + current.velocity = ( current.origin - oldOrigin ) / timeStep; + masterDeltaYaw = masterYaw; + masterYaw = masterAxis[0].ToYaw(); + masterDeltaYaw = masterYaw - masterDeltaYaw; + return true; + } + + // if the monster is at rest + if ( current.atRest >= 0 ) { + return false; + } + + ActivateContactEntities(); + + // move the monster velocity into the frame of a pusher + current.velocity -= current.pushVelocity; + + clipModel->Unlink(); + +#ifdef MOD_WATERPHYSICS + // check water level / type + SetWaterLevel(true); // MOD_WATERPHYSICS +#endif // MOD_WATERPHYSICS + + // check if on the ground + idPhysics_Monster::CheckGround( current ); + + // if not on the ground or moving upwards + float upspeed; + if ( gravityNormal != vec3_zero ) { + upspeed = -( current.velocity * gravityNormal ); + } else { + upspeed = current.velocity.z; + } + if ( fly || ( !forceDeltaMove && ( !current.onGround || upspeed > 1.0f ) ) ) { + if ( upspeed < 0.0f ) { + moveResult = MM_FALLING; + } + else { + current.onGround = false; + moveResult = MM_OK; + } + delta = current.velocity * timeStep; + if ( delta != vec3_origin ) { + moveResult = idPhysics_Monster::SlideMove( current.origin, current.velocity, delta ); + delta.Zero(); + } + + if ( !fly ) { + current.velocity += gravityVector * timeStep; + } + } else { + if ( useVelocityMove ) { + delta = current.velocity * timeStep; + } else { + current.velocity = delta / timeStep; + } + + current.velocity -= ( current.velocity * gravityNormal ) * gravityNormal; + + if ( delta == vec3_origin ) { + Rest(); + } else { + // try moving into the desired direction + moveResult = idPhysics_Monster::StepMove( current.origin, current.velocity, delta ); + delta.Zero(); + } + } + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + + // get all the ground contacts + EvaluateContacts(); + + // move the monster velocity back into the world frame + current.velocity += current.pushVelocity; + current.pushVelocity.Zero(); + + if ( IsOutsideWorld() ) { + gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) ); + Rest(); + } + + return ( current.origin != oldOrigin ); +} + +/* +================ +idPhysics_Monster::UpdateTime +================ +*/ +void idPhysics_Monster::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_Monster::GetTime +================ +*/ +int idPhysics_Monster::GetTime( void ) const { + return gameLocal.time; +} + +/* +================ +idPhysics_Monster::GetImpactInfo +================ +*/ +void idPhysics_Monster::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + info->invMass = invMass; + info->invInertiaTensor.Zero(); + info->position.Zero(); + info->velocity = current.velocity; +} + +/* +================ +idPhysics_Monster::ApplyImpulse +================ +*/ +void idPhysics_Monster::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + if ( noImpact ) { + return; + } + current.velocity += impulse * invMass; + Activate(); +} + +/* +================ +idPhysics_Monster::IsAtRest +================ +*/ +bool idPhysics_Monster::IsAtRest( void ) const { + return current.atRest >= 0; +} + +/* +================ +idPhysics_Monster::GetRestStartTime +================ +*/ +int idPhysics_Monster::GetRestStartTime( void ) const { + return current.atRest; +} + +/* +================ +idPhysics_Monster::SaveState +================ +*/ +void idPhysics_Monster::SaveState( void ) { + saved = current; +} + +/* +================ +idPhysics_Monster::RestoreState +================ +*/ +void idPhysics_Monster::RestoreState( void ) { + current = saved; + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + + EvaluateContacts(); +} + +/* +================ +idPhysics_Player::SetOrigin +================ +*/ +void idPhysics_Monster::SetOrigin( const idVec3 &newOrigin, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localOrigin = newOrigin; + if ( masterEntity ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + newOrigin * masterAxis; + } + else { + current.origin = newOrigin; + } + clipModel->Link( gameLocal.clip, self, 0, newOrigin, clipModel->GetAxis() ); + Activate(); +} + +/* +================ +idPhysics_Player::SetAxis +================ +*/ +void idPhysics_Monster::SetAxis( const idMat3 &newAxis, int id ) { + clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), newAxis ); + Activate(); +} + +/* +================ +idPhysics_Monster::Translate +================ +*/ +void idPhysics_Monster::Translate( const idVec3 &translation, int id ) { + + current.localOrigin += translation; + current.origin += translation; + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + Activate(); +} + +/* +================ +idPhysics_Monster::Rotate +================ +*/ +void idPhysics_Monster::Rotate( const idRotation &rotation, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.origin *= rotation; + if ( masterEntity ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + } + else { + current.localOrigin = current.origin; + } + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() * rotation.ToMat3() ); + Activate(); +} + +/* +================ +idPhysics_Monster::SetLinearVelocity +================ +*/ +void idPhysics_Monster::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { + current.velocity = newLinearVelocity; + Activate(); +} + +/* +================ +idPhysics_Monster::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_Monster::GetLinearVelocity( int id ) const { + return current.velocity; +} + +/* +================ +idPhysics_Monster::SetPushed +================ +*/ +void idPhysics_Monster::SetPushed( int deltaTime ) { + // velocity with which the monster is pushed + current.pushVelocity += ( current.origin - saved.origin ) / ( deltaTime * idMath::M_MS2SEC ); +} + +/* +================ +idPhysics_Monster::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_Monster::GetPushedLinearVelocity( const int id ) const { + return current.pushVelocity; +} + +/* +================ +idPhysics_Monster::SetMaster + + the binding is never orientated +================ +*/ +void idPhysics_Monster::SetMaster( idEntity *master, const bool orientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !masterEntity ) { + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + masterEntity = master; + masterYaw = masterAxis[0].ToYaw(); + } + ClearContacts(); + } + else { + if ( masterEntity ) { + masterEntity = NULL; + Activate(); + } + } +} + +const float MONSTER_VELOCITY_MAX = 4000; +const int MONSTER_VELOCITY_TOTAL_BITS = 16; +const int MONSTER_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( MONSTER_VELOCITY_MAX ) ) + 1; +const int MONSTER_VELOCITY_MANTISSA_BITS = MONSTER_VELOCITY_TOTAL_BITS - 1 - MONSTER_VELOCITY_EXPONENT_BITS; + +/* +================ +idPhysics_Monster::WriteToSnapshot +================ +*/ +void idPhysics_Monster::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteFloat( current.origin[0] ); + msg.WriteFloat( current.origin[1] ); + msg.WriteFloat( current.origin[2] ); + msg.WriteFloat( current.velocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteFloat( current.velocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteFloat( current.velocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); + msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); + msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + msg.WriteLong( current.atRest ); + msg.WriteBits( current.onGround, 1 ); +} + +/* +================ +idPhysics_Monster::ReadFromSnapshot +================ +*/ +void idPhysics_Monster::ReadFromSnapshot( const idBitMsgDelta &msg ) { + current.origin[0] = msg.ReadFloat(); + current.origin[1] = msg.ReadFloat(); + current.origin[2] = msg.ReadFloat(); + current.velocity[0] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.velocity[1] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.velocity[2] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); + current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); + current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); + current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); + current.atRest = msg.ReadLong(); + current.onGround = msg.ReadBits( 1 ) != 0; +} diff --git a/game/physics/Physics_Monster.h b/game/physics/Physics_Monster.h new file mode 100644 index 000000000..592dd4452 --- /dev/null +++ b/game/physics/Physics_Monster.h @@ -0,0 +1,148 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_MONSTER_H__ +#define __PHYSICS_MONSTER_H__ + +/* +=================================================================================== + + Monster physics + + Simulates the motion of a monster through the environment. The monster motion + is typically driven by animations. + +=================================================================================== +*/ + +typedef enum { + MM_OK, + MM_SLIDING, + MM_BLOCKED, + MM_STEPPED, + MM_FALLING +} monsterMoveResult_t; + +typedef struct monsterPState_s { + int atRest; + bool onGround; + idVec3 origin; + idVec3 velocity; + idVec3 localOrigin; + idVec3 pushVelocity; +} monsterPState_t; + +class idPhysics_Monster : public idPhysics_Actor { + +public: + CLASS_PROTOTYPE( idPhysics_Monster ); + + idPhysics_Monster( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // maximum step up the monster can take, default 18 units + void SetMaxStepHeight( const float newMaxStepHeight ); + float GetMaxStepHeight( void ) const; + + // Translates the entity upwards by this amount when stepping up to fight gravity during stepping + void SetStepUpIncrease(float incr); + + // minimum cosine of floor angle to be able to stand on the floor + void SetMinFloorCosine( const float newMinFloorCosine ); + // set delta for next move + void SetDelta( const idVec3 &d ); + // returns true if monster is standing on the ground + bool OnGround( void ) const; + // returns the movement result + monsterMoveResult_t GetMoveResult( void ) const; + // overrides any velocity for pure delta movement + void ForceDeltaMove( bool force ); + // whether velocity should be affected by gravity + void UseFlyMove( bool force ); + // don't use delta movement + void UseVelocityMove( bool force ); + // get entity blocking the move + idEntity * GetSlideMoveEntity( void ) const; + // enable/disable activation by impact + void EnableImpact( void ); + void DisableImpact( void ); + +public: // common physics interface + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + void Activate( void ); + void PutToRest( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated = true ); + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +private: + // monster physics state + monsterPState_t current; + monsterPState_t saved; + + // properties + float maxStepHeight; // maximum step height + float stepUpIncrease; // translates origin upwards by this amount when stepping + float minFloorCosine; // minimum cosine of floor angle + idVec3 delta; // delta for next move + + bool forceDeltaMove; + bool fly; + bool useVelocityMove; + bool noImpact; // if true do not activate when another object collides + + // results of last evaluate + monsterMoveResult_t moveResult; + idEntity * blockingEntity; + +private: + void CheckGround( monsterPState_t &state ); + monsterMoveResult_t SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ); + monsterMoveResult_t StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ); + void Rest( void ); +}; + +#endif /* !__PHYSICS_MONSTER_H__ */ diff --git a/game/physics/Physics_Parametric.cpp b/game/physics/Physics_Parametric.cpp new file mode 100644 index 000000000..903de5a95 --- /dev/null +++ b/game/physics/Physics_Parametric.cpp @@ -0,0 +1,1210 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics_Base, idPhysics_Parametric ) +END_CLASS + + +/* +================ +idPhysics_Parametric::Activate +================ +*/ +void idPhysics_Parametric::Activate( void ) { + current.atRest = -1; + self->BecomeActive( TH_PHYSICS ); +} + +/* +================ +idPhysics_Parametric::TestIfAtRest +================ +*/ +bool idPhysics_Parametric::TestIfAtRest( void ) const { + + if ( ( current.linearExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && + ( current.angularExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && + current.linearInterpolation.GetDuration() == 0 && + current.angularInterpolation.GetDuration() == 0 && + current.spline == NULL ) { + return true; + } + + if ( !current.linearExtrapolation.IsDone( current.time ) ) { + return false; + } + + if ( !current.angularExtrapolation.IsDone( current.time ) ) { + return false; + } + + if ( !current.linearInterpolation.IsDone( current.time ) ) { + return false; + } + + if ( !current.angularInterpolation.IsDone( current.time ) ) { + return false; + } + + if ( current.spline != NULL && !current.spline->IsDone( current.time ) ) { + return false; + } + + return true; +} + +/* +================ +idPhysics_Parametric::Rest +================ +*/ +void idPhysics_Parametric::Rest( void ) { + current.atRest = gameLocal.time; + self->BecomeInactive( TH_PHYSICS ); +} + +/* +================ +idPhysics_Parametric::idPhysics_Parametric +================ +*/ +idPhysics_Parametric::idPhysics_Parametric( void ) { + + current.time = gameLocal.time; + current.atRest = -1; + current.useSplineAngles = false; + current.origin.Zero(); + current.angles.Zero(); + current.axis.Identity(); + current.localOrigin.Zero(); + current.localAngles.Zero(); + current.linearExtrapolation.Init( 0, 0, vec3_zero, vec3_zero, vec3_zero, EXTRAPOLATION_NONE ); + current.angularExtrapolation.Init( 0, 0, ang_zero, ang_zero, ang_zero, EXTRAPOLATION_NONE ); + current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); + current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); + current.spline = NULL; + current.splineInterpolate.Init( 0, 1, 1, 2, 0, 0 ); + + saved = current; + + isPusher = false; + pushFlags = 0; + clipModel = NULL; + isBlocked = false; + memset( &pushResults, 0, sizeof( pushResults ) ); + + hasMaster = false; + isOrientated = false; +} + +/* +================ +idPhysics_Parametric::~idPhysics_Parametric +================ +*/ +idPhysics_Parametric::~idPhysics_Parametric( void ) { + if ( clipModel != NULL ) { + delete clipModel; + clipModel = NULL; + } + if ( current.spline != NULL ) { + delete current.spline; + current.spline = NULL; + } +} + +/* +================ +idPhysics_Parametric_SavePState +================ +*/ +void idPhysics_Parametric_SavePState( idSaveGame *savefile, const parametricPState_t &state ) { + savefile->WriteInt( state.time ); + savefile->WriteInt( state.atRest ); + savefile->WriteBool( state.useSplineAngles ); + savefile->WriteVec3( state.origin ); + savefile->WriteAngles( state.angles ); + savefile->WriteMat3( state.axis ); + savefile->WriteVec3( state.localOrigin ); + savefile->WriteAngles( state.localAngles ); + + savefile->WriteInt( (int)state.linearExtrapolation.GetExtrapolationType() ); + savefile->WriteFloat( state.linearExtrapolation.GetStartTime() ); + savefile->WriteFloat( state.linearExtrapolation.GetDuration() ); + savefile->WriteVec3( state.linearExtrapolation.GetStartValue() ); + savefile->WriteVec3( state.linearExtrapolation.GetBaseSpeed() ); + savefile->WriteVec3( state.linearExtrapolation.GetSpeed() ); + + savefile->WriteInt( (int)state.angularExtrapolation.GetExtrapolationType() ); + savefile->WriteFloat( state.angularExtrapolation.GetStartTime() ); + savefile->WriteFloat( state.angularExtrapolation.GetDuration() ); + savefile->WriteAngles( state.angularExtrapolation.GetStartValue() ); + savefile->WriteAngles( state.angularExtrapolation.GetBaseSpeed() ); + savefile->WriteAngles( state.angularExtrapolation.GetSpeed() ); + + savefile->WriteFloat( state.linearInterpolation.GetStartTime() ); + savefile->WriteFloat( state.linearInterpolation.GetAcceleration() ); + savefile->WriteFloat( state.linearInterpolation.GetDeceleration() ); + savefile->WriteFloat( state.linearInterpolation.GetDuration() ); + savefile->WriteVec3( state.linearInterpolation.GetStartValue() ); + savefile->WriteVec3( state.linearInterpolation.GetEndValue() ); + + savefile->WriteFloat( state.angularInterpolation.GetStartTime() ); + savefile->WriteFloat( state.angularInterpolation.GetAcceleration() ); + savefile->WriteFloat( state.angularInterpolation.GetDeceleration() ); + savefile->WriteFloat( state.angularInterpolation.GetDuration() ); + savefile->WriteAngles( state.angularInterpolation.GetStartValue() ); + savefile->WriteAngles( state.angularInterpolation.GetEndValue() ); + + // spline is handled by owner + + savefile->WriteFloat( state.splineInterpolate.GetStartTime() ); + savefile->WriteFloat( state.splineInterpolate.GetAcceleration() ); + savefile->WriteFloat( state.splineInterpolate.GetDuration() ); + savefile->WriteFloat( state.splineInterpolate.GetDeceleration() ); + savefile->WriteFloat( state.splineInterpolate.GetStartValue() ); + savefile->WriteFloat( state.splineInterpolate.GetEndValue() ); +} + +/* +================ +idPhysics_Parametric_RestorePState +================ +*/ +void idPhysics_Parametric_RestorePState( idRestoreGame *savefile, parametricPState_t &state ) { + extrapolation_t etype; + float startTime, duration, accelTime, decelTime, startValue, endValue; + idVec3 linearStartValue, linearBaseSpeed, linearSpeed, startPos, endPos; + idAngles angularStartValue, angularBaseSpeed, angularSpeed, startAng, endAng; + + savefile->ReadInt( state.time ); + savefile->ReadInt( state.atRest ); + savefile->ReadBool( state.useSplineAngles ); + savefile->ReadVec3( state.origin ); + savefile->ReadAngles( state.angles ); + savefile->ReadMat3( state.axis ); + savefile->ReadVec3( state.localOrigin ); + savefile->ReadAngles( state.localAngles ); + + savefile->ReadInt( (int &)etype ); + savefile->ReadFloat( startTime ); + savefile->ReadFloat( duration ); + savefile->ReadVec3( linearStartValue ); + savefile->ReadVec3( linearBaseSpeed ); + savefile->ReadVec3( linearSpeed ); + + state.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, etype ); + + savefile->ReadInt( (int &)etype ); + savefile->ReadFloat( startTime ); + savefile->ReadFloat( duration ); + savefile->ReadAngles( angularStartValue ); + savefile->ReadAngles( angularBaseSpeed ); + savefile->ReadAngles( angularSpeed ); + + state.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, etype ); + + savefile->ReadFloat( startTime ); + savefile->ReadFloat( accelTime ); + savefile->ReadFloat( decelTime ); + savefile->ReadFloat( duration ); + savefile->ReadVec3( startPos ); + savefile->ReadVec3( endPos ); + + state.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos ); + + savefile->ReadFloat( startTime ); + savefile->ReadFloat( accelTime ); + savefile->ReadFloat( decelTime ); + savefile->ReadFloat( duration ); + savefile->ReadAngles( startAng ); + savefile->ReadAngles( endAng ); + + state.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng ); + + // spline is handled by owner + + savefile->ReadFloat( startTime ); + savefile->ReadFloat( accelTime ); + savefile->ReadFloat( duration ); + savefile->ReadFloat( decelTime ); + savefile->ReadFloat( startValue ); + savefile->ReadFloat( endValue ); + + state.splineInterpolate.Init( startTime, accelTime, decelTime, duration, startValue, endValue ); +} + +/* +================ +idPhysics_Parametric::Save +================ +*/ +void idPhysics_Parametric::Save( idSaveGame *savefile ) const { + + idPhysics_Parametric_SavePState( savefile, current ); + idPhysics_Parametric_SavePState( savefile, saved ); + + savefile->WriteBool( isPusher ); + savefile->WriteClipModel( clipModel ); + savefile->WriteInt( pushFlags ); + + savefile->WriteTrace( pushResults ); + savefile->WriteBool( isBlocked ); + + savefile->WriteBool( hasMaster ); + savefile->WriteBool( isOrientated ); +} + +/* +================ +idPhysics_Parametric::Restore +================ +*/ +void idPhysics_Parametric::Restore( idRestoreGame *savefile ) { + + idPhysics_Parametric_RestorePState( savefile, current ); + idPhysics_Parametric_RestorePState( savefile, saved ); + + savefile->ReadBool( isPusher ); + savefile->ReadClipModel( clipModel ); + savefile->ReadInt( pushFlags ); + + savefile->ReadTrace( pushResults ); + savefile->ReadBool( isBlocked ); + + savefile->ReadBool( hasMaster ); + savefile->ReadBool( isOrientated ); +} + +/* +================ +idPhysics_Parametric::SetPusher +================ +*/ +void idPhysics_Parametric::SetPusher( int flags ) { + assert( clipModel ); + isPusher = true; + pushFlags = flags; +} + +/* +================ +idPhysics_Parametric::IsPusher +================ +*/ +bool idPhysics_Parametric::IsPusher( void ) const { + return isPusher; +} + +/* +================ +idPhysics_Parametric::SetLinearExtrapolation +================ +*/ +void idPhysics_Parametric::SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ) { + current.time = gameLocal.time; + current.linearExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); + current.localOrigin = base; + Activate(); +} + +/* +================ +idPhysics_Parametric::SetAngularExtrapolation +================ +*/ +void idPhysics_Parametric::SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ) { + current.time = gameLocal.time; + current.angularExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); + current.localAngles = base; + Activate(); +} + +/* +================ +idPhysics_Parametric::GetLinearExtrapolationType +================ +*/ +extrapolation_t idPhysics_Parametric::GetLinearExtrapolationType( void ) const { + return current.linearExtrapolation.GetExtrapolationType(); +} + +/* +================ +idPhysics_Parametric::GetAngularExtrapolationType +================ +*/ +extrapolation_t idPhysics_Parametric::GetAngularExtrapolationType( void ) const { + return current.angularExtrapolation.GetExtrapolationType(); +} + +/* +================ +idPhysics_Parametric::SetLinearInterpolation +================ +*/ +void idPhysics_Parametric::SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ) { + current.time = gameLocal.time; + current.linearInterpolation.Init( time, accelTime, decelTime, duration, startPos, endPos ); + current.localOrigin = startPos; + Activate(); +} + +/* +================ +idPhysics_Parametric::SetAngularInterpolation +================ +*/ +void idPhysics_Parametric::SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ) { + current.time = gameLocal.time; + current.angularInterpolation.Init( time, accelTime, decelTime, duration, startAng, endAng ); + current.localAngles = startAng; + Activate(); +} + +/* +================ +idPhysics_Parametric::SetSpline +================ +*/ +void idPhysics_Parametric::SetSpline( idCurve_Spline *spline, int accelTime, int decelTime, bool useSplineAngles ) { + if ( current.spline != NULL ) { + delete current.spline; + current.spline = NULL; + } + current.spline = spline; + if ( current.spline != NULL ) { + float startTime = current.spline->GetTime( 0 ); + float endTime = current.spline->GetTime( current.spline->GetNumValues() - 1 ); + float length = current.spline->GetLengthForTime( endTime ); + current.splineInterpolate.Init( startTime, accelTime, decelTime, endTime - startTime, 0.0f, length ); + } + current.useSplineAngles = useSplineAngles; + Activate(); +} + +/* +================ +idPhysics_Parametric::GetSpline +================ +*/ +idCurve_Spline *idPhysics_Parametric::GetSpline( void ) const { + return current.spline; +} + +/* +================ +idPhysics_Parametric::GetSplineAcceleration +================ +*/ +int idPhysics_Parametric::GetSplineAcceleration( void ) const { + return static_cast(current.splineInterpolate.GetAcceleration()); +} + +/* +================ +idPhysics_Parametric::GetSplineDeceleration +================ +*/ +int idPhysics_Parametric::GetSplineDeceleration( void ) const { + return static_cast(current.splineInterpolate.GetDeceleration()); +} + +/* +================ +idPhysics_Parametric::UsingSplineAngles +================ +*/ +bool idPhysics_Parametric::UsingSplineAngles( void ) const { + return current.useSplineAngles; +} + +/* +================ +idPhysics_Parametric::GetLocalOrigin +================ +*/ +void idPhysics_Parametric::GetLocalOrigin( idVec3 &curOrigin ) const { + curOrigin = current.localOrigin; +} + +const idVec3& idPhysics_Parametric::GetLocalOrigin() const { + return current.localOrigin; +} + +/* +================ +idPhysics_Parametric::GetLocalAngles +================ +*/ +void idPhysics_Parametric::GetLocalAngles( idAngles &curAngles ) const { + curAngles = current.localAngles; +} + +const idAngles& idPhysics_Parametric::GetLocalAngles() const +{ + return current.localAngles; +} + +void idPhysics_Parametric:: SetLocalAngles(idAngles curAngles) +{ + current.localAngles = curAngles; + + current.angularExtrapolation.SetStartValue( current.localAngles ); + current.angularInterpolation.SetStartValue( current.localAngles ); + + current.localAngles = current.angularExtrapolation.GetCurrentValue( current.time ); + if ( hasMaster && isOrientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + self->GetMasterPosition( masterOrigin, masterAxis ); + current.axis = current.localAngles.ToMat3() * masterAxis; + current.angles = current.axis.ToAngles(); + } + else { + current.axis = current.localAngles.ToMat3(); + current.angles = current.localAngles; + } + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } + Activate(); +} + + +/* +================ +idPhysics_Parametric::SetClipModel +================ +*/ +void idPhysics_Parametric::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { + + assert( self ); + assert( model ); + + if ( clipModel && clipModel != model && freeOld ) { + delete clipModel; + } + clipModel = model; + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); +} + +/* +================ +idPhysics_Parametric::GetClipModel +================ +*/ +idClipModel *idPhysics_Parametric::GetClipModel( int id ) const { + return clipModel; +} + +/* +================ +idPhysics_Parametric::GetNumClipModels +================ +*/ +int idPhysics_Parametric::GetNumClipModels( void ) const { + return ( clipModel != NULL ); +} + +/* +================ +idPhysics_Parametric::SetMass +================ +*/ +void idPhysics_Parametric::SetMass( float mass, int id ) { +} + +/* +================ +idPhysics_Parametric::GetMass +================ +*/ +float idPhysics_Parametric::GetMass( int id ) const { + return 0.0f; +} + +/* +================ +idPhysics_Parametric::SetClipMask +================ +*/ +void idPhysics_Parametric::SetContents( int contents, int id ) { + if ( clipModel ) { + clipModel->SetContents( contents ); + } +} + +/* +================ +idPhysics_Parametric::SetClipMask +================ +*/ +int idPhysics_Parametric::GetContents( int id ) const { + if ( clipModel ) { + return clipModel->GetContents(); + } + return 0; +} + +/* +================ +idPhysics_Parametric::GetBounds +================ +*/ +const idBounds &idPhysics_Parametric::GetBounds( int id ) const { + if ( clipModel ) { + return clipModel->GetBounds(); + } + return idPhysics_Base::GetBounds(); +} + +/* +================ +idPhysics_Parametric::GetAbsBounds +================ +*/ +const idBounds &idPhysics_Parametric::GetAbsBounds( int id ) const { + if ( clipModel ) { + return clipModel->GetAbsBounds(); + } + return idPhysics_Base::GetAbsBounds(); +} + +/* +================ +idPhysics_Parametric::Evaluate +================ +*/ +bool idPhysics_Parametric::Evaluate( int timeStepMSec, int endTimeMSec ) { + idVec3 oldLocalOrigin, oldOrigin, masterOrigin; + idAngles oldLocalAngles, oldAngles; + idMat3 oldAxis, masterAxis; + + isBlocked = false; + oldLocalOrigin = current.localOrigin; + oldOrigin = current.origin; + oldLocalAngles = current.localAngles; + oldAngles = current.angles; + oldAxis = current.axis; + + current.localOrigin.Zero(); + current.localAngles.Zero(); + + if ( current.spline != NULL ) { + float length = current.splineInterpolate.GetCurrentValue( endTimeMSec ); + float t = current.spline->GetTimeForLength( length, 0.01f ); + current.localOrigin = current.spline->GetCurrentValue( t ); + if ( current.useSplineAngles ) { + current.localAngles = current.spline->GetCurrentFirstDerivative( t ).ToAngles(); + } + } else if ( current.linearInterpolation.GetDuration() != 0 ) { + current.localOrigin += current.linearInterpolation.GetCurrentValue( endTimeMSec ); + } else { + current.localOrigin += current.linearExtrapolation.GetCurrentValue( endTimeMSec ); + } + + if ( current.angularInterpolation.GetDuration() != 0 ) { + current.localAngles += current.angularInterpolation.GetCurrentValue( endTimeMSec ); + } else { + current.localAngles += current.angularExtrapolation.GetCurrentValue( endTimeMSec ); + } + + current.localAngles.Normalize360(); + current.origin = current.localOrigin; + current.angles = current.localAngles; + current.axis = current.localAngles.ToMat3(); + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + if ( masterAxis.IsRotated() ) { + current.origin = current.origin * masterAxis + masterOrigin; + if ( isOrientated ) { + current.axis *= masterAxis; + current.angles = current.axis.ToAngles(); + } + } + else { + current.origin += masterOrigin; + } + } + + if ( isPusher ) { + + gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis ); + if ( pushResults.fraction < 1.0f ) { + clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis ); + current.localOrigin = oldLocalOrigin; + current.origin = oldOrigin; + current.localAngles = oldLocalAngles; + current.angles = oldAngles; + current.axis = oldAxis; + isBlocked = true; + return false; + } + + current.angles = current.axis.ToAngles(); + } + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } + + current.time = endTimeMSec; + + if ( TestIfAtRest() ) { + Rest(); + } + + return ( current.origin != oldOrigin || current.axis != oldAxis ); +} + +/* +================ +idPhysics_Parametric::UpdateTime +================ +*/ +void idPhysics_Parametric::UpdateTime( int endTimeMSec ) { + int timeLeap = endTimeMSec - current.time; + + current.time = endTimeMSec; + // move the trajectory start times to sync the trajectory with the current endTime + current.linearExtrapolation.SetStartTime( current.linearExtrapolation.GetStartTime() + timeLeap ); + current.angularExtrapolation.SetStartTime( current.angularExtrapolation.GetStartTime() + timeLeap ); + current.linearInterpolation.SetStartTime( current.linearInterpolation.GetStartTime() + timeLeap ); + current.angularInterpolation.SetStartTime( current.angularInterpolation.GetStartTime() + timeLeap ); + if ( current.spline != NULL ) { + current.spline->ShiftTime( timeLeap ); + current.splineInterpolate.SetStartTime( current.splineInterpolate.GetStartTime() + timeLeap ); + } +} + +/* +================ +idPhysics_Parametric::GetTime +================ +*/ +int idPhysics_Parametric::GetTime( void ) const { + return current.time; +} + +/* +================ +idPhysics_Parametric::IsAtRest +================ +*/ +bool idPhysics_Parametric::IsAtRest( void ) const { + return current.atRest >= 0; +} + +/* +================ +idPhysics_Parametric::GetRestStartTime +================ +*/ +int idPhysics_Parametric::GetRestStartTime( void ) const { + return current.atRest; +} + +/* +================ +idPhysics_Parametric::IsPushable +================ +*/ +bool idPhysics_Parametric::IsPushable( void ) const { + return false; +} + +/* +================ +idPhysics_Parametric::SaveState +================ +*/ +void idPhysics_Parametric::SaveState( void ) { + saved = current; +} + +/* +================ +idPhysics_Parametric::RestoreState +================ +*/ +void idPhysics_Parametric::RestoreState( void ) { + + current = saved; + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Parametric::SetOrigin +================ +*/ +void idPhysics_Parametric::SetOrigin( const idVec3 &newOrigin, int id ) { + + current.linearExtrapolation.SetStartValue( newOrigin ); + current.linearInterpolation.SetStartValue( newOrigin ); + + current.localOrigin = current.linearExtrapolation.GetCurrentValue( current.time ); + if ( hasMaster ) { + idVec3 masterOrigin; + idMat3 masterAxis; + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + current.localOrigin * masterAxis; + } + else { + current.origin = current.localOrigin; + } + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } + Activate(); +} + +void idPhysics_Parametric::SetLocalOrigin( const idVec3 &newOrigin) { + current.localOrigin = newOrigin; + if ( hasMaster ) { + idVec3 masterOrigin; + idMat3 masterAxis; + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + current.localOrigin * masterAxis; + } + else { + current.origin = current.localOrigin; + } + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } + + current.linearExtrapolation.SetStartValue( current.localOrigin ); + current.linearInterpolation.SetStartValue( current.localOrigin ); + + Activate(); +} + + +/* +================ +idPhysics_Parametric::SetAxis +================ +*/ +void idPhysics_Parametric::SetAxis( const idMat3 &newAxis, int id ) { + SetLocalAngles(newAxis.ToAngles()); +} + +/* +================ +idPhysics_Parametric::Move +================ +*/ +void idPhysics_Parametric::Translate( const idVec3 &translation, int id ) { +} + +/* +================ +idPhysics_Parametric::Rotate +================ +*/ +void idPhysics_Parametric::Rotate( const idRotation &rotation, int id ) { +} + +/* +================ +idPhysics_Parametric::GetOrigin +================ +*/ +const idVec3 &idPhysics_Parametric::GetOrigin( int id ) const { + return current.origin; +} + +/* +================ +idPhysics_Parametric::GetAxis +================ +*/ +const idMat3 &idPhysics_Parametric::GetAxis( int id ) const { + return current.axis; +} + +/* +================ +idPhysics_Parametric::GetAngles +================ +*/ +void idPhysics_Parametric::GetAngles( idAngles &curAngles ) const { + curAngles = current.angles; +} + +/* +================ +idPhysics_Parametric::SetLinearVelocity +================ +*/ +void idPhysics_Parametric::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { + SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.origin, newLinearVelocity, vec3_origin ); + current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); + Activate(); +} + +/* +================ +idPhysics_Parametric::SetAngularVelocity +================ +*/ +void idPhysics_Parametric::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { + idRotation rotation; + idVec3 vec; + float angle; + + vec = newAngularVelocity; + angle = vec.Normalize(); + rotation.Set( vec3_origin, vec, (float) RAD2DEG( angle ) ); + + SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.angles, rotation.ToAngles(), ang_zero ); + current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); + Activate(); +} + +/* +================ +idPhysics_Parametric::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_Parametric::GetLinearVelocity( int id ) const { + static idVec3 curLinearVelocity; + + curLinearVelocity = current.linearExtrapolation.GetCurrentSpeed( gameLocal.time ); + return curLinearVelocity; +} + +/* +================ +idPhysics_Parametric::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_Parametric::GetAngularVelocity( int id ) const { + static idVec3 curAngularVelocity; + idAngles angles; + + angles = current.angularExtrapolation.GetCurrentSpeed( gameLocal.time ); + curAngularVelocity = angles.ToAngularVelocity(); + return curAngularVelocity; +} + +/* +================ +idPhysics_Parametric::DisableClip +================ +*/ +void idPhysics_Parametric::DisableClip( void ) { + if ( clipModel ) { + clipModel->Disable(); + } +} + +/* +================ +idPhysics_Parametric::EnableClip +================ +*/ +void idPhysics_Parametric::EnableClip( void ) { + if ( clipModel ) { + clipModel->Enable(); + } +} + +/* +================ +idPhysics_Parametric::UnlinkClip +================ +*/ +void idPhysics_Parametric::UnlinkClip( void ) { + if ( clipModel ) { + clipModel->Unlink(); + } +} + +/* +================ +idPhysics_Parametric::LinkClip +================ +*/ +void idPhysics_Parametric::LinkClip( void ) { + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Parametric::GetBlockingInfo +================ +*/ +const trace_t *idPhysics_Parametric::GetBlockingInfo( void ) const { + return ( isBlocked ? &pushResults : NULL ); +} + +/* +================ +idPhysics_Parametric::GetBlockingEntity +================ +*/ +idEntity *idPhysics_Parametric::GetBlockingEntity( void ) const { + if ( isBlocked ) { + return gameLocal.entities[ pushResults.c.entityNum ]; + } + return NULL; +} + +/* +================ +idPhysics_Parametric::SetMaster +================ +*/ +void idPhysics_Parametric::SetMaster( idEntity *master, const bool orientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !hasMaster ) { + + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + if ( orientated ) { + current.localAngles = ( current.axis * masterAxis.Transpose() ).ToAngles(); + } + else { + current.localAngles = current.axis.ToAngles(); + } + + current.linearExtrapolation.SetStartValue( current.localOrigin ); + current.angularExtrapolation.SetStartValue( current.localAngles ); + hasMaster = true; + isOrientated = orientated; + } + } + else { + if ( hasMaster ) { + // transform from master space to world space + current.localOrigin = current.origin; + current.localAngles = current.angles; + SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.origin, vec3_origin, vec3_origin ); + SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.angles, ang_zero, ang_zero ); + hasMaster = false; + } + } +} + +/* +================ +idPhysics_Parametric::GetLinearEndTime +================ +*/ +int idPhysics_Parametric::GetLinearEndTime( void ) const { + if ( current.spline != NULL ) { + if ( current.spline->GetBoundaryType() != idCurve_Spline::BT_CLOSED ) { + return static_cast(current.spline->GetTime( current.spline->GetNumValues() - 1 )); + } else { + return 0; + } + } else if ( current.linearInterpolation.GetDuration() != 0 ) { + return static_cast(current.linearInterpolation.GetEndTime()); + } else { + return static_cast(current.linearExtrapolation.GetEndTime()); + } +} + +/* +================ +idPhysics_Parametric::GetAngularEndTime +================ +*/ +int idPhysics_Parametric::GetAngularEndTime( void ) const { + if ( current.angularInterpolation.GetDuration() != 0 ) { + return static_cast(current.angularInterpolation.GetEndTime()); + } else { + return static_cast(current.angularExtrapolation.GetEndTime()); + } +} + +/* +================ +idPhysics_Parametric::WriteToSnapshot +================ +*/ +void idPhysics_Parametric::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteLong( current.time ); + msg.WriteLong( current.atRest ); + msg.WriteFloat( current.origin[0] ); + msg.WriteFloat( current.origin[1] ); + msg.WriteFloat( current.origin[2] ); + msg.WriteFloat( current.angles[0] ); + msg.WriteFloat( current.angles[1] ); + msg.WriteFloat( current.angles[2] ); + msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); + msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); + msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); + msg.WriteDeltaFloat( current.angles[0], current.localAngles[0] ); + msg.WriteDeltaFloat( current.angles[1], current.localAngles[1] ); + msg.WriteDeltaFloat( current.angles[2], current.localAngles[2] ); + + msg.WriteBits( current.linearExtrapolation.GetExtrapolationType(), 8 ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartTime() ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetDuration() ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[2] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[0] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[1] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[2] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[0] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[1] ); + msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[2] ); + + msg.WriteBits( current.angularExtrapolation.GetExtrapolationType(), 8 ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartTime() ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetDuration() ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[2] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[0] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[1] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[2] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[0] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[1] ); + msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[2] ); + + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartTime() ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetAcceleration() ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDeceleration() ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDuration() ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[2] ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[2] ); + + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartTime() ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetAcceleration() ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDeceleration() ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDuration() ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[2] ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[0] ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[1] ); + msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[2] ); +} + +/* +================ +idPhysics_Parametric::ReadFromSnapshot +================ +*/ +void idPhysics_Parametric::ReadFromSnapshot( const idBitMsgDelta &msg ) { + extrapolation_t linearType, angularType; + float startTime, duration, accelTime, decelTime; + idVec3 linearStartValue, linearSpeed, linearBaseSpeed, startPos, endPos; + idAngles angularStartValue, angularSpeed, angularBaseSpeed, startAng, endAng; + + current.time = msg.ReadLong(); + current.atRest = msg.ReadLong(); + current.origin[0] = msg.ReadFloat(); + current.origin[1] = msg.ReadFloat(); + current.origin[2] = msg.ReadFloat(); + current.angles[0] = msg.ReadFloat(); + current.angles[1] = msg.ReadFloat(); + current.angles[2] = msg.ReadFloat(); + current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); + current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); + current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); + current.localAngles[0] = msg.ReadDeltaFloat( current.angles[0] ); + current.localAngles[1] = msg.ReadDeltaFloat( current.angles[1] ); + current.localAngles[2] = msg.ReadDeltaFloat( current.angles[2] ); + + linearType = (extrapolation_t) msg.ReadBits( 8 ); + startTime = msg.ReadDeltaFloat( 0.0f ); + duration = msg.ReadDeltaFloat( 0.0f ); + linearStartValue[0] = msg.ReadDeltaFloat( 0.0f ); + linearStartValue[1] = msg.ReadDeltaFloat( 0.0f ); + linearStartValue[2] = msg.ReadDeltaFloat( 0.0f ); + linearSpeed[0] = msg.ReadDeltaFloat( 0.0f ); + linearSpeed[1] = msg.ReadDeltaFloat( 0.0f ); + linearSpeed[2] = msg.ReadDeltaFloat( 0.0f ); + linearBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f ); + linearBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f ); + linearBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f ); + current.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, linearType ); + + angularType = (extrapolation_t) msg.ReadBits( 8 ); + startTime = msg.ReadDeltaFloat( 0.0f ); + duration = msg.ReadDeltaFloat( 0.0f ); + angularStartValue[0] = msg.ReadDeltaFloat( 0.0f ); + angularStartValue[1] = msg.ReadDeltaFloat( 0.0f ); + angularStartValue[2] = msg.ReadDeltaFloat( 0.0f ); + angularSpeed[0] = msg.ReadDeltaFloat( 0.0f ); + angularSpeed[1] = msg.ReadDeltaFloat( 0.0f ); + angularSpeed[2] = msg.ReadDeltaFloat( 0.0f ); + angularBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f ); + angularBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f ); + angularBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f ); + current.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, angularType ); + + startTime = msg.ReadDeltaFloat( 0.0f ); + accelTime = msg.ReadDeltaFloat( 0.0f ); + decelTime = msg.ReadDeltaFloat( 0.0f ); + duration = msg.ReadDeltaFloat( 0.0f ); + startPos[0] = msg.ReadDeltaFloat( 0.0f ); + startPos[1] = msg.ReadDeltaFloat( 0.0f ); + startPos[2] = msg.ReadDeltaFloat( 0.0f ); + endPos[0] = msg.ReadDeltaFloat( 0.0f ); + endPos[1] = msg.ReadDeltaFloat( 0.0f ); + endPos[2] = msg.ReadDeltaFloat( 0.0f ); + current.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos ); + + startTime = msg.ReadDeltaFloat( 0.0f ); + accelTime = msg.ReadDeltaFloat( 0.0f ); + decelTime = msg.ReadDeltaFloat( 0.0f ); + duration = msg.ReadDeltaFloat( 0.0f ); + startAng[0] = msg.ReadDeltaFloat( 0.0f ); + startAng[1] = msg.ReadDeltaFloat( 0.0f ); + startAng[2] = msg.ReadDeltaFloat( 0.0f ); + endAng[0] = msg.ReadDeltaFloat( 0.0f ); + endAng[1] = msg.ReadDeltaFloat( 0.0f ); + endAng[2] = msg.ReadDeltaFloat( 0.0f ); + current.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng ); + + current.axis = current.angles.ToMat3(); + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} diff --git a/game/physics/Physics_Parametric.h b/game/physics/Physics_Parametric.h new file mode 100644 index 000000000..25c0bdefe --- /dev/null +++ b/game/physics/Physics_Parametric.h @@ -0,0 +1,171 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_PARAMETRIC_H__ +#define __PHYSICS_PARAMETRIC_H__ + +/* +=================================================================================== + + Parametric physics + + Used for predefined or scripted motion. The motion of an object is completely + parametrized. By adjusting the parameters an object is forced to follow a + predefined path. The parametric physics is typically used for doors, bridges, + rotating fans etc. + +=================================================================================== +*/ + +typedef struct parametricPState_s { + int time; // physics time + int atRest; // set when simulation is suspended + idVec3 origin; // world origin + idAngles angles; // world angles + idMat3 axis; // world axis + idVec3 localOrigin; // local origin + idAngles localAngles; // local angles + idExtrapolate linearExtrapolation; // extrapolation based description of the position over time + idExtrapolate angularExtrapolation; // extrapolation based description of the orientation over time + idInterpolateAccelDecelLinear linearInterpolation; // interpolation based description of the position over time + idInterpolateAccelDecelLinear angularInterpolation; // interpolation based description of the orientation over time + idCurve_Spline * spline; // spline based description of the position over time + idInterpolateAccelDecelLinear splineInterpolate; // position along the spline over time + bool useSplineAngles; // set the orientation using the spline +} parametricPState_t; + +class idPhysics_Parametric : public idPhysics_Base { + +public: + CLASS_PROTOTYPE( idPhysics_Parametric ); + + idPhysics_Parametric( void ); + ~idPhysics_Parametric( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void SetPusher( int flags ); + bool IsPusher( void ) const; + + void SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ); + void SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ); + extrapolation_t GetLinearExtrapolationType( void ) const; + extrapolation_t GetAngularExtrapolationType( void ) const; + + void SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ); + void SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ); + + void SetSpline( idCurve_Spline *spline, int accelTime, int decelTime, bool useSplineAngles ); + idCurve_Spline *GetSpline( void ) const; + int GetSplineAcceleration( void ) const; + int GetSplineDeceleration( void ) const; + bool UsingSplineAngles( void ) const; + + void GetLocalOrigin( idVec3 &curOrigin ) const; + const idVec3& GetLocalOrigin() const; + void SetLocalOrigin( const idVec3 &newOrigin); + void GetLocalAngles( idAngles &curAngles ) const; + const idAngles& GetLocalAngles() const; + void SetLocalAngles(idAngles curAngles); + + void GetAngles( idAngles &curAngles ) const; + +public: // common physics interface + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void Activate( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + void SetMaster( idEntity *master, const bool orientated = true ); + + const trace_t * GetBlockingInfo( void ) const; + idEntity * GetBlockingEntity( void ) const; + + int GetLinearEndTime( void ) const; + int GetAngularEndTime( void ) const; + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +private: + // parametric physics state + parametricPState_t current; + parametricPState_t saved; + + // pusher + bool isPusher; + idClipModel * clipModel; + int pushFlags; + + // results of last evaluate + trace_t pushResults; + bool isBlocked; + + // master + bool hasMaster; + bool isOrientated; + +private: + bool TestIfAtRest( void ) const; + void Rest( void ); +}; + +#endif /* !__PHYSICS_PARAMETRIC_H__ */ diff --git a/game/physics/Physics_Player.cpp b/game/physics/Physics_Player.cpp new file mode 100644 index 000000000..566f96d5f --- /dev/null +++ b/game/physics/Physics_Player.cpp @@ -0,0 +1,5184 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Source$ $Revision$ $Date$", init_version); + +#include "../Game_local.h" +#include "../DarkModGlobals.h" +#include "../Grabber.h" +#include "../BinaryFrobMover.h" +#include "../FrobDoor.h" +#include "Force_Push.h" + +CLASS_DECLARATION( idPhysics_Actor, idPhysics_Player ) +END_CLASS + +// movement parameters +const float PM_STOPSPEED = 100.0f; +const float PM_SWIMSCALE = 1.0f; +const float PM_ROPESPEED = 100.0f; +const float PM_LADDERSPEED = 100.0f; +const float PM_STEPSCALE = 1.0f; + +const float PM_ACCELERATE = 10.0f; +const float PM_AIRACCELERATE = 1.0f; +const float PM_WATERACCELERATE = 4.0f; +const float PM_FLYACCELERATE = 8.0f; + +const float PM_FRICTION = 6.0f; +const float PM_AIRFRICTION = 0.0f; +const float PM_WATERFRICTION = 1.0f; +const float PM_FLYFRICTION = 3.0f; +const float PM_NOCLIPFRICTION = 12.0f; +const float PM_SLICK = 0.1f; // grayman - #2409 - for slippery surfaces + +/** +* Height unit increment for mantle test +* This value should be >= 1.0 +* A larger value reduces the number of tests during a mantle +* initiation, but may not find some small mantleable "nooks" +* in a surface. +**/ +const float MANTLE_TEST_INCREMENT = 1.0; + +/** +* Desired player speed below which ground friction is neglected +* +* This was determined for PM_FRICTION = 6.0 and should change if +* PM_FRICTION changes from 6.0. +**/ +const float PM_NOFRICTION_SPEED = 71.0f; + +const float MIN_WALK_NORMAL = 0.7f; // can't walk on very steep slopes (run = 1, rise = 1) +const float MIN_WALK_SLICK_NORMAL = 0.89f; // grayman #2409 - higher value for slippery slopes (run = 1, rise = 0.5) +const float OVERCLIP = 1.001f; + +// TODO (ishtvan): Move the following to INI file or player def file: + +/** +* Defines the spot above the player's origin where they are attached to the rope +**/ +const float ROPE_GRABHEIGHT = 50.0f; + +/** +* Distance the player is set back from the rope +**/ +const float ROPE_DISTANCE = 20.0f; + +/** +* Angular tolarance for looking at a rope and grabbing it [deg] +**/ +const float ROPE_ATTACHANGLE = 45.0f*idMath::PI/180.0f; +/** +* Angular tolerance for when to start rotating around the rope +* (This one doesn't have to be in the def file) +**/ +const float ROPE_ROTANG_TOL = 1.0f*idMath::PI/180.0f; + +/** +* When moving on a climbable surface, the player's predicted position is checked by this delta ahead +* To make sure it's still on a ladder surface. +**/ +const float CLIMB_SURFCHECK_DELTA = 5.0f; + +/** +* How far to check from the player origin along the surface normal to hit the surface in the above test +* Needs to allow for worst case overhang +**/ +const float CLIMB_SURFCHECK_NORMDELTA = 20.0f; + +/** +* how far away is the player allowed to push out from the climbable section? +* Measured from the last good attachment point at the origin +**/ +const float LADDER_DISTAWAY = 15.0f; + +/** +* Velocity with which the player is shoved over the top of the ladder +* This depends on LADDER_DISTAWAY. If this velocity is too low, the player will +* fall down before they can make it over the top of the ladder +**/ +const float LADDER_TOPVELOCITY = 80.0f; + +/** +* Angle at which the player detaches from a ladder when their feet are walking on a surface +**/ +const float LADDER_WALKDETACH_ANGLE = 45.0f; +const float LADDER_WALKDETACH_DOT = idMath::Cos( DEG2RAD( LADDER_WALKDETACH_ANGLE ) ); + +// movementFlags +const int PMF_DUCKED = 1; // set when ducking +const int PMF_JUMPED = 2; // set when the player jumped this frame +const int PMF_STEPPED_UP = 4; // set when the player stepped up this frame +const int PMF_STEPPED_DOWN = 8; // set when the player stepped down this frame +const int PMF_JUMP_HELD = 16; // set when jump button is held down +const int PMF_TIME_LAND = 32; // movementTime is time before rejump +const int PMF_TIME_KNOCKBACK = 64; // movementTime is an air-accelerate only time +const int PMF_TIME_WATERJUMP = 128; // movementTime is waterjump +const int PMF_ALL_TIMES = (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK); + +int c_pmove = 0; + +void idPhysics_Player::SetSelf( idEntity *e ) +{ + idPhysics_Base::SetSelf(e); + m_PushForce->SetOwner(e); +} + +/* +============ +idPhysics_Player::CmdScale + +Returns the scale factor to apply to cmd movements +This allows the clients to use axial -127 to 127 values for all directions +without getting a sqrt(2) distortion in speed. +============ +*/ +float idPhysics_Player::CmdScale( const usercmd_t &cmd ) const { + int max; + float total; + float scale; + int forwardmove; + int rightmove; + int upmove; + + forwardmove = cmd.forwardmove; + rightmove = cmd.rightmove; + + // since the crouch key doubles as downward movement, ignore downward movement when we're on the ground + // otherwise crouch speed will be lower than specified + if ( walking ) { + upmove = 0; + } else { + upmove = cmd.upmove; + } + + max = abs( forwardmove ); + if ( abs( rightmove ) > max ) { + max = abs( rightmove ); + } + if ( abs( upmove ) > max ) { + max = abs( upmove ); + } + + if ( !max ) { + return 0.0f; + } + + total = idMath::Sqrt( (float) forwardmove * forwardmove + rightmove * rightmove + upmove * upmove ); + scale = (float) playerSpeed * max / ( 127.0f * total ); + + return scale; +} + +/* +============== +idPhysics_Player::Accelerate + +Handles user intended acceleration +============== +*/ +void idPhysics_Player::Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel ) { +#if 1 + // q2 style + float addspeed, accelspeed, currentspeed; + + currentspeed = current.velocity * wishdir; + addspeed = wishspeed - currentspeed; + if (addspeed <= 0) { + return; + } + accelspeed = accel * frametime * wishspeed; + if (accelspeed > addspeed) { + accelspeed = addspeed; + } + + current.velocity += accelspeed * wishdir; +#else + // proper way (avoids strafe jump maxspeed bug), but feels bad + idVec3 wishVelocity; + idVec3 pushDir; + float pushLen; + float canPush; + + wishVelocity = wishdir * wishspeed; + pushDir = wishVelocity - current.velocity; + pushLen = pushDir.Normalize(); + + canPush = accel * frametime * wishspeed; + if (canPush > pushLen) { + canPush = pushLen; + } + + current.velocity += canPush * pushDir; +#endif +} + +/* +================== +idPhysics_Player::SlideMove + +Returns true if the velocity was clipped in some way +================== +*/ +#define MAX_CLIP_PLANES 5 + +bool idPhysics_Player::SlideMove( bool gravity, bool stepUp, bool stepDown, bool push ) { + int i, j, k, pushFlags; + int bumpcount, numbumps, numplanes; + float d, time_left, into; + float totalMass = 0.0f; + idVec3 dir, planes[MAX_CLIP_PLANES]; + idVec3 end, stepEnd, primal_velocity, endVelocity, endClipVelocity, clipVelocity; + trace_t trace, stepTrace, downTrace; + bool nearGround, stepped, pushed; + + numbumps = 4; + + primal_velocity = current.velocity; + + if ( gravity ) { + endVelocity = current.velocity + gravityVector * frametime; + current.velocity = ( current.velocity + endVelocity ) * 0.5f; + primal_velocity = endVelocity; + if ( groundPlane ) { + // slide along the ground plane + current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + } + } + else { + endVelocity = current.velocity; + } + + time_left = frametime; + + // never turn against the ground plane + if ( groundPlane ) { + numplanes = 1; + planes[0] = groundTrace.c.normal; + } else { + numplanes = 0; + } + + // never turn against original velocity + planes[numplanes] = current.velocity; + planes[numplanes].Normalize(); + numplanes++; + + for ( bumpcount = 0; bumpcount < numbumps; bumpcount++ ) + { + // calculate position we are trying to move to + end = current.origin + time_left * current.velocity; + + // see if we can make it there + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); + + time_left -= time_left * trace.fraction; + current.origin = trace.endpos; + + // if moved the entire distance + if ( trace.fraction >= 1.0f ) + { + break; + } + + stepped = pushed = false; + + // if we are allowed to step up + if ( stepUp ) + { + nearGround = groundPlane || m_bOnClimb || m_bClimbDetachThisFrame; + + if ( !nearGround ) + { + // trace down to see if the player is near the ground + // step checking when near the ground allows the player to move up stairs smoothly while jumping + stepEnd = current.origin + maxStepHeight * gravityNormal; + gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); + nearGround = ( downTrace.fraction < 1.0f && (downTrace.c.normal * -gravityNormal) > MIN_WALK_NORMAL ); + } + + // may only step up if near the ground or climbing + if ( nearGround ) + { + + // step up + stepEnd = current.origin - maxStepHeight * gravityNormal; + gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); + + // greebo: Trace along the current velocity, but trace further ahead than we need to judge the situation + idVec3 velocityNorm(current.velocity); + velocityNorm.NormalizeFast(); + + idVec3 fullForward = downTrace.endpos + maxStepHeight * velocityNorm; + gameLocal.clip.Translation( stepTrace, downTrace.endpos, fullForward, clipModel, clipModel->GetAxis(), clipMask, self ); + + // This is the max. distance we can move forward in this frame + idVec3 forward = time_left * current.velocity; + float forwardDist = forward.LengthFast(); + + // step down + idVec3 topStartPoint = downTrace.endpos + forward; + + stepEnd = topStartPoint + maxStepHeight * gravityNormal; + gameLocal.clip.Translation( downTrace, topStartPoint, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); + + if ( downTrace.fraction >= 1.0f || (downTrace.c.normal * -gravityNormal) > MIN_WALK_NORMAL ) + { + // if moved the entire distance + if ( stepTrace.fraction >= 1.0f ) + { + time_left = 0; + current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; + current.origin = downTrace.endpos; + current.movementFlags |= PMF_STEPPED_UP; + current.velocity *= PM_STEPSCALE; + break; + } + + // if the move is further when stepping up + if ( stepTrace.fraction > trace.fraction ) + { + time_left -= time_left * stepTrace.fraction; + current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; + current.origin = downTrace.endpos; + current.movementFlags |= PMF_STEPPED_UP; + current.velocity *= PM_STEPSCALE; + trace = stepTrace; + stepped = true; + } + } + else + { + // greebo: We have a sloped obstacle in front of us + + if (stepTrace.fraction >= 1.0f) + { + // We can step onto this obstacle, the stepTrace has shown that there is enough room + // in front of us (if we translate a bit upwards) + current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; + //static int factor = 10; + current.origin = downTrace.endpos + time_left*current.velocity; //(fullForward - current.origin)*stepTrace.fraction; + time_left = 0; + current.movementFlags |= PMF_STEPPED_UP; + current.velocity *= PM_STEPSCALE; + // greebo: HACK ALARM: We add a "counter-gravity" this frame to avoid us from being dragged down again in the next frame + // TODO: Maybe we can do this somewhere else, where the player is sliding off slopes. + current.velocity -= gravityVector * frametime * 3; + } + } + + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing step up, velocity now %.4f %.4f %.4f\r", current.velocity.x, current.velocity.y, current.velocity.z); + } + } + + // if we can push other entities and not blocked by the world + if ( push && trace.c.entityNum != ENTITYNUM_WORLD ) { + + clipModel->SetPosition( current.origin, clipModel->GetAxis() ); + + // clip movement, only push idMoveables, don't push entities the player is standing on + // apply impact to pushed objects + pushFlags = PUSHFL_CLIP | PUSHFL_ONLYMOVEABLE | PUSHFL_NOGROUNDENTITIES | PUSHFL_APPLYIMPULSE; + + // clip & push + + // greebo: Don't use the idPusher + //totalMass = gameLocal.push.ClipTranslationalPush( trace, self, pushFlags, end, end - current.origin, cv_pm_pushmod.GetFloat() ); + + // Set the trace result to zero, we're pushing into things here + trace.fraction = 0.0f; + trace.endpos = current.origin; + + // greebo: Check the entity in front of us + idEntity* pushedEnt = gameLocal.entities[trace.c.entityNum]; + if (pushedEnt != NULL) + { + // Register the blocking physics object with our push force + m_PushForce->SetPushEntity(pushedEnt, 0); + m_PushForce->SetContactInfo(trace, current.velocity); + + totalMass = pushedEnt->GetPhysics()->GetMass(); + } + + if ( totalMass > 0.0f ) { + // decrease velocity based on the total mass of the objects being pushed ? + current.velocity *= 1.0f - idMath::ClampFloat( 0.0f, 1000.0f, totalMass - 20.0f ) * ( 1.0f / 950.0f ); + pushed = true; + } + + current.origin = trace.endpos; + time_left -= time_left * trace.fraction; + + // if moved the entire distance + if ( trace.fraction >= 1.0f ) { + break; + } + } + + if ( !stepped ) { + // let the entity know about the collision + self->Collide( trace, current.velocity ); + } + + if ( numplanes >= MAX_CLIP_PLANES ) { + // MrElusive: I think we have some relatively high poly LWO models with a lot of slanted tris + // where it may hit the max clip planes + current.velocity = vec3_origin; + return true; + } + + // + // if this is the same plane we hit before, nudge velocity + // out along it, which fixes some epsilon issues with + // non-axial planes + // + for ( i = 0; i < numplanes; i++ ) { + if ( ( trace.c.normal * planes[i] ) > 0.999f ) { + current.velocity += trace.c.normal; + break; + } + } + if ( i < numplanes ) { + continue; + } + planes[numplanes] = trace.c.normal; + numplanes++; + + // + // modify velocity so it parallels all of the clip planes + // + + // find a plane that it enters + for ( i = 0; i < numplanes; i++ ) { + into = current.velocity * planes[i]; + if ( into >= 0.1f ) { + continue; // move doesn't interact with the plane + } + + // slide along the plane + clipVelocity = current.velocity; + clipVelocity.ProjectOntoPlane( planes[i], OVERCLIP ); + + // slide along the plane + endClipVelocity = endVelocity; + endClipVelocity.ProjectOntoPlane( planes[i], OVERCLIP ); + + // see if there is a second plane that the new move enters + for ( j = 0; j < numplanes; j++ ) { + if ( j == i ) { + continue; + } + if ( ( clipVelocity * planes[j] ) >= 0.1f ) { + continue; // move doesn't interact with the plane + } + + // try clipping the move to the plane + clipVelocity.ProjectOntoPlane( planes[j], OVERCLIP ); + endClipVelocity.ProjectOntoPlane( planes[j], OVERCLIP ); + + // see if it goes back into the first clip plane + if ( ( clipVelocity * planes[i] ) >= 0 ) { + continue; + } + + // slide the original velocity along the crease + dir = planes[i].Cross( planes[j] ); + dir.Normalize(); + d = dir * current.velocity; + clipVelocity = d * dir; + + dir = planes[i].Cross( planes[j] ); + dir.Normalize(); + d = dir * endVelocity; + endClipVelocity = d * dir; + + // see if there is a third plane the the new move enters + for ( k = 0; k < numplanes; k++ ) { + if ( k == i || k == j ) { + continue; + } + if ( ( clipVelocity * planes[k] ) >= 0.1f ) { + continue; // move doesn't interact with the plane + } + + // stop dead at a tripple plane interaction + current.velocity = vec3_origin; + return true; + } + } + + // if we have fixed all interactions, try another move + current.velocity = clipVelocity; + endVelocity = endClipVelocity; + break; + } + } + + // step down + if ( stepDown && groundPlane ) + { + stepEnd = current.origin + gravityNormal * maxStepHeight; + gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); + if ( downTrace.fraction > 1e-4f && downTrace.fraction < 1.0f ) + { + current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; + current.origin = downTrace.endpos; + current.movementFlags |= PMF_STEPPED_DOWN; + current.velocity *= PM_STEPSCALE; + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing step down, velocity now %.4f %.4f %.4f\r", current.velocity.x, current.velocity.y, current.velocity.z); + } + } + + if ( gravity ) { + current.velocity = endVelocity; + } + + // come to a dead stop when the velocity orthogonal to the gravity flipped + clipVelocity = current.velocity - gravityNormal * current.velocity * gravityNormal; + endClipVelocity = endVelocity - gravityNormal * endVelocity * gravityNormal; + if ( clipVelocity * endClipVelocity < 0.0f ) { + current.velocity = gravityNormal * current.velocity * gravityNormal; + } + + return (bool)( bumpcount == 0 ); +} + +/* +================== +idPhysics_Player::Friction + +Handles both ground friction and water friction +================== +*/ +void idPhysics_Player::Friction( void ) +{ + idVec3 vel = current.velocity; + + if ( walking ) { + // ignore slope movement, remove all velocity in gravity direction + vel += (vel * gravityNormal) * gravityNormal; + } + + float speed = vel.Length(); + if ( speed < 1.0f ) { + // remove all movement orthogonal to gravity, allows for sinking underwater + if ( fabs( current.velocity * gravityNormal ) < 1e-5f ) { + current.velocity.Zero(); + } else { + current.velocity = (current.velocity * gravityNormal) * gravityNormal; + } + // greebo: We still want the player to slow down when reaching the surface + // This is where velocities are getting really small, but never actually reach 0, + // that's why this z-friction is necessary. + current.velocity.z *= cv_pm_water_z_friction.GetFloat(); + return; + } + + float drop = 0; + + // spectator friction + if ( current.movementType == PM_SPECTATOR ) { + drop += speed * PM_FLYFRICTION * frametime; + } + // apply ground friction + else if ( walking && waterLevel <= WATERLEVEL_FEET ) + { + if ( !(current.movementFlags & PMF_TIME_KNOCKBACK) ) // if getting knocked back, no friction + { + // grayman - #2409 - less friction on slick surfaces + + float friction = PM_FRICTION; // default + if (groundMaterial && (groundMaterial->IsSlick())) + { + friction *= PM_SLICK; // reduce friction + } + float control = (speed < PM_STOPSPEED) ? PM_STOPSPEED : speed; + drop += control * friction * frametime; + } + } + // apply water friction even if just wading + else if ( waterLevel ) { + drop += speed * PM_WATERFRICTION * waterLevel * frametime; + } + // apply air friction + else { + drop += speed * PM_AIRFRICTION * frametime; + } + + // scale the velocity + float newspeed = speed - drop; + if (newspeed < 0) { + newspeed = 0; + } + current.velocity *= ( newspeed / speed ); +} + +/* +=================== +idPhysics_Player::WaterJumpMove + +Flying out of the water + +REMOVED from DarkMod +=================== +*/ + + +/* +=================== +idPhysics_Player::WaterMove +=================== +*/ +void idPhysics_Player::WaterMove() +{ + // Keep track of whether jump is held down for mantling out of water + if ( command.upmove > 10 ) + { + current.movementFlags |= PMF_JUMP_HELD; + } + else + { + current.movementFlags &= ~PMF_JUMP_HELD; + } + + // Lower ranged weapons while swimming + static_cast(self)->SetImmobilization( "WaterMove", EIM_ATTACK_RANGED ); + + Friction(); + + float scale = CmdScale( command ); + + idVec3 wishvel; + + // user intentions + if ( !scale ) { + // greebo: Standard downwards velocity is configurable via this CVAR + if (waterLevel >= WATERLEVEL_HEAD) + { + // greebo: Player is completely submersed, apply upwards velocity, but let it raise over time + float factor = (gameLocal.framenum - submerseFrame) / 60; + if (factor > 1) { + factor = 1; + } + + if (static_cast(self)->m_CrouchIntent) + { + // greebo: we probably have crouch mode activated + // Set the factor to 0, toggle crouch can here be used to keep the player at the current height + factor = 0; + } + + // This makes the player slowly rise/sink in water + wishvel = gravityNormal * cv_pm_water_downwards_velocity.GetFloat() * factor; + } + else + { + wishvel.Zero(); + } + } else { + + wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); + wishvel -= scale * gravityNormal * command.upmove; + } + + idVec3 wishdir = wishvel; + float wishspeed = wishdir.Normalize(); + + if ( wishspeed > playerSpeed * PM_SWIMSCALE ) { + wishspeed = playerSpeed * PM_SWIMSCALE; + } + + idPhysics_Player::Accelerate( wishdir, wishspeed, PM_WATERACCELERATE ); + + // make sure we can go up slopes easily under water + if ( groundPlane && ( current.velocity * groundTrace.c.normal ) < 0.0f ) { + float vel = current.velocity.Length(); + // slide along the ground plane + current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + + current.velocity.Normalize(); + current.velocity *= vel; + } + + idPhysics_Player::SlideMove( false, true, false, false ); +} + +/* +=================== +idPhysics_Player::FlyMove +=================== +*/ +void idPhysics_Player::FlyMove( void ) { + idVec3 wishvel; + float wishspeed; + idVec3 wishdir; + float scale; + + // normal slowdown + idPhysics_Player::Friction(); + + scale = idPhysics_Player::CmdScale( command ); + + if ( !scale ) { + wishvel = vec3_origin; + } else { + wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); + wishvel -= scale * gravityNormal * command.upmove; + } + + wishdir = wishvel; + wishspeed = wishdir.Normalize(); + + idPhysics_Player::Accelerate( wishdir, wishspeed, PM_FLYACCELERATE ); + + idPhysics_Player::SlideMove( false, false, false, false ); +} + +/* +=================== +idPhysics_Player::AirMove +=================== +*/ +void idPhysics_Player::AirMove( void ) { + idVec3 wishvel; + idVec3 wishdir; + float wishspeed; + float scale; + + idPhysics_Player::Friction(); + + scale = idPhysics_Player::CmdScale( command ); + + // project moves down to flat plane + viewForward -= (viewForward * gravityNormal) * gravityNormal; + viewRight -= (viewRight * gravityNormal) * gravityNormal; + viewForward.Normalize(); + viewRight.Normalize(); + + wishvel = viewForward * command.forwardmove + viewRight * command.rightmove; + wishvel -= (wishvel * gravityNormal) * gravityNormal; + wishdir = wishvel; + wishspeed = wishdir.Normalize(); + wishspeed *= scale; + + // not on ground, so little effect on velocity + idPhysics_Player::Accelerate( wishdir, wishspeed, PM_AIRACCELERATE ); + + // we may have a ground plane that is very steep, even + // though we don't have a groundentity + // slide along the steep plane + if ( groundPlane ) { + current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + } + + idPhysics_Player::SlideMove( true, false, false, false ); +} + +/* +=================== +idPhysics_Player::WalkMove +=================== +*/ +void idPhysics_Player::WalkMove( void ) +{ + if ( waterLevel > WATERLEVEL_WAIST && ( viewForward * groundTrace.c.normal ) > 0.0f ) + { + // begin swimming + WaterMove(); + return; + } + + if ( CheckJump() ) { + // jumped away + if ( waterLevel > WATERLEVEL_FEET ) { + WaterMove(); + } + else { + AirMove(); + } + return; + } + + Friction(); + + float scale = CmdScale( command ); + + // project moves down to flat plane + viewForward -= (viewForward * gravityNormal) * gravityNormal; + viewRight -= (viewRight * gravityNormal) * gravityNormal; + + // project the forward and right directions onto the ground plane + viewForward.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + viewRight.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + // + viewForward.Normalize(); + viewRight.Normalize(); + + idVec3 wishvel = viewForward * command.forwardmove + viewRight * command.rightmove; + idVec3 wishdir = wishvel; + float wishspeed = wishdir.Normalize(); + wishspeed *= scale; + + // clamp the speed lower if wading or walking on the bottom + if ( waterLevel ) + { + float waterScale = waterLevel / 3.0f; + waterScale = 1.0f - ( 1.0f - PM_SWIMSCALE ) * waterScale; + if ( wishspeed > playerSpeed * waterScale ) { + wishspeed = playerSpeed * waterScale; + } + } + + float accelerate = 0; + + // when a player gets hit, they temporarily lose full control, which allows them to be moved a bit + if ( /*( groundMaterial && groundMaterial->IsSlick() ) || grayman #2409 */ current.movementFlags & PMF_TIME_KNOCKBACK ) { + accelerate = PM_AIRACCELERATE; + } + else + { + accelerate = PM_ACCELERATE; + + //FIX: If the player is moving very slowly, bump up their acceleration + // so they don't get stuck to the floor by friction. + if( playerSpeed < PM_NOFRICTION_SPEED ) + { + accelerate *= 3.0f; + } + } + + Accelerate( wishdir, wishspeed, accelerate ); + + if ( /*( groundMaterial && groundMaterial->IsSlick() ) || grayman #2409 */ current.movementFlags & PMF_TIME_KNOCKBACK ) + { + current.velocity += gravityVector * frametime; + } + + idVec3 oldVelocity = current.velocity; + + // slide along the ground plane + current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); + + // if not clipped into the opposite direction + if ( oldVelocity * current.velocity > 0.0f ) + { + float newVel = current.velocity.LengthSqr(); + + if ( newVel > 1.0f ) + { + float oldVel = oldVelocity.LengthSqr(); + + if ( oldVel > 1.0f ) + { + // don't decrease velocity when going up or down a slope + current.velocity *= idMath::Sqrt( oldVel / newVel ); + } + } + } + + // don't do anything if standing still + idVec3 vel = current.velocity - (current.velocity * gravityNormal) * gravityNormal; + + if ( !vel.LengthSqr() ) + { + // greebo: We're not moving, so let's clear the push entity + m_PushForce->SetPushEntity(NULL); + return; + } + + gameLocal.push.InitSavingPushedEntityPositions(); + + SlideMove( false, true, true, true ); +} + +/* +============== +idPhysics_Player::DeadMove +============== +*/ +void idPhysics_Player::DeadMove( void ) { + float forward; + + if ( !walking ) { + return; + } + + // extra friction + forward = current.velocity.Length(); + forward -= 20; + if ( forward <= 0 ) { + current.velocity = vec3_origin; + } + else { + current.velocity.Normalize(); + current.velocity *= forward; + } +} + +/* +=============== +idPhysics_Player::NoclipMove +=============== +*/ +void idPhysics_Player::NoclipMove( void ) { + float speed, drop, friction, newspeed, stopspeed; + float scale, wishspeed; + idVec3 wishdir; + + // friction + speed = current.velocity.Length(); + if ( speed < 20.0f ) { + current.velocity = vec3_origin; + } + else { + stopspeed = playerSpeed * 0.3f; + if ( speed < stopspeed ) { + speed = stopspeed; + } + friction = PM_NOCLIPFRICTION; + drop = speed * friction * frametime; + + // scale the velocity + newspeed = speed - drop; + if (newspeed < 0) { + newspeed = 0; + } + + current.velocity *= newspeed / speed; + } + + // accelerate + scale = idPhysics_Player::CmdScale( command ); + + wishdir = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); + wishdir -= scale * gravityNormal * command.upmove; + wishspeed = wishdir.Normalize(); + wishspeed *= scale; + + idPhysics_Player::Accelerate( wishdir, wishspeed, PM_ACCELERATE ); + + // move + current.origin += frametime * current.velocity; +} + +/* +=============== +idPhysics_Player::SpectatorMove +=============== +*/ +void idPhysics_Player::SpectatorMove( void ) { + idVec3 wishvel; + float wishspeed; + idVec3 wishdir; + float scale; + + trace_t trace; + idVec3 end; + + // fly movement + + idPhysics_Player::Friction(); + + scale = idPhysics_Player::CmdScale( command ); + + if ( !scale ) { + wishvel = vec3_origin; + } else { + wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); + } + + wishdir = wishvel; + wishspeed = wishdir.Normalize(); + + idPhysics_Player::Accelerate( wishdir, wishspeed, PM_FLYACCELERATE ); + + idPhysics_Player::SlideMove( false, false, false, false ); +} + +/* +============ +idPhysics_Player::RopeMove +============ +*/ +// TODO: This will probably reverse the up/down controls for upside-down ropes +// Would need some fix where desired direction of travel is flipped +// if climbDir * gravNormal is < 0 +#pragma warning( disable : 4533 ) +void idPhysics_Player::RopeMove( void ) +{ + idVec3 wishdir, wishvel, right, ropeBodyOrig; + idVec3 ropePoint, offset, newOrigin, climbDir; + float wishspeed, scale, temp, deltaYaw, deltaAng1, deltaAng2; + float upscale, ropeTop, ropeBot; // z coordinates of the top and bottom of rope + idBounds ropeBounds; + trace_t transTrace; // used for clipping tests when moving the player + idVec3 transVec, forward, playerVel(0,0,0), PlayerPoint(0,0,0); + // shaft of rope in the rope coordinates, may need to be a spawnarg if rope models are inconsistent + idVec3 ropeShaft( 0.0f, 0.0f, 1.0f ); + int bodID(0); + idPhysics_AF *ropePhys; + idPlayer *player = static_cast(self); + + if( !m_RopeEntity.GetEntity() ) + { + RopeDetach(); + return; // early exit + } + + ropePhys = static_cast(m_RopeEntity.GetEntity()->GetPhysics()); + + // stick the player to the rope at an AF origin point closest to their arms + PlayerPoint = current.origin - gravityNormal*ROPE_GRABHEIGHT; + ropeBodyOrig = ropePhys->NearestBodyOrig( PlayerPoint, &bodID ); + climbDir = ropePhys->GetAxis( bodID ) * ropeShaft; + // Find the rope attachment point, which now moves along the individual AF body axis + // Drawing a diagram, we find: + // (orig - ropeOrig) * gravNormal = | offset along rope axis | * (rope axis * gravNormal) + // Solve for offset along rope axis + idVec3 deltaPlayerBody = PlayerPoint - ropeBodyOrig; + + // float offsetMag = (deltaPlayerBody * gravityNormal) / (climbDir * gravityNormal); + + // angua: the other method got huge values for offsetMag at large angles + // between the climbDir and the gravity axis. + float offsetMag = deltaPlayerBody * climbDir; + ropePoint = ropeBodyOrig + offsetMag * climbDir; + + // Uncomment for climb axis debugging + // gameRenderWorld->DebugArrow( colorRed, ropeBodyOrig, ropePoint, 1 ); + + SetRefEntVel( m_RopeEntity.GetEntity(), bodID ); + // move the player velocity into the rope reference frame + current.velocity -= m_RefEntVelocity; + + // store and then kill the player's transverse velocity + playerVel = current.velocity; + current.velocity = (current.velocity * climbDir) * climbDir; + + // apply the player's weight to the AF body - COMMENTED OUT DUE TO AF CRAZINESS +// ropePhys->AddForce(bodID, ropePoint, mass * gravityVector ); + + // if the player has hit the rope this frame, apply an impulse based on their velocity + // pretend the deceleration takes place over a number of frames for realism (100 ms?) + if( m_bJustHitRope ) + { + m_bJustHitRope = false; + + // greebo: Apply an impulse on the entity the rope arrow is bound to + idEntity* ropeBindMaster = m_RopeEntity.GetEntity()->GetBindMaster(); + if (ropeBindMaster != NULL) + { + idVec3 direction = GetGravityNormal(); + + idPhysics* bindMasterPhysics = ropeBindMaster->GetPhysics(); + + const idVec3& ropeOrigin = ropePhys->GetOrigin(); + + idAFBody* topMostBody = ropePhys->GetBody(0); + if (topMostBody != NULL) + { + // Correct the pull direction using the orientation of the topmost body. + const idMat3& axis = topMostBody->GetWorldAxis(); + direction = topMostBody->GetWorldAxis() * ropeShaft; + } + + bindMasterPhysics->ApplyImpulse(0, ropeOrigin, direction * mass * cv_tdm_rope_pull_force_factor.GetFloat()); + } + + idVec3 vImpulse = playerVel - (playerVel * climbDir) * climbDir; + vImpulse *= mass; + + // ishtvan fix: Always translational force, do not torque the rope body + // ropePhys->AddForce( bodID, ropePoint, vImpulse/0.1f ); + ropePhys->AddForce( bodID, ropePhys->GetOrigin(bodID), vImpulse/0.1f ); + } + +// ======================== Rope Swinging ===================== + if( ( player->usercmd.buttons & BUTTON_ATTACK ) && !( player->oldButtons & BUTTON_ATTACK ) + && (gameLocal.time - m_RopeKickTime) > cv_pm_rope_swing_reptime.GetInteger() ) + { + // default kick direction is forward + idVec3 kickDir = player->firstPersonViewAxis[0]; + idVec3 bodyOrig = ropePhys->GetOrigin(bodID); + idMat3 rotDir = mat3_identity; + // apply modifiers if holding left/right/back + if( common->ButtonState(UB_MOVELEFT) ) + { + rotDir = idAngles(0.0f, 90.0f, 0.0f).ToMat3(); + } + else if( common->ButtonState(UB_MOVERIGHT) ) + { + rotDir = idAngles(0.0f, 270.0f, 0.0f).ToMat3(); + } + else if( common->ButtonState(UB_BACK) ) + { + rotDir = idAngles(0.0f, 180.0f, 0.0f).ToMat3(); + } + kickDir = rotDir * kickDir; + + // do a trace to see if a solid is in the way, if so, kick off of it + trace_t trKick; + + gameLocal.clip.TracePoint + ( + trKick, bodyOrig, + bodyOrig + cv_pm_rope_swing_kickdist.GetFloat()*kickDir, + MASK_SOLID, self + ); + if( trKick.fraction < 1.0f ) + { + // reverse direction to kick off + kickDir *= -1.0f; + // apply reaction force to entity kicked (TODO: watch out for exploits) + idEntity *kickedEnt = gameLocal.entities[trKick.c.entityNum]; + float kickMag = cv_pm_rope_swing_impulse.GetFloat() / 25.0f; // divide by 25, it takes a lot to move AFs for some reason + kickedEnt->ApplyImpulse( self, trKick.c.id, trKick.c.point, -kickMag * kickDir ); + } + + // project to XY plane + kickDir -= GetGravityNormal() * (kickDir*GetGravityNormal()); + kickDir.Normalize(); + + ropePhys->AddForce( bodID, bodyOrig, kickDir * cv_pm_rope_swing_impulse.GetFloat() ); + // test: apply velocity to all bodies lower as well? + m_RopeKickTime = gameLocal.time; + } + +// ==== Translate the player to the rope attachment point ===== + + offset = (current.origin - ropePoint); + offset.ProjectOntoPlane( -gravityNormal ); + offset.Normalize(); + offset *= ROPE_DISTANCE; + + newOrigin = ropePoint + offset; + transVec = newOrigin - current.origin; + transVec -= (transVec * gravityNormal)*gravityNormal; + + // check whether the player will clip anything, and only translate up to that point + ClipTranslation(transTrace, transVec, NULL); + newOrigin = current.origin + (transVec * transTrace.fraction); + Translate( newOrigin - current.origin ); + + + // Find the top and bottom of the rope + // This must be done every frame since the rope may be deforming + ropeBounds = m_RopeEntity.GetEntity()->GetPhysics()->GetAbsBounds(); + ropeTop = ropeBounds[0] * -gravityNormal; + ropeBot = ropeBounds[1] * -gravityNormal; + + if( ropeTop < ropeBot ) + { + // switch 'em + temp = ropeTop; + ropeTop = ropeBot; + ropeBot = temp; + } + + // ============== read mouse input and orbit around the rope =============== + + // recalculate offset because the player may have moved to stick point + offset = (ropePoint - current.origin); + offset.ProjectOntoPlane( -gravityNormal ); + offset.Normalize(); + + // forward vector orthogonal to gravity + forward = viewForward - (gravityNormal * viewForward) * gravityNormal; + forward.Normalize(); + + deltaAng1 = offset * forward; + deltaYaw = m_DeltaViewYaw; + + // use a different tolerance for rotating toward the rope vs away + // rotate forward by deltaAng to see if we are rotating towards or away from the rope + idRotation rotateView( vec3_origin, -gravityNormal, -deltaYaw ); + rotateView.RotatePoint( forward ); + + deltaAng2 = offset * forward; + + + // only rotate around the rope if looking at the rope to within some angular tolerance + // always rotate if shifting view away + if( deltaAng1 >= idMath::Cos( ROPE_ROTANG_TOL ) + || ( (deltaAng2 < deltaAng1) && deltaAng1 > 0 ) ) + { + + newOrigin = current.origin; + + // define the counter-rotation around the rope point using gravity axis + idRotation rotatePlayer( ropePoint, -gravityNormal, -deltaYaw ); + rotatePlayer.RotatePoint( newOrigin ); + + // check whether the player will clip anything when orbiting + transVec = newOrigin - current.origin; + ClipTranslation(transTrace, transVec, NULL); + newOrigin = current.origin + (transVec * transTrace.fraction); + + Translate( newOrigin - current.origin ); + } + + + // ================ read control input for climbing movement =============== + + upscale = (climbDir * viewForward - 0.5f) * 2.5f; + if ( upscale > 1.0f ) + { + upscale = 1.0f; + } + else if ( upscale < -1.0f ) + { + upscale = -1.0f; + } + + scale = idPhysics_Player::CmdScale( command ); + // up down movement + + wishvel = 0.9f * climbDir * upscale * scale * (float)command.forwardmove; + + /* greebo: Removed command.upmove portion from wishvel. I guess this was to support + the old crouching code which set command.upmove to negative values. This code + is no longer there so command.upmove is only non-zero during jumping, + which we can ignore here. + + if ( command.upmove ) + { + wishvel += 0.5f * climbDir * scale * (float) command.upmove; + }*/ + + // detach the player from the rope if they jump + if ( idPhysics_Player::CheckRopeJump()) + { + RopeDetach(); + goto Quit; + } + + // if the player is above the top of the rope, don't climb up + // if the player is at the bottom of the rope, don't climb down + // subtract some amount to represent hanging on with arms above head + if ( + ( + wishvel * gravityNormal <= 0.0f + && (((current.origin * -gravityNormal) + ROPE_GRABHEIGHT ) > ropeTop) + ) + || + ( + wishvel * gravityNormal >= 0.0f + && (((current.origin * -gravityNormal) + ROPE_GRABHEIGHT + 35.0f) < ropeBot) + ) + ) + { + current.velocity -= (current.velocity * climbDir) * climbDir; + goto Quit; + } + + // accelerate + wishspeed = wishvel.Normalize(); + idPhysics_Player::Accelerate( wishvel, wishspeed, PM_ACCELERATE ); + + // cap the climb velocity + upscale = current.velocity * -climbDir; + if ( upscale < -PM_ROPESPEED ) + { + current.velocity += climbDir * (upscale + PM_ROPESPEED); + } + else if ( upscale > PM_ROPESPEED ) + { + current.velocity += climbDir * (upscale - PM_ROPESPEED); + } + + // stop the player from sliding when they let go of the button + if ( (wishvel * gravityNormal) == 0.0f ) + { + if ( current.velocity * gravityNormal < 0.0f ) + { + current.velocity += gravityVector * frametime; + if ( current.velocity * gravityNormal > 0.0f ) + { + current.velocity -= (gravityNormal * current.velocity) * gravityNormal; + } + } + else + { + current.velocity -= gravityVector * frametime; + if ( current.velocity * gravityNormal < 0.0f ) + { + current.velocity -= (gravityNormal * current.velocity) * gravityNormal; + } + } + } + + // If the player is climbing down and hits the ground, detach them from the rope + if ( (wishvel * gravityNormal) > 0.0f && groundPlane ) + { + RopeDetach(); + goto Quit; + } + + // move the player velocity back into the world frame + current.velocity += m_RefEntVelocity; + + // slide the player up and down with their calculated velocity + idPhysics_Player::SlideMove( false, ( command.forwardmove > 0 ), false, false ); + +Quit: + return; +} +#pragma warning( default : 4533 ) + +/* +============ +idPhysics_Player::RopeDetach +============ +*/ +void idPhysics_Player::RopeDetach() +{ + m_bOnRope = false; + + // start the reattach timer + SetNextAttachTime(gameLocal.time + cv_tdm_reattach_delay.GetFloat()); + + static_cast(self)->SetImmobilization( "RopeMove", 0 ); + + // move the player velocity back into the world frame + current.velocity += m_RefEntVelocity; + + // switch movement modes to the appropriate one + if ( waterLevel > WATERLEVEL_FEET ) + { + WaterMove(); + } + else + { + AirMove(); + } +} + +/* +============ +idPhysics_Player::ClimbDetach +============ +*/ +void idPhysics_Player::ClimbDetach( bool bStepUp ) +{ + m_bOnClimb = false; + m_ClimbingOnEnt = NULL; + m_bClimbDetachThisFrame = true; + + static_cast(self)->SetImmobilization("ClimbMove", 0); + + current.velocity += m_RefEntVelocity; + + // switch movement modes to the appropriate one + if( bStepUp ) + { + // Step up at the top of a ladder + idVec3 ClimbNormXY = m_vClimbNormal - (gravityNormal * m_vClimbNormal) * gravityNormal; + ClimbNormXY.Normalize(); + current.velocity += -ClimbNormXY * LADDER_TOPVELOCITY; + idPhysics_Player::SlideMove( false, true, false, true ); + } + else if ( waterLevel > WATERLEVEL_FEET ) + { + WaterMove(); + } + else + { + AirMove(); + } + + SetNextAttachTime(gameLocal.time + cv_tdm_reattach_delay.GetFloat()); + +} + +/* +============ +idPhysics_Player::LadderMove +============ +*/ +void idPhysics_Player::LadderMove( void ) +{ + idVec3 wishdir( vec3_zero ), wishvel( vec3_zero ), right( vec3_zero ); + idVec3 dir( vec3_zero ), start( vec3_zero ), end( vec3_zero ), delta( vec3_zero ); + idVec3 AttachVel( vec3_zero ), RefFrameVel( vec3_zero ); + idVec3 vReqVert( vec3_zero ), vReqHoriz( vec3_zero ), vHorizVect( vec3_zero ); + float wishspeed(0.0f), scale(0.0f), accel(0.0f); + float upscale(0.0f), horizscale(0.0f), NormalDot(0.0f); + trace_t SurfTrace; + bool bMoveAllowed( true ); + + accel = PM_ACCELERATE; + + // TODO: Support non-rope climbable AFs by storing the AF body hit in the trace? + SetRefEntVel( m_ClimbingOnEnt.GetEntity() ); + + // Move player into climbed on ent reference frame + current.velocity -= m_RefEntVelocity; + + idVec3 ClimbNormXY = m_vClimbNormal - (m_vClimbNormal * gravityNormal) * gravityNormal; + ClimbNormXY.Normalize(); + + // jump off the climbable surface if they jump, or fall off if they hit crouch + // angua: detaching when hitting crouch is handled in idPlayer::PerformImpulse + if (idPhysics_Player::CheckRopeJump()) + { + ClimbDetach(); + return; + } + + NormalDot = ClimbNormXY * viewForward; + // detach if their feet are on the ground walking away from the surface + if ( walking && -NormalDot * command.forwardmove < LADDER_WALKDETACH_DOT ) + { + ClimbDetach(); + return; + } + + // ====================== stick to the ladder ======================== + // Do a trace to figure out where to attach the player: + start = current.origin; + end = start - 48.0f * ClimbNormXY; + gameLocal.clip.Translation( SurfTrace, start, end, clipModel, clipModel->GetAxis(), clipMask, self ); + + // if there is a climbable surface in front of the player, stick to it + + idEntity* testEnt = gameLocal.entities[SurfTrace.c.entityNum]; // grayman #2787 + bool isVine = ( testEnt && testEnt->IsType( tdmVine::Type ) ); // grayman #2787 + if ( ( SurfTrace.fraction != 1.0f ) && + ( ( SurfTrace.c.material && SurfTrace.c.material->IsLadder() ) || isVine ) ) // grayman #2787 + { + // grayman #2787 - smooth out the end position if you struck a climbable vine piece. + // This fixes the choppy sideways movement on a vine. + + idVec3 endPoint = SurfTrace.endpos; + idVec3 p = endPoint; + if ( isVine ) + { + idVec3 vineOrigin = testEnt->GetPhysics()->GetOrigin(); + idVec3 vinePeak = vineOrigin + 3.875 * ClimbNormXY; // 3.875 is the distance from the vine origin to its peak + float c = ( vinePeak - start ) * ClimbNormXY; + float e = -ClimbNormXY * ClimbNormXY; + idVec3 size = GetBounds().GetSize(); + p = start - ( c/e - size.x/2 )*ClimbNormXY; + } + + m_vClimbPoint = p + cv_pm_climb_distance.GetFloat() * ClimbNormXY; +// m_vClimbPoint = endPoint + cv_pm_climb_distance.GetFloat() * ClimbNormXY; + AttachVel = 10 * (m_vClimbPoint - current.origin); + + // Now that we have a valid point, don't need to use the initial one + m_bClimbInitialPhase = false; + + // Update sounds and movement speed caps for the surface if we change surfaces + idStr surfName = g_Global.GetSurfName(SurfTrace.c.material); + + if (surfName != m_ClimbSurfName) + { + idStr LookUpName, TempStr; + const idKeyValue *kv = NULL; + + m_ClimbSurfName = surfName; + + LookUpName = "climb_max_speed_vert_"; + TempStr = LookUpName + surfName; + if( ( kv = self->spawnArgs.FindKey(LookUpName.c_str()) ) != NULL ) + m_ClimbMaxVelVert = atof( kv->GetValue().c_str() ); + else + { + TempStr = LookUpName + "default"; + m_ClimbMaxVelVert = self->spawnArgs.GetFloat( LookUpName.c_str(), "1.0" ); + } + + LookUpName = "climb_max_speed_horiz_"; + TempStr = LookUpName + surfName; + if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) + m_ClimbMaxVelHoriz = atof( kv->GetValue().c_str() ); + else + { + TempStr = LookUpName + "default"; + m_ClimbMaxVelHoriz = self->spawnArgs.GetFloat( LookUpName.c_str(), "2.3" ); + } + + // sound repitition distances + LookUpName = "climb_snd_repdist_vert_"; + TempStr = LookUpName + surfName; + if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) + m_ClimbSndRepDistVert = atoi( kv->GetValue().c_str() ); + else + { + TempStr = LookUpName + "default"; + m_ClimbSndRepDistVert = self->spawnArgs.GetInt( LookUpName.c_str(), "32" ); + } + + // sound repitition distances + LookUpName = "climb_snd_repdist_horiz_"; + TempStr = LookUpName + surfName; + if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) + m_ClimbSndRepDistHoriz = atoi( kv->GetValue().c_str() ); + else + { + TempStr = LookUpName + "default"; + m_ClimbSndRepDistHoriz = self->spawnArgs.GetInt( LookUpName.c_str(), "32" ); + } + } + } + else if( m_bClimbInitialPhase ) + { + // We should already have m_vClimbPoint stored from the initial trace + AttachVel = 12.0f * (m_vClimbPoint - current.origin); + } + + current.velocity = (gravityNormal * current.velocity) * gravityNormal + AttachVel; + + scale = idPhysics_Player::CmdScale( command ); + + float lenVert = viewForward * -gravityNormal; + float lenTransv = idMath::Sqrt( 1.0f - NormalDot * NormalDot - lenVert * lenVert ); + // Dump everything that's not in the transverse direction into the vertical direction + float lenVert2 = idMath::Sqrt( 1.0f - lenTransv * lenTransv ); + + // resolve up/down, with some tolerance so player can still go up looking slightly down + if( lenVert < -0.3 ) + lenVert2 = -lenVert2; + + vReqVert = lenVert2 * -gravityNormal * scale * (float)command.forwardmove; + vReqVert *= m_ClimbMaxVelVert; + + // obtain the horizontal direction + vReqHoriz = viewForward - (ClimbNormXY * viewForward) * ClimbNormXY; + vReqHoriz -= (vReqHoriz * gravityNormal) * gravityNormal; + vReqHoriz.Normalize(); + vReqHoriz *= lenTransv * scale * (float)command.forwardmove; + vReqHoriz *= m_ClimbMaxVelHoriz; + + + // Pure horizontal motion if looking close enough to horizontal: + if( lenTransv > 0.906 ) + wishvel = vReqHoriz; + else + wishvel = vReqVert + vReqHoriz; + + // strafe + if ( command.rightmove ) + { + // right vector orthogonal to gravity + right = viewRight - (gravityNormal * viewRight) * gravityNormal; + // project right vector into ladder plane + right = right - (ClimbNormXY * right) * ClimbNormXY; + right.Normalize(); + + wishvel += m_ClimbMaxVelHoriz * right * scale * (float) command.rightmove; + } + + // ========================== Surface Extent Test ====================== + // This now just checks distance from the last valid climbing point + dir = wishvel; + dir.Normalize(); + + end = start + wishvel * frametime + dir * CLIMB_SURFCHECK_DELTA; + delta = m_vClimbPoint - end; + if( delta.LengthSqr() > LADDER_DISTAWAY * LADDER_DISTAWAY ) + bMoveAllowed = false; + + if( !bMoveAllowed ) + { + // If we were trying to go up and reached the extent, attempt to step off the ladder + // Make sure we are really trying to go up, not first going off to the side and then up + // TODO: Tweak this delta.lengthsqr parameter of 25.0, only measure in the horizontal axis? + delta = current.origin - m_vClimbPoint; + delta -= (delta * gravityNormal) * gravityNormal; + + if( NormalDot < 0.0f && -wishvel * gravityNormal > 0 && delta.LengthSqr() < 25.0f ) + { + ClimbDetach( true ); + return; + } + + accel = idMath::INFINITY; + wishvel = vec3_zero; + } + + // ========================== End Surface Extent Test ================== + + // do strafe friction + idPhysics_Player::Friction(); + + // accelerate + wishspeed = wishvel.Normalize(); + idPhysics_Player::Accelerate( wishvel, wishspeed, accel ); + + // cap the vertical travel velocity + upscale = current.velocity * -gravityNormal; + if ( upscale < -m_ClimbMaxVelVert * playerSpeed ) + current.velocity += gravityNormal * (upscale + m_ClimbMaxVelVert * playerSpeed ); + else if ( upscale > m_ClimbMaxVelVert * playerSpeed ) + current.velocity += gravityNormal * (upscale - m_ClimbMaxVelVert * playerSpeed ); + + // cap the horizontal travel velocity + vHorizVect = current.velocity - (current.velocity * gravityNormal) * gravityNormal; + horizscale = vHorizVect.Normalize(); + float horizDelta = horizscale; + horizscale = idMath::ClampFloat( -m_ClimbMaxVelHoriz * playerSpeed, m_ClimbMaxVelHoriz * playerSpeed, horizscale ); + horizDelta -= horizscale; + current.velocity -= vHorizVect * horizDelta; + + if ( (wishvel * gravityNormal) == 0.0f ) + { + if ( current.velocity * gravityNormal < 0.0f ) + { + current.velocity += gravityVector * frametime; + if ( current.velocity * gravityNormal > 0.0f ) + { + current.velocity -= (gravityNormal * current.velocity) * gravityNormal; + } + } + else { + current.velocity -= gravityVector * frametime; + if ( current.velocity * gravityNormal < 0.0f ) + { + current.velocity -= (gravityNormal * current.velocity) * gravityNormal; + } + } + } + + // Move player velocity back into the world frame + current.velocity += m_RefEntVelocity; + + idPhysics_Player::SlideMove( false, ( command.forwardmove > 0 ), false, false ); +} + +/* +============= +idPhysics_Player::CorrectAllSolid +============= +*/ +void idPhysics_Player::CorrectAllSolid( trace_t &trace, int contents ) { + if ( debugLevel ) { + gameLocal.Printf( "%i:allsolid\n", c_pmove ); + } + + // SophisticatedZombie + //DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing CorrectAllSolid due to player inside solid object\n"); + // + // Don't bump player up if they're standing in a previously picked up objects. + // This is complicated but because we want free object movement, we have to temporarily disable player clipping. + // But, if a players releases an object when they're inside it they float to the surface. By doing this check + // we can avoid that. + // ishtvan: Only use the "rising code" if we're still clipping something after a mantle has finished + if( m_mantlePhase == fixClipping_DarkModMantlePhase + && !gameLocal.m_Grabber->HasClippedEntity() ) + { + current.origin -= (GetGravityNormal() * 0.2f); + } + + + // FIXME: jitter around to find a free spot ? + + if ( trace.fraction >= 1.0f ) { + memset( &trace, 0, sizeof( trace ) ); + trace.endpos = current.origin; + trace.endAxis = clipModelAxis; + trace.fraction = 0.0f; + trace.c.dist = current.origin.z; + trace.c.normal.Set( 0, 0, 1 ); + trace.c.point = current.origin; + trace.c.entityNum = ENTITYNUM_WORLD; + trace.c.id = 0; + trace.c.type = CONTACT_TRMVERTEX; + trace.c.material = NULL; + trace.c.contents = contents; + } +} + +/* +============= +idPhysics_Player::CheckGround +============= +*/ +void idPhysics_Player::CheckGround( void ) { + int i, contents; + idVec3 point; + bool hadGroundContacts; + + hadGroundContacts = HasGroundContacts(); + + // set the clip model origin before getting the contacts + clipModel->SetPosition( current.origin, clipModel->GetAxis() ); + + EvaluateContacts(); + + // setup a ground trace from the contacts + groundTrace.endpos = current.origin; + groundTrace.endAxis = clipModel->GetAxis(); + if ( contacts.Num() ) { + groundTrace.fraction = 0.0f; + groundTrace.c = contacts[0]; + for ( i = 1; i < contacts.Num(); i++ ) { + groundTrace.c.normal += contacts[i].normal; + } + groundTrace.c.normal.Normalize(); + } else { + groundTrace.fraction = 1.0f; + } + + contents = gameLocal.clip.Contents( current.origin, clipModel, clipModel->GetAxis(), -1, self ); + if ( contents & MASK_SOLID ) + { + // do something corrective if stuck in solid + idPhysics_Player::CorrectAllSolid( groundTrace, contents ); + } + else if ( m_mantlePhase == fixClipping_DarkModMantlePhase ) + { + // the mantle stage can advance to done if we're not currently clipping + m_mantlePhase = notMantling_DarkModMantlePhase; + } + + // if the trace didn't hit anything, we are in free fall + if ( groundTrace.fraction == 1.0f ) + { + groundPlane = false; + walking = false; + groundEntityPtr = NULL; + return; + } + + groundMaterial = groundTrace.c.material; + + // Store the ground entity + idEntity* groundEnt = gameLocal.entities[ groundTrace.c.entityNum ]; + groundEntityPtr = groundEnt; + + // check if getting thrown off the ground + if ( (current.velocity * -gravityNormal) > 0.0f && ( current.velocity * groundTrace.c.normal ) > 10.0f ) { + if ( debugLevel ) { + gameLocal.Printf( "%i:kickoff\n", c_pmove ); + } + + groundPlane = false; + walking = false; + return; + } + + // grayman #2409 - apply velocity change due to friction loss on slick surfaces + + bool slick = (groundMaterial && (groundMaterial->IsSlick())); + float walkNormal = MIN_WALK_NORMAL; + if (slick) + { + idVec3 velocityChange = groundTrace.c.normal; + velocityChange.z = 0; // no vertical component + current.velocity += 3*velocityChange; + walkNormal = MIN_WALK_SLICK_NORMAL; + } + + // slopes that are too steep will not be considered onground + if ( ( groundTrace.c.normal * -gravityNormal ) < walkNormal ) // grayman #2409 + { + if ( debugLevel ) { + gameLocal.Printf( "%i:steep\n", c_pmove ); + } + + // FIXME: if they can't slide down the slope, let them walk (sharp crevices) + + // make sure we don't die from sliding down a steep slope + if ( current.velocity * gravityNormal > 150.0f ) { + current.velocity -= ( current.velocity * gravityNormal - 150.0f ) * gravityNormal; + } + + groundPlane = true; + walking = false; + return; + } + + groundPlane = true; + walking = true; + + // hitting solid ground will end a waterjump + if ( current.movementFlags & PMF_TIME_WATERJUMP ) { + current.movementFlags &= ~( PMF_TIME_WATERJUMP | PMF_TIME_LAND ); + current.movementTime = 0; + } + + // if the player didn't have ground contacts the previous frame + if ( !hadGroundContacts ) { + // greebo: Set the "jump" deadtime in any case to 100 msec to disallow jumps for small timespan + current.movementTime = 100; + + // don't do landing time if we were just going down a slope + if ( (current.velocity * -gravityNormal) < -200.0f ) { + // don't allow another jump for a little while + current.movementFlags |= PMF_TIME_LAND; + current.movementTime = 100; + } + } + + // let the entity know about the collision + self->Collide( groundTrace, current.velocity ); + + groundEnt = groundEntityPtr.GetEntity(); + + if ( groundTrace.c.entityNum != ENTITYNUM_WORLD && groundEnt != NULL ) + { + idPhysics* groundPhysics = groundEnt->GetPhysics(); + + impactInfo_t info; + groundEnt->GetImpactInfo( self, groundTrace.c.id, groundTrace.c.point, &info ); + + // greebo: Don't push entities that already have a velocity towards the ground. + if (groundPhysics != NULL && info.invMass != 0.0f && + idMath::Fabs(groundPhysics->GetLinearVelocity()*gravityNormal) < VECTOR_EPSILON) + { + // greebo: Apply a force to the entity below the player + //gameRenderWorld->DebugArrow(colorCyan, current.origin, current.origin + gravityNormal*20, 1, 16); + groundPhysics->AddForce(0, current.origin, gravityNormal*mass*cv_pm_weightmod.GetFloat()); + } + } +} + +/* +============== +idPhysics_Player::CheckDuck + +Sets clip model size +============== +*/ +void idPhysics_Player::CheckDuck( void ) { + float maxZ; + + idPlayer* player = static_cast(self); + int oldMovementFlags = current.movementFlags; + + bool idealCrouchState = player->GetIdealCrouchState(); + + if ( current.movementType == PM_DEAD ) { + maxZ = pm_deadheight.GetFloat(); + } else { + // stand up when climbing a ladder or rope + if (idealCrouchState == true && !m_bOnClimb && !m_bOnRope) + { + if (waterLevel <= WATERLEVEL_WAIST) + { + // greebo: We're waist-deep in water, trace down a few units to see if we're standing on ground + trace_t trace; + idVec3 end = current.origin + gravityNormal * 20; + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); + + if (trace.fraction < 1.0f) + { + // We're not floating in deep water, we're standing in waist-deep water, duck as requested. + current.movementFlags |= PMF_DUCKED; + } + } + else + { + // We're outside of water, just duck as requested + current.movementFlags |= PMF_DUCKED; + } + + // greebo: Update the lean physics when crouching + UpdateLeanPhysics(); + } + else if (!IsMantling() && idealCrouchState == false) // MantleMod: SophisticatedZombie (DH): Don't stand up if crouch during mantle + { + // ideal crouch state is not negative anymore, check if we are still in crouch mode + // stand up if appropriate + if ( current.movementFlags & PMF_DUCKED ) + { + bool canStandUp = true; + + if (waterLevel >= WATERLEVEL_HEAD) + { + // greebo: We're still in water, check if there is ground below us so that we can stand up + trace_t trace; + float viewHeightDelta = pm_normalviewheight.GetFloat() - pm_crouchviewheight.GetFloat(); + idVec3 end = current.origin + gravityNormal * viewHeightDelta; + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); + + if (trace.fraction == 1.0f) + { + canStandUp = false; // trace missed, no ground below + } + else + { + // The ground trace hit a target, see if our eyes would emerge from the water + idVec3 pointAboveHead = player->GetEyePosition() - gravityNormal * viewHeightDelta * (1.0f - trace.fraction); + + int contents = gameLocal.clip.Contents( pointAboveHead, NULL, mat3_identity, -1, self ); + if (contents & MASK_WATER) + { + canStandUp = false; // The point above our head is in water + } + } + } + + if (canStandUp) + { + // greebo: We're not in deep water, so try to stand up + idVec3 end = current.origin - ( pm_normalheight.GetFloat() - pm_crouchheight.GetFloat() ) * gravityNormal; + + // Now perform the upwards trace to check if we have room to stand up + trace_t trace; + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); + if ( trace.fraction >= 1.0f ) { + // We have room above us, so turn off the crouch flag + current.movementFlags &= ~PMF_DUCKED; + } + } + } + } + + // TODO_CROUCH: don't use crouch speed while climbing + if ( current.movementFlags & PMF_DUCKED ) + { + playerSpeed = crouchSpeed; + maxZ = pm_crouchheight.GetFloat(); + } + else + { + maxZ = pm_normalheight.GetFloat(); + } + + if (waterLevel == WATERLEVEL_HEAD) + { + // greebo: We're underwater, set the clipmodel to the crouched size + maxZ = pm_crouchheight.GetFloat(); + + // greebo: But still let the player swim as fast as if he was uncrouched + playerSpeed = walkSpeed; + } + + // greebo: Check if we've submersed in a liquid. If yes: set the clipmodel to crouchheight + // And set the DUCKED flag to 1. + if (waterLevelChanged) + { + if (waterLevel == WATERLEVEL_HEAD) + { + // We've just submersed into water, set the model to ducked + current.movementFlags |= PMF_DUCKED; + + // Translate the origin a bit upwards to prevent the player head from "jumping" downwards + SetOrigin(player->GetEyePosition() + gravityNormal * pm_crouchviewheight.GetFloat()); + + // Set the Eye height directly to the new value, to avoid the smoothing happening in idPlayer::Move() + player->SetEyeHeight(pm_crouchviewheight.GetFloat()); + } + else if ((oldMovementFlags & PMF_DUCKED) && waterLevel == WATERLEVEL_WAIST && previousWaterLevel == WATERLEVEL_HEAD) + { + // angua: only stand up when we should not be crouching + if (idealCrouchState == false) + { + // We're just floating up to the water surface, switch back to non-crouch mode + // Clear the flag again, just to be sure + current.movementFlags &= ~PMF_DUCKED; + + // greebo: Perform a trace to see how far we can move downwards + trace_t trace; + idVec3 end = player->GetEyePosition() + gravityNormal * pm_normalviewheight.GetFloat(); + gameLocal.clip.Translation(trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self); + + // Set the origin to the end position of the trace + SetOrigin(trace.endpos); + + maxZ = pm_normalheight.GetFloat(); + + // Set the Eye height directly to the new value, to avoid the smoothing happening in idPlayer::Move() + player->SetEyeHeight(pm_normalviewheight.GetFloat()); + } + } + } + + // greebo: Update the lean physics when not crouching + UpdateLeanPhysics(); + } + + // if the clipModel height should change + if ( clipModel->GetBounds()[1][2] != maxZ ) + { + idBounds bounds = clipModel->GetBounds(); + bounds[1][2] = maxZ; + if ( pm_usecylinder.GetBool() ) { + clipModel->LoadModel( idTraceModel( bounds, 8 ) ); + } else { + clipModel->LoadModel( idTraceModel( bounds ) ); + } + } +} + +/* +================ +idPhysics_Player::CheckClimbable +DarkMod: Checks ropes, ladders and other climbables +================ +*/ +void idPhysics_Player::CheckClimbable( void ) +{ + if( current.movementTime ) + return; + + // if on the ground moving backwards + // TODO: This causes problems when rope-climbing down a steep incline + if( walking && command.forwardmove <= 0 ) + return; + + // Don't attach to ropes or ladders in the middle of a mantle + if ( IsMantling() ) + return; + + if ( m_bClimbDetachCrouchHeld ) + return; + +/* + // Don't attach if we are holding an object in our hands + if( gameLocal.m_Grabber->GetSelected() != NULL ) + goto Quit; +*/ + + // forward vector orthogonal to gravity + idVec3 forward = viewForward - (gravityNormal * viewForward) * gravityNormal; + forward.Normalize(); + + float tracedist; + if ( walking ) + { + // don't want to get sucked towards the ladder when still walking or when climbing + tracedist = 1.0f; + } + else + { + tracedist = 48.0f; + } + + idVec3 end = current.origin + tracedist * forward; + // modified to check contents_corpse to check for ropes + trace_t trace; + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask | CONTENTS_CORPSE, self ); + + idVec3 delta; + float angleOff; + float dist; + // if near a surface + if ( trace.fraction < 1.0f ) + { + idEntity* testEnt = gameLocal.entities[trace.c.entityNum]; + + // DarkMod: Check if we're looking at a rope and airborne + // TODO: Check the class type instead of the stringname, make new rope class + + if ( testEnt && testEnt->m_bIsClimbableRope ) + { + m_RopeEntTouched = static_cast(testEnt); + + delta = (trace.c.point - current.origin); + delta = delta - (gravityNormal * delta) * gravityNormal; + dist = delta.LengthFast(); + + delta.Normalize(); + angleOff = delta * forward; + + // must be in the air to attach to the rope + // this is kind've a hack, but the rope has a different attach distance than the ladder + if( + !m_bOnRope + && ( (trace.endpos - current.origin).Length() <= 2.0f ) + && !groundPlane + && angleOff >= idMath::Cos( ROPE_ATTACHANGLE ) + && (testEnt != m_RopeEntity.GetEntity() || gameLocal.time > m_NextAttachTime) + ) + { + // make sure rope segment is not touching the ground + int bodyID = m_RopeEntTouched.GetEntity()->BodyForClipModelId( trace.c.id ); + if( !static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->HasGroundContacts( bodyID ) ) + { + m_bRopeContact = true; + m_bJustHitRope = true; + m_RopeEntity = static_cast(testEnt); + + return; + } + } + } + + // if a climbable surface + // grayman #2787 - add a test for a climbable vine. + + bool isVine = ( testEnt && testEnt->IsType( tdmVine::Type ) ); + if ( ( ( trace.c.material && ( trace.c.material->IsLadder() ) ) || isVine ) + && ( gameLocal.time > m_NextAttachTime ) ) + { + idVec3 vStickPoint = trace.endpos; + // check a step height higher + end = current.origin - gravityNormal * ( maxStepHeight * 0.75f ); + gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); + idVec3 start = trace.endpos; + end = start + tracedist * forward; + gameLocal.clip.Translation( trace, start, end, clipModel, clipModel->GetAxis(), clipMask, self ); + + // if also near a surface a step height higher + if ( trace.fraction < 1.0f ) + { + // if it also is a ladder surface + // grayman #2787 - add a test for a climbable vine + + idEntity* testEntHigher = gameLocal.entities[trace.c.entityNum]; // grayman #2787 + bool isVineHigher = ( testEntHigher && testEntHigher->IsType( tdmVine::Type ) ); + if ( ( trace.c.material && trace.c.material->IsLadder() ) || isVineHigher ) // grayman #2787 + { + m_vClimbNormal = trace.c.normal; + if ( isVineHigher ) // grayman #2787 - if climbing a vine, flatten out the normal + { + m_vClimbNormal = testEntHigher->GetPhysics()->GetAxis().ToAngles().ToForward(); + } + m_ClimbingOnEnt = testEntHigher; + + // Initial climbing attachment + // FIX: Used to get stuck hovering in some cases, now there's an initial phase + if ( !m_bOnClimb ) + { + m_bClimbInitialPhase = true; + m_vClimbPoint = vStickPoint; + static_cast(self)->SetImmobilization( "ClimbMove", EIM_WEAPON_SELECT | EIM_ATTACK ); + } + + m_bClimbableAhead = true; + m_bOnClimb = true; + + return; + } + } + } + } + + // Rope attachment failsafe: Check intersection with the rope as well + if + ( + !m_bOnRope + && m_RopeEntTouched.GetEntity() != NULL + && m_RopeEntTouched.GetEntity()->GetPhysics()->GetAbsBounds().IntersectsBounds( self->GetPhysics()->GetAbsBounds() ) + && !groundPlane + ) + { + // test distance against the nearest rope body + int touchedBody = -1; + idVec3 PlayerPoint = current.origin + -gravityNormal*ROPE_GRABHEIGHT; + idVec3 RopeSegPoint = static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->NearestBodyOrig( PlayerPoint, &touchedBody ); + + delta = ( RopeSegPoint - PlayerPoint); + delta = delta - (gravityNormal * delta) * gravityNormal; + dist = delta.LengthFast(); + + delta.Normalize(); + angleOff = delta * forward; + + // if the player is looking high up, override the angle check + float lookUpAng = viewForward * -gravityNormal; + // set lookup to true if the player is looking 60 deg up or more + bool bLookingUp = lookUpAng >= idMath::Cos(idMath::PI/6); + + if + ( + dist <= ROPE_DISTANCE + && ( angleOff >= idMath::Cos( ROPE_ATTACHANGLE ) || bLookingUp ) + && (m_RopeEntTouched.GetEntity() != m_RopeEntity.GetEntity() || gameLocal.time > m_NextAttachTime) + && !static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->HasGroundContacts( touchedBody ) + ) + { + m_bRopeContact = true; + m_bJustHitRope = true; + m_RopeEntity = m_RopeEntTouched.GetEntity(); + return; + } + } +} + +/* +============= +idPhysics_Player::CheckJump +============= +*/ +bool idPhysics_Player::CheckJump() +{ + if ( command.upmove < 10 ) + { + // not holding jump + return false; + } + + // must wait for jump to be released or dead time to have passed + if ( current.movementFlags & PMF_JUMP_HELD || current.movementTime > 0) + { + return false; + } + + groundPlane = false; // jumping away + walking = false; + current.movementFlags |= PMF_JUMP_HELD | PMF_JUMPED; + + idVec3 extraSpeedForward = viewForward - (gravityNormal * viewForward) * gravityNormal; + extraSpeedForward.Normalize(); + + // back paddling ? + if ( command.forwardmove < 0 ) + { + // greebo: Apply a modifier when doing backwards jumps + extraSpeedForward = -extraSpeedForward * cv_tdm_backwards_jump_modifier.GetFloat(); + } + + // strafing right? + if ( command.rightmove > 0) + { + extraSpeedForward = viewRight - (gravityNormal * viewRight) * gravityNormal; + extraSpeedForward.Normalize(); + } + // strafing left? + else if ( command.rightmove < 0 ) + { + extraSpeedForward = viewRight - (gravityNormal * viewRight) * gravityNormal; + extraSpeedForward = -extraSpeedForward; + extraSpeedForward.Normalize(); + } + + idVec3 addVelocity; + float curVelocity = current.velocity.LengthFast(); + + // are we walking? + if ( curVelocity >= cv_tdm_min_vel_jump.GetFloat() && + curVelocity >= pm_walkspeed.GetFloat() && + curVelocity < ( pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat() ) ) + { + addVelocity = cv_tdm_walk_jump_vel.GetFloat() * maxJumpHeight * -gravityVector; + extraSpeedForward *= cv_tdm_fwd_jump_vel.GetFloat(); + } + // running ? + else if ( curVelocity >= cv_tdm_min_vel_jump.GetFloat() + && curVelocity >= cv_pm_runmod.GetFloat()) + { + addVelocity = cv_tdm_run_jump_vel.GetFloat() * maxJumpHeight * -gravityVector; + extraSpeedForward *= cv_tdm_fwd_jump_vel.GetFloat(); + } + // stationary + else + { + addVelocity = 2.0f * maxJumpHeight * -gravityVector; + } + + // angua: reduce jump velocity when crouching, unless we are on a ladder or rope + // cv_tdm_crouch_jump_vel can also be set to 0 to disable jumping while crouching + if ( current.movementFlags & PMF_DUCKED && !OnRope() && !OnLadder()) + { + addVelocity *= cv_tdm_crouch_jump_vel.GetFloat(); + extraSpeedForward *= cv_tdm_crouch_jump_vel.GetFloat(); + } + + if (addVelocity.LengthFast() > 0) + { + addVelocity *= idMath::Sqrt( addVelocity.Normalize() ); + } + + // greebo: Consider jump stamina + float jumpStaminaFactor = 1.0f; + + if (lastJumpTime > -1) + { + int timeSinceLastJump = gameLocal.time - lastJumpTime; + + float jumpRelaxationTime = SEC2MS(cv_tdm_jump_relaxation_time.GetFloat()); + + float factor = timeSinceLastJump * timeSinceLastJump / (jumpRelaxationTime * jumpRelaxationTime); + + jumpStaminaFactor = idMath::ClampFloat(0.2f, 1, factor); + } + + current.velocity += addVelocity + extraSpeedForward * jumpStaminaFactor; + + // Remember the last jump time + if (jumpStaminaFactor > 0.1f) + { + lastJumpTime = gameLocal.time; + } + + return true; +} + +/* +============= +idPhysics_Player::CheckRopeJump +============= +*/ +bool idPhysics_Player::CheckRopeJump( void ) +{ + if ( command.upmove < 10 ) { + // not holding jump + return false; + } + + // must wait for jump to be released + if ( current.movementFlags & PMF_JUMP_HELD ) { + return false; + } + + // angua: should be able to jump on a rope or ladder, even when crouched + // don't jump if we can't stand up + // if ( current.movementFlags & PMF_DUCKED ) { + // return false; + // } + + groundPlane = false; // jumping away + walking = false; + current.movementFlags |= PMF_JUMP_HELD | PMF_JUMPED; + + // the jump direction is an equal sum of up and the direction we're looking + idVec3 jumpDir = viewForward - gravityNormal; + jumpDir *= 1.0f/idMath::Sqrt(2.0f); + +// TODO: Make this an adjustable cvar, currently too high? + idVec3 addVelocity = 2.0f * maxJumpHeight * gravityVector.Length() * jumpDir; + addVelocity *= idMath::Sqrt( addVelocity.Normalize() ); + + current.velocity += addVelocity; + + return true; +} + +/* +============= +idPhysics_Player::CheckWaterJump + +REMOVED from DarkMod +============= +*/ + +/* + +============= + +idPhysics_Player::SetWaterLevel + +For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp + +============= + +*/ + +#ifndef MOD_WATERPHYSICS + +void idPhysics_Player::SetWaterLevel( void ) { + idVec3 point; + idBounds bounds; + int contents; + + // + // get waterlevel, accounting for ducking + // + waterLevel = WATERLEVEL_NONE; + waterType = 0; + + bounds = clipModel->GetBounds(); + + // check at feet level + point = current.origin - ( bounds[0][2] + 1.0f ) * gravityNormal; + contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + + waterType = contents; + waterLevel = WATERLEVEL_FEET; + + // check at waist level + point = current.origin - ( bounds[1][2] - bounds[0][2] ) * 0.5f * gravityNormal; + contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + + waterLevel = WATERLEVEL_WAIST; + + // check at head level + point = current.origin - ( bounds[1][2] - 1.0f ) * gravityNormal; + contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); + if ( contents & MASK_WATER ) { + waterLevel = WATERLEVEL_HEAD; + } + } + } +} +#endif + +/* +================ +idPhysics_Player::DropTimers +================ +*/ +void idPhysics_Player::DropTimers( void ) { + // drop misc timing counter + if ( current.movementTime ) { + if ( framemsec >= current.movementTime ) { + current.movementFlags &= ~PMF_ALL_TIMES; + current.movementTime = 0; + } + else { + current.movementTime -= framemsec; + } + } +} + +/* +================ +idPhysics_Player::MovePlayer +================ +*/ +void idPhysics_Player::MovePlayer( int msec ) { + + // this counter lets us debug movement problems with a journal + // by setting a conditional breakpoint for the previous frame + c_pmove++; + + walking = false; + groundPlane = false; + + m_bRopeContact = false; + m_bClimbableAhead = false; + m_bClimbDetachThisFrame = false; + + // determine the time + framemsec = msec; + frametime = framemsec * 0.001f; + + // default speed + playerSpeed = walkSpeed; + + // remove jumped and stepped up flag + current.movementFlags &= ~(PMF_JUMPED|PMF_STEPPED_UP|PMF_STEPPED_DOWN); + current.stepUp = 0.0f; + + if ( command.upmove < 10 ) { + // not holding jump + current.movementFlags &= ~PMF_JUMP_HELD; + + if (m_mantlePhase == notMantling_DarkModMantlePhase + || m_mantlePhase == fixClipping_DarkModMantlePhase) + { + // greebo: Jump button is released and no mantle phase is active, + // we can allow the next mantling process. + m_mantleStartPossible = true; + } + } + + // if no movement at all + if ( current.movementType == PM_FREEZE ) { + return; + } + + // move the player velocity into the frame of a pusher + current.velocity -= current.pushVelocity; + + // view vectors + viewAngles.ToVectors( &viewForward, NULL, NULL ); + viewForward *= clipModelAxis; + viewRight = gravityNormal.Cross( viewForward ); + viewRight.Normalize(); + + // fly in spectator mode + if ( current.movementType == PM_SPECTATOR ) { + SpectatorMove(); + idPhysics_Player::DropTimers(); + return; + } + + // special no clip mode + if ( current.movementType == PM_NOCLIP ) { + idPhysics_Player::NoclipMove(); + idPhysics_Player::DropTimers(); + return; + } + + // no control when dead + if ( current.movementType == PM_DEAD ) { + command.forwardmove = 0; + command.rightmove = 0; + command.upmove = 0; + } + + // set watertype and waterlevel + idPhysics_Player::SetWaterLevel(true); // greebo: Update the previousWaterLevel here + + // check for ground + idPhysics_Player::CheckGround(); + + // check if a ladder or a rope is straight ahead + idPhysics_Player::CheckClimbable(); + + // set clip model size + idPhysics_Player::CheckDuck(); + + // handle timers + idPhysics_Player::DropTimers(); + + // Mantle Mod: SophisticatdZombie (DH) + idPhysics_Player::UpdateMantleTimers(); + + // Lean Mod: Zaccheus and SophisticatedZombie (DH) + idPhysics_Player::LeanMove(); + + // Check if holding down jump + if (CheckJumpHeldDown()) + { + PerformMantle(); + } + + // move + if ( current.movementType == PM_DEAD ) { + // dead + DeadMove(); + } + // continue moving on the rope if still attached + else if ( m_bOnRope ) + { + // Check rope movement and let go if the rope is moving too fast + float maxRopeVelocity = cv_pm_rope_velocity_letgo.GetFloat(); + idEntity* ropeEntity = m_RopeEntity.GetEntity(); + if (ropeEntity != NULL) + { + + float ropeVelocity = ropeEntity->/*GetBindMaster()->*/GetPhysics()->GetLinearVelocity().z; + + //gameLocal.Printf("Rope Velocity: %f\n", m_RopeEntity.GetEntity()->GetBindMaster()->GetPhysics()->GetLinearVelocity().LengthFast()); + if (ropeVelocity > maxRopeVelocity) + { + gameLocal.Printf("Rope is too fast (%f)! Letting go...\n", ropeVelocity); + RopeDetach(); + } + } + + RopeMove(); + } + // Mantle MOD + // SophisticatedZombie (DH) + // greebo: Do the MantleMove before checking the rope contacts + else if ( !(m_mantlePhase == notMantling_DarkModMantlePhase || m_mantlePhase == fixClipping_DarkModMantlePhase) ) + { + MantleMove(); + } + else if ( m_bRopeContact ) + { + // toggle m_bOnRope + m_bOnRope = true; + + // lower weapon + static_cast(self)->SetImmobilization( "RopeMove", EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_DROP ); + + RopeMove(); + } + else if ( m_bOnClimb ) + { + // going up or down a ladder + LadderMove(); + } + else if ( waterLevel > WATERLEVEL_FEET ) + { + // swimming + WaterMove(); + } + else if ( walking ) { + // walking on ground + WalkMove(); + } + else { + // airborne + AirMove(); + } + + // enable weapon if not swimming + if( waterLevel <= WATERLEVEL_FEET && static_cast(self)->GetImmobilization("WaterMove") ) + { + static_cast(self)->SetImmobilization("WaterMove", 0); + } + + // set watertype, waterlevel and groundentity + SetWaterLevel(false); // greebo: Don't update the previousWaterLevel this time + CheckGround(); + + // move the player velocity back into the world frame + current.velocity += current.pushVelocity; + current.pushVelocity.Zero(); + + // DEBUG + /* + gameRenderWorld->DebugBounds + ( + idVec4 (1.0, 0.0, 1.0, 1.0), + clipModel->GetAbsBounds(), + idVec3 (0.0, 0.0, 0.0) + ); + */ + + m_lastCommandViewYaw = command.angles[1]; + m_lastCommandViewPitch = command.angles[0]; + +} + +#ifndef MOD_WATERPHYSICS + +/* +================ +idPhysics_Player::GetWaterLevel + +For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp + +================ +*/ +waterLevel_t idPhysics_Player::GetWaterLevel( void ) const { + return waterLevel; +} + +/* +================ +idPhysics_Player::GetWaterType + +For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp + +================ +*/ +int idPhysics_Player::GetWaterType( void ) const { + return waterType; +} + +#endif + + +/* +================ +idPhysics_Player::HasJumped +================ +*/ +bool idPhysics_Player::HasJumped( void ) const { + return ( ( current.movementFlags & PMF_JUMPED ) != 0 && current.movementTime <= 0); +} + +/* +================ +idPhysics_Player::HasSteppedUp +================ +*/ +bool idPhysics_Player::HasSteppedUp( void ) const { + return ( ( current.movementFlags & ( PMF_STEPPED_UP | PMF_STEPPED_DOWN ) ) != 0 ); +} + +/* +================ +idPhysics_Player::GetStepUp +================ +*/ +float idPhysics_Player::GetStepUp( void ) const { + return current.stepUp; +} + +/* +================ +idPhysics_Player::IsCrouching +================ +*/ +bool idPhysics_Player::IsCrouching( void ) const { + return ( ( current.movementFlags & PMF_DUCKED ) != 0 ); +} + +idEntity* idPhysics_Player::GetRopeEntity() +{ + return (m_bOnRope) ? m_RopeEntity.GetEntity() : NULL; +} + +/* +================ +idPhysics_Player::OnRope +================ +*/ +bool idPhysics_Player::OnRope( void ) const +{ + return m_bOnRope; +} + + +/* +================ +idPhysics_Player::OnLadder +================ +*/ +bool idPhysics_Player::OnLadder( void ) const { + return m_bOnClimb; +} + +/* +================ +idPhysics_Player::idPhysics_Player +================ +*/ +idPhysics_Player::idPhysics_Player( void ) +{ + debugLevel = false; + clipModel = NULL; + clipMask = 0; + memset( ¤t, 0, sizeof( current ) ); + saved = current; + walkSpeed = 0; + crouchSpeed = 0; + maxStepHeight = 0; + maxJumpHeight = 0; + memset( &command, 0, sizeof( command ) ); + + lastJumpTime = -1; + + viewAngles.Zero(); + framemsec = 0; + frametime = 0; + playerSpeed = 0; + viewForward.Zero(); + viewRight.Zero(); + walking = false; + groundPlane = false; + memset( &groundTrace, 0, sizeof( groundTrace ) ); + groundMaterial = NULL; + + m_RefEntVelocity.Zero(); + + // rope climbing + m_bRopeContact = false; + m_bOnRope = false; + m_bJustHitRope = false; + m_RopeEntity = NULL; + m_RopeEntTouched = NULL; + m_RopeKickTime = 0; + + // wall/ladder climbing + m_bClimbableAhead = false; + m_bOnClimb = false; + m_bClimbDetachThisFrame = false; + m_bClimbInitialPhase = false; + m_vClimbNormal.Zero(); + m_vClimbPoint.Zero(); + m_ClimbingOnEnt = NULL; + m_ClimbSurfName.Clear(); + m_ClimbMaxVelHoriz = 0.0f; + m_ClimbMaxVelVert = 0.0f; + m_ClimbSndRepDistVert = 0; + m_ClimbSndRepDistHoriz = 0; + m_bClimbDetachCrouchHeld = false; + + m_NextAttachTime = -1; + + m_PushForce = CForcePushPtr(new CForcePush); + + // swimming + waterLevel = WATERLEVEL_NONE; + waterType = 0; + + // Mantle Mod + m_mantlePhase = notMantling_DarkModMantlePhase; + m_mantleTime = 0.0; + m_p_mantledEntity = NULL; + m_mantledEntityID = 0; + m_jumpHeldDownTime = 0.0; + m_mantleStartPossible = true; + + // Leaning Mod + m_bIsLeaning = false; + m_leanYawAngleDegrees = 0.0; + m_CurrentLeanTiltDegrees = 0.0; + m_CurrentLeanStretch = 0.0; + m_b_leanFinished = true; + m_leanMoveStartTilt = 0.0; + m_leanMoveEndTilt = 0.0; + m_leanMoveMaxAngle = 0.0; + m_leanMoveMaxStretch = 0.0; + + m_lastCommandViewYaw = 0; + m_lastCommandViewPitch = 0; + m_viewLeanAngles = ang_zero; + m_viewLeanTranslation = vec3_zero; + + m_LeanDoorListenPos = vec3_zero; + m_LeanDoorEnt = NULL; + + m_DeltaViewYaw = 0.0; + m_DeltaViewPitch = 0.0; + + // Initialize lean view bounds used for collision + m_LeanViewBounds.Zero(); + m_LeanViewBounds.ExpandSelf( 4.0f ); + // bounds extend downwards so that player can't lean over very high ledges + idVec3 lowerPoint(0,0,-15.0f); + m_LeanViewBounds.AddPoint( lowerPoint ); +} + +/* +================ +idPhysics_Player_SavePState +================ +*/ +void idPhysics_Player_SavePState( idSaveGame *savefile, const playerPState_t &state ) { + savefile->WriteVec3( state.origin ); + savefile->WriteVec3( state.velocity ); + savefile->WriteVec3( state.localOrigin ); + savefile->WriteVec3( state.pushVelocity ); + savefile->WriteFloat( state.stepUp ); + savefile->WriteInt( state.movementType ); + savefile->WriteInt( state.movementFlags ); + savefile->WriteInt( state.movementTime ); +} + +/* +================ +idPhysics_Player_RestorePState +================ +*/ +void idPhysics_Player_RestorePState( idRestoreGame *savefile, playerPState_t &state ) { + savefile->ReadVec3( state.origin ); + savefile->ReadVec3( state.velocity ); + savefile->ReadVec3( state.localOrigin ); + savefile->ReadVec3( state.pushVelocity ); + savefile->ReadFloat( state.stepUp ); + savefile->ReadInt( state.movementType ); + savefile->ReadInt( state.movementFlags ); + savefile->ReadInt( state.movementTime ); +} + +/* +================ +idPhysics_Player::Save +================ +*/ +void idPhysics_Player::Save( idSaveGame *savefile ) const { + + idPhysics_Player_SavePState( savefile, current ); + idPhysics_Player_SavePState( savefile, saved ); + + savefile->WriteFloat( walkSpeed ); + savefile->WriteFloat( crouchSpeed ); + savefile->WriteFloat( maxStepHeight ); + savefile->WriteFloat( maxJumpHeight ); + savefile->WriteInt( debugLevel ); + savefile->WriteInt(lastJumpTime); + + savefile->WriteUsercmd( command ); + savefile->WriteAngles( viewAngles ); + + savefile->WriteInt( framemsec ); + savefile->WriteFloat( frametime ); + savefile->WriteFloat( playerSpeed ); + savefile->WriteVec3( viewForward ); + savefile->WriteVec3( viewRight ); + + savefile->WriteBool( walking ); + savefile->WriteBool( groundPlane ); + savefile->WriteTrace( groundTrace ); + savefile->WriteMaterial( groundMaterial ); + + savefile->WriteVec3( m_RefEntVelocity ); + + savefile->WriteBool( m_bRopeContact ); + savefile->WriteBool( m_bJustHitRope ); + savefile->WriteBool( m_bOnRope ); + savefile->WriteInt( m_RopeKickTime ); + m_RopeEntity.Save( savefile ); + m_RopeEntTouched.Save( savefile ); + + savefile->WriteBool( m_bClimbableAhead ); + savefile->WriteBool( m_bOnClimb ); + savefile->WriteBool( m_bClimbDetachThisFrame ); + savefile->WriteBool( m_bClimbInitialPhase ); + savefile->WriteVec3( m_vClimbNormal ); + savefile->WriteVec3( m_vClimbPoint ); + savefile->WriteString( m_ClimbSurfName.c_str() ); + savefile->WriteFloat( m_ClimbMaxVelHoriz ); + savefile->WriteFloat( m_ClimbMaxVelVert ); + savefile->WriteInt( m_ClimbSndRepDistVert ); + savefile->WriteInt( m_ClimbSndRepDistHoriz ); + m_ClimbingOnEnt.Save( savefile ); + + savefile->WriteInt( m_NextAttachTime ); + + savefile->WriteInt( (int)waterLevel ); + savefile->WriteInt( waterType ); + + // Mantle mod + savefile->WriteInt(m_mantlePhase); + savefile->WriteBool(m_mantleStartPossible); + savefile->WriteVec3(m_mantlePullStartPos); + savefile->WriteVec3(m_mantlePullEndPos); + savefile->WriteVec3(m_mantlePushEndPos); + savefile->WriteObject(m_p_mantledEntity); + savefile->WriteInt(m_mantledEntityID); + savefile->WriteFloat(m_mantleTime); + savefile->WriteFloat(m_jumpHeldDownTime); + + // Lean mod + savefile->WriteFloat (m_leanYawAngleDegrees); + savefile->WriteFloat (m_CurrentLeanTiltDegrees); + savefile->WriteFloat (m_CurrentLeanStretch); + savefile->WriteFloat (m_leanMoveStartTilt); + savefile->WriteFloat (m_leanMoveEndTilt); + savefile->WriteFloat (m_leanMoveMaxAngle); + savefile->WriteFloat (m_leanMoveMaxStretch); + savefile->WriteBool (m_b_leanFinished); + savefile->WriteFloat (m_leanTime); + savefile->WriteAngles (m_lastPlayerViewAngles); + savefile->WriteAngles (m_viewLeanAngles); + savefile->WriteVec3 (m_viewLeanTranslation); + savefile->WriteVec3 (m_LeanDoorListenPos); + m_LeanDoorEnt.Save( savefile ); + + savefile->WriteStaticObject(*m_PushForce); +} + +/* +================ +idPhysics_Player::Restore +================ +*/ +void idPhysics_Player::Restore( idRestoreGame *savefile ) { + + idPhysics_Player_RestorePState( savefile, current ); + idPhysics_Player_RestorePState( savefile, saved ); + + savefile->ReadFloat( walkSpeed ); + savefile->ReadFloat( crouchSpeed ); + savefile->ReadFloat( maxStepHeight ); + savefile->ReadFloat( maxJumpHeight ); + savefile->ReadInt( debugLevel ); + savefile->ReadInt(lastJumpTime); + + savefile->ReadUsercmd( command ); + savefile->ReadAngles( viewAngles ); + + savefile->ReadInt( framemsec ); + savefile->ReadFloat( frametime ); + savefile->ReadFloat( playerSpeed ); + savefile->ReadVec3( viewForward ); + savefile->ReadVec3( viewRight ); + + savefile->ReadBool( walking ); + savefile->ReadBool( groundPlane ); + savefile->ReadTrace( groundTrace ); + savefile->ReadMaterial( groundMaterial ); + + savefile->ReadVec3( m_RefEntVelocity ); + + savefile->ReadBool( m_bRopeContact ); + savefile->ReadBool( m_bJustHitRope ); + savefile->ReadBool( m_bOnRope ); + savefile->ReadInt( m_RopeKickTime ); + m_RopeEntity.Restore( savefile ); + m_RopeEntTouched.Restore( savefile ); + // Angle storage vars need to be reset on a restore, since D3 resets the command angle to 0 + m_lastCommandViewYaw = 0.0f; + m_lastCommandViewPitch = 0.0f; + m_DeltaViewYaw = 0.0f; + m_DeltaViewPitch = 0.0f; + + savefile->ReadBool( m_bClimbableAhead ); + savefile->ReadBool( m_bOnClimb ); + savefile->ReadBool( m_bClimbDetachThisFrame ); + savefile->ReadBool( m_bClimbInitialPhase ); + savefile->ReadVec3( m_vClimbNormal ); + savefile->ReadVec3( m_vClimbPoint ); + savefile->ReadString( m_ClimbSurfName ); + savefile->ReadFloat( m_ClimbMaxVelHoriz ); + savefile->ReadFloat( m_ClimbMaxVelVert ); + savefile->ReadInt( m_ClimbSndRepDistVert ); + savefile->ReadInt( m_ClimbSndRepDistHoriz ); + m_ClimbingOnEnt.Restore( savefile ); + + savefile->ReadInt( m_NextAttachTime ); + + savefile->ReadInt( (int &)waterLevel ); + savefile->ReadInt( waterType ); + + // Mantle mod + int temp; + savefile->ReadInt(temp); + assert(temp >= 0 && temp < NumMantlePhases); // sanity check + m_mantlePhase = static_cast(temp); + + savefile->ReadBool(m_mantleStartPossible); + savefile->ReadVec3(m_mantlePullStartPos); + savefile->ReadVec3(m_mantlePullEndPos); + savefile->ReadVec3(m_mantlePushEndPos); + savefile->ReadObject(reinterpret_cast(m_p_mantledEntity)); + savefile->ReadInt(m_mantledEntityID); + savefile->ReadFloat(m_mantleTime); + savefile->ReadFloat(m_jumpHeldDownTime); + + // Lean mod + savefile->ReadFloat (m_leanYawAngleDegrees); + savefile->ReadFloat (m_CurrentLeanTiltDegrees); + savefile->ReadFloat (m_CurrentLeanStretch); + savefile->ReadFloat (m_leanMoveStartTilt); + savefile->ReadFloat (m_leanMoveEndTilt); + savefile->ReadFloat (m_leanMoveMaxAngle); + savefile->ReadFloat (m_leanMoveMaxStretch); + savefile->ReadBool (m_b_leanFinished); + savefile->ReadFloat (m_leanTime); + savefile->ReadAngles (m_lastPlayerViewAngles); + savefile->ReadAngles (m_viewLeanAngles); + savefile->ReadVec3 (m_viewLeanTranslation); + savefile->ReadVec3 (m_LeanDoorListenPos); + m_LeanDoorEnt.Restore( savefile ); + + savefile->ReadStaticObject( *m_PushForce ); + + // ishtvan: To avoid accidental latching, clear held crouch key var + m_bClimbDetachCrouchHeld = false; + + DM_LOG (LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Restore finished\n"); +} + +/* +================ +idPhysics_Player::SetPlayerInput +================ +*/ +void idPhysics_Player::SetPlayerInput( const usercmd_t &cmd, const idAngles &newViewAngles ) +{ + command = cmd; + + m_DeltaViewYaw = command.angles[1] - m_lastCommandViewYaw; + m_DeltaViewPitch = command.angles[0] - m_lastCommandViewPitch; + m_DeltaViewYaw = SHORT2ANGLE(m_DeltaViewYaw); + m_DeltaViewPitch = SHORT2ANGLE(m_DeltaViewPitch); + + // Test for pitch clamping + float TestPitch = viewAngles.pitch + m_DeltaViewPitch; + TestPitch = idMath::AngleNormalize180( TestPitch ); + + if( TestPitch > pm_maxviewpitch.GetFloat() ) + m_DeltaViewPitch = pm_maxviewpitch.GetFloat() - viewAngles.pitch; + else if( TestPitch < pm_minviewpitch.GetFloat() ) + m_DeltaViewPitch = pm_minviewpitch.GetFloat() - viewAngles.pitch; + + // zero the delta angles if the player's view is locked in place + if( static_cast(self)->GetImmobilization() & EIM_VIEW_ANGLE ) + { + m_DeltaViewYaw = 0.0f; + m_DeltaViewPitch = 0.0f; + } + + viewAngles = newViewAngles; // can't use cmd.angles cause of the delta_angles + + m_lastCommandViewYaw = command.angles[1]; + m_lastCommandViewPitch = command.angles[0]; +} + +/* +================ +idPhysics_Player::SetSpeed +================ +*/ +void idPhysics_Player::SetSpeed( const float newWalkSpeed, const float newCrouchSpeed ) +{ + walkSpeed = newWalkSpeed; + crouchSpeed = newCrouchSpeed; +} + +/* +================ +idPhysics_Player::SetMaxStepHeight +================ +*/ +void idPhysics_Player::SetMaxStepHeight( const float newMaxStepHeight ) { + maxStepHeight = newMaxStepHeight; +} + +/* +================ +idPhysics_Player::GetMaxStepHeight +================ +*/ +float idPhysics_Player::GetMaxStepHeight( void ) const { + return maxStepHeight; +} + +/* +================ +idPhysics_Player::SetMaxJumpHeight +================ +*/ +void idPhysics_Player::SetMaxJumpHeight( const float newMaxJumpHeight ) { + maxJumpHeight = newMaxJumpHeight; +} + +/* +================ +idPhysics_Player::SetMovementType +================ +*/ +void idPhysics_Player::SetMovementType( const pmtype_t type ) { + current.movementType = type; +} + +/* +================ +idPhysics_Player::GetMovementType - grayman #2345 +================ +*/ +int idPhysics_Player::GetMovementType( void ) { + return current.movementType; +} + +/* +================ +idPhysics_Player::SetKnockBack +================ +*/ +void idPhysics_Player::SetKnockBack( const int knockBackTime ) { + if ( current.movementTime ) { + return; + } + current.movementFlags |= PMF_TIME_KNOCKBACK; + current.movementTime = knockBackTime; +} + +/* +================ +idPhysics_Player::SetDebugLevel +================ +*/ +void idPhysics_Player::SetDebugLevel( bool set ) { + debugLevel = set; +} + +/* +================ +idPhysics_Player::Evaluate +================ +*/ +bool idPhysics_Player::Evaluate( int timeStepMSec, int endTimeMSec ) { + idVec3 masterOrigin, oldOrigin; + idMat3 masterAxis; + + // greebo: Don't clear the WATERLEVELs each frame, they are updated anyway. + //waterLevel = WATERLEVEL_NONE; + //waterType = 0; + oldOrigin = current.origin; + + clipModel->Unlink(); + + // if bound to a master + if ( masterEntity ) + { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + current.localOrigin * masterAxis; + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + current.velocity = ( current.origin - oldOrigin ) / ( timeStepMSec * 0.001f ); + masterDeltaYaw = masterYaw; + masterYaw = masterAxis[0].ToYaw(); + masterDeltaYaw = masterYaw - masterDeltaYaw; + return true; + } + + ActivateContactEntities(); + + MovePlayer( timeStepMSec ); + + // Apply the push force to all objects encountered during MovePlayer + m_PushForce->Evaluate(timeStepMSec); + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + + if ( IsOutsideWorld() ) { + gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) ); + } + + return true; //( current.origin != oldOrigin ); +} + +/* +================ +idPhysics_Player::UpdateTime +================ +*/ +void idPhysics_Player::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_Player::GetTime +================ +*/ +int idPhysics_Player::GetTime( void ) const { + return gameLocal.time; +} + +/* +================ +idPhysics_Player::GetImpactInfo +================ +*/ +void idPhysics_Player::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + info->invMass = invMass; + info->invInertiaTensor.Zero(); + info->position.Zero(); + info->velocity = current.velocity; +} + +/* +================ +idPhysics_Player::ApplyImpulse +================ +*/ +void idPhysics_Player::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + if ( current.movementType != PM_NOCLIP ) { + current.velocity += impulse * invMass; + } +} + +/* +================ +idPhysics_Player::IsAtRest +================ +*/ +bool idPhysics_Player::IsAtRest( void ) const { + return false; +} + +/* +================ +idPhysics_Player::GetRestStartTime +================ +*/ +int idPhysics_Player::GetRestStartTime( void ) const { + return -1; +} + +/* +================ +idPhysics_Player::SaveState +================ +*/ +void idPhysics_Player::SaveState( void ) { + saved = current; +} + +/* +================ +idPhysics_Player::RestoreState +================ +*/ +void idPhysics_Player::RestoreState( void ) { + current = saved; + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + + EvaluateContacts(); +} + +/* +================ +idPhysics_Player::SetOrigin +================ +*/ +void idPhysics_Player::SetOrigin( const idVec3 &newOrigin, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localOrigin = newOrigin; + if ( masterEntity ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + newOrigin * masterAxis; + } + else { + current.origin = newOrigin; + } + + clipModel->Link( gameLocal.clip, self, 0, newOrigin, clipModel->GetAxis() ); +} + +/* +================ +idPhysics_Player::GetOrigin +================ +*/ +const idVec3 & idPhysics_Player::PlayerGetOrigin( void ) const { + return current.origin; +} + +/* +================ +idPhysics_Player::SetAxis +================ +*/ +void idPhysics_Player::SetAxis( const idMat3 &newAxis, int id ) { + clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), newAxis ); +} + +/* +================ +idPhysics_Player::Translate +================ +*/ +void idPhysics_Player::Translate( const idVec3 &translation, int id ) { + + current.localOrigin += translation; + current.origin += translation; + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); +} + +/* +================ +idPhysics_Player::Rotate +================ +*/ +void idPhysics_Player::Rotate( const idRotation &rotation, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.origin *= rotation; + if ( masterEntity ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + } + else { + current.localOrigin = current.origin; + } + + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() * rotation.ToMat3() ); +} + +/* +================ +idPhysics_Player::SetLinearVelocity +================ +*/ +void idPhysics_Player::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { + current.velocity = newLinearVelocity; +} + +/* +================ +idPhysics_Player::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_Player::GetLinearVelocity( int id ) const { + return current.velocity; +} + +bool idPhysics_Player::HasRunningVelocity() +{ + // Return true when about 7% above walkspeed + return (current.velocity.LengthSqr() > Square(pm_walkspeed.GetFloat()) * 1.15); +} + +/* +================ +idPhysics_Player::SetPushed +================ +*/ +void idPhysics_Player::SetPushed( int deltaTime ) { + idVec3 velocity; + float d; + + // velocity with which the player is pushed + velocity = ( current.origin - saved.origin ) / ( deltaTime * idMath::M_MS2SEC ); + + // remove any downward push velocity + d = velocity * gravityNormal; + if ( d > 0.0f ) { + velocity -= d * gravityNormal; + } + + current.pushVelocity += velocity; +} + +/* +================ +idPhysics_Player::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_Player::GetPushedLinearVelocity( const int id ) const { + return current.pushVelocity; +} + +/* +================ +idPhysics_Player::ClearPushedVelocity +================ +*/ +void idPhysics_Player::ClearPushedVelocity( void ) { + current.pushVelocity.Zero(); +} + +/* +================ +idPhysics_Player::SetMaster + + the binding is never orientated +================ +*/ +void idPhysics_Player::SetMaster( idEntity *master, const bool orientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !masterEntity ) { + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + masterEntity = master; + masterYaw = masterAxis[0].ToYaw(); + } + ClearContacts(); + } + else { + if ( masterEntity ) { + masterEntity = NULL; + } + } +} + +const float PLAYER_VELOCITY_MAX = 4000; +const int PLAYER_VELOCITY_TOTAL_BITS = 16; +const int PLAYER_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( PLAYER_VELOCITY_MAX ) ) + 1; +const int PLAYER_VELOCITY_MANTISSA_BITS = PLAYER_VELOCITY_TOTAL_BITS - 1 - PLAYER_VELOCITY_EXPONENT_BITS; +const int PLAYER_MOVEMENT_TYPE_BITS = 3; +const int PLAYER_MOVEMENT_FLAGS_BITS = 8; + +/* +================ +idPhysics_Player::WriteToSnapshot +================ +*/ +void idPhysics_Player::WriteToSnapshot( idBitMsgDelta &msg ) const { + msg.WriteFloat( current.origin[0] ); + msg.WriteFloat( current.origin[1] ); + msg.WriteFloat( current.origin[2] ); + msg.WriteFloat( current.velocity[0], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteFloat( current.velocity[1], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteFloat( current.velocity[2], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); + msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); + msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.stepUp ); + msg.WriteBits( current.movementType, PLAYER_MOVEMENT_TYPE_BITS ); + msg.WriteBits( current.movementFlags, PLAYER_MOVEMENT_FLAGS_BITS ); + msg.WriteDeltaLong( 0, current.movementTime ); +} + +/* +================ +idPhysics_Player::ReadFromSnapshot +================ +*/ +void idPhysics_Player::ReadFromSnapshot( const idBitMsgDelta &msg ) { + current.origin[0] = msg.ReadFloat(); + current.origin[1] = msg.ReadFloat(); + current.origin[2] = msg.ReadFloat(); + current.velocity[0] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.velocity[1] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.velocity[2] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); + current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); + current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); + current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); + current.stepUp = msg.ReadDeltaFloat( 0.0f ); + current.movementType = msg.ReadBits( PLAYER_MOVEMENT_TYPE_BITS ); + current.movementFlags = msg.ReadBits( PLAYER_MOVEMENT_FLAGS_BITS ); + current.movementTime = msg.ReadDeltaLong( 0 ); + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); + } +} + +//################################################################ +// Start Mantling Mod +//################################################################ + +float idPhysics_Player::GetMantleTimeForPhase(EMantlePhase mantlePhase) +{ + // Current implementation uses constants + switch (mantlePhase) + { + case hang_DarkModMantlePhase: + return cv_pm_mantle_hang_msecs.GetFloat(); + + case pull_DarkModMantlePhase: + return cv_pm_mantle_pull_msecs.GetFloat(); + + case shiftHands_DarkModMantlePhase: + return cv_pm_mantle_shift_hands_msecs.GetFloat(); + + case push_DarkModMantlePhase: + return cv_pm_mantle_push_msecs.GetFloat(); + + default: + return 0.0f; + } +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::MantleMove() +{ + idVec3 newPosition = current.origin; + idVec3 totalMove(0,0,0); + float timeForMantlePhase = GetMantleTimeForPhase(m_mantlePhase); + + // Compute proportion into the current movement phase which we are + float timeRatio = 0.0f; + + if (timeForMantlePhase != 0) + { + timeRatio = (timeForMantlePhase - m_mantleTime) / timeForMantlePhase; + } + + // Branch based on phase + if (m_mantlePhase == hang_DarkModMantlePhase) + { + // Starting at current position, hanging, rocking a bit. + float rockDistance = 2.0f; + + newPosition = m_mantlePullStartPos; + float timeRadians = idMath::PI * timeRatio; + viewAngles.roll = idMath::Sin(timeRadians) * rockDistance; + newPosition += (idMath::Sin(timeRadians) * rockDistance) * viewRight; + + if (self != NULL) + { + static_cast(self)->SetViewAngles(viewAngles); + } + } + else if (m_mantlePhase == pull_DarkModMantlePhase) + { + // Player pulls themself up to shoulder even with the surface + totalMove = m_mantlePullEndPos - m_mantlePullStartPos; + newPosition = m_mantlePullStartPos + (totalMove * idMath::Sin(timeRatio * (idMath::PI/2)) ); + } + else if (m_mantlePhase == shiftHands_DarkModMantlePhase) + { + // Rock back and forth a bit? + float rockDistance = 1.0f; + + newPosition = m_mantlePullEndPos; + float timeRadians = idMath::PI * timeRatio; + newPosition += (idMath::Sin(timeRadians) * rockDistance) * viewRight; + viewAngles.roll = idMath::Sin(timeRadians) * rockDistance; + + if (self != NULL) + { + static_cast(self)->SetViewAngles(viewAngles); + } + } + else if (m_mantlePhase == push_DarkModMantlePhase) + { + // Rocking back and forth to get legs up over edge + float rockDistance = 10.0f; + + // Player pushes themselves upward to get their legs onto the surface + totalMove = m_mantlePushEndPos - m_mantlePullEndPos; + newPosition = m_mantlePullEndPos + (totalMove * idMath::Sin(timeRatio * (idMath::PI/2)) ); + + // We go into duck during this phase and stay there until end + current.movementFlags |= PMF_DUCKED; + + float timeRadians = idMath::PI * timeRatio; + newPosition += (idMath::Sin (timeRadians) * rockDistance) * viewRight; + viewAngles.roll = idMath::Sin (timeRadians) * rockDistance; + + if (self != NULL) + { + static_cast(self)->SetViewAngles(viewAngles); + } + } + + // If there is a mantled entity, positions are relative to it. + // Transform position to be relative to world origin. + // (For now, translation only, TODO: Add rotation) + if (m_p_mantledEntity != NULL) + { + idPhysics* p_physics = m_p_mantledEntity->GetPhysics(); + if (p_physics != NULL) + { + // Ishtvan: Track rotation as well + // newPosition += p_physics->GetOrigin(); + newPosition = p_physics->GetOrigin() + p_physics->GetAxis() * newPosition; + } + } + + SetOrigin(newPosition); +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::UpdateMantleTimers() +{ + // Frame seconds left + float framemSecLeft = framemsec; + + // Update jump held down timer: This actually grows, not drops + if (!( current.movementFlags & PMF_JUMP_HELD ) ) + { + m_jumpHeldDownTime = 0; + } + else + { + m_jumpHeldDownTime += framemsec; + } + + // Skip all this if done mantling + if (m_mantlePhase != notMantling_DarkModMantlePhase && m_mantlePhase != fixClipping_DarkModMantlePhase) + { + // Handle expiring mantle phases + while (framemSecLeft >= m_mantleTime && m_mantlePhase != notMantling_DarkModMantlePhase) + { + framemSecLeft -= m_mantleTime; + m_mantleTime = 0; + + // Advance mantle phase + switch (m_mantlePhase) + { + case hang_DarkModMantlePhase: + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Pulling up...\r"); + m_mantlePhase = pull_DarkModMantlePhase; + break; + + case pull_DarkModMantlePhase: + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Shifting hand position...\r"); + m_mantlePhase = shiftHands_DarkModMantlePhase; + break; + + case shiftHands_DarkModMantlePhase: + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Pushing self up...\r"); + m_mantlePhase = push_DarkModMantlePhase; + + // Go into crouch + current.movementFlags |= PMF_DUCKED; + break; + + case push_DarkModMantlePhase: + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: mantle completed\r"); + // check for clipping problems after mantling + // will advance to notMantling when the player isn't clipping + m_mantlePhase = fixClipping_DarkModMantlePhase; + + // greebo: Reset the viewangle roll to 0 after mantling, sometimes this stays at 0.6 or something + viewAngles.roll = 0; + + if (self != NULL) + { + static_cast(self)->SetViewAngles(viewAngles); + } + + break; + + default: + m_mantlePhase = notMantling_DarkModMantlePhase; + break; + } + + // Get time it takes to perform a mantling phase + m_mantleTime = GetMantleTimeForPhase(m_mantlePhase); + + // Handle end of mantle + if (m_mantlePhase == fixClipping_DarkModMantlePhase) + { + // Handle end of mantle + // Ishtvan 11/20/05 - Raise weapons after mantle is done + static_cast(self)->SetImmobilization("MantleMove", 0); + } + } + + // Reduce mantle timer + if (m_mantlePhase == fixClipping_DarkModMantlePhase) + { + m_mantleTime = 0; + } + else + { + m_mantleTime -= framemSecLeft; + } + } // This code block is executed only if phase != notMantling && phase != fixClipping +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::IsMantling() const +{ + return m_mantlePhase != notMantling_DarkModMantlePhase && m_mantlePhase != fixClipping_DarkModMantlePhase; +} + +//---------------------------------------------------------------------- + +EMantlePhase idPhysics_Player::GetMantlePhase() const +{ + return m_mantlePhase; +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::CancelMantle() +{ + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Mantle cancelled\r"); + + m_mantlePhase = notMantling_DarkModMantlePhase; + m_mantleTime = 0.0f; +} + +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- + +void idPhysics_Player::StartMantle +( + EMantlePhase initialMantlePhase, + idVec3 eyePos, + idVec3 startPos, + idVec3 endPos +) +{ + // Ishtvan 10/16/05 + // If mantling starts while on a rope, detach from that rope + if ( m_bOnRope ) + { + RopeDetach(); + } + + // If mantling starts while climbing, detach from climbing surface + if ( m_bOnClimb ) + { + ClimbDetach(); + } + + // Ishtvan 11/20/05 - Lower weapons when mantling + static_cast(self)->SetImmobilization( "MantleMove", EIM_WEAPON_SELECT | EIM_ATTACK ); + + // greebo: Disable the next mantle start here, this is set to TRUE again + // when the jump key is released outside a mantle phase + m_mantleStartPossible = false; + + // If mantling from a jump, cancel any velocity so that it does + // not continue after the mantle is completed. + current.velocity.Zero(); + + // Calculate mantle distance + idVec3 mantleDistanceVec = endPos - startPos; +// float mantleDistance = mantleDistanceVec.Length(); + + // Log starting phase + if (initialMantlePhase == hang_DarkModMantlePhase) + { + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with hang\r"); + + // Impart a force on mantled object? + if (m_p_mantledEntity != NULL && self != NULL) + { + impactInfo_t info; + m_p_mantledEntity->GetImpactInfo(self, m_mantledEntityID, endPos, &info); + + if (info.invMass != 0.0f) + { + m_p_mantledEntity->ActivatePhysics(self); + m_p_mantledEntity->ApplyImpulse( self, m_mantledEntityID, endPos, current.velocity / ( info.invMass * 2.0f ) ); + } + } + } + else if (initialMantlePhase == pull_DarkModMantlePhase) + { + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with pull upward\r"); + } + else if (initialMantlePhase == shiftHands_DarkModMantlePhase) + { + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with shift hands\r"); + } + else if (initialMantlePhase == push_DarkModMantlePhase) + { + // Go into crouch + current.movementFlags |= PMF_DUCKED; + + // Start with push upward + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with push upward\r"); + } + + m_mantlePhase = initialMantlePhase; + m_mantleTime = GetMantleTimeForPhase(m_mantlePhase); + + // Make positions relative to entity + if (m_p_mantledEntity != NULL) + { + idPhysics* p_physics = m_p_mantledEntity->GetPhysics(); + if (p_physics != NULL) + { + const idVec3& mantledEntityOrigin = p_physics->GetOrigin(); + const idMat3& mantledEntityAxis = p_physics->GetAxis(); + + // ishtvan 1/3/2010: Incorporate entity rotation as well as translation + /* + startPos -= mantledEntityOrigin; + eyePos -= mantledEntityOrigin; + endPos -= mantledEntityOrigin; + */ + startPos = (startPos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); + eyePos = (eyePos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); + endPos = (endPos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); + } + } + + // Set end position + m_mantlePushEndPos = endPos; + + if (initialMantlePhase == pull_DarkModMantlePhase || initialMantlePhase == hang_DarkModMantlePhase) + { + // Pull from start position up to about 2/3 of eye height + m_mantlePullStartPos = startPos; + m_mantlePullEndPos = eyePos; + + m_mantlePullEndPos += GetGravityNormal() * pm_normalheight.GetFloat() / 3.0f; + } + else + { + // Starting with push from current position + m_mantlePullEndPos = startPos; + } +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::CheckJumpHeldDown() +{ + return m_jumpHeldDownTime > cv_pm_mantle_jump_hold_trigger.GetInteger(); +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::GetCurrentMantlingReachDistances +( + float& out_maxVerticalReachDistance, + float& out_maxHorizontalReachDistance, + float& out_maxMantleTraceDistance +) +{ + // Determine arm reach in each direction + float armReach = pm_normalheight.GetFloat() * cv_pm_mantle_reach.GetFloat(); + float armVerticalReach = pm_normalheight.GetFloat() * cv_pm_mantle_height.GetFloat(); + + // Trace out as far as horizontal arm length from player + out_maxMantleTraceDistance = armReach; + + // Determine maximum vertical and horizontal distance components for + // a mantleable surface + if (current.movementFlags & PMF_DUCKED /*&& !OnRope() && !OnLadder()*/) + { + out_maxVerticalReachDistance = pm_crouchheight.GetFloat() + armVerticalReach; + out_maxHorizontalReachDistance = armReach; + } + /*else if (OnRope() || OnLadder()) + { + // angua: need larger reach when on rope + out_maxVerticalReachDistance = pm_normalheight.GetFloat() + armVerticalReach; + out_maxHorizontalReachDistance = 2* armReach; + out_maxMantleTraceDistance *= 2; + }*/ + else + { + // This vertical distance is up from the players feet + out_maxVerticalReachDistance = pm_normalheight.GetFloat() + armVerticalReach; + out_maxHorizontalReachDistance = armReach; + } +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::MantleTargetTrace +( + float maxMantleTraceDistance, + const idVec3& eyePos, + const idVec3& forwardVec, + trace_t& out_trace +) +{ + // Calculate end point of gaze trace + idVec3 end = eyePos + (maxMantleTraceDistance * forwardVec); + + // Run gaze trace + gameLocal.clip.TracePoint( out_trace, eyePos, end, MASK_SOLID, self ); + + // If that trace didn't hit anything, try a taller trace forward along the midline + // of the player's body for the full player's height out the trace distance. + if ( out_trace.fraction >= 1.0f ) + { + idVec3 upVector = -GetGravityNormal(); + + // Project forward vector onto the a plane perpendicular to gravity + idVec3 forwardPerpGrav = forwardVec; + forwardPerpGrav.ProjectOntoPlane(upVector); + + // Create bounds for translation trace model + idBounds bounds = clipModel->GetBounds(); + idBounds savedBounds = bounds; + + bounds[0][1] = (savedBounds[0][1] + savedBounds[1][1]) / 2; + bounds[0][1] -= 0.01f; + bounds[1][1] = bounds[0][1] + 0.02f; + bounds[0][0] = bounds[0][1]; + bounds[1][0] = bounds[1][1]; + + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle gaze trace didn't hit anything, so doing forward movement trace for mantle target\r"); + + gameLocal.clip.Translation + ( + out_trace, + current.origin, + current.origin + (maxMantleTraceDistance * forwardPerpGrav), + clipModel, + clipModel->GetAxis(), + MASK_SOLID, + self + ); + + //gameRenderWorld->DebugBounds(colorCyan, bounds, current.origin, 2000); + //gameRenderWorld->DebugBounds(colorBlue, bounds, current.origin + (maxMantleTraceDistance * forwardPerpGrav), 2000); + + // Restore player clip model to normal + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(savedBounds, 8) : idTraceModel(savedBounds) ); + } + + // Get the entity to be mantled + if (out_trace.c.entityNum != ENTITYNUM_NONE) + { + // Track entity which is was the chosen target + m_p_mantledEntity = gameLocal.entities[out_trace.c.entityNum]; + + if (m_p_mantledEntity->IsMantleable()) + { + m_mantledEntityID = out_trace.c.id; + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle target entity is called '%s'\r", m_p_mantledEntity->name.c_str()); + } + else + { + // Oops, this entity isn't mantleable + m_p_mantledEntity = NULL; + out_trace.fraction = 1.0f; // Pretend we didn't hit anything + } + } +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::DetermineIfMantleTargetHasMantleableSurface +( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + trace_t& in_targetTraceResult, + idVec3& out_mantleEndPoint +) +{ + // Never mantle onto non-mantleable entities (early exit) + if (in_targetTraceResult.fraction < 1.0f) + { + idEntity* ent = gameLocal.entities[in_targetTraceResult.c.entityNum]; + + if (ent == NULL || !ent->IsMantleable()) + { + // The mantle target is an unmantleable entity + return false; + } + } + + // Try moving player's bounding box up from the trace hit point + // in steps up to the maximum distance and see if at any point + // there are no collisions. If so, we can mantle. + + // First point to test has gravity orthogonal coordinates set + // to the ray trace collision point. It then has gravity non-orthogonal + // coordinates set from the current player origin. However, + // for the non-orthogonal-to-gravity coordinates, the trace.c.point + // location is a better starting place. Because of rear surface occlusion, + // it will always be closer to the actual "upper" surface than the player + // origin unless the object is "below" the player relative to gravity. + // And, in that "below" case, mantling isn't possible anyway. + + // This sets coordinates to their components which are orthogonal + // to gravity. + idVec3 componentOrthogonalToGravity = in_targetTraceResult.c.point; + componentOrthogonalToGravity.ProjectOntoPlane(-gravityNormal); + + // This sets coordintes to their components parallel to gravity + idVec3 componentParallelToGravity; + componentParallelToGravity.x = -gravityNormal.x * in_targetTraceResult.c.point.x; + componentParallelToGravity.y = -gravityNormal.y * in_targetTraceResult.c.point.y; + componentParallelToGravity.z = -gravityNormal.z * in_targetTraceResult.c.point.z; + + // What parallel to gravity reach distance is already used up at this point + idVec3 originParallelToGravity; + originParallelToGravity.x = -gravityNormal.x * current.origin.x; + originParallelToGravity.y = -gravityNormal.y * current.origin.y; + originParallelToGravity.z = -gravityNormal.z * current.origin.z; + + float verticalReachDistanceUsed = (componentParallelToGravity - originParallelToGravity).Length(); + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Initial vertical reach distance used = %f out of maximum of %f\r", + verticalReachDistanceUsed, + maxVerticalReachDistance + ); + + // The first test point + idVec3 testPosition = componentOrthogonalToGravity + componentParallelToGravity; + + // Load crouch model + // as mantling ends in a crouch + if (!(current.movementFlags & PMF_DUCKED)) + { + idBounds bounds = clipModel->GetBounds(); + bounds[1][2] = pm_crouchheight.GetFloat(); + + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); + } + + // We try moving it up by the step distance up to the maximum height until + // there are no collisions + bool b_keepTesting = verticalReachDistanceUsed < maxVerticalReachDistance; + bool b_mantlePossible = false; + bool b_lastCollisionWasMantleable = true; + + trace_t worldMantleTrace; + + while (b_keepTesting) + { + // Try collision in_targetTraceResult + idVec3 mantleTraceStart = testPosition; + gameLocal.clip.Translation( worldMantleTrace, mantleTraceStart, testPosition, clipModel, clipModel->GetAxis(), clipMask, self ); + + if (worldMantleTrace.fraction >= 1.0f) + { + // We can mantle to there, unless the last test collided with something non-mantleable. + // Either way we're done here. + b_keepTesting = false; + + if (b_lastCollisionWasMantleable) + { + b_mantlePossible = true; + } + } + else + { + idEntity* ent = gameLocal.entities[ worldMantleTrace.c.entityNum ]; + + if (ent && !ent->IsMantleable()) + { + // If we collided with a non-mantleable entity, then flag that. + // This is to prevent situations where we start out mantling on a low ledge + // (like a stair) on which a non-mantleable entity (like an AI) is standing, + // and proceed to mantle over the AI. + b_lastCollisionWasMantleable = false; + } + else + { + // On the other hand, if there's a shelf above the AI, then we can still mantle + // the shelf. + b_lastCollisionWasMantleable = true; + } + + if (verticalReachDistanceUsed < maxVerticalReachDistance) + { + // Try next test position + + float testIncrementAmount = maxVerticalReachDistance - verticalReachDistanceUsed; + + // Establish upper bound for increment test size + if (testIncrementAmount > MANTLE_TEST_INCREMENT) + { + testIncrementAmount = MANTLE_TEST_INCREMENT; + } + + // Establish absolute minimum increment size so that + // we don't approach increment size below floating point precision, + // which would cause an infinite loop. + if (testIncrementAmount < 1.0f) + { + testIncrementAmount = 1.0f; + } + + // Update location by increment size + componentParallelToGravity += (-gravityNormal * testIncrementAmount); + verticalReachDistanceUsed = (componentParallelToGravity - originParallelToGravity).Length(); + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Ledge Search: Vertical reach distance used = %f out of maximum of %f\r", + verticalReachDistanceUsed, + maxVerticalReachDistance + ); + + // Modify test position + testPosition = componentOrthogonalToGravity + componentParallelToGravity; + } + else + { + // No surface we could fit on against gravity from raytrace hit point + // up as far as we can reach + b_keepTesting = false; + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("No mantleable surface within reach distance\r"); + } + } + + } + + // Don't mantle onto surfaces that are too steep. + // Any surface with an angle whose cosine is + // smaller than MIN_FLATNESS is too steep. + float minFlatness = cv_pm_mantle_minflatness.GetFloat(); + + if (b_mantlePossible) + { + // Attempt to get the normal of the surface we'd be standing on + // In rare cases this may not collide + trace_t floorTrace; + gameLocal.clip.Translation( floorTrace, testPosition, + testPosition + (gravityNormal * MANTLE_TEST_INCREMENT), + clipModel, clipModel->GetAxis(), clipMask, self ); + + if (floorTrace.fraction < 1.0f) + { + // Uses the dot product to compare against the cosine of an angle. + // Comparing to cos(90)=0 means we can mantle on top of any surface + // Comparing to cos(0)=1 means we can only mantle on top of perfectly flat surfaces + + float flatness = floorTrace.c.normal * (-gravityNormal); + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING( + "Floor %.2f,%.2f,%.2f; grav %.2f,%.2f,%.2f; dot %f; %s\r", + floorTrace.c.normal.x, floorTrace.c.normal.y, floorTrace.c.normal.z, + gravityNormal.x, gravityNormal.y, gravityNormal.z, + flatness, flatness < minFlatness ? "too steep" : "OK"); + + if (flatness < minFlatness) + { + b_mantlePossible = false; + } + } + } + + // Must restore standing model if player is not crouched + if (!(current.movementFlags & PMF_DUCKED)) + { + // Load back standing model + idBounds bounds = clipModel->GetBounds(); + bounds[1][2] = pm_normalheight.GetFloat(); + + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); + } + + // Return result + if (b_mantlePossible) + { + out_mantleEndPoint = testPosition; + } + return b_mantlePossible; +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::DetermineIfPathToMantleSurfaceIsPossible +( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + const idVec3& in_eyePos, + const idVec3& in_mantleStartPoint, + const idVec3& in_mantleEndPoint +) +{ + // Make sure path from current location + // upward can be traversed. + trace_t roomForMoveUpTrace; + idVec3 MoveUpStart = in_mantleStartPoint; + idVec3 MoveUpEnd; + + // Go to coordinate components against gravity from current location + idVec3 componentOrthogonalToGravity; + componentOrthogonalToGravity = in_mantleStartPoint; + componentOrthogonalToGravity.ProjectOntoPlane (-gravityNormal); + MoveUpEnd = componentOrthogonalToGravity; + + MoveUpEnd.x += -gravityNormal.x * in_mantleEndPoint.x; + MoveUpEnd.y += -gravityNormal.y * in_mantleEndPoint.y; + MoveUpEnd.z += -gravityNormal.z * in_mantleEndPoint.z; + + // Use crouch clip model + if (!(current.movementFlags & PMF_DUCKED)) + { + // Load crouching model + idBounds bounds = clipModel->GetBounds(); + bounds[1][2] = pm_crouchheight.GetFloat(); + + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); + } + + gameLocal.clip.Translation + ( + roomForMoveUpTrace, + MoveUpStart, + MoveUpEnd, + clipModel, + clipModel->GetAxis(), + clipMask, + self + ); + + // Done with crouch model if not currently crouched + if (!(current.movementFlags & PMF_DUCKED)) + { + // Load back standing model + idBounds bounds = clipModel->GetBounds(); + bounds[1][2] = pm_normalheight.GetFloat(); + + clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); + } + + // Log + if (roomForMoveUpTrace.fraction < 1.0) + { + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Collision test from (%f %f %f) to (%f %f %f) yieled trace fraction %f\r", + MoveUpStart.x, + MoveUpStart.y, + MoveUpStart.z, + MoveUpEnd.x, + MoveUpEnd.y, + MoveUpEnd.z, + roomForMoveUpTrace.fraction + ); + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Not enough vertical clearance along mantle path\r"); + return false; + } + else + { + return true; + } + +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::ComputeMantlePathForTarget +( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + const idVec3& eyePos, + trace_t& in_targetTraceResult, + idVec3& out_mantleEndPoint +) +{ + // Up vector + idVec3 upVector = -GetGravityNormal(); + + // Mantle start point is origin + const idVec3& mantleStartPoint = GetOrigin(); + + // Check if trace target has a mantleable surface + bool b_canBeMantled = DetermineIfMantleTargetHasMantleableSurface + ( + maxVerticalReachDistance, + maxHorizontalReachDistance, + in_targetTraceResult, + out_mantleEndPoint + ); + + if (b_canBeMantled) + { + // Check if path to mantle end point is not blocked + b_canBeMantled &= DetermineIfPathToMantleSurfaceIsPossible + ( + maxVerticalReachDistance, + maxHorizontalReachDistance, + eyePos, + mantleStartPoint, + out_mantleEndPoint + ); + + if (b_canBeMantled) + { + // Is end point too far away? + idVec3 endDistanceVector = out_mantleEndPoint - eyePos; + float endDistance = endDistanceVector.Length(); + idVec3 upDistance = endDistanceVector; + + upDistance.x *= upVector.x; + upDistance.y *= upVector.y; + upDistance.z *= upVector.z; + float upDist = upDistance.Length(); + + float nonUpDist = idMath::Sqrt(endDistance*endDistance - upDist*upDist); + + // Check the calculated distances + if (upDist < 0.0) + { + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantleable surface was below player's feet. No belly slide allowed.\r"); + b_canBeMantled = false; + } + else if (upDist > maxVerticalReachDistance || nonUpDist > maxHorizontalReachDistance) + { + // Its too far away either horizontally or vertically + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Distance to end point was (%f, %f) (horizontal, vertical) which is greater than limits of (%f %f), so mantle cannot be done\n", + upDist, + nonUpDist, + maxVerticalReachDistance, + maxHorizontalReachDistance + ); + + b_canBeMantled = false; + } + + // Distances are reasonable + } + } + + // Return result + return b_canBeMantled; +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::PerformMantle() +{ + // Can't start mantle if already mantling or not yet possible (jump button not yet released) + if ( !(m_mantlePhase == notMantling_DarkModMantlePhase || m_mantlePhase == fixClipping_DarkModMantlePhase) + || !m_mantleStartPossible ) + { + return; + } + + if (static_cast(self)->GetImmobilization() & EIM_MANTLE) + { + return; // greebo: Mantling disabled by immobilization system + } + + // Clear mantled entity members to indicate nothing is + // being mantled + m_p_mantledEntity = NULL; + m_mantledEntityID = 0; + + // Forward vector is direction player is looking + idVec3 forward = viewAngles.ToForward(); + forward.Normalize(); + + // We use gravity alot here... + idVec3 gravityNormal = GetGravityNormal(); + idVec3 upVector = -gravityNormal; + + // Get maximum reach distances for mantling + float maxVerticalReachDistance; + float maxHorizontalReachDistance; + float maxMantleTraceDistance; + + GetCurrentMantlingReachDistances + ( + maxVerticalReachDistance, + maxHorizontalReachDistance, + maxMantleTraceDistance + ); + + // Get start position of gaze trace, which is player's eye position + idPlayer* p_player = static_cast(self); + + if (p_player == NULL) + { + DM_LOG(LC_MOVEMENT, LT_ERROR)LOGSTRING("p_player is NULL\r"); + return; + } + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Getting eye position\r"); + idVec3 eyePos = p_player->GetEyePosition(); + + // Ishtvan: Do not attempt to mantle if holding an object + if( gameLocal.m_Grabber->GetSelected() ) + return; + + // Run mantle trace + trace_t trace; + + MantleTargetTrace + ( + maxMantleTraceDistance, + eyePos, + forward, + trace + ); + + // If the trace found a target, see if it is mantleable + if ( trace.fraction < 1.0f ) + { + // Log trace hit point + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Mantle target trace collision point (%f %f %f)\r", + trace.c.point.x, + trace.c.point.y, + trace.c.point.z + ); + + // Find mantle end point and make sure mantle is + // possible + idVec3 mantleEndPoint; + if (ComputeMantlePathForTarget + ( + maxVerticalReachDistance, + maxHorizontalReachDistance, + eyePos, + trace, + mantleEndPoint + )) + { + // Log the end point + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Mantle end position = (%f %f %f)\r", + mantleEndPoint.x, + mantleEndPoint.y, + mantleEndPoint.z + ); + + // Start with log phase dependent on position relative + // to the mantle end point + if (mantleEndPoint * gravityNormal < eyePos * gravityNormal) + { + // Start with pull if on the ground, hang if not + if (groundPlane) + { + StartMantle(pull_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); + } + else + { + StartMantle(hang_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); + } + } + else + { + // We are above it, start with push + StartMantle(push_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); + } + } // Mantle target passed mantleability tests + } // End mantle target found +} + +//#################################################################### +// End Mantle Mod +// SophisticatedZombie (DH) +//#################################################################### + +//#################################################################### +// Start Leaning Mod +// Zaccheus (some original geometric drawings) +// SophsiticatedZombie (DH) +// +//#################################################################### + +void idPhysics_Player::ToggleLean(float leanYawAngleDegrees) +{ + //if (m_CurrentLeanTiltDegrees < 0.0001) // prevent floating point compare errors + if (m_CurrentLeanTiltDegrees < 0.00001) // prevent floating point compare errors + { + // Start the lean + m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; + m_leanYawAngleDegrees = leanYawAngleDegrees; + + // Hack: Use different values for forward/backward lean than side/side + if( leanYawAngleDegrees == 90.0f || leanYawAngleDegrees == -90.0f ) + { + m_leanTime = cv_pm_lean_forward_time.GetFloat(); + m_leanMoveEndTilt = cv_pm_lean_forward_angle.GetFloat(); + m_leanMoveMaxStretch = cv_pm_lean_forward_stretch.GetFloat(); + m_leanMoveMaxAngle = cv_pm_lean_forward_angle.GetFloat(); + } + else + { + m_leanTime = cv_pm_lean_time.GetFloat(); + m_leanMoveEndTilt = cv_pm_lean_angle.GetFloat(); + m_leanMoveMaxStretch = cv_pm_lean_stretch.GetFloat(); + m_leanMoveMaxAngle = cv_pm_lean_angle.GetFloat(); + } + + m_b_leanFinished = false; + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("ToggleLean starting lean\r"); + } + else + { + if (m_leanTime > 0 && m_leanMoveEndTilt == 0) + { + // We are already un-leaning + return; + } + + // End the lean + m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; + m_leanTime = cv_pm_lean_forward_time.GetFloat(); + m_leanMoveEndTilt = 0.0; + m_b_leanFinished = false; + + // greebo: Leave the rest of the variables as they are + // to avoid view-jumping issues due to leaning back. + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("ToggleLean ending lean\r"); + } +} + +//---------------------------------------------------------------------- + +bool idPhysics_Player::IsLeaning() +{ + if (m_CurrentLeanTiltDegrees < 0.001) + { + return false; + } + else + { + // entering, exiting, or holding lean + return true; + } +} + +//---------------------------------------------------------------------- + +const idAngles& idPhysics_Player::GetViewLeanAngles() const +{ + return m_viewLeanAngles; +} + +//---------------------------------------------------------------------- + +idVec3 idPhysics_Player::GetViewLeanTranslation() +{ + idAngles viewAngNoPitch = viewAngles; + viewAngNoPitch.pitch = 0.0f; + return viewAngNoPitch.ToMat4() * m_viewLeanTranslation; +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::UpdateLeanAngle (float deltaLeanTiltDegrees, float deltaLeanStretch) +{ + // What would the new lean angle be? + float newLeanTiltDegrees = m_CurrentLeanTiltDegrees + deltaLeanTiltDegrees; + + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("newLeanTiltDegrees = %f\r", newLeanTiltDegrees ); + + if (newLeanTiltDegrees < 0.0) + { + // Adjust delta + deltaLeanTiltDegrees = 0.0 - m_CurrentLeanTiltDegrees; + deltaLeanStretch = 0.0 - m_CurrentLeanStretch; + m_leanTime = 0.0; + m_b_leanFinished = true; + } + else if (newLeanTiltDegrees > m_leanMoveMaxAngle) + { + // Adjust delta + deltaLeanTiltDegrees = m_leanMoveMaxAngle - m_CurrentLeanTiltDegrees; + deltaLeanStretch = m_leanMoveMaxStretch - m_CurrentLeanStretch; + m_leanTime = 0.0; + m_b_leanFinished = true; + } + + // Log max possible lean + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Currently leaning %.2f degrees, can lean up to %.2f more degrees this frame\r", + m_CurrentLeanTiltDegrees, + deltaLeanTiltDegrees + ); + + newLeanTiltDegrees = m_CurrentLeanTiltDegrees + deltaLeanTiltDegrees; + float newLeanStretch = m_CurrentLeanStretch + deltaLeanStretch; + + // Collision test: do not change lean angles any more if collision has occurred + // convert proposed angle and stretch to a viewpoint in space: + idVec3 newPoint = LeanParmsToPoint( newLeanTiltDegrees, newLeanStretch ); + + idPlayer* player = static_cast(self); + idVec3 origPoint = player->GetEyePosition(); + + // Add some delta so we can lean back afterwards without already being clipped + idVec3 vDelta = newPoint - origPoint; + vDelta.Normalize(); + + float fLeanTestDelta = 6.0f; + vDelta *= fLeanTestDelta; + + // Perform the trace (greebo: use PLAYERSOLID to include player_clip collisions) + trace_t trTest; + gameLocal.clip.TraceBounds( trTest, origPoint, newPoint + vDelta, m_LeanViewBounds, MASK_PLAYERSOLID, player ); + + bool bWouldClip = trTest.fraction < 1.0f; + //DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Collision trace between old view point ( %d, %d, %d ) and newPoint: ( %d, %d, %d )\r", origPoint.x, origPoint.y, origPoint.z, newPoint.x, newPoint.y, newPoint.z ); + + // Do not lean farther if the player would hit the wall + if( bWouldClip ) + { + idEntity* traceEnt = gameLocal.GetTraceEntity( trTest ); + + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Lean test point within solid, lean motion stopped.\r" ); + + if( traceEnt != NULL) + { + // Door leaning test + if (traceEnt->IsType(CFrobDoor::Type) && + !static_cast(traceEnt)->IsOpen() && + m_LeanDoorEnt.GetEntity() == NULL ) + { + // If it is a door, can it be listened through? + if( FindLeanDoorListenPos( trTest.c.point, static_cast(traceEnt) ) ) + { + m_LeanDoorEnt = static_cast(traceEnt); + } + } + // Detect AI collision + else if (traceEnt->IsType(idAI::Type) ) + { + static_cast(traceEnt)->HadTactile(player); + } + } + + return; + } + + // Adjust lean angle by delta which was allowed + m_CurrentLeanTiltDegrees += deltaLeanTiltDegrees; + m_CurrentLeanStretch += deltaLeanStretch; + + // Update the physics: + UpdateLeanPhysics(); + + // Log activity + DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING + ( + "Lean tilt is now %.2f degrees, lean stretch is now %.2f fractional\r", + m_CurrentLeanTiltDegrees, + m_CurrentLeanStretch + ); +} + +//---------------------------------------------------------------------- + +void idPhysics_Player::LeanMove() +{ + + // Change in lean tilt this frame + float deltaLeanTiltDegrees = 0.0; + float deltaLeanStretch = 0.0; + float newLeanTiltDegrees = 0.0; + float newLeanStretch = 0.0; + + if ( !m_b_leanFinished ) + { + + // Update lean time + m_leanTime -= framemsec; + if (m_leanTime <= 0.0) + { + m_leanTime = 0.0; + m_b_leanFinished = true; + } + + // Try sinusoidal movement + float timeRatio = ( cv_pm_lean_time.GetFloat() - m_leanTime) / cv_pm_lean_time.GetFloat(); + + float timeRadians = (idMath::PI/2.0f) * timeRatio; + + if (m_leanMoveEndTilt > m_leanMoveStartTilt) + { + newLeanTiltDegrees = (idMath::Sin(timeRadians) * (m_leanMoveEndTilt - m_leanMoveStartTilt)) + + m_leanMoveStartTilt; + newLeanStretch = idMath::Sin(timeRadians); + } + else if (m_leanMoveStartTilt > m_leanMoveEndTilt) + { + newLeanTiltDegrees = m_leanMoveStartTilt - (idMath::Sin(timeRadians) * (m_leanMoveStartTilt - m_leanMoveEndTilt)); + newLeanStretch = idMath::Sin( (idMath::PI/2.0f) * (1.0f - timeRatio) ); + } + + deltaLeanTiltDegrees = newLeanTiltDegrees - m_CurrentLeanTiltDegrees; + deltaLeanStretch = newLeanStretch - m_CurrentLeanStretch; + + } + + // Perform any change to leaning + if (deltaLeanTiltDegrees != 0.0) + { + // Re-orient clip model before change so that collision tests + // are accurate (player may have rotated mid-lean) + UpdateLeanAngle (deltaLeanTiltDegrees, deltaLeanStretch); + } + + // If player is leaned at all, do an additional clip test and unlean them + // In case they lean and walk into something, or a moveable moves into them, etc. + if( m_CurrentLeanTiltDegrees != 0.0 && TestLeanClip() ) + { + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned player clipped solid, unleaning to valid position \r"); + + UnleanToValidPosition(); + } + + // Lean door test + if( IsLeaning() ) + { + UpdateLeanDoor(); + } + + // TODO: Update lean radius if player is crouching/uncrouching +} + +bool idPhysics_Player::TestLeanClip() +{ + idPlayer *p_player = static_cast(self); + // convert proposed angle and stretch to a viewpoint in space: + + idVec3 vTest = p_player->GetEyePosition(); + idVec3 vEyeOffset = -GetGravityNormal()*p_player->EyeHeight(); + + trace_t trTest; + gameLocal.clip.TraceBounds( trTest, current.origin + vEyeOffset, vTest, m_LeanViewBounds, MASK_SOLID | CONTENTS_BODY, self ); + + idEntity *TrEnt(NULL); + + // Detect AI collision, if entity hit or its bindmaster is an AI: + if( trTest.fraction != 1.0f + && ( TrEnt = gameLocal.GetTraceEntity( trTest ) ) != NULL + && TrEnt->IsType(idAI::Type) ) + { + static_cast( TrEnt )->HadTactile( (idActor *) self ); + } + + // Uncomment for debug bounds display + //gameRenderWorld->DebugBounds( colorGreen, m_LeanViewBounds, vTest ); + + return (trTest.fraction != 1.0f); +} + +idVec3 idPhysics_Player::LeanParmsToPoint(float tilt, float stretch) +{ + idPlayer* p_player = static_cast(self); + + // Find the lean fulcrum to rotate about, and radius of lean + float eyeHeight = p_player->EyeHeight(); + float leanFulcrumHeight = eyeHeight * cv_pm_lean_height.GetFloat(); + float radius = eyeHeight - leanFulcrumHeight; + + // Set lean view angles + float pitchAngle = tilt * idMath::Sin(DEG2RAD(m_leanYawAngleDegrees)); + float rollAngle = tilt * idMath::Cos(DEG2RAD(m_leanYawAngleDegrees)); + + // Set lean translate vector + float stretchedDist = radius * (1.0f + m_leanMoveMaxStretch * stretch); + + // This will be the point in space relative to the player's eye position + idVec3 vPoint( + stretchedDist * idMath::Sin(DEG2RAD(-pitchAngle)), + stretchedDist * idMath::Sin(DEG2RAD(rollAngle)), + 0.0 + ); + + // Calculate the z-coordinate of the point, by projecting it + // onto a sphere of radius + vPoint.ProjectSelfOntoSphere( stretchedDist ); + + // Subtract the radius, we only need the difference relative to the eyepos + vPoint.z -= stretchedDist; + + // Rotate to player's facing + // this worked for yaw, but had issues with pitch, try something instead + //idMat4 rotMat = viewAngles.ToMat4(); + idAngles viewAngNoPitch = viewAngles; + viewAngNoPitch.pitch = 0.0f; + idMat4 rotMat = viewAngNoPitch.ToMat4(); + + vPoint *= rotMat; + + // Sign h4x0rx + vPoint.x *= -1; + vPoint.y *= -1; + + // Extract what the player's eye position would be without lean + // Need to do this rather than just adding origin and eye offset due to smoothing + vPoint += p_player->GetEyePosition() - rotMat * m_viewLeanTranslation; + + return vPoint; +} + +void idPhysics_Player::RopeRemovalCleanup( idEntity *RopeEnt ) +{ + if( RopeEnt && m_RopeEntity.GetEntity() && m_RopeEntity.GetEntity() == RopeEnt ) + m_RopeEntity = NULL; + if( RopeEnt && m_RopeEntTouched.GetEntity() && m_RopeEntTouched.GetEntity() == RopeEnt ) + m_RopeEntTouched = NULL; +} + +void idPhysics_Player::UpdateLeanPhysics() +{ + idPlayer *p_player = static_cast(self); + + idAngles viewAngNoPitch = viewAngles; + viewAngNoPitch.pitch = 0; + + idMat4 rotPlayerToWorld = viewAngNoPitch.ToMat4(); + idMat4 rotWorldToPlayer = rotPlayerToWorld.Transpose(); + + // unleaned player view origin + idVec3 viewOrig = p_player->GetEyePosition(); + // convert angle and stretch to a viewpoint in space: + idVec3 newPoint = LeanParmsToPoint( m_CurrentLeanTiltDegrees, m_CurrentLeanStretch ); + + // This is cumbersome, but it lets us extract the smoothed view origin from idPlayer + m_viewLeanTranslation = newPoint - (viewOrig - rotPlayerToWorld * m_viewLeanTranslation); + m_viewLeanTranslation *= rotWorldToPlayer; + + float angle = m_CurrentLeanTiltDegrees; + + m_viewLeanAngles.pitch = angle * idMath::Sin(DEG2RAD(m_leanYawAngleDegrees)); + m_viewLeanAngles.roll = angle * idMath::Cos(DEG2RAD(m_leanYawAngleDegrees)); +} + +float idPhysics_Player::GetDeltaViewYaw( void ) +{ + return m_DeltaViewYaw; +} + +float idPhysics_Player::GetDeltaViewPitch( void ) +{ + return m_DeltaViewPitch; +} + +void idPhysics_Player::UpdateLeanedInputYaw( idAngles &InputAngles ) +{ + if (!IsLeaning()) return; // nothing to do + + /** + * Leaned view yaw check for clipping + **/ + + // Have a delta so that we don't get stuck on the wall due to floating point errors + float AddedYawDelt = 4.0f; // amount to check ahead of the yaw change, in degrees + float TestDeltaYaw = idMath::AngleNormalize180( InputAngles.yaw - viewAngles.yaw ); + + // Add delta + if( TestDeltaYaw < 0.0f ) + TestDeltaYaw -= AddedYawDelt; + else + TestDeltaYaw += AddedYawDelt; + + idPlayer* player = static_cast(self); + + idVec3 vEyeOffset = -GetGravityNormal() * player->EyeHeight(); + + // make the test bounds go back to the unleaned eye point + idBounds ViewBoundsExp = m_LeanViewBounds; + ViewBoundsExp.AddPoint( -m_viewLeanTranslation ); + + idClipModel ViewClip( ViewBoundsExp ); + idAngles viewAngYaw; + viewAngYaw.Zero(); + viewAngYaw.yaw = viewAngles.yaw; + + ViewClip.SetPosition( player->GetEyePosition(), viewAngYaw.ToMat3() ); + + //idRotation ViewYawRot( current.origin, -GetGravityNormal(), TestDeltaYaw ); + idRotation ViewYawRot( current.origin, GetGravityNormal(), TestDeltaYaw ); + + idVec3 startPoint = player->GetEyePosition(); + idVec3 endPoint = startPoint; + ViewYawRot.RotatePoint( endPoint ); + + trace_t TrResults; + gameLocal.clip.Rotation( TrResults, startPoint, ViewYawRot, &ViewClip, ViewClip.GetAxis(), MASK_SOLID | CONTENTS_BODY, self ); + + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned View Yaw Test: Original viewpoint (%f, %f, %f) Tested viewpoint: (%f, %f, %f) \r", startPoint.x, startPoint.y, startPoint.z, endPoint.x, endPoint.y, endPoint.z ); + + // Cancel rotation if check-ahead rotation trace fails + if( TrResults.fraction != 1.0f ) + { + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned View Yaw Test: Clipped with rotation trace fraction %f. Delta yaw not allowed \r", TrResults.fraction ); + InputAngles.yaw = viewAngles.yaw; + + idEntity* TrEnt = gameLocal.GetTraceEntity( TrResults ); + + // Detect AI collision, if entity hit or its bindmaster is an AI: + if( TrEnt != NULL && TrEnt->IsType(idAI::Type) ) + { + static_cast( TrEnt )->HadTactile( static_cast(self) ); + } + + return; + } + + // debug draw the test clip model + /* + collisionModelManager->DrawModel( ViewClip.Handle(), ViewClip.GetOrigin(), + ViewClip.GetAxis(), vec3_origin, 0.0f ); + */ +} + +void idPhysics_Player::UnleanToValidPosition( void ) +{ + trace_t trTest; + idVec3 vTest(vec3_zero); + + idPlayer *p_player = (idPlayer *) self; + idVec3 vEyeOffset = -GetGravityNormal()*p_player->EyeHeight(); + + float TestLeanDegrees = m_CurrentLeanTiltDegrees; + float TestLeanStretch = m_CurrentLeanStretch; + float DeltaDeg = TestLeanDegrees / (float) cv_pm_lean_to_valid_increments.GetInteger(); + float DeltaStretch = TestLeanStretch / (float) cv_pm_lean_to_valid_increments.GetInteger(); + + // Must temporarily set these to get proper behavior from max angle + m_leanMoveMaxAngle = m_CurrentLeanTiltDegrees; + m_leanMoveMaxStretch = m_CurrentLeanStretch; + m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; + m_leanMoveEndTilt = 0.0f; + + for( int i=0; i < cv_pm_lean_to_valid_increments.GetInteger(); i++ ) + { + // Lean degrees are always positive + TestLeanDegrees -= DeltaDeg; + TestLeanStretch -= DeltaStretch; + + // convert proposed angle and stretch to a viewpoint in world space: + vTest = LeanParmsToPoint( TestLeanDegrees, TestLeanStretch ); + gameLocal.clip.TraceBounds( trTest, current.origin + vEyeOffset, vTest, m_LeanViewBounds, MASK_SOLID | CONTENTS_BODY, self ); + + // break if valid point was found + if( trTest.fraction == 1.0f ) + break; + } + + // transform lean parameters with final answer + m_CurrentLeanTiltDegrees = TestLeanDegrees; + m_CurrentLeanStretch = TestLeanStretch; + + UpdateLeanPhysics(); +} + +bool idPhysics_Player::FindLeanDoorListenPos(const idVec3& incidencePoint, CFrobDoor* door) +{ + bool bFoundEmptySpace( false ); + int contents = -1; + idVec3 vTest(incidencePoint), vDirTest(0,0,0), vLeanDir( 1.0f, 0.0f, 0.0f ); + idAngles LeanYaw; + idAngles viewYawOnly = viewAngles; + + LeanYaw.Zero(); + LeanYaw.yaw = m_leanYawAngleDegrees - 90.0f; + + viewYawOnly.pitch = 0.0f; + viewYawOnly.roll = 0.0f; + + vDirTest = viewYawOnly.ToMat3() * LeanYaw.ToMat3() * vLeanDir; + vDirTest.Normalize(); + + int MaxCount = cv_pm_lean_door_increments.GetInteger(); + + + for( int count = 1; count < MaxCount; count++ ) + { + vTest += vDirTest * ( (float) count / (float) MaxCount ) * cv_pm_lean_door_max.GetFloat(); + + contents = gameLocal.clip.Contents( vTest, NULL, mat3_identity, CONTENTS_SOLID, self ); + + // found empty space on other side of door + if( !( (contents & MASK_SOLID) > 0 ) ) + { + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Lean Into Door: Found empty space on other side of door. Incidence point: %s Empty space point: %s \r", incidencePoint.ToString(), vTest.ToString() ); + + bFoundEmptySpace = true; + m_LeanDoorListenPos = vTest; + break; + } + } + + // uncomment to debug the lean direction line + // gameRenderWorld->DebugArrow( colorBlue, IncidencePoint, IncidencePoint + 15.0f * vDirTest, 5.0f, 10000 ); + + return bFoundEmptySpace; +} + +void idPhysics_Player::UpdateLeanDoor( void ) +{ + idPlayer* player = static_cast(self); + + CFrobDoor* door = m_LeanDoorEnt.GetEntity(); + + if( door && player ) + { + if (!m_LeanDoorEnt.IsValid() || door->IsOpen() || !IsLeaning()) + { + m_LeanDoorEnt = NULL; + return; + } + + idBounds TestBounds = m_LeanViewBounds; + TestBounds.ExpandSelf( cv_pm_lean_door_bounds_exp.GetFloat() ); + TestBounds.TranslateSelf( player->GetEyePosition() ); + +/** More precise test (Not currently used) + + int numEnts = 0; + idEntity *ents[MAX_GENTITIES]; + idEntity *ent = NULL; + bool bMatchedDoor(false); + + numEnts = gameLocal.clip.EntitiesTouchingBounds( TestBounds, CONTENTS_SOLID, ents, MAX_GENTITIES); + for( int i=0; i < numEnts; i++ ) + { + if( ents[i] == (idEntity *) door ) + { + bMatchedDoor = true; + break; + } + } + + if( !bMatchedDoor ) + { + m_LeanDoorEnt = NULL; + goto Quit; + } +**/ + + if( !TestBounds.IntersectsBounds( door->GetPhysics()->GetAbsBounds() ) ) + { + m_LeanDoorEnt = NULL; + return; + } + + // We are leaning into a door + // overwrite the current player listener loc with that calculated for the door + player->SetDoorListenLoc( m_LeanDoorListenPos ); + } +} + +bool idPhysics_Player::IsDoorLeaning( void ) +{ + return (m_LeanDoorEnt.GetEntity() != NULL) && m_LeanDoorEnt.IsValid(); +} + +idStr idPhysics_Player::GetClimbSurfaceType() const +{ + return m_bOnClimb ? m_ClimbSurfName : ""; +} + +float idPhysics_Player::GetClimbLateralCoord(const idVec3& origVec) const +{ + if (m_bOnClimb) + { + idVec3 orig = origVec - (origVec * gravityNormal) * gravityNormal; + + idVec3 climbNormXY = m_vClimbNormal - (m_vClimbNormal * gravityNormal) * gravityNormal; + idVec3 latNormal = climbNormXY.Cross(gravityNormal); + latNormal.NormalizeFast(); + + return orig * latNormal; + } + + return 0.0f; +} + +void idPhysics_Player::SetRefEntVel( idEntity *ent, int bodID) +{ + idVec3 EntCOM, ThisCOM, r, AngVel; + idMat3 DummyMat; + float dummy; + + if( !ent ) + { + m_RefEntVelocity.Zero(); + } + else + { + idPhysics *phys = ent->GetPhysics(); + + // Sometimes we have statics bound to movers, and the static doesn't return a velocity + if( phys->IsType(idPhysics_Static::Type) + || phys->IsType(idPhysics_StaticMulti::Type) ) + { + if( ent->GetBindMaster() ) + { + phys = ent->GetBindMaster()->GetPhysics(); + // TODO: Replace this with ent->bindbody + bodID = 0; + DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("SetRefVel switched from ent %s to bindmaster %s\r", ent->name.c_str(), ent->GetBindMaster()->name.c_str() ); + } + } + + m_RefEntVelocity = phys->GetLinearVelocity( bodID ); + // Apparently this is needed for moveables riding on movers: + m_RefEntVelocity += phys->GetPushedLinearVelocity( bodID ); + + // Add orbit velocity from angular vel of mover + // v_tangential = omega X r, where r is the distance between COM + AngVel = phys->GetAngularVelocity( bodID ); + AngVel += phys->GetPushedAngularVelocity( bodID ); + + // Find our center of mass: + GetClipModel()->GetMassProperties( 1.0f, dummy, ThisCOM, DummyMat ); + ThisCOM = GetOrigin() + ThisCOM * GetAxis(); + // Find entity center of mass + if( phys->GetClipModel( bodID)->IsTraceModel() ) + { + phys->GetClipModel( bodID )->GetMassProperties( 1.0f, dummy, EntCOM, DummyMat ); + EntCOM = phys->GetOrigin( bodID ) + EntCOM * phys->GetAxis( bodID ); + } + else + EntCOM = phys->GetOrigin( bodID ); + + // r = ThisCOM - EntCOM; + r = GetOrigin() - phys->GetOrigin( bodID ); + +// Linear component due to angular velocity commented out for now +// Is not correct and tends to kill the player. + +// m_RefEntVelocity += AngVel.Cross( r ); + + // Uncomment for debugging + // DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("SetRefEntVelocity: Ent angular velocity is %s, Ent COM is %s, player COM is %s, added linear velocity due to angular rotation of ent is: %s\r",AngVel.ToString(),EntCOM.ToString(),ThisCOM.ToString(),AngVel.Cross(r).ToString() ); + } +} + +idVec3 idPhysics_Player::GetRefEntVel( void ) const +{ + return m_RefEntVelocity; +} + +int idPhysics_Player::GetMovementFlags( void ) +{ + return current.movementFlags; +} + +void idPhysics_Player::SetMovementFlags( int flags ) +{ + current.movementFlags = flags; +} diff --git a/game/physics/Physics_Player.h b/game/physics/Physics_Player.h new file mode 100644 index 000000000..08bb07d8d --- /dev/null +++ b/game/physics/Physics_Player.h @@ -0,0 +1,884 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +#ifndef __PHYSICS_PLAYER_H__ +#define __PHYSICS_PLAYER_H__ + +#include + +/* +=================================================================================== + + Player physics + + Simulates the motion of a player through the environment. Input from the + player is used to allow a certain degree of control over the motion. + +=================================================================================== +*/ + +class idAFEntity_Base; +class CFrobDoor; + +// movementType +typedef enum { + PM_NORMAL, // normal physics + PM_DEAD, // no acceleration or turning, but free falling + PM_SPECTATOR, // flying without gravity but with collision detection + PM_FREEZE, // stuck in place without control + PM_NOCLIP // flying without collision detection nor gravity +} pmtype_t; + +#ifndef MOD_WATERPHYSICS + +// waterLevel_t has been moved to Physics_Actor.h + +typedef enum +{ + WATERLEVEL_NONE, + WATERLEVEL_FEET, + WATERLEVEL_WAIST, + WATERLEVEL_HEAD +} waterLevel_t; + +#endif // MOD_WATERPHYSICS + + +#define MAXTOUCH 32 + +typedef struct playerPState_s { + idVec3 origin; + idVec3 velocity; + idVec3 localOrigin; + idVec3 pushVelocity; + float stepUp; + int movementType; + int movementFlags; + int movementTime; +} playerPState_t; + + +// This enumreation defines the phases of the mantling movement +enum EMantlePhase +{ + notMantling_DarkModMantlePhase = 0, + hang_DarkModMantlePhase, + pull_DarkModMantlePhase, + shiftHands_DarkModMantlePhase, + push_DarkModMantlePhase, + fixClipping_DarkModMantlePhase, + NumMantlePhases, +}; + +class CForcePush; +typedef boost::shared_ptr CForcePushPtr; + +// The class itself +class idPhysics_Player : + public idPhysics_Actor +{ +public: + CLASS_PROTOTYPE( idPhysics_Player ); + + idPhysics_Player(); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // initialisation + void SetSpeed( const float newWalkSpeed, const float newCrouchSpeed ); + void SetMaxStepHeight( const float newMaxStepHeight ); + float GetMaxStepHeight( void ) const; + void SetMaxJumpHeight( const float newMaxJumpHeight ); + void SetMovementType( const pmtype_t type ); + int GetMovementType( void ); // grayman #2345 + + /** + * Get/set the movement flags, used to force a crouch externally + **/ + int GetMovementFlags( void ); + void SetMovementFlags( int ); + void SetPlayerInput( const usercmd_t &cmd, const idAngles &newViewAngles ); + void SetKnockBack( const int knockBackTime ); + void SetDebugLevel( bool set ); + // feed back from last physics frame +#ifndef MOD_WATERPHYSICS + + waterLevel_t GetWaterLevel( void ) const; + + int GetWaterType( void ) const; + +#endif + + bool HasJumped( void ) const; + bool HasSteppedUp( void ) const; + float GetStepUp( void ) const; + bool IsCrouching( void ) const; + + /** + * Returns the reference entity velocity. Nonzero only when the + * player is climbing/roping so that their reference frame + * is determined by some ent they're attached to + **/ + idVec3 GetRefEntVel( void ) const; + + /** + * greebo: Returns the rope entity or NULL if the player is not attached to any rope. + */ + idEntity* GetRopeEntity(); + + bool OnRope() const; + + /** + * True if the player is climbing on a ladder or wall + **/ + bool OnLadder() const; + + /** + * Returns the surface type the player is climbing + * Returns empty string if the player is not climbing + **/ + idStr GetClimbSurfaceType() const; + + /** + * Returns the lateral world coordinates resolved into the lateral direction + * of the climbing surface. Used to keep track of lateral position for climb movement sounds + **/ + float GetClimbLateralCoord(const idVec3& origVec) const; + + /** + * Returns the distance between climbing sounds, in horizontal and vertical coords + **/ + int GetClimbSndRepDistVert() { return m_ClimbSndRepDistVert; } + int GetClimbSndRepDistHoriz() { return m_ClimbSndRepDistHoriz; } + + const idVec3 & PlayerGetOrigin() const; // != GetOrigin + + /** + * Get the view yaw and pitch changes between last frame and this frame + * Useful for rotating items in response to yaw, rope arrow, etc + * Returns the change in degrees + **/ + float GetDeltaViewYaw(); + float GetDeltaViewPitch(); + +public: + + /** + * Ishtvan: This variable is set when the player used crouch to detach + * from a climbable and is still holding down the button + * This is not saved/restored but cleared on restore, just to be safe + **/ + bool m_bClimbDetachCrouchHeld; + +public: // common physics interface + + // virtual override of base class method SetSelf() to set the push force owner + virtual void SetSelf( idEntity *e ); + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + + // This is true as soon as the player's velocity is well enough above walk speed + bool HasRunningVelocity(); + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + void ClearPushedVelocity( void ); + + void SetMaster( idEntity *master, const bool orientated = true ); + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +/** +* Removes stale pointers when a rope entity is destroyed +* RopeEnt is the rope entity that's about to be destroyed. +**/ + void RopeRemovalCleanup( idEntity *RopeEnt ); + +private: + // player physics state + playerPState_t current; + playerPState_t saved; + + // properties + float walkSpeed; + float crouchSpeed; + float maxStepHeight; + float maxJumpHeight; + int debugLevel; // if set, diagnostic output will be printed + + // greebo: Used for "jump stamina" + int lastJumpTime; + + // player input + usercmd_t command; + idAngles viewAngles; + + // run-time variables + int framemsec; + float frametime; + float playerSpeed; + idVec3 viewForward; + idVec3 viewRight; + + // walk movement + bool walking; + bool groundPlane; + trace_t groundTrace; + const idMaterial * groundMaterial; + + /** + * When the player is climbing on an entity (rope/wall, TODO: Apply to mantling) + * This stores the velocity of the entity they're climbing on, for adding and subtracting + * across functions if needed. + **/ + idVec3 m_RefEntVelocity; + + // rope movement + + /** + * Set to true if the player is moving and contacts a rope + **/ + bool m_bRopeContact; + + /** + * The rope entity that the player last attached to + **/ + idEntityPtr m_RopeEntity; + + /** + * The rope entity that the player last touched (not necessarily attached to) + * Used for the case where the player starts inside a rope and jumps up + **/ + idEntityPtr m_RopeEntTouched; + + + /** + * toggled based on whether the player should stay attached to rope + **/ + bool m_bOnRope; + + /** + * toggled on in the frame that the player first attaches to the rope + **/ + bool m_bJustHitRope; + /** + * Timer used to enforce time between kicks while on rope + **/ + int m_RopeKickTime; + + // ladder movement + /** + * Ladder is found ahead of us along view direction + **/ + bool m_bClimbableAhead; + /** + * We are currently attached to a ladder + **/ + bool m_bOnClimb; + /** + * Normal vector of the surface we're climbing on + **/ + idVec3 m_vClimbNormal; + /** + * Attachment point of where the player's origin attaches to the ladder + * In World coordinates + * NOTE: This is the last known attachment point + * The player is allowed to deviate from this a little to climb around corners + **/ + idVec3 m_vClimbPoint; + + /** + * Entity they're currently climbing on (used to add relative velocity) + **/ + idEntityPtr m_ClimbingOnEnt; + /** + * Set to true if the player has just detached from climbing this frame + * Used to tell SlideMove to step up at the top of something + **/ + bool m_bClimbDetachThisFrame; + + /** + * Set to true during the initial climb phase when the player + * has gone from not climbing on anything to attaching to something ahead. + * This is intended to fix a hovering-in-midair bug. + **/ + bool m_bClimbInitialPhase; + + /** + * String name of the surface type the player is climbing + **/ + idStr m_ClimbSurfName; + /** + * Max horizontal climbing velocity (parsed from player.def for given surface name) + **/ + float m_ClimbMaxVelHoriz; + /** + * Max vertical climbing veocity (parsed from player.def for given surface name) + **/ + float m_ClimbMaxVelVert; + /** + * Distance between repitions of the climbing sound, in vertical and horizontal direction + * An integer number of doomunits + **/ + int m_ClimbSndRepDistVert; + int m_ClimbSndRepDistHoriz; + + int m_NextAttachTime; + + /** + * View yaw and pitch changes between this frame and last frame + * In degrees. + **/ + float m_DeltaViewYaw; + float m_DeltaViewPitch; + + /** + * Door that the player is leaning into + * Set to NULL if the player is not leaning into a door + **/ + idEntityPtr m_LeanDoorEnt; + + /** + * Position to place the player listener beyond the door when door leaning + **/ + idVec3 m_LeanDoorListenPos; + + // greebo: The push force as applied to blocking objects + CForcePushPtr m_PushForce; + + // results of last evaluate +#ifndef MOD_WATERPHYSICS + + waterLevel_t waterLevel; + + int waterType; + +#endif + + +private: + float CmdScale( const usercmd_t &cmd ) const; + void Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel ); + bool SlideMove( bool gravity, bool stepUp, bool stepDown, bool push ); + void Friction( void ); + void WaterMove( void ); + void FlyMove( void ); + void AirMove( void ); + void WalkMove( void ); + void DeadMove( void ); + void NoclipMove( void ); + void SpectatorMove( void ); + void RopeMove( void ); + void LadderMove( void ); + void CorrectAllSolid( trace_t &trace, int contents ); + void CheckGround( void ); + void CheckDuck( void ); + bool CheckJump( void ); + bool CheckRopeJump( void ); + /** + * Read in the entity's velocity and store it to m_RefEntVelocity + * If the ent is a static, the bindmaster velocity is read off instead + * bodID is the clipmodel ID for AFs, defaults to zero + **/ + void SetRefEntVel( idEntity *ent, int bodID = 0 ); + +/** +* The following are used in wall/ladder climbing +**/ + void CheckClimbable( void ); + +#ifndef MOD_WATERPHYSICS + void SetWaterLevel( void ); +#endif + void DropTimers( void ); + void MovePlayer( int msec ); + +public: + void ClimbDetach( bool bStepUp = false ); + void RopeDetach( void ); + + // angua: player can not attach to rope/ladder before this time is over + void SetNextAttachTime(int time) + { + m_NextAttachTime = time; + } + + + + //##################################################### + // Mantling handler + // by SophisticatedZombie (Damon Hill) + // + //##################################################### + +public: + + + // This method returns + // true if the player is mantling, false otherwise + bool IsMantling() const; + + // This returns the current mantling phase + EMantlePhase GetMantlePhase() const; + + // Cancels any current mantle + void CancelMantle(); + + // Checks to see if there is a mantleable target within reach + // of the player's view. If so, starts the mantle... + // If the player is already mantling, this does nothing. + void PerformMantle(); + +protected: + + /*! + * The current mantling phase + */ + EMantlePhase m_mantlePhase; + + /** + * greebo: Set to TRUE if the next mantling can start. Set to FALSE at the + * beginning of a mantle process - the jump button has to be released + * again during a non-mantling phase to set this to TRUE again. + */ + bool m_mantleStartPossible; + + /*! + * Points along the mantle path + */ + idVec3 m_mantlePullStartPos; + idVec3 m_mantlePullEndPos; + idVec3 m_mantlePushEndPos; + + /*! + * Pointer to the entity being mantled. + * This is undefined if m_mantlePhase == notMantling_DarkModMantlePhase + */ + idEntity* m_p_mantledEntity; + + /*! + * ID number of the entity being mantled + * This is 0 if m_mantlePhase == notMantling_DarkModMantlePhase + */ + int m_mantledEntityID; + + /*! + * How long will the current phase of the mantle operation take? + * Uses milliseconds and counts down to 0. + */ + float m_mantleTime; + + /*! + * Tracks, in milliseconds, how long jump button has been held down + * Counts upwards from 0. + */ + float m_jumpHeldDownTime; + + /*! + * This method determines the mantle time required for each phase of the mantle. + * I made this a function so you could implement things such as carry-weight, + * tiredness, length of lift.... + * @param[in] mantlePhase The mantle phase for which the duration is to be retrieved + */ + float GetMantleTimeForPhase(EMantlePhase mantlePhase); + + /*! + * + * Internal method to start the mantle operation + * + * @param[in] initialMantlePhase The mantle phase in which the mantle starts. + * @param[in] eyePos The position of the player's eyes in the world + * @param[in] startPos The position of the player's feet at the start of the mantle + * @param[in] endPos The position of the player's feet at the end of the mantle + */ + void StartMantle + ( + EMantlePhase initialMantlePhase, + idVec3 eyePos, + idVec3 startPos, + idVec3 endPos + ); + + /*! + * Internal method which determines the maximum vertical + * and horizontal distances for mantling + * + * @param[out] out_maxVerticalReachDistance The distance that the player can reach vertically, from their current origin + * @param[out] out_maxHorizontalReachDistance The distance that the player can reach horizontally, from their current origin + * @param[out] out_maxMantleTraceDistance The maximum distance that the traces should look in front of the player for a mantle target + */ + void GetCurrentMantlingReachDistances + ( + float& out_maxVerticalReachDistance, + float& out_maxHorizontalReachDistance, + float& out_maxMantleTraceDistance + ); + + /*! + * This method runs the trace to find a mantle target + * It first attempts to raycast along the player's gaze + * direction to determine a target. If it doesn't find one, + * then it tries a collision test along a vertical plane + * from the players feet to their height, out in the direction + * the player is facing. + * + * @param[in] maxMantleTraceDistance The maximum distance from the player that should be used in the traces + * @param[in] eyePos The position of the player's eyes, used for the beginning of the gaze trace + * @param[in] forwardVec The vector gives the direction that the player is facing + * @param[out] out_trace This trace structure will hold the result of whichever trace succeeds. If both fail, the trace fraction will be 1.0 + */ + void MantleTargetTrace + ( + float maxMantleTraceDistance, + const idVec3& eyePos, + const idVec3& forwardVec, + trace_t& out_trace + ); + + /*! + * + * This function checks the collision target of the mantle + * trace to see if there is a surface within reach distance + * upon which the player will fit. + * + * @param[in] maxVerticalReachDistance The maximum distance that the player can reach vertically from their current origin + * @param[in] maxHorizontalReachDistance The maximum distance that the player can reach horizontally from their current origin + * @param[in] in_targetTraceResult The trace which found the mantle target + * @param[out] out_mantleEndPoint If the return code is true, this out paramter specifies the position of the player's origin at the end of the mantle move. + * + * @return the result of the test + * @retval true if the mantle target has a mantleable surface + * @retval false if the mantel target does not have a mantleable surface + * + */ + bool DetermineIfMantleTargetHasMantleableSurface + ( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + trace_t& in_targetTraceResult, + idVec3& out_mantleEndPoint + ); + + /*! + * Call this method to test whether or not the path + * along the mantle movement is free of obstructions. + * + * @param[in] maxVerticalReachDistance The maximum distance that the player can reach vertically from their current origin + * @param[in] maxHorizontalReachDistance The maximum distance that the player can reach horizontally from their current origin + * @param[in] eyePos The position of the player's eyes in the world + * @param[in] mantleStartPoint The player's origin at the start of the mantle movement + * @param[in] mantleEndPoint The player's origin at the end of the mantle movement + * + * @return the result of the test + * @retval true if the path is clear + * @retval false if the path is blocked + */ + bool DetermineIfPathToMantleSurfaceIsPossible + ( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + const idVec3& eyePos, + const idVec3& mantleStartPoint, + const idVec3& mantleEndPoint + ); + + /*! + * Given a trace which resulted in a detected mantle + * target, this method checks to see if the target + * is mantleable. It looks for a surface up from gravity + * on which the player can fit while crouching. It also + * checks that the distance does not violate horizontal + * and vertical displacement rules for mantling. Finally + * it checks that the path to the mantleable surface is + * not blocked by obstructions. + * + * This method calls DetermineIfMantleTargetHasMantleableSurface and + * also DetermineIfPathToMantleSurfaceIsPossible + * + * @param[in] maxVerticalReachDistance The maximum distance from the player's origin that the player can reach vertically + * @param[in] maxHorizontalReachDistance The maximum distance from the player's origin that the player can reach horizontally + * @param[in] eyePos The position of the player's eyes (camera point) in the world coordinate system + * @param[in] in_targetTraceResult Pass in the trace result from MantleTargetTrace + * @param[out] out_mantleEndPoint If the return value is true, this passes back out what the player's origin will be at the end of the mantle + * + * @returns the result of the test + * @retval true if the mantle target can be mantled + * @retval false if the mantle target cannot be mantled + * + */ + bool ComputeMantlePathForTarget + ( + float maxVerticalReachDistance, + float maxHorizontalReachDistance, + const idVec3& eyePos, + trace_t& in_targetTraceResult, + idVec3& out_mantleEndPoint + ); + + /*! + * This handles the reduction of the mantle timer by the + * number of milliseconds between animation frames. It + * uses the timer results to update the mantle timers. + */ + void UpdateMantleTimers(); + + /*! + * This handles the movement of the the player during + * the phases of the mantle. It performs the translation + * of the player along the mantle path, the camera movement + * that creates the visual effect, and the placing of the + * player into a crouch during the end phase of the mantle. + * + */ + void MantleMove(); + + // Tests if player is holding down jump while already jumping + // (can be used to trigger mantle) + bool CheckJumpHeldDown(); + + //################################################# + // End mantling handler + //################################################# + + //##################################################### + // Leaning handler + // by SophisticatedZombie (Damon Hill) + // + //##################################################### + +protected: + + /** + * Set to true if the player is leaning at all from the vertical + **/ + bool m_bIsLeaning; + + /*! + * An axis which is perpendicular to the gravity normal and + * rotated by the given yaw angle clockwise (when looking down in direction of + * gravity) around it. The player always leans to positive angles + * around this axis. + */ + float m_leanYawAngleDegrees; + + /*! + * The current lean angle + */ + float m_CurrentLeanTiltDegrees; + + /** + * Current lean stretch fraction. When this is 1.0, the player is at full stretch, at 0.0, not stretched + **/ + float m_CurrentLeanStretch; + + /*! + * The start (roll) angle of this lean movement + */ + float m_leanMoveStartTilt; + + /*! + * The end (roll) angle of this lean movement + */ + float m_leanMoveEndTilt; + + /** + * Max lean angle (set dynamically depending on forward/sideways leans) + **/ + float m_leanMoveMaxAngle; + + /** + * Maximum lean stretch (set dynamically depending on forward/sideways leans) + **/ + float m_leanMoveMaxStretch; + + /*! + * Is the lean finished + */ + bool m_b_leanFinished; + + /*! + * How long will the current phase of the leaning operation take? + * Uses milliseconds and counts down to 0 + */ + float m_leanTime; + + /*! + * The last recorded view angles + * These are updated each animation frame and are used + * to track player rotations to due rotation collision detection. + * The original Doom3 code did not need to due collision tests + * during player view rotation, but if the player is leaning, it is + * necessary to prevent passing through solid objects + */ + idAngles m_lastPlayerViewAngles; + + float m_lastCommandViewYaw; + float m_lastCommandViewPitch; + + /*! + * The current resulting view lean angles + */ + idAngles m_viewLeanAngles; + + /*! + * The current resulting view lean translation + * In local/player coordinates (along player model axes, not world axes) + */ + idVec3 m_viewLeanTranslation; + + /** + * Lean bounds for collision testing. Same as most view testing bounds, 10x10x10 box + * Also extends 15 units downwards. Initialized once at spawn. + **/ + idBounds m_LeanViewBounds; + +protected: + /** + * This uses the other internal mtehods to coordiante the lean + * lean movement. + **/ + void LeanMove(); + + /** + * Test clipping for the current eye position, plus delta in the lean direction + **/ + bool TestLeanClip(); + + /** + * Convert a lean angle and stretch into a point in space, in world coordinates + **/ + idVec3 LeanParmsToPoint( float AngTilt, float Stretch ); + + /*! + * This method updates the lean by as much of the delta amount given + * that does not result in a clip model trace collision. + * + * This is an internal method called by LeanMove. + * UpdateLeanPhysics must be called after this. + **/ + void UpdateLeanAngle(float deltaLeanAngle, float deltaLeanStretch); + + /** + * Takes the currently set m_CurrentLeanTiltDegrees and m_CurrentLeanStretch + * And updates m_LeanTranslation and m_ViewLeanAngles + * Should be called after changing these member vars. + **/ + void UpdateLeanPhysics(); + + /** + * This method gets called when the leaned player view is found to be clipping something + * It un-leans them in increments until they are outside the solid object + **/ + void UnleanToValidPosition(); + + /** + * Calculates the listener position when leaning against a given door + * Tests points in space along the lean yaw axis until they come out the other + * side of the door into empty space. + * + * Takes the point of contact (where the trace hit the door), + * starts testing at this point, extending along lean yaw axis. + * + * If a point is found, it sets m_DoorListenPos and returns true + * If door is too thick to listen through, returns false + **/ + bool FindLeanDoorListenPos(const idVec3& incidencePoint, CFrobDoor* door); + + /** + * Tests whether the player is still leaning against the door. + * If not, clears m_LeanDoorEnt + **/ + void UpdateLeanDoor(); + +public: + + /*! + * Starts or ends a lean around and axis which is perpendicular to the gravity normal and + * rotated by the given yaw angle clockwise (when looking down in direction of + * gravity) around it. + * + * @param[in] leanYawAngleDegrees The angle of the axis around which the player will + * lean clockwise, itself rotated clockwise from straight forward. + * 0.0 leans right, 180.0 leans left, 90.0 leans forward, 270.0 leans backward + * + */ + void ToggleLean(float leanYawAngleDegrees); + + /*! + * This method tests if the player is in the middle of a leaning + * movement. + * + * @return the result of the test + * @retval true if the player is changing lean + * @retval false if the player is not changing lean + */ + bool IsLeaning(); + + /** + * Returns true if the player is leaning against a door + **/ + bool IsDoorLeaning(); + + /*! + * This is called from idPlayer to adjust the camera before + * rendering + * Returns current view lean translation in world axes + */ + const idAngles& GetViewLeanAngles() const; + + /* + * This is called from idPlayer to adjust the camera before + * rendering + */ + idVec3 GetViewLeanTranslation(); + + /** + * Takes proposed new view angles InputAngles, + * tests whether the change in yaw will cause a collision + * of the leaned camera with a wall. If so, clamps the yaw before the collision. + * Overwrites InputAngles with the new vetted angles. + * Does nothing if the player is not leaned + **/ + void UpdateLeanedInputYaw( idAngles &InputAngles ); +}; + +#endif /* !__PHYSICS_PLAYER_H__ */ diff --git a/game/physics/Physics_RigidBody.cpp b/game/physics/Physics_RigidBody.cpp new file mode 100644 index 000000000..2f74f9ee1 --- /dev/null +++ b/game/physics/Physics_RigidBody.cpp @@ -0,0 +1,2194 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../Grabber.h" + +CLASS_DECLARATION( idPhysics_Base, idPhysics_RigidBody ) +END_CLASS + +#ifdef MOD_WATERPHYSICS +const int STOP_SPEED = 10; +// if linearVelocity < WATER_STOP_LINEAR && angularVelocity < WATER_STOP_ANGULAR then set the RB to rest +// and we need this->noMoveTime + NO_MOVE_TIME < gameLocal.getTime() +const idVec3 WATER_STOP_LINEAR(10.0f,10.0f,10.0f); +const idVec3 WATER_STOP_ANGULAR(500000.0f,500000.0f,500000.0f); +const int NO_MOVE_TIME = 200; +static const float MAX_GRABBER_EXT_VELOCITY = 120.0f; +static const float MAX_GRABBER_EXT_ANGVEL = 5.0f; +#else +const float STOP_SPEED = 10.0f; +#endif + + +#undef RB_TIMINGS + +#ifdef RB_TIMINGS +static int lastTimerReset = 0; +static int numRigidBodies = 0; +static idTimer timer_total, timer_collision; +#endif + + +/* +================ +RigidBodyDerivatives +================ +*/ +void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives ) { + const idPhysics_RigidBody *p = (idPhysics_RigidBody *) clientData; + rigidBodyIState_t *s = (rigidBodyIState_t *) state; + // NOTE: this struct should be build conform rigidBodyIState_t + struct rigidBodyDerivatives_s { + idVec3 linearVelocity; + idMat3 angularMatrix; + idVec3 force; + idVec3 torque; + } *d = (struct rigidBodyDerivatives_s *) derivatives; + idVec3 angularVelocity; + idMat3 inverseWorldInertiaTensor; + + inverseWorldInertiaTensor = s->orientation * p->inverseInertiaTensor * s->orientation.Transpose(); + angularVelocity = inverseWorldInertiaTensor * s->angularMomentum; + // derivatives + d->linearVelocity = p->inverseMass * s->linearMomentum; + d->angularMatrix = SkewSymmetric( angularVelocity ) * s->orientation; + +#ifdef MOD_WATERPHYSICS + // underwater we have a higher friction + if( p->GetWaterLevelf() == 0.0f ) { + d->force = - p->linearFriction * s->linearMomentum + p->current.externalForce; + d->torque = - p->angularFriction * s->angularMomentum + p->current.externalTorque; + } else { + // don't let water friction go less than 25% of the water viscosity + float percent = Max(0.25f,p->GetSubmergedPercent(s->position,s->orientation.Transpose())); + + d->force = (-p->linearFriction * p->water->GetViscosity() * percent) * s->linearMomentum + p->current.externalForce; + d->torque = (-p->angularFriction * p->water->GetViscosity()) * s->angularMomentum + p->current.externalTorque; + } +#else + d->force = - p->linearFriction * s->linearMomentum + p->current.externalForce; + d->torque = - p->angularFriction * s->angularMomentum + p->current.externalTorque; +#endif +} + +#ifdef MOD_WATERPHYSICS +/* +================ +idPhysics_RigidBody::GetSubmergedPercent + + Approximates the percentage of the body that is submerged +================ +*/ +float idPhysics_RigidBody::GetSubmergedPercent( const idVec3 &pos, const idMat3 &rotation ) const +{ + idVec3 depth,bottom(pos); + idBounds bounds = this->GetBounds(); + float height,d; + + if( this->water == NULL ) + return 0.0f; + + // offset and rotate the bounding box + bounds += -centerOfMass; + bounds *= rotation; + + // gets the position of the object relative to the surface of the water + height = fabs(bounds[1] * gravityNormal * 2); + + // calculates the depth of the bottom of the object + bottom += (height * 0.5f) * gravityNormal; + depth = this->water->GetDepth(bottom); + d = fabs(depth * gravityNormal); + + if( d > height ) { + // the body is totally submerged + return 1.0f; + } + else if( d <= 0 ) { + return 0.0f; + } + else { + // the body is partly submerged + return d / height; + } +} + +/* +================ +idPhysics_RigidBody::GetBuoyancy + + Gets buoyancy information for this RB +================ +*/ +bool idPhysics_RigidBody::GetBuoyancy( const idVec3 &pos, const idMat3 &rotation, idVec3 &bCenter, float &percent ) const +{ + // pos - position of the RB + // rotation - axis for the RB + // bCenter - after the function is called this is an approximation for the center of buoyancy + // percent - rough percentage of the body that is under water + // used to calculate the volume of the submersed object (volume * percent) to give + // the body somewhat realistic bobbing. + // + // return true if the body is in water, false otherwise + + idVec3 tbCenter(pos); + idBounds bounds = this->GetBounds(); + idTraceModel tm = *this->GetClipModel()->GetTraceModel(); + int i,count; + + percent = this->GetSubmergedPercent(pos,rotation); + bCenter = pos; + + if( percent == 1.0f ) { + // the body is totally submerged + return true; + } + else { + // the body is partly submerged (or not in the water) + // + // We do a rough approximation for center of buoyancy. + // Normally this is done by calculating the volume of the submersed part of the body + // so the center of buoyancy is the center of mass of the submersed volume. This is + // probably a slow computation so what I do is take an average of the submersed + // vertices of the trace model. + // + // I was suprized when this first worked but you can use rb_showBuoyancy to see + // what the approximation looks like. + + // set up clip model for approximation of center of buoyancy + tm.Translate( -centerOfMass ); + tm.Rotate( rotation ); + tm.Translate( pos ); + + // calculate which vertices are under water + for( i = 0, count = 1; i < tm.numVerts; i++ ) { + if( gameLocal.clip.Contents( tm.verts[ i ], NULL, this->GetAxis(), MASK_WATER, NULL ) ) { + tbCenter += tm.verts[ i ]; + count += 1; + } + } + + if( count == 1 ) + bCenter = pos; + else + bCenter = tbCenter / count; + return (count != 1); + } +} +#endif // MOD_WATERPHYSICS + +/* +================ +idPhysics_RigidBody::Integrate + + Calculate next state from the current state using an integrator. +================ +*/ +void idPhysics_RigidBody::Integrate( float deltaTime, rigidBodyPState_t &next ) { + idVec3 position; + + position = current.i.position; + current.i.position += centerOfMass * current.i.orientation; + + current.i.orientation.TransposeSelf(); + + integrator->Evaluate( (float *) ¤t.i, (float *) &next.i, 0, deltaTime ); + next.i.orientation.OrthoNormalizeSelf(); + +#ifdef MOD_WATERPHYSICS + // apply a water gravity if the body is in water + if( this->SetWaterLevelf() != 0.0f ) { + idVec3 bCenter; + idVec3 bForce(gravityVector),rForce(-gravityVector); + float bMass,fraction,liquidMass; + bool inWater; + + inWater = this->GetBuoyancy(next.i.position,next.i.orientation.Transpose(),bCenter,fraction); + + // calculate water mass + liquidMass = this->volume * this->water->GetDensity() * fraction; + // don't let liquid mass get too high + liquidMass = Min( liquidMass, 3 * this->mass ); + + bMass = this->mass - liquidMass; + + // calculate buoyancy force + bForce *= deltaTime * bMass; + rForce *= deltaTime * liquidMass; + + // apply water force + // basically here we do a ::ApplyImpulse() but we apply it to next, not current + next.i.linearMomentum += bForce; + next.i.angularMomentum += (bCenter - next.i.position).Cross(rForce); + + // take the body out of water if it's not in water. + if( !inWater ) this->SetWater(NULL, 0.0f); + } else +#endif + next.i.linearMomentum += deltaTime * gravityVector * mass; // apply normal gravity + + current.i.orientation.TransposeSelf(); + next.i.orientation.TransposeSelf(); + + current.i.position = position; + next.i.position -= centerOfMass * next.i.orientation; + + next.atRest = current.atRest; +} + +bool idPhysics_RigidBody::PropagateImpulse(const int id, const idVec3& point, const idVec3& impulse) +{ + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Contacts with this entity %s = %d\r", self->name.c_str(), contacts.Num()); + + if (propagateImpulseLock || impulse.LengthSqr() < 1e-5) + { + // greebo: Don't process incoming small impulses, quit at once. + return false; + } + + // Don't accept other propagations during processing + propagateImpulseLock = true; + + // greebo: Check all entities touching this physics object + EvaluateContacts(); + + /** + * greebo: The incoming impulse goes through 3 stages: + * + * 1) The contact friction of this object reduces the impulse + * 2) The reduced impulse is distributed among the contact entities + * 3) The remaining impulse is applied to self. + */ + + // Save the current state + rigidBodyPState_t savedState = current; + + // Apply the impulse to the current state, as if the object was resting + current.i.linearMomentum.Zero(); + current.i.angularMomentum.Zero(); + ApplyImpulse(0, point, impulse); + +// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum before friction:", current.i.linearMomentum); +// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum before friction:", current.i.angularMomentum); + + // Calculate the friction using this state + //ContactFriction(current.lastTimeStep); + + // greebo: Disabled contact friction for now + //current.i.linearMomentum *= 1.0f; + //current.i.angularMomentum *= 1.0f; + +// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum after friction:", current.i.linearMomentum); +// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum after friction:", current.i.angularMomentum); + + // The list of all the touching entities + idList touching; + + // greebo: FIXME: A possible optimisation would be to store the contact indices instead of copying the entire struct + + //gameRenderWorld->DebugArrow(colorGreen, point, point + impulseN*10, 1, 5000); + + // greebo: Check for any contact normals that are suitable for this impulse direction + // Contact normals with angles larger than pi/2 are discarded. + for (int i = 0; i < contacts.Num(); i++) + { + if (contacts[i].entityNum == ENTITYNUM_WORLD) + continue; + + idEntity* contactEntity = gameLocal.entities[contacts[i].entityNum]; + + //gameRenderWorld->DebugArrow(colorBlue, contacts[i].point, contacts[i].point + contacts[i].normal*20, 1, 5000); + + if (contactEntity == NULL) + continue; + + if ((impulse * -contacts[i].normal) < 0.0f) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Entity %s is not in push direction.\r", contactEntity->name.c_str()); + continue; + } + + // Add the contact info to the list, it is significant + touching.Append(contacts[i]); + } + + int numTouching = touching.Num(); + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Contacts with this entity %s without world = %d\r", self->name.c_str(), numTouching); + + if (numTouching > 0) + { + // Distribute the impulse evenly across the touching entities + idVec3 impulseFraction(current.i.linearMomentum / touching.Num()); + float impulseFractionLen(impulseFraction.LengthFast()); + + // Now apply the impulse to the touching entities + for (int i = 0; i < numTouching; i++) + { + idEntity* pushed = gameLocal.entities[touching[i].entityNum]; + + if (pushed == NULL) + continue; + + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Propagating impulse to entity %s\r", pushed->name.c_str()); + //gameRenderWorld->DebugArrow(colorRed, touching[i].point, touching[i].point - touching[i].normal*10, 1, 1000); + + pushed->GetPhysics()->PropagateImpulse(id, touching[i].point, -touching[i].normal * impulseFractionLen); + + // Substract this propagated impulse from the remaining one + current.i.linearMomentum -= impulseFraction; + } + } + + // Save the remaining impulse before reverting the physics state + idVec3 remainingImpulse(current.i.linearMomentum); + + // Revert the state to as it was before + current = savedState; + + // Apply the remaining impulse to this object + ApplyImpulse(0, point, remainingImpulse); + + DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum after applyImpulse:", current.i.linearMomentum); + DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum after applyImpulse:", current.i.angularMomentum); + + propagateImpulseLock = false; + + // Return TRUE if we pushed any neighbours, FALSE if this was a single pushed object + return (numTouching > 0); +} + +/* +================ +idPhysics_RigidBody::CollisionImpulse + + Calculates the collision impulse using the velocity relative to the collision object. + The current state should be set to the moment of impact. +================ +*/ +bool idPhysics_RigidBody::CollisionImpulse( const trace_t &collision, idVec3 &impulse ) +{ + idVec3 r, linearVelocity, angularVelocity, velocity; + idMat3 inverseWorldInertiaTensor; + float impulseNumerator, impulseDenominator, vel; + impactInfo_t info; + idEntity *ent; + + // get info from other entity involved + ent = gameLocal.entities[collision.c.entityNum]; + ent->GetImpactInfo( self, collision.c.id, collision.c.point, &info ); + + // Check if we are grabbed by the grabber, and set collision var if so + if ( self == gameLocal.m_Grabber->GetSelected() ) + { + // greebo: Don't collide grabbed entities with its own bindslaves + if ( (ent->GetBindMaster() == NULL || self != ent->GetBindMaster()) + && ent != gameLocal.GetLocalPlayer() ) + { + gameLocal.m_Grabber->m_bIsColliding = true; + gameLocal.m_Grabber->m_CollNorms.AddUnique( collision.c.normal ); + } + } + + // Update moved by and set in motion by actor + if( self->m_SetInMotionByActor.GetEntity() != NULL ) + { + ent->m_SetInMotionByActor = self->m_SetInMotionByActor.GetEntity(); + ent->m_MovedByActor = self->m_MovedByActor.GetEntity(); + } + // Note: Actors should not overwrite the moved by other actors when they are hit with something + // So only overwrite if MovedByActor is NULL + if( ent->IsType(idActor::Type) + && self->m_SetInMotionByActor.GetEntity() == NULL + && !(static_cast(ent)->IsKnockedOut() || ent->health < 0) ) + { + self->m_SetInMotionByActor = (idActor *) ent; + self->m_MovedByActor = (idActor *) ent; + } + + // collision point relative to the body center of mass + r = collision.c.point - ( current.i.position + centerOfMass * current.i.orientation ); + // the velocity at the collision point + linearVelocity = inverseMass * current.i.linearMomentum; + inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; + angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; + velocity = linearVelocity + angularVelocity.Cross(r); + // subtract velocity of other entity + velocity -= info.velocity; + + // velocity in normal direction + vel = velocity * collision.c.normal; + + if ( vel > -STOP_SPEED ) { + impulseNumerator = STOP_SPEED; + } + else { + impulseNumerator = -( 1.0f + bouncyness ) * vel; + } + impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); + if ( info.invMass ) { + impulseDenominator += info.invMass + ( ( info.invInertiaTensor * info.position.Cross( collision.c.normal ) ).Cross( info.position ) * collision.c.normal ); + } + impulse = (impulseNumerator / impulseDenominator) * collision.c.normal; + +//#define DEBUG_COLLISIONS +#ifdef DEBUG_COLLISIONS + idVec3 velocityN(GetLinearVelocity()); + velocityN.NormalizeFast(); + + idVec3 velocityA(GetAngularVelocity()); + velocityA.NormalizeFast(); + + idVec3 impulseN(impulse); + impulseN.NormalizeFast(); + + idVec3 impulseA(r.Cross(impulse)); + impulseA.NormalizeFast(); + + idVec3 origin = current.i.position + centerOfMass * current.i.orientation; + + gameRenderWorld->DebugArrow(colorRed, origin, origin + velocityN*10, 1, 15); + gameRenderWorld->DebugArrow(colorBlue, origin, origin + velocityA*10, 1, 15); + + gameRenderWorld->DebugArrow(colorMagenta, idVec3(1,0,0) + origin + velocityN*10, origin + velocityN*10 + impulseN*10, 1, 15); + gameRenderWorld->DebugArrow(colorGreen, idVec3(1,0,0) + origin + velocityA*10, origin + velocityA*10 + impulseA*10, 1, 15); + + gameRenderWorld->DebugArrow(colorMdGrey, collision.c.point, collision.c.point + collision.c.normal*10, 1, 15); + //gameRenderWorld->DrawTextA(ent->name.c_str(), collision.c.point, 1, colorMdGrey, current.i.orientation, 1, 500); + +#endif + + // update linear and angular momentum with impulse + current.i.linearMomentum += impulse; + current.i.angularMomentum += r.Cross(impulse); + + //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Collision fraction of %s = %f\r", self->name.c_str(), collision.fraction); + + // if no movement at all don't blow up + if ( collision.fraction < 0.0001f ) { + current.i.linearMomentum *= 0.5f; + current.i.angularMomentum *= 0.5f; + } + + // callback to self to let the entity know about the collision + return self->Collide( collision, velocity ); +} + +/* +================ +idPhysics_RigidBody::CheckForCollisions + + Check for collisions between the current and next state. + If there is a collision the next state is set to the state at the moment of impact. +================ +*/ +bool idPhysics_RigidBody::CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision ) { +//#define TEST_COLLISION_DETECTION + idMat3 axis; + idRotation rotation; +#ifdef MOD_WATERPHYSICS + idVec3 pos; + trace_t waterCollision; +#endif + bool collided = false; + +#ifdef TEST_COLLISION_DETECTION + bool startsolid; + if ( gameLocal.clip.Contents( current.i.position, clipModel, current.i.orientation, clipMask, self ) ) { + startsolid = true; + } +#endif + + TransposeMultiply( current.i.orientation, next.i.orientation, axis ); + rotation = axis.ToRotation(); + rotation.SetOrigin( current.i.position ); + + // if there was a collision +#ifdef MOD_WATERPHYSICS + pos = next.i.position; +#endif + + if ( gameLocal.clip.Motion( collision, current.i.position, next.i.position, rotation, clipModel, current.i.orientation, clipMask, self ) ) { + + // set the next state to the state at the moment of impact + next.i.position = collision.endpos; + next.i.orientation = collision.endAxis; + next.i.linearMomentum = current.i.linearMomentum; + next.i.angularMomentum = current.i.angularMomentum; + collided = true; + } + +#ifdef MOD_WATERPHYSICS + // Check for water collision + // ideally we could do this check in one step but if a body moves quickly in shallow water + // they will occasionally clip through a solid entity (ie. fall through the floor) + if ( gameLocal.clip.Motion( waterCollision, current.i.position, pos, rotation, clipModel, current.i.orientation, MASK_WATER, self ) ) + { + idEntity *ent = gameLocal.entities[waterCollision.c.entityNum]; + + // make sure the object didn't collide with something before hitting the water (we don't splash for that case) + if( !collided || waterCollision.fraction < collision.fraction ) { + + // if the object collides with something with a physics_liquid + if( ent->GetPhysics()->IsType( idPhysics_Liquid::Type ) ) { + idPhysics_Liquid *liquid = static_cast(ent->GetPhysics()); + impactInfo_t info; + + self->GetImpactInfo(ent,waterCollision.c.id,waterCollision.c.point,&info); + + // apply water splash friction + if( this->water == NULL ) { + idVec3 impulse = -info.velocity * this->volume * liquid->GetDensity() * 0.25f; + impulse = (impulse * gravityNormal) * gravityNormal; + + if( next.i.linearMomentum.LengthSqr() < impulse.LengthSqr() ) { + // cancel falling, maintain sideways movement (lateral?) + next.i.linearMomentum -= (next.i.linearMomentum * gravityNormal) * gravityNormal; + } + else { + next.i.angularMomentum += ( waterCollision.c.point - ( next.i.position + centerOfMass * next.i.orientation ) ).Cross( impulse ); + next.i.linearMomentum += impulse * 0.5f; + } + } + + this->SetWater(liquid, ent->spawnArgs.GetFloat("murkiness", "0")); + this->water->Splash(this->self,this->volume,info,waterCollision); + } + } + } +#endif + +#ifdef TEST_COLLISION_DETECTION + if ( gameLocal.clip.Contents( next.i.position, clipModel, next.i.orientation, clipMask, self ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + return collided; +} + +/* +================ +idPhysics_RigidBody::ContactFriction + + Does not solve friction for multiple simultaneous contacts but applies contact friction in isolation. + Uses absolute velocity at the contact points instead of the velocity relative to the contact object. +================ +*/ +void idPhysics_RigidBody::ContactFriction( float deltaTime ) { + int i; + float magnitude, impulseNumerator, impulseDenominator; + idMat3 inverseWorldInertiaTensor; + idVec3 linearVelocity, angularVelocity; + idVec3 massCenter, r, velocity, normal, impulse, normalVelocity; + + inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; + + massCenter = current.i.position + centerOfMass * current.i.orientation; + + for ( i = 0; i < contacts.Num(); i++ ) { + + r = contacts[i].point - massCenter; + + // calculate velocity at contact point + linearVelocity = inverseMass * current.i.linearMomentum; + angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; + velocity = linearVelocity + angularVelocity.Cross(r); + + // velocity along normal vector + normalVelocity = ( velocity * contacts[i].normal ) * contacts[i].normal; + + // calculate friction impulse + normal = -( velocity - normalVelocity ); + magnitude = normal.Normalize(); + impulseNumerator = contactFriction * magnitude; + impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( normal ) ).Cross( r ) * normal ); + impulse = (impulseNumerator / impulseDenominator) * normal; + + // apply friction impulse + current.i.linearMomentum += impulse; + current.i.angularMomentum += r.Cross(impulse); + + // if moving towards the surface at the contact point + if ( normalVelocity * contacts[i].normal < 0.0f ) { + // calculate impulse + normal = -normalVelocity; + impulseNumerator = normal.Normalize(); + impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( normal ) ).Cross( r ) * normal ); + impulse = (impulseNumerator / impulseDenominator) * normal; + + // apply impulse + current.i.linearMomentum += impulse; + current.i.angularMomentum += r.Cross( impulse ); + } + } +} + +/* +================ +idPhysics_RigidBody::TestIfAtRest + + Returns true if the body is considered at rest. + Does not catch all cases where the body is at rest but is generally good enough. +================ +*/ +#ifdef MOD_WATERPHYSICS +bool idPhysics_RigidBody::TestIfAtRest( void ) { +#else +bool idPhysics_RigidBody::TestIfAtRest( void ) const { +#endif + int i; + float gv; + idVec3 v, av, normal, point; + idMat3 inverseWorldInertiaTensor; + idFixedWinding contactWinding; + + if ( current.atRest >= 0 ) { + return true; + } +#ifdef MOD_WATERPHYSICS + // do some special checks if the body is in water + if( this->water != NULL ) { + if( this->current.i.linearMomentum.LengthSqr() < WATER_STOP_LINEAR.LengthSqr() && + this->current.i.angularMomentum.LengthSqr() < WATER_STOP_ANGULAR.LengthSqr() ) { + + if( this->noMoveTime == 0 ) { + this->noMoveTime = gameLocal.GetTime(); + } else if( this->noMoveTime+NO_MOVE_TIME < gameLocal.GetTime() ) { + this->noMoveTime = 0; + return true; + } + } else { + this->noMoveTime = 0; + } + } +#endif + + // need at least 3 contact points to come to rest + if ( contacts.Num() < 3 ) { + return false; + } + + // get average contact plane normal + normal.Zero(); + for ( i = 0; i < contacts.Num(); i++ ) { + normal += contacts[i].normal; + } + normal /= (float) contacts.Num(); + normal.Normalize(); + + // if on a too steep surface + if ( (normal * gravityNormal) > -0.7f ) { + return false; + } + + // create bounds for contact points + contactWinding.Clear(); + for ( i = 0; i < contacts.Num(); i++ ) { + // project point onto plane through origin orthogonal to the gravity + point = contacts[i].point - (contacts[i].point * gravityNormal) * gravityNormal; + contactWinding.AddToConvexHull( point, gravityNormal ); + } + + // need at least 3 contact points to come to rest + if ( contactWinding.GetNumPoints() < 3 ) { + return false; + } + + // center of mass in world space + point = current.i.position + centerOfMass * current.i.orientation; + point -= (point * gravityNormal) * gravityNormal; + + // if the point is not inside the winding + if ( !contactWinding.PointInside( gravityNormal, point, 0 ) ) { + return false; + } + + // linear velocity of body + v = inverseMass * current.i.linearMomentum; + // linear velocity in gravity direction + gv = v * gravityNormal; + // linear velocity orthogonal to gravity direction + v -= gv * gravityNormal; + + // if too much velocity orthogonal to gravity direction + if ( v.Length() > STOP_SPEED ) { + return false; + } + // if too much velocity in gravity direction + if ( gv > 2.0f * STOP_SPEED || gv < -2.0f * STOP_SPEED ) { + return false; + } + + // calculate rotational velocity + inverseWorldInertiaTensor = current.i.orientation * inverseInertiaTensor * current.i.orientation.Transpose(); + av = inverseWorldInertiaTensor * current.i.angularMomentum; + + // if too much rotational velocity + if ( av.LengthSqr() > STOP_SPEED ) { + return false; + } + + return true; +} + +/* +================ +idPhysics_RigidBody::DropToFloorAndRest + + Drops the object straight down to the floor and verifies if the object is at rest on the floor. +================ +*/ +void idPhysics_RigidBody::DropToFloorAndRest( void ) { + idVec3 down; + trace_t tr; + + if ( testSolid ) { + + testSolid = false; + + if ( gameLocal.clip.Contents( current.i.position, clipModel, current.i.orientation, clipMask, self ) ) { + gameLocal.DWarning( "rigid body in solid for entity '%s' type '%s' at (%s)", + self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); + Rest(); + dropToFloor = false; + return; + } + } + + // put the body on the floor + down = current.i.position + gravityNormal * 128.0f; + gameLocal.clip.Translation( tr, current.i.position, down, clipModel, current.i.orientation, clipMask, self ); + current.i.position = tr.endpos; + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), tr.endpos, current.i.orientation ); + + // if on the floor already + if ( tr.fraction == 0.0f ) { + // test if we are really at rest + EvaluateContacts(); + if ( !TestIfAtRest() ) { + gameLocal.DWarning( "rigid body not at rest for entity '%s' type '%s' at (%s)", + self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); + } + Rest(); + dropToFloor = false; + } else if ( IsOutsideWorld() ) { + gameLocal.Warning( "rigid body outside world bounds for entity '%s' type '%s' at (%s)", + self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); + Rest(); + dropToFloor = false; + } +} + +/* +================ +idPhysics_RigidBody::DebugDraw +================ +*/ +void idPhysics_RigidBody::DebugDraw( void ) { + + if ( rb_showBodies.GetBool() || ( rb_showActive.GetBool() && current.atRest < 0 ) ) { + collisionModelManager->DrawModel( clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis(), vec3_origin, 0.0f ); + } + + if ( rb_showMass.GetBool() ) { +#ifdef MOD_WATERPHYSICS + if( this->water != NULL ) { + idVec3 pos; + float percent, liquidMass; + + pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; + percent = this->GetSubmergedPercent(pos,this->current.i.orientation.Transpose()); + + liquidMass = this->mass - ( this->volume * this->water->GetDensity() * percent ); + + gameRenderWorld->DrawText( va( "\n%1.2f", liquidMass), current.i.position, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + else +#endif + gameRenderWorld->DrawText( va( "\n%1.2f", mass ), current.i.position, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + + if ( rb_showInertia.GetBool() ) { + idMat3 &I = inertiaTensor; + gameRenderWorld->DrawText( va( "\n\n\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )", + I[0].x, I[0].y, I[0].z, + I[1].x, I[1].y, I[1].z, + I[2].x, I[2].y, I[2].z ), + current.i.position, 0.05f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); + } + + if ( rb_showVelocity.GetBool() ) { + DrawVelocity( clipModel->GetId(), 0.1f, 4.0f ); + } + +#ifdef MOD_WATERPHYSICS + if( rb_showBuoyancy.GetBool() && this->water != NULL ) { + idVec3 pos; + idVec3 bCenter; + float percent; + + pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; + this->GetBuoyancy(pos,this->current.i.orientation.Transpose(),bCenter,percent); + + gameRenderWorld->DebugArrow(colorGreen,pos,bCenter,1); + gameRenderWorld->DrawText( va( "%1.2f",percent), pos, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); + } +#endif +} + +/* +================ +idPhysics_RigidBody::idPhysics_RigidBody +================ +*/ +idPhysics_RigidBody::idPhysics_RigidBody( void ) { + + // set default rigid body properties + SetClipMask( MASK_SOLID ); + SetBouncyness( 0.6f ); + SetFriction( 0.6f, 0.6f, 0.0f ); + clipModel = NULL; + + memset( ¤t, 0, sizeof( current ) ); + + current.atRest = -1; + current.lastTimeStep = USERCMD_MSEC; + + current.i.position.Zero(); + current.i.orientation.Identity(); + + current.i.linearMomentum.Zero(); + current.i.angularMomentum.Zero(); + + saved = current; + + mass = 1.0f; + inverseMass = 1.0f; + centerOfMass.Zero(); + inertiaTensor.Identity(); + inverseInertiaTensor.Identity(); +#ifdef MOD_WATERPHYSICS + this->water = NULL; + this->m_fWaterMurkiness = 0.0f; +#endif + + // use the least expensive euler integrator + integrator = new idODE_Euler( sizeof(rigidBodyIState_t) / sizeof(float), RigidBodyDerivatives, this ); + + dropToFloor = false; + noImpact = false; + noContact = false; + + hasMaster = false; + isOrientated = false; + +#ifdef MOD_WATERPHYSICS + this->noMoveTime = 0; +#endif +#ifdef RB_TIMINGS + lastTimerReset = 0; +#endif + + isBlocked = false; + propagateImpulseLock = false; + + memset(&collisionTrace, 0, sizeof(collisionTrace)); + + // tels + maxForce.Zero(); + maxTorque.Zero(); +} + +/* +================ +idPhysics_RigidBody::~idPhysics_RigidBody +================ +*/ +idPhysics_RigidBody::~idPhysics_RigidBody( void ) { + if ( clipModel ) { + delete clipModel; + clipModel = NULL; + } + delete integrator; +} + +/* +================ +idPhysics_RigidBody_SavePState +================ +*/ +void idPhysics_RigidBody_SavePState( idSaveGame *savefile, const rigidBodyPState_t &state ) { + savefile->WriteInt( state.atRest ); + savefile->WriteFloat( state.lastTimeStep ); + savefile->WriteVec3( state.localOrigin ); + savefile->WriteMat3( state.localAxis ); + savefile->Write( &state.pushVelocity, sizeof( state.pushVelocity ) ); + savefile->WriteVec3( state.externalForce ); + savefile->WriteVec3( state.externalTorque ); + + savefile->WriteVec3( state.i.position ); + savefile->WriteMat3( state.i.orientation ); + savefile->WriteVec3( state.i.linearMomentum ); + savefile->WriteVec3( state.i.angularMomentum ); +} + +/* +================ +idPhysics_RigidBody_RestorePState +================ +*/ +void idPhysics_RigidBody_RestorePState( idRestoreGame *savefile, rigidBodyPState_t &state ) { + savefile->ReadInt( state.atRest ); + savefile->ReadFloat( state.lastTimeStep ); + savefile->ReadVec3( state.localOrigin ); + savefile->ReadMat3( state.localAxis ); + savefile->Read( &state.pushVelocity, sizeof( state.pushVelocity ) ); + savefile->ReadVec3( state.externalForce ); + savefile->ReadVec3( state.externalTorque ); + + savefile->ReadVec3( state.i.position ); + savefile->ReadMat3( state.i.orientation ); + savefile->ReadVec3( state.i.linearMomentum ); + savefile->ReadVec3( state.i.angularMomentum ); +} + +/* +================ +idPhysics_RigidBody::Save +================ +*/ +void idPhysics_RigidBody::Save( idSaveGame *savefile ) const { + + idPhysics_RigidBody_SavePState( savefile, current ); + idPhysics_RigidBody_SavePState( savefile, saved ); + + savefile->WriteFloat( linearFriction ); + savefile->WriteFloat( angularFriction ); + savefile->WriteFloat( contactFriction ); + savefile->WriteFloat( bouncyness ); + savefile->WriteClipModel( clipModel ); + + savefile->WriteFloat( mass ); +#ifdef MOD_WATERPHYSICS + savefile->WriteFloat( volume ); +#endif + savefile->WriteFloat( inverseMass ); + savefile->WriteVec3( centerOfMass ); + savefile->WriteMat3( inertiaTensor ); + savefile->WriteMat3( inverseInertiaTensor ); + + savefile->WriteBool( dropToFloor ); + savefile->WriteBool( testSolid ); + savefile->WriteBool( noImpact ); + savefile->WriteBool( noContact ); + + savefile->WriteBool( hasMaster ); + savefile->WriteBool( isOrientated ); + + savefile->WriteBool(isBlocked); + // greebo: Note this is not saved (yet). Uncomment this after release 1.00 + //savefile->WriteBool(propagateImpulseLock); + savefile->WriteTrace(collisionTrace); + + // tels + savefile->WriteVec3( maxForce ); + savefile->WriteVec3( maxTorque ); +} + +/* +================ +idPhysics_RigidBody::Restore +================ +*/ +void idPhysics_RigidBody::Restore( idRestoreGame *savefile ) { + + idPhysics_RigidBody_RestorePState( savefile, current ); + idPhysics_RigidBody_RestorePState( savefile, saved ); + + savefile->ReadFloat( linearFriction ); + savefile->ReadFloat( angularFriction ); + savefile->ReadFloat( contactFriction ); + savefile->ReadFloat( bouncyness ); + savefile->ReadClipModel( clipModel ); + + savefile->ReadFloat( mass ); +#ifdef MOD_WATERPHYSICS + savefile->ReadFloat( volume ); +#endif + savefile->ReadFloat( inverseMass ); + savefile->ReadVec3( centerOfMass ); + savefile->ReadMat3( inertiaTensor ); + savefile->ReadMat3( inverseInertiaTensor ); + + savefile->ReadBool( dropToFloor ); + savefile->ReadBool( testSolid ); + savefile->ReadBool( noImpact ); + savefile->ReadBool( noContact ); + + savefile->ReadBool( hasMaster ); + savefile->ReadBool( isOrientated ); + + savefile->ReadBool(isBlocked); + // greebo: Note this is not saved (yet). Uncomment this after release 1.00 + //savefile->ReadBool(propagateImpulseLock); + savefile->ReadTrace(collisionTrace); + + // tels + savefile->ReadVec3( maxForce ); + savefile->ReadVec3( maxTorque ); +} + +/* +================ +idPhysics_RigidBody::SetClipModel +================ +*/ +#define MAX_INERTIA_SCALE 10.0f + +void idPhysics_RigidBody::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) { + int minIndex; + idMat3 inertiaScale; + + assert( self ); + assert( model ); // we need a clip model + assert( model->IsTraceModel() ); // and it should be a trace model + assert( density > 0.0f ); // density should be valid + + if ( clipModel && clipModel != model && freeOld ) { + delete clipModel; + } + clipModel = model; + clipModel->Link( gameLocal.clip, self, 0, current.i.position, current.i.orientation ); + + // get mass properties from the trace model + clipModel->GetMassProperties( density, mass, centerOfMass, inertiaTensor ); + + // check whether or not the clip model has valid mass properties + if ( mass <= 0.0f || FLOAT_IS_NAN( mass ) ) { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING( "idPhysics_RigidBody::SetClipModel: invalid mass for entity '%s' type '%s'", + self->name.c_str(), self->GetType()->classname ); + mass = 1.0f; + centerOfMass.Zero(); + inertiaTensor.Identity(); + } + +#ifdef MOD_WATERPHYSICS + this->volume = mass / density; +#endif + + // check whether or not the inertia tensor is balanced + minIndex = Min3Index( inertiaTensor[0][0], inertiaTensor[1][1], inertiaTensor[2][2] ); + inertiaScale.Identity(); + inertiaScale[0][0] = inertiaTensor[0][0] / inertiaTensor[minIndex][minIndex]; + inertiaScale[1][1] = inertiaTensor[1][1] / inertiaTensor[minIndex][minIndex]; + inertiaScale[2][2] = inertiaTensor[2][2] / inertiaTensor[minIndex][minIndex]; + + if ( inertiaScale[0][0] > MAX_INERTIA_SCALE || inertiaScale[1][1] > MAX_INERTIA_SCALE || inertiaScale[2][2] > MAX_INERTIA_SCALE ) { + gameLocal.DWarning( "idPhysics_RigidBody::SetClipModel: unbalanced inertia tensor for entity '%s' type '%s'", + self->name.c_str(), self->GetType()->classname ); + float min = inertiaTensor[minIndex][minIndex] * MAX_INERTIA_SCALE; + inertiaScale[(minIndex+1)%3][(minIndex+1)%3] = min / inertiaTensor[(minIndex+1)%3][(minIndex+1)%3]; + inertiaScale[(minIndex+2)%3][(minIndex+2)%3] = min / inertiaTensor[(minIndex+2)%3][(minIndex+2)%3]; + inertiaTensor *= inertiaScale; + } + + inverseMass = 1.0f / mass; + inverseInertiaTensor = inertiaTensor.Inverse() * ( 1.0f / 6.0f ); + + current.i.linearMomentum.Zero(); + current.i.angularMomentum.Zero(); +} + +/* +================ +idPhysics_RigidBody::GetClipModel +================ +*/ +idClipModel *idPhysics_RigidBody::GetClipModel( int id ) const { + return clipModel; +} + +/* +================ +idPhysics_RigidBody::GetNumClipModels +================ +*/ +int idPhysics_RigidBody::GetNumClipModels( void ) const { + return 1; +} + +/* +================ +idPhysics_RigidBody::SetMass +================ +*/ +void idPhysics_RigidBody::SetMass( float mass, int id ) { + assert( mass > 0.0f ); + inertiaTensor *= mass / this->mass; + inverseInertiaTensor = inertiaTensor.Inverse() * (1.0f / 6.0f); + this->mass = mass; + inverseMass = 1.0f / mass; +} + +/* +================ +idPhysics_RigidBody::GetMass +================ +*/ +float idPhysics_RigidBody::GetMass( int id ) const { +#ifdef MOD_WATERPHYSICS + if( this->water != NULL ) { + idVec3 pos; + float percent,bMass; + + pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; + percent = this->GetSubmergedPercent(pos,this->current.i.orientation); + bMass = mass - (this->volume * this->water->GetDensity() * percent); + + return bMass; + } + else +#endif + return mass; +} + +/* +================ +idPhysics_RigidBody::SetFriction +================ +*/ +void idPhysics_RigidBody::SetFriction( const float linear, const float angular, const float contact ) { + if ( linear < 0.0f || + angular < 0.0f || angular > 1.0f || + contact < 0.0f || contact > 1.0f ) { + return; + } + linearFriction = linear; + angularFriction = angular; + contactFriction = contact; +} + +/* +================ +idPhysics_RigidBody::SetBouncyness +================ +*/ +void idPhysics_RigidBody::SetBouncyness( const float b ) { + if ( b < 0.0f || b > 1.0f ) { + return; + } + bouncyness = b; +} + +/* +================ +idPhysics_RigidBody::Rest +================ +*/ +void idPhysics_RigidBody::Rest( void ) +{ + current.atRest = gameLocal.time; + current.i.linearMomentum.Zero(); + current.i.angularMomentum.Zero(); + self->BecomeInactive( TH_PHYSICS ); + + // grayman #2908 - if this is a mine, we can't NULL m_SetInMotionByActor + // because we need that if the mine ever kills someone + + if ( self->IsType(idProjectile::Type) ) + { + idProjectile* proj = static_cast(self); + if ( !proj->IsMine() ) + { + self->m_SetInMotionByActor = NULL; + } + } + +// self->m_SetInMotionByActor = NULL; + self->m_droppedByAI = false; // grayman #1330 +} + +/* +================ +idPhysics_RigidBody::DropToFloor +================ +*/ +void idPhysics_RigidBody::DropToFloor( void ) { + dropToFloor = true; + testSolid = true; +} + +/* +================ +idPhysics_RigidBody::NoContact +================ +*/ +void idPhysics_RigidBody::NoContact( void ) { + noContact = true; +} + +/* +================ +idPhysics_RigidBody::Activate +================ +*/ +void idPhysics_RigidBody::Activate( void ) { + current.atRest = -1; + self->BecomeActive( TH_PHYSICS ); +} + +/* +================ +idPhysics_RigidBody::PutToRest + + put to rest untill something collides with this physics object +================ +*/ +void idPhysics_RigidBody::PutToRest( void ) { + Rest(); +} + +/* +================ +idPhysics_RigidBody::EnableImpact +================ +*/ +void idPhysics_RigidBody::EnableImpact( void ) { + noImpact = false; +} + +/* +================ +idPhysics_RigidBody::DisableImpact +================ +*/ +void idPhysics_RigidBody::DisableImpact( void ) { + noImpact = true; +} + +/* +================ +idPhysics_RigidBody::SetContents +================ +*/ +void idPhysics_RigidBody::SetContents( int contents, int id ) { + assert(clipModel != NULL); + clipModel->SetContents( contents ); +} + +/* +================ +idPhysics_RigidBody::GetContents +================ +*/ +int idPhysics_RigidBody::GetContents( int id ) const { + assert(clipModel != NULL); + return clipModel->GetContents(); +} + +/* +================ +idPhysics_RigidBody::GetBounds +================ +*/ +const idBounds &idPhysics_RigidBody::GetBounds( int id ) const { + assert(clipModel != NULL); + return clipModel->GetBounds(); +} + +/* +================ +idPhysics_RigidBody::GetAbsBounds +================ +*/ +const idBounds &idPhysics_RigidBody::GetAbsBounds( int id ) const { + assert(clipModel != NULL); + return clipModel->GetAbsBounds(); +} + +const trace_t* idPhysics_RigidBody::GetBlockingInfo() const +{ + return isBlocked ? &collisionTrace : NULL; +} + +idEntity* idPhysics_RigidBody::GetBlockingEntity() const +{ + return isBlocked ? gameLocal.entities[collisionTrace.c.entityNum] : NULL; +} + +/* +================ +idPhysics_RigidBody::Evaluate + + Evaluate the impulse based rigid body physics. + When a collision occurs an impulse is applied at the moment of impact but + the remaining time after the collision is ignored. +================ +*/ +bool idPhysics_RigidBody::Evaluate( int timeStepMSec, int endTimeMSec ) { + rigidBodyPState_t next; + idAngles angles; + trace_t collision; + idVec3 impulse; + idEntity *ent(NULL); + idVec3 oldOrigin, masterOrigin; + idMat3 oldAxis, masterAxis; + float timeStep; + bool collided = false; + bool cameToRest = false; + + // greebo: For now, we aren't blocked + isBlocked = false; + + timeStep = MS2SEC( timeStepMSec ); + current.lastTimeStep = timeStep; + + if ( hasMaster ) { + oldOrigin = current.i.position; + oldAxis = current.i.orientation; + self->GetMasterPosition( masterOrigin, masterAxis ); + + current.i.position = masterOrigin + current.localOrigin * masterAxis; + current.i.orientation = (isOrientated) ? current.localAxis * masterAxis : current.localAxis; + + // greebo: Only check for collisions for "solid" bind slaves and if the master is non-AF + // Ishtvan: Do not block an AF attachment that is itself attached to an AF. + // This causes problems with AF evaluation. + // TODO: Use advanced AF binding code to add AF body for entity in this case, as if it were bound directly to AF + if ( + (clipModel->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) + && !self->GetBindMaster()->IsType(idAnimatedEntity::Type) + && !( + self->GetBindMaster()->IsType(idAFAttachment::Type) + && static_cast(self->GetBindMaster())->GetBody() + ) + ) + { + // For non-AF masters we check for collisions + gameLocal.push.ClipPush( collisionTrace, self, PUSHFL_CLIP|PUSHFL_APPLYIMPULSE, oldOrigin, oldAxis, current.i.position, current.i.orientation ); + + if (collisionTrace.fraction < 1.0f ) + { + clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis ); + current.i.position = oldOrigin; + current.i.orientation = oldAxis; + isBlocked = true; + return false; + } + } + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); + current.i.linearMomentum = mass * ( ( current.i.position - oldOrigin ) / timeStep ); + current.i.angularMomentum = inertiaTensor * ( ( current.i.orientation * oldAxis.Transpose() ).ToAngularVelocity() / timeStep ); + current.externalForce.Zero(); + current.externalTorque.Zero(); + + return ( current.i.position != oldOrigin || current.i.orientation != oldAxis ); + } + + // if the body is at rest + if ( current.atRest >= 0 || timeStep <= 0.0f ) { + DebugDraw(); + return false; + } + + // if putting the body to rest + if (dropToFloor && !self->m_droppedByAI) // grayman #1330 - only go straight to the floor if an AI didn't drop it + { + DropToFloorAndRest(); + current.externalForce.Zero(); + current.externalTorque.Zero(); + return true; + } + +#ifdef RB_TIMINGS + timer_total.Start(); +#endif + + // move the rigid body velocity into the frame of a pusher +// current.i.linearMomentum -= current.pushVelocity.SubVec3( 0 ) * mass; +// current.i.angularMomentum -= current.pushVelocity.SubVec3( 1 ) * inertiaTensor; + + clipModel->Unlink(); + + next = current; + + // calculate next position and orientation + Integrate( timeStep, next ); + +#ifdef RB_TIMINGS + timer_collision.Start(); +#endif + + // check for collisions from the current to the next state + collided = CheckForCollisions( timeStep, next, collision ); + +#ifdef RB_TIMINGS + timer_collision.Stop(); +#endif + + // set the new state + current = next; + + if ( collided ) { + // apply collision impulse + if ( CollisionImpulse( collision, impulse ) ) { + current.atRest = gameLocal.time; + } + } + + // update the position of the clip model + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); + + DebugDraw(); + + if ( !noContact ) { + +#ifdef RB_TIMINGS + timer_collision.Start(); +#endif + // get contacts + EvaluateContacts(); + +#ifdef RB_TIMINGS + timer_collision.Stop(); +#endif + + // check if the body has come to rest + if ( current.externalForce.LengthSqr() == 0.0f && TestIfAtRest() ) { + // put to rest + Rest(); + cameToRest = true; + } else { + // apply contact friction + ContactFriction( timeStep ); + } + } + + if ( current.atRest < 0 ) { + ActivateContactEntities(); + } + + if ( collided ) { + // if the rigid body didn't come to rest or the other entity is not at rest + ent = gameLocal.entities[collision.c.entityNum]; + if ( ent && ( !cameToRest || !ent->IsAtRest() ) ) { + // apply impact to other entity + ent->ApplyImpulse( self, collision.c.id, collision.c.point, -impulse ); + + if (ent->m_SetInMotionByActor.GetEntity() == NULL) + { + ent->m_SetInMotionByActor = self->m_SetInMotionByActor; + ent->m_MovedByActor = self->m_MovedByActor; + } + } + + // greebo: Are we stuck? We still have to consider gravity and external forces + if (collision.fraction <= 0.001f) + { + // Get the mass center in world coordinates + idVec3 massCenter(current.i.position + centerOfMass * current.i.orientation); + + // Calculate the lever arms + idVec3 arm1(current.externalForcePoint - massCenter); + idVec3 arm2(current.externalForcePoint - collision.c.point); + idVec3 arm1N(arm1); + + //gameRenderWorld->DebugArrow(colorCyan, massCenter, massCenter + arm1, 1, 20); + //gameRenderWorld->DebugArrow(colorMagenta, collision.c.point, collision.c.point + arm2, 1, 20); + + float l1 = arm1N.NormalizeFast(); + float l2 = arm1N * arm2; + //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Arm 1: %f, Arm2: %f\r", l1, l2); + + if (arm2.LengthFast() > l1) + { + // Apply the linear momentum caused by the external force + current.i.linearMomentum -= current.externalForce*2; + current.i.angularMomentum += (current.externalForcePoint - collision.c.point).Cross(current.externalForce); + } + else if (fabs(l1) > 0.01f) + { + float armRatio = l2/l1; + float forceFactor = 4*armRatio*(armRatio - 1); + + forceFactor *= 15; + idVec3 leverForceLinear = current.externalForce * forceFactor; + + //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("forceFactor: %f\r", forceFactor); + //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Current impulse", current.i.linearMomentum); + //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("External Force", current.externalForce); + //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("External Force Modified", current.externalForce*forceFactor); + //gameRenderWorld->DebugArrow(colorMdGrey, massCenter, massCenter + leverForceLinear, 1, 20); + + // Apply the linear momentum caused by the lever force + current.i.linearMomentum += leverForceLinear; + current.i.angularMomentum += (current.externalForcePoint - collision.c.point).Cross(current.externalForce); + } + } + } + + // move the rigid body velocity back into the world frame +// current.i.linearMomentum += current.pushVelocity.SubVec3( 0 ) * mass; +// current.i.angularMomentum += current.pushVelocity.SubVec3( 1 ) * inertiaTensor; + current.pushVelocity.Zero(); + + current.lastTimeStep = timeStep; + current.externalForce.Zero(); + current.externalForcePoint.Zero(); + current.externalTorque.Zero(); + + if ( IsOutsideWorld() ) { + gameLocal.Warning( "rigid body moved outside world bounds for entity '%s' type '%s' at (%s)", + self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); + Rest(); + } + +#ifdef RB_TIMINGS + timer_total.Stop(); + + if ( rb_showTimings->integer == 1 ) { + gameLocal.Printf( "%12s: t %1.4f cd %1.4f\n", + self->name.c_str(), + timer_total.Milliseconds(), timer_collision.Milliseconds() ); + lastTimerReset = 0; + } + else if ( rb_showTimings->integer == 2 ) { + numRigidBodies++; + if ( endTimeMSec > lastTimerReset ) { + gameLocal.Printf( "rb %d: t %1.4f cd %1.4f\n", + numRigidBodies, + timer_total.Milliseconds(), timer_collision.Milliseconds() ); + } + } + if ( endTimeMSec > lastTimerReset ) { + lastTimerReset = endTimeMSec; + numRigidBodies = 0; + timer_total.Clear(); + timer_collision.Clear(); + } +#endif + + if (cv_phys_show_momentum.GetBool()) + { + gameRenderWorld->DrawText( idStr(current.i.linearMomentum.LengthFast()), GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + } + + return true; // grayman #2478 +} + +/* +================ +idPhysics_RigidBody::UpdateTime +================ +*/ +void idPhysics_RigidBody::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_RigidBody::GetTime +================ +*/ +int idPhysics_RigidBody::GetTime( void ) const { + return gameLocal.time; +} + +/* +================ +idPhysics_RigidBody::GetImpactInfo +================ +*/ +void idPhysics_RigidBody::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + idVec3 linearVelocity, angularVelocity; + idMat3 inverseWorldInertiaTensor; + + linearVelocity = inverseMass * current.i.linearMomentum; + inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; + angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; + + info->invMass = inverseMass; + info->invInertiaTensor = inverseWorldInertiaTensor; + info->position = point - ( current.i.position + centerOfMass * current.i.orientation ); + info->velocity = linearVelocity + angularVelocity.Cross( info->position ); +} + +/* +================ +idPhysics_RigidBody::ApplyImpulse +================ +*/ +void idPhysics_RigidBody::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + if ( noImpact ) + { + return; + } + + // tels: check that the impulse does not exceed the max values + // FIXME: the comparisation here is just a dummy + if ((maxForce.x > 0) && + ((fabs(impulse.x) > maxForce.x) || + (fabs(impulse.y) > maxForce.y) || + (fabs(impulse.z) > maxForce.z)) ) + { + DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("impulse (%f %f %f) > maxForce (%f %f %f) for entity %s\r\r", + impulse.x, impulse.y, impulse.z, + maxForce.x, maxForce.y, maxForce.z, + self->name.c_str() + ); + // FIXME: self needs to be replaced by whatever entity generated the impulse + self->Killed( gameLocal.world, gameLocal.world, 0, self->GetLocalCoordinates(GetOrigin()), 0); + return; + } + + // greebo: Check if we have a master - if yes, propagate the impulse to it + if ( hasMaster ) + { + idEntity* master = self->GetBindMaster(); + + assert(master != NULL); // Bind master must not be null + + master->GetPhysics()->ApplyImpulse(id, point, impulse); + } + + current.i.linearMomentum += impulse; + current.i.angularMomentum += ( point - ( current.i.position + centerOfMass * current.i.orientation ) ).Cross( impulse ); + Activate(); +} + +/* +================ +idPhysics_RigidBody::AddForce +================ +*/ +void idPhysics_RigidBody::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { + if ( noImpact ) { + return; + } + current.externalForcePoint = point; + current.externalForce += force; + current.externalTorque += ( point - ( current.i.position + centerOfMass * current.i.orientation ) ).Cross( force ); + Activate(); +} + +/* +================ +idPhysics_RigidBody::IsAtRest +================ +*/ +bool idPhysics_RigidBody::IsAtRest( void ) const { + return current.atRest >= 0; +} + +/* +================ +idPhysics_RigidBody::GetRestStartTime +================ +*/ +int idPhysics_RigidBody::GetRestStartTime( void ) const { + return current.atRest; +} + +/* +================ +idPhysics_RigidBody::IsPushable +================ +*/ +bool idPhysics_RigidBody::IsPushable( void ) const { + return ( !noImpact && !hasMaster ); +} + +/* +================ +idPhysics_RigidBody::SaveState +================ +*/ +void idPhysics_RigidBody::SaveState( void ) { + saved = current; +} + +/* +================ +idPhysics_RigidBody::RestoreState +================ +*/ +void idPhysics_RigidBody::RestoreState( void ) { + current = saved; + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); + + EvaluateContacts(); +} + +/* +================ +idPhysics::SetOrigin +================ +*/ +void idPhysics_RigidBody::SetOrigin( const idVec3 &newOrigin, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localOrigin = newOrigin; + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.i.position = masterOrigin + newOrigin * masterAxis; + } + else { + current.i.position = newOrigin; + } + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, clipModel->GetAxis() ); + + Activate(); +} + +/* +================ +idPhysics::SetAxis +================ +*/ +void idPhysics_RigidBody::SetAxis( const idMat3 &newAxis, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localAxis = newAxis; + if ( hasMaster && isOrientated ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.i.orientation = newAxis * masterAxis; + } + else { + current.i.orientation = newAxis; + } + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), clipModel->GetOrigin(), current.i.orientation ); + + Activate(); +} + +/* +================ +idPhysics::Move +================ +*/ +void idPhysics_RigidBody::Translate( const idVec3 &translation, int id ) { + + current.localOrigin += translation; + current.i.position += translation; + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, clipModel->GetAxis() ); + + Activate(); +} + +/* +================ +idPhysics::Rotate +================ +*/ +void idPhysics_RigidBody::Rotate( const idRotation &rotation, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.i.orientation *= rotation.ToMat3(); + current.i.position *= rotation; + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localAxis *= rotation.ToMat3(); + current.localOrigin = ( current.i.position - masterOrigin ) * masterAxis.Transpose(); + } + else { + current.localAxis = current.i.orientation; + current.localOrigin = current.i.position; + } + + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); + + Activate(); +} + +/* +================ +idPhysics_RigidBody::GetOrigin +================ +*/ +const idVec3 &idPhysics_RigidBody::GetOrigin( int id ) const { + return current.i.position; +} + +/* +================ +idPhysics_RigidBody::GetAxis +================ +*/ +const idMat3 &idPhysics_RigidBody::GetAxis( int id ) const { + return current.i.orientation; +} + +/* +================ +idPhysics_RigidBody::SetLinearVelocity +================ +*/ +void idPhysics_RigidBody::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { + current.i.linearMomentum = newLinearVelocity * mass; + Activate(); +} + +/* +================ +idPhysics_RigidBody::SetAngularVelocity +================ +*/ +void idPhysics_RigidBody::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { + current.i.angularMomentum = newAngularVelocity * current.i.orientation.Transpose() * inertiaTensor * current.i.orientation; + Activate(); +} + +/* +================ +idPhysics_RigidBody::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_RigidBody::GetLinearVelocity( int id ) const { + static idVec3 curLinearVelocity; + curLinearVelocity = current.i.linearMomentum * inverseMass; + return curLinearVelocity; +} + +/* +================ +idPhysics_RigidBody::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_RigidBody::GetAngularVelocity( int id ) const { + static idVec3 curAngularVelocity; + idMat3 inverseWorldInertiaTensor; + + inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; + curAngularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; + return curAngularVelocity; +} + +/* +================ +idPhysics_RigidBody::SetMaxForce +================ +*/ +void idPhysics_RigidBody::SetMaxForce( const idVec3 &newMaxForce ) { + maxForce = newMaxForce; +} + +/* +================ +idPhysics_RigidBody::SetMaxTorque +================ +*/ +void idPhysics_RigidBody::SetMaxTorque( const idVec3 &newMaxTorque ) { + maxTorque = newMaxTorque; +} + +/* +================ +idPhysics_RigidBody::GetMaxForce +================ +*/ +const idVec3 &idPhysics_RigidBody::GetMaxForce( void ) const { + return maxForce; +} + +/* +================ +idPhysics_RigidBody::GetMaxTorque +================ +*/ +const idVec3 &idPhysics_RigidBody::GetMaxTorque( void ) const { + return maxTorque; +} + +/* +================ +idPhysics_RigidBody::ClipTranslation +================ +*/ +void idPhysics_RigidBody::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, + clipModel, clipModel->GetAxis(), clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, + clipModel, clipModel->GetAxis(), clipMask, self ); + } +} + +/* +================ +idPhysics_RigidBody::ClipRotation +================ +*/ +void idPhysics_RigidBody::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation, + clipModel, clipModel->GetAxis(), clipMask, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, + clipModel, clipModel->GetAxis(), clipMask, self ); + } +} + +/* +================ +idPhysics_RigidBody::ClipContents +================ +*/ +int idPhysics_RigidBody::ClipContents( const idClipModel *model ) const { + if ( model ) { + return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } + else { + return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); + } +} + +/* +================ +idPhysics_RigidBody::DisableClip +================ +*/ +void idPhysics_RigidBody::DisableClip( void ) { + clipModel->Disable(); +} + +/* +================ +idPhysics_RigidBody::EnableClip +================ +*/ +void idPhysics_RigidBody::EnableClip( void ) { + clipModel->Enable(); +} + +/* +================ +idPhysics_RigidBody::UnlinkClip +================ +*/ +void idPhysics_RigidBody::UnlinkClip( void ) { + clipModel->Unlink(); +} + +/* +================ +idPhysics_RigidBody::LinkClip +================ +*/ +void idPhysics_RigidBody::LinkClip( void ) { + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); +} + +/* +================ +idPhysics_RigidBody::EvaluateContacts +================ +*/ +bool idPhysics_RigidBody::EvaluateContacts( void ) { + idVec6 dir; + int num; + + ClearContacts(); + + contacts.SetNum( 10, false ); + + dir.SubVec3(0) = current.i.linearMomentum + current.lastTimeStep * gravityVector * mass; + dir.SubVec3(1) = current.i.angularMomentum; + dir.SubVec3(0).Normalize(); + dir.SubVec3(1).Normalize(); + num = gameLocal.clip.Contacts( &contacts[0], 10, clipModel->GetOrigin(), + dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self ); + contacts.SetNum( num, false ); + + AddContactEntitiesForContacts(); + + return ( contacts.Num() != 0 ); +} + +/* +================ +idPhysics_RigidBody::SetPushed +================ +*/ +void idPhysics_RigidBody::SetPushed( int deltaTime ) { + idRotation rotation; + + rotation = ( saved.i.orientation * current.i.orientation ).ToRotation(); + + // velocity with which the af is pushed + current.pushVelocity.SubVec3(0) += ( current.i.position - saved.i.position ) / ( deltaTime * idMath::M_MS2SEC ); + current.pushVelocity.SubVec3(1) += rotation.GetVec() * -DEG2RAD( rotation.GetAngle() ) / ( deltaTime * idMath::M_MS2SEC ); +} + +/* +================ +idPhysics_RigidBody::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_RigidBody::GetPushedLinearVelocity( const int id ) const { + return current.pushVelocity.SubVec3(0); +} + +/* +================ +idPhysics_RigidBody::GetPushedAngularVelocity +================ +*/ +const idVec3 &idPhysics_RigidBody::GetPushedAngularVelocity( const int id ) const { + return current.pushVelocity.SubVec3(1); +} + +/* +================ +idPhysics_RigidBody::SetMaster +================ +*/ +void idPhysics_RigidBody::SetMaster( idEntity *master, const bool orientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !hasMaster ) { + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.i.position - masterOrigin ) * masterAxis.Transpose(); + if ( orientated ) { + current.localAxis = current.i.orientation * masterAxis.Transpose(); + } + else { + current.localAxis = current.i.orientation; + } + hasMaster = true; + isOrientated = orientated; + ClearContacts(); + } + } + else { + if ( hasMaster ) { + hasMaster = false; + Activate(); + } + } +} + +/* +================ +idPhysics_RigidBody::WriteToSnapshot +================ +*/ +void idPhysics_RigidBody::WriteToSnapshot( idBitMsgDelta &msg ) const { + idCQuat quat, localQuat; + + quat = current.i.orientation.ToCQuat(); + localQuat = current.localAxis.ToCQuat(); + + msg.WriteLong( current.atRest ); + msg.WriteFloat( current.i.position[0] ); + msg.WriteFloat( current.i.position[1] ); + msg.WriteFloat( current.i.position[2] ); + msg.WriteFloat( quat.x ); + msg.WriteFloat( quat.y ); + msg.WriteFloat( quat.z ); + msg.WriteFloat( current.i.linearMomentum[0], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteFloat( current.i.linearMomentum[1], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteFloat( current.i.linearMomentum[2], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteFloat( current.i.angularMomentum[0], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteFloat( current.i.angularMomentum[1], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteFloat( current.i.angularMomentum[2], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + msg.WriteDeltaFloat( current.i.position[0], current.localOrigin[0] ); + msg.WriteDeltaFloat( current.i.position[1], current.localOrigin[1] ); + msg.WriteDeltaFloat( current.i.position[2], current.localOrigin[2] ); + msg.WriteDeltaFloat( quat.x, localQuat.x ); + msg.WriteDeltaFloat( quat.y, localQuat.y ); + msg.WriteDeltaFloat( quat.z, localQuat.z ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalForce[0], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalForce[1], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalForce[2], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalTorque[0], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalTorque[1], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + msg.WriteDeltaFloat( 0.0f, current.externalTorque[2], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); +} + +/* +================ +idPhysics_RigidBody::ReadFromSnapshot +================ +*/ +void idPhysics_RigidBody::ReadFromSnapshot( const idBitMsgDelta &msg ) { + idCQuat quat, localQuat; + + current.atRest = msg.ReadLong(); + current.i.position[0] = msg.ReadFloat(); + current.i.position[1] = msg.ReadFloat(); + current.i.position[2] = msg.ReadFloat(); + quat.x = msg.ReadFloat(); + quat.y = msg.ReadFloat(); + quat.z = msg.ReadFloat(); + current.i.linearMomentum[0] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.i.linearMomentum[1] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.i.linearMomentum[2] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.i.angularMomentum[0] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.i.angularMomentum[1] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.i.angularMomentum[2] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); + current.localOrigin[0] = msg.ReadDeltaFloat( current.i.position[0] ); + current.localOrigin[1] = msg.ReadDeltaFloat( current.i.position[1] ); + current.localOrigin[2] = msg.ReadDeltaFloat( current.i.position[2] ); + localQuat.x = msg.ReadDeltaFloat( quat.x ); + localQuat.y = msg.ReadDeltaFloat( quat.y ); + localQuat.z = msg.ReadDeltaFloat( quat.z ); + current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); + current.externalForce[0] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + current.externalForce[1] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + current.externalForce[2] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + current.externalTorque[0] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + current.externalTorque[1] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + current.externalTorque[2] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); + + current.i.orientation = quat.ToMat3(); + current.localAxis = localQuat.ToMat3(); + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); + } +} diff --git a/game/physics/Physics_RigidBody.h b/game/physics/Physics_RigidBody.h new file mode 100644 index 000000000..03f8d47cb --- /dev/null +++ b/game/physics/Physics_RigidBody.h @@ -0,0 +1,244 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_RIGIDBODY_H__ +#define __PHYSICS_RIGIDBODY_H__ + +/* +=================================================================================== + + Rigid body physics + + Employs an impulse based dynamic simulation which is not very accurate but + relatively fast and still reliable due to the continuous collision detection. + +=================================================================================== +*/ + +typedef struct rididBodyIState_s { + idVec3 position; // position of trace model + idMat3 orientation; // orientation of trace model + idVec3 linearMomentum; // translational momentum relative to center of mass + idVec3 angularMomentum; // rotational momentum relative to center of mass +} rigidBodyIState_t; + +typedef struct rigidBodyPState_s { + int atRest; // set when simulation is suspended + float lastTimeStep; // length of last time step + idVec3 localOrigin; // origin relative to master + idMat3 localAxis; // axis relative to master + idVec6 pushVelocity; // push velocity + idVec3 externalForce; // external force relative to center of mass + idVec3 externalTorque; // external torque relative to center of mass + idVec3 externalForcePoint; // point where the externalForce is being applied at + rigidBodyIState_t i; // state used for integration +} rigidBodyPState_t; + +class idPhysics_RigidBody : public idPhysics_Base { + +public: + + CLASS_PROTOTYPE( idPhysics_RigidBody ); + + idPhysics_RigidBody( void ); + ~idPhysics_RigidBody( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + // initialisation + void SetFriction( const float linear, const float angular, const float contact ); + void SetBouncyness( const float b ); + // same as above but drop to the floor first + void DropToFloor( void ); + // no contact determination and contact friction + void NoContact( void ); + // enable/disable activation by impact + void EnableImpact( void ); + void DisableImpact( void ); + +public: // common physics interface + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + + /** + * greebo: This is similar to ApplyImpulse, although this distributes the impulse + * on all entities in contact with this one in *this* very frame. If + * no entities are in contact, all the impulse gets applied to this one. + */ + bool PropagateImpulse(const int id, const idVec3& point, const idVec3& impulse); + + void AddForce( const int id, const idVec3 &point, const idVec3 &force ); + void Activate( void ); + void PutToRest( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + // tels: force and torque that make entitiy "break down" when exceeded + void SetMaxForce( const idVec3 &newMaxForce ); + void SetMaxTorque( const idVec3 &newMaxTorque ); + + const idVec3 & GetMaxForce( void ) const; + const idVec3 & GetMaxTorque( void ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + /** + * greebo: Override empty default implementation of idPhysics_Base::GetBlockingEntity(). + */ + virtual const trace_t* GetBlockingInfo( void ) const; + virtual idEntity * GetBlockingEntity( void ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated ); + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +public: + /** + * greebo: "Accessor" method to the internal state. This is a bit hacky, I admit. + */ + rigidBodyPState_t& State() { return current; } + +private: + // state of the rigid body + rigidBodyPState_t current; + rigidBodyPState_t saved; + + // rigid body properties + float linearFriction; // translational friction + float angularFriction; // rotational friction + float contactFriction; // friction with contact surfaces + float bouncyness; // bouncyness +#ifdef MOD_WATERPHYSICS + float volume; // MOD_WATERPHYSICS object volume +#endif // MOD_WATERPHYSICS + idClipModel * clipModel; // clip model used for collision detection + + // tels: if the applied impulse/torque exceeds these values, the entity breaks down + idVec3 maxForce; // spawnarg "max_force" + idVec3 maxTorque; // spawnarg "max_torque" + + // derived properties + float mass; // mass of body + float inverseMass; // 1 / mass + idVec3 centerOfMass; // center of mass of trace model + idMat3 inertiaTensor; // mass distribution + idMat3 inverseInertiaTensor; // inverse inertia tensor + + idODE * integrator; // integrator + bool dropToFloor; // true if dropping to the floor and putting to rest + bool testSolid; // true if testing for solid when dropping to the floor + bool noImpact; // if true do not activate when another object collides + bool noContact; // if true do not determine contacts and no contact friction + + // master + bool hasMaster; + bool isOrientated; + + /** + * greebo: This saved the collision information when this object is in "bind slave mode". + */ + trace_t collisionTrace; + bool isBlocked; + + bool propagateImpulseLock; + +#ifdef MOD_WATERPHYSICS + // buoyancy + int noMoveTime; // MOD_WATERPHYSICS suspend simulation if hardly any movement for this many seconds +#endif + +private: + friend void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives ); + void Integrate( const float deltaTime, rigidBodyPState_t &next ); + bool CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision ); +public: + bool CollisionImpulse( const trace_t &collision, idVec3 &impulse ); +private: + void ContactFriction( float deltaTime ); + void DropToFloorAndRest( void ); +#ifdef MOD_WATERPHYSICS + bool TestIfAtRest( void ); +#else // MOD_WATERPHYSICS + bool TestIfAtRest( void ) const; +#endif // MOD_WATERPHYSICS + void Rest( void ); + void DebugDraw( void ); + +#ifdef MOD_WATERPHYSICS + // Buoyancy stuff + // Approximates the center of mass of the submerged portion of the rigid body. + virtual bool GetBuoyancy( const idVec3 &pos, const idMat3 &rotation, idVec3 &bCenter, float &percent ) const; // MOD_WATERPHYSICS + // Returns rough a percentage of which percent of the body is in water. + virtual float GetSubmergedPercent( const idVec3 &pos, const idMat3 &rotation ) const; // MOD_WATERPHYSICS +#endif +}; + +#endif /* !__PHYSICS_RIGIDBODY_H__ */ diff --git a/game/physics/Physics_Static.cpp b/game/physics/Physics_Static.cpp new file mode 100644 index 000000000..8e672207a --- /dev/null +++ b/game/physics/Physics_Static.cpp @@ -0,0 +1,843 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics, idPhysics_Static ) +END_CLASS + +/* +================ +idPhysics_Static::idPhysics_Static +================ +*/ +idPhysics_Static::idPhysics_Static( void ) { + self = NULL; + clipModel = NULL; + current.origin.Zero(); + current.axis.Identity(); + current.localOrigin.Zero(); + current.localAxis.Identity(); + hasMaster = false; + isOrientated = false; +} + +/* +================ +idPhysics_Static::~idPhysics_Static +================ +*/ +idPhysics_Static::~idPhysics_Static( void ) { + if ( self && self->GetPhysics() == this ) { + self->SetPhysics( NULL ); + } + idForce::DeletePhysics( this ); + if ( clipModel ) { + delete clipModel; + } +} + +/* +================ +idPhysics_Static::Save +================ +*/ +void idPhysics_Static::Save( idSaveGame *savefile ) const { + savefile->WriteObject( self ); + + savefile->WriteVec3( current.origin ); + savefile->WriteMat3( current.axis ); + savefile->WriteVec3( current.localOrigin ); + savefile->WriteMat3( current.localAxis ); + savefile->WriteClipModel( clipModel ); + + savefile->WriteBool( hasMaster ); + savefile->WriteBool( isOrientated ); +} + +/* +================ +idPhysics_Static::Restore +================ +*/ +void idPhysics_Static::Restore( idRestoreGame *savefile ) { + savefile->ReadObject( reinterpret_cast( self ) ); + + savefile->ReadVec3( current.origin ); + savefile->ReadMat3( current.axis ); + savefile->ReadVec3( current.localOrigin ); + savefile->ReadMat3( current.localAxis ); + savefile->ReadClipModel( clipModel ); + + savefile->ReadBool( hasMaster ); + savefile->ReadBool( isOrientated ); +} + +/* +================ +idPhysics_Static::SetSelf +================ +*/ +void idPhysics_Static::SetSelf( idEntity *e ) { + assert( e ); + self = e; +} + +/* +================ +idPhysics_Static::SetClipModel +================ +*/ +void idPhysics_Static::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { + assert( self ); + + if ( clipModel && clipModel != model && freeOld ) { + delete clipModel; + } + clipModel = model; + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::GetClipModel +================ +*/ +idClipModel *idPhysics_Static::GetClipModel( int id ) const { + if ( clipModel ) { + return clipModel; + } + return gameLocal.clip.DefaultClipModel(); +} + +/* +================ +idPhysics_Static::GetNumClipModels +================ +*/ +int idPhysics_Static::GetNumClipModels( void ) const { + return ( clipModel != NULL ); +} + +/* +================ +idPhysics_Static::SetMass +================ +*/ +void idPhysics_Static::SetMass( float mass, int id ) { +} + +/* +================ +idPhysics_Static::GetMass +================ +*/ +float idPhysics_Static::GetMass( int id ) const { + return 0.0f; +} + +/* +================ +idPhysics_Static::SetContents +================ +*/ +void idPhysics_Static::SetContents( int contents, int id ) { + if ( clipModel ) { + clipModel->SetContents( contents ); + } +} + +/* +================ +idPhysics_Static::GetContents +================ +*/ +int idPhysics_Static::GetContents( int id ) const { + if ( clipModel ) { + return clipModel->GetContents(); + } + return 0; +} + +/* +================ +idPhysics_Static::SetClipMask +================ +*/ +void idPhysics_Static::SetClipMask( int mask, int id ) { +} + +/* +================ +idPhysics_Static::GetClipMask +================ +*/ +int idPhysics_Static::GetClipMask( int id ) const { + return 0; +} + +/* +================ +idPhysics_Static::GetBounds +================ +*/ +const idBounds &idPhysics_Static::GetBounds( int id ) const { + if ( clipModel ) { + return clipModel->GetBounds(); + } + return bounds_zero; +} + +/* +================ +idPhysics_Static::GetAbsBounds +================ +*/ +const idBounds &idPhysics_Static::GetAbsBounds( int id ) const { + static idBounds absBounds; + + if ( clipModel ) { + return clipModel->GetAbsBounds(); + } + absBounds[0] = absBounds[1] = current.origin; + return absBounds; +} + +/* +================ +idPhysics_Static::Evaluate +================ +*/ +bool idPhysics_Static::Evaluate( int timeStepMSec, int endTimeMSec ) { + idVec3 masterOrigin, oldOrigin; + idMat3 masterAxis, oldAxis; + + + if ( hasMaster ) { + oldOrigin = current.origin; + oldAxis = current.axis; + + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + current.localOrigin * masterAxis; + if ( isOrientated ) { + current.axis = current.localAxis * masterAxis; + } else { + current.axis = current.localAxis; + } + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } + + return ( current.origin != oldOrigin || current.axis != oldAxis ); + } + return false; +} + +/* +================ +idPhysics_Static::UpdateTime +================ +*/ +void idPhysics_Static::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_Static::GetTime +================ +*/ +int idPhysics_Static::GetTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Static::GetImpactInfo +================ +*/ +void idPhysics_Static::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + memset( info, 0, sizeof( *info ) ); +} + +/* +================ +idPhysics_Static::ApplyImpulse +================ +*/ +void idPhysics_Static::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { +} + +bool idPhysics_Static::PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + return false; +} + +/* +================ +idPhysics_Static::AddForce +================ +*/ +void idPhysics_Static::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { +} + +/* +================ +idPhysics_Static::Activate +================ +*/ +void idPhysics_Static::Activate( void ) { +} + +/* +================ +idPhysics_Static::PutToRest +================ +*/ +void idPhysics_Static::PutToRest( void ) { +} + +/* +================ +idPhysics_Static::IsAtRest +================ +*/ +bool idPhysics_Static::IsAtRest( void ) const { + return true; +} + +/* +================ +idPhysics_Static::GetRestStartTime +================ +*/ +int idPhysics_Static::GetRestStartTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Static::IsPushable +================ +*/ +bool idPhysics_Static::IsPushable( void ) const { + return false; +} + +/* +================ +idPhysics_Static::SaveState +================ +*/ +void idPhysics_Static::SaveState( void ) { +} + +/* +================ +idPhysics_Static::RestoreState +================ +*/ +void idPhysics_Static::RestoreState( void ) { +} + +/* +================ +idPhysics_Static::SetOrigin +================ +*/ +void idPhysics_Static::SetOrigin( const idVec3 &newOrigin, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localOrigin = newOrigin; + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.origin = masterOrigin + newOrigin * masterAxis; + } else { + current.origin = newOrigin; + } + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::SetAxis +================ +*/ +void idPhysics_Static::SetAxis( const idMat3 &newAxis, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.localAxis = newAxis; + + if ( hasMaster && isOrientated ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.axis = newAxis * masterAxis; + } else { + current.axis = newAxis; + } + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::Translate +================ +*/ +void idPhysics_Static::Translate( const idVec3 &translation, int id ) { + current.localOrigin += translation; + current.origin += translation; + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::Rotate +================ +*/ +void idPhysics_Static::Rotate( const idRotation &rotation, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + current.origin *= rotation; + current.axis *= rotation.ToMat3(); + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localAxis *= rotation.ToMat3(); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + } else { + current.localAxis = current.axis; + current.localOrigin = current.origin; + } + + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::GetOrigin +================ +*/ +const idVec3 &idPhysics_Static::GetOrigin( int id ) const { + return current.origin; +} + +/* +================ +idPhysics_Static::GetAxis +================ +*/ +const idMat3 &idPhysics_Static::GetAxis( int id ) const { + return current.axis; +} + +/* +================ +idPhysics_Static::SetLinearVelocity +================ +*/ +void idPhysics_Static::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { +} + +/* +================ +idPhysics_Static::SetAngularVelocity +================ +*/ +void idPhysics_Static::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { +} + +/* +================ +idPhysics_Static::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_Static::GetLinearVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Static::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_Static::GetAngularVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Static::SetGravity +================ +*/ +void idPhysics_Static::SetGravity( const idVec3 &newGravity ) { +} + +/* +================ +idPhysics_Static::GetGravity +================ +*/ +const idVec3 &idPhysics_Static::GetGravity( void ) const { + static idVec3 gravity( 0, 0, -g_gravity.GetFloat() ); + return gravity; +} + +/* +================ +idPhysics_Static::GetGravityNormal +================ +*/ +const idVec3 &idPhysics_Static::GetGravityNormal( void ) const { + static idVec3 gravity( 0, 0, -1 ); + return gravity; +} + +/* +================ +idPhysics_Static::ClipTranslation +================ +*/ +void idPhysics_Static::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.TranslationModel( results, current.origin, current.origin + translation, + clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() ); + } else { + gameLocal.clip.Translation( results, current.origin, current.origin + translation, + clipModel, current.axis, MASK_SOLID, self ); + } +} + +/* +================ +idPhysics_Static::ClipRotation +================ +*/ +void idPhysics_Static::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + if ( model ) { + gameLocal.clip.RotationModel( results, current.origin, rotation, + clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() ); + } else { + gameLocal.clip.Rotation( results, current.origin, rotation, clipModel, current.axis, MASK_SOLID, self ); + } +} + +/* +================ +idPhysics_Static::ClipContents +================ +*/ +int idPhysics_Static::ClipContents( const idClipModel *model ) const { + if ( clipModel ) { + if ( model ) { + return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } else { + return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); + } + } + return 0; +} + +/* +================ +idPhysics_Static::DisableClip +================ +*/ +void idPhysics_Static::DisableClip( void ) { + if ( clipModel ) { + clipModel->Disable(); + } +} + +/* +================ +idPhysics_Static::EnableClip +================ +*/ +void idPhysics_Static::EnableClip( void ) { + if ( clipModel ) { + clipModel->Enable(); + } +} + +/* +================ +idPhysics_Static::UnlinkClip +================ +*/ +void idPhysics_Static::UnlinkClip( void ) { + if ( clipModel ) { + clipModel->Unlink(); + } +} + +/* +================ +idPhysics_Static::LinkClip +================ +*/ +void idPhysics_Static::LinkClip( void ) { + if ( clipModel ) { + clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); + } +} + +/* +================ +idPhysics_Static::EvaluateContacts +================ +*/ +bool idPhysics_Static::EvaluateContacts( void ) { + return false; +} + +/* +================ +idPhysics_Static::GetNumContacts +================ +*/ +int idPhysics_Static::GetNumContacts( void ) const { + return 0; +} + +bool idPhysics_Static::HasNonStaticContacts() { + return false; +} + +/* +================ +idPhysics_Static::GetContact +================ +*/ +const contactInfo_t &idPhysics_Static::GetContact( int num ) const { + static contactInfo_t info; + memset( &info, 0, sizeof( info ) ); + return info; +} + +/* +================ +idPhysics_Static::ClearContacts +================ +*/ +void idPhysics_Static::ClearContacts( void ) { +} + +/* +================ +idPhysics_Static::AddContactEntity +================ +*/ +void idPhysics_Static::AddContactEntity( idEntity *e ) { +} + +/* +================ +idPhysics_Static::RemoveContactEntity +================ +*/ +void idPhysics_Static::RemoveContactEntity( idEntity *e ) { +} + +/* +================ +idPhysics_Static::HasGroundContacts +================ +*/ +bool idPhysics_Static::HasGroundContacts( void ) const { + return false; +} + +/* +================ +idPhysics_Static::IsGroundEntity +================ +*/ +bool idPhysics_Static::IsGroundEntity( int entityNum ) const { + return false; +} + +/* +================ +idPhysics_Static::IsGroundClipModel +================ +*/ +bool idPhysics_Static::IsGroundClipModel( int entityNum, int id ) const { + return false; +} + +/* +================ +idPhysics_Static::SetPushed +================ +*/ +void idPhysics_Static::SetPushed( int deltaTime ) { +} + +/* +================ +idPhysics_Static::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_Static::GetPushedLinearVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Static::GetPushedAngularVelocity +================ +*/ +const idVec3 &idPhysics_Static::GetPushedAngularVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_Static::SetMaster +================ +*/ +void idPhysics_Static::SetMaster( idEntity *master, const bool orientated ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !hasMaster ) { + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); + if ( orientated ) { + current.localAxis = current.axis * masterAxis.Transpose(); + } else { + current.localAxis = current.axis; + } + hasMaster = true; + isOrientated = orientated; + } + } else { + if ( hasMaster ) { + hasMaster = false; + } + } +} + +/* +================ +idPhysics_Static::GetBlockingInfo +================ +*/ +const trace_t *idPhysics_Static::GetBlockingInfo( void ) const { + return NULL; +} + +/* +================ +idPhysics_Static::GetBlockingEntity +================ +*/ +idEntity *idPhysics_Static::GetBlockingEntity( void ) const { + return NULL; +} + +/* +================ +idPhysics_Static::GetLinearEndTime +================ +*/ +int idPhysics_Static::GetLinearEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Static::GetAngularEndTime +================ +*/ +int idPhysics_Static::GetAngularEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_Static::WriteToSnapshot +================ +*/ +void idPhysics_Static::WriteToSnapshot( idBitMsgDelta &msg ) const { + idCQuat quat, localQuat; + + quat = current.axis.ToCQuat(); + localQuat = current.localAxis.ToCQuat(); + + msg.WriteFloat( current.origin[0] ); + msg.WriteFloat( current.origin[1] ); + msg.WriteFloat( current.origin[2] ); + msg.WriteFloat( quat.x ); + msg.WriteFloat( quat.y ); + msg.WriteFloat( quat.z ); + msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); + msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); + msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); + msg.WriteDeltaFloat( quat.x, localQuat.x ); + msg.WriteDeltaFloat( quat.y, localQuat.y ); + msg.WriteDeltaFloat( quat.z, localQuat.z ); +} + +/* +================ +idPhysics_Base::ReadFromSnapshot +================ +*/ +void idPhysics_Static::ReadFromSnapshot( const idBitMsgDelta &msg ) { + idCQuat quat, localQuat; + + current.origin[0] = msg.ReadFloat(); + current.origin[1] = msg.ReadFloat(); + current.origin[2] = msg.ReadFloat(); + quat.x = msg.ReadFloat(); + quat.y = msg.ReadFloat(); + quat.z = msg.ReadFloat(); + current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); + current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); + current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); + localQuat.x = msg.ReadDeltaFloat( quat.x ); + localQuat.y = msg.ReadDeltaFloat( quat.y ); + localQuat.z = msg.ReadDeltaFloat( quat.z ); + + current.axis = quat.ToMat3(); + current.localAxis = localQuat.ToMat3(); +} diff --git a/game/physics/Physics_Static.h b/game/physics/Physics_Static.h new file mode 100644 index 000000000..7f6db6405 --- /dev/null +++ b/game/physics/Physics_Static.h @@ -0,0 +1,159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_STATIC_H__ +#define __PHYSICS_STATIC_H__ + +/* +=============================================================================== + + Physics for a non moving object using at most one collision model. + +=============================================================================== +*/ + +typedef struct staticPState_s { + idVec3 origin; + idMat3 axis; + idVec3 localOrigin; + idMat3 localAxis; +} staticPState_t; + +class idPhysics_Static : public idPhysics { + +public: + CLASS_PROTOTYPE( idPhysics_Static ); + + idPhysics_Static( void ); + ~idPhysics_Static( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + +public: // common physics interface + void SetSelf( idEntity *e ); + idEntity * GetSelf( void ) { return self; } // Get the original entity - Dram + + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + void SetClipMask( int mask, int id = -1 ); + int GetClipMask( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + bool PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + void AddForce( const int id, const idVec3 &point, const idVec3 &force ); + void Activate( void ); + void PutToRest( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + void SetGravity( const idVec3 &newGravity ); + const idVec3 & GetGravity( void ) const; + const idVec3 & GetGravityNormal( void ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + int GetNumContacts( void ) const; + bool HasNonStaticContacts(); + const contactInfo_t & GetContact( int num ) const; + void ClearContacts( void ); + void AddContactEntity( idEntity *e ); + void RemoveContactEntity( idEntity *e ); + + bool HasGroundContacts( void ) const; + bool IsGroundEntity( int entityNum ) const; + bool IsGroundClipModel( int entityNum, int id ) const; + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated = true ); + + const trace_t * GetBlockingInfo( void ) const; + idEntity * GetBlockingEntity( void ) const; + + int GetLinearEndTime( void ) const; + int GetAngularEndTime( void ) const; + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +#ifdef MOD_WATERPHYSICS + // gets/sets the water + // just some functions to avoid making this class abstract. Water has no effect on a static object + // so it sort of makes sense these functions do nothing. + virtual idPhysics_Liquid *GetWater() { return NULL; } // MOD_WATERPHYSICS + virtual void SetWater( idPhysics_Liquid *e, const float murkiness ) {} // MOD_WATERPHYSICS +#endif +protected: + idEntity * self; // entity using this physics object + staticPState_t current; // physics state + idClipModel * clipModel; // collision model + + // master + bool hasMaster; + bool isOrientated; +}; + +#endif /* !__PHYSICS_STATIC_H__ */ diff --git a/game/physics/Physics_StaticMulti.cpp b/game/physics/Physics_StaticMulti.cpp new file mode 100644 index 000000000..19c9d4898 --- /dev/null +++ b/game/physics/Physics_StaticMulti.cpp @@ -0,0 +1,1074 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +CLASS_DECLARATION( idPhysics, idPhysics_StaticMulti ) +END_CLASS + +staticPState_t defaultState; + + +/* +================ +idPhysics_StaticMulti::idPhysics_StaticMulti +================ +*/ +idPhysics_StaticMulti::idPhysics_StaticMulti( void ) { + self = NULL; + hasMaster = false; + isOrientated = false; + + defaultState.origin.Zero(); + defaultState.axis.Identity(); + defaultState.localOrigin.Zero(); + defaultState.localAxis.Identity(); + + current.SetNum( 1 ); + current[0] = defaultState; + clipModels.SetNum( 1 ); + clipModels[0] = NULL; +} + +/* +================ +idPhysics_StaticMulti::~idPhysics_StaticMulti +================ +*/ +idPhysics_StaticMulti::~idPhysics_StaticMulti( void ) { + if ( self && self->GetPhysics() == this ) { + self->SetPhysics( NULL ); + } + idForce::DeletePhysics( this ); + for ( int i = 0; i < clipModels.Num(); i++ ) { + delete clipModels[i]; + } +} + +/* +================ +idPhysics_StaticMulti::Save +================ +*/ +void idPhysics_StaticMulti::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteObject( self ); + + savefile->WriteInt(current.Num()); + for ( i = 0; i < current.Num(); i++ ) { + savefile->WriteVec3( current[i].origin ); + savefile->WriteMat3( current[i].axis ); + savefile->WriteVec3( current[i].localOrigin ); + savefile->WriteMat3( current[i].localAxis ); + } + + savefile->WriteInt( clipModels.Num() ); + for ( i = 0; i < clipModels.Num(); i++ ) { + savefile->WriteClipModel( clipModels[i] ); + } + + savefile->WriteBool(hasMaster); + savefile->WriteBool(isOrientated); +} + +/* +================ +idPhysics_StaticMulti::Restore +================ +*/ +void idPhysics_StaticMulti::Restore( idRestoreGame *savefile ) { + int i, num; + + savefile->ReadObject( reinterpret_cast( self ) ); + + savefile->ReadInt(num); + current.AssureSize( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadVec3( current[i].origin ); + savefile->ReadMat3( current[i].axis ); + savefile->ReadVec3( current[i].localOrigin ); + savefile->ReadMat3( current[i].localAxis ); + } + + savefile->ReadInt(num); + clipModels.SetNum( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadClipModel( clipModels[i] ); + } + + savefile->ReadBool(hasMaster); + savefile->ReadBool(isOrientated); +} + +/* +================ +idPhysics_StaticMulti::SetSelf +================ +*/ +void idPhysics_StaticMulti::SetSelf( idEntity *e ) { + assert( e ); + self = e; +} + +/* +================ +idPhysics_StaticMulti::RemoveIndex +================ +*/ +void idPhysics_StaticMulti::RemoveIndex( int id, bool freeClipModel ) { + if ( id < 0 || id >= clipModels.Num() ) { + return; + } + if ( clipModels[id] && freeClipModel ) { + delete clipModels[id]; + clipModels[id] = NULL; + } + clipModels.RemoveIndex( id ); + current.RemoveIndex( id ); +} + +/* +================ +idPhysics_StaticMulti::SetClipModel +================ +*/ +void idPhysics_StaticMulti::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { + int i; + + assert( self ); + + if ( id >= clipModels.Num() ) { + current.AssureSize( id+1, defaultState ); + clipModels.AssureSize( id+1, NULL ); + } + + if ( clipModels[id] && clipModels[id] != model && freeOld ) { + delete clipModels[id]; + } + clipModels[id] = model; + if ( clipModels[id] ) { + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + + for ( i = clipModels.Num() - 1; i >= 1; i-- ) { + if ( clipModels[i] ) { + break; + } + } + current.SetNum( i+1, false ); + clipModels.SetNum( i+1, false ); +} + +/* +================ +idPhysics_StaticMulti::GetClipModel +================ +*/ +idClipModel *idPhysics_StaticMulti::GetClipModel( int id ) const { + if ( id >= 0 && id < clipModels.Num() && clipModels[id] ) { + return clipModels[id]; + } + return gameLocal.clip.DefaultClipModel(); +} + +/* +================ +idPhysics_StaticMulti::GetNumClipModels +================ +*/ +int idPhysics_StaticMulti::GetNumClipModels( void ) const { + return clipModels.Num(); +} + +/* +================ +idPhysics_StaticMulti::SetMass +================ +*/ +void idPhysics_StaticMulti::SetMass( float mass, int id ) { +} + +/* +================ +idPhysics_StaticMulti::GetMass +================ +*/ +float idPhysics_StaticMulti::GetMass( int id ) const { + return 0.0f; +} + +/* +================ +idPhysics_StaticMulti::SetContents +================ +*/ +void idPhysics_StaticMulti::SetContents( int contents, int id ) { + int i; + + if ( id >= 0 && id < clipModels.Num() ) { + if ( clipModels[id] ) { + clipModels[id]->SetContents( contents ); + } + } else if ( id == -1 ) { + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->SetContents( contents ); + } + } + } +} + +/* +================ +idPhysics_StaticMulti::GetContents +================ +*/ +int idPhysics_StaticMulti::GetContents( int id ) const { + int i, contents = 0; + + if ( id >= 0 && id < clipModels.Num() ) { + if ( clipModels[id] ) { + contents = clipModels[id]->GetContents(); + } + } else if ( id == -1 ) { + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + contents |= clipModels[i]->GetContents(); + } + } + } + return contents; +} + +/* +================ +idPhysics_StaticMulti::SetClipMask +================ +*/ +void idPhysics_StaticMulti::SetClipMask( int mask, int id ) { +} + +/* +================ +idPhysics_StaticMulti::GetClipMask +================ +*/ +int idPhysics_StaticMulti::GetClipMask( int id ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::GetBounds +================ +*/ +const idBounds &idPhysics_StaticMulti::GetBounds( int id ) const { + int i; + static idBounds bounds; + + if ( id >= 0 && id < clipModels.Num() ) { + if ( clipModels[id] ) { + return clipModels[id]->GetBounds(); + } + } + if ( id == -1 ) { + bounds.Clear(); + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + bounds.AddBounds( clipModels[i]->GetAbsBounds() ); + } + } + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + bounds[0] -= clipModels[i]->GetOrigin(); + bounds[1] -= clipModels[i]->GetOrigin(); + break; + } + } + return bounds; + } + return bounds_zero; +} + +/* +================ +idPhysics_StaticMulti::GetAbsBounds +================ +*/ +const idBounds &idPhysics_StaticMulti::GetAbsBounds( int id ) const { + int i; + static idBounds absBounds; + + if ( id >= 0 && id < clipModels.Num() ) { + if ( clipModels[id] ) { + return clipModels[id]->GetAbsBounds(); + } + } + if ( id == -1 ) { + absBounds.Clear(); + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + absBounds.AddBounds( clipModels[i]->GetAbsBounds() ); + } + } + return absBounds; + } + return bounds_zero; +} + +/* +================ +idPhysics_StaticMulti::Evaluate +================ +*/ +bool idPhysics_StaticMulti::Evaluate( int timeStepMSec, int endTimeMSec ) { + int i; + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + for ( i = 0; i < clipModels.Num(); i++ ) { + current[i].origin = masterOrigin + current[i].localOrigin * masterAxis; + if ( isOrientated ) { + current[i].axis = current[i].localAxis * masterAxis; + } else { + current[i].axis = current[i].localAxis; + } + if ( clipModels[i] ) { + clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); + } + } + + // FIXME: return false if master did not move + return true; + } + return false; +} + +/* +================ +idPhysics_StaticMulti::UpdateTime +================ +*/ +void idPhysics_StaticMulti::UpdateTime( int endTimeMSec ) { +} + +/* +================ +idPhysics_StaticMulti::GetTime +================ +*/ +int idPhysics_StaticMulti::GetTime( void ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::GetImpactInfo +================ +*/ +void idPhysics_StaticMulti::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { + memset( info, 0, sizeof( *info ) ); +} + +/* +================ +idPhysics_StaticMulti::ApplyImpulse +================ +*/ +void idPhysics_StaticMulti::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { +} + +bool idPhysics_StaticMulti::PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { + return false; +} + +/* +================ +idPhysics_StaticMulti::AddForce +================ +*/ +void idPhysics_StaticMulti::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { +} + +/* +================ +idPhysics_StaticMulti::Activate +================ +*/ +void idPhysics_StaticMulti::Activate( void ) { +} + +/* +================ +idPhysics_StaticMulti::PutToRest +================ +*/ +void idPhysics_StaticMulti::PutToRest( void ) { +} + +/* +================ +idPhysics_StaticMulti::IsAtRest +================ +*/ +bool idPhysics_StaticMulti::IsAtRest( void ) const { + return true; +} + +/* +================ +idPhysics_StaticMulti::GetRestStartTime +================ +*/ +int idPhysics_StaticMulti::GetRestStartTime( void ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::IsPushable +================ +*/ +bool idPhysics_StaticMulti::IsPushable( void ) const { + return false; +} + +/* +================ +idPhysics_StaticMulti::SaveState +================ +*/ +void idPhysics_StaticMulti::SaveState( void ) { +} + +/* +================ +idPhysics_StaticMulti::RestoreState +================ +*/ +void idPhysics_StaticMulti::RestoreState( void ) { +} + +/* +================ +idPhysics_StaticMulti::SetOrigin +================ +*/ +void idPhysics_StaticMulti::SetOrigin( const idVec3 &newOrigin, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( id >= 0 && id < clipModels.Num() ) { + current[id].localOrigin = newOrigin; + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current[id].origin = masterOrigin + newOrigin * masterAxis; + } else { + current[id].origin = newOrigin; + } + if ( clipModels[id] ) { + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + } else if ( id == -1 ) { + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + Translate( masterOrigin + masterAxis * newOrigin - current[0].origin ); + } else { + Translate( newOrigin - current[0].origin ); + } + } +} + +/* +================ +idPhysics_StaticMulti::SetAxis +================ +*/ +void idPhysics_StaticMulti::SetAxis( const idMat3 &newAxis, int id ) { + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( id >= 0 && id < clipModels.Num() ) { + current[id].localAxis = newAxis; + if ( hasMaster && isOrientated ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current[id].axis = newAxis * masterAxis; + } else { + current[id].axis = newAxis; + } + if ( clipModels[id] ) { + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + } else if ( id == -1 ) { + idMat3 axis; + idRotation rotation; + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + axis = current[0].axis.Transpose() * ( newAxis * masterAxis ); + } else { + axis = current[0].axis.Transpose() * newAxis; + } + rotation = axis.ToRotation(); + rotation.SetOrigin( current[0].origin ); + + Rotate( rotation ); + } +} + +/* +================ +idPhysics_StaticMulti::Translate +================ +*/ +void idPhysics_StaticMulti::Translate( const idVec3 &translation, int id ) { + int i; + + if ( id >= 0 && id < clipModels.Num() ) { + current[id].localOrigin += translation; + current[id].origin += translation; + + if ( clipModels[id] ) { + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + } else if ( id == -1 ) { + for ( i = 0; i < clipModels.Num(); i++ ) { + current[i].localOrigin += translation; + current[i].origin += translation; + + if ( clipModels[i] ) { + clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); + } + } + } +} + +/* +================ +Tels: idPhysics_StaticMulti::Scale +================ +*/ +void idPhysics_StaticMulti::Scale( const idVec3 &scale, int id ) { + int i; + + if ( id >= 0 && id < clipModels.Num() ) { + if ( clipModels[id] ) { + clipModels[id]->Scale( scale ); + // Tels: nec.? + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + } else if ( id == -1 ) { + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->Scale( scale ); + clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); + } + } + } +} + +/* +================ +idPhysics_StaticMulti::Rotate +================ +*/ +void idPhysics_StaticMulti::Rotate( const idRotation &rotation, int id ) { + int i; + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( id >= 0 && id < clipModels.Num() ) { + current[id].origin *= rotation; + current[id].axis *= rotation.ToMat3(); + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current[id].localAxis *= rotation.ToMat3(); + current[id].localOrigin = ( current[id].origin - masterOrigin ) * masterAxis.Transpose(); + } else { + current[id].localAxis = current[id].axis; + current[id].localOrigin = current[id].origin; + } + + if ( clipModels[id] ) { + clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); + } + } else if ( id == -1 ) { + for ( i = 0; i < clipModels.Num(); i++ ) { + current[i].origin *= rotation; + current[i].axis *= rotation.ToMat3(); + + if ( hasMaster ) { + self->GetMasterPosition( masterOrigin, masterAxis ); + current[i].localAxis *= rotation.ToMat3(); + current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose(); + } else { + current[i].localAxis = current[i].axis; + current[i].localOrigin = current[i].origin; + } + + if ( clipModels[i] ) { + clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); + } + } + } +} + +/* +================ +idPhysics_StaticMulti::GetOrigin +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetOrigin( int id ) const { + if ( id >= 0 && id < clipModels.Num() ) { + return current[id].origin; + } + if ( clipModels.Num() ) { + return current[0].origin; + } else { + return vec3_origin; + } +} + +/* +================ +idPhysics_StaticMulti::GetAxis +================ +*/ +const idMat3 &idPhysics_StaticMulti::GetAxis( int id ) const { + if ( id >= 0 && id < clipModels.Num() ) { + return current[id].axis; + } + if ( clipModels.Num() ) { + return current[0].axis; + } else { + return mat3_identity; + } +} + +/* +================ +idPhysics_StaticMulti::SetLinearVelocity +================ +*/ +void idPhysics_StaticMulti::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { +} + +/* +================ +idPhysics_StaticMulti::SetAngularVelocity +================ +*/ +void idPhysics_StaticMulti::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { +} + +/* +================ +idPhysics_StaticMulti::GetLinearVelocity +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetLinearVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_StaticMulti::GetAngularVelocity +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetAngularVelocity( int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_StaticMulti::SetGravity +================ +*/ +void idPhysics_StaticMulti::SetGravity( const idVec3 &newGravity ) { +} + +/* +================ +idPhysics_StaticMulti::GetGravity +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetGravity( void ) const { + static idVec3 gravity( 0, 0, -g_gravity.GetFloat() ); + return gravity; +} + +/* +================ +idPhysics_StaticMulti::GetGravityNormal +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetGravityNormal( void ) const { + static idVec3 gravity( 0, 0, -1 ); + return gravity; +} + +/* +================ +idPhysics_StaticMulti::ClipTranslation +================ +*/ +void idPhysics_StaticMulti::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { + memset( &results, 0, sizeof( trace_t ) ); + gameLocal.Warning( "idPhysics_StaticMulti::ClipTranslation called" ); +} + +/* +================ +idPhysics_StaticMulti::ClipRotation +================ +*/ +void idPhysics_StaticMulti::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { + memset( &results, 0, sizeof( trace_t ) ); + gameLocal.Warning( "idPhysics_StaticMulti::ClipRotation called" ); +} + +/* +================ +idPhysics_StaticMulti::ClipContents +================ +*/ +int idPhysics_StaticMulti::ClipContents( const idClipModel *model ) const { + int i, contents; + + contents = 0; + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + if ( model ) { + contents |= gameLocal.clip.ContentsModel( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1, + model->Handle(), model->GetOrigin(), model->GetAxis() ); + } else { + contents |= gameLocal.clip.Contents( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1, NULL ); + } + } + } + return contents; +} + +/* +================ +idPhysics_StaticMulti::DisableClip +================ +*/ +void idPhysics_StaticMulti::DisableClip( void ) { + int i; + + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->Disable(); + } + } +} + +/* +================ +idPhysics_StaticMulti::EnableClip +================ +*/ +void idPhysics_StaticMulti::EnableClip( void ) { + int i; + + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->Enable(); + } + } +} + +/* +================ +idPhysics_StaticMulti::UnlinkClip +================ +*/ +void idPhysics_StaticMulti::UnlinkClip( void ) { + int i; + + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->Unlink(); + } + } +} + +/* +================ +idPhysics_StaticMulti::LinkClip +================ +*/ +void idPhysics_StaticMulti::LinkClip( void ) { + int i; + + for ( i = 0; i < clipModels.Num(); i++ ) { + if ( clipModels[i] ) { + clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); + } + } +} + +/* +================ +idPhysics_StaticMulti::EvaluateContacts +================ +*/ +bool idPhysics_StaticMulti::EvaluateContacts( void ) { + return false; +} + +/* +================ +idPhysics_StaticMulti::GetNumContacts +================ +*/ +int idPhysics_StaticMulti::GetNumContacts( void ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::GetContact +================ +*/ +const contactInfo_t &idPhysics_StaticMulti::GetContact( int num ) const { + static contactInfo_t info; + memset( &info, 0, sizeof( info ) ); + return info; +} + +bool idPhysics_StaticMulti::HasNonStaticContacts() { + return false; +} + +/* +================ +idPhysics_StaticMulti::ClearContacts +================ +*/ +void idPhysics_StaticMulti::ClearContacts( void ) { +} + +/* +================ +idPhysics_StaticMulti::AddContactEntity +================ +*/ +void idPhysics_StaticMulti::AddContactEntity( idEntity *e ) { +} + +/* +================ +idPhysics_StaticMulti::RemoveContactEntity +================ +*/ +void idPhysics_StaticMulti::RemoveContactEntity( idEntity *e ) { +} + +/* +================ +idPhysics_StaticMulti::HasGroundContacts +================ +*/ +bool idPhysics_StaticMulti::HasGroundContacts( void ) const { + return false; +} + +/* +================ +idPhysics_StaticMulti::IsGroundEntity +================ +*/ +bool idPhysics_StaticMulti::IsGroundEntity( int entityNum ) const { + return false; +} + +/* +================ +idPhysics_StaticMulti::IsGroundClipModel +================ +*/ +bool idPhysics_StaticMulti::IsGroundClipModel( int entityNum, int id ) const { + return false; +} + +/* +================ +idPhysics_StaticMulti::SetPushed +================ +*/ +void idPhysics_StaticMulti::SetPushed( int deltaTime ) { +} + +/* +================ +idPhysics_StaticMulti::GetPushedLinearVelocity +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetPushedLinearVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_StaticMulti::GetPushedAngularVelocity +================ +*/ +const idVec3 &idPhysics_StaticMulti::GetPushedAngularVelocity( const int id ) const { + return vec3_origin; +} + +/* +================ +idPhysics_StaticMulti::SetMaster +================ +*/ +void idPhysics_StaticMulti::SetMaster( idEntity *master, const bool orientated ) { + int i; + idVec3 masterOrigin; + idMat3 masterAxis; + + if ( master ) { + if ( !hasMaster ) { + // transform from world space to master space + self->GetMasterPosition( masterOrigin, masterAxis ); + for ( i = 0; i < clipModels.Num(); i++ ) { + current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose(); + if ( orientated ) { + current[i].localAxis = current[i].axis * masterAxis.Transpose(); + } else { + current[i].localAxis = current[i].axis; + } + } + hasMaster = true; + isOrientated = orientated; + } + } else { + if ( hasMaster ) { + hasMaster = false; + } + } +} + +/* +================ +idPhysics_StaticMulti::GetBlockingInfo +================ +*/ +const trace_t *idPhysics_StaticMulti::GetBlockingInfo( void ) const { + return NULL; +} + +/* +================ +idPhysics_StaticMulti::GetBlockingEntity +================ +*/ +idEntity *idPhysics_StaticMulti::GetBlockingEntity( void ) const { + return NULL; +} + +/* +================ +idPhysics_StaticMulti::GetLinearEndTime +================ +*/ +int idPhysics_StaticMulti::GetLinearEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::GetAngularEndTime +================ +*/ +int idPhysics_StaticMulti::GetAngularEndTime( void ) const { + return 0; +} + +/* +================ +idPhysics_StaticMulti::WriteToSnapshot +================ +*/ +void idPhysics_StaticMulti::WriteToSnapshot( idBitMsgDelta &msg ) const { + int i; + idCQuat quat, localQuat; + + msg.WriteByte( current.Num() ); + + for ( i = 0; i < current.Num(); i++ ) { + quat = current[i].axis.ToCQuat(); + localQuat = current[i].localAxis.ToCQuat(); + + msg.WriteFloat( current[i].origin[0] ); + msg.WriteFloat( current[i].origin[1] ); + msg.WriteFloat( current[i].origin[2] ); + msg.WriteFloat( quat.x ); + msg.WriteFloat( quat.y ); + msg.WriteFloat( quat.z ); + msg.WriteDeltaFloat( current[i].origin[0], current[i].localOrigin[0] ); + msg.WriteDeltaFloat( current[i].origin[1], current[i].localOrigin[1] ); + msg.WriteDeltaFloat( current[i].origin[2], current[i].localOrigin[2] ); + msg.WriteDeltaFloat( quat.x, localQuat.x ); + msg.WriteDeltaFloat( quat.y, localQuat.y ); + msg.WriteDeltaFloat( quat.z, localQuat.z ); + } +} + +/* +================ +idPhysics_StaticMulti::ReadFromSnapshot +================ +*/ +void idPhysics_StaticMulti::ReadFromSnapshot( const idBitMsgDelta &msg ) { + int i, num; + idCQuat quat, localQuat; + + num = msg.ReadByte(); + assert( num == current.Num() ); + + for ( i = 0; i < current.Num(); i++ ) { + current[i].origin[0] = msg.ReadFloat(); + current[i].origin[1] = msg.ReadFloat(); + current[i].origin[2] = msg.ReadFloat(); + quat.x = msg.ReadFloat(); + quat.y = msg.ReadFloat(); + quat.z = msg.ReadFloat(); + current[i].localOrigin[0] = msg.ReadDeltaFloat( current[i].origin[0] ); + current[i].localOrigin[1] = msg.ReadDeltaFloat( current[i].origin[1] ); + current[i].localOrigin[2] = msg.ReadDeltaFloat( current[i].origin[2] ); + localQuat.x = msg.ReadDeltaFloat( quat.x ); + localQuat.y = msg.ReadDeltaFloat( quat.y ); + localQuat.z = msg.ReadDeltaFloat( quat.z ); + + current[i].axis = quat.ToMat3(); + current[i].localAxis = localQuat.ToMat3(); + } +} diff --git a/game/physics/Physics_StaticMulti.h b/game/physics/Physics_StaticMulti.h new file mode 100644 index 000000000..efbcf5f05 --- /dev/null +++ b/game/physics/Physics_StaticMulti.h @@ -0,0 +1,159 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PHYSICS_STATICMULTI_H__ +#define __PHYSICS_STATICMULTI_H__ + +/* +=============================================================================== + + Physics for a non moving object using no or multiple collision models. + +=============================================================================== +*/ + +class idPhysics_StaticMulti : public idPhysics { + +public: + CLASS_PROTOTYPE( idPhysics_StaticMulti ); + + idPhysics_StaticMulti( void ); + ~idPhysics_StaticMulti( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void RemoveIndex( int id = 0, bool freeClipModel = true ); + +public: // common physics interface + + void SetSelf( idEntity *e ); + + void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); + idClipModel * GetClipModel( int id = 0 ) const; + int GetNumClipModels( void ) const; + + void SetMass( float mass, int id = -1 ); + float GetMass( int id = -1 ) const; + + void SetContents( int contents, int id = -1 ); + int GetContents( int id = -1 ) const; + + void SetClipMask( int mask, int id = -1 ); + int GetClipMask( int id = -1 ) const; + + const idBounds & GetBounds( int id = -1 ) const; + const idBounds & GetAbsBounds( int id = -1 ) const; + + bool Evaluate( int timeStepMSec, int endTimeMSec ); + void UpdateTime( int endTimeMSec ); + int GetTime( void ) const; + + void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; + void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + bool PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); + void AddForce( const int id, const idVec3 &point, const idVec3 &force ); + void Activate( void ); + void PutToRest( void ); + bool IsAtRest( void ) const; + int GetRestStartTime( void ) const; + bool IsPushable( void ) const; + + void SaveState( void ); + void RestoreState( void ); + + void SetOrigin( const idVec3 &newOrigin, int id = -1 ); + void SetAxis( const idMat3 &newAxis, int id = -1 ); + + // Tels: Scale the clipmodel with the id "id" + void Scale( const idVec3 &scale, int id = -1 ); + + void Translate( const idVec3 &translation, int id = -1 ); + void Rotate( const idRotation &rotation, int id = -1 ); + + const idVec3 & GetOrigin( int id = 0 ) const; + const idMat3 & GetAxis( int id = 0 ) const; + + void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); + void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); + + const idVec3 & GetLinearVelocity( int id = 0 ) const; + const idVec3 & GetAngularVelocity( int id = 0 ) const; + + void SetGravity( const idVec3 &newGravity ); + const idVec3 & GetGravity( void ) const; + const idVec3 & GetGravityNormal( void ) const; + + void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; + void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; + int ClipContents( const idClipModel *model ) const; + + void DisableClip( void ); + void EnableClip( void ); + + void UnlinkClip( void ); + void LinkClip( void ); + + bool EvaluateContacts( void ); + int GetNumContacts( void ) const; + const contactInfo_t & GetContact( int num ) const; + bool HasNonStaticContacts(); + void ClearContacts( void ); + void AddContactEntity( idEntity *e ); + void RemoveContactEntity( idEntity *e ); + + bool HasGroundContacts( void ) const; + bool IsGroundEntity( int entityNum ) const; + bool IsGroundClipModel( int entityNum, int id ) const; + + void SetPushed( int deltaTime ); + const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; + const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; + + void SetMaster( idEntity *master, const bool orientated = true ); + + const trace_t * GetBlockingInfo( void ) const; + idEntity * GetBlockingEntity( void ) const; + + int GetLinearEndTime( void ) const; + int GetAngularEndTime( void ) const; + + void WriteToSnapshot( idBitMsgDelta &msg ) const; + void ReadFromSnapshot( const idBitMsgDelta &msg ); + +#ifdef MOD_WATERPHYSICS + // gets/sets the water + // just some functions to avoid making this class abstract. Water has no effect on a static object + // so it sort of makes sense these functions do nothing. + virtual idPhysics_Liquid *GetWater() { return NULL; } // MOD_WATERPHYSICS + virtual void SetWater( idPhysics_Liquid *e, const float murkiness ) {} // MOD_WATERPHYSICS +#endif + +protected: + idEntity * self; // entity using this physics object + idList current; // physics state + idList clipModels; // collision model(s) + + // master + bool hasMaster; + bool isOrientated; +}; + +#endif /* !__PHYSICS_STATICMULTI_H__ */ diff --git a/game/physics/Push.cpp b/game/physics/Push.cpp new file mode 100644 index 000000000..6edc408e0 --- /dev/null +++ b/game/physics/Push.cpp @@ -0,0 +1,1493 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + + +/* +============ +idPush::InitSavingPushedEntityPositions +============ +*/ +void idPush::InitSavingPushedEntityPositions( void ) { + numPushed = 0; +} + +/* +============ +idPush::SaveEntityPosition +============ +*/ +void idPush::SaveEntityPosition( idEntity *ent ) { + int i; + + // if already saved the physics state for this entity + for ( i = 0; i < numPushed; i++ ) { + if ( pushed[i].ent == ent ) { + return; + } + } + + // don't overflow + if ( numPushed >= MAX_GENTITIES ) { + gameLocal.Error( "more than MAX_GENTITIES pushed entities" ); + return; + } + + pushed[numPushed].ent = ent; + + // if the entity is an actor + if ( ent->IsType( idActor::Type ) ) { + // save the delta view angles + pushed[numPushed].deltaViewAngles = static_cast(ent)->GetDeltaViewAngles(); + } + + // save the physics state + ent->GetPhysics()->SaveState(); + + numPushed++; +} + +/* +============ +idPush::RestorePushedEntityPositions +============ +*/ +void idPush::RestorePushedEntityPositions( void ) { + int i; + + for ( i = 0; i < numPushed; i++ ) { + + // if the entity is an actor + if ( pushed[i].ent->IsType( idActor::Type ) ) { + // set back the delta view angles + static_cast(pushed[i].ent)->SetDeltaViewAngles( pushed[i].deltaViewAngles ); + } + + // restore the physics state + pushed[i].ent->GetPhysics()->RestoreState(); + } +} + +/* +============ +idPush::RotateEntityToAxial +============ +*/ +bool idPush::RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint ) { + int i; + trace_t trace; + idRotation rotation; + idMat3 axis; + idPhysics *physics; + + physics = ent->GetPhysics(); + axis = physics->GetAxis(); + if ( !axis.IsRotated() ) { + return true; + } + // try to rotate the bbox back to axial with at most four rotations + for ( i = 0; i < 4; i++ ) { + axis = physics->GetAxis(); + rotation = axis.ToRotation(); + rotation.Scale( -1 ); + rotation.SetOrigin( rotationPoint ); + // tiny float numbers in the clip axis, this can get the entity stuck + if ( rotation.GetAngle() == 0.0f ) { + physics->SetAxis( mat3_identity ); + return true; + } + // + ent->GetPhysics()->ClipRotation( trace, rotation, NULL ); + // if the full rotation is possible + if ( trace.fraction >= 1.0f ) { + // set bbox in final axial position + physics->SetOrigin( trace.endpos ); + physics->SetAxis( mat3_identity ); + return true; + } + // if partial rotation was possible + else if ( trace.fraction > 0.0f ) { + // partial rotation + physics->SetOrigin( trace.endpos ); + physics->SetAxis( trace.endAxis ); + } + // next rotate around collision point + rotationPoint = trace.c.point; + } + return false; +} + +#ifdef NEW_PUSH + +/* +============ +idPush::CanPushEntity +============ +*/ +bool idPush::CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags ) { + + // if the physics object is not pushable + if ( !ent->GetPhysics()->IsPushable() ) { + return false; + } + + // if the entity doesn't clip with this pusher + if ( !( ent->GetPhysics()->GetClipMask() & pusher->GetPhysics()->GetContents() ) ) { + return false; + } + + // don't push players in noclip mode + if ( ent->client && ent->client->noclip ) { + return false; + } + + // if we should only push idMoveable entities + if ( ( flags & PUSHFL_ONLYMOVEABLE ) && !ent->IsType( idMoveable::Type ) ) { + return false; + } + + // if we shouldn't push entities the original pusher rests upon + if ( flags & PUSHFL_NOGROUNDENTITIES ) { + if ( initialPusher->GetPhysics()->IsGroundEntity( ent->entityNumber ) ) { + return false; + } + } + + return true; +} + +/* +============ +idPush::AddEntityToPushedGroup +============ +*/ +void idPush::AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact ) { + int i, j; + + for ( i = 0; i < pushedGroupSize; i++ ) { + if ( ent == pushedGroup[i].ent ) { + if ( fraction > pushedGroup[i].fraction ) { + pushedGroup[i].fraction = fraction; + pushedGroup[i].groundContact &= groundContact; + pushedGroup[i].test = true; + } + return; + } + else if ( fraction > pushedGroup[i].fraction ) { + for ( j = pushedGroupSize; j > i; j-- ) { + pushedGroup[j] = pushedGroup[j-1]; + } + break; + } + } + + // put the entity in the group + pushedGroupSize++; + pushedGroup[i].ent = ent; + pushedGroup[i].fraction = fraction; + pushedGroup[i].groundContact = groundContact; + pushedGroup[i].test = true; + + // remove any further occurances of the same entity in the group + for ( i++; i < pushedGroupSize; i++ ) { + if ( ent == pushedGroup[i].ent ) { + for ( j = i+1; j < pushedGroupSize; j++ ) { + pushedGroup[j-1] = pushedGroup[j]; + } + pushedGroupSize--; + break; + } + } +} + +/* +============ +idPush::IsFullyPushed +============ +*/ +bool idPush::IsFullyPushed( idEntity *ent ) { + int i; + + for ( i = 0; i < pushedGroupSize; i++ ) { + if ( pushedGroup[i].fraction < 1.0f ) { + return false; + } + if ( ent == pushedGroup[i].ent ) { + return true; + } + } + return false; +} + +/* +============ +idPush::ClipTranslationAgainstPusher +============ +*/ +bool idPush::ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation ) { + int i, n; + trace_t t; + + results.fraction = 1.0f; + + n = pusher->GetPhysics()->GetNumClipModels(); + for ( i = 0; i < n; i++ ) { + ent->GetPhysics()->ClipTranslation( t, translation, pusher->GetPhysics()->GetClipModel( i ) ); + if ( t.fraction < results.fraction ) { + results = t; + } + } + return ( results.fraction < 1.0f ); +} + +/* +============ +idPush::GetPushableEntitiesForTranslation +============ +*/ +int idPush::GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags, + const idVec3 &translation, idEntity *entityList[], int maxEntities ) { + int i, n, l; + idBounds bounds, pushBounds; + idPhysics *physics; + + // get bounds for the whole movement + physics = pusher->GetPhysics(); + bounds = physics->GetBounds(); + pushBounds.FromBoundsTranslation( bounds, physics->GetOrigin(), physics->GetAxis(), translation ); + pushBounds.ExpandSelf( 2.0f ); + + // get all entities within the push bounds + n = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); + + for ( l = i = 0; i < n; i++ ) { + if ( entityList[i] == pusher || entityList[i] == initialPusher ) { + continue; + } + if ( CanPushEntity( entityList[i], pusher, initialPusher, flags ) ) { + entityList[l++] = entityList[i]; + } + } + + return l; +} + +/* +============ +idPush::ClipTranslationalPush + + Try to push other entities by translating the given entity. +============ +*/ +float idPush::ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, + const idVec3 &newOrigin, const idVec3 &translation, + float ImpulseMod ) +{ + int i, j, numListedEntities; + idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ]; + float fraction; + bool groundContact, blocked = false; + float totalMass; + trace_t trace; + idVec3 realTranslation, partialTranslation; + + totalMass = 0.0f; + + results.fraction = 1.0f; + results.endpos = newOrigin; + results.endAxis = pusher->GetPhysics()->GetAxis(); + memset( results.c, 0, sizeof( results.c ) ); + + if ( translation == vec3_origin ) { + return totalMass; + } + + // clip against all non-pushable physics objects + if ( flags & PUSHFL_CLIP ) { + + numListedEntities = GetPushableEntitiesForTranslation( pusher, pusher, flags, translation, entityList, MAX_GENTITIES ); + // disable pushable entities for collision detection + for ( i = 0; i < numListedEntities; i++ ) { + entityList[i]->GetPhysics()->DisableClip(); + } + // clip translation + pusher->GetPhysics()->ClipTranslation( results, translation, NULL ); + // enable pushable entities + for ( i = 0; i < numListedEntities; i++ ) { + entityList[i]->GetPhysics()->EnableClip(); + } + if ( results.fraction == 0.0f ) { + return totalMass; + } + realTranslation = results.fraction * translation; + } + else { + realTranslation = translation; + } + + // put the pusher in the group of pushed physics objects + pushedGroup[0].ent = pusher; + pushedGroup[0].fraction = 1.0f; + pushedGroup[0].groundContact = true; + pushedGroup[0].test = true; + pushedGroupSize = 1; + + // get all physics objects that need to be pushed + for ( i = 0; i < pushedGroupSize; ) { + if ( !pushedGroup[i].test ) { + i++; + continue; + } + pushedGroup[i].test = false; + curPusher = pushedGroup[i].ent; + fraction = pushedGroup[i].fraction; + groundContact = pushedGroup[i].groundContact; + i = 0; + + numListedEntities = GetPushableEntitiesForTranslation( curPusher, pusher, flags, realTranslation, entityList, MAX_GENTITIES ); + + for ( j = 0; j < numListedEntities; j++ ) { + ent = entityList[ j ]; + + if ( IsFullyPushed( ent ) ) { + continue; + } + + if ( !CanPushEntity( ent, curPusher, pusher, flags ) ) { + continue; + } + + if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) { + AddEntityToPushedGroup( ent, 1.0f * fraction, false ); + } + else if ( ClipTranslationAgainstPusher( trace, ent, curPusher, -fraction * realTranslation ) ) { + AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact ); + } + } + } + + // save physics states and disable physics objects for collision detection + for ( i = 0; i < pushedGroupSize; i++ ) { + SaveEntityPosition( pushedGroup[i].ent ); + pushedGroup[i].ent->GetPhysics()->DisableClip(); + } + + // clip all pushed physics objects + for ( i = 1; i < pushedGroupSize; i++ ) { + partialTranslation = realTranslation * pushedGroup[i].fraction; + + pushedGroup[i].ent->GetPhysics()->ClipTranslation( trace, partialTranslation, NULL ); + + if ( trace.fraction < 1.0f ) { + blocked = true; + break; + } + } + + // enable all physics objects for collision detection + for ( i = 1; i < pushedGroupSize; i++ ) { + pushedGroup[i].ent->GetPhysics()->EnableClip(); + } + + // push all or nothing + if ( blocked ) { + if ( flags & PUSHFL_CLIP ) { + pusher->GetPhysics()->ClipTranslation( results, realTranslation, NULL ); + } + else { + results.fraction = 0.0f; + results.endpos = pusher->GetPhysics()->GetOrigin(); + results.endAxis = pusher->GetPhysics()->GetAxis(); + } + } + else { + // translate all pushed physics objects + for ( i = 1; i < pushedGroupSize; i++ ) { + partialTranslation = realTranslation * pushedGroup[i].fraction; + pushedGroup[i].ent->GetPhysics()->Translate( partialTranslation ); + totalMass += pushedGroup[i].ent->GetPhysics()->GetMass(); + } + // translate the clip models of the pusher + for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) { + pusher->GetPhysics()->GetClipModel(i)->Translate( results.fraction * realTranslation ); + pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip ); + } + } + + return totalMass; +} + +/* +============ +idPush::ClipRotationAgainstPusher +============ +*/ +bool idPush::ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation ) { + int i, n; + trace_t t; + + results.fraction = 1.0f; + + n = pusher->GetPhysics()->GetNumClipModels(); + for ( i = 0; i < n; i++ ) { + ent->GetPhysics()->ClipRotation( t, rotation, pusher->GetPhysics()->GetClipModel( i ) ); + if ( t.fraction < results.fraction ) { + results = t; + } + } + return ( results.fraction < 1.0f ); +} + +/* +============ +idPush::GetPushableEntitiesForRotation +============ +*/ +int idPush::GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags, + const idRotation &rotation, idEntity *entityList[], int maxEntities ) { + int i, n, l; + idBounds bounds, pushBounds; + idPhysics *physics; + + // get bounds for the whole movement + physics = pusher->GetPhysics(); + bounds = physics->GetBounds(); + pushBounds.FromBoundsRotation( bounds, physics->GetOrigin(), physics->GetAxis(), rotation ); + pushBounds.ExpandSelf( 2.0f ); + + // get all entities within the push bounds + n = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); + + for ( l = i = 0; i < n; i++ ) { + if ( entityList[i] == pusher || entityList[i] == initialPusher ) { + continue; + } + if ( CanPushEntity( entityList[i], pusher, initialPusher, flags ) ) { + entityList[l++] = entityList[i]; + } + } + + return l; +} + +/* +============ +idPush::ClipRotationalPush + + Try to push other entities by rotating the given entity. +============ +*/ +float idPush::ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, + const idMat3 &newAxis, const idRotation &rotation ) { + int i, j, numListedEntities; + idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ]; + float fraction; + bool groundContact, blocked = false; + float totalMass; + trace_t trace; + idRotation realRotation, partialRotation; + idMat3 oldAxis; + + totalMass = 0.0f; + + results.fraction = 1.0f; + results.endpos = pusher->GetPhysics()->GetOrigin(); + results.endAxis = newAxis; + memset( results.c, 0, sizeof( results.c ) ); + + if ( !rotation.GetAngle() ) { + return totalMass; + } + + // clip against all non-pushable physics objects + if ( flags & PUSHFL_CLIP ) { + + numListedEntities = GetPushableEntitiesForRotation( pusher, pusher, flags, rotation, entityList, MAX_GENTITIES ); + // disable pushable entities for collision detection + for ( i = 0; i < numListedEntities; i++ ) { + entityList[i]->GetPhysics()->DisableClip(); + } + // clip rotation + pusher->GetPhysics()->ClipRotation( results, rotation, NULL ); + // enable pushable entities + for ( i = 0; i < numListedEntities; i++ ) { + entityList[i]->GetPhysics()->EnableClip(); + } + if ( results.fraction == 0.0f ) { + return totalMass; + } + realRotation = results.fraction * rotation; + } + else { + realRotation = rotation; + } + + // put the pusher in the group of pushed physics objects + pushedGroup[0].ent = pusher; + pushedGroup[0].fraction = 1.0f; + pushedGroup[0].groundContact = true; + pushedGroup[0].test = true; + pushedGroupSize = 1; + + // get all physics objects that need to be pushed + for ( i = 0; i < pushedGroupSize; ) { + if ( !pushedGroup[i].test ) { + i++; + continue; + } + pushedGroup[i].test = false; + curPusher = pushedGroup[i].ent; + fraction = pushedGroup[i].fraction; + groundContact = pushedGroup[i].groundContact; + i = 0; + + numListedEntities = GetPushableEntitiesForRotation( curPusher, pusher, flags, realRotation, entityList, MAX_GENTITIES ); + + for ( j = 0; j < numListedEntities; j++ ) { + ent = entityList[ j ]; + + if ( IsFullyPushed( ent ) ) { + continue; + } + + if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) { + AddEntityToPushedGroup( ent, 1.0f * fraction, false ); + } + else if ( ClipRotationAgainstPusher( trace, ent, curPusher, -fraction * realRotation ) ) { + AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact ); + } + } + } + + // save physics states and disable physics objects for collision detection + for ( i = 1; i < pushedGroupSize; i++ ) { + SaveEntityPosition( pushedGroup[i].ent ); + pushedGroup[i].ent->GetPhysics()->DisableClip(); + } + + // clip all pushed physics objects + for ( i = 1; i < pushedGroupSize; i++ ) { + partialRotation = realRotation * pushedGroup[i].fraction; + + pushedGroup[i].ent->GetPhysics()->ClipRotation( trace, partialRotation, NULL ); + + if ( trace.fraction < 1.0f ) { + blocked = true; + break; + } + } + + // enable all physics objects for collision detection + for ( i = 1; i < pushedGroupSize; i++ ) { + pushedGroup[i].ent->GetPhysics()->EnableClip(); + } + + // push all or nothing + if ( blocked ) { + if ( flags & PUSHFL_CLIP ) { + pusher->GetPhysics()->ClipRotation( results, realRotation, NULL ); + } + else { + results.fraction = 0.0f; + results.endpos = pusher->GetPhysics()->GetOrigin(); + results.endAxis = pusher->GetPhysics()->GetAxis(); + } + } + else { + // rotate all pushed physics objects + for ( i = 1; i < pushedGroupSize; i++ ) { + partialRotation = realRotation * pushedGroup[i].fraction; + pushedGroup[i].ent->GetPhysics()->Rotate( partialRotation ); + totalMass += pushedGroup[i].ent->GetPhysics()->GetMass(); + } + // rotate the clip models of the pusher + for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) { + pusher->GetPhysics()->GetClipModel(i)->Rotate( realRotation ); + pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip ); + pusher->GetPhysics()->GetClipModel(i)->Enable(); + } + // rotate any actors back to axial + for ( i = 1; i < pushedGroupSize; i++ ) { + // if the entity is using actor physics + if ( pushedGroup[i].ent->GetPhysics()->IsType( idPhysics_Actor::Type ) ) { + + // rotate the collision model back to axial + if ( !RotateEntityToAxial( pushedGroup[i].ent, pushedGroup[i].ent->GetPhysics()->GetOrigin() ) ) { + // don't allow rotation if the bbox is no longer axial + results.fraction = 0.0f; + results.endpos = pusher->GetPhysics()->GetOrigin(); + results.endAxis = pusher->GetPhysics()->GetAxis(); + } + } + } + } + + return totalMass; +} + +#else /* !NEW_PUSH */ + +enum { + PUSH_NO, // not pushed + PUSH_OK, // pushed ok + PUSH_BLOCKED // blocked +}; + +/* +============ +idPush::ClipEntityRotation +============ +*/ +void idPush::ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, idClipModel *skip, const idRotation &rotation ) { + + if ( skip ) { + skip->Disable(); + } + + ent->GetPhysics()->ClipRotation( trace, rotation, clipModel ); + + if ( skip ) { + skip->Enable(); + } +} + +/* +============ +idPush::ClipEntityTranslation +============ +*/ +void idPush::ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, idClipModel *skip, const idVec3 &translation ) { + + if ( skip ) { + skip->Disable(); + } + + ent->GetPhysics()->ClipTranslation( trace, translation, clipModel ); + + if ( skip ) { + skip->Enable(); + } +} + +/* +============ +idPush::TryRotatePushEntity +============ +*/ +#ifdef _DEBUG +// #define ROTATIONAL_PUSH_DEBUG +#endif + +int idPush::TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, + const idMat3 &newAxis, const idRotation &rotation ) { + trace_t trace; + idVec3 rotationPoint; + idRotation newRotation; + float checkAngle; + + idPhysics* physics = check->GetPhysics(); + +#ifdef ROTATIONAL_PUSH_DEBUG + bool startsolid = false; + if ( physics->ClipContents( clipModel ) ) { + startsolid = true; + } +#endif + + results.fraction = 1.0f; + results.endpos = clipModel->GetOrigin(); + results.endAxis = newAxis; + memset( &results.c, 0, sizeof( results.c ) ); + + // always pushed when standing on the pusher + if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { + // rotate the entity colliding with all other entities except the pusher itself + ClipEntityRotation( trace, check, NULL, clipModel, rotation ); + // if there is a collision + if ( trace.fraction < 1.0f ) { + // angle along which the entity is pushed + checkAngle = rotation.GetAngle() * trace.fraction; + // test if the entity can stay at it's partly pushed position by rotating + // the entity in reverse only colliding with pusher + newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), -(rotation.GetAngle() - checkAngle) ); + ClipEntityRotation( results, check, clipModel, NULL, newRotation ); + // if there is a collision + if ( results.fraction < 1.0f ) { + + // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? + + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + // the entity will be crushed between the pusher and some other entity + return PUSH_BLOCKED; + } + } + else { + // angle along which the entity is pushed + checkAngle = rotation.GetAngle(); + } + // point to rotate entity bbox around back to axial + rotationPoint = physics->GetOrigin(); + } + else { + // rotate entity in reverse only colliding with pusher + newRotation = rotation; + newRotation.Scale( -1 ); + // + ClipEntityRotation( results, check, clipModel, NULL, newRotation ); + // if no collision with the pusher then the entity is not pushed by the pusher + if ( results.fraction >= 1.0f ) { +#ifdef ROTATIONAL_PUSH_DEBUG + // set pusher into final position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); + if ( physics->ClipContents( clipModel ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + return PUSH_NO; + } + + // greebo: At this point, the pushes knows that the check entity is in the way + // Normally, the pusher tries to rotate the entity to see if the entity itself + // is colliding with anything else, but for players, we want to (optionally) skip that. + if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) + { + // We are colliding with a player and are not allowed to push it, return BLOCKED + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + return PUSH_BLOCKED; + } + + // get point to rotate bbox around back to axial + rotationPoint = results.c.point; + // angle along which the entity will be pushed + checkAngle = rotation.GetAngle() * (1.0f - results.fraction); + // rotate the entity colliding with all other entities except the pusher itself + newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle ); + ClipEntityRotation( trace, check, NULL, clipModel, newRotation ); + // if there is a collision + if ( trace.fraction < 1.0f ) { + + // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? + + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + // the entity will be crushed between the pusher and some other entity + return PUSH_BLOCKED; + } + } + + SaveEntityPosition( check ); + + newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle ); +#ifndef __linux__ + // NOTE: this code prevents msvc 6.0 & 7.0 from screwing up the above code in + // release builds moving less floats than it should + static float shit = checkAngle; +#endif + + newRotation.RotatePoint( rotationPoint ); + + // rotate the entity + physics->Rotate( newRotation ); + + // set pusher into final position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); + +#ifdef ROTATIONAL_PUSH_DEBUG + if ( physics->ClipContents( clipModel ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + + // if the entity uses actor physics + if ( physics->IsType( idPhysics_Actor::Type ) ) { + + // rotate the collision model back to axial + if ( !RotateEntityToAxial( check, rotationPoint ) ) { + // don't allow rotation if the bbox is no longer axial + return PUSH_BLOCKED; + } + } + +#ifdef ROTATIONAL_PUSH_DEBUG + if ( physics->ClipContents( clipModel ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + + // if the entity is an actor using actor physics + if ( check->IsType( idActor::Type ) && physics->IsType( idPhysics_Actor::Type ) ) { + + // if the entity is standing ontop of the pusher + if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { + // rotate actor view + idActor *actor = static_cast(check); + idAngles delta = actor->GetDeltaViewAngles(); + delta.yaw += newRotation.ToMat3()[0].ToYaw(); + actor->SetDeltaViewAngles( delta ); + } + } + + return PUSH_OK; +} + +/* +============ +idPush::TryTranslatePushEntity +============ +*/ +#ifdef _DEBUG +// #define TRANSLATIONAL_PUSH_DEBUG +#endif + +int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, + const idVec3 &newOrigin, const idVec3 &move ) { + trace_t trace; + idVec3 checkMove; + idVec3 oldOrigin; + + idPhysics* physics = check->GetPhysics(); + +#ifdef TRANSLATIONAL_PUSH_DEBUG + bool startsolid = false; + if ( physics->ClipContents( clipModel ) ) { + startsolid = true; + } +#endif + + results.fraction = 1.0f; + results.endpos = newOrigin; + results.endAxis = clipModel->GetAxis(); + memset( &results.c, 0, sizeof( results.c ) ); + + // always pushed when standing on the pusher + if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { + // move the entity colliding with all other entities except the pusher itself + ClipEntityTranslation( trace, check, NULL, clipModel, move ); + // if there is a collision + if ( trace.fraction < 1.0f ) { + // vector along which the entity is pushed + checkMove = move * trace.fraction; + // test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher + ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) ); + // if there is a collision + if ( results.fraction < 1.0f ) { + + // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? + + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + // the entity will be crushed between the pusher and some other entity + return PUSH_BLOCKED; + } + } + else { + // vector along which the entity is pushed + checkMove = move; + } + } + else { + // move entity in reverse only colliding with pusher + ClipEntityTranslation( results, check, clipModel, NULL, -move ); + // if no collision with the pusher then the entity is not pushed by the pusher + if ( results.fraction >= 1.0f ) { + return PUSH_NO; + } + + + // greebo: At this point, the pushes knows that the check entity is in the way + // Normally, the pusher tries to rotate the entity to see if the entity itself + // is colliding with anything else, but for players, we want to (optionally) skip that. + if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) + { + // We are colliding with a player and are not allowed to push it, return BLOCKED + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + return PUSH_BLOCKED; + } + + // vector along which the entity is pushed + checkMove = move * (1.0f - results.fraction); + // move the entity colliding with all other entities except the pusher itself + ClipEntityTranslation( trace, check, NULL, clipModel, checkMove ); + // if there is a collisions + if ( trace.fraction < 1.0f ) { + + results.c.normal = -results.c.normal; + results.c.dist = -results.c.dist; + + // FIXME: try to push the blocking entity as well ? + // FIXME: handle sliding along more than one collision plane ? + // FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map" + +/* + oldOrigin = physics->GetOrigin(); + + // movement still remaining + checkMove *= (1.0f - trace.fraction); + + // project the movement along the collision plane + if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) { + return PUSH_BLOCKED; + } + checkMove *= 1.001f; + + // move entity from collision point along the collision plane + physics->SetOrigin( trace.endpos ); + ClipEntityTranslation( trace, check, NULL, NULL, checkMove ); + + if ( trace.fraction < 1.0f ) { + physics->SetOrigin( oldOrigin ); + return PUSH_BLOCKED; + } + + checkMove = trace.endpos - oldOrigin; + + // move entity in reverse only colliding with pusher + physics->SetOrigin( trace.endpos ); + ClipEntityTranslation( trace, check, clipModel, NULL, -move ); + + physics->SetOrigin( oldOrigin ); +*/ + if ( trace.fraction < 1.0f ) { + return PUSH_BLOCKED; + } + } + } + + SaveEntityPosition( check ); + + // translate the entity + physics->Translate( checkMove ); + +#ifdef TRANSLATIONAL_PUSH_DEBUG + // set the pusher in the translated position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() ); + if ( physics->ClipContents( clipModel ) ) { + if ( !startsolid ) { + int bah = 1; + } + } +#endif + + return PUSH_OK; +} + +/* +============ +idPush::DiscardEntities +============ +*/ +int idPush::DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher ) { + int i, num; + idEntity *check; + + // remove all entities we cannot or should not push from the list + for ( num = i = 0; i < numEntities; i++ ) { + check = entityList[ i ]; + + // if the physics object is not pushable + if ( !check->GetPhysics()->IsPushable() ) { + continue; + } + + // if the entity doesn't clip with this pusher + if ( !( check->GetPhysics()->GetClipMask() & pusher->GetPhysics()->GetContents() ) ) { + continue; + } + + // don't push players in noclip mode + if ( check->IsType( idPlayer::Type ) && static_cast(check)->noclip ) { + continue; + } + + // if we should only push idMoveable entities + if ( ( flags & PUSHFL_ONLYMOVEABLE ) && !check->IsType( idMoveable::Type ) ) { + continue; + } + + // if we shouldn't push entities the clip model rests upon + if ( flags & PUSHFL_NOGROUNDENTITIES ) { + if ( pusher->GetPhysics()->IsGroundEntity( check->entityNumber ) ) { + continue; + } + } + + // keep entity in list + entityList[ num++ ] = entityList[i]; + } + + return num; +} + +/* +============ +idPush::ClipTranslationalPush + + Try to push other entities by moving the given entity. +============ +*/ +float idPush::ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, + const idVec3 &newOrigin, const idVec3 &translation, + float ImpulseMod ) +{ + int i, listedEntities, res; + idEntity *check, *entityList[ MAX_GENTITIES ]; + idBounds bounds, pushBounds; + idVec3 clipMove, clipOrigin, oldOrigin, dir, impulse; + trace_t pushResults; + bool wasEnabled; + float totalMass; + idClipModel *clipModel; + + clipModel = pusher->GetPhysics()->GetClipModel(); + + totalMass = 0.0f; + + results.fraction = 1.0f; + results.endpos = newOrigin; + results.endAxis = clipModel->GetAxis(); + memset( &results.c, 0, sizeof( results.c ) ); + + if ( translation == vec3_origin ) + { + return totalMass; + } + + dir = translation; + dir.Normalize(); + dir.z += 1.0f; + dir *= 10.0f; + + // get bounds for the whole movement + bounds = clipModel->GetBounds(); + if ( bounds[0].x >= bounds[1].x ) + { + return totalMass; + } + pushBounds.FromBoundsTranslation( bounds, clipModel->GetOrigin(), clipModel->GetAxis(), translation ); + + wasEnabled = clipModel->IsEnabled(); + + // make sure we don't get the pushing clip model in the list + clipModel->Disable(); + + listedEntities = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); + + // discard entities we cannot or should not push + listedEntities = DiscardEntities( entityList, listedEntities, flags, pusher ); + + if ( flags & PUSHFL_CLIP ) + { + + // can only clip movement of a trace model + assert( clipModel->IsTraceModel() ); + + // disable to be pushed entities for collision detection + for ( i = 0; i < listedEntities; i++ ) + { + entityList[i]->GetPhysics()->DisableClip(); + } + + gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, clipModel, clipModel->GetAxis(), pusher->GetPhysics()->GetClipMask(), NULL ); + + // enable to be pushed entities for collision detection + for ( i = 0; i < listedEntities; i++ ) + { + entityList[i]->GetPhysics()->EnableClip(); + } + + if ( results.fraction == 0.0f ) + { + if ( wasEnabled ) + { + clipModel->Enable(); + } + return totalMass; + } + + clipMove = results.endpos - clipModel->GetOrigin(); + clipOrigin = results.endpos; + + } + else + { + + clipMove = translation; + clipOrigin = newOrigin; + } + + // we have to enable the clip model because we use it during pushing + clipModel->Enable(); + + // save pusher old position + oldOrigin = clipModel->GetOrigin(); + + // try to push the entities + for ( i = 0; i < listedEntities; i++ ) + { + + check = entityList[ i ]; + + idPhysics *physics = check->GetPhysics(); + + // disable the entity for collision detection + physics->DisableClip(); + + res = TryTranslatePushEntity( pushResults, check, clipModel, flags, clipOrigin, clipMove ); + + // enable the entity for collision detection + physics->EnableClip(); + + // if the entity is pushed + if ( res == PUSH_OK ) + { + // set the pusher in the translated position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() ); + // the entity might be pushed off the ground + physics->EvaluateContacts(); + // put pusher back in old position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), oldOrigin, clipModel->GetAxis() ); + + // wake up this object + if ( flags & PUSHFL_APPLYIMPULSE ) + { + impulse = ImpulseMod * physics->GetMass() * dir; + } else + { + impulse.Zero(); + } + check->ApplyImpulse( clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), impulse ); + + // add mass of pushed entity + totalMass += physics->GetMass(); + } + + // if the entity is not blocking + if ( res != PUSH_BLOCKED ) + { + continue; + } + + // if the blocking entity is a projectile + if ( check->IsType( idProjectile::Type ) ) + { + check->ProcessEvent( &EV_Explode ); + continue; + } + + // if blocking entities should be crushed + if ( flags & PUSHFL_CRUSH ) + { + check->Damage( clipModel->GetEntity(), clipModel->GetEntity(), vec3_origin, "damage_crush", 1.0f, CLIPMODEL_ID_TO_JOINT_HANDLE( pushResults.c.id ) ); + continue; + } + + // if the entity is an active articulated figure and gibs + if ( check->IsType( idAFEntity_Base::Type ) && check->spawnArgs.GetBool( "gib" ) ) + { + if ( static_cast(check)->IsActiveAF() ) + { + check->ProcessEvent( &EV_Gib, "damage_Gib" ); + } + } + + // if the entity is a moveable item and gibs + if ( check->IsType( idMoveableItem::Type ) && check->spawnArgs.GetBool( "gib" ) ) + { + check->ProcessEvent( &EV_Gib, "damage_Gib" ); + } + + // blocked + results = pushResults; + results.fraction = 0.0f; + results.endAxis = clipModel->GetAxis(); + results.endpos = clipModel->GetOrigin(); + results.c.entityNum = check->entityNumber; + results.c.id = 0; + + if ( !wasEnabled ) + { + clipModel->Disable(); + } + + return totalMass; + } + + if ( !wasEnabled ) + { + clipModel->Disable(); + } + + return totalMass; +} + +/* +============ +idPush::ClipRotationalPush + + Try to push other entities by moving the given entity. +============ +*/ +float idPush::ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, + const idMat3 &newAxis, const idRotation &rotation ) { + int i, listedEntities, res; + idEntity *check; + static idEntity* entityList[ MAX_GENTITIES ]; + idBounds bounds, pushBounds; + idRotation clipRotation; + idMat3 clipAxis, oldAxis; + trace_t pushResults; + bool wasEnabled; + float totalMass; + idClipModel *clipModel; + + clipModel = pusher->GetPhysics()->GetClipModel(); + + totalMass = 0.0f; + + results.fraction = 1.0f; + results.endpos = clipModel->GetOrigin(); + results.endAxis = newAxis; + memset( &results.c, 0, sizeof( results.c ) ); + + if ( !rotation.GetAngle() ) { + return totalMass; + } + + // get bounds for the whole movement + bounds = clipModel->GetBounds(); + if ( bounds[0].x >= bounds[1].x ) { + return totalMass; + } + pushBounds.FromBoundsRotation( bounds, clipModel->GetOrigin(), clipModel->GetAxis(), rotation ); + + wasEnabled = clipModel->IsEnabled(); + + // make sure we don't get the pushing clip model in the list + clipModel->Disable(); + + listedEntities = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); + + // discard entities we cannot or should not push + listedEntities = DiscardEntities( entityList, listedEntities, flags, pusher ); + + if ( flags & PUSHFL_CLIP ) { + + // can only clip movement of a trace model + assert( clipModel->IsTraceModel() ); + + // disable to be pushed entities for collision detection + for ( i = 0; i < listedEntities; i++ ) { + entityList[i]->GetPhysics()->DisableClip(); + } + + gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, clipModel, clipModel->GetAxis(), pusher->GetPhysics()->GetClipMask(), NULL ); + + // enable to be pushed entities for collision detection + for ( i = 0; i < listedEntities; i++ ) { + entityList[i]->GetPhysics()->EnableClip(); + } + + if ( results.fraction == 0.0f ) { + if ( wasEnabled ) { + clipModel->Enable(); + } + return totalMass; + } + + clipRotation = rotation * results.fraction; + clipAxis = results.endAxis; + } + else { + + clipRotation = rotation; + clipAxis = newAxis; + } + + // we have to enable the clip model because we use it during pushing + clipModel->Enable(); + + // save pusher old position + oldAxis = clipModel->GetAxis(); + + // try to push all the entities + for ( i = 0; i < listedEntities; i++ ) { + + check = entityList[ i ]; + + idPhysics *physics = check->GetPhysics(); + + // disable the entity for collision detection + physics->DisableClip(); + + res = TryRotatePushEntity( pushResults, check, clipModel, flags, clipAxis, clipRotation ); + + // enable the entity for collision detection + physics->EnableClip(); + + // if the entity is pushed + if ( res == PUSH_OK ) { + // set the pusher in the rotated position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); + // the entity might be pushed off the ground + physics->EvaluateContacts(); + // put pusher back in old position + clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), oldAxis ); + + // wake up this object + check->ApplyImpulse( clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), vec3_origin ); + + // add mass of pushed entity + totalMass += physics->GetMass(); + } + + // if the entity is not blocking + if ( res != PUSH_BLOCKED ) { + continue; + } + + // if the blocking entity is a projectile + if ( check->IsType( idProjectile::Type ) ) { + check->ProcessEvent( &EV_Explode ); + continue; + } + + // if blocking entities should be crushed + if ( flags & PUSHFL_CRUSH ) { + check->Damage( clipModel->GetEntity(), clipModel->GetEntity(), vec3_origin, "damage_crush", 1.0f, CLIPMODEL_ID_TO_JOINT_HANDLE( pushResults.c.id ) ); + continue; + } + + // if the entity is an active articulated figure and gibs + if ( check->IsType( idAFEntity_Base::Type ) && check->spawnArgs.GetBool( "gib" ) ) { + if ( static_cast(check)->IsActiveAF() ) { + check->ProcessEvent( &EV_Gib, "damage_Gib" ); + } + } + + // blocked + results = pushResults; + results.fraction = 0.0f; + results.endAxis = clipModel->GetAxis(); + results.endpos = clipModel->GetOrigin(); + results.c.entityNum = check->entityNumber; + results.c.id = 0; + + if ( !wasEnabled ) { + clipModel->Disable(); + } + + return totalMass; + } + + if ( !wasEnabled ) { + clipModel->Disable(); + } + + return totalMass; +} + +#endif /* !NEW_PUSH */ + + +/* +============ +idPush::ClipPush + + Try to push other entities by moving the given entity. +============ +*/ +float idPush::ClipPush( trace_t &results, idEntity *pusher, const int flags, + const idVec3 &oldOrigin, const idMat3 &oldAxis, + idVec3 &newOrigin, idMat3 &newAxis ) { + idVec3 translation; + idRotation rotation; + float mass; + + mass = 0.0f; + + results.fraction = 1.0f; + results.endpos = newOrigin; + results.endAxis = newAxis; + memset( &results.c, 0, sizeof( results.c ) ); + + // translational push + translation = newOrigin - oldOrigin; + + // if the pusher translates + if ( translation != vec3_origin ) { + + mass += ClipTranslationalPush( results, pusher, flags, newOrigin, translation ); + if ( results.fraction < 1.0f ) { + newOrigin = oldOrigin; + newAxis = oldAxis; + return mass; + } + } else { + newOrigin = oldOrigin; + } + + // rotational push + rotation = ( oldAxis.Transpose() * newAxis ).ToRotation(); + rotation.SetOrigin( newOrigin ); + rotation.Normalize180(); + rotation.ReCalculateMatrix(); // recalculate the rotation matrix to avoid accumulating rounding errors + + // if the pusher rotates + if ( rotation.GetAngle() != 0.0f ) { + + // recalculate new axis to avoid floating point rounding problems + newAxis = oldAxis * rotation.ToMat3(); + newAxis.OrthoNormalizeSelf(); + newAxis.FixDenormals(); + newAxis.FixDegeneracies(); + + pusher->GetPhysics()->GetClipModel()->SetPosition( newOrigin, oldAxis ); + + mass += ClipRotationalPush( results, pusher, flags, newAxis, rotation ); + if ( results.fraction < 1.0f ) { + newOrigin = oldOrigin; + newAxis = oldAxis; + return mass; + } + } else { + newAxis = oldAxis; + } + + return mass; +} diff --git a/game/physics/Push.h b/game/physics/Push.h new file mode 100644 index 000000000..5d1cb4b56 --- /dev/null +++ b/game/physics/Push.h @@ -0,0 +1,105 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PUSH_H__ +#define __PUSH_H__ + +/* +=============================================================================== + + Allows physics objects to be pushed geometrically. + +=============================================================================== +*/ + +#define PUSHFL_ONLYMOVEABLE 1 // only push moveable entities +#define PUSHFL_NOGROUNDENTITIES 2 // don't push entities the clip model rests upon +#define PUSHFL_CLIP 4 // also clip against all non-moveable entities +#define PUSHFL_CRUSH 8 // kill blocking entities +#define PUSHFL_APPLYIMPULSE 16 // apply impulse to pushed entities +#define PUSHFL_NOPLAYER 32 // greebo: Don't push player entities + +//#define NEW_PUSH + +class idPush { +public: + // Try to push other entities by moving the given entity. + // If results.fraction < 1.0 the move was blocked by results.c.entityNum + // Returns total mass of all pushed entities. + float ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, + const idVec3 &newOrigin, const idVec3 &move, float ImpulseMod = 1.0f ); + + float ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, + const idMat3 &newAxis, const idRotation &rotation ); + + float ClipPush( trace_t &results, idEntity *pusher, const int flags, + const idVec3 &oldOrigin, const idMat3 &oldAxis, + idVec3 &newOrigin, idMat3 &newAxis ); + + // initialize saving the positions of entities being pushed + void InitSavingPushedEntityPositions( void ); + // move all pushed entities back to their previous position + void RestorePushedEntityPositions( void ); + // returns the number of pushed entities + int GetNumPushedEntities( void ) const { return numPushed; } + // get the ith pushed entity + idEntity * GetPushedEntity( int i ) const { assert( i >= 0 && i < numPushed ); return pushed[i].ent; } + +private: + struct pushed_s { + idEntity * ent; // pushed entity + idAngles deltaViewAngles; // actor delta view angles + } pushed[MAX_GENTITIES]; // pushed entities + int numPushed; // number of pushed entities + + struct pushedGroup_s { + idEntity * ent; + float fraction; + bool groundContact; + bool test; + } pushedGroup[MAX_GENTITIES]; + int pushedGroupSize; + +private: + void SaveEntityPosition( idEntity *ent ); + bool RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint ); +#ifdef NEW_PUSH + bool CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags ); + void AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact ); + bool IsFullyPushed( idEntity *ent ); + bool ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation ); + int GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags, + const idVec3 &translation, idEntity *entityList[], int maxEntities ); + bool ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation ); + int GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags, + const idRotation &rotation, idEntity *entityList[], int maxEntities ); +#else + void ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, + idClipModel *skip, const idRotation &rotation ); + void ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, + idClipModel *skip, const idVec3 &translation ); + int TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, + const idVec3 &newOrigin, const idVec3 &move ); + int TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, + const idMat3 &newAxis, const idRotation &rotation ); + int DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher ); +#endif +}; + +#endif /* !__PUSH_H__ */ diff --git a/game/physics/clip.cpp b/game/physics/clip.cpp deleted file mode 100644 index af0189b33..000000000 --- a/game/physics/clip.cpp +++ /dev/null @@ -1,1671 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#define MAX_SECTOR_DEPTH 12 -#define MAX_SECTORS ((1<<(MAX_SECTOR_DEPTH+1))-1) - -typedef struct clipSector_s { - int axis; // -1 = leaf node - float dist; - struct clipSector_s * children[2]; - struct clipLink_s * clipLinks; -} clipSector_t; - -typedef struct clipLink_s { - idClipModel * clipModel; - struct clipSector_s * sector; - struct clipLink_s * prevInSector; - struct clipLink_s * nextInSector; - struct clipLink_s * nextLink; -} clipLink_t; - -typedef struct trmCache_s { - idTraceModel trm; - int refCount; - float volume; - idVec3 centerOfMass; - idMat3 inertiaTensor; -} trmCache_t; - -idVec3 vec3_boxEpsilon( CM_BOX_EPSILON, CM_BOX_EPSILON, CM_BOX_EPSILON ); - -idBlockAlloc clipLinkAllocator; - - -/* -=============================================================== - - idClipModel trace model cache - -=============================================================== -*/ - -static idList traceModelCache; -static idHashIndex traceModelHash; - -/* -=============== -idClipModel::ClearTraceModelCache -=============== -*/ -void idClipModel::ClearTraceModelCache( void ) { - traceModelCache.DeleteContents( true ); - traceModelHash.Free(); -} - -/* -=============== -idClipModel::TraceModelCacheSize -=============== -*/ -int idClipModel::TraceModelCacheSize( void ) { - return traceModelCache.Num() * sizeof( idTraceModel ); -} - -/* -=============== -idClipModel::AllocTraceModel -=============== -*/ -int idClipModel::AllocTraceModel( const idTraceModel &trm ) { - int i, hashKey, traceModelIndex; - trmCache_t *entry; - - hashKey = GetTraceModelHashKey( trm ); - for ( i = traceModelHash.First( hashKey ); i >= 0; i = traceModelHash.Next( i ) ) { - if ( traceModelCache[i]->trm == trm ) { - traceModelCache[i]->refCount++; - return i; - } - } - - entry = new trmCache_t; - entry->trm = trm; - - // If density is 1 the volume has the same size as the mass (m = d*v). The calling code wants to know the volume, - // and with density equal to 1 it's allowed to use the mass value returned by idTraceModel::GetMassProperties(). - // That's what's happening here. - entry->trm.GetMassProperties( 1.0f, entry->volume, entry->centerOfMass, entry->inertiaTensor ); - entry->refCount = 1; - - traceModelIndex = traceModelCache.Append( entry ); - traceModelHash.Add( hashKey, traceModelIndex ); - return traceModelIndex; -} - -/* -=============== -idClipModel::FreeTraceModel -=============== -*/ -void idClipModel::FreeTraceModel( const int traceModelIndex ) { - if ( traceModelIndex < 0 || traceModelIndex >= traceModelCache.Num() ) { - gameLocal.Warning( "idClipModel::FreeTraceModel: traceModelIndex %i out of range (0..%i)", traceModelIndex, traceModelCache.Num() ); - return; - } - if ( traceModelCache[traceModelIndex]->refCount <= 0 ) { - gameLocal.Warning( "idClipModel::FreeTraceModel: tried to free uncached trace model (index=%i)", traceModelIndex ); - return; - } - traceModelCache[traceModelIndex]->refCount--; -} - -/* -=============== -idClipModel::GetCachedTraceModel -=============== -*/ -idTraceModel *idClipModel::GetCachedTraceModel( int traceModelIndex ) { - return &traceModelCache[traceModelIndex]->trm; -} - -/* -=============== -idClipModel::GetTraceModelHashKey -=============== -*/ -int idClipModel::GetTraceModelHashKey( const idTraceModel &trm ) { - const idVec3 &v = trm.bounds[0]; - return ( trm.type << 8 ) ^ ( trm.numVerts << 4 ) ^ ( trm.numEdges << 2 ) ^ ( trm.numPolys << 0 ) ^ idMath::FloatHash( v.ToFloatPtr(), v.GetDimension() ); -} - -/* -=============== -idClipModel::SaveTraceModels -=============== -*/ -void idClipModel::SaveTraceModels( idSaveGame *savefile ) { - int i; - - savefile->WriteInt( traceModelCache.Num() ); - for ( i = 0; i < traceModelCache.Num(); i++ ) { - trmCache_t *entry = traceModelCache[i]; - - savefile->WriteTraceModel( entry->trm ); - savefile->WriteFloat( entry->volume ); - savefile->WriteVec3( entry->centerOfMass ); - savefile->WriteMat3( entry->inertiaTensor ); - } -} - -/* -=============== -idClipModel::RestoreTraceModels -=============== -*/ -void idClipModel::RestoreTraceModels( idRestoreGame *savefile ) { - int i, num; - - ClearTraceModelCache(); - - savefile->ReadInt( num ); - traceModelCache.SetNum( num ); - - for ( i = 0; i < num; i++ ) { - trmCache_t *entry = new trmCache_t; - - savefile->ReadTraceModel( entry->trm ); - - savefile->ReadFloat( entry->volume ); - savefile->ReadVec3( entry->centerOfMass ); - savefile->ReadMat3( entry->inertiaTensor ); - entry->refCount = 0; - - traceModelCache[i] = entry; - traceModelHash.Add( GetTraceModelHashKey( entry->trm ), i ); - } -} - - -/* -=============================================================== - - idClipModel - -=============================================================== -*/ - -/* -================ -idClipModel::LoadModel -================ -*/ -bool idClipModel::LoadModel( const char *name ) { - renderModelHandle = -1; - if ( traceModelIndex != -1 ) { - FreeTraceModel( traceModelIndex ); - traceModelIndex = -1; - } - collisionModelHandle = collisionModelManager->LoadModel( name, false ); - if ( collisionModelHandle ) { - collisionModelManager->GetModelBounds( collisionModelHandle, bounds ); - collisionModelManager->GetModelContents( collisionModelHandle, contents ); - return true; - } else { - bounds.Zero(); - return false; - } -} - -/* -================ -idClipModel::LoadModel -================ -*/ -void idClipModel::LoadModel( const idTraceModel &trm ) { - collisionModelHandle = 0; - renderModelHandle = -1; - if ( traceModelIndex != -1 ) { - FreeTraceModel( traceModelIndex ); - } - traceModelIndex = AllocTraceModel( trm ); - bounds = trm.bounds; -} - -/* -================ -idClipModel::LoadModel -================ -*/ -void idClipModel::LoadModel( const int renderModelHandle ) { - collisionModelHandle = 0; - this->renderModelHandle = renderModelHandle; - if ( renderModelHandle != -1 ) { - const renderEntity_t *renderEntity = gameRenderWorld->GetRenderEntity( renderModelHandle ); - if ( renderEntity ) { - bounds = renderEntity->bounds; - } - } - if ( traceModelIndex != -1 ) { - FreeTraceModel( traceModelIndex ); - traceModelIndex = -1; - } -} - -/* -================ -idClipModel::Init -================ -*/ -void idClipModel::Init( void ) { - enabled = true; - entity = NULL; - id = 0; - owner = NULL; - origin.Zero(); - axis.Identity(); - bounds.Zero(); - absBounds.Zero(); - material = NULL; - contents = CONTENTS_BODY; - collisionModelHandle = 0; - renderModelHandle = -1; - traceModelIndex = -1; - clipLinks = NULL; - touchCount = -1; -} - -/* -================ -idClipModel::idClipModel -================ -*/ -idClipModel::idClipModel( void ) { - Init(); -} - -/* -================ -idClipModel::idClipModel -================ -*/ -idClipModel::idClipModel( const char *name ) { - Init(); - LoadModel( name ); -} - -/* -================ -idClipModel::idClipModel -================ -*/ -idClipModel::idClipModel( const idTraceModel &trm ) { - Init(); - LoadModel( trm ); -} - -/* -================ -idClipModel::idClipModel -================ -*/ -idClipModel::idClipModel( const int renderModelHandle ) { - Init(); - contents = CONTENTS_RENDERMODEL; - LoadModel( renderModelHandle ); -} - -/* -================ -idClipModel::idClipModel -================ -*/ -idClipModel::idClipModel( const idClipModel *model ) { - enabled = model->enabled; - entity = model->entity; - id = model->id; - owner = model->owner; - origin = model->origin; - axis = model->axis; - bounds = model->bounds; - absBounds = model->absBounds; - material = model->material; - contents = model->contents; - collisionModelHandle = model->collisionModelHandle; - traceModelIndex = -1; - if ( model->traceModelIndex != -1 ) { - LoadModel( *GetCachedTraceModel( model->traceModelIndex ) ); - } - renderModelHandle = model->renderModelHandle; - clipLinks = NULL; - touchCount = -1; -} - -/* -================ -idClipModel::~idClipModel -================ -*/ -idClipModel::~idClipModel( void ) { - // make sure the clip model is no longer linked - Unlink(); - if ( traceModelIndex != -1 ) { - FreeTraceModel( traceModelIndex ); - } -} - -/* -================ -idClipModel::Save -================ -*/ -void idClipModel::Save( idSaveGame *savefile ) const { - savefile->WriteBool( enabled ); - savefile->WriteObject( entity ); - savefile->WriteInt( id ); - savefile->WriteObject( owner ); - savefile->WriteVec3( origin ); - savefile->WriteMat3( axis ); - savefile->WriteBounds( bounds ); - savefile->WriteBounds( absBounds ); - savefile->WriteMaterial( material ); - savefile->WriteInt( contents ); - if ( collisionModelHandle >= 0 ) { - savefile->WriteString( collisionModelManager->GetModelName( collisionModelHandle ) ); - } else { - savefile->WriteString( "" ); - } - savefile->WriteInt( traceModelIndex ); - savefile->WriteBool( clipLinks != NULL ); - savefile->WriteInt( touchCount ); -} - -/* -================ -idClipModel::Restore -================ -*/ -void idClipModel::Restore( idRestoreGame *savefile ) { - idStr collisionModelName; - bool linked; - - savefile->ReadBool( enabled ); - savefile->ReadObject( reinterpret_cast( entity ) ); - savefile->ReadInt( id ); - savefile->ReadObject( reinterpret_cast( owner ) ); - savefile->ReadVec3( origin ); - savefile->ReadMat3( axis ); - savefile->ReadBounds( bounds ); - savefile->ReadBounds( absBounds ); - savefile->ReadMaterial( material ); - savefile->ReadInt( contents ); - savefile->ReadString( collisionModelName ); - if ( collisionModelName.Length() ) { - collisionModelHandle = collisionModelManager->LoadModel( collisionModelName, false ); - } else { - collisionModelHandle = -1; - } - savefile->ReadInt( traceModelIndex ); - if ( traceModelIndex >= 0 ) { - traceModelCache[traceModelIndex]->refCount++; - } - savefile->ReadBool( linked ); - savefile->ReadInt( touchCount ); - - // the render model will be set when the clip model is linked, so do not restore it - renderModelHandle = -1; - clipLinks = NULL; - touchCount = -1; - - if ( linked ) { - Link( gameLocal.clip, entity, id, origin, axis, renderModelHandle ); - } -} - -/* -================ -idClipModel::SetPosition -================ -*/ -void idClipModel::SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ) { - if ( clipLinks ) { - Unlink(); // unlink from old position - } - origin = newOrigin; - axis = newAxis; -} - -/* -================ -idClipModel::Handle -================ -*/ -cmHandle_t idClipModel::Handle( void ) const { - assert( renderModelHandle == -1 ); - if ( collisionModelHandle ) { - return collisionModelHandle; - } else if ( traceModelIndex != -1 ) { - return collisionModelManager->SetupTrmModel( *GetCachedTraceModel( traceModelIndex ), material ); - } else { - // this happens in multiplayer on the combat models - gameLocal.Warning( "idClipModel::Handle: clip model %d on '%s' (%x) is not a collision or trace model", id, entity->name.c_str(), entity->entityNumber ); - return 0; - } -} - -/* -================ -idClipModel::GetMassProperties -================ -*/ -void idClipModel::GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const { - if ( traceModelIndex == -1 ) { - gameLocal.Error( "idClipModel::GetMassProperties: clip model %d on '%s' is not a trace model\n", id, entity->name.c_str() ); - } - - trmCache_t *entry = traceModelCache[traceModelIndex]; - mass = entry->volume * density; - centerOfMass = entry->centerOfMass; - inertiaTensor = density * entry->inertiaTensor; -} - -/* -=============== -idClipModel::Unlink -=============== -*/ -void idClipModel::Unlink( void ) { - clipLink_t *link; - - for ( link = clipLinks; link; link = clipLinks ) { - clipLinks = link->nextLink; - if ( link->prevInSector ) { - link->prevInSector->nextInSector = link->nextInSector; - } else { - link->sector->clipLinks = link->nextInSector; - } - if ( link->nextInSector ) { - link->nextInSector->prevInSector = link->prevInSector; - } - clipLinkAllocator.Free( link ); - } -} - -/* -=============== -idClipModel::Link_r -=============== -*/ -void idClipModel::Link_r( struct clipSector_s *node ) { - clipLink_t *link; - - while( node->axis != -1 ) { - if ( absBounds[0][node->axis] > node->dist ) { - node = node->children[0]; - } else if ( absBounds[1][node->axis] < node->dist ) { - node = node->children[1]; - } else { - Link_r( node->children[0] ); - node = node->children[1]; - } - } - - link = clipLinkAllocator.Alloc(); - link->clipModel = this; - link->sector = node; - link->nextInSector = node->clipLinks; - link->prevInSector = NULL; - if ( node->clipLinks ) { - node->clipLinks->prevInSector = link; - } - node->clipLinks = link; - link->nextLink = clipLinks; - clipLinks = link; -} - -/* -=============== -idClipModel::Link -=============== -*/ -void idClipModel::Link( idClip &clp ) { - - assert( idClipModel::entity ); - if ( !idClipModel::entity ) { - return; - } - - if ( clipLinks ) { - Unlink(); // unlink from old position - } - - if ( bounds.IsCleared() ) { - return; - } - - // set the abs box - if ( axis.IsRotated() ) { - // expand for rotation - absBounds.FromTransformedBounds( bounds, origin, axis ); - } else { - // normal - absBounds[0] = bounds[0] + origin; - absBounds[1] = bounds[1] + origin; - } - - // because movement is clipped an epsilon away from an actual edge, - // we must fully check even when bounding boxes don't quite touch - absBounds[0] -= vec3_boxEpsilon; - absBounds[1] += vec3_boxEpsilon; - - Link_r( clp.clipSectors ); -} - -/* -=============== -idClipModel::Link -=============== -*/ -void idClipModel::Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle ) { - - this->entity = ent; - this->id = newId; - this->origin = newOrigin; - this->axis = newAxis; - if ( renderModelHandle != -1 ) { - this->renderModelHandle = renderModelHandle; - const renderEntity_t *renderEntity = gameRenderWorld->GetRenderEntity( renderModelHandle ); - if ( renderEntity ) { - this->bounds = renderEntity->bounds; - } - } - this->Link( clp ); -} - -/* -============ -idClipModel::CheckModel -============ -*/ -cmHandle_t idClipModel::CheckModel( const char *name ) { - return collisionModelManager->LoadModel( name, false ); -} - - -/* -=============================================================== - - idClip - -=============================================================== -*/ - -/* -=============== -idClip::idClip -=============== -*/ -idClip::idClip( void ) { - numClipSectors = 0; - clipSectors = NULL; - worldBounds.Zero(); - numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; -} - -/* -=============== -idClip::CreateClipSectors_r - -Builds a uniformly subdivided tree for the given world size -=============== -*/ -clipSector_t *idClip::CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector ) { - int i; - clipSector_t *anode; - idVec3 size; - idBounds front, back; - - anode = &clipSectors[idClip::numClipSectors]; - idClip::numClipSectors++; - - if ( depth == MAX_SECTOR_DEPTH ) { - anode->axis = -1; - anode->children[0] = anode->children[1] = NULL; - - for ( i = 0; i < 3; i++ ) { - if ( bounds[1][i] - bounds[0][i] > maxSector[i] ) { - maxSector[i] = bounds[1][i] - bounds[0][i]; - } - } - return anode; - } - - size = bounds[1] - bounds[0]; - if ( size[0] >= size[1] && size[0] >= size[2] ) { - anode->axis = 0; - } else if ( size[1] >= size[0] && size[1] >= size[2] ) { - anode->axis = 1; - } else { - anode->axis = 2; - } - - anode->dist = 0.5f * ( bounds[1][anode->axis] + bounds[0][anode->axis] ); - - front = bounds; - back = bounds; - - front[0][anode->axis] = back[1][anode->axis] = anode->dist; - - anode->children[0] = CreateClipSectors_r( depth+1, front, maxSector ); - anode->children[1] = CreateClipSectors_r( depth+1, back, maxSector ); - - return anode; -} - -/* -=============== -idClip::Init -=============== -*/ -void idClip::Init( void ) { - cmHandle_t h; - idVec3 size, maxSector = vec3_origin; - - // clear clip sectors - clipSectors = new clipSector_t[MAX_SECTORS]; - memset( clipSectors, 0, MAX_SECTORS * sizeof( clipSector_t ) ); - numClipSectors = 0; - touchCount = -1; - // get world map bounds - h = collisionModelManager->LoadModel( "worldMap", false ); - collisionModelManager->GetModelBounds( h, worldBounds ); - // create world sectors - CreateClipSectors_r( 0, worldBounds, maxSector ); - - size = worldBounds[1] - worldBounds[0]; - gameLocal.Printf( "map bounds are (%1.1f, %1.1f, %1.1f)\n", size[0], size[1], size[2] ); - gameLocal.Printf( "max clip sector is (%1.1f, %1.1f, %1.1f)\n", maxSector[0], maxSector[1], maxSector[2] ); - - // initialize a default clip model - defaultClipModel.LoadModel( idTraceModel( idBounds( idVec3( 0, 0, 0 ) ).Expand( 8 ) ) ); - - // set counters to zero - numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; -} - -/* -=============== -idClip::Shutdown -=============== -*/ -void idClip::Shutdown( void ) { - delete[] clipSectors; - clipSectors = NULL; - - // free the trace model used for the temporaryClipModel - if ( temporaryClipModel.traceModelIndex != -1 ) { - idClipModel::FreeTraceModel( temporaryClipModel.traceModelIndex ); - temporaryClipModel.traceModelIndex = -1; - } - - // free the trace model used for the defaultClipModel - if ( defaultClipModel.traceModelIndex != -1 ) { - idClipModel::FreeTraceModel( defaultClipModel.traceModelIndex ); - defaultClipModel.traceModelIndex = -1; - } - - clipLinkAllocator.Shutdown(); -} - -/* -==================== -idClip::ClipModelsTouchingBounds_r -==================== -*/ -typedef struct listParms_s { - idBounds bounds; - int contentMask; - idClipModel ** list; - int count; - int maxCount; -} listParms_t; - -void idClip::ClipModelsTouchingBounds_r( const struct clipSector_s *node, listParms_t &parms ) const { - - while( node->axis != -1 ) { - if ( parms.bounds[0][node->axis] > node->dist ) { - node = node->children[0]; - } else if ( parms.bounds[1][node->axis] < node->dist ) { - node = node->children[1]; - } else { - ClipModelsTouchingBounds_r( node->children[0], parms ); - node = node->children[1]; - } - } - - for ( clipLink_t *link = node->clipLinks; link; link = link->nextInSector ) { - idClipModel *check = link->clipModel; - - // if the clip model is enabled - if ( !check->enabled ) { - continue; - } - - // avoid duplicates in the list - if ( check->touchCount == touchCount ) { - continue; - } - - // if the clip model does not have any contents we are looking for - if ( !( check->contents & parms.contentMask ) ) { - continue; - } - - // if the bounds really do overlap - if ( check->absBounds[0][0] > parms.bounds[1][0] || - check->absBounds[1][0] < parms.bounds[0][0] || - check->absBounds[0][1] > parms.bounds[1][1] || - check->absBounds[1][1] < parms.bounds[0][1] || - check->absBounds[0][2] > parms.bounds[1][2] || - check->absBounds[1][2] < parms.bounds[0][2] ) { - continue; - } - - if ( parms.count >= parms.maxCount ) { - gameLocal.Warning( "idClip::ClipModelsTouchingBounds_r: max count (%i) reached", parms.maxCount ); - return; - } - - check->touchCount = touchCount; - parms.list[parms.count] = check; - parms.count++; - } -} - -/* -================ -idClip::ClipModelsTouchingBounds -================ -*/ -int idClip::ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const { - listParms_t parms; - - if ( bounds[0][0] > bounds[1][0] || - bounds[0][1] > bounds[1][1] || - bounds[0][2] > bounds[1][2] ) { - // we should not go through the tree for degenerate or backwards bounds - assert( false ); - return 0; - } - - parms.bounds[0] = bounds[0] - vec3_boxEpsilon; - parms.bounds[1] = bounds[1] + vec3_boxEpsilon; - parms.contentMask = contentMask; - parms.list = clipModelList; - parms.count = 0; - parms.maxCount = maxCount; - - touchCount++; - ClipModelsTouchingBounds_r( clipSectors, parms ); - - return parms.count; -} - -/* -================ -idClip::EntitiesTouchingBounds -================ -*/ -int idClip::EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const { - idClipModel *clipModelList[MAX_GENTITIES]; - int i, j, count, entCount; - - count = idClip::ClipModelsTouchingBounds( bounds, contentMask, clipModelList, MAX_GENTITIES ); - entCount = 0; - for ( i = 0; i < count; i++ ) { - // entity could already be in the list because an entity can use multiple clip models - for ( j = 0; j < entCount; j++ ) { - if ( entityList[j] == clipModelList[i]->entity ) { - break; - } - } - if ( j >= entCount ) { - if ( entCount >= maxCount ) { - gameLocal.Warning( "idClip::EntitiesTouchingBounds: max count (%i) reached.", maxCount ); - return entCount; - } - entityList[entCount] = clipModelList[i]->entity; - entCount++; - } - } - - return entCount; -} - -/* -==================== -idClip::GetTraceClipModels - - an ent will be excluded from testing if: - cm->entity == passEntity ( don't clip against the pass entity ) - cm->entity == passOwner ( missiles don't clip with owner ) - cm->owner == passEntity ( don't interact with your own missiles ) - cm->owner == passOwner ( don't interact with other missiles from same owner ) -==================== -*/ -int idClip::GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const { - int i, num; - idClipModel *cm; - idEntity *passOwner; - - num = ClipModelsTouchingBounds( bounds, contentMask, clipModelList, MAX_GENTITIES ); - - if ( !passEntity ) { - return num; - } - - if ( passEntity->GetPhysics()->GetNumClipModels() > 0 ) { - passOwner = passEntity->GetPhysics()->GetClipModel()->GetOwner(); - } else { - passOwner = NULL; - } - - for ( i = 0; i < num; i++ ) { - - cm = clipModelList[i]; - - // check if we should ignore this entity - if ( cm->entity == passEntity ) { - clipModelList[i] = NULL; // don't clip against the pass entity - } else if ( cm->entity == passOwner ) { - clipModelList[i] = NULL; // missiles don't clip with their owner - } else if ( cm->owner ) { - if ( cm->owner == passEntity ) { - clipModelList[i] = NULL; // don't clip against own missiles - } else if ( cm->owner == passOwner ) { - clipModelList[i] = NULL; // don't clip against other missiles from same owner - } - } - } - - return num; -} - -/* -============ -idClip::TraceRenderModel -============ -*/ -void idClip::TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const { - trace.fraction = 1.0f; - - // if the trace is passing through the bounds - if ( touch->absBounds.Expand( radius ).LineIntersection( start, end ) ) { - modelTrace_t modelTrace; - - // test with exact render model and modify trace_t structure accordingly - if ( gameRenderWorld->ModelTrace( modelTrace, touch->renderModelHandle, start, end, radius ) ) { - trace.fraction = modelTrace.fraction; - trace.endAxis = axis; - trace.endpos = modelTrace.point; - trace.c.normal = modelTrace.normal; - trace.c.dist = modelTrace.point * modelTrace.normal; - trace.c.point = modelTrace.point; - trace.c.type = CONTACT_TRMVERTEX; - trace.c.modelFeature = 0; - trace.c.trmFeature = 0; - trace.c.contents = modelTrace.material->GetContentFlags(); - trace.c.material = modelTrace.material; - // NOTE: trace.c.id will be the joint number - touch->id = JOINT_HANDLE_TO_CLIPMODEL_ID( modelTrace.jointNumber ); - } - } -} - -/* -============ -idClip::TraceModelForClipModel -============ -*/ -const idTraceModel *idClip::TraceModelForClipModel( const idClipModel *mdl ) const { - if ( !mdl ) { - return NULL; - } else { - if ( !mdl->IsTraceModel() ) { - if ( mdl->GetEntity() ) { - gameLocal.Error( "TraceModelForClipModel: clip model %d on '%s' is not a trace model\n", mdl->GetId(), mdl->GetEntity()->name.c_str() ); - } else { - gameLocal.Error( "TraceModelForClipModel: clip model %d is not a trace model\n", mdl->GetId() ); - } - } - return idClipModel::GetCachedTraceModel( mdl->traceModelIndex ); - } -} - -/* -============ -idClip::TestHugeTranslation -============ -*/ -ID_INLINE bool TestHugeTranslation( trace_t &results, const idClipModel *mdl, const idVec3 &start, const idVec3 &end, const idMat3 &trmAxis ) { - if ( mdl != NULL && ( end - start ).LengthSqr() > Square( CM_MAX_TRACE_DIST ) ) { -// assert( 0 ); - - results.fraction = 0.0f; - results.endpos = start; - results.endAxis = trmAxis; - memset( &results.c, 0, sizeof( results.c ) ); - results.c.point = start; - results.c.entityNum = ENTITYNUM_WORLD; - - if ( mdl->GetEntity() ) { - gameLocal.Printf( "huge translation for clip model %d on entity %d '%s'\n", mdl->GetId(), mdl->GetEntity()->entityNumber, mdl->GetEntity()->GetName() ); - } else { - gameLocal.Printf( "huge translation for clip model %d\n", mdl->GetId() ); - } - return true; - } - return false; -} - -/* -============ -idClip::TranslationEntities -============ -*/ -void idClip::TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, num; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idBounds traceBounds; - float radius; - trace_t trace; - const idTraceModel *trm; - - if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { - return; - } - - trm = TraceModelForClipModel( mdl ); - - results.fraction = 1.0f; - results.endpos = end; - results.endAxis = trmAxis; - - if ( !trm ) { - traceBounds.FromPointTranslation( start, end - start ); - radius = 0.0f; - } else { - traceBounds.FromBoundsTranslation( trm->bounds, start, trmAxis, end - start ); - radius = trm->bounds.GetRadius(); - } - - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - if ( touch->renderModelHandle != -1 ) { - idClip::numRenderModelTraces++; - TraceRenderModel( trace, start, end, radius, trmAxis, touch ); - } else { - idClip::numTranslations++; - collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - } - - if ( trace.fraction < results.fraction ) { - results = trace; - results.c.entityNum = touch->entity->entityNumber; - results.c.id = touch->id; - if ( results.fraction == 0.0f ) { - break; - } - } - } -} - -/* -============ -idClip::Translation -============ -*/ -bool idClip::Translation( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, num; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idBounds traceBounds; - float radius; - trace_t trace; - const idTraceModel *trm; - - if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { - return true; - } - - trm = TraceModelForClipModel( mdl ); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // test world - idClip::numTranslations++; - collisionModelManager->Translation( &results, start, end, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - results.c.entityNum = results.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; - if ( results.fraction == 0.0f ) { - return true; // blocked immediately by the world - } - } else { - memset( &results, 0, sizeof( results ) ); - results.fraction = 1.0f; - results.endpos = end; - results.endAxis = trmAxis; - } - - if ( !trm ) { - traceBounds.FromPointTranslation( start, results.endpos - start ); - radius = 0.0f; - } else { - traceBounds.FromBoundsTranslation( trm->bounds, start, trmAxis, results.endpos - start ); - radius = trm->bounds.GetRadius(); - } - - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - if ( touch->renderModelHandle != -1 ) { - idClip::numRenderModelTraces++; - TraceRenderModel( trace, start, end, radius, trmAxis, touch ); - } else { - idClip::numTranslations++; - collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - } - - if ( trace.fraction < results.fraction ) { - results = trace; - results.c.entityNum = touch->entity->entityNumber; - results.c.id = touch->id; - if ( results.fraction == 0.0f ) { - break; - } - } - } - - return ( results.fraction < 1.0f ); -} - -/* -============ -idClip::Rotation -============ -*/ -bool idClip::Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, num; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idBounds traceBounds; - trace_t trace; - const idTraceModel *trm; - - trm = TraceModelForClipModel( mdl ); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // test world - idClip::numRotations++; - collisionModelManager->Rotation( &results, start, rotation, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - results.c.entityNum = results.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; - if ( results.fraction == 0.0f ) { - return true; // blocked immediately by the world - } - } else { - memset( &results, 0, sizeof( results ) ); - results.fraction = 1.0f; - results.endpos = start; - results.endAxis = trmAxis * rotation.ToMat3(); - } - - if ( !trm ) { - traceBounds.FromPointRotation( start, rotation ); - } else { - traceBounds.FromBoundsRotation( trm->bounds, start, trmAxis, rotation ); - } - - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - // no rotational collision with render models - if ( touch->renderModelHandle != -1 ) { - continue; - } - - idClip::numRotations++; - collisionModelManager->Rotation( &trace, start, rotation, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - - if ( trace.fraction < results.fraction ) { - results = trace; - results.c.entityNum = touch->entity->entityNumber; - results.c.id = touch->id; - if ( results.fraction == 0.0f ) { - break; - } - } - } - - return ( results.fraction < 1.0f ); -} - -/* -============ -idClip::Motion -============ -*/ -bool idClip::Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, num; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idVec3 dir, endPosition; - idBounds traceBounds; - float radius; - trace_t translationalTrace, rotationalTrace, trace; - idRotation endRotation; - const idTraceModel *trm; - - assert( rotation.GetOrigin() == start ); - - if ( TestHugeTranslation( results, mdl, start, end, trmAxis ) ) { - return true; - } - - if ( mdl != NULL && rotation.GetAngle() != 0.0f && rotation.GetVec() != vec3_origin ) { - // if no translation - if ( start == end ) { - // pure rotation - return Rotation( results, start, rotation, mdl, trmAxis, contentMask, passEntity ); - } - } else if ( start != end ) { - // pure translation - return Translation( results, start, end, mdl, trmAxis, contentMask, passEntity ); - } else { - // no motion - results.fraction = 1.0f; - results.endpos = start; - results.endAxis = trmAxis; - return false; - } - - trm = TraceModelForClipModel( mdl ); - - radius = trm->bounds.GetRadius(); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // translational collision with world - idClip::numTranslations++; - collisionModelManager->Translation( &translationalTrace, start, end, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - translationalTrace.c.entityNum = translationalTrace.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; - } else { - memset( &translationalTrace, 0, sizeof( translationalTrace ) ); - translationalTrace.fraction = 1.0f; - translationalTrace.endpos = end; - translationalTrace.endAxis = trmAxis; - } - - if ( translationalTrace.fraction != 0.0f ) { - - traceBounds.FromBoundsRotation( trm->bounds, start, trmAxis, rotation ); - dir = translationalTrace.endpos - start; - for ( i = 0; i < 3; i++ ) { - if ( dir[i] < 0.0f ) { - traceBounds[0][i] += dir[i]; - } - else { - traceBounds[1][i] += dir[i]; - } - } - - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - if ( touch->renderModelHandle != -1 ) { - idClip::numRenderModelTraces++; - TraceRenderModel( trace, start, end, radius, trmAxis, touch ); - } else { - idClip::numTranslations++; - collisionModelManager->Translation( &trace, start, end, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - } - - if ( trace.fraction < translationalTrace.fraction ) { - translationalTrace = trace; - translationalTrace.c.entityNum = touch->entity->entityNumber; - translationalTrace.c.id = touch->id; - if ( translationalTrace.fraction == 0.0f ) { - break; - } - } - } - } else { - num = -1; - } - - endPosition = translationalTrace.endpos; - endRotation = rotation; - endRotation.SetOrigin( endPosition ); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // rotational collision with world - idClip::numRotations++; - collisionModelManager->Rotation( &rotationalTrace, endPosition, endRotation, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - rotationalTrace.c.entityNum = rotationalTrace.fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; - } else { - memset( &rotationalTrace, 0, sizeof( rotationalTrace ) ); - rotationalTrace.fraction = 1.0f; - rotationalTrace.endpos = endPosition; - rotationalTrace.endAxis = trmAxis * rotation.ToMat3(); - } - - if ( rotationalTrace.fraction != 0.0f ) { - - if ( num == -1 ) { - traceBounds.FromBoundsRotation( trm->bounds, endPosition, trmAxis, endRotation ); - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - } - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - // no rotational collision detection with render models - if ( touch->renderModelHandle != -1 ) { - continue; - } - - idClip::numRotations++; - collisionModelManager->Rotation( &trace, endPosition, endRotation, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - - if ( trace.fraction < rotationalTrace.fraction ) { - rotationalTrace = trace; - rotationalTrace.c.entityNum = touch->entity->entityNumber; - rotationalTrace.c.id = touch->id; - if ( rotationalTrace.fraction == 0.0f ) { - break; - } - } - } - } - - if ( rotationalTrace.fraction < 1.0f ) { - results = rotationalTrace; - } else { - results = translationalTrace; - results.endAxis = rotationalTrace.endAxis; - } - - results.fraction = Max( translationalTrace.fraction, rotationalTrace.fraction ); - - return ( translationalTrace.fraction < 1.0f || rotationalTrace.fraction < 1.0f ); -} - -/* -============ -idClip::Contacts -============ -*/ -int idClip::Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, j, num, n, numContacts; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idBounds traceBounds; - const idTraceModel *trm; - - trm = TraceModelForClipModel( mdl ); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // test world - idClip::numContacts++; - numContacts = collisionModelManager->Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - } else { - numContacts = 0; - } - - for ( i = 0; i < numContacts; i++ ) { - contacts[i].entityNum = ENTITYNUM_WORLD; - contacts[i].id = 0; - } - - if ( numContacts >= maxContacts ) { - return numContacts; - } - - if ( !trm ) { - traceBounds = idBounds( start ).Expand( depth ); - } else { - traceBounds.FromTransformedBounds( trm->bounds, start, trmAxis ); - traceBounds.ExpandSelf( depth ); - } - - num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - // no contacts with render models - if ( touch->renderModelHandle != -1 ) { - continue; - } - - idClip::numContacts++; - n = collisionModelManager->Contacts( contacts + numContacts, maxContacts - numContacts, - start, dir, depth, trm, trmAxis, contentMask, - touch->Handle(), touch->origin, touch->axis ); - - for ( j = 0; j < n; j++ ) { - contacts[numContacts].entityNum = touch->entity->entityNumber; - contacts[numContacts].id = touch->id; - numContacts++; - } - - if ( numContacts >= maxContacts ) { - break; - } - } - - return numContacts; -} - -/* -============ -idClip::Contents -============ -*/ -int idClip::Contents( const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { - int i, num, contents; - idClipModel *touch, *clipModelList[MAX_GENTITIES]; - idBounds traceBounds; - const idTraceModel *trm; - - trm = TraceModelForClipModel( mdl ); - - if ( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { - // test world - idClip::numContents++; - contents = collisionModelManager->Contents( start, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); - } else { - contents = 0; - } - - if ( !trm ) { - traceBounds[0] = start; - traceBounds[1] = start; - } else if ( trmAxis.IsRotated() ) { - traceBounds.FromTransformedBounds( trm->bounds, start, trmAxis ); - } else { - traceBounds[0] = trm->bounds[0] + start; - traceBounds[1] = trm->bounds[1] + start; - } - - num = GetTraceClipModels( traceBounds, -1, passEntity, clipModelList ); - - for ( i = 0; i < num; i++ ) { - touch = clipModelList[i]; - - if ( !touch ) { - continue; - } - - // no contents test with render models - if ( touch->renderModelHandle != -1 ) { - continue; - } - - // if the entity does not have any contents we are looking for - if ( ( touch->contents & contentMask ) == 0 ) { - continue; - } - - // if the entity has no new contents flags - if ( ( touch->contents & contents ) == touch->contents ) { - continue; - } - - idClip::numContents++; - if ( collisionModelManager->Contents( start, trm, trmAxis, contentMask, touch->Handle(), touch->origin, touch->axis ) ) { - contents |= ( touch->contents & contentMask ); - } - } - - return contents; -} - -/* -============ -idClip::TranslationModel -============ -*/ -void idClip::TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { - const idTraceModel *trm = TraceModelForClipModel( mdl ); - idClip::numTranslations++; - collisionModelManager->Translation( &results, start, end, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); -} - -/* -============ -idClip::RotationModel -============ -*/ -void idClip::RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { - const idTraceModel *trm = TraceModelForClipModel( mdl ); - idClip::numRotations++; - collisionModelManager->Rotation( &results, start, rotation, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); -} - -/* -============ -idClip::ContactsModel -============ -*/ -int idClip::ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { - const idTraceModel *trm = TraceModelForClipModel( mdl ); - idClip::numContacts++; - return collisionModelManager->Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); -} - -/* -============ -idClip::ContentsModel -============ -*/ -int idClip::ContentsModel( const idVec3 &start, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ) { - const idTraceModel *trm = TraceModelForClipModel( mdl ); - idClip::numContents++; - return collisionModelManager->Contents( start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis ); -} - -/* -============ -idClip::GetModelContactFeature -============ -*/ -bool idClip::GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const { - int i; - cmHandle_t handle; - idVec3 start, end; - - handle = -1; - winding.Clear(); - - if ( clipModel == NULL ) { - handle = 0; - } else { - if ( clipModel->renderModelHandle != -1 ) { - winding += contact.point; - return true; - } else if ( clipModel->traceModelIndex != -1 ) { - handle = collisionModelManager->SetupTrmModel( *idClipModel::GetCachedTraceModel( clipModel->traceModelIndex ), clipModel->material ); - } else { - handle = clipModel->collisionModelHandle; - } - } - - // if contact with a collision model - if ( handle != -1 ) { - switch( contact.type ) { - case CONTACT_EDGE: { - // the model contact feature is a collision model edge - collisionModelManager->GetModelEdge( handle, contact.modelFeature, start, end ); - winding += start; - winding += end; - break; - } - case CONTACT_MODELVERTEX: { - // the model contact feature is a collision model vertex - collisionModelManager->GetModelVertex( handle, contact.modelFeature, start ); - winding += start; - break; - } - case CONTACT_TRMVERTEX: { - // the model contact feature is a collision model polygon - collisionModelManager->GetModelPolygon( handle, contact.modelFeature, winding ); - break; - } - default: break; - } - } - - // transform the winding to world space - if ( clipModel ) { - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - winding[i].ToVec3() *= clipModel->axis; - winding[i].ToVec3() += clipModel->origin; - } - } - - return true; -} - -/* -============ -idClip::PrintStatistics -============ -*/ -void idClip::PrintStatistics( void ) { - gameLocal.Printf( "t = %-3d, r = %-3d, m = %-3d, render = %-3d, contents = %-3d, contacts = %-3d\n", - numTranslations, numRotations, numMotions, numRenderModelTraces, numContents, numContacts ); - numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; -} - -/* -============ -idClip::DrawClipModels -============ -*/ -void idClip::DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity ) { - int i, num; - idBounds bounds; - idClipModel *clipModelList[MAX_GENTITIES]; - idClipModel *clipModel; - - bounds = idBounds( eye ).Expand( radius ); - - num = idClip::ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); - - for ( i = 0; i < num; i++ ) { - clipModel = clipModelList[i]; - if ( clipModel->GetEntity() == passEntity ) { - continue; - } - if ( clipModel->renderModelHandle != -1 ) { - gameRenderWorld->DebugBounds( colorCyan, clipModel->GetAbsBounds() ); - } else { - collisionModelManager->DrawModel( clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis(), eye, radius ); - } - } -} - -/* -============ -idClip::DrawModelContactFeature -============ -*/ -bool idClip::DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const { - int i; - idMat3 axis; - idFixedWinding winding; - - if ( !GetModelContactFeature( contact, clipModel, winding ) ) { - return false; - } - - axis = contact.normal.ToMat3(); - - if ( winding.GetNumPoints() == 1 ) { - gameRenderWorld->DebugLine( colorCyan, winding[0].ToVec3(), winding[0].ToVec3() + 2.0f * axis[0], lifetime ); - gameRenderWorld->DebugLine( colorWhite, winding[0].ToVec3() - 1.0f * axis[1], winding[0].ToVec3() + 1.0f * axis[1], lifetime ); - gameRenderWorld->DebugLine( colorWhite, winding[0].ToVec3() - 1.0f * axis[2], winding[0].ToVec3() + 1.0f * axis[2], lifetime ); - } else { - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - gameRenderWorld->DebugLine( colorCyan, winding[i].ToVec3(), winding[(i+1)%winding.GetNumPoints()].ToVec3(), lifetime ); - } - } - - axis[0] = -axis[0]; - axis[2] = -axis[2]; - gameRenderWorld->DrawText( contact.material->GetName(), winding.GetCenter() - 4.0f * axis[2], 0.1f, colorWhite, axis, 1, 5000 ); - - return true; -} - -void idClipModel::TranslateOrigin( const idVec3 &translation ) -{ - if( IsTraceModel() ) - { - // Copy the tracemodel - idTraceModel trm = *(idClipModel::GetCachedTraceModel( traceModelIndex )); - trm.Translate( translation ); - - LoadModel( trm ); - } -} diff --git a/game/physics/clip.h b/game/physics/clip.h deleted file mode 100644 index 7562fb0e5..000000000 --- a/game/physics/clip.h +++ /dev/null @@ -1,358 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CLIP_H__ -#define __CLIP_H__ - -#ifdef __linux__ -#include "cm/collisionmodel.h" -#endif - -/* -=============================================================================== - - Handles collision detection with the world and between physics objects. - -=============================================================================== -*/ - -#define CLIPMODEL_ID_TO_JOINT_HANDLE( id ) ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) ) -#define JOINT_HANDLE_TO_CLIPMODEL_ID( id ) ( -1 - id ) - -class idClip; -class idClipModel; -class idEntity; - - -//=============================================================== -// -// idClipModel -// -//=============================================================== - -class idClipModel { - - friend class idClip; - -public: - idClipModel( void ); - explicit idClipModel( const char *name ); - explicit idClipModel( const idTraceModel &trm ); - explicit idClipModel( const int renderModelHandle ); - explicit idClipModel( const idClipModel *model ); - ~idClipModel( void ); - - bool LoadModel( const char *name ); - void LoadModel( const idTraceModel &trm ); - void LoadModel( const int renderModelHandle ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Link( idClip &clp ); // must have been linked with an entity and id before - void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 ); - void Unlink( void ); // unlink from sectors - void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model - /** - * Translates the origin of the clip model relative to the clipmodel itself - * Unlinks the clip model - **/ - void TranslateOrigin( const idVec3 &translation ); - void Translate( const idVec3 &translation ); // unlinks the clip model - void Scale( const idVec3 &scale ); // unlinks the clip model - void Rotate( const idRotation &rotation ); // unlinks the clip model - void Enable( void ); // enable for clipping - void Disable( void ); // keep linked but disable for clipping - void SetMaterial( const idMaterial *m ); - const idMaterial * GetMaterial( void ) const; - void SetContents( int newContents ); // override contents - int GetContents( void ) const; - void SetEntity( idEntity *newEntity ); - idEntity * GetEntity( void ) const; - void SetId( int newId ); - int GetId( void ) const; - void SetOwner( idEntity *newOwner ); - idEntity * GetOwner( void ) const; - const idBounds & GetBounds( void ) const; - const idBounds & GetAbsBounds( void ) const; - const idVec3 & GetOrigin( void ) const; - const idMat3 & GetAxis( void ) const; - bool IsTraceModel( void ) const; // returns true if this is a trace model - bool IsRenderModel( void ) const; // returns true if this is a render model - bool IsLinked( void ) const; // returns true if the clip model is linked - bool IsEnabled( void ) const; // returns true if enabled for collision detection - bool IsEqual( const idTraceModel &trm ) const; - cmHandle_t Handle( void ) const; // returns handle used to collide vs this model - const idTraceModel * GetTraceModel( void ) const; - void GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const; - - static cmHandle_t CheckModel( const char *name ); - static void ClearTraceModelCache( void ); - static int TraceModelCacheSize( void ); - - static void SaveTraceModels( idSaveGame *savefile ); - static void RestoreTraceModels( idRestoreGame *savefile ); - -private: - bool enabled; // true if this clip model is used for clipping - idEntity * entity; // entity using this clip model - int id; // id for entities that use multiple clip models - idEntity * owner; // owner of the entity that owns this clip model - idVec3 origin; // origin of clip model - idMat3 axis; // orientation of clip model - idBounds bounds; // bounds - idBounds absBounds; // absolute bounds - const idMaterial * material; // material for trace models - int contents; // all contents ored together - cmHandle_t collisionModelHandle; // handle to collision model - int traceModelIndex; // trace model used for collision detection - int renderModelHandle; // render model def handle - - struct clipLink_s * clipLinks; // links into sectors - int touchCount; - - void Init( void ); // initialize - void Link_r( struct clipSector_s *node ); - - static int AllocTraceModel( const idTraceModel &trm ); - static void FreeTraceModel( const int traceModelIndex ); - static idTraceModel * GetCachedTraceModel( int traceModelIndex ); - static int GetTraceModelHashKey( const idTraceModel &trm ); -}; - - -ID_INLINE void idClipModel::Translate( const idVec3 &translation ) { - Unlink(); - origin += translation; -} - -ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) { - Unlink(); - origin *= rotation; - axis *= rotation.ToMat3(); -} - -ID_INLINE void idClipModel::Scale( const idVec3 &scale ) { - if( IsTraceModel() ) - { - // copy & scale the tracemodel - // Tels: Is the copy nec.? - idTraceModel trm = *(idClipModel::GetCachedTraceModel( traceModelIndex )); - trm.Scale( scale ); - - LoadModel( trm ); - } -} - -ID_INLINE void idClipModel::Enable( void ) { - enabled = true; -} - -ID_INLINE void idClipModel::Disable( void ) { - enabled = false; -} - -ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) { - material = m; -} - -ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const { - return material; -} - -ID_INLINE void idClipModel::SetContents( int newContents ) { - contents = newContents; -} - -ID_INLINE int idClipModel::GetContents( void ) const { - return contents; -} - -ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) { - entity = newEntity; -} - -ID_INLINE idEntity *idClipModel::GetEntity( void ) const { - return entity; -} - -ID_INLINE void idClipModel::SetId( int newId ) { - id = newId; -} - -ID_INLINE int idClipModel::GetId( void ) const { - return id; -} - -ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) { - owner = newOwner; -} - -ID_INLINE idEntity *idClipModel::GetOwner( void ) const { - return owner; -} - -ID_INLINE const idBounds &idClipModel::GetBounds( void ) const { - return bounds; -} - -ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const { - return absBounds; -} - -ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const { - return origin; -} - -ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const { - return axis; -} - -ID_INLINE bool idClipModel::IsRenderModel( void ) const { - return ( renderModelHandle != -1 ); -} - -ID_INLINE bool idClipModel::IsTraceModel( void ) const { - return ( traceModelIndex != -1 ); -} - -ID_INLINE bool idClipModel::IsLinked( void ) const { - return ( clipLinks != NULL ); -} - -ID_INLINE bool idClipModel::IsEnabled( void ) const { - return enabled; -} - -ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const { - return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm ); -} - -ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const { - if ( !IsTraceModel() ) { - return NULL; - } - return idClipModel::GetCachedTraceModel( traceModelIndex ); -} - - -//=============================================================== -// -// idClip -// -//=============================================================== - -class idClip { - - friend class idClipModel; - -public: - idClip( void ); - - void Init( void ); - void Shutdown( void ); - - // clip versus the rest of the world - bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - int Contents( const idVec3 &start, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - - // special case translations versus the rest of the world - bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, - int contentMask, const idEntity *passEntity ); - bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, - int contentMask, const idEntity *passEntity ); - - // clip versus a specific model - void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); - void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); - int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); - int ContentsModel( const idVec3 &start, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, - cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); - - // clip versus all entities but not the world - void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end, - const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ); - - // get a contact feature - bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const; - - // get entities/clip models within or touching the given bounds - int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const; - int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const; - - const idBounds & GetWorldBounds( void ) const; - idClipModel * DefaultClipModel( void ); - - // stats and debug drawing - void PrintStatistics( void ); - void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity ); - bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const; - -private: - int numClipSectors; - struct clipSector_s * clipSectors; - idBounds worldBounds; - idClipModel temporaryClipModel; - idClipModel defaultClipModel; - mutable int touchCount; - // statistics - int numTranslations; - int numRotations; - int numMotions; - int numRenderModelTraces; - int numContents; - int numContacts; - -private: - struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector ); - void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const; - const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const; - int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const; - void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const; -}; - - -ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) { - Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity ); - return ( results.fraction < 1.0f ); -} - -ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) { - temporaryClipModel.LoadModel( idTraceModel( bounds ) ); - Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity ); - return ( results.fraction < 1.0f ); -} - -ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const { - return worldBounds; -} - -ID_INLINE idClipModel *idClip::DefaultClipModel( void ) { - return &defaultClipModel; -} - -#endif /* !__CLIP_H__ */ diff --git a/game/physics/force.cpp b/game/physics/force.cpp deleted file mode 100644 index 8c10cd597..000000000 --- a/game/physics/force.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idClass, idForce ) -END_CLASS - -idList idForce::forceList; - -/* -================ -idForce::idForce -================ -*/ -idForce::idForce( void ) { - forceList.Append( this ); -} - -/* -================ -idForce::~idForce -================ -*/ -idForce::~idForce( void ) { - forceList.Remove( this ); -} - -/* -================ -idForce::DeletePhysics -================ -*/ -void idForce::DeletePhysics( const idPhysics *phys ) { - int i; - - for ( i = 0; i < forceList.Num(); i++ ) { - forceList[i]->RemovePhysics( phys ); - } -} - -/* -================ -idForce::ClearForceList -================ -*/ -void idForce::ClearForceList( void ) { - forceList.Clear(); -} - -/* -================ -idForce::Evaluate -================ -*/ -void idForce::Evaluate( int time ) { -} - -/* -================ -idForce::RemovePhysics -================ -*/ -void idForce::RemovePhysics( const idPhysics *phys ) { -} diff --git a/game/physics/force.h b/game/physics/force.h deleted file mode 100644 index 831087824..000000000 --- a/game/physics/force.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FORCE_H__ -#define __FORCE_H__ - -/* -=============================================================================== - - Force base class - - A force object applies a force to a physics object. - -=============================================================================== -*/ - -class idEntity; -class idPhysics; - -class idForce : public idClass { - -public: - CLASS_PROTOTYPE( idForce ); - - idForce( void ); - virtual ~idForce( void ); - static void DeletePhysics( const idPhysics *phys ); - static void ClearForceList( void ); - -public: // common force interface - // evalulate the force up to the given time - virtual void Evaluate( int time ); - // removes any pointers to the physics object - virtual void RemovePhysics( const idPhysics *phys ); - -private: - - static idList forceList; -}; - -#endif /* !__FORCE_H__ */ diff --git a/game/physics/force_constant.cpp b/game/physics/force_constant.cpp deleted file mode 100644 index 0bc50f084..000000000 --- a/game/physics/force_constant.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idForce, idForce_Constant ) -END_CLASS - -/* -================ -idForce_Constant::idForce_Constant -================ -*/ -idForce_Constant::idForce_Constant( void ) { - force = vec3_zero; - physics = NULL; - id = 0; - point = vec3_zero; -} - -/* -================ -idForce_Constant::~idForce_Constant -================ -*/ -idForce_Constant::~idForce_Constant( void ) { -} - -/* -================ -idForce_Constant::Save -================ -*/ -void idForce_Constant::Save( idSaveGame *savefile ) const { - savefile->WriteVec3( force ); - savefile->WriteInt( id ); - savefile->WriteVec3( point ); -} - -/* -================ -idForce_Constant::Restore -================ -*/ -void idForce_Constant::Restore( idRestoreGame *savefile ) { - // Owner needs to call SetPhysics!! - savefile->ReadVec3( force ); - savefile->ReadInt( id ); - savefile->ReadVec3( point ); -} - -/* -================ -idForce_Constant::SetPosition -================ -*/ -void idForce_Constant::SetPosition( idPhysics *physics, int id, const idVec3 &point ) { - this->physics = physics; - this->id = id; - this->point = point; -} - -/* -================ -idForce_Constant::SetForce -================ -*/ -void idForce_Constant::SetForce( const idVec3 &force ) { - this->force = force; -} - -/* -================ -idForce_Constant::SetPhysics -================ -*/ -void idForce_Constant::SetPhysics( idPhysics *physics ) { - this->physics = physics; -} - -/* -================ -idForce_Constant::Evaluate -================ -*/ -void idForce_Constant::Evaluate( int time ) { - idVec3 p; - - if ( !physics ) { - return; - } - - p = physics->GetOrigin( id ) + point * physics->GetAxis( id ); - - physics->AddForce( id, p, force ); -} - -/* -================ -idForce_Constant::RemovePhysics -================ -*/ -void idForce_Constant::RemovePhysics( const idPhysics *phys ) { - if ( physics == phys ) { - physics = NULL; - } -} diff --git a/game/physics/force_constant.h b/game/physics/force_constant.h deleted file mode 100644 index 590c5f9dd..000000000 --- a/game/physics/force_constant.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FORCE_CONSTANT_H__ -#define __FORCE_CONSTANT_H__ - -/* -=============================================================================== - - Constant force - -=============================================================================== -*/ - -class idForce_Constant : public idForce { - -public: - CLASS_PROTOTYPE( idForce_Constant ); - - idForce_Constant( void ); - virtual ~idForce_Constant( void ); - - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // constant force - void SetForce( const idVec3 &force ); - // set force position - void SetPosition( idPhysics *physics, int id, const idVec3 &point ); - - void SetPhysics( idPhysics *physics ); - -public: // common force interface - virtual void Evaluate( int time ); - virtual void RemovePhysics( const idPhysics *phys ); - -private: - // force properties - idVec3 force; - idPhysics * physics; - int id; - idVec3 point; -}; - -#endif /* !__FORCE_CONSTANT_H__ */ diff --git a/game/physics/force_drag.cpp b/game/physics/force_drag.cpp deleted file mode 100644 index d306f74b6..000000000 --- a/game/physics/force_drag.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idForce, idForce_Drag ) -END_CLASS - -/* -================ -idForce_Drag::idForce_Drag -================ -*/ -idForce_Drag::idForce_Drag( void ) { - damping = 0.5f; - dragPosition = vec3_zero; - physics = NULL; - id = 0; - p = vec3_zero; - dragPosition = vec3_zero; -} - -/* -================ -idForce_Drag::~idForce_Drag -================ -*/ -idForce_Drag::~idForce_Drag( void ) { -} - -/* -================ -idForce_Drag::Init -================ -*/ -void idForce_Drag::Init( float damping ) { - if ( damping >= 0.0f && damping < 1.0f ) { - this->damping = damping; - } -} - -/* -================ -idForce_Drag::SetPhysics -================ -*/ -void idForce_Drag::SetPhysics( idPhysics *phys, int id, const idVec3 &p ) { - this->physics = phys; - this->id = id; - this->p = p; -} - -/* -================ -idForce_Drag::SetDragPosition -================ -*/ -void idForce_Drag::SetDragPosition( const idVec3 &pos ) { - this->dragPosition = pos; -} - -/* -================ -idForce_Drag::GetDragPosition -================ -*/ -const idVec3 &idForce_Drag::GetDragPosition( void ) const { - return this->dragPosition; -} - -/* -================ -idForce_Drag::GetDraggedPosition -================ -*/ -const idVec3 idForce_Drag::GetDraggedPosition( void ) const { - return ( physics->GetOrigin( id ) + p * physics->GetAxis( id ) ); -} - -/* -================ -idForce_Drag::Evaluate -================ -*/ -void idForce_Drag::Evaluate( int time ) { - float l1, l2, mass; - idVec3 dragOrigin, dir1, dir2, velocity, centerOfMass; - idMat3 inertiaTensor; - idRotation rotation; - idClipModel *clipModel; - - if ( !physics ) { - return; - } - - clipModel = physics->GetClipModel( id ); - if ( clipModel != NULL && clipModel->IsTraceModel() ) { - clipModel->GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor ); - } else { - centerOfMass.Zero(); - } - - centerOfMass = physics->GetOrigin( id ) + centerOfMass * physics->GetAxis( id ); - dragOrigin = physics->GetOrigin( id ) + p * physics->GetAxis( id ); - - dir1 = dragPosition - centerOfMass; - dir2 = dragOrigin - centerOfMass; - l1 = dir1.Normalize(); - l2 = dir2.Normalize(); - - rotation.Set( centerOfMass, dir2.Cross( dir1 ), RAD2DEG( idMath::ACos( dir1 * dir2 ) ) ); - physics->SetAngularVelocity( rotation.ToAngularVelocity() / MS2SEC( USERCMD_MSEC ), id ); - - velocity = physics->GetLinearVelocity( id ) * damping + dir1 * ( ( l1 - l2 ) * ( 1.0f - damping ) / MS2SEC( USERCMD_MSEC ) ); - physics->SetLinearVelocity( velocity, id ); -} - -/* -================ -idForce_Drag::RemovePhysics -================ -*/ -void idForce_Drag::RemovePhysics( const idPhysics *phys ) { - if ( physics == phys ) { - physics = NULL; - } -} diff --git a/game/physics/force_drag.h b/game/physics/force_drag.h deleted file mode 100644 index cef61914f..000000000 --- a/game/physics/force_drag.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FORCE_DRAG_H__ -#define __FORCE_DRAG_H__ - -/* -=============================================================================== - - Drag force - -=============================================================================== -*/ - -class idForce_Drag : public idForce { - -public: - CLASS_PROTOTYPE( idForce_Drag ); - - idForce_Drag( void ); - virtual ~idForce_Drag( void ); - // initialize the drag force - void Init( float damping ); - // set physics object being dragged - void SetPhysics( idPhysics *physics, int id, const idVec3 &p ); - // set position to drag towards - void SetDragPosition( const idVec3 &pos ); - // get the position dragged towards - const idVec3 & GetDragPosition( void ) const; - // get the position on the dragged physics object - const idVec3 GetDraggedPosition( void ) const; - -public: // common force interface - virtual void Evaluate( int time ); - virtual void RemovePhysics( const idPhysics *phys ); - -private: - - // properties - float damping; - - // positioning - idPhysics * physics; // physics object - int id; // clip model id of physics object - idVec3 p; // position on clip model - idVec3 dragPosition; // drag towards this position -}; - -#endif /* !__FORCE_DRAG_H__ */ diff --git a/game/physics/force_field.cpp b/game/physics/force_field.cpp deleted file mode 100644 index 392185006..000000000 --- a/game/physics/force_field.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idForce, idForce_Field ) -END_CLASS - -/* -================ -idForce_Field::idForce_Field -================ -*/ -idForce_Field::idForce_Field( void ) { - type = FORCEFIELD_UNIFORM; - applyType = FORCEFIELD_APPLY_FORCE; - magnitude = 0.0f; - dir.Set( 0, 0, 1 ); - randomTorque = 0.0f; - playerOnly = false; - monsterOnly = false; - clipModel = NULL; -} - -/* -================ -idForce_Field::~idForce_Field -================ -*/ -idForce_Field::~idForce_Field( void ) { - if ( this->clipModel ) { - delete this->clipModel; - } -} - -/* -================ -idForce_Field::Save -================ -*/ -void idForce_Field::Save( idSaveGame *savefile ) const { - savefile->WriteInt( type ); - savefile->WriteInt( applyType); - savefile->WriteFloat( magnitude ); - savefile->WriteVec3( dir ); - savefile->WriteFloat( randomTorque ); - savefile->WriteBool( playerOnly ); - savefile->WriteBool( monsterOnly ); - savefile->WriteClipModel( clipModel ); -} - -/* -================ -idForce_Field::Restore -================ -*/ -void idForce_Field::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( (int &)type ); - savefile->ReadInt( (int &)applyType); - savefile->ReadFloat( magnitude ); - savefile->ReadVec3( dir ); - savefile->ReadFloat( randomTorque ); - savefile->ReadBool( playerOnly ); - savefile->ReadBool( monsterOnly ); - savefile->ReadClipModel( clipModel ); -} - -/* -================ -idForce_Field::SetClipModel -================ -*/ -void idForce_Field::SetClipModel( idClipModel *clipModel ) { - if ( this->clipModel && clipModel != this->clipModel ) { - delete this->clipModel; - } - this->clipModel = clipModel; -} - -/* -================ -idForce_Field::Uniform -================ -*/ -void idForce_Field::Uniform( const idVec3 &force ) { - dir = force; - magnitude = dir.Normalize(); - type = FORCEFIELD_UNIFORM; -} - -/* -================ -idForce_Field::Explosion -================ -*/ -void idForce_Field::Explosion( float force ) { - magnitude = force; - type = FORCEFIELD_EXPLOSION; -} - -/* -================ -idForce_Field::Implosion -================ -*/ -void idForce_Field::Implosion( float force ) { - magnitude = force; - type = FORCEFIELD_IMPLOSION; -} - -/* -================ -idForce_Field::RandomTorque -================ -*/ -void idForce_Field::RandomTorque( float force ) { - randomTorque = force; -} - -/* -================ -idForce_Field::Evaluate -================ -*/ -void idForce_Field::Evaluate( int time ) { - int numClipModels, i; - idBounds bounds; - idVec3 force, torque, angularVelocity; - idClipModel *cm, *clipModelList[ MAX_GENTITIES ]; - - assert( clipModel ); - - bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); - numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); - - for ( i = 0; i < numClipModels; i++ ) { - cm = clipModelList[ i ]; - - if ( !cm->IsTraceModel() ) { - continue; - } - - idEntity *entity = cm->GetEntity(); - - if ( !entity ) { - continue; - } - - idPhysics *physics = entity->GetPhysics(); - - if ( playerOnly ) { - if ( !physics->IsType( idPhysics_Player::Type ) ) { - continue; - } - } else if ( monsterOnly ) { - if ( !physics->IsType( idPhysics_Monster::Type ) ) { - continue; - } - } - - if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1, - clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) { - continue; - } - - switch( type ) { - case FORCEFIELD_UNIFORM: { - force = dir; - break; - } - case FORCEFIELD_EXPLOSION: { - force = cm->GetOrigin() - clipModel->GetOrigin(); - force.Normalize(); - break; - } - case FORCEFIELD_IMPLOSION: { - force = clipModel->GetOrigin() - cm->GetOrigin(); - force.Normalize(); - break; - } - default: { - gameLocal.Error( "idForce_Field: invalid type" ); - break; - } - } - - if ( randomTorque != 0.0f ) { - torque[0] = gameLocal.random.CRandomFloat(); - torque[1] = gameLocal.random.CRandomFloat(); - torque[2] = gameLocal.random.CRandomFloat(); - if ( torque.Normalize() == 0.0f ) { - torque[2] = 1.0f; - } - } - - switch( applyType ) { - case FORCEFIELD_APPLY_FORCE: { - if ( randomTorque != 0.0f ) { - entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude ); - } - else { - entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude ); - } - break; - } - case FORCEFIELD_APPLY_VELOCITY: { - physics->SetLinearVelocity( force * magnitude, cm->GetId() ); - if ( randomTorque != 0.0f ) { - angularVelocity = physics->GetAngularVelocity( cm->GetId() ); - physics->SetAngularVelocity( 0.5f * (angularVelocity + torque * randomTorque), cm->GetId() ); - } - break; - } - case FORCEFIELD_APPLY_IMPULSE: { - if ( randomTorque != 0.0f ) { - entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude ); - } - else { - entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude ); - } - break; - } - default: { - gameLocal.Error( "idForce_Field: invalid apply type" ); - break; - } - } - } -} diff --git a/game/physics/force_field.h b/game/physics/force_field.h deleted file mode 100644 index 541119d59..000000000 --- a/game/physics/force_field.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FORCE_FIELD_H__ -#define __FORCE_FIELD_H__ - -/* -=============================================================================== - - Force field - -=============================================================================== -*/ - -enum forceFieldType { - FORCEFIELD_UNIFORM, - FORCEFIELD_EXPLOSION, - FORCEFIELD_IMPLOSION -}; - -enum forceFieldApplyType { - FORCEFIELD_APPLY_FORCE, - FORCEFIELD_APPLY_VELOCITY, - FORCEFIELD_APPLY_IMPULSE -}; - -class idForce_Field : public idForce { - -public: - CLASS_PROTOTYPE( idForce_Field ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - idForce_Field( void ); - virtual ~idForce_Field( void ); - // uniform constant force - void Uniform( const idVec3 &force ); - // explosion from clip model origin - void Explosion( float force ); - // implosion towards clip model origin - void Implosion( float force ); - // add random torque - void RandomTorque( float force ); - // should the force field apply a force, velocity or impulse - void SetApplyType( const forceFieldApplyType type ) { applyType = type; } - // make the force field only push players - void SetPlayerOnly( bool set ) { playerOnly = set; } - // make the force field only push monsters - void SetMonsterOnly( bool set ) { monsterOnly = set; } - // clip model describing the extents of the force field - void SetClipModel( idClipModel *clipModel ); - -public: // common force interface - virtual void Evaluate( int time ); - -private: - // force properties - forceFieldType type; - forceFieldApplyType applyType; - float magnitude; - idVec3 dir; - float randomTorque; - bool playerOnly; - bool monsterOnly; - idClipModel * clipModel; -}; - -#endif /* !__FORCE_FIELD_H__ */ diff --git a/game/physics/force_push.cpp b/game/physics/force_push.cpp deleted file mode 100644 index fce941d69..000000000 --- a/game/physics/force_push.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "force_push.h" -#include "../game_local.h" - -CLASS_DECLARATION( idForce, CForcePush ) -END_CLASS - -CForcePush::CForcePush() : - pushEnt(NULL), - id(0), - impactVelocity(vec3_zero), - startPushTime(-1), - owner(NULL) -{ - lastPushEnt = NULL; - memset(&contactInfo, 0, sizeof(contactInfo)); -} - -void CForcePush::SetOwner(idEntity* ownerEnt) -{ - owner = ownerEnt; -} - -void CForcePush::SetPushEntity(idEntity* pushEnt, int id) -{ - idEntity* lastPushEntity = lastPushEnt.GetEntity(); - - if (pushEnt != lastPushEntity) - { - // entity has changed, reset the timer - startPushTime = gameLocal.time; - } - - // Check if we are pushing anything - if (pushEnt == NULL) - { - // No, update the owning actor's push state - if (owner != NULL) - { - SetOwnerIsPushing(false); - } - - // Did we push anything the frame before? - if (lastPushEntity != NULL && lastPushEntity->IsType(idMoveable::Type)) - { - // Let the pushed entity know that it is not being pushed anymore - static_cast(lastPushEntity)->SetIsPushed(false, vec3_zero); - } - } - - this->pushEnt = pushEnt; - this->id = id; -} - -void CForcePush::SetContactInfo(const trace_t& contactInfo, const idVec3& impactVelocity) -{ - this->contactInfo = contactInfo; - this->impactVelocity = impactVelocity; -} - -void CForcePush::Evaluate( int time ) -{ - if (owner == NULL) return; - - if (pushEnt == NULL) - { - // nothing to do, but update the owning actor's push state - SetOwnerIsPushing(false); - return; - } - - // Do not push static entity or non-pushable ones - if (pushEnt->IsType(idStaticEntity::Type) || pushEnt->spawnArgs.GetBool("notpushable", "0")) - { - return; - } - - idPhysics* physics = pushEnt->GetPhysics(); - //gameRenderWorld->DebugBox(colorRed, idBox(physics->GetBounds(), physics->GetOrigin(), physics->GetAxis()), 16); - - if (physics == NULL) return; // fix crash for entites not having physics - - float mass = physics->GetMass(); - float ownerMass = owner->GetPhysics()->GetMass(); - - // This is the maximum mass an object can have to be kickable - float massThresholdHeavy = ownerMass * cv_pm_push_heavy_threshold.GetFloat(); - - bool isPushing = false; - - if (mass < massThresholdHeavy) - { - // Get the owner's velocity and project it on the impact normal - float normalVelocity = -contactInfo.c.normal * impactVelocity; - - // Clamp to positive values - if (normalVelocity < 0) - { - normalVelocity = 0; - } - - float maxPlayerSpeed = pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat(); - float speedFraction = idMath::ClampFloat(0, 1, normalVelocity / maxPlayerSpeed); - - // Maximum resulting velocity in m/s - const float vmax = 1.0f; - - // Calculate the resulting velocity of the kicked object, linearly scaled and clamped to [0..vmax] m/s - float resultingVelocity = vmax * (1.02f - physics->GetMass()/49); - resultingVelocity = METERS_TO_DOOM * idMath::ClampFloat(0, vmax, resultingVelocity); - - // This is the scale of our impulse, based on the maximum allowed kick velocity - float scale = physics->GetMass() * resultingVelocity * speedFraction; - - // The pushed entity is not a heavy one, kick it - //float scale = (-contactInfo.c.normal * impactVelocity) * ownerMass * cv_pm_pushmod.GetFloat(); - - // Clamp the value to the maximum impulse we're allowed to give - scale = idMath::ClampFloat(0, cv_pm_push_maximpulse.GetFloat(), scale); - - // greebo: Nullify the z-component of the impact impulse, we're always kicking horizontally - idVec3 pushDirection(impactVelocity.x, impactVelocity.y, 0); - pushDirection.NormalizeFast(); - - // Check if the moveable has already a large impulse in that direction - float currentDirectionalImpulse = (physics->GetLinearVelocity()*pushDirection) * physics->GetMass(); - - if (currentDirectionalImpulse < cv_pm_push_maximpulse.GetFloat()) - { - idVec3 pushImpulse = pushDirection * scale; - - //gameRenderWorld->DrawText( idStr(pushImpulse.LengthFast()), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec*10 ); - //gameRenderWorld->DebugArrow( colorWhite, physics->GetAbsBounds().GetCenter(), physics->GetAbsBounds().GetCenter() - contactInfo.c.normal*100, 1, gameLocal.msec*10 ); - - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking impulse = %f,%f,%f, scale was %f\r", pushImpulse.x, pushImpulse.y, pushImpulse.z, scale); - - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, velocity BEFORE is %f,%f,%f\r", pushEnt->name.c_str(), - physics->GetLinearVelocity().x, physics->GetLinearVelocity().y, physics->GetLinearVelocity().z); - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, angular velocity BEFORE is %f,%f,%f\r", pushEnt->name.c_str(), - physics->GetAngularVelocity().x, physics->GetAngularVelocity().y, physics->GetAngularVelocity().z); - - physics->PropagateImpulse(id, contactInfo.c.point, pushImpulse); - - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, velocity AFTER is %f,%f,%f\r", pushEnt->name.c_str(), - physics->GetLinearVelocity().x, physics->GetLinearVelocity().y, physics->GetLinearVelocity().z); - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Kicking obstacle %s, angular velocity AFTER is %f,%f,%f\r", pushEnt->name.c_str(), - physics->GetAngularVelocity().x, physics->GetAngularVelocity().y, physics->GetAngularVelocity().z); - } - } - // The pushed entity is considered heavy - else if (pushEnt == lastPushEnt.GetEntity()) - { - int pushTime = gameLocal.time - startPushTime; - //gameRenderWorld->DrawText( idStr(pushTime), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - - int pushStartDelay = cv_pm_push_start_delay.GetInteger(); - - // If we've been pushing long enough, start moving the obstacle - if (pushTime > pushStartDelay) - { - // greebo: Scale the velocity during the acceleration phase - float accelScale = idMath::ClampFloat(0, 1, (pushTime - pushStartDelay)/cv_pm_push_accel_time.GetFloat()); - - // Let the entity itself modify its pushing behaviour - float entityScale = pushEnt->spawnArgs.GetFloat("push_mod", "1"); - - // Scale the movement velocity according to the object's mass - // At maxPushMass, the velocity is zero, at the minimum push mass threshold below it's about 0.75 - float maxPushableMass = entityScale*cv_pm_push_max_mass.GetFloat(); - float massScale = idMath::ClampFloat(0.0f, 1.0f, 1.0f - (mass / maxPushableMass)); - - // Project the impactVelocity onto the contact normal - idVec3 pushVelocity = (impactVelocity * -contactInfo.c.normal) * (-contactInfo.c.normal); - - //gameRenderWorld->DebugArrow( colorRed, physics->GetAbsBounds().GetCenter(), physics->GetAbsBounds().GetCenter() + pushVelocity, 1, gameLocal.msec ); - - // Finally, apply a maximum cap, based on the player's normal walkspeed - float velocity = idMath::ClampFloat(0, pm_walkspeed.GetFloat()*0.8f, pushVelocity.NormalizeFast()); - - //gameRenderWorld->DrawText( idStr(velocity * accelScale * massScale), physics->GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - - // Apply the mass scale and the acceleration scale to the capped velocity - physics->SetLinearVelocity(pushVelocity * velocity * accelScale * massScale * entityScale); - - DM_LOG(LC_MOVEMENT, LT_INFO)LOGSTRING("Pushing obstacle %s\r", pushEnt->name.c_str()); - - isPushing = true; - - // Update the pushed status if this entity is a moveable - if (pushEnt->IsType(idMoveable::Type)) - { - // Pass the pushDirection to the moveable - static_cast(pushEnt)->SetIsPushed(true, impactVelocity); - } - } - } - - // Update the owning actor's push state if it has changed - SetOwnerIsPushing(isPushing); - - // Remember the last push entity - lastPushEnt = pushEnt; - - // Clear the push entity again - pushEnt = NULL; -} - -void CForcePush::SetOwnerIsPushing(bool isPushing) -{ - // Update the owning actor's push state if it has changed - if (owner->IsType(idActor::Type)) - { - idActor* owningActor = static_cast(owner); - - if (owningActor->IsPushing() != isPushing) - { - owningActor->SetIsPushing(isPushing); - } - } -} - -void CForcePush::Save( idSaveGame *savefile ) const -{ - // Store the entity pointer behind the physics object - savefile->WriteObject(pushEnt); - lastPushEnt.Save(savefile); - savefile->WriteInt(id); - savefile->WriteTrace(contactInfo); - savefile->WriteVec3(impactVelocity); - savefile->WriteInt(startPushTime); - savefile->WriteObject(owner); -} - -void CForcePush::Restore( idRestoreGame *savefile ) -{ - savefile->ReadObject(reinterpret_cast(pushEnt)); - lastPushEnt.Restore(savefile); - savefile->ReadInt(id); - savefile->ReadTrace(contactInfo); - savefile->ReadVec3(impactVelocity); - savefile->ReadInt(startPushTime); - savefile->ReadObject(reinterpret_cast(owner)); -} diff --git a/game/physics/force_push.h b/game/physics/force_push.h deleted file mode 100644 index 9e0c77844..000000000 --- a/game/physics/force_push.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -#ifndef __FORCE_PUSH_H__ -#define __FORCE_PUSH_H__ - -#include "force.h" -#include - -/** - * greebo: This class should represent the push force as applied by the player - * to large game world objects. - */ -class CForcePush : - public idForce -{ -public: - CLASS_PROTOTYPE( CForcePush ); - - CForcePush(); - - void SetOwner(idEntity* ownerEnt); - - // Set physics object which is about to be pushed - void SetPushEntity(idEntity* pushEnt, int id = -1); - - // Set the push parameters for the next evaluation frame - void SetContactInfo(const trace_t& contactInfo, const idVec3& impactVelocity); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -public: // common force interface - virtual void Evaluate( int time ); - -private: - void SetOwnerIsPushing(bool isPushing); - -private: - idEntity* pushEnt; // entity being pushed - idEntityPtr lastPushEnt; // the entity we pushed last frame - - int id; // clip model id of physics object - trace_t contactInfo; // the contact info of the object we're pushing - idVec3 impactVelocity; // the velocity the owner had at impact time - int startPushTime; // the time we started to push the physics object - - idEntity* owner; // the owning entity -}; -typedef boost::shared_ptr CForcePushPtr; - -#endif /* __FORCE_PUSH_H__ */ diff --git a/game/physics/force_spring.cpp b/game/physics/force_spring.cpp deleted file mode 100644 index f0a034760..000000000 --- a/game/physics/force_spring.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idForce, idForce_Spring ) -END_CLASS - -/* -================ -idForce_Spring::idForce_Spring -================ -*/ -idForce_Spring::idForce_Spring( void ) { - Kstretch = 100.0f; - Kcompress = 100.0f; - damping = 0.0f; - restLength = 0.0f; - physics1 = NULL; - id1 = 0; - p1 = vec3_zero; - physics2 = NULL; - id2 = 0; - p2 = vec3_zero; -} - -/* -================ -idForce_Spring::~idForce_Spring -================ -*/ -idForce_Spring::~idForce_Spring( void ) { -} - -/* -================ -idForce_Spring::InitSpring -================ -*/ -void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength ) { - this->Kstretch = Kstretch; - this->Kcompress = Kcompress; - this->damping = damping; - this->restLength = restLength; -} - -/* -================ -idForce_Spring::SetPosition -================ -*/ -void idForce_Spring::SetPosition( idPhysics *physics1, int id1, const idVec3 &p1, idPhysics *physics2, int id2, const idVec3 &p2 ) { - this->physics1 = physics1; - this->id1 = id1; - this->p1 = p1; - this->physics2 = physics2; - this->id2 = id2; - this->p2 = p2; -} - -/* -================ -idForce_Spring::Evaluate -================ -*/ -void idForce_Spring::Evaluate( int time ) { - float length; - idMat3 axis; - idVec3 pos1, pos2, velocity1, velocity2, force, dampingForce; - impactInfo_t info; - - pos1 = p1; - pos2 = p2; - velocity1 = velocity2 = vec3_origin; - - if ( physics1 ) { - axis = physics1->GetAxis( id1 ); - pos1 = physics1->GetOrigin( id1 ); - pos1 += p1 * axis; - if ( damping > 0.0f ) { - physics1->GetImpactInfo( id1, pos1, &info ); - velocity1 = info.velocity; - } - } - - if ( physics2 ) { - axis = physics2->GetAxis( id2 ); - pos2 = physics2->GetOrigin( id2 ); - pos2 += p2 * axis; - if ( damping > 0.0f ) { - physics2->GetImpactInfo( id2, pos2, &info ); - velocity2 = info.velocity; - } - } - - force = pos2 - pos1; - dampingForce = ( damping * ( ((velocity2 - velocity1) * force) / (force * force) ) ) * force; - length = force.Normalize(); - - // if the spring is stretched - if ( length > restLength ) { - if ( Kstretch > 0.0f ) { - force = ( Square( length - restLength ) * Kstretch ) * force - dampingForce; - if ( physics1 ) { - physics1->AddForce( id1, pos1, force ); - } - if ( physics2 ) { - physics2->AddForce( id2, pos2, -force ); - } - } - } - else { - if ( Kcompress > 0.0f ) { - force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce; - if ( physics1 ) { - physics1->AddForce( id1, pos1, -force ); - } - if ( physics2 ) { - physics2->AddForce( id2, pos2, force ); - } - } - } -} - -/* -================ -idForce_Spring::RemovePhysics -================ -*/ -void idForce_Spring::RemovePhysics( const idPhysics *phys ) { - if ( physics1 == phys ) { - physics1 = NULL; - } - if ( physics2 == phys ) { - physics2 = NULL; - } -} diff --git a/game/physics/force_spring.h b/game/physics/force_spring.h deleted file mode 100644 index 7d3507c9c..000000000 --- a/game/physics/force_spring.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __FORCE_SPRING_H__ -#define __FORCE_SPRING_H__ - -/* -=============================================================================== - - Spring force - -=============================================================================== -*/ - -class idForce_Spring : public idForce { - -public: - CLASS_PROTOTYPE( idForce_Spring ); - - idForce_Spring( void ); - virtual ~idForce_Spring( void ); - // initialize the spring - void InitSpring( float Kstretch, float Kcompress, float damping, float restLength ); - // set the entities and positions on these entities the spring is attached to - void SetPosition( idPhysics *physics1, int id1, const idVec3 &p1, - idPhysics *physics2, int id2, const idVec3 &p2 ); - -public: // common force interface - virtual void Evaluate( int time ); - virtual void RemovePhysics( const idPhysics *phys ); - -private: - - // spring properties - float Kstretch; - float Kcompress; - float damping; - float restLength; - - // positioning - idPhysics * physics1; // first physics object - int id1; // clip model id of first physics object - idVec3 p1; // position on clip model - idPhysics * physics2; // second physics object - int id2; // clip model id of second physics object - idVec3 p2; // position on clip model - -}; - -#endif /* !__FORCE_SPRING_H__ */ diff --git a/game/physics/physics.cpp b/game/physics/physics.cpp deleted file mode 100644 index 4b164a896..000000000 --- a/game/physics/physics.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -ABSTRACT_DECLARATION( idClass, idPhysics ) -END_CLASS - - -/* -================ -idPhysics::~idPhysics -================ -*/ -idPhysics::~idPhysics( void ) { -} - -/* -================ -idPhysics::Save -================ -*/ -void idPhysics::Save( idSaveGame *savefile ) const { -} - -/* -================ -idPhysics::Restore -================ -*/ -void idPhysics::Restore( idRestoreGame *savefile ) { -} - -/* -================ -idPhysics::SetClipBox -================ -*/ -void idPhysics::SetClipBox( const idBounds &bounds, float density ) { - SetClipModel( new idClipModel( idTraceModel( bounds ) ), density ); -} - -/* -================ -idPhysics::SnapTimeToPhysicsFrame -================ -*/ -int idPhysics::SnapTimeToPhysicsFrame( int t ) { - int s; - s = t + USERCMD_MSEC - 1; - return ( s - s % USERCMD_MSEC ); -} diff --git a/game/physics/physics.h b/game/physics/physics.h deleted file mode 100644 index aceceb1d4..000000000 --- a/game/physics/physics.h +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_H__ -#define __PHYSICS_H__ - -/* -=============================================================================== - - Physics abstract class - - A physics object is a tool to manipulate the position and orientation of - an entity. The physics object is a container for idClipModels used for - collision detection. The physics deals with moving these collision models - through the world according to the laws of physics or other rules. - - The mass of a clip model is the volume of the clip model times the density. - An arbitrary mass can however be set for specific clip models or the - whole physics object. The contents of a clip model is a set of bit flags - that define the contents. The clip mask defines the contents a clip model - collides with. - - The linear velocity of a physics object is a vector that defines the - translation of the center of mass in units per second. The angular velocity - of a physics object is a vector that passes through the center of mass. The - direction of this vector defines the axis of rotation and the magnitude - defines the rate of rotation about the axis in radians per second. - The gravity is the change in velocity per second due to gravitational force. - - Entities update their visual position and orientation from the physics - using GetOrigin() and GetAxis(). Direct origin and axis changes of - entities should go through the physics. In other words the physics origin - and axis are updated first and the entity updates its visual position - from the physics. - -=============================================================================== -*/ - -#define CONTACT_EPSILON 0.25f // maximum contact seperation distance - -class idEntity; -#ifdef MOD_WATERPHYSICS - -class idPhysics_Liquid; // MOD_WATERPHYSICS - -#endif - - -typedef struct impactInfo_s { - float invMass; // inverse mass - idMat3 invInertiaTensor; // inverse inertia tensor - idVec3 position; // impact position relative to center of mass - idVec3 velocity; // velocity at the impact position -} impactInfo_t; - - -class idPhysics : public idClass { - -public: - ABSTRACT_PROTOTYPE( idPhysics ); - - virtual ~idPhysics( void ); - static int SnapTimeToPhysicsFrame( int t ); - - // Must not be virtual - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -public: // common physics interface - // set pointer to entity using physics - virtual void SetSelf( idEntity *e ) = 0; - virtual idEntity * GetSelf( void ) { return NULL; } - // clip models - virtual void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ) = 0; - virtual void SetClipBox( const idBounds &bounds, float density ); - virtual idClipModel * GetClipModel( int id = 0 ) const = 0; - virtual int GetNumClipModels( void ) const = 0; - // get/set the mass of a specific clip model or the whole physics object - virtual void SetMass( float mass, int id = -1 ) = 0; - virtual float GetMass( int id = -1 ) const = 0; - // get/set the contents of a specific clip model or the whole physics object - virtual void SetContents( int contents, int id = -1 ) = 0; - virtual int GetContents( int id = -1 ) const = 0; - // get/set the contents a specific clip model or the whole physics object collides with - virtual void SetClipMask( int mask, int id = -1 ) = 0; - virtual int GetClipMask( int id = -1 ) const = 0; - // get the bounds of a specific clip model or the whole physics object - virtual const idBounds & GetBounds( int id = -1 ) const = 0; - virtual const idBounds & GetAbsBounds( int id = -1 ) const = 0; - // evaluate the physics with the given time step, returns true if the object moved - virtual bool Evaluate( int timeStepMSec, int endTimeMSec ) = 0; - // update the time without moving - virtual void UpdateTime( int endTimeMSec ) = 0; - // get the last physics update time - virtual int GetTime( void ) const = 0; - // collision interaction between different physics objects - virtual void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const = 0; - virtual void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) = 0; - - // greebo: Applies the impulse to this entity and lets it propagate to other contacts - // (not supported by all entities, works good in rigid body physics) - // returns true if the impulse has been applied to any neighbours - virtual bool PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ) = 0; - - virtual void AddForce( const int id, const idVec3 &point, const idVec3 &force ) = 0; - virtual void Activate( void ) = 0; - virtual void PutToRest( void ) = 0; - virtual bool IsAtRest( void ) const = 0; - virtual int GetRestStartTime( void ) const = 0; - virtual bool IsPushable( void ) const = 0; - // save and restore the physics state - virtual void SaveState( void ) = 0; - virtual void RestoreState( void ) = 0; - // set the position and orientation in master space or world space if no master set - virtual void SetOrigin( const idVec3 &newOrigin, int id = -1 ) = 0; - virtual void SetAxis( const idMat3 &newAxis, int id = -1 ) = 0; - // translate or rotate the physics object in world space - virtual void Translate( const idVec3 &translation, int id = -1 ) = 0; - virtual void Rotate( const idRotation &rotation, int id = -1 ) = 0; - // get the position and orientation in world space - virtual const idVec3 & GetOrigin( int id = 0 ) const = 0; - virtual const idMat3 & GetAxis( int id = 0 ) const = 0; - // set linear and angular velocity - virtual void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ) = 0; - virtual void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ) = 0; - // get linear and angular velocity - virtual const idVec3 & GetLinearVelocity( int id = 0 ) const = 0; - virtual const idVec3 & GetAngularVelocity( int id = 0 ) const = 0; - // gravity - virtual void SetGravity( const idVec3 &newGravity ) = 0; - virtual const idVec3 & GetGravity( void ) const = 0; - virtual const idVec3 & GetGravityNormal( void ) const = 0; - // get first collision when translating or rotating this physics object - virtual void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const = 0; - virtual void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const = 0; - virtual int ClipContents( const idClipModel *model ) const = 0; - // disable/enable the clip models contained by this physics object - virtual void DisableClip( void ) = 0; - virtual void EnableClip( void ) = 0; - // link/unlink the clip models contained by this physics object - virtual void UnlinkClip( void ) = 0; - virtual void LinkClip( void ) = 0; - // contacts - virtual bool EvaluateContacts( void ) = 0; - virtual int GetNumContacts( void ) const = 0; - virtual const contactInfo_t &GetContact( int num ) const = 0; - virtual void ClearContacts( void ) = 0; - virtual void AddContactEntity( idEntity *e ) = 0; - virtual void RemoveContactEntity( idEntity *e ) = 0; - // ground contacts - virtual bool HasGroundContacts( void ) const = 0; - virtual bool IsGroundEntity( int entityNum ) const = 0; - virtual bool IsGroundClipModel( int entityNum, int id ) const = 0; - // set the master entity for objects bound to a master - virtual void SetMaster( idEntity *master, const bool orientated = true ) = 0; - // set pushed state - virtual void SetPushed( int deltaTime ) = 0; - virtual const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const = 0; - virtual const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const = 0; - // get blocking info, returns NULL if the object is not blocked - virtual const trace_t * GetBlockingInfo( void ) const = 0; - virtual idEntity * GetBlockingEntity( void ) const = 0; - // movement end times in msec for reached events at the end of predefined motion - virtual int GetLinearEndTime( void ) const = 0; - virtual int GetAngularEndTime( void ) const = 0; - // networking - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const = 0; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ) = 0; - -#ifdef MOD_WATERPHYSICS - - // gets/sets the water - - virtual idPhysics_Liquid *GetWater() = 0; // MOD_WATERPHYSICS - - virtual void SetWater( idPhysics_Liquid *e, const float murkiness) = 0; // MOD_WATERPHYSICS - -#endif - -}; - -#endif /* !__PHYSICS_H__ */ diff --git a/game/physics/physics_actor.cpp b/game/physics/physics_actor.cpp deleted file mode 100644 index 0482442ae..000000000 --- a/game/physics/physics_actor.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics_Base, idPhysics_Actor ) -END_CLASS - -/* -================ -idPhysics_Actor::idPhysics_Actor -================ -*/ -idPhysics_Actor::idPhysics_Actor( void ) { - clipModel = NULL; - SetClipModelAxis(); - mass = 100.0f; - invMass = 1.0f / mass; - masterEntity = NULL; - masterYaw = 0.0f; - masterDeltaYaw = 0.0f; - groundEntityPtr = NULL; - -#ifdef MOD_WATERPHYSICS - waterLevel = WATERLEVEL_NONE; // MOD_WATERPHYSICS - waterType = 0; // MOD_WATERPHYSICS - waterLevelChanged = true; - submerseFrame = 0; - submerseTime = -1; -#endif // MOD_WATERPHYSICS -} - -/* -================ -idPhysics_Actor::~idPhysics_Actor -================ -*/ -idPhysics_Actor::~idPhysics_Actor( void ) { - if ( clipModel ) { - delete clipModel; - clipModel = NULL; - } -} - -/* -================ -idPhysics_Actor::Save -================ -*/ -void idPhysics_Actor::Save( idSaveGame *savefile ) const { - - savefile->WriteClipModel( clipModel ); - savefile->WriteMat3( clipModelAxis ); - - savefile->WriteFloat( mass ); - savefile->WriteFloat( invMass ); - - savefile->WriteObject( masterEntity ); - savefile->WriteFloat( masterYaw ); - savefile->WriteFloat( masterDeltaYaw ); - -#ifdef MOD_WATERPHYSICS - savefile->WriteInt( (int)waterLevel ); // MOD_WATERPHYSICS - savefile->WriteInt((int)previousWaterLevel); - savefile->WriteInt( waterType ); // MOD_WATERPHYSICS - savefile->WriteBool(waterLevelChanged); - savefile->WriteInt(submerseFrame); - savefile->WriteInt(submerseTime); -#endif // MOD_WATERPHYSICS - - groundEntityPtr.Save( savefile ); -} - -/* -================ -idPhysics_Actor::Restore -================ -*/ -void idPhysics_Actor::Restore( idRestoreGame *savefile ) { - - savefile->ReadClipModel( clipModel ); - savefile->ReadMat3( clipModelAxis ); - - savefile->ReadFloat( mass ); - savefile->ReadFloat( invMass ); - - savefile->ReadObject( reinterpret_cast( masterEntity ) ); - savefile->ReadFloat( masterYaw ); - savefile->ReadFloat( masterDeltaYaw ); - -#ifdef MOD_WATERPHYSICS - savefile->ReadInt( (int &)waterLevel ); // MOD_WATERPHYSICS - savefile->ReadInt( (int &)previousWaterLevel ); - savefile->ReadInt( waterType ); // MOD_WATERPHYSICS - savefile->ReadBool(waterLevelChanged); - savefile->ReadInt(submerseFrame); - savefile->ReadInt(submerseTime); -#endif // MOD_WATERPHYSICS - - groundEntityPtr.Restore( savefile ); -} - -/* -================ -idPhysics_Actor::SetClipModelAxis -================ -*/ -void idPhysics_Actor::SetClipModelAxis( void ) { - // align clip model to gravity direction - if ( ( gravityNormal[2] == -1.0f ) || ( gravityNormal == vec3_zero ) ) { - clipModelAxis.Identity(); - } - else { - clipModelAxis[2] = -gravityNormal; - clipModelAxis[2].NormalVectors( clipModelAxis[0], clipModelAxis[1] ); - clipModelAxis[1] = -clipModelAxis[1]; - } - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); - } -} - -/* -================ -idPhysics_Actor::GetGravityAxis -================ -*/ -const idMat3 &idPhysics_Actor::GetGravityAxis( void ) const { - return clipModelAxis; -} - -/* -================ -idPhysics_Actor::GetMasterDeltaYaw -================ -*/ -float idPhysics_Actor::GetMasterDeltaYaw( void ) const { - return masterDeltaYaw; -} - -/* -================ -idPhysics_Actor::GetGroundEntity -================ -*/ -idEntity *idPhysics_Actor::GetGroundEntity( void ) const { - return groundEntityPtr.GetEntity(); -} - -/* -================ -idPhysics_Actor::SetClipModel -================ -*/ -void idPhysics_Actor::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) { - assert( self ); - assert( model ); // a clip model is required - assert( model->IsTraceModel() ); // and it should be a trace model - assert( density > 0.0f ); // density should be valid - - if ( clipModel && clipModel != model && freeOld ) { - delete clipModel; - } - clipModel = model; - clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModelAxis ); -} - -/* -================ -idPhysics_Actor::GetClipModel -================ -*/ -idClipModel *idPhysics_Actor::GetClipModel( int id ) const { - return clipModel; -} - -/* -================ -idPhysics_Actor::GetNumClipModels -================ -*/ -int idPhysics_Actor::GetNumClipModels( void ) const { - return 1; -} - -/* -================ -idPhysics_Actor::SetMass -================ -*/ -void idPhysics_Actor::SetMass( float _mass, int id ) { - assert( _mass > 0.0f ); - mass = _mass; - invMass = 1.0f / _mass; -} - -/* -================ -idPhysics_Actor::GetMass -================ -*/ -float idPhysics_Actor::GetMass( int id ) const { - return mass; -} - -/* -================ -idPhysics_Actor::SetClipMask -================ -*/ -void idPhysics_Actor::SetContents( int contents, int id ) { - clipModel->SetContents( contents ); -} - -/* -================ -idPhysics_Actor::SetClipMask -================ -*/ -int idPhysics_Actor::GetContents( int id ) const { - return clipModel->GetContents(); -} - -/* -================ -idPhysics_Actor::GetBounds -================ -*/ -const idBounds &idPhysics_Actor::GetBounds( int id ) const { - return clipModel->GetBounds(); -} - -/* -================ -idPhysics_Actor::GetAbsBounds -================ -*/ -const idBounds &idPhysics_Actor::GetAbsBounds( int id ) const { - return clipModel->GetAbsBounds(); -} - -/* -================ -idPhysics_Actor::IsPushable -================ -*/ -bool idPhysics_Actor::IsPushable( void ) const { - return ( masterEntity == NULL ); -} - -/* -================ -idPhysics_Actor::GetOrigin -================ -*/ -const idVec3 &idPhysics_Actor::GetOrigin( int id ) const { - return clipModel->GetOrigin(); -} - -/* -================ -idPhysics_Player::GetAxis -================ -*/ -const idMat3 &idPhysics_Actor::GetAxis( int id ) const { - return clipModel->GetAxis(); -} - -/* -================ -idPhysics_Actor::SetGravity -================ -*/ -void idPhysics_Actor::SetGravity( const idVec3 &newGravity ) { - if ( newGravity != gravityVector ) { - idPhysics_Base::SetGravity( newGravity ); - SetClipModelAxis(); - } -} - -/* -================ -idPhysics_Actor::ClipTranslation -================ -*/ -void idPhysics_Actor::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, - clipModel, clipModel->GetAxis(), clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, - clipModel, clipModel->GetAxis(), clipMask, self ); - } -} - -/* -================ -idPhysics_Actor::ClipRotation -================ -*/ -void idPhysics_Actor::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation, - clipModel, clipModel->GetAxis(), clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, - clipModel, clipModel->GetAxis(), clipMask, self ); - } -} - -/* -================ -idPhysics_Actor::ClipContents -================ -*/ -int idPhysics_Actor::ClipContents( const idClipModel *model ) const { - if ( model ) { - return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); - } -} - -/* -================ -idPhysics_Actor::DisableClip -================ -*/ -void idPhysics_Actor::DisableClip( void ) { - clipModel->Disable(); -} - -/* -================ -idPhysics_Actor::EnableClip -================ -*/ -void idPhysics_Actor::EnableClip( void ) { - clipModel->Enable(); -} - -/* -================ -idPhysics_Actor::UnlinkClip -================ -*/ -void idPhysics_Actor::UnlinkClip( void ) { - clipModel->Unlink(); -} - -/* -================ -idPhysics_Actor::LinkClip -================ -*/ -void idPhysics_Actor::LinkClip( void ) { - clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), clipModel->GetAxis() ); -} - -/* -================ -idPhysics_Actor::EvaluateContacts -================ -*/ -bool idPhysics_Actor::EvaluateContacts( void ) { - - // get all the ground contacts - ClearContacts(); - AddGroundContacts( clipModel ); - AddContactEntitiesForContacts(); - - return ( contacts.Num() != 0 ); -} - -#ifdef MOD_WATERPHYSICS -/* -============= -idPhysics_Actor::SetWaterLevel -============= -*/ -void idPhysics_Actor::SetWaterLevel( bool updateWaterLevelChanged ) { - // - // get waterlevel, accounting for ducking - // - // Remember the current water level - previousWaterLevel = waterLevel; - - waterLevel = WATERLEVEL_NONE; - waterType = 0; - - const idVec3& origin = this->GetOrigin(); - const idBounds& bounds = clipModel->GetBounds(); - - // check at feet level - idVec3 point = origin - ( bounds[0][2] + 1.0f ) * gravityNormal; - int contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - // sets water entity - this->SetWaterLevelf(); - - waterType = contents; - waterLevel = WATERLEVEL_FEET; - - // check at waist level - point = origin - ( bounds[1][2] - bounds[0][2] ) * 0.5f * gravityNormal; - contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - - waterLevel = WATERLEVEL_WAIST; - - // check at head level - // point = origin - ( bounds[1][2] - 1.0f ) * gravityNormal; - - // greebo: Changed the check for head level to test the eyeheight. This is enough - // for letting AI drown or for the player to "feel" underwater. - point = static_cast(self)->GetEyePosition(); - - contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - waterLevel = WATERLEVEL_HEAD; - } - } - } - else - this->SetWater(NULL, 0.0f); - - if (updateWaterLevelChanged) - { - // Set the changed flag - waterLevelChanged = (previousWaterLevel != waterLevel); - - if (waterLevel == WATERLEVEL_HEAD && waterLevelChanged) - { - submerseFrame = gameLocal.framenum; - submerseTime = gameLocal.time; - } - } -} - -/* -================ -idPhysics_Actor::GetWaterLevel -================ -*/ -waterLevel_t idPhysics_Actor::GetWaterLevel( void ) const { - return waterLevel; -} - -/* -================ -idPhysics_Actor::GetWaterType -================ -*/ -int idPhysics_Actor::GetWaterType( void ) const { - return waterType; -} - -int idPhysics_Actor::GetSubmerseTime() const -{ - return submerseTime; -} - -#endif // MOD_WATERPHYSICS diff --git a/game/physics/physics_actor.h b/game/physics/physics_actor.h deleted file mode 100644 index 01960b192..000000000 --- a/game/physics/physics_actor.h +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_ACTOR_H__ -#define __PHYSICS_ACTOR_H__ - -/* -=================================================================================== - - Actor physics base class - - An actor typically uses one collision model which is aligned with the gravity - direction. The collision model is usually a simple box with the origin at the - bottom center. - -=================================================================================== -*/ - -#ifdef MOD_WATERPHYSICS -typedef enum { // MOD_WATERPHYSICS - WATERLEVEL_NONE, // MOD_WATERPHYSICS - WATERLEVEL_FEET, // MOD_WATERPHYSICS - WATERLEVEL_WAIST, // MOD_WATERPHYSICS - WATERLEVEL_HEAD // MOD_WATERPHYSICS -} waterLevel_t; // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - -class idPhysics_Actor : public idPhysics_Base { - -public: - CLASS_PROTOTYPE( idPhysics_Actor ); - - idPhysics_Actor( void ); - ~idPhysics_Actor( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // get delta yaw of master - float GetMasterDeltaYaw( void ) const; - // returns the ground entity - idEntity * GetGroundEntity( void ) const; - // align the clip model with the gravity direction - void SetClipModelAxis( void ); - -#ifdef MOD_WATERPHYSICS - virtual waterLevel_t GetWaterLevel( void ) const; // MOD_WATERPHYSICS - virtual int GetWaterType( void ) const; // MOD_WATERPHYSICS - - // greebo: returns the time we (last) submersed into water (above HEAD) - int GetSubmerseTime() const; -#endif - -public: // common physics interface - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool IsPushable( void ) const; - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetGravity( const idVec3 &newGravity ); - const idMat3 & GetGravityAxis( void ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - -protected: -#ifdef MOD_WATERPHYSICS - virtual void SetWaterLevel( bool updateWaterLevelChanged ); // MOD_WATERPHYSICS - waterLevel_t waterLevel; // MOD_WATERPHYSICS - waterLevel_t previousWaterLevel; // greebo: The water level of the previous frame - int waterType; // MOD_WATERPHYSICS - int submerseFrame; // greebo: The frame in which we submersed (above WATERLEVEL_HEAD) - int submerseTime; // greebo: The time we submersed (above WATERLEVEL_HEAD) - - // greebo: This is TRUE if the water level has changed since the last physics evaluation (frame) - bool waterLevelChanged; -#endif - - idClipModel * clipModel; // clip model used for collision detection - idMat3 clipModelAxis; // axis of clip model aligned with gravity direction - - // derived properties - float mass; - float invMass; - - // master - idEntity * masterEntity; - float masterYaw; - float masterDeltaYaw; - - // results of last evaluate - idEntityPtr groundEntityPtr; -}; - -#endif /* !__PHYSICS_ACTOR_H__ */ diff --git a/game/physics/physics_af.cpp b/game/physics/physics_af.cpp deleted file mode 100644 index 35c96d092..000000000 --- a/game/physics/physics_af.cpp +++ /dev/null @@ -1,8551 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../DarkMod/Grabber.h" - -CLASS_DECLARATION( idPhysics_Base, idPhysics_AF ) -END_CLASS - -const float ERROR_REDUCTION = 0.5f; -const float ERROR_REDUCTION_MAX = 256.0f; -const float LIMIT_ERROR_REDUCTION = 0.3f; -const float LCP_EPSILON = 1e-7f; -const float LIMIT_LCP_EPSILON = 1e-4f; -const float CONTACT_LCP_EPSILON = 1e-6f; -const float CENTER_OF_MASS_EPSILON = 1e-2f; -#ifdef MOD_WATERPHYSICS -const float NO_MOVE_TIME = 2.0f; -// ishtvan test: move impulse threshold back to D3 default or below -// const float IMPULSE_THRESHOLD = 1500.0f; -const float IMPULSE_THRESHOLD = 250.0f; -const float WATER_FRICTION = 0.0f; // we need AF friction to be a little bigger than RB water friction, we add this value -const float DEFAULT_LIQUID_SCALAR = -0.28f; -const float DEFAULT_LIQUID_DENSITY = 0.005f; -const float LIQUID_MASS_MUL = 3.0f; // I'm not sure how to explain this, without it body bob way too quickly -#else -const float NO_MOVE_TIME = 1.0f; -const float IMPULSE_THRESHOLD = 500.0f; -#endif -const float NO_MOVE_TRANSLATION_TOLERANCE = 10.0f; -const float NO_MOVE_ROTATION_TOLERANCE = 10.0f; -const float MIN_MOVE_TIME = -1.0f; -const float MAX_MOVE_TIME = -1.0f; -const float SUSPEND_LINEAR_VELOCITY = 10.0f; -const float SUSPEND_ANGULAR_VELOCITY = 15.0f; -const float SUSPEND_LINEAR_ACCELERATION = 20.0f; -const float SUSPEND_ANGULAR_ACCELERATION = 30.0f; -const idVec6 vec6_lcp_epsilon = idVec6( LCP_EPSILON, LCP_EPSILON, LCP_EPSILON, - LCP_EPSILON, LCP_EPSILON, LCP_EPSILON ); - -static const float MAX_GRABBER_EXT_VELOCITY = 120.0f; -static const float MAX_GRABBER_EXT_ANGVEL = 5.0f; - -#define AF_TIMINGS - -#ifdef AF_TIMINGS -static int lastTimerReset = 0; -static int numArticulatedFigures = 0; -static idTimer timer_total, timer_pc, timer_ac, timer_collision, timer_lcp; -#endif - - - -//=============================================================== -// -// idAFConstraint -// -//=============================================================== - -/* -================ -idAFConstraint::idAFConstraint -================ -*/ -idAFConstraint::idAFConstraint( void ) { - type = CONSTRAINT_INVALID; - name = "noname"; - body1 = NULL; - body2 = NULL; - physics = NULL; - - lo.Zero( 6 ); - lo.SubVec6(0) = -vec6_infinity; - hi.Zero( 6 ); - hi.SubVec6(0) = vec6_infinity; - e.SetSize( 6 ); - e.SubVec6(0) = vec6_lcp_epsilon; - - boxConstraint = NULL; - boxIndex[0] = -1; - boxIndex[1] = -1; - boxIndex[2] = -1; - boxIndex[3] = -1; - boxIndex[4] = -1; - boxIndex[5] = -1; - - firstIndex = 0; - - memset( &fl, 0, sizeof( fl ) ); -} - -/* -================ -idAFConstraint::~idAFConstraint -================ -*/ -idAFConstraint::~idAFConstraint( void ) { -} - -/* -================ -idAFConstraint::SetBody1 -================ -*/ -void idAFConstraint::SetBody1( idAFBody *body ) { - if ( body1 != body) { - body1 = body; - if ( physics ) { - physics->SetChanged(); - } - } -} - -/* -================ -idAFConstraint::SetBody2 -================ -*/ -void idAFConstraint::SetBody2( idAFBody *body ) { - if ( body2 != body ) { - body2 = body; - if ( physics ) { - physics->SetChanged(); - } - } -} - -/* -================ -idAFConstraint::GetMultiplier -================ -*/ -const idVecX &idAFConstraint::GetMultiplier( void ) { - return lm; -} - -/* -================ -idAFConstraint::Evaluate -================ -*/ -void idAFConstraint::Evaluate( float invTimeStep ) { - assert( 0 ); -} - -/* -================ -idAFConstraint::ApplyFriction -================ -*/ -void idAFConstraint::ApplyFriction( float invTimeStep ) { -} - -/* -================ -idAFConstraint::GetForce -================ -*/ -void idAFConstraint::GetForce( idAFBody *body, idVec6 &force ) { - idVecX v; - - v.SetData( 6, VECX_ALLOCA( 6 ) ); - if ( body == body1 ) { - J1.TransposeMultiply( v, lm ); - } - else if ( body == body2 ) { - J2.TransposeMultiply( v, lm ); - } - else { - v.Zero(); - } - force[0] = v[0]; force[1] = v[1]; force[2] = v[2]; force[3] = v[3]; force[4] = v[4]; force[5] = v[5]; -} - -/* -================ -idAFConstraint::Translate -================ -*/ -void idAFConstraint::Translate( const idVec3 &translation ) { - assert( 0 ); -} - -/* -================ -idAFConstraint::Rotate -================ -*/ -void idAFConstraint::Rotate( const idRotation &rotation ) { - assert( 0 ); -} - -/* -================ -idAFConstraint::GetCenter -================ -*/ -void idAFConstraint::GetCenter( idVec3 ¢er ) { - center.Zero(); -} - -/* -================ -idAFConstraint::DebugDraw -================ -*/ -void idAFConstraint::DebugDraw( void ) { -} - -/* -================ -idAFConstraint::InitSize -================ -*/ -void idAFConstraint::InitSize( int size ) { - J1.Zero( size, 6 ); - J2.Zero( size, 6 ); - c1.Zero( size ); - c2.Zero( size ); - s.Zero( size ); - lm.Zero( size ); -} - -/* -================ -idAFConstraint::Save -================ -*/ -void idAFConstraint::Save( idSaveGame *saveFile ) const { - saveFile->WriteInt( type ); -} - -/* -================ -idAFConstraint::Restore -================ -*/ -void idAFConstraint::Restore( idRestoreGame *saveFile ) { - constraintType_t t; - saveFile->ReadInt( (int &)t ); - assert( t == type ); -} - - -//=============================================================== -// -// idAFConstraint_Fixed -// -//=============================================================== - -/* -================ -idAFConstraint_Fixed::idAFConstraint_Fixed -================ -*/ -idAFConstraint_Fixed::idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_FIXED; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 6 ); - fl.allowPrimary = true; - fl.noCollision = true; - - InitOffset(); -} - -/* -================ -idAFConstraint_Fixed::InitOffset -================ -*/ -void idAFConstraint_Fixed::InitOffset( void ) { - if ( body2 ) { - offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose(); - } - else { - offset = body1->GetWorldOrigin(); - relAxis = body1->GetWorldAxis(); - } -} - -/* -================ -idAFConstraint_Fixed::SetBody1 -================ -*/ -void idAFConstraint_Fixed::SetBody1( idAFBody *body ) { - if ( body1 != body) { - body1 = body; - InitOffset(); - if ( physics ) { - physics->SetChanged(); - } - } -} - -/* -================ -idAFConstraint_Fixed::SetBody2 -================ -*/ -void idAFConstraint_Fixed::SetBody2( idAFBody *body ) { - if ( body2 != body ) { - body2 = body; - InitOffset(); - if ( physics ) { - physics->SetChanged(); - } - } -} - -/* -================ -idAFConstraint_Fixed::Evaluate -================ -*/ -void idAFConstraint_Fixed::Evaluate( float invTimeStep ) { - idVec3 ofs, a2; - idMat3 ax; - idRotation r; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - a2 = offset * master->GetWorldAxis(); - ofs = a2 + master->GetWorldOrigin(); - ax = relAxis * master->GetWorldAxis(); - } - else { - a2.Zero(); - ofs = offset; - ax = relAxis; - } - - J1.Set( mat3_identity, mat3_zero, - mat3_zero, mat3_identity ); - - if ( body2 ) { - J2.Set( -mat3_identity, SkewSymmetric( a2 ), - mat3_zero, -mat3_identity ); - } - else { - J2.Zero( 6, 6 ); - } - - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( ofs - body1->GetWorldOrigin() ); - r = ( body1->GetWorldAxis().Transpose() * ax ).ToRotation(); - c1.SubVec3(1) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * -(float) DEG2RAD( r.GetAngle() ) ); - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); -} - -/* -================ -idAFConstraint_Fixed::ApplyFriction -================ -*/ -void idAFConstraint_Fixed::ApplyFriction( float invTimeStep ) { - // no friction -} - -/* -================ -idAFConstraint_Fixed::Translate -================ -*/ -void idAFConstraint_Fixed::Translate( const idVec3 &translation ) { - if ( !body2 ) { - offset += translation; - } -} - -/* -================ -idAFConstraint_Fixed::Rotate -================ -*/ -void idAFConstraint_Fixed::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - offset *= rotation; - relAxis *= rotation.ToMat3(); - } -} - -/* -================ -idAFConstraint_Fixed::GetCenter -================ -*/ -void idAFConstraint_Fixed::GetCenter( idVec3 ¢er ) { - center = body1->GetWorldOrigin(); -} - -/* -================ -idAFConstraint_Fixed::DebugDraw -================ -*/ -void idAFConstraint_Fixed::DebugDraw( void ) { - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - if ( master ) { - gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), master->GetWorldOrigin() ); - } - else { - gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), vec3_origin ); - } -} - -/* -================ -idAFConstraint_Fixed::Save -================ -*/ -void idAFConstraint_Fixed::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( offset ); - saveFile->WriteMat3( relAxis ); -} - -/* -================ -idAFConstraint_Fixed::Restore -================ -*/ -void idAFConstraint_Fixed::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( offset ); - saveFile->ReadMat3( relAxis ); -} - - -//=============================================================== -// -// idAFConstraint_BallAndSocketJoint -// -//=============================================================== - -/* -================ -idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint -================ -*/ -idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_BALLANDSOCKETJOINT; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 3 ); - coneLimit = NULL; - pyramidLimit = NULL; - friction = 0.0f; - fc = NULL; - fl.allowPrimary = true; - fl.noCollision = true; -} - -/* -================ -idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint -================ -*/ -idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint( void ) { - if ( coneLimit ) { - delete coneLimit; - } - if ( pyramidLimit ) { - delete pyramidLimit; - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::SetAnchor -================ -*/ -void idAFConstraint_BallAndSocketJoint::SetAnchor( const idVec3 &worldPosition ) { - - // get anchor relative to center of mass of body1 - anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get anchor relative to center of mass of body2 - anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - } - else { - anchor2 = worldPosition; - } - - if ( coneLimit ) { - coneLimit->SetAnchor( anchor2 ); - } - if ( pyramidLimit ) { - pyramidLimit->SetAnchor( anchor2 ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::GetAnchor -================ -*/ -idVec3 idAFConstraint_BallAndSocketJoint::GetAnchor( void ) const { - if ( body2 ) { - return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; - } - return anchor2; -} - -/* -================ -idAFConstraint_BallAndSocketJoint::SetNoLimit -================ -*/ -void idAFConstraint_BallAndSocketJoint::SetNoLimit( void ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } - if ( pyramidLimit ) { - delete pyramidLimit; - pyramidLimit = NULL; - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::SetConeLimit -================ -*/ -void idAFConstraint_BallAndSocketJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) { - if ( pyramidLimit ) { - delete pyramidLimit; - pyramidLimit = NULL; - } - if ( !coneLimit ) { - coneLimit = new idAFConstraint_ConeLimit; - coneLimit->SetPhysics( physics ); - } - if ( body2 ) { - coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, body1Axis * body1->GetWorldAxis().Transpose() ); - } - else { - coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, body1Axis * body1->GetWorldAxis().Transpose() ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::SetPyramidLimit -================ -*/ -void idAFConstraint_BallAndSocketJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float angle1, const float angle2, const idVec3 &body1Axis ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } - if ( !pyramidLimit ) { - pyramidLimit = new idAFConstraint_PyramidLimit; - pyramidLimit->SetPhysics( physics ); - } - if ( body2 ) { - pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(), - baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2, - body1Axis * body1->GetWorldAxis().Transpose() ); - } - else { - pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2, - body1Axis * body1->GetWorldAxis().Transpose() ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::SetLimitEpsilon -================ -*/ -void idAFConstraint_BallAndSocketJoint::SetLimitEpsilon( const float e ) { - if ( coneLimit ) { - coneLimit->SetEpsilon( e ); - } - if ( pyramidLimit ) { - pyramidLimit->SetEpsilon( e ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::GetFriction -================ -*/ -float idAFConstraint_BallAndSocketJoint::GetFriction( void ) const { - if ( af_forceFriction.GetFloat() > 0.0f ) { - return af_forceFriction.GetFloat(); - } - return friction * physics->GetJointFrictionScale(); -} - -/* -================ -idAFConstraint_BallAndSocketJoint::Evaluate -================ -*/ -void idAFConstraint_BallAndSocketJoint::Evaluate( float invTimeStep ) { - idVec3 a1, a2; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = anchor1 * body1->GetWorldAxis(); - - if ( master ) { - a2 = anchor2 * master->GetWorldAxis(); - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); - } - else { - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( anchor2 - ( a1 + body1->GetWorldOrigin() ) ); - } - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); - - J1.Set( mat3_identity, -SkewSymmetric( a1 ) ); - - if ( body2 ) { - J2.Set( -mat3_identity, SkewSymmetric( a2 ) ); - } - else { - J2.Zero( 3, 6 ); - } - - if ( coneLimit ) { - coneLimit->Add( physics, invTimeStep ); - } - else if ( pyramidLimit ) { - pyramidLimit->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::ApplyFriction -================ -*/ -void idAFConstraint_BallAndSocketJoint::ApplyFriction( float invTimeStep ) { - idVec3 angular; - float invMass, currentFriction; - - currentFriction = GetFriction(); - - if ( currentFriction <= 0.0f ) { - return; - } - - if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { - - angular = body1->GetAngularVelocity(); - invMass = body1->GetInverseMass(); - if ( body2 ) { - angular -= body2->GetAngularVelocity(); - invMass += body2->GetInverseMass(); - } - - angular *= currentFriction / invMass; - - body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); - if ( body2 ) { - body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); - } - } - else { - if ( !fc ) { - fc = new idAFConstraint_BallAndSocketJointFriction; - fc->Setup( this ); - } - - fc->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::GetForce -================ -*/ -void idAFConstraint_BallAndSocketJoint::GetForce( idAFBody *body, idVec6 &force ) { - idAFConstraint::GetForce( body, force ); - // FIXME: add limit force -} - -/* -================ -idAFConstraint_BallAndSocketJoint::Translate -================ -*/ -void idAFConstraint_BallAndSocketJoint::Translate( const idVec3 &translation ) { - if ( !body2 ) { - anchor2 += translation; - } - if ( coneLimit ) { - coneLimit->Translate( translation ); - } - else if ( pyramidLimit ) { - pyramidLimit->Translate( translation ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::Rotate -================ -*/ -void idAFConstraint_BallAndSocketJoint::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - anchor2 *= rotation; - } - if ( coneLimit ) { - coneLimit->Rotate( rotation ); - } - else if ( pyramidLimit ) { - pyramidLimit->Rotate( rotation ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::GetCenter -================ -*/ -void idAFConstraint_BallAndSocketJoint::GetCenter( idVec3 ¢er ) { - center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); -} - -/* -================ -idAFConstraint_BallAndSocketJoint::DebugDraw -================ -*/ -void idAFConstraint_BallAndSocketJoint::DebugDraw( void ) { - idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 5, 0, 0 ), a1 + idVec3( 5, 0, 0 ) ); - gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 5, 0 ), a1 + idVec3( 0, 5, 0 ) ); - gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 0, 5 ), a1 + idVec3( 0, 0, 5 ) ); - - if ( af_showLimits.GetBool() ) { - if ( coneLimit ) { - coneLimit->DebugDraw(); - } - if ( pyramidLimit ) { - pyramidLimit->DebugDraw(); - } - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::Save -================ -*/ -void idAFConstraint_BallAndSocketJoint::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( anchor1 ); - saveFile->WriteVec3( anchor2 ); - saveFile->WriteFloat( friction ); - if ( coneLimit ) { - coneLimit->Save( saveFile ); - } - if ( pyramidLimit ) { - pyramidLimit->Save( saveFile ); - } -} - -/* -================ -idAFConstraint_BallAndSocketJoint::Restore -================ -*/ -void idAFConstraint_BallAndSocketJoint::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( anchor1 ); - saveFile->ReadVec3( anchor2 ); - saveFile->ReadFloat( friction ); - if ( coneLimit ) { - coneLimit->Restore( saveFile ); - } - if ( pyramidLimit ) { - pyramidLimit->Restore( saveFile ); - } -} - - -//=============================================================== -// -// idAFConstraint_BallAndSocketJointFriction -// -//=============================================================== - -/* -================ -idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction -================ -*/ -idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction( void ) { - type = CONSTRAINT_FRICTION; - name = "ballAndSocketJointFriction"; - InitSize( 3 ); - joint = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::Setup -================ -*/ -void idAFConstraint_BallAndSocketJointFriction::Setup( idAFConstraint_BallAndSocketJoint *bsj ) { - this->joint = bsj; - body1 = bsj->GetBody1(); - body2 = bsj->GetBody2(); -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::Evaluate -================ -*/ -void idAFConstraint_BallAndSocketJointFriction::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::ApplyFriction -================ -*/ -void idAFConstraint_BallAndSocketJointFriction::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::Add -================ -*/ -bool idAFConstraint_BallAndSocketJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) { - float f; - - physics = phys; - - f = joint->GetFriction() * joint->GetMultiplier().Length(); - if ( f == 0.0f ) { - return false; - } - - lo[0] = lo[1] = lo[2] = -f; - hi[0] = hi[1] = hi[2] = f; - - J1.Zero( 3, 6 ); - J1[0][3] = J1[1][4] = J1[2][5] = 1.0f; - - if ( body2 ) { - - J2.Zero( 3, 6 ); - J2[0][3] = J2[1][4] = J2[2][5] = 1.0f; - } - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::Translate -================ -*/ -void idAFConstraint_BallAndSocketJointFriction::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_BallAndSocketJointFriction::Rotate -================ -*/ -void idAFConstraint_BallAndSocketJointFriction::Rotate( const idRotation &rotation ) { -} - - -//=============================================================== -// -// idAFConstraint_UniversalJoint -// -//=============================================================== - -/* -================ -idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint -================ -*/ -idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_UNIVERSALJOINT; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 4 ); - coneLimit = NULL; - pyramidLimit = NULL; - friction = 0.0f; - fc = NULL; - fl.allowPrimary = true; - fl.noCollision = true; -} - -/* -================ -idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint -================ -*/ -idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint( void ) { - if ( coneLimit ) { - delete coneLimit; - } - if ( pyramidLimit ) { - delete pyramidLimit; - } - if ( fc ) { - delete fc; - } -} - -/* -================ -idAFConstraint_UniversalJoint::SetAnchor -================ -*/ -void idAFConstraint_UniversalJoint::SetAnchor( const idVec3 &worldPosition ) { - - // get anchor relative to center of mass of body1 - anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get anchor relative to center of mass of body2 - anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - } - else { - anchor2 = worldPosition; - } - - if ( coneLimit ) { - coneLimit->SetAnchor( anchor2 ); - } - if ( pyramidLimit ) { - pyramidLimit->SetAnchor( anchor2 ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::GetAnchor -================ -*/ -idVec3 idAFConstraint_UniversalJoint::GetAnchor( void ) const { - if ( body2 ) { - return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; - } - return anchor2; -} - -/* -================ -idAFConstraint_UniversalJoint::SetShafts -================ -*/ -void idAFConstraint_UniversalJoint::SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 ) { - idVec3 cardanAxis; - float l; - - shaft1 = cardanShaft1; - l = shaft1.Normalize(); - assert( l != 0.0f ); - shaft2 = cardanShaft2; - l = shaft2.Normalize(); - assert( l != 0.0f ); - - // the cardan axis is a vector orthogonal to both cardan shafts - cardanAxis = shaft1.Cross( shaft2 ); - if ( cardanAxis.Normalize() == 0.0f ) { - idVec3 vecY; - shaft1.OrthogonalBasis( cardanAxis, vecY ); - cardanAxis.Normalize(); - } - - shaft1 *= body1->GetWorldAxis().Transpose(); - axis1 = cardanAxis * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - shaft2 *= body2->GetWorldAxis().Transpose(); - axis2 = cardanAxis * body2->GetWorldAxis().Transpose(); - } - else { - axis2 = cardanAxis; - } - - if ( coneLimit ) { - coneLimit->SetBody1Axis( shaft1 ); - } - if ( pyramidLimit ) { - pyramidLimit->SetBody1Axis( shaft1 ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::SetNoLimit -================ -*/ -void idAFConstraint_UniversalJoint::SetNoLimit( void ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } - if ( pyramidLimit ) { - delete pyramidLimit; - pyramidLimit = NULL; - } -} - -/* -================ -idAFConstraint_UniversalJoint::SetConeLimit -================ -*/ -void idAFConstraint_UniversalJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle ) { - if ( pyramidLimit ) { - delete pyramidLimit; - pyramidLimit = NULL; - } - if ( !coneLimit ) { - coneLimit = new idAFConstraint_ConeLimit; - coneLimit->SetPhysics( physics ); - } - if ( body2 ) { - coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, shaft1 ); - } - else { - coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, shaft1 ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::SetPyramidLimit -================ -*/ -void idAFConstraint_UniversalJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float angle1, const float angle2 ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } - if ( !pyramidLimit ) { - pyramidLimit = new idAFConstraint_PyramidLimit; - pyramidLimit->SetPhysics( physics ); - } - if ( body2 ) { - pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(), - baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2, shaft1 ); - } - else { - pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2, shaft1 ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::SetLimitEpsilon -================ -*/ -void idAFConstraint_UniversalJoint::SetLimitEpsilon( const float e ) { - if ( coneLimit ) { - coneLimit->SetEpsilon( e ); - } - if ( pyramidLimit ) { - pyramidLimit->SetEpsilon( e ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::GetFriction -================ -*/ -float idAFConstraint_UniversalJoint::GetFriction( void ) const { - if ( af_forceFriction.GetFloat() > 0.0f ) { - return af_forceFriction.GetFloat(); - } - return friction * physics->GetJointFrictionScale(); -} - -/* -================ -idAFConstraint_UniversalJoint::Evaluate - - NOTE: this joint is homokinetic -================ -*/ -void idAFConstraint_UniversalJoint::Evaluate( float invTimeStep ) { - idVec3 a1, a2, s1, s2, d1, d2, v; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = anchor1 * body1->GetWorldAxis(); - s1 = shaft1 * body1->GetWorldAxis(); - d1 = s1.Cross( axis1 * body1->GetWorldAxis() ); - - if ( master ) { - a2 = anchor2 * master->GetWorldAxis(); - s2 = shaft2 * master->GetWorldAxis(); - d2 = axis2 * master->GetWorldAxis(); - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); - } - else { - a2 = anchor2; - s2 = shaft2; - d2 = axis2; - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) ); - } - - J1.Set( mat3_identity, -SkewSymmetric( a1 ), - mat3_zero, idMat3( s1[0], s1[1], s1[2], - 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f ) ); - J1.SetSize( 4, 6 ); - - if ( body2 ) { - J2.Set( -mat3_identity, SkewSymmetric( a2 ), - mat3_zero, idMat3( s2[0], s2[1], s2[2], - 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f ) ); - J2.SetSize( 4, 6 ); - } - else { - J2.Zero( 4, 6 ); - } - - v = s1.Cross( s2 ); - if ( v.Normalize() != 0.0f ) { - idMat3 m1, m2; - - m1[0] = s1; - m1[1] = v; - m1[2] = v.Cross( m1[0] ); - - m2[0] = -s2; - m2[1] = v; - m2[2] = v.Cross( m2[0] ); - - d2 *= m2.Transpose() * m1; - } - - c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( d1 * d2 ); - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); - - if ( coneLimit ) { - coneLimit->Add( physics, invTimeStep ); - } - else if ( pyramidLimit ) { - pyramidLimit->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::ApplyFriction -================ -*/ -void idAFConstraint_UniversalJoint::ApplyFriction( float invTimeStep ) { - idVec3 angular; - float invMass, currentFriction; - - currentFriction = GetFriction(); - - if ( currentFriction <= 0.0f ) { - return; - } - - if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { - - angular = body1->GetAngularVelocity(); - invMass = body1->GetInverseMass(); - if ( body2 ) { - angular -= body2->GetAngularVelocity(); - invMass += body2->GetInverseMass(); - } - - angular *= currentFriction / invMass; - - body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); - if ( body2 ) { - body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); - } - } - else { - if ( !fc ) { - fc = new idAFConstraint_UniversalJointFriction; - fc->Setup( this ); - } - - fc->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::GetForce -================ -*/ -void idAFConstraint_UniversalJoint::GetForce( idAFBody *body, idVec6 &force ) { - idAFConstraint::GetForce( body, force ); - // FIXME: add limit force -} - -/* -================ -idAFConstraint_UniversalJoint::Translate -================ -*/ -void idAFConstraint_UniversalJoint::Translate( const idVec3 &translation ) { - if ( !body2 ) { - anchor2 += translation; - } - if ( coneLimit ) { - coneLimit->Translate( translation ); - } - else if ( pyramidLimit ) { - pyramidLimit->Translate( translation ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::Rotate -================ -*/ -void idAFConstraint_UniversalJoint::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - anchor2 *= rotation; - shaft2 *= rotation.ToMat3(); - axis2 *= rotation.ToMat3(); - } - if ( coneLimit ) { - coneLimit->Rotate( rotation ); - } - else if ( pyramidLimit ) { - pyramidLimit->Rotate( rotation ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::GetCenter -================ -*/ -void idAFConstraint_UniversalJoint::GetCenter( idVec3 ¢er ) { - center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); -} - -/* -================ -idAFConstraint_UniversalJoint::DebugDraw -================ -*/ -void idAFConstraint_UniversalJoint::DebugDraw( void ) { - idVec3 a1, a2, s1, s2, d1, d2, v; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - s1 = shaft1 * body1->GetWorldAxis(); - d1 = axis1 * body1->GetWorldAxis(); - - if ( master ) { - a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); - s2 = shaft2 * master->GetWorldAxis(); - d2 = axis2 * master->GetWorldAxis(); - } - else { - a2 = anchor2; - s2 = shaft2; - d2 = axis2; - } - - v = s1.Cross( s2 ); - if ( v.Normalize() != 0.0f ) { - idMat3 m1, m2; - - m1[0] = s1; - m1[1] = v; - m1[2] = v.Cross( m1[0] ); - - m2[0] = -s2; - m2[1] = v; - m2[2] = v.Cross( m2[0] ); - - d2 *= m2.Transpose() * m1; - } - - gameRenderWorld->DebugArrow( colorCyan, a1, a1 + s1 * 5.0f, 1 ); - gameRenderWorld->DebugArrow( colorBlue, a2, a2 + s2 * 5.0f, 1 ); - gameRenderWorld->DebugLine( colorGreen, a1, a1 + d1 * 5.0f ); - gameRenderWorld->DebugLine( colorGreen, a2, a2 + d2 * 5.0f ); - - if ( af_showLimits.GetBool() ) { - if ( coneLimit ) { - coneLimit->DebugDraw(); - } - if ( pyramidLimit ) { - pyramidLimit->DebugDraw(); - } - } -} - -/* -================ -idAFConstraint_UniversalJoint::Save -================ -*/ -void idAFConstraint_UniversalJoint::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( anchor1 ); - saveFile->WriteVec3( anchor2 ); - saveFile->WriteVec3( shaft1 ); - saveFile->WriteVec3( shaft2 ); - saveFile->WriteVec3( axis1 ); - saveFile->WriteVec3( axis2 ); - saveFile->WriteFloat( friction ); - if ( coneLimit ) { - coneLimit->Save( saveFile ); - } - if ( pyramidLimit ) { - pyramidLimit->Save( saveFile ); - } -} - -/* -================ -idAFConstraint_UniversalJoint::Restore -================ -*/ -void idAFConstraint_UniversalJoint::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( anchor1 ); - saveFile->ReadVec3( anchor2 ); - saveFile->ReadVec3( shaft1 ); - saveFile->ReadVec3( shaft2 ); - saveFile->ReadVec3( axis1 ); - saveFile->ReadVec3( axis2 ); - saveFile->ReadFloat( friction ); - if ( coneLimit ) { - coneLimit->Restore( saveFile ); - } - if ( pyramidLimit ) { - pyramidLimit->Restore( saveFile ); - } -} - - -//=============================================================== -// -// idAFConstraint_UniversalJointFriction -// -//=============================================================== - -/* -================ -idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction -================ -*/ -idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction( void ) { - type = CONSTRAINT_FRICTION; - name = "universalJointFriction"; - InitSize( 2 ); - joint = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_UniversalJointFriction::Setup -================ -*/ -void idAFConstraint_UniversalJointFriction::Setup( idAFConstraint_UniversalJoint *uj ) { - this->joint = uj; - body1 = uj->GetBody1(); - body2 = uj->GetBody2(); -} - -/* -================ -idAFConstraint_UniversalJointFriction::Evaluate -================ -*/ -void idAFConstraint_UniversalJointFriction::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_UniversalJointFriction::ApplyFriction -================ -*/ -void idAFConstraint_UniversalJointFriction::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_UniversalJointFriction::Add -================ -*/ -bool idAFConstraint_UniversalJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) { - idVec3 s1, s2, dir1, dir2; - float f; - - physics = phys; - - f = joint->GetFriction() * joint->GetMultiplier().Length(); - if ( f == 0.0f ) { - return false; - } - - lo[0] = lo[1] = -f; - hi[0] = hi[1] = f; - - joint->GetShafts( s1, s2 ); - - s1 *= body1->GetWorldAxis(); - s1.NormalVectors( dir1, dir2 ); - - J1.SetSize( 2, 6 ); - J1.SubVec6(0).SubVec3(0).Zero(); - J1.SubVec6(0).SubVec3(1) = dir1; - J1.SubVec6(1).SubVec3(0).Zero(); - J1.SubVec6(1).SubVec3(1) = dir2; - - if ( body2 ) { - - J2.SetSize( 2, 6 ); - J2.SubVec6(0).SubVec3(0).Zero(); - J2.SubVec6(0).SubVec3(1) = -dir1; - J2.SubVec6(1).SubVec3(0).Zero(); - J2.SubVec6(1).SubVec3(1) = -dir2; - } - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_UniversalJointFriction::Translate -================ -*/ -void idAFConstraint_UniversalJointFriction::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_UniversalJointFriction::Rotate -================ -*/ -void idAFConstraint_UniversalJointFriction::Rotate( const idRotation &rotation ) { -} - - -//=============================================================== -// -// idAFConstraint_CylindricalJoint -// -//=============================================================== - -/* -================ -idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint -================ -*/ -idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_CylindricalJoint::Evaluate -================ -*/ -void idAFConstraint_CylindricalJoint::Evaluate( float invTimeStep ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_CylindricalJoint::ApplyFriction -================ -*/ -void idAFConstraint_CylindricalJoint::ApplyFriction( float invTimeStep ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_CylindricalJoint::Translate -================ -*/ -void idAFConstraint_CylindricalJoint::Translate( const idVec3 &translation ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_CylindricalJoint::Rotate -================ -*/ -void idAFConstraint_CylindricalJoint::Rotate( const idRotation &rotation ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_CylindricalJoint::DebugDraw -================ -*/ -void idAFConstraint_CylindricalJoint::DebugDraw( void ) { - assert( 0 ); // FIXME: implement -} - - -//=============================================================== -// -// idAFConstraint_Hinge -// -//=============================================================== - -/* -================ -idAFConstraint_Hinge::idAFConstraint_Hinge -================ -*/ -idAFConstraint_Hinge::idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_HINGE; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 5 ); - coneLimit = NULL; - steering = NULL; - friction = 0.0f; - fc = NULL; - fl.allowPrimary = true; - fl.noCollision = true; - initialAxis = body1->GetWorldAxis(); - if ( body2 ) { - initialAxis *= body2->GetWorldAxis().Transpose(); - } -} - -/* -================ -idAFConstraint_Hinge::~idAFConstraint_Hinge -================ -*/ -idAFConstraint_Hinge::~idAFConstraint_Hinge( void ) { - if ( coneLimit ) { - delete coneLimit; - } - if ( fc ) { - delete fc; - } - if ( steering ) { - delete steering; - } -} - -/* -================ -idAFConstraint_Hinge::SetAnchor -================ -*/ -void idAFConstraint_Hinge::SetAnchor( const idVec3 &worldPosition ) { - // get anchor relative to center of mass of body1 - anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get anchor relative to center of mass of body2 - anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - } - else { - anchor2 = worldPosition; - } - - if ( coneLimit ) { - coneLimit->SetAnchor( anchor2 ); - } -} - -/* -================ -idAFConstraint_Hinge::GetAnchor -================ -*/ -idVec3 idAFConstraint_Hinge::GetAnchor( void ) const { - if ( body2 ) { - return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2; - } - return anchor2; -} - -/* -================ -idAFConstraint_Hinge::SetAxis -================ -*/ -void idAFConstraint_Hinge::SetAxis( const idVec3 &axis ) { - idVec3 normAxis; - - normAxis = axis; - normAxis.Normalize(); - - // get axis relative to body1 - axis1 = normAxis * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get axis relative to body2 - axis2 = normAxis * body2->GetWorldAxis().Transpose(); - } - else { - axis2 = normAxis; - } -} - -/* -================ -idAFConstraint_Hinge::GetAxis -================ -*/ -idVec3 idAFConstraint_Hinge::GetAxis( void ) const { - if ( body2 ) { - return axis2 * body2->GetWorldAxis(); - } - return axis2; -} - -/* -================ -idAFConstraint_Hinge::SetNoLimit -================ -*/ -void idAFConstraint_Hinge::SetNoLimit( void ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } -} - -/* -================ -idAFConstraint_Hinge::SetLimit -================ -*/ -void idAFConstraint_Hinge::SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis ) { - if ( !coneLimit ) { - coneLimit = new idAFConstraint_ConeLimit; - coneLimit->SetPhysics( physics ); - } - if ( body2 ) { - coneLimit->Setup( body1, body2, anchor2, axis * body2->GetWorldAxis().Transpose(), angle, body1Axis * body1->GetWorldAxis().Transpose() ); - } - else { - coneLimit->Setup( body1, body2, anchor2, axis, angle, body1Axis * body1->GetWorldAxis().Transpose() ); - } -} - -/* -================ -idAFConstraint_Hinge::SetLimitEpsilon -================ -*/ -void idAFConstraint_Hinge::SetLimitEpsilon( const float e ) { - if ( coneLimit ) { - coneLimit->SetEpsilon( e ); - } -} - -/* -================ -idAFConstraint_Hinge::GetFriction -================ -*/ -float idAFConstraint_Hinge::GetFriction( void ) const { - if ( af_forceFriction.GetFloat() > 0.0f ) { - return af_forceFriction.GetFloat(); - } - return friction * physics->GetJointFrictionScale(); -} - -/* -================ -idAFConstraint_Hinge::GetAngle -================ -*/ -float idAFConstraint_Hinge::GetAngle( void ) const { - idMat3 axis; - idRotation rotation; - float angle; - - axis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose() * initialAxis.Transpose(); - rotation = axis.ToRotation(); - angle = rotation.GetAngle(); - if ( rotation.GetVec() * axis1 < 0.0f ) { - return -angle; - } - return angle; -} - -/* -================ -idAFConstraint_Hinge::SetSteerAngle -================ -*/ -void idAFConstraint_Hinge::SetSteerAngle( const float degrees ) { - if ( coneLimit ) { - delete coneLimit; - coneLimit = NULL; - } - if ( !steering ) { - steering = new idAFConstraint_HingeSteering(); - steering->Setup( this ); - } - steering->SetSteerAngle( degrees ); -} - -/* -================ -idAFConstraint_Hinge::SetSteerSpeed -================ -*/ -void idAFConstraint_Hinge::SetSteerSpeed( const float speed ) { - if ( steering ) { - steering->SetSteerSpeed( speed ); - } -} - -/* -================ -idAFConstraint_Hinge::Evaluate -================ -*/ -void idAFConstraint_Hinge::Evaluate( float invTimeStep ) { - idVec3 a1, a2; - idVec3 x1, x2, cross; - idVec3 vecX, vecY; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - x1 = axis1 * body1->GetWorldAxis(); // axis in body1 space - x1.OrthogonalBasis( vecX, vecY ); // basis for axis in body1 space - - a1 = anchor1 * body1->GetWorldAxis(); // anchor in body1 space - - if ( master ) { - a2 = anchor2 * master->GetWorldAxis(); // anchor in master space - x2 = axis2 * master->GetWorldAxis(); - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) ); - } - else { - a2 = anchor2; - x2 = axis2; - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) ); - } - - J1.Set( mat3_identity, -SkewSymmetric( a1 ), - mat3_zero, idMat3( vecX[0], vecX[1], vecX[2], - vecY[0], vecY[1], vecY[2], - 0.0f, 0.0f, 0.0f ) ); - J1.SetSize( 5, 6 ); - - if ( body2 ) { - J2.Set( -mat3_identity, SkewSymmetric( a2 ), - mat3_zero, idMat3( -vecX[0], -vecX[1], -vecX[2], - -vecY[0], -vecY[1], -vecY[2], - 0.0f, 0.0f, 0.0f ) ); - J2.SetSize( 5, 6 ); - } - else { - J2.Zero( 5, 6 ); - } - - cross = x1.Cross( x2 ); - - c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecX ); - c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecY ); - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); - - if ( steering ) { - steering->Add( physics, invTimeStep ); - } - else if ( coneLimit ) { - coneLimit->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_Hinge::ApplyFriction -================ -*/ -void idAFConstraint_Hinge::ApplyFriction( float invTimeStep ) { - idVec3 angular; - float invMass, currentFriction; - - currentFriction = GetFriction(); - - if ( currentFriction <= 0.0f ) { - return; - } - - if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) { - - angular = body1->GetAngularVelocity(); - invMass = body1->GetInverseMass(); - if ( body2 ) { - angular -= body2->GetAngularVelocity(); - invMass += body2->GetInverseMass(); - } - - angular *= currentFriction / invMass; - - body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() ); - if ( body2 ) { - body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() ); - } - } - else { - if ( !fc ) { - fc = new idAFConstraint_HingeFriction; - fc->Setup( this ); - } - - fc->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_Hinge::GetForce -================ -*/ -void idAFConstraint_Hinge::GetForce( idAFBody *body, idVec6 &force ) { - idAFConstraint::GetForce( body, force ); - // FIXME: add limit force -} - -/* -================ -idAFConstraint_Hinge::Translate -================ -*/ -void idAFConstraint_Hinge::Translate( const idVec3 &translation ) { - if ( !body2 ) { - anchor2 += translation; - } - if ( coneLimit ) { - coneLimit->Translate( translation ); - } -} - -/* -================ -idAFConstraint_Hinge::Rotate -================ -*/ -void idAFConstraint_Hinge::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - anchor2 *= rotation; - axis2 *= rotation.ToMat3(); - } - if ( coneLimit ) { - coneLimit->Rotate( rotation ); - } -} - -/* -================ -idAFConstraint_Hinge::GetCenter -================ -*/ -void idAFConstraint_Hinge::GetCenter( idVec3 ¢er ) { - center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); -} - -/* -================ -idAFConstraint_Hinge::DebugDraw -================ -*/ -void idAFConstraint_Hinge::DebugDraw( void ) { - idVec3 vecX, vecY; - idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - idVec3 x1 = axis1 * body1->GetWorldAxis(); - x1.OrthogonalBasis( vecX, vecY ); - - gameRenderWorld->DebugArrow( colorBlue, a1 - 4.0f * x1, a1 + 4.0f * x1, 1 ); - gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecX, a1 + 2.0f * vecX ); - gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecY, a1 + 2.0f * vecY ); - - if ( af_showLimits.GetBool() ) { - if ( coneLimit ) { - coneLimit->DebugDraw(); - } - } -} - -/* -================ -idAFConstraint_Hinge::Save -================ -*/ -void idAFConstraint_Hinge::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( anchor1 ); - saveFile->WriteVec3( anchor2 ); - saveFile->WriteVec3( axis1 ); - saveFile->WriteVec3( axis2 ); - saveFile->WriteMat3( initialAxis ); - saveFile->WriteFloat( friction ); - if ( coneLimit ) { - saveFile->WriteBool( true ); - coneLimit->Save( saveFile ); - } else { - saveFile->WriteBool( false ); - } - if ( steering ) { - saveFile->WriteBool( true ); - steering->Save( saveFile ); - } else { - saveFile->WriteBool( false ); - } - if ( fc ) { - saveFile->WriteBool( true ); - fc->Save( saveFile ); - } else { - saveFile->WriteBool( false ); - } -} - -/* -================ -idAFConstraint_Hinge::Restore -================ -*/ -void idAFConstraint_Hinge::Restore( idRestoreGame *saveFile ) { - bool b; - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( anchor1 ); - saveFile->ReadVec3( anchor2 ); - saveFile->ReadVec3( axis1 ); - saveFile->ReadVec3( axis2 ); - saveFile->ReadMat3( initialAxis ); - saveFile->ReadFloat( friction ); - - saveFile->ReadBool( b ); - if ( b ) { - if ( !coneLimit ) { - coneLimit = new idAFConstraint_ConeLimit; - } - coneLimit->SetPhysics( physics ); - coneLimit->Restore( saveFile ); - } - saveFile->ReadBool( b ); - if ( b ) { - if ( !steering ) { - steering = new idAFConstraint_HingeSteering; - } - steering->Setup( this ); - steering->Restore( saveFile ); - } - saveFile->ReadBool( b ); - if ( b ) { - if ( !fc ) { - fc = new idAFConstraint_HingeFriction; - } - fc->Setup( this ); - fc->Restore( saveFile ); - } -} - - -//=============================================================== -// -// idAFConstraint_HingeFriction -// -//=============================================================== - -/* -================ -idAFConstraint_HingeFriction::idAFConstraint_HingeFriction -================ -*/ -idAFConstraint_HingeFriction::idAFConstraint_HingeFriction( void ) { - type = CONSTRAINT_FRICTION; - name = "hingeFriction"; - InitSize( 1 ); - hinge = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_HingeFriction::Setup -================ -*/ -void idAFConstraint_HingeFriction::Setup( idAFConstraint_Hinge *h ) { - this->hinge = h; - body1 = h->GetBody1(); - body2 = h->GetBody2(); -} - -/* -================ -idAFConstraint_HingeFriction::Evaluate -================ -*/ -void idAFConstraint_HingeFriction::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_HingeFriction::ApplyFriction -================ -*/ -void idAFConstraint_HingeFriction::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_HingeFriction::Add -================ -*/ -bool idAFConstraint_HingeFriction::Add( idPhysics_AF *phys, float invTimeStep ) { - idVec3 a1, a2; - float f; - - physics = phys; - - f = hinge->GetFriction() * hinge->GetMultiplier().Length(); - if ( f == 0.0f ) { - return false; - } - - lo[0] = -f; - hi[0] = f; - - hinge->GetAxis( a1, a2 ); - - a1 *= body1->GetWorldAxis(); - - J1.SetSize( 1, 6 ); - J1.SubVec6(0).SubVec3(0).Zero(); - J1.SubVec6(0).SubVec3(1) = a1; - - if ( body2 ) { - a2 *= body2->GetWorldAxis(); - - J2.SetSize( 1, 6 ); - J2.SubVec6(0).SubVec3(0).Zero(); - J2.SubVec6(0).SubVec3(1) = -a2; - } - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_HingeFriction::Translate -================ -*/ -void idAFConstraint_HingeFriction::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_HingeFriction::Rotate -================ -*/ -void idAFConstraint_HingeFriction::Rotate( const idRotation &rotation ) { -} - - -//=============================================================== -// -// idAFConstraint_HingeSteering -// -//=============================================================== - -/* -================ -idAFConstraint_HingeSteering::idAFConstraint_HingeSteering -================ -*/ -idAFConstraint_HingeSteering::idAFConstraint_HingeSteering( void ) { - type = CONSTRAINT_HINGESTEERING; - name = "hingeFriction"; - InitSize( 1 ); - hinge = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; - steerSpeed = 0.0f; - epsilon = LCP_EPSILON; -} - -/* -================ -idAFConstraint_HingeSteering::Save -================ -*/ -void idAFConstraint_HingeSteering::Save( idSaveGame *saveFile ) const { - saveFile->WriteFloat(steerAngle); - saveFile->WriteFloat(steerSpeed); - saveFile->WriteFloat(epsilon); -} - -/* -================ -idAFConstraint_HingeSteering::Restore -================ -*/ -void idAFConstraint_HingeSteering::Restore( idRestoreGame *saveFile ) { - saveFile->ReadFloat(steerAngle); - saveFile->ReadFloat(steerSpeed); - saveFile->ReadFloat(epsilon); -} - -/* -================ -idAFConstraint_HingeSteering::Setup -================ -*/ -void idAFConstraint_HingeSteering::Setup( idAFConstraint_Hinge *h ) { - this->hinge = h; - body1 = h->GetBody1(); - body2 = h->GetBody2(); -} - -/* -================ -idAFConstraint_HingeSteering::Evaluate -================ -*/ -void idAFConstraint_HingeSteering::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_HingeSteering::ApplyFriction -================ -*/ -void idAFConstraint_HingeSteering::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_HingeSteering::Add -================ -*/ -bool idAFConstraint_HingeSteering::Add( idPhysics_AF *phys, float invTimeStep ) { - float angle, speed; - idVec3 a1, a2; - - physics = phys; - - hinge->GetAxis( a1, a2 ); - angle = hinge->GetAngle(); - - a1 *= body1->GetWorldAxis(); - - J1.SetSize( 1, 6 ); - J1.SubVec6(0).SubVec3(0).Zero(); - J1.SubVec6(0).SubVec3(1) = a1; - - if ( body2 ) { - a2 *= body2->GetWorldAxis(); - - J2.SetSize( 1, 6 ); - J2.SubVec6(0).SubVec3(0).Zero(); - J2.SubVec6(0).SubVec3(1) = -a2; - } - - speed = steerAngle - angle; - if ( steerSpeed != 0.0f ) { - if ( speed > steerSpeed ) { - speed = steerSpeed; - } - else if ( speed < -steerSpeed ) { - speed = -steerSpeed; - } - } - - c1[0] = DEG2RAD( speed ) * invTimeStep; - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_HingeSteering::Translate -================ -*/ -void idAFConstraint_HingeSteering::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_HingeSteering::Rotate -================ -*/ -void idAFConstraint_HingeSteering::Rotate( const idRotation &rotation ) { -} - - -//=============================================================== -// -// idAFConstraint_Slider -// -//=============================================================== - -/* -================ -idAFConstraint_Slider::idAFConstraint_Slider -================ -*/ -idAFConstraint_Slider::idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_SLIDER; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 5 ); - fl.allowPrimary = true; - fl.noCollision = true; - - if ( body2 ) { - offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose(); - } - else { - offset = body1->GetWorldOrigin(); - relAxis = body1->GetWorldAxis(); - } -} - -/* -================ -idAFConstraint_Slider::SetAxis -================ -*/ -void idAFConstraint_Slider::SetAxis( const idVec3 &ax ) { - idVec3 normAxis; - - // get normalized axis relative to body1 - normAxis = ax; - normAxis.Normalize(); - if ( body2 ) { - axis = normAxis * body2->GetWorldAxis().Transpose(); - } - else { - axis = normAxis; - } -} - -/* -================ -idAFConstraint_Slider::Evaluate -================ -*/ -void idAFConstraint_Slider::Evaluate( float invTimeStep ) { - idVec3 vecX, vecY, ofs; - idRotation r; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - (axis * master->GetWorldAxis()).OrthogonalBasis( vecX, vecY ); - ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); - r = ( body1->GetWorldAxis().Transpose() * (relAxis * master->GetWorldAxis()) ).ToRotation(); - } - else { - axis.OrthogonalBasis( vecX, vecY ); - ofs = offset - body1->GetWorldOrigin(); - r = ( body1->GetWorldAxis().Transpose() * relAxis ).ToRotation(); - } - - J1.Set( mat3_zero, mat3_identity, - idMat3( vecX, vecY, vec3_origin ), mat3_zero ); - J1.SetSize( 5, 6 ); - - if ( body2 ) { - - J2.Set( mat3_zero, -mat3_identity, - idMat3( -vecX, -vecY, vec3_origin ), mat3_zero ); - J2.SetSize( 5, 6 ); - } - else { - J2.Zero( 5, 6 ); - } - - c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * - (float) DEG2RAD( r.GetAngle() ) ); - - c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( vecX * ofs ); - c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( vecY * ofs ); - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); -} - -/* -================ -idAFConstraint_Slider::ApplyFriction -================ -*/ -void idAFConstraint_Slider::ApplyFriction( float invTimeStep ) { - // no friction -} - -/* -================ -idAFConstraint_Slider::Translate -================ -*/ -void idAFConstraint_Slider::Translate( const idVec3 &translation ) { - if ( !body2 ) { - offset += translation; - } -} - -/* -================ -idAFConstraint_Slider::Rotate -================ -*/ -void idAFConstraint_Slider::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - offset *= rotation; - } -} - -/* -================ -idAFConstraint_Slider::GetCenter -================ -*/ -void idAFConstraint_Slider::GetCenter( idVec3 ¢er ) { - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - if ( master ) { - center = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); - } - else { - center = offset - body1->GetWorldOrigin(); - } -} - -/* -================ -idAFConstraint_Slider::DebugDraw -================ -*/ -void idAFConstraint_Slider::DebugDraw( void ) { - idVec3 ofs; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - if ( master ) { - ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin(); - } - else { - ofs = offset - body1->GetWorldOrigin(); - } - gameRenderWorld->DebugLine( colorGreen, ofs, ofs + axis * body1->GetWorldAxis() ); -} - -/* -================ -idAFConstraint_Slider::Save -================ -*/ -void idAFConstraint_Slider::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( axis ); - saveFile->WriteVec3( offset ); - saveFile->WriteMat3( relAxis ); -} - -/* -================ -idAFConstraint_Slider::Restore -================ -*/ -void idAFConstraint_Slider::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( axis ); - saveFile->ReadVec3( offset ); - saveFile->ReadMat3( relAxis ); -} - - -//=============================================================== -// -// idAFConstraint_Line -// -//=============================================================== - -/* -================ -idAFConstraint_Line::idAFConstraint_Line -================ -*/ -idAFConstraint_Line::idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_Line::Evaluate -================ -*/ -void idAFConstraint_Line::Evaluate( float invTimeStep ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_Line::ApplyFriction -================ -*/ -void idAFConstraint_Line::ApplyFriction( float invTimeStep ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_Line::Translate -================ -*/ -void idAFConstraint_Line::Translate( const idVec3 &translation ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_Line::Rotate -================ -*/ -void idAFConstraint_Line::Rotate( const idRotation &rotation ) { - assert( 0 ); // FIXME: implement -} - -/* -================ -idAFConstraint_Line::DebugDraw -================ -*/ -void idAFConstraint_Line::DebugDraw( void ) { - assert( 0 ); // FIXME: implement -} - - -//=============================================================== -// -// idAFConstraint_Plane -// -//=============================================================== - -/* -================ -idAFConstraint_Plane::idAFConstraint_Plane -================ -*/ -idAFConstraint_Plane::idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_PLANE; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 1 ); - fl.allowPrimary = true; - fl.noCollision = true; -} - -/* -================ -idAFConstraint_Plane::SetPlane -================ -*/ -void idAFConstraint_Plane::SetPlane( const idVec3 &normal, const idVec3 &anchor ) { - // get anchor relative to center of mass of body1 - anchor1 = ( anchor - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get anchor relative to center of mass of body2 - anchor2 = ( anchor - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - planeNormal = normal * body2->GetWorldAxis().Transpose(); - } - else { - anchor2 = anchor; - planeNormal = normal; - } -} - -/* -================ -idAFConstraint_Plane::Evaluate -================ -*/ -void idAFConstraint_Plane::Evaluate( float invTimeStep ) { - idVec3 a1, a2, normal, p; - idVec6 v; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - if ( master ) { - a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); - normal = planeNormal * master->GetWorldAxis(); - } - else { - a2 = anchor2; - normal = planeNormal; - } - - p = a1 - body1->GetWorldOrigin(); - v.SubVec3(0) = normal; - v.SubVec3(1) = p.Cross( normal ); - J1.Set( 1, 6, v.ToFloatPtr() ); - - if ( body2 ) { - p = a1 - body2->GetWorldOrigin(); - v.SubVec3(0) = -normal; - v.SubVec3(1) = p.Cross( -normal ); - J2.Set( 1, 6, v.ToFloatPtr() ); - } - - c1[0] = -( invTimeStep * ERROR_REDUCTION ) * (a1 * normal - a2 * normal); - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); -} - -/* -================ -idAFConstraint_Plane::ApplyFriction -================ -*/ -void idAFConstraint_Plane::ApplyFriction( float invTimeStep ) { - // no friction -} - -/* -================ -idAFConstraint_Plane::Translate -================ -*/ -void idAFConstraint_Plane::Translate( const idVec3 &translation ) { - if ( !body2 ) { - anchor2 += translation; - } -} - -/* -================ -idAFConstraint_Plane::Rotate -================ -*/ -void idAFConstraint_Plane::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - anchor2 *= rotation; - planeNormal *= rotation.ToMat3(); - } -} - -/* -================ -idAFConstraint_Plane::DebugDraw -================ -*/ -void idAFConstraint_Plane::DebugDraw( void ) { - idVec3 a1, normal, right, up; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - if ( master ) { - normal = planeNormal * master->GetWorldAxis(); - } - else { - normal = planeNormal; - } - normal.NormalVectors( right, up ); - normal *= 4.0f; - right *= 4.0f; - up *= 4.0f; - - gameRenderWorld->DebugLine( colorCyan, a1 - right, a1 + right ); - gameRenderWorld->DebugLine( colorCyan, a1 - up, a1 + up ); - gameRenderWorld->DebugArrow( colorCyan, a1, a1 + normal, 1 ); -} - -/* -================ -idAFConstraint_Plane::Save -================ -*/ -void idAFConstraint_Plane::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( anchor1 ); - saveFile->WriteVec3( anchor2 ); - saveFile->WriteVec3( planeNormal ); -} - -/* -================ -idAFConstraint_Plane::Restore -================ -*/ -void idAFConstraint_Plane::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( anchor1 ); - saveFile->ReadVec3( anchor2 ); - saveFile->ReadVec3( planeNormal ); -} - - -//=============================================================== -// -// idAFConstraint_Spring -// -//=============================================================== - -/* -================ -idAFConstraint_Spring::idAFConstraint_Spring -================ -*/ -idAFConstraint_Spring::idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 ) { - assert( body1 ); - type = CONSTRAINT_SPRING; - this->name = name; - this->body1 = body1; - this->body2 = body2; - InitSize( 1 ); - fl.allowPrimary = false; - kstretch = kcompress = damping = 1.0f; - minLength = maxLength = restLength = 0.0f; -} - -/* -================ -idAFConstraint_Spring::SetAnchor -================ -*/ -void idAFConstraint_Spring::SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 ) { - // get anchor relative to center of mass of body1 - anchor1 = ( worldAnchor1 - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - if ( body2 ) { - // get anchor relative to center of mass of body2 - anchor2 = ( worldAnchor2 - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose(); - } - else { - anchor2 = worldAnchor2; - } -} - -/* -================ -idAFConstraint_Spring::SetSpring -================ -*/ -void idAFConstraint_Spring::SetSpring( const float stretch, const float compress, const float damping, const float restLength ) { - assert( stretch >= 0.0f && compress >= 0.0f && restLength >= 0.0f ); - this->kstretch = stretch; - this->kcompress = compress; - this->damping = damping; - this->restLength = restLength; -} - -/* -================ -idAFConstraint_Spring::SetLimit -================ -*/ -void idAFConstraint_Spring::SetLimit( const float minLength, const float maxLength ) { - assert( minLength >= 0.0f && maxLength >= 0.0f && maxLength >= minLength ); - this->minLength = minLength; - this->maxLength = maxLength; -} - -/* -================ -idAFConstraint_Spring::Evaluate -================ -*/ -void idAFConstraint_Spring::Evaluate( float invTimeStep ) { - idVec3 a1, a2, velocity1, velocity2, force; - idVec6 v1, v2; - float d, dampingForce, length, error; - bool limit; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - velocity1 = body1->GetPointVelocity( a1 ); - - if ( master ) { - a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); - velocity2 = master->GetPointVelocity( a2 ); - } - else { - a2 = anchor2; - velocity2.Zero(); - } - - force = a2 - a1; - d = force * force; - if ( d != 0.0f ) { - dampingForce = damping * idMath::Fabs( (velocity2 - velocity1) * force ) / d; - } - else { - dampingForce = 0.0f; - } - length = force.Normalize(); - - if ( length > restLength ) { - if ( kstretch > 0.0f ) { - idVec3 springForce = force * ( Square( length - restLength ) * kstretch - dampingForce ); - body1->AddForce( a1, springForce ); - if ( master ) { - master->AddForce( a2, -springForce ); - } - } - } - else { - if ( kcompress > 0.0f ) { - idVec3 springForce = force * -( Square( restLength - length ) * kcompress - dampingForce ); - body1->AddForce( a1, springForce ); - if ( master ) { - master->AddForce( a2, -springForce ); - } - } - } - - // check for spring limits - if ( length < minLength ) { - force = -force; - error = minLength - length; - limit = true; - } - else if ( maxLength > 0.0f && length > maxLength ) { - error = length - maxLength; - limit = true; - } - else { - error = 0.0f; - limit = false; - } - - if ( limit ) { - a1 -= body1->GetWorldOrigin(); - v1.SubVec3(0) = force; - v1.SubVec3(1) = a1.Cross( force ); - J1.Set( 1, 6, v1.ToFloatPtr() ); - if ( body2 ) { - a2 -= body2->GetWorldOrigin(); - v2.SubVec3(0) = -force; - v2.SubVec3(1) = a2.Cross( -force ); - J2.Set( 1, 6, v2.ToFloatPtr() ); - } - c1[0] = -( invTimeStep * ERROR_REDUCTION ) * error; - lo[0] = 0.0f; - } - else { - J1.Zero( 0, 0 ); - J2.Zero( 0, 0 ); - } - - c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX ); -} - -/* -================ -idAFConstraint_Spring::ApplyFriction -================ -*/ -void idAFConstraint_Spring::ApplyFriction( float invTimeStep ) { - // no friction -} - -/* -================ -idAFConstraint_Spring::Translate -================ -*/ -void idAFConstraint_Spring::Translate( const idVec3 &translation ) { - if ( !body2 ) { - anchor2 += translation; - } -} - -/* -================ -idAFConstraint_Spring::Rotate -================ -*/ -void idAFConstraint_Spring::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - anchor2 *= rotation; - } -} - -/* -================ -idAFConstraint_Spring::GetCenter -================ -*/ -void idAFConstraint_Spring::GetCenter( idVec3 ¢er ) { - idAFBody *master; - idVec3 a1, a2; - - master = body2 ? body2 : physics->GetMasterBody(); - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - if ( master ) { - a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); - } - else { - a2 = anchor2; - } - center = ( a1 + a2 ) * 0.5f; -} - -/* -================ -idAFConstraint_Spring::DebugDraw -================ -*/ -void idAFConstraint_Spring::DebugDraw( void ) { - idAFBody *master; - float length; - idVec3 a1, a2, dir, mid, p; - - master = body2 ? body2 : physics->GetMasterBody(); - a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis(); - if ( master ) { - a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis(); - } - else { - a2 = anchor2; - } - dir = a2 - a1; - mid = a1 + 0.5f * dir; - length = dir.Normalize(); - - // draw spring - gameRenderWorld->DebugLine( colorGreen, a1, a2 ); - - // draw rest length - p = restLength * 0.5f * dir; - gameRenderWorld->DebugCircle( colorWhite, mid + p, dir, 1.0f, 10 ); - gameRenderWorld->DebugCircle( colorWhite, mid - p, dir, 1.0f, 10 ); - if ( restLength > length ) { - gameRenderWorld->DebugLine( colorWhite, a2, mid + p ); - gameRenderWorld->DebugLine( colorWhite, a1, mid - p ); - } - - if ( minLength > 0.0f ) { - // draw min length - gameRenderWorld->DebugCircle( colorBlue, mid + minLength * 0.5f * dir, dir, 2.0f, 10 ); - gameRenderWorld->DebugCircle( colorBlue, mid - minLength * 0.5f * dir, dir, 2.0f, 10 ); - } - - if ( maxLength > 0.0f ) { - // draw max length - gameRenderWorld->DebugCircle( colorRed, mid + maxLength * 0.5f * dir, dir, 2.0f, 10 ); - gameRenderWorld->DebugCircle( colorRed, mid - maxLength * 0.5f * dir, dir, 2.0f, 10 ); - } -} - -/* -================ -idAFConstraint_Spring::Save -================ -*/ -void idAFConstraint_Spring::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( anchor1 ); - saveFile->WriteVec3( anchor2 ); - saveFile->WriteFloat( kstretch ); - saveFile->WriteFloat( kcompress ); - saveFile->WriteFloat( damping ); - saveFile->WriteFloat( restLength ); - saveFile->WriteFloat( minLength ); - saveFile->WriteFloat( maxLength ); -} - -/* -================ -idAFConstraint_Spring::Restore -================ -*/ -void idAFConstraint_Spring::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( anchor1 ); - saveFile->ReadVec3( anchor2 ); - saveFile->ReadFloat( kstretch ); - saveFile->ReadFloat( kcompress ); - saveFile->ReadFloat( damping ); - saveFile->ReadFloat( restLength ); - saveFile->ReadFloat( minLength ); - saveFile->ReadFloat( maxLength ); -} - - -//=============================================================== -// -// idAFConstraint_Contact -// -//=============================================================== - -/* -================ -idAFConstraint_Contact::idAFConstraint_Contact -================ -*/ -idAFConstraint_Contact::idAFConstraint_Contact( void ) { - name = "contact"; - type = CONSTRAINT_CONTACT; - InitSize( 1 ); - fc = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_Contact::~idAFConstraint_Contact -================ -*/ -idAFConstraint_Contact::~idAFConstraint_Contact( void ) { - if ( fc ) { - delete fc; - } -} - -/* -================ -idAFConstraint_Contact::Setup -================ -*/ -void idAFConstraint_Contact::Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c ) { - idVec3 p; - idVec6 v; - float vel; - float minBounceVelocity = 2.0f; - - assert( b1 ); - - body1 = b1; - body2 = b2; - contact = c; - - p = c.point - body1->GetWorldOrigin(); - v.SubVec3(0) = c.normal; - v.SubVec3(1) = p.Cross( c.normal ); - J1.Set( 1, 6, v.ToFloatPtr() ); - vel = v.SubVec3(0) * body1->GetLinearVelocity() + v.SubVec3(1) * body1->GetAngularVelocity(); - - if ( body2 ) { - p = c.point - body2->GetWorldOrigin(); - v.SubVec3(0) = -c.normal; - v.SubVec3(1) = p.Cross( -c.normal ); - J2.Set( 1, 6, v.ToFloatPtr() ); - vel += v.SubVec3(0) * body2->GetLinearVelocity() + v.SubVec3(1) * body2->GetAngularVelocity(); - c2[0] = 0.0f; - } - - if ( body1->GetBouncyness() > 0.0f && -vel > minBounceVelocity ) { - c1[0] = body1->GetBouncyness() * vel; - } else { - c1[0] = 0.0f; - } - - e[0] = CONTACT_LCP_EPSILON; - lo[0] = 0.0f; - hi[0] = idMath::INFINITY; - boxConstraint = NULL; - boxIndex[0] = -1; -} - -/* -================ -idAFConstraint_Contact::Evaluate -================ -*/ -void idAFConstraint_Contact::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_Contact::ApplyFriction -================ -*/ -void idAFConstraint_Contact::ApplyFriction( float invTimeStep ) { - idVec3 r, velocity, normal, dir1, dir2; - float friction, magnitude, forceNumerator, forceDenominator; - idVecX impulse, dv; - - friction = body1->GetContactFriction(); - if ( body2 && body2->GetContactFriction() < friction ) { - friction = body2->GetContactFriction(); - } - - friction *= physics->GetContactFrictionScale(); - - if ( friction <= 0.0f ) { - return; - } - - // seperate friction per contact is silly but it's fast and often looks close enough - if ( af_useImpulseFriction.GetBool() ) { - - impulse.SetData( 6, VECX_ALLOCA( 6 ) ); - dv.SetData( 6, VECX_ALLOCA( 6 ) ); - - // calculate velocity in the contact plane - r = contact.point - body1->GetWorldOrigin(); - velocity = body1->GetLinearVelocity() + body1->GetAngularVelocity().Cross( r ); - velocity -= contact.normal * velocity * contact.normal; - - // get normalized direction of friction and magnitude of velocity - normal = -velocity; - magnitude = normal.Normalize(); - - forceNumerator = friction * magnitude; - forceDenominator = body1->GetInverseMass() + ( ( body1->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal ); - impulse.SubVec3(0) = (forceNumerator / forceDenominator) * normal; - impulse.SubVec3(1) = r.Cross( impulse.SubVec3(0) ); - body1->InverseWorldSpatialInertiaMultiply( dv, impulse.ToFloatPtr() ); - - // modify velocity with friction force - body1->SetLinearVelocity( body1->GetLinearVelocity() + dv.SubVec3(0) ); - body1->SetAngularVelocity( body1->GetAngularVelocity() + dv.SubVec3(1) ); - } - else { - - if ( !fc ) { - fc = new idAFConstraint_ContactFriction; - } - // call setup each frame because contact constraints are re-used for different bodies - fc->Setup( this ); - fc->Add( physics, invTimeStep ); - } -} - -/* -================ -idAFConstraint_Contact::Translate -================ -*/ -void idAFConstraint_Contact::Translate( const idVec3 &translation ) { - assert( 0 ); // contact should never be translated -} - -/* -================ -idAFConstraint_Contact::Rotate -================ -*/ -void idAFConstraint_Contact::Rotate( const idRotation &rotation ) { - assert( 0 ); // contact should never be rotated -} - -/* -================ -idAFConstraint_Contact::GetCenter -================ -*/ -void idAFConstraint_Contact::GetCenter( idVec3 ¢er ) { - center = contact.point; -} - -/* -================ -idAFConstraint_Contact::DebugDraw -================ -*/ -void idAFConstraint_Contact::DebugDraw( void ) { - idVec3 x, y; - contact.normal.NormalVectors( x, y ); - gameRenderWorld->DebugLine( colorWhite, contact.point, contact.point + 6.0f * contact.normal ); - gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * x, contact.point + 2.0f * x ); - gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * y, contact.point + 2.0f * y ); -} - - -//=============================================================== -// -// idAFConstraint_ContactFriction -// -//=============================================================== - -/* -================ -idAFConstraint_ContactFriction::idAFConstraint_ContactFriction -================ -*/ -idAFConstraint_ContactFriction::idAFConstraint_ContactFriction( void ) { - type = CONSTRAINT_FRICTION; - name = "contactFriction"; - InitSize( 2 ); - cc = NULL; - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_ContactFriction::Setup -================ -*/ -void idAFConstraint_ContactFriction::Setup( idAFConstraint_Contact *cc ) { - this->cc = cc; - body1 = cc->GetBody1(); - body2 = cc->GetBody2(); -} - -/* -================ -idAFConstraint_ContactFriction::Evaluate -================ -*/ -void idAFConstraint_ContactFriction::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_ContactFriction::ApplyFriction -================ -*/ -void idAFConstraint_ContactFriction::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_ContactFriction::Add -================ -*/ -bool idAFConstraint_ContactFriction::Add( idPhysics_AF *phys, float invTimeStep ) { - idVec3 r, dir1, dir2; - float friction; - int newRow; - - physics = phys; - - friction = body1->GetContactFriction() * physics->GetContactFrictionScale(); - - // if the body only has friction in one direction - if ( body1->GetFrictionDirection( dir1 ) ) { - // project the friction direction into the contact plane - dir1 -= dir1 * cc->GetContact().normal * dir1; - dir1.Normalize(); - - r = cc->GetContact().point - body1->GetWorldOrigin(); - - J1.SetSize( 1, 6 ); - J1.SubVec6(0).SubVec3(0) = dir1; - J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 ); - c1.SetSize( 1 ); - c1[0] = 0.0f; - - if ( body2 ) { - r = cc->GetContact().point - body2->GetWorldOrigin(); - - J2.SetSize( 1, 6 ); - J2.SubVec6(0).SubVec3(0) = -dir1; - J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 ); - c2.SetSize( 1 ); - c2[0] = 0.0f; - } - - lo[0] = -friction; - hi[0] = friction; - boxConstraint = cc; - boxIndex[0] = 0; - } - else { - // get two friction directions orthogonal to contact normal - cc->GetContact().normal.NormalVectors( dir1, dir2 ); - - r = cc->GetContact().point - body1->GetWorldOrigin(); - - J1.SetSize( 2, 6 ); - J1.SubVec6(0).SubVec3(0) = dir1; - J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 ); - J1.SubVec6(1).SubVec3(0) = dir2; - J1.SubVec6(1).SubVec3(1) = r.Cross( dir2 ); - c1.SetSize( 2 ); - c1[0] = c1[1] = 0.0f; - - if ( body2 ) { - r = cc->GetContact().point - body2->GetWorldOrigin(); - - J2.SetSize( 2, 6 ); - J2.SubVec6(0).SubVec3(0) = -dir1; - J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 ); - J2.SubVec6(1).SubVec3(0) = -dir2; - J2.SubVec6(1).SubVec3(1) = r.Cross( -dir2 ); - c2.SetSize( 2 ); - c2[0] = c2[1] = 0.0f; - - if ( body2->GetContactFriction() < friction ) { - friction = body2->GetContactFriction(); - } - } - - lo[0] = -friction; - hi[0] = friction; - boxConstraint = cc; - boxIndex[0] = 0; - lo[1] = -friction; - hi[1] = friction; - boxIndex[1] = 0; - } - - if ( body1->GetContactMotorDirection( dir1 ) && body1->GetContactMotorForce() > 0.0f ) { - // project the motor force direction into the contact plane - dir1 -= dir1 * cc->GetContact().normal * dir1; - dir1.Normalize(); - - r = cc->GetContact().point - body1->GetWorldOrigin(); - - newRow = J1.GetNumRows(); - J1.ChangeSize( newRow+1, J1.GetNumColumns() ); - J1.SubVec6(newRow).SubVec3(0) = -dir1; - J1.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 ); - c1.ChangeSize( newRow+1 ); - c1[newRow] = body1->GetContactMotorVelocity(); - - if ( body2 ) { - r = cc->GetContact().point - body2->GetWorldOrigin(); - - J2.ChangeSize( newRow+1, J2.GetNumColumns() ); - J2.SubVec6(newRow).SubVec3(0) = -dir1; - J2.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 ); - c2.ChangeSize( newRow+1 ); - c2[newRow] = 0.0f; - } - - lo[newRow] = -body1->GetContactMotorForce(); - hi[newRow] = body1->GetContactMotorForce(); - boxIndex[newRow] = -1; - } - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_ContactFriction::Translate -================ -*/ -void idAFConstraint_ContactFriction::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_ContactFriction::Rotate -================ -*/ -void idAFConstraint_ContactFriction::Rotate( const idRotation &rotation ) { -} - -/* -================ -idAFConstraint_ContactFriction::DebugDraw -================ -*/ -void idAFConstraint_ContactFriction::DebugDraw( void ) { -} - - -//=============================================================== -// -// idAFConstraint_ConeLimit -// -//=============================================================== - -/* -================ -idAFConstraint_ConeLimit::idAFConstraint_ConeLimit -================ -*/ -idAFConstraint_ConeLimit::idAFConstraint_ConeLimit( void ) { - type = CONSTRAINT_CONELIMIT; - name = "coneLimit"; - InitSize( 1 ); - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_ConeLimit::Setup - - the coneAnchor is the top of the cone in body2 space - the coneAxis is the axis of the cone in body2 space - the coneAngle is the angle the cone hull makes at the top - the body1Axis is the axis in body1 space that should stay within the cone -================ -*/ -void idAFConstraint_ConeLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) { - this->body1 = b1; - this->body2 = b2; - this->coneAxis = coneAxis; - this->coneAxis.Normalize(); - this->coneAnchor = coneAnchor; - this->body1Axis = body1Axis; - this->body1Axis.Normalize(); - this->cosAngle = (float) cos( DEG2RAD( coneAngle * 0.5f ) ); - this->sinHalfAngle = (float) sin( DEG2RAD( coneAngle * 0.25f ) ); - this->cosHalfAngle = (float) cos( DEG2RAD( coneAngle * 0.25f ) ); -} - -/* -================ -idAFConstraint_ConeLimit::SetAnchor -================ -*/ -void idAFConstraint_ConeLimit::SetAnchor( const idVec3 &coneAnchor ) { - this->coneAnchor = coneAnchor; -} - -/* -================ -idAFConstraint_ConeLimit::SetBody1Axis -================ -*/ -void idAFConstraint_ConeLimit::SetBody1Axis( const idVec3 &body1Axis ) { - this->body1Axis = body1Axis; -} - -/* -================ -idAFConstraint_ConeLimit::Evaluate -================ -*/ -void idAFConstraint_ConeLimit::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_ConeLimit::ApplyFriction -================ -*/ -void idAFConstraint_ConeLimit::ApplyFriction( float invTimeStep ) { -} - -/* -================ -idAFConstraint_ConeLimit::Add -================ -*/ -bool idAFConstraint_ConeLimit::Add( idPhysics_AF *phys, float invTimeStep ) { - float a; - idVec6 J1row, J2row; - idVec3 ax, anchor, body1ax, normal, coneVector, p1, p2; - idQuat q; - idAFBody *master; - - if ( af_skipLimits.GetBool() ) { - lm.Zero(); // constraint exerts no force - return false; - } - - physics = phys; - - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - ax = coneAxis * master->GetWorldAxis(); - anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis(); - } - else { - ax = coneAxis; - anchor = coneAnchor; - } - - body1ax = body1Axis * body1->GetWorldAxis(); - - a = ax * body1ax; - - // if the body1 axis is inside the cone - if ( a > cosAngle ) { - lm.Zero(); // constraint exerts no force - return false; - } - - // calculate the inward cone normal for the position the body1 axis went outside the cone - normal = body1ax.Cross( ax ); - normal.Normalize(); - q.x = normal.x * sinHalfAngle; - q.y = normal.y * sinHalfAngle; - q.z = normal.z * sinHalfAngle; - q.w = cosHalfAngle; - coneVector = ax * q.ToMat3(); - normal = coneVector.Cross( ax ).Cross( coneVector ); - normal.Normalize(); - - p1 = anchor + 32.0f * coneVector - body1->GetWorldOrigin(); - - J1row.SubVec3(0) = normal; - J1row.SubVec3(1) = p1.Cross( normal ); - J1.Set( 1, 6, J1row.ToFloatPtr() ); - - c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) ); - - if ( body2 ) { - - p2 = anchor + 32.0f * coneVector - master->GetWorldOrigin(); - - J2row.SubVec3(0) = -normal; - J2row.SubVec3(1) = p2.Cross( -normal ); - J2.Set( 1, 6, J2row.ToFloatPtr() ); - - c2[0] = 0.0f; - } - - lo[0] = 0.0f; - e[0] = LIMIT_LCP_EPSILON; - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_ConeLimit::Translate -================ -*/ -void idAFConstraint_ConeLimit::Translate( const idVec3 &translation ) { - if ( !body2 ) { - coneAnchor += translation; - } -} - -/* -================ -idAFConstraint_ConeLimit::Rotate -================ -*/ -void idAFConstraint_ConeLimit::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - coneAnchor *= rotation; - coneAxis *= rotation.ToMat3(); - } -} - -/* -================ -idAFConstraint_ConeLimit::DebugDraw -================ -*/ -void idAFConstraint_ConeLimit::DebugDraw( void ) { - idVec3 ax, anchor, x, y, z, start, end; - float sinAngle, a, size = 10.0f; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - ax = coneAxis * master->GetWorldAxis(); - anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis(); - } - else { - ax = coneAxis; - anchor = coneAnchor; - } - - // draw body1 axis - gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) ); - - // draw cone - ax.NormalVectors( x, y ); - sinAngle = idMath::Sqrt( 1.0f - cosAngle * cosAngle ); - x *= size * sinAngle; - y *= size * sinAngle; - z = anchor + ax * size * cosAngle; - start = x + z; - for ( a = 0.0f; a < 360.0f; a += 45.0f ) { - end = x * (float) cos( DEG2RAD(a + 45.0f) ) + y * (float) sin( DEG2RAD(a + 45.0f) ) + z; - gameRenderWorld->DebugLine( colorMagenta, anchor, start ); - gameRenderWorld->DebugLine( colorMagenta, start, end ); - start = end; - } -} - -/* -================ -idAFConstraint_ConeLimit::Save -================ -*/ -void idAFConstraint_ConeLimit::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( coneAnchor ); - saveFile->WriteVec3( coneAxis ); - saveFile->WriteVec3( body1Axis ); - saveFile->WriteFloat( cosAngle ); - saveFile->WriteFloat( sinHalfAngle ); - saveFile->WriteFloat( cosHalfAngle ); - saveFile->WriteFloat( epsilon ); -} - -/* -================ -idAFConstraint_ConeLimit::Restore -================ -*/ -void idAFConstraint_ConeLimit::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( coneAnchor ); - saveFile->ReadVec3( coneAxis ); - saveFile->ReadVec3( body1Axis ); - saveFile->ReadFloat( cosAngle ); - saveFile->ReadFloat( sinHalfAngle ); - saveFile->ReadFloat( cosHalfAngle ); - saveFile->ReadFloat( epsilon ); -} - - -//=============================================================== -// -// idAFConstraint_PyramidLimit -// -//=============================================================== - -/* -================ -idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit -================ -*/ -idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit( void ) { - type = CONSTRAINT_PYRAMIDLIMIT; - name = "pyramidLimit"; - InitSize( 1 ); - fl.allowPrimary = false; - fl.frameConstraint = true; -} - -/* -================ -idAFConstraint_PyramidLimit::Setup -================ -*/ -void idAFConstraint_PyramidLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor, - const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis ) { - body1 = b1; - body2 = b2; - // setup the base and make sure the basis is orthonormal - pyramidBasis[2] = pyramidAxis; - pyramidBasis[2].Normalize(); - pyramidBasis[0] = baseAxis; - pyramidBasis[0] -= pyramidBasis[2] * baseAxis * pyramidBasis[2]; - pyramidBasis[0].Normalize(); - pyramidBasis[1] = pyramidBasis[0].Cross( pyramidBasis[2] ); - // pyramid top - this->pyramidAnchor = pyramidAnchor; - // angles - cosAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.5f ) ); - cosAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.5f ) ); - sinHalfAngle[0] = (float) sin( DEG2RAD( pyramidAngle1 * 0.25f ) ); - sinHalfAngle[1] = (float) sin( DEG2RAD( pyramidAngle2 * 0.25f ) ); - cosHalfAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.25f ) ); - cosHalfAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.25f ) ); - - this->body1Axis = body1Axis; -} - -/* -================ -idAFConstraint_PyramidLimit::SetAnchor -================ -*/ -void idAFConstraint_PyramidLimit::SetAnchor( const idVec3 &pyramidAnchor ) { - this->pyramidAnchor = pyramidAnchor; -} - -/* -================ -idAFConstraint_PyramidLimit::SetBody1Axis -================ -*/ -void idAFConstraint_PyramidLimit::SetBody1Axis( const idVec3 &body1Axis ) { - this->body1Axis = body1Axis; -} - -/* -================ -idAFConstraint_PyramidLimit::Evaluate -================ -*/ -void idAFConstraint_PyramidLimit::Evaluate( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_PyramidLimit::ApplyFriction -================ -*/ -void idAFConstraint_PyramidLimit::ApplyFriction( float invTimeStep ) { -} - -/* -================ -idAFConstraint_PyramidLimit::Add -================ -*/ -bool idAFConstraint_PyramidLimit::Add( idPhysics_AF *phys, float invTimeStep ) { - int i; - float a[2]; - idVec6 J1row, J2row; - idMat3 worldBase; - idVec3 anchor, body1ax, ax[2], v, normal, pyramidVector, p1, p2; - idQuat q; - idAFBody *master; - - if ( af_skipLimits.GetBool() ) { - lm.Zero(); // constraint exerts no force - return false; - } - - physics = phys; - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - worldBase[0] = pyramidBasis[0] * master->GetWorldAxis(); - worldBase[1] = pyramidBasis[1] * master->GetWorldAxis(); - worldBase[2] = pyramidBasis[2] * master->GetWorldAxis(); - anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis(); - } - else { - worldBase = pyramidBasis; - anchor = pyramidAnchor; - } - - body1ax = body1Axis * body1->GetWorldAxis(); - - for ( i = 0; i < 2; i++ ) { - ax[i] = body1ax - worldBase[!i] * body1ax * worldBase[!i]; - ax[i].Normalize(); - a[i] = worldBase[2] * ax[i]; - } - - // if the body1 axis is inside the pyramid - if ( a[0] > cosAngle[0] && a[1] > cosAngle[1] ) { - lm.Zero(); // constraint exerts no force - return false; - } - - // calculate the inward pyramid normal for the position the body1 axis went outside the pyramid - pyramidVector = worldBase[2]; - for ( i = 0; i < 2; i++ ) { - if ( a[i] <= cosAngle[i] ) { - v = ax[i].Cross( worldBase[2] ); - v.Normalize(); - q.x = v.x * sinHalfAngle[i]; - q.y = v.y * sinHalfAngle[i]; - q.z = v.z * sinHalfAngle[i]; - q.w = cosHalfAngle[i]; - pyramidVector *= q.ToMat3(); - } - } - normal = pyramidVector.Cross( worldBase[2] ).Cross( pyramidVector ); - normal.Normalize(); - - p1 = anchor + 32.0f * pyramidVector - body1->GetWorldOrigin(); - - J1row.SubVec3(0) = normal; - J1row.SubVec3(1) = p1.Cross( normal ); - J1.Set( 1, 6, J1row.ToFloatPtr() ); - - c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) ); - - if ( body2 ) { - - p2 = anchor + 32.0f * pyramidVector - master->GetWorldOrigin(); - - J2row.SubVec3(0) = -normal; - J2row.SubVec3(1) = p2.Cross( -normal ); - J2.Set( 1, 6, J2row.ToFloatPtr() ); - - c2[0] = 0.0f; - } - - lo[0] = 0.0f; - e[0] = LIMIT_LCP_EPSILON; - - physics->AddFrameConstraint( this ); - - return true; -} - -/* -================ -idAFConstraint_PyramidLimit::Translate -================ -*/ -void idAFConstraint_PyramidLimit::Translate( const idVec3 &translation ) { - if ( !body2 ) { - pyramidAnchor += translation; - } -} - -/* -================ -idAFConstraint_PyramidLimit::Rotate -================ -*/ -void idAFConstraint_PyramidLimit::Rotate( const idRotation &rotation ) { - if ( !body2 ) { - pyramidAnchor *= rotation; - pyramidBasis[0] *= rotation.ToMat3(); - pyramidBasis[1] *= rotation.ToMat3(); - pyramidBasis[2] *= rotation.ToMat3(); - } -} - -/* -================ -idAFConstraint_PyramidLimit::DebugDraw -================ -*/ -void idAFConstraint_PyramidLimit::DebugDraw( void ) { - int i; - float size = 10.0f; - idVec3 anchor, dir, p[4]; - idMat3 worldBase, m[2]; - idQuat q; - idAFBody *master; - - master = body2 ? body2 : physics->GetMasterBody(); - - if ( master ) { - worldBase[0] = pyramidBasis[0] * master->GetWorldAxis(); - worldBase[1] = pyramidBasis[1] * master->GetWorldAxis(); - worldBase[2] = pyramidBasis[2] * master->GetWorldAxis(); - anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis(); - } - else { - worldBase = pyramidBasis; - anchor = pyramidAnchor; - } - - // draw body1 axis - gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) ); - - // draw the pyramid - for ( i = 0; i < 2; i++ ) { - q.x = worldBase[!i].x * sinHalfAngle[i]; - q.y = worldBase[!i].y * sinHalfAngle[i]; - q.z = worldBase[!i].z * sinHalfAngle[i]; - q.w = cosHalfAngle[i]; - m[i] = q.ToMat3(); - } - - dir = worldBase[2] * size; - p[0] = anchor + m[0] * (m[1] * dir); - p[1] = anchor + m[0] * (m[1].Transpose() * dir); - p[2] = anchor + m[0].Transpose() * (m[1].Transpose() * dir); - p[3] = anchor + m[0].Transpose() * (m[1] * dir); - - for ( i = 0; i < 4; i++ ) { - gameRenderWorld->DebugLine( colorMagenta, anchor, p[i] ); - gameRenderWorld->DebugLine( colorMagenta, p[i], p[(i+1)&3] ); - } -} - -/* -================ -idAFConstraint_PyramidLimit::Save -================ -*/ -void idAFConstraint_PyramidLimit::Save( idSaveGame *saveFile ) const { - idAFConstraint::Save( saveFile ); - saveFile->WriteVec3( pyramidAnchor ); - saveFile->WriteMat3( pyramidBasis ); - saveFile->WriteVec3( body1Axis ); - saveFile->WriteFloat( cosAngle[0] ); - saveFile->WriteFloat( cosAngle[1] ); - saveFile->WriteFloat( sinHalfAngle[0] ); - saveFile->WriteFloat( sinHalfAngle[1] ); - saveFile->WriteFloat( cosHalfAngle[0] ); - saveFile->WriteFloat( cosHalfAngle[1] ); - saveFile->WriteFloat( epsilon ); -} - -/* -================ -idAFConstraint_PyramidLimit::Restore -================ -*/ -void idAFConstraint_PyramidLimit::Restore( idRestoreGame *saveFile ) { - idAFConstraint::Restore( saveFile ); - saveFile->ReadVec3( pyramidAnchor ); - saveFile->ReadMat3( pyramidBasis ); - saveFile->ReadVec3( body1Axis ); - saveFile->ReadFloat( cosAngle[0] ); - saveFile->ReadFloat( cosAngle[1] ); - saveFile->ReadFloat( sinHalfAngle[0] ); - saveFile->ReadFloat( sinHalfAngle[1] ); - saveFile->ReadFloat( cosHalfAngle[0] ); - saveFile->ReadFloat( cosHalfAngle[1] ); - saveFile->ReadFloat( epsilon ); -} - - -//=============================================================== -// -// idAFConstraint_Suspension -// -//=============================================================== - -/* -================ -idAFConstraint_Suspension::idAFConstraint_Suspension -================ -*/ -idAFConstraint_Suspension::idAFConstraint_Suspension( void ) { - type = CONSTRAINT_SUSPENSION; - name = "suspension"; - InitSize( 3 ); - fl.allowPrimary = false; - fl.frameConstraint = true; - - localOrigin.Zero(); - localAxis.Identity(); - suspensionUp = 0.0f; - suspensionDown = 0.0f; - suspensionKCompress = 0.0f; - suspensionDamping = 0.0f; - steerAngle = 0.0f; - friction = 2.0f; - motorEnabled = false; - motorForce = 0.0f; - motorVelocity = 0.0f; - wheelModel = NULL; - memset( &trace, 0, sizeof( trace ) ); - epsilon = LCP_EPSILON; -} - -/* -================ -idAFConstraint_Suspension::Setup -================ -*/ -void idAFConstraint_Suspension::Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel ) { - this->name = name; - body1 = body; - body2 = NULL; - localOrigin = ( origin - body->GetWorldOrigin() ) * body->GetWorldAxis().Transpose(); - localAxis = axis * body->GetWorldAxis().Transpose(); - wheelModel = clipModel; -} - -/* -================ -idAFConstraint_Suspension::SetSuspension -================ -*/ -void idAFConstraint_Suspension::SetSuspension( const float up, const float down, const float k, const float d, const float f ) { - suspensionUp = up; - suspensionDown = down; - suspensionKCompress = k; - suspensionDamping = d; - friction = f; -} - -/* -================ -idAFConstraint_Suspension::GetWheelOrigin -================ -*/ -const idVec3 idAFConstraint_Suspension::GetWheelOrigin( void ) const { - return body1->GetWorldOrigin() + wheelOffset * body1->GetWorldAxis(); -} - -/* -================ -idAFConstraint_Suspension::Evaluate -================ -*/ -void idAFConstraint_Suspension::Evaluate( float invTimeStep ) { - float velocity, suspensionLength, springLength, compression, dampingForce, springForce; - idVec3 origin, start, end, vel1, vel2, springDir, r, frictionDir, motorDir; - idMat3 axis; - idRotation rotation; - - axis = localAxis * body1->GetWorldAxis(); - origin = body1->GetWorldOrigin() + localOrigin * body1->GetWorldAxis(); - start = origin + suspensionUp * axis[2]; - end = origin - suspensionDown * axis[2]; - - rotation.SetVec( axis[2] ); - rotation.SetAngle( steerAngle ); - - axis *= rotation.ToMat3(); - - gameLocal.clip.Translation( trace, start, end, wheelModel, axis, MASK_SOLID, NULL ); - - wheelOffset = ( trace.endpos - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose(); - - if ( trace.fraction >= 1.0f ) { - J1.SetSize( 0, 6 ); - if ( body2 ) { - J2.SetSize( 0, 6 ); - } - return; - } - - // calculate and add spring force - vel1 = body1->GetPointVelocity( start ); - if ( body2 ) { - vel2 = body2->GetPointVelocity( trace.c.point ); - } else { - vel2.Zero(); - } - - suspensionLength = suspensionUp + suspensionDown; - springDir = trace.endpos - start; - springLength = trace.fraction * suspensionLength; - dampingForce = suspensionDamping * idMath::Fabs( ( vel2 - vel1 ) * springDir ) / ( 1.0f + springLength * springLength ); - compression = suspensionLength - springLength; - springForce = compression * compression * suspensionKCompress - dampingForce; - - r = trace.c.point - body1->GetWorldOrigin(); - J1.SetSize( 2, 6 ); - J1.SubVec6(0).SubVec3(0) = trace.c.normal; - J1.SubVec6(0).SubVec3(1) = r.Cross( trace.c.normal ); - c1.SetSize( 2 ); - c1[0] = 0.0f; - velocity = J1.SubVec6(0).SubVec3(0) * body1->GetLinearVelocity() + J1.SubVec6(0).SubVec3(1) * body1->GetAngularVelocity(); - - if ( body2 ) { - r = trace.c.point - body2->GetWorldOrigin(); - J2.SetSize( 2, 6 ); - J2.SubVec6(0).SubVec3(0) = -trace.c.normal; - J2.SubVec6(0).SubVec3(1) = r.Cross( -trace.c.normal ); - c2.SetSize( 2 ); - c2[0] = 0.0f; - velocity += J2.SubVec6(0).SubVec3(0) * body2->GetLinearVelocity() + J2.SubVec6(0).SubVec3(1) * body2->GetAngularVelocity(); - } - - c1[0] = -compression; // + 0.5f * -velocity; - - e[0] = 1e-4f; - lo[0] = 0.0f; - hi[0] = springForce; - boxConstraint = NULL; - boxIndex[0] = -1; - - // project the friction direction into the contact plane - frictionDir = axis[1] - axis[1] * trace.c.normal * axis[1]; - frictionDir.Normalize(); - - r = trace.c.point - body1->GetWorldOrigin(); - - J1.SubVec6(1).SubVec3(0) = frictionDir; - J1.SubVec6(1).SubVec3(1) = r.Cross( frictionDir ); - c1[1] = 0.0f; - - if ( body2 ) { - r = trace.c.point - body2->GetWorldOrigin(); - - J2.SubVec6(1).SubVec3(0) = -frictionDir; - J2.SubVec6(1).SubVec3(1) = r.Cross( -frictionDir ); - c2[1] = 0.0f; - } - - lo[1] = -friction * physics->GetContactFrictionScale(); - hi[1] = friction * physics->GetContactFrictionScale(); - - boxConstraint = this; - boxIndex[1] = 0; - - - if ( motorEnabled ) { - // project the motor force direction into the contact plane - motorDir = axis[0] - axis[0] * trace.c.normal * axis[0]; - motorDir.Normalize(); - - r = trace.c.point - body1->GetWorldOrigin(); - - J1.ChangeSize( 3, J1.GetNumColumns() ); - J1.SubVec6(2).SubVec3(0) = -motorDir; - J1.SubVec6(2).SubVec3(1) = r.Cross( -motorDir ); - c1.ChangeSize( 3 ); - c1[2] = motorVelocity; - - if ( body2 ) { - r = trace.c.point - body2->GetWorldOrigin(); - - J2.ChangeSize( 3, J2.GetNumColumns() ); - J2.SubVec6(2).SubVec3(0) = -motorDir; - J2.SubVec6(2).SubVec3(1) = r.Cross( -motorDir ); - c2.ChangeSize( 3 ); - c2[2] = 0.0f; - } - - lo[2] = -motorForce; - hi[2] = motorForce; - boxIndex[2] = -1; - } -} - -/* -================ -idAFConstraint_Suspension::ApplyFriction -================ -*/ -void idAFConstraint_Suspension::ApplyFriction( float invTimeStep ) { - // do nothing -} - -/* -================ -idAFConstraint_Suspension::Translate -================ -*/ -void idAFConstraint_Suspension::Translate( const idVec3 &translation ) { -} - -/* -================ -idAFConstraint_Suspension::Rotate -================ -*/ -void idAFConstraint_Suspension::Rotate( const idRotation &rotation ) { -} - -/* -================ -idAFConstraint_Suspension::DebugDraw -================ -*/ -void idAFConstraint_Suspension::DebugDraw( void ) { - idVec3 origin; - idMat3 axis; - idRotation rotation; - - axis = localAxis * body1->GetWorldAxis(); - - rotation.SetVec( axis[2] ); - rotation.SetAngle( steerAngle ); - - axis *= rotation.ToMat3(); - - if ( trace.fraction < 1.0f ) { - origin = trace.c.point; - - gameRenderWorld->DebugLine( colorWhite, origin, origin + 6.0f * axis[2] ); - gameRenderWorld->DebugLine( colorWhite, origin - 4.0f * axis[0], origin + 4.0f * axis[0] ); - gameRenderWorld->DebugLine( colorWhite, origin - 2.0f * axis[1], origin + 2.0f * axis[1] ); - } -} - - -//=============================================================== -// -// idAFBody -// -//=============================================================== - -/* -================ -idAFBody::idAFBody -================ -*/ -idAFBody::idAFBody( void ) { - Init(); -} - -/* -================ -idAFBody::idAFBody -================ -*/ -idAFBody::idAFBody( const idStr &name, idClipModel *clipModel, float density ) { - - assert( clipModel ); - assert( clipModel->IsTraceModel() ); - - Init(); - - this->name = name; - this->clipModel = NULL; - - SetClipModel( clipModel ); - SetDensity( density ); - - current->worldOrigin = clipModel->GetOrigin(); - current->worldAxis = clipModel->GetAxis(); - *next = *current; - -} - -/* -================ -idAFBody::~idAFBody -================ -*/ -idAFBody::~idAFBody( void ) { - delete clipModel; -} - -/* -================ -idAFBody::Init -================ -*/ -void idAFBody::Init( void ) { - name = "noname"; - parent = NULL; - clipModel = NULL; - primaryConstraint = NULL; - tree = NULL; - - linearFriction = -1.0f; - angularFriction = -1.0f; - contactFriction = -1.0f; - bouncyness = -1.0f; - clipMask = 0; - - frictionDir = vec3_zero; - contactMotorDir = vec3_zero; - contactMotorVelocity = 0.0f; - contactMotorForce = 0.0f; - - mass = 1.0f; - invMass = 1.0f; - centerOfMass = vec3_zero; - inertiaTensor = mat3_identity; - inverseInertiaTensor = mat3_identity; -#ifdef MOD_WATERPHYSICS - this->volume = 1.0f; - this->liquidMass = 1.0f; - this->invLiquidMass = 1.0f; - this->waterLevel = 0.0f; -#endif - - current = &state[0]; - next = &state[1]; - current->worldOrigin = vec3_zero; - current->worldAxis = mat3_identity; - current->spatialVelocity = vec6_zero; - current->externalForce = vec6_zero; - *next = *current; - saved = *current; - atRestOrigin = vec3_zero; - atRestAxis = mat3_identity; - - s.Zero( 6 ); - totalForce.Zero( 6 ); - auxForce.Zero( 6 ); - acceleration.Zero( 6 ); - - response = NULL; - responseIndex = NULL; - numResponses = 0; - maxAuxiliaryIndex = 0; - maxSubTreeAuxiliaryIndex = 0; - - memset( &fl, 0, sizeof( fl ) ); - - fl.selfCollision = true; - fl.isZero = true; - - m_RerouteEnt = NULL; -} - -/* -================ -idAFBody::SetClipModel -================ -*/ -void idAFBody::SetClipModel( idClipModel *clipModel ) { - if ( this->clipModel && this->clipModel != clipModel ) { - delete this->clipModel; - } - this->clipModel = clipModel; -} - -/* -================ -idAFBody::SetFriction -================ -*/ -void idAFBody::SetFriction( float linear, float angular, float contact ) { - if ( linear < 0.0f || linear > 1.0f || - angular < 0.0f || angular > 1.0f || - contact < 0.0f ) { - gameLocal.Warning( "idAFBody::SetFriction: friction out of range, linear = %.1f, angular = %.1f, contact = %.1f", linear, angular, contact ); - return; - } - linearFriction = linear; - angularFriction = angular; - contactFriction = contact; -} - -/* -================ -idAFBody::SetBouncyness -================ -*/ -void idAFBody::SetBouncyness( float bounce ) { - if ( bounce < 0.0f || bounce > 1.0f ) { - gameLocal.Warning( "idAFBody::SetBouncyness: bouncyness out of range, bounce = %.1f", bounce ); - return; - } - bouncyness = bounce; -} - -/* -================ -idAFBody::SetDensity -================ -*/ -void idAFBody::SetDensity( float density, const idMat3 &inertiaScale ) { - - // get the body mass properties - clipModel->GetMassProperties( density, mass, centerOfMass, inertiaTensor ); - - // make sure we have a valid mass - if ( mass <= 0.0f || FLOAT_IS_NAN( mass ) ) { - gameLocal.Warning( "idAFBody::SetDensity: invalid mass for body '%s'", name.c_str() ); - mass = 1.0f; - centerOfMass.Zero(); - inertiaTensor.Identity(); - } - - // make sure the center of mass is at the body origin - if ( !centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) { - gameLocal.Warning( "idAFBody::SetDensity: center of mass (%f, %f, %f) not at origin (%f, %f, %f) for body '%s'", - vec3_origin.x, vec3_origin.y, vec3_origin.z, - centerOfMass.x, centerOfMass.y, centerOfMass.z, name.c_str() ); - } - centerOfMass.Zero(); - - // calculate the inverse mass and inverse inertia tensor - invMass = 1.0f / mass; - if ( inertiaScale != mat3_identity ) { - inertiaTensor *= inertiaScale; - } - if ( inertiaTensor.IsDiagonal( 1e-3f ) ) { - inertiaTensor[0][1] = inertiaTensor[0][2] = 0.0f; - inertiaTensor[1][0] = inertiaTensor[1][2] = 0.0f; - inertiaTensor[2][0] = inertiaTensor[2][1] = 0.0f; - inverseInertiaTensor.Identity(); - inverseInertiaTensor[0][0] = 1.0f / inertiaTensor[0][0]; - inverseInertiaTensor[1][1] = 1.0f / inertiaTensor[1][1]; - inverseInertiaTensor[2][2] = 1.0f / inertiaTensor[2][2]; - } - else { - inverseInertiaTensor = inertiaTensor.Inverse(); - } -#ifdef MOD_WATERPHYSICS - this->volume = mass / density; - this->liquidMass = this->mass; - this->invLiquidMass = this->invMass; -#endif -} - -/* -================ -idAFBody::SetFrictionDirection -================ -*/ -void idAFBody::SetFrictionDirection( const idVec3 &dir ) { - frictionDir = dir * current->worldAxis.Transpose(); - fl.useFrictionDir = true; -} - -/* -================ -idAFBody::GetFrictionDirection -================ -*/ -bool idAFBody::GetFrictionDirection( idVec3 &dir ) const { - if ( fl.useFrictionDir ) { - dir = frictionDir * current->worldAxis; - return true; - } - return false; -} - -/* -================ -idAFBody::SetContactMotorDirection -================ -*/ -void idAFBody::SetContactMotorDirection( const idVec3 &dir ) { - contactMotorDir = dir * current->worldAxis.Transpose(); - fl.useContactMotorDir = true; -} - -/* -================ -idAFBody::GetContactMotorDirection -================ -*/ -bool idAFBody::GetContactMotorDirection( idVec3 &dir ) const { - if ( fl.useContactMotorDir ) { - dir = contactMotorDir * current->worldAxis; - return true; - } - return false; -} - -/* -================ -idAFBody::GetPointVelocity -================ -*/ -idVec3 idAFBody::GetPointVelocity( const idVec3 &point ) const { - idVec3 r = point - current->worldOrigin; - return current->spatialVelocity.SubVec3(0) + current->spatialVelocity.SubVec3(1).Cross( r ); -} - -/* -================ -idAFBody::AddForce -================ -*/ -void idAFBody::AddForce( const idVec3 &point, const idVec3 &force ) { - current->externalForce.SubVec3(0) += force; - current->externalForce.SubVec3(1) += (point - current->worldOrigin).Cross( force ); -} - -/* -================ -idAFBody::InverseWorldSpatialInertiaMultiply - - dst = this->inverseWorldSpatialInertia * v; -================ -*/ -ID_INLINE void idAFBody::InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const { - const float *mPtr = inverseWorldSpatialInertia.ToFloatPtr(); - const float *vPtr = v; - float *dstPtr = dst.ToFloatPtr(); - - if ( fl.spatialInertiaSparse ) { - dstPtr[0] = mPtr[0*6+0] * vPtr[0]; - dstPtr[1] = mPtr[1*6+1] * vPtr[1]; - dstPtr[2] = mPtr[2*6+2] * vPtr[2]; - dstPtr[3] = mPtr[3*6+3] * vPtr[3] + mPtr[3*6+4] * vPtr[4] + mPtr[3*6+5] * vPtr[5]; - dstPtr[4] = mPtr[4*6+3] * vPtr[3] + mPtr[4*6+4] * vPtr[4] + mPtr[4*6+5] * vPtr[5]; - dstPtr[5] = mPtr[5*6+3] * vPtr[3] + mPtr[5*6+4] * vPtr[4] + mPtr[5*6+5] * vPtr[5]; - } else { - gameLocal.Warning( "spatial inertia is not sparse for body %s", name.c_str() ); - } -} - -/* -================ -idAFBody::Save -================ -*/ -void idAFBody::Save( idSaveGame *saveFile ) { - saveFile->WriteFloat( linearFriction ); - saveFile->WriteFloat( angularFriction ); - saveFile->WriteFloat( contactFriction ); - saveFile->WriteFloat( bouncyness ); - saveFile->WriteInt( clipMask ); - saveFile->WriteVec3( frictionDir ); - saveFile->WriteVec3( contactMotorDir ); - saveFile->WriteFloat( contactMotorVelocity ); - saveFile->WriteFloat( contactMotorForce ); - -#ifdef MOD_WATERPHYSICS - saveFile->WriteFloat( volume ); - saveFile->WriteFloat( liquidMass ); - saveFile->WriteFloat( invLiquidMass ); -#endif - saveFile->WriteFloat( mass ); - saveFile->WriteFloat( invMass ); - saveFile->WriteVec3( centerOfMass ); - saveFile->WriteMat3( inertiaTensor ); - saveFile->WriteMat3( inverseInertiaTensor ); - - saveFile->WriteVec3( current->worldOrigin ); - saveFile->WriteMat3( current->worldAxis ); - saveFile->WriteVec6( current->spatialVelocity ); - saveFile->WriteVec6( current->externalForce ); - saveFile->WriteVec3( atRestOrigin ); - saveFile->WriteMat3( atRestAxis ); - m_RerouteEnt.Save( saveFile ); -} - -/* -================ -idAFBody::Restore -================ -*/ -void idAFBody::Restore( idRestoreGame *saveFile ) { - saveFile->ReadFloat( linearFriction ); - saveFile->ReadFloat( angularFriction ); - saveFile->ReadFloat( contactFriction ); - saveFile->ReadFloat( bouncyness ); - saveFile->ReadInt( clipMask ); - saveFile->ReadVec3( frictionDir ); - saveFile->ReadVec3( contactMotorDir ); - saveFile->ReadFloat( contactMotorVelocity ); - saveFile->ReadFloat( contactMotorForce ); - -#ifdef MOD_WATERPHYSICS - saveFile->ReadFloat( volume ); - saveFile->ReadFloat( liquidMass ); - saveFile->ReadFloat( invLiquidMass ); -#endif - - saveFile->ReadFloat( mass ); - saveFile->ReadFloat( invMass ); - saveFile->ReadVec3( centerOfMass ); - saveFile->ReadMat3( inertiaTensor ); - saveFile->ReadMat3( inverseInertiaTensor ); - - saveFile->ReadVec3( current->worldOrigin ); - saveFile->ReadMat3( current->worldAxis ); - saveFile->ReadVec6( current->spatialVelocity ); - saveFile->ReadVec6( current->externalForce ); - saveFile->ReadVec3( atRestOrigin ); - saveFile->ReadMat3( atRestAxis ); - m_RerouteEnt.Restore( saveFile ); -} - -idEntity *idAFBody::GetRerouteEnt( void ) -{ - return m_RerouteEnt.GetEntity(); -} - -void idAFBody::SetRerouteEnt( idEntity *ent ) -{ - m_RerouteEnt = ent; -} - -#ifdef MOD_WATERPHYSICS -/* -================ -idAFBody::GetWaterLevel - returns the percent of the body in water (set by SetWaterLevel) -================ -*/ -float idAFBody::GetWaterLevel() const { - return this->waterLevel; -} - -/* -================ -idAFBody::SetWaterLevel - returns the percent of the body in water - 0.0f if out of water - - Note we use the liquid's gravity normal for - floating because the idPhysics_AF gravity normal - is really hard to get a hold of! -================ -*/ -float idAFBody::SetWaterLevel( idPhysics_Liquid *l, const idVec3 &gravityNormal, bool fixedDensityBuoyancy ) { - if( l == NULL ) { - this->waterLevel = 0.0f; - this->m_fWaterMurkiness = 0.0f; - return 0.0f; - } - - if( !fixedDensityBuoyancy ) { - const idBounds &bounds = this->clipModel->GetBounds(); - idVec3 depth,point; - float height, d; - - // - // check if physics object is under water - // and return the percentage of the object under water - // - point = this->GetWorldOrigin(); - - depth = l->GetDepth(point); - // height = abs( (bounds[0] - bounds[1]) * gravityNormal ) * 0.5f; - // d = abs( depth * gravityNormal ); - height = fabs( bounds[0].z - bounds[1].z ) * 0.5f; - d = depth.z; - - if( d < 0 ) - this->waterLevel = 0.0f; - else if( d > height ) - this->waterLevel = 1.0f; - else - this->waterLevel = d / height; - } - else { - idVec3 depth,bottom(this->current->worldOrigin); - idBounds bounds = this->clipModel->GetBounds(); - float height,d; - - // offset and rotate the bounding box - bounds += -centerOfMass; - bounds *= this->current->worldAxis.Transpose(); - - // gets the position of the object relative to the surface of the water - height = fabs(bounds[1] * gravityNormal * 2); - - // calculates the depth of the bottom of the object - bottom += (height * 0.5f) * gravityNormal; - depth = l->GetDepth(bottom); - d = fabs(depth * gravityNormal); - - if( d > height ) { - // the body is totally submerged - this->waterLevel = 1.0f; - } - else if( depth.x == -1 && depth.y == -1 && depth.z == -1 ) { - this->waterLevel = 0.0f; - } - else { - // the body is partly submerged - this->waterLevel = d / height; - } - } - return this->waterLevel; -} - -#endif - -//=============================================================== -// M -// idAFTree MrE -// E -//=============================================================== - -/* -================ -idAFTree::Factor - - factor matrix for the primary constraints in the tree -================ -*/ -void idAFTree::Factor( void ) const { - int i, j; - idAFBody *body; - idAFConstraint *child(NULL); - idMatX childI; - - childI.SetData( 6, 6, MATX_ALLOCA( 6 * 6 ) ); - - // from the leaves up towards the root - for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { - body = sortedBodies[i]; - - if ( body->children.Num() ) { - - for ( j = 0; j < body->children.Num(); j++ ) { - - child = body->children[j]->primaryConstraint; - - // child->I = - child->body1->J.Transpose() * child->body1->I * child->body1->J; - childI.SetSize( child->J1.GetNumRows(), child->J1.GetNumRows() ); - child->body1->J.TransposeMultiply( child->body1->I ).Multiply( childI, child->body1->J ); - childI.Negate(); - - child->invI = childI; - if ( !child->invI.InverseFastSelf() ) { - gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for constraint '%s'", - child->invI.GetNumRows(), child->invI.GetNumColumns(), child->GetName().c_str() ); - } - child->J = child->invI * child->J; - - body->I -= child->J.TransposeMultiply( childI ) * child->J; - } - - body->invI = body->I; - if ( !body->invI.InverseFastSelf() ) { - gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for body %s", - child->invI.GetNumRows(), child->invI.GetNumColumns(), body->GetName().c_str() ); - } - if ( body->primaryConstraint ) { - body->J = body->invI * body->J; - } - } - else if ( body->primaryConstraint ) { - body->J = body->inverseWorldSpatialInertia * body->J; - } - } -} - -/* -================ -idAFTree::Solve - - solve for primary constraints in the tree -================ -*/ -void idAFTree::Solve( int auxiliaryIndex ) const { - int i, j; - idAFBody *body, *child; - idAFConstraint *primaryConstraint; - - // from the leaves up towards the root - for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { - body = sortedBodies[i]; - - for ( j = 0; j < body->children.Num(); j++ ) { - child = body->children[j]; - primaryConstraint = child->primaryConstraint; - - if ( !child->fl.isZero ) { - child->J.TransposeMultiplySub( primaryConstraint->s, child->s ); - primaryConstraint->fl.isZero = false; - } - if ( !primaryConstraint->fl.isZero ) { - primaryConstraint->J.TransposeMultiplySub( body->s, primaryConstraint->s ); - body->fl.isZero = false; - } - } - } - - bool useSymmetry = af_useSymmetry.GetBool(); - - // from the root down towards the leaves - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - primaryConstraint = body->primaryConstraint; - - if ( primaryConstraint ) { - - if ( useSymmetry && body->parent->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) { - continue; - } - - if ( !primaryConstraint->fl.isZero ) { - primaryConstraint->s = primaryConstraint->invI * primaryConstraint->s; - } - primaryConstraint->J.MultiplySub( primaryConstraint->s, primaryConstraint->body2->s ); - - primaryConstraint->lm = primaryConstraint->s; - - if ( useSymmetry && body->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) { - continue; - } - - if ( body->children.Num() ) { - if ( !body->fl.isZero ) { - body->s = body->invI * body->s; - } - body->J.MultiplySub( body->s, primaryConstraint->s ); - } - } else if ( body->children.Num() ) { - body->s = body->invI * body->s; - } - } -} - -/* -================ -idAFTree::Response - - calculate body forces in the tree in response to a constraint force -================ -*/ -void idAFTree::Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const { - int i, j; - idAFBody *body; - idAFConstraint *child, *primaryConstraint; - idVecX v; - - // if a single body don't waste time because there aren't any primary constraints - if ( sortedBodies.Num() == 1 ) { - body = constraint->body1; - if ( body->tree == this ) { - body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row ); - body->responseIndex[body->numResponses++] = auxiliaryIndex; - } - else { - body = constraint->body2; - body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row ); - body->responseIndex[body->numResponses++] = auxiliaryIndex; - } - return; - } - - v.SetData( 6, VECX_ALLOCA( 6 ) ); - - // initialize right hand side to zero - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - primaryConstraint->s.Zero(); - primaryConstraint->fl.isZero = true; - } - body->s.Zero(); - body->fl.isZero = true; - body->GetResponseForce( body->numResponses ).Zero(); - } - - // set right hand side for first constrained body - body = constraint->body1; - if ( body->tree == this ) { - body->InverseWorldSpatialInertiaMultiply( v, constraint->J1[row] ); - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - primaryConstraint->J1.Multiply( primaryConstraint->s, v ); - primaryConstraint->fl.isZero = false; - } - for ( i = 0; i < body->children.Num(); i++ ) { - child = body->children[i]->primaryConstraint; - child->J2.Multiply( child->s, v ); - child->fl.isZero = false; - } - body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row ); - } - - // set right hand side for second constrained body - body = constraint->body2; - if ( body && body->tree == this ) { - body->InverseWorldSpatialInertiaMultiply( v, constraint->J2[row] ); - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - primaryConstraint->J1.MultiplyAdd( primaryConstraint->s, v ); - primaryConstraint->fl.isZero = false; - } - for ( i = 0; i < body->children.Num(); i++ ) { - child = body->children[i]->primaryConstraint; - child->J2.MultiplyAdd( child->s, v ); - child->fl.isZero = false; - } - body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row ); - } - - - // solve for primary constraints - Solve( auxiliaryIndex ); - - bool useSymmetry = af_useSymmetry.GetBool(); - - // store body forces in response to the constraint force - idVecX force; - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - - if ( useSymmetry && body->maxAuxiliaryIndex < auxiliaryIndex ) { - continue; - } - - force.SetData( 6, body->response + body->numResponses * 8 ); - - // add forces of all primary constraints acting on this body - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - primaryConstraint->J1.TransposeMultiplyAdd( force, primaryConstraint->lm ); - } - for ( j = 0; j < body->children.Num(); j++ ) { - child = body->children[j]->primaryConstraint; - child->J2.TransposeMultiplyAdd( force, child->lm ); - } - - body->responseIndex[body->numResponses++] = auxiliaryIndex; - } -} - -/* -================ -idAFTree::CalculateForces - - calculate forces on the bodies in the tree -================ -*/ -void idAFTree::CalculateForces( float timeStep ) const { - int i, j; - float invStep; - idAFBody *body; - idAFConstraint *child, *c, *primaryConstraint; - - // forces on bodies - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - - body->totalForce.SubVec6(0) = body->current->externalForce + body->auxForce.SubVec6(0); - } - - // if a single body don't waste time because there aren't any primary constraints - if ( sortedBodies.Num() == 1 ) { - return; - } - - invStep = 1.0f / timeStep; - - // initialize right hand side - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - - body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); - body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep; - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - // b = ( J * acc + c ) - c = primaryConstraint; - c->s = c->J1 * c->body1->acceleration + c->J2 * c->body2->acceleration + invStep * ( c->c1 + c->c2 ); - c->fl.isZero = false; - } - body->s.Zero(); - body->fl.isZero = true; - } - - // solve for primary constraints - Solve(); - - // calculate forces on bodies after applying primary constraints - for ( i = 0; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - - // add forces of all primary constraints acting on this body - primaryConstraint = body->primaryConstraint; - if ( primaryConstraint ) { - primaryConstraint->J1.TransposeMultiplyAdd( body->totalForce, primaryConstraint->lm ); - } - for ( j = 0; j < body->children.Num(); j++ ) { - child = body->children[j]->primaryConstraint; - child->J2.TransposeMultiplyAdd( body->totalForce, child->lm ); - } - } -} - -/* -================ -idAFTree::SetMaxSubTreeAuxiliaryIndex -================ -*/ -void idAFTree::SetMaxSubTreeAuxiliaryIndex( void ) { - int i, j; - idAFBody *body, *child; - - // from the leaves up towards the root - for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) { - body = sortedBodies[i]; - - body->maxSubTreeAuxiliaryIndex = body->maxAuxiliaryIndex; - for ( j = 0; j < body->children.Num(); j++ ) { - child = body->children[j]; - if ( child->maxSubTreeAuxiliaryIndex > body->maxSubTreeAuxiliaryIndex ) { - body->maxSubTreeAuxiliaryIndex = child->maxSubTreeAuxiliaryIndex; - } - } - } -} - -/* -================ -idAFTree::SortBodies_r -================ -*/ -void idAFTree::SortBodies_r( idList&sortedList, idAFBody *body ) { - int i; - - for ( i = 0; i < body->children.Num(); i++ ) { - sortedList.Append( body->children[i] ); - } - for ( i = 0; i < body->children.Num(); i++ ) { - SortBodies_r( sortedList, body->children[i] ); - } -} - -/* -================ -idAFTree::SortBodies - - sort body list to make sure parents come first -================ -*/ -void idAFTree::SortBodies( void ) { - int i; - idAFBody *body; - - // find the root - for ( i = 0; i < sortedBodies.Num(); i++ ) { - if ( !sortedBodies[i]->parent ) { - break; - } - } - - if ( i >= sortedBodies.Num() ) { - gameLocal.Error( "Articulated figure tree has no root." ); - } - - body = sortedBodies[i]; - sortedBodies.Clear(); - sortedBodies.Append( body ); - SortBodies_r( sortedBodies, body ); -} - -/* -================ -idAFTree::DebugDraw -================ -*/ -void idAFTree::DebugDraw( const idVec4 &color ) const { - int i; - idAFBody *body; - - for ( i = 1; i < sortedBodies.Num(); i++ ) { - body = sortedBodies[i]; - gameRenderWorld->DebugArrow( color, body->parent->current->worldOrigin, body->current->worldOrigin, 1 ); - } -} - - -//=============================================================== -// M -// idPhysics_AF MrE -// E -//=============================================================== - -/* -================ -idPhysics_AF::EvaluateConstraints -================ -*/ -void idPhysics_AF::EvaluateConstraints( float timeStep ) { - int i; - float invTimeStep; - idAFBody *body; - idAFConstraint *c; - - invTimeStep = 1.0f / timeStep; - - // setup the constraint equations for the current position and orientation of the bodies - for ( i = 0; i < primaryConstraints.Num(); i++ ) { - c = primaryConstraints[i]; - c->Evaluate( invTimeStep ); - c->J = c->J2; - } - for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { - auxiliaryConstraints[i]->Evaluate( invTimeStep ); - } - - // add contact constraints to the list with frame constraints - for ( i = 0; i < contactConstraints.Num(); i++ ) { - AddFrameConstraint( contactConstraints[i] ); - } - - // setup body primary constraint matrix - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->primaryConstraint ) { - body->J = body->primaryConstraint->J1.Transpose(); - } - } -} - -/* -================ -idPhysics_AF::EvaluateBodies -================ -*/ -void idPhysics_AF::EvaluateBodies( float timeStep ) { - int i; - idAFBody *body; -#ifdef MOD_WATERPHYSICS - float bMass, invbMass; -#endif - idMat3 axis; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; -#ifdef MOD_WATERPHYSICS - if( this->water != NULL && body->GetWaterLevel() > 0.0f ) { - bMass = body->liquidMass; - invbMass = body->invLiquidMass; - } - else { - bMass = body->mass; - invbMass = body->invMass; - } -#endif - // we transpose the axis before using it because idMat3 is column-major - axis = body->current->worldAxis.Transpose(); - - // if the center of mass is at the body point of reference - if ( body->centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) { - - // spatial inertia in world space -#ifdef MOD_WATERPHYSICS - body->I.Set( bMass * mat3_identity, mat3_zero, - mat3_zero, axis * body->inertiaTensor * axis.Transpose() ); - body->inverseWorldSpatialInertia.Set( invbMass * mat3_identity, mat3_zero, -#else - body->I.Set( body->mass * mat3_identity, mat3_zero, - mat3_zero, axis * body->inertiaTensor * axis.Transpose() ); - // inverse spatial inertia in world space - body->inverseWorldSpatialInertia.Set( body->invMass * mat3_identity, mat3_zero, -#endif - mat3_zero, axis * body->inverseInertiaTensor * axis.Transpose() ); - - body->fl.spatialInertiaSparse = true; - } - else { -#ifdef MOD_WATERPHYSICS - idMat3 massMoment =bMass * SkewSymmetric( body->centerOfMass ); - body->I.Set( bMass * mat3_identity, massMoment, -#else - idMat3 massMoment = body->mass * SkewSymmetric( body->centerOfMass ); - // spatial inertia in world space - body->I.Set( body->mass * mat3_identity, massMoment, -#endif - massMoment.Transpose(), axis * body->inertiaTensor * axis.Transpose() ); - - // inverse spatial inertia in world space - body->inverseWorldSpatialInertia = body->I.InverseFast(); - - body->fl.spatialInertiaSparse = false; - } - - // initialize auxiliary constraint force to zero - body->auxForce.Zero(); - } -} - -/* -================ -idPhysics_AF::AddFrameConstraints -================ -*/ -void idPhysics_AF::AddFrameConstraints( void ) { - int i; - - // add frame constraints to auxiliary constraints - for ( i = 0; i < frameConstraints.Num(); i++ ) { - auxiliaryConstraints.Append( frameConstraints[i] ); - } -} - -/* -================ -idPhysics_AF::RemoveFrameConstraints -================ -*/ -void idPhysics_AF::RemoveFrameConstraints( void ) { - // remove all the frame constraints from the auxiliary constraints - auxiliaryConstraints.SetNum( auxiliaryConstraints.Num() - frameConstraints.Num(), false ); - frameConstraints.SetNum( 0, false ); -} - -/* -================ -idPhysics_AF::ApplyFriction -================ -*/ -void idPhysics_AF::ApplyFriction( float timeStep, float endTimeMSec ) { - int i; - float invTimeStep; - - if ( af_skipFriction.GetBool() ) { - return; - } - - if ( jointFrictionDentStart < MS2SEC( endTimeMSec ) && jointFrictionDentEnd > MS2SEC( endTimeMSec ) ) { - float halfTime = ( jointFrictionDentEnd - jointFrictionDentStart ) * 0.5f; - if ( jointFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) { - jointFrictionDentScale = 1.0f - ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart ) / halfTime; - } else { - jointFrictionDentScale = jointFrictionDent + ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart - halfTime ) / halfTime; - } - } else { - jointFrictionDentScale = 0.0f; - } - - if ( contactFrictionDentStart < MS2SEC( endTimeMSec ) && contactFrictionDentEnd > MS2SEC( endTimeMSec ) ) { - float halfTime = ( contactFrictionDentEnd - contactFrictionDentStart ) * 0.5f; - if ( contactFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) { - contactFrictionDentScale = 1.0f - ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart ) / halfTime; - } else { - contactFrictionDentScale = contactFrictionDent + ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart - halfTime ) / halfTime; - } - } else { - contactFrictionDentScale = 0.0f; - } - - invTimeStep = 1.0f / timeStep; - - for ( i = 0; i < primaryConstraints.Num(); i++ ) { - primaryConstraints[i]->ApplyFriction( invTimeStep ); - } - for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { - auxiliaryConstraints[i]->ApplyFriction( invTimeStep ); - } - for ( i = 0; i < frameConstraints.Num(); i++ ) { - frameConstraints[i]->ApplyFriction( invTimeStep ); - } -} - -/* -================ -idPhysics_AF::PrimaryFactor -================ -*/ -void idPhysics_AF::PrimaryFactor( void ) { - int i; - - for ( i = 0; i < trees.Num(); i++ ) { - trees[i]->Factor(); - } -} - -/* -================ -idPhysics_AF::PrimaryForces -================ -*/ -void idPhysics_AF::PrimaryForces( float timeStep ) { - int i; - - for ( i = 0; i < trees.Num(); i++ ) { - trees[i]->CalculateForces( timeStep ); - } -} - -/* -================ -idPhysics_AF::AuxiliaryForces -================ -*/ -void idPhysics_AF::AuxiliaryForces( float timeStep ) { - int i, j, k, l, n, m, s, numAuxConstraints, *index, *boxIndex; - float *ptr, *j1, *j2, *dstPtr, *forcePtr; - float invStep, u; - idAFBody *body; - idAFConstraint *constraint; - idVecX tmp; - idMatX jmk; - idVecX rhs, w, lm, lo, hi; - - // get the number of one dimensional auxiliary constraints - for ( numAuxConstraints = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - numAuxConstraints += auxiliaryConstraints[i]->J1.GetNumRows(); - } - - if ( numAuxConstraints == 0 ) { - return; - } - - // allocate memory to store the body response to auxiliary constraint forces - forcePtr = (float *) _alloca16( bodies.Num() * numAuxConstraints * 8 * sizeof( float ) ); - index = (int *) _alloca16( bodies.Num() * numAuxConstraints * sizeof( int ) ); - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->response = forcePtr; - body->responseIndex = index; - body->numResponses = 0; - body->maxAuxiliaryIndex = 0; - forcePtr += numAuxConstraints * 8; - index += numAuxConstraints; - } - - // set on each body the largest index of an auxiliary constraint constraining the body - if ( af_useSymmetry.GetBool() ) { - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { - if ( k > constraint->body1->maxAuxiliaryIndex ) { - constraint->body1->maxAuxiliaryIndex = k; - } - if ( constraint->body2 && k > constraint->body2->maxAuxiliaryIndex ) { - constraint->body2->maxAuxiliaryIndex = k; - } - } - } - for ( i = 0; i < trees.Num(); i++ ) { - trees[i]->SetMaxSubTreeAuxiliaryIndex(); - } - } - - // calculate forces of primary constraints in response to the auxiliary constraint forces - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - - for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { - - // calculate body forces in the tree in response to the constraint force - constraint->body1->tree->Response( constraint, j, k ); - // if there is a second body which is part of a different tree - if ( constraint->body2 && constraint->body2->tree != constraint->body1->tree ) { - // calculate body forces in the second tree in response to the constraint force - constraint->body2->tree->Response( constraint, j, k ); - } - } - } - - // NOTE: the rows are 16 byte padded - jmk.SetData( numAuxConstraints, ((numAuxConstraints+3)&~3), MATX_ALLOCA( numAuxConstraints * ((numAuxConstraints+3)&~3) ) ); - tmp.SetData( 6, VECX_ALLOCA( 6 ) ); - - // create constraint matrix for auxiliary constraints using a mass matrix adjusted for the primary constraints - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - - for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { - constraint->body1->InverseWorldSpatialInertiaMultiply( tmp, constraint->J1[j] ); - j1 = tmp.ToFloatPtr(); - ptr = constraint->body1->response; - index = constraint->body1->responseIndex; - dstPtr = jmk[k]; - s = af_useSymmetry.GetBool() ? k + 1 : numAuxConstraints; - for ( l = n = 0, m = index[n]; n < constraint->body1->numResponses && m < s; n++, m = index[n] ) { - while( l < m ) { - dstPtr[l++] = 0.0f; - } - dstPtr[l++] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] + - j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5]; - ptr += 8; - } - - while( l < s ) { - dstPtr[l++] = 0.0f; - } - - if ( constraint->body2 ) { - constraint->body2->InverseWorldSpatialInertiaMultiply( tmp, constraint->J2[j] ); - j2 = tmp.ToFloatPtr(); - ptr = constraint->body2->response; - index = constraint->body2->responseIndex; - for ( n = 0, m = index[n]; n < constraint->body2->numResponses && m < s; n++, m = index[n] ) { - dstPtr[m] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] + - j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5]; - ptr += 8; - } - } - } - } - - if ( af_useSymmetry.GetBool() ) { - n = jmk.GetNumColumns(); - for ( i = 0; i < numAuxConstraints; i++ ) { - ptr = jmk.ToFloatPtr() + ( i + 1 ) * n + i; - dstPtr = jmk.ToFloatPtr() + i * n + i + 1; - for ( j = i+1; j < numAuxConstraints; j++ ) { - *dstPtr++ = *ptr; - ptr += n; - } - } - } - - invStep = 1.0f / timeStep; - - // calculate body acceleration - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); - body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep; - } - - rhs.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); - lo.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); - hi.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); - lm.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) ); - boxIndex = (int *) _alloca16( numAuxConstraints * sizeof( int ) ); - - // set first index for special box constrained variables - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - auxiliaryConstraints[i]->firstIndex = k; - k += auxiliaryConstraints[i]->J1.GetNumRows(); - } - - // initialize right hand side and low and high bounds for auxiliary constraints - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - n = k; - - for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { - - j1 = constraint->J1[j]; - ptr = constraint->body1->acceleration.ToFloatPtr(); - rhs[k] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] + j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5]; - rhs[k] += constraint->c1[j] * invStep; - - if ( constraint->body2 ) { - j2 = constraint->J2[j]; - ptr = constraint->body2->acceleration.ToFloatPtr(); - rhs[k] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] + j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5]; - rhs[k] += constraint->c2[j] * invStep; - } - - rhs[k] = -rhs[k]; - lo[k] = constraint->lo[j]; - hi[k] = constraint->hi[j]; - - if ( constraint->boxIndex[j] >= 0 ) { - if ( constraint->boxConstraint->fl.isPrimary ) { - gameLocal.Error( "cannot reference primary constraints for the box index" ); - } - boxIndex[k] = constraint->boxConstraint->firstIndex + constraint->boxIndex[j]; - } - else { - boxIndex[k] = -1; - } - jmk[k][k] += constraint->e[j] * invStep; - } - } - -#ifdef AF_TIMINGS - timer_lcp.Start(); -#endif - - // calculate lagrange multipliers for auxiliary constraints - if ( !lcp->Solve( jmk, lm, rhs, lo, hi, boxIndex ) ) { - return; // bad monkey! - } - -#ifdef AF_TIMINGS - timer_lcp.Stop(); -#endif - - // calculate auxiliary constraint forces - for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - - for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) { - constraint->lm[j] = u = lm[k]; - - j1 = constraint->J1[j]; - ptr = constraint->body1->auxForce.ToFloatPtr(); - ptr[0] += j1[0] * u; ptr[1] += j1[1] * u; ptr[2] += j1[2] * u; - ptr[3] += j1[3] * u; ptr[4] += j1[4] * u; ptr[5] += j1[5] * u; - - if ( constraint->body2 ) { - j2 = constraint->J2[j]; - ptr = constraint->body2->auxForce.ToFloatPtr(); - ptr[0] += j2[0] * u; ptr[1] += j2[1] * u; ptr[2] += j2[2] * u; - ptr[3] += j2[3] * u; ptr[4] += j2[4] * u; ptr[5] += j2[5] * u; - } - } - } - - // recalculate primary constraint forces in response to auxiliary constraint forces - PrimaryForces( timeStep ); - - // clear pointers pointing to stack space so tools don't get confused - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->response = NULL; - body->responseIndex = NULL; - } -} - -/* -================ -idPhysics_AF::VerifyContactConstraints -================ -*/ -void idPhysics_AF::VerifyContactConstraints( void ) { -#if 0 - int i; - float impulseNumerator, impulseDenominator; - idVec3 r, velocity, normalVelocity, normal, impulse; - idAFBody *body; - - for ( i = 0; i < contactConstraints.Num(); i++ ) { - body = contactConstraints[i]->body1; - const contactInfo_t &contact = contactConstraints[i]->GetContact(); - - r = contact.point - body->GetCenterOfMass(); - - // calculate velocity at contact point - velocity = body->GetLinearVelocity() + body->GetAngularVelocity().Cross( r ); - - // velocity along normal vector - normalVelocity = ( velocity * contact.normal ) * contact.normal; - - // if moving towards the surface at the contact point - if ( normalVelocity * contact.normal < 0.0f ) { - // calculate impulse - normal = -normalVelocity; - impulseNumerator = normal.Normalize(); - impulseDenominator = body->GetInverseMass() + ( ( body->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal ); - impulse = (impulseNumerator / impulseDenominator) * normal * 1.0001f; - - // apply impulse - body->SetLinearVelocity( body->GetLinearVelocity() + impulse ); - body->SetAngularVelocity( body->GetAngularVelocity() + r.Cross( impulse ) ); - } - } -#else - int i; - idAFBody *body; - idVec3 normal; - - for ( i = 0; i < contactConstraints.Num(); i++ ) { - body = contactConstraints[i]->body1; - normal = contactConstraints[i]->GetContact().normal; - if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) { - body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal; - } - body = contactConstraints[i]->body2; - if ( !body ) { - continue; - } - normal = -normal; - if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) { - body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal; - } - } -#endif -} - -/* -================ -idPhysics_AF::Evolve -================ -*/ -void idPhysics_AF::Evolve( float timeStep ) { - int i; - float angle; -#ifdef MOD_WATERPHYSICS - float waterLevel; -#endif - idVec3 vec; - idAFBody *body; - idVec6 force; - idRotation rotation; - float vSqr, maxLinearVelocity, maxAngularVelocity; - - maxLinearVelocity = af_maxLinearVelocity.GetFloat() / timeStep; - maxAngularVelocity = af_maxAngularVelocity.GetFloat() / timeStep; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - // calculate the spatial velocity for the next physics state - body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() ); - body->next->spatialVelocity = body->current->spatialVelocity + timeStep * body->acceleration.SubVec6(0); - - if ( maxLinearVelocity > 0.0f ) { - // cap the linear velocity - vSqr = body->next->spatialVelocity.SubVec3(0).LengthSqr(); - if ( vSqr > Square( maxLinearVelocity ) ) { - body->next->spatialVelocity.SubVec3(0) *= idMath::InvSqrt( vSqr ) * maxLinearVelocity; - } - } - - if ( maxAngularVelocity > 0.0f ) { - // cap the angular velocity - vSqr = body->next->spatialVelocity.SubVec3(1).LengthSqr(); - if ( vSqr > Square( maxAngularVelocity ) ) { - body->next->spatialVelocity.SubVec3(1) *= idMath::InvSqrt( vSqr ) * maxAngularVelocity; - } - } - } - - // make absolutely sure all contact constraints are satisfied - VerifyContactConstraints(); - - // calculate the position of the bodies for the next physics state - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - // translate world origin - body->next->worldOrigin = body->current->worldOrigin + timeStep * body->next->spatialVelocity.SubVec3( 0 ); - - // convert angular velocity to a rotation matrix - vec = body->next->spatialVelocity.SubVec3( 1 ); - angle = -timeStep * (float) RAD2DEG( vec.Normalize() ); - rotation = idRotation( vec3_origin, vec, angle ); - rotation.Normalize180(); - - // rotate world axis - body->next->worldAxis = body->current->worldAxis * rotation.ToMat3(); - body->next->worldAxis.OrthoNormalizeSelf(); - - // linear and angular friction -#ifdef MOD_WATERPHYSICS - // apply a higher friction value if the AF is underwater - waterLevel = body->GetWaterLevel(); - if( waterLevel == 0.0f || this->water == NULL ) { - body->next->spatialVelocity.SubVec3(0) -= body->linearFriction * body->next->spatialVelocity.SubVec3(0); - } - else { - body->next->spatialVelocity.SubVec3(0) -= (body->linearFriction * (this->water->GetViscosity()+WATER_FRICTION) * waterLevel) * body->next->spatialVelocity.SubVec3(0); - } -#else - body->next->spatialVelocity.SubVec3(0) -= body->linearFriction * body->next->spatialVelocity.SubVec3(0); -#endif - body->next->spatialVelocity.SubVec3(1) -= body->angularFriction * body->next->spatialVelocity.SubVec3(1); - } -} - -/* -================ -idPhysics_AF::CollisionImpulse - - apply impulse to the colliding bodies - the current state of the body should be set to the moment of impact - this is silly as it doesn't take the AF structure into account -================ -*/ -bool idPhysics_AF::CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision ) { - idVec3 r, velocity, impulse; - idMat3 inverseWorldInertiaTensor; - float impulseNumerator, impulseDenominator; -#ifdef MOD_WATERPHYSICS - float invMass; -#endif - impactInfo_t info; - idEntity *ent; - - ent = gameLocal.entities[collision.c.entityNum]; - if ( ent == self ) { - return false; - } - -#ifdef MOD_WATERPHYSICS - if( this->water != NULL ) { - invMass = body->invLiquidMass; - } else { - invMass = body->invMass; - } -#endif - - // get info from other entity involved - ent->GetImpactInfo( self, collision.c.id, collision.c.point, &info ); - - // Update moved by and set in motion by actor - if( self->m_SetInMotionByActor.GetEntity() ) - { - ent->m_SetInMotionByActor = self->m_SetInMotionByActor.GetEntity(); - ent->m_MovedByActor = self->m_MovedByActor.GetEntity(); - } - // Note: Actors should not overwrite the moved by other actors when they are hit with something - // So only overwrite if MovedByActor is NULL - if( ent->IsType(idActor::Type) - && self->m_SetInMotionByActor.GetEntity() == NULL - && !(static_cast(ent)->IsKnockedOut() || ent->health < 0) ) - { - self->m_SetInMotionByActor = (idActor *) ent; - self->m_MovedByActor = (idActor *) ent; - } - if( self->IsType(idActor::Type) - && ent->m_SetInMotionByActor.GetEntity() == NULL - && !(static_cast(self)->IsKnockedOut() || self->health < 0) ) - { - ent->m_SetInMotionByActor = (idActor *) self; - ent->m_MovedByActor = (idActor *) self; - } - - - // collision point relative to the body center of mass - r = collision.c.point - (body->current->worldOrigin + body->centerOfMass * body->current->worldAxis); - // the velocity at the collision point - velocity = body->current->spatialVelocity.SubVec3(0) + body->current->spatialVelocity.SubVec3(1).Cross(r); - // subtract velocity of other entity - velocity -= info.velocity; - // never stick - if ( velocity * collision.c.normal > 0.0f ) { - velocity = collision.c.normal; - } - inverseWorldInertiaTensor = body->current->worldAxis.Transpose() * body->inverseInertiaTensor * body->current->worldAxis; - impulseNumerator = -( 1.0f + body->bouncyness ) * ( velocity * collision.c.normal ); -#ifdef MOD_WATERPHYSICS - impulseDenominator = invMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); -#else - impulseDenominator = body->invMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); -#endif - if ( info.invMass ) { - impulseDenominator += info.invMass + ( ( info.invInertiaTensor * info.position.Cross( collision.c.normal ) ).Cross( info.position ) * collision.c.normal ); - } - impulse = (impulseNumerator / impulseDenominator) * collision.c.normal; - - // apply impact to other entity - ent->ApplyImpulse( self, collision.c.id, collision.c.point, -impulse ); - - // callback to self to let the entity know about the impact - return self->Collide( collision, velocity ); -} - -/* -================ -idPhysics_AF::ApplyCollisions -================ -*/ -bool idPhysics_AF::ApplyCollisions( float timeStep ) { - int i; - - for ( i = 0; i < collisions.Num(); i++ ) { - if ( CollisionImpulse( timeStep, collisions[i].body, collisions[i].trace ) ) { - return true; - } - } - return false; -} - -/* -================ -idPhysics_AF::SetupCollisionForBody -================ -*/ -idEntity *idPhysics_AF::SetupCollisionForBody( idAFBody *body ) const { - int i; - idAFBody *b; - idEntity *passEntity; - - passEntity = NULL; - - if ( !selfCollision || !body->fl.selfCollision || af_skipSelfCollision.GetBool() ) { - - // disable all bodies - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->clipModel->Disable(); - } - - // don't collide with world collision model if attached to the world - for ( i = 0; i < body->constraints.Num(); i++ ) { - if ( !body->constraints[i]->fl.noCollision ) { - continue; - } - // if this constraint attaches the body to the world - if ( body->constraints[i]->body2 == NULL ) { - // don't collide with the world collision model - passEntity = gameLocal.world; - } - } - - } else { - - // enable all bodies that have self collision - for ( i = 0; i < bodies.Num(); i++ ) { - if ( bodies[i]->fl.selfCollision ) { - bodies[i]->clipModel->Enable(); - } else { - bodies[i]->clipModel->Disable(); - } - } - - // don't let the body collide with itself - body->clipModel->Disable(); - - // disable any bodies attached with constraints - for ( i = 0; i < body->constraints.Num(); i++ ) { - if ( !body->constraints[i]->fl.noCollision ) { - continue; - } - // if this constraint attaches the body to the world - if ( body->constraints[i]->body2 == NULL ) { - // don't collide with the world collision model - passEntity = gameLocal.world; - } else { - if ( body->constraints[i]->body1 == body ) { - b = body->constraints[i]->body2; - } else if ( body->constraints[i]->body2 == body ) { - b = body->constraints[i]->body1; - } else { - continue; - } - // don't collide with this body - b->clipModel->Disable(); - } - } - } - - return passEntity; -} - -/* -================ -idPhysics_AF::CheckForCollisions - - check for collisions between the current and next state - if there is a collision the next state is set to the state at the moment of impact - assumes all bodies are linked for collision detection and relinks all bodies after moving them -================ -*/ -void idPhysics_AF::CheckForCollisions( float timeStep ) { -// #define TEST_COLLISION_DETECTION - int i, index; - idAFBody *body; - idMat3 axis; - idRotation rotation; - trace_t collision; - idEntity *passEntity; -#ifdef MOD_WATERPHYSICS - impactInfo_t info; -#endif - - // clear list with collisions - collisions.SetNum( 0, false ); - - if ( !enableCollision ) { - return; - } - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->clipMask != 0 ) { - - passEntity = SetupCollisionForBody( body ); - -#ifdef TEST_COLLISION_DETECTION - bool startsolid = false; - if ( gameLocal.clip.Contents( body->current->worldOrigin, body->clipModel, - body->current->worldAxis, body->clipMask, passEntity ) ) { - startsolid = true; - } -#endif - - TransposeMultiply( body->current->worldAxis, body->next->worldAxis, axis ); - rotation = axis.ToRotation(); - rotation.SetOrigin( body->current->worldOrigin ); - - // if there was a collision - if ( gameLocal.clip.Motion( collision, body->current->worldOrigin, body->next->worldOrigin, rotation, - body->clipModel, body->current->worldAxis, body->clipMask, passEntity ) ) { - - // set the next state to the state at the moment of impact - body->next->worldOrigin = collision.endpos; - body->next->worldAxis = collision.endAxis; - - // add collision to the list - index = collisions.Num(); - collisions.SetNum( index + 1, false ); - collisions[index].trace = collision; - collisions[index].body = body; - } - -#ifdef MOD_WATERPHYSICS - // Check for water collision - // ideally we could do this check in one step but if a body moves quickly in shallow water - // they will occasionally clip through a solid entity (ie. fall through the floor) - if ( gameLocal.clip.Motion( collision, body->current->worldOrigin, body->next->worldOrigin, rotation, - body->clipModel, body->current->worldAxis, MASK_WATER, passEntity ) ) { - idEntity *ent = gameLocal.entities[collision.c.entityNum]; - - // if the object collides with something with a physics_liquid - if( ent->GetPhysics()->IsType( idPhysics_Liquid::Type ) ) { - idPhysics_Liquid *liquid = static_cast(ent->GetPhysics()); - impactInfo_t info; - - this->self->GetImpactInfo(ent,collision.c.id,collision.c.point,&info); - - this->SetWater(liquid, ent->spawnArgs.GetFloat("murkiness", "0") ); - this->water->Splash(this->self,body->GetVolume(),info,collision); - } - } -#endif - - -#ifdef TEST_COLLISION_DETECTION - if ( gameLocal.clip.Contents( body->next->worldOrigin, body->clipModel, - body->next->worldAxis, body->clipMask, passEntity ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - } - - body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->next->worldOrigin, body->next->worldAxis ); - } -} - -/* -================ -idPhysics_AF::EvaluateContacts -================ -*/ -bool idPhysics_AF::EvaluateContacts( void ) { - int i, j, k, numContacts, numBodyContacts; - idAFBody *body; - contactInfo_t contactInfo[10]; - idEntity *passEntity; - idVecX dir( 6, VECX_ALLOCA( 6 ) ); - - // evaluate bodies - EvaluateBodies( current.lastTimeStep ); - - // remove all existing contacts - ClearContacts(); - - contactBodies.SetNum( 0, false ); - - if ( !enableCollision ) { - return false; - } - - // find all the contacts - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->clipMask == 0 ) { - continue; - } - - passEntity = SetupCollisionForBody( body ); - - body->InverseWorldSpatialInertiaMultiply( dir, body->current->externalForce.ToFloatPtr() ); - dir.SubVec6(0) = body->current->spatialVelocity + current.lastTimeStep * dir.SubVec6(0); - dir.SubVec3(0).Normalize(); - dir.SubVec3(1).Normalize(); - - numContacts = gameLocal.clip.Contacts( contactInfo, 10, body->current->worldOrigin, dir.SubVec6(0), 2.0f, //CONTACT_EPSILON, - body->clipModel, body->current->worldAxis, body->clipMask, passEntity ); - -#if 1 - // merge nearby contacts between the same bodies - // and assure there are at most three planar contacts between any pair of bodies - for ( j = 0; j < numContacts; j++ ) { - - numBodyContacts = 0; - for ( k = 0; k < contacts.Num(); k++ ) { - if ( contacts[k].entityNum == contactInfo[j].entityNum ) { - if ( ( contacts[k].id == i && contactInfo[j].id == contactBodies[k] ) || - ( contactBodies[k] == i && contacts[k].id == contactInfo[j].id ) ) { - - if ( ( contacts[k].point - contactInfo[j].point ).LengthSqr() < Square( 2.0f ) ) { - break; - } - if ( idMath::Fabs( contacts[k].normal * contactInfo[j].normal ) > 0.9f ) { - numBodyContacts++; - } - } - } - } - - if ( k >= contacts.Num() && numBodyContacts < 3 ) { - contacts.Append( contactInfo[j] ); - contactBodies.Append( i ); - } - } - -#else - - for ( j = 0; j < numContacts; j++ ) { - contacts.Append( contactInfo[j] ); - contactBodies.Append( i ); - } -#endif - - } - - AddContactEntitiesForContacts(); - - return ( contacts.Num() != 0 ); -} - -/* -================ -idPhysics_AF::SetupContactConstraints -================ -*/ -void idPhysics_AF::SetupContactConstraints( void ) { - int i; - - // make sure enough contact constraints are allocated - contactConstraints.AssureSizeAlloc( contacts.Num(), idListNewElement ); - contactConstraints.SetNum( contacts.Num(), false ); - - // setup contact constraints - for ( i = 0; i < contacts.Num(); i++ ) { - // add contact constraint - contactConstraints[i]->physics = this; - if ( contacts[i].entityNum == self->entityNumber ) { - contactConstraints[i]->Setup( bodies[contactBodies[i]], bodies[ contacts[i].id ], contacts[i] ); - } - else { - contactConstraints[i]->Setup( bodies[contactBodies[i]], NULL, contacts[i] ); - } - } -} - -/* -================ -idPhysics_AF::ApplyContactForces -================ -*/ -void idPhysics_AF::ApplyContactForces( void ) { -#if 0 - int i; - idEntity *ent; - idVec3 force; - - for ( i = 0; i < contactConstraints.Num(); i++ ) { - if ( contactConstraints[i]->body2 != NULL ) { - continue; - } - const contactInfo_t &contact = contactConstraints[i]->GetContact(); - ent = gameLocal.entities[contact.entityNum]; - if ( !ent ) { - continue; - } - force.Zero(); - ent->AddForce( self, contact.id, contact.point, force ); - } -#endif -} - -/* -================ -idPhysics_AF::ClearExternalForce -================ -*/ -void idPhysics_AF::ClearExternalForce( void ) { - int i; - idAFBody *body; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - // clear external force - body->current->externalForce.Zero(); - body->next->externalForce.Zero(); - } -} - -/* -================ -idPhysics_AF::AddGravity -================ -*/ -void idPhysics_AF::AddGravity( void ) { - int i; - idAFBody *body; -#ifdef MOD_WATERPHYSICS - idVec3 grav( this->liquidDensity * this->gravityVector ); - float waterLevel,wDensity = 0; - bool inWater,bodyBuoyancy = 0; - - if( this->SetWaterLevelf() == 1.0f ) { - wDensity = this->water->GetDensity(); - bodyBuoyancy = af_useBodyDensityBuoyancy.GetBool(); - } - - inWater = false; -#endif - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; -#ifdef MOD_WATERPHYSICS - // add gravitational force - waterLevel = body->SetWaterLevel(this->water,this->gravityNormal,this->fixedDensityBuoyancy); - if( waterLevel > 0.0f ) { - if( !this->fixedDensityBuoyancy && !bodyBuoyancy ) - { - body->liquidMass = body->mass; - body->invLiquidMass = body->invMass; - } - else { - body->liquidMass = body->volume * this->liquidDensity * LIQUID_MASS_MUL; - body->invLiquidMass = 1 / body->liquidMass; - } - - // we float the body in water - if( bodyBuoyancy ) - body->current->externalForce.SubVec3( 0 ) += (body->mass - (body->volume * wDensity * waterLevel)) * gravityVector; - else if( this->fixedDensityBuoyancy ) - body->current->externalForce.SubVec3( 0 ) += body->volume * ( this->liquidDensity - (wDensity * waterLevel) ) * gravityVector; - else - body->current->externalForce.SubVec3( 0 ) += body->mass * grav * waterLevel; - - inWater = true; - } - else { - body->current->externalForce.SubVec3( 0 ) += body->mass * gravityVector; - } -#else - // add gravitational force - body->current->externalForce.SubVec3( 0 ) += body->mass * gravityVector; -#endif - } - -#ifdef MOD_WATERPHYSICS -// if all AFBodies are not in the water, we assume the whole entity is not in water so -// we clear the water flag - if( !inWater ) - { - this->water = NULL; - this->m_fWaterMurkiness = 0.0f; - } -#endif -} - -/* -================ -idPhysics_AF::SwapStates -================ -*/ -void idPhysics_AF::SwapStates( void ) { - int i; - idAFBody *body; - AFBodyPState_t *swap; - - for ( i = 0; i < bodies.Num(); i++ ) { - - body = bodies[i]; - - // swap the current and next state for next simulation step - swap = body->current; - body->current = body->next; - body->next = swap; - } -} - -/* -================ -idPhysics_AF::UpdateClipModels -================ -*/ -void idPhysics_AF::UpdateClipModels( void ) { - int i; - idAFBody *body; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->current->worldOrigin, body->current->worldAxis ); - } -} - -/* -================ -idPhysics_AF::SetSuspendSpeed -================ -*/ -void idPhysics_AF::SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration ) { - this->suspendVelocity = velocity; - this->suspendAcceleration = acceleration; -} - -/* -================ -idPhysics_AF::SetSuspendTime -================ -*/ -void idPhysics_AF::SetSuspendTime( const float minTime, const float maxTime ) { - this->minMoveTime = minTime; - this->maxMoveTime = maxTime; -} - -/* -================ -idPhysics_AF::SetSuspendTolerance -================ -*/ -void idPhysics_AF::SetSuspendTolerance( const float noMoveTime, const float noMoveTranslation, const float noMoveRotation ) { - this->noMoveTime = noMoveTime; - this->noMoveTranslation = noMoveTranslation; - this->noMoveRotation = noMoveRotation; -} - -/* -================ -idPhysics_AF::SetTimeScaleRamp -================ -*/ -void idPhysics_AF::SetTimeScaleRamp( const float start, const float end ) { - timeScaleRampStart = start; - timeScaleRampEnd = end; -} - -/* -================ -idPhysics_AF::SetJointFrictionDent -================ -*/ -void idPhysics_AF::SetJointFrictionDent( const float dent, const float start, const float end ) { - jointFrictionDent = dent; - jointFrictionDentStart = start; - jointFrictionDentEnd = end; -} - -/* -================ -idPhysics_AF::GetJointFrictionScale -================ -*/ -float idPhysics_AF::GetJointFrictionScale( void ) const { - if ( jointFrictionDentScale > 0.0f ) { - return jointFrictionDentScale; - } else if ( jointFrictionScale > 0.0f ) { - return jointFrictionScale; - } else if ( af_jointFrictionScale.GetFloat() > 0.0f ) { - return af_jointFrictionScale.GetFloat(); - } - return 1.0f; -} - -/* -================ -idPhysics_AF::SetContactFrictionDent -================ -*/ -void idPhysics_AF::SetContactFrictionDent( const float dent, const float start, const float end ) { - contactFrictionDent = dent; - contactFrictionDentStart = start; - contactFrictionDentEnd = end; -} - -/* -================ -idPhysics_AF::GetContactFrictionScale -================ -*/ -float idPhysics_AF::GetContactFrictionScale( void ) const { - if ( contactFrictionDentScale > 0.0f ) { - return contactFrictionDentScale; - } else if ( contactFrictionScale > 0.0f ) { - return contactFrictionScale; - } else if ( af_contactFrictionScale.GetFloat() > 0.0f ) { - return af_contactFrictionScale.GetFloat(); - } - return 1.0f; -} - -/* -================ -idPhysics_AF::TestIfAtRest -================ -*/ -bool idPhysics_AF::TestIfAtRest( float timeStep ) { - int i; - float translationSqr, maxTranslationSqr, rotation, maxRotation; - idAFBody *body; - - if ( current.atRest >= 0 ) { - return true; - } - -#ifdef MOD_WATERPHYSICS -// prevent bodies from going in active after floating. You don't really want bodies to -// go inactive if they're in water (sometimes they just have a long way to go before surfacing) - if( this->water != NULL ) current.activateTime = 0.0f; -#endif - - current.activateTime += timeStep; - - // if the simulation should never be suspended before a certaint amount of time passed - if ( minMoveTime > 0.0f && current.activateTime < minMoveTime ) { - return false; - } - - // if the simulation should always be suspended after a certain amount time passed - if ( maxMoveTime > 0.0f && current.activateTime > maxMoveTime ) { - return true; - } - - // test if all bodies hardly moved over a period of time - if ( current.noMoveTime == 0.0f ) { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->atRestOrigin = body->current->worldOrigin; - body->atRestAxis = body->current->worldAxis; - } - current.noMoveTime += timeStep; - } - else if ( current.noMoveTime > noMoveTime ) { - current.noMoveTime = 0.0f; - maxTranslationSqr = 0.0f; - maxRotation = 0.0f; - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - translationSqr = ( body->current->worldOrigin - body->atRestOrigin ).LengthSqr(); - if ( translationSqr > maxTranslationSqr ) { - maxTranslationSqr = translationSqr; - } - rotation = ( body->atRestAxis.Transpose() * body->current->worldAxis ).ToRotation().GetAngle(); - if ( rotation > maxRotation ) { - maxRotation = rotation; - } - } - - if ( maxTranslationSqr < Square( noMoveTranslation ) && maxRotation < noMoveRotation ) { - // hardly moved over a period of time so the articulated figure may come to rest - return true; - } - } else { - current.noMoveTime += timeStep; - } - - // test if the velocity or acceleration of any body is still too large to come to rest -#ifdef MOD_WATERPHYSICS - if( this->water == NULL ) { -#endif - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->current->spatialVelocity.SubVec3(0).LengthSqr() > Square( suspendVelocity[0] ) ) { - return false; - } - if ( body->current->spatialVelocity.SubVec3(1).LengthSqr() > Square( suspendVelocity[1] ) ) { - return false; - } - if ( body->acceleration.SubVec3(0).LengthSqr() > Square( suspendAcceleration[0] ) ) { - return false; - } - if ( body->acceleration.SubVec3(1).LengthSqr() > Square( suspendAcceleration[1] ) ) { - return false; - } - } -#ifdef MOD_WATERPHYSICS - } else { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->current->spatialVelocity.SubVec3(0).LengthSqr() > Square( suspendVelocity[0] ) ) { - return false; - } - if ( body->current->spatialVelocity.SubVec3(1).LengthSqr() > Square( suspendVelocity[1] ) ) { - return false; - } - if ( body->acceleration.SubVec3(0).LengthSqr() > Square( suspendAcceleration[0] ) ) { - return false; - } - if ( body->acceleration.SubVec3(1).LengthSqr() > Square( suspendAcceleration[1] ) ) { - return false; - } - } - } -#endif - - // all bodies have a velocity and acceleration small enough to come to rest - return true; -} - -/* -================ -idPhysics_AF::Rest -================ -*/ -void idPhysics_AF::Rest( void ) { - int i; - - current.atRest = gameLocal.time; - - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->current->spatialVelocity.Zero(); - bodies[i]->current->externalForce.Zero(); - } - - self->BecomeInactive( TH_PHYSICS ); - self->m_SetInMotionByActor = NULL; - self->m_droppedByAI = false; // grayman #1330 -} - -/* -================ -idPhysics_AF::Activate -================ -*/ -void idPhysics_AF::Activate( void ) { - // if the articulated figure was at rest - if ( current.atRest >= 0 ) { - // normally gravity is added at the end of a simulation frame - // if the figure was at rest add gravity here so it is applied this simulation frame - AddGravity(); - // reset the active time for the max move time - current.activateTime = 0.0f; - } - current.atRest = -1; - current.noMoveTime = 0.0f; - self->BecomeActive( TH_PHYSICS ); -} - -/* -================ -idPhysics_AF::PutToRest - - put to rest untill something collides with this physics object -================ -*/ -void idPhysics_AF::PutToRest( void ) { - Rest(); -} - -/* -================ -idPhysics_AF::EnableImpact -================ -*/ -void idPhysics_AF::EnableImpact( void ) { - noImpact = false; -} - -/* -================ -idPhysics_AF::DisableImpact -================ -*/ -void idPhysics_AF::DisableImpact( void ) { - noImpact = true; -} - -/* -================ -idPhysics_AF::AddPushVelocity -================ -*/ -void idPhysics_AF::AddPushVelocity( const idVec6 &pushVelocity ) { - int i; - - if ( pushVelocity != vec6_origin ) { - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->current->spatialVelocity += pushVelocity; - } - } -} - -/* -================ -idPhysics_AF::SetClipModel -================ -*/ -void idPhysics_AF::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { -} - -/* -================ -idPhysics_AF::GetClipModel -================ -*/ -idClipModel *idPhysics_AF::GetClipModel( int id ) const { - if ( id >= 0 && id < bodies.Num() ) { - return bodies[id]->GetClipModel(); - } - return NULL; -} - -/* -================ -idPhysics_AF::GetNumClipModels -================ -*/ -int idPhysics_AF::GetNumClipModels( void ) const { - return bodies.Num(); -} - -/* -================ -idPhysics_AF::SetMass -================ -*/ -void idPhysics_AF::SetMass( float mass, int id ) { - if ( id >= 0 && id < bodies.Num() ) { - } - else { - forceTotalMass = mass; - } - SetChanged(); -} - -/* -================ -idPhysics_AF::GetMass -================ -*/ -float idPhysics_AF::GetMass( int id ) const { - if ( id >= 0 && id < bodies.Num() ) { -#ifdef MOD_WATERPHYSICS - if ( bodies[id]->GetWaterLevel() > 0.0f ) - return bodies[id]->liquidMass; - else -#endif - return bodies[id]->mass; - } - -#ifdef MOD_WATERPHYSICS - // if body in water, we have to recompute the total mass - if( this->water != NULL ) { - int i; - float waterMass = 0.0f; - - for( i = 0; i < this->bodies.Num(); i++ ) { - waterMass += this->bodies[i]->liquidMass; - } - - return waterMass; - } -#endif - - return totalMass; -} - -/* -================ -idPhysics_AF::SetContents -================ -*/ -void idPhysics_AF::SetContents( int contents, int id ) { - int i; - - if ( id >= 0 && id < bodies.Num() ) { - bodies[id]->GetClipModel()->SetContents( contents ); - } - else { - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->GetClipModel()->SetContents( contents ); - } - } -} - -/* -================ -idPhysics_AF::GetContents -================ -*/ -int idPhysics_AF::GetContents( int id ) const { - int i, contents; - - if ( id >= 0 && id < bodies.Num() ) { - return bodies[id]->GetClipModel()->GetContents(); - } - else { - contents = 0; - for ( i = 0; i < bodies.Num(); i++ ) { - contents |= bodies[i]->GetClipModel()->GetContents(); - } - return contents; - } -} - -/* -================ -idPhysics_AF::GetBounds -================ -*/ -const idBounds &idPhysics_AF::GetBounds( int id ) const { - int i; - static idBounds relBounds; - - if ( id >= 0 && id < bodies.Num() ) { - return bodies[id]->GetClipModel()->GetBounds(); - } - else if ( !bodies.Num() ) { - relBounds.Zero(); - return relBounds; - } - else { - relBounds = bodies[0]->GetClipModel()->GetBounds(); - for ( i = 1; i < bodies.Num(); i++ ) { - idBounds bounds; - idVec3 origin = ( bodies[i]->GetWorldOrigin() - bodies[0]->GetWorldOrigin() ) * bodies[0]->GetWorldAxis().Transpose(); - idMat3 axis = bodies[i]->GetWorldAxis() * bodies[0]->GetWorldAxis().Transpose(); - bounds.FromTransformedBounds( bodies[i]->GetClipModel()->GetBounds(), origin, axis ); - relBounds += bounds; - } - return relBounds; - } -} - -/* -================ -idPhysics_AF::GetAbsBounds -================ -*/ -const idBounds &idPhysics_AF::GetAbsBounds( int id ) const { - int i; - static idBounds absBounds; - - if ( id >= 0 && id < bodies.Num() ) { - return bodies[id]->GetClipModel()->GetAbsBounds(); - } - else if ( !bodies.Num() ) { - absBounds.Zero(); - return absBounds; - } - else { - absBounds = bodies[0]->GetClipModel()->GetAbsBounds(); - for ( i = 1; i < bodies.Num(); i++ ) { - absBounds += bodies[i]->GetClipModel()->GetAbsBounds(); - } - return absBounds; - } -} - -/* -================ -idPhysics_AF::Evaluate -================ -*/ -bool idPhysics_AF::Evaluate( int timeStepMSec, int endTimeMSec ) -{ - float timeStep; - - if ( timeScaleRampStart < MS2SEC( endTimeMSec ) && timeScaleRampEnd > MS2SEC( endTimeMSec ) ) { - timeStep = MS2SEC( timeStepMSec ) * ( MS2SEC( endTimeMSec ) - timeScaleRampStart ) / ( timeScaleRampEnd - timeScaleRampStart ); - } else if ( af_timeScale.GetFloat() != 1.0f ) { - timeStep = MS2SEC( timeStepMSec ) * af_timeScale.GetFloat(); - } else { - timeStep = MS2SEC( timeStepMSec ) * timeScale; - } - current.lastTimeStep = timeStep; - - - // if the articulated figure changed - if ( changedAF || ( linearTime != af_useLinearTime.GetBool() ) ) { - BuildTrees(); - changedAF = false; - linearTime = af_useLinearTime.GetBool(); - } - - // get the new master position - if ( masterBody ) { - idVec3 masterOrigin; - idMat3 masterAxis; - self->GetMasterPosition( masterOrigin, masterAxis ); - if ( current.atRest >= 0 && ( masterBody->current->worldOrigin != masterOrigin || masterBody->current->worldAxis != masterAxis ) ) { - Activate(); - } - masterBody->current->worldOrigin = masterOrigin; - masterBody->current->worldAxis = masterAxis; - } - - // if the simulation is suspended because the figure is at rest - if ( current.atRest >= 0 || timeStep <= 0.0f ) { - DebugDraw(); - return false; - } - - // move the af velocity into the frame of a pusher - AddPushVelocity( -current.pushVelocity ); - - // TDM: Enable the clipmodels of all team members for collisions - idEntity *part = NULL; - - idList InitClipStates; - bool PartClipState = false; - - if( ((idAFEntity_Base *) self )->CollidesWithTeam() ) - { - for ( part = self->GetTeamMaster(); part != NULL; part = part->GetNextTeamEntity() ) - { - if ( part != self && part->GetPhysics() ) - { - PartClipState = part->GetPhysics()->GetClipModel()->IsEnabled(); - InitClipStates.Append( PartClipState ); - - part->GetPhysics()->EnableClip(); - } - } - } - -#ifdef AF_TIMINGS - timer_total.Start(); -#endif - -#ifdef AF_TIMINGS - timer_collision.Start(); -#endif - - // evaluate contacts - EvaluateContacts(); - - // setup contact constraints - SetupContactConstraints(); - -#ifdef AF_TIMINGS - timer_collision.Stop(); -#endif - - // evaluate constraint equations - EvaluateConstraints( timeStep ); - - // apply friction - ApplyFriction( timeStep, endTimeMSec ); - - // add frame constraints - AddFrameConstraints(); - -#ifdef AF_TIMINGS - int i, numPrimary = 0, numAuxiliary = 0; - for ( i = 0; i < primaryConstraints.Num(); i++ ) { - numPrimary += primaryConstraints[i]->J1.GetNumRows(); - } - for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { - numAuxiliary += auxiliaryConstraints[i]->J1.GetNumRows(); - } - timer_pc.Start(); -#endif - - // factor matrices for primary constraints - PrimaryFactor(); - - // calculate forces on bodies after applying primary constraints - PrimaryForces( timeStep ); - -#ifdef AF_TIMINGS - timer_pc.Stop(); - timer_ac.Start(); -#endif - - // calculate and apply auxiliary constraint forces - AuxiliaryForces( timeStep ); - -#ifdef AF_TIMINGS - timer_ac.Stop(); -#endif - - // evolve current state to next state - Evolve( timeStep ); - - // debug graphics - DebugDraw(); - - // clear external forces on all bodies - ClearExternalForce(); - - // apply contact force to other entities - ApplyContactForces(); - - // remove all frame constraints - RemoveFrameConstraints(); - -#ifdef AF_TIMINGS - timer_collision.Start(); -#endif - - // check for collisions between current and next state - CheckForCollisions( timeStep ); - -#ifdef AF_TIMINGS - timer_collision.Stop(); -#endif - - // swap the current and next state - SwapStates(); - - // make sure all clip models are disabled in case they were enabled for self collision - if ( selfCollision && !af_skipSelfCollision.GetBool() ) { - DisableClip(); - } - - // apply collision impulses - if ( ApplyCollisions( timeStep ) ) { - current.atRest = gameLocal.time; - comeToRest = true; - } - - // test if the simulation can be suspended because the whole figure is at rest - if ( comeToRest && TestIfAtRest( timeStep ) ) { - Rest(); - } else { - ActivateContactEntities(); - } - - // add gravitational force - AddGravity(); - - // move the af velocity back into the world frame - AddPushVelocity( current.pushVelocity ); - current.pushVelocity.Zero(); - - if ( IsOutsideWorld() ) { - gameLocal.Warning( "articulated figure moved outside world bounds for entity '%s' type '%s' at (%s)", - self->name.c_str(), self->GetType()->classname, bodies[0]->current->worldOrigin.ToString(0) ); - Rest(); - } - -#ifdef AF_TIMINGS - timer_total.Stop(); - - if ( af_showTimings.GetInteger() == 1 ) { - gameLocal.Printf( "%12s: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n", - self->name.c_str(), - timer_total.Milliseconds(), - numPrimary, timer_pc.Milliseconds(), - numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(), - timer_lcp.Milliseconds(), timer_collision.Milliseconds() ); - } - else if ( af_showTimings.GetInteger() == 2 ) { - numArticulatedFigures++; - if ( endTimeMSec > lastTimerReset ) { - gameLocal.Printf( "af %d: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n", - numArticulatedFigures, - timer_total.Milliseconds(), - numPrimary, timer_pc.Milliseconds(), - numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(), - timer_lcp.Milliseconds(), timer_collision.Milliseconds() ); - } - } - - if ( endTimeMSec > lastTimerReset ) { - lastTimerReset = endTimeMSec; - numArticulatedFigures = 0; - timer_total.Clear(); - timer_pc.Clear(); - timer_ac.Clear(); - timer_collision.Clear(); - timer_lcp.Clear(); - } -#endif - - - // TDM: Disable the clipmodels that we enabled above - int count = 0; - - if( ((idAFEntity_Base *) self )->CollidesWithTeam() ) - { - for ( part = self->GetTeamMaster(); part != NULL; part = part->GetNextTeamEntity() ) - { - if ( part != self && part->GetPhysics() ) - { - if( !InitClipStates[count] ) - part->GetPhysics()->DisableClip(); - - count++; - } - } - } - - return true; -} - -/* -================ -idPhysics_AF::UpdateTime -================ -*/ -void idPhysics_AF::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_AF::GetTime -================ -*/ -int idPhysics_AF::GetTime( void ) const { - return gameLocal.time; -} - -/* -================ -DrawTraceModelSilhouette -================ -*/ -void DrawTraceModelSilhouette( const idVec3 &projectionOrigin, const idClipModel *clipModel ) { - int i, numSilEdges; - int silEdges[MAX_TRACEMODEL_EDGES]; - idVec3 v1, v2; - const idTraceModel *trm = clipModel->GetTraceModel(); - const idVec3 &origin = clipModel->GetOrigin(); - const idMat3 &axis = clipModel->GetAxis(); - - numSilEdges = trm->GetProjectionSilhouetteEdges( ( projectionOrigin - origin ) * axis.Transpose(), silEdges ); - for ( i = 0; i < numSilEdges; i++ ) { - v1 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INTSIGNBITSET( silEdges[i] ) ] ]; - v2 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INTSIGNBITNOTSET( silEdges[i] ) ] ]; - gameRenderWorld->DebugArrow( colorRed, origin + v1 * axis, origin + v2 * axis, 1 ); - } -} - -/* -================ -idPhysics_AF::DebugDraw -================ -*/ -void idPhysics_AF::DebugDraw( void ) { - int i; - idAFBody *body, *highlightBody = NULL, *constrainedBody1 = NULL, *constrainedBody2 = NULL; - idAFConstraint *constraint; - idVec3 center; - idMat3 axis; - - if ( af_highlightConstraint.GetString()[0] ) { - constraint = GetConstraint( af_highlightConstraint.GetString() ); - if ( constraint ) { - constraint->GetCenter( center ); - axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); - gameRenderWorld->DebugCone( colorYellow, center, (axis[2] - axis[1]) * 4.0f, 0.0f, 1.0f, 0 ); - - if ( af_showConstrainedBodies.GetBool() ) { - cvarSystem->SetCVarString( "cm_drawColor", colorCyan.ToString( 0 ) ); - constrainedBody1 = constraint->body1; - if ( constrainedBody1 ) { - collisionModelManager->DrawModel( constrainedBody1->clipModel->Handle(), constrainedBody1->clipModel->GetOrigin(), - constrainedBody1->clipModel->GetAxis(), vec3_origin, 0.0f ); - } - cvarSystem->SetCVarString( "cm_drawColor", colorBlue.ToString( 0 ) ); - constrainedBody2 = constraint->body2; - if ( constrainedBody2 ) { - collisionModelManager->DrawModel( constrainedBody2->clipModel->Handle(), constrainedBody2->clipModel->GetOrigin(), - constrainedBody2->clipModel->GetAxis(), vec3_origin, 0.0f ); - } - cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) ); - } - } - } - - if ( af_highlightBody.GetString()[0] ) { - highlightBody = GetBody( af_highlightBody.GetString() ); - if ( highlightBody ) { - cvarSystem->SetCVarString( "cm_drawColor", colorYellow.ToString( 0 ) ); - collisionModelManager->DrawModel( highlightBody->clipModel->Handle(), highlightBody->clipModel->GetOrigin(), - highlightBody->clipModel->GetAxis(), vec3_origin, 0.0f ); - cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) ); - } - } - - if ( af_showBodies.GetBool() ) { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - if ( body == constrainedBody1 || body == constrainedBody2 ) { - continue; - } - if ( body == highlightBody ) { - continue; - } - collisionModelManager->DrawModel( body->clipModel->Handle(), body->clipModel->GetOrigin(), - body->clipModel->GetAxis(), vec3_origin, 0.0f ); - //DrawTraceModelSilhouette( gameLocal.GetLocalPlayer()->GetEyePosition(), body->clipModel ); - } - } - - if ( af_showBodyNames.GetBool() ) { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - gameRenderWorld->DrawText( body->GetName().c_str(), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - } - - if ( af_showMass.GetBool() ) { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; -#ifdef MOD_WATERPHYSICS - if( body->GetWaterLevel() > 0.0f ) - gameRenderWorld->DrawText( va( "\n%1.2f", body->liquidMass ), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - else -#endif - gameRenderWorld->DrawText( va( "\n%1.2f", 1.0f / body->GetInverseMass() ), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - } - - if ( af_showTotalMass.GetBool() ) { - axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); -#ifdef MOD_WATERPHYSICS - gameRenderWorld->DrawText( va( "\n%1.2f", this->GetMass() ), bodies[0]->GetWorldOrigin() + axis[2] * 8.0f, 0.15f, colorCyan, axis, 1 ); -#else - gameRenderWorld->DrawText( va( "\n%1.2f", totalMass ), bodies[0]->GetWorldOrigin() + axis[2] * 8.0f, 0.15f, colorCyan, axis, 1 ); -#endif - } - - if ( af_showInertia.GetBool() ) { - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - idMat3 &I = body->inertiaTensor; - gameRenderWorld->DrawText( va( "\n\n\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )", - I[0].x, I[0].y, I[0].z, - I[1].x, I[1].y, I[1].z, - I[2].x, I[2].y, I[2].z ), - body->GetWorldOrigin(), 0.05f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - } - - if ( af_showVelocity.GetBool() ) { - for ( i = 0; i < bodies.Num(); i++ ) { - DrawVelocity( bodies[i]->clipModel->GetId(), 0.1f, 4.0f ); - } - } - - if ( af_showConstraints.GetBool() ) { - for ( i = 0; i < primaryConstraints.Num(); i++ ) { - constraint = primaryConstraints[i]; - constraint->DebugDraw(); - } - if ( !af_showPrimaryOnly.GetBool() ) { - for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - constraint->DebugDraw(); - } - } - } - - if ( af_showConstraintNames.GetBool() ) { - for ( i = 0; i < primaryConstraints.Num(); i++ ) { - constraint = primaryConstraints[i]; - constraint->GetCenter( center ); - gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - if ( !af_showPrimaryOnly.GetBool() ) { - for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) { - constraint = auxiliaryConstraints[i]; - constraint->GetCenter( center ); - gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - } - } - - if ( af_showTrees.GetBool() || ( af_showActive.GetBool() && current.atRest < 0 ) ) { - for ( i = 0; i < trees.Num(); i++ ) { - trees[i]->DebugDraw( idStr::ColorForIndex( i+3 ) ); - } - } -} - -/* -================ -idPhysics_AF::idPhysics_AF -================ -*/ -idPhysics_AF::idPhysics_AF( void ) { - trees.Clear(); - bodies.Clear(); - constraints.Clear(); - primaryConstraints.Clear(); - auxiliaryConstraints.Clear(); - frameConstraints.Clear(); - contacts.Clear(); - collisions.Clear(); - changedAF = true; - masterBody = NULL; - - lcp = idLCP::AllocSymmetric(); - - memset( ¤t, 0, sizeof( current ) ); - current.atRest = -1; - current.lastTimeStep = USERCMD_MSEC; - saved = current; - - linearFriction = 0.005f; - angularFriction = 0.005f; - contactFriction = 0.8f; - bouncyness = 0.4f; - totalMass = 0.0f; - forceTotalMass = -1.0f; - -#ifdef MOD_WATERPHYSICS - // sets default buoyancy property based on CVar - if( af_useFixedDensityBuoyancy.GetBool() ) { - this->fixedDensityBuoyancy = true; - this->liquidDensity = DEFAULT_LIQUID_DENSITY; - } - else { - this->fixedDensityBuoyancy = false; - this->liquidDensity = DEFAULT_LIQUID_SCALAR; - } - this->water = NULL; - this->m_fWaterMurkiness = 0.0f; -#endif - - suspendVelocity.Set( SUSPEND_LINEAR_VELOCITY, SUSPEND_ANGULAR_VELOCITY ); - suspendAcceleration.Set( SUSPEND_LINEAR_ACCELERATION, SUSPEND_LINEAR_ACCELERATION ); - noMoveTime = NO_MOVE_TIME; - noMoveTranslation = NO_MOVE_TRANSLATION_TOLERANCE; - noMoveRotation = NO_MOVE_ROTATION_TOLERANCE; - minMoveTime = MIN_MOVE_TIME; - maxMoveTime = MAX_MOVE_TIME; - impulseThreshold = IMPULSE_THRESHOLD; - - timeScale = 1.0f; - timeScaleRampStart = 0.0f; - timeScaleRampEnd = 0.0f; - - jointFrictionScale = 0.0f; - jointFrictionDent = 0.0f; - jointFrictionDentStart = 0.0f; - jointFrictionDentEnd = 0.0f; - jointFrictionDentScale = 0.0f; - - contactFrictionScale = 0.0f; - contactFrictionDent = 0.0f; - contactFrictionDentStart = 0.0f; - contactFrictionDentEnd = 0.0f; - contactFrictionDentScale = 0.0f; - - enableCollision = true; - selfCollision = true; - comeToRest = true; - linearTime = true; - noImpact = false; - worldConstraintsLocked = false; - forcePushable = false; - - // Init these to -1, if they are still -1 on save time, - // save just uses the actual numbers in the lists - m_NumOrigBodies = -1; - m_NumOrigConstraints = -1; - -#ifdef AF_TIMINGS - lastTimerReset = 0; -#endif -} - -/* -================ -idPhysics_AF::~idPhysics_AF -================ -*/ -idPhysics_AF::~idPhysics_AF( void ) { - int i; - - trees.DeleteContents( true ); - - for ( i = 0; i < bodies.Num(); i++ ) { - delete bodies[i]; - } - - for ( i = 0; i < constraints.Num(); i++ ) { - delete constraints[i]; - } - - contactConstraints.SetNum( contactConstraints.NumAllocated(), false ); - for ( i = 0; i < contactConstraints.NumAllocated(); i++ ) { - delete contactConstraints[i]; - } - - delete lcp; - - if ( masterBody ) { - delete masterBody; - } -} - -/* -================ -idPhysics_AF_SavePState -================ -*/ -void idPhysics_AF_SavePState( idSaveGame *saveFile, const AFPState_t &state ) { - saveFile->WriteInt( state.atRest ); - saveFile->WriteFloat( state.noMoveTime ); - saveFile->WriteFloat( state.activateTime ); - saveFile->WriteFloat( state.lastTimeStep ); - saveFile->WriteVec6( state.pushVelocity ); -} - -/* -================ -idPhysics_AF_RestorePState -================ -*/ -void idPhysics_AF_RestorePState( idRestoreGame *saveFile, AFPState_t &state ) { - saveFile->ReadInt( state.atRest ); - saveFile->ReadFloat( state.noMoveTime ); - saveFile->ReadFloat( state.activateTime ); - saveFile->ReadFloat( state.lastTimeStep ); - saveFile->ReadVec6( state.pushVelocity ); -} - -/* -================ -idPhysics_AF::Save -================ -*/ -void idPhysics_AF::Save( idSaveGame *saveFile ) const -{ - int i, num; - - // the articulated figure structure is handled by the owner - - idPhysics_AF_SavePState( saveFile, current ); - idPhysics_AF_SavePState( saveFile, saved ); - - if( m_NumOrigBodies < 0 ) - num = bodies.Num(); - else - num = m_NumOrigBodies; - - saveFile->WriteInt( num ); - for ( i = 0; i < num; i++ ) { - bodies[i]->Save( saveFile ); - } - if ( masterBody ) { - saveFile->WriteBool( true ); - masterBody->Save( saveFile ); - } else { - saveFile->WriteBool( false ); - } - - if( m_NumOrigConstraints < 0 ) - num = constraints.Num(); - else - num = m_NumOrigConstraints; - - saveFile->WriteInt( num ); - for ( i = 0; i < num; i++ ) { - constraints[i]->Save( saveFile ); - } - - saveFile->WriteBool( changedAF ); - - saveFile->WriteFloat( linearFriction ); - saveFile->WriteFloat( angularFriction ); - saveFile->WriteFloat( contactFriction ); - saveFile->WriteFloat( bouncyness ); - saveFile->WriteFloat( totalMass ); - saveFile->WriteFloat( forceTotalMass ); - -#ifdef MOD_WATERPHYSICS - saveFile->WriteBool( this->fixedDensityBuoyancy ); - saveFile->WriteFloat( this->liquidDensity ); -#endif - - saveFile->WriteVec2( suspendVelocity ); - saveFile->WriteVec2( suspendAcceleration ); - saveFile->WriteFloat( noMoveTime ); - saveFile->WriteFloat( noMoveTranslation ); - saveFile->WriteFloat( noMoveRotation ); - saveFile->WriteFloat( minMoveTime ); - saveFile->WriteFloat( maxMoveTime ); - saveFile->WriteFloat( impulseThreshold ); - - saveFile->WriteFloat( timeScale ); - saveFile->WriteFloat( timeScaleRampStart ); - saveFile->WriteFloat( timeScaleRampEnd ); - - saveFile->WriteFloat( jointFrictionScale ); - saveFile->WriteFloat( jointFrictionDent ); - saveFile->WriteFloat( jointFrictionDentStart ); - saveFile->WriteFloat( jointFrictionDentEnd ); - saveFile->WriteFloat( jointFrictionDentScale ); - - saveFile->WriteFloat( contactFrictionScale ); - saveFile->WriteFloat( contactFrictionDent ); - saveFile->WriteFloat( contactFrictionDentStart ); - saveFile->WriteFloat( contactFrictionDentEnd ); - saveFile->WriteFloat( contactFrictionDentScale ); - - saveFile->WriteBool( enableCollision ); - saveFile->WriteBool( selfCollision ); - saveFile->WriteBool( comeToRest ); - saveFile->WriteBool( linearTime ); - saveFile->WriteBool( noImpact ); - saveFile->WriteBool( worldConstraintsLocked ); - saveFile->WriteBool( forcePushable ); -} - -/* -================ -idPhysics_AF::Restore -================ -*/ -void idPhysics_AF::Restore( idRestoreGame *saveFile ) { - int i, num; - bool hasMaster; - - // the articulated figure structure should have already been restored - - idPhysics_AF_RestorePState( saveFile, current ); - idPhysics_AF_RestorePState( saveFile, saved ); - - saveFile->ReadInt( num ); - assert( num == bodies.Num() ); - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->Restore( saveFile ); - } - saveFile->ReadBool( hasMaster ); - if ( hasMaster ) { - masterBody = new idAFBody(); - masterBody->Restore( saveFile ); - } - - saveFile->ReadInt( num ); - assert( num == constraints.Num() ); - for ( i = 0; i < constraints.Num(); i++ ) { - constraints[i]->Restore( saveFile ); - } - - saveFile->ReadBool( changedAF ); - - saveFile->ReadFloat( linearFriction ); - saveFile->ReadFloat( angularFriction ); - saveFile->ReadFloat( contactFriction ); - saveFile->ReadFloat( bouncyness ); - saveFile->ReadFloat( totalMass ); - saveFile->ReadFloat( forceTotalMass ); - -#ifdef MOD_WATERPHYSICS - saveFile->ReadBool( this->fixedDensityBuoyancy ); - saveFile->ReadFloat( this->liquidDensity ); -#endif - - saveFile->ReadVec2( suspendVelocity ); - saveFile->ReadVec2( suspendAcceleration ); - saveFile->ReadFloat( noMoveTime ); - saveFile->ReadFloat( noMoveTranslation ); - saveFile->ReadFloat( noMoveRotation ); - saveFile->ReadFloat( minMoveTime ); - saveFile->ReadFloat( maxMoveTime ); - saveFile->ReadFloat( impulseThreshold ); - - saveFile->ReadFloat( timeScale ); - saveFile->ReadFloat( timeScaleRampStart ); - saveFile->ReadFloat( timeScaleRampEnd ); - - saveFile->ReadFloat( jointFrictionScale ); - saveFile->ReadFloat( jointFrictionDent ); - saveFile->ReadFloat( jointFrictionDentStart ); - saveFile->ReadFloat( jointFrictionDentEnd ); - saveFile->ReadFloat( jointFrictionDentScale ); - - saveFile->ReadFloat( contactFrictionScale ); - saveFile->ReadFloat( contactFrictionDent ); - saveFile->ReadFloat( contactFrictionDentStart ); - saveFile->ReadFloat( contactFrictionDentEnd ); - saveFile->ReadFloat( contactFrictionDentScale ); - - saveFile->ReadBool( enableCollision ); - saveFile->ReadBool( selfCollision ); - saveFile->ReadBool( comeToRest ); - saveFile->ReadBool( linearTime ); - saveFile->ReadBool( noImpact ); - saveFile->ReadBool( worldConstraintsLocked ); - saveFile->ReadBool( forcePushable ); - - changedAF = true; - - UpdateClipModels(); -} - -/* -================ -idPhysics_AF::IsClosedLoop -================ -*/ -bool idPhysics_AF::IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const { - const idAFBody *b1, *b2; - - for ( b1 = body1; b1->parent; b1 = b1->parent ) { - } - for ( b2 = body2; b2->parent; b2 = b2->parent ) { - } - return ( b1 == b2 ); -} - -/* -================ -idPhysics_AF::BuildTrees -================ -*/ -void idPhysics_AF::BuildTrees( void ) { - int i; - float scale; - idAFBody *b; - idAFConstraint *c; - idAFTree *tree; - - primaryConstraints.Clear(); - auxiliaryConstraints.Clear(); - trees.DeleteContents( true ); - - totalMass = 0.0f; - for ( i = 0; i < bodies.Num(); i++ ) { - b = bodies[i]; - b->parent = NULL; - b->primaryConstraint = NULL; - b->constraints.SetNum( 0, false ); - b->children.Clear(); - b->tree = NULL; - totalMass += b->mass; - } - - if ( forceTotalMass > 0.0f ) { - scale = forceTotalMass / totalMass; - for ( i = 0; i < bodies.Num(); i++ ) { - b = bodies[i]; - b->mass *= scale; - b->invMass = 1.0f / b->mass; - b->inertiaTensor *= scale; - b->inverseInertiaTensor = b->inertiaTensor.Inverse(); - } - totalMass = forceTotalMass; - } - - if ( af_useLinearTime.GetBool() ) { - - for ( i = 0; i < constraints.Num(); i++ ) { - c = constraints[i]; - - c->body1->constraints.Append( c ); - if ( c->body2 ) { - c->body2->constraints.Append( c ); - } - - // only bilateral constraints between two non-world bodies that do not - // create loops can be used as primary constraints - if ( !c->body1->primaryConstraint && c->fl.allowPrimary && c->body2 != NULL && !IsClosedLoop( c->body1, c->body2 ) ) { - c->body1->primaryConstraint = c; - c->body1->parent = c->body2; - c->body2->children.Append( c->body1 ); - c->fl.isPrimary = true; - c->firstIndex = 0; - primaryConstraints.Append( c ); - } else { - c->fl.isPrimary = false; - auxiliaryConstraints.Append( c ); - } - } - - // create trees for all parent bodies - for ( i = 0; i < bodies.Num(); i++ ) { - if ( !bodies[i]->parent ) { - tree = new idAFTree(); - tree->sortedBodies.Clear(); - tree->sortedBodies.Append( bodies[i] ); - bodies[i]->tree = tree; - trees.Append( tree ); - } - } - - // add each child body to the appropriate tree - for ( i = 0; i < bodies.Num(); i++ ) { - if ( bodies[i]->parent ) { - for ( b = bodies[i]->parent; !b->tree; b = b->parent ) { - } - b->tree->sortedBodies.Append( bodies[i] ); - bodies[i]->tree = b->tree; - } - } - - if ( trees.Num() > 1 ) { - gameLocal.Warning( "Articulated figure has multiple seperate tree structures for entity '%s' type '%s'.", - self->name.c_str(), self->GetType()->classname ); - } - - // sort bodies in each tree to make sure parents come first - for ( i = 0; i < trees.Num(); i++ ) { - trees[i]->SortBodies(); - } - - } else { - - // create a tree for each body - for ( i = 0; i < bodies.Num(); i++ ) { - tree = new idAFTree(); - tree->sortedBodies.Clear(); - tree->sortedBodies.Append( bodies[i] ); - bodies[i]->tree = tree; - trees.Append( tree ); - } - - for ( i = 0; i < constraints.Num(); i++ ) { - c = constraints[i]; - - c->body1->constraints.Append( c ); - if ( c->body2 ) { - c->body2->constraints.Append( c ); - } - - c->fl.isPrimary = false; - auxiliaryConstraints.Append( c ); - } - } -} - -/* -================ -idPhysics_AF::AddBody - - bodies get an id in the order they are added starting at zero - as such the first body added will get id zero -================ -*/ -int idPhysics_AF::AddBody( idAFBody *body ) { - int id = 0; - - if ( !body->clipModel ) { - gameLocal.Error( "idPhysics_AF::AddBody: body '%s' has no clip model.", body->name.c_str() ); - } - - if ( bodies.Find( body ) ) { - gameLocal.Error( "idPhysics_AF::AddBody: body '%s' added twice.", body->name.c_str() ); - } - - if ( GetBody( body->name ) ) { - gameLocal.Error( "idPhysics_AF::AddBody: a body with the name '%s' already exists.", body->name.c_str() ); - } - - id = bodies.Num(); - body->clipModel->SetId( id ); - if ( body->linearFriction < 0.0f ) { - body->linearFriction = linearFriction; - body->angularFriction = angularFriction; - body->contactFriction = contactFriction; - } - if ( body->bouncyness < 0.0f ) { - body->bouncyness = bouncyness; - } - if ( !body->fl.clipMaskSet ) { - body->clipMask = clipMask; - } - - bodies.Append( body ); - - changedAF = true; - - return id; -} - -/* -================ -idPhysics_AF::AddConstraint -================ -*/ -void idPhysics_AF::AddConstraint( idAFConstraint *constraint ) { - - if ( constraints.Find( constraint ) ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: constraint '%s' added twice.", constraint->name.c_str() ); - } - if ( GetConstraint( constraint->name ) ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: a constraint with the name '%s' already exists.", constraint->name.c_str() ); - } - if ( !constraint->body1 ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: body1 == NULL on constraint '%s'.", constraint->name.c_str() ); - } - if ( !bodies.Find( constraint->body1 ) ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: body1 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() ); - } - if ( constraint->body2 && !bodies.Find( constraint->body2 ) ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: body2 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() ); - } - if ( constraint->body1 == constraint->body2 ) { - gameLocal.Error( "idPhysics_AF::AddConstraint: body1 and body2 of constraint '%s' are the same.", constraint->name.c_str() ); - } - - constraints.Append( constraint ); - constraint->physics = this; - - changedAF = true; -} - -/* -================ -idPhysics_AF::AddFrameConstraint -================ -*/ -void idPhysics_AF::AddFrameConstraint( idAFConstraint *constraint ) { - frameConstraints.Append( constraint ); - constraint->physics = this; -} - -/* -================ -idPhysics_AF::ForceBodyId -================ -*/ -void idPhysics_AF::ForceBodyId( idAFBody *body, int newId ) { - int id; - - id = bodies.FindIndex( body ); - if ( id == -1 ) { - gameLocal.Error( "ForceBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() ); - } - if ( id != newId ) { - idAFBody *b = bodies[newId]; - bodies[newId] = bodies[id]; - bodies[id] = b; - changedAF = true; - } -} - -/* -================ -idPhysics_AF::GetBodyId -================ -*/ -int idPhysics_AF::GetBodyId( idAFBody *body ) const { - int id; - - id = bodies.FindIndex( body ); - if ( id == -1 && body ) { - gameLocal.Error( "GetBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() ); - } - return id; -} - -/* -================ -idPhysics_AF::GetBodyId -================ -*/ -int idPhysics_AF::GetBodyId( const char *bodyName ) const { - int i; - - for ( i = 0; i < bodies.Num(); i++ ) { - if ( !bodies[i]->name.Icmp( bodyName ) ) { - return i; - } - } - gameLocal.Error( "GetBodyId: no body with the name '%s' is not part of the articulated figure.\n", bodyName ); - return 0; -} - -/* -================ -idPhysics_AF::GetConstraintId -================ -*/ -int idPhysics_AF::GetConstraintId( idAFConstraint *constraint ) const { - int id; - - id = constraints.FindIndex( constraint ); - if ( id == -1 && constraint ) { - gameLocal.Error( "GetConstraintId: constraint '%s' is not part of the articulated figure.\n", constraint->name.c_str() ); - } - return id; -} - -/* -================ -idPhysics_AF::GetConstraintId -================ -*/ -int idPhysics_AF::GetConstraintId( const char *constraintName ) const { - int i; - - for ( i = 0; i < constraints.Num(); i++ ) { - if ( constraints[i]->name.Icmp( constraintName ) == 0 ) { - return i; - } - } - gameLocal.Error( "GetConstraintId: no constraint with the name '%s' is not part of the articulated figure.\n", constraintName ); - return 0; -} - -/* -================ -idPhysics_AF::GetNumBodies -================ -*/ -int idPhysics_AF::GetNumBodies( void ) const { - return bodies.Num(); -} - -/* -================ -idPhysics_AF::GetNumConstraints -================ -*/ -int idPhysics_AF::GetNumConstraints( void ) const { - return constraints.Num(); -} - -/* -================ -idPhysics_AF::GetBody -================ -*/ -idAFBody *idPhysics_AF::GetBody( const char *bodyName ) const { - int i; - - for ( i = 0; i < bodies.Num(); i++ ) { - if ( !bodies[i]->name.Icmp( bodyName ) ) { - return bodies[i]; - } - } - - return NULL; -} - -/* -================ -idPhysics_AF::GetBody -================ -*/ -idAFBody *idPhysics_AF::GetBody( const int id ) const { - if ( id < 0 || id >= bodies.Num() ) { - gameLocal.Error( "GetBody: no body with id %d exists on ent %s\n", id, self->name.c_str() ); - return NULL; - } - return bodies[id]; -} - -/* -================ -idPhysics_AF::GetConstraint -================ -*/ -idAFConstraint *idPhysics_AF::GetConstraint( const char *constraintName ) const { - int i; - - for ( i = 0; i < constraints.Num(); i++ ) { - if ( constraints[i]->name.Icmp( constraintName ) == 0 ) { - return constraints[i]; - } - } - - return NULL; -} - -/* -================ -idPhysics_AF::GetConstraint -================ -*/ -idAFConstraint *idPhysics_AF::GetConstraint( const int id ) const { - if ( id < 0 || id >= constraints.Num() ) { - gameLocal.Error( "GetConstraint: no constraint with id %d exists\n", id ); - return NULL; - } - return constraints[id]; -} - -/* -================ -idPhysics_AF::DeleteBody -================ -*/ -void idPhysics_AF::DeleteBody( const char *bodyName ) { - int i; - - // find the body with the given name - for ( i = 0; i < bodies.Num(); i++ ) { - if ( !bodies[i]->name.Icmp( bodyName ) ) { - break; - } - } - - if ( i >= bodies.Num() ) { - gameLocal.Warning( "DeleteBody: no body found in the articulated figure with the name '%s' for entity '%s' type '%s'.", - bodyName, self->name.c_str(), self->GetType()->classname ); - return; - } - - DeleteBody( i ); -} - -/* -================ -idPhysics_AF::DeleteBody -================ -*/ -void idPhysics_AF::DeleteBody( const int id ) { - int j; - - if ( id < 0 || id > bodies.Num() ) { - gameLocal.Error( "DeleteBody: no body with id %d.", id ); - return; - } - - // remove any constraints attached to this body - for ( j = 0; j < constraints.Num(); j++ ) { - if ( constraints[j]->body1 == bodies[id] || constraints[j]->body2 == bodies[id] ) { - delete constraints[j]; - constraints.RemoveIndex( j ); - j--; - } - } - - // remove the body - delete bodies[id]; - bodies.RemoveIndex( id ); - - // set new body ids - for ( j = 0; j < bodies.Num(); j++ ) { - bodies[j]->clipModel->SetId( j ); - } - - changedAF = true; -} - -/* -================ -idPhysics_AF::DeleteConstraint -================ -*/ -void idPhysics_AF::DeleteConstraint( const char *constraintName ) { - int i; - - // find the constraint with the given name - for ( i = 0; i < constraints.Num(); i++ ) { - if ( !constraints[i]->name.Icmp( constraintName ) ) { - break; - } - } - - if ( i >= constraints.Num() ) { - gameLocal.Warning( "DeleteConstraint: no constriant found in the articulated figure with the name '%s' for entity '%s' type '%s'.", - constraintName, self->name.c_str(), self->GetType()->classname ); - return; - } - - DeleteConstraint( i ); -} - -/* -================ -idPhysics_AF::DeleteConstraint -================ -*/ -void idPhysics_AF::DeleteConstraint( const int id ) { - - if ( id < 0 || id >= constraints.Num() ) { - gameLocal.Error( "DeleteConstraint: no constraint with id %d.", id ); - return; - } - - // remove the constraint - delete constraints[id]; - constraints.RemoveIndex( id ); - - changedAF = true; -} - -/* -================ -idPhysics_AF::GetBodyContactConstraints -================ -*/ -int idPhysics_AF::GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const { - int i, numContacts; - idAFBody *body; - idAFConstraint_Contact *contact; - - if ( id < 0 || id >= bodies.Num() || maxContacts <= 0 ) { - return 0; - } - - numContacts = 0; - body = bodies[id]; - for ( i = 0; i < contactConstraints.Num(); i++ ) { - contact = contactConstraints[i]; - if ( contact->body1 == body || contact->body2 == body ) { - contacts[numContacts++] = contact; - if ( numContacts >= maxContacts ) { - return numContacts; - } - } - } - return numContacts; -} - -/* -================ -idPhysics_AF::SetDefaultFriction -================ -*/ -void idPhysics_AF::SetDefaultFriction( float linear, float angular, float contact ) { - if ( linear < 0.0f || linear > 1.0f || - angular < 0.0f || angular > 1.0f || - contact < 0.0f || contact > 1.0f ) { - return; - } - linearFriction = linear; - angularFriction = angular; - contactFriction = contact; -} - -/* -================ -idPhysics_AF::GetImpactInfo -================ -*/ -void idPhysics_AF::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - if ( id < 0 || id >= bodies.Num() ) { - memset( info, 0, sizeof( *info ) ); - return; - } -#ifdef MOD_WATERPHYSICS - if( this->water != NULL ) - info->invMass = bodies[id]->invLiquidMass; - else - info->invMass = bodies[id]->invMass; -#else - info->invMass = 1.0f / bodies[id]->mass; -#endif - info->invInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis; - info->position = point - bodies[id]->current->worldOrigin; - info->velocity = bodies[id]->current->spatialVelocity.SubVec3(0) + bodies[id]->current->spatialVelocity.SubVec3(1).Cross( info->position ); -} - -/* -================ -idPhysics_AF::ApplyImpulse -================ -*/ -void idPhysics_AF::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - - if ( id < 0 || id >= bodies.Num() ) { - return; - } - if ( noImpact || impulse.LengthSqr() < Square( impulseThreshold ) ) { - return; - } - idMat3 invWorldInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis; -#ifdef MOD_WATERPHYSICS - if( this->water != NULL ) - bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invLiquidMass * impulse; - else - bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invMass * impulse; -#else - bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invMass * impulse; -#endif - bodies[id]->current->spatialVelocity.SubVec3(1) += invWorldInertiaTensor * (point - bodies[id]->current->worldOrigin).Cross( impulse ); - Activate(); -} - -/* -================ -idPhysics_AF::AddForce -================ -*/ -void idPhysics_AF::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { - if ( noImpact ) { - return; - } - if ( id < 0 || id >= bodies.Num() ) { - return; - } - bodies[id]->current->externalForce.SubVec3( 0 ) += force; - bodies[id]->current->externalForce.SubVec3( 1 ) += (point - bodies[id]->current->worldOrigin).Cross( force ); - Activate(); -} - -/* -================ -idPhysics_AF::IsAtRest -================ -*/ -bool idPhysics_AF::IsAtRest( void ) const { - return current.atRest >= 0; -} - -/* -================ -idPhysics_AF::GetRestStartTime -================ -*/ -int idPhysics_AF::GetRestStartTime( void ) const { - return current.atRest; -} - -/* -================ -idPhysics_AF::IsPushable -================ -*/ -bool idPhysics_AF::IsPushable( void ) const { - return ( !noImpact && ( masterBody == NULL || forcePushable ) ); -} - -/* -================ -idPhysics_AF::SaveState -================ -*/ -void idPhysics_AF::SaveState( void ) { - int i; - - saved = current; - - for ( i = 0; i < bodies.Num(); i++ ) { - memcpy( &bodies[i]->saved, bodies[i]->current, sizeof( AFBodyPState_t ) ); - } -} - -/* -================ -idPhysics_AF::RestoreState -================ -*/ -void idPhysics_AF::RestoreState( void ) { - int i; - - current = saved; - - for ( i = 0; i < bodies.Num(); i++ ) { - *(bodies[i]->current) = bodies[i]->saved; - } - - EvaluateContacts(); -} - -/* -================ -idPhysics_AF::SetOrigin -================ -*/ -void idPhysics_AF::SetOrigin( const idVec3 &newOrigin, int id ) { - if ( masterBody ) { - Translate( masterBody->current->worldOrigin + masterBody->current->worldAxis * newOrigin - bodies[0]->current->worldOrigin ); - } else { - Translate( newOrigin - bodies[0]->current->worldOrigin ); - } -} - -/* -================ -idPhysics_AF::SetAxis -================ -*/ -void idPhysics_AF::SetAxis( const idMat3 &newAxis, int id ) { - idMat3 axis; - idRotation rotation; - - if ( masterBody ) { - axis = bodies[0]->current->worldAxis.Transpose() * ( newAxis * masterBody->current->worldAxis ); - } else { - axis = bodies[0]->current->worldAxis.Transpose() * newAxis; - } - rotation = axis.ToRotation(); - rotation.SetOrigin( bodies[0]->current->worldOrigin ); - - Rotate( rotation ); -} - -/* -================ -idPhysics_AF::Translate -================ -*/ -void idPhysics_AF::Translate( const idVec3 &translation, int id ) { - int i; - idAFBody *body; - - if ( !worldConstraintsLocked ) { - // translate constraints attached to the world - for ( i = 0; i < constraints.Num(); i++ ) { - constraints[i]->Translate( translation ); - } - } - - // translate all the bodies - for ( i = 0; i < bodies.Num(); i++ ) { - - body = bodies[i]; - body->current->worldOrigin += translation; - } - - Activate(); - - UpdateClipModels(); -} - -/* -================ -idPhysics_AF::Rotate -================ -*/ -void idPhysics_AF::Rotate( const idRotation &rotation, int id ) { - int i; - idAFBody *body; - - // ishtvan: Stop the stretching error due to too many - // mat3 to rotation to mat3 conversions - idRotation rotationC = rotation; - rotationC.ReCalculateMatrix(); - - if ( !worldConstraintsLocked ) { - // rotate constraints attached to the world - for ( i = 0; i < constraints.Num(); i++ ) { - constraints[i]->Rotate( rotationC ); - } - } - - // rotate all the bodies - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - body->current->worldOrigin *= rotationC; - body->current->worldAxis *= rotationC.ToMat3(); - } - - Activate(); - - UpdateClipModels(); -} - -/* -================ -idPhysics_AF::GetOrigin -================ -*/ -const idVec3 &idPhysics_AF::GetOrigin( int id ) const { - if ( id < 0 || id >= bodies.Num() ) { - return vec3_origin; - } - else { - return bodies[id]->current->worldOrigin; - } -} - -/* -================ -idPhysics_AF::GetAxis -================ -*/ -const idMat3 &idPhysics_AF::GetAxis( int id ) const { - if ( id < 0 || id >= bodies.Num() ) { - return mat3_identity; - } - else { - return bodies[id]->current->worldAxis; - } -} - -/* -================ -idPhysics_AF::SetLinearVelocity -================ -*/ -void idPhysics_AF::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { - if ( id < 0 || id >= bodies.Num() ) { - return; - } - bodies[id]->current->spatialVelocity.SubVec3( 0 ) = newLinearVelocity; - Activate(); -} - -/* -================ -idPhysics_AF::SetAngularVelocity -================ -*/ -void idPhysics_AF::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { - if ( id < 0 || id >= bodies.Num() ) { - return; - } - bodies[id]->current->spatialVelocity.SubVec3( 1 ) = newAngularVelocity; - Activate(); -} - -/* -================ -idPhysics_AF::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_AF::GetLinearVelocity( int id ) const { - if ( id < 0 || id >= bodies.Num() ) { - return vec3_origin; - } - else { - return bodies[id]->current->spatialVelocity.SubVec3( 0 ); - } -} - -/* -================ -idPhysics_AF::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_AF::GetAngularVelocity( int id ) const { - if ( id < 0 || id >= bodies.Num() ) { - return vec3_origin; - } - else { - return bodies[id]->current->spatialVelocity.SubVec3( 1 ); - } -} - -/* -================ -idPhysics_AF::ClipTranslation -================ -*/ -void idPhysics_AF::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - int i; - idAFBody *body; - trace_t bodyResults; - - results.fraction = 1.0f; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->clipModel->IsTraceModel() ) { - if ( model ) { - gameLocal.clip.TranslationModel( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation, - body->clipModel, body->current->worldAxis, body->clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Translation( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation, - body->clipModel, body->current->worldAxis, body->clipMask, self ); - } - if ( bodyResults.fraction < results.fraction ) { - results = bodyResults; - } - } - } - - results.endpos = bodies[0]->current->worldOrigin + results.fraction * translation; - results.endAxis = bodies[0]->current->worldAxis; -} - -/* -================ -idPhysics_AF::ClipRotation -================ -*/ -void idPhysics_AF::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - int i; - idAFBody *body; - trace_t bodyResults; - idRotation partialRotation; - - results.fraction = 1.0f; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->clipModel->IsTraceModel() ) { - if ( model ) { - gameLocal.clip.RotationModel( bodyResults, body->current->worldOrigin, rotation, - body->clipModel, body->current->worldAxis, body->clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Rotation( bodyResults, body->current->worldOrigin, rotation, - body->clipModel, body->current->worldAxis, body->clipMask, self ); - } - if ( bodyResults.fraction < results.fraction ) { - results = bodyResults; - } - } - } - - partialRotation = rotation * results.fraction; - results.endpos = bodies[0]->current->worldOrigin * partialRotation; - results.endAxis = bodies[0]->current->worldAxis * partialRotation.ToMat3(); -} - -/* -================ -idPhysics_AF::ClipContents -================ -*/ -int idPhysics_AF::ClipContents( const idClipModel *model ) const { - int i, contents; - idAFBody *body; - - contents = 0; - - for ( i = 0; i < bodies.Num(); i++ ) { - body = bodies[i]; - - if ( body->clipModel->IsTraceModel() ) { - if ( model ) { - contents |= gameLocal.clip.ContentsModel( body->current->worldOrigin, - body->clipModel, body->current->worldAxis, -1, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - contents |= gameLocal.clip.Contents( body->current->worldOrigin, - body->clipModel, body->current->worldAxis, -1, NULL ); - } - } - } - - return contents; -} - -/* -================ -idPhysics_AF::DisableClip -================ -*/ -void idPhysics_AF::DisableClip( void ) { - int i; - - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->clipModel->Disable(); - } -} - -/* -================ -idPhysics_AF::EnableClip -================ -*/ -void idPhysics_AF::EnableClip( void ) { - int i; - - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->clipModel->Enable(); - } -} - -/* -================ -idPhysics_AF::UnlinkClip -================ -*/ -void idPhysics_AF::UnlinkClip( void ) { - int i; - - for ( i = 0; i < bodies.Num(); i++ ) { - bodies[i]->clipModel->Unlink(); - } -} - -/* -================ -idPhysics_AF::LinkClip -================ -*/ -void idPhysics_AF::LinkClip( void ) { - UpdateClipModels(); -} - -/* -================ -idPhysics_AF::SetPushed -================ -*/ -void idPhysics_AF::SetPushed( int deltaTime ) { - idAFBody *body; - idRotation rotation; - - if ( bodies.Num() ) { - body = bodies[0]; - rotation = ( body->saved.worldAxis.Transpose() * body->current->worldAxis ).ToRotation(); - - // velocity with which the af is pushed - current.pushVelocity.SubVec3(0) += ( body->current->worldOrigin - body->saved.worldOrigin ) / ( deltaTime * idMath::M_MS2SEC ); - current.pushVelocity.SubVec3(1) += rotation.GetVec() * -DEG2RAD( rotation.GetAngle() ) / ( deltaTime * idMath::M_MS2SEC ); - } -} - -/* -================ -idPhysics_AF::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_AF::GetPushedLinearVelocity( const int id ) const { - return current.pushVelocity.SubVec3(0); -} - -/* -================ -idPhysics_AF::GetPushedAngularVelocity -================ -*/ -const idVec3 &idPhysics_AF::GetPushedAngularVelocity( const int id ) const { - return current.pushVelocity.SubVec3(1); -} - -/* -================ -idPhysics_AF::SetMaster - - the binding is orientated based on the constraints being used -================ -*/ -void idPhysics_AF::SetMaster( idEntity *master, const bool orientated ) { - int i; - idVec3 masterOrigin; - idMat3 masterAxis; - idRotation rotation; - - if ( master ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - if ( !masterBody ) { - masterBody = new idAFBody(); - // translate and rotate all the constraints with body2 == NULL from world space to master space - rotation = masterAxis.Transpose().ToRotation(); - for ( i = 0; i < constraints.Num(); i++ ) { - if ( constraints[i]->GetBody2() == NULL ) { - constraints[i]->Translate( -masterOrigin ); - constraints[i]->Rotate( rotation ); - } - } - Activate(); - } - masterBody->current->worldOrigin = masterOrigin; - masterBody->current->worldAxis = masterAxis; - } - else { - if ( masterBody ) { - // translate and rotate all the constraints with body2 == NULL from master space to world space - rotation = masterBody->current->worldAxis.ToRotation(); - for ( i = 0; i < constraints.Num(); i++ ) { - if ( constraints[i]->GetBody2() == NULL ) { - constraints[i]->Rotate( rotation ); - constraints[i]->Translate( masterBody->current->worldOrigin ); - } - } - delete masterBody; - masterBody = NULL; - Activate(); - } - } -} - - -const float AF_VELOCITY_MAX = 16000; -const int AF_VELOCITY_TOTAL_BITS = 16; -const int AF_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_VELOCITY_MAX ) ) + 1; -const int AF_VELOCITY_MANTISSA_BITS = AF_VELOCITY_TOTAL_BITS - 1 - AF_VELOCITY_EXPONENT_BITS; -const float AF_FORCE_MAX = 1e20f; -const int AF_FORCE_TOTAL_BITS = 16; -const int AF_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_FORCE_MAX ) ) + 1; -const int AF_FORCE_MANTISSA_BITS = AF_FORCE_TOTAL_BITS - 1 - AF_FORCE_EXPONENT_BITS; - -/* -================ -idPhysics_AF::WriteToSnapshot -================ -*/ -void idPhysics_AF::WriteToSnapshot( idBitMsgDelta &msg ) const { - int i; - idCQuat quat; - - msg.WriteLong( current.atRest ); - msg.WriteFloat( current.noMoveTime ); - msg.WriteFloat( current.activateTime ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - - msg.WriteByte( bodies.Num() ); - - for ( i = 0; i < bodies.Num(); i++ ) { - AFBodyPState_t *state = bodies[i]->current; - quat = state->worldAxis.ToCQuat(); - - msg.WriteFloat( state->worldOrigin[0] ); - msg.WriteFloat( state->worldOrigin[1] ); - msg.WriteFloat( state->worldOrigin[2] ); - msg.WriteFloat( quat.x ); - msg.WriteFloat( quat.y ); - msg.WriteFloat( quat.z ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); -/* msg.WriteDeltaFloat( 0.0f, state->externalForce[0], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->externalForce[1], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->externalForce[2], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->externalForce[3], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->externalForce[4], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, state->externalForce[5], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); -*/ - } -} - -/* -================ -idPhysics_AF::ReadFromSnapshot -================ -*/ -void idPhysics_AF::ReadFromSnapshot( const idBitMsgDelta &msg ) { - int i, num; - idCQuat quat; - - current.atRest = msg.ReadLong(); - current.noMoveTime = msg.ReadFloat(); - current.activateTime = msg.ReadFloat(); - current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - - num = msg.ReadByte(); - assert( num == bodies.Num() ); - - for ( i = 0; i < bodies.Num(); i++ ) { - AFBodyPState_t *state = bodies[i]->current; - - state->worldOrigin[0] = msg.ReadFloat(); - state->worldOrigin[1] = msg.ReadFloat(); - state->worldOrigin[2] = msg.ReadFloat(); - quat.x = msg.ReadFloat(); - quat.y = msg.ReadFloat(); - quat.z = msg.ReadFloat(); - state->spatialVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - state->spatialVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - state->spatialVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - state->spatialVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - state->spatialVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); - state->spatialVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS ); -/* state->externalForce[0] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - state->externalForce[1] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - state->externalForce[2] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - state->externalForce[3] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - state->externalForce[4] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); - state->externalForce[5] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS ); -*/ - state->worldAxis = quat.ToMat3(); - } - - UpdateClipModels(); -} -/* -================ -idPhysics_AF::NearestBodyOrig - -Linear search to find the body origin nearest to the given point -================ -*/ -idVec3 idPhysics_AF::NearestBodyOrig( idVec3 point, int *bodyID ) -{ - idVec3 bodyOrigin, delta, returnVec; - float tempDist; - float minDist = idMath::INFINITY; - int numBods(0), returnBody(-1); - - // return (0,0,0) if something unexpected happens - returnVec.Zero(); - - numBods = GetNumBodies(); - for( int i = 0; i < numBods; i++ ) - { - if( GetBody( i ) ) - { - bodyOrigin = GetBody( i )->GetWorldOrigin(); - delta = bodyOrigin - point; - - tempDist = delta.LengthSqr(); - if (tempDist < minDist) - { - minDist = tempDist; - returnVec = bodyOrigin; - returnBody = i; - } - } - } - - if( bodyID ) - *bodyID = returnBody; - - return returnVec; -} - -bool idPhysics_AF::HasGroundContacts( int id ) -{ - int numContacts; - idAFConstraint_Contact *contacts[5]; - bool bReturnVal(false); - idEntity *contactEnt(NULL); - - numContacts = GetBodyContactConstraints( id, contacts, 5 ); - - for ( int i = 0; i < numContacts; i++ ) - { - contactEnt = gameLocal.entities[ contacts[i]->GetContact().entityNum ]; - - if( contacts[i]->GetContact().normal * -gravityNormal > 0.0f - && contactEnt && contactEnt != self ) - { - bReturnVal = true; - goto Quit; - } - } - -Quit: - return bReturnVal; -} - -#ifdef MOD_WATERPHYSICS -/* -================ -idPhysics_AF::SetLiquidDensity -================ -*/ -void idPhysics_AF::SetLiquidDensity( float density ) -{ - this->liquidDensity = density; -} - -/* -================ -idPhysics_AF::GetLiquidDensity -================ -*/ -float idPhysics_AF::GetLiquidDensity() const -{ - return this->liquidDensity; -} - -/* -================ -idPhysics_AF::SetFixedDensityBuoyancy - This will reset the liquid density to the default value depending on the mode. -================ -*/ -void idPhysics_AF::SetFixedDensityBuoyancy( bool fixed ) -{ - this->fixedDensityBuoyancy = fixed; - if( this->fixedDensityBuoyancy ) - this->liquidDensity = DEFAULT_LIQUID_DENSITY; - else - this->liquidDensity = DEFAULT_LIQUID_SCALAR; -} - -/* -================ -idPhysics_AF::GetFixedDensityBuoyancy -================ -*/ -bool idPhysics_AF::GetFixedDensityBuoyancy() const -{ - return this->fixedDensityBuoyancy; -} -#endif diff --git a/game/physics/physics_af.h b/game/physics/physics_af.h deleted file mode 100644 index ab9cda06b..000000000 --- a/game/physics/physics_af.h +++ /dev/null @@ -1,1111 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_AF_H__ -#define __PHYSICS_AF_H__ - -/* -=================================================================================== - - Articulated Figure physics - - Employs a constraint force based dynamic simulation using a lagrangian - multiplier method to solve for the constraint forces. - -=================================================================================== -*/ - -class idAFConstraint; -class idAFConstraint_Fixed; -class idAFConstraint_BallAndSocketJoint; -class idAFConstraint_BallAndSocketJointFriction; -class idAFConstraint_UniversalJoint; -class idAFConstraint_UniversalJointFriction; -class idAFConstraint_CylindricalJoint; -class idAFConstraint_Hinge; -class idAFConstraint_HingeFriction; -class idAFConstraint_HingeSteering; -class idAFConstraint_Slider; -class idAFConstraint_Line; -class idAFConstraint_Plane; -class idAFConstraint_Spring; -class idAFConstraint_Contact; -class idAFConstraint_ContactFriction; -class idAFConstraint_ConeLimit; -class idAFConstraint_PyramidLimit; -class idAFConstraint_Suspension; -class idAFBody; -class idAFTree; -class idPhysics_AF; - -typedef enum { - CONSTRAINT_INVALID, - CONSTRAINT_FIXED, - CONSTRAINT_BALLANDSOCKETJOINT, - CONSTRAINT_UNIVERSALJOINT, - CONSTRAINT_HINGE, - CONSTRAINT_HINGESTEERING, - CONSTRAINT_SLIDER, - CONSTRAINT_CYLINDRICALJOINT, - CONSTRAINT_LINE, - CONSTRAINT_PLANE, - CONSTRAINT_SPRING, - CONSTRAINT_CONTACT, - CONSTRAINT_FRICTION, - CONSTRAINT_CONELIMIT, - CONSTRAINT_PYRAMIDLIMIT, - CONSTRAINT_SUSPENSION -} constraintType_t; - - -//=============================================================== -// -// idAFConstraint -// -//=============================================================== - -// base class for all constraints -class idAFConstraint { - - friend class idPhysics_AF; - friend class idAFTree; - -public: - idAFConstraint( void ); - virtual ~idAFConstraint( void ); - constraintType_t GetType( void ) const { return type; } - const idStr & GetName( void ) const { return name; } - idAFBody * GetBody1( void ) const { return body1; } - idAFBody * GetBody2( void ) const { return body2; } - void SetPhysics( idPhysics_AF *p ) { physics = p; } - const idVecX & GetMultiplier( void ); - virtual void SetBody1( idAFBody *body ); - virtual void SetBody2( idAFBody *body ); - virtual void DebugDraw( void ); - virtual void GetForce( idAFBody *body, idVec6 &force ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - constraintType_t type; // constraint type - idStr name; // name of constraint - idAFBody * body1; // first constrained body - idAFBody * body2; // second constrained body, NULL for world - idPhysics_AF * physics; // for adding additional constraints like limits - - // simulation variables set by Evaluate - idMatX J1, J2; // matrix with left hand side of constraint equations - idVecX c1, c2; // right hand side of constraint equations - idVecX lo, hi, e; // low and high bounds and lcp epsilon - idAFConstraint * boxConstraint; // constraint the boxIndex refers to - int boxIndex[6]; // indexes for special box constrained variables - - // simulation variables used during calculations - idMatX invI; // transformed inertia - idMatX J; // transformed constraint matrix - idVecX s; // temp solution - idVecX lm; // lagrange multipliers - int firstIndex; // index of the first constraint row in the lcp matrix - - struct constraintFlags_s { - bool allowPrimary : 1; // true if the constraint can be used as a primary constraint - bool frameConstraint : 1; // true if this constraint is added to the frame constraints - bool noCollision : 1; // true if body1 and body2 never collide with each other - bool isPrimary : 1; // true if this is a primary constraint - bool isZero : 1; // true if 's' is zero during calculations - } fl; - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); - void InitSize( int size ); -}; - -// fixed or rigid joint which allows zero degrees of freedom -// constrains body1 to have a fixed position and orientation relative to body2 -class idAFConstraint_Fixed : public idAFConstraint { - -public: - idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 ); - void SetRelativeOrigin( const idVec3 &origin ) { this->offset = origin; } - void SetRelativeAxis( const idMat3 &axis ) { this->relAxis = axis; } - virtual void SetBody1( idAFBody *body ); - virtual void SetBody2( idAFBody *body ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 offset; // offset of body1 relative to body2 in body2 space - idMat3 relAxis; // rotation of body1 relative to body2 - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); - void InitOffset( void ); -}; - -// ball and socket or spherical joint which allows 3 degrees of freedom -// constrains body1 relative to body2 with a ball and socket joint -class idAFConstraint_BallAndSocketJoint : public idAFConstraint { - -public: - idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); - ~idAFConstraint_BallAndSocketJoint( void ); - void SetAnchor( const idVec3 &worldPosition ); - idVec3 GetAnchor( void ) const; - void SetNoLimit( void ); - void SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ); - void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float angle1, const float angle2, const idVec3 &body1Axis ); - void SetLimitEpsilon( const float e ); - void SetFriction( const float f ) { friction = f; } - float GetFriction( void ) const; - virtual void DebugDraw( void ); - virtual void GetForce( idAFBody *body, idVec6 &force ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 anchor1; // anchor in body1 space - idVec3 anchor2; // anchor in body2 space - float friction; // joint friction - idAFConstraint_ConeLimit *coneLimit; // cone shaped limit - idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit - idAFConstraint_BallAndSocketJointFriction *fc; // friction constraint - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// ball and socket joint friction -class idAFConstraint_BallAndSocketJointFriction : public idAFConstraint { - -public: - idAFConstraint_BallAndSocketJointFriction( void ); - void Setup( idAFConstraint_BallAndSocketJoint *cc ); - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - idAFConstraint_BallAndSocketJoint *joint; - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// universal, Cardan or Hooke joint which allows 2 degrees of freedom -// like a ball and socket joint but also constrains the rotation about the cardan shafts -class idAFConstraint_UniversalJoint : public idAFConstraint { - -public: - idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); - ~idAFConstraint_UniversalJoint( void ); - void SetAnchor( const idVec3 &worldPosition ); - idVec3 GetAnchor( void ) const; - void SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 ); - void GetShafts( idVec3 &cardanShaft1, idVec3 &cardanShaft2 ) { cardanShaft1 = shaft1; cardanShaft2 = shaft2; } - void SetNoLimit( void ); - void SetConeLimit( const idVec3 &coneAxis, const float coneAngle ); - void SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float angle1, const float angle2 ); - void SetLimitEpsilon( const float e ); - void SetFriction( const float f ) { friction = f; } - float GetFriction( void ) const; - virtual void DebugDraw( void ); - virtual void GetForce( idAFBody *body, idVec6 &force ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 anchor1; // anchor in body1 space - idVec3 anchor2; // anchor in body2 space - idVec3 shaft1; // body1 cardan shaft in body1 space - idVec3 shaft2; // body2 cardan shaft in body2 space - idVec3 axis1; // cardan axis in body1 space - idVec3 axis2; // cardan axis in body2 space - float friction; // joint friction - idAFConstraint_ConeLimit *coneLimit; // cone shaped limit - idAFConstraint_PyramidLimit *pyramidLimit; // pyramid shaped limit - idAFConstraint_UniversalJointFriction *fc; // friction constraint - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// universal joint friction -class idAFConstraint_UniversalJointFriction : public idAFConstraint { - -public: - idAFConstraint_UniversalJointFriction( void ); - void Setup( idAFConstraint_UniversalJoint *cc ); - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - idAFConstraint_UniversalJoint *joint; // universal joint - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// cylindrical joint which allows 2 degrees of freedom -// constrains body1 to lie on a line relative to body2 and allows only translation along and rotation about the line -class idAFConstraint_CylindricalJoint : public idAFConstraint { - -public: - idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// hinge, revolute or pin joint which allows 1 degree of freedom -// constrains all motion of body1 relative to body2 except the rotation about the hinge axis -class idAFConstraint_Hinge : public idAFConstraint { - -public: - idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 ); - ~idAFConstraint_Hinge( void ); - void SetAnchor( const idVec3 &worldPosition ); - idVec3 GetAnchor( void ) const; - void SetAxis( const idVec3 &axis ); - void GetAxis( idVec3 &a1, idVec3 &a2 ) const { a1 = axis1; a2 = axis2; } - idVec3 GetAxis( void ) const; - void SetNoLimit( void ); - void SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis ); - void SetLimitEpsilon( const float e ); - float GetAngle( void ) const; - void SetSteerAngle( const float degrees ); - void SetSteerSpeed( const float speed ); - void SetFriction( const float f ) { friction = f; } - float GetFriction( void ) const; - virtual void DebugDraw( void ); - virtual void GetForce( idAFBody *body, idVec6 &force ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 anchor1; // anchor in body1 space - idVec3 anchor2; // anchor in body2 space - idVec3 axis1; // axis in body1 space - idVec3 axis2; // axis in body2 space - idMat3 initialAxis; // initial axis of body1 relative to body2 - float friction; // hinge friction - idAFConstraint_ConeLimit *coneLimit; // cone limit - idAFConstraint_HingeSteering *steering; // steering - idAFConstraint_HingeFriction *fc; // friction constraint - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// hinge joint friction -class idAFConstraint_HingeFriction : public idAFConstraint { - -public: - idAFConstraint_HingeFriction( void ); - void Setup( idAFConstraint_Hinge *cc ); - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - idAFConstraint_Hinge * hinge; // hinge - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// constrains two bodies attached to each other with a hinge to get a specified relative orientation -class idAFConstraint_HingeSteering : public idAFConstraint { - -public: - idAFConstraint_HingeSteering( void ); - void Setup( idAFConstraint_Hinge *cc ); - void SetSteerAngle( const float degrees ) { steerAngle = degrees; } - void SetSteerSpeed( const float speed ) { steerSpeed = speed; } - void SetEpsilon( const float e ) { epsilon = e; } - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idAFConstraint_Hinge * hinge; // hinge - float steerAngle; // desired steer angle in degrees - float steerSpeed; // steer speed - float epsilon; // lcp epsilon - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// slider, prismatic or translational constraint which allows 1 degree of freedom -// constrains body1 to lie on a line relative to body2, the orientation is also fixed relative to body2 -class idAFConstraint_Slider : public idAFConstraint { - -public: - idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 ); - void SetAxis( const idVec3 &ax ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 axis; // axis along which body1 slides in body2 space - idVec3 offset; // offset of body1 relative to body2 - idMat3 relAxis; // rotation of body1 relative to body2 - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// line constraint which allows 4 degrees of freedom -// constrains body1 to lie on a line relative to body2, does not constrain the orientation. -class idAFConstraint_Line : public idAFConstraint { - -public: - idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// plane constraint which allows 5 degrees of freedom -// constrains body1 to lie in a plane relative to body2, does not constrain the orientation. -class idAFConstraint_Plane : public idAFConstraint { - -public: - idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 ); - void SetPlane( const idVec3 &normal, const idVec3 &anchor ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 anchor1; // anchor in body1 space - idVec3 anchor2; // anchor in body2 space - idVec3 planeNormal; // plane normal in body2 space - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// spring constraint which allows 6 or 5 degrees of freedom based on the spring limits -// constrains body1 relative to body2 with a spring -class idAFConstraint_Spring : public idAFConstraint { - -public: - idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 ); - void SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 ); - void SetSpring( const float stretch, const float compress, const float damping, const float restLength ); - void SetLimit( const float minLength, const float maxLength ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 anchor1; // anchor in body1 space - idVec3 anchor2; // anchor in body2 space - float kstretch; // spring constant when stretched - float kcompress; // spring constant when compressed - float damping; // spring damping - float restLength; // rest length of spring - float minLength; // minimum spring length - float maxLength; // maximum spring length - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// constrains body1 to either be in contact with or move away from body2 -class idAFConstraint_Contact : public idAFConstraint { - -public: - idAFConstraint_Contact( void ); - ~idAFConstraint_Contact( void ); - void Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c ); - const contactInfo_t & GetContact( void ) const { return contact; } - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void GetCenter( idVec3 ¢er ); - -protected: - contactInfo_t contact; // contact information - idAFConstraint_ContactFriction *fc; // contact friction - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// contact friction -class idAFConstraint_ContactFriction : public idAFConstraint { - -public: - idAFConstraint_ContactFriction( void ); - void Setup( idAFConstraint_Contact *cc ); - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - idAFConstraint_Contact *cc; // contact constraint - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// constrains an axis attached to body1 to be inside a cone relative to body2 -class idAFConstraint_ConeLimit : public idAFConstraint { - -public: - idAFConstraint_ConeLimit( void ); - void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis, - const float coneAngle, const idVec3 &body1Axis ); - void SetAnchor( const idVec3 &coneAnchor ); - void SetBody1Axis( const idVec3 &body1Axis ); - void SetEpsilon( const float e ) { epsilon = e; } - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 coneAnchor; // top of the cone in body2 space - idVec3 coneAxis; // cone axis in body2 space - idVec3 body1Axis; // axis in body1 space that should stay within the cone - float cosAngle; // cos( coneAngle / 2 ) - float sinHalfAngle; // sin( coneAngle / 4 ) - float cosHalfAngle; // cos( coneAngle / 4 ) - float epsilon; // lcp epsilon - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// constrains an axis attached to body1 to be inside a pyramid relative to body2 -class idAFConstraint_PyramidLimit : public idAFConstraint { - -public: - idAFConstraint_PyramidLimit( void ); - void Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor, - const idVec3 &pyramidAxis, const idVec3 &baseAxis, - const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis ); - void SetAnchor( const idVec3 &pyramidAxis ); - void SetBody1Axis( const idVec3 &body1Axis ); - void SetEpsilon( const float e ) { epsilon = e; } - bool Add( idPhysics_AF *phys, float invTimeStep ); - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - virtual void Save( idSaveGame *saveFile ) const; - virtual void Restore( idRestoreGame *saveFile ); - -protected: - idVec3 pyramidAnchor; // top of the pyramid in body2 space - idMat3 pyramidBasis; // pyramid basis in body2 space with base[2] being the pyramid axis - idVec3 body1Axis; // axis in body1 space that should stay within the cone - float cosAngle[2]; // cos( pyramidAngle / 2 ) - float sinHalfAngle[2]; // sin( pyramidAngle / 4 ) - float cosHalfAngle[2]; // cos( pyramidAngle / 4 ) - float epsilon; // lcp epsilon - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - -// vehicle suspension -class idAFConstraint_Suspension : public idAFConstraint { - -public: - idAFConstraint_Suspension( void ); - - void Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel ); - void SetSuspension( const float up, const float down, const float k, const float d, const float f ); - - void SetSteerAngle( const float degrees ) { steerAngle = degrees; } - void EnableMotor( const bool enable ) { motorEnabled = enable; } - void SetMotorForce( const float force ) { motorForce = force; } - void SetMotorVelocity( const float vel ) { motorVelocity = vel; } - void SetEpsilon( const float e ) { epsilon = e; } - const idVec3 GetWheelOrigin( void ) const; - - virtual void DebugDraw( void ); - virtual void Translate( const idVec3 &translation ); - virtual void Rotate( const idRotation &rotation ); - -protected: - idVec3 localOrigin; // position of suspension relative to body1 - idMat3 localAxis; // orientation of suspension relative to body1 - float suspensionUp; // suspension up movement - float suspensionDown; // suspension down movement - float suspensionKCompress; // spring compress constant - float suspensionDamping; // spring damping - float steerAngle; // desired steer angle in degrees - float friction; // friction - bool motorEnabled; // whether the motor is enabled or not - float motorForce; // motor force - float motorVelocity; // desired velocity - idClipModel * wheelModel; // wheel model - idVec3 wheelOffset; // wheel position relative to body1 - trace_t trace; // contact point with the ground - float epsilon; // lcp epsilon - -protected: - virtual void Evaluate( float invTimeStep ); - virtual void ApplyFriction( float invTimeStep ); -}; - - -//=============================================================== -// -// idAFBody -// -//=============================================================== - -typedef struct AFBodyPState_s { - idVec3 worldOrigin; // position in world space - idMat3 worldAxis; // axis at worldOrigin - idVec6 spatialVelocity; // linear and rotational velocity of body - idVec6 externalForce; // external force and torque applied to body -} AFBodyPState_t; - - -class idAFBody { - - friend class idPhysics_AF; - friend class idAFTree; - -public: - idAFBody( void ); - idAFBody( const idStr &name, idClipModel *clipModel, float density ); - ~idAFBody( void ); - - void Init( void ); - const idStr & GetName( void ) const { return name; } - const idVec3 & GetWorldOrigin( void ) const { return current->worldOrigin; } - const idMat3 & GetWorldAxis( void ) const { return current->worldAxis; } - const idVec3 & GetLinearVelocity( void ) const { return current->spatialVelocity.SubVec3(0); } - const idVec3 & GetAngularVelocity( void ) const { return current->spatialVelocity.SubVec3(1); } - idVec3 GetPointVelocity( const idVec3 &point ) const; - const idVec3 & GetCenterOfMass( void ) const { return centerOfMass; } - void SetClipModel( idClipModel *clipModel ); - idClipModel * GetClipModel( void ) const { return clipModel; } - void SetClipMask( const int mask ) { clipMask = mask; fl.clipMaskSet = true; } - int GetClipMask( void ) const { return clipMask; } - void SetSelfCollision( const bool enable ) { fl.selfCollision = enable; } - void SetWorldOrigin( const idVec3 &origin ) { current->worldOrigin = origin; } - void SetWorldAxis( const idMat3 &axis ) { current->worldAxis = axis; } - void SetLinearVelocity( const idVec3 &linear ) const { current->spatialVelocity.SubVec3(0) = linear; } - void SetAngularVelocity( const idVec3 &angular ) const { current->spatialVelocity.SubVec3(1) = angular; } - void SetFriction( float linear, float angular, float contact ); - float GetContactFriction( void ) const { return contactFriction; } - void SetBouncyness( float bounce ); - float GetBouncyness( void ) const { return bouncyness; } - void SetDensity( float density, const idMat3 &inertiaScale = mat3_identity ); - float GetInverseMass( void ) const { return invMass; } - idMat3 GetInverseWorldInertia( void ) const { return current->worldAxis.Transpose() * inverseInertiaTensor * current->worldAxis; } - void SetFrictionDirection( const idVec3 &dir ); - bool GetFrictionDirection( idVec3 &dir ) const; - -#ifdef MOD_WATERPHYSICS - float GetVolume( void ) const { return volume; } - // returns the depth of the object in the water - // 0.0f if out of water - float GetWaterLevel() const; // MOD_WATERPHYSICS - float SetWaterLevel( idPhysics_Liquid *l, const idVec3 &gravityNormal, bool fixedDensityBuoyancy ); // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS` - - void SetContactMotorDirection( const idVec3 &dir ); - bool GetContactMotorDirection( idVec3 &dir ) const; - void SetContactMotorVelocity( float vel ) { contactMotorVelocity = vel; } - float GetContactMotorVelocity( void ) const { return contactMotorVelocity; } - void SetContactMotorForce( float force ) { contactMotorForce = force; } - float GetContactMotorForce( void ) const { return contactMotorForce; } - - void AddForce( const idVec3 &point, const idVec3 &force ); - void InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const; - idVec6 & GetResponseForce( int index ) { return reinterpret_cast(response[ index * 8 ]); } - - /** - * Get or set the entity that stims and damage are routed to - **/ - void SetRerouteEnt( idEntity *ent ); - idEntity * GetRerouteEnt( void ); - - void Save( idSaveGame *saveFile ); - void Restore( idRestoreGame *saveFile ); - -private: - // properties - idStr name; // name of body - idAFBody * parent; // parent of this body - idList children; // children of this body - idClipModel * clipModel; // model used for collision detection - /** - * Entity to reroute damage and stims to, used when dynamically adding ents to an AF - * Defaults to NULL - **/ - idEntityPtr m_RerouteEnt; - idAFConstraint * primaryConstraint; // primary constraint (this->constraint->body1 = this) - idListconstraints; // all constraints attached to this body - idAFTree * tree; // tree structure this body is part of - float linearFriction; // translational friction - float angularFriction; // rotational friction - float contactFriction; // friction with contact surfaces - float bouncyness; // bounce -#ifdef MOD_WATERPHYSICS - float volume; // volume of body MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - int clipMask; // contents this body collides with - idVec3 frictionDir; // specifies a single direction of friction in body space - idVec3 contactMotorDir; // contact motor direction - float contactMotorVelocity; // contact motor velocity - float contactMotorForce; // maximum force applied to reach the motor velocity - - // derived properties - float mass; // mass of body - float invMass; // inverse mass -#ifdef MOD_WATERPHYSICS - float liquidMass; // mass of object in a liquid MOD_WATERPHYSICS - float invLiquidMass; // inverse liquid mass MOD_WATERPHYSICS - float waterLevel; // percent of body in water MOD_WATERPHYSICS - float m_fWaterMurkiness; // Tels: murkiness of the water body this entity is in -#endif // MOD_WATERPHYSICS - idVec3 centerOfMass; // center of mass of body - idMat3 inertiaTensor; // inertia tensor - idMat3 inverseInertiaTensor; // inverse inertia tensor - - // physics state - AFBodyPState_t state[2]; - AFBodyPState_t * current; // current physics state - AFBodyPState_t * next; // next physics state - AFBodyPState_t saved; // saved physics state - idVec3 atRestOrigin; // origin at rest - idMat3 atRestAxis; // axis at rest - - // simulation variables used during calculations - idMatX inverseWorldSpatialInertia; // inverse spatial inertia in world space - idMatX I, invI; // transformed inertia - idMatX J; // transformed constraint matrix - idVecX s; // temp solution - idVecX totalForce; // total force acting on body - idVecX auxForce; // force from auxiliary constraints - idVecX acceleration; // acceleration - float * response; // forces on body in response to auxiliary constraint forces - int * responseIndex; // index to response forces - int numResponses; // number of response forces - int maxAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body - int maxSubTreeAuxiliaryIndex; // largest index of an auxiliary constraint constraining this body or one of it's children - - struct bodyFlags_s { - bool clipMaskSet : 1; // true if this body has a clip mask set - bool selfCollision : 1; // true if this body can collide with other bodies of this AF - bool spatialInertiaSparse: 1; // true if the spatial inertia matrix is sparse - bool useFrictionDir : 1; // true if a single friction direction should be used - bool useContactMotorDir : 1; // true if a contact motor should be used - bool isZero : 1; // true if 's' is zero during calculations - } fl; -}; - - -//=============================================================== -// -// idAFTree -// -//=============================================================== - -class idAFTree { - friend class idPhysics_AF; - -public: - void Factor( void ) const; - void Solve( int auxiliaryIndex = 0 ) const; - void Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const; - void CalculateForces( float timeStep ) const; - void SetMaxSubTreeAuxiliaryIndex( void ); - void SortBodies( void ); - void SortBodies_r( idList&sortedList, idAFBody *body ); - void DebugDraw( const idVec4 &color ) const; - -private: - idList sortedBodies; -}; - - -//=============================================================== -// -// idPhysics_AF -// -//=============================================================== - -typedef struct AFPState_s { - int atRest; // >= 0 if articulated figure is at rest - float noMoveTime; // time the articulated figure is hardly moving - float activateTime; // time since last activation - float lastTimeStep; // last time step - idVec6 pushVelocity; // velocity with which the af is pushed -} AFPState_t; - -typedef struct AFCollision_s { - trace_t trace; - idAFBody * body; -} AFCollision_t; - - -class idPhysics_AF : public idPhysics_Base { - -public: - CLASS_PROTOTYPE( idPhysics_AF ); - - idPhysics_AF( void ); - ~idPhysics_AF( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // initialisation - int AddBody( idAFBody *body ); // returns body id - void AddConstraint( idAFConstraint *constraint ); - void AddFrameConstraint( idAFConstraint *constraint ); - // force a body to have a certain id - void ForceBodyId( idAFBody *body, int newId ); - // get body or constraint id - int GetBodyId( idAFBody *body ) const; - int GetBodyId( const char *bodyName ) const; - int GetConstraintId( idAFConstraint *constraint ) const; - int GetConstraintId( const char *constraintName ) const; - // number of bodies and constraints - int GetNumBodies( void ) const; - int GetNumConstraints( void ) const; - // retrieve body or constraint - idAFBody * GetBody( const char *bodyName ) const; - idAFBody * GetBody( const int id ) const; - idAFBody * GetMasterBody( void ) const { return masterBody; } - idAFConstraint * GetConstraint( const char *constraintName ) const; - idAFConstraint * GetConstraint( const int id ) const; - // delete body or constraint - void DeleteBody( const char *bodyName ); - void DeleteBody( const int id ); - void DeleteConstraint( const char *constraintName ); - void DeleteConstraint( const int id ); - // get all the contact constraints acting on the body - int GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const; - // set the default friction for bodies - void SetDefaultFriction( float linear, float angular, float contact ); - // suspend settings - void SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration ); - // set the time and tolerances used to determine if the simulation can be suspended when the figure hardly moves for a while - void SetSuspendTolerance( const float noMoveTime, const float translationTolerance, const float rotationTolerance ); - // set minimum and maximum simulation time in seconds - void SetSuspendTime( const float minTime, const float maxTime ); - // set the time scale value - void SetTimeScale( const float ts ) { timeScale = ts; } - // set time scale ramp - void SetTimeScaleRamp( const float start, const float end ); - // set the joint friction scale - void SetJointFrictionScale( const float scale ) { jointFrictionScale = scale; } - // set joint friction dent - void SetJointFrictionDent( const float dent, const float start, const float end ); - // get the current joint friction scale - float GetJointFrictionScale( void ) const; - // set the contact friction scale - void SetContactFrictionScale( const float scale ) { contactFrictionScale = scale; } - // set contact friction dent - void SetContactFrictionDent( const float dent, const float start, const float end ); - // get the current contact friction scale - float GetContactFrictionScale( void ) const; - // enable or disable collision detection - void SetCollision( const bool enable ) { enableCollision = enable; } - // enable or disable self collision - void SetSelfCollision( const bool enable ) { selfCollision = enable; } - // enable or disable coming to a dead stop - void SetComeToRest( bool enable ) { comeToRest = enable; } - // call when structure of articulated figure changes - void SetChanged( void ) { changedAF = true; } - // enable/disable activation by impact - void EnableImpact( void ); - void DisableImpact( void ); - // lock of unlock the world constraints - void LockWorldConstraints( const bool lock ) { worldConstraintsLocked = lock; } - // set force pushable - void SetForcePushable( const bool enable ) { forcePushable = enable; } - // update the clip model positions - void UpdateClipModels( void ); - /** -* DarkMod: -* Returns the origin of the AF body nearest to the given point -* -* If int pointer body is non-NULL, the body Id of the nearest body is written -* to this pointer. Will be set to -1 if no body was found. -**/ -idVec3 NearestBodyOrig( idVec3 point, int *bodyID = NULL ); - /** -* Returns true if the specified body is in contact with the ground -* (Called by the rope climbing code) -**/ -bool HasGroundContacts( int id ); -#ifdef MOD_WATERPHYSICS - // buoyancy stuff - void SetLiquidDensity( float density ); // MOD_WATERPHYSICS - float GetLiquidDensity() const; // MOD_WATERPHYSICS - // this will reset liquidDensity so be careful when using it - void SetFixedDensityBuoyancy( bool fixed ); // MOD_WATERPHYSICS - bool GetFixedDensityBuoyancy() const; // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - - -public: // common physics interface - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - void AddForce( const int id, const idVec3 &point, const idVec3 &force ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - void Activate( void ); - void PutToRest( void ); - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated = true ); - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - /** - * TDM: Had to make this public so we could call it earlier than intended - **/ - void BuildTrees( void ); - - /** - * Get/Set the number of original bodies or constraints - * These are constraints that are added by this entity's AF only, not ones that are attached later - **/ - int GetNumOrigBodies( void ) { return m_NumOrigBodies; }; - void SetNumOrigBodies( int num ) { m_NumOrigBodies = num; }; - int GetNumOrigConstraints( void ) { return m_NumOrigConstraints; }; - void SetNumOrigConstraints( int num ) { m_NumOrigConstraints = num; }; - -private: - // articulated figure - idList trees; // tree structures - idList bodies; // all bodies - idListconstraints; // all frame independent constraints - idListprimaryConstraints; // list with primary constraints - idListauxiliaryConstraints; // list with auxiliary constraints - idListframeConstraints; // constraints that only live one frame - idListcontactConstraints; // contact constraints - idList contactBodies; // body id for each contact - idList collisions; // collisions - bool changedAF; // true when the articulated figure just changed - - /** - * TDM: Number of _original_ bodies from the loaded AF file - * We need this to implement a hack where added bodies aren't saved/loaded, - * because they will be added again from scratch on restore. - * We must do this because Id chose to re-load the AFs instead of restore them - **/ - int m_NumOrigBodies; - /** - * Number of original constraints loaded from this entity's AF file - **/ - int m_NumOrigConstraints; - - // properties - float linearFriction; // default translational friction - float angularFriction; // default rotational friction - float contactFriction; // default friction with contact surfaces - float bouncyness; // default bouncyness - float totalMass; // total mass of articulated figure - float forceTotalMass; // force this total mass - - idVec2 suspendVelocity; // simulation may not be suspended if a body has more velocity - idVec2 suspendAcceleration; // simulation may not be suspended if a body has more acceleration - float noMoveTime; // suspend simulation if hardly any movement for this many seconds - float noMoveTranslation; // maximum translation considered no movement - float noMoveRotation; // maximum rotation considered no movement - float minMoveTime; // if > 0 the simulation is never suspended before running this many seconds - float maxMoveTime; // if > 0 the simulation is always suspeded after running this many seconds - float impulseThreshold; // threshold below which impulses are ignored to avoid continuous activation - - float timeScale; // the time is scaled with this value for slow motion effects - float timeScaleRampStart; // start of time scale change - float timeScaleRampEnd; // end of time scale change - - float jointFrictionScale; // joint friction scale - float jointFrictionDent; // joint friction dives from 1 to this value and goes up again - float jointFrictionDentStart; // start time of joint friction dent - float jointFrictionDentEnd; // end time of joint friction dent - float jointFrictionDentScale; // dent scale - - float contactFrictionScale; // contact friction scale - float contactFrictionDent; // contact friction dives from 1 to this value and goes up again - float contactFrictionDentStart; // start time of contact friction dent - float contactFrictionDentEnd; // end time of contact friction dent - float contactFrictionDentScale; // dent scale - - bool enableCollision; // if true collision detection is enabled - bool selfCollision; // if true the self collision is allowed - bool comeToRest; // if true the figure can come to rest - bool linearTime; // if true use the linear time algorithm - bool noImpact; // if true do not activate when another object collides - bool worldConstraintsLocked; // if true world constraints cannot be moved - bool forcePushable; // if true can be pushed even when bound to a master - - // physics state - AFPState_t current; - AFPState_t saved; -#ifdef MOD_WATERPHYSICS -// treats liquid Density as THE density for each body when the AF is in liquid. -// otherwise liquidDensity is just a gravity scalar for the AF in any liquid. - bool fixedDensityBuoyancy; // MOD_WATERPHYSICS - float liquidDensity; // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - - idAFBody * masterBody; // master body - idLCP * lcp; // linear complementarity problem solver - -private: - bool IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const; - void PrimaryFactor( void ); - void EvaluateBodies( float timeStep ); - void EvaluateConstraints( float timeStep ); - void AddFrameConstraints( void ); - void RemoveFrameConstraints( void ); - void ApplyFriction( float timeStep, float endTimeMSec ); - void PrimaryForces( float timeStep ); - void AuxiliaryForces( float timeStep ); - void VerifyContactConstraints( void ); - void SetupContactConstraints( void ); - void ApplyContactForces( void ); - void Evolve( float timeStep ); - idEntity * SetupCollisionForBody( idAFBody *body ) const; - bool CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision ); - bool ApplyCollisions( float timeStep ); - void CheckForCollisions( float timeStep ); - void ClearExternalForce( void ); - void AddGravity( void ); - void SwapStates( void ); - bool TestIfAtRest( float timeStep ); - void Rest( void ); - void AddPushVelocity( const idVec6 &pushVelocity ); - void DebugDraw( void ); -}; - -#endif /* !__PHYSICS_AF_H__ */ diff --git a/game/physics/physics_base.cpp b/game/physics/physics_base.cpp deleted file mode 100644 index 7cafcea17..000000000 --- a/game/physics/physics_base.cpp +++ /dev/null @@ -1,935 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics, idPhysics_Base ) -END_CLASS - -/* -================ -idPhysics_Base::idPhysics_Base -================ -*/ -idPhysics_Base::idPhysics_Base( void ) { - self = NULL; -#ifdef MOD_WATERPHYSICS - water = NULL; // MOD_WATERPHYSICS - m_fWaterMurkiness = 0.0f; -#endif // MOD_WATERPHYSICS - - clipMask = 0; - SetGravity( gameLocal.GetGravity() ); - ClearContacts(); -} - -/* -================ -idPhysics_Base::~idPhysics_Base -================ -*/ -idPhysics_Base::~idPhysics_Base( void ) { - if ( self && self->GetPhysics() == this ) { - self->SetPhysics( NULL ); - } - idForce::DeletePhysics( this ); - ClearContacts(); -} - -/* -================ -idPhysics_Base::Save -================ -*/ -void idPhysics_Base::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteObject( self ); - savefile->WriteInt( clipMask ); - savefile->WriteVec3( gravityVector ); - savefile->WriteVec3( gravityNormal ); - - savefile->WriteInt( contacts.Num() ); - for ( i = 0; i < contacts.Num(); i++ ) { - savefile->WriteContactInfo( contacts[i] ); - } - - savefile->WriteInt( contactEntities.Num() ); - for ( i = 0; i < contactEntities.Num(); i++ ) { - contactEntities[i].Save( savefile ); - } -} - -/* -================ -idPhysics_Base::Restore -================ -*/ -void idPhysics_Base::Restore( idRestoreGame *savefile ) { - int i, num; - - savefile->ReadObject( reinterpret_cast( self ) ); - savefile->ReadInt( clipMask ); - savefile->ReadVec3( gravityVector ); - savefile->ReadVec3( gravityNormal ); - - savefile->ReadInt( num ); - contacts.SetNum( num ); - for ( i = 0; i < contacts.Num(); i++ ) { - savefile->ReadContactInfo( contacts[i] ); - } - - savefile->ReadInt( num ); - contactEntities.SetNum( num ); - for ( i = 0; i < contactEntities.Num(); i++ ) { - contactEntities[i].Restore( savefile ); - } -} - -/* -================ -idPhysics_Base::SetSelf -================ -*/ -void idPhysics_Base::SetSelf( idEntity *e ) { - assert( e ); - self = e; -} - -/* -================ -idPhysics_Base::SetClipModel -================ -*/ -void idPhysics_Base::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { -} - -/* -================ -idPhysics_Base::GetClipModel -================ -*/ -idClipModel *idPhysics_Base::GetClipModel( int id ) const { - return NULL; -} - -/* -================ -idPhysics_Base::GetNumClipModels -================ -*/ -int idPhysics_Base::GetNumClipModels( void ) const { - return 0; -} - -/* -================ -idPhysics_Base::SetMass -================ -*/ -void idPhysics_Base::SetMass( float mass, int id ) { -} - -/* -================ -idPhysics_Base::GetMass -================ -*/ -float idPhysics_Base::GetMass( int id ) const { - return 0.0f; -} - -/* -================ -idPhysics_Base::SetContents -================ -*/ -void idPhysics_Base::SetContents( int contents, int id ) { -} - -/* -================ -idPhysics_Base::SetClipMask -================ -*/ -int idPhysics_Base::GetContents( int id ) const { - return 0; -} - -/* -================ -idPhysics_Base::SetClipMask -================ -*/ -void idPhysics_Base::SetClipMask( int mask, int id ) { - clipMask = mask; -} - -/* -================ -idPhysics_Base::GetClipMask -================ -*/ -int idPhysics_Base::GetClipMask( int id ) const { - return clipMask; -} - -/* -================ -idPhysics_Base::GetBounds -================ -*/ -const idBounds &idPhysics_Base::GetBounds( int id ) const { - return bounds_zero; -} - -/* -================ -idPhysics_Base::GetAbsBounds -================ -*/ -const idBounds &idPhysics_Base::GetAbsBounds( int id ) const { - return bounds_zero; -} - -/* -================ -idPhysics_Base::Evaluate -================ -*/ -bool idPhysics_Base::Evaluate( int timeStepMSec, int endTimeMSec ) { - return false; -} - -/* -================ -idPhysics_Base::UpdateTime -================ -*/ -void idPhysics_Base::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_Base::GetTime -================ -*/ -int idPhysics_Base::GetTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Base::GetImpactInfo -================ -*/ -void idPhysics_Base::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - memset( info, 0, sizeof( *info ) ); -} - -/* -================ -idPhysics_Base::ApplyImpulse -================ -*/ -void idPhysics_Base::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { -} - -// greebo: The default implementation of PropagateImpulse just applies the impulse -bool idPhysics_Base::PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ) { - ApplyImpulse(id, point, impulse); - return false; -} - -/* -================ -idPhysics_Base::AddForce -================ -*/ -void idPhysics_Base::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { -} - -/* -================ -idPhysics_Base::Activate -================ -*/ -void idPhysics_Base::Activate( void ) { -} - -/* -================ -idPhysics_Base::PutToRest -================ -*/ -void idPhysics_Base::PutToRest( void ) { -} - -/* -================ -idPhysics_Base::IsAtRest -================ -*/ -bool idPhysics_Base::IsAtRest( void ) const { - return true; -} - -/* -================ -idPhysics_Base::GetRestStartTime -================ -*/ -int idPhysics_Base::GetRestStartTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Base::IsPushable -================ -*/ -bool idPhysics_Base::IsPushable( void ) const { - return true; -} - -/* -================ -idPhysics_Base::SaveState -================ -*/ -void idPhysics_Base::SaveState( void ) { -} - -/* -================ -idPhysics_Base::RestoreState -================ -*/ -void idPhysics_Base::RestoreState( void ) { -} - -/* -================ -idPhysics_Base::SetOrigin -================ -*/ -void idPhysics_Base::SetOrigin( const idVec3 &newOrigin, int id ) { -} - -/* -================ -idPhysics_Base::SetAxis -================ -*/ -void idPhysics_Base::SetAxis( const idMat3 &newAxis, int id ) { -} - -/* -================ -idPhysics_Base::Translate -================ -*/ -void idPhysics_Base::Translate( const idVec3 &translation, int id ) { -} - -/* -================ -idPhysics_Base::Rotate -================ -*/ -void idPhysics_Base::Rotate( const idRotation &rotation, int id ) { -} - -/* -================ -idPhysics_Base::GetOrigin -================ -*/ -const idVec3 &idPhysics_Base::GetOrigin( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Base::GetAxis -================ -*/ -const idMat3 &idPhysics_Base::GetAxis( int id ) const { - return mat3_identity; -} - -/* -================ -idPhysics_Base::SetLinearVelocity -================ -*/ -void idPhysics_Base::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { -} - -/* -================ -idPhysics_Base::SetAngularVelocity -================ -*/ -void idPhysics_Base::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { -} - -/* -================ -idPhysics_Base::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_Base::GetLinearVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Base::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_Base::GetAngularVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Base::SetGravity -================ -*/ -void idPhysics_Base::SetGravity( const idVec3 &newGravity ) { - gravityVector = newGravity; - gravityNormal = newGravity; - gravityNormal.Normalize(); -} - -/* -================ -idPhysics_Base::GetGravity -================ -*/ -const idVec3 &idPhysics_Base::GetGravity( void ) const { - return gravityVector; -} - -/* -================ -idPhysics_Base::GetGravityNormal -================ -*/ -const idVec3 &idPhysics_Base::GetGravityNormal( void ) const { - return gravityNormal; -} - -/* -================ -idPhysics_Base::ClipTranslation -================ -*/ -void idPhysics_Base::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - memset( &results, 0, sizeof( trace_t ) ); -} - -/* -================ -idPhysics_Base::ClipRotation -================ -*/ -void idPhysics_Base::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - memset( &results, 0, sizeof( trace_t ) ); -} - -/* -================ -idPhysics_Base::ClipContents -================ -*/ -int idPhysics_Base::ClipContents( const idClipModel *model ) const { - return 0; -} - -/* -================ -idPhysics_Base::DisableClip -================ -*/ -void idPhysics_Base::DisableClip( void ) { -} - -/* -================ -idPhysics_Base::EnableClip -================ -*/ -void idPhysics_Base::EnableClip( void ) { -} - -/* -================ -idPhysics_Base::UnlinkClip -================ -*/ -void idPhysics_Base::UnlinkClip( void ) { -} - -/* -================ -idPhysics_Base::LinkClip -================ -*/ -void idPhysics_Base::LinkClip( void ) { -} - -/* -================ -idPhysics_Base::EvaluateContacts -================ -*/ -bool idPhysics_Base::EvaluateContacts( void ) { - return false; -} - -/* -================ -idPhysics_Base::GetNumContacts -================ -*/ -int idPhysics_Base::GetNumContacts( void ) const { - return contacts.Num(); -} - -/* -================ -idPhysics_Base::GetContact -================ -*/ -const contactInfo_t &idPhysics_Base::GetContact( int num ) const { - return contacts[num]; -} - -/* -================ -idPhysics_Base::ClearContacts -================ -*/ -void idPhysics_Base::ClearContacts( void ) { - int i; - idEntity *ent; - - for ( i = 0; i < contacts.Num(); i++ ) { - ent = gameLocal.entities[ contacts[i].entityNum ]; - if ( ent ) { - ent->RemoveContactEntity( self ); - } - } - contacts.SetNum( 0, false ); -} - -/* -================ -idPhysics_Base::AddContactEntity -================ -*/ -void idPhysics_Base::AddContactEntity( idEntity *e ) { - int i; - idEntity *ent; - bool found = false; - - for ( i = 0; i < contactEntities.Num(); i++ ) { - ent = contactEntities[i].GetEntity(); - if ( ent == NULL ) { - contactEntities.RemoveIndex( i-- ); - } - if ( ent == e ) { - found = true; - } - } - if ( !found ) { - contactEntities.Alloc() = e; - } -} - -/* -================ -idPhysics_Base::RemoveContactEntity -================ -*/ -void idPhysics_Base::RemoveContactEntity( idEntity *e ) { - int i; - idEntity *ent; - - for ( i = 0; i < contactEntities.Num(); i++ ) { - ent = contactEntities[i].GetEntity(); - if ( !ent ) { - contactEntities.RemoveIndex( i-- ); - continue; - } - if ( ent == e ) { - contactEntities.RemoveIndex( i-- ); - return; - } - } -} - -/* -================ -idPhysics_Base::HasGroundContacts -================ -*/ -bool idPhysics_Base::HasGroundContacts( void ) const { - int i; - - for ( i = 0; i < contacts.Num(); i++ ) { - if ( contacts[i].normal * -gravityNormal > 0.0f ) { - return true; - } - } - return false; -} - -/* -================ -idPhysics_Base::IsGroundEntity -================ -*/ -bool idPhysics_Base::IsGroundEntity( int entityNum ) const { - int i; - - for ( i = 0; i < contacts.Num(); i++ ) { - if ( contacts[i].entityNum == entityNum && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { - return true; - } - } - return false; -} - -/* -================ -idPhysics_Base::IsGroundClipModel -================ -*/ -bool idPhysics_Base::IsGroundClipModel( int entityNum, int id ) const { - int i; - - for ( i = 0; i < contacts.Num(); i++ ) { - if ( contacts[i].entityNum == entityNum && contacts[i].id == id && ( contacts[i].normal * -gravityNormal > 0.0f ) ) { - return true; - } - } - return false; -} - -/* -================ -idPhysics_Base::SetPushed -================ -*/ -void idPhysics_Base::SetPushed( int deltaTime ) { -} - -/* -================ -idPhysics_Base::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_Base::GetPushedLinearVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Base::GetPushedAngularVelocity -================ -*/ -const idVec3 &idPhysics_Base::GetPushedAngularVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Base::SetMaster -================ -*/ -void idPhysics_Base::SetMaster( idEntity *master, const bool orientated ) { -} - -/* -================ -idPhysics_Base::GetBlockingInfo -================ -*/ -const trace_t *idPhysics_Base::GetBlockingInfo( void ) const { - return NULL; -} - -/* -================ -idPhysics_Base::GetBlockingEntity -================ -*/ -idEntity *idPhysics_Base::GetBlockingEntity( void ) const { - return NULL; -} - -/* -================ -idPhysics_Base::GetLinearEndTime -================ -*/ -int idPhysics_Base::GetLinearEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Base::GetAngularEndTime -================ -*/ -int idPhysics_Base::GetAngularEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Base::AddGroundContacts -================ -*/ -void idPhysics_Base::AddGroundContacts( const idClipModel *clipModel ) { - idVec6 dir; - int index, num; - - index = contacts.Num(); - contacts.SetNum( index + 10, false ); - - dir.SubVec3(0) = gravityNormal; - dir.SubVec3(1) = vec3_origin; - num = gameLocal.clip.Contacts( &contacts[index], 10, clipModel->GetOrigin(), - dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self ); - contacts.SetNum( index + num, false ); -} - -/* -================ -idPhysics_Base::AddContactEntitiesForContacts -================ -*/ -void idPhysics_Base::AddContactEntitiesForContacts( void ) { - int i; - idEntity *ent; - - for ( i = 0; i < contacts.Num(); i++ ) { - ent = gameLocal.entities[ contacts[i].entityNum ]; - if ( ent && ent != self ) { - ent->AddContactEntity( self ); - } - } -} - -/* -================ -idPhysics_Base::ActivateContactEntities -================ -*/ -void idPhysics_Base::ActivateContactEntities( void ) { - int i; - idEntity *ent; - - for ( i = 0; i < contactEntities.Num(); i++ ) { - ent = contactEntities[i].GetEntity(); - if ( ent ) { - ent->ActivatePhysics( self ); - } else { - contactEntities.RemoveIndex( i-- ); - } - } -} - -/* -================ -idPhysics_Base::IsOutsideWorld -================ -*/ -bool idPhysics_Base::IsOutsideWorld( void ) const { - if ( !gameLocal.clip.GetWorldBounds().Expand( 128.0f ).IntersectsBounds( GetAbsBounds() ) ) { - return true; - } - return false; -} - -/* -================ -idPhysics_Base::DrawVelocity -================ -*/ -void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const { - idVec3 dir, org, vec, start, end; - idMat3 axis; - float length, a; - - dir = GetLinearVelocity( id ); - dir *= linearScale; - if ( dir.LengthSqr() > Square( 0.1f ) ) { - dir.Truncate( 10.0f ); - org = GetOrigin( id ); - gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 ); - } - - dir = GetAngularVelocity( id ); - length = dir.Normalize(); - length *= angularScale; - if ( length > 0.1f ) { - if ( length < 60.0f ) { - length = 60.0f; - } - else if ( length > 360.0f ) { - length = 360.0f; - } - axis = GetAxis( id ); - vec = axis[2]; - if ( idMath::Fabs( dir * vec ) > 0.99f ) { - vec = axis[0]; - } - vec -= vec * dir * vec; - vec.Normalize(); - vec *= 4.0f; - start = org + vec; - for ( a = 20.0f; a < length; a += 20.0f ) { - end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec; - gameRenderWorld->DebugLine( colorBlue, start, end, 1 ); - start = end; - } - end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec; - gameRenderWorld->DebugArrow( colorBlue, start, end, 1 ); - } -} - -/* -================ -idPhysics_Base::WriteToSnapshot -================ -*/ -void idPhysics_Base::WriteToSnapshot( idBitMsgDelta &msg ) const { -} - -/* -================ -idPhysics_Base::ReadFromSnapshot -================ -*/ -void idPhysics_Base::ReadFromSnapshot( const idBitMsgDelta &msg ) { -} - -#ifdef MOD_WATERPHYSICS -/* -================ -idPhysics_Base::SetWater -================ -*/ -void idPhysics_Base::SetWater( idPhysics_Liquid *e, const float m ) { -/* - if (e != this->water) - { - if (NULL != e) - { - gameLocal.Printf("Entered water with murkiness %f.\n", m ); - } - else - { - gameLocal.Printf("Leaving water.\n"); - } - } -*/ - this->water = e; - this->m_fWaterMurkiness = m; -} - -/* -================ -idPhysics_Base::GetWater -================ -*/ -idPhysics_Liquid *idPhysics_Base::GetWater() -{ - return this->water; -} - -/* -================ -idPhysics_Base::GetWaterMurkiness -================ -*/ -float idPhysics_Base::GetWaterMurkiness() const -{ - return this->m_fWaterMurkiness; -} - -/* -================ -idPhysics_Base::SetWaterLevelf - - Returns 1.0f if the object is in a liquid, 0.0f otherwise. - - If the object's not in a liquid it double checks to make sure it's really not. - Normally we only set this->water when an object collides with a water material but - what happens if an object spawns inside a liquid or something? Nothing, it'll just sit - there. This function sets the water level for an object that's already inside the water. - - This was most noticeable when I had monsters walking into the water and of course, they'd - sink to the bottom. After I'd kill them they'd die normally and not float. After adding - this function they float after they're killed. - -================ -*/ -float idPhysics_Base::SetWaterLevelf() { - if( this->water == NULL ) { - idEntity *e[2]; - trace_t result; - idBounds bounds = this->GetBounds(); - - bounds += this->GetOrigin(); - - // trace for a water contact - // Tels: TODO This additional trace might be expensive because it is done every frame - if( gameLocal.clip.EntitiesTouchingBounds(bounds,MASK_WATER,e,2) ) { - if( e[0]->GetPhysics()->IsType(idPhysics_Liquid::Type) ) { - SetWater( static_cast(e[0]->GetPhysics()), e[0]->spawnArgs.GetFloat("murkiness", "0") ); - return 1.0f; - } - } - - this->m_fWaterMurkiness = 0.0f; - return 0.0f; - } - else - return 1.0f; -} - -/* -================ -idPhysics_Base::GetWaterLevelf - - The water level for this object, 0.0f if not in the water, 1.0f if in water -================ -*/ -float idPhysics_Base::GetWaterLevelf() const { - if( this->water == NULL ) - return 0.0f; - else - return 1.0f; -} - -#endif // MOD_WATERPHYSICS diff --git a/game/physics/physics_base.h b/game/physics/physics_base.h deleted file mode 100644 index 955740787..000000000 --- a/game/physics/physics_base.h +++ /dev/null @@ -1,170 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_BASE_H__ -#define __PHYSICS_BASE_H__ - -/* -=============================================================================== - - Physics base for a moving object using one or more collision models. - -=============================================================================== -*/ - -#define contactEntity_t idEntityPtr - -class idPhysics_Base : public idPhysics { - -public: - CLASS_PROTOTYPE( idPhysics_Base ); - - idPhysics_Base( void ); - ~idPhysics_Base( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -public: // common physics interface - - virtual void SetSelf( idEntity *e ); -#ifdef MOD_WATERPHYSICS - idEntity *GetSelf() { return self; } // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - void SetClipMask( int mask, int id = -1 ); - int GetClipMask( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - bool PropagateImpulse( const int id, const idVec3& point, const idVec3& impulse ); - - void AddForce( const int id, const idVec3 &point, const idVec3 &force ); - void Activate( void ); - void PutToRest( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - void SetGravity( const idVec3 &newGravity ); - const idVec3 & GetGravity( void ) const; - const idVec3 & GetGravityNormal( void ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - int GetNumContacts( void ) const; - const contactInfo_t & GetContact( int num ) const; - void ClearContacts( void ); - void AddContactEntity( idEntity *e ); - void RemoveContactEntity( idEntity *e ); - - bool HasGroundContacts( void ) const; - bool IsGroundEntity( int entityNum ) const; - bool IsGroundClipModel( int entityNum, int id ) const; - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated = true ); - - const trace_t * GetBlockingInfo( void ) const; - idEntity * GetBlockingEntity( void ) const; - - int GetLinearEndTime( void ) const; - int GetAngularEndTime( void ) const; - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -#ifdef MOD_WATERPHYSICS - idPhysics_Liquid * GetWater(); // MOD_WATERPHYSICS - float GetWaterMurkiness() const; // TDM Tels - void SetWater( idPhysics_Liquid *e, const float murkiness ); // MOD_WATERPHYSICS - float SetWaterLevelf(); // MOD_WATERPHYSICS - float GetWaterLevelf() const; // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - -protected: - idEntity * self; // entity using this physics object - int clipMask; // contents the physics object collides with - idVec3 gravityVector; // direction and magnitude of gravity - idVec3 gravityNormal; // normalized direction of gravity - idList contacts; // contacts with other physics objects - idList contactEntities; // entities touching this physics object - -#ifdef MOD_WATERPHYSICS -// the water object the object is in, we use this to check density/viscosity - idPhysics_Liquid *water; // MOD_WATERPHYSICS -// TDM Tels: The murkiness of this water, 0 => clear as crystal, 1 => opaque - float m_fWaterMurkiness; -#endif - -protected: - // add ground contacts for the clip model - void AddGroundContacts( const idClipModel *clipModel ); - // add contact entity links to contact entities - void AddContactEntitiesForContacts( void ); - // active all contact entities - void ActivateContactEntities( void ); - // returns true if the whole physics object is outside the world bounds - bool IsOutsideWorld( void ) const; - // draw linear and angular velocity - void DrawVelocity( int id, float linearScale, float angularScale ) const; -}; - -#endif /* !__PHYSICS_BASE_H__ */ diff --git a/game/physics/physics_liquid.cpp b/game/physics/physics_liquid.cpp deleted file mode 100755 index 2e82c9805..000000000 --- a/game/physics/physics_liquid.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#ifdef MOD_WATERPHYSICS - -CLASS_DECLARATION( idPhysics_Static, idPhysics_Liquid ) -END_CLASS - -/* -=============================================================================== - - idPhysics_Liquid - -=============================================================================== -*/ - -/* -================ -idPhysics_Liquid::idPhysics_Liquid -================ -*/ -idPhysics_Liquid::idPhysics_Liquid() { - - // initializes to a water-like liquid - this->density = 0.001043f; - this->viscosity = 3.0f; -} - -/* -================ -idPhysics_Liquid::~idPhysics_Liquid -================ -*/ -idPhysics_Liquid::~idPhysics_Liquid() { -} - -/* -================ -idPhysics_Liquid::Save -================ -*/ -void idPhysics_Liquid::Save( idSaveGame *savefile ) const -{ - savefile->WriteFloat(this->density); - savefile->WriteFloat(this->viscosity); - savefile->WriteVec3(this->minSplashVelocity); - savefile->WriteVec3(this->minWaveVelocity); -} - -/* -================ -idPhysics_Liquid::Restore -================ -*/ -void idPhysics_Liquid::Restore( idRestoreGame *savefile ) -{ - savefile->ReadFloat(this->density); - savefile->ReadFloat(this->viscosity); - savefile->ReadVec3(this->minSplashVelocity); - savefile->ReadVec3(this->minWaveVelocity); -} - -/* -================ -idPhysics_Liquid::GetDepth - Gets the depth of a point in the liquid. Returns -1 -1 -1 if the object is not in the liquid -================ -*/ -idVec3 idPhysics_Liquid::GetDepth( const idVec3 &point ) const { - const idBounds &bounds = this->GetBounds(); - idVec3 gravityNormal = this->GetGravityNormal(); - idVec3 depth(-1.0f,-1.0f,-1.0f); - - if( !this->isInLiquid(point) ) - return depth; - depth = (((bounds[1] + this->GetOrigin()) - point) * gravityNormal) * gravityNormal; - - return depth; -} - -/* -================ -idPhysics_Liquid::Splash - Causes the liquid to splash but only if the velocity is greater than minSplashVelocity -================ -*/ -void idPhysics_Liquid::Splash( idEntity *other, float volume, impactInfo_t &info, trace_t &collision ) { - collision.c.entityNum = other->entityNumber; - self->Collide(collision,info.velocity); -} - -/* -================ -idPhysics_Liquid::isInLiquid - Returns true if a point is in the liquid -================ -*/ -bool idPhysics_Liquid::isInLiquid( const idVec3 &point ) const { - bool result; - - result = (gameLocal.clip.Contents(point,NULL,mat3_identity,MASK_WATER,NULL) != 0); - return result; -} - -/* -================ -idPhysics_Liquid::GetPressure - Returns the amount of pressure the liquid applies to the given point -================ -*/ -idVec3 idPhysics_Liquid::GetPressure( const idVec3 &point ) const { - idVec3 pressure; - idVec3 depth = this->GetDepth(point); -//NJM idVec3 &depth = this->GetDepth(point); - - pressure = depth * this->density; - - return pressure; -} - -/* -================ -idPhysics_Liquid::GetDensity -================ -*/ -float idPhysics_Liquid::GetDensity() const { - return this->density; -} - -/* -================ -idPhysics_Liquid::SetDensity -================ -*/ -void idPhysics_Liquid::SetDensity( float density ) { - if( density > 0.0f ) - this->density = density; -} - -/* -================ -idPhysics_Liquid::GetViscosity -================ -*/ -float idPhysics_Liquid::GetViscosity() const { - return this->viscosity; -} - -/* -================ -idPhysics_Liquid::SetViscosity -================ -*/ -void idPhysics_Liquid::SetViscosity( float viscosity ) { - if( viscosity >= 0.0f ) - this->viscosity = viscosity; -} - -/* -================ -idPhysics_Liquid::GetMinSplashVelocity -================ -*/ -const idVec3 &idPhysics_Liquid::GetMinSplashVelocity() const { - return this->minSplashVelocity; -} - -/* -================ -idPhysics_Liquid::SetMinSplashVelocity -================ -*/ -void idPhysics_Liquid::SetMinSplashVelocity( const idVec3 &m ) { - this->minSplashVelocity = m; -} - -/* -================ -idPhysics_Liquid::GetMinWaveVelocity -================ -*/ -const idVec3 &idPhysics_Liquid::GetMinWaveVelocity() const { - return this->minWaveVelocity; -} - -/* -================ -idPhysics_Liquid::SetMinWaveVelocity -================ -*/ -void idPhysics_Liquid::SetMinWaveVelocity( const idVec3 &w ) { - this->minWaveVelocity = w; -} - -#endif - diff --git a/game/physics/physics_liquid.h b/game/physics/physics_liquid.h deleted file mode 100755 index d2a2910d0..000000000 --- a/game/physics/physics_liquid.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -/* -=============================================================================== - - Physics object for a liquid. This class contains physics properties for a - given liquid. Note: Liquid does not necessarily imply water. - - This class does very little functionally as it relies on the other physics - classes to do the bouoyancy calculations. It simply holds information and - allows the other object to deal with that information however they please. - - As a side note, the difference between minSplashVelocity and - minWaveVelocity is that min splash is the minimum amount of velocity - before the liquid spawns a splash particle. minWaveVelocity is to generate - a wave on the surface, not a splash. It should be lower than min splash - velocity. It's the reason some things won't splash but will still cause - ripples in the water (especially when surfacing) -=============================================================================== -*/ - -#ifdef MOD_WATERPHYSICS - -class idPhysics_Liquid : public idPhysics_Static { -public: - CLASS_PROTOTYPE( idPhysics_Liquid ); - - idPhysics_Liquid( void ); - ~idPhysics_Liquid( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -public: - // Creates a splash on the liquid - virtual void Splash( idEntity *other, float volume, impactInfo_t &info, trace_t &collision ); - - // Derived information - virtual bool isInLiquid( const idVec3 &point ) const; - virtual idVec3 GetDepth( const idVec3 &point ) const; - virtual idVec3 GetPressure( const idVec3 &point ) const; - - // Physical properties - virtual float GetDensity() const; - virtual void SetDensity( float density ); - - virtual float GetViscosity() const; - virtual void SetViscosity( float viscosity ); - - virtual const idVec3 &GetMinSplashVelocity() const; - virtual void SetMinSplashVelocity( const idVec3 &m ); - - virtual const idVec3 &GetMinWaveVelocity() const; - virtual void SetMinWaveVelocity( const idVec3 &w ); - -private: - // STATE - float density; - float viscosity; - - idVec3 minWaveVelocity; - idVec3 minSplashVelocity; -}; - -#endif diff --git a/game/physics/physics_monster.cpp b/game/physics/physics_monster.cpp deleted file mode 100644 index 0fb3324e2..000000000 --- a/game/physics/physics_monster.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics_Actor, idPhysics_Monster ) -END_CLASS - -const float OVERCLIP = 1.001f; - -/* -===================== -idPhysics_Monster::CheckGround -===================== -*/ -void idPhysics_Monster::CheckGround( monsterPState_t &state ) { - trace_t groundTrace; - idVec3 down; - - if ( gravityNormal == vec3_zero ) { - state.onGround = false; - groundEntityPtr = NULL; - return; - } - - down = state.origin + gravityNormal * CONTACT_EPSILON; - gameLocal.clip.Translation( groundTrace, state.origin, down, clipModel, clipModel->GetAxis(), clipMask, self ); - - if ( groundTrace.fraction == 1.0f ) { - state.onGround = false; - groundEntityPtr = NULL; - return; - } - - groundEntityPtr = gameLocal.entities[ groundTrace.c.entityNum ]; - - if ( ( groundTrace.c.normal * -gravityNormal ) < minFloorCosine ) - { - // grayman #2356 - assumed to be sliding down an incline > 45 degrees, but could also - // be sitting on an angled piece of a func_static, so check current origin.z against - // previous origin.z to see if you're really sliding. This prevents excessive buildup - // of gravity-induced vertical velocity, which leads to death once you get free and - // fall to the ground, where Crashland() thinks you fell from a great height. - - idVec3 prevMove = static_cast(self)->movementSubsystem->GetLastMove(); - if (prevMove.z < 0) // are you truly falling? - { - state.onGround = false; - return; - } - } - - state.onGround = true; - - // let the entity know about the collision - self->Collide( groundTrace, state.velocity ); - - idEntity* groundEnt = groundEntityPtr.GetEntity(); - - // greebo: Apply force/impulse to entities below the clipmodel - if ( groundTrace.c.entityNum != ENTITYNUM_WORLD && groundEnt != NULL ) - { - idPhysics* groundPhysics = groundEnt->GetPhysics(); - - impactInfo_t info; - groundEnt->GetImpactInfo( self, groundTrace.c.id, groundTrace.c.point, &info ); - - // greebo: Don't push entities that already have a velocity towards the ground. - if ( groundPhysics && info.invMass != 0.0f ) - { - // grayman #2478 - is this a mine? if so, blow it up now instead of waiting - // for the Collide() code to blow it up. Waiting allows the physics engine - // to sink the mine into the floor before it blows. If the mine is not - // armed yet, nothing happens, but at least the mine isn't pushed into the floor. - - if ( groundEnt->IsType(idProjectile::Type) && static_cast(groundEnt)->IsMine() ) - { - static_cast(groundEnt)->MineExplode( self->entityNumber ); - } - else - { - // greebo: Apply a force to the entity below the player - //gameRenderWorld->DebugArrow(colorCyan, current.origin, current.origin + gravityNormal*20, 1, 16); - - // grayman TODO: When an AI steps on something and applies this force, it's - // possible that physics will cause the thing to fall through the floor. - // gameLocal.clip.Motion() might have a problem with something sitting flat - // on a world brush. - - groundPhysics->AddForce(0, current.origin, gravityNormal); - groundPhysics->Activate(); - } - } - } -} - -/* -===================== -idPhysics_Monster::SlideMove -===================== -*/ -monsterMoveResult_t idPhysics_Monster::SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) { - int i; - trace_t tr; - idVec3 move; - - blockingEntity = NULL; - move = delta; - for( i = 0; i < 3; i++ ) { - gameLocal.clip.Translation( tr, start, start + move, clipModel, clipModel->GetAxis(), clipMask, self ); - //gameRenderWorld->DebugArrow(colorWhite, start, tr.endpos, 2, 5000); - - start = tr.endpos; - - if ( tr.fraction == 1.0f ) { - if ( i > 0 ) { - return MM_SLIDING; - } - return MM_OK; - } - - if ( tr.c.entityNum != ENTITYNUM_NONE ) { - blockingEntity = gameLocal.entities[ tr.c.entityNum ]; - } - - // clip the movement delta and velocity - move.ProjectOntoPlane( tr.c.normal, OVERCLIP ); - velocity.ProjectOntoPlane( tr.c.normal, OVERCLIP ); - } - - return MM_BLOCKED; -} - -/* -===================== -idPhysics_Monster::StepMove - - move start into the delta direction - the velocity is clipped conform any collisions -===================== -*/ -monsterMoveResult_t idPhysics_Monster::StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) { - trace_t tr; - idVec3 up, down, noStepPos, noStepVel, stepPos, stepVel; - monsterMoveResult_t result1, result2; - float stepdist; - float nostepdist; - - if ( delta == vec3_origin ) { - return MM_OK; - } - - // try to move without stepping up - noStepPos = start; - noStepVel = velocity; - result1 = SlideMove( noStepPos, noStepVel, delta ); - if ( result1 == MM_OK ) { - velocity = noStepVel; - if ( gravityNormal == vec3_zero ) { - start = noStepPos; - return MM_OK; - } - - // try to step down so that we walk down slopes and stairs at a normal rate - down = noStepPos + gravityNormal * maxStepHeight; - gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); - if ( tr.fraction < 1.0f ) { - start = tr.endpos; - return MM_STEPPED; - } else { - start = noStepPos; - return MM_OK; - } - } - - if ( blockingEntity && blockingEntity->IsType( idActor::Type ) ) { - // try to step down in case walking into an actor while going down steps - down = noStepPos + gravityNormal * maxStepHeight; - gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); - start = tr.endpos; - velocity = noStepVel; - return MM_BLOCKED; - } - - if ( gravityNormal == vec3_zero ) { - return result1; - } - - // try to step up - up = start - gravityNormal * maxStepHeight; - gameLocal.clip.Translation( tr, start, up, clipModel, clipModel->GetAxis(), clipMask, self ); - //gameRenderWorld->DebugArrow(colorRed, start, up, 2, 5000); - if ( tr.fraction == 0.0f ) { - start = noStepPos; - velocity = noStepVel; - return result1; - } - - // try to move at the stepped up position - stepPos = tr.endpos; - stepVel = velocity; - result2 = SlideMove( stepPos, stepVel, delta ); - if ( result2 == MM_BLOCKED ) { - start = noStepPos; - velocity = noStepVel; - return result1; - } - - // step down again - down = stepPos + gravityNormal * maxStepHeight; - gameLocal.clip.Translation( tr, stepPos, down, clipModel, clipModel->GetAxis(), clipMask, self ); - //gameRenderWorld->DebugArrow(colorGreen, stepPos, down, 2, 5000); - //gameRenderWorld->DebugArrow(colorBlue, tr.c.point, tr.c.point + 5 * tr.c.normal, 2, 5000); - - float projection = tr.c.normal * -gravityNormal; - - // greebo: We have collided with a steep slope in front of us - if (projection < minFloorCosine && projection > 0.06f) - { - // greebo: Set the endposition a bit more upwards than necessary to prevent gravity from pulling us down immediately again - stepPos = tr.endpos - gravityNormal * stepUpIncrease; - } - else - { - // No slope, just use the step position - stepPos = tr.endpos; - } - - // if the move is further without stepping up, or the slope is too steep, don't step up - nostepdist = ( noStepPos - start ).LengthSqr(); - stepdist = ( stepPos - start ).LengthSqr(); - - // Use the position that brought us the largest forward movement - if (nostepdist >= stepdist) - { - start = noStepPos; - velocity = noStepVel; - return MM_SLIDING; - } - - - start = stepPos; - velocity = stepVel; - - return MM_STEPPED; -} - -/* -================ -idPhysics_Monster::Activate -================ -*/ -void idPhysics_Monster::Activate( void ) { - current.atRest = -1; - self->BecomeActive( TH_PHYSICS ); -} - -/* -================ -idPhysics_Monster::Rest -================ -*/ -void idPhysics_Monster::Rest( void ) { - current.atRest = gameLocal.time; - current.velocity.Zero(); - self->BecomeInactive( TH_PHYSICS ); -} - -/* -================ -idPhysics_Monster::PutToRest -================ -*/ -void idPhysics_Monster::PutToRest( void ) { - Rest(); -} - -/* -================ -idPhysics_Monster::idPhysics_Monster -================ -*/ -idPhysics_Monster::idPhysics_Monster( void ) { - - memset( ¤t, 0, sizeof( current ) ); - current.atRest = -1; - saved = current; - - delta.Zero(); - maxStepHeight = 18.0f; - stepUpIncrease = 10.0f; - minFloorCosine = 0.7f; - moveResult = MM_OK; - forceDeltaMove = false; - fly = false; - useVelocityMove = false; - noImpact = false; - blockingEntity = NULL; -} - -/* -================ -idPhysics_Monster_SavePState -================ -*/ -void idPhysics_Monster_SavePState( idSaveGame *savefile, const monsterPState_t &state ) { - savefile->WriteVec3( state.origin ); - savefile->WriteVec3( state.velocity ); - savefile->WriteVec3( state.localOrigin ); - savefile->WriteVec3( state.pushVelocity ); - savefile->WriteBool( state.onGround ); - savefile->WriteInt( state.atRest ); -} - -/* -================ -idPhysics_Monster_RestorePState -================ -*/ -void idPhysics_Monster_RestorePState( idRestoreGame *savefile, monsterPState_t &state ) { - savefile->ReadVec3( state.origin ); - savefile->ReadVec3( state.velocity ); - savefile->ReadVec3( state.localOrigin ); - savefile->ReadVec3( state.pushVelocity ); - savefile->ReadBool( state.onGround ); - savefile->ReadInt( state.atRest ); -} - -/* -================ -idPhysics_Monster::Save -================ -*/ -void idPhysics_Monster::Save( idSaveGame *savefile ) const { - - idPhysics_Monster_SavePState( savefile, current ); - idPhysics_Monster_SavePState( savefile, saved ); - - savefile->WriteFloat( maxStepHeight ); - savefile->WriteFloat(stepUpIncrease); - savefile->WriteFloat( minFloorCosine ); - savefile->WriteVec3( delta ); - - savefile->WriteBool( forceDeltaMove ); - savefile->WriteBool( fly ); - savefile->WriteBool( useVelocityMove ); - savefile->WriteBool( noImpact ); - - savefile->WriteInt( (int)moveResult ); - savefile->WriteObject( blockingEntity ); -} - -/* -================ -idPhysics_Monster::Restore -================ -*/ -void idPhysics_Monster::Restore( idRestoreGame *savefile ) { - - idPhysics_Monster_RestorePState( savefile, current ); - idPhysics_Monster_RestorePState( savefile, saved ); - - savefile->ReadFloat( maxStepHeight ); - savefile->ReadFloat(stepUpIncrease); - savefile->ReadFloat( minFloorCosine ); - savefile->ReadVec3( delta ); - - savefile->ReadBool( forceDeltaMove ); - savefile->ReadBool( fly ); - savefile->ReadBool( useVelocityMove ); - savefile->ReadBool( noImpact ); - - savefile->ReadInt( (int &)moveResult ); - savefile->ReadObject( reinterpret_cast( blockingEntity ) ); -} - -/* -================ -idPhysics_Monster::SetDelta -================ -*/ -void idPhysics_Monster::SetDelta( const idVec3 &d ) { - delta = d; - if ( delta != vec3_origin ) { - Activate(); - } -} - -/* -================ -idPhysics_Monster::SetMaxStepHeight -================ -*/ -void idPhysics_Monster::SetMaxStepHeight( const float newMaxStepHeight ) { - maxStepHeight = newMaxStepHeight; -} - -/* -================ -idPhysics_Monster::GetMaxStepHeight -================ -*/ -float idPhysics_Monster::GetMaxStepHeight( void ) const { - return maxStepHeight; -} - -void idPhysics_Monster::SetStepUpIncrease(float incr) { - stepUpIncrease = incr; -} - -/* -================ -idPhysics_Monster::OnGround -================ -*/ -bool idPhysics_Monster::OnGround( void ) const { - return current.onGround; -} - -/* -================ -idPhysics_Monster::GetSlideMoveEntity -================ -*/ -idEntity *idPhysics_Monster::GetSlideMoveEntity( void ) const { - return blockingEntity; -} - -/* -================ -idPhysics_Monster::GetMoveResult -================ -*/ -monsterMoveResult_t idPhysics_Monster::GetMoveResult( void ) const { - return moveResult; -} - -/* -================ -idPhysics_Monster::ForceDeltaMove -================ -*/ -void idPhysics_Monster::ForceDeltaMove( bool force ) { - forceDeltaMove = force; -} - -/* -================ -idPhysics_Monster::UseFlyMove -================ -*/ -void idPhysics_Monster::UseFlyMove( bool force ) { - fly = force; -} - -/* -================ -idPhysics_Monster::UseVelocityMove -================ -*/ -void idPhysics_Monster::UseVelocityMove( bool force ) { - useVelocityMove = force; -} - -/* -================ -idPhysics_Monster::EnableImpact -================ -*/ -void idPhysics_Monster::EnableImpact( void ) { - noImpact = false; -} - -/* -================ -idPhysics_Monster::DisableImpact -================ -*/ -void idPhysics_Monster::DisableImpact( void ) { - noImpact = true; -} - -/* -================ -idPhysics_Monster::Evaluate -================ -*/ -bool idPhysics_Monster::Evaluate( int timeStepMSec, int endTimeMSec ) { - - if (timeStepMSec == 0) - { - // angua: time step can be zero when the AI comes back from being dormant - return false; - } - - idVec3 masterOrigin, oldOrigin; - idMat3 masterAxis; - float timeStep; - -#ifdef MOD_WATERPHYSICS - waterLevel = WATERLEVEL_NONE; // MOD_WATERPHYSICS - waterType = 0; // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - - timeStep = MS2SEC( timeStepMSec ); - - moveResult = MM_OK; - blockingEntity = NULL; - oldOrigin = current.origin; - - // if bound to a master - if ( masterEntity ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + current.localOrigin * masterAxis; - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - current.velocity = ( current.origin - oldOrigin ) / timeStep; - masterDeltaYaw = masterYaw; - masterYaw = masterAxis[0].ToYaw(); - masterDeltaYaw = masterYaw - masterDeltaYaw; - return true; - } - - // if the monster is at rest - if ( current.atRest >= 0 ) { - return false; - } - - ActivateContactEntities(); - - // move the monster velocity into the frame of a pusher - current.velocity -= current.pushVelocity; - - clipModel->Unlink(); - -#ifdef MOD_WATERPHYSICS - // check water level / type - SetWaterLevel(true); // MOD_WATERPHYSICS -#endif // MOD_WATERPHYSICS - - // check if on the ground - idPhysics_Monster::CheckGround( current ); - - // if not on the ground or moving upwards - float upspeed; - if ( gravityNormal != vec3_zero ) { - upspeed = -( current.velocity * gravityNormal ); - } else { - upspeed = current.velocity.z; - } - if ( fly || ( !forceDeltaMove && ( !current.onGround || upspeed > 1.0f ) ) ) { - if ( upspeed < 0.0f ) { - moveResult = MM_FALLING; - } - else { - current.onGround = false; - moveResult = MM_OK; - } - delta = current.velocity * timeStep; - if ( delta != vec3_origin ) { - moveResult = idPhysics_Monster::SlideMove( current.origin, current.velocity, delta ); - delta.Zero(); - } - - if ( !fly ) { - current.velocity += gravityVector * timeStep; - } - } else { - if ( useVelocityMove ) { - delta = current.velocity * timeStep; - } else { - current.velocity = delta / timeStep; - } - - current.velocity -= ( current.velocity * gravityNormal ) * gravityNormal; - - if ( delta == vec3_origin ) { - Rest(); - } else { - // try moving into the desired direction - moveResult = idPhysics_Monster::StepMove( current.origin, current.velocity, delta ); - delta.Zero(); - } - } - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - - // get all the ground contacts - EvaluateContacts(); - - // move the monster velocity back into the world frame - current.velocity += current.pushVelocity; - current.pushVelocity.Zero(); - - if ( IsOutsideWorld() ) { - gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) ); - Rest(); - } - - return ( current.origin != oldOrigin ); -} - -/* -================ -idPhysics_Monster::UpdateTime -================ -*/ -void idPhysics_Monster::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_Monster::GetTime -================ -*/ -int idPhysics_Monster::GetTime( void ) const { - return gameLocal.time; -} - -/* -================ -idPhysics_Monster::GetImpactInfo -================ -*/ -void idPhysics_Monster::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - info->invMass = invMass; - info->invInertiaTensor.Zero(); - info->position.Zero(); - info->velocity = current.velocity; -} - -/* -================ -idPhysics_Monster::ApplyImpulse -================ -*/ -void idPhysics_Monster::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - if ( noImpact ) { - return; - } - current.velocity += impulse * invMass; - Activate(); -} - -/* -================ -idPhysics_Monster::IsAtRest -================ -*/ -bool idPhysics_Monster::IsAtRest( void ) const { - return current.atRest >= 0; -} - -/* -================ -idPhysics_Monster::GetRestStartTime -================ -*/ -int idPhysics_Monster::GetRestStartTime( void ) const { - return current.atRest; -} - -/* -================ -idPhysics_Monster::SaveState -================ -*/ -void idPhysics_Monster::SaveState( void ) { - saved = current; -} - -/* -================ -idPhysics_Monster::RestoreState -================ -*/ -void idPhysics_Monster::RestoreState( void ) { - current = saved; - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - - EvaluateContacts(); -} - -/* -================ -idPhysics_Player::SetOrigin -================ -*/ -void idPhysics_Monster::SetOrigin( const idVec3 &newOrigin, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localOrigin = newOrigin; - if ( masterEntity ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + newOrigin * masterAxis; - } - else { - current.origin = newOrigin; - } - clipModel->Link( gameLocal.clip, self, 0, newOrigin, clipModel->GetAxis() ); - Activate(); -} - -/* -================ -idPhysics_Player::SetAxis -================ -*/ -void idPhysics_Monster::SetAxis( const idMat3 &newAxis, int id ) { - clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), newAxis ); - Activate(); -} - -/* -================ -idPhysics_Monster::Translate -================ -*/ -void idPhysics_Monster::Translate( const idVec3 &translation, int id ) { - - current.localOrigin += translation; - current.origin += translation; - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - Activate(); -} - -/* -================ -idPhysics_Monster::Rotate -================ -*/ -void idPhysics_Monster::Rotate( const idRotation &rotation, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.origin *= rotation; - if ( masterEntity ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - } - else { - current.localOrigin = current.origin; - } - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() * rotation.ToMat3() ); - Activate(); -} - -/* -================ -idPhysics_Monster::SetLinearVelocity -================ -*/ -void idPhysics_Monster::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { - current.velocity = newLinearVelocity; - Activate(); -} - -/* -================ -idPhysics_Monster::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_Monster::GetLinearVelocity( int id ) const { - return current.velocity; -} - -/* -================ -idPhysics_Monster::SetPushed -================ -*/ -void idPhysics_Monster::SetPushed( int deltaTime ) { - // velocity with which the monster is pushed - current.pushVelocity += ( current.origin - saved.origin ) / ( deltaTime * idMath::M_MS2SEC ); -} - -/* -================ -idPhysics_Monster::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_Monster::GetPushedLinearVelocity( const int id ) const { - return current.pushVelocity; -} - -/* -================ -idPhysics_Monster::SetMaster - - the binding is never orientated -================ -*/ -void idPhysics_Monster::SetMaster( idEntity *master, const bool orientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !masterEntity ) { - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - masterEntity = master; - masterYaw = masterAxis[0].ToYaw(); - } - ClearContacts(); - } - else { - if ( masterEntity ) { - masterEntity = NULL; - Activate(); - } - } -} - -const float MONSTER_VELOCITY_MAX = 4000; -const int MONSTER_VELOCITY_TOTAL_BITS = 16; -const int MONSTER_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( MONSTER_VELOCITY_MAX ) ) + 1; -const int MONSTER_VELOCITY_MANTISSA_BITS = MONSTER_VELOCITY_TOTAL_BITS - 1 - MONSTER_VELOCITY_EXPONENT_BITS; - -/* -================ -idPhysics_Monster::WriteToSnapshot -================ -*/ -void idPhysics_Monster::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteFloat( current.origin[0] ); - msg.WriteFloat( current.origin[1] ); - msg.WriteFloat( current.origin[2] ); - msg.WriteFloat( current.velocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteFloat( current.velocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteFloat( current.velocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); - msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); - msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - msg.WriteLong( current.atRest ); - msg.WriteBits( current.onGround, 1 ); -} - -/* -================ -idPhysics_Monster::ReadFromSnapshot -================ -*/ -void idPhysics_Monster::ReadFromSnapshot( const idBitMsgDelta &msg ) { - current.origin[0] = msg.ReadFloat(); - current.origin[1] = msg.ReadFloat(); - current.origin[2] = msg.ReadFloat(); - current.velocity[0] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.velocity[1] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.velocity[2] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); - current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); - current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); - current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); - current.atRest = msg.ReadLong(); - current.onGround = msg.ReadBits( 1 ) != 0; -} diff --git a/game/physics/physics_monster.h b/game/physics/physics_monster.h deleted file mode 100644 index c6df89d1a..000000000 --- a/game/physics/physics_monster.h +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_MONSTER_H__ -#define __PHYSICS_MONSTER_H__ - -/* -=================================================================================== - - Monster physics - - Simulates the motion of a monster through the environment. The monster motion - is typically driven by animations. - -=================================================================================== -*/ - -typedef enum { - MM_OK, - MM_SLIDING, - MM_BLOCKED, - MM_STEPPED, - MM_FALLING -} monsterMoveResult_t; - -typedef struct monsterPState_s { - int atRest; - bool onGround; - idVec3 origin; - idVec3 velocity; - idVec3 localOrigin; - idVec3 pushVelocity; -} monsterPState_t; - -class idPhysics_Monster : public idPhysics_Actor { - -public: - CLASS_PROTOTYPE( idPhysics_Monster ); - - idPhysics_Monster( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // maximum step up the monster can take, default 18 units - void SetMaxStepHeight( const float newMaxStepHeight ); - float GetMaxStepHeight( void ) const; - - // Translates the entity upwards by this amount when stepping up to fight gravity during stepping - void SetStepUpIncrease(float incr); - - // minimum cosine of floor angle to be able to stand on the floor - void SetMinFloorCosine( const float newMinFloorCosine ); - // set delta for next move - void SetDelta( const idVec3 &d ); - // returns true if monster is standing on the ground - bool OnGround( void ) const; - // returns the movement result - monsterMoveResult_t GetMoveResult( void ) const; - // overrides any velocity for pure delta movement - void ForceDeltaMove( bool force ); - // whether velocity should be affected by gravity - void UseFlyMove( bool force ); - // don't use delta movement - void UseVelocityMove( bool force ); - // get entity blocking the move - idEntity * GetSlideMoveEntity( void ) const; - // enable/disable activation by impact - void EnableImpact( void ); - void DisableImpact( void ); - -public: // common physics interface - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - void Activate( void ); - void PutToRest( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated = true ); - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -private: - // monster physics state - monsterPState_t current; - monsterPState_t saved; - - // properties - float maxStepHeight; // maximum step height - float stepUpIncrease; // translates origin upwards by this amount when stepping - float minFloorCosine; // minimum cosine of floor angle - idVec3 delta; // delta for next move - - bool forceDeltaMove; - bool fly; - bool useVelocityMove; - bool noImpact; // if true do not activate when another object collides - - // results of last evaluate - monsterMoveResult_t moveResult; - idEntity * blockingEntity; - -private: - void CheckGround( monsterPState_t &state ); - monsterMoveResult_t SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ); - monsterMoveResult_t StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ); - void Rest( void ); -}; - -#endif /* !__PHYSICS_MONSTER_H__ */ diff --git a/game/physics/physics_parametric.cpp b/game/physics/physics_parametric.cpp deleted file mode 100644 index 847203f58..000000000 --- a/game/physics/physics_parametric.cpp +++ /dev/null @@ -1,1203 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics_Base, idPhysics_Parametric ) -END_CLASS - - -/* -================ -idPhysics_Parametric::Activate -================ -*/ -void idPhysics_Parametric::Activate( void ) { - current.atRest = -1; - self->BecomeActive( TH_PHYSICS ); -} - -/* -================ -idPhysics_Parametric::TestIfAtRest -================ -*/ -bool idPhysics_Parametric::TestIfAtRest( void ) const { - - if ( ( current.linearExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && - ( current.angularExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE && - current.linearInterpolation.GetDuration() == 0 && - current.angularInterpolation.GetDuration() == 0 && - current.spline == NULL ) { - return true; - } - - if ( !current.linearExtrapolation.IsDone( current.time ) ) { - return false; - } - - if ( !current.angularExtrapolation.IsDone( current.time ) ) { - return false; - } - - if ( !current.linearInterpolation.IsDone( current.time ) ) { - return false; - } - - if ( !current.angularInterpolation.IsDone( current.time ) ) { - return false; - } - - if ( current.spline != NULL && !current.spline->IsDone( current.time ) ) { - return false; - } - - return true; -} - -/* -================ -idPhysics_Parametric::Rest -================ -*/ -void idPhysics_Parametric::Rest( void ) { - current.atRest = gameLocal.time; - self->BecomeInactive( TH_PHYSICS ); -} - -/* -================ -idPhysics_Parametric::idPhysics_Parametric -================ -*/ -idPhysics_Parametric::idPhysics_Parametric( void ) { - - current.time = gameLocal.time; - current.atRest = -1; - current.useSplineAngles = false; - current.origin.Zero(); - current.angles.Zero(); - current.axis.Identity(); - current.localOrigin.Zero(); - current.localAngles.Zero(); - current.linearExtrapolation.Init( 0, 0, vec3_zero, vec3_zero, vec3_zero, EXTRAPOLATION_NONE ); - current.angularExtrapolation.Init( 0, 0, ang_zero, ang_zero, ang_zero, EXTRAPOLATION_NONE ); - current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); - current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); - current.spline = NULL; - current.splineInterpolate.Init( 0, 1, 1, 2, 0, 0 ); - - saved = current; - - isPusher = false; - pushFlags = 0; - clipModel = NULL; - isBlocked = false; - memset( &pushResults, 0, sizeof( pushResults ) ); - - hasMaster = false; - isOrientated = false; -} - -/* -================ -idPhysics_Parametric::~idPhysics_Parametric -================ -*/ -idPhysics_Parametric::~idPhysics_Parametric( void ) { - if ( clipModel != NULL ) { - delete clipModel; - clipModel = NULL; - } - if ( current.spline != NULL ) { - delete current.spline; - current.spline = NULL; - } -} - -/* -================ -idPhysics_Parametric_SavePState -================ -*/ -void idPhysics_Parametric_SavePState( idSaveGame *savefile, const parametricPState_t &state ) { - savefile->WriteInt( state.time ); - savefile->WriteInt( state.atRest ); - savefile->WriteBool( state.useSplineAngles ); - savefile->WriteVec3( state.origin ); - savefile->WriteAngles( state.angles ); - savefile->WriteMat3( state.axis ); - savefile->WriteVec3( state.localOrigin ); - savefile->WriteAngles( state.localAngles ); - - savefile->WriteInt( (int)state.linearExtrapolation.GetExtrapolationType() ); - savefile->WriteFloat( state.linearExtrapolation.GetStartTime() ); - savefile->WriteFloat( state.linearExtrapolation.GetDuration() ); - savefile->WriteVec3( state.linearExtrapolation.GetStartValue() ); - savefile->WriteVec3( state.linearExtrapolation.GetBaseSpeed() ); - savefile->WriteVec3( state.linearExtrapolation.GetSpeed() ); - - savefile->WriteInt( (int)state.angularExtrapolation.GetExtrapolationType() ); - savefile->WriteFloat( state.angularExtrapolation.GetStartTime() ); - savefile->WriteFloat( state.angularExtrapolation.GetDuration() ); - savefile->WriteAngles( state.angularExtrapolation.GetStartValue() ); - savefile->WriteAngles( state.angularExtrapolation.GetBaseSpeed() ); - savefile->WriteAngles( state.angularExtrapolation.GetSpeed() ); - - savefile->WriteFloat( state.linearInterpolation.GetStartTime() ); - savefile->WriteFloat( state.linearInterpolation.GetAcceleration() ); - savefile->WriteFloat( state.linearInterpolation.GetDeceleration() ); - savefile->WriteFloat( state.linearInterpolation.GetDuration() ); - savefile->WriteVec3( state.linearInterpolation.GetStartValue() ); - savefile->WriteVec3( state.linearInterpolation.GetEndValue() ); - - savefile->WriteFloat( state.angularInterpolation.GetStartTime() ); - savefile->WriteFloat( state.angularInterpolation.GetAcceleration() ); - savefile->WriteFloat( state.angularInterpolation.GetDeceleration() ); - savefile->WriteFloat( state.angularInterpolation.GetDuration() ); - savefile->WriteAngles( state.angularInterpolation.GetStartValue() ); - savefile->WriteAngles( state.angularInterpolation.GetEndValue() ); - - // spline is handled by owner - - savefile->WriteFloat( state.splineInterpolate.GetStartTime() ); - savefile->WriteFloat( state.splineInterpolate.GetAcceleration() ); - savefile->WriteFloat( state.splineInterpolate.GetDuration() ); - savefile->WriteFloat( state.splineInterpolate.GetDeceleration() ); - savefile->WriteFloat( state.splineInterpolate.GetStartValue() ); - savefile->WriteFloat( state.splineInterpolate.GetEndValue() ); -} - -/* -================ -idPhysics_Parametric_RestorePState -================ -*/ -void idPhysics_Parametric_RestorePState( idRestoreGame *savefile, parametricPState_t &state ) { - extrapolation_t etype; - float startTime, duration, accelTime, decelTime, startValue, endValue; - idVec3 linearStartValue, linearBaseSpeed, linearSpeed, startPos, endPos; - idAngles angularStartValue, angularBaseSpeed, angularSpeed, startAng, endAng; - - savefile->ReadInt( state.time ); - savefile->ReadInt( state.atRest ); - savefile->ReadBool( state.useSplineAngles ); - savefile->ReadVec3( state.origin ); - savefile->ReadAngles( state.angles ); - savefile->ReadMat3( state.axis ); - savefile->ReadVec3( state.localOrigin ); - savefile->ReadAngles( state.localAngles ); - - savefile->ReadInt( (int &)etype ); - savefile->ReadFloat( startTime ); - savefile->ReadFloat( duration ); - savefile->ReadVec3( linearStartValue ); - savefile->ReadVec3( linearBaseSpeed ); - savefile->ReadVec3( linearSpeed ); - - state.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, etype ); - - savefile->ReadInt( (int &)etype ); - savefile->ReadFloat( startTime ); - savefile->ReadFloat( duration ); - savefile->ReadAngles( angularStartValue ); - savefile->ReadAngles( angularBaseSpeed ); - savefile->ReadAngles( angularSpeed ); - - state.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, etype ); - - savefile->ReadFloat( startTime ); - savefile->ReadFloat( accelTime ); - savefile->ReadFloat( decelTime ); - savefile->ReadFloat( duration ); - savefile->ReadVec3( startPos ); - savefile->ReadVec3( endPos ); - - state.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos ); - - savefile->ReadFloat( startTime ); - savefile->ReadFloat( accelTime ); - savefile->ReadFloat( decelTime ); - savefile->ReadFloat( duration ); - savefile->ReadAngles( startAng ); - savefile->ReadAngles( endAng ); - - state.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng ); - - // spline is handled by owner - - savefile->ReadFloat( startTime ); - savefile->ReadFloat( accelTime ); - savefile->ReadFloat( duration ); - savefile->ReadFloat( decelTime ); - savefile->ReadFloat( startValue ); - savefile->ReadFloat( endValue ); - - state.splineInterpolate.Init( startTime, accelTime, decelTime, duration, startValue, endValue ); -} - -/* -================ -idPhysics_Parametric::Save -================ -*/ -void idPhysics_Parametric::Save( idSaveGame *savefile ) const { - - idPhysics_Parametric_SavePState( savefile, current ); - idPhysics_Parametric_SavePState( savefile, saved ); - - savefile->WriteBool( isPusher ); - savefile->WriteClipModel( clipModel ); - savefile->WriteInt( pushFlags ); - - savefile->WriteTrace( pushResults ); - savefile->WriteBool( isBlocked ); - - savefile->WriteBool( hasMaster ); - savefile->WriteBool( isOrientated ); -} - -/* -================ -idPhysics_Parametric::Restore -================ -*/ -void idPhysics_Parametric::Restore( idRestoreGame *savefile ) { - - idPhysics_Parametric_RestorePState( savefile, current ); - idPhysics_Parametric_RestorePState( savefile, saved ); - - savefile->ReadBool( isPusher ); - savefile->ReadClipModel( clipModel ); - savefile->ReadInt( pushFlags ); - - savefile->ReadTrace( pushResults ); - savefile->ReadBool( isBlocked ); - - savefile->ReadBool( hasMaster ); - savefile->ReadBool( isOrientated ); -} - -/* -================ -idPhysics_Parametric::SetPusher -================ -*/ -void idPhysics_Parametric::SetPusher( int flags ) { - assert( clipModel ); - isPusher = true; - pushFlags = flags; -} - -/* -================ -idPhysics_Parametric::IsPusher -================ -*/ -bool idPhysics_Parametric::IsPusher( void ) const { - return isPusher; -} - -/* -================ -idPhysics_Parametric::SetLinearExtrapolation -================ -*/ -void idPhysics_Parametric::SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ) { - current.time = gameLocal.time; - current.linearExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); - current.localOrigin = base; - Activate(); -} - -/* -================ -idPhysics_Parametric::SetAngularExtrapolation -================ -*/ -void idPhysics_Parametric::SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ) { - current.time = gameLocal.time; - current.angularExtrapolation.Init( time, duration, base, baseSpeed, speed, type ); - current.localAngles = base; - Activate(); -} - -/* -================ -idPhysics_Parametric::GetLinearExtrapolationType -================ -*/ -extrapolation_t idPhysics_Parametric::GetLinearExtrapolationType( void ) const { - return current.linearExtrapolation.GetExtrapolationType(); -} - -/* -================ -idPhysics_Parametric::GetAngularExtrapolationType -================ -*/ -extrapolation_t idPhysics_Parametric::GetAngularExtrapolationType( void ) const { - return current.angularExtrapolation.GetExtrapolationType(); -} - -/* -================ -idPhysics_Parametric::SetLinearInterpolation -================ -*/ -void idPhysics_Parametric::SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ) { - current.time = gameLocal.time; - current.linearInterpolation.Init( time, accelTime, decelTime, duration, startPos, endPos ); - current.localOrigin = startPos; - Activate(); -} - -/* -================ -idPhysics_Parametric::SetAngularInterpolation -================ -*/ -void idPhysics_Parametric::SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ) { - current.time = gameLocal.time; - current.angularInterpolation.Init( time, accelTime, decelTime, duration, startAng, endAng ); - current.localAngles = startAng; - Activate(); -} - -/* -================ -idPhysics_Parametric::SetSpline -================ -*/ -void idPhysics_Parametric::SetSpline( idCurve_Spline *spline, int accelTime, int decelTime, bool useSplineAngles ) { - if ( current.spline != NULL ) { - delete current.spline; - current.spline = NULL; - } - current.spline = spline; - if ( current.spline != NULL ) { - float startTime = current.spline->GetTime( 0 ); - float endTime = current.spline->GetTime( current.spline->GetNumValues() - 1 ); - float length = current.spline->GetLengthForTime( endTime ); - current.splineInterpolate.Init( startTime, accelTime, decelTime, endTime - startTime, 0.0f, length ); - } - current.useSplineAngles = useSplineAngles; - Activate(); -} - -/* -================ -idPhysics_Parametric::GetSpline -================ -*/ -idCurve_Spline *idPhysics_Parametric::GetSpline( void ) const { - return current.spline; -} - -/* -================ -idPhysics_Parametric::GetSplineAcceleration -================ -*/ -int idPhysics_Parametric::GetSplineAcceleration( void ) const { - return static_cast(current.splineInterpolate.GetAcceleration()); -} - -/* -================ -idPhysics_Parametric::GetSplineDeceleration -================ -*/ -int idPhysics_Parametric::GetSplineDeceleration( void ) const { - return static_cast(current.splineInterpolate.GetDeceleration()); -} - -/* -================ -idPhysics_Parametric::UsingSplineAngles -================ -*/ -bool idPhysics_Parametric::UsingSplineAngles( void ) const { - return current.useSplineAngles; -} - -/* -================ -idPhysics_Parametric::GetLocalOrigin -================ -*/ -void idPhysics_Parametric::GetLocalOrigin( idVec3 &curOrigin ) const { - curOrigin = current.localOrigin; -} - -const idVec3& idPhysics_Parametric::GetLocalOrigin() const { - return current.localOrigin; -} - -/* -================ -idPhysics_Parametric::GetLocalAngles -================ -*/ -void idPhysics_Parametric::GetLocalAngles( idAngles &curAngles ) const { - curAngles = current.localAngles; -} - -const idAngles& idPhysics_Parametric::GetLocalAngles() const -{ - return current.localAngles; -} - -void idPhysics_Parametric:: SetLocalAngles(idAngles curAngles) -{ - current.localAngles = curAngles; - - current.angularExtrapolation.SetStartValue( current.localAngles ); - current.angularInterpolation.SetStartValue( current.localAngles ); - - current.localAngles = current.angularExtrapolation.GetCurrentValue( current.time ); - if ( hasMaster && isOrientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - self->GetMasterPosition( masterOrigin, masterAxis ); - current.axis = current.localAngles.ToMat3() * masterAxis; - current.angles = current.axis.ToAngles(); - } - else { - current.axis = current.localAngles.ToMat3(); - current.angles = current.localAngles; - } - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } - Activate(); -} - - -/* -================ -idPhysics_Parametric::SetClipModel -================ -*/ -void idPhysics_Parametric::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { - - assert( self ); - assert( model ); - - if ( clipModel && clipModel != model && freeOld ) { - delete clipModel; - } - clipModel = model; - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); -} - -/* -================ -idPhysics_Parametric::GetClipModel -================ -*/ -idClipModel *idPhysics_Parametric::GetClipModel( int id ) const { - return clipModel; -} - -/* -================ -idPhysics_Parametric::GetNumClipModels -================ -*/ -int idPhysics_Parametric::GetNumClipModels( void ) const { - return ( clipModel != NULL ); -} - -/* -================ -idPhysics_Parametric::SetMass -================ -*/ -void idPhysics_Parametric::SetMass( float mass, int id ) { -} - -/* -================ -idPhysics_Parametric::GetMass -================ -*/ -float idPhysics_Parametric::GetMass( int id ) const { - return 0.0f; -} - -/* -================ -idPhysics_Parametric::SetClipMask -================ -*/ -void idPhysics_Parametric::SetContents( int contents, int id ) { - if ( clipModel ) { - clipModel->SetContents( contents ); - } -} - -/* -================ -idPhysics_Parametric::SetClipMask -================ -*/ -int idPhysics_Parametric::GetContents( int id ) const { - if ( clipModel ) { - return clipModel->GetContents(); - } - return 0; -} - -/* -================ -idPhysics_Parametric::GetBounds -================ -*/ -const idBounds &idPhysics_Parametric::GetBounds( int id ) const { - if ( clipModel ) { - return clipModel->GetBounds(); - } - return idPhysics_Base::GetBounds(); -} - -/* -================ -idPhysics_Parametric::GetAbsBounds -================ -*/ -const idBounds &idPhysics_Parametric::GetAbsBounds( int id ) const { - if ( clipModel ) { - return clipModel->GetAbsBounds(); - } - return idPhysics_Base::GetAbsBounds(); -} - -/* -================ -idPhysics_Parametric::Evaluate -================ -*/ -bool idPhysics_Parametric::Evaluate( int timeStepMSec, int endTimeMSec ) { - idVec3 oldLocalOrigin, oldOrigin, masterOrigin; - idAngles oldLocalAngles, oldAngles; - idMat3 oldAxis, masterAxis; - - isBlocked = false; - oldLocalOrigin = current.localOrigin; - oldOrigin = current.origin; - oldLocalAngles = current.localAngles; - oldAngles = current.angles; - oldAxis = current.axis; - - current.localOrigin.Zero(); - current.localAngles.Zero(); - - if ( current.spline != NULL ) { - float length = current.splineInterpolate.GetCurrentValue( endTimeMSec ); - float t = current.spline->GetTimeForLength( length, 0.01f ); - current.localOrigin = current.spline->GetCurrentValue( t ); - if ( current.useSplineAngles ) { - current.localAngles = current.spline->GetCurrentFirstDerivative( t ).ToAngles(); - } - } else if ( current.linearInterpolation.GetDuration() != 0 ) { - current.localOrigin += current.linearInterpolation.GetCurrentValue( endTimeMSec ); - } else { - current.localOrigin += current.linearExtrapolation.GetCurrentValue( endTimeMSec ); - } - - if ( current.angularInterpolation.GetDuration() != 0 ) { - current.localAngles += current.angularInterpolation.GetCurrentValue( endTimeMSec ); - } else { - current.localAngles += current.angularExtrapolation.GetCurrentValue( endTimeMSec ); - } - - current.localAngles.Normalize360(); - current.origin = current.localOrigin; - current.angles = current.localAngles; - current.axis = current.localAngles.ToMat3(); - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - if ( masterAxis.IsRotated() ) { - current.origin = current.origin * masterAxis + masterOrigin; - if ( isOrientated ) { - current.axis *= masterAxis; - current.angles = current.axis.ToAngles(); - } - } - else { - current.origin += masterOrigin; - } - } - - if ( isPusher ) { - - gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis ); - if ( pushResults.fraction < 1.0f ) { - clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis ); - current.localOrigin = oldLocalOrigin; - current.origin = oldOrigin; - current.localAngles = oldLocalAngles; - current.angles = oldAngles; - current.axis = oldAxis; - isBlocked = true; - return false; - } - - current.angles = current.axis.ToAngles(); - } - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } - - current.time = endTimeMSec; - - if ( TestIfAtRest() ) { - Rest(); - } - - return ( current.origin != oldOrigin || current.axis != oldAxis ); -} - -/* -================ -idPhysics_Parametric::UpdateTime -================ -*/ -void idPhysics_Parametric::UpdateTime( int endTimeMSec ) { - int timeLeap = endTimeMSec - current.time; - - current.time = endTimeMSec; - // move the trajectory start times to sync the trajectory with the current endTime - current.linearExtrapolation.SetStartTime( current.linearExtrapolation.GetStartTime() + timeLeap ); - current.angularExtrapolation.SetStartTime( current.angularExtrapolation.GetStartTime() + timeLeap ); - current.linearInterpolation.SetStartTime( current.linearInterpolation.GetStartTime() + timeLeap ); - current.angularInterpolation.SetStartTime( current.angularInterpolation.GetStartTime() + timeLeap ); - if ( current.spline != NULL ) { - current.spline->ShiftTime( timeLeap ); - current.splineInterpolate.SetStartTime( current.splineInterpolate.GetStartTime() + timeLeap ); - } -} - -/* -================ -idPhysics_Parametric::GetTime -================ -*/ -int idPhysics_Parametric::GetTime( void ) const { - return current.time; -} - -/* -================ -idPhysics_Parametric::IsAtRest -================ -*/ -bool idPhysics_Parametric::IsAtRest( void ) const { - return current.atRest >= 0; -} - -/* -================ -idPhysics_Parametric::GetRestStartTime -================ -*/ -int idPhysics_Parametric::GetRestStartTime( void ) const { - return current.atRest; -} - -/* -================ -idPhysics_Parametric::IsPushable -================ -*/ -bool idPhysics_Parametric::IsPushable( void ) const { - return false; -} - -/* -================ -idPhysics_Parametric::SaveState -================ -*/ -void idPhysics_Parametric::SaveState( void ) { - saved = current; -} - -/* -================ -idPhysics_Parametric::RestoreState -================ -*/ -void idPhysics_Parametric::RestoreState( void ) { - - current = saved; - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Parametric::SetOrigin -================ -*/ -void idPhysics_Parametric::SetOrigin( const idVec3 &newOrigin, int id ) { - - current.linearExtrapolation.SetStartValue( newOrigin ); - current.linearInterpolation.SetStartValue( newOrigin ); - - current.localOrigin = current.linearExtrapolation.GetCurrentValue( current.time ); - if ( hasMaster ) { - idVec3 masterOrigin; - idMat3 masterAxis; - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + current.localOrigin * masterAxis; - } - else { - current.origin = current.localOrigin; - } - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } - Activate(); -} - -void idPhysics_Parametric::SetLocalOrigin( const idVec3 &newOrigin) { - current.localOrigin = newOrigin; - if ( hasMaster ) { - idVec3 masterOrigin; - idMat3 masterAxis; - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + current.localOrigin * masterAxis; - } - else { - current.origin = current.localOrigin; - } - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } - - current.linearExtrapolation.SetStartValue( current.localOrigin ); - current.linearInterpolation.SetStartValue( current.localOrigin ); - - Activate(); -} - - -/* -================ -idPhysics_Parametric::SetAxis -================ -*/ -void idPhysics_Parametric::SetAxis( const idMat3 &newAxis, int id ) { - SetLocalAngles(newAxis.ToAngles()); -} - -/* -================ -idPhysics_Parametric::Move -================ -*/ -void idPhysics_Parametric::Translate( const idVec3 &translation, int id ) { -} - -/* -================ -idPhysics_Parametric::Rotate -================ -*/ -void idPhysics_Parametric::Rotate( const idRotation &rotation, int id ) { -} - -/* -================ -idPhysics_Parametric::GetOrigin -================ -*/ -const idVec3 &idPhysics_Parametric::GetOrigin( int id ) const { - return current.origin; -} - -/* -================ -idPhysics_Parametric::GetAxis -================ -*/ -const idMat3 &idPhysics_Parametric::GetAxis( int id ) const { - return current.axis; -} - -/* -================ -idPhysics_Parametric::GetAngles -================ -*/ -void idPhysics_Parametric::GetAngles( idAngles &curAngles ) const { - curAngles = current.angles; -} - -/* -================ -idPhysics_Parametric::SetLinearVelocity -================ -*/ -void idPhysics_Parametric::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { - SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.origin, newLinearVelocity, vec3_origin ); - current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero ); - Activate(); -} - -/* -================ -idPhysics_Parametric::SetAngularVelocity -================ -*/ -void idPhysics_Parametric::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { - idRotation rotation; - idVec3 vec; - float angle; - - vec = newAngularVelocity; - angle = vec.Normalize(); - rotation.Set( vec3_origin, vec, (float) RAD2DEG( angle ) ); - - SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.angles, rotation.ToAngles(), ang_zero ); - current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero ); - Activate(); -} - -/* -================ -idPhysics_Parametric::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_Parametric::GetLinearVelocity( int id ) const { - static idVec3 curLinearVelocity; - - curLinearVelocity = current.linearExtrapolation.GetCurrentSpeed( gameLocal.time ); - return curLinearVelocity; -} - -/* -================ -idPhysics_Parametric::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_Parametric::GetAngularVelocity( int id ) const { - static idVec3 curAngularVelocity; - idAngles angles; - - angles = current.angularExtrapolation.GetCurrentSpeed( gameLocal.time ); - curAngularVelocity = angles.ToAngularVelocity(); - return curAngularVelocity; -} - -/* -================ -idPhysics_Parametric::DisableClip -================ -*/ -void idPhysics_Parametric::DisableClip( void ) { - if ( clipModel ) { - clipModel->Disable(); - } -} - -/* -================ -idPhysics_Parametric::EnableClip -================ -*/ -void idPhysics_Parametric::EnableClip( void ) { - if ( clipModel ) { - clipModel->Enable(); - } -} - -/* -================ -idPhysics_Parametric::UnlinkClip -================ -*/ -void idPhysics_Parametric::UnlinkClip( void ) { - if ( clipModel ) { - clipModel->Unlink(); - } -} - -/* -================ -idPhysics_Parametric::LinkClip -================ -*/ -void idPhysics_Parametric::LinkClip( void ) { - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Parametric::GetBlockingInfo -================ -*/ -const trace_t *idPhysics_Parametric::GetBlockingInfo( void ) const { - return ( isBlocked ? &pushResults : NULL ); -} - -/* -================ -idPhysics_Parametric::GetBlockingEntity -================ -*/ -idEntity *idPhysics_Parametric::GetBlockingEntity( void ) const { - if ( isBlocked ) { - return gameLocal.entities[ pushResults.c.entityNum ]; - } - return NULL; -} - -/* -================ -idPhysics_Parametric::SetMaster -================ -*/ -void idPhysics_Parametric::SetMaster( idEntity *master, const bool orientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !hasMaster ) { - - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - if ( orientated ) { - current.localAngles = ( current.axis * masterAxis.Transpose() ).ToAngles(); - } - else { - current.localAngles = current.axis.ToAngles(); - } - - current.linearExtrapolation.SetStartValue( current.localOrigin ); - current.angularExtrapolation.SetStartValue( current.localAngles ); - hasMaster = true; - isOrientated = orientated; - } - } - else { - if ( hasMaster ) { - // transform from master space to world space - current.localOrigin = current.origin; - current.localAngles = current.angles; - SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.origin, vec3_origin, vec3_origin ); - SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.angles, ang_zero, ang_zero ); - hasMaster = false; - } - } -} - -/* -================ -idPhysics_Parametric::GetLinearEndTime -================ -*/ -int idPhysics_Parametric::GetLinearEndTime( void ) const { - if ( current.spline != NULL ) { - if ( current.spline->GetBoundaryType() != idCurve_Spline::BT_CLOSED ) { - return static_cast(current.spline->GetTime( current.spline->GetNumValues() - 1 )); - } else { - return 0; - } - } else if ( current.linearInterpolation.GetDuration() != 0 ) { - return static_cast(current.linearInterpolation.GetEndTime()); - } else { - return static_cast(current.linearExtrapolation.GetEndTime()); - } -} - -/* -================ -idPhysics_Parametric::GetAngularEndTime -================ -*/ -int idPhysics_Parametric::GetAngularEndTime( void ) const { - if ( current.angularInterpolation.GetDuration() != 0 ) { - return static_cast(current.angularInterpolation.GetEndTime()); - } else { - return static_cast(current.angularExtrapolation.GetEndTime()); - } -} - -/* -================ -idPhysics_Parametric::WriteToSnapshot -================ -*/ -void idPhysics_Parametric::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteLong( current.time ); - msg.WriteLong( current.atRest ); - msg.WriteFloat( current.origin[0] ); - msg.WriteFloat( current.origin[1] ); - msg.WriteFloat( current.origin[2] ); - msg.WriteFloat( current.angles[0] ); - msg.WriteFloat( current.angles[1] ); - msg.WriteFloat( current.angles[2] ); - msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); - msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); - msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); - msg.WriteDeltaFloat( current.angles[0], current.localAngles[0] ); - msg.WriteDeltaFloat( current.angles[1], current.localAngles[1] ); - msg.WriteDeltaFloat( current.angles[2], current.localAngles[2] ); - - msg.WriteBits( current.linearExtrapolation.GetExtrapolationType(), 8 ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartTime() ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetDuration() ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[2] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[0] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[1] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[2] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[0] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[1] ); - msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[2] ); - - msg.WriteBits( current.angularExtrapolation.GetExtrapolationType(), 8 ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartTime() ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetDuration() ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[2] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[0] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[1] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[2] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[0] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[1] ); - msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[2] ); - - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartTime() ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetAcceleration() ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDeceleration() ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDuration() ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[2] ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[2] ); - - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartTime() ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetAcceleration() ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDeceleration() ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDuration() ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[2] ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[0] ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[1] ); - msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[2] ); -} - -/* -================ -idPhysics_Parametric::ReadFromSnapshot -================ -*/ -void idPhysics_Parametric::ReadFromSnapshot( const idBitMsgDelta &msg ) { - extrapolation_t linearType, angularType; - float startTime, duration, accelTime, decelTime; - idVec3 linearStartValue, linearSpeed, linearBaseSpeed, startPos, endPos; - idAngles angularStartValue, angularSpeed, angularBaseSpeed, startAng, endAng; - - current.time = msg.ReadLong(); - current.atRest = msg.ReadLong(); - current.origin[0] = msg.ReadFloat(); - current.origin[1] = msg.ReadFloat(); - current.origin[2] = msg.ReadFloat(); - current.angles[0] = msg.ReadFloat(); - current.angles[1] = msg.ReadFloat(); - current.angles[2] = msg.ReadFloat(); - current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); - current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); - current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); - current.localAngles[0] = msg.ReadDeltaFloat( current.angles[0] ); - current.localAngles[1] = msg.ReadDeltaFloat( current.angles[1] ); - current.localAngles[2] = msg.ReadDeltaFloat( current.angles[2] ); - - linearType = (extrapolation_t) msg.ReadBits( 8 ); - startTime = msg.ReadDeltaFloat( 0.0f ); - duration = msg.ReadDeltaFloat( 0.0f ); - linearStartValue[0] = msg.ReadDeltaFloat( 0.0f ); - linearStartValue[1] = msg.ReadDeltaFloat( 0.0f ); - linearStartValue[2] = msg.ReadDeltaFloat( 0.0f ); - linearSpeed[0] = msg.ReadDeltaFloat( 0.0f ); - linearSpeed[1] = msg.ReadDeltaFloat( 0.0f ); - linearSpeed[2] = msg.ReadDeltaFloat( 0.0f ); - linearBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f ); - linearBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f ); - linearBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f ); - current.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, linearType ); - - angularType = (extrapolation_t) msg.ReadBits( 8 ); - startTime = msg.ReadDeltaFloat( 0.0f ); - duration = msg.ReadDeltaFloat( 0.0f ); - angularStartValue[0] = msg.ReadDeltaFloat( 0.0f ); - angularStartValue[1] = msg.ReadDeltaFloat( 0.0f ); - angularStartValue[2] = msg.ReadDeltaFloat( 0.0f ); - angularSpeed[0] = msg.ReadDeltaFloat( 0.0f ); - angularSpeed[1] = msg.ReadDeltaFloat( 0.0f ); - angularSpeed[2] = msg.ReadDeltaFloat( 0.0f ); - angularBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f ); - angularBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f ); - angularBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f ); - current.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, angularType ); - - startTime = msg.ReadDeltaFloat( 0.0f ); - accelTime = msg.ReadDeltaFloat( 0.0f ); - decelTime = msg.ReadDeltaFloat( 0.0f ); - duration = msg.ReadDeltaFloat( 0.0f ); - startPos[0] = msg.ReadDeltaFloat( 0.0f ); - startPos[1] = msg.ReadDeltaFloat( 0.0f ); - startPos[2] = msg.ReadDeltaFloat( 0.0f ); - endPos[0] = msg.ReadDeltaFloat( 0.0f ); - endPos[1] = msg.ReadDeltaFloat( 0.0f ); - endPos[2] = msg.ReadDeltaFloat( 0.0f ); - current.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos ); - - startTime = msg.ReadDeltaFloat( 0.0f ); - accelTime = msg.ReadDeltaFloat( 0.0f ); - decelTime = msg.ReadDeltaFloat( 0.0f ); - duration = msg.ReadDeltaFloat( 0.0f ); - startAng[0] = msg.ReadDeltaFloat( 0.0f ); - startAng[1] = msg.ReadDeltaFloat( 0.0f ); - startAng[2] = msg.ReadDeltaFloat( 0.0f ); - endAng[0] = msg.ReadDeltaFloat( 0.0f ); - endAng[1] = msg.ReadDeltaFloat( 0.0f ); - endAng[2] = msg.ReadDeltaFloat( 0.0f ); - current.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng ); - - current.axis = current.angles.ToMat3(); - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} diff --git a/game/physics/physics_parametric.h b/game/physics/physics_parametric.h deleted file mode 100644 index e381e1b30..000000000 --- a/game/physics/physics_parametric.h +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_PARAMETRIC_H__ -#define __PHYSICS_PARAMETRIC_H__ - -/* -=================================================================================== - - Parametric physics - - Used for predefined or scripted motion. The motion of an object is completely - parametrized. By adjusting the parameters an object is forced to follow a - predefined path. The parametric physics is typically used for doors, bridges, - rotating fans etc. - -=================================================================================== -*/ - -typedef struct parametricPState_s { - int time; // physics time - int atRest; // set when simulation is suspended - idVec3 origin; // world origin - idAngles angles; // world angles - idMat3 axis; // world axis - idVec3 localOrigin; // local origin - idAngles localAngles; // local angles - idExtrapolate linearExtrapolation; // extrapolation based description of the position over time - idExtrapolate angularExtrapolation; // extrapolation based description of the orientation over time - idInterpolateAccelDecelLinear linearInterpolation; // interpolation based description of the position over time - idInterpolateAccelDecelLinear angularInterpolation; // interpolation based description of the orientation over time - idCurve_Spline * spline; // spline based description of the position over time - idInterpolateAccelDecelLinear splineInterpolate; // position along the spline over time - bool useSplineAngles; // set the orientation using the spline -} parametricPState_t; - -class idPhysics_Parametric : public idPhysics_Base { - -public: - CLASS_PROTOTYPE( idPhysics_Parametric ); - - idPhysics_Parametric( void ); - ~idPhysics_Parametric( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void SetPusher( int flags ); - bool IsPusher( void ) const; - - void SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ); - void SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ); - extrapolation_t GetLinearExtrapolationType( void ) const; - extrapolation_t GetAngularExtrapolationType( void ) const; - - void SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ); - void SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ); - - void SetSpline( idCurve_Spline *spline, int accelTime, int decelTime, bool useSplineAngles ); - idCurve_Spline *GetSpline( void ) const; - int GetSplineAcceleration( void ) const; - int GetSplineDeceleration( void ) const; - bool UsingSplineAngles( void ) const; - - void GetLocalOrigin( idVec3 &curOrigin ) const; - const idVec3& GetLocalOrigin() const; - void SetLocalOrigin( const idVec3 &newOrigin); - void GetLocalAngles( idAngles &curAngles ) const; - const idAngles& GetLocalAngles() const; - void SetLocalAngles(idAngles curAngles); - - void GetAngles( idAngles &curAngles ) const; - -public: // common physics interface - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void Activate( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - void SetMaster( idEntity *master, const bool orientated = true ); - - const trace_t * GetBlockingInfo( void ) const; - idEntity * GetBlockingEntity( void ) const; - - int GetLinearEndTime( void ) const; - int GetAngularEndTime( void ) const; - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -private: - // parametric physics state - parametricPState_t current; - parametricPState_t saved; - - // pusher - bool isPusher; - idClipModel * clipModel; - int pushFlags; - - // results of last evaluate - trace_t pushResults; - bool isBlocked; - - // master - bool hasMaster; - bool isOrientated; - -private: - bool TestIfAtRest( void ) const; - void Rest( void ); -}; - -#endif /* !__PHYSICS_PARAMETRIC_H__ */ diff --git a/game/physics/physics_player.cpp b/game/physics/physics_player.cpp deleted file mode 100644 index d8db9a687..000000000 --- a/game/physics/physics_player.cpp +++ /dev/null @@ -1,5179 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Source$ $Revision$ $Date$", init_version); - -#include "../game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Grabber.h" -#include "../DarkMod/BinaryFrobMover.h" -#include "../DarkMod/FrobDoor.h" -#include "force_push.h" - -CLASS_DECLARATION( idPhysics_Actor, idPhysics_Player ) -END_CLASS - -// movement parameters -const float PM_STOPSPEED = 100.0f; -const float PM_SWIMSCALE = 1.0f; -const float PM_ROPESPEED = 100.0f; -const float PM_LADDERSPEED = 100.0f; -const float PM_STEPSCALE = 1.0f; - -const float PM_ACCELERATE = 10.0f; -const float PM_AIRACCELERATE = 1.0f; -const float PM_WATERACCELERATE = 4.0f; -const float PM_FLYACCELERATE = 8.0f; - -const float PM_FRICTION = 6.0f; -const float PM_AIRFRICTION = 0.0f; -const float PM_WATERFRICTION = 1.0f; -const float PM_FLYFRICTION = 3.0f; -const float PM_NOCLIPFRICTION = 12.0f; -const float PM_SLICK = 0.1f; // grayman - #2409 - for slippery surfaces - -/** -* Height unit increment for mantle test -* This value should be >= 1.0 -* A larger value reduces the number of tests during a mantle -* initiation, but may not find some small mantleable "nooks" -* in a surface. -**/ -const float MANTLE_TEST_INCREMENT = 1.0; - -/** -* Desired player speed below which ground friction is neglected -* -* This was determined for PM_FRICTION = 6.0 and should change if -* PM_FRICTION changes from 6.0. -**/ -const float PM_NOFRICTION_SPEED = 71.0f; - -const float MIN_WALK_NORMAL = 0.7f; // can't walk on very steep slopes (run = 1, rise = 1) -const float MIN_WALK_SLICK_NORMAL = 0.89f; // grayman #2409 - higher value for slippery slopes (run = 1, rise = 0.5) -const float OVERCLIP = 1.001f; - -// TODO (ishtvan): Move the following to INI file or player def file: - -/** -* Defines the spot above the player's origin where they are attached to the rope -**/ -const float ROPE_GRABHEIGHT = 50.0f; - -/** -* Distance the player is set back from the rope -**/ -const float ROPE_DISTANCE = 20.0f; - -/** -* Angular tolarance for looking at a rope and grabbing it [deg] -**/ -const float ROPE_ATTACHANGLE = 45.0f*idMath::PI/180.0f; -/** -* Angular tolerance for when to start rotating around the rope -* (This one doesn't have to be in the def file) -**/ -const float ROPE_ROTANG_TOL = 1.0f*idMath::PI/180.0f; - -/** -* When moving on a climbable surface, the player's predicted position is checked by this delta ahead -* To make sure it's still on a ladder surface. -**/ -const float CLIMB_SURFCHECK_DELTA = 5.0f; - -/** -* How far to check from the player origin along the surface normal to hit the surface in the above test -* Needs to allow for worst case overhang -**/ -const float CLIMB_SURFCHECK_NORMDELTA = 20.0f; - -/** -* how far away is the player allowed to push out from the climbable section? -* Measured from the last good attachment point at the origin -**/ -const float LADDER_DISTAWAY = 15.0f; - -/** -* Velocity with which the player is shoved over the top of the ladder -* This depends on LADDER_DISTAWAY. If this velocity is too low, the player will -* fall down before they can make it over the top of the ladder -**/ -const float LADDER_TOPVELOCITY = 80.0f; - -/** -* Angle at which the player detaches from a ladder when their feet are walking on a surface -**/ -const float LADDER_WALKDETACH_ANGLE = 45.0f; -const float LADDER_WALKDETACH_DOT = idMath::Cos( DEG2RAD( LADDER_WALKDETACH_ANGLE ) ); - -// movementFlags -const int PMF_DUCKED = 1; // set when ducking -const int PMF_JUMPED = 2; // set when the player jumped this frame -const int PMF_STEPPED_UP = 4; // set when the player stepped up this frame -const int PMF_STEPPED_DOWN = 8; // set when the player stepped down this frame -const int PMF_JUMP_HELD = 16; // set when jump button is held down -const int PMF_TIME_LAND = 32; // movementTime is time before rejump -const int PMF_TIME_KNOCKBACK = 64; // movementTime is an air-accelerate only time -const int PMF_TIME_WATERJUMP = 128; // movementTime is waterjump -const int PMF_ALL_TIMES = (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK); - -int c_pmove = 0; - -void idPhysics_Player::SetSelf( idEntity *e ) -{ - idPhysics_Base::SetSelf(e); - m_PushForce->SetOwner(e); -} - -/* -============ -idPhysics_Player::CmdScale - -Returns the scale factor to apply to cmd movements -This allows the clients to use axial -127 to 127 values for all directions -without getting a sqrt(2) distortion in speed. -============ -*/ -float idPhysics_Player::CmdScale( const usercmd_t &cmd ) const { - int max; - float total; - float scale; - int forwardmove; - int rightmove; - int upmove; - - forwardmove = cmd.forwardmove; - rightmove = cmd.rightmove; - - // since the crouch key doubles as downward movement, ignore downward movement when we're on the ground - // otherwise crouch speed will be lower than specified - if ( walking ) { - upmove = 0; - } else { - upmove = cmd.upmove; - } - - max = abs( forwardmove ); - if ( abs( rightmove ) > max ) { - max = abs( rightmove ); - } - if ( abs( upmove ) > max ) { - max = abs( upmove ); - } - - if ( !max ) { - return 0.0f; - } - - total = idMath::Sqrt( (float) forwardmove * forwardmove + rightmove * rightmove + upmove * upmove ); - scale = (float) playerSpeed * max / ( 127.0f * total ); - - return scale; -} - -/* -============== -idPhysics_Player::Accelerate - -Handles user intended acceleration -============== -*/ -void idPhysics_Player::Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel ) { -#if 1 - // q2 style - float addspeed, accelspeed, currentspeed; - - currentspeed = current.velocity * wishdir; - addspeed = wishspeed - currentspeed; - if (addspeed <= 0) { - return; - } - accelspeed = accel * frametime * wishspeed; - if (accelspeed > addspeed) { - accelspeed = addspeed; - } - - current.velocity += accelspeed * wishdir; -#else - // proper way (avoids strafe jump maxspeed bug), but feels bad - idVec3 wishVelocity; - idVec3 pushDir; - float pushLen; - float canPush; - - wishVelocity = wishdir * wishspeed; - pushDir = wishVelocity - current.velocity; - pushLen = pushDir.Normalize(); - - canPush = accel * frametime * wishspeed; - if (canPush > pushLen) { - canPush = pushLen; - } - - current.velocity += canPush * pushDir; -#endif -} - -/* -================== -idPhysics_Player::SlideMove - -Returns true if the velocity was clipped in some way -================== -*/ -#define MAX_CLIP_PLANES 5 - -bool idPhysics_Player::SlideMove( bool gravity, bool stepUp, bool stepDown, bool push ) { - int i, j, k, pushFlags; - int bumpcount, numbumps, numplanes; - float d, time_left, into; - float totalMass = 0.0f; - idVec3 dir, planes[MAX_CLIP_PLANES]; - idVec3 end, stepEnd, primal_velocity, endVelocity, endClipVelocity, clipVelocity; - trace_t trace, stepTrace, downTrace; - bool nearGround, stepped, pushed; - - numbumps = 4; - - primal_velocity = current.velocity; - - if ( gravity ) { - endVelocity = current.velocity + gravityVector * frametime; - current.velocity = ( current.velocity + endVelocity ) * 0.5f; - primal_velocity = endVelocity; - if ( groundPlane ) { - // slide along the ground plane - current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - } - } - else { - endVelocity = current.velocity; - } - - time_left = frametime; - - // never turn against the ground plane - if ( groundPlane ) { - numplanes = 1; - planes[0] = groundTrace.c.normal; - } else { - numplanes = 0; - } - - // never turn against original velocity - planes[numplanes] = current.velocity; - planes[numplanes].Normalize(); - numplanes++; - - for ( bumpcount = 0; bumpcount < numbumps; bumpcount++ ) - { - // calculate position we are trying to move to - end = current.origin + time_left * current.velocity; - - // see if we can make it there - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); - - time_left -= time_left * trace.fraction; - current.origin = trace.endpos; - - // if moved the entire distance - if ( trace.fraction >= 1.0f ) - { - break; - } - - stepped = pushed = false; - - // if we are allowed to step up - if ( stepUp ) - { - nearGround = groundPlane || m_bOnClimb || m_bClimbDetachThisFrame; - - if ( !nearGround ) - { - // trace down to see if the player is near the ground - // step checking when near the ground allows the player to move up stairs smoothly while jumping - stepEnd = current.origin + maxStepHeight * gravityNormal; - gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); - nearGround = ( downTrace.fraction < 1.0f && (downTrace.c.normal * -gravityNormal) > MIN_WALK_NORMAL ); - } - - // may only step up if near the ground or climbing - if ( nearGround ) - { - - // step up - stepEnd = current.origin - maxStepHeight * gravityNormal; - gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); - - // greebo: Trace along the current velocity, but trace further ahead than we need to judge the situation - idVec3 velocityNorm(current.velocity); - velocityNorm.NormalizeFast(); - - idVec3 fullForward = downTrace.endpos + maxStepHeight * velocityNorm; - gameLocal.clip.Translation( stepTrace, downTrace.endpos, fullForward, clipModel, clipModel->GetAxis(), clipMask, self ); - - // This is the max. distance we can move forward in this frame - idVec3 forward = time_left * current.velocity; - float forwardDist = forward.LengthFast(); - - // step down - idVec3 topStartPoint = downTrace.endpos + forward; - - stepEnd = topStartPoint + maxStepHeight * gravityNormal; - gameLocal.clip.Translation( downTrace, topStartPoint, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); - - if ( downTrace.fraction >= 1.0f || (downTrace.c.normal * -gravityNormal) > MIN_WALK_NORMAL ) - { - // if moved the entire distance - if ( stepTrace.fraction >= 1.0f ) - { - time_left = 0; - current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; - current.origin = downTrace.endpos; - current.movementFlags |= PMF_STEPPED_UP; - current.velocity *= PM_STEPSCALE; - break; - } - - // if the move is further when stepping up - if ( stepTrace.fraction > trace.fraction ) - { - time_left -= time_left * stepTrace.fraction; - current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; - current.origin = downTrace.endpos; - current.movementFlags |= PMF_STEPPED_UP; - current.velocity *= PM_STEPSCALE; - trace = stepTrace; - stepped = true; - } - } - else - { - // greebo: We have a sloped obstacle in front of us - - if (stepTrace.fraction >= 1.0f) - { - // We can step onto this obstacle, the stepTrace has shown that there is enough room - // in front of us (if we translate a bit upwards) - current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; - //static int factor = 10; - current.origin = downTrace.endpos + time_left*current.velocity; //(fullForward - current.origin)*stepTrace.fraction; - time_left = 0; - current.movementFlags |= PMF_STEPPED_UP; - current.velocity *= PM_STEPSCALE; - // greebo: HACK ALARM: We add a "counter-gravity" this frame to avoid us from being dragged down again in the next frame - // TODO: Maybe we can do this somewhere else, where the player is sliding off slopes. - current.velocity -= gravityVector * frametime * 3; - } - } - - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing step up, velocity now %.4f %.4f %.4f\r", current.velocity.x, current.velocity.y, current.velocity.z); - } - } - - // if we can push other entities and not blocked by the world - if ( push && trace.c.entityNum != ENTITYNUM_WORLD ) { - - clipModel->SetPosition( current.origin, clipModel->GetAxis() ); - - // clip movement, only push idMoveables, don't push entities the player is standing on - // apply impact to pushed objects - pushFlags = PUSHFL_CLIP | PUSHFL_ONLYMOVEABLE | PUSHFL_NOGROUNDENTITIES | PUSHFL_APPLYIMPULSE; - - // clip & push - - // greebo: Don't use the idPusher - //totalMass = gameLocal.push.ClipTranslationalPush( trace, self, pushFlags, end, end - current.origin, cv_pm_pushmod.GetFloat() ); - - // Set the trace result to zero, we're pushing into things here - trace.fraction = 0.0f; - trace.endpos = current.origin; - - // greebo: Check the entity in front of us - idEntity* pushedEnt = gameLocal.entities[trace.c.entityNum]; - if (pushedEnt != NULL) - { - // Register the blocking physics object with our push force - m_PushForce->SetPushEntity(pushedEnt, 0); - m_PushForce->SetContactInfo(trace, current.velocity); - - totalMass = pushedEnt->GetPhysics()->GetMass(); - } - - if ( totalMass > 0.0f ) { - // decrease velocity based on the total mass of the objects being pushed ? - current.velocity *= 1.0f - idMath::ClampFloat( 0.0f, 1000.0f, totalMass - 20.0f ) * ( 1.0f / 950.0f ); - pushed = true; - } - - current.origin = trace.endpos; - time_left -= time_left * trace.fraction; - - // if moved the entire distance - if ( trace.fraction >= 1.0f ) { - break; - } - } - - if ( !stepped ) { - // let the entity know about the collision - self->Collide( trace, current.velocity ); - } - - if ( numplanes >= MAX_CLIP_PLANES ) { - // MrElusive: I think we have some relatively high poly LWO models with a lot of slanted tris - // where it may hit the max clip planes - current.velocity = vec3_origin; - return true; - } - - // - // if this is the same plane we hit before, nudge velocity - // out along it, which fixes some epsilon issues with - // non-axial planes - // - for ( i = 0; i < numplanes; i++ ) { - if ( ( trace.c.normal * planes[i] ) > 0.999f ) { - current.velocity += trace.c.normal; - break; - } - } - if ( i < numplanes ) { - continue; - } - planes[numplanes] = trace.c.normal; - numplanes++; - - // - // modify velocity so it parallels all of the clip planes - // - - // find a plane that it enters - for ( i = 0; i < numplanes; i++ ) { - into = current.velocity * planes[i]; - if ( into >= 0.1f ) { - continue; // move doesn't interact with the plane - } - - // slide along the plane - clipVelocity = current.velocity; - clipVelocity.ProjectOntoPlane( planes[i], OVERCLIP ); - - // slide along the plane - endClipVelocity = endVelocity; - endClipVelocity.ProjectOntoPlane( planes[i], OVERCLIP ); - - // see if there is a second plane that the new move enters - for ( j = 0; j < numplanes; j++ ) { - if ( j == i ) { - continue; - } - if ( ( clipVelocity * planes[j] ) >= 0.1f ) { - continue; // move doesn't interact with the plane - } - - // try clipping the move to the plane - clipVelocity.ProjectOntoPlane( planes[j], OVERCLIP ); - endClipVelocity.ProjectOntoPlane( planes[j], OVERCLIP ); - - // see if it goes back into the first clip plane - if ( ( clipVelocity * planes[i] ) >= 0 ) { - continue; - } - - // slide the original velocity along the crease - dir = planes[i].Cross( planes[j] ); - dir.Normalize(); - d = dir * current.velocity; - clipVelocity = d * dir; - - dir = planes[i].Cross( planes[j] ); - dir.Normalize(); - d = dir * endVelocity; - endClipVelocity = d * dir; - - // see if there is a third plane the the new move enters - for ( k = 0; k < numplanes; k++ ) { - if ( k == i || k == j ) { - continue; - } - if ( ( clipVelocity * planes[k] ) >= 0.1f ) { - continue; // move doesn't interact with the plane - } - - // stop dead at a tripple plane interaction - current.velocity = vec3_origin; - return true; - } - } - - // if we have fixed all interactions, try another move - current.velocity = clipVelocity; - endVelocity = endClipVelocity; - break; - } - } - - // step down - if ( stepDown && groundPlane ) - { - stepEnd = current.origin + gravityNormal * maxStepHeight; - gameLocal.clip.Translation( downTrace, current.origin, stepEnd, clipModel, clipModel->GetAxis(), clipMask, self ); - if ( downTrace.fraction > 1e-4f && downTrace.fraction < 1.0f ) - { - current.stepUp -= ( downTrace.endpos - current.origin ) * gravityNormal; - current.origin = downTrace.endpos; - current.movementFlags |= PMF_STEPPED_DOWN; - current.velocity *= PM_STEPSCALE; - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing step down, velocity now %.4f %.4f %.4f\r", current.velocity.x, current.velocity.y, current.velocity.z); - } - } - - if ( gravity ) { - current.velocity = endVelocity; - } - - // come to a dead stop when the velocity orthogonal to the gravity flipped - clipVelocity = current.velocity - gravityNormal * current.velocity * gravityNormal; - endClipVelocity = endVelocity - gravityNormal * endVelocity * gravityNormal; - if ( clipVelocity * endClipVelocity < 0.0f ) { - current.velocity = gravityNormal * current.velocity * gravityNormal; - } - - return (bool)( bumpcount == 0 ); -} - -/* -================== -idPhysics_Player::Friction - -Handles both ground friction and water friction -================== -*/ -void idPhysics_Player::Friction( void ) -{ - idVec3 vel = current.velocity; - - if ( walking ) { - // ignore slope movement, remove all velocity in gravity direction - vel += (vel * gravityNormal) * gravityNormal; - } - - float speed = vel.Length(); - if ( speed < 1.0f ) { - // remove all movement orthogonal to gravity, allows for sinking underwater - if ( fabs( current.velocity * gravityNormal ) < 1e-5f ) { - current.velocity.Zero(); - } else { - current.velocity = (current.velocity * gravityNormal) * gravityNormal; - } - // greebo: We still want the player to slow down when reaching the surface - // This is where velocities are getting really small, but never actually reach 0, - // that's why this z-friction is necessary. - current.velocity.z *= cv_pm_water_z_friction.GetFloat(); - return; - } - - float drop = 0; - - // spectator friction - if ( current.movementType == PM_SPECTATOR ) { - drop += speed * PM_FLYFRICTION * frametime; - } - // apply ground friction - else if ( walking && waterLevel <= WATERLEVEL_FEET ) - { - if ( !(current.movementFlags & PMF_TIME_KNOCKBACK) ) // if getting knocked back, no friction - { - // grayman - #2409 - less friction on slick surfaces - - float friction = PM_FRICTION; // default - if (groundMaterial && (groundMaterial->IsSlick())) - { - friction *= PM_SLICK; // reduce friction - } - float control = (speed < PM_STOPSPEED) ? PM_STOPSPEED : speed; - drop += control * friction * frametime; - } - } - // apply water friction even if just wading - else if ( waterLevel ) { - drop += speed * PM_WATERFRICTION * waterLevel * frametime; - } - // apply air friction - else { - drop += speed * PM_AIRFRICTION * frametime; - } - - // scale the velocity - float newspeed = speed - drop; - if (newspeed < 0) { - newspeed = 0; - } - current.velocity *= ( newspeed / speed ); -} - -/* -=================== -idPhysics_Player::WaterJumpMove - -Flying out of the water - -REMOVED from DarkMod -=================== -*/ - - -/* -=================== -idPhysics_Player::WaterMove -=================== -*/ -void idPhysics_Player::WaterMove() -{ - // Keep track of whether jump is held down for mantling out of water - if ( command.upmove > 10 ) - { - current.movementFlags |= PMF_JUMP_HELD; - } - else - { - current.movementFlags &= ~PMF_JUMP_HELD; - } - - // Lower ranged weapons while swimming - static_cast(self)->SetImmobilization( "WaterMove", EIM_ATTACK_RANGED ); - - Friction(); - - float scale = CmdScale( command ); - - idVec3 wishvel; - - // user intentions - if ( !scale ) { - // greebo: Standard downwards velocity is configurable via this CVAR - if (waterLevel >= WATERLEVEL_HEAD) - { - // greebo: Player is completely submersed, apply upwards velocity, but let it raise over time - float factor = (gameLocal.framenum - submerseFrame) / 60; - if (factor > 1) { - factor = 1; - } - - if (static_cast(self)->m_CrouchIntent) - { - // greebo: we probably have crouch mode activated - // Set the factor to 0, toggle crouch can here be used to keep the player at the current height - factor = 0; - } - - // This makes the player slowly rise/sink in water - wishvel = gravityNormal * cv_pm_water_downwards_velocity.GetFloat() * factor; - } - else - { - wishvel.Zero(); - } - } else { - - wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); - wishvel -= scale * gravityNormal * command.upmove; - } - - idVec3 wishdir = wishvel; - float wishspeed = wishdir.Normalize(); - - if ( wishspeed > playerSpeed * PM_SWIMSCALE ) { - wishspeed = playerSpeed * PM_SWIMSCALE; - } - - idPhysics_Player::Accelerate( wishdir, wishspeed, PM_WATERACCELERATE ); - - // make sure we can go up slopes easily under water - if ( groundPlane && ( current.velocity * groundTrace.c.normal ) < 0.0f ) { - float vel = current.velocity.Length(); - // slide along the ground plane - current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - - current.velocity.Normalize(); - current.velocity *= vel; - } - - idPhysics_Player::SlideMove( false, true, false, false ); -} - -/* -=================== -idPhysics_Player::FlyMove -=================== -*/ -void idPhysics_Player::FlyMove( void ) { - idVec3 wishvel; - float wishspeed; - idVec3 wishdir; - float scale; - - // normal slowdown - idPhysics_Player::Friction(); - - scale = idPhysics_Player::CmdScale( command ); - - if ( !scale ) { - wishvel = vec3_origin; - } else { - wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); - wishvel -= scale * gravityNormal * command.upmove; - } - - wishdir = wishvel; - wishspeed = wishdir.Normalize(); - - idPhysics_Player::Accelerate( wishdir, wishspeed, PM_FLYACCELERATE ); - - idPhysics_Player::SlideMove( false, false, false, false ); -} - -/* -=================== -idPhysics_Player::AirMove -=================== -*/ -void idPhysics_Player::AirMove( void ) { - idVec3 wishvel; - idVec3 wishdir; - float wishspeed; - float scale; - - idPhysics_Player::Friction(); - - scale = idPhysics_Player::CmdScale( command ); - - // project moves down to flat plane - viewForward -= (viewForward * gravityNormal) * gravityNormal; - viewRight -= (viewRight * gravityNormal) * gravityNormal; - viewForward.Normalize(); - viewRight.Normalize(); - - wishvel = viewForward * command.forwardmove + viewRight * command.rightmove; - wishvel -= (wishvel * gravityNormal) * gravityNormal; - wishdir = wishvel; - wishspeed = wishdir.Normalize(); - wishspeed *= scale; - - // not on ground, so little effect on velocity - idPhysics_Player::Accelerate( wishdir, wishspeed, PM_AIRACCELERATE ); - - // we may have a ground plane that is very steep, even - // though we don't have a groundentity - // slide along the steep plane - if ( groundPlane ) { - current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - } - - idPhysics_Player::SlideMove( true, false, false, false ); -} - -/* -=================== -idPhysics_Player::WalkMove -=================== -*/ -void idPhysics_Player::WalkMove( void ) -{ - if ( waterLevel > WATERLEVEL_WAIST && ( viewForward * groundTrace.c.normal ) > 0.0f ) - { - // begin swimming - WaterMove(); - return; - } - - if ( CheckJump() ) { - // jumped away - if ( waterLevel > WATERLEVEL_FEET ) { - WaterMove(); - } - else { - AirMove(); - } - return; - } - - Friction(); - - float scale = CmdScale( command ); - - // project moves down to flat plane - viewForward -= (viewForward * gravityNormal) * gravityNormal; - viewRight -= (viewRight * gravityNormal) * gravityNormal; - - // project the forward and right directions onto the ground plane - viewForward.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - viewRight.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - // - viewForward.Normalize(); - viewRight.Normalize(); - - idVec3 wishvel = viewForward * command.forwardmove + viewRight * command.rightmove; - idVec3 wishdir = wishvel; - float wishspeed = wishdir.Normalize(); - wishspeed *= scale; - - // clamp the speed lower if wading or walking on the bottom - if ( waterLevel ) - { - float waterScale = waterLevel / 3.0f; - waterScale = 1.0f - ( 1.0f - PM_SWIMSCALE ) * waterScale; - if ( wishspeed > playerSpeed * waterScale ) { - wishspeed = playerSpeed * waterScale; - } - } - - float accelerate = 0; - - // when a player gets hit, they temporarily lose full control, which allows them to be moved a bit - if ( /*( groundMaterial && groundMaterial->IsSlick() ) || grayman #2409 */ current.movementFlags & PMF_TIME_KNOCKBACK ) { - accelerate = PM_AIRACCELERATE; - } - else - { - accelerate = PM_ACCELERATE; - - //FIX: If the player is moving very slowly, bump up their acceleration - // so they don't get stuck to the floor by friction. - if( playerSpeed < PM_NOFRICTION_SPEED ) - { - accelerate *= 3.0f; - } - } - - Accelerate( wishdir, wishspeed, accelerate ); - - if ( /*( groundMaterial && groundMaterial->IsSlick() ) || grayman #2409 */ current.movementFlags & PMF_TIME_KNOCKBACK ) - { - current.velocity += gravityVector * frametime; - } - - idVec3 oldVelocity = current.velocity; - - // slide along the ground plane - current.velocity.ProjectOntoPlane( groundTrace.c.normal, OVERCLIP ); - - // if not clipped into the opposite direction - if ( oldVelocity * current.velocity > 0.0f ) - { - float newVel = current.velocity.LengthSqr(); - - if ( newVel > 1.0f ) - { - float oldVel = oldVelocity.LengthSqr(); - - if ( oldVel > 1.0f ) - { - // don't decrease velocity when going up or down a slope - current.velocity *= idMath::Sqrt( oldVel / newVel ); - } - } - } - - // don't do anything if standing still - idVec3 vel = current.velocity - (current.velocity * gravityNormal) * gravityNormal; - - if ( !vel.LengthSqr() ) - { - // greebo: We're not moving, so let's clear the push entity - m_PushForce->SetPushEntity(NULL); - return; - } - - gameLocal.push.InitSavingPushedEntityPositions(); - - SlideMove( false, true, true, true ); -} - -/* -============== -idPhysics_Player::DeadMove -============== -*/ -void idPhysics_Player::DeadMove( void ) { - float forward; - - if ( !walking ) { - return; - } - - // extra friction - forward = current.velocity.Length(); - forward -= 20; - if ( forward <= 0 ) { - current.velocity = vec3_origin; - } - else { - current.velocity.Normalize(); - current.velocity *= forward; - } -} - -/* -=============== -idPhysics_Player::NoclipMove -=============== -*/ -void idPhysics_Player::NoclipMove( void ) { - float speed, drop, friction, newspeed, stopspeed; - float scale, wishspeed; - idVec3 wishdir; - - // friction - speed = current.velocity.Length(); - if ( speed < 20.0f ) { - current.velocity = vec3_origin; - } - else { - stopspeed = playerSpeed * 0.3f; - if ( speed < stopspeed ) { - speed = stopspeed; - } - friction = PM_NOCLIPFRICTION; - drop = speed * friction * frametime; - - // scale the velocity - newspeed = speed - drop; - if (newspeed < 0) { - newspeed = 0; - } - - current.velocity *= newspeed / speed; - } - - // accelerate - scale = idPhysics_Player::CmdScale( command ); - - wishdir = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); - wishdir -= scale * gravityNormal * command.upmove; - wishspeed = wishdir.Normalize(); - wishspeed *= scale; - - idPhysics_Player::Accelerate( wishdir, wishspeed, PM_ACCELERATE ); - - // move - current.origin += frametime * current.velocity; -} - -/* -=============== -idPhysics_Player::SpectatorMove -=============== -*/ -void idPhysics_Player::SpectatorMove( void ) { - idVec3 wishvel; - float wishspeed; - idVec3 wishdir; - float scale; - - trace_t trace; - idVec3 end; - - // fly movement - - idPhysics_Player::Friction(); - - scale = idPhysics_Player::CmdScale( command ); - - if ( !scale ) { - wishvel = vec3_origin; - } else { - wishvel = scale * (viewForward * command.forwardmove + viewRight * command.rightmove); - } - - wishdir = wishvel; - wishspeed = wishdir.Normalize(); - - idPhysics_Player::Accelerate( wishdir, wishspeed, PM_FLYACCELERATE ); - - idPhysics_Player::SlideMove( false, false, false, false ); -} - -/* -============ -idPhysics_Player::RopeMove -============ -*/ -// TODO: This will probably reverse the up/down controls for upside-down ropes -// Would need some fix where desired direction of travel is flipped -// if climbDir * gravNormal is < 0 -#pragma warning( disable : 4533 ) -void idPhysics_Player::RopeMove( void ) -{ - idVec3 wishdir, wishvel, right, ropeBodyOrig; - idVec3 ropePoint, offset, newOrigin, climbDir; - float wishspeed, scale, temp, deltaYaw, deltaAng1, deltaAng2; - float upscale, ropeTop, ropeBot; // z coordinates of the top and bottom of rope - idBounds ropeBounds; - trace_t transTrace; // used for clipping tests when moving the player - idVec3 transVec, forward, playerVel(0,0,0), PlayerPoint(0,0,0); - // shaft of rope in the rope coordinates, may need to be a spawnarg if rope models are inconsistent - idVec3 ropeShaft( 0.0f, 0.0f, 1.0f ); - int bodID(0); - idPhysics_AF *ropePhys; - idPlayer *player = static_cast(self); - - if( !m_RopeEntity.GetEntity() ) - { - RopeDetach(); - return; // early exit - } - - ropePhys = static_cast(m_RopeEntity.GetEntity()->GetPhysics()); - - // stick the player to the rope at an AF origin point closest to their arms - PlayerPoint = current.origin - gravityNormal*ROPE_GRABHEIGHT; - ropeBodyOrig = ropePhys->NearestBodyOrig( PlayerPoint, &bodID ); - climbDir = ropePhys->GetAxis( bodID ) * ropeShaft; - // Find the rope attachment point, which now moves along the individual AF body axis - // Drawing a diagram, we find: - // (orig - ropeOrig) * gravNormal = | offset along rope axis | * (rope axis * gravNormal) - // Solve for offset along rope axis - idVec3 deltaPlayerBody = PlayerPoint - ropeBodyOrig; - - // float offsetMag = (deltaPlayerBody * gravityNormal) / (climbDir * gravityNormal); - - // angua: the other method got huge values for offsetMag at large angles - // between the climbDir and the gravity axis. - float offsetMag = deltaPlayerBody * climbDir; - ropePoint = ropeBodyOrig + offsetMag * climbDir; - - // Uncomment for climb axis debugging - // gameRenderWorld->DebugArrow( colorRed, ropeBodyOrig, ropePoint, 1 ); - - SetRefEntVel( m_RopeEntity.GetEntity(), bodID ); - // move the player velocity into the rope reference frame - current.velocity -= m_RefEntVelocity; - - // store and then kill the player's transverse velocity - playerVel = current.velocity; - current.velocity = (current.velocity * climbDir) * climbDir; - - // apply the player's weight to the AF body - COMMENTED OUT DUE TO AF CRAZINESS -// ropePhys->AddForce(bodID, ropePoint, mass * gravityVector ); - - // if the player has hit the rope this frame, apply an impulse based on their velocity - // pretend the deceleration takes place over a number of frames for realism (100 ms?) - if( m_bJustHitRope ) - { - m_bJustHitRope = false; - - // greebo: Apply an impulse on the entity the rope arrow is bound to - idEntity* ropeBindMaster = m_RopeEntity.GetEntity()->GetBindMaster(); - if (ropeBindMaster != NULL) - { - idVec3 direction = GetGravityNormal(); - - idPhysics* bindMasterPhysics = ropeBindMaster->GetPhysics(); - - const idVec3& ropeOrigin = ropePhys->GetOrigin(); - - idAFBody* topMostBody = ropePhys->GetBody(0); - if (topMostBody != NULL) - { - // Correct the pull direction using the orientation of the topmost body. - const idMat3& axis = topMostBody->GetWorldAxis(); - direction = topMostBody->GetWorldAxis() * ropeShaft; - } - - bindMasterPhysics->ApplyImpulse(0, ropeOrigin, direction * mass * cv_tdm_rope_pull_force_factor.GetFloat()); - } - - idVec3 vImpulse = playerVel - (playerVel * climbDir) * climbDir; - vImpulse *= mass; - - // ishtvan fix: Always translational force, do not torque the rope body - // ropePhys->AddForce( bodID, ropePoint, vImpulse/0.1f ); - ropePhys->AddForce( bodID, ropePhys->GetOrigin(bodID), vImpulse/0.1f ); - } - -// ======================== Rope Swinging ===================== - if( ( player->usercmd.buttons & BUTTON_ATTACK ) && !( player->oldButtons & BUTTON_ATTACK ) - && (gameLocal.time - m_RopeKickTime) > cv_pm_rope_swing_reptime.GetInteger() ) - { - // default kick direction is forward - idVec3 kickDir = player->firstPersonViewAxis[0]; - idVec3 bodyOrig = ropePhys->GetOrigin(bodID); - idMat3 rotDir = mat3_identity; - // apply modifiers if holding left/right/back - if( common->ButtonState(UB_MOVELEFT) ) - { - rotDir = idAngles(0.0f, 90.0f, 0.0f).ToMat3(); - } - else if( common->ButtonState(UB_MOVERIGHT) ) - { - rotDir = idAngles(0.0f, 270.0f, 0.0f).ToMat3(); - } - else if( common->ButtonState(UB_BACK) ) - { - rotDir = idAngles(0.0f, 180.0f, 0.0f).ToMat3(); - } - kickDir = rotDir * kickDir; - - // do a trace to see if a solid is in the way, if so, kick off of it - trace_t trKick; - - gameLocal.clip.TracePoint - ( - trKick, bodyOrig, - bodyOrig + cv_pm_rope_swing_kickdist.GetFloat()*kickDir, - MASK_SOLID, self - ); - if( trKick.fraction < 1.0f ) - { - // reverse direction to kick off - kickDir *= -1.0f; - // apply reaction force to entity kicked (TODO: watch out for exploits) - idEntity *kickedEnt = gameLocal.entities[trKick.c.entityNum]; - float kickMag = cv_pm_rope_swing_impulse.GetFloat() / 25.0f; // divide by 25, it takes a lot to move AFs for some reason - kickedEnt->ApplyImpulse( self, trKick.c.id, trKick.c.point, -kickMag * kickDir ); - } - - // project to XY plane - kickDir -= GetGravityNormal() * (kickDir*GetGravityNormal()); - kickDir.Normalize(); - - ropePhys->AddForce( bodID, bodyOrig, kickDir * cv_pm_rope_swing_impulse.GetFloat() ); - // test: apply velocity to all bodies lower as well? - m_RopeKickTime = gameLocal.time; - } - -// ==== Translate the player to the rope attachment point ===== - - offset = (current.origin - ropePoint); - offset.ProjectOntoPlane( -gravityNormal ); - offset.Normalize(); - offset *= ROPE_DISTANCE; - - newOrigin = ropePoint + offset; - transVec = newOrigin - current.origin; - transVec -= (transVec * gravityNormal)*gravityNormal; - - // check whether the player will clip anything, and only translate up to that point - ClipTranslation(transTrace, transVec, NULL); - newOrigin = current.origin + (transVec * transTrace.fraction); - Translate( newOrigin - current.origin ); - - - // Find the top and bottom of the rope - // This must be done every frame since the rope may be deforming - ropeBounds = m_RopeEntity.GetEntity()->GetPhysics()->GetAbsBounds(); - ropeTop = ropeBounds[0] * -gravityNormal; - ropeBot = ropeBounds[1] * -gravityNormal; - - if( ropeTop < ropeBot ) - { - // switch 'em - temp = ropeTop; - ropeTop = ropeBot; - ropeBot = temp; - } - - // ============== read mouse input and orbit around the rope =============== - - // recalculate offset because the player may have moved to stick point - offset = (ropePoint - current.origin); - offset.ProjectOntoPlane( -gravityNormal ); - offset.Normalize(); - - // forward vector orthogonal to gravity - forward = viewForward - (gravityNormal * viewForward) * gravityNormal; - forward.Normalize(); - - deltaAng1 = offset * forward; - deltaYaw = m_DeltaViewYaw; - - // use a different tolerance for rotating toward the rope vs away - // rotate forward by deltaAng to see if we are rotating towards or away from the rope - idRotation rotateView( vec3_origin, -gravityNormal, -deltaYaw ); - rotateView.RotatePoint( forward ); - - deltaAng2 = offset * forward; - - - // only rotate around the rope if looking at the rope to within some angular tolerance - // always rotate if shifting view away - if( deltaAng1 >= idMath::Cos( ROPE_ROTANG_TOL ) - || ( (deltaAng2 < deltaAng1) && deltaAng1 > 0 ) ) - { - - newOrigin = current.origin; - - // define the counter-rotation around the rope point using gravity axis - idRotation rotatePlayer( ropePoint, -gravityNormal, -deltaYaw ); - rotatePlayer.RotatePoint( newOrigin ); - - // check whether the player will clip anything when orbiting - transVec = newOrigin - current.origin; - ClipTranslation(transTrace, transVec, NULL); - newOrigin = current.origin + (transVec * transTrace.fraction); - - Translate( newOrigin - current.origin ); - } - - - // ================ read control input for climbing movement =============== - - upscale = (climbDir * viewForward - 0.5f) * 2.5f; - if ( upscale > 1.0f ) - { - upscale = 1.0f; - } - else if ( upscale < -1.0f ) - { - upscale = -1.0f; - } - - scale = idPhysics_Player::CmdScale( command ); - // up down movement - - wishvel = 0.9f * climbDir * upscale * scale * (float)command.forwardmove; - - /* greebo: Removed command.upmove portion from wishvel. I guess this was to support - the old crouching code which set command.upmove to negative values. This code - is no longer there so command.upmove is only non-zero during jumping, - which we can ignore here. - - if ( command.upmove ) - { - wishvel += 0.5f * climbDir * scale * (float) command.upmove; - }*/ - - // detach the player from the rope if they jump - if ( idPhysics_Player::CheckRopeJump()) - { - RopeDetach(); - goto Quit; - } - - // if the player is above the top of the rope, don't climb up - // if the player is at the bottom of the rope, don't climb down - // subtract some amount to represent hanging on with arms above head - if ( - ( - wishvel * gravityNormal <= 0.0f - && (((current.origin * -gravityNormal) + ROPE_GRABHEIGHT ) > ropeTop) - ) - || - ( - wishvel * gravityNormal >= 0.0f - && (((current.origin * -gravityNormal) + ROPE_GRABHEIGHT + 35.0f) < ropeBot) - ) - ) - { - current.velocity -= (current.velocity * climbDir) * climbDir; - goto Quit; - } - - // accelerate - wishspeed = wishvel.Normalize(); - idPhysics_Player::Accelerate( wishvel, wishspeed, PM_ACCELERATE ); - - // cap the climb velocity - upscale = current.velocity * -climbDir; - if ( upscale < -PM_ROPESPEED ) - { - current.velocity += climbDir * (upscale + PM_ROPESPEED); - } - else if ( upscale > PM_ROPESPEED ) - { - current.velocity += climbDir * (upscale - PM_ROPESPEED); - } - - // stop the player from sliding when they let go of the button - if ( (wishvel * gravityNormal) == 0.0f ) - { - if ( current.velocity * gravityNormal < 0.0f ) - { - current.velocity += gravityVector * frametime; - if ( current.velocity * gravityNormal > 0.0f ) - { - current.velocity -= (gravityNormal * current.velocity) * gravityNormal; - } - } - else - { - current.velocity -= gravityVector * frametime; - if ( current.velocity * gravityNormal < 0.0f ) - { - current.velocity -= (gravityNormal * current.velocity) * gravityNormal; - } - } - } - - // If the player is climbing down and hits the ground, detach them from the rope - if ( (wishvel * gravityNormal) > 0.0f && groundPlane ) - { - RopeDetach(); - goto Quit; - } - - // move the player velocity back into the world frame - current.velocity += m_RefEntVelocity; - - // slide the player up and down with their calculated velocity - idPhysics_Player::SlideMove( false, ( command.forwardmove > 0 ), false, false ); - -Quit: - return; -} -#pragma warning( default : 4533 ) - -/* -============ -idPhysics_Player::RopeDetach -============ -*/ -void idPhysics_Player::RopeDetach() -{ - m_bOnRope = false; - - // start the reattach timer - SetNextAttachTime(gameLocal.time + cv_tdm_reattach_delay.GetFloat()); - - static_cast(self)->SetImmobilization( "RopeMove", 0 ); - - // move the player velocity back into the world frame - current.velocity += m_RefEntVelocity; - - // switch movement modes to the appropriate one - if ( waterLevel > WATERLEVEL_FEET ) - { - WaterMove(); - } - else - { - AirMove(); - } -} - -/* -============ -idPhysics_Player::ClimbDetach -============ -*/ -void idPhysics_Player::ClimbDetach( bool bStepUp ) -{ - m_bOnClimb = false; - m_ClimbingOnEnt = NULL; - m_bClimbDetachThisFrame = true; - - static_cast(self)->SetImmobilization("ClimbMove", 0); - - current.velocity += m_RefEntVelocity; - - // switch movement modes to the appropriate one - if( bStepUp ) - { - // Step up at the top of a ladder - idVec3 ClimbNormXY = m_vClimbNormal - (gravityNormal * m_vClimbNormal) * gravityNormal; - ClimbNormXY.Normalize(); - current.velocity += -ClimbNormXY * LADDER_TOPVELOCITY; - idPhysics_Player::SlideMove( false, true, false, true ); - } - else if ( waterLevel > WATERLEVEL_FEET ) - { - WaterMove(); - } - else - { - AirMove(); - } - - SetNextAttachTime(gameLocal.time + cv_tdm_reattach_delay.GetFloat()); - -} - -/* -============ -idPhysics_Player::LadderMove -============ -*/ -void idPhysics_Player::LadderMove( void ) -{ - idVec3 wishdir( vec3_zero ), wishvel( vec3_zero ), right( vec3_zero ); - idVec3 dir( vec3_zero ), start( vec3_zero ), end( vec3_zero ), delta( vec3_zero ); - idVec3 AttachVel( vec3_zero ), RefFrameVel( vec3_zero ); - idVec3 vReqVert( vec3_zero ), vReqHoriz( vec3_zero ), vHorizVect( vec3_zero ); - float wishspeed(0.0f), scale(0.0f), accel(0.0f); - float upscale(0.0f), horizscale(0.0f), NormalDot(0.0f); - trace_t SurfTrace; - bool bMoveAllowed( true ); - - accel = PM_ACCELERATE; - - // TODO: Support non-rope climbable AFs by storing the AF body hit in the trace? - SetRefEntVel( m_ClimbingOnEnt.GetEntity() ); - - // Move player into climbed on ent reference frame - current.velocity -= m_RefEntVelocity; - - idVec3 ClimbNormXY = m_vClimbNormal - (m_vClimbNormal * gravityNormal) * gravityNormal; - ClimbNormXY.Normalize(); - - // jump off the climbable surface if they jump, or fall off if they hit crouch - // angua: detaching when hitting crouch is handled in idPlayer::PerformImpulse - if (idPhysics_Player::CheckRopeJump()) - { - ClimbDetach(); - return; - } - - NormalDot = ClimbNormXY * viewForward; - // detach if their feet are on the ground walking away from the surface - if ( walking && -NormalDot * command.forwardmove < LADDER_WALKDETACH_DOT ) - { - ClimbDetach(); - return; - } - - // ====================== stick to the ladder ======================== - // Do a trace to figure out where to attach the player: - start = current.origin; - end = start - 48.0f * ClimbNormXY; - gameLocal.clip.Translation( SurfTrace, start, end, clipModel, clipModel->GetAxis(), clipMask, self ); - - // if there is a climbable surface in front of the player, stick to it - - idEntity* testEnt = gameLocal.entities[SurfTrace.c.entityNum]; // grayman #2787 - bool isVine = ( testEnt && testEnt->IsType( tdmVine::Type ) ); // grayman #2787 - if ( ( SurfTrace.fraction != 1.0f ) && - ( ( SurfTrace.c.material && SurfTrace.c.material->IsLadder() ) || isVine ) ) // grayman #2787 - { - // grayman #2787 - smooth out the end position if you struck a climbable vine piece. - // This fixes the choppy sideways movement on a vine. - - idVec3 endPoint = SurfTrace.endpos; - idVec3 p = endPoint; - if ( isVine ) - { - idVec3 vineOrigin = testEnt->GetPhysics()->GetOrigin(); - idVec3 vinePeak = vineOrigin + 3.875 * ClimbNormXY; // 3.875 is the distance from the vine origin to its peak - float c = ( vinePeak - start ) * ClimbNormXY; - float e = -ClimbNormXY * ClimbNormXY; - idVec3 size = GetBounds().GetSize(); - p = start - ( c/e - size.x/2 )*ClimbNormXY; - } - - m_vClimbPoint = p + cv_pm_climb_distance.GetFloat() * ClimbNormXY; -// m_vClimbPoint = endPoint + cv_pm_climb_distance.GetFloat() * ClimbNormXY; - AttachVel = 10 * (m_vClimbPoint - current.origin); - - // Now that we have a valid point, don't need to use the initial one - m_bClimbInitialPhase = false; - - // Update sounds and movement speed caps for the surface if we change surfaces - idStr surfName = g_Global.GetSurfName(SurfTrace.c.material); - - if (surfName != m_ClimbSurfName) - { - idStr LookUpName, TempStr; - const idKeyValue *kv = NULL; - - m_ClimbSurfName = surfName; - - LookUpName = "climb_max_speed_vert_"; - TempStr = LookUpName + surfName; - if( ( kv = self->spawnArgs.FindKey(LookUpName.c_str()) ) != NULL ) - m_ClimbMaxVelVert = atof( kv->GetValue().c_str() ); - else - { - TempStr = LookUpName + "default"; - m_ClimbMaxVelVert = self->spawnArgs.GetFloat( LookUpName.c_str(), "1.0" ); - } - - LookUpName = "climb_max_speed_horiz_"; - TempStr = LookUpName + surfName; - if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) - m_ClimbMaxVelHoriz = atof( kv->GetValue().c_str() ); - else - { - TempStr = LookUpName + "default"; - m_ClimbMaxVelHoriz = self->spawnArgs.GetFloat( LookUpName.c_str(), "2.3" ); - } - - // sound repitition distances - LookUpName = "climb_snd_repdist_vert_"; - TempStr = LookUpName + surfName; - if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) - m_ClimbSndRepDistVert = atoi( kv->GetValue().c_str() ); - else - { - TempStr = LookUpName + "default"; - m_ClimbSndRepDistVert = self->spawnArgs.GetInt( LookUpName.c_str(), "32" ); - } - - // sound repitition distances - LookUpName = "climb_snd_repdist_horiz_"; - TempStr = LookUpName + surfName; - if( ( kv = const_cast( self->spawnArgs.FindKey(LookUpName.c_str())) ) != NULL ) - m_ClimbSndRepDistHoriz = atoi( kv->GetValue().c_str() ); - else - { - TempStr = LookUpName + "default"; - m_ClimbSndRepDistHoriz = self->spawnArgs.GetInt( LookUpName.c_str(), "32" ); - } - } - } - else if( m_bClimbInitialPhase ) - { - // We should already have m_vClimbPoint stored from the initial trace - AttachVel = 12.0f * (m_vClimbPoint - current.origin); - } - - current.velocity = (gravityNormal * current.velocity) * gravityNormal + AttachVel; - - scale = idPhysics_Player::CmdScale( command ); - - float lenVert = viewForward * -gravityNormal; - float lenTransv = idMath::Sqrt( 1.0f - NormalDot * NormalDot - lenVert * lenVert ); - // Dump everything that's not in the transverse direction into the vertical direction - float lenVert2 = idMath::Sqrt( 1.0f - lenTransv * lenTransv ); - - // resolve up/down, with some tolerance so player can still go up looking slightly down - if( lenVert < -0.3 ) - lenVert2 = -lenVert2; - - vReqVert = lenVert2 * -gravityNormal * scale * (float)command.forwardmove; - vReqVert *= m_ClimbMaxVelVert; - - // obtain the horizontal direction - vReqHoriz = viewForward - (ClimbNormXY * viewForward) * ClimbNormXY; - vReqHoriz -= (vReqHoriz * gravityNormal) * gravityNormal; - vReqHoriz.Normalize(); - vReqHoriz *= lenTransv * scale * (float)command.forwardmove; - vReqHoriz *= m_ClimbMaxVelHoriz; - - - // Pure horizontal motion if looking close enough to horizontal: - if( lenTransv > 0.906 ) - wishvel = vReqHoriz; - else - wishvel = vReqVert + vReqHoriz; - - // strafe - if ( command.rightmove ) - { - // right vector orthogonal to gravity - right = viewRight - (gravityNormal * viewRight) * gravityNormal; - // project right vector into ladder plane - right = right - (ClimbNormXY * right) * ClimbNormXY; - right.Normalize(); - - wishvel += m_ClimbMaxVelHoriz * right * scale * (float) command.rightmove; - } - - // ========================== Surface Extent Test ====================== - // This now just checks distance from the last valid climbing point - dir = wishvel; - dir.Normalize(); - - end = start + wishvel * frametime + dir * CLIMB_SURFCHECK_DELTA; - delta = m_vClimbPoint - end; - if( delta.LengthSqr() > LADDER_DISTAWAY * LADDER_DISTAWAY ) - bMoveAllowed = false; - - if( !bMoveAllowed ) - { - // If we were trying to go up and reached the extent, attempt to step off the ladder - // Make sure we are really trying to go up, not first going off to the side and then up - // TODO: Tweak this delta.lengthsqr parameter of 25.0, only measure in the horizontal axis? - delta = current.origin - m_vClimbPoint; - delta -= (delta * gravityNormal) * gravityNormal; - - if( NormalDot < 0.0f && -wishvel * gravityNormal > 0 && delta.LengthSqr() < 25.0f ) - { - ClimbDetach( true ); - return; - } - - accel = idMath::INFINITY; - wishvel = vec3_zero; - } - - // ========================== End Surface Extent Test ================== - - // do strafe friction - idPhysics_Player::Friction(); - - // accelerate - wishspeed = wishvel.Normalize(); - idPhysics_Player::Accelerate( wishvel, wishspeed, accel ); - - // cap the vertical travel velocity - upscale = current.velocity * -gravityNormal; - if ( upscale < -m_ClimbMaxVelVert * playerSpeed ) - current.velocity += gravityNormal * (upscale + m_ClimbMaxVelVert * playerSpeed ); - else if ( upscale > m_ClimbMaxVelVert * playerSpeed ) - current.velocity += gravityNormal * (upscale - m_ClimbMaxVelVert * playerSpeed ); - - // cap the horizontal travel velocity - vHorizVect = current.velocity - (current.velocity * gravityNormal) * gravityNormal; - horizscale = vHorizVect.Normalize(); - float horizDelta = horizscale; - horizscale = idMath::ClampFloat( -m_ClimbMaxVelHoriz * playerSpeed, m_ClimbMaxVelHoriz * playerSpeed, horizscale ); - horizDelta -= horizscale; - current.velocity -= vHorizVect * horizDelta; - - if ( (wishvel * gravityNormal) == 0.0f ) - { - if ( current.velocity * gravityNormal < 0.0f ) - { - current.velocity += gravityVector * frametime; - if ( current.velocity * gravityNormal > 0.0f ) - { - current.velocity -= (gravityNormal * current.velocity) * gravityNormal; - } - } - else { - current.velocity -= gravityVector * frametime; - if ( current.velocity * gravityNormal < 0.0f ) - { - current.velocity -= (gravityNormal * current.velocity) * gravityNormal; - } - } - } - - // Move player velocity back into the world frame - current.velocity += m_RefEntVelocity; - - idPhysics_Player::SlideMove( false, ( command.forwardmove > 0 ), false, false ); -} - -/* -============= -idPhysics_Player::CorrectAllSolid -============= -*/ -void idPhysics_Player::CorrectAllSolid( trace_t &trace, int contents ) { - if ( debugLevel ) { - gameLocal.Printf( "%i:allsolid\n", c_pmove ); - } - - // SophisticatedZombie - //DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("performing CorrectAllSolid due to player inside solid object\n"); - // - // Don't bump player up if they're standing in a previously picked up objects. - // This is complicated but because we want free object movement, we have to temporarily disable player clipping. - // But, if a players releases an object when they're inside it they float to the surface. By doing this check - // we can avoid that. - // ishtvan: Only use the "rising code" if we're still clipping something after a mantle has finished - if( m_mantlePhase == fixClipping_DarkModMantlePhase - && !gameLocal.m_Grabber->HasClippedEntity() ) - { - current.origin -= (GetGravityNormal() * 0.2f); - } - - - // FIXME: jitter around to find a free spot ? - - if ( trace.fraction >= 1.0f ) { - memset( &trace, 0, sizeof( trace ) ); - trace.endpos = current.origin; - trace.endAxis = clipModelAxis; - trace.fraction = 0.0f; - trace.c.dist = current.origin.z; - trace.c.normal.Set( 0, 0, 1 ); - trace.c.point = current.origin; - trace.c.entityNum = ENTITYNUM_WORLD; - trace.c.id = 0; - trace.c.type = CONTACT_TRMVERTEX; - trace.c.material = NULL; - trace.c.contents = contents; - } -} - -/* -============= -idPhysics_Player::CheckGround -============= -*/ -void idPhysics_Player::CheckGround( void ) { - int i, contents; - idVec3 point; - bool hadGroundContacts; - - hadGroundContacts = HasGroundContacts(); - - // set the clip model origin before getting the contacts - clipModel->SetPosition( current.origin, clipModel->GetAxis() ); - - EvaluateContacts(); - - // setup a ground trace from the contacts - groundTrace.endpos = current.origin; - groundTrace.endAxis = clipModel->GetAxis(); - if ( contacts.Num() ) { - groundTrace.fraction = 0.0f; - groundTrace.c = contacts[0]; - for ( i = 1; i < contacts.Num(); i++ ) { - groundTrace.c.normal += contacts[i].normal; - } - groundTrace.c.normal.Normalize(); - } else { - groundTrace.fraction = 1.0f; - } - - contents = gameLocal.clip.Contents( current.origin, clipModel, clipModel->GetAxis(), -1, self ); - if ( contents & MASK_SOLID ) - { - // do something corrective if stuck in solid - idPhysics_Player::CorrectAllSolid( groundTrace, contents ); - } - else if ( m_mantlePhase == fixClipping_DarkModMantlePhase ) - { - // the mantle stage can advance to done if we're not currently clipping - m_mantlePhase = notMantling_DarkModMantlePhase; - } - - // if the trace didn't hit anything, we are in free fall - if ( groundTrace.fraction == 1.0f ) - { - groundPlane = false; - walking = false; - groundEntityPtr = NULL; - return; - } - - groundMaterial = groundTrace.c.material; - - // Store the ground entity - idEntity* groundEnt = gameLocal.entities[ groundTrace.c.entityNum ]; - groundEntityPtr = groundEnt; - - // check if getting thrown off the ground - if ( (current.velocity * -gravityNormal) > 0.0f && ( current.velocity * groundTrace.c.normal ) > 10.0f ) { - if ( debugLevel ) { - gameLocal.Printf( "%i:kickoff\n", c_pmove ); - } - - groundPlane = false; - walking = false; - return; - } - - // grayman #2409 - apply velocity change due to friction loss on slick surfaces - - bool slick = (groundMaterial && (groundMaterial->IsSlick())); - float walkNormal = MIN_WALK_NORMAL; - if (slick) - { - idVec3 velocityChange = groundTrace.c.normal; - velocityChange.z = 0; // no vertical component - current.velocity += 3*velocityChange; - walkNormal = MIN_WALK_SLICK_NORMAL; - } - - // slopes that are too steep will not be considered onground - if ( ( groundTrace.c.normal * -gravityNormal ) < walkNormal ) // grayman #2409 - { - if ( debugLevel ) { - gameLocal.Printf( "%i:steep\n", c_pmove ); - } - - // FIXME: if they can't slide down the slope, let them walk (sharp crevices) - - // make sure we don't die from sliding down a steep slope - if ( current.velocity * gravityNormal > 150.0f ) { - current.velocity -= ( current.velocity * gravityNormal - 150.0f ) * gravityNormal; - } - - groundPlane = true; - walking = false; - return; - } - - groundPlane = true; - walking = true; - - // hitting solid ground will end a waterjump - if ( current.movementFlags & PMF_TIME_WATERJUMP ) { - current.movementFlags &= ~( PMF_TIME_WATERJUMP | PMF_TIME_LAND ); - current.movementTime = 0; - } - - // if the player didn't have ground contacts the previous frame - if ( !hadGroundContacts ) { - // greebo: Set the "jump" deadtime in any case to 100 msec to disallow jumps for small timespan - current.movementTime = 100; - - // don't do landing time if we were just going down a slope - if ( (current.velocity * -gravityNormal) < -200.0f ) { - // don't allow another jump for a little while - current.movementFlags |= PMF_TIME_LAND; - current.movementTime = 100; - } - } - - // let the entity know about the collision - self->Collide( groundTrace, current.velocity ); - - groundEnt = groundEntityPtr.GetEntity(); - - if ( groundTrace.c.entityNum != ENTITYNUM_WORLD && groundEnt != NULL ) - { - idPhysics* groundPhysics = groundEnt->GetPhysics(); - - impactInfo_t info; - groundEnt->GetImpactInfo( self, groundTrace.c.id, groundTrace.c.point, &info ); - - // greebo: Don't push entities that already have a velocity towards the ground. - if (groundPhysics != NULL && info.invMass != 0.0f && - idMath::Fabs(groundPhysics->GetLinearVelocity()*gravityNormal) < VECTOR_EPSILON) - { - // greebo: Apply a force to the entity below the player - //gameRenderWorld->DebugArrow(colorCyan, current.origin, current.origin + gravityNormal*20, 1, 16); - groundPhysics->AddForce(0, current.origin, gravityNormal*mass*cv_pm_weightmod.GetFloat()); - } - } -} - -/* -============== -idPhysics_Player::CheckDuck - -Sets clip model size -============== -*/ -void idPhysics_Player::CheckDuck( void ) { - float maxZ; - - idPlayer* player = static_cast(self); - int oldMovementFlags = current.movementFlags; - - bool idealCrouchState = player->GetIdealCrouchState(); - - if ( current.movementType == PM_DEAD ) { - maxZ = pm_deadheight.GetFloat(); - } else { - // stand up when climbing a ladder or rope - if (idealCrouchState == true && !m_bOnClimb && !m_bOnRope) - { - if (waterLevel <= WATERLEVEL_WAIST) - { - // greebo: We're waist-deep in water, trace down a few units to see if we're standing on ground - trace_t trace; - idVec3 end = current.origin + gravityNormal * 20; - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); - - if (trace.fraction < 1.0f) - { - // We're not floating in deep water, we're standing in waist-deep water, duck as requested. - current.movementFlags |= PMF_DUCKED; - } - } - else - { - // We're outside of water, just duck as requested - current.movementFlags |= PMF_DUCKED; - } - - // greebo: Update the lean physics when crouching - UpdateLeanPhysics(); - } - else if (!IsMantling() && idealCrouchState == false) // MantleMod: SophisticatedZombie (DH): Don't stand up if crouch during mantle - { - // ideal crouch state is not negative anymore, check if we are still in crouch mode - // stand up if appropriate - if ( current.movementFlags & PMF_DUCKED ) - { - bool canStandUp = true; - - if (waterLevel >= WATERLEVEL_HEAD) - { - // greebo: We're still in water, check if there is ground below us so that we can stand up - trace_t trace; - float viewHeightDelta = pm_normalviewheight.GetFloat() - pm_crouchviewheight.GetFloat(); - idVec3 end = current.origin + gravityNormal * viewHeightDelta; - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); - - if (trace.fraction == 1.0f) - { - canStandUp = false; // trace missed, no ground below - } - else - { - // The ground trace hit a target, see if our eyes would emerge from the water - idVec3 pointAboveHead = player->GetEyePosition() - gravityNormal * viewHeightDelta * (1.0f - trace.fraction); - - int contents = gameLocal.clip.Contents( pointAboveHead, NULL, mat3_identity, -1, self ); - if (contents & MASK_WATER) - { - canStandUp = false; // The point above our head is in water - } - } - } - - if (canStandUp) - { - // greebo: We're not in deep water, so try to stand up - idVec3 end = current.origin - ( pm_normalheight.GetFloat() - pm_crouchheight.GetFloat() ) * gravityNormal; - - // Now perform the upwards trace to check if we have room to stand up - trace_t trace; - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); - if ( trace.fraction >= 1.0f ) { - // We have room above us, so turn off the crouch flag - current.movementFlags &= ~PMF_DUCKED; - } - } - } - } - - // TODO_CROUCH: don't use crouch speed while climbing - if ( current.movementFlags & PMF_DUCKED ) - { - playerSpeed = crouchSpeed; - maxZ = pm_crouchheight.GetFloat(); - } - else - { - maxZ = pm_normalheight.GetFloat(); - } - - if (waterLevel == WATERLEVEL_HEAD) - { - // greebo: We're underwater, set the clipmodel to the crouched size - maxZ = pm_crouchheight.GetFloat(); - - // greebo: But still let the player swim as fast as if he was uncrouched - playerSpeed = walkSpeed; - } - - // greebo: Check if we've submersed in a liquid. If yes: set the clipmodel to crouchheight - // And set the DUCKED flag to 1. - if (waterLevelChanged) - { - if (waterLevel == WATERLEVEL_HEAD) - { - // We've just submersed into water, set the model to ducked - current.movementFlags |= PMF_DUCKED; - - // Translate the origin a bit upwards to prevent the player head from "jumping" downwards - SetOrigin(player->GetEyePosition() + gravityNormal * pm_crouchviewheight.GetFloat()); - - // Set the Eye height directly to the new value, to avoid the smoothing happening in idPlayer::Move() - player->SetEyeHeight(pm_crouchviewheight.GetFloat()); - } - else if ((oldMovementFlags & PMF_DUCKED) && waterLevel == WATERLEVEL_WAIST && previousWaterLevel == WATERLEVEL_HEAD) - { - // angua: only stand up when we should not be crouching - if (idealCrouchState == false) - { - // We're just floating up to the water surface, switch back to non-crouch mode - // Clear the flag again, just to be sure - current.movementFlags &= ~PMF_DUCKED; - - // greebo: Perform a trace to see how far we can move downwards - trace_t trace; - idVec3 end = player->GetEyePosition() + gravityNormal * pm_normalviewheight.GetFloat(); - gameLocal.clip.Translation(trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self); - - // Set the origin to the end position of the trace - SetOrigin(trace.endpos); - - maxZ = pm_normalheight.GetFloat(); - - // Set the Eye height directly to the new value, to avoid the smoothing happening in idPlayer::Move() - player->SetEyeHeight(pm_normalviewheight.GetFloat()); - } - } - } - - // greebo: Update the lean physics when not crouching - UpdateLeanPhysics(); - } - - // if the clipModel height should change - if ( clipModel->GetBounds()[1][2] != maxZ ) - { - idBounds bounds = clipModel->GetBounds(); - bounds[1][2] = maxZ; - if ( pm_usecylinder.GetBool() ) { - clipModel->LoadModel( idTraceModel( bounds, 8 ) ); - } else { - clipModel->LoadModel( idTraceModel( bounds ) ); - } - } -} - -/* -================ -idPhysics_Player::CheckClimbable -DarkMod: Checks ropes, ladders and other climbables -================ -*/ -void idPhysics_Player::CheckClimbable( void ) -{ - if( current.movementTime ) - return; - - // if on the ground moving backwards - // TODO: This causes problems when rope-climbing down a steep incline - if( walking && command.forwardmove <= 0 ) - return; - - // Don't attach to ropes or ladders in the middle of a mantle - if ( IsMantling() ) - return; - - if ( m_bClimbDetachCrouchHeld ) - return; - -/* - // Don't attach if we are holding an object in our hands - if( gameLocal.m_Grabber->GetSelected() != NULL ) - goto Quit; -*/ - - // forward vector orthogonal to gravity - idVec3 forward = viewForward - (gravityNormal * viewForward) * gravityNormal; - forward.Normalize(); - - float tracedist; - if ( walking ) - { - // don't want to get sucked towards the ladder when still walking or when climbing - tracedist = 1.0f; - } - else - { - tracedist = 48.0f; - } - - idVec3 end = current.origin + tracedist * forward; - // modified to check contents_corpse to check for ropes - trace_t trace; - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask | CONTENTS_CORPSE, self ); - - idVec3 delta; - float angleOff; - float dist; - // if near a surface - if ( trace.fraction < 1.0f ) - { - idEntity* testEnt = gameLocal.entities[trace.c.entityNum]; - - // DarkMod: Check if we're looking at a rope and airborne - // TODO: Check the class type instead of the stringname, make new rope class - - if ( testEnt && testEnt->m_bIsClimbableRope ) - { - m_RopeEntTouched = static_cast(testEnt); - - delta = (trace.c.point - current.origin); - delta = delta - (gravityNormal * delta) * gravityNormal; - dist = delta.LengthFast(); - - delta.Normalize(); - angleOff = delta * forward; - - // must be in the air to attach to the rope - // this is kind've a hack, but the rope has a different attach distance than the ladder - if( - !m_bOnRope - && ( (trace.endpos - current.origin).Length() <= 2.0f ) - && !groundPlane - && angleOff >= idMath::Cos( ROPE_ATTACHANGLE ) - && (testEnt != m_RopeEntity.GetEntity() || gameLocal.time > m_NextAttachTime) - ) - { - // make sure rope segment is not touching the ground - int bodyID = m_RopeEntTouched.GetEntity()->BodyForClipModelId( trace.c.id ); - if( !static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->HasGroundContacts( bodyID ) ) - { - m_bRopeContact = true; - m_bJustHitRope = true; - m_RopeEntity = static_cast(testEnt); - - return; - } - } - } - - // if a climbable surface - // grayman #2787 - add a test for a climbable vine. - - bool isVine = ( testEnt && testEnt->IsType( tdmVine::Type ) ); - if ( ( ( trace.c.material && ( trace.c.material->IsLadder() ) ) || isVine ) - && ( gameLocal.time > m_NextAttachTime ) ) - { - idVec3 vStickPoint = trace.endpos; - // check a step height higher - end = current.origin - gravityNormal * ( maxStepHeight * 0.75f ); - gameLocal.clip.Translation( trace, current.origin, end, clipModel, clipModel->GetAxis(), clipMask, self ); - idVec3 start = trace.endpos; - end = start + tracedist * forward; - gameLocal.clip.Translation( trace, start, end, clipModel, clipModel->GetAxis(), clipMask, self ); - - // if also near a surface a step height higher - if ( trace.fraction < 1.0f ) - { - // if it also is a ladder surface - // grayman #2787 - add a test for a climbable vine - - idEntity* testEntHigher = gameLocal.entities[trace.c.entityNum]; // grayman #2787 - bool isVineHigher = ( testEntHigher && testEntHigher->IsType( tdmVine::Type ) ); - if ( ( trace.c.material && trace.c.material->IsLadder() ) || isVineHigher ) // grayman #2787 - { - m_vClimbNormal = trace.c.normal; - if ( isVineHigher ) // grayman #2787 - if climbing a vine, flatten out the normal - { - m_vClimbNormal = testEntHigher->GetPhysics()->GetAxis().ToAngles().ToForward(); - } - m_ClimbingOnEnt = testEntHigher; - - // Initial climbing attachment - // FIX: Used to get stuck hovering in some cases, now there's an initial phase - if ( !m_bOnClimb ) - { - m_bClimbInitialPhase = true; - m_vClimbPoint = vStickPoint; - static_cast(self)->SetImmobilization( "ClimbMove", EIM_WEAPON_SELECT | EIM_ATTACK ); - } - - m_bClimbableAhead = true; - m_bOnClimb = true; - - return; - } - } - } - } - - // Rope attachment failsafe: Check intersection with the rope as well - if - ( - !m_bOnRope - && m_RopeEntTouched.GetEntity() != NULL - && m_RopeEntTouched.GetEntity()->GetPhysics()->GetAbsBounds().IntersectsBounds( self->GetPhysics()->GetAbsBounds() ) - && !groundPlane - ) - { - // test distance against the nearest rope body - int touchedBody = -1; - idVec3 PlayerPoint = current.origin + -gravityNormal*ROPE_GRABHEIGHT; - idVec3 RopeSegPoint = static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->NearestBodyOrig( PlayerPoint, &touchedBody ); - - delta = ( RopeSegPoint - PlayerPoint); - delta = delta - (gravityNormal * delta) * gravityNormal; - dist = delta.LengthFast(); - - delta.Normalize(); - angleOff = delta * forward; - - // if the player is looking high up, override the angle check - float lookUpAng = viewForward * -gravityNormal; - // set lookup to true if the player is looking 60 deg up or more - bool bLookingUp = lookUpAng >= idMath::Cos(idMath::PI/6); - - if - ( - dist <= ROPE_DISTANCE - && ( angleOff >= idMath::Cos( ROPE_ATTACHANGLE ) || bLookingUp ) - && (m_RopeEntTouched.GetEntity() != m_RopeEntity.GetEntity() || gameLocal.time > m_NextAttachTime) - && !static_cast(m_RopeEntTouched.GetEntity()->GetPhysics())->HasGroundContacts( touchedBody ) - ) - { - m_bRopeContact = true; - m_bJustHitRope = true; - m_RopeEntity = m_RopeEntTouched.GetEntity(); - return; - } - } -} - -/* -============= -idPhysics_Player::CheckJump -============= -*/ -bool idPhysics_Player::CheckJump() -{ - if ( command.upmove < 10 ) - { - // not holding jump - return false; - } - - // must wait for jump to be released or dead time to have passed - if ( current.movementFlags & PMF_JUMP_HELD || current.movementTime > 0) - { - return false; - } - - groundPlane = false; // jumping away - walking = false; - current.movementFlags |= PMF_JUMP_HELD | PMF_JUMPED; - - idVec3 extraSpeedForward = viewForward - (gravityNormal * viewForward) * gravityNormal; - extraSpeedForward.Normalize(); - - // back paddling ? - if ( command.forwardmove < 0 ) - { - // greebo: Apply a modifier when doing backwards jumps - extraSpeedForward = -extraSpeedForward * cv_tdm_backwards_jump_modifier.GetFloat(); - } - - // strafing right? - if ( command.rightmove > 0) - { - extraSpeedForward = viewRight - (gravityNormal * viewRight) * gravityNormal; - extraSpeedForward.Normalize(); - } - // strafing left? - else if ( command.rightmove < 0 ) - { - extraSpeedForward = viewRight - (gravityNormal * viewRight) * gravityNormal; - extraSpeedForward = -extraSpeedForward; - extraSpeedForward.Normalize(); - } - - idVec3 addVelocity; - float curVelocity = current.velocity.LengthFast(); - - // are we walking? - if ( curVelocity >= cv_tdm_min_vel_jump.GetFloat() && - curVelocity >= pm_walkspeed.GetFloat() && - curVelocity < ( pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat() ) ) - { - addVelocity = cv_tdm_walk_jump_vel.GetFloat() * maxJumpHeight * -gravityVector; - extraSpeedForward *= cv_tdm_fwd_jump_vel.GetFloat(); - } - // running ? - else if ( curVelocity >= cv_tdm_min_vel_jump.GetFloat() - && curVelocity >= cv_pm_runmod.GetFloat()) - { - addVelocity = cv_tdm_run_jump_vel.GetFloat() * maxJumpHeight * -gravityVector; - extraSpeedForward *= cv_tdm_fwd_jump_vel.GetFloat(); - } - // stationary - else - { - addVelocity = 2.0f * maxJumpHeight * -gravityVector; - } - - // angua: reduce jump velocity when crouching, unless we are on a ladder or rope - // cv_tdm_crouch_jump_vel can also be set to 0 to disable jumping while crouching - if ( current.movementFlags & PMF_DUCKED && !OnRope() && !OnLadder()) - { - addVelocity *= cv_tdm_crouch_jump_vel.GetFloat(); - extraSpeedForward *= cv_tdm_crouch_jump_vel.GetFloat(); - } - - if (addVelocity.LengthFast() > 0) - { - addVelocity *= idMath::Sqrt( addVelocity.Normalize() ); - } - - // greebo: Consider jump stamina - float jumpStaminaFactor = 1.0f; - - if (lastJumpTime > -1) - { - int timeSinceLastJump = gameLocal.time - lastJumpTime; - - float jumpRelaxationTime = SEC2MS(cv_tdm_jump_relaxation_time.GetFloat()); - - float factor = timeSinceLastJump * timeSinceLastJump / (jumpRelaxationTime * jumpRelaxationTime); - - jumpStaminaFactor = idMath::ClampFloat(0.2f, 1, factor); - } - - current.velocity += addVelocity + extraSpeedForward * jumpStaminaFactor; - - // Remember the last jump time - if (jumpStaminaFactor > 0.1f) - { - lastJumpTime = gameLocal.time; - } - - return true; -} - -/* -============= -idPhysics_Player::CheckRopeJump -============= -*/ -bool idPhysics_Player::CheckRopeJump( void ) -{ - if ( command.upmove < 10 ) { - // not holding jump - return false; - } - - // must wait for jump to be released - if ( current.movementFlags & PMF_JUMP_HELD ) { - return false; - } - - // angua: should be able to jump on a rope or ladder, even when crouched - // don't jump if we can't stand up - // if ( current.movementFlags & PMF_DUCKED ) { - // return false; - // } - - groundPlane = false; // jumping away - walking = false; - current.movementFlags |= PMF_JUMP_HELD | PMF_JUMPED; - - // the jump direction is an equal sum of up and the direction we're looking - idVec3 jumpDir = viewForward - gravityNormal; - jumpDir *= 1.0f/idMath::Sqrt(2.0f); - -// TODO: Make this an adjustable cvar, currently too high? - idVec3 addVelocity = 2.0f * maxJumpHeight * gravityVector.Length() * jumpDir; - addVelocity *= idMath::Sqrt( addVelocity.Normalize() ); - - current.velocity += addVelocity; - - return true; -} - -/* -============= -idPhysics_Player::CheckWaterJump - -REMOVED from DarkMod -============= -*/ - -/* - -============= - -idPhysics_Player::SetWaterLevel - -For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp - -============= - -*/ - -#ifndef MOD_WATERPHYSICS - -void idPhysics_Player::SetWaterLevel( void ) { - idVec3 point; - idBounds bounds; - int contents; - - // - // get waterlevel, accounting for ducking - // - waterLevel = WATERLEVEL_NONE; - waterType = 0; - - bounds = clipModel->GetBounds(); - - // check at feet level - point = current.origin - ( bounds[0][2] + 1.0f ) * gravityNormal; - contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - - waterType = contents; - waterLevel = WATERLEVEL_FEET; - - // check at waist level - point = current.origin - ( bounds[1][2] - bounds[0][2] ) * 0.5f * gravityNormal; - contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - - waterLevel = WATERLEVEL_WAIST; - - // check at head level - point = current.origin - ( bounds[1][2] - 1.0f ) * gravityNormal; - contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self ); - if ( contents & MASK_WATER ) { - waterLevel = WATERLEVEL_HEAD; - } - } - } -} -#endif - -/* -================ -idPhysics_Player::DropTimers -================ -*/ -void idPhysics_Player::DropTimers( void ) { - // drop misc timing counter - if ( current.movementTime ) { - if ( framemsec >= current.movementTime ) { - current.movementFlags &= ~PMF_ALL_TIMES; - current.movementTime = 0; - } - else { - current.movementTime -= framemsec; - } - } -} - -/* -================ -idPhysics_Player::MovePlayer -================ -*/ -void idPhysics_Player::MovePlayer( int msec ) { - - // this counter lets us debug movement problems with a journal - // by setting a conditional breakpoint for the previous frame - c_pmove++; - - walking = false; - groundPlane = false; - - m_bRopeContact = false; - m_bClimbableAhead = false; - m_bClimbDetachThisFrame = false; - - // determine the time - framemsec = msec; - frametime = framemsec * 0.001f; - - // default speed - playerSpeed = walkSpeed; - - // remove jumped and stepped up flag - current.movementFlags &= ~(PMF_JUMPED|PMF_STEPPED_UP|PMF_STEPPED_DOWN); - current.stepUp = 0.0f; - - if ( command.upmove < 10 ) { - // not holding jump - current.movementFlags &= ~PMF_JUMP_HELD; - - if (m_mantlePhase == notMantling_DarkModMantlePhase - || m_mantlePhase == fixClipping_DarkModMantlePhase) - { - // greebo: Jump button is released and no mantle phase is active, - // we can allow the next mantling process. - m_mantleStartPossible = true; - } - } - - // if no movement at all - if ( current.movementType == PM_FREEZE ) { - return; - } - - // move the player velocity into the frame of a pusher - current.velocity -= current.pushVelocity; - - // view vectors - viewAngles.ToVectors( &viewForward, NULL, NULL ); - viewForward *= clipModelAxis; - viewRight = gravityNormal.Cross( viewForward ); - viewRight.Normalize(); - - // fly in spectator mode - if ( current.movementType == PM_SPECTATOR ) { - SpectatorMove(); - idPhysics_Player::DropTimers(); - return; - } - - // special no clip mode - if ( current.movementType == PM_NOCLIP ) { - idPhysics_Player::NoclipMove(); - idPhysics_Player::DropTimers(); - return; - } - - // no control when dead - if ( current.movementType == PM_DEAD ) { - command.forwardmove = 0; - command.rightmove = 0; - command.upmove = 0; - } - - // set watertype and waterlevel - idPhysics_Player::SetWaterLevel(true); // greebo: Update the previousWaterLevel here - - // check for ground - idPhysics_Player::CheckGround(); - - // check if a ladder or a rope is straight ahead - idPhysics_Player::CheckClimbable(); - - // set clip model size - idPhysics_Player::CheckDuck(); - - // handle timers - idPhysics_Player::DropTimers(); - - // Mantle Mod: SophisticatdZombie (DH) - idPhysics_Player::UpdateMantleTimers(); - - // Lean Mod: Zaccheus and SophisticatedZombie (DH) - idPhysics_Player::LeanMove(); - - // Check if holding down jump - if (CheckJumpHeldDown()) - { - PerformMantle(); - } - - // move - if ( current.movementType == PM_DEAD ) { - // dead - DeadMove(); - } - // continue moving on the rope if still attached - else if ( m_bOnRope ) - { - // Check rope movement and let go if the rope is moving too fast - float maxRopeVelocity = cv_pm_rope_velocity_letgo.GetFloat(); - idEntity* ropeEntity = m_RopeEntity.GetEntity(); - if (ropeEntity != NULL) - { - - float ropeVelocity = ropeEntity->/*GetBindMaster()->*/GetPhysics()->GetLinearVelocity().z; - - //gameLocal.Printf("Rope Velocity: %f\n", m_RopeEntity.GetEntity()->GetBindMaster()->GetPhysics()->GetLinearVelocity().LengthFast()); - if (ropeVelocity > maxRopeVelocity) - { - gameLocal.Printf("Rope is too fast (%f)! Letting go...\n", ropeVelocity); - RopeDetach(); - } - } - - RopeMove(); - } - // Mantle MOD - // SophisticatedZombie (DH) - // greebo: Do the MantleMove before checking the rope contacts - else if ( !(m_mantlePhase == notMantling_DarkModMantlePhase || m_mantlePhase == fixClipping_DarkModMantlePhase) ) - { - MantleMove(); - } - else if ( m_bRopeContact ) - { - // toggle m_bOnRope - m_bOnRope = true; - - // lower weapon - static_cast(self)->SetImmobilization( "RopeMove", EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_DROP ); - - RopeMove(); - } - else if ( m_bOnClimb ) - { - // going up or down a ladder - LadderMove(); - } - else if ( waterLevel > WATERLEVEL_FEET ) - { - // swimming - WaterMove(); - } - else if ( walking ) { - // walking on ground - WalkMove(); - } - else { - // airborne - AirMove(); - } - - // enable weapon if not swimming - if( waterLevel <= WATERLEVEL_FEET && static_cast(self)->GetImmobilization("WaterMove") ) - { - static_cast(self)->SetImmobilization("WaterMove", 0); - } - - // set watertype, waterlevel and groundentity - SetWaterLevel(false); // greebo: Don't update the previousWaterLevel this time - CheckGround(); - - // move the player velocity back into the world frame - current.velocity += current.pushVelocity; - current.pushVelocity.Zero(); - - // DEBUG - /* - gameRenderWorld->DebugBounds - ( - idVec4 (1.0, 0.0, 1.0, 1.0), - clipModel->GetAbsBounds(), - idVec3 (0.0, 0.0, 0.0) - ); - */ - - m_lastCommandViewYaw = command.angles[1]; - m_lastCommandViewPitch = command.angles[0]; - -} - -#ifndef MOD_WATERPHYSICS - -/* -================ -idPhysics_Player::GetWaterLevel - -For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp - -================ -*/ -waterLevel_t idPhysics_Player::GetWaterLevel( void ) const { - return waterLevel; -} - -/* -================ -idPhysics_Player::GetWaterType - -For MOD_WATERPHYSICS this is moved to Physics_Actor.cpp - -================ -*/ -int idPhysics_Player::GetWaterType( void ) const { - return waterType; -} - -#endif - - -/* -================ -idPhysics_Player::HasJumped -================ -*/ -bool idPhysics_Player::HasJumped( void ) const { - return ( ( current.movementFlags & PMF_JUMPED ) != 0 && current.movementTime <= 0); -} - -/* -================ -idPhysics_Player::HasSteppedUp -================ -*/ -bool idPhysics_Player::HasSteppedUp( void ) const { - return ( ( current.movementFlags & ( PMF_STEPPED_UP | PMF_STEPPED_DOWN ) ) != 0 ); -} - -/* -================ -idPhysics_Player::GetStepUp -================ -*/ -float idPhysics_Player::GetStepUp( void ) const { - return current.stepUp; -} - -/* -================ -idPhysics_Player::IsCrouching -================ -*/ -bool idPhysics_Player::IsCrouching( void ) const { - return ( ( current.movementFlags & PMF_DUCKED ) != 0 ); -} - -idEntity* idPhysics_Player::GetRopeEntity() -{ - return (m_bOnRope) ? m_RopeEntity.GetEntity() : NULL; -} - -/* -================ -idPhysics_Player::OnRope -================ -*/ -bool idPhysics_Player::OnRope( void ) const -{ - return m_bOnRope; -} - - -/* -================ -idPhysics_Player::OnLadder -================ -*/ -bool idPhysics_Player::OnLadder( void ) const { - return m_bOnClimb; -} - -/* -================ -idPhysics_Player::idPhysics_Player -================ -*/ -idPhysics_Player::idPhysics_Player( void ) -{ - debugLevel = false; - clipModel = NULL; - clipMask = 0; - memset( ¤t, 0, sizeof( current ) ); - saved = current; - walkSpeed = 0; - crouchSpeed = 0; - maxStepHeight = 0; - maxJumpHeight = 0; - memset( &command, 0, sizeof( command ) ); - - lastJumpTime = -1; - - viewAngles.Zero(); - framemsec = 0; - frametime = 0; - playerSpeed = 0; - viewForward.Zero(); - viewRight.Zero(); - walking = false; - groundPlane = false; - memset( &groundTrace, 0, sizeof( groundTrace ) ); - groundMaterial = NULL; - - m_RefEntVelocity.Zero(); - - // rope climbing - m_bRopeContact = false; - m_bOnRope = false; - m_bJustHitRope = false; - m_RopeEntity = NULL; - m_RopeEntTouched = NULL; - m_RopeKickTime = 0; - - // wall/ladder climbing - m_bClimbableAhead = false; - m_bOnClimb = false; - m_bClimbDetachThisFrame = false; - m_bClimbInitialPhase = false; - m_vClimbNormal.Zero(); - m_vClimbPoint.Zero(); - m_ClimbingOnEnt = NULL; - m_ClimbSurfName.Clear(); - m_ClimbMaxVelHoriz = 0.0f; - m_ClimbMaxVelVert = 0.0f; - m_ClimbSndRepDistVert = 0; - m_ClimbSndRepDistHoriz = 0; - m_bClimbDetachCrouchHeld = false; - - m_NextAttachTime = -1; - - m_PushForce = CForcePushPtr(new CForcePush); - - // swimming - waterLevel = WATERLEVEL_NONE; - waterType = 0; - - // Mantle Mod - m_mantlePhase = notMantling_DarkModMantlePhase; - m_mantleTime = 0.0; - m_p_mantledEntity = NULL; - m_mantledEntityID = 0; - m_jumpHeldDownTime = 0.0; - m_mantleStartPossible = true; - - // Leaning Mod - m_bIsLeaning = false; - m_leanYawAngleDegrees = 0.0; - m_CurrentLeanTiltDegrees = 0.0; - m_CurrentLeanStretch = 0.0; - m_b_leanFinished = true; - m_leanMoveStartTilt = 0.0; - m_leanMoveEndTilt = 0.0; - m_leanMoveMaxAngle = 0.0; - m_leanMoveMaxStretch = 0.0; - - m_lastCommandViewYaw = 0; - m_lastCommandViewPitch = 0; - m_viewLeanAngles = ang_zero; - m_viewLeanTranslation = vec3_zero; - - m_LeanDoorListenPos = vec3_zero; - m_LeanDoorEnt = NULL; - - m_DeltaViewYaw = 0.0; - m_DeltaViewPitch = 0.0; - - // Initialize lean view bounds used for collision - m_LeanViewBounds.Zero(); - m_LeanViewBounds.ExpandSelf( 4.0f ); - // bounds extend downwards so that player can't lean over very high ledges - idVec3 lowerPoint(0,0,-15.0f); - m_LeanViewBounds.AddPoint( lowerPoint ); -} - -/* -================ -idPhysics_Player_SavePState -================ -*/ -void idPhysics_Player_SavePState( idSaveGame *savefile, const playerPState_t &state ) { - savefile->WriteVec3( state.origin ); - savefile->WriteVec3( state.velocity ); - savefile->WriteVec3( state.localOrigin ); - savefile->WriteVec3( state.pushVelocity ); - savefile->WriteFloat( state.stepUp ); - savefile->WriteInt( state.movementType ); - savefile->WriteInt( state.movementFlags ); - savefile->WriteInt( state.movementTime ); -} - -/* -================ -idPhysics_Player_RestorePState -================ -*/ -void idPhysics_Player_RestorePState( idRestoreGame *savefile, playerPState_t &state ) { - savefile->ReadVec3( state.origin ); - savefile->ReadVec3( state.velocity ); - savefile->ReadVec3( state.localOrigin ); - savefile->ReadVec3( state.pushVelocity ); - savefile->ReadFloat( state.stepUp ); - savefile->ReadInt( state.movementType ); - savefile->ReadInt( state.movementFlags ); - savefile->ReadInt( state.movementTime ); -} - -/* -================ -idPhysics_Player::Save -================ -*/ -void idPhysics_Player::Save( idSaveGame *savefile ) const { - - idPhysics_Player_SavePState( savefile, current ); - idPhysics_Player_SavePState( savefile, saved ); - - savefile->WriteFloat( walkSpeed ); - savefile->WriteFloat( crouchSpeed ); - savefile->WriteFloat( maxStepHeight ); - savefile->WriteFloat( maxJumpHeight ); - savefile->WriteInt( debugLevel ); - savefile->WriteInt(lastJumpTime); - - savefile->WriteUsercmd( command ); - savefile->WriteAngles( viewAngles ); - - savefile->WriteInt( framemsec ); - savefile->WriteFloat( frametime ); - savefile->WriteFloat( playerSpeed ); - savefile->WriteVec3( viewForward ); - savefile->WriteVec3( viewRight ); - - savefile->WriteBool( walking ); - savefile->WriteBool( groundPlane ); - savefile->WriteTrace( groundTrace ); - savefile->WriteMaterial( groundMaterial ); - - savefile->WriteVec3( m_RefEntVelocity ); - - savefile->WriteBool( m_bRopeContact ); - savefile->WriteBool( m_bJustHitRope ); - savefile->WriteBool( m_bOnRope ); - savefile->WriteInt( m_RopeKickTime ); - m_RopeEntity.Save( savefile ); - m_RopeEntTouched.Save( savefile ); - - savefile->WriteBool( m_bClimbableAhead ); - savefile->WriteBool( m_bOnClimb ); - savefile->WriteBool( m_bClimbDetachThisFrame ); - savefile->WriteBool( m_bClimbInitialPhase ); - savefile->WriteVec3( m_vClimbNormal ); - savefile->WriteVec3( m_vClimbPoint ); - savefile->WriteString( m_ClimbSurfName.c_str() ); - savefile->WriteFloat( m_ClimbMaxVelHoriz ); - savefile->WriteFloat( m_ClimbMaxVelVert ); - savefile->WriteInt( m_ClimbSndRepDistVert ); - savefile->WriteInt( m_ClimbSndRepDistHoriz ); - m_ClimbingOnEnt.Save( savefile ); - - savefile->WriteInt( m_NextAttachTime ); - - savefile->WriteInt( (int)waterLevel ); - savefile->WriteInt( waterType ); - - // Mantle mod - savefile->WriteInt(m_mantlePhase); - savefile->WriteBool(m_mantleStartPossible); - savefile->WriteVec3(m_mantlePullStartPos); - savefile->WriteVec3(m_mantlePullEndPos); - savefile->WriteVec3(m_mantlePushEndPos); - savefile->WriteObject(m_p_mantledEntity); - savefile->WriteInt(m_mantledEntityID); - savefile->WriteFloat(m_mantleTime); - savefile->WriteFloat(m_jumpHeldDownTime); - - // Lean mod - savefile->WriteFloat (m_leanYawAngleDegrees); - savefile->WriteFloat (m_CurrentLeanTiltDegrees); - savefile->WriteFloat (m_CurrentLeanStretch); - savefile->WriteFloat (m_leanMoveStartTilt); - savefile->WriteFloat (m_leanMoveEndTilt); - savefile->WriteFloat (m_leanMoveMaxAngle); - savefile->WriteFloat (m_leanMoveMaxStretch); - savefile->WriteBool (m_b_leanFinished); - savefile->WriteFloat (m_leanTime); - savefile->WriteAngles (m_lastPlayerViewAngles); - savefile->WriteAngles (m_viewLeanAngles); - savefile->WriteVec3 (m_viewLeanTranslation); - savefile->WriteVec3 (m_LeanDoorListenPos); - m_LeanDoorEnt.Save( savefile ); - - savefile->WriteStaticObject(*m_PushForce); -} - -/* -================ -idPhysics_Player::Restore -================ -*/ -void idPhysics_Player::Restore( idRestoreGame *savefile ) { - - idPhysics_Player_RestorePState( savefile, current ); - idPhysics_Player_RestorePState( savefile, saved ); - - savefile->ReadFloat( walkSpeed ); - savefile->ReadFloat( crouchSpeed ); - savefile->ReadFloat( maxStepHeight ); - savefile->ReadFloat( maxJumpHeight ); - savefile->ReadInt( debugLevel ); - savefile->ReadInt(lastJumpTime); - - savefile->ReadUsercmd( command ); - savefile->ReadAngles( viewAngles ); - - savefile->ReadInt( framemsec ); - savefile->ReadFloat( frametime ); - savefile->ReadFloat( playerSpeed ); - savefile->ReadVec3( viewForward ); - savefile->ReadVec3( viewRight ); - - savefile->ReadBool( walking ); - savefile->ReadBool( groundPlane ); - savefile->ReadTrace( groundTrace ); - savefile->ReadMaterial( groundMaterial ); - - savefile->ReadVec3( m_RefEntVelocity ); - - savefile->ReadBool( m_bRopeContact ); - savefile->ReadBool( m_bJustHitRope ); - savefile->ReadBool( m_bOnRope ); - savefile->ReadInt( m_RopeKickTime ); - m_RopeEntity.Restore( savefile ); - m_RopeEntTouched.Restore( savefile ); - // Angle storage vars need to be reset on a restore, since D3 resets the command angle to 0 - m_lastCommandViewYaw = 0.0f; - m_lastCommandViewPitch = 0.0f; - m_DeltaViewYaw = 0.0f; - m_DeltaViewPitch = 0.0f; - - savefile->ReadBool( m_bClimbableAhead ); - savefile->ReadBool( m_bOnClimb ); - savefile->ReadBool( m_bClimbDetachThisFrame ); - savefile->ReadBool( m_bClimbInitialPhase ); - savefile->ReadVec3( m_vClimbNormal ); - savefile->ReadVec3( m_vClimbPoint ); - savefile->ReadString( m_ClimbSurfName ); - savefile->ReadFloat( m_ClimbMaxVelHoriz ); - savefile->ReadFloat( m_ClimbMaxVelVert ); - savefile->ReadInt( m_ClimbSndRepDistVert ); - savefile->ReadInt( m_ClimbSndRepDistHoriz ); - m_ClimbingOnEnt.Restore( savefile ); - - savefile->ReadInt( m_NextAttachTime ); - - savefile->ReadInt( (int &)waterLevel ); - savefile->ReadInt( waterType ); - - // Mantle mod - int temp; - savefile->ReadInt(temp); - assert(temp >= 0 && temp < NumMantlePhases); // sanity check - m_mantlePhase = static_cast(temp); - - savefile->ReadBool(m_mantleStartPossible); - savefile->ReadVec3(m_mantlePullStartPos); - savefile->ReadVec3(m_mantlePullEndPos); - savefile->ReadVec3(m_mantlePushEndPos); - savefile->ReadObject(reinterpret_cast(m_p_mantledEntity)); - savefile->ReadInt(m_mantledEntityID); - savefile->ReadFloat(m_mantleTime); - savefile->ReadFloat(m_jumpHeldDownTime); - - // Lean mod - savefile->ReadFloat (m_leanYawAngleDegrees); - savefile->ReadFloat (m_CurrentLeanTiltDegrees); - savefile->ReadFloat (m_CurrentLeanStretch); - savefile->ReadFloat (m_leanMoveStartTilt); - savefile->ReadFloat (m_leanMoveEndTilt); - savefile->ReadFloat (m_leanMoveMaxAngle); - savefile->ReadFloat (m_leanMoveMaxStretch); - savefile->ReadBool (m_b_leanFinished); - savefile->ReadFloat (m_leanTime); - savefile->ReadAngles (m_lastPlayerViewAngles); - savefile->ReadAngles (m_viewLeanAngles); - savefile->ReadVec3 (m_viewLeanTranslation); - savefile->ReadVec3 (m_LeanDoorListenPos); - m_LeanDoorEnt.Restore( savefile ); - - savefile->ReadStaticObject( *m_PushForce ); - - // ishtvan: To avoid accidental latching, clear held crouch key var - m_bClimbDetachCrouchHeld = false; - - DM_LOG (LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Restore finished\n"); -} - -/* -================ -idPhysics_Player::SetPlayerInput -================ -*/ -void idPhysics_Player::SetPlayerInput( const usercmd_t &cmd, const idAngles &newViewAngles ) -{ - command = cmd; - - m_DeltaViewYaw = command.angles[1] - m_lastCommandViewYaw; - m_DeltaViewPitch = command.angles[0] - m_lastCommandViewPitch; - m_DeltaViewYaw = SHORT2ANGLE(m_DeltaViewYaw); - m_DeltaViewPitch = SHORT2ANGLE(m_DeltaViewPitch); - - // Test for pitch clamping - float TestPitch = viewAngles.pitch + m_DeltaViewPitch; - TestPitch = idMath::AngleNormalize180( TestPitch ); - - if( TestPitch > pm_maxviewpitch.GetFloat() ) - m_DeltaViewPitch = pm_maxviewpitch.GetFloat() - viewAngles.pitch; - else if( TestPitch < pm_minviewpitch.GetFloat() ) - m_DeltaViewPitch = pm_minviewpitch.GetFloat() - viewAngles.pitch; - - // zero the delta angles if the player's view is locked in place - if( static_cast(self)->GetImmobilization() & EIM_VIEW_ANGLE ) - { - m_DeltaViewYaw = 0.0f; - m_DeltaViewPitch = 0.0f; - } - - viewAngles = newViewAngles; // can't use cmd.angles cause of the delta_angles - - m_lastCommandViewYaw = command.angles[1]; - m_lastCommandViewPitch = command.angles[0]; -} - -/* -================ -idPhysics_Player::SetSpeed -================ -*/ -void idPhysics_Player::SetSpeed( const float newWalkSpeed, const float newCrouchSpeed ) -{ - walkSpeed = newWalkSpeed; - crouchSpeed = newCrouchSpeed; -} - -/* -================ -idPhysics_Player::SetMaxStepHeight -================ -*/ -void idPhysics_Player::SetMaxStepHeight( const float newMaxStepHeight ) { - maxStepHeight = newMaxStepHeight; -} - -/* -================ -idPhysics_Player::GetMaxStepHeight -================ -*/ -float idPhysics_Player::GetMaxStepHeight( void ) const { - return maxStepHeight; -} - -/* -================ -idPhysics_Player::SetMaxJumpHeight -================ -*/ -void idPhysics_Player::SetMaxJumpHeight( const float newMaxJumpHeight ) { - maxJumpHeight = newMaxJumpHeight; -} - -/* -================ -idPhysics_Player::SetMovementType -================ -*/ -void idPhysics_Player::SetMovementType( const pmtype_t type ) { - current.movementType = type; -} - -/* -================ -idPhysics_Player::GetMovementType - grayman #2345 -================ -*/ -int idPhysics_Player::GetMovementType( void ) { - return current.movementType; -} - -/* -================ -idPhysics_Player::SetKnockBack -================ -*/ -void idPhysics_Player::SetKnockBack( const int knockBackTime ) { - if ( current.movementTime ) { - return; - } - current.movementFlags |= PMF_TIME_KNOCKBACK; - current.movementTime = knockBackTime; -} - -/* -================ -idPhysics_Player::SetDebugLevel -================ -*/ -void idPhysics_Player::SetDebugLevel( bool set ) { - debugLevel = set; -} - -/* -================ -idPhysics_Player::Evaluate -================ -*/ -bool idPhysics_Player::Evaluate( int timeStepMSec, int endTimeMSec ) { - idVec3 masterOrigin, oldOrigin; - idMat3 masterAxis; - - // greebo: Don't clear the WATERLEVELs each frame, they are updated anyway. - //waterLevel = WATERLEVEL_NONE; - //waterType = 0; - oldOrigin = current.origin; - - clipModel->Unlink(); - - // if bound to a master - if ( masterEntity ) - { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + current.localOrigin * masterAxis; - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - current.velocity = ( current.origin - oldOrigin ) / ( timeStepMSec * 0.001f ); - masterDeltaYaw = masterYaw; - masterYaw = masterAxis[0].ToYaw(); - masterDeltaYaw = masterYaw - masterDeltaYaw; - return true; - } - - ActivateContactEntities(); - - MovePlayer( timeStepMSec ); - - // Apply the push force to all objects encountered during MovePlayer - m_PushForce->Evaluate(timeStepMSec); - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - - if ( IsOutsideWorld() ) { - gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) ); - } - - return true; //( current.origin != oldOrigin ); -} - -/* -================ -idPhysics_Player::UpdateTime -================ -*/ -void idPhysics_Player::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_Player::GetTime -================ -*/ -int idPhysics_Player::GetTime( void ) const { - return gameLocal.time; -} - -/* -================ -idPhysics_Player::GetImpactInfo -================ -*/ -void idPhysics_Player::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - info->invMass = invMass; - info->invInertiaTensor.Zero(); - info->position.Zero(); - info->velocity = current.velocity; -} - -/* -================ -idPhysics_Player::ApplyImpulse -================ -*/ -void idPhysics_Player::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - if ( current.movementType != PM_NOCLIP ) { - current.velocity += impulse * invMass; - } -} - -/* -================ -idPhysics_Player::IsAtRest -================ -*/ -bool idPhysics_Player::IsAtRest( void ) const { - return false; -} - -/* -================ -idPhysics_Player::GetRestStartTime -================ -*/ -int idPhysics_Player::GetRestStartTime( void ) const { - return -1; -} - -/* -================ -idPhysics_Player::SaveState -================ -*/ -void idPhysics_Player::SaveState( void ) { - saved = current; -} - -/* -================ -idPhysics_Player::RestoreState -================ -*/ -void idPhysics_Player::RestoreState( void ) { - current = saved; - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - - EvaluateContacts(); -} - -/* -================ -idPhysics_Player::SetOrigin -================ -*/ -void idPhysics_Player::SetOrigin( const idVec3 &newOrigin, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localOrigin = newOrigin; - if ( masterEntity ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + newOrigin * masterAxis; - } - else { - current.origin = newOrigin; - } - - clipModel->Link( gameLocal.clip, self, 0, newOrigin, clipModel->GetAxis() ); -} - -/* -================ -idPhysics_Player::GetOrigin -================ -*/ -const idVec3 & idPhysics_Player::PlayerGetOrigin( void ) const { - return current.origin; -} - -/* -================ -idPhysics_Player::SetAxis -================ -*/ -void idPhysics_Player::SetAxis( const idMat3 &newAxis, int id ) { - clipModel->Link( gameLocal.clip, self, 0, clipModel->GetOrigin(), newAxis ); -} - -/* -================ -idPhysics_Player::Translate -================ -*/ -void idPhysics_Player::Translate( const idVec3 &translation, int id ) { - - current.localOrigin += translation; - current.origin += translation; - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); -} - -/* -================ -idPhysics_Player::Rotate -================ -*/ -void idPhysics_Player::Rotate( const idRotation &rotation, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.origin *= rotation; - if ( masterEntity ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - } - else { - current.localOrigin = current.origin; - } - - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() * rotation.ToMat3() ); -} - -/* -================ -idPhysics_Player::SetLinearVelocity -================ -*/ -void idPhysics_Player::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { - current.velocity = newLinearVelocity; -} - -/* -================ -idPhysics_Player::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_Player::GetLinearVelocity( int id ) const { - return current.velocity; -} - -bool idPhysics_Player::HasRunningVelocity() -{ - // Return true when about 7% above walkspeed - return (current.velocity.LengthSqr() > Square(pm_walkspeed.GetFloat()) * 1.15); -} - -/* -================ -idPhysics_Player::SetPushed -================ -*/ -void idPhysics_Player::SetPushed( int deltaTime ) { - idVec3 velocity; - float d; - - // velocity with which the player is pushed - velocity = ( current.origin - saved.origin ) / ( deltaTime * idMath::M_MS2SEC ); - - // remove any downward push velocity - d = velocity * gravityNormal; - if ( d > 0.0f ) { - velocity -= d * gravityNormal; - } - - current.pushVelocity += velocity; -} - -/* -================ -idPhysics_Player::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_Player::GetPushedLinearVelocity( const int id ) const { - return current.pushVelocity; -} - -/* -================ -idPhysics_Player::ClearPushedVelocity -================ -*/ -void idPhysics_Player::ClearPushedVelocity( void ) { - current.pushVelocity.Zero(); -} - -/* -================ -idPhysics_Player::SetMaster - - the binding is never orientated -================ -*/ -void idPhysics_Player::SetMaster( idEntity *master, const bool orientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !masterEntity ) { - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - masterEntity = master; - masterYaw = masterAxis[0].ToYaw(); - } - ClearContacts(); - } - else { - if ( masterEntity ) { - masterEntity = NULL; - } - } -} - -const float PLAYER_VELOCITY_MAX = 4000; -const int PLAYER_VELOCITY_TOTAL_BITS = 16; -const int PLAYER_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( PLAYER_VELOCITY_MAX ) ) + 1; -const int PLAYER_VELOCITY_MANTISSA_BITS = PLAYER_VELOCITY_TOTAL_BITS - 1 - PLAYER_VELOCITY_EXPONENT_BITS; -const int PLAYER_MOVEMENT_TYPE_BITS = 3; -const int PLAYER_MOVEMENT_FLAGS_BITS = 8; - -/* -================ -idPhysics_Player::WriteToSnapshot -================ -*/ -void idPhysics_Player::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteFloat( current.origin[0] ); - msg.WriteFloat( current.origin[1] ); - msg.WriteFloat( current.origin[2] ); - msg.WriteFloat( current.velocity[0], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteFloat( current.velocity[1], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteFloat( current.velocity[2], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); - msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); - msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.stepUp ); - msg.WriteBits( current.movementType, PLAYER_MOVEMENT_TYPE_BITS ); - msg.WriteBits( current.movementFlags, PLAYER_MOVEMENT_FLAGS_BITS ); - msg.WriteDeltaLong( 0, current.movementTime ); -} - -/* -================ -idPhysics_Player::ReadFromSnapshot -================ -*/ -void idPhysics_Player::ReadFromSnapshot( const idBitMsgDelta &msg ) { - current.origin[0] = msg.ReadFloat(); - current.origin[1] = msg.ReadFloat(); - current.origin[2] = msg.ReadFloat(); - current.velocity[0] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.velocity[1] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.velocity[2] = msg.ReadFloat( PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); - current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); - current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); - current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, PLAYER_VELOCITY_EXPONENT_BITS, PLAYER_VELOCITY_MANTISSA_BITS ); - current.stepUp = msg.ReadDeltaFloat( 0.0f ); - current.movementType = msg.ReadBits( PLAYER_MOVEMENT_TYPE_BITS ); - current.movementFlags = msg.ReadBits( PLAYER_MOVEMENT_FLAGS_BITS ); - current.movementTime = msg.ReadDeltaLong( 0 ); - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, clipModel->GetAxis() ); - } -} - -//################################################################ -// Start Mantling Mod -//################################################################ - -float idPhysics_Player::GetMantleTimeForPhase(EMantlePhase mantlePhase) -{ - // Current implementation uses constants - switch (mantlePhase) - { - case hang_DarkModMantlePhase: - return cv_pm_mantle_hang_msecs.GetFloat(); - - case pull_DarkModMantlePhase: - return cv_pm_mantle_pull_msecs.GetFloat(); - - case shiftHands_DarkModMantlePhase: - return cv_pm_mantle_shift_hands_msecs.GetFloat(); - - case push_DarkModMantlePhase: - return cv_pm_mantle_push_msecs.GetFloat(); - - default: - return 0.0f; - } -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::MantleMove() -{ - idVec3 newPosition = current.origin; - idVec3 totalMove(0,0,0); - float timeForMantlePhase = GetMantleTimeForPhase(m_mantlePhase); - - // Compute proportion into the current movement phase which we are - float timeRatio = 0.0f; - - if (timeForMantlePhase != 0) - { - timeRatio = (timeForMantlePhase - m_mantleTime) / timeForMantlePhase; - } - - // Branch based on phase - if (m_mantlePhase == hang_DarkModMantlePhase) - { - // Starting at current position, hanging, rocking a bit. - float rockDistance = 2.0f; - - newPosition = m_mantlePullStartPos; - float timeRadians = idMath::PI * timeRatio; - viewAngles.roll = idMath::Sin(timeRadians) * rockDistance; - newPosition += (idMath::Sin(timeRadians) * rockDistance) * viewRight; - - if (self != NULL) - { - static_cast(self)->SetViewAngles(viewAngles); - } - } - else if (m_mantlePhase == pull_DarkModMantlePhase) - { - // Player pulls themself up to shoulder even with the surface - totalMove = m_mantlePullEndPos - m_mantlePullStartPos; - newPosition = m_mantlePullStartPos + (totalMove * idMath::Sin(timeRatio * (idMath::PI/2)) ); - } - else if (m_mantlePhase == shiftHands_DarkModMantlePhase) - { - // Rock back and forth a bit? - float rockDistance = 1.0f; - - newPosition = m_mantlePullEndPos; - float timeRadians = idMath::PI * timeRatio; - newPosition += (idMath::Sin(timeRadians) * rockDistance) * viewRight; - viewAngles.roll = idMath::Sin(timeRadians) * rockDistance; - - if (self != NULL) - { - static_cast(self)->SetViewAngles(viewAngles); - } - } - else if (m_mantlePhase == push_DarkModMantlePhase) - { - // Rocking back and forth to get legs up over edge - float rockDistance = 10.0f; - - // Player pushes themselves upward to get their legs onto the surface - totalMove = m_mantlePushEndPos - m_mantlePullEndPos; - newPosition = m_mantlePullEndPos + (totalMove * idMath::Sin(timeRatio * (idMath::PI/2)) ); - - // We go into duck during this phase and stay there until end - current.movementFlags |= PMF_DUCKED; - - float timeRadians = idMath::PI * timeRatio; - newPosition += (idMath::Sin (timeRadians) * rockDistance) * viewRight; - viewAngles.roll = idMath::Sin (timeRadians) * rockDistance; - - if (self != NULL) - { - static_cast(self)->SetViewAngles(viewAngles); - } - } - - // If there is a mantled entity, positions are relative to it. - // Transform position to be relative to world origin. - // (For now, translation only, TODO: Add rotation) - if (m_p_mantledEntity != NULL) - { - idPhysics* p_physics = m_p_mantledEntity->GetPhysics(); - if (p_physics != NULL) - { - // Ishtvan: Track rotation as well - // newPosition += p_physics->GetOrigin(); - newPosition = p_physics->GetOrigin() + p_physics->GetAxis() * newPosition; - } - } - - SetOrigin(newPosition); -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::UpdateMantleTimers() -{ - // Frame seconds left - float framemSecLeft = framemsec; - - // Update jump held down timer: This actually grows, not drops - if (!( current.movementFlags & PMF_JUMP_HELD ) ) - { - m_jumpHeldDownTime = 0; - } - else - { - m_jumpHeldDownTime += framemsec; - } - - // Skip all this if done mantling - if (m_mantlePhase != notMantling_DarkModMantlePhase && m_mantlePhase != fixClipping_DarkModMantlePhase) - { - // Handle expiring mantle phases - while (framemSecLeft >= m_mantleTime && m_mantlePhase != notMantling_DarkModMantlePhase) - { - framemSecLeft -= m_mantleTime; - m_mantleTime = 0; - - // Advance mantle phase - switch (m_mantlePhase) - { - case hang_DarkModMantlePhase: - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Pulling up...\r"); - m_mantlePhase = pull_DarkModMantlePhase; - break; - - case pull_DarkModMantlePhase: - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Shifting hand position...\r"); - m_mantlePhase = shiftHands_DarkModMantlePhase; - break; - - case shiftHands_DarkModMantlePhase: - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: Pushing self up...\r"); - m_mantlePhase = push_DarkModMantlePhase; - - // Go into crouch - current.movementFlags |= PMF_DUCKED; - break; - - case push_DarkModMantlePhase: - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("MantleMod: mantle completed\r"); - // check for clipping problems after mantling - // will advance to notMantling when the player isn't clipping - m_mantlePhase = fixClipping_DarkModMantlePhase; - - // greebo: Reset the viewangle roll to 0 after mantling, sometimes this stays at 0.6 or something - viewAngles.roll = 0; - - if (self != NULL) - { - static_cast(self)->SetViewAngles(viewAngles); - } - - break; - - default: - m_mantlePhase = notMantling_DarkModMantlePhase; - break; - } - - // Get time it takes to perform a mantling phase - m_mantleTime = GetMantleTimeForPhase(m_mantlePhase); - - // Handle end of mantle - if (m_mantlePhase == fixClipping_DarkModMantlePhase) - { - // Handle end of mantle - // Ishtvan 11/20/05 - Raise weapons after mantle is done - static_cast(self)->SetImmobilization("MantleMove", 0); - } - } - - // Reduce mantle timer - if (m_mantlePhase == fixClipping_DarkModMantlePhase) - { - m_mantleTime = 0; - } - else - { - m_mantleTime -= framemSecLeft; - } - } // This code block is executed only if phase != notMantling && phase != fixClipping -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::IsMantling() const -{ - return m_mantlePhase != notMantling_DarkModMantlePhase && m_mantlePhase != fixClipping_DarkModMantlePhase; -} - -//---------------------------------------------------------------------- - -EMantlePhase idPhysics_Player::GetMantlePhase() const -{ - return m_mantlePhase; -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::CancelMantle() -{ - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Mantle cancelled\r"); - - m_mantlePhase = notMantling_DarkModMantlePhase; - m_mantleTime = 0.0f; -} - -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- - -void idPhysics_Player::StartMantle -( - EMantlePhase initialMantlePhase, - idVec3 eyePos, - idVec3 startPos, - idVec3 endPos -) -{ - // Ishtvan 10/16/05 - // If mantling starts while on a rope, detach from that rope - if ( m_bOnRope ) - { - RopeDetach(); - } - - // If mantling starts while climbing, detach from climbing surface - if ( m_bOnClimb ) - { - ClimbDetach(); - } - - // Ishtvan 11/20/05 - Lower weapons when mantling - static_cast(self)->SetImmobilization( "MantleMove", EIM_WEAPON_SELECT | EIM_ATTACK ); - - // greebo: Disable the next mantle start here, this is set to TRUE again - // when the jump key is released outside a mantle phase - m_mantleStartPossible = false; - - // If mantling from a jump, cancel any velocity so that it does - // not continue after the mantle is completed. - current.velocity.Zero(); - - // Calculate mantle distance - idVec3 mantleDistanceVec = endPos - startPos; -// float mantleDistance = mantleDistanceVec.Length(); - - // Log starting phase - if (initialMantlePhase == hang_DarkModMantlePhase) - { - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with hang\r"); - - // Impart a force on mantled object? - if (m_p_mantledEntity != NULL && self != NULL) - { - impactInfo_t info; - m_p_mantledEntity->GetImpactInfo(self, m_mantledEntityID, endPos, &info); - - if (info.invMass != 0.0f) - { - m_p_mantledEntity->ActivatePhysics(self); - m_p_mantledEntity->ApplyImpulse( self, m_mantledEntityID, endPos, current.velocity / ( info.invMass * 2.0f ) ); - } - } - } - else if (initialMantlePhase == pull_DarkModMantlePhase) - { - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with pull upward\r"); - } - else if (initialMantlePhase == shiftHands_DarkModMantlePhase) - { - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with shift hands\r"); - } - else if (initialMantlePhase == push_DarkModMantlePhase) - { - // Go into crouch - current.movementFlags |= PMF_DUCKED; - - // Start with push upward - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle starting with push upward\r"); - } - - m_mantlePhase = initialMantlePhase; - m_mantleTime = GetMantleTimeForPhase(m_mantlePhase); - - // Make positions relative to entity - if (m_p_mantledEntity != NULL) - { - idPhysics* p_physics = m_p_mantledEntity->GetPhysics(); - if (p_physics != NULL) - { - const idVec3& mantledEntityOrigin = p_physics->GetOrigin(); - const idMat3& mantledEntityAxis = p_physics->GetAxis(); - - // ishtvan 1/3/2010: Incorporate entity rotation as well as translation - /* - startPos -= mantledEntityOrigin; - eyePos -= mantledEntityOrigin; - endPos -= mantledEntityOrigin; - */ - startPos = (startPos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); - eyePos = (eyePos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); - endPos = (endPos - mantledEntityOrigin) * mantledEntityAxis.Transpose(); - } - } - - // Set end position - m_mantlePushEndPos = endPos; - - if (initialMantlePhase == pull_DarkModMantlePhase || initialMantlePhase == hang_DarkModMantlePhase) - { - // Pull from start position up to about 2/3 of eye height - m_mantlePullStartPos = startPos; - m_mantlePullEndPos = eyePos; - - m_mantlePullEndPos += GetGravityNormal() * pm_normalheight.GetFloat() / 3.0f; - } - else - { - // Starting with push from current position - m_mantlePullEndPos = startPos; - } -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::CheckJumpHeldDown() -{ - return m_jumpHeldDownTime > cv_pm_mantle_jump_hold_trigger.GetInteger(); -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::GetCurrentMantlingReachDistances -( - float& out_maxVerticalReachDistance, - float& out_maxHorizontalReachDistance, - float& out_maxMantleTraceDistance -) -{ - // Determine arm reach in each direction - float armReach = pm_normalheight.GetFloat() * cv_pm_mantle_reach.GetFloat(); - float armVerticalReach = pm_normalheight.GetFloat() * cv_pm_mantle_height.GetFloat(); - - // Trace out as far as horizontal arm length from player - out_maxMantleTraceDistance = armReach; - - // Determine maximum vertical and horizontal distance components for - // a mantleable surface - if (current.movementFlags & PMF_DUCKED /*&& !OnRope() && !OnLadder()*/) - { - out_maxVerticalReachDistance = pm_crouchheight.GetFloat() + armVerticalReach; - out_maxHorizontalReachDistance = armReach; - } - /*else if (OnRope() || OnLadder()) - { - // angua: need larger reach when on rope - out_maxVerticalReachDistance = pm_normalheight.GetFloat() + armVerticalReach; - out_maxHorizontalReachDistance = 2* armReach; - out_maxMantleTraceDistance *= 2; - }*/ - else - { - // This vertical distance is up from the players feet - out_maxVerticalReachDistance = pm_normalheight.GetFloat() + armVerticalReach; - out_maxHorizontalReachDistance = armReach; - } -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::MantleTargetTrace -( - float maxMantleTraceDistance, - const idVec3& eyePos, - const idVec3& forwardVec, - trace_t& out_trace -) -{ - // Calculate end point of gaze trace - idVec3 end = eyePos + (maxMantleTraceDistance * forwardVec); - - // Run gaze trace - gameLocal.clip.TracePoint( out_trace, eyePos, end, MASK_SOLID, self ); - - // If that trace didn't hit anything, try a taller trace forward along the midline - // of the player's body for the full player's height out the trace distance. - if ( out_trace.fraction >= 1.0f ) - { - idVec3 upVector = -GetGravityNormal(); - - // Project forward vector onto the a plane perpendicular to gravity - idVec3 forwardPerpGrav = forwardVec; - forwardPerpGrav.ProjectOntoPlane(upVector); - - // Create bounds for translation trace model - idBounds bounds = clipModel->GetBounds(); - idBounds savedBounds = bounds; - - bounds[0][1] = (savedBounds[0][1] + savedBounds[1][1]) / 2; - bounds[0][1] -= 0.01f; - bounds[1][1] = bounds[0][1] + 0.02f; - bounds[0][0] = bounds[0][1]; - bounds[1][0] = bounds[1][1]; - - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle gaze trace didn't hit anything, so doing forward movement trace for mantle target\r"); - - gameLocal.clip.Translation - ( - out_trace, - current.origin, - current.origin + (maxMantleTraceDistance * forwardPerpGrav), - clipModel, - clipModel->GetAxis(), - MASK_SOLID, - self - ); - - //gameRenderWorld->DebugBounds(colorCyan, bounds, current.origin, 2000); - //gameRenderWorld->DebugBounds(colorBlue, bounds, current.origin + (maxMantleTraceDistance * forwardPerpGrav), 2000); - - // Restore player clip model to normal - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(savedBounds, 8) : idTraceModel(savedBounds) ); - } - - // Get the entity to be mantled - if (out_trace.c.entityNum != ENTITYNUM_NONE) - { - // Track entity which is was the chosen target - m_p_mantledEntity = gameLocal.entities[out_trace.c.entityNum]; - - if (m_p_mantledEntity->IsMantleable()) - { - m_mantledEntityID = out_trace.c.id; - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantle target entity is called '%s'\r", m_p_mantledEntity->name.c_str()); - } - else - { - // Oops, this entity isn't mantleable - m_p_mantledEntity = NULL; - out_trace.fraction = 1.0f; // Pretend we didn't hit anything - } - } -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::DetermineIfMantleTargetHasMantleableSurface -( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - trace_t& in_targetTraceResult, - idVec3& out_mantleEndPoint -) -{ - // Never mantle onto non-mantleable entities (early exit) - if (in_targetTraceResult.fraction < 1.0f) - { - idEntity* ent = gameLocal.entities[in_targetTraceResult.c.entityNum]; - - if (ent == NULL || !ent->IsMantleable()) - { - // The mantle target is an unmantleable entity - return false; - } - } - - // Try moving player's bounding box up from the trace hit point - // in steps up to the maximum distance and see if at any point - // there are no collisions. If so, we can mantle. - - // First point to test has gravity orthogonal coordinates set - // to the ray trace collision point. It then has gravity non-orthogonal - // coordinates set from the current player origin. However, - // for the non-orthogonal-to-gravity coordinates, the trace.c.point - // location is a better starting place. Because of rear surface occlusion, - // it will always be closer to the actual "upper" surface than the player - // origin unless the object is "below" the player relative to gravity. - // And, in that "below" case, mantling isn't possible anyway. - - // This sets coordinates to their components which are orthogonal - // to gravity. - idVec3 componentOrthogonalToGravity = in_targetTraceResult.c.point; - componentOrthogonalToGravity.ProjectOntoPlane(-gravityNormal); - - // This sets coordintes to their components parallel to gravity - idVec3 componentParallelToGravity; - componentParallelToGravity.x = -gravityNormal.x * in_targetTraceResult.c.point.x; - componentParallelToGravity.y = -gravityNormal.y * in_targetTraceResult.c.point.y; - componentParallelToGravity.z = -gravityNormal.z * in_targetTraceResult.c.point.z; - - // What parallel to gravity reach distance is already used up at this point - idVec3 originParallelToGravity; - originParallelToGravity.x = -gravityNormal.x * current.origin.x; - originParallelToGravity.y = -gravityNormal.y * current.origin.y; - originParallelToGravity.z = -gravityNormal.z * current.origin.z; - - float verticalReachDistanceUsed = (componentParallelToGravity - originParallelToGravity).Length(); - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Initial vertical reach distance used = %f out of maximum of %f\r", - verticalReachDistanceUsed, - maxVerticalReachDistance - ); - - // The first test point - idVec3 testPosition = componentOrthogonalToGravity + componentParallelToGravity; - - // Load crouch model - // as mantling ends in a crouch - if (!(current.movementFlags & PMF_DUCKED)) - { - idBounds bounds = clipModel->GetBounds(); - bounds[1][2] = pm_crouchheight.GetFloat(); - - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); - } - - // We try moving it up by the step distance up to the maximum height until - // there are no collisions - bool b_keepTesting = verticalReachDistanceUsed < maxVerticalReachDistance; - bool b_mantlePossible = false; - bool b_lastCollisionWasMantleable = true; - - trace_t worldMantleTrace; - - while (b_keepTesting) - { - // Try collision in_targetTraceResult - idVec3 mantleTraceStart = testPosition; - gameLocal.clip.Translation( worldMantleTrace, mantleTraceStart, testPosition, clipModel, clipModel->GetAxis(), clipMask, self ); - - if (worldMantleTrace.fraction >= 1.0f) - { - // We can mantle to there, unless the last test collided with something non-mantleable. - // Either way we're done here. - b_keepTesting = false; - - if (b_lastCollisionWasMantleable) - { - b_mantlePossible = true; - } - } - else - { - idEntity* ent = gameLocal.entities[ worldMantleTrace.c.entityNum ]; - - if (ent && !ent->IsMantleable()) - { - // If we collided with a non-mantleable entity, then flag that. - // This is to prevent situations where we start out mantling on a low ledge - // (like a stair) on which a non-mantleable entity (like an AI) is standing, - // and proceed to mantle over the AI. - b_lastCollisionWasMantleable = false; - } - else - { - // On the other hand, if there's a shelf above the AI, then we can still mantle - // the shelf. - b_lastCollisionWasMantleable = true; - } - - if (verticalReachDistanceUsed < maxVerticalReachDistance) - { - // Try next test position - - float testIncrementAmount = maxVerticalReachDistance - verticalReachDistanceUsed; - - // Establish upper bound for increment test size - if (testIncrementAmount > MANTLE_TEST_INCREMENT) - { - testIncrementAmount = MANTLE_TEST_INCREMENT; - } - - // Establish absolute minimum increment size so that - // we don't approach increment size below floating point precision, - // which would cause an infinite loop. - if (testIncrementAmount < 1.0f) - { - testIncrementAmount = 1.0f; - } - - // Update location by increment size - componentParallelToGravity += (-gravityNormal * testIncrementAmount); - verticalReachDistanceUsed = (componentParallelToGravity - originParallelToGravity).Length(); - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Ledge Search: Vertical reach distance used = %f out of maximum of %f\r", - verticalReachDistanceUsed, - maxVerticalReachDistance - ); - - // Modify test position - testPosition = componentOrthogonalToGravity + componentParallelToGravity; - } - else - { - // No surface we could fit on against gravity from raytrace hit point - // up as far as we can reach - b_keepTesting = false; - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("No mantleable surface within reach distance\r"); - } - } - - } - - // Don't mantle onto surfaces that are too steep. - // Any surface with an angle whose cosine is - // smaller than MIN_FLATNESS is too steep. - float minFlatness = cv_pm_mantle_minflatness.GetFloat(); - - if (b_mantlePossible) - { - // Attempt to get the normal of the surface we'd be standing on - // In rare cases this may not collide - trace_t floorTrace; - gameLocal.clip.Translation( floorTrace, testPosition, - testPosition + (gravityNormal * MANTLE_TEST_INCREMENT), - clipModel, clipModel->GetAxis(), clipMask, self ); - - if (floorTrace.fraction < 1.0f) - { - // Uses the dot product to compare against the cosine of an angle. - // Comparing to cos(90)=0 means we can mantle on top of any surface - // Comparing to cos(0)=1 means we can only mantle on top of perfectly flat surfaces - - float flatness = floorTrace.c.normal * (-gravityNormal); - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING( - "Floor %.2f,%.2f,%.2f; grav %.2f,%.2f,%.2f; dot %f; %s\r", - floorTrace.c.normal.x, floorTrace.c.normal.y, floorTrace.c.normal.z, - gravityNormal.x, gravityNormal.y, gravityNormal.z, - flatness, flatness < minFlatness ? "too steep" : "OK"); - - if (flatness < minFlatness) - { - b_mantlePossible = false; - } - } - } - - // Must restore standing model if player is not crouched - if (!(current.movementFlags & PMF_DUCKED)) - { - // Load back standing model - idBounds bounds = clipModel->GetBounds(); - bounds[1][2] = pm_normalheight.GetFloat(); - - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); - } - - // Return result - if (b_mantlePossible) - { - out_mantleEndPoint = testPosition; - } - return b_mantlePossible; -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::DetermineIfPathToMantleSurfaceIsPossible -( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - const idVec3& in_eyePos, - const idVec3& in_mantleStartPoint, - const idVec3& in_mantleEndPoint -) -{ - // Make sure path from current location - // upward can be traversed. - trace_t roomForMoveUpTrace; - idVec3 MoveUpStart = in_mantleStartPoint; - idVec3 MoveUpEnd; - - // Go to coordinate components against gravity from current location - idVec3 componentOrthogonalToGravity; - componentOrthogonalToGravity = in_mantleStartPoint; - componentOrthogonalToGravity.ProjectOntoPlane (-gravityNormal); - MoveUpEnd = componentOrthogonalToGravity; - - MoveUpEnd.x += -gravityNormal.x * in_mantleEndPoint.x; - MoveUpEnd.y += -gravityNormal.y * in_mantleEndPoint.y; - MoveUpEnd.z += -gravityNormal.z * in_mantleEndPoint.z; - - // Use crouch clip model - if (!(current.movementFlags & PMF_DUCKED)) - { - // Load crouching model - idBounds bounds = clipModel->GetBounds(); - bounds[1][2] = pm_crouchheight.GetFloat(); - - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); - } - - gameLocal.clip.Translation - ( - roomForMoveUpTrace, - MoveUpStart, - MoveUpEnd, - clipModel, - clipModel->GetAxis(), - clipMask, - self - ); - - // Done with crouch model if not currently crouched - if (!(current.movementFlags & PMF_DUCKED)) - { - // Load back standing model - idBounds bounds = clipModel->GetBounds(); - bounds[1][2] = pm_normalheight.GetFloat(); - - clipModel->LoadModel( pm_usecylinder.GetBool() ? idTraceModel(bounds, 8) : idTraceModel(bounds) ); - } - - // Log - if (roomForMoveUpTrace.fraction < 1.0) - { - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Collision test from (%f %f %f) to (%f %f %f) yieled trace fraction %f\r", - MoveUpStart.x, - MoveUpStart.y, - MoveUpStart.z, - MoveUpEnd.x, - MoveUpEnd.y, - MoveUpEnd.z, - roomForMoveUpTrace.fraction - ); - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Not enough vertical clearance along mantle path\r"); - return false; - } - else - { - return true; - } - -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::ComputeMantlePathForTarget -( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - const idVec3& eyePos, - trace_t& in_targetTraceResult, - idVec3& out_mantleEndPoint -) -{ - // Up vector - idVec3 upVector = -GetGravityNormal(); - - // Mantle start point is origin - const idVec3& mantleStartPoint = GetOrigin(); - - // Check if trace target has a mantleable surface - bool b_canBeMantled = DetermineIfMantleTargetHasMantleableSurface - ( - maxVerticalReachDistance, - maxHorizontalReachDistance, - in_targetTraceResult, - out_mantleEndPoint - ); - - if (b_canBeMantled) - { - // Check if path to mantle end point is not blocked - b_canBeMantled &= DetermineIfPathToMantleSurfaceIsPossible - ( - maxVerticalReachDistance, - maxHorizontalReachDistance, - eyePos, - mantleStartPoint, - out_mantleEndPoint - ); - - if (b_canBeMantled) - { - // Is end point too far away? - idVec3 endDistanceVector = out_mantleEndPoint - eyePos; - float endDistance = endDistanceVector.Length(); - idVec3 upDistance = endDistanceVector; - - upDistance.x *= upVector.x; - upDistance.y *= upVector.y; - upDistance.z *= upVector.z; - float upDist = upDistance.Length(); - - float nonUpDist = idMath::Sqrt(endDistance*endDistance - upDist*upDist); - - // Check the calculated distances - if (upDist < 0.0) - { - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Mantleable surface was below player's feet. No belly slide allowed.\r"); - b_canBeMantled = false; - } - else if (upDist > maxVerticalReachDistance || nonUpDist > maxHorizontalReachDistance) - { - // Its too far away either horizontally or vertically - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Distance to end point was (%f, %f) (horizontal, vertical) which is greater than limits of (%f %f), so mantle cannot be done\n", - upDist, - nonUpDist, - maxVerticalReachDistance, - maxHorizontalReachDistance - ); - - b_canBeMantled = false; - } - - // Distances are reasonable - } - } - - // Return result - return b_canBeMantled; -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::PerformMantle() -{ - // Can't start mantle if already mantling or not yet possible (jump button not yet released) - if ( !(m_mantlePhase == notMantling_DarkModMantlePhase || m_mantlePhase == fixClipping_DarkModMantlePhase) - || !m_mantleStartPossible ) - { - return; - } - - if (static_cast(self)->GetImmobilization() & EIM_MANTLE) - { - return; // greebo: Mantling disabled by immobilization system - } - - // Clear mantled entity members to indicate nothing is - // being mantled - m_p_mantledEntity = NULL; - m_mantledEntityID = 0; - - // Forward vector is direction player is looking - idVec3 forward = viewAngles.ToForward(); - forward.Normalize(); - - // We use gravity alot here... - idVec3 gravityNormal = GetGravityNormal(); - idVec3 upVector = -gravityNormal; - - // Get maximum reach distances for mantling - float maxVerticalReachDistance; - float maxHorizontalReachDistance; - float maxMantleTraceDistance; - - GetCurrentMantlingReachDistances - ( - maxVerticalReachDistance, - maxHorizontalReachDistance, - maxMantleTraceDistance - ); - - // Get start position of gaze trace, which is player's eye position - idPlayer* p_player = static_cast(self); - - if (p_player == NULL) - { - DM_LOG(LC_MOVEMENT, LT_ERROR)LOGSTRING("p_player is NULL\r"); - return; - } - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING ("Getting eye position\r"); - idVec3 eyePos = p_player->GetEyePosition(); - - // Ishtvan: Do not attempt to mantle if holding an object - if( gameLocal.m_Grabber->GetSelected() ) - return; - - // Run mantle trace - trace_t trace; - - MantleTargetTrace - ( - maxMantleTraceDistance, - eyePos, - forward, - trace - ); - - // If the trace found a target, see if it is mantleable - if ( trace.fraction < 1.0f ) - { - // Log trace hit point - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Mantle target trace collision point (%f %f %f)\r", - trace.c.point.x, - trace.c.point.y, - trace.c.point.z - ); - - // Find mantle end point and make sure mantle is - // possible - idVec3 mantleEndPoint; - if (ComputeMantlePathForTarget - ( - maxVerticalReachDistance, - maxHorizontalReachDistance, - eyePos, - trace, - mantleEndPoint - )) - { - // Log the end point - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Mantle end position = (%f %f %f)\r", - mantleEndPoint.x, - mantleEndPoint.y, - mantleEndPoint.z - ); - - // Start with log phase dependent on position relative - // to the mantle end point - if (mantleEndPoint * gravityNormal < eyePos * gravityNormal) - { - // Start with pull if on the ground, hang if not - if (groundPlane) - { - StartMantle(pull_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); - } - else - { - StartMantle(hang_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); - } - } - else - { - // We are above it, start with push - StartMantle(push_DarkModMantlePhase, eyePos, GetOrigin(), mantleEndPoint); - } - } // Mantle target passed mantleability tests - } // End mantle target found -} - -//#################################################################### -// End Mantle Mod -// SophisticatedZombie (DH) -//#################################################################### - -//#################################################################### -// Start Leaning Mod -// Zaccheus (some original geometric drawings) -// SophsiticatedZombie (DH) -// -//#################################################################### - -void idPhysics_Player::ToggleLean(float leanYawAngleDegrees) -{ - //if (m_CurrentLeanTiltDegrees < 0.0001) // prevent floating point compare errors - if (m_CurrentLeanTiltDegrees < 0.00001) // prevent floating point compare errors - { - // Start the lean - m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; - m_leanYawAngleDegrees = leanYawAngleDegrees; - - // Hack: Use different values for forward/backward lean than side/side - if( leanYawAngleDegrees == 90.0f || leanYawAngleDegrees == -90.0f ) - { - m_leanTime = cv_pm_lean_forward_time.GetFloat(); - m_leanMoveEndTilt = cv_pm_lean_forward_angle.GetFloat(); - m_leanMoveMaxStretch = cv_pm_lean_forward_stretch.GetFloat(); - m_leanMoveMaxAngle = cv_pm_lean_forward_angle.GetFloat(); - } - else - { - m_leanTime = cv_pm_lean_time.GetFloat(); - m_leanMoveEndTilt = cv_pm_lean_angle.GetFloat(); - m_leanMoveMaxStretch = cv_pm_lean_stretch.GetFloat(); - m_leanMoveMaxAngle = cv_pm_lean_angle.GetFloat(); - } - - m_b_leanFinished = false; - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("ToggleLean starting lean\r"); - } - else - { - if (m_leanTime > 0 && m_leanMoveEndTilt == 0) - { - // We are already un-leaning - return; - } - - // End the lean - m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; - m_leanTime = cv_pm_lean_forward_time.GetFloat(); - m_leanMoveEndTilt = 0.0; - m_b_leanFinished = false; - - // greebo: Leave the rest of the variables as they are - // to avoid view-jumping issues due to leaning back. - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("ToggleLean ending lean\r"); - } -} - -//---------------------------------------------------------------------- - -bool idPhysics_Player::IsLeaning() -{ - if (m_CurrentLeanTiltDegrees < 0.001) - { - return false; - } - else - { - // entering, exiting, or holding lean - return true; - } -} - -//---------------------------------------------------------------------- - -const idAngles& idPhysics_Player::GetViewLeanAngles() const -{ - return m_viewLeanAngles; -} - -//---------------------------------------------------------------------- - -idVec3 idPhysics_Player::GetViewLeanTranslation() -{ - idAngles viewAngNoPitch = viewAngles; - viewAngNoPitch.pitch = 0.0f; - return viewAngNoPitch.ToMat4() * m_viewLeanTranslation; -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::UpdateLeanAngle (float deltaLeanTiltDegrees, float deltaLeanStretch) -{ - // What would the new lean angle be? - float newLeanTiltDegrees = m_CurrentLeanTiltDegrees + deltaLeanTiltDegrees; - - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("newLeanTiltDegrees = %f\r", newLeanTiltDegrees ); - - if (newLeanTiltDegrees < 0.0) - { - // Adjust delta - deltaLeanTiltDegrees = 0.0 - m_CurrentLeanTiltDegrees; - deltaLeanStretch = 0.0 - m_CurrentLeanStretch; - m_leanTime = 0.0; - m_b_leanFinished = true; - } - else if (newLeanTiltDegrees > m_leanMoveMaxAngle) - { - // Adjust delta - deltaLeanTiltDegrees = m_leanMoveMaxAngle - m_CurrentLeanTiltDegrees; - deltaLeanStretch = m_leanMoveMaxStretch - m_CurrentLeanStretch; - m_leanTime = 0.0; - m_b_leanFinished = true; - } - - // Log max possible lean - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Currently leaning %.2f degrees, can lean up to %.2f more degrees this frame\r", - m_CurrentLeanTiltDegrees, - deltaLeanTiltDegrees - ); - - newLeanTiltDegrees = m_CurrentLeanTiltDegrees + deltaLeanTiltDegrees; - float newLeanStretch = m_CurrentLeanStretch + deltaLeanStretch; - - // Collision test: do not change lean angles any more if collision has occurred - // convert proposed angle and stretch to a viewpoint in space: - idVec3 newPoint = LeanParmsToPoint( newLeanTiltDegrees, newLeanStretch ); - - idPlayer* player = static_cast(self); - idVec3 origPoint = player->GetEyePosition(); - - // Add some delta so we can lean back afterwards without already being clipped - idVec3 vDelta = newPoint - origPoint; - vDelta.Normalize(); - - float fLeanTestDelta = 6.0f; - vDelta *= fLeanTestDelta; - - // Perform the trace (greebo: use PLAYERSOLID to include player_clip collisions) - trace_t trTest; - gameLocal.clip.TraceBounds( trTest, origPoint, newPoint + vDelta, m_LeanViewBounds, MASK_PLAYERSOLID, player ); - - bool bWouldClip = trTest.fraction < 1.0f; - //DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Collision trace between old view point ( %d, %d, %d ) and newPoint: ( %d, %d, %d )\r", origPoint.x, origPoint.y, origPoint.z, newPoint.x, newPoint.y, newPoint.z ); - - // Do not lean farther if the player would hit the wall - if( bWouldClip ) - { - idEntity* traceEnt = gameLocal.GetTraceEntity( trTest ); - - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Lean test point within solid, lean motion stopped.\r" ); - - if( traceEnt != NULL) - { - // Door leaning test - if (traceEnt->IsType(CFrobDoor::Type) && - !static_cast(traceEnt)->IsOpen() && - m_LeanDoorEnt.GetEntity() == NULL ) - { - // If it is a door, can it be listened through? - if( FindLeanDoorListenPos( trTest.c.point, static_cast(traceEnt) ) ) - { - m_LeanDoorEnt = static_cast(traceEnt); - } - } - // Detect AI collision - else if (traceEnt->IsType(idAI::Type) ) - { - static_cast(traceEnt)->HadTactile(player); - } - } - - return; - } - - // Adjust lean angle by delta which was allowed - m_CurrentLeanTiltDegrees += deltaLeanTiltDegrees; - m_CurrentLeanStretch += deltaLeanStretch; - - // Update the physics: - UpdateLeanPhysics(); - - // Log activity - DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING - ( - "Lean tilt is now %.2f degrees, lean stretch is now %.2f fractional\r", - m_CurrentLeanTiltDegrees, - m_CurrentLeanStretch - ); -} - -//---------------------------------------------------------------------- - -void idPhysics_Player::LeanMove() -{ - - // Change in lean tilt this frame - float deltaLeanTiltDegrees = 0.0; - float deltaLeanStretch = 0.0; - float newLeanTiltDegrees = 0.0; - float newLeanStretch = 0.0; - - if ( !m_b_leanFinished ) - { - - // Update lean time - m_leanTime -= framemsec; - if (m_leanTime <= 0.0) - { - m_leanTime = 0.0; - m_b_leanFinished = true; - } - - // Try sinusoidal movement - float timeRatio = ( cv_pm_lean_time.GetFloat() - m_leanTime) / cv_pm_lean_time.GetFloat(); - - float timeRadians = (idMath::PI/2.0f) * timeRatio; - - if (m_leanMoveEndTilt > m_leanMoveStartTilt) - { - newLeanTiltDegrees = (idMath::Sin(timeRadians) * (m_leanMoveEndTilt - m_leanMoveStartTilt)) - + m_leanMoveStartTilt; - newLeanStretch = idMath::Sin(timeRadians); - } - else if (m_leanMoveStartTilt > m_leanMoveEndTilt) - { - newLeanTiltDegrees = m_leanMoveStartTilt - (idMath::Sin(timeRadians) * (m_leanMoveStartTilt - m_leanMoveEndTilt)); - newLeanStretch = idMath::Sin( (idMath::PI/2.0f) * (1.0f - timeRatio) ); - } - - deltaLeanTiltDegrees = newLeanTiltDegrees - m_CurrentLeanTiltDegrees; - deltaLeanStretch = newLeanStretch - m_CurrentLeanStretch; - - } - - // Perform any change to leaning - if (deltaLeanTiltDegrees != 0.0) - { - // Re-orient clip model before change so that collision tests - // are accurate (player may have rotated mid-lean) - UpdateLeanAngle (deltaLeanTiltDegrees, deltaLeanStretch); - } - - // If player is leaned at all, do an additional clip test and unlean them - // In case they lean and walk into something, or a moveable moves into them, etc. - if( m_CurrentLeanTiltDegrees != 0.0 && TestLeanClip() ) - { - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned player clipped solid, unleaning to valid position \r"); - - UnleanToValidPosition(); - } - - // Lean door test - if( IsLeaning() ) - { - UpdateLeanDoor(); - } - - // TODO: Update lean radius if player is crouching/uncrouching -} - -bool idPhysics_Player::TestLeanClip() -{ - idPlayer *p_player = static_cast(self); - // convert proposed angle and stretch to a viewpoint in space: - - idVec3 vTest = p_player->GetEyePosition(); - idVec3 vEyeOffset = -GetGravityNormal()*p_player->EyeHeight(); - - trace_t trTest; - gameLocal.clip.TraceBounds( trTest, current.origin + vEyeOffset, vTest, m_LeanViewBounds, MASK_SOLID | CONTENTS_BODY, self ); - - idEntity *TrEnt(NULL); - - // Detect AI collision, if entity hit or its bindmaster is an AI: - if( trTest.fraction != 1.0f - && ( TrEnt = gameLocal.GetTraceEntity( trTest ) ) != NULL - && TrEnt->IsType(idAI::Type) ) - { - static_cast( TrEnt )->HadTactile( (idActor *) self ); - } - - // Uncomment for debug bounds display - //gameRenderWorld->DebugBounds( colorGreen, m_LeanViewBounds, vTest ); - - return (trTest.fraction != 1.0f); -} - -idVec3 idPhysics_Player::LeanParmsToPoint(float tilt, float stretch) -{ - idPlayer* p_player = static_cast(self); - - // Find the lean fulcrum to rotate about, and radius of lean - float eyeHeight = p_player->EyeHeight(); - float leanFulcrumHeight = eyeHeight * cv_pm_lean_height.GetFloat(); - float radius = eyeHeight - leanFulcrumHeight; - - // Set lean view angles - float pitchAngle = tilt * idMath::Sin(DEG2RAD(m_leanYawAngleDegrees)); - float rollAngle = tilt * idMath::Cos(DEG2RAD(m_leanYawAngleDegrees)); - - // Set lean translate vector - float stretchedDist = radius * (1.0f + m_leanMoveMaxStretch * stretch); - - // This will be the point in space relative to the player's eye position - idVec3 vPoint( - stretchedDist * idMath::Sin(DEG2RAD(-pitchAngle)), - stretchedDist * idMath::Sin(DEG2RAD(rollAngle)), - 0.0 - ); - - // Calculate the z-coordinate of the point, by projecting it - // onto a sphere of radius - vPoint.ProjectSelfOntoSphere( stretchedDist ); - - // Subtract the radius, we only need the difference relative to the eyepos - vPoint.z -= stretchedDist; - - // Rotate to player's facing - // this worked for yaw, but had issues with pitch, try something instead - //idMat4 rotMat = viewAngles.ToMat4(); - idAngles viewAngNoPitch = viewAngles; - viewAngNoPitch.pitch = 0.0f; - idMat4 rotMat = viewAngNoPitch.ToMat4(); - - vPoint *= rotMat; - - // Sign h4x0rx - vPoint.x *= -1; - vPoint.y *= -1; - - // Extract what the player's eye position would be without lean - // Need to do this rather than just adding origin and eye offset due to smoothing - vPoint += p_player->GetEyePosition() - rotMat * m_viewLeanTranslation; - - return vPoint; -} - -void idPhysics_Player::RopeRemovalCleanup( idEntity *RopeEnt ) -{ - if( RopeEnt && m_RopeEntity.GetEntity() && m_RopeEntity.GetEntity() == RopeEnt ) - m_RopeEntity = NULL; - if( RopeEnt && m_RopeEntTouched.GetEntity() && m_RopeEntTouched.GetEntity() == RopeEnt ) - m_RopeEntTouched = NULL; -} - -void idPhysics_Player::UpdateLeanPhysics() -{ - idPlayer *p_player = static_cast(self); - - idAngles viewAngNoPitch = viewAngles; - viewAngNoPitch.pitch = 0; - - idMat4 rotPlayerToWorld = viewAngNoPitch.ToMat4(); - idMat4 rotWorldToPlayer = rotPlayerToWorld.Transpose(); - - // unleaned player view origin - idVec3 viewOrig = p_player->GetEyePosition(); - // convert angle and stretch to a viewpoint in space: - idVec3 newPoint = LeanParmsToPoint( m_CurrentLeanTiltDegrees, m_CurrentLeanStretch ); - - // This is cumbersome, but it lets us extract the smoothed view origin from idPlayer - m_viewLeanTranslation = newPoint - (viewOrig - rotPlayerToWorld * m_viewLeanTranslation); - m_viewLeanTranslation *= rotWorldToPlayer; - - float angle = m_CurrentLeanTiltDegrees; - - m_viewLeanAngles.pitch = angle * idMath::Sin(DEG2RAD(m_leanYawAngleDegrees)); - m_viewLeanAngles.roll = angle * idMath::Cos(DEG2RAD(m_leanYawAngleDegrees)); -} - -float idPhysics_Player::GetDeltaViewYaw( void ) -{ - return m_DeltaViewYaw; -} - -float idPhysics_Player::GetDeltaViewPitch( void ) -{ - return m_DeltaViewPitch; -} - -void idPhysics_Player::UpdateLeanedInputYaw( idAngles &InputAngles ) -{ - if (!IsLeaning()) return; // nothing to do - - /** - * Leaned view yaw check for clipping - **/ - - // Have a delta so that we don't get stuck on the wall due to floating point errors - float AddedYawDelt = 4.0f; // amount to check ahead of the yaw change, in degrees - float TestDeltaYaw = idMath::AngleNormalize180( InputAngles.yaw - viewAngles.yaw ); - - // Add delta - if( TestDeltaYaw < 0.0f ) - TestDeltaYaw -= AddedYawDelt; - else - TestDeltaYaw += AddedYawDelt; - - idPlayer* player = static_cast(self); - - idVec3 vEyeOffset = -GetGravityNormal() * player->EyeHeight(); - - // make the test bounds go back to the unleaned eye point - idBounds ViewBoundsExp = m_LeanViewBounds; - ViewBoundsExp.AddPoint( -m_viewLeanTranslation ); - - idClipModel ViewClip( ViewBoundsExp ); - idAngles viewAngYaw; - viewAngYaw.Zero(); - viewAngYaw.yaw = viewAngles.yaw; - - ViewClip.SetPosition( player->GetEyePosition(), viewAngYaw.ToMat3() ); - - //idRotation ViewYawRot( current.origin, -GetGravityNormal(), TestDeltaYaw ); - idRotation ViewYawRot( current.origin, GetGravityNormal(), TestDeltaYaw ); - - idVec3 startPoint = player->GetEyePosition(); - idVec3 endPoint = startPoint; - ViewYawRot.RotatePoint( endPoint ); - - trace_t TrResults; - gameLocal.clip.Rotation( TrResults, startPoint, ViewYawRot, &ViewClip, ViewClip.GetAxis(), MASK_SOLID | CONTENTS_BODY, self ); - - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned View Yaw Test: Original viewpoint (%f, %f, %f) Tested viewpoint: (%f, %f, %f) \r", startPoint.x, startPoint.y, startPoint.z, endPoint.x, endPoint.y, endPoint.z ); - - // Cancel rotation if check-ahead rotation trace fails - if( TrResults.fraction != 1.0f ) - { - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Leaned View Yaw Test: Clipped with rotation trace fraction %f. Delta yaw not allowed \r", TrResults.fraction ); - InputAngles.yaw = viewAngles.yaw; - - idEntity* TrEnt = gameLocal.GetTraceEntity( TrResults ); - - // Detect AI collision, if entity hit or its bindmaster is an AI: - if( TrEnt != NULL && TrEnt->IsType(idAI::Type) ) - { - static_cast( TrEnt )->HadTactile( static_cast(self) ); - } - - return; - } - - // debug draw the test clip model - /* - collisionModelManager->DrawModel( ViewClip.Handle(), ViewClip.GetOrigin(), - ViewClip.GetAxis(), vec3_origin, 0.0f ); - */ -} - -void idPhysics_Player::UnleanToValidPosition( void ) -{ - trace_t trTest; - idVec3 vTest(vec3_zero); - - idPlayer *p_player = (idPlayer *) self; - idVec3 vEyeOffset = -GetGravityNormal()*p_player->EyeHeight(); - - float TestLeanDegrees = m_CurrentLeanTiltDegrees; - float TestLeanStretch = m_CurrentLeanStretch; - float DeltaDeg = TestLeanDegrees / (float) cv_pm_lean_to_valid_increments.GetInteger(); - float DeltaStretch = TestLeanStretch / (float) cv_pm_lean_to_valid_increments.GetInteger(); - - // Must temporarily set these to get proper behavior from max angle - m_leanMoveMaxAngle = m_CurrentLeanTiltDegrees; - m_leanMoveMaxStretch = m_CurrentLeanStretch; - m_leanMoveStartTilt = m_CurrentLeanTiltDegrees; - m_leanMoveEndTilt = 0.0f; - - for( int i=0; i < cv_pm_lean_to_valid_increments.GetInteger(); i++ ) - { - // Lean degrees are always positive - TestLeanDegrees -= DeltaDeg; - TestLeanStretch -= DeltaStretch; - - // convert proposed angle and stretch to a viewpoint in world space: - vTest = LeanParmsToPoint( TestLeanDegrees, TestLeanStretch ); - gameLocal.clip.TraceBounds( trTest, current.origin + vEyeOffset, vTest, m_LeanViewBounds, MASK_SOLID | CONTENTS_BODY, self ); - - // break if valid point was found - if( trTest.fraction == 1.0f ) - break; - } - - // transform lean parameters with final answer - m_CurrentLeanTiltDegrees = TestLeanDegrees; - m_CurrentLeanStretch = TestLeanStretch; - - UpdateLeanPhysics(); -} - -bool idPhysics_Player::FindLeanDoorListenPos(const idVec3& incidencePoint, CFrobDoor* door) -{ - bool bFoundEmptySpace( false ); - int contents = -1; - idVec3 vTest(incidencePoint), vDirTest(0,0,0), vLeanDir( 1.0f, 0.0f, 0.0f ); - idAngles LeanYaw; - idAngles viewYawOnly = viewAngles; - - LeanYaw.Zero(); - LeanYaw.yaw = m_leanYawAngleDegrees - 90.0f; - - viewYawOnly.pitch = 0.0f; - viewYawOnly.roll = 0.0f; - - vDirTest = viewYawOnly.ToMat3() * LeanYaw.ToMat3() * vLeanDir; - vDirTest.Normalize(); - - int MaxCount = cv_pm_lean_door_increments.GetInteger(); - - - for( int count = 1; count < MaxCount; count++ ) - { - vTest += vDirTest * ( (float) count / (float) MaxCount ) * cv_pm_lean_door_max.GetFloat(); - - contents = gameLocal.clip.Contents( vTest, NULL, mat3_identity, CONTENTS_SOLID, self ); - - // found empty space on other side of door - if( !( (contents & MASK_SOLID) > 0 ) ) - { - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("Lean Into Door: Found empty space on other side of door. Incidence point: %s Empty space point: %s \r", incidencePoint.ToString(), vTest.ToString() ); - - bFoundEmptySpace = true; - m_LeanDoorListenPos = vTest; - break; - } - } - - // uncomment to debug the lean direction line - // gameRenderWorld->DebugArrow( colorBlue, IncidencePoint, IncidencePoint + 15.0f * vDirTest, 5.0f, 10000 ); - - return bFoundEmptySpace; -} - -void idPhysics_Player::UpdateLeanDoor( void ) -{ - idPlayer* player = static_cast(self); - - CFrobDoor* door = m_LeanDoorEnt.GetEntity(); - - if( door && player ) - { - if (!m_LeanDoorEnt.IsValid() || door->IsOpen() || !IsLeaning()) - { - m_LeanDoorEnt = NULL; - return; - } - - idBounds TestBounds = m_LeanViewBounds; - TestBounds.ExpandSelf( cv_pm_lean_door_bounds_exp.GetFloat() ); - TestBounds.TranslateSelf( player->GetEyePosition() ); - -/** More precise test (Not currently used) - - int numEnts = 0; - idEntity *ents[MAX_GENTITIES]; - idEntity *ent = NULL; - bool bMatchedDoor(false); - - numEnts = gameLocal.clip.EntitiesTouchingBounds( TestBounds, CONTENTS_SOLID, ents, MAX_GENTITIES); - for( int i=0; i < numEnts; i++ ) - { - if( ents[i] == (idEntity *) door ) - { - bMatchedDoor = true; - break; - } - } - - if( !bMatchedDoor ) - { - m_LeanDoorEnt = NULL; - goto Quit; - } -**/ - - if( !TestBounds.IntersectsBounds( door->GetPhysics()->GetAbsBounds() ) ) - { - m_LeanDoorEnt = NULL; - return; - } - - // We are leaning into a door - // overwrite the current player listener loc with that calculated for the door - player->SetDoorListenLoc( m_LeanDoorListenPos ); - } -} - -bool idPhysics_Player::IsDoorLeaning( void ) -{ - return (m_LeanDoorEnt.GetEntity() != NULL) && m_LeanDoorEnt.IsValid(); -} - -idStr idPhysics_Player::GetClimbSurfaceType() const -{ - return m_bOnClimb ? m_ClimbSurfName : ""; -} - -float idPhysics_Player::GetClimbLateralCoord(const idVec3& origVec) const -{ - if (m_bOnClimb) - { - idVec3 orig = origVec - (origVec * gravityNormal) * gravityNormal; - - idVec3 climbNormXY = m_vClimbNormal - (m_vClimbNormal * gravityNormal) * gravityNormal; - idVec3 latNormal = climbNormXY.Cross(gravityNormal); - latNormal.NormalizeFast(); - - return orig * latNormal; - } - - return 0.0f; -} - -void idPhysics_Player::SetRefEntVel( idEntity *ent, int bodID) -{ - idVec3 EntCOM, ThisCOM, r, AngVel; - idMat3 DummyMat; - float dummy; - - if( !ent ) - { - m_RefEntVelocity.Zero(); - } - else - { - idPhysics *phys = ent->GetPhysics(); - - // Sometimes we have statics bound to movers, and the static doesn't return a velocity - if( phys->IsType(idPhysics_Static::Type) - || phys->IsType(idPhysics_StaticMulti::Type) ) - { - if( ent->GetBindMaster() ) - { - phys = ent->GetBindMaster()->GetPhysics(); - // TODO: Replace this with ent->bindbody - bodID = 0; - DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("SetRefVel switched from ent %s to bindmaster %s\r", ent->name.c_str(), ent->GetBindMaster()->name.c_str() ); - } - } - - m_RefEntVelocity = phys->GetLinearVelocity( bodID ); - // Apparently this is needed for moveables riding on movers: - m_RefEntVelocity += phys->GetPushedLinearVelocity( bodID ); - - // Add orbit velocity from angular vel of mover - // v_tangential = omega X r, where r is the distance between COM - AngVel = phys->GetAngularVelocity( bodID ); - AngVel += phys->GetPushedAngularVelocity( bodID ); - - // Find our center of mass: - GetClipModel()->GetMassProperties( 1.0f, dummy, ThisCOM, DummyMat ); - ThisCOM = GetOrigin() + ThisCOM * GetAxis(); - // Find entity center of mass - if( phys->GetClipModel( bodID)->IsTraceModel() ) - { - phys->GetClipModel( bodID )->GetMassProperties( 1.0f, dummy, EntCOM, DummyMat ); - EntCOM = phys->GetOrigin( bodID ) + EntCOM * phys->GetAxis( bodID ); - } - else - EntCOM = phys->GetOrigin( bodID ); - - // r = ThisCOM - EntCOM; - r = GetOrigin() - phys->GetOrigin( bodID ); - -// Linear component due to angular velocity commented out for now -// Is not correct and tends to kill the player. - -// m_RefEntVelocity += AngVel.Cross( r ); - - // Uncomment for debugging - // DM_LOG(LC_MOVEMENT,LT_DEBUG)LOGSTRING("SetRefEntVelocity: Ent angular velocity is %s, Ent COM is %s, player COM is %s, added linear velocity due to angular rotation of ent is: %s\r",AngVel.ToString(),EntCOM.ToString(),ThisCOM.ToString(),AngVel.Cross(r).ToString() ); - } -} - -idVec3 idPhysics_Player::GetRefEntVel( void ) const -{ - return m_RefEntVelocity; -} - -int idPhysics_Player::GetMovementFlags( void ) -{ - return current.movementFlags; -} - -void idPhysics_Player::SetMovementFlags( int flags ) -{ - current.movementFlags = flags; -} diff --git a/game/physics/physics_player.h b/game/physics/physics_player.h deleted file mode 100644 index 96df37c8b..000000000 --- a/game/physics/physics_player.h +++ /dev/null @@ -1,876 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_PLAYER_H__ -#define __PHYSICS_PLAYER_H__ - -#include - -/* -=================================================================================== - - Player physics - - Simulates the motion of a player through the environment. Input from the - player is used to allow a certain degree of control over the motion. - -=================================================================================== -*/ - -class idAFEntity_Base; -class CFrobDoor; - -// movementType -typedef enum { - PM_NORMAL, // normal physics - PM_DEAD, // no acceleration or turning, but free falling - PM_SPECTATOR, // flying without gravity but with collision detection - PM_FREEZE, // stuck in place without control - PM_NOCLIP // flying without collision detection nor gravity -} pmtype_t; - -#ifndef MOD_WATERPHYSICS - -// waterLevel_t has been moved to Physics_Actor.h - -typedef enum -{ - WATERLEVEL_NONE, - WATERLEVEL_FEET, - WATERLEVEL_WAIST, - WATERLEVEL_HEAD -} waterLevel_t; - -#endif // MOD_WATERPHYSICS - - -#define MAXTOUCH 32 - -typedef struct playerPState_s { - idVec3 origin; - idVec3 velocity; - idVec3 localOrigin; - idVec3 pushVelocity; - float stepUp; - int movementType; - int movementFlags; - int movementTime; -} playerPState_t; - - -// This enumreation defines the phases of the mantling movement -enum EMantlePhase -{ - notMantling_DarkModMantlePhase = 0, - hang_DarkModMantlePhase, - pull_DarkModMantlePhase, - shiftHands_DarkModMantlePhase, - push_DarkModMantlePhase, - fixClipping_DarkModMantlePhase, - NumMantlePhases, -}; - -class CForcePush; -typedef boost::shared_ptr CForcePushPtr; - -// The class itself -class idPhysics_Player : - public idPhysics_Actor -{ -public: - CLASS_PROTOTYPE( idPhysics_Player ); - - idPhysics_Player(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // initialisation - void SetSpeed( const float newWalkSpeed, const float newCrouchSpeed ); - void SetMaxStepHeight( const float newMaxStepHeight ); - float GetMaxStepHeight( void ) const; - void SetMaxJumpHeight( const float newMaxJumpHeight ); - void SetMovementType( const pmtype_t type ); - int GetMovementType( void ); // grayman #2345 - - /** - * Get/set the movement flags, used to force a crouch externally - **/ - int GetMovementFlags( void ); - void SetMovementFlags( int ); - void SetPlayerInput( const usercmd_t &cmd, const idAngles &newViewAngles ); - void SetKnockBack( const int knockBackTime ); - void SetDebugLevel( bool set ); - // feed back from last physics frame -#ifndef MOD_WATERPHYSICS - - waterLevel_t GetWaterLevel( void ) const; - - int GetWaterType( void ) const; - -#endif - - bool HasJumped( void ) const; - bool HasSteppedUp( void ) const; - float GetStepUp( void ) const; - bool IsCrouching( void ) const; - - /** - * Returns the reference entity velocity. Nonzero only when the - * player is climbing/roping so that their reference frame - * is determined by some ent they're attached to - **/ - idVec3 GetRefEntVel( void ) const; - - /** - * greebo: Returns the rope entity or NULL if the player is not attached to any rope. - */ - idEntity* GetRopeEntity(); - - bool OnRope() const; - - /** - * True if the player is climbing on a ladder or wall - **/ - bool OnLadder() const; - - /** - * Returns the surface type the player is climbing - * Returns empty string if the player is not climbing - **/ - idStr GetClimbSurfaceType() const; - - /** - * Returns the lateral world coordinates resolved into the lateral direction - * of the climbing surface. Used to keep track of lateral position for climb movement sounds - **/ - float GetClimbLateralCoord(const idVec3& origVec) const; - - /** - * Returns the distance between climbing sounds, in horizontal and vertical coords - **/ - int GetClimbSndRepDistVert() { return m_ClimbSndRepDistVert; } - int GetClimbSndRepDistHoriz() { return m_ClimbSndRepDistHoriz; } - - const idVec3 & PlayerGetOrigin() const; // != GetOrigin - - /** - * Get the view yaw and pitch changes between last frame and this frame - * Useful for rotating items in response to yaw, rope arrow, etc - * Returns the change in degrees - **/ - float GetDeltaViewYaw(); - float GetDeltaViewPitch(); - -public: - - /** - * Ishtvan: This variable is set when the player used crouch to detach - * from a climbable and is still holding down the button - * This is not saved/restored but cleared on restore, just to be safe - **/ - bool m_bClimbDetachCrouchHeld; - -public: // common physics interface - - // virtual override of base class method SetSelf() to set the push force owner - virtual void SetSelf( idEntity *e ); - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - - // This is true as soon as the player's velocity is well enough above walk speed - bool HasRunningVelocity(); - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - void ClearPushedVelocity( void ); - - void SetMaster( idEntity *master, const bool orientated = true ); - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -/** -* Removes stale pointers when a rope entity is destroyed -* RopeEnt is the rope entity that's about to be destroyed. -**/ - void RopeRemovalCleanup( idEntity *RopeEnt ); - -private: - // player physics state - playerPState_t current; - playerPState_t saved; - - // properties - float walkSpeed; - float crouchSpeed; - float maxStepHeight; - float maxJumpHeight; - int debugLevel; // if set, diagnostic output will be printed - - // greebo: Used for "jump stamina" - int lastJumpTime; - - // player input - usercmd_t command; - idAngles viewAngles; - - // run-time variables - int framemsec; - float frametime; - float playerSpeed; - idVec3 viewForward; - idVec3 viewRight; - - // walk movement - bool walking; - bool groundPlane; - trace_t groundTrace; - const idMaterial * groundMaterial; - - /** - * When the player is climbing on an entity (rope/wall, TODO: Apply to mantling) - * This stores the velocity of the entity they're climbing on, for adding and subtracting - * across functions if needed. - **/ - idVec3 m_RefEntVelocity; - - // rope movement - - /** - * Set to true if the player is moving and contacts a rope - **/ - bool m_bRopeContact; - - /** - * The rope entity that the player last attached to - **/ - idEntityPtr m_RopeEntity; - - /** - * The rope entity that the player last touched (not necessarily attached to) - * Used for the case where the player starts inside a rope and jumps up - **/ - idEntityPtr m_RopeEntTouched; - - - /** - * toggled based on whether the player should stay attached to rope - **/ - bool m_bOnRope; - - /** - * toggled on in the frame that the player first attaches to the rope - **/ - bool m_bJustHitRope; - /** - * Timer used to enforce time between kicks while on rope - **/ - int m_RopeKickTime; - - // ladder movement - /** - * Ladder is found ahead of us along view direction - **/ - bool m_bClimbableAhead; - /** - * We are currently attached to a ladder - **/ - bool m_bOnClimb; - /** - * Normal vector of the surface we're climbing on - **/ - idVec3 m_vClimbNormal; - /** - * Attachment point of where the player's origin attaches to the ladder - * In World coordinates - * NOTE: This is the last known attachment point - * The player is allowed to deviate from this a little to climb around corners - **/ - idVec3 m_vClimbPoint; - - /** - * Entity they're currently climbing on (used to add relative velocity) - **/ - idEntityPtr m_ClimbingOnEnt; - /** - * Set to true if the player has just detached from climbing this frame - * Used to tell SlideMove to step up at the top of something - **/ - bool m_bClimbDetachThisFrame; - - /** - * Set to true during the initial climb phase when the player - * has gone from not climbing on anything to attaching to something ahead. - * This is intended to fix a hovering-in-midair bug. - **/ - bool m_bClimbInitialPhase; - - /** - * String name of the surface type the player is climbing - **/ - idStr m_ClimbSurfName; - /** - * Max horizontal climbing velocity (parsed from player.def for given surface name) - **/ - float m_ClimbMaxVelHoriz; - /** - * Max vertical climbing veocity (parsed from player.def for given surface name) - **/ - float m_ClimbMaxVelVert; - /** - * Distance between repitions of the climbing sound, in vertical and horizontal direction - * An integer number of doomunits - **/ - int m_ClimbSndRepDistVert; - int m_ClimbSndRepDistHoriz; - - int m_NextAttachTime; - - /** - * View yaw and pitch changes between this frame and last frame - * In degrees. - **/ - float m_DeltaViewYaw; - float m_DeltaViewPitch; - - /** - * Door that the player is leaning into - * Set to NULL if the player is not leaning into a door - **/ - idEntityPtr m_LeanDoorEnt; - - /** - * Position to place the player listener beyond the door when door leaning - **/ - idVec3 m_LeanDoorListenPos; - - // greebo: The push force as applied to blocking objects - CForcePushPtr m_PushForce; - - // results of last evaluate -#ifndef MOD_WATERPHYSICS - - waterLevel_t waterLevel; - - int waterType; - -#endif - - -private: - float CmdScale( const usercmd_t &cmd ) const; - void Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel ); - bool SlideMove( bool gravity, bool stepUp, bool stepDown, bool push ); - void Friction( void ); - void WaterMove( void ); - void FlyMove( void ); - void AirMove( void ); - void WalkMove( void ); - void DeadMove( void ); - void NoclipMove( void ); - void SpectatorMove( void ); - void RopeMove( void ); - void LadderMove( void ); - void CorrectAllSolid( trace_t &trace, int contents ); - void CheckGround( void ); - void CheckDuck( void ); - bool CheckJump( void ); - bool CheckRopeJump( void ); - /** - * Read in the entity's velocity and store it to m_RefEntVelocity - * If the ent is a static, the bindmaster velocity is read off instead - * bodID is the clipmodel ID for AFs, defaults to zero - **/ - void SetRefEntVel( idEntity *ent, int bodID = 0 ); - -/** -* The following are used in wall/ladder climbing -**/ - void CheckClimbable( void ); - -#ifndef MOD_WATERPHYSICS - void SetWaterLevel( void ); -#endif - void DropTimers( void ); - void MovePlayer( int msec ); - -public: - void ClimbDetach( bool bStepUp = false ); - void RopeDetach( void ); - - // angua: player can not attach to rope/ladder before this time is over - void SetNextAttachTime(int time) - { - m_NextAttachTime = time; - } - - - - //##################################################### - // Mantling handler - // by SophisticatedZombie (Damon Hill) - // - //##################################################### - -public: - - - // This method returns - // true if the player is mantling, false otherwise - bool IsMantling() const; - - // This returns the current mantling phase - EMantlePhase GetMantlePhase() const; - - // Cancels any current mantle - void CancelMantle(); - - // Checks to see if there is a mantleable target within reach - // of the player's view. If so, starts the mantle... - // If the player is already mantling, this does nothing. - void PerformMantle(); - -protected: - - /*! - * The current mantling phase - */ - EMantlePhase m_mantlePhase; - - /** - * greebo: Set to TRUE if the next mantling can start. Set to FALSE at the - * beginning of a mantle process - the jump button has to be released - * again during a non-mantling phase to set this to TRUE again. - */ - bool m_mantleStartPossible; - - /*! - * Points along the mantle path - */ - idVec3 m_mantlePullStartPos; - idVec3 m_mantlePullEndPos; - idVec3 m_mantlePushEndPos; - - /*! - * Pointer to the entity being mantled. - * This is undefined if m_mantlePhase == notMantling_DarkModMantlePhase - */ - idEntity* m_p_mantledEntity; - - /*! - * ID number of the entity being mantled - * This is 0 if m_mantlePhase == notMantling_DarkModMantlePhase - */ - int m_mantledEntityID; - - /*! - * How long will the current phase of the mantle operation take? - * Uses milliseconds and counts down to 0. - */ - float m_mantleTime; - - /*! - * Tracks, in milliseconds, how long jump button has been held down - * Counts upwards from 0. - */ - float m_jumpHeldDownTime; - - /*! - * This method determines the mantle time required for each phase of the mantle. - * I made this a function so you could implement things such as carry-weight, - * tiredness, length of lift.... - * @param[in] mantlePhase The mantle phase for which the duration is to be retrieved - */ - float GetMantleTimeForPhase(EMantlePhase mantlePhase); - - /*! - * - * Internal method to start the mantle operation - * - * @param[in] initialMantlePhase The mantle phase in which the mantle starts. - * @param[in] eyePos The position of the player's eyes in the world - * @param[in] startPos The position of the player's feet at the start of the mantle - * @param[in] endPos The position of the player's feet at the end of the mantle - */ - void StartMantle - ( - EMantlePhase initialMantlePhase, - idVec3 eyePos, - idVec3 startPos, - idVec3 endPos - ); - - /*! - * Internal method which determines the maximum vertical - * and horizontal distances for mantling - * - * @param[out] out_maxVerticalReachDistance The distance that the player can reach vertically, from their current origin - * @param[out] out_maxHorizontalReachDistance The distance that the player can reach horizontally, from their current origin - * @param[out] out_maxMantleTraceDistance The maximum distance that the traces should look in front of the player for a mantle target - */ - void GetCurrentMantlingReachDistances - ( - float& out_maxVerticalReachDistance, - float& out_maxHorizontalReachDistance, - float& out_maxMantleTraceDistance - ); - - /*! - * This method runs the trace to find a mantle target - * It first attempts to raycast along the player's gaze - * direction to determine a target. If it doesn't find one, - * then it tries a collision test along a vertical plane - * from the players feet to their height, out in the direction - * the player is facing. - * - * @param[in] maxMantleTraceDistance The maximum distance from the player that should be used in the traces - * @param[in] eyePos The position of the player's eyes, used for the beginning of the gaze trace - * @param[in] forwardVec The vector gives the direction that the player is facing - * @param[out] out_trace This trace structure will hold the result of whichever trace succeeds. If both fail, the trace fraction will be 1.0 - */ - void MantleTargetTrace - ( - float maxMantleTraceDistance, - const idVec3& eyePos, - const idVec3& forwardVec, - trace_t& out_trace - ); - - /*! - * - * This function checks the collision target of the mantle - * trace to see if there is a surface within reach distance - * upon which the player will fit. - * - * @param[in] maxVerticalReachDistance The maximum distance that the player can reach vertically from their current origin - * @param[in] maxHorizontalReachDistance The maximum distance that the player can reach horizontally from their current origin - * @param[in] in_targetTraceResult The trace which found the mantle target - * @param[out] out_mantleEndPoint If the return code is true, this out paramter specifies the position of the player's origin at the end of the mantle move. - * - * @return the result of the test - * @retval true if the mantle target has a mantleable surface - * @retval false if the mantel target does not have a mantleable surface - * - */ - bool DetermineIfMantleTargetHasMantleableSurface - ( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - trace_t& in_targetTraceResult, - idVec3& out_mantleEndPoint - ); - - /*! - * Call this method to test whether or not the path - * along the mantle movement is free of obstructions. - * - * @param[in] maxVerticalReachDistance The maximum distance that the player can reach vertically from their current origin - * @param[in] maxHorizontalReachDistance The maximum distance that the player can reach horizontally from their current origin - * @param[in] eyePos The position of the player's eyes in the world - * @param[in] mantleStartPoint The player's origin at the start of the mantle movement - * @param[in] mantleEndPoint The player's origin at the end of the mantle movement - * - * @return the result of the test - * @retval true if the path is clear - * @retval false if the path is blocked - */ - bool DetermineIfPathToMantleSurfaceIsPossible - ( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - const idVec3& eyePos, - const idVec3& mantleStartPoint, - const idVec3& mantleEndPoint - ); - - /*! - * Given a trace which resulted in a detected mantle - * target, this method checks to see if the target - * is mantleable. It looks for a surface up from gravity - * on which the player can fit while crouching. It also - * checks that the distance does not violate horizontal - * and vertical displacement rules for mantling. Finally - * it checks that the path to the mantleable surface is - * not blocked by obstructions. - * - * This method calls DetermineIfMantleTargetHasMantleableSurface and - * also DetermineIfPathToMantleSurfaceIsPossible - * - * @param[in] maxVerticalReachDistance The maximum distance from the player's origin that the player can reach vertically - * @param[in] maxHorizontalReachDistance The maximum distance from the player's origin that the player can reach horizontally - * @param[in] eyePos The position of the player's eyes (camera point) in the world coordinate system - * @param[in] in_targetTraceResult Pass in the trace result from MantleTargetTrace - * @param[out] out_mantleEndPoint If the return value is true, this passes back out what the player's origin will be at the end of the mantle - * - * @returns the result of the test - * @retval true if the mantle target can be mantled - * @retval false if the mantle target cannot be mantled - * - */ - bool ComputeMantlePathForTarget - ( - float maxVerticalReachDistance, - float maxHorizontalReachDistance, - const idVec3& eyePos, - trace_t& in_targetTraceResult, - idVec3& out_mantleEndPoint - ); - - /*! - * This handles the reduction of the mantle timer by the - * number of milliseconds between animation frames. It - * uses the timer results to update the mantle timers. - */ - void UpdateMantleTimers(); - - /*! - * This handles the movement of the the player during - * the phases of the mantle. It performs the translation - * of the player along the mantle path, the camera movement - * that creates the visual effect, and the placing of the - * player into a crouch during the end phase of the mantle. - * - */ - void MantleMove(); - - // Tests if player is holding down jump while already jumping - // (can be used to trigger mantle) - bool CheckJumpHeldDown(); - - //################################################# - // End mantling handler - //################################################# - - //##################################################### - // Leaning handler - // by SophisticatedZombie (Damon Hill) - // - //##################################################### - -protected: - - /** - * Set to true if the player is leaning at all from the vertical - **/ - bool m_bIsLeaning; - - /*! - * An axis which is perpendicular to the gravity normal and - * rotated by the given yaw angle clockwise (when looking down in direction of - * gravity) around it. The player always leans to positive angles - * around this axis. - */ - float m_leanYawAngleDegrees; - - /*! - * The current lean angle - */ - float m_CurrentLeanTiltDegrees; - - /** - * Current lean stretch fraction. When this is 1.0, the player is at full stretch, at 0.0, not stretched - **/ - float m_CurrentLeanStretch; - - /*! - * The start (roll) angle of this lean movement - */ - float m_leanMoveStartTilt; - - /*! - * The end (roll) angle of this lean movement - */ - float m_leanMoveEndTilt; - - /** - * Max lean angle (set dynamically depending on forward/sideways leans) - **/ - float m_leanMoveMaxAngle; - - /** - * Maximum lean stretch (set dynamically depending on forward/sideways leans) - **/ - float m_leanMoveMaxStretch; - - /*! - * Is the lean finished - */ - bool m_b_leanFinished; - - /*! - * How long will the current phase of the leaning operation take? - * Uses milliseconds and counts down to 0 - */ - float m_leanTime; - - /*! - * The last recorded view angles - * These are updated each animation frame and are used - * to track player rotations to due rotation collision detection. - * The original Doom3 code did not need to due collision tests - * during player view rotation, but if the player is leaning, it is - * necessary to prevent passing through solid objects - */ - idAngles m_lastPlayerViewAngles; - - float m_lastCommandViewYaw; - float m_lastCommandViewPitch; - - /*! - * The current resulting view lean angles - */ - idAngles m_viewLeanAngles; - - /*! - * The current resulting view lean translation - * In local/player coordinates (along player model axes, not world axes) - */ - idVec3 m_viewLeanTranslation; - - /** - * Lean bounds for collision testing. Same as most view testing bounds, 10x10x10 box - * Also extends 15 units downwards. Initialized once at spawn. - **/ - idBounds m_LeanViewBounds; - -protected: - /** - * This uses the other internal mtehods to coordiante the lean - * lean movement. - **/ - void LeanMove(); - - /** - * Test clipping for the current eye position, plus delta in the lean direction - **/ - bool TestLeanClip(); - - /** - * Convert a lean angle and stretch into a point in space, in world coordinates - **/ - idVec3 LeanParmsToPoint( float AngTilt, float Stretch ); - - /*! - * This method updates the lean by as much of the delta amount given - * that does not result in a clip model trace collision. - * - * This is an internal method called by LeanMove. - * UpdateLeanPhysics must be called after this. - **/ - void UpdateLeanAngle(float deltaLeanAngle, float deltaLeanStretch); - - /** - * Takes the currently set m_CurrentLeanTiltDegrees and m_CurrentLeanStretch - * And updates m_LeanTranslation and m_ViewLeanAngles - * Should be called after changing these member vars. - **/ - void UpdateLeanPhysics(); - - /** - * This method gets called when the leaned player view is found to be clipping something - * It un-leans them in increments until they are outside the solid object - **/ - void UnleanToValidPosition(); - - /** - * Calculates the listener position when leaning against a given door - * Tests points in space along the lean yaw axis until they come out the other - * side of the door into empty space. - * - * Takes the point of contact (where the trace hit the door), - * starts testing at this point, extending along lean yaw axis. - * - * If a point is found, it sets m_DoorListenPos and returns true - * If door is too thick to listen through, returns false - **/ - bool FindLeanDoorListenPos(const idVec3& incidencePoint, CFrobDoor* door); - - /** - * Tests whether the player is still leaning against the door. - * If not, clears m_LeanDoorEnt - **/ - void UpdateLeanDoor(); - -public: - - /*! - * Starts or ends a lean around and axis which is perpendicular to the gravity normal and - * rotated by the given yaw angle clockwise (when looking down in direction of - * gravity) around it. - * - * @param[in] leanYawAngleDegrees The angle of the axis around which the player will - * lean clockwise, itself rotated clockwise from straight forward. - * 0.0 leans right, 180.0 leans left, 90.0 leans forward, 270.0 leans backward - * - */ - void ToggleLean(float leanYawAngleDegrees); - - /*! - * This method tests if the player is in the middle of a leaning - * movement. - * - * @return the result of the test - * @retval true if the player is changing lean - * @retval false if the player is not changing lean - */ - bool IsLeaning(); - - /** - * Returns true if the player is leaning against a door - **/ - bool IsDoorLeaning(); - - /*! - * This is called from idPlayer to adjust the camera before - * rendering - * Returns current view lean translation in world axes - */ - const idAngles& GetViewLeanAngles() const; - - /* - * This is called from idPlayer to adjust the camera before - * rendering - */ - idVec3 GetViewLeanTranslation(); - - /** - * Takes proposed new view angles InputAngles, - * tests whether the change in yaw will cause a collision - * of the leaned camera with a wall. If so, clamps the yaw before the collision. - * Overwrites InputAngles with the new vetted angles. - * Does nothing if the player is not leaned - **/ - void UpdateLeanedInputYaw( idAngles &InputAngles ); -}; - -#endif /* !__PHYSICS_PLAYER_H__ */ diff --git a/game/physics/physics_rigidbody.cpp b/game/physics/physics_rigidbody.cpp deleted file mode 100644 index 3d368112a..000000000 --- a/game/physics/physics_rigidbody.cpp +++ /dev/null @@ -1,2187 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../DarkMod/Grabber.h" - -CLASS_DECLARATION( idPhysics_Base, idPhysics_RigidBody ) -END_CLASS - -#ifdef MOD_WATERPHYSICS -const int STOP_SPEED = 10; -// if linearVelocity < WATER_STOP_LINEAR && angularVelocity < WATER_STOP_ANGULAR then set the RB to rest -// and we need this->noMoveTime + NO_MOVE_TIME < gameLocal.getTime() -const idVec3 WATER_STOP_LINEAR(10.0f,10.0f,10.0f); -const idVec3 WATER_STOP_ANGULAR(500000.0f,500000.0f,500000.0f); -const int NO_MOVE_TIME = 200; -static const float MAX_GRABBER_EXT_VELOCITY = 120.0f; -static const float MAX_GRABBER_EXT_ANGVEL = 5.0f; -#else -const float STOP_SPEED = 10.0f; -#endif - - -#undef RB_TIMINGS - -#ifdef RB_TIMINGS -static int lastTimerReset = 0; -static int numRigidBodies = 0; -static idTimer timer_total, timer_collision; -#endif - - -/* -================ -RigidBodyDerivatives -================ -*/ -void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives ) { - const idPhysics_RigidBody *p = (idPhysics_RigidBody *) clientData; - rigidBodyIState_t *s = (rigidBodyIState_t *) state; - // NOTE: this struct should be build conform rigidBodyIState_t - struct rigidBodyDerivatives_s { - idVec3 linearVelocity; - idMat3 angularMatrix; - idVec3 force; - idVec3 torque; - } *d = (struct rigidBodyDerivatives_s *) derivatives; - idVec3 angularVelocity; - idMat3 inverseWorldInertiaTensor; - - inverseWorldInertiaTensor = s->orientation * p->inverseInertiaTensor * s->orientation.Transpose(); - angularVelocity = inverseWorldInertiaTensor * s->angularMomentum; - // derivatives - d->linearVelocity = p->inverseMass * s->linearMomentum; - d->angularMatrix = SkewSymmetric( angularVelocity ) * s->orientation; - -#ifdef MOD_WATERPHYSICS - // underwater we have a higher friction - if( p->GetWaterLevelf() == 0.0f ) { - d->force = - p->linearFriction * s->linearMomentum + p->current.externalForce; - d->torque = - p->angularFriction * s->angularMomentum + p->current.externalTorque; - } else { - // don't let water friction go less than 25% of the water viscosity - float percent = Max(0.25f,p->GetSubmergedPercent(s->position,s->orientation.Transpose())); - - d->force = (-p->linearFriction * p->water->GetViscosity() * percent) * s->linearMomentum + p->current.externalForce; - d->torque = (-p->angularFriction * p->water->GetViscosity()) * s->angularMomentum + p->current.externalTorque; - } -#else - d->force = - p->linearFriction * s->linearMomentum + p->current.externalForce; - d->torque = - p->angularFriction * s->angularMomentum + p->current.externalTorque; -#endif -} - -#ifdef MOD_WATERPHYSICS -/* -================ -idPhysics_RigidBody::GetSubmergedPercent - - Approximates the percentage of the body that is submerged -================ -*/ -float idPhysics_RigidBody::GetSubmergedPercent( const idVec3 &pos, const idMat3 &rotation ) const -{ - idVec3 depth,bottom(pos); - idBounds bounds = this->GetBounds(); - float height,d; - - if( this->water == NULL ) - return 0.0f; - - // offset and rotate the bounding box - bounds += -centerOfMass; - bounds *= rotation; - - // gets the position of the object relative to the surface of the water - height = fabs(bounds[1] * gravityNormal * 2); - - // calculates the depth of the bottom of the object - bottom += (height * 0.5f) * gravityNormal; - depth = this->water->GetDepth(bottom); - d = fabs(depth * gravityNormal); - - if( d > height ) { - // the body is totally submerged - return 1.0f; - } - else if( d <= 0 ) { - return 0.0f; - } - else { - // the body is partly submerged - return d / height; - } -} - -/* -================ -idPhysics_RigidBody::GetBuoyancy - - Gets buoyancy information for this RB -================ -*/ -bool idPhysics_RigidBody::GetBuoyancy( const idVec3 &pos, const idMat3 &rotation, idVec3 &bCenter, float &percent ) const -{ - // pos - position of the RB - // rotation - axis for the RB - // bCenter - after the function is called this is an approximation for the center of buoyancy - // percent - rough percentage of the body that is under water - // used to calculate the volume of the submersed object (volume * percent) to give - // the body somewhat realistic bobbing. - // - // return true if the body is in water, false otherwise - - idVec3 tbCenter(pos); - idBounds bounds = this->GetBounds(); - idTraceModel tm = *this->GetClipModel()->GetTraceModel(); - int i,count; - - percent = this->GetSubmergedPercent(pos,rotation); - bCenter = pos; - - if( percent == 1.0f ) { - // the body is totally submerged - return true; - } - else { - // the body is partly submerged (or not in the water) - // - // We do a rough approximation for center of buoyancy. - // Normally this is done by calculating the volume of the submersed part of the body - // so the center of buoyancy is the center of mass of the submersed volume. This is - // probably a slow computation so what I do is take an average of the submersed - // vertices of the trace model. - // - // I was suprized when this first worked but you can use rb_showBuoyancy to see - // what the approximation looks like. - - // set up clip model for approximation of center of buoyancy - tm.Translate( -centerOfMass ); - tm.Rotate( rotation ); - tm.Translate( pos ); - - // calculate which vertices are under water - for( i = 0, count = 1; i < tm.numVerts; i++ ) { - if( gameLocal.clip.Contents( tm.verts[ i ], NULL, this->GetAxis(), MASK_WATER, NULL ) ) { - tbCenter += tm.verts[ i ]; - count += 1; - } - } - - if( count == 1 ) - bCenter = pos; - else - bCenter = tbCenter / count; - return (count != 1); - } -} -#endif // MOD_WATERPHYSICS - -/* -================ -idPhysics_RigidBody::Integrate - - Calculate next state from the current state using an integrator. -================ -*/ -void idPhysics_RigidBody::Integrate( float deltaTime, rigidBodyPState_t &next ) { - idVec3 position; - - position = current.i.position; - current.i.position += centerOfMass * current.i.orientation; - - current.i.orientation.TransposeSelf(); - - integrator->Evaluate( (float *) ¤t.i, (float *) &next.i, 0, deltaTime ); - next.i.orientation.OrthoNormalizeSelf(); - -#ifdef MOD_WATERPHYSICS - // apply a water gravity if the body is in water - if( this->SetWaterLevelf() != 0.0f ) { - idVec3 bCenter; - idVec3 bForce(gravityVector),rForce(-gravityVector); - float bMass,fraction,liquidMass; - bool inWater; - - inWater = this->GetBuoyancy(next.i.position,next.i.orientation.Transpose(),bCenter,fraction); - - // calculate water mass - liquidMass = this->volume * this->water->GetDensity() * fraction; - // don't let liquid mass get too high - liquidMass = Min( liquidMass, 3 * this->mass ); - - bMass = this->mass - liquidMass; - - // calculate buoyancy force - bForce *= deltaTime * bMass; - rForce *= deltaTime * liquidMass; - - // apply water force - // basically here we do a ::ApplyImpulse() but we apply it to next, not current - next.i.linearMomentum += bForce; - next.i.angularMomentum += (bCenter - next.i.position).Cross(rForce); - - // take the body out of water if it's not in water. - if( !inWater ) this->SetWater(NULL, 0.0f); - } else -#endif - next.i.linearMomentum += deltaTime * gravityVector * mass; // apply normal gravity - - current.i.orientation.TransposeSelf(); - next.i.orientation.TransposeSelf(); - - current.i.position = position; - next.i.position -= centerOfMass * next.i.orientation; - - next.atRest = current.atRest; -} - -bool idPhysics_RigidBody::PropagateImpulse(const int id, const idVec3& point, const idVec3& impulse) -{ - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Contacts with this entity %s = %d\r", self->name.c_str(), contacts.Num()); - - if (propagateImpulseLock || impulse.LengthSqr() < 1e-5) - { - // greebo: Don't process incoming small impulses, quit at once. - return false; - } - - // Don't accept other propagations during processing - propagateImpulseLock = true; - - // greebo: Check all entities touching this physics object - EvaluateContacts(); - - /** - * greebo: The incoming impulse goes through 3 stages: - * - * 1) The contact friction of this object reduces the impulse - * 2) The reduced impulse is distributed among the contact entities - * 3) The remaining impulse is applied to self. - */ - - // Save the current state - rigidBodyPState_t savedState = current; - - // Apply the impulse to the current state, as if the object was resting - current.i.linearMomentum.Zero(); - current.i.angularMomentum.Zero(); - ApplyImpulse(0, point, impulse); - -// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum before friction:", current.i.linearMomentum); -// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum before friction:", current.i.angularMomentum); - - // Calculate the friction using this state - //ContactFriction(current.lastTimeStep); - - // greebo: Disabled contact friction for now - //current.i.linearMomentum *= 1.0f; - //current.i.angularMomentum *= 1.0f; - -// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum after friction:", current.i.linearMomentum); -// DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum after friction:", current.i.angularMomentum); - - // The list of all the touching entities - idList touching; - - // greebo: FIXME: A possible optimisation would be to store the contact indices instead of copying the entire struct - - //gameRenderWorld->DebugArrow(colorGreen, point, point + impulseN*10, 1, 5000); - - // greebo: Check for any contact normals that are suitable for this impulse direction - // Contact normals with angles larger than pi/2 are discarded. - for (int i = 0; i < contacts.Num(); i++) - { - if (contacts[i].entityNum == ENTITYNUM_WORLD) - continue; - - idEntity* contactEntity = gameLocal.entities[contacts[i].entityNum]; - - //gameRenderWorld->DebugArrow(colorBlue, contacts[i].point, contacts[i].point + contacts[i].normal*20, 1, 5000); - - if (contactEntity == NULL) - continue; - - if ((impulse * -contacts[i].normal) < 0.0f) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Entity %s is not in push direction.\r", contactEntity->name.c_str()); - continue; - } - - // Add the contact info to the list, it is significant - touching.Append(contacts[i]); - } - - int numTouching = touching.Num(); - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Contacts with this entity %s without world = %d\r", self->name.c_str(), numTouching); - - if (numTouching > 0) - { - // Distribute the impulse evenly across the touching entities - idVec3 impulseFraction(current.i.linearMomentum / touching.Num()); - float impulseFractionLen(impulseFraction.LengthFast()); - - // Now apply the impulse to the touching entities - for (int i = 0; i < numTouching; i++) - { - idEntity* pushed = gameLocal.entities[touching[i].entityNum]; - - if (pushed == NULL) - continue; - - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Propagating impulse to entity %s\r", pushed->name.c_str()); - //gameRenderWorld->DebugArrow(colorRed, touching[i].point, touching[i].point - touching[i].normal*10, 1, 1000); - - pushed->GetPhysics()->PropagateImpulse(id, touching[i].point, -touching[i].normal * impulseFractionLen); - - // Substract this propagated impulse from the remaining one - current.i.linearMomentum -= impulseFraction; - } - } - - // Save the remaining impulse before reverting the physics state - idVec3 remainingImpulse(current.i.linearMomentum); - - // Revert the state to as it was before - current = savedState; - - // Apply the remaining impulse to this object - ApplyImpulse(0, point, remainingImpulse); - - DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Linear Momentum after applyImpulse:", current.i.linearMomentum); - DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Angular Momentum after applyImpulse:", current.i.angularMomentum); - - propagateImpulseLock = false; - - // Return TRUE if we pushed any neighbours, FALSE if this was a single pushed object - return (numTouching > 0); -} - -/* -================ -idPhysics_RigidBody::CollisionImpulse - - Calculates the collision impulse using the velocity relative to the collision object. - The current state should be set to the moment of impact. -================ -*/ -bool idPhysics_RigidBody::CollisionImpulse( const trace_t &collision, idVec3 &impulse ) -{ - idVec3 r, linearVelocity, angularVelocity, velocity; - idMat3 inverseWorldInertiaTensor; - float impulseNumerator, impulseDenominator, vel; - impactInfo_t info; - idEntity *ent; - - // get info from other entity involved - ent = gameLocal.entities[collision.c.entityNum]; - ent->GetImpactInfo( self, collision.c.id, collision.c.point, &info ); - - // Check if we are grabbed by the grabber, and set collision var if so - if ( self == gameLocal.m_Grabber->GetSelected() ) - { - // greebo: Don't collide grabbed entities with its own bindslaves - if ( (ent->GetBindMaster() == NULL || self != ent->GetBindMaster()) - && ent != gameLocal.GetLocalPlayer() ) - { - gameLocal.m_Grabber->m_bIsColliding = true; - gameLocal.m_Grabber->m_CollNorms.AddUnique( collision.c.normal ); - } - } - - // Update moved by and set in motion by actor - if( self->m_SetInMotionByActor.GetEntity() != NULL ) - { - ent->m_SetInMotionByActor = self->m_SetInMotionByActor.GetEntity(); - ent->m_MovedByActor = self->m_MovedByActor.GetEntity(); - } - // Note: Actors should not overwrite the moved by other actors when they are hit with something - // So only overwrite if MovedByActor is NULL - if( ent->IsType(idActor::Type) - && self->m_SetInMotionByActor.GetEntity() == NULL - && !(static_cast(ent)->IsKnockedOut() || ent->health < 0) ) - { - self->m_SetInMotionByActor = (idActor *) ent; - self->m_MovedByActor = (idActor *) ent; - } - - // collision point relative to the body center of mass - r = collision.c.point - ( current.i.position + centerOfMass * current.i.orientation ); - // the velocity at the collision point - linearVelocity = inverseMass * current.i.linearMomentum; - inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; - angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; - velocity = linearVelocity + angularVelocity.Cross(r); - // subtract velocity of other entity - velocity -= info.velocity; - - // velocity in normal direction - vel = velocity * collision.c.normal; - - if ( vel > -STOP_SPEED ) { - impulseNumerator = STOP_SPEED; - } - else { - impulseNumerator = -( 1.0f + bouncyness ) * vel; - } - impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal ); - if ( info.invMass ) { - impulseDenominator += info.invMass + ( ( info.invInertiaTensor * info.position.Cross( collision.c.normal ) ).Cross( info.position ) * collision.c.normal ); - } - impulse = (impulseNumerator / impulseDenominator) * collision.c.normal; - -//#define DEBUG_COLLISIONS -#ifdef DEBUG_COLLISIONS - idVec3 velocityN(GetLinearVelocity()); - velocityN.NormalizeFast(); - - idVec3 velocityA(GetAngularVelocity()); - velocityA.NormalizeFast(); - - idVec3 impulseN(impulse); - impulseN.NormalizeFast(); - - idVec3 impulseA(r.Cross(impulse)); - impulseA.NormalizeFast(); - - idVec3 origin = current.i.position + centerOfMass * current.i.orientation; - - gameRenderWorld->DebugArrow(colorRed, origin, origin + velocityN*10, 1, 15); - gameRenderWorld->DebugArrow(colorBlue, origin, origin + velocityA*10, 1, 15); - - gameRenderWorld->DebugArrow(colorMagenta, idVec3(1,0,0) + origin + velocityN*10, origin + velocityN*10 + impulseN*10, 1, 15); - gameRenderWorld->DebugArrow(colorGreen, idVec3(1,0,0) + origin + velocityA*10, origin + velocityA*10 + impulseA*10, 1, 15); - - gameRenderWorld->DebugArrow(colorMdGrey, collision.c.point, collision.c.point + collision.c.normal*10, 1, 15); - //gameRenderWorld->DrawTextA(ent->name.c_str(), collision.c.point, 1, colorMdGrey, current.i.orientation, 1, 500); - -#endif - - // update linear and angular momentum with impulse - current.i.linearMomentum += impulse; - current.i.angularMomentum += r.Cross(impulse); - - //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Collision fraction of %s = %f\r", self->name.c_str(), collision.fraction); - - // if no movement at all don't blow up - if ( collision.fraction < 0.0001f ) { - current.i.linearMomentum *= 0.5f; - current.i.angularMomentum *= 0.5f; - } - - // callback to self to let the entity know about the collision - return self->Collide( collision, velocity ); -} - -/* -================ -idPhysics_RigidBody::CheckForCollisions - - Check for collisions between the current and next state. - If there is a collision the next state is set to the state at the moment of impact. -================ -*/ -bool idPhysics_RigidBody::CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision ) { -//#define TEST_COLLISION_DETECTION - idMat3 axis; - idRotation rotation; -#ifdef MOD_WATERPHYSICS - idVec3 pos; - trace_t waterCollision; -#endif - bool collided = false; - -#ifdef TEST_COLLISION_DETECTION - bool startsolid; - if ( gameLocal.clip.Contents( current.i.position, clipModel, current.i.orientation, clipMask, self ) ) { - startsolid = true; - } -#endif - - TransposeMultiply( current.i.orientation, next.i.orientation, axis ); - rotation = axis.ToRotation(); - rotation.SetOrigin( current.i.position ); - - // if there was a collision -#ifdef MOD_WATERPHYSICS - pos = next.i.position; -#endif - - if ( gameLocal.clip.Motion( collision, current.i.position, next.i.position, rotation, clipModel, current.i.orientation, clipMask, self ) ) { - - // set the next state to the state at the moment of impact - next.i.position = collision.endpos; - next.i.orientation = collision.endAxis; - next.i.linearMomentum = current.i.linearMomentum; - next.i.angularMomentum = current.i.angularMomentum; - collided = true; - } - -#ifdef MOD_WATERPHYSICS - // Check for water collision - // ideally we could do this check in one step but if a body moves quickly in shallow water - // they will occasionally clip through a solid entity (ie. fall through the floor) - if ( gameLocal.clip.Motion( waterCollision, current.i.position, pos, rotation, clipModel, current.i.orientation, MASK_WATER, self ) ) - { - idEntity *ent = gameLocal.entities[waterCollision.c.entityNum]; - - // make sure the object didn't collide with something before hitting the water (we don't splash for that case) - if( !collided || waterCollision.fraction < collision.fraction ) { - - // if the object collides with something with a physics_liquid - if( ent->GetPhysics()->IsType( idPhysics_Liquid::Type ) ) { - idPhysics_Liquid *liquid = static_cast(ent->GetPhysics()); - impactInfo_t info; - - self->GetImpactInfo(ent,waterCollision.c.id,waterCollision.c.point,&info); - - // apply water splash friction - if( this->water == NULL ) { - idVec3 impulse = -info.velocity * this->volume * liquid->GetDensity() * 0.25f; - impulse = (impulse * gravityNormal) * gravityNormal; - - if( next.i.linearMomentum.LengthSqr() < impulse.LengthSqr() ) { - // cancel falling, maintain sideways movement (lateral?) - next.i.linearMomentum -= (next.i.linearMomentum * gravityNormal) * gravityNormal; - } - else { - next.i.angularMomentum += ( waterCollision.c.point - ( next.i.position + centerOfMass * next.i.orientation ) ).Cross( impulse ); - next.i.linearMomentum += impulse * 0.5f; - } - } - - this->SetWater(liquid, ent->spawnArgs.GetFloat("murkiness", "0")); - this->water->Splash(this->self,this->volume,info,waterCollision); - } - } - } -#endif - -#ifdef TEST_COLLISION_DETECTION - if ( gameLocal.clip.Contents( next.i.position, clipModel, next.i.orientation, clipMask, self ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - return collided; -} - -/* -================ -idPhysics_RigidBody::ContactFriction - - Does not solve friction for multiple simultaneous contacts but applies contact friction in isolation. - Uses absolute velocity at the contact points instead of the velocity relative to the contact object. -================ -*/ -void idPhysics_RigidBody::ContactFriction( float deltaTime ) { - int i; - float magnitude, impulseNumerator, impulseDenominator; - idMat3 inverseWorldInertiaTensor; - idVec3 linearVelocity, angularVelocity; - idVec3 massCenter, r, velocity, normal, impulse, normalVelocity; - - inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; - - massCenter = current.i.position + centerOfMass * current.i.orientation; - - for ( i = 0; i < contacts.Num(); i++ ) { - - r = contacts[i].point - massCenter; - - // calculate velocity at contact point - linearVelocity = inverseMass * current.i.linearMomentum; - angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; - velocity = linearVelocity + angularVelocity.Cross(r); - - // velocity along normal vector - normalVelocity = ( velocity * contacts[i].normal ) * contacts[i].normal; - - // calculate friction impulse - normal = -( velocity - normalVelocity ); - magnitude = normal.Normalize(); - impulseNumerator = contactFriction * magnitude; - impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( normal ) ).Cross( r ) * normal ); - impulse = (impulseNumerator / impulseDenominator) * normal; - - // apply friction impulse - current.i.linearMomentum += impulse; - current.i.angularMomentum += r.Cross(impulse); - - // if moving towards the surface at the contact point - if ( normalVelocity * contacts[i].normal < 0.0f ) { - // calculate impulse - normal = -normalVelocity; - impulseNumerator = normal.Normalize(); - impulseDenominator = inverseMass + ( ( inverseWorldInertiaTensor * r.Cross( normal ) ).Cross( r ) * normal ); - impulse = (impulseNumerator / impulseDenominator) * normal; - - // apply impulse - current.i.linearMomentum += impulse; - current.i.angularMomentum += r.Cross( impulse ); - } - } -} - -/* -================ -idPhysics_RigidBody::TestIfAtRest - - Returns true if the body is considered at rest. - Does not catch all cases where the body is at rest but is generally good enough. -================ -*/ -#ifdef MOD_WATERPHYSICS -bool idPhysics_RigidBody::TestIfAtRest( void ) { -#else -bool idPhysics_RigidBody::TestIfAtRest( void ) const { -#endif - int i; - float gv; - idVec3 v, av, normal, point; - idMat3 inverseWorldInertiaTensor; - idFixedWinding contactWinding; - - if ( current.atRest >= 0 ) { - return true; - } -#ifdef MOD_WATERPHYSICS - // do some special checks if the body is in water - if( this->water != NULL ) { - if( this->current.i.linearMomentum.LengthSqr() < WATER_STOP_LINEAR.LengthSqr() && - this->current.i.angularMomentum.LengthSqr() < WATER_STOP_ANGULAR.LengthSqr() ) { - - if( this->noMoveTime == 0 ) { - this->noMoveTime = gameLocal.GetTime(); - } else if( this->noMoveTime+NO_MOVE_TIME < gameLocal.GetTime() ) { - this->noMoveTime = 0; - return true; - } - } else { - this->noMoveTime = 0; - } - } -#endif - - // need at least 3 contact points to come to rest - if ( contacts.Num() < 3 ) { - return false; - } - - // get average contact plane normal - normal.Zero(); - for ( i = 0; i < contacts.Num(); i++ ) { - normal += contacts[i].normal; - } - normal /= (float) contacts.Num(); - normal.Normalize(); - - // if on a too steep surface - if ( (normal * gravityNormal) > -0.7f ) { - return false; - } - - // create bounds for contact points - contactWinding.Clear(); - for ( i = 0; i < contacts.Num(); i++ ) { - // project point onto plane through origin orthogonal to the gravity - point = contacts[i].point - (contacts[i].point * gravityNormal) * gravityNormal; - contactWinding.AddToConvexHull( point, gravityNormal ); - } - - // need at least 3 contact points to come to rest - if ( contactWinding.GetNumPoints() < 3 ) { - return false; - } - - // center of mass in world space - point = current.i.position + centerOfMass * current.i.orientation; - point -= (point * gravityNormal) * gravityNormal; - - // if the point is not inside the winding - if ( !contactWinding.PointInside( gravityNormal, point, 0 ) ) { - return false; - } - - // linear velocity of body - v = inverseMass * current.i.linearMomentum; - // linear velocity in gravity direction - gv = v * gravityNormal; - // linear velocity orthogonal to gravity direction - v -= gv * gravityNormal; - - // if too much velocity orthogonal to gravity direction - if ( v.Length() > STOP_SPEED ) { - return false; - } - // if too much velocity in gravity direction - if ( gv > 2.0f * STOP_SPEED || gv < -2.0f * STOP_SPEED ) { - return false; - } - - // calculate rotational velocity - inverseWorldInertiaTensor = current.i.orientation * inverseInertiaTensor * current.i.orientation.Transpose(); - av = inverseWorldInertiaTensor * current.i.angularMomentum; - - // if too much rotational velocity - if ( av.LengthSqr() > STOP_SPEED ) { - return false; - } - - return true; -} - -/* -================ -idPhysics_RigidBody::DropToFloorAndRest - - Drops the object straight down to the floor and verifies if the object is at rest on the floor. -================ -*/ -void idPhysics_RigidBody::DropToFloorAndRest( void ) { - idVec3 down; - trace_t tr; - - if ( testSolid ) { - - testSolid = false; - - if ( gameLocal.clip.Contents( current.i.position, clipModel, current.i.orientation, clipMask, self ) ) { - gameLocal.DWarning( "rigid body in solid for entity '%s' type '%s' at (%s)", - self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); - Rest(); - dropToFloor = false; - return; - } - } - - // put the body on the floor - down = current.i.position + gravityNormal * 128.0f; - gameLocal.clip.Translation( tr, current.i.position, down, clipModel, current.i.orientation, clipMask, self ); - current.i.position = tr.endpos; - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), tr.endpos, current.i.orientation ); - - // if on the floor already - if ( tr.fraction == 0.0f ) { - // test if we are really at rest - EvaluateContacts(); - if ( !TestIfAtRest() ) { - gameLocal.DWarning( "rigid body not at rest for entity '%s' type '%s' at (%s)", - self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); - } - Rest(); - dropToFloor = false; - } else if ( IsOutsideWorld() ) { - gameLocal.Warning( "rigid body outside world bounds for entity '%s' type '%s' at (%s)", - self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); - Rest(); - dropToFloor = false; - } -} - -/* -================ -idPhysics_RigidBody::DebugDraw -================ -*/ -void idPhysics_RigidBody::DebugDraw( void ) { - - if ( rb_showBodies.GetBool() || ( rb_showActive.GetBool() && current.atRest < 0 ) ) { - collisionModelManager->DrawModel( clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis(), vec3_origin, 0.0f ); - } - - if ( rb_showMass.GetBool() ) { -#ifdef MOD_WATERPHYSICS - if( this->water != NULL ) { - idVec3 pos; - float percent, liquidMass; - - pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; - percent = this->GetSubmergedPercent(pos,this->current.i.orientation.Transpose()); - - liquidMass = this->mass - ( this->volume * this->water->GetDensity() * percent ); - - gameRenderWorld->DrawText( va( "\n%1.2f", liquidMass), current.i.position, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - else -#endif - gameRenderWorld->DrawText( va( "\n%1.2f", mass ), current.i.position, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - - if ( rb_showInertia.GetBool() ) { - idMat3 &I = inertiaTensor; - gameRenderWorld->DrawText( va( "\n\n\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )", - I[0].x, I[0].y, I[0].z, - I[1].x, I[1].y, I[1].z, - I[2].x, I[2].y, I[2].z ), - current.i.position, 0.05f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 ); - } - - if ( rb_showVelocity.GetBool() ) { - DrawVelocity( clipModel->GetId(), 0.1f, 4.0f ); - } - -#ifdef MOD_WATERPHYSICS - if( rb_showBuoyancy.GetBool() && this->water != NULL ) { - idVec3 pos; - idVec3 bCenter; - float percent; - - pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; - this->GetBuoyancy(pos,this->current.i.orientation.Transpose(),bCenter,percent); - - gameRenderWorld->DebugArrow(colorGreen,pos,bCenter,1); - gameRenderWorld->DrawText( va( "%1.2f",percent), pos, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); - } -#endif -} - -/* -================ -idPhysics_RigidBody::idPhysics_RigidBody -================ -*/ -idPhysics_RigidBody::idPhysics_RigidBody( void ) { - - // set default rigid body properties - SetClipMask( MASK_SOLID ); - SetBouncyness( 0.6f ); - SetFriction( 0.6f, 0.6f, 0.0f ); - clipModel = NULL; - - memset( ¤t, 0, sizeof( current ) ); - - current.atRest = -1; - current.lastTimeStep = USERCMD_MSEC; - - current.i.position.Zero(); - current.i.orientation.Identity(); - - current.i.linearMomentum.Zero(); - current.i.angularMomentum.Zero(); - - saved = current; - - mass = 1.0f; - inverseMass = 1.0f; - centerOfMass.Zero(); - inertiaTensor.Identity(); - inverseInertiaTensor.Identity(); -#ifdef MOD_WATERPHYSICS - this->water = NULL; - this->m_fWaterMurkiness = 0.0f; -#endif - - // use the least expensive euler integrator - integrator = new idODE_Euler( sizeof(rigidBodyIState_t) / sizeof(float), RigidBodyDerivatives, this ); - - dropToFloor = false; - noImpact = false; - noContact = false; - - hasMaster = false; - isOrientated = false; - -#ifdef MOD_WATERPHYSICS - this->noMoveTime = 0; -#endif -#ifdef RB_TIMINGS - lastTimerReset = 0; -#endif - - isBlocked = false; - propagateImpulseLock = false; - - memset(&collisionTrace, 0, sizeof(collisionTrace)); - - // tels - maxForce.Zero(); - maxTorque.Zero(); -} - -/* -================ -idPhysics_RigidBody::~idPhysics_RigidBody -================ -*/ -idPhysics_RigidBody::~idPhysics_RigidBody( void ) { - if ( clipModel ) { - delete clipModel; - clipModel = NULL; - } - delete integrator; -} - -/* -================ -idPhysics_RigidBody_SavePState -================ -*/ -void idPhysics_RigidBody_SavePState( idSaveGame *savefile, const rigidBodyPState_t &state ) { - savefile->WriteInt( state.atRest ); - savefile->WriteFloat( state.lastTimeStep ); - savefile->WriteVec3( state.localOrigin ); - savefile->WriteMat3( state.localAxis ); - savefile->Write( &state.pushVelocity, sizeof( state.pushVelocity ) ); - savefile->WriteVec3( state.externalForce ); - savefile->WriteVec3( state.externalTorque ); - - savefile->WriteVec3( state.i.position ); - savefile->WriteMat3( state.i.orientation ); - savefile->WriteVec3( state.i.linearMomentum ); - savefile->WriteVec3( state.i.angularMomentum ); -} - -/* -================ -idPhysics_RigidBody_RestorePState -================ -*/ -void idPhysics_RigidBody_RestorePState( idRestoreGame *savefile, rigidBodyPState_t &state ) { - savefile->ReadInt( state.atRest ); - savefile->ReadFloat( state.lastTimeStep ); - savefile->ReadVec3( state.localOrigin ); - savefile->ReadMat3( state.localAxis ); - savefile->Read( &state.pushVelocity, sizeof( state.pushVelocity ) ); - savefile->ReadVec3( state.externalForce ); - savefile->ReadVec3( state.externalTorque ); - - savefile->ReadVec3( state.i.position ); - savefile->ReadMat3( state.i.orientation ); - savefile->ReadVec3( state.i.linearMomentum ); - savefile->ReadVec3( state.i.angularMomentum ); -} - -/* -================ -idPhysics_RigidBody::Save -================ -*/ -void idPhysics_RigidBody::Save( idSaveGame *savefile ) const { - - idPhysics_RigidBody_SavePState( savefile, current ); - idPhysics_RigidBody_SavePState( savefile, saved ); - - savefile->WriteFloat( linearFriction ); - savefile->WriteFloat( angularFriction ); - savefile->WriteFloat( contactFriction ); - savefile->WriteFloat( bouncyness ); - savefile->WriteClipModel( clipModel ); - - savefile->WriteFloat( mass ); -#ifdef MOD_WATERPHYSICS - savefile->WriteFloat( volume ); -#endif - savefile->WriteFloat( inverseMass ); - savefile->WriteVec3( centerOfMass ); - savefile->WriteMat3( inertiaTensor ); - savefile->WriteMat3( inverseInertiaTensor ); - - savefile->WriteBool( dropToFloor ); - savefile->WriteBool( testSolid ); - savefile->WriteBool( noImpact ); - savefile->WriteBool( noContact ); - - savefile->WriteBool( hasMaster ); - savefile->WriteBool( isOrientated ); - - savefile->WriteBool(isBlocked); - // greebo: Note this is not saved (yet). Uncomment this after release 1.00 - //savefile->WriteBool(propagateImpulseLock); - savefile->WriteTrace(collisionTrace); - - // tels - savefile->WriteVec3( maxForce ); - savefile->WriteVec3( maxTorque ); -} - -/* -================ -idPhysics_RigidBody::Restore -================ -*/ -void idPhysics_RigidBody::Restore( idRestoreGame *savefile ) { - - idPhysics_RigidBody_RestorePState( savefile, current ); - idPhysics_RigidBody_RestorePState( savefile, saved ); - - savefile->ReadFloat( linearFriction ); - savefile->ReadFloat( angularFriction ); - savefile->ReadFloat( contactFriction ); - savefile->ReadFloat( bouncyness ); - savefile->ReadClipModel( clipModel ); - - savefile->ReadFloat( mass ); -#ifdef MOD_WATERPHYSICS - savefile->ReadFloat( volume ); -#endif - savefile->ReadFloat( inverseMass ); - savefile->ReadVec3( centerOfMass ); - savefile->ReadMat3( inertiaTensor ); - savefile->ReadMat3( inverseInertiaTensor ); - - savefile->ReadBool( dropToFloor ); - savefile->ReadBool( testSolid ); - savefile->ReadBool( noImpact ); - savefile->ReadBool( noContact ); - - savefile->ReadBool( hasMaster ); - savefile->ReadBool( isOrientated ); - - savefile->ReadBool(isBlocked); - // greebo: Note this is not saved (yet). Uncomment this after release 1.00 - //savefile->ReadBool(propagateImpulseLock); - savefile->ReadTrace(collisionTrace); - - // tels - savefile->ReadVec3( maxForce ); - savefile->ReadVec3( maxTorque ); -} - -/* -================ -idPhysics_RigidBody::SetClipModel -================ -*/ -#define MAX_INERTIA_SCALE 10.0f - -void idPhysics_RigidBody::SetClipModel( idClipModel *model, const float density, int id, bool freeOld ) { - int minIndex; - idMat3 inertiaScale; - - assert( self ); - assert( model ); // we need a clip model - assert( model->IsTraceModel() ); // and it should be a trace model - assert( density > 0.0f ); // density should be valid - - if ( clipModel && clipModel != model && freeOld ) { - delete clipModel; - } - clipModel = model; - clipModel->Link( gameLocal.clip, self, 0, current.i.position, current.i.orientation ); - - // get mass properties from the trace model - clipModel->GetMassProperties( density, mass, centerOfMass, inertiaTensor ); - - // check whether or not the clip model has valid mass properties - if ( mass <= 0.0f || FLOAT_IS_NAN( mass ) ) { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING( "idPhysics_RigidBody::SetClipModel: invalid mass for entity '%s' type '%s'", - self->name.c_str(), self->GetType()->classname ); - mass = 1.0f; - centerOfMass.Zero(); - inertiaTensor.Identity(); - } - -#ifdef MOD_WATERPHYSICS - this->volume = mass / density; -#endif - - // check whether or not the inertia tensor is balanced - minIndex = Min3Index( inertiaTensor[0][0], inertiaTensor[1][1], inertiaTensor[2][2] ); - inertiaScale.Identity(); - inertiaScale[0][0] = inertiaTensor[0][0] / inertiaTensor[minIndex][minIndex]; - inertiaScale[1][1] = inertiaTensor[1][1] / inertiaTensor[minIndex][minIndex]; - inertiaScale[2][2] = inertiaTensor[2][2] / inertiaTensor[minIndex][minIndex]; - - if ( inertiaScale[0][0] > MAX_INERTIA_SCALE || inertiaScale[1][1] > MAX_INERTIA_SCALE || inertiaScale[2][2] > MAX_INERTIA_SCALE ) { - gameLocal.DWarning( "idPhysics_RigidBody::SetClipModel: unbalanced inertia tensor for entity '%s' type '%s'", - self->name.c_str(), self->GetType()->classname ); - float min = inertiaTensor[minIndex][minIndex] * MAX_INERTIA_SCALE; - inertiaScale[(minIndex+1)%3][(minIndex+1)%3] = min / inertiaTensor[(minIndex+1)%3][(minIndex+1)%3]; - inertiaScale[(minIndex+2)%3][(minIndex+2)%3] = min / inertiaTensor[(minIndex+2)%3][(minIndex+2)%3]; - inertiaTensor *= inertiaScale; - } - - inverseMass = 1.0f / mass; - inverseInertiaTensor = inertiaTensor.Inverse() * ( 1.0f / 6.0f ); - - current.i.linearMomentum.Zero(); - current.i.angularMomentum.Zero(); -} - -/* -================ -idPhysics_RigidBody::GetClipModel -================ -*/ -idClipModel *idPhysics_RigidBody::GetClipModel( int id ) const { - return clipModel; -} - -/* -================ -idPhysics_RigidBody::GetNumClipModels -================ -*/ -int idPhysics_RigidBody::GetNumClipModels( void ) const { - return 1; -} - -/* -================ -idPhysics_RigidBody::SetMass -================ -*/ -void idPhysics_RigidBody::SetMass( float mass, int id ) { - assert( mass > 0.0f ); - inertiaTensor *= mass / this->mass; - inverseInertiaTensor = inertiaTensor.Inverse() * (1.0f / 6.0f); - this->mass = mass; - inverseMass = 1.0f / mass; -} - -/* -================ -idPhysics_RigidBody::GetMass -================ -*/ -float idPhysics_RigidBody::GetMass( int id ) const { -#ifdef MOD_WATERPHYSICS - if( this->water != NULL ) { - idVec3 pos; - float percent,bMass; - - pos = this->current.i.position + this->centerOfMass*this->current.i.orientation; - percent = this->GetSubmergedPercent(pos,this->current.i.orientation); - bMass = mass - (this->volume * this->water->GetDensity() * percent); - - return bMass; - } - else -#endif - return mass; -} - -/* -================ -idPhysics_RigidBody::SetFriction -================ -*/ -void idPhysics_RigidBody::SetFriction( const float linear, const float angular, const float contact ) { - if ( linear < 0.0f || - angular < 0.0f || angular > 1.0f || - contact < 0.0f || contact > 1.0f ) { - return; - } - linearFriction = linear; - angularFriction = angular; - contactFriction = contact; -} - -/* -================ -idPhysics_RigidBody::SetBouncyness -================ -*/ -void idPhysics_RigidBody::SetBouncyness( const float b ) { - if ( b < 0.0f || b > 1.0f ) { - return; - } - bouncyness = b; -} - -/* -================ -idPhysics_RigidBody::Rest -================ -*/ -void idPhysics_RigidBody::Rest( void ) -{ - current.atRest = gameLocal.time; - current.i.linearMomentum.Zero(); - current.i.angularMomentum.Zero(); - self->BecomeInactive( TH_PHYSICS ); - - // grayman #2908 - if this is a mine, we can't NULL m_SetInMotionByActor - // because we need that if the mine ever kills someone - - if ( self->IsType(idProjectile::Type) ) - { - idProjectile* proj = static_cast(self); - if ( !proj->IsMine() ) - { - self->m_SetInMotionByActor = NULL; - } - } - -// self->m_SetInMotionByActor = NULL; - self->m_droppedByAI = false; // grayman #1330 -} - -/* -================ -idPhysics_RigidBody::DropToFloor -================ -*/ -void idPhysics_RigidBody::DropToFloor( void ) { - dropToFloor = true; - testSolid = true; -} - -/* -================ -idPhysics_RigidBody::NoContact -================ -*/ -void idPhysics_RigidBody::NoContact( void ) { - noContact = true; -} - -/* -================ -idPhysics_RigidBody::Activate -================ -*/ -void idPhysics_RigidBody::Activate( void ) { - current.atRest = -1; - self->BecomeActive( TH_PHYSICS ); -} - -/* -================ -idPhysics_RigidBody::PutToRest - - put to rest untill something collides with this physics object -================ -*/ -void idPhysics_RigidBody::PutToRest( void ) { - Rest(); -} - -/* -================ -idPhysics_RigidBody::EnableImpact -================ -*/ -void idPhysics_RigidBody::EnableImpact( void ) { - noImpact = false; -} - -/* -================ -idPhysics_RigidBody::DisableImpact -================ -*/ -void idPhysics_RigidBody::DisableImpact( void ) { - noImpact = true; -} - -/* -================ -idPhysics_RigidBody::SetContents -================ -*/ -void idPhysics_RigidBody::SetContents( int contents, int id ) { - assert(clipModel != NULL); - clipModel->SetContents( contents ); -} - -/* -================ -idPhysics_RigidBody::GetContents -================ -*/ -int idPhysics_RigidBody::GetContents( int id ) const { - assert(clipModel != NULL); - return clipModel->GetContents(); -} - -/* -================ -idPhysics_RigidBody::GetBounds -================ -*/ -const idBounds &idPhysics_RigidBody::GetBounds( int id ) const { - assert(clipModel != NULL); - return clipModel->GetBounds(); -} - -/* -================ -idPhysics_RigidBody::GetAbsBounds -================ -*/ -const idBounds &idPhysics_RigidBody::GetAbsBounds( int id ) const { - assert(clipModel != NULL); - return clipModel->GetAbsBounds(); -} - -const trace_t* idPhysics_RigidBody::GetBlockingInfo() const -{ - return isBlocked ? &collisionTrace : NULL; -} - -idEntity* idPhysics_RigidBody::GetBlockingEntity() const -{ - return isBlocked ? gameLocal.entities[collisionTrace.c.entityNum] : NULL; -} - -/* -================ -idPhysics_RigidBody::Evaluate - - Evaluate the impulse based rigid body physics. - When a collision occurs an impulse is applied at the moment of impact but - the remaining time after the collision is ignored. -================ -*/ -bool idPhysics_RigidBody::Evaluate( int timeStepMSec, int endTimeMSec ) { - rigidBodyPState_t next; - idAngles angles; - trace_t collision; - idVec3 impulse; - idEntity *ent(NULL); - idVec3 oldOrigin, masterOrigin; - idMat3 oldAxis, masterAxis; - float timeStep; - bool collided = false; - bool cameToRest = false; - - // greebo: For now, we aren't blocked - isBlocked = false; - - timeStep = MS2SEC( timeStepMSec ); - current.lastTimeStep = timeStep; - - if ( hasMaster ) { - oldOrigin = current.i.position; - oldAxis = current.i.orientation; - self->GetMasterPosition( masterOrigin, masterAxis ); - - current.i.position = masterOrigin + current.localOrigin * masterAxis; - current.i.orientation = (isOrientated) ? current.localAxis * masterAxis : current.localAxis; - - // greebo: Only check for collisions for "solid" bind slaves and if the master is non-AF - // Ishtvan: Do not block an AF attachment that is itself attached to an AF. - // This causes problems with AF evaluation. - // TODO: Use advanced AF binding code to add AF body for entity in this case, as if it were bound directly to AF - if ( - (clipModel->GetContents() & (CONTENTS_SOLID|CONTENTS_CORPSE)) - && !self->GetBindMaster()->IsType(idAnimatedEntity::Type) - && !( - self->GetBindMaster()->IsType(idAFAttachment::Type) - && static_cast(self->GetBindMaster())->GetBody() - ) - ) - { - // For non-AF masters we check for collisions - gameLocal.push.ClipPush( collisionTrace, self, PUSHFL_CLIP|PUSHFL_APPLYIMPULSE, oldOrigin, oldAxis, current.i.position, current.i.orientation ); - - if (collisionTrace.fraction < 1.0f ) - { - clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis ); - current.i.position = oldOrigin; - current.i.orientation = oldAxis; - isBlocked = true; - return false; - } - } - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); - current.i.linearMomentum = mass * ( ( current.i.position - oldOrigin ) / timeStep ); - current.i.angularMomentum = inertiaTensor * ( ( current.i.orientation * oldAxis.Transpose() ).ToAngularVelocity() / timeStep ); - current.externalForce.Zero(); - current.externalTorque.Zero(); - - return ( current.i.position != oldOrigin || current.i.orientation != oldAxis ); - } - - // if the body is at rest - if ( current.atRest >= 0 || timeStep <= 0.0f ) { - DebugDraw(); - return false; - } - - // if putting the body to rest - if (dropToFloor && !self->m_droppedByAI) // grayman #1330 - only go straight to the floor if an AI didn't drop it - { - DropToFloorAndRest(); - current.externalForce.Zero(); - current.externalTorque.Zero(); - return true; - } - -#ifdef RB_TIMINGS - timer_total.Start(); -#endif - - // move the rigid body velocity into the frame of a pusher -// current.i.linearMomentum -= current.pushVelocity.SubVec3( 0 ) * mass; -// current.i.angularMomentum -= current.pushVelocity.SubVec3( 1 ) * inertiaTensor; - - clipModel->Unlink(); - - next = current; - - // calculate next position and orientation - Integrate( timeStep, next ); - -#ifdef RB_TIMINGS - timer_collision.Start(); -#endif - - // check for collisions from the current to the next state - collided = CheckForCollisions( timeStep, next, collision ); - -#ifdef RB_TIMINGS - timer_collision.Stop(); -#endif - - // set the new state - current = next; - - if ( collided ) { - // apply collision impulse - if ( CollisionImpulse( collision, impulse ) ) { - current.atRest = gameLocal.time; - } - } - - // update the position of the clip model - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); - - DebugDraw(); - - if ( !noContact ) { - -#ifdef RB_TIMINGS - timer_collision.Start(); -#endif - // get contacts - EvaluateContacts(); - -#ifdef RB_TIMINGS - timer_collision.Stop(); -#endif - - // check if the body has come to rest - if ( current.externalForce.LengthSqr() == 0.0f && TestIfAtRest() ) { - // put to rest - Rest(); - cameToRest = true; - } else { - // apply contact friction - ContactFriction( timeStep ); - } - } - - if ( current.atRest < 0 ) { - ActivateContactEntities(); - } - - if ( collided ) { - // if the rigid body didn't come to rest or the other entity is not at rest - ent = gameLocal.entities[collision.c.entityNum]; - if ( ent && ( !cameToRest || !ent->IsAtRest() ) ) { - // apply impact to other entity - ent->ApplyImpulse( self, collision.c.id, collision.c.point, -impulse ); - - if (ent->m_SetInMotionByActor.GetEntity() == NULL) - { - ent->m_SetInMotionByActor = self->m_SetInMotionByActor; - ent->m_MovedByActor = self->m_MovedByActor; - } - } - - // greebo: Are we stuck? We still have to consider gravity and external forces - if (collision.fraction <= 0.001f) - { - // Get the mass center in world coordinates - idVec3 massCenter(current.i.position + centerOfMass * current.i.orientation); - - // Calculate the lever arms - idVec3 arm1(current.externalForcePoint - massCenter); - idVec3 arm2(current.externalForcePoint - collision.c.point); - idVec3 arm1N(arm1); - - //gameRenderWorld->DebugArrow(colorCyan, massCenter, massCenter + arm1, 1, 20); - //gameRenderWorld->DebugArrow(colorMagenta, collision.c.point, collision.c.point + arm2, 1, 20); - - float l1 = arm1N.NormalizeFast(); - float l2 = arm1N * arm2; - //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Arm 1: %f, Arm2: %f\r", l1, l2); - - if (arm2.LengthFast() > l1) - { - // Apply the linear momentum caused by the external force - current.i.linearMomentum -= current.externalForce*2; - current.i.angularMomentum += (current.externalForcePoint - collision.c.point).Cross(current.externalForce); - } - else if (fabs(l1) > 0.01f) - { - float armRatio = l2/l1; - float forceFactor = 4*armRatio*(armRatio - 1); - - forceFactor *= 15; - idVec3 leverForceLinear = current.externalForce * forceFactor; - - //DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("forceFactor: %f\r", forceFactor); - //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("Current impulse", current.i.linearMomentum); - //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("External Force", current.externalForce); - //DM_LOG(LC_ENTITY, LT_INFO)LOGVECTOR("External Force Modified", current.externalForce*forceFactor); - //gameRenderWorld->DebugArrow(colorMdGrey, massCenter, massCenter + leverForceLinear, 1, 20); - - // Apply the linear momentum caused by the lever force - current.i.linearMomentum += leverForceLinear; - current.i.angularMomentum += (current.externalForcePoint - collision.c.point).Cross(current.externalForce); - } - } - } - - // move the rigid body velocity back into the world frame -// current.i.linearMomentum += current.pushVelocity.SubVec3( 0 ) * mass; -// current.i.angularMomentum += current.pushVelocity.SubVec3( 1 ) * inertiaTensor; - current.pushVelocity.Zero(); - - current.lastTimeStep = timeStep; - current.externalForce.Zero(); - current.externalForcePoint.Zero(); - current.externalTorque.Zero(); - - if ( IsOutsideWorld() ) { - gameLocal.Warning( "rigid body moved outside world bounds for entity '%s' type '%s' at (%s)", - self->name.c_str(), self->GetType()->classname, current.i.position.ToString(0) ); - Rest(); - } - -#ifdef RB_TIMINGS - timer_total.Stop(); - - if ( rb_showTimings->integer == 1 ) { - gameLocal.Printf( "%12s: t %1.4f cd %1.4f\n", - self->name.c_str(), - timer_total.Milliseconds(), timer_collision.Milliseconds() ); - lastTimerReset = 0; - } - else if ( rb_showTimings->integer == 2 ) { - numRigidBodies++; - if ( endTimeMSec > lastTimerReset ) { - gameLocal.Printf( "rb %d: t %1.4f cd %1.4f\n", - numRigidBodies, - timer_total.Milliseconds(), timer_collision.Milliseconds() ); - } - } - if ( endTimeMSec > lastTimerReset ) { - lastTimerReset = endTimeMSec; - numRigidBodies = 0; - timer_total.Clear(); - timer_collision.Clear(); - } -#endif - - if (cv_phys_show_momentum.GetBool()) - { - gameRenderWorld->DrawText( idStr(current.i.linearMomentum.LengthFast()), GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - } - - return true; // grayman #2478 -} - -/* -================ -idPhysics_RigidBody::UpdateTime -================ -*/ -void idPhysics_RigidBody::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_RigidBody::GetTime -================ -*/ -int idPhysics_RigidBody::GetTime( void ) const { - return gameLocal.time; -} - -/* -================ -idPhysics_RigidBody::GetImpactInfo -================ -*/ -void idPhysics_RigidBody::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - idVec3 linearVelocity, angularVelocity; - idMat3 inverseWorldInertiaTensor; - - linearVelocity = inverseMass * current.i.linearMomentum; - inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; - angularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; - - info->invMass = inverseMass; - info->invInertiaTensor = inverseWorldInertiaTensor; - info->position = point - ( current.i.position + centerOfMass * current.i.orientation ); - info->velocity = linearVelocity + angularVelocity.Cross( info->position ); -} - -/* -================ -idPhysics_RigidBody::ApplyImpulse -================ -*/ -void idPhysics_RigidBody::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - if ( noImpact ) - { - return; - } - - // tels: check that the impulse does not exceed the max values - // FIXME: the comparisation here is just a dummy - if ((maxForce.x > 0) && - ((fabs(impulse.x) > maxForce.x) || - (fabs(impulse.y) > maxForce.y) || - (fabs(impulse.z) > maxForce.z)) ) - { - DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("impulse (%f %f %f) > maxForce (%f %f %f) for entity %s\r\r", - impulse.x, impulse.y, impulse.z, - maxForce.x, maxForce.y, maxForce.z, - self->name.c_str() - ); - // FIXME: self needs to be replaced by whatever entity generated the impulse - self->Killed( gameLocal.world, gameLocal.world, 0, self->GetLocalCoordinates(GetOrigin()), 0); - return; - } - - // greebo: Check if we have a master - if yes, propagate the impulse to it - if ( hasMaster ) - { - idEntity* master = self->GetBindMaster(); - - assert(master != NULL); // Bind master must not be null - - master->GetPhysics()->ApplyImpulse(id, point, impulse); - } - - current.i.linearMomentum += impulse; - current.i.angularMomentum += ( point - ( current.i.position + centerOfMass * current.i.orientation ) ).Cross( impulse ); - Activate(); -} - -/* -================ -idPhysics_RigidBody::AddForce -================ -*/ -void idPhysics_RigidBody::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { - if ( noImpact ) { - return; - } - current.externalForcePoint = point; - current.externalForce += force; - current.externalTorque += ( point - ( current.i.position + centerOfMass * current.i.orientation ) ).Cross( force ); - Activate(); -} - -/* -================ -idPhysics_RigidBody::IsAtRest -================ -*/ -bool idPhysics_RigidBody::IsAtRest( void ) const { - return current.atRest >= 0; -} - -/* -================ -idPhysics_RigidBody::GetRestStartTime -================ -*/ -int idPhysics_RigidBody::GetRestStartTime( void ) const { - return current.atRest; -} - -/* -================ -idPhysics_RigidBody::IsPushable -================ -*/ -bool idPhysics_RigidBody::IsPushable( void ) const { - return ( !noImpact && !hasMaster ); -} - -/* -================ -idPhysics_RigidBody::SaveState -================ -*/ -void idPhysics_RigidBody::SaveState( void ) { - saved = current; -} - -/* -================ -idPhysics_RigidBody::RestoreState -================ -*/ -void idPhysics_RigidBody::RestoreState( void ) { - current = saved; - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); - - EvaluateContacts(); -} - -/* -================ -idPhysics::SetOrigin -================ -*/ -void idPhysics_RigidBody::SetOrigin( const idVec3 &newOrigin, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localOrigin = newOrigin; - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.i.position = masterOrigin + newOrigin * masterAxis; - } - else { - current.i.position = newOrigin; - } - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, clipModel->GetAxis() ); - - Activate(); -} - -/* -================ -idPhysics::SetAxis -================ -*/ -void idPhysics_RigidBody::SetAxis( const idMat3 &newAxis, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localAxis = newAxis; - if ( hasMaster && isOrientated ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.i.orientation = newAxis * masterAxis; - } - else { - current.i.orientation = newAxis; - } - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), clipModel->GetOrigin(), current.i.orientation ); - - Activate(); -} - -/* -================ -idPhysics::Move -================ -*/ -void idPhysics_RigidBody::Translate( const idVec3 &translation, int id ) { - - current.localOrigin += translation; - current.i.position += translation; - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, clipModel->GetAxis() ); - - Activate(); -} - -/* -================ -idPhysics::Rotate -================ -*/ -void idPhysics_RigidBody::Rotate( const idRotation &rotation, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.i.orientation *= rotation.ToMat3(); - current.i.position *= rotation; - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localAxis *= rotation.ToMat3(); - current.localOrigin = ( current.i.position - masterOrigin ) * masterAxis.Transpose(); - } - else { - current.localAxis = current.i.orientation; - current.localOrigin = current.i.position; - } - - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); - - Activate(); -} - -/* -================ -idPhysics_RigidBody::GetOrigin -================ -*/ -const idVec3 &idPhysics_RigidBody::GetOrigin( int id ) const { - return current.i.position; -} - -/* -================ -idPhysics_RigidBody::GetAxis -================ -*/ -const idMat3 &idPhysics_RigidBody::GetAxis( int id ) const { - return current.i.orientation; -} - -/* -================ -idPhysics_RigidBody::SetLinearVelocity -================ -*/ -void idPhysics_RigidBody::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { - current.i.linearMomentum = newLinearVelocity * mass; - Activate(); -} - -/* -================ -idPhysics_RigidBody::SetAngularVelocity -================ -*/ -void idPhysics_RigidBody::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { - current.i.angularMomentum = newAngularVelocity * current.i.orientation.Transpose() * inertiaTensor * current.i.orientation; - Activate(); -} - -/* -================ -idPhysics_RigidBody::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_RigidBody::GetLinearVelocity( int id ) const { - static idVec3 curLinearVelocity; - curLinearVelocity = current.i.linearMomentum * inverseMass; - return curLinearVelocity; -} - -/* -================ -idPhysics_RigidBody::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_RigidBody::GetAngularVelocity( int id ) const { - static idVec3 curAngularVelocity; - idMat3 inverseWorldInertiaTensor; - - inverseWorldInertiaTensor = current.i.orientation.Transpose() * inverseInertiaTensor * current.i.orientation; - curAngularVelocity = inverseWorldInertiaTensor * current.i.angularMomentum; - return curAngularVelocity; -} - -/* -================ -idPhysics_RigidBody::SetMaxForce -================ -*/ -void idPhysics_RigidBody::SetMaxForce( const idVec3 &newMaxForce ) { - maxForce = newMaxForce; -} - -/* -================ -idPhysics_RigidBody::SetMaxTorque -================ -*/ -void idPhysics_RigidBody::SetMaxTorque( const idVec3 &newMaxTorque ) { - maxTorque = newMaxTorque; -} - -/* -================ -idPhysics_RigidBody::GetMaxForce -================ -*/ -const idVec3 &idPhysics_RigidBody::GetMaxForce( void ) const { - return maxForce; -} - -/* -================ -idPhysics_RigidBody::GetMaxTorque -================ -*/ -const idVec3 &idPhysics_RigidBody::GetMaxTorque( void ) const { - return maxTorque; -} - -/* -================ -idPhysics_RigidBody::ClipTranslation -================ -*/ -void idPhysics_RigidBody::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.TranslationModel( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, - clipModel, clipModel->GetAxis(), clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, - clipModel, clipModel->GetAxis(), clipMask, self ); - } -} - -/* -================ -idPhysics_RigidBody::ClipRotation -================ -*/ -void idPhysics_RigidBody::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.RotationModel( results, clipModel->GetOrigin(), rotation, - clipModel, clipModel->GetAxis(), clipMask, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, - clipModel, clipModel->GetAxis(), clipMask, self ); - } -} - -/* -================ -idPhysics_RigidBody::ClipContents -================ -*/ -int idPhysics_RigidBody::ClipContents( const idClipModel *model ) const { - if ( model ) { - return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } - else { - return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); - } -} - -/* -================ -idPhysics_RigidBody::DisableClip -================ -*/ -void idPhysics_RigidBody::DisableClip( void ) { - clipModel->Disable(); -} - -/* -================ -idPhysics_RigidBody::EnableClip -================ -*/ -void idPhysics_RigidBody::EnableClip( void ) { - clipModel->Enable(); -} - -/* -================ -idPhysics_RigidBody::UnlinkClip -================ -*/ -void idPhysics_RigidBody::UnlinkClip( void ) { - clipModel->Unlink(); -} - -/* -================ -idPhysics_RigidBody::LinkClip -================ -*/ -void idPhysics_RigidBody::LinkClip( void ) { - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); -} - -/* -================ -idPhysics_RigidBody::EvaluateContacts -================ -*/ -bool idPhysics_RigidBody::EvaluateContacts( void ) { - idVec6 dir; - int num; - - ClearContacts(); - - contacts.SetNum( 10, false ); - - dir.SubVec3(0) = current.i.linearMomentum + current.lastTimeStep * gravityVector * mass; - dir.SubVec3(1) = current.i.angularMomentum; - dir.SubVec3(0).Normalize(); - dir.SubVec3(1).Normalize(); - num = gameLocal.clip.Contacts( &contacts[0], 10, clipModel->GetOrigin(), - dir, CONTACT_EPSILON, clipModel, clipModel->GetAxis(), clipMask, self ); - contacts.SetNum( num, false ); - - AddContactEntitiesForContacts(); - - return ( contacts.Num() != 0 ); -} - -/* -================ -idPhysics_RigidBody::SetPushed -================ -*/ -void idPhysics_RigidBody::SetPushed( int deltaTime ) { - idRotation rotation; - - rotation = ( saved.i.orientation * current.i.orientation ).ToRotation(); - - // velocity with which the af is pushed - current.pushVelocity.SubVec3(0) += ( current.i.position - saved.i.position ) / ( deltaTime * idMath::M_MS2SEC ); - current.pushVelocity.SubVec3(1) += rotation.GetVec() * -DEG2RAD( rotation.GetAngle() ) / ( deltaTime * idMath::M_MS2SEC ); -} - -/* -================ -idPhysics_RigidBody::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_RigidBody::GetPushedLinearVelocity( const int id ) const { - return current.pushVelocity.SubVec3(0); -} - -/* -================ -idPhysics_RigidBody::GetPushedAngularVelocity -================ -*/ -const idVec3 &idPhysics_RigidBody::GetPushedAngularVelocity( const int id ) const { - return current.pushVelocity.SubVec3(1); -} - -/* -================ -idPhysics_RigidBody::SetMaster -================ -*/ -void idPhysics_RigidBody::SetMaster( idEntity *master, const bool orientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !hasMaster ) { - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.i.position - masterOrigin ) * masterAxis.Transpose(); - if ( orientated ) { - current.localAxis = current.i.orientation * masterAxis.Transpose(); - } - else { - current.localAxis = current.i.orientation; - } - hasMaster = true; - isOrientated = orientated; - ClearContacts(); - } - } - else { - if ( hasMaster ) { - hasMaster = false; - Activate(); - } - } -} - -/* -================ -idPhysics_RigidBody::WriteToSnapshot -================ -*/ -void idPhysics_RigidBody::WriteToSnapshot( idBitMsgDelta &msg ) const { - idCQuat quat, localQuat; - - quat = current.i.orientation.ToCQuat(); - localQuat = current.localAxis.ToCQuat(); - - msg.WriteLong( current.atRest ); - msg.WriteFloat( current.i.position[0] ); - msg.WriteFloat( current.i.position[1] ); - msg.WriteFloat( current.i.position[2] ); - msg.WriteFloat( quat.x ); - msg.WriteFloat( quat.y ); - msg.WriteFloat( quat.z ); - msg.WriteFloat( current.i.linearMomentum[0], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteFloat( current.i.linearMomentum[1], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteFloat( current.i.linearMomentum[2], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteFloat( current.i.angularMomentum[0], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteFloat( current.i.angularMomentum[1], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteFloat( current.i.angularMomentum[2], RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - msg.WriteDeltaFloat( current.i.position[0], current.localOrigin[0] ); - msg.WriteDeltaFloat( current.i.position[1], current.localOrigin[1] ); - msg.WriteDeltaFloat( current.i.position[2], current.localOrigin[2] ); - msg.WriteDeltaFloat( quat.x, localQuat.x ); - msg.WriteDeltaFloat( quat.y, localQuat.y ); - msg.WriteDeltaFloat( quat.z, localQuat.z ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalForce[0], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalForce[1], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalForce[2], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalTorque[0], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalTorque[1], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - msg.WriteDeltaFloat( 0.0f, current.externalTorque[2], RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); -} - -/* -================ -idPhysics_RigidBody::ReadFromSnapshot -================ -*/ -void idPhysics_RigidBody::ReadFromSnapshot( const idBitMsgDelta &msg ) { - idCQuat quat, localQuat; - - current.atRest = msg.ReadLong(); - current.i.position[0] = msg.ReadFloat(); - current.i.position[1] = msg.ReadFloat(); - current.i.position[2] = msg.ReadFloat(); - quat.x = msg.ReadFloat(); - quat.y = msg.ReadFloat(); - quat.z = msg.ReadFloat(); - current.i.linearMomentum[0] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.i.linearMomentum[1] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.i.linearMomentum[2] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.i.angularMomentum[0] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.i.angularMomentum[1] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.i.angularMomentum[2] = msg.ReadFloat( RB_MOMENTUM_EXPONENT_BITS, RB_MOMENTUM_MANTISSA_BITS ); - current.localOrigin[0] = msg.ReadDeltaFloat( current.i.position[0] ); - current.localOrigin[1] = msg.ReadDeltaFloat( current.i.position[1] ); - current.localOrigin[2] = msg.ReadDeltaFloat( current.i.position[2] ); - localQuat.x = msg.ReadDeltaFloat( quat.x ); - localQuat.y = msg.ReadDeltaFloat( quat.y ); - localQuat.z = msg.ReadDeltaFloat( quat.z ); - current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - current.externalForce[0] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - current.externalForce[1] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - current.externalForce[2] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - current.externalTorque[0] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - current.externalTorque[1] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - current.externalTorque[2] = msg.ReadDeltaFloat( 0.0f, RB_FORCE_EXPONENT_BITS, RB_FORCE_MANTISSA_BITS ); - - current.i.orientation = quat.ToMat3(); - current.localAxis = localQuat.ToMat3(); - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation ); - } -} diff --git a/game/physics/physics_rigidbody.h b/game/physics/physics_rigidbody.h deleted file mode 100644 index c0d694ba7..000000000 --- a/game/physics/physics_rigidbody.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_RIGIDBODY_H__ -#define __PHYSICS_RIGIDBODY_H__ - -/* -=================================================================================== - - Rigid body physics - - Employs an impulse based dynamic simulation which is not very accurate but - relatively fast and still reliable due to the continuous collision detection. - -=================================================================================== -*/ - -typedef struct rididBodyIState_s { - idVec3 position; // position of trace model - idMat3 orientation; // orientation of trace model - idVec3 linearMomentum; // translational momentum relative to center of mass - idVec3 angularMomentum; // rotational momentum relative to center of mass -} rigidBodyIState_t; - -typedef struct rigidBodyPState_s { - int atRest; // set when simulation is suspended - float lastTimeStep; // length of last time step - idVec3 localOrigin; // origin relative to master - idMat3 localAxis; // axis relative to master - idVec6 pushVelocity; // push velocity - idVec3 externalForce; // external force relative to center of mass - idVec3 externalTorque; // external torque relative to center of mass - idVec3 externalForcePoint; // point where the externalForce is being applied at - rigidBodyIState_t i; // state used for integration -} rigidBodyPState_t; - -class idPhysics_RigidBody : public idPhysics_Base { - -public: - - CLASS_PROTOTYPE( idPhysics_RigidBody ); - - idPhysics_RigidBody( void ); - ~idPhysics_RigidBody( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - // initialisation - void SetFriction( const float linear, const float angular, const float contact ); - void SetBouncyness( const float b ); - // same as above but drop to the floor first - void DropToFloor( void ); - // no contact determination and contact friction - void NoContact( void ); - // enable/disable activation by impact - void EnableImpact( void ); - void DisableImpact( void ); - -public: // common physics interface - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - - /** - * greebo: This is similar to ApplyImpulse, although this distributes the impulse - * on all entities in contact with this one in *this* very frame. If - * no entities are in contact, all the impulse gets applied to this one. - */ - bool PropagateImpulse(const int id, const idVec3& point, const idVec3& impulse); - - void AddForce( const int id, const idVec3 &point, const idVec3 &force ); - void Activate( void ); - void PutToRest( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - // tels: force and torque that make entitiy "break down" when exceeded - void SetMaxForce( const idVec3 &newMaxForce ); - void SetMaxTorque( const idVec3 &newMaxTorque ); - - const idVec3 & GetMaxForce( void ) const; - const idVec3 & GetMaxTorque( void ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - /** - * greebo: Override empty default implementation of idPhysics_Base::GetBlockingEntity(). - */ - virtual const trace_t* GetBlockingInfo( void ) const; - virtual idEntity * GetBlockingEntity( void ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated ); - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -public: - /** - * greebo: "Accessor" method to the internal state. This is a bit hacky, I admit. - */ - rigidBodyPState_t& State() { return current; } - -private: - // state of the rigid body - rigidBodyPState_t current; - rigidBodyPState_t saved; - - // rigid body properties - float linearFriction; // translational friction - float angularFriction; // rotational friction - float contactFriction; // friction with contact surfaces - float bouncyness; // bouncyness -#ifdef MOD_WATERPHYSICS - float volume; // MOD_WATERPHYSICS object volume -#endif // MOD_WATERPHYSICS - idClipModel * clipModel; // clip model used for collision detection - - // tels: if the applied impulse/torque exceeds these values, the entity breaks down - idVec3 maxForce; // spawnarg "max_force" - idVec3 maxTorque; // spawnarg "max_torque" - - // derived properties - float mass; // mass of body - float inverseMass; // 1 / mass - idVec3 centerOfMass; // center of mass of trace model - idMat3 inertiaTensor; // mass distribution - idMat3 inverseInertiaTensor; // inverse inertia tensor - - idODE * integrator; // integrator - bool dropToFloor; // true if dropping to the floor and putting to rest - bool testSolid; // true if testing for solid when dropping to the floor - bool noImpact; // if true do not activate when another object collides - bool noContact; // if true do not determine contacts and no contact friction - - // master - bool hasMaster; - bool isOrientated; - - /** - * greebo: This saved the collision information when this object is in "bind slave mode". - */ - trace_t collisionTrace; - bool isBlocked; - - bool propagateImpulseLock; - -#ifdef MOD_WATERPHYSICS - // buoyancy - int noMoveTime; // MOD_WATERPHYSICS suspend simulation if hardly any movement for this many seconds -#endif - -private: - friend void RigidBodyDerivatives( const float t, const void *clientData, const float *state, float *derivatives ); - void Integrate( const float deltaTime, rigidBodyPState_t &next ); - bool CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision ); -public: - bool CollisionImpulse( const trace_t &collision, idVec3 &impulse ); -private: - void ContactFriction( float deltaTime ); - void DropToFloorAndRest( void ); -#ifdef MOD_WATERPHYSICS - bool TestIfAtRest( void ); -#else // MOD_WATERPHYSICS - bool TestIfAtRest( void ) const; -#endif // MOD_WATERPHYSICS - void Rest( void ); - void DebugDraw( void ); - -#ifdef MOD_WATERPHYSICS - // Buoyancy stuff - // Approximates the center of mass of the submerged portion of the rigid body. - virtual bool GetBuoyancy( const idVec3 &pos, const idMat3 &rotation, idVec3 &bCenter, float &percent ) const; // MOD_WATERPHYSICS - // Returns rough a percentage of which percent of the body is in water. - virtual float GetSubmergedPercent( const idVec3 &pos, const idMat3 &rotation ) const; // MOD_WATERPHYSICS -#endif -}; - -#endif /* !__PHYSICS_RIGIDBODY_H__ */ diff --git a/game/physics/physics_static.cpp b/game/physics/physics_static.cpp deleted file mode 100644 index 76508257e..000000000 --- a/game/physics/physics_static.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics, idPhysics_Static ) -END_CLASS - -/* -================ -idPhysics_Static::idPhysics_Static -================ -*/ -idPhysics_Static::idPhysics_Static( void ) { - self = NULL; - clipModel = NULL; - current.origin.Zero(); - current.axis.Identity(); - current.localOrigin.Zero(); - current.localAxis.Identity(); - hasMaster = false; - isOrientated = false; -} - -/* -================ -idPhysics_Static::~idPhysics_Static -================ -*/ -idPhysics_Static::~idPhysics_Static( void ) { - if ( self && self->GetPhysics() == this ) { - self->SetPhysics( NULL ); - } - idForce::DeletePhysics( this ); - if ( clipModel ) { - delete clipModel; - } -} - -/* -================ -idPhysics_Static::Save -================ -*/ -void idPhysics_Static::Save( idSaveGame *savefile ) const { - savefile->WriteObject( self ); - - savefile->WriteVec3( current.origin ); - savefile->WriteMat3( current.axis ); - savefile->WriteVec3( current.localOrigin ); - savefile->WriteMat3( current.localAxis ); - savefile->WriteClipModel( clipModel ); - - savefile->WriteBool( hasMaster ); - savefile->WriteBool( isOrientated ); -} - -/* -================ -idPhysics_Static::Restore -================ -*/ -void idPhysics_Static::Restore( idRestoreGame *savefile ) { - savefile->ReadObject( reinterpret_cast( self ) ); - - savefile->ReadVec3( current.origin ); - savefile->ReadMat3( current.axis ); - savefile->ReadVec3( current.localOrigin ); - savefile->ReadMat3( current.localAxis ); - savefile->ReadClipModel( clipModel ); - - savefile->ReadBool( hasMaster ); - savefile->ReadBool( isOrientated ); -} - -/* -================ -idPhysics_Static::SetSelf -================ -*/ -void idPhysics_Static::SetSelf( idEntity *e ) { - assert( e ); - self = e; -} - -/* -================ -idPhysics_Static::SetClipModel -================ -*/ -void idPhysics_Static::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { - assert( self ); - - if ( clipModel && clipModel != model && freeOld ) { - delete clipModel; - } - clipModel = model; - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::GetClipModel -================ -*/ -idClipModel *idPhysics_Static::GetClipModel( int id ) const { - if ( clipModel ) { - return clipModel; - } - return gameLocal.clip.DefaultClipModel(); -} - -/* -================ -idPhysics_Static::GetNumClipModels -================ -*/ -int idPhysics_Static::GetNumClipModels( void ) const { - return ( clipModel != NULL ); -} - -/* -================ -idPhysics_Static::SetMass -================ -*/ -void idPhysics_Static::SetMass( float mass, int id ) { -} - -/* -================ -idPhysics_Static::GetMass -================ -*/ -float idPhysics_Static::GetMass( int id ) const { - return 0.0f; -} - -/* -================ -idPhysics_Static::SetContents -================ -*/ -void idPhysics_Static::SetContents( int contents, int id ) { - if ( clipModel ) { - clipModel->SetContents( contents ); - } -} - -/* -================ -idPhysics_Static::GetContents -================ -*/ -int idPhysics_Static::GetContents( int id ) const { - if ( clipModel ) { - return clipModel->GetContents(); - } - return 0; -} - -/* -================ -idPhysics_Static::SetClipMask -================ -*/ -void idPhysics_Static::SetClipMask( int mask, int id ) { -} - -/* -================ -idPhysics_Static::GetClipMask -================ -*/ -int idPhysics_Static::GetClipMask( int id ) const { - return 0; -} - -/* -================ -idPhysics_Static::GetBounds -================ -*/ -const idBounds &idPhysics_Static::GetBounds( int id ) const { - if ( clipModel ) { - return clipModel->GetBounds(); - } - return bounds_zero; -} - -/* -================ -idPhysics_Static::GetAbsBounds -================ -*/ -const idBounds &idPhysics_Static::GetAbsBounds( int id ) const { - static idBounds absBounds; - - if ( clipModel ) { - return clipModel->GetAbsBounds(); - } - absBounds[0] = absBounds[1] = current.origin; - return absBounds; -} - -/* -================ -idPhysics_Static::Evaluate -================ -*/ -bool idPhysics_Static::Evaluate( int timeStepMSec, int endTimeMSec ) { - idVec3 masterOrigin, oldOrigin; - idMat3 masterAxis, oldAxis; - - - if ( hasMaster ) { - oldOrigin = current.origin; - oldAxis = current.axis; - - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + current.localOrigin * masterAxis; - if ( isOrientated ) { - current.axis = current.localAxis * masterAxis; - } else { - current.axis = current.localAxis; - } - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } - - return ( current.origin != oldOrigin || current.axis != oldAxis ); - } - return false; -} - -/* -================ -idPhysics_Static::UpdateTime -================ -*/ -void idPhysics_Static::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_Static::GetTime -================ -*/ -int idPhysics_Static::GetTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Static::GetImpactInfo -================ -*/ -void idPhysics_Static::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - memset( info, 0, sizeof( *info ) ); -} - -/* -================ -idPhysics_Static::ApplyImpulse -================ -*/ -void idPhysics_Static::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { -} - -bool idPhysics_Static::PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - return false; -} - -/* -================ -idPhysics_Static::AddForce -================ -*/ -void idPhysics_Static::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { -} - -/* -================ -idPhysics_Static::Activate -================ -*/ -void idPhysics_Static::Activate( void ) { -} - -/* -================ -idPhysics_Static::PutToRest -================ -*/ -void idPhysics_Static::PutToRest( void ) { -} - -/* -================ -idPhysics_Static::IsAtRest -================ -*/ -bool idPhysics_Static::IsAtRest( void ) const { - return true; -} - -/* -================ -idPhysics_Static::GetRestStartTime -================ -*/ -int idPhysics_Static::GetRestStartTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Static::IsPushable -================ -*/ -bool idPhysics_Static::IsPushable( void ) const { - return false; -} - -/* -================ -idPhysics_Static::SaveState -================ -*/ -void idPhysics_Static::SaveState( void ) { -} - -/* -================ -idPhysics_Static::RestoreState -================ -*/ -void idPhysics_Static::RestoreState( void ) { -} - -/* -================ -idPhysics_Static::SetOrigin -================ -*/ -void idPhysics_Static::SetOrigin( const idVec3 &newOrigin, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localOrigin = newOrigin; - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.origin = masterOrigin + newOrigin * masterAxis; - } else { - current.origin = newOrigin; - } - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::SetAxis -================ -*/ -void idPhysics_Static::SetAxis( const idMat3 &newAxis, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.localAxis = newAxis; - - if ( hasMaster && isOrientated ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.axis = newAxis * masterAxis; - } else { - current.axis = newAxis; - } - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::Translate -================ -*/ -void idPhysics_Static::Translate( const idVec3 &translation, int id ) { - current.localOrigin += translation; - current.origin += translation; - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::Rotate -================ -*/ -void idPhysics_Static::Rotate( const idRotation &rotation, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - current.origin *= rotation; - current.axis *= rotation.ToMat3(); - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localAxis *= rotation.ToMat3(); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - } else { - current.localAxis = current.axis; - current.localOrigin = current.origin; - } - - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::GetOrigin -================ -*/ -const idVec3 &idPhysics_Static::GetOrigin( int id ) const { - return current.origin; -} - -/* -================ -idPhysics_Static::GetAxis -================ -*/ -const idMat3 &idPhysics_Static::GetAxis( int id ) const { - return current.axis; -} - -/* -================ -idPhysics_Static::SetLinearVelocity -================ -*/ -void idPhysics_Static::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { -} - -/* -================ -idPhysics_Static::SetAngularVelocity -================ -*/ -void idPhysics_Static::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { -} - -/* -================ -idPhysics_Static::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_Static::GetLinearVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Static::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_Static::GetAngularVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Static::SetGravity -================ -*/ -void idPhysics_Static::SetGravity( const idVec3 &newGravity ) { -} - -/* -================ -idPhysics_Static::GetGravity -================ -*/ -const idVec3 &idPhysics_Static::GetGravity( void ) const { - static idVec3 gravity( 0, 0, -g_gravity.GetFloat() ); - return gravity; -} - -/* -================ -idPhysics_Static::GetGravityNormal -================ -*/ -const idVec3 &idPhysics_Static::GetGravityNormal( void ) const { - static idVec3 gravity( 0, 0, -1 ); - return gravity; -} - -/* -================ -idPhysics_Static::ClipTranslation -================ -*/ -void idPhysics_Static::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.TranslationModel( results, current.origin, current.origin + translation, - clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() ); - } else { - gameLocal.clip.Translation( results, current.origin, current.origin + translation, - clipModel, current.axis, MASK_SOLID, self ); - } -} - -/* -================ -idPhysics_Static::ClipRotation -================ -*/ -void idPhysics_Static::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - if ( model ) { - gameLocal.clip.RotationModel( results, current.origin, rotation, - clipModel, current.axis, MASK_SOLID, model->Handle(), model->GetOrigin(), model->GetAxis() ); - } else { - gameLocal.clip.Rotation( results, current.origin, rotation, clipModel, current.axis, MASK_SOLID, self ); - } -} - -/* -================ -idPhysics_Static::ClipContents -================ -*/ -int idPhysics_Static::ClipContents( const idClipModel *model ) const { - if ( clipModel ) { - if ( model ) { - return gameLocal.clip.ContentsModel( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } else { - return gameLocal.clip.Contents( clipModel->GetOrigin(), clipModel, clipModel->GetAxis(), -1, NULL ); - } - } - return 0; -} - -/* -================ -idPhysics_Static::DisableClip -================ -*/ -void idPhysics_Static::DisableClip( void ) { - if ( clipModel ) { - clipModel->Disable(); - } -} - -/* -================ -idPhysics_Static::EnableClip -================ -*/ -void idPhysics_Static::EnableClip( void ) { - if ( clipModel ) { - clipModel->Enable(); - } -} - -/* -================ -idPhysics_Static::UnlinkClip -================ -*/ -void idPhysics_Static::UnlinkClip( void ) { - if ( clipModel ) { - clipModel->Unlink(); - } -} - -/* -================ -idPhysics_Static::LinkClip -================ -*/ -void idPhysics_Static::LinkClip( void ) { - if ( clipModel ) { - clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis ); - } -} - -/* -================ -idPhysics_Static::EvaluateContacts -================ -*/ -bool idPhysics_Static::EvaluateContacts( void ) { - return false; -} - -/* -================ -idPhysics_Static::GetNumContacts -================ -*/ -int idPhysics_Static::GetNumContacts( void ) const { - return 0; -} - -bool idPhysics_Static::HasNonStaticContacts() { - return false; -} - -/* -================ -idPhysics_Static::GetContact -================ -*/ -const contactInfo_t &idPhysics_Static::GetContact( int num ) const { - static contactInfo_t info; - memset( &info, 0, sizeof( info ) ); - return info; -} - -/* -================ -idPhysics_Static::ClearContacts -================ -*/ -void idPhysics_Static::ClearContacts( void ) { -} - -/* -================ -idPhysics_Static::AddContactEntity -================ -*/ -void idPhysics_Static::AddContactEntity( idEntity *e ) { -} - -/* -================ -idPhysics_Static::RemoveContactEntity -================ -*/ -void idPhysics_Static::RemoveContactEntity( idEntity *e ) { -} - -/* -================ -idPhysics_Static::HasGroundContacts -================ -*/ -bool idPhysics_Static::HasGroundContacts( void ) const { - return false; -} - -/* -================ -idPhysics_Static::IsGroundEntity -================ -*/ -bool idPhysics_Static::IsGroundEntity( int entityNum ) const { - return false; -} - -/* -================ -idPhysics_Static::IsGroundClipModel -================ -*/ -bool idPhysics_Static::IsGroundClipModel( int entityNum, int id ) const { - return false; -} - -/* -================ -idPhysics_Static::SetPushed -================ -*/ -void idPhysics_Static::SetPushed( int deltaTime ) { -} - -/* -================ -idPhysics_Static::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_Static::GetPushedLinearVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Static::GetPushedAngularVelocity -================ -*/ -const idVec3 &idPhysics_Static::GetPushedAngularVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_Static::SetMaster -================ -*/ -void idPhysics_Static::SetMaster( idEntity *master, const bool orientated ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !hasMaster ) { - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose(); - if ( orientated ) { - current.localAxis = current.axis * masterAxis.Transpose(); - } else { - current.localAxis = current.axis; - } - hasMaster = true; - isOrientated = orientated; - } - } else { - if ( hasMaster ) { - hasMaster = false; - } - } -} - -/* -================ -idPhysics_Static::GetBlockingInfo -================ -*/ -const trace_t *idPhysics_Static::GetBlockingInfo( void ) const { - return NULL; -} - -/* -================ -idPhysics_Static::GetBlockingEntity -================ -*/ -idEntity *idPhysics_Static::GetBlockingEntity( void ) const { - return NULL; -} - -/* -================ -idPhysics_Static::GetLinearEndTime -================ -*/ -int idPhysics_Static::GetLinearEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Static::GetAngularEndTime -================ -*/ -int idPhysics_Static::GetAngularEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_Static::WriteToSnapshot -================ -*/ -void idPhysics_Static::WriteToSnapshot( idBitMsgDelta &msg ) const { - idCQuat quat, localQuat; - - quat = current.axis.ToCQuat(); - localQuat = current.localAxis.ToCQuat(); - - msg.WriteFloat( current.origin[0] ); - msg.WriteFloat( current.origin[1] ); - msg.WriteFloat( current.origin[2] ); - msg.WriteFloat( quat.x ); - msg.WriteFloat( quat.y ); - msg.WriteFloat( quat.z ); - msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] ); - msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] ); - msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] ); - msg.WriteDeltaFloat( quat.x, localQuat.x ); - msg.WriteDeltaFloat( quat.y, localQuat.y ); - msg.WriteDeltaFloat( quat.z, localQuat.z ); -} - -/* -================ -idPhysics_Base::ReadFromSnapshot -================ -*/ -void idPhysics_Static::ReadFromSnapshot( const idBitMsgDelta &msg ) { - idCQuat quat, localQuat; - - current.origin[0] = msg.ReadFloat(); - current.origin[1] = msg.ReadFloat(); - current.origin[2] = msg.ReadFloat(); - quat.x = msg.ReadFloat(); - quat.y = msg.ReadFloat(); - quat.z = msg.ReadFloat(); - current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); - current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); - current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); - localQuat.x = msg.ReadDeltaFloat( quat.x ); - localQuat.y = msg.ReadDeltaFloat( quat.y ); - localQuat.z = msg.ReadDeltaFloat( quat.z ); - - current.axis = quat.ToMat3(); - current.localAxis = localQuat.ToMat3(); -} diff --git a/game/physics/physics_static.h b/game/physics/physics_static.h deleted file mode 100644 index 3edeabc52..000000000 --- a/game/physics/physics_static.h +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_STATIC_H__ -#define __PHYSICS_STATIC_H__ - -/* -=============================================================================== - - Physics for a non moving object using at most one collision model. - -=============================================================================== -*/ - -typedef struct staticPState_s { - idVec3 origin; - idMat3 axis; - idVec3 localOrigin; - idMat3 localAxis; -} staticPState_t; - -class idPhysics_Static : public idPhysics { - -public: - CLASS_PROTOTYPE( idPhysics_Static ); - - idPhysics_Static( void ); - ~idPhysics_Static( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -public: // common physics interface - void SetSelf( idEntity *e ); - idEntity * GetSelf( void ) { return self; } // Get the original entity - Dram - - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - void SetClipMask( int mask, int id = -1 ); - int GetClipMask( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - bool PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - void AddForce( const int id, const idVec3 &point, const idVec3 &force ); - void Activate( void ); - void PutToRest( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - void SetGravity( const idVec3 &newGravity ); - const idVec3 & GetGravity( void ) const; - const idVec3 & GetGravityNormal( void ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - int GetNumContacts( void ) const; - bool HasNonStaticContacts(); - const contactInfo_t & GetContact( int num ) const; - void ClearContacts( void ); - void AddContactEntity( idEntity *e ); - void RemoveContactEntity( idEntity *e ); - - bool HasGroundContacts( void ) const; - bool IsGroundEntity( int entityNum ) const; - bool IsGroundClipModel( int entityNum, int id ) const; - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated = true ); - - const trace_t * GetBlockingInfo( void ) const; - idEntity * GetBlockingEntity( void ) const; - - int GetLinearEndTime( void ) const; - int GetAngularEndTime( void ) const; - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -#ifdef MOD_WATERPHYSICS - // gets/sets the water - // just some functions to avoid making this class abstract. Water has no effect on a static object - // so it sort of makes sense these functions do nothing. - virtual idPhysics_Liquid *GetWater() { return NULL; } // MOD_WATERPHYSICS - virtual void SetWater( idPhysics_Liquid *e, const float murkiness ) {} // MOD_WATERPHYSICS -#endif -protected: - idEntity * self; // entity using this physics object - staticPState_t current; // physics state - idClipModel * clipModel; // collision model - - // master - bool hasMaster; - bool isOrientated; -}; - -#endif /* !__PHYSICS_STATIC_H__ */ diff --git a/game/physics/physics_staticmulti.cpp b/game/physics/physics_staticmulti.cpp deleted file mode 100644 index 4a786f9c7..000000000 --- a/game/physics/physics_staticmulti.cpp +++ /dev/null @@ -1,1067 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -CLASS_DECLARATION( idPhysics, idPhysics_StaticMulti ) -END_CLASS - -staticPState_t defaultState; - - -/* -================ -idPhysics_StaticMulti::idPhysics_StaticMulti -================ -*/ -idPhysics_StaticMulti::idPhysics_StaticMulti( void ) { - self = NULL; - hasMaster = false; - isOrientated = false; - - defaultState.origin.Zero(); - defaultState.axis.Identity(); - defaultState.localOrigin.Zero(); - defaultState.localAxis.Identity(); - - current.SetNum( 1 ); - current[0] = defaultState; - clipModels.SetNum( 1 ); - clipModels[0] = NULL; -} - -/* -================ -idPhysics_StaticMulti::~idPhysics_StaticMulti -================ -*/ -idPhysics_StaticMulti::~idPhysics_StaticMulti( void ) { - if ( self && self->GetPhysics() == this ) { - self->SetPhysics( NULL ); - } - idForce::DeletePhysics( this ); - for ( int i = 0; i < clipModels.Num(); i++ ) { - delete clipModels[i]; - } -} - -/* -================ -idPhysics_StaticMulti::Save -================ -*/ -void idPhysics_StaticMulti::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteObject( self ); - - savefile->WriteInt(current.Num()); - for ( i = 0; i < current.Num(); i++ ) { - savefile->WriteVec3( current[i].origin ); - savefile->WriteMat3( current[i].axis ); - savefile->WriteVec3( current[i].localOrigin ); - savefile->WriteMat3( current[i].localAxis ); - } - - savefile->WriteInt( clipModels.Num() ); - for ( i = 0; i < clipModels.Num(); i++ ) { - savefile->WriteClipModel( clipModels[i] ); - } - - savefile->WriteBool(hasMaster); - savefile->WriteBool(isOrientated); -} - -/* -================ -idPhysics_StaticMulti::Restore -================ -*/ -void idPhysics_StaticMulti::Restore( idRestoreGame *savefile ) { - int i, num; - - savefile->ReadObject( reinterpret_cast( self ) ); - - savefile->ReadInt(num); - current.AssureSize( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadVec3( current[i].origin ); - savefile->ReadMat3( current[i].axis ); - savefile->ReadVec3( current[i].localOrigin ); - savefile->ReadMat3( current[i].localAxis ); - } - - savefile->ReadInt(num); - clipModels.SetNum( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadClipModel( clipModels[i] ); - } - - savefile->ReadBool(hasMaster); - savefile->ReadBool(isOrientated); -} - -/* -================ -idPhysics_StaticMulti::SetSelf -================ -*/ -void idPhysics_StaticMulti::SetSelf( idEntity *e ) { - assert( e ); - self = e; -} - -/* -================ -idPhysics_StaticMulti::RemoveIndex -================ -*/ -void idPhysics_StaticMulti::RemoveIndex( int id, bool freeClipModel ) { - if ( id < 0 || id >= clipModels.Num() ) { - return; - } - if ( clipModels[id] && freeClipModel ) { - delete clipModels[id]; - clipModels[id] = NULL; - } - clipModels.RemoveIndex( id ); - current.RemoveIndex( id ); -} - -/* -================ -idPhysics_StaticMulti::SetClipModel -================ -*/ -void idPhysics_StaticMulti::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) { - int i; - - assert( self ); - - if ( id >= clipModels.Num() ) { - current.AssureSize( id+1, defaultState ); - clipModels.AssureSize( id+1, NULL ); - } - - if ( clipModels[id] && clipModels[id] != model && freeOld ) { - delete clipModels[id]; - } - clipModels[id] = model; - if ( clipModels[id] ) { - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - - for ( i = clipModels.Num() - 1; i >= 1; i-- ) { - if ( clipModels[i] ) { - break; - } - } - current.SetNum( i+1, false ); - clipModels.SetNum( i+1, false ); -} - -/* -================ -idPhysics_StaticMulti::GetClipModel -================ -*/ -idClipModel *idPhysics_StaticMulti::GetClipModel( int id ) const { - if ( id >= 0 && id < clipModels.Num() && clipModels[id] ) { - return clipModels[id]; - } - return gameLocal.clip.DefaultClipModel(); -} - -/* -================ -idPhysics_StaticMulti::GetNumClipModels -================ -*/ -int idPhysics_StaticMulti::GetNumClipModels( void ) const { - return clipModels.Num(); -} - -/* -================ -idPhysics_StaticMulti::SetMass -================ -*/ -void idPhysics_StaticMulti::SetMass( float mass, int id ) { -} - -/* -================ -idPhysics_StaticMulti::GetMass -================ -*/ -float idPhysics_StaticMulti::GetMass( int id ) const { - return 0.0f; -} - -/* -================ -idPhysics_StaticMulti::SetContents -================ -*/ -void idPhysics_StaticMulti::SetContents( int contents, int id ) { - int i; - - if ( id >= 0 && id < clipModels.Num() ) { - if ( clipModels[id] ) { - clipModels[id]->SetContents( contents ); - } - } else if ( id == -1 ) { - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->SetContents( contents ); - } - } - } -} - -/* -================ -idPhysics_StaticMulti::GetContents -================ -*/ -int idPhysics_StaticMulti::GetContents( int id ) const { - int i, contents = 0; - - if ( id >= 0 && id < clipModels.Num() ) { - if ( clipModels[id] ) { - contents = clipModels[id]->GetContents(); - } - } else if ( id == -1 ) { - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - contents |= clipModels[i]->GetContents(); - } - } - } - return contents; -} - -/* -================ -idPhysics_StaticMulti::SetClipMask -================ -*/ -void idPhysics_StaticMulti::SetClipMask( int mask, int id ) { -} - -/* -================ -idPhysics_StaticMulti::GetClipMask -================ -*/ -int idPhysics_StaticMulti::GetClipMask( int id ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::GetBounds -================ -*/ -const idBounds &idPhysics_StaticMulti::GetBounds( int id ) const { - int i; - static idBounds bounds; - - if ( id >= 0 && id < clipModels.Num() ) { - if ( clipModels[id] ) { - return clipModels[id]->GetBounds(); - } - } - if ( id == -1 ) { - bounds.Clear(); - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - bounds.AddBounds( clipModels[i]->GetAbsBounds() ); - } - } - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - bounds[0] -= clipModels[i]->GetOrigin(); - bounds[1] -= clipModels[i]->GetOrigin(); - break; - } - } - return bounds; - } - return bounds_zero; -} - -/* -================ -idPhysics_StaticMulti::GetAbsBounds -================ -*/ -const idBounds &idPhysics_StaticMulti::GetAbsBounds( int id ) const { - int i; - static idBounds absBounds; - - if ( id >= 0 && id < clipModels.Num() ) { - if ( clipModels[id] ) { - return clipModels[id]->GetAbsBounds(); - } - } - if ( id == -1 ) { - absBounds.Clear(); - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - absBounds.AddBounds( clipModels[i]->GetAbsBounds() ); - } - } - return absBounds; - } - return bounds_zero; -} - -/* -================ -idPhysics_StaticMulti::Evaluate -================ -*/ -bool idPhysics_StaticMulti::Evaluate( int timeStepMSec, int endTimeMSec ) { - int i; - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - for ( i = 0; i < clipModels.Num(); i++ ) { - current[i].origin = masterOrigin + current[i].localOrigin * masterAxis; - if ( isOrientated ) { - current[i].axis = current[i].localAxis * masterAxis; - } else { - current[i].axis = current[i].localAxis; - } - if ( clipModels[i] ) { - clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); - } - } - - // FIXME: return false if master did not move - return true; - } - return false; -} - -/* -================ -idPhysics_StaticMulti::UpdateTime -================ -*/ -void idPhysics_StaticMulti::UpdateTime( int endTimeMSec ) { -} - -/* -================ -idPhysics_StaticMulti::GetTime -================ -*/ -int idPhysics_StaticMulti::GetTime( void ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::GetImpactInfo -================ -*/ -void idPhysics_StaticMulti::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const { - memset( info, 0, sizeof( *info ) ); -} - -/* -================ -idPhysics_StaticMulti::ApplyImpulse -================ -*/ -void idPhysics_StaticMulti::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { -} - -bool idPhysics_StaticMulti::PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) { - return false; -} - -/* -================ -idPhysics_StaticMulti::AddForce -================ -*/ -void idPhysics_StaticMulti::AddForce( const int id, const idVec3 &point, const idVec3 &force ) { -} - -/* -================ -idPhysics_StaticMulti::Activate -================ -*/ -void idPhysics_StaticMulti::Activate( void ) { -} - -/* -================ -idPhysics_StaticMulti::PutToRest -================ -*/ -void idPhysics_StaticMulti::PutToRest( void ) { -} - -/* -================ -idPhysics_StaticMulti::IsAtRest -================ -*/ -bool idPhysics_StaticMulti::IsAtRest( void ) const { - return true; -} - -/* -================ -idPhysics_StaticMulti::GetRestStartTime -================ -*/ -int idPhysics_StaticMulti::GetRestStartTime( void ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::IsPushable -================ -*/ -bool idPhysics_StaticMulti::IsPushable( void ) const { - return false; -} - -/* -================ -idPhysics_StaticMulti::SaveState -================ -*/ -void idPhysics_StaticMulti::SaveState( void ) { -} - -/* -================ -idPhysics_StaticMulti::RestoreState -================ -*/ -void idPhysics_StaticMulti::RestoreState( void ) { -} - -/* -================ -idPhysics_StaticMulti::SetOrigin -================ -*/ -void idPhysics_StaticMulti::SetOrigin( const idVec3 &newOrigin, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( id >= 0 && id < clipModels.Num() ) { - current[id].localOrigin = newOrigin; - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current[id].origin = masterOrigin + newOrigin * masterAxis; - } else { - current[id].origin = newOrigin; - } - if ( clipModels[id] ) { - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - } else if ( id == -1 ) { - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - Translate( masterOrigin + masterAxis * newOrigin - current[0].origin ); - } else { - Translate( newOrigin - current[0].origin ); - } - } -} - -/* -================ -idPhysics_StaticMulti::SetAxis -================ -*/ -void idPhysics_StaticMulti::SetAxis( const idMat3 &newAxis, int id ) { - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( id >= 0 && id < clipModels.Num() ) { - current[id].localAxis = newAxis; - if ( hasMaster && isOrientated ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current[id].axis = newAxis * masterAxis; - } else { - current[id].axis = newAxis; - } - if ( clipModels[id] ) { - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - } else if ( id == -1 ) { - idMat3 axis; - idRotation rotation; - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - axis = current[0].axis.Transpose() * ( newAxis * masterAxis ); - } else { - axis = current[0].axis.Transpose() * newAxis; - } - rotation = axis.ToRotation(); - rotation.SetOrigin( current[0].origin ); - - Rotate( rotation ); - } -} - -/* -================ -idPhysics_StaticMulti::Translate -================ -*/ -void idPhysics_StaticMulti::Translate( const idVec3 &translation, int id ) { - int i; - - if ( id >= 0 && id < clipModels.Num() ) { - current[id].localOrigin += translation; - current[id].origin += translation; - - if ( clipModels[id] ) { - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - } else if ( id == -1 ) { - for ( i = 0; i < clipModels.Num(); i++ ) { - current[i].localOrigin += translation; - current[i].origin += translation; - - if ( clipModels[i] ) { - clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); - } - } - } -} - -/* -================ -Tels: idPhysics_StaticMulti::Scale -================ -*/ -void idPhysics_StaticMulti::Scale( const idVec3 &scale, int id ) { - int i; - - if ( id >= 0 && id < clipModels.Num() ) { - if ( clipModels[id] ) { - clipModels[id]->Scale( scale ); - // Tels: nec.? - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - } else if ( id == -1 ) { - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->Scale( scale ); - clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); - } - } - } -} - -/* -================ -idPhysics_StaticMulti::Rotate -================ -*/ -void idPhysics_StaticMulti::Rotate( const idRotation &rotation, int id ) { - int i; - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( id >= 0 && id < clipModels.Num() ) { - current[id].origin *= rotation; - current[id].axis *= rotation.ToMat3(); - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current[id].localAxis *= rotation.ToMat3(); - current[id].localOrigin = ( current[id].origin - masterOrigin ) * masterAxis.Transpose(); - } else { - current[id].localAxis = current[id].axis; - current[id].localOrigin = current[id].origin; - } - - if ( clipModels[id] ) { - clipModels[id]->Link( gameLocal.clip, self, id, current[id].origin, current[id].axis ); - } - } else if ( id == -1 ) { - for ( i = 0; i < clipModels.Num(); i++ ) { - current[i].origin *= rotation; - current[i].axis *= rotation.ToMat3(); - - if ( hasMaster ) { - self->GetMasterPosition( masterOrigin, masterAxis ); - current[i].localAxis *= rotation.ToMat3(); - current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose(); - } else { - current[i].localAxis = current[i].axis; - current[i].localOrigin = current[i].origin; - } - - if ( clipModels[i] ) { - clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); - } - } - } -} - -/* -================ -idPhysics_StaticMulti::GetOrigin -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetOrigin( int id ) const { - if ( id >= 0 && id < clipModels.Num() ) { - return current[id].origin; - } - if ( clipModels.Num() ) { - return current[0].origin; - } else { - return vec3_origin; - } -} - -/* -================ -idPhysics_StaticMulti::GetAxis -================ -*/ -const idMat3 &idPhysics_StaticMulti::GetAxis( int id ) const { - if ( id >= 0 && id < clipModels.Num() ) { - return current[id].axis; - } - if ( clipModels.Num() ) { - return current[0].axis; - } else { - return mat3_identity; - } -} - -/* -================ -idPhysics_StaticMulti::SetLinearVelocity -================ -*/ -void idPhysics_StaticMulti::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) { -} - -/* -================ -idPhysics_StaticMulti::SetAngularVelocity -================ -*/ -void idPhysics_StaticMulti::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) { -} - -/* -================ -idPhysics_StaticMulti::GetLinearVelocity -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetLinearVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_StaticMulti::GetAngularVelocity -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetAngularVelocity( int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_StaticMulti::SetGravity -================ -*/ -void idPhysics_StaticMulti::SetGravity( const idVec3 &newGravity ) { -} - -/* -================ -idPhysics_StaticMulti::GetGravity -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetGravity( void ) const { - static idVec3 gravity( 0, 0, -g_gravity.GetFloat() ); - return gravity; -} - -/* -================ -idPhysics_StaticMulti::GetGravityNormal -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetGravityNormal( void ) const { - static idVec3 gravity( 0, 0, -1 ); - return gravity; -} - -/* -================ -idPhysics_StaticMulti::ClipTranslation -================ -*/ -void idPhysics_StaticMulti::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const { - memset( &results, 0, sizeof( trace_t ) ); - gameLocal.Warning( "idPhysics_StaticMulti::ClipTranslation called" ); -} - -/* -================ -idPhysics_StaticMulti::ClipRotation -================ -*/ -void idPhysics_StaticMulti::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const { - memset( &results, 0, sizeof( trace_t ) ); - gameLocal.Warning( "idPhysics_StaticMulti::ClipRotation called" ); -} - -/* -================ -idPhysics_StaticMulti::ClipContents -================ -*/ -int idPhysics_StaticMulti::ClipContents( const idClipModel *model ) const { - int i, contents; - - contents = 0; - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - if ( model ) { - contents |= gameLocal.clip.ContentsModel( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1, - model->Handle(), model->GetOrigin(), model->GetAxis() ); - } else { - contents |= gameLocal.clip.Contents( clipModels[i]->GetOrigin(), clipModels[i], clipModels[i]->GetAxis(), -1, NULL ); - } - } - } - return contents; -} - -/* -================ -idPhysics_StaticMulti::DisableClip -================ -*/ -void idPhysics_StaticMulti::DisableClip( void ) { - int i; - - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->Disable(); - } - } -} - -/* -================ -idPhysics_StaticMulti::EnableClip -================ -*/ -void idPhysics_StaticMulti::EnableClip( void ) { - int i; - - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->Enable(); - } - } -} - -/* -================ -idPhysics_StaticMulti::UnlinkClip -================ -*/ -void idPhysics_StaticMulti::UnlinkClip( void ) { - int i; - - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->Unlink(); - } - } -} - -/* -================ -idPhysics_StaticMulti::LinkClip -================ -*/ -void idPhysics_StaticMulti::LinkClip( void ) { - int i; - - for ( i = 0; i < clipModels.Num(); i++ ) { - if ( clipModels[i] ) { - clipModels[i]->Link( gameLocal.clip, self, i, current[i].origin, current[i].axis ); - } - } -} - -/* -================ -idPhysics_StaticMulti::EvaluateContacts -================ -*/ -bool idPhysics_StaticMulti::EvaluateContacts( void ) { - return false; -} - -/* -================ -idPhysics_StaticMulti::GetNumContacts -================ -*/ -int idPhysics_StaticMulti::GetNumContacts( void ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::GetContact -================ -*/ -const contactInfo_t &idPhysics_StaticMulti::GetContact( int num ) const { - static contactInfo_t info; - memset( &info, 0, sizeof( info ) ); - return info; -} - -bool idPhysics_StaticMulti::HasNonStaticContacts() { - return false; -} - -/* -================ -idPhysics_StaticMulti::ClearContacts -================ -*/ -void idPhysics_StaticMulti::ClearContacts( void ) { -} - -/* -================ -idPhysics_StaticMulti::AddContactEntity -================ -*/ -void idPhysics_StaticMulti::AddContactEntity( idEntity *e ) { -} - -/* -================ -idPhysics_StaticMulti::RemoveContactEntity -================ -*/ -void idPhysics_StaticMulti::RemoveContactEntity( idEntity *e ) { -} - -/* -================ -idPhysics_StaticMulti::HasGroundContacts -================ -*/ -bool idPhysics_StaticMulti::HasGroundContacts( void ) const { - return false; -} - -/* -================ -idPhysics_StaticMulti::IsGroundEntity -================ -*/ -bool idPhysics_StaticMulti::IsGroundEntity( int entityNum ) const { - return false; -} - -/* -================ -idPhysics_StaticMulti::IsGroundClipModel -================ -*/ -bool idPhysics_StaticMulti::IsGroundClipModel( int entityNum, int id ) const { - return false; -} - -/* -================ -idPhysics_StaticMulti::SetPushed -================ -*/ -void idPhysics_StaticMulti::SetPushed( int deltaTime ) { -} - -/* -================ -idPhysics_StaticMulti::GetPushedLinearVelocity -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetPushedLinearVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_StaticMulti::GetPushedAngularVelocity -================ -*/ -const idVec3 &idPhysics_StaticMulti::GetPushedAngularVelocity( const int id ) const { - return vec3_origin; -} - -/* -================ -idPhysics_StaticMulti::SetMaster -================ -*/ -void idPhysics_StaticMulti::SetMaster( idEntity *master, const bool orientated ) { - int i; - idVec3 masterOrigin; - idMat3 masterAxis; - - if ( master ) { - if ( !hasMaster ) { - // transform from world space to master space - self->GetMasterPosition( masterOrigin, masterAxis ); - for ( i = 0; i < clipModels.Num(); i++ ) { - current[i].localOrigin = ( current[i].origin - masterOrigin ) * masterAxis.Transpose(); - if ( orientated ) { - current[i].localAxis = current[i].axis * masterAxis.Transpose(); - } else { - current[i].localAxis = current[i].axis; - } - } - hasMaster = true; - isOrientated = orientated; - } - } else { - if ( hasMaster ) { - hasMaster = false; - } - } -} - -/* -================ -idPhysics_StaticMulti::GetBlockingInfo -================ -*/ -const trace_t *idPhysics_StaticMulti::GetBlockingInfo( void ) const { - return NULL; -} - -/* -================ -idPhysics_StaticMulti::GetBlockingEntity -================ -*/ -idEntity *idPhysics_StaticMulti::GetBlockingEntity( void ) const { - return NULL; -} - -/* -================ -idPhysics_StaticMulti::GetLinearEndTime -================ -*/ -int idPhysics_StaticMulti::GetLinearEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::GetAngularEndTime -================ -*/ -int idPhysics_StaticMulti::GetAngularEndTime( void ) const { - return 0; -} - -/* -================ -idPhysics_StaticMulti::WriteToSnapshot -================ -*/ -void idPhysics_StaticMulti::WriteToSnapshot( idBitMsgDelta &msg ) const { - int i; - idCQuat quat, localQuat; - - msg.WriteByte( current.Num() ); - - for ( i = 0; i < current.Num(); i++ ) { - quat = current[i].axis.ToCQuat(); - localQuat = current[i].localAxis.ToCQuat(); - - msg.WriteFloat( current[i].origin[0] ); - msg.WriteFloat( current[i].origin[1] ); - msg.WriteFloat( current[i].origin[2] ); - msg.WriteFloat( quat.x ); - msg.WriteFloat( quat.y ); - msg.WriteFloat( quat.z ); - msg.WriteDeltaFloat( current[i].origin[0], current[i].localOrigin[0] ); - msg.WriteDeltaFloat( current[i].origin[1], current[i].localOrigin[1] ); - msg.WriteDeltaFloat( current[i].origin[2], current[i].localOrigin[2] ); - msg.WriteDeltaFloat( quat.x, localQuat.x ); - msg.WriteDeltaFloat( quat.y, localQuat.y ); - msg.WriteDeltaFloat( quat.z, localQuat.z ); - } -} - -/* -================ -idPhysics_StaticMulti::ReadFromSnapshot -================ -*/ -void idPhysics_StaticMulti::ReadFromSnapshot( const idBitMsgDelta &msg ) { - int i, num; - idCQuat quat, localQuat; - - num = msg.ReadByte(); - assert( num == current.Num() ); - - for ( i = 0; i < current.Num(); i++ ) { - current[i].origin[0] = msg.ReadFloat(); - current[i].origin[1] = msg.ReadFloat(); - current[i].origin[2] = msg.ReadFloat(); - quat.x = msg.ReadFloat(); - quat.y = msg.ReadFloat(); - quat.z = msg.ReadFloat(); - current[i].localOrigin[0] = msg.ReadDeltaFloat( current[i].origin[0] ); - current[i].localOrigin[1] = msg.ReadDeltaFloat( current[i].origin[1] ); - current[i].localOrigin[2] = msg.ReadDeltaFloat( current[i].origin[2] ); - localQuat.x = msg.ReadDeltaFloat( quat.x ); - localQuat.y = msg.ReadDeltaFloat( quat.y ); - localQuat.z = msg.ReadDeltaFloat( quat.z ); - - current[i].axis = quat.ToMat3(); - current[i].localAxis = localQuat.ToMat3(); - } -} diff --git a/game/physics/physics_staticmulti.h b/game/physics/physics_staticmulti.h deleted file mode 100644 index da66cec57..000000000 --- a/game/physics/physics_staticmulti.h +++ /dev/null @@ -1,152 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PHYSICS_STATICMULTI_H__ -#define __PHYSICS_STATICMULTI_H__ - -/* -=============================================================================== - - Physics for a non moving object using no or multiple collision models. - -=============================================================================== -*/ - -class idPhysics_StaticMulti : public idPhysics { - -public: - CLASS_PROTOTYPE( idPhysics_StaticMulti ); - - idPhysics_StaticMulti( void ); - ~idPhysics_StaticMulti( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void RemoveIndex( int id = 0, bool freeClipModel = true ); - -public: // common physics interface - - void SetSelf( idEntity *e ); - - void SetClipModel( idClipModel *model, float density, int id = 0, bool freeOld = true ); - idClipModel * GetClipModel( int id = 0 ) const; - int GetNumClipModels( void ) const; - - void SetMass( float mass, int id = -1 ); - float GetMass( int id = -1 ) const; - - void SetContents( int contents, int id = -1 ); - int GetContents( int id = -1 ) const; - - void SetClipMask( int mask, int id = -1 ); - int GetClipMask( int id = -1 ) const; - - const idBounds & GetBounds( int id = -1 ) const; - const idBounds & GetAbsBounds( int id = -1 ) const; - - bool Evaluate( int timeStepMSec, int endTimeMSec ); - void UpdateTime( int endTimeMSec ); - int GetTime( void ) const; - - void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const; - void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - bool PropagateImpulse( const int id, const idVec3 &point, const idVec3 &impulse ); - void AddForce( const int id, const idVec3 &point, const idVec3 &force ); - void Activate( void ); - void PutToRest( void ); - bool IsAtRest( void ) const; - int GetRestStartTime( void ) const; - bool IsPushable( void ) const; - - void SaveState( void ); - void RestoreState( void ); - - void SetOrigin( const idVec3 &newOrigin, int id = -1 ); - void SetAxis( const idMat3 &newAxis, int id = -1 ); - - // Tels: Scale the clipmodel with the id "id" - void Scale( const idVec3 &scale, int id = -1 ); - - void Translate( const idVec3 &translation, int id = -1 ); - void Rotate( const idRotation &rotation, int id = -1 ); - - const idVec3 & GetOrigin( int id = 0 ) const; - const idMat3 & GetAxis( int id = 0 ) const; - - void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 ); - void SetAngularVelocity( const idVec3 &newAngularVelocity, int id = 0 ); - - const idVec3 & GetLinearVelocity( int id = 0 ) const; - const idVec3 & GetAngularVelocity( int id = 0 ) const; - - void SetGravity( const idVec3 &newGravity ); - const idVec3 & GetGravity( void ) const; - const idVec3 & GetGravityNormal( void ) const; - - void ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const; - void ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const; - int ClipContents( const idClipModel *model ) const; - - void DisableClip( void ); - void EnableClip( void ); - - void UnlinkClip( void ); - void LinkClip( void ); - - bool EvaluateContacts( void ); - int GetNumContacts( void ) const; - const contactInfo_t & GetContact( int num ) const; - bool HasNonStaticContacts(); - void ClearContacts( void ); - void AddContactEntity( idEntity *e ); - void RemoveContactEntity( idEntity *e ); - - bool HasGroundContacts( void ) const; - bool IsGroundEntity( int entityNum ) const; - bool IsGroundClipModel( int entityNum, int id ) const; - - void SetPushed( int deltaTime ); - const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const; - const idVec3 & GetPushedAngularVelocity( const int id = 0 ) const; - - void SetMaster( idEntity *master, const bool orientated = true ); - - const trace_t * GetBlockingInfo( void ) const; - idEntity * GetBlockingEntity( void ) const; - - int GetLinearEndTime( void ) const; - int GetAngularEndTime( void ) const; - - void WriteToSnapshot( idBitMsgDelta &msg ) const; - void ReadFromSnapshot( const idBitMsgDelta &msg ); - -#ifdef MOD_WATERPHYSICS - // gets/sets the water - // just some functions to avoid making this class abstract. Water has no effect on a static object - // so it sort of makes sense these functions do nothing. - virtual idPhysics_Liquid *GetWater() { return NULL; } // MOD_WATERPHYSICS - virtual void SetWater( idPhysics_Liquid *e, const float murkiness ) {} // MOD_WATERPHYSICS -#endif - -protected: - idEntity * self; // entity using this physics object - idList current; // physics state - idList clipModels; // collision model(s) - - // master - bool hasMaster; - bool isOrientated; -}; - -#endif /* !__PHYSICS_STATICMULTI_H__ */ diff --git a/game/physics/push.cpp b/game/physics/push.cpp deleted file mode 100644 index 99bc7bbcf..000000000 --- a/game/physics/push.cpp +++ /dev/null @@ -1,1486 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - - -/* -============ -idPush::InitSavingPushedEntityPositions -============ -*/ -void idPush::InitSavingPushedEntityPositions( void ) { - numPushed = 0; -} - -/* -============ -idPush::SaveEntityPosition -============ -*/ -void idPush::SaveEntityPosition( idEntity *ent ) { - int i; - - // if already saved the physics state for this entity - for ( i = 0; i < numPushed; i++ ) { - if ( pushed[i].ent == ent ) { - return; - } - } - - // don't overflow - if ( numPushed >= MAX_GENTITIES ) { - gameLocal.Error( "more than MAX_GENTITIES pushed entities" ); - return; - } - - pushed[numPushed].ent = ent; - - // if the entity is an actor - if ( ent->IsType( idActor::Type ) ) { - // save the delta view angles - pushed[numPushed].deltaViewAngles = static_cast(ent)->GetDeltaViewAngles(); - } - - // save the physics state - ent->GetPhysics()->SaveState(); - - numPushed++; -} - -/* -============ -idPush::RestorePushedEntityPositions -============ -*/ -void idPush::RestorePushedEntityPositions( void ) { - int i; - - for ( i = 0; i < numPushed; i++ ) { - - // if the entity is an actor - if ( pushed[i].ent->IsType( idActor::Type ) ) { - // set back the delta view angles - static_cast(pushed[i].ent)->SetDeltaViewAngles( pushed[i].deltaViewAngles ); - } - - // restore the physics state - pushed[i].ent->GetPhysics()->RestoreState(); - } -} - -/* -============ -idPush::RotateEntityToAxial -============ -*/ -bool idPush::RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint ) { - int i; - trace_t trace; - idRotation rotation; - idMat3 axis; - idPhysics *physics; - - physics = ent->GetPhysics(); - axis = physics->GetAxis(); - if ( !axis.IsRotated() ) { - return true; - } - // try to rotate the bbox back to axial with at most four rotations - for ( i = 0; i < 4; i++ ) { - axis = physics->GetAxis(); - rotation = axis.ToRotation(); - rotation.Scale( -1 ); - rotation.SetOrigin( rotationPoint ); - // tiny float numbers in the clip axis, this can get the entity stuck - if ( rotation.GetAngle() == 0.0f ) { - physics->SetAxis( mat3_identity ); - return true; - } - // - ent->GetPhysics()->ClipRotation( trace, rotation, NULL ); - // if the full rotation is possible - if ( trace.fraction >= 1.0f ) { - // set bbox in final axial position - physics->SetOrigin( trace.endpos ); - physics->SetAxis( mat3_identity ); - return true; - } - // if partial rotation was possible - else if ( trace.fraction > 0.0f ) { - // partial rotation - physics->SetOrigin( trace.endpos ); - physics->SetAxis( trace.endAxis ); - } - // next rotate around collision point - rotationPoint = trace.c.point; - } - return false; -} - -#ifdef NEW_PUSH - -/* -============ -idPush::CanPushEntity -============ -*/ -bool idPush::CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags ) { - - // if the physics object is not pushable - if ( !ent->GetPhysics()->IsPushable() ) { - return false; - } - - // if the entity doesn't clip with this pusher - if ( !( ent->GetPhysics()->GetClipMask() & pusher->GetPhysics()->GetContents() ) ) { - return false; - } - - // don't push players in noclip mode - if ( ent->client && ent->client->noclip ) { - return false; - } - - // if we should only push idMoveable entities - if ( ( flags & PUSHFL_ONLYMOVEABLE ) && !ent->IsType( idMoveable::Type ) ) { - return false; - } - - // if we shouldn't push entities the original pusher rests upon - if ( flags & PUSHFL_NOGROUNDENTITIES ) { - if ( initialPusher->GetPhysics()->IsGroundEntity( ent->entityNumber ) ) { - return false; - } - } - - return true; -} - -/* -============ -idPush::AddEntityToPushedGroup -============ -*/ -void idPush::AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact ) { - int i, j; - - for ( i = 0; i < pushedGroupSize; i++ ) { - if ( ent == pushedGroup[i].ent ) { - if ( fraction > pushedGroup[i].fraction ) { - pushedGroup[i].fraction = fraction; - pushedGroup[i].groundContact &= groundContact; - pushedGroup[i].test = true; - } - return; - } - else if ( fraction > pushedGroup[i].fraction ) { - for ( j = pushedGroupSize; j > i; j-- ) { - pushedGroup[j] = pushedGroup[j-1]; - } - break; - } - } - - // put the entity in the group - pushedGroupSize++; - pushedGroup[i].ent = ent; - pushedGroup[i].fraction = fraction; - pushedGroup[i].groundContact = groundContact; - pushedGroup[i].test = true; - - // remove any further occurances of the same entity in the group - for ( i++; i < pushedGroupSize; i++ ) { - if ( ent == pushedGroup[i].ent ) { - for ( j = i+1; j < pushedGroupSize; j++ ) { - pushedGroup[j-1] = pushedGroup[j]; - } - pushedGroupSize--; - break; - } - } -} - -/* -============ -idPush::IsFullyPushed -============ -*/ -bool idPush::IsFullyPushed( idEntity *ent ) { - int i; - - for ( i = 0; i < pushedGroupSize; i++ ) { - if ( pushedGroup[i].fraction < 1.0f ) { - return false; - } - if ( ent == pushedGroup[i].ent ) { - return true; - } - } - return false; -} - -/* -============ -idPush::ClipTranslationAgainstPusher -============ -*/ -bool idPush::ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation ) { - int i, n; - trace_t t; - - results.fraction = 1.0f; - - n = pusher->GetPhysics()->GetNumClipModels(); - for ( i = 0; i < n; i++ ) { - ent->GetPhysics()->ClipTranslation( t, translation, pusher->GetPhysics()->GetClipModel( i ) ); - if ( t.fraction < results.fraction ) { - results = t; - } - } - return ( results.fraction < 1.0f ); -} - -/* -============ -idPush::GetPushableEntitiesForTranslation -============ -*/ -int idPush::GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags, - const idVec3 &translation, idEntity *entityList[], int maxEntities ) { - int i, n, l; - idBounds bounds, pushBounds; - idPhysics *physics; - - // get bounds for the whole movement - physics = pusher->GetPhysics(); - bounds = physics->GetBounds(); - pushBounds.FromBoundsTranslation( bounds, physics->GetOrigin(), physics->GetAxis(), translation ); - pushBounds.ExpandSelf( 2.0f ); - - // get all entities within the push bounds - n = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); - - for ( l = i = 0; i < n; i++ ) { - if ( entityList[i] == pusher || entityList[i] == initialPusher ) { - continue; - } - if ( CanPushEntity( entityList[i], pusher, initialPusher, flags ) ) { - entityList[l++] = entityList[i]; - } - } - - return l; -} - -/* -============ -idPush::ClipTranslationalPush - - Try to push other entities by translating the given entity. -============ -*/ -float idPush::ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, - const idVec3 &newOrigin, const idVec3 &translation, - float ImpulseMod ) -{ - int i, j, numListedEntities; - idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ]; - float fraction; - bool groundContact, blocked = false; - float totalMass; - trace_t trace; - idVec3 realTranslation, partialTranslation; - - totalMass = 0.0f; - - results.fraction = 1.0f; - results.endpos = newOrigin; - results.endAxis = pusher->GetPhysics()->GetAxis(); - memset( results.c, 0, sizeof( results.c ) ); - - if ( translation == vec3_origin ) { - return totalMass; - } - - // clip against all non-pushable physics objects - if ( flags & PUSHFL_CLIP ) { - - numListedEntities = GetPushableEntitiesForTranslation( pusher, pusher, flags, translation, entityList, MAX_GENTITIES ); - // disable pushable entities for collision detection - for ( i = 0; i < numListedEntities; i++ ) { - entityList[i]->GetPhysics()->DisableClip(); - } - // clip translation - pusher->GetPhysics()->ClipTranslation( results, translation, NULL ); - // enable pushable entities - for ( i = 0; i < numListedEntities; i++ ) { - entityList[i]->GetPhysics()->EnableClip(); - } - if ( results.fraction == 0.0f ) { - return totalMass; - } - realTranslation = results.fraction * translation; - } - else { - realTranslation = translation; - } - - // put the pusher in the group of pushed physics objects - pushedGroup[0].ent = pusher; - pushedGroup[0].fraction = 1.0f; - pushedGroup[0].groundContact = true; - pushedGroup[0].test = true; - pushedGroupSize = 1; - - // get all physics objects that need to be pushed - for ( i = 0; i < pushedGroupSize; ) { - if ( !pushedGroup[i].test ) { - i++; - continue; - } - pushedGroup[i].test = false; - curPusher = pushedGroup[i].ent; - fraction = pushedGroup[i].fraction; - groundContact = pushedGroup[i].groundContact; - i = 0; - - numListedEntities = GetPushableEntitiesForTranslation( curPusher, pusher, flags, realTranslation, entityList, MAX_GENTITIES ); - - for ( j = 0; j < numListedEntities; j++ ) { - ent = entityList[ j ]; - - if ( IsFullyPushed( ent ) ) { - continue; - } - - if ( !CanPushEntity( ent, curPusher, pusher, flags ) ) { - continue; - } - - if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) { - AddEntityToPushedGroup( ent, 1.0f * fraction, false ); - } - else if ( ClipTranslationAgainstPusher( trace, ent, curPusher, -fraction * realTranslation ) ) { - AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact ); - } - } - } - - // save physics states and disable physics objects for collision detection - for ( i = 0; i < pushedGroupSize; i++ ) { - SaveEntityPosition( pushedGroup[i].ent ); - pushedGroup[i].ent->GetPhysics()->DisableClip(); - } - - // clip all pushed physics objects - for ( i = 1; i < pushedGroupSize; i++ ) { - partialTranslation = realTranslation * pushedGroup[i].fraction; - - pushedGroup[i].ent->GetPhysics()->ClipTranslation( trace, partialTranslation, NULL ); - - if ( trace.fraction < 1.0f ) { - blocked = true; - break; - } - } - - // enable all physics objects for collision detection - for ( i = 1; i < pushedGroupSize; i++ ) { - pushedGroup[i].ent->GetPhysics()->EnableClip(); - } - - // push all or nothing - if ( blocked ) { - if ( flags & PUSHFL_CLIP ) { - pusher->GetPhysics()->ClipTranslation( results, realTranslation, NULL ); - } - else { - results.fraction = 0.0f; - results.endpos = pusher->GetPhysics()->GetOrigin(); - results.endAxis = pusher->GetPhysics()->GetAxis(); - } - } - else { - // translate all pushed physics objects - for ( i = 1; i < pushedGroupSize; i++ ) { - partialTranslation = realTranslation * pushedGroup[i].fraction; - pushedGroup[i].ent->GetPhysics()->Translate( partialTranslation ); - totalMass += pushedGroup[i].ent->GetPhysics()->GetMass(); - } - // translate the clip models of the pusher - for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) { - pusher->GetPhysics()->GetClipModel(i)->Translate( results.fraction * realTranslation ); - pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip ); - } - } - - return totalMass; -} - -/* -============ -idPush::ClipRotationAgainstPusher -============ -*/ -bool idPush::ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation ) { - int i, n; - trace_t t; - - results.fraction = 1.0f; - - n = pusher->GetPhysics()->GetNumClipModels(); - for ( i = 0; i < n; i++ ) { - ent->GetPhysics()->ClipRotation( t, rotation, pusher->GetPhysics()->GetClipModel( i ) ); - if ( t.fraction < results.fraction ) { - results = t; - } - } - return ( results.fraction < 1.0f ); -} - -/* -============ -idPush::GetPushableEntitiesForRotation -============ -*/ -int idPush::GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags, - const idRotation &rotation, idEntity *entityList[], int maxEntities ) { - int i, n, l; - idBounds bounds, pushBounds; - idPhysics *physics; - - // get bounds for the whole movement - physics = pusher->GetPhysics(); - bounds = physics->GetBounds(); - pushBounds.FromBoundsRotation( bounds, physics->GetOrigin(), physics->GetAxis(), rotation ); - pushBounds.ExpandSelf( 2.0f ); - - // get all entities within the push bounds - n = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); - - for ( l = i = 0; i < n; i++ ) { - if ( entityList[i] == pusher || entityList[i] == initialPusher ) { - continue; - } - if ( CanPushEntity( entityList[i], pusher, initialPusher, flags ) ) { - entityList[l++] = entityList[i]; - } - } - - return l; -} - -/* -============ -idPush::ClipRotationalPush - - Try to push other entities by rotating the given entity. -============ -*/ -float idPush::ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, - const idMat3 &newAxis, const idRotation &rotation ) { - int i, j, numListedEntities; - idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ]; - float fraction; - bool groundContact, blocked = false; - float totalMass; - trace_t trace; - idRotation realRotation, partialRotation; - idMat3 oldAxis; - - totalMass = 0.0f; - - results.fraction = 1.0f; - results.endpos = pusher->GetPhysics()->GetOrigin(); - results.endAxis = newAxis; - memset( results.c, 0, sizeof( results.c ) ); - - if ( !rotation.GetAngle() ) { - return totalMass; - } - - // clip against all non-pushable physics objects - if ( flags & PUSHFL_CLIP ) { - - numListedEntities = GetPushableEntitiesForRotation( pusher, pusher, flags, rotation, entityList, MAX_GENTITIES ); - // disable pushable entities for collision detection - for ( i = 0; i < numListedEntities; i++ ) { - entityList[i]->GetPhysics()->DisableClip(); - } - // clip rotation - pusher->GetPhysics()->ClipRotation( results, rotation, NULL ); - // enable pushable entities - for ( i = 0; i < numListedEntities; i++ ) { - entityList[i]->GetPhysics()->EnableClip(); - } - if ( results.fraction == 0.0f ) { - return totalMass; - } - realRotation = results.fraction * rotation; - } - else { - realRotation = rotation; - } - - // put the pusher in the group of pushed physics objects - pushedGroup[0].ent = pusher; - pushedGroup[0].fraction = 1.0f; - pushedGroup[0].groundContact = true; - pushedGroup[0].test = true; - pushedGroupSize = 1; - - // get all physics objects that need to be pushed - for ( i = 0; i < pushedGroupSize; ) { - if ( !pushedGroup[i].test ) { - i++; - continue; - } - pushedGroup[i].test = false; - curPusher = pushedGroup[i].ent; - fraction = pushedGroup[i].fraction; - groundContact = pushedGroup[i].groundContact; - i = 0; - - numListedEntities = GetPushableEntitiesForRotation( curPusher, pusher, flags, realRotation, entityList, MAX_GENTITIES ); - - for ( j = 0; j < numListedEntities; j++ ) { - ent = entityList[ j ]; - - if ( IsFullyPushed( ent ) ) { - continue; - } - - if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) { - AddEntityToPushedGroup( ent, 1.0f * fraction, false ); - } - else if ( ClipRotationAgainstPusher( trace, ent, curPusher, -fraction * realRotation ) ) { - AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact ); - } - } - } - - // save physics states and disable physics objects for collision detection - for ( i = 1; i < pushedGroupSize; i++ ) { - SaveEntityPosition( pushedGroup[i].ent ); - pushedGroup[i].ent->GetPhysics()->DisableClip(); - } - - // clip all pushed physics objects - for ( i = 1; i < pushedGroupSize; i++ ) { - partialRotation = realRotation * pushedGroup[i].fraction; - - pushedGroup[i].ent->GetPhysics()->ClipRotation( trace, partialRotation, NULL ); - - if ( trace.fraction < 1.0f ) { - blocked = true; - break; - } - } - - // enable all physics objects for collision detection - for ( i = 1; i < pushedGroupSize; i++ ) { - pushedGroup[i].ent->GetPhysics()->EnableClip(); - } - - // push all or nothing - if ( blocked ) { - if ( flags & PUSHFL_CLIP ) { - pusher->GetPhysics()->ClipRotation( results, realRotation, NULL ); - } - else { - results.fraction = 0.0f; - results.endpos = pusher->GetPhysics()->GetOrigin(); - results.endAxis = pusher->GetPhysics()->GetAxis(); - } - } - else { - // rotate all pushed physics objects - for ( i = 1; i < pushedGroupSize; i++ ) { - partialRotation = realRotation * pushedGroup[i].fraction; - pushedGroup[i].ent->GetPhysics()->Rotate( partialRotation ); - totalMass += pushedGroup[i].ent->GetPhysics()->GetMass(); - } - // rotate the clip models of the pusher - for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) { - pusher->GetPhysics()->GetClipModel(i)->Rotate( realRotation ); - pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip ); - pusher->GetPhysics()->GetClipModel(i)->Enable(); - } - // rotate any actors back to axial - for ( i = 1; i < pushedGroupSize; i++ ) { - // if the entity is using actor physics - if ( pushedGroup[i].ent->GetPhysics()->IsType( idPhysics_Actor::Type ) ) { - - // rotate the collision model back to axial - if ( !RotateEntityToAxial( pushedGroup[i].ent, pushedGroup[i].ent->GetPhysics()->GetOrigin() ) ) { - // don't allow rotation if the bbox is no longer axial - results.fraction = 0.0f; - results.endpos = pusher->GetPhysics()->GetOrigin(); - results.endAxis = pusher->GetPhysics()->GetAxis(); - } - } - } - } - - return totalMass; -} - -#else /* !NEW_PUSH */ - -enum { - PUSH_NO, // not pushed - PUSH_OK, // pushed ok - PUSH_BLOCKED // blocked -}; - -/* -============ -idPush::ClipEntityRotation -============ -*/ -void idPush::ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, idClipModel *skip, const idRotation &rotation ) { - - if ( skip ) { - skip->Disable(); - } - - ent->GetPhysics()->ClipRotation( trace, rotation, clipModel ); - - if ( skip ) { - skip->Enable(); - } -} - -/* -============ -idPush::ClipEntityTranslation -============ -*/ -void idPush::ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, idClipModel *skip, const idVec3 &translation ) { - - if ( skip ) { - skip->Disable(); - } - - ent->GetPhysics()->ClipTranslation( trace, translation, clipModel ); - - if ( skip ) { - skip->Enable(); - } -} - -/* -============ -idPush::TryRotatePushEntity -============ -*/ -#ifdef _DEBUG -// #define ROTATIONAL_PUSH_DEBUG -#endif - -int idPush::TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, - const idMat3 &newAxis, const idRotation &rotation ) { - trace_t trace; - idVec3 rotationPoint; - idRotation newRotation; - float checkAngle; - - idPhysics* physics = check->GetPhysics(); - -#ifdef ROTATIONAL_PUSH_DEBUG - bool startsolid = false; - if ( physics->ClipContents( clipModel ) ) { - startsolid = true; - } -#endif - - results.fraction = 1.0f; - results.endpos = clipModel->GetOrigin(); - results.endAxis = newAxis; - memset( &results.c, 0, sizeof( results.c ) ); - - // always pushed when standing on the pusher - if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { - // rotate the entity colliding with all other entities except the pusher itself - ClipEntityRotation( trace, check, NULL, clipModel, rotation ); - // if there is a collision - if ( trace.fraction < 1.0f ) { - // angle along which the entity is pushed - checkAngle = rotation.GetAngle() * trace.fraction; - // test if the entity can stay at it's partly pushed position by rotating - // the entity in reverse only colliding with pusher - newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), -(rotation.GetAngle() - checkAngle) ); - ClipEntityRotation( results, check, clipModel, NULL, newRotation ); - // if there is a collision - if ( results.fraction < 1.0f ) { - - // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? - - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - // the entity will be crushed between the pusher and some other entity - return PUSH_BLOCKED; - } - } - else { - // angle along which the entity is pushed - checkAngle = rotation.GetAngle(); - } - // point to rotate entity bbox around back to axial - rotationPoint = physics->GetOrigin(); - } - else { - // rotate entity in reverse only colliding with pusher - newRotation = rotation; - newRotation.Scale( -1 ); - // - ClipEntityRotation( results, check, clipModel, NULL, newRotation ); - // if no collision with the pusher then the entity is not pushed by the pusher - if ( results.fraction >= 1.0f ) { -#ifdef ROTATIONAL_PUSH_DEBUG - // set pusher into final position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); - if ( physics->ClipContents( clipModel ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - return PUSH_NO; - } - - // greebo: At this point, the pushes knows that the check entity is in the way - // Normally, the pusher tries to rotate the entity to see if the entity itself - // is colliding with anything else, but for players, we want to (optionally) skip that. - if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) - { - // We are colliding with a player and are not allowed to push it, return BLOCKED - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - return PUSH_BLOCKED; - } - - // get point to rotate bbox around back to axial - rotationPoint = results.c.point; - // angle along which the entity will be pushed - checkAngle = rotation.GetAngle() * (1.0f - results.fraction); - // rotate the entity colliding with all other entities except the pusher itself - newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle ); - ClipEntityRotation( trace, check, NULL, clipModel, newRotation ); - // if there is a collision - if ( trace.fraction < 1.0f ) { - - // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? - - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - // the entity will be crushed between the pusher and some other entity - return PUSH_BLOCKED; - } - } - - SaveEntityPosition( check ); - - newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle ); -#ifndef __linux__ - // NOTE: this code prevents msvc 6.0 & 7.0 from screwing up the above code in - // release builds moving less floats than it should - static float shit = checkAngle; -#endif - - newRotation.RotatePoint( rotationPoint ); - - // rotate the entity - physics->Rotate( newRotation ); - - // set pusher into final position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); - -#ifdef ROTATIONAL_PUSH_DEBUG - if ( physics->ClipContents( clipModel ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - - // if the entity uses actor physics - if ( physics->IsType( idPhysics_Actor::Type ) ) { - - // rotate the collision model back to axial - if ( !RotateEntityToAxial( check, rotationPoint ) ) { - // don't allow rotation if the bbox is no longer axial - return PUSH_BLOCKED; - } - } - -#ifdef ROTATIONAL_PUSH_DEBUG - if ( physics->ClipContents( clipModel ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - - // if the entity is an actor using actor physics - if ( check->IsType( idActor::Type ) && physics->IsType( idPhysics_Actor::Type ) ) { - - // if the entity is standing ontop of the pusher - if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { - // rotate actor view - idActor *actor = static_cast(check); - idAngles delta = actor->GetDeltaViewAngles(); - delta.yaw += newRotation.ToMat3()[0].ToYaw(); - actor->SetDeltaViewAngles( delta ); - } - } - - return PUSH_OK; -} - -/* -============ -idPush::TryTranslatePushEntity -============ -*/ -#ifdef _DEBUG -// #define TRANSLATIONAL_PUSH_DEBUG -#endif - -int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, - const idVec3 &newOrigin, const idVec3 &move ) { - trace_t trace; - idVec3 checkMove; - idVec3 oldOrigin; - - idPhysics* physics = check->GetPhysics(); - -#ifdef TRANSLATIONAL_PUSH_DEBUG - bool startsolid = false; - if ( physics->ClipContents( clipModel ) ) { - startsolid = true; - } -#endif - - results.fraction = 1.0f; - results.endpos = newOrigin; - results.endAxis = clipModel->GetAxis(); - memset( &results.c, 0, sizeof( results.c ) ); - - // always pushed when standing on the pusher - if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) { - // move the entity colliding with all other entities except the pusher itself - ClipEntityTranslation( trace, check, NULL, clipModel, move ); - // if there is a collision - if ( trace.fraction < 1.0f ) { - // vector along which the entity is pushed - checkMove = move * trace.fraction; - // test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher - ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) ); - // if there is a collision - if ( results.fraction < 1.0f ) { - - // FIXME: try to push the blocking entity as well or try to slide along collision plane(s)? - - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - // the entity will be crushed between the pusher and some other entity - return PUSH_BLOCKED; - } - } - else { - // vector along which the entity is pushed - checkMove = move; - } - } - else { - // move entity in reverse only colliding with pusher - ClipEntityTranslation( results, check, clipModel, NULL, -move ); - // if no collision with the pusher then the entity is not pushed by the pusher - if ( results.fraction >= 1.0f ) { - return PUSH_NO; - } - - - // greebo: At this point, the pushes knows that the check entity is in the way - // Normally, the pusher tries to rotate the entity to see if the entity itself - // is colliding with anything else, but for players, we want to (optionally) skip that. - if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) - { - // We are colliding with a player and are not allowed to push it, return BLOCKED - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - return PUSH_BLOCKED; - } - - // vector along which the entity is pushed - checkMove = move * (1.0f - results.fraction); - // move the entity colliding with all other entities except the pusher itself - ClipEntityTranslation( trace, check, NULL, clipModel, checkMove ); - // if there is a collisions - if ( trace.fraction < 1.0f ) { - - results.c.normal = -results.c.normal; - results.c.dist = -results.c.dist; - - // FIXME: try to push the blocking entity as well ? - // FIXME: handle sliding along more than one collision plane ? - // FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map" - -/* - oldOrigin = physics->GetOrigin(); - - // movement still remaining - checkMove *= (1.0f - trace.fraction); - - // project the movement along the collision plane - if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) { - return PUSH_BLOCKED; - } - checkMove *= 1.001f; - - // move entity from collision point along the collision plane - physics->SetOrigin( trace.endpos ); - ClipEntityTranslation( trace, check, NULL, NULL, checkMove ); - - if ( trace.fraction < 1.0f ) { - physics->SetOrigin( oldOrigin ); - return PUSH_BLOCKED; - } - - checkMove = trace.endpos - oldOrigin; - - // move entity in reverse only colliding with pusher - physics->SetOrigin( trace.endpos ); - ClipEntityTranslation( trace, check, clipModel, NULL, -move ); - - physics->SetOrigin( oldOrigin ); -*/ - if ( trace.fraction < 1.0f ) { - return PUSH_BLOCKED; - } - } - } - - SaveEntityPosition( check ); - - // translate the entity - physics->Translate( checkMove ); - -#ifdef TRANSLATIONAL_PUSH_DEBUG - // set the pusher in the translated position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() ); - if ( physics->ClipContents( clipModel ) ) { - if ( !startsolid ) { - int bah = 1; - } - } -#endif - - return PUSH_OK; -} - -/* -============ -idPush::DiscardEntities -============ -*/ -int idPush::DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher ) { - int i, num; - idEntity *check; - - // remove all entities we cannot or should not push from the list - for ( num = i = 0; i < numEntities; i++ ) { - check = entityList[ i ]; - - // if the physics object is not pushable - if ( !check->GetPhysics()->IsPushable() ) { - continue; - } - - // if the entity doesn't clip with this pusher - if ( !( check->GetPhysics()->GetClipMask() & pusher->GetPhysics()->GetContents() ) ) { - continue; - } - - // don't push players in noclip mode - if ( check->IsType( idPlayer::Type ) && static_cast(check)->noclip ) { - continue; - } - - // if we should only push idMoveable entities - if ( ( flags & PUSHFL_ONLYMOVEABLE ) && !check->IsType( idMoveable::Type ) ) { - continue; - } - - // if we shouldn't push entities the clip model rests upon - if ( flags & PUSHFL_NOGROUNDENTITIES ) { - if ( pusher->GetPhysics()->IsGroundEntity( check->entityNumber ) ) { - continue; - } - } - - // keep entity in list - entityList[ num++ ] = entityList[i]; - } - - return num; -} - -/* -============ -idPush::ClipTranslationalPush - - Try to push other entities by moving the given entity. -============ -*/ -float idPush::ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, - const idVec3 &newOrigin, const idVec3 &translation, - float ImpulseMod ) -{ - int i, listedEntities, res; - idEntity *check, *entityList[ MAX_GENTITIES ]; - idBounds bounds, pushBounds; - idVec3 clipMove, clipOrigin, oldOrigin, dir, impulse; - trace_t pushResults; - bool wasEnabled; - float totalMass; - idClipModel *clipModel; - - clipModel = pusher->GetPhysics()->GetClipModel(); - - totalMass = 0.0f; - - results.fraction = 1.0f; - results.endpos = newOrigin; - results.endAxis = clipModel->GetAxis(); - memset( &results.c, 0, sizeof( results.c ) ); - - if ( translation == vec3_origin ) - { - return totalMass; - } - - dir = translation; - dir.Normalize(); - dir.z += 1.0f; - dir *= 10.0f; - - // get bounds for the whole movement - bounds = clipModel->GetBounds(); - if ( bounds[0].x >= bounds[1].x ) - { - return totalMass; - } - pushBounds.FromBoundsTranslation( bounds, clipModel->GetOrigin(), clipModel->GetAxis(), translation ); - - wasEnabled = clipModel->IsEnabled(); - - // make sure we don't get the pushing clip model in the list - clipModel->Disable(); - - listedEntities = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); - - // discard entities we cannot or should not push - listedEntities = DiscardEntities( entityList, listedEntities, flags, pusher ); - - if ( flags & PUSHFL_CLIP ) - { - - // can only clip movement of a trace model - assert( clipModel->IsTraceModel() ); - - // disable to be pushed entities for collision detection - for ( i = 0; i < listedEntities; i++ ) - { - entityList[i]->GetPhysics()->DisableClip(); - } - - gameLocal.clip.Translation( results, clipModel->GetOrigin(), clipModel->GetOrigin() + translation, clipModel, clipModel->GetAxis(), pusher->GetPhysics()->GetClipMask(), NULL ); - - // enable to be pushed entities for collision detection - for ( i = 0; i < listedEntities; i++ ) - { - entityList[i]->GetPhysics()->EnableClip(); - } - - if ( results.fraction == 0.0f ) - { - if ( wasEnabled ) - { - clipModel->Enable(); - } - return totalMass; - } - - clipMove = results.endpos - clipModel->GetOrigin(); - clipOrigin = results.endpos; - - } - else - { - - clipMove = translation; - clipOrigin = newOrigin; - } - - // we have to enable the clip model because we use it during pushing - clipModel->Enable(); - - // save pusher old position - oldOrigin = clipModel->GetOrigin(); - - // try to push the entities - for ( i = 0; i < listedEntities; i++ ) - { - - check = entityList[ i ]; - - idPhysics *physics = check->GetPhysics(); - - // disable the entity for collision detection - physics->DisableClip(); - - res = TryTranslatePushEntity( pushResults, check, clipModel, flags, clipOrigin, clipMove ); - - // enable the entity for collision detection - physics->EnableClip(); - - // if the entity is pushed - if ( res == PUSH_OK ) - { - // set the pusher in the translated position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() ); - // the entity might be pushed off the ground - physics->EvaluateContacts(); - // put pusher back in old position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), oldOrigin, clipModel->GetAxis() ); - - // wake up this object - if ( flags & PUSHFL_APPLYIMPULSE ) - { - impulse = ImpulseMod * physics->GetMass() * dir; - } else - { - impulse.Zero(); - } - check->ApplyImpulse( clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), impulse ); - - // add mass of pushed entity - totalMass += physics->GetMass(); - } - - // if the entity is not blocking - if ( res != PUSH_BLOCKED ) - { - continue; - } - - // if the blocking entity is a projectile - if ( check->IsType( idProjectile::Type ) ) - { - check->ProcessEvent( &EV_Explode ); - continue; - } - - // if blocking entities should be crushed - if ( flags & PUSHFL_CRUSH ) - { - check->Damage( clipModel->GetEntity(), clipModel->GetEntity(), vec3_origin, "damage_crush", 1.0f, CLIPMODEL_ID_TO_JOINT_HANDLE( pushResults.c.id ) ); - continue; - } - - // if the entity is an active articulated figure and gibs - if ( check->IsType( idAFEntity_Base::Type ) && check->spawnArgs.GetBool( "gib" ) ) - { - if ( static_cast(check)->IsActiveAF() ) - { - check->ProcessEvent( &EV_Gib, "damage_Gib" ); - } - } - - // if the entity is a moveable item and gibs - if ( check->IsType( idMoveableItem::Type ) && check->spawnArgs.GetBool( "gib" ) ) - { - check->ProcessEvent( &EV_Gib, "damage_Gib" ); - } - - // blocked - results = pushResults; - results.fraction = 0.0f; - results.endAxis = clipModel->GetAxis(); - results.endpos = clipModel->GetOrigin(); - results.c.entityNum = check->entityNumber; - results.c.id = 0; - - if ( !wasEnabled ) - { - clipModel->Disable(); - } - - return totalMass; - } - - if ( !wasEnabled ) - { - clipModel->Disable(); - } - - return totalMass; -} - -/* -============ -idPush::ClipRotationalPush - - Try to push other entities by moving the given entity. -============ -*/ -float idPush::ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, - const idMat3 &newAxis, const idRotation &rotation ) { - int i, listedEntities, res; - idEntity *check; - static idEntity* entityList[ MAX_GENTITIES ]; - idBounds bounds, pushBounds; - idRotation clipRotation; - idMat3 clipAxis, oldAxis; - trace_t pushResults; - bool wasEnabled; - float totalMass; - idClipModel *clipModel; - - clipModel = pusher->GetPhysics()->GetClipModel(); - - totalMass = 0.0f; - - results.fraction = 1.0f; - results.endpos = clipModel->GetOrigin(); - results.endAxis = newAxis; - memset( &results.c, 0, sizeof( results.c ) ); - - if ( !rotation.GetAngle() ) { - return totalMass; - } - - // get bounds for the whole movement - bounds = clipModel->GetBounds(); - if ( bounds[0].x >= bounds[1].x ) { - return totalMass; - } - pushBounds.FromBoundsRotation( bounds, clipModel->GetOrigin(), clipModel->GetAxis(), rotation ); - - wasEnabled = clipModel->IsEnabled(); - - // make sure we don't get the pushing clip model in the list - clipModel->Disable(); - - listedEntities = gameLocal.clip.EntitiesTouchingBounds( pushBounds, -1, entityList, MAX_GENTITIES ); - - // discard entities we cannot or should not push - listedEntities = DiscardEntities( entityList, listedEntities, flags, pusher ); - - if ( flags & PUSHFL_CLIP ) { - - // can only clip movement of a trace model - assert( clipModel->IsTraceModel() ); - - // disable to be pushed entities for collision detection - for ( i = 0; i < listedEntities; i++ ) { - entityList[i]->GetPhysics()->DisableClip(); - } - - gameLocal.clip.Rotation( results, clipModel->GetOrigin(), rotation, clipModel, clipModel->GetAxis(), pusher->GetPhysics()->GetClipMask(), NULL ); - - // enable to be pushed entities for collision detection - for ( i = 0; i < listedEntities; i++ ) { - entityList[i]->GetPhysics()->EnableClip(); - } - - if ( results.fraction == 0.0f ) { - if ( wasEnabled ) { - clipModel->Enable(); - } - return totalMass; - } - - clipRotation = rotation * results.fraction; - clipAxis = results.endAxis; - } - else { - - clipRotation = rotation; - clipAxis = newAxis; - } - - // we have to enable the clip model because we use it during pushing - clipModel->Enable(); - - // save pusher old position - oldAxis = clipModel->GetAxis(); - - // try to push all the entities - for ( i = 0; i < listedEntities; i++ ) { - - check = entityList[ i ]; - - idPhysics *physics = check->GetPhysics(); - - // disable the entity for collision detection - physics->DisableClip(); - - res = TryRotatePushEntity( pushResults, check, clipModel, flags, clipAxis, clipRotation ); - - // enable the entity for collision detection - physics->EnableClip(); - - // if the entity is pushed - if ( res == PUSH_OK ) { - // set the pusher in the rotated position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis ); - // the entity might be pushed off the ground - physics->EvaluateContacts(); - // put pusher back in old position - clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), oldAxis ); - - // wake up this object - check->ApplyImpulse( clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), vec3_origin ); - - // add mass of pushed entity - totalMass += physics->GetMass(); - } - - // if the entity is not blocking - if ( res != PUSH_BLOCKED ) { - continue; - } - - // if the blocking entity is a projectile - if ( check->IsType( idProjectile::Type ) ) { - check->ProcessEvent( &EV_Explode ); - continue; - } - - // if blocking entities should be crushed - if ( flags & PUSHFL_CRUSH ) { - check->Damage( clipModel->GetEntity(), clipModel->GetEntity(), vec3_origin, "damage_crush", 1.0f, CLIPMODEL_ID_TO_JOINT_HANDLE( pushResults.c.id ) ); - continue; - } - - // if the entity is an active articulated figure and gibs - if ( check->IsType( idAFEntity_Base::Type ) && check->spawnArgs.GetBool( "gib" ) ) { - if ( static_cast(check)->IsActiveAF() ) { - check->ProcessEvent( &EV_Gib, "damage_Gib" ); - } - } - - // blocked - results = pushResults; - results.fraction = 0.0f; - results.endAxis = clipModel->GetAxis(); - results.endpos = clipModel->GetOrigin(); - results.c.entityNum = check->entityNumber; - results.c.id = 0; - - if ( !wasEnabled ) { - clipModel->Disable(); - } - - return totalMass; - } - - if ( !wasEnabled ) { - clipModel->Disable(); - } - - return totalMass; -} - -#endif /* !NEW_PUSH */ - - -/* -============ -idPush::ClipPush - - Try to push other entities by moving the given entity. -============ -*/ -float idPush::ClipPush( trace_t &results, idEntity *pusher, const int flags, - const idVec3 &oldOrigin, const idMat3 &oldAxis, - idVec3 &newOrigin, idMat3 &newAxis ) { - idVec3 translation; - idRotation rotation; - float mass; - - mass = 0.0f; - - results.fraction = 1.0f; - results.endpos = newOrigin; - results.endAxis = newAxis; - memset( &results.c, 0, sizeof( results.c ) ); - - // translational push - translation = newOrigin - oldOrigin; - - // if the pusher translates - if ( translation != vec3_origin ) { - - mass += ClipTranslationalPush( results, pusher, flags, newOrigin, translation ); - if ( results.fraction < 1.0f ) { - newOrigin = oldOrigin; - newAxis = oldAxis; - return mass; - } - } else { - newOrigin = oldOrigin; - } - - // rotational push - rotation = ( oldAxis.Transpose() * newAxis ).ToRotation(); - rotation.SetOrigin( newOrigin ); - rotation.Normalize180(); - rotation.ReCalculateMatrix(); // recalculate the rotation matrix to avoid accumulating rounding errors - - // if the pusher rotates - if ( rotation.GetAngle() != 0.0f ) { - - // recalculate new axis to avoid floating point rounding problems - newAxis = oldAxis * rotation.ToMat3(); - newAxis.OrthoNormalizeSelf(); - newAxis.FixDenormals(); - newAxis.FixDegeneracies(); - - pusher->GetPhysics()->GetClipModel()->SetPosition( newOrigin, oldAxis ); - - mass += ClipRotationalPush( results, pusher, flags, newAxis, rotation ); - if ( results.fraction < 1.0f ) { - newOrigin = oldOrigin; - newAxis = oldAxis; - return mass; - } - } else { - newAxis = oldAxis; - } - - return mass; -} diff --git a/game/physics/push.h b/game/physics/push.h deleted file mode 100644 index 3b6963b21..000000000 --- a/game/physics/push.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PUSH_H__ -#define __PUSH_H__ - -/* -=============================================================================== - - Allows physics objects to be pushed geometrically. - -=============================================================================== -*/ - -#define PUSHFL_ONLYMOVEABLE 1 // only push moveable entities -#define PUSHFL_NOGROUNDENTITIES 2 // don't push entities the clip model rests upon -#define PUSHFL_CLIP 4 // also clip against all non-moveable entities -#define PUSHFL_CRUSH 8 // kill blocking entities -#define PUSHFL_APPLYIMPULSE 16 // apply impulse to pushed entities -#define PUSHFL_NOPLAYER 32 // greebo: Don't push player entities - -//#define NEW_PUSH - -class idPush { -public: - // Try to push other entities by moving the given entity. - // If results.fraction < 1.0 the move was blocked by results.c.entityNum - // Returns total mass of all pushed entities. - float ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags, - const idVec3 &newOrigin, const idVec3 &move, float ImpulseMod = 1.0f ); - - float ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags, - const idMat3 &newAxis, const idRotation &rotation ); - - float ClipPush( trace_t &results, idEntity *pusher, const int flags, - const idVec3 &oldOrigin, const idMat3 &oldAxis, - idVec3 &newOrigin, idMat3 &newAxis ); - - // initialize saving the positions of entities being pushed - void InitSavingPushedEntityPositions( void ); - // move all pushed entities back to their previous position - void RestorePushedEntityPositions( void ); - // returns the number of pushed entities - int GetNumPushedEntities( void ) const { return numPushed; } - // get the ith pushed entity - idEntity * GetPushedEntity( int i ) const { assert( i >= 0 && i < numPushed ); return pushed[i].ent; } - -private: - struct pushed_s { - idEntity * ent; // pushed entity - idAngles deltaViewAngles; // actor delta view angles - } pushed[MAX_GENTITIES]; // pushed entities - int numPushed; // number of pushed entities - - struct pushedGroup_s { - idEntity * ent; - float fraction; - bool groundContact; - bool test; - } pushedGroup[MAX_GENTITIES]; - int pushedGroupSize; - -private: - void SaveEntityPosition( idEntity *ent ); - bool RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint ); -#ifdef NEW_PUSH - bool CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags ); - void AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact ); - bool IsFullyPushed( idEntity *ent ); - bool ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation ); - int GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags, - const idVec3 &translation, idEntity *entityList[], int maxEntities ); - bool ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation ); - int GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags, - const idRotation &rotation, idEntity *entityList[], int maxEntities ); -#else - void ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, - idClipModel *skip, const idRotation &rotation ); - void ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel, - idClipModel *skip, const idVec3 &translation ); - int TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, - const idVec3 &newOrigin, const idVec3 &move ); - int TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags, - const idMat3 &newAxis, const idRotation &rotation ); - int DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher ); -#endif -}; - -#endif /* !__PUSH_H__ */ diff --git a/game/player.cpp b/game/player.cpp deleted file mode 100644 index 46b4f5334..000000000 --- a/game/player.cpp +++ /dev/null @@ -1,11456 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -#pragma warning(disable : 4355) // greebo: Disable warning "'this' used in constructor" - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "ai/aas_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Grabber.h" -#include "../DarkMod/Intersection.h" -#include "../DarkMod/Relations.h" -#include "../DarkMod/DarkmodAASHidingSpotFinder.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/Missions/MissionManager.h" -#include "../DarkMod/Inventory/Inventory.h" -#include "../DarkMod/Inventory/WeaponItem.h" -#include "../DarkMod/Shop/Shop.h" - -/* -=============================================================================== - - Player control of the TDM player thief. - This object handles all player movement and world interaction. - -=============================================================================== -*/ - -// amount of health per dose from the health station -const int HEALTH_PER_DOSE = 10; - -// time before a weapon dropped to the floor disappears -const int WEAPON_DROP_TIME = 20 * 1000; - -// time before a next or prev weapon switch happens -const int WEAPON_SWITCH_DELAY = 150; - -// how many units to raise spectator above default view height so it's in the head of someone -const int SPECTATE_RAISE = 25; - -const int HEALTHPULSE_TIME = 333; - -// minimum speed to bob and play run/walk animations at -const float MIN_BOB_SPEED = 5.0f; - -// shouldered body immobilizations -const int SHOULDER_IMMOBILIZATIONS = EIM_CLIMB | EIM_ITEM_SELECT | EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_USE | EIM_MANTLE | EIM_FROB_COMPLEX; -const float SHOULDER_JUMP_HINDERANCE = 0.25f; - -const idEventDef EV_Player_GetButtons( "getButtons", NULL, 'd' ); -const idEventDef EV_Player_GetMove( "getMove", NULL, 'v' ); -const idEventDef EV_Player_GetViewAngles( "getViewAngles", NULL, 'v' ); -const idEventDef EV_Player_GetMouseGesture( "getMouseGesture", NULL, 'd'); -const idEventDef EV_Player_MouseGestureFinished( "mouseGestureFinished", NULL, 'd' ); -const idEventDef EV_Player_ClearMouseDeadTime("clearMouseDeadTime"); -const idEventDef EV_Player_StartMouseGesture( "startMouseGesture", "ddddfdd" ); -const idEventDef EV_Player_StopMouseGesture( "stopMouseGesture" ); -const idEventDef EV_Player_StopFxFov( "stopFxFov" ); -const idEventDef EV_Player_EnableWeapon( "enableWeapon" ); -const idEventDef EV_Player_DisableWeapon( "disableWeapon" ); -const idEventDef EV_Player_GetCurrentWeapon( "getCurrentWeapon", NULL, 's' ); -const idEventDef EV_Player_GetPreviousWeapon( "getPreviousWeapon", NULL, 's' ); -const idEventDef EV_Player_SelectWeapon( "selectWeapon", "s" ); -const idEventDef EV_Player_GetWeaponEntity( "getWeaponEntity", NULL, 'e' ); -const idEventDef EV_Player_ExitTeleporter( "exitTeleporter" ); -const idEventDef EV_SpectatorTouch( "spectatorTouch", "et" ); -const idEventDef EV_Player_GetIdealWeapon( "getIdealWeapon", NULL, 's' ); - -const idEventDef EV_Player_GetEyePos( "getEyePos", NULL, 'v' ); -const idEventDef EV_Player_SetImmobilization( "setImmobilization", "sd" ); -const idEventDef EV_Player_GetImmobilization( "getImmobilization", "s", 'd' ); -const idEventDef EV_Player_GetNextImmobilization( "getNextImmobilization", "ss", 's' ); -const idEventDef EV_Player_SetHinderance( "setHinderance", "sff" ); -const idEventDef EV_Player_GetHinderance( "getHinderance", "s", 'v' ); -const idEventDef EV_Player_GetNextHinderance( "getNextHinderance", "ss", 's' ); -const idEventDef EV_Player_SetTurnHinderance( "setTurnHinderance", "sff" ); -const idEventDef EV_Player_GetTurnHinderance( "getTurnHinderance", "s", 'v' ); -const idEventDef EV_Player_GetNextTurnHinderance( "getNextTurnHinderance", "ss", 's' ); - -const idEventDef EV_Player_SetGui( "setGui", "ds" ); -const idEventDef EV_Player_GetInventoryOverlay( "getInventoryOverlay", NULL, 'd' ); - -const idEventDef EV_Player_PlayStartSound( "playStartSound", NULL ); -const idEventDef EV_Player_MissionFailed("missionFailed", NULL ); -const idEventDef EV_Player_CustomDeath("customDeath", NULL ); -const idEventDef EV_Player_DeathMenu("deathMenu", NULL ); -const idEventDef EV_Player_HoldEntity( "holdEntity", "E", 'f' ); -const idEventDef EV_Player_HeldEntity( "heldEntity", NULL, 'E' ); - -const idEventDef EV_Player_RopeRemovalCleanup( "ropeRemovalCleanup", "e" ); -// NOTE: The following all take the "user" objective indices, starting at 1 instead of 0 -const idEventDef EV_Player_SetObjectiveState( "setObjectiveState", "dd" ); -const idEventDef EV_Player_GetObjectiveState( "getObjectiveState", "d", 'd'); -const idEventDef EV_Player_SetObjectiveComp( "setObjectiveComp", "ddd" ); -const idEventDef EV_Player_GetObjectiveComp( "getObjectiveComp", "dd", 'd' ); -const idEventDef EV_Player_ObjectiveUnlatch( "objectiveUnlatch", "d" ); -const idEventDef EV_Player_ObjectiveCompUnlatch( "objectiveCompUnlatch", "dd" ); -const idEventDef EV_Player_SetObjectiveVisible( "setObjectiveVisible", "dd" ); -const idEventDef EV_Player_SetObjectiveOptional( "setObjectiveOptional", "dd" ); -const idEventDef EV_Player_SetObjectiveOngoing( "setObjectiveOngoing", "dd" ); -const idEventDef EV_Player_SetObjectiveEnabling( "setObjectiveEnabling", "ds" ); -// greebo: This allows scripts to set the "healthpool" for gradual healing -const idEventDef EV_Player_GiveHealthPool("giveHealthPool", "f"); -const idEventDef EV_Player_WasDamaged("wasDamaged", NULL, 'd'); - -const idEventDef EV_Mission_Success("missionSuccess", NULL); -const idEventDef EV_TriggerMissionEnd("triggerMissionEnd", NULL); -const idEventDef EV_DisconnectFromMission("_disconnectFromMission", NULL); - -// Private event to process intermission triggers -const idEventDef EV_ProcessInterMissionTriggers("_processInterMissionTriggers"); - -const idEventDef EV_GetLocation("getLocation", NULL, 'e'); - -// greebo: These events are handling the FOV. -const idEventDef EV_Player_StartZoom("startZoom", "fff"); -const idEventDef EV_Player_EndZoom("endZoom", "f"); -const idEventDef EV_Player_ResetZoom("resetZoom", NULL); -const idEventDef EV_Player_GetFov("getFov", NULL, 'f'); - -const idEventDef EV_Player_PauseGame("pauseGame", NULL); -const idEventDef EV_Player_UnpauseGame("unpauseGame", NULL); -const idEventDef EV_Player_StartGamePlayTimer("startGamePlayTimer", NULL); - -const idEventDef EV_CheckAAS("checkAAS", NULL); - -// greebo: Allows scripts to set a named lightgem modifier to a certain value (e.g. "lantern" => 32) -const idEventDef EV_Player_SetLightgemModifier("setLightgemModifier", "sd"); -const idEventDef EV_ReadLightgemModifierFromWorldspawn("readLightgemModifierFromWorldspawn", NULL); - -// greebo: Changes the projectile entityDef name of the given weapon (e.g. "broadhead"). -const idEventDef EV_ChangeWeaponProjectile("changeWeaponProjectile", "ss", NULL); -const idEventDef EV_ResetWeaponProjectile("resetWeaponProjectile", "s", NULL); -const idEventDef EV_ChangeWeaponName("changeWeaponName", "ss", NULL); -const idEventDef EV_GetCurWeaponName("getCurWeaponName", NULL, 's'); -const idEventDef EV_SetActiveInventoryMapEnt("setActiveInventoryMapEnt", "e"); -const idEventDef EV_ClearActiveInventoryMap("clearActiveInventoryMap", NULL); - -// ishtvan: Let scripts get the currently frobbed entity, and set "frob only used by" mode -const idEventDef EV_Player_GetFrobbed("getFrobbed", NULL, 'e'); -const idEventDef EV_Player_SetFrobOnlyUsedByInv("setFrobOnlyUsedByInv", "d", NULL); - -CLASS_DECLARATION( idActor, idPlayer ) - EVENT( EV_Player_GetButtons, idPlayer::Event_GetButtons ) - EVENT( EV_Player_GetMove, idPlayer::Event_GetMove ) - EVENT( EV_Player_GetViewAngles, idPlayer::Event_GetViewAngles ) - EVENT( EV_Player_GetMouseGesture, idPlayer::Event_GetMouseGesture ) - EVENT( EV_Player_MouseGestureFinished, idPlayer::Event_MouseGestureFinished ) - EVENT( EV_Player_StartMouseGesture, idPlayer::StartMouseGesture ) - EVENT( EV_Player_StopMouseGesture, idPlayer::StopMouseGesture ) - EVENT( EV_Player_ClearMouseDeadTime, idPlayer::Event_ClearMouseDeadTime ) - EVENT( EV_Player_StopFxFov, idPlayer::Event_StopFxFov ) - EVENT( EV_Player_EnableWeapon, idPlayer::Event_EnableWeapon ) - EVENT( EV_Player_DisableWeapon, idPlayer::Event_DisableWeapon ) - EVENT( EV_Player_GetCurrentWeapon, idPlayer::Event_GetCurrentWeapon ) - EVENT( EV_Player_GetPreviousWeapon, idPlayer::Event_GetPreviousWeapon ) - EVENT( EV_Player_SelectWeapon, idPlayer::Event_SelectWeapon ) - EVENT( EV_Player_GetWeaponEntity, idPlayer::Event_GetWeaponEntity ) - EVENT( EV_Player_ExitTeleporter, idPlayer::Event_ExitTeleporter ) - EVENT( EV_Gibbed, idPlayer::Event_Gibbed ) - - EVENT( EV_Player_GetEyePos, idPlayer::Event_GetEyePos ) - EVENT( EV_Player_SetImmobilization, idPlayer::Event_SetImmobilization ) - EVENT( EV_Player_GetImmobilization, idPlayer::Event_GetImmobilization ) - EVENT( EV_Player_GetNextImmobilization, idPlayer::Event_GetNextImmobilization ) - EVENT( EV_Player_SetHinderance, idPlayer::Event_SetHinderance ) - EVENT( EV_Player_GetHinderance, idPlayer::Event_GetHinderance ) - EVENT( EV_Player_GetNextHinderance, idPlayer::Event_GetNextHinderance ) - EVENT( EV_Player_SetTurnHinderance, idPlayer::Event_SetTurnHinderance ) - EVENT( EV_Player_GetTurnHinderance, idPlayer::Event_GetTurnHinderance ) - EVENT( EV_Player_GetNextTurnHinderance, idPlayer::Event_GetNextTurnHinderance ) - - EVENT( EV_Player_SetGui, idPlayer::Event_SetGui ) - EVENT( EV_Player_GetInventoryOverlay, idPlayer::Event_GetInventoryOverlay ) - - EVENT( EV_Player_PlayStartSound, idPlayer::Event_PlayStartSound ) - EVENT( EV_Player_MissionFailed, idPlayer::Event_MissionFailed ) - EVENT( EV_Player_CustomDeath, idPlayer::Event_CustomDeath ) - EVENT( EV_Player_DeathMenu, idPlayer::Event_LoadDeathMenu ) - EVENT( EV_Player_HoldEntity, idPlayer::Event_HoldEntity ) - EVENT( EV_Player_HeldEntity, idPlayer::Event_HeldEntity ) - EVENT( EV_Player_RopeRemovalCleanup, idPlayer::Event_RopeRemovalCleanup ) - EVENT( EV_Player_SetObjectiveState, idPlayer::Event_SetObjectiveState ) - EVENT( EV_Player_GetObjectiveState, idPlayer::Event_GetObjectiveState ) - EVENT( EV_Player_SetObjectiveComp, idPlayer::Event_SetObjectiveComp ) - EVENT( EV_Player_GetObjectiveComp, idPlayer::Event_GetObjectiveComp ) - EVENT( EV_Player_ObjectiveUnlatch, idPlayer::Event_ObjectiveUnlatch ) - EVENT( EV_Player_ObjectiveCompUnlatch, idPlayer::Event_ObjectiveComponentUnlatch ) - EVENT( EV_Player_SetObjectiveVisible, idPlayer::Event_SetObjectiveVisible ) - EVENT( EV_Player_SetObjectiveOptional, idPlayer::Event_SetObjectiveOptional ) - EVENT( EV_Player_SetObjectiveOngoing, idPlayer::Event_SetObjectiveOngoing ) - EVENT( EV_Player_SetObjectiveEnabling, idPlayer::Event_SetObjectiveEnabling ) - - EVENT( EV_Player_GiveHealthPool, idPlayer::Event_GiveHealthPool ) - EVENT( EV_Player_WasDamaged, idPlayer::Event_WasDamaged ) - - EVENT( EV_Player_SetLightgemModifier, idPlayer::Event_SetLightgemModifier ) - EVENT( EV_ReadLightgemModifierFromWorldspawn, idPlayer::Event_ReadLightgemModifierFromWorldspawn ) - - EVENT( EV_Player_StartZoom, idPlayer::Event_StartZoom ) - EVENT( EV_Player_EndZoom, idPlayer::Event_EndZoom ) - EVENT( EV_Player_ResetZoom, idPlayer::Event_ResetZoom ) - EVENT( EV_Player_GetFov, idPlayer::Event_GetFov ) - - // Events needed for the Objectives GUI (is a blocking GUI - pauses the game) - EVENT( EV_Player_PauseGame, idPlayer::Event_Pausegame ) - EVENT( EV_Player_UnpauseGame, idPlayer::Event_Unpausegame ) - EVENT( EV_Player_StartGamePlayTimer, idPlayer::Event_StartGamePlayTimer ) - - EVENT( EV_Mission_Success, idPlayer::Event_MissionSuccess) - EVENT( EV_TriggerMissionEnd, idPlayer::Event_TriggerMissionEnd ) - EVENT( EV_DisconnectFromMission, idPlayer::Event_DisconnectFromMission ) - - EVENT( EV_GetLocation, idPlayer::Event_GetLocation ) - - EVENT( EV_ChangeWeaponProjectile, idPlayer::Event_ChangeWeaponProjectile ) - EVENT( EV_ResetWeaponProjectile, idPlayer::Event_ResetWeaponProjectile ) - EVENT( EV_ChangeWeaponName, idPlayer::Event_ChangeWeaponName ) - EVENT( EV_GetCurWeaponName, idPlayer::Event_GetCurWeaponName ) - EVENT( EV_SetActiveInventoryMapEnt, idPlayer::Event_SetActiveInventoryMapEnt ) - EVENT( EV_ClearActiveInventoryMap, idPlayer::Event_ClearActiveInventoryMap ) - - EVENT( EV_Player_GetFrobbed, idPlayer::Event_GetFrobbed ) - EVENT( EV_Player_SetFrobOnlyUsedByInv, idPlayer::Event_SetFrobOnlyUsedByInv ) - - EVENT( EV_ProcessInterMissionTriggers, idPlayer::Event_ProcessInterMissionTriggers ) - EVENT( EV_CheckAAS, idPlayer::Event_CheckAAS ) - -END_CLASS - -const int MAX_RESPAWN_TIME = 10000; -const int RAGDOLL_DEATH_TIME = 3000; -const int STEPUP_TIME = 200; - -idVec3 idPlayer::colorBarTable[ 5 ] = { - idVec3( 0.25f, 0.25f, 0.25f ), - idVec3( 1.00f, 0.00f, 0.00f ), - idVec3( 0.00f, 0.80f, 0.10f ), - idVec3( 0.20f, 0.50f, 0.80f ), - idVec3( 1.00f, 0.80f, 0.10f ) -}; - -/* -============== -idPlayer::idPlayer -============== -*/ -idPlayer::idPlayer() : - m_ButtonStateTracker(this) -{ - memset( &usercmd, 0, sizeof( usercmd ) ); - - noclip = false; - godmode = false; - - spawnAnglesSet = false; - spawnAngles = ang_zero; - viewAngles = ang_zero; - cmdAngles = ang_zero; - - oldButtons = 0; - buttonMask = 0; - oldFlags = 0; - - lastHitTime = 0; - lastSndHitTime = 0; - lastSavingThrowTime = 0; - - lockpickHUD = 0; - - hasLanded = false; - - weapon = NULL; - - hud = NULL; - inventoryHUDNeedsUpdate = true; - - heartRate = BASE_HEARTRATE; - heartInfo.Init( 0, 0, 0, 0 ); - lastHeartAdjust = 0; - lastHeartBeat = 0; - lastDmgTime = 0; - deathClearContentsTime = 0; - lastArmorPulse = -10000; - stamina = 0.0f; - healthPool = 0.0f; - nextHealthPulse = 0; - healthPulse = false; - nextHealthTake = 0; - healthTake = false; - healthPoolTimeInterval = HEALTHPULSE_TIME; - healthPoolTimeIntervalFactor = 1.0f; - healthPoolStepAmount = 5; - - scoreBoardOpen = false; - forceScoreBoard = false; - forceRespawn = false; - spectating = false; - spectator = 0; - colorBar = vec3_zero; - colorBarIndex = 0; - forcedReady = false; - wantSpectate = false; - - lastHitToggle = false; - - minRespawnTime = 0; - maxRespawnTime = 0; - - m_WaitUntilReadyGuiHandle = OVERLAYS_INVALID_HANDLE; - m_WaitUntilReadyGuiTime = 0; - - firstPersonViewOrigin = vec3_zero; - firstPersonViewAxis = mat3_identity; - - hipJoint = INVALID_JOINT; - chestJoint = INVALID_JOINT; - headJoint = INVALID_JOINT; - - bobFoot = 0; - bobFrac = 0.0f; - bobfracsin = 0.0f; - bobCycle = 0; - xyspeed = 0.0f; - stepUpTime = 0; - stepUpDelta = 0.0f; - idealLegsYaw = 0.0f; - legsYaw = 0.0f; - legsForward = true; - oldViewYaw = 0.0f; - viewBobAngles = ang_zero; - viewBob = vec3_zero; - landChange = 0; - landTime = 0; - lastFootstepPlaytime = -1; - - currentWeapon = -1; - idealWeapon = -1; - previousWeapon = -1; - weaponSwitchTime = 0; - weaponEnabled = true; - weapon_fists = -1; - showWeaponViewModel = true; - - skin = NULL; - powerUpSkin = NULL; - baseSkinName = ""; - - numProjectilesFired = 0; - numProjectileHits = 0; - - airless = false; - airTics = 0; - lastAirDamage = 0; - underWaterEffectsActive = false; - underWaterGUIHandle = -1; - - gibDeath = false; - gibsLaunched = false; - gibsDir = vec3_zero; - - zoomFov.Init( 0, 0, 0, 0 ); - centerView.Init( 0, 0, 0, 0 ); - fxFov = false; - - influenceFov = 0; - influenceActive = 0; - influenceRadius = 0.0f; - influenceEntity = NULL; - influenceMaterial = NULL; - influenceSkin = NULL; - - privateCameraView = NULL; - - m_ListenerLoc = vec3_zero; - m_DoorListenLoc = vec3_zero; - - // m_immobilization.Clear(); - m_immobilizationCache = 0; - - // m_hinderance.Clear(); - m_hinderanceCache = 1.0f; - m_TurnHinderanceCache = 1.0f; - m_JumpHinderanceCache = 1.0f; - - memset( loggedViewAngles, 0, sizeof( loggedViewAngles ) ); - memset( loggedAccel, 0, sizeof( loggedAccel ) ); - currentLoggedAccel = 0; - -#if 0 - focusTime = 0; - focusGUIent = NULL; - focusUI = NULL; - focusCharacter = NULL; - talkCursor = 0; - focusVehicle = NULL; -#endif - cursor = NULL; - - oldMouseX = 0; - oldMouseY = 0; - - lastDamageDef = 0; - lastDamageDir = vec3_zero; - lastDamageLocation = 0; - m_bDamagedThisFrame = false; - smoothedFrame = 0; - smoothedOriginUpdated = false; - smoothedOrigin = vec3_zero; - smoothedAngles = ang_zero; - - fl.networkSync = true; - - latchedTeam = -1; - doingDeathSkin = false; - weaponGone = false; - useInitialSpawns = false; - tourneyRank = 0; - lastSpectateTeleport = 0; - tourneyLine = 0; - hiddenWeapon = false; - tipUp = false; - teleportEntity = NULL; - teleportKiller = -1; - respawning = false; - ready = false; - leader = false; - lastSpectateChange = 0; - lastTeleFX = -9999; - weaponCatchup = false; - lastSnapshotSequence = 0; - - MPAim = -1; - lastMPAim = -1; - lastMPAimTime = 0; - MPAimFadeTime = 0; - MPAimHighlight = false; - - spawnedTime = 0; - lastManOver = false; - lastManPlayAgain = false; - lastManPresent = false; - - isTelefragged = false; - - isLagged = false; - isChatting = false; - selfSmooth = false; - - m_FrobPressedTarget = NULL; - - m_FrobEntity = NULL; - m_FrobJoint = INVALID_JOINT; - m_FrobID = 0; - // greebo: Initialise the frob trace contact material to avoid - // crashing during map save when nothing has been frobbed yet - memset(&m_FrobTrace, 0, sizeof(trace_t)); - m_bFrobOnlyUsedByInv = false; - - m_bGrabberActive = false; - m_bDraggingBody = false; - m_bShoulderingBody = false; - - m_IdealCrouchState = false; - m_CrouchIntent = false; - - m_LeanButtonTimeStamp = 0; - m_InventoryOverlay = -1; - objectivesOverlay = -1; - m_WeaponCursor = CInventoryCursorPtr(); - m_MapCursor = CInventoryCursorPtr(); - m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; - - m_LightgemModifier = 0; - m_LightgemValue = 0; - m_fColVal = 0; - m_fBlendColVal = 0; - m_LightgemInterleave = 0; - ignoreWeaponAttack = false; // grayman #597 -} - -/* -============== -idPlayer::LinkScriptVariables - -set up conditions for animation -============== -*/ -void idPlayer::LinkScriptVariables() -{ - // Call the base class first - idActor::LinkScriptVariables(); - - AI_FORWARD.LinkTo( scriptObject, "AI_FORWARD" ); - AI_BACKWARD.LinkTo( scriptObject, "AI_BACKWARD" ); - AI_STRAFE_LEFT.LinkTo( scriptObject, "AI_STRAFE_LEFT" ); - AI_STRAFE_RIGHT.LinkTo( scriptObject, "AI_STRAFE_RIGHT" ); - AI_ATTACK_HELD.LinkTo( scriptObject, "AI_ATTACK_HELD" ); - AI_BLOCK_HELD.LinkTo( scriptObject, "AI_BLOCK_HELD" ); - AI_WEAPON_FIRED.LinkTo( scriptObject, "AI_WEAPON_FIRED" ); - AI_WEAPON_BLOCKED.LinkTo( scriptObject, "AI_WEAPON_BLOCKED" ); - AI_JUMP.LinkTo( scriptObject, "AI_JUMP" ); - AI_CROUCH.LinkTo( scriptObject, "AI_CROUCH" ); - AI_ONGROUND.LinkTo( scriptObject, "AI_ONGROUND" ); - AI_ONLADDER.LinkTo( scriptObject, "AI_ONLADDER" ); - AI_HARDLANDING.LinkTo( scriptObject, "AI_HARDLANDING" ); - AI_SOFTLANDING.LinkTo( scriptObject, "AI_SOFTLANDING" ); - AI_RUN.LinkTo( scriptObject, "AI_RUN" ); - AI_PAIN.LinkTo( scriptObject, "AI_PAIN" ); - AI_RELOAD.LinkTo( scriptObject, "AI_RELOAD" ); - AI_TELEPORT.LinkTo( scriptObject, "AI_TELEPORT" ); - AI_TURN_LEFT.LinkTo( scriptObject, "AI_TURN_LEFT" ); - AI_TURN_RIGHT.LinkTo( scriptObject, "AI_TURN_RIGHT" ); - AI_LEAN_LEFT.LinkTo( scriptObject, "AI_LEAN_LEFT" ); - AI_LEAN_RIGHT.LinkTo( scriptObject, "AI_LEAN_RIGHT" ); - AI_LEAN_FORWARD.LinkTo( scriptObject, "AI_LEAN_FORWARD" ); - AI_CREEP.LinkTo( scriptObject, "AI_CREEP" ); -} - -/* -============== -idPlayer::SetupWeaponEntity -============== -*/ -void idPlayer::SetupWeaponEntity() -{ - if ( weapon.GetEntity() ) { - // get rid of old weapon - weapon.GetEntity()->Clear(); - currentWeapon = -1; - } - else if ( !gameLocal.isClient ) { - weapon = static_cast( gameLocal.SpawnEntityType( idWeapon::Type, NULL ) ); - weapon.GetEntity()->SetOwner( this ); - currentWeapon = -1; - } - - for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) - { - if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs - - idWeapon::CacheWeapon(kv->GetValue()); - } -} - -/* -============== -idPlayer::Init -============== -*/ -void idPlayer::Init( void ) { - const char *value; - const idKeyValue *kv; - - noclip = false; - godmode = false; - - oldButtons = 0; - oldFlags = 0; - - currentWeapon = -1; - idealWeapon = 0; - previousWeapon = -1; - weaponSwitchTime = 0; - weaponEnabled = true; - weapon_fists = 0;//SlotForWeapon( "weapon_fists" ); - showWeaponViewModel = GetUserInfo()->GetBool( "ui_showGun" ); - - lastDmgTime = 0; - lastArmorPulse = -10000; - lastHeartAdjust = 0; - lastHeartBeat = 0; - heartInfo.Init( 0, 0, 0, 0 ); - - bobCycle = 0; - bobFrac = 0.0f; - landChange = 0; - landTime = 0; - lastFootstepPlaytime = -1; - isPushing = false; - zoomFov.Init( 0, 0, 0, 0 ); - - centerView.Init( 0, 0, 0, 0 ); - fxFov = false; - - influenceFov = 0; - influenceActive = 0; - influenceRadius = 0.0f; - influenceEntity = NULL; - influenceMaterial = NULL; - influenceSkin = NULL; - - currentLoggedAccel = 0; - -#if 0 - focusTime = 0; - focusGUIent = NULL; - focusUI = NULL; - focusCharacter = NULL; - talkCursor = 0; - focusVehicle = NULL; -#endif - - // remove any damage effects - playerView.ClearEffects(); - - // damage values - fl.takedamage = true; - ClearPain(); - - // restore persistent data - RestorePersistantInfo(); - - bobCycle = 0; - stamina = 0.0f; - healthPool = 0.0f; - nextHealthPulse = 0; - healthPulse = false; - nextHealthTake = 0; - healthTake = false; - - SetupWeaponEntity(); - currentWeapon = -1; - previousWeapon = -1; - - heartRate = BASE_HEARTRATE; - AdjustHeartRate( BASE_HEARTRATE, 0.0f, 0.0f, true ); - - idealLegsYaw = 0.0f; - legsYaw = 0.0f; - legsForward = true; - oldViewYaw = 0.0f; - - // set the pm_ cvars - if ( !gameLocal.isMultiplayer || gameLocal.isServer ) { - kv = spawnArgs.MatchPrefix( "pm_", NULL ); - while( kv ) { - cvarSystem->SetCVarString( kv->GetKey(), kv->GetValue() ); - kv = spawnArgs.MatchPrefix( "pm_", kv ); - } - } - - // Commented out by Dram. TDM does not use stamina -/* - // disable stamina on hell levels - if ( gameLocal.world && gameLocal.world->spawnArgs.GetBool( "no_stamina" ) ) { - pm_stamina.SetFloat( 0.0f ); - } - - // stamina always initialized to maximum - stamina = pm_stamina.GetFloat(); -*/ - stamina = 0.0f; // Set stamina to 0 - Dram - - // air always initialized to maximum too - airTics = pm_airTics.GetInteger(); - airless = false; - - gibDeath = false; - gibsLaunched = false; - gibsDir.Zero(); - - // set the gravity - physicsObj.SetGravity( gameLocal.GetGravity() ); - - // start out standing - SetEyeHeight( pm_normalviewheight.GetFloat() ); - - stepUpTime = 0; - stepUpDelta = 0.0f; - viewBobAngles.Zero(); - viewBob.Zero(); - - value = spawnArgs.GetString( "model" ); - if ( value && ( *value != 0 ) ) { - SetModel( value ); - } - - if ( cursor ) { - cursor->SetStateInt( "talkcursor", 0 ); - cursor->SetStateString( "combatcursor", "1" ); - cursor->SetStateString( "itemcursor", "0" ); - cursor->SetStateString( "guicursor", "0" ); - } - - if ( ( gameLocal.isMultiplayer || g_testDeath.GetBool() ) && skin ) { - SetSkin( skin ); - renderEntity.shaderParms[6] = 0.0f; - } else if ( spawnArgs.GetString( "spawn_skin", NULL, &value ) ) { - skin = declManager->FindSkin( value ); - SetSkin( skin ); - renderEntity.shaderParms[6] = 0.0f; - } - - value = spawnArgs.GetString( "bone_hips", "" ); - hipJoint = animator.GetJointHandle( value ); - if ( hipJoint == INVALID_JOINT ) { - gameLocal.Error( "Joint '%s' not found for 'bone_hips' on '%s'", value, name.c_str() ); - } - - value = spawnArgs.GetString( "bone_chest", "" ); - chestJoint = animator.GetJointHandle( value ); - if ( chestJoint == INVALID_JOINT ) { - gameLocal.Error( "Joint '%s' not found for 'bone_chest' on '%s'", value, name.c_str() ); - } - - value = spawnArgs.GetString( "bone_head", "" ); - headJoint = animator.GetJointHandle( value ); - if ( headJoint == INVALID_JOINT ) { - gameLocal.Error( "Joint '%s' not found for 'bone_head' on '%s'", value, name.c_str() ); - } - - // initialize the script variables - AI_FORWARD = false; - AI_BACKWARD = false; - AI_STRAFE_LEFT = false; - AI_STRAFE_RIGHT = false; - AI_ATTACK_HELD = false; - AI_BLOCK_HELD = false; - AI_WEAPON_FIRED = false; - AI_WEAPON_BLOCKED = false; - AI_JUMP = false; - AI_DEAD = false; - AI_CROUCH = false; - AI_ONGROUND = true; - AI_ONLADDER = false; - AI_HARDLANDING = false; - AI_SOFTLANDING = false; - AI_RUN = false; - AI_PAIN = false; - AI_RELOAD = false; - AI_TELEPORT = false; - AI_TURN_LEFT = false; - AI_TURN_RIGHT = false; - - AI_LEAN_LEFT = false; - AI_LEAN_RIGHT = false; - AI_LEAN_FORWARD = false; - - AI_CREEP = false; - - m_pathRank = 1000; // grayman #2345 - - // reset the script object - ConstructScriptObject(); - - // execute the script so the script object's constructor takes effect immediately - scriptThread->Execute(); - - forceScoreBoard = false; - forcedReady = false; - - privateCameraView = NULL; - - lastSpectateChange = 0; - lastTeleFX = -9999; - - hiddenWeapon = false; - tipUp = false; - teleportEntity = NULL; - teleportKiller = -1; - leader = false; - - SetPrivateCameraView( NULL ); - - lastSnapshotSequence = 0; - - MPAim = -1; - lastMPAim = -1; - lastMPAimTime = 0; - MPAimFadeTime = 0; - MPAimHighlight = false; - - if ( hud ) { - hud->HandleNamedEvent( "aim_clear" ); - } - - cvarSystem->SetCVarBool( "ui_chat", false ); -} - -/* -============== -idPlayer::Spawn - -Prepare any resources used by the player. -============== -*/ -void idPlayer::Spawn( void ) -{ - int i; - idStr temp; - idBounds bounds; - - if ( entityNumber >= MAX_CLIENTS ) { - gameLocal.Error( "entityNum > MAX_CLIENTS for player. Player may only be spawned with a client." ); - } - - // allow thinking during cinematics - cinematic = true; - - if ( gameLocal.isMultiplayer ) { - // always start in spectating state waiting to be spawned in - // do this before SetClipModel to get the right bounding box - spectating = true; - } - - maxHealth = spawnArgs.GetInt("maxhealth", "100"); - - m_immobilization.Clear(); - m_immobilizationCache = 0; - - m_hinderance.Clear(); - m_hinderanceCache = 1.0f; - - m_TurnHinderance.Clear(); - m_TurnHinderanceCache = 1.0f; - - // set our collision model - physicsObj.SetSelf( this ); - SetClipModel(); - physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) ); - physicsObj.SetContents( CONTENTS_BODY ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - physicsObj.SetClipMask( MASK_PLAYERSOLID ); - SetPhysics( &physicsObj ); - InitAASLocation(); - - skin = renderEntity.customSkin; - - // only the local player needs guis - if ( !gameLocal.isMultiplayer || entityNumber == gameLocal.localClientNum ) { - - // load HUD - if ( gameLocal.isMultiplayer ) { - // I need the HUD uniqued for the inventory code to interact with it. - //hud = uiManager->FindGui( "guis/mphud.gui", true, false, true ); - hud = uiManager->FindGui( "guis/mphud.gui", true, true ); - } else if ( spawnArgs.GetString( "hud", "", temp ) ) { - // I need the HUD uniqued for the inventory code to interact with it. - //hud = uiManager->FindGui( temp, true, false, true ); - hud = uiManager->FindGui( temp, true, true ); - } - if ( hud ) { - hud->Activate( true, gameLocal.time ); - } - - // load cursor - if ( spawnArgs.GetString( "cursor", "", temp ) ) { - cursor = uiManager->FindGui( temp, true, gameLocal.isMultiplayer, gameLocal.isMultiplayer ); - } - if ( cursor ) { - cursor->Activate( true, gameLocal.time ); - } - } - - // Remove entity GUIs from our overlay system. - for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) - m_overlays.destroyOverlay( OVERLAYS_MIN_HANDLE + i ); - // Add the HUD. - if ( m_overlays.createOverlay( 0, LAYER_MAIN_HUD ) >= OVERLAYS_MIN_HANDLE ) - m_overlays.setGui( OVERLAYS_MIN_HANDLE , hud ); - else - gameLocal.Warning( "Unable to create overlay for HUD.\n" ); - - SetLastHitTime( 0 ); - - // load the armor sound feedback - declManager->FindSound( "player_sounds_hitArmor" ); - - // set up conditions for animation - LinkScriptVariables(); - - animator.RemoveOriginOffset( true ); - - // initialize user info related settings - // on server, we wait for the userinfo broadcast, as this controls when the player is initially spawned in game - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) { - UserInfoChanged(false); - } - - // create combat collision hull for exact collision detection - SetCombatModel(); - - // init the damage effects - playerView.SetPlayerEntity( this ); - - // suppress model in non-player views, but allow it in mirrors and remote views - renderEntity.suppressSurfaceInViewID = entityNumber+1; - - // don't project shadow on self or weapon - renderEntity.noSelfShadow = true; - - idAFAttachment *headEnt = head.GetEntity(); - if ( headEnt ) { - headEnt->GetRenderEntity()->suppressSurfaceInViewID = entityNumber+1; - headEnt->GetRenderEntity()->noSelfShadow = true; - } - - if ( gameLocal.isMultiplayer ) - { - Init(); - Hide(); // properly hidden if starting as a spectator - if ( !gameLocal.isClient ) - { - // set yourself ready to spawn. idMultiplayerGame will decide when/if appropriate and call SpawnFromSpawnSpot - SetupWeaponEntity(); - SpawnFromSpawnSpot(); - forceRespawn = true; - assert( spectating ); - } - } - else - { - SetupWeaponEntity(); - SpawnFromSpawnSpot(); - } - - // trigger playtesting item gives, if we didn't get here from a previous level - // the devmap key will be set on the first devmap, but cleared on any level - // transitions - if ( !gameLocal.isMultiplayer && gameLocal.serverInfo.FindKey( "devmap" ) ) { - // fire a trigger with the name "devmap" - idEntity *ent = gameLocal.FindEntity( "devmap" ); - if ( ent ) { - ent->ActivateTargets( this ); - } - } - - if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) - { - hiddenWeapon = true; - if ( weapon.GetEntity() ) - weapon.GetEntity()->LowerWeapon(); - idealWeapon = 0; - } - else - hiddenWeapon = false; - - if ( hud ) - { - UpdateHudWeapon(); - hud->StateChanged( gameLocal.time ); - // greebo: Initialise the Message code on the HUD - hud->HandleNamedEvent("SetupMessageSystem"); - } - - tipUp = false; - - // copy step volumes over from cvars - UpdateMoveVolumes(); - - if ( !gameLocal.isMultiplayer ) - { - if ( g_skill.GetInteger() < 2 ) - { - if ( health < 25 ) - { - health = 25; - } - if ( g_useDynamicProtection.GetBool() ) - { - g_damageScale.SetFloat( 1.0f ); - } - } - else - { - g_damageScale.SetFloat( 1.0f ); - g_armorProtection.SetFloat( ( g_skill.GetInteger() < 2 ) ? 0.4f : 0.2f ); -#ifndef ID_DEMO_BUILD - if ( g_skill.GetInteger() == 3 ) - { - healthTake = true; - nextHealthTake = gameLocal.time + g_healthTakeTime.GetInteger() * 1000; - } -#endif - } - } - - lockpickHUD = CreateOverlay("guis/tdm_lockpick.gui", 20); - - // Clear the lightgem modifiers - m_LightgemModifierList.clear(); - - //FIX: Set the walkspeed back to the stored value. - pm_walkspeed.SetFloat( gameLocal.m_walkSpeed ); - SetupInventory(); - - // greebo: Set the player variable on the grabber - gameLocal.m_Grabber->SetPlayer(this); - - // greebo: Initialise the default fov. - zoomFov.Init(gameLocal.time, 0, g_fov.GetFloat(), g_fov.GetFloat()); - - // Post an event to read the LG modifier from the worldspawn entity - PostEventMS(&EV_ReadLightgemModifierFromWorldspawn, 0); - - // Process inter-mission triggers after the first few frames to ensure all entities have acquired their targets - PostEventMS(&EV_ProcessInterMissionTriggers, 48); - - // Start the gameplay timer half a second after spawn - PostEventMS(&EV_Player_StartGamePlayTimer, 500); - - // Check the AAS status - PostEventMS(&EV_CheckAAS, 0); -} - -CInventoryWeaponItemPtr idPlayer::GetCurrentWeaponItem() -{ - if (m_WeaponCursor == NULL) - { - return CInventoryWeaponItemPtr(); - } - - return boost::dynamic_pointer_cast(m_WeaponCursor->GetCurrentItem()); -} - -CInventoryWeaponItemPtr idPlayer::GetWeaponItem(const idStr& weaponName) -{ - if (m_WeaponCursor == NULL) - { - return CInventoryWeaponItemPtr(); - } - - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - if (weaponCategory == NULL) - { - return CInventoryWeaponItemPtr(); - } - - // Cycle through all available weapons and find the one with the given name - for (int i = 0; i < weaponCategory->GetNumItems(); ++i) - { - CInventoryWeaponItemPtr weapon = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); - - if (weapon != NULL && weaponName == weapon->GetWeaponName()) - { - return weapon; // Found! - } - } - - return CInventoryWeaponItemPtr(); -} - -void idPlayer::SortWeaponItems() -{ - // A local storage, to sort weapons by index - // This code is kind of cumbersome, the idList<>::Sort code is not really suitable for non-raw pointers - std::map weapons; - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Sorting weapon items.\r"); - - // Add it to the weapon category - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - for (int i = 0; i < weaponCategory->GetNumItems(); ++i) - { - CInventoryWeaponItemPtr item = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); - - if (item == NULL) continue; - - // Store the item in the map - weapons[item->GetWeaponIndex()] = item; - } - - // Finally, add all found weapons to our inventory category, sorted by their index - for (std::map::const_iterator i = weapons.begin(); i != weapons.end(); ++i) - { - // Remove first, will be pushed to back - weaponCategory->RemoveItem(i->second); - - // Add it to the weapon category - weaponCategory->PutItemBack(i->second); - } - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon items sorted, we have now %d items.\r", weaponCategory->GetNumItems()); -} - -void idPlayer::AddWeaponsToInventory() -{ - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) - { - if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs - - // Get the weapon index from the key by removing the prefix - idStr weaponNumStr = kv->GetKey(); - weaponNumStr.StripLeading("def_weapon"); - - if (weaponNumStr.IsEmpty() || !weaponNumStr.IsNumeric()) continue; // not a numeric weapon - - int weaponNum = atoi(weaponNumStr); - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Trying to add weapon as defined by key %s to inventory (index %d)\r", kv->GetKey().c_str(), weaponNum); - - idStr weaponDef(kv->GetValue()); - - if (gameLocal.FindEntityDefDict(weaponDef) == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Weapon entityDef not found: %s\r", weaponDef.c_str()); - continue; - } - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Adding weapon to inventory: %s\r", weaponDef.c_str()); - - // Allocate a new weapon item using the found entityDef - CInventoryWeaponItemPtr item(new CInventoryWeaponItem(weaponDef, this)); - - item->SetWeaponIndex(weaponNum); - - // Add it to the weapon category, will be sorted later on - weaponCategory->PutItemBack(item); - } - - SortWeaponItems(); - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Total number of weapons: %d\r", m_WeaponCursor->GetCurrentCategory()->GetNumItems()); -} - -void idPlayer::NextInventoryMap() -{ - if (GetImmobilization() & EIM_ITEM_SELECT) return; - - if (m_MapCursor == NULL) - { - return; // We have no cursor! - } - - CInventoryItemPtr prevMapItem = m_MapCursor->GetCurrentItem(); - - if (prevMapItem != NULL) - { - // We already have a map selected, toggle it off - UseInventoryItem(EPressed, prevMapItem, 0, false); - } - - // Clear any previously active maps - ClearActiveInventoryMap(); - - if (m_MapCursor->IsLastItemInCategory()) - { - // Reached last map, return without cycling to the next map - // Clear the item, so that we start afresh next time - m_MapCursor->ClearItem(); - return; - } - - // Advance the cursor to the next item - CInventoryItemPtr nextMapItem = m_MapCursor->GetNextItem(); - - if (nextMapItem != NULL && nextMapItem != prevMapItem) - { - // Use this new item - UseInventoryItem(EPressed, nextMapItem, 0, false); - } -} - -bool idPlayer::WaitUntilReady() -{ - if (IsReady() || !cv_player_waituntilready.GetBool()) - { - ready = true; - return true; - } - - // Create the overlay if necessary - if (m_WaitUntilReadyGuiHandle == OVERLAYS_INVALID_HANDLE) - { - m_WaitUntilReadyGuiHandle = CreateOverlay(cv_tdm_waituntilready_gui_file.GetString(), LAYER_WAITUNTILREADY); - - if (m_WaitUntilReadyGuiHandle == OVERLAYS_INVALID_HANDLE) - { - gameLocal.Warning("Cannot find wait-until-ready GUI %s", cv_tdm_waituntilready_gui_file.GetString()); - ready = true; - return ready; // done - } - } - - idUserInterface* gui = GetOverlay(m_WaitUntilReadyGuiHandle); - - // Make sure we have a valid mission number in the GUI, the first mission is always 1 - int missionNum = gameLocal.m_MissionManager->GetCurrentMissionIndex() + 1; - gui->SetStateInt("CurrentMission", missionNum); - - // Remember button state of the previous frame - oldButtons = usercmd.buttons; - - // grab out usercmd - usercmd_t oldCmd = usercmd; - usercmd = gameLocal.usercmds[ entityNumber ]; - buttonMask &= usercmd.buttons; - usercmd.buttons &= ~buttonMask; - - // Allow cursor movement in the GUI, even if it's hidden anyway - if (usercmd.mx != oldMouseX || usercmd.my != oldMouseY) - { - sysEvent_t ev = sys->GenerateMouseMoveEvent(usercmd.mx - oldMouseX, usercmd.my - oldMouseY); - gui->HandleEvent(&ev, m_WaitUntilReadyGuiTime); - oldMouseX = usercmd.mx; - oldMouseY = usercmd.my; - } - - // Allow attack button actions to be propagated to the GUI - if ((oldButtons ^ usercmd.buttons) & BUTTON_ATTACK) - { - bool updateVisuals = false; - - sysEvent_t ev = sys->GenerateMouseButtonEvent(1, ( usercmd.buttons & BUTTON_ATTACK ) != 0); - idStr cmd = gui->HandleEvent(&ev, m_WaitUntilReadyGuiTime, &updateVisuals); - - if (cmd == "playerIsReady") - { - int delay = gui->GetStateInt("DestroyDelay"); - - PostEventMS(&EV_DestroyOverlay, delay, m_WaitUntilReadyGuiHandle); - - // We can safely disconnect the GUI handle now, it has been passed by value to the event system - m_WaitUntilReadyGuiHandle = OVERLAYS_INVALID_HANDLE; - - // We're handing control over to the Overlay System, add the time offset to the GUI - gui->SetStateInt("GuiTimeOffset", m_WaitUntilReadyGuiTime); - - // We're done here, the GUI will be doing it's stuff and be destroyed after the given delay - // In the meantime, the overlay system will issue a few Redraw() calls to the GUI using our time offset. - ready = true; - } - } - - // Redraw the GUI - gui->Redraw(m_WaitUntilReadyGuiTime); - - // Increase the "private" GUI time - m_WaitUntilReadyGuiTime += gameLocal.msec; - - return ready; -} - -void idPlayer::CreateObjectivesGUI() -{ - if (objectivesOverlay != -1) return; - - objectivesOverlay = CreateOverlay(cv_tdm_obj_gui_file.GetString(), LAYER_OBJECTIVES); - - idUserInterface* objGUI = GetOverlay(objectivesOverlay); - - if (objGUI == NULL) - { - gameLocal.Error("Failed setting up objectives GUI: %s", cv_tdm_obj_gui_file.GetString()); - return; - } - - objGUI->HandleNamedEvent("InitObjectivesGUI"); - - // Set the weapon and inventory immobilisation flags - SetImmobilization("objectivesDisplay", EIM_WEAPON_SELECT | EIM_ITEM_USE | EIM_ITEM_SELECT | EIM_ITEM_DROP | EIM_FROB | EIM_FROB_COMPLEX); - - // Trigger an update - UpdateObjectivesGUI(); -} - -void idPlayer::DestroyObjectivesGUI() -{ - if (objectivesOverlay == -1) return; - - SetImmobilization("objectivesDisplay", 0); - - DestroyOverlay(objectivesOverlay); - objectivesOverlay = -1; -} - -void idPlayer::ToggleObjectivesGUI() -{ - if (objectivesOverlay == -1) - { - CreateObjectivesGUI(); - } - else - { - DestroyObjectivesGUI(); - } -} - -void idPlayer::UpdateObjectivesGUI() -{ - if (objectivesOverlay == -1) return; - - idUserInterface* objGUI = m_overlays.getGui(objectivesOverlay); - - if (objGUI == NULL) - { - gameLocal.Error("Could not find objectives GUI: %s", cv_tdm_obj_gui_file.GetString()); - return; - } - - // Trigger an update for this GUI - gameLocal.m_MissionData->UpdateGUIState(objGUI); -} - -void idPlayer::SetupInventory() -{ - m_InventoryOverlay = CreateOverlay(cv_tdm_inv_gui_file.GetString(), LAYER_INVENTORY); - - idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); - - if (invGUI == NULL) - { - gameLocal.Error("Could not set up inventory GUI: %s", cv_tdm_inv_gui_file.GetString()); - return; - } - - // Initialise the pickup message system - invGUI->HandleNamedEvent("SetupInventoryPickUpMessageSystem"); - - const CInventoryPtr& inv = Inventory(); - int idx = 0; - - // We create a cursor and a category for the weapons, which is then locked - // to this category, so we can only cycle within that one group. - m_WeaponCursor = inv->CreateCursor(); - inv->CreateCategory(TDM_PLAYER_WEAPON_CATEGORY, &idx); - m_WeaponCursor->SetCurrentCategory(idx); - m_WeaponCursor->SetCategoryLock(true); - - // greebo: Parse the spawnargs and add the weapon items to the inventory. - AddWeaponsToInventory(); - - // Disable all non-ammo weapons except unarmed, the items will be given by the shop - CInventoryCategoryPtr category = m_WeaponCursor->GetCurrentCategory(); - for (int i = 0; i < category->GetNumItems(); i++) - { - CInventoryWeaponItemPtr item = - boost::dynamic_pointer_cast(category->GetItem(i)); - - if (item->GetWeaponIndex() != 0 && item->IsAllowedEmpty()) - { - // Doesn't need ammo, disable this weapon for now - item->SetEnabled(false); - } - } - - // greebo: Create the cursor for map/floorplan inventory items. - m_MapCursor = inv->CreateCursor(); - inv->CreateCategory(TDM_PLAYER_MAPS_CATEGORY, &idx); - m_MapCursor->SetCurrentCategory(idx); - m_MapCursor->SetCategoryLock(true); - m_MapCursor->SetWrapAround(true); - m_MapCursor->ClearItem(); // invalidate the cursor - - // give the player weapon ammo based on shop purchases - category = m_WeaponCursor->GetCurrentCategory(); - const ShopItemList& startingItems = gameLocal.m_Shop->GetPlayerStartingEquipment(); - - for (int si = 0; si < startingItems.Num(); si++) - { - const CShopItemPtr& shopItem = startingItems[si]; - idStr weaponName = shopItem->GetID(); - - // greebo: Append "atdm:" if it's missing, all weapon entityDefs are atdm:* now - if (idStr::Cmpn(weaponName, "atdm:", 5) != 0) - { - weaponName = "atdm:" + weaponName; - } - - if (idStr::Cmpn(weaponName, "atdm:weapon_", 12) == 0) - { - weaponName.Strip("atdm:weapon_"); - - for (int i = 0; i < category->GetNumItems(); i++) - { - CInventoryWeaponItemPtr item = - boost::dynamic_pointer_cast(category->GetItem(i)); - - if (item->GetWeaponName() == weaponName) - { - // Enable non-ammo weapons, if the count is > 0 - if (item->IsAllowedEmpty()) - { - item->SetEnabled(shopItem->GetCount() > 0); - } - - // greebo: Don't set the persistent flag for weapons, they need to be persistent at all times - // The carry-over limits can be controlled via atdm:campaign_info objects - // item->SetPersistent(shopItem->GetPersistent()); - - // Set the ammo - item->SetAmmo(shopItem->GetCount()); - break; - } - } - } - } - - // Now create the standard cursor for all the other inventory items (excl. weapons) - CInventoryCursorPtr crsr = InventoryCursor(); - - // We set the filter to ignore the weapon category, since this will be - // handled by the weapon cursor. We don't want the weapons to show up - // in the weapon slot AND in the inventory at the same time. - crsr->AddCategoryIgnored(TDM_PLAYER_WEAPON_CATEGORY); - - // The player always gets a dummyentry (so the player can have an empty space if he - // chooses to not see the inventory all the time. - CInventoryItemPtr it(new CInventoryItem(this)); - it->SetName(TDM_DUMMY_ITEM); - it->SetType(CInventoryItem::IT_DUMMY); - it->SetCount(0); - it->SetStackable(false); - crsr->Inventory()->PutItem(it, TDM_INVENTORY_DEFAULT_GROUP); - - // Focus on the empty dummy inventory item - crsr->SetCurrentItem(TDM_DUMMY_ITEM); - m_LastItemNameBeforeClear = TDM_DUMMY_ITEM; - - // greebo: Set up the loot inventory item - const idDeclEntityDef* lootItemDef = static_cast( - declManager->FindType(DECL_ENTITYDEF, cv_tdm_inv_loot_item_def.GetString()) - ); - - if (lootItemDef == NULL) - { - gameLocal.Error("Could not find loot inventory entityDef.\n"); - } - - idEntity* lootItemEnt; - gameLocal.SpawnEntityDef(lootItemDef->dict, &lootItemEnt); - - assert(lootItemEnt != NULL); // must succeed - - CInventoryItemPtr lootItem = Inventory()->PutItem(lootItemEnt, this); - assert(lootItem != NULL); // must succeed as well - - // Flag this item as loot info item - lootItem->SetType(CInventoryItem::IT_LOOT_INFO); - - // Give player non-weapon items obtained from the Shop - for (int si = 0; si < startingItems.Num(); si++) - { - const CShopItemPtr& item = startingItems[si]; - - idStr itemName = item->GetID(); - int count = item->GetCount(); - - // greebo: Append "atdm:" if it's missing, all weapon entityDefs are atdm:* now - if (idStr::Cmpn(itemName, "atdm:", 5) != 0) - { - itemName = "atdm:" + itemName; - } - - if (idStr::Cmpn(itemName, "atdm:weapon_", 12) != 0 && count > 0) - { - const idStringList& classNames = item->GetClassnames(); - - for (int j = 0; j < classNames.Num(); ++j) - { - // Spawn this entitydef - const idDict* itemDict = gameLocal.FindEntityDefDict(classNames[j], true); - - idEntity* entity = NULL; - gameLocal.SpawnEntityDef( *itemDict, &entity ); - - // Inhibit pickup messages for these items - entity->spawnArgs.Set("inv_no_pickup_message", "1"); - - // grayman #2467 - Items added in this manner should be set to inv_map_start = 0. - // Otherwise they run the risk of being deleted when the map processes inv_map_start/1 items. - // Since this item is now in the inventory, inv_map_start should no longer need to be queried. - entity->spawnArgs.Set("inv_map_start", "0"); - - // add it to the inventory - CInventoryItemPtr invItem = crsr->Inventory()->PutItem(entity, this); - - invItem->SetCount(count); - invItem->SetPersistent(item->GetPersistent()); - } - } - } - - // Carry over persistent items from the previous map - AddPersistentInventoryItems(); -} - -void idPlayer::AddPersistentInventoryItems() -{ - // Copy all persistent items into our own inventory - Inventory()->CopyPersistentItemsFrom(*gameLocal.persistentPlayerInventory, this); - - // There might be new weapons coming in, sort the category again - SortWeaponItems(); - - // We've changed maps, let's respawn our item entities where needed, put them to our own position - Inventory()->RestoreItemEntities(GetPhysics()->GetOrigin()); -} - -/* -============== -idPlayer::~idPlayer() - -Release any resources used by the player. -============== -*/ -idPlayer::~idPlayer() -{ - delete weapon.GetEntity(); - weapon = NULL; -} - -/* -=========== -idPlayer::Save -=========== -*/ -void idPlayer::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteUsercmd( usercmd ); - playerView.Save( savefile ); - - savefile->WriteBool( noclip ); - savefile->WriteBool( godmode ); - - // don't save spawnAnglesSet, since we'll have to reset them after loading the savegame - savefile->WriteAngles( spawnAngles ); - savefile->WriteAngles( viewAngles ); - savefile->WriteAngles( cmdAngles ); - - // Mouse gesture - m_MouseGesture.Save( savefile ); - m_FrobPressedTarget.Save( savefile ); - - m_FrobEntity.Save(savefile); - savefile->WriteJoint(m_FrobJoint); - savefile->WriteInt(m_FrobID); - savefile->WriteTrace(m_FrobTrace); - savefile->WriteBool(m_bFrobOnlyUsedByInv); - - savefile->WriteInt( buttonMask ); - savefile->WriteInt( oldButtons ); - savefile->WriteInt( oldFlags ); - - savefile->WriteInt( lastHitTime ); - savefile->WriteInt( lastSndHitTime ); - savefile->WriteInt( lastSavingThrowTime ); - - savefile->WriteInt( lockpickHUD ); - savefile->WriteBool( hasLanded ); - - // idBoolFields don't need to be saved, just re-linked in Restore - - weapon.Save( savefile ); - - savefile->WriteUserInterface( hud, false ); - savefile->WriteBool(inventoryHUDNeedsUpdate); - - savefile->WriteInt(hudMessages.Num()); - for (int i = 0; i < hudMessages.Num(); i++) - { - savefile->WriteString(hudMessages[i]); - } - - savefile->WriteInt(inventoryPickedUpMessages.Num()); - for (int i = 0; i < inventoryPickedUpMessages.Num(); i++) - { - savefile->WriteString(inventoryPickedUpMessages[i]); - } - - savefile->WriteInt( weapon_fists ); - - savefile->WriteInt( heartRate ); - savefile->WriteBool(m_HeartBeatAllow); - - savefile->WriteFloat( heartInfo.GetStartTime() ); - savefile->WriteFloat( heartInfo.GetDuration() ); - savefile->WriteFloat( heartInfo.GetStartValue() ); - savefile->WriteFloat( heartInfo.GetEndValue() ); - - savefile->WriteInt( lastHeartAdjust ); - savefile->WriteInt( lastHeartBeat ); - savefile->WriteInt( lastDmgTime ); - savefile->WriteInt( deathClearContentsTime ); - savefile->WriteBool( doingDeathSkin ); - savefile->WriteInt( lastArmorPulse ); - savefile->WriteFloat( stamina ); - savefile->WriteFloat( healthPool ); - savefile->WriteInt( nextHealthPulse ); - savefile->WriteBool( healthPulse ); - savefile->WriteInt( nextHealthTake ); - savefile->WriteBool( healthTake ); - - savefile->WriteInt(healthPoolStepAmount); - savefile->WriteInt(healthPoolTimeInterval); - savefile->WriteFloat(healthPoolTimeIntervalFactor); - - savefile->WriteBool( hiddenWeapon ); - - savefile->WriteInt( spectator ); - savefile->WriteVec3( colorBar ); - savefile->WriteInt( colorBarIndex ); - savefile->WriteBool( scoreBoardOpen ); - savefile->WriteBool( forceScoreBoard ); - savefile->WriteBool( forceRespawn ); - savefile->WriteBool( spectating ); - savefile->WriteInt( lastSpectateTeleport ); - savefile->WriteBool( lastHitToggle ); - savefile->WriteBool( forcedReady ); - savefile->WriteBool( wantSpectate ); - savefile->WriteBool( weaponGone ); - savefile->WriteBool( useInitialSpawns ); - savefile->WriteInt( latchedTeam ); - savefile->WriteInt( tourneyRank ); - savefile->WriteInt( tourneyLine ); - - teleportEntity.Save( savefile ); - savefile->WriteInt( teleportKiller ); - - savefile->WriteInt( minRespawnTime ); - savefile->WriteInt( maxRespawnTime ); - - savefile->WriteVec3( firstPersonViewOrigin ); - savefile->WriteMat3( firstPersonViewAxis ); - - // don't bother saving dragEntity since it's a dev tool - - savefile->WriteJoint( hipJoint ); - savefile->WriteJoint( chestJoint ); - savefile->WriteJoint( headJoint ); - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteInt( aasLocation.Num() ); - for( i = 0; i < aasLocation.Num(); i++ ) { - savefile->WriteInt( aasLocation[ i ].areaNum ); - savefile->WriteVec3( aasLocation[ i ].pos ); - } - - savefile->WriteInt( bobFoot ); - savefile->WriteFloat( bobFrac ); - savefile->WriteFloat( bobfracsin ); - savefile->WriteInt( bobCycle ); - savefile->WriteFloat( xyspeed ); - savefile->WriteInt( stepUpTime ); - savefile->WriteFloat( stepUpDelta ); - savefile->WriteFloat( idealLegsYaw ); - savefile->WriteFloat( legsYaw ); - savefile->WriteBool( legsForward ); - savefile->WriteFloat( oldViewYaw ); - savefile->WriteAngles( viewBobAngles ); - savefile->WriteVec3( viewBob ); - savefile->WriteInt( landChange ); - savefile->WriteInt( landTime ); - savefile->WriteInt( lastFootstepPlaytime ); - savefile->WriteBool(isPushing); - - savefile->WriteInt( currentWeapon ); - savefile->WriteInt( idealWeapon ); - savefile->WriteInt( previousWeapon ); - savefile->WriteInt( weaponSwitchTime ); - savefile->WriteBool( weaponEnabled ); - savefile->WriteBool( showWeaponViewModel ); - - savefile->WriteSkin( skin ); - savefile->WriteSkin( powerUpSkin ); - savefile->WriteString( baseSkinName ); - - savefile->WriteInt( numProjectilesFired ); - savefile->WriteInt( numProjectileHits ); - - savefile->WriteBool( airless ); - savefile->WriteInt( airTics ); - savefile->WriteInt( lastAirDamage ); - - savefile->WriteBool(underWaterEffectsActive); - savefile->WriteInt(underWaterGUIHandle); - - savefile->WriteBool( gibDeath ); - savefile->WriteBool( gibsLaunched ); - savefile->WriteVec3( gibsDir ); - - savefile->WriteFloat( zoomFov.GetStartTime() ); - savefile->WriteFloat( zoomFov.GetDuration() ); - savefile->WriteFloat( zoomFov.GetStartValue() ); - savefile->WriteFloat( zoomFov.GetEndValue() ); - - savefile->WriteFloat( centerView.GetStartTime() ); - savefile->WriteFloat( centerView.GetDuration() ); - savefile->WriteFloat( centerView.GetStartValue() ); - savefile->WriteFloat( centerView.GetEndValue() ); - - savefile->WriteBool( fxFov ); - - savefile->WriteFloat( influenceFov ); - savefile->WriteInt( influenceActive ); - savefile->WriteFloat( influenceRadius ); - savefile->WriteObject( influenceEntity ); - savefile->WriteMaterial( influenceMaterial ); - savefile->WriteSkin( influenceSkin ); - - savefile->WriteObject( privateCameraView ); - savefile->WriteVec3( m_ListenerLoc ); - savefile->WriteVec3( m_DoorListenLoc ); - - savefile->WriteDict( &m_immobilization ); - savefile->WriteInt( m_immobilizationCache ); - - savefile->WriteDict( &m_hinderance ); - savefile->WriteFloat( m_hinderanceCache ); - savefile->WriteDict( &m_TurnHinderance ); - savefile->WriteFloat( m_TurnHinderanceCache ); - - for( i = 0; i < NUM_LOGGED_VIEW_ANGLES; i++ ) { - savefile->WriteAngles( loggedViewAngles[ i ] ); - } - for( i = 0; i < NUM_LOGGED_ACCELS; i++ ) { - savefile->WriteInt( loggedAccel[ i ].time ); - savefile->WriteVec3( loggedAccel[ i ].dir ); - } - savefile->WriteInt( currentLoggedAccel ); - -#if 0 - savefile->WriteObject( focusGUIent ); - // can't save focusUI - savefile->WriteObject( focusCharacter ); - savefile->WriteInt( talkCursor ); - savefile->WriteInt( focusTime ); - savefile->WriteObject( focusVehicle ); -#endif - savefile->WriteUserInterface( cursor, false ); - - savefile->WriteInt( oldMouseX ); - savefile->WriteInt( oldMouseY ); - - savefile->WriteBool( tipUp ); - - savefile->WriteInt( lastDamageDef ); - savefile->WriteVec3( lastDamageDir ); - savefile->WriteInt( lastDamageLocation ); - savefile->WriteBool( m_bDamagedThisFrame ); - savefile->WriteInt( smoothedFrame ); - savefile->WriteBool( smoothedOriginUpdated ); - savefile->WriteVec3( smoothedOrigin ); - savefile->WriteAngles( smoothedAngles ); - - savefile->WriteBool( ready ); - savefile->WriteBool( respawning ); - savefile->WriteBool( leader ); - savefile->WriteInt( lastSpectateChange ); - savefile->WriteInt( lastTeleFX ); - - // Commented out by Dram. TDM does not use stamina - //savefile->WriteFloat( pm_stamina.GetFloat() ); - - savefile->WriteBool( m_bGrabberActive ); - savefile->WriteBool( m_bDraggingBody ); - savefile->WriteBool( m_bShoulderingBody ); - - savefile->WriteBool( m_IdealCrouchState ); - savefile->WriteBool( m_CrouchIntent ); - - savefile->WriteInt(m_InventoryOverlay); - - savefile->WriteInt(m_WaitUntilReadyGuiHandle); - savefile->WriteInt(m_WaitUntilReadyGuiTime); - - savefile->WriteInt(objectivesOverlay); - - savefile->WriteBool(m_WeaponCursor != NULL); - if (m_WeaponCursor != NULL) { - savefile->WriteInt(m_WeaponCursor->GetId()); - } - - savefile->WriteBool(m_MapCursor != NULL); - if (m_MapCursor != NULL) { - savefile->WriteInt(m_MapCursor->GetId()); - } - - savefile->WriteString(m_LastItemNameBeforeClear.c_str()); - - m_ActiveInventoryMapEnt.Save(savefile); - - savefile->WriteInt(m_LightgemModifier); - - savefile->WriteInt(static_cast(m_LightgemModifierList.size())); - for (std::map::const_iterator i = m_LightgemModifierList.begin(); i != m_LightgemModifierList.end(); ++i) - { - savefile->WriteString(i->first.c_str()); - savefile->WriteInt(i->second); - } - - savefile->WriteInt(m_LightList.Num()); - for (int i = 0; i < m_LightList.Num(); i++) - { - savefile->WriteObject(m_LightList[i]); - } - - savefile->WriteInt(m_LightgemValue); - savefile->WriteFloat(m_fColVal); - savefile->WriteInt(m_LightgemInterleave); - savefile->WriteBool(ignoreWeaponAttack); // grayman #597 - - if(hud) - { - hud->SetStateString( "message", gameLocal.m_I18N->Translate( "#str_02916" ) ); - hud->HandleNamedEvent( "Message" ); - } -} - -/* -=========== -idPlayer::Restore -=========== -*/ -void idPlayer::Restore( idRestoreGame *savefile ) { - int i; - int num; - float set; - - savefile->ReadUsercmd( usercmd ); - playerView.Restore( savefile ); - - savefile->ReadBool( noclip ); - savefile->ReadBool( godmode ); - - savefile->ReadAngles( spawnAngles ); - savefile->ReadAngles( viewAngles ); - savefile->ReadAngles( cmdAngles ); - - memset( usercmd.angles, 0, sizeof( usercmd.angles ) ); - SetViewAngles( viewAngles ); - spawnAnglesSet = true; - - m_MouseGesture.Restore( savefile ); - m_FrobPressedTarget.Restore( savefile ); - - m_FrobEntity.Restore(savefile); - savefile->ReadJoint(m_FrobJoint); - savefile->ReadInt(m_FrobID); - savefile->ReadTrace(m_FrobTrace); - savefile->ReadBool(m_bFrobOnlyUsedByInv); - - savefile->ReadInt( buttonMask ); - savefile->ReadInt( oldButtons ); - savefile->ReadInt( oldFlags ); - - usercmd.flags = 0; - oldFlags = 0; - - savefile->ReadInt( lastHitTime ); - savefile->ReadInt( lastSndHitTime ); - savefile->ReadInt( lastSavingThrowTime ); - - savefile->ReadInt( lockpickHUD ); - savefile->ReadBool( hasLanded ); - - // Re-link idBoolFields to the scriptObject, values will be restored in scriptObject's restore - LinkScriptVariables(); - - weapon.Restore( savefile ); - - savefile->ReadUserInterface( hud ); - savefile->ReadBool(inventoryHUDNeedsUpdate); - - savefile->ReadInt(num); - hudMessages.Clear(); - hudMessages.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(hudMessages[i]); - } - - savefile->ReadInt(num); - inventoryPickedUpMessages.Clear(); - inventoryPickedUpMessages.SetNum(num); - for (i = 0; i < num; i++) - { - savefile->ReadString(inventoryPickedUpMessages[i]); - } - - savefile->ReadInt( weapon_fists ); - - savefile->ReadInt( heartRate ); - savefile->ReadBool(m_HeartBeatAllow); - - savefile->ReadFloat( set ); - heartInfo.SetStartTime( set ); - savefile->ReadFloat( set ); - heartInfo.SetDuration( set ); - savefile->ReadFloat( set ); - heartInfo.SetStartValue( set ); - savefile->ReadFloat( set ); - heartInfo.SetEndValue( set ); - - savefile->ReadInt( lastHeartAdjust ); - savefile->ReadInt( lastHeartBeat ); - savefile->ReadInt( lastDmgTime ); - savefile->ReadInt( deathClearContentsTime ); - savefile->ReadBool( doingDeathSkin ); - savefile->ReadInt( lastArmorPulse ); - savefile->ReadFloat( stamina ); - savefile->ReadFloat( healthPool ); - savefile->ReadInt( nextHealthPulse ); - savefile->ReadBool( healthPulse ); - savefile->ReadInt( nextHealthTake ); - savefile->ReadBool( healthTake ); - - savefile->ReadInt(healthPoolStepAmount); - savefile->ReadInt(healthPoolTimeInterval); - savefile->ReadFloat(healthPoolTimeIntervalFactor); - - savefile->ReadBool( hiddenWeapon ); - - savefile->ReadInt( spectator ); - savefile->ReadVec3( colorBar ); - savefile->ReadInt( colorBarIndex ); - savefile->ReadBool( scoreBoardOpen ); - savefile->ReadBool( forceScoreBoard ); - savefile->ReadBool( forceRespawn ); - savefile->ReadBool( spectating ); - savefile->ReadInt( lastSpectateTeleport ); - savefile->ReadBool( lastHitToggle ); - savefile->ReadBool( forcedReady ); - savefile->ReadBool( wantSpectate ); - savefile->ReadBool( weaponGone ); - savefile->ReadBool( useInitialSpawns ); - savefile->ReadInt( latchedTeam ); - savefile->ReadInt( tourneyRank ); - savefile->ReadInt( tourneyLine ); - - teleportEntity.Restore( savefile ); - savefile->ReadInt( teleportKiller ); - - savefile->ReadInt( minRespawnTime ); - savefile->ReadInt( maxRespawnTime ); - - savefile->ReadVec3( firstPersonViewOrigin ); - savefile->ReadMat3( firstPersonViewAxis ); - - // don't bother saving dragEntity since it's a dev tool - dragEntity.Clear(); - - savefile->ReadJoint( hipJoint ); - savefile->ReadJoint( chestJoint ); - savefile->ReadJoint( headJoint ); - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadInt( num ); - aasLocation.SetGranularity( 1 ); - aasLocation.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadInt( aasLocation[ i ].areaNum ); - savefile->ReadVec3( aasLocation[ i ].pos ); - } - - savefile->ReadInt( bobFoot ); - savefile->ReadFloat( bobFrac ); - savefile->ReadFloat( bobfracsin ); - savefile->ReadInt( bobCycle ); - savefile->ReadFloat( xyspeed ); - savefile->ReadInt( stepUpTime ); - savefile->ReadFloat( stepUpDelta ); - savefile->ReadFloat( idealLegsYaw ); - savefile->ReadFloat( legsYaw ); - savefile->ReadBool( legsForward ); - savefile->ReadFloat( oldViewYaw ); - savefile->ReadAngles( viewBobAngles ); - savefile->ReadVec3( viewBob ); - savefile->ReadInt( landChange ); - savefile->ReadInt( landTime ); - savefile->ReadInt( lastFootstepPlaytime ); - savefile->ReadBool(isPushing); - - savefile->ReadInt( currentWeapon ); - savefile->ReadInt( idealWeapon ); - savefile->ReadInt( previousWeapon ); - savefile->ReadInt( weaponSwitchTime ); - savefile->ReadBool( weaponEnabled ); - savefile->ReadBool( showWeaponViewModel ); - - savefile->ReadSkin( skin ); - savefile->ReadSkin( powerUpSkin ); - savefile->ReadString( baseSkinName ); - - savefile->ReadInt( numProjectilesFired ); - savefile->ReadInt( numProjectileHits ); - - savefile->ReadBool( airless ); - savefile->ReadInt( airTics ); - savefile->ReadInt( lastAirDamage ); - - savefile->ReadBool(underWaterEffectsActive); - savefile->ReadInt(underWaterGUIHandle); - - savefile->ReadBool( gibDeath ); - savefile->ReadBool( gibsLaunched ); - savefile->ReadVec3( gibsDir ); - - savefile->ReadFloat( set ); - zoomFov.SetStartTime( set ); - savefile->ReadFloat( set ); - zoomFov.SetDuration( set ); - savefile->ReadFloat( set ); - zoomFov.SetStartValue( set ); - savefile->ReadFloat( set ); - zoomFov.SetEndValue( set ); - - savefile->ReadFloat( set ); - centerView.SetStartTime( set ); - savefile->ReadFloat( set ); - centerView.SetDuration( set ); - savefile->ReadFloat( set ); - centerView.SetStartValue( set ); - savefile->ReadFloat( set ); - centerView.SetEndValue( set ); - - savefile->ReadBool( fxFov ); - - savefile->ReadFloat( influenceFov ); - savefile->ReadInt( influenceActive ); - savefile->ReadFloat( influenceRadius ); - savefile->ReadObject( reinterpret_cast( influenceEntity ) ); - savefile->ReadMaterial( influenceMaterial ); - savefile->ReadSkin( influenceSkin ); - - savefile->ReadObject( reinterpret_cast( privateCameraView ) ); - savefile->ReadVec3( m_ListenerLoc ); - savefile->ReadVec3( m_DoorListenLoc ); - - savefile->ReadDict( &m_immobilization ); - savefile->ReadInt( m_immobilizationCache ); - - savefile->ReadDict( &m_hinderance ); - savefile->ReadFloat( m_hinderanceCache ); - savefile->ReadDict( &m_TurnHinderance ); - savefile->ReadFloat( m_TurnHinderanceCache ); - - for( i = 0; i < NUM_LOGGED_VIEW_ANGLES; i++ ) { - savefile->ReadAngles( loggedViewAngles[ i ] ); - } - for( i = 0; i < NUM_LOGGED_ACCELS; i++ ) { - savefile->ReadInt( loggedAccel[ i ].time ); - savefile->ReadVec3( loggedAccel[ i ].dir ); - } - savefile->ReadInt( currentLoggedAccel ); - -#if 0 - savefile->ReadObject( reinterpret_cast( focusGUIent ) ); - // can't save focusUI - focusUI = NULL; - savefile->ReadObject( reinterpret_cast( focusCharacter ) ); - savefile->ReadInt( talkCursor ); - savefile->ReadInt( focusTime ); - savefile->ReadObject( reinterpret_cast( focusVehicle ) ); -#endif - savefile->ReadUserInterface( cursor ); - - savefile->ReadInt( oldMouseX ); - savefile->ReadInt( oldMouseY ); - - savefile->ReadBool( tipUp ); - - savefile->ReadInt( lastDamageDef ); - savefile->ReadVec3( lastDamageDir ); - savefile->ReadInt( lastDamageLocation ); - savefile->ReadBool( m_bDamagedThisFrame ); - savefile->ReadInt( smoothedFrame ); - savefile->ReadBool( smoothedOriginUpdated ); - savefile->ReadVec3( smoothedOrigin ); - savefile->ReadAngles( smoothedAngles ); - - savefile->ReadBool( ready ); - savefile->ReadBool( respawning ); - savefile->ReadBool( leader ); - savefile->ReadInt( lastSpectateChange ); - savefile->ReadInt( lastTeleFX ); - - // set the pm_ cvars - const idKeyValue *kv; - kv = spawnArgs.MatchPrefix( "pm_", NULL ); - while( kv ) { - cvarSystem->SetCVarString( kv->GetKey(), kv->GetValue() ); - kv = spawnArgs.MatchPrefix( "pm_", kv ); - } - - // savefile->ReadFloat( set ); - // Commented out by Dram. TDM does not use stamina - //pm_stamina.SetFloat( set ); - - savefile->ReadBool( m_bGrabberActive ); - savefile->ReadBool( m_bDraggingBody ); - savefile->ReadBool( m_bShoulderingBody ); - - savefile->ReadBool( m_IdealCrouchState ); - savefile->ReadBool( m_CrouchIntent ); - - savefile->ReadInt(m_InventoryOverlay); - - savefile->ReadInt(m_WaitUntilReadyGuiHandle); - savefile->ReadInt(m_WaitUntilReadyGuiTime); - - savefile->ReadInt(objectivesOverlay); - - bool hasWeaponCursor; - savefile->ReadBool(hasWeaponCursor); - if (hasWeaponCursor) { - int cursorId; - savefile->ReadInt(cursorId); - m_WeaponCursor = Inventory()->GetCursor(cursorId); - } - - bool hasMapCursor; - savefile->ReadBool(hasMapCursor); - if (hasMapCursor) { - int cursorId; - savefile->ReadInt(cursorId); - m_MapCursor = Inventory()->GetCursor(cursorId); - } - - savefile->ReadString(m_LastItemNameBeforeClear); - - m_ActiveInventoryMapEnt.Restore(savefile); - - savefile->ReadInt(m_LightgemModifier); - - savefile->ReadInt(num); - for (int i = 0; i < num; i++) - { - idStr name; - int value; - savefile->ReadString(name); - savefile->ReadInt(value); - // Store the pair into the map - m_LightgemModifierList[std::string(name.c_str())] = value; - } - - savefile->ReadInt(num); - m_LightList.SetNum(num); - for (int i = 0; i < num; i++) - { - idLight* light = NULL; - savefile->ReadObject(reinterpret_cast(light)); - m_LightList[i] = light; - } - - savefile->ReadInt(m_LightgemValue); - savefile->ReadFloat(m_fColVal); - savefile->ReadInt(m_LightgemInterleave); - savefile->ReadBool(ignoreWeaponAttack); // grayman #597 - - // create combat collision hull for exact collision detection - SetCombatModel(); - - // Necessary, since the overlay system can't save external GUI pointers. - if ( m_overlays.isExternal( OVERLAYS_MIN_HANDLE ) ) - m_overlays.setGui( OVERLAYS_MIN_HANDLE, hud ); - else - gameLocal.Warning( "Unable to relink HUD to overlay system.\n" ); -} - -/* -=============== -idPlayer::PrepareForRestart -================ -*/ -void idPlayer::PrepareForRestart( void ) { - Spectate( true ); - forceRespawn = true; - - // we will be restarting program, clear the client entities from program-related things first - ShutdownThreads(); - - // the sound world is going to be cleared, don't keep references to emitters - FreeSoundEmitter( false ); -} - -/* -=============== -idPlayer::Restart -================ -*/ -void idPlayer::Restart( void ) { - idActor::Restart(); - - // client needs to setup the animation script object again - if ( gameLocal.isClient ) { - Init(); - } else { - // choose a random spot and prepare the point of view in case player is left spectating - assert( spectating ); - SpawnFromSpawnSpot(); - } - - useInitialSpawns = true; - UpdateSkinSetup( true ); -} - -/* -=============== -idPlayer::ServerSpectate -================ -*/ -void idPlayer::ServerSpectate( bool spectate ) { - assert( !gameLocal.isClient ); - - if ( spectating != spectate ) { - Spectate( spectate ); - if ( spectate ) { - SetSpectateOrigin(); - } else { - if ( gameLocal.gameType == GAME_DM ) { - // make sure the scores are reset so you can't exploit by spectating and entering the game back - // other game types don't matter, as you either can't join back, or it's team scores - gameLocal.mpGame.ClearFrags( entityNumber ); - } - } - } - if ( !spectate ) { - SpawnFromSpawnSpot(); - } -} - -/* -=========== -idPlayer::SelectInitialSpawnPoint - -Try to find a spawn point marked 'initial', otherwise -use normal spawn selection. -============ -*/ -void idPlayer::SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles ) { - idEntity *spot; - idStr skin; - - spot = gameLocal.SelectInitialSpawnPoint( this ); - - // set the player skin from the spawn location - if ( spot->spawnArgs.GetString( "skin", NULL, skin ) ) { - spawnArgs.Set( "spawn_skin", skin ); - } - - // activate the spawn locations targets - spot->PostEventMS( &EV_ActivateTargets, 0, this ); - - origin = spot->GetPhysics()->GetOrigin(); - origin[2] += 4.0f + CM_BOX_EPSILON; // move up to make sure the player is at least an epsilon above the floor - angles = spot->GetPhysics()->GetAxis().ToAngles(); -} - -/* -=========== -idPlayer::SpawnFromSpawnSpot - -Chooses a spawn location and spawns the player -============ -*/ -void idPlayer::SpawnFromSpawnSpot( void ) { - idVec3 spawn_origin; - idAngles spawn_angles; - - SelectInitialSpawnPoint( spawn_origin, spawn_angles ); - SpawnToPoint( spawn_origin, spawn_angles ); -} - -/* -=========== -idPlayer::SpawnToPoint - -Called every time a client is placed fresh in the world: -after the first ClientBegin, and after each respawn -Initializes all non-persistant parts of playerState - -when called here with spectating set to true, just place yourself and init -============ -*/ -void idPlayer::SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles ) { - idVec3 spec_origin; - - assert( !gameLocal.isClient ); - - respawning = true; - - Init(); - - fl.noknockback = false; - - // stop any ragdolls being used - StopRagdoll(); - - // set back the player physics - SetPhysics( &physicsObj ); - - physicsObj.SetClipModelAxis(); - physicsObj.EnableClip(); - - if ( !spectating ) { - SetCombatContents( true ); - } - - physicsObj.SetLinearVelocity( vec3_origin ); - - // setup our initial view - if ( !spectating ) { - SetOrigin( spawn_origin ); - } else { - spec_origin = spawn_origin; - spec_origin[ 2 ] += pm_normalheight.GetFloat(); - spec_origin[ 2 ] += SPECTATE_RAISE; - SetOrigin( spec_origin ); - } - - // if this is the first spawn of the map, we don't have a usercmd yet, - // so the delta angles won't be correct. This will be fixed on the first think. - viewAngles = ang_zero; - SetDeltaViewAngles( ang_zero ); - SetViewAngles( spawn_angles ); - spawnAngles = spawn_angles; - spawnAnglesSet = false; - - legsForward = true; - legsYaw = 0.0f; - idealLegsYaw = 0.0f; - oldViewYaw = viewAngles.yaw; - - if ( spectating ) { - Hide(); - } else { - Show(); - } - - if ( gameLocal.isMultiplayer ) { - if ( !spectating ) { - // we may be called twice in a row in some situations. avoid a double fx and 'fly to the roof' - if ( lastTeleFX < gameLocal.time - 1000 ) { - idEntityFx::StartFx( spawnArgs.GetString( "fx_spawn" ), &spawn_origin, NULL, this, true ); - lastTeleFX = gameLocal.time; - } - } - AI_TELEPORT = true; - } else { - AI_TELEPORT = false; - } - - // kill anything at the new position - if ( !spectating ) { - physicsObj.SetClipMask( MASK_PLAYERSOLID ); // the clip mask is usually maintained in Move(), but KillBox requires it - gameLocal.KillBox( this ); - } - - // don't allow full run speed for a bit - physicsObj.SetKnockBack( 100 ); - - // set our respawn time and buttons so that if we're killed we don't respawn immediately - minRespawnTime = gameLocal.time; - maxRespawnTime = gameLocal.time; - if ( !spectating ) { - forceRespawn = false; - } - - privateCameraView = NULL; - - BecomeActive( TH_THINK ); - - // run a client frame to drop exactly to the floor, - // initialize animations and other things - Think(); - - respawning = false; - lastManOver = false; - lastManPlayAgain = false; - isTelefragged = false; -} - -/* -=============== -idPlayer::SavePersistantInfo - -Saves any inventory and player stats when changing levels. -=============== -*/ -void idPlayer::SavePersistantInfo( void ) { - idDict &playerInfo = gameLocal.persistentPlayerInfo[entityNumber]; - - playerInfo.Clear(); - - // greebo: Don't persist current weapon when switching maps (issue #2774) - // Keep writing the health value to the dict, the engine is using that to query the player's health - playerInfo.SetInt( "health", health ); -#if 0 - playerInfo.SetInt( "current_weapon", currentWeapon ); -#endif -} - -/* -=============== -idPlayer::RestorePersistantInfo - -Restores any inventory and player stats when changing levels. -=============== -*/ -void idPlayer::RestorePersistantInfo( void ) { - if ( gameLocal.isMultiplayer ) { - gameLocal.persistentPlayerInfo[entityNumber].Clear(); - } - - // greebo: TDM doesn't need to load health or weapon from the dict, that is not (yet) intended since - // map switching within missions is not yet planned or fleshed out -#if 0 - spawnArgs.Copy( gameLocal.persistentPlayerInfo[entityNumber] ); - - health = spawnArgs.GetInt( "health", "100" ); - if ( !gameLocal.isClient ) { - idealWeapon = spawnArgs.GetInt( "current_weapon", "0" ); - } -#endif -} - -/* -================ -idPlayer::GetUserInfo -================ -*/ -idDict *idPlayer::GetUserInfo( void ) { - return &gameLocal.userInfo[ entityNumber ]; -} - -/* -============== -idPlayer::UpdateSkinSetup -============== -*/ -void idPlayer::UpdateSkinSetup( bool restart ) { - if ( restart ) { - team = ( idStr::Icmp( GetUserInfo()->GetString( "ui_team" ), "Blue" ) == 0 ); - } - if ( gameLocal.gameType == GAME_TDM ) { - if ( team ) { - baseSkinName = "skins/characters/player/marine_mp_blue"; - } else { - baseSkinName = "skins/characters/player/marine_mp_red"; - } - if ( !gameLocal.isClient && team != latchedTeam ) { - gameLocal.mpGame.SwitchToTeam( entityNumber, latchedTeam, team ); - } - latchedTeam = team; - } else { - baseSkinName = GetUserInfo()->GetString( "ui_skin" ); - } - if ( !baseSkinName.Length() ) { - baseSkinName = "skins/characters/player/marine_mp"; - } - skin = declManager->FindSkin( baseSkinName, false ); - assert( skin ); - // match the skin to a color band for scoreboard - if ( baseSkinName.Find( "red" ) != -1 ) { - colorBarIndex = 1; - } else if ( baseSkinName.Find( "green" ) != -1 ) { - colorBarIndex = 2; - } else if ( baseSkinName.Find( "blue" ) != -1 ) { - colorBarIndex = 3; - } else if ( baseSkinName.Find( "yellow" ) != -1 ) { - colorBarIndex = 4; - } else { - colorBarIndex = 0; - } - colorBar = colorBarTable[ colorBarIndex ]; -} - -/* -============== -idPlayer::BalanceTDM -============== -*/ -bool idPlayer::BalanceTDM( void ) { - int i, balanceTeam, teamCount[2]; - idEntity *ent; - - teamCount[ 0 ] = teamCount[ 1 ] = 0; - for( i = 0; i < gameLocal.numClients; i++ ) { - ent = gameLocal.entities[ i ]; - if ( ent && ent->IsType( idPlayer::Type ) ) { - teamCount[ static_cast< idPlayer * >( ent )->team ]++; - } - } - balanceTeam = -1; - if ( teamCount[ 0 ] < teamCount[ 1 ] ) { - balanceTeam = 0; - } else if ( teamCount[ 0 ] > teamCount[ 1 ] ) { - balanceTeam = 1; - } - if ( balanceTeam != -1 && team != balanceTeam ) { - common->DPrintf( "team balance: forcing player %d to %s team\n", entityNumber, balanceTeam ? "blue" : "red" ); - team = balanceTeam; - GetUserInfo()->Set( "ui_team", team ? "Blue" : "Red" ); - return true; - } - return false; -} - -/* -============== -idPlayer::UserInfoChanged -============== -*/ -bool idPlayer::UserInfoChanged( bool canModify ) { - idDict *userInfo; - bool modifiedInfo; - bool spec; - bool newready; - - userInfo = GetUserInfo(); - showWeaponViewModel = userInfo->GetBool( "ui_showGun" ); - - if ( !gameLocal.isMultiplayer ) { - return false; - } - - modifiedInfo = false; - - spec = ( idStr::Icmp( userInfo->GetString( "ui_spectate" ), "Spectate" ) == 0 ); - if ( gameLocal.serverInfo.GetBool( "si_spectators" ) ) { - // never let spectators go back to game while sudden death is on - if ( canModify && gameLocal.mpGame.GetGameState() == idMultiplayerGame::SUDDENDEATH && !spec && wantSpectate == true ) { - - userInfo->Set( "ui_spectate", "Spectate" ); - modifiedInfo |= true; - } else { - if ( spec != wantSpectate && !spec ) { - // returning from spectate, set forceRespawn so we don't get stuck in spectate forever - forceRespawn = true; - } - wantSpectate = spec; - } - } else { - if ( canModify && spec ) { - - userInfo->Set( "ui_spectate", "Play" ); - modifiedInfo |= true; - } else if ( spectating ) { - // allow player to leaving spectator mode if they were in it when si_spectators got turned off - - forceRespawn = true; - } - wantSpectate = false; - } - newready = ( idStr::Icmp( userInfo->GetString( "ui_ready" ), "Ready" ) == 0 ); - if ( ready != newready && gameLocal.mpGame.GetGameState() == idMultiplayerGame::WARMUP && !wantSpectate ) { - gameLocal.mpGame.AddChatLine( gameLocal.m_I18N->Translate( "#str_07180" ), userInfo->GetString( "ui_name" ), newready ? gameLocal.m_I18N->Translate( "#str_04300" ) : gameLocal.m_I18N->Translate( "#str_04301" ) ); - } - ready = newready; - team = ( idStr::Icmp( userInfo->GetString( "ui_team" ), "Blue" ) == 0 ); - // server maintains TDM balance - if ( canModify && gameLocal.gameType == GAME_TDM && !gameLocal.mpGame.IsInGame( entityNumber ) && g_balanceTDM.GetBool() ) { - - modifiedInfo |= BalanceTDM( ); - } - UpdateSkinSetup( false ); - - isChatting = userInfo->GetBool( "ui_chat", "0" ); - if ( canModify && isChatting && AI_DEAD ) { - - // if dead, always force chat icon off. - isChatting = false; - userInfo->SetBool( "ui_chat", false ); - modifiedInfo |= true; - } - - return modifiedInfo; -} - -/* -=============== -idPlayer::UpdateHudAmmo -=============== -*/ -void idPlayer::UpdateHudAmmo() -{ - CInventoryWeaponItemPtr curWeapon = GetCurrentWeaponItem(); - - // If no weapon item there, or the first one is selected, switch off the HUD - bool weaponSelected = (curWeapon != NULL && curWeapon->GetWeaponIndex() > 0); - - hud->SetStateBool("WeaponAmmoVisible", weaponSelected && curWeapon->NeedsAmmo()); - - if (!weaponSelected) return; // done here - - hud->SetStateString("WeaponAmmoAmount", va("%d", curWeapon->GetAmmo())); -} - -/* -=============== -idPlayer::UpdateHudStats -=============== -*/ -void idPlayer::UpdateHudStats( idUserInterface *_hud ) -{ - // Commented out by Dram. TDM does not use stamina - //int staminapercentage; - //float max_stamina; - - assert( _hud ); - - // Commented out by Dram. TDM does not use stamina - /*max_stamina = pm_stamina.GetFloat(); - if ( !max_stamina ) { - // stamina disabled, so show full stamina bar - staminapercentage = 100; - } else { - staminapercentage = idMath::FtoiFast( 100.0f * stamina / max_stamina ); - }*/ - - _hud->SetStateInt( "player_health", health ); - // Commented out by Dram. TDM does not use stamina - //_hud->SetStateInt( "player_stamina", staminapercentage ); - _hud->SetStateInt( "player_shadow", 1 ); - - _hud->SetStateInt( "player_hr", heartRate ); - // Commented out by Dram. TDM does not use stamina - //_hud->SetStateInt( "player_nostamina", ( max_stamina == 0 ) ? 1 : 0 ); - - _hud->HandleNamedEvent( "updateArmorHealthAir" ); - - if ( healthPulse ) { - _hud->HandleNamedEvent( "healthPulse" ); - StartSound( "snd_healthpulse", SND_CHANNEL_ITEM, 0, false, NULL ); - healthPulse = false; - } - - if ( healthTake ) { - _hud->HandleNamedEvent( "healthPulse" ); - StartSound( "snd_healthtake", SND_CHANNEL_ITEM, 0, false, NULL ); - healthTake = false; - } - - UpdateHudAmmo(); -} - -/* -=============== -idPlayer::UpdateHudWeapon -=============== -*/ -void idPlayer::UpdateHudWeapon( bool flashWeapon ) -{ - // if updating the hud of a followed client - if ( gameLocal.localClientNum >= 0 && gameLocal.entities[ gameLocal.localClientNum ] && gameLocal.entities[ gameLocal.localClientNum ]->IsType( idPlayer::Type ) ) { - idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ gameLocal.localClientNum ] ); - if ( p->spectating && p->spectator == entityNumber ) { - assert( p->hud ); - hud = p->hud; - } - } - - if (hud == NULL || m_WeaponCursor == NULL) { - return; - } - - CInventoryWeaponItemPtr curWeapon = GetCurrentWeaponItem(); - - // If no weapon item there, or the first one is selected, switch off the HUD - bool weaponSelected = (curWeapon != NULL && curWeapon->GetWeaponIndex() > 0); - - // Update the visibility of the various GUI elements - hud->SetStateBool("WeaponIconVisible", weaponSelected); - hud->SetStateBool("WeaponNameVisible", weaponSelected); - - if (!weaponSelected) return; // done here - - // Set the icon and name strings - hud->SetStateString("WeaponName", gameLocal.m_I18N->Translate( curWeapon->GetName().c_str() )); - hud->SetStateString("WeaponIcon", curWeapon->GetIcon().c_str()); - - hud->HandleNamedEvent("OnWeaponChange"); - - UpdateHudAmmo(); -} - -void idPlayer::PrintDebugHUD(void) -{ - idStr strText; - idVec3 a, b, c; - int y; - - // TODO: Remove this when no longer needed. - y = 100; - sprintf(strText, "ViewOrg: x: %f y: %f z: %f", renderView->vieworg.x, renderView->vieworg.y, renderView->vieworg.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - renderView->viewaxis.GetMat3Params(a, b, c); - sprintf(strText, "ViewMatrix:", renderView->vieworg.x, renderView->vieworg.y, renderView->vieworg.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "x: %f y: %f z: %f", a.x, a.y, a.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "x: %f y: %f z: %f", b.x, b.y, b.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "x: %f y: %f z: %f", c.x, c.y, c.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "FOV x: %f y: %f", renderView->fov_x, renderView->fov_y); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "ViewAngles Pitch: %f Yaw: %f Roll: %f", viewAngles.pitch, viewAngles.yaw, viewAngles.roll); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - sprintf(strText, "ViewBobAngles Pitch: %f Yaw: %f Roll: %f", viewBobAngles.pitch, viewBobAngles.yaw, viewBobAngles.roll); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - y += 12; - a = GetEyePosition(); - sprintf(strText, "EyePosition x: %f y: %f z: %f", a.x, a.y, a.z); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); -} - -/* -=============== -idPlayer::DrawHUD -=============== -*/ -void idPlayer::DrawHUD(idUserInterface *_hud) -{ -// if(cv_lg_debug.GetInteger() != 0) -// PrintDebugHUD(); - - /*renderSystem->DrawSmallStringExt(1, 30, - va("Player velocity: %f", physicsObj.GetLinearVelocity().Length()), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" ));*/ - - const char *name; - if((name = cv_dm_distance.GetString()) != NULL) - { - idEntity *e; - - if((e = gameLocal.FindEntity(name)) != NULL) - { - idStr strText; - float d; - int y; - - d = (GetPhysics()->GetOrigin() - e->GetPhysics()->GetOrigin()).Length(); - - y = 100; - sprintf(strText, "Entity [%s] distance: %f", name, d); - renderSystem->DrawSmallStringExt(1, y, strText.c_str( ), idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - } - } - - if (cv_frob_debug_hud.GetBool()) - { - idStr name = m_FrobEntity.GetEntity() != NULL ? m_FrobEntity.GetEntity()->name : "none"; - renderSystem->DrawSmallStringExt(1, 120, "Frobbed entity: " + name, idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - - if (m_FrobEntity.GetEntity() != NULL) - { - float distance = (GetEyePosition() - m_FrobTrace.endpos).Length(); - idStr distanceStr = "Distance: " + idStr(distance); - renderSystem->DrawSmallStringExt(1, 150, distanceStr, idVec4( 1, 1, 1, 1 ), false, declManager->FindMaterial( "textures/bigchars" )); - } - } - - if(_hud) - { - DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("PlayerHUD: [%s]\r", (_hud->Name() == NULL)?"null":_hud->Name()); - } - else - { - DM_LOG(LC_SYSTEM, LT_INFO)LOGSTRING("PlayerHUD: NULL\r"); - } - - if ( !weapon.GetEntity() || influenceActive != INFLUENCE_NONE || privateCameraView || gameLocal.GetCamera() || !_hud || !g_showHud.GetBool() ) { - return; - } - - UpdateHudStats( _hud ); - - //_hud->SetStateString( "weapicon", weapon.GetEntity()->Icon() ); - - // FIXME: this is temp to allow the sound meter to show up in the hud - // it should be commented out before shipping but the code can remain - // for mod developers to enable for the same functionality - _hud->SetStateInt( "s_debug", cvarSystem->GetCVarInteger( "s_showLevelMeter" ) ); - - weapon.GetEntity()->UpdateGUI(); - - //_hud->Redraw( gameLocal.realClientTime ); - m_overlays.drawOverlays(); - - // weapon targeting crosshair - -#if 0 // greebo: disabled cursor calls entirely - if ( !GuiActive() ) { - if ( cursor && weapon.GetEntity()->ShowCrosshair() ) { - cursor->Redraw( gameLocal.realClientTime ); - } - } -#endif - - // Only use this if the old lightgem is selected. This may be usefull for - // slower machines. - if (cv_lg_weak.GetBool()) - { - CalculateWeakLightgem(); - } - - // J.C.Denton Start - float fFadeDelay = Max(0.0001f, cv_lg_fade_delay.GetFloat() ); // Avoid divide by zero errors. - m_fBlendColVal = Lerp( m_fBlendColVal, (float)m_LightgemValue, (gameLocal.time - gameLocal.previousTime)/(1000.0f * fFadeDelay ) ); - // J.C.Denton End - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Setting Lightgemvalue: %u on hud: %08lX\r\r", m_LightgemValue, hud); - hud->SetStateFloat("lightgem_val", m_fBlendColVal ); -} - -/* -=============== -idPlayer::EnterCinematic -=============== -*/ -void idPlayer::EnterCinematic( void ) { - Hide(); - - physicsObj.SetLinearVelocity( vec3_origin ); - - SetState( "EnterCinematic" ); - UpdateScript(); - - if ( weaponEnabled && weapon.GetEntity() ) { - weapon.GetEntity()->EnterCinematic(); - } - - AI_FORWARD = false; - AI_BACKWARD = false; - AI_STRAFE_LEFT = false; - AI_STRAFE_RIGHT = false; - AI_RUN = false; - AI_ATTACK_HELD = false; - AI_BLOCK_HELD = false; - AI_WEAPON_FIRED = false; - AI_WEAPON_BLOCKED = false; - AI_JUMP = false; - AI_CROUCH = false; - AI_ONGROUND = true; - AI_ONLADDER = false; - AI_DEAD = ( health <= 0 ); - AI_RUN = false; - AI_PAIN = false; - AI_HARDLANDING = false; - AI_SOFTLANDING = false; - AI_RELOAD = false; - AI_TELEPORT = false; - AI_TURN_LEFT = false; - AI_TURN_RIGHT = false; - - AI_LEAN_LEFT = false; - AI_LEAN_RIGHT = false; - AI_LEAN_FORWARD = false; - - AI_CREEP = false; - - m_pathRank = 1000; // grayman #2345 -} - -/* -=============== -idPlayer::ExitCinematic -=============== -*/ -void idPlayer::ExitCinematic( void ) { - Show(); - - if ( weaponEnabled && weapon.GetEntity() ) { - weapon.GetEntity()->ExitCinematic(); - } - - SetState( "ExitCinematic" ); - UpdateScript(); -} - -/* -===================== -idPlayer::UpdateConditions -===================== -*/ -void idPlayer::UpdateConditions( void ) -{ - idVec3 velocity; - float fallspeed; - float forwardspeed; - float sidespeed; - - // minus the push velocity to avoid playing the walking animation and sounds when riding a mover - velocity = physicsObj.GetLinearVelocity() - physicsObj.GetPushedLinearVelocity(); - fallspeed = velocity * physicsObj.GetGravityNormal(); - - if ( influenceActive ) { - AI_FORWARD = false; - AI_BACKWARD = false; - AI_STRAFE_LEFT = false; - AI_STRAFE_RIGHT = false; - } else if ( gameLocal.time - lastDmgTime < 500 ) { - forwardspeed = velocity * viewAxis[ 0 ]; - sidespeed = velocity * viewAxis[ 1 ]; - AI_FORWARD = AI_ONGROUND && ( forwardspeed > 20.01f ); - AI_BACKWARD = AI_ONGROUND && ( forwardspeed < -20.01f ); - AI_STRAFE_LEFT = AI_ONGROUND && ( sidespeed > 20.01f ); - AI_STRAFE_RIGHT = AI_ONGROUND && ( sidespeed < -20.01f ); - } else if ( xyspeed > MIN_BOB_SPEED ) { - AI_FORWARD = AI_ONGROUND && ( usercmd.forwardmove > 0 ); - AI_BACKWARD = AI_ONGROUND && ( usercmd.forwardmove < 0 ); - AI_STRAFE_LEFT = AI_ONGROUND && ( usercmd.rightmove < 0 ); - AI_STRAFE_RIGHT = AI_ONGROUND && ( usercmd.rightmove > 0 ); - } else { - AI_FORWARD = false; - AI_BACKWARD = false; - AI_STRAFE_LEFT = false; - AI_STRAFE_RIGHT = false; - } - - m_pathRank = AI_FORWARD ? rank : 1000; // grayman #2345 - - // stamina disabled, always run regardless of stamina - //AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); - AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && true ; - AI_DEAD = ( health <= 0 ); - - // DarkMod: Catch the creep modifier - AI_CREEP =( usercmd.buttons & BUTTON_5 ) && true; -} - -/* -================== -WeaponFireFeedback - -Called when a weapon fires, generates head twitches, etc -================== -*/ -void idPlayer::WeaponFireFeedback( const idDict *weaponDef ) { - // force a blink - blink_time = 0; - - // play the fire animation - AI_WEAPON_FIRED = true; - - // update view feedback - playerView.WeaponFireFeedback( weaponDef ); -} - -/* -=============== -idPlayer::StopFiring -=============== -*/ -void idPlayer::StopFiring( void ) -{ - AI_ATTACK_HELD = false; - AI_BLOCK_HELD = false; - AI_WEAPON_BLOCKED = false; - AI_WEAPON_FIRED = false; - AI_RELOAD = false; - if ( weapon.GetEntity() ) { - weapon.GetEntity()->EndAttack(); - } -} - -/* -=============== -idPlayer::FireWeapon -=============== -*/ -void idPlayer::FireWeapon( void ) -{ - idMat3 axis; - idVec3 muzzle; - - if ( privateCameraView ) { - return; - } - - if ( g_editEntityMode.GetInteger() ) { - GetViewPos( muzzle, axis ); - if ( gameLocal.editEntities->SelectEntity( muzzle, axis[0], this ) ) { - return; - } - } - - if ( !hiddenWeapon && weapon.GetEntity()->IsReady() ) - { - if ( weapon.GetEntity()->AmmoInClip() || weapon.GetEntity()->AmmoAvailable() ) - { - AI_ATTACK_HELD = true; - weapon.GetEntity()->BeginAttack(); - } else if( cv_weapon_next_on_empty.GetBool() ) - { - NextBestWeapon(); - } - } -} - -/* -=============== -idPlayer::BlockWeapon -=============== -*/ -void idPlayer::BlockWeapon( void ) -{ - if ( privateCameraView ) - { - return; - } - - if ( !hiddenWeapon && weapon.GetEntity()->IsReady() ) - { - if (AI_ATTACK_HELD) // grayman #597 - { - ignoreWeaponAttack = true; - } - AI_BLOCK_HELD = true; - weapon.GetEntity()->BeginBlock(); - } -} - -/* -=============== -idPlayer::CacheWeapons -=============== -*/ -void idPlayer::CacheWeapons() -{ - // greebo: Cache all weapons, regardless if we have them or not - for (const idKeyValue* kv = spawnArgs.MatchPrefix("def_weapon"); kv != NULL; kv = spawnArgs.MatchPrefix("def_weapon", kv)) - { - if (kv->GetValue().IsEmpty()) continue; // skip empty spawnargs - - idWeapon::CacheWeapon(kv->GetValue()); - } -} - -/* -=============== -idPlayer::Give -=============== -*/ -bool idPlayer::Give( const char *statname, const char *value ) { - int amount; - - if ( AI_DEAD ) { - return false; - } - - if ( !idStr::Icmp( statname, "health" ) ) { - if ( health >= maxHealth ) { - return false; - } - amount = atoi( value ); - if ( amount ) { - health += amount; - if ( health > maxHealth ) { - health = maxHealth; - } - if ( hud ) { - hud->HandleNamedEvent( "healthPulse" ); - } - } - - } else if ( !idStr::Icmp( statname, "stamina" ) ) { - if ( stamina >= 100 ) { - return false; - } - stamina += atof( value ); - if ( stamina > 100 ) { - stamina = 100; - } - - } else if ( !idStr::Icmp( statname, "heartRate" ) ) { - heartRate += atoi( value ); - if ( heartRate > MAX_HEARTRATE ) { - heartRate = MAX_HEARTRATE; - } - - } else if ( !idStr::Icmp( statname, "air" ) ) { - if ( airTics >= pm_airTics.GetInteger() ) { - return false; - } - airTics += static_cast(atof( value ) / 100.0 * pm_airTics.GetInteger()); - if ( airTics > pm_airTics.GetInteger() ) { - airTics = pm_airTics.GetInteger(); - } - } else { - return false;//inventory.Give( this, spawnArgs, statname, value, &idealWeapon, true ); - } - return true; -} - - -/* -=============== -idPlayer::GiveHealthPool - -adds health to the player health pool -=============== -*/ -void idPlayer::GiveHealthPool( float amt ) { - - if ( AI_DEAD ) { - return; - } - - if ( health > 0 ) { - healthPool += amt; - if ( healthPool > maxHealth - health ) { - healthPool = maxHealth - health; - } - nextHealthPulse = gameLocal.time; - - // Reset the values to default - healthPoolTimeInterval = HEALTHPULSE_TIME; - healthPoolTimeIntervalFactor = 1.0f; - healthPoolStepAmount = 5; - } -} - -/* -=============== -idPlayer::PowerUpModifier -=============== -*/ -float idPlayer::PowerUpModifier( int type ) { - // greebo: Unused at the moment, maybe in the future - return 1.0f; -} - -/* -=============== -idPlayer::GivePowerUp -=============== -*/ -bool idPlayer::GivePowerUp( int powerup, int time ) { - const char *sound; - const char *skin; - - if ( powerup >= 0 && powerup < MAX_POWERUPS ) { - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteShort( powerup ); - msg.WriteBits( 1, 1 ); - ServerSendEvent( EVENT_POWERUP, &msg, false, -1 ); - } - - const idDeclEntityDef *def = NULL; - - switch( powerup ) { - case BERSERK: { - if ( spawnArgs.GetString( "snd_berserk_third", "", &sound ) ) { - StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_DEMONIC, 0, false, NULL ); - } - if ( baseSkinName.Length() ) { - powerUpSkin = declManager->FindSkin( baseSkinName + "_berserk" ); - } - if ( !gameLocal.isClient ) { - idealWeapon = 0; - } - break; - } - case INVISIBILITY: { - spawnArgs.GetString( "skin_invisibility", "", &skin ); - powerUpSkin = declManager->FindSkin( skin ); - // remove any decals from the model - if ( modelDefHandle != -1 ) { - gameRenderWorld->RemoveDecals( modelDefHandle ); - } - if ( weapon.GetEntity() ) { - weapon.GetEntity()->UpdateSkin(); - } - if ( spawnArgs.GetString( "snd_invisibility", "", &sound ) ) { - StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_ANY, 0, false, NULL ); - } - break; - } - case ADRENALINE: { - stamina = 100.0f; - break; - } - case MEGAHEALTH: { - if ( spawnArgs.GetString( "snd_megahealth", "", &sound ) ) { - StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_ANY, 0, false, NULL ); - } - def = gameLocal.FindEntityDef( "powerup_megahealth", false ); - if ( def ) { - health = def->dict.GetInt( "inv_health" ); - } - break; - } - } - - if ( hud ) { - hud->HandleNamedEvent( "itemPickup" ); - } - - return true; - } else { - gameLocal.Warning( "Player given power up %i\n which is out of range", powerup ); - } - return false; -} - -/* -============== -idPlayer::UpdatePowerUps -============== -*/ -void idPlayer::UpdatePowerUps( void ) { - if ( health > 0 ) { - if ( powerUpSkin ) { - renderEntity.customSkin = powerUpSkin; - } else { - renderEntity.customSkin = skin; - } - } - - if ( healthPool && gameLocal.time > nextHealthPulse && !AI_DEAD && health > 0 ) { - assert( !gameLocal.isClient ); // healthPool never be set on client - - //int amt = ( healthPool > 5 ) ? 5 : healthPool; // old code - // greebo: Changed step amount to be a variable that can be set from the "outside" - int amt = ( healthPool > healthPoolStepAmount ) ? healthPoolStepAmount : static_cast(healthPool); - - int oldHealth = health; - - health += amt; - if ( health > maxHealth ) { - health = maxHealth; - healthPool = 0; - } else { - healthPool -= amt; - } - - // greebo: Check how much health we actually took - int healthTaken = health - oldHealth; - // Update the mission statistics - gameLocal.m_MissionData->HealthReceivedByPlayer(healthTaken); - - nextHealthPulse = gameLocal.time + healthPoolTimeInterval; - - // Check whether we have a valid interval factor and if yes: apply it - if (healthPoolTimeIntervalFactor > 0) { - healthPoolTimeInterval = static_cast(healthPoolTimeInterval*healthPoolTimeIntervalFactor); - } - - healthPulse = true; - } -#ifndef ID_DEMO_BUILD - if ( !gameLocal.inCinematic && influenceActive == 0 && g_skill.GetInteger() == 3 && gameLocal.time > nextHealthTake && !AI_DEAD && health > g_healthTakeLimit.GetInteger() ) { - assert( !gameLocal.isClient ); // healthPool never be set on client - health -= g_healthTakeAmt.GetInteger(); - if ( health < g_healthTakeLimit.GetInteger() ) { - health = g_healthTakeLimit.GetInteger(); - } - nextHealthTake = gameLocal.time + g_healthTakeTime.GetInteger() * 1000; - healthTake = true; - } -#endif -} - -/* -=============== -idPlayer::GiveItem -=============== -*/ -void idPlayer::GiveItem( const char *itemname ) { - idDict args; - - args.Set( "classname", itemname ); - args.Set( "owner", name.c_str() ); - gameLocal.SpawnEntityDef( args ); - if ( hud ) { - hud->HandleNamedEvent( "itemPickup" ); - } -} - -/* -================== -idPlayer::SlotForWeapon -================== -*/ -int idPlayer::SlotForWeapon( const char *weaponName ) -{ - // Find the weapon category - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - if (weaponCategory == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find weapon category in inventory.\r"); - return -1; - } - - // Look for the weapon with the given name - for (int i = 0; i < weaponCategory->GetNumItems(); i++) - { - CInventoryWeaponItemPtr weaponItem = - boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); - - // Is this the right weapon? - if (weaponItem != NULL && weaponItem->GetWeaponName() == weaponName) - { - // We're done - return i; - } - } - - // not found - return -1; -} - -/* -=============== -idPlayer::Reload -=============== -*/ -void idPlayer::Reload( void ) { - if ( gameLocal.isClient ) { - return; - } - - if ( spectating || gameLocal.inCinematic || influenceActive ) { - return; - } - - if ( weapon.GetEntity() && weapon.GetEntity()->IsLinked() ) { - weapon.GetEntity()->Reload(); - } -} - -/* -=============== -idPlayer::NextBestWeapon -=============== -*/ -void idPlayer::NextBestWeapon( void ) { - // greebo: No "best" weapons in TDM, route the call to NextWeapon() - NextWeapon(); -} - -int idPlayer::GetHightestWeaponIndex() -{ - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - assert(weaponCategory != NULL); - - int numWeapons = weaponCategory->GetNumItems(); - - int highestIndex = -1; - - for (int i = 0; i < numWeapons; ++i) - { - CInventoryWeaponItemPtr item = boost::dynamic_pointer_cast(weaponCategory->GetItem(i)); - - assert(item != NULL); - - int candidate = item->GetWeaponIndex(); - - if (candidate > highestIndex) - { - highestIndex = candidate; - } - } - - return highestIndex; -} - -/* -=============== -idPlayer::NextWeapon -=============== -*/ -void idPlayer::NextWeapon() { - if ( !weaponEnabled || spectating || hiddenWeapon || gameLocal.inCinematic || gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) || health < 0 ) { - return; - } - - if ( gameLocal.isClient ) { - return; - } - - if (m_WeaponCursor == NULL || m_WeaponCursor->GetCurrentCategory() == NULL) { - return; - } - - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - int numWeapons = weaponCategory->GetNumItems(); - - if (numWeapons == 0) { - return; // no weapons... - } - - // Get the current weaponItem - CInventoryWeaponItemPtr curItem = GetCurrentWeaponItem(); - - if (curItem == NULL) { - return; - } - - int curWeaponIndex = curItem->GetWeaponIndex(); - int highestIndex = GetHightestWeaponIndex(); - - int nextWeaponIndex = curWeaponIndex; - - do - { - // Try to select the next weapon item - nextWeaponIndex++; - - if (nextWeaponIndex > highestIndex) - { - nextWeaponIndex = 0; - } - } while (!SelectWeapon(nextWeaponIndex, false) && nextWeaponIndex != curWeaponIndex); -} - -/* -=============== -idPlayer::PrevWeapon -=============== -*/ -void idPlayer::PrevWeapon( void ) { - if ( !weaponEnabled || spectating || hiddenWeapon || gameLocal.inCinematic || gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) || health < 0 ) { - return; - } - - if ( gameLocal.isClient ) { - return; - } - - if (m_WeaponCursor == NULL || m_WeaponCursor->GetCurrentCategory() == NULL) { - return; - } - - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - int numWeapons = weaponCategory->GetNumItems(); - - if (numWeapons == 0) { - return; // no weapons... - } - - // Get the current weaponItem - CInventoryWeaponItemPtr curItem = GetCurrentWeaponItem(); - - if (curItem == NULL) { - return; - } - - int curWeaponIndex = curItem->GetWeaponIndex(); - int highestIndex = GetHightestWeaponIndex(); - - int prevWeaponIndex = curWeaponIndex; - - do - { - // Try to select the previous weapon item - prevWeaponIndex--; - - if (prevWeaponIndex < 0) - { - prevWeaponIndex = highestIndex; - } - } while (!SelectWeapon(prevWeaponIndex, false) && prevWeaponIndex != curWeaponIndex); -} - -/* -=============== -idPlayer::SelectWeapon -=============== -*/ -bool idPlayer::SelectWeapon( int num, bool force ) -{ - if ( !weaponEnabled || spectating || gameLocal.inCinematic || health < 0 ) { - return false; - } - - if ( gameLocal.isClient ) { - return false; - } - - if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { - num = weapon_fists; - hiddenWeapon ^= 1; - if ( hiddenWeapon && weapon.GetEntity() ) { - weapon.GetEntity()->LowerWeapon(); - } else { - weapon.GetEntity()->RaiseWeapon(); - } - } - - if (m_WeaponCursor == NULL) { - return false; - } - - // Check if we want to toggle the current weapon item (requested index == current index) - CInventoryWeaponItemPtr item = GetCurrentWeaponItem(); - - if (item != NULL && item->GetWeaponIndex() == num && item->IsToggleable()) { - // Requested toggleable weapon is already active, hide it (switch to unarmed) - num = 0; - } - - CInventoryCategoryPtr category = m_WeaponCursor->GetCurrentCategory(); - if (category == NULL) { - return false; - } - - // Cycle through the weapons and find the one with the given weaponIndex - for (int i = 0; i < category->GetNumItems(); i++) - { - // Try to retrieve a weapon item from the given category - CInventoryWeaponItemPtr item = - boost::dynamic_pointer_cast(category->GetItem(i)); - - if (item != NULL && item->GetWeaponIndex() == num) - { - if (item->GetAmmo() <= 0 && item->NeedsAmmo()) - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon requires ammo. Cannot select: %d\r", num); - break; - } - - if (!item->IsEnabled()) - { - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Weapon not enabled, cannot select: %d\r", num); - break; - } - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Selecting weapon #%d\r", num); - - // Set the cursor onto this item - m_WeaponCursor->SetCurrentItem(item); - - weaponSwitchTime = gameLocal.time + WEAPON_SWITCH_DELAY; - idealWeapon = num; - - UpdateHudWeapon(); - return true; - } - } - - return false; -} - -/* -================= -idPlayer::DropWeapon -================= -*/ -void idPlayer::DropWeapon( bool died ) { - idVec3 forward, up; - int inclip, ammoavailable; - - assert( !gameLocal.isClient ); - - if ( spectating || weaponGone || weapon.GetEntity() == NULL ) { - return; - } - - if ( ( !died && !weapon.GetEntity()->IsReady() ) || weapon.GetEntity()->IsReloading() ) { - return; - } - // ammoavailable is how many shots we can fire - // inclip is which amount is in clip right now - ammoavailable = weapon.GetEntity()->AmmoAvailable(); - inclip = weapon.GetEntity()->AmmoInClip(); - - // don't drop a grenade if we have none left - /*if ( !idStr::Icmp( idWeapon::GetAmmoNameForNum( weapon.GetEntity()->GetAmmoType() ), "ammo_grenades" ) && ( ammoavailable - inclip <= 0 ) ) { - return; - }*/ - - // expect an ammo setup that makes sense before doing any dropping - // ammoavailable is -1 for infinite ammo, and weapons like chainsaw - // a bad ammo config usually indicates a bad weapon state, so we should not drop - // used to be an assertion check, but it still happens in edge cases - if ( ( ammoavailable != -1 ) && ( ammoavailable - inclip < 0 ) ) { - common->DPrintf( "idPlayer::DropWeapon: bad ammo setup\n" ); - return; - } - idEntity *item = NULL; - if ( died ) { - // ain't gonna throw you no weapon if I'm dead - item = weapon.GetEntity()->DropItem( vec3_origin, 0, WEAPON_DROP_TIME, died ); - } else { - viewAngles.ToVectors( &forward, NULL, &up ); - item = weapon.GetEntity()->DropItem( 250.0f * forward + 150.0f * up, 500, WEAPON_DROP_TIME, died ); - } - if ( !item ) { - return; - } - // set the appropriate ammo in the dropped object - const idKeyValue * keyval = item->spawnArgs.MatchPrefix( "inv_ammo_" ); - if ( keyval ) { - item->spawnArgs.SetInt( keyval->GetKey(), ammoavailable ); - idStr inclipKey = keyval->GetKey(); - inclipKey.Insert( "inclip_", 4 ); - item->spawnArgs.SetInt( inclipKey, inclip ); - } - if ( !died ) { - // remove from our local inventory completely - weapon.GetEntity()->ResetAmmoClip(); - NextWeapon(); - weapon.GetEntity()->WeaponStolen(); - weaponGone = true; - } -} - -/* -================= -idPlayer::StealWeapon -steal the target player's current weapon -================= -*/ -void idPlayer::StealWeapon( idPlayer *player ) -{ - assert( !gameLocal.isClient ); - - // make sure there's something to steal - idWeapon *player_weapon = static_cast< idWeapon * >( player->weapon.GetEntity() ); - if ( !player_weapon || !player_weapon->CanDrop() || weaponGone ) { - return; - } - // steal - we need to effectively force the other player to abandon his weapon - int newweap = player->currentWeapon; - if ( newweap == -1 ) { - return; - } - - const char *weapon_classname = spawnArgs.GetString( va( "def_weapon%d", newweap ) ); - assert( weapon_classname ); - int ammoavailable = player->weapon.GetEntity()->AmmoAvailable(); - int inclip = player->weapon.GetEntity()->AmmoInClip(); - if ( ( ammoavailable != -1 ) && ( ammoavailable - inclip < 0 ) ) { - // see DropWeapon - common->DPrintf( "idPlayer::StealWeapon: bad ammo setup\n" ); - // we still steal the weapon, so let's use the default ammo levels - inclip = -1; - const idDeclEntityDef *decl = gameLocal.FindEntityDef( weapon_classname ); - assert( decl ); - const idKeyValue *keypair = decl->dict.MatchPrefix( "inv_ammo_" ); - assert( keypair ); - ammoavailable = atoi( keypair->GetValue() ); - } - - player->weapon.GetEntity()->WeaponStolen(); - //player->inventory.Drop( player->spawnArgs, NULL, newweap ); - player->SelectWeapon( weapon_fists, false ); - // in case the robbed player is firing rounds with a continuous fire weapon like the chaingun/plasma etc. - // this will ensure the firing actually stops - player->weaponGone = true; - - // give weapon, setup the ammo count - Give( "weapon", weapon_classname ); - idealWeapon = newweap; -} - -/* -=============== -idPlayer::ActiveGui -=============== -*/ -idUserInterface *idPlayer::ActiveGui( void ) -{ - if ( m_overlays.findInteractive() ) - return m_overlays.findInteractive(); - - return NULL; // greebo: No focusUI anymore - //return focusUI; -} - -/* -=============== -idPlayer::Weapon_Combat -=============== -*/ -void idPlayer::Weapon_Combat( void ) { - if ( influenceActive || !weaponEnabled || gameLocal.inCinematic || privateCameraView ) { - return; - } - - weapon.GetEntity()->RaiseWeapon(); - if ( weapon.GetEntity()->IsReloading() ) { - if ( !AI_RELOAD ) { - AI_RELOAD = true; - SetState( "ReloadWeapon" ); - UpdateScript(); - } - } else { - AI_RELOAD = false; - } - - if ( idealWeapon != currentWeapon ) { - if ( weaponCatchup ) { - assert( gameLocal.isClient ); - - currentWeapon = idealWeapon; - weaponGone = false; - animPrefix = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); - weapon.GetEntity()->GetWeaponDef( animPrefix, 0 /*inventory.clip[ currentWeapon ]*/ ); - animPrefix.Strip( "weapon_" ); - - weapon.GetEntity()->NetCatchup(); - const function_t *newstate = GetScriptFunction( "NetCatchup" ); - if ( newstate ) { - SetState( newstate ); - UpdateScript(); - } - weaponCatchup = false; - } else { - - // grayman #597 - if the current weapon is an arrow, and the ideal - // weapon is also an arrow, make the switch, but - // don't play the "lower bow, then raise bow" animation. - - weapon.GetEntity()->SetArrow2Arrow((currentWeapon >= ARROW_WEAPON_INDEX_BEGIN) && (idealWeapon >= ARROW_WEAPON_INDEX_BEGIN)); - - if ( weapon.GetEntity()->IsReady() ) { - weapon.GetEntity()->PutAway(); - if (usercmd.buttons & BUTTON_ATTACK) // grayman #597 - is this an aborted attack while the attack button is depressed? - { - ignoreWeaponAttack = true; // this stays true until the attack button is released - } - } - - if ( weapon.GetEntity()->IsHolstered() ) { - assert( idealWeapon >= 0 ); - - if ( !spawnArgs.GetBool( va( "weapon%d_toggle", currentWeapon ) ) ) { - previousWeapon = currentWeapon; - } - currentWeapon = idealWeapon; - weaponGone = false; - animPrefix = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); - weapon.GetEntity()->GetWeaponDef( animPrefix, 0/*inventory.clip[ currentWeapon ]*/ ); - animPrefix.Strip( "weapon_" ); - weapon.GetEntity()->Raise(); - } - } - } else { - weaponGone = false; // if you drop and re-get weap, you may miss the = false above - if ( weapon.GetEntity()->IsHolstered() ) { - if ( !weapon.GetEntity()->AmmoAvailable() ) - { - // weapons can switch automatically if they have no more ammo - // ishtvan: Only if the cvar is set - if (cv_weapon_next_on_empty.GetBool()) - { - NextBestWeapon(); - } - else - { - // Switch to unarmed if no more ammo available - SelectWeapon(weapon_fists, false); - } - } - else - { - weapon.GetEntity()->Raise(); - state = GetScriptFunction( "RaiseWeapon" ); - if ( state ) { - SetState( state ); - } - } - } - } - - if (!(usercmd.buttons & BUTTON_ATTACK) && (oldButtons & BUTTON_ATTACK)) // grayman #597 - was the attack button just released? - { - ignoreWeaponAttack = false; - } - - // check for attack - AI_WEAPON_FIRED = false; - if ( !influenceActive ) - { - // grayman #597 - if ignoreWeaponAttack is true, the weapon is no longer in the attack state, but the attack button is still depressed - if ( ( usercmd.buttons & BUTTON_ATTACK ) && !weaponGone && !ignoreWeaponAttack) - { - FireWeapon(); - } - else if ( oldButtons & BUTTON_ATTACK ) - { - AI_ATTACK_HELD = false; - weapon.GetEntity()->EndAttack(); - } - } - - // check for block - AI_WEAPON_BLOCKED = false; - if ( !influenceActive ) - { - if ( ( usercmd.buttons & BUTTON_ZOOM ) && !weaponGone ) - { - BlockWeapon(); - } - else if ( oldButtons & BUTTON_ZOOM ) - { - AI_BLOCK_HELD = false; - weapon.GetEntity()->EndBlock(); - } - } - - // update our ammo clip in our inventory - if ( currentWeapon == idealWeapon ) { - UpdateHudAmmo(); - } -} - -/* -=============== -idPlayer::Weapon_NPC -=============== -*/ -#if 0 -void idPlayer::Weapon_NPC( void ) { - if ( idealWeapon != currentWeapon ) { - Weapon_Combat(); - } - StopFiring(); - weapon.GetEntity()->LowerWeapon(); - - if ( ( usercmd.buttons & BUTTON_ATTACK ) && !( oldButtons & BUTTON_ATTACK ) ) { - buttonMask |= BUTTON_ATTACK; - focusCharacter->TalkTo( this ); - } -} -#endif - -/* -=============== -idPlayer::LowerWeapon -=============== -*/ -void idPlayer::LowerWeapon( void ) { - if ( weapon.GetEntity() && !weapon.GetEntity()->IsHidden() ) { - weapon.GetEntity()->LowerWeapon(); - } -} - -/* -=============== -idPlayer::RaiseWeapon -=============== -*/ -void idPlayer::RaiseWeapon( void ) -{ - if (weapon.GetEntity() && - weapon.GetEntity()->IsHidden() && - !(GetImmobilization() & EIM_ATTACK)) - { - weapon.GetEntity()->RaiseWeapon(); - } -} - -/* -=============== -idPlayer::WeaponLoweringCallback -=============== -*/ -void idPlayer::WeaponLoweringCallback( void ) { - SetState( "LowerWeapon" ); - UpdateScript(); - UpdateWeaponEncumbrance(); -} - -/* -=============== -idPlayer::WeaponRisingCallback -=============== -*/ -void idPlayer::WeaponRisingCallback( void ) { - SetState( "RaiseWeapon" ); - UpdateScript(); - UpdateWeaponEncumbrance(); -} - -/* -=============== -idPlayer::Weapon_GUI -=============== -*/ -void idPlayer::Weapon_GUI( void ) -{ - if ( idealWeapon != currentWeapon ) { - Weapon_Combat(); - } - StopFiring(); - weapon.GetEntity()->LowerWeapon(); - - // disable click prediction for the GUIs. handy to check the state sync does the right thing - if ( gameLocal.isClient && !net_clientPredictGUI.GetBool() ) { - return; - } - - if ( ( oldButtons ^ usercmd.buttons ) & BUTTON_ATTACK ) { - sysEvent_t ev; - const char *command = NULL; - bool updateVisuals = false; - - idUserInterface *ui = ActiveGui(); - if ( ui ) { - ev = sys->GenerateMouseButtonEvent( 1, ( usercmd.buttons & BUTTON_ATTACK ) != 0 ); - command = ui->HandleEvent( &ev, gameLocal.time, &updateVisuals ); -#if 0 - if ( updateVisuals && focusGUIent && ui == focusUI ) { - focusGUIent->UpdateVisuals(); - } -#endif - } - if ( gameLocal.isClient ) { - // we predict enough, but don't want to execute commands - return; - } - -#if 0 - if ( focusGUIent ) { - HandleGuiCommands( focusGUIent, command ); - } else { - HandleGuiCommands( this, command ); - } -#else // greebo: Replaced the above with this, no focusGUIEnt anymore - HandleGuiCommands( this, command ); -#endif - } -} - -/* -=============== -idPlayer::UpdateWeapon -=============== -*/ -void idPlayer::UpdateWeapon( void ) { - if ( health <= 0 ) { - return; - } - - assert( !spectating ); - - if ( gameLocal.isClient ) { - // clients need to wait till the weapon and it's world model entity - // are present and synchronized ( weapon.worldModel idEntityPtr to idAnimatedEntity ) - if ( !weapon.GetEntity()->IsWorldModelReady() ) { - return; - } - } - - // always make sure the weapon is correctly setup before accessing it - if ( !weapon.GetEntity()->IsLinked() ) { - if ( idealWeapon != -1 ) { - animPrefix = spawnArgs.GetString( va( "def_weapon%d", idealWeapon ) ); - weapon.GetEntity()->GetWeaponDef( animPrefix, 0/*inventory.clip[ idealWeapon ]*/ ); - assert( weapon.GetEntity()->IsLinked() ); - } else { - return; - } - } - - if ( g_dragEntity.GetBool() ) { - StopFiring(); - weapon.GetEntity()->LowerWeapon(); - dragEntity.Update( this ); - } else if ( ActiveGui() ) { - // gui handling overrides weapon use - Weapon_GUI(); -#if 0 - } else if ( focusCharacter && ( focusCharacter->health > 0 ) ) { - Weapon_NPC(); -#endif - } else if( gameLocal.m_Grabber->GetSelected() ) { - gameLocal.m_Grabber->Update( this, true ); - } else { - Weapon_Combat(); - } - - if( GetImmobilization() & EIM_ATTACK ) - { - StopFiring(); - weapon.GetEntity()->LowerWeapon(); - } - - if ( hiddenWeapon ) { - weapon.GetEntity()->LowerWeapon(); - } - - // update weapon state, particles, dlights, etc - weapon.GetEntity()->PresentWeapon( showWeaponViewModel ); -} - -void idPlayer::ChangeWeaponProjectile(const idStr& weaponName, const idStr& projectileDefName) -{ - CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); - if (weaponItem == NULL) return; - - weaponItem->SetProjectileDefName(projectileDefName); -} - -void idPlayer::ResetWeaponProjectile(const idStr& weaponName) -{ - CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); - if (weaponItem == NULL) return; - - weaponItem->ResetProjectileDefName(); -} - -void idPlayer::ChangeWeaponName(const idStr& weaponName, const idStr& displayName) -{ - CInventoryWeaponItemPtr weaponItem = GetWeaponItem(weaponName); - if (weaponItem == NULL) return; - - if (!displayName.IsEmpty()) - { - weaponItem->SetName(displayName); - } - else - { - const idDeclEntityDef* def = gameLocal.FindEntityDef(weaponItem->GetWeaponDefName()); - - if (def != NULL) - { - // Empty name passed, reset to definition - weaponItem->SetName(def->dict.GetString("inv_name")); - } - } - - UpdateHudWeapon(); -} - -void idPlayer::SetIsPushing(bool isPushing) -{ - this->isPushing = isPushing; - - // Raise/lower the weapons according to our push state - SetImmobilization("pushing", isPushing ? EIM_ATTACK : 0); -} - -bool idPlayer::IsPushing() -{ - return isPushing; -} - -void idPlayer::OnStartShoulderingBody(idEntity* body) -{ - // grayman #2478 - shouldering light bodies, like rats, shouldn't elicit shouldering sounds - - idStr sound = "snd_shoulder_body"; - - // Check if the other body is at least 30 kg heavier than us - - if ( body->GetPhysics()->GetMass() >= ( GetPhysics()->GetMass() + 30 ) ) - { - sound = "snd_shoulder_body_heavy"; - } - else if ( body->GetPhysics()->GetMass() <= 10 ) // very light? - { - sound = ""; - } - - // play the sound on the player, not the body (that was creating inconsistent volume) - if ( sound.Length() > 0 ) - { - StartSound( sound.c_str(), SND_CHANNEL_ITEM, 0, false, NULL ); - } - - // set immobilizations - int immob = SHOULDER_IMMOBILIZATIONS; - - // TODO: Also make sure you can't grab anything else (hands are full) - // requires a new EIM flag? - SetImmobilization( "ShoulderedBody", SHOULDER_IMMOBILIZATIONS ); - - // set hinderance - float maxSpeed = body->spawnArgs.GetFloat("shouldered_maxspeed","1.0f"); - SetHinderance( "ShoulderedBody", 1.0f, maxSpeed ); - SetJumpHinderance( "ShoulderedBody", 1.0f, SHOULDER_JUMP_HINDERANCE ); - - // greebo: Determine which text to display on the HUD - idStr itemName; - if( body->health > 0 ) - { - itemName = body->spawnArgs.GetString("shouldered_name", "#str_02410" ); // Body - } - else - { - itemName = body->spawnArgs.GetString("shouldered_name_dead", "#str_02409" ); // Corpse - } - - // Send the name to the inventory HUD - SetGuiString(m_InventoryOverlay, "GrabbedItemName", gameLocal.m_I18N->Translate( itemName ) ); - - // Notify all GUIs about the event - m_overlays.broadcastNamedEvent("OnStartShoulderingBody"); - - // Clear the inventory cursor - SelectInventoryItem(""); - - m_bShoulderingBody = true; -} - -void idPlayer::OnStopShoulderingBody(idEntity* body) -{ - // clear immobilizations - SetImmobilization( "ShoulderedBody", 0 ); - SetHinderance( "ShoulderedBody", 1.0f, 1.0f ); - SetJumpHinderance( "ShoulderedBody", 1.0f, 1.0f ); - - // grayman #2478 - unshouldering light bodies, like rats, shouldn't elicit unshouldering sounds - - if ( body->GetPhysics()->GetMass() > 10 ) - { - StartSound( "snd_shoulder_body", SND_CHANNEL_ITEM, 0, false, NULL ); - } - - m_overlays.broadcastNamedEvent("OnStopShoulderingBody"); - - // Send the name to the inventory HUD - SetGuiString(m_InventoryOverlay, "GrabbedItemName", ""); - - m_bShoulderingBody = false; -} - -/* -=============== -idPlayer::SpectateFreeFly -=============== -*/ -void idPlayer::SpectateFreeFly( bool force ) { - idPlayer *player; - idVec3 newOrig; - idVec3 spawn_origin; - idAngles spawn_angles; - - player = gameLocal.GetClientByNum( spectator ); - if ( force || gameLocal.time > lastSpectateChange ) { - spectator = entityNumber; - if ( player && player != this && !player->spectating && !player->IsInTeleport() ) { - newOrig = player->GetPhysics()->GetOrigin(); - if ( player->physicsObj.IsCrouching() ) { - newOrig[ 2 ] += pm_crouchviewheight.GetFloat(); - } else { - newOrig[ 2 ] += pm_normalviewheight.GetFloat(); - } - newOrig[ 2 ] += SPECTATE_RAISE; - idBounds b = idBounds( vec3_origin ).Expand( pm_spectatebbox.GetFloat() * 0.5f ); - idVec3 start = player->GetPhysics()->GetOrigin(); - start[2] += pm_spectatebbox.GetFloat() * 0.5f; - trace_t t; - // assuming spectate bbox is inside stand or crouch box - gameLocal.clip.TraceBounds( t, start, newOrig, b, MASK_PLAYERSOLID, player ); - newOrig.Lerp( start, newOrig, t.fraction ); - SetOrigin( newOrig ); - idAngles angle = player->viewAngles; - angle[ 2 ] = 0; - SetViewAngles( angle ); - } else { - SelectInitialSpawnPoint( spawn_origin, spawn_angles ); - spawn_origin[ 2 ] += pm_normalviewheight.GetFloat(); - spawn_origin[ 2 ] += SPECTATE_RAISE; - SetOrigin( spawn_origin ); - SetViewAngles( spawn_angles ); - } - lastSpectateChange = gameLocal.time + 500; - } -} - -/* -=============== -idPlayer::SpectateCycle -=============== -*/ -void idPlayer::SpectateCycle( void ) { - idPlayer *player; - - if ( gameLocal.time > lastSpectateChange ) { - int latchedSpectator = spectator; - spectator = gameLocal.GetNextClientNum( spectator ); - player = gameLocal.GetClientByNum( spectator ); - assert( player ); // never call here when the current spectator is wrong - // ignore other spectators - while ( latchedSpectator != spectator && player->spectating ) { - spectator = gameLocal.GetNextClientNum( spectator ); - player = gameLocal.GetClientByNum( spectator ); - } - lastSpectateChange = gameLocal.time + 500; - } -} - -/* -=============== -idPlayer::UpdateSpectating -=============== -*/ -void idPlayer::UpdateSpectating( void ) { - assert( spectating ); - assert( !gameLocal.isClient ); - assert( IsHidden() ); - idPlayer *player; - if ( !gameLocal.isMultiplayer ) { - return; - } - player = gameLocal.GetClientByNum( spectator ); - if ( !player || ( player->spectating && player != this ) ) { - SpectateFreeFly( true ); - } else if ( usercmd.upmove > 0 ) { - SpectateFreeFly( false ); - } else if ( usercmd.buttons & BUTTON_ATTACK ) { - SpectateCycle(); - } -} - -/* -=============== -idPlayer::HandleSingleGuiCommand -=============== -*/ -bool idPlayer::HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ) { - idToken token; - - if ( !src->ReadToken( &token ) ) { - return false; - } - - if ( token == ";" ) { - return false; - } - - if ( token.Icmp( "addhealth" ) == 0 ) { - if ( entityGui && health < 100 ) { - int _health = entityGui->spawnArgs.GetInt( "gui_parm1" ); - int amt = ( _health >= HEALTH_PER_DOSE ) ? HEALTH_PER_DOSE : _health; - _health -= amt; - entityGui->spawnArgs.SetInt( "gui_parm1", _health ); - if ( entityGui->GetRenderEntity() && entityGui->GetRenderEntity()->gui[ 0 ] ) { - entityGui->GetRenderEntity()->gui[ 0 ]->SetStateInt( "gui_parm1", _health ); - } - health += amt; - if ( health > 100 ) { - health = 100; - } - } - return true; - } - - if ( token.Icmp( "ready" ) == 0 ) { - PerformImpulse( IMPULSE_17 ); - return true; - } - - src->UnreadToken( &token ); - return false; -} - -/* -============== -idPlayer::Collide -============== -*/ - -bool idPlayer::Collide( const trace_t &collision, const idVec3 &velocity ) { - if( collision.fraction == 1.0f || collision.c.type == CONTACT_NONE // didnt hit anything - || gameLocal.isClient // server computes - ) - { - return false; - } - idEntity *other = gameLocal.entities[ collision.c.entityNum ]; - // don't let player collide with grabber entity - if ( other && other != gameLocal.m_Grabber->GetSelected() ) - { - ProcCollisionStims( other, collision.c.id ); - - other->Signal( SIG_TOUCH ); - if ( !spectating ) { - if ( other->RespondsTo( EV_Touch ) ) { - other->ProcessEvent( &EV_Touch, this, &collision ); - } - } else { - if ( other->RespondsTo( EV_SpectatorTouch ) ) { - other->ProcessEvent( &EV_SpectatorTouch, this, &collision ); - } - } - } - return false; -} - -/* -================ -idPlayer::UpdateLocation - -Searches nearby locations -================ -*/ -void idPlayer::UpdateLocation( void ) { - if ( hud ) { - idLocationEntity *locationEntity = gameLocal.LocationForPoint( GetEyePosition() ); - if ( locationEntity ) { - // Tels: Make it possible that location names like "#str_01234" are automatically translated to "Kitchen" - hud->SetStateString( "location", gameLocal.m_I18N->Translate( locationEntity->GetLocation() ) ); - } else { - hud->SetStateString( "location", gameLocal.m_I18N->Translate( "#str_02911" ) ); - } - } -} - -/* -================ -idPlayer::GetLocation -================ -*/ -idLocationEntity *idPlayer::GetLocation( void ) -{ - return gameLocal.LocationForPoint( GetEyePosition() ); -} - -/* -================ -idPlayer::ClearFocus - -Clears the focus cursor -================ -*/ -#if 0 -void idPlayer::ClearFocus( void ) { - focusCharacter = NULL; - focusGUIent = NULL; - focusUI = NULL; - focusVehicle = NULL; - talkCursor = 0; -} -#endif - -/* -================ -idPlayer::UpdateFocus - -Searches nearby entities for interactive guis, possibly making one of them -the focus and sending it a mouse move event -================ -*/ -#if 0 -void idPlayer::UpdateFocus( void ) { - idClipModel *clipModelList[ MAX_GENTITIES ]; - idClipModel *clip; - int listedClipModels; - idEntity *oldFocus; - idEntity *ent; - idUserInterface *oldUI; - idAI *oldChar; - int oldTalkCursor; - idAFEntity_Vehicle *oldVehicle; - int i; - idVec3 start, end; - bool allowFocus; - const char *command; - trace_t trace; - guiPoint_t pt; - sysEvent_t ev; - idUserInterface *ui; - - if ( gameLocal.inCinematic ) { - return; - } - - // only update the focus character when attack button isn't pressed so players - // can still chainsaw NPC's - if ( gameLocal.isMultiplayer || ( !focusCharacter && ( usercmd.buttons & BUTTON_ATTACK ) ) ) { - allowFocus = false; - } else { - allowFocus = true; - } - - oldFocus = focusGUIent; - oldUI = focusUI; - oldChar = focusCharacter; - oldTalkCursor = talkCursor; - oldVehicle = focusVehicle; - - if ( focusTime <= gameLocal.time ) { - ClearFocus(); - } - - // don't let spectators interact with GUIs - if ( spectating ) { - return; - } - - start = GetEyePosition(); - end = start + viewAngles.ToForward() * 80.0f; - - // player identification -> names to the hud - if ( gameLocal.isMultiplayer && entityNumber == gameLocal.localClientNum ) { - idVec3 end = start + viewAngles.ToForward() * 768.0f; - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); - int iclient = -1; - if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum < MAX_CLIENTS ) ) { - iclient = trace.c.entityNum; - } - if ( MPAim != iclient ) { - lastMPAim = MPAim; - MPAim = iclient; - lastMPAimTime = gameLocal.realClientTime; - } - } - - idBounds bounds( start ); - bounds.AddPoint( end ); - - listedClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); - - // no pretense at sorting here, just assume that there will only be one active - // gui within range along the trace - for ( i = 0; i < listedClipModels; i++ ) { - clip = clipModelList[ i ]; - ent = clip->GetEntity(); - - if ( ent->IsHidden() ) { - continue; - } - - if ( allowFocus ) { - if ( ent->IsType( idAFAttachment::Type ) ) { - idEntity *body = static_cast( ent )->GetBody(); - if ( body && body->IsType( idAI::Type ) && ( static_cast( body )->GetTalkState() >= TALK_OK ) ) { - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); - if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { - ClearFocus(); - focusCharacter = static_cast( body ); - talkCursor = 1; - focusTime = gameLocal.time + FOCUS_TIME; - break; - } - } - continue; - } - - if ( ent->IsType( idAI::Type ) ) { - if ( static_cast( ent )->GetTalkState() >= TALK_OK ) { - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); - if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { - ClearFocus(); - focusCharacter = static_cast( ent ); - talkCursor = 1; - focusTime = gameLocal.time + FOCUS_TIME; - break; - } - } - continue; - } - - if ( ent->IsType( idAFEntity_Vehicle::Type ) ) { - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); - if ( ( trace.fraction < 1.0f ) && ( trace.c.entityNum == ent->entityNumber ) ) { - ClearFocus(); - focusVehicle = static_cast( ent ); - focusTime = gameLocal.time + FOCUS_TIME; - break; - } - continue; - } - } - - if ( !ent->GetRenderEntity() || !ent->GetRenderEntity()->gui[ 0 ] || !ent->GetRenderEntity()->gui[ 0 ]->IsInteractive() ) { - continue; - } - - if ( ent->spawnArgs.GetBool( "inv_item" ) ) { - // don't allow guis on pickup items focus - continue; - } - - pt = gameRenderWorld->GuiTrace( ent->GetModelDefHandle(), start, end ); - if ( pt.x != -1 ) { - // we have a hit - renderEntity_t *focusGUIrenderEntity = ent->GetRenderEntity(); - if ( !focusGUIrenderEntity ) { - continue; - } - - if ( pt.guiId == 1 ) { - ui = focusGUIrenderEntity->gui[ 0 ]; - } else if ( pt.guiId == 2 ) { - ui = focusGUIrenderEntity->gui[ 1 ]; - } else { - ui = focusGUIrenderEntity->gui[ 2 ]; - } - - if ( ui == NULL ) { - continue; - } - - ClearFocus(); - focusGUIent = ent; - focusUI = ui; - - // clamp the mouse to the corner - ev = sys->GenerateMouseMoveEvent( -2000, -2000 ); - command = focusUI->HandleEvent( &ev, gameLocal.time ); - HandleGuiCommands( focusGUIent, command ); - - // move to an absolute position - ev = sys->GenerateMouseMoveEvent( static_cast(pt.x) * SCREEN_WIDTH, static_cast(pt.y) * SCREEN_HEIGHT ); - command = focusUI->HandleEvent( &ev, gameLocal.time ); - HandleGuiCommands( focusGUIent, command ); - focusTime = gameLocal.time + FOCUS_GUI_TIME; - break; - } - } - - if ( focusGUIent && focusUI ) { - if ( !oldFocus || oldFocus != focusGUIent ) { - command = focusUI->Activate( true, gameLocal.time ); - HandleGuiCommands( focusGUIent, command ); - StartSound( "snd_guienter", SND_CHANNEL_ANY, 0, false, NULL ); - // HideTip(); - // HideObjective(); - } - } else if ( oldFocus && oldUI ) { - command = oldUI->Activate( false, gameLocal.time ); - HandleGuiCommands( oldFocus, command ); - StartSound( "snd_guiexit", SND_CHANNEL_ANY, 0, false, NULL ); - } - - if ( cursor && ( oldTalkCursor != talkCursor ) ) { - cursor->SetStateInt( "talkcursor", talkCursor ); - } - - if ( oldChar != focusCharacter && hud ) { - if ( focusCharacter ) { - hud->SetStateString( "npc", focusCharacter->spawnArgs.GetString( "npc_name", "Joe" ) ); - hud->HandleNamedEvent( "showNPC" ); - // HideTip(); - // HideObjective(); - } else { - hud->SetStateString( "npc", "" ); - hud->HandleNamedEvent( "hideNPC" ); - } - } -} -#endif - -/* -================= -idPlayer::CrashLand - -Check for hard landings that generate sound events -================= -*/ - -void idPlayer::CrashLand( const idVec3 &savedOrigin, const idVec3 &savedVelocity ) { - - AI_SOFTLANDING = false; - AI_HARDLANDING = false; - - CrashLandResult result = idActor::CrashLand( physicsObj, savedOrigin, savedVelocity ); - - if (result.hasLanded && - ( (!AI_CROUCH && savedVelocity.z < -300) || savedVelocity.z < -600) ) - { - hasLanded = true; - - PlayFootStepSound(); - } - else - { - hasLanded = false; - } - - - if (health < 0) - { - // This was a deadly fall - AI_HARDLANDING = true; - landChange = -32; - landTime = gameLocal.time; - } - else if (result.damageDealt >= m_damage_thresh_hard) - { - AI_HARDLANDING = true; - landChange = -24; - landTime = gameLocal.time; - } - else if (result.hasLanded || result.damageDealt >= m_damage_thresh_min) - { - AI_SOFTLANDING = true; - landChange = -8; - landTime = gameLocal.time; - } - - // otherwise, just walk on -} - -/* -=============== -idPlayer::BobCycle -=============== -*/ -void idPlayer::BobCycle( const idVec3 &pushVelocity ) { - float bobmove; - int old, deltaTime; - idVec3 vel, gravityDir, velocity; - idMat3 viewaxis; - float bob; - float delta; - float speed; - float f; - - // - // calculate speed and cycle to be used for - // all cyclic walking effects - // - velocity = physicsObj.GetLinearVelocity() - pushVelocity; - - gravityDir = physicsObj.GetGravityNormal(); - vel = velocity - ( velocity * gravityDir ) * gravityDir; - xyspeed = vel.LengthFast(); - - // do not evaluate the bob for other clients - // when doing a spectate follow, don't do any weapon bobbing - if ( gameLocal.isClient && entityNumber != gameLocal.localClientNum ) { - viewBobAngles.Zero(); - viewBob.Zero(); - return; - } - - if ( !physicsObj.HasGroundContacts() || influenceActive == INFLUENCE_LEVEL2 || ( gameLocal.isMultiplayer && spectating ) ) { - // airborne - bobCycle = 0; - bobFoot = 0; - bobfracsin = 0; - } - else if (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD || noclip) - { - // No viewbob when fully underwater or in noclip mode, start at beginning of cycle again - bobCycle = 0; - bobFoot = 0; - bobfracsin = 0; - } - else if ( ( !usercmd.forwardmove && !usercmd.rightmove ) || ( xyspeed <= MIN_BOB_SPEED ) ) { - // Play a footstep sound when we stop walking (the foot is lowered to the ground; - // also this prevents exploits) - if (bobCycle != 0) { - PlayFootStepSound(); - } - // start at beginning of cycle again - bobCycle = 0; - bobFoot = 0; - bobfracsin = 0; - } - else { - if ( physicsObj.IsCrouching() ) { - // greebo: Double the crouchbob speed when fully running - bobmove = pm_crouchbob.GetFloat() * (1 + bobFrac); - } - else - { - // vary the bobbing based on the speed of the player - bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; - } - - // greebo: is the player creeping? (Only kicks in when not running, run key cancels out creep key) - if (usercmd.buttons & BUTTON_5 && !(usercmd.buttons & BUTTON_RUN)) - { - bobmove *= 0.5f * (1 - bobFrac); - } - - // additional explanatory comments added by Crispy - - old = bobCycle; - - // bobCycle is effectively an 8-bit integer, which increases at a speed determined by bobmove - // and wraps around when it exceeds 8 bits. - bobCycle = (int)( old + bobmove * gameLocal.msec ) & 255; - - // bobFoot = most significant bit of bobCycle, so it will be equal to 1 for half the time, - // and 0 for the other half. This represents which foot we're placing our weight on right now. - bobFoot = ( bobCycle & 128 ) >> 7; - - // Take the other 7 bits of bobCycle, scale them to range from 0 to PI, and take the sine. - // The result produces positive values only, from within the first "hump" of the function. - // (Look at the graph of sin(x) with x = 0...PI) - bobfracsin = idMath::Fabs( sin( ( bobCycle & 127 ) / 127.0 * idMath::PI ) ); - - // Crispy: Play footstep sounds when we hit the bottom of the cycle (i.e. when bobFoot changes) - if ((old&128) != (bobCycle&128)) { - // We've changed feet, so play a footstep - PlayFootStepSound(); - } - } - - // calculate angles for view bobbing - viewBobAngles.Zero(); - - viewaxis = viewAngles.ToMat3() * physicsObj.GetGravityAxis(); - - // add angles based on velocity - delta = velocity * viewaxis[0]; - viewBobAngles.pitch += delta * pm_runpitch.GetFloat(); - - delta = velocity * viewaxis[1]; - viewBobAngles.roll -= delta * pm_runroll.GetFloat(); - - // add angles based on bob - // make sure the bob is visible even at low speeds - speed = xyspeed > 200 ? xyspeed : 200; - - delta = bobfracsin * pm_bobpitch.GetFloat() * speed; - if ( physicsObj.IsCrouching() ) { - delta *= 3; // crouching - } - viewBobAngles.pitch += delta; - delta = bobfracsin * pm_bobroll.GetFloat() * speed; - if ( physicsObj.IsCrouching() ) { - delta *= 3; // crouching accentuates roll - } - if ( bobFoot & 1 ) { - delta = -delta; - } - viewBobAngles.roll += delta; - - // calculate position for view bobbing - viewBob.Zero(); - - if ( physicsObj.HasSteppedUp() ) { - - // check for stepping up before a previous step is completed - deltaTime = gameLocal.time - stepUpTime; - if ( deltaTime < STEPUP_TIME ) { - stepUpDelta = stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME + physicsObj.GetStepUp(); - } else { - stepUpDelta = physicsObj.GetStepUp(); - } - if ( stepUpDelta > 2.0f * pm_stepsize.GetFloat() ) { - stepUpDelta = 2.0f * pm_stepsize.GetFloat(); - } - stepUpTime = gameLocal.time; - } - - idVec3 gravity = physicsObj.GetGravityNormal(); - - // if the player stepped up recently - deltaTime = gameLocal.time - stepUpTime; - if ( deltaTime < STEPUP_TIME ) { - viewBob += gravity * ( stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME ); - } - - // add bob height after any movement smoothing - bob = bobfracsin * xyspeed * pm_bobup.GetFloat(); - if ( bob > 6 ) { - bob = 6; - } - viewBob[2] += bob; - - // add fall height - delta = gameLocal.time - landTime; - if ( delta < LAND_DEFLECT_TIME ) { - f = delta / LAND_DEFLECT_TIME; - viewBob -= gravity * ( landChange * f ); - } else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) { - delta -= LAND_DEFLECT_TIME; - f = 1.0 - ( delta / LAND_RETURN_TIME ); - viewBob -= gravity * ( landChange * f ); - } -} - -/* -================ -idPlayer::UpdateDeltaViewAngles -================ -*/ -void idPlayer::UpdateDeltaViewAngles( const idAngles &angles ) { - // set the delta angle - idAngles delta; - for( int i = 0; i < 3; i++ ) { - delta[ i ] = angles[ i ] - SHORT2ANGLE( usercmd.angles[ i ] ); - } - - SetDeltaViewAngles( delta ); -} - -/* -================ -idPlayer::SetViewAngles -================ -*/ -void idPlayer::SetViewAngles( const idAngles &angles ) { - UpdateDeltaViewAngles( angles ); - viewAngles = angles; -} - -/* -================ -idPlayer::UpdateViewAngles -================ -*/ -void idPlayer::UpdateViewAngles( void ) -{ - int i; - idAngles delta; - idAngles TestAngles = viewAngles; - - if ( !noclip && - ( gameLocal.inCinematic || privateCameraView || gameLocal.GetCamera() || - influenceActive == INFLUENCE_LEVEL2 || GetImmobilization() & EIM_VIEW_ANGLE ) ) - { - // no view changes at all, but we still want to update the deltas or else when - // we get out of this mode, our view will snap to a kind of random angle - UpdateDeltaViewAngles( viewAngles ); - goto Quit; - } - - // if dead - if ( health <= 0 ) { - if ( pm_thirdPersonDeath.GetBool() ) { - viewAngles.roll = 0.0f; - viewAngles.pitch = 30.0f; - } else { - viewAngles.roll = 40.0f; - viewAngles.pitch = -15.0f; - } - goto Quit; - } - - // circularly clamp the angles with deltas - for ( i = 0; i < 3; i++ ) - { - cmdAngles[i] = SHORT2ANGLE( usercmd.angles[i] ); - if ( influenceActive == INFLUENCE_LEVEL3 ) - { - TestAngles[i] += idMath::ClampFloat( -1.0f, 1.0f, idMath::AngleDelta( idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ) , viewAngles[i] ) ); - } - else if( GetTurnHinderance() != 1.0f ) - { - TestAngles[i] += GetTurnHinderance() * idMath::AngleDelta( idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ) , viewAngles[i] ); - } - else - { - TestAngles[i] = idMath::AngleNormalize180( SHORT2ANGLE( usercmd.angles[i]) + deltaViewAngles[i] ); - } - } - if ( !centerView.IsDone( gameLocal.time ) ) { - TestAngles.pitch = centerView.GetCurrentValue(gameLocal.time); - } - - // clamp the pitch - if ( noclip ) { - if ( TestAngles.pitch > 89.0f ) { - // don't let the player look down more than 89 degrees while noclipping - TestAngles.pitch = 89.0f; - } else if ( TestAngles.pitch < -89.0f ) { - // don't let the player look up more than 89 degrees while noclipping - TestAngles.pitch = -89.0f; - } - } else { - if ( TestAngles.pitch > pm_maxviewpitch.GetFloat() ) { - // don't let the player look down enough to see the shadow of his (non-existant) feet - TestAngles.pitch = pm_maxviewpitch.GetFloat(); - } else if ( TestAngles.pitch < pm_minviewpitch.GetFloat() ) { - // don't let the player look up more than 89 degrees - TestAngles.pitch = pm_minviewpitch.GetFloat(); - } - } - - // TDM: Check for collisions due to delta yaw when leaning, overwrite test angles to avoid - physicsObj.UpdateLeanedInputYaw( TestAngles ); - viewAngles = TestAngles; - - UpdateDeltaViewAngles( viewAngles ); - - // orient the model towards the direction we're looking - // LeanMod: SophisticatedZombie: Added roll to this - SetAngles( idAngles( 0.0f, viewAngles.yaw, viewAngles.roll ) ); - - // save in the log for analyzing weapon angle offsets - loggedViewAngles[ gameLocal.framenum & (NUM_LOGGED_VIEW_ANGLES-1) ] = viewAngles; - -Quit: - return; -} - -/* -============== -idPlayer::AdjustHeartRate - -Player heartrate works as follows - -DEF_HEARTRATE is resting heartrate - -Taking damage when health is above 75 adjusts heart rate by 1 beat per second -Taking damage when health is below 75 adjusts heart rate by 5 beats per second -Maximum heartrate from damage is MAX_HEARTRATE - -Firing a weapon adds 1 beat per second up to a maximum of COMBAT_HEARTRATE - -Being at less than 25% stamina adds 5 beats per second up to ZEROSTAMINA_HEARTRATE - -All heartrates are target rates.. the heart rate will start falling as soon as there have been no adjustments for 5 seconds -Once it starts falling it always tries to get to DEF_HEARTRATE - -The exception to the above rule is upon death at which point the rate is set to DYING_HEARTRATE and starts falling -immediately to zero - -Heart rate volumes go from zero ( -40 db for DEF_HEARTRATE to 5 db for MAX_HEARTRATE ) the volume is -scaled linearly based on the actual rate - -Exception to the above rule is once the player is dead, the dying heart rate starts at either the current volume if -it is audible or -10db and scales to 8db on the last few beats -============== -*/ -void idPlayer::AdjustHeartRate( int target, float timeInSecs, float delay, bool force ) { - - if ( heartInfo.GetEndValue() == target ) { - return; - } - - if ( AI_DEAD && !force ) { - return; - } - - lastHeartAdjust = gameLocal.time; - - heartInfo.Init( gameLocal.time + delay * 1000, timeInSecs * 1000, heartRate, target ); -} - -/* -============== -idPlayer::GetBaseHeartRate -============== -*/ -int idPlayer::GetBaseHeartRate( void ) { - /* - int base = idMath::FtoiFast( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( (float)health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ); - int rate = idMath::FtoiFast( base + ( ZEROSTAMINA_HEARTRATE - base ) * ( 1.0f - stamina / pm_stamina.GetFloat() ) ); - int diff = ( lastDmgTime ) ? gameLocal.time - lastDmgTime : 99999; - rate += ( diff < 5000 ) ? ( diff < 2500 ) ? ( diff < 1000 ) ? 15 : 10 : 5 : 0; - return rate; - */ - return BASE_HEARTRATE; -} - -/* -============== -idPlayer::SetCurrentHeartRate -============== -*/ -void idPlayer::SetCurrentHeartRate( void ) { - /// reasons why we should exit - if( false == airless && health > 0 ) - { - if( true == m_HeartBeatAllow ) - { - AdjustHeartRate( BASE_HEARTRATE, 5.5f, 0.0f, false );/// We were allowing so fade it - } - else /// We were NOT allowing it so set to default - { - heartRate = BASE_HEARTRATE; - } - m_HeartBeatAllow = false; - return; - } - /* - if( false == m_HeartBeatAllow )/// we did not want heartbeat heard so make sure - { - heartInfo.Init( gameLocal.time, 0, BASE_HEARTRATE, BASE_HEARTRATE ); - heartRate = BASE_HEARTRATE; - StopSound( SND_CHANNEL_HEART, false ); - } - */ - m_HeartBeatAllow = true; - - - int base = idMath::FtoiFast( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( (float) health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ); - - /// removed adrenaline affect - Rich - heartRate = idMath::FtoiFast( heartInfo.GetCurrentValue( gameLocal.time ) ); - int currentRate = GetBaseHeartRate(); - if ( health >= 0 && gameLocal.time > lastHeartAdjust + 2500 ) { - AdjustHeartRate( currentRate, 2.5f, 0.0f, false ); - } - int bps = idMath::FtoiFast( 60.0f / heartRate * 1000.0f ); - if ( gameLocal.time - lastHeartBeat > bps ) { - int dmgVol = DMG_VOLUME; - int deathVol = DEATH_VOLUME; - int zeroVol = ZERO_VOLUME; - float pct = 0.0; - if ( heartRate > BASE_HEARTRATE && health > 0 ) { - pct = (float)(heartRate - base) / (MAX_HEARTRATE - base); - pct *= ((float)dmgVol - (float)zeroVol); - } else if ( health <= 0 ) { - pct = (float)(heartRate - DYING_HEARTRATE) / (BASE_HEARTRATE - DYING_HEARTRATE); - if ( pct > 1.0f ) { - pct = 1.0f; - } else if (pct < 0.0f) { - pct = 0.0f; - } - pct *= ((float)deathVol - (float)zeroVol); - } - - pct += (float)zeroVol; - - if ( pct != zeroVol ) { - StartSound( "snd_heartbeat", SND_CHANNEL_HEART, SSF_PRIVATE_SOUND, false, NULL ); - // modify just this channel to a custom volume - soundShaderParms_t parms; - memset( &parms, 0, sizeof( parms ) ); - parms.volume = pct; - refSound.referenceSound->ModifySound( SND_CHANNEL_HEART, &parms ); - } - - lastHeartBeat = gameLocal.time; - } -} - -/* -============== -idPlayer::UpdateAir -============== -*/ -void idPlayer::UpdateAir( void ) { - if ( health <= 0 ) { - return; - } - - // see if the player is connected to the info_vacuum - bool newAirless = false; - - if ( gameLocal.vacuumAreaNum != -1 ) { - int num = GetNumPVSAreas(); - if ( num > 0 ) { - int areaNum; - - // if the player box spans multiple areas, get the area from the origin point instead, - // otherwise a rotating player box may poke into an outside area - if ( num == 1 ) { - const int *pvsAreas = GetPVSAreas(); - areaNum = pvsAreas[0]; - } else { - areaNum = gameRenderWorld->PointInArea( this->GetPhysics()->GetOrigin() ); - } - newAirless = gameRenderWorld->AreasAreConnected( gameLocal.vacuumAreaNum, areaNum, PS_BLOCK_AIR ); - } - } - -#ifdef MOD_WATERPHYSICS // check if the player is in water - - idPhysics* phys = GetPhysics(); - - if (phys != NULL && phys->IsType(idPhysics_Actor::Type) && - static_cast(phys)->GetWaterLevel() >= WATERLEVEL_HEAD ) - { - newAirless = true; // MOD_WATERPHYSICS - } - -#endif // MOD_WATERPHYSICS - - - if ( newAirless ) { - if ( !airless ) { - StartSound( "snd_decompress", SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); - StartSound( "snd_noAir", SND_CHANNEL_BODY2, 0, false, NULL ); - if ( hud ) { - hud->HandleNamedEvent( "noAir" ); - } - } - airTics--; - if ( airTics < 0 ) { - airTics = 0; - // check for damage - const idDict *damageDef = gameLocal.FindEntityDefDict( "damage_noair", false ); - int dmgTiming = 1000 * (damageDef ? static_cast(damageDef->GetFloat( "delay", "3.0" )) : 3 ); - if ( gameLocal.time > lastAirDamage + dmgTiming ) { - Damage( NULL, NULL, vec3_origin, "damage_noair", 1.0f, 0 ); - lastAirDamage = gameLocal.time; - } - } - - } else { - if ( airless ) { - StartSound( "snd_recompress", SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL ); - StopSound( SND_CHANNEL_BODY2, false ); - if ( hud ) { - hud->HandleNamedEvent( "Air" ); - } - } - airTics+=2; // regain twice as fast as lose - if ( airTics > pm_airTics.GetInteger() ) { - airTics = pm_airTics.GetInteger(); - } - } - - airless = newAirless; - - if ( hud ) { - hud->SetStateInt( "player_air", 100 * airTics / pm_airTics.GetInteger() ); - } -} - -int idPlayer::getAirTicks() const { - return airTics; -} - -void idPlayer::setAirTicks(int airTicks) { - airTics = airTicks; - // Clamp to maximum value - if( airTics > pm_airTics.GetInteger() ) { - airTics = pm_airTics.GetInteger(); - } -} - -/* -============== -idPlayer::ToggleScoreboard -============== -*/ -void idPlayer::ToggleScoreboard( void ) { - scoreBoardOpen ^= 1; -} - -/* -============== -idPlayer::Spectate -============== -*/ -void idPlayer::Spectate( bool spectate ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - // track invisible player bug - // all hiding and showing should be performed through Spectate calls - // except for the private camera view, which is used for teleports - assert( ( teleportEntity.GetEntity() != NULL ) || ( IsHidden() == spectating ) ); - - if ( spectating == spectate ) { - return; - } - - spectating = spectate; - - if ( gameLocal.isServer ) { - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteBits( spectating, 1 ); - ServerSendEvent( EVENT_SPECTATE, &msg, false, -1 ); - } - - if ( spectating ) { - // join the spectators - spectator = this->entityNumber; - Init(); - StopRagdoll(); - SetPhysics( &physicsObj ); - physicsObj.DisableClip(); - Hide(); - Event_DisableWeapon(); - if ( hud ) { - hud->HandleNamedEvent( "aim_clear" ); - MPAimFadeTime = 0; - } - } else { - // put everything back together again - currentWeapon = -1; // to make sure the def will be loaded if necessary - Show(); - Event_EnableWeapon(); - } - SetClipModel(); -} - -/* -============== -idPlayer::SetClipModel -============== -*/ -void idPlayer::SetClipModel( void ) { - idBounds bounds; - - if ( spectating ) { - bounds = idBounds( vec3_origin ).Expand( pm_spectatebbox.GetFloat() * 0.5f ); - } else { - bounds[0].Set( -pm_bboxwidth.GetFloat() * 0.5f, -pm_bboxwidth.GetFloat() * 0.5f, 0 ); - bounds[1].Set( pm_bboxwidth.GetFloat() * 0.5f, pm_bboxwidth.GetFloat() * 0.5f, pm_normalheight.GetFloat() ); - } - // the origin of the clip model needs to be set before calling SetClipModel - // otherwise our physics object's current origin value gets reset to 0 - idClipModel *newClip; - if ( pm_usecylinder.GetBool() ) { - newClip = new idClipModel( idTraceModel( bounds, 8 ) ); - newClip->Translate( physicsObj.PlayerGetOrigin() ); - physicsObj.SetClipModel( newClip, 1.0f ); - } else { - newClip = new idClipModel( idTraceModel( bounds ) ); - newClip->Translate( physicsObj.PlayerGetOrigin() ); - physicsObj.SetClipModel( newClip, 1.0f ); - } -} - -/* -============== -idPlayer::UseVehicle -============== -*/ -void idPlayer::UseVehicle( void ) { - trace_t trace; - idVec3 start, end; - idEntity *ent; - - if ( GetBindMaster() && GetBindMaster()->IsType( idAFEntity_Vehicle::Type ) ) { - Show(); - static_cast(GetBindMaster())->Use( this ); - } else { - start = GetEyePosition(); - end = start + viewAngles.ToForward() * 80.0f; - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); - if ( trace.fraction < 1.0f ) { - ent = gameLocal.entities[ trace.c.entityNum ]; - if ( ent && ent->IsType( idAFEntity_Vehicle::Type ) ) { - Hide(); - static_cast(ent)->Use( this ); - } - } - } -} - -/* -============== -idPlayer::PerformImpulse -============== -*/ -void idPlayer::PerformImpulse( int impulse ) { - - if ( gameLocal.isClient ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - assert( entityNumber == gameLocal.localClientNum ); - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteBits( impulse, 6 ); - ClientSendEvent( EVENT_IMPULSE, &msg ); - } - - if ( impulse >= IMPULSE_0 && impulse <= IMPULSE_12 ) - { - // Prevent the player from choosing to switch weapons. - if ( GetImmobilization() & EIM_WEAPON_SELECT ) - { - return; - } - - SelectWeapon( impulse, false ); - return; - } - - switch( impulse ) - { - case IMPULSE_13: - { - Reload(); - break; - } - - case IMPULSE_14: // Next weapon - { - // If the grabber is active, next weapon modifies the distance based on the CVAR setting - if (m_bGrabberActive) - { - gameLocal.m_Grabber->IncrementDistance( cv_reverse_grab_control.GetBool() ); - } - - // Pass the "next weapon" event to the GUIs - m_overlays.broadcastNamedEvent("nextWeapon"); - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Prevent the player from choosing to switch weapons. - if ( GetImmobilization() & EIM_WEAPON_SELECT ) - { - return; - } - - NextWeapon(); - break; - } - case IMPULSE_15: // Previous Weapon - { - // If the grabber is active, previous weapon modifies the distance based on the CVAR setting - if (m_bGrabberActive) - { - gameLocal.m_Grabber->IncrementDistance( !cv_reverse_grab_control.GetBool() ); - } - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Pass the "previous weapon" event to the GUIs - m_overlays.broadcastNamedEvent("prevWeapon"); - - // Prevent the player from choosing to switch weapons. - if ( GetImmobilization() & EIM_WEAPON_SELECT ) - { - return; - } - - PrevWeapon(); - break; - } - case IMPULSE_17: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - gameLocal.mpGame.ToggleReady(); - } - break; - } - - case IMPULSE_18: - { - centerView.Init(gameLocal.time, 200, viewAngles.pitch, 0); - break; - } - case IMPULSE_19: // Toggle Objectives GUI (was previously assigned to the PDA) - { - ToggleObjectivesGUI(); - break; - } - case IMPULSE_20: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - gameLocal.mpGame.ToggleTeam(); - } - break; - } - case IMPULSE_22: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - gameLocal.mpGame.ToggleSpectate(); - } - break; - } - - case IMPULSE_23: // Crouch - { - if (!cv_tdm_crouch_toggle.GetBool()) - { - m_CrouchIntent = true; - } - - m_ButtonStateTracker.StartTracking(impulse); - } - break; - - case IMPULSE_24: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - physicsObj.PerformMantle(); - } - break; - } - - // DarkMod: Sophisticated Zombie: For testing purposes only - // This tests the hiding spot search function relative to the player - case IMPULSE_25: // Test hiding spots. - { - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Attempting hiding spot test"); - idVec3 searchOrigin = GetEyePosition(); - idBounds searchBounds (searchOrigin); - - idVec3 forward; - idVec3 right; - viewAngles.ToVectors (&forward, &right); - right.Normalize(); - forward.Normalize(); - - idVec3 widthPoint = searchOrigin + (right * 300.0f); - searchBounds.AddPoint (widthPoint); - idVec3 widthPoint2 = searchOrigin - (right * 300.0f); - searchBounds.AddPoint (widthPoint2); - idVec3 endPoint = searchOrigin + (forward * 1000.0f); - searchBounds.AddPoint (endPoint); - - // Get AAS - idAAS* p_aas = NULL; - for (int i = 0; i < gameLocal.NumAAS(); i++) { - p_aas = gameLocal.GetAAS(i); - if (p_aas != NULL) { - CDarkmodAASHidingSpotFinder::testFindHidingSpots( - searchOrigin, - 0.35f, - searchBounds, - this, // Ignore self as a hiding screen - p_aas - ); - DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("Done hiding spot test"); - } - } - - if (p_aas == NULL) - { - DM_LOG(LC_AI, LT_WARNING)LOGSTRING("No default AAS is present for map, number of AAS: %d\n", gameLocal.NumAAS()); - } - - } - break; - - case IMPULSE_27: - { - //LAS.pvsToAASMappingTable.DebugShowMappings(10000); - idAASLocal* aas = dynamic_cast(gameLocal.GetAAS(cv_debug_aastype.GetString())); - - if (aas != NULL) - { - aas->DrawAreas(GetEyePosition()); - } - } - break; - - case IMPULSE_28: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - gameLocal.mpGame.CastVote( gameLocal.localClientNum, true ); - } - } - break; - - case IMPULSE_29: - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - gameLocal.mpGame.CastVote( gameLocal.localClientNum, false ); - } - } - break; - - case IMPULSE_40: // TDM: grab item with grabber - { - CGrabber *grabber = gameLocal.m_Grabber; - idEntity *useEnt = grabber->GetSelected(); - if(useEnt == NULL) - { - idEntity *frob = m_FrobEntity.GetEntity(); - if(frob != NULL) - grabber->PutInHands(frob, frob->GetPhysics()->GetAxis() ); - } - } - break; - - case IMPULSE_41: // TDM Use/Frob - { - // Register the button for tracking - m_ButtonStateTracker.StartTracking(impulse); - // Perform the frob - PerformFrob(); - } - break; - - /*! - * Lean forward is impulse 44 - */ - case IMPULSE_44: // Lean forward - { - m_ButtonStateTracker.StartTracking(impulse); - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - physicsObj.ToggleLean(90.0); - } - break; - - /*! - * Lean left is impulse 45 - */ - case IMPULSE_45: // Lean left - { - m_ButtonStateTracker.StartTracking(impulse); - DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Left lean impulse pressed\r"); - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - // Do we need to enter the leaning state? - DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Left leaning started\r"); - physicsObj.ToggleLean(180.0); - } - } - break; - - /*! - * Lean right is impulse 46 - */ - case IMPULSE_46: // Lean right - { - m_ButtonStateTracker.StartTracking(impulse); - DM_LOG(LC_SYSTEM, LT_DEBUG)LOGSTRING("Right lean impulse pressed\r"); - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - physicsObj.ToggleLean(0.0); - } - break; - - case IMPULSE_47: // Inventory previous item - { - // If the grabber is active, prev item modifies the distance based on the CVAR setting - if (m_bGrabberActive) - { - gameLocal.m_Grabber->IncrementDistance( !cv_reverse_grab_control.GetBool() ); - } - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Notify the GUIs about the button event - m_overlays.broadcastNamedEvent("inventoryPrevItem"); - - if(GetImmobilization() & EIM_ITEM_SELECT) - return; - - NextPrevInventoryItem(-1); - } - break; - - case IMPULSE_48: // Inventory next item - { - // If the grabber is active, next item modifies the distance based on the CVAR setting - if (m_bGrabberActive) - { - gameLocal.m_Grabber->IncrementDistance( cv_reverse_grab_control.GetBool() ); - } - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Notify the GUIs about the button event - m_overlays.broadcastNamedEvent("inventoryNextItem"); - - if(GetImmobilization() & EIM_ITEM_SELECT) - return; - - NextPrevInventoryItem(1); - } - break; - - case IMPULSE_49: // Inventory previous group - { - // Check for a held grabber entity, which should be put back into the inventory - if (AddGrabberEntityToInventory()) - return; - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Notify the GUIs about the button event - m_overlays.broadcastNamedEvent("inventoryPrevGroup"); - - if(GetImmobilization() & EIM_ITEM_SELECT) - return; - - NextPrevInventoryGroup(-1); - } - break; - - case IMPULSE_50: // Inventory next group - { - // Check for a held grabber entity, which should be put back into the inventory - if (AddGrabberEntityToInventory()) - return; - - // Trigger an objectives GUI update if applicable - UpdateObjectivesGUI(); - - // Notify the GUIs about the button event - m_overlays.broadcastNamedEvent("inventoryNextGroup"); - - if(GetImmobilization() & EIM_ITEM_SELECT) - return; - - NextPrevInventoryGroup(1); - } - break; - - case IMPULSE_51: // Inventory use item - { - // Use key has "hold down" functions - m_ButtonStateTracker.StartTracking(impulse); - // Pass the call - UseInventoryItem(); - } - break; - - case IMPULSE_52: // Inventory drop item - { - // Pass the "inventoryDropItem" event to the GUIs - m_overlays.broadcastNamedEvent("inventoryDropItem"); - - if (GetImmobilization() & EIM_ITEM_DROP) { - return; - } - - DropInventoryItem(); - } - break; - - } -} - -void idPlayer::PerformKeyRepeat(int impulse, int holdTime) -{ - - - switch (impulse) - { - case IMPULSE_23: // TDM Crouch - { - if (holdTime > cv_tdm_crouch_toggle_hold_time.GetFloat()) - { - if (physicsObj.OnRope()) - { - physicsObj.RopeDetach(); - physicsObj.m_bClimbDetachCrouchHeld = true; - } - else if (physicsObj.OnLadder()) - { - physicsObj.ClimbDetach(); - physicsObj.m_bClimbDetachCrouchHeld = true; - } - } - - } - break; - - case IMPULSE_41: // TDM Use/Frob - { - PerformFrobKeyRepeat(holdTime); - } - break; - - case IMPULSE_51: // Inventory Use Item - { - const CInventoryCursorPtr& crsr = InventoryCursor(); - CInventoryItemPtr it = crsr->GetCurrentItem(); - - if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) - { - UseInventoryItem(ERepeat, it, holdTime, false); - } - } - break; - } -} - -void idPlayer::PerformKeyRelease(int impulse, int holdTime) -{ - // The key associated to has been released - DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Button %d has been released, has been held down %d ms.\r", impulse, holdTime); - - switch (impulse) - { - case IMPULSE_23: // TDM crouch - if (cv_tdm_crouch_toggle.GetBool()) - { - if ( gameLocal.isClient || entityNumber == gameLocal.localClientNum ) - { - m_CrouchIntent = !m_CrouchIntent; - } - } - else - { - m_CrouchIntent = false; - } - - // clear climb detach intent when crouch is released - physicsObj.m_bClimbDetachCrouchHeld = false; - - break; - - case IMPULSE_41: // TDM Use/Frob - { - PerformFrobKeyRelease(holdTime); - } - break; - - - - case IMPULSE_44: - if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) - physicsObj.ToggleLean(90.0); - break; - - case IMPULSE_45: - if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) - physicsObj.ToggleLean(180.0); - break; - - case IMPULSE_46: - if ( !cv_pm_lean_toggle.GetBool() && physicsObj.IsLeaning() ) - physicsObj.ToggleLean(0.0); - break; - - case IMPULSE_51: // Inventory Use item - { - InventoryUseKeyRelease(holdTime); - } - break; - } -} - -bool idPlayer::HandleESC( void ) { - if ( gameLocal.inCinematic ) { - return SkipCinematic(); - } - - if ( m_overlays.findInteractive() ) { - // Handle the escape? - // Not yet implemented. - // return true? - } - - return false; -} - -bool idPlayer::SkipCinematic( void ) { - StartSound( "snd_skipcinematic", SND_CHANNEL_ANY, 0, false, NULL ); - return gameLocal.SkipCinematic(); -} - - -/* -============== -idPlayer::GetImmobilization -============== -*/ -int idPlayer::GetImmobilization() -{ - // Has something changed since the cache was last calculated? - if ( m_immobilizationCache & EIM_UPDATE ) - { - // Recalculate the immobilization from scratch. - m_immobilizationCache = 0; - - for (const idKeyValue* kv = m_immobilization.MatchPrefix(""); kv != NULL; kv = m_immobilization.MatchPrefix("", kv)) - { - m_immobilizationCache |= atoi(kv->GetValue()); - } - } - - return m_immobilizationCache; -} - -/* -============== -idPlayer::GetHinderance -============== -*/ -float idPlayer::GetHinderance( void ) -{ - // Has something changed since the cache was last calculated? - if (m_hinderanceCache < 0.0f) - { - // Recalculate the hinderance from scratch. - float mCap = 1.0f, aCap = 1.0f; - - for (const idKeyValue* kv = m_hinderance.MatchPrefix("", NULL); kv != NULL; kv = m_hinderance.MatchPrefix("", kv)) - { - idVec3 vec = m_hinderance.GetVector(kv->GetKey()); - mCap *= vec[0]; - - if ( aCap > vec[1] ) - { - aCap = vec[1]; - } - } - - if ( aCap > mCap ) - { - aCap = mCap; - } - - m_hinderanceCache = aCap; - } - - return m_hinderanceCache; -} - -/* -============== -idPlayer::GetTurnHinderance -============== -*/ -float idPlayer::GetTurnHinderance( void ) -{ - // Has something changed since the cache was last calculated? - if (m_TurnHinderanceCache < 0.0f) - { - // Recalculate the hinderance from scratch. - float mCap = 1.0f, aCap = 1.0f; - - for (const idKeyValue* kv = m_TurnHinderance.MatchPrefix( "", NULL ); kv != NULL; kv = m_TurnHinderance.MatchPrefix("", kv)) - { - idVec3 vec = m_TurnHinderance.GetVector(kv->GetKey()); - mCap *= vec[0]; - - if ( aCap > vec[1] ) - { - aCap = vec[1]; - } - } - - if ( aCap > mCap ) - { - aCap = mCap; - } - - m_TurnHinderanceCache = aCap; - } - - return m_TurnHinderanceCache; -} - -/* -============== -idPlayer::EvaluateControls -============== -*/ -void idPlayer::EvaluateControls( void ) -{ - // check for respawning - // TDM: Section removed, click-to-respawn functionality not needed for TDM - // TDM: Added lean key check - - // in MP, idMultiplayerGame decides spawns - if ( forceRespawn && !gameLocal.isMultiplayer && !g_testDeath.GetBool() ) { - // in single player, we let the session handle restarting the level or loading a game - gameLocal.sessionCommand = "died"; - } - - if( m_MouseGesture.bActive ) - UpdateMouseGesture(); - - if ( ( usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) - { - PerformImpulse( usercmd.impulse ); - } - - scoreBoardOpen = ( ( usercmd.buttons & BUTTON_SCORES ) != 0 || forceScoreBoard ); - - oldFlags = usercmd.flags; - - AdjustSpeed(); - - // update the viewangles - UpdateViewAngles(); -} - - -void idPlayer::EvaluateCrouch() -{ - if ( GetImmobilization() & EIM_CROUCH) - { - m_IdealCrouchState = false; - return; - } - m_IdealCrouchState = m_CrouchIntent; -} - - - -/** -* TDM Mouse Gestures -**/ -void idPlayer::StartMouseGesture( int impulse, int thresh, EMouseTest test, bool bInverted, float TurnHinderance, int DecideTime, int DeadTime ) -{ - m_MouseGesture.bActive = true; - m_MouseGesture.test = test; - m_MouseGesture.bInverted = bInverted; - m_MouseGesture.key = impulse; - m_MouseGesture.thresh = thresh; - m_MouseGesture.DecideTime = DecideTime; - m_MouseGesture.DeadTime = DeadTime; - - m_MouseGesture.started = gameLocal.time; - m_MouseGesture.StartPos.x = usercmd.mx; - m_MouseGesture.StartPos.y = usercmd.my; - m_MouseGesture.motion = vec2_zero; - - // NOTE: Do not clear the last result as we may use it again if we can't decide - - SetTurnHinderance( "MouseGesture", 1.0f, TurnHinderance ); -} - -void idPlayer::UpdateMouseGesture( void ) -{ - bool bStop( false ); - float mag(0.0f); - EMouseDir CurrentDir; - - m_MouseGesture.motion.x += usercmd.mx - m_MouseGesture.StartPos.x; - m_MouseGesture.motion.y += usercmd.my - m_MouseGesture.StartPos.y; - if( m_MouseGesture.bInverted ) - m_MouseGesture.motion = -m_MouseGesture.motion; - - EMouseTest test = m_MouseGesture.test; - idVec2 motion = m_MouseGesture.motion; - - // Get the current dominant direction and magnitude - // NOTE: Apparently y is positive if we go down, not up? - if( test == MOUSETEST_UPDOWN ) - { - if( motion.y < 0 ) - CurrentDir = MOUSEDIR_UP; - else - CurrentDir = MOUSEDIR_DOWN; - - mag = idMath::Fabs( motion.y ); - } - else if ( test == MOUSETEST_LEFTRIGHT ) - { - if( motion.x > 0 ) - CurrentDir = MOUSEDIR_RIGHT; - else - CurrentDir = MOUSEDIR_LEFT; - - mag = idMath::Fabs( motion.x ); - } - else if( test == MOUSETEST_4DIR ) - { - // up/down motion dominant - if( idMath::Fabs(motion.y) > idMath::Fabs(motion.x) ) - { - if( motion.y < 0 ) - CurrentDir = MOUSEDIR_UP; - else - CurrentDir = MOUSEDIR_DOWN; - - mag = idMath::Fabs( motion.y ); - } - // side/side dominant (default left for zero input) - else - { - if( motion.x > 0 ) - CurrentDir = MOUSEDIR_RIGHT; - else - CurrentDir = MOUSEDIR_LEFT; - - mag = idMath::Fabs( motion.x ); - } - } - else - { - // Test along 8 directions (NOT TESTED!) - - // Step 1, resolve onto diagonal basis - idVec2 DiagVec; - // upper right - DiagVec.x = motion * idMath::SQRT_1OVER2 * idVec2(1.0f,1.0f); - // lower right - DiagVec.y = motion * idMath::SQRT_1OVER2 * idVec2(1.0f,-1.0f); - - // figure out which is dominant - idList dirs; - dirs.Append(idMath::Fabs(motion.y)); - dirs.Append(idMath::Fabs(motion.x)); - dirs.Append(idMath::Fabs(DiagVec.x)); - dirs.Append(idMath::Fabs(DiagVec.y)); - - mag = 0.0f; - int MaxAxis = 1; // default to left if we have zero motion - - for( int i=0; i < 4; i++ ) - { - if( dirs[i] > mag ) - { - mag = dirs[i]; - MaxAxis = i; - } - } - - // up/down - if( MaxAxis == 0 ) - { - if( motion.y < 0 ) - CurrentDir = MOUSEDIR_UP; - else - CurrentDir = MOUSEDIR_DOWN; - } - // left/right - else if( MaxAxis == 1) - { - if( motion.x > 0 ) - CurrentDir = MOUSEDIR_RIGHT; - else - CurrentDir = MOUSEDIR_LEFT; - } - // lower right/upper left - else if( MaxAxis == 2) - { - if( DiagVec.x < 0 ) - CurrentDir = MOUSEDIR_UP_LEFT; - else - CurrentDir = MOUSEDIR_DOWN_RIGHT; - } - // upper right/lower left - else - { - if( DiagVec.y < 0 ) - CurrentDir = MOUSEDIR_DOWN_LEFT; - else - CurrentDir = MOUSEDIR_UP_RIGHT; - } - } - - - // If above threshold, decision timer ran out, or button released, we're done - if( mag > m_MouseGesture.thresh - || (m_MouseGesture.DecideTime >= 0 && (gameLocal.time - m_MouseGesture.started) > m_MouseGesture.DecideTime) - || !common->ButtonState(m_MouseGesture.key) ) - { - m_MouseGesture.result = CurrentDir; - StopMouseGesture(); - } -} - -void idPlayer::StopMouseGesture( void ) -{ - m_MouseGesture.bActive = false; - - // clear the angular hinderance, or if dead time is still going, schedule an event to clear it - if( (gameLocal.time - m_MouseGesture.started) > m_MouseGesture.DeadTime ) - SetTurnHinderance( "MouseGesture", 1.0f, 1.0f ); - else - PostEventMS( &EV_Player_ClearMouseDeadTime, (m_MouseGesture.DeadTime - (gameLocal.time - m_MouseGesture.started)) ); -} - -EMouseDir idPlayer::GetMouseGesture( void ) -{ - return m_MouseGesture.result; -} - -void idPlayer::Event_GetMouseGesture( void ) -{ - idThread::ReturnInt( (int) GetMouseGesture() ); -} - -void idPlayer::Event_MouseGestureFinished( void ) -{ - idThread::ReturnInt( !m_MouseGesture.bActive ); -} - -void idPlayer::Event_ClearMouseDeadTime( void ) -{ - SetTurnHinderance( "MouseGesture", 1.0f, 1.0f ); -} - -/* -============== -idPlayer::AdjustSpeed - -DarkMod Note: Wow... this was pretty badly written -============== -*/ -void idPlayer::AdjustSpeed( void ) -{ - float speed(0.0f); - float crouchspeed(0.0f); - float rate(0.0f); - - float maxSpeed = pm_walkspeed.GetFloat() * cv_pm_runmod.GetFloat() * GetHinderance(); - - if ( spectating ) - { - speed = pm_spectatespeed.GetFloat(); - bobFrac = 0.0f; - } - else if ( noclip && !( usercmd.buttons & BUTTON_RUN )) - { - // "Walk" noclip - speed = pm_noclipspeed.GetFloat(); - bobFrac = 0.0f; - } - else if ( noclip && ( usercmd.buttons & BUTTON_RUN )) - { - // "run" noclip - speed = pm_noclipspeed.GetFloat() * cv_pm_runmod.GetFloat(); - bobFrac = 0.0f; - } - // running case - // TDM: removed check for not crouching.. - else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) ) - { - float walkSpeed = pm_walkspeed.GetFloat(); - - speed = walkSpeed * cv_pm_runmod.GetFloat(); - - // greebo: Only adjust bob fraction if actually running - if (physicsObj.HasRunningVelocity()) - { - // Scale the viewbob with the velocity - // At walkspeed, bobfrac is 0, at full run speed it should be 1 - const idVec3& vel = physicsObj.GetLinearVelocity(); - bobFrac = idMath::ClampFloat(0, 1, (vel.LengthFast() - walkSpeed) / (speed - walkSpeed)); - } - - // ishtvan: we'll see if this works to prevent backwards running, depends on order things are set - // Don't apply backwards run penalty to crouch run. It's already slow enough. - crouchspeed = speed * cv_pm_crouchmod.GetFloat(); - if( usercmd.forwardmove < 0 ) - { - speed *= cv_pm_run_backmod.GetFloat(); - } - - // Clamp to encumbrance limits: - speed = idMath::ClampFloat(0, maxSpeed, speed); - crouchspeed = idMath::ClampFloat(0, maxSpeed, crouchspeed); - } - else // standing still, walking, or creeping case - { - speed = pm_walkspeed.GetFloat(); - bobFrac = 0.0f; - - // apply creep modifier; creep is on button_5 - if( usercmd.buttons & BUTTON_5 ) - { - speed *= cv_pm_creepmod.GetFloat(); - } - - // apply movement multipliers to crouch as well - crouchspeed = speed * cv_pm_crouchmod.GetFloat(); - - // Clamp to encumbrance limits: - speed = idMath::ClampFloat(0, maxSpeed, speed); - crouchspeed = idMath::ClampFloat(0, maxSpeed, crouchspeed); - } - - // greebo: Clamp speed if swimming to 1.3 x walkspeed - if (physicsObj.GetWaterLevel() >= WATERLEVEL_WAIST) - { - speed = idMath::ClampFloat(0, pm_walkspeed.GetFloat() * cv_pm_max_swimspeed_mod.GetFloat(), speed); - } - - // TDM: leave this in for speed potions or something - speed *= PowerUpModifier(SPEED); - - if (influenceActive == INFLUENCE_LEVEL3) - { - speed *= 0.33f; - } - - physicsObj.SetSpeed(speed, crouchspeed); - - //gameRenderWorld->DrawText(va("bobFrac: %f\n", bobFrac), GetEyePosition() + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); - //gameRenderWorld->DrawText(va("speed: %f\n", physicsObj.GetLinearVelocity().Length()), GetEyePosition() + idVec3(0,0,-20) + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); - //gameLocal.Printf("bobFrac: %f\n", bobFrac); -} - -/* -============== -idPlayer::AdjustBodyAngles -============== -*/ -void idPlayer::AdjustBodyAngles( void ) { - idMat3 lookAxis; - idMat3 legsAxis; - bool blend; - float diff; - float frac; - float upBlend; - float forwardBlend; - float downBlend; - - if ( health < 0 ) { - return; - } - - blend = true; - - if ( !physicsObj.HasGroundContacts() ) { - idealLegsYaw = 0.0f; - legsForward = true; - } else if ( usercmd.forwardmove < 0 ) { - idealLegsYaw = idMath::AngleNormalize180( idVec3( -usercmd.forwardmove, usercmd.rightmove, 0.0f ).ToYaw() ); - legsForward = false; - } else if ( usercmd.forwardmove > 0 ) { - idealLegsYaw = idMath::AngleNormalize180( idVec3( usercmd.forwardmove, -usercmd.rightmove, 0.0f ).ToYaw() ); - legsForward = true; - } else if ( ( usercmd.rightmove != 0 ) && physicsObj.IsCrouching() ) { - if ( !legsForward ) { - idealLegsYaw = idMath::AngleNormalize180( idVec3( idMath::Abs( usercmd.rightmove ), usercmd.rightmove, 0.0f ).ToYaw() ); - } else { - idealLegsYaw = idMath::AngleNormalize180( idVec3( idMath::Abs( usercmd.rightmove ), -usercmd.rightmove, 0.0f ).ToYaw() ); - } - } else if ( usercmd.rightmove != 0 ) { - idealLegsYaw = 0.0f; - legsForward = true; - } else { - legsForward = true; - diff = idMath::Fabs( idealLegsYaw - legsYaw ); - idealLegsYaw = idealLegsYaw - idMath::AngleNormalize180( viewAngles.yaw - oldViewYaw ); - if ( diff < 0.1f ) { - legsYaw = idealLegsYaw; - blend = false; - } - } - - if ( !physicsObj.IsCrouching() ) { - legsForward = true; - } - - oldViewYaw = viewAngles.yaw; - - AI_TURN_LEFT = false; - AI_TURN_RIGHT = false; - if ( idealLegsYaw < -45.0f ) { - idealLegsYaw = 0; - AI_TURN_RIGHT = true; - blend = true; - } else if ( idealLegsYaw > 45.0f ) { - idealLegsYaw = 0; - AI_TURN_LEFT = true; - blend = true; - } - - if ( blend ) { - legsYaw = legsYaw * 0.9f + idealLegsYaw * 0.1f; - } - legsAxis = idAngles( 0.0f, legsYaw, 0.0f ).ToMat3(); - animator.SetJointAxis( hipJoint, JOINTMOD_WORLD, legsAxis ); - - // calculate the blending between down, straight, and up - frac = viewAngles.pitch / 90.0f; - if ( frac > 0.0f ) { - downBlend = frac; - forwardBlend = 1.0f - frac; - upBlend = 0.0f; - } else { - downBlend = 0.0f; - forwardBlend = 1.0f + frac; - upBlend = -frac; - } - - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, downBlend ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, forwardBlend ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 2, upBlend ); - - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, downBlend ); - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, forwardBlend ); - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 2, upBlend ); -} - -/* -============== -idPlayer::InitAASLocation -============== -*/ -void idPlayer::InitAASLocation( void ) { - int i; - int num; - idVec3 size; - idBounds bounds; - idAAS *aas; - idVec3 origin; - - GetFloorPos( 64.0f, origin ); - - num = gameLocal.NumAAS(); - aasLocation.SetGranularity( 1 ); - aasLocation.SetNum( num ); - for( i = 0; i < aasLocation.Num(); i++ ) { - aasLocation[ i ].areaNum = 0; - aasLocation[ i ].pos = origin; - aas = gameLocal.GetAAS( i ); - if ( aas && aas->GetSettings() ) { - size = aas->GetSettings()->boundingBoxes[0][1]; - bounds[0] = -size; - size.z = 32.0f; - bounds[1] = size; - - aasLocation[ i ].areaNum = aas->PointReachableAreaNum( origin, bounds, AREA_REACHABLE_WALK ); - } - } -} - -/* -============== -idPlayer::SetAASLocation -============== -*/ -void idPlayer::SetAASLocation( void ) { - int i; - int areaNum; - idVec3 size; - idBounds bounds; - idAAS *aas; - idVec3 origin; - - if ( !GetFloorPos( 64.0f, origin ) ) { - return; - } - - for( i = 0; i < aasLocation.Num(); i++ ) { - aas = gameLocal.GetAAS( i ); - if ( !aas ) { - continue; - } - - size = aas->GetSettings()->boundingBoxes[0][1]; - bounds[0] = -size; - size.z = 32.0f; - bounds[1] = size; - - areaNum = aas->PointReachableAreaNum( origin, bounds, AREA_REACHABLE_WALK ); - if ( areaNum ) { - aasLocation[ i ].pos = origin; - aasLocation[ i ].areaNum = areaNum; - } - } -} - -/* -============== -idPlayer::GetAASLocation -============== -*/ -void idPlayer::GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const { - int i; - - if ( aas != NULL ) { - for( i = 0; i < aasLocation.Num(); i++ ) { - if ( aas == gameLocal.GetAAS( i ) ) { - areaNum = aasLocation[ i ].areaNum; - pos = aasLocation[ i ].pos; - return; - } - } - } - - areaNum = 0; - pos = physicsObj.GetOrigin(); -} - -/* -============== -idPlayer::Move -============== -*/ -void idPlayer::Move( void ) -{ - float newEyeOffset; - idVec3 savedOrigin; - idVec3 savedVelocity; - idVec3 pushVelocity; - - // save old origin and velocity for crashlanding - savedOrigin = physicsObj.GetOrigin(); - savedVelocity = physicsObj.GetLinearVelocity(); - - pushVelocity = physicsObj.GetPushedLinearVelocity(); - - // set physics variables - physicsObj.SetMaxStepHeight( pm_stepsize.GetFloat() ); - physicsObj.SetMaxJumpHeight( pm_jumpheight.GetFloat()*GetJumpHinderance() ); - - if ( noclip ) { - physicsObj.SetContents( 0 ); - physicsObj.SetMovementType( PM_NOCLIP ); - } else if ( spectating ) { - physicsObj.SetContents( 0 ); - physicsObj.SetMovementType( PM_SPECTATOR ); - } else if ( health <= 0 ) { - physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ); - physicsObj.SetMovementType( PM_DEAD ); - } else if ( gameLocal.inCinematic || gameLocal.GetCamera() || privateCameraView || ( influenceActive == INFLUENCE_LEVEL2 ) ) { - physicsObj.SetContents( CONTENTS_BODY ); - physicsObj.SetMovementType( PM_FREEZE ); - } else { - physicsObj.SetContents( CONTENTS_BODY ); - physicsObj.SetMovementType( PM_NORMAL ); - } - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - if ( spectating ) { - physicsObj.SetClipMask( MASK_DEADSOLID ); - } else if ( health <= 0 ) { - physicsObj.SetClipMask( MASK_DEADSOLID ); - } else { - physicsObj.SetClipMask( MASK_PLAYERSOLID ); - } - - physicsObj.SetDebugLevel( g_debugMove.GetBool() ); - physicsObj.SetPlayerInput( usercmd, viewAngles ); - - // FIXME: physics gets disabled somehow - BecomeActive( TH_PHYSICS ); - RunPhysics(); - - // update our last valid AAS location for the AI - SetAASLocation(); - - if ( spectating ) { - newEyeOffset = 0.0f; - } else if ( health <= 0 ) { - newEyeOffset = pm_deadviewheight.GetFloat(); - } else if ( physicsObj.IsCrouching() ) { - newEyeOffset = pm_crouchviewheight.GetFloat(); - } else if ( GetBindMaster() && GetBindMaster()->IsType( idAFEntity_Vehicle::Type ) ) { - newEyeOffset = 0.0f; - } else { - newEyeOffset = pm_normalviewheight.GetFloat(); - } - - if ( EyeHeight() != newEyeOffset ) { - if ( spectating ) { - SetEyeHeight( newEyeOffset ); - } else { - // smooth out duck height changes - SetEyeHeight( EyeHeight() * pm_crouchrate.GetFloat() + newEyeOffset * ( 1.0f - pm_crouchrate.GetFloat() ) ); - } - } - - if ( noclip || gameLocal.inCinematic || ( influenceActive == INFLUENCE_LEVEL2 ) ) { - AI_CROUCH = false; - AI_ONGROUND = ( influenceActive == INFLUENCE_LEVEL2 ); - AI_ONLADDER = false; - AI_JUMP = false; - } else { - AI_CROUCH = physicsObj.IsCrouching(); - AI_ONGROUND = physicsObj.HasGroundContacts(); - AI_ONLADDER = physicsObj.OnLadder(); - AI_JUMP = physicsObj.HasJumped(); - - // check if we're standing on top of a monster and give a push if we are - idEntity *groundEnt = physicsObj.GetGroundEntity(); - if - ( - groundEnt && groundEnt->IsType( idAI::Type ) - && groundEnt->health > 0 - && static_cast(groundEnt)->m_bPushOffPlayer - ) - { - idVec3 vel = physicsObj.GetLinearVelocity(); - if ( vel.ToVec2().LengthSqr() < 0.1f ) { - vel.ToVec2() = physicsObj.GetOrigin().ToVec2() - groundEnt->GetPhysics()->GetAbsBounds().GetCenter().ToVec2(); - vel.ToVec2().NormalizeFast(); - vel.ToVec2() *= pm_walkspeed.GetFloat(); - } else { - // give em a push in the direction they're going - vel *= 1.1f; - } - physicsObj.SetLinearVelocity( vel ); - } - } - - if ( AI_JUMP ) - { - // bounce the view weapon - loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; - currentLoggedAccel++; - acc->time = gameLocal.time; - acc->dir[2] = 200; - acc->dir[0] = acc->dir[1] = 0; - } - - // play rope movement sounds - if (physicsObj.OnRope()) - { - // Correct for moving reference frame - int startTime = gameLocal.previousTime; - int endTime = gameLocal.time; - float refZOffset = MS2SEC(endTime - startTime) * physicsObj.GetRefEntVel().z; - - int old_vert = static_cast(savedOrigin.z / cv_pm_rope_snd_rep_dist.GetInteger()); - int new_vert = static_cast((physicsObj.GetOrigin().z - refZOffset) / cv_pm_rope_snd_rep_dist.GetInteger()); - - if (old_vert != new_vert) - { - // greebo: Get the rope entity and read the material/sound type from its spawnargs - idEntity* rope = physicsObj.GetRopeEntity(); - - // If we have a valid rope entity, copy the rope movement snd_ value from it to the player's spawnargs - if (rope != NULL) - { - const char* const tempKey = "snd_rope_climb_temp__"; // temporary key - - // Check if the rope has an override keyvalue - const idKeyValue* kv = rope->spawnArgs.FindKey("snd_rope_climb"); - - // Fill the temporary key on the player entity - if (kv != NULL && kv->GetValue().Length() > 0) - { - spawnArgs.Set(tempKey, kv->GetValue()); - } - else - { - // No special climb sound on the entity, use the one in the player def - spawnArgs.Set(tempKey, spawnArgs.GetString("snd_rope_climb")); - } - - // Start the sound using the temporary key - StartSound(tempKey, SND_CHANNEL_ANY, 0, false, NULL); - } - else - { - // No rope entity?! Fall back to player default - StartSound("snd_rope_climb", SND_CHANNEL_ANY, 0, false, NULL); - } - } - } - // play climbing movement sounds - else if (AI_ONLADDER) - { - // Correct for moving reference frame - int startTime = gameLocal.previousTime; - int endTime = gameLocal.time; - idVec3 RefFrameOffset = MS2SEC(endTime - startTime) * physicsObj.GetRefEntVel(); - idVec3 GravNormal = physicsObj.GetGravityNormal(); - idVec3 RefFrameOffsetXY = RefFrameOffset - (RefFrameOffset * GravNormal ) * GravNormal; - - int old_vert = static_cast(savedOrigin.z / physicsObj.GetClimbSndRepDistVert()); - int new_vert = static_cast((physicsObj.GetOrigin().z - RefFrameOffset.z) / physicsObj.GetClimbSndRepDistVert()); - - int old_horiz = static_cast(physicsObj.GetClimbLateralCoord( savedOrigin ) / physicsObj.GetClimbSndRepDistHoriz()); - int new_horiz = static_cast(physicsObj.GetClimbLateralCoord( physicsObj.GetOrigin() - RefFrameOffsetXY ) / physicsObj.GetClimbSndRepDistHoriz()); - - idStr localSound; - - if (old_vert != new_vert) - { - localSound = "snd_climb_vert_"; - } - else if (old_horiz != new_horiz) - { - localSound = "snd_climb_horiz_"; - } - - if (localSound.Length() > 0) - { - idStr surfaceName = physicsObj.GetClimbSurfaceType(); - - idStr tempStr = localSound + surfaceName; - idStr sound = spawnArgs.GetString(tempStr.c_str()); - - if (sound.Length() == 0) - { - tempStr = localSound + "default"; - sound = spawnArgs.GetString(tempStr.c_str()); - } - // DM_LOG(LC_MOVEMENT, LT_DEBUG)LOGSTRING("Climb sound: %s\r", TempStr.c_str() ); - if (sound.Length() > 0) - { - StartSound(tempStr.c_str(), SND_CHANNEL_BODY, 0, false, NULL); // grayman - #2341 - was SND_CHANNEL_ANY - } - } - } - - if (health > 0) - { - CrashLand(savedOrigin, savedVelocity); - } - - BobCycle(pushVelocity); -} - -/* -============== -idPlayer::UpdateHUD -============== -*/ -void idPlayer::UpdateHUD() -{ - if (hud == NULL) return; - - if ( entityNumber != gameLocal.localClientNum ) { - return; - } - - // Broadcast the HUD opacity value - m_overlays.setGlobalStateFloat("HUD_Opacity", cv_tdm_hud_opacity.GetFloat()); - - // Propagate the CVAR to the HUD - hud->SetStateBool("HUD_LightgemVisible", !cv_tdm_hud_hide_lightgem.GetBool()); - - // Update the inventory HUD - UpdateInventoryHUD(); - - // Check if any HUD messages are pending - UpdateHUDMessages(); - UpdateInventoryPickedUpMessages(); - - // Update the playing time in the HUD, if desired - hud->SetStateString("PlayingTime", cv_show_gameplay_time.GetBool() ? gameLocal.m_GamePlayTimer.GetTime().c_str() : ""); - - hud->SetStateBool("PlayerIsCrouched", m_CrouchIntent ? true : false); -} - -void idPlayer::UpdateInventoryHUD() -{ - if (!inventoryHUDNeedsUpdate) return; // nothing to do - - // Clear the flag right before taking any action - inventoryHUDNeedsUpdate = false; - - CInventoryItemPtr curItem = InventoryCursor()->GetCurrentItem(); - - if (curItem == NULL) return; // no current item, nothing to do - - idEntity* curItemEnt = curItem->GetItemEntity(); - - if (curItemEnt != NULL) - { - // Call the item's update routine for the update - idThread* thread = curItemEnt->CallScriptFunctionArgs( - "inventory_item_update", true, 0, - "eef", curItemEnt, curItem->GetOwner(), static_cast(curItem->GetOverlay()) - ); - - if (thread != NULL) - { - thread->Execute(); - } - } - - // Now take the correct action based on the selected type - switch (curItem->GetType()) - { - case CInventoryItem::IT_ITEM: - { - // We display the default hud if the item doesn't have its own. Each item - // with its own gui is responsible for switching it on and off - // appropriately with their respective events. - if (curItem->HasHUD() == false) - { - SetGuiInt(m_InventoryOverlay, "Inventory_GroupVisible", 1); - SetGuiInt(m_InventoryOverlay, "Inventory_ItemVisible", 1); - - idStr itemName = gameLocal.m_I18N->Translate( curItem->GetName() ); - - // Tels: translated names can have two lines, so tell the GUI about it - SetGuiInt(m_InventoryOverlay, "Inventory_ItemNameMultiline", itemName.Find( '\n' ) != -1 ? 1 : 0 ); - - SetGuiFloat(m_InventoryOverlay, "Inventory_ItemStackable", curItem->IsStackable() ? 1 : 0); - SetGuiString(m_InventoryOverlay, "Inventory_ItemGroup", gameLocal.m_I18N->Translate( curItem->Category()->GetName() ) ); - SetGuiString(m_InventoryOverlay, "Inventory_ItemName", itemName ); - SetGuiInt(m_InventoryOverlay, "Inventory_ItemCount", curItem->GetCount()); - SetGuiString(m_InventoryOverlay, "Inventory_ItemIcon", curItem->GetIcon().c_str()); - } - } - break; - - case CInventoryItem::IT_DUMMY: - { - // All objects are set to empty, so we have an empty entry in the inventory. - SetGuiInt(m_InventoryOverlay, "Inventory_ItemVisible", 0); - SetGuiInt(m_InventoryOverlay, "Inventory_LootVisible", 0); - SetGuiInt(m_InventoryOverlay, "Inventory_GroupVisible", 0); - } - break; - - default: break; - } - - idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); - if (invGUI != NULL) - { - invGUI->StateChanged(gameLocal.time); - } -} - -void idPlayer::UpdateHUDMessages() -{ - if (hudMessages.Num() == 0) { - return; // nothing to do - } - - // We have a message to display, check if the HUD is ready for it - if (hud == NULL) { - return; // no HUD? - } - - int hasMessage = hud->GetStateInt("HasMessage"); - - if (hasMessage == 1) { - // The HUD is still busy, leave it for the moment being - return; - } - - // greebo: We have a message and the HUD is ready, shove it into the GUI. - hud->SetStateString("MessageText", hudMessages[0]); - hud->HandleNamedEvent("DisplayMessage"); - - // Remove the first string, now that it's been moved into the GUI - hudMessages.RemoveIndex(0); -} - -void idPlayer::UpdateInventoryPickedUpMessages() -{ - if (inventoryPickedUpMessages.Num() == 0) return; // nothing to do - - // We have a message to display, check if the HUD is ready for it - - idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); - - if (invGUI == NULL) - { - DM_LOG(LC_INVENTORY, LT_ERROR)LOGSTRING("Could not find inventory HUD, cannot update pickup messages.\r"); - return; // no overlay? - } - - /* - greebo: Commented this out to let new pickup messages overwrite the old ones. - Put this back in to let the GUI display one message after the other. - - int hasMessage = invGUI->GetStateInt("HasInventoryPickUpMessage"); - - if (hasMessage == 1) - { - // The HUD is still busy, leave it for the moment being - return; - }*/ - - // greebo: We have a message and the HUD is ready, shove it into the GUI. - invGUI->SetStateString("InventoryPickUpMessageText", inventoryPickedUpMessages[0]); - invGUI->HandleNamedEvent("DisplayInventoryPickUpMessage"); - - // Remove the first string, now that it's been moved into the GUI - inventoryPickedUpMessages.RemoveIndex(0); -} - -/* -============== -idPlayer::UpdateDeathSkin -============== -*/ -void idPlayer::UpdateDeathSkin( bool state_hitch ) { - if ( !( gameLocal.isMultiplayer || g_testDeath.GetBool() ) ) { - return; - } - if ( health <= 0 ) { - if ( !doingDeathSkin ) { - deathClearContentsTime = spawnArgs.GetInt( "deathSkinTime" ); - doingDeathSkin = true; - renderEntity.noShadow = true; - if ( state_hitch ) { - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f - 2.0f; - } else { - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; - } - UpdateVisuals(); - } - - // wait a bit before switching off the content - if ( deathClearContentsTime && gameLocal.time > deathClearContentsTime ) { - SetCombatContents( false ); - deathClearContentsTime = 0; - } - } else { - renderEntity.noShadow = false; - renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = 0.0f; - UpdateVisuals(); - doingDeathSkin = false; - } -} - -/* -============== -idPlayer::StartFxOnBone -============== -*/ -void idPlayer::StartFxOnBone( const char *fx, const char *bone ) { - idVec3 offset; - idMat3 axis; - jointHandle_t jointHandle = GetAnimator()->GetJointHandle( bone ); - - if ( jointHandle == INVALID_JOINT ) { - gameLocal.Printf( "Cannot find bone %s\n", bone ); - return; - } - - if ( GetAnimator()->GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { - offset = GetPhysics()->GetOrigin() + offset * GetPhysics()->GetAxis(); - axis = axis * GetPhysics()->GetAxis(); - } - - idEntityFx::StartFx( fx, &offset, &axis, this, true ); -} - -void idPlayer::UpdateUnderWaterEffects() { - if ( physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD ) { - if (!underWaterEffectsActive) { - StartSound( "snd_airless", SND_CHANNEL_DEMONIC, 0, false, NULL ); - - // Underwater GUI section, allows custom water guis for each water entity etc - Dram - idStr overlay; - idPhysics_Liquid* CurWaterEnt = GetPlayerPhysics()->GetWater(); - if (CurWaterEnt != NULL) { // Get the GUI from the current water entity - idEntity* CurEnt = CurWaterEnt->GetSelf(); - if (CurEnt != NULL) { - overlay = CurEnt->spawnArgs.GetString("underwater_gui"); - } - gameLocal.Printf( "UNDERWATER: After water check overlay is %s\n", overlay.c_str() ); - } - if (overlay.IsEmpty()) { // If the overlay string is empty it has failed to find the GUI on the entity, so give warning - gameLocal.Warning( "UNDERWATER: water check overlay failed, check key/val pairs\n" ); - } - else if (!overlay.IsEmpty()) { - underWaterGUIHandle = CreateOverlay(overlay.c_str(), LAYER_UNDERWATER); - } - underWaterEffectsActive = true; - } - } - else { - if (underWaterEffectsActive) - { - StopSound( SND_CHANNEL_DEMONIC, false ); - if (underWaterGUIHandle != -1) { - DestroyOverlay(underWaterGUIHandle); - underWaterGUIHandle = -1; - } - - // If we were underwater for more than 4 seconds, play the "take breath" sound - if (gameLocal.time > physicsObj.GetSubmerseTime() + 4000) - { - StartSound( "snd_resurface", SND_CHANNEL_VOICE, 0, false, NULL ); - } - - underWaterEffectsActive = false; - } - } -} - -/* -============== -idPlayer::Think - -Called every tic for each player -============== -*/ -void idPlayer::Think( void ) -{ - bool allowAttack = false; - renderEntity_t *headRenderEnt; - UpdatePlayerIcons(); - - // latch button actions - oldButtons = usercmd.buttons; - - // grab out usercmd - usercmd_t oldCmd = usercmd; - usercmd = gameLocal.usercmds[ entityNumber ]; - buttonMask &= usercmd.buttons; - usercmd.buttons &= ~buttonMask; - - // Solarsplace 19th Nov 2010 - Bug tracker id 0002424 - if ( ! (gameLocal.mainMenuExited && ( usercmd.buttons & BUTTON_ATTACK )) ) - { - allowAttack = true; - gameLocal.mainMenuExited = false; - } - - // angua: disable doom3 crouching - if (usercmd.upmove < 0) - { - usercmd.upmove = 0; - } - - // greebo: Check always run - if (cvarSystem->GetCVarBool("in_alwaysRun")) - { - // Always run active, invert the behaviour, user has to hold down button to walk - usercmd.buttons ^= BUTTON_RUN; - } - - if( !AI_PAIN ) - m_bDamagedThisFrame = false; - - if ( gameLocal.inCinematic && gameLocal.skipCinematic ) { - return; - } - - // clear the ik before we do anything else so the skeleton doesn't get updated twice - walkIK.ClearJointMods(); - - // if this is the very first frame of the map, set the delta view angles - // based on the usercmd angles - if ( !spawnAnglesSet && ( gameLocal.GameState() != GAMESTATE_STARTUP ) ) { - spawnAnglesSet = true; - SetViewAngles( spawnAngles ); - oldFlags = usercmd.flags; - } - - if ( gameLocal.inCinematic || influenceActive ) - { - usercmd.forwardmove = 0; - usercmd.rightmove = 0; - usercmd.upmove = 0; - } - - // I'm not sure if this is the best way to do things, since it doesn't yet - // take into account whether the player is swimming/climbing, etc. But it - // should be good enough for now. I'll improve it later. - // -Gildoran - if ( GetImmobilization() & EIM_MOVEMENT ) { - usercmd.forwardmove = 0; - usercmd.rightmove = 0; - } - // Note to self: I should probably be thinking about having some sort of - // flag where the player is kept crouching if that's how they started out. - - // angua: crouch immobilization is handled in EvaluateCrouch now - if ( GetImmobilization() & EIM_JUMP && usercmd.upmove > 0 ) { - usercmd.upmove = 0; - } - - // log movement changes for weapon bobbing effects - if ( usercmd.forwardmove != oldCmd.forwardmove ) { - loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; - currentLoggedAccel++; - acc->time = gameLocal.time; - acc->dir[0] = usercmd.forwardmove - oldCmd.forwardmove; - acc->dir[1] = acc->dir[2] = 0; - } - - if ( usercmd.rightmove != oldCmd.rightmove ) { - loggedAccel_t *acc = &loggedAccel[currentLoggedAccel&(NUM_LOGGED_ACCELS-1)]; - currentLoggedAccel++; - acc->time = gameLocal.time; - acc->dir[1] = usercmd.rightmove - oldCmd.rightmove; - acc->dir[0] = acc->dir[2] = 0; - } - - // freelook centering - if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_MLOOK ) { - centerView.Init( gameLocal.time, 200, viewAngles.pitch, 0 ); - } - - // zooming (greebo: Disabled this due to interference with the spyglass, isn't needed anymore) - /*if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_ZOOM ) { - if ( ( usercmd.buttons & BUTTON_ZOOM ) && weapon.GetEntity() ) { - zoomFov.Init( gameLocal.time, 200.0f, CalcFov( false ), weapon.GetEntity()->GetZoomFov() ); - } else { - zoomFov.Init( gameLocal.time, 200.0f, zoomFov.GetCurrentValue( gameLocal.time ), DefaultFov() ); - } - }*/ - - // if we have an active gui, we will unrotate the view angles as - // we turn the mouse movements into gui events - idUserInterface *gui = ActiveGui(); - if ( gui /*&& gui != focusUI*/ ) { - RouteGuiMouse( gui ); - } - - // set the push velocity on the weapon before running the physics - if ( weapon.GetEntity() ) { - weapon.GetEntity()->SetPushVelocity( physicsObj.GetPushedLinearVelocity() ); - } - - EvaluateControls(); - - EvaluateCrouch(); - - - if ( !af.IsActive() ) { - AdjustBodyAngles(); - CopyJointsFromBodyToHead(); - } - - Move(); - - if ( !g_stopTime.GetBool() ) { - - if ( !noclip && !spectating && ( health > 0 ) && !IsHidden() ) { - TouchTriggers(); - } - - // not done on clients for various reasons. don't do it on server and save the sound channel for other things - /*if ( !gameLocal.isMultiplayer ) { - SetCurrentHeartRate(); - float scale = g_damageScale.GetFloat(); - if ( g_useDynamicProtection.GetBool() && scale < 1.0f && gameLocal.time - lastDmgTime > 500 ) { - if ( scale < 1.0f ) { - scale += 0.05f; - } - if ( scale > 1.0f ) { - scale = 1.0f; - } - g_damageScale.SetFloat( scale ); - } - }*/ - -#if 0 - // update GUIs, Items, and character interactions - UpdateFocus(); -#endif - - UpdateLocation(); - - // update player script - UpdateScript(); - - // service animations - if ( !spectating && !af.IsActive() && !gameLocal.inCinematic ) { - // Update the button state, this calls PerformKeyRelease() if a button has been released - m_ButtonStateTracker.Update(); - - UpdateConditions(); - - UpdateAnimState(); - CheckBlink(); - } - - // clear out our pain flag so we can tell if we recieve any damage between now and the next time we think - AI_PAIN = false; - } - - // calculate the exact bobbed view position, which is used to - // position the view weapon, among other things - CalculateFirstPersonView(); - - // this may use firstPersonView, or a thirdPerson / camera view - CalculateRenderView(); - - PerformFrobCheck(); - - // greebo: Close any opened inventory maps when releasing the attack button (#2460) - if (m_ActiveInventoryMapEnt.GetEntity() != NULL && (oldButtons & BUTTON_ATTACK) && !(usercmd.buttons & BUTTON_ATTACK)) - { - ClearActiveInventoryMap(); - - // Disallow attacks to avoid triggering the weapon immediately after closing the map - allowAttack = false; - } - - // Check if we just hit the attack button - idEntity* frobbedEnt = m_FrobEntity.GetEntity(); - - // Solarsplace: allowAttack - bug fix for #2424 - if (frobbedEnt != NULL && usercmd.buttons & BUTTON_ATTACK && !(oldButtons & BUTTON_ATTACK) && allowAttack) - { - frobbedEnt->AttackAction(this); - } - -/* - // TODO: remove this because it is just to determine how to fill out the renderstructure. - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("RenderViewId: %u\r", renderView->viewID); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("x: %u y: %u w: %u h: %u\r", renderView->x, renderView->y, renderView->width, renderView->height); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("FovX: %f FovY: %f\r", renderView->fov_x, renderView->fov_y); - DM_LOGVECTOR3(LC_LIGHT, LT_DEBUG, "vieworg", renderView->vieworg); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("cramZNear: %u forceUpdate: %u\r", renderView->cramZNear, renderView->forceUpdate); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("time: %u\r", renderView->time); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("time: %u\r", renderView->globalMaterial); - for(i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++) - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Param[%u]: %f\r", i, renderView->shaderParms[i]); -*/ - if ( spectating ) { - UpdateSpectating(); - } else if ( health > 0 && allowAttack) { - UpdateWeapon(); - } - - UpdateAir(); - - // greebo: update underwater overlay and sounds - UpdateUnderWaterEffects(); - - UpdateHUD(); - - UpdatePowerUps(); - - UpdateDeathSkin( false ); - - if ( gameLocal.isMultiplayer ) { - DrawPlayerIcons(); - } - - if ( head.GetEntity() ) { - headRenderEnt = head.GetEntity()->GetRenderEntity(); - } else { - headRenderEnt = NULL; - } - - if ( headRenderEnt ) { - if ( influenceSkin ) { - headRenderEnt->customSkin = influenceSkin; - } else { - headRenderEnt->customSkin = NULL; - } - } - - if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() ) { - renderEntity.suppressShadowInViewID = 0; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInViewID = 0; - } - } else { - renderEntity.suppressShadowInViewID = entityNumber+1; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInViewID = entityNumber+1; - } - } - // never cast shadows from our first-person muzzle flashes - renderEntity.suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; - } - - if ( !g_stopTime.GetBool() ) { - UpdateAnimation(); - - Present(); - - UpdateDamageEffects(); - - LinkCombat(); - - playerView.CalculateShake(); - } - - if ( !( thinkFlags & TH_THINK ) ) { - gameLocal.Printf( "player %d not thinking?\n", entityNumber ); - } - - if ( g_showEnemies.GetBool() ) { - idActor *ent; - int num = 0; - for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) { - gameLocal.Printf( "enemy (%d)'%s'\n", ent->entityNumber, ent->name.c_str() ); - gameRenderWorld->DebugBounds( colorRed, ent->GetPhysics()->GetBounds().Expand( 2 ), ent->GetPhysics()->GetOrigin() ); - num++; - } - gameLocal.Printf( "%d: enemies\n", num ); - } - - if (cv_pm_show_waterlevel.GetBool()) - { - idStr waterStr; - switch (physicsObj.GetWaterLevel()) - { - case WATERLEVEL_NONE: waterStr = "WATERLEVEL: NONE"; break; - case WATERLEVEL_FEET: waterStr = "WATERLEVEL: FEET"; break; - case WATERLEVEL_WAIST: waterStr = "WATERLEVEL: WAIST"; break; - case WATERLEVEL_HEAD: waterStr = "WATERLEVEL: HEAD"; break; - default: waterStr = "WATERLEVEL: ???"; break; - }; - gameRenderWorld->DrawText(waterStr.c_str(), GetEyePosition() + viewAxis.ToAngles().ToForward()*200, 0.7f, colorWhite, viewAxis, 1, 16); - } - - // determine if portal sky is in pvs - gameLocal.portalSkyActive = gameLocal.pvs.CheckAreasForPortalSky( gameLocal.GetPlayerPVS(), GetPhysics()->GetOrigin() ); -} - -/* -================= -idPlayer::RouteGuiMouse -================= -*/ -void idPlayer::RouteGuiMouse( idUserInterface *gui ) { - sysEvent_t ev; - const char *command; - - /*if ( gui == m_overlays.findInteractive() ) { - // Ensure that gui overlays are always able to execute commands, - // even if the player isn't moving the mouse. - ev = sys->GenerateMouseMoveEvent( usercmd.mx - oldMouseX, usercmd.my - oldMouseY ); - command = gui->HandleEvent( &ev, gameLocal.time ); - HandleGuiCommands( this, command ); - oldMouseX = usercmd.mx; - oldMouseY = usercmd.my; - }*/ - - if ( usercmd.mx != oldMouseX || usercmd.my != oldMouseY ) { - ev = sys->GenerateMouseMoveEvent( usercmd.mx - oldMouseX, usercmd.my - oldMouseY ); - command = gui->HandleEvent( &ev, gameLocal.time ); - oldMouseX = usercmd.mx; - oldMouseY = usercmd.my; - } -} - -/* -================== -idPlayer::LookAtKiller -================== -*/ -void idPlayer::LookAtKiller( idEntity *inflictor, idEntity *attacker ) { - idVec3 dir; - - if ( attacker && attacker != this ) { - dir = attacker->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - } else if ( inflictor && inflictor != this ) { - dir = inflictor->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - } else { - dir = viewAxis[ 0 ]; - } - - idAngles ang( 0, dir.ToYaw(), 0 ); - SetViewAngles( ang ); -} - -/* -============== -idPlayer::Kill -============== -*/ -void idPlayer::Kill( bool delayRespawn, bool nodamage ) { - if ( spectating ) { - SpectateFreeFly( false ); - } else if ( health > 0 ) { - godmode = false; - if ( nodamage ) { - ServerSpectate( true ); - forceRespawn = true; - } else { - Damage( this, this, vec3_origin, "damage_suicide", 1.0f, INVALID_JOINT ); - if ( delayRespawn ) { - forceRespawn = false; - int delay = spawnArgs.GetInt( "respawn_delay" ); - minRespawnTime = gameLocal.time + SEC2MS( delay ); - maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; - } - } - } -} - -/* -================== -idPlayer::Killed -================== -*/ -void idPlayer::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - float delay; - - assert( !gameLocal.isClient ); - - // stop taking knockback once dead - fl.noknockback = true; - if ( health < -999 ) { - health = -999; - } - - if ( AI_DEAD ) { - AI_PAIN = true; - return; - } - - heartInfo.Init( 0, 0, 0, BASE_HEARTRATE ); - AdjustHeartRate( DEAD_HEARTRATE, 10.0f, 0.0f, true ); - - AI_DEAD = true; - - // greebo: Before posting mission failed and going to ragdoll, check for custom death script - if (gameLocal.world != NULL && gameLocal.world->spawnArgs.GetInt("custom_death_delay") > 0) - { - // greebo: Still call the ownerdied method to cleanup the weapon script state - weapon.GetEntity()->OwnerDied(); - - // Run the death event in a few seconds - PostEventMS(&EV_Player_CustomDeath, SEC2MS(gameLocal.world->spawnArgs.GetInt("custom_death_delay"))); - return; // stop death processing here - } - - this->PostEventMS( &EV_Player_MissionFailed, spawnArgs.GetInt("death_transit_time", "2000") ); - - SetAnimState( ANIMCHANNEL_LEGS, "Legs_Death", 4 ); - SetAnimState( ANIMCHANNEL_TORSO, "Torso_Death", 4 ); - SetWaitState( "" ); - - animator.ClearAllJoints(); - -// NOTE: RespawnTime not used anymore in TDM except maybe for third person death later? - if ( StartRagdoll() ) { - pm_modelView.SetInteger( 0 ); - minRespawnTime = gameLocal.time + RAGDOLL_DEATH_TIME; - maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; - } else { - // don't allow respawn until the death anim is done - // g_forcerespawn may force spawning at some later time - delay = spawnArgs.GetFloat( "respawn_delay" ); - minRespawnTime = gameLocal.time + SEC2MS( delay ); - maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME; - } - - physicsObj.SetMovementType( PM_DEAD ); - - // greebo: Prevent all movement, weapon and item usage when dead - SetImmobilization("death", EIM_ALL); - - // Play the death sound on the voice channel - idStr deathSound = (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD) ? "snd_death_liquid" : "snd_death"; - StartSound( deathSound, SND_CHANNEL_VOICE, 0, false, NULL ); - - StopSound( SND_CHANNEL_BODY2, false ); - - fl.takedamage = true; // can still be gibbed - - // get rid of weapon - weapon.GetEntity()->OwnerDied(); - - // drop the weapon as an item - DropWeapon( true ); - - if ( !g_testDeath.GetBool() ) { - LookAtKiller( inflictor, attacker ); - } - - if ( gameLocal.isMultiplayer || g_testDeath.GetBool() ) { - idPlayer *killer = NULL; - // no gibbing in MP. Event_Gib will early out in MP - if ( attacker->IsType( idPlayer::Type ) ) { - killer = static_cast(attacker); - if ( health < -20 ) { - gibDeath = true; - gibsDir = dir; - gibsLaunched = false; - } - } - gameLocal.mpGame.PlayerDeath( this, killer, isTelefragged ); - } else - { - physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - { - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - } - } - - UpdateVisuals(); - - isChatting = false; -} - -/* -===================== -idPlayer::GetAIAimTargets - -Returns positions for the AI to aim at. -===================== -*/ -void idPlayer::GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ) { - idVec3 offset; - idMat3 axis; - idVec3 origin; - - origin = lastSightPos - physicsObj.GetOrigin(); - - GetJointWorldTransform( chestJoint, gameLocal.time, offset, axis ); - headPos = offset + origin; - - GetJointWorldTransform( headJoint, gameLocal.time, offset, axis ); - chestPos = offset + origin; -} - -/* -================ -idPlayer::DamageFeedback - -callback function for when another entity recieved damage from this entity. damage can be adjusted and returned to the caller. -================ -*/ -void idPlayer::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { - assert( !gameLocal.isClient ); - damage = static_cast(damage * PowerUpModifier( BERSERK )); - if ( damage && ( victim != this ) && victim->IsType( idActor::Type ) ) { - SetLastHitTime( gameLocal.time ); - } - - // greebo: Update the mission statistics, we've damaged another actor - gameLocal.m_MissionData->AIDamagedByPlayer(damage); -} - -/* -================= -idPlayer::CalcDamagePoints - -Calculates how many health and armor points will be inflicted, but -doesn't actually do anything with them. This is used to tell when an attack -would have killed the player, possibly allowing a "saving throw" -================= -*/ -void idPlayer::CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef, - const float damageScale, const int location, int *health, int *armor ) { - int damage; - int armorSave; - - damageDef->GetInt( "damage", "20", damage ); - damage = GetDamageForLocation( damage, location ); - - idPlayer *player = attacker->IsType( idPlayer::Type ) ? static_cast(attacker) : NULL; - if ( !gameLocal.isMultiplayer ) { - if ( inflictor != gameLocal.world ) { - switch ( g_skill.GetInteger() ) { - case 0: - damage *= 0.80f; - if ( damage < 1 ) { - damage = 1; - } - break; - case 2: - damage *= 1.70f; - break; - case 3: - damage *= 3.5f; - break; - default: - break; - } - } - } - - damage *= damageScale; - - // always give half damage if hurting self - if ( attacker == this ) { - if ( gameLocal.isMultiplayer ) { - // only do this in mp so single player plasma and rocket splash is very dangerous in close quarters - damage *= damageDef->GetFloat( "selfDamageScale", "0.5" ); - } else { - damage *= damageDef->GetFloat( "selfDamageScale", "1" ); - } - } - - // check for completely getting out of the damage - if ( !damageDef->GetBool( "noGod" ) ) { - // check for godmode - if ( godmode ) { - damage = 0; - } - } - - // inform the attacker that they hit someone - attacker->DamageFeedback( this, inflictor, damage ); - - // save some from armor - if ( !damageDef->GetBool( "noArmor" ) ) { - /*float armor_protection; - - armor_protection = ( gameLocal.isMultiplayer ) ? g_armorProtectionMP.GetFloat() : g_armorProtection.GetFloat(); - - armorSave = ceil( damage * armor_protection ); - if ( armorSave >= inventory.armor ) { - armorSave = inventory.armor; - }*/ - armorSave = 0; - - if ( !damage ) { - armorSave = 0; - } else if ( armorSave >= damage ) { - armorSave = damage - 1; - damage = 1; - } else { - damage -= armorSave; - } - } else { - armorSave = 0; - } - - // check for team damage - if ( gameLocal.gameType == GAME_TDM - && !gameLocal.serverInfo.GetBool( "si_teamDamage" ) - && !damageDef->GetBool( "noTeam" ) - && player - && player != this // you get self damage no matter what - && player->team == team ) { - damage = 0; - } - - *health = damage; - *armor = armorSave; -} - -/* -============ -Damage - -this entity that is being damaged -inflictor entity that is causing the damage -attacker entity that caused the inflictor to damage targ - example: this=monster, inflictor=rocket, attacker=player - -dir direction of the attack for knockback in global space - -damageDef an idDict with all the options for damage effects - -inflictor, attacker, dir, and point can be NULL for environmental effects -============ -*/ -void idPlayer::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision ) -{ - idVec3 kick; - int damage; - int armorSave; - int knockback; - idVec3 damage_from; - idVec3 localDamageVector; - float attackerPushScale; - - // damage is only processed on server - if ( gameLocal.isClient ) { - return; - } - - if ( !fl.takedamage || noclip || spectating || gameLocal.inCinematic ) { - return; - } - - if ( !inflictor ) { - inflictor = gameLocal.world; - } - if ( !attacker ) { - attacker = gameLocal.world; - } - - if ( attacker->IsType( idAI::Type ) ) { - // don't take damage from monsters during influences - if ( influenceActive != 0 ) { - return; - } - } - - const idDeclEntityDef *damageDef = gameLocal.FindEntityDef( damageDefName, false ); - if ( !damageDef ) { - gameLocal.Warning( "Unknown damageDef '%s'", damageDefName ); - return; - } - - if ( damageDef->dict.GetBool( "ignore_player" ) ) { - return; - } - - CalcDamagePoints( inflictor, attacker, &damageDef->dict, damageScale, location, &damage, &armorSave ); - - // determine knockback - damageDef->dict.GetInt( "knockback", "20", knockback ); - - if ( knockback != 0 && !fl.noknockback ) { - if ( attacker == this ) { - damageDef->dict.GetFloat( "attackerPushScale", "0", attackerPushScale ); - } else { - attackerPushScale = 1.0f; - } - - kick = dir; - kick.Normalize(); - kick *= g_knockback.GetFloat() * knockback * attackerPushScale / 200.0f; - physicsObj.SetLinearVelocity( physicsObj.GetLinearVelocity() + kick ); - - // set the timer so that the player can't cancel out the movement immediately - physicsObj.SetKnockBack( idMath::ClampInt( 50, 200, knockback * 2 ) ); - } - - // give feedback on the player view and audibly when armor is helping - /*if ( armorSave ) { - inventory.armor -= armorSave; - - if ( gameLocal.time > lastArmorPulse + 200 ) { - StartSound( "snd_hitArmor", SND_CHANNEL_ITEM, 0, false, NULL ); - } - lastArmorPulse = gameLocal.time; - }*/ - - if ( damageDef->dict.GetBool( "burn" ) ) - { - StartSound( "snd_burn", SND_CHANNEL_BODY3, 0, false, NULL ); - } - - if ( g_debugDamage.GetInteger() ) { - gameLocal.Printf( "client:%i health:%i damage:%i armor:%i\n", - entityNumber, health, damage, armorSave ); - } - - // move the world direction vector to local coordinates - damage_from = dir; - damage_from.Normalize(); - - viewAxis.ProjectVector( damage_from, localDamageVector ); - - // add to the damage inflicted on a player this frame - // the total will be turned into screen blends and view angle kicks - // at the end of the frame - if ( health > 0 ) { - playerView.DamageImpulse( localDamageVector, &damageDef->dict ); - } - - // do the damage - if ( damage > 0 ) - { - - if ( !gameLocal.isMultiplayer ) - { - float scale = g_damageScale.GetFloat(); - /*if ( g_useDynamicProtection.GetBool() && g_skill.GetInteger() < 2 ) { - if ( gameLocal.time > lastDmgTime + 500 && scale > 0.25f ) { - scale -= 0.05f; - g_damageScale.SetFloat( scale ); - } - }*/ - - if ( scale > 0.0f ) - { - damage *= scale; - } - } - - if ( damage < 1 ) - { - damage = 1; - } - -// int oldHealth = health; - health -= damage; - - // greebo: Update mission statistics, we've taken damage - gameLocal.m_MissionData->PlayerDamaged(damage); - - // ishtvan bugfix: set m_bDamagedThisFrame here, rather than in ::Think - // compare against pain threshold so that things like low-grade poison gas don't prevent player actions - if ( damage > pain_threshold ) - m_bDamagedThisFrame = true; - - if ( health <= 0 ) - { - - if ( health < -999 ) - { - health = -999; - } - - isTelefragged = damageDef->dict.GetBool( "telefrag" ); - - lastDmgTime = gameLocal.time; - Killed( inflictor, attacker, damage, dir, location ); - - } else - { - // force a blink - blink_time = 0; - - if (!damageDef->dict.GetBool( "no_pain" )) - { - // let the anim script know we took damage - AI_PAIN = Pain( inflictor, attacker, damage, dir, location, &damageDef->dict ); - } - - // FIX: if drowning, stop pain SFX and play drown SFX on voice channel - if ( damageDef->dict.GetBool( "no_air" ) ) - { - if ( !armorSave && health > 0 ) - { - StopSound( SND_CHANNEL_VOICE, false ); - StartSound( "snd_airGasp", SND_CHANNEL_VOICE, 0, false, NULL ); - } - } - - if ( !g_testDeath.GetBool() ) - { - lastDmgTime = gameLocal.time; - } - } - } else - { - // don't accumulate impulses - if ( af.IsLoaded() ) - { - // clear impacts - af.Rest(); - - // physics is turned off by calling af.Rest() - BecomeActive( TH_PHYSICS ); - } - } - - lastDamageDef = damageDef->Index(); - lastDamageDir = damage_from; - lastDamageLocation = location; -} - -/* -=========== -idPlayer::Teleport -============ -*/ -void idPlayer::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) { - idVec3 org; - - if ( weapon.GetEntity() ) { - weapon.GetEntity()->LowerWeapon(); - } - - SetOrigin( origin + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - if ( !gameLocal.isMultiplayer && GetFloorPos( 16.0f, org ) ) { - SetOrigin( org ); - } - - // clear the ik heights so model doesn't appear in the wrong place - walkIK.EnableAll(); - - GetPhysics()->SetLinearVelocity( vec3_origin ); - - SetViewAngles( angles ); - - legsYaw = 0.0f; - idealLegsYaw = 0.0f; - oldViewYaw = viewAngles.yaw; - - if ( gameLocal.isMultiplayer ) { - playerView.Flash( colorWhite, 140 ); - } - - UpdateVisuals(); - - teleportEntity = destination; - - if ( !gameLocal.isClient && !noclip ) { - if ( gameLocal.isMultiplayer ) { - // kill anything at the new position or mark for kill depending on immediate or delayed teleport - gameLocal.KillBox( this, destination != NULL ); - } else { - // kill anything at the new position - gameLocal.KillBox( this, true ); - } - } -} - -/* -==================== -idPlayer::SetPrivateCameraView -==================== -*/ -void idPlayer::SetPrivateCameraView( idCamera *camView ) { - privateCameraView = camView; - if ( camView ) { - StopFiring(); - Hide(); - } else { - if ( !spectating ) { - Show(); - } - } -} - -/* -==================== -idPlayer::DefaultFov - -Returns the base FOV -==================== -*/ -float idPlayer::DefaultFov( void ) const { - float fov; - - fov = g_fov.GetFloat(); - if ( gameLocal.isMultiplayer ) { - if ( fov < 90.0f ) { - return 90.0f; - } else if ( fov > 110.0f ) { - return 110.0f; - } - } - - return fov; -} - -/* -==================== -idPlayer::CalcFov - -Fixed fov at intermissions, otherwise account for fov variable and zooms. -==================== -*/ -float idPlayer::CalcFov( bool honorZoom ) { - float fov; - float defaultFov = DefaultFov(); - - if ( fxFov ) { - return defaultFov + 10.0f + cos( ( gameLocal.time + 2000 ) * 0.01 ) * 10.0f; - } - - if ( influenceFov ) { - return influenceFov; - } - - // prevent FOV from zooming if the player is holding an object - if( gameLocal.m_Grabber->GetSelected() ) { - return defaultFov; - } - - // Check if a transition is still ongoing - bool zoomDone = zoomFov.IsDone(gameLocal.time); - float curZoomFov = zoomFov.GetCurrentValue(gameLocal.time); - - // Take the interpolation value, if the zoom is enabled, take the default otherwise - fov = (zoomFov.Enabled()) ? curZoomFov : defaultFov; - - // Check if we need the zoom interpolation anymore - if (zoomFov.Enabled() && zoomDone && curZoomFov == defaultFov) - { - // Zoom is done and is equal to default fov, so we no longer need it - zoomFov.SetEnabled(false); - fov = DefaultFov(); - } - - // bound normal viewsize - if ( fov < 1 ) { - fov = 1; - } else if ( fov > 179 ) { - fov = 179; - } - - return fov; -} - -/* -============== -idPlayer::GunTurningOffset - -generate a rotational offset for the gun based on the view angle -history in loggedViewAngles -============== -*/ -idAngles idPlayer::GunTurningOffset( void ) { - idAngles a; - - a.Zero(); - - if ( gameLocal.framenum < NUM_LOGGED_VIEW_ANGLES ) { - return a; - } - - idAngles current = loggedViewAngles[ gameLocal.framenum & (NUM_LOGGED_VIEW_ANGLES-1) ]; - - idAngles av, base; - int weaponAngleOffsetAverages; - float weaponAngleOffsetScale, weaponAngleOffsetMax; - - weapon.GetEntity()->GetWeaponAngleOffsets( &weaponAngleOffsetAverages, &weaponAngleOffsetScale, &weaponAngleOffsetMax ); - - av = current; - - // calcualte this so the wrap arounds work properly - for ( int j = 1 ; j < weaponAngleOffsetAverages ; j++ ) { - idAngles a2 = loggedViewAngles[ ( gameLocal.framenum - j ) & (NUM_LOGGED_VIEW_ANGLES-1) ]; - - idAngles delta = a2 - current; - - if ( delta[1] > 180 ) { - delta[1] -= 360; - } else if ( delta[1] < -180 ) { - delta[1] += 360; - } - - av += delta * ( 1.0f / weaponAngleOffsetAverages ); - } - - a = ( av - current ) * weaponAngleOffsetScale; - - for ( int i = 0 ; i < 3 ; i++ ) { - if ( a[i] < -weaponAngleOffsetMax ) { - a[i] = -weaponAngleOffsetMax; - } else if ( a[i] > weaponAngleOffsetMax ) { - a[i] = weaponAngleOffsetMax; - } - } - - return a; -} - -/* -============== -idPlayer::GunAcceleratingOffset - -generate a positional offset for the gun based on the movement -history in loggedAccelerations -============== -*/ -idVec3 idPlayer::GunAcceleratingOffset( void ) { - idVec3 ofs; - - float weaponOffsetTime, weaponOffsetScale; - - ofs.Zero(); - - weapon.GetEntity()->GetWeaponTimeOffsets( &weaponOffsetTime, &weaponOffsetScale ); - - int stop = currentLoggedAccel - NUM_LOGGED_ACCELS; - if ( stop < 0 ) { - stop = 0; - } - for ( int i = currentLoggedAccel-1 ; i > stop ; i-- ) { - loggedAccel_t *acc = &loggedAccel[i&(NUM_LOGGED_ACCELS-1)]; - - float f; - float t = gameLocal.time - acc->time; - if ( t >= weaponOffsetTime ) { - break; // remainder are too old to care about - } - - f = t / weaponOffsetTime; - f = ( cos( f * 2.0f * idMath::PI ) - 1.0f ) * 0.5f; - ofs += f * weaponOffsetScale * acc->dir; - } - - return ofs; -} - -/* -============== -idPlayer::CalculateViewWeaponPos - -Calculate the bobbing position of the view weapon -============== -*/ -void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { - float scale; - float fracsin1; - float fracsin2; - float fracsin3; - idAngles angles; - int delta; - - // CalculateRenderView must have been called first - const idVec3 &viewOrigin = firstPersonViewOrigin; - const idMat3 &viewAxis = firstPersonViewAxis; - - // these cvars are just for hand tweaking before moving a value to the weapon def - idVec3 gunpos( g_gun_x.GetFloat(), g_gun_y.GetFloat(), g_gun_z.GetFloat() ); - - // as the player changes direction, the gun will take a small lag - idVec3 gunOfs = GunAcceleratingOffset(); - origin = viewOrigin + ( gunpos + gunOfs ) * viewAxis; - - // on odd legs, invert some angles - if ( bobCycle & 128 ) { - scale = -xyspeed; - } else { - scale = xyspeed; - } - - // gun angles from bobbing - angles.roll = scale * bobfracsin * 0.005f; - angles.yaw = scale * bobfracsin * 0.01f; - angles.pitch = xyspeed * bobfracsin * 0.005f; - - // gun angles from turning - if ( gameLocal.isMultiplayer ) { - idAngles offset = GunTurningOffset(); - offset *= g_mpWeaponAngleScale.GetFloat(); - angles += offset; - } else { - angles += GunTurningOffset(); - } - - idVec3 gravity = physicsObj.GetGravityNormal(); - - // drop the weapon when landing after a jump / fall - delta = gameLocal.time - landTime; - if ( delta < LAND_DEFLECT_TIME ) { - origin -= gravity * ( landChange*0.25f * delta / LAND_DEFLECT_TIME ); - } else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) { - origin -= gravity * ( landChange*0.25f * (LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta) / LAND_RETURN_TIME ); - } - - // speed sensitive idle drift - // Dram: Changed so that each axis has it's own fracsin. Now they move independantly of each other - scale = xyspeed + 40.0f; - fracsin1 = scale * sin( MS2SEC( gameLocal.time * 0.42 ) ) * 0.006f; - fracsin2 = scale * sin( MS2SEC( gameLocal.time * 1.63 ) ) * 0.01f; - fracsin3 = scale * sin( MS2SEC( gameLocal.time * 2 ) ) * 0.01f; - angles.roll += fracsin1; - angles.yaw += fracsin2; - angles.pitch += fracsin3; - - axis = angles.ToMat3() * viewAxis; -} - -/* -=============== -idPlayer::OffsetThirdPersonView -=============== -*/ -void idPlayer::OffsetThirdPersonView( float angle, float range, float height, bool clip ) { - idVec3 view; - idVec3 focusAngles; - trace_t trace; - idVec3 focusPoint; - float focusDist; - float forwardScale, sideScale; - idVec3 origin; - idAngles angles; - idMat3 axis; - idBounds bounds; - - angles = viewAngles; - GetViewPos( origin, axis ); - - if ( angle ) { - angles.pitch = 0.0f; - } - - if ( angles.pitch > 45.0f ) { - angles.pitch = 45.0f; // don't go too far overhead - } - - focusPoint = origin + angles.ToForward() * THIRD_PERSON_FOCUS_DISTANCE; - focusPoint.z += height; - view = origin; - view.z += 8 + height; - - angles.pitch *= 0.5f; - renderView->viewaxis = angles.ToMat3() * physicsObj.GetGravityAxis(); - - idMath::SinCos( DEG2RAD( angle ), sideScale, forwardScale ); - view -= range * forwardScale * renderView->viewaxis[ 0 ]; - view += range * sideScale * renderView->viewaxis[ 1 ]; - - if ( clip ) { - // trace a ray from the origin to the viewpoint to make sure the view isn't - // in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything - bounds = idBounds( idVec3( -4, -4, -4 ), idVec3( 4, 4, 4 ) ); - gameLocal.clip.TraceBounds( trace, origin, view, bounds, MASK_SOLID, this ); - if ( trace.fraction != 1.0f ) { - view = trace.endpos; - view.z += ( 1.0f - trace.fraction ) * 32.0f; - - // try another trace to this position, because a tunnel may have the ceiling - // close enough that this is poking out - gameLocal.clip.TraceBounds( trace, origin, view, bounds, MASK_SOLID, this ); - view = trace.endpos; - } - } - - // select pitch to look at focus point from vieword - focusPoint -= view; - focusDist = idMath::Sqrt( focusPoint[0] * focusPoint[0] + focusPoint[1] * focusPoint[1] ); - if ( focusDist < 1.0f ) { - focusDist = 1.0f; // should never happen - } - - angles.pitch = - RAD2DEG( atan2( focusPoint.z, focusDist ) ); - angles.yaw -= angle; - - renderView->vieworg = view; - renderView->viewaxis = angles.ToMat3() * physicsObj.GetGravityAxis(); - renderView->viewID = 0; -} - -/* -=============== -idPlayer::GetEyePosition -=============== -*/ -idVec3 idPlayer::GetEyePosition( void ) const { - idVec3 org; - - // use the smoothed origin if spectating another player in multiplayer - if ( gameLocal.isClient && entityNumber != gameLocal.localClientNum ) { - org = smoothedOrigin; - } else { - org = GetPhysics()->GetOrigin(); - } - - /*! - * Lean Mod - * @author sophisticatedZombie (DH) - * Move eye position due to leaning - * angua: need to check whether physics type is correct, dead player uses AF physics - */ - idPhysics* physics = GetPhysics(); - if (physics->IsType(idPhysics_Player::Type)) - { - org += static_cast(physics)->GetViewLeanTranslation(); - } - - // This was in SDK untouched - return org + ( GetPhysics()->GetGravityNormal() * -eyeOffset.z ); -} - -/* -=============== -idPlayer::GetViewPos -=============== -*/ -void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { - idAngles angles; - - // if dead, fix the angle and don't add any kick - if ( health <= 0 ) { - angles.yaw = viewAngles.yaw; - angles.roll = 40; - angles.pitch = -15; - axis = angles.ToMat3(); - origin = GetEyePosition(); - } else { - origin = GetEyePosition() + viewBob; - angles = viewAngles + viewBobAngles + physicsObj.GetViewLeanAngles() + playerView.AngleOffset(); - - axis = angles.ToMat3() * physicsObj.GetGravityAxis(); - - // adjust the origin based on the camera nodal distance (eye distance from neck) - origin += physicsObj.GetGravityNormal() * g_viewNodalZ.GetFloat(); - origin += axis[0] * g_viewNodalX.GetFloat() + axis[2] * g_viewNodalZ.GetFloat(); - } -} - -/* -=============== -idPlayer::CalculateFirstPersonView -=============== -*/ -void idPlayer::CalculateFirstPersonView( void ) -{ - idPhysics* physics = GetPhysics(); - - if ( ( pm_modelView.GetInteger() == 1 ) || ( ( pm_modelView.GetInteger() == 2 ) && ( health <= 0 ) ) ) - { - // Displays the view from the point of view of the "camera" joint in the player model - - idMat3 axis; - idVec3 origin; - idAngles ang = viewBobAngles + playerView.AngleOffset(); - - /*! - * Lean mod: - * @author: sophisticatedZombie - */ - if (physics->IsType(idPhysics_Player::Type)) - { - ang += static_cast(physics)->GetViewLeanAngles(); - } - - ang.yaw += viewAxis[ 0 ].ToYaw(); - - jointHandle_t joint = animator.GetJointHandle( "camera" ); - animator.GetJointTransform( joint, gameLocal.time, origin, axis ); - firstPersonViewOrigin = ( origin + modelOffset ) * ( viewAxis * physicsObj.GetGravityAxis() ) + physicsObj.GetOrigin() + viewBob + physicsObj.GetViewLeanTranslation(); - firstPersonViewAxis = axis * ang.ToMat3() * physicsObj.GetGravityAxis(); - } else - { - // offset for local bobbing and kicks - GetViewPos( firstPersonViewOrigin, firstPersonViewAxis ); -#if 0 - // shakefrom sound stuff only happens in first person - firstPersonViewAxis = firstPersonViewAxis * playerView.ShakeAxis(); -#endif - } - - // Set the listener location (on the other side of a door if door leaning) - if (physics->IsType(idPhysics_Player::Type) && - static_cast(physics)->IsDoorLeaning() && - !gameLocal.inCinematic) - { - SetListenerLoc( m_DoorListenLoc ); - } - else - { - SetListenerLoc( firstPersonViewOrigin ); - } -} - -/* -================== -idPlayer::GetRenderView - -Returns the renderView that was calculated for this tic -================== -*/ -renderView_t *idPlayer::GetRenderView( void ) { - return renderView; -} - -/* -================== -idPlayer::CalculateRenderView - -create the renderView for the current tic -================== -*/ -void idPlayer::CalculateRenderView( void ) { - int i; - float range; - - if ( !renderView ) { - renderView = new renderView_t; - } - memset( renderView, 0, sizeof( *renderView ) ); - - // copy global shader parms - for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { - renderView->shaderParms[ i ] = gameLocal.globalShaderParms[ i ]; - } - renderView->globalMaterial = gameLocal.GetGlobalMaterial(); - renderView->time = gameLocal.time; - - // calculate size of 3D view - renderView->x = 0; - renderView->y = 0; - renderView->width = SCREEN_WIDTH; - renderView->height = SCREEN_HEIGHT; - renderView->viewID = 0; - - // check if we should be drawing from a camera's POV - if ( !noclip && (gameLocal.GetCamera() || privateCameraView) ) { - // get origin, axis, and fov - if ( privateCameraView ) { - privateCameraView->GetViewParms( renderView ); - } else { - gameLocal.GetCamera()->GetViewParms( renderView ); - } - } else { - if ( g_stopTime.GetBool() ) { - renderView->vieworg = firstPersonViewOrigin; - renderView->viewaxis = firstPersonViewAxis; - - if ( !pm_thirdPerson.GetBool() ) { - // set the viewID to the clientNum + 1, so we can suppress the right player bodies and - // allow the right player view weapons - renderView->viewID = entityNumber + 1; - } - } else if ( pm_thirdPerson.GetBool() ) { - OffsetThirdPersonView( pm_thirdPersonAngle.GetFloat(), pm_thirdPersonRange.GetFloat(), pm_thirdPersonHeight.GetFloat(), pm_thirdPersonClip.GetBool() ); - } else if ( pm_thirdPersonDeath.GetBool() ) { - range = gameLocal.time < minRespawnTime ? ( gameLocal.time + RAGDOLL_DEATH_TIME - minRespawnTime ) * ( 120.0f / RAGDOLL_DEATH_TIME ) : 120.0f; - OffsetThirdPersonView( 0.0f, 20.0f + range, 0.0f, false ); - } else { - renderView->vieworg = firstPersonViewOrigin; - renderView->viewaxis = firstPersonViewAxis; - - // set the viewID to the clientNum + 1, so we can suppress the right player bodies and - // allow the right player view weapons - renderView->viewID = entityNumber + 1; - } - - // field of view - gameLocal.CalcFov( CalcFov( true ), renderView->fov_x, renderView->fov_y ); - } - - if ( renderView->fov_y == 0 ) { - common->Error( "renderView->fov_y == 0" ); - } - - if ( g_showviewpos.GetBool() ) { - gameLocal.Printf( "%s : %s\n", renderView->vieworg.ToString(), renderView->viewaxis.ToAngles().ToString() ); - } -} - -/* -============= -idPlayer::AddProjectilesFired -============= -*/ -void idPlayer::AddProjectilesFired( int count ) { - numProjectilesFired += count; -} - -/* -============= -idPlayer::AddProjectileHites -============= -*/ -void idPlayer::AddProjectileHits( int count ) { - numProjectileHits += count; -} - -/* -============= -idPlayer::SetLastHitTime -============= -*/ -void idPlayer::SetLastHitTime( int time ) { - idPlayer *aimed = NULL; - - if ( time && lastHitTime != time ) { - lastHitToggle ^= 1; - } - lastHitTime = time; - if ( !time ) { - // level start and inits - return; - } - if ( gameLocal.isMultiplayer && ( time - lastSndHitTime ) > 10 ) { - lastSndHitTime = time; - StartSound( "snd_hit_feedback", SND_CHANNEL_ANY, SSF_PRIVATE_SOUND, false, NULL ); - } - if ( cursor ) { - cursor->HandleNamedEvent( "hitTime" ); - } - if ( hud ) { - if ( MPAim != -1 ) { - if ( gameLocal.entities[ MPAim ] && gameLocal.entities[ MPAim ]->IsType( idPlayer::Type ) ) { - aimed = static_cast< idPlayer * >( gameLocal.entities[ MPAim ] ); - } - assert( aimed ); - // full highlight, no fade till loosing aim - hud->SetStateString( "aim_text", gameLocal.userInfo[ MPAim ].GetString( "ui_name" ) ); - if ( aimed ) { - hud->SetStateFloat( "aim_color", aimed->colorBarIndex ); - } - hud->HandleNamedEvent( "aim_flash" ); - MPAimHighlight = true; - MPAimFadeTime = 0; - } else if ( lastMPAim != -1 ) { - if ( gameLocal.entities[ lastMPAim ] && gameLocal.entities[ lastMPAim ]->IsType( idPlayer::Type ) ) { - aimed = static_cast< idPlayer * >( gameLocal.entities[ lastMPAim ] ); - } - assert( aimed ); - // start fading right away - hud->SetStateString( "aim_text", gameLocal.userInfo[ lastMPAim ].GetString( "ui_name" ) ); - if ( aimed ) { - hud->SetStateFloat( "aim_color", aimed->colorBarIndex ); - } - hud->HandleNamedEvent( "aim_flash" ); - hud->HandleNamedEvent( "aim_fade" ); - MPAimHighlight = false; - MPAimFadeTime = gameLocal.realClientTime; - } - } -} - -/* -============= -idPlayer::SetInfluenceLevel -============= -*/ -void idPlayer::SetInfluenceLevel( int level ) { - if ( level != influenceActive ) { - if ( level ) { - for ( idEntity *ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->IsType( idProjectile::Type ) ) { - // remove all projectiles - ent->PostEventMS( &EV_Remove, 0 ); - } - } - if ( weaponEnabled && weapon.GetEntity() ) { - weapon.GetEntity()->EnterCinematic(); - } - } else { - physicsObj.SetLinearVelocity( vec3_origin ); - if ( weaponEnabled && weapon.GetEntity() ) { - weapon.GetEntity()->ExitCinematic(); - } - } - influenceActive = level; - } -} - -/* -============= -idPlayer::SetInfluenceView -============= -*/ -void idPlayer::SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent ) { - influenceMaterial = NULL; - influenceEntity = NULL; - influenceSkin = NULL; - if ( mtr && *mtr ) { - influenceMaterial = declManager->FindMaterial( mtr ); - } - if ( skinname && *skinname ) { - influenceSkin = declManager->FindSkin( skinname ); - if ( head.GetEntity() ) { - head.GetEntity()->GetRenderEntity()->shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - } - UpdateVisuals(); - } - influenceRadius = radius; - if ( radius > 0.0f ) { - influenceEntity = ent; - } -} - -/* -============= -idPlayer::SetInfluenceFov -============= -*/ -void idPlayer::SetInfluenceFov( float fov ) { - influenceFov = fov; -} - -/* -================ -idPlayer::OnLadder -================ -*/ -bool idPlayer::OnLadder( void ) const { - return physicsObj.OnLadder(); -} - -CMultiStateMover* idPlayer::OnElevator(bool mustBeMoving) const -{ - idEntity* ent = physicsObj.GetGroundEntity(); - - // Return false if ground entity is not a mover - if (ent == NULL || !ent->IsType(CMultiStateMover::Type)) return NULL; - - CMultiStateMover* mover = static_cast(ent); - - if (mustBeMoving) - { - return (!mover->IsAtRest()) ? mover : NULL; - } - return mover; -} - -/* -================== -idPlayer::Event_GetButtons -================== -*/ -void idPlayer::Event_GetButtons( void ) { - idThread::ReturnInt( usercmd.buttons ); -} - -/* -================== -idPlayer::Event_GetMove -================== -*/ -void idPlayer::Event_GetMove( void ) { - idVec3 move( usercmd.forwardmove, usercmd.rightmove, usercmd.upmove ); - idThread::ReturnVector( move ); -} - -/* -================ -idPlayer::Event_GetViewAngles -================ -*/ -void idPlayer::Event_GetViewAngles( void ) { - idThread::ReturnVector( idVec3( viewAngles[0], viewAngles[1], viewAngles[2] ) ); -} - -/* -================== -idPlayer::Event_StopFxFov -================== -*/ -void idPlayer::Event_StopFxFov( void ) { - fxFov = false; -} - -/* -================== -idPlayer::StartFxFov -================== -*/ -void idPlayer::StartFxFov( float duration ) { - fxFov = true; - PostEventSec( &EV_Player_StopFxFov, duration ); -} - -/* -================== -idPlayer::Event_EnableWeapon -================== -*/ -void idPlayer::Event_EnableWeapon( void ) { - hiddenWeapon = gameLocal.world->spawnArgs.GetBool( "no_Weapons" ); - weaponEnabled = true; - if ( weapon.GetEntity() ) { - weapon.GetEntity()->ExitCinematic(); - } -} - -/* -================== -idPlayer::Event_DisableWeapon -================== -*/ -void idPlayer::Event_DisableWeapon( void ) { - hiddenWeapon = gameLocal.world->spawnArgs.GetBool( "no_Weapons" ); - weaponEnabled = false; - if ( weapon.GetEntity() ) { - weapon.GetEntity()->EnterCinematic(); - } -} - -/* -================== -idPlayer::Event_GetCurrentWeapon -================== -*/ -void idPlayer::Event_GetCurrentWeapon( void ) { - const char *weapon; - - if ( currentWeapon >= 0 ) { - weapon = spawnArgs.GetString( va( "def_weapon%d", currentWeapon ) ); - idThread::ReturnString( weapon ); - } else { - idThread::ReturnString( "" ); - } -} - -/* -================== -idPlayer::Event_GetPreviousWeapon -================== -*/ -void idPlayer::Event_GetPreviousWeapon( void ) { - const char *weapon; - - if ( previousWeapon >= 0 ) { - int pw = ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) ? 0 : previousWeapon; - weapon = spawnArgs.GetString( va( "def_weapon%d", pw) ); - idThread::ReturnString( weapon ); - } else { - idThread::ReturnString( spawnArgs.GetString( "def_weapon0" ) ); - } -} - -/* -================== -idPlayer::Event_SelectWeapon -================== -*/ -void idPlayer::Event_SelectWeapon( const char *weaponName ) -{ - if ( gameLocal.isClient ) { - gameLocal.Warning( "Cannot switch weapons from script in multiplayer" ); - return; - } - - if ( hiddenWeapon && gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) { - idealWeapon = weapon_fists; - weapon.GetEntity()->HideWeapon(); - return; - } - - int weaponNum = SlotForWeapon(weaponName); - - if (weaponNum != -1) - { - // Found, select it - SelectWeapon(weaponNum, false); - } -} - -/* -================== -idPlayer::Event_GetWeaponEntity -================== -*/ -void idPlayer::Event_GetWeaponEntity( void ) { - idThread::ReturnEntity( weapon.GetEntity() ); -} - -/* -================== -idPlayer::TeleportDeath -================== -*/ -void idPlayer::TeleportDeath( int killer ) { - teleportKiller = killer; -} - -/* -================== -idPlayer::Event_ExitTeleporter -================== -*/ -void idPlayer::Event_ExitTeleporter( void ) { - idEntity *exitEnt; - float pushVel; - - // verify and setup - exitEnt = teleportEntity.GetEntity(); - if ( !exitEnt ) { - common->DPrintf( "Event_ExitTeleporter player %d while not being teleported\n", entityNumber ); - return; - } - - pushVel = exitEnt->spawnArgs.GetFloat( "push", "300" ); - - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_EXIT_TELEPORTER, NULL, false, -1 ); - } - - SetPrivateCameraView( NULL ); - // setup origin and push according to the exit target - SetOrigin( exitEnt->GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - SetViewAngles( exitEnt->GetPhysics()->GetAxis().ToAngles() ); - physicsObj.SetLinearVelocity( exitEnt->GetPhysics()->GetAxis()[ 0 ] * pushVel ); - physicsObj.ClearPushedVelocity(); - // teleport fx - playerView.Flash( colorWhite, 120 ); - - // clear the ik heights so model doesn't appear in the wrong place - walkIK.EnableAll(); - - UpdateVisuals(); - - StartSound( "snd_teleport_exit", SND_CHANNEL_ANY, 0, false, NULL ); - - if ( teleportKiller != -1 ) { - // we got killed while being teleported - Damage( gameLocal.entities[ teleportKiller ], gameLocal.entities[ teleportKiller ], vec3_origin, "damage_telefrag", 1.0f, INVALID_JOINT ); - teleportKiller = -1; - } else { - // kill anything that would have waited at teleport exit - gameLocal.KillBox( this ); - } - teleportEntity = NULL; -} - -/* -================ -idPlayer::ClientPredictionThink -================ -*/ -void idPlayer::ClientPredictionThink( void ) { - renderEntity_t *headRenderEnt; - - oldFlags = usercmd.flags; - oldButtons = usercmd.buttons; - - usercmd = gameLocal.usercmds[ entityNumber ]; - - if ( entityNumber != gameLocal.localClientNum ) - { - // ignore attack button of other clients. that's no good for predictions - - usercmd.buttons &= ~BUTTON_ATTACK; - // tdm: Also ignore block button - usercmd.buttons &= ~BUTTON_ZOOM; - } - - - - buttonMask &= usercmd.buttons; - usercmd.buttons &= ~buttonMask; - - // clear the ik before we do anything else so the skeleton doesn't get updated twice - walkIK.ClearJointMods(); - - if ( gameLocal.isNewFrame ) { - if ( ( usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) { - PerformImpulse( usercmd.impulse ); - } - } - - scoreBoardOpen = ( ( usercmd.buttons & BUTTON_SCORES ) != 0 || forceScoreBoard ); - - AdjustSpeed(); - - UpdateViewAngles(); - - // update the smoothed view angles - if ( gameLocal.framenum >= smoothedFrame && entityNumber != gameLocal.localClientNum ) { - idAngles anglesDiff = viewAngles - smoothedAngles; - anglesDiff.Normalize180(); - if ( idMath::Fabs( anglesDiff.yaw ) < 90.0f && idMath::Fabs( anglesDiff.pitch ) < 90.0f ) { - // smoothen by pushing back to the previous angles - viewAngles -= gameLocal.clientSmoothing * anglesDiff; - viewAngles.Normalize180(); - } - smoothedAngles = viewAngles; - } - smoothedOriginUpdated = false; - - if ( !af.IsActive() ) { - AdjustBodyAngles(); - } - - if ( !isLagged ) { - // don't allow client to move when lagged - Move(); - } - -#if 0 - // update GUIs, Items, and character interactions - UpdateFocus(); -#endif - - // service animations - if ( !spectating && !af.IsActive() ) { - m_ButtonStateTracker.Update(); - UpdateConditions(); - UpdateAnimState(); - CheckBlink(); - } - - // clear out our pain flag so we can tell if we recieve any damage between now and the next time we think - AI_PAIN = false; - - // calculate the exact bobbed view position, which is used to - // position the view weapon, among other things - CalculateFirstPersonView(); - - // this may use firstPersonView, or a thirdPerson / camera view - CalculateRenderView(); - - if ( !gameLocal.inCinematic && weapon.GetEntity() && ( health > 0 ) && !( gameLocal.isMultiplayer && spectating ) ) { - UpdateWeapon(); - } - - UpdateHUD(); - - if ( gameLocal.isNewFrame ) { - UpdatePowerUps(); - } - - UpdateDeathSkin( false ); - - if ( head.GetEntity() ) { - headRenderEnt = head.GetEntity()->GetRenderEntity(); - } else { - headRenderEnt = NULL; - } - - if ( headRenderEnt ) { - if ( influenceSkin ) { - headRenderEnt->customSkin = influenceSkin; - } else { - headRenderEnt->customSkin = NULL; - } - } - - if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() ) { - renderEntity.suppressShadowInViewID = 0; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInViewID = 0; - } - } else { - renderEntity.suppressShadowInViewID = entityNumber+1; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInViewID = entityNumber+1; - } - } - // never cast shadows from our first-person muzzle flashes - renderEntity.suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; - if ( headRenderEnt ) { - headRenderEnt->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber; - } - - if ( !gameLocal.inCinematic ) { - UpdateAnimation(); - } - - if ( gameLocal.isMultiplayer ) { - DrawPlayerIcons(); - } - - Present(); - - UpdateDamageEffects(); - - LinkCombat(); - - if ( gameLocal.isNewFrame && entityNumber == gameLocal.localClientNum ) { - playerView.CalculateShake(); - } - - // determine if portal sky is in pvs - - pvsHandle_t clientPVS = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() ); - - gameLocal.portalSkyActive = gameLocal.pvs.CheckAreasForPortalSky( clientPVS, GetPhysics()->GetOrigin() ); - - gameLocal.pvs.FreeCurrentPVS( clientPVS ); - -} - -/* -================ -idPlayer::GetPhysicsToVisualTransform -================ -*/ -bool idPlayer::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) { - if ( af.IsActive() ) { - af.GetPhysicsToVisualTransform( origin, axis ); - return true; - } - - // smoothen the rendered origin and angles of other clients - if ( gameLocal.isClient && gameLocal.framenum >= smoothedFrame && ( entityNumber != gameLocal.localClientNum || selfSmooth ) ) { - - // render origin and axis - idMat3 renderAxis = viewAxis * GetPhysics()->GetAxis(); - idVec3 renderOrigin = GetPhysics()->GetOrigin() + modelOffset * renderAxis; - - // update the smoothed origin - if ( !smoothedOriginUpdated ) { - idVec2 originDiff = renderOrigin.ToVec2() - smoothedOrigin.ToVec2(); - if ( originDiff.LengthSqr() < Square( 100.0f ) ) { - // smoothen by pushing back to the previous position - if ( selfSmooth ) { - - assert( entityNumber == gameLocal.localClientNum ); - - renderOrigin.ToVec2() -= net_clientSelfSmoothing.GetFloat() * originDiff; - - } else { - - renderOrigin.ToVec2() -= gameLocal.clientSmoothing * originDiff; - } - } - smoothedOrigin = renderOrigin; - - smoothedFrame = gameLocal.framenum; - smoothedOriginUpdated = true; - } - - axis = idAngles( 0.0f, smoothedAngles.yaw, 0.0f ).ToMat3(); - origin = ( smoothedOrigin - GetPhysics()->GetOrigin() ) * axis.Transpose(); - - } else { - - axis = viewAxis; - origin = modelOffset; - } - return true; -} - -/* -================ -idPlayer::GetPhysicsToSoundTransform -================ -*/ -bool idPlayer::GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ) { - idCamera *camera; - - if ( privateCameraView ) { - camera = privateCameraView; - } else { - camera = gameLocal.GetCamera(); - } - - if ( camera ) { - renderView_t view; - - memset( &view, 0, sizeof( view ) ); - camera->GetViewParms( &view ); - origin = view.vieworg; - axis = view.viewaxis; - return true; - } else { - return idActor::GetPhysicsToSoundTransform( origin, axis ); - } -} - -/* -================ -idPlayer::WriteToSnapshot -================ -*/ -void idPlayer::WriteToSnapshot( idBitMsgDelta &msg ) const { - physicsObj.WriteToSnapshot( msg ); - WriteBindToSnapshot( msg ); - msg.WriteDeltaFloat( 0.0f, deltaViewAngles[0] ); - msg.WriteDeltaFloat( 0.0f, deltaViewAngles[1] ); - msg.WriteDeltaFloat( 0.0f, deltaViewAngles[2] ); - msg.WriteShort( health ); - msg.WriteBits( gameLocal.ServerRemapDecl( -1, DECL_ENTITYDEF, lastDamageDef ), gameLocal.entityDefBits ); - msg.WriteDir( lastDamageDir, 9 ); - msg.WriteShort( lastDamageLocation ); - msg.WriteBits( idealWeapon, idMath::BitsForInteger( 256 ) ); - msg.WriteBits( weapon.GetSpawnId(), 32 ); - msg.WriteBits( spectator, idMath::BitsForInteger( MAX_CLIENTS ) ); - msg.WriteBits( lastHitToggle, 1 ); - msg.WriteBits( weaponGone, 1 ); - msg.WriteBits( isLagged, 1 ); - msg.WriteBits( isChatting, 1 ); -} - -/* -================ -idPlayer::ReadFromSnapshot -================ -*/ -void idPlayer::ReadFromSnapshot( const idBitMsgDelta &msg ) { - int oldHealth, newIdealWeapon, weaponSpawnId; - bool newHitToggle, stateHitch; - - if ( snapshotSequence - lastSnapshotSequence > 1 ) { - stateHitch = true; - } else { - stateHitch = false; - } - lastSnapshotSequence = snapshotSequence; - - oldHealth = health; - - physicsObj.ReadFromSnapshot( msg ); - ReadBindFromSnapshot( msg ); - deltaViewAngles[0] = msg.ReadDeltaFloat( 0.0f ); - deltaViewAngles[1] = msg.ReadDeltaFloat( 0.0f ); - deltaViewAngles[2] = msg.ReadDeltaFloat( 0.0f ); - health = msg.ReadShort(); - lastDamageDef = gameLocal.ClientRemapDecl( DECL_ENTITYDEF, msg.ReadBits( gameLocal.entityDefBits ) ); - lastDamageDir = msg.ReadDir( 9 ); - lastDamageLocation = msg.ReadShort(); - newIdealWeapon = msg.ReadBits( idMath::BitsForInteger( 256 ) ); - weaponSpawnId = msg.ReadBits( 32 ); - spectator = msg.ReadBits( idMath::BitsForInteger( MAX_CLIENTS ) ); - newHitToggle = msg.ReadBits( 1 ) != 0; - weaponGone = msg.ReadBits( 1 ) != 0; - isLagged = msg.ReadBits( 1 ) != 0; - isChatting = msg.ReadBits( 1 ) != 0; - - // no msg reading below this - - if ( weapon.SetSpawnId( weaponSpawnId ) ) { - if ( weapon.GetEntity() ) { - // maintain ownership locally - weapon.GetEntity()->SetOwner( this ); - } - currentWeapon = -1; - } - - if ( oldHealth > 0 && health <= 0 ) { - if ( stateHitch ) { - // so we just hide and don't show a death skin - UpdateDeathSkin( true ); - } - // die - AI_DEAD = true; - SetAnimState( ANIMCHANNEL_LEGS, "Legs_Death", 4 ); - SetAnimState( ANIMCHANNEL_TORSO, "Torso_Death", 4 ); - SetWaitState( "" ); - animator.ClearAllJoints(); - if ( entityNumber == gameLocal.localClientNum ) { - playerView.Fade( colorBlack, 12000 ); - } - StartRagdoll(); - physicsObj.SetMovementType( PM_DEAD ); - if ( !stateHitch ) { - StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); - } - if ( weapon.GetEntity() ) { - weapon.GetEntity()->OwnerDied(); - } - } else if ( oldHealth <= 0 && health > 0 ) { - // respawn - Init(); - StopRagdoll(); - SetPhysics( &physicsObj ); - physicsObj.EnableClip(); - SetCombatContents( true ); - } else if ( health < oldHealth && health > 0 ) { - if ( stateHitch ) { - lastDmgTime = gameLocal.time; - } else { - // damage feedback - const idDeclEntityDef *def = static_cast( declManager->DeclByIndex( DECL_ENTITYDEF, lastDamageDef, false ) ); - if ( def ) { - playerView.DamageImpulse( lastDamageDir * viewAxis.Transpose(), &def->dict ); - AI_PAIN = Pain( NULL, NULL, oldHealth - health, lastDamageDir, lastDamageLocation, &def->dict ); - lastDmgTime = gameLocal.time; - } else { - common->Warning( "NET: no damage def for damage feedback '%d'\n", lastDamageDef ); - } - } - } else if ( health > oldHealth && !stateHitch ) { - // just pulse, for any health raise - healthPulse = true; - } - - // If the player is alive, restore proper physics object - - if ( health > 0 && IsActiveAF() ) { - - StopRagdoll(); - - SetPhysics( &physicsObj ); - - physicsObj.EnableClip(); - - SetCombatContents( true ); - - } - - - - if ( idealWeapon != newIdealWeapon ) { - if ( stateHitch ) { - weaponCatchup = true; - } - idealWeapon = newIdealWeapon; - UpdateHudWeapon(); - } - - if ( lastHitToggle != newHitToggle ) { - SetLastHitTime( gameLocal.realClientTime ); - } - - if ( msg.HasChanged() ) { - UpdateVisuals(); - } -} - -/* -================ -idPlayer::WritePlayerStateToSnapshot -================ -*/ -void idPlayer::WritePlayerStateToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteByte( bobCycle ); - msg.WriteLong( stepUpTime ); - msg.WriteFloat( stepUpDelta ); -} - -/* -================ -idPlayer::ReadPlayerStateFromSnapshot -================ -*/ -void idPlayer::ReadPlayerStateFromSnapshot( const idBitMsgDelta &msg ) { - bobCycle = msg.ReadByte(); - stepUpTime = msg.ReadLong(); - stepUpDelta = msg.ReadFloat(); -} - -/* -================ -idPlayer::ServerReceiveEvent -================ -*/ -bool idPlayer::ServerReceiveEvent( int event, int time, const idBitMsg &msg ) { - - if ( idEntity::ServerReceiveEvent( event, time, msg ) ) { - return true; - } - - // client->server events - switch( event ) { - case EVENT_IMPULSE: { - PerformImpulse( msg.ReadBits( 6 ) ); - return true; - } - default: { - return false; - } - } -} - -/* -================ -idPlayer::ClientReceiveEvent -================ -*/ -bool idPlayer::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - switch ( event ) { - case EVENT_EXIT_TELEPORTER: - Event_ExitTeleporter(); - return true; - case EVENT_ABORT_TELEPORTER: - SetPrivateCameraView( NULL ); - return true; - case EVENT_POWERUP: { - // greebo: No EVENT_POWERUP handling at the moment - return true; - } - case EVENT_SPECTATE: { - bool spectate = ( msg.ReadBits( 1 ) != 0 ); - Spectate( spectate ); - return true; - } - case EVENT_ADD_DAMAGE_EFFECT: { - if ( spectating ) { - // if we're spectating, ignore - // happens if the event and the spectate change are written on the server during the same frame (fraglimit) - return true; - } - return idActor::ClientReceiveEvent( event, time, msg ); - } - default: { - return idActor::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -================ -idPlayer::Hide -================ -*/ -void idPlayer::Hide( void ) { - idWeapon *weap; - - idActor::Hide(); - weap = weapon.GetEntity(); - if ( weap ) { - weap->HideWorldModel(); - } -} - -/* -================ -idPlayer::Show -================ -*/ -void idPlayer::Show( void ) { - idWeapon *weap; - - idActor::Show(); - weap = weapon.GetEntity(); - if ( weap ) { - weap->ShowWorldModel(); - } -} - -/* -=============== -idPlayer::SetSpectateOrigin -=============== -*/ -void idPlayer::SetSpectateOrigin( void ) { - idVec3 neworig; - - neworig = GetPhysics()->GetOrigin(); - neworig[ 2 ] += EyeHeight(); - neworig[ 2 ] += 25; - SetOrigin( neworig ); -} - -/* -=============== -idPlayer::RemoveWeapon -=============== -*/ -void idPlayer::RemoveWeapon( const char *weap ) { - if ( weap && *weap ) { - // greebo: Not yet implemented for TDM inventory - //inventory.Drop( spawnArgs, spawnArgs.GetString( weap ), -1 ); - } -} - -/* -=============== -idPlayer::CanShowWeaponViewmodel -=============== -*/ -bool idPlayer::CanShowWeaponViewmodel( void ) const { - return showWeaponViewModel; -} - -void idPlayer::UpdateWeaponEncumbrance() -{ - if (m_WeaponCursor != NULL) // grayman #2773 - { - // Get the currently selected weapon - CInventoryItemPtr weapon = m_WeaponCursor->GetCurrentItem(); - - if (weapon != NULL) - { - SetHinderance("weapon", weapon->GetMovementModifier(), 1.0f); - } - } -} - -/* -=============== -idPlayer::Event_Gibbed -=============== -*/ -void idPlayer::Event_Gibbed( void ) { - // do nothing -} - -/* -================== -idPlayer::Event_GetIdealWeapon -================== -*/ -void idPlayer::Event_GetIdealWeapon( void ) { - const char *weapon; - - if ( idealWeapon >= 0 ) { - weapon = spawnArgs.GetString( va( "def_weapon%d", idealWeapon ) ); - idThread::ReturnString( weapon ); - } else { - idThread::ReturnString( "" ); - } -} - -/* -=============== -idPlayer::UpdatePlayerIcons -=============== -*/ -void idPlayer::UpdatePlayerIcons( void ) { - int time = networkSystem->ServerGetClientTimeSinceLastPacket( entityNumber ); - if ( time > cvarSystem->GetCVarInteger( "net_clientMaxPrediction" ) ) { - isLagged = true; - } else { - isLagged = false; - } - // TODO: chatting, PDA, etc? -} - -/* -=============== -idPlayer::DrawPlayerIcons -=============== -*/ -void idPlayer::DrawPlayerIcons( void ) { - if ( !NeedsIcon() ) { - playerIcon.FreeIcon(); - return; - } - playerIcon.Draw( this, headJoint ); -} - -/* -=============== -idPlayer::HidePlayerIcons -=============== -*/ -void idPlayer::HidePlayerIcons( void ) { - playerIcon.FreeIcon(); -} - -/* -=============== -idPlayer::NeedsIcon -============== -*/ -bool idPlayer::NeedsIcon( void ) { - // local clients don't render their own icons... they're only info for other clients - - return entityNumber != gameLocal.localClientNum && ( isLagged || isChatting ); -} - -int idPlayer::ProcessLightgem(bool processing) -{ - float fValue = m_fColVal; - - int n = cv_lg_interleave.GetInteger(); - - // Skip every nth frame according to the value set in - if (processing && !cv_lg_weak.GetBool() && n > 0) - { - m_LightgemInterleave++; - - if (m_LightgemInterleave >= n) - { - m_LightgemInterleave = 0; - - fValue = gameLocal.CalcLightgem(this); - -// if( cv_interaction_vfp_type.GetBool() ) // If HDR is enabled then make sure that we decode the compressed value and tone-map it. J.C.Denton -// { -// //Decode -// fValue = fValue /( 1 - fValue ); -// -// // Tone-map -// fValue *= ((1.0f / Max(cv_lg_maxColorIntensity.GetFloat(), 0.0001f )) * fValue + 1.0); -// fValue /= (fValue + 1); -// -// } - } - } - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Averaged colorvalue total: %f\r", fValue); - - fValue += cv_lg_adjust.GetFloat(); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Adjustment %f\r", cv_lg_adjust.GetFloat()); - - // Tels: #2324 Water should decrease visibility - // Subtract the adjustment value from the water body we are in so we can - // have clear water, murky water etc. - if (physicsObj.GetWaterLevel() >= WATERLEVEL_HEAD) - { - float murkiness = physicsObj.GetWaterMurkiness(); - fValue -= murkiness; - // gameLocal.Printf( "Water murkiness %0.2f, final value: %0.2f\n", murkiness, value); - } - - m_fColVal = fValue; - m_LightgemValue = int(DARKMOD_LG_MAX * fValue); - - // Give the inventory items a chance to adjust the lightgem (fire arrow, crouching) - m_LightgemValue = GetLightgemModifier(m_LightgemValue); - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("After player adjustment %d\r", m_LightgemValue); - - m_LightgemValue = idMath::ClampInt(DARKMOD_LG_MIN, DARKMOD_LG_MAX, m_LightgemValue); - - return m_LightgemValue; -} - -void idPlayer::CalculateWeakLightgem() -{ - double fx, fy; - idLight *helper; - trace_t trace; - int h = -1; - bool bMinOneLight = false, bStump; - - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("[%s]\r", __FUNCTION__); - - double fLightgemVal = 0; - int n = m_LightList.Num(); - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%u entities found within lightradius\r", n); - idVec3 vStart(GetEyePosition()); - idVec3 vPlayerPos(GetPhysics()->GetOrigin()); - idVec3 vPlayerSeg[LSG_COUNT]; - idVec3 vLightCone[ELC_COUNT]; - idVec3 vResult[2]; - EIntersection inter; - - vPlayerSeg[LSG_ORIGIN] = vPlayerPos; - vPlayerSeg[LSG_DIRECTION] = vStart - vPlayerPos; - - for (int i = 0; i < n; i++) - { - idLight* light = m_LightList[i]; - idVec3 vLight = light->GetPhysics()->GetOrigin(); - - idVec3 vPlayer = vPlayerPos; - vPlayer.z = vLight.z; - - idVec3 vDifference = vPlayer - vLight; - double distance = vDifference.LengthFast(); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Ligth: [%s] %i px: %f py: %f pz: %f - lx: %f ly: %f lz: %f Distance: %f\r", - light->name.c_str(), i, vPlayer.x, vPlayer.y, vPlayer.z, vLight.x, vLight.y, vLight.z, distance); - - // Fast and cheap test to see if the player could be in the area of the light. - // Well, it is not exactly cheap, but it is the cheapest test that we can do at this point. :) - if (distance > light->m_MaxLightRadius) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%s is outside distance: %f/%f\r", light->name.c_str(), light->m_MaxLightRadius, distance); - if(h == -1) - h = i; - continue; - } - - if (light->IsPointlight()) - { - light->GetLightCone(vLightCone[ELL_ORIGIN], vLightCone[ELA_AXIS], vLightCone[ELA_CENTER]); - inter = IntersectLineEllipsoid(vPlayerSeg, vLightCone, vResult); - - // If this is a centerlight we have to move the origin from the original origin to where the - // center of the light is supposed to be. - // Centerlight means that the center of the ellipsoid is not the same as the origin. It has to - // be adjusted because if it casts shadows we have to trace to it, and in this case the light - // might be inside geometry and would be reported as not being visible even though it casts - // a visible light outside the geometry it is embedded. If it is not a centerlight and has - // cast shadows enabled, it wouldn't cast any light at all in such a case because it would - // be blocked by the geometry. - vLight = vLightCone[ELL_ORIGIN] + vLightCone[ELA_CENTER]; - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("IntersectLineEllipsoid returned %u\r", inter); - } - else - { - bStump = false; - light->GetLightCone(vLightCone[ELC_ORIGIN], vLightCone[ELA_TARGET], vLightCone[ELA_RIGHT], vLightCone[ELA_UP], vLightCone[ELA_START], vLightCone[ELA_END]); - inter = IntersectLineCone(vPlayerSeg, vLightCone, vResult, bStump); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("IntersectLineCone returned %u\r", inter); - } - - // The line intersection can only return three states. Either the line is passing - // through the lightcone in which case we will get two intersection points, the line - // is not passing through which means that the player is fully outside, or the line - // is touching the cone in exactly one point. The last case is not really helpfull in - // our case and doesn't make a difference for the gameplay so we simply ignore it and - // consider only cases where the player is at least partially inside the cone. - if (inter != INTERSECT_FULL) - continue; - - if (light->CastsShadow()) - { - gameLocal.clip.TracePoint(trace, vStart, vLight, CONTENTS_SOLID|CONTENTS_OPAQUE|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP - |CONTENTS_MOVEABLECLIP|CONTENTS_BODY|CONTENTS_CORPSE|CONTENTS_RENDERMODEL - |CONTENTS_FLASHLIGHT_TRIGGER, this); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("TraceFraction: %f\r", trace.fraction); - if(trace.fraction < 1.0f) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Light [%s] can not be seen\r", light->name.c_str()); - continue; - } - } - - int l = (vResult[0].z < vResult[1].z) ? 0 : 1; - - if (vResult[l].z < vPlayerPos.z) - { - fx = vPlayerPos.x; - fy = vPlayerPos.y; - } - else - { - fx = vResult[l].x; - fy = vResult[l].y; - } - - bMinOneLight = true; - - fLightgemVal += light->GetDistanceColor(distance, vLightCone[ELL_ORIGIN].x - fx, vLightCone[ELL_ORIGIN].y - fy); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("%s in x/y: %f/%f Distance: %f/%f Brightness: %f\r", - light->name.c_str(), fx, fy, fLightgemVal, distance, light->m_MaxLightRadius); - - // Exchange the position of these lights, so that nearer lights are more - // at the beginning of the list. You may not use the arrayentry from this point on now. - // This sorting is not exactly good, but it is very cheap and we don't want to waste - // time to sort an everchanging array. - if (h != -1) - { - helper = m_LightList[h]; - m_LightList[h] = light; - m_LightList[i] = helper; - h = -1; - } - - // No need to do further calculations when we are fully lit. 0 < n < 1 - if (fLightgemVal >= 1.0) - { - fLightgemVal = 1.0; - break; - } - } - - m_LightgemValue = static_cast(DARKMOD_LG_MAX * fLightgemVal); - - // Clamp the result to [DARKMOD_LG_MIN .. DARKMOD_LG_MAX] - m_LightgemValue = idMath::ClampInt(DARKMOD_LG_MIN, DARKMOD_LG_MAX, m_LightgemValue); - - // if the player is in a lit area and the lightgem would be totally dark we set it to at least - // one step higher. - if (bMinOneLight && m_LightgemValue <= DARKMOD_LG_MIN) - { - m_LightgemValue++; - } -} - -int idPlayer::AddLight(idLight *light) -{ - if (light != NULL) - { - m_LightList.Append(light); - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("%08lX [%s] %lu added to LightList\r", light, light->name.c_str(), m_LightList.Num()); - } - - return m_LightList.Num(); -} - -int idPlayer::RemoveLight(idLight *light) -{ - int found = m_LightList.FindIndex(light); - - if (found != -1) - { - // Light found, remove it - m_LightList.RemoveIndex(found); - DM_LOG(LC_FUNCTION, LT_DEBUG)LOGSTRING("%08lX [%s] %lu removed from LightList\r", light, light->name.c_str(), m_LightList.Num()); - } - - return m_LightList.Num(); -} - -void idPlayer::UpdateMoveVolumes( void ) -{ - // copy step volumes from current cvar value - m_stepvol_walk = cv_pm_stepvol_walk.GetFloat(); - m_stepvol_run = cv_pm_stepvol_run.GetFloat(); - m_stepvol_creep = cv_pm_stepvol_creep.GetFloat(); - - m_stepvol_crouch_walk = cv_pm_stepvol_crouch_walk.GetFloat(); - m_stepvol_crouch_creep = cv_pm_stepvol_crouch_creep.GetFloat(); - m_stepvol_crouch_run = cv_pm_stepvol_crouch_run.GetFloat(); -} - -/* -===================== -idPlayer::GetMovementVolMod -===================== -*/ - -float idPlayer::GetMovementVolMod( void ) -{ - float returnval = 0.0f; - - bool isCrouched = AI_CROUCH != 0; - - // figure out which of the 6 possible cases we have: - // NOTE: running always has priority over creeping - if( AI_RUN ) - { - if (physicsObj.HasRunningVelocity()) - { - returnval = (isCrouched) ? m_stepvol_crouch_run : m_stepvol_run; - } - else - { - returnval = (isCrouched) ? m_stepvol_crouch_walk : m_stepvol_walk; - } - } - else if( AI_CREEP ) - { - returnval = (isCrouched) ? m_stepvol_crouch_creep : m_stepvol_creep; - } - // else it is not: AI_RUN or AI_CREEP - else - { - returnval = (isCrouched) ? m_stepvol_crouch_walk : m_stepvol_walk; - } - //gameRenderWorld->DrawText(idStr(returnval), GetEyePosition() + viewAngles.ToForward()*20, 0.15f, colorWhite, viewAngles.ToMat3(), 1, 500); - - return returnval; -} - -void idPlayer::InventoryUseKeyRelease(int holdTime) -{ - const CInventoryCursorPtr& crsr = InventoryCursor(); - CInventoryItemPtr it = crsr->GetCurrentItem(); - - // Check for a held grabber entity, which should be put back into the inventory - if (!AddGrabberEntityToInventory()) - { - // Check if there is a valid item selected - if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) - { - UseInventoryItem(EReleased, it, holdTime, false); - } - } -} - -void idPlayer::UseInventoryItem() -{ - // If the grabber item can be equipped/dequipped, use item does this - if ( gameLocal.m_Grabber->GetSelected() || gameLocal.m_Grabber->GetEquipped() ) - { - if( gameLocal.m_Grabber->ToggleEquip() ) - { - return; - } - } - - // If the player has an item that is selected we need to check if this - // is a usable item (like a key). In this case the use action takes - // precedence over the frobaction. - const CInventoryCursorPtr& crsr = InventoryCursor(); - CInventoryItemPtr it = crsr->GetCurrentItem(); - - if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) - { - bool couldBeUsed = UseInventoryItem(EPressed, it, 0, false); // false => not a frob action - - // Give optional visual feedback on the KeyDown event - if (cv_tdm_inv_use_visual_feedback.GetBool()) - { - m_overlays.broadcastNamedEvent(couldBeUsed ? "onInvPositiveFeedback" : "onInvNegativeFeedback"); - } - } -} - -bool idPlayer::UseInventoryItem(EImpulseState impulseState, const CInventoryItemPtr& item, int holdTime, bool isFrobUse) -{ - if (impulseState == EPressed) - { - // Pass the "inventoryUseItem" event to the GUIs - m_overlays.broadcastNamedEvent("inventoryUseItem"); - } - - // Check if we're allowed to use items at all - if (GetImmobilization() & EIM_ITEM_USE) return false; - - // Sanity check - if (item == NULL) return false; - - idEntity* ent = item->GetItemEntity(); - if (ent == NULL) return false; - - idEntity* highlightedEntity = m_FrobEntity.GetEntity(); - - bool itemIsUsable = ent->spawnArgs.GetBool("usable"); - - if (highlightedEntity != NULL && itemIsUsable && highlightedEntity->CanBeUsedBy(item, isFrobUse)) - { - // Pass the use call - if (highlightedEntity->UseBy(impulseState, item)) - { - // Item could be used, return TRUE, we're done - return true; - } - } - - // Item could not be used on the highlighted entity, launch the use script - - idThread* thread = NULL; - - if (impulseState == EPressed) - { - thread = ent->CallScriptFunctionArgs("inventoryUse", true, 0, "eeed", ent, this, highlightedEntity, impulseState); - } - else if (impulseState == EReleased) - { - thread = ent->CallScriptFunctionArgs("inventoryUseKeyRelease", true, 0, "eeef", ent, this, highlightedEntity, static_cast(holdTime)); - } - - if (thread != NULL) - { - thread->Execute(); // Start the thread immediately. - - // A working scriptfunction means the item could be used - return true; - } - - return false; -} - -void idPlayer::DropInventoryItem() -{ - bool bDropped = false; - CGrabber *grabber = gameLocal.m_Grabber; - idEntity *heldEntity = grabber->GetSelected(); - idEntity *equippedEntity = grabber->GetEquipped(); - - // Dequip or drop the item in the grabber hands first - if( equippedEntity != NULL ) - { - grabber->Dequip(); - } - else if(heldEntity != NULL) - { - grabber->Update( this, false ); - } - else - { - // Grabber is empty (no item is held), drop the current inventory item - const CInventoryCursorPtr& cursor = InventoryCursor(); - - CInventoryItemPtr item = cursor->GetCurrentItem(); - CInventoryCategoryPtr category = cursor->GetCurrentCategory(); - - // Do we have a droppable item in the first place? - if (item != NULL && item->IsDroppable() && item->GetCount() > 0) - { - // Retrieve the actual entity behind the inventory item - idEntity* ent = item->GetItemEntity(); - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Attempting to drop inventory entity %s\r", ent->name.c_str()); - - // greebo: Try to locate a drop script function on the entity's scriptobject - const function_t* dropScript = ent->scriptObject.GetFunction(TDM_INVENTORY_DROPSCRIPT); - - if( dropScript != NULL ) - { - // Call the custom drop script - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Running inventory drop script...\r"); - idThread* thread = new idThread(dropScript); - thread->CallFunctionArgs(dropScript, true, "ee", ent, this); - thread->DelayedStart(0); - - // The dropScript changes the inventory count itself, so don't set - // bDropped to true here. - } - // greebo: Only place the entity in the world, if there is no custom dropscript - // The flashbomb for example is spawning projectiles on its own. - else if( DropToHands( ent, item ) ) - { - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item was successfully put in hands: %s\r", ent->name.c_str()); - bDropped = true; - } - else - { - // There wasn't space to drop the item - StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Grabber did not find space in the world to fit entity in hands: %s\r", ent->name.c_str()); - } - - // Decrease the inventory count (this will also clear empty categories) - // This applies for both stackable as well as droppable items - if( bDropped) - { - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item dropped, changing inventory count.\r"); - - ChangeInventoryItemCount(item->GetName(), category->GetName(), -1); - } - - // Always update the HUD, the drop script might have changed the inventory count itself. - inventoryHUDNeedsUpdate = true; - } - } -} - -bool idPlayer::SelectInventoryItem(const idStr& name) -{ - CInventoryItemPtr prev = InventoryCursor()->GetCurrentItem(); - idStr itemName(name); - - if (itemName.IsEmpty()) - { - // Empty name specified, clear the inventory cursor - itemName = TDM_DUMMY_ITEM; - if (prev->GetName() != itemName) - { - // Save name of current item (to restore it in idEntity::NextPrevInventoryItem) - m_LastItemNameBeforeClear = prev->GetName(); - } - } - - // Try to lookup the item in the inventory - CInventoryItemPtr item = Inventory()->GetItem(itemName); - - if (item != NULL) - { - // Item found, set the cursor to it - InventoryCursor()->SetCurrentItem(item); - - // Trigger an update, passing the previous item along - OnInventorySelectionChanged(prev); - return true; - } - else - { - gameLocal.Printf("Could not find item in player inventory: %s\n", itemName.c_str()); - return false; - } -} - -void idPlayer::OnInventoryItemChanged() -{ - // Call the base class - idEntity::OnInventoryItemChanged(); - - inventoryHUDNeedsUpdate = true; -} - -void idPlayer::OnInventorySelectionChanged(const CInventoryItemPtr& prevItem) -{ - // Call the base class first - idEntity::OnInventorySelectionChanged(prevItem); - - // Set the "dirty" flag, the HUD needs a redraw - inventoryHUDNeedsUpdate = true; - - // Notify the GUIs about the change event - m_overlays.broadcastNamedEvent("inventorySelectionChange"); - - // Get the current item - const CInventoryCursorPtr& cursor = InventoryCursor(); - const CInventoryItemPtr& curItem = cursor->GetCurrentItem(); - - if (prevItem != NULL && prevItem != curItem) - { - // We had a valid previous item, un-select the old one - idEntity* prevItemEnt = prevItem->GetItemEntity(); - - // greebo: Call the "UN-SELECT" script method on the "old" item - if (prevItemEnt != NULL) - { - idThread* thread = prevItemEnt->CallScriptFunctionArgs( - "inventory_item_unselect", - true, 0, - "eef", prevItemEnt, prevItem->GetOwner(), static_cast(prevItem->GetOverlay()) - ); - - if (thread != NULL) - { - thread->Execute(); - } - } - - // Remove the hinderance of the previous item - SetHinderance("inventory_item", 1.0f, 1.0f); - } - - if (curItem != NULL && prevItem != curItem) - { - // We have a valid curItem and it is different to the previously selected one - idEntity* curItemEnt = curItem->GetItemEntity(); - - // greebo: Call the "SELECT" script method on the newly selected item to give it a chance to initialise. - if (curItemEnt != NULL) - { - idThread* thread = curItemEnt->CallScriptFunctionArgs( - "inventory_item_select", - true, 0, - "eef", curItemEnt, curItem->GetOwner(), static_cast(curItem->GetOverlay()) - ); - - if (thread != NULL) - { - thread->Execute(); - } - } - - // Update the player's encumbrance based on the new item - SetHinderance("inventory_item", curItem->GetMovementModifier(), 1.0f); - } - - // Lastly, let's see if the category has changed - if (curItem != NULL && prevItem != NULL && curItem->Category() != prevItem->Category()) - { - idUserInterface* invGUI = m_overlays.getGui(m_InventoryOverlay); - if (invGUI != NULL) - { - invGUI->HandleNamedEvent("onInventoryCategoryChanged"); - } - } -} - -bool idPlayer::DropToHands( idEntity *ent, CInventoryItemPtr item ) -{ - bool rc = false; - CGrabber *grabber = gameLocal.m_Grabber; - - if( !ent || !grabber ) - return false; - - // get player view data to apply yaw and roll to dropped object's orientation - idVec3 playViewPos; - idMat3 playViewAxis; - GetViewPos( playViewPos, playViewAxis ); - idAngles viewYaw = playViewAxis.ToAngles(); - // ignore pitch and roll - viewYaw[0] = 0; - viewYaw[2] = 0; - idMat3 playViewYaw = viewYaw.ToMat3(); - - // Set up the initial orientation and point at which we want to drop - idMat3 dropAxis; - if( item != NULL ) - dropAxis = item->GetDropOrientation(); - else if( ent->spawnArgs.FindKey("drop_angles") ) - { - idAngles dropAngles = ent->spawnArgs.GetAngles("drop_angles"); - dropAxis = dropAngles.ToMat3(); - } - else - dropAxis = ent->GetPhysics()->GetAxis(); - - dropAxis *= playViewYaw; - - // flip dropped bodies if appropriate... move elsewhere? - if( ent->IsType(idAFEntity_Base::Type) && ent->spawnArgs.GetBool("shoulderable") ) - { - if( grabber->m_bDropBodyFaceUp ) - dropAxis *= idAngles(0.0f,0.0f,180.0f).ToMat3(); - } - - idVec3 dropPoint; - if( ent->spawnArgs.FindKey("drop_point") ) - { - dropPoint = ent->spawnArgs.GetVector("drop_point"); - dropPoint *= playViewYaw; - dropPoint += playViewPos; - } - else - { - dropPoint = grabber->GetHoldPoint( ent ); - } - - // Stackables: Test that the item fits in world with dummy item first, before spawning the drop item - // NOTE: TestDropItemRotations will overwrite DropAxis if the supplied doesn't work and it finds a working one - if( TestDropItemRotations(ent, playViewPos, dropPoint, dropAxis) ) - { - // Drop the item into the grabber hands - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item fits in hands.\r"); - - // Stackable items only have one "real" entity for the whole item stack. - // When the stack size == 1, this entity can be dropped as it is, - // otherwise we need to spawn a new entity. - if( item && item->IsStackable() && item->GetCount() > 1 ) - { - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Spawning new entity from stackable inventory item...\r"); - // Spawn a new entity of this type - idEntity* spawnedEntity; - const idDict* entityDef = gameLocal.FindEntityDefDict(ent->GetEntityDefName()); - gameLocal.SpawnEntityDef(*entityDef, &spawnedEntity); - - // Replace the entity to be dropped with the newly spawned one. - ent = spawnedEntity; - } - - // If the item is referenced by any objective with a item-location component set the flag - // so it will be considered by location entities. - if ( gameLocal.m_MissionData->MatchLocationObjectives( ent ) ) - { - ent->m_bIsObjective = true; - } - - grabber->PutInHands( ent, dropPoint, dropAxis ); - DM_LOG(LC_INVENTORY, LT_INFO)LOGSTRING("Item was successfully put in hands: %s\r", ent->name.c_str()); - rc = true; - - // check if the item drops straight to the ground, not going in hands first - if( !ent->spawnArgs.GetBool("drop_to_hands","1") ) - { - grabber->Update( this, false ); - } - - // Tels: #2826: re-enable LOD again, in case the entity was in the inventory (like a shoulderable body) - ent->EnableLOD( true ); - } - - return rc; -} - -bool idPlayer::TestDropItemRotations( idEntity *ent, idVec3 viewPoint, idVec3 DropPoint, idMat3 &DropAxis ) -{ - bool bReturnVal(false); - - idList Rotations; - // first try the supplied orientation - Rotations.Append( mat3_identity ); - // yaw rotations - Rotations.Append( idAngles(0.0f, 90.0f, 0.0f).ToMat3() ); - Rotations.Append( idAngles(0.0f, 180.0f, 0.0f).ToMat3() ); - Rotations.Append( idAngles(0.0f, 270.0f, 0.0f).ToMat3() ); - // roll rotations - Rotations.Append( idAngles(0.0f, 0.0f, 90.0f).ToMat3() ); - Rotations.Append( idAngles(0.0f, 0.0f, 180.0f).ToMat3() ); - Rotations.Append( idAngles(0.0f, 0.0f, 270.0f).ToMat3() ); - // pitch up and down - // Dropping upside-down should always be a last resort - if( !gameLocal.m_Grabber->m_bDropBodyFaceUp ) - { - Rotations.Append( idAngles(-90.0f, 0.0f, 0.0f).ToMat3() ); - Rotations.Append( idAngles(90.0f, 0.0f, 0.0f).ToMat3() ); - } - else - { - Rotations.Append( idAngles(90.0f, 0.0f, 0.0f).ToMat3() ); - Rotations.Append( idAngles(-90.0f, 0.0f, 0.0f).ToMat3() ); - } - - // test each orientation to see if it fits in the world - idMat3 InitAxis = DropAxis; - idMat3 TestAxis( mat3_identity ); - for( int i=0; i < Rotations.Num(); i++ ) - { - TestAxis = Rotations[i] * InitAxis; - if( gameLocal.m_Grabber->FitsInWorld( ent, viewPoint, DropPoint, TestAxis ) ) - { - bReturnVal = true; - DropAxis = TestAxis; - break; - } - } - - return bReturnVal; -} - -void idPlayer::Event_GetEyePos( void ) -{ - idThread::ReturnVector( firstPersonViewOrigin ); -} - -void idPlayer::Event_SetImmobilization( const char *source, int type ) -{ - SetImmobilization( source, type ); -} - -/* -===================== -idPlayer::Event_GetImmobilization -===================== -*/ -void idPlayer::Event_GetImmobilization( const char *source ) -{ - if (idStr::Length(source)) { - idThread::ReturnInt( m_immobilization.GetInt(source) ); - } else { - idThread::ReturnInt( GetImmobilization() ); - } -} - -/* -===================== -idPlayer::Event_GetNextImmobilization -===================== -*/ -void idPlayer::Event_GetNextImmobilization( const char *prefix, const char *lastMatch ) -{ - // Code is plagarized from getNextKey() - const idKeyValue *kv; - const idKeyValue *previous; - - if ( *lastMatch ) { - previous = m_immobilization.FindKey( lastMatch ); - } else { - previous = NULL; - } - - kv = m_immobilization.MatchPrefix( prefix, previous ); - if ( !kv ) { - idThread::ReturnString( "" ); - } else { - idThread::ReturnString( kv->GetKey() ); - } -} - -/* -===================== -idPlayer::Event_SetHinderance -===================== -*/ -void idPlayer::Event_SetHinderance( const char *source, float mCap, float aCap ) -{ - SetHinderance( source, mCap, aCap ); -} - -/* -===================== -idPlayer::Event_SetTurnHinderance -===================== -*/ -void idPlayer::Event_SetTurnHinderance( const char *source, float mCap, float aCap ) -{ - SetTurnHinderance(source, mCap, aCap); -} - -/* -===================== -idPlayer::Event_GetHinderance -===================== -*/ -void idPlayer::Event_GetHinderance( const char *source ) -{ - if (idStr::Length(source)) { - idThread::ReturnVector( m_hinderance.GetVector( source, "1 1 0" ) ); - } else { - float h = GetHinderance(); - idVec3 vec( h, h, 0.0f ); - idThread::ReturnVector( vec ); - } -} - -/* -===================== -idPlayer::Event_GetTurnHinderance -===================== -*/ -void idPlayer::Event_GetTurnHinderance( const char *source ) -{ - if (idStr::Length(source)) { - idThread::ReturnVector( m_TurnHinderance.GetVector( source, "1 1 0" ) ); - } else { - float h = GetTurnHinderance(); - idVec3 vec( h, h, 0.0f ); - idThread::ReturnVector( vec ); - } -} - -/* -===================== -idPlayer::Event_GetNextHinderance -===================== -*/ -void idPlayer::Event_GetNextHinderance( const char *prefix, const char *lastMatch ) -{ - // Code is plagarized from getNextKey() - const idKeyValue *kv; - const idKeyValue *previous; - - if ( *lastMatch ) { - previous = m_hinderance.FindKey( lastMatch ); - } else { - previous = NULL; - } - - kv = m_hinderance.MatchPrefix( prefix, previous ); - if ( !kv ) { - idThread::ReturnString( "" ); - } else { - idThread::ReturnString( kv->GetKey() ); - } -} - -/* -===================== -idPlayer::Event_GetNextTurnHinderance -===================== -*/ -void idPlayer::Event_GetNextTurnHinderance( const char *prefix, const char *lastMatch ) -{ - // Code is plagarized from getNextKey() - const idKeyValue *kv; - const idKeyValue *previous; - - if ( *lastMatch ) { - previous = m_TurnHinderance.FindKey( lastMatch ); - } else { - previous = NULL; - } - - kv = m_TurnHinderance.MatchPrefix( prefix, previous ); - if ( !kv ) { - idThread::ReturnString( "" ); - } else { - idThread::ReturnString( kv->GetKey() ); - } -} - -/* -===================== -idPlayer::Event_SetGui -===================== -*/ -void idPlayer::Event_SetGui( int handle, const char *guiFile ) { - if ( !uiManager->CheckGui(guiFile) ) { - gameLocal.Warning( "Unable to load GUI file: %s\n", guiFile ); - goto Quit; - } - - if ( !m_overlays.exists( handle ) ) { - gameLocal.Warning( "Non-existant GUI handle: %d\n", handle ); - goto Quit; - } - - // Entity GUIs are handled differently from regular ones. - if ( handle == OVERLAYS_MIN_HANDLE ) { - - assert( hud ); - assert( m_overlays.isExternal( handle ) ); - - // We're dealing with an existing unique GUI. - // We need to read a new GUI into it. - - // Clear the state. - const idDict &state = hud->State(); - const idKeyValue *kv; - while ( ( kv = state.MatchPrefix( "" ) ) != NULL ) - hud->DeleteStateVar( kv->GetKey() ); - - hud->InitFromFile( guiFile ); - - } else if ( !m_overlays.isExternal( handle ) ) { - - bool result = m_overlays.setGui( handle, guiFile ); - assert( result ); - - idUserInterface *gui = m_overlays.getGui( handle ); - if ( gui ) { - gui->SetStateInt( "handle", handle ); - gui->Activate( true, gameLocal.time ); - // Let's set a good default value for whether or not the overlay is interactive. - m_overlays.setInteractive( handle, gui->IsInteractive() ); - } else { - gameLocal.Warning( "Unknown error: Unable to load GUI into overlay.\n" ); - } - - } else { - gameLocal.Warning( "Cannot call setGui() on external handle: %d\n", handle ); - } - - Quit: - return; -} - -void idPlayer::Event_GetInventoryOverlay(void) -{ - idThread::ReturnInt(m_InventoryOverlay); -} - -void idPlayer::Event_PlayStartSound( void ) -{ - StartSound("snd_mission_start", SND_CHANNEL_ANY, 0, false, NULL); -} - -void idPlayer::Event_MissionFailed( void ) -{ - gameLocal.m_MissionData->Event_MissionFailed(); -} - -void idPlayer::Event_CustomDeath() -{ - // Run the custom death script - idThread* thread = CallScriptFunctionArgs("custom_death", true, 0, "e", this); - - if (thread != NULL) { - // Run immediately - thread->Execute(); - } -} - -void idPlayer::Event_LoadDeathMenu( void ) -{ - forceRespawn = true; -} - -/* -================ -idPlayer::Event_HoldEntity -================ -*/ -void idPlayer::Event_HoldEntity( idEntity *ent ) -{ - if ( ent ) - { - bool successful = gameLocal.m_Grabber->PutInHands( ent, ent->GetPhysics()->GetAxis() ); - idThread::ReturnInt( successful ); - } - else - { - gameLocal.m_Grabber->Update( this, false ); - idThread::ReturnInt( 1 ); - } -} - -/* -================ -idPlayer::Event_HeldEntity -================ -*/ -void idPlayer::Event_HeldEntity( void ) -{ - idThread::ReturnEntity(gameLocal.m_Grabber->GetSelected()); -} - -void idPlayer::Event_RopeRemovalCleanup(idEntity *RopeEnt) -{ - if (GetPhysics()->IsType(idPhysics_Player::Type)) - { - static_cast(GetPhysics())->RopeRemovalCleanup( RopeEnt ); - } -} - -void idPlayer::Event_SetObjectiveState( int ObjIndex, int State ) -{ - // when calling this function externally, the "user" indices are - // used, so subtract one from the index - gameLocal.m_MissionData->SetCompletionState( ObjIndex - 1, State ); -} - -void idPlayer::Event_GetObjectiveState( int ObjIndex ) -{ - int CompState = gameLocal.m_MissionData->GetCompletionState( ObjIndex - 1 ); - idThread::ReturnInt( CompState ); -} - -void idPlayer::Event_SetObjectiveComp( int ObjIndex, int CompIndex, int bState ) -{ - gameLocal.m_MissionData->SetComponentState_Ext( ObjIndex, CompIndex, (bState != 0) ); -} - -void idPlayer::Event_GetObjectiveComp( int ObjIndex, int CompIndex ) -{ - bool bCompState = gameLocal.m_MissionData->GetComponentState( ObjIndex -1, CompIndex -1 ); - - idThread::ReturnInt( (int) bCompState ); -} - -void idPlayer::Event_ObjectiveUnlatch( int ObjIndex ) -{ - gameLocal.m_MissionData->UnlatchObjective( ObjIndex - 1 ); -} - -void idPlayer::Event_ObjectiveComponentUnlatch( int ObjIndex, int CompIndex ) -{ - gameLocal.m_MissionData->UnlatchObjectiveComp( ObjIndex - 1, CompIndex -1 ); -} - -void idPlayer::Event_SetObjectiveVisible( int ObjIndex, bool bVal ) -{ - gameLocal.m_MissionData->SetObjectiveVisibility(ObjIndex, bVal); -} - -void idPlayer::Event_SetObjectiveOptional( int ObjIndex, bool bVal ) -{ - gameLocal.m_MissionData->SetObjectiveMandatory(ObjIndex, !bVal); // negate the incoming bool -} - -void idPlayer::Event_SetObjectiveOngoing( int ObjIndex, bool bVal ) -{ - gameLocal.m_MissionData->SetObjectiveOngoing(ObjIndex, bVal); -} - -void idPlayer::Event_SetObjectiveEnabling( int ObjIndex, const char *strIn ) -{ - gameLocal.m_MissionData->SetEnablingObjectives(ObjIndex, strIn); -} - -void idPlayer::Event_GiveHealthPool( float amount ) { - // Pass the call to the proper member method - GiveHealthPool(amount); -} - -void idPlayer::Event_WasDamaged( void ) -{ - idThread::ReturnInt(m_bDamagedThisFrame); -} - -void idPlayer::Event_StartZoom(float duration, float startFOV, float endFOV) -{ - // greebo: Start the new transition from startFOV >> endFOV, this enables the idInterpolate - zoomFov.Init(gameLocal.time, duration, startFOV, endFOV); -} - -void idPlayer::Event_EndZoom(float duration) -{ - // greebo: Make a transition from the current FOV back to the default FOV, this enables the idInterpolate - zoomFov.Init(gameLocal.time, duration, zoomFov.GetCurrentValue(gameLocal.time), DefaultFov()); -} - -void idPlayer::Event_ResetZoom() -{ - // Reset the FOV to the default values, this enables the idInterpolate - zoomFov.Init(gameLocal.time, 0, DefaultFov(), DefaultFov()); -} - -void idPlayer::Event_GetFov() -{ - // greebo: Return the current fov - idThread::ReturnFloat(CalcFov(true)); -} - -void idPlayer::PerformFrobCheck() -{ - // greebo: Don't run this when dead - if (AI_DEAD) - { - return; - } - - // greebo: Don't run the frobcheck when we're dragging items around - if (m_bGrabberActive) - { - return; - } - - // ishtvan: Don't run if frob hilighting is disabled - // TODO: Should we just add this functionality to EIM_FROB and get rid of EIM_FROBHILIGHT? - if ( GetImmobilization() & EIM_FROB_HILIGHT ) - { - m_FrobEntity = NULL; - return; - } - - idVec3 eyePos = GetEyePosition(); - float maxFrobDistance = g_Global.m_MaxFrobDistance; - - // greebo: Let the currently selected inventory item affect the frob distance (lockpicks, for instance) - CInventoryItemPtr curItem = InventoryCursor()->GetCurrentItem(); - - idVec3 start = eyePos; - idVec3 end = start + viewAngles.ToForward() * maxFrobDistance; - - // Do frob trace first, along view axis, record distance traveled - // Frob collision mask: - int cm = CONTENTS_SOLID|CONTENTS_OPAQUE|CONTENTS_BODY - |CONTENTS_CORPSE|CONTENTS_RENDERMODEL|CONTENTS_FROBABLE; - - trace_t trace; - gameLocal.clip.TracePoint(trace, start, end, cm, this); - - float traceDist = g_Global.m_MaxFrobDistance * trace.fraction; - - if ( trace.fraction < 1.0f ) - { - idEntity *ent = gameLocal.entities[ trace.c.entityNum ]; - - float extraSpace = 0; // grayman #2478 - a little extra room to disarm a mine - if ( ent->IsType(idProjectile::Type) && static_cast(ent)->IsMine() ) - { - extraSpace = 8; - } - - DM_LOG(LC_FROBBING, LT_INFO)LOGSTRING("Frob: Direct hit on entity %s\r", ent->name.c_str()); - - // This is taking locked items into account - bool lockedItemCheck = true; - // If we are in the mode where we only frob ents used by our inventory item, this checks if it passes the test - bool bUsedByCheck = true; - - // greebo: Check if the frobbed entity is the bindmaster of the currently climbed rope - bool isRopeMaster = physicsObj.OnRope() && physicsObj.GetRopeEntity()->GetBindMaster() == ent; - - // ishtvan: Check if the frobbed entity is a dynamically added AF body linked to another entity - if ( ent->IsType(idAFEntity_Base::Type) ) - { - idAFEntity_Base *afEnt = static_cast(ent); - idAFBody *AFbod = afEnt->GetAFPhysics()->GetBody( afEnt->BodyForClipModelId(trace.c.id) ); - - if ( AFbod->GetRerouteEnt() && AFbod->GetRerouteEnt()->m_bFrobable ) - { - ent = AFbod->GetRerouteEnt(); - } - } - - // Inventory items might impose a reduction of the frob distance to some entities - if ( curItem != NULL ) - { - bool bCanBeUsed = ent->CanBeUsedBy(curItem, true); - - if ( bCanBeUsed && ( traceDist > curItem->GetFrobDistanceCap() + extraSpace ) ) - { - // Failed the distance check for locked items, disable this entity - lockedItemCheck = false; - } - - if ( m_bFrobOnlyUsedByInv && !bCanBeUsed ) - { - // frob only used by is active and ent can't be used, failed check - bUsedByCheck = false; - } - } - - // If shouldering a body, we only allow "simple" frobs - bool frobAllowed = !m_bShoulderingBody || ent->m_bFrobSimple; - - // only frob frobable, non-hidden entities within their frobdistance - // also, do not frob the ent we are currently holding in our hands - if ( ent->m_bFrobable && frobAllowed && lockedItemCheck && bUsedByCheck && !isRopeMaster - && !ent->IsHidden() && ( traceDist < ent->m_FrobDistance ) - && ( ent != gameLocal.m_Grabber->GetSelected() ) ) - { - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING(" Entity %s was within frobdistance\r", ent->name.c_str()); - - // Mark as frobbed for this frame - ent->SetFrobbed(true); - - // Store the trace for later reference - m_FrobTrace = trace; - // Store the frob entity - m_FrobEntity = ent; - - // we have found our frobbed entity, so exit - return; - } - } - - // If the trace didn't hit anything frobable, do the radius test - DM_LOG(LC_FROBBING,LT_INFO)LOGSTRING("No entity frobbed by direct LOS frob, trying frob radius.\r"); - - idBounds frobBounds(trace.endpos); - frobBounds.ExpandSelf( cv_frob_width.GetFloat() ); - - // Optional debug drawing of frob bounds - if( cv_frob_debug_bounds.GetBool() ) - { - gameRenderWorld->DebugBounds( colorBlue, frobBounds ); - } - - static idEntity* frobRangeEnts[MAX_GENTITIES]; - - int numFrobEnt = gameLocal.clip.EntitiesTouchingBounds(frobBounds, -1, frobRangeEnts, MAX_GENTITIES); - - idVec3 vecForward = viewAngles.ToForward(); - float bestDot = 0; - idEntity* bestEnt = NULL; - - for ( int i = 0 ; i < numFrobEnt ; i++ ) - { - idEntity *ent = frobRangeEnts[i]; - - if (ent == NULL) - { - continue; - } - - if (!ent->m_FrobDistance || ent->IsHidden() || !ent->m_bFrobable) - { - continue; - } - - // If shouldering a body, we only allow "simple" frobs - if (m_bShoulderingBody && !ent->m_bFrobSimple) - { - continue; - } - - // Get the frob distance from the entity candidate - float frobDist = ent->m_FrobDistance; - idVec3 delta = ent->GetPhysics()->GetOrigin() - eyePos; - - float entDistance = delta.LengthFast(); - - if (entDistance > frobDist) - { - continue; // too far - } - - if (curItem != NULL) // grayman #2478 - rearranged code - { - bool canBeUsed = ent->CanBeUsedBy(curItem, true); - - // Inventory items might impose a reduction of the frob distance to some entities. - // grayman #2478 - If the frobbed entity is a mine, increase the distance. - - // Special case for armed mine and lockpick. - - bool isMine = ( ent->IsType(idProjectile::Type) && static_cast(ent)->IsMine() ); - if ( isMine ) - { - if ( !canBeUsed || ( entDistance > ( curItem->GetFrobDistanceCap() + 8 ) ) ) - { - continue; - } - } - else if ( canBeUsed && ( entDistance > curItem->GetFrobDistanceCap() ) ) - { - // Failed inventory item distance check, ignore this entity - continue; - } - - // Frob only used by inv. item is active, and this entity cannot be used by it - if ( m_bFrobOnlyUsedByInv && !canBeUsed ) - { - continue; - } - } - - delta.NormalizeFast(); - float currentDot = delta * vecForward; - currentDot *= ent->m_FrobBias; - - if ( currentDot > bestDot ) - { - bestDot = currentDot; - bestEnt = ent; - } - } - - if ( ( bestEnt != NULL ) && ( bestEnt != gameLocal.m_Grabber->GetSelected() ) ) - { - // Mark the entity as frobbed this frame - bestEnt->SetFrobbed(true); - // Store the frob entity - m_FrobEntity = bestEnt; - // and the trace for reference - m_FrobTrace = trace; - - return; // done - } - - // No frob entity - m_FrobEntity = NULL; -} - -int idPlayer::GetImmobilization( const char *source ) -{ - // greebo: Return named immobilizations or return the sum of all immobilizations - return (idStr::Length(source) > 0) ? m_immobilization.GetInt(source) : GetImmobilization(); -} - -void idPlayer::SetImmobilization( const char *source, int type ) -{ - if (idStr::Length(source)) - { - // The user cannot set the update bit directly. - type &= ~EIM_UPDATE; - - if (type != 0) - { - m_immobilization.SetInt( source, type ); - } - else - { - m_immobilization.Delete( source ); - } - - m_immobilizationCache |= EIM_UPDATE; - } - else - { - gameLocal.Warning( "source was empty; no immobilization set\n" ); - } -} - -void idPlayer::SetHinderance( const char *source, float mCap, float aCap ) -{ - if (idStr::Length(source)) - { - // Clamp the values to [0,1] - mCap = idMath::ClampFloat(0, 1, mCap); - aCap = idMath::ClampFloat(0, 1, aCap); - - if (mCap < 1.0f || aCap < 1.0f) - { - // Store the values into a vector and into the hinderance dictionary - m_hinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); - } - else - { - // greebo: Both values are 1 == no hinderance, delete the value - m_hinderance.Delete( source ); - } - - m_hinderanceCache = -1; - } - else - { - gameLocal.Warning( "source was empty; no hinderance set\n" ); - } -} - -void idPlayer::SetTurnHinderance( const char *source, float mCap, float aCap ) -{ - if (idStr::Length(source)) - { - // Clamp the values to [0,1] - mCap = idMath::ClampFloat(0, 1, mCap); - aCap = idMath::ClampFloat(0, 1, aCap); - - if (mCap < 1.0f || aCap < 1.0f) - { - // Store the values into a vector and into the hinderance dictionary - m_TurnHinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); - } - else - { - m_TurnHinderance.Delete( source ); - } - - m_TurnHinderanceCache = -1; - } - else - { - gameLocal.Warning( "source was empty; no turn hinderance set\n" ); - } -} - -float idPlayer::GetJumpHinderance() -{ - // Has something changed since the cache was last calculated? - if (m_JumpHinderanceCache < 0.0f) - { - // Recalculate the hinderance from scratch. - float mCap = 1.0f, aCap = 1.0f; - - for (const idKeyValue* kv = m_JumpHinderance.MatchPrefix( "", NULL ); kv != NULL; kv = m_JumpHinderance.MatchPrefix("", kv)) - { - idVec3 vec = m_JumpHinderance.GetVector(kv->GetKey()); - mCap *= vec[0]; - - if ( aCap > vec[1] ) - { - aCap = vec[1]; - } - } - - if ( aCap > mCap ) - { - aCap = mCap; - } - - m_JumpHinderanceCache = aCap; - } - - return m_JumpHinderanceCache; -} - -void idPlayer::SetJumpHinderance( const char *source, float mCap, float aCap ) -{ - if (idStr::Length(source)) - { - // Clamp the values to [0,1] - mCap = idMath::ClampFloat(0, 1, mCap); - aCap = idMath::ClampFloat(0, 1, aCap); - - if (mCap < 1.0f || aCap < 1.0f) - { - // Store the values into a vector and into the hinderance dictionary - m_JumpHinderance.SetVector( source, idVec3(mCap, aCap, 0.0f) ); - } - else - { - m_JumpHinderance.Delete( source ); - } - - m_JumpHinderanceCache = -1; - } - else - { - gameLocal.Warning( "source was empty; no jump hinderance set\n" ); - } -} - -void idPlayer::PlayFootStepSound() -{ - if ( !GetPhysics()->HasGroundContacts() ) { - return; - } - - // This implements a certain dead time before the next footstep is allowed to be played - if (gameLocal.time <= lastFootstepPlaytime + cv_pm_min_stepsound_interval.GetInteger()) - { - return; - } - - idStr localSound; - - // DarkMod: make the string to identify the movement speed (crouch_run, creep, etc) - // Currently only players have movement flags set up this way, not AI. We could change that later. - idStr moveType(""); - - UpdateMoveVolumes(); - - // angua: check whether the player has just landed from jumping or a fall - if (!hasLanded) - { - if (AI_CROUCH) - { - moveType = "_crouch"; - } - - // greebo: Make sure that "_run" is only applied when actually running - if (AI_RUN && physicsObj.HasRunningVelocity()) - { - moveType += "_run"; - } - else if (AI_CREEP) - { - moveType += "_creep"; - } - else - { - moveType += "_walk"; - } - } - - // start footstep sound based on material type - const idMaterial* material = GetPhysics()->GetContact( 0 ).material; - if ( material != NULL ) - { - DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Player %s stepped on entity %s, material %s \r", name.c_str(), gameLocal.entities[GetPhysics()->GetContact( 0 ).entityNum]->name.c_str(), material->GetName() ); - g_Global.GetSurfName(material, localSound); - if (hasLanded) - { - localSound = "snd_jump_" + localSound; - } - else - { - localSound = "snd_footstep_" + localSound; - } - - DM_LOG(LC_SOUND,LT_DEBUG)LOGSTRING("Found surface type sound: %s\r", localSound.c_str() ); - } - - waterLevel_t waterLevel = physicsObj.GetWaterLevel(); - // If player is walking in liquid, replace the bottom surface sound with water sounds - if (waterLevel == WATERLEVEL_FEET ) - { - if (hasLanded) - { - localSound = "snd_jump_puddle"; - } - else - { - localSound = "snd_footstep_puddle"; - } - } - else if (waterLevel == WATERLEVEL_WAIST) - { - localSound = "snd_footstep_wading"; - } - // greebo: Added this to disable the walking sound when completely underwater - // this should be replaced by snd_ - else if (waterLevel == WATERLEVEL_HEAD) - { - localSound = "snd_footstep_swim"; - } - - idStr sound; - - if (cv_tdm_footfalls_movetype_specific.GetBool()) - { - sound = spawnArgs.GetString( localSound + moveType ); - - if (sound.IsEmpty()) - { - //gameLocal.Warning("Did not find footstep sound %s", (localSound + moveType).c_str()); - - // Fall back to normal sound - sound = spawnArgs.GetString( localSound ); - } - } - else - { - sound = spawnArgs.GetString( localSound ); - } - - if ( sound.IsEmpty() && waterLevel != WATERLEVEL_HEAD ) - { - localSound = "snd_footstep"; - } - - // if a sound was not found for that specific material, use default - if( sound.IsEmpty() && waterLevel != WATERLEVEL_HEAD ) - { - sound = spawnArgs.GetString( "snd_footstep" ); - localSound = "snd_footstep"; - } - - // The player always considers the movement type when propagating - if (!hasLanded) - { - localSound += moveType; - } - - if ( !sound.IsEmpty() ) - { - // apply the movement type modifier to the volume - const idSoundShader* sndShader = declManager->FindSound( sound ); - SetSoundVolume( sndShader->GetParms()->volume + GetMovementVolMod() ); - StartSoundShader( sndShader, SND_CHANNEL_BODY, 0, false, NULL ); - SetSoundVolume( 0.0f ); - - // propagate the suspicious sound to other AI - PropSoundDirect( localSound, true, false ); - - lastFootstepPlaytime = gameLocal.time; - } -} - -/* -================ -idPlayer::RangedThreatTo - -Return nonzero if this entity could potentially -attack the given (target) entity at range, or -entities in general if target is NULL. -i.e. Return 1 if we have a projectile weapon -equipped, and 0 otherwise. -================ -*/ -float idPlayer::RangedThreatTo(idEntity* target) { - idWeapon* weaponEnt = weapon.GetEntity(); - - return weaponEnt->IsRanged(); -} - -void idPlayer::SetListenerLoc( idVec3 loc ) -{ - m_ListenerLoc = loc; -} - -idVec3 idPlayer::GetListenerLoc( void ) -{ - return m_ListenerLoc; -} - -void idPlayer::SetDoorListenLoc( idVec3 loc ) -{ - m_DoorListenLoc = loc; -} - -idVec3 idPlayer::GetDoorListenLoc( void ) -{ - return m_DoorListenLoc; -} - -CInventoryItemPtr idPlayer::AddToInventory(idEntity *ent) -{ - // Pass the call to the base class first - CInventoryItemPtr returnValue = idEntity::AddToInventory(ent); - - // Has this item been added to a weapon item? - CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast(returnValue); - - CInventoryItemPtr prev; - - if (weaponItem != NULL) - { - // greebo: This is a weapon-related inventory item, use the weapon inventory cursor - // Do it only if the respective CVAR is set - if (cv_frob_weapon_selects_weapon.GetBool()) - { - m_WeaponCursor->SetCurrentItem(returnValue); - SelectWeapon(weaponItem->GetWeaponIndex(), false); - } - } - else if (returnValue != NULL) - { - // Ordinary inventory item, set the cursor onto it - prev = InventoryCursor()->GetCurrentItem(); - // Focus the cursor on the newly added item - InventoryCursor()->SetCurrentItem(returnValue); - - // Fire the script events and update the HUD - OnInventorySelectionChanged(prev); - } - - return returnValue; -} - -void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target) -{ - // greebo: Don't perform frobs on hidden or NULL entities - if (target == NULL || target->IsHidden()) - { - return; - } - - // if we only allow "simple" frob actions and this isn't one, play forbidden sound - if( (GetImmobilization() & EIM_FROB_COMPLEX) && !target->m_bFrobSimple ) - { - // TODO: Rename this "uh-uh" sound to something more general? - StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); - return; - } - - // greebo: Check the frob entity, this might be the same as the argument - // Retrieve the entity before trying to add it to the inventory, the pointer - // might be cleared after calling AddToInventory(). - idEntity* highlightedEntity = m_FrobEntity.GetEntity(); - - if (impulseState == EPressed) - { - // Fire the STIM_FROB response on key down (if defined) on this entity - target->TriggerResponse(this, ST_FROB); - } - - // Do we allow use on frob? - if (cv_tdm_inv_use_on_frob.GetBool()) - { - // Check if we have a "use" relationship with the currently selected inventory item (key => door) - CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); - - // Only allow items with UseOnFrob == TRUE to be used when frobbing - if (item != NULL && item->UseOnFrob() && highlightedEntity->CanBeUsedBy(item, true)) - { - // Try to use the item - bool couldBeUsed = UseInventoryItem(impulseState, item, gameLocal.msec, true); // true => is frob action - - // Give optional visual feedback on the KeyDown event - if (impulseState == EPressed && cv_tdm_inv_use_visual_feedback.GetBool()) - { - m_overlays.broadcastNamedEvent(couldBeUsed ? "onInvPositiveFeedback" : "onInvNegativeFeedback"); - } - - return; - } - } - - // If FrobUsedOnlyByInv mode is active, we can only perform use_on_frob actions, so skip all the rest - if( m_bFrobOnlyUsedByInv ) - return; - - // Inventory item could not be used with the highlighted entity, proceed with ordinary frob action - - // These actions are only applicable for EPressed buttonstate - if (impulseState == EPressed) - { - // Trigger the frob action script on key down - target->FrobAction(true); - - DM_LOG(LC_FROBBING, LT_DEBUG)LOGSTRING("USE: frob target: %s \r", target->name.c_str()); - - // note which target we started pressing frob on - m_FrobPressedTarget = target; - - // First we have to check whether that entity is an inventory - // item. In that case, we have to add it to the inventory and - // hide the entity. - CInventoryItemPtr addedItem = AddToInventory(target); - - // Check if the frobbed entity is the one currently highlighted by the player - if (addedItem != NULL && highlightedEntity == target) - { - // Item has been added to the inventory, clear the entity pointer - m_FrobEntity = NULL; - } - - // Grab it if it's a grabable class - if (target->IsType(idMoveable::Type) || target->IsType(idAFEntity_Base::Type) || - target->IsType(idMoveableItem::Type) || target->IsType(idAFAttachment::Type)) - { - // allow override of default grabbing behavior - if( !target->spawnArgs.GetBool("grabable","1") ) - return; - - // Do not pick up live, conscious AI - if( target->IsType( idAI::Type ) ) - { - idAI *AItarget = static_cast(target); - if( AItarget->health > 0 && !AItarget->IsKnockedOut() ) - return; - } - - gameLocal.m_Grabber->Update( this ); - } - } -} - -void idPlayer::PerformFrob() -{ - // Ignore frobs if player-frobbing is immobilized. - if ( GetImmobilization() & EIM_FROB ) - { - return; - } - - // if the grabber is currently holding something and frob is pressed, - // release it. Do not frob anything new since you're holding an item. - if( gameLocal.m_Grabber->GetSelected() ) - { - gameLocal.m_Grabber->Update( this ); - return; - } - - // Get the currently frobbed entity - idEntity* frob = m_FrobEntity.GetEntity(); - - // Relay the function to the specialised method - PerformFrob(EPressed, frob); -} - -void idPlayer::PerformFrobKeyRepeat(int holdTime) -{ - // Ignore frobs if player-frobbing is immobilized. - if ( GetImmobilization() & EIM_FROB ) return; - - // Get the currently frobbed entity - idEntity* frob = m_FrobEntity.GetEntity(); - - // use the original target until frob is released and pressed again - if( m_FrobPressedTarget.IsValid() && m_FrobPressedTarget.GetEntity() != NULL ) - m_FrobPressedTarget.GetEntity()->FrobHeld( true, false, holdTime ); - - // Relay the function to the specialised method - PerformFrob(ERepeat, frob); -} - -void idPlayer::PerformFrobKeyRelease(int holdTime) -{ - // Ignore frobs if player-frobbing is immobilized. - if ( GetImmobilization() & EIM_FROB ) return; - - // Get the currently frobbed entity - idEntity* frob = m_FrobEntity.GetEntity(); - - // use the original target until frob is released and pressed again - if( m_FrobPressedTarget.IsValid() && m_FrobPressedTarget.GetEntity() != NULL ) - m_FrobPressedTarget.GetEntity()->FrobReleased( true, false, holdTime ); - - // Relay the function to the specialised method - PerformFrob(EReleased, frob); -} - -void idPlayer::setHealthPoolTimeInterval(int newTimeInterval, float factor, int stepAmount) { - healthPoolTimeInterval = newTimeInterval; - healthPoolTimeIntervalFactor = factor; - healthPoolStepAmount = stepAmount; -} - -bool idPlayer::AddGrabberEntityToInventory() -{ - CGrabber* grabber = gameLocal.m_Grabber; - idEntity* heldEntity = grabber->GetSelected(); - - if (heldEntity != NULL) - { - CInventoryItemPtr item = AddToInventory(heldEntity); - - if (item != NULL) - { - // greebo: Release any items from the grabber, this immobilized the player somehow before - grabber->Update( this, false ); - - // greebo: Prevent the grabber from checking the added entity (it may be - // entirely removed from the game, which would cause crashes). - grabber->RemoveFromClipList(heldEntity); - - return true; - } - } - - return false; -} - -int idPlayer::GetLightgemModifier(int curLightgemValue) -{ - // Take the compiled lightgem modifier as starting point - int returnValue = curLightgemValue + m_LightgemModifier; - - // greebo: Take the current velocity into account - // This is a multiplicative modifier and is applied first - { - // Get the velocity, but don't take "inherited" speed into account. - idVec3 velocityVec = physicsObj.GetLinearVelocity() - physicsObj.GetPushedLinearVelocity(); - - const idVec3& gravityDir = physicsObj.GetGravityNormal(); - velocityVec -= (velocityVec * gravityDir) * gravityDir; - - float velocity = velocityVec.LengthFast(); - float minVelocity = cv_lg_velocity_mod_min_velocity.GetFloat(); - float maxVelocity = cv_lg_velocity_mod_max_velocity.GetFloat(); - - float velocityFactor = (velocity - minVelocity) / (maxVelocity - minVelocity); - - // Force the factor into [0..1] - if (velocityFactor > 1) velocityFactor = 1; - if (velocityFactor < 0) velocityFactor = 0; - - float factor = 1.0f + velocityFactor*cv_lg_velocity_mod_amount.GetFloat(); - returnValue = static_cast(returnValue * factor); - } - - // Check the weapon/inventory items - if (m_WeaponCursor != NULL) - { - CInventoryItemPtr weapon = m_WeaponCursor->GetCurrentItem(); - if (weapon != NULL) - { - returnValue += weapon->GetLightgemModifier(); - } - } - - CInventoryItemPtr item = InventoryCursor()->GetCurrentItem(); - if (item != NULL) - { - returnValue += item->GetLightgemModifier(); - } - - // Take the crouching into account - if (physicsObj.IsCrouching()) - { - returnValue += cv_lg_crouch_modifier.GetInteger(); - } - - // No need to cap the value, this is done in idGameLocal again. - - return returnValue; -} - -void idPlayer::Event_SetLightgemModifier(const char* modifierName, int amount) -{ - if (amount != 0) - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Setting modifier %s to %d\r", modifierName, amount); - m_LightgemModifierList[std::string(modifierName)] = amount; - } - else - { - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Removing modifier %s as %d was passed\r", modifierName, amount); - // Zero value passed, remove the named value - std::string modifierNameStr(modifierName); - std::map::iterator i = m_LightgemModifierList.find(modifierNameStr); - - if (i != m_LightgemModifierList.end()) { - // Value found, remove it - m_LightgemModifierList.erase(i); - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("Removed.\r"); - } - } - - // Recalculate the lightgem modifier value - m_LightgemModifier = 0; - - for (std::map::const_iterator i = m_LightgemModifierList.begin(); - i != m_LightgemModifierList.end(); - ++i) - { - // Add the value to the lightgem modifier - m_LightgemModifier += i->second; - } - - DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING("New lightgem modifier value: %d\r", m_LightgemModifier); -} - -void idPlayer::Event_ReadLightgemModifierFromWorldspawn() -{ - int modifierValue(0); - - idEntity* worldspawn = gameLocal.entities[ENTITYNUM_WORLD]; - - if (worldspawn != NULL) - { - // Read the modifier value from the worldspawn, default to zero - modifierValue = worldspawn->spawnArgs.GetInt("lightgem_adjust", "0"); - } - - Event_SetLightgemModifier("world", modifierValue); -} - -void idPlayer::SendHUDMessage(const idStr& text) -{ - if (text.IsEmpty()) { - return; - } - - hudMessages.Append( gameLocal.m_I18N->Translate( text ) ); -} - -void idPlayer::SendInventoryPickedUpMessage(const idStr& text) -{ - if (text.IsEmpty()) return; - - inventoryPickedUpMessages.Append(text); -} - -void idPlayer::EnforcePersistentInventoryItemLimits() -{ - idStr diffPrefix = va("diff_%d_", gameLocal.m_DifficultyManager.GetDifficultyLevel()); - - for (int i = 0; i < gameLocal.campaignInfoEntities.Num(); ++i) - { - idEntity* campaignInfo = gameLocal.campaignInfoEntities[i]; - assert(campaignInfo != NULL); - - // Enforce weapon limits - CInventoryCategoryPtr weaponCategory = m_WeaponCursor->GetCurrentCategory(); - - idList itemsToRemove; - - for (int w = 0; w < weaponCategory->GetNumItems(); ++w) - { - CInventoryWeaponItemPtr weaponItem = boost::dynamic_pointer_cast(weaponCategory->GetItem(w)); - - if (weaponItem->GetPersistentCount() <= 0) - { - continue; // not a persistent weapon - } - - const idStr& weaponName = weaponItem->GetWeaponName(); - - // Get the active limit, check non-difficulty-specific ones first, defaults to no limit - int limit = campaignInfo->spawnArgs.GetInt("weapon_limit_" + weaponName, "-1"); - - // Let the difficulty-specific limit override the global one - limit = campaignInfo->spawnArgs.GetInt(diffPrefix + "weapon_limit_" + weaponName, va("%d", limit)); - - if (limit == -1) - { - continue; // no limit specified for this weapon - } - - bool needsAmmo = weaponItem->NeedsAmmo(); - - if (needsAmmo) - { - if (weaponItem->GetAmmo() > limit) - { - weaponItem->SetAmmo(limit); - } - } - else - { - // Weapons without ammonition - if (limit == 0) - { - // Limit set to 0, drop this weapon - itemsToRemove.Append(weaponItem); - } - } - } - - // Remove all marked items from this category - for (int w = 0; w < itemsToRemove.Num(); ++w) - { - weaponCategory->RemoveItem(itemsToRemove[w]); - } - - // Enforce regular inventory item limits - for (const idKeyValue* kv = campaignInfo->spawnArgs.MatchPrefix("item_"); - kv != NULL; kv = campaignInfo->spawnArgs.MatchPrefix("item_", kv)) - { - idStr indexStr = kv->GetKey(); - indexStr.StripLeadingOnce("item_"); - - int index = atoi(indexStr.c_str()); - - const idStr& itemName = kv->GetValue(); - int limit = campaignInfo->spawnArgs.GetInt(va("limit_%d", index), "-1"); - - // let difficulty-specific settings override this - limit = campaignInfo->spawnArgs.GetInt(diffPrefix + va("limit_%d", index), va("%d", limit)); - - // Item limit of -1 means: no limit - if (limit == -1) - { - continue; - } - - DM_LOG(LC_INVENTORY, LT_DEBUG)LOGSTRING("Trying to enforce inventory item limit: %s => max %d\r", itemName.c_str(), limit); - - CInventoryItemPtr item = Inventory()->GetItem(itemName); - - if (!item) - { - continue; // no item with that name - } - - if (item->IsPersistent() && item->GetCount() > limit) - { - ChangeInventoryItemCount(item->GetName(), item->Category()->GetName(), limit - item->GetCount()); - } - } - } -} - -void idPlayer::Event_Pausegame() -{ - gameLocal.PauseGame(true); -} - -void idPlayer::Event_Unpausegame() -{ - gameLocal.PauseGame(false); -} - -void idPlayer::Event_MissionSuccess() -{ - // Clear the persistent inventory, it might have old data from the previous mission - gameLocal.persistentPlayerInventory->Clear(); - - // Enfore item limits on mission end - drop everything exceeding the limits - EnforcePersistentInventoryItemLimits(); - - // Save current inventory into the persistent one - Inventory()->CopyTo(*gameLocal.persistentPlayerInventory); - - // Save the item entities of all persistent items - gameLocal.persistentPlayerInventory->SaveItemEntities(true); - - // Schedule the disconnect command, this needs to be done before issuing the save call - PostEventMS(&EV_DisconnectFromMission, 0); - - // Issue an automatic save at the end of this mission - // greebo: Don't do this immediately, the player PVS must be freed before saving! - gameLocal.m_TriggerFinalSave = true; -} - -void idPlayer::Event_DisconnectFromMission() -{ - // Set the gamestate - gameLocal.SetMissionResult(MISSION_COMPLETE); - gameLocal.sessionCommand = "disconnect"; -} - -void idPlayer::Event_TriggerMissionEnd() -{ - if (hudMessages.Num() > 0) - { - // There are still HUD messages pending, postpone this event - PostEventMS(&EV_TriggerMissionEnd, 3000); - return; - } - - gameLocal.PrepareForMissionEnd(); - - idVec4 fadeColor(0,0,0,1); - playerView.Fade(fadeColor, 1500); - - // Schedule an mission success event right after fadeout - PostEventMS(&EV_Mission_Success, 1500); -} - -void idPlayer::Event_GetLocation() -{ - idThread::ReturnEntity( GetLocation() ); -} - -void idPlayer::Event_StartGamePlayTimer() -{ - gameLocal.m_GamePlayTimer.Clear(); - gameLocal.m_GamePlayTimer.Start(); -} - -void idPlayer::Event_CheckAAS() -{ - if (gameLocal.GameState() >= GAMESTATE_ACTIVE) - { - idList aasNames; - - for (idAI* ai = gameLocal.spawnedAI.Next(); ai != NULL; ai = ai->aiNode.Next()) - { - if (ai->GetAAS() == NULL) - { - idStr aasName = ai->spawnArgs.GetString("use_aas"); - aasNames.AddUnique(aasName); - } - } - - for (int i = 0; i < aasNames.Num(); i++) - { - SendHUDMessage("Warning: " + aasNames[i] + " is out of date!"); - } - } -} - -void idPlayer::Event_ChangeWeaponProjectile(const char* weaponName, const char* projectileDefName) -{ - // Just wrap to the actual method - ChangeWeaponProjectile(weaponName, projectileDefName); -} - -void idPlayer::Event_ResetWeaponProjectile(const char* weaponName) -{ - ResetWeaponProjectile(weaponName); -} - -void idPlayer::Event_ChangeWeaponName(const char* weaponName, const char* newName) -{ - ChangeWeaponName(weaponName, newName); -} - -void idPlayer::Event_GetCurWeaponName() -{ - CInventoryWeaponItemPtr weaponItem = GetCurrentWeaponItem(); - if (weaponItem == NULL) return; - - idThread::ReturnString( weaponItem->GetWeaponName().c_str() ); -} - -void idPlayer::ClearActiveInventoryMap() -{ - idEntity* mapEnt = m_ActiveInventoryMapEnt.GetEntity(); - - if (mapEnt == NULL) return; - - // Call the method inventory_map::clear(entity userEnt) - idThread* thread = mapEnt->CallScriptFunctionArgs("clear", true, 0, "ee", mapEnt, this); - - if (thread != NULL) - { - // Run the thread at once - thread->Execute(); - } - - m_ActiveInventoryMapEnt = NULL; -} - -void idPlayer::Event_ClearActiveInventoryMap() -{ - ClearActiveInventoryMap(); -} - -void idPlayer::Event_SetActiveInventoryMapEnt(idEntity* mapEnt) -{ - // Check for a previously active map and clear it if necessary - if (m_ActiveInventoryMapEnt.GetEntity() != NULL) - { - ClearActiveInventoryMap(); - } - - m_ActiveInventoryMapEnt = mapEnt; -} - -void idPlayer::Event_GetFrobbed() -{ - idThread::ReturnEntity( m_FrobEntity.GetEntity() ); -} - -void idPlayer::Event_SetFrobOnlyUsedByInv( bool value ) -{ - m_bFrobOnlyUsedByInv = value; -} - -void idPlayer::Event_ProcessInterMissionTriggers() -{ - gameLocal.ProcessInterMissionTriggers(); -} diff --git a/game/player.h b/game/player.h deleted file mode 100644 index 7ea02c46a..000000000 --- a/game/player.h +++ /dev/null @@ -1,1419 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_PLAYER_H__ -#define __GAME_PLAYER_H__ - -#include "../DarkMod/ButtonStateTracker.h" -class CInventoryItem; -typedef boost::shared_ptr CInventoryItemPtr; - -class CInventoryWeaponItem; -typedef boost::shared_ptr CInventoryWeaponItemPtr; - -/* -=============================================================================== - - Player entity. - -=============================================================================== -*/ - -extern const idEventDef EV_Player_GetButtons; -extern const idEventDef EV_Player_GetMove; -extern const idEventDef EV_Player_GetViewAngles; -extern const idEventDef EV_Player_GetMouseGesture; -extern const idEventDef EV_Player_MouseGestureFinished; -extern const idEventDef EV_Player_StartMouseGesture; -extern const idEventDef EV_Player_StopMouseGesture; -extern const idEventDef EV_Player_ClearMouseDeadTime; -extern const idEventDef EV_Player_EnableWeapon; -extern const idEventDef EV_Player_DisableWeapon; -extern const idEventDef EV_Player_ExitTeleporter; -extern const idEventDef EV_Player_SelectWeapon; -extern const idEventDef EV_SpectatorTouch; -extern const idEventDef EV_Player_PlayStartSound; -extern const idEventDef EV_Player_DeathMenu; -extern const idEventDef EV_Player_MissionFailed; -extern const idEventDef EV_Player_GiveHealthPool; -extern const idEventDef EV_Player_WasDamaged; -extern const idEventDef EV_Mission_Success; -extern const idEventDef EV_TriggerMissionEnd; -extern const idEventDef EV_Player_GetLocation; -extern const idEventDef EV_Player_GetFrobbed; -extern const idEventDef EV_Player_SetFrobOnlyUsedByInv; - -const float THIRD_PERSON_FOCUS_DISTANCE = 512.0f; -const int LAND_DEFLECT_TIME = 150; -const int LAND_RETURN_TIME = 300; -const int FOCUS_TIME = 300; -const int FOCUS_GUI_TIME = 500; - -#define TDM_PLAYER_WEAPON_CATEGORY "Weapons" -#define TDM_PLAYER_MAPS_CATEGORY "#str_02390" - -#define ARROW_WEAPON_INDEX_BEGIN 3 // grayman #597 - weapons at or above this index are arrows - -const int DEAD_HEARTRATE = 0; // fall to as you die -const int LOWHEALTH_HEARTRATE_ADJ = 20; // -const int DYING_HEARTRATE = 30; // used for volumen calc when dying/dead -const int BASE_HEARTRATE = 70; // default -const int ZEROSTAMINA_HEARTRATE = 115; // no stamina -const int MAX_HEARTRATE = 130; // maximum -const int ZERO_VOLUME = -40; // volume at zero -const int DMG_VOLUME = 5; // volume when taking damage -const int DEATH_VOLUME = 15; // volume at death - -const int SAVING_THROW_TIME = 5000; // maximum one "saving throw" every five seconds - -const int ASYNC_PLAYER_INV_AMMO_BITS = idMath::BitsForInteger( 999 ); // 9 bits to cover the range [0, 999] -const int ASYNC_PLAYER_INV_CLIP_BITS = -7; // -7 bits to cover the range [-1, 60] - -// powerups - the "type" in item .def must match -enum { - BERSERK = 0, - INVISIBILITY, - MEGAHEALTH, - ADRENALINE, - MAX_POWERUPS -}; - -// powerup modifiers -enum { - SPEED = 0, - PROJECTILE_DAMAGE, - MELEE_DAMAGE, - MELEE_DISTANCE -}; - -// influence levels -enum { - INFLUENCE_NONE = 0, // none - INFLUENCE_LEVEL1, // no gun or hud - INFLUENCE_LEVEL2, // no gun, hud, movement - INFLUENCE_LEVEL3, // slow player movement -}; - -/** -* Possible mouse directions, for mouse gestures -**/ -typedef enum { - MOUSEDIR_NONE, - MOUSEDIR_LEFT, - MOUSEDIR_UP_LEFT, - MOUSEDIR_UP, - MOUSEDIR_UP_RIGHT, - MOUSEDIR_RIGHT, - MOUSEDIR_DOWN_RIGHT, - MOUSEDIR_DOWN, - MOUSEDIR_DOWN_LEFT -} EMouseDir; - -/** -* Possible tests, for mouse gestues -**/ -typedef enum -{ - MOUSETEST_UPDOWN, - MOUSETEST_LEFTRIGHT, - MOUSETEST_4DIR, // up down left right - MOUSETEST_8DIR, // 4 DIR + the diagonals -} EMouseTest; - -/** -* Mouse gesture data -**/ -typedef struct SMouseGesture_s -{ - bool bActive; // we are currently checking a mouse gesture - EMouseTest test; // defines which directions we're testing for movement - bool bInverted; // mouse motions are inverted - - int key; // key being checked - int thresh; // mouse input threshold required to decide - int DecideTime; // time in ms before we auto-decide (default -1, wait forever) - int DeadTime; // time over which the response is dampened, can be greater than decide time - - int started; // time in ms at which we started - idVec2 StartPos; // mouse position at which we started - idVec2 motion; // accumulated mouse motion over the gesture - EMouseDir result; // result of the last gesture, using the MOUSEDIR_* enum - - SMouseGesture_s( void ) - { - bActive = false; - test = MOUSETEST_LEFTRIGHT; - bInverted = false; - key = 0; - thresh = 0; - DecideTime = -1; - DeadTime = 0; - started = 0; - StartPos = vec2_zero; - motion = vec2_zero; - result = MOUSEDIR_RIGHT; - }; - - void Save(idSaveGame *savefile) const - { - savefile->WriteBool( bActive ); - savefile->WriteInt( (int) test ); - savefile->WriteBool( bInverted ); - savefile->WriteInt( key ); - savefile->WriteInt( thresh ); - savefile->WriteInt( DecideTime ); - savefile->WriteInt( started ); - savefile->WriteVec2( StartPos ); - savefile->WriteVec2( motion ); - savefile->WriteInt( (int) result ); - }; - void Restore(idRestoreGame *savefile) - { - int tempInt; - - savefile->ReadBool(bActive); - savefile->ReadInt( tempInt ); - test = (EMouseTest) tempInt; - savefile->ReadBool( bInverted ); - savefile->ReadInt( key ); - savefile->ReadInt( thresh ); - savefile->ReadInt( DecideTime ); - savefile->ReadInt( started ); - savefile->ReadVec2( StartPos ); - savefile->ReadVec2( motion ); - savefile->ReadInt( tempInt ); - result = (EMouseDir) tempInt; - }; -} SMouseGesture; - -// Player control immobilization categories. -enum { - EIM_ALL = -1, - EIM_UPDATE = BIT( 0), // For internal use only. True if immobilization needs to be recalculated. - EIM_VIEW_ANGLE = BIT( 1), // Looking around - EIM_MOVEMENT = BIT( 2), // Forwards/backwards, strafing and swimming. - EIM_CROUCH = BIT( 3), // Crouching. - EIM_CROUCH_HOLD = BIT( 4), // Prevent changes to crouching state. (NYI) - EIM_JUMP = BIT( 5), // Jumping. - EIM_MANTLE = BIT( 6), // Mantling (excluding jumping) - EIM_CLIMB = BIT( 7), // Climbing ladders, ropes and mantling. - EIM_FROB = BIT( 8), // Frobbing. - EIM_FROB_HILIGHT = BIT( 9), // Frobbing AND frob hilighting (not sure if needed or if EIM_FROB can disable hilight also) - EIM_FROB_COMPLEX = BIT(10), // Frobbing of "complex" items (not a door, lever, button, etc) - EIM_ATTACK = BIT(11), // Using weapons - EIM_ATTACK_RANGED = BIT(12), // Using ranged weapons (bows) - EIM_WEAPON_SELECT = BIT(13), // Selecting weapons. - EIM_ITEM_USE = BIT(14), // Using items - EIM_ITEM_SELECT = BIT(15), // Selecting items. - EIM_ITEM_DROP = BIT(16), // Dropping inventory items. -}; - -typedef struct { - int time; - idVec3 dir; // scaled larger for running -} loggedAccel_t; - -typedef struct { - int areaNum; - idVec3 pos; -} aasLocation_t; - -class idPlayer : public idActor { -public: - enum { - EVENT_IMPULSE = idEntity::EVENT_MAXEVENTS, - EVENT_EXIT_TELEPORTER, - EVENT_ABORT_TELEPORTER, - EVENT_POWERUP, - EVENT_SPECTATE, - EVENT_MAXEVENTS - }; - - usercmd_t usercmd; - - class idPlayerView playerView; // handles damage kicks and effects - - bool noclip; - bool godmode; - - bool spawnAnglesSet; // on first usercmd, we must set deltaAngles - idAngles spawnAngles; - idAngles viewAngles; // player view angles - idAngles cmdAngles; // player cmd angles - - int buttonMask; - int oldButtons; - int oldFlags; - - int lastHitTime; // last time projectile fired by player hit target - int lastSndHitTime; // MP hit sound - != lastHitTime because we throttle - int lastSavingThrowTime; // for the "free miss" effect - - // The GUI of the lockpick visualisation HUD - int lockpickHUD; - - // angua: this is true when the player lands after jumping or a fall - // to play the jumping footstep sounds - bool hasLanded; - - idScriptBool AI_FORWARD; - idScriptBool AI_BACKWARD; - idScriptBool AI_STRAFE_LEFT; - idScriptBool AI_STRAFE_RIGHT; - idScriptBool AI_ATTACK_HELD; - idScriptBool AI_BLOCK_HELD; - idScriptBool AI_WEAPON_FIRED; - idScriptBool AI_WEAPON_BLOCKED; - idScriptBool AI_JUMP; - idScriptBool AI_CROUCH; - idScriptBool AI_ONGROUND; - idScriptBool AI_ONLADDER; - //idScriptBool AI_DEAD; // is defined on idActor now - idScriptBool AI_RUN; - idScriptBool AI_PAIN; - idScriptBool AI_HARDLANDING; - idScriptBool AI_SOFTLANDING; - idScriptBool AI_RELOAD; - idScriptBool AI_TELEPORT; - idScriptBool AI_TURN_LEFT; - idScriptBool AI_TURN_RIGHT; - /** - * Leaning - **/ - idScriptBool AI_LEAN_LEFT; - idScriptBool AI_LEAN_RIGHT; - idScriptBool AI_LEAN_FORWARD; - - /** - * Ishtvan: Set to true for the duration of the frame if the AI takes damage - * (more reliable than AI_PAIN) - **/ - bool m_bDamagedThisFrame; - - /** - * Set to true if the player is creeping - **/ - idScriptBool AI_CREEP; - - /** - * greebo: Helper class keeping track of which buttons are currently - * held down and which got released. - * calls PerformButtonRelease() on this entity on this occasion. - */ - ButtonStateTracker m_ButtonStateTracker; - - /** - * Player's current/last mouse gesture: - **/ - SMouseGesture m_MouseGesture; - - // ---- Frob-related members (moved from CDarkmodPlayer to here) ---- - - /** - * Ishtvan: The target that we initially started pressing frob on - * keep track of this for things that react to frob held, so we don't - * move from one target to another without first letting go of frob - **/ - idEntityPtr m_FrobPressedTarget; - - /** - * FrobEntity is NULL when no entity is highlighted. Otherwise it will point - * to the entity which is currently highlighted. - */ - idEntityPtr m_FrobEntity; - - /** - * Frobbed joint and frobbed clipmodel ID if an AF has been frobbed - * Set to INVALID and -1 if the frobbed entity is not an AF - **/ - jointHandle_t m_FrobJoint; - int m_FrobID; - - /** - * The trace that was done for frobbing - * Read off by idEntity::UpdateFrob when something has been newly frobbed - **/ - trace_t m_FrobTrace; - - /** - * If true, this only allows frobbing of entities that can be used by - * the currently selected inventory item. - * This also disables normal frob actions on pressing frob, - * only allowing the "used by" action. - **/ - bool m_bFrobOnlyUsedByInv; - - /** - * Set to true if the player is holding an item with the Grabber - **/ - bool m_bGrabberActive; - - /** - * Set to true if the player is dragging a body - * NOT YET IMPLEMENTED - **/ - bool m_bDraggingBody; - - /** - * Set to true if the player is shouldering a body - **/ - bool m_bShoulderingBody; - - - // angua: whether the player should be crouching - bool m_IdealCrouchState; - - // angua: this is true when the player is holding the crocuh button - // or toggle crouch is active - bool m_CrouchIntent; - - - /** - * Hack to fix the leaning test of key-releases - * Timestamp to wait a few frames before testing for button release - **/ - int m_LeanButtonTimeStamp; - - idEntityPtr weapon; - idUserInterface * hud; // MP: is NULL if not local player - - // greebo: This is true if the inventory HUD needs a refresh - bool inventoryHUDNeedsUpdate; - - // greebo: A list of HUD messages which are displayed one after the other - idList hudMessages; - idList inventoryPickedUpMessages; - - int weapon_fists; - - bool m_HeartBeatAllow; /// disable hearbeat except when dying or drowning - Need this to track state - int heartRate; - idInterpolate heartInfo; - int lastHeartAdjust; - int lastHeartBeat; - int lastDmgTime; - int deathClearContentsTime; - bool doingDeathSkin; - int lastArmorPulse; // lastDmgTime if we had armor at time of hit - float stamina; - float healthPool; // amount of health to give over time - int nextHealthPulse; - bool healthPulse; - bool healthTake; - int nextHealthTake; - // greebo: added these to make the interval customisable - int healthPoolStepAmount; // The amount of healing in each pulse - int healthPoolTimeInterval; // The time between health pulses - float healthPoolTimeIntervalFactor; // The factor to increase the time interval after each pulse - - - bool hiddenWeapon; // if the weapon is hidden ( in noWeapons maps ) - - // mp stuff - static idVec3 colorBarTable[ 5 ]; - int spectator; - idVec3 colorBar; // used for scoreboard and hud display - int colorBarIndex; - bool scoreBoardOpen; - bool forceScoreBoard; - bool forceRespawn; - bool spectating; - int lastSpectateTeleport; - bool lastHitToggle; - bool forcedReady; - bool wantSpectate; // from userInfo - bool weaponGone; // force stop firing - bool useInitialSpawns; // toggled by a map restart to be active for the first game spawn - int latchedTeam; // need to track when team gets changed - int tourneyRank; // for tourney cycling - the higher, the more likely to play next - server - int tourneyLine; // client side - our spot in the wait line. 0 means no info. - int spawnedTime; // when client first enters the game - - idEntityPtr teleportEntity; // while being teleported, this is set to the entity we'll use for exit - int teleportKiller; // entity number of an entity killing us at teleporter exit - bool lastManOver; // can't respawn in last man anymore (srv only) - bool lastManPlayAgain; // play again when end game delay is cancelled out before expiring (srv only) - bool lastManPresent; // true when player was in when game started (spectators can't join a running LMS) - bool isLagged; // replicated from server, true if packets haven't been received from client. - bool isChatting; // replicated from server, true if the player is chatting. - - // timers - int minRespawnTime; // can respawn when time > this, force after g_forcerespawn - int maxRespawnTime; // force respawn after this time - - // the first person view values are always calculated, even - // if a third person view is used - idVec3 firstPersonViewOrigin; - idMat3 firstPersonViewAxis; - - idDragEntity dragEntity; - - // A pointer to our weaponslot. - CInventoryCursorPtr m_WeaponCursor; - // A pointer to the current map/floorplan. - CInventoryCursorPtr m_MapCursor; - // The name of the item that was current before pressing inventory clear - idStr m_LastItemNameBeforeClear; - - // The currently active inventory map entity - idEntityPtr m_ActiveInventoryMapEnt; - - int m_WaitUntilReadyGuiHandle; - int m_WaitUntilReadyGuiTime; - -public: - CLASS_PROTOTYPE( idPlayer ); - - idPlayer(); - virtual ~idPlayer(); - - void Spawn( void ); - void Think( void ); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - virtual void Hide( void ); - virtual void Show( void ); - - void Init( void ); - void PrepareForRestart( void ); - virtual void Restart( void ); - void LinkScriptVariables( void ); - void SetupWeaponEntity( void ); - void SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles ); - void SpawnFromSpawnSpot( void ); - void SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles ); - void SetClipModel( void ); // spectator mode uses a different bbox size - - void SavePersistantInfo( void ); - void RestorePersistantInfo( void ); - - bool UserInfoChanged( bool canModify ); - idDict * GetUserInfo( void ); - bool BalanceTDM( void ); - - void CacheWeapons( void ); - - void EnterCinematic( void ); - void ExitCinematic( void ); - bool HandleESC( void ); - bool SkipCinematic( void ); - - int GetImmobilization(); - int GetImmobilization( const char *source ); - void SetImmobilization( const char *source, int type ); - - // greebo: Consolidate these three hinderances into one, selectable via an enum? - float GetHinderance(); - float GetTurnHinderance(); - float GetJumpHinderance(); - - /** - * Sets the linear movement hinderance. - * This should be a fraction relative to max movement speed - * mCap values multiply together with those of other hinderances, aCap is an absolute cap - * for this particular hinderance. - **/ - void SetHinderance( const char *source, float mCap, float aCap ); - /** - * Same as SetHinderance, but applies to angular view turning speed - **/ - void SetTurnHinderance( const char *source, float mCap, float aCap ); - - void SetJumpHinderance( const char *source, float mCap, float aCap ); - - // greebo: Sets the "player is pushing something heavy" state to the given bool (virtual override) - virtual void SetIsPushing(bool isPushing); - // Returns whether the player is currently pushing something heavy (virtual override) - virtual bool IsPushing(); - - // Called by the grabber to signal that we start/stop shouldering a body - void OnStartShoulderingBody(idEntity* body); - void OnStopShoulderingBody(idEntity* body); - - /** - * greebo: Plays the footstep sound according to the current movement type. - */ - virtual void PlayFootStepSound(); - - void UpdateConditions( void ); - void SetViewAngles( const idAngles &angles ); - - // delta view angles to allow movers to rotate the view of the player - void UpdateDeltaViewAngles( const idAngles &angles ); - - /** - * Get or set the listener location for the player, in world coordinates - **/ - idVec3 GetListenerLoc( void ); - void SetListenerLoc( idVec3 loc ); - - /** - * Set/Get the door listening location - **/ - void SetDoorListenLoc( idVec3 loc ); - idVec3 GetDoorListenLoc( void ); - - - void CrashLand( const idVec3 &savedOrigin, const idVec3 &savedVelocity ); - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - - virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const; - virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos ); - virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ); - void CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef, - const float damageScale, const int location, int *health, int *armor ); - virtual void Damage - ( - idEntity *inflictor, idEntity *attacker, const idVec3 &dir, - const char *damageDefName, const float damageScale, const int location, - trace_t *collision = NULL - ); - - // use exitEntityNum to specify a teleport with private camera view and delayed exit - virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ); - - void Kill( bool delayRespawn, bool nodamage ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - void StartFxOnBone(const char *fx, const char *bone); - - renderView_t * GetRenderView( void ); - void CalculateRenderView( void ); // called every tic by player code - void CalculateFirstPersonView( void ); - - void DrawHUD( idUserInterface *hud ); - - void WeaponFireFeedback( const idDict *weaponDef ); - - float DefaultFov( void ) const; - float CalcFov( bool honorZoom ); - void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ); - idVec3 GetEyePosition( void ) const; - void GetViewPos( idVec3 &origin, idMat3 &axis ) const; - void OffsetThirdPersonView( float angle, float range, float height, bool clip ); - - bool Give( const char *statname, const char *value ); - void GiveItem( const char *name ); - void GiveHealthPool( float amt ); - - bool GivePowerUp( int powerup, int time ); - float PowerUpModifier( int type ); - - int SlotForWeapon( const char *weaponName ); - void Reload( void ); - void NextWeapon( void ); - void NextBestWeapon( void ); - void PrevWeapon( void ); - - // greebo: Returns the highest weapon index in the weapon inventory category (-1 if empty/error) - // Traverses the entire category, so this is not the fastest code - int GetHightestWeaponIndex(); - - // returns FALSE if the weapon with the requested index could not be selected - bool SelectWeapon( int num, bool force ); - - /** - * greebo: This returns the current weapon being focused at by the weapon inventory cursor. - * Can return NULL, but should not in 99% of the cases. - */ - CInventoryWeaponItemPtr GetCurrentWeaponItem(); - - /** - * greebo: Returns the inventory weapon item with the given name (e.g. "shortsword" or "broadhead"). - * This can actually return NULL if no weapon item with the given name exists. - */ - CInventoryWeaponItemPtr GetWeaponItem(const idStr& weaponName); - - void DropWeapon( bool died ) ; - void StealWeapon( idPlayer *player ); - void AddProjectilesFired( int count ); - void AddProjectileHits( int count ); - void SetLastHitTime( int time ); - void LowerWeapon( void ); - void RaiseWeapon( void ); - void WeaponLoweringCallback( void ); - void WeaponRisingCallback( void ); - void RemoveWeapon( const char *weap ); - bool CanShowWeaponViewmodel( void ) const; - // greebo: This method updates the player's movement hinderance when weapons are drawn - void UpdateWeaponEncumbrance(); - - void AdjustHeartRate( int target, float timeInSecs, float delay, bool force ); - void SetCurrentHeartRate( void ); - int GetBaseHeartRate( void ); - void UpdateAir( void ); - - /** - * This updates the audiovisual effects when the player is underwater - */ - void UpdateUnderWaterEffects(); - - /** - * greebo: Accessor methods for the airTicks member variable. - */ - int getAirTicks() const; - void setAirTicks(int airTicks); - - virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src ); -#if 0 - bool GuiActive( void ) { return focusGUIent != NULL; } -#endif - - void PerformImpulse( int impulse ); - - /** - * greebo: This gets called by the ButtonStateTracker helper class - * whenever a key is released. - * - * @impulse: The impulse number - * @holdTime: The time the button has been held down - */ - void PerformKeyRelease(int impulse, int holdTime); - - /** - * sparhawk: This gets called by the ButtonStateTracker helper class - * whenever a key is held. - * - * @impulse: The impulse number - * @holdTime: The time the button has been held down - */ - void PerformKeyRepeat(int impulse, int holdTime); - - /** - * Ishtvan: Start tracking a mouse gesture that started when the key "impulse" was pressed - * Discretizes analog mouse movement into a few different gesture possibilities - * "Impulse" arg can also be a "button," see the UB_* enum in usercmdgen.h - * - * Waits until the threshold mouse input is reached before deciding - * The test argument determines what to test for (up/down, left/right, etc) - * determined by the enum EMouseTest - * TurnHinderane sets the max palyer view turn rate when checking this mouse gesture - * 0 => player view locked, 1.0 => no effect on view turning - * DecideTime is the time in milliseconds after which the mouse gesture is auto-decided, - * in the event that the mouse movement threshold was not reached. - * For now, only one mouse gesture check at a time. - **/ - void StartMouseGesture( int impulse, int thresh, EMouseTest test, bool bInverted, float TurnHinderance, int DecideTime = -1, int DeadTime = 0 ); - void UpdateMouseGesture( void ); - void StopMouseGesture( void ); - /** - * Returns the result of the last mouse gesture (MOUSEDIR_* enum) - **/ - EMouseDir GetMouseGesture( void ); - - void Spectate( bool spectate ); - void ToggleScoreboard( void ); - - void RouteGuiMouse( idUserInterface *gui ); - void UpdateHUD(); - - // greebo: Checks if any messages are still pending. - void UpdateHUDMessages(); - - // Updates the HUD for the inventory items - void UpdateInventoryHUD(); - void UpdateInventoryPickedUpMessages(); - - void SetInfluenceFov( float fov ); - void SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent ); - void SetInfluenceLevel( int level ); - int GetInfluenceLevel( void ) { return influenceActive; }; - void SetPrivateCameraView( idCamera *camView ); - idCamera * GetPrivateCameraView( void ) const { return privateCameraView; } - void StartFxFov( float duration ); - void UpdateHudWeapon( bool flashWeapon = true ); - void UpdateHudStats( idUserInterface *hud ); - void UpdateHudAmmo(); - - virtual void ClientPredictionThink( void ); - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - void WritePlayerStateToSnapshot( idBitMsgDelta &msg ) const; - void ReadPlayerStateFromSnapshot( const idBitMsgDelta &msg ); - - virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg ); - - virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ); - virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis ); - - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - bool IsReady( void ); - bool IsRespawning( void ); - bool IsInTeleport( void ); - - idEntity *GetInfluenceEntity( void ) { return influenceEntity; }; - const idMaterial *GetInfluenceMaterial( void ) { return influenceMaterial; }; - float GetInfluenceRadius( void ) { return influenceRadius; }; - - // server side work for in/out of spectate. takes care of spawning it into the world as well - void ServerSpectate( bool spectate ); - // for very specific usage. != GetPhysics() - idPhysics *GetPlayerPhysics( void ); - void TeleportDeath( int killer ); - void SetLeader( bool lead ); - bool IsLeader( void ); - - void UpdateSkinSetup( bool restart ); - - bool OnLadder( void ) const; - // Virtal override of idActor::OnElevator() - virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; - - virtual void UpdatePlayerIcons( void ); - virtual void DrawPlayerIcons( void ); - virtual void HidePlayerIcons( void ); - bool NeedsIcon( void ); - - bool SelfSmooth( void ); - - void SetSelfSmooth( bool b ); - - - /** - * Do the frobbing trace and bounds intersection to mark entities as frobable - **/ - void PerformFrobCheck(); - - /** - * greebo: Performs a frob action on the given entity. The above method - * PerformFrob() without arguments redirects the call to this one. - * This method might be invoked by scripts as well to simulate - * a frob action without having the player to hit any buttons. - * - * @impulseState: the button state of the frob key. Pass EPressed if you - * want to simulate a one-time frob event. - * - * Hold time: The amount of time the button has been held, if applicable (0 by default) - */ - void PerformFrob(EImpulseState impulseState, idEntity* frobbed); - - // Gets called when the player hits the frob button. - void PerformFrob(); - // Gets repeatedly called when the player holds down the frob button - void PerformFrobKeyRepeat(int holdTime); - // Gets called when the player releases the frob button - void PerformFrobKeyRelease(int holdTime); - - - // angua: Set ideal crouch state - void EvaluateCrouch(); - - ID_INLINE bool GetIdealCrouchState() - { - return m_IdealCrouchState; - } - - - /** - * CalculateWeakLightgem (formerly AdjustLightgem) will do the "weak" - * lightgem calculation, based on a list of lights, not using the rendershot. - */ - void CalculateWeakLightgem(); - - // Register/unregister a light for the weak lightgem calculation - int AddLight(idLight* lightToAdd); - int RemoveLight(idLight* lightToRemove); - - /** - * GetHeadEntity will return the entity for the head of the playermodel - */ - idEntity *GetHeadEntity(void) { return head.GetEntity(); }; - - /** - * Update movement volumes: Reads the movement volume - * modifiers from cvars (for now) - **/ - void UpdateMoveVolumes( void ); - - /** - * Get the volume modifier for a given movement type - **/ - float GetMovementVolMod( void ); - - /** - * greebo: Cycles through the inventory and opens the next map. - * If no map is displayed currently, the first map is toggled. - * If there is a map currently on the HUD, the next one is chosen. - * If there is no next map, the map is closed again. - */ - void NextInventoryMap(); - - // Shows/hides the in-game objectives GUI - void ToggleObjectivesGUI(); - - /** - * Physically test whether an item would fit in the world when - * dropped with its center of mass (not origin!) at the specified point - * Initially tries the supplied orientation, and tries all possible 90 degree - * rotations, overwriting the supplied orientation with the one that fits - **/ - bool TestDropItemRotations( idEntity *ent, idVec3 viewPoint, idVec3 DropPoint, idMat3 &DropAxis ); - - /** - * Uses the currently held/selected item. - **/ - void UseInventoryItem(); - - /** - * Tries to drop the currently held/selected item. - **/ - void DropInventoryItem(); - - /** - * Physically put the item in the hands, returns true if it fits - * Called by DropInventoryItem, also called from Grabber::Dequip - * When dropping an item from the inventory, item argument should be supplied - * When dropping other objects (e.g., equipped junk item), it need not be - **/ - bool DropToHands( idEntity *ent, CInventoryItemPtr item = CInventoryItemPtr() ); - - // Performs the inventory action for onButtonRelease - void InventoryUseKeyRelease(int holdTime); - - // Uses a specific inventory item - bool UseInventoryItem(EImpulseState nState, const CInventoryItemPtr& item, int holdTime, bool isFrobUse); - - // Changes the inventory selection to the item with the given name - // Returns false if there is no such item - bool SelectInventoryItem(const idStr& name); - - // Override idEntity method to get notified upon item changes - virtual void OnInventoryItemChanged(); - - // Override idEntity method: the "selection changed" event is called after the inventory cursor has changed its position - virtual void OnInventorySelectionChanged(const CInventoryItemPtr& prevItem); - - /** - * Overload the idEntity::AddToInventory method to catch weapon items. - */ - virtual CInventoryItemPtr AddToInventory(idEntity *ent); - - /** - * greebo: Attempts to put the current grabber item back into the inventory. - * - * @returns: TRUE if an item was put back, FALSE if the grabber hands are empty. - */ - bool AddGrabberEntityToInventory(); - - // Returns the current lightgem value - int GetCurrentLightgemValue() { return m_LightgemValue; } - - // Runs the (strong) lightgem calculation, returns the resulting value - int ProcessLightgem(bool processing); - - /** - * greebo: Returns the lightgem modifier value according to the currently selected inventory items - * and other factors (like crouching). Returns a value between 0 and DARKMOD_LG_MAX. - * This value is added to the calculated lightgem value. - */ - int GetLightgemModifier(int curLightgemValue); - - /// Am I a ranged threat to the given entity (or entities in general if target is NULL)? - float RangedThreatTo(idEntity* target); - - // greebo: Sends a message to the HUD (used for "Game Saved" and such). - void SendHUDMessage(const idStr& text); - - // greebo: Sends a "picked up so and so" message to the inventory HUD - void SendInventoryPickedUpMessage(const idStr& text); - - // Updates the in-game Objectives GUI, if visible (otherwise nothing happens) - void UpdateObjectivesGUI(); - - void PrintDebugHUD(); - - // Runs the "Click when ready" GUI, returns TRUE if the player is ready - bool WaitUntilReady(); - - /** - * greebo: Sets the time between health "pulses" if the healthPool > 0 - * - * @newTimeInterval: the new value for the time interval - * @factor: The factor that the time interval is being multiplied with after each pulse. - * This can be used to increase the time between pulses gradually. - * @stepAmount: The amount of health to be taken from the healthpool at each step - */ - void setHealthPoolTimeInterval(int newTimeInterval, float factor, int stepAmount); - - - /** - * Get the current idLocation entity for the location the player is in - **/ - idLocationEntity *GetLocation( void ); - -protected: - /** - * greebo: This creates all the default inventory items and adds the weapons. - */ - void SetupInventory(); - - void AddPersistentInventoryItems(); - - // greebo: Methods used to manage the GUI layer for the in-game objectives - void CreateObjectivesGUI(); - void DestroyObjectivesGUI(); - - /** - * greebo: Parses the spawnargs for any weapon definitions and adds them - * to the inventory. Expects the weapon category to exist. - */ - void AddWeaponsToInventory(); - - // Sorts the weapon item category by weapon index - void SortWeaponItems(); - -private: - jointHandle_t hipJoint; - jointHandle_t chestJoint; - jointHandle_t headJoint; - - idPhysics_Player physicsObj; // player physics - - idList aasLocation; // for AI tracking the player - - int bobFoot; - float bobFrac; - float bobfracsin; - int bobCycle; // for view bobbing and footstep generation - float xyspeed; - int stepUpTime; - float stepUpDelta; - float idealLegsYaw; - float legsYaw; - bool legsForward; - float oldViewYaw; - idAngles viewBobAngles; - idVec3 viewBob; - int landChange; - int landTime; - int lastFootstepPlaytime; - bool isPushing; // is true while the player is pushing something heavy - - int currentWeapon; - int idealWeapon; - int previousWeapon; - int weaponSwitchTime; - bool weaponEnabled; - bool showWeaponViewModel; - - const idDeclSkin * skin; - const idDeclSkin * powerUpSkin; - idStr baseSkinName; - - int numProjectilesFired; // number of projectiles fired - int numProjectileHits; // number of hits on mobs - - bool airless; - int airTics; // set to pm_airTics at start, drops in vacuum - int lastAirDamage; - - bool underWaterEffectsActive; // True, if the under water effects are in charge - int underWaterGUIHandle; // The handle of the GUI underwater overlay - - bool gibDeath; - bool gibsLaunched; - idVec3 gibsDir; - int m_InventoryOverlay; - - // The GUI handle used by the in-game objectives display - int objectivesOverlay; - - idInterpolate zoomFov; - idInterpolate centerView; - bool fxFov; - - float influenceFov; - int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement - idEntity * influenceEntity; - const idMaterial * influenceMaterial; - float influenceRadius; - const idDeclSkin * influenceSkin; - - idCamera * privateCameraView; - - /** - * Location of the player's ears for sound rendering - **/ - idVec3 m_ListenerLoc; - - /** - * Location of the player's ear point when the player is leaning against - * a door (i.e., a point on the other side of the door) - **/ - idVec3 m_DoorListenLoc; - - /** - * m_immobilization keeps track of sources of immobilization. - * m_immobilizationCache caches the total immobilization so it - * only gets recalculated when something is changed. - **/ - idDict m_immobilization; - int m_immobilizationCache; - - /** - * m_hinderance keeps track of sources of hinderance. (slowing the player) - * m_hinderanceCache caches the current hinderance level so it - * only gets recalculated when something is changed. - **/ - idDict m_hinderance; - float m_hinderanceCache; - - /** - * m_TurnHinderance keeps track of sources of turn hinderance. - * These slow down the rate at which the player can turn their view - * m_TurnHinderanceCache works the same as m_hinderanceCache above - **/ - idDict m_TurnHinderance; - float m_TurnHinderanceCache; - - /** - * m_JumpHinderance keeps track of sources of jump height hinderance. - * These limit the height which the player can jump. - * m_JumpHinderanceCache works the same as m_hinderanceCache above - **/ - idDict m_JumpHinderance; - float m_JumpHinderanceCache; - - /** - * greebo: This is the list of named lightgem modifier values. These can be accessed - * via script events to allow several modifiers to be active at the same time. - * To save for performance, the sum of these values is stored in m_LightgemModifier - */ - std::map m_LightgemModifierList; - - // greebo: The sum of the values in the above list - int m_LightgemModifier; - - /** - * Each light entity must register here itself. This is used - * to calculate the value for the weak lightgem. - */ - idList m_LightList; - - /** - * LightgemValue determines the level of visibility of the player. - * This value is used to light up the lightgem and is defined as - * DARKMOD_LG_MIN (1) <= N <= DARKMOG_LG_MAX (32) - */ - int m_LightgemValue; - - /** - * Contains the last lightgem value. This is stored for interleaving. - */ - float m_fColVal; - float m_fBlendColVal; // Store the result for smooth fading of lightgem - J.C.Denton - - // An integer keeping track of the lightgem interleaving - int m_LightgemInterleave; - - // grayman #597 - ignore attack button if depressed, but weapon has been lowered - bool ignoreWeaponAttack; - - static const int NUM_LOGGED_VIEW_ANGLES = 64; // for weapon turning angle offsets - idAngles loggedViewAngles[NUM_LOGGED_VIEW_ANGLES]; // [gameLocal.framenum&(LOGGED_VIEW_ANGLES-1)] - static const int NUM_LOGGED_ACCELS = 16; // for weapon turning angle offsets - loggedAccel_t loggedAccel[NUM_LOGGED_ACCELS]; // [currentLoggedAccel & (NUM_LOGGED_ACCELS-1)] - int currentLoggedAccel; - - // if there is a focusGUIent, the attack button will be changed into mouse clicks -#if 0 - idEntity * focusGUIent; - idUserInterface * focusUI; // focusGUIent->renderEntity.gui, gui2, or gui3 - idAI * focusCharacter; - int talkCursor; // show the state of the focusCharacter (0 == can't talk/dead, 1 == ready to talk, 2 == busy talking) - int focusTime; - idAFEntity_Vehicle * focusVehicle; -#endif - idUserInterface * cursor; - - // full screen guis track mouse movements directly - int oldMouseX; - int oldMouseY; - - bool tipUp; - - int lastDamageDef; - idVec3 lastDamageDir; - int lastDamageLocation; - int smoothedFrame; - bool smoothedOriginUpdated; - idVec3 smoothedOrigin; - idAngles smoothedAngles; - - // mp - bool ready; // from userInfo - bool respawning; // set to true while in SpawnToPoint for telefrag checks - bool leader; // for sudden death situations - int lastSpectateChange; - int lastTeleFX; - unsigned int lastSnapshotSequence; // track state hitches on clients - bool weaponCatchup; // raise up the weapon silently ( state catchups ) - int MPAim; // player num in aim - int lastMPAim; - int lastMPAimTime; // last time the aim changed - int MPAimFadeTime; // for GUI fade - bool MPAimHighlight; - bool isTelefragged; // proper obituaries - - idPlayerIcon playerIcon; - - bool selfSmooth; - - - void LookAtKiller( idEntity *inflictor, idEntity *attacker ); - - void StopFiring( void ); - void FireWeapon( void ); - void BlockWeapon( void ); - void Weapon_Combat( void ); -#if 0 - void Weapon_NPC( void ); -#endif - void Weapon_GUI( void ); - void UpdateWeapon( void ); - - /** - * greebo: Changes the projectileDef name of the weapon inventory item with the given name. - * The name is defined in the "inv_weapon_name" spawnarg in the weaponDef. - */ - void ChangeWeaponProjectile(const idStr& weaponName, const idStr& projectileDefName); - - // greebo: Resets the weapon projectile as originally defined in the weaponDef - void ResetWeaponProjectile(const idStr& weaponName); - - /** - * greebo: Changes the name of the given weapon item to a new string. Pass an empty string "" to this - * function to reset the name to the value defined in the weaponDef. - */ - void ChangeWeaponName(const idStr& weaponName, const idStr& displayName); - - void UpdateSpectating( void ); - void SpectateFreeFly( bool force ); // ignore the timeout to force when followed spec is no longer valid - void SpectateCycle( void ); - idAngles GunTurningOffset( void ); - idVec3 GunAcceleratingOffset( void ); - - void UseObjects( void ); - void BobCycle( const idVec3 &pushVelocity ); - void UpdateViewAngles( void ); - void EvaluateControls( void ); - void AdjustSpeed( void ); - void AdjustBodyAngles( void ); - void InitAASLocation( void ); - void SetAASLocation( void ); - void Move( void ); - void UpdatePowerUps( void ); - void UpdateDeathSkin( bool state_hitch ); - void SetSpectateOrigin( void ); - -#if 0 - void ClearFocus( void ); - void UpdateFocus( void ); -#endif - - void UpdateLocation( void ); - idUserInterface * ActiveGui( void ); - void ExtractEmailInfo( const idStr &email, const char *scan, idStr &out ); - - void UseVehicle( void ); - - void ClearActiveInventoryMap(); - - // Considers item limits as defined in atdm:campaign_info entities placed in the map - // All items exceeding the defined limits are removed from the player's inventory - void EnforcePersistentInventoryItemLimits(); - - void Event_GetButtons( void ); - void Event_GetMove( void ); - void Event_GetViewAngles( void ); - void Event_StopFxFov( void ); - void Event_EnableWeapon( void ); - void Event_DisableWeapon( void ); - void Event_GetCurrentWeapon( void ); - void Event_GetPreviousWeapon( void ); - void Event_SelectWeapon( const char *weaponName ); - void Event_GetWeaponEntity( void ); - void Event_ExitTeleporter( void ); - void Event_Gibbed( void ); - void Event_GetIdealWeapon( void ); - void Event_RopeRemovalCleanup( idEntity *RopeEnt ); - - -/** -* TDM Events -**/ - void Event_GetEyePos( void ); - void Event_SetImmobilization( const char *source, int type ); - void Event_GetImmobilization( const char *source ); - void Event_GetNextImmobilization( const char *prefix, const char *lastMatch ); - void Event_SetHinderance( const char *source, float mCap, float aCap ); - void Event_GetHinderance( const char *source ); - void Event_GetNextHinderance( const char *prefix, const char *lastMatch ); - void Event_SetTurnHinderance( const char *source, float mCap, float aCap ); - void Event_GetTurnHinderance( const char *source ); - void Event_GetNextTurnHinderance( const char *prefix, const char *lastMatch ); - - - void Event_SetGui( int handle, const char *guiFile ); - void Event_GetInventoryOverlay(void); - - void Event_PlayStartSound( void ); - - // greebo: Gets posted when the player is dead and the "custom_death_delay" spawnarg is set to a positive value on worldspawn - void Event_CustomDeath(); - - void Event_MissionFailed( void ); - void Event_LoadDeathMenu( void ); - - void Event_HoldEntity( idEntity *ent ); - void Event_HeldEntity( void ); - - /** - * Return the last mouse gesture result to the script - **/ - void Event_GetMouseGesture( void ); - /** - * Return to script whether we are currently waiting for a mouse gesture to finish - **/ - void Event_MouseGestureFinished( void ); - /** - * Clear the mouse dead time if it extends beyond the time used to determine the gesture - **/ - void Event_ClearMouseDeadTime( void ); - - /** - * greebo: Sets the named lightgem modifier to a particular value. - * Setting the modifier to 0 removes it from the internal list. - */ - void Event_SetLightgemModifier(const char* modifierName, int amount); - - /** - * greebo: Reads the lightgem modifier setting from the worldspawn entity (defaults to 0). - */ - void Event_ReadLightgemModifierFromWorldspawn(); - - /** - * NOTE: The following objective functions all take the "user" objective indices - * That is, the indices start at 1 instead of 0 - * - * If the objective/component for that index was not found - * The getters return -1 for completion state and FALSE for component state - **/ - void Event_SetObjectiveState( int ObjIndex, int State ); - void Event_GetObjectiveState( int ObjIndex ); - void Event_SetObjectiveComp( int ObjIndex, int CompIndex, int bState ); - void Event_GetObjectiveComp( int ObjIndex, int CompIndex ); - void Event_ObjectiveUnlatch( int ObjIndex ); - void Event_ObjectiveComponentUnlatch( int ObjIndex, int CompIndex ); - void Event_SetObjectiveVisible( int ObjIndex, bool bVal ); - void Event_SetObjectiveOptional( int ObjIndex, bool bVal ); - void Event_SetObjectiveOngoing( int ObjIndex, bool bVal ); - void Event_SetObjectiveEnabling( int ObjIndex, const char *strIn ); - - /** - * greebo: This scriptevent routes the call to the member method "GiveHealthPool". - */ - void Event_GiveHealthPool( float amount ); - - /** Returns true if we were damaged this frame **/ - void Event_WasDamaged( void ); - - /** - * greebo: These scriptevents handle the player zoom in/out behaviour. - */ - void Event_StartZoom(float duration, float startFOV, float endFOV); - void Event_EndZoom(float duration); - void Event_ResetZoom(); - void Event_GetFov(); - - // Objectives GUI-related events - void Event_Pausegame(); - void Event_Unpausegame(); - - // Ends the game (fade out, success.gui, etc.) - void Event_MissionSuccess(); - - // greebo: This event prepares the running map for mission success. - // Basically waits for any HUD messages and fades out the screen, afterwards - // the Mission Success event is called. - void Event_TriggerMissionEnd(); - - // Disconnects the player from the mission, this is the final action during gameplay - void Event_DisconnectFromMission(); - - /** Returns to script the current idLocation of the player **/ - void Event_GetLocation(); - - // Gets called in the first few frames - void Event_StartGamePlayTimer(); - - // Checks the AAS status and displays the HUD warning - void Event_CheckAAS(); - - // Changes the projectile def name of the given weapon inventory item - void Event_ChangeWeaponProjectile(const char* weaponName, const char* projectileDefName); - void Event_ResetWeaponProjectile(const char* weaponName); - void Event_ChangeWeaponName(const char* weaponName, const char* newName); - void Event_GetCurWeaponName(); - - // Clears any active inventory maps - void Event_ClearActiveInventoryMap(); - - // Sets the currently active map (feedback method for inventory map scripts) - void Event_SetActiveInventoryMapEnt(idEntity* mapEnt); - - // return the frobbed entity - void Event_GetFrobbed(); - // enables "frob only ents used by active inventory item" mode - void Event_SetFrobOnlyUsedByInv( bool Value ); - - // Call gameLocal.ProcessInterMissionTriggers - void Event_ProcessInterMissionTriggers(); - -}; - -ID_INLINE bool idPlayer::IsReady( void ) { - return ready || forcedReady; -} - -ID_INLINE bool idPlayer::IsRespawning( void ) { - return respawning; -} - -ID_INLINE idPhysics* idPlayer::GetPlayerPhysics( void ) { - return &physicsObj; -} - -ID_INLINE bool idPlayer::IsInTeleport( void ) { - return ( teleportEntity.GetEntity() != NULL ); -} - -ID_INLINE void idPlayer::SetLeader( bool lead ) { - leader = lead; -} - -ID_INLINE bool idPlayer::IsLeader( void ) { - return leader; -} - -ID_INLINE bool idPlayer::SelfSmooth( void ) { - return selfSmooth; -} - -ID_INLINE void idPlayer::SetSelfSmooth( bool b ) { - selfSmooth = b; -} - -#endif /* !__GAME_PLAYER_H__ */ - diff --git a/game/playericon.cpp b/game/playericon.cpp deleted file mode 100644 index b02869956..000000000 --- a/game/playericon.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "playericon.h" - -static const char * iconKeys[ ICON_NONE ] = { - "mtr_icon_lag", - "mtr_icon_chat" -}; - -/* -=============== -idPlayerIcon::idPlayerIcon -=============== -*/ -idPlayerIcon::idPlayerIcon() { - iconHandle = -1; - iconType = ICON_NONE; -} - -/* -=============== -idPlayerIcon::~idPlayerIcon -=============== -*/ -idPlayerIcon::~idPlayerIcon() { - FreeIcon(); -} - -/* -=============== -idPlayerIcon::Draw -=============== -*/ -void idPlayerIcon::Draw( idPlayer *player, jointHandle_t joint ) { - idVec3 origin; - idMat3 axis; - - if ( joint == INVALID_JOINT ) { - FreeIcon(); - return; - } - - player->GetJointWorldTransform( joint, gameLocal.time, origin, axis ); - origin.z += 16.0f; - - Draw( player, origin ); -} - -/* -=============== -idPlayerIcon::Draw -=============== -*/ -void idPlayerIcon::Draw( idPlayer *player, const idVec3 &origin ) { - idPlayer *localPlayer = gameLocal.GetLocalPlayer(); - if ( !localPlayer || !localPlayer->GetRenderView() ) { - FreeIcon(); - return; - } - - idMat3 axis = localPlayer->GetRenderView()->viewaxis; - - if ( player->isLagged ) { - // create the icon if necessary, or update if already created - if ( !CreateIcon( player, ICON_LAG, origin, axis ) ) { - UpdateIcon( player, origin, axis ); - } - } else if ( player->isChatting ) { - if ( !CreateIcon( player, ICON_CHAT, origin, axis ) ) { - UpdateIcon( player, origin, axis ); - } - } else { - FreeIcon(); - } -} - -/* -=============== -idPlayerIcon::FreeIcon -=============== -*/ -void idPlayerIcon::FreeIcon( void ) { - if ( iconHandle != - 1 ) { - gameRenderWorld->FreeEntityDef( iconHandle ); - iconHandle = -1; - } - iconType = ICON_NONE; -} - -/* -=============== -idPlayerIcon::CreateIcon -=============== -*/ -bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ) { - assert( type != ICON_NONE ); - const char *mtr = player->spawnArgs.GetString( iconKeys[ type ], "_default" ); - return CreateIcon( player, type, mtr, origin, axis ); -} - -/* -=============== -idPlayerIcon::CreateIcon -=============== -*/ -bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ) { - assert( type != ICON_NONE ); - - if ( type == iconType ) { - return false; - } - - FreeIcon(); - - memset( &renderEnt, 0, sizeof( renderEnt ) ); - renderEnt.origin = origin; - renderEnt.axis = axis; - renderEnt.shaderParms[ SHADERPARM_RED ] = 1.0f; - renderEnt.shaderParms[ SHADERPARM_GREEN ] = 1.0f; - renderEnt.shaderParms[ SHADERPARM_BLUE ] = 1.0f; - renderEnt.shaderParms[ SHADERPARM_ALPHA ] = 1.0f; - renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ] = 16.0f; - renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ] = 16.0f; - renderEnt.hModel = renderModelManager->FindModel( "_sprite" ); - renderEnt.callback = NULL; - renderEnt.numJoints = 0; - renderEnt.joints = NULL; - renderEnt.customSkin = 0; - renderEnt.noShadow = true; - renderEnt.noSelfShadow = true; - renderEnt.customShader = declManager->FindMaterial( mtr ); - renderEnt.referenceShader = 0; - renderEnt.bounds = renderEnt.hModel->Bounds( &renderEnt ); - - iconHandle = gameRenderWorld->AddEntityDef( &renderEnt ); - iconType = type; - - return true; -} - -/* -=============== -idPlayerIcon::UpdateIcon -=============== -*/ -void idPlayerIcon::UpdateIcon( idPlayer *player, const idVec3 &origin, const idMat3 &axis ) { - assert( iconHandle >= 0 ); - - renderEnt.origin = origin; - renderEnt.axis = axis; - gameRenderWorld->UpdateEntityDef( iconHandle, &renderEnt ); -} - diff --git a/game/playericon.h b/game/playericon.h deleted file mode 100644 index c7eda0621..000000000 --- a/game/playericon.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PLAYERICON_H__ -#define __PLAYERICON_H__ - -typedef enum { - ICON_LAG, - ICON_CHAT, - ICON_NONE -} playerIconType_t; - -class idPlayerIcon { -public: - -public: - idPlayerIcon(); - ~idPlayerIcon(); - - void Draw( idPlayer *player, jointHandle_t joint ); - void Draw( idPlayer *player, const idVec3 &origin ); - -public: - playerIconType_t iconType; - renderEntity_t renderEnt; - qhandle_t iconHandle; - -public: - void FreeIcon( void ); - bool CreateIcon( idPlayer* player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ); - bool CreateIcon( idPlayer* player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ); - void UpdateIcon( idPlayer* player, const idVec3 &origin, const idMat3 &axis ); - -}; - - -#endif /* !_PLAYERICON_H_ */ - diff --git a/game/playerview.cpp b/game/playerview.cpp deleted file mode 100644 index 54ea96f09..000000000 --- a/game/playerview.cpp +++ /dev/null @@ -1,1129 +0,0 @@ -/*************************************************************************** -* -* PROJECT: The Dark Mod -* $Revision$ -* $Date$ -* $Author$ -* -***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -#include "../DarkMod/sourcehook/sourcehook.h" - -extern SourceHook::ISourceHook *g_SHPtr; -extern int g_PLID; - -SH_DECL_HOOK2_void( idCmdSystem, BufferCommandText, SH_NOATTRIB, 0, cmdExecution_t, const char * ); - -static int MakePowerOfTwo( int num ) { - int pot; - - for (pot = 1 ; pot < num ; pot<<=1) {} - - return pot; -} - -const int IMPULSE_DELAY = 150; - -/* -============== -idPlayerView::idPlayerView -============== -*/ -idPlayerView::idPlayerView() : -m_postProcessManager() // Invoke the postprocess Manager Constructor - J.C.Denton -{ - memset( screenBlobs, 0, sizeof( screenBlobs ) ); - memset( &view, 0, sizeof( view ) ); - player = NULL; - dvMaterial = declManager->FindMaterial( "_scratch" ); - tunnelMaterial = declManager->FindMaterial( "textures/decals/tunnel" ); - armorMaterial = declManager->FindMaterial( "armorViewEffect" ); - berserkMaterial = declManager->FindMaterial( "textures/decals/berserk" ); - irGogglesMaterial = declManager->FindMaterial( "textures/decals/irblend" ); - bloodSprayMaterial = declManager->FindMaterial( "textures/decals/bloodspray" ); - lagoMaterial = declManager->FindMaterial( LAGO_MATERIAL, false ); - - dvFinishTime = 0; - kickFinishTime = 0; - kickAngles.Zero(); - lastDamageTime = 0.0f; - fadeTime = 0; - fadeRate = 0.0; - fadeFromColor.Zero(); - fadeToColor.Zero(); - fadeColor.Zero(); - shakeAng.Zero(); - - /* - fxManager = NULL; - - if ( !fxManager ) { - fxManager = new FullscreenFXManager; - fxManager->Initialize( this ); - } - */ - - ClearEffects(); - - // greebo: Set the bool to the inverse of the CVAR, so that the code triggers - // an update in the first frame - //cur_amb_method = !cv_ambient_method.GetBool(); - // JC: Just set the flag so that we know that the update is needed. - cv_ambient_method.SetModified(); - cv_interaction_vfp_type.SetModified(); // Always update interaction shader the first time. J.C.Denton -} - -/* -============== -idPlayerView::Save -============== -*/ -void idPlayerView::Save( idSaveGame *savefile ) const { - int i; - const screenBlob_t *blob; - - blob = &screenBlobs[ 0 ]; - for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) { - savefile->WriteMaterial( blob->material ); - savefile->WriteFloat( blob->x ); - savefile->WriteFloat( blob->y ); - savefile->WriteFloat( blob->w ); - savefile->WriteFloat( blob->h ); - savefile->WriteFloat( blob->s1 ); - savefile->WriteFloat( blob->t1 ); - savefile->WriteFloat( blob->s2 ); - savefile->WriteFloat( blob->t2 ); - savefile->WriteInt( blob->finishTime ); - savefile->WriteInt( blob->startFadeTime ); - savefile->WriteFloat( blob->driftAmount ); - } - - savefile->WriteInt( dvFinishTime ); - savefile->WriteMaterial( dvMaterial ); - savefile->WriteInt( kickFinishTime ); - savefile->WriteAngles( kickAngles ); - - savefile->WriteMaterial( tunnelMaterial ); - savefile->WriteMaterial( armorMaterial ); - savefile->WriteMaterial( berserkMaterial ); - savefile->WriteMaterial( irGogglesMaterial ); - savefile->WriteMaterial( bloodSprayMaterial ); - savefile->WriteFloat( lastDamageTime ); - - savefile->WriteVec4( fadeColor ); - savefile->WriteVec4( fadeToColor ); - savefile->WriteVec4( fadeFromColor ); - savefile->WriteFloat( fadeRate ); - savefile->WriteInt( fadeTime ); - - savefile->WriteAngles( shakeAng ); - - savefile->WriteObject( player ); - savefile->WriteRenderView( view ); - - // Save games are not going to work after this change - JC Denton - // savefile->WriteBool(cur_amb_method); -} - -/* -============== -idPlayerView::Restore -============== -*/ -void idPlayerView::Restore( idRestoreGame *savefile ) { - int i; - screenBlob_t *blob; - - blob = &screenBlobs[ 0 ]; - for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) { - savefile->ReadMaterial( blob->material ); - savefile->ReadFloat( blob->x ); - savefile->ReadFloat( blob->y ); - savefile->ReadFloat( blob->w ); - savefile->ReadFloat( blob->h ); - savefile->ReadFloat( blob->s1 ); - savefile->ReadFloat( blob->t1 ); - savefile->ReadFloat( blob->s2 ); - savefile->ReadFloat( blob->t2 ); - savefile->ReadInt( blob->finishTime ); - savefile->ReadInt( blob->startFadeTime ); - savefile->ReadFloat( blob->driftAmount ); - } - - savefile->ReadInt( dvFinishTime ); - savefile->ReadMaterial( dvMaterial ); - savefile->ReadInt( kickFinishTime ); - savefile->ReadAngles( kickAngles ); - - savefile->ReadMaterial( tunnelMaterial ); - savefile->ReadMaterial( armorMaterial ); - savefile->ReadMaterial( berserkMaterial ); - savefile->ReadMaterial( irGogglesMaterial ); - savefile->ReadMaterial( bloodSprayMaterial ); - savefile->ReadFloat( lastDamageTime ); - - savefile->ReadVec4( fadeColor ); - savefile->ReadVec4( fadeToColor ); - savefile->ReadVec4( fadeFromColor ); - savefile->ReadFloat( fadeRate ); - savefile->ReadInt( fadeTime ); - - savefile->ReadAngles( shakeAng ); - - savefile->ReadObject( reinterpret_cast( player ) ); - savefile->ReadRenderView( view ); - - // Save games are not going to work after this change - JC Denton - // savefile->ReadBool(cur_amb_method); - - // Re-Initialize the PostProcess Manager. - JC Denton - this->m_postProcessManager.Initialize(); -} - -/* -============== -idPlayerView::SetPlayerEntity -============== -*/ -void idPlayerView::SetPlayerEntity( idPlayer *playerEnt ) { - player = playerEnt; -} - -/* -============== -idPlayerView::ClearEffects -============== -*/ -void idPlayerView::ClearEffects() { - lastDamageTime = MS2SEC( gameLocal.time - 99999 ); - - dvFinishTime = ( gameLocal.time - 99999 ); - kickFinishTime = ( gameLocal.time - 99999 ); - - for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) { - screenBlobs[i].finishTime = gameLocal.time; - } - - fadeTime = 0; -} - -/* -============== -idPlayerView::GetScreenBlob -============== -*/ -screenBlob_t *idPlayerView::GetScreenBlob() { - screenBlob_t *oldest = &screenBlobs[0]; - - for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) { - if ( screenBlobs[i].finishTime < oldest->finishTime ) { - oldest = &screenBlobs[i]; - } - } - return oldest; -} - -/* -============== -idPlayerView::DamageImpulse - -LocalKickDir is the direction of force in the player's coordinate system, -which will determine the head kick direction -============== -*/ -void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) { - // - // double vision effect - // - if ( lastDamageTime > 0.0f && SEC2MS( lastDamageTime ) + IMPULSE_DELAY > gameLocal.time ) { - // keep shotgun from obliterating the view - return; - } - - float dvTime = damageDef->GetFloat( "dv_time" ); - if ( dvTime ) { - if ( dvFinishTime < gameLocal.time ) { - dvFinishTime = gameLocal.time; - } - dvFinishTime += static_cast(g_dvTime.GetFloat() * dvTime); - // don't let it add up too much in god mode - if ( dvFinishTime > gameLocal.time + 5000 ) { - dvFinishTime = gameLocal.time + 5000; - } - } - - // - // head angle kick - // - float kickTime = damageDef->GetFloat( "kick_time" ); - if ( kickTime ) { - kickFinishTime = gameLocal.time + static_cast(g_kickTime.GetFloat() * kickTime); - - // forward / back kick will pitch view - kickAngles[0] = localKickDir[0]; - - // side kick will yaw view - kickAngles[1] = localKickDir[1]*0.5f; - - // up / down kick will pitch view - kickAngles[0] += localKickDir[2]; - - // roll will come from side - kickAngles[2] = localKickDir[1]; - - float kickAmplitude = damageDef->GetFloat( "kick_amplitude" ); - if ( kickAmplitude ) { - kickAngles *= kickAmplitude; - } - } - - // - // screen blob - // - float blobTime = damageDef->GetFloat( "blob_time" ); - if ( blobTime ) { - screenBlob_t *blob = GetScreenBlob(); - blob->startFadeTime = gameLocal.time; - blob->finishTime = gameLocal.time + static_cast(blobTime * g_blobTime.GetFloat()); - - const char *materialName = damageDef->GetString( "mtr_blob" ); - blob->material = declManager->FindMaterial( materialName ); - blob->x = damageDef->GetFloat( "blob_x" ); - blob->x += ( gameLocal.random.RandomInt()&63 ) - 32; - blob->y = damageDef->GetFloat( "blob_y" ); - blob->y += ( gameLocal.random.RandomInt()&63 ) - 32; - - float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; - blob->w = damageDef->GetFloat( "blob_width" ) * g_blobSize.GetFloat() * scale; - blob->h = damageDef->GetFloat( "blob_height" ) * g_blobSize.GetFloat() * scale; - blob->s1 = 0; - blob->t1 = 0; - blob->s2 = 1; - blob->t2 = 1; - } - - // - // save lastDamageTime for tunnel vision accentuation - // - lastDamageTime = MS2SEC( gameLocal.time ); - -} - -/* -================== -idPlayerView::AddBloodSpray - -If we need a more generic way to add blobs then we can do that -but having it localized here lets the material be pre-looked up etc. -================== -*/ -void idPlayerView::AddBloodSpray( float duration ) { - /* - if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) { - return; - } - // visit this for chainsaw - screenBlob_t *blob = GetScreenBlob(); - blob->startFadeTime = gameLocal.time; - blob->finishTime = gameLocal.time + ( duration * 1000 ); - blob->material = bloodSprayMaterial; - blob->x = ( gameLocal.random.RandomInt() & 63 ) - 32; - blob->y = ( gameLocal.random.RandomInt() & 63 ) - 32; - blob->driftAmount = 0.5f + gameLocal.random.CRandomFloat() * 0.5; - float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; - blob->w = 600 * g_blobSize.GetFloat() * scale; - blob->h = 480 * g_blobSize.GetFloat() * scale; - float s1 = 0.0f; - float t1 = 0.0f; - float s2 = 1.0f; - float t2 = 1.0f; - if ( blob->driftAmount < 0.6 ) { - s1 = 1.0f; - s2 = 0.0f; - } else if ( blob->driftAmount < 0.75 ) { - t1 = 1.0f; - t2 = 0.0f; - } else if ( blob->driftAmount < 0.85 ) { - s1 = 1.0f; - s2 = 0.0f; - t1 = 1.0f; - t2 = 0.0f; - } - blob->s1 = s1; - blob->t1 = t1; - blob->s2 = s2; - blob->t2 = t2; - */ -} - -/* -================== -idPlayerView::WeaponFireFeedback - -Called when a weapon fires, generates head twitches, etc -================== -*/ -void idPlayerView::WeaponFireFeedback( const idDict *weaponDef ) { - int recoilTime; - - recoilTime = weaponDef->GetInt( "recoilTime" ); - // don't shorten a damage kick in progress - if ( recoilTime && kickFinishTime < gameLocal.time ) { - idAngles angles; - weaponDef->GetAngles( "recoilAngles", "5 0 0", angles ); - kickAngles = angles; - int finish = gameLocal.time + static_cast(g_kickTime.GetFloat() * recoilTime); - kickFinishTime = finish; - } - -} - -/* -=================== -idPlayerView::CalculateShake -=================== -*/ -void idPlayerView::CalculateShake() { - idVec3 origin, matrix; - - float shakeVolume = gameSoundWorld->CurrentShakeAmplitudeForPosition( gameLocal.time, player->firstPersonViewOrigin ); - // - // shakeVolume should somehow be molded into an angle here - // it should be thought of as being in the range 0.0 -> 1.0, although - // since CurrentShakeAmplitudeForPosition() returns all the shake sounds - // the player can hear, it can go over 1.0 too. - // - shakeAng[0] = gameLocal.random.CRandomFloat() * shakeVolume; - shakeAng[1] = gameLocal.random.CRandomFloat() * shakeVolume; - shakeAng[2] = gameLocal.random.CRandomFloat() * shakeVolume; -} - -/* -=================== -idPlayerView::ShakeAxis -=================== -*/ -idMat3 idPlayerView::ShakeAxis() const { - return shakeAng.ToMat3(); -} - -/* -=================== -idPlayerView::AngleOffset - -kickVector, a world space direction that the attack should -=================== -*/ -idAngles idPlayerView::AngleOffset() const { - idAngles ang; - - ang.Zero(); - - if ( gameLocal.time < kickFinishTime ) { - float offset = kickFinishTime - gameLocal.time; - - ang = kickAngles * offset * offset * g_kickAmplitude.GetFloat(); - - for ( int i = 0 ; i < 3 ; i++ ) { - if ( ang[i] > 70.0f ) { - ang[i] = 70.0f; - } else if ( ang[i] < -70.0f ) { - ang[i] = -70.0f; - } - } - } - return ang; -} - -/* -================== -idPlayerView::SingleView -================== -*/ -void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view, bool drawHUD ) { - - // normal rendering - if ( !view ) { - return; - } - - // place the sound origin for the player - // TODO: Support overriding the location area so that reverb settings can be applied for listening thru doors? - gameSoundWorld->PlaceListener( player->GetListenerLoc(), view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" ); - - // hack the shake in at the very last moment, so it can't cause any consistency problems - renderView_t hackedView = *view; - hackedView.viewaxis = hackedView.viewaxis * ShakeAxis(); - - //gameRenderWorld->RenderScene( &hackedView ); - - if ( gameLocal.portalSkyEnt.GetEntity() && gameLocal.IsPortalSkyAcive() && g_enablePortalSky.GetBool() ) { - - renderView_t portalView = hackedView; - - portalView.vieworg = gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetOrigin(); - portalView.viewaxis = portalView.viewaxis * gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetAxis(); - - // setup global fixup projection vars - if ( 1 ) { - int vidWidth, vidHeight; - idVec2 shiftScale; - - renderSystem->GetGLSettings( vidWidth, vidHeight ); - - float pot; - int w = vidWidth; - pot = MakePowerOfTwo( w ); - shiftScale.x = (float)w / pot; - - int h = vidHeight; - pot = MakePowerOfTwo( h ); - shiftScale.y = (float)h / pot; - - hackedView.shaderParms[6] = shiftScale.x; - hackedView.shaderParms[7] = shiftScale.y; - } - - gameRenderWorld->RenderScene( &portalView ); - renderSystem->CaptureRenderToImage( "_currentRender" ); - - hackedView.forceUpdate = true; // FIX: for smoke particles not drawing when portalSky present - } - - hackedView.forceUpdate = true; // Fix for lightgem problems? -Gildoran - gameRenderWorld->RenderScene( &hackedView ); - // process the frame - - // fxManager->Process( &hackedView ); - - - if ( player->spectating ) { - return; - } - - // draw screen blobs - if ( !pm_thirdPerson.GetBool() && !g_skipViewEffects.GetBool() ) { - for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) { - screenBlob_t *blob = &screenBlobs[i]; - if ( blob->finishTime <= gameLocal.time ) { - continue; - } - - blob->y += blob->driftAmount; - - float fade = (float)( blob->finishTime - gameLocal.time ) / ( blob->finishTime - blob->startFadeTime ); - if ( fade > 1.0f ) { - fade = 1.0f; - } - if ( fade ) { - renderSystem->SetColor4( 1,1,1,fade ); - renderSystem->DrawStretchPic( blob->x, blob->y, blob->w, blob->h,blob->s1, blob->t1, blob->s2, blob->t2, blob->material ); - } - } - if (drawHUD) - { - player->DrawHUD( hud ); - } - - // armor impulse feedback - float armorPulse = ( gameLocal.time - player->lastArmorPulse ) / 250.0f; - - if ( armorPulse > 0.0f && armorPulse < 1.0f ) { - renderSystem->SetColor4( 1, 1, 1, 1.0 - armorPulse ); - renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, armorMaterial ); - } - - - // tunnel vision - float health = 0.0f; - if ( g_testHealthVision.GetFloat() != 0.0f ) { - health = g_testHealthVision.GetFloat(); - } else { - health = player->health; - } - float alpha = health / 100.0f; - if ( alpha < 0.0f ) { - alpha = 0.0f; - } - if ( alpha > 1.0f ) { - alpha = 1.0f; - } - - if ( alpha < 1.0f ) { - renderSystem->SetColor4( ( player->health <= 0.0f ) ? MS2SEC( gameLocal.time ) : lastDamageTime, 1.0f, 1.0f, ( player->health <= 0.0f ) ? 0.0f : alpha ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial ); - } - - } - - // Rotoscope (Cartoon-like) rendering - (Rotoscope Shader v1.0 by Hellborg) - added by Dram - if ( g_rotoscope.GetBool() ) { - const idMaterial *mtr = declManager->FindMaterial( "textures/postprocess/rotoedge", false ); - if ( !mtr ) { - common->Printf( "Rotoscope material not found.\n" ); - } else { - renderSystem->CaptureRenderToImage( "_currentRender" ); - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr ); - } - } - - // test a single material drawn over everything - if ( g_testPostProcess.GetString()[0] ) { - const idMaterial *mtr = declManager->FindMaterial( g_testPostProcess.GetString(), false ); - if ( !mtr ) { - common->Printf( "Material not found.\n" ); - g_testPostProcess.SetString( "" ); - } else { - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr ); - } - } -} - -/* -=================== -idPlayerView::DoubleVision -=================== -*/ -void idPlayerView::DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ) { - - if ( !g_doubleVision.GetBool() ) { - SingleView( hud, view ); - return; - } - - float scale = offset * g_dvAmplitude.GetFloat(); - if ( scale > 0.5f ) { - scale = 0.5f; - } - float shift = scale * sin( sqrt( (float)offset ) * g_dvFrequency.GetFloat() ); - shift = fabs( shift ); - - // if double vision, render to a texture - renderSystem->CropRenderSize( SCREEN_WIDTH, SCREEN_HEIGHT, true ); - - // greebo: Draw the single view, but skip the HUD, this is done later - SingleView( hud, view, false ); - - renderSystem->CaptureRenderToImage( "_scratch" ); - renderSystem->UnCrop(); - - // carry red tint if in berserk mode - idVec4 color(1, 1, 1, 1); - /*if ( gameLocal.time < player->inventory.powerupEndTime[ BERSERK ] ) { - color.y = 0; - color.z = 0; - }*/ - - renderSystem->SetColor4( color.x, color.y, color.z, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, shift, 1-shift, 1, 0, dvMaterial ); - renderSystem->SetColor4( color.x, color.y, color.z, 0.5f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1-shift, shift, dvMaterial ); - - // Do not post-process the HUD - JC Denton - // Bloom related - added by Dram - // if ( r_bloom_hud.GetBool() || !r_bloom.GetBool() ) // If HUD blooming is enabled or bloom is disabled - // { - // player->DrawHUD(hud); - // } -} - -/* -=================== -idPlayerView::BerserkVision -=================== -*/ -void idPlayerView::BerserkVision( idUserInterface *hud, const renderView_t *view ) { - renderSystem->CropRenderSize( 512, 256, true ); - SingleView( hud, view ); - renderSystem->CaptureRenderToImage( "_scratch" ); - renderSystem->UnCrop(); - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, dvMaterial ); -} - - -/* -================= -idPlayerView::Flash - -flashes the player view with the given color -================= -*/ -void idPlayerView::Flash(idVec4 color, int time ) { - Fade(idVec4(0, 0, 0, 0), time); - fadeFromColor = colorWhite; -} - -/* -================= -idPlayerView::Fade - -used for level transition fades -assumes: color.w is 0 or 1 -================= -*/ -void idPlayerView::Fade( idVec4 color, int time ) { - - if ( !fadeTime ) { - fadeFromColor.Set( 0.0f, 0.0f, 0.0f, 1.0f - color[ 3 ] ); - } else { - fadeFromColor = fadeColor; - } - fadeToColor = color; - - if ( time <= 0 ) { - fadeRate = 0; - time = 0; - fadeColor = fadeToColor; - } else { - fadeRate = 1.0f / ( float )time; - } - - if ( gameLocal.realClientTime == 0 && time == 0 ) { - fadeTime = 1; - } else { - fadeTime = gameLocal.realClientTime + time; - } -} - -/* -================= -idPlayerView::ScreenFade -================= -*/ -void idPlayerView::ScreenFade() { - int msec; - float t; - - if ( !fadeTime ) { - return; - } - - msec = fadeTime - gameLocal.realClientTime; - - if ( msec <= 0 ) { - fadeColor = fadeToColor; - if ( fadeColor[ 3 ] == 0.0f ) { - fadeTime = 0; - } - } else { - t = ( float )msec * fadeRate; - fadeColor = fadeFromColor * t + fadeToColor * ( 1.0f - t ); - } - - if ( fadeColor[ 3 ] != 0.0f ) { - renderSystem->SetColor4( fadeColor[ 0 ], fadeColor[ 1 ], fadeColor[ 2 ], fadeColor[ 3 ] ); - renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) ); - } -} - -/* -=================== -idPlayerView::InfluenceVision -=================== -*/ -void idPlayerView::InfluenceVision( idUserInterface *hud, const renderView_t *view ) { - - float distance = 0.0f; - float pct = 1.0f; - if ( player->GetInfluenceEntity() ) { - distance = ( player->GetInfluenceEntity()->GetPhysics()->GetOrigin() - player->GetPhysics()->GetOrigin() ).Length(); - if ( player->GetInfluenceRadius() != 0.0f && distance < player->GetInfluenceRadius() ) { - pct = distance / player->GetInfluenceRadius(); - pct = 1.0f - idMath::ClampFloat( 0.0f, 1.0f, pct ); - } - } - if ( player->GetInfluenceMaterial() ) { - SingleView( hud, view ); - renderSystem->CaptureRenderToImage( "_currentRender" ); - - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, pct ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() ); - } else if ( player->GetInfluenceEntity() == NULL ) { - SingleView( hud, view ); - return; - } else { - int offset = static_cast(25 + sin(static_cast(gameLocal.time))); - DoubleVision( hud, view, static_cast(pct * offset) ); - } -} - -/* -=================== -idPlayerView::RenderPlayerView -=================== -*/ -void idPlayerView::RenderPlayerView( idUserInterface *hud ) -{ - const renderView_t *view = player->GetRenderView(); - - if(g_skipViewEffects.GetBool()) - { - SingleView( hud, view ); - } else { - - /*if ( player->GetInfluenceMaterial() || player->GetInfluenceEntity() ) { - InfluenceVision( hud, view ); - } else if ( gameLocal.time < dvFinishTime ) { - DoubleVision( hud, view, dvFinishTime - gameLocal.time ); - } else {*/ - - // greebo: For underwater effects, use the Doom3 Doubleview - if (static_cast(player->GetPlayerPhysics())->GetWaterLevel() >= WATERLEVEL_HEAD) - { - DoubleVision(hud, view, cv_tdm_underwater_blur.GetInteger()); - } - else - { - // Do not postprocess the HUD - // if ( r_bloom_hud.GetBool() || !r_bloom.GetBool() ) // If HUD blooming is enabled or bloom is disabled - // { - // SingleView( hud, view ); - // } - // else - { - SingleView( hud, view, false ); - } - } - //} - - // Bloom related - J.C.Denton - /* Update post-process */ - this->m_postProcessManager.Update(); - - ScreenFade(); - } - - player->DrawHUD(hud); - - - // TDM Ambient Method checking. By Dram - // Modified by JC Denton - if ( cv_ambient_method.IsModified() ) // If the ambient method option has changed - { - UpdateAmbientLight(); - } -} - -void idPlayerView::UpdateAmbientLight() -{ - // Finds a light with name set as ambient_world, or turns the ambient light with greatest radius into main ambient. - idLight* pAmbientLight = gameLocal.FindMainAmbientLight(true); - - if (pAmbientLight != NULL) // If the light exists - { - if ( 0 == cv_ambient_method.GetInteger() ) // If the Ambient Light method is used - { - gameLocal.globalShaderParms[5] = 0; // Make sure we set this flag to 0 so that materials know which pass is to be enabled. - gameLocal.globalShaderParms[2] = 0; // Set global shader parm 2 to 0 - gameLocal.globalShaderParms[3] = 0; // Set global shader parm 3 to 0 - gameLocal.globalShaderParms[4] = 0; // Set global shader parm 4 to 0 - - pAmbientLight->On(); // Turn on ambient light - } - else // If the Texture Brightness method is used - { - - gameLocal.globalShaderParms[5] = Min( 2, Max (1, cv_ambient_method.GetInteger() ) ); - idVec3 ambient_color = pAmbientLight->spawnArgs.GetVector( "_color" ); // Get the ambient color from the spawn arguments - gameLocal.globalShaderParms[2] = ambient_color.x * 1.5f; // Set global shader parm 2 to Red value of ambient light - gameLocal.globalShaderParms[3] = ambient_color.y * 1.5f; // Set global shader parm 3 to Green value of ambient light - gameLocal.globalShaderParms[4] = ambient_color.z * 1.5f; // Set global shader parm 4 to Blue value of ambient light - - pAmbientLight->Off(); // Turn off ambient light - - } - } - else // The ambient light does not exist - { - gameLocal.Printf( "Note: The main ambient light could not be determined\n"); // Show in console of light not existing in map - } - cv_ambient_method.ClearModified(); - // Clean this up later since not needed. JC Denton - // cur_amb_method = cv_ambient_method.GetBool(); // Set the current ambient method to the CVar value -} - - -/* -=================== -idPlayerView::dnPostProcessManager Class Definitions - JC Denton -=================== -*/ - -idPlayerView::dnPostProcessManager::dnPostProcessManager(): -m_imageCurrentRender ( "_currentRender" ), -m_imageBloom ( "_bloomImage" ), -m_imageCookedMath ( "_cookedMath" ), - -m_matBrightPass ( declManager->FindMaterial( "postprocess/brightPassOptimized" ) ), -m_matGaussBlurX ( declManager->FindMaterial( "postprocess/blurx" ) ), -m_matGaussBlurY ( declManager->FindMaterial( "postprocess/blury" ) ), -//m_matFinalScenePass ( declManager->FindMaterial( "postprocess/finalScenePass" ) ), -m_matFinalScenePass ( declManager->FindMaterial( "postprocess/finalScenePassOptimized" ) ), - -m_matCookMath_pass1 ( declManager->FindMaterial( "postprocess/cookMath_pass1" ) ), -m_matCookMath_pass2 ( declManager->FindMaterial( "postprocess/cookMath_pass2" ) ) -{ - - m_iScreenHeight = m_iScreenWidth = 0; - m_iScreenHeightPowOf2 = m_iScreenWidthPowOf2 = 0; - m_nFramesToUpdateCookedData = 0; - - // Initialize once this object is created. - this->Initialize(); - - SH_ADD_HOOK_MEMFUNC(idCmdSystem, BufferCommandText, cmdSystem, this, &idPlayerView::dnPostProcessManager::Hook_BufferCommandText, false ); - -} - - idPlayerView::dnPostProcessManager::~dnPostProcessManager() - { - // Remove Source Hook before closing. - SH_REMOVE_HOOK_MEMFUNC(idCmdSystem, BufferCommandText, cmdSystem, this, &idPlayerView::dnPostProcessManager::Hook_BufferCommandText, false ); - } - - void idPlayerView::dnPostProcessManager::Hook_BufferCommandText( cmdExecution_t a_eType, const char *a_pcText ) - { - // Using idStr::FindText to make sure that we account for trailing white spaces. However, even an invalid command - // e.g. like "reloadImagesADEAW" would update the cooked data, but that should not be a problem. - if( NULL != a_pcText && - ( 0 == idStr::FindText( a_pcText, "reloadimages", false ) || 0 == idStr::FindText(a_pcText, "vid_restart", false ) || 0 == idStr::FindText(a_pcText, "image_anisotropy", false ) ) - ) - { - - m_nFramesToUpdateCookedData = 1; - if( r_postprocess.GetBool() ) - gameLocal.Printf("Cooked Data will be updated after %d frames...\n", m_nFramesToUpdateCookedData ); - else - gameLocal.Printf("Cooked Data will be updated after %d frames immediately after r_postprocess is enabled.\n", m_nFramesToUpdateCookedData ); - } - - RETURN_META(MRES_IGNORED ); - } - -void idPlayerView::dnPostProcessManager::Initialize() -{ - m_bForceUpdateOnCookedData = true; - r_postprocess_bloomKernelSize.SetModified(); // This will print message in console about bloom kernel size. -} - -void idPlayerView::dnPostProcessManager::UpdateCookedData( void ) -{ - - if( m_nFramesToUpdateCookedData > 0 ) - { - m_nFramesToUpdateCookedData --; - m_bForceUpdateOnCookedData = true; - return; - } - - if ( m_bForceUpdateOnCookedData || - r_postprocess_colorCurveBias.IsModified() || r_postprocess_brightPassOffset.IsModified() || - r_postprocess_brightPassThreshold.IsModified() || r_postprocess_sceneExposure.IsModified() || - r_postprocess_sceneGamma.IsModified() || r_postprocess_colorCorrection.IsModified() || - r_postprocess_colorCorrectBias.IsModified() - ) - { - - if( m_bForceUpdateOnCookedData ) - gameLocal.Printf( "Forcing an update on cooked math data.\n" ); - - gameLocal.Printf( "Cooking math data please wait...\n" ); - - //------------------------------------------------------------------------ - // Crop backbuffer image to the size of our cooked math image - //------------------------------------------------------------------------ - renderSystem->CropRenderSize(256, 1, true); - //------------------------------------------------------------------------ - - //------------------------------------------------------------------------ - // Cook math Pass 1 - //------------------------------------------------------------------------ - renderSystem->SetColor4( r_postprocess_colorCurveBias.GetFloat(), r_postprocess_sceneGamma.GetFloat(), r_postprocess_sceneExposure.GetFloat(), 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matCookMath_pass1 ); - renderSystem->CaptureRenderToImage( m_imageCookedMath ); - - //------------------------------------------------------------------------ - // Cook math Pass 2 - //------------------------------------------------------------------------ - float fColorCurveBias = Max ( Min ( r_postprocess_colorCorrectBias.GetFloat(), 1.0f ), 0.0f ); - renderSystem->SetColor4( r_postprocess_brightPassThreshold.GetFloat(), r_postprocess_brightPassOffset.GetFloat(), r_postprocess_colorCorrection.GetFloat(), fColorCurveBias ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matCookMath_pass2 ); - renderSystem->CaptureRenderToImage( m_imageCookedMath ); - - //------------------------------------------------------------------------ - renderSystem->UnCrop(); - //------------------------------------------------------------------------ - r_postprocess_colorCurveBias.ClearModified(); - r_postprocess_brightPassOffset.ClearModified(); - r_postprocess_brightPassThreshold.ClearModified(); - r_postprocess_sceneExposure.ClearModified(); - r_postprocess_sceneGamma.ClearModified(); - r_postprocess_colorCorrection.ClearModified(); - r_postprocess_colorCorrectBias.ClearModified(); - - m_bForceUpdateOnCookedData = false; - - gameLocal.Printf( "Cooking complete.\n" ); - - //gameLocal.Printf( "Screen size: %d, %d Power of 2 Size: %d, %d", m_iScreenWidth, m_iScreenHeight, m_iScreenWidthPowOf2, m_iScreenHeightPowOf2 ); - } -} - - -void idPlayerView::dnPostProcessManager::Update( void ) -{ - float fBloomImageDownScale = Max(Min(r_postprocess_bloomKernelSize.GetInteger(), 2), 1 ) == 1 ? 2 : 4; - - if( r_postprocess_bloomKernelSize.IsModified() ) - { - gameLocal.Printf(" Bloom Kernel size is set to: %s \n", fBloomImageDownScale == 2.0f ? "Large": "Small" ); - r_postprocess_bloomKernelSize.ClearModified(); - } - - // Check the interaction.vfp settings - if( cv_interaction_vfp_type.IsModified() ) - { - this->UpdateInteractionShader(); - cv_interaction_vfp_type.ClearModified(); - } - - const int iPostProcessType = r_postprocess.GetInteger(); - - if ( iPostProcessType != 0 ) - { - this->UpdateBackBufferParameters(); - - // Note to self1: CropRenderSize if not used before CaptureRenderToImage, then image caputured is of screen's size(non power of two) - // Note to self2: CropRenderSize when used with dimensions greater than backbuffer res, automatically crops screen to res <= backbuffer res. - - renderSystem->CaptureRenderToImage( m_imageCurrentRender ); - - this->UpdateCookedData(); - - const float fBloomIntensity = r_postprocess_bloomIntensity.GetFloat(); - - if( fBloomIntensity > 0.0f ) - { - //------------------------------------------------- - // Apply the bright-pass filter to acquire bloom image - //------------------------------------------------- - renderSystem->CropRenderSize(m_iScreenWidthPowOf2/fBloomImageDownScale, m_iScreenHeightPowOf2/fBloomImageDownScale, true); - - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matBrightPass ); - renderSystem->CaptureRenderToImage( m_imageBloom ); - - //------------------------------------------------- - // Apply Gaussian Smoothing to create bloom - //------------------------------------------------- - - renderSystem->SetColor4( fBloomImageDownScale/m_iScreenWidthPowOf2, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matGaussBlurX ); - renderSystem->CaptureRenderToImage( m_imageBloom ); - renderSystem->SetColor4( fBloomImageDownScale/m_iScreenHeightPowOf2, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, m_matGaussBlurY ); - - renderSystem->CaptureRenderToImage( m_imageBloom ); - renderSystem->UnCrop(); - //--------------------- - - } - - //------------------------------------------------- - // Calculate and Render Final Image - //------------------------------------------------- - float fDesaturation = Max ( Min ( r_postprocess_desaturation.GetFloat(), 1.0f ), 0.0f ); - renderSystem->SetColor4( fBloomIntensity, fDesaturation, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, m_fShiftScale_y, m_fShiftScale_x, 0, m_matFinalScenePass ); - //------------------------------------------------- - - this->RenderDebugTextures(); - } -} - -void idPlayerView::dnPostProcessManager::UpdateBackBufferParameters() -{ - // This condition makes sure that, the 2 loops inside run once only when resolution changes or map starts. - if( m_iScreenHeight != renderSystem->GetScreenHeight() || m_iScreenWidth !=renderSystem->GetScreenWidth() ) - { - m_iScreenWidthPowOf2 = 256, m_iScreenHeightPowOf2 = 256; - - // This should probably fix the ATI issue... - renderSystem->GetGLSettings( m_iScreenWidth, m_iScreenHeight ); - - //assert( iScreenWidth != 0 && iScreenHeight != 0 ); - - while( m_iScreenWidthPowOf2 < m_iScreenWidth ) { - m_iScreenWidthPowOf2 <<= 1; - } - while( m_iScreenHeightPowOf2 < m_iScreenHeight ) { - m_iScreenHeightPowOf2 <<= 1; - } - m_fShiftScale_x = m_iScreenWidth / (float)m_iScreenWidthPowOf2; - m_fShiftScale_y = m_iScreenHeight / (float)m_iScreenHeightPowOf2; - } -} - -void idPlayerView::dnPostProcessManager::RenderDebugTextures() -{ - const int iDebugTexture = r_postprocess_debugMode.GetInteger(); - - if( 0 < iDebugTexture && 4 > iDebugTexture ) - { - struct { - dnImageWrapper *m_pImage; - float m_fShiftScaleX, m_fShiftScaleY; - } - const arrStretchedImages[3] = { - {&m_imageCurrentRender, m_fShiftScale_x, m_fShiftScale_y }, - {&m_imageBloom, m_fShiftScale_x, m_fShiftScale_y }, - {&m_imageCookedMath, 1.0f, 1.0f}, - }; - - int i = iDebugTexture - 1; - - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0, SCREEN_HEIGHT * .2f, SCREEN_WIDTH * 0.6f, SCREEN_HEIGHT * 0.6f, 0, - arrStretchedImages[i].m_fShiftScaleY, arrStretchedImages[i].m_fShiftScaleX, 0, - *arrStretchedImages[i].m_pImage ); - } -} - -// Moved Greebo's method from gameLocal to here. - J.C.Denton -// The CVar is rendering related and from now on, would work when g_stoptime is set to 0 - -void idPlayerView::dnPostProcessManager::UpdateInteractionShader() -{ - // Check the CVARs - switch (cv_interaction_vfp_type.GetInteger()) - { - case 0: // Doom 3's default interaction shader - gameLocal.Printf("Using default interaction.vfp\n"); - cvarSystem->SetCVarInteger("r_testARBProgram", 0); - break; - - case 1: // JC Denton's enhanced interaction - gameLocal.Printf("Using TDM's enhanced interaction\n"); - cvarSystem->SetCVarInteger("r_testARBProgram", 1); - break; - - default: - gameLocal.Warning("Unknown interaction type setting found, reverting to enhanced standard."); - cv_interaction_vfp_type.SetInteger(0); - this->UpdateInteractionShader(); - }; -} - diff --git a/game/playerview.h b/game/playerview.h deleted file mode 100644 index a6753e045..000000000 --- a/game/playerview.h +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_PLAYERVIEW_H__ -#define __GAME_PLAYERVIEW_H__ - -/* -=============================================================================== - - Player view. - -=============================================================================== -*/ - -// screenBlob_t are for the on-screen damage claw marks, etc -typedef struct { - const idMaterial * material; - float x, y, w, h; - float s1, t1, s2, t2; - int finishTime; - int startFadeTime; - float driftAmount; -} screenBlob_t; - -#define MAX_SCREEN_BLOBS 8 - -class idPlayerView { -public: - idPlayerView(); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void SetPlayerEntity( class idPlayer *playerEnt ); - - void ClearEffects( void ); - - void DamageImpulse( idVec3 localKickDir, const idDict *damageDef ); - - void WeaponFireFeedback( const idDict *weaponDef ); - - idAngles AngleOffset( void ) const; // returns the current kick angle - - idMat3 ShakeAxis( void ) const; // returns the current shake angle - - void CalculateShake( void ); - - // this may involve rendering to a texture and displaying - // that with a warp model or in double vision mode - void RenderPlayerView( idUserInterface *hud ); - - void Fade( idVec4 color, int time ); - - void Flash( idVec4 color, int time ); - - void AddBloodSpray( float duration ); - -private: - void SingleView( idUserInterface *hud, const renderView_t *view, bool drawHUD = true); - void DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ); - void BerserkVision( idUserInterface *hud, const renderView_t *view ); - void InfluenceVision( idUserInterface *hud, const renderView_t *view ); - void ScreenFade(); - - // Updates the ambient light settings - void UpdateAmbientLight(); - - screenBlob_t * GetScreenBlob(); - - screenBlob_t screenBlobs[MAX_SCREEN_BLOBS]; - - int dvFinishTime; // double vision will be stopped at this time - const idMaterial * dvMaterial; // material to take the double vision screen shot - - int kickFinishTime; // view kick will be stopped at this time - idAngles kickAngles; - - class dnImageWrapper - { - private: - // Changed const idStr to idStr, so that compiler can provide a default implementation for the assignment operator. - // E.g. copying contents of idPlayerView object to another would be impossible otherwise. - idStr m_strImage; - const idMaterial *m_matImage; - - public: - dnImageWrapper( const char *a_strImage ) : - m_strImage ( a_strImage ), - m_matImage ( declManager->FindMaterial(a_strImage) ) - { - } - ID_INLINE operator const char * () const - { - return m_strImage.c_str(); - } - ID_INLINE operator const idMaterial *() const - { - return m_matImage; - } - }; - - class dnPostProcessManager - { - private: - int m_iScreenHeight; - int m_iScreenWidth; - int m_iScreenHeightPowOf2; - int m_iScreenWidthPowOf2; - float m_fShiftScale_x; - float m_fShiftScale_y; - - int m_nFramesToUpdateCookedData; // After these number of frames Cooked data will be updated. 0 means no update. - - bool m_bForceUpdateOnCookedData; - - dnImageWrapper m_imageCurrentRender; - dnImageWrapper m_imageBloom; - - // Every channel of this image will have a cooked mathematical data. - dnImageWrapper m_imageCookedMath; - const idMaterial* m_matCookMath_pass1; - const idMaterial* m_matCookMath_pass2; - - const idMaterial *m_matBrightPass; - const idMaterial *m_matGaussBlurX; - const idMaterial *m_matGaussBlurY; - - const idMaterial *m_matFinalScenePass; - - public: - dnPostProcessManager(); - ~dnPostProcessManager(); - - // Methods - void Initialize (); // This method should be invoked when idPlayerView::Restore is called. - void Update (); // Called Every Frame. - - private: - // Following methods should not be called by any other object, but itself. - void UpdateBackBufferParameters (); - void RenderDebugTextures (); - void UpdateCookedData (); - void UpdateInteractionShader (); // Chooses between the various VFP files according to the CVAR settings. Only call this if settings got changed. - void Hook_BufferCommandText( cmdExecution_t a_eType, const char *a_pcText ); // Source Hook for idCmdSystem::BufferCommandText - JC. - }; - - dnPostProcessManager m_postProcessManager; - - const idMaterial * tunnelMaterial; // health tunnel vision - const idMaterial * armorMaterial; // armor damage view effect - const idMaterial * berserkMaterial; // berserk effect - const idMaterial * irGogglesMaterial; // ir effect - const idMaterial * bloodSprayMaterial; // blood spray - const idMaterial * lagoMaterial; // lagometer drawing - float lastDamageTime; // accentuate the tunnel effect for a while - - idVec4 fadeColor; // fade color - idVec4 fadeToColor; // color to fade to - idVec4 fadeFromColor; // color to fade from - float fadeRate; // fade rate - int fadeTime; // fade time - - idAngles shakeAng; // from the sound sources - - idPlayer * player; - renderView_t view; -}; - -#endif /* !__GAME_PLAYERVIEW_H__ */ diff --git a/game/projectile.cpp b/game/projectile.cpp deleted file mode 100644 index 988921ed5..000000000 --- a/game/projectile.cpp +++ /dev/null @@ -1,2517 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/ProjectileResult.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" // grayman #2885 - -/* -=============================================================================== - - idProjectile - -=============================================================================== -*/ - - -static const float BOUNCE_SOUND_MIN_VELOCITY = 200.0f; -static const float BOUNCE_SOUND_MAX_VELOCITY = 400.0f; - -const idEventDef EV_Explode( "", NULL ); -const idEventDef EV_Fizzle( "", NULL ); -const idEventDef EV_RadiusDamage( "", "e" ); -const idEventDef EV_GetProjectileState( "getProjectileState", NULL, 'd' ); -// greebo: The launch method (takes 3 vectors as arguments) -const idEventDef EV_Launch("launch", "vvv"); -const idEventDef EV_ActivateProjectile("", NULL); -const idEventDef EV_TDM_Mine_ClearPlayerImmobilization("EV_TDM_Mine_ClearPlayerImmobilization", "e"); // grayman #2478 - allows player to handle weapons again -const idEventDef EV_Mine_Replace("", NULL); // grayman #2478 - -CLASS_DECLARATION( idEntity, idProjectile ) - EVENT( EV_Explode, idProjectile::Event_Explode ) - EVENT( EV_Fizzle, idProjectile::Event_Fizzle ) - EVENT( EV_Touch, idProjectile::Event_Touch ) - EVENT( EV_RadiusDamage, idProjectile::Event_RadiusDamage ) - EVENT( EV_GetProjectileState, idProjectile::Event_GetProjectileState ) - EVENT( EV_Launch, idProjectile::Event_Launch ) - EVENT( EV_ActivateProjectile, idProjectile::Event_ActivateProjectile ) - EVENT( EV_TDM_Mine_ClearPlayerImmobilization, idProjectile::Event_ClearPlayerImmobilization ) // grayman #2478 - EVENT( EV_TDM_Lock_OnLockPicked, idProjectile::Event_Lock_OnLockPicked ) // grayman #2478 - EVENT( EV_Mine_Replace, idProjectile::Event_Mine_Replace ) // grayman #2478 -END_CLASS - -/* -================ -idProjectile::idProjectile -================ -*/ -idProjectile::idProjectile( void ) { - owner = NULL; - lightDefHandle = -1; - thrust = 0.0f; - thrust_end = 0; - smokeFly = NULL; - smokeFlyTime = 0; - state = SPAWNED; - lightOffset = vec3_zero; - lightStartTime = 0; - lightEndTime = 0; - lightColor = vec3_zero; - damagePower = 1.0f; - memset( &projectileFlags, 0, sizeof( projectileFlags ) ); - memset( &renderLight, 0, sizeof( renderLight ) ); - - // note: for net_instanthit projectiles, we will force this back to false at spawn time - - fl.networkSync = true; - netSyncPhysics = false; - m_Lock = NULL; // grayman #2478 - isMine = false; // grayman #2478 - replaced = false; // grayman #2908 -} - -/* -================ -idProjectile::Spawn -================ -*/ -void idProjectile::Spawn( void ) { - physicsObj.SetSelf( this ); - - if (!GetPhysics()->GetClipModel()->IsTraceModel()) - { - // greebo: Clipmodel is not a trace model, try to construct it from the collision mesh - idTraceModel traceModel; - - if ( !collisionModelManager->TrmFromModel( spawnArgs.GetString("model"), traceModel ) ) - { - gameLocal.Error( "idProjectile '%s': cannot load tracemodel from %s", name.c_str(), spawnArgs.GetString("model") ); - return; - } - - // Construct a new clipmodel from that loaded tracemodel - physicsObj.SetClipModel(new idClipModel(traceModel), 1); - } - else - { - // Use the existing clipmodel, it's good enough - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - } - - physicsObj.SetContents( 0 ); - physicsObj.SetClipMask( 0 ); - physicsObj.PutToRest(); - SetPhysics( &physicsObj ); -} - -void idProjectile::AddObjectsToSaveGame(idSaveGame* savefile) // grayman #2478 -{ - idEntity::AddObjectsToSaveGame(savefile); - - savefile->AddObject(m_Lock); -} - -/* -================ -idProjectile::Save -================ -*/ -void idProjectile::Save( idSaveGame *savefile ) const { - - owner.Save( savefile ); - - projectileFlags_s flags = projectileFlags; - - LittleBitField( &flags, sizeof( flags ) ); - - savefile->Write( &flags, sizeof( flags ) ); - - - savefile->WriteFloat( thrust ); - savefile->WriteInt( thrust_end ); - - savefile->WriteRenderLight( renderLight ); - savefile->WriteInt( (int)lightDefHandle ); - savefile->WriteVec3( lightOffset ); - savefile->WriteInt( lightStartTime ); - savefile->WriteInt( lightEndTime ); - savefile->WriteVec3( lightColor ); - - savefile->WriteParticle( smokeFly ); - savefile->WriteInt( smokeFlyTime ); - - savefile->WriteInt( (int)state ); - - savefile->WriteFloat( damagePower ); - savefile->WriteBool(isMine); // grayman #2478 - savefile->WriteBool(replaced); // grayman #2908 - - savefile->WriteStaticObject( physicsObj ); - savefile->WriteStaticObject( thruster ); -} - -/* -================ -idProjectile::Restore -================ -*/ -void idProjectile::Restore( idRestoreGame *savefile ) { - - owner.Restore( savefile ); - - savefile->Read( &projectileFlags, sizeof( projectileFlags ) ); - LittleBitField( &projectileFlags, sizeof( projectileFlags ) ); - - - savefile->ReadFloat( thrust ); - savefile->ReadInt( thrust_end ); - - savefile->ReadRenderLight( renderLight ); - savefile->ReadInt( (int &)lightDefHandle ); - savefile->ReadVec3( lightOffset ); - savefile->ReadInt( lightStartTime ); - savefile->ReadInt( lightEndTime ); - savefile->ReadVec3( lightColor ); - - savefile->ReadParticle( smokeFly ); - savefile->ReadInt( smokeFlyTime ); - - savefile->ReadInt( (int &)state ); - - savefile->ReadFloat( damagePower ); - savefile->ReadBool(isMine); // grayman #2478 - savefile->ReadBool(replaced); // grayman #2908 - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadStaticObject( thruster ); - thruster.SetPhysics( &physicsObj ); - - if ( smokeFly != NULL ) { - idVec3 dir; - dir = physicsObj.GetLinearVelocity(); - dir.NormalizeFast(); - gameLocal.smokeParticles->EmitSmoke( smokeFly, gameLocal.time, gameLocal.random.RandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - } -} - -/* -================ -idProjectile::GetOwner -================ -*/ -idEntity *idProjectile::GetOwner( void ) const { - return owner.GetEntity(); -} - -/* -================ -idProjectile::SetReplaced -================ -*/ -void idProjectile::SetReplaced() // grayman #2908 -{ - this->replaced = true; -} - -/* -================ -idProjectile::Create -================ -*/ -void idProjectile::Create( idEntity *owner, const idVec3 &start, const idVec3 &dir ) { - idDict args; - idStr shaderName; - idVec3 light_color; - idVec3 light_offset; - idVec3 tmp; - idMat3 axis; - - Unbind(); - - // align z-axis of model with the direction - axis = dir.ToMat3(); - tmp = axis[2]; - axis[2] = axis[0]; - axis[0] = -tmp; - - physicsObj.SetOrigin( start ); - physicsObj.SetAxis( axis ); - - physicsObj.GetClipModel()->SetOwner( owner ); - - this->owner = owner; - - memset( &renderLight, 0, sizeof( renderLight ) ); - shaderName = spawnArgs.GetString( "mtr_light_shader" ); - if ( *(const char*)shaderName ) { - renderLight.shader = declManager->FindMaterial( shaderName, false ); - renderLight.pointLight = true; - renderLight.lightRadius[0] = - renderLight.lightRadius[1] = - renderLight.lightRadius[2] = spawnArgs.GetFloat( "light_radius" ); - spawnArgs.GetVector( "light_color", "1 1 1", light_color ); - renderLight.shaderParms[0] = light_color[0]; - renderLight.shaderParms[1] = light_color[1]; - renderLight.shaderParms[2] = light_color[2]; - renderLight.shaderParms[3] = 1.0f; - renderLight.noShadows = spawnArgs.GetBool("light_noshadows", "0"); - } - - spawnArgs.GetVector( "light_offset", "0 0 0", lightOffset ); - - lightStartTime = 0; - lightEndTime = 0; - smokeFlyTime = 0; - - damagePower = 1.0f; - - UpdateVisuals(); - - state = CREATED; - - - if ( spawnArgs.GetBool( "net_fullphysics" ) ) { - netSyncPhysics = true; - } -} - -/* -================= -idProjectile::~idProjectile -================= -*/ -idProjectile::~idProjectile() { - StopSound( SND_CHANNEL_ANY, false ); - FreeLightDef(); - delete m_Lock; // grayman #2478 -} - -/* -================= -idProjectile::FreeLightDef -================= -*/ -void idProjectile::FreeLightDef( void ) { - if ( lightDefHandle != -1 ) { - gameRenderWorld->FreeLightDef( lightDefHandle ); - lightDefHandle = -1; - } -} - -/* -================= -idProjectile::Launch -================= -*/ -void idProjectile::Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire, const float launchPower, const float dmgPower ) { - float fuse; - float startthrust; - float endthrust; - idVec3 velocity; - idAngles angular_velocity; - float linear_friction; - float angular_friction; - float contact_friction; - float bounce; - float mass; - float speed; - float delay; - float gravity; - idVec3 gravVec; - idVec3 tmp; - idMat3 axis; - int thrust_start; - int contents; - int clipMask; - - // allow characters to throw projectiles during cinematics, but not the player - if ( owner.GetEntity() && !owner.GetEntity()->IsType( idPlayer::Type ) ) { - cinematic = owner.GetEntity()->cinematic; - } else { - cinematic = false; - } - - thrust = spawnArgs.GetFloat( "thrust" ); - startthrust = spawnArgs.GetFloat( "thrust_start" ); - endthrust = spawnArgs.GetFloat( "thrust_end" ); - - spawnArgs.GetVector( "velocity", "0 0 0", velocity ); - - speed = velocity.Length() * launchPower; - - damagePower = dmgPower; - - spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); - - linear_friction = spawnArgs.GetFloat( "linear_friction" ); - angular_friction = spawnArgs.GetFloat( "angular_friction" ); - contact_friction = spawnArgs.GetFloat( "contact_friction" ); - bounce = spawnArgs.GetFloat( "bounce" ); - mass = spawnArgs.GetFloat( "mass" ); - - // greebo: Fall back to default gravity if the spawnarg is missing completely (still allows "0" gravity being set) - if (!spawnArgs.GetFloat("gravity", "0", gravity)) - { - gravity = gameLocal.GetGravity().Length(); - } - - fuse = spawnArgs.GetFloat( "fuse" ); - delay = spawnArgs.GetFloat( "delay" ); - - projectileFlags.detonate_on_world = spawnArgs.GetBool( "detonate_on_world" ); - projectileFlags.detonate_on_actor = spawnArgs.GetBool( "detonate_on_actor" ); - projectileFlags.randomShaderSpin = spawnArgs.GetBool( "random_shader_spin" ); - - if ( mass <= 0 ) { - gameLocal.Error( "Invalid mass on '%s'\n", GetEntityDefName() ); - } - - thrust *= mass; - thrust_start = SEC2MS( startthrust ) + gameLocal.time; - thrust_end = SEC2MS( endthrust ) + gameLocal.time; - - lightStartTime = 0; - lightEndTime = 0; - - if ( health ) { - fl.takedamage = true; - } - - gravVec = gameLocal.GetGravity(); - gravVec.NormalizeFast(); - - Unbind(); - - // align z-axis of model with the direction - axis = dir.ToMat3(); - tmp = axis[2]; - axis[2] = axis[0]; - axis[0] = -tmp; - - contents = 0; - clipMask = MASK_SHOT_RENDERMODEL; - if ( spawnArgs.GetBool( "detonate_on_trigger" ) ) { - contents |= CONTENTS_TRIGGER; - } - if ( !spawnArgs.GetBool( "no_contents" ) ) { - contents |= CONTENTS_PROJECTILE|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP; - clipMask |= CONTENTS_PROJECTILE; - } - - // don't do tracers on client, we don't know origin and direction - if ( spawnArgs.GetBool( "tracers" ) && gameLocal.random.RandomFloat() > 0.5f ) { - SetModel( spawnArgs.GetString( "model_tracer" ) ); - projectileFlags.isTracer = true; - } - - physicsObj.SetMass( mass ); - physicsObj.SetFriction( linear_friction, angular_friction, contact_friction ); - if ( contact_friction == 0.0f ) { - physicsObj.NoContact(); - } - physicsObj.SetBouncyness( bounce ); - physicsObj.SetGravity( gravVec * gravity ); - physicsObj.SetContents( contents ); - physicsObj.SetClipMask( clipMask ); - physicsObj.SetLinearVelocity( axis[ 2 ] * speed + pushVelocity ); - physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); - physicsObj.SetOrigin( start ); - - // greebo: Allow overriding of the projectile orientation via "angles" spawnarg - idAngles angles; - if (spawnArgs.GetAngles("angles", "0 0 0", angles)) - { - axis = angles.ToMat3(); - } - physicsObj.SetAxis( axis ); - - // grayman #2478 - is this a mine? - isMine = spawnArgs.GetBool("is_mine","0"); - - thruster.SetPosition( &physicsObj, 0, idVec3( GetPhysics()->GetBounds()[ 0 ].x, 0, 0 ) ); - - if ( !gameLocal.isClient ) { - if ( fuse <= 0 ) { - // run physics for 1 second - RunPhysics(); - PostEventMS( &EV_Remove, spawnArgs.GetInt( "remove_time", "1500" ) ); - } else if ( spawnArgs.GetBool( "detonate_on_fuse" ) ) { - fuse -= timeSinceFire; - if ( fuse < 0.0f ) { - fuse = 0.0f; - } - PostEventSec( &EV_Explode, fuse ); - } - // greebo: Added this to allow for mines - else if ( spawnArgs.GetBool( "no_fizzle" ) ) { - if ( fuse < 0.0f ) { - fuse = 0.0f; - } - } - else { - fuse -= timeSinceFire; - if ( fuse < 0.0f ) { - fuse = 0.0f; - } - PostEventSec( &EV_Fizzle, fuse ); - } - } - - if (delay > 0.0f) { - // Activate this projectile in seconds - PostEventSec( &EV_ActivateProjectile, delay); - } - - if ( projectileFlags.isTracer ) { - StartSound( "snd_tracer", SND_CHANNEL_BODY, 0, false, NULL ); - } else { - StartSound( "snd_fly", SND_CHANNEL_BODY, 0, false, NULL ); - } - - smokeFlyTime = 0; - const char *smokeName = spawnArgs.GetString( "smoke_fly" ); - if ( *smokeName != '\0' ) { - smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - smokeFlyTime = gameLocal.time; - } - - // used for the plasma bolts but may have other uses as well - if ( projectileFlags.randomShaderSpin ) { - float f = gameLocal.random.RandomFloat(); - f *= 0.5f; - renderEntity.shaderParms[SHADERPARM_DIVERSITY] = f; - } - - UpdateVisuals(); - - // Set this to inactive if there is a delay set - state = (delay > 0) ? INACTIVE : LAUNCHED; -} - -/* -========================= -idProjectile::IsMine - grayman #2478 -========================= -*/ - -bool idProjectile::IsMine() -{ - return isMine; -} - -/* -========================= -idProjectile::IsArmed - grayman #2906 -========================= -*/ - -bool idProjectile::IsArmed() -{ - return ( state == LAUNCHED ); -} - -/* -========================= -idProjectile::AngleAdjust - grayman #2478 -========================= -*/ - -float idProjectile::AngleAdjust(float angle) -{ - // Adjust a mine's pitch and roll angles so that it wants to - // return to the vertical. A larger adjustment occurs when - // the given angle is near +- 90 degrees. A smaller adjustment - // occurs when the angle is near zero or near +- 180 degrees. - // This keeps mines from flipping over if they land upside-down, - // but allows them to correct when in flight. The amount of - // adjustment varies between 0 and 5 degrees. - - float factor = 5.0f/90.0f; - float adjust = 0; - - if (abs(angle) >= 10) // small adjustments are not interesting - { - if (angle < -90) - { - adjust = factor*angle + 10; - } - else if (angle < 90) - { - adjust = -factor*angle; - } - else - { - adjust = factor*angle - 10; - } - } - - return adjust; -} - -/* -================ -idProjectile::Think -================ -*/ - -void idProjectile::Think( void ) { - if ( thinkFlags & TH_THINK ) { - if ( thrust && ( gameLocal.time < thrust_end ) ) { - // evaluate force - thruster.SetForce( GetPhysics()->GetAxis()[ 0 ] * thrust ); - thruster.Evaluate( gameLocal.time ); - } - } - - if ( IsMine() ) - { - // grayman #2478 - if this is a mine in flight, adjust its pitch and - // roll slightly so it has a better chance of landing rightside-up. - - if ( !IsAtRest() && !(thinkFlags & TH_ARMED) ) - { - idAngles ang = GetPhysics()->GetAxis().ToAngles(); - ang.pitch += AngleAdjust(ang.pitch); - ang.roll += AngleAdjust(ang.roll); - SetAngles(ang); - } - - if ( thinkFlags & TH_ARMED ) // grayman #2478 - if armed, this is a ticking mine - { - // Any AI around? For AI who manage to avoid a collision with the mine, catch them here if they're close enough and moving/rotating. - - idEntity* entityList[ MAX_GENTITIES ]; - idVec3 org = GetPhysics()->GetOrigin(); - idBounds bounds = GetPhysics()->GetAbsBounds(); - float closeEnough = Square(23); - - // get all entities touching the bounds - - int numListedEntities = gameLocal.clip.EntitiesTouchingBounds( bounds, -1, entityList, MAX_GENTITIES ); - - for ( int i = 0 ; i < numListedEntities ; i++ ) - { - idEntity* ent = entityList[ i ]; - if ( ent && ent->IsType(idAI::Type) ) - { - idAI* entAI = static_cast(ent); - if ( entAI->AI_FORWARD || (entAI->GetPhysics()->GetAngularVelocity().LengthSqr() > 0) ) - { - if ( (entAI->GetPhysics()->GetOrigin() - org).LengthSqr() <= closeEnough ) - { - MineExplode( entAI->entityNumber ); - break; - } - } - } - } - } - } - - /*idStr stateStr; - switch (state) - { - case SPAWNED: stateStr = "SPAWNED"; break; - case CREATED: stateStr = "CREATED"; break; - case LAUNCHED: stateStr = "LAUNCHED"; break; - case FIZZLED: stateStr = "FIZZLED"; break; - case EXPLODED: stateStr = "EXPLODED"; break; - case INACTIVE: stateStr = "INACTIVE"; break; - }; - - gameRenderWorld->DrawText(stateStr, physicsObj.GetOrigin(), 0.2f, colorRed, gameLocal.GetLocalPlayer()->viewAxis);*/ - - // run physics - RunPhysics(); - - Present(); - - // add the particles - if ( smokeFly != NULL && smokeFlyTime && !IsHidden() ) { - idVec3 dir = -GetPhysics()->GetLinearVelocity(); - dir.Normalize(); - if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.RandomFloat(), GetPhysics()->GetOrigin(), dir.ToMat3() ) ) { - smokeFlyTime = gameLocal.time; - } - } - - // add the light - if ( renderLight.lightRadius.x > 0.0f && g_projectileLights.GetBool() ) { - renderLight.origin = GetPhysics()->GetOrigin() + GetPhysics()->GetAxis() * lightOffset; - renderLight.axis = GetPhysics()->GetAxis(); - if ( ( lightDefHandle != -1 ) ) { - if ( lightEndTime > 0 && gameLocal.time <= lightEndTime + gameLocal.GetMSec() ) { - idVec3 color( 0, 0, 0 ); - if ( gameLocal.time < lightEndTime ) { - float frac = ( float )( gameLocal.time - lightStartTime ) / ( float )( lightEndTime - lightStartTime ); - color.Lerp( lightColor, color, frac ); - } - renderLight.shaderParms[SHADERPARM_RED] = color.x; - renderLight.shaderParms[SHADERPARM_GREEN] = color.y; - renderLight.shaderParms[SHADERPARM_BLUE] = color.z; - } - gameRenderWorld->UpdateLightDef( lightDefHandle, &renderLight ); - } else { - lightDefHandle = gameRenderWorld->AddLightDef( &renderLight ); - } - } -} - -/* -================= -idProjectile::Collide -================= -*/ -bool idProjectile::Collide( const trace_t &collision, const idVec3 &velocity ) { - idEntity *ent; - idEntity *ignore; - const char *damageDefName; - idVec3 dir; - float push; - float damageScale; - idStr SurfTypeName; - - if ( state == INACTIVE ) { - // projectile not active, return FALSE - return false; - } - - if ( state == EXPLODED || state == FIZZLED ) { - return true; - } - - // predict the explosion - if ( gameLocal.isClient ) { - if ( ClientPredictionCollide( this, spawnArgs, collision, velocity, !spawnArgs.GetBool( "net_instanthit" ) ) ) { - Explode( collision, NULL ); - return true; - } - return false; - } - - // remove projectile when a 'noimpact' surface is hit - if ( ( collision.c.material != NULL ) && ( collision.c.material->GetSurfaceFlags() & SURF_NOIMPACT ) ) { - PostEventMS( &EV_Remove, 0 ); - common->DPrintf( "Projectile collision no impact\n" ); - return true; - } - - // get the entity the projectile collided with - ent = gameLocal.entities[ collision.c.entityNum ]; - - if ( ent ) - { - ProcCollisionStims( ent, collision.c.id ); - - if( ent->IsType( idAI::Type ) ) - { - idAI *alertee = static_cast(ent); - alertee->TactileAlert( this ); - } - } - - if ( ent == owner.GetEntity() ) { - assert( 0 ); - return true; - } - - // just get rid of the projectile when it hits a player in noclip - if ( ent->IsType( idPlayer::Type ) && static_cast( ent )->noclip ) { - PostEventMS( &EV_Remove, 0 ); - return true; - } - - // direction of projectile - dir = velocity; - dir.Normalize(); - - // projectiles can apply an additional impulse next to the rigid body physics impulse - if ( spawnArgs.GetFloat( "push", "0", push ) && ( push > 0.0f ) ) - { - idVec3 pushDir = dir; - if ( IsMine() ) // grayman #2478 - if this is a mine, push up - { - pushDir = idVec3( 0,0,1 ); - } - ent->ApplyImpulse( this, collision.c.id, collision.c.point, push * pushDir ); - } - - // MP: projectiles open doors - // tels: TODO 2010-06-11 need another way to find out if entity is a door (low priority, we don't have MP in TDM yet) - //if ( gameLocal.isMultiplayer && ent->IsType( idDoor::Type ) && !static_cast< idDoor * >(ent)->IsOpen() && !ent->spawnArgs.GetBool( "no_touch" ) ) { - // ent->ProcessEvent( &EV_Activate , this ); - //} - - if ( ent->IsType( idActor::Type ) || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody()->IsType( idActor::Type ) ) ) { - if ( !projectileFlags.detonate_on_actor ) { - return false; - } - } else { - if ( !projectileFlags.detonate_on_world ) { - if ( !StartSound( "snd_ricochet", SND_CHANNEL_ITEM, 0, true, NULL ) ) { - float len = velocity.Length(); - if ( len > BOUNCE_SOUND_MIN_VELOCITY ) { - SetSoundVolume( len > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( len - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) ) ); - StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, true, NULL ); - } - } - return false; - } - } - - SetOrigin( collision.endpos ); - SetAxis( collision.endAxis ); - - // unlink the clip model because we no longer need it - GetPhysics()->UnlinkClip(); - - damageDefName = spawnArgs.GetString( "def_damage" ); - - ignore = NULL; - - bool damageInflicted = false; // grayman #2794 - whether damage was inflicted below - - // if the hit entity takes damage - if ( ent->fl.takedamage ) - { - if ( damagePower ) { - damageScale = damagePower; - } else { - damageScale = 1.0f; - } - - // scale the damage by the surface type multiplier, if any - g_Global.GetSurfName( collision.c.material, SurfTypeName ); - SurfTypeName = "damage_mult_" + SurfTypeName; - - damageScale *= spawnArgs.GetFloat( SurfTypeName.c_str(), "1.0" ); - - // if the projectile owner is a player - if ( owner.GetEntity() && owner.GetEntity()->IsType( idPlayer::Type ) ) { - // if the projectile hit an actor - if ( ent->IsType( idActor::Type ) ) { - idPlayer *player = static_cast( owner.GetEntity() ); - player->AddProjectileHits( 1 ); - damageScale *= player->PowerUpModifier( PROJECTILE_DAMAGE ); - } - } - - if ( damageDefName[0] != '\0' ) - { - // grayman #2794 - if no damage is being inflicted, then there's no need for a damage effect - - const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName ); - if ( !damageDef ) - { - gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); - } - - int damage = damageDef->GetInt( "damage" ); - damageInflicted = ( damage > 0 ); - - // grayman #2906 - check for the special case of hitting a mine. - // If a mine is unarmed, it won't take damage or explode. - - if ( damageInflicted ) - { - if ( ent->IsType(idProjectile::Type) ) - { - idProjectile *proj = static_cast(ent); - if ( proj->IsMine() && !proj->IsArmed() ) // is mine armed? - { - damageInflicted = false; - } - } - } - - if ( damageInflicted ) // grayman #2906 - only run the damage code if there's damage - { - ent->Damage( this, owner.GetEntity(), dir, damageDefName, damageScale, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ), const_cast(&collision) ); - } - ignore = ent; - } - } - - if ( damageInflicted ) // grayman #2794 - { - // if the projectile causes a damage effect - if ( spawnArgs.GetBool( "impact_damage_effect" ) ) - { - // if the hit entity has a special damage effect - if ( ent->spawnArgs.GetBool( "bleed" ) ) - { - ent->AddDamageEffect( collision, velocity, damageDefName ); - } - else - { - AddDefaultDamageEffect( collision, velocity ); - } - } - } - - Explode( collision, ignore ); - - return true; -} - -/* -================================= -idProjectile::AddDamageEffect - grayman #2478 -================================= -*/ - -void idProjectile::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) -{ - AddDefaultDamageEffect( collision, velocity ); -} - -/* -================= -idProjectile::DefaultDamageEffect -================= -*/ - -void idProjectile::DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity ) { - const char *decal, *sound; - idStr typeName; - - if ( collision.c.material != NULL ) - { - g_Global.GetSurfName( collision.c.material, typeName ); - } - else - { - typeName = gameLocal.sufaceTypeNames[ SURFTYPE_METAL ]; - } - - // play impact sound - sound = projectileDef.GetString( va( "snd_%s", typeName.c_str() ) ); - if ( *sound == '\0' ) { - sound = projectileDef.GetString( "snd_metal" ); - } - if ( *sound == '\0' ) { - sound = projectileDef.GetString( "snd_impact" ); - } - if ( *sound != '\0' ) { - soundEnt->StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL ); - } - - // project decal - decal = projectileDef.GetString( va( "mtr_detonate_%s", typeName.c_str() ) ); - if ( *decal == '\0' ) { - decal = projectileDef.GetString( "mtr_detonate" ); - } - if ( *decal != '\0' ) { - gameLocal.ProjectDecal( collision.c.point, -collision.c.normal, 8.0f, true, projectileDef.GetFloat( "decal_size", "6.0" ), decal ); - } -} - -/* -================= -idProjectile::AddDefaultDamageEffect -================= -*/ -void idProjectile::AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity ) { - - DefaultDamageEffect( this, spawnArgs, collision, velocity ); - - if ( gameLocal.isServer && fl.networkSync ) { - - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - int excludeClient; - - if ( spawnArgs.GetBool( "net_instanthit" ) ) { - excludeClient = owner.GetEntityNum(); - } else { - excludeClient = -1; - } - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.BeginWriting(); - msg.WriteFloat( collision.c.point[0] ); - msg.WriteFloat( collision.c.point[1] ); - msg.WriteFloat( collision.c.point[2] ); - msg.WriteDir( collision.c.normal, 24 ); - msg.WriteLong( ( collision.c.material != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_MATERIAL, collision.c.material->Index() ) : -1 ); - msg.WriteFloat( velocity[0], 5, 10 ); - msg.WriteFloat( velocity[1], 5, 10 ); - msg.WriteFloat( velocity[2], 5, 10 ); - ServerSendEvent( EVENT_DAMAGE_EFFECT, &msg, false, excludeClient ); - } -} - -/* -================ -idProjectile::Killed -================ -*/ -void idProjectile::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - if ( spawnArgs.GetBool( "detonate_on_death" ) ) { - trace_t collision; - - memset( &collision, 0, sizeof( collision ) ); - collision.endAxis = GetPhysics()->GetAxis(); - collision.endpos = GetPhysics()->GetOrigin(); - collision.c.point = GetPhysics()->GetOrigin(); - collision.c.normal.Set( 0, 0, 1 ); - Explode( collision, NULL ); - physicsObj.ClearContacts(); - physicsObj.PutToRest(); - } else { - Fizzle(); - } -} - -/* -================ -idProjectile::Fizzle -================ -*/ -void idProjectile::Fizzle( void ) { - - if ( state == INACTIVE || state == EXPLODED || state == FIZZLED ) { - return; - } - - StopSound( SND_CHANNEL_BODY, false ); - StartSound( "snd_fizzle", SND_CHANNEL_BODY, 0, false, NULL ); - - // fizzle FX - const char *psystem = spawnArgs.GetString( "smoke_fuse" ); - if ( psystem && *psystem ) { -//FIXME:SMOKE gameLocal.particles->SpawnParticles( GetPhysics()->GetOrigin(), vec3_origin, psystem ); - } - - // we need to work out how long the effects last and then remove them at that time - // for example, bullets have no real effects - if ( smokeFly && smokeFlyTime ) { - smokeFlyTime = 0; - } - - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.GetClipModel()->Unlink(); - physicsObj.PutToRest(); - - Hide(); - FreeLightDef(); - - state = FIZZLED; - - if ( gameLocal.isClient ) { - return; - } - - CancelEvents( &EV_Fizzle ); - PostEventMS( &EV_Remove, spawnArgs.GetInt( "remove_time", "1500" ) ); -} - -/** -* greebo: This event is being scheduled by the Launch() method, if a "delay" is set on the projectileDef -*/ -void idProjectile::Event_ActivateProjectile() -{ - state = LAUNCHED; - - // grayman #2478 - arm it if it's a mine - - if ( IsMine() ) - { - // The mine is now armed, so loop the armed sound. - - // grayman #2908 - determine if this mine was set by the map author or thrown by the player - if ( !replaced ) - { - m_SetInMotionByActor = gameLocal.GetLocalPlayer(); - } - - StartSound( "snd_mine_armed", SND_CHANNEL_BODY, 0, true, NULL ); - - // Make it frobable. It won't highlight, though, for any inventory - // item other than a lockpick, so that the player doesn't get the - // impression that he can frob it. - - SetFrobable( true ); - m_FrobDistance = cv_frob_distance_default.GetInteger(); - - // Make it locked and pickable. - - // Set up our PickableLock instance - - m_Lock = static_cast( PickableLock::CreateInstance() ); - m_Lock->InitFromSpawnargs( spawnArgs ); // Load the spawnargs for the lock - m_Lock->SetOwner( this ); - m_Lock->SetLocked( true ); - - BecomeActive( TH_ARMED ); // guarantee continued thinking - } -} - -/* -================ -idProjectile::Event_RadiusDamage -================ -*/ - -void idProjectile::Event_RadiusDamage( idEntity *ignore ) { - const char *splash_damage = spawnArgs.GetString( "def_splash_damage" ); - if ( splash_damage[0] != '\0' ) { - gameLocal.RadiusDamage( physicsObj.GetOrigin(), this, owner.GetEntity(), ignore, this, splash_damage, damagePower ); - } -} - -/* -================ -idProjectile::Event_GetProjectileState -================ -*/ -void idProjectile::Event_GetProjectileState( void ) { - idThread::ReturnInt( state ); -} - -/* -================ -idProjectile::Explode -================ -*/ -void idProjectile::Explode( const trace_t &collision, idEntity *ignore ) { - const char *fxname, *light_shader, *sndExplode; - idStr SurfTypeName; - float light_fadetime; - idVec3 normal, tempVel, tempAngVel; - int removeTime; - bool bActivated; - - if ( state == INACTIVE || state == EXPLODED || state == FIZZLED ) { - return; - } - - // stop sound - StopSound( SND_CHANNEL_BODY2, false ); - StopSound( SND_CHANNEL_BODY, false ); - - // DarkMod: Check material list to see if it's activated - g_Global.GetSurfName( collision.c.material, SurfTypeName ); - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Weapon: Projectile surface was %s \r", SurfTypeName.c_str() ); - - bActivated = TestActivated( SurfTypeName.c_str() ); -// TODO: Add spawnarg option to only play explode sound and explode light on activate - - // play explode sound - switch ( ( int ) damagePower ) { - case 2: sndExplode = "snd_explode2"; break; - case 3: sndExplode = "snd_explode3"; break; - case 4: sndExplode = "snd_explode4"; break; - default: sndExplode = "snd_explode"; break; - } - StartSound( sndExplode, SND_CHANNEL_BODY, 0, true, NULL ); - - // we need to work out how long the effects last and then remove them at that time - // for example, bullets have no real effects - if ( smokeFly && smokeFlyTime ) { - smokeFlyTime = 0; - } - - Hide(); - FreeLightDef(); - - if ( spawnArgs.GetVector( "detonation_axis", "", normal ) ) { - GetPhysics()->SetAxis( normal.ToMat3() ); - } - GetPhysics()->SetOrigin( collision.endpos + 2.0f * collision.c.normal ); - - // default remove time - removeTime = spawnArgs.GetInt( "remove_time", "1500" ); - - // change the model, usually to a PRT - fxname = NULL; - if ( g_testParticle.GetInteger() == TEST_PARTICLE_IMPACT ) { - fxname = g_testParticleName.GetString(); - } else { - fxname = spawnArgs.GetString( "model_detonate" ); - } - - int surfaceType = collision.c.material != NULL ? collision.c.material->GetSurfaceType() : SURFTYPE_METAL; - if ( !( fxname && *fxname ) ) { - if ( ( surfaceType == SURFTYPE_NONE ) || ( surfaceType == SURFTYPE_METAL ) || ( surfaceType == SURFTYPE_STONE ) ) { - fxname = spawnArgs.GetString( "model_smokespark" ); - } else if ( surfaceType == SURFTYPE_RICOCHET ) { - fxname = spawnArgs.GetString( "model_ricochet" ); - } else { - fxname = spawnArgs.GetString( "model_smoke" ); - } - } - - if ( fxname && *fxname ) { - SetModel( fxname ); - renderEntity.shaderParms[SHADERPARM_RED] = - renderEntity.shaderParms[SHADERPARM_GREEN] = - renderEntity.shaderParms[SHADERPARM_BLUE] = - renderEntity.shaderParms[SHADERPARM_ALPHA] = 1.0f; - renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - renderEntity.shaderParms[SHADERPARM_DIVERSITY] = gameLocal.random.CRandomFloat(); - Show(); - removeTime = ( removeTime > 3000 ) ? removeTime : 3000; - } - - // explosion light - light_shader = spawnArgs.GetString( "mtr_explode_light_shader" ); - if ( *light_shader ) { - renderLight.shader = declManager->FindMaterial( light_shader, false ); - renderLight.pointLight = true; - renderLight.lightRadius[0] = - renderLight.lightRadius[1] = - renderLight.lightRadius[2] = spawnArgs.GetFloat( "explode_light_radius" ); - spawnArgs.GetVector( "explode_light_color", "1 1 1", lightColor ); - renderLight.shaderParms[SHADERPARM_RED] = lightColor.x; - renderLight.shaderParms[SHADERPARM_GREEN] = lightColor.y; - renderLight.shaderParms[SHADERPARM_BLUE] = lightColor.z; - renderLight.shaderParms[SHADERPARM_ALPHA] = 1.0f; - renderLight.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - renderLight.noShadows = spawnArgs.GetBool("explode_light_noshadows", "0"); - light_fadetime = spawnArgs.GetFloat( "explode_light_fadetime", "0.5" ); - lightStartTime = gameLocal.time; - lightEndTime = gameLocal.time + SEC2MS( light_fadetime ); - BecomeActive( TH_THINK ); - } - - // store the last known velocity and angular velocity for later use - tempVel = GetPhysics()->GetLinearVelocity(); - tempAngVel = GetPhysics()->GetAngularVelocity(); - - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.PutToRest(); - - state = EXPLODED; - BecomeInactive( TH_ARMED ); // grayman #2478 - disable armed thinking - - if ( gameLocal.isClient ) { - return; - } - - // - // bind the projectile to the impact entity if necesary - // NOW: with special handling for the bind to AFEntity case. - // Lloyd: Fixed binding objects to bodies: this doesn't work for animated objects, - // need to bind to joints instead - if ( gameLocal.entities[collision.c.entityNum] && spawnArgs.GetBool( "bindOnImpact" ) ) { - idEntity *e = gameLocal.entities[ collision.c.entityNum ]; - - if( e->IsType( idAFEntity_Base::Type ) ) { - -// idAFEntity_Base *af = static_cast< idAFEntity_Base * >( e ); - - this->BindToJoint( e, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ), true ); - } - else { - Bind( gameLocal.entities[collision.c.entityNum], true ); - } - } - - // splash damage - if ( !projectileFlags.noSplashDamage ) { - float delay = spawnArgs.GetFloat( "delay_splash" ); - if ( delay ) { - if ( removeTime < delay * 1000 ) { - removeTime = static_cast( delay + 0.10f ) * 1000; - } - PostEventSec( &EV_RadiusDamage, delay, ignore ); - } else { - Event_RadiusDamage( ignore ); - } - } - - // spawn debris entities - int fxdebris = spawnArgs.GetInt( "debris_count" ); - if ( fxdebris ) { - const idDict *debris = gameLocal.FindEntityDefDict( "projectile_debris", false ); - if ( debris ) { - int amount = gameLocal.random.RandomInt( fxdebris ); - for ( int i = 0; i < amount; i++ ) { - idEntity *ent; - idVec3 dir; - dir.x = gameLocal.random.CRandomFloat() * 4.0f; - dir.y = gameLocal.random.CRandomFloat() * 4.0f; - dir.z = gameLocal.random.RandomFloat() * 8.0f; - dir.Normalize(); - - gameLocal.SpawnEntityDef( *debris, &ent, false ); - if ( !ent || !ent->IsType( idDebris::Type ) ) { - gameLocal.Error( "'projectile_debris' is not an idDebris" ); - } - - idDebris *debris = static_cast(ent); - debris->Create( owner.GetEntity(), physicsObj.GetOrigin(), dir.ToMat3() ); - debris->Launch(); - } - } - debris = gameLocal.FindEntityDefDict( "projectile_shrapnel", false ); - if ( debris ) { - int amount = gameLocal.random.RandomInt( fxdebris ); - for ( int i = 0; i < amount; i++ ) { - idEntity *ent; - idVec3 dir; - dir.x = gameLocal.random.CRandomFloat() * 8.0f; - dir.y = gameLocal.random.CRandomFloat() * 8.0f; - dir.z = gameLocal.random.RandomFloat() * 8.0f + 8.0f; - dir.Normalize(); - - gameLocal.SpawnEntityDef( *debris, &ent, false ); - if ( !ent || !ent->IsType( idDebris::Type ) ) { - gameLocal.Error( "'projectile_shrapnel' is not an idDebris" ); - } - - idDebris *debris = static_cast(ent); - debris->Create( owner.GetEntity(), physicsObj.GetOrigin(), dir.ToMat3() ); - debris->Launch(); - } - } - } - - // DarkMod: Spawn projectile result entity - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Checking projectile result:\r" ); - if( spawnArgs.GetBool( "has_result", "0" ) ) - { - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Has_result set to true\r" ); - const char* resultName = spawnArgs.GetString("def_result"); - - const idDict *resultDef = gameLocal.FindEntityDefDict( resultName, false ); - if( resultDef ) - { - idEntity *ent2; - - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("Result object found for projectile %s\r", name.c_str()); - - gameLocal.SpawnEntityDef( *resultDef, &ent2, false ); - if ( !ent2 || !ent2->IsType( CProjectileResult::Type ) ) - { - DM_LOG(LC_WEAPON, LT_ERROR)LOGSTRING("Projectile %s has a non projectile result entity in projectile_result.\r", name.c_str()); - gameLocal.Error( "'projectile_result' is not a CProjectileResult" ); - } - - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING( "Spawned projectile result\r" ); - - CProjectileResult *result = static_cast( ent2 ); - - // Populate the data object to pass to the projectile result object - SFinalProjData DataIn; - - DataIn.Owner = owner.GetEntity(); - DataIn.FinalOrigin = collision.endpos; - DataIn.FinalAxis = GetPhysics()->GetAxis(); - DataIn.LinVelocity = tempVel; - DataIn.AngVelocity = tempAngVel; - // rotate the axial direction by the axis to get world direction vector - DataIn.AxialDir = DataIn.FinalAxis * spawnArgs.GetVector( "axial_dir", "0 0 1" ); - DataIn.mass = GetPhysics()->GetMass(); - DataIn.SurfaceType = SurfTypeName; - - // Set up the projectile result with the last known results of the projectile - result->Init( &DataIn, collision, this, bActivated ); - } - } - - CancelEvents( &EV_Explode ); - PostEventMS( &EV_Remove, removeTime ); - - // grayman #2885 - turn off any visual stims this projectile is generating - - if ( GetStimResponseCollection()->HasStim() ) - { - GetStimResponseCollection()->RemoveStim( ST_VISUAL ); - } -} - -// grayman #2934 - -void idProjectile::AttackAction(idPlayer* player) -{ - if ( m_Lock != NULL ) - { - m_Lock->AttackAction(player); - } -} - - - -/* -================ -idProjectile::GetVelocity -================ -*/ -idVec3 idProjectile::GetVelocity( const idDict *projectile ) { - idVec3 velocity; - - projectile->GetVector( "velocity", "0 0 0", velocity ); - return velocity; -} - -/* -================ -idProjectile::GetGravity -================ -*/ -idVec3 idProjectile::GetGravity( const idDict *projectile ) { - float gravity; - - gravity = projectile->GetFloat( "gravity" ); - return idVec3( 0, 0, -gravity ); -} - -/* -================ -idProjectile::Event_Launch -================ -*/ -void idProjectile::Event_Launch( idVec3 const &origin, idVec3 const &direction, idVec3 const &velocity ) { - Launch(origin, direction, velocity); -} - -/* -================ -idProjectile::Event_Explode -================ -*/ -void idProjectile::Event_Explode( void ) { - trace_t collision; - - memset( &collision, 0, sizeof( collision ) ); - collision.endAxis = GetPhysics()->GetAxis(); - collision.endpos = GetPhysics()->GetOrigin(); - collision.c.point = GetPhysics()->GetOrigin(); - collision.c.normal.Set( 0, 0, 1 ); - AddDefaultDamageEffect( collision, collision.c.normal ); - Explode( collision, NULL ); -} - -/* -================ -idProjectile::MineExplode - grayman #2478 -================ -*/ -void idProjectile::MineExplode( int entityNumber ) // entityNumber belongs to the entity that stepped on you -{ - if ( state == LAUNCHED ) // only explode if you're armed and haven't already blown up - { - trace_t collision; - memset( &collision, 0, sizeof( collision ) ); - collision.endAxis = GetPhysics()->GetAxis(); - collision.endpos = GetPhysics()->GetOrigin(); - collision.c.point = collision.endpos; - collision.c.normal.Set( 0, 0, 1 ); - collision.c.entityNum = entityNumber; - AddDefaultDamageEffect( collision, collision.c.normal ); - Collide( collision, idVec3(0,0,0) ); - } -} - -/* -================ -idProjectile::Event_Fizzle -================ -*/ -void idProjectile::Event_Fizzle( void ) { - Fizzle(); -} - -/* -================ -idProjectile::Event_Touch -================ -*/ -void idProjectile::Event_Touch( idEntity *other, trace_t *trace ) -{ - if ( state == INACTIVE ) { - // greebo: projectile not active yet, return FALSE - return; - } - - if ( IsHidden() ) { - return; - } - - if ( other != owner.GetEntity() ) { - trace_t collision; - memset( &collision, 0, sizeof( collision ) ); - collision.endAxis = GetPhysics()->GetAxis(); - collision.endpos = GetPhysics()->GetOrigin(); - collision.c.point = GetPhysics()->GetOrigin(); - collision.c.normal.Set( 0, 0, 1 ); - AddDefaultDamageEffect( collision, collision.c.normal ); - Explode( collision, NULL ); - } -} - -/* -================= -idProjectile::ClientPredictionCollide -================= -*/ -bool idProjectile::ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect ) { - idEntity *ent; - - // remove projectile when a 'noimpact' surface is hit - if ( collision.c.material && ( collision.c.material->GetSurfaceFlags() & SURF_NOIMPACT ) ) { - return false; - } - - // get the entity the projectile collided with - ent = gameLocal.entities[ collision.c.entityNum ]; - if ( ent == NULL ) { - return false; - } - - // At this point it's for sure that the projectile is colliding with an entity, check the type - - // don't do anything if hitting a noclip player - if ( ent->IsType( idPlayer::Type ) && static_cast( ent )->noclip ) { - return false; - } - - // Are we hitting an actor? - if ( ent->IsType( idActor::Type ) || ( ent->IsType( idAFAttachment::Type ) && static_cast(ent)->GetBody()->IsType( idActor::Type ) ) ) { - // Yes, check if we should detonate on actors - if ( !projectileDef.GetBool( "detonate_on_actor" ) ) { - return false; - } - } else { - // Not an actor, check if we should detonate on something else - if ( !projectileDef.GetBool( "detonate_on_world" ) ) { - return false; - } - } - - // if the projectile causes a damage effect - if ( addDamageEffect && projectileDef.GetBool( "impact_damage_effect" ) ) { - // if the hit entity does not have a special damage effect - if ( !ent->spawnArgs.GetBool( "bleed" ) ) { - // predict damage effect - DefaultDamageEffect( soundEnt, projectileDef, collision, velocity ); - } - } - return true; -} - -/* -================ -idProjectile::ClientPredictionThink -================ -*/ -void idProjectile::ClientPredictionThink( void ) { - if ( !renderEntity.hModel ) { - return; - } - Think(); -} - -/* -================ -idProjectile::WriteToSnapshot -================ -*/ -void idProjectile::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteBits( owner.GetSpawnId(), 32 ); - - msg.WriteBits( state, 3 ); - - msg.WriteBits( fl.hidden, 1 ); - - if ( netSyncPhysics ) { - - msg.WriteBits( 1, 1 ); - - physicsObj.WriteToSnapshot( msg ); - - } else { - - msg.WriteBits( 0, 1 ); - - const idVec3 &origin = physicsObj.GetOrigin(); - - const idVec3 &velocity = physicsObj.GetLinearVelocity(); - - - - msg.WriteFloat( origin.x ); - - msg.WriteFloat( origin.y ); - - msg.WriteFloat( origin.z ); - - - - msg.WriteDeltaFloat( 0.0f, velocity[0], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - msg.WriteDeltaFloat( 0.0f, velocity[1], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - msg.WriteDeltaFloat( 0.0f, velocity[2], RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - } - -} - -/* -================ -idProjectile::ReadFromSnapshot -================ -*/ -void idProjectile::ReadFromSnapshot( const idBitMsgDelta &msg ) { - projectileState_t newState; - - owner.SetSpawnId( msg.ReadBits( 32 ) ); - newState = (projectileState_t) msg.ReadBits( 3 ); - if ( msg.ReadBits( 1 ) ) { - Hide(); - } else { - Show(); - } - - while( state != newState ) { - switch( state ) { - case SPAWNED: { - Create( owner.GetEntity(), vec3_origin, idVec3( 1, 0, 0 ) ); - break; - } - case CREATED: { - // the right origin and direction are required if you want bullet traces - Launch( vec3_origin, idVec3( 1, 0, 0 ), vec3_origin ); - break; - } - case LAUNCHED: { - if ( newState == FIZZLED ) { - Fizzle(); - } else { - trace_t collision; - memset( &collision, 0, sizeof( collision ) ); - collision.endAxis = GetPhysics()->GetAxis(); - collision.endpos = GetPhysics()->GetOrigin(); - collision.c.point = GetPhysics()->GetOrigin(); - collision.c.normal.Set( 0, 0, 1 ); - Explode( collision, NULL ); - } - break; - } - case FIZZLED: - case EXPLODED: { - StopSound( SND_CHANNEL_BODY2, false ); - gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &renderEntity ); - state = SPAWNED; - break; - } - case INACTIVE: { - state = INACTIVE; - break; - } - } - } - - if ( msg.ReadBits( 1 ) ) { - - physicsObj.ReadFromSnapshot( msg ); - - } else { - - idVec3 origin; - - idVec3 velocity; - - idVec3 tmp; - - idMat3 axis; - - - - origin.x = msg.ReadFloat(); - - origin.y = msg.ReadFloat(); - - origin.z = msg.ReadFloat(); - - - - velocity.x = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - velocity.y = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - velocity.z = msg.ReadDeltaFloat( 0.0f, RB_VELOCITY_EXPONENT_BITS, RB_VELOCITY_MANTISSA_BITS ); - - - - physicsObj.SetOrigin( origin ); - - physicsObj.SetLinearVelocity( velocity ); - - - - // align z-axis of model with the direction - - velocity.NormalizeFast(); - - axis = velocity.ToMat3(); - - tmp = axis[2]; - - axis[2] = axis[0]; - - axis[0] = -tmp; - - physicsObj.SetAxis( axis ); - - } - - - - if ( msg.HasChanged() ) { - - UpdateVisuals(); - - } - -} - -/* -================ -idProjectile::ClientReceiveEvent -================ -*/ -bool idProjectile::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - trace_t collision; - idVec3 velocity; - - switch( event ) { - case EVENT_DAMAGE_EFFECT: { - memset( &collision, 0, sizeof( collision ) ); - collision.c.point[0] = msg.ReadFloat(); - collision.c.point[1] = msg.ReadFloat(); - collision.c.point[2] = msg.ReadFloat(); - collision.c.normal = msg.ReadDir( 24 ); - int index = gameLocal.ClientRemapDecl( DECL_MATERIAL, msg.ReadLong() ); - collision.c.material = ( index != -1 ) ? static_cast( declManager->DeclByIndex( DECL_MATERIAL, index ) ) : NULL; - velocity[0] = msg.ReadFloat( 5, 10 ); - velocity[1] = msg.ReadFloat( 5, 10 ); - velocity[2] = msg.ReadFloat( 5, 10 ); - DefaultDamageEffect( this, spawnArgs, collision, velocity ); - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -================ -idProjectile::TestActivated -DarkMod Addition -================ -*/ - -bool idProjectile::TestActivated( const char *typeName ) -{ - bool bReturnVal(false), bAssumeActive(false); - idStr MaterialsList; - - if( !spawnArgs.GetBool( "assume_active", "0" ) ) - { - if( !spawnArgs.GetString( "active_surfaces", "", MaterialsList ) - || !typeName ) - { - // return false if the surfaces list is blank - goto Quit; - } - } - else - { - bAssumeActive = true; - - if( !spawnArgs.GetString( "dud_surfaces", "", MaterialsList ) - || !typeName ) - { - // return true if the surfaces list is blank and we assume active - bReturnVal = true; - goto Quit; - } - } - - // pad front and back with spaces for unique name searching - MaterialsList.Insert(' ', 0 ); - MaterialsList.Append(' '); - - bReturnVal = ( MaterialsList.Find( va(" %s ", typeName) ) != -1 ); - // this XOR should cover both cases, assumed active and found dud, assumed dud found active - bReturnVal ^= bAssumeActive; - -Quit: - return bReturnVal; -} - -/* -========================= -idProjectile::CanBeUsedBy - grayman #2478 -========================= -*/ - -bool idProjectile::CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse) -{ - if (item == NULL) - { - return false; - } - - assert(item->Category() != NULL); - - // FIXME: Move this to idEntity to some sort of "usable_by_inv_category" list? - const idStr& categoryName = item->Category()->GetName(); - if (categoryName == "#str_02389" ) // Lockpicks - { - if (!m_Lock->IsPickable()) - { - // Lock is not pickable - return false; - } - - // Lockpicks behave similar to keys - return (isFrobUse) ? IsLocked() : true; - } - - return false; -} - -/* -=================== -idProjectile::UseBy - grayman #2478 -=================== -*/ - -bool idProjectile::UseBy(EImpulseState impulseState, const CInventoryItemPtr& item) -{ - if (item == NULL) - { - return false; - } - - assert(item->Category() != NULL); - - // Retrieve the entity behind that item and reject NULL entities - idEntity* itemEntity = item->GetItemEntity(); - if (itemEntity == NULL) - { - return false; - } - - // Get the name of this inventory category - const idStr& categoryName = item->Category()->GetName(); - - if (categoryName == "#str_02389" ) // Lockpicks - { - if (!m_Lock->IsPickable()) - { - // Lock is not pickable - DM_LOG(LC_LOCKPICK, LT_DEBUG)LOGSTRING("FrobDoor %s is not pickable\r", name.c_str()); - return false; - } - - // Lockpicks are different, we need to look at the button state - // First we check if this item is a lockpick. It has to be of the toolclass lockpick - // and the type must be set. - idStr str = itemEntity->spawnArgs.GetString( "lockpick_type", "" ); - - if (str.Length() == 1) - { - // greebo: Check if the item owner is a player, and if yes, - // update the immobilization flags. - idEntity* itemOwner = item->GetOwner(); - - if (itemOwner->IsType(idPlayer::Type)) - { - idPlayer* playerOwner = static_cast(itemOwner); - playerOwner->SetImmobilization("Lockpicking", EIM_ATTACK); - - // Schedule an event 1/3 sec. from now, to enable weapons again after this time - CancelEvents(&EV_TDM_Mine_ClearPlayerImmobilization); - PostEventMS(&EV_TDM_Mine_ClearPlayerImmobilization, 300, playerOwner); - } - - // Pass the call to the lockpick routine - return m_Lock->ProcessLockpickImpulse(impulseState, static_cast(str[0])); - } - else - { - gameLocal.Warning("Wrong 'type' spawnarg for lockpicking on item %s, must be a single character.", itemEntity->name.c_str()); - return false; - } - } - - return false; -} - -/* -====================== -idProjectile::IsLocked - grayman #2478 -====================== -*/ - -bool idProjectile::IsLocked() -{ - return m_Lock->IsLocked(); -} - -/* -============================================= -idProjectile::Event_ClearPlayerImmobilization - grayman #2478 -============================================= -*/ - -void idProjectile::Event_ClearPlayerImmobilization(idEntity* player) -{ - if (!player->IsType(idPlayer::Type)) - { - return; - } - - // Release the immobilization imposed on the player by Lockpicking - static_cast(player)->SetImmobilization("Lockpicking", 0); -} - -/* -===================================== -idProjectile::Event_Lock_OnLockPicked - grayman #2478 -===================================== -*/ - -void idProjectile::Event_Lock_OnLockPicked() -{ - // "Lock is picked" signal - - m_Lock->SetLocked(false); - state = INACTIVE; // disarm the mine - BecomeInactive( TH_ARMED ); // disable armed thinking - StartSound( "snd_mine_disarmed", SND_CHANNEL_BODY, 0, true, NULL ); - SetFrobable(false); // can't frob this until after the disarm sound is finished - PostEventSec( &EV_Mine_Replace, 1.0f ); -} - -/* -================================ -idProjectile::Event_Mine_Replace - grayman #2478 -================================ -*/ - -void idProjectile::Event_Mine_Replace() -{ - // Change the projectile into a mine entity the player can put back into inventory. - - const char* resultName = spawnArgs.GetString("def_disarmed"); - - const idDict *resultDef = gameLocal.FindEntityDefDict( resultName, false ); - if ( resultDef ) - { - idEntity *newMine; - gameLocal.SpawnEntityDef( *resultDef, &newMine, false ); - newMine->GetPhysics()->SetOrigin( GetPhysics()->GetOrigin() ); - newMine->GetPhysics()->SetAxis( GetPhysics()->GetAxis() ); - newMine->BecomeInactive( TH_PHYSICS ); // turn off physics so the new mine doesn't sink through the floor - - SetFrobable(false); - PostEventMS( &EV_Remove, 1 ); // Remove the projectile, which has been replaced - } -} - -/* -=============================================================================== - - idGuidedProjectile - -=============================================================================== -*/ - -CLASS_DECLARATION( idProjectile, idGuidedProjectile ) -END_CLASS - -/* -================ -idGuidedProjectile::idGuidedProjectile -================ -*/ -idGuidedProjectile::idGuidedProjectile( void ) { - enemy = NULL; - speed = 0.0f; - turn_max = 0.0f; - clamp_dist = 0.0f; - rndScale = ang_zero; - rndAng = ang_zero; - rndUpdateTime = 0; - angles = ang_zero; - burstMode = false; - burstDist = 0; - burstVelocity = 0.0f; - unGuided = false; -} - -/* -================= -idGuidedProjectile::~idGuidedProjectile -================= -*/ -idGuidedProjectile::~idGuidedProjectile( void ) { -} - -/* -================ -idGuidedProjectile::Spawn -================ -*/ -void idGuidedProjectile::Spawn( void ) { -} - -/* -================ -idGuidedProjectile::Save -================ -*/ -void idGuidedProjectile::Save( idSaveGame *savefile ) const { - enemy.Save( savefile ); - savefile->WriteFloat( speed ); - savefile->WriteAngles( rndScale ); - savefile->WriteAngles( rndAng ); - savefile->WriteInt( rndUpdateTime ); - savefile->WriteFloat( turn_max ); - savefile->WriteFloat( clamp_dist ); - savefile->WriteAngles( angles ); - savefile->WriteBool( burstMode ); - savefile->WriteBool( unGuided ); - savefile->WriteFloat( burstDist ); - savefile->WriteFloat( burstVelocity ); - // The lock class is saved by the idSaveGame class on close, no need to handle it here - savefile->WriteObject(m_Lock); // grayman #2478 -} - -/* -================ -idGuidedProjectile::Restore -================ -*/ -void idGuidedProjectile::Restore( idRestoreGame *savefile ) { - enemy.Restore( savefile ); - savefile->ReadFloat( speed ); - savefile->ReadAngles( rndScale ); - savefile->ReadAngles( rndAng ); - savefile->ReadInt( rndUpdateTime ); - savefile->ReadFloat( turn_max ); - savefile->ReadFloat( clamp_dist ); - savefile->ReadAngles( angles ); - savefile->ReadBool( burstMode ); - savefile->ReadBool( unGuided ); - savefile->ReadFloat( burstDist ); - savefile->ReadFloat( burstVelocity ); - // The lock class is restored by the idRestoreGame, don't handle it here - savefile->ReadObject(reinterpret_cast(m_Lock)); // grayman #2478 -} - - -/* -================ -idGuidedProjectile::GetSeekPos -================ -*/ -void idGuidedProjectile::GetSeekPos( idVec3 &out ) { - idEntity *enemyEnt = enemy.GetEntity(); - if ( enemyEnt ) { - if ( enemyEnt->IsType( idActor::Type ) ) { - out = static_cast(enemyEnt)->GetEyePosition(); - out.z -= 12.0f; - } else { - out = enemyEnt->GetPhysics()->GetOrigin(); - } - } else { - out = GetPhysics()->GetOrigin() + physicsObj.GetLinearVelocity() * 2.0f; - } -} - -/* -================ -idGuidedProjectile::Think -================ -*/ -void idGuidedProjectile::Think( void ) { - idVec3 dir; - idVec3 seekPos; - idVec3 velocity; - idVec3 nose; - idVec3 tmp; - idMat3 axis; - idAngles dirAng; - idAngles diff; - float dist; - float frac; - int i; - - if ( state == LAUNCHED && !unGuided ) { - - GetSeekPos( seekPos ); - - if ( rndUpdateTime < gameLocal.time ) { - rndAng[ 0 ] = rndScale[ 0 ] * gameLocal.random.CRandomFloat(); - rndAng[ 1 ] = rndScale[ 1 ] * gameLocal.random.CRandomFloat(); - rndAng[ 2 ] = rndScale[ 2 ] * gameLocal.random.CRandomFloat(); - rndUpdateTime = gameLocal.time + 200; - } - - nose = physicsObj.GetOrigin() + 10.0f * physicsObj.GetAxis()[0]; - - dir = seekPos - nose; - dist = dir.Normalize(); - dirAng = dir.ToAngles(); - - // make it more accurate as it gets closer - frac = dist / clamp_dist; - if ( frac > 1.0f ) { - frac = 1.0f; - } - - diff = dirAng - angles + rndAng * frac; - - // clamp the to the max turn rate - diff.Normalize180(); - for( i = 0; i < 3; i++ ) { - if ( diff[ i ] > turn_max ) { - diff[ i ] = turn_max; - } else if ( diff[ i ] < -turn_max ) { - diff[ i ] = -turn_max; - } - } - angles += diff; - - // make the visual model always points the dir we're traveling - dir = angles.ToForward(); - velocity = dir * speed; - - if ( burstMode && dist < burstDist ) { - unGuided = true; - velocity *= burstVelocity; - } - - physicsObj.SetLinearVelocity( velocity ); - - // align z-axis of model with the direction - axis = dir.ToMat3(); - tmp = axis[2]; - axis[2] = axis[0]; - axis[0] = -tmp; - - GetPhysics()->SetAxis( axis ); - } - - idProjectile::Think(); -} - -/* -================= -idGuidedProjectile::Launch -================= -*/ -void idGuidedProjectile::Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire, const float launchPower, float dmgPower ) { - idProjectile::Launch( start, dir, pushVelocity, timeSinceFire, launchPower, dmgPower ); - if ( owner.GetEntity() ) { - if ( owner.GetEntity()->IsType( idAI::Type ) ) { - enemy = static_cast( owner.GetEntity() )->GetEnemy(); - } else if ( owner.GetEntity()->IsType( idPlayer::Type ) ) { - trace_t tr; - idPlayer *player = static_cast( owner.GetEntity() ); - idVec3 start = player->GetEyePosition(); - idVec3 end = start + player->viewAxis[0] * 1000.0f; - gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL | CONTENTS_BODY, owner.GetEntity() ); - if ( tr.fraction < 1.0f ) { - enemy = gameLocal.GetTraceEntity( tr ); - } - // ignore actors on the player's team - if ( enemy.GetEntity() == NULL || !enemy.GetEntity()->IsType( idActor::Type ) || ( static_cast( enemy.GetEntity() )->team == player->team ) ) { - enemy = player->EnemyWithMostHealth(); - } - } - } - const idVec3 &vel = physicsObj.GetLinearVelocity(); - angles = vel.ToAngles(); - speed = vel.Length(); - rndScale = spawnArgs.GetAngles( "random", "15 15 0" ); - turn_max = spawnArgs.GetFloat( "turn_max", "180" ) / ( float )USERCMD_HZ; - clamp_dist = spawnArgs.GetFloat( "clamp_dist", "256" ); - burstMode = spawnArgs.GetBool( "burstMode" ); - unGuided = false; - burstDist = spawnArgs.GetFloat( "burstDist", "64" ); - burstVelocity = spawnArgs.GetFloat( "burstVelocity", "1.25" ); - UpdateVisuals(); -} - - -/* -=============================================================================== - - idDebris - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idDebris ) -EVENT( EV_Explode, idDebris::Event_Explode ) -EVENT( EV_Fizzle, idDebris::Event_Fizzle ) -END_CLASS - -/* -================ -idDebris::Spawn -================ -*/ -void idDebris::Spawn( void ) { - owner = NULL; - smokeFly = NULL; - smokeFlyTime = 0; -} - -/* -================ -idDebris::Create -================ -*/ -void idDebris::Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ) { - Unbind(); - GetPhysics()->SetOrigin( start ); - GetPhysics()->SetAxis( axis ); - GetPhysics()->SetContents( 0 ); - this->owner = owner; - smokeFly = NULL; - smokeFlyTime = 0; - sndBounce = NULL; - UpdateVisuals(); -} - -/* -================= -idDebris::idDebris -================= -*/ -idDebris::idDebris( void ) { - owner = NULL; - smokeFly = NULL; - smokeFlyTime = 0; - sndBounce = NULL; -} - -/* -================= -idDebris::~idDebris -================= -*/ -idDebris::~idDebris( void ) { -} - -/* -================= -idDebris::Save -================= -*/ -void idDebris::Save( idSaveGame *savefile ) const { - owner.Save( savefile ); - - savefile->WriteStaticObject( physicsObj ); - - savefile->WriteParticle( smokeFly ); - savefile->WriteInt( smokeFlyTime ); - savefile->WriteSoundShader( sndBounce ); -} - -/* -================= -idDebris::Restore -================= -*/ -void idDebris::Restore( idRestoreGame *savefile ) { - owner.Restore( savefile ); - - savefile->ReadStaticObject( physicsObj ); - RestorePhysics( &physicsObj ); - - savefile->ReadParticle( smokeFly ); - savefile->ReadInt( smokeFlyTime ); - savefile->ReadSoundShader( sndBounce ); -} - -/* -================= -idDebris::Launch -================= -*/ -void idDebris::Launch( void ) { - float fuse; - idVec3 velocity; - idAngles angular_velocity; - float linear_friction; - float angular_friction; - float contact_friction; - float bounce; - float mass; - float gravity; - idVec3 gravVec; - bool randomVelocity; - idMat3 axis; - - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - - spawnArgs.GetVector( "velocity", "0 0 0", velocity ); - spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); - - linear_friction = spawnArgs.GetFloat( "linear_friction" ); - angular_friction = spawnArgs.GetFloat( "angular_friction" ); - contact_friction = spawnArgs.GetFloat( "contact_friction" ); - bounce = spawnArgs.GetFloat( "bounce" ); - mass = spawnArgs.GetFloat( "mass" ); - gravity = spawnArgs.GetFloat( "gravity" ); - fuse = spawnArgs.GetFloat( "fuse" ); - randomVelocity = spawnArgs.GetBool ( "random_velocity" ); - - if ( mass <= 0 ) { - gameLocal.Error( "Invalid mass on '%s'\n", GetEntityDefName() ); - } - - if ( randomVelocity ) { - velocity.x *= gameLocal.random.RandomFloat() + 0.5f; - velocity.y *= gameLocal.random.RandomFloat() + 0.5f; - velocity.z *= gameLocal.random.RandomFloat() + 0.5f; - } - - if ( health ) { - fl.takedamage = true; - } - - gravVec = gameLocal.GetGravity(); - gravVec.NormalizeFast(); - axis = GetPhysics()->GetAxis(); - - Unbind(); - - physicsObj.SetSelf( this ); - - // check if a clip model is set - const char *clipModelName; - idTraceModel trm; - spawnArgs.GetString( "clipmodel", "", &clipModelName ); - if ( !clipModelName[0] ) { - clipModelName = spawnArgs.GetString( "model" ); // use the visual model - } - - // load the trace model - if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { - // default to a box - physicsObj.SetClipBox( renderEntity.bounds, 1.0f ); - } else { - physicsObj.SetClipModel( new idClipModel( trm ), 1.0f ); - } - - physicsObj.GetClipModel()->SetOwner( owner.GetEntity() ); - physicsObj.SetMass( mass ); - physicsObj.SetFriction( linear_friction, angular_friction, contact_friction ); - if ( contact_friction == 0.0f ) { - physicsObj.NoContact(); - } - physicsObj.SetBouncyness( bounce ); - physicsObj.SetGravity( gravVec * gravity ); - physicsObj.SetContents( 0 ); - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); - physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); - physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( axis ); - SetPhysics( &physicsObj ); - - if ( !gameLocal.isClient ) { - if ( fuse <= 0 ) { - // run physics for 1 second - RunPhysics(); - PostEventMS( &EV_Remove, 0 ); - } else if ( spawnArgs.GetBool( "detonate_on_fuse" ) ) { - if ( fuse < 0.0f ) { - fuse = 0.0f; - } - RunPhysics(); - PostEventSec( &EV_Explode, fuse ); - } else { - if ( fuse < 0.0f ) { - fuse = 0.0f; - } - PostEventSec( &EV_Fizzle, fuse ); - } - } - - StartSound( "snd_fly", SND_CHANNEL_BODY, 0, false, NULL ); - - smokeFly = NULL; - smokeFlyTime = 0; - const char *smokeName = spawnArgs.GetString( "smoke_fly" ); - if ( *smokeName != '\0' ) { - smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - smokeFlyTime = gameLocal.time; - gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - } - - const char *sndName = spawnArgs.GetString( "snd_bounce" ); - if ( *sndName != '\0' ) { - sndBounce = declManager->FindSound( sndName ); - } - - UpdateVisuals(); -} - -/* -================ -idDebris::Think -================ -*/ -void idDebris::Think( void ) { - - // run physics - RunPhysics(); - Present(); - - if ( smokeFly && smokeFlyTime ) { - if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { - smokeFlyTime = 0; - } - } -} - -/* -================ -idDebris::Killed -================ -*/ -void idDebris::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - if ( spawnArgs.GetBool( "detonate_on_death" ) ) { - Explode(); - } else { - Fizzle(); - } -} - -/* -================= -idDebris::Collide -================= -*/ -bool idDebris::Collide( const trace_t &collision, const idVec3 &velocity ) { - if ( sndBounce != NULL ) { - StartSoundShader( sndBounce, SND_CHANNEL_BODY, 0, false, NULL ); - } - sndBounce = NULL; - return false; -} - - -/* -================ -idDebris::Fizzle -================ -*/ -void idDebris::Fizzle( void ) { - if ( IsHidden() ) { - // already exploded - return; - } - - StopSound( SND_CHANNEL_ANY, false ); - StartSound( "snd_fizzle", SND_CHANNEL_BODY, 0, false, NULL ); - - // fizzle FX - const char *smokeName = spawnArgs.GetString( "smoke_fuse" ); - if ( *smokeName != '\0' ) { - smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - smokeFlyTime = gameLocal.time; - gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - } - - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.PutToRest(); - - Hide(); - - if ( gameLocal.isClient ) { - return; - } - - CancelEvents( &EV_Fizzle ); - PostEventMS( &EV_Remove, 0 ); -} - -/* -================ -idDebris::Explode -================ -*/ -void idDebris::Explode( void ) { - if ( IsHidden() ) { - // already exploded - return; - } - - StopSound( SND_CHANNEL_ANY, false ); - StartSound( "snd_explode", SND_CHANNEL_BODY, 0, false, NULL ); - - Hide(); - - // these must not be "live forever" particle systems - smokeFly = NULL; - smokeFlyTime = 0; - const char *smokeName = spawnArgs.GetString( "smoke_detonate" ); - if ( *smokeName != '\0' ) { - smokeFly = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - smokeFlyTime = gameLocal.time; - gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); - } - - fl.takedamage = false; - physicsObj.SetContents( 0 ); - physicsObj.PutToRest(); - - CancelEvents( &EV_Explode ); - PostEventMS( &EV_Remove, 0 ); -} - -/* -================ -idDebris::Event_Explode -================ -*/ -void idDebris::Event_Explode( void ) { - Explode(); -} - -/* -================ -idDebris::Event_Fizzle -================ -*/ -void idDebris::Event_Fizzle( void ) { - Fizzle(); -} - - diff --git a/game/projectile.h b/game/projectile.h deleted file mode 100644 index d5d3eadf0..000000000 --- a/game/projectile.h +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_PROJECTILE_H__ -#define __GAME_PROJECTILE_H__ - -#include "../DarkMod/PickableLock.h" -#include "../DarkMod/Inventory/Item.h" -#include "../DarkMod/Inventory/Category.h" - -/** -* SFinalProjData: Structure storing the final projectile data at impact -* Passed on to CProjectileResult object -**/ -typedef struct SFinalProjData_s -{ - /** - * greebo: The entity which fired the projectile - */ - idEntityPtr Owner; - - /** - * Final world position of the origin of the projectile on impact - **/ - idVec3 FinalOrigin; - - /** - * Final orientation of the projectile on impact - **/ - idMat3 FinalAxis; - - /** - * Final linear velocity of the projectile just before impact - **/ - idVec3 LinVelocity; - - /** - * Final angular velocity of the projectile just before impact - **/ - idVec3 AngVelocity; - - /** - * Direction vector for the axis of the arrow. Needed for pushing it in. - **/ - idVec3 AxialDir; - - /** - * Max Angle of incidence when projectile hits surface - * (Calculated in CProjectileResult::Init ) - **/ - float IncidenceAngle; - - /** - * Mass of the projectile (might be useful) - **/ - float mass; - - /** - * Name of the surface that was struck - **/ - idStr SurfaceType; - -} SFinalProjData; - -/* -=============================================================================== - - idProjectile - -=============================================================================== -*/ - -extern const idEventDef EV_Explode; -// greebo: Exposed projectile launch method to scripts -extern const idEventDef EV_Launch; - -class idProjectile : public idEntity { -public : - CLASS_PROTOTYPE( idProjectile ); - - idProjectile(); - virtual ~idProjectile(); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Create( idEntity *owner, const idVec3 &start, const idVec3 &dir ); - virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f ); - virtual void FreeLightDef( void ); - - idEntity * GetOwner( void ) const; - void SetReplaced(); // grayman #2908 - - virtual void Think( void ); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - virtual void Explode( const trace_t &collision, idEntity *ignore ); - void Fizzle( void ); - - static idVec3 GetVelocity( const idDict *projectile ); - static idVec3 GetGravity( const idDict *projectile ); - - enum { - EVENT_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS, - EVENT_MAXEVENTS - }; - - static void DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity ); - static bool ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect ); - virtual void ClientPredictionThink( void ); - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - void MineExplode( int entityNumber ); // grayman #2478 - bool IsMine(); // grayman #2478 - bool IsArmed(); // grayman #2906 - void AttackAction(idPlayer* player); // grayman #2934 - void Event_ActivateProjectile(); - -protected: - idEntityPtr owner; - - struct projectileFlags_s { - bool detonate_on_world : 1; - bool detonate_on_actor : 1; - bool randomShaderSpin : 1; - bool isTracer : 1; - bool noSplashDamage : 1; - } projectileFlags; - - float thrust; - int thrust_end; - float damagePower; - - renderLight_t renderLight; - qhandle_t lightDefHandle; // handle to renderer light def - idVec3 lightOffset; - int lightStartTime; - int lightEndTime; - idVec3 lightColor; - - idForce_Constant thruster; - idPhysics_RigidBody physicsObj; - - const idDeclParticle * smokeFly; - int smokeFlyTime; - - typedef enum { - // must update these in script/doom_defs.script if changed - SPAWNED = 0, - CREATED = 1, - LAUNCHED = 2, - FIZZLED = 3, - EXPLODED = 4, - INACTIVE = 5 // greebo: this applies to mines that haven't become active yet - } projectileState_t; - - projectileState_t state; - - PickableLock* m_Lock; // grayman #2478 - A lock implementation for this mover - bool isMine; // grayman #2478 - true if this is a mine - bool replaced; // grayman #2908 - true if this is a projectile mine that replaced a map author-placed armed mine - -protected: - /** - * Determine whether the projectile "activates" based on the surface type argument - * This checks a space-delimited spawnarg list of activating materials and - * returns true if the struck material activates this projectile - **/ - bool TestActivated( const char *typeName ); - -private: - bool netSyncPhysics; - - void AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity ); - - void AddObjectsToSaveGame(idSaveGame* savefile); // grayman #2478 - bool CanBeUsedBy(const CInventoryItemPtr& item, const bool isFrobUse); // grayman #2478 - bool UseBy(EImpulseState impulseState, const CInventoryItemPtr& item); // grayman #2478 - bool IsLocked(); // grayman #2478 - void Event_ClearPlayerImmobilization(idEntity* player); // grayman #2478 - - void Event_Explode( void ); - void Event_Fizzle( void ); - void Event_RadiusDamage( idEntity *ignore ); - void Event_Touch( idEntity *other, trace_t *trace ); - void Event_GetProjectileState( void ); - void Event_Launch( idVec3 const &origin, idVec3 const &direction, idVec3 const &velocity ); - void Event_Lock_OnLockPicked(); // grayman #2478 - void Event_Mine_Replace(); // grayman #2478 - float AngleAdjust(float angle); // grayman #2478 - void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ); // grayman #2478 -}; - -class idGuidedProjectile : public idProjectile { -public : - CLASS_PROTOTYPE( idGuidedProjectile ); - - idGuidedProjectile( void ); - ~idGuidedProjectile( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - virtual void Think( void ); - virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f ); - -protected: - float speed; - idEntityPtr enemy; - virtual void GetSeekPos( idVec3 &out ); - -private: - idAngles rndScale; - idAngles rndAng; - idAngles angles; - int rndUpdateTime; - float turn_max; - float clamp_dist; - bool burstMode; - bool unGuided; - float burstDist; - float burstVelocity; -}; - - -/* -=============================================================================== - - idDebris - -=============================================================================== -*/ - -class idDebris : public idEntity { -public : - CLASS_PROTOTYPE( idDebris ); - - idDebris(); - ~idDebris(); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void Spawn( void ); - - void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ); - void Launch( void ); - void Think( void ); - void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - void Explode( void ); - void Fizzle( void ); - virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); - - -private: - idEntityPtr owner; - idPhysics_RigidBody physicsObj; - const idDeclParticle * smokeFly; - int smokeFlyTime; - const idSoundShader * sndBounce; - - void Event_Explode( void ); - void Event_Fizzle( void ); -}; - -#endif /* !__GAME_PROJECTILE_H__ */ diff --git a/DarkMod/pugixml/pugiconfig.hpp b/game/pugixml/pugiconfig.hpp similarity index 100% rename from DarkMod/pugixml/pugiconfig.hpp rename to game/pugixml/pugiconfig.hpp diff --git a/DarkMod/pugixml/pugixml.cpp b/game/pugixml/pugixml.cpp similarity index 99% rename from DarkMod/pugixml/pugixml.cpp rename to game/pugixml/pugixml.cpp index 8af15f2a3..1f1ba5815 100644 --- a/DarkMod/pugixml/pugixml.cpp +++ b/game/pugixml/pugixml.cpp @@ -12,7 +12,7 @@ */ // Begin TDM -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #pragma hdrstop // end TDM diff --git a/DarkMod/pugixml/pugixml.hpp b/game/pugixml/pugixml.hpp similarity index 100% rename from DarkMod/pugixml/pugixml.hpp rename to game/pugixml/pugixml.hpp diff --git a/DarkMod/pugixml/pugixpath.cpp b/game/pugixml/pugixpath.cpp similarity index 99% rename from DarkMod/pugixml/pugixpath.cpp rename to game/pugixml/pugixpath.cpp index 93af0167d..f18ae4fd3 100644 --- a/DarkMod/pugixml/pugixpath.cpp +++ b/game/pugixml/pugixpath.cpp @@ -11,7 +11,7 @@ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ // Begin TDM -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #pragma hdrstop // end TDM @@ -784,8 +784,11 @@ namespace pugi m_eos = storage + capacity; } - std::copy(begin, end, m_end); - m_end += count; + if (m_end != NULL) + { + std::copy(begin, end, m_end); + m_end += count; + } } void xpath_node_set::truncate(iterator it) diff --git a/game/pvs.cpp b/game/pvs.cpp deleted file mode 100644 index f799f48e4..000000000 --- a/game/pvs.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -#define MAX_BOUNDS_AREAS 16 - - -typedef struct pvsPassage_s { - byte * canSee; // bit set for all portals that can be seen through this passage -} pvsPassage_t; - - -typedef struct pvsPortal_s { - int areaNum; // area this portal leads to - idWinding * w; // winding goes counter clockwise seen from the area this portal is part of - idBounds bounds; // winding bounds - idPlane plane; // winding plane, normal points towards the area this portal leads to - pvsPassage_t * passages; // passages to portals in the area this portal leads to - bool done; // true if pvs is calculated for this portal - byte * vis; // PVS for this portal - byte * mightSee; // used during construction -} pvsPortal_t; - - -typedef struct pvsArea_s { - int numPortals; // number of portals in this area - idBounds bounds; // bounds of the whole area - pvsPortal_t ** portals; // array with pointers to the portals of this area -} pvsArea_t; - - -typedef struct pvsStack_s { - struct pvsStack_s * next; // next stack entry - byte * mightSee; // bit set for all portals that might be visible through this passage/portal stack -} pvsStack_t; - - -/* -================ -idPVS::idPVS -================ -*/ -idPVS::idPVS( void ) { - int i; - - numAreas = 0; - numPortals = 0; - - connectedAreas = NULL; - areaQueue = NULL; - areaPVS = NULL; - - for ( i = 0; i < MAX_CURRENT_PVS; i++ ) { - currentPVS[i].handle.i = -1; - currentPVS[i].handle.h = 0; - currentPVS[i].pvs = NULL; - } - - pvsAreas = NULL; - pvsPortals = NULL; -} - -/* -================ -idPVS::~idPVS -================ -*/ -idPVS::~idPVS( void ) { - Shutdown(); -} - -/* -================ -idPVS::GetPortalCount -================ -*/ -int idPVS::GetPortalCount( void ) const { - int i, na, np; - - na = gameRenderWorld->NumAreas(); - np = 0; - for ( i = 0; i < na; i++ ) { - np += gameRenderWorld->NumPortalsInArea( i ); - } - return np; -} - -/* -================ -idPVS::CreatePVSData -================ -*/ -void idPVS::CreatePVSData( void ) { - int i, j, n, cp; - exitPortal_t portal; - pvsArea_t *area; - pvsPortal_t *p, **portalPtrs; - - if ( !numPortals ) { - return; - } - - pvsPortals = new pvsPortal_t[numPortals]; - pvsAreas = new pvsArea_t[numAreas]; - memset( pvsAreas, 0, numAreas * sizeof( *pvsAreas ) ); - - cp = 0; - portalPtrs = new pvsPortal_t*[numPortals]; - - for ( i = 0; i < numAreas; i++ ) { - - area = &pvsAreas[i]; - area->bounds.Clear(); - area->portals = portalPtrs + cp; - - n = gameRenderWorld->NumPortalsInArea( i ); - - for ( j = 0; j < n; j++ ) { - - portal = gameRenderWorld->GetPortal( i, j ); - - p = &pvsPortals[cp++]; - // the winding goes counter clockwise seen from this area - p->w = portal.w->Copy(); - p->areaNum = portal.areas[1]; // area[1] is always the area the portal leads to - - p->vis = new byte[portalVisBytes]; - memset( p->vis, 0, portalVisBytes ); - p->mightSee = new byte[portalVisBytes]; - memset( p->mightSee, 0, portalVisBytes ); - p->w->GetBounds( p->bounds ); - p->w->GetPlane( p->plane ); - // plane normal points to outside the area - p->plane = -p->plane; - // no PVS calculated for this portal yet - p->done = false; - - area->portals[area->numPortals] = p; - area->numPortals++; - - area->bounds += p->bounds; - } - } -} - -/* -================ -idPVS::DestroyPVSData -================ -*/ -void idPVS::DestroyPVSData( void ) { - int i; - - if ( !pvsAreas ) { - return; - } - - // delete portal pointer array - delete[] pvsAreas[0].portals; - - // delete all areas - delete[] pvsAreas; - pvsAreas = NULL; - - // delete portal data - for ( i = 0; i < numPortals; i++ ) { - delete[] pvsPortals[i].vis; - delete[] pvsPortals[i].mightSee; - delete pvsPortals[i].w; - } - - // delete portals - delete[] pvsPortals; - pvsPortals = NULL; -} - -/* -================ -idPVS::FloodFrontPortalPVS_r -================ -*/ -void idPVS::FloodFrontPortalPVS_r( pvsPortal_t *portal, int areaNum ) const { - int i, n; - pvsArea_t *area; - pvsPortal_t *p; - - area = &pvsAreas[ areaNum ]; - - for ( i = 0; i < area->numPortals; i++ ) { - p = area->portals[i]; - n = p - pvsPortals; - // don't flood through if this portal is not at the front - if ( !( portal->mightSee[ n>>3 ] & (1 << (n&7)) ) ) { - continue; - } - // don't flood through if already visited this portal - if ( portal->vis[ n>>3 ] & (1 << (n&7)) ) { - continue; - } - // this portal might be visible - portal->vis[ n>>3 ] |= (1 << (n&7)); - // flood through the portal - FloodFrontPortalPVS_r( portal, p->areaNum ); - } -} - -/* -================ -idPVS::FrontPortalPVS -================ -*/ -void idPVS::FrontPortalPVS( void ) const { - int i, j, k, n, p, side1, side2, areaSide; - pvsPortal_t *p1, *p2; - pvsArea_t *area; - - for ( i = 0; i < numPortals; i++ ) { - p1 = &pvsPortals[i]; - - for ( j = 0; j < numAreas; j++ ) { - - area = &pvsAreas[j]; - - areaSide = side1 = area->bounds.PlaneSide( p1->plane ); - - // if the whole area is at the back side of the portal - if ( areaSide == PLANESIDE_BACK ) { - continue; - } - - for ( p = 0; p < area->numPortals; p++ ) { - - p2 = area->portals[p]; - - // if we the whole area is not at the front we need to check - if ( areaSide != PLANESIDE_FRONT ) { - // if the second portal is completely at the back side of the first portal - side1 = p2->bounds.PlaneSide( p1->plane ); - if ( side1 == PLANESIDE_BACK ) { - continue; - } - } - - // if the first portal is completely at the front of the second portal - side2 = p1->bounds.PlaneSide( p2->plane ); - if ( side2 == PLANESIDE_FRONT ) { - continue; - } - - // if the second portal is not completely at the front of the first portal - if ( side1 != PLANESIDE_FRONT ) { - // more accurate check - for ( k = 0; k < p2->w->GetNumPoints(); k++ ) { - // if more than an epsilon at the front side - if ( p1->plane.Side( (*p2->w)[k].ToVec3(), ON_EPSILON ) == PLANESIDE_FRONT ) { - break; - } - } - if ( k >= p2->w->GetNumPoints() ) { - continue; // second portal is at the back of the first portal - } - } - - // if the first portal is not completely at the back side of the second portal - if ( side2 != PLANESIDE_BACK ) { - // more accurate check - for ( k = 0; k < p1->w->GetNumPoints(); k++ ) { - // if more than an epsilon at the back side - if ( p2->plane.Side( (*p1->w)[k].ToVec3(), ON_EPSILON ) == PLANESIDE_BACK ) { - break; - } - } - if ( k >= p1->w->GetNumPoints() ) { - continue; // first portal is at the front of the second portal - } - } - - // the portal might be visible at the front - n = p2 - pvsPortals; - p1->mightSee[ n >> 3 ] |= 1 << (n&7); - } - } - } - - // flood the front portal pvs for all portals - for ( i = 0; i < numPortals; i++ ) { - p1 = &pvsPortals[i]; - FloodFrontPortalPVS_r( p1, p1->areaNum ); - } -} - -/* -=============== -idPVS::FloodPassagePVS_r -=============== -*/ -pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *portal, pvsStack_t *prevStack ) const { - int i, j, n, m; - pvsPortal_t *p; - pvsArea_t *area; - pvsStack_t *stack; - pvsPassage_t *passage; - long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; - - area = &pvsAreas[portal->areaNum]; - - stack = prevStack->next; - // if no next stack entry allocated - if ( !stack ) { - stack = reinterpret_cast(new byte[sizeof(pvsStack_t) + portalVisBytes]); - stack->mightSee = (reinterpret_cast(stack)) + sizeof(pvsStack_t); - stack->next = NULL; - prevStack->next = stack; - } - - // check all portals for flooding into other areas - for ( i = 0; i < area->numPortals; i++ ) { - - passage = &portal->passages[i]; - - // if this passage is completely empty - if ( !passage->canSee ) { - continue; - } - - p = area->portals[i]; - n = p - pvsPortals; - - // if this portal cannot be seen through our current portal/passage stack - if ( !( prevStack->mightSee[n >> 3] & (1 << (n & 7)) ) ) { - continue; - } - - // mark the portal as visible - source->vis[n >> 3] |= (1 << (n & 7)); - - // get pointers to vis data - prevMightSee = reinterpret_cast(prevStack->mightSee); - passageVis = reinterpret_cast(passage->canSee); - sourceVis = reinterpret_cast(source->vis); - mightSee = reinterpret_cast(stack->mightSee); - - more = 0; - // use the portal PVS if it has been calculated - if ( p->done ) { - portalVis = reinterpret_cast(p->vis); - for ( j = 0; j < portalVisLongs; j++ ) { - // get new PVS which is decreased by going through this passage - m = *prevMightSee++ & *passageVis++ & *portalVis++; - // check if anything might be visible through this passage that wasn't yet visible - more |= (m & ~(*sourceVis++)); - // store new PVS - *mightSee++ = m; - } - } - else { - // the p->mightSee is implicitely stored in the passageVis - for ( j = 0; j < portalVisLongs; j++ ) { - // get new PVS which is decreased by going through this passage - m = *prevMightSee++ & *passageVis++; - // check if anything might be visible through this passage that wasn't yet visible - more |= (m & ~(*sourceVis++)); - // store new PVS - *mightSee++ = m; - } - } - - // if nothing more can be seen - if ( !more ) { - continue; - } - - // go through the portal - stack->next = FloodPassagePVS_r( source, p, stack ); - } - - return stack; -} - -/* -=============== -idPVS::PassagePVS -=============== -*/ -void idPVS::PassagePVS( void ) const { - int i; - pvsPortal_t *source; - pvsStack_t *stack, *s; - - // create the passages - CreatePassages(); - - // allocate first stack entry - stack = reinterpret_cast(new byte[sizeof(pvsStack_t) + portalVisBytes]); - stack->mightSee = (reinterpret_cast(stack)) + sizeof(pvsStack_t); - stack->next = NULL; - - // calculate portal PVS by flooding through the passages - for ( i = 0; i < numPortals; i++ ) { - source = &pvsPortals[i]; - memset( source->vis, 0, portalVisBytes ); - memcpy( stack->mightSee, source->mightSee, portalVisBytes ); - FloodPassagePVS_r( source, source, stack ); - source->done = true; - } - - // free the allocated stack - for ( s = stack; s; s = stack ) { - stack = stack->next; - delete[] s; - } - - // destroy the passages - DestroyPassages(); -} - -/* -=============== -idPVS::AddPassageBoundaries -=============== -*/ -void idPVS::AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const { - int i, j, k, l; - idVec3 v1, v2, normal; - float d, dist; - bool flipTest, front; - idPlane plane; - - - // check all combinations - for ( i = 0; i < source.GetNumPoints(); i++ ) { - - l = (i + 1) % source.GetNumPoints(); - v1 = source[l].ToVec3() - source[i].ToVec3(); - - // find a vertex of pass that makes a plane that puts all of the - // vertices of pass on the front side and all of the vertices of - // source on the back side - for ( j = 0; j < pass.GetNumPoints(); j++ ) { - - v2 = pass[j].ToVec3() - source[i].ToVec3(); - - normal = v1.Cross( v2 ); - if ( normal.Normalize() < 0.01f ) { - continue; - } - dist = normal * pass[j].ToVec3(); - - // - // find out which side of the generated seperating plane has the - // source portal - // - flipTest = false; - for ( k = 0; k < source.GetNumPoints(); k++ ) { - if ( k == i || k == l ) { - continue; - } - d = source[k].ToVec3() * normal - dist; - if ( d < -ON_EPSILON ) { - // source is on the negative side, so we want all - // pass and target on the positive side - flipTest = false; - break; - } - else if ( d > ON_EPSILON ) { - // source is on the positive side, so we want all - // pass and target on the negative side - flipTest = true; - break; - } - } - if ( k == source.GetNumPoints() ) { - continue; // planar with source portal - } - - // flip the normal if the source portal is backwards - if (flipTest) { - normal = -normal; - dist = -dist; - } - - // if all of the pass portal points are now on the positive side, - // this is the seperating plane - front = false; - for ( k = 0; k < pass.GetNumPoints(); k++ ) { - if ( k == j ) { - continue; - } - d = pass[k].ToVec3() * normal - dist; - if ( d < -ON_EPSILON ) { - break; - } - else if ( d > ON_EPSILON ) { - front = true; - } - } - if ( k < pass.GetNumPoints() ) { - continue; // points on negative side, not a seperating plane - } - if ( !front ) { - continue; // planar with seperating plane - } - - // flip the normal if we want the back side - if ( flipClip ) { - plane.SetNormal( -normal ); - plane.SetDist( -dist ); - } - else { - plane.SetNormal( normal ); - plane.SetDist( dist ); - } - - // check if the plane is already a passage boundary - for ( k = 0; k < numBounds; k++ ) { - if ( plane.Compare( bounds[k], 0.001f, 0.01f ) ) { - break; - } - } - if ( k < numBounds ) { - break; - } - - if ( numBounds >= maxBounds ) { - gameLocal.Warning( "max passage boundaries." ); - break; - } - bounds[numBounds] = plane; - numBounds++; - break; - } - } -} - -/* -================ -idPVS::CreatePassages -================ -*/ -#define MAX_PASSAGE_BOUNDS 128 - -void idPVS::CreatePassages( void ) const { - int i, j, l, n, numBounds, front, passageMemory, byteNum, bitNum; - int sides[MAX_PASSAGE_BOUNDS]; - idPlane passageBounds[MAX_PASSAGE_BOUNDS]; - pvsPortal_t *source, *target, *p; - pvsArea_t *area; - pvsPassage_t *passage; - idFixedWinding winding; - byte canSee, mightSee, bit; - - passageMemory = 0; - for ( i = 0; i < numPortals; i++ ) { - source = &pvsPortals[i]; - area = &pvsAreas[source->areaNum]; - - source->passages = new pvsPassage_t[area->numPortals]; - - for ( j = 0; j < area->numPortals; j++ ) { - target = area->portals[j]; - n = target - pvsPortals; - - passage = &source->passages[j]; - - // if the source portal cannot see this portal - if ( !( source->mightSee[ n>>3 ] & (1 << (n&7)) ) ) { - // not all portals in the area have to be visible because areas are not necesarily convex - // also no passage has to be created for the portal which is the opposite of the source - passage->canSee = NULL; - continue; - } - - passage->canSee = new byte[portalVisBytes]; - passageMemory += portalVisBytes; - - // boundary plane normals point inwards - numBounds = 0; - AddPassageBoundaries( *(source->w), *(target->w), false, passageBounds, numBounds, MAX_PASSAGE_BOUNDS ); - AddPassageBoundaries( *(target->w), *(source->w), true, passageBounds, numBounds, MAX_PASSAGE_BOUNDS ); - - // get all portals visible through this passage - for ( byteNum = 0; byteNum < portalVisBytes; byteNum++) { - - canSee = 0; - mightSee = source->mightSee[byteNum] & target->mightSee[byteNum]; - - // go through eight portals at a time to speed things up - for ( bitNum = 0; bitNum < 8; bitNum++ ) { - - bit = 1 << bitNum; - - if ( !( mightSee & bit ) ) { - continue; - } - - p = &pvsPortals[(byteNum << 3) + bitNum]; - - if ( p->areaNum == source->areaNum ) { - continue; - } - - for ( front = 0, l = 0; l < numBounds; l++ ) { - sides[l] = p->bounds.PlaneSide( passageBounds[l] ); - // if completely at the back of the passage bounding plane - if ( sides[l] == PLANESIDE_BACK ) { - break; - } - // if completely at the front - if ( sides[l] == PLANESIDE_FRONT ) { - front++; - } - } - // if completely outside the passage - if ( l < numBounds ) { - continue; - } - - // if not at the front of all bounding planes and thus not completely inside the passage - if ( front != numBounds ) { - - winding = *p->w; - - for ( l = 0; l < numBounds; l++ ) { - // only clip if the winding possibly crosses this plane - if ( sides[l] != PLANESIDE_CROSS ) { - continue; - } - // clip away the part at the back of the bounding plane - winding.ClipInPlace( passageBounds[l] ); - // if completely clipped away - if ( !winding.GetNumPoints() ) { - break; - } - } - // if completely outside the passage - if ( l < numBounds ) { - continue; - } - } - - canSee |= bit; - } - - // store results of all eight portals - passage->canSee[byteNum] = canSee; - } - - // can always see the target portal - passage->canSee[n >> 3] |= (1 << (n&7)); - } - } - if ( passageMemory < 1024 ) { - gameLocal.Printf( "%5d bytes passage memory used to build PVS\n", passageMemory ); - } - else { - gameLocal.Printf( "%5d KB passage memory used to build PVS\n", passageMemory>>10 ); - } -} - -/* -================ -idPVS::DestroyPassages -================ -*/ -void idPVS::DestroyPassages( void ) const { - int i, j; - pvsPortal_t *p; - pvsArea_t *area; - - for ( i = 0; i < numPortals; i++ ) { - p = &pvsPortals[i]; - area = &pvsAreas[p->areaNum]; - for ( j = 0; j < area->numPortals; j++ ) { - if ( p->passages[j].canSee ) { - delete[] p->passages[j].canSee; - } - } - delete[] p->passages; - } -} - -/* -================ -idPVS::CopyPortalPVSToMightSee -================ -*/ -void idPVS::CopyPortalPVSToMightSee( void ) const { - int i; - pvsPortal_t *p; - - for ( i = 0; i < numPortals; i++ ) { - p = &pvsPortals[i]; - memcpy( p->mightSee, p->vis, portalVisBytes ); - } -} - -/* -================ -idPVS::AreaPVSFromPortalPVS -================ -*/ -int idPVS::AreaPVSFromPortalPVS( void ) const { - int i, j, k, areaNum, totalVisibleAreas; - long *p1, *p2; - byte *pvs, *portalPVS; - pvsArea_t *area; - - totalVisibleAreas = 0; - - if ( !numPortals ) { - return totalVisibleAreas; - } - - memset( areaPVS, 0, numAreas * areaVisBytes ); - - for ( i = 0; i < numAreas; i++ ) { - area = &pvsAreas[i]; - pvs = areaPVS + i * areaVisBytes; - - // the area is visible to itself - pvs[ i >> 3 ] |= 1 << (i & 7); - - if ( !area->numPortals ) { - continue; - } - - // store the PVS of all portals in this area at the first portal - for ( j = 1; j < area->numPortals; j++ ) { - p1 = reinterpret_cast(area->portals[0]->vis); - p2 = reinterpret_cast(area->portals[j]->vis); - for ( k = 0; k < portalVisLongs; k++ ) { - *p1++ |= *p2++; - } - } - - // the portals of this area are always visible - for ( j = 0; j < area->numPortals; j++ ) { - k = area->portals[j] - pvsPortals; - area->portals[0]->vis[ k >> 3 ] |= 1 << (k & 7); - } - - // set all areas to visible that can be seen from the portals of this area - portalPVS = area->portals[0]->vis; - for ( j = 0; j < numPortals; j++ ) { - // if this portal is visible - if ( portalPVS[j>>3] & (1 << (j&7)) ) { - areaNum = pvsPortals[j].areaNum; - pvs[ areaNum >> 3 ] |= 1 << (areaNum & 7); - } - } - - // count the number of visible areas - for ( j = 0; j < numAreas; j++ ) { - if ( pvs[j>>3] & (1 << (j&7)) ) { - totalVisibleAreas++; - } - } - } - return totalVisibleAreas; -} - -/* -================ -idPVS::Init -================ -*/ -void idPVS::Init( void ) { - int totalVisibleAreas; - - Shutdown(); - - numAreas = gameRenderWorld->NumAreas(); - if ( numAreas <= 0 ) { - return; - } - - connectedAreas = new bool[numAreas]; - areaQueue = new int[numAreas]; - - areaVisBytes = ( ((numAreas+31)&~31) >> 3); - areaVisLongs = areaVisBytes/sizeof(long); - - areaPVS = new byte[numAreas * areaVisBytes]; - memset( areaPVS, 0xFF, numAreas * areaVisBytes ); - - numPortals = GetPortalCount(); - - portalVisBytes = ( ((numPortals+31)&~31) >> 3); - portalVisLongs = portalVisBytes/sizeof(long); - - for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { - currentPVS[i].handle.i = -1; - currentPVS[i].handle.h = 0; - currentPVS[i].pvs = new byte[areaVisBytes]; - memset( currentPVS[i].pvs, 0, areaVisBytes ); - } - - idTimer timer; - timer.Start(); - - CreatePVSData(); - - FrontPortalPVS(); - - CopyPortalPVSToMightSee(); - - PassagePVS(); - - totalVisibleAreas = AreaPVSFromPortalPVS(); - - DestroyPVSData(); - - timer.Stop(); - - gameLocal.Printf( "%5.0f msec to calculate PVS\n", timer.Milliseconds() ); - gameLocal.Printf( "%5d areas\n", numAreas ); - gameLocal.Printf( "%5d portals\n", numPortals ); - gameLocal.Printf( "%5d areas visible on average\n", totalVisibleAreas / numAreas ); - if ( numAreas * areaVisBytes < 1024 ) { - gameLocal.Printf( "%5d bytes PVS data\n", numAreas * areaVisBytes ); - } - else { - gameLocal.Printf( "%5d KB PVS data\n", (numAreas * areaVisBytes) >> 10 ); - } -} - -/* -================ -idPVS::Shutdown -================ -*/ -void idPVS::Shutdown( void ) { - if ( connectedAreas ) { - delete[] connectedAreas; - connectedAreas = NULL; - } - if ( areaQueue ) { - delete[] areaQueue; - areaQueue = NULL; - } - if ( areaPVS ) { - delete[] areaPVS; - areaPVS = NULL; - } - if ( currentPVS ) { - for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { - delete[] currentPVS[i].pvs; - currentPVS[i].pvs = NULL; - } - } -} - -/* -================ -idPVS::GetConnectedAreas - - assumes the 'areas' array is initialized to false -================ -*/ -void idPVS::GetConnectedAreas( int srcArea, bool *areas ) const { - int curArea, nextArea; - int queueStart, queueEnd; - int i, n; - exitPortal_t portal; - - queueStart = -1; - queueEnd = 0; - areas[srcArea] = true; - - for ( curArea = srcArea; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) { - - n = gameRenderWorld->NumPortalsInArea( curArea ); - - for ( i = 0; i < n; i++ ) { - portal = gameRenderWorld->GetPortal( curArea, i ); - - if ( portal.blockingBits & PS_BLOCK_VIEW ) { - continue; - } - - // area[1] is always the area the portal leads to - nextArea = portal.areas[1]; - - // if already visited this area - if ( areas[nextArea] ) { - continue; - } - - // add area to queue - areaQueue[queueEnd++] = nextArea; - areas[nextArea] = true; - } - } -} - -/* -================ -idPVS::GetPVSArea -================ -*/ -int idPVS::GetPVSArea( const idVec3 &point ) const { - return gameRenderWorld->PointInArea( point ); -} - -/* -================ -idPVS::GetPVSAreas -================ -*/ -int idPVS::GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const { - return gameRenderWorld->BoundsInAreas( bounds, areas, maxAreas ); -} - -/* -================ -idPVS::SetupCurrentPVS -================ -*/ -pvsHandle_t idPVS::SetupCurrentPVS( const idVec3 &source, const pvsType_t type ) const { - int sourceArea; - - sourceArea = gameRenderWorld->PointInArea( source ); - - return SetupCurrentPVS( sourceArea, type ); -} - -/* -================ -idPVS::SetupCurrentPVS -================ -*/ -pvsHandle_t idPVS::SetupCurrentPVS( const idBounds &source, const pvsType_t type ) const { - int numSourceAreas, sourceAreas[MAX_BOUNDS_AREAS]; - - numSourceAreas = gameRenderWorld->BoundsInAreas( source, sourceAreas, MAX_BOUNDS_AREAS ); - - return SetupCurrentPVS( sourceAreas, numSourceAreas, type ); -} - -/* -================ -idPVS::SetupCurrentPVS -================ -*/ -pvsHandle_t idPVS::SetupCurrentPVS( const int sourceArea, const pvsType_t type ) const { - int i; - pvsHandle_t handle; - - handle = AllocCurrentPVS( *reinterpret_cast(&sourceArea) ); - - if ( sourceArea < 0 || sourceArea >= numAreas ) { - memset( currentPVS[handle.i].pvs, 0, areaVisBytes ); - return handle; - } - - if ( type != PVS_CONNECTED_AREAS ) { - memcpy( currentPVS[handle.i].pvs, areaPVS + sourceArea * areaVisBytes, areaVisBytes ); - } else { - memset( currentPVS[handle.i].pvs, -1, areaVisBytes ); - } - - if ( type == PVS_ALL_PORTALS_OPEN ) { - return handle; - } - - memset( connectedAreas, 0, numAreas * sizeof( *connectedAreas ) ); - - GetConnectedAreas( sourceArea, connectedAreas ); - - for ( i = 0; i < numAreas; i++ ) { - if ( !connectedAreas[i] ) { - currentPVS[handle.i].pvs[i>>3] &= ~(1 << (i&7)); - } - } - - return handle; -} - -/* -================ -idPVS::SetupCurrentPVS -================ -*/ -pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const { - int i, j; - unsigned int h; - long *vis, *pvs; - pvsHandle_t handle; - - h = 0; - for ( i = 0; i < numSourceAreas; i++ ) { - h ^= *reinterpret_cast(&sourceAreas[i]); - } - handle = AllocCurrentPVS( h ); - - if ( !numSourceAreas || sourceAreas[0] < 0 || sourceAreas[0] >= numAreas) { - memset( currentPVS[handle.i].pvs, 0, areaVisBytes ); - return handle; - } - - if ( type != PVS_CONNECTED_AREAS ) { - // merge PVS of all areas the source is in - memcpy( currentPVS[handle.i].pvs, areaPVS + sourceAreas[0] * areaVisBytes, areaVisBytes ); - for ( i = 1; i < numSourceAreas; i++ ) { - - assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); - - vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); - pvs = reinterpret_cast(currentPVS[handle.i].pvs); - for ( j = 0; j < areaVisLongs; j++ ) { - *pvs++ |= *vis++; - } - } - } else { - memset( currentPVS[handle.i].pvs, -1, areaVisBytes ); - } - - if ( type == PVS_ALL_PORTALS_OPEN ) { - return handle; - } - - memset( connectedAreas, 0, numAreas * sizeof( *connectedAreas ) ); - - // get all areas connected to any of the source areas - for ( i = 0; i < numSourceAreas; i++ ) { - if ( !connectedAreas[sourceAreas[i]] ) { - GetConnectedAreas( sourceAreas[i], connectedAreas ); - } - } - - // remove unconnected areas from the PVS - for ( i = 0; i < numAreas; i++ ) { - if ( !connectedAreas[i] ) { - currentPVS[handle.i].pvs[i>>3] &= ~(1 << (i&7)); - } - } - - return handle; -} - -/* -================ -idPVS::MergeCurrentPVS -================ -*/ -pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { - int i; - long *pvs1Ptr, *pvs2Ptr, *ptr; - pvsHandle_t handle; - - if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h || - pvs2.i < 0 || pvs2.i >= MAX_CURRENT_PVS || pvs2.h != currentPVS[pvs2.i].handle.h ) { - gameLocal.Error( "idPVS::MergeCurrentPVS: invalid handle" ); - } - - handle = AllocCurrentPVS( pvs1.h ^ pvs2.h ); - - ptr = reinterpret_cast(currentPVS[handle.i].pvs); - pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); - pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); - - for ( i = 0; i < areaVisLongs; i++ ) { - *ptr++ = *pvs1Ptr++ | *pvs2Ptr++; - } - - return handle; -} - -/* -================ -idPVS::AllocCurrentPVS -================ -*/ -pvsHandle_t idPVS::AllocCurrentPVS( unsigned int h ) const { - int i; - pvsHandle_t handle; - - for ( i = 0; i < MAX_CURRENT_PVS; i++ ) { - if ( currentPVS[i].handle.i == -1 ) { - currentPVS[i].handle.i = i; - currentPVS[i].handle.h = h; -/* - // angua: debug output, shows allocated PVS numbers in front of the player - idVec3 viewPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + idVec3(0,0,50+6*i) - + gameLocal.GetLocalPlayer()->viewAngles.ToForward() * 30; - idStr maxPVS(i); - gameRenderWorld->DrawText(maxPVS.c_str(), viewPos, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec); -*/ - return currentPVS[i].handle; - } - } - - gameLocal.Error( "idPVS::AllocCurrentPVS: no free PVS left" ); - - handle.i = -1; - handle.h = 0; - return handle; -} - -/* -================ -idPVS::FreeCurrentPVS -================ -*/ -void idPVS::FreeCurrentPVS( pvsHandle_t handle ) const { - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Warning( "idPVS::FreeCurrentPVS: invalid handle" ); - return; - } - - currentPVS[handle.i].handle.i = -1; -} - -/* -================ -idPVS::InCurrentPVS -================ -*/ -bool idPVS::InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const { - int targetArea; - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || - handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); - } - - targetArea = gameRenderWorld->PointInArea( target ); - - if ( targetArea == -1 ) { - return false; - } - - return ( ( currentPVS[handle.i].pvs[targetArea>>3] & (1 << (targetArea&7)) ) != 0 ); -} - -/* -================ -idPVS::InCurrentPVS -================ -*/ -bool idPVS::InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const { - int i, numTargetAreas, targetAreas[MAX_BOUNDS_AREAS]; - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || - handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); - } - - numTargetAreas = gameRenderWorld->BoundsInAreas( target, targetAreas, MAX_BOUNDS_AREAS ); - - for ( i = 0; i < numTargetAreas; i++ ) { - if ( currentPVS[handle.i].pvs[targetAreas[i]>>3] & (1 << (targetAreas[i]&7)) ) { - return true; - } - } - return false; -} - -/* -================ -idPVS::InCurrentPVS -================ -*/ -bool idPVS::InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const { - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || - handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); - } - - if ( targetArea < 0 || targetArea >= numAreas ) { - return false; - } - - return ( ( currentPVS[handle.i].pvs[targetArea>>3] & (1 << (targetArea&7)) ) != 0 ); -} - -/* -================ -idPVS::InCurrentPVS -================ -*/ -bool idPVS::InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const { - int i; - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || - handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Error( "idPVS::InCurrentPVS: invalid handle" ); - } - - for ( i = 0; i < numTargetAreas; i++ ) { - if ( targetAreas[i] < 0 || targetAreas[i] >= numAreas ) { - continue; - } - if ( currentPVS[handle.i].pvs[targetAreas[i]>>3] & (1 << (targetAreas[i]&7)) ) { - return true; - } - } - return false; -} - -/* -================ -idPVS::DrawPVS -================ -*/ -void idPVS::DrawPVS( const idVec3 &source, const pvsType_t type ) const { - int i, j, k, numPoints, n, sourceArea; - exitPortal_t portal; - idPlane plane; - idVec3 offset; - idVec4 *color; - pvsHandle_t handle; - - sourceArea = gameRenderWorld->PointInArea( source ); - - if ( sourceArea == -1 ) { - return; - } - - handle = SetupCurrentPVS( source, type ); - - for ( j = 0; j < numAreas; j++ ) { - - if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { - continue; - } - - if ( j == sourceArea ) { - color = &colorRed; - } - else { - color = &colorCyan; - } - - n = gameRenderWorld->NumPortalsInArea( j ); - - // draw all the portals of the area - for ( i = 0; i < n; i++ ) { - portal = gameRenderWorld->GetPortal( j, i ); - - numPoints = portal.w->GetNumPoints(); - - portal.w->GetPlane( plane ); - offset = plane.Normal() * 4.0f; - for ( k = 0; k < numPoints; k++ ) { - gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); - } - } - } - - FreeCurrentPVS( handle ); -} - -/* -================ -idPVS::DrawPVS -================ -*/ -void idPVS::DrawPVS( const idBounds &source, const pvsType_t type ) const { - int i, j, k, numPoints, n, num, areas[MAX_BOUNDS_AREAS]; - exitPortal_t portal; - idPlane plane; - idVec3 offset; - idVec4 *color; - pvsHandle_t handle; - - num = gameRenderWorld->BoundsInAreas( source, areas, MAX_BOUNDS_AREAS ); - - if ( !num ) { - return; - } - - handle = SetupCurrentPVS( source, type ); - - for ( j = 0; j < numAreas; j++ ) { - - if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { - continue; - } - - for ( i = 0; i < num; i++ ) { - if ( j == areas[i] ) { - break; - } - } - if ( i < num ) { - color = &colorRed; - } - else { - color = &colorCyan; - } - - n = gameRenderWorld->NumPortalsInArea( j ); - - // draw all the portals of the area - for ( i = 0; i < n; i++ ) { - portal = gameRenderWorld->GetPortal( j, i ); - - numPoints = portal.w->GetNumPoints(); - - portal.w->GetPlane( plane ); - offset = plane.Normal() * 4.0f; - for ( k = 0; k < numPoints; k++ ) { - gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); - } - } - } - - FreeCurrentPVS( handle ); -} - -/* -================ -idPVS::DrawPVS -================ -*/ -void idPVS::DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const { - int i, j, k, numPoints, n, sourceArea; - exitPortal_t portal; - idPlane plane; - idVec3 offset; - idVec4 *color; - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || - handle.h != currentPVS[handle.i].handle.h ) { - gameLocal.Error( "idPVS::DrawCurrentPVS: invalid handle" ); - } - - sourceArea = gameRenderWorld->PointInArea( source ); - - if ( sourceArea == -1 ) { - return; - } - - for ( j = 0; j < numAreas; j++ ) { - - if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { - continue; - } - - if ( j == sourceArea ) { - color = &colorRed; - } - else { - color = &colorCyan; - } - - n = gameRenderWorld->NumPortalsInArea( j ); - - // draw all the portals of the area - for ( i = 0; i < n; i++ ) { - portal = gameRenderWorld->GetPortal( j, i ); - - numPoints = portal.w->GetNumPoints(); - - portal.w->GetPlane( plane ); - offset = plane.Normal() * 4.0f; - for ( k = 0; k < numPoints; k++ ) { - gameRenderWorld->DebugLine( *color, (*portal.w)[k].ToVec3() + offset, (*portal.w)[(k+1)%numPoints].ToVec3() + offset ); - } - } - } -} - -#if ASYNC_WRITE_PVS - -/* -=================== -idPVS::WritePVS -=================== -*/ -void idPVS::WritePVS( const pvsHandle_t handle, idBitMsg &msg ) { - msg.WriteData( currentPVS[ handle.i ].pvs, areaVisBytes ); -} - -/* -=================== -idPVS::ReadPVS -=================== -*/ -void idPVS::ReadPVS( const pvsHandle_t handle, const idBitMsg &msg ) { - byte l_pvs[ 256 ]; - int i; - - assert( areaVisBytes <= 256 ); - msg.ReadData( l_pvs, areaVisBytes ); - if ( memcmp( l_pvs, currentPVS[ handle.i ].pvs, areaVisBytes ) ) { - common->Printf( "PVS not matching ( %d areaVisBytes ) - server then client:\n", areaVisBytes ); - for ( i = 0; i < areaVisBytes; i++ ) { - common->Printf( "%x ", l_pvs[ i ] ); - } - common->Printf( "\n" ); - for ( i = 0; i < areaVisBytes; i++ ) { - common->Printf( "%x ", currentPVS[ handle.i ].pvs[ i ] ); - } - common->Printf( "\n" ); - } -} - -#endif - - -/* -================ -idPVS::CheckAreasForPortalSky -================ -*/ -bool idPVS::CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin ) { - int j, sourceArea; - - if ( handle.i < 0 || handle.i >= MAX_CURRENT_PVS || handle.h != currentPVS[handle.i].handle.h ) { - return false; - } - - sourceArea = gameRenderWorld->PointInArea( origin ); - - if ( sourceArea == -1 ) { - return false; - } - - for ( j = 0; j < numAreas; j++ ) { - - if ( !( currentPVS[handle.i].pvs[j>>3] & (1 << (j&7)) ) ) { - continue; - } - - if ( gameRenderWorld->CheckAreaForPortalSky( j ) ) { - return true; - } - } - - return false; -} diff --git a/game/pvs.h b/game/pvs.h deleted file mode 100644 index 134a5c2ed..000000000 --- a/game/pvs.h +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_PVS_H__ -#define __GAME_PVS_H__ - -/* -=================================================================================== - - PVS - - Note: mirrors and other special view portals are not taken into account - -=================================================================================== -*/ - - -typedef struct pvsHandle_s { - int i; // index to current pvs - unsigned int h; // handle for current pvs -} pvsHandle_t; - - -typedef struct pvsCurrent_s { - pvsHandle_t handle; // current pvs handle - byte * pvs; // current pvs bit string -} pvsCurrent_t; - -#define MAX_CURRENT_PVS 16 // must be a power of 2 - -typedef enum { - PVS_NORMAL = 0, // PVS through portals taking portal states into account - PVS_ALL_PORTALS_OPEN = 1, // PVS through portals assuming all portals are open - PVS_CONNECTED_AREAS = 2 // PVS considering all topologically connected areas visible -} pvsType_t; - - -class idPVS { -public: - idPVS( void ); - ~idPVS( void ); - // setup for the current map - void Init( void ); - void Shutdown( void ); - // get the area(s) the source is in - int GetPVSArea( const idVec3 &point ) const; // returns the area number - int GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const; // returns number of areas - // setup current PVS for the source - pvsHandle_t SetupCurrentPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const; - pvsHandle_t SetupCurrentPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const; - pvsHandle_t SetupCurrentPVS( const int sourceArea, const pvsType_t type = PVS_NORMAL ) const; - pvsHandle_t SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type = PVS_NORMAL ) const; - pvsHandle_t MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const; - void FreeCurrentPVS( pvsHandle_t handle ) const; - // returns true if the target is within the current PVS - bool InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const; - bool InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const; - bool InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const; - bool InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const; - // draw all portals that are within the PVS of the source - void DrawPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const; - void DrawPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const; - // visualize the PVS the handle points to - void DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const; - -#if ASYNC_WRITE_PVS - void WritePVS( const pvsHandle_t handle, idBitMsg &msg ); - void ReadPVS( const pvsHandle_t handle, const idBitMsg &msg ); -#endif - - bool CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin ); - -private: - int numAreas; - int numPortals; - bool * connectedAreas; - int * areaQueue; - byte * areaPVS; - // current PVS for a specific source possibly taking portal states (open/closed) into account - mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; - // used to create PVS - int portalVisBytes; - int portalVisLongs; - int areaVisBytes; - int areaVisLongs; - struct pvsPortal_s * pvsPortals; - struct pvsArea_s * pvsAreas; - -private: - int GetPortalCount( void ) const; - void CreatePVSData( void ); - void DestroyPVSData( void ); - void CopyPortalPVSToMightSee( void ) const; - void FloodFrontPortalPVS_r( struct pvsPortal_s *portal, int areaNum ) const; - void FrontPortalPVS( void ) const; - struct pvsStack_s * FloodPassagePVS_r( struct pvsPortal_s *source, const struct pvsPortal_s *portal, struct pvsStack_s *prevStack ) const; - void PassagePVS( void ) const; - void AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const; - void CreatePassages( void ) const; - void DestroyPassages( void ) const; - int AreaPVSFromPortalPVS( void ) const; - void GetConnectedAreas( int srcArea, bool *connectedAreas ) const; - pvsHandle_t AllocCurrentPVS( unsigned int h ) const; -}; - -#endif /* !__GAME_PVS_H__ */ diff --git a/DarkMod/randomizer/_lrotl.h b/game/randomizer/_lrotl.h similarity index 100% rename from DarkMod/randomizer/_lrotl.h rename to game/randomizer/_lrotl.h diff --git a/DarkMod/randomizer/ex-ran.cpp b/game/randomizer/ex-ran.cpp similarity index 100% rename from DarkMod/randomizer/ex-ran.cpp rename to game/randomizer/ex-ran.cpp diff --git a/DarkMod/randomizer/licence.htm b/game/randomizer/licence.htm similarity index 100% rename from DarkMod/randomizer/licence.htm rename to game/randomizer/licence.htm diff --git a/DarkMod/randomizer/mersenne.cpp b/game/randomizer/mersenne.cpp similarity index 87% rename from DarkMod/randomizer/mersenne.cpp rename to game/randomizer/mersenne.cpp index ce13b98fa..00e005a89 100644 --- a/DarkMod/randomizer/mersenne.cpp +++ b/game/randomizer/mersenne.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /************************** MERSENNE.CPP ******************** AgF 2001-10-18 * * Random Number generator 'Mersenne Twister' * * * diff --git a/DarkMod/randomizer/mother.cpp b/game/randomizer/mother.cpp similarity index 78% rename from DarkMod/randomizer/mother.cpp rename to game/randomizer/mother.cpp index fe8a8a2d1..88d34879f 100644 --- a/DarkMod/randomizer/mother.cpp +++ b/game/randomizer/mother.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /************************** MOTHER.CPP ****************** AgF 1999-03-03 * * 'Mother-of-All' random number generator * * * diff --git a/DarkMod/randomizer/rancombi.h b/game/randomizer/rancombi.h similarity index 77% rename from DarkMod/randomizer/rancombi.h rename to game/randomizer/rancombi.h index caac4ad1d..791c3e3a5 100644 --- a/DarkMod/randomizer/rancombi.h +++ b/game/randomizer/rancombi.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /************************ RANCOMBI.CPP ****************** AgF 2001-10-18 * * * * This file defines a template class for combining two different * diff --git a/DarkMod/randomizer/randomc.h b/game/randomizer/randomc.h similarity index 90% rename from DarkMod/randomizer/randomc.h rename to game/randomizer/randomc.h index fcb74b64f..fcfc84d5b 100644 --- a/DarkMod/randomizer/randomc.h +++ b/game/randomizer/randomc.h @@ -78,20 +78,24 @@ * GNU General Public License www.gnu.org/copyleft/gpl.html *******************************************************************************/ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * - * $Log$ - * Revision 1.1 2006/11/04 10:47:28 sparhawk - * Advanced randomizer added. - * - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef RANDOMC_H #define RANDOMC_H diff --git a/DarkMod/randomizer/randomc.htm b/game/randomizer/randomc.htm similarity index 100% rename from DarkMod/randomizer/randomc.htm rename to game/randomizer/randomc.htm diff --git a/DarkMod/randomizer/ranrotb.cpp b/game/randomizer/ranrotb.cpp similarity index 86% rename from DarkMod/randomizer/ranrotb.cpp rename to game/randomizer/ranrotb.cpp index b9346f3c6..b797aff01 100644 --- a/DarkMod/randomizer/ranrotb.cpp +++ b/game/randomizer/ranrotb.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /************************* RANROTB.CPP ****************** AgF 1999-03-03 * * Random Number generator 'RANROT' type B * * * diff --git a/DarkMod/randomizer/ranrotw.cpp b/game/randomizer/ranrotw.cpp similarity index 87% rename from DarkMod/randomizer/ranrotw.cpp rename to game/randomizer/ranrotw.cpp index 99fd94a4b..a2c6d6ecd 100644 --- a/DarkMod/randomizer/ranrotw.cpp +++ b/game/randomizer/ranrotw.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /************************* RANROTW.CPP ****************** AgF 1999-03-03 * * Random Number generator 'RANROT' type W * * This version is used when a resolution higher that 32 bits is desired.* diff --git a/DarkMod/randomizer/userintf.cpp b/game/randomizer/userintf.cpp similarity index 100% rename from DarkMod/randomizer/userintf.cpp rename to game/randomizer/userintf.cpp diff --git a/game/script/Script_Compiler.cpp b/game/script/Script_Compiler.cpp new file mode 100644 index 000000000..f7fe9d124 --- /dev/null +++ b/game/script/Script_Compiler.cpp @@ -0,0 +1,2643 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +#define FUNCTION_PRIORITY 2 +#define INT_PRIORITY 2 +#define NOT_PRIORITY 5 +#define TILDE_PRIORITY 5 +#define TOP_PRIORITY 7 + +bool idCompiler::punctuationValid[ 256 ]; +char *idCompiler::punctuation[] = { + "+=", "-=", "*=", "/=", "%=", "&=", "|=", "++", "--", + "&&", "||", "<=", ">=", "==", "!=", "::", ";", ",", + "~", "!", "*", "/", "%", "(", ")", "-", "+", + "=", "[", "]", ".", "<", ">" , "&", "|", ":", NULL +}; + +opcode_t idCompiler::opcodes[] = { + { "", "RETURN", -1, false, &def_void, &def_void, &def_void }, + + { "++", "UINC_F", 1, true, &def_float, &def_void, &def_void }, + { "++", "UINCP_F", 1, true, &def_object, &def_field, &def_float }, + { "--", "UDEC_F", 1, true, &def_float, &def_void, &def_void }, + { "--", "UDECP_F", 1, true, &def_object, &def_field, &def_float }, + + { "~", "COMP_F", -1, false, &def_float, &def_void, &def_float }, + + { "*", "MUL_F", 3, false, &def_float, &def_float, &def_float }, + { "*", "MUL_V", 3, false, &def_vector, &def_vector, &def_float }, + { "*", "MUL_FV", 3, false, &def_float, &def_vector, &def_vector }, + { "*", "MUL_VF", 3, false, &def_vector, &def_float, &def_vector }, + + { "/", "DIV", 3, false, &def_float, &def_float, &def_float }, + { "%", "MOD_F", 3, false, &def_float, &def_float, &def_float }, + + { "+", "ADD_F", 4, false, &def_float, &def_float, &def_float }, + { "+", "ADD_V", 4, false, &def_vector, &def_vector, &def_vector }, + { "+", "ADD_S", 4, false, &def_string, &def_string, &def_string }, + { "+", "ADD_FS", 4, false, &def_float, &def_string, &def_string }, + { "+", "ADD_SF", 4, false, &def_string, &def_float, &def_string }, + { "+", "ADD_VS", 4, false, &def_vector, &def_string, &def_string }, + { "+", "ADD_SV", 4, false, &def_string, &def_vector, &def_string }, + + { "-", "SUB_F", 4, false, &def_float, &def_float, &def_float }, + { "-", "SUB_V", 4, false, &def_vector, &def_vector, &def_vector }, + + { "==", "EQ_F", 5, false, &def_float, &def_float, &def_float }, + { "==", "EQ_V", 5, false, &def_vector, &def_vector, &def_float }, + { "==", "EQ_S", 5, false, &def_string, &def_string, &def_float }, + { "==", "EQ_E", 5, false, &def_entity, &def_entity, &def_float }, + { "==", "EQ_EO", 5, false, &def_entity, &def_object, &def_float }, + { "==", "EQ_OE", 5, false, &def_object, &def_entity, &def_float }, + { "==", "EQ_OO", 5, false, &def_object, &def_object, &def_float }, + + { "!=", "NE_F", 5, false, &def_float, &def_float, &def_float }, + { "!=", "NE_V", 5, false, &def_vector, &def_vector, &def_float }, + { "!=", "NE_S", 5, false, &def_string, &def_string, &def_float }, + { "!=", "NE_E", 5, false, &def_entity, &def_entity, &def_float }, + { "!=", "NE_EO", 5, false, &def_entity, &def_object, &def_float }, + { "!=", "NE_OE", 5, false, &def_object, &def_entity, &def_float }, + { "!=", "NE_OO", 5, false, &def_object, &def_object, &def_float }, + + { "<=", "LE", 5, false, &def_float, &def_float, &def_float }, + { ">=", "GE", 5, false, &def_float, &def_float, &def_float }, + { "<", "LT", 5, false, &def_float, &def_float, &def_float }, + { ">", "GT", 5, false, &def_float, &def_float, &def_float }, + + { ".", "INDIRECT_F", 1, false, &def_object, &def_field, &def_float }, + { ".", "INDIRECT_V", 1, false, &def_object, &def_field, &def_vector }, + { ".", "INDIRECT_S", 1, false, &def_object, &def_field, &def_string }, + { ".", "INDIRECT_E", 1, false, &def_object, &def_field, &def_entity }, + { ".", "INDIRECT_BOOL", 1, false, &def_object, &def_field, &def_boolean }, + { ".", "INDIRECT_OBJ", 1, false, &def_object, &def_field, &def_object }, + + { ".", "ADDRESS", 1, false, &def_entity, &def_field, &def_pointer }, + + { ".", "EVENTCALL", 2, false, &def_entity, &def_function, &def_void }, + { ".", "OBJECTCALL", 2, false, &def_object, &def_function, &def_void }, + { ".", "SYSCALL", 2, false, &def_void, &def_function, &def_void }, + + { "=", "STORE_F", 6, true, &def_float, &def_float, &def_float }, + { "=", "STORE_V", 6, true, &def_vector, &def_vector, &def_vector }, + { "=", "STORE_S", 6, true, &def_string, &def_string, &def_string }, + { "=", "STORE_ENT", 6, true, &def_entity, &def_entity, &def_entity }, + { "=", "STORE_BOOL", 6, true, &def_boolean, &def_boolean, &def_boolean }, + { "=", "STORE_OBJENT", 6, true, &def_object, &def_entity, &def_object }, + { "=", "STORE_OBJ", 6, true, &def_object, &def_object, &def_object }, + { "=", "STORE_OBJENT", 6, true, &def_entity, &def_object, &def_object }, + + { "=", "STORE_FTOS", 6, true, &def_string, &def_float, &def_string }, + { "=", "STORE_BTOS", 6, true, &def_string, &def_boolean, &def_string }, + { "=", "STORE_VTOS", 6, true, &def_string, &def_vector, &def_string }, + { "=", "STORE_FTOBOOL", 6, true, &def_boolean, &def_float, &def_boolean }, + { "=", "STORE_BOOLTOF", 6, true, &def_float, &def_boolean, &def_float }, + + { "=", "STOREP_F", 6, true, &def_pointer, &def_float, &def_float }, + { "=", "STOREP_V", 6, true, &def_pointer, &def_vector, &def_vector }, + { "=", "STOREP_S", 6, true, &def_pointer, &def_string, &def_string }, + { "=", "STOREP_ENT", 6, true, &def_pointer, &def_entity, &def_entity }, + { "=", "STOREP_FLD", 6, true, &def_pointer, &def_field, &def_field }, + { "=", "STOREP_BOOL", 6, true, &def_pointer, &def_boolean, &def_boolean }, + { "=", "STOREP_OBJ", 6, true, &def_pointer, &def_object, &def_object }, + { "=", "STOREP_OBJENT", 6, true, &def_pointer, &def_object, &def_object }, + + { "<=>", "STOREP_FTOS", 6, true, &def_pointer, &def_float, &def_string }, + { "<=>", "STOREP_BTOS", 6, true, &def_pointer, &def_boolean, &def_string }, + { "<=>", "STOREP_VTOS", 6, true, &def_pointer, &def_vector, &def_string }, + { "<=>", "STOREP_FTOBOOL", 6, true, &def_pointer, &def_float, &def_boolean }, + { "<=>", "STOREP_BOOLTOF", 6, true, &def_pointer, &def_boolean, &def_float }, + + { "*=", "UMUL_F", 6, true, &def_float, &def_float, &def_void }, + { "*=", "UMUL_V", 6, true, &def_vector, &def_float, &def_void }, + { "/=", "UDIV_F", 6, true, &def_float, &def_float, &def_void }, + { "/=", "UDIV_V", 6, true, &def_vector, &def_float, &def_void }, + { "%=", "UMOD_F", 6, true, &def_float, &def_float, &def_void }, + { "+=", "UADD_F", 6, true, &def_float, &def_float, &def_void }, + { "+=", "UADD_V", 6, true, &def_vector, &def_vector, &def_void }, + { "-=", "USUB_F", 6, true, &def_float, &def_float, &def_void }, + { "-=", "USUB_V", 6, true, &def_vector, &def_vector, &def_void }, + { "&=", "UAND_F", 6, true, &def_float, &def_float, &def_void }, + { "|=", "UOR_F", 6, true, &def_float, &def_float, &def_void }, + + { "!", "NOT_BOOL", -1, false, &def_boolean, &def_void, &def_float }, + { "!", "NOT_F", -1, false, &def_float, &def_void, &def_float }, + { "!", "NOT_V", -1, false, &def_vector, &def_void, &def_float }, + { "!", "NOT_S", -1, false, &def_vector, &def_void, &def_float }, + { "!", "NOT_ENT", -1, false, &def_entity, &def_void, &def_float }, + + { "", "NEG_F", -1, false, &def_float, &def_void, &def_float }, + { "", "NEG_V", -1, false, &def_vector, &def_void, &def_vector }, + + { "int", "INT_F", -1, false, &def_float, &def_void, &def_float }, + + { "", "IF", -1, false, &def_float, &def_jumpoffset, &def_void }, + { "", "IFNOT", -1, false, &def_float, &def_jumpoffset, &def_void }, + + // calls returns REG_RETURN + { "", "CALL", -1, false, &def_function, &def_argsize, &def_void }, + { "", "THREAD", -1, false, &def_function, &def_argsize, &def_void }, + { "", "OBJTHREAD", -1, false, &def_function, &def_argsize, &def_void }, + + { "", "PUSH_F", -1, false, &def_float, &def_float, &def_void }, + { "", "PUSH_V", -1, false, &def_vector, &def_vector, &def_void }, + { "", "PUSH_S", -1, false, &def_string, &def_string, &def_void }, + { "", "PUSH_ENT", -1, false, &def_entity, &def_entity, &def_void }, + { "", "PUSH_OBJ", -1, false, &def_object, &def_object, &def_void }, + { "", "PUSH_OBJENT", -1, false, &def_entity, &def_object, &def_void }, + { "", "PUSH_FTOS", -1, false, &def_string, &def_float, &def_void }, + { "", "PUSH_BTOF", -1, false, &def_float, &def_boolean, &def_void }, + { "", "PUSH_FTOB", -1, false, &def_boolean, &def_float, &def_void }, + { "", "PUSH_VTOS", -1, false, &def_string, &def_vector, &def_void }, + { "", "PUSH_BTOS", -1, false, &def_string, &def_boolean, &def_void }, + + { "", "GOTO", -1, false, &def_jumpoffset, &def_void, &def_void }, + + { "&&", "AND", 7, false, &def_float, &def_float, &def_float }, + { "&&", "AND_BOOLF", 7, false, &def_boolean, &def_float, &def_float }, + { "&&", "AND_FBOOL", 7, false, &def_float, &def_boolean, &def_float }, + { "&&", "AND_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float }, + { "||", "OR", 7, false, &def_float, &def_float, &def_float }, + { "||", "OR_BOOLF", 7, false, &def_boolean, &def_float, &def_float }, + { "||", "OR_FBOOL", 7, false, &def_float, &def_boolean, &def_float }, + { "||", "OR_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float }, + + { "&", "BITAND", 3, false, &def_float, &def_float, &def_float }, + { "|", "BITOR", 3, false, &def_float, &def_float, &def_float }, + + { "", "BREAK", -1, false, &def_float, &def_void, &def_void }, + { "", "CONTINUE", -1, false, &def_float, &def_void, &def_void }, + + { NULL } +}; + +/* +================ +idCompiler::idCompiler() +================ +*/ +idCompiler::idCompiler() { + char **ptr; + int id; + + // make sure we have the right # of opcodes in the table + assert( ( sizeof( opcodes ) / sizeof( opcodes[ 0 ] ) ) == ( NUM_OPCODES + 1 ) ); + + eof = true; + parserPtr = &parser; + + callthread = false; + loopDepth = 0; + eof = false; + braceDepth = 0; + immediateType = NULL; + basetype = NULL; + currentLineNumber = 0; + currentFileNumber = 0; + errorCount = 0; + console = false; + scope = &def_namespace; + + memset( &immediate, 0, sizeof( immediate ) ); + memset( punctuationValid, 0, sizeof( punctuationValid ) ); + for( ptr = punctuation; *ptr != NULL; ptr++ ) { + id = parserPtr->GetPunctuationId( *ptr ); + if ( ( id >= 0 ) && ( id < 256 ) ) { + punctuationValid[ id ] = true; + } + } +} + +/* +============ +idCompiler::Error + +Aborts the current file load +============ +*/ +void idCompiler::Error( const char *message, ... ) const { + va_list argptr; + char string[ 1024 ]; + + va_start( argptr, message ); + vsprintf( string, message, argptr ); + va_end( argptr ); + + throw idCompileError( string ); +} + +/* +============ +idCompiler::Warning + +Prints a warning about the current line +============ +*/ +void idCompiler::Warning( const char *message, ... ) const { + va_list argptr; + char string[ 1024 ]; + + va_start( argptr, message ); + vsprintf( string, message, argptr ); + va_end( argptr ); + + parserPtr->Warning( "%s", string ); +} + +/* +============ +idCompiler::VirtualFunctionConstant + +Creates a def for an index into a virtual function table +============ +*/ +ID_INLINE idVarDef *idCompiler::VirtualFunctionConstant( idVarDef *func ) { + eval_t eval; + + memset( &eval, 0, sizeof( eval ) ); + eval._int = func->scope->TypeDef()->GetFunctionNumber( func->value.functionPtr ); + if ( eval._int < 0 ) { + Error( "Function '%s' not found in scope '%s'", func->Name(), func->scope->Name() ); + } + + return GetImmediate( &type_virtualfunction, &eval, "" ); +} + +/* +============ +idCompiler::SizeConstant + +Creates a def for a size constant +============ +*/ +ID_INLINE idVarDef *idCompiler::SizeConstant( int size ) { + eval_t eval; + + memset( &eval, 0, sizeof( eval ) ); + eval._int = size; + return GetImmediate( &type_argsize, &eval, "" ); +} + +/* +============ +idCompiler::JumpConstant + +Creates a def for a jump constant +============ +*/ +ID_INLINE idVarDef *idCompiler::JumpConstant( int value ) { + eval_t eval; + + memset( &eval, 0, sizeof( eval ) ); + eval._int = value; + return GetImmediate( &type_jumpoffset, &eval, "" ); +} + +/* +============ +idCompiler::JumpDef + +Creates a def for a relative jump from one code location to another +============ +*/ +ID_INLINE idVarDef *idCompiler::JumpDef( int jumpfrom, int jumpto ) { + return JumpConstant( jumpto - jumpfrom ); +} + +/* +============ +idCompiler::JumpTo + +Creates a def for a relative jump from current code location +============ +*/ +ID_INLINE idVarDef *idCompiler::JumpTo( int jumpto ) { + return JumpDef( gameLocal.program.NumStatements(), jumpto ); +} + +/* +============ +idCompiler::JumpFrom + +Creates a def for a relative jump from code location to current code location +============ +*/ +ID_INLINE idVarDef *idCompiler::JumpFrom( int jumpfrom ) { + return JumpDef( jumpfrom, gameLocal.program.NumStatements() ); +} + +/* +============ +idCompiler::Divide +============ +*/ +ID_INLINE float idCompiler::Divide( float numerator, float denominator ) { + if ( denominator == 0 ) { + Error( "Divide by zero" ); + return 0; + } + + return numerator / denominator; +} + +/* +============ +idCompiler::FindImmediate + +tries to find an existing immediate with the same value +============ +*/ +idVarDef *idCompiler::FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const { + idVarDef *def; + etype_t etype; + + etype = type->Type(); + + // check for a constant with the same value + for( def = gameLocal.program.GetDefList( "" ); def != NULL; def = def->Next() ) { + if ( def->TypeDef() != type ) { + continue; + } + + switch( etype ) { + case ev_field : + if ( *def->value.intPtr == eval->_int ) { + return def; + } + break; + + case ev_argsize : + if ( def->value.argSize == eval->_int ) { + return def; + } + break; + + case ev_jumpoffset : + if ( def->value.jumpOffset == eval->_int ) { + return def; + } + break; + + case ev_entity : + if ( *def->value.intPtr == eval->entity ) { + return def; + } + break; + + case ev_string : + if ( idStr::Cmp( def->value.stringPtr, string ) == 0 ) { + return def; + } + break; + + case ev_float : + if ( *def->value.floatPtr == eval->_float ) { + return def; + } + break; + + case ev_virtualfunction : + if ( def->value.virtualFunction == eval->_int ) { + return def; + } + break; + + + case ev_vector : + if ( ( def->value.vectorPtr->x == eval->vector[ 0 ] ) && + ( def->value.vectorPtr->y == eval->vector[ 1 ] ) && + ( def->value.vectorPtr->z == eval->vector[ 2 ] ) ) { + return def; + } + break; + + default : + Error( "weird immediate type" ); + break; + } + } + + return NULL; +} + +/* +============ +idCompiler::GetImmediate + +returns an existing immediate with the same value, or allocates a new one +============ +*/ +idVarDef *idCompiler::GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ) { + idVarDef *def; + + def = FindImmediate( type, eval, string ); + if ( def ) { + def->numUsers++; + } else { + // allocate a new def + def = gameLocal.program.AllocDef( type, "", &def_namespace, true ); + if ( type->Type() == ev_string ) { + def->SetString( string, true ); + } else { + def->SetValue( *eval, true ); + } + } + + return def; +} + +/* +============ +idCompiler::OptimizeOpcode + +try to optimize when the operator works on constants only +============ +*/ +idVarDef *idCompiler::OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { + eval_t c; + idTypeDef *type; + + if ( var_a && var_a->initialized != idVarDef::initializedConstant ) { + return NULL; + } + if ( var_b && var_b->initialized != idVarDef::initializedConstant ) { + return NULL; + } + + idVec3 &vec_c = *reinterpret_cast( &c.vector[ 0 ] ); + + memset( &c, 0, sizeof( c ) ); + switch( op - opcodes ) { + case OP_ADD_F: c._float = *var_a->value.floatPtr + *var_b->value.floatPtr; type = &type_float; break; + case OP_ADD_V: vec_c = *var_a->value.vectorPtr + *var_b->value.vectorPtr; type = &type_vector; break; + case OP_SUB_F: c._float = *var_a->value.floatPtr - *var_b->value.floatPtr; type = &type_float; break; + case OP_SUB_V: vec_c = *var_a->value.vectorPtr - *var_b->value.vectorPtr; type = &type_vector; break; + case OP_MUL_F: c._float = *var_a->value.floatPtr * *var_b->value.floatPtr; type = &type_float; break; + case OP_MUL_V: c._float = *var_a->value.vectorPtr * *var_b->value.vectorPtr; type = &type_float; break; + case OP_MUL_FV: vec_c = *var_b->value.vectorPtr * *var_a->value.floatPtr; type = &type_vector; break; + case OP_MUL_VF: vec_c = *var_a->value.vectorPtr * *var_b->value.floatPtr; type = &type_vector; break; + case OP_DIV_F: c._float = Divide( *var_a->value.floatPtr, *var_b->value.floatPtr ); type = &type_float; break; + case OP_MOD_F: c._float = (int)*var_a->value.floatPtr % (int)*var_b->value.floatPtr; type = &type_float; break; + case OP_BITAND: c._float = ( int )*var_a->value.floatPtr & ( int )*var_b->value.floatPtr; type = &type_float; break; + case OP_BITOR: c._float = ( int )*var_a->value.floatPtr | ( int )*var_b->value.floatPtr; type = &type_float; break; + case OP_GE: c._float = *var_a->value.floatPtr >= *var_b->value.floatPtr; type = &type_float; break; + case OP_LE: c._float = *var_a->value.floatPtr <= *var_b->value.floatPtr; type = &type_float; break; + case OP_GT: c._float = *var_a->value.floatPtr > *var_b->value.floatPtr; type = &type_float; break; + case OP_LT: c._float = *var_a->value.floatPtr < *var_b->value.floatPtr; type = &type_float; break; + case OP_AND: c._float = *var_a->value.floatPtr && *var_b->value.floatPtr; type = &type_float; break; + case OP_OR: c._float = *var_a->value.floatPtr || *var_b->value.floatPtr; type = &type_float; break; + case OP_NOT_BOOL: c._int = !*var_a->value.intPtr; type = &type_boolean; break; + case OP_NOT_F: c._float = !*var_a->value.floatPtr; type = &type_float; break; + case OP_NOT_V: c._float = !var_a->value.vectorPtr->x && !var_a->value.vectorPtr->y && !var_a->value.vectorPtr->z; type = &type_float; break; + case OP_NEG_F: c._float = -*var_a->value.floatPtr; type = &type_float; break; + case OP_NEG_V: vec_c = -*var_a->value.vectorPtr; type = &type_vector; break; + case OP_INT_F: c._float = ( int )*var_a->value.floatPtr; type = &type_float; break; + case OP_EQ_F: c._float = ( *var_a->value.floatPtr == *var_b->value.floatPtr ); type = &type_float; break; + case OP_EQ_V: c._float = var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; + case OP_EQ_E: c._float = ( *var_a->value.intPtr == *var_b->value.intPtr ); type = &type_float; break; + case OP_NE_F: c._float = ( *var_a->value.floatPtr != *var_b->value.floatPtr ); type = &type_float; break; + case OP_NE_V: c._float = !var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; + case OP_NE_E: c._float = ( *var_a->value.intPtr != *var_b->value.intPtr ); type = &type_float; break; + case OP_UADD_F: c._float = *var_b->value.floatPtr + *var_a->value.floatPtr; type = &type_float; break; + case OP_USUB_F: c._float = *var_b->value.floatPtr - *var_a->value.floatPtr; type = &type_float; break; + case OP_UMUL_F: c._float = *var_b->value.floatPtr * *var_a->value.floatPtr; type = &type_float; break; + case OP_UDIV_F: c._float = Divide( *var_b->value.floatPtr, *var_a->value.floatPtr ); type = &type_float; break; + case OP_UMOD_F: c._float = ( int ) *var_b->value.floatPtr % ( int )*var_a->value.floatPtr; type = &type_float; break; + case OP_UOR_F: c._float = ( int )*var_b->value.floatPtr | ( int )*var_a->value.floatPtr; type = &type_float; break; + case OP_UAND_F: c._float = ( int )*var_b->value.floatPtr & ( int )*var_a->value.floatPtr; type = &type_float; break; + case OP_UINC_F: c._float = *var_a->value.floatPtr + 1; type = &type_float; break; + case OP_UDEC_F: c._float = *var_a->value.floatPtr - 1; type = &type_float; break; + case OP_COMP_F: c._float = ( float )~( int )*var_a->value.floatPtr; type = &type_float; break; + default: type = NULL; break; + } + + if ( !type ) { + return NULL; + } + + if ( var_a ) { + var_a->numUsers--; + if ( var_a->numUsers <= 0 ) { + gameLocal.program.FreeDef( var_a, NULL ); + } + } + if ( var_b ) { + var_b->numUsers--; + if ( var_b->numUsers <= 0 ) { + gameLocal.program.FreeDef( var_b, NULL ); + } + } + + return GetImmediate( type, &c, "" ); +} + +/* +============ +idCompiler::EmitOpcode + +Emits a primitive statement, returning the var it places it's value in +============ +*/ +idVarDef *idCompiler::EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { + statement_t *statement; + idVarDef *var_c; + + var_c = OptimizeOpcode( op, var_a, var_b ); + if ( var_c ) { + return var_c; + } + + if ( var_a && !strcmp( var_a->Name(), RESULT_STRING ) ) { + var_a->numUsers++; + } + if ( var_b && !strcmp( var_b->Name(), RESULT_STRING ) ) { + var_b->numUsers++; + } + + statement = gameLocal.program.AllocStatement(); + statement->linenumber = currentLineNumber; + statement->file = currentFileNumber; + + if ( ( op->type_c == &def_void ) || op->rightAssociative ) { + // ifs, gotos, and assignments don't need vars allocated + var_c = NULL; + } else { + // allocate result space + // try to reuse result defs as much as possible + var_c = gameLocal.program.FindFreeResultDef( op->type_c->TypeDef(), RESULT_STRING, scope, var_a, var_b ); + // set user count back to 1, a result def needs to be used twice before it can be reused + var_c->numUsers = 1; + } + + statement->op = op - opcodes; + statement->a = var_a; + statement->b = var_b; + statement->c = var_c; + + if ( op->rightAssociative ) { + return var_a; + } + + return var_c; +} + +/* +============ +idCompiler::EmitOpcode + +Emits a primitive statement, returning the var it places it's value in +============ +*/ +ID_INLINE idVarDef *idCompiler::EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ) { + return EmitOpcode( &opcodes[ op ], var_a, var_b ); +} + +/* +============ +idCompiler::EmitPush + +Emits an opcode to push the variable onto the stack. +============ +*/ +bool idCompiler::EmitPush( idVarDef *expression, const idTypeDef *funcArg ) { + opcode_t *op; + opcode_t *out; + + out = NULL; + for( op = &opcodes[ OP_PUSH_F ]; op->name && !strcmp( op->name, "" ); op++ ) { + if ( ( funcArg->Type() == op->type_a->Type() ) && ( expression->Type() == op->type_b->Type() ) ) { + out = op; + break; + } + } + + if ( !out ) { + if ( ( expression->TypeDef() != funcArg ) && !expression->TypeDef()->Inherits( funcArg ) ) { + return false; + } + + out = &opcodes[ OP_PUSH_ENT ]; + } + + EmitOpcode( out, expression, 0 ); + + return true; +} + +/* +============== +idCompiler::NextToken + +Sets token, immediateType, and possibly immediate +============== +*/ +void idCompiler::NextToken( void ) { + int i; + + // reset our type + immediateType = NULL; + memset( &immediate, 0, sizeof( immediate ) ); + + // Save the token's line number and filename since when we emit opcodes the current + // token is always the next one to be read + currentLineNumber = token.line; + const char* currentFileName = parserPtr->GetFileName(); + currentFileNumber = gameLocal.program.GetFilenum( currentFileName ); + + if ( !parserPtr->ReadToken( &token ) ) { + eof = true; + return; + } + + if ( currentFileNumber != gameLocal.program.GetFilenum( parserPtr->GetFileName() ) ) { + if ( ( braceDepth > 0 ) && ( token != "}" ) ) { + // missing a closing brace. try to give as much info as possible. + if ( scope->Type() == ev_function ) { + Error( "Unexpected end of file inside function '%s'. Missing closing braces.", scope->Name() ); + } else if ( scope->Type() == ev_object ) { + Error( "Unexpected end of file inside object '%s'. Missing closing braces.", scope->Name() ); + } else if ( scope->Type() == ev_namespace ) { + Error( "Unexpected end of file inside namespace '%s'. Missing closing braces.", scope->Name() ); + } else { + Error( "Unexpected end of file inside braced section" ); + } + } + } + + switch( token.type ) { + case TT_STRING: + // handle quoted strings as a unit + immediateType = &type_string; + return; + + case TT_LITERAL: { + // handle quoted vectors as a unit + immediateType = &type_vector; + idLexer lex( token, token.Length(), parserPtr->GetFileName(), LEXFL_NOERRORS ); + idToken token2; + for( i = 0; i < 3; i++ ) { + if ( !lex.ReadToken( &token2 ) ) { + Error( "Couldn't read vector. '%s' is not in the form of 'x y z'", token.c_str() ); + } + if ( token2.type == TT_PUNCTUATION && token2 == "-" ) { + if ( !lex.CheckTokenType( TT_NUMBER, 0, &token2 ) ) { + Error( "expected a number following '-' but found '%s' in vector '%s'", token2.c_str(), token.c_str() ); + } + immediate.vector[ i ] = -token2.GetFloatValue(); + } else if ( token2.type == TT_NUMBER ) { + immediate.vector[ i ] = token2.GetFloatValue(); + } else { + Error( "vector '%s' is not in the form of 'x y z'. expected float value, found '%s'", token.c_str(), token2.c_str() ); + } + } + return; + } + + case TT_NUMBER: + immediateType = &type_float; + immediate._float = token.GetFloatValue(); + return; + + case TT_PUNCTUATION: + // entity names + if ( token == "$" ) { + immediateType = &type_entity; + parserPtr->ReadToken( &token ); + return; + } + + if ( token == "{" ) { + braceDepth++; + return; + } + + if ( token == "}" ) { + braceDepth--; + return; + } + + if ( punctuationValid[ token.subtype ] ) { + return; + } + + Error( "Unknown punctuation '%s' on line %i, file '%s'", token.c_str(), currentLineNumber, currentFileName ); + break; + + case TT_NAME: + return; + + default: + Error( "Unknown token '%s' on line %i, file '%s'", token.c_str(), currentLineNumber, currentFileName ); + } +} + +/* +============= +idCompiler::ExpectToken + +Issues an Error if the current token isn't equal to string +Gets the next token +============= +*/ +void idCompiler::ExpectToken( const char *string ) { + if ( token != string ) { + Error( "expected '%s', found '%s'", string, token.c_str() ); + } + + NextToken(); +} + +/* +============= +idCompiler::CheckToken + +Returns true and gets the next token if the current token equals string +Returns false and does nothing otherwise +============= +*/ +bool idCompiler::CheckToken( const char *string ) { + if ( token != string ) { + return false; + } + + NextToken(); + + return true; +} + +/* +============ +idCompiler::ParseName + +Checks to see if the current token is a valid name +============ +*/ +void idCompiler::ParseName( idStr &name ) { + if ( token.type != TT_NAME ) { + Error( "'%s' is not a name", token.c_str() ); + } + + name = token; + NextToken(); +} + +/* +============ +idCompiler::SkipOutOfFunction + +For error recovery, pops out of nested braces +============ +*/ +void idCompiler::SkipOutOfFunction( void ) { + while( braceDepth ) { + parserPtr->SkipBracedSection( false ); + braceDepth--; + } + NextToken(); +} + +/* +============ +idCompiler::SkipToSemicolon + +For error recovery +============ +*/ +void idCompiler::SkipToSemicolon( void ) { + do { + if ( CheckToken( ";" ) ) { + return; + } + + NextToken(); + } while( !eof ); +} + +/* +============ +idCompiler::CheckType + +Parses a variable type, including functions types +============ +*/ +idTypeDef *idCompiler::CheckType( void ) { + idTypeDef *type; + + if ( token == "float" ) { + type = &type_float; + } else if ( token == "vector" ) { + type = &type_vector; + } else if ( token == "entity" ) { + type = &type_entity; + } else if ( token == "string" ) { + type = &type_string; + } else if ( token == "void" ) { + type = &type_void; + } else if ( token == "object" ) { + type = &type_object; + } else if ( token == "boolean" ) { + type = &type_boolean; + } else if ( token == "namespace" ) { + type = &type_namespace; + } else if ( token == "scriptEvent" ) { + type = &type_scriptevent; + } else { + type = gameLocal.program.FindType( token.c_str() ); + if ( type && !type->Inherits( &type_object ) ) { + type = NULL; + } + } + + return type; +} + +/* +============ +idCompiler::ParseType + +Parses a variable type, including functions types +============ +*/ +idTypeDef *idCompiler::ParseType( void ) { + idTypeDef *type; + + type = CheckType(); + if ( !type ) { + Error( "\"%s\" is not a type", token.c_str() ); + } + + if ( ( type == &type_scriptevent ) && ( scope != &def_namespace ) ) { + Error( "scriptEvents can only defined in the global namespace" ); + } + + if ( ( type == &type_namespace ) && ( scope->Type() != ev_namespace ) ) { + Error( "A namespace may only be defined globally, or within another namespace" ); + } + + NextToken(); + + return type; +} + +/* +============ +idCompiler::ParseImmediate + +Looks for a preexisting constant +============ +*/ +idVarDef *idCompiler::ParseImmediate( void ) { + idVarDef *def; + + def = GetImmediate( immediateType, &immediate, token.c_str() ); + NextToken(); + + return def; +} + +/* +============ +idCompiler::EmitFunctionParms +============ +*/ +idVarDef *idCompiler::EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ) { + idVarDef *e; + const idTypeDef *type; + const idTypeDef *funcArg; + idVarDef *returnDef; + idTypeDef *returnType; + int arg; + int size; + int resultOp; + + type = func->TypeDef(); + if ( func->Type() != ev_function ) { + Error( "'%s' is not a function", func->Name() ); + } + + // copy the parameters to the global parameter variables + arg = startarg; + size = startsize; + if ( !CheckToken( ")" ) ) { + do { + if ( arg >= type->NumParameters() ) { + Error( "too many parameters" ); + } + + e = GetExpression( TOP_PRIORITY ); + + funcArg = type->GetParmType( arg ); + if ( !EmitPush( e, funcArg ) ) { + Error( "type mismatch on parm %i of call to '%s'", arg + 1, func->Name() ); + } + + if ( funcArg->Type() == ev_object ) { + size += type_object.Size(); + } else { + size += funcArg->Size(); + } + + arg++; + } while( CheckToken( "," ) ); + + ExpectToken( ")" ); + } + + if ( arg < type->NumParameters() ) { + Error( "too few parameters for function '%s'", func->Name() ); + } + + if ( op == OP_CALL ) { + EmitOpcode( op, func, 0 ); + } else if ( ( op == OP_OBJECTCALL ) || ( op == OP_OBJTHREAD ) ) { + EmitOpcode( op, object, VirtualFunctionConstant( func ) ); + + // need arg size seperate since script object may be NULL + statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); + statement.c = SizeConstant( func->value.functionPtr->parmTotal ); + } else { + EmitOpcode( op, func, SizeConstant( size ) ); + } + + // we need to copy off the result into a temporary result location, so figure out the opcode + returnType = type->ReturnType(); + if ( returnType->Type() == ev_string ) { + resultOp = OP_STORE_S; + returnDef = gameLocal.program.returnStringDef; + } else { + gameLocal.program.returnDef->SetTypeDef( returnType ); + returnDef = gameLocal.program.returnDef; + + switch( returnType->Type() ) { + case ev_void : + resultOp = OP_STORE_F; + break; + + case ev_boolean : + resultOp = OP_STORE_BOOL; + break; + + case ev_float : + resultOp = OP_STORE_F; + break; + + case ev_vector : + resultOp = OP_STORE_V; + break; + + case ev_entity : + resultOp = OP_STORE_ENT; + break; + + case ev_object : + resultOp = OP_STORE_OBJ; + break; + + default : + Error( "Invalid return type for function '%s'", func->Name() ); + // shut up compiler + resultOp = OP_STORE_OBJ; + break; + } + } + + if ( returnType->Type() == ev_void ) { + // don't need result space since there's no result, so just return the normal result def. + return returnDef; + } + + // allocate result space + // try to reuse result defs as much as possible + statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); + idVarDef *resultDef = gameLocal.program.FindFreeResultDef( returnType, RESULT_STRING, scope, statement.a, statement.b ); + // set user count back to 0, a result def needs to be used twice before it can be reused + resultDef->numUsers = 0; + + EmitOpcode( resultOp, returnDef, resultDef ); + + return resultDef; +} + +/* +============ +idCompiler::ParseFunctionCall +============ +*/ +idVarDef *idCompiler::ParseFunctionCall( idVarDef *funcDef ) { + assert( funcDef ); + + if ( funcDef->Type() != ev_function ) { + Error( "'%s' is not a function", funcDef->Name() ); + } + + if ( funcDef->initialized == idVarDef::uninitialized ) { + Error( "Function '%s' has not been defined yet", funcDef->GlobalName() ); + } + + assert( funcDef->value.functionPtr ); + if ( callthread ) { + if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) { + Error( "Built-in functions cannot be called as threads" ); + } + callthread = false; + return EmitFunctionParms( OP_THREAD, funcDef, 0, 0, NULL ); + } else { + if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) { + if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) { + // get the local object pointer + idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope ); + if ( !thisdef ) { + Error( "No 'self' within scope" ); + } + + return ParseEventCall( thisdef, funcDef ); + } else { + Error( "Built-in functions cannot be called without an object" ); + } + } + + return EmitFunctionParms( OP_CALL, funcDef, 0, 0, NULL ); + } +} + +/* +============ +idCompiler::ParseObjectCall +============ +*/ +idVarDef *idCompiler::ParseObjectCall( idVarDef *object, idVarDef *func ) { + EmitPush( object, object->TypeDef() ); + if ( callthread ) { + callthread = false; + return EmitFunctionParms( OP_OBJTHREAD, func, 1, type_object.Size(), object ); + } else { + return EmitFunctionParms( OP_OBJECTCALL, func, 1, 0, object ); + } +} + +/* +============ +idCompiler::ParseEventCall +============ +*/ +idVarDef *idCompiler::ParseEventCall( idVarDef *object, idVarDef *funcDef ) { + if ( callthread ) { + Error( "Cannot call built-in functions as a thread" ); + } + + if ( funcDef->Type() != ev_function ) { + Error( "'%s' is not a function", funcDef->Name() ); + } + + if ( !funcDef->value.functionPtr->eventdef ) { + Error( "\"%s\" cannot be called with object notation", funcDef->Name() ); + } + + if ( object->Type() == ev_object ) { + EmitPush( object, &type_entity ); + } else { + EmitPush( object, object->TypeDef() ); + } + + return EmitFunctionParms( OP_EVENTCALL, funcDef, 0, type_object.Size(), NULL ); +} + +/* +============ +idCompiler::ParseSysObjectCall +============ +*/ +idVarDef *idCompiler::ParseSysObjectCall( idVarDef *funcDef ) { + if ( callthread ) { + Error( "Cannot call built-in functions as a thread" ); + } + + if ( funcDef->Type() != ev_function ) { + Error( "'%s' is not a function", funcDef->Name() ); + } + + if ( !funcDef->value.functionPtr->eventdef ) { + Error( "\"%s\" cannot be called with object notation", funcDef->Name() ); + } + + if ( !idThread::Type.RespondsTo( *funcDef->value.functionPtr->eventdef ) ) { + Error( "\"%s\" is not callable as a 'sys' function", funcDef->Name() ); + } + + return EmitFunctionParms( OP_SYSCALL, funcDef, 0, 0, NULL ); +} + +/* +============ +idCompiler::LookupDef +============ +*/ +idVarDef *idCompiler::LookupDef( const char *name, const idVarDef *baseobj ) { + idVarDef *def; + idVarDef *field; + etype_t type_b; + etype_t type_c; + opcode_t *op; + + // check if we're accessing a field + if ( baseobj && ( baseobj->Type() == ev_object ) ) { + const idVarDef *tdef; + + def = NULL; + for( tdef = baseobj; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) { + def = gameLocal.program.GetDef( NULL, name, tdef ); + if ( def ) { + break; + } + } + } else { + // first look through the defs in our scope + def = gameLocal.program.GetDef( NULL, name, scope ); + if ( !def ) { + // if we're in a member function, check types local to the object + if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) { + // get the local object pointer + idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope ); + + field = LookupDef( name, scope->scope->TypeDef()->def ); + if ( !field ) { + Error( "Unknown value \"%s\"", name ); + } + + // type check + type_b = field->Type(); + if ( field->Type() == ev_function ) { + type_c = field->TypeDef()->ReturnType()->Type(); + } else { + type_c = field->TypeDef()->FieldType()->Type(); // field access gets type from field + if ( CheckToken( "++" ) ) { + if ( type_c != ev_float ) { + Error( "Invalid type for ++" ); + } + def = EmitOpcode( OP_UINCP_F, thisdef, field ); + return def; + } else if ( CheckToken( "--" ) ) { + if ( type_c != ev_float ) { + Error( "Invalid type for --" ); + } + def = EmitOpcode( OP_UDECP_F, thisdef, field ); + return def; + } + } + + op = &opcodes[ OP_INDIRECT_F ]; + while( ( op->type_a->Type() != ev_object ) + || ( type_b != op->type_b->Type() ) || ( type_c != op->type_c->Type() ) ) { + if ( ( op->priority == FUNCTION_PRIORITY ) && ( op->type_a->Type() == ev_object ) && ( op->type_c->Type() == ev_void ) && + ( type_c != op->type_c->Type() ) ) { + // catches object calls that return a value + break; + } + op++; + if ( !op->name || strcmp( op->name, "." ) ) { + Error( "no valid opcode to access type '%s'", field->TypeDef()->SuperClass()->Name() ); + } + } + + if ( ( op - opcodes ) == OP_OBJECTCALL ) { + ExpectToken( "(" ); + def = ParseObjectCall( thisdef, field ); + } else { + // emit the conversion opcode + def = EmitOpcode( op, thisdef, field ); + + // field access gets type from field + def->SetTypeDef( field->TypeDef()->FieldType() ); + } + } + } + } + + return def; +} + +/* +============ +idCompiler::ParseValue + +Returns the def for the current token +============ +*/ +idVarDef *idCompiler::ParseValue( void ) { + idVarDef *def; + idVarDef *namespaceDef; + idStr name; + + if ( immediateType == &type_entity ) { + // if an immediate entity ($-prefaced name) then create or lookup a def for it. + // when entities are spawned, they'll lookup the def and point it to them. + def = gameLocal.program.GetDef( &type_entity, "$" + token, &def_namespace ); + if ( !def ) { + def = gameLocal.program.AllocDef( &type_entity, "$" + token, &def_namespace, true ); + } + NextToken(); + return def; + } else if ( immediateType ) { + // if the token is an immediate, allocate a constant for it + return ParseImmediate(); + } + + ParseName( name ); + def = LookupDef( name, basetype ); + if ( !def ) { + if ( basetype ) { + Error( "%s is not a member of %s", name.c_str(), basetype->TypeDef()->Name() ); + } else { + Error( "Unknown value \"%s\"", name.c_str() ); + } + // if namespace, then look up the variable in that namespace + } else if ( def->Type() == ev_namespace ) { + while( def->Type() == ev_namespace ) { + ExpectToken( "::" ); + ParseName( name ); + namespaceDef = def; + def = gameLocal.program.GetDef( NULL, name, namespaceDef ); + if ( !def ) { + Error( "Unknown value \"%s::%s\"", namespaceDef->GlobalName(), name.c_str() ); + } + } + //def = LookupDef( name, basetype ); + } + + return def; +} + +/* +============ +idCompiler::GetTerm +============ +*/ +idVarDef *idCompiler::GetTerm( void ) { + idVarDef *e; + int op; + + if ( !immediateType && CheckToken( "~" ) ) { + e = GetExpression( TILDE_PRIORITY ); + switch( e->Type() ) { + case ev_float : + op = OP_COMP_F; + break; + + default : + Error( "type mismatch for ~" ); + + // shut up compiler + op = OP_COMP_F; + break; + } + + return EmitOpcode( op, e, 0 ); + } + + if ( !immediateType && CheckToken( "!" ) ) { + e = GetExpression( NOT_PRIORITY ); + switch( e->Type() ) { + case ev_boolean : + op = OP_NOT_BOOL; + break; + + case ev_float : + op = OP_NOT_F; + break; + + case ev_string : + op = OP_NOT_S; + break; + + case ev_vector : + op = OP_NOT_V; + break; + + case ev_entity : + op = OP_NOT_ENT; + break; + + case ev_function : + Error( "Invalid type for !" ); + + // shut up compiler + op = OP_NOT_F; + break; + + case ev_object : + op = OP_NOT_ENT; + break; + + default : + Error( "type mismatch for !" ); + + // shut up compiler + op = OP_NOT_F; + break; + } + + return EmitOpcode( op, e, 0 ); + } + + // check for negation operator + if ( !immediateType && CheckToken( "-" ) ) { + // constants are directly negated without an instruction + if ( immediateType == &type_float ) { + immediate._float = -immediate._float; + return ParseImmediate(); + } else if ( immediateType == &type_vector ) { + immediate.vector[0] = -immediate.vector[0]; + immediate.vector[1] = -immediate.vector[1]; + immediate.vector[2] = -immediate.vector[2]; + return ParseImmediate(); + } else { + e = GetExpression( NOT_PRIORITY ); + switch( e->Type() ) { + case ev_float : + op = OP_NEG_F; + break; + + case ev_vector : + op = OP_NEG_V; + break; + default : + Error( "type mismatch for -" ); + + // shut up compiler + op = OP_NEG_F; + break; + } + return EmitOpcode( &opcodes[ op ], e, 0 ); + } + } + + if ( CheckToken( "int" ) ) { + ExpectToken( "(" ); + + e = GetExpression( INT_PRIORITY ); + if ( e->Type() != ev_float ) { + Error( "type mismatch for int()" ); + } + + ExpectToken( ")" ); + + return EmitOpcode( OP_INT_F, e, 0 ); + } + + if ( CheckToken( "thread" ) ) { + callthread = true; + e = GetExpression( FUNCTION_PRIORITY ); + + if ( callthread ) { + Error( "Invalid thread call" ); + } + + // threads return the thread number + gameLocal.program.returnDef->SetTypeDef( &type_float ); + return gameLocal.program.returnDef; + } + + if ( !immediateType && CheckToken( "(" ) ) { + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ")" ); + + return e; + } + + return ParseValue(); +} + +/* +============== +idCompiler::TypeMatches +============== +*/ +bool idCompiler::TypeMatches( etype_t type1, etype_t type2 ) const { + if ( type1 == type2 ) { + return true; + } + + //if ( ( type1 == ev_entity ) && ( type2 == ev_object ) ) { + // return true; + //} + + //if ( ( type2 == ev_entity ) && ( type1 == ev_object ) ) { + // return true; + //} + + return false; +} + +/* +============== +idCompiler::GetExpression +============== +*/ +idVarDef *idCompiler::GetExpression( int priority ) { + opcode_t *op; + opcode_t *oldop; + idVarDef *e; + idVarDef *e2; + const idVarDef *oldtype; + etype_t type_a; + etype_t type_b; + etype_t type_c; + + if ( priority == 0 ) { + return GetTerm(); + } + + e = GetExpression( priority - 1 ); + if ( token == ";" ) { + // save us from searching through the opcodes unneccesarily + return e; + } + + while( 1 ) { + if ( ( priority == FUNCTION_PRIORITY ) && CheckToken( "(" ) ) { + return ParseFunctionCall( e ); + } + + // has to be a punctuation + if ( immediateType ) { + break; + } + + for( op = opcodes; op->name; op++ ) { + if ( ( op->priority == priority ) && CheckToken( op->name ) ) { + break; + } + } + + if ( !op->name ) { + // next token isn't at this priority level + break; + } + + // unary operators act only on the left operand + if ( op->type_b == &def_void ) { + e = EmitOpcode( op, e, 0 ); + return e; + } + + // preserve our base type + oldtype = basetype; + + // field access needs scope from object + if ( ( op->name[ 0 ] == '.' ) && e->TypeDef()->Inherits( &type_object ) ) { + // save off what type this field is part of + basetype = e->TypeDef()->def; + } + + if ( op->rightAssociative ) { + // if last statement is an indirect, change it to an address of + if ( gameLocal.program.NumStatements() > 0 ) { + statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); + if ( ( statement.op >= OP_INDIRECT_F ) && ( statement.op < OP_ADDRESS ) ) { + statement.op = OP_ADDRESS; + type_pointer.SetPointerType( e->TypeDef() ); + e->SetTypeDef( &type_pointer ); + } + } + + e2 = GetExpression( priority ); + } else { + e2 = GetExpression( priority - 1 ); + } + + // restore type + basetype = oldtype; + + // type check + type_a = e->Type(); + type_b = e2->Type(); + + // field access gets type from field + if ( op->name[ 0 ] == '.' ) { + if ( ( e2->Type() == ev_function ) && e2->TypeDef()->ReturnType() ) { + type_c = e2->TypeDef()->ReturnType()->Type(); + } else if ( e2->TypeDef()->FieldType() ) { + type_c = e2->TypeDef()->FieldType()->Type(); + } else { + // not a field + type_c = ev_error; + } + } else { + type_c = ev_void; + } + + oldop = op; + while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) || + ( ( type_c != ev_void ) && !TypeMatches( type_c, op->type_c->Type() ) ) ) { + if ( ( op->priority == FUNCTION_PRIORITY ) && TypeMatches( type_a, op->type_a->Type() ) && TypeMatches( type_b, op->type_b->Type() ) ) { + break; + } + + op++; + if ( !op->name || strcmp( op->name, oldop->name ) ) { + Error( "type mismatch for '%s'", oldop->name ); + } + } + + switch( op - opcodes ) { + case OP_SYSCALL : + ExpectToken( "(" ); + e = ParseSysObjectCall( e2 ); + break; + + case OP_OBJECTCALL : + ExpectToken( "(" ); + if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) { + e = ParseEventCall( e, e2 ); + } else { + e = ParseObjectCall( e, e2 ); + } + break; + + case OP_EVENTCALL : + ExpectToken( "(" ); + if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) { + e = ParseEventCall( e, e2 ); + } else { + e = ParseObjectCall( e, e2 ); + } + break; + + default: + if ( callthread ) { + Error( "Expecting function call after 'thread'" ); + } + + if ( ( type_a == ev_pointer ) && ( type_b != e->TypeDef()->PointerType()->Type() ) ) { + // FIXME: need to make a general case for this + if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_boolean ) ) { + // copy from float to boolean pointer + op = &opcodes[ OP_STOREP_FTOBOOL ]; + } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_float ) ) { + // copy from boolean to float pointer + op = &opcodes[ OP_STOREP_BOOLTOF ]; + } else if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { + // copy from float to string pointer + op = &opcodes[ OP_STOREP_FTOS ]; + } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { + // copy from boolean to string pointer + op = &opcodes[ OP_STOREP_BTOS ]; + } else if ( ( op - opcodes == OP_STOREP_V ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { + // copy from vector to string pointer + op = &opcodes[ OP_STOREP_VTOS ]; + } else if ( ( op - opcodes == OP_STOREP_ENT ) && ( e->TypeDef()->PointerType()->Type() == ev_object ) ) { + // store an entity into an object pointer + op = &opcodes[ OP_STOREP_OBJENT ]; + } else { + Error( "type mismatch for '%s'", op->name ); + } + } + + if ( op->rightAssociative ) { + e = EmitOpcode( op, e2, e ); + } else { + e = EmitOpcode( op, e, e2 ); + } + + if ( op - opcodes == OP_STOREP_OBJENT ) { + // statement.b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in statement.c + // so that we can do a type check during run time since we don't know what type the script object is at compile time because it + // comes from an entity + statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); + statement.c = type_pointer.PointerType()->def; + } + + // field access gets type from field + if ( type_c != ev_void ) { + e->SetTypeDef( e2->TypeDef()->FieldType() ); + } + break; + } + } + + return e; +} + +/* +================ +idCompiler::PatchLoop +================ +*/ +void idCompiler::PatchLoop( int start, int continuePos ) { + int i; + statement_t *pos; + + pos = &gameLocal.program.GetStatement( start ); + for( i = start; i < gameLocal.program.NumStatements(); i++, pos++ ) { + if ( pos->op == OP_BREAK ) { + pos->op = OP_GOTO; + pos->a = JumpFrom( i ); + } else if ( pos->op == OP_CONTINUE ) { + pos->op = OP_GOTO; + pos->a = JumpDef( i, continuePos ); + } + } +} + +/* +================ +idCompiler::ParseReturnStatement +================ +*/ +void idCompiler::ParseReturnStatement( void ) { + idVarDef *e; + etype_t type_a; + etype_t type_b; + opcode_t *op; + + if ( CheckToken( ";" ) ) { + if ( scope->TypeDef()->ReturnType()->Type() != ev_void ) { + Error( "expecting return value" ); + } + + EmitOpcode( OP_RETURN, 0, 0 ); + return; + } + + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ";" ); + + type_a = e->Type(); + type_b = scope->TypeDef()->ReturnType()->Type(); + + if ( TypeMatches( type_a, type_b ) ) { + EmitOpcode( OP_RETURN, e, 0 ); + return; + } + + for( op = opcodes; op->name; op++ ) { + if ( !strcmp( op->name, "=" ) ) { + break; + } + } + + assert( op->name ); + + while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) ) { + op++; + if ( !op->name || strcmp( op->name, "=" ) ) { + Error( "type mismatch for return value" ); + } + } + + idTypeDef *returnType = scope->TypeDef()->ReturnType(); + if ( returnType->Type() == ev_string ) { + EmitOpcode( op, e, gameLocal.program.returnStringDef ); + } else { + gameLocal.program.returnDef->SetTypeDef( returnType ); + EmitOpcode( op, e, gameLocal.program.returnDef ); + } + EmitOpcode( OP_RETURN, 0, 0 ); +} + +/* +================ +idCompiler::ParseWhileStatement +================ +*/ +void idCompiler::ParseWhileStatement( void ) { + idVarDef *e; + int patch1; + int patch2; + + loopDepth++; + + ExpectToken( "(" ); + + patch2 = gameLocal.program.NumStatements(); + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ")" ); + + if ( ( e->initialized == idVarDef::initializedConstant ) && ( *e->value.intPtr != 0 ) ) { + //FIXME: we can completely skip generation of this code in the opposite case + ParseStatement(); + EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); + } else { + patch1 = gameLocal.program.NumStatements(); + EmitOpcode( OP_IFNOT, e, 0 ); + ParseStatement(); + EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); + gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); + } + + // fixup breaks and continues + PatchLoop( patch2, patch2 ); + + loopDepth--; +} + +/* +================ +idCompiler::ParseForStatement + +Form of for statement with a counter: + + a = 0; +start: << patch4 + if ( !( a < 10 ) ) { + goto end; << patch1 + } else { + goto process; << patch3 + } + +increment: << patch2 + a = a + 1; + goto start; << goto patch4 + +process: + statements; + goto increment; << goto patch2 + +end: + +Form of for statement without a counter: + + a = 0; +start: << patch2 + if ( !( a < 10 ) ) { + goto end; << patch1 + } + +process: + statements; + goto start; << goto patch2 + +end: +================ +*/ +void idCompiler::ParseForStatement( void ) { + idVarDef *e; + int start; + int patch1; + int patch2; + int patch3; + int patch4; + + loopDepth++; + + start = gameLocal.program.NumStatements(); + + ExpectToken( "(" ); + + // init + if ( !CheckToken( ";" ) ) { + do { + GetExpression( TOP_PRIORITY ); + } while( CheckToken( "," ) ); + + ExpectToken( ";" ); + } + + // condition + patch2 = gameLocal.program.NumStatements(); + + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ";" ); + + //FIXME: add check for constant expression + patch1 = gameLocal.program.NumStatements(); + EmitOpcode( OP_IFNOT, e, 0 ); + + // counter + if ( !CheckToken( ")" ) ) { + patch3 = gameLocal.program.NumStatements(); + EmitOpcode( OP_IF, e, 0 ); + + patch4 = patch2; + patch2 = gameLocal.program.NumStatements(); + do { + GetExpression( TOP_PRIORITY ); + } while( CheckToken( "," ) ); + + ExpectToken( ")" ); + + // goto patch4 + EmitOpcode( OP_GOTO, JumpTo( patch4 ), 0 ); + + // fixup patch3 + gameLocal.program.GetStatement( patch3 ).b = JumpFrom( patch3 ); + } + + ParseStatement(); + + // goto patch2 + EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); + + // fixup patch1 + gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); + + // fixup breaks and continues + PatchLoop( start, patch2 ); + + loopDepth--; +} + +/* +================ +idCompiler::ParseDoWhileStatement +================ +*/ +void idCompiler::ParseDoWhileStatement( void ) { + idVarDef *e; + int patch1; + + loopDepth++; + + patch1 = gameLocal.program.NumStatements(); + ParseStatement(); + ExpectToken( "while" ); + ExpectToken( "(" ); + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ")" ); + ExpectToken( ";" ); + + EmitOpcode( OP_IF, e, JumpTo( patch1 ) ); + + // fixup breaks and continues + PatchLoop( patch1, patch1 ); + + loopDepth--; +} + +/* +================ +idCompiler::ParseIfStatement +================ +*/ +void idCompiler::ParseIfStatement( void ) { + idVarDef *e; + int patch1; + int patch2; + + ExpectToken( "(" ); + e = GetExpression( TOP_PRIORITY ); + ExpectToken( ")" ); + + //FIXME: add check for constant expression + patch1 = gameLocal.program.NumStatements(); + EmitOpcode( OP_IFNOT, e, 0 ); + + ParseStatement(); + + if ( CheckToken( "else" ) ) { + patch2 = gameLocal.program.NumStatements(); + EmitOpcode( OP_GOTO, 0, 0 ); + gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); + ParseStatement(); + gameLocal.program.GetStatement( patch2 ).a = JumpFrom( patch2 ); + } else { + gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); + } +} + +/* +============ +idCompiler::ParseStatement +============ +*/ +void idCompiler::ParseStatement( void ) { + if ( CheckToken( ";" ) ) { + // skip semicolons, which are harmless and ok syntax + return; + } + + if ( CheckToken( "{" ) ) { + do { + ParseStatement(); + } while( !CheckToken( "}" ) ); + + return; + } + + if ( CheckToken( "return" ) ) { + ParseReturnStatement(); + return; + } + + if ( CheckToken( "while" ) ) { + ParseWhileStatement(); + return; + } + + if ( CheckToken( "for" ) ) { + ParseForStatement(); + return; + } + + if ( CheckToken( "do" ) ) { + ParseDoWhileStatement(); + return; + } + + if ( CheckToken( "break" ) ) { + ExpectToken( ";" ); + if ( !loopDepth ) { + Error( "cannot break outside of a loop" ); + } + EmitOpcode( OP_BREAK, 0, 0 ); + return; + } + + if ( CheckToken( "continue" ) ) { + ExpectToken( ";" ); + if ( !loopDepth ) { + Error( "cannot contine outside of a loop" ); + } + EmitOpcode( OP_CONTINUE, 0, 0 ); + return; + } + + if ( CheckType() != NULL ) { + ParseDefs(); + return; + } + + if ( CheckToken( "if" ) ) { + ParseIfStatement(); + return; + } + + GetExpression( TOP_PRIORITY ); + ExpectToken(";"); +} + +/* +================ +idCompiler::ParseObjectDef +================ +*/ +void idCompiler::ParseObjectDef( const char *objname ) { + idTypeDef *objtype; + idTypeDef *type; + idTypeDef *parentType; + idTypeDef *fieldtype; + idStr name; + const char *fieldname; + idTypeDef newtype( ev_field, NULL, "", 0, NULL ); + idVarDef *oldscope; + int num; + int i; + + oldscope = scope; + if ( scope->Type() != ev_namespace ) { + Error( "Objects cannot be defined within functions or other objects" ); + } + + // make sure it doesn't exist before we create it + if ( gameLocal.program.FindType( objname ) != NULL ) { + Error( "'%s' : redefinition; different basic types", objname ); + } + + // base type + if ( !CheckToken( ":" ) ) { + parentType = &type_object; + } else { + parentType = ParseType(); + if ( !parentType->Inherits( &type_object ) ) { + Error( "Objects may only inherit from objects." ); + } + } + + objtype = gameLocal.program.AllocType( ev_object, NULL, objname, parentType == &type_object ? 0 : parentType->Size(), parentType ); + objtype->def = gameLocal.program.AllocDef( objtype, objname, scope, true ); + scope = objtype->def; + + // inherit all the functions + num = parentType->NumFunctions(); + for( i = 0; i < parentType->NumFunctions(); i++ ) { + const function_t *func = parentType->GetFunction( i ); + objtype->AddFunction( func ); + } + + ExpectToken( "{" ); + + do { + if ( CheckToken( ";" ) ) { + // skip semicolons, which are harmless and ok syntax + continue; + } + + fieldtype = ParseType(); + newtype.SetFieldType( fieldtype ); + + fieldname = va( "%s field", fieldtype->Name() ); + newtype.SetName( fieldname ); + + ParseName( name ); + + // check for a function prototype or declaraction + if ( CheckToken( "(" ) ) { + ParseFunctionDef( newtype.FieldType(), name ); + } else { + type = gameLocal.program.GetType( newtype, true ); + assert( !type->def ); + gameLocal.program.AllocDef( type, name, scope, true ); + objtype->AddField( type, name ); + ExpectToken( ";" ); + } + } while( !CheckToken( "}" ) ); + + scope = oldscope; + + ExpectToken( ";" ); +} + +/* +============ +idCompiler::ParseFunction + +parse a function type +============ +*/ +idTypeDef *idCompiler::ParseFunction( idTypeDef *returnType, const char *name ) { + idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType ); + idTypeDef *type; + + if ( scope->Type() != ev_namespace ) { + // create self pointer + newtype.AddFunctionParm( scope->TypeDef(), "self" ); + } + + if ( !CheckToken( ")" ) ) { + idStr parmName; + do { + type = ParseType(); + ParseName( parmName ); + newtype.AddFunctionParm( type, parmName ); + } while( CheckToken( "," ) ); + + ExpectToken( ")" ); + } + + return gameLocal.program.GetType( newtype, true ); +} + +/* +================ +idCompiler::ParseFunctionDef +================ +*/ +void idCompiler::ParseFunctionDef( idTypeDef *returnType, const char *name ) { + idTypeDef *type; + idVarDef *def; + const idVarDef *parm; + idVarDef *oldscope; + int i; + int numParms; + const idTypeDef *parmType; + function_t *func; + statement_t *pos; + + if ( ( scope->Type() != ev_namespace ) && !scope->TypeDef()->Inherits( &type_object ) ) { + Error( "Functions may not be defined within other functions" ); + } + + type = ParseFunction( returnType, name ); + def = gameLocal.program.GetDef( type, name, scope ); + if ( !def ) { + def = gameLocal.program.AllocDef( type, name, scope, true ); + type->def = def; + + func = &gameLocal.program.AllocFunction( def ); + if ( scope->TypeDef()->Inherits( &type_object ) ) { + scope->TypeDef()->AddFunction( func ); + } + } else { + func = def->value.functionPtr; + assert( func ); + if ( func->firstStatement ) { + Error( "%s redeclared", def->GlobalName() ); + } + } + + // check if this is a prototype or declaration + if ( !CheckToken( "{" ) ) { + // it's just a prototype, so get the ; and move on + ExpectToken( ";" ); + return; + } + + // calculate stack space used by parms + numParms = type->NumParameters(); + func->parmSize.SetNum( numParms ); + for( i = 0; i < numParms; i++ ) { + parmType = type->GetParmType( i ); + if ( parmType->Inherits( &type_object ) ) { + func->parmSize[ i ] = type_object.Size(); + } else { + func->parmSize[ i ] = parmType->Size(); + } + func->parmTotal += func->parmSize[ i ]; + } + + // define the parms + for( i = 0; i < numParms; i++ ) { + if ( gameLocal.program.GetDef( type->GetParmType( i ), type->GetParmName( i ), def ) ) { + Error( "'%s' defined more than once in function parameters", type->GetParmName( i ) ); + } + parm = gameLocal.program.AllocDef( type->GetParmType( i ), type->GetParmName( i ), def, false ); + } + + oldscope = scope; + scope = def; + + func->firstStatement = gameLocal.program.NumStatements(); + + // check if we should call the super class constructor + if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "init" ) ) { + idTypeDef *superClass; + function_t *constructorFunc = NULL; + + // find the superclass constructor + for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) { + constructorFunc = gameLocal.program.FindFunction( va( "%s::init", superClass->Name() ) ); + if ( constructorFunc ) { + break; + } + } + + // emit the call to the constructor + if ( constructorFunc ) { + idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def ); + assert( selfDef ); + EmitPush( selfDef, selfDef->TypeDef() ); + EmitOpcode( &opcodes[ OP_CALL ], constructorFunc->def, 0 ); + } + } + + // parse regular statements + while( !CheckToken( "}" ) ) { + ParseStatement(); + } + + // check if we should call the super class destructor + if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "destroy" ) ) { + idTypeDef *superClass; + function_t *destructorFunc = NULL; + + // find the superclass destructor + for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) { + destructorFunc = gameLocal.program.FindFunction( va( "%s::destroy", superClass->Name() ) ); + if ( destructorFunc ) { + break; + } + } + + if ( destructorFunc ) { + if ( func->firstStatement < gameLocal.program.NumStatements() ) { + // change all returns to point to the call to the destructor + pos = &gameLocal.program.GetStatement( func->firstStatement ); + for( i = func->firstStatement; i < gameLocal.program.NumStatements(); i++, pos++ ) { + if ( pos->op == OP_RETURN ) { + pos->op = OP_GOTO; + pos->a = JumpDef( i, gameLocal.program.NumStatements() ); + } + } + } + + // emit the call to the destructor + idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def ); + assert( selfDef ); + EmitPush( selfDef, selfDef->TypeDef() ); + EmitOpcode( &opcodes[ OP_CALL ], destructorFunc->def, 0 ); + } + } + +// Disabled code since it caused a function to fall through to the next function when last statement is in the form "if ( x ) { return; }" +#if 0 + // don't bother adding a return opcode if the "return" statement was used. + if ( ( func->firstStatement == gameLocal.program.NumStatements() ) || ( gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ).op != OP_RETURN ) ) { + // emit an end of statements opcode + EmitOpcode( OP_RETURN, 0, 0 ); + } +#else + // always emit the return opcode + EmitOpcode( OP_RETURN, 0, 0 ); +#endif + + // record the number of statements in the function + func->numStatements = gameLocal.program.NumStatements() - func->firstStatement; + + scope = oldscope; +} + +/* +================ +idCompiler::ParseVariableDef +================ +*/ +void idCompiler::ParseVariableDef( idTypeDef *type, const char *name ) { + idVarDef *def, *def2; + bool negate; + + def = gameLocal.program.GetDef( type, name, scope ); + if ( def ) { + Error( "%s redeclared", name ); + } + + def = gameLocal.program.AllocDef( type, name, scope, false ); + + // check for an initialization + if ( CheckToken( "=" ) ) { + // if a local variable in a function then write out interpreter code to initialize variable + if ( scope->Type() == ev_function ) { + def2 = GetExpression( TOP_PRIORITY ); + if ( ( type == &type_float ) && ( def2->TypeDef() == &type_float ) ) { + EmitOpcode( OP_STORE_F, def2, def ); + } else if ( ( type == &type_vector ) && ( def2->TypeDef() == &type_vector ) ) { + EmitOpcode( OP_STORE_V, def2, def ); + } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_string ) ) { + EmitOpcode( OP_STORE_S, def2, def ); + } else if ( ( type == &type_entity ) && ( ( def2->TypeDef() == &type_entity ) || ( def2->TypeDef()->Inherits( &type_object ) ) ) ) { + EmitOpcode( OP_STORE_ENT, def2, def ); + } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef() == &type_entity ) ) { + EmitOpcode( OP_STORE_OBJENT, def2, def ); + } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef()->Inherits( type ) ) ) { + EmitOpcode( OP_STORE_OBJ, def2, def ); + } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_boolean ) ) { + EmitOpcode( OP_STORE_BOOL, def2, def ); + } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_float ) ) { + EmitOpcode( OP_STORE_FTOS, def2, def ); + } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_boolean ) ) { + EmitOpcode( OP_STORE_BTOS, def2, def ); + } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_vector ) ) { + EmitOpcode( OP_STORE_VTOS, def2, def ); + } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_float ) ) { + EmitOpcode( OP_STORE_FTOBOOL, def2, def ); + } else if ( ( type == &type_float ) && ( def2->TypeDef() == &type_boolean ) ) { + EmitOpcode( OP_STORE_BOOLTOF, def2, def ); + } else { + Error( "bad initialization for '%s'", name ); + } + } else { + // global variables can only be initialized with immediate values + negate = false; + if ( token.type == TT_PUNCTUATION && token == "-" ) { + negate = true; + NextToken(); + if ( immediateType != &type_float ) { + Error( "wrong immediate type for '-' on variable '%s'", name ); + } + } + + if ( immediateType != type ) { + Error( "wrong immediate type for '%s'", name ); + } + + // global variables are initialized at start up + if ( type == &type_string ) { + def->SetString( token, false ); + } else { + if ( negate ) { + immediate._float = -immediate._float; + } + def->SetValue( immediate, false ); + } + NextToken(); + } + } else if ( type == &type_string ) { + // local strings on the stack are initialized in the interpreter + if ( scope->Type() != ev_function ) { + def->SetString( "", false ); + } + } else if ( type->Inherits( &type_object ) ) { + if ( scope->Type() != ev_function ) { + def->SetObject( NULL ); + } + } +} + +/* +================ +idCompiler::GetTypeForEventArg +================ +*/ +idTypeDef *idCompiler::GetTypeForEventArg( char argType ) { + idTypeDef *type; + + switch( argType ) { + case D_EVENT_INTEGER : + // this will get converted to int by the interpreter + type = &type_float; + break; + + case D_EVENT_FLOAT : + type = &type_float; + break; + + case D_EVENT_VECTOR : + type = &type_vector; + break; + + case D_EVENT_STRING : + type = &type_string; + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + type = &type_entity; + break; + + case D_EVENT_VOID : + type = &type_void; + break; + + case D_EVENT_TRACE : + // This data type isn't available from script + type = NULL; + break; + + default: + // probably a typo + type = NULL; + break; + } + + return type; +} + +/* +================ +idCompiler::ParseEventDef +================ +*/ +void idCompiler::ParseEventDef( idTypeDef *returnType, const char *name ) { + const idTypeDef *expectedType; + idTypeDef *argType; + idTypeDef *type; + int i; + int num; + const char *format; + const idEventDef *ev; + idStr parmName; + + ev = idEventDef::FindEvent( name ); + if ( !ev ) { + Error( "Unknown event '%s'", name ); + } + + // set the return type + expectedType = GetTypeForEventArg( ev->GetReturnType() ); + if ( !expectedType ) { + Error( "Invalid return type '%c' in definition of '%s' event.", ev->GetReturnType(), name ); + } + if ( returnType != expectedType ) { + Error( "Return type doesn't match internal return type '%s'", expectedType->Name() ); + } + + idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType ); + + ExpectToken( "(" ); + + format = ev->GetArgFormat(); + num = strlen( format ); + for( i = 0; i < num; i++ ) { + expectedType = GetTypeForEventArg( format[ i ] ); + if ( !expectedType || ( expectedType == &type_void ) ) { + Error( "Invalid parameter '%c' in definition of '%s' event.", format[ i ], name ); + } + + argType = ParseType(); + ParseName( parmName ); + if ( argType != expectedType ) { + Error( "The type of parm %d ('%s') does not match the internal type '%s' in definition of '%s' event.", + i + 1, parmName.c_str(), expectedType->Name(), name ); + } + + newtype.AddFunctionParm( argType, "" ); + + if ( i < num - 1 ) { + if ( CheckToken( ")" ) ) { + Error( "Too few parameters for event definition. Internal definition has %d parameters.", num ); + } + ExpectToken( "," ); + } + } + if ( !CheckToken( ")" ) ) { + Error( "Too many parameters for event definition. Internal definition has %d parameters.", num ); + } + ExpectToken( ";" ); + + type = gameLocal.program.FindType( name ); + if ( type ) { + if ( !newtype.MatchesType( *type ) || ( type->def->value.functionPtr->eventdef != ev ) ) { + Error( "Type mismatch on redefinition of '%s'", name ); + } + } else { + type = gameLocal.program.AllocType( newtype ); + type->def = gameLocal.program.AllocDef( type, name, &def_namespace, true ); + + function_t &func = gameLocal.program.AllocFunction( type->def ); + func.eventdef = ev; + func.parmSize.SetNum( num ); + for( i = 0; i < num; i++ ) { + argType = newtype.GetParmType( i ); + func.parmTotal += argType->Size(); + func.parmSize[ i ] = argType->Size(); + } + + // mark the parms as local + func.locals = func.parmTotal; + } +} + +/* +================ +idCompiler::ParseDefs + +Called at the outer layer and when a local statement is hit +================ +*/ +void idCompiler::ParseDefs( void ) { + idStr name; + idTypeDef *type; + idVarDef *def; + idVarDef *oldscope; + + if ( CheckToken( ";" ) ) { + // skip semicolons, which are harmless and ok syntax + return; + } + + type = ParseType(); + if ( type == &type_scriptevent ) { + type = ParseType(); + ParseName( name ); + ParseEventDef( type, name ); + return; + } + + ParseName( name ); + + if ( type == &type_namespace ) { + def = gameLocal.program.GetDef( type, name, scope ); + if ( !def ) { + def = gameLocal.program.AllocDef( type, name, scope, true ); + } + ParseNamespace( def ); + } else if ( CheckToken( "::" ) ) { + def = gameLocal.program.GetDef( NULL, name, scope ); + if ( !def ) { + Error( "Unknown object name '%s'", name.c_str() ); + } + ParseName( name ); + oldscope = scope; + scope = def; + + ExpectToken( "(" ); + ParseFunctionDef( type, name.c_str() ); + scope = oldscope; + } else if ( type == &type_object ) { + ParseObjectDef( name.c_str() ); + } else if ( CheckToken( "(" ) ) { // check for a function prototype or declaraction + ParseFunctionDef( type, name.c_str() ); + } else { + ParseVariableDef( type, name.c_str() ); + while( CheckToken( "," ) ) { + ParseName( name ); + ParseVariableDef( type, name.c_str() ); + } + ExpectToken( ";" ); + } +} + +/* +================ +idCompiler::ParseNamespace + +Parses anything within a namespace definition +================ +*/ +void idCompiler::ParseNamespace( idVarDef *newScope ) { + idVarDef *oldscope; + + oldscope = scope; + if ( newScope != &def_namespace ) { + ExpectToken( "{" ); + } + + while( !eof ) { + scope = newScope; + callthread = false; + + if ( ( newScope != &def_namespace ) && CheckToken( "}" ) ) { + break; + } + + ParseDefs(); + } + + scope = oldscope; +} + +/* +============ +idCompiler::CompileFile + +compiles the 0 terminated text, adding definitions to the program structure +============ +*/ +void idCompiler::CompileFile( const char *text, const char *filename, bool toConsole ) { + idTimer compile_time; + bool error; + + compile_time.Start(); + + scope = &def_namespace; + basetype = NULL; + callthread = false; + loopDepth = 0; + eof = false; + braceDepth = 0; + immediateType = NULL; + currentLineNumber = 0; + console = toConsole; + + memset( &immediate, 0, sizeof( immediate ) ); + + parser.SetFlags( LEXFL_ALLOWMULTICHARLITERALS ); + parser.LoadMemory( text, strlen( text ), filename ); + parserPtr = &parser; + + // unread tokens to include script defines + token = SCRIPT_DEFAULTDEFS; + token.type = TT_STRING; + token.subtype = token.Length(); + token.line = token.linesCrossed = 0; + parser.UnreadToken( &token ); + + token = "include"; + token.type = TT_NAME; + token.subtype = token.Length(); + token.line = token.linesCrossed = 0; + parser.UnreadToken( &token ); + + token = "#"; + token.type = TT_PUNCTUATION; + token.subtype = P_PRECOMP; + token.line = token.linesCrossed = 0; + parser.UnreadToken( &token ); + + // init the current token line to be the first line so that currentLineNumber is set correctly in NextToken + token.line = 1; + + error = false; + try { + // read first token + NextToken(); + while( !eof && !error ) { + // parse from global namespace + ParseNamespace( &def_namespace ); + } + } + + catch( idCompileError &err ) { + idStr error; + + if ( console ) { + // don't print line number of an error if were calling script from the console using the "script" command + sprintf( error, "Error: %s\n", err.error ); + } else { + sprintf( error, "Error: file %s, line %d: %s\n", gameLocal.program.GetFilename( currentFileNumber ), currentLineNumber, err.error ); + } + + parser.FreeSource(); + + throw idCompileError( error ); + } + + parser.FreeSource(); + + compile_time.Stop(); + if ( !toConsole ) { + gameLocal.Printf( "Compiled '%s': %.1f ms\n", filename, compile_time.Milliseconds() ); + } +} diff --git a/game/script/Script_Compiler.h b/game/script/Script_Compiler.h new file mode 100644 index 000000000..2936f4687 --- /dev/null +++ b/game/script/Script_Compiler.h @@ -0,0 +1,272 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// Copyright (C) 2004 Id Software, Inc. +// +#ifndef __SCRIPT_COMPILER_H__ +#define __SCRIPT_COMPILER_H__ + +const char * const RESULT_STRING = ""; + +typedef struct opcode_s { + const char *name; + const char *opname; + int priority; + bool rightAssociative; + idVarDef *type_a; + idVarDef *type_b; + idVarDef *type_c; +} opcode_t; + +// These opcodes are no longer necessary: +// OP_PUSH_OBJ: +// OP_PUSH_OBJENT: + +enum { + OP_RETURN, + + OP_UINC_F, + OP_UINCP_F, + OP_UDEC_F, + OP_UDECP_F, + OP_COMP_F, + + OP_MUL_F, + OP_MUL_V, + OP_MUL_FV, + OP_MUL_VF, + OP_DIV_F, + OP_MOD_F, + OP_ADD_F, + OP_ADD_V, + OP_ADD_S, + OP_ADD_FS, + OP_ADD_SF, + OP_ADD_VS, + OP_ADD_SV, + OP_SUB_F, + OP_SUB_V, + + OP_EQ_F, + OP_EQ_V, + OP_EQ_S, + OP_EQ_E, + OP_EQ_EO, + OP_EQ_OE, + OP_EQ_OO, + + OP_NE_F, + OP_NE_V, + OP_NE_S, + OP_NE_E, + OP_NE_EO, + OP_NE_OE, + OP_NE_OO, + + OP_LE, + OP_GE, + OP_LT, + OP_GT, + + OP_INDIRECT_F, + OP_INDIRECT_V, + OP_INDIRECT_S, + OP_INDIRECT_ENT, + OP_INDIRECT_BOOL, + OP_INDIRECT_OBJ, + + OP_ADDRESS, + + OP_EVENTCALL, + OP_OBJECTCALL, + OP_SYSCALL, + + OP_STORE_F, + OP_STORE_V, + OP_STORE_S, + OP_STORE_ENT, + OP_STORE_BOOL, + OP_STORE_OBJENT, + OP_STORE_OBJ, + OP_STORE_ENTOBJ, + + OP_STORE_FTOS, + OP_STORE_BTOS, + OP_STORE_VTOS, + OP_STORE_FTOBOOL, + OP_STORE_BOOLTOF, + + OP_STOREP_F, + OP_STOREP_V, + OP_STOREP_S, + OP_STOREP_ENT, + OP_STOREP_FLD, + OP_STOREP_BOOL, + OP_STOREP_OBJ, + OP_STOREP_OBJENT, + + OP_STOREP_FTOS, + OP_STOREP_BTOS, + OP_STOREP_VTOS, + OP_STOREP_FTOBOOL, + OP_STOREP_BOOLTOF, + + OP_UMUL_F, + OP_UMUL_V, + OP_UDIV_F, + OP_UDIV_V, + OP_UMOD_F, + OP_UADD_F, + OP_UADD_V, + OP_USUB_F, + OP_USUB_V, + OP_UAND_F, + OP_UOR_F, + + OP_NOT_BOOL, + OP_NOT_F, + OP_NOT_V, + OP_NOT_S, + OP_NOT_ENT, + + OP_NEG_F, + OP_NEG_V, + + OP_INT_F, + OP_IF, + OP_IFNOT, + + OP_CALL, + OP_THREAD, + OP_OBJTHREAD, + + OP_PUSH_F, + OP_PUSH_V, + OP_PUSH_S, + OP_PUSH_ENT, + OP_PUSH_OBJ, + OP_PUSH_OBJENT, + OP_PUSH_FTOS, + OP_PUSH_BTOF, + OP_PUSH_FTOB, + OP_PUSH_VTOS, + OP_PUSH_BTOS, + + OP_GOTO, + + OP_AND, + OP_AND_BOOLF, + OP_AND_FBOOL, + OP_AND_BOOLBOOL, + OP_OR, + OP_OR_BOOLF, + OP_OR_FBOOL, + OP_OR_BOOLBOOL, + + OP_BITAND, + OP_BITOR, + + OP_BREAK, // placeholder op. not used in final code + OP_CONTINUE, // placeholder op. not used in final code + + NUM_OPCODES +}; + +class idCompiler { +private: + static bool punctuationValid[ 256 ]; + static char *punctuation[]; + + idParser parser; + idParser *parserPtr; + idToken token; + + idTypeDef *immediateType; + eval_t immediate; + + bool eof; + bool console; + bool callthread; + int braceDepth; + int loopDepth; + int currentLineNumber; + int currentFileNumber; + int errorCount; + + idVarDef *scope; // the function being parsed, or NULL + const idVarDef *basetype; // for accessing fields + + float Divide( float numerator, float denominator ); + void Error( const char *error, ... ) const id_attribute((format(printf,2,3))); + void Warning( const char *message, ... ) const id_attribute((format(printf,2,3))); + idVarDef *OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); + idVarDef *EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); + idVarDef *EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ); + bool EmitPush( idVarDef *expression, const idTypeDef *funcArg ); + void NextToken( void ); + void ExpectToken( const char *string ); + bool CheckToken( const char *string ); + void ParseName( idStr &name ); + void SkipOutOfFunction( void ); + void SkipToSemicolon( void ); + idTypeDef *CheckType( void ); + idTypeDef *ParseType( void ); + idVarDef *FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const; + idVarDef *GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ); + idVarDef *VirtualFunctionConstant( idVarDef *func ); + idVarDef *SizeConstant( int size ); + idVarDef *JumpConstant( int value ); + idVarDef *JumpDef( int jumpfrom, int jumpto ); + idVarDef *JumpTo( int jumpto ); + idVarDef *JumpFrom( int jumpfrom ); + idVarDef *ParseImmediate( void ); + idVarDef *EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ); + idVarDef *ParseFunctionCall( idVarDef *func ); + idVarDef *ParseObjectCall( idVarDef *object, idVarDef *func ); + idVarDef *ParseEventCall( idVarDef *object, idVarDef *func ); + idVarDef *ParseSysObjectCall( idVarDef *func ); + idVarDef *LookupDef( const char *name, const idVarDef *baseobj ); + idVarDef *ParseValue( void ); + idVarDef *GetTerm( void ); + bool TypeMatches( etype_t type1, etype_t type2 ) const; + idVarDef *GetExpression( int priority ); + idTypeDef *GetTypeForEventArg( char argType ); + void PatchLoop( int start, int continuePos ); + void ParseReturnStatement( void ); + void ParseWhileStatement( void ); + void ParseForStatement( void ); + void ParseDoWhileStatement( void ); + void ParseIfStatement( void ); + void ParseStatement( void ); + void ParseObjectDef( const char *objname ); + idTypeDef *ParseFunction( idTypeDef *returnType, const char *name ); + void ParseFunctionDef( idTypeDef *returnType, const char *name ); + void ParseVariableDef( idTypeDef *type, const char *name ); + void ParseEventDef( idTypeDef *type, const char *name ); + void ParseDefs( void ); + void ParseNamespace( idVarDef *newScope ); + +public : + static opcode_t opcodes[]; + + idCompiler(); + void CompileFile( const char *text, const char *filename, bool console ); +}; + +#endif /* !__SCRIPT_COMPILER_H__ */ diff --git a/game/script/Script_Interpreter.cpp b/game/script/Script_Interpreter.cpp new file mode 100644 index 000000000..b1f7f8d85 --- /dev/null +++ b/game/script/Script_Interpreter.cpp @@ -0,0 +1,2025 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +/* +================ +idInterpreter::idInterpreter() +================ +*/ +idInterpreter::idInterpreter() { + localstackUsed = 0; + terminateOnExit = true; + debug = 0; + memset( localstack, 0, sizeof( localstack ) ); + memset( callStack, 0, sizeof( callStack ) ); + Reset(); +#ifdef PROFILE_SCRIPT + while (functionTimers.size() > 0) + { + functionTimers.pop(); + } +#endif +} + +/* +================ +idInterpreter::Save +================ +*/ +void idInterpreter::Save( idSaveGame *savefile ) const { + int i; + + savefile->WriteInt( callStackDepth ); + for( i = 0; i < callStackDepth; i++ ) { + savefile->WriteInt( callStack[i].s ); + if ( callStack[i].f ) { + savefile->WriteInt( gameLocal.program.GetFunctionIndex( callStack[i].f ) ); + } else { + savefile->WriteInt( -1 ); + } + savefile->WriteInt( callStack[i].stackbase ); + } + savefile->WriteInt( maxStackDepth ); + + savefile->WriteInt( localstackUsed ); + savefile->Write( &localstack, localstackUsed ); + + savefile->WriteInt( localstackBase ); + savefile->WriteInt( maxLocalstackUsed ); + + if ( currentFunction ) { + savefile->WriteInt( gameLocal.program.GetFunctionIndex( currentFunction ) ); + } else { + savefile->WriteInt( -1 ); + } + savefile->WriteInt( instructionPointer ); + + savefile->WriteInt( popParms ); + + if ( multiFrameEvent ) { + savefile->WriteString( multiFrameEvent->GetName() ); + } else { + savefile->WriteString( "" ); + } + savefile->WriteObject( eventEntity ); + + savefile->WriteObject( thread ); + + savefile->WriteBool( doneProcessing ); + savefile->WriteBool( threadDying ); + savefile->WriteBool( terminateOnExit ); + savefile->WriteBool( debug ); +} + +/* +================ +idInterpreter::Restore +================ +*/ +void idInterpreter::Restore( idRestoreGame *savefile ) { + int i; + idStr funcname; + int func_index; + + savefile->ReadInt( callStackDepth ); + for( i = 0; i < callStackDepth; i++ ) { + savefile->ReadInt( callStack[i].s ); + + savefile->ReadInt( func_index ); + if ( func_index >= 0 ) { + callStack[i].f = gameLocal.program.GetFunction( func_index ); + } else { + callStack[i].f = NULL; + } + + savefile->ReadInt( callStack[i].stackbase ); + } + savefile->ReadInt( maxStackDepth ); + + savefile->ReadInt( localstackUsed ); + savefile->Read( &localstack, localstackUsed ); + + savefile->ReadInt( localstackBase ); + savefile->ReadInt( maxLocalstackUsed ); + + savefile->ReadInt( func_index ); + if ( func_index >= 0 ) { + currentFunction = gameLocal.program.GetFunction( func_index ); + } else { + currentFunction = NULL; + } + savefile->ReadInt( instructionPointer ); + + savefile->ReadInt( popParms ); + + savefile->ReadString( funcname ); + if ( funcname.Length() ) { + multiFrameEvent = idEventDef::FindEvent( funcname ); + } + + savefile->ReadObject( reinterpret_cast( eventEntity ) ); + savefile->ReadObject( reinterpret_cast( thread ) ); + + savefile->ReadBool( doneProcessing ); + savefile->ReadBool( threadDying ); + savefile->ReadBool( terminateOnExit ); + savefile->ReadBool( debug ); +} + +/* +================ +idInterpreter::Reset +================ +*/ +void idInterpreter::Reset( void ) { +#ifdef PROFILE_SCRIPT + // Clear out any function timers + while (functionTimers.size() > 0) + { + idTimer& topMost = functionTimers.top(); + if (topMost.Running()) + { + topMost.Stop(); + } + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Resetting script stack, Timer: %lf\n", functionTimers.top().Milliseconds()); + functionTimers.pop(); + } +#endif + + callStackDepth = 0; + localstackUsed = 0; + localstackBase = 0; + + maxLocalstackUsed = 0; + maxStackDepth = 0; + + popParms = 0; + multiFrameEvent = NULL; + eventEntity = NULL; + + currentFunction = 0; + NextInstruction( 0 ); + + threadDying = false; + doneProcessing = true; +} + +/* +================ +idInterpreter::GetRegisterValue + +Returns a string representation of the value of the register. This is +used primarily for the debugger and debugging + +//FIXME: This is pretty much wrong. won't access data in most situations. +================ +*/ +bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) { + varEval_t reg; + idVarDef *d; + char funcObject[ 1024 ]; + char *funcName; + const idVarDef *scope; + const idTypeDef *field; + const idScriptObject *obj; + const function_t *func; + + out.Empty(); + + if ( scopeDepth == -1 ) { + scopeDepth = callStackDepth; + } + + if ( scopeDepth == callStackDepth ) { + func = currentFunction; + } else { + func = callStack[ scopeDepth ].f; + } + if ( !func ) { + return false; + } + + idStr::Copynz( funcObject, func->Name(), sizeof( funcObject ) ); + funcName = strstr( funcObject, "::" ); + if ( funcName ) { + *funcName = '\0'; + scope = gameLocal.program.GetDef( NULL, funcObject, &def_namespace ); + funcName += 2; + } else { + funcName = funcObject; + scope = &def_namespace; + } + + // Get the function from the object + d = gameLocal.program.GetDef( NULL, funcName, scope ); + if ( !d ) { + return false; + } + + // Get the variable itself and check various namespaces + d = gameLocal.program.GetDef( NULL, name, d ); + if ( !d ) { + if ( scope == &def_namespace ) { + return false; + } + + d = gameLocal.program.GetDef( NULL, name, scope ); + if ( !d ) { + d = gameLocal.program.GetDef( NULL, name, &def_namespace ); + if ( !d ) { + return false; + } + } + } + + reg = GetVariable( d ); + switch( d->Type() ) { + case ev_float: + if ( reg.floatPtr ) { + out = va("%g", *reg.floatPtr ); + } else { + out = "0"; + } + return true; + break; + + case ev_vector: + if ( reg.vectorPtr ) { + out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z ); + } else { + out = "0,0,0"; + } + return true; + break; + + case ev_boolean: + if ( reg.intPtr ) { + out = va( "%d", *reg.intPtr ); + } else { + out = "0"; + } + return true; + break; + + case ev_field: + if ( scope == &def_namespace ) { + // should never happen, but handle it safely anyway + return false; + } + + field = scope->TypeDef()->GetParmType( reg.ptrOffset )->FieldType(); + obj = *reinterpret_cast( &localstack[ callStack[ callStackDepth ].stackbase ] ); + if ( !field || !obj ) { + return false; + } + + switch ( field->Type() ) { + case ev_boolean: + out = va( "%d", *( reinterpret_cast( &obj->data[ reg.ptrOffset ] ) ) ); + return true; + + case ev_float: + out = va( "%g", *( reinterpret_cast( &obj->data[ reg.ptrOffset ] ) ) ); + return true; + + default: + return false; + } + break; + + case ev_string: + if ( reg.stringPtr ) { + out = "\""; + out += reg.stringPtr; + out += "\""; + } else { + out = "\"\""; + } + return true; + + default: + return false; + } +} + +/* +================ +idInterpreter::GetCallstackDepth +================ +*/ +int idInterpreter::GetCallstackDepth( void ) const { + return callStackDepth; +} + +/* +================ +idInterpreter::GetCallstack +================ +*/ +const prstack_t *idInterpreter::GetCallstack( void ) const { + return &callStack[ 0 ]; +} + +/* +================ +idInterpreter::GetCurrentFunction +================ +*/ +const function_t *idInterpreter::GetCurrentFunction( void ) const { + return currentFunction; +} + +/* +================ +idInterpreter::GetThread +================ +*/ +idThread *idInterpreter::GetThread( void ) const { + return thread; +} + + +/* +================ +idInterpreter::SetThread +================ +*/ +void idInterpreter::SetThread( idThread *pThread ) { + thread = pThread; +} + +/* +================ +idInterpreter::CurrentLine +================ +*/ +int idInterpreter::CurrentLine( void ) const { + if ( instructionPointer < 0 ) { + return 0; + } + return gameLocal.program.GetLineNumberForStatement( instructionPointer ); +} + +/* +================ +idInterpreter::CurrentFile +================ +*/ +const char *idInterpreter::CurrentFile( void ) const { + if ( instructionPointer < 0 ) { + return ""; + } + return gameLocal.program.GetFilenameForStatement( instructionPointer ); +} + +/* +============ +idInterpreter::StackTrace +============ +*/ +void idInterpreter::StackTrace( void ) const { + const function_t *f; + int i; + int top; + + if ( callStackDepth == 0 ) { + gameLocal.Printf( "\n" ); + return; + } + + top = callStackDepth; + if ( top >= MAX_STACK_DEPTH ) { + top = MAX_STACK_DEPTH - 1; + } + + if ( !currentFunction ) { + gameLocal.Printf( "\n" ); + } else { + gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( currentFunction->filenum ), currentFunction->Name() ); + } + + for( i = top; i >= 0; i-- ) { + f = callStack[ i ].f; + if ( !f ) { + gameLocal.Printf( "\n" ); + } else { + gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( f->filenum ), f->Name() ); + } + } +} + +/* +============ +idInterpreter::Error + +Aborts the currently executing function +============ +*/ +void idInterpreter::Error( const char *fmt, ... ) const { + va_list argptr; + char text[ 1024 ]; + + va_start( argptr, fmt ); + vsprintf( text, fmt, argptr ); + va_end( argptr ); + + StackTrace(); + + if ( ( instructionPointer >= 0 ) && ( instructionPointer < gameLocal.program.NumStatements() ) ) { + statement_t &line = gameLocal.program.GetStatement( instructionPointer ); + common->Error( "%s(%d): Thread '%s': %s\n", gameLocal.program.GetFilename( line.file ), line.linenumber, thread->GetThreadName(), text ); + } else { + common->Error( "Thread '%s': %s\n", thread->GetThreadName(), text ); + } +} + +/* +============ +idInterpreter::Warning + +Prints file and line number information with warning. +============ +*/ +void idInterpreter::Warning( const char *fmt, ... ) const { + va_list argptr; + char text[ 1024 ]; + + va_start( argptr, fmt ); + vsprintf( text, fmt, argptr ); + va_end( argptr ); + + if ( ( instructionPointer >= 0 ) && ( instructionPointer < gameLocal.program.NumStatements() ) ) { + statement_t &line = gameLocal.program.GetStatement( instructionPointer ); + common->Warning( "%s(%d): Thread '%s': %s", gameLocal.program.GetFilename( line.file ), line.linenumber, thread->GetThreadName(), text ); + } else { + common->Warning( "Thread '%s' : %s", thread->GetThreadName(), text ); + } +} + +/* +================ +idInterpreter::DisplayInfo +================ +*/ +void idInterpreter::DisplayInfo( void ) const { + const function_t *f; + int i; + + gameLocal.Printf( " Stack depth: %d bytes, %d max\n", localstackUsed, maxLocalstackUsed ); + gameLocal.Printf( " Call depth: %d, %d max\n", callStackDepth, maxStackDepth ); + gameLocal.Printf( " Call Stack: " ); + + if ( callStackDepth == 0 ) { + gameLocal.Printf( "\n" ); + } else { + if ( !currentFunction ) { + gameLocal.Printf( "\n" ); + } else { + gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( currentFunction->filenum ), currentFunction->Name() ); + } + + for( i = callStackDepth; i > 0; i-- ) { + gameLocal.Printf( " " ); + f = callStack[ i ].f; + if ( !f ) { + gameLocal.Printf( "\n" ); + } else { + gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( f->filenum ), f->Name() ); + } + } + } +} + +/* +==================== +idInterpreter::ThreadCall + +Copys the args from the calling thread's stack +==================== +*/ +void idInterpreter::ThreadCall( idInterpreter *source, const function_t *func, int args ) { + Reset(); + + memcpy( localstack, &source->localstack[ source->localstackUsed - args ], args ); + + localstackUsed = args; + localstackBase = 0; + + maxLocalstackUsed = localstackUsed; + EnterFunction( func, false ); + + thread->SetThreadName( currentFunction->Name() ); +} + +/* +================ +idInterpreter::EnterObjectFunction + +Calls a function on a script object. + +NOTE: If this is called from within a event called by this interpreter, the function arguments will be invalid after calling this function. +================ +*/ +void idInterpreter::EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack ) { + if ( clearStack ) { + Reset(); + } + if ( popParms ) { + PopParms( popParms ); + popParms = 0; + } + Push( self->entityNumber + 1 ); + EnterFunction( func, false ); +} + +/* +==================== +idInterpreter::EnterFunction + +Returns the new program statement counter + +NOTE: If this is called from within a event called by this interpreter, the function arguments will be invalid after calling this function. +==================== +*/ +void idInterpreter::EnterFunction( const function_t *func, bool clearStack ) { + int c; + prstack_t *stack; + + if ( clearStack ) { + Reset(); + } + if ( popParms ) { + PopParms( popParms ); + popParms = 0; + } + + if ( callStackDepth >= MAX_STACK_DEPTH ) { + Error( "call stack overflow" ); + } + + stack = &callStack[ callStackDepth ]; + + stack->s = instructionPointer + 1; // point to the next instruction to execute + stack->f = currentFunction; + stack->stackbase = localstackBase; + + callStackDepth++; + if ( callStackDepth > maxStackDepth ) { + maxStackDepth = callStackDepth; + } + + if ( !func ) { + Error( "NULL function" ); + } + + if ( debug ) { + if ( currentFunction ) { + gameLocal.Printf( "%d: call '%s' from '%s'(line %d)%s\n", gameLocal.time, func->Name(), currentFunction->Name(), + gameLocal.program.GetStatement( instructionPointer ).linenumber, clearStack ? " clear stack" : "" ); + } else { + gameLocal.Printf( "%d: call '%s'%s\n", gameLocal.time, func->Name(), clearStack ? " clear stack" : "" ); + } + } + + currentFunction = func; + assert( !func->eventdef ); + NextInstruction( func->firstStatement ); + + // allocate space on the stack for locals + // parms are already on stack + c = func->locals - func->parmTotal; + assert( c >= 0 ); + + if ( localstackUsed + c > LOCALSTACK_SIZE ) { + Error( "EnterFuncton: locals stack overflow\n" ); + } + + // initialize local stack variables to zero + memset( &localstack[ localstackUsed ], 0, c ); + + localstackUsed += c; + localstackBase = localstackUsed - func->locals; + + if ( localstackUsed > maxLocalstackUsed ) { + maxLocalstackUsed = localstackUsed ; + } +} + +/* +==================== +idInterpreter::LeaveFunction +==================== +*/ +void idInterpreter::LeaveFunction( idVarDef *returnDef ) { + prstack_t *stack; + varEval_t ret; + + if ( callStackDepth <= 0 ) { + Error( "prog stack underflow" ); + } + + // return value + if ( returnDef ) { + switch( returnDef->Type() ) { + case ev_string : + gameLocal.program.ReturnString( GetString( returnDef ) ); + break; + + case ev_vector : + ret = GetVariable( returnDef ); + gameLocal.program.ReturnVector( *ret.vectorPtr ); + break; + + default : + ret = GetVariable( returnDef ); + gameLocal.program.ReturnInteger( *ret.intPtr ); + } + } + + // remove locals from the stack + PopParms( currentFunction->locals ); + assert( localstackUsed == localstackBase ); + + if ( debug ) { + statement_t &line = gameLocal.program.GetStatement( instructionPointer ); + gameLocal.Printf( "%d: %s(%d): exit %s", gameLocal.time, gameLocal.program.GetFilename( line.file ), line.linenumber, currentFunction->Name() ); + if ( callStackDepth > 1 ) { + gameLocal.Printf( " return to %s(line %d)\n", callStack[ callStackDepth - 1 ].f->Name(), gameLocal.program.GetStatement( callStack[ callStackDepth - 1 ].s ).linenumber ); + } else { + gameLocal.Printf( " done\n" ); + } + } + + // up stack + callStackDepth--; + stack = &callStack[ callStackDepth ]; + currentFunction = stack->f; + localstackBase = stack->stackbase; + NextInstruction( stack->s ); + + if ( !callStackDepth ) { + // all done + doneProcessing = true; + threadDying = true; + currentFunction = 0; + } +} + +/* +================ +idInterpreter::CallEvent +================ +*/ +void idInterpreter::CallEvent( const function_t *func, int argsize ) { + int i; + int j; + varEval_t var; + int pos; + int start; + int data[ D_EVENT_MAXARGS ]; + const idEventDef *evdef; + const char *format; + + if ( !func ) { + Error( "NULL function" ); + } + + assert( func->eventdef ); + evdef = func->eventdef; + + start = localstackUsed - argsize; + var.intPtr = ( int * )&localstack[ start ]; + eventEntity = GetEntity( *var.entityNumberPtr ); + + if ( !eventEntity || !eventEntity->RespondsTo( *evdef ) ) { + if ( eventEntity && developer.GetBool() ) { + // give a warning in developer mode + Warning( "Function '%s' not supported on entity '%s'", evdef->GetName(), eventEntity->name.c_str() ); + } + // always return a safe value when an object doesn't exist + switch( evdef->GetReturnType() ) { + case D_EVENT_INTEGER : + gameLocal.program.ReturnInteger( 0 ); + break; + + case D_EVENT_FLOAT : + gameLocal.program.ReturnFloat( 0 ); + break; + + case D_EVENT_VECTOR : + gameLocal.program.ReturnVector( vec3_zero ); + break; + + case D_EVENT_STRING : + gameLocal.program.ReturnString( "" ); + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + gameLocal.program.ReturnEntity( ( idEntity * )NULL ); + break; + + case D_EVENT_TRACE : + default: + // unsupported data type + break; + } + + PopParms( argsize ); + eventEntity = NULL; + return; + } + + format = evdef->GetArgFormat(); + for( j = 0, i = 0, pos = type_object.Size(); ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) { + switch( format[ i ] ) { + case D_EVENT_INTEGER : + var.intPtr = ( int * )&localstack[ start + pos ]; + data[ i ] = int( *var.floatPtr ); + break; + + case D_EVENT_FLOAT : + var.intPtr = ( int * )&localstack[ start + pos ]; + ( *( float * )&data[ i ] ) = *var.floatPtr; + break; + + case D_EVENT_VECTOR : + var.intPtr = ( int * )&localstack[ start + pos ]; + ( *( idVec3 ** )&data[ i ] ) = var.vectorPtr; + break; + + case D_EVENT_STRING : + ( *( const char ** )&data[ i ] ) = ( char * )&localstack[ start + pos ]; + break; + + case D_EVENT_ENTITY : + var.intPtr = ( int * )&localstack[ start + pos ]; + ( *( idEntity ** )&data[ i ] ) = GetEntity( *var.entityNumberPtr ); + if ( !( *( idEntity ** )&data[ i ] ) ) { + Warning( "Entity not found for event '%s'. Terminating thread.", evdef->GetName() ); + threadDying = true; + PopParms( argsize ); + return; + } + break; + + case D_EVENT_ENTITY_NULL : + var.intPtr = ( int * )&localstack[ start + pos ]; + ( *( idEntity ** )&data[ i ] ) = GetEntity( *var.entityNumberPtr ); + break; + + case D_EVENT_TRACE : + Error( "trace type not supported from script for '%s' event.", evdef->GetName() ); + break; + + default : + Error( "Invalid arg format string for '%s' event.", evdef->GetName() ); + break; + } + + pos += func->parmSize[ j++ ]; + } + + popParms = argsize; + eventEntity->ProcessEventArgPtr( evdef, data ); + + if ( !multiFrameEvent ) { + if ( popParms ) { + PopParms( popParms ); + } + eventEntity = NULL; + } else { + doneProcessing = true; + } + popParms = 0; +} + +/* +================ +idInterpreter::BeginMultiFrameEvent +================ +*/ +bool idInterpreter::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) { + if ( eventEntity != ent ) { + Error( "idInterpreter::BeginMultiFrameEvent called with wrong entity" ); + } + if ( multiFrameEvent ) { + if ( multiFrameEvent != event ) { + Error( "idInterpreter::BeginMultiFrameEvent called with wrong event" ); + } + return false; + } + + multiFrameEvent = event; + return true; +} + +/* +================ +idInterpreter::EndMultiFrameEvent +================ +*/ +void idInterpreter::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) { + if ( multiFrameEvent != event ) { + Error( "idInterpreter::EndMultiFrameEvent called with wrong event" ); + } + + multiFrameEvent = NULL; +} + +/* +================ +idInterpreter::MultiFrameEventInProgress +================ +*/ +bool idInterpreter::MultiFrameEventInProgress( void ) const { + return multiFrameEvent != NULL; +} + +/* +================ +idInterpreter::CallSysEvent +================ +*/ +void idInterpreter::CallSysEvent( const function_t *func, int argsize ) { + int i; + int j; + varEval_t source; + int pos; + int start; + int data[ D_EVENT_MAXARGS ]; + const idEventDef *evdef; + const char *format; + + if ( !func ) { + Error( "NULL function" ); + } + + assert( func->eventdef ); + evdef = func->eventdef; + + start = localstackUsed - argsize; + + format = evdef->GetArgFormat(); + for( j = 0, i = 0, pos = 0; ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) { + switch( format[ i ] ) { + case D_EVENT_INTEGER : + source.intPtr = ( int * )&localstack[ start + pos ]; + *( int * )&data[ i ] = int( *source.floatPtr ); + break; + + case D_EVENT_FLOAT : + source.intPtr = ( int * )&localstack[ start + pos ]; + *( float * )&data[ i ] = *source.floatPtr; + break; + + case D_EVENT_VECTOR : + source.intPtr = ( int * )&localstack[ start + pos ]; + *( idVec3 ** )&data[ i ] = source.vectorPtr; + break; + + case D_EVENT_STRING : + *( const char ** )&data[ i ] = ( char * )&localstack[ start + pos ]; + break; + + case D_EVENT_ENTITY : + source.intPtr = ( int * )&localstack[ start + pos ]; + *( idEntity ** )&data[ i ] = GetEntity( *source.entityNumberPtr ); + if ( !*( idEntity ** )&data[ i ] ) { + Warning( "Entity not found for event '%s'. Terminating thread.", evdef->GetName() ); + threadDying = true; + PopParms( argsize ); + return; + } + break; + + case D_EVENT_ENTITY_NULL : + source.intPtr = ( int * )&localstack[ start + pos ]; + *( idEntity ** )&data[ i ] = GetEntity( *source.entityNumberPtr ); + break; + + case D_EVENT_TRACE : + Error( "trace type not supported from script for '%s' event.", evdef->GetName() ); + break; + + default : + Error( "Invalid arg format string for '%s' event.", evdef->GetName() ); + break; + } + + pos += func->parmSize[ j++ ]; + } + + popParms = argsize; + thread->ProcessEventArgPtr( evdef, data ); + if ( popParms ) { + PopParms( popParms ); + } + popParms = 0; +} + +/* +==================== +idInterpreter::Execute +==================== +*/ +bool idInterpreter::Execute( void ) { + varEval_t var_a; + varEval_t var_b; + varEval_t var_c; + varEval_t var; + statement_t *st; + int runaway; + idThread *newThread; + float floatVal; + idScriptObject *obj; + const function_t *func; + + if ( threadDying || !currentFunction ) { + return true; + } + + if ( multiFrameEvent ) { + // move to previous instruction and call it again + instructionPointer--; + } + +#ifdef PROFILE_SCRIPT + if (debug && functionTimers.size() == 0) { + // Create a new function timer, as we don't appear to have one + functionTimers.push(idTimer()); + } + if (debug) { + functionTimers.top().Start(); + } +#endif + + runaway = 5000000; + + doneProcessing = false; + while( !doneProcessing && !threadDying ) { + instructionPointer++; + + if ( !--runaway ) { + Error( "runaway loop error" ); + } + + // next statement + st = &gameLocal.program.GetStatement( instructionPointer ); + + switch( st->op ) { + case OP_RETURN: + +#ifdef PROFILE_SCRIPT + if (debug && functionTimers.size() > 0) + { + // greebo: End the current timer, before adding a new one + functionTimers.top().Stop(); + + DM_LOG(LC_AI, LT_INFO)LOGSTRING("Spent %lf msec in function %s.", functionTimers.top().Milliseconds(), currentFunction->Name()); + + // Remove the stopped timer + functionTimers.pop(); + } +#endif + // Actually leave the function + LeaveFunction( st->a ); + +#ifdef PROFILE_SCRIPT + // greebo: Maybe we have a timer of a previous function? + if (debug && functionTimers.size() > 0) + { + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Restarting timer of previous function: %s", currentFunction->Name()); + // Start the timer of the previous thread + functionTimers.top().Start(); + } +#endif + break; + + case OP_THREAD: + newThread = new idThread( this, st->a->value.functionPtr, st->b->value.argSize ); + newThread->Start(); + + // return the thread number to the script + gameLocal.program.ReturnFloat( newThread->GetThreadNum() ); + PopParms( st->b->value.argSize ); + break; + + case OP_OBJTHREAD: + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction ); + assert( st->c->value.argSize == func->parmTotal ); + newThread = new idThread( this, GetEntity( *var_a.entityNumberPtr ), func, func->parmTotal ); + newThread->Start(); + + // return the thread number to the script + gameLocal.program.ReturnFloat( newThread->GetThreadNum() ); + } else { + // return a null thread to the script + gameLocal.program.ReturnFloat( 0.0f ); + } + PopParms( st->c->value.argSize ); + break; + + case OP_CALL: + +#ifdef PROFILE_SCRIPT + if (debug && functionTimers.size() > 0) + { + // End the current timer, before leaving the current one + functionTimers.top().Stop(); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Stopping timer of %s at %lf msec.", currentFunction->Name(), functionTimers.top().Milliseconds()); + } +#endif + EnterFunction( st->a->value.functionPtr, false ); +#ifdef PROFILE_SCRIPT + if (debug) { + // Add and start a new timer + functionTimers.push(idTimer()); + + functionTimers.top().Clear(); + functionTimers.top().Start(); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Starting new timer on entering function %s.", currentFunction->Name()); + } +#endif + break; + + case OP_EVENTCALL: +#ifdef PROFILE_SCRIPT + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Calling script event."); +#endif + CallEvent( st->a->value.functionPtr, st->b->value.argSize ); + break; + + case OP_OBJECTCALL: + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction ); + +#ifdef PROFILE_SCRIPT + if (debug && functionTimers.size() > 0) + { + // End the current timer, before leaving the current one + functionTimers.top().Stop(); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Stopping timer of %s at %lf msec.", currentFunction->Name(), functionTimers.top().Milliseconds()); + } +#endif + EnterFunction( func, false ); +#ifdef PROFILE_SCRIPT + if (debug) { + // Add and start a new timer + functionTimers.push(idTimer()); + + functionTimers.top().Clear(); + functionTimers.top().Start(); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Starting new timer on entering function %s.", currentFunction->Name()); + } +#endif + } else { + int entNum = *var_a.entityNumberPtr; + idEntity *ent = GetEntity(entNum); + if (ent) { + Warning("Tried to call function on entity %s, but entity has no script object", ent->name.c_str()); + } else { + Warning("Tried to call function on non-existent entity (#%d)", entNum); + } + + // return a 'safe' value + gameLocal.program.ReturnVector( vec3_zero ); + gameLocal.program.ReturnString( "" ); + PopParms( st->c->value.argSize ); + } + break; + + case OP_SYSCALL: + CallSysEvent( st->a->value.functionPtr, st->b->value.argSize ); + break; + + case OP_IFNOT: + var_a = GetVariable( st->a ); + if ( *var_a.intPtr == 0 ) { + NextInstruction( instructionPointer + st->b->value.jumpOffset ); + } + break; + + case OP_IF: + var_a = GetVariable( st->a ); + if ( *var_a.intPtr != 0 ) { + NextInstruction( instructionPointer + st->b->value.jumpOffset ); + } + break; + + case OP_GOTO: + NextInstruction( instructionPointer + st->a->value.jumpOffset ); + break; + + case OP_ADD_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = *var_a.floatPtr + *var_b.floatPtr; + break; + + case OP_ADD_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.vectorPtr = *var_a.vectorPtr + *var_b.vectorPtr; + break; + + case OP_ADD_S: + SetString( st->c, GetString( st->a ) ); + AppendString( st->c, GetString( st->b ) ); + break; + + case OP_ADD_FS: + var_a = GetVariable( st->a ); + SetString( st->c, FloatToString( *var_a.floatPtr ) ); + AppendString( st->c, GetString( st->b ) ); + break; + + case OP_ADD_SF: + var_b = GetVariable( st->b ); + SetString( st->c, GetString( st->a ) ); + AppendString( st->c, FloatToString( *var_b.floatPtr ) ); + break; + + case OP_ADD_VS: + var_a = GetVariable( st->a ); + SetString( st->c, var_a.vectorPtr->ToString() ); + AppendString( st->c, GetString( st->b ) ); + break; + + case OP_ADD_SV: + var_b = GetVariable( st->b ); + SetString( st->c, GetString( st->a ) ); + AppendString( st->c, var_b.vectorPtr->ToString() ); + break; + + case OP_SUB_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = *var_a.floatPtr - *var_b.floatPtr; + break; + + case OP_SUB_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.vectorPtr = *var_a.vectorPtr - *var_b.vectorPtr; + break; + + case OP_MUL_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = *var_a.floatPtr * *var_b.floatPtr; + break; + + case OP_MUL_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = *var_a.vectorPtr * *var_b.vectorPtr; + break; + + case OP_MUL_FV: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.vectorPtr = *var_a.floatPtr * *var_b.vectorPtr; + break; + + case OP_MUL_VF: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.vectorPtr = *var_a.vectorPtr * *var_b.floatPtr; + break; + + case OP_DIV_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + + if ( *var_b.floatPtr == 0.0f ) { + Warning( "Divide by zero" ); + *var_c.floatPtr = idMath::INFINITY; + } else { + *var_c.floatPtr = *var_a.floatPtr / *var_b.floatPtr; + } + break; + + case OP_MOD_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable ( st->c ); + + if ( *var_b.floatPtr == 0.0f ) { + Warning( "Divide by zero" ); + *var_c.floatPtr = *var_a.floatPtr; + } else { + *var_c.floatPtr = static_cast( *var_a.floatPtr ) % static_cast( *var_b.floatPtr ); + } + break; + + case OP_BITAND: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = static_cast( *var_a.floatPtr ) & static_cast( *var_b.floatPtr ); + break; + + case OP_BITOR: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = static_cast( *var_a.floatPtr ) | static_cast( *var_b.floatPtr ); + break; + + case OP_GE: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr >= *var_b.floatPtr ); + break; + + case OP_LE: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr <= *var_b.floatPtr ); + break; + + case OP_GT: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr > *var_b.floatPtr ); + break; + + case OP_LT: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr < *var_b.floatPtr ); + break; + + case OP_AND: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.floatPtr != 0.0f ); + break; + + case OP_AND_BOOLF: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.floatPtr != 0.0f ); + break; + + case OP_AND_FBOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.intPtr != 0 ); + break; + + case OP_AND_BOOLBOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.intPtr != 0 ); + break; + + case OP_OR: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.floatPtr != 0.0f ); + break; + + case OP_OR_BOOLF: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.floatPtr != 0.0f ); + break; + + case OP_OR_FBOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.intPtr != 0 ); + break; + + case OP_OR_BOOLBOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.intPtr != 0 ); + break; + + case OP_NOT_BOOL: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.intPtr == 0 ); + break; + + case OP_NOT_F: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr == 0.0f ); + break; + + case OP_NOT_V: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.vectorPtr == vec3_zero ); + break; + + case OP_NOT_S: + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( strlen( GetString( st->a ) ) == 0 ); + break; + + case OP_NOT_ENT: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( GetEntity( *var_a.entityNumberPtr ) == NULL ); + break; + + case OP_NEG_F: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = -*var_a.floatPtr; + break; + + case OP_NEG_V: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.vectorPtr = -*var_a.vectorPtr; + break; + + case OP_INT_F: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = static_cast( *var_a.floatPtr ); + break; + + case OP_EQ_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr == *var_b.floatPtr ); + break; + + case OP_EQ_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.vectorPtr == *var_b.vectorPtr ); + break; + + case OP_EQ_S: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) == 0 ); + break; + + case OP_EQ_E: + case OP_EQ_EO: + case OP_EQ_OE: + case OP_EQ_OO: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.entityNumberPtr == *var_b.entityNumberPtr ); + break; + + case OP_NE_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.floatPtr != *var_b.floatPtr ); + break; + + case OP_NE_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.vectorPtr != *var_b.vectorPtr ); + break; + + case OP_NE_S: + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) != 0 ); + break; + + case OP_NE_E: + case OP_NE_EO: + case OP_NE_OE: + case OP_NE_OO: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ( *var_a.entityNumberPtr != *var_b.entityNumberPtr ); + break; + + case OP_UADD_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr += *var_a.floatPtr; + break; + + case OP_UADD_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.vectorPtr += *var_a.vectorPtr; + break; + + case OP_USUB_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr -= *var_a.floatPtr; + break; + + case OP_USUB_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.vectorPtr -= *var_a.vectorPtr; + break; + + case OP_UMUL_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr *= *var_a.floatPtr; + break; + + case OP_UMUL_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.vectorPtr *= *var_a.floatPtr; + break; + + case OP_UDIV_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + + if ( *var_a.floatPtr == 0.0f ) { + Warning( "Divide by zero" ); + *var_b.floatPtr = idMath::INFINITY; + } else { + *var_b.floatPtr = *var_b.floatPtr / *var_a.floatPtr; + } + break; + + case OP_UDIV_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + + if ( *var_a.floatPtr == 0.0f ) { + Warning( "Divide by zero" ); + var_b.vectorPtr->Set( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY ); + } else { + *var_b.vectorPtr = *var_b.vectorPtr / *var_a.floatPtr; + } + break; + + case OP_UMOD_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + + if ( *var_a.floatPtr == 0.0f ) { + Warning( "Divide by zero" ); + *var_b.floatPtr = *var_a.floatPtr; + } else { + *var_b.floatPtr = static_cast( *var_b.floatPtr ) % static_cast( *var_a.floatPtr ); + } + break; + + case OP_UOR_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr = static_cast( *var_b.floatPtr ) | static_cast( *var_a.floatPtr ); + break; + + case OP_UAND_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr = static_cast( *var_b.floatPtr ) & static_cast( *var_a.floatPtr ); + break; + + case OP_UINC_F: + var_a = GetVariable( st->a ); + ( *var_a.floatPtr )++; + break; + + case OP_UINCP_F: + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + ( *var.floatPtr )++; + } + break; + + case OP_UDEC_F: + var_a = GetVariable( st->a ); + ( *var_a.floatPtr )--; + break; + + case OP_UDECP_F: + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + ( *var.floatPtr )--; + } + break; + + case OP_COMP_F: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + *var_c.floatPtr = ~static_cast( *var_a.floatPtr ); + break; + + case OP_STORE_F: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr = *var_a.floatPtr; + break; + + case OP_STORE_ENT: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.entityNumberPtr = *var_a.entityNumberPtr; + break; + + case OP_STORE_BOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.intPtr = *var_a.intPtr; + break; + + case OP_STORE_OBJENT: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( !obj ) { + *var_b.entityNumberPtr = 0; + } else if ( !obj->GetTypeDef()->Inherits( st->b->TypeDef() ) ) { + //Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->b->TypeDef()->Name() ); + *var_b.entityNumberPtr = 0; + } else { + *var_b.entityNumberPtr = *var_a.entityNumberPtr; + } + break; + + case OP_STORE_OBJ: + case OP_STORE_ENTOBJ: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.entityNumberPtr = *var_a.entityNumberPtr; + break; + + case OP_STORE_S: + SetString( st->b, GetString( st->a ) ); + break; + + case OP_STORE_V: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.vectorPtr = *var_a.vectorPtr; + break; + + case OP_STORE_FTOS: + var_a = GetVariable( st->a ); + SetString( st->b, FloatToString( *var_a.floatPtr ) ); + break; + + case OP_STORE_BTOS: + var_a = GetVariable( st->a ); + SetString( st->b, *var_a.intPtr ? "true" : "false" ); + break; + + case OP_STORE_VTOS: + var_a = GetVariable( st->a ); + SetString( st->b, var_a.vectorPtr->ToString() ); + break; + + case OP_STORE_FTOBOOL: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + if ( *var_a.floatPtr != 0.0f ) { + *var_b.intPtr = 1; + } else { + *var_b.intPtr = 0; + } + break; + + case OP_STORE_BOOLTOF: + var_a = GetVariable( st->a ); + var_b = GetVariable( st->b ); + *var_b.floatPtr = static_cast( *var_a.intPtr ); + break; + + case OP_STOREP_F: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->floatPtr = *var_a.floatPtr; + } + break; + + case OP_STOREP_ENT: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; + } + break; + + case OP_STOREP_FLD: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->intPtr = *var_a.intPtr; + } + break; + + case OP_STOREP_BOOL: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->intPtr = *var_a.intPtr; + } + break; + + case OP_STOREP_S: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { + idStr::Copynz( var_b.evalPtr->stringPtr, GetString( st->a ), MAX_STRING_LEN ); + } + break; + + case OP_STOREP_V: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->vectorPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->vectorPtr = *var_a.vectorPtr; + } + break; + + case OP_STOREP_FTOS: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { + var_a = GetVariable( st->a ); + idStr::Copynz( var_b.evalPtr->stringPtr, FloatToString( *var_a.floatPtr ), MAX_STRING_LEN ); + } + break; + + case OP_STOREP_BTOS: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { + var_a = GetVariable( st->a ); + if ( *var_a.floatPtr != 0.0f ) { + idStr::Copynz( var_b.evalPtr->stringPtr, "true", MAX_STRING_LEN ); + } else { + idStr::Copynz( var_b.evalPtr->stringPtr, "false", MAX_STRING_LEN ); + } + } + break; + + case OP_STOREP_VTOS: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { + var_a = GetVariable( st->a ); + idStr::Copynz( var_b.evalPtr->stringPtr, var_a.vectorPtr->ToString(), MAX_STRING_LEN ); + } + break; + + case OP_STOREP_FTOBOOL: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { + var_a = GetVariable( st->a ); + if ( *var_a.floatPtr != 0.0f ) { + *var_b.evalPtr->intPtr = 1; + } else { + *var_b.evalPtr->intPtr = 0; + } + } + break; + + case OP_STOREP_BOOLTOF: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->floatPtr = static_cast( *var_a.intPtr ); + } + break; + + case OP_STOREP_OBJ: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { + var_a = GetVariable( st->a ); + *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; + } + break; + + case OP_STOREP_OBJENT: + var_b = GetVariable( st->b ); + if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( !obj ) { + *var_b.evalPtr->entityNumberPtr = 0; + + // st->b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in st->c + // so that we can do a type check during run time since we don't know what type the script object is at compile time because it + // comes from an entity + } else if ( !obj->GetTypeDef()->Inherits( st->c->TypeDef() ) ) { + //Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->c->TypeDef()->Name() ); + *var_b.evalPtr->entityNumberPtr = 0; + } else { + *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; + } + } + break; + + case OP_ADDRESS: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var_c.evalPtr->bytePtr = &obj->data[ st->b->value.ptrOffset ]; + } else { + var_c.evalPtr->bytePtr = NULL; + } + break; + + case OP_INDIRECT_F: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + *var_c.floatPtr = *var.floatPtr; + } else { + *var_c.floatPtr = 0.0f; + } + break; + + case OP_INDIRECT_ENT: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + *var_c.entityNumberPtr = *var.entityNumberPtr; + } else { + *var_c.entityNumberPtr = 0; + } + break; + + case OP_INDIRECT_BOOL: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + *var_c.intPtr = *var.intPtr; + } else { + *var_c.intPtr = 0; + } + break; + + case OP_INDIRECT_S: + var_a = GetVariable( st->a ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + SetString( st->c, var.stringPtr ); + } else { + SetString( st->c, "" ); + } + break; + + case OP_INDIRECT_V: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( obj ) { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + *var_c.vectorPtr = *var.vectorPtr; + } else { + var_c.vectorPtr->Zero(); + } + break; + + case OP_INDIRECT_OBJ: + var_a = GetVariable( st->a ); + var_c = GetVariable( st->c ); + obj = GetScriptObject( *var_a.entityNumberPtr ); + if ( !obj ) { + *var_c.entityNumberPtr = 0; + } else { + var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; + *var_c.entityNumberPtr = *var.entityNumberPtr; + } + break; + + case OP_PUSH_F: + var_a = GetVariable( st->a ); + Push( *var_a.intPtr ); + break; + + case OP_PUSH_FTOS: + var_a = GetVariable( st->a ); + PushString( FloatToString( *var_a.floatPtr ) ); + break; + + case OP_PUSH_BTOF: + var_a = GetVariable( st->a ); + floatVal = *var_a.intPtr; + Push( *reinterpret_cast( &floatVal ) ); + break; + + case OP_PUSH_FTOB: + var_a = GetVariable( st->a ); + if ( *var_a.floatPtr != 0.0f ) { + Push( 1 ); + } else { + Push( 0 ); + } + break; + + case OP_PUSH_VTOS: + var_a = GetVariable( st->a ); + PushString( var_a.vectorPtr->ToString() ); + break; + + case OP_PUSH_BTOS: + var_a = GetVariable( st->a ); + PushString( *var_a.intPtr ? "true" : "false" ); + break; + + case OP_PUSH_ENT: + var_a = GetVariable( st->a ); + Push( *var_a.entityNumberPtr ); + break; + + case OP_PUSH_S: + PushString( GetString( st->a ) ); + break; + + case OP_PUSH_V: + var_a = GetVariable( st->a ); + Push( *reinterpret_cast( &var_a.vectorPtr->x ) ); + Push( *reinterpret_cast( &var_a.vectorPtr->y ) ); + Push( *reinterpret_cast( &var_a.vectorPtr->z ) ); + break; + + case OP_PUSH_OBJ: + var_a = GetVariable( st->a ); + Push( *var_a.entityNumberPtr ); + break; + + case OP_PUSH_OBJENT: + var_a = GetVariable( st->a ); + Push( *var_a.entityNumberPtr ); + break; + + case OP_BREAK: + case OP_CONTINUE: + default: + Error( "Bad opcode %i", st->op ); + break; + } + } + +#ifdef PROFILE_SCRIPT + if (debug && functionTimers.size() > 0) { + functionTimers.top().Stop(); + } +#endif + + return threadDying; +} + +bool idInterpreter::EnterFunctionVarArg(const function_t *func, bool clearStack, const char *fmt, ...) +{ + bool rc = false; + va_list argptr; + + va_start(argptr, fmt); + rc = EnterFunctionVarArgVN(func, clearStack, fmt, argptr); + va_end(argptr); + + return rc; +} + +bool idInterpreter::EnterFunctionVarArgVN(const function_t *func, bool clearStack, const char *fmt, va_list args) +{ + bool rc = false; + char c; + int i; + float f; + idEntity *e; + idVec3 *v; + + if(func == NULL) + goto Quit; + + if(clearStack) + Reset(); + + while((c = *fmt) != 0) + { + switch(c) + { + case 'e': + e = va_arg(args, idEntity *); + // SZ: Allow pushing of null entity pointers (entity ID 0) + if (e != NULL) + { + Push(e->entityNumber + 1); + } + else + { + Push (0); + } + break; + + case 'v': + v = va_arg(args, idVec3 *); + Push(*reinterpret_cast(&v->x)); + Push(*reinterpret_cast(&v->y)); + Push(*reinterpret_cast(&v->z)); + break; + + case 's': + PushString(va_arg(args, char *)); + break; + + case 'f': + f = va_arg(args, double); + // i = static_cast(f); + i = *( (int*) &f); + Push(i); + break; + + case 'd': + i = va_arg(args, int); + Push(i); + break; + + case 'b': + i = va_arg(args, int); + Push(i); + break; + + default: // Unknown argument, so we clear the stack and exit + Reset(); + goto Quit; + } + fmt++; + } + + EnterFunction(func, false); + + rc = true; + +Quit: + return rc; +} + diff --git a/game/script/Script_Interpreter.h b/game/script/Script_Interpreter.h new file mode 100644 index 000000000..8acbfed4a --- /dev/null +++ b/game/script/Script_Interpreter.h @@ -0,0 +1,284 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SCRIPT_INTERPRETER_H__ +#define __SCRIPT_INTERPRETER_H__ + +#ifdef PROFILE_SCRIPT +#include +#endif + +#define MAX_STACK_DEPTH 64 +#define LOCALSTACK_SIZE 6144 + +typedef struct prstack_s { + int s; + const function_t *f; + int stackbase; +} prstack_t; + +class idInterpreter { +private: + prstack_t callStack[ MAX_STACK_DEPTH ]; + int callStackDepth; + int maxStackDepth; + + byte localstack[ LOCALSTACK_SIZE ]; + int localstackUsed; + int localstackBase; + int maxLocalstackUsed; + + const function_t *currentFunction; + int instructionPointer; + + int popParms; + const idEventDef *multiFrameEvent; + idEntity *eventEntity; + + idThread *thread; + +#ifdef PROFILE_SCRIPT + typedef std::stack TimerStack; + TimerStack functionTimers; +#endif + + void PopParms( int numParms ); + void PushString( const char *string ); + void Push( int value ); + const char *FloatToString( float value ); + void AppendString( idVarDef *def, const char *from ); + void SetString( idVarDef *def, const char *from ); + const char *GetString( idVarDef *def ); + varEval_t GetVariable( idVarDef *def ); + idEntity *GetEntity( int entnum ) const; + idScriptObject *GetScriptObject( int entnum ) const; + void NextInstruction( int position ); + + void LeaveFunction( idVarDef *returnDef ); + void CallEvent( const function_t *func, int argsize ); + void CallSysEvent( const function_t *func, int argsize ); + +public: + bool doneProcessing; + bool threadDying; + bool terminateOnExit; + bool debug; + + idInterpreter(); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void SetThread( idThread *pThread ); + + void StackTrace( void ) const; + + int CurrentLine( void ) const; + const char *CurrentFile( void ) const; + + void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + void DisplayInfo( void ) const; + + bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ); + void EndMultiFrameEvent( idEntity *ent, const idEventDef *event ); + bool MultiFrameEventInProgress( void ) const; + + void ThreadCall( idInterpreter *source, const function_t *func, int args ); + void EnterFunction( const function_t *func, bool clearStack ); + void EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack ); + + /** + * EnterVarArgFunction runs a script function, but allows to pass parameters to the script. + * The format string specifies which parameters are passed and in which order. The parameters + * are the same as used in event.h. + * e = entity + * s = string (char *) + * f = float + * v = vector + * b = boolean + */ + bool EnterFunctionVarArgVN(const function_t *func, bool clearStack, const char *fmt, va_list args); + bool EnterFunctionVarArg(const function_t *func, bool clearStack, const char *fmt, ...); + + bool Execute( void ); + void Reset( void ); + + bool GetRegisterValue( const char *name, idStr &out, int scopeDepth ); + int GetCallstackDepth( void ) const; + const prstack_t *GetCallstack( void ) const; + const function_t *GetCurrentFunction( void ) const; + idThread *GetThread( void ) const; + +}; + +/* +==================== +idInterpreter::PopParms +==================== +*/ +ID_INLINE void idInterpreter::PopParms( int numParms ) { + // pop our parms off the stack + if ( localstackUsed < numParms ) { + Error( "locals stack underflow\n" ); + } + + localstackUsed -= numParms; +} + +/* +==================== +idInterpreter::Push +==================== +*/ +ID_INLINE void idInterpreter::Push( int value ) { + if ( localstackUsed + sizeof( int ) > LOCALSTACK_SIZE ) { + Error( "Push: locals stack overflow\n" ); + } + *( int * )&localstack[ localstackUsed ] = value; + localstackUsed += sizeof( int ); +} + +/* +==================== +idInterpreter::PushString +==================== +*/ +ID_INLINE void idInterpreter::PushString( const char *string ) { + if ( localstackUsed + MAX_STRING_LEN > LOCALSTACK_SIZE ) { + Error( "PushString: locals stack overflow\n" ); + } + idStr::Copynz( ( char * )&localstack[ localstackUsed ], string, MAX_STRING_LEN ); + localstackUsed += MAX_STRING_LEN; +} + +/* +==================== +idInterpreter::FloatToString +==================== +*/ +ID_INLINE const char *idInterpreter::FloatToString( float value ) { + static char text[ 32 ]; + + if ( value == ( float )( int )value ) { + sprintf( text, "%d", ( int )value ); + } else { + sprintf( text, "%f", value ); + } + return text; +} + +/* +==================== +idInterpreter::AppendString +==================== +*/ +ID_INLINE void idInterpreter::AppendString( idVarDef *def, const char *from ) { + if ( def->initialized == idVarDef::stackVariable ) { + idStr::Append( ( char * )&localstack[ localstackBase + def->value.stackOffset ], MAX_STRING_LEN, from ); + } else { + idStr::Append( def->value.stringPtr, MAX_STRING_LEN, from ); + } +} + +/* +==================== +idInterpreter::SetString +==================== +*/ +ID_INLINE void idInterpreter::SetString( idVarDef *def, const char *from ) { + if ( def->initialized == idVarDef::stackVariable ) { + idStr::Copynz( ( char * )&localstack[ localstackBase + def->value.stackOffset ], from, MAX_STRING_LEN ); + } else { + idStr::Copynz( def->value.stringPtr, from, MAX_STRING_LEN ); + } +} + +/* +==================== +idInterpreter::GetString +==================== +*/ +ID_INLINE const char *idInterpreter::GetString( idVarDef *def ) { + if ( def->initialized == idVarDef::stackVariable ) { + return ( char * )&localstack[ localstackBase + def->value.stackOffset ]; + } else { + return def->value.stringPtr; + } +} + +/* +==================== +idInterpreter::GetVariable +==================== +*/ +ID_INLINE varEval_t idInterpreter::GetVariable( idVarDef *def ) { + if ( def->initialized == idVarDef::stackVariable ) { + varEval_t val; + val.intPtr = ( int * )&localstack[ localstackBase + def->value.stackOffset ]; + return val; + } else { + return def->value; + } +} + +/* +================ +idInterpreter::GetEntity +================ +*/ +ID_INLINE idEntity *idInterpreter::GetEntity( int entnum ) const{ + assert( entnum <= MAX_GENTITIES ); + if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) { + return gameLocal.entities[ entnum - 1 ]; + } + return NULL; +} + +/* +================ +idInterpreter::GetScriptObject +================ +*/ +ID_INLINE idScriptObject *idInterpreter::GetScriptObject( int entnum ) const { + idEntity *ent; + + assert( entnum <= MAX_GENTITIES ); + if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) { + ent = gameLocal.entities[ entnum - 1 ]; + if ( ent && ent->scriptObject.data ) { + return &ent->scriptObject; + } + } + return NULL; +} + +/* +==================== +idInterpreter::NextInstruction +==================== +*/ +ID_INLINE void idInterpreter::NextInstruction( int position ) { + // Before we execute an instruction, we increment instructionPointer, + // therefore we need to compensate for that here. + instructionPointer = position - 1; +} + +#endif /* !__SCRIPT_INTERPRETER_H__ */ diff --git a/game/script/Script_Program.cpp b/game/script/Script_Program.cpp new file mode 100644 index 000000000..a8774961d --- /dev/null +++ b/game/script/Script_Program.cpp @@ -0,0 +1,2139 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" + +// simple types. function types are dynamically allocated +idTypeDef type_void( ev_void, &def_void, "void", 0, NULL ); +idTypeDef type_scriptevent( ev_scriptevent, &def_scriptevent, "scriptevent", sizeof( void * ), NULL ); +idTypeDef type_namespace( ev_namespace, &def_namespace, "namespace", sizeof( void * ), NULL ); +idTypeDef type_string( ev_string, &def_string, "string", MAX_STRING_LEN, NULL ); +idTypeDef type_float( ev_float, &def_float, "float", sizeof( float ), NULL ); +idTypeDef type_vector( ev_vector, &def_vector, "vector", sizeof( idVec3 ), NULL ); +idTypeDef type_entity( ev_entity, &def_entity, "entity", sizeof( int * ), NULL ); // stored as entity number pointer +idTypeDef type_field( ev_field, &def_field, "field", sizeof( void * ), NULL ); +idTypeDef type_function( ev_function, &def_function, "function", sizeof( void * ), &type_void ); +idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof( int ), NULL ); +idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof( void * ), NULL ); +idTypeDef type_object( ev_object, &def_object, "object", sizeof( int * ), NULL ); // stored as entity number pointer +idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "", sizeof( int ), NULL ); // only used for jump opcodes +idTypeDef type_argsize( ev_argsize, &def_argsize, "", sizeof( int ), NULL ); // only used for function call and thread opcodes +idTypeDef type_boolean( ev_boolean, &def_boolean, "boolean", sizeof( int ), NULL ); + +idVarDef def_void( &type_void ); +idVarDef def_scriptevent( &type_scriptevent ); +idVarDef def_namespace( &type_namespace ); +idVarDef def_string( &type_string ); +idVarDef def_float( &type_float ); +idVarDef def_vector( &type_vector ); +idVarDef def_entity( &type_entity ); +idVarDef def_field( &type_field ); +idVarDef def_function( &type_function ); +idVarDef def_virtualfunction( &type_virtualfunction ); +idVarDef def_pointer( &type_pointer ); +idVarDef def_object( &type_object ); +idVarDef def_jumpoffset( &type_jumpoffset ); // only used for jump opcodes +idVarDef def_argsize( &type_argsize ); +idVarDef def_boolean( &type_boolean ); + +/*********************************************************************** + + function_t + +***********************************************************************/ + +/* +================ +function_t::function_t +================ +*/ +function_t::function_t() { + Clear(); +} + +/* +================ +function_t::Allocated +================ +*/ +size_t function_t::Allocated( void ) const { + return name.Allocated() + parmSize.Allocated(); +} + +/* +================ +function_t::SetName +================ +*/ +void function_t::SetName( const char *name ) { + this->name = name; +} + +/* +================ +function_t::Name +================ +*/ +const char *function_t::Name( void ) const { + return name; +} + +/* +================ +function_t::Clear +================ +*/ +void function_t::Clear( void ) { + eventdef = NULL; + def = NULL; + type = NULL; + firstStatement = 0; + numStatements = 0; + parmTotal = 0; + locals = 0; + filenum = 0; + name.Clear(); + parmSize.Clear(); +} + +/*********************************************************************** + + idTypeDef + +***********************************************************************/ + +/* +================ +idTypeDef::idTypeDef +================ +*/ +idTypeDef::idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) { + name = ename; + type = etype; + def = edef; + size = esize; + auxType = aux; + + parmTypes.SetGranularity( 1 ); + parmNames.SetGranularity( 1 ); + functions.SetGranularity( 1 ); +} + +/* +================ +idTypeDef::idTypeDef +================ +*/ +idTypeDef::idTypeDef( const idTypeDef &other ) { + *this = other; +} + +/* +================ +idTypeDef::operator= +================ +*/ +void idTypeDef::operator=( const idTypeDef& other ) { + type = other.type; + def = other.def; + name = other.name; + size = other.size; + auxType = other.auxType; + parmTypes = other.parmTypes; + parmNames = other.parmNames; + functions = other.functions; +} + +/* +================ +idTypeDef::Allocated +================ +*/ +size_t idTypeDef::Allocated( void ) const { + size_t memsize; + int i; + + memsize = name.Allocated() + parmTypes.Allocated() + parmNames.Allocated() + functions.Allocated(); + for( i = 0; i < parmTypes.Num(); i++ ) { + memsize += parmNames[ i ].Allocated(); + } + + return memsize; +} + +/* +================ +idTypeDef::Inherits + +Returns true if basetype is an ancestor of this type. +================ +*/ +bool idTypeDef::Inherits( const idTypeDef *basetype ) const { + idTypeDef *superType; + + if ( type != ev_object ) { + return false; + } + + if ( this == basetype ) { + return true; + } + for( superType = auxType; superType != NULL; superType = superType->auxType ) { + if ( superType == basetype ) { + return true; + } + } + + return false; +} + +/* +================ +idTypeDef::MatchesType + +Returns true if both types' base types and parameters match +================ +*/ +bool idTypeDef::MatchesType( const idTypeDef &matchtype ) const { + int i; + + if ( this == &matchtype ) { + return true; + } + + if ( ( type != matchtype.type ) || ( auxType != matchtype.auxType ) ) { + return false; + } + + if ( parmTypes.Num() != matchtype.parmTypes.Num() ) { + return false; + } + + for( i = 0; i < matchtype.parmTypes.Num(); i++ ) { + if ( parmTypes[ i ] != matchtype.parmTypes[ i ] ) { + return false; + } + } + + return true; +} + +/* +================ +idTypeDef::MatchesVirtualFunction + +Returns true if both functions' base types and parameters match +================ +*/ +bool idTypeDef::MatchesVirtualFunction( const idTypeDef &matchfunc ) const { + int i; + + if ( this == &matchfunc ) { + return true; + } + + if ( ( type != matchfunc.type ) || ( auxType != matchfunc.auxType ) ) { + return false; + } + + if ( parmTypes.Num() != matchfunc.parmTypes.Num() ) { + return false; + } + + if ( parmTypes.Num() > 0 ) { + if ( !parmTypes[ 0 ]->Inherits( matchfunc.parmTypes[ 0 ] ) ) { + return false; + } + } + + for( i = 1; i < matchfunc.parmTypes.Num(); i++ ) { + if ( parmTypes[ i ] != matchfunc.parmTypes[ i ] ) { + return false; + } + } + + return true; +} + +/* +================ +idTypeDef::AddFunctionParm + +Adds a new parameter for a function type. +================ +*/ +void idTypeDef::AddFunctionParm( idTypeDef *parmtype, const char *name ) { + if ( type != ev_function ) { + throw idCompileError( "idTypeDef::AddFunctionParm : tried to add parameter on non-function type" ); + } + + parmTypes.Append( parmtype ); + idStr &parmName = parmNames.Alloc(); + parmName = name; +} + +/* +================ +idTypeDef::AddField + +Adds a new field to an object type. +================ +*/ +void idTypeDef::AddField( idTypeDef *fieldtype, const char *name ) { + if ( type != ev_object ) { + throw idCompileError( "idTypeDef::AddField : tried to add field to non-object type" ); + } + + parmTypes.Append( fieldtype ); + idStr &parmName = parmNames.Alloc(); + parmName = name; + + if ( fieldtype->FieldType()->Inherits( &type_object ) ) { + size += type_object.Size(); + } else { + size += fieldtype->FieldType()->Size(); + } +} + +/* +================ +idTypeDef::SetName +================ +*/ +void idTypeDef::SetName( const char *newname ) { + name = newname; +} + +/* +================ +idTypeDef::Name +================ +*/ +const char *idTypeDef::Name( void ) const { + return name; +} + +/* +================ +idTypeDef::Type +================ +*/ +etype_t idTypeDef::Type( void ) const { + return type; +} + +/* +================ +idTypeDef::Size +================ +*/ +int idTypeDef::Size( void ) const { + return size; +} + +/* +================ +idTypeDef::SuperClass + +If type is an object, then returns the object's superclass +================ +*/ +idTypeDef *idTypeDef::SuperClass( void ) const { + if ( type != ev_object ) { + throw idCompileError( "idTypeDef::SuperClass : tried to get superclass of a non-object type" ); + } + + return auxType; +} + +/* +================ +idTypeDef::ReturnType + +If type is a function, then returns the function's return type +================ +*/ +idTypeDef *idTypeDef::ReturnType( void ) const { + if ( type != ev_function ) { + throw idCompileError( "idTypeDef::ReturnType: tried to get return type on non-function type" ); + } + + return auxType; +} + +/* +================ +idTypeDef::SetReturnType + +If type is a function, then sets the function's return type +================ +*/ +void idTypeDef::SetReturnType( idTypeDef *returntype ) { + if ( type != ev_function ) { + throw idCompileError( "idTypeDef::SetReturnType: tried to set return type on non-function type" ); + } + + auxType = returntype; +} + +/* +================ +idTypeDef::FieldType + +If type is a field, then returns it's type +================ +*/ +idTypeDef *idTypeDef::FieldType( void ) const { + if ( type != ev_field ) { + throw idCompileError( "idTypeDef::FieldType: tried to get field type on non-field type" ); + } + + return auxType; +} + +/* +================ +idTypeDef::SetFieldType + +If type is a field, then sets the function's return type +================ +*/ +void idTypeDef::SetFieldType( idTypeDef *fieldtype ) { + if ( type != ev_field ) { + throw idCompileError( "idTypeDef::SetFieldType: tried to set return type on non-function type" ); + } + + auxType = fieldtype; +} + +/* +================ +idTypeDef::PointerType + +If type is a pointer, then returns the type it points to +================ +*/ +idTypeDef *idTypeDef::PointerType( void ) const { + if ( type != ev_pointer ) { + throw idCompileError( "idTypeDef::PointerType: tried to get pointer type on non-pointer" ); + } + + return auxType; +} + +/* +================ +idTypeDef::SetPointerType + +If type is a pointer, then sets the pointer's type +================ +*/ +void idTypeDef::SetPointerType( idTypeDef *pointertype ) { + if ( type != ev_pointer ) { + throw idCompileError( "idTypeDef::SetPointerType: tried to set type on non-pointer" ); + } + + auxType = pointertype; +} + +/* +================ +idTypeDef::NumParameters +================ +*/ +int idTypeDef::NumParameters( void ) const { + return parmTypes.Num(); +} + +/* +================ +idTypeDef::GetParmType +================ +*/ +idTypeDef *idTypeDef::GetParmType( int parmNumber ) const { + assert( parmNumber >= 0 ); + assert( parmNumber < parmTypes.Num() ); + return parmTypes[ parmNumber ]; +} + +/* +================ +idTypeDef::GetParmName +================ +*/ +const char *idTypeDef::GetParmName( int parmNumber ) const { + assert( parmNumber >= 0 ); + assert( parmNumber < parmTypes.Num() ); + return parmNames[ parmNumber ]; +} + +/* +================ +idTypeDef::NumFunctions +================ +*/ +int idTypeDef::NumFunctions( void ) const { + return functions.Num(); +} + +/* +================ +idTypeDef::GetFunctionNumber +================ +*/ +int idTypeDef::GetFunctionNumber( const function_t *func ) const { + int i; + + for( i = 0; i < functions.Num(); i++ ) { + if ( functions[ i ] == func ) { + return i; + } + } + return -1; +} + +/* +================ +idTypeDef::GetFunction +================ +*/ +const function_t *idTypeDef::GetFunction( int funcNumber ) const { + assert( funcNumber >= 0 ); + assert( funcNumber < functions.Num() ); + return functions[ funcNumber ]; +} + +/* +================ +idTypeDef::AddFunction +================ +*/ +void idTypeDef::AddFunction( const function_t *func ) { + int i; + + for( i = 0; i < functions.Num(); i++ ) { + if ( !strcmp( functions[ i ]->def->Name(), func->def->Name() ) ) { + if ( func->def->TypeDef()->MatchesVirtualFunction( *functions[ i ]->def->TypeDef() ) ) { + functions[ i ] = func; + return; + } + } + } + functions.Append( func ); +} + +/*********************************************************************** + + idVarDef + +***********************************************************************/ + +/* +================ +idVarDef::idVarDef() +================ +*/ +idVarDef::idVarDef( idTypeDef *typeptr ) { + typeDef = typeptr; + num = 0; + scope = NULL; + numUsers = 0; + initialized = idVarDef::uninitialized; + memset( &value, 0, sizeof( value ) ); + name = NULL; + next = NULL; +} + +/* +============ +idVarDef::~idVarDef +============ +*/ +idVarDef::~idVarDef() { + if ( name ) { + name->RemoveDef( this ); + } +} + +/* +============ +idVarDef::Name +============ +*/ +const char *idVarDef::Name( void ) const { + return name->Name(); +} + +/* +============ +idVarDef::GlobalName +============ +*/ +const char *idVarDef::GlobalName( void ) const { + if ( scope != &def_namespace ) { + return va( "%s::%s", scope->GlobalName(), name->Name() ); + } else { + return name->Name(); + } +} + +/* +============ +idVarDef::DepthOfScope +============ +*/ +int idVarDef::DepthOfScope( const idVarDef *otherScope ) const { + const idVarDef *def; + int depth; + + depth = 1; + for( def = otherScope; def != NULL; def = def->scope ) { + if ( def == scope ) { + return depth; + } + depth++; + } + + return 0; +} + +/* +============ +idVarDef::SetFunction +============ +*/ +void idVarDef::SetFunction( function_t *func ) { + assert( typeDef ); + initialized = initializedConstant; + assert( typeDef->Type() == ev_function ); + value.functionPtr = func; +} + +/* +============ +idVarDef::SetObject +============ +*/ +void idVarDef::SetObject( idScriptObject *object ) { + assert( typeDef ); + initialized = initialized; + assert( typeDef->Inherits( &type_object ) ); + *value.objectPtrPtr = object; +} + +/* +============ +idVarDef::SetValue +============ +*/ +void idVarDef::SetValue( const eval_t &_value, bool constant ) { + assert( typeDef ); + if ( constant ) { + initialized = initializedConstant; + } else { + initialized = initializedVariable; + } + + switch( typeDef->Type() ) { + case ev_pointer : + case ev_boolean : + case ev_field : + *value.intPtr = _value._int; + break; + + case ev_jumpoffset : + value.jumpOffset = _value._int; + break; + + case ev_argsize : + value.argSize = _value._int; + break; + + case ev_entity : + *value.entityNumberPtr = _value.entity; + break; + + case ev_string : + idStr::Copynz( value.stringPtr, _value.stringPtr, MAX_STRING_LEN ); + break; + + case ev_float : + *value.floatPtr = _value._float; + break; + + case ev_vector : + value.vectorPtr->x = _value.vector[ 0 ]; + value.vectorPtr->y = _value.vector[ 1 ]; + value.vectorPtr->z = _value.vector[ 2 ]; + break; + + case ev_function : + value.functionPtr = _value.function; + break; + + case ev_virtualfunction : + value.virtualFunction = _value._int; + break; + + case ev_object : + *value.entityNumberPtr = _value.entity; + break; + + default : + throw idCompileError( va( "weird type on '%s'", Name() ) ); + break; + } +} + +/* +============ +idVarDef::SetString +============ +*/ +void idVarDef::SetString( const char *string, bool constant ) { + if ( constant ) { + initialized = initializedConstant; + } else { + initialized = initializedVariable; + } + + assert( typeDef && ( typeDef->Type() == ev_string ) ); + idStr::Copynz( value.stringPtr, string, MAX_STRING_LEN ); +} + +/* +============ +idVarDef::PrintInfo +============ +*/ +void idVarDef::PrintInfo( idFile *file, int instructionPointer ) const { + statement_t *jumpst; + int jumpto; + etype_t etype; + int i; + int len; + const char *ch; + + if ( initialized == initializedConstant ) { + file->Printf( "const " ); + } + + etype = typeDef->Type(); + switch( etype ) { + case ev_jumpoffset : + jumpto = instructionPointer + value.jumpOffset; + jumpst = &gameLocal.program.GetStatement( jumpto ); + file->Printf( "address %d [%s(%d)]", jumpto, gameLocal.program.GetFilename( jumpst->file ), jumpst->linenumber ); + break; + + case ev_function : + if ( value.functionPtr->eventdef ) { + file->Printf( "event %s", GlobalName() ); + } else { + file->Printf( "function %s", GlobalName() ); + } + break; + + case ev_field : + file->Printf( "field %d", value.ptrOffset ); + break; + + case ev_argsize: + file->Printf( "args %d", value.argSize ); + break; + + default: + file->Printf( "%s ", typeDef->Name() ); + if ( initialized == initializedConstant ) { + switch( etype ) { + case ev_string : + file->Printf( "\"" ); + len = strlen( value.stringPtr ); + ch = value.stringPtr; + for( i = 0; i < len; i++, ch++ ) { + if ( idStr::CharIsPrintable( *ch ) ) { + file->Printf( "%c", *ch ); + } else if ( *ch == '\n' ) { + file->Printf( "\\n" ); + } else { + file->Printf( "\\x%.2x", static_cast( *ch ) ); + } + } + file->Printf( "\"" ); + break; + + case ev_vector : + file->Printf( "'%s'", value.vectorPtr->ToString() ); + break; + + case ev_float : + file->Printf( "%f", *value.floatPtr ); + break; + + case ev_virtualfunction : + file->Printf( "vtable[ %d ]", value.virtualFunction ); + break; + + default : + file->Printf( "%d", *value.intPtr ); + break; + } + } else if ( initialized == stackVariable ) { + file->Printf( "stack[%d]", value.stackOffset ); + } else { + file->Printf( "global[%d]", num ); + } + break; + } +} + +/*********************************************************************** + + idVarDef + +***********************************************************************/ + +/* +============ +idVarDefName::AddDef +============ +*/ +void idVarDefName::AddDef( idVarDef *def ) { + assert( def->next == NULL ); + def->name = this; + def->next = defs; + defs = def; +} + +/* +============ +idVarDefName::RemoveDef +============ +*/ +void idVarDefName::RemoveDef( idVarDef *def ) { + if ( defs == def ) { + defs = def->next; + } else { + for ( idVarDef *d = defs; d->next != NULL; d = d->next ) { + if ( d->next == def ) { + d->next = def->next; + break; + } + } + } + def->next = NULL; + def->name = NULL; +} + +/*********************************************************************** + + idScriptObject + +***********************************************************************/ + +/* +============ +idScriptObject::idScriptObject +============ +*/ +idScriptObject::idScriptObject() { + data = NULL; + type = &type_object; +} + +/* +============ +idScriptObject::~idScriptObject +============ +*/ +idScriptObject::~idScriptObject() { + Free(); +} + +/* +============ +idScriptObject::Free +============ +*/ +void idScriptObject::Free( void ) { + if ( data ) { + Mem_Free( data ); + } + + data = NULL; + type = &type_object; +} + +/* +================ +idScriptObject::Save +================ +*/ +void idScriptObject::Save( idSaveGame *savefile ) const { + size_t size; + + if ( type == &type_object && data == NULL ) { + // Write empty string for uninitialized object + savefile->WriteString( "" ); + } else { + savefile->WriteString( type->Name() ); + size = type->Size(); + savefile->WriteInt( size ); + savefile->Write( data, size ); + } +} + +/* +================ +idScriptObject::Restore +================ +*/ +void idScriptObject::Restore( idRestoreGame *savefile ) { + idStr typeName; + int size; + + savefile->ReadString( typeName ); + + // Empty string signals uninitialized object + if ( typeName.Length() == 0 ) { + return; + } + + if ( !SetType( typeName ) ) { + savefile->Error( "idScriptObject::Restore: failed to restore object of type '%s'.", typeName.c_str() ); + } + + savefile->ReadInt( (int &)size ); + if ( size != type->Size() ) { + savefile->Error( "idScriptObject::Restore: size of object '%s' doesn't match size in save game.", typeName.c_str() ); + } + + savefile->Read( data, size ); +} + +/* +============ +idScriptObject::SetType + +Allocates an object and initializes memory. +============ +*/ +bool idScriptObject::SetType( const char *typeName ) { + size_t size; + idTypeDef *newtype; + + // lookup the type + newtype = gameLocal.program.FindType( typeName ); + + // only allocate memory if the object type changes + if ( newtype != type ) { + Free(); + if ( !newtype ) { + gameLocal.Warning( "idScriptObject::SetType: Unknown type '%s'", typeName ); + return false; + } + + if ( !newtype->Inherits( &type_object ) ) { + gameLocal.Warning( "idScriptObject::SetType: Can't create object of type '%s'. Must be an object type.", newtype->Name() ); + return false; + } + + // set the type + type = newtype; + + // allocate the memory + size = type->Size(); + data = ( byte * )Mem_Alloc( size ); + } + + // init object memory + ClearObject(); + + return true; +} + +/* +============ +idScriptObject::ClearObject + +Resets the memory for the script object without changing its type. +============ +*/ +void idScriptObject::ClearObject( void ) { + size_t size; + + if ( type != &type_object ) { + // init object memory + size = type->Size(); + memset( data, 0, size ); + } +} + +/* +============ +idScriptObject::HasObject +============ +*/ +bool idScriptObject::HasObject( void ) const { + return ( type != &type_object ); +} + +/* +============ +idScriptObject::GetTypeDef +============ +*/ +idTypeDef *idScriptObject::GetTypeDef( void ) const { + return type; +} + +/* +============ +idScriptObject::GetTypeName +============ +*/ +const char *idScriptObject::GetTypeName( void ) const { + return type->Name(); +} + +/* +============ +idScriptObject::GetConstructor +============ +*/ +const function_t *idScriptObject::GetConstructor( void ) const { + const function_t *func; + + func = GetFunction( "init" ); + return func; +} + +/* +============ +idScriptObject::GetDestructor +============ +*/ +const function_t *idScriptObject::GetDestructor( void ) const { + const function_t *func; + + func = GetFunction( "destroy" ); + return func; +} + +/* +============ +idScriptObject::GetFunction +============ +*/ +const function_t *idScriptObject::GetFunction( const char *name ) const { + const function_t *func; + + if ( type == &type_object ) { + return NULL; + } + + func = gameLocal.program.FindFunction( name, type ); + return func; +} + +/* +============ +idScriptObject::GetVariable +============ +*/ +byte *idScriptObject::GetVariable( const char *name, etype_t etype ) const { + int i; + int pos; + const idTypeDef *t; + const idTypeDef *parm; + + if ( type == &type_object ) { + return NULL; + } + + t = type; + do { + if ( t->SuperClass() != &type_object ) { + pos = t->SuperClass()->Size(); + } else { + pos = 0; + } + for( i = 0; i < t->NumParameters(); i++ ) { + parm = t->GetParmType( i ); + if ( !strcmp( t->GetParmName( i ), name ) ) { + if ( etype != parm->FieldType()->Type() ) { + return NULL; + } + return &data[ pos ]; + } + + if ( parm->FieldType()->Inherits( &type_object ) ) { + pos += type_object.Size(); + } else { + pos += parm->FieldType()->Size(); + } + } + t = t->SuperClass(); + } while( t && ( t != &type_object ) ); + + return NULL; +} + +/*********************************************************************** + + idProgram + +***********************************************************************/ + +/* +============ +idProgram::AllocType +============ +*/ +idTypeDef *idProgram::AllocType( idTypeDef &type ) { + idTypeDef *newtype; + + newtype = new idTypeDef( type ); + types.Append( newtype ); + + return newtype; +} + +/* +============ +idProgram::AllocType +============ +*/ +idTypeDef *idProgram::AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) { + idTypeDef *newtype; + + newtype = new idTypeDef( etype, edef, ename, esize, aux ); + types.Append( newtype ); + + return newtype; +} + +/* +============ +idProgram::GetType + +Returns a preexisting complex type that matches the parm, or allocates +a new one and copies it out. +============ +*/ +idTypeDef *idProgram::GetType( idTypeDef &type, bool allocate ) { + int i; + + //FIXME: linear search == slow + for( i = types.Num() - 1; i >= 0; i-- ) { + if ( types[ i ]->MatchesType( type ) && !strcmp( types[ i ]->Name(), type.Name() ) ) { + return types[ i ]; + } + } + + if ( !allocate ) { + return NULL; + } + + // allocate a new one + return AllocType( type ); +} + +/* +============ +idProgram::FindType + +Returns a preexisting complex type that matches the name, or returns NULL if not found +============ +*/ +idTypeDef *idProgram::FindType( const char *name ) { + idTypeDef *check; + int i; + + for( i = types.Num() - 1; i >= 0; i-- ) { + check = types[ i ]; + if ( !strcmp( check->Name(), name ) ) { + return check; + } + } + + return NULL; +} + +/* +============ +idProgram::GetDefList +============ +*/ +idVarDef *idProgram::GetDefList( const char *name ) const { + int i, hash; + + hash = varDefNameHash.GenerateKey( name, true ); + for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) { + if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) { + return varDefNames[i]->GetDefs(); + } + } + return NULL; +} + +/* +============ +idProgram::AddDefToNameList +============ +*/ +void idProgram::AddDefToNameList( idVarDef *def, const char *name ) { + int i, hash; + + hash = varDefNameHash.GenerateKey( name, true ); + for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) { + if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) { + break; + } + } + if ( i == -1 ) { + i = varDefNames.Append( new idVarDefName( name ) ); + varDefNameHash.Add( hash, i ); + } + varDefNames[i]->AddDef( def ); +} + +/* +============ +idProgram::AllocDef +============ +*/ +idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ) { + idVarDef *def; + idStr element; + idVarDef *def_x; + idVarDef *def_y; + idVarDef *def_z; + + // allocate a new def + def = new idVarDef( type ); + def->scope = scope; + def->numUsers = 1; + def->num = varDefs.Append( def ); + + // add the def to the list with defs with this name and set the name pointer + AddDefToNameList( def, name ); + + if ( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) ) { + // + // vector + // + if ( !strcmp( name, RESULT_STRING ) ) { + // vector defs don't need the _x, _y and _z components + assert( scope->Type() == ev_function ); + def->value.stackOffset = scope->value.functionPtr->locals; + def->initialized = idVarDef::stackVariable; + scope->value.functionPtr->locals += type->Size(); + } else if ( scope->TypeDef()->Inherits( &type_object ) ) { + idTypeDef newtype( ev_field, NULL, "float field", 0, &type_float ); + idTypeDef *type = GetType( newtype, true ); + + // set the value to the variable's position in the object + def->value.ptrOffset = scope->TypeDef()->Size(); + + // make automatic defs for the vectors elements + // origin can be accessed as origin_x, origin_y, and origin_z + sprintf( element, "%s_x", def->Name() ); + def_x = AllocDef( type, element, scope, constant ); + + sprintf( element, "%s_y", def->Name() ); + def_y = AllocDef( type, element, scope, constant ); + def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size(); + + sprintf( element, "%s_z", def->Name() ); + def_z = AllocDef( type, element, scope, constant ); + def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size(); + } else { + // make automatic defs for the vectors elements + // origin can be accessed as origin_x, origin_y, and origin_z + sprintf( element, "%s_x", def->Name() ); + def_x = AllocDef( &type_float, element, scope, constant ); + + sprintf( element, "%s_y", def->Name() ); + def_y = AllocDef( &type_float, element, scope, constant ); + + sprintf( element, "%s_z", def->Name() ); + def_z = AllocDef( &type_float, element, scope, constant ); + + // point the vector def to the x coordinate + def->value = def_x->value; + def->initialized = def_x->initialized; + } + } else if ( scope->TypeDef()->Inherits( &type_object ) ) { + // + // object variable + // + // set the value to the variable's position in the object + def->value.ptrOffset = scope->TypeDef()->Size(); + } else if ( scope->Type() == ev_function ) { + // + // stack variable + // + // since we don't know how many local variables there are, + // we have to have them go backwards on the stack + def->value.stackOffset = scope->value.functionPtr->locals; + def->initialized = idVarDef::stackVariable; + + if ( type->Inherits( &type_object ) ) { + // objects only have their entity number on the stack, not the entire object + scope->value.functionPtr->locals += type_object.Size(); + } else { + scope->value.functionPtr->locals += type->Size(); + } + } else { + // + // global variable + // + def->value.bytePtr = &variables[ numVariables ]; + numVariables += def->TypeDef()->Size(); + if ( numVariables > sizeof( variables ) ) { + throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) ); + } + + memset( def->value.bytePtr, 0, def->TypeDef()->Size() ); + } + + return def; +} + +/* +============ +idProgram::GetDef + +If type is NULL, it will match any type +============ +*/ +idVarDef *idProgram::GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const { + idVarDef *def; + idVarDef *bestDef; + int bestDepth; + int depth; + + bestDepth = 0; + bestDef = NULL; + for( def = GetDefList( name ); def != NULL; def = def->Next() ) { + if ( def->scope->Type() == ev_namespace ) { + depth = def->DepthOfScope( scope ); + if ( !depth ) { + // not in the same namespace + continue; + } + } else if ( def->scope != scope ) { + // in a different function + continue; + } else { + depth = 1; + } + + if ( !bestDef || ( depth < bestDepth ) ) { + bestDepth = depth; + bestDef = def; + } + } + + // see if the name is already in use for another type + if ( bestDef && type && ( bestDef->TypeDef() != type ) ) { + throw idCompileError( va( "Type mismatch on redeclaration of %s", name ) ); + } + + return bestDef; +} + +/* +============ +idProgram::FreeDef +============ +*/ +void idProgram::FreeDef( idVarDef *def, const idVarDef *scope ) { + idVarDef *e; + int i; + + if ( def->Type() == ev_vector ) { + idStr name; + + sprintf( name, "%s_x", def->Name() ); + e = GetDef( NULL, name, scope ); + if ( e ) { + FreeDef( e, scope ); + } + + sprintf( name, "%s_y", def->Name() ); + e = GetDef( NULL, name, scope ); + if ( e ) { + FreeDef( e, scope ); + } + + sprintf( name, "%s_z", def->Name() ); + e = GetDef( NULL, name, scope ); + if ( e ) { + FreeDef( e, scope ); + } + } + + varDefs.RemoveIndex( def->num ); + for( i = def->num; i < varDefs.Num(); i++ ) { + varDefs[ i ]->num = i; + } + + delete def; +} + +/* +============ +idProgram::FindFreeResultDef +============ +*/ +idVarDef *idProgram::FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b ) { + idVarDef *def; + + for( def = GetDefList( name ); def != NULL; def = def->Next() ) { + if ( def == a || def == b ) { + continue; + } + if ( def->TypeDef() != type ) { + continue; + } + if ( def->scope != scope ) { + continue; + } + if ( def->numUsers <= 1 ) { + continue; + } + return def; + } + + return AllocDef( type, name, scope, false ); +} + +/* +================ +idProgram::FindFunction + +Searches for the specified function in the currently loaded script. A full namespace should be +specified if not in the global namespace. + +Returns 0 if function not found. +Returns >0 if function found. +================ +*/ +function_t *idProgram::FindFunction( const char *name ) const { + int start; + int pos; + idVarDef *namespaceDef; + idVarDef *def; + + assert( name ); + + idStr fullname = name; + start = 0; + namespaceDef = &def_namespace; + do { + pos = fullname.Find( "::", true, start ); + if ( pos < 0 ) { + break; + } + + idStr namespaceName = fullname.Mid( start, pos - start ); + def = GetDef( NULL, namespaceName, namespaceDef ); + if ( !def ) { + // couldn't find namespace + return NULL; + } + namespaceDef = def; + + // skip past the :: + start = pos + 2; + } while( def->Type() == ev_namespace ); + + idStr funcName = fullname.Right( fullname.Length() - start ); + def = GetDef( NULL, funcName, namespaceDef ); + if ( !def ) { + // couldn't find function + return NULL; + } + + if ( ( def->Type() == ev_function ) && ( def->value.functionPtr->eventdef == NULL ) ) { + return def->value.functionPtr; + } + + // is not a function, or is an eventdef + return NULL; +} + +/* +================ +idProgram::FindFunction + +Searches for the specified object function in the currently loaded script. + +Returns 0 if function not found. +Returns >0 if function found. +================ +*/ +function_t *idProgram::FindFunction( const char *name, const idTypeDef *type ) const { + const idVarDef *tdef; + const idVarDef *def; + + // look for the function + def = NULL; + for( tdef = type->def; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) { + def = GetDef( NULL, name, tdef ); + if ( def ) { + return def->value.functionPtr; + } + } + + return NULL; +} + +/* +================ +idProgram::AllocFunction +================ +*/ +function_t &idProgram::AllocFunction( idVarDef *def ) { + if ( functions.Num() >= functions.Max() ) { + throw idCompileError( va( "Exceeded maximum allowed number of functions (%d)", functions.Max() ) ); + } + + // fill in the dfunction + function_t &func = *functions.Alloc(); + func.eventdef = NULL; + func.def = def; + func.type = def->TypeDef(); + func.firstStatement = 0; + func.numStatements = 0; + func.parmTotal = 0; + func.locals = 0; + func.filenum = filenum; + func.parmSize.SetGranularity( 1 ); + func.SetName( def->GlobalName() ); + + def->SetFunction( &func ); + + return func; +} + +/* +================ +idProgram::SetEntity +================ +*/ +void idProgram::SetEntity( const char *name, idEntity *ent ) { + idVarDef *def; + idStr defName( "$" ); + + defName += name; + + def = GetDef( &type_entity, defName, &def_namespace ); + if ( def && ( def->initialized != idVarDef::stackVariable ) ) { + // 0 is reserved for NULL entity + if ( !ent ) { + *def->value.entityNumberPtr = 0; + } else { + *def->value.entityNumberPtr = ent->entityNumber + 1; + } + } +} + +/* +================ +idProgram::AllocStatement +================ +*/ +statement_t *idProgram::AllocStatement( void ) { + if ( statements.Num() >= statements.Max() ) { + throw idCompileError( va( "Exceeded maximum allowed number of statements (%d)", statements.Max() ) ); + } + return statements.Alloc(); +} + +/* +============== +idProgram::BeginCompilation + +called before compiling a batch of files, clears the pr struct +============== +*/ +void idProgram::BeginCompilation( void ) { + statement_t *statement; + + FreeData(); + + try { + // make the first statement a return for a "NULL" function + statement = AllocStatement(); + statement->linenumber = 0; + statement->file = 0; + statement->op = OP_RETURN; + statement->a = NULL; + statement->b = NULL; + statement->c = NULL; + + // define NULL + //AllocDef( &type_void, "", &def_namespace, true ); + + // define the return def + returnDef = AllocDef( &type_vector, "", &def_namespace, false ); + + // define the return def for strings + returnStringDef = AllocDef( &type_string, "", &def_namespace, false ); + + // define the sys object + sysDef = AllocDef( &type_void, "sys", &def_namespace, true ); + } + + catch( idCompileError &err ) { + gameLocal.Error( "%s", err.error ); + } +} + +/* +============== +idProgram::DisassembleStatement +============== +*/ +void idProgram::DisassembleStatement( idFile *file, int instructionPointer ) const { + opcode_t *op; + const statement_t *statement; + + statement = &statements[ instructionPointer ]; + op = &idCompiler::opcodes[ statement->op ]; + file->Printf( "%20s(%d):\t%6d: %15s\t", fileList[ statement->file ].c_str(), statement->linenumber, instructionPointer, op->opname ); + + if ( statement->a ) { + file->Printf( "\ta: " ); + statement->a->PrintInfo( file, instructionPointer ); + } + + if ( statement->b ) { + file->Printf( "\tb: " ); + statement->b->PrintInfo( file, instructionPointer ); + } + + if ( statement->c ) { + file->Printf( "\tc: " ); + statement->c->PrintInfo( file, instructionPointer ); + } + + file->Printf( "\n" ); +} + +/* +============== +idProgram::Disassemble +============== +*/ +void idProgram::Disassemble( void ) const { + int i; + int instructionPointer; + const function_t *func; + idFile *file; + + file = fileSystem->OpenFileByMode( "script/disasm.txt", FS_WRITE ); + + for( i = 0; i < functions.Num(); i++ ) { + func = &functions[ i ]; + if ( func->eventdef ) { + // skip eventdefs + continue; + } + + file->Printf( "\nfunction %s() %d stack used, %d parms, %d locals {\n", func->Name(), func->locals, func->parmTotal, func->locals - func->parmTotal ); + + for( instructionPointer = 0; instructionPointer < func->numStatements; instructionPointer++ ) { + DisassembleStatement( file, func->firstStatement + instructionPointer ); + } + + file->Printf( "}\n" ); + } + + fileSystem->CloseFile( file ); +} + +/* +============== +idProgram::FinishCompilation + +Called after all files are compiled to check for errors +============== +*/ +void idProgram::FinishCompilation( void ) { + int i; + + top_functions = functions.Num(); + top_statements = statements.Num(); + top_types = types.Num(); + top_defs = varDefs.Num(); + top_files = fileList.Num(); + + variableDefaults.Clear(); + variableDefaults.SetNum( numVariables ); + + for( i = 0; i < numVariables; i++ ) { + variableDefaults[ i ] = variables[ i ]; + } +} + +/* +============== +idProgram::CompileStats + +called after all files are compiled to report memory usage. +============== +*/ +void idProgram::CompileStats( void ) { + int memused; + int memallocated; + int numdefs; + int stringspace; + int funcMem; + int i; + + gameLocal.Printf( "---------- Compile stats ----------\n" ); + gameLocal.DPrintf( "Files loaded:\n" ); + + stringspace = 0; + for( i = 0; i < fileList.Num(); i++ ) { + gameLocal.DPrintf( " %s\n", fileList[ i ].c_str() ); + stringspace += fileList[ i ].Allocated(); + } + stringspace += fileList.Size(); + + numdefs = varDefs.Num(); + memused = varDefs.Num() * sizeof( idVarDef ); + memused += types.Num() * sizeof( idTypeDef ); + memused += stringspace; + + for( i = 0; i < types.Num(); i++ ) { + memused += types[ i ]->Allocated(); + } + + funcMem = functions.MemoryUsed(); + for( i = 0; i < functions.Num(); i++ ) { + funcMem += functions[ i ].Allocated(); + } + + memallocated = funcMem + memused + sizeof( idProgram ); + + memused += statements.MemoryUsed(); + memused += functions.MemoryUsed(); // name and filename of functions are shared, so no need to include them + memused += sizeof( variables ); + + gameLocal.Printf( "\nMemory usage:\n" ); + gameLocal.Printf( " Strings: %d, %d bytes\n", fileList.Num(), stringspace ); + gameLocal.Printf( " Statements: %d, %d bytes\n", statements.Num(), statements.MemoryUsed() ); + gameLocal.Printf( " Functions: %d, %d bytes\n", functions.Num(), funcMem ); + gameLocal.Printf( " Variables: %d bytes\n", numVariables ); + gameLocal.Printf( " Mem used: %d bytes\n", memused ); + gameLocal.Printf( " Static data: %d bytes\n", sizeof( idProgram ) ); + gameLocal.Printf( " Allocated: %d bytes\n", memallocated ); + gameLocal.Printf( " Thread size: %d bytes\n\n", sizeof( idThread ) ); +} + +/* +================ +idProgram::CompileText +================ +*/ +bool idProgram::CompileText( const char *source, const char *text, bool console ) { + idCompiler compiler; + int i; + idVarDef *def; + idStr ospath; + + // use a full os path for GetFilenum since it calls OSPathToRelativePath to convert filenames from the parser + ospath = fileSystem->RelativePathToOSPath( source ); + filenum = GetFilenum( ospath ); + + try { + compiler.CompileFile( text, filename, console ); + + // check to make sure all functions prototyped have code + for( i = 0; i < varDefs.Num(); i++ ) { + def = varDefs[ i ]; + if ( ( def->Type() == ev_function ) && ( ( def->scope->Type() == ev_namespace ) || def->scope->TypeDef()->Inherits( &type_object ) ) ) { + if ( !def->value.functionPtr->eventdef && !def->value.functionPtr->firstStatement ) { + throw idCompileError( va( "function %s was not defined\n", def->GlobalName() ) ); + } + } + } + } + + catch( idCompileError &err ) { + if ( console ) { + gameLocal.Printf( "%s\n", err.error ); + return false; + } else { + gameLocal.Error( "%s\n", err.error ); + } + }; + + if ( !console ) { + CompileStats(); + } + + return true; +} + +/* +================ +idProgram::CompileFunction +================ +*/ +const function_t *idProgram::CompileFunction( const char *functionName, const char *text ) { + bool result; + + result = CompileText( functionName, text, false ); + + if ( g_disasm.GetBool() ) { + Disassemble(); + } + + if ( !result ) { + gameLocal.Error( "Compile failed." ); + } + + return FindFunction( functionName ); +} + +/* +================ +idProgram::CompileFile +================ +*/ +void idProgram::CompileFile( const char *filename ) { + char *src; + bool result; + + if ( fileSystem->ReadFile( filename, ( void ** )&src, NULL ) < 0 ) { + gameLocal.Error( "Couldn't load %s\n", filename ); + } + + result = CompileText( filename, src, false ); + + fileSystem->FreeFile( src ); + + if ( g_disasm.GetBool() ) { + Disassemble(); + } + + if ( !result ) { + gameLocal.Error( "Compile failed in file %s.", filename ); + } +} + +/* +================ +idProgram::FreeData +================ +*/ +void idProgram::FreeData( void ) { + int i; + + // free the defs + varDefs.DeleteContents( true ); + varDefNames.DeleteContents( true ); + varDefNameHash.Free(); + + returnDef = NULL; + returnStringDef = NULL; + sysDef = NULL; + + // free any special types we've created + types.DeleteContents( true ); + + filenum = 0; + + numVariables = 0; + memset( variables, 0, sizeof( variables ) ); + + // clear all the strings in the functions so that it doesn't look like we're leaking memory. + for( i = 0; i < functions.Num(); i++ ) { + functions[ i ].Clear(); + } + + filename.Clear(); + fileList.Clear(); + statements.Clear(); + functions.Clear(); + + top_functions = 0; + top_statements = 0; + top_types = 0; + top_defs = 0; + top_files = 0; + + filename = ""; +} + +/* +================ +idProgram::Startup +================ +*/ +void idProgram::Startup( const char *defaultScript ) { + gameLocal.Printf( "Initializing scripts\n" ); + + // make sure all data is freed up + idThread::Restart(); + + // get ready for loading scripts + BeginCompilation(); + + // load the default script + if ( defaultScript && *defaultScript ) { + CompileFile( defaultScript ); + } + + FinishCompilation(); +} + +/* +================ +idProgram::Save +================ +*/ +void idProgram::Save( idSaveGame *savefile ) const { + int i; + int currentFileNum = top_files; + + savefile->WriteInt( (fileList.Num() - currentFileNum) ); + while ( currentFileNum < fileList.Num() ) { + savefile->WriteString( fileList[ currentFileNum ] ); + currentFileNum++; + } + + for ( i = 0; i < variableDefaults.Num(); i++ ) { + if ( variables[i] != variableDefaults[i] ) { + savefile->WriteInt( i ); + savefile->WriteByte( variables[i] ); + } + } + // Mark the end of the diff with default variables with -1 + savefile->WriteInt( -1 ); + + savefile->WriteInt( numVariables ); + for ( i = variableDefaults.Num(); i < numVariables; i++ ) { + savefile->WriteByte( variables[i] ); + } + + int checksum = CalculateChecksum(); + savefile->WriteInt( checksum ); +} + +/* +================ +idProgram::Restore +================ +*/ +bool idProgram::Restore( idRestoreGame *savefile ) { + int i, num, index; + bool result = true; + idStr scriptname; + + savefile->ReadInt( num ); + for ( i = 0; i < num; i++ ) { + savefile->ReadString( scriptname ); + CompileFile( scriptname ); + } + + savefile->ReadInt( index ); + while( index >= 0 ) { + savefile->ReadByte( variables[index] ); + savefile->ReadInt( index ); + } + + savefile->ReadInt( num ); + for ( i = variableDefaults.Num(); i < num; i++ ) { + savefile->ReadByte( variables[i] ); + } + + int saved_checksum, checksum; + + savefile->ReadInt( saved_checksum ); + checksum = CalculateChecksum(); + + if ( saved_checksum != checksum ) { + result = false; + } + + return result; +} + +/* +================ +idProgram::CalculateChecksum +================ +*/ +int idProgram::CalculateChecksum( void ) const { + int i, result; + + typedef struct { + unsigned short op; + int a; + int b; + int c; + unsigned short linenumber; + unsigned short file; + } statementBlock_t; + + statementBlock_t *statementList = new statementBlock_t[ statements.Num() ]; + + memset( statementList, 0, ( sizeof(statementBlock_t) * statements.Num() ) ); + + // Copy info into new list, using the variable numbers instead of a pointer to the variable + for( i = 0; i < statements.Num(); i++ ) { + statementList[i].op = statements[i].op; + + if ( statements[i].a ) { + statementList[i].a = statements[i].a->num; + } else { + statementList[i].a = -1; + } + if ( statements[i].b ) { + statementList[i].b = statements[i].b->num; + } else { + statementList[i].b = -1; + } + if ( statements[i].c ) { + statementList[i].c = statements[i].c->num; + } else { + statementList[i].c = -1; + } + + statementList[i].linenumber = statements[i].linenumber; + statementList[i].file = statements[i].file; + } + + result = MD4_BlockChecksum( statementList, ( sizeof(statementBlock_t) * statements.Num() ) ); + + delete [] statementList; + + return result; +} + +/* +============== +idProgram::Restart + +Restores all variables to their initial value +============== +*/ +void idProgram::Restart( void ) { + int i; + + idThread::Restart(); + + // + // since there may have been a script loaded by the map or the user may + // have typed "script" from the console, free up any types and vardefs that + // have been allocated after the initial startup + // + for( i = top_types; i < types.Num(); i++ ) { + delete types[ i ]; + } + types.SetNum( top_types, false ); + + for( i = top_defs; i < varDefs.Num(); i++ ) { + delete varDefs[ i ]; + } + varDefs.SetNum( top_defs, false ); + + for( i = top_functions; i < functions.Num(); i++ ) { + functions[ i ].Clear(); + } + functions.SetNum( top_functions ); + + statements.SetNum( top_statements ); + fileList.SetNum( top_files, false ); + filename.Clear(); + + // reset the variables to their default values + numVariables = variableDefaults.Num(); + for( i = 0; i < numVariables; i++ ) { + variables[ i ] = variableDefaults[ i ]; + } +} + +/* +================ +idProgram::GetFilenum +================ +*/ +int idProgram::GetFilenum( const char *name ) { + if ( filename == name ) { + return filenum; + } + + idStr strippedName; + strippedName = fileSystem->OSPathToRelativePath( name ); + if ( !strippedName.Length() ) { + // not off the base path so just use the full path + filenum = fileList.AddUnique( name ); + } else { + filenum = fileList.AddUnique( strippedName ); + } + + // save the unstripped name so that we don't have to strip the incoming name every time we call GetFilenum + filename = name; + + return filenum; +} + +/* +================ +idProgram::idProgram +================ +*/ +idProgram::idProgram() { + FreeData(); +} + +/* +================ +idProgram::~idProgram +================ +*/ +idProgram::~idProgram() { + FreeData(); +} + +/* +================ +idProgram::ReturnEntity +================ +*/ +void idProgram::ReturnEntity( idEntity *ent ) { + if ( ent ) { + *returnDef->value.entityNumberPtr = ent->entityNumber + 1; + } else { + *returnDef->value.entityNumberPtr = 0; + } +} diff --git a/game/script/Script_Program.h b/game/script/Script_Program.h new file mode 100644 index 000000000..c6ac7b372 --- /dev/null +++ b/game/script/Script_Program.h @@ -0,0 +1,614 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SCRIPT_PROGRAM_H__ +#define __SCRIPT_PROGRAM_H__ + +class idScriptObject; +class idEventDef; +class idVarDef; +class idTypeDef; +class idEntity; +class idThread; +class idSaveGame; +class idRestoreGame; + +#define MAX_STRING_LEN 128 +#define MAX_GLOBALS 196608 // in bytes +#define MAX_STRINGS 1024 +#define MAX_FUNCS 3072 +#define MAX_STATEMENTS 81920 // statement_t - 18 bytes last I checked + +typedef enum { + ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean +} etype_t; + +class function_t { +public: + function_t(); + + size_t Allocated( void ) const; + void SetName( const char *name ); + const char *Name( void ) const; + void Clear( void ); + +private: + idStr name; +public: + const idEventDef *eventdef; + idVarDef *def; + const idTypeDef *type; + int firstStatement; + int numStatements; + int parmTotal; + int locals; // total ints of parms + locals + int filenum; // source file defined in + idList parmSize; +}; + +typedef union eval_s { + const char *stringPtr; + float _float; + float vector[ 3 ]; + function_t *function; + int _int; + int entity; +} eval_t; + +/*********************************************************************** + +idTypeDef + +Contains type information for variables and functions. + +***********************************************************************/ + +class idTypeDef { +private: + etype_t type; + idStr name; + int size; + + // function types are more complex + idTypeDef *auxType; // return type + idList parmTypes; + idStrList parmNames; + idList functions; + +public: + idVarDef *def; // a def that points to this type + + idTypeDef( const idTypeDef &other ); + idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ); + void operator=( const idTypeDef& other ); + size_t Allocated( void ) const; + + bool Inherits( const idTypeDef *basetype ) const; + bool MatchesType( const idTypeDef &matchtype ) const; + bool MatchesVirtualFunction( const idTypeDef &matchfunc ) const; + void AddFunctionParm( idTypeDef *parmtype, const char *name ); + void AddField( idTypeDef *fieldtype, const char *name ); + + void SetName( const char *newname ); + const char *Name( void ) const; + + etype_t Type( void ) const; + int Size( void ) const; + + idTypeDef *SuperClass( void ) const; + + idTypeDef *ReturnType( void ) const; + void SetReturnType( idTypeDef *type ); + + idTypeDef *FieldType( void ) const; + void SetFieldType( idTypeDef *type ); + + idTypeDef *PointerType( void ) const; + void SetPointerType( idTypeDef *type ); + + int NumParameters( void ) const; + idTypeDef *GetParmType( int parmNumber ) const; + const char *GetParmName( int parmNumber ) const; + + int NumFunctions( void ) const; + int GetFunctionNumber( const function_t *func ) const; + const function_t *GetFunction( int funcNumber ) const; + void AddFunction( const function_t *func ); +}; + +/*********************************************************************** + +idScriptObject + +In-game representation of objects in scripts. Use the idScriptVariable template +(below) to access variables. + +***********************************************************************/ + +class idScriptObject { +private: + idTypeDef *type; + +public: + byte *data; + + idScriptObject(); + ~idScriptObject(); + + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void Free( void ); + bool SetType( const char *typeName ); + void ClearObject( void ); + bool HasObject( void ) const; + idTypeDef *GetTypeDef( void ) const; + const char *GetTypeName( void ) const; + const function_t *GetConstructor( void ) const; + const function_t *GetDestructor( void ) const; + const function_t *GetFunction( const char *name ) const; + + byte *GetVariable( const char *name, etype_t etype ) const; +}; + +/*********************************************************************** + +idScriptVariable + +Helper template that handles looking up script variables stored in objects. +If the specified variable doesn't exist, or is the wrong data type, idScriptVariable +will cause an error. + +***********************************************************************/ + +template +class idScriptVariable { +private: + type *data; + +public: + idScriptVariable(); + bool IsLinked( void ) const; + void Unlink( void ); + void LinkTo( idScriptObject &obj, const char *name ); + idScriptVariable &operator=( const returnType &value ); + operator returnType() const; +}; + +template +ID_INLINE idScriptVariable::idScriptVariable() { + data = NULL; +} + +template +ID_INLINE bool idScriptVariable::IsLinked( void ) const { + return ( data != NULL ); +} + +template +ID_INLINE void idScriptVariable::Unlink( void ) { + data = NULL; +} + +template +ID_INLINE void idScriptVariable::LinkTo( idScriptObject &obj, const char *name ) { + data = ( type * )obj.GetVariable( name, etype ); + if ( !data ) { + gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() ); + } +} + +template +ID_INLINE idScriptVariable &idScriptVariable::operator=( const returnType &value ) { + // check if we attempt to access the object before it's been linked + assert( data ); + + // make sure we don't crash if we don't have a pointer + if ( data ) { + *data = ( type )value; + } + return *this; +} + +template +ID_INLINE idScriptVariable::operator returnType() const { + // check if we attempt to access the object before it's been linked + assert( data ); + + // make sure we don't crash if we don't have a pointer + if ( data ) { + return ( const returnType )*data; + } else { + // reasonably safe value + return ( const returnType )0; + } +} + +/*********************************************************************** + +Script object variable access template instantiations + +These objects will automatically handle looking up of the current value +of a variable in a script object. They can be stored as part of a class +for up-to-date values of the variable, or can be used in functions to +sample the data for non-dynamic values. + +***********************************************************************/ + +typedef idScriptVariable idScriptBool; +typedef idScriptVariable idScriptFloat; +typedef idScriptVariable idScriptInt; +typedef idScriptVariable idScriptVector; +typedef idScriptVariable idScriptString; + +/*********************************************************************** + +idCompileError + +Causes the compiler to exit out of compiling the current function and +display an error message with line and file info. + +***********************************************************************/ + +class idCompileError : public idException { +public: + idCompileError( const char *text ) : idException( text ) {} +}; + +/*********************************************************************** + +idVarDef + +Define the name, type, and location of variables, functions, and objects +defined in script. + +***********************************************************************/ + +typedef union varEval_s { + idScriptObject **objectPtrPtr; + char *stringPtr; + float *floatPtr; + idVec3 *vectorPtr; + function_t *functionPtr; + int *intPtr; + byte *bytePtr; + int *entityNumberPtr; + int virtualFunction; + int jumpOffset; + int stackOffset; // offset in stack for local variables + int argSize; + varEval_s *evalPtr; + int ptrOffset; +} varEval_t; + +class idVarDefName; + +class idVarDef { + friend class idVarDefName; + +public: + int num; + varEval_t value; + idVarDef * scope; // function, namespace, or object the var was defined in + int numUsers; // number of users if this is a constant + + typedef enum { + uninitialized, initializedVariable, initializedConstant, stackVariable + } initialized_t; + + initialized_t initialized; + +public: + idVarDef( idTypeDef *typeptr = NULL ); + ~idVarDef(); + + const char * Name( void ) const; + const char * GlobalName( void ) const; + + void SetTypeDef( idTypeDef *_type ) { typeDef = _type; } + idTypeDef * TypeDef( void ) const { return typeDef; } + etype_t Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; } + + int DepthOfScope( const idVarDef *otherScope ) const; + + void SetFunction( function_t *func ); + void SetObject( idScriptObject *object ); + void SetValue( const eval_t &value, bool constant ); + void SetString( const char *string, bool constant ); + + idVarDef * Next( void ) const { return next; } // next var def with same name + + void PrintInfo( idFile *file, int instructionPointer ) const; + +private: + idTypeDef * typeDef; + idVarDefName * name; // name of this var + idVarDef * next; // next var with the same name +}; + +/*********************************************************************** + + idVarDefName + +***********************************************************************/ + +class idVarDefName { +public: + idVarDefName( void ) { defs = NULL; } + idVarDefName( const char *n ) { name = n; defs = NULL; } + + const char * Name( void ) const { return name; } + idVarDef * GetDefs( void ) const { return defs; } + + void AddDef( idVarDef *def ); + void RemoveDef( idVarDef *def ); + +private: + idStr name; + idVarDef * defs; +}; + +/*********************************************************************** + + Variable and type defintions + +***********************************************************************/ + +extern idTypeDef type_void; +extern idTypeDef type_scriptevent; +extern idTypeDef type_namespace; +extern idTypeDef type_string; +extern idTypeDef type_float; +extern idTypeDef type_vector; +extern idTypeDef type_entity; +extern idTypeDef type_field; +extern idTypeDef type_function; +extern idTypeDef type_virtualfunction; +extern idTypeDef type_pointer; +extern idTypeDef type_object; +extern idTypeDef type_jumpoffset; // only used for jump opcodes +extern idTypeDef type_argsize; // only used for function call and thread opcodes +extern idTypeDef type_boolean; + +extern idVarDef def_void; +extern idVarDef def_scriptevent; +extern idVarDef def_namespace; +extern idVarDef def_string; +extern idVarDef def_float; +extern idVarDef def_vector; +extern idVarDef def_entity; +extern idVarDef def_field; +extern idVarDef def_function; +extern idVarDef def_virtualfunction; +extern idVarDef def_pointer; +extern idVarDef def_object; +extern idVarDef def_jumpoffset; // only used for jump opcodes +extern idVarDef def_argsize; // only used for function call and thread opcodes +extern idVarDef def_boolean; + +typedef struct statement_s { + unsigned short op; + idVarDef *a; + idVarDef *b; + idVarDef *c; + unsigned short linenumber; + unsigned short file; +} statement_t; + +/*********************************************************************** + +idProgram + +Handles compiling and storage of script data. Multiple idProgram objects +would represent seperate programs with no knowledge of each other. Scripts +meant to access shared data and functions should all be compiled by a +single idProgram. + +***********************************************************************/ + +class idProgram { +private: + idStrList fileList; + idStr filename; + int filenum; + + int numVariables; + byte variables[ MAX_GLOBALS ]; + idStaticList variableDefaults; + idStaticList functions; + idStaticList statements; + idList types; + idList varDefNames; + idHashIndex varDefNameHash; + idList varDefs; + + idVarDef *sysDef; + + int top_functions; + int top_statements; + int top_types; + int top_defs; + int top_files; + + void CompileStats( void ); + +public: + idVarDef *returnDef; + idVarDef *returnStringDef; + + idProgram(); + ~idProgram(); + + // save games + void Save( idSaveGame *savefile ) const; + bool Restore( idRestoreGame *savefile ); + int CalculateChecksum( void ) const; // Used to insure program code has not + // changed between savegames + + void Startup( const char *defaultScript ); + void Restart( void ); + bool CompileText( const char *source, const char *text, bool console ); + const function_t *CompileFunction( const char *functionName, const char *text ); + void CompileFile( const char *filename ); + void BeginCompilation( void ); + void FinishCompilation( void ); + void DisassembleStatement( idFile *file, int instructionPointer ) const; + void Disassemble( void ) const; + void FreeData( void ); + + const char *GetFilename( int num ); + int GetFilenum( const char *name ); + int GetLineNumberForStatement( int index ); + const char *GetFilenameForStatement( int index ); + + idTypeDef *AllocType( idTypeDef &type ); + idTypeDef *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ); + idTypeDef *GetType( idTypeDef &type, bool allocate ); + idTypeDef *FindType( const char *name ); + + idVarDef *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ); + idVarDef *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const; + void FreeDef( idVarDef *d, const idVarDef *scope ); + idVarDef *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b ); + idVarDef *GetDefList( const char *name ) const; + void AddDefToNameList( idVarDef *def, const char *name ); + + function_t *FindFunction( const char *name ) const; // returns NULL if function not found + function_t *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found + function_t &AllocFunction( idVarDef *def ); + function_t *GetFunction( int index ); + int GetFunctionIndex( const function_t *func ); + + void SetEntity( const char *name, idEntity *ent ); + + statement_t *AllocStatement( void ); + statement_t &GetStatement( int index ); + int NumStatements( void ) { return statements.Num(); } + + int GetReturnedInteger( void ); + + void ReturnFloat( float value ); + void ReturnInteger( int value ); + void ReturnVector( idVec3 const &vec ); + void ReturnString( const char *string ); + void ReturnEntity( idEntity *ent ); + + int NumFilenames( void ) { return fileList.Num( ); } +}; + +/* +================ +idProgram::GetStatement +================ +*/ +ID_INLINE statement_t &idProgram::GetStatement( int index ) { + return statements[ index ]; +} + +/* +================ +idProgram::GetFunction +================ +*/ +ID_INLINE function_t *idProgram::GetFunction( int index ) { + return &functions[ index ]; +} + +/* +================ +idProgram::GetFunctionIndex +================ +*/ +ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) { + return func - &functions[0]; +} + +/* +================ +idProgram::GetReturnedInteger +================ +*/ +ID_INLINE int idProgram::GetReturnedInteger( void ) { + return *returnDef->value.intPtr; +} + +/* +================ +idProgram::ReturnFloat +================ +*/ +ID_INLINE void idProgram::ReturnFloat( float value ) { + *returnDef->value.floatPtr = value; +} + +/* +================ +idProgram::ReturnInteger +================ +*/ +ID_INLINE void idProgram::ReturnInteger( int value ) { + *returnDef->value.intPtr = value; +} + +/* +================ +idProgram::ReturnVector +================ +*/ +ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) { + *returnDef->value.vectorPtr = vec; +} + +/* +================ +idProgram::ReturnString +================ +*/ +ID_INLINE void idProgram::ReturnString( const char *string ) { + idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN ); +} + +/* +================ +idProgram::GetFilename +================ +*/ +ID_INLINE const char *idProgram::GetFilename( int num ) { + return fileList[ num ]; +} + +/* +================ +idProgram::GetLineNumberForStatement +================ +*/ +ID_INLINE int idProgram::GetLineNumberForStatement( int index ) { + return statements[ index ].linenumber; +} + +/* +================ +idProgram::GetFilenameForStatement +================ +*/ +ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) { + return GetFilename( statements[ index ].file ); +} + +#endif /* !__SCRIPT_PROGRAM_H__ */ diff --git a/game/script/Script_Thread.cpp b/game/script/Script_Thread.cpp new file mode 100644 index 000000000..b501a0209 --- /dev/null +++ b/game/script/Script_Thread.cpp @@ -0,0 +1,2089 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +static bool init_version = FileVersionList("$Id$", init_version); + +#include "../Game_local.h" +#include "../decltdm_matinfo.h" +#include "../Relations.h" +#include "../SndProp.h" +#include "../Objectives/MissionData.h" +#include "../Missions/MissionManager.h" + +class CRelations; +class CsndProp; + +const idEventDef EV_Thread_Execute( "", NULL ); +const idEventDef EV_Thread_SetCallback( "", NULL ); +const idEventDef EV_Thread_SetRenderCallback( "", NULL ); + +// script callable events +const idEventDef EV_Thread_TerminateThread( "terminate", "d" ); +const idEventDef EV_Thread_Pause( "pause", NULL ); +const idEventDef EV_Thread_Wait( "wait", "f" ); +const idEventDef EV_Thread_WaitFrame( "waitFrame" ); +const idEventDef EV_Thread_WaitFor( "waitFor", "e" ); +const idEventDef EV_Thread_WaitForThread( "waitForThread", "d" ); +const idEventDef EV_Thread_WaitForRender( "waitForRender", "e" ); +const idEventDef EV_Thread_Print( "print", "s" ); +const idEventDef EV_Thread_PrintLn( "println", "s" ); +const idEventDef EV_Thread_Say( "say", "s" ); +const idEventDef EV_Thread_Assert( "assert", "f" ); +const idEventDef EV_Thread_Trigger( "trigger", "e" ); +const idEventDef EV_Thread_SetCvar( "setcvar", "ss" ); +const idEventDef EV_Thread_GetCvar( "getcvar", "s", 's' ); +const idEventDef EV_Thread_Random( "random", "f", 'f' ); +const idEventDef EV_Thread_GetTime( "getTime", NULL, 'f' ); +const idEventDef EV_Thread_KillThread( "killthread", "s" ); +const idEventDef EV_Thread_SetThreadName( "threadname", "s" ); +const idEventDef EV_Thread_GetEntity( "getEntity", "s", 'e' ); +const idEventDef EV_Thread_Spawn( "spawn", "s", 'e' ); +const idEventDef EV_Thread_CopySpawnArgs( "copySpawnArgs", "e" ); +const idEventDef EV_Thread_SetSpawnArg( "setSpawnArg", "ss" ); +const idEventDef EV_Thread_SpawnString( "SpawnString", "ss", 's' ); +const idEventDef EV_Thread_SpawnFloat( "SpawnFloat", "sf", 'f' ); +const idEventDef EV_Thread_SpawnVector( "SpawnVector", "sv", 'v' ); +const idEventDef EV_Thread_ClearPersistantArgs( "clearPersistantArgs" ); +const idEventDef EV_Thread_SetPersistantArg( "setPersistantArg", "ss" ); +const idEventDef EV_Thread_GetPersistantString( "getPersistantString", "s", 's' ); +const idEventDef EV_Thread_GetPersistantFloat( "getPersistantFloat", "s", 'f' ); +const idEventDef EV_Thread_GetPersistantVector( "getPersistantVector", "s", 'v' ); + +// Returns the number of the current mission (0-based) +const idEventDef EV_Thread_GetCurrentMissionNum( "getCurrentMissionNum", NULL, 'f' ); + +const idEventDef EV_Thread_AngToForward( "angToForward", "v", 'v' ); +const idEventDef EV_Thread_AngToRight( "angToRight", "v", 'v' ); +const idEventDef EV_Thread_AngToUp( "angToUp", "v", 'v' ); +const idEventDef EV_Thread_Sine( "sin", "f", 'f' ); +const idEventDef EV_Thread_Cosine( "cos", "f", 'f' ); +const idEventDef EV_Thread_Log( "log", "f", 'f' ); +const idEventDef EV_Thread_Pow( "pow", "ff", 'f' ); +const idEventDef EV_Thread_SquareRoot( "sqrt", "f", 'f' ); +const idEventDef EV_Thread_Normalize( "vecNormalize", "v", 'v' ); +const idEventDef EV_Thread_VecLength( "vecLength", "v", 'f' ); +const idEventDef EV_Thread_VecDotProduct( "DotProduct", "vv", 'f' ); +const idEventDef EV_Thread_VecCrossProduct( "CrossProduct", "vv", 'v' ); +const idEventDef EV_Thread_VecToAngles( "VecToAngles", "v", 'v' ); +const idEventDef EV_Thread_OnSignal( "onSignal", "des" ); +const idEventDef EV_Thread_ClearSignal( "clearSignalThread", "de" ); +const idEventDef EV_Thread_SetCamera( "setCamera", "e" ); +const idEventDef EV_Thread_FirstPerson( "firstPerson", NULL ); +const idEventDef EV_Thread_Trace( "trace", "vvvvde", 'f' ); +const idEventDef EV_Thread_TracePoint( "tracePoint", "vvde", 'f' ); +const idEventDef EV_Thread_GetTraceFraction( "getTraceFraction", NULL, 'f' ); +const idEventDef EV_Thread_GetTraceEndPos( "getTraceEndPos", NULL, 'v' ); +const idEventDef EV_Thread_GetTraceNormal( "getTraceNormal", NULL, 'v' ); +const idEventDef EV_Thread_GetTraceEntity( "getTraceEntity", NULL, 'e' ); +const idEventDef EV_Thread_GetTraceJoint( "getTraceJoint", NULL, 's' ); +const idEventDef EV_Thread_GetTraceBody( "getTraceBody", NULL, 's' ); +const idEventDef EV_Thread_FadeIn( "fadeIn", "vf" ); +const idEventDef EV_Thread_FadeOut( "fadeOut", "vf" ); +const idEventDef EV_Thread_FadeTo( "fadeTo", "vff" ); +const idEventDef EV_Thread_StartMusic( "music", "s" ); +const idEventDef EV_Thread_Error( "error", "s" ); +const idEventDef EV_Thread_Warning( "warning", "s" ); +const idEventDef EV_Thread_StrLen( "strLength", "s", 'd' ); +const idEventDef EV_Thread_StrLeft( "strLeft", "sd", 's' ); +const idEventDef EV_Thread_StrRight( "strRight", "sd", 's' ); +const idEventDef EV_Thread_StrSkip( "strSkip", "sd", 's' ); +const idEventDef EV_Thread_StrMid( "strMid", "sdd", 's' ); +const idEventDef EV_Thread_StrToFloat( "strToFloat", "s", 'f' ); +const idEventDef EV_Thread_RadiusDamage( "radiusDamage", "vEEEsf" ); +const idEventDef EV_Thread_IsClient( "isClient", NULL, 'f' ); +const idEventDef EV_Thread_IsMultiplayer( "isMultiplayer", NULL, 'f' ); +const idEventDef EV_Thread_GetFrameTime( "getFrameTime", NULL, 'f' ); +const idEventDef EV_Thread_GetTicsPerSecond( "getTicsPerSecond", NULL, 'f' ); +const idEventDef EV_Thread_DebugLine( "debugLine", "vvvf" ); +const idEventDef EV_Thread_DebugArrow( "debugArrow", "vvvdf" ); +const idEventDef EV_Thread_DebugCircle( "debugCircle", "vvvfdf" ); +const idEventDef EV_Thread_DebugBounds( "debugBounds", "vvvf" ); +const idEventDef EV_Thread_DrawText( "drawText", "svfvdf" ); +const idEventDef EV_Thread_InfluenceActive( "influenceActive", NULL, 'd' ); + +//AI relationship manager events +const idEventDef EV_AI_GetRelationSys( "getRelation", "dd", 'd' ); +const idEventDef EV_AI_SetRelation( "setRelation", "ddd" ); +const idEventDef EV_AI_OffsetRelation( "offsetRelation", "ddd" ); + +// Dark Mod soundprop events +const idEventDef EV_TDM_SetPortSoundLoss( "setPortSoundLoss", "df" ); +const idEventDef EV_TDM_GetPortSoundLoss( "getPortSoundLoss", "d", 'f' ); + +// greebo: General water test function, tests if a point is in a liquid +const idEventDef EV_PointInLiquid( "pointInLiquid", "ve", 'f' ); + +const idEventDef EV_Thread_DebugTDM_MatInfo( "debug_tdm_material", "s" ); + +// greebo: Writes the string to the Darkmod.log file using DM_LOG +const idEventDef EV_LogString("logString", "dds"); + +// Propagates the string to the sessioncommand variable in gameLocal +const idEventDef EV_SessionCommand("sessionCommand", "s"); + +// Generic interface for passing on mission events from scripts to the SDK +// First argument is the entity which has triggered this event (e.g. a readable) +// Second argument is a numeric identifier (enumerated both in MissionData.h and tdm_defs.script) specifying the type of event +// Third argument is an optional string parameter +const idEventDef EV_HandleMissionEvent("handleMissionEvent", "eds"); + +const idEventDef EV_Thread_CanPlant( "canPlant", "vvEe", 'f' ); // grayman #2787 + +CLASS_DECLARATION( idClass, idThread ) + EVENT( EV_Thread_Execute, idThread::Event_Execute ) + EVENT( EV_Thread_TerminateThread, idThread::Event_TerminateThread ) + EVENT( EV_Thread_Pause, idThread::Event_Pause ) + EVENT( EV_Thread_Wait, idThread::Event_Wait ) + EVENT( EV_Thread_WaitFrame, idThread::Event_WaitFrame ) + EVENT( EV_Thread_WaitFor, idThread::Event_WaitFor ) + EVENT( EV_Thread_WaitForThread, idThread::Event_WaitForThread ) + EVENT( EV_Thread_WaitForRender, idThread::Event_WaitForRender ) + EVENT( EV_Thread_Print, idThread::Event_Print ) + EVENT( EV_Thread_PrintLn, idThread::Event_PrintLn ) + EVENT( EV_Thread_Say, idThread::Event_Say ) + EVENT( EV_Thread_Assert, idThread::Event_Assert ) + EVENT( EV_Thread_Trigger, idThread::Event_Trigger ) + EVENT( EV_Thread_SetCvar, idThread::Event_SetCvar ) + EVENT( EV_Thread_GetCvar, idThread::Event_GetCvar ) + EVENT( EV_Thread_Random, idThread::Event_Random ) + EVENT( EV_Thread_GetTime, idThread::Event_GetTime ) + EVENT( EV_Thread_KillThread, idThread::Event_KillThread ) + EVENT( EV_Thread_SetThreadName, idThread::Event_SetThreadName ) + EVENT( EV_Thread_GetEntity, idThread::Event_GetEntity ) + EVENT( EV_Thread_Spawn, idThread::Event_Spawn ) + EVENT( EV_Thread_CopySpawnArgs, idThread::Event_CopySpawnArgs ) + EVENT( EV_Thread_SetSpawnArg, idThread::Event_SetSpawnArg ) + EVENT( EV_Thread_SpawnString, idThread::Event_SpawnString ) + EVENT( EV_Thread_SpawnFloat, idThread::Event_SpawnFloat ) + EVENT( EV_Thread_SpawnVector, idThread::Event_SpawnVector ) + EVENT( EV_Thread_ClearPersistantArgs, idThread::Event_ClearPersistantArgs ) + EVENT( EV_Thread_SetPersistantArg, idThread::Event_SetPersistantArg ) + EVENT( EV_Thread_GetPersistantString, idThread::Event_GetPersistantString ) + EVENT( EV_Thread_GetPersistantFloat, idThread::Event_GetPersistantFloat ) + EVENT( EV_Thread_GetPersistantVector, idThread::Event_GetPersistantVector ) + + EVENT( EV_Thread_GetCurrentMissionNum, idThread::Event_GetCurrentMissionNum ) + + EVENT( EV_Thread_AngToForward, idThread::Event_AngToForward ) + EVENT( EV_Thread_AngToRight, idThread::Event_AngToRight ) + EVENT( EV_Thread_AngToUp, idThread::Event_AngToUp ) + EVENT( EV_Thread_Sine, idThread::Event_GetSine ) + EVENT( EV_Thread_Cosine, idThread::Event_GetCosine ) + EVENT( EV_Thread_Log, idThread::Event_GetLog ) + EVENT( EV_Thread_Pow, idThread::Event_GetPow ) + EVENT( EV_Thread_SquareRoot, idThread::Event_GetSquareRoot ) + EVENT( EV_Thread_Normalize, idThread::Event_VecNormalize ) + EVENT( EV_Thread_VecLength, idThread::Event_VecLength ) + EVENT( EV_Thread_VecDotProduct, idThread::Event_VecDotProduct ) + EVENT( EV_Thread_VecCrossProduct, idThread::Event_VecCrossProduct ) + EVENT( EV_Thread_VecToAngles, idThread::Event_VecToAngles ) + EVENT( EV_Thread_OnSignal, idThread::Event_OnSignal ) + EVENT( EV_Thread_ClearSignal, idThread::Event_ClearSignalThread ) + EVENT( EV_Thread_SetCamera, idThread::Event_SetCamera ) + EVENT( EV_Thread_FirstPerson, idThread::Event_FirstPerson ) + EVENT( EV_Thread_Trace, idThread::Event_Trace ) + EVENT( EV_Thread_TracePoint, idThread::Event_TracePoint ) + EVENT( EV_Thread_GetTraceFraction, idThread::Event_GetTraceFraction ) + EVENT( EV_Thread_GetTraceEndPos, idThread::Event_GetTraceEndPos ) + EVENT( EV_Thread_GetTraceNormal, idThread::Event_GetTraceNormal ) + EVENT( EV_Thread_GetTraceEntity, idThread::Event_GetTraceEntity ) + EVENT( EV_Thread_GetTraceJoint, idThread::Event_GetTraceJoint ) + EVENT( EV_Thread_GetTraceBody, idThread::Event_GetTraceBody ) + EVENT( EV_Thread_FadeIn, idThread::Event_FadeIn ) + EVENT( EV_Thread_FadeOut, idThread::Event_FadeOut ) + EVENT( EV_Thread_FadeTo, idThread::Event_FadeTo ) + EVENT( EV_SetShaderParm, idThread::Event_SetShaderParm ) + EVENT( EV_Thread_StartMusic, idThread::Event_StartMusic ) + EVENT( EV_Thread_Warning, idThread::Event_Warning ) + EVENT( EV_Thread_Error, idThread::Event_Error ) + EVENT( EV_Thread_StrLen, idThread::Event_StrLen ) + EVENT( EV_Thread_StrLeft, idThread::Event_StrLeft ) + EVENT( EV_Thread_StrRight, idThread::Event_StrRight ) + EVENT( EV_Thread_StrSkip, idThread::Event_StrSkip ) + EVENT( EV_Thread_StrMid, idThread::Event_StrMid ) + EVENT( EV_Thread_StrToFloat, idThread::Event_StrToFloat ) + EVENT( EV_Thread_RadiusDamage, idThread::Event_RadiusDamage ) + EVENT( EV_Thread_IsClient, idThread::Event_IsClient ) + EVENT( EV_Thread_IsMultiplayer, idThread::Event_IsMultiplayer ) + EVENT( EV_Thread_GetFrameTime, idThread::Event_GetFrameTime ) + EVENT( EV_Thread_GetTicsPerSecond, idThread::Event_GetTicsPerSecond ) + EVENT( EV_CacheSoundShader, idThread::Event_CacheSoundShader ) + EVENT( EV_Thread_DebugLine, idThread::Event_DebugLine ) + EVENT( EV_Thread_DebugArrow, idThread::Event_DebugArrow ) + EVENT( EV_Thread_DebugCircle, idThread::Event_DebugCircle ) + EVENT( EV_Thread_DebugBounds, idThread::Event_DebugBounds ) + EVENT( EV_Thread_DrawText, idThread::Event_DrawText ) + EVENT( EV_Thread_InfluenceActive, idThread::Event_InfluenceActive ) + + EVENT( EV_AI_GetRelationSys, idThread::Event_GetRelation ) + EVENT( EV_AI_SetRelation, idThread::Event_SetRelation ) + EVENT( EV_AI_OffsetRelation, idThread::Event_OffsetRelation ) + EVENT( EV_TDM_SetPortSoundLoss, idThread::Event_SetPortSoundLoss ) + EVENT( EV_TDM_GetPortSoundLoss, idThread::Event_GetPortSoundLoss ) + + EVENT( EV_PointInLiquid, idThread::Event_PointInLiquid ) + + EVENT( EV_Thread_DebugTDM_MatInfo, idThread::Event_DebugTDM_MatInfo ) + + EVENT( EV_LogString, idThread::Event_LogString ) + EVENT( EV_SessionCommand, idThread::Event_SessionCommand ) + + EVENT( EV_HandleMissionEvent, idThread::Event_HandleMissionEvent ) + + EVENT( EV_Thread_CanPlant, idThread::Event_CanPlant ) // grayman #2787 + + END_CLASS + +idThread *idThread::currentThread = NULL; +int idThread::threadIndex = 0; +idList idThread::threadList; +trace_t idThread::trace; + +#define VINE_TRACE_CONTENTS 1281 // grayman #2787 - CONTENTS_CORPSE|CONTENTS_BODY|CONTENTS_SOLID + +/* +================ +idThread::CurrentThread +================ +*/ +idThread *idThread::CurrentThread( void ) { + return currentThread; +} + +/* +================ +idThread::CurrentThreadNum +================ +*/ +int idThread::CurrentThreadNum( void ) { + if ( currentThread ) { + return currentThread->GetThreadNum(); + } else { + return 0; + } +} + +/* +================ +idThread::BeginMultiFrameEvent +================ +*/ +bool idThread::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) { + if ( !currentThread ) { + gameLocal.Error( "idThread::BeginMultiFrameEvent called without a current thread" ); + } + return currentThread->interpreter.BeginMultiFrameEvent( ent, event ); +} + +/* +================ +idThread::EndMultiFrameEvent +================ +*/ +void idThread::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) { + if ( !currentThread ) { + gameLocal.Error( "idThread::EndMultiFrameEvent called without a current thread" ); + } + currentThread->interpreter.EndMultiFrameEvent( ent, event ); +} + +/* +================ +idThread::idThread +================ +*/ +idThread::idThread() { + Init(); + SetThreadName( va( "thread_%d", threadIndex ) ); + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } +} + +/* +================ +idThread::idThread +================ +*/ +idThread::idThread( idEntity *self, const function_t *func ) { + assert( self ); + + Init(); + SetThreadName( self->name ); + interpreter.EnterObjectFunction( self, func, false ); + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } +} + +/* +================ +idThread::idThread +================ +*/ +idThread::idThread( const function_t *func ) { + assert( func ); + + Init(); + SetThreadName( func->Name() ); + interpreter.EnterFunction( func, false ); + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } +} + +/* +================ +idThread::idThread +================ +*/ +idThread::idThread( idInterpreter *source, const function_t *func, int args ) { + Init(); + interpreter.ThreadCall( source, func, args ); + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } +} + +/* +================ +idThread::idThread +================ +*/ +idThread::idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ) { + assert( self ); + + Init(); + SetThreadName( self->name ); + interpreter.ThreadCall( source, func, args ); + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } +} + +/* +================ +idThread::~idThread +================ +*/ +idThread::~idThread() { + idThread *thread; + int i; + int n; + + if ( g_debugScript.GetBool() ) { + gameLocal.Printf( "%d: end thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); + } + threadList.Remove( this ); + n = threadList.Num(); + for( i = 0; i < n; i++ ) { + thread = threadList[ i ]; + if ( thread->WaitingOnThread() == this ) { + thread->ThreadCallback( this ); + } + } + + if ( currentThread == this ) { + currentThread = NULL; + } +} + +/* +================ +idThread::ManualDelete +================ +*/ +void idThread::ManualDelete( void ) { + interpreter.terminateOnExit = false; +} + +/* +================ +idThread::Save +================ +*/ +void idThread::Save( idSaveGame *savefile ) const { + + // We will check on restore that threadNum is still the same, + // threads should have been restored in the same order. + savefile->WriteInt( threadNum ); + + savefile->WriteObject( waitingForThread ); + savefile->WriteInt( waitingFor ); + savefile->WriteInt( waitingUntil ); + + interpreter.Save( savefile ); + + savefile->WriteDict( &spawnArgs ); + savefile->WriteString( threadName ); + + savefile->WriteInt( lastExecuteTime ); + savefile->WriteInt( creationTime ); + + savefile->WriteBool( manualControl ); +} + +/* +================ +idThread::Restore +================ +*/ +void idThread::Restore( idRestoreGame *savefile ) { + savefile->ReadInt( threadNum ); + + savefile->ReadObject( reinterpret_cast( waitingForThread ) ); + savefile->ReadInt( waitingFor ); + savefile->ReadInt( waitingUntil ); + + interpreter.Restore( savefile ); + + savefile->ReadDict( &spawnArgs ); + savefile->ReadString( threadName ); + + savefile->ReadInt( lastExecuteTime ); + savefile->ReadInt( creationTime ); + + savefile->ReadBool( manualControl ); +} + +/* +================ +idThread::Init +================ +*/ +void idThread::Init( void ) { + // create a unique threadNum + do { + threadIndex++; + if ( threadIndex == 0 ) { + threadIndex = 1; + } + } while( GetThread( threadIndex ) ); + + threadNum = threadIndex; + threadList.Append( this ); + + creationTime = gameLocal.time; + lastExecuteTime = 0; + manualControl = false; + + ClearWaitFor(); + + interpreter.SetThread( this ); +} + +/* +================ +idThread::GetThread +================ +*/ +idThread *idThread::GetThread( int num ) { + int i; + int n; + idThread *thread; + + n = threadList.Num(); + for( i = 0; i < n; i++ ) { + thread = threadList[ i ]; + if ( thread->GetThreadNum() == num ) { + return thread; + } + } + + return NULL; +} + +/* +================ +idThread::DisplayInfo +================ +*/ +void idThread::DisplayInfo( void ) { + gameLocal.Printf( + "%12i: '%s'\n" + " File: %s(%d)\n" + " Created: %d (%d ms ago)\n" + " Status: ", + threadNum, threadName.c_str(), + interpreter.CurrentFile(), interpreter.CurrentLine(), + creationTime, gameLocal.time - creationTime ); + + if ( interpreter.threadDying ) { + gameLocal.Printf( "Dying\n" ); + } else if ( interpreter.doneProcessing ) { + gameLocal.Printf( + "Paused since %d (%d ms)\n" + " Reason: ", lastExecuteTime, gameLocal.time - lastExecuteTime ); + if ( waitingForThread ) { + gameLocal.Printf( "Waiting for thread #%3i '%s'\n", waitingForThread->GetThreadNum(), waitingForThread->GetThreadName() ); + } else if ( ( waitingFor != ENTITYNUM_NONE ) && ( gameLocal.entities[ waitingFor ] ) ) { + gameLocal.Printf( "Waiting for entity #%3i '%s'\n", waitingFor, gameLocal.entities[ waitingFor ]->name.c_str() ); + } else if ( waitingUntil ) { + gameLocal.Printf( "Waiting until %d (%d ms total wait time)\n", waitingUntil, waitingUntil - lastExecuteTime ); + } else { + gameLocal.Printf( "None\n" ); + } + } else { + gameLocal.Printf( "Processing\n" ); + } + + interpreter.DisplayInfo(); + + gameLocal.Printf( "\n" ); +} + +/* +================ +idThread::ListThreads_f +================ +*/ +void idThread::ListThreads_f( const idCmdArgs &args ) { + int i; + int n; + + n = threadList.Num(); + for( i = 0; i < n; i++ ) { + //threadList[ i ]->DisplayInfo(); + gameLocal.Printf( "%3i: %-20s : %s(%d)\n", threadList[ i ]->threadNum, threadList[ i ]->threadName.c_str(), threadList[ i ]->interpreter.CurrentFile(), threadList[ i ]->interpreter.CurrentLine() ); + } + gameLocal.Printf( "%d active threads\n\n", n ); +} + +/* +================ +idThread::Restart +================ +*/ +void idThread::Restart( void ) { + int i; + int n; + + // reset the threadIndex + threadIndex = 0; + + currentThread = NULL; + n = threadList.Num(); + for( i = n - 1; i >= 0; i-- ) { + delete threadList[ i ]; + } + threadList.Clear(); + + memset( &trace, 0, sizeof( trace ) ); + trace.c.entityNum = ENTITYNUM_NONE; +} + +/* +================ +idThread::DelayedStart +================ +*/ +void idThread::DelayedStart( int delay ) { + CancelEvents( &EV_Thread_Execute ); + if ( gameLocal.time <= 0 ) { + delay++; + } + PostEventMS( &EV_Thread_Execute, delay ); +} + +/* +================ +idThread::Start +================ +*/ +bool idThread::Start( void ) { + bool result; + + CancelEvents( &EV_Thread_Execute ); + result = Execute(); + + return result; +} + +/* +================ +idThread::SetThreadName +================ +*/ +void idThread::SetThreadName( const char *name ) { + threadName = name; +} + +/* +================ +idThread::ObjectMoveDone +================ +*/ +void idThread::ObjectMoveDone( int threadnum, idEntity *obj ) { + idThread *thread; + + if ( !threadnum ) { + return; + } + + thread = GetThread( threadnum ); + if ( thread ) { + thread->ObjectMoveDone( obj ); + } +} + +/* +================ +idThread::End +================ +*/ +void idThread::End( void ) { + // Tell thread to die. It will exit on its own. + Pause(); + interpreter.threadDying = true; +} + +/* +================ +idThread::KillThread +================ +*/ +void idThread::KillThread( const char *name ) { + int i; + int num; + int len; + const char *ptr; + idThread *thread; + + // see if the name uses a wild card + ptr = strchr( name, '*' ); + if ( ptr ) { + len = ptr - name; + } else { + len = strlen( name ); + } + + // kill only those threads whose name matches name + num = threadList.Num(); + for( i = 0; i < num; i++ ) { + thread = threadList[ i ]; + if ( !idStr::Cmpn( thread->GetThreadName(), name, len ) ) { + thread->End(); + } + } +} + +/* +================ +idThread::KillThread +================ +*/ +void idThread::KillThread( int num ) { + idThread *thread; + + thread = GetThread( num ); + if ( thread ) { + // Tell thread to die. It will delete itself on it's own. + thread->End(); + } +} + +/* +================ +idThread::Execute +================ +*/ +bool idThread::Execute( void ) { + idThread *oldThread; + bool done; + + if ( manualControl && ( waitingUntil > gameLocal.time ) ) { + return false; + } + + oldThread = currentThread; + currentThread = this; + + lastExecuteTime = gameLocal.time; + ClearWaitFor(); + done = interpreter.Execute(); + if ( done ) { + End(); + if ( interpreter.terminateOnExit ) { + PostEventMS( &EV_Remove, 0 ); + } + } else if ( !manualControl ) { + if ( waitingUntil > lastExecuteTime ) { + PostEventMS( &EV_Thread_Execute, waitingUntil - lastExecuteTime ); + } else if ( interpreter.MultiFrameEventInProgress() ) { + PostEventMS( &EV_Thread_Execute, gameLocal.msec ); + } + } + + currentThread = oldThread; + + return done; +} + +/* +================ +idThread::IsWaiting + +Checks if thread is still waiting for some event to occur. +================ +*/ +bool idThread::IsWaiting( void ) { + if ( waitingForThread || ( waitingFor != ENTITYNUM_NONE ) ) { + return true; + } + + if ( waitingUntil && ( waitingUntil > gameLocal.time ) ) { + return true; + } + + return false; +} + +/* +================ +idThread::CallFunction + +NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. +================ +*/ +void idThread::CallFunction( const function_t *func, bool clearStack ) { + ClearWaitFor(); + interpreter.EnterFunction( func, clearStack ); +} + +/* +================ +idThread::CallFunction + +NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. +================ +*/ +void idThread::CallFunction( idEntity *self, const function_t *func, bool clearStack ) { + assert( self ); + ClearWaitFor(); + interpreter.EnterObjectFunction( self, func, clearStack ); +} + +/* +================ +idThread::ClearWaitFor +================ +*/ +void idThread::ClearWaitFor( void ) { + waitingFor = ENTITYNUM_NONE; + waitingForThread = NULL; + waitingUntil = 0; +} + +/* +================ +idThread::IsWaitingFor +================ +*/ +bool idThread::IsWaitingFor( idEntity *obj ) { + assert( obj ); + return waitingFor == obj->entityNumber; +} + +/* +================ +idThread::ObjectMoveDone +================ +*/ +void idThread::ObjectMoveDone( idEntity *obj ) { + assert( obj ); + + if ( IsWaitingFor( obj ) ) { + ClearWaitFor(); + DelayedStart( 0 ); + } +} + +/* +================ +idThread::ThreadCallback +================ +*/ +void idThread::ThreadCallback( idThread *thread ) { + if ( interpreter.threadDying ) { + return; + } + + if ( thread == waitingForThread ) { + ClearWaitFor(); + DelayedStart( 0 ); + } +} + +/* +================ +idThread::Event_SetThreadName +================ +*/ +void idThread::Event_SetThreadName( const char *name ) { + SetThreadName( name ); +} + +/* +================ +idThread::Error +================ +*/ +void idThread::Error( const char *fmt, ... ) const { + va_list argptr; + char text[ 1024 ]; + + va_start( argptr, fmt ); + vsprintf( text, fmt, argptr ); + va_end( argptr ); + + interpreter.Error( text ); +} + +/* +================ +idThread::Warning +================ +*/ +void idThread::Warning( const char *fmt, ... ) const { + va_list argptr; + char text[ 1024 ]; + + va_start( argptr, fmt ); + vsprintf( text, fmt, argptr ); + va_end( argptr ); + + interpreter.Warning( text ); +} + +/* +================ +idThread::ReturnString +================ +*/ +void idThread::ReturnString( const char *text ) { + gameLocal.program.ReturnString( text ); +} + +/* +================ +idThread::ReturnFloat +================ +*/ +void idThread::ReturnFloat( float value ) { + gameLocal.program.ReturnFloat( value ); +} + +/* +================ +idThread::ReturnInt +================ +*/ +void idThread::ReturnInt( int value ) { + // true integers aren't supported in the compiler, + // so int values are stored as floats + gameLocal.program.ReturnFloat( value ); +} + +/* +================ +idThread::ReturnVector +================ +*/ +void idThread::ReturnVector( idVec3 const &vec ) { + gameLocal.program.ReturnVector( vec ); +} + +/* +================ +idThread::ReturnEntity +================ +*/ +void idThread::ReturnEntity( idEntity *ent ) { + gameLocal.program.ReturnEntity( ent ); +} + +/* +================ +idThread::Event_Execute +================ +*/ +void idThread::Event_Execute( void ) { + Execute(); +} + +/* +================ +idThread::Pause +================ +*/ +void idThread::Pause( void ) { + ClearWaitFor(); + interpreter.doneProcessing = true; +} + +/* +================ +idThread::WaitMS +================ +*/ +void idThread::WaitMS( int time ) { + Pause(); + waitingUntil = gameLocal.time + time; +} + +/* +================ +idThread::WaitSec +================ +*/ +void idThread::WaitSec( float time ) { + WaitMS( SEC2MS( time ) ); +} + +/* +================ +idThread::WaitFrame +================ +*/ +void idThread::WaitFrame( void ) { + Pause(); + + // manual control threads don't set waitingUntil so that they can be run again + // that frame if necessary. + if ( !manualControl ) { + waitingUntil = gameLocal.time + gameLocal.msec; + } +} + +/*********************************************************************** + + Script callable events + +***********************************************************************/ + +/* +================ +idThread::Event_TerminateThread +================ +*/ +void idThread::Event_TerminateThread( int num ) { + idThread *thread; + + thread = GetThread( num ); + KillThread( num ); +} + +/* +================ +idThread::Event_Pause +================ +*/ +void idThread::Event_Pause( void ) { + Pause(); +} + +/* +================ +idThread::Event_Wait +================ +*/ +void idThread::Event_Wait( float time ) { + WaitSec( time ); +} + +/* +================ +idThread::Event_WaitFrame +================ +*/ +void idThread::Event_WaitFrame( void ) { + WaitFrame(); +} + +/* +================ +idThread::Event_WaitFor +================ +*/ +void idThread::Event_WaitFor( idEntity *ent ) { + if ( ent && ent->RespondsTo( EV_Thread_SetCallback ) ) { + ent->ProcessEvent( &EV_Thread_SetCallback ); + if ( gameLocal.program.GetReturnedInteger() ) { + Pause(); + waitingFor = ent->entityNumber; + } + } +} + +/* +================ +idThread::Event_WaitForThread +================ +*/ +void idThread::Event_WaitForThread( int num ) { + idThread *thread; + + thread = GetThread( num ); + if ( !thread ) { + if ( g_debugScript.GetBool() ) { + // just print a warning and continue executing + Warning( "Thread %d not running", num ); + } + } else { + Pause(); + waitingForThread = thread; + } +} + +/* +================ +idThread::Event_WaitForRender + +Waits for an entity to render before resuming. +================ +*/ +void idThread::Event_WaitForRender( idEntity* ent ) +{ + if ( ent && ent->RespondsTo( EV_Thread_SetRenderCallback ) ) { + ent->ProcessEvent( &EV_Thread_SetRenderCallback ); + if ( gameLocal.program.GetReturnedInteger() ) { + Pause(); + waitingFor = ent->entityNumber; + } + } +} + +/* +================ +idThread::Event_Print +================ +*/ +void idThread::Event_Print( const char *text ) { + gameLocal.Printf( "%s", text ); +} + +/* +================ +idThread::Event_PrintLn +================ +*/ +void idThread::Event_PrintLn( const char *text ) { + gameLocal.Printf( "%s\n", text ); +} + +/* +================ +idThread::Event_Say +================ +*/ +void idThread::Event_Say( const char *text ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", text ) ); +} + +/* +================ +idThread::Event_Assert +================ +*/ +void idThread::Event_Assert( float value ) { + assert( value ); +} + +/* +================ +idThread::Event_Trigger +================ +*/ +void idThread::Event_Trigger( idEntity *ent ) { + if ( ent ) { + ent->Activate(NULL); + } +} + +/* +================ +idThread::Event_SetCvar +================ +*/ +void idThread::Event_SetCvar( const char *name, const char *value ) const { + cvarSystem->SetCVarString( name, value ); +} + +/* +================ +idThread::Event_GetCvar +================ +*/ +void idThread::Event_GetCvar( const char *name ) const { + ReturnString( cvarSystem->GetCVarString( name ) ); +} + +/* +================ +idThread::Event_Random +================ +*/ +void idThread::Event_Random( float range ) const { + float result; + + result = gameLocal.random.RandomFloat(); + ReturnFloat( range * result ); +} + +/* +================ +idThread::Event_GetTime +================ +*/ +void idThread::Event_GetTime( void ) { + ReturnFloat( MS2SEC( gameLocal.realClientTime ) ); +} + +/* +================ +idThread::Event_KillThread +================ +*/ +void idThread::Event_KillThread( const char *name ) { + KillThread( name ); +} + +/* +================ +idThread::Event_GetEntity +================ +*/ +void idThread::Event_GetEntity( const char *name ) { + int entnum; + idEntity *ent; + + assert( name ); + + if ( name[ 0 ] == '*' ) { + entnum = atoi( &name[ 1 ] ); + if ( ( entnum < 0 ) || ( entnum >= MAX_GENTITIES ) ) { + Error( "Entity number in string out of range." ); + } + ReturnEntity( gameLocal.entities[ entnum ] ); + } else { + ent = gameLocal.FindEntity( name ); + ReturnEntity( ent ); + } +} + +/* +================ +idThread::Event_Spawn +================ +*/ +void idThread::Event_Spawn( const char *classname ) { + idEntity *ent; + + spawnArgs.Set( "classname", classname ); + gameLocal.SpawnEntityDef( spawnArgs, &ent ); + ReturnEntity( ent ); + spawnArgs.Clear(); +} + +/* +================ +idThread::Event_CopySpawnArgs +================ +*/ +void idThread::Event_CopySpawnArgs( idEntity *ent ) { + spawnArgs.Copy( ent->spawnArgs ); +} + +/* +================ +idThread::Event_SetSpawnArg +================ +*/ +void idThread::Event_SetSpawnArg( const char *key, const char *value ) { + spawnArgs.Set( key, value ); +} + +/* +================ +idThread::Event_SpawnString +================ +*/ +void idThread::Event_SpawnString( const char *key, const char *defaultvalue ) { + const char *result; + + spawnArgs.GetString( key, defaultvalue, &result ); + ReturnString( result ); +} + +/* +================ +idThread::Event_SpawnFloat +================ +*/ +void idThread::Event_SpawnFloat( const char *key, float defaultvalue ) { + float result; + + spawnArgs.GetFloat( key, va( "%f", defaultvalue ), result ); + ReturnFloat( result ); +} + +/* +================ +idThread::Event_SpawnVector +================ +*/ +void idThread::Event_SpawnVector( const char *key, idVec3 &defaultvalue ) { + idVec3 result; + + spawnArgs.GetVector( key, va( "%f %f %f", defaultvalue.x, defaultvalue.y, defaultvalue.z ), result ); + ReturnVector( result ); +} + +/* +================ +idThread::Event_ClearPersistantArgs +================ +*/ +void idThread::Event_ClearPersistantArgs( void ) { + gameLocal.persistentLevelInfo.Clear(); +} + + +/* +================ +idThread::Event_SetPersistantArg +================ +*/ +void idThread::Event_SetPersistantArg( const char *key, const char *value ) { + gameLocal.persistentLevelInfo.Set( key, value ); +} + +/* +================ +idThread::Event_GetPersistantString +================ +*/ +void idThread::Event_GetPersistantString( const char *key ) { + const char *result; + + gameLocal.persistentLevelInfo.GetString( key, "", &result ); + ReturnString( result ); +} + +/* +================ +idThread::Event_GetPersistantFloat +================ +*/ +void idThread::Event_GetPersistantFloat( const char *key ) { + float result; + + gameLocal.persistentLevelInfo.GetFloat( key, "0", result ); + ReturnFloat( result ); +} + +/* +================ +idThread::Event_GetPersistantVector +================ +*/ +void idThread::Event_GetPersistantVector( const char *key ) { + idVec3 result; + + gameLocal.persistentLevelInfo.GetVector( key, "0 0 0", result ); + ReturnVector( result ); +} + +void idThread::Event_GetCurrentMissionNum() +{ + ReturnFloat(gameLocal.m_MissionManager->GetCurrentMissionIndex()); +} + +/* +================ +idThread::Event_AngToForward +================ +*/ +void idThread::Event_AngToForward( idAngles &ang ) { + ReturnVector( ang.ToForward() ); +} + +/* +================ +idThread::Event_AngToRight +================ +*/ +void idThread::Event_AngToRight( idAngles &ang ) { + idVec3 vec; + + ang.ToVectors( NULL, &vec ); + ReturnVector( vec ); +} + +/* +================ +idThread::Event_AngToUp +================ +*/ +void idThread::Event_AngToUp( idAngles &ang ) { + idVec3 vec; + + ang.ToVectors( NULL, NULL, &vec ); + ReturnVector( vec ); +} + +/* +================ +idThread::Event_GetSine +================ +*/ +void idThread::Event_GetSine( const float angle ) { + ReturnFloat( idMath::Sin( DEG2RAD( angle ) ) ); +} + +/* +================ +idThread::Event_GetCosine +================ +*/ +void idThread::Event_GetCosine( const float angle ) { + ReturnFloat( idMath::Cos( DEG2RAD( angle ) ) ); +} + +/* +================ +Tels: idThread::Event_GetLog +================ +*/ +void idThread::Event_GetLog( const float x ) { + ReturnFloat( idMath::Log( x ) ); +} + +/* +================ +Tels: idThread::Event_GetPow +================ +*/ +void idThread::Event_GetPow( const float x, const float y ) { + ReturnFloat( idMath::Pow( x, y ) ); +} + +/* +================ +idThread::Event_GetSquareRoot +================ +*/ +void idThread::Event_GetSquareRoot( float theSquare ) { + ReturnFloat( idMath::Sqrt( theSquare ) ); +} + +/* +================ +idThread::Event_VecNormalize +================ +*/ +void idThread::Event_VecNormalize( idVec3 &vec ) { + idVec3 n; + + n = vec; + n.Normalize(); + ReturnVector( n ); +} + +/* +================ +idThread::Event_VecLength +================ +*/ +void idThread::Event_VecLength( idVec3 &vec ) { + ReturnFloat( vec.Length() ); +} + +/* +================ +idThread::Event_VecDotProduct +================ +*/ +void idThread::Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ) { + ReturnFloat( vec1 * vec2 ); +} + +/* +================ +idThread::Event_VecCrossProduct +================ +*/ +void idThread::Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ) { + ReturnVector( vec1.Cross( vec2 ) ); +} + +/* +================ +idThread::Event_VecToAngles +================ +*/ +void idThread::Event_VecToAngles( idVec3 &vec ) { + idAngles ang = vec.ToAngles(); + ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); +} + +/* +================ +idThread::Event_OnSignal +================ +*/ +void idThread::Event_OnSignal( int signal, idEntity *ent, const char *func ) { + const function_t *function; + + assert( func ); + + if ( !ent ) { + Error( "Entity not found" ); + } + + if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) { + Error( "Signal out of range" ); + } + + function = gameLocal.program.FindFunction( func ); + if ( !function ) { + Error( "Function '%s' not found", func ); + } + + ent->SetSignal( ( signalNum_t )signal, this, function ); +} + +/* +================ +idThread::Event_ClearSignalThread +================ +*/ +void idThread::Event_ClearSignalThread( int signal, idEntity *ent ) { + if ( !ent ) { + Error( "Entity not found" ); + } + + if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) { + Error( "Signal out of range" ); + } + + ent->ClearSignalThread( ( signalNum_t )signal, this ); +} + +/* +================ +idThread::Event_SetCamera +================ +*/ +void idThread::Event_SetCamera( idEntity *ent ) { + if ( !ent ) { + Error( "Entity not found" ); + return; + } + + if ( !ent->IsType( idCamera::Type ) ) { + Error( "Entity is not a camera" ); + return; + } + + gameLocal.SetCamera( ( idCamera * )ent ); +} + +/* +================ +idThread::Event_FirstPerson +================ +*/ +void idThread::Event_FirstPerson( void ) { + gameLocal.SetCamera( NULL ); +} + +/* +================ +idThread::Event_Trace +================ +*/ +void idThread::Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ) { + if ( mins == vec3_origin && maxs == vec3_origin ) { + gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity ); + } else { + gameLocal.clip.TraceBounds( trace, start, end, idBounds( mins, maxs ), contents_mask, passEntity ); + } + ReturnFloat( trace.fraction ); +} + +/* +================ +idThread::Event_TracePoint +================ +*/ +void idThread::Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ) { + gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity ); + ReturnFloat( trace.fraction ); +} + +/* +================ +idThread::Event_GetTraceFraction +================ +*/ +void idThread::Event_GetTraceFraction( void ) { + ReturnFloat( trace.fraction ); +} + +/* +================ +idThread::Event_GetTraceEndPos +================ +*/ +void idThread::Event_GetTraceEndPos( void ) { + ReturnVector( trace.endpos ); +} + +/* +================ +idThread::Event_GetTraceNormal +================ +*/ +void idThread::Event_GetTraceNormal( void ) { + if ( trace.fraction < 1.0f ) { + ReturnVector( trace.c.normal ); + } else { + ReturnVector( vec3_origin ); + } +} + +/* +================ +idThread::Event_GetTraceEntity +================ +*/ +void idThread::Event_GetTraceEntity( void ) { + if ( trace.fraction < 1.0f ) { + ReturnEntity( gameLocal.entities[ trace.c.entityNum ] ); + } else { + ReturnEntity( ( idEntity * )NULL ); + } +} + +/* +================ +idThread::Event_GetTraceJoint +================ +*/ +void idThread::Event_GetTraceJoint( void ) { + if ( trace.fraction < 1.0f && trace.c.id < 0 ) { + idAFEntity_Base *af = static_cast( gameLocal.entities[ trace.c.entityNum ] ); + if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) { + ReturnString( af->GetAnimator()->GetJointName( CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ) ) ); + return; + } + } + ReturnString( "" ); +} + +/* +================ +idThread::Event_GetTraceBody +================ +*/ +void idThread::Event_GetTraceBody( void ) { + if ( trace.fraction < 1.0f && trace.c.id < 0 ) { + idAFEntity_Base *af = static_cast( gameLocal.entities[ trace.c.entityNum ] ); + if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) { + int bodyId = af->BodyForClipModelId( trace.c.id ); + idAFBody *body = af->GetAFPhysics()->GetBody( bodyId ); + if ( body ) { + ReturnString( body->GetName() ); + return; + } + } + } + ReturnString( "" ); +} + +/* +================ +idThread::Event_FadeIn +================ +*/ +void idThread::Event_FadeIn( idVec3 &color, float time ) { + idVec4 fadeColor; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( player ) { + fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 0.0f ); + player->playerView.Fade(fadeColor, SEC2MS( time ) ); + } +} + +/* +================ +idThread::Event_FadeOut +================ +*/ +void idThread::Event_FadeOut( idVec3 &color, float time ) { + idVec4 fadeColor; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( player ) { + fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 1.0f ); + player->playerView.Fade(fadeColor, SEC2MS( time ) ); + } +} + +/* +================ +idThread::Event_FadeTo +================ +*/ +void idThread::Event_FadeTo( idVec3 &color, float alpha, float time ) { + idVec4 fadeColor; + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( player ) { + fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], alpha ); + player->playerView.Fade(fadeColor, SEC2MS( time ) ); + } +} + +/* +================ +idThread::Event_SetShaderParm +================ +*/ +void idThread::Event_SetShaderParm( int parmnum, float value ) { + if ( ( parmnum < 0 ) || ( parmnum >= MAX_GLOBAL_SHADER_PARMS ) ) { + Error( "shader parm index (%d) out of range", parmnum ); + } + + gameLocal.globalShaderParms[ parmnum ] = value; +} + +/* +================ +idThread::Event_StartMusic +================ +*/ +void idThread::Event_StartMusic( const char *text ) { + gameSoundWorld->PlayShaderDirectly( text ); +} + +/* +================ +idThread::Event_Warning +================ +*/ +void idThread::Event_Warning( const char *text ) { + Warning( "%s", text ); +} + +/* +================ +idThread::Event_Error +================ +*/ +void idThread::Event_Error( const char *text ) { + Error( "%s", text ); +} + +/* +================ +idThread::Event_StrLen +================ +*/ +void idThread::Event_StrLen( const char *string ) { + int len; + + len = strlen( string ); + idThread::ReturnInt( len ); +} + +/* +================ +idThread::Event_StrLeft +================ +*/ +void idThread::Event_StrLeft( const char *string, int num ) { + int len; + + if ( num < 0 ) { + idThread::ReturnString( "" ); + return; + } + + len = strlen( string ); + if ( len < num ) { + idThread::ReturnString( string ); + return; + } + + idStr result( string, 0, num ); + idThread::ReturnString( result ); +} + +/* +================ +idThread::Event_StrRight +================ +*/ +void idThread::Event_StrRight( const char *string, int num ) { + int len; + + if ( num < 0 ) { + idThread::ReturnString( "" ); + return; + } + + len = strlen( string ); + if ( len < num ) { + idThread::ReturnString( string ); + return; + } + + idThread::ReturnString( string + len - num ); +} + +/* +================ +idThread::Event_StrSkip +================ +*/ +void idThread::Event_StrSkip( const char *string, int num ) { + int len; + + if ( num < 0 ) { + idThread::ReturnString( string ); + return; + } + + len = strlen( string ); + if ( len < num ) { + idThread::ReturnString( "" ); + return; + } + + idThread::ReturnString( string + num ); +} + +/* +================ +idThread::Event_StrMid +================ +*/ +void idThread::Event_StrMid( const char *string, int start, int num ) { + int len; + + if ( num < 0 ) { + idThread::ReturnString( "" ); + return; + } + + if ( start < 0 ) { + start = 0; + } + len = strlen( string ); + if ( start > len ) { + start = len; + } + + if ( start + num > len ) { + num = len - start; + } + + idStr result( string, start, start + num ); + idThread::ReturnString( result ); +} + +/* +================ +idThread::Event_StrToFloat( const char *string ) +================ +*/ +void idThread::Event_StrToFloat( const char *string ) { + float result; + + result = atof( string ); + idThread::ReturnFloat( result ); +} + +/* +================ +idThread::Event_RadiusDamage +================ +*/ +void idThread::Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ) { + gameLocal.RadiusDamage( origin, inflictor, attacker, ignore, ignore, damageDefName, dmgPower ); +} + +/* +================ +idThread::Event_IsClient +================ +*/ +void idThread::Event_IsClient( void ) { + idThread::ReturnFloat( gameLocal.isClient ); +} + +/* +================ +idThread::Event_IsMultiplayer +================ +*/ +void idThread::Event_IsMultiplayer( void ) { + idThread::ReturnFloat( gameLocal.isMultiplayer ); +} + +/* +================ +idThread::Event_GetFrameTime +================ +*/ +void idThread::Event_GetFrameTime( void ) { + idThread::ReturnFloat( MS2SEC( gameLocal.msec ) ); +} + +/* +================ +idThread::Event_GetTicsPerSecond +================ +*/ +void idThread::Event_GetTicsPerSecond( void ) { + idThread::ReturnFloat( USERCMD_HZ ); +} + +/* +================ +idThread::Event_CacheSoundShader +================ +*/ +void idThread::Event_CacheSoundShader( const char *soundName ) { + declManager->FindSound( soundName ); +} + +/* +================ +idThread::Event_DebugLine +================ +*/ +void idThread::Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ) { + gameRenderWorld->DebugLine( idVec4( color.x, color.y, color.z, 0.0f ), start, end, SEC2MS( lifetime ) ); +} + +/* +================ +idThread::Event_DebugArrow +================ +*/ +void idThread::Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ) { + gameRenderWorld->DebugArrow( idVec4( color.x, color.y, color.z, 0.0f ), start, end, size, SEC2MS( lifetime ) ); +} + +/* +================ +idThread::Event_DebugCircle +================ +*/ +void idThread::Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ) { + gameRenderWorld->DebugCircle( idVec4( color.x, color.y, color.z, 0.0f ), origin, dir, radius, numSteps, SEC2MS( lifetime ) ); +} + +/* +================ +idThread::Event_DebugBounds +================ +*/ +void idThread::Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ) { + gameRenderWorld->DebugBounds( idVec4( color.x, color.y, color.z, 0.0f ), idBounds( mins, maxs ), vec3_origin, SEC2MS( lifetime ) ); +} + +/* +================ +idThread::Event_DrawText +================ +*/ +void idThread::Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ) { + gameRenderWorld->DrawText( text, origin, scale, idVec4( color.x, color.y, color.z, 0.0f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), align, SEC2MS( lifetime ) ); +} + +/* +================ +idThread::Event_InfluenceActive +================ +*/ +void idThread::Event_InfluenceActive( void ) { + idPlayer *player; + + player = gameLocal.GetLocalPlayer(); + if ( player && player->GetInfluenceLevel() ) { + idThread::ReturnInt( true ); + } else { + idThread::ReturnInt( false ); + } +} + +/** +* DarkMod: The following script events are a frontend for +* the global AI relationship manager (stored in game_local) +**/ +void idThread::Event_GetRelation( int team1, int team2 ) +{ + idThread::ReturnInt( gameLocal.m_RelationsManager->GetRelNum( team1, team2 ) ); +} + +void idThread::Event_SetRelation( int team1, int team2, int val ) +{ + gameLocal.m_RelationsManager->SetRel( team1, team2, val ); +} + +void idThread::Event_OffsetRelation( int team1, int team2, int offset ) +{ + gameLocal.m_RelationsManager->ChangeRel( team1, team2, offset ); +} + +void idThread::Event_SetPortSoundLoss( int handle, float value ) +{ + gameLocal.m_sndProp->SetPortalLoss( handle, value ); +} + +void idThread::Event_GetPortSoundLoss( int handle ) +{ + idThread::ReturnFloat( gameLocal.m_sndProp->GetPortalLoss( handle ) ); +} + +void idThread::Event_LogString(int logClass, int logType, const char* output) +{ + DM_LOG(static_cast(logClass), static_cast(logType))LOGSTRING(const_cast(output)); +} + +/* +================ +idThread::CallFunctionArgs + +NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. +================ +*/ +bool idThread::CallFunctionArgs(const function_t *func, bool clearStack, const char *fmt, ...) +{ + bool rc = false; + va_list argptr; + + ClearWaitFor(); + + va_start(argptr, fmt); + rc = interpreter.EnterFunctionVarArgVN(func, clearStack, fmt, argptr); + va_end(argptr); + + return rc; +} + +bool idThread::CallFunctionArgsVN(const function_t *func, bool clearStack, const char *fmt, va_list args) +{ + bool rc = false; + + ClearWaitFor(); + + rc = interpreter.EnterFunctionVarArgVN(func, clearStack, fmt, args); + + return rc; +} + +void idThread::Event_DebugTDM_MatInfo( const char *mat ) +{ + const tdmDeclTDM_MatInfo *tdmat = static_cast< const tdmDeclTDM_MatInfo* >( declManager->FindType( DECL_TDM_MATINFO, mat, false ) ); + if ( tdmat != NULL ) { + gameLocal.Printf( "Information for tdm material declaration: %s\n", mat ); + gameLocal.Printf( "surfacetype: %s\n", tdmat->surfaceType.c_str() ); + } else { + gameLocal.Warning( "Non-existant tdm material declaration: %s", mat ); + } +} + +void idThread::Event_PointInLiquid( const idVec3 &point, idEntity* ignoreEntity ) { + // Check if the point is in water + int contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, ignoreEntity ); + ReturnFloat( (contents & MASK_WATER) ? 1 : 0); +} + +void idThread::Event_SessionCommand(const char* cmd) +{ + gameLocal.sessionCommand = cmd; +} + +void idThread::Event_HandleMissionEvent(idEntity* entity, int eventType, const char* argument) +{ + // Safety check the enum + if (eventType < EVENT_NOTHING || eventType >= EVENT_INVALID) + { + gameLocal.Warning("Invalid mission event type passed by %s to handleMissionEvent(): %d", entity->name.c_str(), eventType); + return; + } + + // Pass on the call + gameLocal.m_MissionData->HandleMissionEvent(entity, static_cast(eventType), argument); +} + +// grayman #2787 + +void idThread::Event_CanPlant( const idVec3 &traceStart, const idVec3 &traceEnd, idEntity *ignore, idEntity *vine ) +{ + float vineFriendly = 0; // assume the vine can't grow + trace_t result; + if ( gameLocal.clip.TracePoint( result, traceStart, traceEnd, VINE_TRACE_CONTENTS, ignore ) ) + { + int contents = gameLocal.clip.Contents( result.endpos, NULL, mat3_identity, -1, ignore ); + if ( !( contents & MASK_WATER ) ) // grow if not in water + { + if ( abs( result.c.normal.z ) < 0.866 ) // grow if not on a flat surface + { + idEntity* struckEnt = gameLocal.entities[result.c.entityNum]; + if ( struckEnt ) + { + if ( ( struckEnt == gameLocal.world ) || struckEnt->IsType( idStaticEntity::Type ) ) + { + // Either we hit a world brush, or a func_static. We can grow on both types. + + const idMaterial* material = result.c.material; + if ( material ) + { + idStr description = material->GetDescription(); + if ( idStr::FindText(description,"vine_friendly") >= 0 ) + { + // We can plant here, so save planting data on the vine entity + + vine->m_VinePlantLoc = result.endpos; + vine->m_VinePlantNormal = result.c.normal; + vineFriendly = 1; + } + } + } + } + } + } + } + + idThread::ReturnFloat( vineFriendly ); +} + diff --git a/game/script/Script_Thread.h b/game/script/Script_Thread.h new file mode 100644 index 000000000..3bc532fd6 --- /dev/null +++ b/game/script/Script_Thread.h @@ -0,0 +1,384 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SCRIPT_THREAD_H__ +#define __SCRIPT_THREAD_H__ + +extern const idEventDef EV_Thread_Execute; +extern const idEventDef EV_Thread_SetCallback; +extern const idEventDef EV_Thread_SetRenderCallback; +extern const idEventDef EV_Thread_TerminateThread; +extern const idEventDef EV_Thread_Pause; +extern const idEventDef EV_Thread_Wait; +extern const idEventDef EV_Thread_WaitFrame; +extern const idEventDef EV_Thread_WaitFor; +extern const idEventDef EV_Thread_WaitForThread; +extern const idEventDef EV_Thread_Print; +extern const idEventDef EV_Thread_PrintLn; +extern const idEventDef EV_Thread_Say; +extern const idEventDef EV_Thread_Assert; +extern const idEventDef EV_Thread_Trigger; +extern const idEventDef EV_Thread_SetCvar; +extern const idEventDef EV_Thread_GetCvar; +extern const idEventDef EV_Thread_Random; +extern const idEventDef EV_Thread_GetTime; +extern const idEventDef EV_Thread_KillThread; +extern const idEventDef EV_Thread_SetThreadName; +extern const idEventDef EV_Thread_GetEntity; +extern const idEventDef EV_Thread_Spawn; +extern const idEventDef EV_Thread_SetSpawnArg; +extern const idEventDef EV_Thread_SpawnString; +extern const idEventDef EV_Thread_SpawnFloat; +extern const idEventDef EV_Thread_SpawnVector; +extern const idEventDef EV_Thread_AngToForward; +extern const idEventDef EV_Thread_AngToRight; +extern const idEventDef EV_Thread_AngToUp; +extern const idEventDef EV_Thread_Sine; +extern const idEventDef EV_Thread_Cosine; +extern const idEventDef EV_Thread_Log; +extern const idEventDef EV_Thread_Pow; +extern const idEventDef EV_Thread_Normalize; +extern const idEventDef EV_Thread_VecLength; +extern const idEventDef EV_Thread_VecDotProduct; +extern const idEventDef EV_Thread_VecCrossProduct; +extern const idEventDef EV_Thread_OnSignal; +extern const idEventDef EV_Thread_ClearSignal; +extern const idEventDef EV_Thread_SetCamera; +extern const idEventDef EV_Thread_FirstPerson; +extern const idEventDef EV_Thread_TraceFraction; +extern const idEventDef EV_Thread_TracePos; +extern const idEventDef EV_Thread_FadeIn; +extern const idEventDef EV_Thread_FadeOut; +extern const idEventDef EV_Thread_FadeTo; +extern const idEventDef EV_Thread_Restart; + +extern const idEventDef EV_AI_GetRelationSys; +extern const idEventDef EV_AI_SetRelation; +extern const idEventDef EV_AI_OffsetRelation; + +extern const idEventDef EV_PointInLiquid; + +extern const idEventDef EV_TDM_SetPortSoundLoss; +extern const idEventDef EV_TDM_GetPortSoundLoss; + +extern const idEventDef EV_HandleMissionEvent; + +class idThread : public idClass { +private: + static idThread *currentThread; + + idThread *waitingForThread; + int waitingFor; + int waitingUntil; + idInterpreter interpreter; + + idDict spawnArgs; + + int threadNum; + idStr threadName; + + int lastExecuteTime; + int creationTime; + + bool manualControl; + + static int threadIndex; + static idList threadList; + + static trace_t trace; + + void Init( void ); + void Pause( void ); + + void Event_Execute( void ); + void Event_SetThreadName( const char *name ); + + // + // script callable Events + // + void Event_TerminateThread( int num ); + void Event_Pause( void ); + void Event_Wait( float time ); + void Event_WaitFrame( void ); + void Event_WaitFor( idEntity *ent ); + void Event_WaitForThread( int num ); + void Event_WaitForRender( idEntity *ent ); + void Event_Print( const char *text ); + void Event_PrintLn( const char *text ); + void Event_Say( const char *text ); + void Event_Assert( float value ); + void Event_Trigger( idEntity *ent ); + void Event_SetCvar( const char *name, const char *value ) const; + void Event_GetCvar( const char *name ) const; + void Event_Random( float range ) const; + void Event_GetTime( void ); + void Event_KillThread( const char *name ); + void Event_GetEntity( const char *name ); + void Event_Spawn( const char *classname ); + void Event_CopySpawnArgs( idEntity *ent ); + void Event_SetSpawnArg( const char *key, const char *value ); + void Event_SpawnString( const char *key, const char *defaultvalue ); + void Event_SpawnFloat( const char *key, float defaultvalue ); + void Event_SpawnVector( const char *key, idVec3 &defaultvalue ); + void Event_ClearPersistantArgs( void ); + void Event_SetPersistantArg( const char *key, const char *value ); + void Event_GetPersistantString( const char *key ); + void Event_GetPersistantFloat( const char *key ); + void Event_GetPersistantVector( const char *key ); + + void Event_GetCurrentMissionNum(); + + void Event_AngToForward( idAngles &ang ); + void Event_AngToRight( idAngles &ang ); + void Event_AngToUp( idAngles &ang ); + void Event_GetSine( const float angle ); + void Event_GetCosine( const float angle ); + void Event_GetLog( const float x ); + void Event_GetPow( const float x, const float y ); + void Event_GetSquareRoot( float theSquare ); + void Event_VecNormalize( idVec3 &vec ); + void Event_VecLength( idVec3 &vec ); + void Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ); + void Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ); + void Event_VecToAngles( idVec3 &vec ); + void Event_OnSignal( int signal, idEntity *ent, const char *func ); + void Event_ClearSignalThread( int signal, idEntity *ent ); + void Event_SetCamera( idEntity *ent ); + void Event_FirstPerson( void ); + void Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ); + void Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ); + void Event_GetTraceFraction( void ); + void Event_GetTraceEndPos( void ); + void Event_GetTraceNormal( void ); + void Event_GetTraceEntity( void ); + void Event_GetTraceJoint( void ); + void Event_GetTraceBody( void ); + void Event_FadeIn( idVec3 &color, float time ); + void Event_FadeOut( idVec3 &color, float time ); + void Event_FadeTo( idVec3 &color, float alpha, float time ); + void Event_SetShaderParm( int parmnum, float value ); + void Event_StartMusic( const char *name ); + void Event_Warning( const char *text ); + void Event_Error( const char *text ); + void Event_StrLen( const char *string ); + void Event_StrLeft( const char *string, int num ); + void Event_StrRight( const char *string, int num ); + void Event_StrSkip( const char *string, int num ); + void Event_StrMid( const char *string, int start, int num ); + void Event_StrToFloat( const char *string ); + void Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ); + void Event_IsClient( void ); + void Event_IsMultiplayer( void ); + void Event_GetFrameTime( void ); + void Event_GetTicsPerSecond( void ); + void Event_CacheSoundShader( const char *soundName ); + void Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ); + void Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ); + void Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ); + void Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ); + void Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ); + void Event_InfluenceActive( void ); + + /** + * greebo: Tests if a point is in a liquid. + * + * @ignoreEntity: This excludes an entity from the clip test. + * @returns: returns TRUE to the calling thread if the point is in a liquid + */ + void Event_PointInLiquid( const idVec3 &point, idEntity* ignoreEntity ); + + // Emits the string to the session command variable in gameLocal. + void Event_SessionCommand(const char* cmd); + + // For test purposes only. + void Event_DebugTDM_MatInfo( const char *mat ); + + /** + * The following events are a frontend for the AI relationship + * manager (stored in game_local). + * See CRelations definition for descriptions of functions called + **/ + void Event_GetRelation( int team1, int team2 ); + void Event_SetRelation( int team1, int team2, int val ); + void Event_OffsetRelation( int team1, int team2, int offset ); + + /** + * TDM Soundprop Events: + * Set or get the acoustical loss for a portal with a given handle. + * Handle must be greater than zero and less than the number of portals in the map. + **/ + void Event_SetPortSoundLoss( int handle, float value ); + void Event_GetPortSoundLoss( int handle ); + + // The scriptevent counterpart of DM_LOG + void Event_LogString(int logClass, int logType, const char* output); + + // The script interface for raising mission events, like readable callbacks + void Event_HandleMissionEvent(idEntity* entity, int eventType, const char* argument); + + void Event_CanPlant( const idVec3 &traceStart, const idVec3 &traceEnd, idEntity *ignore, idEntity *vine ); // grayman #2787 + +public: + CLASS_PROTOTYPE( idThread ); + + idThread(); + idThread( idEntity *self, const function_t *func ); + idThread( const function_t *func ); + idThread( idInterpreter *source, const function_t *func, int args ); + idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ); + + virtual ~idThread(); + + // tells the thread manager not to delete this thread when it ends + void ManualDelete( void ); + + // save games + void Save( idSaveGame *savefile ) const; // archives object for save game file + void Restore( idRestoreGame *savefile ); // unarchives object from save game file + + void EnableDebugInfo( void ) { interpreter.debug = true; }; + void DisableDebugInfo( void ) { interpreter.debug = false; }; + + void WaitMS( int time ); + void WaitSec( float time ); + void WaitFrame( void ); + + // NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. + void CallFunction(const function_t *func, bool clearStack ); + + bool CallFunctionArgs(const function_t *func, bool clearStack, const char *fmt, ...); + bool CallFunctionArgsVN(const function_t *func, bool clearStack, const char *fmt, va_list args); + + // NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. + void CallFunction( idEntity *obj, const function_t *func, bool clearStack ); + + void DisplayInfo(); + static idThread *GetThread( int num ); + static void ListThreads_f( const idCmdArgs &args ); + static void Restart( void ); + static void ObjectMoveDone( int threadnum, idEntity *obj ); + + static idList& GetThreads ( void ); + + bool IsDoneProcessing ( void ); + bool IsDying ( void ); + + void End( void ); + static void KillThread( const char *name ); + static void KillThread( int num ); + bool Execute( void ); + void ManualControl( void ) { manualControl = true; CancelEvents( &EV_Thread_Execute ); }; + void DoneProcessing( void ) { interpreter.doneProcessing = true; }; + void ContinueProcessing( void ) { interpreter.doneProcessing = false; }; + bool ThreadDying( void ) { return interpreter.threadDying; }; + void EndThread( void ) { interpreter.threadDying = true; }; + bool IsWaiting( void ); + void ClearWaitFor( void ); + bool IsWaitingFor( idEntity *obj ); + void ObjectMoveDone( idEntity *obj ); + void ThreadCallback( idThread *thread ); + void DelayedStart( int delay ); + bool Start( void ); + idThread *WaitingOnThread( void ); + void SetThreadNum( int num ); + int GetThreadNum( void ); + void SetThreadName( const char *name ); + const char *GetThreadName( void ); + + void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + + void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); + + + static idThread *CurrentThread( void ); + static int CurrentThreadNum( void ); + static bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ); + static void EndMultiFrameEvent( idEntity *ent, const idEventDef *event ); + + static void ReturnString( const char *text ); + static void ReturnFloat( float value ); + static void ReturnInt( int value ); + static void ReturnVector( idVec3 const &vec ); + static void ReturnEntity( idEntity *ent ); +}; + +/* +================ +idThread::WaitingOnThread +================ +*/ +ID_INLINE idThread *idThread::WaitingOnThread( void ) { + return waitingForThread; +} + +/* +================ +idThread::SetThreadNum +================ +*/ +ID_INLINE void idThread::SetThreadNum( int num ) { + threadNum = num; +} + +/* +================ +idThread::GetThreadNum +================ +*/ +ID_INLINE int idThread::GetThreadNum( void ) { + return threadNum; +} + +/* +================ +idThread::GetThreadName +================ +*/ +ID_INLINE const char *idThread::GetThreadName( void ) { + return threadName.c_str(); +} + +/* +================ +idThread::GetThreads +================ +*/ +ID_INLINE idList& idThread::GetThreads ( void ) { + return threadList; +} + +/* +================ +idThread::IsDoneProcessing +================ +*/ +ID_INLINE bool idThread::IsDoneProcessing ( void ) { + return interpreter.doneProcessing; +} + +/* +================ +idThread::IsDying +================ +*/ +ID_INLINE bool idThread::IsDying ( void ) { + return interpreter.threadDying; +} + +#endif /* !__SCRIPT_THREAD_H__ */ diff --git a/game/script/script_compiler.cpp b/game/script/script_compiler.cpp deleted file mode 100644 index 340015913..000000000 --- a/game/script/script_compiler.cpp +++ /dev/null @@ -1,2636 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -#define FUNCTION_PRIORITY 2 -#define INT_PRIORITY 2 -#define NOT_PRIORITY 5 -#define TILDE_PRIORITY 5 -#define TOP_PRIORITY 7 - -bool idCompiler::punctuationValid[ 256 ]; -char *idCompiler::punctuation[] = { - "+=", "-=", "*=", "/=", "%=", "&=", "|=", "++", "--", - "&&", "||", "<=", ">=", "==", "!=", "::", ";", ",", - "~", "!", "*", "/", "%", "(", ")", "-", "+", - "=", "[", "]", ".", "<", ">" , "&", "|", ":", NULL -}; - -opcode_t idCompiler::opcodes[] = { - { "", "RETURN", -1, false, &def_void, &def_void, &def_void }, - - { "++", "UINC_F", 1, true, &def_float, &def_void, &def_void }, - { "++", "UINCP_F", 1, true, &def_object, &def_field, &def_float }, - { "--", "UDEC_F", 1, true, &def_float, &def_void, &def_void }, - { "--", "UDECP_F", 1, true, &def_object, &def_field, &def_float }, - - { "~", "COMP_F", -1, false, &def_float, &def_void, &def_float }, - - { "*", "MUL_F", 3, false, &def_float, &def_float, &def_float }, - { "*", "MUL_V", 3, false, &def_vector, &def_vector, &def_float }, - { "*", "MUL_FV", 3, false, &def_float, &def_vector, &def_vector }, - { "*", "MUL_VF", 3, false, &def_vector, &def_float, &def_vector }, - - { "/", "DIV", 3, false, &def_float, &def_float, &def_float }, - { "%", "MOD_F", 3, false, &def_float, &def_float, &def_float }, - - { "+", "ADD_F", 4, false, &def_float, &def_float, &def_float }, - { "+", "ADD_V", 4, false, &def_vector, &def_vector, &def_vector }, - { "+", "ADD_S", 4, false, &def_string, &def_string, &def_string }, - { "+", "ADD_FS", 4, false, &def_float, &def_string, &def_string }, - { "+", "ADD_SF", 4, false, &def_string, &def_float, &def_string }, - { "+", "ADD_VS", 4, false, &def_vector, &def_string, &def_string }, - { "+", "ADD_SV", 4, false, &def_string, &def_vector, &def_string }, - - { "-", "SUB_F", 4, false, &def_float, &def_float, &def_float }, - { "-", "SUB_V", 4, false, &def_vector, &def_vector, &def_vector }, - - { "==", "EQ_F", 5, false, &def_float, &def_float, &def_float }, - { "==", "EQ_V", 5, false, &def_vector, &def_vector, &def_float }, - { "==", "EQ_S", 5, false, &def_string, &def_string, &def_float }, - { "==", "EQ_E", 5, false, &def_entity, &def_entity, &def_float }, - { "==", "EQ_EO", 5, false, &def_entity, &def_object, &def_float }, - { "==", "EQ_OE", 5, false, &def_object, &def_entity, &def_float }, - { "==", "EQ_OO", 5, false, &def_object, &def_object, &def_float }, - - { "!=", "NE_F", 5, false, &def_float, &def_float, &def_float }, - { "!=", "NE_V", 5, false, &def_vector, &def_vector, &def_float }, - { "!=", "NE_S", 5, false, &def_string, &def_string, &def_float }, - { "!=", "NE_E", 5, false, &def_entity, &def_entity, &def_float }, - { "!=", "NE_EO", 5, false, &def_entity, &def_object, &def_float }, - { "!=", "NE_OE", 5, false, &def_object, &def_entity, &def_float }, - { "!=", "NE_OO", 5, false, &def_object, &def_object, &def_float }, - - { "<=", "LE", 5, false, &def_float, &def_float, &def_float }, - { ">=", "GE", 5, false, &def_float, &def_float, &def_float }, - { "<", "LT", 5, false, &def_float, &def_float, &def_float }, - { ">", "GT", 5, false, &def_float, &def_float, &def_float }, - - { ".", "INDIRECT_F", 1, false, &def_object, &def_field, &def_float }, - { ".", "INDIRECT_V", 1, false, &def_object, &def_field, &def_vector }, - { ".", "INDIRECT_S", 1, false, &def_object, &def_field, &def_string }, - { ".", "INDIRECT_E", 1, false, &def_object, &def_field, &def_entity }, - { ".", "INDIRECT_BOOL", 1, false, &def_object, &def_field, &def_boolean }, - { ".", "INDIRECT_OBJ", 1, false, &def_object, &def_field, &def_object }, - - { ".", "ADDRESS", 1, false, &def_entity, &def_field, &def_pointer }, - - { ".", "EVENTCALL", 2, false, &def_entity, &def_function, &def_void }, - { ".", "OBJECTCALL", 2, false, &def_object, &def_function, &def_void }, - { ".", "SYSCALL", 2, false, &def_void, &def_function, &def_void }, - - { "=", "STORE_F", 6, true, &def_float, &def_float, &def_float }, - { "=", "STORE_V", 6, true, &def_vector, &def_vector, &def_vector }, - { "=", "STORE_S", 6, true, &def_string, &def_string, &def_string }, - { "=", "STORE_ENT", 6, true, &def_entity, &def_entity, &def_entity }, - { "=", "STORE_BOOL", 6, true, &def_boolean, &def_boolean, &def_boolean }, - { "=", "STORE_OBJENT", 6, true, &def_object, &def_entity, &def_object }, - { "=", "STORE_OBJ", 6, true, &def_object, &def_object, &def_object }, - { "=", "STORE_OBJENT", 6, true, &def_entity, &def_object, &def_object }, - - { "=", "STORE_FTOS", 6, true, &def_string, &def_float, &def_string }, - { "=", "STORE_BTOS", 6, true, &def_string, &def_boolean, &def_string }, - { "=", "STORE_VTOS", 6, true, &def_string, &def_vector, &def_string }, - { "=", "STORE_FTOBOOL", 6, true, &def_boolean, &def_float, &def_boolean }, - { "=", "STORE_BOOLTOF", 6, true, &def_float, &def_boolean, &def_float }, - - { "=", "STOREP_F", 6, true, &def_pointer, &def_float, &def_float }, - { "=", "STOREP_V", 6, true, &def_pointer, &def_vector, &def_vector }, - { "=", "STOREP_S", 6, true, &def_pointer, &def_string, &def_string }, - { "=", "STOREP_ENT", 6, true, &def_pointer, &def_entity, &def_entity }, - { "=", "STOREP_FLD", 6, true, &def_pointer, &def_field, &def_field }, - { "=", "STOREP_BOOL", 6, true, &def_pointer, &def_boolean, &def_boolean }, - { "=", "STOREP_OBJ", 6, true, &def_pointer, &def_object, &def_object }, - { "=", "STOREP_OBJENT", 6, true, &def_pointer, &def_object, &def_object }, - - { "<=>", "STOREP_FTOS", 6, true, &def_pointer, &def_float, &def_string }, - { "<=>", "STOREP_BTOS", 6, true, &def_pointer, &def_boolean, &def_string }, - { "<=>", "STOREP_VTOS", 6, true, &def_pointer, &def_vector, &def_string }, - { "<=>", "STOREP_FTOBOOL", 6, true, &def_pointer, &def_float, &def_boolean }, - { "<=>", "STOREP_BOOLTOF", 6, true, &def_pointer, &def_boolean, &def_float }, - - { "*=", "UMUL_F", 6, true, &def_float, &def_float, &def_void }, - { "*=", "UMUL_V", 6, true, &def_vector, &def_float, &def_void }, - { "/=", "UDIV_F", 6, true, &def_float, &def_float, &def_void }, - { "/=", "UDIV_V", 6, true, &def_vector, &def_float, &def_void }, - { "%=", "UMOD_F", 6, true, &def_float, &def_float, &def_void }, - { "+=", "UADD_F", 6, true, &def_float, &def_float, &def_void }, - { "+=", "UADD_V", 6, true, &def_vector, &def_vector, &def_void }, - { "-=", "USUB_F", 6, true, &def_float, &def_float, &def_void }, - { "-=", "USUB_V", 6, true, &def_vector, &def_vector, &def_void }, - { "&=", "UAND_F", 6, true, &def_float, &def_float, &def_void }, - { "|=", "UOR_F", 6, true, &def_float, &def_float, &def_void }, - - { "!", "NOT_BOOL", -1, false, &def_boolean, &def_void, &def_float }, - { "!", "NOT_F", -1, false, &def_float, &def_void, &def_float }, - { "!", "NOT_V", -1, false, &def_vector, &def_void, &def_float }, - { "!", "NOT_S", -1, false, &def_vector, &def_void, &def_float }, - { "!", "NOT_ENT", -1, false, &def_entity, &def_void, &def_float }, - - { "", "NEG_F", -1, false, &def_float, &def_void, &def_float }, - { "", "NEG_V", -1, false, &def_vector, &def_void, &def_vector }, - - { "int", "INT_F", -1, false, &def_float, &def_void, &def_float }, - - { "", "IF", -1, false, &def_float, &def_jumpoffset, &def_void }, - { "", "IFNOT", -1, false, &def_float, &def_jumpoffset, &def_void }, - - // calls returns REG_RETURN - { "", "CALL", -1, false, &def_function, &def_argsize, &def_void }, - { "", "THREAD", -1, false, &def_function, &def_argsize, &def_void }, - { "", "OBJTHREAD", -1, false, &def_function, &def_argsize, &def_void }, - - { "", "PUSH_F", -1, false, &def_float, &def_float, &def_void }, - { "", "PUSH_V", -1, false, &def_vector, &def_vector, &def_void }, - { "", "PUSH_S", -1, false, &def_string, &def_string, &def_void }, - { "", "PUSH_ENT", -1, false, &def_entity, &def_entity, &def_void }, - { "", "PUSH_OBJ", -1, false, &def_object, &def_object, &def_void }, - { "", "PUSH_OBJENT", -1, false, &def_entity, &def_object, &def_void }, - { "", "PUSH_FTOS", -1, false, &def_string, &def_float, &def_void }, - { "", "PUSH_BTOF", -1, false, &def_float, &def_boolean, &def_void }, - { "", "PUSH_FTOB", -1, false, &def_boolean, &def_float, &def_void }, - { "", "PUSH_VTOS", -1, false, &def_string, &def_vector, &def_void }, - { "", "PUSH_BTOS", -1, false, &def_string, &def_boolean, &def_void }, - - { "", "GOTO", -1, false, &def_jumpoffset, &def_void, &def_void }, - - { "&&", "AND", 7, false, &def_float, &def_float, &def_float }, - { "&&", "AND_BOOLF", 7, false, &def_boolean, &def_float, &def_float }, - { "&&", "AND_FBOOL", 7, false, &def_float, &def_boolean, &def_float }, - { "&&", "AND_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float }, - { "||", "OR", 7, false, &def_float, &def_float, &def_float }, - { "||", "OR_BOOLF", 7, false, &def_boolean, &def_float, &def_float }, - { "||", "OR_FBOOL", 7, false, &def_float, &def_boolean, &def_float }, - { "||", "OR_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float }, - - { "&", "BITAND", 3, false, &def_float, &def_float, &def_float }, - { "|", "BITOR", 3, false, &def_float, &def_float, &def_float }, - - { "", "BREAK", -1, false, &def_float, &def_void, &def_void }, - { "", "CONTINUE", -1, false, &def_float, &def_void, &def_void }, - - { NULL } -}; - -/* -================ -idCompiler::idCompiler() -================ -*/ -idCompiler::idCompiler() { - char **ptr; - int id; - - // make sure we have the right # of opcodes in the table - assert( ( sizeof( opcodes ) / sizeof( opcodes[ 0 ] ) ) == ( NUM_OPCODES + 1 ) ); - - eof = true; - parserPtr = &parser; - - callthread = false; - loopDepth = 0; - eof = false; - braceDepth = 0; - immediateType = NULL; - basetype = NULL; - currentLineNumber = 0; - currentFileNumber = 0; - errorCount = 0; - console = false; - scope = &def_namespace; - - memset( &immediate, 0, sizeof( immediate ) ); - memset( punctuationValid, 0, sizeof( punctuationValid ) ); - for( ptr = punctuation; *ptr != NULL; ptr++ ) { - id = parserPtr->GetPunctuationId( *ptr ); - if ( ( id >= 0 ) && ( id < 256 ) ) { - punctuationValid[ id ] = true; - } - } -} - -/* -============ -idCompiler::Error - -Aborts the current file load -============ -*/ -void idCompiler::Error( const char *message, ... ) const { - va_list argptr; - char string[ 1024 ]; - - va_start( argptr, message ); - vsprintf( string, message, argptr ); - va_end( argptr ); - - throw idCompileError( string ); -} - -/* -============ -idCompiler::Warning - -Prints a warning about the current line -============ -*/ -void idCompiler::Warning( const char *message, ... ) const { - va_list argptr; - char string[ 1024 ]; - - va_start( argptr, message ); - vsprintf( string, message, argptr ); - va_end( argptr ); - - parserPtr->Warning( "%s", string ); -} - -/* -============ -idCompiler::VirtualFunctionConstant - -Creates a def for an index into a virtual function table -============ -*/ -ID_INLINE idVarDef *idCompiler::VirtualFunctionConstant( idVarDef *func ) { - eval_t eval; - - memset( &eval, 0, sizeof( eval ) ); - eval._int = func->scope->TypeDef()->GetFunctionNumber( func->value.functionPtr ); - if ( eval._int < 0 ) { - Error( "Function '%s' not found in scope '%s'", func->Name(), func->scope->Name() ); - } - - return GetImmediate( &type_virtualfunction, &eval, "" ); -} - -/* -============ -idCompiler::SizeConstant - -Creates a def for a size constant -============ -*/ -ID_INLINE idVarDef *idCompiler::SizeConstant( int size ) { - eval_t eval; - - memset( &eval, 0, sizeof( eval ) ); - eval._int = size; - return GetImmediate( &type_argsize, &eval, "" ); -} - -/* -============ -idCompiler::JumpConstant - -Creates a def for a jump constant -============ -*/ -ID_INLINE idVarDef *idCompiler::JumpConstant( int value ) { - eval_t eval; - - memset( &eval, 0, sizeof( eval ) ); - eval._int = value; - return GetImmediate( &type_jumpoffset, &eval, "" ); -} - -/* -============ -idCompiler::JumpDef - -Creates a def for a relative jump from one code location to another -============ -*/ -ID_INLINE idVarDef *idCompiler::JumpDef( int jumpfrom, int jumpto ) { - return JumpConstant( jumpto - jumpfrom ); -} - -/* -============ -idCompiler::JumpTo - -Creates a def for a relative jump from current code location -============ -*/ -ID_INLINE idVarDef *idCompiler::JumpTo( int jumpto ) { - return JumpDef( gameLocal.program.NumStatements(), jumpto ); -} - -/* -============ -idCompiler::JumpFrom - -Creates a def for a relative jump from code location to current code location -============ -*/ -ID_INLINE idVarDef *idCompiler::JumpFrom( int jumpfrom ) { - return JumpDef( jumpfrom, gameLocal.program.NumStatements() ); -} - -/* -============ -idCompiler::Divide -============ -*/ -ID_INLINE float idCompiler::Divide( float numerator, float denominator ) { - if ( denominator == 0 ) { - Error( "Divide by zero" ); - return 0; - } - - return numerator / denominator; -} - -/* -============ -idCompiler::FindImmediate - -tries to find an existing immediate with the same value -============ -*/ -idVarDef *idCompiler::FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const { - idVarDef *def; - etype_t etype; - - etype = type->Type(); - - // check for a constant with the same value - for( def = gameLocal.program.GetDefList( "" ); def != NULL; def = def->Next() ) { - if ( def->TypeDef() != type ) { - continue; - } - - switch( etype ) { - case ev_field : - if ( *def->value.intPtr == eval->_int ) { - return def; - } - break; - - case ev_argsize : - if ( def->value.argSize == eval->_int ) { - return def; - } - break; - - case ev_jumpoffset : - if ( def->value.jumpOffset == eval->_int ) { - return def; - } - break; - - case ev_entity : - if ( *def->value.intPtr == eval->entity ) { - return def; - } - break; - - case ev_string : - if ( idStr::Cmp( def->value.stringPtr, string ) == 0 ) { - return def; - } - break; - - case ev_float : - if ( *def->value.floatPtr == eval->_float ) { - return def; - } - break; - - case ev_virtualfunction : - if ( def->value.virtualFunction == eval->_int ) { - return def; - } - break; - - - case ev_vector : - if ( ( def->value.vectorPtr->x == eval->vector[ 0 ] ) && - ( def->value.vectorPtr->y == eval->vector[ 1 ] ) && - ( def->value.vectorPtr->z == eval->vector[ 2 ] ) ) { - return def; - } - break; - - default : - Error( "weird immediate type" ); - break; - } - } - - return NULL; -} - -/* -============ -idCompiler::GetImmediate - -returns an existing immediate with the same value, or allocates a new one -============ -*/ -idVarDef *idCompiler::GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ) { - idVarDef *def; - - def = FindImmediate( type, eval, string ); - if ( def ) { - def->numUsers++; - } else { - // allocate a new def - def = gameLocal.program.AllocDef( type, "", &def_namespace, true ); - if ( type->Type() == ev_string ) { - def->SetString( string, true ); - } else { - def->SetValue( *eval, true ); - } - } - - return def; -} - -/* -============ -idCompiler::OptimizeOpcode - -try to optimize when the operator works on constants only -============ -*/ -idVarDef *idCompiler::OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { - eval_t c; - idTypeDef *type; - - if ( var_a && var_a->initialized != idVarDef::initializedConstant ) { - return NULL; - } - if ( var_b && var_b->initialized != idVarDef::initializedConstant ) { - return NULL; - } - - idVec3 &vec_c = *reinterpret_cast( &c.vector[ 0 ] ); - - memset( &c, 0, sizeof( c ) ); - switch( op - opcodes ) { - case OP_ADD_F: c._float = *var_a->value.floatPtr + *var_b->value.floatPtr; type = &type_float; break; - case OP_ADD_V: vec_c = *var_a->value.vectorPtr + *var_b->value.vectorPtr; type = &type_vector; break; - case OP_SUB_F: c._float = *var_a->value.floatPtr - *var_b->value.floatPtr; type = &type_float; break; - case OP_SUB_V: vec_c = *var_a->value.vectorPtr - *var_b->value.vectorPtr; type = &type_vector; break; - case OP_MUL_F: c._float = *var_a->value.floatPtr * *var_b->value.floatPtr; type = &type_float; break; - case OP_MUL_V: c._float = *var_a->value.vectorPtr * *var_b->value.vectorPtr; type = &type_float; break; - case OP_MUL_FV: vec_c = *var_b->value.vectorPtr * *var_a->value.floatPtr; type = &type_vector; break; - case OP_MUL_VF: vec_c = *var_a->value.vectorPtr * *var_b->value.floatPtr; type = &type_vector; break; - case OP_DIV_F: c._float = Divide( *var_a->value.floatPtr, *var_b->value.floatPtr ); type = &type_float; break; - case OP_MOD_F: c._float = (int)*var_a->value.floatPtr % (int)*var_b->value.floatPtr; type = &type_float; break; - case OP_BITAND: c._float = ( int )*var_a->value.floatPtr & ( int )*var_b->value.floatPtr; type = &type_float; break; - case OP_BITOR: c._float = ( int )*var_a->value.floatPtr | ( int )*var_b->value.floatPtr; type = &type_float; break; - case OP_GE: c._float = *var_a->value.floatPtr >= *var_b->value.floatPtr; type = &type_float; break; - case OP_LE: c._float = *var_a->value.floatPtr <= *var_b->value.floatPtr; type = &type_float; break; - case OP_GT: c._float = *var_a->value.floatPtr > *var_b->value.floatPtr; type = &type_float; break; - case OP_LT: c._float = *var_a->value.floatPtr < *var_b->value.floatPtr; type = &type_float; break; - case OP_AND: c._float = *var_a->value.floatPtr && *var_b->value.floatPtr; type = &type_float; break; - case OP_OR: c._float = *var_a->value.floatPtr || *var_b->value.floatPtr; type = &type_float; break; - case OP_NOT_BOOL: c._int = !*var_a->value.intPtr; type = &type_boolean; break; - case OP_NOT_F: c._float = !*var_a->value.floatPtr; type = &type_float; break; - case OP_NOT_V: c._float = !var_a->value.vectorPtr->x && !var_a->value.vectorPtr->y && !var_a->value.vectorPtr->z; type = &type_float; break; - case OP_NEG_F: c._float = -*var_a->value.floatPtr; type = &type_float; break; - case OP_NEG_V: vec_c = -*var_a->value.vectorPtr; type = &type_vector; break; - case OP_INT_F: c._float = ( int )*var_a->value.floatPtr; type = &type_float; break; - case OP_EQ_F: c._float = ( *var_a->value.floatPtr == *var_b->value.floatPtr ); type = &type_float; break; - case OP_EQ_V: c._float = var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; - case OP_EQ_E: c._float = ( *var_a->value.intPtr == *var_b->value.intPtr ); type = &type_float; break; - case OP_NE_F: c._float = ( *var_a->value.floatPtr != *var_b->value.floatPtr ); type = &type_float; break; - case OP_NE_V: c._float = !var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; - case OP_NE_E: c._float = ( *var_a->value.intPtr != *var_b->value.intPtr ); type = &type_float; break; - case OP_UADD_F: c._float = *var_b->value.floatPtr + *var_a->value.floatPtr; type = &type_float; break; - case OP_USUB_F: c._float = *var_b->value.floatPtr - *var_a->value.floatPtr; type = &type_float; break; - case OP_UMUL_F: c._float = *var_b->value.floatPtr * *var_a->value.floatPtr; type = &type_float; break; - case OP_UDIV_F: c._float = Divide( *var_b->value.floatPtr, *var_a->value.floatPtr ); type = &type_float; break; - case OP_UMOD_F: c._float = ( int ) *var_b->value.floatPtr % ( int )*var_a->value.floatPtr; type = &type_float; break; - case OP_UOR_F: c._float = ( int )*var_b->value.floatPtr | ( int )*var_a->value.floatPtr; type = &type_float; break; - case OP_UAND_F: c._float = ( int )*var_b->value.floatPtr & ( int )*var_a->value.floatPtr; type = &type_float; break; - case OP_UINC_F: c._float = *var_a->value.floatPtr + 1; type = &type_float; break; - case OP_UDEC_F: c._float = *var_a->value.floatPtr - 1; type = &type_float; break; - case OP_COMP_F: c._float = ( float )~( int )*var_a->value.floatPtr; type = &type_float; break; - default: type = NULL; break; - } - - if ( !type ) { - return NULL; - } - - if ( var_a ) { - var_a->numUsers--; - if ( var_a->numUsers <= 0 ) { - gameLocal.program.FreeDef( var_a, NULL ); - } - } - if ( var_b ) { - var_b->numUsers--; - if ( var_b->numUsers <= 0 ) { - gameLocal.program.FreeDef( var_b, NULL ); - } - } - - return GetImmediate( type, &c, "" ); -} - -/* -============ -idCompiler::EmitOpcode - -Emits a primitive statement, returning the var it places it's value in -============ -*/ -idVarDef *idCompiler::EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { - statement_t *statement; - idVarDef *var_c; - - var_c = OptimizeOpcode( op, var_a, var_b ); - if ( var_c ) { - return var_c; - } - - if ( var_a && !strcmp( var_a->Name(), RESULT_STRING ) ) { - var_a->numUsers++; - } - if ( var_b && !strcmp( var_b->Name(), RESULT_STRING ) ) { - var_b->numUsers++; - } - - statement = gameLocal.program.AllocStatement(); - statement->linenumber = currentLineNumber; - statement->file = currentFileNumber; - - if ( ( op->type_c == &def_void ) || op->rightAssociative ) { - // ifs, gotos, and assignments don't need vars allocated - var_c = NULL; - } else { - // allocate result space - // try to reuse result defs as much as possible - var_c = gameLocal.program.FindFreeResultDef( op->type_c->TypeDef(), RESULT_STRING, scope, var_a, var_b ); - // set user count back to 1, a result def needs to be used twice before it can be reused - var_c->numUsers = 1; - } - - statement->op = op - opcodes; - statement->a = var_a; - statement->b = var_b; - statement->c = var_c; - - if ( op->rightAssociative ) { - return var_a; - } - - return var_c; -} - -/* -============ -idCompiler::EmitOpcode - -Emits a primitive statement, returning the var it places it's value in -============ -*/ -ID_INLINE idVarDef *idCompiler::EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ) { - return EmitOpcode( &opcodes[ op ], var_a, var_b ); -} - -/* -============ -idCompiler::EmitPush - -Emits an opcode to push the variable onto the stack. -============ -*/ -bool idCompiler::EmitPush( idVarDef *expression, const idTypeDef *funcArg ) { - opcode_t *op; - opcode_t *out; - - out = NULL; - for( op = &opcodes[ OP_PUSH_F ]; op->name && !strcmp( op->name, "" ); op++ ) { - if ( ( funcArg->Type() == op->type_a->Type() ) && ( expression->Type() == op->type_b->Type() ) ) { - out = op; - break; - } - } - - if ( !out ) { - if ( ( expression->TypeDef() != funcArg ) && !expression->TypeDef()->Inherits( funcArg ) ) { - return false; - } - - out = &opcodes[ OP_PUSH_ENT ]; - } - - EmitOpcode( out, expression, 0 ); - - return true; -} - -/* -============== -idCompiler::NextToken - -Sets token, immediateType, and possibly immediate -============== -*/ -void idCompiler::NextToken( void ) { - int i; - - // reset our type - immediateType = NULL; - memset( &immediate, 0, sizeof( immediate ) ); - - // Save the token's line number and filename since when we emit opcodes the current - // token is always the next one to be read - currentLineNumber = token.line; - const char* currentFileName = parserPtr->GetFileName(); - currentFileNumber = gameLocal.program.GetFilenum( currentFileName ); - - if ( !parserPtr->ReadToken( &token ) ) { - eof = true; - return; - } - - if ( currentFileNumber != gameLocal.program.GetFilenum( parserPtr->GetFileName() ) ) { - if ( ( braceDepth > 0 ) && ( token != "}" ) ) { - // missing a closing brace. try to give as much info as possible. - if ( scope->Type() == ev_function ) { - Error( "Unexpected end of file inside function '%s'. Missing closing braces.", scope->Name() ); - } else if ( scope->Type() == ev_object ) { - Error( "Unexpected end of file inside object '%s'. Missing closing braces.", scope->Name() ); - } else if ( scope->Type() == ev_namespace ) { - Error( "Unexpected end of file inside namespace '%s'. Missing closing braces.", scope->Name() ); - } else { - Error( "Unexpected end of file inside braced section" ); - } - } - } - - switch( token.type ) { - case TT_STRING: - // handle quoted strings as a unit - immediateType = &type_string; - return; - - case TT_LITERAL: { - // handle quoted vectors as a unit - immediateType = &type_vector; - idLexer lex( token, token.Length(), parserPtr->GetFileName(), LEXFL_NOERRORS ); - idToken token2; - for( i = 0; i < 3; i++ ) { - if ( !lex.ReadToken( &token2 ) ) { - Error( "Couldn't read vector. '%s' is not in the form of 'x y z'", token.c_str() ); - } - if ( token2.type == TT_PUNCTUATION && token2 == "-" ) { - if ( !lex.CheckTokenType( TT_NUMBER, 0, &token2 ) ) { - Error( "expected a number following '-' but found '%s' in vector '%s'", token2.c_str(), token.c_str() ); - } - immediate.vector[ i ] = -token2.GetFloatValue(); - } else if ( token2.type == TT_NUMBER ) { - immediate.vector[ i ] = token2.GetFloatValue(); - } else { - Error( "vector '%s' is not in the form of 'x y z'. expected float value, found '%s'", token.c_str(), token2.c_str() ); - } - } - return; - } - - case TT_NUMBER: - immediateType = &type_float; - immediate._float = token.GetFloatValue(); - return; - - case TT_PUNCTUATION: - // entity names - if ( token == "$" ) { - immediateType = &type_entity; - parserPtr->ReadToken( &token ); - return; - } - - if ( token == "{" ) { - braceDepth++; - return; - } - - if ( token == "}" ) { - braceDepth--; - return; - } - - if ( punctuationValid[ token.subtype ] ) { - return; - } - - Error( "Unknown punctuation '%s' on line %i, file '%s'", token.c_str(), currentLineNumber, currentFileName ); - break; - - case TT_NAME: - return; - - default: - Error( "Unknown token '%s' on line %i, file '%s'", token.c_str(), currentLineNumber, currentFileName ); - } -} - -/* -============= -idCompiler::ExpectToken - -Issues an Error if the current token isn't equal to string -Gets the next token -============= -*/ -void idCompiler::ExpectToken( const char *string ) { - if ( token != string ) { - Error( "expected '%s', found '%s'", string, token.c_str() ); - } - - NextToken(); -} - -/* -============= -idCompiler::CheckToken - -Returns true and gets the next token if the current token equals string -Returns false and does nothing otherwise -============= -*/ -bool idCompiler::CheckToken( const char *string ) { - if ( token != string ) { - return false; - } - - NextToken(); - - return true; -} - -/* -============ -idCompiler::ParseName - -Checks to see if the current token is a valid name -============ -*/ -void idCompiler::ParseName( idStr &name ) { - if ( token.type != TT_NAME ) { - Error( "'%s' is not a name", token.c_str() ); - } - - name = token; - NextToken(); -} - -/* -============ -idCompiler::SkipOutOfFunction - -For error recovery, pops out of nested braces -============ -*/ -void idCompiler::SkipOutOfFunction( void ) { - while( braceDepth ) { - parserPtr->SkipBracedSection( false ); - braceDepth--; - } - NextToken(); -} - -/* -============ -idCompiler::SkipToSemicolon - -For error recovery -============ -*/ -void idCompiler::SkipToSemicolon( void ) { - do { - if ( CheckToken( ";" ) ) { - return; - } - - NextToken(); - } while( !eof ); -} - -/* -============ -idCompiler::CheckType - -Parses a variable type, including functions types -============ -*/ -idTypeDef *idCompiler::CheckType( void ) { - idTypeDef *type; - - if ( token == "float" ) { - type = &type_float; - } else if ( token == "vector" ) { - type = &type_vector; - } else if ( token == "entity" ) { - type = &type_entity; - } else if ( token == "string" ) { - type = &type_string; - } else if ( token == "void" ) { - type = &type_void; - } else if ( token == "object" ) { - type = &type_object; - } else if ( token == "boolean" ) { - type = &type_boolean; - } else if ( token == "namespace" ) { - type = &type_namespace; - } else if ( token == "scriptEvent" ) { - type = &type_scriptevent; - } else { - type = gameLocal.program.FindType( token.c_str() ); - if ( type && !type->Inherits( &type_object ) ) { - type = NULL; - } - } - - return type; -} - -/* -============ -idCompiler::ParseType - -Parses a variable type, including functions types -============ -*/ -idTypeDef *idCompiler::ParseType( void ) { - idTypeDef *type; - - type = CheckType(); - if ( !type ) { - Error( "\"%s\" is not a type", token.c_str() ); - } - - if ( ( type == &type_scriptevent ) && ( scope != &def_namespace ) ) { - Error( "scriptEvents can only defined in the global namespace" ); - } - - if ( ( type == &type_namespace ) && ( scope->Type() != ev_namespace ) ) { - Error( "A namespace may only be defined globally, or within another namespace" ); - } - - NextToken(); - - return type; -} - -/* -============ -idCompiler::ParseImmediate - -Looks for a preexisting constant -============ -*/ -idVarDef *idCompiler::ParseImmediate( void ) { - idVarDef *def; - - def = GetImmediate( immediateType, &immediate, token.c_str() ); - NextToken(); - - return def; -} - -/* -============ -idCompiler::EmitFunctionParms -============ -*/ -idVarDef *idCompiler::EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ) { - idVarDef *e; - const idTypeDef *type; - const idTypeDef *funcArg; - idVarDef *returnDef; - idTypeDef *returnType; - int arg; - int size; - int resultOp; - - type = func->TypeDef(); - if ( func->Type() != ev_function ) { - Error( "'%s' is not a function", func->Name() ); - } - - // copy the parameters to the global parameter variables - arg = startarg; - size = startsize; - if ( !CheckToken( ")" ) ) { - do { - if ( arg >= type->NumParameters() ) { - Error( "too many parameters" ); - } - - e = GetExpression( TOP_PRIORITY ); - - funcArg = type->GetParmType( arg ); - if ( !EmitPush( e, funcArg ) ) { - Error( "type mismatch on parm %i of call to '%s'", arg + 1, func->Name() ); - } - - if ( funcArg->Type() == ev_object ) { - size += type_object.Size(); - } else { - size += funcArg->Size(); - } - - arg++; - } while( CheckToken( "," ) ); - - ExpectToken( ")" ); - } - - if ( arg < type->NumParameters() ) { - Error( "too few parameters for function '%s'", func->Name() ); - } - - if ( op == OP_CALL ) { - EmitOpcode( op, func, 0 ); - } else if ( ( op == OP_OBJECTCALL ) || ( op == OP_OBJTHREAD ) ) { - EmitOpcode( op, object, VirtualFunctionConstant( func ) ); - - // need arg size seperate since script object may be NULL - statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); - statement.c = SizeConstant( func->value.functionPtr->parmTotal ); - } else { - EmitOpcode( op, func, SizeConstant( size ) ); - } - - // we need to copy off the result into a temporary result location, so figure out the opcode - returnType = type->ReturnType(); - if ( returnType->Type() == ev_string ) { - resultOp = OP_STORE_S; - returnDef = gameLocal.program.returnStringDef; - } else { - gameLocal.program.returnDef->SetTypeDef( returnType ); - returnDef = gameLocal.program.returnDef; - - switch( returnType->Type() ) { - case ev_void : - resultOp = OP_STORE_F; - break; - - case ev_boolean : - resultOp = OP_STORE_BOOL; - break; - - case ev_float : - resultOp = OP_STORE_F; - break; - - case ev_vector : - resultOp = OP_STORE_V; - break; - - case ev_entity : - resultOp = OP_STORE_ENT; - break; - - case ev_object : - resultOp = OP_STORE_OBJ; - break; - - default : - Error( "Invalid return type for function '%s'", func->Name() ); - // shut up compiler - resultOp = OP_STORE_OBJ; - break; - } - } - - if ( returnType->Type() == ev_void ) { - // don't need result space since there's no result, so just return the normal result def. - return returnDef; - } - - // allocate result space - // try to reuse result defs as much as possible - statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); - idVarDef *resultDef = gameLocal.program.FindFreeResultDef( returnType, RESULT_STRING, scope, statement.a, statement.b ); - // set user count back to 0, a result def needs to be used twice before it can be reused - resultDef->numUsers = 0; - - EmitOpcode( resultOp, returnDef, resultDef ); - - return resultDef; -} - -/* -============ -idCompiler::ParseFunctionCall -============ -*/ -idVarDef *idCompiler::ParseFunctionCall( idVarDef *funcDef ) { - assert( funcDef ); - - if ( funcDef->Type() != ev_function ) { - Error( "'%s' is not a function", funcDef->Name() ); - } - - if ( funcDef->initialized == idVarDef::uninitialized ) { - Error( "Function '%s' has not been defined yet", funcDef->GlobalName() ); - } - - assert( funcDef->value.functionPtr ); - if ( callthread ) { - if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) { - Error( "Built-in functions cannot be called as threads" ); - } - callthread = false; - return EmitFunctionParms( OP_THREAD, funcDef, 0, 0, NULL ); - } else { - if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) { - if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) { - // get the local object pointer - idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope ); - if ( !thisdef ) { - Error( "No 'self' within scope" ); - } - - return ParseEventCall( thisdef, funcDef ); - } else { - Error( "Built-in functions cannot be called without an object" ); - } - } - - return EmitFunctionParms( OP_CALL, funcDef, 0, 0, NULL ); - } -} - -/* -============ -idCompiler::ParseObjectCall -============ -*/ -idVarDef *idCompiler::ParseObjectCall( idVarDef *object, idVarDef *func ) { - EmitPush( object, object->TypeDef() ); - if ( callthread ) { - callthread = false; - return EmitFunctionParms( OP_OBJTHREAD, func, 1, type_object.Size(), object ); - } else { - return EmitFunctionParms( OP_OBJECTCALL, func, 1, 0, object ); - } -} - -/* -============ -idCompiler::ParseEventCall -============ -*/ -idVarDef *idCompiler::ParseEventCall( idVarDef *object, idVarDef *funcDef ) { - if ( callthread ) { - Error( "Cannot call built-in functions as a thread" ); - } - - if ( funcDef->Type() != ev_function ) { - Error( "'%s' is not a function", funcDef->Name() ); - } - - if ( !funcDef->value.functionPtr->eventdef ) { - Error( "\"%s\" cannot be called with object notation", funcDef->Name() ); - } - - if ( object->Type() == ev_object ) { - EmitPush( object, &type_entity ); - } else { - EmitPush( object, object->TypeDef() ); - } - - return EmitFunctionParms( OP_EVENTCALL, funcDef, 0, type_object.Size(), NULL ); -} - -/* -============ -idCompiler::ParseSysObjectCall -============ -*/ -idVarDef *idCompiler::ParseSysObjectCall( idVarDef *funcDef ) { - if ( callthread ) { - Error( "Cannot call built-in functions as a thread" ); - } - - if ( funcDef->Type() != ev_function ) { - Error( "'%s' is not a function", funcDef->Name() ); - } - - if ( !funcDef->value.functionPtr->eventdef ) { - Error( "\"%s\" cannot be called with object notation", funcDef->Name() ); - } - - if ( !idThread::Type.RespondsTo( *funcDef->value.functionPtr->eventdef ) ) { - Error( "\"%s\" is not callable as a 'sys' function", funcDef->Name() ); - } - - return EmitFunctionParms( OP_SYSCALL, funcDef, 0, 0, NULL ); -} - -/* -============ -idCompiler::LookupDef -============ -*/ -idVarDef *idCompiler::LookupDef( const char *name, const idVarDef *baseobj ) { - idVarDef *def; - idVarDef *field; - etype_t type_b; - etype_t type_c; - opcode_t *op; - - // check if we're accessing a field - if ( baseobj && ( baseobj->Type() == ev_object ) ) { - const idVarDef *tdef; - - def = NULL; - for( tdef = baseobj; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) { - def = gameLocal.program.GetDef( NULL, name, tdef ); - if ( def ) { - break; - } - } - } else { - // first look through the defs in our scope - def = gameLocal.program.GetDef( NULL, name, scope ); - if ( !def ) { - // if we're in a member function, check types local to the object - if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) { - // get the local object pointer - idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope ); - - field = LookupDef( name, scope->scope->TypeDef()->def ); - if ( !field ) { - Error( "Unknown value \"%s\"", name ); - } - - // type check - type_b = field->Type(); - if ( field->Type() == ev_function ) { - type_c = field->TypeDef()->ReturnType()->Type(); - } else { - type_c = field->TypeDef()->FieldType()->Type(); // field access gets type from field - if ( CheckToken( "++" ) ) { - if ( type_c != ev_float ) { - Error( "Invalid type for ++" ); - } - def = EmitOpcode( OP_UINCP_F, thisdef, field ); - return def; - } else if ( CheckToken( "--" ) ) { - if ( type_c != ev_float ) { - Error( "Invalid type for --" ); - } - def = EmitOpcode( OP_UDECP_F, thisdef, field ); - return def; - } - } - - op = &opcodes[ OP_INDIRECT_F ]; - while( ( op->type_a->Type() != ev_object ) - || ( type_b != op->type_b->Type() ) || ( type_c != op->type_c->Type() ) ) { - if ( ( op->priority == FUNCTION_PRIORITY ) && ( op->type_a->Type() == ev_object ) && ( op->type_c->Type() == ev_void ) && - ( type_c != op->type_c->Type() ) ) { - // catches object calls that return a value - break; - } - op++; - if ( !op->name || strcmp( op->name, "." ) ) { - Error( "no valid opcode to access type '%s'", field->TypeDef()->SuperClass()->Name() ); - } - } - - if ( ( op - opcodes ) == OP_OBJECTCALL ) { - ExpectToken( "(" ); - def = ParseObjectCall( thisdef, field ); - } else { - // emit the conversion opcode - def = EmitOpcode( op, thisdef, field ); - - // field access gets type from field - def->SetTypeDef( field->TypeDef()->FieldType() ); - } - } - } - } - - return def; -} - -/* -============ -idCompiler::ParseValue - -Returns the def for the current token -============ -*/ -idVarDef *idCompiler::ParseValue( void ) { - idVarDef *def; - idVarDef *namespaceDef; - idStr name; - - if ( immediateType == &type_entity ) { - // if an immediate entity ($-prefaced name) then create or lookup a def for it. - // when entities are spawned, they'll lookup the def and point it to them. - def = gameLocal.program.GetDef( &type_entity, "$" + token, &def_namespace ); - if ( !def ) { - def = gameLocal.program.AllocDef( &type_entity, "$" + token, &def_namespace, true ); - } - NextToken(); - return def; - } else if ( immediateType ) { - // if the token is an immediate, allocate a constant for it - return ParseImmediate(); - } - - ParseName( name ); - def = LookupDef( name, basetype ); - if ( !def ) { - if ( basetype ) { - Error( "%s is not a member of %s", name.c_str(), basetype->TypeDef()->Name() ); - } else { - Error( "Unknown value \"%s\"", name.c_str() ); - } - // if namespace, then look up the variable in that namespace - } else if ( def->Type() == ev_namespace ) { - while( def->Type() == ev_namespace ) { - ExpectToken( "::" ); - ParseName( name ); - namespaceDef = def; - def = gameLocal.program.GetDef( NULL, name, namespaceDef ); - if ( !def ) { - Error( "Unknown value \"%s::%s\"", namespaceDef->GlobalName(), name.c_str() ); - } - } - //def = LookupDef( name, basetype ); - } - - return def; -} - -/* -============ -idCompiler::GetTerm -============ -*/ -idVarDef *idCompiler::GetTerm( void ) { - idVarDef *e; - int op; - - if ( !immediateType && CheckToken( "~" ) ) { - e = GetExpression( TILDE_PRIORITY ); - switch( e->Type() ) { - case ev_float : - op = OP_COMP_F; - break; - - default : - Error( "type mismatch for ~" ); - - // shut up compiler - op = OP_COMP_F; - break; - } - - return EmitOpcode( op, e, 0 ); - } - - if ( !immediateType && CheckToken( "!" ) ) { - e = GetExpression( NOT_PRIORITY ); - switch( e->Type() ) { - case ev_boolean : - op = OP_NOT_BOOL; - break; - - case ev_float : - op = OP_NOT_F; - break; - - case ev_string : - op = OP_NOT_S; - break; - - case ev_vector : - op = OP_NOT_V; - break; - - case ev_entity : - op = OP_NOT_ENT; - break; - - case ev_function : - Error( "Invalid type for !" ); - - // shut up compiler - op = OP_NOT_F; - break; - - case ev_object : - op = OP_NOT_ENT; - break; - - default : - Error( "type mismatch for !" ); - - // shut up compiler - op = OP_NOT_F; - break; - } - - return EmitOpcode( op, e, 0 ); - } - - // check for negation operator - if ( !immediateType && CheckToken( "-" ) ) { - // constants are directly negated without an instruction - if ( immediateType == &type_float ) { - immediate._float = -immediate._float; - return ParseImmediate(); - } else if ( immediateType == &type_vector ) { - immediate.vector[0] = -immediate.vector[0]; - immediate.vector[1] = -immediate.vector[1]; - immediate.vector[2] = -immediate.vector[2]; - return ParseImmediate(); - } else { - e = GetExpression( NOT_PRIORITY ); - switch( e->Type() ) { - case ev_float : - op = OP_NEG_F; - break; - - case ev_vector : - op = OP_NEG_V; - break; - default : - Error( "type mismatch for -" ); - - // shut up compiler - op = OP_NEG_F; - break; - } - return EmitOpcode( &opcodes[ op ], e, 0 ); - } - } - - if ( CheckToken( "int" ) ) { - ExpectToken( "(" ); - - e = GetExpression( INT_PRIORITY ); - if ( e->Type() != ev_float ) { - Error( "type mismatch for int()" ); - } - - ExpectToken( ")" ); - - return EmitOpcode( OP_INT_F, e, 0 ); - } - - if ( CheckToken( "thread" ) ) { - callthread = true; - e = GetExpression( FUNCTION_PRIORITY ); - - if ( callthread ) { - Error( "Invalid thread call" ); - } - - // threads return the thread number - gameLocal.program.returnDef->SetTypeDef( &type_float ); - return gameLocal.program.returnDef; - } - - if ( !immediateType && CheckToken( "(" ) ) { - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ")" ); - - return e; - } - - return ParseValue(); -} - -/* -============== -idCompiler::TypeMatches -============== -*/ -bool idCompiler::TypeMatches( etype_t type1, etype_t type2 ) const { - if ( type1 == type2 ) { - return true; - } - - //if ( ( type1 == ev_entity ) && ( type2 == ev_object ) ) { - // return true; - //} - - //if ( ( type2 == ev_entity ) && ( type1 == ev_object ) ) { - // return true; - //} - - return false; -} - -/* -============== -idCompiler::GetExpression -============== -*/ -idVarDef *idCompiler::GetExpression( int priority ) { - opcode_t *op; - opcode_t *oldop; - idVarDef *e; - idVarDef *e2; - const idVarDef *oldtype; - etype_t type_a; - etype_t type_b; - etype_t type_c; - - if ( priority == 0 ) { - return GetTerm(); - } - - e = GetExpression( priority - 1 ); - if ( token == ";" ) { - // save us from searching through the opcodes unneccesarily - return e; - } - - while( 1 ) { - if ( ( priority == FUNCTION_PRIORITY ) && CheckToken( "(" ) ) { - return ParseFunctionCall( e ); - } - - // has to be a punctuation - if ( immediateType ) { - break; - } - - for( op = opcodes; op->name; op++ ) { - if ( ( op->priority == priority ) && CheckToken( op->name ) ) { - break; - } - } - - if ( !op->name ) { - // next token isn't at this priority level - break; - } - - // unary operators act only on the left operand - if ( op->type_b == &def_void ) { - e = EmitOpcode( op, e, 0 ); - return e; - } - - // preserve our base type - oldtype = basetype; - - // field access needs scope from object - if ( ( op->name[ 0 ] == '.' ) && e->TypeDef()->Inherits( &type_object ) ) { - // save off what type this field is part of - basetype = e->TypeDef()->def; - } - - if ( op->rightAssociative ) { - // if last statement is an indirect, change it to an address of - if ( gameLocal.program.NumStatements() > 0 ) { - statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); - if ( ( statement.op >= OP_INDIRECT_F ) && ( statement.op < OP_ADDRESS ) ) { - statement.op = OP_ADDRESS; - type_pointer.SetPointerType( e->TypeDef() ); - e->SetTypeDef( &type_pointer ); - } - } - - e2 = GetExpression( priority ); - } else { - e2 = GetExpression( priority - 1 ); - } - - // restore type - basetype = oldtype; - - // type check - type_a = e->Type(); - type_b = e2->Type(); - - // field access gets type from field - if ( op->name[ 0 ] == '.' ) { - if ( ( e2->Type() == ev_function ) && e2->TypeDef()->ReturnType() ) { - type_c = e2->TypeDef()->ReturnType()->Type(); - } else if ( e2->TypeDef()->FieldType() ) { - type_c = e2->TypeDef()->FieldType()->Type(); - } else { - // not a field - type_c = ev_error; - } - } else { - type_c = ev_void; - } - - oldop = op; - while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) || - ( ( type_c != ev_void ) && !TypeMatches( type_c, op->type_c->Type() ) ) ) { - if ( ( op->priority == FUNCTION_PRIORITY ) && TypeMatches( type_a, op->type_a->Type() ) && TypeMatches( type_b, op->type_b->Type() ) ) { - break; - } - - op++; - if ( !op->name || strcmp( op->name, oldop->name ) ) { - Error( "type mismatch for '%s'", oldop->name ); - } - } - - switch( op - opcodes ) { - case OP_SYSCALL : - ExpectToken( "(" ); - e = ParseSysObjectCall( e2 ); - break; - - case OP_OBJECTCALL : - ExpectToken( "(" ); - if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) { - e = ParseEventCall( e, e2 ); - } else { - e = ParseObjectCall( e, e2 ); - } - break; - - case OP_EVENTCALL : - ExpectToken( "(" ); - if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) { - e = ParseEventCall( e, e2 ); - } else { - e = ParseObjectCall( e, e2 ); - } - break; - - default: - if ( callthread ) { - Error( "Expecting function call after 'thread'" ); - } - - if ( ( type_a == ev_pointer ) && ( type_b != e->TypeDef()->PointerType()->Type() ) ) { - // FIXME: need to make a general case for this - if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_boolean ) ) { - // copy from float to boolean pointer - op = &opcodes[ OP_STOREP_FTOBOOL ]; - } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_float ) ) { - // copy from boolean to float pointer - op = &opcodes[ OP_STOREP_BOOLTOF ]; - } else if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { - // copy from float to string pointer - op = &opcodes[ OP_STOREP_FTOS ]; - } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { - // copy from boolean to string pointer - op = &opcodes[ OP_STOREP_BTOS ]; - } else if ( ( op - opcodes == OP_STOREP_V ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) { - // copy from vector to string pointer - op = &opcodes[ OP_STOREP_VTOS ]; - } else if ( ( op - opcodes == OP_STOREP_ENT ) && ( e->TypeDef()->PointerType()->Type() == ev_object ) ) { - // store an entity into an object pointer - op = &opcodes[ OP_STOREP_OBJENT ]; - } else { - Error( "type mismatch for '%s'", op->name ); - } - } - - if ( op->rightAssociative ) { - e = EmitOpcode( op, e2, e ); - } else { - e = EmitOpcode( op, e, e2 ); - } - - if ( op - opcodes == OP_STOREP_OBJENT ) { - // statement.b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in statement.c - // so that we can do a type check during run time since we don't know what type the script object is at compile time because it - // comes from an entity - statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ); - statement.c = type_pointer.PointerType()->def; - } - - // field access gets type from field - if ( type_c != ev_void ) { - e->SetTypeDef( e2->TypeDef()->FieldType() ); - } - break; - } - } - - return e; -} - -/* -================ -idCompiler::PatchLoop -================ -*/ -void idCompiler::PatchLoop( int start, int continuePos ) { - int i; - statement_t *pos; - - pos = &gameLocal.program.GetStatement( start ); - for( i = start; i < gameLocal.program.NumStatements(); i++, pos++ ) { - if ( pos->op == OP_BREAK ) { - pos->op = OP_GOTO; - pos->a = JumpFrom( i ); - } else if ( pos->op == OP_CONTINUE ) { - pos->op = OP_GOTO; - pos->a = JumpDef( i, continuePos ); - } - } -} - -/* -================ -idCompiler::ParseReturnStatement -================ -*/ -void idCompiler::ParseReturnStatement( void ) { - idVarDef *e; - etype_t type_a; - etype_t type_b; - opcode_t *op; - - if ( CheckToken( ";" ) ) { - if ( scope->TypeDef()->ReturnType()->Type() != ev_void ) { - Error( "expecting return value" ); - } - - EmitOpcode( OP_RETURN, 0, 0 ); - return; - } - - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ";" ); - - type_a = e->Type(); - type_b = scope->TypeDef()->ReturnType()->Type(); - - if ( TypeMatches( type_a, type_b ) ) { - EmitOpcode( OP_RETURN, e, 0 ); - return; - } - - for( op = opcodes; op->name; op++ ) { - if ( !strcmp( op->name, "=" ) ) { - break; - } - } - - assert( op->name ); - - while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) ) { - op++; - if ( !op->name || strcmp( op->name, "=" ) ) { - Error( "type mismatch for return value" ); - } - } - - idTypeDef *returnType = scope->TypeDef()->ReturnType(); - if ( returnType->Type() == ev_string ) { - EmitOpcode( op, e, gameLocal.program.returnStringDef ); - } else { - gameLocal.program.returnDef->SetTypeDef( returnType ); - EmitOpcode( op, e, gameLocal.program.returnDef ); - } - EmitOpcode( OP_RETURN, 0, 0 ); -} - -/* -================ -idCompiler::ParseWhileStatement -================ -*/ -void idCompiler::ParseWhileStatement( void ) { - idVarDef *e; - int patch1; - int patch2; - - loopDepth++; - - ExpectToken( "(" ); - - patch2 = gameLocal.program.NumStatements(); - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ")" ); - - if ( ( e->initialized == idVarDef::initializedConstant ) && ( *e->value.intPtr != 0 ) ) { - //FIXME: we can completely skip generation of this code in the opposite case - ParseStatement(); - EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); - } else { - patch1 = gameLocal.program.NumStatements(); - EmitOpcode( OP_IFNOT, e, 0 ); - ParseStatement(); - EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); - gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); - } - - // fixup breaks and continues - PatchLoop( patch2, patch2 ); - - loopDepth--; -} - -/* -================ -idCompiler::ParseForStatement - -Form of for statement with a counter: - - a = 0; -start: << patch4 - if ( !( a < 10 ) ) { - goto end; << patch1 - } else { - goto process; << patch3 - } - -increment: << patch2 - a = a + 1; - goto start; << goto patch4 - -process: - statements; - goto increment; << goto patch2 - -end: - -Form of for statement without a counter: - - a = 0; -start: << patch2 - if ( !( a < 10 ) ) { - goto end; << patch1 - } - -process: - statements; - goto start; << goto patch2 - -end: -================ -*/ -void idCompiler::ParseForStatement( void ) { - idVarDef *e; - int start; - int patch1; - int patch2; - int patch3; - int patch4; - - loopDepth++; - - start = gameLocal.program.NumStatements(); - - ExpectToken( "(" ); - - // init - if ( !CheckToken( ";" ) ) { - do { - GetExpression( TOP_PRIORITY ); - } while( CheckToken( "," ) ); - - ExpectToken( ";" ); - } - - // condition - patch2 = gameLocal.program.NumStatements(); - - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ";" ); - - //FIXME: add check for constant expression - patch1 = gameLocal.program.NumStatements(); - EmitOpcode( OP_IFNOT, e, 0 ); - - // counter - if ( !CheckToken( ")" ) ) { - patch3 = gameLocal.program.NumStatements(); - EmitOpcode( OP_IF, e, 0 ); - - patch4 = patch2; - patch2 = gameLocal.program.NumStatements(); - do { - GetExpression( TOP_PRIORITY ); - } while( CheckToken( "," ) ); - - ExpectToken( ")" ); - - // goto patch4 - EmitOpcode( OP_GOTO, JumpTo( patch4 ), 0 ); - - // fixup patch3 - gameLocal.program.GetStatement( patch3 ).b = JumpFrom( patch3 ); - } - - ParseStatement(); - - // goto patch2 - EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 ); - - // fixup patch1 - gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); - - // fixup breaks and continues - PatchLoop( start, patch2 ); - - loopDepth--; -} - -/* -================ -idCompiler::ParseDoWhileStatement -================ -*/ -void idCompiler::ParseDoWhileStatement( void ) { - idVarDef *e; - int patch1; - - loopDepth++; - - patch1 = gameLocal.program.NumStatements(); - ParseStatement(); - ExpectToken( "while" ); - ExpectToken( "(" ); - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ")" ); - ExpectToken( ";" ); - - EmitOpcode( OP_IF, e, JumpTo( patch1 ) ); - - // fixup breaks and continues - PatchLoop( patch1, patch1 ); - - loopDepth--; -} - -/* -================ -idCompiler::ParseIfStatement -================ -*/ -void idCompiler::ParseIfStatement( void ) { - idVarDef *e; - int patch1; - int patch2; - - ExpectToken( "(" ); - e = GetExpression( TOP_PRIORITY ); - ExpectToken( ")" ); - - //FIXME: add check for constant expression - patch1 = gameLocal.program.NumStatements(); - EmitOpcode( OP_IFNOT, e, 0 ); - - ParseStatement(); - - if ( CheckToken( "else" ) ) { - patch2 = gameLocal.program.NumStatements(); - EmitOpcode( OP_GOTO, 0, 0 ); - gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); - ParseStatement(); - gameLocal.program.GetStatement( patch2 ).a = JumpFrom( patch2 ); - } else { - gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 ); - } -} - -/* -============ -idCompiler::ParseStatement -============ -*/ -void idCompiler::ParseStatement( void ) { - if ( CheckToken( ";" ) ) { - // skip semicolons, which are harmless and ok syntax - return; - } - - if ( CheckToken( "{" ) ) { - do { - ParseStatement(); - } while( !CheckToken( "}" ) ); - - return; - } - - if ( CheckToken( "return" ) ) { - ParseReturnStatement(); - return; - } - - if ( CheckToken( "while" ) ) { - ParseWhileStatement(); - return; - } - - if ( CheckToken( "for" ) ) { - ParseForStatement(); - return; - } - - if ( CheckToken( "do" ) ) { - ParseDoWhileStatement(); - return; - } - - if ( CheckToken( "break" ) ) { - ExpectToken( ";" ); - if ( !loopDepth ) { - Error( "cannot break outside of a loop" ); - } - EmitOpcode( OP_BREAK, 0, 0 ); - return; - } - - if ( CheckToken( "continue" ) ) { - ExpectToken( ";" ); - if ( !loopDepth ) { - Error( "cannot contine outside of a loop" ); - } - EmitOpcode( OP_CONTINUE, 0, 0 ); - return; - } - - if ( CheckType() != NULL ) { - ParseDefs(); - return; - } - - if ( CheckToken( "if" ) ) { - ParseIfStatement(); - return; - } - - GetExpression( TOP_PRIORITY ); - ExpectToken(";"); -} - -/* -================ -idCompiler::ParseObjectDef -================ -*/ -void idCompiler::ParseObjectDef( const char *objname ) { - idTypeDef *objtype; - idTypeDef *type; - idTypeDef *parentType; - idTypeDef *fieldtype; - idStr name; - const char *fieldname; - idTypeDef newtype( ev_field, NULL, "", 0, NULL ); - idVarDef *oldscope; - int num; - int i; - - oldscope = scope; - if ( scope->Type() != ev_namespace ) { - Error( "Objects cannot be defined within functions or other objects" ); - } - - // make sure it doesn't exist before we create it - if ( gameLocal.program.FindType( objname ) != NULL ) { - Error( "'%s' : redefinition; different basic types", objname ); - } - - // base type - if ( !CheckToken( ":" ) ) { - parentType = &type_object; - } else { - parentType = ParseType(); - if ( !parentType->Inherits( &type_object ) ) { - Error( "Objects may only inherit from objects." ); - } - } - - objtype = gameLocal.program.AllocType( ev_object, NULL, objname, parentType == &type_object ? 0 : parentType->Size(), parentType ); - objtype->def = gameLocal.program.AllocDef( objtype, objname, scope, true ); - scope = objtype->def; - - // inherit all the functions - num = parentType->NumFunctions(); - for( i = 0; i < parentType->NumFunctions(); i++ ) { - const function_t *func = parentType->GetFunction( i ); - objtype->AddFunction( func ); - } - - ExpectToken( "{" ); - - do { - if ( CheckToken( ";" ) ) { - // skip semicolons, which are harmless and ok syntax - continue; - } - - fieldtype = ParseType(); - newtype.SetFieldType( fieldtype ); - - fieldname = va( "%s field", fieldtype->Name() ); - newtype.SetName( fieldname ); - - ParseName( name ); - - // check for a function prototype or declaraction - if ( CheckToken( "(" ) ) { - ParseFunctionDef( newtype.FieldType(), name ); - } else { - type = gameLocal.program.GetType( newtype, true ); - assert( !type->def ); - gameLocal.program.AllocDef( type, name, scope, true ); - objtype->AddField( type, name ); - ExpectToken( ";" ); - } - } while( !CheckToken( "}" ) ); - - scope = oldscope; - - ExpectToken( ";" ); -} - -/* -============ -idCompiler::ParseFunction - -parse a function type -============ -*/ -idTypeDef *idCompiler::ParseFunction( idTypeDef *returnType, const char *name ) { - idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType ); - idTypeDef *type; - - if ( scope->Type() != ev_namespace ) { - // create self pointer - newtype.AddFunctionParm( scope->TypeDef(), "self" ); - } - - if ( !CheckToken( ")" ) ) { - idStr parmName; - do { - type = ParseType(); - ParseName( parmName ); - newtype.AddFunctionParm( type, parmName ); - } while( CheckToken( "," ) ); - - ExpectToken( ")" ); - } - - return gameLocal.program.GetType( newtype, true ); -} - -/* -================ -idCompiler::ParseFunctionDef -================ -*/ -void idCompiler::ParseFunctionDef( idTypeDef *returnType, const char *name ) { - idTypeDef *type; - idVarDef *def; - const idVarDef *parm; - idVarDef *oldscope; - int i; - int numParms; - const idTypeDef *parmType; - function_t *func; - statement_t *pos; - - if ( ( scope->Type() != ev_namespace ) && !scope->TypeDef()->Inherits( &type_object ) ) { - Error( "Functions may not be defined within other functions" ); - } - - type = ParseFunction( returnType, name ); - def = gameLocal.program.GetDef( type, name, scope ); - if ( !def ) { - def = gameLocal.program.AllocDef( type, name, scope, true ); - type->def = def; - - func = &gameLocal.program.AllocFunction( def ); - if ( scope->TypeDef()->Inherits( &type_object ) ) { - scope->TypeDef()->AddFunction( func ); - } - } else { - func = def->value.functionPtr; - assert( func ); - if ( func->firstStatement ) { - Error( "%s redeclared", def->GlobalName() ); - } - } - - // check if this is a prototype or declaration - if ( !CheckToken( "{" ) ) { - // it's just a prototype, so get the ; and move on - ExpectToken( ";" ); - return; - } - - // calculate stack space used by parms - numParms = type->NumParameters(); - func->parmSize.SetNum( numParms ); - for( i = 0; i < numParms; i++ ) { - parmType = type->GetParmType( i ); - if ( parmType->Inherits( &type_object ) ) { - func->parmSize[ i ] = type_object.Size(); - } else { - func->parmSize[ i ] = parmType->Size(); - } - func->parmTotal += func->parmSize[ i ]; - } - - // define the parms - for( i = 0; i < numParms; i++ ) { - if ( gameLocal.program.GetDef( type->GetParmType( i ), type->GetParmName( i ), def ) ) { - Error( "'%s' defined more than once in function parameters", type->GetParmName( i ) ); - } - parm = gameLocal.program.AllocDef( type->GetParmType( i ), type->GetParmName( i ), def, false ); - } - - oldscope = scope; - scope = def; - - func->firstStatement = gameLocal.program.NumStatements(); - - // check if we should call the super class constructor - if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "init" ) ) { - idTypeDef *superClass; - function_t *constructorFunc = NULL; - - // find the superclass constructor - for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) { - constructorFunc = gameLocal.program.FindFunction( va( "%s::init", superClass->Name() ) ); - if ( constructorFunc ) { - break; - } - } - - // emit the call to the constructor - if ( constructorFunc ) { - idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def ); - assert( selfDef ); - EmitPush( selfDef, selfDef->TypeDef() ); - EmitOpcode( &opcodes[ OP_CALL ], constructorFunc->def, 0 ); - } - } - - // parse regular statements - while( !CheckToken( "}" ) ) { - ParseStatement(); - } - - // check if we should call the super class destructor - if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "destroy" ) ) { - idTypeDef *superClass; - function_t *destructorFunc = NULL; - - // find the superclass destructor - for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) { - destructorFunc = gameLocal.program.FindFunction( va( "%s::destroy", superClass->Name() ) ); - if ( destructorFunc ) { - break; - } - } - - if ( destructorFunc ) { - if ( func->firstStatement < gameLocal.program.NumStatements() ) { - // change all returns to point to the call to the destructor - pos = &gameLocal.program.GetStatement( func->firstStatement ); - for( i = func->firstStatement; i < gameLocal.program.NumStatements(); i++, pos++ ) { - if ( pos->op == OP_RETURN ) { - pos->op = OP_GOTO; - pos->a = JumpDef( i, gameLocal.program.NumStatements() ); - } - } - } - - // emit the call to the destructor - idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def ); - assert( selfDef ); - EmitPush( selfDef, selfDef->TypeDef() ); - EmitOpcode( &opcodes[ OP_CALL ], destructorFunc->def, 0 ); - } - } - -// Disabled code since it caused a function to fall through to the next function when last statement is in the form "if ( x ) { return; }" -#if 0 - // don't bother adding a return opcode if the "return" statement was used. - if ( ( func->firstStatement == gameLocal.program.NumStatements() ) || ( gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ).op != OP_RETURN ) ) { - // emit an end of statements opcode - EmitOpcode( OP_RETURN, 0, 0 ); - } -#else - // always emit the return opcode - EmitOpcode( OP_RETURN, 0, 0 ); -#endif - - // record the number of statements in the function - func->numStatements = gameLocal.program.NumStatements() - func->firstStatement; - - scope = oldscope; -} - -/* -================ -idCompiler::ParseVariableDef -================ -*/ -void idCompiler::ParseVariableDef( idTypeDef *type, const char *name ) { - idVarDef *def, *def2; - bool negate; - - def = gameLocal.program.GetDef( type, name, scope ); - if ( def ) { - Error( "%s redeclared", name ); - } - - def = gameLocal.program.AllocDef( type, name, scope, false ); - - // check for an initialization - if ( CheckToken( "=" ) ) { - // if a local variable in a function then write out interpreter code to initialize variable - if ( scope->Type() == ev_function ) { - def2 = GetExpression( TOP_PRIORITY ); - if ( ( type == &type_float ) && ( def2->TypeDef() == &type_float ) ) { - EmitOpcode( OP_STORE_F, def2, def ); - } else if ( ( type == &type_vector ) && ( def2->TypeDef() == &type_vector ) ) { - EmitOpcode( OP_STORE_V, def2, def ); - } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_string ) ) { - EmitOpcode( OP_STORE_S, def2, def ); - } else if ( ( type == &type_entity ) && ( ( def2->TypeDef() == &type_entity ) || ( def2->TypeDef()->Inherits( &type_object ) ) ) ) { - EmitOpcode( OP_STORE_ENT, def2, def ); - } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef() == &type_entity ) ) { - EmitOpcode( OP_STORE_OBJENT, def2, def ); - } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef()->Inherits( type ) ) ) { - EmitOpcode( OP_STORE_OBJ, def2, def ); - } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_boolean ) ) { - EmitOpcode( OP_STORE_BOOL, def2, def ); - } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_float ) ) { - EmitOpcode( OP_STORE_FTOS, def2, def ); - } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_boolean ) ) { - EmitOpcode( OP_STORE_BTOS, def2, def ); - } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_vector ) ) { - EmitOpcode( OP_STORE_VTOS, def2, def ); - } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_float ) ) { - EmitOpcode( OP_STORE_FTOBOOL, def2, def ); - } else if ( ( type == &type_float ) && ( def2->TypeDef() == &type_boolean ) ) { - EmitOpcode( OP_STORE_BOOLTOF, def2, def ); - } else { - Error( "bad initialization for '%s'", name ); - } - } else { - // global variables can only be initialized with immediate values - negate = false; - if ( token.type == TT_PUNCTUATION && token == "-" ) { - negate = true; - NextToken(); - if ( immediateType != &type_float ) { - Error( "wrong immediate type for '-' on variable '%s'", name ); - } - } - - if ( immediateType != type ) { - Error( "wrong immediate type for '%s'", name ); - } - - // global variables are initialized at start up - if ( type == &type_string ) { - def->SetString( token, false ); - } else { - if ( negate ) { - immediate._float = -immediate._float; - } - def->SetValue( immediate, false ); - } - NextToken(); - } - } else if ( type == &type_string ) { - // local strings on the stack are initialized in the interpreter - if ( scope->Type() != ev_function ) { - def->SetString( "", false ); - } - } else if ( type->Inherits( &type_object ) ) { - if ( scope->Type() != ev_function ) { - def->SetObject( NULL ); - } - } -} - -/* -================ -idCompiler::GetTypeForEventArg -================ -*/ -idTypeDef *idCompiler::GetTypeForEventArg( char argType ) { - idTypeDef *type; - - switch( argType ) { - case D_EVENT_INTEGER : - // this will get converted to int by the interpreter - type = &type_float; - break; - - case D_EVENT_FLOAT : - type = &type_float; - break; - - case D_EVENT_VECTOR : - type = &type_vector; - break; - - case D_EVENT_STRING : - type = &type_string; - break; - - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - type = &type_entity; - break; - - case D_EVENT_VOID : - type = &type_void; - break; - - case D_EVENT_TRACE : - // This data type isn't available from script - type = NULL; - break; - - default: - // probably a typo - type = NULL; - break; - } - - return type; -} - -/* -================ -idCompiler::ParseEventDef -================ -*/ -void idCompiler::ParseEventDef( idTypeDef *returnType, const char *name ) { - const idTypeDef *expectedType; - idTypeDef *argType; - idTypeDef *type; - int i; - int num; - const char *format; - const idEventDef *ev; - idStr parmName; - - ev = idEventDef::FindEvent( name ); - if ( !ev ) { - Error( "Unknown event '%s'", name ); - } - - // set the return type - expectedType = GetTypeForEventArg( ev->GetReturnType() ); - if ( !expectedType ) { - Error( "Invalid return type '%c' in definition of '%s' event.", ev->GetReturnType(), name ); - } - if ( returnType != expectedType ) { - Error( "Return type doesn't match internal return type '%s'", expectedType->Name() ); - } - - idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType ); - - ExpectToken( "(" ); - - format = ev->GetArgFormat(); - num = strlen( format ); - for( i = 0; i < num; i++ ) { - expectedType = GetTypeForEventArg( format[ i ] ); - if ( !expectedType || ( expectedType == &type_void ) ) { - Error( "Invalid parameter '%c' in definition of '%s' event.", format[ i ], name ); - } - - argType = ParseType(); - ParseName( parmName ); - if ( argType != expectedType ) { - Error( "The type of parm %d ('%s') does not match the internal type '%s' in definition of '%s' event.", - i + 1, parmName.c_str(), expectedType->Name(), name ); - } - - newtype.AddFunctionParm( argType, "" ); - - if ( i < num - 1 ) { - if ( CheckToken( ")" ) ) { - Error( "Too few parameters for event definition. Internal definition has %d parameters.", num ); - } - ExpectToken( "," ); - } - } - if ( !CheckToken( ")" ) ) { - Error( "Too many parameters for event definition. Internal definition has %d parameters.", num ); - } - ExpectToken( ";" ); - - type = gameLocal.program.FindType( name ); - if ( type ) { - if ( !newtype.MatchesType( *type ) || ( type->def->value.functionPtr->eventdef != ev ) ) { - Error( "Type mismatch on redefinition of '%s'", name ); - } - } else { - type = gameLocal.program.AllocType( newtype ); - type->def = gameLocal.program.AllocDef( type, name, &def_namespace, true ); - - function_t &func = gameLocal.program.AllocFunction( type->def ); - func.eventdef = ev; - func.parmSize.SetNum( num ); - for( i = 0; i < num; i++ ) { - argType = newtype.GetParmType( i ); - func.parmTotal += argType->Size(); - func.parmSize[ i ] = argType->Size(); - } - - // mark the parms as local - func.locals = func.parmTotal; - } -} - -/* -================ -idCompiler::ParseDefs - -Called at the outer layer and when a local statement is hit -================ -*/ -void idCompiler::ParseDefs( void ) { - idStr name; - idTypeDef *type; - idVarDef *def; - idVarDef *oldscope; - - if ( CheckToken( ";" ) ) { - // skip semicolons, which are harmless and ok syntax - return; - } - - type = ParseType(); - if ( type == &type_scriptevent ) { - type = ParseType(); - ParseName( name ); - ParseEventDef( type, name ); - return; - } - - ParseName( name ); - - if ( type == &type_namespace ) { - def = gameLocal.program.GetDef( type, name, scope ); - if ( !def ) { - def = gameLocal.program.AllocDef( type, name, scope, true ); - } - ParseNamespace( def ); - } else if ( CheckToken( "::" ) ) { - def = gameLocal.program.GetDef( NULL, name, scope ); - if ( !def ) { - Error( "Unknown object name '%s'", name.c_str() ); - } - ParseName( name ); - oldscope = scope; - scope = def; - - ExpectToken( "(" ); - ParseFunctionDef( type, name.c_str() ); - scope = oldscope; - } else if ( type == &type_object ) { - ParseObjectDef( name.c_str() ); - } else if ( CheckToken( "(" ) ) { // check for a function prototype or declaraction - ParseFunctionDef( type, name.c_str() ); - } else { - ParseVariableDef( type, name.c_str() ); - while( CheckToken( "," ) ) { - ParseName( name ); - ParseVariableDef( type, name.c_str() ); - } - ExpectToken( ";" ); - } -} - -/* -================ -idCompiler::ParseNamespace - -Parses anything within a namespace definition -================ -*/ -void idCompiler::ParseNamespace( idVarDef *newScope ) { - idVarDef *oldscope; - - oldscope = scope; - if ( newScope != &def_namespace ) { - ExpectToken( "{" ); - } - - while( !eof ) { - scope = newScope; - callthread = false; - - if ( ( newScope != &def_namespace ) && CheckToken( "}" ) ) { - break; - } - - ParseDefs(); - } - - scope = oldscope; -} - -/* -============ -idCompiler::CompileFile - -compiles the 0 terminated text, adding definitions to the program structure -============ -*/ -void idCompiler::CompileFile( const char *text, const char *filename, bool toConsole ) { - idTimer compile_time; - bool error; - - compile_time.Start(); - - scope = &def_namespace; - basetype = NULL; - callthread = false; - loopDepth = 0; - eof = false; - braceDepth = 0; - immediateType = NULL; - currentLineNumber = 0; - console = toConsole; - - memset( &immediate, 0, sizeof( immediate ) ); - - parser.SetFlags( LEXFL_ALLOWMULTICHARLITERALS ); - parser.LoadMemory( text, strlen( text ), filename ); - parserPtr = &parser; - - // unread tokens to include script defines - token = SCRIPT_DEFAULTDEFS; - token.type = TT_STRING; - token.subtype = token.Length(); - token.line = token.linesCrossed = 0; - parser.UnreadToken( &token ); - - token = "include"; - token.type = TT_NAME; - token.subtype = token.Length(); - token.line = token.linesCrossed = 0; - parser.UnreadToken( &token ); - - token = "#"; - token.type = TT_PUNCTUATION; - token.subtype = P_PRECOMP; - token.line = token.linesCrossed = 0; - parser.UnreadToken( &token ); - - // init the current token line to be the first line so that currentLineNumber is set correctly in NextToken - token.line = 1; - - error = false; - try { - // read first token - NextToken(); - while( !eof && !error ) { - // parse from global namespace - ParseNamespace( &def_namespace ); - } - } - - catch( idCompileError &err ) { - idStr error; - - if ( console ) { - // don't print line number of an error if were calling script from the console using the "script" command - sprintf( error, "Error: %s\n", err.error ); - } else { - sprintf( error, "Error: file %s, line %d: %s\n", gameLocal.program.GetFilename( currentFileNumber ), currentLineNumber, err.error ); - } - - parser.FreeSource(); - - throw idCompileError( error ); - } - - parser.FreeSource(); - - compile_time.Stop(); - if ( !toConsole ) { - gameLocal.Printf( "Compiled '%s': %.1f ms\n", filename, compile_time.Milliseconds() ); - } -} diff --git a/game/script/script_compiler.h b/game/script/script_compiler.h deleted file mode 100644 index 987f0c8d9..000000000 --- a/game/script/script_compiler.h +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -#ifndef __SCRIPT_COMPILER_H__ -#define __SCRIPT_COMPILER_H__ - -const char * const RESULT_STRING = ""; - -typedef struct opcode_s { - const char *name; - const char *opname; - int priority; - bool rightAssociative; - idVarDef *type_a; - idVarDef *type_b; - idVarDef *type_c; -} opcode_t; - -// These opcodes are no longer necessary: -// OP_PUSH_OBJ: -// OP_PUSH_OBJENT: - -enum { - OP_RETURN, - - OP_UINC_F, - OP_UINCP_F, - OP_UDEC_F, - OP_UDECP_F, - OP_COMP_F, - - OP_MUL_F, - OP_MUL_V, - OP_MUL_FV, - OP_MUL_VF, - OP_DIV_F, - OP_MOD_F, - OP_ADD_F, - OP_ADD_V, - OP_ADD_S, - OP_ADD_FS, - OP_ADD_SF, - OP_ADD_VS, - OP_ADD_SV, - OP_SUB_F, - OP_SUB_V, - - OP_EQ_F, - OP_EQ_V, - OP_EQ_S, - OP_EQ_E, - OP_EQ_EO, - OP_EQ_OE, - OP_EQ_OO, - - OP_NE_F, - OP_NE_V, - OP_NE_S, - OP_NE_E, - OP_NE_EO, - OP_NE_OE, - OP_NE_OO, - - OP_LE, - OP_GE, - OP_LT, - OP_GT, - - OP_INDIRECT_F, - OP_INDIRECT_V, - OP_INDIRECT_S, - OP_INDIRECT_ENT, - OP_INDIRECT_BOOL, - OP_INDIRECT_OBJ, - - OP_ADDRESS, - - OP_EVENTCALL, - OP_OBJECTCALL, - OP_SYSCALL, - - OP_STORE_F, - OP_STORE_V, - OP_STORE_S, - OP_STORE_ENT, - OP_STORE_BOOL, - OP_STORE_OBJENT, - OP_STORE_OBJ, - OP_STORE_ENTOBJ, - - OP_STORE_FTOS, - OP_STORE_BTOS, - OP_STORE_VTOS, - OP_STORE_FTOBOOL, - OP_STORE_BOOLTOF, - - OP_STOREP_F, - OP_STOREP_V, - OP_STOREP_S, - OP_STOREP_ENT, - OP_STOREP_FLD, - OP_STOREP_BOOL, - OP_STOREP_OBJ, - OP_STOREP_OBJENT, - - OP_STOREP_FTOS, - OP_STOREP_BTOS, - OP_STOREP_VTOS, - OP_STOREP_FTOBOOL, - OP_STOREP_BOOLTOF, - - OP_UMUL_F, - OP_UMUL_V, - OP_UDIV_F, - OP_UDIV_V, - OP_UMOD_F, - OP_UADD_F, - OP_UADD_V, - OP_USUB_F, - OP_USUB_V, - OP_UAND_F, - OP_UOR_F, - - OP_NOT_BOOL, - OP_NOT_F, - OP_NOT_V, - OP_NOT_S, - OP_NOT_ENT, - - OP_NEG_F, - OP_NEG_V, - - OP_INT_F, - OP_IF, - OP_IFNOT, - - OP_CALL, - OP_THREAD, - OP_OBJTHREAD, - - OP_PUSH_F, - OP_PUSH_V, - OP_PUSH_S, - OP_PUSH_ENT, - OP_PUSH_OBJ, - OP_PUSH_OBJENT, - OP_PUSH_FTOS, - OP_PUSH_BTOF, - OP_PUSH_FTOB, - OP_PUSH_VTOS, - OP_PUSH_BTOS, - - OP_GOTO, - - OP_AND, - OP_AND_BOOLF, - OP_AND_FBOOL, - OP_AND_BOOLBOOL, - OP_OR, - OP_OR_BOOLF, - OP_OR_FBOOL, - OP_OR_BOOLBOOL, - - OP_BITAND, - OP_BITOR, - - OP_BREAK, // placeholder op. not used in final code - OP_CONTINUE, // placeholder op. not used in final code - - NUM_OPCODES -}; - -class idCompiler { -private: - static bool punctuationValid[ 256 ]; - static char *punctuation[]; - - idParser parser; - idParser *parserPtr; - idToken token; - - idTypeDef *immediateType; - eval_t immediate; - - bool eof; - bool console; - bool callthread; - int braceDepth; - int loopDepth; - int currentLineNumber; - int currentFileNumber; - int errorCount; - - idVarDef *scope; // the function being parsed, or NULL - const idVarDef *basetype; // for accessing fields - - float Divide( float numerator, float denominator ); - void Error( const char *error, ... ) const id_attribute((format(printf,2,3))); - void Warning( const char *message, ... ) const id_attribute((format(printf,2,3))); - idVarDef *OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); - idVarDef *EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); - idVarDef *EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ); - bool EmitPush( idVarDef *expression, const idTypeDef *funcArg ); - void NextToken( void ); - void ExpectToken( const char *string ); - bool CheckToken( const char *string ); - void ParseName( idStr &name ); - void SkipOutOfFunction( void ); - void SkipToSemicolon( void ); - idTypeDef *CheckType( void ); - idTypeDef *ParseType( void ); - idVarDef *FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const; - idVarDef *GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ); - idVarDef *VirtualFunctionConstant( idVarDef *func ); - idVarDef *SizeConstant( int size ); - idVarDef *JumpConstant( int value ); - idVarDef *JumpDef( int jumpfrom, int jumpto ); - idVarDef *JumpTo( int jumpto ); - idVarDef *JumpFrom( int jumpfrom ); - idVarDef *ParseImmediate( void ); - idVarDef *EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ); - idVarDef *ParseFunctionCall( idVarDef *func ); - idVarDef *ParseObjectCall( idVarDef *object, idVarDef *func ); - idVarDef *ParseEventCall( idVarDef *object, idVarDef *func ); - idVarDef *ParseSysObjectCall( idVarDef *func ); - idVarDef *LookupDef( const char *name, const idVarDef *baseobj ); - idVarDef *ParseValue( void ); - idVarDef *GetTerm( void ); - bool TypeMatches( etype_t type1, etype_t type2 ) const; - idVarDef *GetExpression( int priority ); - idTypeDef *GetTypeForEventArg( char argType ); - void PatchLoop( int start, int continuePos ); - void ParseReturnStatement( void ); - void ParseWhileStatement( void ); - void ParseForStatement( void ); - void ParseDoWhileStatement( void ); - void ParseIfStatement( void ); - void ParseStatement( void ); - void ParseObjectDef( const char *objname ); - idTypeDef *ParseFunction( idTypeDef *returnType, const char *name ); - void ParseFunctionDef( idTypeDef *returnType, const char *name ); - void ParseVariableDef( idTypeDef *type, const char *name ); - void ParseEventDef( idTypeDef *type, const char *name ); - void ParseDefs( void ); - void ParseNamespace( idVarDef *newScope ); - -public : - static opcode_t opcodes[]; - - idCompiler(); - void CompileFile( const char *text, const char *filename, bool console ); -}; - -#endif /* !__SCRIPT_COMPILER_H__ */ diff --git a/game/script/script_interpreter.cpp b/game/script/script_interpreter.cpp deleted file mode 100644 index 9dec6b576..000000000 --- a/game/script/script_interpreter.cpp +++ /dev/null @@ -1,2018 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -/* -================ -idInterpreter::idInterpreter() -================ -*/ -idInterpreter::idInterpreter() { - localstackUsed = 0; - terminateOnExit = true; - debug = 0; - memset( localstack, 0, sizeof( localstack ) ); - memset( callStack, 0, sizeof( callStack ) ); - Reset(); -#ifdef PROFILE_SCRIPT - while (functionTimers.size() > 0) - { - functionTimers.pop(); - } -#endif -} - -/* -================ -idInterpreter::Save -================ -*/ -void idInterpreter::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( callStackDepth ); - for( i = 0; i < callStackDepth; i++ ) { - savefile->WriteInt( callStack[i].s ); - if ( callStack[i].f ) { - savefile->WriteInt( gameLocal.program.GetFunctionIndex( callStack[i].f ) ); - } else { - savefile->WriteInt( -1 ); - } - savefile->WriteInt( callStack[i].stackbase ); - } - savefile->WriteInt( maxStackDepth ); - - savefile->WriteInt( localstackUsed ); - savefile->Write( &localstack, localstackUsed ); - - savefile->WriteInt( localstackBase ); - savefile->WriteInt( maxLocalstackUsed ); - - if ( currentFunction ) { - savefile->WriteInt( gameLocal.program.GetFunctionIndex( currentFunction ) ); - } else { - savefile->WriteInt( -1 ); - } - savefile->WriteInt( instructionPointer ); - - savefile->WriteInt( popParms ); - - if ( multiFrameEvent ) { - savefile->WriteString( multiFrameEvent->GetName() ); - } else { - savefile->WriteString( "" ); - } - savefile->WriteObject( eventEntity ); - - savefile->WriteObject( thread ); - - savefile->WriteBool( doneProcessing ); - savefile->WriteBool( threadDying ); - savefile->WriteBool( terminateOnExit ); - savefile->WriteBool( debug ); -} - -/* -================ -idInterpreter::Restore -================ -*/ -void idInterpreter::Restore( idRestoreGame *savefile ) { - int i; - idStr funcname; - int func_index; - - savefile->ReadInt( callStackDepth ); - for( i = 0; i < callStackDepth; i++ ) { - savefile->ReadInt( callStack[i].s ); - - savefile->ReadInt( func_index ); - if ( func_index >= 0 ) { - callStack[i].f = gameLocal.program.GetFunction( func_index ); - } else { - callStack[i].f = NULL; - } - - savefile->ReadInt( callStack[i].stackbase ); - } - savefile->ReadInt( maxStackDepth ); - - savefile->ReadInt( localstackUsed ); - savefile->Read( &localstack, localstackUsed ); - - savefile->ReadInt( localstackBase ); - savefile->ReadInt( maxLocalstackUsed ); - - savefile->ReadInt( func_index ); - if ( func_index >= 0 ) { - currentFunction = gameLocal.program.GetFunction( func_index ); - } else { - currentFunction = NULL; - } - savefile->ReadInt( instructionPointer ); - - savefile->ReadInt( popParms ); - - savefile->ReadString( funcname ); - if ( funcname.Length() ) { - multiFrameEvent = idEventDef::FindEvent( funcname ); - } - - savefile->ReadObject( reinterpret_cast( eventEntity ) ); - savefile->ReadObject( reinterpret_cast( thread ) ); - - savefile->ReadBool( doneProcessing ); - savefile->ReadBool( threadDying ); - savefile->ReadBool( terminateOnExit ); - savefile->ReadBool( debug ); -} - -/* -================ -idInterpreter::Reset -================ -*/ -void idInterpreter::Reset( void ) { -#ifdef PROFILE_SCRIPT - // Clear out any function timers - while (functionTimers.size() > 0) - { - idTimer& topMost = functionTimers.top(); - if (topMost.Running()) - { - topMost.Stop(); - } - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Resetting script stack, Timer: %lf\n", functionTimers.top().Milliseconds()); - functionTimers.pop(); - } -#endif - - callStackDepth = 0; - localstackUsed = 0; - localstackBase = 0; - - maxLocalstackUsed = 0; - maxStackDepth = 0; - - popParms = 0; - multiFrameEvent = NULL; - eventEntity = NULL; - - currentFunction = 0; - NextInstruction( 0 ); - - threadDying = false; - doneProcessing = true; -} - -/* -================ -idInterpreter::GetRegisterValue - -Returns a string representation of the value of the register. This is -used primarily for the debugger and debugging - -//FIXME: This is pretty much wrong. won't access data in most situations. -================ -*/ -bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) { - varEval_t reg; - idVarDef *d; - char funcObject[ 1024 ]; - char *funcName; - const idVarDef *scope; - const idTypeDef *field; - const idScriptObject *obj; - const function_t *func; - - out.Empty(); - - if ( scopeDepth == -1 ) { - scopeDepth = callStackDepth; - } - - if ( scopeDepth == callStackDepth ) { - func = currentFunction; - } else { - func = callStack[ scopeDepth ].f; - } - if ( !func ) { - return false; - } - - idStr::Copynz( funcObject, func->Name(), sizeof( funcObject ) ); - funcName = strstr( funcObject, "::" ); - if ( funcName ) { - *funcName = '\0'; - scope = gameLocal.program.GetDef( NULL, funcObject, &def_namespace ); - funcName += 2; - } else { - funcName = funcObject; - scope = &def_namespace; - } - - // Get the function from the object - d = gameLocal.program.GetDef( NULL, funcName, scope ); - if ( !d ) { - return false; - } - - // Get the variable itself and check various namespaces - d = gameLocal.program.GetDef( NULL, name, d ); - if ( !d ) { - if ( scope == &def_namespace ) { - return false; - } - - d = gameLocal.program.GetDef( NULL, name, scope ); - if ( !d ) { - d = gameLocal.program.GetDef( NULL, name, &def_namespace ); - if ( !d ) { - return false; - } - } - } - - reg = GetVariable( d ); - switch( d->Type() ) { - case ev_float: - if ( reg.floatPtr ) { - out = va("%g", *reg.floatPtr ); - } else { - out = "0"; - } - return true; - break; - - case ev_vector: - if ( reg.vectorPtr ) { - out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z ); - } else { - out = "0,0,0"; - } - return true; - break; - - case ev_boolean: - if ( reg.intPtr ) { - out = va( "%d", *reg.intPtr ); - } else { - out = "0"; - } - return true; - break; - - case ev_field: - if ( scope == &def_namespace ) { - // should never happen, but handle it safely anyway - return false; - } - - field = scope->TypeDef()->GetParmType( reg.ptrOffset )->FieldType(); - obj = *reinterpret_cast( &localstack[ callStack[ callStackDepth ].stackbase ] ); - if ( !field || !obj ) { - return false; - } - - switch ( field->Type() ) { - case ev_boolean: - out = va( "%d", *( reinterpret_cast( &obj->data[ reg.ptrOffset ] ) ) ); - return true; - - case ev_float: - out = va( "%g", *( reinterpret_cast( &obj->data[ reg.ptrOffset ] ) ) ); - return true; - - default: - return false; - } - break; - - case ev_string: - if ( reg.stringPtr ) { - out = "\""; - out += reg.stringPtr; - out += "\""; - } else { - out = "\"\""; - } - return true; - - default: - return false; - } -} - -/* -================ -idInterpreter::GetCallstackDepth -================ -*/ -int idInterpreter::GetCallstackDepth( void ) const { - return callStackDepth; -} - -/* -================ -idInterpreter::GetCallstack -================ -*/ -const prstack_t *idInterpreter::GetCallstack( void ) const { - return &callStack[ 0 ]; -} - -/* -================ -idInterpreter::GetCurrentFunction -================ -*/ -const function_t *idInterpreter::GetCurrentFunction( void ) const { - return currentFunction; -} - -/* -================ -idInterpreter::GetThread -================ -*/ -idThread *idInterpreter::GetThread( void ) const { - return thread; -} - - -/* -================ -idInterpreter::SetThread -================ -*/ -void idInterpreter::SetThread( idThread *pThread ) { - thread = pThread; -} - -/* -================ -idInterpreter::CurrentLine -================ -*/ -int idInterpreter::CurrentLine( void ) const { - if ( instructionPointer < 0 ) { - return 0; - } - return gameLocal.program.GetLineNumberForStatement( instructionPointer ); -} - -/* -================ -idInterpreter::CurrentFile -================ -*/ -const char *idInterpreter::CurrentFile( void ) const { - if ( instructionPointer < 0 ) { - return ""; - } - return gameLocal.program.GetFilenameForStatement( instructionPointer ); -} - -/* -============ -idInterpreter::StackTrace -============ -*/ -void idInterpreter::StackTrace( void ) const { - const function_t *f; - int i; - int top; - - if ( callStackDepth == 0 ) { - gameLocal.Printf( "\n" ); - return; - } - - top = callStackDepth; - if ( top >= MAX_STACK_DEPTH ) { - top = MAX_STACK_DEPTH - 1; - } - - if ( !currentFunction ) { - gameLocal.Printf( "\n" ); - } else { - gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( currentFunction->filenum ), currentFunction->Name() ); - } - - for( i = top; i >= 0; i-- ) { - f = callStack[ i ].f; - if ( !f ) { - gameLocal.Printf( "\n" ); - } else { - gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( f->filenum ), f->Name() ); - } - } -} - -/* -============ -idInterpreter::Error - -Aborts the currently executing function -============ -*/ -void idInterpreter::Error( const char *fmt, ... ) const { - va_list argptr; - char text[ 1024 ]; - - va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); - va_end( argptr ); - - StackTrace(); - - if ( ( instructionPointer >= 0 ) && ( instructionPointer < gameLocal.program.NumStatements() ) ) { - statement_t &line = gameLocal.program.GetStatement( instructionPointer ); - common->Error( "%s(%d): Thread '%s': %s\n", gameLocal.program.GetFilename( line.file ), line.linenumber, thread->GetThreadName(), text ); - } else { - common->Error( "Thread '%s': %s\n", thread->GetThreadName(), text ); - } -} - -/* -============ -idInterpreter::Warning - -Prints file and line number information with warning. -============ -*/ -void idInterpreter::Warning( const char *fmt, ... ) const { - va_list argptr; - char text[ 1024 ]; - - va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); - va_end( argptr ); - - if ( ( instructionPointer >= 0 ) && ( instructionPointer < gameLocal.program.NumStatements() ) ) { - statement_t &line = gameLocal.program.GetStatement( instructionPointer ); - common->Warning( "%s(%d): Thread '%s': %s", gameLocal.program.GetFilename( line.file ), line.linenumber, thread->GetThreadName(), text ); - } else { - common->Warning( "Thread '%s' : %s", thread->GetThreadName(), text ); - } -} - -/* -================ -idInterpreter::DisplayInfo -================ -*/ -void idInterpreter::DisplayInfo( void ) const { - const function_t *f; - int i; - - gameLocal.Printf( " Stack depth: %d bytes, %d max\n", localstackUsed, maxLocalstackUsed ); - gameLocal.Printf( " Call depth: %d, %d max\n", callStackDepth, maxStackDepth ); - gameLocal.Printf( " Call Stack: " ); - - if ( callStackDepth == 0 ) { - gameLocal.Printf( "\n" ); - } else { - if ( !currentFunction ) { - gameLocal.Printf( "\n" ); - } else { - gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( currentFunction->filenum ), currentFunction->Name() ); - } - - for( i = callStackDepth; i > 0; i-- ) { - gameLocal.Printf( " " ); - f = callStack[ i ].f; - if ( !f ) { - gameLocal.Printf( "\n" ); - } else { - gameLocal.Printf( "%12s : %s\n", gameLocal.program.GetFilename( f->filenum ), f->Name() ); - } - } - } -} - -/* -==================== -idInterpreter::ThreadCall - -Copys the args from the calling thread's stack -==================== -*/ -void idInterpreter::ThreadCall( idInterpreter *source, const function_t *func, int args ) { - Reset(); - - memcpy( localstack, &source->localstack[ source->localstackUsed - args ], args ); - - localstackUsed = args; - localstackBase = 0; - - maxLocalstackUsed = localstackUsed; - EnterFunction( func, false ); - - thread->SetThreadName( currentFunction->Name() ); -} - -/* -================ -idInterpreter::EnterObjectFunction - -Calls a function on a script object. - -NOTE: If this is called from within a event called by this interpreter, the function arguments will be invalid after calling this function. -================ -*/ -void idInterpreter::EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack ) { - if ( clearStack ) { - Reset(); - } - if ( popParms ) { - PopParms( popParms ); - popParms = 0; - } - Push( self->entityNumber + 1 ); - EnterFunction( func, false ); -} - -/* -==================== -idInterpreter::EnterFunction - -Returns the new program statement counter - -NOTE: If this is called from within a event called by this interpreter, the function arguments will be invalid after calling this function. -==================== -*/ -void idInterpreter::EnterFunction( const function_t *func, bool clearStack ) { - int c; - prstack_t *stack; - - if ( clearStack ) { - Reset(); - } - if ( popParms ) { - PopParms( popParms ); - popParms = 0; - } - - if ( callStackDepth >= MAX_STACK_DEPTH ) { - Error( "call stack overflow" ); - } - - stack = &callStack[ callStackDepth ]; - - stack->s = instructionPointer + 1; // point to the next instruction to execute - stack->f = currentFunction; - stack->stackbase = localstackBase; - - callStackDepth++; - if ( callStackDepth > maxStackDepth ) { - maxStackDepth = callStackDepth; - } - - if ( !func ) { - Error( "NULL function" ); - } - - if ( debug ) { - if ( currentFunction ) { - gameLocal.Printf( "%d: call '%s' from '%s'(line %d)%s\n", gameLocal.time, func->Name(), currentFunction->Name(), - gameLocal.program.GetStatement( instructionPointer ).linenumber, clearStack ? " clear stack" : "" ); - } else { - gameLocal.Printf( "%d: call '%s'%s\n", gameLocal.time, func->Name(), clearStack ? " clear stack" : "" ); - } - } - - currentFunction = func; - assert( !func->eventdef ); - NextInstruction( func->firstStatement ); - - // allocate space on the stack for locals - // parms are already on stack - c = func->locals - func->parmTotal; - assert( c >= 0 ); - - if ( localstackUsed + c > LOCALSTACK_SIZE ) { - Error( "EnterFuncton: locals stack overflow\n" ); - } - - // initialize local stack variables to zero - memset( &localstack[ localstackUsed ], 0, c ); - - localstackUsed += c; - localstackBase = localstackUsed - func->locals; - - if ( localstackUsed > maxLocalstackUsed ) { - maxLocalstackUsed = localstackUsed ; - } -} - -/* -==================== -idInterpreter::LeaveFunction -==================== -*/ -void idInterpreter::LeaveFunction( idVarDef *returnDef ) { - prstack_t *stack; - varEval_t ret; - - if ( callStackDepth <= 0 ) { - Error( "prog stack underflow" ); - } - - // return value - if ( returnDef ) { - switch( returnDef->Type() ) { - case ev_string : - gameLocal.program.ReturnString( GetString( returnDef ) ); - break; - - case ev_vector : - ret = GetVariable( returnDef ); - gameLocal.program.ReturnVector( *ret.vectorPtr ); - break; - - default : - ret = GetVariable( returnDef ); - gameLocal.program.ReturnInteger( *ret.intPtr ); - } - } - - // remove locals from the stack - PopParms( currentFunction->locals ); - assert( localstackUsed == localstackBase ); - - if ( debug ) { - statement_t &line = gameLocal.program.GetStatement( instructionPointer ); - gameLocal.Printf( "%d: %s(%d): exit %s", gameLocal.time, gameLocal.program.GetFilename( line.file ), line.linenumber, currentFunction->Name() ); - if ( callStackDepth > 1 ) { - gameLocal.Printf( " return to %s(line %d)\n", callStack[ callStackDepth - 1 ].f->Name(), gameLocal.program.GetStatement( callStack[ callStackDepth - 1 ].s ).linenumber ); - } else { - gameLocal.Printf( " done\n" ); - } - } - - // up stack - callStackDepth--; - stack = &callStack[ callStackDepth ]; - currentFunction = stack->f; - localstackBase = stack->stackbase; - NextInstruction( stack->s ); - - if ( !callStackDepth ) { - // all done - doneProcessing = true; - threadDying = true; - currentFunction = 0; - } -} - -/* -================ -idInterpreter::CallEvent -================ -*/ -void idInterpreter::CallEvent( const function_t *func, int argsize ) { - int i; - int j; - varEval_t var; - int pos; - int start; - int data[ D_EVENT_MAXARGS ]; - const idEventDef *evdef; - const char *format; - - if ( !func ) { - Error( "NULL function" ); - } - - assert( func->eventdef ); - evdef = func->eventdef; - - start = localstackUsed - argsize; - var.intPtr = ( int * )&localstack[ start ]; - eventEntity = GetEntity( *var.entityNumberPtr ); - - if ( !eventEntity || !eventEntity->RespondsTo( *evdef ) ) { - if ( eventEntity && developer.GetBool() ) { - // give a warning in developer mode - Warning( "Function '%s' not supported on entity '%s'", evdef->GetName(), eventEntity->name.c_str() ); - } - // always return a safe value when an object doesn't exist - switch( evdef->GetReturnType() ) { - case D_EVENT_INTEGER : - gameLocal.program.ReturnInteger( 0 ); - break; - - case D_EVENT_FLOAT : - gameLocal.program.ReturnFloat( 0 ); - break; - - case D_EVENT_VECTOR : - gameLocal.program.ReturnVector( vec3_zero ); - break; - - case D_EVENT_STRING : - gameLocal.program.ReturnString( "" ); - break; - - case D_EVENT_ENTITY : - case D_EVENT_ENTITY_NULL : - gameLocal.program.ReturnEntity( ( idEntity * )NULL ); - break; - - case D_EVENT_TRACE : - default: - // unsupported data type - break; - } - - PopParms( argsize ); - eventEntity = NULL; - return; - } - - format = evdef->GetArgFormat(); - for( j = 0, i = 0, pos = type_object.Size(); ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) { - switch( format[ i ] ) { - case D_EVENT_INTEGER : - var.intPtr = ( int * )&localstack[ start + pos ]; - data[ i ] = int( *var.floatPtr ); - break; - - case D_EVENT_FLOAT : - var.intPtr = ( int * )&localstack[ start + pos ]; - ( *( float * )&data[ i ] ) = *var.floatPtr; - break; - - case D_EVENT_VECTOR : - var.intPtr = ( int * )&localstack[ start + pos ]; - ( *( idVec3 ** )&data[ i ] ) = var.vectorPtr; - break; - - case D_EVENT_STRING : - ( *( const char ** )&data[ i ] ) = ( char * )&localstack[ start + pos ]; - break; - - case D_EVENT_ENTITY : - var.intPtr = ( int * )&localstack[ start + pos ]; - ( *( idEntity ** )&data[ i ] ) = GetEntity( *var.entityNumberPtr ); - if ( !( *( idEntity ** )&data[ i ] ) ) { - Warning( "Entity not found for event '%s'. Terminating thread.", evdef->GetName() ); - threadDying = true; - PopParms( argsize ); - return; - } - break; - - case D_EVENT_ENTITY_NULL : - var.intPtr = ( int * )&localstack[ start + pos ]; - ( *( idEntity ** )&data[ i ] ) = GetEntity( *var.entityNumberPtr ); - break; - - case D_EVENT_TRACE : - Error( "trace type not supported from script for '%s' event.", evdef->GetName() ); - break; - - default : - Error( "Invalid arg format string for '%s' event.", evdef->GetName() ); - break; - } - - pos += func->parmSize[ j++ ]; - } - - popParms = argsize; - eventEntity->ProcessEventArgPtr( evdef, data ); - - if ( !multiFrameEvent ) { - if ( popParms ) { - PopParms( popParms ); - } - eventEntity = NULL; - } else { - doneProcessing = true; - } - popParms = 0; -} - -/* -================ -idInterpreter::BeginMultiFrameEvent -================ -*/ -bool idInterpreter::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) { - if ( eventEntity != ent ) { - Error( "idInterpreter::BeginMultiFrameEvent called with wrong entity" ); - } - if ( multiFrameEvent ) { - if ( multiFrameEvent != event ) { - Error( "idInterpreter::BeginMultiFrameEvent called with wrong event" ); - } - return false; - } - - multiFrameEvent = event; - return true; -} - -/* -================ -idInterpreter::EndMultiFrameEvent -================ -*/ -void idInterpreter::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) { - if ( multiFrameEvent != event ) { - Error( "idInterpreter::EndMultiFrameEvent called with wrong event" ); - } - - multiFrameEvent = NULL; -} - -/* -================ -idInterpreter::MultiFrameEventInProgress -================ -*/ -bool idInterpreter::MultiFrameEventInProgress( void ) const { - return multiFrameEvent != NULL; -} - -/* -================ -idInterpreter::CallSysEvent -================ -*/ -void idInterpreter::CallSysEvent( const function_t *func, int argsize ) { - int i; - int j; - varEval_t source; - int pos; - int start; - int data[ D_EVENT_MAXARGS ]; - const idEventDef *evdef; - const char *format; - - if ( !func ) { - Error( "NULL function" ); - } - - assert( func->eventdef ); - evdef = func->eventdef; - - start = localstackUsed - argsize; - - format = evdef->GetArgFormat(); - for( j = 0, i = 0, pos = 0; ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) { - switch( format[ i ] ) { - case D_EVENT_INTEGER : - source.intPtr = ( int * )&localstack[ start + pos ]; - *( int * )&data[ i ] = int( *source.floatPtr ); - break; - - case D_EVENT_FLOAT : - source.intPtr = ( int * )&localstack[ start + pos ]; - *( float * )&data[ i ] = *source.floatPtr; - break; - - case D_EVENT_VECTOR : - source.intPtr = ( int * )&localstack[ start + pos ]; - *( idVec3 ** )&data[ i ] = source.vectorPtr; - break; - - case D_EVENT_STRING : - *( const char ** )&data[ i ] = ( char * )&localstack[ start + pos ]; - break; - - case D_EVENT_ENTITY : - source.intPtr = ( int * )&localstack[ start + pos ]; - *( idEntity ** )&data[ i ] = GetEntity( *source.entityNumberPtr ); - if ( !*( idEntity ** )&data[ i ] ) { - Warning( "Entity not found for event '%s'. Terminating thread.", evdef->GetName() ); - threadDying = true; - PopParms( argsize ); - return; - } - break; - - case D_EVENT_ENTITY_NULL : - source.intPtr = ( int * )&localstack[ start + pos ]; - *( idEntity ** )&data[ i ] = GetEntity( *source.entityNumberPtr ); - break; - - case D_EVENT_TRACE : - Error( "trace type not supported from script for '%s' event.", evdef->GetName() ); - break; - - default : - Error( "Invalid arg format string for '%s' event.", evdef->GetName() ); - break; - } - - pos += func->parmSize[ j++ ]; - } - - popParms = argsize; - thread->ProcessEventArgPtr( evdef, data ); - if ( popParms ) { - PopParms( popParms ); - } - popParms = 0; -} - -/* -==================== -idInterpreter::Execute -==================== -*/ -bool idInterpreter::Execute( void ) { - varEval_t var_a; - varEval_t var_b; - varEval_t var_c; - varEval_t var; - statement_t *st; - int runaway; - idThread *newThread; - float floatVal; - idScriptObject *obj; - const function_t *func; - - if ( threadDying || !currentFunction ) { - return true; - } - - if ( multiFrameEvent ) { - // move to previous instruction and call it again - instructionPointer--; - } - -#ifdef PROFILE_SCRIPT - if (debug && functionTimers.size() == 0) { - // Create a new function timer, as we don't appear to have one - functionTimers.push(idTimer()); - } - if (debug) { - functionTimers.top().Start(); - } -#endif - - runaway = 5000000; - - doneProcessing = false; - while( !doneProcessing && !threadDying ) { - instructionPointer++; - - if ( !--runaway ) { - Error( "runaway loop error" ); - } - - // next statement - st = &gameLocal.program.GetStatement( instructionPointer ); - - switch( st->op ) { - case OP_RETURN: - -#ifdef PROFILE_SCRIPT - if (debug && functionTimers.size() > 0) - { - // greebo: End the current timer, before adding a new one - functionTimers.top().Stop(); - - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Spent %lf msec in function %s.", functionTimers.top().Milliseconds(), currentFunction->Name()); - - // Remove the stopped timer - functionTimers.pop(); - } -#endif - // Actually leave the function - LeaveFunction( st->a ); - -#ifdef PROFILE_SCRIPT - // greebo: Maybe we have a timer of a previous function? - if (debug && functionTimers.size() > 0) - { - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Restarting timer of previous function: %s", currentFunction->Name()); - // Start the timer of the previous thread - functionTimers.top().Start(); - } -#endif - break; - - case OP_THREAD: - newThread = new idThread( this, st->a->value.functionPtr, st->b->value.argSize ); - newThread->Start(); - - // return the thread number to the script - gameLocal.program.ReturnFloat( newThread->GetThreadNum() ); - PopParms( st->b->value.argSize ); - break; - - case OP_OBJTHREAD: - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction ); - assert( st->c->value.argSize == func->parmTotal ); - newThread = new idThread( this, GetEntity( *var_a.entityNumberPtr ), func, func->parmTotal ); - newThread->Start(); - - // return the thread number to the script - gameLocal.program.ReturnFloat( newThread->GetThreadNum() ); - } else { - // return a null thread to the script - gameLocal.program.ReturnFloat( 0.0f ); - } - PopParms( st->c->value.argSize ); - break; - - case OP_CALL: - -#ifdef PROFILE_SCRIPT - if (debug && functionTimers.size() > 0) - { - // End the current timer, before leaving the current one - functionTimers.top().Stop(); - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Stopping timer of %s at %lf msec.", currentFunction->Name(), functionTimers.top().Milliseconds()); - } -#endif - EnterFunction( st->a->value.functionPtr, false ); -#ifdef PROFILE_SCRIPT - if (debug) { - // Add and start a new timer - functionTimers.push(idTimer()); - - functionTimers.top().Clear(); - functionTimers.top().Start(); - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Starting new timer on entering function %s.", currentFunction->Name()); - } -#endif - break; - - case OP_EVENTCALL: -#ifdef PROFILE_SCRIPT - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Calling script event."); -#endif - CallEvent( st->a->value.functionPtr, st->b->value.argSize ); - break; - - case OP_OBJECTCALL: - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction ); - -#ifdef PROFILE_SCRIPT - if (debug && functionTimers.size() > 0) - { - // End the current timer, before leaving the current one - functionTimers.top().Stop(); - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Stopping timer of %s at %lf msec.", currentFunction->Name(), functionTimers.top().Milliseconds()); - } -#endif - EnterFunction( func, false ); -#ifdef PROFILE_SCRIPT - if (debug) { - // Add and start a new timer - functionTimers.push(idTimer()); - - functionTimers.top().Clear(); - functionTimers.top().Start(); - //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Starting new timer on entering function %s.", currentFunction->Name()); - } -#endif - } else { - int entNum = *var_a.entityNumberPtr; - idEntity *ent = GetEntity(entNum); - if (ent) { - Warning("Tried to call function on entity %s, but entity has no script object", ent->name.c_str()); - } else { - Warning("Tried to call function on non-existent entity (#%d)", entNum); - } - - // return a 'safe' value - gameLocal.program.ReturnVector( vec3_zero ); - gameLocal.program.ReturnString( "" ); - PopParms( st->c->value.argSize ); - } - break; - - case OP_SYSCALL: - CallSysEvent( st->a->value.functionPtr, st->b->value.argSize ); - break; - - case OP_IFNOT: - var_a = GetVariable( st->a ); - if ( *var_a.intPtr == 0 ) { - NextInstruction( instructionPointer + st->b->value.jumpOffset ); - } - break; - - case OP_IF: - var_a = GetVariable( st->a ); - if ( *var_a.intPtr != 0 ) { - NextInstruction( instructionPointer + st->b->value.jumpOffset ); - } - break; - - case OP_GOTO: - NextInstruction( instructionPointer + st->a->value.jumpOffset ); - break; - - case OP_ADD_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = *var_a.floatPtr + *var_b.floatPtr; - break; - - case OP_ADD_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.vectorPtr = *var_a.vectorPtr + *var_b.vectorPtr; - break; - - case OP_ADD_S: - SetString( st->c, GetString( st->a ) ); - AppendString( st->c, GetString( st->b ) ); - break; - - case OP_ADD_FS: - var_a = GetVariable( st->a ); - SetString( st->c, FloatToString( *var_a.floatPtr ) ); - AppendString( st->c, GetString( st->b ) ); - break; - - case OP_ADD_SF: - var_b = GetVariable( st->b ); - SetString( st->c, GetString( st->a ) ); - AppendString( st->c, FloatToString( *var_b.floatPtr ) ); - break; - - case OP_ADD_VS: - var_a = GetVariable( st->a ); - SetString( st->c, var_a.vectorPtr->ToString() ); - AppendString( st->c, GetString( st->b ) ); - break; - - case OP_ADD_SV: - var_b = GetVariable( st->b ); - SetString( st->c, GetString( st->a ) ); - AppendString( st->c, var_b.vectorPtr->ToString() ); - break; - - case OP_SUB_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = *var_a.floatPtr - *var_b.floatPtr; - break; - - case OP_SUB_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.vectorPtr = *var_a.vectorPtr - *var_b.vectorPtr; - break; - - case OP_MUL_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = *var_a.floatPtr * *var_b.floatPtr; - break; - - case OP_MUL_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = *var_a.vectorPtr * *var_b.vectorPtr; - break; - - case OP_MUL_FV: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.vectorPtr = *var_a.floatPtr * *var_b.vectorPtr; - break; - - case OP_MUL_VF: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.vectorPtr = *var_a.vectorPtr * *var_b.floatPtr; - break; - - case OP_DIV_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - - if ( *var_b.floatPtr == 0.0f ) { - Warning( "Divide by zero" ); - *var_c.floatPtr = idMath::INFINITY; - } else { - *var_c.floatPtr = *var_a.floatPtr / *var_b.floatPtr; - } - break; - - case OP_MOD_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable ( st->c ); - - if ( *var_b.floatPtr == 0.0f ) { - Warning( "Divide by zero" ); - *var_c.floatPtr = *var_a.floatPtr; - } else { - *var_c.floatPtr = static_cast( *var_a.floatPtr ) % static_cast( *var_b.floatPtr ); - } - break; - - case OP_BITAND: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = static_cast( *var_a.floatPtr ) & static_cast( *var_b.floatPtr ); - break; - - case OP_BITOR: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = static_cast( *var_a.floatPtr ) | static_cast( *var_b.floatPtr ); - break; - - case OP_GE: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr >= *var_b.floatPtr ); - break; - - case OP_LE: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr <= *var_b.floatPtr ); - break; - - case OP_GT: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr > *var_b.floatPtr ); - break; - - case OP_LT: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr < *var_b.floatPtr ); - break; - - case OP_AND: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.floatPtr != 0.0f ); - break; - - case OP_AND_BOOLF: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.floatPtr != 0.0f ); - break; - - case OP_AND_FBOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.intPtr != 0 ); - break; - - case OP_AND_BOOLBOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.intPtr != 0 ); - break; - - case OP_OR: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.floatPtr != 0.0f ); - break; - - case OP_OR_BOOLF: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.floatPtr != 0.0f ); - break; - - case OP_OR_FBOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.intPtr != 0 ); - break; - - case OP_OR_BOOLBOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.intPtr != 0 ); - break; - - case OP_NOT_BOOL: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.intPtr == 0 ); - break; - - case OP_NOT_F: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr == 0.0f ); - break; - - case OP_NOT_V: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.vectorPtr == vec3_zero ); - break; - - case OP_NOT_S: - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( strlen( GetString( st->a ) ) == 0 ); - break; - - case OP_NOT_ENT: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( GetEntity( *var_a.entityNumberPtr ) == NULL ); - break; - - case OP_NEG_F: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = -*var_a.floatPtr; - break; - - case OP_NEG_V: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.vectorPtr = -*var_a.vectorPtr; - break; - - case OP_INT_F: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = static_cast( *var_a.floatPtr ); - break; - - case OP_EQ_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr == *var_b.floatPtr ); - break; - - case OP_EQ_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.vectorPtr == *var_b.vectorPtr ); - break; - - case OP_EQ_S: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) == 0 ); - break; - - case OP_EQ_E: - case OP_EQ_EO: - case OP_EQ_OE: - case OP_EQ_OO: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.entityNumberPtr == *var_b.entityNumberPtr ); - break; - - case OP_NE_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.floatPtr != *var_b.floatPtr ); - break; - - case OP_NE_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.vectorPtr != *var_b.vectorPtr ); - break; - - case OP_NE_S: - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) != 0 ); - break; - - case OP_NE_E: - case OP_NE_EO: - case OP_NE_OE: - case OP_NE_OO: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ( *var_a.entityNumberPtr != *var_b.entityNumberPtr ); - break; - - case OP_UADD_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr += *var_a.floatPtr; - break; - - case OP_UADD_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.vectorPtr += *var_a.vectorPtr; - break; - - case OP_USUB_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr -= *var_a.floatPtr; - break; - - case OP_USUB_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.vectorPtr -= *var_a.vectorPtr; - break; - - case OP_UMUL_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr *= *var_a.floatPtr; - break; - - case OP_UMUL_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.vectorPtr *= *var_a.floatPtr; - break; - - case OP_UDIV_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - - if ( *var_a.floatPtr == 0.0f ) { - Warning( "Divide by zero" ); - *var_b.floatPtr = idMath::INFINITY; - } else { - *var_b.floatPtr = *var_b.floatPtr / *var_a.floatPtr; - } - break; - - case OP_UDIV_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - - if ( *var_a.floatPtr == 0.0f ) { - Warning( "Divide by zero" ); - var_b.vectorPtr->Set( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY ); - } else { - *var_b.vectorPtr = *var_b.vectorPtr / *var_a.floatPtr; - } - break; - - case OP_UMOD_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - - if ( *var_a.floatPtr == 0.0f ) { - Warning( "Divide by zero" ); - *var_b.floatPtr = *var_a.floatPtr; - } else { - *var_b.floatPtr = static_cast( *var_b.floatPtr ) % static_cast( *var_a.floatPtr ); - } - break; - - case OP_UOR_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr = static_cast( *var_b.floatPtr ) | static_cast( *var_a.floatPtr ); - break; - - case OP_UAND_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr = static_cast( *var_b.floatPtr ) & static_cast( *var_a.floatPtr ); - break; - - case OP_UINC_F: - var_a = GetVariable( st->a ); - ( *var_a.floatPtr )++; - break; - - case OP_UINCP_F: - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - ( *var.floatPtr )++; - } - break; - - case OP_UDEC_F: - var_a = GetVariable( st->a ); - ( *var_a.floatPtr )--; - break; - - case OP_UDECP_F: - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - ( *var.floatPtr )--; - } - break; - - case OP_COMP_F: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - *var_c.floatPtr = ~static_cast( *var_a.floatPtr ); - break; - - case OP_STORE_F: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr = *var_a.floatPtr; - break; - - case OP_STORE_ENT: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.entityNumberPtr = *var_a.entityNumberPtr; - break; - - case OP_STORE_BOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.intPtr = *var_a.intPtr; - break; - - case OP_STORE_OBJENT: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( !obj ) { - *var_b.entityNumberPtr = 0; - } else if ( !obj->GetTypeDef()->Inherits( st->b->TypeDef() ) ) { - //Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->b->TypeDef()->Name() ); - *var_b.entityNumberPtr = 0; - } else { - *var_b.entityNumberPtr = *var_a.entityNumberPtr; - } - break; - - case OP_STORE_OBJ: - case OP_STORE_ENTOBJ: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.entityNumberPtr = *var_a.entityNumberPtr; - break; - - case OP_STORE_S: - SetString( st->b, GetString( st->a ) ); - break; - - case OP_STORE_V: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.vectorPtr = *var_a.vectorPtr; - break; - - case OP_STORE_FTOS: - var_a = GetVariable( st->a ); - SetString( st->b, FloatToString( *var_a.floatPtr ) ); - break; - - case OP_STORE_BTOS: - var_a = GetVariable( st->a ); - SetString( st->b, *var_a.intPtr ? "true" : "false" ); - break; - - case OP_STORE_VTOS: - var_a = GetVariable( st->a ); - SetString( st->b, var_a.vectorPtr->ToString() ); - break; - - case OP_STORE_FTOBOOL: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - if ( *var_a.floatPtr != 0.0f ) { - *var_b.intPtr = 1; - } else { - *var_b.intPtr = 0; - } - break; - - case OP_STORE_BOOLTOF: - var_a = GetVariable( st->a ); - var_b = GetVariable( st->b ); - *var_b.floatPtr = static_cast( *var_a.intPtr ); - break; - - case OP_STOREP_F: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->floatPtr = *var_a.floatPtr; - } - break; - - case OP_STOREP_ENT: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; - } - break; - - case OP_STOREP_FLD: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->intPtr = *var_a.intPtr; - } - break; - - case OP_STOREP_BOOL: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->intPtr = *var_a.intPtr; - } - break; - - case OP_STOREP_S: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { - idStr::Copynz( var_b.evalPtr->stringPtr, GetString( st->a ), MAX_STRING_LEN ); - } - break; - - case OP_STOREP_V: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->vectorPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->vectorPtr = *var_a.vectorPtr; - } - break; - - case OP_STOREP_FTOS: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { - var_a = GetVariable( st->a ); - idStr::Copynz( var_b.evalPtr->stringPtr, FloatToString( *var_a.floatPtr ), MAX_STRING_LEN ); - } - break; - - case OP_STOREP_BTOS: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { - var_a = GetVariable( st->a ); - if ( *var_a.floatPtr != 0.0f ) { - idStr::Copynz( var_b.evalPtr->stringPtr, "true", MAX_STRING_LEN ); - } else { - idStr::Copynz( var_b.evalPtr->stringPtr, "false", MAX_STRING_LEN ); - } - } - break; - - case OP_STOREP_VTOS: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) { - var_a = GetVariable( st->a ); - idStr::Copynz( var_b.evalPtr->stringPtr, var_a.vectorPtr->ToString(), MAX_STRING_LEN ); - } - break; - - case OP_STOREP_FTOBOOL: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->intPtr ) { - var_a = GetVariable( st->a ); - if ( *var_a.floatPtr != 0.0f ) { - *var_b.evalPtr->intPtr = 1; - } else { - *var_b.evalPtr->intPtr = 0; - } - } - break; - - case OP_STOREP_BOOLTOF: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->floatPtr = static_cast( *var_a.intPtr ); - } - break; - - case OP_STOREP_OBJ: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { - var_a = GetVariable( st->a ); - *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; - } - break; - - case OP_STOREP_OBJENT: - var_b = GetVariable( st->b ); - if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) { - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( !obj ) { - *var_b.evalPtr->entityNumberPtr = 0; - - // st->b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in st->c - // so that we can do a type check during run time since we don't know what type the script object is at compile time because it - // comes from an entity - } else if ( !obj->GetTypeDef()->Inherits( st->c->TypeDef() ) ) { - //Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->c->TypeDef()->Name() ); - *var_b.evalPtr->entityNumberPtr = 0; - } else { - *var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr; - } - } - break; - - case OP_ADDRESS: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var_c.evalPtr->bytePtr = &obj->data[ st->b->value.ptrOffset ]; - } else { - var_c.evalPtr->bytePtr = NULL; - } - break; - - case OP_INDIRECT_F: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - *var_c.floatPtr = *var.floatPtr; - } else { - *var_c.floatPtr = 0.0f; - } - break; - - case OP_INDIRECT_ENT: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - *var_c.entityNumberPtr = *var.entityNumberPtr; - } else { - *var_c.entityNumberPtr = 0; - } - break; - - case OP_INDIRECT_BOOL: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - *var_c.intPtr = *var.intPtr; - } else { - *var_c.intPtr = 0; - } - break; - - case OP_INDIRECT_S: - var_a = GetVariable( st->a ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - SetString( st->c, var.stringPtr ); - } else { - SetString( st->c, "" ); - } - break; - - case OP_INDIRECT_V: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( obj ) { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - *var_c.vectorPtr = *var.vectorPtr; - } else { - var_c.vectorPtr->Zero(); - } - break; - - case OP_INDIRECT_OBJ: - var_a = GetVariable( st->a ); - var_c = GetVariable( st->c ); - obj = GetScriptObject( *var_a.entityNumberPtr ); - if ( !obj ) { - *var_c.entityNumberPtr = 0; - } else { - var.bytePtr = &obj->data[ st->b->value.ptrOffset ]; - *var_c.entityNumberPtr = *var.entityNumberPtr; - } - break; - - case OP_PUSH_F: - var_a = GetVariable( st->a ); - Push( *var_a.intPtr ); - break; - - case OP_PUSH_FTOS: - var_a = GetVariable( st->a ); - PushString( FloatToString( *var_a.floatPtr ) ); - break; - - case OP_PUSH_BTOF: - var_a = GetVariable( st->a ); - floatVal = *var_a.intPtr; - Push( *reinterpret_cast( &floatVal ) ); - break; - - case OP_PUSH_FTOB: - var_a = GetVariable( st->a ); - if ( *var_a.floatPtr != 0.0f ) { - Push( 1 ); - } else { - Push( 0 ); - } - break; - - case OP_PUSH_VTOS: - var_a = GetVariable( st->a ); - PushString( var_a.vectorPtr->ToString() ); - break; - - case OP_PUSH_BTOS: - var_a = GetVariable( st->a ); - PushString( *var_a.intPtr ? "true" : "false" ); - break; - - case OP_PUSH_ENT: - var_a = GetVariable( st->a ); - Push( *var_a.entityNumberPtr ); - break; - - case OP_PUSH_S: - PushString( GetString( st->a ) ); - break; - - case OP_PUSH_V: - var_a = GetVariable( st->a ); - Push( *reinterpret_cast( &var_a.vectorPtr->x ) ); - Push( *reinterpret_cast( &var_a.vectorPtr->y ) ); - Push( *reinterpret_cast( &var_a.vectorPtr->z ) ); - break; - - case OP_PUSH_OBJ: - var_a = GetVariable( st->a ); - Push( *var_a.entityNumberPtr ); - break; - - case OP_PUSH_OBJENT: - var_a = GetVariable( st->a ); - Push( *var_a.entityNumberPtr ); - break; - - case OP_BREAK: - case OP_CONTINUE: - default: - Error( "Bad opcode %i", st->op ); - break; - } - } - -#ifdef PROFILE_SCRIPT - if (debug && functionTimers.size() > 0) { - functionTimers.top().Stop(); - } -#endif - - return threadDying; -} - -bool idInterpreter::EnterFunctionVarArg(const function_t *func, bool clearStack, const char *fmt, ...) -{ - bool rc = false; - va_list argptr; - - va_start(argptr, fmt); - rc = EnterFunctionVarArgVN(func, clearStack, fmt, argptr); - va_end(argptr); - - return rc; -} - -bool idInterpreter::EnterFunctionVarArgVN(const function_t *func, bool clearStack, const char *fmt, va_list args) -{ - bool rc = false; - char c; - int i; - float f; - idEntity *e; - idVec3 *v; - - if(func == NULL) - goto Quit; - - if(clearStack) - Reset(); - - while((c = *fmt) != 0) - { - switch(c) - { - case 'e': - e = va_arg(args, idEntity *); - // SZ: Allow pushing of null entity pointers (entity ID 0) - if (e != NULL) - { - Push(e->entityNumber + 1); - } - else - { - Push (0); - } - break; - - case 'v': - v = va_arg(args, idVec3 *); - Push(*reinterpret_cast(&v->x)); - Push(*reinterpret_cast(&v->y)); - Push(*reinterpret_cast(&v->z)); - break; - - case 's': - PushString(va_arg(args, char *)); - break; - - case 'f': - f = va_arg(args, double); - // i = static_cast(f); - i = *( (int*) &f); - Push(i); - break; - - case 'd': - i = va_arg(args, int); - Push(i); - break; - - case 'b': - i = va_arg(args, int); - Push(i); - break; - - default: // Unknown argument, so we clear the stack and exit - Reset(); - goto Quit; - } - fmt++; - } - - EnterFunction(func, false); - - rc = true; - -Quit: - return rc; -} - diff --git a/game/script/script_interpreter.h b/game/script/script_interpreter.h deleted file mode 100644 index 3774d315f..000000000 --- a/game/script/script_interpreter.h +++ /dev/null @@ -1,277 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SCRIPT_INTERPRETER_H__ -#define __SCRIPT_INTERPRETER_H__ - -#ifdef PROFILE_SCRIPT -#include -#endif - -#define MAX_STACK_DEPTH 64 -#define LOCALSTACK_SIZE 6144 - -typedef struct prstack_s { - int s; - const function_t *f; - int stackbase; -} prstack_t; - -class idInterpreter { -private: - prstack_t callStack[ MAX_STACK_DEPTH ]; - int callStackDepth; - int maxStackDepth; - - byte localstack[ LOCALSTACK_SIZE ]; - int localstackUsed; - int localstackBase; - int maxLocalstackUsed; - - const function_t *currentFunction; - int instructionPointer; - - int popParms; - const idEventDef *multiFrameEvent; - idEntity *eventEntity; - - idThread *thread; - -#ifdef PROFILE_SCRIPT - typedef std::stack TimerStack; - TimerStack functionTimers; -#endif - - void PopParms( int numParms ); - void PushString( const char *string ); - void Push( int value ); - const char *FloatToString( float value ); - void AppendString( idVarDef *def, const char *from ); - void SetString( idVarDef *def, const char *from ); - const char *GetString( idVarDef *def ); - varEval_t GetVariable( idVarDef *def ); - idEntity *GetEntity( int entnum ) const; - idScriptObject *GetScriptObject( int entnum ) const; - void NextInstruction( int position ); - - void LeaveFunction( idVarDef *returnDef ); - void CallEvent( const function_t *func, int argsize ); - void CallSysEvent( const function_t *func, int argsize ); - -public: - bool doneProcessing; - bool threadDying; - bool terminateOnExit; - bool debug; - - idInterpreter(); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void SetThread( idThread *pThread ); - - void StackTrace( void ) const; - - int CurrentLine( void ) const; - const char *CurrentFile( void ) const; - - void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - void DisplayInfo( void ) const; - - bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ); - void EndMultiFrameEvent( idEntity *ent, const idEventDef *event ); - bool MultiFrameEventInProgress( void ) const; - - void ThreadCall( idInterpreter *source, const function_t *func, int args ); - void EnterFunction( const function_t *func, bool clearStack ); - void EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack ); - - /** - * EnterVarArgFunction runs a script function, but allows to pass parameters to the script. - * The format string specifies which parameters are passed and in which order. The parameters - * are the same as used in event.h. - * e = entity - * s = string (char *) - * f = float - * v = vector - * b = boolean - */ - bool EnterFunctionVarArgVN(const function_t *func, bool clearStack, const char *fmt, va_list args); - bool EnterFunctionVarArg(const function_t *func, bool clearStack, const char *fmt, ...); - - bool Execute( void ); - void Reset( void ); - - bool GetRegisterValue( const char *name, idStr &out, int scopeDepth ); - int GetCallstackDepth( void ) const; - const prstack_t *GetCallstack( void ) const; - const function_t *GetCurrentFunction( void ) const; - idThread *GetThread( void ) const; - -}; - -/* -==================== -idInterpreter::PopParms -==================== -*/ -ID_INLINE void idInterpreter::PopParms( int numParms ) { - // pop our parms off the stack - if ( localstackUsed < numParms ) { - Error( "locals stack underflow\n" ); - } - - localstackUsed -= numParms; -} - -/* -==================== -idInterpreter::Push -==================== -*/ -ID_INLINE void idInterpreter::Push( int value ) { - if ( localstackUsed + sizeof( int ) > LOCALSTACK_SIZE ) { - Error( "Push: locals stack overflow\n" ); - } - *( int * )&localstack[ localstackUsed ] = value; - localstackUsed += sizeof( int ); -} - -/* -==================== -idInterpreter::PushString -==================== -*/ -ID_INLINE void idInterpreter::PushString( const char *string ) { - if ( localstackUsed + MAX_STRING_LEN > LOCALSTACK_SIZE ) { - Error( "PushString: locals stack overflow\n" ); - } - idStr::Copynz( ( char * )&localstack[ localstackUsed ], string, MAX_STRING_LEN ); - localstackUsed += MAX_STRING_LEN; -} - -/* -==================== -idInterpreter::FloatToString -==================== -*/ -ID_INLINE const char *idInterpreter::FloatToString( float value ) { - static char text[ 32 ]; - - if ( value == ( float )( int )value ) { - sprintf( text, "%d", ( int )value ); - } else { - sprintf( text, "%f", value ); - } - return text; -} - -/* -==================== -idInterpreter::AppendString -==================== -*/ -ID_INLINE void idInterpreter::AppendString( idVarDef *def, const char *from ) { - if ( def->initialized == idVarDef::stackVariable ) { - idStr::Append( ( char * )&localstack[ localstackBase + def->value.stackOffset ], MAX_STRING_LEN, from ); - } else { - idStr::Append( def->value.stringPtr, MAX_STRING_LEN, from ); - } -} - -/* -==================== -idInterpreter::SetString -==================== -*/ -ID_INLINE void idInterpreter::SetString( idVarDef *def, const char *from ) { - if ( def->initialized == idVarDef::stackVariable ) { - idStr::Copynz( ( char * )&localstack[ localstackBase + def->value.stackOffset ], from, MAX_STRING_LEN ); - } else { - idStr::Copynz( def->value.stringPtr, from, MAX_STRING_LEN ); - } -} - -/* -==================== -idInterpreter::GetString -==================== -*/ -ID_INLINE const char *idInterpreter::GetString( idVarDef *def ) { - if ( def->initialized == idVarDef::stackVariable ) { - return ( char * )&localstack[ localstackBase + def->value.stackOffset ]; - } else { - return def->value.stringPtr; - } -} - -/* -==================== -idInterpreter::GetVariable -==================== -*/ -ID_INLINE varEval_t idInterpreter::GetVariable( idVarDef *def ) { - if ( def->initialized == idVarDef::stackVariable ) { - varEval_t val; - val.intPtr = ( int * )&localstack[ localstackBase + def->value.stackOffset ]; - return val; - } else { - return def->value; - } -} - -/* -================ -idInterpreter::GetEntity -================ -*/ -ID_INLINE idEntity *idInterpreter::GetEntity( int entnum ) const{ - assert( entnum <= MAX_GENTITIES ); - if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) { - return gameLocal.entities[ entnum - 1 ]; - } - return NULL; -} - -/* -================ -idInterpreter::GetScriptObject -================ -*/ -ID_INLINE idScriptObject *idInterpreter::GetScriptObject( int entnum ) const { - idEntity *ent; - - assert( entnum <= MAX_GENTITIES ); - if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) { - ent = gameLocal.entities[ entnum - 1 ]; - if ( ent && ent->scriptObject.data ) { - return &ent->scriptObject; - } - } - return NULL; -} - -/* -==================== -idInterpreter::NextInstruction -==================== -*/ -ID_INLINE void idInterpreter::NextInstruction( int position ) { - // Before we execute an instruction, we increment instructionPointer, - // therefore we need to compensate for that here. - instructionPointer = position - 1; -} - -#endif /* !__SCRIPT_INTERPRETER_H__ */ diff --git a/game/script/script_program.cpp b/game/script/script_program.cpp deleted file mode 100644 index 7e63d1528..000000000 --- a/game/script/script_program.cpp +++ /dev/null @@ -1,2132 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" - -// simple types. function types are dynamically allocated -idTypeDef type_void( ev_void, &def_void, "void", 0, NULL ); -idTypeDef type_scriptevent( ev_scriptevent, &def_scriptevent, "scriptevent", sizeof( void * ), NULL ); -idTypeDef type_namespace( ev_namespace, &def_namespace, "namespace", sizeof( void * ), NULL ); -idTypeDef type_string( ev_string, &def_string, "string", MAX_STRING_LEN, NULL ); -idTypeDef type_float( ev_float, &def_float, "float", sizeof( float ), NULL ); -idTypeDef type_vector( ev_vector, &def_vector, "vector", sizeof( idVec3 ), NULL ); -idTypeDef type_entity( ev_entity, &def_entity, "entity", sizeof( int * ), NULL ); // stored as entity number pointer -idTypeDef type_field( ev_field, &def_field, "field", sizeof( void * ), NULL ); -idTypeDef type_function( ev_function, &def_function, "function", sizeof( void * ), &type_void ); -idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof( int ), NULL ); -idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof( void * ), NULL ); -idTypeDef type_object( ev_object, &def_object, "object", sizeof( int * ), NULL ); // stored as entity number pointer -idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "", sizeof( int ), NULL ); // only used for jump opcodes -idTypeDef type_argsize( ev_argsize, &def_argsize, "", sizeof( int ), NULL ); // only used for function call and thread opcodes -idTypeDef type_boolean( ev_boolean, &def_boolean, "boolean", sizeof( int ), NULL ); - -idVarDef def_void( &type_void ); -idVarDef def_scriptevent( &type_scriptevent ); -idVarDef def_namespace( &type_namespace ); -idVarDef def_string( &type_string ); -idVarDef def_float( &type_float ); -idVarDef def_vector( &type_vector ); -idVarDef def_entity( &type_entity ); -idVarDef def_field( &type_field ); -idVarDef def_function( &type_function ); -idVarDef def_virtualfunction( &type_virtualfunction ); -idVarDef def_pointer( &type_pointer ); -idVarDef def_object( &type_object ); -idVarDef def_jumpoffset( &type_jumpoffset ); // only used for jump opcodes -idVarDef def_argsize( &type_argsize ); -idVarDef def_boolean( &type_boolean ); - -/*********************************************************************** - - function_t - -***********************************************************************/ - -/* -================ -function_t::function_t -================ -*/ -function_t::function_t() { - Clear(); -} - -/* -================ -function_t::Allocated -================ -*/ -size_t function_t::Allocated( void ) const { - return name.Allocated() + parmSize.Allocated(); -} - -/* -================ -function_t::SetName -================ -*/ -void function_t::SetName( const char *name ) { - this->name = name; -} - -/* -================ -function_t::Name -================ -*/ -const char *function_t::Name( void ) const { - return name; -} - -/* -================ -function_t::Clear -================ -*/ -void function_t::Clear( void ) { - eventdef = NULL; - def = NULL; - type = NULL; - firstStatement = 0; - numStatements = 0; - parmTotal = 0; - locals = 0; - filenum = 0; - name.Clear(); - parmSize.Clear(); -} - -/*********************************************************************** - - idTypeDef - -***********************************************************************/ - -/* -================ -idTypeDef::idTypeDef -================ -*/ -idTypeDef::idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) { - name = ename; - type = etype; - def = edef; - size = esize; - auxType = aux; - - parmTypes.SetGranularity( 1 ); - parmNames.SetGranularity( 1 ); - functions.SetGranularity( 1 ); -} - -/* -================ -idTypeDef::idTypeDef -================ -*/ -idTypeDef::idTypeDef( const idTypeDef &other ) { - *this = other; -} - -/* -================ -idTypeDef::operator= -================ -*/ -void idTypeDef::operator=( const idTypeDef& other ) { - type = other.type; - def = other.def; - name = other.name; - size = other.size; - auxType = other.auxType; - parmTypes = other.parmTypes; - parmNames = other.parmNames; - functions = other.functions; -} - -/* -================ -idTypeDef::Allocated -================ -*/ -size_t idTypeDef::Allocated( void ) const { - size_t memsize; - int i; - - memsize = name.Allocated() + parmTypes.Allocated() + parmNames.Allocated() + functions.Allocated(); - for( i = 0; i < parmTypes.Num(); i++ ) { - memsize += parmNames[ i ].Allocated(); - } - - return memsize; -} - -/* -================ -idTypeDef::Inherits - -Returns true if basetype is an ancestor of this type. -================ -*/ -bool idTypeDef::Inherits( const idTypeDef *basetype ) const { - idTypeDef *superType; - - if ( type != ev_object ) { - return false; - } - - if ( this == basetype ) { - return true; - } - for( superType = auxType; superType != NULL; superType = superType->auxType ) { - if ( superType == basetype ) { - return true; - } - } - - return false; -} - -/* -================ -idTypeDef::MatchesType - -Returns true if both types' base types and parameters match -================ -*/ -bool idTypeDef::MatchesType( const idTypeDef &matchtype ) const { - int i; - - if ( this == &matchtype ) { - return true; - } - - if ( ( type != matchtype.type ) || ( auxType != matchtype.auxType ) ) { - return false; - } - - if ( parmTypes.Num() != matchtype.parmTypes.Num() ) { - return false; - } - - for( i = 0; i < matchtype.parmTypes.Num(); i++ ) { - if ( parmTypes[ i ] != matchtype.parmTypes[ i ] ) { - return false; - } - } - - return true; -} - -/* -================ -idTypeDef::MatchesVirtualFunction - -Returns true if both functions' base types and parameters match -================ -*/ -bool idTypeDef::MatchesVirtualFunction( const idTypeDef &matchfunc ) const { - int i; - - if ( this == &matchfunc ) { - return true; - } - - if ( ( type != matchfunc.type ) || ( auxType != matchfunc.auxType ) ) { - return false; - } - - if ( parmTypes.Num() != matchfunc.parmTypes.Num() ) { - return false; - } - - if ( parmTypes.Num() > 0 ) { - if ( !parmTypes[ 0 ]->Inherits( matchfunc.parmTypes[ 0 ] ) ) { - return false; - } - } - - for( i = 1; i < matchfunc.parmTypes.Num(); i++ ) { - if ( parmTypes[ i ] != matchfunc.parmTypes[ i ] ) { - return false; - } - } - - return true; -} - -/* -================ -idTypeDef::AddFunctionParm - -Adds a new parameter for a function type. -================ -*/ -void idTypeDef::AddFunctionParm( idTypeDef *parmtype, const char *name ) { - if ( type != ev_function ) { - throw idCompileError( "idTypeDef::AddFunctionParm : tried to add parameter on non-function type" ); - } - - parmTypes.Append( parmtype ); - idStr &parmName = parmNames.Alloc(); - parmName = name; -} - -/* -================ -idTypeDef::AddField - -Adds a new field to an object type. -================ -*/ -void idTypeDef::AddField( idTypeDef *fieldtype, const char *name ) { - if ( type != ev_object ) { - throw idCompileError( "idTypeDef::AddField : tried to add field to non-object type" ); - } - - parmTypes.Append( fieldtype ); - idStr &parmName = parmNames.Alloc(); - parmName = name; - - if ( fieldtype->FieldType()->Inherits( &type_object ) ) { - size += type_object.Size(); - } else { - size += fieldtype->FieldType()->Size(); - } -} - -/* -================ -idTypeDef::SetName -================ -*/ -void idTypeDef::SetName( const char *newname ) { - name = newname; -} - -/* -================ -idTypeDef::Name -================ -*/ -const char *idTypeDef::Name( void ) const { - return name; -} - -/* -================ -idTypeDef::Type -================ -*/ -etype_t idTypeDef::Type( void ) const { - return type; -} - -/* -================ -idTypeDef::Size -================ -*/ -int idTypeDef::Size( void ) const { - return size; -} - -/* -================ -idTypeDef::SuperClass - -If type is an object, then returns the object's superclass -================ -*/ -idTypeDef *idTypeDef::SuperClass( void ) const { - if ( type != ev_object ) { - throw idCompileError( "idTypeDef::SuperClass : tried to get superclass of a non-object type" ); - } - - return auxType; -} - -/* -================ -idTypeDef::ReturnType - -If type is a function, then returns the function's return type -================ -*/ -idTypeDef *idTypeDef::ReturnType( void ) const { - if ( type != ev_function ) { - throw idCompileError( "idTypeDef::ReturnType: tried to get return type on non-function type" ); - } - - return auxType; -} - -/* -================ -idTypeDef::SetReturnType - -If type is a function, then sets the function's return type -================ -*/ -void idTypeDef::SetReturnType( idTypeDef *returntype ) { - if ( type != ev_function ) { - throw idCompileError( "idTypeDef::SetReturnType: tried to set return type on non-function type" ); - } - - auxType = returntype; -} - -/* -================ -idTypeDef::FieldType - -If type is a field, then returns it's type -================ -*/ -idTypeDef *idTypeDef::FieldType( void ) const { - if ( type != ev_field ) { - throw idCompileError( "idTypeDef::FieldType: tried to get field type on non-field type" ); - } - - return auxType; -} - -/* -================ -idTypeDef::SetFieldType - -If type is a field, then sets the function's return type -================ -*/ -void idTypeDef::SetFieldType( idTypeDef *fieldtype ) { - if ( type != ev_field ) { - throw idCompileError( "idTypeDef::SetFieldType: tried to set return type on non-function type" ); - } - - auxType = fieldtype; -} - -/* -================ -idTypeDef::PointerType - -If type is a pointer, then returns the type it points to -================ -*/ -idTypeDef *idTypeDef::PointerType( void ) const { - if ( type != ev_pointer ) { - throw idCompileError( "idTypeDef::PointerType: tried to get pointer type on non-pointer" ); - } - - return auxType; -} - -/* -================ -idTypeDef::SetPointerType - -If type is a pointer, then sets the pointer's type -================ -*/ -void idTypeDef::SetPointerType( idTypeDef *pointertype ) { - if ( type != ev_pointer ) { - throw idCompileError( "idTypeDef::SetPointerType: tried to set type on non-pointer" ); - } - - auxType = pointertype; -} - -/* -================ -idTypeDef::NumParameters -================ -*/ -int idTypeDef::NumParameters( void ) const { - return parmTypes.Num(); -} - -/* -================ -idTypeDef::GetParmType -================ -*/ -idTypeDef *idTypeDef::GetParmType( int parmNumber ) const { - assert( parmNumber >= 0 ); - assert( parmNumber < parmTypes.Num() ); - return parmTypes[ parmNumber ]; -} - -/* -================ -idTypeDef::GetParmName -================ -*/ -const char *idTypeDef::GetParmName( int parmNumber ) const { - assert( parmNumber >= 0 ); - assert( parmNumber < parmTypes.Num() ); - return parmNames[ parmNumber ]; -} - -/* -================ -idTypeDef::NumFunctions -================ -*/ -int idTypeDef::NumFunctions( void ) const { - return functions.Num(); -} - -/* -================ -idTypeDef::GetFunctionNumber -================ -*/ -int idTypeDef::GetFunctionNumber( const function_t *func ) const { - int i; - - for( i = 0; i < functions.Num(); i++ ) { - if ( functions[ i ] == func ) { - return i; - } - } - return -1; -} - -/* -================ -idTypeDef::GetFunction -================ -*/ -const function_t *idTypeDef::GetFunction( int funcNumber ) const { - assert( funcNumber >= 0 ); - assert( funcNumber < functions.Num() ); - return functions[ funcNumber ]; -} - -/* -================ -idTypeDef::AddFunction -================ -*/ -void idTypeDef::AddFunction( const function_t *func ) { - int i; - - for( i = 0; i < functions.Num(); i++ ) { - if ( !strcmp( functions[ i ]->def->Name(), func->def->Name() ) ) { - if ( func->def->TypeDef()->MatchesVirtualFunction( *functions[ i ]->def->TypeDef() ) ) { - functions[ i ] = func; - return; - } - } - } - functions.Append( func ); -} - -/*********************************************************************** - - idVarDef - -***********************************************************************/ - -/* -================ -idVarDef::idVarDef() -================ -*/ -idVarDef::idVarDef( idTypeDef *typeptr ) { - typeDef = typeptr; - num = 0; - scope = NULL; - numUsers = 0; - initialized = idVarDef::uninitialized; - memset( &value, 0, sizeof( value ) ); - name = NULL; - next = NULL; -} - -/* -============ -idVarDef::~idVarDef -============ -*/ -idVarDef::~idVarDef() { - if ( name ) { - name->RemoveDef( this ); - } -} - -/* -============ -idVarDef::Name -============ -*/ -const char *idVarDef::Name( void ) const { - return name->Name(); -} - -/* -============ -idVarDef::GlobalName -============ -*/ -const char *idVarDef::GlobalName( void ) const { - if ( scope != &def_namespace ) { - return va( "%s::%s", scope->GlobalName(), name->Name() ); - } else { - return name->Name(); - } -} - -/* -============ -idVarDef::DepthOfScope -============ -*/ -int idVarDef::DepthOfScope( const idVarDef *otherScope ) const { - const idVarDef *def; - int depth; - - depth = 1; - for( def = otherScope; def != NULL; def = def->scope ) { - if ( def == scope ) { - return depth; - } - depth++; - } - - return 0; -} - -/* -============ -idVarDef::SetFunction -============ -*/ -void idVarDef::SetFunction( function_t *func ) { - assert( typeDef ); - initialized = initializedConstant; - assert( typeDef->Type() == ev_function ); - value.functionPtr = func; -} - -/* -============ -idVarDef::SetObject -============ -*/ -void idVarDef::SetObject( idScriptObject *object ) { - assert( typeDef ); - initialized = initialized; - assert( typeDef->Inherits( &type_object ) ); - *value.objectPtrPtr = object; -} - -/* -============ -idVarDef::SetValue -============ -*/ -void idVarDef::SetValue( const eval_t &_value, bool constant ) { - assert( typeDef ); - if ( constant ) { - initialized = initializedConstant; - } else { - initialized = initializedVariable; - } - - switch( typeDef->Type() ) { - case ev_pointer : - case ev_boolean : - case ev_field : - *value.intPtr = _value._int; - break; - - case ev_jumpoffset : - value.jumpOffset = _value._int; - break; - - case ev_argsize : - value.argSize = _value._int; - break; - - case ev_entity : - *value.entityNumberPtr = _value.entity; - break; - - case ev_string : - idStr::Copynz( value.stringPtr, _value.stringPtr, MAX_STRING_LEN ); - break; - - case ev_float : - *value.floatPtr = _value._float; - break; - - case ev_vector : - value.vectorPtr->x = _value.vector[ 0 ]; - value.vectorPtr->y = _value.vector[ 1 ]; - value.vectorPtr->z = _value.vector[ 2 ]; - break; - - case ev_function : - value.functionPtr = _value.function; - break; - - case ev_virtualfunction : - value.virtualFunction = _value._int; - break; - - case ev_object : - *value.entityNumberPtr = _value.entity; - break; - - default : - throw idCompileError( va( "weird type on '%s'", Name() ) ); - break; - } -} - -/* -============ -idVarDef::SetString -============ -*/ -void idVarDef::SetString( const char *string, bool constant ) { - if ( constant ) { - initialized = initializedConstant; - } else { - initialized = initializedVariable; - } - - assert( typeDef && ( typeDef->Type() == ev_string ) ); - idStr::Copynz( value.stringPtr, string, MAX_STRING_LEN ); -} - -/* -============ -idVarDef::PrintInfo -============ -*/ -void idVarDef::PrintInfo( idFile *file, int instructionPointer ) const { - statement_t *jumpst; - int jumpto; - etype_t etype; - int i; - int len; - const char *ch; - - if ( initialized == initializedConstant ) { - file->Printf( "const " ); - } - - etype = typeDef->Type(); - switch( etype ) { - case ev_jumpoffset : - jumpto = instructionPointer + value.jumpOffset; - jumpst = &gameLocal.program.GetStatement( jumpto ); - file->Printf( "address %d [%s(%d)]", jumpto, gameLocal.program.GetFilename( jumpst->file ), jumpst->linenumber ); - break; - - case ev_function : - if ( value.functionPtr->eventdef ) { - file->Printf( "event %s", GlobalName() ); - } else { - file->Printf( "function %s", GlobalName() ); - } - break; - - case ev_field : - file->Printf( "field %d", value.ptrOffset ); - break; - - case ev_argsize: - file->Printf( "args %d", value.argSize ); - break; - - default: - file->Printf( "%s ", typeDef->Name() ); - if ( initialized == initializedConstant ) { - switch( etype ) { - case ev_string : - file->Printf( "\"" ); - len = strlen( value.stringPtr ); - ch = value.stringPtr; - for( i = 0; i < len; i++, ch++ ) { - if ( idStr::CharIsPrintable( *ch ) ) { - file->Printf( "%c", *ch ); - } else if ( *ch == '\n' ) { - file->Printf( "\\n" ); - } else { - file->Printf( "\\x%.2x", static_cast( *ch ) ); - } - } - file->Printf( "\"" ); - break; - - case ev_vector : - file->Printf( "'%s'", value.vectorPtr->ToString() ); - break; - - case ev_float : - file->Printf( "%f", *value.floatPtr ); - break; - - case ev_virtualfunction : - file->Printf( "vtable[ %d ]", value.virtualFunction ); - break; - - default : - file->Printf( "%d", *value.intPtr ); - break; - } - } else if ( initialized == stackVariable ) { - file->Printf( "stack[%d]", value.stackOffset ); - } else { - file->Printf( "global[%d]", num ); - } - break; - } -} - -/*********************************************************************** - - idVarDef - -***********************************************************************/ - -/* -============ -idVarDefName::AddDef -============ -*/ -void idVarDefName::AddDef( idVarDef *def ) { - assert( def->next == NULL ); - def->name = this; - def->next = defs; - defs = def; -} - -/* -============ -idVarDefName::RemoveDef -============ -*/ -void idVarDefName::RemoveDef( idVarDef *def ) { - if ( defs == def ) { - defs = def->next; - } else { - for ( idVarDef *d = defs; d->next != NULL; d = d->next ) { - if ( d->next == def ) { - d->next = def->next; - break; - } - } - } - def->next = NULL; - def->name = NULL; -} - -/*********************************************************************** - - idScriptObject - -***********************************************************************/ - -/* -============ -idScriptObject::idScriptObject -============ -*/ -idScriptObject::idScriptObject() { - data = NULL; - type = &type_object; -} - -/* -============ -idScriptObject::~idScriptObject -============ -*/ -idScriptObject::~idScriptObject() { - Free(); -} - -/* -============ -idScriptObject::Free -============ -*/ -void idScriptObject::Free( void ) { - if ( data ) { - Mem_Free( data ); - } - - data = NULL; - type = &type_object; -} - -/* -================ -idScriptObject::Save -================ -*/ -void idScriptObject::Save( idSaveGame *savefile ) const { - size_t size; - - if ( type == &type_object && data == NULL ) { - // Write empty string for uninitialized object - savefile->WriteString( "" ); - } else { - savefile->WriteString( type->Name() ); - size = type->Size(); - savefile->WriteInt( size ); - savefile->Write( data, size ); - } -} - -/* -================ -idScriptObject::Restore -================ -*/ -void idScriptObject::Restore( idRestoreGame *savefile ) { - idStr typeName; - int size; - - savefile->ReadString( typeName ); - - // Empty string signals uninitialized object - if ( typeName.Length() == 0 ) { - return; - } - - if ( !SetType( typeName ) ) { - savefile->Error( "idScriptObject::Restore: failed to restore object of type '%s'.", typeName.c_str() ); - } - - savefile->ReadInt( (int &)size ); - if ( size != type->Size() ) { - savefile->Error( "idScriptObject::Restore: size of object '%s' doesn't match size in save game.", typeName.c_str() ); - } - - savefile->Read( data, size ); -} - -/* -============ -idScriptObject::SetType - -Allocates an object and initializes memory. -============ -*/ -bool idScriptObject::SetType( const char *typeName ) { - size_t size; - idTypeDef *newtype; - - // lookup the type - newtype = gameLocal.program.FindType( typeName ); - - // only allocate memory if the object type changes - if ( newtype != type ) { - Free(); - if ( !newtype ) { - gameLocal.Warning( "idScriptObject::SetType: Unknown type '%s'", typeName ); - return false; - } - - if ( !newtype->Inherits( &type_object ) ) { - gameLocal.Warning( "idScriptObject::SetType: Can't create object of type '%s'. Must be an object type.", newtype->Name() ); - return false; - } - - // set the type - type = newtype; - - // allocate the memory - size = type->Size(); - data = ( byte * )Mem_Alloc( size ); - } - - // init object memory - ClearObject(); - - return true; -} - -/* -============ -idScriptObject::ClearObject - -Resets the memory for the script object without changing its type. -============ -*/ -void idScriptObject::ClearObject( void ) { - size_t size; - - if ( type != &type_object ) { - // init object memory - size = type->Size(); - memset( data, 0, size ); - } -} - -/* -============ -idScriptObject::HasObject -============ -*/ -bool idScriptObject::HasObject( void ) const { - return ( type != &type_object ); -} - -/* -============ -idScriptObject::GetTypeDef -============ -*/ -idTypeDef *idScriptObject::GetTypeDef( void ) const { - return type; -} - -/* -============ -idScriptObject::GetTypeName -============ -*/ -const char *idScriptObject::GetTypeName( void ) const { - return type->Name(); -} - -/* -============ -idScriptObject::GetConstructor -============ -*/ -const function_t *idScriptObject::GetConstructor( void ) const { - const function_t *func; - - func = GetFunction( "init" ); - return func; -} - -/* -============ -idScriptObject::GetDestructor -============ -*/ -const function_t *idScriptObject::GetDestructor( void ) const { - const function_t *func; - - func = GetFunction( "destroy" ); - return func; -} - -/* -============ -idScriptObject::GetFunction -============ -*/ -const function_t *idScriptObject::GetFunction( const char *name ) const { - const function_t *func; - - if ( type == &type_object ) { - return NULL; - } - - func = gameLocal.program.FindFunction( name, type ); - return func; -} - -/* -============ -idScriptObject::GetVariable -============ -*/ -byte *idScriptObject::GetVariable( const char *name, etype_t etype ) const { - int i; - int pos; - const idTypeDef *t; - const idTypeDef *parm; - - if ( type == &type_object ) { - return NULL; - } - - t = type; - do { - if ( t->SuperClass() != &type_object ) { - pos = t->SuperClass()->Size(); - } else { - pos = 0; - } - for( i = 0; i < t->NumParameters(); i++ ) { - parm = t->GetParmType( i ); - if ( !strcmp( t->GetParmName( i ), name ) ) { - if ( etype != parm->FieldType()->Type() ) { - return NULL; - } - return &data[ pos ]; - } - - if ( parm->FieldType()->Inherits( &type_object ) ) { - pos += type_object.Size(); - } else { - pos += parm->FieldType()->Size(); - } - } - t = t->SuperClass(); - } while( t && ( t != &type_object ) ); - - return NULL; -} - -/*********************************************************************** - - idProgram - -***********************************************************************/ - -/* -============ -idProgram::AllocType -============ -*/ -idTypeDef *idProgram::AllocType( idTypeDef &type ) { - idTypeDef *newtype; - - newtype = new idTypeDef( type ); - types.Append( newtype ); - - return newtype; -} - -/* -============ -idProgram::AllocType -============ -*/ -idTypeDef *idProgram::AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) { - idTypeDef *newtype; - - newtype = new idTypeDef( etype, edef, ename, esize, aux ); - types.Append( newtype ); - - return newtype; -} - -/* -============ -idProgram::GetType - -Returns a preexisting complex type that matches the parm, or allocates -a new one and copies it out. -============ -*/ -idTypeDef *idProgram::GetType( idTypeDef &type, bool allocate ) { - int i; - - //FIXME: linear search == slow - for( i = types.Num() - 1; i >= 0; i-- ) { - if ( types[ i ]->MatchesType( type ) && !strcmp( types[ i ]->Name(), type.Name() ) ) { - return types[ i ]; - } - } - - if ( !allocate ) { - return NULL; - } - - // allocate a new one - return AllocType( type ); -} - -/* -============ -idProgram::FindType - -Returns a preexisting complex type that matches the name, or returns NULL if not found -============ -*/ -idTypeDef *idProgram::FindType( const char *name ) { - idTypeDef *check; - int i; - - for( i = types.Num() - 1; i >= 0; i-- ) { - check = types[ i ]; - if ( !strcmp( check->Name(), name ) ) { - return check; - } - } - - return NULL; -} - -/* -============ -idProgram::GetDefList -============ -*/ -idVarDef *idProgram::GetDefList( const char *name ) const { - int i, hash; - - hash = varDefNameHash.GenerateKey( name, true ); - for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) { - if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) { - return varDefNames[i]->GetDefs(); - } - } - return NULL; -} - -/* -============ -idProgram::AddDefToNameList -============ -*/ -void idProgram::AddDefToNameList( idVarDef *def, const char *name ) { - int i, hash; - - hash = varDefNameHash.GenerateKey( name, true ); - for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) { - if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) { - break; - } - } - if ( i == -1 ) { - i = varDefNames.Append( new idVarDefName( name ) ); - varDefNameHash.Add( hash, i ); - } - varDefNames[i]->AddDef( def ); -} - -/* -============ -idProgram::AllocDef -============ -*/ -idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ) { - idVarDef *def; - idStr element; - idVarDef *def_x; - idVarDef *def_y; - idVarDef *def_z; - - // allocate a new def - def = new idVarDef( type ); - def->scope = scope; - def->numUsers = 1; - def->num = varDefs.Append( def ); - - // add the def to the list with defs with this name and set the name pointer - AddDefToNameList( def, name ); - - if ( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) ) { - // - // vector - // - if ( !strcmp( name, RESULT_STRING ) ) { - // vector defs don't need the _x, _y and _z components - assert( scope->Type() == ev_function ); - def->value.stackOffset = scope->value.functionPtr->locals; - def->initialized = idVarDef::stackVariable; - scope->value.functionPtr->locals += type->Size(); - } else if ( scope->TypeDef()->Inherits( &type_object ) ) { - idTypeDef newtype( ev_field, NULL, "float field", 0, &type_float ); - idTypeDef *type = GetType( newtype, true ); - - // set the value to the variable's position in the object - def->value.ptrOffset = scope->TypeDef()->Size(); - - // make automatic defs for the vectors elements - // origin can be accessed as origin_x, origin_y, and origin_z - sprintf( element, "%s_x", def->Name() ); - def_x = AllocDef( type, element, scope, constant ); - - sprintf( element, "%s_y", def->Name() ); - def_y = AllocDef( type, element, scope, constant ); - def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size(); - - sprintf( element, "%s_z", def->Name() ); - def_z = AllocDef( type, element, scope, constant ); - def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size(); - } else { - // make automatic defs for the vectors elements - // origin can be accessed as origin_x, origin_y, and origin_z - sprintf( element, "%s_x", def->Name() ); - def_x = AllocDef( &type_float, element, scope, constant ); - - sprintf( element, "%s_y", def->Name() ); - def_y = AllocDef( &type_float, element, scope, constant ); - - sprintf( element, "%s_z", def->Name() ); - def_z = AllocDef( &type_float, element, scope, constant ); - - // point the vector def to the x coordinate - def->value = def_x->value; - def->initialized = def_x->initialized; - } - } else if ( scope->TypeDef()->Inherits( &type_object ) ) { - // - // object variable - // - // set the value to the variable's position in the object - def->value.ptrOffset = scope->TypeDef()->Size(); - } else if ( scope->Type() == ev_function ) { - // - // stack variable - // - // since we don't know how many local variables there are, - // we have to have them go backwards on the stack - def->value.stackOffset = scope->value.functionPtr->locals; - def->initialized = idVarDef::stackVariable; - - if ( type->Inherits( &type_object ) ) { - // objects only have their entity number on the stack, not the entire object - scope->value.functionPtr->locals += type_object.Size(); - } else { - scope->value.functionPtr->locals += type->Size(); - } - } else { - // - // global variable - // - def->value.bytePtr = &variables[ numVariables ]; - numVariables += def->TypeDef()->Size(); - if ( numVariables > sizeof( variables ) ) { - throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) ); - } - - memset( def->value.bytePtr, 0, def->TypeDef()->Size() ); - } - - return def; -} - -/* -============ -idProgram::GetDef - -If type is NULL, it will match any type -============ -*/ -idVarDef *idProgram::GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const { - idVarDef *def; - idVarDef *bestDef; - int bestDepth; - int depth; - - bestDepth = 0; - bestDef = NULL; - for( def = GetDefList( name ); def != NULL; def = def->Next() ) { - if ( def->scope->Type() == ev_namespace ) { - depth = def->DepthOfScope( scope ); - if ( !depth ) { - // not in the same namespace - continue; - } - } else if ( def->scope != scope ) { - // in a different function - continue; - } else { - depth = 1; - } - - if ( !bestDef || ( depth < bestDepth ) ) { - bestDepth = depth; - bestDef = def; - } - } - - // see if the name is already in use for another type - if ( bestDef && type && ( bestDef->TypeDef() != type ) ) { - throw idCompileError( va( "Type mismatch on redeclaration of %s", name ) ); - } - - return bestDef; -} - -/* -============ -idProgram::FreeDef -============ -*/ -void idProgram::FreeDef( idVarDef *def, const idVarDef *scope ) { - idVarDef *e; - int i; - - if ( def->Type() == ev_vector ) { - idStr name; - - sprintf( name, "%s_x", def->Name() ); - e = GetDef( NULL, name, scope ); - if ( e ) { - FreeDef( e, scope ); - } - - sprintf( name, "%s_y", def->Name() ); - e = GetDef( NULL, name, scope ); - if ( e ) { - FreeDef( e, scope ); - } - - sprintf( name, "%s_z", def->Name() ); - e = GetDef( NULL, name, scope ); - if ( e ) { - FreeDef( e, scope ); - } - } - - varDefs.RemoveIndex( def->num ); - for( i = def->num; i < varDefs.Num(); i++ ) { - varDefs[ i ]->num = i; - } - - delete def; -} - -/* -============ -idProgram::FindFreeResultDef -============ -*/ -idVarDef *idProgram::FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b ) { - idVarDef *def; - - for( def = GetDefList( name ); def != NULL; def = def->Next() ) { - if ( def == a || def == b ) { - continue; - } - if ( def->TypeDef() != type ) { - continue; - } - if ( def->scope != scope ) { - continue; - } - if ( def->numUsers <= 1 ) { - continue; - } - return def; - } - - return AllocDef( type, name, scope, false ); -} - -/* -================ -idProgram::FindFunction - -Searches for the specified function in the currently loaded script. A full namespace should be -specified if not in the global namespace. - -Returns 0 if function not found. -Returns >0 if function found. -================ -*/ -function_t *idProgram::FindFunction( const char *name ) const { - int start; - int pos; - idVarDef *namespaceDef; - idVarDef *def; - - assert( name ); - - idStr fullname = name; - start = 0; - namespaceDef = &def_namespace; - do { - pos = fullname.Find( "::", true, start ); - if ( pos < 0 ) { - break; - } - - idStr namespaceName = fullname.Mid( start, pos - start ); - def = GetDef( NULL, namespaceName, namespaceDef ); - if ( !def ) { - // couldn't find namespace - return NULL; - } - namespaceDef = def; - - // skip past the :: - start = pos + 2; - } while( def->Type() == ev_namespace ); - - idStr funcName = fullname.Right( fullname.Length() - start ); - def = GetDef( NULL, funcName, namespaceDef ); - if ( !def ) { - // couldn't find function - return NULL; - } - - if ( ( def->Type() == ev_function ) && ( def->value.functionPtr->eventdef == NULL ) ) { - return def->value.functionPtr; - } - - // is not a function, or is an eventdef - return NULL; -} - -/* -================ -idProgram::FindFunction - -Searches for the specified object function in the currently loaded script. - -Returns 0 if function not found. -Returns >0 if function found. -================ -*/ -function_t *idProgram::FindFunction( const char *name, const idTypeDef *type ) const { - const idVarDef *tdef; - const idVarDef *def; - - // look for the function - def = NULL; - for( tdef = type->def; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) { - def = GetDef( NULL, name, tdef ); - if ( def ) { - return def->value.functionPtr; - } - } - - return NULL; -} - -/* -================ -idProgram::AllocFunction -================ -*/ -function_t &idProgram::AllocFunction( idVarDef *def ) { - if ( functions.Num() >= functions.Max() ) { - throw idCompileError( va( "Exceeded maximum allowed number of functions (%d)", functions.Max() ) ); - } - - // fill in the dfunction - function_t &func = *functions.Alloc(); - func.eventdef = NULL; - func.def = def; - func.type = def->TypeDef(); - func.firstStatement = 0; - func.numStatements = 0; - func.parmTotal = 0; - func.locals = 0; - func.filenum = filenum; - func.parmSize.SetGranularity( 1 ); - func.SetName( def->GlobalName() ); - - def->SetFunction( &func ); - - return func; -} - -/* -================ -idProgram::SetEntity -================ -*/ -void idProgram::SetEntity( const char *name, idEntity *ent ) { - idVarDef *def; - idStr defName( "$" ); - - defName += name; - - def = GetDef( &type_entity, defName, &def_namespace ); - if ( def && ( def->initialized != idVarDef::stackVariable ) ) { - // 0 is reserved for NULL entity - if ( !ent ) { - *def->value.entityNumberPtr = 0; - } else { - *def->value.entityNumberPtr = ent->entityNumber + 1; - } - } -} - -/* -================ -idProgram::AllocStatement -================ -*/ -statement_t *idProgram::AllocStatement( void ) { - if ( statements.Num() >= statements.Max() ) { - throw idCompileError( va( "Exceeded maximum allowed number of statements (%d)", statements.Max() ) ); - } - return statements.Alloc(); -} - -/* -============== -idProgram::BeginCompilation - -called before compiling a batch of files, clears the pr struct -============== -*/ -void idProgram::BeginCompilation( void ) { - statement_t *statement; - - FreeData(); - - try { - // make the first statement a return for a "NULL" function - statement = AllocStatement(); - statement->linenumber = 0; - statement->file = 0; - statement->op = OP_RETURN; - statement->a = NULL; - statement->b = NULL; - statement->c = NULL; - - // define NULL - //AllocDef( &type_void, "", &def_namespace, true ); - - // define the return def - returnDef = AllocDef( &type_vector, "", &def_namespace, false ); - - // define the return def for strings - returnStringDef = AllocDef( &type_string, "", &def_namespace, false ); - - // define the sys object - sysDef = AllocDef( &type_void, "sys", &def_namespace, true ); - } - - catch( idCompileError &err ) { - gameLocal.Error( "%s", err.error ); - } -} - -/* -============== -idProgram::DisassembleStatement -============== -*/ -void idProgram::DisassembleStatement( idFile *file, int instructionPointer ) const { - opcode_t *op; - const statement_t *statement; - - statement = &statements[ instructionPointer ]; - op = &idCompiler::opcodes[ statement->op ]; - file->Printf( "%20s(%d):\t%6d: %15s\t", fileList[ statement->file ].c_str(), statement->linenumber, instructionPointer, op->opname ); - - if ( statement->a ) { - file->Printf( "\ta: " ); - statement->a->PrintInfo( file, instructionPointer ); - } - - if ( statement->b ) { - file->Printf( "\tb: " ); - statement->b->PrintInfo( file, instructionPointer ); - } - - if ( statement->c ) { - file->Printf( "\tc: " ); - statement->c->PrintInfo( file, instructionPointer ); - } - - file->Printf( "\n" ); -} - -/* -============== -idProgram::Disassemble -============== -*/ -void idProgram::Disassemble( void ) const { - int i; - int instructionPointer; - const function_t *func; - idFile *file; - - file = fileSystem->OpenFileByMode( "script/disasm.txt", FS_WRITE ); - - for( i = 0; i < functions.Num(); i++ ) { - func = &functions[ i ]; - if ( func->eventdef ) { - // skip eventdefs - continue; - } - - file->Printf( "\nfunction %s() %d stack used, %d parms, %d locals {\n", func->Name(), func->locals, func->parmTotal, func->locals - func->parmTotal ); - - for( instructionPointer = 0; instructionPointer < func->numStatements; instructionPointer++ ) { - DisassembleStatement( file, func->firstStatement + instructionPointer ); - } - - file->Printf( "}\n" ); - } - - fileSystem->CloseFile( file ); -} - -/* -============== -idProgram::FinishCompilation - -Called after all files are compiled to check for errors -============== -*/ -void idProgram::FinishCompilation( void ) { - int i; - - top_functions = functions.Num(); - top_statements = statements.Num(); - top_types = types.Num(); - top_defs = varDefs.Num(); - top_files = fileList.Num(); - - variableDefaults.Clear(); - variableDefaults.SetNum( numVariables ); - - for( i = 0; i < numVariables; i++ ) { - variableDefaults[ i ] = variables[ i ]; - } -} - -/* -============== -idProgram::CompileStats - -called after all files are compiled to report memory usage. -============== -*/ -void idProgram::CompileStats( void ) { - int memused; - int memallocated; - int numdefs; - int stringspace; - int funcMem; - int i; - - gameLocal.Printf( "---------- Compile stats ----------\n" ); - gameLocal.DPrintf( "Files loaded:\n" ); - - stringspace = 0; - for( i = 0; i < fileList.Num(); i++ ) { - gameLocal.DPrintf( " %s\n", fileList[ i ].c_str() ); - stringspace += fileList[ i ].Allocated(); - } - stringspace += fileList.Size(); - - numdefs = varDefs.Num(); - memused = varDefs.Num() * sizeof( idVarDef ); - memused += types.Num() * sizeof( idTypeDef ); - memused += stringspace; - - for( i = 0; i < types.Num(); i++ ) { - memused += types[ i ]->Allocated(); - } - - funcMem = functions.MemoryUsed(); - for( i = 0; i < functions.Num(); i++ ) { - funcMem += functions[ i ].Allocated(); - } - - memallocated = funcMem + memused + sizeof( idProgram ); - - memused += statements.MemoryUsed(); - memused += functions.MemoryUsed(); // name and filename of functions are shared, so no need to include them - memused += sizeof( variables ); - - gameLocal.Printf( "\nMemory usage:\n" ); - gameLocal.Printf( " Strings: %d, %d bytes\n", fileList.Num(), stringspace ); - gameLocal.Printf( " Statements: %d, %d bytes\n", statements.Num(), statements.MemoryUsed() ); - gameLocal.Printf( " Functions: %d, %d bytes\n", functions.Num(), funcMem ); - gameLocal.Printf( " Variables: %d bytes\n", numVariables ); - gameLocal.Printf( " Mem used: %d bytes\n", memused ); - gameLocal.Printf( " Static data: %d bytes\n", sizeof( idProgram ) ); - gameLocal.Printf( " Allocated: %d bytes\n", memallocated ); - gameLocal.Printf( " Thread size: %d bytes\n\n", sizeof( idThread ) ); -} - -/* -================ -idProgram::CompileText -================ -*/ -bool idProgram::CompileText( const char *source, const char *text, bool console ) { - idCompiler compiler; - int i; - idVarDef *def; - idStr ospath; - - // use a full os path for GetFilenum since it calls OSPathToRelativePath to convert filenames from the parser - ospath = fileSystem->RelativePathToOSPath( source ); - filenum = GetFilenum( ospath ); - - try { - compiler.CompileFile( text, filename, console ); - - // check to make sure all functions prototyped have code - for( i = 0; i < varDefs.Num(); i++ ) { - def = varDefs[ i ]; - if ( ( def->Type() == ev_function ) && ( ( def->scope->Type() == ev_namespace ) || def->scope->TypeDef()->Inherits( &type_object ) ) ) { - if ( !def->value.functionPtr->eventdef && !def->value.functionPtr->firstStatement ) { - throw idCompileError( va( "function %s was not defined\n", def->GlobalName() ) ); - } - } - } - } - - catch( idCompileError &err ) { - if ( console ) { - gameLocal.Printf( "%s\n", err.error ); - return false; - } else { - gameLocal.Error( "%s\n", err.error ); - } - }; - - if ( !console ) { - CompileStats(); - } - - return true; -} - -/* -================ -idProgram::CompileFunction -================ -*/ -const function_t *idProgram::CompileFunction( const char *functionName, const char *text ) { - bool result; - - result = CompileText( functionName, text, false ); - - if ( g_disasm.GetBool() ) { - Disassemble(); - } - - if ( !result ) { - gameLocal.Error( "Compile failed." ); - } - - return FindFunction( functionName ); -} - -/* -================ -idProgram::CompileFile -================ -*/ -void idProgram::CompileFile( const char *filename ) { - char *src; - bool result; - - if ( fileSystem->ReadFile( filename, ( void ** )&src, NULL ) < 0 ) { - gameLocal.Error( "Couldn't load %s\n", filename ); - } - - result = CompileText( filename, src, false ); - - fileSystem->FreeFile( src ); - - if ( g_disasm.GetBool() ) { - Disassemble(); - } - - if ( !result ) { - gameLocal.Error( "Compile failed in file %s.", filename ); - } -} - -/* -================ -idProgram::FreeData -================ -*/ -void idProgram::FreeData( void ) { - int i; - - // free the defs - varDefs.DeleteContents( true ); - varDefNames.DeleteContents( true ); - varDefNameHash.Free(); - - returnDef = NULL; - returnStringDef = NULL; - sysDef = NULL; - - // free any special types we've created - types.DeleteContents( true ); - - filenum = 0; - - numVariables = 0; - memset( variables, 0, sizeof( variables ) ); - - // clear all the strings in the functions so that it doesn't look like we're leaking memory. - for( i = 0; i < functions.Num(); i++ ) { - functions[ i ].Clear(); - } - - filename.Clear(); - fileList.Clear(); - statements.Clear(); - functions.Clear(); - - top_functions = 0; - top_statements = 0; - top_types = 0; - top_defs = 0; - top_files = 0; - - filename = ""; -} - -/* -================ -idProgram::Startup -================ -*/ -void idProgram::Startup( const char *defaultScript ) { - gameLocal.Printf( "Initializing scripts\n" ); - - // make sure all data is freed up - idThread::Restart(); - - // get ready for loading scripts - BeginCompilation(); - - // load the default script - if ( defaultScript && *defaultScript ) { - CompileFile( defaultScript ); - } - - FinishCompilation(); -} - -/* -================ -idProgram::Save -================ -*/ -void idProgram::Save( idSaveGame *savefile ) const { - int i; - int currentFileNum = top_files; - - savefile->WriteInt( (fileList.Num() - currentFileNum) ); - while ( currentFileNum < fileList.Num() ) { - savefile->WriteString( fileList[ currentFileNum ] ); - currentFileNum++; - } - - for ( i = 0; i < variableDefaults.Num(); i++ ) { - if ( variables[i] != variableDefaults[i] ) { - savefile->WriteInt( i ); - savefile->WriteByte( variables[i] ); - } - } - // Mark the end of the diff with default variables with -1 - savefile->WriteInt( -1 ); - - savefile->WriteInt( numVariables ); - for ( i = variableDefaults.Num(); i < numVariables; i++ ) { - savefile->WriteByte( variables[i] ); - } - - int checksum = CalculateChecksum(); - savefile->WriteInt( checksum ); -} - -/* -================ -idProgram::Restore -================ -*/ -bool idProgram::Restore( idRestoreGame *savefile ) { - int i, num, index; - bool result = true; - idStr scriptname; - - savefile->ReadInt( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadString( scriptname ); - CompileFile( scriptname ); - } - - savefile->ReadInt( index ); - while( index >= 0 ) { - savefile->ReadByte( variables[index] ); - savefile->ReadInt( index ); - } - - savefile->ReadInt( num ); - for ( i = variableDefaults.Num(); i < num; i++ ) { - savefile->ReadByte( variables[i] ); - } - - int saved_checksum, checksum; - - savefile->ReadInt( saved_checksum ); - checksum = CalculateChecksum(); - - if ( saved_checksum != checksum ) { - result = false; - } - - return result; -} - -/* -================ -idProgram::CalculateChecksum -================ -*/ -int idProgram::CalculateChecksum( void ) const { - int i, result; - - typedef struct { - unsigned short op; - int a; - int b; - int c; - unsigned short linenumber; - unsigned short file; - } statementBlock_t; - - statementBlock_t *statementList = new statementBlock_t[ statements.Num() ]; - - memset( statementList, 0, ( sizeof(statementBlock_t) * statements.Num() ) ); - - // Copy info into new list, using the variable numbers instead of a pointer to the variable - for( i = 0; i < statements.Num(); i++ ) { - statementList[i].op = statements[i].op; - - if ( statements[i].a ) { - statementList[i].a = statements[i].a->num; - } else { - statementList[i].a = -1; - } - if ( statements[i].b ) { - statementList[i].b = statements[i].b->num; - } else { - statementList[i].b = -1; - } - if ( statements[i].c ) { - statementList[i].c = statements[i].c->num; - } else { - statementList[i].c = -1; - } - - statementList[i].linenumber = statements[i].linenumber; - statementList[i].file = statements[i].file; - } - - result = MD4_BlockChecksum( statementList, ( sizeof(statementBlock_t) * statements.Num() ) ); - - delete [] statementList; - - return result; -} - -/* -============== -idProgram::Restart - -Restores all variables to their initial value -============== -*/ -void idProgram::Restart( void ) { - int i; - - idThread::Restart(); - - // - // since there may have been a script loaded by the map or the user may - // have typed "script" from the console, free up any types and vardefs that - // have been allocated after the initial startup - // - for( i = top_types; i < types.Num(); i++ ) { - delete types[ i ]; - } - types.SetNum( top_types, false ); - - for( i = top_defs; i < varDefs.Num(); i++ ) { - delete varDefs[ i ]; - } - varDefs.SetNum( top_defs, false ); - - for( i = top_functions; i < functions.Num(); i++ ) { - functions[ i ].Clear(); - } - functions.SetNum( top_functions ); - - statements.SetNum( top_statements ); - fileList.SetNum( top_files, false ); - filename.Clear(); - - // reset the variables to their default values - numVariables = variableDefaults.Num(); - for( i = 0; i < numVariables; i++ ) { - variables[ i ] = variableDefaults[ i ]; - } -} - -/* -================ -idProgram::GetFilenum -================ -*/ -int idProgram::GetFilenum( const char *name ) { - if ( filename == name ) { - return filenum; - } - - idStr strippedName; - strippedName = fileSystem->OSPathToRelativePath( name ); - if ( !strippedName.Length() ) { - // not off the base path so just use the full path - filenum = fileList.AddUnique( name ); - } else { - filenum = fileList.AddUnique( strippedName ); - } - - // save the unstripped name so that we don't have to strip the incoming name every time we call GetFilenum - filename = name; - - return filenum; -} - -/* -================ -idProgram::idProgram -================ -*/ -idProgram::idProgram() { - FreeData(); -} - -/* -================ -idProgram::~idProgram -================ -*/ -idProgram::~idProgram() { - FreeData(); -} - -/* -================ -idProgram::ReturnEntity -================ -*/ -void idProgram::ReturnEntity( idEntity *ent ) { - if ( ent ) { - *returnDef->value.entityNumberPtr = ent->entityNumber + 1; - } else { - *returnDef->value.entityNumberPtr = 0; - } -} diff --git a/game/script/script_program.h b/game/script/script_program.h deleted file mode 100644 index d277db60e..000000000 --- a/game/script/script_program.h +++ /dev/null @@ -1,607 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SCRIPT_PROGRAM_H__ -#define __SCRIPT_PROGRAM_H__ - -class idScriptObject; -class idEventDef; -class idVarDef; -class idTypeDef; -class idEntity; -class idThread; -class idSaveGame; -class idRestoreGame; - -#define MAX_STRING_LEN 128 -#define MAX_GLOBALS 196608 // in bytes -#define MAX_STRINGS 1024 -#define MAX_FUNCS 3072 -#define MAX_STATEMENTS 81920 // statement_t - 18 bytes last I checked - -typedef enum { - ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean -} etype_t; - -class function_t { -public: - function_t(); - - size_t Allocated( void ) const; - void SetName( const char *name ); - const char *Name( void ) const; - void Clear( void ); - -private: - idStr name; -public: - const idEventDef *eventdef; - idVarDef *def; - const idTypeDef *type; - int firstStatement; - int numStatements; - int parmTotal; - int locals; // total ints of parms + locals - int filenum; // source file defined in - idList parmSize; -}; - -typedef union eval_s { - const char *stringPtr; - float _float; - float vector[ 3 ]; - function_t *function; - int _int; - int entity; -} eval_t; - -/*********************************************************************** - -idTypeDef - -Contains type information for variables and functions. - -***********************************************************************/ - -class idTypeDef { -private: - etype_t type; - idStr name; - int size; - - // function types are more complex - idTypeDef *auxType; // return type - idList parmTypes; - idStrList parmNames; - idList functions; - -public: - idVarDef *def; // a def that points to this type - - idTypeDef( const idTypeDef &other ); - idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ); - void operator=( const idTypeDef& other ); - size_t Allocated( void ) const; - - bool Inherits( const idTypeDef *basetype ) const; - bool MatchesType( const idTypeDef &matchtype ) const; - bool MatchesVirtualFunction( const idTypeDef &matchfunc ) const; - void AddFunctionParm( idTypeDef *parmtype, const char *name ); - void AddField( idTypeDef *fieldtype, const char *name ); - - void SetName( const char *newname ); - const char *Name( void ) const; - - etype_t Type( void ) const; - int Size( void ) const; - - idTypeDef *SuperClass( void ) const; - - idTypeDef *ReturnType( void ) const; - void SetReturnType( idTypeDef *type ); - - idTypeDef *FieldType( void ) const; - void SetFieldType( idTypeDef *type ); - - idTypeDef *PointerType( void ) const; - void SetPointerType( idTypeDef *type ); - - int NumParameters( void ) const; - idTypeDef *GetParmType( int parmNumber ) const; - const char *GetParmName( int parmNumber ) const; - - int NumFunctions( void ) const; - int GetFunctionNumber( const function_t *func ) const; - const function_t *GetFunction( int funcNumber ) const; - void AddFunction( const function_t *func ); -}; - -/*********************************************************************** - -idScriptObject - -In-game representation of objects in scripts. Use the idScriptVariable template -(below) to access variables. - -***********************************************************************/ - -class idScriptObject { -private: - idTypeDef *type; - -public: - byte *data; - - idScriptObject(); - ~idScriptObject(); - - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void Free( void ); - bool SetType( const char *typeName ); - void ClearObject( void ); - bool HasObject( void ) const; - idTypeDef *GetTypeDef( void ) const; - const char *GetTypeName( void ) const; - const function_t *GetConstructor( void ) const; - const function_t *GetDestructor( void ) const; - const function_t *GetFunction( const char *name ) const; - - byte *GetVariable( const char *name, etype_t etype ) const; -}; - -/*********************************************************************** - -idScriptVariable - -Helper template that handles looking up script variables stored in objects. -If the specified variable doesn't exist, or is the wrong data type, idScriptVariable -will cause an error. - -***********************************************************************/ - -template -class idScriptVariable { -private: - type *data; - -public: - idScriptVariable(); - bool IsLinked( void ) const; - void Unlink( void ); - void LinkTo( idScriptObject &obj, const char *name ); - idScriptVariable &operator=( const returnType &value ); - operator returnType() const; -}; - -template -ID_INLINE idScriptVariable::idScriptVariable() { - data = NULL; -} - -template -ID_INLINE bool idScriptVariable::IsLinked( void ) const { - return ( data != NULL ); -} - -template -ID_INLINE void idScriptVariable::Unlink( void ) { - data = NULL; -} - -template -ID_INLINE void idScriptVariable::LinkTo( idScriptObject &obj, const char *name ) { - data = ( type * )obj.GetVariable( name, etype ); - if ( !data ) { - gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() ); - } -} - -template -ID_INLINE idScriptVariable &idScriptVariable::operator=( const returnType &value ) { - // check if we attempt to access the object before it's been linked - assert( data ); - - // make sure we don't crash if we don't have a pointer - if ( data ) { - *data = ( type )value; - } - return *this; -} - -template -ID_INLINE idScriptVariable::operator returnType() const { - // check if we attempt to access the object before it's been linked - assert( data ); - - // make sure we don't crash if we don't have a pointer - if ( data ) { - return ( const returnType )*data; - } else { - // reasonably safe value - return ( const returnType )0; - } -} - -/*********************************************************************** - -Script object variable access template instantiations - -These objects will automatically handle looking up of the current value -of a variable in a script object. They can be stored as part of a class -for up-to-date values of the variable, or can be used in functions to -sample the data for non-dynamic values. - -***********************************************************************/ - -typedef idScriptVariable idScriptBool; -typedef idScriptVariable idScriptFloat; -typedef idScriptVariable idScriptInt; -typedef idScriptVariable idScriptVector; -typedef idScriptVariable idScriptString; - -/*********************************************************************** - -idCompileError - -Causes the compiler to exit out of compiling the current function and -display an error message with line and file info. - -***********************************************************************/ - -class idCompileError : public idException { -public: - idCompileError( const char *text ) : idException( text ) {} -}; - -/*********************************************************************** - -idVarDef - -Define the name, type, and location of variables, functions, and objects -defined in script. - -***********************************************************************/ - -typedef union varEval_s { - idScriptObject **objectPtrPtr; - char *stringPtr; - float *floatPtr; - idVec3 *vectorPtr; - function_t *functionPtr; - int *intPtr; - byte *bytePtr; - int *entityNumberPtr; - int virtualFunction; - int jumpOffset; - int stackOffset; // offset in stack for local variables - int argSize; - varEval_s *evalPtr; - int ptrOffset; -} varEval_t; - -class idVarDefName; - -class idVarDef { - friend class idVarDefName; - -public: - int num; - varEval_t value; - idVarDef * scope; // function, namespace, or object the var was defined in - int numUsers; // number of users if this is a constant - - typedef enum { - uninitialized, initializedVariable, initializedConstant, stackVariable - } initialized_t; - - initialized_t initialized; - -public: - idVarDef( idTypeDef *typeptr = NULL ); - ~idVarDef(); - - const char * Name( void ) const; - const char * GlobalName( void ) const; - - void SetTypeDef( idTypeDef *_type ) { typeDef = _type; } - idTypeDef * TypeDef( void ) const { return typeDef; } - etype_t Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; } - - int DepthOfScope( const idVarDef *otherScope ) const; - - void SetFunction( function_t *func ); - void SetObject( idScriptObject *object ); - void SetValue( const eval_t &value, bool constant ); - void SetString( const char *string, bool constant ); - - idVarDef * Next( void ) const { return next; } // next var def with same name - - void PrintInfo( idFile *file, int instructionPointer ) const; - -private: - idTypeDef * typeDef; - idVarDefName * name; // name of this var - idVarDef * next; // next var with the same name -}; - -/*********************************************************************** - - idVarDefName - -***********************************************************************/ - -class idVarDefName { -public: - idVarDefName( void ) { defs = NULL; } - idVarDefName( const char *n ) { name = n; defs = NULL; } - - const char * Name( void ) const { return name; } - idVarDef * GetDefs( void ) const { return defs; } - - void AddDef( idVarDef *def ); - void RemoveDef( idVarDef *def ); - -private: - idStr name; - idVarDef * defs; -}; - -/*********************************************************************** - - Variable and type defintions - -***********************************************************************/ - -extern idTypeDef type_void; -extern idTypeDef type_scriptevent; -extern idTypeDef type_namespace; -extern idTypeDef type_string; -extern idTypeDef type_float; -extern idTypeDef type_vector; -extern idTypeDef type_entity; -extern idTypeDef type_field; -extern idTypeDef type_function; -extern idTypeDef type_virtualfunction; -extern idTypeDef type_pointer; -extern idTypeDef type_object; -extern idTypeDef type_jumpoffset; // only used for jump opcodes -extern idTypeDef type_argsize; // only used for function call and thread opcodes -extern idTypeDef type_boolean; - -extern idVarDef def_void; -extern idVarDef def_scriptevent; -extern idVarDef def_namespace; -extern idVarDef def_string; -extern idVarDef def_float; -extern idVarDef def_vector; -extern idVarDef def_entity; -extern idVarDef def_field; -extern idVarDef def_function; -extern idVarDef def_virtualfunction; -extern idVarDef def_pointer; -extern idVarDef def_object; -extern idVarDef def_jumpoffset; // only used for jump opcodes -extern idVarDef def_argsize; // only used for function call and thread opcodes -extern idVarDef def_boolean; - -typedef struct statement_s { - unsigned short op; - idVarDef *a; - idVarDef *b; - idVarDef *c; - unsigned short linenumber; - unsigned short file; -} statement_t; - -/*********************************************************************** - -idProgram - -Handles compiling and storage of script data. Multiple idProgram objects -would represent seperate programs with no knowledge of each other. Scripts -meant to access shared data and functions should all be compiled by a -single idProgram. - -***********************************************************************/ - -class idProgram { -private: - idStrList fileList; - idStr filename; - int filenum; - - int numVariables; - byte variables[ MAX_GLOBALS ]; - idStaticList variableDefaults; - idStaticList functions; - idStaticList statements; - idList types; - idList varDefNames; - idHashIndex varDefNameHash; - idList varDefs; - - idVarDef *sysDef; - - int top_functions; - int top_statements; - int top_types; - int top_defs; - int top_files; - - void CompileStats( void ); - -public: - idVarDef *returnDef; - idVarDef *returnStringDef; - - idProgram(); - ~idProgram(); - - // save games - void Save( idSaveGame *savefile ) const; - bool Restore( idRestoreGame *savefile ); - int CalculateChecksum( void ) const; // Used to insure program code has not - // changed between savegames - - void Startup( const char *defaultScript ); - void Restart( void ); - bool CompileText( const char *source, const char *text, bool console ); - const function_t *CompileFunction( const char *functionName, const char *text ); - void CompileFile( const char *filename ); - void BeginCompilation( void ); - void FinishCompilation( void ); - void DisassembleStatement( idFile *file, int instructionPointer ) const; - void Disassemble( void ) const; - void FreeData( void ); - - const char *GetFilename( int num ); - int GetFilenum( const char *name ); - int GetLineNumberForStatement( int index ); - const char *GetFilenameForStatement( int index ); - - idTypeDef *AllocType( idTypeDef &type ); - idTypeDef *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ); - idTypeDef *GetType( idTypeDef &type, bool allocate ); - idTypeDef *FindType( const char *name ); - - idVarDef *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ); - idVarDef *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const; - void FreeDef( idVarDef *d, const idVarDef *scope ); - idVarDef *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b ); - idVarDef *GetDefList( const char *name ) const; - void AddDefToNameList( idVarDef *def, const char *name ); - - function_t *FindFunction( const char *name ) const; // returns NULL if function not found - function_t *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found - function_t &AllocFunction( idVarDef *def ); - function_t *GetFunction( int index ); - int GetFunctionIndex( const function_t *func ); - - void SetEntity( const char *name, idEntity *ent ); - - statement_t *AllocStatement( void ); - statement_t &GetStatement( int index ); - int NumStatements( void ) { return statements.Num(); } - - int GetReturnedInteger( void ); - - void ReturnFloat( float value ); - void ReturnInteger( int value ); - void ReturnVector( idVec3 const &vec ); - void ReturnString( const char *string ); - void ReturnEntity( idEntity *ent ); - - int NumFilenames( void ) { return fileList.Num( ); } -}; - -/* -================ -idProgram::GetStatement -================ -*/ -ID_INLINE statement_t &idProgram::GetStatement( int index ) { - return statements[ index ]; -} - -/* -================ -idProgram::GetFunction -================ -*/ -ID_INLINE function_t *idProgram::GetFunction( int index ) { - return &functions[ index ]; -} - -/* -================ -idProgram::GetFunctionIndex -================ -*/ -ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) { - return func - &functions[0]; -} - -/* -================ -idProgram::GetReturnedInteger -================ -*/ -ID_INLINE int idProgram::GetReturnedInteger( void ) { - return *returnDef->value.intPtr; -} - -/* -================ -idProgram::ReturnFloat -================ -*/ -ID_INLINE void idProgram::ReturnFloat( float value ) { - *returnDef->value.floatPtr = value; -} - -/* -================ -idProgram::ReturnInteger -================ -*/ -ID_INLINE void idProgram::ReturnInteger( int value ) { - *returnDef->value.intPtr = value; -} - -/* -================ -idProgram::ReturnVector -================ -*/ -ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) { - *returnDef->value.vectorPtr = vec; -} - -/* -================ -idProgram::ReturnString -================ -*/ -ID_INLINE void idProgram::ReturnString( const char *string ) { - idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN ); -} - -/* -================ -idProgram::GetFilename -================ -*/ -ID_INLINE const char *idProgram::GetFilename( int num ) { - return fileList[ num ]; -} - -/* -================ -idProgram::GetLineNumberForStatement -================ -*/ -ID_INLINE int idProgram::GetLineNumberForStatement( int index ) { - return statements[ index ].linenumber; -} - -/* -================ -idProgram::GetFilenameForStatement -================ -*/ -ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) { - return GetFilename( statements[ index ].file ); -} - -#endif /* !__SCRIPT_PROGRAM_H__ */ diff --git a/game/script/script_thread.cpp b/game/script/script_thread.cpp deleted file mode 100644 index 5f56c595e..000000000 --- a/game/script/script_thread.cpp +++ /dev/null @@ -1,2082 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "../game_local.h" -#include "../../DarkMod/decltdm_matinfo.h" -#include "../../DarkMod/Relations.h" -#include "../../DarkMod/sndProp.h" -#include "../../DarkMod/Objectives/MissionData.h" -#include "../../DarkMod/Missions/MissionManager.h" - -class CRelations; -class CsndProp; - -const idEventDef EV_Thread_Execute( "", NULL ); -const idEventDef EV_Thread_SetCallback( "", NULL ); -const idEventDef EV_Thread_SetRenderCallback( "", NULL ); - -// script callable events -const idEventDef EV_Thread_TerminateThread( "terminate", "d" ); -const idEventDef EV_Thread_Pause( "pause", NULL ); -const idEventDef EV_Thread_Wait( "wait", "f" ); -const idEventDef EV_Thread_WaitFrame( "waitFrame" ); -const idEventDef EV_Thread_WaitFor( "waitFor", "e" ); -const idEventDef EV_Thread_WaitForThread( "waitForThread", "d" ); -const idEventDef EV_Thread_WaitForRender( "waitForRender", "e" ); -const idEventDef EV_Thread_Print( "print", "s" ); -const idEventDef EV_Thread_PrintLn( "println", "s" ); -const idEventDef EV_Thread_Say( "say", "s" ); -const idEventDef EV_Thread_Assert( "assert", "f" ); -const idEventDef EV_Thread_Trigger( "trigger", "e" ); -const idEventDef EV_Thread_SetCvar( "setcvar", "ss" ); -const idEventDef EV_Thread_GetCvar( "getcvar", "s", 's' ); -const idEventDef EV_Thread_Random( "random", "f", 'f' ); -const idEventDef EV_Thread_GetTime( "getTime", NULL, 'f' ); -const idEventDef EV_Thread_KillThread( "killthread", "s" ); -const idEventDef EV_Thread_SetThreadName( "threadname", "s" ); -const idEventDef EV_Thread_GetEntity( "getEntity", "s", 'e' ); -const idEventDef EV_Thread_Spawn( "spawn", "s", 'e' ); -const idEventDef EV_Thread_CopySpawnArgs( "copySpawnArgs", "e" ); -const idEventDef EV_Thread_SetSpawnArg( "setSpawnArg", "ss" ); -const idEventDef EV_Thread_SpawnString( "SpawnString", "ss", 's' ); -const idEventDef EV_Thread_SpawnFloat( "SpawnFloat", "sf", 'f' ); -const idEventDef EV_Thread_SpawnVector( "SpawnVector", "sv", 'v' ); -const idEventDef EV_Thread_ClearPersistantArgs( "clearPersistantArgs" ); -const idEventDef EV_Thread_SetPersistantArg( "setPersistantArg", "ss" ); -const idEventDef EV_Thread_GetPersistantString( "getPersistantString", "s", 's' ); -const idEventDef EV_Thread_GetPersistantFloat( "getPersistantFloat", "s", 'f' ); -const idEventDef EV_Thread_GetPersistantVector( "getPersistantVector", "s", 'v' ); - -// Returns the number of the current mission (0-based) -const idEventDef EV_Thread_GetCurrentMissionNum( "getCurrentMissionNum", NULL, 'f' ); - -const idEventDef EV_Thread_AngToForward( "angToForward", "v", 'v' ); -const idEventDef EV_Thread_AngToRight( "angToRight", "v", 'v' ); -const idEventDef EV_Thread_AngToUp( "angToUp", "v", 'v' ); -const idEventDef EV_Thread_Sine( "sin", "f", 'f' ); -const idEventDef EV_Thread_Cosine( "cos", "f", 'f' ); -const idEventDef EV_Thread_Log( "log", "f", 'f' ); -const idEventDef EV_Thread_Pow( "pow", "ff", 'f' ); -const idEventDef EV_Thread_SquareRoot( "sqrt", "f", 'f' ); -const idEventDef EV_Thread_Normalize( "vecNormalize", "v", 'v' ); -const idEventDef EV_Thread_VecLength( "vecLength", "v", 'f' ); -const idEventDef EV_Thread_VecDotProduct( "DotProduct", "vv", 'f' ); -const idEventDef EV_Thread_VecCrossProduct( "CrossProduct", "vv", 'v' ); -const idEventDef EV_Thread_VecToAngles( "VecToAngles", "v", 'v' ); -const idEventDef EV_Thread_OnSignal( "onSignal", "des" ); -const idEventDef EV_Thread_ClearSignal( "clearSignalThread", "de" ); -const idEventDef EV_Thread_SetCamera( "setCamera", "e" ); -const idEventDef EV_Thread_FirstPerson( "firstPerson", NULL ); -const idEventDef EV_Thread_Trace( "trace", "vvvvde", 'f' ); -const idEventDef EV_Thread_TracePoint( "tracePoint", "vvde", 'f' ); -const idEventDef EV_Thread_GetTraceFraction( "getTraceFraction", NULL, 'f' ); -const idEventDef EV_Thread_GetTraceEndPos( "getTraceEndPos", NULL, 'v' ); -const idEventDef EV_Thread_GetTraceNormal( "getTraceNormal", NULL, 'v' ); -const idEventDef EV_Thread_GetTraceEntity( "getTraceEntity", NULL, 'e' ); -const idEventDef EV_Thread_GetTraceJoint( "getTraceJoint", NULL, 's' ); -const idEventDef EV_Thread_GetTraceBody( "getTraceBody", NULL, 's' ); -const idEventDef EV_Thread_FadeIn( "fadeIn", "vf" ); -const idEventDef EV_Thread_FadeOut( "fadeOut", "vf" ); -const idEventDef EV_Thread_FadeTo( "fadeTo", "vff" ); -const idEventDef EV_Thread_StartMusic( "music", "s" ); -const idEventDef EV_Thread_Error( "error", "s" ); -const idEventDef EV_Thread_Warning( "warning", "s" ); -const idEventDef EV_Thread_StrLen( "strLength", "s", 'd' ); -const idEventDef EV_Thread_StrLeft( "strLeft", "sd", 's' ); -const idEventDef EV_Thread_StrRight( "strRight", "sd", 's' ); -const idEventDef EV_Thread_StrSkip( "strSkip", "sd", 's' ); -const idEventDef EV_Thread_StrMid( "strMid", "sdd", 's' ); -const idEventDef EV_Thread_StrToFloat( "strToFloat", "s", 'f' ); -const idEventDef EV_Thread_RadiusDamage( "radiusDamage", "vEEEsf" ); -const idEventDef EV_Thread_IsClient( "isClient", NULL, 'f' ); -const idEventDef EV_Thread_IsMultiplayer( "isMultiplayer", NULL, 'f' ); -const idEventDef EV_Thread_GetFrameTime( "getFrameTime", NULL, 'f' ); -const idEventDef EV_Thread_GetTicsPerSecond( "getTicsPerSecond", NULL, 'f' ); -const idEventDef EV_Thread_DebugLine( "debugLine", "vvvf" ); -const idEventDef EV_Thread_DebugArrow( "debugArrow", "vvvdf" ); -const idEventDef EV_Thread_DebugCircle( "debugCircle", "vvvfdf" ); -const idEventDef EV_Thread_DebugBounds( "debugBounds", "vvvf" ); -const idEventDef EV_Thread_DrawText( "drawText", "svfvdf" ); -const idEventDef EV_Thread_InfluenceActive( "influenceActive", NULL, 'd' ); - -//AI relationship manager events -const idEventDef EV_AI_GetRelationSys( "getRelation", "dd", 'd' ); -const idEventDef EV_AI_SetRelation( "setRelation", "ddd" ); -const idEventDef EV_AI_OffsetRelation( "offsetRelation", "ddd" ); - -// Dark Mod soundprop events -const idEventDef EV_TDM_SetPortSoundLoss( "setPortSoundLoss", "df" ); -const idEventDef EV_TDM_GetPortSoundLoss( "getPortSoundLoss", "d", 'f' ); - -// greebo: General water test function, tests if a point is in a liquid -const idEventDef EV_PointInLiquid( "pointInLiquid", "ve", 'f' ); - -const idEventDef EV_Thread_DebugTDM_MatInfo( "debug_tdm_material", "s" ); - -// greebo: Writes the string to the Darkmod.log file using DM_LOG -const idEventDef EV_LogString("logString", "dds"); - -// Propagates the string to the sessioncommand variable in gameLocal -const idEventDef EV_SessionCommand("sessionCommand", "s"); - -// Generic interface for passing on mission events from scripts to the SDK -// First argument is the entity which has triggered this event (e.g. a readable) -// Second argument is a numeric identifier (enumerated both in MissionData.h and tdm_defs.script) specifying the type of event -// Third argument is an optional string parameter -const idEventDef EV_HandleMissionEvent("handleMissionEvent", "eds"); - -const idEventDef EV_Thread_CanPlant( "canPlant", "vvEe", 'f' ); // grayman #2787 - -CLASS_DECLARATION( idClass, idThread ) - EVENT( EV_Thread_Execute, idThread::Event_Execute ) - EVENT( EV_Thread_TerminateThread, idThread::Event_TerminateThread ) - EVENT( EV_Thread_Pause, idThread::Event_Pause ) - EVENT( EV_Thread_Wait, idThread::Event_Wait ) - EVENT( EV_Thread_WaitFrame, idThread::Event_WaitFrame ) - EVENT( EV_Thread_WaitFor, idThread::Event_WaitFor ) - EVENT( EV_Thread_WaitForThread, idThread::Event_WaitForThread ) - EVENT( EV_Thread_WaitForRender, idThread::Event_WaitForRender ) - EVENT( EV_Thread_Print, idThread::Event_Print ) - EVENT( EV_Thread_PrintLn, idThread::Event_PrintLn ) - EVENT( EV_Thread_Say, idThread::Event_Say ) - EVENT( EV_Thread_Assert, idThread::Event_Assert ) - EVENT( EV_Thread_Trigger, idThread::Event_Trigger ) - EVENT( EV_Thread_SetCvar, idThread::Event_SetCvar ) - EVENT( EV_Thread_GetCvar, idThread::Event_GetCvar ) - EVENT( EV_Thread_Random, idThread::Event_Random ) - EVENT( EV_Thread_GetTime, idThread::Event_GetTime ) - EVENT( EV_Thread_KillThread, idThread::Event_KillThread ) - EVENT( EV_Thread_SetThreadName, idThread::Event_SetThreadName ) - EVENT( EV_Thread_GetEntity, idThread::Event_GetEntity ) - EVENT( EV_Thread_Spawn, idThread::Event_Spawn ) - EVENT( EV_Thread_CopySpawnArgs, idThread::Event_CopySpawnArgs ) - EVENT( EV_Thread_SetSpawnArg, idThread::Event_SetSpawnArg ) - EVENT( EV_Thread_SpawnString, idThread::Event_SpawnString ) - EVENT( EV_Thread_SpawnFloat, idThread::Event_SpawnFloat ) - EVENT( EV_Thread_SpawnVector, idThread::Event_SpawnVector ) - EVENT( EV_Thread_ClearPersistantArgs, idThread::Event_ClearPersistantArgs ) - EVENT( EV_Thread_SetPersistantArg, idThread::Event_SetPersistantArg ) - EVENT( EV_Thread_GetPersistantString, idThread::Event_GetPersistantString ) - EVENT( EV_Thread_GetPersistantFloat, idThread::Event_GetPersistantFloat ) - EVENT( EV_Thread_GetPersistantVector, idThread::Event_GetPersistantVector ) - - EVENT( EV_Thread_GetCurrentMissionNum, idThread::Event_GetCurrentMissionNum ) - - EVENT( EV_Thread_AngToForward, idThread::Event_AngToForward ) - EVENT( EV_Thread_AngToRight, idThread::Event_AngToRight ) - EVENT( EV_Thread_AngToUp, idThread::Event_AngToUp ) - EVENT( EV_Thread_Sine, idThread::Event_GetSine ) - EVENT( EV_Thread_Cosine, idThread::Event_GetCosine ) - EVENT( EV_Thread_Log, idThread::Event_GetLog ) - EVENT( EV_Thread_Pow, idThread::Event_GetPow ) - EVENT( EV_Thread_SquareRoot, idThread::Event_GetSquareRoot ) - EVENT( EV_Thread_Normalize, idThread::Event_VecNormalize ) - EVENT( EV_Thread_VecLength, idThread::Event_VecLength ) - EVENT( EV_Thread_VecDotProduct, idThread::Event_VecDotProduct ) - EVENT( EV_Thread_VecCrossProduct, idThread::Event_VecCrossProduct ) - EVENT( EV_Thread_VecToAngles, idThread::Event_VecToAngles ) - EVENT( EV_Thread_OnSignal, idThread::Event_OnSignal ) - EVENT( EV_Thread_ClearSignal, idThread::Event_ClearSignalThread ) - EVENT( EV_Thread_SetCamera, idThread::Event_SetCamera ) - EVENT( EV_Thread_FirstPerson, idThread::Event_FirstPerson ) - EVENT( EV_Thread_Trace, idThread::Event_Trace ) - EVENT( EV_Thread_TracePoint, idThread::Event_TracePoint ) - EVENT( EV_Thread_GetTraceFraction, idThread::Event_GetTraceFraction ) - EVENT( EV_Thread_GetTraceEndPos, idThread::Event_GetTraceEndPos ) - EVENT( EV_Thread_GetTraceNormal, idThread::Event_GetTraceNormal ) - EVENT( EV_Thread_GetTraceEntity, idThread::Event_GetTraceEntity ) - EVENT( EV_Thread_GetTraceJoint, idThread::Event_GetTraceJoint ) - EVENT( EV_Thread_GetTraceBody, idThread::Event_GetTraceBody ) - EVENT( EV_Thread_FadeIn, idThread::Event_FadeIn ) - EVENT( EV_Thread_FadeOut, idThread::Event_FadeOut ) - EVENT( EV_Thread_FadeTo, idThread::Event_FadeTo ) - EVENT( EV_SetShaderParm, idThread::Event_SetShaderParm ) - EVENT( EV_Thread_StartMusic, idThread::Event_StartMusic ) - EVENT( EV_Thread_Warning, idThread::Event_Warning ) - EVENT( EV_Thread_Error, idThread::Event_Error ) - EVENT( EV_Thread_StrLen, idThread::Event_StrLen ) - EVENT( EV_Thread_StrLeft, idThread::Event_StrLeft ) - EVENT( EV_Thread_StrRight, idThread::Event_StrRight ) - EVENT( EV_Thread_StrSkip, idThread::Event_StrSkip ) - EVENT( EV_Thread_StrMid, idThread::Event_StrMid ) - EVENT( EV_Thread_StrToFloat, idThread::Event_StrToFloat ) - EVENT( EV_Thread_RadiusDamage, idThread::Event_RadiusDamage ) - EVENT( EV_Thread_IsClient, idThread::Event_IsClient ) - EVENT( EV_Thread_IsMultiplayer, idThread::Event_IsMultiplayer ) - EVENT( EV_Thread_GetFrameTime, idThread::Event_GetFrameTime ) - EVENT( EV_Thread_GetTicsPerSecond, idThread::Event_GetTicsPerSecond ) - EVENT( EV_CacheSoundShader, idThread::Event_CacheSoundShader ) - EVENT( EV_Thread_DebugLine, idThread::Event_DebugLine ) - EVENT( EV_Thread_DebugArrow, idThread::Event_DebugArrow ) - EVENT( EV_Thread_DebugCircle, idThread::Event_DebugCircle ) - EVENT( EV_Thread_DebugBounds, idThread::Event_DebugBounds ) - EVENT( EV_Thread_DrawText, idThread::Event_DrawText ) - EVENT( EV_Thread_InfluenceActive, idThread::Event_InfluenceActive ) - - EVENT( EV_AI_GetRelationSys, idThread::Event_GetRelation ) - EVENT( EV_AI_SetRelation, idThread::Event_SetRelation ) - EVENT( EV_AI_OffsetRelation, idThread::Event_OffsetRelation ) - EVENT( EV_TDM_SetPortSoundLoss, idThread::Event_SetPortSoundLoss ) - EVENT( EV_TDM_GetPortSoundLoss, idThread::Event_GetPortSoundLoss ) - - EVENT( EV_PointInLiquid, idThread::Event_PointInLiquid ) - - EVENT( EV_Thread_DebugTDM_MatInfo, idThread::Event_DebugTDM_MatInfo ) - - EVENT( EV_LogString, idThread::Event_LogString ) - EVENT( EV_SessionCommand, idThread::Event_SessionCommand ) - - EVENT( EV_HandleMissionEvent, idThread::Event_HandleMissionEvent ) - - EVENT( EV_Thread_CanPlant, idThread::Event_CanPlant ) // grayman #2787 - - END_CLASS - -idThread *idThread::currentThread = NULL; -int idThread::threadIndex = 0; -idList idThread::threadList; -trace_t idThread::trace; - -#define VINE_TRACE_CONTENTS 1281 // grayman #2787 - CONTENTS_CORPSE|CONTENTS_BODY|CONTENTS_SOLID - -/* -================ -idThread::CurrentThread -================ -*/ -idThread *idThread::CurrentThread( void ) { - return currentThread; -} - -/* -================ -idThread::CurrentThreadNum -================ -*/ -int idThread::CurrentThreadNum( void ) { - if ( currentThread ) { - return currentThread->GetThreadNum(); - } else { - return 0; - } -} - -/* -================ -idThread::BeginMultiFrameEvent -================ -*/ -bool idThread::BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ) { - if ( !currentThread ) { - gameLocal.Error( "idThread::BeginMultiFrameEvent called without a current thread" ); - } - return currentThread->interpreter.BeginMultiFrameEvent( ent, event ); -} - -/* -================ -idThread::EndMultiFrameEvent -================ -*/ -void idThread::EndMultiFrameEvent( idEntity *ent, const idEventDef *event ) { - if ( !currentThread ) { - gameLocal.Error( "idThread::EndMultiFrameEvent called without a current thread" ); - } - currentThread->interpreter.EndMultiFrameEvent( ent, event ); -} - -/* -================ -idThread::idThread -================ -*/ -idThread::idThread() { - Init(); - SetThreadName( va( "thread_%d", threadIndex ) ); - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } -} - -/* -================ -idThread::idThread -================ -*/ -idThread::idThread( idEntity *self, const function_t *func ) { - assert( self ); - - Init(); - SetThreadName( self->name ); - interpreter.EnterObjectFunction( self, func, false ); - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } -} - -/* -================ -idThread::idThread -================ -*/ -idThread::idThread( const function_t *func ) { - assert( func ); - - Init(); - SetThreadName( func->Name() ); - interpreter.EnterFunction( func, false ); - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } -} - -/* -================ -idThread::idThread -================ -*/ -idThread::idThread( idInterpreter *source, const function_t *func, int args ) { - Init(); - interpreter.ThreadCall( source, func, args ); - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } -} - -/* -================ -idThread::idThread -================ -*/ -idThread::idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ) { - assert( self ); - - Init(); - SetThreadName( self->name ); - interpreter.ThreadCall( source, func, args ); - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: create thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } -} - -/* -================ -idThread::~idThread -================ -*/ -idThread::~idThread() { - idThread *thread; - int i; - int n; - - if ( g_debugScript.GetBool() ) { - gameLocal.Printf( "%d: end thread (%d) '%s'\n", gameLocal.time, threadNum, threadName.c_str() ); - } - threadList.Remove( this ); - n = threadList.Num(); - for( i = 0; i < n; i++ ) { - thread = threadList[ i ]; - if ( thread->WaitingOnThread() == this ) { - thread->ThreadCallback( this ); - } - } - - if ( currentThread == this ) { - currentThread = NULL; - } -} - -/* -================ -idThread::ManualDelete -================ -*/ -void idThread::ManualDelete( void ) { - interpreter.terminateOnExit = false; -} - -/* -================ -idThread::Save -================ -*/ -void idThread::Save( idSaveGame *savefile ) const { - - // We will check on restore that threadNum is still the same, - // threads should have been restored in the same order. - savefile->WriteInt( threadNum ); - - savefile->WriteObject( waitingForThread ); - savefile->WriteInt( waitingFor ); - savefile->WriteInt( waitingUntil ); - - interpreter.Save( savefile ); - - savefile->WriteDict( &spawnArgs ); - savefile->WriteString( threadName ); - - savefile->WriteInt( lastExecuteTime ); - savefile->WriteInt( creationTime ); - - savefile->WriteBool( manualControl ); -} - -/* -================ -idThread::Restore -================ -*/ -void idThread::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( threadNum ); - - savefile->ReadObject( reinterpret_cast( waitingForThread ) ); - savefile->ReadInt( waitingFor ); - savefile->ReadInt( waitingUntil ); - - interpreter.Restore( savefile ); - - savefile->ReadDict( &spawnArgs ); - savefile->ReadString( threadName ); - - savefile->ReadInt( lastExecuteTime ); - savefile->ReadInt( creationTime ); - - savefile->ReadBool( manualControl ); -} - -/* -================ -idThread::Init -================ -*/ -void idThread::Init( void ) { - // create a unique threadNum - do { - threadIndex++; - if ( threadIndex == 0 ) { - threadIndex = 1; - } - } while( GetThread( threadIndex ) ); - - threadNum = threadIndex; - threadList.Append( this ); - - creationTime = gameLocal.time; - lastExecuteTime = 0; - manualControl = false; - - ClearWaitFor(); - - interpreter.SetThread( this ); -} - -/* -================ -idThread::GetThread -================ -*/ -idThread *idThread::GetThread( int num ) { - int i; - int n; - idThread *thread; - - n = threadList.Num(); - for( i = 0; i < n; i++ ) { - thread = threadList[ i ]; - if ( thread->GetThreadNum() == num ) { - return thread; - } - } - - return NULL; -} - -/* -================ -idThread::DisplayInfo -================ -*/ -void idThread::DisplayInfo( void ) { - gameLocal.Printf( - "%12i: '%s'\n" - " File: %s(%d)\n" - " Created: %d (%d ms ago)\n" - " Status: ", - threadNum, threadName.c_str(), - interpreter.CurrentFile(), interpreter.CurrentLine(), - creationTime, gameLocal.time - creationTime ); - - if ( interpreter.threadDying ) { - gameLocal.Printf( "Dying\n" ); - } else if ( interpreter.doneProcessing ) { - gameLocal.Printf( - "Paused since %d (%d ms)\n" - " Reason: ", lastExecuteTime, gameLocal.time - lastExecuteTime ); - if ( waitingForThread ) { - gameLocal.Printf( "Waiting for thread #%3i '%s'\n", waitingForThread->GetThreadNum(), waitingForThread->GetThreadName() ); - } else if ( ( waitingFor != ENTITYNUM_NONE ) && ( gameLocal.entities[ waitingFor ] ) ) { - gameLocal.Printf( "Waiting for entity #%3i '%s'\n", waitingFor, gameLocal.entities[ waitingFor ]->name.c_str() ); - } else if ( waitingUntil ) { - gameLocal.Printf( "Waiting until %d (%d ms total wait time)\n", waitingUntil, waitingUntil - lastExecuteTime ); - } else { - gameLocal.Printf( "None\n" ); - } - } else { - gameLocal.Printf( "Processing\n" ); - } - - interpreter.DisplayInfo(); - - gameLocal.Printf( "\n" ); -} - -/* -================ -idThread::ListThreads_f -================ -*/ -void idThread::ListThreads_f( const idCmdArgs &args ) { - int i; - int n; - - n = threadList.Num(); - for( i = 0; i < n; i++ ) { - //threadList[ i ]->DisplayInfo(); - gameLocal.Printf( "%3i: %-20s : %s(%d)\n", threadList[ i ]->threadNum, threadList[ i ]->threadName.c_str(), threadList[ i ]->interpreter.CurrentFile(), threadList[ i ]->interpreter.CurrentLine() ); - } - gameLocal.Printf( "%d active threads\n\n", n ); -} - -/* -================ -idThread::Restart -================ -*/ -void idThread::Restart( void ) { - int i; - int n; - - // reset the threadIndex - threadIndex = 0; - - currentThread = NULL; - n = threadList.Num(); - for( i = n - 1; i >= 0; i-- ) { - delete threadList[ i ]; - } - threadList.Clear(); - - memset( &trace, 0, sizeof( trace ) ); - trace.c.entityNum = ENTITYNUM_NONE; -} - -/* -================ -idThread::DelayedStart -================ -*/ -void idThread::DelayedStart( int delay ) { - CancelEvents( &EV_Thread_Execute ); - if ( gameLocal.time <= 0 ) { - delay++; - } - PostEventMS( &EV_Thread_Execute, delay ); -} - -/* -================ -idThread::Start -================ -*/ -bool idThread::Start( void ) { - bool result; - - CancelEvents( &EV_Thread_Execute ); - result = Execute(); - - return result; -} - -/* -================ -idThread::SetThreadName -================ -*/ -void idThread::SetThreadName( const char *name ) { - threadName = name; -} - -/* -================ -idThread::ObjectMoveDone -================ -*/ -void idThread::ObjectMoveDone( int threadnum, idEntity *obj ) { - idThread *thread; - - if ( !threadnum ) { - return; - } - - thread = GetThread( threadnum ); - if ( thread ) { - thread->ObjectMoveDone( obj ); - } -} - -/* -================ -idThread::End -================ -*/ -void idThread::End( void ) { - // Tell thread to die. It will exit on its own. - Pause(); - interpreter.threadDying = true; -} - -/* -================ -idThread::KillThread -================ -*/ -void idThread::KillThread( const char *name ) { - int i; - int num; - int len; - const char *ptr; - idThread *thread; - - // see if the name uses a wild card - ptr = strchr( name, '*' ); - if ( ptr ) { - len = ptr - name; - } else { - len = strlen( name ); - } - - // kill only those threads whose name matches name - num = threadList.Num(); - for( i = 0; i < num; i++ ) { - thread = threadList[ i ]; - if ( !idStr::Cmpn( thread->GetThreadName(), name, len ) ) { - thread->End(); - } - } -} - -/* -================ -idThread::KillThread -================ -*/ -void idThread::KillThread( int num ) { - idThread *thread; - - thread = GetThread( num ); - if ( thread ) { - // Tell thread to die. It will delete itself on it's own. - thread->End(); - } -} - -/* -================ -idThread::Execute -================ -*/ -bool idThread::Execute( void ) { - idThread *oldThread; - bool done; - - if ( manualControl && ( waitingUntil > gameLocal.time ) ) { - return false; - } - - oldThread = currentThread; - currentThread = this; - - lastExecuteTime = gameLocal.time; - ClearWaitFor(); - done = interpreter.Execute(); - if ( done ) { - End(); - if ( interpreter.terminateOnExit ) { - PostEventMS( &EV_Remove, 0 ); - } - } else if ( !manualControl ) { - if ( waitingUntil > lastExecuteTime ) { - PostEventMS( &EV_Thread_Execute, waitingUntil - lastExecuteTime ); - } else if ( interpreter.MultiFrameEventInProgress() ) { - PostEventMS( &EV_Thread_Execute, gameLocal.msec ); - } - } - - currentThread = oldThread; - - return done; -} - -/* -================ -idThread::IsWaiting - -Checks if thread is still waiting for some event to occur. -================ -*/ -bool idThread::IsWaiting( void ) { - if ( waitingForThread || ( waitingFor != ENTITYNUM_NONE ) ) { - return true; - } - - if ( waitingUntil && ( waitingUntil > gameLocal.time ) ) { - return true; - } - - return false; -} - -/* -================ -idThread::CallFunction - -NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. -================ -*/ -void idThread::CallFunction( const function_t *func, bool clearStack ) { - ClearWaitFor(); - interpreter.EnterFunction( func, clearStack ); -} - -/* -================ -idThread::CallFunction - -NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. -================ -*/ -void idThread::CallFunction( idEntity *self, const function_t *func, bool clearStack ) { - assert( self ); - ClearWaitFor(); - interpreter.EnterObjectFunction( self, func, clearStack ); -} - -/* -================ -idThread::ClearWaitFor -================ -*/ -void idThread::ClearWaitFor( void ) { - waitingFor = ENTITYNUM_NONE; - waitingForThread = NULL; - waitingUntil = 0; -} - -/* -================ -idThread::IsWaitingFor -================ -*/ -bool idThread::IsWaitingFor( idEntity *obj ) { - assert( obj ); - return waitingFor == obj->entityNumber; -} - -/* -================ -idThread::ObjectMoveDone -================ -*/ -void idThread::ObjectMoveDone( idEntity *obj ) { - assert( obj ); - - if ( IsWaitingFor( obj ) ) { - ClearWaitFor(); - DelayedStart( 0 ); - } -} - -/* -================ -idThread::ThreadCallback -================ -*/ -void idThread::ThreadCallback( idThread *thread ) { - if ( interpreter.threadDying ) { - return; - } - - if ( thread == waitingForThread ) { - ClearWaitFor(); - DelayedStart( 0 ); - } -} - -/* -================ -idThread::Event_SetThreadName -================ -*/ -void idThread::Event_SetThreadName( const char *name ) { - SetThreadName( name ); -} - -/* -================ -idThread::Error -================ -*/ -void idThread::Error( const char *fmt, ... ) const { - va_list argptr; - char text[ 1024 ]; - - va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); - va_end( argptr ); - - interpreter.Error( text ); -} - -/* -================ -idThread::Warning -================ -*/ -void idThread::Warning( const char *fmt, ... ) const { - va_list argptr; - char text[ 1024 ]; - - va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); - va_end( argptr ); - - interpreter.Warning( text ); -} - -/* -================ -idThread::ReturnString -================ -*/ -void idThread::ReturnString( const char *text ) { - gameLocal.program.ReturnString( text ); -} - -/* -================ -idThread::ReturnFloat -================ -*/ -void idThread::ReturnFloat( float value ) { - gameLocal.program.ReturnFloat( value ); -} - -/* -================ -idThread::ReturnInt -================ -*/ -void idThread::ReturnInt( int value ) { - // true integers aren't supported in the compiler, - // so int values are stored as floats - gameLocal.program.ReturnFloat( value ); -} - -/* -================ -idThread::ReturnVector -================ -*/ -void idThread::ReturnVector( idVec3 const &vec ) { - gameLocal.program.ReturnVector( vec ); -} - -/* -================ -idThread::ReturnEntity -================ -*/ -void idThread::ReturnEntity( idEntity *ent ) { - gameLocal.program.ReturnEntity( ent ); -} - -/* -================ -idThread::Event_Execute -================ -*/ -void idThread::Event_Execute( void ) { - Execute(); -} - -/* -================ -idThread::Pause -================ -*/ -void idThread::Pause( void ) { - ClearWaitFor(); - interpreter.doneProcessing = true; -} - -/* -================ -idThread::WaitMS -================ -*/ -void idThread::WaitMS( int time ) { - Pause(); - waitingUntil = gameLocal.time + time; -} - -/* -================ -idThread::WaitSec -================ -*/ -void idThread::WaitSec( float time ) { - WaitMS( SEC2MS( time ) ); -} - -/* -================ -idThread::WaitFrame -================ -*/ -void idThread::WaitFrame( void ) { - Pause(); - - // manual control threads don't set waitingUntil so that they can be run again - // that frame if necessary. - if ( !manualControl ) { - waitingUntil = gameLocal.time + gameLocal.msec; - } -} - -/*********************************************************************** - - Script callable events - -***********************************************************************/ - -/* -================ -idThread::Event_TerminateThread -================ -*/ -void idThread::Event_TerminateThread( int num ) { - idThread *thread; - - thread = GetThread( num ); - KillThread( num ); -} - -/* -================ -idThread::Event_Pause -================ -*/ -void idThread::Event_Pause( void ) { - Pause(); -} - -/* -================ -idThread::Event_Wait -================ -*/ -void idThread::Event_Wait( float time ) { - WaitSec( time ); -} - -/* -================ -idThread::Event_WaitFrame -================ -*/ -void idThread::Event_WaitFrame( void ) { - WaitFrame(); -} - -/* -================ -idThread::Event_WaitFor -================ -*/ -void idThread::Event_WaitFor( idEntity *ent ) { - if ( ent && ent->RespondsTo( EV_Thread_SetCallback ) ) { - ent->ProcessEvent( &EV_Thread_SetCallback ); - if ( gameLocal.program.GetReturnedInteger() ) { - Pause(); - waitingFor = ent->entityNumber; - } - } -} - -/* -================ -idThread::Event_WaitForThread -================ -*/ -void idThread::Event_WaitForThread( int num ) { - idThread *thread; - - thread = GetThread( num ); - if ( !thread ) { - if ( g_debugScript.GetBool() ) { - // just print a warning and continue executing - Warning( "Thread %d not running", num ); - } - } else { - Pause(); - waitingForThread = thread; - } -} - -/* -================ -idThread::Event_WaitForRender - -Waits for an entity to render before resuming. -================ -*/ -void idThread::Event_WaitForRender( idEntity* ent ) -{ - if ( ent && ent->RespondsTo( EV_Thread_SetRenderCallback ) ) { - ent->ProcessEvent( &EV_Thread_SetRenderCallback ); - if ( gameLocal.program.GetReturnedInteger() ) { - Pause(); - waitingFor = ent->entityNumber; - } - } -} - -/* -================ -idThread::Event_Print -================ -*/ -void idThread::Event_Print( const char *text ) { - gameLocal.Printf( "%s", text ); -} - -/* -================ -idThread::Event_PrintLn -================ -*/ -void idThread::Event_PrintLn( const char *text ) { - gameLocal.Printf( "%s\n", text ); -} - -/* -================ -idThread::Event_Say -================ -*/ -void idThread::Event_Say( const char *text ) { - cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say \"%s\"", text ) ); -} - -/* -================ -idThread::Event_Assert -================ -*/ -void idThread::Event_Assert( float value ) { - assert( value ); -} - -/* -================ -idThread::Event_Trigger -================ -*/ -void idThread::Event_Trigger( idEntity *ent ) { - if ( ent ) { - ent->Activate(NULL); - } -} - -/* -================ -idThread::Event_SetCvar -================ -*/ -void idThread::Event_SetCvar( const char *name, const char *value ) const { - cvarSystem->SetCVarString( name, value ); -} - -/* -================ -idThread::Event_GetCvar -================ -*/ -void idThread::Event_GetCvar( const char *name ) const { - ReturnString( cvarSystem->GetCVarString( name ) ); -} - -/* -================ -idThread::Event_Random -================ -*/ -void idThread::Event_Random( float range ) const { - float result; - - result = gameLocal.random.RandomFloat(); - ReturnFloat( range * result ); -} - -/* -================ -idThread::Event_GetTime -================ -*/ -void idThread::Event_GetTime( void ) { - ReturnFloat( MS2SEC( gameLocal.realClientTime ) ); -} - -/* -================ -idThread::Event_KillThread -================ -*/ -void idThread::Event_KillThread( const char *name ) { - KillThread( name ); -} - -/* -================ -idThread::Event_GetEntity -================ -*/ -void idThread::Event_GetEntity( const char *name ) { - int entnum; - idEntity *ent; - - assert( name ); - - if ( name[ 0 ] == '*' ) { - entnum = atoi( &name[ 1 ] ); - if ( ( entnum < 0 ) || ( entnum >= MAX_GENTITIES ) ) { - Error( "Entity number in string out of range." ); - } - ReturnEntity( gameLocal.entities[ entnum ] ); - } else { - ent = gameLocal.FindEntity( name ); - ReturnEntity( ent ); - } -} - -/* -================ -idThread::Event_Spawn -================ -*/ -void idThread::Event_Spawn( const char *classname ) { - idEntity *ent; - - spawnArgs.Set( "classname", classname ); - gameLocal.SpawnEntityDef( spawnArgs, &ent ); - ReturnEntity( ent ); - spawnArgs.Clear(); -} - -/* -================ -idThread::Event_CopySpawnArgs -================ -*/ -void idThread::Event_CopySpawnArgs( idEntity *ent ) { - spawnArgs.Copy( ent->spawnArgs ); -} - -/* -================ -idThread::Event_SetSpawnArg -================ -*/ -void idThread::Event_SetSpawnArg( const char *key, const char *value ) { - spawnArgs.Set( key, value ); -} - -/* -================ -idThread::Event_SpawnString -================ -*/ -void idThread::Event_SpawnString( const char *key, const char *defaultvalue ) { - const char *result; - - spawnArgs.GetString( key, defaultvalue, &result ); - ReturnString( result ); -} - -/* -================ -idThread::Event_SpawnFloat -================ -*/ -void idThread::Event_SpawnFloat( const char *key, float defaultvalue ) { - float result; - - spawnArgs.GetFloat( key, va( "%f", defaultvalue ), result ); - ReturnFloat( result ); -} - -/* -================ -idThread::Event_SpawnVector -================ -*/ -void idThread::Event_SpawnVector( const char *key, idVec3 &defaultvalue ) { - idVec3 result; - - spawnArgs.GetVector( key, va( "%f %f %f", defaultvalue.x, defaultvalue.y, defaultvalue.z ), result ); - ReturnVector( result ); -} - -/* -================ -idThread::Event_ClearPersistantArgs -================ -*/ -void idThread::Event_ClearPersistantArgs( void ) { - gameLocal.persistentLevelInfo.Clear(); -} - - -/* -================ -idThread::Event_SetPersistantArg -================ -*/ -void idThread::Event_SetPersistantArg( const char *key, const char *value ) { - gameLocal.persistentLevelInfo.Set( key, value ); -} - -/* -================ -idThread::Event_GetPersistantString -================ -*/ -void idThread::Event_GetPersistantString( const char *key ) { - const char *result; - - gameLocal.persistentLevelInfo.GetString( key, "", &result ); - ReturnString( result ); -} - -/* -================ -idThread::Event_GetPersistantFloat -================ -*/ -void idThread::Event_GetPersistantFloat( const char *key ) { - float result; - - gameLocal.persistentLevelInfo.GetFloat( key, "0", result ); - ReturnFloat( result ); -} - -/* -================ -idThread::Event_GetPersistantVector -================ -*/ -void idThread::Event_GetPersistantVector( const char *key ) { - idVec3 result; - - gameLocal.persistentLevelInfo.GetVector( key, "0 0 0", result ); - ReturnVector( result ); -} - -void idThread::Event_GetCurrentMissionNum() -{ - ReturnFloat(gameLocal.m_MissionManager->GetCurrentMissionIndex()); -} - -/* -================ -idThread::Event_AngToForward -================ -*/ -void idThread::Event_AngToForward( idAngles &ang ) { - ReturnVector( ang.ToForward() ); -} - -/* -================ -idThread::Event_AngToRight -================ -*/ -void idThread::Event_AngToRight( idAngles &ang ) { - idVec3 vec; - - ang.ToVectors( NULL, &vec ); - ReturnVector( vec ); -} - -/* -================ -idThread::Event_AngToUp -================ -*/ -void idThread::Event_AngToUp( idAngles &ang ) { - idVec3 vec; - - ang.ToVectors( NULL, NULL, &vec ); - ReturnVector( vec ); -} - -/* -================ -idThread::Event_GetSine -================ -*/ -void idThread::Event_GetSine( const float angle ) { - ReturnFloat( idMath::Sin( DEG2RAD( angle ) ) ); -} - -/* -================ -idThread::Event_GetCosine -================ -*/ -void idThread::Event_GetCosine( const float angle ) { - ReturnFloat( idMath::Cos( DEG2RAD( angle ) ) ); -} - -/* -================ -Tels: idThread::Event_GetLog -================ -*/ -void idThread::Event_GetLog( const float x ) { - ReturnFloat( idMath::Log( x ) ); -} - -/* -================ -Tels: idThread::Event_GetPow -================ -*/ -void idThread::Event_GetPow( const float x, const float y ) { - ReturnFloat( idMath::Pow( x, y ) ); -} - -/* -================ -idThread::Event_GetSquareRoot -================ -*/ -void idThread::Event_GetSquareRoot( float theSquare ) { - ReturnFloat( idMath::Sqrt( theSquare ) ); -} - -/* -================ -idThread::Event_VecNormalize -================ -*/ -void idThread::Event_VecNormalize( idVec3 &vec ) { - idVec3 n; - - n = vec; - n.Normalize(); - ReturnVector( n ); -} - -/* -================ -idThread::Event_VecLength -================ -*/ -void idThread::Event_VecLength( idVec3 &vec ) { - ReturnFloat( vec.Length() ); -} - -/* -================ -idThread::Event_VecDotProduct -================ -*/ -void idThread::Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ) { - ReturnFloat( vec1 * vec2 ); -} - -/* -================ -idThread::Event_VecCrossProduct -================ -*/ -void idThread::Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ) { - ReturnVector( vec1.Cross( vec2 ) ); -} - -/* -================ -idThread::Event_VecToAngles -================ -*/ -void idThread::Event_VecToAngles( idVec3 &vec ) { - idAngles ang = vec.ToAngles(); - ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); -} - -/* -================ -idThread::Event_OnSignal -================ -*/ -void idThread::Event_OnSignal( int signal, idEntity *ent, const char *func ) { - const function_t *function; - - assert( func ); - - if ( !ent ) { - Error( "Entity not found" ); - } - - if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) { - Error( "Signal out of range" ); - } - - function = gameLocal.program.FindFunction( func ); - if ( !function ) { - Error( "Function '%s' not found", func ); - } - - ent->SetSignal( ( signalNum_t )signal, this, function ); -} - -/* -================ -idThread::Event_ClearSignalThread -================ -*/ -void idThread::Event_ClearSignalThread( int signal, idEntity *ent ) { - if ( !ent ) { - Error( "Entity not found" ); - } - - if ( ( signal < 0 ) || ( signal >= NUM_SIGNALS ) ) { - Error( "Signal out of range" ); - } - - ent->ClearSignalThread( ( signalNum_t )signal, this ); -} - -/* -================ -idThread::Event_SetCamera -================ -*/ -void idThread::Event_SetCamera( idEntity *ent ) { - if ( !ent ) { - Error( "Entity not found" ); - return; - } - - if ( !ent->IsType( idCamera::Type ) ) { - Error( "Entity is not a camera" ); - return; - } - - gameLocal.SetCamera( ( idCamera * )ent ); -} - -/* -================ -idThread::Event_FirstPerson -================ -*/ -void idThread::Event_FirstPerson( void ) { - gameLocal.SetCamera( NULL ); -} - -/* -================ -idThread::Event_Trace -================ -*/ -void idThread::Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ) { - if ( mins == vec3_origin && maxs == vec3_origin ) { - gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity ); - } else { - gameLocal.clip.TraceBounds( trace, start, end, idBounds( mins, maxs ), contents_mask, passEntity ); - } - ReturnFloat( trace.fraction ); -} - -/* -================ -idThread::Event_TracePoint -================ -*/ -void idThread::Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ) { - gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity ); - ReturnFloat( trace.fraction ); -} - -/* -================ -idThread::Event_GetTraceFraction -================ -*/ -void idThread::Event_GetTraceFraction( void ) { - ReturnFloat( trace.fraction ); -} - -/* -================ -idThread::Event_GetTraceEndPos -================ -*/ -void idThread::Event_GetTraceEndPos( void ) { - ReturnVector( trace.endpos ); -} - -/* -================ -idThread::Event_GetTraceNormal -================ -*/ -void idThread::Event_GetTraceNormal( void ) { - if ( trace.fraction < 1.0f ) { - ReturnVector( trace.c.normal ); - } else { - ReturnVector( vec3_origin ); - } -} - -/* -================ -idThread::Event_GetTraceEntity -================ -*/ -void idThread::Event_GetTraceEntity( void ) { - if ( trace.fraction < 1.0f ) { - ReturnEntity( gameLocal.entities[ trace.c.entityNum ] ); - } else { - ReturnEntity( ( idEntity * )NULL ); - } -} - -/* -================ -idThread::Event_GetTraceJoint -================ -*/ -void idThread::Event_GetTraceJoint( void ) { - if ( trace.fraction < 1.0f && trace.c.id < 0 ) { - idAFEntity_Base *af = static_cast( gameLocal.entities[ trace.c.entityNum ] ); - if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) { - ReturnString( af->GetAnimator()->GetJointName( CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id ) ) ); - return; - } - } - ReturnString( "" ); -} - -/* -================ -idThread::Event_GetTraceBody -================ -*/ -void idThread::Event_GetTraceBody( void ) { - if ( trace.fraction < 1.0f && trace.c.id < 0 ) { - idAFEntity_Base *af = static_cast( gameLocal.entities[ trace.c.entityNum ] ); - if ( af && af->IsType( idAFEntity_Base::Type ) && af->IsActiveAF() ) { - int bodyId = af->BodyForClipModelId( trace.c.id ); - idAFBody *body = af->GetAFPhysics()->GetBody( bodyId ); - if ( body ) { - ReturnString( body->GetName() ); - return; - } - } - } - ReturnString( "" ); -} - -/* -================ -idThread::Event_FadeIn -================ -*/ -void idThread::Event_FadeIn( idVec3 &color, float time ) { - idVec4 fadeColor; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( player ) { - fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 0.0f ); - player->playerView.Fade(fadeColor, SEC2MS( time ) ); - } -} - -/* -================ -idThread::Event_FadeOut -================ -*/ -void idThread::Event_FadeOut( idVec3 &color, float time ) { - idVec4 fadeColor; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( player ) { - fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], 1.0f ); - player->playerView.Fade(fadeColor, SEC2MS( time ) ); - } -} - -/* -================ -idThread::Event_FadeTo -================ -*/ -void idThread::Event_FadeTo( idVec3 &color, float alpha, float time ) { - idVec4 fadeColor; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( player ) { - fadeColor.Set( color[ 0 ], color[ 1 ], color[ 2 ], alpha ); - player->playerView.Fade(fadeColor, SEC2MS( time ) ); - } -} - -/* -================ -idThread::Event_SetShaderParm -================ -*/ -void idThread::Event_SetShaderParm( int parmnum, float value ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_GLOBAL_SHADER_PARMS ) ) { - Error( "shader parm index (%d) out of range", parmnum ); - } - - gameLocal.globalShaderParms[ parmnum ] = value; -} - -/* -================ -idThread::Event_StartMusic -================ -*/ -void idThread::Event_StartMusic( const char *text ) { - gameSoundWorld->PlayShaderDirectly( text ); -} - -/* -================ -idThread::Event_Warning -================ -*/ -void idThread::Event_Warning( const char *text ) { - Warning( "%s", text ); -} - -/* -================ -idThread::Event_Error -================ -*/ -void idThread::Event_Error( const char *text ) { - Error( "%s", text ); -} - -/* -================ -idThread::Event_StrLen -================ -*/ -void idThread::Event_StrLen( const char *string ) { - int len; - - len = strlen( string ); - idThread::ReturnInt( len ); -} - -/* -================ -idThread::Event_StrLeft -================ -*/ -void idThread::Event_StrLeft( const char *string, int num ) { - int len; - - if ( num < 0 ) { - idThread::ReturnString( "" ); - return; - } - - len = strlen( string ); - if ( len < num ) { - idThread::ReturnString( string ); - return; - } - - idStr result( string, 0, num ); - idThread::ReturnString( result ); -} - -/* -================ -idThread::Event_StrRight -================ -*/ -void idThread::Event_StrRight( const char *string, int num ) { - int len; - - if ( num < 0 ) { - idThread::ReturnString( "" ); - return; - } - - len = strlen( string ); - if ( len < num ) { - idThread::ReturnString( string ); - return; - } - - idThread::ReturnString( string + len - num ); -} - -/* -================ -idThread::Event_StrSkip -================ -*/ -void idThread::Event_StrSkip( const char *string, int num ) { - int len; - - if ( num < 0 ) { - idThread::ReturnString( string ); - return; - } - - len = strlen( string ); - if ( len < num ) { - idThread::ReturnString( "" ); - return; - } - - idThread::ReturnString( string + num ); -} - -/* -================ -idThread::Event_StrMid -================ -*/ -void idThread::Event_StrMid( const char *string, int start, int num ) { - int len; - - if ( num < 0 ) { - idThread::ReturnString( "" ); - return; - } - - if ( start < 0 ) { - start = 0; - } - len = strlen( string ); - if ( start > len ) { - start = len; - } - - if ( start + num > len ) { - num = len - start; - } - - idStr result( string, start, start + num ); - idThread::ReturnString( result ); -} - -/* -================ -idThread::Event_StrToFloat( const char *string ) -================ -*/ -void idThread::Event_StrToFloat( const char *string ) { - float result; - - result = atof( string ); - idThread::ReturnFloat( result ); -} - -/* -================ -idThread::Event_RadiusDamage -================ -*/ -void idThread::Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ) { - gameLocal.RadiusDamage( origin, inflictor, attacker, ignore, ignore, damageDefName, dmgPower ); -} - -/* -================ -idThread::Event_IsClient -================ -*/ -void idThread::Event_IsClient( void ) { - idThread::ReturnFloat( gameLocal.isClient ); -} - -/* -================ -idThread::Event_IsMultiplayer -================ -*/ -void idThread::Event_IsMultiplayer( void ) { - idThread::ReturnFloat( gameLocal.isMultiplayer ); -} - -/* -================ -idThread::Event_GetFrameTime -================ -*/ -void idThread::Event_GetFrameTime( void ) { - idThread::ReturnFloat( MS2SEC( gameLocal.msec ) ); -} - -/* -================ -idThread::Event_GetTicsPerSecond -================ -*/ -void idThread::Event_GetTicsPerSecond( void ) { - idThread::ReturnFloat( USERCMD_HZ ); -} - -/* -================ -idThread::Event_CacheSoundShader -================ -*/ -void idThread::Event_CacheSoundShader( const char *soundName ) { - declManager->FindSound( soundName ); -} - -/* -================ -idThread::Event_DebugLine -================ -*/ -void idThread::Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ) { - gameRenderWorld->DebugLine( idVec4( color.x, color.y, color.z, 0.0f ), start, end, SEC2MS( lifetime ) ); -} - -/* -================ -idThread::Event_DebugArrow -================ -*/ -void idThread::Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ) { - gameRenderWorld->DebugArrow( idVec4( color.x, color.y, color.z, 0.0f ), start, end, size, SEC2MS( lifetime ) ); -} - -/* -================ -idThread::Event_DebugCircle -================ -*/ -void idThread::Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ) { - gameRenderWorld->DebugCircle( idVec4( color.x, color.y, color.z, 0.0f ), origin, dir, radius, numSteps, SEC2MS( lifetime ) ); -} - -/* -================ -idThread::Event_DebugBounds -================ -*/ -void idThread::Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ) { - gameRenderWorld->DebugBounds( idVec4( color.x, color.y, color.z, 0.0f ), idBounds( mins, maxs ), vec3_origin, SEC2MS( lifetime ) ); -} - -/* -================ -idThread::Event_DrawText -================ -*/ -void idThread::Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ) { - gameRenderWorld->DrawText( text, origin, scale, idVec4( color.x, color.y, color.z, 0.0f ), gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), align, SEC2MS( lifetime ) ); -} - -/* -================ -idThread::Event_InfluenceActive -================ -*/ -void idThread::Event_InfluenceActive( void ) { - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( player && player->GetInfluenceLevel() ) { - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); - } -} - -/** -* DarkMod: The following script events are a frontend for -* the global AI relationship manager (stored in game_local) -**/ -void idThread::Event_GetRelation( int team1, int team2 ) -{ - idThread::ReturnInt( gameLocal.m_RelationsManager->GetRelNum( team1, team2 ) ); -} - -void idThread::Event_SetRelation( int team1, int team2, int val ) -{ - gameLocal.m_RelationsManager->SetRel( team1, team2, val ); -} - -void idThread::Event_OffsetRelation( int team1, int team2, int offset ) -{ - gameLocal.m_RelationsManager->ChangeRel( team1, team2, offset ); -} - -void idThread::Event_SetPortSoundLoss( int handle, float value ) -{ - gameLocal.m_sndProp->SetPortalLoss( handle, value ); -} - -void idThread::Event_GetPortSoundLoss( int handle ) -{ - idThread::ReturnFloat( gameLocal.m_sndProp->GetPortalLoss( handle ) ); -} - -void idThread::Event_LogString(int logClass, int logType, const char* output) -{ - DM_LOG(static_cast(logClass), static_cast(logType))LOGSTRING(const_cast(output)); -} - -/* -================ -idThread::CallFunctionArgs - -NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. -================ -*/ -bool idThread::CallFunctionArgs(const function_t *func, bool clearStack, const char *fmt, ...) -{ - bool rc = false; - va_list argptr; - - ClearWaitFor(); - - va_start(argptr, fmt); - rc = interpreter.EnterFunctionVarArgVN(func, clearStack, fmt, argptr); - va_end(argptr); - - return rc; -} - -bool idThread::CallFunctionArgsVN(const function_t *func, bool clearStack, const char *fmt, va_list args) -{ - bool rc = false; - - ClearWaitFor(); - - rc = interpreter.EnterFunctionVarArgVN(func, clearStack, fmt, args); - - return rc; -} - -void idThread::Event_DebugTDM_MatInfo( const char *mat ) -{ - const tdmDeclTDM_MatInfo *tdmat = static_cast< const tdmDeclTDM_MatInfo* >( declManager->FindType( DECL_TDM_MATINFO, mat, false ) ); - if ( tdmat != NULL ) { - gameLocal.Printf( "Information for tdm material declaration: %s\n", mat ); - gameLocal.Printf( "surfacetype: %s\n", tdmat->surfaceType.c_str() ); - } else { - gameLocal.Warning( "Non-existant tdm material declaration: %s", mat ); - } -} - -void idThread::Event_PointInLiquid( const idVec3 &point, idEntity* ignoreEntity ) { - // Check if the point is in water - int contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, ignoreEntity ); - ReturnFloat( (contents & MASK_WATER) ? 1 : 0); -} - -void idThread::Event_SessionCommand(const char* cmd) -{ - gameLocal.sessionCommand = cmd; -} - -void idThread::Event_HandleMissionEvent(idEntity* entity, int eventType, const char* argument) -{ - // Safety check the enum - if (eventType < EVENT_NOTHING || eventType >= EVENT_INVALID) - { - gameLocal.Warning("Invalid mission event type passed by %s to handleMissionEvent(): %d", entity->name.c_str(), eventType); - return; - } - - // Pass on the call - gameLocal.m_MissionData->HandleMissionEvent(entity, static_cast(eventType), argument); -} - -// grayman #2787 - -void idThread::Event_CanPlant( const idVec3 &traceStart, const idVec3 &traceEnd, idEntity *ignore, idEntity *vine ) -{ - float vineFriendly = 0; // assume the vine can't grow - trace_t result; - if ( gameLocal.clip.TracePoint( result, traceStart, traceEnd, VINE_TRACE_CONTENTS, ignore ) ) - { - int contents = gameLocal.clip.Contents( result.endpos, NULL, mat3_identity, -1, ignore ); - if ( !( contents & MASK_WATER ) ) // grow if not in water - { - if ( abs( result.c.normal.z ) < 0.866 ) // grow if not on a flat surface - { - idEntity* struckEnt = gameLocal.entities[result.c.entityNum]; - if ( struckEnt ) - { - if ( ( struckEnt == gameLocal.world ) || struckEnt->IsType( idStaticEntity::Type ) ) - { - // Either we hit a world brush, or a func_static. We can grow on both types. - - const idMaterial* material = result.c.material; - if ( material ) - { - idStr description = material->GetDescription(); - if ( idStr::FindText(description,"vine_friendly") >= 0 ) - { - // We can plant here, so save planting data on the vine entity - - vine->m_VinePlantLoc = result.endpos; - vine->m_VinePlantNormal = result.c.normal; - vineFriendly = 1; - } - } - } - } - } - } - } - - idThread::ReturnFloat( vineFriendly ); -} - diff --git a/game/script/script_thread.h b/game/script/script_thread.h deleted file mode 100644 index d18bad22e..000000000 --- a/game/script/script_thread.h +++ /dev/null @@ -1,377 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SCRIPT_THREAD_H__ -#define __SCRIPT_THREAD_H__ - -extern const idEventDef EV_Thread_Execute; -extern const idEventDef EV_Thread_SetCallback; -extern const idEventDef EV_Thread_SetRenderCallback; -extern const idEventDef EV_Thread_TerminateThread; -extern const idEventDef EV_Thread_Pause; -extern const idEventDef EV_Thread_Wait; -extern const idEventDef EV_Thread_WaitFrame; -extern const idEventDef EV_Thread_WaitFor; -extern const idEventDef EV_Thread_WaitForThread; -extern const idEventDef EV_Thread_Print; -extern const idEventDef EV_Thread_PrintLn; -extern const idEventDef EV_Thread_Say; -extern const idEventDef EV_Thread_Assert; -extern const idEventDef EV_Thread_Trigger; -extern const idEventDef EV_Thread_SetCvar; -extern const idEventDef EV_Thread_GetCvar; -extern const idEventDef EV_Thread_Random; -extern const idEventDef EV_Thread_GetTime; -extern const idEventDef EV_Thread_KillThread; -extern const idEventDef EV_Thread_SetThreadName; -extern const idEventDef EV_Thread_GetEntity; -extern const idEventDef EV_Thread_Spawn; -extern const idEventDef EV_Thread_SetSpawnArg; -extern const idEventDef EV_Thread_SpawnString; -extern const idEventDef EV_Thread_SpawnFloat; -extern const idEventDef EV_Thread_SpawnVector; -extern const idEventDef EV_Thread_AngToForward; -extern const idEventDef EV_Thread_AngToRight; -extern const idEventDef EV_Thread_AngToUp; -extern const idEventDef EV_Thread_Sine; -extern const idEventDef EV_Thread_Cosine; -extern const idEventDef EV_Thread_Log; -extern const idEventDef EV_Thread_Pow; -extern const idEventDef EV_Thread_Normalize; -extern const idEventDef EV_Thread_VecLength; -extern const idEventDef EV_Thread_VecDotProduct; -extern const idEventDef EV_Thread_VecCrossProduct; -extern const idEventDef EV_Thread_OnSignal; -extern const idEventDef EV_Thread_ClearSignal; -extern const idEventDef EV_Thread_SetCamera; -extern const idEventDef EV_Thread_FirstPerson; -extern const idEventDef EV_Thread_TraceFraction; -extern const idEventDef EV_Thread_TracePos; -extern const idEventDef EV_Thread_FadeIn; -extern const idEventDef EV_Thread_FadeOut; -extern const idEventDef EV_Thread_FadeTo; -extern const idEventDef EV_Thread_Restart; - -extern const idEventDef EV_AI_GetRelationSys; -extern const idEventDef EV_AI_SetRelation; -extern const idEventDef EV_AI_OffsetRelation; - -extern const idEventDef EV_PointInLiquid; - -extern const idEventDef EV_TDM_SetPortSoundLoss; -extern const idEventDef EV_TDM_GetPortSoundLoss; - -extern const idEventDef EV_HandleMissionEvent; - -class idThread : public idClass { -private: - static idThread *currentThread; - - idThread *waitingForThread; - int waitingFor; - int waitingUntil; - idInterpreter interpreter; - - idDict spawnArgs; - - int threadNum; - idStr threadName; - - int lastExecuteTime; - int creationTime; - - bool manualControl; - - static int threadIndex; - static idList threadList; - - static trace_t trace; - - void Init( void ); - void Pause( void ); - - void Event_Execute( void ); - void Event_SetThreadName( const char *name ); - - // - // script callable Events - // - void Event_TerminateThread( int num ); - void Event_Pause( void ); - void Event_Wait( float time ); - void Event_WaitFrame( void ); - void Event_WaitFor( idEntity *ent ); - void Event_WaitForThread( int num ); - void Event_WaitForRender( idEntity *ent ); - void Event_Print( const char *text ); - void Event_PrintLn( const char *text ); - void Event_Say( const char *text ); - void Event_Assert( float value ); - void Event_Trigger( idEntity *ent ); - void Event_SetCvar( const char *name, const char *value ) const; - void Event_GetCvar( const char *name ) const; - void Event_Random( float range ) const; - void Event_GetTime( void ); - void Event_KillThread( const char *name ); - void Event_GetEntity( const char *name ); - void Event_Spawn( const char *classname ); - void Event_CopySpawnArgs( idEntity *ent ); - void Event_SetSpawnArg( const char *key, const char *value ); - void Event_SpawnString( const char *key, const char *defaultvalue ); - void Event_SpawnFloat( const char *key, float defaultvalue ); - void Event_SpawnVector( const char *key, idVec3 &defaultvalue ); - void Event_ClearPersistantArgs( void ); - void Event_SetPersistantArg( const char *key, const char *value ); - void Event_GetPersistantString( const char *key ); - void Event_GetPersistantFloat( const char *key ); - void Event_GetPersistantVector( const char *key ); - - void Event_GetCurrentMissionNum(); - - void Event_AngToForward( idAngles &ang ); - void Event_AngToRight( idAngles &ang ); - void Event_AngToUp( idAngles &ang ); - void Event_GetSine( const float angle ); - void Event_GetCosine( const float angle ); - void Event_GetLog( const float x ); - void Event_GetPow( const float x, const float y ); - void Event_GetSquareRoot( float theSquare ); - void Event_VecNormalize( idVec3 &vec ); - void Event_VecLength( idVec3 &vec ); - void Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ); - void Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ); - void Event_VecToAngles( idVec3 &vec ); - void Event_OnSignal( int signal, idEntity *ent, const char *func ); - void Event_ClearSignalThread( int signal, idEntity *ent ); - void Event_SetCamera( idEntity *ent ); - void Event_FirstPerson( void ); - void Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ); - void Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity ); - void Event_GetTraceFraction( void ); - void Event_GetTraceEndPos( void ); - void Event_GetTraceNormal( void ); - void Event_GetTraceEntity( void ); - void Event_GetTraceJoint( void ); - void Event_GetTraceBody( void ); - void Event_FadeIn( idVec3 &color, float time ); - void Event_FadeOut( idVec3 &color, float time ); - void Event_FadeTo( idVec3 &color, float alpha, float time ); - void Event_SetShaderParm( int parmnum, float value ); - void Event_StartMusic( const char *name ); - void Event_Warning( const char *text ); - void Event_Error( const char *text ); - void Event_StrLen( const char *string ); - void Event_StrLeft( const char *string, int num ); - void Event_StrRight( const char *string, int num ); - void Event_StrSkip( const char *string, int num ); - void Event_StrMid( const char *string, int start, int num ); - void Event_StrToFloat( const char *string ); - void Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower ); - void Event_IsClient( void ); - void Event_IsMultiplayer( void ); - void Event_GetFrameTime( void ); - void Event_GetTicsPerSecond( void ); - void Event_CacheSoundShader( const char *soundName ); - void Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime ); - void Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime ); - void Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime ); - void Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ); - void Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime ); - void Event_InfluenceActive( void ); - - /** - * greebo: Tests if a point is in a liquid. - * - * @ignoreEntity: This excludes an entity from the clip test. - * @returns: returns TRUE to the calling thread if the point is in a liquid - */ - void Event_PointInLiquid( const idVec3 &point, idEntity* ignoreEntity ); - - // Emits the string to the session command variable in gameLocal. - void Event_SessionCommand(const char* cmd); - - // For test purposes only. - void Event_DebugTDM_MatInfo( const char *mat ); - - /** - * The following events are a frontend for the AI relationship - * manager (stored in game_local). - * See CRelations definition for descriptions of functions called - **/ - void Event_GetRelation( int team1, int team2 ); - void Event_SetRelation( int team1, int team2, int val ); - void Event_OffsetRelation( int team1, int team2, int offset ); - - /** - * TDM Soundprop Events: - * Set or get the acoustical loss for a portal with a given handle. - * Handle must be greater than zero and less than the number of portals in the map. - **/ - void Event_SetPortSoundLoss( int handle, float value ); - void Event_GetPortSoundLoss( int handle ); - - // The scriptevent counterpart of DM_LOG - void Event_LogString(int logClass, int logType, const char* output); - - // The script interface for raising mission events, like readable callbacks - void Event_HandleMissionEvent(idEntity* entity, int eventType, const char* argument); - - void Event_CanPlant( const idVec3 &traceStart, const idVec3 &traceEnd, idEntity *ignore, idEntity *vine ); // grayman #2787 - -public: - CLASS_PROTOTYPE( idThread ); - - idThread(); - idThread( idEntity *self, const function_t *func ); - idThread( const function_t *func ); - idThread( idInterpreter *source, const function_t *func, int args ); - idThread( idInterpreter *source, idEntity *self, const function_t *func, int args ); - - virtual ~idThread(); - - // tells the thread manager not to delete this thread when it ends - void ManualDelete( void ); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - void EnableDebugInfo( void ) { interpreter.debug = true; }; - void DisableDebugInfo( void ) { interpreter.debug = false; }; - - void WaitMS( int time ); - void WaitSec( float time ); - void WaitFrame( void ); - - // NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. - void CallFunction(const function_t *func, bool clearStack ); - - bool CallFunctionArgs(const function_t *func, bool clearStack, const char *fmt, ...); - bool CallFunctionArgsVN(const function_t *func, bool clearStack, const char *fmt, va_list args); - - // NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function. - void CallFunction( idEntity *obj, const function_t *func, bool clearStack ); - - void DisplayInfo(); - static idThread *GetThread( int num ); - static void ListThreads_f( const idCmdArgs &args ); - static void Restart( void ); - static void ObjectMoveDone( int threadnum, idEntity *obj ); - - static idList& GetThreads ( void ); - - bool IsDoneProcessing ( void ); - bool IsDying ( void ); - - void End( void ); - static void KillThread( const char *name ); - static void KillThread( int num ); - bool Execute( void ); - void ManualControl( void ) { manualControl = true; CancelEvents( &EV_Thread_Execute ); }; - void DoneProcessing( void ) { interpreter.doneProcessing = true; }; - void ContinueProcessing( void ) { interpreter.doneProcessing = false; }; - bool ThreadDying( void ) { return interpreter.threadDying; }; - void EndThread( void ) { interpreter.threadDying = true; }; - bool IsWaiting( void ); - void ClearWaitFor( void ); - bool IsWaitingFor( idEntity *obj ); - void ObjectMoveDone( idEntity *obj ); - void ThreadCallback( idThread *thread ); - void DelayedStart( int delay ); - bool Start( void ); - idThread *WaitingOnThread( void ); - void SetThreadNum( int num ); - int GetThreadNum( void ); - void SetThreadName( const char *name ); - const char *GetThreadName( void ); - - void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - - void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3))); - - - static idThread *CurrentThread( void ); - static int CurrentThreadNum( void ); - static bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event ); - static void EndMultiFrameEvent( idEntity *ent, const idEventDef *event ); - - static void ReturnString( const char *text ); - static void ReturnFloat( float value ); - static void ReturnInt( int value ); - static void ReturnVector( idVec3 const &vec ); - static void ReturnEntity( idEntity *ent ); -}; - -/* -================ -idThread::WaitingOnThread -================ -*/ -ID_INLINE idThread *idThread::WaitingOnThread( void ) { - return waitingForThread; -} - -/* -================ -idThread::SetThreadNum -================ -*/ -ID_INLINE void idThread::SetThreadNum( int num ) { - threadNum = num; -} - -/* -================ -idThread::GetThreadNum -================ -*/ -ID_INLINE int idThread::GetThreadNum( void ) { - return threadNum; -} - -/* -================ -idThread::GetThreadName -================ -*/ -ID_INLINE const char *idThread::GetThreadName( void ) { - return threadName.c_str(); -} - -/* -================ -idThread::GetThreads -================ -*/ -ID_INLINE idList& idThread::GetThreads ( void ) { - return threadList; -} - -/* -================ -idThread::IsDoneProcessing -================ -*/ -ID_INLINE bool idThread::IsDoneProcessing ( void ) { - return interpreter.doneProcessing; -} - -/* -================ -idThread::IsDying -================ -*/ -ID_INLINE bool idThread::IsDying ( void ) { - return interpreter.threadDying; -} - -#endif /* !__SCRIPT_THREAD_H__ */ diff --git a/game/securitycamera.cpp b/game/securitycamera.cpp deleted file mode 100644 index 28ce09155..000000000 --- a/game/securitycamera.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* - - SecurityCamera.cpp - - Security camera that triggers targets when player is in view - -*/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - - -/*********************************************************************** - - idSecurityCamera - -***********************************************************************/ - -const idEventDef EV_SecurityCam_ReverseSweep( "" ); -const idEventDef EV_SecurityCam_ContinueSweep( "" ); -const idEventDef EV_SecurityCam_Pause( "" ); -const idEventDef EV_SecurityCam_Alert( "" ); -const idEventDef EV_SecurityCam_AddLight( "" ); - -CLASS_DECLARATION( idEntity, idSecurityCamera ) - EVENT( EV_SecurityCam_ReverseSweep, idSecurityCamera::Event_ReverseSweep ) - EVENT( EV_SecurityCam_ContinueSweep, idSecurityCamera::Event_ContinueSweep ) - EVENT( EV_SecurityCam_Pause, idSecurityCamera::Event_Pause ) - EVENT( EV_SecurityCam_Alert, idSecurityCamera::Event_Alert ) - EVENT( EV_SecurityCam_AddLight, idSecurityCamera::Event_AddLight ) -END_CLASS - -/* -================ -idSecurityCamera::Save -================ -*/ -void idSecurityCamera::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( angle ); - savefile->WriteFloat( sweepAngle ); - savefile->WriteInt( modelAxis ); - savefile->WriteBool( flipAxis ); - savefile->WriteFloat( scanDist ); - savefile->WriteFloat( scanFov ); - - savefile->WriteFloat( sweepStart ); - savefile->WriteFloat( sweepEnd ); - savefile->WriteBool( negativeSweep ); - savefile->WriteBool( sweeping ); - savefile->WriteInt( alertMode ); - savefile->WriteFloat( stopSweeping ); - savefile->WriteFloat( scanFovCos ); - - savefile->WriteVec3( viewOffset ); - - savefile->WriteInt( pvsArea ); - savefile->WriteStaticObject( physicsObj ); - savefile->WriteTraceModel( trm ); -} - -/* -================ -idSecurityCamera::Restore -================ -*/ -void idSecurityCamera::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( angle ); - savefile->ReadFloat( sweepAngle ); - savefile->ReadInt( modelAxis ); - savefile->ReadBool( flipAxis ); - savefile->ReadFloat( scanDist ); - savefile->ReadFloat( scanFov ); - - savefile->ReadFloat( sweepStart ); - savefile->ReadFloat( sweepEnd ); - savefile->ReadBool( negativeSweep ); - savefile->ReadBool( sweeping ); - savefile->ReadInt( alertMode ); - savefile->ReadFloat( stopSweeping ); - savefile->ReadFloat( scanFovCos ); - - savefile->ReadVec3( viewOffset ); - - savefile->ReadInt( pvsArea ); - savefile->ReadStaticObject( physicsObj ); - savefile->ReadTraceModel( trm ); -} - -/* -================ -idSecurityCamera::Spawn -================ -*/ -void idSecurityCamera::Spawn( void ) { - idStr str; - - sweepAngle = spawnArgs.GetFloat( "sweepAngle", "90" ); - health = spawnArgs.GetInt( "health", "100" ); - scanFov = spawnArgs.GetFloat( "scanFov", "90" ); - scanDist = spawnArgs.GetFloat( "scanDist", "200" ); - flipAxis = spawnArgs.GetBool( "flipAxis" ); - - modelAxis = spawnArgs.GetInt( "modelAxis" ); - if ( modelAxis < 0 || modelAxis > 2 ) { - modelAxis = 0; - } - - spawnArgs.GetVector( "viewOffset", "0 0 0", viewOffset ); - - if ( spawnArgs.GetBool( "spotLight" ) ) { - PostEventMS( &EV_SecurityCam_AddLight, 0 ); - } - - negativeSweep = ( sweepAngle < 0 ) ? true : false; - sweepAngle = fabs( sweepAngle ); - - scanFovCos = cos( scanFov * idMath::PI / 360.0f ); - - angle = GetPhysics()->GetAxis().ToAngles().yaw; - StartSweep(); - SetAlertMode( SCANNING ); - BecomeActive( TH_THINK ); - - if ( health ) { - fl.takedamage = true; - } - - pvsArea = gameLocal.pvs.GetPVSArea( GetPhysics()->GetOrigin() ); - // if no target specified use ourself - str = spawnArgs.GetString( "cameraTarget" ); - if ( str.Length() == 0 ) { - spawnArgs.Set( "cameraTarget", spawnArgs.GetString( "name" ) ); - } - - // check if a clip model is set - spawnArgs.GetString( "clipmodel", "", str ); - if ( !str[0] ) { - str = spawnArgs.GetString( "model" ); // use the visual model - } - - if ( !collisionModelManager->TrmFromModel( str, trm ) ) { - gameLocal.Error( "idSecurityCamera '%s': cannot load collision model %s", name.c_str(), str.c_str() ); - return; - } - - GetPhysics()->SetContents( CONTENTS_SOLID ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); - - GetPhysics()->SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); - // setup the physics - UpdateChangeableSpawnArgs( NULL ); -} - -/* -================ -idSecurityCamera::Event_AddLight -================ -*/ -void idSecurityCamera::Event_AddLight( void ) { - idDict args; - idVec3 right, up, target, temp; - idVec3 dir; - float radius; - idVec3 lightOffset; - idLight *spotLight; - - dir = GetAxis(); - dir.NormalVectors( right, up ); - target = GetPhysics()->GetOrigin() + dir * scanDist; - - radius = tan( scanFov * idMath::PI / 360.0f ); - up = dir + up * radius; - up.Normalize(); - up = GetPhysics()->GetOrigin() + up * scanDist; - up -= target; - - right = dir + right * radius; - right.Normalize(); - right = GetPhysics()->GetOrigin() + right * scanDist; - right -= target; - - spawnArgs.GetVector( "lightOffset", "0 0 0", lightOffset ); - - args.Set( "origin", ( GetPhysics()->GetOrigin() + lightOffset ).ToString() ); - args.Set( "light_target", target.ToString() ); - args.Set( "light_right", right.ToString() ); - args.Set( "light_up", up.ToString() ); - args.SetFloat( "angle", GetPhysics()->GetAxis()[0].ToYaw() ); - - spotLight = static_cast( gameLocal.SpawnEntityType( idLight::Type, &args ) ); - spotLight->Bind( this, true ); - spotLight->UpdateVisuals(); -} - -/* -================ -idSecurityCamera::DrawFov -================ -*/ -void idSecurityCamera::DrawFov( void ) { - int i; - float radius, a, s, c, halfRadius; - idVec3 right, up; - idVec4 color(1, 0, 0, 1), color2(0, 0, 1, 1); - idVec3 lastPoint, point, lastHalfPoint, halfPoint, center; - - idVec3 dir = GetAxis(); - dir.NormalVectors( right, up ); - - radius = tan( scanFov * idMath::PI / 360.0f ); - halfRadius = radius * 0.5f; - lastPoint = dir + up * radius; - lastPoint.Normalize(); - lastPoint = GetPhysics()->GetOrigin() + lastPoint * scanDist; - lastHalfPoint = dir + up * halfRadius; - lastHalfPoint.Normalize(); - lastHalfPoint = GetPhysics()->GetOrigin() + lastHalfPoint * scanDist; - center = GetPhysics()->GetOrigin() + dir * scanDist; - for ( i = 1; i < 12; i++ ) { - a = idMath::TWO_PI * i / 12.0f; - idMath::SinCos( a, s, c ); - point = dir + right * s * radius + up * c * radius; - point.Normalize(); - point = GetPhysics()->GetOrigin() + point * scanDist; - gameRenderWorld->DebugLine( color, lastPoint, point ); - gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), point ); - lastPoint = point; - - halfPoint = dir + right * s * halfRadius + up * c * halfRadius; - halfPoint.Normalize(); - halfPoint = GetPhysics()->GetOrigin() + halfPoint * scanDist; - gameRenderWorld->DebugLine( color2, point, halfPoint ); - gameRenderWorld->DebugLine( color2, lastHalfPoint, halfPoint ); - lastHalfPoint = halfPoint; - - gameRenderWorld->DebugLine( color2, halfPoint, center ); - } -} - -/* -================ -idSecurityCamera::GetRenderView -================ -*/ -renderView_t *idSecurityCamera::GetRenderView() { - renderView_t *rv = idEntity::GetRenderView(); - rv->fov_x = scanFov; - rv->fov_y = scanFov; - rv->viewaxis = GetAxis().ToAngles().ToMat3(); - rv->vieworg = GetPhysics()->GetOrigin() + viewOffset; - return rv; -} - -/* -================ -idSecurityCamera::CanSeePlayer -================ -*/ -bool idSecurityCamera::CanSeePlayer( void ) { - int i; - float dist; - idPlayer *ent; - trace_t tr; - idVec3 dir; - pvsHandle_t handle; - - handle = gameLocal.pvs.SetupCurrentPVS( pvsArea ); - - for ( i = 0; i < gameLocal.numClients; i++ ) { - ent = static_cast(gameLocal.entities[ i ]); - - if ( !ent || ( ent->fl.notarget ) ) { - continue; - } - - // if there is no way we can see this player - if ( !gameLocal.pvs.InCurrentPVS( handle, ent->GetPVSAreas(), ent->GetNumPVSAreas() ) ) { - continue; - } - - dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); - dist = dir.Normalize(); - - if ( dist > scanDist ) { - continue; - } - - if ( dir * GetAxis() < scanFovCos ) { - continue; - } - - idVec3 eye; - - eye = ent->EyeOffset(); - - gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), ent->GetPhysics()->GetOrigin() + eye, MASK_OPAQUE, this ); - if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == ent ) ) { - gameLocal.pvs.FreeCurrentPVS( handle ); - return true; - } - } - - gameLocal.pvs.FreeCurrentPVS( handle ); - - return false; -} - -/* -================ -idSecurityCamera::SetAlertMode -================ -*/ -void idSecurityCamera::SetAlertMode( int alert ) { - if (alert >= SCANNING && alert <= ACTIVATED) { - alertMode = alert; - } - renderEntity.shaderParms[ SHADERPARM_MODE ] = alertMode; - UpdateVisuals(); -} - -/* -================ -idSecurityCamera::Think -================ -*/ -void idSecurityCamera::Think( void ) { - float pct; - float travel; - - if ( thinkFlags & TH_THINK ) { - if ( g_showEntityInfo.GetBool() ) { - DrawFov(); - } - - if (health <= 0) { - BecomeInactive( TH_THINK ); - return; - } - } - - // run physics - RunPhysics(); - - if ( thinkFlags & TH_THINK ) { - if (CanSeePlayer()) { - if (alertMode == SCANNING) { - float sightTime; - - SetAlertMode(ALERT); - stopSweeping = gameLocal.time; - if (sweeping) { - CancelEvents( &EV_SecurityCam_Pause ); - } else { - CancelEvents( &EV_SecurityCam_ReverseSweep ); - } - sweeping = false; - StopSound( SND_CHANNEL_ANY, false ); - StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL ); - - sightTime = spawnArgs.GetFloat( "sightTime", "5" ); - PostEventSec(&EV_SecurityCam_Alert, sightTime); - } - } else { - if (alertMode == ALERT) { - float sightResume; - - SetAlertMode(LOSINGINTEREST); - CancelEvents( &EV_SecurityCam_Alert ); - - sightResume = spawnArgs.GetFloat( "sightResume", "1.5" ); - PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume ); - } - - if ( sweeping ) { - idAngles a = GetPhysics()->GetAxis().ToAngles(); - - pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart ); - travel = pct * sweepAngle; - if ( negativeSweep ) { - a.yaw = angle + travel; - } else { - a.yaw = angle - travel; - } - - SetAngles( a ); - } - } - } - Present(); -} - -/* -================ -idSecurityCamera::GetAxis -================ -*/ -const idVec3 idSecurityCamera::GetAxis( void ) const { - return (flipAxis) ? -GetPhysics()->GetAxis()[modelAxis] : GetPhysics()->GetAxis()[modelAxis]; -}; - -/* -================ -idSecurityCamera::SweepSpeed -================ -*/ -float idSecurityCamera::SweepSpeed( void ) const { - return spawnArgs.GetFloat( "sweepSpeed", "5" ); -} - -/* -================ -idSecurityCamera::StartSweep -================ -*/ -void idSecurityCamera::StartSweep( void ) { - int speed; - - sweeping = true; - sweepStart = gameLocal.time; - speed = SEC2MS( SweepSpeed() ); - sweepEnd = sweepStart + speed; - PostEventMS( &EV_SecurityCam_Pause, speed ); - StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL ); -} - -/* -================ -idSecurityCamera::Event_ContinueSweep -================ -*/ -void idSecurityCamera::Event_ContinueSweep( void ) { - float pct = (stopSweeping - sweepStart) / (sweepEnd - sweepStart); - float f = gameLocal.time - (sweepEnd - sweepStart) * pct; - int speed; - - sweepStart = f; - speed = static_cast(MS2SEC( SweepSpeed() )); - sweepEnd = sweepStart + speed; - PostEventMS( &EV_SecurityCam_Pause, static_cast(speed * (1.0f - pct))); - StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL ); - SetAlertMode(SCANNING); - sweeping = true; -} - -/* -================ -idSecurityCamera::Event_Alert -================ -*/ -void idSecurityCamera::Event_Alert( void ) { - float wait; - - SetAlertMode(ACTIVATED); - StopSound( SND_CHANNEL_ANY, false ); - StartSound( "snd_activate", SND_CHANNEL_BODY, 0, false, NULL ); - ActivateTargets(this); - CancelEvents( &EV_SecurityCam_ContinueSweep ); - - wait = spawnArgs.GetFloat( "wait", "20" ); - PostEventSec( &EV_SecurityCam_ContinueSweep, wait ); -} - -/* -================ -idSecurityCamera::Event_ReverseSweep -================ -*/ -void idSecurityCamera::Event_ReverseSweep( void ) { - angle = GetPhysics()->GetAxis().ToAngles().yaw; - negativeSweep = !negativeSweep; - StartSweep(); -} - -/* -================ -idSecurityCamera::Event_Pause -================ -*/ -void idSecurityCamera::Event_Pause( void ) { - float sweepWait; - - sweepWait = spawnArgs.GetFloat( "sweepWait", "0.5" ); - sweeping = false; - StopSound( SND_CHANNEL_ANY, false ); - StartSound( "snd_stop", SND_CHANNEL_BODY, 0, false, NULL ); - PostEventSec( &EV_SecurityCam_ReverseSweep, sweepWait ); -} - -/* -============ -idSecurityCamera::Killed -============ -*/ -void idSecurityCamera::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - sweeping = false; - StopSound( SND_CHANNEL_ANY, false ); - const char *fx = spawnArgs.GetString( "fx_destroyed" ); - if ( fx[0] != '\0' ) { - idEntityFx::StartFx( fx, NULL, NULL, this, true ); - } - - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( trm ), 0.02f ); - physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); - physicsObj.SetAxis( GetPhysics()->GetAxis() ); - physicsObj.SetBouncyness( 0.2f ); - physicsObj.SetFriction( 0.6f, 0.6f, 0.2f ); - physicsObj.SetGravity( gameLocal.GetGravity() ); - physicsObj.SetContents( CONTENTS_SOLID ); - physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP ); - SetPhysics( &physicsObj ); - physicsObj.DropToFloor(); -} - - -/* -============ -idSecurityCamera::Pain -============ -*/ -bool idSecurityCamera::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - const char *fx = spawnArgs.GetString( "fx_damage" ); - if ( fx[0] != '\0' ) { - idEntityFx::StartFx( fx, NULL, NULL, this, true ); - } - return true; -} - - -/* -================ -idSecurityCamera::Present - -Present is called to allow entities to generate refEntities, lights, etc for the renderer. -================ -*/ -void idSecurityCamera::Present( void ) -{ - if( m_FrobDistance ) - { - UpdateFrobState(); - UpdateFrobDisplay(); - } - - // don't present to the renderer if the entity hasn't changed - if ( !( thinkFlags & TH_UPDATEVISUALS ) ) { - return; - } - BecomeInactive( TH_UPDATEVISUALS ); - - // camera target for remote render views - if ( cameraTarget ) { - renderEntity.remoteRenderView = cameraTarget->GetRenderView(); - } - - // if set to invisible, skip - if ( !renderEntity.hModel || IsHidden() ) { - return; - } - - // add to refresh list - if ( modelDefHandle == -1 ) { - modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - } else { - gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity ); - } -} diff --git a/game/securitycamera.h b/game/securitycamera.h deleted file mode 100644 index 05ca62bb2..000000000 --- a/game/securitycamera.h +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_SECURITYCAMERA_H__ -#define __GAME_SECURITYCAMERA_H__ - -/* -=================================================================================== - - Security camera - -=================================================================================== -*/ - - -class idSecurityCamera : public idEntity { -public: - CLASS_PROTOTYPE( idSecurityCamera ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Think( void ); - - virtual renderView_t * GetRenderView(); - virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ); - virtual void Present( void ); - - -private: - - enum { SCANNING, LOSINGINTEREST, ALERT, ACTIVATED }; - - float angle; - float sweepAngle; - int modelAxis; - bool flipAxis; - float scanDist; - float scanFov; - - float sweepStart; - float sweepEnd; - bool negativeSweep; - bool sweeping; - int alertMode; - float stopSweeping; - float scanFovCos; - - idVec3 viewOffset; - - int pvsArea; - idPhysics_RigidBody physicsObj; - idTraceModel trm; - - void StartSweep( void ); - bool CanSeePlayer( void ); - void SetAlertMode( int status ); - void DrawFov( void ); - const idVec3 GetAxis( void ) const; - float SweepSpeed( void ) const; - - void Event_ReverseSweep( void ); - void Event_ContinueSweep( void ); - void Event_Pause( void ); - void Event_Alert( void ); - void Event_AddLight( void ); -}; - -#endif /* !__GAME_SECURITYCAMERA_H__ */ diff --git a/game/smokeparticles.cpp b/game/smokeparticles.cpp deleted file mode 100644 index fcfee63f7..000000000 --- a/game/smokeparticles.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -static const char *smokeParticle_SnapshotName = "_SmokeParticle_Snapshot_"; - -/* -================ -idSmokeParticles::idSmokeParticles -================ -*/ -idSmokeParticles::idSmokeParticles( void ) { - initialized = false; - memset( &renderEntity, 0, sizeof( renderEntity ) ); - renderEntityHandle = -1; - memset( smokes, 0, sizeof( smokes ) ); - freeSmokes = NULL; - numActiveSmokes = 0; - currentParticleTime = -1; -} - -/* -================ -idSmokeParticles::Init -================ -*/ -void idSmokeParticles::Init( void ) { - if ( initialized ) { - Shutdown(); - } - - // set up the free list - for ( int i = 0; i < MAX_SMOKE_PARTICLES-1; i++ ) { - smokes[i].next = &smokes[i+1]; - } - smokes[MAX_SMOKE_PARTICLES-1].next = NULL; - freeSmokes = &smokes[0]; - numActiveSmokes = 0; - - activeStages.Clear(); - - memset( &renderEntity, 0, sizeof( renderEntity ) ); - - renderEntity.bounds.Clear(); - renderEntity.axis = mat3_identity; - renderEntity.shaderParms[ SHADERPARM_RED ] = 1; - renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1; - renderEntity.shaderParms[3] = 1; - - renderEntity.hModel = renderModelManager->AllocModel(); - renderEntity.hModel->InitEmpty( smokeParticle_SnapshotName ); - - // we certainly don't want particle shadows - renderEntity.noShadow = 1; - - // huge bounds, so it will be present in every world area - renderEntity.bounds.AddPoint( idVec3(-100000, -100000, -100000) ); - renderEntity.bounds.AddPoint( idVec3( 100000, 100000, 100000) ); - - renderEntity.callback = idSmokeParticles::ModelCallback; - // add to renderer list - renderEntityHandle = gameRenderWorld->AddEntityDef( &renderEntity ); - - currentParticleTime = -1; - - initialized = true; -} - -/* -================ -idSmokeParticles::Shutdown -================ -*/ -void idSmokeParticles::Shutdown( void ) { - // make sure the render entity is freed before the model is freed - if ( renderEntityHandle != -1 ) { - gameRenderWorld->FreeEntityDef( renderEntityHandle ); - renderEntityHandle = -1; - } - if ( renderEntity.hModel != NULL ) { - renderModelManager->FreeModel( renderEntity.hModel ); - renderEntity.hModel = NULL; - } - initialized = false; -} - -/* -================ -idSmokeParticles::FreeSmokes -================ -*/ -void idSmokeParticles::FreeSmokes( void ) { - for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) { - singleSmoke_t *smoke, *next, *last; - - activeSmokeStage_t *active = &activeStages[activeStageNum]; - const idParticleStage *stage = active->stage; - - for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) { - next = smoke->next; - - float frac = (float)( gameLocal.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 ); - if ( frac >= 1.0f ) { - // remove the particle from the stage list - if ( last != NULL ) { - last->next = smoke->next; - } else { - active->smokes = smoke->next; - } - // put the particle on the free list - smoke->next = freeSmokes; - freeSmokes = smoke; - numActiveSmokes--; - continue; - } - - last = smoke; - } - - if ( !active->smokes ) { - // remove this from the activeStages list - activeStages.RemoveIndex( activeStageNum ); - activeStageNum--; - } - } -} - -/* -================ -idSmokeParticles::EmitSmoke - -Called by game code to drop another particle into the list -================ -*/ -bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemStartTime, const float diversity, const idVec3 &origin, const idMat3 &axis ) { - bool continues = false; - - if ( !smoke ) { - return false; - } - - if ( !gameLocal.isNewFrame ) { - return false; - } - - // dedicated doesn't smoke. No UpdateRenderEntity, so they would not be freed - if ( gameLocal.localClientNum < 0 ) { - return false; - } - - assert( gameLocal.time == 0 || systemStartTime <= gameLocal.time ); - if ( systemStartTime > gameLocal.time ) { - return false; - } - - idRandom steppingRandom( static_cast(0xffff * diversity) ); - - // for each stage in the smoke that is still emitting particles, emit a new singleSmoke_t - for ( int stageNum = 0; stageNum < smoke->stages.Num(); stageNum++ ) { - const idParticleStage *stage = smoke->stages[stageNum]; - - if ( !stage->cycleMsec ) { - continue; - } - - if ( !stage->material ) { - continue; - } - - if ( stage->particleLife <= 0 ) { - continue; - } - - // see how many particles we should emit this tic - // FIXME: smoke.privateStartTime += stage->timeOffset; - int finalParticleTime = static_cast(stage->spawnBunching * stage->cycleMsec); - int deltaMsec = gameLocal.time - systemStartTime; - - int nowCount = 0, prevCount; - if ( finalParticleTime == 0 ) { - // if spawnBunching is 0, they will all come out at once - if ( gameLocal.time == systemStartTime ) { - prevCount = -1; - nowCount = stage->totalParticles-1; - } else { - prevCount = stage->totalParticles; - } - } else { - nowCount = static_cast(floor( ( (float)deltaMsec / finalParticleTime ) * stage->totalParticles )); - if ( nowCount >= stage->totalParticles ) { - nowCount = stage->totalParticles-1; - } - prevCount = static_cast(floor( ((float)( deltaMsec - USERCMD_MSEC ) / finalParticleTime) * stage->totalParticles )); - if ( prevCount < -1 ) { - prevCount = -1; - } - } - - if ( prevCount >= stage->totalParticles ) { - // no more particles from this stage - continue; - } - - if ( nowCount < stage->totalParticles-1 ) { - // the system will need to emit particles next frame as well - continues = true; - } - - // find an activeSmokeStage that matches this - activeSmokeStage_t *active(NULL); - int i; - for ( i = 0 ; i < activeStages.Num() ; i++ ) { - active = &activeStages[i]; - if ( active->stage == stage ) { - break; - } - } - if ( i == activeStages.Num() ) { - // add a new one - activeSmokeStage_t newActive; - - newActive.smokes = NULL; - newActive.stage = stage; - i = activeStages.Append( newActive ); - active = &activeStages[i]; - } - - // add all the required particles - for ( prevCount++ ; prevCount <= nowCount ; prevCount++ ) { - if ( !freeSmokes ) { - gameLocal.Printf( "idSmokeParticles::EmitSmoke: no free smokes with %d active stages\n", activeStages.Num() ); - return true; - } - singleSmoke_t *newSmoke = freeSmokes; - freeSmokes = freeSmokes->next; - numActiveSmokes++; - - newSmoke->index = prevCount; - newSmoke->axis = axis; - newSmoke->origin = origin; - newSmoke->random = steppingRandom; - newSmoke->privateStartTime = systemStartTime + prevCount * finalParticleTime / stage->totalParticles; - newSmoke->next = active->smokes; - active->smokes = newSmoke; - - steppingRandom.RandomInt(); // advance the random - } - } - - return continues; -} - -/* -================ -idSmokeParticles::UpdateRenderEntity -================ -*/ -bool idSmokeParticles::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) { - - // FIXME: re-use model surfaces - renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName ); - - // this may be triggered by a model trace or other non-view related source, - // to which we should look like an empty model - if ( !renderView ) { - return false; - } - - // don't regenerate it if it is current - if ( renderView->time == currentParticleTime && !renderView->forceUpdate ) { - return false; - } - currentParticleTime = renderView->time; - - particleGen_t g; - - g.renderEnt = renderEntity; - g.renderView = renderView; - - for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) { - singleSmoke_t *smoke, *next, *last; - - activeSmokeStage_t *active = &activeStages[activeStageNum]; - const idParticleStage *stage = active->stage; - - if ( !stage->material ) { - continue; - } - - // allocate a srfTriangles that can hold all the particles - int count = 0; - for ( smoke = active->smokes; smoke; smoke = smoke->next ) { - count++; - } - int quads = count * stage->NumQuadsPerParticle(); - srfTriangles_t *tri = renderEntity->hModel->AllocSurfaceTriangles( quads * 4, quads * 6 ); - tri->numIndexes = quads * 6; - tri->numVerts = quads * 4; - - // just always draw the particles - tri->bounds[0][0] = - tri->bounds[0][1] = - tri->bounds[0][2] = -99999; - tri->bounds[1][0] = - tri->bounds[1][1] = - tri->bounds[1][2] = 99999; - - tri->numVerts = 0; - for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) { - next = smoke->next; - - g.frac = (float)( gameLocal.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 ); - if ( g.frac >= 1.0f ) { - // remove the particle from the stage list - if ( last != NULL ) { - last->next = smoke->next; - } else { - active->smokes = smoke->next; - } - // put the particle on the free list - smoke->next = freeSmokes; - freeSmokes = smoke; - numActiveSmokes--; - continue; - } - - g.index = smoke->index; - g.random = smoke->random; - - g.origin = smoke->origin; - g.axis = smoke->axis; - - g.originalRandom = g.random; - g.age = g.frac * stage->particleLife; - - tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts ); - - last = smoke; - } - if ( tri->numVerts > quads * 4 ) { - gameLocal.Error( "idSmokeParticles::UpdateRenderEntity: miscounted verts" ); - } - - if ( tri->numVerts == 0 ) { - - // they were all removed - renderEntity->hModel->FreeSurfaceTriangles( tri ); - - if ( !active->smokes ) { - // remove this from the activeStages list - activeStages.RemoveIndex( activeStageNum ); - activeStageNum--; - } - } else { - // build the index list - int indexes = 0; - for ( int i = 0 ; i < tri->numVerts ; i += 4 ) { - tri->indexes[indexes+0] = i; - tri->indexes[indexes+1] = i+2; - tri->indexes[indexes+2] = i+3; - tri->indexes[indexes+3] = i; - tri->indexes[indexes+4] = i+3; - tri->indexes[indexes+5] = i+1; - indexes += 6; - } - tri->numIndexes = indexes; - - modelSurface_t surf; - surf.geometry = tri; - surf.shader = stage->material; - surf.id = 0; - - renderEntity->hModel->AddSurface( surf ); - } - } - return true; -} - -/* -================ -idSmokeParticles::ModelCallback -================ -*/ -bool idSmokeParticles::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) { - // update the particles - if ( gameLocal.smokeParticles ) { - return gameLocal.smokeParticles->UpdateRenderEntity( renderEntity, renderView ); - } - - return true; -} diff --git a/game/smokeparticles.h b/game/smokeparticles.h deleted file mode 100644 index cad9638f0..000000000 --- a/game/smokeparticles.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SMOKEPARTICLES_H__ -#define __SMOKEPARTICLES_H__ - -/* -=============================================================================== - - Smoke systems are for particles that are emitted off of things that are - constantly changing position and orientation, like muzzle smoke coming - from a bone on a weapon, blood spurting from a wound, or particles - trailing from a monster limb. - - The smoke particles are always evaluated and rendered each tic, so there - is a performance cost with using them for continuous effects. The general - particle systems are completely parametric, and have no performance - overhead when not in view. - - All smoke systems share the same shaderparms, so any coloration must be - done in the particle definition. - - Each particle model has its own shaderparms, which can be used by the - particle materials. - -=============================================================================== -*/ - -typedef struct singleSmoke_s { - struct singleSmoke_s * next; - int privateStartTime; // start time for this particular particle - int index; // particle index in system, 0 <= index < stage->totalParticles - idRandom random; - idVec3 origin; - idMat3 axis; -} singleSmoke_t; - -class idParticleStage; - -typedef struct { - const idParticleStage * stage; - singleSmoke_t * smokes; -} activeSmokeStage_t; - - -class idSmokeParticles { -public: - idSmokeParticles( void ); - - // creats an entity covering the entire world that will call back each rendering - void Init( void ); - void Shutdown( void ); - - // spits out a particle, returning false if the system will not emit any more particles in the future - bool EmitSmoke( const idDeclParticle *smoke, const int startTime, const float diversity, - const idVec3 &origin, const idMat3 &axis ); - - // free old smokes - void FreeSmokes( void ); - -private: - bool initialized; - - renderEntity_t renderEntity; // used to present a model to the renderer - int renderEntityHandle; // handle to static renderer model - - static const int MAX_SMOKE_PARTICLES = 10000; - singleSmoke_t smokes[MAX_SMOKE_PARTICLES]; - - idList activeStages; - singleSmoke_t * freeSmokes; - int numActiveSmokes; - int currentParticleTime; // don't need to recalculate if == view time - - bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ); - static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ); -}; - -#endif /* !__SMOKEPARTICLES_H__ */ diff --git a/game/sound.cpp b/game/sound.cpp deleted file mode 100644 index 2508ca502..000000000 --- a/game/sound.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -=============================================================================== - - SOUND - -=============================================================================== -*/ - -const idEventDef EV_Speaker_On( "On", NULL ); -const idEventDef EV_Speaker_Off( "Off", NULL ); -const idEventDef EV_Speaker_Timer( "", NULL ); - -CLASS_DECLARATION( idEntity, idSound ) - EVENT( EV_Activate, idSound::Event_Trigger ) - EVENT( EV_Speaker_On, idSound::Event_On ) - EVENT( EV_Speaker_Off, idSound::Event_Off ) - EVENT( EV_Speaker_Timer, idSound::Event_Timer ) -END_CLASS - - -/* -================ -idSound::idSound -================ -*/ -idSound::idSound( void ) { - lastSoundVol = 0.0f; - soundVol = 0.0f; - shakeTranslate.Zero(); - shakeRotate.Zero(); - random = 0.0f; - wait = 0.0f; - timerOn = false; - playingUntilTime = 0; -} - -/* -================ -idSound::Save -================ -*/ -void idSound::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( lastSoundVol ); - savefile->WriteFloat( soundVol ); - savefile->WriteFloat( random ); - savefile->WriteFloat( wait ); - savefile->WriteBool( timerOn ); - savefile->WriteVec3( shakeTranslate ); - savefile->WriteAngles( shakeRotate ); - savefile->WriteInt( playingUntilTime ); -} - -/* -================ -idSound::Restore -================ -*/ -void idSound::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( lastSoundVol ); - savefile->ReadFloat( soundVol ); - savefile->ReadFloat( random ); - savefile->ReadFloat( wait ); - savefile->ReadBool( timerOn ); - savefile->ReadVec3( shakeTranslate ); - savefile->ReadAngles( shakeRotate ); - savefile->ReadInt( playingUntilTime ); -} - -/* -================ -idSound::Spawn -================ -*/ -void idSound::Spawn( void ) { - spawnArgs.GetVector( "move", "0 0 0", shakeTranslate ); - spawnArgs.GetAngles( "rotate", "0 0 0", shakeRotate ); - spawnArgs.GetFloat( "random", "0", random ); - spawnArgs.GetFloat( "wait", "0", wait ); - - if ( ( wait > 0.0f ) && ( random >= wait ) ) { - random = wait - 0.001; - gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - soundVol = 0.0f; - lastSoundVol = 0.0f; - - if ( ( shakeRotate != ang_zero ) || ( shakeTranslate != vec3_zero ) ) { - BecomeActive( TH_THINK ); - } - - if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) { - timerOn = true; - PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); - } else { - timerOn = false; - } - // add this speaker to the list of ambient music speakers affected by tdm_music_volume - if ( spawnArgs.GetBool( "s_music" ) ) { - gameLocal.musicSpeakers.Append( entityNumber ); - } -} - -/* -================ -idSound::Event_Trigger - -this will toggle the idle idSound on and off -================ -*/ -void idSound::Event_Trigger( idEntity *activator ) { - if ( wait > 0.0f ) { - if ( timerOn ) { - timerOn = false; - CancelEvents( &EV_Speaker_Timer ); - } else { - timerOn = true; - DoSound( true ); - PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); - } - } else { - if ( gameLocal.isMultiplayer ) { - if ( refSound.referenceSound && ( gameLocal.time < playingUntilTime ) ) { - DoSound( false ); - } else { - DoSound( true ); - } - } else { - if ( refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) { - DoSound( false ); - } else { - DoSound( true ); - } - } - } -} - -/* -================ -idSound::Event_Timer -================ -*/ -void idSound::Event_Timer( void ) { - DoSound( true ); - PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); -} - -/* -================ -idSound::Think -================ -*/ -void idSound::Think( void ) { - idAngles ang; - - // run physics - RunPhysics(); - - // clear out our update visuals think flag since we never call Present - BecomeInactive( TH_UPDATEVISUALS ); -} - -/* -=============== -idSound::UpdateChangableSpawnArgs -=============== -*/ -void idSound::UpdateChangeableSpawnArgs( const idDict *source ) { - - idEntity::UpdateChangeableSpawnArgs( source ); - - if ( source ) { - FreeSoundEmitter( true ); - spawnArgs.Copy( *source ); - idSoundEmitter *saveRef = refSound.referenceSound; - gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound ); - refSound.referenceSound = saveRef; - - idVec3 origin; - idMat3 axis; - - if ( GetPhysicsToSoundTransform( origin, axis ) ) { - refSound.origin = GetPhysics()->GetOrigin() + origin * axis; - } else { - refSound.origin = GetPhysics()->GetOrigin(); - } - - spawnArgs.GetFloat( "random", "0", random ); - spawnArgs.GetFloat( "wait", "0", wait ); - - if ( ( wait > 0.0f ) && ( random >= wait ) ) { - random = wait - 0.001; - gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) { - timerOn = true; - DoSound( false ); - CancelEvents( &EV_Speaker_Timer ); - PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); - } else if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) { - // start it if it isn't already playing, and we aren't waitForTrigger - DoSound( true ); - timerOn = false; - } - } -} - -/* -=============== -idSound::SetSound -=============== -*/ -void idSound::SetSound( const char *sound, int channel ) { - const idSoundShader *shader = declManager->FindSound( sound ); - if ( shader != refSound.shader ) { - FreeSoundEmitter( true ); - } - gameEdit->ParseSpawnArgsToRefSound(&spawnArgs, &refSound); - refSound.shader = shader; - // start it if it isn't already playing, and we aren't waitForTrigger - if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) { - DoSound( true ); - } -} - -/* -================ -idSound::DoSound -================ -*/ -void idSound::DoSound( bool play ) { - if ( play ) { - StartSoundShader( refSound.shader, SND_CHANNEL_ANY, refSound.parms.soundShaderFlags, true, &playingUntilTime ); - playingUntilTime += gameLocal.time; - } else { - StopSound( SND_CHANNEL_ANY, true ); - playingUntilTime = 0; - } -} - -/* -================ -idSound::Event_On -================ -*/ -void idSound::Event_On( void ) { - if ( wait > 0.0f ) { - timerOn = true; - PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random ); - } - DoSound( true ); -} - -/* -================ -idSound::Event_Off -================ -*/ -void idSound::Event_Off( void ) { - if ( timerOn ) { - timerOn = false; - CancelEvents( &EV_Speaker_Timer ); - } - DoSound( false ); -} - -/* -=============== -idSound::ShowEditingDialog -=============== -*/ -void idSound::ShowEditingDialog( void ) { - common->InitTool( EDITOR_SOUND, &spawnArgs ); -} - diff --git a/game/sound.h b/game/sound.h deleted file mode 100644 index 92ebd8c9b..000000000 --- a/game/sound.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_SOUND_H__ -#define __GAME_SOUND_H__ - -/* -=============================================================================== - - Generic sound emitter. - -=============================================================================== -*/ - -class idSound : public idEntity { -public: - CLASS_PROTOTYPE( idSound ); - - idSound( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void UpdateChangeableSpawnArgs( const idDict *source ); - - void Spawn( void ); - - void ToggleOnOff( idEntity *other, idEntity *activator ); - void Think( void ); - void SetSound( const char *sound, int channel = SND_CHANNEL_ANY ); - - virtual void ShowEditingDialog( void ); - -private: - float lastSoundVol; - float soundVol; - float random; - float wait; - bool timerOn; - idVec3 shakeTranslate; - idAngles shakeRotate; - int playingUntilTime; - - void Event_Trigger( idEntity *activator ); - void Event_Timer( void ); - void Event_On( void ); - void Event_Off( void ); - void DoSound( bool play ); -}; - -#endif /* !__GAME_SOUND_H__ */ diff --git a/DarkMod/sourcehook/FastDelegate.h b/game/sourcehook/FastDelegate.h similarity index 100% rename from DarkMod/sourcehook/FastDelegate.h rename to game/sourcehook/FastDelegate.h diff --git a/DarkMod/sourcehook/sh_list.h b/game/sourcehook/sh_list.h similarity index 100% rename from DarkMod/sourcehook/sh_list.h rename to game/sourcehook/sh_list.h diff --git a/DarkMod/sourcehook/sh_memfuncinfo.h b/game/sourcehook/sh_memfuncinfo.h similarity index 100% rename from DarkMod/sourcehook/sh_memfuncinfo.h rename to game/sourcehook/sh_memfuncinfo.h diff --git a/DarkMod/sourcehook/sh_memory.h b/game/sourcehook/sh_memory.h similarity index 100% rename from DarkMod/sourcehook/sh_memory.h rename to game/sourcehook/sh_memory.h diff --git a/DarkMod/sourcehook/sh_stack.h b/game/sourcehook/sh_stack.h similarity index 100% rename from DarkMod/sourcehook/sh_stack.h rename to game/sourcehook/sh_stack.h diff --git a/DarkMod/sourcehook/sh_string.h b/game/sourcehook/sh_string.h similarity index 100% rename from DarkMod/sourcehook/sh_string.h rename to game/sourcehook/sh_string.h diff --git a/DarkMod/sourcehook/sh_tinyhash.h b/game/sourcehook/sh_tinyhash.h similarity index 100% rename from DarkMod/sourcehook/sh_tinyhash.h rename to game/sourcehook/sh_tinyhash.h diff --git a/DarkMod/sourcehook/sh_vector.h b/game/sourcehook/sh_vector.h similarity index 100% rename from DarkMod/sourcehook/sh_vector.h rename to game/sourcehook/sh_vector.h diff --git a/DarkMod/sourcehook/sourcehook.cpp b/game/sourcehook/sourcehook.cpp similarity index 97% rename from DarkMod/sourcehook/sourcehook.cpp rename to game/sourcehook/sourcehook.cpp index 0309cbe73..4d1685e1c 100644 --- a/DarkMod/sourcehook/sourcehook.cpp +++ b/game/sourcehook/sourcehook.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* ======== SourceHook ======== * Copyright (C) 2004-2008 Metamod:Source Development Team * No warranties of any kind @@ -17,7 +27,7 @@ * ============================ */ -#include "../idlib/precompiled.h" +#include "../../idlib/precompiled.h" #pragma hdrstop /** diff --git a/DarkMod/sourcehook/sourcehook.h b/game/sourcehook/sourcehook.h similarity index 100% rename from DarkMod/sourcehook/sourcehook.h rename to game/sourcehook/sourcehook.h diff --git a/DarkMod/sourcehook/sourcehook_impl.h b/game/sourcehook/sourcehook_impl.h similarity index 100% rename from DarkMod/sourcehook/sourcehook_impl.h rename to game/sourcehook/sourcehook_impl.h diff --git a/game/target.cpp b/game/target.cpp deleted file mode 100644 index b2c6b2042..000000000 --- a/game/target.cpp +++ /dev/null @@ -1,2264 +0,0 @@ -/*************************************************************************** - * - * For VIM users, do not remove: vim:ts=4:sw=4:cindent - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* - -Invisible entities that affect other entities or the world when activated. - -*/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/Objectives/MissionData.h" -#include "../DarkMod/Missions/MissionManager.h" -#include "../DarkMod/AI/Conversation/ConversationSystem.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -/* -=============================================================================== - -idTarget - -=============================================================================== -*/ - -CLASS_DECLARATION( idEntity, idTarget ) -END_CLASS - - -/* -=============================================================================== - -idTarget_Remove - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_Remove ) - EVENT( EV_Activate, idTarget_Remove::Event_Activate ) -END_CLASS - -/* -================ -idTarget_Remove::Event_Activate -================ -*/ -void idTarget_Remove::Event_Activate( idEntity *activator ) { - int i; - idEntity *ent; - - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->PostEventMS( &EV_Remove, 0 ); - } - } - - // delete our self when done - PostEventMS( &EV_Remove, 0 ); -} - - -/* -=============================================================================== - -idTarget_Show - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_Show ) - EVENT( EV_Activate, idTarget_Show::Event_Activate ) -END_CLASS - -/* -================ -idTarget_Show::Event_Activate -================ -*/ -void idTarget_Show::Event_Activate( idEntity *activator ) { - int i; - idEntity *ent; - - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->Show(); - } - } - - // delete our self when done - PostEventMS( &EV_Remove, 0 ); -} - - -/* -=============================================================================== - -idTarget_Damage - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_Damage ) - EVENT( EV_Activate, idTarget_Damage::Event_Activate ) -END_CLASS - -/* -================ -idTarget_Damage::Event_Activate -================ -*/ -void idTarget_Damage::Event_Activate( idEntity *activator ) { - int i; - const char *damage; - idEntity * ent; - - damage = spawnArgs.GetString( "def_damage", "damage_generic" ); - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->Damage( this, this, vec3_origin, damage, 1.0f, INVALID_JOINT ); - } - } -} - - -/* -=============================================================================== - -idTarget_SessionCommand - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SessionCommand ) - EVENT( EV_Activate, idTarget_SessionCommand::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SessionCommand::Event_Activate -================ -*/ -void idTarget_SessionCommand::Event_Activate( idEntity *activator ) { - gameLocal.sessionCommand = spawnArgs.GetString( "command" ); -} - - -/* -=============================================================================== - -idTarget_EndLevel - -Just a modified form of idTarget_SessionCommand -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_EndLevel ) - EVENT( EV_Activate, idTarget_EndLevel::Event_Activate ) -END_CLASS - -/* -================ -idTarget_EndLevel::Event_Activate -================ -*/ -void idTarget_EndLevel::Event_Activate( idEntity *activator ) { - idStr nextMap; - -#ifdef ID_DEMO_BUILD - if ( spawnArgs.GetBool( "endOfGame" ) ) { - cvarSystem->SetCVarBool( "g_nightmare", true ); - gameLocal.sessionCommand = "endofDemo"; - return; - } -#else - if ( spawnArgs.GetBool( "endOfGame" ) ) { - cvarSystem->SetCVarBool( "g_nightmare", true ); - gameLocal.sessionCommand = "disconnect"; - return; - } -#endif - if ( !spawnArgs.GetString( "nextMap", "", nextMap ) ) { - gameLocal.Printf( "idTarget_SessionCommand::Event_Activate: no nextMap key\n" ); - return; - } - - if ( spawnArgs.GetInt( "devmap", "0" ) ) { - gameLocal.sessionCommand = "devmap "; // only for special demos - } else { - gameLocal.sessionCommand = "map "; - } - - gameLocal.sessionCommand += nextMap; -} - - -/* -=============================================================================== - -idTarget_WaitForButton - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_WaitForButton ) - EVENT( EV_Activate, idTarget_WaitForButton::Event_Activate ) -END_CLASS - -/* -================ -idTarget_WaitForButton::Event_Activate -================ -*/ -void idTarget_WaitForButton::Event_Activate( idEntity *activator ) { - if ( thinkFlags & TH_THINK ) { - BecomeInactive( TH_THINK ); - } else { - // always allow during cinematics - cinematic = true; - BecomeActive( TH_THINK ); - } -} - -/* -================ -idTarget_WaitForButton::Think -================ -*/ -void idTarget_WaitForButton::Think( void ) { - idPlayer *player; - - if ( thinkFlags & TH_THINK ) { - player = gameLocal.GetLocalPlayer(); - if ( player && ( !player->oldButtons & BUTTON_ATTACK ) && ( player->usercmd.buttons & BUTTON_ATTACK ) ) { - player->usercmd.buttons &= ~BUTTON_ATTACK; - BecomeInactive( TH_THINK ); - ActivateTargets( player ); - } - } else { - BecomeInactive( TH_ALL ); - } -} - - -/* -=============================================================================== - -idTarget_SetGlobalShaderParm - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetGlobalShaderTime ) -EVENT( EV_Activate, idTarget_SetGlobalShaderTime::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SetGlobalShaderTime::Event_Activate -================ -*/ -void idTarget_SetGlobalShaderTime::Event_Activate( idEntity *activator ) { - int parm = spawnArgs.GetInt( "globalParm" ); - float time = -MS2SEC( gameLocal.time ); - if ( parm >= 0 && parm < MAX_GLOBAL_SHADER_PARMS ) { - gameLocal.globalShaderParms[parm] = time; - } -} - -/* -=============================================================================== - -idTarget_SetShaderParm - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetShaderParm ) - EVENT( EV_Activate, idTarget_SetShaderParm::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SetShaderParm::Event_Activate -================ -*/ -void idTarget_SetShaderParm::Event_Activate( idEntity *activator ) { - int i; - idEntity * ent; - float value; - idVec3 color; - int parmnum; - - // set the color on the targets - if ( spawnArgs.GetVector( "_color", "1 1 1", color ) ) { - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->SetColor( color[ 0 ], color[ 1 ], color[ 2 ] ); - } - } - } - - // set any shader parms on the targets - for( parmnum = 0; parmnum < MAX_ENTITY_SHADER_PARMS; parmnum++ ) { - if ( spawnArgs.GetFloat( va( "shaderParm%d", parmnum ), "0", value ) ) { - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->SetShaderParm( parmnum, value ); - } - } - if (spawnArgs.GetBool("toggle") && (value == 0 || value == 1)) { - int val = static_cast(value); - val ^= 1; - value = val; - spawnArgs.SetFloat(va("shaderParm%d", parmnum), value); - } - } - } -} - - -/* -=============================================================================== - -idTarget_SetShaderTime - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetShaderTime ) - EVENT( EV_Activate, idTarget_SetShaderTime::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SetShaderTime::Event_Activate -================ -*/ -void idTarget_SetShaderTime::Event_Activate( idEntity *activator ) { - int i; - idEntity * ent; - float time; - - time = -MS2SEC( gameLocal.time ); - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->SetShaderParm( SHADERPARM_TIMEOFFSET, time ); - if ( ent->IsType( idLight::Type ) ) { - static_cast(ent)->SetLightParm( SHADERPARM_TIMEOFFSET, time ); - } - } - } -} - -/* -=============================================================================== - -idTarget_FadeEntity - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_FadeEntity ) - EVENT( EV_Activate, idTarget_FadeEntity::Event_Activate ) -END_CLASS - -/* -================ -idTarget_FadeEntity::idTarget_FadeEntity -================ -*/ -idTarget_FadeEntity::idTarget_FadeEntity( void ) { - fadeFrom.Zero(); - fadeStart = 0; - fadeEnd = 0; -} - -/* -================ -idTarget_FadeEntity::Save -================ -*/ -void idTarget_FadeEntity::Save( idSaveGame *savefile ) const { - savefile->WriteVec4( fadeFrom ); - savefile->WriteInt( fadeStart ); - savefile->WriteInt( fadeEnd ); -} - -/* -================ -idTarget_FadeEntity::Restore -================ -*/ -void idTarget_FadeEntity::Restore( idRestoreGame *savefile ) { - savefile->ReadVec4( fadeFrom ); - savefile->ReadInt( fadeStart ); - savefile->ReadInt( fadeEnd ); -} - -/* -================ -idTarget_FadeEntity::Event_Activate -================ -*/ -void idTarget_FadeEntity::Event_Activate( idEntity *activator ) { - idEntity *ent; - int i; - - if ( !targets.Num() ) { - return; - } - - // always allow during cinematics - cinematic = true; - BecomeActive( TH_THINK ); - - ent = this; - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->GetColor( fadeFrom ); - break; - } - } - - fadeStart = gameLocal.time; - fadeEnd = gameLocal.time + SEC2MS( spawnArgs.GetFloat( "fadetime" ) ); -} - -/* -================ -idTarget_FadeEntity::Think -================ -*/ -void idTarget_FadeEntity::Think( void ) { - int i; - idEntity *ent; - idVec4 color; - idVec4 fadeTo; - float frac; - - if ( thinkFlags & TH_THINK ) { - GetColor( fadeTo ); - if ( gameLocal.time >= fadeEnd ) { - color = fadeTo; - BecomeInactive( TH_THINK ); - } else { - frac = ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ); - color.Lerp( fadeFrom, fadeTo, frac ); - } - - // set the color on the targets - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->SetColor( color ); - } - } - } else { - BecomeInactive( TH_ALL ); - } -} - -/* -=============================================================================== - -idTarget_LightFadeIn - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_LightFadeIn ) - EVENT( EV_Activate, idTarget_LightFadeIn::Event_Activate ) -END_CLASS - -/* -================ -idTarget_LightFadeIn::Event_Activate -================ -*/ -void idTarget_LightFadeIn::Event_Activate( idEntity *activator ) { - idEntity *ent; - idLight *light; - int i; - float time; - - if ( !targets.Num() ) { - return; - } - - time = spawnArgs.GetFloat( "fadetime" ); - ent = this; - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( !ent ) { - continue; - } - if ( ent->IsType( idLight::Type ) ) { - light = static_cast( ent ); - light->FadeIn( time ); - } else { - gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() ); - } - } -} - -/* -=============================================================================== - -idTarget_LightFadeOut - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_LightFadeOut ) - EVENT( EV_Activate, idTarget_LightFadeOut::Event_Activate ) -END_CLASS - -/* -================ -idTarget_LightFadeOut::Event_Activate -================ -*/ -void idTarget_LightFadeOut::Event_Activate( idEntity *activator ) { - idEntity *ent; - idLight *light; - int i; - float time; - - if ( !targets.Num() ) { - return; - } - - time = spawnArgs.GetFloat( "fadetime" ); - ent = this; - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( !ent ) { - continue; - } - if ( ent->IsType( idLight::Type ) ) { - light = static_cast( ent ); - light->FadeOut( time ); - } else { - gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() ); - } - } -} - -/* -=============================================================================== - -idTarget_Give - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_Give ) - EVENT( EV_Activate, idTarget_Give::Event_Activate ) -END_CLASS - -/* -================ -idTarget_Give::Spawn -================ -*/ -void idTarget_Give::Spawn( void ) { - if ( spawnArgs.GetBool( "onSpawn" ) ) { - PostEventMS( &EV_Activate, 50 ); - } -} - -/* -================ -idTarget_Give::Event_Activate -================ -*/ -void idTarget_Give::Event_Activate( idEntity *activator ) { - - if ( spawnArgs.GetBool( "development" ) && developer.GetInteger() == 0 ) { - return; - } - - static int giveNum = 0; - idPlayer *player = gameLocal.GetLocalPlayer(); - if ( player ) { - const idKeyValue *kv = spawnArgs.MatchPrefix( "item", NULL ); - while ( kv ) { - const idDict *dict = gameLocal.FindEntityDefDict( kv->GetValue(), false ); - if ( dict ) { - idDict d2; - d2.Copy( *dict ); - d2.Set( "name", va( "givenitem_%i", giveNum++ ) ); - idEntity *ent = NULL; - if ( gameLocal.SpawnEntityDef( d2, &ent ) && ent && ent->IsType( idItem::Type ) ) { - idItem *item = static_cast(ent); - item->GiveToPlayer( gameLocal.GetLocalPlayer() ); - } - } - kv = spawnArgs.MatchPrefix( "item", kv ); - } - } -} - -/* -=============================================================================== - -idTarget_SetModel - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetModel ) - EVENT( EV_Activate, idTarget_SetModel::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SetModel::Spawn -================ -*/ -void idTarget_SetModel::Spawn( void ) { - const char *model; - - model = spawnArgs.GetString( "newmodel" ); - if ( declManager->FindType( DECL_MODELDEF, model, false ) == NULL ) { - // precache the render model - renderModelManager->FindModel( model ); - // precache .cm files only - collisionModelManager->LoadModel( model, true ); - } -} - -/* -================ -idTarget_SetModel::Event_Activate -================ -*/ -void idTarget_SetModel::Event_Activate( idEntity *activator ) { - for( int i = 0; i < targets.Num(); i++ ) { - idEntity *ent = targets[ i ].GetEntity(); - if ( ent ) { - ent->SetModel( spawnArgs.GetString( "newmodel" ) ); - } - } -} - - -/* -=============================================================================== - -idTarget_SetInfluence - -=============================================================================== -*/ - -const idEventDef EV_RestoreInfluence( "" ); -const idEventDef EV_GatherEntities( "" ); -const idEventDef EV_Flash( "", "fd" ); -const idEventDef EV_ClearFlash( "", "f" ); - -CLASS_DECLARATION( idTarget, idTarget_SetInfluence ) - EVENT( EV_Activate, idTarget_SetInfluence::Event_Activate ) - EVENT( EV_RestoreInfluence, idTarget_SetInfluence::Event_RestoreInfluence ) - EVENT( EV_GatherEntities, idTarget_SetInfluence::Event_GatherEntities ) - EVENT( EV_Flash, idTarget_SetInfluence::Event_Flash ) - EVENT( EV_ClearFlash, idTarget_SetInfluence::Event_ClearFlash ) -END_CLASS - -/* -================ -idTarget_SetInfluence::idTarget_SetInfluence -================ -*/ -idTarget_SetInfluence::idTarget_SetInfluence( void ) { - flashIn = 0.0f; - flashOut = 0.0f; - delay = 0.0f; - switchToCamera = NULL; - soundFaded = false; - restoreOnTrigger = false; -} - -/* -================ -idTarget_SetInfluence::Save -================ -*/ -void idTarget_SetInfluence::Save( idSaveGame *savefile ) const { - int i; - - savefile->WriteInt( lightList.Num() ); - for( i = 0; i < lightList.Num(); i++ ) { - savefile->WriteInt( lightList[ i ] ); - } - - savefile->WriteInt( guiList.Num() ); - for( i = 0; i < guiList.Num(); i++ ) { - savefile->WriteInt( guiList[ i ] ); - } - - savefile->WriteInt( soundList.Num() ); - for( i = 0; i < soundList.Num(); i++ ) { - savefile->WriteInt( soundList[ i ] ); - } - - savefile->WriteInt( genericList.Num() ); - for( i = 0; i < genericList.Num(); i++ ) { - savefile->WriteInt( genericList[ i ] ); - } - - savefile->WriteFloat( flashIn ); - savefile->WriteFloat( flashOut ); - - savefile->WriteFloat( delay ); - - savefile->WriteString( flashInSound ); - savefile->WriteString( flashOutSound ); - - savefile->WriteObject( switchToCamera ); - - savefile->WriteFloat( fovSetting.GetStartTime() ); - savefile->WriteFloat( fovSetting.GetDuration() ); - savefile->WriteFloat( fovSetting.GetStartValue() ); - savefile->WriteFloat( fovSetting.GetEndValue() ); - - savefile->WriteBool( soundFaded ); - savefile->WriteBool( restoreOnTrigger ); -} - -/* -================ -idTarget_SetInfluence::Restore -================ -*/ -void idTarget_SetInfluence::Restore( idRestoreGame *savefile ) { - int i, num; - int itemNum; - float set; - - savefile->ReadInt( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadInt( itemNum ); - lightList.Append( itemNum ); - } - - savefile->ReadInt( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadInt( itemNum ); - guiList.Append( itemNum ); - } - - savefile->ReadInt( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadInt( itemNum ); - soundList.Append( itemNum ); - } - - savefile->ReadInt( num ); - for ( i = 0; i < num; i++ ) { - savefile->ReadInt( itemNum ); - genericList.Append( itemNum ); - } - - savefile->ReadFloat( flashIn ); - savefile->ReadFloat( flashOut ); - - savefile->ReadFloat( delay ); - - savefile->ReadString( flashInSound ); - savefile->ReadString( flashOutSound ); - - savefile->ReadObject( reinterpret_cast( switchToCamera ) ); - - savefile->ReadFloat( set ); - fovSetting.SetStartTime( set ); - savefile->ReadFloat( set ); - fovSetting.SetDuration( set ); - savefile->ReadFloat( set ); - fovSetting.SetStartValue( set ); - savefile->ReadFloat( set ); - fovSetting.SetEndValue( set ); - - savefile->ReadBool( soundFaded ); - savefile->ReadBool( restoreOnTrigger ); -} - -/* -================ -idTarget_SetInfluence::Spawn -================ -*/ -void idTarget_SetInfluence::Spawn() { - PostEventMS( &EV_GatherEntities, 0 ); - flashIn = spawnArgs.GetFloat( "flashIn", "0" ); - flashOut = spawnArgs.GetFloat( "flashOut", "0" ); - flashInSound = spawnArgs.GetString( "snd_flashin" ); - flashOutSound = spawnArgs.GetString( "snd_flashout" ); - delay = spawnArgs.GetFloat( "delay" ); - soundFaded = false; - restoreOnTrigger = false; - - // always allow during cinematics - cinematic = true; -} - -/* -================ -idTarget_SetInfluence::Event_Flash -================ -*/ -void idTarget_SetInfluence::Event_Flash( float flash, int out ) { - idPlayer *player = gameLocal.GetLocalPlayer(); - player->playerView.Fade( idVec4( 1, 1, 1, 1 ), static_cast(flash) ); - const idSoundShader *shader = NULL; - if ( !out && flashInSound.Length() ){ - shader = declManager->FindSound( flashInSound ); - player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL ); - } else if ( out && ( flashOutSound.Length() || flashInSound.Length() ) ) { - shader = declManager->FindSound( flashOutSound.Length() ? flashOutSound : flashInSound ); - player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL ); - } - PostEventSec( &EV_ClearFlash, flash, flash ); -} - - -/* -================ -idTarget_SetInfluence::Event_ClearFlash -================ -*/ -void idTarget_SetInfluence::Event_ClearFlash( float flash ) { - idPlayer *player = gameLocal.GetLocalPlayer(); - player->playerView.Fade( vec4_zero , static_cast(flash) ); -} -/* -================ -idTarget_SetInfluence::Event_GatherEntities -================ -*/ -void idTarget_SetInfluence::Event_GatherEntities() { - int i, listedEntities; - idEntity *entityList[ MAX_GENTITIES ]; - -// bool demonicOnly = spawnArgs.GetBool( "effect_demonic" ); - bool lights = spawnArgs.GetBool( "effect_lights" ); - bool sounds = spawnArgs.GetBool( "effect_sounds" ); - bool guis = spawnArgs.GetBool( "effect_guis" ); - bool models = spawnArgs.GetBool( "effect_models" ); - bool vision = spawnArgs.GetBool( "effect_vision" ); - bool targetsOnly = spawnArgs.GetBool( "targetsOnly" ); - - lightList.Clear(); - guiList.Clear(); - soundList.Clear(); - - if ( spawnArgs.GetBool( "effect_all" ) ) { - lights = sounds = guis = models = vision = true; - } - - if ( targetsOnly ) { - listedEntities = targets.Num(); - for ( i = 0; i < listedEntities; i++ ) { - entityList[i] = targets[i].GetEntity(); - } - } else { - float radius = spawnArgs.GetFloat( "radius" ); - listedEntities = gameLocal.EntitiesWithinRadius( GetPhysics()->GetOrigin(), radius, entityList, MAX_GENTITIES ); - } - - for( i = 0; i < listedEntities; i++ ) { - idEntity *ent = entityList[ i ]; - if ( ent ) { - if ( lights && ent->IsType( idLight::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) { - lightList.Append( ent->entityNumber ); - continue; - } - if ( sounds && ent->IsType( idSound::Type ) && ent->spawnArgs.FindKey( "snd_demonic" ) ) { - soundList.Append( ent->entityNumber ); - continue; - } - if ( guis && ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ 0 ] && ent->spawnArgs.FindKey( "gui_demonic" ) ) { - guiList.Append( ent->entityNumber ); - continue; - } - if ( ent->IsType( idStaticEntity::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) { - genericList.Append( ent->entityNumber ); - continue; - } - } - } - idStr temp; - temp = spawnArgs.GetString( "switchToView" ); - switchToCamera = ( temp.Length() ) ? gameLocal.FindEntity( temp ) : NULL; - -} - -/* -================ -idTarget_SetInfluence::Event_Activate -================ -*/ -void idTarget_SetInfluence::Event_Activate( idEntity *activator ) { - int i, j; - idEntity *ent; - idLight *light; - idSound *sound; - idStaticEntity *generic; - const char *parm; - const char *skin; - bool update; - idVec3 color; - idVec4 colorTo; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - - if ( spawnArgs.GetBool( "triggerActivate" ) ) { - if ( restoreOnTrigger ) { - ProcessEvent( &EV_RestoreInfluence ); - restoreOnTrigger = false; - return; - } - restoreOnTrigger = true; - } - - float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" ); - - if ( delay > 0.0f ) { - PostEventSec( &EV_Activate, delay, activator ); - delay = 0.0f; - // start any sound fading now - if ( fadeTime ) { - gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime ); - soundFaded = true; - } - return; - } else if ( fadeTime && !soundFaded ) { - gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime ); - soundFaded = true; - } - - if ( spawnArgs.GetBool( "triggerTargets" ) ) { - ActivateTargets( activator ); - } - - if ( flashIn ) { - PostEventSec( &EV_Flash, 0.0f, flashIn, 0 ); - } - - parm = spawnArgs.GetString( "snd_influence" ); - if ( parm && *parm ) { - PostEventSec( &EV_StartSoundShader, flashIn, parm, SND_CHANNEL_ANY ); - } - - if ( switchToCamera ) { - switchToCamera->PostEventSec( &EV_Activate, flashIn + 0.05f, this ); - } - - int fov = spawnArgs.GetInt( "fov" ); - if ( fov ) { - fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "fovTime" ) ), player->DefaultFov(), fov ); - BecomeActive( TH_THINK ); - } - - for ( i = 0; i < genericList.Num(); i++ ) { - ent = gameLocal.entities[genericList[i]]; - if ( ent == NULL ) { - continue; - } - generic = static_cast( ent ); - color = generic->spawnArgs.GetVector( "color_demonic" ); - colorTo.Set( color.x, color.y, color.z, 1.0f ); - generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); - } - - for ( i = 0; i < lightList.Num(); i++ ) { - ent = gameLocal.entities[lightList[i]]; - if ( ent == NULL || !ent->IsType( idLight::Type ) ) { - continue; - } - light = static_cast(ent); - parm = light->spawnArgs.GetString( "mat_demonic" ); - if ( parm && *parm ) { - light->SetShader( parm ); - } - - color = light->spawnArgs.GetVector( "_color" ); - color = light->spawnArgs.GetVector( "color_demonic", color.ToString() ); - colorTo.Set( color.x, color.y, color.z, 1.0f ); - light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); - } - - for ( i = 0; i < soundList.Num(); i++ ) { - ent = gameLocal.entities[soundList[i]]; - if ( ent == NULL || !ent->IsType( idSound::Type ) ) { - continue; - } - sound = static_cast(ent); - parm = sound->spawnArgs.GetString( "snd_demonic" ); - if ( parm && *parm ) { - if ( sound->spawnArgs.GetBool( "overlayDemonic" ) ) { - sound->StartSound( "snd_demonic", SND_CHANNEL_DEMONIC, 0, false, NULL ); - } else { - sound->StopSound( SND_CHANNEL_ANY, false ); - sound->SetSound( parm ); - } - } - } - - for ( i = 0; i < guiList.Num(); i++ ) { - ent = gameLocal.entities[guiList[i]]; - if ( ent == NULL || ent->GetRenderEntity() == NULL ) { - continue; - } - update = false; - for ( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { - if ( ent->GetRenderEntity()->gui[ j ] && ent->spawnArgs.FindKey( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ) ) { - ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ), true ); - update = true; - } - } - - if ( update ) { - ent->UpdateVisuals(); - ent->Present(); - } - } - - player->SetInfluenceLevel( spawnArgs.GetInt( "influenceLevel" ) ); - - int snapAngle = spawnArgs.GetInt( "snapAngle" ); - if ( snapAngle ) { - idAngles ang( 0, snapAngle, 0 ); - player->SetViewAngles( ang ); - player->SetAngles( ang ); - } - - if ( spawnArgs.GetBool( "effect_vision" ) ) { - parm = spawnArgs.GetString( "mtrVision" ); - skin = spawnArgs.GetString( "skinVision" ); - player->SetInfluenceView( parm, skin, spawnArgs.GetInt( "visionRadius" ), this ); - } - - parm = spawnArgs.GetString( "mtrWorld" ); - if ( parm && *parm ) { - gameLocal.SetGlobalMaterial( declManager->FindMaterial( parm ) ); - } - - if ( !restoreOnTrigger ) { - PostEventMS( &EV_RestoreInfluence, SEC2MS( spawnArgs.GetFloat( "time" ) ) ); - } -} - -/* -================ -idTarget_SetInfluence::Think -================ -*/ -void idTarget_SetInfluence::Think( void ) { - if ( thinkFlags & TH_THINK ) { - idPlayer *player = gameLocal.GetLocalPlayer(); - player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) ); - if ( fovSetting.IsDone( gameLocal.time ) ) { - if ( !spawnArgs.GetBool( "leaveFOV" ) ) { - player->SetInfluenceFov( 0 ); - } - BecomeInactive( TH_THINK ); - } - } else { - BecomeInactive( TH_ALL ); - } -} - - -/* -================ -idTarget_SetInfluence::Event_RestoreInfluence -================ -*/ -void idTarget_SetInfluence::Event_RestoreInfluence() { - int i, j; - idEntity *ent; - idLight *light; - idSound *sound; - idStaticEntity *generic; - bool update; - idVec3 color; - idVec4 colorTo; - - if ( flashOut ) { - PostEventSec( &EV_Flash, 0.0f, flashOut, 1 ); - } - - if ( switchToCamera ) { - switchToCamera->PostEventMS( &EV_Activate, 0, this ); - } - - for ( i = 0; i < genericList.Num(); i++ ) { - ent = gameLocal.entities[genericList[i]]; - if ( ent == NULL ) { - continue; - } - generic = static_cast( ent ); - colorTo.Set( 1.0f, 1.0f, 1.0f, 1.0f ); - generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); - } - - for ( i = 0; i < lightList.Num(); i++ ) { - ent = gameLocal.entities[lightList[i]]; - if ( ent == NULL || !ent->IsType( idLight::Type ) ) { - continue; - } - light = static_cast(ent); - if ( !light->spawnArgs.GetBool( "leave_demonic_mat" ) ) { - const char *texture = light->spawnArgs.GetString( "texture", "lights/squarelight1" ); - light->SetShader( texture ); - } - color = light->spawnArgs.GetVector( "_color" ); - colorTo.Set( color.x, color.y, color.z, 1.0f ); - light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) ); - } - - for ( i = 0; i < soundList.Num(); i++ ) { - ent = gameLocal.entities[soundList[i]]; - if ( ent == NULL || !ent->IsType( idSound::Type ) ) { - continue; - } - sound = static_cast(ent); - sound->StopSound( SND_CHANNEL_ANY, false ); - sound->SetSound( sound->spawnArgs.GetString( "s_shader" ) ); - } - - for ( i = 0; i < guiList.Num(); i++ ) { - ent = gameLocal.entities[guiList[i]]; - if ( ent == NULL || GetRenderEntity() == NULL ) { - continue; - } - update = false; - for( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { - if ( ent->GetRenderEntity()->gui[ j ] ) { - ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui" : va( "gui%d", j+1 ) ) ); - update = true; - } - } - if ( update ) { - ent->UpdateVisuals(); - ent->Present(); - } - } - - idPlayer *player = gameLocal.GetLocalPlayer(); - player->SetInfluenceLevel( 0 ); - player->SetInfluenceView( NULL, NULL, 0.0f, NULL ); - player->SetInfluenceFov( 0 ); - gameLocal.SetGlobalMaterial( NULL ); - float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" ); - if ( fadeTime ) { - gameSoundWorld->FadeSoundClasses( 0, 0.0f, fadeTime / 2.0f ); - } - -} - -/* -=============================================================================== - -idTarget_SetKeyVal - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetKeyVal ) - EVENT( EV_Activate, idTarget_SetKeyVal::Event_Activate ) -END_CLASS - -/* -================ -idTarget_SetKeyVal::Event_Activate -================ -*/ -void idTarget_SetKeyVal::Event_Activate( idEntity *activator ) { - int i; - idStr key, val; - idEntity *ent; - const idKeyValue *kv; - int n; - - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent ) { - kv = spawnArgs.MatchPrefix("keyval"); - while ( kv ) { - n = kv->GetValue().Find( ";" ); - if ( n > 0 ) { - key = kv->GetValue().Left( n ); - val = kv->GetValue().Right( kv->GetValue().Length() - n - 1 ); - ent->spawnArgs.Set( key, val ); - for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) { - if ( ent->GetRenderEntity()->gui[ j ] ) { - if ( idStr::Icmpn( key, "gui_", 4 ) == 0 ) { - ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val ); - ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time ); - } - } - } - } - kv = spawnArgs.MatchPrefix( "keyval", kv ); - } - ent->UpdateChangeableSpawnArgs( NULL ); - ent->UpdateVisuals(); - ent->Present(); - } - } -} - -/* -=============================================================================== - -idTarget_SetFov - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_SetFov ) - EVENT( EV_Activate, idTarget_SetFov::Event_Activate ) -END_CLASS - - -/* -================ -idTarget_SetFov::Save -================ -*/ -void idTarget_SetFov::Save( idSaveGame *savefile ) const { - - savefile->WriteFloat( fovSetting.GetStartTime() ); - savefile->WriteFloat( fovSetting.GetDuration() ); - savefile->WriteFloat( fovSetting.GetStartValue() ); - savefile->WriteFloat( fovSetting.GetEndValue() ); -} - -/* -================ -idTarget_SetFov::Restore -================ -*/ -void idTarget_SetFov::Restore( idRestoreGame *savefile ) { - float setting; - - savefile->ReadFloat( setting ); - fovSetting.SetStartTime( setting ); - savefile->ReadFloat( setting ); - fovSetting.SetDuration( setting ); - savefile->ReadFloat( setting ); - fovSetting.SetStartValue( static_cast(setting) ); - savefile->ReadFloat( setting ); - fovSetting.SetEndValue( static_cast(setting) ); - - fovSetting.GetCurrentValue( gameLocal.time ); -} - -/* -================ -idTarget_SetFov::Event_Activate -================ -*/ -void idTarget_SetFov::Event_Activate( idEntity *activator ) { - // always allow during cinematics - cinematic = true; - - idPlayer *player = gameLocal.GetLocalPlayer(); - fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "time" ) ), static_cast(player ? player->DefaultFov() : g_fov.GetFloat()), static_cast(spawnArgs.GetFloat( "fov" )) ); - BecomeActive( TH_THINK ); -} - -/* -================ -idTarget_SetFov::Think -================ -*/ -void idTarget_SetFov::Think( void ) { - if ( thinkFlags & TH_THINK ) { - idPlayer *player = gameLocal.GetLocalPlayer(); - player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) ); - if ( fovSetting.IsDone( gameLocal.time ) ) { - player->SetInfluenceFov( 0.0f ); - BecomeInactive( TH_THINK ); - } - } else { - BecomeInactive( TH_ALL ); - } -} - -/* -=============================================================================== - -idTarget_CallObjectFunction - -Tels: - -If "pass_self" is true, the first argument of the called object function is the -triggered entity. This is useful for teleportTo(target), for instance. - -If "pass_activator" is true, the first argument of the called object function -is the entity that caused the trigger. -This is useful for atdm:voice, for instance. - -If "pass_self" and "pass_activator" are true, then the order of arguments -is first "target", then as second argument "activator". - -Note that the method you want to call needs to have exactly the number -of arguments, e.g. zero (pass_self and pass_activator false), 1 (pass_self -or pass_activator true) or two (both are true). - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_CallObjectFunction ) - EVENT( EV_Activate, idTarget_CallObjectFunction::Event_Activate ) -END_CLASS - -/* -================ -idTarget_CallObjectFunction::Event_Activate -================ -*/ -void idTarget_CallObjectFunction::Event_Activate( idEntity *activator ) { - int i; - idEntity *ent; - const function_t *func; - const char *funcName; - idThread *thread; - - funcName = spawnArgs.GetString( "call" ); - // we delay each post by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget - float wait = spawnArgs.GetFloat ( "wait", "0"); - float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); - float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); - float delay = spawnArgs.GetFloat ( "delay", "0"); - bool pass_self = spawnArgs.GetBool ( "pass_self", "0"); - bool pass_activator = spawnArgs.GetBool ( "pass_activator", "0"); - - // avoid a negative delay - if (wait < 0) { wait = 0; } - if (delay < 0) { delay = 0; } - // wait_add can be negative, we will later make sure that wait is never negative - // - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("%s: Calling object function %s on %i targets.\r", name.c_str(), funcName, targets.Num() ); - - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - if ( ent && ent->scriptObject.HasObject() ) { - func = ent->scriptObject.GetFunction( funcName ); - if ( !func ) { - gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - int numParams = 1; - if (pass_self) { numParams ++; } - if (pass_activator) { numParams ++; } - - if ( func->type->NumParameters() != numParams ) { - gameLocal.Error( "Function '%s' on entity '%s' has the wrong number of parameters for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { - gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Starting call for target #%i\r", i); - // create a thread and call the function - thread = new idThread(); - if (numParams == 1) { - thread->CallFunction( ent, func, true ); - } else if (numParams == 2) { - if (pass_self) { - thread->CallFunctionArgs( func, true, "ee", ent, this ); - } else { - thread->CallFunctionArgs( func, true, "ee", ent, activator ); - } - } else { // if (numParams == 3) { - thread->CallFunctionArgs( func, true, "eee", ent, this, activator ); - } - thread->DelayedStart( delay ); - - delay += wait; - wait += wait_add; - wait *= wait_mul; - // avoid a negative delay - if (wait < 0) { wait = 0; } - } - else - { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No entity or no script object on target #%i.\r", i ); - } - } -} - -/* -=============================================================================== - -Tels idTarget_PostScriptEvent - -This locks up the named event and then posts it with the specified "delay" -for each target. The delay is increased for each target as specified with -the "wait" spawnarg. - -If "pass_self" is true, the first argument of the posted event is the -triggered entity. This is useful for target->teleportTo(triggeredEntity). - -If "pass_activator" is true, the first argument of the posted event is the -entity that activated the trigger. This is useful for target->AddItemToInv(activator). - -If "propagate_to_team" is true, then the event will be posted to all members -of the team that the target is a member of. Useful for posting events -to entites that have other entities bound to them like holders with lights. - -In case the named event cannot be found, this tries to call the script -object function on each target entity, provided the entity in question -has a script object (if not, a warning is issued) and the method -there exists (if not, an error is thrown). -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_PostScriptEvent ) - EVENT( EV_Activate, idTarget_PostScriptEvent::Event_Activate ) -END_CLASS - -void idTarget_PostScriptEvent::TryPostOrCall( idEntity *ent, idEntity *activator, const idEventDef *ev, const char* funcName, const bool pass_self, const bool pass_activator, const float delay) -{ - const function_t *func; - - if (ev) { - if (pass_self) { - ent->PostEventSec( ev, delay, this ); - } - else if (pass_activator && !pass_self) { - ent->PostEventSec( ev, delay, activator ); - } else { - // both pass_self and pass_activator - ent->PostEventSec( ev, delay, this, activator ); - } - } else { - // try the script object function - if ( ent->scriptObject.HasObject() ) { - func = ent->scriptObject.GetFunction( funcName ); - if ( !func ) { - gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - int numParams = 1; - if (pass_self || pass_activator) { numParams = 2; } - if (pass_self && pass_activator) { numParams = 3; } - - if ( func->type->NumParameters() != numParams ) { - gameLocal.Error( "Function '%s' on entity '%s' has the wrong number of parameters for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - - if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) { - gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() ); - } - - // create a thread and call the function - idThread *thread = new idThread(); - if (numParams == 1) { - thread->CallFunction( ent, func, true ); - } else if (numParams == 2) { - thread->CallFunctionArgs( func, true, "ee", ent, this ); - } else { - thread->CallFunctionArgs( func, true, "eee", ent, this, activator ); - } - thread->DelayedStart( delay ); - } - else - { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No script object on target %s.\r", ent->name.c_str() ); - } - } -} - -/* -================ -idTarget_PostScriptEvent::Event_Activate -================ -*/ - -void idTarget_PostScriptEvent::Event_Activate( idEntity *activator ) { - int i; - idEntity *ent; - idEntity *NextEnt; - - // we delay each post by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget - float wait = spawnArgs.GetFloat ( "wait", "0"); - float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); - float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); - float delay = spawnArgs.GetFloat ( "delay", "0"); - const char* evName = spawnArgs.GetString( "event" ); - bool pass_self = spawnArgs.GetBool ( "pass_self", "0"); - bool pass_activator = spawnArgs.GetBool ( "pass_activator", "0"); - bool do_team = spawnArgs.GetBool ( "propagate_to_team", "0"); - - // avoid a negative delay - if (wait < 0) { wait = 0; } - if (delay < 0) { delay = 0; } - // wait_add can be negative, we will later make sure that wait is never negative - - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("%s: Posting event %s on %i targets (team: %i, pass_self: %i).\r", name.c_str(), evName, targets.Num(), do_team, pass_self ); - const idEventDef *ev = idEventDef::FindEvent( evName ); - - if ( !ev ) { - gameLocal.Error( "Unknown event '%s' on entity '%s'", evName, name.c_str() ); - } - - for( i = 0; i < targets.Num(); i++ ) { - ent = targets[ i ].GetEntity(); - - if (!ent) { continue; } - - // DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("Posting event on target #%i.\r", i); - if (do_team) { - NextEnt = ent; - idEntity* bind_master = ent->GetBindMaster(); - if (bind_master) { - NextEnt = bind_master; - } - - while ( NextEnt != NULL ) { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING(" Posting event on team member %s of target #%i.\r", NextEnt->GetName(), i); - TryPostOrCall( NextEnt, activator, ev, evName, pass_self, pass_activator, delay); - /* get next Team member */ - NextEnt = NextEnt->GetNextTeamEntity(); - } - - } else { - // we should post only to the target directly - TryPostOrCall( ent, activator, ev, evName, pass_self, pass_activator, delay); - } - - delay += wait; - wait += wait_add; - wait *= wait_mul; - // avoid a negative delay - if (wait < 0) { wait = 0; } - } // end for all targets -} - - -/* -=============================================================================== - -idTarget_EnableLevelWeapons - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_EnableLevelWeapons ) - EVENT( EV_Activate, idTarget_EnableLevelWeapons::Event_Activate ) -END_CLASS - -/* -================ -idTarget_EnableLevelWeapons::Event_Activate -================ -*/ -void idTarget_EnableLevelWeapons::Event_Activate( idEntity *activator ) { - int i; - const char *weap; - - gameLocal.world->spawnArgs.SetBool( "no_Weapons", spawnArgs.GetBool( "disable" ) ); - - if ( spawnArgs.GetBool( "disable" ) ) { - for( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] ) { - gameLocal.entities[ i ]->ProcessEvent( &EV_Player_DisableWeapon ); - } - } - } else { - weap = spawnArgs.GetString( "weapon" ); - for( i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] ) { - gameLocal.entities[ i ]->ProcessEvent( &EV_Player_EnableWeapon ); - if ( weap && weap[ 0 ] ) { - gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, weap ); - } - } - } - } -} - -/* -=============================================================================== - -idTarget_RemoveWeapons - -=============================================================================== -*/ - -CLASS_DECLARATION( idTarget, idTarget_RemoveWeapons ) -EVENT( EV_Activate, idTarget_RemoveWeapons::Event_Activate ) -END_CLASS - -/* -================ -idTarget_RemoveWeapons::Event_Activate -================ -*/ -void idTarget_RemoveWeapons::Event_Activate( idEntity *activator ) { - for( int i = 0; i < gameLocal.numClients; i++ ) { - if ( gameLocal.entities[ i ] ) { - idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] ); - const idKeyValue *kv = spawnArgs.MatchPrefix( "weapon", NULL ); - while ( kv ) { - player->RemoveWeapon( kv->GetValue() ); - kv = spawnArgs.MatchPrefix( "weapon", kv ); - } - player->SelectWeapon( player->weapon_fists, true ); - } - } -} - - -/* -=============================================================================== - -idTarget_FadeSoundClass - -=============================================================================== -*/ - -const idEventDef EV_RestoreVolume( "" ); -CLASS_DECLARATION( idTarget, idTarget_FadeSoundClass ) -EVENT( EV_Activate, idTarget_FadeSoundClass::Event_Activate ) -EVENT( EV_RestoreVolume, idTarget_FadeSoundClass::Event_RestoreVolume ) -END_CLASS - -/* -================ -idTarget_FadeSoundClass::Event_Activate -================ -*/ -void idTarget_FadeSoundClass::Event_Activate( idEntity *activator ) { - float fadeTime = spawnArgs.GetFloat( "fadeTime" ); - float fadeDB = spawnArgs.GetFloat( "fadeDB" ); - float fadeDuration = spawnArgs.GetFloat( "fadeDuration" ); - int fadeClass = spawnArgs.GetInt( "fadeClass" ); - // start any sound fading now - if ( fadeTime ) { - gameSoundWorld->FadeSoundClasses( fadeClass, spawnArgs.GetBool( "fadeIn" ) ? fadeDB : 0.0f - fadeDB, fadeTime ); - if ( fadeDuration ) { - PostEventSec( &EV_RestoreVolume, fadeDuration ); - } - } -} - -/* -================ -idTarget_FadeSoundClass::Event_RestoreVolume -================ -*/ -void idTarget_FadeSoundClass::Event_RestoreVolume() { - float fadeTime = spawnArgs.GetFloat( "fadeTime" ); - float fadeDB = spawnArgs.GetFloat( "fadeDB" ); -// int fadeClass = spawnArgs.GetInt( "fadeClass" ); - // restore volume - gameSoundWorld->FadeSoundClasses( 0, fadeDB, fadeTime ); -} - -/* -=============================================================================== - -CTarget_AddObjectives - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_AddObjectives ) - EVENT( EV_Activate, CTarget_AddObjectives::Event_Activate ) -END_CLASS - -void CTarget_AddObjectives::Spawn( void ) -{ - if( !spawnArgs.GetBool( "wait_for_trigger" ) ) - PostEventMS( &EV_Activate, 0, this ); -} - -void CTarget_AddObjectives::Event_Activate( idEntity *activator ) -{ - int SetVal(-1); - - if( gameLocal.m_MissionData ) - { - SetVal = gameLocal.m_MissionData->AddObjsFromEnt( this ); - } - - // greebo: If the entity is not the world entity, notify the player - if (spawnArgs.GetBool("wait_for_trigger") && activator != gameLocal.world) - { - gameLocal.m_MissionData->Event_NewObjective(); - } - - spawnArgs.Set( "obj_num_offset", va("%d", SetVal) ); -} - -/* -=============================================================================== - -CTarget_SetObjectiveState - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_SetObjectiveState ) - EVENT( EV_Activate, CTarget_SetObjectiveState::Event_Activate ) -END_CLASS - -void CTarget_SetObjectiveState::Spawn( void ) -{ - if( !spawnArgs.GetBool( "wait_for_trigger" ) ) - { - // Immediately fire the activate event, as we - // don't need to wait for a trigger event - PostEventMS(&EV_Activate, 0, this); - } -} - -void CTarget_SetObjectiveState::Event_Activate( idEntity *activator ) -{ - // greebo: Get the state we should set the objectives to - int state = spawnArgs.GetInt("obj_state", "0"); - - // Find all values that match the given prefix - const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); - - // greebo: Cycle through all matching spawnargs - while (keyVal != NULL) { - int objId = atoi(keyVal->GetValue().c_str()); - - if (objId > 0) { - // "Unlock" the objective first, if desired - if (spawnArgs.GetBool("unlatch_irreversible_objectives", "1")) - { - gameLocal.m_MissionData->UnlatchObjective(objId-1); - } - - // Now set the completion state - gameLocal.m_MissionData->SetCompletionState(objId-1, state); - } - else { - gameLocal.Warning("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); - } - - // greebo: Lookup the next matching spawnarg - keyVal = spawnArgs.MatchPrefix("obj_id", keyVal); - } -} - -/* -=============================================================================== - -CTarget_SetObjectiveVisibility - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_SetObjectiveVisibility ) - EVENT( EV_Activate, CTarget_SetObjectiveVisibility::Event_Activate ) -END_CLASS - -void CTarget_SetObjectiveVisibility::Spawn( void ) -{ - if( !spawnArgs.GetBool( "wait_for_trigger" ) ) - { - // Immediately fire the activate event, as we - // don't need to wait for a trigger event - PostEventMS(&EV_Activate, 0, this); - } -} - -void CTarget_SetObjectiveVisibility::Event_Activate( idEntity *activator ) -{ - // Get the visibility we should set the objectives to - bool bVisible = spawnArgs.GetBool("obj_visibility", "0"); - - // Find all values that match the given prefix - const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); - - // Cycle through all matching spawnargs - for (const idKeyValue* keyVal = spawnArgs.MatchPrefix("obj_id"); keyVal != NULL; - keyVal = spawnArgs.MatchPrefix("obj_id", keyVal)) - { - int objId = atoi(keyVal->GetValue().c_str()); - - if (objId > 0) - { - gameLocal.m_MissionData->SetObjectiveVisibility(objId - 1, bVisible); - } - else - { - gameLocal.Warning("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); - DM_LOG(LC_OBJECTIVES, LT_ERROR)LOGSTRING("Invalid objective ID %s on CTarget_SetObjectiveState %s\n", keyVal->GetValue().c_str(), name.c_str()); - } - } -} - -/* -=============================================================================== - -CTarget_SetObjectiveComponentState - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_SetObjectiveComponentState ) - EVENT( EV_Activate, CTarget_SetObjectiveComponentState::Event_Activate ) -END_CLASS - -void CTarget_SetObjectiveComponentState::Spawn( void ) -{ - if( !spawnArgs.GetBool( "wait_for_trigger" ) ) - { - // Immediately fire the activate event, as we - // don't need to wait for a trigger event - PostEventMS(&EV_Activate, 0, this); - } -} - -void CTarget_SetObjectiveComponentState::Event_Activate( idEntity *activator ) -{ - // Get the state we should set the objectives to - bool state = spawnArgs.GetBool("comp_state", "0"); - - // Find all values that match the given prefix - const idKeyValue* keyVal = spawnArgs.MatchPrefix("comp_id"); - - // Cycle through all matching spawnargs - while (keyVal != NULL) - { - idStr StringID = keyVal->GetValue(); - idStr objIDStr(StringID), compIDStr(StringID); - - objIDStr.StripTrailing(","); - compIDStr.StripLeading(","); - - int objId = atoi( objIDStr.c_str() ); - int compId = atoi( compIDStr.c_str() ); - - if (objId > 0 && compId > 0) - gameLocal.m_MissionData->SetComponentState_Ext(objId, compId, state); - else - gameLocal.Warning("Invalid objective component ID %s on CTarget_SetObjectiveState %s\n", StringID.c_str(), name.c_str()); - - // Lookup the next matching spawnarg - keyVal = spawnArgs.MatchPrefix("comp_id", keyVal); - } -} - -/* -=============================================================================== - -CTarget_StartConversation - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_StartConversation ) - EVENT( EV_Activate, CTarget_StartConversation::Event_Activate ) -END_CLASS - -void CTarget_StartConversation::Spawn( void ) -{ - if (spawnArgs.FindKey("conversation") == NULL) - { - gameLocal.Warning("Target %s has no 'conversation' spawnarg set!", name.c_str()); - return; - } -} - -void CTarget_StartConversation::Event_Activate( idEntity *activator ) -{ - idStr conversationName = spawnArgs.GetString("conversation"); - - if (conversationName.IsEmpty()) - { - gameLocal.Printf("Target %s has no 'conversation' spawnarg set!\n", name.c_str()); - return; - } - - // Try to find the conversation - int convIndex = gameLocal.m_ConversationSystem->GetConversationIndex(conversationName); - - if (convIndex == -1) - { - gameLocal.Printf("Target %s references non-existent conversation %s!\n", name.c_str(), conversationName.c_str()); - return; - } - - // Pass the torch to the conversationsystem to do the rest - gameLocal.m_ConversationSystem->StartConversation(convIndex); -} - -/* -=============================================================================== - -CTarget_SetFrobable - -=============================================================================== -*/ -CLASS_DECLARATION( idTarget, CTarget_SetFrobable ) - EVENT( EV_Activate, CTarget_SetFrobable::Event_Activate ) -END_CLASS - -CTarget_SetFrobable::CTarget_SetFrobable( void ) -{ - m_bCurFrobState = false; - m_EntsSetUnfrobable.Clear(); -} - -void CTarget_SetFrobable::Spawn( void ) -{ - spawnArgs.GetBool( "start_frobable", "0", m_bCurFrobState ); - - // Set the contents to a useless trigger so that the collision model will be loaded - // FLASHLIGHT_TRIGGER seems to be the only one that doesn't do anything else we don't want - GetPhysics()->SetContents( CONTENTS_FLASHLIGHT_TRIGGER ); - - // SR CONTENTS_RESONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - // Disable the clipmodel for now, only enable when needed - GetPhysics()->DisableClip(); - - // If we don't start frobable, activate once and set everything to not frobable - // This saves the mapper the time of manually setting everything inside not frobable to start out with - if( !m_bCurFrobState ) - { - m_bCurFrobState = true; - PostEventMS( &EV_Activate, 0, this ); - } -} - -void CTarget_SetFrobable::Event_Activate( idEntity *activator ) -{ - idEntity *Ents[MAX_GENTITIES]; - bool bOnList(false); - - // Contents mask: - int cm = CONTENTS_SOLID | CONTENTS_CORPSE | CONTENTS_RENDERMODEL | CONTENTS_BODY | CONTENTS_FROBABLE; - - // bounding box test to get entities inside - GetPhysics()->EnableClip(); - int numEnts = gameLocal.clip.EntitiesTouchingBounds(GetPhysics()->GetAbsBounds(), cm, Ents, MAX_GENTITIES); - GetPhysics()->DisableClip(); - - // toggle frobability - m_bCurFrobState = !m_bCurFrobState; - - for (int i = 0; i < numEnts; i++) - { - idEntity* ent = Ents[i]; - - // Don't set self or the world, or the player frobable - if (ent == NULL || ent == this || - ent == gameLocal.world || ent == gameLocal.GetLocalPlayer()) - { - continue; - } - - if (ent->spawnArgs.GetBool("immune_to_target_setfrobable", "0")) - { - continue; // greebo: per-entity exclusion - } - - if( m_bCurFrobState ) - { - // Before setting something frobable, check if it is on the - // list of things we set un-frobable earlier - bOnList = false; - - for( int k=0; k < m_EntsSetUnfrobable.Num(); k++ ) - { - if( m_EntsSetUnfrobable[k] == ent->name ) - { - bOnList = true; - break; - } - } - - if( bOnList ) - ent->SetFrobable( m_bCurFrobState ); - } - else - { - // setting unfrobable - if( ent->m_bFrobable ) - { - m_EntsSetUnfrobable.AddUnique( ent->name ); - ent->SetFrobable( m_bCurFrobState ); - } - } - -// Uncomment for debugging - - idStr frobnofrob = "not frobable."; - if( m_bCurFrobState ) - frobnofrob = "frobable."; - - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_SetFrobable: Set entity %s to frob state: %s\r", Ents[i]->name.c_str(), frobnofrob.c_str() ); - - } -} - -void CTarget_SetFrobable::Save( idSaveGame *savefile ) const -{ - savefile->WriteBool( m_bCurFrobState ); - - savefile->WriteInt( m_EntsSetUnfrobable.Num() ); - for( int i=0;i < m_EntsSetUnfrobable.Num(); i++ ) - savefile->WriteString( m_EntsSetUnfrobable[i] ); -} - -void CTarget_SetFrobable::Restore( idRestoreGame *savefile ) -{ - int num; - - savefile->ReadBool( m_bCurFrobState ); - - m_EntsSetUnfrobable.Clear(); - savefile->ReadInt( num ); - m_EntsSetUnfrobable.SetNum( num ); - for( int i=0;i < num; i++ ) - savefile->ReadString( m_EntsSetUnfrobable[i] ); -} - -/* -================ -CTarget_CallScriptFunction -================ -*/ -CLASS_DECLARATION( idTarget, CTarget_CallScriptFunction ) - EVENT( EV_Activate, CTarget_CallScriptFunction::Event_Activate ) -END_CLASS - -void CTarget_CallScriptFunction::Event_Activate( idEntity *activator ) -{ - // Get the function name - idStr funcName = spawnArgs.GetString("call"); - if (funcName.IsEmpty()) - { - gameLocal.Warning("Target %s has no script function to call!", name.c_str()); - return; - } - - // Get the function - const function_t* scriptFunction = gameLocal.program.FindFunction(funcName); - if (scriptFunction == NULL) - { - // script function not found! - gameLocal.Warning("Target %s specifies non-existent script function!", funcName.c_str()); - return; - } - - bool forEach = spawnArgs.GetBool("foreach","0"); - - if (forEach) - { - // we delay each call by: delay + (wait + (wait_add * numberOfTarget)) * numberOfTarget - float wait = spawnArgs.GetFloat ( "wait", "0"); - float wait_add = spawnArgs.GetFloat ( "wait_add", "0"); - float wait_mul = spawnArgs.GetFloat ( "wait_mul", "0"); - float delay = spawnArgs.GetFloat ( "delay", "0"); - - // avoid a negative delay - if (wait < 0) { wait = 0; } - if (delay < 0) { delay = 0; } - // wait_add can be negative, we will later make sure that wait is never negative - - for(int i = 0; i < targets.Num(); i++ ) - { - idEntity* ent = targets[ i ].GetEntity(); - if (!ent) - { - DM_LOG(LC_MISC, LT_DEBUG)LOGSTRING("No entity for script call on target #%i.\r", i ); - continue; - } - - // each call in its own thread so they can run in parallel - idThread* thread = new idThread(); - // Call "Foo(target, activator, triggred_entity);" - thread->CallFunctionArgs( scriptFunction, true, "eee", ent, activator, this ); - // and finally start the new thread after "delay" ms: - thread->DelayedStart(delay); - - delay += wait; - wait += wait_add; - wait *= wait_mul; - // avoid a negative delay - if (wait < 0) { wait = 0; } - } - } - else - { - idThread* thread = new idThread(scriptFunction); - thread->DelayedStart(0); - } -} - -/* -================ -CTarget_ChangeLockState -================ -*/ -CLASS_DECLARATION( idTarget, CTarget_ChangeLockState ) - EVENT( EV_Activate, CTarget_ChangeLockState::Event_Activate ) -END_CLASS - -void CTarget_ChangeLockState::Event_Activate(idEntity *activator) -{ - // Find all targetted frobmovers - for (int i = 0; i < targets.Num(); i++) - { - idEntity* ent = targets[i].GetEntity(); - - if (ent == NULL) continue; - - if (ent->IsType(CBinaryFrobMover::Type)) - { - CBinaryFrobMover* frobMover = static_cast(ent); - - if (spawnArgs.GetBool("toggle", "0")) - { - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Toggling lock state of entity %s\r", ent->name.c_str()); - frobMover->ToggleLock(); - } - else if (spawnArgs.GetBool("unlock", "1")) - { - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Unlocking entity %s\r", ent->name.c_str()); - frobMover->Unlock(); - } - else - { - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeLockState: Locking entity %s\r", ent->name.c_str()); - frobMover->Lock(); - } - } - } -} - -/* -================ -CTarget_ChangeTarget -================ -*/ -CLASS_DECLARATION( idTarget, CTarget_ChangeTarget ) - EVENT( EV_Activate, CTarget_ChangeTarget::Event_Activate ) -END_CLASS - -void CTarget_ChangeTarget::Event_Activate(idEntity *activator) -{ - // Get the targetted entities - for (int i = 0; i < targets.Num(); i++) - { - idEntity* ent = targets[i].GetEntity(); - - if (ent == NULL) continue; - - // Let's check if we should remove a target - idEntity* removeEnt = gameLocal.FindEntity(spawnArgs.GetString("remove")); - - if (removeEnt != NULL) - { - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeTarget: Removing target %s from %s\r", removeEnt->name.c_str(), ent->name.c_str()); - ent->RemoveTarget(removeEnt); - } - - // Let's check if we should add a target (happens after the removal) - idEntity* addEnt = gameLocal.FindEntity(spawnArgs.GetString("add")); - - if (addEnt != NULL) - { - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Target_ChangeTarget: Adding target %s to %s\r", addEnt->name.c_str(), ent->name.c_str()); - ent->AddTarget(addEnt); - } - } -} - -CLASS_DECLARATION( idTarget, CTarget_InterMissionTrigger ) - EVENT( EV_Activate, CTarget_InterMissionTrigger::Event_Activate ) -END_CLASS - -void CTarget_InterMissionTrigger::Event_Activate(idEntity* activator) -{ - // greebo: Get the target mission number, defaults to the next mission number (which is current+2 to get the 1-based index, see comment below) - // We don't care if this is the last mission. - int missionNum = spawnArgs.GetInt("mission"); - - if (missionNum == 0) - { - missionNum = gameLocal.m_MissionManager->GetCurrentMissionIndex() + 2; - } - - // The mission number is 0-based but the mapper can use 1-based indices for convenience => subtract 1 after reading the spawnarg. - missionNum--; - - if (missionNum < 0) - { - return; - } - - // Get the name of the activating entity, can be overridden by the spawnarg, otherwise defaults to the activator passed in - idStr activatorName = spawnArgs.GetString("activator"); - - if (activatorName.IsEmpty() && activator != NULL) - { - activatorName = activator->name; - } - - // Now register an inter-mission trigger for each target spawnarg we find on this entity - for (const idKeyValue* kv = spawnArgs.MatchPrefix("target"); kv != NULL; kv = spawnArgs.MatchPrefix("target", kv)) - { - const idStr& targetName = kv->GetValue(); - - DM_LOG(LC_MISC,LT_DEBUG)LOGSTRING("Registering Inter-Mission trigger for mission %d, from %s to %s\r", missionNum, activatorName.c_str(), targetName.c_str()); - - gameLocal.AddInterMissionTrigger(missionNum, activatorName, targetName); - } -} - -/* ************************************** Target setTeam ********************************* */ - -// Tels: Can be targetted from a trigger and changes the team of all of its targets to the -// team according to the spawnarg "team". Will also cause the affected actors to re- -// evaluate their targets (so if they "see" someone, they might consider them an -// enemy, or friend now): - -CLASS_DECLARATION( idEntity, CTarget_SetTeam ) - EVENT( EV_Activate, CTarget_SetTeam::Event_Activate ) -END_CLASS - -void CTarget_SetTeam::Event_Activate(idEntity* activator) -{ - float newTeam = spawnArgs.GetFloat("team", 0); - - // for all targets - int t = targets.Num(); - for( int i = 0; i < t; i++ ) - { - idEntity *ent = targets[ i ].GetEntity(); - if ( ent ) - //if ( ent && ent->IsType(idActor::Type) ) - { - // idActor* actor = static_cast(ent); - ent->Event_SetTeam( newTeam ); - } - } -} diff --git a/game/target.h b/game/target.h deleted file mode 100644 index 4b90f3fa3..000000000 --- a/game/target.h +++ /dev/null @@ -1,642 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_TARGET_H__ -#define __GAME_TARGET_H__ - - -/* -=============================================================================== - -idTarget - -=============================================================================== -*/ - -class idTarget : public idEntity { -public: - CLASS_PROTOTYPE( idTarget ); -}; - - -/* -=============================================================================== - -idTarget_Remove - -=============================================================================== -*/ - -class idTarget_Remove : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_Remove ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_Show - -=============================================================================== -*/ - -class idTarget_Show : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_Show ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_Damage - -=============================================================================== -*/ - -class idTarget_Damage : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_Damage ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SessionCommand - -=============================================================================== -*/ - -class idTarget_SessionCommand : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SessionCommand ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_EndLevel - -=============================================================================== -*/ - -class idTarget_EndLevel : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_EndLevel ); - -private: - void Event_Activate( idEntity *activator ); - -}; - - -/* -=============================================================================== - -idTarget_WaitForButton - -=============================================================================== -*/ - -class idTarget_WaitForButton : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_WaitForButton ); - - void Think( void ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -idTarget_SetGlobalShaderTime - -=============================================================================== -*/ - -class idTarget_SetGlobalShaderTime : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetGlobalShaderTime ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SetShaderParm - -=============================================================================== -*/ - -class idTarget_SetShaderParm : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetShaderParm ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SetShaderTime - -=============================================================================== -*/ - -class idTarget_SetShaderTime : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetShaderTime ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -idTarget_FadeEntity - -=============================================================================== -*/ - -class idTarget_FadeEntity : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_FadeEntity ); - - idTarget_FadeEntity( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Think( void ); - -private: - idVec4 fadeFrom; - int fadeStart; - int fadeEnd; - - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -idTarget_LightFadeIn - -=============================================================================== -*/ - -class idTarget_LightFadeIn : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_LightFadeIn ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -idTarget_LightFadeOut - -=============================================================================== -*/ - -class idTarget_LightFadeOut : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_LightFadeOut ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -idTarget_Give - -=============================================================================== -*/ - -class idTarget_Give : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_Give ); - - void Spawn( void ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SetModel - -=============================================================================== -*/ - -class idTarget_SetModel : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetModel ); - - void Spawn( void ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SetInfluence - -=============================================================================== -*/ - -class idTarget_SetInfluence : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetInfluence ); - - idTarget_SetInfluence( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - -private: - void Event_Activate( idEntity *activator ); - void Event_RestoreInfluence(); - void Event_GatherEntities(); - void Event_Flash( float flash, int out ); - void Event_ClearFlash( float flash ); - void Think( void ); - - idList lightList; - idList guiList; - idList soundList; - idList genericList; - float flashIn; - float flashOut; - float delay; - idStr flashInSound; - idStr flashOutSound; - idEntity * switchToCamera; - idInterpolatefovSetting; - bool soundFaded; - bool restoreOnTrigger; -}; - - -/* -=============================================================================== - -idTarget_SetKeyVal - -=============================================================================== -*/ - -class idTarget_SetKeyVal : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetKeyVal ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_SetFov - -=============================================================================== -*/ - -class idTarget_SetFov : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_SetFov ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Think( void ); - -private: - idInterpolate fovSetting; - - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_CallObjectFunction - -=============================================================================== -*/ - -class idTarget_CallObjectFunction : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_CallObjectFunction ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/* -=============================================================================== - -Tels: idTarget_PostScriptEvent - -=============================================================================== -*/ - -class idTarget_PostScriptEvent : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_PostScriptEvent ); - -private: - void Event_Activate( idEntity *activator ); - void TryPostOrCall( idEntity *ent, idEntity *activator, const idEventDef *ev, const char* funcName, const bool pass_self, const bool pass_activator, const float delay); -}; - -/* -=============================================================================== - -idTarget_LockDoor - -=============================================================================== -*/ - -class idTarget_EnableLevelWeapons : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_EnableLevelWeapons ); - -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_Tip - -=============================================================================== -*/ - -class idTarget_Tip : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_Tip ); - - idTarget_Tip( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - idVec3 playerPos; - - void Event_Activate( idEntity *activator ); - void Event_TipOff( void ); - void Event_GetPlayerPos( void ); -}; - -/* -=============================================================================== - -idTarget_RemoveWeapons - -=============================================================================== -*/ -class idTarget_RemoveWeapons : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_RemoveWeapons ); -private: - void Event_Activate( idEntity *activator ); -}; - - -/* -=============================================================================== - -idTarget_FadeSoundClass - -=============================================================================== -*/ -class idTarget_FadeSoundClass : public idTarget { -public: - CLASS_PROTOTYPE( idTarget_FadeSoundClass ); -private: - void Event_Activate( idEntity *activator ); - void Event_RestoreVolume(); -}; - -/** -* CTarget_AddObjectives -* Helper entity for the objectives system. When triggered, adds the -* objectives on it into the objectives system. -* -* It sets the spawnargs "obj_num_offset" on itself for the numerical offset -* of the first objective it added, used for later addressing that objective. -**/ -class CTarget_AddObjectives : public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_AddObjectives ); -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -}; - -/** - * greebo: Target for altering the state of certain objectives. - */ -class CTarget_SetObjectiveState : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_SetObjectiveState ); -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -}; - -/** -* Target for hiding or showing certain objectives. -**/ -class CTarget_SetObjectiveVisibility : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_SetObjectiveVisibility ); -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -}; - -/** -* Target for setting the state of an objective component -**/ -class CTarget_SetObjectiveComponentState : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_SetObjectiveComponentState ); -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -}; - -/** - * greebo: Target for triggerig conversations. - */ -class CTarget_StartConversation : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_StartConversation ); -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -}; - -/** -* CTarget_SetFrobable -* Sets all items inside frobable or not when triggered -**/ -class CTarget_SetFrobable : public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_SetFrobable ); - - CTarget_SetFrobable( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - void Event_Activate( idEntity *activator ); - virtual void Spawn( void ); -private: - /** - * Current frob state, whether stuff inside has been set frobable or not - **/ - bool m_bCurFrobState; - - /** - * List of the names of entities previously set unfrobable - * This list is maintained to avoid accidentally setting anything frobable - * that was not frobable before it went in the brush - * Only ents that get added to this list will become frobable. - **/ - idStrList m_EntsSetUnfrobable; -}; - -/** - * greebo: This target calls a specific script function (with no arguments). - */ -class CTarget_CallScriptFunction : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_CallScriptFunction ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/** - * greebo: This target locks or unlocks a specific frobmover. - */ -class CTarget_ChangeLockState : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_ChangeLockState ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/** - * greebo: This target changes the targets of existing entities. - */ -class CTarget_ChangeTarget : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_ChangeTarget ); - -private: - void Event_Activate( idEntity *activator ); -}; - -/** - * greebo: This target eats incoming triggers and releases them when the next map loads. - */ -class CTarget_InterMissionTrigger : - public idTarget -{ -public: - CLASS_PROTOTYPE( CTarget_InterMissionTrigger ); - -private: - void Event_Activate(idEntity* activator); -}; - -/* -=============================================================================== - -Tels: set the team of its targets. - -=============================================================================== -*/ - -class CTarget_SetTeam : public idTarget { -public: - CLASS_PROTOTYPE( CTarget_SetTeam ); - -private: - void Event_Activate( idEntity *activator ); -}; - -#endif /* !__GAME_TARGET_H__ */ diff --git a/game/trigger.cpp b/game/trigger.cpp deleted file mode 100644 index 76c7cc59c..000000000 --- a/game/trigger.cpp +++ /dev/null @@ -1,1199 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/StimResponse/StimResponseCollection.h" - -/* -=============================================================================== - - idTrigger - -=============================================================================== -*/ - -const idEventDef EV_Enable( "enable", NULL ); -const idEventDef EV_Disable( "disable", NULL ); - -CLASS_DECLARATION( idEntity, idTrigger ) - EVENT( EV_Enable, idTrigger::Event_Enable ) - EVENT( EV_Disable, idTrigger::Event_Disable ) -END_CLASS - -/* -================ -idTrigger::DrawDebugInfo -================ -*/ -void idTrigger::DrawDebugInfo( void ) { - idMat3 axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); - idVec3 up = axis[ 2 ] * 5.0f; - idBounds viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); - idBounds viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); - idBounds box( idVec3( -4.0f, -4.0f, -4.0f ), idVec3( 4.0f, 4.0f, 4.0f ) ); - idEntity *ent; - idEntity *target; - int i; - bool show; - const function_t *func; - - viewTextBounds.ExpandSelf( 128.0f ); - viewBounds.ExpandSelf( 512.0f ); - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( ent->GetPhysics()->GetContents() & ( CONTENTS_TRIGGER | CONTENTS_FLASHLIGHT_TRIGGER ) ) { - show = viewBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ); - if ( !show ) { - for( i = 0; i < ent->targets.Num(); i++ ) { - target = ent->targets[ i ].GetEntity(); - if ( target && viewBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) { - show = true; - break; - } - } - } - - if ( !show ) { - continue; - } - - gameRenderWorld->DebugBounds( colorOrange, ent->GetPhysics()->GetAbsBounds() ); - if ( viewTextBounds.IntersectsBounds( ent->GetPhysics()->GetAbsBounds() ) ) { - gameRenderWorld->DrawText( ent->name.c_str(), ent->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 ); - gameRenderWorld->DrawText( ent->GetEntityDefName(), ent->GetPhysics()->GetAbsBounds().GetCenter() + up, 0.1f, colorWhite, axis, 1 ); - if ( ent->IsType( idTrigger::Type ) ) { - func = static_cast( ent )->GetScriptFunction(); - } else { - func = NULL; - } - - if ( func ) { - gameRenderWorld->DrawText( va( "call script '%s'", func->Name() ), ent->GetPhysics()->GetAbsBounds().GetCenter() - up, 0.1f, colorWhite, axis, 1 ); - } - } - - for( i = 0; i < ent->targets.Num(); i++ ) { - target = ent->targets[ i ].GetEntity(); - if ( target ) { - gameRenderWorld->DebugArrow( colorYellow, ent->GetPhysics()->GetAbsBounds().GetCenter(), target->GetPhysics()->GetOrigin(), 10, 0 ); - gameRenderWorld->DebugBounds( colorGreen, box, target->GetPhysics()->GetOrigin() ); - if ( viewTextBounds.IntersectsBounds( target->GetPhysics()->GetAbsBounds() ) ) { - gameRenderWorld->DrawText( target->name.c_str(), target->GetPhysics()->GetAbsBounds().GetCenter(), 0.1f, colorWhite, axis, 1 ); - } - } - } - } - } -} - -/* -================ -idTrigger::Enable -================ -*/ -void idTrigger::Enable( void ) -{ - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - GetPhysics()->EnableClip(); -} - -/* -================ -idTrigger::Disable -================ -*/ -void idTrigger::Disable( void ) { - // we may be relinked if we're bound to another object, so clear the contents as well - GetPhysics()->SetContents( 0 ); - GetPhysics()->DisableClip(); -} - -/* -================ -idTrigger::CallScript -================ -*/ -void idTrigger::CallScript( void ) const { - idThread *thread; - - if ( scriptFunction ) { - thread = new idThread( scriptFunction ); - thread->DelayedStart( 0 ); - } -} - -/* -================ -idTrigger::GetScriptFunction -================ -*/ -const function_t *idTrigger::GetScriptFunction( void ) const { - return scriptFunction; -} - -/* -================ -idTrigger::Save -================ -*/ -void idTrigger::Save( idSaveGame *savefile ) const { - if ( scriptFunction ) { - savefile->WriteString( scriptFunction->Name() ); - } else { - savefile->WriteString( "" ); - } -} - -/* -================ -idTrigger::Restore -================ -*/ -void idTrigger::Restore( idRestoreGame *savefile ) { - idStr funcname; - savefile->ReadString( funcname ); - if ( funcname.Length() ) { - scriptFunction = gameLocal.program.FindFunction( funcname ); - if ( scriptFunction == NULL ) { - gameLocal.Warning( "idTrigger_Multi '%s' at (%s) calls unknown function '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), funcname.c_str() ); - } - } else { - scriptFunction = NULL; - } -} - -/* -================ -idTrigger::Event_Enable -================ -*/ -void idTrigger::Event_Enable( void ) { - Enable(); -} - -/* -================ -idTrigger::Event_Disable -================ -*/ -void idTrigger::Event_Disable( void ) { - Disable(); -} - -/* -================ -idTrigger::idTrigger -================ -*/ -idTrigger::idTrigger() { - scriptFunction = NULL; -} - -/* -================ -idTrigger::Spawn -================ -*/ -void idTrigger::Spawn( void ) -{ - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); - - idStr funcname = spawnArgs.GetString( "call", "" ); - if ( funcname.Length() ) { - scriptFunction = gameLocal.program.FindFunction( funcname ); - if ( scriptFunction == NULL ) { - gameLocal.Warning( "trigger '%s' at (%s) calls unknown function '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), funcname.c_str() ); - } - } else { - scriptFunction = NULL; - } -} - - -/* -=============================================================================== - - idTrigger_Multi - -=============================================================================== -*/ - -const idEventDef EV_TriggerAction( "", "e" ); - -CLASS_DECLARATION( idTrigger, idTrigger_Multi ) - EVENT( EV_Touch, idTrigger_Multi::Event_Touch ) - EVENT( EV_Activate, idTrigger_Multi::Event_Trigger ) - EVENT( EV_TriggerAction, idTrigger_Multi::Event_TriggerAction ) -END_CLASS - - -/* -================ -idTrigger_Multi::idTrigger_Multi -================ -*/ -idTrigger_Multi::idTrigger_Multi( void ) { - wait = 0.0f; - random = 0.0f; - delay = 0.0f; - random_delay = 0.0f; - nextTriggerTime = 0; - removeItem = 0; - touchClient = false; - touchOther = false; - triggerFirst = false; - triggerWithSelf = false; -} - -/* -================ -idTrigger_Multi::Save -================ -*/ -void idTrigger_Multi::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( wait ); - savefile->WriteFloat( random ); - savefile->WriteFloat( delay ); - savefile->WriteFloat( random_delay ); - savefile->WriteInt( nextTriggerTime ); - savefile->WriteString( requires ); - savefile->WriteInt( removeItem ); - savefile->WriteBool( touchClient ); - savefile->WriteBool( touchOther ); - savefile->WriteBool( triggerFirst ); - savefile->WriteBool( triggerWithSelf ); -} - -/* -================ -idTrigger_Multi::Restore -================ -*/ -void idTrigger_Multi::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( wait ); - savefile->ReadFloat( random ); - savefile->ReadFloat( delay ); - savefile->ReadFloat( random_delay ); - savefile->ReadInt( nextTriggerTime ); - savefile->ReadString( requires ); - savefile->ReadInt( removeItem ); - savefile->ReadBool( touchClient ); - savefile->ReadBool( touchOther ); - savefile->ReadBool( triggerFirst ); - savefile->ReadBool( triggerWithSelf ); -} - -/* -================ -idTrigger_Multi::Spawn - -"wait" : Seconds between triggerings, 0.5 default, -1 = one time only. -"call" : Script function to call when triggered -"random" wait variance, default is 0 -Variable sized repeatable trigger. Must be targeted at one or more entities. -so, the basic time between firing is a random time between -(wait - random) and (wait + random) -================ -*/ -void idTrigger_Multi::Spawn( void ) { - spawnArgs.GetFloat( "wait", "0.5", wait ); - spawnArgs.GetFloat( "random", "0", random ); - spawnArgs.GetFloat( "delay", "0", delay ); - spawnArgs.GetFloat( "random_delay", "0", random_delay ); - - if ( random && ( random >= wait ) && ( wait >= 0 ) ) { - random = wait - 1; - gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) { - random_delay = delay - 1; - gameLocal.Warning( "idTrigger_Multi '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - spawnArgs.GetString( "requires", "", requires ); - spawnArgs.GetInt( "removeItem", "0", removeItem ); - spawnArgs.GetBool( "triggerFirst", "0", triggerFirst ); - spawnArgs.GetBool( "triggerWithSelf", "0", triggerWithSelf ); - - if ( spawnArgs.GetBool( "anyTouch" ) ) { - touchClient = true; - touchOther = true; - } else if ( spawnArgs.GetBool( "noTouch" ) ) { - touchClient = false; - touchOther = false; - } else if ( spawnArgs.GetBool( "noClient" ) ) { - touchClient = false; - touchOther = true; - } else { - touchClient = true; - touchOther = false; - } - - nextTriggerTime = 0; - - if ( spawnArgs.GetBool( "flashlight_trigger" ) ) { - GetPhysics()->SetContents( CONTENTS_FLASHLIGHT_TRIGGER ); - } else { - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - } - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); -} - -/* -================ -idTrigger_Multi::CheckFacing -================ -*/ -bool idTrigger_Multi::CheckFacing( idEntity *activator ) { - if ( spawnArgs.GetBool( "facing" ) ) { - if ( !activator->IsType( idPlayer::Type ) ) { - return true; - } - idPlayer *player = static_cast< idPlayer* >( activator ); - float dot = player->viewAngles.ToForward() * GetPhysics()->GetAxis()[0]; - float angle = RAD2DEG( idMath::ACos( dot ) ); - if ( angle > spawnArgs.GetFloat( "angleLimit", "30" ) ) { - return false; - } - } - return true; -} - - -/* -================ -idTrigger_Multi::TriggerAction -================ -*/ -void idTrigger_Multi::TriggerAction( idEntity *activator ) { - ActivateTargets( triggerWithSelf ? this : activator ); - CallScript(); - - if ( wait >= 0 ) { - nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); - } else { - // we can't just remove (this) here, because this is a touch function - // called while looping through area links... - nextTriggerTime = gameLocal.time + 1; - PostEventMS( &EV_Remove, 0 ); - } -} - -/* -================ -idTrigger_Multi::Event_TriggerAction -================ -*/ -void idTrigger_Multi::Event_TriggerAction( idEntity *activator ) { - TriggerAction( activator ); -} - -/* -================ -idTrigger_Multi::Event_Trigger - -the trigger was just activated -activated should be the entity that originated the activation sequence (ie. the original target) -activator should be set to the activator so it can be held through a delay -so wait for the delay time before firing -================ -*/ -void idTrigger_Multi::Event_Trigger( idEntity *activator ) { - if ( nextTriggerTime > gameLocal.time ) { - // can't retrigger until the wait is over - return; - } - - // see if this trigger requires an item - if ( !gameLocal.RequirementMet( activator, requires, removeItem ) ) { - return; - } - - if ( !CheckFacing( activator ) ) { - return; - } - - if ( triggerFirst ) { - triggerFirst = false; - return; - } - - // don't allow it to trigger twice in a single frame - nextTriggerTime = gameLocal.time + 1; - - if ( delay > 0 ) { - // don't allow it to trigger again until our delay has passed - nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); - PostEventSec( &EV_TriggerAction, delay, activator ); - } else { - TriggerAction( activator ); - } -} - -/* -================ -idTrigger_Multi::Event_Touch -================ -*/ -void idTrigger_Multi::Event_Touch( idEntity *other, trace_t *trace ) { - if( triggerFirst ) { - return; - } - - bool player = other->IsType( idPlayer::Type ); - if ( player ) { - if ( !touchClient ) { - return; - } - if ( static_cast< idPlayer * >( other )->spectating ) { - return; - } - } else if ( !touchOther ) { - return; - } - - if ( nextTriggerTime > gameLocal.time ) { - // can't retrigger until the wait is over - return; - } - - // see if this trigger requires an item - if ( !gameLocal.RequirementMet( other, requires, removeItem ) ) { - return; - } - - if ( !CheckFacing( other ) ) { - return; - } - - if ( spawnArgs.GetBool( "toggleTriggerFirst" ) ) { - triggerFirst = true; - } - - nextTriggerTime = gameLocal.time + 1; - if ( delay > 0 ) { - // don't allow it to trigger again until our delay has passed - nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); - PostEventSec( &EV_TriggerAction, delay, other ); - } else { - TriggerAction( other ); - } -} - -/* -=============================================================================== - - idTrigger_EntityName - -=============================================================================== -*/ - -CLASS_DECLARATION( idTrigger, idTrigger_EntityName ) - EVENT( EV_Touch, idTrigger_EntityName::Event_Touch ) - EVENT( EV_Activate, idTrigger_EntityName::Event_Trigger ) - EVENT( EV_TriggerAction, idTrigger_EntityName::Event_TriggerAction ) -END_CLASS - -/* -================ -idTrigger_EntityName::idTrigger_EntityName -================ -*/ -idTrigger_EntityName::idTrigger_EntityName( void ) { - wait = 0.0f; - random = 0.0f; - delay = 0.0f; - random_delay = 0.0f; - nextTriggerTime = 0; - triggerFirst = false; -} - -/* -================ -idTrigger_EntityName::Save -================ -*/ -void idTrigger_EntityName::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( wait ); - savefile->WriteFloat( random ); - savefile->WriteFloat( delay ); - savefile->WriteFloat( random_delay ); - savefile->WriteInt( nextTriggerTime ); - savefile->WriteBool( triggerFirst ); - savefile->WriteString( entityName ); -} - -/* -================ -idTrigger_EntityName::Restore -================ -*/ -void idTrigger_EntityName::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( wait ); - savefile->ReadFloat( random ); - savefile->ReadFloat( delay ); - savefile->ReadFloat( random_delay ); - savefile->ReadInt( nextTriggerTime ); - savefile->ReadBool( triggerFirst ); - savefile->ReadString( entityName ); -} - -/* -================ -idTrigger_EntityName::Spawn -================ -*/ -void idTrigger_EntityName::Spawn( void ) -{ - spawnArgs.GetFloat( "wait", "0.5", wait ); - spawnArgs.GetFloat( "random", "0", random ); - spawnArgs.GetFloat( "delay", "0", delay ); - spawnArgs.GetFloat( "random_delay", "0", random_delay ); - - if ( random && ( random >= wait ) && ( wait >= 0 ) ) { - random = wait - 1; - gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - if ( random_delay && ( random_delay >= delay ) && ( delay >= 0 ) ) { - random_delay = delay - 1; - gameLocal.Warning( "idTrigger_EntityName '%s' at (%s) has random_delay >= delay", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - spawnArgs.GetBool( "triggerFirst", "0", triggerFirst ); - - entityName = spawnArgs.GetString( "entityname" ); - if ( !entityName.Length() ) { - gameLocal.Error( "idTrigger_EntityName '%s' at (%s) doesn't have 'entityname' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - nextTriggerTime = 0; - - if ( !spawnArgs.GetBool( "noTouch" ) ) - { - GetPhysics()->SetContents( CONTENTS_TRIGGER ); - } - // SR CONTENTS_RESPONSE FIX - if( m_StimResponseColl->HasResponse() ) - GetPhysics()->SetContents( GetPhysics()->GetContents() | CONTENTS_RESPONSE ); -} - -/* -================ -idTrigger_EntityName::TriggerAction -================ -*/ -void idTrigger_EntityName::TriggerAction( idEntity *activator ) { - ActivateTargets( activator ); - CallScript(); - - if ( wait >= 0 ) { - nextTriggerTime = gameLocal.time + SEC2MS( wait + random * gameLocal.random.CRandomFloat() ); - } else { - // we can't just remove (this) here, because this is a touch function - // called while looping through area links... - nextTriggerTime = gameLocal.time + 1; - PostEventMS( &EV_Remove, 0 ); - } -} - -/* -================ -idTrigger_EntityName::Event_TriggerAction -================ -*/ -void idTrigger_EntityName::Event_TriggerAction( idEntity *activator ) { - TriggerAction( activator ); -} - -/* -================ -idTrigger_EntityName::Event_Trigger - -the trigger was just activated -activated should be the entity that originated the activation sequence (ie. the original target) -activator should be set to the activator so it can be held through a delay -so wait for the delay time before firing -================ -*/ -void idTrigger_EntityName::Event_Trigger( idEntity *activator ) { - if ( nextTriggerTime > gameLocal.time ) { - // can't retrigger until the wait is over - return; - } - - if ( !activator || ( activator->name != entityName ) ) { - return; - } - - if ( triggerFirst ) { - triggerFirst = false; - return; - } - - // don't allow it to trigger twice in a single frame - nextTriggerTime = gameLocal.time + 1; - - if ( delay > 0 ) { - // don't allow it to trigger again until our delay has passed - nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); - PostEventSec( &EV_TriggerAction, delay, activator ); - } else { - TriggerAction( activator ); - } -} - -/* -================ -idTrigger_EntityName::Event_Touch -================ -*/ -void idTrigger_EntityName::Event_Touch( idEntity *other, trace_t *trace ) { - if( triggerFirst ) { - return; - } - - if ( nextTriggerTime > gameLocal.time ) { - // can't retrigger until the wait is over - return; - } - - if ( !other || ( other->name != entityName ) ) { - return; - } - - nextTriggerTime = gameLocal.time + 1; - if ( delay > 0 ) { - // don't allow it to trigger again until our delay has passed - nextTriggerTime += SEC2MS( delay + random_delay * gameLocal.random.CRandomFloat() ); - PostEventSec( &EV_TriggerAction, delay, other ); - } else { - TriggerAction( other ); - } -} - -/* -=============================================================================== - - idTrigger_Timer - -=============================================================================== -*/ - -const idEventDef EV_Timer( "", NULL ); - -CLASS_DECLARATION( idTrigger, idTrigger_Timer ) - EVENT( EV_Timer, idTrigger_Timer::Event_Timer ) - EVENT( EV_Activate, idTrigger_Timer::Event_Use ) -END_CLASS - -/* -================ -idTrigger_Timer::idTrigger_Timer -================ -*/ -idTrigger_Timer::idTrigger_Timer( void ) { - random = 0.0f; - wait = 0.0f; - on = false; - delay = 0.0f; -} - -/* -================ -idTrigger_Timer::Save -================ -*/ -void idTrigger_Timer::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( random ); - savefile->WriteFloat( wait ); - savefile->WriteBool( on ); - savefile->WriteFloat( delay ); - savefile->WriteString( onName ); - savefile->WriteString( offName ); -} - -/* -================ -idTrigger_Timer::Restore -================ -*/ -void idTrigger_Timer::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( random ); - savefile->ReadFloat( wait ); - savefile->ReadBool( on ); - savefile->ReadFloat( delay ); - savefile->ReadString( onName ); - savefile->ReadString( offName ); -} - -/* -================ -idTrigger_Timer::Spawn - -Repeatedly fires its targets. -Can be turned on or off by using. -================ -*/ -void idTrigger_Timer::Spawn( void ) { - spawnArgs.GetFloat( "random", "1", random ); - spawnArgs.GetFloat( "wait", "1", wait ); - spawnArgs.GetBool( "start_on", "0", on ); - spawnArgs.GetFloat( "delay", "0", delay ); - onName = spawnArgs.GetString( "onName" ); - offName = spawnArgs.GetString( "offName" ); - - if ( random >= wait && wait >= 0 ) { - random = wait - 0.001; - gameLocal.Warning( "idTrigger_Timer '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) ); - } - - if ( on ) { - PostEventSec( &EV_Timer, delay ); - } -} - -/* -================ -idTrigger_Timer::Enable -================ -*/ -void idTrigger_Timer::Enable( void ) { - // if off, turn it on - if ( !on ) { - on = true; - PostEventSec( &EV_Timer, delay ); - } -} - -/* -================ -idTrigger_Timer::Disable -================ -*/ -void idTrigger_Timer::Disable( void ) { - // if on, turn it off - if ( on ) { - on = false; - CancelEvents( &EV_Timer ); - } -} - -/* -================ -idTrigger_Timer::Event_Timer -================ -*/ -void idTrigger_Timer::Event_Timer( void ) { - ActivateTargets( this ); - - // set time before next firing - if ( wait >= 0.0f ) { - PostEventSec( &EV_Timer, wait + gameLocal.random.CRandomFloat() * random ); - } -} - -/* -================ -idTrigger_Timer::Event_Use -================ -*/ -void idTrigger_Timer::Event_Use( idEntity *activator ) { - // if on, turn it off - if ( on ) { - if ( offName.Length() && offName.Icmp( activator->GetName() ) ) { - return; - } - on = false; - CancelEvents( &EV_Timer ); - } else { - // turn it on - if ( onName.Length() && onName.Icmp( activator->GetName() ) ) { - return; - } - on = true; - PostEventSec( &EV_Timer, delay ); - } -} - -/* -=============================================================================== - - idTrigger_Count - -=============================================================================== -*/ - -CLASS_DECLARATION( idTrigger, idTrigger_Count ) - EVENT( EV_Activate, idTrigger_Count::Event_Trigger ) - EVENT( EV_TriggerAction, idTrigger_Count::Event_TriggerAction ) -END_CLASS - -/* -================ -idTrigger_Count::idTrigger_Count -================ -*/ -idTrigger_Count::idTrigger_Count( void ) { - goal = 0; - count = 0; - delay = 0.0f; -} - -/* -================ -idTrigger_Count::Save -================ -*/ -void idTrigger_Count::Save( idSaveGame *savefile ) const { - savefile->WriteInt( goal ); - savefile->WriteInt( count ); - savefile->WriteFloat( delay ); -} - -/* -================ -idTrigger_Count::Restore -================ -*/ -void idTrigger_Count::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( goal ); - savefile->ReadInt( count ); - savefile->ReadFloat( delay ); -} - -/* -================ -idTrigger_Count::Spawn -================ -*/ -void idTrigger_Count::Spawn( void ) { - spawnArgs.GetInt( "count", "1", goal ); - spawnArgs.GetFloat( "delay", "0", delay ); - count = 0; -} - -/* -================ -idTrigger_Count::Event_Trigger -================ -*/ -void idTrigger_Count::Event_Trigger( idEntity *activator ) { - // goal of -1 means trigger has been exhausted - if (goal >= 0) { - count++; - if ( count >= goal ) { - if (spawnArgs.GetBool("repeat")) { - count = 0; - } else { - goal = -1; - } - PostEventSec( &EV_TriggerAction, delay, activator ); - } - } -} - -/* -================ -idTrigger_Count::Event_TriggerAction -================ -*/ -void idTrigger_Count::Event_TriggerAction( idEntity *activator ) { - ActivateTargets( activator ); - CallScript(); - if ( goal == -1 ) { - PostEventMS( &EV_Remove, 0 ); - } -} - -/* -=============================================================================== - - idTrigger_Hurt - -=============================================================================== -*/ - -CLASS_DECLARATION( idTrigger, idTrigger_Hurt ) - EVENT( EV_Touch, idTrigger_Hurt::Event_Touch ) - EVENT( EV_Activate, idTrigger_Hurt::Event_Toggle ) -END_CLASS - - -/* -================ -idTrigger_Hurt::idTrigger_Hurt -================ -*/ -idTrigger_Hurt::idTrigger_Hurt( void ) { - on = false; - delay = 0.0f; - nextTime = 0; -} - -/* -================ -idTrigger_Hurt::Save -================ -*/ -void idTrigger_Hurt::Save( idSaveGame *savefile ) const { - savefile->WriteBool( on ); - savefile->WriteFloat( delay ); - savefile->WriteInt( nextTime ); -} - -/* -================ -idTrigger_Hurt::Restore -================ -*/ -void idTrigger_Hurt::Restore( idRestoreGame *savefile ) { - savefile->ReadBool( on ); - savefile->ReadFloat( delay ); - savefile->ReadInt( nextTime ); -} - -/* -================ -idTrigger_Hurt::Spawn - - Damages activator - Can be turned on or off by using. -================ -*/ -void idTrigger_Hurt::Spawn( void ) { - spawnArgs.GetBool( "on", "1", on ); - spawnArgs.GetFloat( "delay", "1.0", delay ); - nextTime = gameLocal.time; - Enable(); -} - -/* -================ -idTrigger_Hurt::Event_Touch -================ -*/ -void idTrigger_Hurt::Event_Touch( idEntity *other, trace_t *trace ) { - const char *damage; - - if ( on && other && gameLocal.time >= nextTime ) { - damage = spawnArgs.GetString( "def_damage", "damage_painTrigger" ); - other->Damage( NULL, NULL, vec3_origin, damage, 1.0f, INVALID_JOINT ); - - ActivateTargets( other ); - CallScript(); - - nextTime = gameLocal.time + SEC2MS( delay ); - } -} - -/* -================ -idTrigger_Hurt::Event_Toggle -================ -*/ -void idTrigger_Hurt::Event_Toggle( idEntity *activator ) { - on = !on; -} - - -/* -=============================================================================== - - idTrigger_Fade - -=============================================================================== -*/ - -CLASS_DECLARATION( idTrigger, idTrigger_Fade ) - EVENT( EV_Activate, idTrigger_Fade::Event_Trigger ) -END_CLASS - -/* -================ -idTrigger_Fade::Event_Trigger -================ -*/ -void idTrigger_Fade::Event_Trigger( idEntity *activator ) { - idVec4 fadeColor; - int fadeTime; - idPlayer *player; - - player = gameLocal.GetLocalPlayer(); - if ( player ) { - fadeColor = spawnArgs.GetVec4( "fadeColor", "0, 0, 0, 1" ); - fadeTime = SEC2MS( spawnArgs.GetFloat( "fadeTime", "0.5" ) ); - player->playerView.Fade( fadeColor, fadeTime ); - PostEventMS( &EV_ActivateTargets, fadeTime, activator ); - } -} - -/* -=============================================================================== - - idTrigger_Touch - -=============================================================================== -*/ - -CLASS_DECLARATION( idTrigger, idTrigger_Touch ) - EVENT( EV_Activate, idTrigger_Touch::Event_Trigger ) -END_CLASS - - -/* -================ -idTrigger_Touch::idTrigger_Touch -================ -*/ -idTrigger_Touch::idTrigger_Touch( void ) { - clipModel = NULL; -} - -/* -================ -idTrigger_Touch::Spawn -================ -*/ -void idTrigger_Touch::Spawn( void ) { - // get the clip model - clipModel = new idClipModel( GetPhysics()->GetClipModel() ); - - // remove the collision model from the physics object - GetPhysics()->SetClipModel( NULL, 1.0f ); - - if ( spawnArgs.GetBool( "start_on" ) ) { - BecomeActive( TH_THINK ); - } -} - -/* -================ -idTrigger_Touch::Save -================ -*/ -void idTrigger_Touch::Save( idSaveGame *savefile ) { - savefile->WriteClipModel( clipModel ); -} - -/* -================ -idTrigger_Touch::Restore -================ -*/ -void idTrigger_Touch::Restore( idRestoreGame *savefile ) { - savefile->ReadClipModel( clipModel ); -} - -/* -================ -idTrigger_Touch::TouchEntities -================ -*/ -void idTrigger_Touch::TouchEntities( void ) { - int numClipModels, i; - idBounds bounds; - idClipModel *cm, *clipModelList[ MAX_GENTITIES ]; - - if ( clipModel == NULL) - { - return; - } - - bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() ); - numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); - - for ( i = 0; i < numClipModels; i++ ) { - cm = clipModelList[ i ]; - - if ( !cm->IsTraceModel() ) { - continue; - } - - idEntity *entity = cm->GetEntity(); - - if ( !entity ) { - continue; - } - - if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1, - clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) { - continue; - } - - ActivateTargets( entity ); - - if (scriptFunction != NULL) - { - idThread *thread = new idThread(); - thread->CallFunction( entity, scriptFunction, false ); - thread->DelayedStart( 0 ); - } - } -} - -/* -================ -idTrigger_Touch::Think -================ -*/ -void idTrigger_Touch::Think( void ) { - if ( thinkFlags & TH_THINK ) { - TouchEntities(); - } - idEntity::Think(); -} - -/* -================ -idTrigger_Touch::Event_Trigger -================ -*/ -void idTrigger_Touch::Event_Trigger( idEntity *activator ) { - if ( thinkFlags & TH_THINK ) { - BecomeInactive( TH_THINK ); - } else { - BecomeActive( TH_THINK ); - } -} - -/* -================ -idTrigger_Touch::Enable -================ -*/ -void idTrigger_Touch::Enable( void ) { - BecomeActive( TH_THINK ); -} - -/* -================ -idTrigger_Touch::Disable -================ -*/ -void idTrigger_Touch::Disable( void ) { - BecomeInactive( TH_THINK ); -} diff --git a/game/trigger.h b/game/trigger.h deleted file mode 100644 index ccb1b2f1d..000000000 --- a/game/trigger.h +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_TRIGGER_H__ -#define __GAME_TRIGGER_H__ - -extern const idEventDef EV_Enable; -extern const idEventDef EV_Disable; - -/* -=============================================================================== - - Trigger base. - -=============================================================================== -*/ - -class idTrigger : public idEntity { -public: - CLASS_PROTOTYPE( idTrigger ); - - static void DrawDebugInfo( void ); - - idTrigger(); - void Spawn( void ); - - const function_t * GetScriptFunction( void ) const; - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - virtual void Enable( void ); - virtual void Disable( void ); - -protected: - void CallScript( void ) const; - - void Event_Enable( void ); - void Event_Disable( void ); - - const function_t * scriptFunction; -}; - - -/* -=============================================================================== - - Trigger which can be activated multiple times. - -=============================================================================== -*/ - -class idTrigger_Multi : public idTrigger { -public: - CLASS_PROTOTYPE( idTrigger_Multi ); - - idTrigger_Multi( void ); - - void Spawn( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - -private: - float wait; - float random; - float delay; - float random_delay; - int nextTriggerTime; - idStr requires; - int removeItem; - bool touchClient; - bool touchOther; - bool triggerFirst; - bool triggerWithSelf; - - bool CheckFacing( idEntity *activator ); - void TriggerAction( idEntity *activator ); - void Event_TriggerAction( idEntity *activator ); - void Event_Trigger( idEntity *activator ); - void Event_Touch( idEntity *other, trace_t *trace ); -}; - - -/* -=============================================================================== - - Trigger which can only be activated by an entity with a specific name. - -=============================================================================== -*/ - -class idTrigger_EntityName : public idTrigger { -public: - CLASS_PROTOTYPE( idTrigger_EntityName ); - - idTrigger_EntityName( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - -private: - float wait; - float random; - float delay; - float random_delay; - int nextTriggerTime; - bool triggerFirst; - idStr entityName; - - void TriggerAction( idEntity *activator ); - void Event_TriggerAction( idEntity *activator ); - void Event_Trigger( idEntity *activator ); - void Event_Touch( idEntity *other, trace_t *trace ); -}; - -/* -=============================================================================== - - Trigger which repeatedly fires targets. - -=============================================================================== -*/ - -class idTrigger_Timer : public idTrigger { -public: - CLASS_PROTOTYPE( idTrigger_Timer ); - - idTrigger_Timer( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - - virtual void Enable( void ); - virtual void Disable( void ); - -private: - float random; - float wait; - bool on; - float delay; - idStr onName; - idStr offName; - - void Event_Timer( void ); - void Event_Use( idEntity *activator ); -}; - - -/* -=============================================================================== - - Trigger which fires targets after being activated a specific number of times. - -=============================================================================== -*/ - -class idTrigger_Count : public idTrigger { -public: - CLASS_PROTOTYPE( idTrigger_Count ); - - idTrigger_Count( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - -private: - int goal; - int count; - float delay; - - void Event_Trigger( idEntity *activator ); - void Event_TriggerAction( idEntity *activator ); -}; - - -/* -=============================================================================== - - Trigger which hurts touching entities. - -=============================================================================== -*/ - -class idTrigger_Hurt : public idTrigger { -public: - CLASS_PROTOTYPE( idTrigger_Hurt ); - - idTrigger_Hurt( void ); - - void Save( idSaveGame *savefile ) const; - void Restore( idRestoreGame *savefile ); - - void Spawn( void ); - -private: - bool on; - float delay; - int nextTime; - - void Event_Touch( idEntity *other, trace_t *trace ); - void Event_Toggle( idEntity *activator ); -}; - - -/* -=============================================================================== - - Trigger which fades the player view. - -=============================================================================== -*/ - -class idTrigger_Fade : public idTrigger { -public: - - CLASS_PROTOTYPE( idTrigger_Fade ); - -private: - void Event_Trigger( idEntity *activator ); -}; - - -/* -=============================================================================== - - Trigger which continuously tests whether other entities are touching it. - -=============================================================================== -*/ - -class idTrigger_Touch : public idTrigger { -public: - - CLASS_PROTOTYPE( idTrigger_Touch ); - - idTrigger_Touch( void ); - - void Spawn( void ); - virtual void Think( void ); - - void Save( idSaveGame *savefile ); - void Restore( idRestoreGame *savefile ); - - virtual void Enable( void ); - virtual void Disable( void ); - - void TouchEntities( void ); - -private: - idClipModel * clipModel; - - void Event_Trigger( idEntity *activator ); -}; - -#endif /* !__GAME_TRIGGER_H__ */ diff --git a/game/weapon.cpp b/game/weapon.cpp deleted file mode 100644 index e177c6de6..000000000 --- a/game/weapon.cpp +++ /dev/null @@ -1,3594 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" -#include "../DarkMod/DarkModGlobals.h" -#include "../DarkMod/Inventory/WeaponItem.h" - -/*********************************************************************** - - idWeapon - -***********************************************************************/ - -// -// event defs -// -const idEventDef EV_Weapon_Clear( "" ); -const idEventDef EV_Weapon_GetOwner( "getOwner", NULL, 'e' ); -const idEventDef EV_Weapon_Next( "nextWeapon" ); -const idEventDef EV_Weapon_State( "weaponState", "sd" ); -const idEventDef EV_Weapon_UseAmmo( "useAmmo", "d" ); -const idEventDef EV_Weapon_AddToClip( "addToClip", "d" ); -const idEventDef EV_Weapon_AmmoInClip( "ammoInClip", NULL, 'f' ); -const idEventDef EV_Weapon_AmmoAvailable( "ammoAvailable", NULL, 'f' ); -const idEventDef EV_Weapon_TotalAmmoCount( "totalAmmoCount", NULL, 'f' ); -const idEventDef EV_Weapon_ClipSize( "clipSize", NULL, 'f' ); -const idEventDef EV_Weapon_WeaponOutOfAmmo( "weaponOutOfAmmo" ); -const idEventDef EV_Weapon_WeaponReady( "weaponReady" ); -const idEventDef EV_Weapon_WeaponReloading( "weaponReloading" ); -const idEventDef EV_Weapon_WeaponHolstered( "weaponHolstered" ); -const idEventDef EV_Weapon_WeaponRising( "weaponRising" ); -const idEventDef EV_Weapon_WeaponLowering( "weaponLowering" ); -const idEventDef EV_Weapon_Flashlight( "flashlight", "d" ); -const idEventDef EV_Weapon_LaunchProjectiles( "launchProjectiles", "dffff" ); -const idEventDef EV_Weapon_CreateProjectile( "createProjectile", NULL, 'e' ); -const idEventDef EV_Weapon_EjectBrass( "ejectBrass" ); -const idEventDef EV_Weapon_Melee( "melee", NULL, 'd' ); -const idEventDef EV_Weapon_GetWorldModel( "getWorldModel", NULL, 'e' ); -const idEventDef EV_Weapon_AllowDrop( "allowDrop", "d" ); -const idEventDef EV_Weapon_AutoReload( "autoReload", NULL, 'f' ); -const idEventDef EV_Weapon_NetReload( "netReload" ); -const idEventDef EV_Weapon_IsInvisible( "isInvisible", NULL, 'f' ); -const idEventDef EV_Weapon_NetEndReload( "netEndReload" ); -const idEventDef EV_Weapon_ShowAttachment( "showAttachment", "sd" ); -const idEventDef EV_Weapon_ShowAttachmentInd( "showAttachmentInd", "dd" ); - -// -// class def -// -CLASS_DECLARATION( idAnimatedEntity, idWeapon ) - EVENT( EV_Weapon_Clear, idWeapon::Event_Clear ) - EVENT( EV_Weapon_GetOwner, idWeapon::Event_GetOwner ) - EVENT( EV_Weapon_State, idWeapon::Event_WeaponState ) - EVENT( EV_Weapon_WeaponReady, idWeapon::Event_WeaponReady ) - EVENT( EV_Weapon_WeaponOutOfAmmo, idWeapon::Event_WeaponOutOfAmmo ) - EVENT( EV_Weapon_WeaponReloading, idWeapon::Event_WeaponReloading ) - EVENT( EV_Weapon_WeaponHolstered, idWeapon::Event_WeaponHolstered ) - EVENT( EV_Weapon_WeaponRising, idWeapon::Event_WeaponRising ) - EVENT( EV_Weapon_WeaponLowering, idWeapon::Event_WeaponLowering ) - EVENT( EV_Weapon_UseAmmo, idWeapon::Event_UseAmmo ) - EVENT( EV_Weapon_AddToClip, idWeapon::Event_AddToClip ) - EVENT( EV_Weapon_AmmoInClip, idWeapon::Event_AmmoInClip ) - EVENT( EV_Weapon_AmmoAvailable, idWeapon::Event_AmmoAvailable ) - EVENT( EV_Weapon_TotalAmmoCount, idWeapon::Event_TotalAmmoCount ) - EVENT( EV_Weapon_ClipSize, idWeapon::Event_ClipSize ) - EVENT( AI_PlayAnim, idWeapon::Event_PlayAnim ) - EVENT( AI_PauseAnim, idWeapon::Event_PauseAnim ) - EVENT( AI_AnimIsPaused, idWeapon::Event_AnimIsPaused ) - EVENT( AI_PlayCycle, idWeapon::Event_PlayCycle ) - EVENT( AI_SetBlendFrames, idWeapon::Event_SetBlendFrames ) - EVENT( AI_GetBlendFrames, idWeapon::Event_GetBlendFrames ) - EVENT( AI_AnimDone, idWeapon::Event_AnimDone ) - EVENT( EV_Weapon_Next, idWeapon::Event_Next ) - EVENT( EV_SetSkin, idWeapon::Event_SetSkin ) - EVENT( EV_Weapon_ShowAttachment, idWeapon::ShowAttachment ) - EVENT( EV_Weapon_ShowAttachmentInd, idWeapon::ShowAttachmentInd ) - EVENT( EV_Weapon_Flashlight, idWeapon::Event_Flashlight ) - EVENT( EV_Light_GetLightParm, idWeapon::Event_GetLightParm ) - EVENT( EV_Light_SetLightParm, idWeapon::Event_SetLightParm ) - EVENT( EV_Light_SetLightParms, idWeapon::Event_SetLightParms ) - EVENT( EV_Weapon_LaunchProjectiles, idWeapon::Event_LaunchProjectiles ) - EVENT( EV_Weapon_CreateProjectile, idWeapon::Event_CreateProjectile ) - EVENT( EV_Weapon_EjectBrass, idWeapon::Event_EjectBrass ) - EVENT( EV_Weapon_Melee, idWeapon::Event_Melee ) - EVENT( EV_Weapon_GetWorldModel, idWeapon::Event_GetWorldModel ) - EVENT( EV_Weapon_AllowDrop, idWeapon::Event_AllowDrop ) - EVENT( EV_Weapon_AutoReload, idWeapon::Event_AutoReload ) - EVENT( EV_Weapon_NetReload, idWeapon::Event_NetReload ) - EVENT( EV_Weapon_IsInvisible, idWeapon::Event_IsInvisible ) - EVENT( EV_Weapon_NetEndReload, idWeapon::Event_NetEndReload ) -END_CLASS - -/*********************************************************************** - - init - -***********************************************************************/ - -/* -================ -idWeapon::idWeapon() -================ -*/ -idWeapon::idWeapon() { - owner = NULL; - worldModel = NULL; - weaponDef = NULL; - thread = NULL; - - memset( &guiLight, 0, sizeof( guiLight ) ); - memset( &muzzleFlash, 0, sizeof( muzzleFlash ) ); - memset( &worldMuzzleFlash, 0, sizeof( worldMuzzleFlash ) ); - memset( &nozzleGlow, 0, sizeof( nozzleGlow ) ); - - muzzleFlashEnd = 0; - flashColor = vec3_origin; - muzzleFlashHandle = -1; - worldMuzzleFlashHandle = -1; - guiLightHandle = -1; - nozzleGlowHandle = -1; - modelDefHandle = -1; - - berserk = 2; - brassDelay = 0; - - allowDrop = true; - - Clear(); - - fl.networkSync = true; -} - -/* -================ -idWeapon::~idWeapon() -================ -*/ -idWeapon::~idWeapon() -{ - // destroy weapon attachments - for( int i=0; iEvent_Remove(); - } - - Clear(); - delete worldModel.GetEntity(); -} - - -/* -================ -idWeapon::Spawn -================ -*/ -void idWeapon::Spawn( void ) { - if ( !gameLocal.isClient ) { - // setup the world model - worldModel = static_cast< idAnimatedEntity * >( gameLocal.SpawnEntityType( idAnimatedEntity::Type, NULL ) ); - worldModel.GetEntity()->fl.networkSync = true; - } - - thread = new idThread(); - thread->ManualDelete(); - thread->ManualControl(); -} - -/* -================ -idWeapon::SetOwner - -Only called at player spawn time, not each weapon switch -================ -*/ -void idWeapon::SetOwner( idPlayer *_owner ) { - assert( !owner ); - owner = _owner; - SetName( va( "%s_weapon", owner->name.c_str() ) ); - - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetName( va( "%s_weapon_worldmodel", owner->name.c_str() ) ); - } -} - -/* -================ -idWeapon::ShouldConstructScriptObjectAtSpawn - -Called during idEntity::Spawn to see if it should construct the script object or not. -Overridden by subclasses that need to spawn the script object themselves. -================ -*/ -bool idWeapon::ShouldConstructScriptObjectAtSpawn( void ) const { - return false; -} - -/* -================ -idWeapon::CacheWeapon -================ -*/ -void idWeapon::CacheWeapon( const char *weaponName ) { - const idDeclEntityDef *weaponDef; - const char *brassDefName; - const char *clipModelName; - idTraceModel trm; - const char *guiName; - - weaponDef = gameLocal.FindEntityDef( weaponName, false ); - if ( !weaponDef ) { - return; - } - - // precache the brass collision model - brassDefName = weaponDef->dict.GetString( "def_ejectBrass" ); - if ( brassDefName[0] ) { - const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( brassDefName, false ); - if ( brassDef ) { - brassDef->dict.GetString( "clipmodel", "", &clipModelName ); - if ( !clipModelName[0] ) { - clipModelName = brassDef->dict.GetString( "model" ); // use the visual model - } - // load the trace model - collisionModelManager->TrmFromModel( clipModelName, trm ); - } - } - - guiName = weaponDef->dict.GetString( "gui" ); - if ( guiName[0] ) { - uiManager->FindGui( guiName, true, false, true ); - } -} - -/* -================ -idWeapon::Save -================ -*/ -void idWeapon::Save( idSaveGame *savefile ) const { - - savefile->WriteInt( status ); - savefile->WriteObject( thread ); - savefile->WriteString( state ); - savefile->WriteString( idealState ); - savefile->WriteInt( animBlendFrames ); - savefile->WriteInt( animDoneTime ); - savefile->WriteBool( isLinked ); - - savefile->WriteObject( owner ); - worldModel.Save( savefile ); - - savefile->WriteInt( hideTime ); - savefile->WriteFloat( hideDistance ); - savefile->WriteInt( hideStartTime ); - savefile->WriteFloat( hideStart ); - savefile->WriteFloat( hideEnd ); - savefile->WriteFloat( hideOffset ); - savefile->WriteBool( hide ); - savefile->WriteBool( disabled ); - - savefile->WriteInt( berserk ); - - savefile->WriteVec3( playerViewOrigin ); - savefile->WriteMat3( playerViewAxis ); - - savefile->WriteVec3( viewWeaponOrigin ); - savefile->WriteMat3( viewWeaponAxis ); - - savefile->WriteVec3( muzzleOrigin ); - savefile->WriteMat3( muzzleAxis ); - - savefile->WriteVec3( pushVelocity ); - - savefile->WriteString( weaponDef->GetName() ); - savefile->WriteFloat( meleeDistance ); - savefile->WriteString( meleeDefName ); - savefile->WriteInt( brassDelay ); - savefile->WriteString( icon ); - - savefile->WriteInt( guiLightHandle ); - savefile->WriteRenderLight( guiLight ); - - savefile->WriteInt( muzzleFlashHandle ); - savefile->WriteRenderLight( muzzleFlash ); - - savefile->WriteInt( worldMuzzleFlashHandle ); - savefile->WriteRenderLight( worldMuzzleFlash ); - - savefile->WriteVec3( flashColor ); - savefile->WriteInt( muzzleFlashEnd ); - savefile->WriteInt( flashTime ); - - savefile->WriteBool( lightOn ); - - savefile->WriteInt( kick_endtime ); - savefile->WriteInt( muzzle_kick_time ); - savefile->WriteInt( muzzle_kick_maxtime ); - savefile->WriteAngles( muzzle_kick_angles ); - savefile->WriteVec3( muzzle_kick_offset ); - - savefile->WriteInt( ammoRequired ); - savefile->WriteInt( clipSize ); - savefile->WriteInt( ammoClip ); - savefile->WriteInt( lowAmmo ); - savefile->WriteBool( powerAmmo ); - - // savegames <= 17 - savefile->WriteInt( 0 ); - - savefile->WriteInt( zoomFov ); - - savefile->WriteJoint( barrelJointView ); - savefile->WriteJoint( flashJointView ); - savefile->WriteJoint( ejectJointView ); - savefile->WriteJoint( guiLightJointView ); - savefile->WriteJoint( ventLightJointView ); - - savefile->WriteJoint( flashJointWorld ); - savefile->WriteJoint( barrelJointWorld ); - savefile->WriteJoint( ejectJointWorld ); - - savefile->WriteBool( hasBloodSplat ); - - savefile->WriteSoundShader( sndHum ); - - savefile->WriteParticle( weaponSmoke ); - savefile->WriteInt( weaponSmokeStartTime ); - savefile->WriteBool( continuousSmoke ); - savefile->WriteParticle( strikeSmoke ); - savefile->WriteInt( strikeSmokeStartTime ); - savefile->WriteVec3( strikePos ); - savefile->WriteMat3( strikeAxis ); - savefile->WriteInt( nextStrikeFx ); - - savefile->WriteBool( nozzleFx ); - savefile->WriteInt( nozzleFxFade ); - - savefile->WriteInt( lastAttack ); - - savefile->WriteInt( nozzleGlowHandle ); - savefile->WriteRenderLight( nozzleGlow ); - - savefile->WriteVec3( nozzleGlowColor ); - savefile->WriteMaterial( nozzleGlowShader ); - savefile->WriteFloat( nozzleGlowRadius ); - - savefile->WriteInt( weaponAngleOffsetAverages ); - savefile->WriteFloat( weaponAngleOffsetScale ); - savefile->WriteFloat( weaponAngleOffsetMax ); - savefile->WriteFloat( weaponOffsetTime ); - savefile->WriteFloat( weaponOffsetScale ); - - savefile->WriteBool( allowDrop ); - savefile->WriteObject( projectileEnt ); - - savefile->WriteInt(m_Attachments.Num()); - for (int i = 0; i < m_Attachments.Num(); i++) - { - m_Attachments[i].Save(savefile); - } -} - -/* -================ -idWeapon::Restore -================ -*/ -void idWeapon::Restore( idRestoreGame *savefile ) { - - savefile->ReadInt( (int &)status ); - savefile->ReadObject( reinterpret_cast( thread ) ); - savefile->ReadString( state ); - savefile->ReadString( idealState ); - savefile->ReadInt( animBlendFrames ); - savefile->ReadInt( animDoneTime ); - savefile->ReadBool( isLinked ); - - // Re-link script fields - WEAPON_ATTACK.LinkTo( scriptObject, "WEAPON_ATTACK" ); - WEAPON_BLOCK.LinkTo( scriptObject, "WEAPON_BLOCK" ); - WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); - WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); - WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); - WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); - WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); - WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); - - savefile->ReadObject( reinterpret_cast( owner ) ); - worldModel.Restore( savefile ); - - savefile->ReadInt( hideTime ); - savefile->ReadFloat( hideDistance ); - savefile->ReadInt( hideStartTime ); - savefile->ReadFloat( hideStart ); - savefile->ReadFloat( hideEnd ); - savefile->ReadFloat( hideOffset ); - savefile->ReadBool( hide ); - savefile->ReadBool( disabled ); - - savefile->ReadInt( berserk ); - - savefile->ReadVec3( playerViewOrigin ); - savefile->ReadMat3( playerViewAxis ); - - savefile->ReadVec3( viewWeaponOrigin ); - savefile->ReadMat3( viewWeaponAxis ); - - savefile->ReadVec3( muzzleOrigin ); - savefile->ReadMat3( muzzleAxis ); - - savefile->ReadVec3( pushVelocity ); - - idStr objectname; - savefile->ReadString( objectname ); - weaponDef = gameLocal.FindEntityDef( objectname ); - meleeDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_melee" ), false ); - - /*const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_projectile" ), false ); - if ( projectileDef ) { - projectileDict = projectileDef->dict; - } else { - projectileDict.Clear(); - }*/ - - const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_ejectBrass" ), false ); - if ( brassDef ) { - brassDict = brassDef->dict; - } else { - brassDict.Clear(); - } - - savefile->ReadFloat( meleeDistance ); - savefile->ReadString( meleeDefName ); - savefile->ReadInt( brassDelay ); - savefile->ReadString( icon ); - - savefile->ReadInt( guiLightHandle ); - savefile->ReadRenderLight( guiLight ); - - savefile->ReadInt( muzzleFlashHandle ); - savefile->ReadRenderLight( muzzleFlash ); - - savefile->ReadInt( worldMuzzleFlashHandle ); - savefile->ReadRenderLight( worldMuzzleFlash ); - - savefile->ReadVec3( flashColor ); - savefile->ReadInt( muzzleFlashEnd ); - savefile->ReadInt( flashTime ); - - savefile->ReadBool( lightOn ); - - savefile->ReadInt( kick_endtime ); - savefile->ReadInt( muzzle_kick_time ); - savefile->ReadInt( muzzle_kick_maxtime ); - savefile->ReadAngles( muzzle_kick_angles ); - savefile->ReadVec3( muzzle_kick_offset ); - - savefile->ReadInt( ammoRequired ); - savefile->ReadInt( clipSize ); - savefile->ReadInt( ammoClip ); - savefile->ReadInt( lowAmmo ); - savefile->ReadBool( powerAmmo ); - - // savegame versions <= 17 - int foo; - savefile->ReadInt( foo ); - - savefile->ReadInt( zoomFov ); - - savefile->ReadJoint( barrelJointView ); - savefile->ReadJoint( flashJointView ); - savefile->ReadJoint( ejectJointView ); - savefile->ReadJoint( guiLightJointView ); - savefile->ReadJoint( ventLightJointView ); - - savefile->ReadJoint( flashJointWorld ); - savefile->ReadJoint( barrelJointWorld ); - savefile->ReadJoint( ejectJointWorld ); - - savefile->ReadBool( hasBloodSplat ); - - savefile->ReadSoundShader( sndHum ); - - savefile->ReadParticle( weaponSmoke ); - savefile->ReadInt( weaponSmokeStartTime ); - savefile->ReadBool( continuousSmoke ); - savefile->ReadParticle( strikeSmoke ); - savefile->ReadInt( strikeSmokeStartTime ); - savefile->ReadVec3( strikePos ); - savefile->ReadMat3( strikeAxis ); - savefile->ReadInt( nextStrikeFx ); - - savefile->ReadBool( nozzleFx ); - savefile->ReadInt( nozzleFxFade ); - - savefile->ReadInt( lastAttack ); - - savefile->ReadInt( nozzleGlowHandle ); - savefile->ReadRenderLight( nozzleGlow ); - - savefile->ReadVec3( nozzleGlowColor ); - savefile->ReadMaterial( nozzleGlowShader ); - savefile->ReadFloat( nozzleGlowRadius ); - - savefile->ReadInt( weaponAngleOffsetAverages ); - savefile->ReadFloat( weaponAngleOffsetScale ); - savefile->ReadFloat( weaponAngleOffsetMax ); - savefile->ReadFloat( weaponOffsetTime ); - savefile->ReadFloat( weaponOffsetScale ); - - savefile->ReadBool( allowDrop ); - savefile->ReadObject( reinterpret_cast( projectileEnt ) ); - - int num; - savefile->ReadInt(num); - m_Attachments.SetNum(num); - for (int i = 0; i < num; i++) - { - m_Attachments[i].Restore(savefile); - } -} - -/*********************************************************************** - - Weapon definition management - -***********************************************************************/ - -/* -================ -idWeapon::Clear -================ -*/ -void idWeapon::Clear( void ) { - CancelEvents( &EV_Weapon_Clear ); - - DeconstructScriptObject(); - scriptObject.Free(); - - WEAPON_ATTACK.Unlink(); - WEAPON_BLOCK.Unlink(); - WEAPON_RELOAD.Unlink(); - WEAPON_NETRELOAD.Unlink(); - WEAPON_NETENDRELOAD.Unlink(); - WEAPON_NETFIRING.Unlink(); - WEAPON_RAISEWEAPON.Unlink(); - WEAPON_LOWERWEAPON.Unlink(); - - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); - muzzleFlashHandle = -1; - } - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); - muzzleFlashHandle = -1; - } - if ( worldMuzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); - worldMuzzleFlashHandle = -1; - } - if ( guiLightHandle != -1 ) { - gameRenderWorld->FreeLightDef( guiLightHandle ); - guiLightHandle = -1; - } - if ( nozzleGlowHandle != -1 ) { - gameRenderWorld->FreeLightDef( nozzleGlowHandle ); - nozzleGlowHandle = -1; - } - - memset( &renderEntity, 0, sizeof( renderEntity ) ); - renderEntity.entityNum = entityNumber; - - renderEntity.noShadow = true; - renderEntity.noSelfShadow = true; - renderEntity.customSkin = NULL; - - // set default shader parms - renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f; - renderEntity.shaderParms[ SHADERPARM_GREEN ]= 1.0f; - renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f; - renderEntity.shaderParms[3] = 1.0f; - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = 0.0f; - renderEntity.shaderParms[5] = 0.0f; - renderEntity.shaderParms[6] = 0.0f; - renderEntity.shaderParms[7] = 0.0f; - - if ( refSound.referenceSound ) { - refSound.referenceSound->Free( true ); - } - memset( &refSound, 0, sizeof( refSound_t ) ); - - // setting diversity to 0 results in no random sound. -1 indicates random. - refSound.diversity = -1.0f; - - if ( owner ) { - // don't spatialize the weapon sounds - refSound.listenerId = owner->GetListenerId(); - } - - // clear out the sounds from our spawnargs since we'll copy them from the weapon def - const idKeyValue *kv = spawnArgs.MatchPrefix( "snd_" ); - while( kv ) - { - spawnArgs.Delete( kv->GetKey() ); - kv = spawnArgs.MatchPrefix( "snd_" ); - } - // And the propagated sounds: - kv = spawnArgs.MatchPrefix( "sprS_" ); - while( kv ) - { - spawnArgs.Delete( kv->GetKey() ); - kv = spawnArgs.MatchPrefix( "sprS_" ); - } - - hideTime = 300; - hideDistance = -15.0f; - hideStartTime = gameLocal.time - hideTime; - hideStart = 0.0f; - hideEnd = 0.0f; - hideOffset = 0.0f; - hide = false; - disabled = false; - - weaponSmoke = NULL; - weaponSmokeStartTime = 0; - continuousSmoke = false; - strikeSmoke = NULL; - strikeSmokeStartTime = 0; - strikePos.Zero(); - strikeAxis = mat3_identity; - nextStrikeFx = 0; - - icon = ""; - - playerViewAxis.Identity(); - playerViewOrigin.Zero(); - viewWeaponAxis.Identity(); - viewWeaponOrigin.Zero(); - muzzleAxis.Identity(); - muzzleOrigin.Zero(); - pushVelocity.Zero(); - - status = WP_HOLSTERED; - state = ""; - idealState = ""; - animBlendFrames = 0; - animDoneTime = 0; - - meleeDef = NULL; - meleeDefName = ""; - meleeDistance = 0.0f; - brassDict.Clear(); - - flashTime = 250; - lightOn = false; - - ammoRequired = 0; - ammoClip = 0; - clipSize = 0; - lowAmmo = 0; - powerAmmo = false; - - kick_endtime = 0; - muzzle_kick_time = 0; - muzzle_kick_maxtime = 0; - muzzle_kick_angles.Zero(); - muzzle_kick_offset.Zero(); - - zoomFov = 90; - - barrelJointView = INVALID_JOINT; - flashJointView = INVALID_JOINT; - ejectJointView = INVALID_JOINT; - guiLightJointView = INVALID_JOINT; - ventLightJointView = INVALID_JOINT; - - barrelJointWorld = INVALID_JOINT; - flashJointWorld = INVALID_JOINT; - ejectJointWorld = INVALID_JOINT; - - hasBloodSplat = false; - nozzleFx = false; - nozzleFxFade = 1500; - lastAttack = 0; - nozzleGlowHandle = -1; - nozzleGlowShader = NULL; - nozzleGlowRadius = 10; - nozzleGlowColor.Zero(); - - weaponAngleOffsetAverages = 0; - weaponAngleOffsetScale = 0.0f; - weaponAngleOffsetMax = 0.0f; - weaponOffsetTime = 0.0f; - weaponOffsetScale = 0.0f; - - allowDrop = true; - - animator.ClearAllAnims( gameLocal.time, 0 ); - FreeModelDef(); - - sndHum = NULL; - - isLinked = false; - projectileEnt = NULL; - - isFiring = false; - - // TDM: destroy previous weapon attachments - for( int i=0; iEvent_Remove(); - } - - m_Attachments.Clear(); - - m_animRates.Clear(); - - // clear attack flags on the player - if( owner ) - { - owner->SetAttackFlag(COMBAT_MELEE, false); - owner->SetAttackFlag(COMBAT_RANGED, false); - } -} - -/* -================ -idWeapon::InitWorldModel -================ -*/ -void idWeapon::InitWorldModel( const idDeclEntityDef *def ) { - idEntity *ent; - - ent = worldModel.GetEntity(); - - assert( ent ); - assert( def ); - - const char *model = def->dict.GetString( "model_world" ); - const char *attach = def->dict.GetString( "joint_attach" ); - - ent->SetSkin( NULL ); - if ( model[0] && attach[0] ) { - ent->Show(); - ent->SetModel( model ); - if ( ent->GetAnimator()->ModelDef() ) { - ent->SetSkin( ent->GetAnimator()->ModelDef()->GetDefaultSkin() ); - } - ent->GetPhysics()->SetContents( 0 ); - ent->GetPhysics()->SetClipModel( NULL, 1.0f ); - ent->BindToJoint( owner, attach, true ); - ent->GetPhysics()->SetOrigin( vec3_origin ); - ent->GetPhysics()->SetAxis( mat3_identity ); - - // supress model in player views, but allow it in mirrors and remote views - renderEntity_t *worldModelRenderEntity = ent->GetRenderEntity(); - if ( worldModelRenderEntity ) { - worldModelRenderEntity->suppressSurfaceInViewID = owner->entityNumber+1; - worldModelRenderEntity->suppressShadowInViewID = owner->entityNumber+1; - worldModelRenderEntity->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; - } - } else { - ent->SetModel( "" ); - ent->Hide(); - } - - flashJointWorld = ent->GetAnimator()->GetJointHandle( "flash" ); - barrelJointWorld = ent->GetAnimator()->GetJointHandle( "muzzle" ); - ejectJointWorld = ent->GetAnimator()->GetJointHandle( "eject" ); -} - -/* -================ -idWeapon::GetWeaponDef -================ -*/ -void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { - const char *shader; - const char *objectType; - const char *vmodel; - const char *guiName; - const char *brassDefName; - const char *smokeName; - int ammoAvail = 0; - - Clear(); - - if ( !objectname || !objectname[ 0 ] ) { - return; - } - - assert( owner ); - - weaponDef = gameLocal.FindEntityDef( objectname ); - - ammoRequired = weaponDef->dict.GetInt( "ammo_required" ); - - idStr ammoDefName = weaponDef->dict.GetString("def_ammo"); - - if (ammoDefName.IsEmpty() && weaponDef->dict.GetBool("ammo_required")) - { - gameLocal.Error("No 'ammo' spawnarg defined for weapon %s", objectname); - } - - - clipSize = weaponDef->dict.GetInt( "clipSize" ); - lowAmmo = weaponDef->dict.GetInt( "lowAmmo" ); - - icon = weaponDef->dict.GetString( "icon" ); - powerAmmo = weaponDef->dict.GetBool( "powerAmmo" ); - - muzzle_kick_time = SEC2MS( weaponDef->dict.GetFloat( "muzzle_kick_time" ) ); - muzzle_kick_maxtime = SEC2MS( weaponDef->dict.GetFloat( "muzzle_kick_maxtime" ) ); - muzzle_kick_angles = weaponDef->dict.GetAngles( "muzzle_kick_angles" ); - muzzle_kick_offset = weaponDef->dict.GetVector( "muzzle_kick_offset" ); - - hideTime = SEC2MS( weaponDef->dict.GetFloat( "hide_time", "0.3" ) ); - hideDistance = weaponDef->dict.GetFloat( "hide_distance", "-15" ); - - // muzzle smoke - smokeName = weaponDef->dict.GetString( "smoke_muzzle" ); - if ( *smokeName != '\0' ) { - weaponSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } else { - weaponSmoke = NULL; - } - continuousSmoke = weaponDef->dict.GetBool( "continuousSmoke" ); - weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal.time : 0; - - smokeName = weaponDef->dict.GetString( "smoke_strike" ); - if ( *smokeName != '\0' ) { - strikeSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } else { - strikeSmoke = NULL; - } - strikeSmokeStartTime = 0; - strikePos.Zero(); - strikeAxis = mat3_identity; - nextStrikeFx = 0; - - // setup gui light - memset( &guiLight, 0, sizeof( guiLight ) ); - const char *guiLightShader = weaponDef->dict.GetString( "mtr_guiLightShader" ); - if ( *guiLightShader != '\0' ) { - guiLight.shader = declManager->FindMaterial( guiLightShader, false ); - guiLight.lightRadius[0] = guiLight.lightRadius[1] = guiLight.lightRadius[2] = 3; - guiLight.pointLight = true; - } - - // setup the view model - vmodel = weaponDef->dict.GetString( "model_view" ); - SetModel( vmodel ); - - // setup the world model - InitWorldModel( weaponDef ); - - // copy the sounds from the weapon view model def into out spawnargs - const idKeyValue *kv = weaponDef->dict.MatchPrefix( "snd_" ); - while( kv ) - { - spawnArgs.Set( kv->GetKey(), kv->GetValue() ); - kv = weaponDef->dict.MatchPrefix( "snd_", kv ); - } - // And the propagated sounds - kv = weaponDef->dict.MatchPrefix( "sprS_" ); - while( kv ) - { - spawnArgs.Set( kv->GetKey(), kv->GetValue() ); - kv = weaponDef->dict.MatchPrefix( "sprS_", kv ); - } - - // find some joints in the model for locating effects - barrelJointView = animator.GetJointHandle( "barrel" ); - flashJointView = animator.GetJointHandle( "flash" ); - ejectJointView = animator.GetJointHandle( "eject" ); - guiLightJointView = animator.GetJointHandle( "guiLight" ); - ventLightJointView = animator.GetJointHandle( "ventLight" ); - - // ishtvan: Cache the anim rates here to adjust weapon anim speeds - int anims = animator.NumAnims(); - m_animRates.Clear(); - m_animRates.AssureSize(anims); - for (int i=0; iName(); - m_animRates[i] = weaponDef->dict.GetFloat(spawnargname, "1"); - } else - { - m_animRates[i] = 1.0f; - } - } - - // get the projectile - // greebo: Disabled, the projectile def is loaded on demand - /*projectileName = weaponDef->dict.GetString( "def_projectile" ); - if ( projectileName[0] != '\0' ) { - const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( projectileName, false ); - if ( !projectileDef ) { - gameLocal.Warning( "Unknown projectile '%s' in weapon '%s'", projectileName, objectname ); - } else { - const char *spawnclass = projectileDef->dict.GetString( "spawnclass" ); - idTypeInfo *cls = idClass::GetClass( spawnclass ); - if ( !cls || !cls->IsType( idProjectile::Type ) ) { - gameLocal.Warning( "Invalid spawnclass '%s' on projectile '%s' (used by weapon '%s')", spawnclass, projectileName, objectname ); - } else { - projectileDict = projectileDef->dict; - } - } - }*/ - - // set up muzzleflash render light - const idMaterial*flashShader; - idVec3 flashTarget; - idVec3 flashUp; - idVec3 flashRight; - float flashRadius; - bool flashPointLight; - - weaponDef->dict.GetString( "mtr_flashShader", "", &shader ); - flashShader = declManager->FindMaterial( shader, false ); - flashPointLight = weaponDef->dict.GetBool( "flashPointLight", "1" ); - weaponDef->dict.GetVector( "flashColor", "0 0 0", flashColor ); - flashRadius = (float)weaponDef->dict.GetInt( "flashRadius" ); // if 0, no light will spawn - flashTime = SEC2MS( weaponDef->dict.GetFloat( "flashTime", "0.25" ) ); - flashTarget = weaponDef->dict.GetVector( "flashTarget" ); - flashUp = weaponDef->dict.GetVector( "flashUp" ); - flashRight = weaponDef->dict.GetVector( "flashRight" ); - - memset( &muzzleFlash, 0, sizeof( muzzleFlash ) ); - muzzleFlash.lightId = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; - muzzleFlash.allowLightInViewID = owner->entityNumber+1; - - // the weapon lights will only be in first person - guiLight.allowLightInViewID = owner->entityNumber+1; - nozzleGlow.allowLightInViewID = owner->entityNumber+1; - - muzzleFlash.pointLight = flashPointLight; - muzzleFlash.shader = flashShader; - muzzleFlash.shaderParms[ SHADERPARM_RED ] = flashColor[0]; - muzzleFlash.shaderParms[ SHADERPARM_GREEN ] = flashColor[1]; - muzzleFlash.shaderParms[ SHADERPARM_BLUE ] = flashColor[2]; - muzzleFlash.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; - - muzzleFlash.lightRadius[0] = flashRadius; - muzzleFlash.lightRadius[1] = flashRadius; - muzzleFlash.lightRadius[2] = flashRadius; - - if ( !flashPointLight ) { - muzzleFlash.target = flashTarget; - muzzleFlash.up = flashUp; - muzzleFlash.right = flashRight; - muzzleFlash.end = flashTarget; - } - - // the world muzzle flash is the same, just positioned differently - worldMuzzleFlash = muzzleFlash; - worldMuzzleFlash.suppressLightInViewID = owner->entityNumber+1; - worldMuzzleFlash.allowLightInViewID = 0; - worldMuzzleFlash.lightId = LIGHTID_WORLD_MUZZLE_FLASH + owner->entityNumber; - - //----------------------------------- - - nozzleFx = weaponDef->dict.GetBool("nozzleFx"); - nozzleFxFade = weaponDef->dict.GetInt("nozzleFxFade", "1500"); - nozzleGlowColor = weaponDef->dict.GetVector("nozzleGlowColor", "1 1 1"); - nozzleGlowRadius = weaponDef->dict.GetFloat("nozzleGlowRadius", "10"); - weaponDef->dict.GetString( "mtr_nozzleGlowShader", "", &shader ); - nozzleGlowShader = declManager->FindMaterial( shader, false ); - - // get the melee damage def - meleeDistance = weaponDef->dict.GetFloat( "melee_distance" ); - meleeDefName = weaponDef->dict.GetString( "def_melee" ); - if ( meleeDefName.Length() ) { - meleeDef = gameLocal.FindEntityDef( meleeDefName, false ); - if ( !meleeDef ) { - gameLocal.Error( "Unknown melee '%s'", meleeDefName.c_str() ); - } - } - - // get the brass def - brassDict.Clear(); - brassDelay = weaponDef->dict.GetInt( "ejectBrassDelay", "0" ); - brassDefName = weaponDef->dict.GetString( "def_ejectBrass" ); - - if ( brassDefName[0] ) { - const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( brassDefName, false ); - if ( !brassDef ) { - gameLocal.Warning( "Unknown brass '%s'", brassDefName ); - } else { - brassDict = brassDef->dict; - } - } - - ammoClip = ammoinclip; - if ( ( ammoClip < 0 ) || ( ammoClip > clipSize ) ) { - // first time using this weapon so have it fully loaded to start - ammoClip = clipSize; - CInventoryWeaponItemPtr weaponItem = owner->GetCurrentWeaponItem(); - if (weaponItem != NULL) { - ammoAvail = weaponItem->HasAmmo(); - } - if ( ammoClip > ammoAvail ) { - ammoClip = ammoAvail; - } - } - - renderEntity.gui[ 0 ] = NULL; - guiName = weaponDef->dict.GetString( "gui" ); - if ( guiName[0] ) { - renderEntity.gui[ 0 ] = uiManager->FindGui( guiName, true, false, true ); - } - - zoomFov = weaponDef->dict.GetInt( "zoomFov", "70" ); - berserk = weaponDef->dict.GetInt( "berserk", "2" ); - - weaponAngleOffsetAverages = weaponDef->dict.GetInt( "weaponAngleOffsetAverages", "10" ); - weaponAngleOffsetScale = weaponDef->dict.GetFloat( "weaponAngleOffsetScale", "0.25" ); - weaponAngleOffsetMax = weaponDef->dict.GetFloat( "weaponAngleOffsetMax", "10" ); - - weaponOffsetTime = weaponDef->dict.GetFloat( "weaponOffsetTime", "400" ); - weaponOffsetScale = weaponDef->dict.GetFloat( "weaponOffsetScale", "0.005" ); - - // Bow aimer related -- By Dram - const idKeyValue *AimerKeyVal = weaponDef->dict.MatchPrefix( "def_aimer", NULL ); - idEntity *bow_aimer( NULL ); - if ( AimerKeyVal ) // grayman - always attach the aimer - { - idDict aimerArgs; - aimerArgs.Set( "classname", AimerKeyVal->GetValue().c_str() ); - aimerArgs.Set( "dropToFloor", "0" ); - gameLocal.SpawnEntityDef( aimerArgs, &bow_aimer ); - if ( bow_aimer ) - { - Attach( bow_aimer, NULL, NULL ); - } - - // show it or hide it initially based on the menu setting - - if ( !cv_bow_aimer.GetBool() ) - { - bow_aimer->Hide(); - } - } - - // spawn any weapon attachments we might have - const idKeyValue *KeyVal = weaponDef->dict.MatchPrefix( "def_attach", NULL ); - idEntity *ent(NULL); - - while ( KeyVal ) - { - idDict args2; - - args2.Set( "classname", KeyVal->GetValue().c_str() ); - - // don't let them drop to the floor - args2.Set( "dropToFloor", "0" ); - - gameLocal.SpawnEntityDef( args2, &ent ); - if ( !ent ) - { - gameLocal.Error( "Couldn't spawn '%s' to attach to entity '%s'", KeyVal->GetValue().c_str(), name.c_str() ); - } else - { - DM_LOG(LC_WEAPON, LT_DEBUG)LOGSTRING("Def_Attaching entity %s to weapon entity %s.\r", ent->name.c_str(), name.c_str()); - - // check for attachment position spawnarg - idStr Suffix = KeyVal->GetKey(); - Suffix.StripLeading( "def_attach" ); - idStr PosKey = "pos_attach" + Suffix; - // String name of the attachment for later accessing - idStr AttName = "name_attach" + Suffix; - - if( weaponDef->dict.FindKey(PosKey.c_str()) ) - Attach( ent, weaponDef->dict.GetString(PosKey.c_str()), - weaponDef->dict.GetString(AttName.c_str()) ); - else - Attach( ent, NULL, weaponDef->dict.GetString(AttName.c_str()) ); - if (IsRanged()) // grayman #597 - hide arrows for one second & play an 'equip' sound - { - ent->Hide(); - ent->SetHideUntilTime(gameLocal.time + 1000); - - // Play an arrow-equipping sound - - if (arrow2Arrow) - { - const char *shader = "arrow_equip"; - const idSoundShader *sndEquip = declManager->FindSound(shader); - StartSoundShader(sndEquip,SND_CHANNEL_BODY,0,false,NULL); - } - } - } - KeyVal = weaponDef->dict.MatchPrefix( "def_attach", KeyVal ); - } - - if ( !weaponDef->dict.GetString( "weapon_scriptobject", NULL, &objectType ) ) { - gameLocal.Error( "No 'weapon_scriptobject' set on '%s'.", objectname ); - } - - // setup script object - if ( !scriptObject.SetType( objectType ) ) { - gameLocal.Error( "Script object '%s' not found on weapon '%s'.", objectType, objectname ); - } - - WEAPON_ATTACK.LinkTo( scriptObject, "WEAPON_ATTACK" ); - WEAPON_BLOCK.LinkTo( scriptObject, "WEAPON_BLOCK" ); - WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); - WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); - WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); - WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); - WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); - WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); - - spawnArgs = weaponDef->dict; - - shader = spawnArgs.GetString( "snd_hum" ); - if ( shader && *shader ) { - sndHum = declManager->FindSound( shader ); - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); - } - - isLinked = true; - - // call script object's constructor - ConstructScriptObject(); - - // make sure we have the correct skin - UpdateSkin(); - - // update attack flags on the player - if(weaponDef->dict.GetBool("is_weapon_melee")) - { - owner->SetAttackFlag(COMBAT_MELEE, true); - } - else if(weaponDef->dict.GetBool("is_weapon_ranged")) - { - owner->SetAttackFlag(COMBAT_RANGED, true); - } -} - -/*********************************************************************** - - GUIs - -***********************************************************************/ - -/* -================ -idWeapon::Icon -================ -*/ -const char *idWeapon::Icon( void ) const { - return icon; -} - -/* -================ -idWeapon::UpdateGUI -================ -*/ -void idWeapon::UpdateGUI( void ) { - if ( !renderEntity.gui[ 0 ] ) { - return; - } - - if ( status == WP_HOLSTERED ) { - return; - } - - if ( owner->weaponGone ) { - // dropping weapons was implemented wierd, so we have to not update the gui when it happens or we'll get a negative ammo count - return; - } - - if ( gameLocal.localClientNum != owner->entityNumber ) { - // if updating the hud for a followed client - if ( gameLocal.localClientNum >= 0 && gameLocal.entities[ gameLocal.localClientNum ] && gameLocal.entities[ gameLocal.localClientNum ]->IsType( idPlayer::Type ) ) { - idPlayer *p = static_cast< idPlayer * >( gameLocal.entities[ gameLocal.localClientNum ] ); - if ( !p->spectating || p->spectator != owner->entityNumber ) { - return; - } - } else { - return; - } - } - - int inclip = AmmoInClip(); - int ammoamount = AmmoAvailable(); - - if ( ammoamount < 0 ) { - // show infinite ammo - renderEntity.gui[ 0 ]->SetStateString( "player_ammo", "" ); - } else { - // show remaining ammo - renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount - inclip) ); - renderEntity.gui[ 0 ]->SetStateString( "player_ammo", ClipSize() ? va( "%i", inclip ) : "--" ); - renderEntity.gui[ 0 ]->SetStateString( "player_clips", ClipSize() ? va("%i", ammoamount / ClipSize()) : "--" ); - renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount - inclip ) ); - } - renderEntity.gui[ 0 ]->SetStateBool( "player_ammo_empty", ( ammoamount == 0 ) ); - renderEntity.gui[ 0 ]->SetStateBool( "player_clip_empty", ( inclip == 0 ) ); - renderEntity.gui[ 0 ]->SetStateBool( "player_clip_low", ( inclip <= lowAmmo ) ); -} - -/*********************************************************************** - - Model and muzzleflash - -***********************************************************************/ - -/* -================ -idWeapon::UpdateFlashPosition -================ -*/ -void idWeapon::UpdateFlashPosition( void ) { - // the flash has an explicit joint for locating it - GetGlobalJointTransform( true, flashJointView, muzzleFlash.origin, muzzleFlash.axis ); - - // if the desired point is inside or very close to a wall, back it up until it is clear - idVec3 start = muzzleFlash.origin - playerViewAxis[0] * 16; - idVec3 end = muzzleFlash.origin + playerViewAxis[0] * 8; - trace_t tr; - gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL, owner ); - // be at least 8 units away from a solid - muzzleFlash.origin = tr.endpos - playerViewAxis[0] * 8; - - // put the world muzzle flash on the end of the joint, no matter what - GetGlobalJointTransform( false, flashJointWorld, worldMuzzleFlash.origin, worldMuzzleFlash.axis ); -} - -/* -================ -idWeapon::MuzzleFlashLight -================ -*/ -void idWeapon::MuzzleFlashLight( void ) { - - if ( !lightOn && ( !g_muzzleFlash.GetBool() || !muzzleFlash.lightRadius[0] ) ) { - return; - } - - if ( flashJointView == INVALID_JOINT ) { - return; - } - - UpdateFlashPosition(); - - // these will be different each fire - muzzleFlash.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - muzzleFlash.shaderParms[ SHADERPARM_DIVERSITY ] = renderEntity.shaderParms[ SHADERPARM_DIVERSITY ]; - - worldMuzzleFlash.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - worldMuzzleFlash.shaderParms[ SHADERPARM_DIVERSITY ] = renderEntity.shaderParms[ SHADERPARM_DIVERSITY ]; - - // the light will be removed at this time - muzzleFlashEnd = gameLocal.time + flashTime; - - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->UpdateLightDef( muzzleFlashHandle, &muzzleFlash ); - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - } else { - muzzleFlashHandle = gameRenderWorld->AddLightDef( &muzzleFlash ); - worldMuzzleFlashHandle = gameRenderWorld->AddLightDef( &worldMuzzleFlash ); - } -} - -/* -================ -idWeapon::UpdateSkin -================ -*/ -bool idWeapon::UpdateSkin( void ) { - const function_t *func; - - if ( !isLinked ) { - return false; - } - - func = scriptObject.GetFunction( "UpdateSkin" ); - if ( !func ) { - common->Warning( "Can't find function 'UpdateSkin' in object '%s'", scriptObject.GetTypeName() ); - return false; - } - - // use the frameCommandThread since it's safe to use outside of framecommands - gameLocal.frameCommandThread->CallFunction( this, func, true ); - gameLocal.frameCommandThread->Execute(); - - return true; -} - -/* -================ -idWeapon::SetModel -================ -*/ -void idWeapon::SetModel( const char *modelname ) { - assert( modelname ); - - if ( modelDefHandle >= 0 ) { - gameRenderWorld->RemoveDecals( modelDefHandle ); - } - - renderEntity.hModel = animator.SetModel( modelname ); - if ( renderEntity.hModel ) { - renderEntity.customSkin = animator.ModelDef()->GetDefaultSkin(); - animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); - } else { - renderEntity.customSkin = NULL; - renderEntity.callback = NULL; - renderEntity.numJoints = 0; - renderEntity.joints = NULL; - } - - // hide the model until an animation is played - Hide(); -} - -/* -================ -idWeapon::GetGlobalJointTransform - -This returns the offset and axis of a weapon bone in world space, suitable for attaching models or lights -================ -*/ -bool idWeapon::GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) { - if ( viewModel ) { - // view model - if ( animator.GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { - offset = offset * viewWeaponAxis + viewWeaponOrigin; - axis = axis * viewWeaponAxis; - return true; - } - } else { - // world model - if ( worldModel.GetEntity() && worldModel.GetEntity()->GetAnimator()->GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { - offset = worldModel.GetEntity()->GetPhysics()->GetOrigin() + offset * worldModel.GetEntity()->GetPhysics()->GetAxis(); - axis = axis * worldModel.GetEntity()->GetPhysics()->GetAxis(); - return true; - } - } - offset = viewWeaponOrigin; - axis = viewWeaponAxis; - return false; -} - -/* -================ -idWeapon::SetPushVelocity -================ -*/ -void idWeapon::SetPushVelocity( const idVec3 &pushVelocity ) { - this->pushVelocity = pushVelocity; -} - - -/*********************************************************************** - - State control/player interface - -***********************************************************************/ - -/* -================ -idWeapon::Think -================ -*/ -void idWeapon::Think( void ) { - // do nothing because the present is called from the player through PresentWeapon -} - -/* -================ -idWeapon::Raise -================ -*/ -void idWeapon::Raise( void ) { - if ( isLinked ) { - WEAPON_RAISEWEAPON = true; - } -} - -/* -================ -idWeapon::PutAway -================ -*/ -void idWeapon::PutAway( void ) { - hasBloodSplat = false; - if ( isLinked ) { - WEAPON_LOWERWEAPON = true; - } -} - -/* -================ -idWeapon::SetArrow2Arrow -================ -*/ -void idWeapon::SetArrow2Arrow( bool state ) // grayman #597 -{ - arrow2Arrow = state; -} - - -/* -================ -idWeapon::Reload -NOTE: this is only for impulse-triggered reload, auto reload is scripted -================ -*/ -void idWeapon::Reload( void ) { - if ( isLinked ) { - WEAPON_RELOAD = true; - } -} - -/* -================ -idWeapon::LowerWeapon -================ -*/ -void idWeapon::LowerWeapon( void ) { - if ( !hide ) { - hideStart = 0.0f; - hideEnd = hideDistance; - if ( gameLocal.time - hideStartTime < hideTime ) { - hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); - } else { - hideStartTime = gameLocal.time; - } - hide = true; - } -} - -/* -================ -idWeapon::RaiseWeapon -================ -*/ -void idWeapon::RaiseWeapon( void ) { - Show(); - - if ( hide ) { - hideStart = hideDistance; - hideEnd = 0.0f; - if ( gameLocal.time - hideStartTime < hideTime ) { - hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); - } else { - hideStartTime = gameLocal.time; - } - hide = false; - } -} - -/* -================ -idWeapon::HideWeapon -================ -*/ -void idWeapon::HideWeapon( void ) { - Hide(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->Hide(); - } - muzzleFlashEnd = 0; - - // hide attachments: - for(int i=0; iHide(); - } -} - -/* -================ -idWeapon::ShowWeapon -================ -*/ -void idWeapon::ShowWeapon( void ) { - Show(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->Show(); - } - if ( lightOn ) { - MuzzleFlashLight(); - } - - // show attachments - - // grayman #597 - don't show attachments if they're hidden and there's a hide timeout - - for (int i = 0; i < m_Attachments.Num() ; i++) - { - idEntity *e = m_Attachments[i].ent.GetEntity(); - if ((gameLocal.time >= e->GetHideUntilTime()) && e->IsHidden()) - { - e->Show(); - } - } -} - -/* -================ -idWeapon::HideWorldModel -================ -*/ -void idWeapon::HideWorldModel( void ) { - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->Hide(); - } -} - -/* -================ -idWeapon::ShowWorldModel -================ -*/ -void idWeapon::ShowWorldModel( void ) { - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->Show(); - } -} - -/* -================ -idWeapon::OwnerDied -================ -*/ -void idWeapon::OwnerDied( void ) { - if ( isLinked ) { - SetState( "OwnerDied", 0 ); - thread->Execute(); - } - - Hide(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->Hide(); - } - - // don't clear the weapon immediately since the owner might have killed himself by firing the weapon - // within the current stack frame - PostEventMS( &EV_Weapon_Clear, 0 ); -} - -/* -================ -idWeapon::BeginAttack -================ -*/ -void idWeapon::BeginAttack( void ) -{ - if ( status != WP_OUTOFAMMO ) { - lastAttack = gameLocal.time; - } - - if ( !isLinked ) { - return; - } - - if ( !WEAPON_ATTACK ) - { - if ( sndHum ) - { - StopSound( SND_CHANNEL_BODY, false ); - } - - // grayman #597 - show hidden arrows the first time through - - if (IsRanged()) - { - for (int i = 0; i < m_Attachments.Num() ; i++) - { - idEntity *e = m_Attachments[i].ent.GetEntity(); - - // grayman - If this is the bow aimer, and the player is using it, show it. - // If the player isn't using it, hide it. - - if ( idStr::Cmp( e->spawnArgs.GetString("classname"), "atdm:attachment_aimer" ) == 0 ) - { - if ( cv_bow_aimer.GetBool() ) - { - if ( e->IsHidden() ) - { - e->Show(); - } - } - else if ( !e->IsHidden() ) - { - e->Hide(); - } - } - else if ( e->IsHidden() ) // attachments other than the bow aimer - { - e->Show(); - } - } - } - } - - WEAPON_ATTACK = true; -} - -/* -================ -idWeapon::EndAttack -================ -*/ -void idWeapon::EndAttack( void ) -{ - if ( !WEAPON_ATTACK.IsLinked() ) - return; - if ( WEAPON_ATTACK ) { - WEAPON_ATTACK = false; - if ( sndHum ) { - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); - } - } -} - -/* -================ -idWeapon::BeginBlock -================ -*/ -void idWeapon::BeginBlock( void ) -{ - lastBlock = gameLocal.time; - - if ( !isLinked ) - return; - - if ( !WEAPON_BLOCK ) - { - if ( sndHum ) - { - StopSound( SND_CHANNEL_BODY, false ); - } - } - WEAPON_BLOCK = true; -} - -/* -================ -idWeapon::EndBlock -================ -*/ -void idWeapon::EndBlock( void ) -{ - if ( !WEAPON_BLOCK.IsLinked() ) - return; - - if ( WEAPON_BLOCK ) - { - WEAPON_BLOCK = false; - if ( sndHum ) - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); - } -} - -/* -================ -idWeapon::isReady -================ -*/ -bool idWeapon::IsReady( void ) const { - return !hide && !IsHidden() && ( ( status == WP_RELOAD ) || ( status == WP_READY ) || ( status == WP_OUTOFAMMO ) ); -} - -/* -================ -idWeapon::IsReloading -================ -*/ -bool idWeapon::IsReloading( void ) const { - return ( status == WP_RELOAD ); -} - -/* -================ -idWeapon::IsHolstered -================ -*/ -bool idWeapon::IsHolstered( void ) const { - return ( status == WP_HOLSTERED ); -} - -/* -================ -idWeapon::ShowCrosshair -================ -*/ -bool idWeapon::ShowCrosshair( void ) const { -// return !( state == idStr( WP_RISING ) || state == idStr( WP_LOWERING ) || state == idStr( WP_HOLSTERED ) ); - // Never show the crosshair in TDM. - return false; -} - -/* -===================== -idWeapon::CanDrop -===================== -*/ -bool idWeapon::CanDrop( void ) const { - if ( !weaponDef || !worldModel.GetEntity() ) { - return false; - } - const char *classname = weaponDef->dict.GetString( "def_dropItem" ); - if ( !classname[ 0 ] ) { - return false; - } - return true; -} - -/* -================ -idWeapon::WeaponStolen -================ -*/ -void idWeapon::WeaponStolen( void ) { - assert( !gameLocal.isClient ); - if ( projectileEnt ) { - if ( isLinked ) { - SetState( "WeaponStolen", 0 ); - thread->Execute(); - } - projectileEnt = NULL; - } - - // set to holstered so we can switch weapons right away - status = WP_HOLSTERED; - - HideWeapon(); -} - -/* -===================== -idWeapon::DropItem -===================== -*/ -idEntity * idWeapon::DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died ) { - if ( !weaponDef || !worldModel.GetEntity() ) { - return NULL; - } - if ( !allowDrop ) { - return NULL; - } - const char *classname = weaponDef->dict.GetString( "def_dropItem" ); - if ( !classname[0] ) { - return NULL; - } - StopSound( SND_CHANNEL_BODY, true ); - StopSound( SND_CHANNEL_BODY3, true ); - - return idMoveableItem::DropItem( classname, worldModel.GetEntity()->GetPhysics()->GetOrigin(), worldModel.GetEntity()->GetPhysics()->GetAxis(), velocity, activateDelay, removeDelay ); -} - -/*********************************************************************** - - Script state management - -***********************************************************************/ - -/* -===================== -idWeapon::SetState -===================== -*/ -void idWeapon::SetState( const char *statename, int blendFrames ) { - const function_t *func; - - if ( !isLinked ) { - return; - } - - func = scriptObject.GetFunction( statename ); - if ( !func ) { - assert( 0 ); - gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); - } - - thread->CallFunction( this, func, true ); - state = statename; - - animBlendFrames = blendFrames; - if ( g_debugWeapon.GetBool() ) { - gameLocal.Printf( "%d: weapon state : %s\n", gameLocal.time, statename ); - } - - idealState = ""; -} - - -/*********************************************************************** - - Particles/Effects - -***********************************************************************/ - -/* -================ -idWeapon::UpdateNozzelFx -================ -*/ -void idWeapon::UpdateNozzleFx( void ) { - if ( !nozzleFx ) { - return; - } - - // - // shader parms - // - int la = gameLocal.time - lastAttack + 1; - float s = 1.0f; - float l = 0.0f; - if ( la < nozzleFxFade ) { - s = ((float)la / nozzleFxFade); - l = 1.0f - s; - } - renderEntity.shaderParms[5] = s; - renderEntity.shaderParms[6] = l; - - if ( ventLightJointView == INVALID_JOINT ) { - return; - } - - // - // vent light - // - if ( nozzleGlowHandle == -1 ) { - memset(&nozzleGlow, 0, sizeof(nozzleGlow)); - if ( owner ) { - nozzleGlow.allowLightInViewID = owner->entityNumber+1; - } - nozzleGlow.pointLight = true; - nozzleGlow.noShadows = true; - nozzleGlow.lightRadius.x = nozzleGlowRadius; - nozzleGlow.lightRadius.y = nozzleGlowRadius; - nozzleGlow.lightRadius.z = nozzleGlowRadius; - nozzleGlow.shader = nozzleGlowShader; - nozzleGlow.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; - nozzleGlow.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - GetGlobalJointTransform( true, ventLightJointView, nozzleGlow.origin, nozzleGlow.axis ); - nozzleGlowHandle = gameRenderWorld->AddLightDef(&nozzleGlow); - } - - GetGlobalJointTransform( true, ventLightJointView, nozzleGlow.origin, nozzleGlow.axis ); - - nozzleGlow.shaderParms[ SHADERPARM_RED ] = nozzleGlowColor.x * s; - nozzleGlow.shaderParms[ SHADERPARM_GREEN ] = nozzleGlowColor.y * s; - nozzleGlow.shaderParms[ SHADERPARM_BLUE ] = nozzleGlowColor.z * s; - gameRenderWorld->UpdateLightDef(nozzleGlowHandle, &nozzleGlow); -} - - -/* -================ -idWeapon::BloodSplat -================ -*/ -bool idWeapon::BloodSplat( float size ) { - float s, c; - idMat3 localAxis, axistemp; - idVec3 localOrigin, normal; - - if ( hasBloodSplat ) { - return true; - } - - hasBloodSplat = true; - - if ( modelDefHandle < 0 ) { - return false; - } - - if ( !GetGlobalJointTransform( true, ejectJointView, localOrigin, localAxis ) ) { - return false; - } - - localOrigin[0] += gameLocal.random.RandomFloat() * -10.0f; - localOrigin[1] += gameLocal.random.RandomFloat() * 1.0f; - localOrigin[2] += gameLocal.random.RandomFloat() * -2.0f; - - normal = idVec3( gameLocal.random.CRandomFloat(), -gameLocal.random.RandomFloat(), -1 ); - normal.Normalize(); - - idMath::SinCos16( gameLocal.random.RandomFloat() * idMath::TWO_PI, s, c ); - - localAxis[2] = -normal; - localAxis[2].NormalVectors( axistemp[0], axistemp[1] ); - localAxis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s; - localAxis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c; - - localAxis[0] *= 1.0f / size; - localAxis[1] *= 1.0f / size; - - idPlane localPlane[2]; - - localPlane[0] = localAxis[0]; - localPlane[0][3] = -(localOrigin * localAxis[0]) + 0.5f; - - localPlane[1] = localAxis[1]; - localPlane[1][3] = -(localOrigin * localAxis[1]) + 0.5f; - - const idMaterial *mtr = declManager->FindMaterial( "textures/decals/duffysplatgun" ); - - gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr ); - - return true; -} - - -/*********************************************************************** - - Visual presentation - -***********************************************************************/ - -/* -================ -idWeapon::MuzzleRise - -The machinegun and chaingun will incrementally back up as they are being fired -================ -*/ -void idWeapon::MuzzleRise( idVec3 &origin, idMat3 &axis ) { - int time; - float amount; - idAngles ang; - idVec3 offset; - - time = kick_endtime - gameLocal.time; - if ( time <= 0 ) { - return; - } - - if ( muzzle_kick_maxtime <= 0 ) { - return; - } - - if ( time > muzzle_kick_maxtime ) { - time = muzzle_kick_maxtime; - } - - amount = ( float )time / ( float )muzzle_kick_maxtime; - ang = muzzle_kick_angles * amount; - offset = muzzle_kick_offset * amount; - - origin = origin - axis * offset; - axis = ang.ToMat3() * axis; -} - -/* -================ -idWeapon::ConstructScriptObject - -Called during idEntity::Spawn. Calls the constructor on the script object. -Can be overridden by subclasses when a thread doesn't need to be allocated. -================ -*/ -idThread *idWeapon::ConstructScriptObject( void ) { - const function_t *constructor; - - thread->EndThread(); - - // call script object's constructor - constructor = scriptObject.GetConstructor(); - if ( !constructor ) { - gameLocal.Error( "Missing constructor on '%s' for weapon", scriptObject.GetTypeName() ); - } - - // init the script object's data - scriptObject.ClearObject(); - thread->CallFunction( this, constructor, true ); - thread->Execute(); - - return thread; -} - -/* -================ -idWeapon::DeconstructScriptObject - -Called during idEntity::~idEntity. Calls the destructor on the script object. -Can be overridden by subclasses when a thread doesn't need to be allocated. -Not called during idGameLocal::MapShutdown. -================ -*/ -void idWeapon::DeconstructScriptObject( void ) { - const function_t *destructor; - - if ( !thread ) { - return; - } - - // don't bother calling the script object's destructor on map shutdown - if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) { - return; - } - - thread->EndThread(); - - // call script object's destructor - destructor = scriptObject.GetDestructor(); - if ( destructor ) { - // start a thread that will run immediately and end - thread->CallFunction( this, destructor, true ); - thread->Execute(); - thread->EndThread(); - } - - // clear out the object's memory - scriptObject.ClearObject(); -} - -/* -================ -idWeapon::UpdateScript -================ -*/ -void idWeapon::UpdateScript( void ) { - int count; - - if ( !isLinked ) { - return; - } - - // only update the script on new frames - if ( !gameLocal.isNewFrame ) { - return; - } - - if ( idealState.Length() ) { - SetState( idealState, animBlendFrames ); - } - - // update script state, which may call Event_LaunchProjectiles, among other things - count = 10; - while( ( thread->Execute() || idealState.Length() ) && count-- ) { - // happens for weapons with no clip (like grenades) - if ( idealState.Length() ) { - SetState( idealState, animBlendFrames ); - } - } - - WEAPON_RELOAD = false; -} - -/* -================ -idWeapon::AlertMonsters -================ -*/ -void idWeapon::AlertMonsters( void ) { - trace_t tr; - idEntity *ent; - idVec3 end = muzzleFlash.origin + muzzleFlash.axis * muzzleFlash.target; - - gameLocal.clip.TracePoint( tr, muzzleFlash.origin, end, CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER, owner ); - if ( g_debugWeapon.GetBool() ) { - gameRenderWorld->DebugLine( colorYellow, muzzleFlash.origin, end, 0 ); - gameRenderWorld->DebugArrow( colorGreen, muzzleFlash.origin, tr.endpos, 2, 0 ); - } - - if ( tr.fraction < 1.0f ) { - ent = gameLocal.GetTraceEntity( tr ); - if ( ent->IsType( idAI::Type ) ) { - static_cast( ent )->TouchedByFlashlight( owner ); - } else if ( ent->IsType( idTrigger::Type ) ) { - ent->Signal( SIG_TOUCH ); - ent->ProcessEvent( &EV_Touch, owner, &tr ); - } - } - - // jitter the trace to try to catch cases where a trace down the center doesn't hit the monster - end += muzzleFlash.axis * muzzleFlash.right * idMath::Sin16( MS2SEC( gameLocal.time ) * 31.34f ); - end += muzzleFlash.axis * muzzleFlash.up * idMath::Sin16( MS2SEC( gameLocal.time ) * 12.17f ); - gameLocal.clip.TracePoint( tr, muzzleFlash.origin, end, CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER, owner ); - if ( g_debugWeapon.GetBool() ) { - gameRenderWorld->DebugLine( colorYellow, muzzleFlash.origin, end, 0 ); - gameRenderWorld->DebugArrow( colorGreen, muzzleFlash.origin, tr.endpos, 2, 0 ); - } - - if ( tr.fraction < 1.0f ) { - ent = gameLocal.GetTraceEntity( tr ); - if ( ent->IsType( idAI::Type ) ) { - static_cast( ent )->TouchedByFlashlight( owner ); - } else if ( ent->IsType( idTrigger::Type ) ) { - ent->Signal( SIG_TOUCH ); - ent->ProcessEvent( &EV_Touch, owner, &tr ); - } - } -} - -/* -================ -idWeapon::PresentWeapon -================ -*/ -void idWeapon::PresentWeapon( bool showViewModel ) -{ - playerViewOrigin = owner->firstPersonViewOrigin; - playerViewAxis = owner->firstPersonViewAxis; - - // calculate weapon position based on player movement bobbing - owner->CalculateViewWeaponPos( viewWeaponOrigin, viewWeaponAxis ); - - // hide offset is for dropping the gun when approaching a GUI or NPC - // This is simpler to manage than doing the weapon put-away animation - if ( gameLocal.time - hideStartTime < hideTime ) { - float frac = ( float )( gameLocal.time - hideStartTime ) / ( float )hideTime; - if ( hideStart < hideEnd ) { - frac = 1.0f - frac; - frac = 1.0f - frac * frac; - } else { - frac = frac * frac; - } - hideOffset = hideStart + ( hideEnd - hideStart ) * frac; - } else { - hideOffset = hideEnd; - if ( hide && disabled ) { - Hide(); - } - } - viewWeaponOrigin += hideOffset * viewWeaponAxis[ 2 ]; - - // kick up based on repeat firing - MuzzleRise( viewWeaponOrigin, viewWeaponAxis ); - - // set the physics position and orientation - GetPhysics()->SetOrigin( viewWeaponOrigin ); - GetPhysics()->SetAxis( viewWeaponAxis ); - - // TDM/Ishtvan : Call RunPhysics to update bound entity positions - RunPhysics(); - - UpdateVisuals(); - - // update the weapon script - UpdateScript(); - - UpdateGUI(); - - // update animation - UpdateAnimation(); - - // only show the surface in player view - renderEntity.allowSurfaceInViewID = owner->entityNumber+1; - - // crunch the depth range so it never pokes into walls this breaks the machine gun gui - renderEntity.weaponDepthHack = true; - - // present the model - if ( showViewModel ) { - Present(); - } else { - FreeModelDef(); - } - - if ( worldModel.GetEntity() && worldModel.GetEntity()->GetRenderEntity() ) { - // deal with the third-person visible world model - // don't show shadows of the world model in first person - if ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() || pm_thirdPerson.GetBool() ) { - worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; - } else { - worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = owner->entityNumber+1; - worldModel.GetEntity()->GetRenderEntity()->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; - } - } - - if ( nozzleFx ) { - UpdateNozzleFx(); - } - - // muzzle smoke - if ( showViewModel && !disabled && weaponSmoke && ( weaponSmokeStartTime != 0 ) ) { - // use the barrel joint if available - if ( barrelJointView ) { - GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); - } else { - // default to going straight out the view - muzzleOrigin = playerViewOrigin; - muzzleAxis = playerViewAxis; - } - // spit out a particle - if ( !gameLocal.smokeParticles->EmitSmoke( weaponSmoke, weaponSmokeStartTime, gameLocal.random.RandomFloat(), muzzleOrigin, muzzleAxis ) ) { - weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal.time : 0; - } - } - - if ( showViewModel && strikeSmoke && strikeSmokeStartTime != 0 ) { - // spit out a particle - if ( !gameLocal.smokeParticles->EmitSmoke( strikeSmoke, strikeSmokeStartTime, gameLocal.random.RandomFloat(), strikePos, strikeAxis ) ) { - strikeSmokeStartTime = 0; - } - } - - // remove the muzzle flash light when it's done - if ( ( !lightOn && ( gameLocal.time >= muzzleFlashEnd ) ) || IsHidden() ) { - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); - muzzleFlashHandle = -1; - } - if ( worldMuzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); - worldMuzzleFlashHandle = -1; - } - } - - // update the muzzle flash light, so it moves with the gun - if ( muzzleFlashHandle != -1 ) { - UpdateFlashPosition(); - gameRenderWorld->UpdateLightDef( muzzleFlashHandle, &muzzleFlash ); - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - - // wake up monsters with the flashlight - if ( !gameLocal.isMultiplayer && lightOn && !owner->fl.notarget ) { - AlertMonsters(); - } - } - - // update the gui light - if ( guiLight.lightRadius[0] && guiLightJointView != INVALID_JOINT ) { - GetGlobalJointTransform( true, guiLightJointView, guiLight.origin, guiLight.axis ); - - if ( ( guiLightHandle != -1 ) ) { - gameRenderWorld->UpdateLightDef( guiLightHandle, &guiLight ); - } else { - guiLightHandle = gameRenderWorld->AddLightDef( &guiLight ); - } - } - - if ( status != WP_READY && sndHum ) { - StopSound( SND_CHANNEL_BODY, false ); - } - - UpdateSound(); -} - -/* -================ -idWeapon::EnterCinematic -================ -*/ -void idWeapon::EnterCinematic( void ) { - StopSound( SND_CHANNEL_ANY, false ); - - if ( isLinked ) { - SetState( "EnterCinematic", 0 ); - thread->Execute(); - - WEAPON_ATTACK = false; - WEAPON_BLOCK = false; - WEAPON_RELOAD = false; - WEAPON_NETRELOAD = false; - WEAPON_NETENDRELOAD = false; - WEAPON_NETFIRING = false; - WEAPON_RAISEWEAPON = false; - WEAPON_LOWERWEAPON = false; - } - - disabled = true; - arrow2Arrow = false; // grayman #597 - for arrow switching - - LowerWeapon(); -} - -/* -================ -idWeapon::ExitCinematic -================ -*/ -void idWeapon::ExitCinematic( void ) { - disabled = false; - - if ( isLinked ) { - SetState( "ExitCinematic", 0 ); - thread->Execute(); - } - - RaiseWeapon(); -} - -/* -================ -idWeapon::NetCatchup -================ -*/ -void idWeapon::NetCatchup( void ) { - if ( isLinked ) { - SetState( "NetCatchup", 0 ); - thread->Execute(); - } -} - -/* -================ -idWeapon::GetZoomFov -================ -*/ -int idWeapon::GetZoomFov( void ) { - return zoomFov; -} - -/* -================ -idWeapon::GetWeaponAngleOffsets -================ -*/ -void idWeapon::GetWeaponAngleOffsets( int *average, float *scale, float *max ) { - *average = weaponAngleOffsetAverages; - *scale = weaponAngleOffsetScale; - *max = weaponAngleOffsetMax; -} - -/* -================ -idWeapon::GetWeaponTimeOffsets -================ -*/ -void idWeapon::GetWeaponTimeOffsets( float *time, float *scale ) { - *time = weaponOffsetTime; - *scale = weaponOffsetScale; -} - - -/*********************************************************************** - - Ammo - -***********************************************************************/ - -/* -================ -idWeapon::GetAmmoNumForName -================ - -ammo_t idWeapon::GetAmmoNumForName( const char *ammoname ) { - int num; - const idDict *ammoDict; - - assert( ammoname ); - - ammoDict = gameLocal.FindEntityDefDict( "ammo_types", false ); - if ( !ammoDict ) { - gameLocal.Error( "Could not find entity definition for 'ammo_types'\n" ); - } - - if ( !ammoname[ 0 ] ) { - return 0; - } - - if ( !ammoDict->GetInt( ammoname, "-1", num ) ) { - gameLocal.Error( "Unknown ammo type '%s'", ammoname ); - } - - if ( ( num < 0 ) || ( num >= AMMO_NUMTYPES ) ) { - gameLocal.Error( "Ammo type '%s' value out of range. Maximum ammo types is %d.\n", ammoname, AMMO_NUMTYPES ); - } - - return ( ammo_t )num; -}*/ - -/* -================ -idWeapon::GetAmmoNameForNum -================ -*/ -const char *idWeapon::GetAmmoNameForNum( int ammonum ) { - int i; - int num; - const idDict *ammoDict; - const idKeyValue *kv; - char text[ 32 ]; - - ammoDict = gameLocal.FindEntityDefDict( "ammo_types", false ); - if ( !ammoDict ) { - gameLocal.Error( "Could not find entity definition for 'ammo_types'\n" ); - } - - sprintf( text, "%d", ammonum ); - - num = ammoDict->GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - kv = ammoDict->GetKeyVal( i ); - if ( kv->GetValue() == text ) { - return kv->GetKey(); - } - } - - return NULL; -} - -/* -================ -idWeapon::GetAmmoPickupNameForNum -================ -*/ -const char *idWeapon::GetAmmoPickupNameForNum( int ammonum ) { - int i; - int num; - const idDict *ammoDict; - const idKeyValue *kv; - - ammoDict = gameLocal.FindEntityDefDict( "ammo_names", false ); - if ( !ammoDict ) { - gameLocal.Error( "Could not find entity definition for 'ammo_names'\n" ); - } - - const char *name = GetAmmoNameForNum( ammonum ); - - if ( name && *name ) { - num = ammoDict->GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - kv = ammoDict->GetKeyVal( i ); - if ( idStr::Icmp( kv->GetKey(), name) == 0 ) { - return kv->GetValue(); - } - } - } - - return ""; -} - -/* -================ -idWeapon::AmmoAvailable -================ -*/ -int idWeapon::AmmoAvailable( void ) const { - if (owner && owner->GetCurrentWeaponItem()) { - return owner->GetCurrentWeaponItem()->HasAmmo(); - } else { - return 0; - } -} - -/* -================ -idWeapon::AmmoInClip -================ -*/ -int idWeapon::AmmoInClip( void ) const { - return ammoClip; -} - -/* -================ -idWeapon::ResetAmmoClip -================ -*/ -void idWeapon::ResetAmmoClip( void ) { - ammoClip = -1; -} - -/* -================ -idWeapon::ClipSize -================ -*/ -int idWeapon::ClipSize( void ) const { - return clipSize; -} - -/* -================ -idWeapon::LowAmmo -================ -*/ -int idWeapon::LowAmmo() const { - return lowAmmo; -} - -/* -================ -idWeapon::AmmoRequired -================ -*/ -int idWeapon::AmmoRequired( void ) const { - return ammoRequired; -} - -/* -================ -idWeapon::WriteToSnapshot -================ -*/ -void idWeapon::WriteToSnapshot( idBitMsgDelta &msg ) const { - msg.WriteBits( ammoClip, ASYNC_PLAYER_INV_CLIP_BITS ); - msg.WriteBits( worldModel.GetSpawnId(), 32 ); - msg.WriteBits( lightOn, 1 ); - msg.WriteBits( isFiring ? 1 : 0, 1 ); -} - -/* -================ -idWeapon::ReadFromSnapshot -================ -*/ -void idWeapon::ReadFromSnapshot( const idBitMsgDelta &msg ) { - ammoClip = msg.ReadBits( ASYNC_PLAYER_INV_CLIP_BITS ); - worldModel.SetSpawnId( msg.ReadBits( 32 ) ); - bool snapLight = msg.ReadBits( 1 ) != 0; - isFiring = msg.ReadBits( 1 ) != 0; - - // WEAPON_NETFIRING is only turned on for other clients we're predicting. not for local client - if ( owner && gameLocal.localClientNum != owner->entityNumber && WEAPON_NETFIRING.IsLinked() ) { - - // immediately go to the firing state so we don't skip fire animations - if ( !WEAPON_NETFIRING && isFiring ) { - idealState = "Fire"; - } - - // immediately switch back to idle - if ( WEAPON_NETFIRING && !isFiring ) { - idealState = "Idle"; - } - - WEAPON_NETFIRING = isFiring; - } - - if ( snapLight != lightOn ) { - Reload(); - } -} - -/* -================ -idWeapon::ClientReceiveEvent -================ -*/ -bool idWeapon::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { - - switch( event ) { - case EVENT_RELOAD: { - if ( gameLocal.time - time < 1000 ) { - if ( WEAPON_NETRELOAD.IsLinked() ) { - WEAPON_NETRELOAD = true; - WEAPON_NETENDRELOAD = false; - } - } - return true; - } - case EVENT_ENDRELOAD: { - if ( WEAPON_NETENDRELOAD.IsLinked() ) { - WEAPON_NETENDRELOAD = true; - } - return true; - } - case EVENT_CHANGESKIN: { - int index = gameLocal.ClientRemapDecl( DECL_SKIN, msg.ReadLong() ); - renderEntity.customSkin = ( index != -1 ) ? static_cast( declManager->DeclByIndex( DECL_SKIN, index ) ) : NULL; - UpdateVisuals(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetSkin( renderEntity.customSkin ); - } - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); - } - } -// return false; -} - -/* -idWeapon::IsRanged -*/ -bool idWeapon::IsRanged() { - // greebo: Check the weapon dictionary, whether a projectile def is declared - return (weaponDef != NULL && weaponDef->dict.FindKey("def_projectile") != NULL); -} - -/*********************************************************************** - - Script events - -***********************************************************************/ - -/* -=============== -idWeapon::Event_Clear -=============== -*/ -void idWeapon::Event_Clear( void ) { - Clear(); -} - -/* -=============== -idWeapon::Event_GetOwner -=============== -*/ -void idWeapon::Event_GetOwner( void ) { - idThread::ReturnEntity( owner ); -} - -/* -=============== -idWeapon::Event_WeaponState -=============== -*/ -void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { - const function_t *func; - - func = scriptObject.GetFunction( statename ); - if ( !func ) { - assert( 0 ); - gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); - } - - idealState = statename; - - if ( !idealState.Icmp( "Fire" ) ) { - isFiring = true; - } else { - isFiring = false; - } - - animBlendFrames = blendFrames; - thread->DoneProcessing(); -} - -/* -=============== -idWeapon::Event_WeaponReady -=============== -*/ -void idWeapon::Event_WeaponReady( void ) { - status = WP_READY; - if ( isLinked ) { - WEAPON_RAISEWEAPON = false; - } - if ( sndHum ) { - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); - } - -} - -/* -=============== -idWeapon::Event_WeaponOutOfAmmo -=============== -*/ -void idWeapon::Event_WeaponOutOfAmmo( void ) { - status = WP_OUTOFAMMO; - if ( isLinked ) { - WEAPON_RAISEWEAPON = false; - } -} - -/* -=============== -idWeapon::Event_WeaponReloading -=============== -*/ -void idWeapon::Event_WeaponReloading( void ) { - status = WP_RELOAD; -} - -/* -=============== -idWeapon::Event_WeaponHolstered -=============== -*/ -void idWeapon::Event_WeaponHolstered( void ) { - status = WP_HOLSTERED; - if ( isLinked ) { - WEAPON_LOWERWEAPON = false; - } -} - -/* -=============== -idWeapon::Event_WeaponRising -=============== -*/ -void idWeapon::Event_WeaponRising( void ) { - status = WP_RISING; - if ( isLinked ) { - WEAPON_LOWERWEAPON = false; - } - owner->WeaponRisingCallback(); -} - -/* -=============== -idWeapon::Event_WeaponLowering -=============== -*/ -void idWeapon::Event_WeaponLowering( void ) { - status = WP_LOWERING; - if ( isLinked ) { - WEAPON_RAISEWEAPON = false; - } - owner->WeaponLoweringCallback(); -} - -/* -=============== -idWeapon::Event_UseAmmo -=============== -*/ -void idWeapon::Event_UseAmmo( int amount ) { - if ( gameLocal.isClient ) { - return; - } - - owner->GetCurrentWeaponItem()->UseAmmo(( powerAmmo ) ? amount : ( amount * ammoRequired ) ); - if ( clipSize && ammoRequired ) { - ammoClip -= powerAmmo ? amount : ( amount * ammoRequired ); - if ( ammoClip < 0 ) { - ammoClip = 0; - } - } -} - -/* -=============== -idWeapon::Event_AddToClip -=============== -*/ -void idWeapon::Event_AddToClip( int amount ) { - int ammoAvail; - - if ( gameLocal.isClient ) { - return; - } - - ammoClip += amount; - if ( ammoClip > clipSize ) { - ammoClip = clipSize; - } - - ammoAvail = owner->GetCurrentWeaponItem()->HasAmmo(); - if ( ammoClip > ammoAvail ) { - ammoClip = ammoAvail; - } -} - -/* -=============== -idWeapon::Event_AmmoInClip -=============== -*/ -void idWeapon::Event_AmmoInClip( void ) { - int ammo = AmmoInClip(); - idThread::ReturnFloat( ammo ); -} - -/* -=============== -idWeapon::Event_AmmoAvailable -=============== -*/ -void idWeapon::Event_AmmoAvailable( void ) { - CInventoryWeaponItemPtr currentWeapon = owner->GetCurrentWeaponItem(); - int ammoAvail = (currentWeapon != NULL) ? currentWeapon->HasAmmo() : 0; - idThread::ReturnFloat( ammoAvail ); -} - -/* -=============== -idWeapon::Event_TotalAmmoCount -=============== -*/ -void idWeapon::Event_TotalAmmoCount( void ) { - CInventoryWeaponItemPtr currentWeapon = owner->GetCurrentWeaponItem(); - int ammoAvail = (currentWeapon != NULL) ? currentWeapon->HasAmmo() : 0; - idThread::ReturnFloat( ammoAvail ); -} - -/* -=============== -idWeapon::Event_ClipSize -=============== -*/ -void idWeapon::Event_ClipSize( void ) { - idThread::ReturnFloat( clipSize ); -} - -/* -=============== -idWeapon::Event_AutoReload -=============== -*/ -void idWeapon::Event_AutoReload( void ) { - assert( owner ); - if ( gameLocal.isClient ) { - idThread::ReturnFloat( 0.0f ); - return; - } - idThread::ReturnFloat( gameLocal.userInfo[ owner->entityNumber ].GetBool( "ui_autoReload" ) ); -} - -/* -=============== -idWeapon::Event_NetReload -=============== -*/ -void idWeapon::Event_NetReload( void ) { - assert( owner ); - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_RELOAD, NULL, false, -1 ); - } -} - -/* -=============== -idWeapon::Event_NetEndReload -=============== -*/ -void idWeapon::Event_NetEndReload( void ) { - assert( owner ); - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_ENDRELOAD, NULL, false, -1 ); - } -} - -/* -=============== -idWeapon::Event_PlayAnim -=============== -*/ -void idWeapon::Event_PlayAnim( int channel, const char *animname ) { - int anim; - - anim = animator.GetAnim( animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - gameLocal.Warning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); -#endif - - animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); - animDoneTime = 0; - } else { - - // grayman #597 - if this is a raise or lower animation, and we're - // switching from one arrow to another, skip the animation. - - idStr raiseString = "raise"; - idStr lowerString = "lower"; - bool raiseOrLower = ((raiseString.Cmp(animname) == 0) || (lowerString.Cmp(animname) == 0)); - if (arrow2Arrow && raiseOrLower) - { - animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); - animDoneTime = 0; - if (lowerString.Cmp(animname) == 0) - { - status = WP_HOLSTERED; // do this right away, otherwise it takes 12 frames to have it done elsewhere - // and you see a gap in the bow animation - } - } - else - { - if ( !( owner && owner->GetInfluenceLevel() ) ) { - Show(); - } - animator.PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - animDoneTime = animator.CurrentAnim( channel )->GetEndTime(); - if ( worldModel.GetEntity() ) { - anim = worldModel.GetEntity()->GetAnimator()->GetAnim( animname ); - if ( anim ) { - worldModel.GetEntity()->GetAnimator()->PlayAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - } - } - } - } - animBlendFrames = 0; - idThread::ReturnInt( 0 ); -} - -/* -=============== -idWeapon::Event_PlayCycle -=============== -*/ -void idWeapon::Event_PlayCycle( int channel, const char *animname ) { - int anim; - - anim = animator.GetAnim( animname ); - if ( !anim ) { - -#ifndef SUPPRESS_CONSOLE_WARNINGS - gameLocal.Warning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() ); -#endif - - animator.Clear( channel, gameLocal.time, FRAME2MS( animBlendFrames ) ); - animDoneTime = 0; - } else { - if ( !( owner && owner->GetInfluenceLevel() ) ) { - Show(); - } - animator.CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - animDoneTime = animator.CurrentAnim( channel )->GetEndTime(); - if ( worldModel.GetEntity() ) { - anim = worldModel.GetEntity()->GetAnimator()->GetAnim( animname ); - worldModel.GetEntity()->GetAnimator()->CycleAnim( channel, anim, gameLocal.time, FRAME2MS( animBlendFrames ) ); - } - } - animBlendFrames = 0; - idThread::ReturnInt( 0 ); -} - -/* -=============== -idWeapon::Event_PauseAnim -=============== -*/ -void idWeapon::Event_PauseAnim( int channel, bool bPause ) -{ - animator.CurrentAnim( channel )->Pause( bPause ); -} - -/* -=============== -idWeapon::Event_AnimIsPaused -=============== -*/ -void idWeapon::Event_AnimIsPaused( int channel ) -{ - idThread::ReturnInt( animator.CurrentAnim( channel )->IsPaused() ); -} - -/* -=============== -idWeapon::Event_AnimDone -=============== -*/ -void idWeapon::Event_AnimDone( int channel, int blendFrames ) -{ -// ishtvan: rewrote this to be more like what happens in idActor/idAnimState - int DoneTime = animator.CurrentAnim( channel )->GetEndTime(); - - if (DoneTime < 0) - { - // playing a cycle or paused - idThread::ReturnInt( false ); - } - else if ( DoneTime - FRAME2MS( blendFrames ) <= gameLocal.time ) - { - idThread::ReturnInt( true ); - } else - { - idThread::ReturnInt( false ); - } -} - -/* -=============== -idWeapon::Event_SetBlendFrames -=============== -*/ -void idWeapon::Event_SetBlendFrames( int channel, int blendFrames ) -{ - // ishtvan: this is a problem with animrate?? - animBlendFrames = blendFrames; -} - -/* -=============== -idWeapon::Event_GetBlendFrames -=============== -*/ -void idWeapon::Event_GetBlendFrames( int channel ) { - idThread::ReturnInt( animBlendFrames ); -} - -/* -================ -idWeapon::Event_Next -================ -*/ -void idWeapon::Event_Next( void ) { - // change to another weapon if possible - owner->NextBestWeapon(); -} - -/* -================ -idWeapon::Event_SetSkin -================ -*/ -void idWeapon::Event_SetSkin( const char *skinname ) { - const idDeclSkin *skinDecl; - - if ( !skinname || !skinname[ 0 ] ) { - skinDecl = NULL; - } else { - skinDecl = declManager->FindSkin( skinname ); - } - - renderEntity.customSkin = skinDecl; - UpdateVisuals(); - - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetSkin( skinDecl ); - } - - if ( gameLocal.isServer ) { - idBitMsg msg; - byte msgBuf[MAX_EVENT_PARAM_SIZE]; - - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteLong( ( skinDecl != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_SKIN, skinDecl->Index() ) : -1 ); - ServerSendEvent( EVENT_CHANGESKIN, &msg, false, -1 ); - } -} - -/* -================ -idWeapon::Event_Flashlight -================ -*/ -void idWeapon::Event_Flashlight( int enable ) { - if ( enable ) { - lightOn = true; - MuzzleFlashLight(); - } else { - lightOn = false; - muzzleFlashEnd = 0; - } -} - -/* -================ -idWeapon::Event_GetLightParm -================ -*/ -void idWeapon::Event_GetLightParm( int parmnum ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Error( "shader parm index (%d) out of range", parmnum ); - } - - idThread::ReturnFloat( muzzleFlash.shaderParms[ parmnum ] ); -} - -/* -================ -idWeapon::Event_SetLightParm -================ -*/ -void idWeapon::Event_SetLightParm( int parmnum, float value ) { - if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) { - gameLocal.Error( "shader parm index (%d) out of range", parmnum ); - } - - muzzleFlash.shaderParms[ parmnum ] = value; - worldMuzzleFlash.shaderParms[ parmnum ] = value; - UpdateVisuals(); -} - -/* -================ -idWeapon::Event_SetLightParms -================ -*/ -void idWeapon::Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ) { - muzzleFlash.shaderParms[ SHADERPARM_RED ] = parm0; - muzzleFlash.shaderParms[ SHADERPARM_GREEN ] = parm1; - muzzleFlash.shaderParms[ SHADERPARM_BLUE ] = parm2; - muzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = parm3; - - worldMuzzleFlash.shaderParms[ SHADERPARM_RED ] = parm0; - worldMuzzleFlash.shaderParms[ SHADERPARM_GREEN ] = parm1; - worldMuzzleFlash.shaderParms[ SHADERPARM_BLUE ] = parm2; - worldMuzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = parm3; - - UpdateVisuals(); -} - -/* -================ -idWeapon::Event_CreateProjectile -================ -*/ -void idWeapon::Event_CreateProjectile() -{ - if ( !gameLocal.isClient ) - { - projectileEnt = NULL; - - // Try to get the weapon inventory item - CInventoryWeaponItemPtr weaponItem = owner->GetWeaponItem(weaponDef->dict.GetString("inv_weapon_name")); - - if (weaponItem == NULL) - { - idThread::ReturnEntity( NULL ); - return; - } - - // Retrieve the currently active projectile def name from the inventory item - const idStr& projectileDefName = weaponItem->GetProjectileDefName(); - - const idDeclEntityDef* projectileDef = gameLocal.FindEntityDef(projectileDefName); - - if (projectileDef != NULL) - { - gameLocal.SpawnEntityDef( projectileDef->dict, &projectileEnt, false ); - - if ( projectileEnt ) - { - projectileEnt->SetOrigin( GetPhysics()->GetOrigin() ); - projectileEnt->Bind( owner, false ); - projectileEnt->Hide(); - } - } - - idThread::ReturnEntity( projectileEnt ); - } - else - { - idThread::ReturnEntity( NULL ); - } -} - -/* -================ -idWeapon::Event_LaunchProjectiles -================ -*/ -void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ) { - idProjectile *proj; - idEntity *ent; - int i; - idVec3 dir; - float ang; - float spin; - trace_t tr; - idVec3 start; - idVec3 muzzle_pos; - idBounds ownerBounds, projBounds; - - if ( IsHidden() ) { - return; - } - - /*if ( !projectileDict.GetNumKeyVals() ) { - const char *classname = weaponDef->dict.GetString( "classname" ); - gameLocal.Warning( "No projectile defined on '%s'", classname ); - return; - }*/ - CInventoryWeaponItemPtr weaponItem = owner->GetWeaponItem(weaponDef->dict.GetString("inv_weapon_name")); - if (weaponItem == NULL) return; - - // Retrieve the currently active projectile def name from the inventory item - const idStr& projectileDefName = weaponItem->GetProjectileDefName(); - - if (projectileDefName.IsEmpty()) - { - gameLocal.Warning("No projectile entityDef defined on '%s'", name.c_str()); - return; - } - - const idDeclEntityDef* projectileDef = gameLocal.FindEntityDef(projectileDefName); - - if (projectileDef == NULL) - { - gameLocal.Warning("Projectile entityDef %s not found.", projectileDefName.c_str()); - return; - } - - // avoid all ammo considerations on an MP client - if ( !gameLocal.isClient ) { - - CInventoryWeaponItemPtr weaponItem = owner->GetCurrentWeaponItem(); - - // check if we're out of ammo or the clip is empty - int ammoAvail = weaponItem->HasAmmo(); - if ( !ammoAvail || ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) ) { - return; - } - - weaponItem->UseAmmo(ammoRequired); - - if ( clipSize && ammoRequired ) { - ammoClip -= powerAmmo ? (int) dmgPower : 1; - } - } - - // set the shader parm to the time of last projectile firing, - // which the gun material shaders can reference for single shot barrel glows, etc - renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = gameLocal.random.CRandomFloat(); - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.realClientTime ); - - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetShaderParm( SHADERPARM_DIVERSITY, renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] ); - worldModel.GetEntity()->SetShaderParm( SHADERPARM_TIMEOFFSET, renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] ); - } - - // calculate the muzzle position - if ( barrelJointView != INVALID_JOINT && projectileDef->dict.GetBool( "launchFromBarrel" ) ) { - // there is an explicit joint for the muzzle - GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); - } else { - // go straight out of the view - muzzleOrigin = playerViewOrigin; - muzzleAxis = playerViewAxis; - } - - // add some to the kick time, incrementally moving repeat firing weapons back - if ( kick_endtime < gameLocal.realClientTime ) { - kick_endtime = gameLocal.realClientTime; - } - kick_endtime += muzzle_kick_time; - if ( kick_endtime > gameLocal.realClientTime + muzzle_kick_maxtime ) { - kick_endtime = gameLocal.realClientTime + muzzle_kick_maxtime; - } - - if ( gameLocal.isClient ) { - - // predict instant hit projectiles - if ( projectileDef->dict.GetBool( "net_instanthit" ) ) { - float spreadRad = DEG2RAD( spread ); - muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; - for( i = 0; i < num_projectiles; i++ ) { - ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); - spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); - //dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); - dir = muzzleAxis[ 0 ]; // Dram: Make the weapon shoot directly from the barrel bone. Found by Ishtvan - dir.Normalize(); - gameLocal.clip.Translation( tr, muzzle_pos, muzzle_pos + dir * 4096.0f, NULL, mat3_identity, MASK_SHOT_RENDERMODEL, owner ); - if ( tr.fraction < 1.0f ) { - idProjectile::ClientPredictionCollide( this, projectileDef->dict, tr, vec3_origin, true ); - } - } - } - - } else { - - ownerBounds = owner->GetPhysics()->GetAbsBounds(); - - owner->AddProjectilesFired( num_projectiles ); - - float spreadRad = DEG2RAD( spread ); - for( i = 0; i < num_projectiles; i++ ) { - ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); - spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); - //dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); - dir = muzzleAxis[ 0 ]; // Dram: Make the weapon shoot directly from the barrel bone. Found by Ishtvan - - if (projectileDef->dict.GetBool("fire_along_playerview", "0")) - { - // greebo: Fire the projectile along the playerview direction - dir = playerViewAxis.ToAngles().ToForward(); - } - - dir.Normalize(); - - //gameRenderWorld->DebugArrow(colorWhite, muzzleOrigin, muzzleOrigin + dir*100, 1, 15000); - - if ( projectileEnt ) { - ent = projectileEnt; - ent->Show(); - ent->Unbind(); - projectileEnt = NULL; - } else { - gameLocal.SpawnEntityDef( projectileDef->dict, &ent, false ); - } - - if ( !ent || !ent->IsType( idProjectile::Type ) ) { - const char *projectileName = weaponDef->dict.GetString( "def_projectile" ); - gameLocal.Error( "'%s' is not an idProjectile", projectileName ); - } - - if ( projectileDef->dict.GetBool( "net_instanthit" ) ) { - // don't synchronize this on top of the already predicted effect - ent->fl.networkSync = false; - } - - proj = static_cast(ent); - proj->Create( owner, muzzleOrigin, dir ); - - projBounds = proj->GetPhysics()->GetBounds().Rotate( proj->GetPhysics()->GetAxis() ); - - // make sure the projectile start point does not clip with anything - if ( i == 0 ) { - muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; - start = ownerBounds.GetCenter(); - /* stgatilov: translate to viewpoint first, then to muzzle point. - Otherwise shot while leaning over the corner would lag. Picture: - XXXX M C - center of player's bbox - XXXX | V - player's view origin - XXXX | M - muzzle position - C----V - */ - idClipModel *clm = proj->GetPhysics()->GetClipModel(); - if (!gameLocal.clip.Translation( tr, start, playerViewOrigin, clm, clm->GetAxis(), MASK_SHOT_RENDERMODEL, owner )) { - gameLocal.clip.Translation( tr, playerViewOrigin, muzzle_pos, clm, clm->GetAxis(), MASK_SHOT_RENDERMODEL, owner ); - } - muzzle_pos = tr.endpos; - - } - - proj->Launch( muzzle_pos, dir, pushVelocity, fuseOffset, launchPower, dmgPower ); - - // TDM: Update responsible actor for the projectile, so it can be tracked for alerts - proj->m_SetInMotionByActor = owner; - proj->m_MovedByActor = owner; - } - - // toss the brass - PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); - } - - // add the light for the muzzleflash - if ( !lightOn ) { - MuzzleFlashLight(); - } - - owner->WeaponFireFeedback( &weaponDef->dict ); - - // reset muzzle smoke - weaponSmokeStartTime = gameLocal.realClientTime; -} - -/* -===================== -idWeapon::Event_Melee -===================== -*/ -void idWeapon::Event_Melee( void ) { - idEntity *ent; - trace_t tr; - - if ( !meleeDef ) { - gameLocal.Error( "No meleeDef on '%s'", weaponDef->dict.GetString( "classname" ) ); - } - - if ( !gameLocal.isClient ) { - idVec3 start = playerViewOrigin; - idVec3 end = start + playerViewAxis[0] * ( meleeDistance * owner->PowerUpModifier( MELEE_DISTANCE ) ); - gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL, owner ); - if ( tr.fraction < 1.0f && gameLocal.entities[tr.c.entityNum] ) - { - //ent = gameLocal.GetTraceEntity( tr ); - ent = gameLocal.entities[ tr.c.entityNum ]; - } else - { - ent = NULL; - } - - if ( g_debugWeapon.GetBool() ) { - gameRenderWorld->DebugLine( colorYellow, start, end, 100 ); - if ( ent ) { - gameRenderWorld->DebugBounds( colorRed, ent->GetPhysics()->GetBounds(), ent->GetPhysics()->GetOrigin(), 100 ); - } - } - - bool hit = false; - idStr hitSound = meleeDef->dict.GetString( "snd_miss" ); - idStr sndName = "snd_miss"; - - if ( ent ) { - - float push = meleeDef->dict.GetFloat( "push" ); - idVec3 impulse = -push * owner->PowerUpModifier( SPEED ) * tr.c.normal; - - if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) && ( ent->IsType( idActor::Type ) || ent->IsType( idAFAttachment::Type) ) ) { - idThread::ReturnInt( 0 ); - return; - } - - ent->ApplyImpulse( this, tr.c.id, tr.c.point, impulse ); - - // weapon stealing - do this before damaging so weapons are not dropped twice - if ( gameLocal.isMultiplayer - && weaponDef && weaponDef->dict.GetBool( "stealing" ) - && ent->IsType( idPlayer::Type ) - && ( gameLocal.gameType != GAME_TDM || gameLocal.serverInfo.GetBool( "si_teamDamage" ) || ( owner->team != static_cast< idPlayer * >( ent )->team ) ) - ) { - owner->StealWeapon( static_cast< idPlayer * >( ent ) ); - } - - if ( ent->fl.takedamage ) { - idVec3 kickDir, globalKickDir; - meleeDef->dict.GetVector( "kickDir", "0 0 0", kickDir ); - globalKickDir = muzzleAxis * kickDir; - - ent->Damage( owner, owner, globalKickDir, meleeDefName, owner->PowerUpModifier( MELEE_DAMAGE ), CLIPMODEL_ID_TO_JOINT_HANDLE(tr.c.id), &tr ); - - // apply a LARGE tactile alert to AI - if( ent->IsType(idAI::Type) ) - { - static_cast(ent)->TactileAlert( GetOwner(), 100 ); - } - - hit = true; - } - - if ( weaponDef->dict.GetBool( "impact_damage_effect" ) ) { - - if ( ent->spawnArgs.GetBool( "bleed" ) ) { - - hitSound = meleeDef->dict.GetString( "snd_hit" ); - sndName = "snd_hit"; - - ent->AddDamageEffect( tr, impulse, meleeDef->dict.GetString( "classname" ) ); - - } else - { - - idStr materialType; - int type = tr.c.material->GetSurfaceType(); - - if ( type == SURFTYPE_NONE ) - materialType = gameLocal.sufaceTypeNames[ GetDefaultSurfaceType() ]; - else - g_Global.GetSurfName( tr.c.material, materialType ); - - // start impact sound based on material type - hitSound = meleeDef->dict.GetString( va( "snd_%s", materialType.c_str() ) ); - sndName = va( "snd_%s", materialType.c_str() ); - - if ( hitSound.IsEmpty() ) - { - hitSound = meleeDef->dict.GetString( "snd_metal" ); - sndName = "snd_metal"; - } - - if ( gameLocal.time > nextStrikeFx ) { - const char *decal; - // project decal - decal = weaponDef->dict.GetString( "mtr_strike" ); - if ( decal && *decal ) { - gameLocal.ProjectDecal( tr.c.point, -tr.c.normal, 8.0f, true, 6.0, decal ); - } - nextStrikeFx = gameLocal.time + 200; - } else { - hitSound = ""; - sndName = ""; - } - - strikeSmokeStartTime = gameLocal.time; - strikePos = tr.c.point; - strikeAxis = -tr.endAxis; - } - } - } - - if ( !hitSound.IsEmpty() ) - { - const idSoundShader *snd = declManager->FindSound( hitSound.c_str() ); - StartSoundShader( snd, SND_CHANNEL_BODY2, 0, true, NULL ); - - // Propagate the sound to AI, must find global sound first because it's on a different dict - sndName.StripLeading("snd_"); - sndName = meleeDef->dict.GetString( va("sprS_%s", sndName.c_str()) ); - if( !sndName.IsEmpty() ) - PropSoundDirect( sndName.c_str(), false, false ); - } - - idThread::ReturnInt( hit ); - owner->WeaponFireFeedback( &weaponDef->dict ); - return; - } - - idThread::ReturnInt( 0 ); - owner->WeaponFireFeedback( &weaponDef->dict ); -} - -/* -===================== -idWeapon::Event_GetWorldModel -===================== -*/ -void idWeapon::Event_GetWorldModel( void ) { - idThread::ReturnEntity( worldModel.GetEntity() ); -} - -/* -===================== -idWeapon::Event_AllowDrop -===================== -*/ -void idWeapon::Event_AllowDrop( int allow ) { - if ( allow ) { - allowDrop = true; - } else { - allowDrop = false; - } -} - -/* -================ -idWeapon::Event_EjectBrass - -Toss a shell model out from the breach if the bone is present -================ -*/ -void idWeapon::Event_EjectBrass( void ) { - if ( !g_showBrass.GetBool() || !owner->CanShowWeaponViewmodel() ) { - return; - } - - if ( ejectJointView == INVALID_JOINT || !brassDict.GetNumKeyVals() ) { - return; - } - - if ( gameLocal.isClient ) { - return; - } - - idMat3 axis; - idVec3 origin, linear_velocity, angular_velocity; - idEntity *ent; - - if ( !GetGlobalJointTransform( true, ejectJointView, origin, axis ) ) { - return; - } - - gameLocal.SpawnEntityDef( brassDict, &ent, false ); - if ( !ent || !ent->IsType( idDebris::Type ) ) { - gameLocal.Error( "'%s' is not an idDebris", weaponDef ? weaponDef->dict.GetString( "def_ejectBrass" ) : "def_ejectBrass" ); - } - idDebris *debris = static_cast(ent); - debris->Create( owner, origin, axis ); - debris->Launch(); - - linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] ); - angular_velocity.Set( 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat() ); - - debris->GetPhysics()->SetLinearVelocity( linear_velocity ); - debris->GetPhysics()->SetAngularVelocity( angular_velocity ); -} - -/* -=============== -idWeapon::Event_IsInvisible -=============== -*/ -void idWeapon::Event_IsInvisible( void ) { - // greebo: No invisibility in TDM currently - idThread::ReturnFloat( 0 ); -} - -/* -=============== -idWeapon::ClientPredictionThink -=============== -*/ -void idWeapon::ClientPredictionThink( void ) { - UpdateAnimation(); -} - -/* -================ -idWeapon::Attach -================ -*/ -void idWeapon::Attach( idEntity *ent, const char *PosName, const char *AttName ) -{ - idAnimatedEntity::Attach( ent, PosName, AttName ); - - // set up the same rendering conditions as the weapon viewmodel - ent->GetRenderEntity()->allowSurfaceInViewID = owner->entityNumber+1; - ent->GetRenderEntity()->weaponDepthHack = true; -} - -/* -================ -idWeapon::GetAttachingTransform -================ -*/ -void idWeapon::GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ) -{ - GetGlobalJointTransform( true, jointHandle, offset, axis ); -} - - diff --git a/game/weapon.h b/game/weapon.h deleted file mode 100644 index 09788194a..000000000 --- a/game/weapon.h +++ /dev/null @@ -1,387 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_WEAPON_H__ -#define __GAME_WEAPON_H__ - -/* -=============================================================================== - - Player Weapon - -=============================================================================== -*/ - -typedef enum { - WP_READY, - WP_OUTOFAMMO, - WP_RELOAD, - WP_HOLSTERED, - WP_RISING, - WP_LOWERING -} weaponStatus_t; - -class idPlayer; - -static const int LIGHTID_WORLD_MUZZLE_FLASH = 1; -static const int LIGHTID_VIEW_MUZZLE_FLASH = 100; - -class idMoveableItem; - -class idWeapon : public idAnimatedEntity { -public: - CLASS_PROTOTYPE( idWeapon ); - - idWeapon(); - virtual ~idWeapon(); - - // Init - void Spawn( void ); - void SetOwner( idPlayer *owner ); - idPlayer* GetOwner( void ); - virtual bool ShouldConstructScriptObjectAtSpawn( void ) const; - - static void CacheWeapon( const char *weaponName ); - - // save games - void Save( idSaveGame *savefile ) const; // archives object for save game file - void Restore( idRestoreGame *savefile ); // unarchives object from save game file - - // Weapon definition management - void Clear( void ); - void GetWeaponDef( const char *objectname, int ammoinclip ); - bool IsLinked( void ); - bool IsWorldModelReady( void ); - - // GUIs - const char * Icon( void ) const; - void UpdateGUI( void ); - - virtual void SetModel( const char *modelname ); - bool GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); - void SetPushVelocity( const idVec3 &pushVelocity ); - bool UpdateSkin( void ); - - // State control/player interface - void Think( void ); - void Raise( void ); - void PutAway( void ); - void Reload( void ); - void LowerWeapon( void ); - void RaiseWeapon( void ); - void HideWeapon( void ); - void ShowWeapon( void ); - void HideWorldModel( void ); - void ShowWorldModel( void ); - void OwnerDied( void ); - void BeginAttack( void ); - void EndAttack( void ); - void BeginBlock( void ); - void EndBlock( void ); - bool IsReady( void ) const; - bool IsReloading( void ) const; - bool IsHolstered( void ) const; - bool ShowCrosshair( void ) const; - idEntity * DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died ); - bool CanDrop( void ) const; - void WeaponStolen( void ); - void SetArrow2Arrow( bool state); // grayman #597 - - // Script state management - virtual idThread * ConstructScriptObject( void ); - virtual void DeconstructScriptObject( void ); - void SetState( const char *statename, int blendFrames ); - void UpdateScript( void ); - void EnterCinematic( void ); - void ExitCinematic( void ); - void NetCatchup( void ); - - // Visual presentation - void PresentWeapon( bool showViewModel ); - int GetZoomFov( void ); - void GetWeaponAngleOffsets( int *average, float *scale, float *max ); - void GetWeaponTimeOffsets( float *time, float *scale ); - bool BloodSplat( float size ); - - // Ammo - static const char *GetAmmoNameForNum( int ammonum ); - static const char *GetAmmoPickupNameForNum( int ammonum ); - int AmmoAvailable( void ) const; - int AmmoInClip( void ) const; - void ResetAmmoClip( void ); - int ClipSize( void ) const; - int LowAmmo( void ) const; - int AmmoRequired( void ) const; - - virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; - virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); - - /** - * TDM: Attach an entity to the weapon's AF. Different than plain entity attachment - * Does not use position name for now - **/ - virtual void Attach( idEntity *ent, const char *PosName = NULL, const char *AttName = NULL ); - - enum { - EVENT_RELOAD = idEntity::EVENT_MAXEVENTS, - EVENT_ENDRELOAD, - EVENT_CHANGESKIN, - EVENT_MAXEVENTS - }; - virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg ); - - virtual void ClientPredictionThink( void ); - - /** - * TDM: Return true if this is a ranged weapon - **/ - bool IsRanged(); - -protected: - /** - * Used internally by the Attach methods. - * Offset and axis are filled with the correct offset and axis - * for attaching to a particular joint. - * Overloaded to call GetJointGlobalTransform on idWeapon entities. - **/ - virtual void GetAttachingTransform( jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis ); - -private: - // script control - idScriptBool WEAPON_ATTACK; - idScriptBool WEAPON_BLOCK; - idScriptBool WEAPON_RELOAD; - idScriptBool WEAPON_NETRELOAD; - idScriptBool WEAPON_NETENDRELOAD; - idScriptBool WEAPON_NETFIRING; - idScriptBool WEAPON_RAISEWEAPON; - idScriptBool WEAPON_LOWERWEAPON; - weaponStatus_t status; - idThread * thread; - idStr state; - idStr idealState; - int animBlendFrames; - /** - * TDM: animDoneTime no longer used, but keep it around - * for compatibility with future patches/engines - **/ - int animDoneTime; - bool isLinked; - - // precreated projectile - idEntity *projectileEnt; - - idPlayer * owner; - idEntityPtr worldModel; - - // hiding (for GUIs and NPCs) - int hideTime; - float hideDistance; - int hideStartTime; - float hideStart; - float hideEnd; - float hideOffset; - bool hide; - bool disabled; - - // berserk - int berserk; - - // these are the player render view parms, which include bobbing - idVec3 playerViewOrigin; - idMat3 playerViewAxis; - - // the view weapon render entity parms - idVec3 viewWeaponOrigin; - idMat3 viewWeaponAxis; - - // the muzzle bone's position, used for launching projectiles and trailing smoke - idVec3 muzzleOrigin; - idMat3 muzzleAxis; - - idVec3 pushVelocity; - - // weapon definition - // we maintain local copies of the projectile and brass dictionaries so they - // do not have to be copied across the DLL boundary when entities are spawned - const idDeclEntityDef * weaponDef; - const idDeclEntityDef * meleeDef; - - // greebo: This is not needed anymore - the projectile dictionary is requested when it's actually needed - //idDict projectileDict; - float meleeDistance; - idStr meleeDefName; - idDict brassDict; - int brassDelay; - idStr icon; - - // view weapon gui light - renderLight_t guiLight; - int guiLightHandle; - - // muzzle flash - renderLight_t muzzleFlash; // positioned on view weapon bone - int muzzleFlashHandle; - - renderLight_t worldMuzzleFlash; // positioned on world weapon bone - int worldMuzzleFlashHandle; - - idVec3 flashColor; - int muzzleFlashEnd; - int flashTime; - bool lightOn; - bool allowDrop; - - int hideUntilTime; // grayman #597 - keep hidden until timer expires (for arrow spawning) - - // effects - bool hasBloodSplat; - - // weapon kick - int kick_endtime; - int muzzle_kick_time; - int muzzle_kick_maxtime; - idAngles muzzle_kick_angles; - idVec3 muzzle_kick_offset; - - // ammo management - int ammoRequired; // amount of ammo to use each shot. 0 means weapon doesn't need ammo. - int clipSize; // 0 means no reload - int ammoClip; - int lowAmmo; // if ammo in clip hits this threshold, snd_ - bool powerAmmo; // true if the clip reduction is a factor of the power setting when - // a projectile is launched - // mp client - bool isFiring; - - // zoom - int zoomFov; // variable zoom fov per weapon - - // joints from models - jointHandle_t barrelJointView; - jointHandle_t flashJointView; - jointHandle_t ejectJointView; - jointHandle_t guiLightJointView; - jointHandle_t ventLightJointView; - - jointHandle_t flashJointWorld; - jointHandle_t barrelJointWorld; - jointHandle_t ejectJointWorld; - - // sound - const idSoundShader * sndHum; - - // new style muzzle smokes - const idDeclParticle * weaponSmoke; // null if it doesn't smoke - int weaponSmokeStartTime; // set to gameLocal.time every weapon fire - bool continuousSmoke; // if smoke is continuous ( chainsaw ) - const idDeclParticle * strikeSmoke; // striking something in melee - int strikeSmokeStartTime; // timing - idVec3 strikePos; // position of last melee strike - idMat3 strikeAxis; // axis of last melee strike - int nextStrikeFx; // used for sound and decal ( may use for strike smoke too ) - - // nozzle effects - bool nozzleFx; // does this use nozzle effects ( parm5 at rest, parm6 firing ) - // this also assumes a nozzle light atm - int nozzleFxFade; // time it takes to fade between the effects - int lastAttack; // last time an attack occurred - int lastBlock; // last time a block occurred - renderLight_t nozzleGlow; // nozzle light - int nozzleGlowHandle; // handle for nozzle light - - idVec3 nozzleGlowColor; // color of the nozzle glow - const idMaterial * nozzleGlowShader; // shader for glow light - float nozzleGlowRadius; // radius of glow light - - // weighting for viewmodel angles - int weaponAngleOffsetAverages; - float weaponAngleOffsetScale; - float weaponAngleOffsetMax; - float weaponOffsetTime; - float weaponOffsetScale; - - // weapon switching - bool arrow2Arrow; // grayman #597 - - // flashlight - void AlertMonsters( void ); - - // Visual presentation - void InitWorldModel( const idDeclEntityDef *def ); - void MuzzleFlashLight( void ); - void MuzzleRise( idVec3 &origin, idMat3 &axis ); - void UpdateNozzleFx( void ); - void UpdateFlashPosition( void ); - - // script events - void Event_Clear( void ); - void Event_GetOwner( void ); - void Event_WeaponState( const char *statename, int blendFrames ); - void Event_SetWeaponStatus( float newStatus ); - void Event_WeaponReady( void ); - void Event_WeaponOutOfAmmo( void ); - void Event_WeaponReloading( void ); - void Event_WeaponHolstered( void ); - void Event_WeaponRising( void ); - void Event_WeaponLowering( void ); - void Event_UseAmmo( int amount ); - void Event_AddToClip( int amount ); - void Event_AmmoInClip( void ); - void Event_AmmoAvailable( void ); - void Event_TotalAmmoCount( void ); - void Event_ClipSize( void ); - void Event_PlayAnim( int channel, const char *animname ); - void Event_PauseAnim( int channel, bool bPause ); - void Event_AnimIsPaused( int channel ); - void Event_PlayCycle( int channel, const char *animname ); - void Event_AnimDone( int channel, int blendFrames ); - void Event_SetBlendFrames( int channel, int blendFrames ); - void Event_GetBlendFrames( int channel ); - void Event_Next( void ); - void Event_SetSkin( const char *skinname ); -/** -* TDM: Show or hide the weapon attachments -* The first argument is an index to the attachments list, starting at 1 -* Second argument is set to true if it should be shown, false for hiding. -**/ - void Event_ShowAttachment( int id, bool bShow ); - - void Event_Flashlight( int enable ); - void Event_GetLightParm( int parmnum ); - void Event_SetLightParm( int parmnum, float value ); - void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 ); - void Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ); - void Event_CreateProjectile( void ); - void Event_EjectBrass( void ); - void Event_Melee( void ); - void Event_GetWorldModel( void ); - void Event_AllowDrop( int allow ); - void Event_AutoReload( void ); - void Event_NetReload( void ); - void Event_IsInvisible( void ); - void Event_NetEndReload( void ); -}; - -ID_INLINE bool idWeapon::IsLinked( void ) { - return isLinked; -} - -ID_INLINE bool idWeapon::IsWorldModelReady( void ) { - return ( worldModel.GetEntity() != NULL ); -} - -ID_INLINE idPlayer* idWeapon::GetOwner( void ) { - return owner; -} - -#endif /* !__GAME_WEAPON_H__ */ diff --git a/game/worldspawn.cpp b/game/worldspawn.cpp deleted file mode 100644 index 1e77e1e6c..000000000 --- a/game/worldspawn.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// -/* -game_worldspawn.cpp - -Worldspawn class. Each map has one worldspawn which handles global spawnargs. - -*/ - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "game_local.h" - -/* -================ -idWorldspawn - -Every map should have exactly one worldspawn. -================ -*/ -CLASS_DECLARATION( idEntity, idWorldspawn ) - EVENT( EV_Remove, idWorldspawn::Event_Remove ) - EVENT( EV_SafeRemove, idWorldspawn::Event_Remove ) -END_CLASS - -/* -================ -idWorldspawn::Spawn -================ -*/ -void idWorldspawn::Spawn( void ) { - idStr scriptname; - idThread *thread; - const function_t *func; - const idKeyValue *kv; - - assert( gameLocal.world == NULL ); - gameLocal.world = this; - - g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); - - // Commented out by Dram. TDM does not use stamina - /* - // disable stamina on hell levels - if ( spawnArgs.GetBool( "no_stamina" ) ) { - pm_stamina.SetFloat( 0.0f ); - }*/ - - // load script - scriptname = gameLocal.GetMapName(); - scriptname.SetFileExtension( ".script" ); - if ( fileSystem->ReadFile( scriptname, NULL, NULL ) > 0 ) { - gameLocal.program.CompileFile( scriptname ); - - // call the main function by default - func = gameLocal.program.FindFunction( "main" ); - if ( func != NULL ) { - thread = new idThread( func ); - thread->DelayedStart( 0 ); - } - } - - // call any functions specified in worldspawn - kv = spawnArgs.MatchPrefix( "call" ); - while( kv != NULL ) { - func = gameLocal.program.FindFunction( kv->GetValue() ); - if ( func == NULL ) { - gameLocal.Error( "Function '%s' not found in script for '%s' key on worldspawn", kv->GetValue().c_str(), kv->GetKey().c_str() ); - } - - thread = new idThread( func ); - thread->DelayedStart( 0 ); - kv = spawnArgs.MatchPrefix( "call", kv ); - } - - // activate worldspawn's targets when it spawns - PostEventMS( &EV_ActivateTargets, 0, this ); -} - -/* -================= -idWorldspawn::Save -================= -*/ -void idWorldspawn::Save( idRestoreGame *savefile ) { -} - -/* -================= -idWorldspawn::Restore -================= -*/ -void idWorldspawn::Restore( idRestoreGame *savefile ) { - assert( gameLocal.world == this ); - - g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); - - // Commented out by Dram. TDM does not use stamina - /*// disable stamina on hell levels - if ( spawnArgs.GetBool( "no_stamina" ) ) { - pm_stamina.SetFloat( 0.0f ); - }*/ -} - -/* -================ -idWorldspawn::~idWorldspawn -================ -*/ -idWorldspawn::~idWorldspawn() { - if ( gameLocal.world == this ) { - gameLocal.world = NULL; - } -} - -/* -================ -idWorldspawn::Event_Remove -================ -*/ -void idWorldspawn::Event_Remove( void ) { - gameLocal.Error( "Tried to remove world" ); -} diff --git a/game/worldspawn.h b/game/worldspawn.h deleted file mode 100644 index 875db38ef..000000000 --- a/game/worldspawn.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __GAME_WORLDSPAWN_H__ -#define __GAME_WORLDSPAWN_H__ - -/* -=============================================================================== - - World entity. - -=============================================================================== -*/ - -class idWorldspawn : public idEntity { -public: - CLASS_PROTOTYPE( idWorldspawn ); - - virtual ~idWorldspawn(); - - void Spawn( void ); - - void Save( idRestoreGame *savefile ); - void Restore( idRestoreGame *savefile ); - -private: - void Event_Remove( void ); -}; - -#endif /* !__GAME_WORLDSPAWN_H__ */ diff --git a/idlib.vcproj b/idlib.vcproj deleted file mode 100644 index cc35127d4..000000000 --- a/idlib.vcproj +++ /dev/null @@ -1,956 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/idlib.vcxproj b/idlib.vcxproj new file mode 100644 index 000000000..03527fdea --- /dev/null +++ b/idlib.vcxproj @@ -0,0 +1,297 @@ + + + + + Debug with inlines and memory log + Win32 + + + Debug with inlines + Win32 + + + Debug + Win32 + + + Dedicated Debug with inlines + Win32 + + + Dedicated Debug + Win32 + + + Dedicated Release + Win32 + + + Release + Win32 + + + + idLib + {49BEC5C6-B964-417A-851E-808886B57400} + idLib + + + + + + + Win32Proj + + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idlib.vcxproj.filters b/idlib.vcxproj.filters new file mode 100644 index 000000000..9047c96a4 --- /dev/null +++ b/idlib.vcxproj.filters @@ -0,0 +1,352 @@ + + + + + {a85fe24a-a784-4008-b54e-5406119c0b8f} + + + {a7fe620c-8364-44be-abff-34f068c7d96f} + + + {3fa21a20-3848-4086-a2e6-816081637779} + + + {10198dd0-bb10-4111-bcd5-5565e4ff61f9} + + + {79062996-1084-4896-b49b-fc6280e388ce} + + + {767fafaf-96d2-4d2b-b4d8-479344d8537c} + + + + + BV + + + BV + + + BV + + + BV + + + Containers + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Hashing + + + Hashing + + + Hashing + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Text + + + Text + + + Text + + + Text + + + Text + + + Text + + + + + + + + + + + + + BV + + + BV + + + BV + + + BV + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Containers + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Geometry + + + Hashing + + + Hashing + + + Hashing + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Math + + + Text + + + Text + + + Text + + + Text + + + Text + + + Text + + + + + + + + + + + \ No newline at end of file diff --git a/idlib/Base64.cpp b/idlib/Base64.cpp new file mode 100644 index 000000000..1274e3d6d --- /dev/null +++ b/idlib/Base64.cpp @@ -0,0 +1,233 @@ + +#include "precompiled.h" +#pragma hdrstop + +/* +Copyright (c) 1996 Lars Wirzenius. All rights reserved. + +June 14 2003: TTimo + modified + endian bug fixes + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=197039 + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +============ +idBase64::Encode +============ +*/ +static const char sixtet_to_base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +void idBase64::Encode( const byte *from, int size ) { + int i, j; + unsigned long w; + byte *to; + + EnsureAlloced( 4*(size+3)/3 + 2 ); // ratio and padding + trailing \0 + to = data; + + w = 0; + i = 0; + while (size > 0) { + w |= *from << i*8; + ++from; + --size; + ++i; + if (size == 0 || i == 3) { + byte out[4]; + SixtetsForInt( out, w ); + for (j = 0; j*6 < i*8; ++j) { + *to++ = sixtet_to_base64[ out[j] ]; + } + if (size == 0) { + for (j = i; j < 3; ++j) { + *to++ = '='; + } + } + w = 0; + i = 0; + } + } + + *to++ = '\0'; + len = to - data; +} + +/* +============ +idBase64::DecodeLength +returns the minimum size in bytes of the target buffer for decoding +4 base64 digits <-> 3 bytes +============ +*/ +int idBase64::DecodeLength( void ) const { + return 3*len/4; +} + +/* +============ +idBase64::Decode +============ +*/ +int idBase64::Decode( byte *to ) const { + unsigned long w; + int i, j; + size_t n; + static char base64_to_sixtet[256]; + static int tab_init = 0; + byte *from = data; + + if (!tab_init) { + memset( base64_to_sixtet, 0, 256 ); + for (i = 0; (j = sixtet_to_base64[i]) != '\0'; ++i) { + base64_to_sixtet[j] = i; + } + tab_init = 1; + } + + w = 0; + i = 0; + n = 0; + byte in[4] = {0,0,0,0}; + while (*from != '\0' && *from != '=' ) { + if (*from == ' ' || *from == '\n') { + ++from; + continue; + } + in[i] = base64_to_sixtet[* (unsigned char *) from]; + ++i; + ++from; + if (*from == '\0' || *from == '=' || i == 4) { + w = IntForSixtets( in ); + for (j = 0; j*8 < i*6; ++j) { + *to++ = w & 0xff; + ++n; + w >>= 8; + } + i = 0; + w = 0; + } + } + return n; +} + +/* +============ +idBase64::Encode +============ +*/ +void idBase64::Encode( const idStr &src ) { + Encode( (const byte *)src.c_str(), src.Length() ); +} + +/* +============ +idBase64::Decode +============ +*/ +void idBase64::Decode( idStr &dest ) const { + byte *buf = new byte[ DecodeLength()+1 ]; // +1 for trailing \0 + int out = Decode( buf ); + buf[out] = '\0'; + dest = (const char *)buf; + delete[] buf; +} + +/* +============ +idBase64::Decode +============ +*/ +void idBase64::Decode( idFile *dest ) const { + byte *buf = new byte[ DecodeLength()+1 ]; // +1 for trailing \0 + int out = Decode( buf ); + dest->Write( buf, out ); + delete[] buf; +} + +#if 0 + +void idBase64_TestBase64() { + + idStr src; + idBase64 dest; + src = "Encode me in base64"; + dest.Encode( src ); + idLib::common->Printf( "%s -> %s\n", src.c_str(), dest.c_str() ); + dest.Decode( src ); + idLib::common->Printf( "%s -> %s\n", dest.c_str(), src.c_str() ); + + idDict src_dict; + src_dict.SetFloat("float", 0.5f); + src_dict.SetBool("bool", true); + src_dict.Set("value", "foo"); + idFile_Memory src_fmem("serialize_dict"); + src_dict.WriteToFileHandle( &src_fmem ); + dest.Encode( (const byte *)src_fmem.GetDataPtr(), src_fmem.Length() ); + idLib::common->Printf( "idDict encoded to %s\n", dest.c_str()); + + // now decode to another stream and build back + idFile_Memory dest_fmem( "build_back" ); + dest.Decode( &dest_fmem ); + dest_fmem.MakeReadOnly(); + idDict dest_dict; + dest_dict.ReadFromFileHandle( &dest_fmem ); + idLib::common->Printf( "idDict reconstructed after base64 decode\n"); + dest_dict.Print(); + + // test idDict read from file - from python generated files, see idDict.py + idFile *file = idLib::fileSystem->OpenFileRead("idDict.test"); + if (file) { + idDict test_dict; + test_dict.ReadFromFileHandle( file ); + // + idLib::common->Printf( "read idDict.test:\n"); + test_dict.Print(); + idLib::fileSystem->CloseFile(file); + file = NULL; + } else { + idLib::common->Printf( "idDict.test not found\n" ); + } + + idBase64 base64_src; + void *buffer; + if ( idLib::fileSystem->ReadFile( "idDict.base64.test", &buffer ) != -1 ) { + idFile_Memory mem_src( "dict" ); + idLib::common->Printf( "read: %d %s\n", idStr::Length( (char*)buffer ), buffer ); + base64_src = (char *)buffer; + base64_src.Decode( &mem_src ); + mem_src.MakeReadOnly(); + idDict test_dict; + test_dict.ReadFromFileHandle( &mem_src ); + idLib::common->Printf( "read idDict.base64.test:\n"); + test_dict.Print(); + idLib::fileSystem->FreeFile( buffer ); + } else { + idLib::common->Printf( "idDict.base64.test not found\n" ); + } +} + +#endif diff --git a/idlib/Base64.h b/idlib/Base64.h new file mode 100644 index 000000000..460a37704 --- /dev/null +++ b/idlib/Base64.h @@ -0,0 +1,102 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BASE64_H__ +#define __BASE64_H__ + +/* +=============================================================================== + + base64 + +=============================================================================== +*/ + +class idBase64 { +public: + idBase64( void ); + idBase64( const idStr &s ); + ~idBase64( void ); + + void Encode( const byte *from, int size ); + void Encode( const idStr &src ); + int DecodeLength( void ) const; // minimum size in bytes of destination buffer for decoding + int Decode( byte *to ) const; // does not append a \0 - needs a DecodeLength() bytes buffer + void Decode( idStr &dest ) const; // decodes the binary content to an idStr (a bit dodgy, \0 and other non-ascii are possible in the decoded content) + void Decode( idFile *dest ) const; + + const char *c_str() const; + + void operator=( const idStr &s ); + +private: + byte * data; + int len; + int alloced; + + void Init( void ); + void Release( void ); + void EnsureAlloced( int size ); +}; + +ID_INLINE idBase64::idBase64( void ) { + Init(); +} + +ID_INLINE idBase64::idBase64( const idStr &s ) { + Init(); + *this = s; +} + +ID_INLINE idBase64::~idBase64( void ) { + Release(); +} + +ID_INLINE const char *idBase64::c_str( void ) const { + return (const char *)data; +} + +ID_INLINE void idBase64::Init( void ) { + len = 0; + alloced = 0; + data = NULL; +} + +ID_INLINE void idBase64::Release( void ) { + if ( data ) { + delete[] data; + } + Init(); +} + +ID_INLINE void idBase64::EnsureAlloced( int size ) { + if ( size > alloced ) { + Release(); + } + data = new byte[size]; + alloced = size; +} + +ID_INLINE void idBase64::operator=( const idStr &s ) { + EnsureAlloced( s.Length()+1 ); // trailing \0 - beware, this does a Release + strcpy( (char *)data, s.c_str() ); + len = s.Length(); +} + +#endif /* !__BASE64_H__ */ diff --git a/idlib/BitMsg.cpp b/idlib/BitMsg.cpp new file mode 100644 index 000000000..30a1cec99 --- /dev/null +++ b/idlib/BitMsg.cpp @@ -0,0 +1,1058 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + +/* +============================================================================== + + idBitMsg + +============================================================================== +*/ + +/* +================ +idBitMsg::idBitMsg +================ +*/ +idBitMsg::idBitMsg() { + writeData = NULL; + readData = NULL; + maxSize = 0; + curSize = 0; + writeBit = 0; + readCount = 0; + readBit = 0; + allowOverflow = false; + overflowed = false; +} + +/* +================ +idBitMsg::CheckOverflow +================ +*/ +bool idBitMsg::CheckOverflow( int numBits ) { + assert( numBits >= 0 ); + if ( numBits > GetRemainingWriteBits() ) { + if ( !allowOverflow ) { + idLib::common->FatalError( "idBitMsg: overflow without allowOverflow set" ); + } + if ( numBits > ( maxSize << 3 ) ) { + idLib::common->FatalError( "idBitMsg: %i bits is > full message size", numBits ); + } + idLib::common->Printf( "idBitMsg: overflow\n" ); + BeginWriting(); + overflowed = true; + return true; + } + return false; +} + +/* +================ +idBitMsg::GetByteSpace +================ +*/ +byte *idBitMsg::GetByteSpace( int length ) { + byte *ptr; + + if ( !writeData ) { + idLib::common->FatalError( "idBitMsg::GetByteSpace: cannot write to message" ); + } + + // round up to the next byte + WriteByteAlign(); + + // check for overflow + CheckOverflow( length << 3 ); + + ptr = writeData + curSize; + curSize += length; + return ptr; +} + +/* +================ +idBitMsg::WriteBits + + If the number of bits is negative a sign is included. +================ +*/ +void idBitMsg::WriteBits( int value, int numBits ) { + int put; + int fraction; + + if ( !writeData ) { + idLib::common->Error( "idBitMsg::WriteBits: cannot write to message" ); + } + + // check if the number of bits is valid + if ( numBits == 0 || numBits < -31 || numBits > 32 ) { + idLib::common->Error( "idBitMsg::WriteBits: bad numBits %i", numBits ); + } + + // check for value overflows + // this should be an error really, as it can go unnoticed and cause either bandwidth or corrupted data transmitted + if ( numBits != 32 ) { + if ( numBits > 0 ) { + if ( value > ( 1 << numBits ) - 1 ) { + idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); + } else if ( value < 0 ) { + idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); + } + } else { + int r = 1 << ( - 1 - numBits ); + if ( value > r - 1 ) { + idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); + } else if ( value < -r ) { + idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); + } + } + } + + if ( numBits < 0 ) { + numBits = -numBits; + } + + // check for msg overflow + if ( CheckOverflow( numBits ) ) { + return; + } + + // write the bits + while( numBits ) { + if ( writeBit == 0 ) { + writeData[curSize] = 0; + curSize++; + } + put = 8 - writeBit; + if ( put > numBits ) { + put = numBits; + } + fraction = value & ( ( 1 << put ) - 1 ); + writeData[curSize - 1] |= fraction << writeBit; + numBits -= put; + value >>= put; + writeBit = ( writeBit + put ) & 7; + } +} + +/* +================ +idBitMsg::WriteString +================ +*/ +void idBitMsg::WriteString( const char *s, int maxLength, bool make7Bit ) { + if ( !s ) { + WriteData( "", 1 ); + } else { + int i, l; + byte *dataPtr; + const byte *bytePtr; + + l = idStr::Length( s ); + if ( maxLength >= 0 && l >= maxLength ) { + l = maxLength - 1; + } + dataPtr = GetByteSpace( l + 1 ); + bytePtr = reinterpret_cast(s); + if ( make7Bit ) { + for ( i = 0; i < l; i++ ) { + if ( bytePtr[i] > 127 ) { + dataPtr[i] = '.'; + } else { + dataPtr[i] = bytePtr[i]; + } + } + } else { + for ( i = 0; i < l; i++ ) { + dataPtr[i] = bytePtr[i]; + } + } + dataPtr[i] = '\0'; + } +} + +/* +================ +idBitMsg::WriteData +================ +*/ +void idBitMsg::WriteData( const void *data, int length ) { + memcpy( GetByteSpace( length ), data, length ); +} + +/* +================ +idBitMsg::WriteNetadr +================ +*/ +void idBitMsg::WriteNetadr( const netadr_t adr ) { + byte *dataPtr; + dataPtr = GetByteSpace( 4 ); + memcpy( dataPtr, adr.ip, 4 ); + WriteUShort( adr.port ); +} + +/* +================ +idBitMsg::WriteDelta +================ +*/ +void idBitMsg::WriteDelta( int oldValue, int newValue, int numBits ) { + if ( oldValue == newValue ) { + WriteBits( 0, 1 ); + return; + } + WriteBits( 1, 1 ); + WriteBits( newValue, numBits ); +} + +/* +================ +idBitMsg::WriteDeltaByteCounter +================ +*/ +void idBitMsg::WriteDeltaByteCounter( int oldValue, int newValue ) { + int i, x; + + x = oldValue ^ newValue; + for ( i = 7; i > 0; i-- ) { + if ( x & ( 1 << i ) ) { + i++; + break; + } + } + WriteBits( i, 3 ); + if ( i ) { + WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); + } +} + +/* +================ +idBitMsg::WriteDeltaShortCounter +================ +*/ +void idBitMsg::WriteDeltaShortCounter( int oldValue, int newValue ) { + int i, x; + + x = oldValue ^ newValue; + for ( i = 15; i > 0; i-- ) { + if ( x & ( 1 << i ) ) { + i++; + break; + } + } + WriteBits( i, 4 ); + if ( i ) { + WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); + } +} + +/* +================ +idBitMsg::WriteDeltaLongCounter +================ +*/ +void idBitMsg::WriteDeltaLongCounter( int oldValue, int newValue ) { + int i, x; + + x = oldValue ^ newValue; + for ( i = 31; i > 0; i-- ) { + if ( x & ( 1 << i ) ) { + i++; + break; + } + } + WriteBits( i, 5 ); + if ( i ) { + WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); + } +} + +/* +================== +idBitMsg::WriteDeltaDict +================== +*/ +bool idBitMsg::WriteDeltaDict( const idDict &dict, const idDict *base ) { + int i; + const idKeyValue *kv, *basekv; + bool changed = false; + + if ( base != NULL ) { + + for ( i = 0; i < dict.GetNumKeyVals(); i++ ) { + kv = dict.GetKeyVal( i ); + basekv = base->FindKey( kv->GetKey() ); + if ( basekv == NULL || basekv->GetValue().Icmp( kv->GetValue() ) != 0 ) { + WriteString( kv->GetKey() ); + WriteString( kv->GetValue() ); + changed = true; + } + } + + WriteString( "" ); + + for ( i = 0; i < base->GetNumKeyVals(); i++ ) { + basekv = base->GetKeyVal( i ); + kv = dict.FindKey( basekv->GetKey() ); + if ( kv == NULL ) { + WriteString( basekv->GetKey() ); + changed = true; + } + } + + WriteString( "" ); + + } else { + + for ( i = 0; i < dict.GetNumKeyVals(); i++ ) { + kv = dict.GetKeyVal( i ); + WriteString( kv->GetKey() ); + WriteString( kv->GetValue() ); + changed = true; + } + WriteString( "" ); + + WriteString( "" ); + + } + + return changed; +} + +/* +================ +idBitMsg::ReadBits + + If the number of bits is negative a sign is included. +================ +*/ +int idBitMsg::ReadBits( int numBits ) const { + int value; + int valueBits; + int get; + int fraction; + bool sgn; + + if ( !readData ) { + idLib::common->FatalError( "idBitMsg::ReadBits: cannot read from message" ); + } + + // check if the number of bits is valid + if ( numBits == 0 || numBits < -31 || numBits > 32 ) { + idLib::common->FatalError( "idBitMsg::ReadBits: bad numBits %i", numBits ); + } + + value = 0; + valueBits = 0; + + if ( numBits < 0 ) { + numBits = -numBits; + sgn = true; + } else { + sgn = false; + } + + // check for overflow + if ( numBits > GetRemainingReadBits() ) { + return -1; + } + + while ( valueBits < numBits ) { + if ( readBit == 0 ) { + readCount++; + } + get = 8 - readBit; + if ( get > (numBits - valueBits) ) { + get = numBits - valueBits; + } + fraction = readData[readCount - 1]; + fraction >>= readBit; + fraction &= ( 1 << get ) - 1; + value |= fraction << valueBits; + + valueBits += get; + readBit = ( readBit + get ) & 7; + } + + if ( sgn ) { + if ( value & ( 1 << ( numBits - 1 ) ) ) { + value |= -1 ^ ( ( 1 << numBits ) - 1 ); + } + } + + return value; +} + +/* +================ +idBitMsg::ReadString +================ +*/ +int idBitMsg::ReadString( char *buffer, int bufferSize ) const { + int l, c; + + ReadByteAlign(); + l = 0; + while( 1 ) { + c = ReadByte(); + if ( c <= 0 || c >= 255 ) { + break; + } + // translate all fmt spec to avoid crash bugs in string routines + if ( c == '%' ) { + c = '.'; + } + + // we will read past any excessively long string, so + // the following data can be read, but the string will + // be truncated + if ( l < bufferSize - 1 ) { + buffer[l] = c; + l++; + } + } + + buffer[l] = 0; + return l; +} + +/* +================ +idBitMsg::ReadData +================ +*/ +int idBitMsg::ReadData( void *data, int length ) const { + int cnt; + + ReadByteAlign(); + cnt = readCount; + + if ( readCount + length > curSize ) { + if ( data ) { + memcpy( data, readData + readCount, GetRemaingData() ); + } + readCount = curSize; + } else { + if ( data ) { + memcpy( data, readData + readCount, length ); + } + readCount += length; + } + + return ( readCount - cnt ); +} + +/* +================ +idBitMsg::ReadNetadr +================ +*/ +void idBitMsg::ReadNetadr( netadr_t *adr ) const { + int i; + + adr->type = NA_IP; + for ( i = 0; i < 4; i++ ) { + adr->ip[ i ] = ReadByte(); + } + adr->port = ReadUShort(); +} + +/* +================ +idBitMsg::ReadDelta +================ +*/ +int idBitMsg::ReadDelta( int oldValue, int numBits ) const { + if ( ReadBits( 1 ) ) { + return ReadBits( numBits ); + } + return oldValue; +} + +/* +================ +idBitMsg::ReadDeltaByteCounter +================ +*/ +int idBitMsg::ReadDeltaByteCounter( int oldValue ) const { + int i, newValue; + + i = ReadBits( 3 ); + if ( !i ) { + return oldValue; + } + newValue = ReadBits( i ); + return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); +} + +/* +================ +idBitMsg::ReadDeltaShortCounter +================ +*/ +int idBitMsg::ReadDeltaShortCounter( int oldValue ) const { + int i, newValue; + + i = ReadBits( 4 ); + if ( !i ) { + return oldValue; + } + newValue = ReadBits( i ); + return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); +} + +/* +================ +idBitMsg::ReadDeltaLongCounter +================ +*/ +int idBitMsg::ReadDeltaLongCounter( int oldValue ) const { + int i, newValue; + + i = ReadBits( 5 ); + if ( !i ) { + return oldValue; + } + newValue = ReadBits( i ); + return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); +} + +/* +================== +idBitMsg::ReadDeltaDict +================== +*/ +bool idBitMsg::ReadDeltaDict( idDict &dict, const idDict *base ) const { + char key[MAX_STRING_CHARS]; + char value[MAX_STRING_CHARS]; + bool changed = false; + + if ( base != NULL ) { + dict = *base; + } else { + dict.Clear(); + } + + while( ReadString( key, sizeof( key ) ) != 0 ) { + ReadString( value, sizeof( value ) ); + dict.Set( key, value ); + changed = true; + } + + while( ReadString( key, sizeof( key ) ) != 0 ) { + dict.Delete( key ); + changed = true; + } + + return changed; +} + +/* +================ +idBitMsg::DirToBits +================ +*/ +int idBitMsg::DirToBits( const idVec3 &dir, int numBits ) { + int max, bits; + float bias; + + assert( numBits >= 6 && numBits <= 32 ); + assert( dir.LengthSqr() - 1.0f < 0.01f ); + + numBits /= 3; + max = ( 1 << ( numBits - 1 ) ) - 1; + bias = 0.5f / max; + + bits = FLOATSIGNBITSET( dir.x ) << ( numBits * 3 - 1 ); + bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.x ) + bias ) * max ) ) << ( numBits * 2 ); + bits |= FLOATSIGNBITSET( dir.y ) << ( numBits * 2 - 1 ); + bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.y ) + bias ) * max ) ) << ( numBits * 1 ); + bits |= FLOATSIGNBITSET( dir.z ) << ( numBits * 1 - 1 ); + bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.z ) + bias ) * max ) ) << ( numBits * 0 ); + return bits; +} + +/* +================ +idBitMsg::BitsToDir +================ +*/ +idVec3 idBitMsg::BitsToDir( int bits, int numBits ) { + static float sign[2] = { 1.0f, -1.0f }; + int max; + float invMax; + idVec3 dir; + + assert( numBits >= 6 && numBits <= 32 ); + + numBits /= 3; + max = ( 1 << ( numBits - 1 ) ) - 1; + invMax = 1.0f / max; + + dir.x = sign[( bits >> ( numBits * 3 - 1 ) ) & 1] * ( ( bits >> ( numBits * 2 ) ) & max ) * invMax; + dir.y = sign[( bits >> ( numBits * 2 - 1 ) ) & 1] * ( ( bits >> ( numBits * 1 ) ) & max ) * invMax; + dir.z = sign[( bits >> ( numBits * 1 - 1 ) ) & 1] * ( ( bits >> ( numBits * 0 ) ) & max ) * invMax; + dir.NormalizeFast(); + return dir; +} + + +/* +============================================================================== + + idBitMsgDelta + +============================================================================== +*/ + +const int MAX_DATA_BUFFER = 1024; + +/* +================ +idBitMsgDelta::WriteBits +================ +*/ +void idBitMsgDelta::WriteBits( int value, int numBits ) { + if ( newBase ) { + newBase->WriteBits( value, numBits ); + } + + if ( !base ) { + writeDelta->WriteBits( value, numBits ); + changed = true; + } else { + int baseValue = base->ReadBits( numBits ); + if ( baseValue == value ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteBits( value, numBits ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::WriteDelta +================ +*/ +void idBitMsgDelta::WriteDelta( int oldValue, int newValue, int numBits ) { + if ( newBase ) { + newBase->WriteBits( newValue, numBits ); + } + + if ( !base ) { + if ( oldValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteBits( newValue, numBits ); + } + changed = true; + } else { + int baseValue = base->ReadBits( numBits ); + if ( baseValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + if ( oldValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + changed = true; + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteBits( newValue, numBits ); + changed = true; + } + } + } +} + +/* +================ +idBitMsgDelta::ReadBits +================ +*/ +int idBitMsgDelta::ReadBits( int numBits ) const { + int value; + + if ( !base ) { + value = readDelta->ReadBits( numBits ); + changed = true; + } else { + int baseValue = base->ReadBits( numBits ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + value = baseValue; + } else { + value = readDelta->ReadBits( numBits ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteBits( value, numBits ); + } + return value; +} + +/* +================ +idBitMsgDelta::ReadDelta +================ +*/ +int idBitMsgDelta::ReadDelta( int oldValue, int numBits ) const { + int value; + + if ( !base ) { + if ( readDelta->ReadBits( 1 ) == 0 ) { + value = oldValue; + } else { + value = readDelta->ReadBits( numBits ); + } + changed = true; + } else { + int baseValue = base->ReadBits( numBits ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + value = baseValue; + } else if ( readDelta->ReadBits( 1 ) == 0 ) { + value = oldValue; + changed = true; + } else { + value = readDelta->ReadBits( numBits ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteBits( value, numBits ); + } + return value; +} + +/* +================ +idBitMsgDelta::WriteString +================ +*/ +void idBitMsgDelta::WriteString( const char *s, int maxLength ) { + if ( newBase ) { + newBase->WriteString( s, maxLength ); + } + + if ( !base ) { + writeDelta->WriteString( s, maxLength ); + changed = true; + } else { + char baseString[MAX_DATA_BUFFER]; + base->ReadString( baseString, sizeof( baseString ) ); + if ( idStr::Cmp( s, baseString ) == 0 ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteString( s, maxLength ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::WriteData +================ +*/ +void idBitMsgDelta::WriteData( const void *data, int length ) { + if ( newBase ) { + newBase->WriteData( data, length ); + } + + if ( !base ) { + writeDelta->WriteData( data, length ); + changed = true; + } else { + byte baseData[MAX_DATA_BUFFER]; + assert( length < sizeof( baseData ) ); + base->ReadData( baseData, length ); + if ( memcmp( data, baseData, length ) == 0 ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteData( data, length ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::WriteDict +================ +*/ +void idBitMsgDelta::WriteDict( const idDict &dict ) { + if ( newBase ) { + newBase->WriteDeltaDict( dict, NULL ); + } + + if ( !base ) { + writeDelta->WriteDeltaDict( dict, NULL ); + changed = true; + } else { + idDict baseDict; + base->ReadDeltaDict( baseDict, NULL ); + changed = writeDelta->WriteDeltaDict( dict, &baseDict ); + } +} + +/* +================ +idBitMsgDelta::WriteDeltaByteCounter +================ +*/ +void idBitMsgDelta::WriteDeltaByteCounter( int oldValue, int newValue ) { + if ( newBase ) { + newBase->WriteBits( newValue, 8 ); + } + + if ( !base ) { + writeDelta->WriteDeltaByteCounter( oldValue, newValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 8 ); + if ( baseValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteDeltaByteCounter( oldValue, newValue ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::WriteDeltaShortCounter +================ +*/ +void idBitMsgDelta::WriteDeltaShortCounter( int oldValue, int newValue ) { + if ( newBase ) { + newBase->WriteBits( newValue, 16 ); + } + + if ( !base ) { + writeDelta->WriteDeltaShortCounter( oldValue, newValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 16 ); + if ( baseValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteDeltaShortCounter( oldValue, newValue ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::WriteDeltaLongCounter +================ +*/ +void idBitMsgDelta::WriteDeltaLongCounter( int oldValue, int newValue ) { + if ( newBase ) { + newBase->WriteBits( newValue, 32 ); + } + + if ( !base ) { + writeDelta->WriteDeltaLongCounter( oldValue, newValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 32 ); + if ( baseValue == newValue ) { + writeDelta->WriteBits( 0, 1 ); + } else { + writeDelta->WriteBits( 1, 1 ); + writeDelta->WriteDeltaLongCounter( oldValue, newValue ); + changed = true; + } + } +} + +/* +================ +idBitMsgDelta::ReadString +================ +*/ +void idBitMsgDelta::ReadString( char *buffer, int bufferSize ) const { + if ( !base ) { + readDelta->ReadString( buffer, bufferSize ); + changed = true; + } else { + char baseString[MAX_DATA_BUFFER]; + base->ReadString( baseString, sizeof( baseString ) ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + idStr::Copynz( buffer, baseString, bufferSize ); + } else { + readDelta->ReadString( buffer, bufferSize ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteString( buffer ); + } +} + +/* +================ +idBitMsgDelta::ReadData +================ +*/ +void idBitMsgDelta::ReadData( void *data, int length ) const { + if ( !base ) { + readDelta->ReadData( data, length ); + changed = true; + } else { + char baseData[MAX_DATA_BUFFER]; + assert( length < sizeof( baseData ) ); + base->ReadData( baseData, length ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + memcpy( data, baseData, length ); + } else { + readDelta->ReadData( data, length ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteData( data, length ); + } +} + +/* +================ +idBitMsgDelta::ReadDict +================ +*/ +void idBitMsgDelta::ReadDict( idDict &dict ) { + if ( !base ) { + readDelta->ReadDeltaDict( dict, NULL ); + changed = true; + } else { + idDict baseDict; + base->ReadDeltaDict( baseDict, NULL ); + if ( !readDelta ) { + dict = baseDict; + } else { + changed = readDelta->ReadDeltaDict( dict, &baseDict ); + } + } + + if ( newBase ) { + newBase->WriteDeltaDict( dict, NULL ); + } +} + +/* +================ +idBitMsgDelta::ReadDeltaByteCounter +================ +*/ +int idBitMsgDelta::ReadDeltaByteCounter( int oldValue ) const { + int value; + + if ( !base ) { + value = readDelta->ReadDeltaByteCounter( oldValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 8 ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + value = baseValue; + } else { + value = readDelta->ReadDeltaByteCounter( oldValue ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteBits( value, 8 ); + } + return value; +} + +/* +================ +idBitMsgDelta::ReadDeltaShortCounter +================ +*/ +int idBitMsgDelta::ReadDeltaShortCounter( int oldValue ) const { + int value; + + if ( !base ) { + value = readDelta->ReadDeltaShortCounter( oldValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 16 ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + value = baseValue; + } else { + value = readDelta->ReadDeltaShortCounter( oldValue ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteBits( value, 16 ); + } + return value; +} + +/* +================ +idBitMsgDelta::ReadDeltaLongCounter +================ +*/ +int idBitMsgDelta::ReadDeltaLongCounter( int oldValue ) const { + int value; + + if ( !base ) { + value = readDelta->ReadDeltaLongCounter( oldValue ); + changed = true; + } else { + int baseValue = base->ReadBits( 32 ); + if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { + value = baseValue; + } else { + value = readDelta->ReadDeltaLongCounter( oldValue ); + changed = true; + } + } + + if ( newBase ) { + newBase->WriteBits( value, 32 ); + } + return value; +} diff --git a/idlib/BitMsg.h b/idlib/BitMsg.h new file mode 100644 index 000000000..41dbfba67 --- /dev/null +++ b/idlib/BitMsg.h @@ -0,0 +1,667 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BITMSG_H__ +#define __BITMSG_H__ + +/* +=============================================================================== + + idBitMsg + + Handles byte ordering and avoids alignment errors. + Allows concurrent writing and reading. + The data set with Init is never freed. + +=============================================================================== +*/ + +class idBitMsg { +public: + idBitMsg(); + ~idBitMsg() {} + + void Init( byte *data, int length ); + void Init( const byte *data, int length ); + byte * GetData( void ); // get data for writing + const byte * GetData( void ) const; // get data for reading + int GetMaxSize( void ) const; // get the maximum message size + void SetAllowOverflow( bool set ); // generate error if not set and message is overflowed + bool IsOverflowed( void ) const; // returns true if the message was overflowed + + int GetSize( void ) const; // size of the message in bytes + void SetSize( int size ); // set the message size + int GetWriteBit( void ) const; // get current write bit + void SetWriteBit( int bit ); // set current write bit + int GetNumBitsWritten( void ) const; // returns number of bits written + int GetRemainingWriteBits( void ) const; // space left in bits for writing + void SaveWriteState( int &s, int &b ) const; // save the write state + void RestoreWriteState( int s, int b ); // restore the write state + + int GetReadCount( void ) const; // bytes read so far + void SetReadCount( int bytes ); // set the number of bytes and bits read + int GetReadBit( void ) const; // get current read bit + void SetReadBit( int bit ); // set current read bit + int GetNumBitsRead( void ) const; // returns number of bits read + int GetRemainingReadBits( void ) const; // number of bits left to read + void SaveReadState( int &c, int &b ) const; // save the read state + void RestoreReadState( int c, int b ); // restore the read state + + void BeginWriting( void ); // begin writing + int GetRemainingSpace( void ) const; // space left in bytes + void WriteByteAlign( void ); // write up to the next byte boundary + void WriteBits( int value, int numBits ); // write the specified number of bits + void WriteChar( int c ); + void WriteByte( int c ); + void WriteShort( int c ); + void WriteUShort( int c ); + void WriteLong( int c ); + void WriteFloat( float f ); + void WriteFloat( float f, int exponentBits, int mantissaBits ); + void WriteAngle8( float f ); + void WriteAngle16( float f ); + void WriteDir( const idVec3 &dir, int numBits ); + void WriteString( const char *s, int maxLength = -1, bool make7Bit = true ); + void WriteData( const void *data, int length ); + void WriteNetadr( const netadr_t adr ); + + void WriteDeltaChar( int oldValue, int newValue ); + void WriteDeltaByte( int oldValue, int newValue ); + void WriteDeltaShort( int oldValue, int newValue ); + void WriteDeltaLong( int oldValue, int newValue ); + void WriteDeltaFloat( float oldValue, float newValue ); + void WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ); + void WriteDeltaByteCounter( int oldValue, int newValue ); + void WriteDeltaShortCounter( int oldValue, int newValue ); + void WriteDeltaLongCounter( int oldValue, int newValue ); + bool WriteDeltaDict( const idDict &dict, const idDict *base ); + + void BeginReading( void ) const; // begin reading. + int GetRemaingData( void ) const; // number of bytes left to read + void ReadByteAlign( void ) const; // read up to the next byte boundary + int ReadBits( int numBits ) const; // read the specified number of bits + int ReadChar( void ) const; + int ReadByte( void ) const; + int ReadShort( void ) const; + int ReadUShort( void ) const; + int ReadLong( void ) const; + float ReadFloat( void ) const; + float ReadFloat( int exponentBits, int mantissaBits ) const; + float ReadAngle8( void ) const; + float ReadAngle16( void ) const; + idVec3 ReadDir( int numBits ) const; + int ReadString( char *buffer, int bufferSize ) const; + int ReadData( void *data, int length ) const; + void ReadNetadr( netadr_t *adr ) const; + + int ReadDeltaChar( int oldValue ) const; + int ReadDeltaByte( int oldValue ) const; + int ReadDeltaShort( int oldValue ) const; + int ReadDeltaLong( int oldValue ) const; + float ReadDeltaFloat( float oldValue ) const; + float ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const; + int ReadDeltaByteCounter( int oldValue ) const; + int ReadDeltaShortCounter( int oldValue ) const; + int ReadDeltaLongCounter( int oldValue ) const; + bool ReadDeltaDict( idDict &dict, const idDict *base ) const; + + static int DirToBits( const idVec3 &dir, int numBits ); + static idVec3 BitsToDir( int bits, int numBits ); + +private: + byte * writeData; // pointer to data for writing + const byte * readData; // pointer to data for reading + int maxSize; // maximum size of message in bytes + int curSize; // current size of message in bytes + int writeBit; // number of bits written to the last written byte + mutable int readCount; // number of bytes read so far + mutable int readBit; // number of bits read from the last read byte + bool allowOverflow; // if false, generate an error when the message is overflowed + bool overflowed; // set to true if the buffer size failed (with allowOverflow set) + +private: + bool CheckOverflow( int numBits ); + byte * GetByteSpace( int length ); + void WriteDelta( int oldValue, int newValue, int numBits ); + int ReadDelta( int oldValue, int numBits ) const; +}; + + +ID_INLINE void idBitMsg::Init( byte *data, int length ) { + writeData = data; + readData = data; + maxSize = length; +} + +ID_INLINE void idBitMsg::Init( const byte *data, int length ) { + writeData = NULL; + readData = data; + maxSize = length; +} + +ID_INLINE byte *idBitMsg::GetData( void ) { + return writeData; +} + +ID_INLINE const byte *idBitMsg::GetData( void ) const { + return readData; +} + +ID_INLINE int idBitMsg::GetMaxSize( void ) const { + return maxSize; +} + +ID_INLINE void idBitMsg::SetAllowOverflow( bool set ) { + allowOverflow = set; +} + +ID_INLINE bool idBitMsg::IsOverflowed( void ) const { + return overflowed; +} + +ID_INLINE int idBitMsg::GetSize( void ) const { + return curSize; +} + +ID_INLINE void idBitMsg::SetSize( int size ) { + if ( size > maxSize ) { + curSize = maxSize; + } else { + curSize = size; + } +} + +ID_INLINE int idBitMsg::GetWriteBit( void ) const { + return writeBit; +} + +ID_INLINE void idBitMsg::SetWriteBit( int bit ) { + writeBit = bit & 7; + if ( writeBit ) { + writeData[curSize - 1] &= ( 1 << writeBit ) - 1; + } +} + +ID_INLINE int idBitMsg::GetNumBitsWritten( void ) const { + return ( ( curSize << 3 ) - ( ( 8 - writeBit ) & 7 ) ); +} + +ID_INLINE int idBitMsg::GetRemainingWriteBits( void ) const { + return ( maxSize << 3 ) - GetNumBitsWritten(); +} + +ID_INLINE void idBitMsg::SaveWriteState( int &s, int &b ) const { + s = curSize; + b = writeBit; +} + +ID_INLINE void idBitMsg::RestoreWriteState( int s, int b ) { + curSize = s; + writeBit = b & 7; + if ( writeBit ) { + writeData[curSize - 1] &= ( 1 << writeBit ) - 1; + } +} + +ID_INLINE int idBitMsg::GetReadCount( void ) const { + return readCount; +} + +ID_INLINE void idBitMsg::SetReadCount( int bytes ) { + readCount = bytes; +} + +ID_INLINE int idBitMsg::GetReadBit( void ) const { + return readBit; +} + +ID_INLINE void idBitMsg::SetReadBit( int bit ) { + readBit = bit & 7; +} + +ID_INLINE int idBitMsg::GetNumBitsRead( void ) const { + return ( ( readCount << 3 ) - ( ( 8 - readBit ) & 7 ) ); +} + +ID_INLINE int idBitMsg::GetRemainingReadBits( void ) const { + return ( curSize << 3 ) - GetNumBitsRead(); +} + +ID_INLINE void idBitMsg::SaveReadState( int &c, int &b ) const { + c = readCount; + b = readBit; +} + +ID_INLINE void idBitMsg::RestoreReadState( int c, int b ) { + readCount = c; + readBit = b & 7; +} + +ID_INLINE void idBitMsg::BeginWriting( void ) { + curSize = 0; + overflowed = false; + writeBit = 0; +} + +ID_INLINE int idBitMsg::GetRemainingSpace( void ) const { + return maxSize - curSize; +} + +ID_INLINE void idBitMsg::WriteByteAlign( void ) { + writeBit = 0; +} + +ID_INLINE void idBitMsg::WriteChar( int c ) { + WriteBits( c, -8 ); +} + +ID_INLINE void idBitMsg::WriteByte( int c ) { + WriteBits( c, 8 ); +} + +ID_INLINE void idBitMsg::WriteShort( int c ) { + WriteBits( c, -16 ); +} + +ID_INLINE void idBitMsg::WriteUShort( int c ) { + WriteBits( c, 16 ); +} + +ID_INLINE void idBitMsg::WriteLong( int c ) { + WriteBits( c, 32 ); +} + +ID_INLINE void idBitMsg::WriteFloat( float f ) { + WriteBits( *reinterpret_cast(&f), 32 ); +} + +ID_INLINE void idBitMsg::WriteFloat( float f, int exponentBits, int mantissaBits ) { + int bits = idMath::FloatToBits( f, exponentBits, mantissaBits ); + WriteBits( bits, 1 + exponentBits + mantissaBits ); +} + +ID_INLINE void idBitMsg::WriteAngle8( float f ) { + WriteByte( ANGLE2BYTE( f ) ); +} + +ID_INLINE void idBitMsg::WriteAngle16( float f ) { + WriteShort( ANGLE2SHORT(f) ); +} + +ID_INLINE void idBitMsg::WriteDir( const idVec3 &dir, int numBits ) { + WriteBits( DirToBits( dir, numBits ), numBits ); +} + +ID_INLINE void idBitMsg::WriteDeltaChar( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, -8 ); +} + +ID_INLINE void idBitMsg::WriteDeltaByte( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, 8 ); +} + +ID_INLINE void idBitMsg::WriteDeltaShort( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, -16 ); +} + +ID_INLINE void idBitMsg::WriteDeltaLong( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, 32 ); +} + +ID_INLINE void idBitMsg::WriteDeltaFloat( float oldValue, float newValue ) { + WriteDelta( *reinterpret_cast(&oldValue), *reinterpret_cast(&newValue), 32 ); +} + +ID_INLINE void idBitMsg::WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ) { + int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); + int newBits = idMath::FloatToBits( newValue, exponentBits, mantissaBits ); + WriteDelta( oldBits, newBits, 1 + exponentBits + mantissaBits ); +} + +ID_INLINE void idBitMsg::BeginReading( void ) const { + readCount = 0; + readBit = 0; +} + +ID_INLINE int idBitMsg::GetRemaingData( void ) const { + return curSize - readCount; +} + +ID_INLINE void idBitMsg::ReadByteAlign( void ) const { + readBit = 0; +} + +ID_INLINE int idBitMsg::ReadChar( void ) const { + return (signed char)ReadBits( -8 ); +} + +ID_INLINE int idBitMsg::ReadByte( void ) const { + return (unsigned char)ReadBits( 8 ); +} + +ID_INLINE int idBitMsg::ReadShort( void ) const { + return (short)ReadBits( -16 ); +} + +ID_INLINE int idBitMsg::ReadUShort( void ) const { + return (unsigned short)ReadBits( 16 ); +} + +ID_INLINE int idBitMsg::ReadLong( void ) const { + return ReadBits( 32 ); +} + +ID_INLINE float idBitMsg::ReadFloat( void ) const { + float value; + *reinterpret_cast(&value) = ReadBits( 32 ); + return value; +} + +ID_INLINE float idBitMsg::ReadFloat( int exponentBits, int mantissaBits ) const { + int bits = ReadBits( 1 + exponentBits + mantissaBits ); + return idMath::BitsToFloat( bits, exponentBits, mantissaBits ); +} + +ID_INLINE float idBitMsg::ReadAngle8( void ) const { + return BYTE2ANGLE( ReadByte() ); +} + +ID_INLINE float idBitMsg::ReadAngle16( void ) const { + return SHORT2ANGLE( ReadShort() ); +} + +ID_INLINE idVec3 idBitMsg::ReadDir( int numBits ) const { + return BitsToDir( ReadBits( numBits ), numBits ); +} + +ID_INLINE int idBitMsg::ReadDeltaChar( int oldValue ) const { + return (signed char)ReadDelta( oldValue, -8 ); +} + +ID_INLINE int idBitMsg::ReadDeltaByte( int oldValue ) const { + return (unsigned char)ReadDelta( oldValue, 8 ); +} + +ID_INLINE int idBitMsg::ReadDeltaShort( int oldValue ) const { + return (short)ReadDelta( oldValue, -16 ); +} + +ID_INLINE int idBitMsg::ReadDeltaLong( int oldValue ) const { + return ReadDelta( oldValue, 32 ); +} + +ID_INLINE float idBitMsg::ReadDeltaFloat( float oldValue ) const { + float value; + *reinterpret_cast(&value) = ReadDelta( *reinterpret_cast(&oldValue), 32 ); + return value; +} + +ID_INLINE float idBitMsg::ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const { + int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); + int newBits = ReadDelta( oldBits, 1 + exponentBits + mantissaBits ); + return idMath::BitsToFloat( newBits, exponentBits, mantissaBits ); +} + + +/* +=============================================================================== + + idBitMsgDelta + +=============================================================================== +*/ + +class idBitMsgDelta { +public: + idBitMsgDelta(); + ~idBitMsgDelta() {} + + void Init( const idBitMsg *base, idBitMsg *newBase, idBitMsg *delta ); + void Init( const idBitMsg *base, idBitMsg *newBase, const idBitMsg *delta ); + bool HasChanged( void ) const; + + void WriteBits( int value, int numBits ); + void WriteChar( int c ); + void WriteByte( int c ); + void WriteShort( int c ); + void WriteUShort( int c ); + void WriteLong( int c ); + void WriteFloat( float f ); + void WriteFloat( float f, int exponentBits, int mantissaBits ); + void WriteAngle8( float f ); + void WriteAngle16( float f ); + void WriteDir( const idVec3 &dir, int numBits ); + void WriteString( const char *s, int maxLength = -1 ); + void WriteData( const void *data, int length ); + void WriteDict( const idDict &dict ); + + void WriteDeltaChar( int oldValue, int newValue ); + void WriteDeltaByte( int oldValue, int newValue ); + void WriteDeltaShort( int oldValue, int newValue ); + void WriteDeltaLong( int oldValue, int newValue ); + void WriteDeltaFloat( float oldValue, float newValue ); + void WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ); + void WriteDeltaByteCounter( int oldValue, int newValue ); + void WriteDeltaShortCounter( int oldValue, int newValue ); + void WriteDeltaLongCounter( int oldValue, int newValue ); + + int ReadBits( int numBits ) const; + int ReadChar( void ) const; + int ReadByte( void ) const; + int ReadShort( void ) const; + int ReadUShort( void ) const; + int ReadLong( void ) const; + float ReadFloat( void ) const; + float ReadFloat( int exponentBits, int mantissaBits ) const; + float ReadAngle8( void ) const; + float ReadAngle16( void ) const; + idVec3 ReadDir( int numBits ) const; + void ReadString( char *buffer, int bufferSize ) const; + void ReadData( void *data, int length ) const; + void ReadDict( idDict &dict ); + + int ReadDeltaChar( int oldValue ) const; + int ReadDeltaByte( int oldValue ) const; + int ReadDeltaShort( int oldValue ) const; + int ReadDeltaLong( int oldValue ) const; + float ReadDeltaFloat( float oldValue ) const; + float ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const; + int ReadDeltaByteCounter( int oldValue ) const; + int ReadDeltaShortCounter( int oldValue ) const; + int ReadDeltaLongCounter( int oldValue ) const; + +private: + const idBitMsg *base; // base + idBitMsg * newBase; // new base + idBitMsg * writeDelta; // delta from base to new base for writing + const idBitMsg *readDelta; // delta from base to new base for reading + mutable bool changed; // true if the new base is different from the base + +private: + void WriteDelta( int oldValue, int newValue, int numBits ); + int ReadDelta( int oldValue, int numBits ) const; +}; + +ID_INLINE idBitMsgDelta::idBitMsgDelta() { + base = NULL; + newBase = NULL; + writeDelta = NULL; + readDelta = NULL; + changed = false; +} + +ID_INLINE void idBitMsgDelta::Init( const idBitMsg *base, idBitMsg *newBase, idBitMsg *delta ) { + this->base = base; + this->newBase = newBase; + this->writeDelta = delta; + this->readDelta = delta; + this->changed = false; +} + +ID_INLINE void idBitMsgDelta::Init( const idBitMsg *base, idBitMsg *newBase, const idBitMsg *delta ) { + this->base = base; + this->newBase = newBase; + this->writeDelta = NULL; + this->readDelta = delta; + this->changed = false; +} + +ID_INLINE bool idBitMsgDelta::HasChanged( void ) const { + return changed; +} + +ID_INLINE void idBitMsgDelta::WriteChar( int c ) { + WriteBits( c, -8 ); +} + +ID_INLINE void idBitMsgDelta::WriteByte( int c ) { + WriteBits( c, 8 ); +} + +ID_INLINE void idBitMsgDelta::WriteShort( int c ) { + WriteBits( c, -16 ); +} + +ID_INLINE void idBitMsgDelta::WriteUShort( int c ) { + WriteBits( c, 16 ); +} + +ID_INLINE void idBitMsgDelta::WriteLong( int c ) { + WriteBits( c, 32 ); +} + +ID_INLINE void idBitMsgDelta::WriteFloat( float f ) { + WriteBits( *reinterpret_cast(&f), 32 ); +} + +ID_INLINE void idBitMsgDelta::WriteFloat( float f, int exponentBits, int mantissaBits ) { + int bits = idMath::FloatToBits( f, exponentBits, mantissaBits ); + WriteBits( bits, 1 + exponentBits + mantissaBits ); +} + +ID_INLINE void idBitMsgDelta::WriteAngle8( float f ) { + WriteBits( ANGLE2BYTE( f ), 8 ); +} + +ID_INLINE void idBitMsgDelta::WriteAngle16( float f ) { + WriteBits( ANGLE2SHORT(f), 16 ); +} + +ID_INLINE void idBitMsgDelta::WriteDir( const idVec3 &dir, int numBits ) { + WriteBits( idBitMsg::DirToBits( dir, numBits ), numBits ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaChar( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, -8 ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaByte( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, 8 ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaShort( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, -16 ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaLong( int oldValue, int newValue ) { + WriteDelta( oldValue, newValue, 32 ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaFloat( float oldValue, float newValue ) { + WriteDelta( *reinterpret_cast(&oldValue), *reinterpret_cast(&newValue), 32 ); +} + +ID_INLINE void idBitMsgDelta::WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ) { + int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); + int newBits = idMath::FloatToBits( newValue, exponentBits, mantissaBits ); + WriteDelta( oldBits, newBits, 1 + exponentBits + mantissaBits ); +} + +ID_INLINE int idBitMsgDelta::ReadChar( void ) const { + return (signed char)ReadBits( -8 ); +} + +ID_INLINE int idBitMsgDelta::ReadByte( void ) const { + return (unsigned char)ReadBits( 8 ); +} + +ID_INLINE int idBitMsgDelta::ReadShort( void ) const { + return (short)ReadBits( -16 ); +} + +ID_INLINE int idBitMsgDelta::ReadUShort( void ) const { + return (unsigned short)ReadBits( 16 ); +} + +ID_INLINE int idBitMsgDelta::ReadLong( void ) const { + return ReadBits( 32 ); +} + +ID_INLINE float idBitMsgDelta::ReadFloat( void ) const { + float value; + *reinterpret_cast(&value) = ReadBits( 32 ); + return value; +} + +ID_INLINE float idBitMsgDelta::ReadFloat( int exponentBits, int mantissaBits ) const { + int bits = ReadBits( 1 + exponentBits + mantissaBits ); + return idMath::BitsToFloat( bits, exponentBits, mantissaBits ); +} + +ID_INLINE float idBitMsgDelta::ReadAngle8( void ) const { + return BYTE2ANGLE( ReadByte() ); +} + +ID_INLINE float idBitMsgDelta::ReadAngle16( void ) const { + return SHORT2ANGLE( ReadShort() ); +} + +ID_INLINE idVec3 idBitMsgDelta::ReadDir( int numBits ) const { + return idBitMsg::BitsToDir( ReadBits( numBits ), numBits ); +} + +ID_INLINE int idBitMsgDelta::ReadDeltaChar( int oldValue ) const { + return (signed char)ReadDelta( oldValue, -8 ); +} + +ID_INLINE int idBitMsgDelta::ReadDeltaByte( int oldValue ) const { + return (unsigned char)ReadDelta( oldValue, 8 ); +} + +ID_INLINE int idBitMsgDelta::ReadDeltaShort( int oldValue ) const { + return (short)ReadDelta( oldValue, -16 ); +} + +ID_INLINE int idBitMsgDelta::ReadDeltaLong( int oldValue ) const { + return ReadDelta( oldValue, 32 ); +} + +ID_INLINE float idBitMsgDelta::ReadDeltaFloat( float oldValue ) const { + float value; + *reinterpret_cast(&value) = ReadDelta( *reinterpret_cast(&oldValue), 32 ); + return value; +} + +ID_INLINE float idBitMsgDelta::ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const { + int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); + int newBits = ReadDelta( oldBits, 1 + exponentBits + mantissaBits ); + return idMath::BitsToFloat( newBits, exponentBits, mantissaBits ); +} + +#endif /* !__BITMSG_H__ */ diff --git a/idlib/CmdArgs.cpp b/idlib/CmdArgs.cpp new file mode 100644 index 000000000..7bf3ea818 --- /dev/null +++ b/idlib/CmdArgs.cpp @@ -0,0 +1,189 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +/* +============ +idCmdArgs::operator= +============ +*/ +void idCmdArgs::operator=( const idCmdArgs &args ) { + int i; + + argc = args.argc; + memcpy( tokenized, args.tokenized, MAX_COMMAND_STRING ); + for ( i = 0; i < argc; i++ ) { + argv[ i ] = tokenized + ( args.argv[ i ] - args.tokenized ); + } +} + +/* +============ +idCmdArgs::Args +============ +*/ +const char *idCmdArgs::Args( int start, int end, bool escapeArgs ) const { + static char cmd_args[MAX_COMMAND_STRING]; + int i; + + if ( end < 0 ) { + end = argc - 1; + } else if ( end >= argc ) { + end = argc - 1; + } + cmd_args[0] = '\0'; + if ( escapeArgs ) { + strcat( cmd_args, "\"" ); + } + for ( i = start; i <= end; i++ ) { + if ( i > start ) { + if ( escapeArgs ) { + strcat( cmd_args, "\" \"" ); + } else { + strcat( cmd_args, " " ); + } + } + if ( escapeArgs && strchr( argv[i], '\\' ) ) { + char *p = argv[i]; + while ( *p != '\0' ) { + if ( *p == '\\' ) { + strcat( cmd_args, "\\\\" ); + } else { + int l = strlen( cmd_args ); + cmd_args[ l ] = *p; + cmd_args[ l+1 ] = '\0'; + } + p++; + } + } else { + strcat( cmd_args, argv[i] ); + } + } + if ( escapeArgs ) { + strcat( cmd_args, "\"" ); + } + + return cmd_args; +} + +/* +============ +idCmdArgs::TokenizeString + +Parses the given string into command line tokens. +The text is copied to a separate buffer and 0 characters +are inserted in the appropriate place. The argv array +will point into this temporary buffer. +============ +*/ +void idCmdArgs::TokenizeString( const char *text, bool keepAsStrings ) { + idLexer lex; + idToken token, number; + int len, totalLen; + + // clear previous args + argc = 0; + + if ( !text ) { + return; + } + + lex.LoadMemory( text, strlen( text ), "idCmdSystemLocal::TokenizeString" ); + lex.SetFlags( LEXFL_NOERRORS + | LEXFL_NOWARNINGS + | LEXFL_NOSTRINGCONCAT + | LEXFL_ALLOWPATHNAMES + | LEXFL_NOSTRINGESCAPECHARS + | LEXFL_ALLOWIPADDRESSES | ( keepAsStrings ? LEXFL_ONLYSTRINGS : 0 ) ); + + totalLen = 0; + + while ( 1 ) { + if ( argc == MAX_COMMAND_ARGS ) { + return; // this is usually something malicious + } + + if ( !lex.ReadToken( &token ) ) { + return; + } + + // check for negative numbers + if ( !keepAsStrings && ( token == "-" ) ) { + if ( lex.CheckTokenType( TT_NUMBER, 0, &number ) ) { + token = "-" + number; + } + } + + // check for cvar expansion + if ( token == "$" ) { + if ( !lex.ReadToken( &token ) ) { + return; + } + if ( idLib::cvarSystem ) { + token = idLib::cvarSystem->GetCVarString( token.c_str() ); + } else { + token = ""; + } + } + + len = token.Length(); + + if ( totalLen + len + 1 > sizeof( tokenized ) ) { + return; // this is usually something malicious + } + + // regular token + argv[argc] = tokenized + totalLen; + argc++; + + idStr::Copynz( tokenized + totalLen, token.c_str(), sizeof( tokenized ) - totalLen ); + + totalLen += len + 1; + } +} + +/* +============ +idCmdArgs::AppendArg +============ +*/ +void idCmdArgs::AppendArg( const char *text ) { + if ( !argc ) { + argc = 1; + argv[ 0 ] = tokenized; + idStr::Copynz( tokenized, text, sizeof( tokenized ) ); + } else { + argv[ argc ] = argv[ argc-1 ] + strlen( argv[ argc-1 ] ) + 1; + idStr::Copynz( argv[ argc ], text, sizeof( tokenized ) - ( argv[ argc ] - tokenized ) ); + argc++; + } +} + +/* +============ +idCmdArgs::GetArgs +============ +*/ +const char **idCmdArgs::GetArgs( int *_argc ) { + *_argc = argc; + return (const char **)&argv[0]; +} + diff --git a/idlib/CmdArgs.h b/idlib/CmdArgs.h new file mode 100644 index 000000000..b37627dc1 --- /dev/null +++ b/idlib/CmdArgs.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CMDARGS_H__ +#define __CMDARGS_H__ + +/* +=============================================================================== + + Command arguments. + +=============================================================================== +*/ + +class idCmdArgs { +public: + idCmdArgs( void ) { argc = 0; } + idCmdArgs( const char *text, bool keepAsStrings ) { TokenizeString( text, keepAsStrings ); } + + void operator=( const idCmdArgs &args ); + + // The functions that execute commands get their parameters with these functions. + int Argc( void ) const { return argc; } + // Argv() will return an empty string, not NULL if arg >= argc. + const char * Argv( int arg ) const { return ( arg >= 0 && arg < argc ) ? argv[arg] : ""; } + // Returns a single string containing argv(start) to argv(end) + // escapeArgs is a fugly way to put the string back into a state ready to tokenize again + const char * Args( int start = 1, int end = -1, bool escapeArgs = false ) const; + + // Takes a null terminated string and breaks the string up into arg tokens. + // Does not need to be /n terminated. + // Set keepAsStrings to true to only seperate tokens from whitespace and comments, ignoring punctuation + void TokenizeString( const char *text, bool keepAsStrings ); + + void AppendArg( const char *text ); + void Clear( void ) { argc = 0; } + const char ** GetArgs( int *argc ); + +private: + static const int MAX_COMMAND_ARGS = 64; + static const int MAX_COMMAND_STRING = 2 * MAX_STRING_CHARS; + + int argc; // number of arguments + char * argv[MAX_COMMAND_ARGS]; // points into tokenized + char tokenized[MAX_COMMAND_STRING]; // will have 0 bytes inserted +}; + +#endif /* !__CMDARGS_H__ */ diff --git a/idlib/Dict.cpp b/idlib/Dict.cpp new file mode 100644 index 000000000..40ae1484e --- /dev/null +++ b/idlib/Dict.cpp @@ -0,0 +1,732 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + + + +idStrPool idDict::globalKeys; +idStrPool idDict::globalValues; + +/* +================ +idDict::operator= + + clear existing key/value pairs and copy all key/value pairs from other +================ +*/ +idDict &idDict::operator=( const idDict &other ) { + int i; + + // check for assignment to self + if ( this == &other ) { + return *this; + } + + Clear(); + + args = other.args; + argHash = other.argHash; + + for ( i = 0; i < args.Num(); i++ ) { + args[i].key = globalKeys.CopyString( args[i].key ); + args[i].value = globalValues.CopyString( args[i].value ); + } + + return *this; +} + +/* +================ +idDict::Copy + + copy all key value pairs without removing existing key/value pairs not present in the other dict +================ +*/ +void idDict::Copy( const idDict &other ) { + int i, n, *found; + idKeyValue kv; + + // check for assignment to self + if ( this == &other ) { + return; + } + + n = other.args.Num(); + + if ( args.Num() ) { + found = (int *) _alloca16( other.args.Num() * sizeof( int ) ); + for ( i = 0; i < n; i++ ) { + found[i] = FindKeyIndex( other.args[i].GetKey() ); + } + } else { + found = NULL; + } + + for ( i = 0; i < n; i++ ) { + if ( found && found[i] != -1 ) { + // first set the new value and then free the old value to allow proper self copying + const idPoolStr *oldValue = args[found[i]].value; + args[found[i]].value = globalValues.CopyString( other.args[i].value ); + globalValues.FreeString( oldValue ); + } else { + kv.key = globalKeys.CopyString( other.args[i].key ); + kv.value = globalValues.CopyString( other.args[i].value ); + argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) ); + } + } +} + +/* +================ +idDict::TransferKeyValues + + clear existing key/value pairs and transfer key/value pairs from other +================ +*/ +void idDict::TransferKeyValues( idDict &other ) { + int i, n; + + if ( this == &other ) { + return; + } + + if ( other.args.Num() && other.args[0].key->GetPool() != &globalKeys ) { + common->FatalError( "idDict::TransferKeyValues: can't transfer values across a DLL boundary" ); + return; + } + + Clear(); + + n = other.args.Num(); + args.SetNum( n ); + for ( i = 0; i < n; i++ ) { + args[i].key = other.args[i].key; + args[i].value = other.args[i].value; + } + argHash = other.argHash; + + other.args.Clear(); + other.argHash.Free(); +} + +/* +================ +idDict::Parse +================ +*/ +bool idDict::Parse( idParser &parser ) { + idToken token; + idToken token2; + bool errors; + + errors = false; + + parser.ExpectTokenString( "{" ); + parser.ReadToken( &token ); + while( ( token.type != TT_PUNCTUATION ) || ( token != "}" ) ) { + if ( token.type != TT_STRING ) { + parser.Error( "Expected quoted string, but found '%s'", token.c_str() ); + } + + if ( !parser.ReadToken( &token2 ) ) { + parser.Error( "Unexpected end of file" ); + } + + if ( FindKey( token ) ) { + parser.Warning( "'%s' already defined", token.c_str() ); + errors = true; + } + Set( token, token2 ); + + if ( !parser.ReadToken( &token ) ) { + parser.Error( "Unexpected end of file" ); + } + } + + return !errors; +} + +/* +================ +idDict::SetDefaults +================ +*/ +void idDict::SetDefaults( const idDict *dict ) { + int i, n; + const idKeyValue *kv, *def; + idKeyValue newkv; + + n = dict->args.Num(); + for( i = 0; i < n; i++ ) { + def = &dict->args[i]; + kv = FindKey( def->GetKey() ); + if ( !kv ) { + newkv.key = globalKeys.CopyString( def->key ); + newkv.value = globalValues.CopyString( def->value ); + argHash.Add( argHash.GenerateKey( newkv.GetKey(), false ), args.Append( newkv ) ); + } + } +} + +/* +================ +idDict::SetDefaults + +Tels: Like SetDefaults(), but skips all entries starting with skip: +================ +*/ +void idDict::SetDefaults( const idDict *dict, const idStr &skip ) { + int i, n, l; + const idKeyValue *kv, *def; + idKeyValue newkv; + + n = dict->args.Num(); + l = skip.Length(); + for( i = 0; i < n; i++ ) { + def = &dict->args[i]; + if (def->GetKey().Icmpn(skip, l) == 0) + { + continue; + } + kv = FindKey( def->GetKey() ); + if ( !kv ) { + newkv.key = globalKeys.CopyString( def->key ); + newkv.value = globalValues.CopyString( def->value ); + argHash.Add( argHash.GenerateKey( newkv.GetKey(), false ), args.Append( newkv ) ); + } + } +} + +/* +================ +idDict::Clear +================ +*/ +void idDict::Clear( void ) { + int i; + + for( i = 0; i < args.Num(); i++ ) { + globalKeys.FreeString( args[i].key ); + globalValues.FreeString( args[i].value ); + } + + args.Clear(); + argHash.Free(); +} + +/* +================ +idDict::Print +================ +*/ +void idDict::Print() const { + int i; + int n; + + n = args.Num(); + for( i = 0; i < n; i++ ) { + idLib::common->Printf( "%s = %s\n", args[i].GetKey().c_str(), args[i].GetValue().c_str() ); + } +} + +int KeyCompare( const idKeyValue *a, const idKeyValue *b ) { + return idStr::Cmp( a->GetKey(), b->GetKey() ); +} + +/* +================ +idDict::Checksum +================ +*/ +int idDict::Checksum( void ) const { + unsigned long ret; + int i, n; + + idList sorted = args; + sorted.Sort( KeyCompare ); + n = sorted.Num(); + CRC32_InitChecksum( ret ); + for( i = 0; i < n; i++ ) { + CRC32_UpdateChecksum( ret, sorted[i].GetKey().c_str(), sorted[i].GetKey().Length() ); + CRC32_UpdateChecksum( ret, sorted[i].GetValue().c_str(), sorted[i].GetValue().Length() ); + } + CRC32_FinishChecksum( ret ); + return ret; +} + +/* +================ +idDict::Allocated +================ +*/ +size_t idDict::Allocated( void ) const { + int i; + size_t size; + + size = args.Allocated() + argHash.Allocated(); + for( i = 0; i < args.Num(); i++ ) { + size += args[i].Size(); + } + + return size; +} + +/* +================ +idDict::Set +================ +*/ +void idDict::Set( const char *key, const char *value ) { + int i; + idKeyValue kv; + + if ( key == NULL || key[0] == '\0' ) { + return; + } + + i = FindKeyIndex( key ); + if ( i != -1 ) { + // first set the new value and then free the old value to allow proper self copying + const idPoolStr *oldValue = args[i].value; + args[i].value = globalValues.AllocString( value ); + globalValues.FreeString( oldValue ); + } else { + kv.key = globalKeys.AllocString( key ); + kv.value = globalValues.AllocString( value ); + argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) ); + } +} + +/* +================ +idDict::GetFloat +================ +*/ +bool idDict::GetFloat( const char *key, const char *defaultString, float &out ) const { + const char *s; + bool found; + + found = GetString( key, defaultString, &s ); + out = atof( s ); + return found; +} + +/* +================ +idDict::GetInt +================ +*/ +bool idDict::GetInt( const char *key, const char *defaultString, int &out ) const { + const char *s; + bool found; + + found = GetString( key, defaultString, &s ); + out = atoi( s ); + return found; +} + +/* +================ +idDict::GetBool +================ +*/ +bool idDict::GetBool( const char *key, const char *defaultString, bool &out ) const { + const char *s; + bool found; + + found = GetString( key, defaultString, &s ); + out = ( atoi( s ) != 0 ); + return found; +} + +/* +================ +idDict::GetAngles +================ +*/ +bool idDict::GetAngles( const char *key, const char *defaultString, idAngles &out ) const { + bool found; + const char *s; + + if ( !defaultString ) { + defaultString = "0 0 0"; + } + + found = GetString( key, defaultString, &s ); + out.Zero(); + sscanf( s, "%f %f %f", &out.pitch, &out.yaw, &out.roll ); + return found; +} + +/* +================ +idDict::GetVector +================ +*/ +bool idDict::GetVector( const char *key, const char *defaultString, idVec3 &out ) const { + bool found; + const char *s; + + if ( !defaultString ) { + defaultString = "0 0 0"; + } + + found = GetString( key, defaultString, &s ); + out.Zero(); + sscanf( s, "%f %f %f", &out.x, &out.y, &out.z ); + return found; +} + +/* +================ +idDict::GetVec2 +================ +*/ +bool idDict::GetVec2( const char *key, const char *defaultString, idVec2 &out ) const { + bool found; + const char *s; + + if ( !defaultString ) { + defaultString = "0 0"; + } + + found = GetString( key, defaultString, &s ); + out.Zero(); + sscanf( s, "%f %f", &out.x, &out.y ); + return found; +} + +/* +================ +idDict::GetVec4 +================ +*/ +bool idDict::GetVec4( const char *key, const char *defaultString, idVec4 &out ) const { + bool found; + const char *s; + + if ( !defaultString ) { + defaultString = "0 0 0 0"; + } + + found = GetString( key, defaultString, &s ); + out.Zero(); + sscanf( s, "%f %f %f %f", &out.x, &out.y, &out.z, &out.w ); + return found; +} + +/* +================ +idDict::GetMatrix +================ +*/ +bool idDict::GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const { + const char *s; + bool found; + + if ( !defaultString ) { + defaultString = "1 0 0 0 1 0 0 0 1"; + } + + found = GetString( key, defaultString, &s ); + out.Identity(); // sccanf has a bug in it on Mac OS 9. Sigh. + sscanf( s, "%f %f %f %f %f %f %f %f %f", &out[0].x, &out[0].y, &out[0].z, &out[1].x, &out[1].y, &out[1].z, &out[2].x, &out[2].y, &out[2].z ); + return found; +} + +/* +================ +WriteString +================ +*/ +static void WriteString( const char *s, idFile *f ) { + int len = strlen( s ); + if ( len >= MAX_STRING_CHARS-1 ) { + idLib::common->Error( "idDict::WriteToFileHandle: bad string" ); + } + f->Write( s, strlen(s) + 1 ); +} + +/* +================ +idDict::FindKey +================ +*/ +const idKeyValue *idDict::FindKey( const char *key ) const { + int i, hash; + + if ( key == NULL || key[0] == '\0' ) { + idLib::common->DWarning( "idDict::FindKey: empty key" ); + return NULL; + } + + hash = argHash.GenerateKey( key, false ); + for ( i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { + if ( args[i].GetKey().Icmp( key ) == 0 ) { + return &args[i]; + } + } + + return NULL; +} + +/* +================ +idDict::FindKeyIndex +================ +*/ +int idDict::FindKeyIndex( const char *key ) const { + + if ( key == NULL || key[0] == '\0' ) { + idLib::common->DWarning( "idDict::FindKeyIndex: empty key" ); + return 0; + } + + int hash = argHash.GenerateKey( key, false ); + for ( int i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { + if ( args[i].GetKey().Icmp( key ) == 0 ) { + return i; + } + } + + return -1; +} + +/* +================ +idDict::Delete +================ +*/ +void idDict::Delete( const char *key ) { + int hash, i; + + hash = argHash.GenerateKey( key, false ); + for ( i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { + if ( args[i].GetKey().Icmp( key ) == 0 ) { + globalKeys.FreeString( args[i].key ); + globalValues.FreeString( args[i].value ); + args.RemoveIndex( i ); + argHash.RemoveIndex( hash, i ); + break; + } + } + +#if 0 + // make sure all keys can still be found in the hash index + for ( i = 0; i < args.Num(); i++ ) { + assert( FindKey( args[i].GetKey() ) != NULL ); + } +#endif +} + +/* +================ +idDict::MatchPrefix +================ +*/ +const idKeyValue *idDict::MatchPrefix( const char *prefix, const idKeyValue *lastMatch ) const { + int i; + int len; + int start; + + assert( prefix ); + len = strlen( prefix ); + + start = -1; + if ( lastMatch ) { + start = args.FindIndex( *lastMatch ); + assert( start >= 0 ); + if ( start < 1 ) { + start = 0; + } + } + + for( i = start + 1; i < args.Num(); i++ ) { + if ( !args[i].GetKey().Icmpn( prefix, len ) ) { + return &args[i]; + } + } + return NULL; +} + +/* +================ +idDict::RandomPrefix +================ +*/ +const char *idDict::RandomPrefix( const char *prefix, idRandom &random ) const { + int count; + const int MAX_RANDOM_KEYS = 2048; + const char *list[MAX_RANDOM_KEYS]; + const idKeyValue *kv; + + list[0] = ""; + for ( count = 0, kv = MatchPrefix( prefix ); kv && count < MAX_RANDOM_KEYS; kv = MatchPrefix( prefix, kv ) ) { + list[count++] = kv->GetValue().c_str(); + } + return list[random.RandomInt( count )]; +} + +/* +================ +idDict::WriteToFileHandle +================ +*/ +void idDict::WriteToFileHandle( idFile *f ) const { + int c = LittleLong( args.Num() ); + f->Write( &c, sizeof( c ) ); + for ( int i = 0; i < args.Num(); i++ ) { // don't loop on the swapped count use the original + WriteString( args[i].GetKey().c_str(), f ); + WriteString( args[i].GetValue().c_str(), f ); + } +} + +/* +================ +ReadString +================ +*/ +static idStr ReadString( idFile *f ) { + char str[MAX_STRING_CHARS]; + int len; + + for ( len = 0; len < MAX_STRING_CHARS; len++ ) { + f->Read( (void *)&str[len], 1 ); + if ( str[len] == 0 ) { + break; + } + } + if ( len == MAX_STRING_CHARS ) { + idLib::common->Error( "idDict::ReadFromFileHandle: bad string" ); + } + + return idStr( str ); +} + +/* +================ +idDict::ReadFromFileHandle +================ +*/ +void idDict::ReadFromFileHandle( idFile *f ) { + int c; + idStr key, val; + + Clear(); + + f->Read( &c, sizeof( c ) ); + c = LittleLong( c ); + for ( int i = 0; i < c; i++ ) { + key = ReadString( f ); + val = ReadString( f ); + Set( key, val ); + } +} + +/* +================ +idDict::Init +================ +*/ +void idDict::Init( void ) { + globalKeys.SetCaseSensitive( false ); + globalValues.SetCaseSensitive( true ); +} + +/* +================ +idDict::Shutdown +================ +*/ +void idDict::Shutdown( void ) { + globalKeys.Clear(); + globalValues.Clear(); +} + +/* +================ +idDict::ShowMemoryUsage_f +================ +*/ +void idDict::ShowMemoryUsage_f( const idCmdArgs &args ) { + idLib::common->Printf( "%5d KB in %d keys\n", globalKeys.Size() >> 10, globalKeys.Num() ); + idLib::common->Printf( "%5d KB in %d values\n", globalValues.Size() >> 10, globalValues.Num() ); +} + +/* +================ +idDict::PrintMemory +================ +*/ +void idDict::PrintMemory( void ) const { + idLib::common->Printf( "%d KB in %d keys, %d KB in %d values.\n", + globalKeys.Size() >> 10, globalKeys.Num(), globalValues.Size() >> 10, globalValues.Num() ); +} + +/* +================ +idDictStringSortCmp +================ +*/ +// NOTE: the const wonkyness is required to make msvc happy +template<> +ID_INLINE int idListSortCompare( const idPoolStr * const *a, const idPoolStr * const *b ) { + return (*a)->Icmp( **b ); +} + +/* +================ +idDict::ListKeys_f +================ +*/ +void idDict::ListKeys_f( const idCmdArgs &args ) { + int i; + idList keyStrings; + + for ( i = 0; i < globalKeys.Num(); i++ ) { + keyStrings.Append( globalKeys[i] ); + } + keyStrings.Sort(); + for ( i = 0; i < keyStrings.Num(); i++ ) { + idLib::common->Printf( "%s\n", keyStrings[i]->c_str() ); + } + idLib::common->Printf( "%5d keys\n", keyStrings.Num() ); +} + +/* +================ +idDict::ListValues_f +================ +*/ +void idDict::ListValues_f( const idCmdArgs &args ) { + int i; + idList valueStrings; + + for ( i = 0; i < globalValues.Num(); i++ ) { + valueStrings.Append( globalValues[i] ); + } + valueStrings.Sort(); + for ( i = 0; i < valueStrings.Num(); i++ ) { + idLib::common->Printf( "%s\n", valueStrings[i]->c_str() ); + } + idLib::common->Printf( "%5d values\n", valueStrings.Num() ); +} diff --git a/idlib/Dict.h b/idlib/Dict.h new file mode 100644 index 000000000..2bd265cea --- /dev/null +++ b/idlib/Dict.h @@ -0,0 +1,297 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DICT_H__ +#define __DICT_H__ + +#include + +/* +=============================================================================== + +Key/value dictionary + +This is a dictionary class that tracks an arbitrary number of key / value +pair combinations. It is used for map entity spawning, GUI state management, +and other things. + +Keys are compared case-insensitive. + +Does not allocate memory until the first key/value pair is added. + +=============================================================================== +*/ + +class idKeyValue { + friend class idDict; + +public: + const idStr & GetKey( void ) const { return *key; } + const idStr & GetValue( void ) const { return *value; } + + size_t Allocated( void ) const { return key->Allocated() + value->Allocated(); } + size_t Size( void ) const { return sizeof( *this ) + key->Size() + value->Size(); } + + bool operator==( const idKeyValue &kv ) const { return ( key == kv.key && value == kv.value ); } + +private: + const idPoolStr * key; + const idPoolStr * value; +}; + +class idDict { +public: + idDict( void ); + idDict( const idDict &other ); // allow declaration with assignment + ~idDict( void ); + + // set the granularity for the index + void SetGranularity( int granularity ); + // set hash size + void SetHashSize( int hashSize ); + // clear existing key/value pairs and copy all key/value pairs from other + idDict & operator=( const idDict &other ); + // copy from other while leaving existing key/value pairs in place + void Copy( const idDict &other ); + // clear existing key/value pairs and transfer key/value pairs from other + void TransferKeyValues( idDict &other ); + // parse dict from parser + bool Parse( idParser &parser ); + // copy key/value pairs from other dict not present in this dict + void SetDefaults( const idDict *dict ); + // Tels: like SetDefaults(), but skip all keys starting with "skip" + void SetDefaults( const idDict *dict, const idStr &skip ); + // clear dict freeing up memory + void Clear( void ); + // print the dict + void Print() const; + + size_t Allocated( void ) const; + size_t Size( void ) const { return sizeof( *this ) + Allocated(); } + + void Set( const char *key, const char *value ); + void SetFloat( const char *key, float val ); + void SetInt( const char *key, int val ); + void SetBool( const char *key, bool val ); + void SetVector( const char *key, const idVec3 &val ); + void SetVec2( const char *key, const idVec2 &val ); + void SetVec4( const char *key, const idVec4 &val ); + void SetAngles( const char *key, const idAngles &val ); + void SetMatrix( const char *key, const idMat3 &val ); + + // these return default values of 0.0, 0 and false + const char * GetString( const char *key, const char *defaultString = "" ) const; + float GetFloat( const char *key, const char *defaultString = "0" ) const; + int GetInt( const char *key, const char *defaultString = "0" ) const; + bool GetBool( const char *key, const char *defaultString = "0" ) const; + idVec3 GetVector( const char *key, const char *defaultString = NULL ) const; + idVec2 GetVec2( const char *key, const char *defaultString = NULL ) const; + idVec4 GetVec4( const char *key, const char *defaultString = NULL ) const; + idAngles GetAngles( const char *key, const char *defaultString = NULL ) const; + idMat3 GetMatrix( const char *key, const char *defaultString = NULL ) const; + + bool GetString( const char *key, const char *defaultString, const char **out ) const; + bool GetString( const char *key, const char *defaultString, idStr &out ) const; + bool GetFloat( const char *key, const char *defaultString, float &out ) const; + bool GetInt( const char *key, const char *defaultString, int &out ) const; + bool GetBool( const char *key, const char *defaultString, bool &out ) const; + bool GetVector( const char *key, const char *defaultString, idVec3 &out ) const; + bool GetVec2( const char *key, const char *defaultString, idVec2 &out ) const; + bool GetVec4( const char *key, const char *defaultString, idVec4 &out ) const; + bool GetAngles( const char *key, const char *defaultString, idAngles &out ) const; + bool GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const; + + int GetNumKeyVals( void ) const; + const idKeyValue * GetKeyVal( int index ) const; + // returns the key/value pair with the given key + // returns NULL if the key/value pair does not exist + const idKeyValue * FindKey( const char *key ) const; + // returns the index to the key/value pair with the given key + // returns -1 if the key/value pair does not exist + int FindKeyIndex( const char *key ) const; + // delete the key/value pair with the given key + void Delete( const char *key ); + // finds the next key/value pair with the given key prefix. + // lastMatch can be used to do additional searches past the first match. + const idKeyValue * MatchPrefix( const char *prefix, const idKeyValue *lastMatch = NULL ) const; + // randomly chooses one of the key/value pairs with the given key prefix and returns it's value + const char * RandomPrefix( const char *prefix, idRandom &random ) const; + + void WriteToFileHandle( idFile *f ) const; + void ReadFromFileHandle( idFile *f ); + + // returns a unique checksum for this dictionary's content + int Checksum( void ) const; + + static void Init( void ); + static void Shutdown( void ); + + static void ShowMemoryUsage_f( const idCmdArgs &args ); + void PrintMemory( void ) const; + static void ListKeys_f( const idCmdArgs &args ); + static void ListValues_f( const idCmdArgs &args ); + +private: + idList args; + idHashIndex argHash; + + static idStrPool globalKeys; + static idStrPool globalValues; +}; + + +ID_INLINE idDict::idDict( void ) { + args.SetGranularity( 16 ); + argHash.SetGranularity( 16 ); + argHash.Clear( 128, 16 ); +} + +ID_INLINE idDict::idDict( const idDict &other ) { + *this = other; +} + +ID_INLINE idDict::~idDict( void ) { + Clear(); +} + +ID_INLINE void idDict::SetGranularity( int granularity ) { + args.SetGranularity( granularity ); + argHash.SetGranularity( granularity ); +} + +ID_INLINE void idDict::SetHashSize( int hashSize ) { + if ( args.Num() == 0 ) { + argHash.Clear( hashSize, 16 ); + } +} + +ID_INLINE void idDict::SetFloat( const char *key, float val ) { + Set( key, va( "%f", val ) ); +} + +ID_INLINE void idDict::SetInt( const char *key, int val ) { + Set( key, va( "%i", val ) ); +} + +ID_INLINE void idDict::SetBool( const char *key, bool val ) { + Set( key, va( "%i", val ) ); +} + +ID_INLINE void idDict::SetVector( const char *key, const idVec3 &val ) { + Set( key, val.ToString() ); +} + +ID_INLINE void idDict::SetVec4( const char *key, const idVec4 &val ) { + Set( key, val.ToString() ); +} + +ID_INLINE void idDict::SetVec2( const char *key, const idVec2 &val ) { + Set( key, val.ToString() ); +} + +ID_INLINE void idDict::SetAngles( const char *key, const idAngles &val ) { + Set( key, val.ToString() ); +} + +ID_INLINE void idDict::SetMatrix( const char *key, const idMat3 &val ) { + Set( key, val.ToString() ); +} + +ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, const char **out ) const { + const idKeyValue *kv = FindKey( key ); + if ( kv ) { + *out = kv->GetValue(); + return true; + } + *out = defaultString; + return false; +} + +ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, idStr &out ) const { + const idKeyValue *kv = FindKey( key ); + if ( kv ) { + out = kv->GetValue(); + return true; + } + out = defaultString; + return false; +} + +ID_INLINE const char *idDict::GetString( const char *key, const char *defaultString ) const { + const idKeyValue *kv = FindKey( key ); + if ( kv ) { + return kv->GetValue(); + } + return defaultString; +} + +ID_INLINE float idDict::GetFloat( const char *key, const char *defaultString ) const { + return atof( GetString( key, defaultString ) ); +} + +ID_INLINE int idDict::GetInt( const char *key, const char *defaultString ) const { + return atoi( GetString( key, defaultString ) ); +} + +ID_INLINE bool idDict::GetBool( const char *key, const char *defaultString ) const { + return ( atoi( GetString( key, defaultString ) ) != 0 ); +} + +ID_INLINE idVec3 idDict::GetVector( const char *key, const char *defaultString ) const { + idVec3 out; + GetVector( key, defaultString, out ); + return out; +} + +ID_INLINE idVec2 idDict::GetVec2( const char *key, const char *defaultString ) const { + idVec2 out; + GetVec2( key, defaultString, out ); + return out; +} + +ID_INLINE idVec4 idDict::GetVec4( const char *key, const char *defaultString ) const { + idVec4 out; + GetVec4( key, defaultString, out ); + return out; +} + +ID_INLINE idAngles idDict::GetAngles( const char *key, const char *defaultString ) const { + idAngles out; + GetAngles( key, defaultString, out ); + return out; +} + +ID_INLINE idMat3 idDict::GetMatrix( const char *key, const char *defaultString ) const { + idMat3 out; + GetMatrix( key, defaultString, out ); + return out; +} + +ID_INLINE int idDict::GetNumKeyVals( void ) const { + return args.Num(); +} + +ID_INLINE const idKeyValue *idDict::GetKeyVal( int index ) const { + if ( index >= 0 && index < args.Num() ) { + return &args[ index ]; + } + return NULL; +} + +#endif /* !__DICT_H__ */ diff --git a/idlib/Heap.cpp b/idlib/Heap.cpp new file mode 100644 index 000000000..f419ac153 --- /dev/null +++ b/idlib/Heap.cpp @@ -0,0 +1,1766 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + + + +#ifndef USE_LIBC_MALLOC + #define USE_LIBC_MALLOC 0 +#endif + +#ifndef CRASH_ON_STATIC_ALLOCATION +// #define CRASH_ON_STATIC_ALLOCATION +#endif + +//=============================================================== +// +// idHeap +// +//=============================================================== + +#define SMALL_HEADER_SIZE ( (int) ( sizeof( byte ) + sizeof( byte ) ) ) +#define MEDIUM_HEADER_SIZE ( (int) ( sizeof( mediumHeapEntry_s ) + sizeof( byte ) ) ) +#define LARGE_HEADER_SIZE ( (int) ( sizeof( dword * ) + sizeof( byte ) ) ) + +#define ALIGN_SIZE( bytes ) ( ( (bytes) + ALIGN - 1 ) & ~(ALIGN - 1) ) +#define SMALL_ALIGN( bytes ) ( ALIGN_SIZE( (bytes) + SMALL_HEADER_SIZE ) - SMALL_HEADER_SIZE ) +#define MEDIUM_SMALLEST_SIZE ( ALIGN_SIZE( 256 ) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ) ) + + +class idHeap { + +public: + idHeap( void ); + ~idHeap( void ); // frees all associated data + void Init( void ); // initialize + void * Allocate( const dword bytes ); // allocate memory + void Free( void *p ); // free memory + void * Allocate16( const dword bytes );// allocate 16 byte aligned memory + void Free16( void *p ); // free 16 byte aligned memory + dword Msize( void *p ); // return size of data block + void Dump( void ); + + void AllocDefragBlock( void ); // hack for huge renderbumps + +private: + + enum { + ALIGN = 8 // memory alignment in bytes + }; + + enum { + INVALID_ALLOC = 0xdd, + SMALL_ALLOC = 0xaa, // small allocation + MEDIUM_ALLOC = 0xbb, // medium allocaction + LARGE_ALLOC = 0xcc // large allocaction + }; + + struct page_s { // allocation page + void * data; // data pointer to allocated memory + dword dataSize; // number of bytes of memory 'data' points to + page_s * next; // next free page in same page manager + page_s * prev; // used only when allocated + dword largestFree; // this data used by the medium-size heap manager + void * firstFree; // pointer to first free entry + }; + + struct mediumHeapEntry_s { + page_s * page; // pointer to page + dword size; // size of block + mediumHeapEntry_s * prev; // previous block + mediumHeapEntry_s * next; // next block + mediumHeapEntry_s * prevFree; // previous free block + mediumHeapEntry_s * nextFree; // next free block + dword freeBlock; // non-zero if free block + }; + + // variables + void * smallFirstFree[256/ALIGN+1]; // small heap allocator lists (for allocs of 1-255 bytes) + page_s * smallCurPage; // current page for small allocations + dword smallCurPageOffset; // byte offset in current page + page_s * smallFirstUsedPage; // first used page of the small heap manager + + page_s * mediumFirstFreePage; // first partially free page + page_s * mediumLastFreePage; // last partially free page + page_s * mediumFirstUsedPage; // completely used page + + page_s * largeFirstUsedPage; // first page used by the large heap manager + + page_s * swapPage; + + dword pagesAllocated; // number of pages currently allocated + dword pageSize; // size of one alloc page in bytes + + dword pageRequests; // page requests + dword OSAllocs; // number of allocs made to the OS + + int c_heapAllocRunningCount; + + void *defragBlock; // a single huge block that can be allocated + // at startup, then freed when needed + + // methods + page_s * AllocatePage( dword bytes ); // allocate page from the OS + void FreePage( idHeap::page_s *p ); // free an OS allocated page + + void * SmallAllocate( dword bytes ); // allocate memory (1-255 bytes) from small heap manager + void SmallFree( void *ptr ); // free memory allocated by small heap manager + + void * MediumAllocateFromPage( idHeap::page_s *p, dword sizeNeeded ); + void * MediumAllocate( dword bytes ); // allocate memory (256-32768 bytes) from medium heap manager + void MediumFree( void *ptr ); // free memory allocated by medium heap manager + + void * LargeAllocate( dword bytes ); // allocate large block from OS directly + void LargeFree( void *ptr ); // free memory allocated by large heap manager + + void ReleaseSwappedPages( void ); + void FreePageReal( idHeap::page_s *p ); +}; + + +/* +================ +idHeap::Init +================ +*/ +void idHeap::Init () { + OSAllocs = 0; + pageRequests = 0; + pageSize = 65536 - sizeof( idHeap::page_s ); + pagesAllocated = 0; // reset page allocation counter + + largeFirstUsedPage = NULL; // init large heap manager + swapPage = NULL; + + memset( smallFirstFree, 0, sizeof(smallFirstFree) ); // init small heap manager + smallFirstUsedPage = NULL; + smallCurPage = AllocatePage( pageSize ); + assert( smallCurPage ); + smallCurPageOffset = SMALL_ALIGN( 0 ); + + defragBlock = NULL; + + mediumFirstFreePage = NULL; // init medium heap manager + mediumLastFreePage = NULL; + mediumFirstUsedPage = NULL; + + c_heapAllocRunningCount = 0; +} + +/* +================ +idHeap::idHeap +================ +*/ +idHeap::idHeap( void ) { + Init(); +} + +/* +================ +idHeap::~idHeap + + returns all allocated memory back to OS +================ +*/ +idHeap::~idHeap( void ) { + + idHeap::page_s *p; + + if ( smallCurPage ) { + FreePage( smallCurPage ); // free small-heap current allocation page + } + p = smallFirstUsedPage; // free small-heap allocated pages + while( p ) { + idHeap::page_s *next = p->next; + FreePage( p ); + p= next; + } + + p = largeFirstUsedPage; // free large-heap allocated pages + while( p ) { + idHeap::page_s *next = p->next; + FreePage( p ); + p = next; + } + + p = mediumFirstFreePage; // free medium-heap allocated pages + while( p ) { + idHeap::page_s *next = p->next; + FreePage( p ); + p = next; + } + + p = mediumFirstUsedPage; // free medium-heap allocated completely used pages + while( p ) { + idHeap::page_s *next = p->next; + FreePage( p ); + p = next; + } + + ReleaseSwappedPages(); + + if ( defragBlock ) { + free( defragBlock ); + } + + assert( pagesAllocated == 0 ); +} + +/* +================ +idHeap::AllocDefragBlock +================ +*/ +void idHeap::AllocDefragBlock( void ) { + int size = 0x40000000; + + if ( defragBlock ) { + return; + } +#pragma warning( push ) +#pragma warning( disable : 4127 ) + while( true ) { + defragBlock = malloc( size ); + if ( defragBlock ) { + break; + } + size >>= 1; + } +#pragma warning( pop ) + idLib::common->Printf( "Allocated a %i mb defrag block\n", size / (1024*1024) ); +} + +/* +================ +idHeap::Allocate +================ +*/ +void *idHeap::Allocate( const dword bytes ) { + if ( !bytes ) { + return NULL; + } + c_heapAllocRunningCount++; + +#if USE_LIBC_MALLOC + return malloc( bytes ); +#else + if ( !(bytes & ~255) ) { + return SmallAllocate( bytes ); + } + if ( !(bytes & ~32767) ) { + return MediumAllocate( bytes ); + } + return LargeAllocate( bytes ); +#endif +} + +/* +================ +idHeap::Free +================ +*/ +void idHeap::Free( void *p ) { + if ( !p ) { + return; + } + c_heapAllocRunningCount--; + +#if USE_LIBC_MALLOC + free( p ); +#else + switch( ((byte *)(p))[-1] ) { + case SMALL_ALLOC: { + SmallFree( p ); + break; + } + case MEDIUM_ALLOC: { + MediumFree( p ); + break; + } + case LARGE_ALLOC: { + LargeFree( p ); + break; + } + default: { + idLib::common->FatalError( "idHeap::Free: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) ); + break; + } + } +#endif +} + +/* +================ +idHeap::Allocate16 +================ +*/ +void *idHeap::Allocate16( const dword bytes ) { + byte *ptr, *alignedPtr; + + ptr = (byte *) malloc( bytes + 16 + 4 ); + if ( !ptr ) { + if ( defragBlock ) { + idLib::common->Printf( "Freeing defragBlock on alloc of %i.\n", bytes ); + free( defragBlock ); + defragBlock = NULL; + ptr = (byte *) malloc( bytes + 16 + 4 ); + AllocDefragBlock(); + } + if ( !ptr ) { + common->FatalError( "malloc failure for %i", bytes ); + } + } + alignedPtr = (byte *) ( ( (int) ptr ) + 15 & ~15 ); + if ( alignedPtr - ptr < 4 ) { + alignedPtr += 16; + } + *((int *)(alignedPtr - 4)) = (int) ptr; + return (void *) alignedPtr; +} + +/* +================ +idHeap::Free16 +================ +*/ +void idHeap::Free16( void *p ) { + free( (void *) *((int *) (( (byte *) p ) - 4)) ); +} + +/* +================ +idHeap::Msize + + returns size of allocated memory block + p = pointer to memory block + Notes: size may not be the same as the size in the original + allocation request (due to block alignment reasons). +================ +*/ +dword idHeap::Msize( void *p ) { + + if ( !p ) { + return 0; + } + +#if USE_LIBC_MALLOC + #ifdef _WIN32 + return _msize( p ); + #else + return 0; + #endif +#else + switch( ((byte *)(p))[-1] ) { + case SMALL_ALLOC: { + return SMALL_ALIGN( ((byte *)(p))[-SMALL_HEADER_SIZE] * ALIGN ); + } + case MEDIUM_ALLOC: { + return ((mediumHeapEntry_s *)(((byte *)(p)) - ALIGN_SIZE( MEDIUM_HEADER_SIZE )))->size - ALIGN_SIZE( MEDIUM_HEADER_SIZE ); + } + case LARGE_ALLOC: { + return ((idHeap::page_s*)(*((dword *)(((byte *)p) - ALIGN_SIZE( LARGE_HEADER_SIZE )))))->dataSize - ALIGN_SIZE( LARGE_HEADER_SIZE ); + } + default: { + idLib::common->FatalError( "idHeap::Msize: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) ); + return 0; + } + } +#endif +} + +/* +================ +idHeap::Dump + + dump contents of the heap +================ +*/ +void idHeap::Dump( void ) { + idHeap::page_s *pg; + + for ( pg = smallFirstUsedPage; pg; pg = pg->next ) { + idLib::common->Printf( "%p bytes %-8d (in use by small heap)\n", pg->data, pg->dataSize); + } + + if ( smallCurPage ) { + pg = smallCurPage; + idLib::common->Printf( "%p bytes %-8d (small heap active page)\n", pg->data, pg->dataSize ); + } + + for ( pg = mediumFirstUsedPage; pg; pg = pg->next ) { + idLib::common->Printf( "%p bytes %-8d (completely used by medium heap)\n", pg->data, pg->dataSize ); + } + + for ( pg = mediumFirstFreePage; pg; pg = pg->next ) { + idLib::common->Printf( "%p bytes %-8d (partially used by medium heap)\n", pg->data, pg->dataSize ); + } + + for ( pg = largeFirstUsedPage; pg; pg = pg->next ) { + idLib::common->Printf( "%p bytes %-8d (fully used by large heap)\n", pg->data, pg->dataSize ); + } + + idLib::common->Printf( "pages allocated : %d\n", pagesAllocated ); +} + +/* +================ +idHeap::FreePageReal + + frees page to be used by the OS + p = page to free +================ +*/ +void idHeap::FreePageReal( idHeap::page_s *p ) { + assert( p ); + ::free( p ); +} + +/* +================ +idHeap::ReleaseSwappedPages + + releases the swap page to OS +================ +*/ +void idHeap::ReleaseSwappedPages () { + if ( swapPage ) { + FreePageReal( swapPage ); + } + swapPage = NULL; +} + +/* +================ +idHeap::AllocatePage + + allocates memory from the OS + bytes = page size in bytes + returns pointer to page +================ +*/ +idHeap::page_s* idHeap::AllocatePage( dword bytes ) { + idHeap::page_s* p; + + pageRequests++; + + if ( swapPage && swapPage->dataSize == bytes ) { // if we've got a swap page somewhere + p = swapPage; + swapPage = NULL; + } + else { + dword size; + + size = bytes + sizeof(idHeap::page_s); + + p = (idHeap::page_s *) ::malloc( size + ALIGN - 1 ); + if ( !p ) { + if ( defragBlock ) { + idLib::common->Printf( "Freeing defragBlock on alloc of %i.\n", size + ALIGN - 1 ); + free( defragBlock ); + defragBlock = NULL; + p = (idHeap::page_s *) ::malloc( size + ALIGN - 1 ); + AllocDefragBlock(); + } + if ( !p ) { + common->FatalError( "malloc failure for %i", bytes ); + } + } + + p->data = (void *) ALIGN_SIZE( (int)((byte *)(p)) + sizeof( idHeap::page_s ) ); + p->dataSize = size - sizeof(idHeap::page_s); + p->firstFree = NULL; + p->largestFree = 0; + OSAllocs++; + } + + p->prev = NULL; + p->next = NULL; + + pagesAllocated++; + + return p; +} + +/* +================ +idHeap::FreePage + + frees a page back to the operating system + p = pointer to page +================ +*/ +void idHeap::FreePage( idHeap::page_s *p ) { + assert( p ); + + if ( p->dataSize == pageSize && !swapPage ) { // add to swap list? + swapPage = p; + } + else { + FreePageReal( p ); + } + + pagesAllocated--; +} + +//=============================================================== +// +// small heap code +// +//=============================================================== + +/* +================ +idHeap::SmallAllocate + + allocate memory (1-255 bytes) from the small heap manager + bytes = number of bytes to allocate + returns pointer to allocated memory +================ +*/ +void *idHeap::SmallAllocate( dword bytes ) { + // we need the at least sizeof( dword ) bytes for the free list + if ( bytes < sizeof( dword ) ) { + bytes = sizeof( dword ); + } + + // increase the number of bytes if necessary to make sure the next small allocation is aligned + bytes = SMALL_ALIGN( bytes ); + + byte *smallBlock = (byte *)(smallFirstFree[bytes / ALIGN]); + if ( smallBlock ) { + dword *link = (dword *)(smallBlock + SMALL_HEADER_SIZE); + smallBlock[1] = SMALL_ALLOC; // allocation identifier + smallFirstFree[bytes / ALIGN] = (void *)(*link); + return (void *)(link); + } + + dword bytesLeft = (long)(pageSize) - smallCurPageOffset; + // if we need to allocate a new page + if ( bytes >= bytesLeft ) { + + smallCurPage->next = smallFirstUsedPage; + smallFirstUsedPage = smallCurPage; + smallCurPage = AllocatePage( pageSize ); + if ( !smallCurPage ) { + return NULL; + } + // make sure the first allocation is aligned + smallCurPageOffset = SMALL_ALIGN( 0 ); + } + + smallBlock = ((byte *)smallCurPage->data) + smallCurPageOffset; + smallBlock[0] = (byte)(bytes / ALIGN); // write # of bytes/ALIGN + smallBlock[1] = SMALL_ALLOC; // allocation identifier + smallCurPageOffset += bytes + SMALL_HEADER_SIZE; // increase the offset on the current page + return ( smallBlock + SMALL_HEADER_SIZE ); // skip the first two bytes +} + +/* +================ +idHeap::SmallFree + + frees a block of memory allocated by SmallAllocate() call + data = pointer to block of memory +================ +*/ +void idHeap::SmallFree( void *ptr ) { + ((byte *)(ptr))[-1] = INVALID_ALLOC; + + byte *d = ( (byte *)ptr ) - SMALL_HEADER_SIZE; + dword *dt = (dword *)ptr; + // index into the table with free small memory blocks + dword ix = *d; + + // check if the index is correct + if ( ix > (256 / ALIGN) ) { + idLib::common->FatalError( "SmallFree: invalid memory block" ); + } + + *dt = (dword)smallFirstFree[ix]; // write next index + smallFirstFree[ix] = (void *)d; // link +} + +//=============================================================== +// +// medium heap code +// +// Medium-heap allocated pages not returned to OS until heap destructor +// called (re-used instead on subsequent medium-size malloc requests). +// +//=============================================================== + +/* +================ +idHeap::MediumAllocateFromPage + + performs allocation using the medium heap manager from a given page + p = page + sizeNeeded = # of bytes needed + returns pointer to allocated memory +================ +*/ +void *idHeap::MediumAllocateFromPage( idHeap::page_s *p, dword sizeNeeded ) { + + mediumHeapEntry_s *best,*nw = NULL; + byte *ret; + + best = (mediumHeapEntry_s *)(p->firstFree); // first block is largest + + assert( best ); + assert( best->size == p->largestFree ); + assert( best->size >= sizeNeeded ); + + // if we can allocate another block from this page after allocating sizeNeeded bytes + if ( best->size >= (dword)( sizeNeeded + MEDIUM_SMALLEST_SIZE ) ) { + nw = (mediumHeapEntry_s *)((byte *)best + best->size - sizeNeeded); + nw->page = p; + nw->prev = best; + nw->next = best->next; + nw->prevFree = NULL; + nw->nextFree = NULL; + nw->size = sizeNeeded; + nw->freeBlock = 0; // used block + if ( best->next ) { + best->next->prev = nw; + } + best->next = nw; + best->size -= sizeNeeded; + + p->largestFree = best->size; + } + else { + if ( best->prevFree ) { + best->prevFree->nextFree = best->nextFree; + } + else { + p->firstFree = (void *)best->nextFree; + } + if ( best->nextFree ) { + best->nextFree->prevFree = best->prevFree; + } + + best->prevFree = NULL; + best->nextFree = NULL; + best->freeBlock = 0; // used block + nw = best; + + p->largestFree = 0; + } + + ret = (byte *)(nw) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ); + ret[-1] = MEDIUM_ALLOC; // allocation identifier + + return (void *)(ret); +} + +/* +================ +idHeap::MediumAllocate + + allocate memory (256-32768 bytes) from medium heap manager + bytes = number of bytes to allocate + returns pointer to allocated memory +================ +*/ +void *idHeap::MediumAllocate( dword bytes ) { + idHeap::page_s *p; + void *data; + + dword sizeNeeded = ALIGN_SIZE( bytes ) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ); + + // find first page with enough space + for ( p = mediumFirstFreePage; p; p = p->next ) { + if ( p->largestFree >= sizeNeeded ) { + break; + } + } + + if ( !p ) { // need to allocate new page? + p = AllocatePage( pageSize ); + if ( !p ) { + return NULL; // malloc failure! + } + p->prev = NULL; + p->next = mediumFirstFreePage; + if (p->next) { + p->next->prev = p; + } + else { + mediumLastFreePage = p; + } + + mediumFirstFreePage = p; + + p->largestFree = pageSize; + p->firstFree = (void *)p->data; + + mediumHeapEntry_s *e; + e = (mediumHeapEntry_s *)(p->firstFree); + e->page = p; + // make sure ((byte *)e + e->size) is aligned + e->size = pageSize & ~(ALIGN - 1); + e->prev = NULL; + e->next = NULL; + e->prevFree = NULL; + e->nextFree = NULL; + e->freeBlock = 1; + } + + data = MediumAllocateFromPage( p, sizeNeeded ); // allocate data from page + + // if the page can no longer serve memory, move it away from free list + // (so that it won't slow down the later alloc queries) + // this modification speeds up the pageWalk from O(N) to O(sqrt(N)) + // a call to free may swap this page back to the free list + + if ( p->largestFree < MEDIUM_SMALLEST_SIZE ) { + if ( p == mediumLastFreePage ) { + mediumLastFreePage = p->prev; + } + + if ( p == mediumFirstFreePage ) { + mediumFirstFreePage = p->next; + } + + if ( p->prev ) { + p->prev->next = p->next; + } + if ( p->next ) { + p->next->prev = p->prev; + } + + // link to "completely used" list + p->prev = NULL; + p->next = mediumFirstUsedPage; + if ( p->next ) { + p->next->prev = p; + } + mediumFirstUsedPage = p; + return data; + } + + // re-order linked list (so that next malloc query starts from current + // matching block) -- this speeds up both the page walks and block walks + + if ( p != mediumFirstFreePage ) { + assert( mediumLastFreePage ); + assert( mediumFirstFreePage ); + assert( p->prev); + + mediumLastFreePage->next = mediumFirstFreePage; + mediumFirstFreePage->prev = mediumLastFreePage; + mediumLastFreePage = p->prev; + p->prev->next = NULL; + p->prev = NULL; + mediumFirstFreePage = p; + } + + return data; +} + +/* +================ +idHeap::MediumFree + + frees a block allocated by the medium heap manager + ptr = pointer to data block +================ +*/ +void idHeap::MediumFree( void *ptr ) { + ((byte *)(ptr))[-1] = INVALID_ALLOC; + + mediumHeapEntry_s *e = (mediumHeapEntry_s *)((byte *)ptr - ALIGN_SIZE( MEDIUM_HEADER_SIZE )); + idHeap::page_s *p = e->page; + bool isInFreeList; + + isInFreeList = p->largestFree >= MEDIUM_SMALLEST_SIZE; + + assert( e->size ); + assert( e->freeBlock == 0 ); + + mediumHeapEntry_s *prev = e->prev; + + // if the previous block is free we can merge + if ( prev && prev->freeBlock ) { + prev->size += e->size; + prev->next = e->next; + if ( e->next ) { + e->next->prev = prev; + } + e = prev; + } + else { + e->prevFree = NULL; // link to beginning of free list + e->nextFree = (mediumHeapEntry_s *)p->firstFree; + if ( e->nextFree ) { + assert( !(e->nextFree->prevFree) ); + e->nextFree->prevFree = e; + } + + p->firstFree = e; + p->largestFree = e->size; + e->freeBlock = 1; // mark block as free + } + + mediumHeapEntry_s *next = e->next; + + // if the next block is free we can merge + if ( next && next->freeBlock ) { + e->size += next->size; + e->next = next->next; + + if ( next->next ) { + next->next->prev = e; + } + + if ( next->prevFree ) { + next->prevFree->nextFree = next->nextFree; + } + else { + assert( next == p->firstFree ); + p->firstFree = next->nextFree; + } + + if ( next->nextFree ) { + next->nextFree->prevFree = next->prevFree; + } + } + + if ( p->firstFree ) { + p->largestFree = ((mediumHeapEntry_s *)(p->firstFree))->size; + } + else { + p->largestFree = 0; + } + + // did e become the largest block of the page ? + + if ( e->size > p->largestFree ) { + assert( e != p->firstFree ); + p->largestFree = e->size; + + if ( e->prevFree ) { + e->prevFree->nextFree = e->nextFree; + } + if ( e->nextFree ) { + e->nextFree->prevFree = e->prevFree; + } + + e->nextFree = (mediumHeapEntry_s *)p->firstFree; + e->prevFree = NULL; + if ( e->nextFree ) { + e->nextFree->prevFree = e; + } + p->firstFree = e; + } + + // if page wasn't in free list (because it was near-full), move it back there + if ( !isInFreeList ) { + + // remove from "completely used" list + if ( p->prev ) { + p->prev->next = p->next; + } + if ( p->next ) { + p->next->prev = p->prev; + } + if ( p == mediumFirstUsedPage ) { + mediumFirstUsedPage = p->next; + } + + p->next = NULL; + p->prev = mediumLastFreePage; + + if ( mediumLastFreePage ) { + mediumLastFreePage->next = p; + } + mediumLastFreePage = p; + if ( !mediumFirstFreePage ) { + mediumFirstFreePage = p; + } + } +} + +//=============================================================== +// +// large heap code +// +//=============================================================== + +/* +================ +idHeap::LargeAllocate + + allocates a block of memory from the operating system + bytes = number of bytes to allocate + returns pointer to allocated memory +================ +*/ +void *idHeap::LargeAllocate( dword bytes ) { + idHeap::page_s *p = AllocatePage( bytes + ALIGN_SIZE( LARGE_HEADER_SIZE ) ); + + assert( p ); + + if ( !p ) { + return NULL; + } + + byte * d = (byte*)(p->data) + ALIGN_SIZE( LARGE_HEADER_SIZE ); + dword * dw = (dword*)(d - ALIGN_SIZE( LARGE_HEADER_SIZE )); + dw[0] = (dword)p; // write pointer back to page table + d[-1] = LARGE_ALLOC; // allocation identifier + + // link to 'large used page list' + p->prev = NULL; + p->next = largeFirstUsedPage; + if ( p->next ) { + p->next->prev = p; + } + largeFirstUsedPage = p; + + return (void *)(d); +} + +/* +================ +idHeap::LargeFree + + frees a block of memory allocated by the 'large memory allocator' + p = pointer to allocated memory +================ +*/ +void idHeap::LargeFree( void *ptr) { + idHeap::page_s* pg; + + ((byte *)(ptr))[-1] = INVALID_ALLOC; + + // get page pointer + pg = (idHeap::page_s *)(*((dword *)(((byte *)ptr) - ALIGN_SIZE( LARGE_HEADER_SIZE )))); + + // unlink from doubly linked list + if ( pg->prev ) { + pg->prev->next = pg->next; + } + if ( pg->next ) { + pg->next->prev = pg->prev; + } + if ( pg == largeFirstUsedPage ) { + largeFirstUsedPage = pg->next; + } + pg->next = pg->prev = NULL; + + FreePage(pg); +} + +//=============================================================== +// +// memory allocation all in one place +// +//=============================================================== + +#undef new + +static idHeap * mem_heap = NULL; +static memoryStats_t mem_total_allocs = { 0, 0x0fffffff, -1, 0 }; +static memoryStats_t mem_frame_allocs; +static memoryStats_t mem_frame_frees; + +/* +================== +Mem_ClearFrameStats +================== +*/ +void Mem_ClearFrameStats( void ) { + mem_frame_allocs.num = mem_frame_frees.num = 0; + mem_frame_allocs.minSize = mem_frame_frees.minSize = 0x0fffffff; + mem_frame_allocs.maxSize = mem_frame_frees.maxSize = -1; + mem_frame_allocs.totalSize = mem_frame_frees.totalSize = 0; +} + +/* +================== +Mem_GetFrameStats +================== +*/ +void Mem_GetFrameStats( memoryStats_t &allocs, memoryStats_t &frees ) { + allocs = mem_frame_allocs; + frees = mem_frame_frees; +} + +/* +================== +Mem_GetStats +================== +*/ +void Mem_GetStats( memoryStats_t &stats ) { + stats = mem_total_allocs; +} + +/* +================== +Mem_UpdateStats +================== +*/ +void Mem_UpdateStats( memoryStats_t &stats, int size ) { + stats.num++; + if ( size < stats.minSize ) { + stats.minSize = size; + } + if ( size > stats.maxSize ) { + stats.maxSize = size; + } + stats.totalSize += size; +} + +/* +================== +Mem_UpdateAllocStats +================== +*/ +void Mem_UpdateAllocStats( int size ) { + Mem_UpdateStats( mem_frame_allocs, size ); + Mem_UpdateStats( mem_total_allocs, size ); +} + +/* +================== +Mem_UpdateFreeStats +================== +*/ +void Mem_UpdateFreeStats( int size ) { + Mem_UpdateStats( mem_frame_frees, size ); + mem_total_allocs.num--; + mem_total_allocs.totalSize -= size; +} + + +#ifndef ID_DEBUG_MEMORY + +/* +================== +Mem_Alloc +================== +*/ +void *Mem_Alloc( const int size ) { + if ( !size ) { + return NULL; + } + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + return malloc( size ); + } + void *mem = mem_heap->Allocate( size ); + Mem_UpdateAllocStats( mem_heap->Msize( mem ) ); + return mem; +} + +/* +================== +Mem_Free +================== +*/ +void Mem_Free( void *ptr ) { + if ( !ptr ) { + return; + } + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + free( ptr ); + return; + } + Mem_UpdateFreeStats( mem_heap->Msize( ptr ) ); + mem_heap->Free( ptr ); +} + +/* +================== +Mem_Alloc16 +================== +*/ +void *Mem_Alloc16( const int size ) { + if ( !size ) { + return NULL; + } + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + return malloc( size ); + } + void *mem = mem_heap->Allocate16( size ); + // make sure the memory is 16 byte aligned + assert( ( ((int)mem) & 15) == 0 ); + return mem; +} + +/* +================== +Mem_Free16 +================== +*/ +void Mem_Free16( void *ptr ) { + if ( !ptr ) { + return; + } + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + free( ptr ); + return; + } + // make sure the memory is 16 byte aligned + assert( ( ((int)ptr) & 15) == 0 ); + mem_heap->Free16( ptr ); +} + +/* +================== +Mem_ClearedAlloc +================== +*/ +void *Mem_ClearedAlloc( const int size ) { + void *mem = Mem_Alloc( size ); + SIMDProcessor->Memset( mem, 0, size ); + return mem; +} + +/* +================== +Mem_ClearedAlloc +================== +*/ +void Mem_AllocDefragBlock( void ) { + mem_heap->AllocDefragBlock(); +} + +/* +================== +Mem_CopyString +================== +*/ +char *Mem_CopyString( const char *in ) { + char *out; + + out = (char *)Mem_Alloc( strlen(in) + 1 ); + strcpy( out, in ); + return out; +} + +/* +================== +Mem_Dump_f +================== +*/ +void Mem_Dump_f( const idCmdArgs &args ) { +} + +/* +================== +Mem_DumpCompressed_f +================== +*/ +void Mem_DumpCompressed_f( const idCmdArgs &args ) { +} + +/* +================== +Mem_Init +================== +*/ +void Mem_Init( void ) { + mem_heap = new idHeap; + Mem_ClearFrameStats(); +} + +/* +================== +Mem_Shutdown +================== +*/ +void Mem_Shutdown( void ) { + idHeap *m = mem_heap; + mem_heap = NULL; + delete m; +} + +/* +================== +Mem_EnableLeakTest +================== +*/ +void Mem_EnableLeakTest( const char *name ) { +} + + +#else /* !ID_DEBUG_MEMORY */ + +#undef Mem_Alloc +#undef Mem_ClearedAlloc +#undef Com_ClearedReAlloc +#undef Mem_Free +#undef Mem_CopyString +#undef Mem_Alloc16 +#undef Mem_Free16 + +#define MAX_CALLSTACK_DEPTH 6 + +// size of this struct must be a multiple of 16 bytes +typedef struct debugMemory_s { + const char * fileName; + int lineNumber; + int frameNumber; + int size; + address_t callStack[MAX_CALLSTACK_DEPTH]; + struct debugMemory_s * prev; + struct debugMemory_s * next; +} debugMemory_t; + +static debugMemory_t * mem_debugMemory = NULL; +static char mem_leakName[256] = ""; + +/* +================== +Mem_CleanupFileName +================== +*/ +const char *Mem_CleanupFileName( const char *fileName ) { + int i1, i2; + idStr newFileName; + static char newFileNames[4][MAX_STRING_CHARS]; + static int index; + + newFileName = fileName; + newFileName.BackSlashesToSlashes(); + i1 = newFileName.Find( "neo", false ); + if ( i1 >= 0 ) { + i1 = newFileName.Find( "/", false, i1 ); + newFileName = newFileName.Right( newFileName.Length() - ( i1 + 1 ) ); + } + while( 1 ) { + i1 = newFileName.Find( "/../" ); + if ( i1 <= 0 ) { + break; + } + i2 = i1 - 1; + while( i2 > 1 && newFileName[i2-1] != '/' ) { + i2--; + } + newFileName = newFileName.Left( i2 - 1 ) + newFileName.Right( newFileName.Length() - ( i1 + 4 ) ); + } + index = ( index + 1 ) & 3; + strncpy( newFileNames[index], newFileName.c_str(), sizeof( newFileNames[index] ) ); + return newFileNames[index]; +} + +/* +================== +Mem_Dump +================== +*/ +void Mem_Dump( const char *fileName ) { + int i, numBlocks, totalSize; + char dump[32], *ptr; + debugMemory_t *b; + idStr module, funcName; + FILE *f; + + f = fopen( fileName, "wb" ); + if ( !f ) { + return; + } + + totalSize = 0; + for ( numBlocks = 0, b = mem_debugMemory; b; b = b->next, numBlocks++ ) { + ptr = ((char *) b) + sizeof(debugMemory_t); + totalSize += b->size; + for ( i = 0; i < (sizeof(dump)-1) && i < b->size; i++) { + if ( ptr[i] >= 32 && ptr[i] < 127 ) { + dump[i] = ptr[i]; + } else { + dump[i] = '_'; + } + } + dump[i] = '\0'; + if ( ( b->size >> 10 ) != 0 ) { + fprintf( f, "size: %6d KB: %s, line: %d [%s], call stack: %s\r\n", ( b->size >> 10 ), Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) ); + } + else { + fprintf( f, "size: %7d B: %s, line: %d [%s], call stack: %s\r\n", b->size, Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) ); + } + } + + idLib::sys->ShutdownSymbols(); + + fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks ); + fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) ); + + fclose( f ); +} + +/* +================== +Mem_Dump_f +================== +*/ +void Mem_Dump_f( const idCmdArgs &args ) { + const char *fileName; + + if ( args.Argc() >= 2 ) { + fileName = args.Argv( 1 ); + } + else { + fileName = "memorydump.txt"; + } + Mem_Dump( fileName ); +} + +/* +================== +Mem_DumpCompressed +================== +*/ +typedef struct allocInfo_s { + const char * fileName; + int lineNumber; + int size; + int numAllocs; + address_t callStack[MAX_CALLSTACK_DEPTH]; + struct allocInfo_s * next; +} allocInfo_t; + +typedef enum { + MEMSORT_SIZE, + MEMSORT_LOCATION, + MEMSORT_NUMALLOCS, + MEMSORT_CALLSTACK +} memorySortType_t; + +void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sortCallStack, int numFrames ) { + int numBlocks, totalSize, r, j; + debugMemory_t *b; + allocInfo_t *a, *nexta, *allocInfo = NULL, *sortedAllocInfo = NULL, *prevSorted = NULL, *nextSorted = NULL; + idStr module, funcName; + FILE *f; + + // build list with memory allocations + totalSize = 0; + numBlocks = 0; + for ( b = mem_debugMemory; b; b = b->next ) { + + if ( numFrames && b->frameNumber < idLib::frameNumber - numFrames ) { + continue; + } + + numBlocks++; + totalSize += b->size; + + // search for an allocation from the same source location + for ( a = allocInfo; a; a = a->next ) { + if ( a->lineNumber != b->lineNumber ) { + continue; + } + for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) { + if ( a->callStack[j] != b->callStack[j] ) { + break; + } + } + if ( j < MAX_CALLSTACK_DEPTH ) { + continue; + } + if ( idStr::Cmp( a->fileName, b->fileName ) != 0 ) { + continue; + } + a->numAllocs++; + a->size += b->size; + break; + } + + // if this is an allocation from a new source location + if ( !a ) { + a = (allocInfo_t *) ::malloc( sizeof( allocInfo_t ) ); + a->fileName = b->fileName; + a->lineNumber = b->lineNumber; + a->size = b->size; + a->numAllocs = 1; + for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) { + a->callStack[j] = b->callStack[j]; + } + a->next = allocInfo; + allocInfo = a; + } + } + + // sort list + for ( a = allocInfo; a; a = nexta ) { + nexta = a->next; + + prevSorted = NULL; + switch( memSort ) { + // sort on size + case MEMSORT_SIZE: { + for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { + if ( a->size > nextSorted->size ) { + break; + } + prevSorted = nextSorted; + } + break; + } + // sort on file name and line number + case MEMSORT_LOCATION: { + for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { + r = idStr::Cmp( Mem_CleanupFileName( a->fileName ), Mem_CleanupFileName( nextSorted->fileName ) ); + if ( r < 0 || ( r == 0 && a->lineNumber < nextSorted->lineNumber ) ) { + break; + } + prevSorted = nextSorted; + } + break; + } + // sort on the number of allocations + case MEMSORT_NUMALLOCS: { + for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { + if ( a->numAllocs > nextSorted->numAllocs ) { + break; + } + prevSorted = nextSorted; + } + break; + } + // sort on call stack + case MEMSORT_CALLSTACK: { + for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { + if ( a->callStack[sortCallStack] < nextSorted->callStack[sortCallStack] ) { + break; + } + prevSorted = nextSorted; + } + break; + } + } + if ( !prevSorted ) { + a->next = sortedAllocInfo; + sortedAllocInfo = a; + } + else { + prevSorted->next = a; + a->next = nextSorted; + } + } + + f = fopen( fileName, "wb" ); + if ( !f ) { + return; + } + + // write list to file + for ( a = sortedAllocInfo; a; a = nexta ) { + nexta = a->next; + fprintf( f, "size: %6d KB, allocs: %5d: %s, line: %d, call stack: %s\r\n", + (a->size >> 10), a->numAllocs, Mem_CleanupFileName(a->fileName), + a->lineNumber, idLib::sys->GetCallStackStr( a->callStack, MAX_CALLSTACK_DEPTH ) ); + ::free( a ); + } + + idLib::sys->ShutdownSymbols(); + + fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks ); + fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) ); + + fclose( f ); +} + +/* +================== +Mem_DumpCompressed_f +================== +*/ +void Mem_DumpCompressed_f( const idCmdArgs &args ) { + int argNum; + const char *arg, *fileName; + memorySortType_t memSort = MEMSORT_LOCATION; + int sortCallStack = 0, numFrames = 0; + + // get cmd-line options + argNum = 1; + arg = args.Argv( argNum ); + while( arg[0] == '-' ) { + arg = args.Argv( ++argNum ); + if ( idStr::Icmp( arg, "s" ) == 0 ) { + memSort = MEMSORT_SIZE; + } else if ( idStr::Icmp( arg, "l" ) == 0 ) { + memSort = MEMSORT_LOCATION; + } else if ( idStr::Icmp( arg, "a" ) == 0 ) { + memSort = MEMSORT_NUMALLOCS; + } else if ( idStr::Icmp( arg, "cs1" ) == 0 ) { + memSort = MEMSORT_CALLSTACK; + sortCallStack = 2; + } else if ( idStr::Icmp( arg, "cs2" ) == 0 ) { + memSort = MEMSORT_CALLSTACK; + sortCallStack = 1; + } else if ( idStr::Icmp( arg, "cs3" ) == 0 ) { + memSort = MEMSORT_CALLSTACK; + sortCallStack = 0; + } else if ( arg[0] == 'f' ) { + numFrames = atoi( arg + 1 ); + } else { + idLib::common->Printf( "memoryDumpCompressed [options] [filename]\n" + "options:\n" + " -s sort on size\n" + " -l sort on location\n" + " -a sort on the number of allocations\n" + " -cs1 sort on first function on call stack\n" + " -cs2 sort on second function on call stack\n" + " -cs3 sort on third function on call stack\n" + " -f only report allocations the last X frames\n" + "By default the memory allocations are sorted on location.\n" + "By default a 'memorydump.txt' is written if no file name is specified.\n" ); + return; + } + arg = args.Argv( ++argNum ); + } + if ( argNum >= args.Argc() ) { + fileName = "memorydump.txt"; + } else { + fileName = arg; + } + Mem_DumpCompressed( fileName, memSort, sortCallStack, numFrames ); +} + +/* +================== +Mem_AllocDebugMemory +================== +*/ +void *Mem_AllocDebugMemory( const int size, const char *fileName, const int lineNumber, const bool align16 ) { + void *p; + debugMemory_t *m; + + if ( !size ) { + return NULL; + } + + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + // NOTE: set a breakpoint here to find memory allocations before mem_heap is initialized + return malloc( size ); + } + + if ( align16 ) { + p = mem_heap->Allocate16( size + sizeof( debugMemory_t ) ); + } + else { + p = mem_heap->Allocate( size + sizeof( debugMemory_t ) ); + } + + Mem_UpdateAllocStats( size ); + + m = (debugMemory_t *) p; + m->fileName = fileName; + m->lineNumber = lineNumber; + m->frameNumber = idLib::frameNumber; + m->size = size; + m->next = mem_debugMemory; + m->prev = NULL; + if ( mem_debugMemory ) { + mem_debugMemory->prev = m; + } + mem_debugMemory = m; + idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH ); + + return ( ( (byte *) p ) + sizeof( debugMemory_t ) ); +} + +/* +================== +Mem_FreeDebugMemory +================== +*/ +void Mem_FreeDebugMemory( void *p, const char *fileName, const int lineNumber, const bool align16 ) { + debugMemory_t *m; + + if ( !p ) { + return; + } + + if ( !mem_heap ) { +#ifdef CRASH_ON_STATIC_ALLOCATION + *((int*)0x0) = 1; +#endif + // NOTE: set a breakpoint here to find memory being freed before mem_heap is initialized + free( p ); + return; + } + + m = (debugMemory_t *) ( ( (byte *) p ) - sizeof( debugMemory_t ) ); + + if ( m->size < 0 ) { + idLib::common->FatalError( "memory freed twice, first from %s, now from %s", idLib::sys->GetCallStackStr( m->callStack, MAX_CALLSTACK_DEPTH ), idLib::sys->GetCallStackCurStr( MAX_CALLSTACK_DEPTH ) ); + } + + Mem_UpdateFreeStats( m->size ); + + if ( m->next ) { + m->next->prev = m->prev; + } + if ( m->prev ) { + m->prev->next = m->next; + } + else { + mem_debugMemory = m->next; + } + + m->fileName = fileName; + m->lineNumber = lineNumber; + m->frameNumber = idLib::frameNumber; + m->size = -m->size; + idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH ); + + if ( align16 ) { + mem_heap->Free16( m ); + } + else { + mem_heap->Free( m ); + } +} + +/* +================== +Mem_Alloc +================== +*/ +void *Mem_Alloc( const int size, const char *fileName, const int lineNumber ) { + if ( !size ) { + return NULL; + } + return Mem_AllocDebugMemory( size, fileName, lineNumber, false ); +} + +/* +================== +Mem_Free +================== +*/ +void Mem_Free( void *ptr, const char *fileName, const int lineNumber ) { + if ( !ptr ) { + return; + } + Mem_FreeDebugMemory( ptr, fileName, lineNumber, false ); +} + +/* +================== +Mem_Alloc16 +================== +*/ +void *Mem_Alloc16( const int size, const char *fileName, const int lineNumber ) { + if ( !size ) { + return NULL; + } + void *mem = Mem_AllocDebugMemory( size, fileName, lineNumber, true ); + // make sure the memory is 16 byte aligned + assert( ( ((int)mem) & 15) == 0 ); + return mem; +} + +/* +================== +Mem_Free16 +================== +*/ +void Mem_Free16( void *ptr, const char *fileName, const int lineNumber ) { + if ( !ptr ) { + return; + } + // make sure the memory is 16 byte aligned + assert( ( ((int)ptr) & 15) == 0 ); + Mem_FreeDebugMemory( ptr, fileName, lineNumber, true ); +} + +/* +================== +Mem_ClearedAlloc +================== +*/ +void *Mem_ClearedAlloc( const int size, const char *fileName, const int lineNumber ) { + void *mem = Mem_Alloc( size, fileName, lineNumber ); + SIMDProcessor->Memset( mem, 0, size ); + return mem; +} + +/* +================== +Mem_CopyString +================== +*/ +char *Mem_CopyString( const char *in, const char *fileName, const int lineNumber ) { + char *out; + + out = (char *)Mem_Alloc( strlen(in) + 1, fileName, lineNumber ); + strcpy( out, in ); + return out; +} + +/* +================== +Mem_Init +================== +*/ +void Mem_Init( void ) { + mem_heap = new idHeap; +} + +/* +================== +Mem_Shutdown +================== +*/ +void Mem_Shutdown( void ) { + + if ( mem_leakName[0] != '\0' ) { + Mem_DumpCompressed( va( "%s_leak_size.txt", mem_leakName ), MEMSORT_SIZE, 0, 0 ); + Mem_DumpCompressed( va( "%s_leak_location.txt", mem_leakName ), MEMSORT_LOCATION, 0, 0 ); + Mem_DumpCompressed( va( "%s_leak_cs1.txt", mem_leakName ), MEMSORT_CALLSTACK, 2, 0 ); + } + + idHeap *m = mem_heap; + mem_heap = NULL; + delete m; +} + +/* +================== +Mem_EnableLeakTest +================== +*/ +void Mem_EnableLeakTest( const char *name ) { + idStr::Copynz( mem_leakName, name, sizeof( mem_leakName ) ); +} + +#endif /* !ID_DEBUG_MEMORY */ diff --git a/idlib/Heap.h b/idlib/Heap.h new file mode 100644 index 000000000..76989cda0 --- /dev/null +++ b/idlib/Heap.h @@ -0,0 +1,883 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __HEAP_H__ +#define __HEAP_H__ + +#include "math/Math.h" // OrbWeaver: Max() macro + +#include + +/* +=============================================================================== + + Memory Management + + This is a replacement for the compiler heap code (i.e. "C" malloc() and + free() calls). On average 2.5-3.0 times faster than MSVC malloc()/free(). + Worst case performance is 1.65 times faster and best case > 70 times. + +=============================================================================== +*/ + + +typedef struct { + int num; + int minSize; + int maxSize; + int totalSize; +} memoryStats_t; + + +void Mem_Init( void ); +void Mem_Shutdown( void ); +void Mem_EnableLeakTest( const char *name ); +void Mem_ClearFrameStats( void ); +void Mem_GetFrameStats( memoryStats_t &allocs, memoryStats_t &frees ); +void Mem_GetStats( memoryStats_t &stats ); +void Mem_Dump_f( const class idCmdArgs &args ); +void Mem_DumpCompressed_f( const class idCmdArgs &args ); +void Mem_AllocDefragBlock( void ); + + +#ifndef ID_DEBUG_MEMORY + +void * Mem_Alloc( const int size ); +void * Mem_ClearedAlloc( const int size ); +void Mem_Free( void *ptr ); +char * Mem_CopyString( const char *in ); +void * Mem_Alloc16( const int size ); +void Mem_Free16( void *ptr ); + +#ifdef ID_REDIRECT_NEWDELETE + +__inline void *operator new( size_t s ) { + return Mem_Alloc( s ); +} +__inline void operator delete( void *p ) { + Mem_Free( p ); +} +__inline void *operator new[]( size_t s ) { + return Mem_Alloc( s ); +} +__inline void operator delete[]( void *p ) { + Mem_Free( p ); +} + +#endif + +#else /* ID_DEBUG_MEMORY */ + +void * Mem_Alloc( const int size, const char *fileName, const int lineNumber ); +void * Mem_ClearedAlloc( const int size, const char *fileName, const int lineNumber ); +void Mem_Free( void *ptr, const char *fileName, const int lineNumber ); +char * Mem_CopyString( const char *in, const char *fileName, const int lineNumber ); +void * Mem_Alloc16( const int size, const char *fileName, const int lineNumber ); +void Mem_Free16( void *ptr, const char *fileName, const int lineNumber ); + +#ifdef ID_REDIRECT_NEWDELETE + +__inline void *operator new( size_t s, int t1, int t2, char *fileName, int lineNumber ) { + return Mem_Alloc( s, fileName, lineNumber ); +} +__inline void operator delete( void *p, int t1, int t2, char *fileName, int lineNumber ) { + Mem_Free( p, fileName, lineNumber ); +} +__inline void *operator new[]( size_t s, int t1, int t2, char *fileName, int lineNumber ) { + return Mem_Alloc( s, fileName, lineNumber ); +} +__inline void operator delete[]( void *p, int t1, int t2, char *fileName, int lineNumber ) { + Mem_Free( p, fileName, lineNumber ); +} +__inline void *operator new( size_t s ) { + return Mem_Alloc( s, "", 0 ); +} +__inline void operator delete( void *p ) { + Mem_Free( p, "", 0 ); +} +__inline void *operator new[]( size_t s ) { + return Mem_Alloc( s, "", 0 ); +} +__inline void operator delete[]( void *p ) { + Mem_Free( p, "", 0 ); +} + +#define ID_DEBUG_NEW new( 0, 0, __FILE__, __LINE__ ) +#undef new +#define new ID_DEBUG_NEW + +#endif + +#define Mem_Alloc( size ) Mem_Alloc( size, __FILE__, __LINE__ ) +#define Mem_ClearedAlloc( size ) Mem_ClearedAlloc( size, __FILE__, __LINE__ ) +#define Mem_Free( ptr ) Mem_Free( ptr, __FILE__, __LINE__ ) +#define Mem_CopyString( s ) Mem_CopyString( s, __FILE__, __LINE__ ) +#define Mem_Alloc16( size ) Mem_Alloc16( size, __FILE__, __LINE__ ) +#define Mem_Free16( ptr ) Mem_Free16( ptr, __FILE__, __LINE__ ) + +#endif /* ID_DEBUG_MEMORY */ + + +/* +=============================================================================== + + Block based allocator for fixed size objects. + + All objects of the 'type' are properly constructed. + However, the constructor is not called for re-used objects. + +=============================================================================== +*/ + +template +class idBlockAlloc { +public: + idBlockAlloc( void ); + ~idBlockAlloc( void ); + + void Shutdown( void ); + + type * Alloc( void ); + void Free( type *element ); + + int GetTotalCount( void ) const { return total; } + int GetAllocCount( void ) const { return active; } + int GetFreeCount( void ) const { return total - active; } + +private: + typedef struct element_s { + struct element_s * next; + type t; + } element_t; + typedef struct block_s { + element_t elements[blockSize]; + struct block_s * next; + } block_t; + + block_t * blocks; + element_t * free; + int total; + int active; +}; + +template +idBlockAlloc::idBlockAlloc( void ) { + blocks = NULL; + free = NULL; + total = active = 0; +} + +template +idBlockAlloc::~idBlockAlloc( void ) { + Shutdown(); +} + +template +type *idBlockAlloc::Alloc( void ) { + if ( !free ) { + block_t *block = new block_t; + block->next = blocks; + blocks = block; + for ( int i = 0; i < blockSize; i++ ) { + block->elements[i].next = free; + free = &block->elements[i]; + } + total += blockSize; + } + active++; + element_t *element = free; + free = free->next; + element->next = NULL; + return &element->t; +} + +template +void idBlockAlloc::Free( type *t ) { + element_t *element = (element_t *)( ( (unsigned char *) t ) - ( (int) &((element_t *)0)->t ) ); + element->next = free; + free = element; + active--; +} + +template +void idBlockAlloc::Shutdown( void ) { + while( blocks ) { + block_t *block = blocks; + blocks = blocks->next; + delete block; + } + blocks = NULL; + free = NULL; + total = active = 0; +} + +/* +============================================================================== + + Dynamic allocator, simple wrapper for normal allocations which can + be interchanged with idDynamicBlockAlloc. + + No constructor is called for the 'type'. + Allocated blocks are always 16 byte aligned. + +============================================================================== +*/ + +template +class idDynamicAlloc { +public: + idDynamicAlloc( void ); + ~idDynamicAlloc( void ); + + void Init( void ); + void Shutdown( void ); + void SetFixedBlocks( int numBlocks ) {} + void SetLockMemory( bool lock ) {} + void FreeEmptyBaseBlocks( void ) {} + + type * Alloc( const int num ); + type * Resize( type *ptr, const int num ); + void Free( type *ptr ); + const char * CheckMemory( const type *ptr ) const; + + int GetNumBaseBlocks( void ) const { return 0; } + int GetBaseBlockMemory( void ) const { return 0; } + int GetNumUsedBlocks( void ) const { return numUsedBlocks; } + int GetUsedBlockMemory( void ) const { return usedBlockMemory; } + int GetNumFreeBlocks( void ) const { return 0; } + int GetFreeBlockMemory( void ) const { return 0; } + int GetNumEmptyBaseBlocks( void ) const { return 0; } + +private: + int numUsedBlocks; // number of used blocks + int usedBlockMemory; // total memory in used blocks + + int numAllocs; + int numResizes; + int numFrees; + + void Clear( void ); +}; + +template +idDynamicAlloc::idDynamicAlloc( void ) { + Clear(); +} + +template +idDynamicAlloc::~idDynamicAlloc( void ) { + Shutdown(); +} + +template +void idDynamicAlloc::Init( void ) { +} + +template +void idDynamicAlloc::Shutdown( void ) { + Clear(); +} + +template +type *idDynamicAlloc::Alloc( const int num ) { + numAllocs++; + if ( num <= 0 ) { + return NULL; + } + numUsedBlocks++; + usedBlockMemory += num * sizeof( type ); + return Mem_Alloc16( num * sizeof( type ) ); +} + +template +type *idDynamicAlloc::Resize( type *ptr, const int num ) { + + numResizes++; + + if ( ptr == NULL ) { + return Alloc( num ); + } + + if ( num <= 0 ) { + Free( ptr ); + return NULL; + } + + assert( 0 ); + return ptr; +} + +template +void idDynamicAlloc::Free( type *ptr ) { + numFrees++; + if ( ptr == NULL ) { + return; + } + Mem_Free16( ptr ); +} + +template +const char *idDynamicAlloc::CheckMemory( const type *ptr ) const { + return NULL; +} + +template +void idDynamicAlloc::Clear( void ) { + numUsedBlocks = 0; + usedBlockMemory = 0; + numAllocs = 0; + numResizes = 0; + numFrees = 0; +} + + +/* +============================================================================== + + Fast dynamic block allocator. + + No constructor is called for the 'type'. + Allocated blocks are always 16 byte aligned. + +============================================================================== +*/ + +#include "containers/BTree.h" + +//#define DYNAMIC_BLOCK_ALLOC_CHECK + +template +class idDynamicBlock { +public: + type * GetMemory( void ) const { return (type *)( ( (byte *) this ) + sizeof( idDynamicBlock ) ); } + int GetSize( void ) const { return abs( size ); } + void SetSize( int s, bool isBaseBlock ) { size = isBaseBlock ? -s : s; } + bool IsBaseBlock( void ) const { return ( size < 0 ); } + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + int id[3]; + void * allocator; +#endif + + int size; // size in bytes of the block + idDynamicBlock * prev; // previous memory block + idDynamicBlock * next; // next memory block + idBTreeNode,int> *node; // node in the B-Tree with free blocks +}; + +template +class idDynamicBlockAlloc { +public: + idDynamicBlockAlloc( void ); + ~idDynamicBlockAlloc( void ); + + void Init( void ); + void Shutdown( void ); + void SetFixedBlocks( int numBlocks ); + void SetLockMemory( bool lock ); + void FreeEmptyBaseBlocks( void ); + + type * Alloc( const int num ); + type * Resize( type *ptr, const int num ); + void Free( type *ptr ); + const char * CheckMemory( const type *ptr ) const; + + int GetNumBaseBlocks( void ) const { return numBaseBlocks; } + int GetBaseBlockMemory( void ) const { return baseBlockMemory; } + int GetNumUsedBlocks( void ) const { return numUsedBlocks; } + int GetUsedBlockMemory( void ) const { return usedBlockMemory; } + int GetNumFreeBlocks( void ) const { return numFreeBlocks; } + int GetFreeBlockMemory( void ) const { return freeBlockMemory; } + int GetNumEmptyBaseBlocks( void ) const; + +private: + idDynamicBlock * firstBlock; // first block in list in order of increasing address + idDynamicBlock * lastBlock; // last block in list in order of increasing address + idBTree,int,4>freeTree; // B-Tree with free memory blocks + bool allowAllocs; // allow base block allocations + bool lockMemory; // lock memory so it cannot get swapped out + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + int blockId[3]; +#endif + + int numBaseBlocks; // number of base blocks + int baseBlockMemory; // total memory in base blocks + int numUsedBlocks; // number of used blocks + int usedBlockMemory; // total memory in used blocks + int numFreeBlocks; // number of free blocks + int freeBlockMemory; // total memory in free blocks + + int numAllocs; + int numResizes; + int numFrees; + + void Clear( void ); + idDynamicBlock * AllocInternal( const int num ); + idDynamicBlock * ResizeInternal( idDynamicBlock *block, const int num ); + void FreeInternal( idDynamicBlock *block ); + void LinkFreeInternal( idDynamicBlock *block ); + void UnlinkFreeInternal( idDynamicBlock *block ); + void CheckMemory( void ) const; +}; + +template +idDynamicBlockAlloc::idDynamicBlockAlloc( void ) { + Clear(); +} + +template +idDynamicBlockAlloc::~idDynamicBlockAlloc( void ) { + Shutdown(); +} + +template +void idDynamicBlockAlloc::Init( void ) { + freeTree.Init(); +} + +template +void idDynamicBlockAlloc::Shutdown( void ) { + idDynamicBlock *block; + + for ( block = firstBlock; block != NULL; block = block->next ) { + if ( block->node == NULL ) { + FreeInternal( block ); + } + } + + for ( block = firstBlock; block != NULL; block = firstBlock ) { + firstBlock = block->next; + assert( block->IsBaseBlock() ); + if ( lockMemory ) { + idLib::sys->UnlockMemory( block, block->GetSize() + (int)sizeof( idDynamicBlock ) ); + } + Mem_Free16( block ); + } + + freeTree.Shutdown(); + + Clear(); +} + +template +void idDynamicBlockAlloc::SetFixedBlocks( int numBlocks ) { + idDynamicBlock *block; + + for ( int i = numBaseBlocks; i < numBlocks; i++ ) { + block = ( idDynamicBlock * ) Mem_Alloc16( baseBlockSize ); + if ( lockMemory ) { + idLib::sys->LockMemory( block, baseBlockSize ); + } +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + memcpy( block->id, blockId, sizeof( block->id ) ); + block->allocator = (void*)this; +#endif + block->SetSize( baseBlockSize - (int)sizeof( idDynamicBlock ), true ); + block->next = NULL; + block->prev = lastBlock; + if ( lastBlock ) { + lastBlock->next = block; + } else { + firstBlock = block; + } + lastBlock = block; + block->node = NULL; + + FreeInternal( block ); + + numBaseBlocks++; + baseBlockMemory += baseBlockSize; + } + + allowAllocs = false; +} + +template +void idDynamicBlockAlloc::SetLockMemory( bool lock ) { + lockMemory = lock; +} + +template +void idDynamicBlockAlloc::FreeEmptyBaseBlocks( void ) { + idDynamicBlock *block, *next; + + for ( block = firstBlock; block != NULL; block = next ) { + next = block->next; + + if ( block->IsBaseBlock() && block->node != NULL && ( next == NULL || next->IsBaseBlock() ) ) { + UnlinkFreeInternal( block ); + if ( block->prev ) { + block->prev->next = block->next; + } else { + firstBlock = block->next; + } + if ( block->next ) { + block->next->prev = block->prev; + } else { + lastBlock = block->prev; + } + if ( lockMemory ) { + idLib::sys->UnlockMemory( block, block->GetSize() + (int)sizeof( idDynamicBlock ) ); + } + numBaseBlocks--; + baseBlockMemory -= block->GetSize() + (int)sizeof( idDynamicBlock ); + Mem_Free16( block ); + } + } + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + CheckMemory(); +#endif +} + +template +int idDynamicBlockAlloc::GetNumEmptyBaseBlocks( void ) const { + int numEmptyBaseBlocks; + idDynamicBlock *block; + + numEmptyBaseBlocks = 0; + for ( block = firstBlock; block != NULL; block = block->next ) { + if ( block->IsBaseBlock() && block->node != NULL && ( block->next == NULL || block->next->IsBaseBlock() ) ) { + numEmptyBaseBlocks++; + } + } + return numEmptyBaseBlocks; +} + +template +type *idDynamicBlockAlloc::Alloc( const int num ) { + idDynamicBlock *block; + + numAllocs++; + + if ( num <= 0 ) { + return NULL; + } + + block = AllocInternal( num ); + if ( block == NULL ) { + return NULL; + } + block = ResizeInternal( block, num ); + if ( block == NULL ) { + return NULL; + } + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + CheckMemory(); +#endif + + numUsedBlocks++; + usedBlockMemory += block->GetSize(); + + return block->GetMemory(); +} + +template +type *idDynamicBlockAlloc::Resize( type *ptr, const int num ) { + + numResizes++; + + if ( ptr == NULL ) { + return Alloc( num ); + } + + if ( num <= 0 ) { + Free( ptr ); + return NULL; + } + + idDynamicBlock *block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); + + usedBlockMemory -= block->GetSize(); + + block = ResizeInternal( block, num ); + if ( block == NULL ) { + return NULL; + } + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + CheckMemory(); +#endif + + usedBlockMemory += block->GetSize(); + + return block->GetMemory(); +} + +template +void idDynamicBlockAlloc::Free( type *ptr ) { + + numFrees++; + + if ( ptr == NULL ) { + return; + } + + idDynamicBlock *block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); + + numUsedBlocks--; + usedBlockMemory -= block->GetSize(); + + FreeInternal( block ); + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + CheckMemory(); +#endif +} + +template +const char *idDynamicBlockAlloc::CheckMemory( const type *ptr ) const { + idDynamicBlock *block; + + if ( ptr == NULL ) { + return NULL; + } + + block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); + + if ( block->node != NULL ) { + return "memory has been freed"; + } + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + if ( block->id[0] != 0x11111111 || block->id[1] != 0x22222222 || block->id[2] != 0x33333333 ) { + return "memory has invalid id"; + } + if ( block->allocator != (void*)this ) { + return "memory was allocated with different allocator"; + } +#endif + + /* base blocks can be larger than baseBlockSize which can cause this code to fail + idDynamicBlock *base; + for ( base = firstBlock; base != NULL; base = base->next ) { + if ( base->IsBaseBlock() ) { + if ( ((int)block) >= ((int)base) && ((int)block) < ((int)base) + baseBlockSize ) { + break; + } + } + } + if ( base == NULL ) { + return "no base block found for memory"; + } + */ + + return NULL; +} + +template +void idDynamicBlockAlloc::Clear( void ) { + firstBlock = lastBlock = NULL; + allowAllocs = true; + lockMemory = false; + numBaseBlocks = 0; + baseBlockMemory = 0; + numUsedBlocks = 0; + usedBlockMemory = 0; + numFreeBlocks = 0; + freeBlockMemory = 0; + numAllocs = 0; + numResizes = 0; + numFrees = 0; + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + blockId[0] = 0x11111111; + blockId[1] = 0x22222222; + blockId[2] = 0x33333333; +#endif +} + +template +idDynamicBlock *idDynamicBlockAlloc::AllocInternal( const int num ) { + idDynamicBlock *block; + int alignedBytes = ( num * sizeof( type ) + 15 ) & ~15; + + block = freeTree.FindSmallestLargerEqual( alignedBytes ); + if ( block != NULL ) { + UnlinkFreeInternal( block ); + } else if ( allowAllocs ) { + int allocSize = Max( baseBlockSize, alignedBytes + (int)sizeof( idDynamicBlock ) ); + block = ( idDynamicBlock * ) Mem_Alloc16( allocSize ); + if ( lockMemory ) { + idLib::sys->LockMemory( block, baseBlockSize ); + } +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + memcpy( block->id, blockId, sizeof( block->id ) ); + block->allocator = (void*)this; +#endif + block->SetSize( allocSize - (int)sizeof( idDynamicBlock ), true ); + block->next = NULL; + block->prev = lastBlock; + if ( lastBlock ) { + lastBlock->next = block; + } else { + firstBlock = block; + } + lastBlock = block; + block->node = NULL; + + numBaseBlocks++; + baseBlockMemory += allocSize; + } + + return block; +} + +template +idDynamicBlock *idDynamicBlockAlloc::ResizeInternal( idDynamicBlock *block, const int num ) { + int alignedBytes = ( num * sizeof( type ) + 15 ) & ~15; + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + assert( block->id[0] == 0x11111111 && block->id[1] == 0x22222222 && block->id[2] == 0x33333333 && block->allocator == (void*)this ); +#endif + + // if the new size is larger + if ( alignedBytes > block->GetSize() ) { + + idDynamicBlock *nextBlock = block->next; + + // try to annexate the next block if it's free + if ( nextBlock && !nextBlock->IsBaseBlock() && nextBlock->node != NULL && + block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize() >= alignedBytes ) { + + UnlinkFreeInternal( nextBlock ); + block->SetSize( block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize(), block->IsBaseBlock() ); + block->next = nextBlock->next; + if ( nextBlock->next ) { + nextBlock->next->prev = block; + } else { + lastBlock = block; + } + } else { + // allocate a new block and copy + idDynamicBlock *oldBlock = block; + block = AllocInternal( num ); + if ( block == NULL ) { + return NULL; + } + memcpy( block->GetMemory(), oldBlock->GetMemory(), oldBlock->GetSize() ); + FreeInternal( oldBlock ); + } + } + + // if the unused space at the end of this block is large enough to hold a block with at least one element + if ( block->GetSize() - alignedBytes - (int)sizeof( idDynamicBlock ) < Max( minBlockSize, (int)sizeof( type ) ) ) { + return block; + } + + idDynamicBlock *newBlock; + + newBlock = ( idDynamicBlock * ) ( ( (byte *) block ) + (int)sizeof( idDynamicBlock ) + alignedBytes ); +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + memcpy( newBlock->id, blockId, sizeof( newBlock->id ) ); + newBlock->allocator = (void*)this; +#endif + newBlock->SetSize( block->GetSize() - alignedBytes - (int)sizeof( idDynamicBlock ), false ); + newBlock->next = block->next; + newBlock->prev = block; + if ( newBlock->next ) { + newBlock->next->prev = newBlock; + } else { + lastBlock = newBlock; + } + newBlock->node = NULL; + block->next = newBlock; + block->SetSize( alignedBytes, block->IsBaseBlock() ); + + FreeInternal( newBlock ); + + return block; +} + +template +void idDynamicBlockAlloc::FreeInternal( idDynamicBlock *block ) { + + assert( block->node == NULL ); + +#ifdef DYNAMIC_BLOCK_ALLOC_CHECK + assert( block->id[0] == 0x11111111 && block->id[1] == 0x22222222 && block->id[2] == 0x33333333 && block->allocator == (void*)this ); +#endif + + // try to merge with a next free block + idDynamicBlock *nextBlock = block->next; + if ( nextBlock && !nextBlock->IsBaseBlock() && nextBlock->node != NULL ) { + UnlinkFreeInternal( nextBlock ); + block->SetSize( block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize(), block->IsBaseBlock() ); + block->next = nextBlock->next; + if ( nextBlock->next ) { + nextBlock->next->prev = block; + } else { + lastBlock = block; + } + } + + // try to merge with a previous free block + idDynamicBlock *prevBlock = block->prev; + if ( prevBlock && !block->IsBaseBlock() && prevBlock->node != NULL ) { + UnlinkFreeInternal( prevBlock ); + prevBlock->SetSize( prevBlock->GetSize() + (int)sizeof( idDynamicBlock ) + block->GetSize(), prevBlock->IsBaseBlock() ); + prevBlock->next = block->next; + if ( block->next ) { + block->next->prev = prevBlock; + } else { + lastBlock = prevBlock; + } + LinkFreeInternal( prevBlock ); + } else { + LinkFreeInternal( block ); + } +} + +template +ID_INLINE void idDynamicBlockAlloc::LinkFreeInternal( idDynamicBlock *block ) { + block->node = freeTree.Add( block, block->GetSize() ); + numFreeBlocks++; + freeBlockMemory += block->GetSize(); +} + +template +ID_INLINE void idDynamicBlockAlloc::UnlinkFreeInternal( idDynamicBlock *block ) { + freeTree.Remove( block->node ); + block->node = NULL; + numFreeBlocks--; + freeBlockMemory -= block->GetSize(); +} + +template +void idDynamicBlockAlloc::CheckMemory( void ) const { + idDynamicBlock *block; + + for ( block = firstBlock; block != NULL; block = block->next ) { + // make sure the block is properly linked + if ( block->prev == NULL ) { + assert( firstBlock == block ); + } else { + assert( block->prev->next == block ); + } + if ( block->next == NULL ) { + assert( lastBlock == block ); + } else { + assert( block->next->prev == block ); + } + } +} + +#endif /* !__HEAP_H__ */ diff --git a/idlib/LangDict.cpp b/idlib/LangDict.cpp new file mode 100644 index 000000000..13f2a3b17 --- /dev/null +++ b/idlib/LangDict.cpp @@ -0,0 +1,326 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + + +/* +============ +idLangDict::idLangDict +============ +*/ +idLangDict::idLangDict( void ) { + args.SetGranularity( 256 ); + hash.SetGranularity( 256 ); + hash.Clear( 4096, 8192 ); + baseID = 0; +} + +/* +============ +idLangDict::~idLangDict +============ +*/ +idLangDict::~idLangDict( void ) { + Clear(); +} + +/* +============ +idLangDict::Clear +============ +*/ +void idLangDict::Clear( void ) { + args.Clear(); + hash.Clear(); +} + +/* +============ +idLangDict::Load +============ +*/ +bool idLangDict::Load( const char *fileName, const bool clear /* _D3XP */, const unsigned int remapcount, const char *remap ) { + + if ( clear ) { + Clear(); + } + + const char *buffer = NULL; + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + int len = idLib::fileSystem->ReadFile( fileName, (void**)&buffer ); + if ( len <= 0 ) { + // let whoever called us deal with the failure (so sys_lang can be reset) + return false; + } + src.LoadMemory( buffer, strlen( buffer ), fileName ); + if ( !src.IsLoaded() ) { + return false; + } + + idToken tok, tok2; + src.ExpectTokenString( "{" ); + while ( src.ReadToken( &tok ) ) { + if ( tok == "}" ) { + break; + } + if ( src.ReadToken( &tok2 ) ) { + if ( tok2 == "}" ) { + break; + } + idLangKeyValue kv; + kv.key = tok; + kv.value = tok2; + if (NULL != remap && remapcount > 0) + { + // Tels: fix #2812, some characters like 0xFF ("Ñ" in russian) are not rendered + // in the GUI, so replace them (as the font contains the characters elsewhere). + // If we were given a replacement table, use it to exchange the characters: + for (unsigned int i = 0; i < remapcount; i ++) + { + kv.value.Replace( remap[i*2], remap[i*2+1] ); + } + } + assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); + hash.Add( GetHashKey( kv.key ), args.Append( kv ) ); + } + } + idLib::common->Printf( "%i strings read from %s\n", args.Num(), fileName ); + idLib::fileSystem->FreeFile( (void*)buffer ); + + return true; +} + +/* +============ +idLangDict::Save +============ +*/ +void idLangDict::Save( const char *fileName ) { + idFile *outFile = idLib::fileSystem->OpenFileWrite( fileName ); + outFile->WriteFloatString( "// string table\n// english\n//\n\n{\n" ); + for ( int j = 0; j < args.Num(); j++ ) { + outFile->WriteFloatString( "\t\"%s\"\t\"", args[j].key.c_str() ); + int l = args[j].value.Length(); + char slash = '\\'; + char tab = 't'; + char nl = 'n'; + for ( int k = 0; k < l; k++ ) { + char ch = args[j].value[k]; + if ( ch == '\t' ) { + outFile->Write( &slash, 1 ); + outFile->Write( &tab, 1 ); + } else if ( ch == '\n' || ch == '\r' ) { + outFile->Write( &slash, 1 ); + outFile->Write( &nl, 1 ); + } else { + outFile->Write( &ch, 1 ); + } + } + outFile->WriteFloatString( "\"\n" ); + } + outFile->WriteFloatString( "\n}\n" ); + idLib::fileSystem->CloseFile( outFile ); +} + +/* +============ +idLangDict::GetString +============ +*/ +const char *idLangDict::GetString( const char *str, const bool dowarn ) const { + + if ( str == NULL || str[0] == '\0' ) { + return ""; + } + + if ( idStr::Cmpn( str, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) { + return str; + } + + int hashKey = GetHashKey( str ); + for ( int i = hash.First( hashKey ); i != -1; i = hash.Next( i ) ) { + if ( args[i].key.Cmp( str ) == 0 ) { + return args[i].value; + } + } + + if (dowarn) + { + idLib::common->Warning( "Unknown string id %s", str ); + } + return str; +} + +/* +============ +idLangDict::AddString +============ +*/ +const char *idLangDict::AddString( const char *str ) { + + if ( ExcludeString( str ) ) { + return str; + } + + int c = args.Num(); + for ( int j = 0; j < c; j++ ) { + if ( idStr::Cmp( args[j].value, str ) == 0 ){ + return args[j].key; + } + } + + int id = GetNextId(); + idLangKeyValue kv; + // _D3XP + kv.key = va( "#str_%08i", id ); + // kv.key = va( "#str_%05i", id ); + kv.value = str; + c = args.Append( kv ); + assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); + hash.Add( GetHashKey( kv.key ), c ); + return args[c].key; +} + +/* +============ +idLangDict::GetNumKeyVals +============ +*/ +int idLangDict::GetNumKeyVals( void ) const { + return args.Num(); +} + +/* +============ +idLangDict::GetKeyVal +============ +*/ +const idLangKeyValue * idLangDict::GetKeyVal( const int i ) const { + return &args[i]; +} + +/* +============ +idLangDict::AddKeyVal +============ +*/ +void idLangDict::AddKeyVal( const char *key, const char *val ) { + idLangKeyValue kv; + kv.key = key; + kv.value = val; + assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); + hash.Add( GetHashKey( kv.key ), args.Append( kv ) ); +} + +/* +============ +idLangDict::ExcludeString +============ +*/ +bool idLangDict::ExcludeString( const char *str ) const { + if ( str == NULL ) { + return true; + } + + int c = strlen( str ); + if ( c <= 1 ) { + return true; + } + + if ( idStr::Cmpn( str, STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ) { + return true; + } + + if ( idStr::Icmpn( str, "gui::", strlen( "gui::" ) ) == 0 ) { + return true; + } + + if ( str[0] == '$' ) { + return true; + } + + int i; + for ( i = 0; i < c; i++ ) { + if ( isalpha( str[i] ) ) { + break; + } + } + if ( i == c ) { + return true; + } + + return false; +} + +/* +============ +idLangDict::GetNextId +============ +*/ +int idLangDict::GetNextId( void ) const { + int c = args.Num(); + + // Let an external user supply the base id for this dictionary + int id = baseID; + + if ( c == 0 ) { + return id; + } + + idStr work; + for ( int j = 0; j < c; j++ ) { + work = args[j].key; + work.StripLeading( STRTABLE_ID ); + int test = atoi( work ); + if ( test > id ) { + id = test; + } + } + return id + 1; +} + +/* +============ +idLangDict::GetHashKey +============ +*/ +int idLangDict::GetHashKey( const char *str ) const { + int hashKey = 0; + for ( str += STRTABLE_ID_LENGTH; str[0] != '\0'; str++ ) { + assert( str[0] >= '0' && str[0] <= '9' ); + hashKey = hashKey * 10 + str[0] - '0'; + } + return hashKey; +} + +/* +============ +idLangDict::Print +============ +*/ +void idLangDict::Print( void ) const { + int c = args.Num(); + idLib::common->Printf("idLangDict: %li KB in %i entries.\n", static_cast(args.Size() + hash.Size()) >> 10l, c); + //hash.Print(); +} diff --git a/idlib/LangDict.h b/idlib/LangDict.h new file mode 100644 index 000000000..34baa8c0a --- /dev/null +++ b/idlib/LangDict.h @@ -0,0 +1,75 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LANGDICT_H__ +#define __LANGDICT_H__ + +/* +=============================================================================== + + Simple dictionary specifically for the localized string tables. + +=============================================================================== +*/ + +class idLangKeyValue { +public: + idStr key; + idStr value; +}; + +class idLangDict { +public: + idLangDict( void ); + ~idLangDict( void ); + + void Clear( void ); + // Tels: #2812: if remapcount and remap are given, use these to replace characters (remap containts two entries for + // each "remapcount", the first is the one to replace, the second the replacement. + bool Load( const char *fileName, const bool clear = true, const unsigned int remapcount = 0, const char *remap = NULL ); + void Save( const char *fileName ); + + const char * AddString( const char *str ); + const char * GetString( const char *str, const bool dowarn = true ) const; + + /** + * Tels: Print some statistics about memory usage. + */ + void Print( void ) const; + // adds the value and key as passed (doesn't generate a "#str_xxxxx" key or ensure the key/value pair is unique) + void AddKeyVal( const char *key, const char *val ); + + int GetNumKeyVals( void ) const; + const idLangKeyValue * GetKeyVal(const int i) const; + + void SetBaseID(const int id) { baseID = id; }; + +private: + idList args; + idHashIndex hash; + + bool ExcludeString( const char *str ) const; + int GetNextId( void ) const; + int GetHashKey( const char *str ) const; + + int baseID; +}; + +#endif /* !__LANGDICT_H__ */ diff --git a/idlib/Lexer.cpp b/idlib/Lexer.cpp new file mode 100644 index 000000000..eafce72b9 --- /dev/null +++ b/idlib/Lexer.cpp @@ -0,0 +1,1834 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + + +#pragma warning( push ) +#pragma warning( disable : 4127 ) +#define PUNCTABLE + +//longer punctuations first +punctuation_t default_punctuations[] = { + //binary operators + {">>=",P_RSHIFT_ASSIGN}, + {"<<=",P_LSHIFT_ASSIGN}, + // + {"...",P_PARMS}, + //define merge operator + {"##",P_PRECOMPMERGE}, // pre-compiler + //logic operators + {"&&",P_LOGIC_AND}, // pre-compiler + {"||",P_LOGIC_OR}, // pre-compiler + {">=",P_LOGIC_GEQ}, // pre-compiler + {"<=",P_LOGIC_LEQ}, // pre-compiler + {"==",P_LOGIC_EQ}, // pre-compiler + {"!=",P_LOGIC_UNEQ}, // pre-compiler + //arithmatic operators + {"*=",P_MUL_ASSIGN}, + {"/=",P_DIV_ASSIGN}, + {"%=",P_MOD_ASSIGN}, + {"+=",P_ADD_ASSIGN}, + {"-=",P_SUB_ASSIGN}, + {"++",P_INC}, + {"--",P_DEC}, + //binary operators + {"&=",P_BIN_AND_ASSIGN}, + {"|=",P_BIN_OR_ASSIGN}, + {"^=",P_BIN_XOR_ASSIGN}, + {">>",P_RSHIFT}, // pre-compiler + {"<<",P_LSHIFT}, // pre-compiler + //reference operators + {"->",P_POINTERREF}, + //C++ + {"::",P_CPP1}, + {".*",P_CPP2}, + //arithmatic operators + {"*",P_MUL}, // pre-compiler + {"/",P_DIV}, // pre-compiler + {"%",P_MOD}, // pre-compiler + {"+",P_ADD}, // pre-compiler + {"-",P_SUB}, // pre-compiler + {"=",P_ASSIGN}, + //binary operators + {"&",P_BIN_AND}, // pre-compiler + {"|",P_BIN_OR}, // pre-compiler + {"^",P_BIN_XOR}, // pre-compiler + {"~",P_BIN_NOT}, // pre-compiler + //logic operators + {"!",P_LOGIC_NOT}, // pre-compiler + {">",P_LOGIC_GREATER}, // pre-compiler + {"<",P_LOGIC_LESS}, // pre-compiler + //reference operator + {".",P_REF}, + //seperators + {",",P_COMMA}, // pre-compiler + {";",P_SEMICOLON}, + //label indication + {":",P_COLON}, // pre-compiler + //if statement + {"?",P_QUESTIONMARK}, // pre-compiler + //embracements + {"(",P_PARENTHESESOPEN}, // pre-compiler + {")",P_PARENTHESESCLOSE}, // pre-compiler + {"{",P_BRACEOPEN}, // pre-compiler + {"}",P_BRACECLOSE}, // pre-compiler + {"[",P_SQBRACKETOPEN}, + {"]",P_SQBRACKETCLOSE}, + // + {"\\",P_BACKSLASH}, + //precompiler operator + {"#",P_PRECOMP}, // pre-compiler + {"$",P_DOLLAR}, + {NULL, 0} +}; + +int default_punctuationtable[256]; +int default_nextpunctuation[sizeof(default_punctuations) / sizeof(punctuation_t)]; +int default_setup; + +char idLexer::baseFolder[ 256 ]; + +/* +================ +idLexer::CreatePunctuationTable +================ +*/ +void idLexer::CreatePunctuationTable( const punctuation_t *punctuations ) { + int i, n, lastp; + const punctuation_t *p, *newp; + + //get memory for the table + if ( punctuations == default_punctuations ) { + idLexer::punctuationtable = default_punctuationtable; + idLexer::nextpunctuation = default_nextpunctuation; + if ( default_setup ) { + return; + } + default_setup = true; + i = sizeof(default_punctuations) / sizeof(punctuation_t); + } + else { + if ( !idLexer::punctuationtable || idLexer::punctuationtable == default_punctuationtable ) { + idLexer::punctuationtable = (int *) Mem_Alloc(256 * sizeof(int)); + } + if ( idLexer::nextpunctuation && idLexer::nextpunctuation != default_nextpunctuation ) { + Mem_Free( idLexer::nextpunctuation ); + } + for (i = 0; punctuations[i].p; i++) { + } + idLexer::nextpunctuation = (int *) Mem_Alloc(i * sizeof(int)); + } + memset(idLexer::punctuationtable, 0xFF, 256 * sizeof(int)); + memset(idLexer::nextpunctuation, 0xFF, i * sizeof(int)); + //add the punctuations in the list to the punctuation table + for (i = 0; punctuations[i].p; i++) { + newp = &punctuations[i]; + lastp = -1; + //sort the punctuations in this table entry on length (longer punctuations first) + for (n = idLexer::punctuationtable[(unsigned int) newp->p[0]]; n >= 0; n = idLexer::nextpunctuation[n] ) { + p = &punctuations[n]; + if (strlen(p->p) < strlen(newp->p)) { + idLexer::nextpunctuation[i] = n; + if (lastp >= 0) { + idLexer::nextpunctuation[lastp] = i; + } + else { + idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; + } + break; + } + lastp = n; + } + if (n < 0) { + idLexer::nextpunctuation[i] = -1; + if (lastp >= 0) { + idLexer::nextpunctuation[lastp] = i; + } + else { + idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; + } + } + } +} + +/* +================ +idLexer::GetPunctuationFromId +================ +*/ +const char *idLexer::GetPunctuationFromId( int id ) { + int i; + + for (i = 0; idLexer::punctuations[i].p; i++) { + if ( idLexer::punctuations[i].n == id ) { + return idLexer::punctuations[i].p; + } + } + return "unkown punctuation"; +} + +/* +================ +idLexer::GetPunctuationId +================ +*/ +int idLexer::GetPunctuationId( const char *p ) { + int i; + + for (i = 0; idLexer::punctuations[i].p; i++) { + if ( !strcmp(idLexer::punctuations[i].p, p) ) { + return idLexer::punctuations[i].n; + } + } + return 0; +} + +/* +================ +idLexer::Error +================ +*/ +void idLexer::Error( const char *str, ... ) { + char text[MAX_STRING_CHARS]; + va_list ap; + + hadError = true; + + if ( idLexer::flags & LEXFL_NOERRORS ) { + return; + } + + va_start(ap, str); + vsprintf(text, str, ap); + va_end(ap); + + if ( idLexer::flags & LEXFL_NOFATALERRORS ) { + idLib::common->Warning( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); + } else { + idLib::common->Error( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); + } +} + +/* +================ +idLexer::Warning +================ +*/ +void idLexer::Warning( const char *str, ... ) { + char text[MAX_STRING_CHARS]; + va_list ap; + + if ( idLexer::flags & LEXFL_NOWARNINGS ) { + return; + } + + va_start( ap, str ); + vsprintf( text, str, ap ); + va_end( ap ); + idLib::common->Warning( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); +} + +/* +================ +idLexer::SetPunctuations +================ +*/ +void idLexer::SetPunctuations( const punctuation_t *p ) { +#ifdef PUNCTABLE + if (p) { + idLexer::CreatePunctuationTable( p ); + } + else { + idLexer::CreatePunctuationTable( default_punctuations ); + } +#endif //PUNCTABLE + if (p) { + idLexer::punctuations = p; + } + else { + idLexer::punctuations = default_punctuations; + } +} + +/* +================ +idLexer::ReadWhiteSpace + +Reads spaces, tabs, C-like comments etc. +When a newline character is found the scripts line counter is increased. +================ +*/ +int idLexer::ReadWhiteSpace( void ) { + while(1) { + // skip white space + while(*idLexer::script_p <= ' ') { + if (!*idLexer::script_p) { + return 0; + } + if (*idLexer::script_p == '\n') { + idLexer::line++; + } + idLexer::script_p++; + } + // skip comments + if (*idLexer::script_p == '/') { + // comments // + if (*(idLexer::script_p+1) == '/') { + idLexer::script_p++; + do { + idLexer::script_p++; + if ( !*idLexer::script_p ) { + return 0; + } + } + while( *idLexer::script_p != '\n' ); + idLexer::line++; + idLexer::script_p++; + if ( !*idLexer::script_p ) { + return 0; + } + continue; + } + // comments /* */ + else if (*(idLexer::script_p+1) == '*') { + idLexer::script_p++; + while( 1 ) { + idLexer::script_p++; + if ( !*idLexer::script_p ) { + return 0; + } + if ( *idLexer::script_p == '\n' ) { + idLexer::line++; + } + else if ( *idLexer::script_p == '/' ) { + if ( *(idLexer::script_p-1) == '*' ) { + break; + } + if ( *(idLexer::script_p+1) == '*' ) { + idLexer::Warning( "nested comment" ); + } + } + } + idLexer::script_p++; + if ( !*idLexer::script_p ) { + return 0; + } + continue; + } + } + break; + } + return 1; +} + +/* +================ +idLexer::ReadEscapeCharacter +================ +*/ +int idLexer::ReadEscapeCharacter( char *ch ) { + int c, val, i; + + // step over the leading '\\' + idLexer::script_p++; + // determine the escape character + switch(*idLexer::script_p) { + case '\\': c = '\\'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'a': c = '\a'; break; + case '\'': c = '\''; break; + case '\"': c = '\"'; break; + case '\?': c = '\?'; break; + case 'x': + { + idLexer::script_p++; + for (i = 0, val = 0; ; i++, idLexer::script_p++) { + c = *idLexer::script_p; + if (c >= '0' && c <= '9') + c = c - '0'; + else if (c >= 'A' && c <= 'Z') + c = c - 'A' + 10; + else if (c >= 'a' && c <= 'z') + c = c - 'a' + 10; + else + break; + val = (val << 4) + c; + } + idLexer::script_p--; + if (val > 0xFF) { + idLexer::Warning( "too large value in escape character" ); + val = 0xFF; + } + c = val; + break; + } + default: //NOTE: decimal ASCII code, NOT octal + { + if (*idLexer::script_p < '0' || *idLexer::script_p > '9') { + idLexer::Error("unknown escape char"); + } + for (i = 0, val = 0; ; i++, idLexer::script_p++) { + c = *idLexer::script_p; + if (c >= '0' && c <= '9') + c = c - '0'; + else + break; + val = val * 10 + c; + } + idLexer::script_p--; + if (val > 0xFF) { + idLexer::Warning( "too large value in escape character" ); + val = 0xFF; + } + c = val; + break; + } + } + // step over the escape character or the last digit of the number + idLexer::script_p++; + // store the escape character + *ch = c; + // succesfully read escape character + return 1; +} + +/* +================ +idLexer::ReadString + +Escape characters are interpretted. +Reads two strings with only a white space between them as one string. +================ +*/ +int idLexer::ReadString( idToken *token, int quote ) { + int tmpline; + const char *tmpscript_p; + char ch; + + if ( quote == '\"' ) { + token->type = TT_STRING; + } else { + token->type = TT_LITERAL; + } + + // leading quote + idLexer::script_p++; + + while(1) { + // if there is an escape character and escape characters are allowed + if (*idLexer::script_p == '\\' && !(idLexer::flags & LEXFL_NOSTRINGESCAPECHARS)) { + if ( !idLexer::ReadEscapeCharacter( &ch ) ) { + return 0; + } + token->AppendDirty( ch ); + } + // if a trailing quote + else if (*idLexer::script_p == quote) { + // step over the quote + idLexer::script_p++; + // if consecutive strings should not be concatenated + if ( (idLexer::flags & LEXFL_NOSTRINGCONCAT) && + (!(idLexer::flags & LEXFL_ALLOWBACKSLASHSTRINGCONCAT) || (quote != '\"')) ) { + break; + } + + tmpscript_p = idLexer::script_p; + tmpline = idLexer::line; + // read white space between possible two consecutive strings + if ( !idLexer::ReadWhiteSpace() ) { + idLexer::script_p = tmpscript_p; + idLexer::line = tmpline; + break; + } + + if ( idLexer::flags & LEXFL_NOSTRINGCONCAT ) { + if ( *idLexer::script_p != '\\' ) { + idLexer::script_p = tmpscript_p; + idLexer::line = tmpline; + break; + } + // step over the '\\' + idLexer::script_p++; + if ( !idLexer::ReadWhiteSpace() || ( *idLexer::script_p != quote ) ) { + idLexer::Error( "expecting string after '\' terminated line" ); + return 0; + } + } + + // if there's no leading qoute + if ( *idLexer::script_p != quote ) { + idLexer::script_p = tmpscript_p; + idLexer::line = tmpline; + break; + } + // step over the new leading quote + idLexer::script_p++; + } + else { + if (*idLexer::script_p == '\0') { + idLexer::Error( "missing trailing quote" ); + return 0; + } + if (*idLexer::script_p == '\n') { + idLexer::Error( "newline inside string" ); + return 0; + } + token->AppendDirty( *idLexer::script_p++ ); + } + } + token->data[token->len] = '\0'; + + if ( token->type == TT_LITERAL ) { + if ( !(idLexer::flags & LEXFL_ALLOWMULTICHARLITERALS) ) { + if ( token->Length() != 1 ) { + idLexer::Warning( "literal is not one character long" ); + } + } + token->subtype = (*token)[0]; + } + else { + // the sub type is the length of the string + token->subtype = token->Length(); + } + return 1; +} + +/* +================ +idLexer::ReadName +================ +*/ +int idLexer::ReadName( idToken *token ) { + char c; + + token->type = TT_NAME; + do { + token->AppendDirty( *idLexer::script_p++ ); + c = *idLexer::script_p; + } while ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '_' || + // if treating all tokens as strings, don't parse '-' as a seperate token + ((idLexer::flags & LEXFL_ONLYSTRINGS) && (c == '-')) || + // if special path name characters are allowed + ((idLexer::flags & LEXFL_ALLOWPATHNAMES) && (c == '/' || c == '\\' || c == ':' || c == '.')) ); + token->data[token->len] = '\0'; + //the sub type is the length of the name + token->subtype = token->Length(); + return 1; +} + +/* +================ +idLexer::CheckString +================ +*/ +ID_INLINE int idLexer::CheckString( const char *str ) const { + int i; + + for ( i = 0; str[i]; i++ ) { + if ( idLexer::script_p[i] != str[i] ) { + return false; + } + } + return true; +} + +/* +================ +idLexer::ReadNumber +================ +*/ +int idLexer::ReadNumber( idToken *token ) { + int i; + int dot; + char c, c2; + + token->type = TT_NUMBER; + token->subtype = 0; + token->intvalue = 0; + token->floatvalue = 0; + + c = *idLexer::script_p; + c2 = *(idLexer::script_p + 1); + + if ( c == '0' && c2 != '.' ) { + // check for a hexadecimal number + if ( c2 == 'x' || c2 == 'X' ) { + token->AppendDirty( *idLexer::script_p++ ); + token->AppendDirty( *idLexer::script_p++ ); + c = *idLexer::script_p; + while((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + token->subtype = TT_HEX | TT_INTEGER; + } + // check for a binary number + else if ( c2 == 'b' || c2 == 'B' ) { + token->AppendDirty( *idLexer::script_p++ ); + token->AppendDirty( *idLexer::script_p++ ); + c = *idLexer::script_p; + while( c == '0' || c == '1' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + token->subtype = TT_BINARY | TT_INTEGER; + } + // its an octal number + else { + token->AppendDirty( *idLexer::script_p++ ); + c = *idLexer::script_p; + while( c >= '0' && c <= '7' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + token->subtype = TT_OCTAL | TT_INTEGER; + } + } + else { + // decimal integer or floating point number or ip address + dot = 0; + while( 1 ) { + if ( c >= '0' && c <= '9' ) { + } + else if ( c == '.' ) { + dot++; + } + else { + break; + } + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + if( c == 'e' && dot == 0) { + + //We have scientific notation without a decimal point + + dot++; + + } + + // if a floating point number + if ( dot == 1 ) { + token->subtype = TT_DECIMAL | TT_FLOAT; + // check for floating point exponent + if ( c == 'e' ) { + //Append the e so that GetFloatValue code works + + token->AppendDirty( c ); + + c = *(++idLexer::script_p); + if ( c == '-' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + else if ( c == '+' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + while( c >= '0' && c <= '9' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + } + // check for floating point exception infinite 1.#INF or indefinite 1.#IND or NaN + else if ( c == '#' ) { + c2 = 4; + if ( CheckString( "INF" ) ) { + token->subtype |= TT_INFINITE; + } + else if ( CheckString( "IND" ) ) { + token->subtype |= TT_INDEFINITE; + } + else if ( CheckString( "NAN" ) ) { + token->subtype |= TT_NAN; + } + else if ( CheckString( "QNAN" ) ) { + token->subtype |= TT_NAN; + c2++; + } + else if ( CheckString( "SNAN" ) ) { + token->subtype |= TT_NAN; + c2++; + } + for ( i = 0; i < c2; i++ ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + while( c >= '0' && c <= '9' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + if ( !(idLexer::flags & LEXFL_ALLOWFLOATEXCEPTIONS) ) { + token->AppendDirty( 0 ); // zero terminate for c_str + idLexer::Error( "parsed %s", token->c_str() ); + } + } + } + else if ( dot > 1 ) { + if ( !( idLexer::flags & LEXFL_ALLOWIPADDRESSES ) ) { + idLexer::Error( "more than one dot in number" ); + return 0; + } + if ( dot != 3 ) { + idLexer::Error( "ip address should have three dots" ); + return 0; + } + token->subtype = TT_IPADDRESS; + } + else { + token->subtype = TT_DECIMAL | TT_INTEGER; + } + } + + if ( token->subtype & TT_FLOAT ) { + if ( c > ' ' ) { + // single-precision: float + if ( c == 'f' || c == 'F' ) { + token->subtype |= TT_SINGLE_PRECISION; + idLexer::script_p++; + } + // extended-precision: long double + else if ( c == 'l' || c == 'L' ) { + token->subtype |= TT_EXTENDED_PRECISION; + idLexer::script_p++; + } + // default is double-precision: double + else { + token->subtype |= TT_DOUBLE_PRECISION; + } + } + else { + token->subtype |= TT_DOUBLE_PRECISION; + } + } + else if ( token->subtype & TT_INTEGER ) { + if ( c > ' ' ) { + // default: signed long + for ( i = 0; i < 2; i++ ) { + // long integer + if ( c == 'l' || c == 'L' ) { + token->subtype |= TT_LONG; + } + // unsigned integer + else if ( c == 'u' || c == 'U' ) { + token->subtype |= TT_UNSIGNED; + } + else { + break; + } + c = *(++idLexer::script_p); + } + } + } + else if ( token->subtype & TT_IPADDRESS ) { + if ( c == ':' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + while( c >= '0' && c <= '9' ) { + token->AppendDirty( c ); + c = *(++idLexer::script_p); + } + token->subtype |= TT_IPPORT; + } + } + token->data[token->len] = '\0'; + return 1; +} + +/* +================ +idLexer::ReadPunctuation +================ +*/ +int idLexer::ReadPunctuation( idToken *token ) { + int l, n, i; + const char *p; + const punctuation_t *punc; + +#ifdef PUNCTABLE + for (n = idLexer::punctuationtable[(unsigned int)*(idLexer::script_p)]; n >= 0; n = idLexer::nextpunctuation[n]) + { + punc = &(idLexer::punctuations[n]); +#else + int i; + + for (i = 0; idLexer::punctuations[i].p; i++) { + punc = &idLexer::punctuations[i]; +#endif + p = punc->p; + // check for this punctuation in the script + for ( l = 0; p[l] && idLexer::script_p[l]; l++ ) { + if ( idLexer::script_p[l] != p[l] ) { + break; + } + } + if ( !p[l] ) { + // + token->EnsureAlloced( l+1, false ); + for ( i = 0; i <= l; i++ ) { + token->data[i] = p[i]; + } + token->len = l; + // + idLexer::script_p += l; + token->type = TT_PUNCTUATION; + // sub type is the punctuation id + token->subtype = punc->n; + return 1; + } + } + return 0; +} + +/* +================ +idLexer::ReadToken +================ +*/ +int idLexer::ReadToken( idToken *token ) { + int c; + + if ( !loaded ) { + idLib::common->Error( "idLexer::ReadToken: no file loaded" ); + return 0; + } + + // if there is a token available (from unreadToken) + if ( tokenavailable ) { + tokenavailable = 0; + *token = idLexer::token; + return 1; + } + // save script pointer + lastScript_p = script_p; + // save line counter + lastline = line; + // clear the token stuff + token->data[0] = '\0'; + token->len = 0; + // start of the white space + whiteSpaceStart_p = script_p; + token->whiteSpaceStart_p = script_p; + // read white space before token + if ( !ReadWhiteSpace() ) { + return 0; + } + // end of the white space + idLexer::whiteSpaceEnd_p = script_p; + token->whiteSpaceEnd_p = script_p; + // line the token is on + token->line = line; + // number of lines crossed before token + token->linesCrossed = line - lastline; + // clear token flags + token->flags = 0; + + c = *idLexer::script_p; + + // if we're keeping everything as whitespace deliminated strings + if ( idLexer::flags & LEXFL_ONLYSTRINGS ) { + // if there is a leading quote + if ( c == '\"' || c == '\'' ) { + if (!idLexer::ReadString( token, c )) { + return 0; + } + } else if ( !idLexer::ReadName( token ) ) { + return 0; + } + } + // if there is a number + else if ( (c >= '0' && c <= '9') || + (c == '.' && (*(idLexer::script_p + 1) >= '0' && *(idLexer::script_p + 1) <= '9')) ) { + if ( !idLexer::ReadNumber( token ) ) { + return 0; + } + // if names are allowed to start with a number + if ( idLexer::flags & LEXFL_ALLOWNUMBERNAMES ) { + c = *idLexer::script_p; + if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ) { + if ( !idLexer::ReadName( token ) ) { + return 0; + } + } + } + } + // if there is a leading quote + else if ( c == '\"' || c == '\'' ) { + if (!idLexer::ReadString( token, c )) { + return 0; + } + } + // if there is a name + else if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ) { + if ( !idLexer::ReadName( token ) ) { + return 0; + } + } + // names may also start with a slash when pathnames are allowed + else if ( ( idLexer::flags & LEXFL_ALLOWPATHNAMES ) && ( (c == '/' || c == '\\') || c == '.' ) ) { + if ( !idLexer::ReadName( token ) ) { + return 0; + } + } + // check for punctuations + else if ( !idLexer::ReadPunctuation( token ) ) { + idLexer::Error( "unknown punctuation %c", c ); + return 0; + } + // succesfully read a token + return 1; +} + +/* +================ +idLexer::ExpectTokenString +================ +*/ +int idLexer::ExpectTokenString( const char *string ) { + idToken token; + + if (!idLexer::ReadToken( &token )) { + idLexer::Error( "couldn't find expected '%s'", string ); + return 0; + } + if ( token != string ) { + idLexer::Error( "expected '%s' but found '%s'", string, token.c_str() ); + return 0; + } + return 1; +} + +/* +================ +idLexer::ExpectTokenType +================ +*/ +int idLexer::ExpectTokenType( int type, int subtype, idToken *token ) { + idStr str; + + if ( !idLexer::ReadToken( token ) ) { + idLexer::Error( "couldn't read expected token" ); + return 0; + } + + if ( token->type != type ) { + switch( type ) { + case TT_STRING: str = "string"; break; + case TT_LITERAL: str = "literal"; break; + case TT_NUMBER: str = "number"; break; + case TT_NAME: str = "name"; break; + case TT_PUNCTUATION: str = "punctuation"; break; + default: str = "unknown type"; break; + } + idLexer::Error( "expected a %s but found '%s'", str.c_str(), token->c_str() ); + return 0; + } + if ( token->type == TT_NUMBER ) { + if ( (token->subtype & subtype) != subtype ) { + str.Clear(); + if ( subtype & TT_DECIMAL ) str = "decimal "; + if ( subtype & TT_HEX ) str = "hex "; + if ( subtype & TT_OCTAL ) str = "octal "; + if ( subtype & TT_BINARY ) str = "binary "; + if ( subtype & TT_UNSIGNED ) str += "unsigned "; + if ( subtype & TT_LONG ) str += "long "; + if ( subtype & TT_FLOAT ) str += "float "; + if ( subtype & TT_INTEGER ) str += "integer "; + str.StripTrailing( ' ' ); + idLexer::Error( "expected %s but found '%s'", str.c_str(), token->c_str() ); + return 0; + } + } + else if ( token->type == TT_PUNCTUATION ) { + if ( subtype < 0 ) { + idLexer::Error( "BUG: wrong punctuation subtype" ); + return 0; + } + if ( token->subtype != subtype ) { + idLexer::Error( "expected '%s' but found '%s'", GetPunctuationFromId( subtype ), token->c_str() ); + return 0; + } + } + return 1; +} + +/* +================ +idLexer::ExpectAnyToken +================ +*/ +int idLexer::ExpectAnyToken( idToken *token ) { + if (!idLexer::ReadToken( token )) { + idLexer::Error( "couldn't read expected token" ); + return 0; + } + else { + return 1; + } +} + +/* +================ +idLexer::CheckTokenString +================ +*/ +int idLexer::CheckTokenString( const char *string ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return 0; + } + // if the given string is available + if ( tok == string ) { + return 1; + } + // unread token + script_p = lastScript_p; + line = lastline; + return 0; +} + +/* +================ +idLexer::CheckTokenType +================ +*/ +int idLexer::CheckTokenType( int type, int subtype, idToken *token ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return 0; + } + // if the type matches + if (tok.type == type && (tok.subtype & subtype) == subtype) { + *token = tok; + return 1; + } + // unread token + script_p = lastScript_p; + line = lastline; + return 0; +} + +/* +================ +idLexer::PeekTokenString +================ +*/ +int idLexer::PeekTokenString( const char *string ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return 0; + } + + // unread token + script_p = lastScript_p; + line = lastline; + + // if the given string is available + if ( tok == string ) { + return 1; + } + return 0; +} + +/* +================ +idLexer::PeekTokenType +================ +*/ +int idLexer::PeekTokenType( int type, int subtype, idToken *token ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return 0; + } + + // unread token + script_p = lastScript_p; + line = lastline; + + // if the type matches + if ( tok.type == type && ( tok.subtype & subtype ) == subtype ) { + *token = tok; + return 1; + } + return 0; +} + +/* +================ +idLexer::SkipUntilString +================ +*/ +int idLexer::SkipUntilString( const char *string ) { + idToken token; + + while(idLexer::ReadToken( &token )) { + if ( token == string ) { + return 1; + } + } + return 0; +} + +/* +================ +idLexer::SkipRestOfLine +================ +*/ +int idLexer::SkipRestOfLine( void ) { + idToken token; + + while(idLexer::ReadToken( &token )) { + if ( token.linesCrossed ) { + idLexer::script_p = lastScript_p; + idLexer::line = lastline; + return 1; + } + } + return 0; +} + +/* +================= +idLexer::SkipBracedSection + +Skips until a matching close brace is found. +Internal brace depths are properly skipped. +================= +*/ +int idLexer::SkipBracedSection( bool parseFirstBrace ) { + idToken token; + int depth; + + depth = parseFirstBrace ? 0 : 1; + do { + if ( !ReadToken( &token ) ) { + return false; + } + if ( token.type == TT_PUNCTUATION ) { + if ( token == "{" ) { + depth++; + } else if ( token == "}" ) { + depth--; + } + } + } while( depth ); + return true; +} + +/* +================ +idLexer::UnreadToken +================ +*/ +void idLexer::UnreadToken( const idToken *token ) { + if ( idLexer::tokenavailable ) { + idLib::common->FatalError( "idLexer::unreadToken, unread token twice\n" ); + } + idLexer::token = *token; + idLexer::tokenavailable = 1; +} + +/* +================ +idLexer::ReadTokenOnLine +================ +*/ +int idLexer::ReadTokenOnLine( idToken *token ) { + idToken tok; + + if (!idLexer::ReadToken( &tok )) { + idLexer::script_p = lastScript_p; + idLexer::line = lastline; + return false; + } + // if no lines were crossed before this token + if ( !tok.linesCrossed ) { + *token = tok; + return true; + } + // restore our position + idLexer::script_p = lastScript_p; + idLexer::line = lastline; + token->Clear(); + return false; +} + +/* +================ +idLexer::ReadRestOfLine +================ +*/ +const char* idLexer::ReadRestOfLine(idStr& out) { + while(1) { + + if(*idLexer::script_p == '\n') { + idLexer::line++; + break; + } + + if(!*idLexer::script_p) { + break; + } + + if(*idLexer::script_p <= ' ') { + out += " "; + } else { + out += *idLexer::script_p; + } + idLexer::script_p++; + } + out.Strip(' '); + return out.c_str(); +} + + +/* +================ +idLexer::ParseInt +================ +*/ +int idLexer::ParseInt( void ) { + idToken token; + + if ( !idLexer::ReadToken( &token ) ) { + idLexer::Error( "couldn't read expected integer" ); + return 0; + } + if ( token.type == TT_PUNCTUATION && token == "-" ) { + idLexer::ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); + return -((signed int) token.GetIntValue()); + } + else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { + idLexer::Error( "expected integer value, found '%s'", token.c_str() ); + } + return token.GetIntValue(); +} + +/* +================ +idLexer::ParseBool +================ +*/ +bool idLexer::ParseBool( void ) { + idToken token; + + if ( !idLexer::ExpectTokenType( TT_NUMBER, 0, &token ) ) { + idLexer::Error( "couldn't read expected boolean" ); + return false; + } + return ( token.GetIntValue() != 0 ); +} + +/* +================ +idLexer::ParseFloat +================ +*/ +float idLexer::ParseFloat( bool *errorFlag ) { + idToken token; + + if ( errorFlag ) { + *errorFlag = false; + } + + if ( !idLexer::ReadToken( &token ) ) { + if ( errorFlag ) { + idLexer::Warning( "couldn't read expected floating point number" ); + *errorFlag = true; + } else { + idLexer::Error( "couldn't read expected floating point number" ); + } + return 0; + } + if ( token.type == TT_PUNCTUATION && token == "-" ) { + idLexer::ExpectTokenType( TT_NUMBER, 0, &token ); + return -token.GetFloatValue(); + } + else if ( token.type != TT_NUMBER ) { + if ( errorFlag ) { + idLexer::Warning( "expected float value, found '%s'", token.c_str() ); + *errorFlag = true; + } else { + idLexer::Error( "expected float value, found '%s'", token.c_str() ); + } + } + return token.GetFloatValue(); +} + +/* +================ +idLexer::Parse1DMatrix +================ +*/ +int idLexer::Parse1DMatrix( int x, float *m, bool bIntsOnly ) { + int i; + + if ( !idLexer::ExpectTokenString( "(" ) ) { + return false; + } + for ( i = 0; i < x; i++ ) { + if(bIntsOnly) + { + m[i] = idLexer::ParseInt(); + continue; + } + m[i] = idLexer::ParseFloat(); + } + + if ( !idLexer::ExpectTokenString( ")" ) ) { + return false; + } + return true; +} + +/* +================ +idLexer::Parse1DMatrix + +Overloaded to write an integer matrix instead of float. + +Added by Ishtvan @ The Dark Mod +================ +*/ +int idLexer::Parse1DMatrix( int x, int *m ) +{ + bool returnval; + int i; + float *mTemp; + if ((mTemp = new float[x]) == NULL) + { + Error( "Out of memory allocating for float to int conversion" ); + returnval = false; + goto Quit; + } + if (!Parse1DMatrix( x, mTemp, true )) + { + returnval = false; + goto Quit; + } + for (i=0; i= 0; + + while( depth && *idLexer::script_p ) { + char c = *(idLexer::script_p++); + + switch ( c ) { + case '\t': + case ' ': { + if ( skipWhite ) { + continue; + } + break; + } + case '\n': { + if ( doTabs ) { + skipWhite = true; + out += c; + continue; + } + break; + } + case '{': { + depth++; + tabs++; + break; + } + case '}': { + depth--; + tabs--; + break; + } + } + + if ( skipWhite ) { + int i = tabs; + if ( c == '{' ) { + i--; + } + skipWhite = false; + for ( ; i > 0; i-- ) { + out += '\t'; + } + } + out += c; + } + return out.c_str(); +} + +/* +================= +idLexer::ParseBracedSection + +The next token should be an open brace. +Parses until a matching close brace is found. +Internal brace depths are properly skipped. +================= +*/ +const char *idLexer::ParseBracedSection( idStr &out ) { + idToken token; + int i, depth; + + out.Empty(); + if ( !idLexer::ExpectTokenString( "{" ) ) { + return out.c_str(); + } + out = "{"; + depth = 1; + do { + if ( !idLexer::ReadToken( &token ) ) { + Error( "missing closing brace" ); + return out.c_str(); + } + + // if the token is on a new line + for ( i = 0; i < token.linesCrossed; i++ ) { + out += "\r\n"; + } + + if ( token.type == TT_PUNCTUATION ) { + if ( token[0] == '{' ) { + depth++; + } + else if ( token[0] == '}' ) { + depth--; + } + } + + if ( token.type == TT_STRING ) { + out += "\"" + token + "\""; + } + else { + out += token; + } + out += " "; + } while( depth ); + + return out.c_str(); +} + +/* +================= +idLexer::ParseRestOfLine + + parse the rest of the line +================= +*/ +const char *idLexer::ParseRestOfLine( idStr &out ) { + idToken token; + + out.Empty(); + while(idLexer::ReadToken( &token )) { + if ( token.linesCrossed ) { + idLexer::script_p = lastScript_p; + idLexer::line = lastline; + break; + } + if ( out.Length() ) { + out += " "; + } + out += token; + } + return out.c_str(); +} + +/* +================ +idLexer::GetLastWhiteSpace +================ +*/ +int idLexer::GetLastWhiteSpace( idStr &whiteSpace ) const { + whiteSpace.Clear(); + for ( const char *p = whiteSpaceStart_p; p < whiteSpaceEnd_p; p++ ) { + whiteSpace.Append( *p ); + } + return whiteSpace.Length(); +} + +/* +================ +idLexer::GetLastWhiteSpaceStart +================ +*/ +int idLexer::GetLastWhiteSpaceStart( void ) const { + return whiteSpaceStart_p - buffer; +} + +/* +================ +idLexer::GetLastWhiteSpaceEnd +================ +*/ +int idLexer::GetLastWhiteSpaceEnd( void ) const { + return whiteSpaceEnd_p - buffer; +} + +/* +================ +idLexer::Reset +================ +*/ +void idLexer::Reset( void ) { + // pointer in script buffer + idLexer::script_p = idLexer::buffer; + // pointer in script buffer before reading token + idLexer::lastScript_p = idLexer::buffer; + // begin of white space + idLexer::whiteSpaceStart_p = NULL; + // end of white space + idLexer::whiteSpaceEnd_p = NULL; + // set if there's a token available in idLexer::token + idLexer::tokenavailable = 0; + + idLexer::line = 1; + idLexer::lastline = 1; + // clear the saved token + idLexer::token = ""; +} + +/* +================ +idLexer::EndOfFile +================ +*/ +int idLexer::EndOfFile( void ) { + return idLexer::script_p >= idLexer::end_p; +} + +/* +================ +idLexer::NumLinesCrossed +================ +*/ +int idLexer::NumLinesCrossed( void ) { + return idLexer::line - idLexer::lastline; +} + +/* +================ +idLexer::LoadFile +================ +*/ +int idLexer::LoadFile( const char *filename, bool OSPath ) { + idFile *fp; + idStr pathname; + int length; + char *buf; + + if ( idLexer::loaded ) { + idLib::common->Error("idLexer::LoadFile: another script already loaded"); + return false; + } + + if ( !OSPath && ( baseFolder[0] != '\0' ) ) { + pathname = va( "%s/%s", baseFolder, filename ); + } else { + pathname = filename; + } + if ( OSPath ) { + fp = idLib::fileSystem->OpenExplicitFileRead( pathname ); + } else { + fp = idLib::fileSystem->OpenFileRead( pathname ); + } + if ( !fp ) { + return false; + } + length = fp->Length(); + buf = (char *) Mem_Alloc( length + 1 ); + buf[length] = '\0'; + fp->Read( buf, length ); + idLexer::fileTime = fp->Timestamp(); + idLexer::filename = fp->GetFullPath(); + idLib::fileSystem->CloseFile( fp ); + + idLexer::buffer = buf; + idLexer::length = length; + // pointer in script buffer + idLexer::script_p = idLexer::buffer; + // pointer in script buffer before reading token + idLexer::lastScript_p = idLexer::buffer; + // pointer to end of script buffer + idLexer::end_p = &(idLexer::buffer[length]); + + idLexer::tokenavailable = 0; + idLexer::line = 1; + idLexer::lastline = 1; + idLexer::allocated = true; + idLexer::loaded = true; + + return true; +} + +/* +================ +idLexer::LoadMemory +================ +*/ +int idLexer::LoadMemory( const char *ptr, int length, const char *name, int startLine ) { + if ( idLexer::loaded ) { + idLib::common->Error("idLexer::LoadMemory: another script already loaded"); + return false; + } + idLexer::filename = name; + idLexer::buffer = ptr; + idLexer::fileTime = 0; + idLexer::length = length; + // pointer in script buffer + idLexer::script_p = idLexer::buffer; + // pointer in script buffer before reading token + idLexer::lastScript_p = idLexer::buffer; + // pointer to end of script buffer + idLexer::end_p = &(idLexer::buffer[length]); + + idLexer::tokenavailable = 0; + idLexer::line = startLine; + idLexer::lastline = startLine; + idLexer::allocated = false; + idLexer::loaded = true; + + return true; +} + +/* +================ +idLexer::FreeSource +================ +*/ +void idLexer::FreeSource( void ) { +#ifdef PUNCTABLE + if ( idLexer::punctuationtable && idLexer::punctuationtable != default_punctuationtable ) { + Mem_Free( (void *) idLexer::punctuationtable ); + idLexer::punctuationtable = NULL; + } + if ( idLexer::nextpunctuation && idLexer::nextpunctuation != default_nextpunctuation ) { + Mem_Free( (void *) idLexer::nextpunctuation ); + idLexer::nextpunctuation = NULL; + } +#endif //PUNCTABLE + if ( idLexer::allocated ) { + Mem_Free( (void *) idLexer::buffer ); + idLexer::buffer = NULL; + idLexer::allocated = false; + } + idLexer::tokenavailable = 0; + idLexer::token = ""; + idLexer::loaded = false; +} + +/* +================ +idLexer::idLexer +================ +*/ +idLexer::idLexer( void ) { + idLexer::loaded = false; + idLexer::filename = ""; + idLexer::flags = 0; + idLexer::SetPunctuations( NULL ); + idLexer::allocated = false; + idLexer::fileTime = 0; + idLexer::length = 0; + idLexer::line = 0; + idLexer::lastline = 0; + idLexer::tokenavailable = 0; + idLexer::token = ""; + idLexer::next = NULL; + idLexer::hadError = false; +} + +/* +================ +idLexer::idLexer +================ +*/ +idLexer::idLexer( int flags ) { + idLexer::loaded = false; + idLexer::filename = ""; + idLexer::flags = flags; + idLexer::SetPunctuations( NULL ); + idLexer::allocated = false; + idLexer::fileTime = 0; + idLexer::length = 0; + idLexer::line = 0; + idLexer::lastline = 0; + idLexer::tokenavailable = 0; + idLexer::token = ""; + idLexer::next = NULL; + idLexer::hadError = false; +} + +/* +================ +idLexer::idLexer +================ +*/ +idLexer::idLexer( const char *filename, int flags, bool OSPath ) { + idLexer::loaded = false; + idLexer::flags = flags; + idLexer::SetPunctuations( NULL ); + idLexer::allocated = false; + idLexer::token = ""; + idLexer::next = NULL; + idLexer::hadError = false; + idLexer::LoadFile( filename, OSPath ); +} + +/* +================ +idLexer::idLexer +================ +*/ +idLexer::idLexer( const char *ptr, int length, const char *name, int flags ) { + idLexer::loaded = false; + idLexer::flags = flags; + idLexer::SetPunctuations( NULL ); + idLexer::allocated = false; + idLexer::token = ""; + idLexer::next = NULL; + idLexer::hadError = false; + idLexer::LoadMemory( ptr, length, name ); +} + +/* +================ +idLexer::~idLexer +================ +*/ +idLexer::~idLexer( void ) { + idLexer::FreeSource(); +} + +/* +================ +idLexer::SetBaseFolder +================ +*/ +void idLexer::SetBaseFolder( const char *path ) { + idStr::Copynz( baseFolder, path, sizeof( baseFolder ) ); +} + +/* +================ +idLexer::HadError +================ +*/ +bool idLexer::HadError( void ) const { + return hadError; +} + +#pragma warning( pop ) diff --git a/idlib/Lexer.h b/idlib/Lexer.h new file mode 100644 index 000000000..f73b8f41f --- /dev/null +++ b/idlib/Lexer.h @@ -0,0 +1,374 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LEXER_H__ +#define __LEXER_H__ + +/* +=============================================================================== + + Lexicographical parser + + Does not use memory allocation during parsing. The lexer uses no + memory allocation if a source is loaded with LoadMemory(). + However, idToken may still allocate memory for large strings. + + A number directly following the escape character '\' in a string is + assumed to be in decimal format instead of octal. Binary numbers of + the form 0b.. or 0B.. can also be used. + +=============================================================================== +*/ + +// lexer flags +typedef enum { + LEXFL_NOERRORS = BIT(0), // don't print any errors + LEXFL_NOWARNINGS = BIT(1), // don't print any warnings + LEXFL_NOFATALERRORS = BIT(2), // errors aren't fatal + LEXFL_NOSTRINGCONCAT = BIT(3), // multiple strings seperated by whitespaces are not concatenated + LEXFL_NOSTRINGESCAPECHARS = BIT(4), // no escape characters inside strings + LEXFL_NODOLLARPRECOMPILE = BIT(5), // don't use the $ sign for precompilation + LEXFL_NOBASEINCLUDES = BIT(6), // don't include files embraced with < > + LEXFL_ALLOWPATHNAMES = BIT(7), // allow path seperators in names + LEXFL_ALLOWNUMBERNAMES = BIT(8), // allow names to start with a number + LEXFL_ALLOWIPADDRESSES = BIT(9), // allow ip addresses to be parsed as numbers + LEXFL_ALLOWFLOATEXCEPTIONS = BIT(10), // allow float exceptions like 1.#INF or 1.#IND to be parsed + LEXFL_ALLOWMULTICHARLITERALS = BIT(11), // allow multi character literals + LEXFL_ALLOWBACKSLASHSTRINGCONCAT = BIT(12), // allow multiple strings seperated by '\' to be concatenated + LEXFL_ONLYSTRINGS = BIT(13) // parse as whitespace deliminated strings (quoted strings keep quotes) +} lexerFlags_t; + +// punctuation ids +#define P_RSHIFT_ASSIGN 1 +#define P_LSHIFT_ASSIGN 2 +#define P_PARMS 3 +#define P_PRECOMPMERGE 4 + +#define P_LOGIC_AND 5 +#define P_LOGIC_OR 6 +#define P_LOGIC_GEQ 7 +#define P_LOGIC_LEQ 8 +#define P_LOGIC_EQ 9 +#define P_LOGIC_UNEQ 10 + +#define P_MUL_ASSIGN 11 +#define P_DIV_ASSIGN 12 +#define P_MOD_ASSIGN 13 +#define P_ADD_ASSIGN 14 +#define P_SUB_ASSIGN 15 +#define P_INC 16 +#define P_DEC 17 + +#define P_BIN_AND_ASSIGN 18 +#define P_BIN_OR_ASSIGN 19 +#define P_BIN_XOR_ASSIGN 20 +#define P_RSHIFT 21 +#define P_LSHIFT 22 + +#define P_POINTERREF 23 +#define P_CPP1 24 +#define P_CPP2 25 +#define P_MUL 26 +#define P_DIV 27 +#define P_MOD 28 +#define P_ADD 29 +#define P_SUB 30 +#define P_ASSIGN 31 + +#define P_BIN_AND 32 +#define P_BIN_OR 33 +#define P_BIN_XOR 34 +#define P_BIN_NOT 35 + +#define P_LOGIC_NOT 36 +#define P_LOGIC_GREATER 37 +#define P_LOGIC_LESS 38 + +#define P_REF 39 +#define P_COMMA 40 +#define P_SEMICOLON 41 +#define P_COLON 42 +#define P_QUESTIONMARK 43 + +#define P_PARENTHESESOPEN 44 +#define P_PARENTHESESCLOSE 45 +#define P_BRACEOPEN 46 +#define P_BRACECLOSE 47 +#define P_SQBRACKETOPEN 48 +#define P_SQBRACKETCLOSE 49 +#define P_BACKSLASH 50 + +#define P_PRECOMP 51 +#define P_DOLLAR 52 + +// punctuation +typedef struct punctuation_s +{ + const char *p; // punctuation character(s) + int n; // punctuation id +} punctuation_t; + +/// A lexer created by ID software. +/** This is a lexer for C-like languages. Whitespace and C-style comments are + * ignored. The input line is broken up into tokens which consist of string + * literals, numeric literals, identifiers and operators. + * + * String literals are of the form "blah blah blah" or 'c', just like in C. + * Double-quoted strings can be of any length, but single-quoted strings are + * expected to contain a single character. (escape sequences are considered + * to form a single character, so '\n' is a valid string literal) The same + * escape characters as C are allowed. Adjacent (ignoring whitespace) string + * literals are considered to represent one long string literal who's + * contents is the concatenation of the smaller strings. For example, + * "foo" "bar" is equivelant to "foobar", and will be returned as a single + * token. + * Lexer flags relavent to string literals: + * LEXFL_NOSTRINGCONCAT: Adjacent string literals aren't considered to form + * one long string. Instead, each string is considered its own token. + * This will cause "foo" "bar" to be treated as two tokens instead of one. + * LEXFL_ALLOWBACKSLASHSTRINGCONCAT: Backslashes may be used to concatenate + * string literals. (whitespace is ignored) For example "foo" \ "bar" is + * equivelant to "foobar". If LEXFL_NOSTRINGCONCAT is also turned on, then + * "foo" "bar" is treated as two tokens, but "foo" \ "bar" is treated as + * one. + * LEXFL_ALLOWMULTICHARLITERALS: Single-quoted string literals such as 'x' + * may to contain multiple characters. So 'blah' is considered a valid + * string literal. 'foo' 'bar' is equivelant to 'foobar' unless + * LEXFL_NOSTRINGCONCAT is turned on. LEXFL_ALLOWBACKSLASHSTRINGCONCAT + * does not have an effect on single-quoted string literals. + * LEXFL_NOSTRINGESCAPECHARS: Escape characters aren't allowed in strings. + * Instead, backslashes are treated as the contents of the string. + * For example, "\\" would be a string of two characters, not one. + * Because of this, '\n' would no longer be a valid string literal, + * unless LEXFL_ALLOWMULTICHARLITERALS is turned on. + * + * I haven't learned much about numeric literals. As such, this section is a + * stub. + * Lexer flags relavent to numeric literals: + * LEXFL_ALLOWIPADDRESSES: allow ip addresses to be parsed as numbers + * LEXFL_ALLOWFLOATEXCEPTIONS: allow float exceptions like 1.#INF or 1.#IND to be parsed + * + * Identifiers (names) are the same as in C. They may contain letters, + * numbers and underscores, but may not start with numbers. + * Lexer flags relavent to identifiers: + * LEXFL_ALLOWPATHNAMES: Identifiers are also allowed to have slashes, + * backslashes, colons and periods in them. + * LEXFL_ALLOWNUMBERNAMES: An identifier may start with a numeric literal. + * LEXFL_ONLYSTRINGS: Tokens are only returned as strings and identifiers. + * Identifiers may contain dashes in them. I beleive this flag is buggy, + * since it looks like +blah is considered a single token, but blah+ is + * considered two. + * + * Generic lexer flags: + * LEXFL_NOERRORS: Errors are disabled. + * LEXFL_NOWARNINGS: Warnings are disabled. + * LEXFL_NOFATALERRORS: Errors are converted to warnings. This flag is + * redundant if LEXFL_NOERRORS is turned on. Even if LEXFL_NOWARNINGS is + * turned on, warnings that were converted from errors will not be ignored. + * + * Lexer flags that are used by the parser instead of the lexer: + * LEXFL_NODOLLARPRECOMPILE: don't use the $ sign for precompilation + * LEXFL_NOBASEINCLUDES: don't include files embraced with < > + * + * Other notes: UnreadToken() appears to be incompatible with many other + * functions, such as the Check or Peek functions. You should Either use + * UnreadToken() or the Peek/Check functions but not both. + * + */ +class idLexer { + + friend class idParser; + +public: + // constructor + idLexer(); + idLexer( int flags ); + idLexer( const char *filename, int flags = 0, bool OSPath = false ); + idLexer( const char *ptr, int length, const char *name, int flags = 0 ); + // destructor + ~idLexer(); + // load a script from the given file at the given offset with the given length + int LoadFile( const char *filename, bool OSPath = false ); + // load a script from the given memory with the given length and a specified line offset, + // so source strings extracted from a file can still refer to proper line numbers in the file + // NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0' + int LoadMemory( const char *ptr, int length, const char *name, int startLine = 1 ); + // free the script + void FreeSource( void ); + // returns true if a script is loaded + int IsLoaded( void ) { return idLexer::loaded; }; + // read a token + int ReadToken( idToken *token ); + // expect a certain token, reads the token when available + int ExpectTokenString( const char *string ); + // expect a certain token type + int ExpectTokenType( int type, int subtype, idToken *token ); + // expect a token + int ExpectAnyToken( idToken *token ); + // returns true when the token is available + int CheckTokenString( const char *string ); + // returns true an reads the token when a token with the given type is available + int CheckTokenType( int type, int subtype, idToken *token ); + // returns true if the next token equals the given string but does not remove the token from the source + int PeekTokenString( const char *string ); + // returns true if the next token equals the given type but does not remove the token from the source + int PeekTokenType( int type, int subtype, idToken *token ); + // skip tokens until the given token string is read + int SkipUntilString( const char *string ); + // skip the rest of the current line + int SkipRestOfLine( void ); + // skip the braced section + int SkipBracedSection( bool parseFirstBrace = true ); + // unread the given token + void UnreadToken( const idToken *token ); + // read a token only if on the same line + int ReadTokenOnLine( idToken *token ); + + //Returns the rest of the current line + const char* ReadRestOfLine(idStr& out); + + // read a signed integer + int ParseInt( void ); + // read a boolean + bool ParseBool( void ); + // read a floating point number. If errorFlag is NULL, a non-numeric token will + // issue an Error(). If it isn't NULL, it will issue a Warning() and set *errorFlag = true + float ParseFloat( bool *errorFlag = NULL ); + /** + * Parse a 1d float matrix of length x and store it in m. + * If bIntsOnly is TRUE, a non-integer token will issue an Error(). + **/ + int Parse1DMatrix( int x, float *m, bool bIntsOnly = false ); + /** + * Parse 1d integer matrix by overloading parse1DMatrix + **/ + int Parse1DMatrix( int x, int *m ); + int Parse2DMatrix( int y, int x, float *m ); + int Parse3DMatrix( int z, int y, int x, float *m ); + // parse a braced section into a string + const char * ParseBracedSection( idStr &out ); + // parse a braced section into a string, maintaining indents and newlines + const char * ParseBracedSectionExact ( idStr &out, int tabs = -1 ); + // parse the rest of the line + const char * ParseRestOfLine( idStr &out ); + // retrieves the white space characters before the last read token + int GetLastWhiteSpace( idStr &whiteSpace ) const; + // returns start index into text buffer of last white space + int GetLastWhiteSpaceStart( void ) const; + // returns end index into text buffer of last white space + int GetLastWhiteSpaceEnd( void ) const; + // set an array with punctuations, NULL restores default C/C++ set, see default_punctuations for an example + void SetPunctuations( const punctuation_t *p ); + // returns a pointer to the punctuation with the given id + const char * GetPunctuationFromId( int id ); + // get the id for the given punctuation + int GetPunctuationId( const char *p ); + // set lexer flags + void SetFlags( int flags ); + // get lexer flags + int GetFlags( void ); + // reset the lexer + void Reset( void ); + // returns true if at the end of the file + int EndOfFile( void ); + // returns the current filename + const char * GetFileName( void ); + // get offset in script + const int GetFileOffset( void ); + // get file time + const ID_TIME_T GetFileTime( void ); + // returns the current line number + const int GetLineNum( void ); + // print an error message + void Error( const char *str, ... ) id_attribute((format(printf,2,3))); + + // print a warning message + + void Warning( const char *str, ... ) id_attribute((format(printf,2,3))); + + // returns true if Error() was called with LEXFL_NOFATALERRORS or LEXFL_NOERRORS set + bool HadError( void ) const; + + // set the base folder to load files from + static void SetBaseFolder( const char *path ); + +private: + int loaded; // set when a script file is loaded from file or memory + idStr filename; // file name of the script + int allocated; // true if buffer memory was allocated + const char * buffer; // buffer containing the script + const char * script_p; // current pointer in the script + const char * end_p; // pointer to the end of the script + const char * lastScript_p; // script pointer before reading token + const char * whiteSpaceStart_p; // start of last white space + const char * whiteSpaceEnd_p; // end of last white space + unsigned int fileTime; // file time + int length; // length of the script in bytes + int line; // current line in script + int lastline; // line before reading token + int tokenavailable; // set by unreadToken + int flags; // several script flags + const punctuation_t *punctuations; // the punctuations used in the script + int * punctuationtable; // ASCII table with punctuations + int * nextpunctuation; // next punctuation in chain + idToken token; // available token + idLexer * next; // next script in a chain + bool hadError; // set by idLexer::Error, even if the error is supressed + + static char baseFolder[ 256 ]; // base folder to load files from + +private: + void CreatePunctuationTable( const punctuation_t *punctuations ); + int ReadWhiteSpace( void ); + int ReadEscapeCharacter( char *ch ); + int ReadString( idToken *token, int quote ); + int ReadName( idToken *token ); + int ReadNumber( idToken *token ); + int ReadPunctuation( idToken *token ); + int ReadPrimitive( idToken *token ); + int CheckString( const char *str ) const; + int NumLinesCrossed( void ); +}; + +ID_INLINE const char *idLexer::GetFileName( void ) { + return idLexer::filename; +} + +ID_INLINE const int idLexer::GetFileOffset( void ) { + return idLexer::script_p - idLexer::buffer; +} + +ID_INLINE const ID_TIME_T idLexer::GetFileTime( void ) { + return idLexer::fileTime; +} + +ID_INLINE const int idLexer::GetLineNum( void ) { + return idLexer::line; +} + +ID_INLINE void idLexer::SetFlags( int flags ) { + idLexer::flags = flags; +} + +ID_INLINE int idLexer::GetFlags( void ) { + return idLexer::flags; +} + +#endif /* !__LEXER_H__ */ + diff --git a/idlib/Lib.cpp b/idlib/Lib.cpp new file mode 100644 index 000000000..57236efd3 --- /dev/null +++ b/idlib/Lib.cpp @@ -0,0 +1,576 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + +#if defined( MACOS_X ) +#include +#include +#include +#endif + +/* +=============================================================================== + + idLib + +=============================================================================== +*/ + +idSys * idLib::sys = NULL; +idCommon * idLib::common = NULL; +idCVarSystem * idLib::cvarSystem = NULL; +idFileSystem * idLib::fileSystem = NULL; +int idLib::frameNumber = 0; + +/* +================ +idLib::Init +================ +*/ +void idLib::Init( void ) { + + assert( sizeof( bool ) == 1 ); + + // initialize little/big endian conversion + Swap_Init(); + + // initialize memory manager + Mem_Init(); + + // init string memory allocator + idStr::InitMemory(); + + // initialize generic SIMD implementation + idSIMD::Init(); + + // initialize math + idMath::Init(); + + // test idMatX + //idMatX::Test(); + + // test idPolynomial + idPolynomial::Test(); + + // initialize the dictionary string pools + idDict::Init(); +} + +/* +================ +idLib::ShutDown +================ +*/ +void idLib::ShutDown( void ) { + + // shut down the dictionary string pools + idDict::Shutdown(); + + // shut down the string memory allocator + idStr::ShutdownMemory(); + + // shut down the SIMD engine + idSIMD::Shutdown(); + + // shut down the memory manager + Mem_Shutdown(); +} + + +/* +=============================================================================== + + Colors + +=============================================================================== +*/ + +idVec4 colorBlack = idVec4( 0.00f, 0.00f, 0.00f, 1.00f ); +idVec4 colorWhite = idVec4( 1.00f, 1.00f, 1.00f, 1.00f ); +idVec4 colorRed = idVec4( 1.00f, 0.00f, 0.00f, 1.00f ); +idVec4 colorGreen = idVec4( 0.00f, 1.00f, 0.00f, 1.00f ); +idVec4 colorBlue = idVec4( 0.00f, 0.00f, 1.00f, 1.00f ); +idVec4 colorYellow = idVec4( 1.00f, 1.00f, 0.00f, 1.00f ); +idVec4 colorMagenta= idVec4( 1.00f, 0.00f, 1.00f, 1.00f ); +idVec4 colorCyan = idVec4( 0.00f, 1.00f, 1.00f, 1.00f ); +idVec4 colorOrange = idVec4( 1.00f, 0.50f, 0.00f, 1.00f ); +idVec4 colorPurple = idVec4( 0.60f, 0.00f, 0.60f, 1.00f ); +idVec4 colorPink = idVec4( 0.73f, 0.40f, 0.48f, 1.00f ); +idVec4 colorBrown = idVec4( 0.40f, 0.35f, 0.08f, 1.00f ); +idVec4 colorLtGrey = idVec4( 0.75f, 0.75f, 0.75f, 1.00f ); +idVec4 colorMdGrey = idVec4( 0.50f, 0.50f, 0.50f, 1.00f ); +idVec4 colorDkGrey = idVec4( 0.25f, 0.25f, 0.25f, 1.00f ); + +static dword colorMask[2] = { 255, 0 }; + +/* +================ +ColorFloatToByte +================ +*/ +ID_INLINE static byte ColorFloatToByte( float c ) { + return (byte) ( ( (dword) ( c * 255.0f ) ) & colorMask[FLOATSIGNBITSET(c)] ); +} + +/* +================ +PackColor +================ +*/ +dword PackColor( const idVec4 &color ) { + dword dw, dx, dy, dz; + + dx = ColorFloatToByte( color.x ); + dy = ColorFloatToByte( color.y ); + dz = ColorFloatToByte( color.z ); + dw = ColorFloatToByte( color.w ); + +#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) + return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 ) | ( dw << 24 ); +#elif (defined(MACOS_X) && defined(__ppc__)) + return ( dx << 24 ) | ( dy << 16 ) | ( dz << 8 ) | ( dw << 0 ); +#else +#error OS define is required! +#endif +} + +/* +================ +UnpackColor +================ +*/ +void UnpackColor( const dword color, idVec4 &unpackedColor ) { +#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) + unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ) ); +#elif (defined(MACOS_X) && defined(__ppc__)) + unpackedColor.Set( ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) ); +#else +#error OS define is required! +#endif +} + +/* +================ +PackColor +================ +*/ +dword PackColor( const idVec3 &color ) { + dword dx, dy, dz; + + dx = ColorFloatToByte( color.x ); + dy = ColorFloatToByte( color.y ); + dz = ColorFloatToByte( color.z ); + +#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) + return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 ); +#elif (defined(MACOS_X) && defined(__ppc__)) + return ( dy << 16 ) | ( dz << 8 ) | ( dx << 0 ); +#else +#error OS define is required! +#endif +} + +/* +================ +UnpackColor +================ +*/ +void UnpackColor( const dword color, idVec3 &unpackedColor ) { +#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) + unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ) ); +#elif (defined(MACOS_X) && defined(__ppc__)) + unpackedColor.Set( ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), + ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) ); +#else +#error OS define is required! +#endif +} + +/* +=============== +idLib::Error +=============== +*/ +void idLib::Error( const char *fmt, ... ) { + va_list argptr; + char text[MAX_STRING_CHARS]; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + common->Error( "%s", text ); +} + +/* +=============== +idLib::Warning +=============== +*/ +void idLib::Warning( const char *fmt, ... ) { + va_list argptr; + char text[MAX_STRING_CHARS]; + + va_start( argptr, fmt ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); + va_end( argptr ); + + common->Warning( "%s", text ); +} + +/* +=============================================================================== + + Byte order functions + +=============================================================================== +*/ + +// can't just use function pointers, or dll linkage can mess up +static short (*_BigShort)( short l ); +static short (*_LittleShort)( short l ); +static int (*_BigLong)( int l ); +static int (*_LittleLong)( int l ); +static float (*_BigFloat)( float l ); +static float (*_LittleFloat)( float l ); +static void (*_BigRevBytes)( void *bp, int elsize, int elcount ); +static void (*_LittleRevBytes)( void *bp, int elsize, int elcount ); +static void (*_LittleBitField)( void *bp, int elsize ); +static void (*_SixtetsForInt)( byte *out, int src ); +static int (*_IntForSixtets)( byte *in ); + +short BigShort( short l ) { return _BigShort( l ); } +short LittleShort( short l ) { return _LittleShort( l ); } +int BigLong( int l ) { return _BigLong( l ); } +int LittleLong( int l ) { return _LittleLong( l ); } +float BigFloat( float l ) { return _BigFloat( l ); } +float LittleFloat( float l ) { return _LittleFloat( l ); } +void BigRevBytes( void *bp, int elsize, int elcount ) { _BigRevBytes( bp, elsize, elcount ); } +void LittleRevBytes( void *bp, int elsize, int elcount ){ _LittleRevBytes( bp, elsize, elcount ); } +void LittleBitField( void *bp, int elsize ){ _LittleBitField( bp, elsize ); } + +void SixtetsForInt( byte *out, int src) { _SixtetsForInt( out, src ); } +int IntForSixtets( byte *in ) { return _IntForSixtets( in ); } + +/* +================ +ShortSwap +================ +*/ +short ShortSwap( short l ) { + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +/* +================ +ShortNoSwap +================ +*/ +short ShortNoSwap( short l ) { + return l; +} + +/* +================ +LongSwap +================ +*/ +int LongSwap ( int l ) { + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +/* +================ +LongNoSwap +================ +*/ +int LongNoSwap( int l ) { + return l; +} + +/* +================ +FloatSwap +================ +*/ +float FloatSwap( float f ) { + union { + float f; + byte b[4]; + } dat1, dat2; + + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + return dat2.f; +} + +/* +================ +FloatNoSwap +================ +*/ +float FloatNoSwap( float f ) { + return f; +} + +/* +===================================================================== +RevBytesSwap + +Reverses byte order in place. + +INPUTS + bp bytes to reverse + elsize size of the underlying data type + elcount number of elements to swap + +RESULTS + Reverses the byte order in each of elcount elements. +===================================================================== */ +void RevBytesSwap( void *bp, int elsize, int elcount ) { + register unsigned char *p, *q; + + p = ( unsigned char * ) bp; + + if ( elsize == 2 ) { + q = p + 1; + while ( elcount-- ) { + *p ^= *q; + *q ^= *p; + *p ^= *q; + p += 2; + q += 2; + } + return; + } + + while ( elcount-- ) { + q = p + elsize - 1; + while ( p < q ) { + *p ^= *q; + *q ^= *p; + *p ^= *q; + ++p; + --q; + } + p += elsize >> 1; + } +} + +/* + ===================================================================== + RevBytesSwap + + Reverses byte order in place, then reverses bits in those bytes + + INPUTS + bp bitfield structure to reverse + elsize size of the underlying data type + + RESULTS + Reverses the bitfield of size elsize. + ===================================================================== */ +void RevBitFieldSwap( void *bp, int elsize) { + int i; + unsigned char *p, t, v; + + LittleRevBytes( bp, elsize, 1 ); + + p = (unsigned char *) bp; + while ( elsize-- ) { + v = *p; + t = 0; + for (i = 7; i; i--) { + t <<= 1; + v >>= 1; + t |= v & 1; + } + *p++ = t; + } +} + +/* +================ +RevBytesNoSwap +================ +*/ +void RevBytesNoSwap( void *bp, int elsize, int elcount ) { + return; +} + +/* + ================ + RevBytesNoSwap + ================ + */ +void RevBitFieldNoSwap( void *bp, int elsize ) { + return; +} + +/* +================ +SixtetsForIntLittle +================ +*/ +void SixtetsForIntLittle( byte *out, int src) { + byte *b = (byte *)&src; + out[0] = ( b[0] & 0xfc ) >> 2; + out[1] = ( ( b[0] & 0x3 ) << 4 ) + ( ( b[1] & 0xf0 ) >> 4 ); + out[2] = ( ( b[1] & 0xf ) << 2 ) + ( ( b[2] & 0xc0 ) >> 6 ); + out[3] = b[2] & 0x3f; +} + +/* +================ +SixtetsForIntBig +TTimo: untested - that's the version from initial base64 encode +================ +*/ +void SixtetsForIntBig( byte *out, int src) { + for( int i = 0 ; i < 4 ; i++ ) { + out[i] = src & 0x3f; + src >>= 6; + } +} + +/* +================ +IntForSixtetsLittle +================ +*/ +int IntForSixtetsLittle( byte *in ) { + int ret = 0; + byte *b = (byte *)&ret; + b[0] |= in[0] << 2; + b[0] |= ( in[1] & 0x30 ) >> 4; + b[1] |= ( in[1] & 0xf ) << 4; + b[1] |= ( in[2] & 0x3c ) >> 2; + b[2] |= ( in[2] & 0x3 ) << 6; + b[2] |= in[3]; + return ret; +} + +/* +================ +IntForSixtetsBig +TTimo: untested - that's the version from initial base64 decode +================ +*/ +int IntForSixtetsBig( byte *in ) { + int ret = 0; + ret |= in[0]; + ret |= in[1] << 6; + ret |= in[2] << 2*6; + ret |= in[3] << 3*6; + return ret; +} + +/* +================ +Swap_Init +================ +*/ +void Swap_Init( void ) { + byte swaptest[2] = {1,0}; + + // set the byte swapping variables in a portable manner + if ( *(short *)swaptest == 1) { + // little endian ex: x86 + _BigShort = ShortSwap; + _LittleShort = ShortNoSwap; + _BigLong = LongSwap; + _LittleLong = LongNoSwap; + _BigFloat = FloatSwap; + _LittleFloat = FloatNoSwap; + _BigRevBytes = RevBytesSwap; + _LittleRevBytes = RevBytesNoSwap; + _LittleBitField = RevBitFieldNoSwap; + _SixtetsForInt = SixtetsForIntLittle; + _IntForSixtets = IntForSixtetsLittle; + } else { + // big endian ex: ppc + _BigShort = ShortNoSwap; + _LittleShort = ShortSwap; + _BigLong = LongNoSwap; + _LittleLong = LongSwap; + _BigFloat = FloatNoSwap; + _LittleFloat = FloatSwap; + _BigRevBytes = RevBytesNoSwap; + _LittleRevBytes = RevBytesSwap; + _LittleBitField = RevBitFieldSwap; + _SixtetsForInt = SixtetsForIntBig; + _IntForSixtets = IntForSixtetsBig; + } +} + +/* +========== +Swap_IsBigEndian +========== +*/ +bool Swap_IsBigEndian( void ) { + byte swaptest[2] = {1,0}; + return *(short *)swaptest != 1; +} + +/* +=============================================================================== + + Assertion + +=============================================================================== +*/ + +void AssertFailed( const char *file, int line, const char *expression ) { + idLib::sys->DebugPrintf( "\n\nASSERTION FAILED!\n%s(%d): '%s'\n", file, line, expression ); +#ifdef _WIN32 + __asm int 0x03 +#elif defined( __linux__ ) + __asm__ __volatile__ ("int $0x03"); +#elif defined( MACOS_X ) + kill( getpid(), SIGINT ); +#endif +} diff --git a/idlib/Lib.h b/idlib/Lib.h new file mode 100644 index 000000000..1e594ff58 --- /dev/null +++ b/idlib/Lib.h @@ -0,0 +1,231 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LIB_H__ +#define __LIB_H__ + + +/* +=============================================================================== + + idLib contains stateless support classes and concrete types. Some classes + do have static variables, but such variables are initialized once and + read-only after initialization (they do not maintain a modifiable state). + + The interface pointers idSys, idCommon, idCVarSystem and idFileSystem + should be set before using idLib. The pointers stored here should not + be used by any part of the engine except for idLib. + + The frameNumber should be continuously set to the number of the current + frame if frame base memory logging is required. + +=============================================================================== +*/ + +class idLib { +public: + static class idSys * sys; + static class idCommon * common; + static class idCVarSystem * cvarSystem; + static class idFileSystem * fileSystem; + static int frameNumber; + + static void Init( void ); + static void ShutDown( void ); + + // wrapper to idCommon functions + static void Error( const char *fmt, ... ); + static void Warning( const char *fmt, ... ); +}; + + +/* +=============================================================================== + + Types and defines used throughout the engine. + +=============================================================================== +*/ + +typedef unsigned char byte; // 8 bits +typedef unsigned short word; // 16 bits +typedef unsigned int dword; // 32 bits +typedef unsigned int uint; +typedef unsigned long ulong; + +typedef int qhandle_t; + +class idFile; +class idVec3; +class idVec4; + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef BIT +#define BIT( num ) ( 1 << ( num ) ) +#endif + +#define MAX_STRING_CHARS 1024 // max length of a string + +// maximum world size +#define MAX_WORLD_COORD ( 128 * 1024 ) +#define MIN_WORLD_COORD ( -128 * 1024 ) +#define MAX_WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD ) + +// basic colors +extern idVec4 colorBlack; +extern idVec4 colorWhite; +extern idVec4 colorRed; +extern idVec4 colorGreen; +extern idVec4 colorBlue; +extern idVec4 colorYellow; +extern idVec4 colorMagenta; +extern idVec4 colorCyan; +extern idVec4 colorOrange; +extern idVec4 colorPurple; +extern idVec4 colorPink; +extern idVec4 colorBrown; +extern idVec4 colorLtGrey; +extern idVec4 colorMdGrey; +extern idVec4 colorDkGrey; + +// packs color floats in the range [0,1] into an integer +dword PackColor( const idVec3 &color ); +void UnpackColor( const dword color, idVec3 &unpackedColor ); +dword PackColor( const idVec4 &color ); +void UnpackColor( const dword color, idVec4 &unpackedColor ); + +// little/big endian conversion +short BigShort( short l ); +short LittleShort( short l ); +int BigLong( int l ); +int LittleLong( int l ); +float BigFloat( float l ); +float LittleFloat( float l ); +void BigRevBytes( void *bp, int elsize, int elcount ); +void LittleRevBytes( void *bp, int elsize, int elcount ); +void LittleBitField( void *bp, int elsize ); +void Swap_Init( void ); + +bool Swap_IsBigEndian( void ); + +// for base64 +void SixtetsForInt( byte *out, int src); +int IntForSixtets( byte *in ); + + +#ifdef _DEBUG +void AssertFailed( const char *file, int line, const char *expression ); +#undef assert +#define assert( X ) if ( X ) { } else AssertFailed( __FILE__, __LINE__, #X ) +#endif + +class idException { +public: + char error[MAX_STRING_CHARS]; + + idException( const char *text = "" ) { strcpy( error, text ); } +}; + +/* +=============================================================================== + + idLib headers. + +=============================================================================== +*/ + +// memory management and arrays +#include "Heap.h" +#include "containers/List.h" + +// math +#include "math/Simd.h" +#include "math/Math.h" +#include "math/Random.h" +#include "math/Complex.h" +#include "math/Vector.h" +#include "math/Matrix.h" +#include "math/Angles.h" +#include "math/Quat.h" +#include "math/Rotation.h" +#include "math/Plane.h" +#include "math/Pluecker.h" +#include "math/Polynomial.h" +#include "math/Extrapolate.h" +#include "math/Interpolate.h" +#include "math/Curve.h" +#include "math/Ode.h" +#include "math/Lcp.h" + +// bounding volumes +#include "bv/Sphere.h" +#include "bv/Bounds.h" +#include "bv/Box.h" +#include "bv/Frustum.h" + +// geometry +#include "geometry/DrawVert.h" +#include "geometry/JointTransform.h" +#include "geometry/Winding.h" +#include "geometry/Winding2D.h" +#include "geometry/Surface.h" +#include "geometry/Surface_Patch.h" +#include "geometry/Surface_Polytope.h" +#include "geometry/Surface_SweptSpline.h" +#include "geometry/TraceModel.h" + +// text manipulation +#include "Str.h" +#include "Token.h" +#include "Lexer.h" +#include "Parser.h" +#include "Base64.h" +#include "CmdArgs.h" + +// containers +#include "containers/BTree.h" +#include "containers/BinSearch.h" +#include "containers/HashIndex.h" +#include "containers/HashTable.h" +#include "containers/StaticList.h" +#include "containers/LinkList.h" +#include "containers/Hierarchy.h" +#include "containers/Queue.h" +#include "containers/Stack.h" +#include "containers/StrList.h" +#include "containers/StrPool.h" +#include "containers/VectorSet.h" +#include "containers/PlaneSet.h" + +// hashing +#include "hashing/CRC32.h" +#include "hashing/MD4.h" +#include "hashing/MD5.h" + +// misc +#include "Dict.h" +#include "LangDict.h" +#include "BitMsg.h" +#include "MapFile.h" +#include "Timer.h" + +#endif /* !__LIB_H__ */ diff --git a/idlib/MapFile.cpp b/idlib/MapFile.cpp new file mode 100644 index 000000000..944b8a531 --- /dev/null +++ b/idlib/MapFile.cpp @@ -0,0 +1,958 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + +/* +=============== +FloatCRC +=============== +*/ +ID_INLINE unsigned int FloatCRC( float f ) { + return *(unsigned int *)&f; +} + +/* +=============== +StringCRC +=============== +*/ +ID_INLINE unsigned int StringCRC( const char *str ) { + unsigned int i, crc; + const unsigned char *ptr; + + crc = 0; + ptr = reinterpret_cast(str); + for ( i = 0; str[i]; i++ ) { + crc ^= str[i] << (i & 3); + } + return crc; +} + +/* +================= +ComputeAxisBase + +WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0 +rotation by (0,RotY,RotZ) assigns X to normal +================= +*/ +static void ComputeAxisBase( const idVec3 &normal, idVec3 &texS, idVec3 &texT ) { + float RotY, RotZ; + idVec3 n; + + // do some cleaning + n[0] = ( idMath::Fabs( normal[0] ) < 1e-6f ) ? 0.0f : normal[0]; + n[1] = ( idMath::Fabs( normal[1] ) < 1e-6f ) ? 0.0f : normal[1]; + n[2] = ( idMath::Fabs( normal[2] ) < 1e-6f ) ? 0.0f : normal[2]; + + RotY = -atan2( n[2], idMath::Sqrt( n[1] * n[1] + n[0] * n[0]) ); + RotZ = atan2( n[1], n[0] ); + // rotate (0,1,0) and (0,0,1) to compute texS and texT + texS[0] = -sin(RotZ); + texS[1] = cos(RotZ); + texS[2] = 0; + // the texT vector is along -Z ( T texture coorinates axis ) + texT[0] = -sin(RotY) * cos(RotZ); + texT[1] = -sin(RotY) * sin(RotZ); + texT[2] = -cos(RotY); +} + +/* +================= +idMapBrushSide::GetTextureVectors +================= +*/ +void idMapBrushSide::GetTextureVectors( idVec4 v[2] ) const { + int i; + idVec3 texX, texY; + + ComputeAxisBase( plane.Normal(), texX, texY ); + for ( i = 0; i < 2; i++ ) { + v[i][0] = texX[0] * texMat[i][0] + texY[0] * texMat[i][1]; + v[i][1] = texX[1] * texMat[i][0] + texY[1] * texMat[i][1]; + v[i][2] = texX[2] * texMat[i][0] + texY[2] * texMat[i][1]; + v[i][3] = texMat[i][2] + ( origin * v[i].ToVec3() ); + } +} + +/* +================= +idMapPatch::Parse +================= +*/ +idMapPatch *idMapPatch::Parse( idLexer &src, const idVec3 &origin, bool patchDef3, float version ) { + float info[7]; + idDrawVert *vert; + idToken token; + int i, j; + + if ( !src.ExpectTokenString( "{" ) ) { + return NULL; + } + + // read the material (we had an implicit 'textures/' in the old format...) + if ( !src.ReadToken( &token ) ) { + src.Error( "idMapPatch::Parse: unexpected EOF" ); + return NULL; + } + + // Parse it + if (patchDef3) { + if ( !src.Parse1DMatrix( 7, info ) ) { + src.Error( "idMapPatch::Parse: unable to Parse patchDef3 info" ); + return NULL; + } + } else { + if ( !src.Parse1DMatrix( 5, info ) ) { + src.Error( "idMapPatch::Parse: unable to parse patchDef2 info" ); + return NULL; + } + } + + idMapPatch *patch = new idMapPatch( info[0], info[1] ); + patch->SetSize( info[0], info[1] ); + if ( version < 2.0f ) { + patch->SetMaterial( "textures/" + token ); + } else { + patch->SetMaterial( token ); + } + + if ( patchDef3 ) { + patch->SetHorzSubdivisions( info[2] ); + patch->SetVertSubdivisions( info[3] ); + patch->SetExplicitlySubdivided( true ); + } + + if ( patch->GetWidth() < 0 || patch->GetHeight() < 0 ) { + src.Error( "idMapPatch::Parse: bad size" ); + delete patch; + return NULL; + } + + // these were written out in the wrong order, IMHO + if ( !src.ExpectTokenString( "(" ) ) { + src.Error( "idMapPatch::Parse: bad patch vertex data" ); + delete patch; + return NULL; + } + for ( j = 0; j < patch->GetWidth(); j++ ) { + if ( !src.ExpectTokenString( "(" ) ) { + src.Error( "idMapPatch::Parse: bad vertex row data" ); + delete patch; + return NULL; + } + for ( i = 0; i < patch->GetHeight(); i++ ) { + float v[5]; + + if ( !src.Parse1DMatrix( 5, v ) ) { + src.Error( "idMapPatch::Parse: bad vertex column data" ); + delete patch; + return NULL; + } + + vert = &((*patch)[i * patch->GetWidth() + j]); + vert->xyz[0] = v[0] - origin[0]; + vert->xyz[1] = v[1] - origin[1]; + vert->xyz[2] = v[2] - origin[2]; + vert->st[0] = v[3]; + vert->st[1] = v[4]; + } + if ( !src.ExpectTokenString( ")" ) ) { + delete patch; + src.Error( "idMapPatch::Parse: unable to parse patch control points" ); + return NULL; + } + } + if ( !src.ExpectTokenString( ")" ) ) { + src.Error( "idMapPatch::Parse: unable to parse patch control points, no closure" ); + delete patch; + return NULL; + } + + // read any key/value pairs + while( src.ReadToken( &token ) ) { + if ( token == "}" ) { + src.ExpectTokenString( "}" ); + break; + } + if ( token.type == TT_STRING ) { + idStr key = token; + src.ExpectTokenType( TT_STRING, 0, &token ); + patch->epairs.Set( key, token ); + } + } + + return patch; +} + +/* +============ +idMapPatch::Write +============ +*/ +bool idMapPatch::Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const { + int i, j; + const idDrawVert *v; + + if ( GetExplicitlySubdivided() ) { + fp->WriteFloatString( "// primitive %d\n{\n patchDef3\n {\n", primitiveNum ); + fp->WriteFloatString( " \"%s\"\n ( %d %d %d %d 0 0 0 )\n", GetMaterial(), GetWidth(), GetHeight(), GetHorzSubdivisions(), GetVertSubdivisions()); + } else { + fp->WriteFloatString( "// primitive %d\n{\n patchDef2\n {\n", primitiveNum ); + fp->WriteFloatString( " \"%s\"\n ( %d %d 0 0 0 )\n", GetMaterial(), GetWidth(), GetHeight()); + } + + fp->WriteFloatString( " (\n" ); + for ( i = 0; i < GetWidth(); i++ ) { + fp->WriteFloatString( " ( " ); + for ( j = 0; j < GetHeight(); j++ ) { + v = &verts[ j * GetWidth() + i ]; + fp->WriteFloatString( " ( %f %f %f %f %f )", v->xyz[0] + origin[0], + v->xyz[1] + origin[1], v->xyz[2] + origin[2], v->st[0], v->st[1] ); + } + fp->WriteFloatString( " )\n" ); + } + fp->WriteFloatString( " )\n }\n}\n" ); + + return true; +} + +/* +=============== +idMapPatch::GetGeometryCRC +=============== +*/ +unsigned int idMapPatch::GetGeometryCRC( void ) const { + int i, j; + unsigned int crc; + + crc = GetHorzSubdivisions() ^ GetVertSubdivisions(); + for ( i = 0; i < GetWidth(); i++ ) { + for ( j = 0; j < GetHeight(); j++ ) { + crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.x ); + crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.y ); + crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.z ); + } + } + + crc ^= StringCRC( GetMaterial() ); + + return crc; +} + +/* +================= +idMapBrush::Parse +================= +*/ +idMapBrush *idMapBrush::Parse( idLexer &src, const idVec3 &origin, bool newFormat, float version ) { + int i; + idVec3 planepts[3]; + idToken token; + idList sides; + idMapBrushSide *side; + idDict epairs; + + if ( !src.ExpectTokenString( "{" ) ) { + return NULL; + } + + do { + if ( !src.ReadToken( &token ) ) { + src.Error( "idMapBrush::Parse: unexpected EOF" ); + sides.DeleteContents( true ); + return NULL; + } + if ( token == "}" ) { + break; + } + + // here we may have to jump over brush epairs ( only used in editor ) + do { + // if token is a brace + if ( token == "(" ) { + break; + } + // the token should be a key string for a key/value pair + if ( token.type != TT_STRING ) { + src.Error( "idMapBrush::Parse: unexpected %s, expected ( or epair key string", token.c_str() ); + sides.DeleteContents( true ); + return NULL; + } + + idStr key = token; + + if ( !src.ReadTokenOnLine( &token ) || token.type != TT_STRING ) { + src.Error( "idMapBrush::Parse: expected epair value string not found" ); + sides.DeleteContents( true ); + return NULL; + } + + epairs.Set( key, token ); + + // try to read the next key + if ( !src.ReadToken( &token ) ) { + src.Error( "idMapBrush::Parse: unexpected EOF" ); + sides.DeleteContents( true ); + return NULL; + } + } while (1); + + src.UnreadToken( &token ); + + side = new idMapBrushSide(); + sides.Append(side); + + if ( newFormat ) { + if ( !src.Parse1DMatrix( 4, side->plane.ToFloatPtr() ) ) { + src.Error( "idMapBrush::Parse: unable to read brush side plane definition" ); + sides.DeleteContents( true ); + return NULL; + } + } else { + // read the three point plane definition + if (!src.Parse1DMatrix( 3, planepts[0].ToFloatPtr() ) || + !src.Parse1DMatrix( 3, planepts[1].ToFloatPtr() ) || + !src.Parse1DMatrix( 3, planepts[2].ToFloatPtr() ) ) { + src.Error( "idMapBrush::Parse: unable to read brush side plane definition" ); + sides.DeleteContents( true ); + return NULL; + } + + planepts[0] -= origin; + planepts[1] -= origin; + planepts[2] -= origin; + + side->plane.FromPoints( planepts[0], planepts[1], planepts[2] ); + } + + // read the texture matrix + // this is odd, because the texmat is 2D relative to default planar texture axis + if ( !src.Parse2DMatrix( 2, 3, side->texMat[0].ToFloatPtr() ) ) { + src.Error( "idMapBrush::Parse: unable to read brush side texture matrix" ); + sides.DeleteContents( true ); + return NULL; + } + side->origin = origin; + + // read the material + if ( !src.ReadTokenOnLine( &token ) ) { + src.Error( "idMapBrush::Parse: unable to read brush side material" ); + sides.DeleteContents( true ); + return NULL; + } + + // we had an implicit 'textures/' in the old format... + if ( version < 2.0f ) { + side->material = "textures/" + token; + } else { + side->material = token; + } + + // Q2 allowed override of default flags and values, but we don't any more + if ( src.ReadTokenOnLine( &token ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + } + } + } + } while( 1 ); + + if ( !src.ExpectTokenString( "}" ) ) { + sides.DeleteContents( true ); + return NULL; + } + + idMapBrush *brush = new idMapBrush(); + for ( i = 0; i < sides.Num(); i++ ) { + brush->AddSide( sides[i] ); + } + + brush->epairs = epairs; + + return brush; +} + +/* +================= +idMapBrush::ParseQ3 +================= +*/ +idMapBrush *idMapBrush::ParseQ3( idLexer &src, const idVec3 &origin ) { + int i, shift[2], rotate; + float scale[2]; + idVec3 planepts[3]; + idToken token; + idList sides; + idMapBrushSide *side; + idDict epairs; + + do { + if ( src.CheckTokenString( "}" ) ) { + break; + } + + side = new idMapBrushSide(); + sides.Append( side ); + + // read the three point plane definition + if (!src.Parse1DMatrix( 3, planepts[0].ToFloatPtr() ) || + !src.Parse1DMatrix( 3, planepts[1].ToFloatPtr() ) || + !src.Parse1DMatrix( 3, planepts[2].ToFloatPtr() ) ) { + src.Error( "idMapBrush::ParseQ3: unable to read brush side plane definition" ); + sides.DeleteContents( true ); + return NULL; + } + + planepts[0] -= origin; + planepts[1] -= origin; + planepts[2] -= origin; + + side->plane.FromPoints( planepts[0], planepts[1], planepts[2] ); + + // read the material + if ( !src.ReadTokenOnLine( &token ) ) { + src.Error( "idMapBrush::ParseQ3: unable to read brush side material" ); + sides.DeleteContents( true ); + return NULL; + } + + // we have an implicit 'textures/' in the old format + side->material = "textures/" + token; + + // read the texture shift, rotate and scale + shift[0] = src.ParseInt(); + shift[1] = src.ParseInt(); + rotate = src.ParseInt(); + scale[0] = src.ParseFloat(); + scale[1] = src.ParseFloat(); + side->texMat[0] = idVec3( 0.03125f, 0.0f, 0.0f ); + side->texMat[1] = idVec3( 0.0f, 0.03125f, 0.0f ); + side->origin = origin; + + // Q2 allowed override of default flags and values, but we don't any more + if ( src.ReadTokenOnLine( &token ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + } + } + } + } while( 1 ); + + idMapBrush *brush = new idMapBrush(); + for ( i = 0; i < sides.Num(); i++ ) { + brush->AddSide( sides[i] ); + } + + brush->epairs = epairs; + + return brush; +} + +/* +============ +idMapBrush::Write +============ +*/ +bool idMapBrush::Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const { + int i; + idMapBrushSide *side; + + fp->WriteFloatString( "// primitive %d\n{\n brushDef3\n {\n", primitiveNum ); + + // write brush epairs + for ( i = 0; i < epairs.GetNumKeyVals(); i++) { + fp->WriteFloatString( " \"%s\" \"%s\"\n", epairs.GetKeyVal(i)->GetKey().c_str(), epairs.GetKeyVal(i)->GetValue().c_str()); + } + + // write brush sides + for ( i = 0; i < GetNumSides(); i++ ) { + side = GetSide( i ); + fp->WriteFloatString( " ( %f %f %f %f ) ", side->plane[0], side->plane[1], side->plane[2], side->plane[3] ); + fp->WriteFloatString( "( ( %f %f %f ) ( %f %f %f ) ) \"%s\" 0 0 0\n", + side->texMat[0][0], side->texMat[0][1], side->texMat[0][2], + side->texMat[1][0], side->texMat[1][1], side->texMat[1][2], + side->material.c_str() ); + } + + fp->WriteFloatString( " }\n}\n" ); + + return true; +} + +/* +=============== +idMapBrush::GetGeometryCRC +=============== +*/ +unsigned int idMapBrush::GetGeometryCRC( void ) const { + int i, j; + idMapBrushSide *mapSide; + unsigned int crc; + + crc = 0; + for ( i = 0; i < GetNumSides(); i++ ) { + mapSide = GetSide(i); + for ( j = 0; j < 4; j++ ) { + crc ^= FloatCRC( mapSide->GetPlane()[j] ); + } + crc ^= StringCRC( mapSide->GetMaterial() ); + } + + return crc; +} + +/* +================ +idMapEntity::Parse +================ +*/ +idMapEntity *idMapEntity::Parse( idLexer &src, bool worldSpawn, float version ) { + idToken token; + idMapEntity *mapEnt; + idMapPatch *mapPatch; + idMapBrush *mapBrush; + bool worldent; + idVec3 origin; + double v1, v2, v3; + + if ( !src.ReadToken(&token) ) { + return NULL; + } + + if ( token != "{" ) { + src.Error( "idMapEntity::Parse: { not found, found %s", token.c_str() ); + return NULL; + } + + mapEnt = new idMapEntity(); + + if ( worldSpawn ) { + mapEnt->primitives.Resize( 1024, 256 ); + } + + origin.Zero(); + worldent = false; + do { + if ( !src.ReadToken(&token) ) { + src.Error( "idMapEntity::Parse: EOF without closing brace" ); + return NULL; + } + if ( token == "}" ) { + break; + } + + if ( token == "{" ) { + // parse a brush or patch + if ( !src.ReadToken( &token ) ) { + src.Error( "idMapEntity::Parse: unexpected EOF" ); + return NULL; + } + + if ( worldent ) { + origin.Zero(); + } + + // if is it a brush: brush, brushDef, brushDef2, brushDef3 + if ( token.Icmpn( "brush", 5 ) == 0 ) { + mapBrush = idMapBrush::Parse( src, origin, ( !token.Icmp( "brushDef2" ) || !token.Icmp( "brushDef3" ) ), version ); + if ( !mapBrush ) { + return NULL; + } + mapEnt->AddPrimitive( mapBrush ); + } + // if is it a patch: patchDef2, patchDef3 + else if ( token.Icmpn( "patch", 5 ) == 0 ) { + mapPatch = idMapPatch::Parse( src, origin, !token.Icmp( "patchDef3" ), version ); + if ( !mapPatch ) { + return NULL; + } + mapEnt->AddPrimitive( mapPatch ); + } + // assume it's a brush in Q3 or older style + else { + src.UnreadToken( &token ); + mapBrush = idMapBrush::ParseQ3( src, origin ); + if ( !mapBrush ) { + return NULL; + } + mapEnt->AddPrimitive( mapBrush ); + } + } else { + idStr key, value; + + // parse a key / value pair + key = token; + src.ReadTokenOnLine( &token ); + value = token; + + // strip trailing spaces that sometimes get accidentally + // added in the editor + value.StripTrailingWhitespace(); + key.StripTrailingWhitespace(); + + mapEnt->epairs.Set( key, value ); + + if ( !idStr::Icmp( key, "origin" ) ) { + // scanf into doubles, then assign, so it is idVec size independent + v1 = v2 = v3 = 0; + sscanf( value, "%lf %lf %lf", &v1, &v2, &v3 ); + origin.x = v1; + origin.y = v2; + origin.z = v3; + } + else if ( !idStr::Icmp( key, "classname" ) && !idStr::Icmp( value, "worldspawn" ) ) { + worldent = true; + } + } + } while( 1 ); + + return mapEnt; +} + +/* +============ +idMapEntity::Write +============ +*/ +bool idMapEntity::Write( idFile *fp, int entityNum ) const { + int i; + idMapPrimitive *mapPrim; + idVec3 origin; + + fp->WriteFloatString( "// entity %d\n{\n", entityNum ); + + // write entity epairs + for ( i = 0; i < epairs.GetNumKeyVals(); i++) { + fp->WriteFloatString( "\"%s\" \"%s\"\n", epairs.GetKeyVal(i)->GetKey().c_str(), epairs.GetKeyVal(i)->GetValue().c_str()); + } + + epairs.GetVector( "origin", "0 0 0", origin ); + + // write pritimives + for ( i = 0; i < GetNumPrimitives(); i++ ) { + mapPrim = GetPrimitive( i ); + + switch( mapPrim->GetType() ) { + case idMapPrimitive::TYPE_BRUSH: + static_cast(mapPrim)->Write( fp, i, origin ); + break; + case idMapPrimitive::TYPE_PATCH: + static_cast(mapPrim)->Write( fp, i, origin ); + break; + } + } + + fp->WriteFloatString( "}\n" ); + + return true; +} + +/* +=============== +idMapEntity::RemovePrimitiveData +=============== +*/ +void idMapEntity::RemovePrimitiveData() { + primitives.DeleteContents(true); +} + +/* +=============== +idMapEntity::GetGeometryCRC +=============== +*/ +unsigned int idMapEntity::GetGeometryCRC( void ) const { + int i; + unsigned int crc; + idMapPrimitive *mapPrim; + + crc = 0; + for ( i = 0; i < GetNumPrimitives(); i++ ) { + mapPrim = GetPrimitive( i ); + + switch( mapPrim->GetType() ) { + case idMapPrimitive::TYPE_BRUSH: + crc ^= static_cast(mapPrim)->GetGeometryCRC(); + break; + case idMapPrimitive::TYPE_PATCH: + crc ^= static_cast(mapPrim)->GetGeometryCRC(); + break; + } + } + + return crc; +} + +/* +=============== +idMapFile::Parse +=============== +*/ +bool idMapFile::Parse( const char *filename, bool ignoreRegion, bool osPath ) { + // no string concatenation for epairs and allow path names for materials + idLexer src( LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + idToken token; + idStr fullName; + idMapEntity *mapEnt; + int i, j, k; + + name = filename; + name.StripFileExtension(); + fullName = name; + hasPrimitiveData = false; + + if ( !ignoreRegion ) { + // try loading a .reg file first + fullName.SetFileExtension( "reg" ); + src.LoadFile( fullName, osPath ); + } + + if ( !src.IsLoaded() ) { + // now try a .map file + fullName.SetFileExtension( "map" ); + src.LoadFile( fullName, osPath ); + if ( !src.IsLoaded() ) { + // didn't get anything at all + return false; + } + } + + version = OLD_MAP_VERSION; + fileTime = src.GetFileTime(); + entities.DeleteContents( true ); + + if ( src.CheckTokenString( "Version" ) ) { + src.ReadTokenOnLine( &token ); + version = token.GetFloatValue(); + } + + while( 1 ) { + mapEnt = idMapEntity::Parse( src, ( entities.Num() == 0 ), version ); + if ( !mapEnt ) { + break; + } + entities.Append( mapEnt ); + } + + SetGeometryCRC(); + + // if the map has a worldspawn + if ( entities.Num() ) { + + // "removeEntities" "classname" can be set in the worldspawn to remove all entities with the given classname + const idKeyValue *removeEntities = entities[0]->epairs.MatchPrefix( "removeEntities", NULL ); + while ( removeEntities ) { + RemoveEntities( removeEntities->GetValue() ); + removeEntities = entities[0]->epairs.MatchPrefix( "removeEntities", removeEntities ); + } + + // "overrideMaterial" "material" can be set in the worldspawn to reset all materials + idStr material; + if ( entities[0]->epairs.GetString( "overrideMaterial", "", material ) ) { + for ( i = 0; i < entities.Num(); i++ ) { + mapEnt = entities[i]; + for ( j = 0; j < mapEnt->GetNumPrimitives(); j++ ) { + idMapPrimitive *mapPrimitive = mapEnt->GetPrimitive( j ); + switch( mapPrimitive->GetType() ) { + case idMapPrimitive::TYPE_BRUSH: { + idMapBrush *mapBrush = static_cast(mapPrimitive); + for ( k = 0; k < mapBrush->GetNumSides(); k++ ) { + mapBrush->GetSide( k )->SetMaterial( material ); + } + break; + } + case idMapPrimitive::TYPE_PATCH: { + static_cast(mapPrimitive)->SetMaterial( material ); + break; + } + } + } + } + } + + // force all entities to have a name key/value pair + if ( entities[0]->epairs.GetBool( "forceEntityNames" ) ) { + for ( i = 1; i < entities.Num(); i++ ) { + mapEnt = entities[i]; + if ( !mapEnt->epairs.FindKey( "name" ) ) { + mapEnt->epairs.Set( "name", va( "%s%d", mapEnt->epairs.GetString( "classname", "forcedName" ), i ) ); + } + } + } + + // move the primitives of any func_group entities to the worldspawn + if ( entities[0]->epairs.GetBool( "moveFuncGroups" ) ) { + for ( i = 1; i < entities.Num(); i++ ) { + mapEnt = entities[i]; + if ( idStr::Icmp( mapEnt->epairs.GetString( "classname" ), "func_group" ) == 0 ) { + entities[0]->primitives.Append( mapEnt->primitives ); + mapEnt->primitives.Clear(); + } + } + } + } + + hasPrimitiveData = true; + return true; +} + +/* +============ +idMapFile::Write +============ +*/ +bool idMapFile::Write( const char *fileName, const char *ext, bool fromBasePath ) { + int i; + idStr qpath; + idFile *fp; + + qpath = fileName; + qpath.SetFileExtension( ext ); + + idLib::common->Printf( "writing %s...\n", qpath.c_str() ); + + if ( fromBasePath ) { + fp = idLib::fileSystem->OpenFileWrite( qpath, "fs_devpath" ); + } + else { + fp = idLib::fileSystem->OpenExplicitFileWrite( qpath ); + } + + if ( !fp ) { + idLib::common->Warning( "Couldn't open %s\n", qpath.c_str() ); + return false; + } + + fp->WriteFloatString( "Version %f\n", (float) CURRENT_MAP_VERSION ); + + for ( i = 0; i < entities.Num(); i++ ) { + entities[i]->Write( fp, i ); + } + + idLib::fileSystem->CloseFile( fp ); + + return true; +} + +/* +=============== +idMapFile::SetGeometryCRC +=============== +*/ +void idMapFile::SetGeometryCRC( void ) { + int i; + + geometryCRC = 0; + for ( i = 0; i < entities.Num(); i++ ) { + geometryCRC ^= entities[i]->GetGeometryCRC(); + } +} + +/* +=============== +idMapFile::AddEntity +=============== +*/ +int idMapFile::AddEntity( idMapEntity *mapEnt ) { + int ret = entities.Append( mapEnt ); + return ret; +} + +/* +=============== +idMapFile::FindEntity +=============== +*/ +idMapEntity *idMapFile::FindEntity( const char *name ) { + for ( int i = 0; i < entities.Num(); i++ ) { + idMapEntity *ent = entities[i]; + if ( idStr::Icmp( ent->epairs.GetString( "name" ), name ) == 0 ) { + return ent; + } + } + return NULL; +} + +/* +=============== +idMapFile::RemoveEntity +=============== +*/ +void idMapFile::RemoveEntity( idMapEntity *mapEnt ) { + entities.Remove( mapEnt ); + delete mapEnt; +} + +/* +=============== +idMapFile::RemoveEntity +=============== +*/ +void idMapFile::RemoveEntities( const char *classname ) { + for ( int i = 0; i < entities.Num(); i++ ) { + idMapEntity *ent = entities[i]; + if ( idStr::Icmp( ent->epairs.GetString( "classname" ), classname ) == 0 ) { + delete entities[i]; + entities.RemoveIndex( i ); + i--; + } + } +} + +/* +=============== +idMapFile::RemoveAllEntities +=============== +*/ +void idMapFile::RemoveAllEntities() { + entities.DeleteContents( true ); + hasPrimitiveData = false; +} + +/* +=============== +idMapFile::RemovePrimitiveData +=============== +*/ +void idMapFile::RemovePrimitiveData() { + for ( int i = 0; i < entities.Num(); i++ ) { + idMapEntity *ent = entities[i]; + ent->RemovePrimitiveData(); + } + hasPrimitiveData = false; +} + +/* +=============== +idMapFile::NeedsReload +=============== +*/ +bool idMapFile::NeedsReload() { + if ( name.Length() ) { + ID_TIME_T time = (ID_TIME_T)-1; + if ( idLib::fileSystem->ReadFile( name, NULL, &time ) > 0 ) { + return ( time > fileTime ); + } + } + return true; +} diff --git a/idlib/MapFile.h b/idlib/MapFile.h new file mode 100644 index 000000000..6d3e210b9 --- /dev/null +++ b/idlib/MapFile.h @@ -0,0 +1,228 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MAPFILE_H__ +#define __MAPFILE_H__ + +/* +=============================================================================== + + Reads or writes the contents of .map files into a standard internal + format, which can then be moved into private formats for collision + detection, map processing, or editor use. + + No validation (duplicate planes, null area brushes, etc) is performed. + There are no limits to the number of any of the elements in maps. + The order of entities, brushes, and sides is maintained. + +=============================================================================== +*/ + +const int OLD_MAP_VERSION = 1; +const int CURRENT_MAP_VERSION = 2; +const int DEFAULT_CURVE_SUBDIVISION = 4; +const float DEFAULT_CURVE_MAX_ERROR = 4.0f; +const float DEFAULT_CURVE_MAX_ERROR_CD = 24.0f; +const float DEFAULT_CURVE_MAX_LENGTH = -1.0f; +const float DEFAULT_CURVE_MAX_LENGTH_CD = -1.0f; + + +class idMapPrimitive { +public: + enum { TYPE_INVALID = -1, TYPE_BRUSH, TYPE_PATCH }; + + idDict epairs; + + idMapPrimitive( void ) { type = TYPE_INVALID; } + virtual ~idMapPrimitive( void ) { } + int GetType( void ) const { return type; } + +protected: + int type; +}; + + +class idMapBrushSide { + friend class idMapBrush; + +public: + idMapBrushSide( void ); + ~idMapBrushSide( void ) { } + const char * GetMaterial( void ) const { return material; } + void SetMaterial( const char *p ) { material = p; } + const idPlane & GetPlane( void ) const { return plane; } + void SetPlane( const idPlane &p ) { plane = p; } + void SetTextureMatrix( const idVec3 mat[2] ) { texMat[0] = mat[0]; texMat[1] = mat[1]; } + void GetTextureMatrix( idVec3 &mat1, idVec3 &mat2 ) { mat1 = texMat[0]; mat2 = texMat[1]; } + void GetTextureVectors( idVec4 v[2] ) const; + +protected: + idStr material; + idPlane plane; + idVec3 texMat[2]; + idVec3 origin; +}; + +ID_INLINE idMapBrushSide::idMapBrushSide( void ) { + plane.Zero(); + texMat[0].Zero(); + texMat[1].Zero(); + origin.Zero(); +} + + +class idMapBrush : public idMapPrimitive { +public: + idMapBrush( void ) { type = TYPE_BRUSH; sides.Resize( 8, 4 ); } + ~idMapBrush( void ) { sides.DeleteContents( true ); } + static idMapBrush * Parse( idLexer &src, const idVec3 &origin, bool newFormat = true, float version = CURRENT_MAP_VERSION ); + static idMapBrush * ParseQ3( idLexer &src, const idVec3 &origin ); + bool Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const; + int GetNumSides( void ) const { return sides.Num(); } + int AddSide( idMapBrushSide *side ) { return sides.Append( side ); } + idMapBrushSide * GetSide( int i ) const { return sides[i]; } + unsigned int GetGeometryCRC( void ) const; + +protected: + int numSides; + idList sides; +}; + + +class idMapPatch : public idMapPrimitive, public idSurface_Patch { +public: + idMapPatch( void ); + idMapPatch( int maxPatchWidth, int maxPatchHeight ); + ~idMapPatch( void ) { } + static idMapPatch * Parse( idLexer &src, const idVec3 &origin, bool patchDef3 = true, float version = CURRENT_MAP_VERSION ); + bool Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const; + const char * GetMaterial( void ) const { return material; } + void SetMaterial( const char *p ) { material = p; } + int GetHorzSubdivisions( void ) const { return horzSubdivisions; } + int GetVertSubdivisions( void ) const { return vertSubdivisions; } + bool GetExplicitlySubdivided( void ) const { return explicitSubdivisions; } + void SetHorzSubdivisions( int n ) { horzSubdivisions = n; } + void SetVertSubdivisions( int n ) { vertSubdivisions = n; } + void SetExplicitlySubdivided( bool b ) { explicitSubdivisions = b; } + unsigned int GetGeometryCRC( void ) const; + +protected: + idStr material; + int horzSubdivisions; + int vertSubdivisions; + bool explicitSubdivisions; +}; + +ID_INLINE idMapPatch::idMapPatch( void ) { + type = TYPE_PATCH; + horzSubdivisions = vertSubdivisions = 0; + explicitSubdivisions = false; + width = height = 0; + maxWidth = maxHeight = 0; + expanded = false; +} + +ID_INLINE idMapPatch::idMapPatch( int maxPatchWidth, int maxPatchHeight ) { + type = TYPE_PATCH; + horzSubdivisions = vertSubdivisions = 0; + explicitSubdivisions = false; + width = height = 0; + maxWidth = maxPatchWidth; + maxHeight = maxPatchHeight; + verts.SetNum( maxWidth * maxHeight ); + expanded = false; +} + + +class idMapEntity { + friend class idMapFile; + +public: + idDict epairs; + +public: + idMapEntity( void ) { epairs.SetHashSize( 64 ); } + ~idMapEntity( void ) { primitives.DeleteContents( true ); } + static idMapEntity * Parse( idLexer &src, bool worldSpawn = false, float version = CURRENT_MAP_VERSION ); + bool Write( idFile *fp, int entityNum ) const; + int GetNumPrimitives( void ) const { return primitives.Num(); } + idMapPrimitive * GetPrimitive( int i ) const { return primitives[i]; } + void AddPrimitive( idMapPrimitive *p ) { primitives.Append( p ); } + unsigned int GetGeometryCRC( void ) const; + void RemovePrimitiveData(); + +protected: + idList primitives; +}; + + +class idMapFile { +public: + idMapFile( void ); + ~idMapFile( void ) { entities.DeleteContents( true ); } + + // filename does not require an extension + // normally this will use a .reg file instead of a .map file if it exists, + // which is what the game and dmap want, but the editor will want to always + // load a .map file + bool Parse( const char *filename, bool ignoreRegion = false, bool osPath = false ); + bool Write( const char *fileName, const char *ext, bool fromBasePath = true ); + // get the number of entities in the map + int GetNumEntities( void ) const { return entities.Num(); } + // get the specified entity + idMapEntity * GetEntity( int i ) const { return entities[i]; } + // get the name without file extension + const char * GetName( void ) const { return name; } + // get the file time + ID_TIME_T GetFileTime( void ) const { return fileTime; } + // get CRC for the map geometry + // texture coordinates and entity key/value pairs are not taken into account + unsigned int GetGeometryCRC( void ) const { return geometryCRC; } + // returns true if the file on disk changed + bool NeedsReload(); + + int AddEntity( idMapEntity *mapentity ); + idMapEntity * FindEntity( const char *name ); + void RemoveEntity( idMapEntity *mapEnt ); + void RemoveEntities( const char *classname ); + void RemoveAllEntities(); + void RemovePrimitiveData(); + bool HasPrimitiveData() { return hasPrimitiveData; } + +protected: + float version; + ID_TIME_T fileTime; + unsigned int geometryCRC; + idList entities; + idStr name; + bool hasPrimitiveData; + +private: + void SetGeometryCRC( void ); +}; + +ID_INLINE idMapFile::idMapFile( void ) { + version = CURRENT_MAP_VERSION; + fileTime = 0; + geometryCRC = 0; + entities.Resize( 1024, 256 ); + hasPrimitiveData = false; +} + +#endif /* !__MAPFILE_H__ */ diff --git a/idlib/Parser.cpp b/idlib/Parser.cpp new file mode 100644 index 000000000..4c81721a5 --- /dev/null +++ b/idlib/Parser.cpp @@ -0,0 +1,3243 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + +//#define DEBUG_EVAL +#define MAX_DEFINEPARMS 128 +#define DEFINEHASHSIZE 2048 + +#define TOKEN_FL_RECURSIVE_DEFINE 1 + +define_t * idParser::globaldefines; + +/* +================ +idParser::SetBaseFolder +================ +*/ +void idParser::SetBaseFolder( const char *path) { + idLexer::SetBaseFolder(path); +} + +/* +================ +idParser::AddGlobalDefine +================ +*/ +int idParser::AddGlobalDefine( const char *string ) { + define_t *define; + + define = idParser::DefineFromString(string); + if (!define) { + return false; + } + define->next = globaldefines; + globaldefines = define; + return true; +} + +/* +================ +idParser::RemoveGlobalDefine +================ +*/ +int idParser::RemoveGlobalDefine( const char *name ) { + define_t *d, *prev; + + for ( prev = NULL, d = idParser::globaldefines; d; prev = d, d = d->next ) { + if ( !strcmp( d->name, name ) ) { + break; + } + } + if ( d ) { + if ( prev ) { + prev->next = d->next; + } + else { + idParser::globaldefines = d->next; + } + idParser::FreeDefine( d ); + return true; + } + return false; +} + +/* +================ +idParser::RemoveAllGlobalDefines +================ +*/ +void idParser::RemoveAllGlobalDefines( void ) { + define_t *define; + + for ( define = globaldefines; define; define = globaldefines ) { + globaldefines = globaldefines->next; + idParser::FreeDefine(define); + } +} + + +/* +=============================================================================== + +idParser + +=============================================================================== +*/ + +/* +================ +idParser::PrintDefine +================ +*/ +void idParser::PrintDefine( define_t *define ) { + idLib::common->Printf("define->name = %s\n", define->name); + idLib::common->Printf("define->flags = %d\n", define->flags); + idLib::common->Printf("define->builtin = %d\n", define->builtin); + idLib::common->Printf("define->numparms = %d\n", define->numparms); +} + +/* +================ +PC_PrintDefineHashTable +================ +* / +static void PC_PrintDefineHashTable(define_t **definehash) { + int i; + define_t *d; + + for (i = 0; i < DEFINEHASHSIZE; i++) { + Log_Write("%4d:", i); + for (d = definehash[i]; d; d = d->hashnext) { + Log_Write(" %s", d->name); + } + Log_Write("\n"); + } +} +*/ + +/* +================ +PC_NameHash +================ +*/ +ID_INLINE int PC_NameHash( const char *name ) { + int hash, i; + + hash = 0; + for ( i = 0; name[i] != '\0'; i++ ) { + hash += name[i] * (119 + i); + } + hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (DEFINEHASHSIZE-1); + return hash; +} + +/* +================ +idParser::AddDefineToHash +================ +*/ +void idParser::AddDefineToHash( define_t *define, define_t **definehash ) { + int hash; + + hash = PC_NameHash(define->name); + define->hashnext = definehash[hash]; + definehash[hash] = define; +} + +/* +================ +FindHashedDefine +================ +*/ +define_t *idParser::FindHashedDefine( define_t **definehash, const char *name ) { + define_t *d; + int hash; + + hash = PC_NameHash(name); + for ( d = definehash[hash]; d; d = d->hashnext ) { + if ( !strcmp(d->name, name) ) { + return d; + } + } + return NULL; +} + +/* +================ +idParser::FindDefine +================ +*/ +define_t *idParser::FindDefine( define_t *defines, const char *name ) { + define_t *d; + + for ( d = defines; d; d = d->next ) { + if ( !strcmp(d->name, name) ) { + return d; + } + } + return NULL; +} + +/* +================ +idParser::FindDefineParm +================ +*/ +int idParser::FindDefineParm( define_t *define, const char *name ) { + idToken *p; + int i; + + i = 0; + for ( p = define->parms; p; p = p->next ) { + if ( (*p) == name ) { + return i; + } + i++; + } + return -1; +} + +/* +================ +idParser::CopyDefine +================ +*/ +define_t *idParser::CopyDefine( define_t *define ) { + define_t *newdefine; + idToken *token, *newtoken, *lasttoken; + + newdefine = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(define->name) + 1); + //copy the define name + newdefine->name = (char *) newdefine + sizeof(define_t); + strcpy(newdefine->name, define->name); + newdefine->flags = define->flags; + newdefine->builtin = define->builtin; + newdefine->numparms = define->numparms; + //the define is not linked + newdefine->next = NULL; + newdefine->hashnext = NULL; + //copy the define tokens + newdefine->tokens = NULL; + for (lasttoken = NULL, token = define->tokens; token; token = token->next) { + newtoken = new idToken(token); + newtoken->next = NULL; + if (lasttoken) lasttoken->next = newtoken; + else newdefine->tokens = newtoken; + lasttoken = newtoken; + } + //copy the define parameters + newdefine->parms = NULL; + for (lasttoken = NULL, token = define->parms; token; token = token->next) { + newtoken = new idToken(token); + newtoken->next = NULL; + if (lasttoken) lasttoken->next = newtoken; + else newdefine->parms = newtoken; + lasttoken = newtoken; + } + return newdefine; +} + +/* +================ +idParser::FreeDefine +================ +*/ +void idParser::FreeDefine( define_t *define ) { + idToken *t, *next; + + //free the define parameters + for (t = define->parms; t; t = next) { + next = t->next; + delete t; + } + //free the define tokens + for (t = define->tokens; t; t = next) { + next = t->next; + delete t; + } + //free the define + Mem_Free( define ); +} + +/* +================ +idParser::DefineFromString +================ +*/ +define_t *idParser::DefineFromString( const char *string ) { + idParser src; + define_t *def; + + if ( !src.LoadMemory(string, strlen(string), "*defineString") ) { + return NULL; + } + // create a define from the source + if ( !src.Directive_define() ) { + src.FreeSource(); + return NULL; + } + def = src.CopyFirstDefine(); + src.FreeSource(); + //if the define was created succesfully + return def; +} + +/* +================ +idParser::Error +================ +*/ +void idParser::Error( const char *str, ... ) const { + char text[MAX_STRING_CHARS]; + va_list ap; + + va_start(ap, str); + vsprintf(text, str, ap); + va_end(ap); + if ( idParser::scriptstack ) { + idParser::scriptstack->Error( text ); + } +} + +/* +================ +idParser::Warning +================ +*/ +void idParser::Warning( const char *str, ... ) const { + char text[MAX_STRING_CHARS]; + va_list ap; + + va_start(ap, str); + vsprintf(text, str, ap); + va_end(ap); + if ( idParser::scriptstack ) { + idParser::scriptstack->Warning( text ); + } +} + +/* +================ +idParser::PushIndent +================ +*/ +void idParser::PushIndent( int type, int skip ) { + indent_t *indent; + + indent = (indent_t *) Mem_Alloc(sizeof(indent_t)); + indent->type = type; + indent->script = idParser::scriptstack; + indent->skip = (skip != 0); + idParser::skip += indent->skip; + indent->next = idParser::indentstack; + idParser::indentstack = indent; +} + +/* +================ +idParser::PopIndent +================ +*/ +void idParser::PopIndent( int *type, int *skip ) { + indent_t *indent; + + *type = 0; + *skip = 0; + + indent = idParser::indentstack; + if (!indent) return; + + // must be an indent from the current script + if (idParser::indentstack->script != idParser::scriptstack) { + return; + } + + *type = indent->type; + *skip = indent->skip; + idParser::indentstack = idParser::indentstack->next; + idParser::skip -= indent->skip; + Mem_Free( indent ); +} + +/* +================ +idParser::PushScript +================ +*/ +void idParser::PushScript( idLexer *script ) { + idLexer *s; + + for ( s = idParser::scriptstack; s; s = s->next ) { + if ( !idStr::Icmp(s->GetFileName(), script->GetFileName()) ) { + idParser::Warning( "'%s' recursively included", script->GetFileName() ); + return; + } + } + //push the script on the script stack + script->next = idParser::scriptstack; + idParser::scriptstack = script; +} + +/* +================ +idParser::ReadSourceToken +================ +*/ +int idParser::ReadSourceToken( idToken *token ) { + idToken *t; + idLexer *script; + int type, skip, changedScript; + + if ( !idParser::scriptstack ) { + idLib::common->FatalError( "idParser::ReadSourceToken: not loaded" ); + return false; + } + changedScript = 0; + // if there's no token already available + while( !idParser::tokens ) { + // if there's a token to read from the script + if ( idParser::scriptstack->ReadToken( token ) ) { + token->linesCrossed += changedScript; + + // set the marker based on the start of the token read in + if ( !marker_p ) { + marker_p = token->whiteSpaceEnd_p; + } + return true; + } + // if at the end of the script + if ( idParser::scriptstack->EndOfFile() ) { + // remove all indents of the script + while( idParser::indentstack && idParser::indentstack->script == idParser::scriptstack ) { + idParser::Warning( "missing #endif" ); + idParser::PopIndent( &type, &skip ); + } + changedScript = 1; + } + // if this was the initial script + if ( !idParser::scriptstack->next ) { + return false; + } + // remove the script and return to the previous one + script = idParser::scriptstack; + idParser::scriptstack = idParser::scriptstack->next; + delete script; + } + // copy the already available token + *token = idParser::tokens; + // remove the token from the source + t = idParser::tokens; + idParser::tokens = idParser::tokens->next; + delete t; + return true; +} + +/* +================ +idParser::UnreadSourceToken +================ +*/ +int idParser::UnreadSourceToken( idToken *token ) { + idToken *t; + + t = new idToken(token); + t->next = idParser::tokens; + idParser::tokens = t; + return true; +} + +/* +================ +idParser::ReadDefineParms +================ +*/ +int idParser::ReadDefineParms( define_t *define, idToken **parms, int maxparms ) { + define_t *newdefine; + idToken token, *t, *last; + int i, done, lastcomma, numparms, indent; + + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "define '%s' missing parameters", define->name ); + return false; + } + + if ( define->numparms > maxparms ) { + idParser::Error( "define with more than %d parameters", maxparms ); + return false; + } + + for ( i = 0; i < define->numparms; i++ ) { + parms[i] = NULL; + } + // if no leading "(" + if ( token != "(" ) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "define '%s' missing parameters", define->name ); + return false; + } + // read the define parameters + for ( done = 0, numparms = 0, indent = 1; !done; ) { + if ( numparms >= maxparms ) { + idParser::Error( "define '%s' with too many parameters", define->name ); + return false; + } + parms[numparms] = NULL; + lastcomma = 1; + last = NULL; + while( !done ) { + + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "define '%s' incomplete", define->name ); + return false; + } + + if ( token == "," ) { + if ( indent <= 1 ) { + if ( lastcomma ) { + idParser::Warning( "too many comma's" ); + } + if ( numparms >= define->numparms ) { + idParser::Warning( "too many define parameters" ); + } + lastcomma = 1; + break; + } + } + else if ( token == "(" ) { + indent++; + } + else if ( token == ")" ) { + indent--; + if ( indent <= 0 ) { + if ( !parms[define->numparms-1] ) { + idParser::Warning( "too few define parameters" ); + } + done = 1; + break; + } + } + else if ( token.type == TT_NAME ) { + newdefine = FindHashedDefine( idParser::definehash, token.c_str() ); + if ( newdefine ) { + if ( !idParser::ExpandDefineIntoSource( &token, newdefine ) ) { + return false; + } + continue; + } + } + + lastcomma = 0; + + if ( numparms < define->numparms ) { + + t = new idToken( token ); + t->next = NULL; + if (last) last->next = t; + else parms[numparms] = t; + last = t; + } + } + numparms++; + } + return true; +} + +/* +================ +idParser::StringizeTokens +================ +*/ +int idParser::StringizeTokens( idToken *tokens, idToken *token ) { + idToken *t; + + token->type = TT_STRING; + token->whiteSpaceStart_p = NULL; + token->whiteSpaceEnd_p = NULL; + (*token) = ""; + for ( t = tokens; t; t = t->next ) { + token->Append( t->c_str() ); + } + return true; +} + +/* +================ +idParser::MergeTokens +================ +*/ +int idParser::MergeTokens( idToken *t1, idToken *t2 ) { + // merging of a name with a name or number + if ( t1->type == TT_NAME && (t2->type == TT_NAME || (t2->type == TT_NUMBER && !(t2->subtype & TT_FLOAT))) ) { + t1->Append( t2->c_str() ); + return true; + } + // merging of two strings + if (t1->type == TT_STRING && t2->type == TT_STRING) { + t1->Append( t2->c_str() ); + return true; + } + // merging of two numbers + if ( t1->type == TT_NUMBER && t2->type == TT_NUMBER && + !(t1->subtype & (TT_HEX|TT_BINARY)) && !(t2->subtype & (TT_HEX|TT_BINARY)) && + (!(t1->subtype & TT_FLOAT) || !(t2->subtype & TT_FLOAT)) ) { + t1->Append( t2->c_str() ); + return true; + } + + return false; +} + +/* +================ +idParser::AddBuiltinDefines +================ +*/ +void idParser::AddBuiltinDefines( void ) { + int i; + define_t *define; + struct builtin + { + const char *string; + int id; + } builtin[] = { + { "__LINE__", BUILTIN_LINE }, + { "__FILE__", BUILTIN_FILE }, + { "__DATE__", BUILTIN_DATE }, + { "__TIME__", BUILTIN_TIME }, + { "__STDC__", BUILTIN_STDC }, + { NULL, 0 } + }; + + for (i = 0; builtin[i].string; i++) { + define = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(builtin[i].string) + 1); + define->name = (char *) define + sizeof(define_t); + strcpy(define->name, builtin[i].string); + define->flags = DEFINE_FIXED; + define->builtin = builtin[i].id; + define->numparms = 0; + define->parms = NULL; + define->tokens = NULL; + // add the define to the source + AddDefineToHash(define, idParser::definehash); + } +} + +/* +================ +idParser::CopyFirstDefine +================ +*/ +define_t *idParser::CopyFirstDefine( void ) { + int i; + + for ( i = 0; i < DEFINEHASHSIZE; i++ ) { + if ( idParser::definehash[i] ) { + return CopyDefine(idParser::definehash[i]); + } + } + return NULL; +} + +/* +================ +idParser::ExpandBuiltinDefine +================ +*/ +int idParser::ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) { + idToken *token; + ID_TIME_T t; + char *curtime; + char buf[MAX_STRING_CHARS]; + + token = new idToken(deftoken); + switch( define->builtin ) { + case BUILTIN_LINE: { + sprintf( buf, "%d", deftoken->line ); + (*token) = buf; + token->intvalue = deftoken->line; + token->floatvalue = deftoken->line; + token->type = TT_NUMBER; + token->subtype = TT_DECIMAL | TT_INTEGER | TT_VALUESVALID; + token->line = deftoken->line; + token->linesCrossed = deftoken->linesCrossed; + token->flags = 0; + *firsttoken = token; + *lasttoken = token; + break; + } + case BUILTIN_FILE: { + (*token) = idParser::scriptstack->GetFileName(); + token->type = TT_NAME; + token->subtype = token->Length(); + token->line = deftoken->line; + token->linesCrossed = deftoken->linesCrossed; + token->flags = 0; + *firsttoken = token; + *lasttoken = token; + break; + } + case BUILTIN_DATE: { + t = time(NULL); + curtime = ctime(&t); + (*token) = "\""; + token->Append( curtime+4 ); + token[7] = '\0'; + token->Append( curtime+20 ); + token[10] = '\0'; + token->Append( "\"" ); + free(curtime); + token->type = TT_STRING; + token->subtype = token->Length(); + token->line = deftoken->line; + token->linesCrossed = deftoken->linesCrossed; + token->flags = 0; + *firsttoken = token; + *lasttoken = token; + break; + } + case BUILTIN_TIME: { + t = time(NULL); + curtime = ctime(&t); + (*token) = "\""; + token->Append( curtime+11 ); + token[8] = '\0'; + token->Append( "\"" ); + free(curtime); + token->type = TT_STRING; + token->subtype = token->Length(); + token->line = deftoken->line; + token->linesCrossed = deftoken->linesCrossed; + token->flags = 0; + *firsttoken = token; + *lasttoken = token; + break; + } + case BUILTIN_STDC: { + idParser::Warning( "__STDC__ not supported\n" ); + *firsttoken = NULL; + *lasttoken = NULL; + break; + } + default: { + *firsttoken = NULL; + *lasttoken = NULL; + break; + } + } + return true; +} + +/* +================ +idParser::ExpandDefine +================ +*/ +int idParser::ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) { + idToken *parms[MAX_DEFINEPARMS], *dt, *pt, *t; + idToken *t1, *t2, *first, *last, *nextpt, token; + int parmnum, i; + + // if it is a builtin define + if ( define->builtin ) { + return idParser::ExpandBuiltinDefine( deftoken, define, firsttoken, lasttoken ); + } + // if the define has parameters + if ( define->numparms ) { + if ( !idParser::ReadDefineParms( define, parms, MAX_DEFINEPARMS ) ) { + return false; + } +#ifdef DEBUG_EVAL + for ( i = 0; i < define->numparms; i++ ) { + Log_Write("define parms %d:", i); + for ( pt = parms[i]; pt; pt = pt->next ) { + Log_Write( "%s", pt->c_str() ); + } + } +#endif //DEBUG_EVAL + } + // empty list at first + first = NULL; + last = NULL; + // create a list with tokens of the expanded define + for ( dt = define->tokens; dt; dt = dt->next ) { + parmnum = -1; + // if the token is a name, it could be a define parameter + if ( dt->type == TT_NAME ) { + parmnum = FindDefineParm( define, dt->c_str() ); + } + // if it is a define parameter + if ( parmnum >= 0 ) { + for ( pt = parms[parmnum]; pt; pt = pt->next ) { + t = new idToken(pt); + //add the token to the list + t->next = NULL; + if (last) last->next = t; + else first = t; + last = t; + } + } + else { + // if stringizing operator + if ( (*dt) == "#" ) { + // the stringizing operator must be followed by a define parameter + if ( dt->next ) { + parmnum = FindDefineParm( define, dt->next->c_str() ); + } + else { + parmnum = -1; + } + + if ( parmnum >= 0 ) { + // step over the stringizing operator + dt = dt->next; + // stringize the define parameter tokens + if ( !idParser::StringizeTokens( parms[parmnum], &token ) ) { + idParser::Error( "can't stringize tokens" ); + return false; + } + t = new idToken(token); + t->line = deftoken->line; + } + else { + idParser::Warning( "stringizing operator without define parameter" ); + continue; + } + } + else { + t = new idToken(dt); + t->line = deftoken->line; + } + // add the token to the list + t->next = NULL; +// the token being read from the define list should use the line number of +// the original file, not the header file + t->line = deftoken->line; + + if ( last ) last->next = t; + else first = t; + last = t; + } + } + // check for the merging operator + for ( t = first; t; ) { + if ( t->next ) { + // if the merging operator + if ( (*t->next) == "##" ) { + t1 = t; + t2 = t->next->next; + if ( t2 ) { + if ( !idParser::MergeTokens( t1, t2 ) ) { + idParser::Error( "can't merge '%s' with '%s'", t1->c_str(), t2->c_str() ); + return false; + } + delete t1->next; + t1->next = t2->next; + if ( t2 == last ) last = t1; + delete t2; + continue; + } + } + } + t = t->next; + } + // store the first and last token of the list + *firsttoken = first; + *lasttoken = last; + // free all the parameter tokens + for ( i = 0; i < define->numparms; i++ ) { + for ( pt = parms[i]; pt; pt = nextpt ) { + nextpt = pt->next; + delete pt; + } + } + + return true; +} + +/* +================ +idParser::ExpandDefineIntoSource +================ +*/ +int idParser::ExpandDefineIntoSource( idToken *deftoken, define_t *define ) { + idToken *firsttoken, *lasttoken; + + if ( !idParser::ExpandDefine( deftoken, define, &firsttoken, &lasttoken ) ) { + return false; + } + // if the define is not empty + if ( firsttoken && lasttoken ) { + firsttoken->linesCrossed += deftoken->linesCrossed; + lasttoken->next = idParser::tokens; + idParser::tokens = firsttoken; + } + return true; +} + +/* +================ +idParser::ReadLine + +reads a token from the current line, continues reading on the next +line only if a backslash '\' is found +================ +*/ +int idParser::ReadLine( idToken *token ) { + int crossline; + + crossline = 0; + do { + if (!idParser::ReadSourceToken( token )) { + return false; + } + + if (token->linesCrossed > crossline) { + idParser::UnreadSourceToken( token ); + return false; + } + crossline = 1; + } while( (*token) == "\\" ); + return true; +} + +/* +================ +idParser::Directive_include +================ +*/ +int idParser::Directive_include( void ) { + idLexer *script; + idToken token; + idStr path; + + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "#include without file name" ); + return false; + } + if ( token.linesCrossed > 0 ) { + idParser::Error( "#include without file name" ); + return false; + } + if ( token.type == TT_STRING ) { + script = new idLexer; + // try relative to the current file + path = scriptstack->GetFileName(); + path.StripFilename(); + path += "/"; + path += token; + if ( !script->LoadFile( path, OSPath ) ) { + // try absolute path + path = token; + if ( !script->LoadFile( path, OSPath ) ) { + // try from the include path + path = includepath + token; + if ( !script->LoadFile( path, OSPath ) ) { + delete script; + script = NULL; + } + } + } + } + else if ( token.type == TT_PUNCTUATION && token == "<" ) { + path = idParser::includepath; + while( idParser::ReadSourceToken( &token ) ) { + if ( token.linesCrossed > 0 ) { + idParser::UnreadSourceToken( &token ); + break; + } + if ( token.type == TT_PUNCTUATION && token == ">" ) { + break; + } + path += token; + } + if ( token != ">" ) { + idParser::Warning( "#include missing trailing >" ); + } + if ( !path.Length() ) { + idParser::Error( "#include without file name between < >" ); + return false; + } + if ( idParser::flags & LEXFL_NOBASEINCLUDES ) { + return true; + } + script = new idLexer; + if ( !script->LoadFile( includepath + path, OSPath ) ) { + delete script; + script = NULL; + } + } + else { + idParser::Error( "#include without file name" ); + return false; + } + if (!script) { + idParser::Error( "file '%s' not found", path.c_str() ); + return false; + } + script->SetFlags( idParser::flags ); + script->SetPunctuations( idParser::punctuations ); + idParser::PushScript( script ); + return true; +} + +/* +================ +idParser::Directive_undef +================ +*/ +int idParser::Directive_undef( void ) { + idToken token; + define_t *define, *lastdefine; + int hash; + + // + if (!idParser::ReadLine( &token )) { + idParser::Error( "undef without name" ); + return false; + } + if (token.type != TT_NAME) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "expected name but found '%s'", token.c_str() ); + return false; + } + + hash = PC_NameHash( token.c_str() ); + for (lastdefine = NULL, define = idParser::definehash[hash]; define; define = define->hashnext) { + if (!strcmp(define->name, token.c_str())) + { + if (define->flags & DEFINE_FIXED) { + idParser::Warning( "can't undef '%s'", token.c_str() ); + } + else { + if (lastdefine) { + lastdefine->hashnext = define->hashnext; + } + else { + idParser::definehash[hash] = define->hashnext; + } + FreeDefine(define); + } + break; + } + lastdefine = define; + } + return true; +} + +/* +================ +idParser::Directive_define +================ +*/ +int idParser::Directive_define( void ) { + idToken token, *t, *last; + define_t *define; + + if (!idParser::ReadLine( &token )) { + idParser::Error( "#define without name" ); + return false; + } + if (token.type != TT_NAME) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "expected name after #define, found '%s'", token.c_str() ); + return false; + } + // check if the define already exists + define = FindHashedDefine(idParser::definehash, token.c_str()); + if (define) { + if (define->flags & DEFINE_FIXED) { + idParser::Error( "can't redefine '%s'", token.c_str() ); + return false; + } + idParser::Warning( "redefinition of '%s'", token.c_str() ); + // unread the define name before executing the #undef directive + idParser::UnreadSourceToken( &token ); + if (!idParser::Directive_undef()) + return false; + // if the define was not removed (define->flags & DEFINE_FIXED) + define = FindHashedDefine(idParser::definehash, token.c_str()); + } + // allocate define + define = (define_t *) Mem_ClearedAlloc(sizeof(define_t) + token.Length() + 1); + define->name = (char *) define + sizeof(define_t); + strcpy(define->name, token.c_str()); + // add the define to the source + AddDefineToHash(define, idParser::definehash); + // if nothing is defined, just return + if ( !idParser::ReadLine( &token ) ) { + return true; + } + // if it is a define with parameters + if ( token.WhiteSpaceBeforeToken() == 0 && token == "(" ) { + // read the define parameters + last = NULL; + if ( !idParser::CheckTokenString(")") ) { + while(1) { + if ( !idParser::ReadLine( &token ) ) { + idParser::Error( "expected define parameter" ); + return false; + } + // if it isn't a name + if (token.type != TT_NAME) { + idParser::Error( "invalid define parameter" ); + return false; + } + + if (FindDefineParm(define, token.c_str()) >= 0) { + idParser::Error( "two the same define parameters" ); + return false; + } + // add the define parm + t = new idToken(token); + t->ClearTokenWhiteSpace(); + t->next = NULL; + if (last) last->next = t; + else define->parms = t; + last = t; + define->numparms++; + // read next token + if (!idParser::ReadLine( &token )) { + idParser::Error( "define parameters not terminated" ); + return false; + } + + if ( token == ")" ) { + break; + } + // then it must be a comma + if ( token != "," ) { + idParser::Error( "define not terminated" ); + return false; + } + } + } + if ( !idParser::ReadLine( &token ) ) { + return true; + } + } + // read the defined stuff + last = NULL; + do + { + t = new idToken(token); + if ( t->type == TT_NAME && !strcmp( t->c_str(), define->name ) ) { + t->flags |= TOKEN_FL_RECURSIVE_DEFINE; + idParser::Warning( "recursive define (removed recursion)" ); + } + t->ClearTokenWhiteSpace(); + t->next = NULL; + if ( last ) last->next = t; + else define->tokens = t; + last = t; + } while( idParser::ReadLine( &token ) ); + + if ( last ) { + // check for merge operators at the beginning or end + if ( (*define->tokens) == "##" || (*last) == "##" ) { + idParser::Error( "define with misplaced ##" ); + return false; + } + } + return true; +} + +/* +================ +idParser::AddDefine +================ +*/ +int idParser::AddDefine( const char *string ) { + define_t *define; + + define = DefineFromString( string ); + if (!define) { + return false; + } + AddDefineToHash(define, idParser::definehash); + return true; +} + +/* +================ +idParser::AddGlobalDefinesToSource +================ +*/ +void idParser::AddGlobalDefinesToSource( void ) { + define_t *define, *newdefine; + + for (define = globaldefines; define; define = define->next) { + newdefine = CopyDefine( define ); + AddDefineToHash(newdefine, idParser::definehash); + } +} + +/* +================ +idParser::Directive_if_def +================ +*/ +int idParser::Directive_if_def( int type ) { + idToken token; + define_t *d; + int skip; + + if ( !idParser::ReadLine( &token ) ) { + idParser::Error( "#ifdef without name" ); + return false; + } + if (token.type != TT_NAME) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "expected name after #ifdef, found '%s'", token.c_str() ); + return false; + } + d = FindHashedDefine(idParser::definehash, token.c_str()); + skip = (type == INDENT_IFDEF) == (d == NULL); + idParser::PushIndent( type, skip ); + return true; +} + +/* +================ +idParser::Directive_ifdef +================ +*/ +int idParser::Directive_ifdef( void ) { + return idParser::Directive_if_def( INDENT_IFDEF ); +} + +/* +================ +idParser::Directive_ifndef +================ +*/ +int idParser::Directive_ifndef( void ) { + return idParser::Directive_if_def( INDENT_IFNDEF ); +} + +/* +================ +idParser::Directive_else +================ +*/ +int idParser::Directive_else( void ) { + int type, skip; + + idParser::PopIndent( &type, &skip ); + if (!type) { + idParser::Error( "misplaced #else" ); + return false; + } + if (type == INDENT_ELSE) { + idParser::Error( "#else after #else" ); + return false; + } + idParser::PushIndent( INDENT_ELSE, !skip ); + return true; +} + +/* +================ +idParser::Directive_endif +================ +*/ +int idParser::Directive_endif( void ) { + int type, skip; + + idParser::PopIndent( &type, &skip ); + if (!type) { + idParser::Error( "misplaced #endif" ); + return false; + } + return true; +} + +/* +================ +idParser::EvaluateTokens +================ +*/ +typedef struct operator_s +{ + int op; + int priority; + int parentheses; + struct operator_s *prev, *next; +} operator_t; + +typedef struct value_s +{ + signed long int intvalue; + double floatvalue; + int parentheses; + struct value_s *prev, *next; +} value_t; + +int PC_OperatorPriority(int op) { + switch(op) { + case P_MUL: return 15; + case P_DIV: return 15; + case P_MOD: return 15; + case P_ADD: return 14; + case P_SUB: return 14; + + case P_LOGIC_AND: return 7; + case P_LOGIC_OR: return 6; + case P_LOGIC_GEQ: return 12; + case P_LOGIC_LEQ: return 12; + case P_LOGIC_EQ: return 11; + case P_LOGIC_UNEQ: return 11; + + case P_LOGIC_NOT: return 16; + case P_LOGIC_GREATER: return 12; + case P_LOGIC_LESS: return 12; + + case P_RSHIFT: return 13; + case P_LSHIFT: return 13; + + case P_BIN_AND: return 10; + case P_BIN_OR: return 8; + case P_BIN_XOR: return 9; + case P_BIN_NOT: return 16; + + case P_COLON: return 5; + case P_QUESTIONMARK: return 5; + } + return false; +} + +//#define AllocValue() GetClearedMemory(sizeof(value_t)); +//#define FreeValue(val) FreeMemory(val) +//#define AllocOperator(op) op = (operator_t *) GetClearedMemory(sizeof(operator_t)); +//#define FreeOperator(op) FreeMemory(op); + +#define MAX_VALUES 64 +#define MAX_OPERATORS 64 + +#define AllocValue(val) \ + if ( numvalues >= MAX_VALUES ) { \ + idParser::Error( "out of value space\n" ); \ + error = 1; \ + break; \ + } \ + else { \ + val = &value_heap[numvalues++]; \ + } + +#define FreeValue(val) + +#define AllocOperator(op) \ + if ( numoperators >= MAX_OPERATORS ) { \ + idParser::Error( "out of operator space\n" ); \ + error = 1; \ + break; \ + } \ + else { \ + op = &operator_heap[numoperators++]; \ + } + +#define FreeOperator(op) + +int idParser::EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ) { + operator_t *o, *firstoperator, *lastoperator; + value_t *v, *firstvalue, *lastvalue, *v1, *v2; + idToken *t; + int brace = 0; + int parentheses = 0; + int error = 0; + int lastwasvalue = 0; + int negativevalue = 0; + int questmarkintvalue = 0; + double questmarkfloatvalue = 0; + int gotquestmarkvalue = false; + int lastoperatortype = 0; + // + operator_t operator_heap[MAX_OPERATORS]; + int numoperators = 0; + value_t value_heap[MAX_VALUES]; + int numvalues = 0; + + firstoperator = lastoperator = NULL; + firstvalue = lastvalue = NULL; + if (intvalue) *intvalue = 0; + if (floatvalue) *floatvalue = 0; + for ( t = tokens; t; t = t->next ) { + switch( t->type ) { + case TT_NAME: + { + if ( lastwasvalue || negativevalue ) { + idParser::Error( "syntax error in #if/#elif" ); + error = 1; + break; + } + if ( (*t) != "defined" ) { + idParser::Error( "undefined name '%s' in #if/#elif", t->c_str() ); + error = 1; + break; + } + t = t->next; + if ( (*t) == "(" ) { + brace = true; + t = t->next; + } + if (!t || t->type != TT_NAME) { + idParser::Error( "defined() without name in #if/#elif" ); + error = 1; + break; + } + //v = (value_t *) GetClearedMemory(sizeof(value_t)); + AllocValue(v); + if (FindHashedDefine(idParser::definehash, t->c_str())) { + v->intvalue = 1; + v->floatvalue = 1; + } + else { + v->intvalue = 0; + v->floatvalue = 0; + } + v->parentheses = parentheses; + v->next = NULL; + v->prev = lastvalue; + if (lastvalue) lastvalue->next = v; + else firstvalue = v; + lastvalue = v; + if (brace) { + t = t->next; + if (!t || (*t) != ")" ) { + idParser::Error( "defined missing ) in #if/#elif" ); + error = 1; + break; + } + } + brace = false; + // defined() creates a value + lastwasvalue = 1; + break; + } + case TT_NUMBER: + { + if (lastwasvalue) { + idParser::Error( "syntax error in #if/#elif" ); + error = 1; + break; + } + //v = (value_t *) GetClearedMemory(sizeof(value_t)); + AllocValue(v); + if (negativevalue) { + v->intvalue = - t->GetIntValue(); + v->floatvalue = - t->GetFloatValue(); + } + else { + v->intvalue = t->GetIntValue(); + v->floatvalue = t->GetFloatValue(); + } + v->parentheses = parentheses; + v->next = NULL; + v->prev = lastvalue; + if (lastvalue) lastvalue->next = v; + else firstvalue = v; + lastvalue = v; + //last token was a value + lastwasvalue = 1; + // + negativevalue = 0; + break; + } + case TT_PUNCTUATION: + { + if (negativevalue) { + idParser::Error( "misplaced minus sign in #if/#elif" ); + error = 1; + break; + } + if (t->subtype == P_PARENTHESESOPEN) { + parentheses++; + break; + } + else if (t->subtype == P_PARENTHESESCLOSE) { + parentheses--; + if (parentheses < 0) { + idParser::Error( "too many ) in #if/#elsif" ); + error = 1; + } + break; + } + //check for invalid operators on floating point values + if ( !integer ) { + if (t->subtype == P_BIN_NOT || t->subtype == P_MOD || + t->subtype == P_RSHIFT || t->subtype == P_LSHIFT || + t->subtype == P_BIN_AND || t->subtype == P_BIN_OR || + t->subtype == P_BIN_XOR) { + idParser::Error( "illigal operator '%s' on floating point operands\n", t->c_str() ); + error = 1; + break; + } + } + switch( t->subtype ) { + case P_LOGIC_NOT: + case P_BIN_NOT: + { + if (lastwasvalue) { + idParser::Error( "! or ~ after value in #if/#elif" ); + error = 1; + break; + } + break; + } + case P_INC: + case P_DEC: + { + idParser::Error( "++ or -- used in #if/#elif" ); + break; + } + case P_SUB: + { + if (!lastwasvalue) { + negativevalue = 1; + break; + } + } + + case P_MUL: + case P_DIV: + case P_MOD: + case P_ADD: + + case P_LOGIC_AND: + case P_LOGIC_OR: + case P_LOGIC_GEQ: + case P_LOGIC_LEQ: + case P_LOGIC_EQ: + case P_LOGIC_UNEQ: + + case P_LOGIC_GREATER: + case P_LOGIC_LESS: + + case P_RSHIFT: + case P_LSHIFT: + + case P_BIN_AND: + case P_BIN_OR: + case P_BIN_XOR: + + case P_COLON: + case P_QUESTIONMARK: + { + if (!lastwasvalue) { + idParser::Error( "operator '%s' after operator in #if/#elif", t->c_str() ); + error = 1; + break; + } + break; + } + default: + { + idParser::Error( "invalid operator '%s' in #if/#elif", t->c_str() ); + error = 1; + break; + } + } + if (!error && !negativevalue) { + //o = (operator_t *) GetClearedMemory(sizeof(operator_t)); + AllocOperator(o); + o->op = t->subtype; + o->priority = PC_OperatorPriority(t->subtype); + o->parentheses = parentheses; + o->next = NULL; + o->prev = lastoperator; + if (lastoperator) lastoperator->next = o; + else firstoperator = o; + lastoperator = o; + lastwasvalue = 0; + } + break; + } + default: + { + idParser::Error( "unknown '%s' in #if/#elif", t->c_str() ); + error = 1; + break; + } + } + if (error) { + break; + } + } + if (!error) { + if (!lastwasvalue) { + idParser::Error( "trailing operator in #if/#elif" ); + error = 1; + } + else if (parentheses) { + idParser::Error( "too many ( in #if/#elif" ); + error = 1; + } + } + // + gotquestmarkvalue = false; + questmarkintvalue = 0; + questmarkfloatvalue = 0; + //while there are operators + while( !error && firstoperator ) { + v = firstvalue; + for (o = firstoperator; o->next; o = o->next) { + //if the current operator is nested deeper in parentheses + //than the next operator + if (o->parentheses > o->next->parentheses) { + break; + } + //if the current and next operator are nested equally deep in parentheses + if (o->parentheses == o->next->parentheses) { + //if the priority of the current operator is equal or higher + //than the priority of the next operator + if (o->priority >= o->next->priority) { + break; + } + } + //if the arity of the operator isn't equal to 1 + if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) { + v = v->next; + } + //if there's no value or no next value + if (!v) { + idParser::Error( "mising values in #if/#elif" ); + error = 1; + break; + } + } + if (error) { + break; + } + v1 = v; + v2 = v->next; +#ifdef DEBUG_EVAL + if (integer) { + Log_Write("operator %s, value1 = %d", idParser::scriptstack->getPunctuationFromId(o->op), v1->intvalue); + if (v2) Log_Write("value2 = %d", v2->intvalue); + } + else { + Log_Write("operator %s, value1 = %f", idParser::scriptstack->getPunctuationFromId(o->op), v1->floatvalue); + if (v2) Log_Write("value2 = %f", v2->floatvalue); + } +#endif //DEBUG_EVAL + switch(o->op) { + case P_LOGIC_NOT: v1->intvalue = !v1->intvalue; + v1->floatvalue = !v1->floatvalue; break; + case P_BIN_NOT: v1->intvalue = ~v1->intvalue; + break; + case P_MUL: v1->intvalue *= v2->intvalue; + v1->floatvalue *= v2->floatvalue; break; + case P_DIV: if (!v2->intvalue || !v2->floatvalue) + { + idParser::Error( "divide by zero in #if/#elif\n" ); + error = 1; + break; + } + v1->intvalue /= v2->intvalue; + v1->floatvalue /= v2->floatvalue; break; + case P_MOD: if (!v2->intvalue) + { + idParser::Error( "divide by zero in #if/#elif\n" ); + error = 1; + break; + } + v1->intvalue %= v2->intvalue; break; + case P_ADD: v1->intvalue += v2->intvalue; + v1->floatvalue += v2->floatvalue; break; + case P_SUB: v1->intvalue -= v2->intvalue; + v1->floatvalue -= v2->floatvalue; break; + case P_LOGIC_AND: v1->intvalue = v1->intvalue && v2->intvalue; + v1->floatvalue = v1->floatvalue && v2->floatvalue; break; + case P_LOGIC_OR: v1->intvalue = v1->intvalue || v2->intvalue; + v1->floatvalue = v1->floatvalue || v2->floatvalue; break; + case P_LOGIC_GEQ: v1->intvalue = v1->intvalue >= v2->intvalue; + v1->floatvalue = v1->floatvalue >= v2->floatvalue; break; + case P_LOGIC_LEQ: v1->intvalue = v1->intvalue <= v2->intvalue; + v1->floatvalue = v1->floatvalue <= v2->floatvalue; break; + case P_LOGIC_EQ: v1->intvalue = v1->intvalue == v2->intvalue; + v1->floatvalue = v1->floatvalue == v2->floatvalue; break; + case P_LOGIC_UNEQ: v1->intvalue = v1->intvalue != v2->intvalue; + v1->floatvalue = v1->floatvalue != v2->floatvalue; break; + case P_LOGIC_GREATER: v1->intvalue = v1->intvalue > v2->intvalue; + v1->floatvalue = v1->floatvalue > v2->floatvalue; break; + case P_LOGIC_LESS: v1->intvalue = v1->intvalue < v2->intvalue; + v1->floatvalue = v1->floatvalue < v2->floatvalue; break; + case P_RSHIFT: v1->intvalue >>= v2->intvalue; + break; + case P_LSHIFT: v1->intvalue <<= v2->intvalue; + break; + case P_BIN_AND: v1->intvalue &= v2->intvalue; + break; + case P_BIN_OR: v1->intvalue |= v2->intvalue; + break; + case P_BIN_XOR: v1->intvalue ^= v2->intvalue; + break; + case P_COLON: + { + if (!gotquestmarkvalue) { + idParser::Error( ": without ? in #if/#elif" ); + error = 1; + break; + } + if (integer) { + if (!questmarkintvalue) + v1->intvalue = v2->intvalue; + } + else { + if (!questmarkfloatvalue) + v1->floatvalue = v2->floatvalue; + } + gotquestmarkvalue = false; + break; + } + case P_QUESTIONMARK: + { + if (gotquestmarkvalue) { + idParser::Error( "? after ? in #if/#elif" ); + error = 1; + break; + } + questmarkintvalue = v1->intvalue; + questmarkfloatvalue = v1->floatvalue; + gotquestmarkvalue = true; + break; + } + } +#ifdef DEBUG_EVAL + if (integer) Log_Write("result value = %d", v1->intvalue); + else Log_Write("result value = %f", v1->floatvalue); +#endif //DEBUG_EVAL + if (error) + break; + lastoperatortype = o->op; + //if not an operator with arity 1 + if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) { + //remove the second value if not question mark operator + if (o->op != P_QUESTIONMARK) { + v = v->next; + } + // + if (v->prev) v->prev->next = v->next; + else firstvalue = v->next; + if (v->next) v->next->prev = v->prev; + else lastvalue = v->prev; + //FreeMemory(v); + FreeValue(v); + } + //remove the operator + if (o->prev) o->prev->next = o->next; + else firstoperator = o->next; + if (o->next) o->next->prev = o->prev; + else lastoperator = o->prev; + //FreeMemory(o); + FreeOperator(o); + } + if (firstvalue) { + if (intvalue) *intvalue = firstvalue->intvalue; + if (floatvalue) *floatvalue = firstvalue->floatvalue; + } + for (o = firstoperator; o; o = lastoperator) { + lastoperator = o->next; + //FreeMemory(o); + FreeOperator(o); + } + for (v = firstvalue; v; v = lastvalue) { + lastvalue = v->next; + //FreeMemory(v); + FreeValue(v); + } + if (!error) { + return true; + } + if (intvalue) { + *intvalue = 0; + } + if (floatvalue) { + *floatvalue = 0; + } + return false; +} + +/* +================ +idParser::Evaluate +================ +*/ +int idParser::Evaluate( signed long int *intvalue, double *floatvalue, int integer ) { + idToken token, *firsttoken, *lasttoken; + idToken *t, *nexttoken; + define_t *define; + int defined = false; + + if (intvalue) { + *intvalue = 0; + } + if (floatvalue) { + *floatvalue = 0; + } + // + if ( !idParser::ReadLine( &token ) ) { + idParser::Error( "no value after #if/#elif" ); + return false; + } + firsttoken = NULL; + lasttoken = NULL; + do { + //if the token is a name + if (token.type == TT_NAME) { + if (defined) { + defined = false; + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else if ( token == "defined" ) { + defined = true; + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else { + //then it must be a define + define = FindHashedDefine(idParser::definehash, token.c_str()); + if (!define) { + idParser::Error( "can't Evaluate '%s', not defined", token.c_str() ); + return false; + } + if ( !idParser::ExpandDefineIntoSource( &token, define ) ) { + return false; + } + } + } + //if the token is a number or a punctuation + else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) { + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else { + idParser::Error( "can't Evaluate '%s'", token.c_str() ); + return false; + } + } while(idParser::ReadLine( &token )); + // + if ( !idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer ) ) { + return false; + } + // +#ifdef DEBUG_EVAL + Log_Write("eval:"); +#endif //DEBUG_EVAL + for (t = firsttoken; t; t = nexttoken) { +#ifdef DEBUG_EVAL + Log_Write(" %s", t->c_str()); +#endif //DEBUG_EVAL + nexttoken = t->next; + delete t; + } //end for +#ifdef DEBUG_EVAL + if (integer) Log_Write("eval result: %d", *intvalue); + else Log_Write("eval result: %f", *floatvalue); +#endif //DEBUG_EVAL + // + return true; +} + +/* +================ +idParser::DollarEvaluate +================ +*/ +int idParser::DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer) { + int indent, defined = false; + idToken token, *firsttoken, *lasttoken; + idToken *t, *nexttoken; + define_t *define; + + if (intvalue) { + *intvalue = 0; + } + if (floatvalue) { + *floatvalue = 0; + } + // + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "no leading ( after $evalint/$evalfloat" ); + return false; + } + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "nothing to Evaluate" ); + return false; + } + indent = 1; + firsttoken = NULL; + lasttoken = NULL; + do { + //if the token is a name + if (token.type == TT_NAME) { + if (defined) { + defined = false; + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else if ( token == "defined" ) { + defined = true; + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else { + //then it must be a define + define = FindHashedDefine(idParser::definehash, token.c_str()); + if (!define) { + idParser::Warning( "can't Evaluate '%s', not defined", token.c_str() ); + return false; + } + if ( !idParser::ExpandDefineIntoSource( &token, define ) ) { + return false; + } + } + } + //if the token is a number or a punctuation + else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) { + if ( token[0] == '(' ) indent++; + else if ( token[0] == ')' ) indent--; + if (indent <= 0) { + break; + } + t = new idToken(token); + t->next = NULL; + if (lasttoken) lasttoken->next = t; + else firsttoken = t; + lasttoken = t; + } + else { + idParser::Error( "can't Evaluate '%s'", token.c_str() ); + return false; + } + } while(idParser::ReadSourceToken( &token )); + // + if (!idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer)) { + return false; + } + // +#ifdef DEBUG_EVAL + Log_Write("$eval:"); +#endif //DEBUG_EVAL + for (t = firsttoken; t; t = nexttoken) { +#ifdef DEBUG_EVAL + Log_Write(" %s", t->c_str()); +#endif //DEBUG_EVAL + nexttoken = t->next; + delete t; + } //end for +#ifdef DEBUG_EVAL + if (integer) Log_Write("$eval result: %d", *intvalue); + else Log_Write("$eval result: %f", *floatvalue); +#endif //DEBUG_EVAL + // + return true; +} + +/* +================ +idParser::Directive_elif +================ +*/ +int idParser::Directive_elif( void ) { + signed long int value; + int type, skip; + + idParser::PopIndent( &type, &skip ); + if (!type || type == INDENT_ELSE) { + idParser::Error( "misplaced #elif" ); + return false; + } + if ( !idParser::Evaluate( &value, NULL, true ) ) { + return false; + } + skip = (value == 0); + idParser::PushIndent( INDENT_ELIF, skip ); + return true; +} + +/* +================ +idParser::Directive_if +================ +*/ +int idParser::Directive_if( void ) { + signed long int value; + int skip; + + if ( !idParser::Evaluate( &value, NULL, true ) ) { + return false; + } + skip = (value == 0); + idParser::PushIndent( INDENT_IF, skip ); + return true; +} + +/* +================ +idParser::Directive_line +================ +*/ +int idParser::Directive_line( void ) { + idToken token; + + idParser::Error( "#line directive not supported" ); + while( idParser::ReadLine( &token ) ) { + } + return true; +} + +/* +================ +idParser::Directive_error +================ +*/ +int idParser::Directive_error( void ) { + idToken token; + + if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) { + idParser::Error( "#error without string" ); + return false; + } + idParser::Error( "#error: %s", token.c_str() ); + return true; +} + +/* +================ +idParser::Directive_warning +================ +*/ +int idParser::Directive_warning( void ) { + idToken token; + + if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) { + idParser::Warning( "#warning without string" ); + return false; + } + idParser::Warning( "#warning: %s", token.c_str() ); + return true; +} + +/* +================ +idParser::Directive_pragma +================ +*/ +int idParser::Directive_pragma( void ) { + idToken token; + + idParser::Warning( "#pragma directive not supported" ); + while( idParser::ReadLine( &token ) ) { + } + return true; +} + +/* +================ +idParser::UnreadSignToken +================ +*/ +void idParser::UnreadSignToken( void ) { + idToken token; + + token.line = idParser::scriptstack->GetLineNum(); + token.whiteSpaceStart_p = NULL; + token.whiteSpaceEnd_p = NULL; + token.linesCrossed = 0; + token.flags = 0; + token = "-"; + token.type = TT_PUNCTUATION; + token.subtype = P_SUB; + idParser::UnreadSourceToken( &token ); +} + +/* +================ +idParser::Directive_eval +================ +*/ +int idParser::Directive_eval( void ) { + signed long int value; + idToken token; + char buf[128]; + + if ( !idParser::Evaluate( &value, NULL, true ) ) { + return false; + } + + token.line = idParser::scriptstack->GetLineNum(); + token.whiteSpaceStart_p = NULL; + token.whiteSpaceEnd_p = NULL; + token.linesCrossed = 0; + token.flags = 0; + sprintf(buf, "%d", abs(value)); + token = buf; + token.type = TT_NUMBER; + token.subtype = TT_INTEGER|TT_LONG|TT_DECIMAL; + idParser::UnreadSourceToken( &token ); + if ( value < 0 ) { + idParser::UnreadSignToken(); + } + return true; +} + +/* +================ +idParser::Directive_evalfloat +================ +*/ +int idParser::Directive_evalfloat( void ) { + double value; + idToken token; + char buf[128]; + + if ( !idParser::Evaluate( NULL, &value, false ) ) { + return false; + } + + token.line = idParser::scriptstack->GetLineNum(); + token.whiteSpaceStart_p = NULL; + token.whiteSpaceEnd_p = NULL; + token.linesCrossed = 0; + token.flags = 0; + sprintf(buf, "%1.2f", idMath::Fabs(value)); + token = buf; + token.type = TT_NUMBER; + token.subtype = TT_FLOAT|TT_LONG|TT_DECIMAL; + idParser::UnreadSourceToken( &token ); + if (value < 0) { + idParser::UnreadSignToken(); + } + return true; +} + +/* +================ +idParser::ReadDirective +================ +*/ +int idParser::ReadDirective( void ) { + idToken token; + + //read the directive name + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "found '#' without name" ); + return false; + } + //directive name must be on the same line + if (token.linesCrossed > 0) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "found '#' at end of line" ); + return false; + } + //if if is a name + if (token.type == TT_NAME) { + if ( token == "if" ) { + return idParser::Directive_if(); + } + else if ( token == "ifdef" ) { + return idParser::Directive_ifdef(); + } + else if ( token == "ifndef" ) { + return idParser::Directive_ifndef(); + } + else if ( token == "elif" ) { + return idParser::Directive_elif(); + } + else if ( token == "else" ) { + return idParser::Directive_else(); + } + else if ( token == "endif" ) { + return idParser::Directive_endif(); + } + else if (idParser::skip > 0) { + // skip the rest of the line + while( idParser::ReadLine( &token ) ) { + } + return true; + } + else { + if ( token == "include" ) { + return idParser::Directive_include(); + } + else if ( token == "define" ) { + return idParser::Directive_define(); + } + else if ( token == "undef" ) { + return idParser::Directive_undef(); + } + else if ( token == "line" ) { + return idParser::Directive_line(); + } + else if ( token == "error" ) { + return idParser::Directive_error(); + } + else if ( token == "warning" ) { + return idParser::Directive_warning(); + } + else if ( token == "pragma" ) { + return idParser::Directive_pragma(); + } + else if ( token == "eval" ) { + return idParser::Directive_eval(); + } + else if ( token == "evalfloat" ) { + return idParser::Directive_evalfloat(); + } + } + } + idParser::Error( "unknown precompiler directive '%s'", token.c_str() ); + return false; +} + +/* +================ +idParser::DollarDirective_evalint +================ +*/ +int idParser::DollarDirective_evalint( void ) { + signed long int value; + idToken token; + char buf[128]; + + if ( !idParser::DollarEvaluate( &value, NULL, true ) ) { + return false; + } + + token.line = idParser::scriptstack->GetLineNum(); + token.whiteSpaceStart_p = NULL; + token.whiteSpaceEnd_p = NULL; + token.linesCrossed = 0; + token.flags = 0; + sprintf( buf, "%d", abs( value ) ); + token = buf; + token.type = TT_NUMBER; + token.subtype = TT_INTEGER | TT_LONG | TT_DECIMAL | TT_VALUESVALID; + token.intvalue = abs( value ); + token.floatvalue = abs( value ); + idParser::UnreadSourceToken( &token ); + if ( value < 0 ) { + idParser::UnreadSignToken(); + } + return true; +} + +/* +================ +idParser::DollarDirective_evalfloat +================ +*/ +int idParser::DollarDirective_evalfloat( void ) { + double value; + idToken token; + char buf[128]; + + if ( !idParser::DollarEvaluate( NULL, &value, false ) ) { + return false; + } + + token.line = idParser::scriptstack->GetLineNum(); + token.whiteSpaceStart_p = NULL; + token.whiteSpaceEnd_p = NULL; + token.linesCrossed = 0; + token.flags = 0; + sprintf( buf, "%1.2f", fabs( value ) ); + token = buf; + token.type = TT_NUMBER; + token.subtype = TT_FLOAT | TT_LONG | TT_DECIMAL | TT_VALUESVALID; + token.intvalue = (unsigned long) fabs( value ); + token.floatvalue = fabs( value ); + idParser::UnreadSourceToken( &token ); + if ( value < 0 ) { + idParser::UnreadSignToken(); + } + return true; +} + +/* +================ +idParser::ReadDollarDirective +================ +*/ +int idParser::ReadDollarDirective( void ) { + idToken token; + + // read the directive name + if ( !idParser::ReadSourceToken( &token ) ) { + idParser::Error( "found '$' without name" ); + return false; + } + // directive name must be on the same line + if ( token.linesCrossed > 0 ) { + idParser::UnreadSourceToken( &token ); + idParser::Error( "found '$' at end of line" ); + return false; + } + // if if is a name + if (token.type == TT_NAME) { + if ( token == "evalint" ) { + return idParser::DollarDirective_evalint(); + } + else if ( token == "evalfloat" ) { + return idParser::DollarDirective_evalfloat(); + } + } + idParser::UnreadSourceToken( &token ); + return false; +} + +/* +================ +idParser::ReadToken +================ +*/ +int idParser::ReadToken( idToken *token ) { + define_t *define; + + while(1) { + if ( !idParser::ReadSourceToken( token ) ) { + return false; + } + // check for precompiler directives + if ( token->type == TT_PUNCTUATION && (*token)[0] == '#' && (*token)[1] == '\0' ) { + // read the precompiler directive + if ( !idParser::ReadDirective() ) { + return false; + } + continue; + } + // if skipping source because of conditional compilation + if ( idParser::skip ) { + continue; + } + // recursively concatenate strings that are behind each other still resolving defines + if ( token->type == TT_STRING && !(idParser::scriptstack->GetFlags() & LEXFL_NOSTRINGCONCAT) ) { + idToken newtoken; + if ( idParser::ReadToken( &newtoken ) ) { + if ( newtoken.type == TT_STRING ) { + token->Append( newtoken.c_str() ); + } + else { + idParser::UnreadSourceToken( &newtoken ); + } + } + } + // + if ( !(idParser::scriptstack->GetFlags() & LEXFL_NODOLLARPRECOMPILE) ) { + // check for special precompiler directives + if ( token->type == TT_PUNCTUATION && (*token)[0] == '$' && (*token)[1] == '\0' ) { + // read the precompiler directive + if ( idParser::ReadDollarDirective() ) { + continue; + } + } + } + // if the token is a name + if ( token->type == TT_NAME && !( token->flags & TOKEN_FL_RECURSIVE_DEFINE ) ) { + // check if the name is a define macro + define = FindHashedDefine( idParser::definehash, token->c_str() ); + // if it is a define macro + if ( define ) { + // expand the defined macro + if ( !idParser::ExpandDefineIntoSource( token, define ) ) { + return false; + } + continue; + } + } + // found a token + return true; + } +} + +/* +================ +idParser::ExpectTokenString +================ +*/ +int idParser::ExpectTokenString( const char *string ) { + idToken token; + + if ( !idParser::ReadToken( &token ) ) { + idParser::Error( "couldn't find expected '%s'", string ); + return false; + } + + if ( token != string ) { + idParser::Error( "expected '%s' but found '%s'", string, token.c_str() ); + return false; + } + return true; +} + +/* +================ +idParser::ExpectTokenType +================ +*/ +int idParser::ExpectTokenType( int type, int subtype, idToken *token ) { + idStr str; + + if ( !idParser::ReadToken( token ) ) { + idParser::Error( "couldn't read expected token" ); + return 0; + } + + if ( token->type != type ) { + switch( type ) { + case TT_STRING: str = "string"; break; + case TT_LITERAL: str = "literal"; break; + case TT_NUMBER: str = "number"; break; + case TT_NAME: str = "name"; break; + case TT_PUNCTUATION: str = "punctuation"; break; + default: str = "unknown type"; break; + } + idParser::Error( "expected a %s but found '%s'", str.c_str(), token->c_str() ); + return 0; + } + if ( token->type == TT_NUMBER ) { + if ( (token->subtype & subtype) != subtype ) { + str.Clear(); + if ( subtype & TT_DECIMAL ) str = "decimal "; + if ( subtype & TT_HEX ) str = "hex "; + if ( subtype & TT_OCTAL ) str = "octal "; + if ( subtype & TT_BINARY ) str = "binary "; + if ( subtype & TT_UNSIGNED ) str += "unsigned "; + if ( subtype & TT_LONG ) str += "long "; + if ( subtype & TT_FLOAT ) str += "float "; + if ( subtype & TT_INTEGER ) str += "integer "; + str.StripTrailing( ' ' ); + idParser::Error( "expected %s but found '%s'", str.c_str(), token->c_str() ); + return 0; + } + } + else if ( token->type == TT_PUNCTUATION ) { + if ( subtype < 0 ) { + idParser::Error( "BUG: wrong punctuation subtype" ); + return 0; + } + if ( token->subtype != subtype ) { + idParser::Error( "expected '%s' but found '%s'", scriptstack->GetPunctuationFromId( subtype ), token->c_str() ); + return 0; + } + } + return 1; +} + +/* +================ +idParser::ExpectAnyToken +================ +*/ +int idParser::ExpectAnyToken( idToken *token ) { + if (!idParser::ReadToken( token )) { + idParser::Error( "couldn't read expected token" ); + return false; + } + else { + return true; + } +} + +/* +================ +idParser::CheckTokenString +================ +*/ +int idParser::CheckTokenString( const char *string ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return false; + } + //if the token is available + if ( tok == string ) { + return true; + } + + UnreadSourceToken( &tok ); + return false; +} + +/* +================ +idParser::CheckTokenType +================ +*/ +int idParser::CheckTokenType( int type, int subtype, idToken *token ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return false; + } + //if the type matches + if (tok.type == type && (tok.subtype & subtype) == subtype) { + *token = tok; + return true; + } + + UnreadSourceToken( &tok ); + return false; +} + +/* +================ +idParser::PeekTokenString +================ +*/ +int idParser::PeekTokenString( const char *string ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return false; + } + + UnreadSourceToken( &tok ); + + // if the token is available + if ( tok == string ) { + return true; + } + return false; +} + +/* +================ +idParser::PeekTokenType +================ +*/ +int idParser::PeekTokenType( int type, int subtype, idToken *token ) { + idToken tok; + + if ( !ReadToken( &tok ) ) { + return false; + } + + UnreadSourceToken( &tok ); + + // if the type matches + if ( tok.type == type && ( tok.subtype & subtype ) == subtype ) { + *token = tok; + return true; + } + return false; +} + +/* +================ +idParser::SkipUntilString +================ +*/ +int idParser::SkipUntilString( const char *string ) { + idToken token; + + while(idParser::ReadToken( &token )) { + if ( token == string ) { + return true; + } + } + return false; +} + +/* +================ +idParser::SkipRestOfLine +================ +*/ +int idParser::SkipRestOfLine( void ) { + idToken token; + + while(idParser::ReadToken( &token )) { + if ( token.linesCrossed ) { + idParser::UnreadSourceToken( &token ); + return true; + } + } + return false; +} + +/* +================= +idParser::SkipBracedSection + +Skips until a matching close brace is found. +Internal brace depths are properly skipped. +================= +*/ +int idParser::SkipBracedSection( bool parseFirstBrace ) { + idToken token; + int depth; + + depth = parseFirstBrace ? 0 : 1; + do { + if ( !ReadToken( &token ) ) { + return false; + } + if( token.type == TT_PUNCTUATION ) { + if( token == "{" ) { + depth++; + } else if ( token == "}" ) { + depth--; + } + } + } while( depth ); + return true; +} + +/* +================= +idParser::ParseBracedSectionExact + +The next token should be an open brace. +Parses until a matching close brace is found. +Maintains the exact formating of the braced section + + FIXME: what about precompilation ? +================= +*/ +const char *idParser::ParseBracedSectionExact( idStr &out, int tabs ) { + return scriptstack->ParseBracedSectionExact( out, tabs ); +} + +/* +================= +idParser::ParseBracedSection + +The next token should be an open brace. +Parses until a matching close brace is found. +Internal brace depths are properly skipped. +================= +*/ +const char *idParser::ParseBracedSection( idStr &out, int tabs ) { + idToken token; + int i, depth; + bool doTabs = false; + if (tabs >= 0) { + doTabs = true; + } + + out.Empty(); + if ( !idParser::ExpectTokenString( "{" ) ) { + return out.c_str(); + } + out = "{"; + depth = 1; + do { + if ( !idParser::ReadToken( &token ) ) { + Error( "missing closing brace" ); + return out.c_str(); + } + + // if the token is on a new line + for ( i = 0; i < token.linesCrossed; i++ ) { + out += "\r\n"; + } + + if (doTabs && token.linesCrossed) { + i = tabs; + if (token[0] == '}' && i > 0) { + i--; + } + while (i-- > 0) { + out += "\t"; + } + } + if ( token.type == TT_PUNCTUATION ) { + if ( token[0] == '{' ) { + depth++; + if (doTabs) { + tabs++; + } + } + else if ( token[0] == '}' ) { + depth--; + if (doTabs) { + tabs--; + } + } + } + + if ( token.type == TT_STRING ) { + out += "\"" + token + "\""; + } + else { + out += token; + } + out += " "; + } while( depth ); + + return out.c_str(); +} + +/* +================= +idParser::ParseRestOfLine + + parse the rest of the line +================= +*/ +const char *idParser::ParseRestOfLine( idStr &out ) { + idToken token; + + out.Empty(); + while(idParser::ReadToken( &token )) { + if ( token.linesCrossed ) { + idParser::UnreadSourceToken( &token ); + break; + } + if ( out.Length() ) { + out += " "; + } + out += token; + } + return out.c_str(); +} + +/* +================ +idParser::UnreadToken +================ +*/ +void idParser::UnreadToken( idToken *token ) { + idParser::UnreadSourceToken( token ); +} + +/* +================ +idParser::ReadTokenOnLine +================ +*/ +int idParser::ReadTokenOnLine( idToken *token ) { + idToken tok; + + if (!idParser::ReadToken( &tok )) { + return false; + } + // if no lines were crossed before this token + if ( !tok.linesCrossed ) { + *token = tok; + return true; + } + // + idParser::UnreadSourceToken( &tok ); + return false; +} + +/* +================ +idParser::ParseInt +================ +*/ +int idParser::ParseInt( void ) { + idToken token; + + if ( !idParser::ReadToken( &token ) ) { + idParser::Error( "couldn't read expected integer" ); + return 0; + } + if ( token.type == TT_PUNCTUATION && token == "-" ) { + idParser::ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); + return -((signed int) token.GetIntValue()); + } + else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { + idParser::Error( "expected integer value, found '%s'", token.c_str() ); + } + return token.GetIntValue(); +} + +/* +================ +idParser::ParseBool +================ +*/ +bool idParser::ParseBool( void ) { + idToken token; + + if ( !idParser::ExpectTokenType( TT_NUMBER, 0, &token ) ) { + idParser::Error( "couldn't read expected boolean" ); + return false; + } + return ( token.GetIntValue() != 0 ); +} + +/* +================ +idParser::ParseFloat +================ +*/ +float idParser::ParseFloat( void ) { + idToken token; + + if ( !idParser::ReadToken( &token ) ) { + idParser::Error( "couldn't read expected floating point number" ); + return 0.0f; + } + if ( token.type == TT_PUNCTUATION && token == "-" ) { + idParser::ExpectTokenType( TT_NUMBER, 0, &token ); + return -token.GetFloatValue(); + } + else if ( token.type != TT_NUMBER ) { + idParser::Error( "expected float value, found '%s'", token.c_str() ); + } + return token.GetFloatValue(); +} + +/* +================ +idParser::Parse1DMatrix +================ +*/ +int idParser::Parse1DMatrix( int x, float *m ) { + int i; + + if ( !idParser::ExpectTokenString( "(" ) ) { + return false; + } + + for ( i = 0; i < x; i++ ) { + m[i] = idParser::ParseFloat(); + } + + if ( !idParser::ExpectTokenString( ")" ) ) { + return false; + } + return true; +} + +/* +================ +idParser::Parse2DMatrix +================ +*/ +int idParser::Parse2DMatrix( int y, int x, float *m ) { + int i; + + if ( !idParser::ExpectTokenString( "(" ) ) { + return false; + } + + for ( i = 0; i < y; i++ ) { + if ( !idParser::Parse1DMatrix( x, m + i * x ) ) { + return false; + } + } + + if ( !idParser::ExpectTokenString( ")" ) ) { + return false; + } + return true; +} + +/* +================ +idParser::Parse3DMatrix +================ +*/ +int idParser::Parse3DMatrix( int z, int y, int x, float *m ) { + int i; + + if ( !idParser::ExpectTokenString( "(" ) ) { + return false; + } + + for ( i = 0 ; i < z; i++ ) { + if ( !idParser::Parse2DMatrix( y, x, m + i * x*y ) ) { + return false; + } + } + + if ( !idParser::ExpectTokenString( ")" ) ) { + return false; + } + return true; +} + +/* +================ +idParser::GetLastWhiteSpace +================ +*/ +int idParser::GetLastWhiteSpace( idStr &whiteSpace ) const { + if ( scriptstack ) { + scriptstack->GetLastWhiteSpace( whiteSpace ); + } else { + whiteSpace.Clear(); + } + return whiteSpace.Length(); +} + +/* +================ +idParser::SetMarker +================ +*/ +void idParser::SetMarker( void ) { + marker_p = NULL; +} + +/* +================ +idParser::GetStringFromMarker + + FIXME: this is very bad code, the script isn't even garrenteed to still be around +================ +*/ +void idParser::GetStringFromMarker( idStr& out, bool clean ) { + char* p; + char save; + + if ( marker_p == NULL ) { + marker_p = scriptstack->buffer; + } + + if ( tokens ) { + p = (char*)tokens->whiteSpaceStart_p; + } else { + p = (char*)scriptstack->script_p; + } + + // Set the end character to NULL to give us a complete string + save = *p; + *p = 0; + + // If cleaning then reparse + if ( clean ) { + idParser temp( marker_p, strlen( marker_p ), "temp", flags ); + idToken token; + while ( temp.ReadToken ( &token ) ) { + out += token; + } + } else { + out = marker_p; + } + + // restore the character we set to NULL + *p = save; +} + +/* +================ +idParser::SetIncludePath +================ +*/ +void idParser::SetIncludePath( const char *path ) { + idParser::includepath = path; + // add trailing path seperator + if (idParser::includepath[idParser::includepath.Length()-1] != '\\' && + idParser::includepath[idParser::includepath.Length()-1] != '/') { + idParser::includepath += PATHSEPERATOR_STR; + } +} + +/* +================ +idParser::SetPunctuations +================ +*/ +void idParser::SetPunctuations( const punctuation_t *p ) { + idParser::punctuations = p; +} + +/* +================ +idParser::SetFlags +================ +*/ +void idParser::SetFlags( int flags ) { + idLexer *s; + + idParser::flags = flags; + for ( s = idParser::scriptstack; s; s = s->next ) { + s->SetFlags( flags ); + } +} + +/* +================ +idParser::GetFlags +================ +*/ +int idParser::GetFlags( void ) const { + return idParser::flags; +} + +/* +================ +idParser::LoadFile +================ +*/ +int idParser::LoadFile( const char *filename, bool OSPath ) { + idLexer *script; + + if ( idParser::loaded ) { + idLib::common->FatalError("idParser::loadFile: another source already loaded"); + return false; + } + script = new idLexer( filename, 0, OSPath ); + if ( !script->IsLoaded() ) { + delete script; + return false; + } + script->SetFlags( idParser::flags ); + script->SetPunctuations( idParser::punctuations ); + script->next = NULL; + idParser::OSPath = OSPath; + idParser::filename = filename; + idParser::scriptstack = script; + idParser::tokens = NULL; + idParser::indentstack = NULL; + idParser::skip = 0; + idParser::loaded = true; + + if ( !idParser::definehash ) { + idParser::defines = NULL; + idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) ); + idParser::AddGlobalDefinesToSource(); + } + return true; +} + +/* +================ +idParser::LoadMemory +================ +*/ +int idParser::LoadMemory(const char *ptr, int length, const char *name ) { + idLexer *script; + + if ( idParser::loaded ) { + idLib::common->FatalError("idParser::loadMemory: another source already loaded"); + return false; + } + script = new idLexer( ptr, length, name ); + if ( !script->IsLoaded() ) { + delete script; + return false; + } + script->SetFlags( idParser::flags ); + script->SetPunctuations( idParser::punctuations ); + script->next = NULL; + idParser::filename = name; + idParser::scriptstack = script; + idParser::tokens = NULL; + idParser::indentstack = NULL; + idParser::skip = 0; + idParser::loaded = true; + + if ( !idParser::definehash ) { + idParser::defines = NULL; + idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) ); + idParser::AddGlobalDefinesToSource(); + } + return true; +} + +/* +================ +idParser::FreeSource +================ +*/ +void idParser::FreeSource( bool keepDefines ) { + idLexer *script; + idToken *token; + define_t *define; + indent_t *indent; + int i; + + // free all the scripts + while( scriptstack ) { + script = scriptstack; + scriptstack = scriptstack->next; + delete script; + } + // free all the tokens + while( tokens ) { + token = tokens; + tokens = tokens->next; + delete token; + } + // free all indents + while( indentstack ) { + indent = indentstack; + indentstack = indentstack->next; + Mem_Free( indent ); + } + if ( !keepDefines ) { + // free hash table + if ( definehash ) { + // free defines + for ( i = 0; i < DEFINEHASHSIZE; i++ ) { + while( definehash[i] ) { + define = definehash[i]; + definehash[i] = definehash[i]->hashnext; + FreeDefine(define); + } + } + defines = NULL; + Mem_Free( idParser::definehash ); + definehash = NULL; + } + } + loaded = false; +} + +/* +================ +idParser::GetPunctuationFromId +================ +*/ +const char *idParser::GetPunctuationFromId( int id ) { + int i; + + if ( !idParser::punctuations ) { + idLexer lex; + return lex.GetPunctuationFromId( id ); + } + + for (i = 0; idParser::punctuations[i].p; i++) { + if ( idParser::punctuations[i].n == id ) { + return idParser::punctuations[i].p; + } + } + return "unkown punctuation"; +} + +/* +================ +idParser::GetPunctuationId +================ +*/ +int idParser::GetPunctuationId( const char *p ) { + int i; + + if ( !idParser::punctuations ) { + idLexer lex; + return lex.GetPunctuationId( p ); + } + + for (i = 0; idParser::punctuations[i].p; i++) { + if ( !strcmp(idParser::punctuations[i].p, p) ) { + return idParser::punctuations[i].n; + } + } + return 0; +} + +/* +================ +idParser::idParser +================ +*/ +idParser::idParser() { + this->loaded = false; + this->OSPath = false; + this->punctuations = 0; + this->flags = 0; + this->scriptstack = NULL; + this->indentstack = NULL; + this->definehash = NULL; + this->defines = NULL; + this->tokens = NULL; + this->marker_p = NULL; +} + +/* +================ +idParser::idParser +================ +*/ +idParser::idParser( int flags ) { + this->loaded = false; + this->OSPath = false; + this->punctuations = 0; + this->flags = flags; + this->scriptstack = NULL; + this->indentstack = NULL; + this->definehash = NULL; + this->defines = NULL; + this->tokens = NULL; + this->marker_p = NULL; +} + +/* +================ +idParser::idParser +================ +*/ +idParser::idParser( const char *filename, int flags, bool OSPath ) { + this->loaded = false; + this->OSPath = true; + this->punctuations = 0; + this->flags = flags; + this->scriptstack = NULL; + this->indentstack = NULL; + this->definehash = NULL; + this->defines = NULL; + this->tokens = NULL; + this->marker_p = NULL; + LoadFile( filename, OSPath ); +} + +/* +================ +idParser::idParser +================ +*/ +idParser::idParser( const char *ptr, int length, const char *name, int flags ) { + this->loaded = false; + this->OSPath = false; + this->punctuations = 0; + this->flags = flags; + this->scriptstack = NULL; + this->indentstack = NULL; + this->definehash = NULL; + this->defines = NULL; + this->tokens = NULL; + this->marker_p = NULL; + LoadMemory( ptr, length, name ); +} + +/* +================ +idParser::~idParser +================ +*/ +idParser::~idParser( void ) { + idParser::FreeSource( false ); +} + diff --git a/idlib/Parser.h b/idlib/Parser.h new file mode 100644 index 000000000..dedb977ab --- /dev/null +++ b/idlib/Parser.h @@ -0,0 +1,274 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PARSER_H__ +#define __PARSER_H__ + +/* +=============================================================================== + + C/C++ compatible pre-compiler + +=============================================================================== +*/ + +#define DEFINE_FIXED 0x0001 + +#define BUILTIN_LINE 1 +#define BUILTIN_FILE 2 +#define BUILTIN_DATE 3 +#define BUILTIN_TIME 4 +#define BUILTIN_STDC 5 + +#define INDENT_IF 0x0001 +#define INDENT_ELSE 0x0002 +#define INDENT_ELIF 0x0004 +#define INDENT_IFDEF 0x0008 +#define INDENT_IFNDEF 0x0010 + +// macro definitions +typedef struct define_s { + char * name; // define name + int flags; // define flags + int builtin; // > 0 if builtin define + int numparms; // number of define parameters + idToken * parms; // define parameters + idToken * tokens; // macro tokens (possibly containing parm tokens) + struct define_s *next; // next defined macro in a list + struct define_s *hashnext; // next define in the hash chain +} define_t; + +// indents used for conditional compilation directives: +// #if, #else, #elif, #ifdef, #ifndef +typedef struct indent_s { + int type; // indent type + int skip; // true if skipping current indent + idLexer * script; // script the indent was in + struct indent_s *next; // next indent on the indent stack +} indent_t; + + +class idParser { + +public: + // constructor + idParser(); + idParser( int flags ); + idParser( const char *filename, int flags = 0, bool OSPath = false ); + idParser( const char *ptr, int length, const char *name, int flags = 0 ); + // destructor + ~idParser(); + // load a source file + int LoadFile( const char *filename, bool OSPath = false ); + // load a source from the given memory with the given length + // NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0' + int LoadMemory( const char *ptr, int length, const char *name ); + // free the current source + void FreeSource( bool keepDefines = false ); + // returns true if a source is loaded + int IsLoaded( void ) const { return idParser::loaded; } + // read a token from the source + int ReadToken( idToken *token ); + // expect a certain token, reads the token when available + int ExpectTokenString( const char *string ); + // expect a certain token type + int ExpectTokenType( int type, int subtype, idToken *token ); + // expect a token + int ExpectAnyToken( idToken *token ); + // returns true if the next token equals the given string and removes the token from the source + int CheckTokenString( const char *string ); + // returns true if the next token equals the given type and removes the token from the source + int CheckTokenType( int type, int subtype, idToken *token ); + // returns true if the next token equals the given string but does not remove the token from the source + int PeekTokenString( const char *string ); + // returns true if the next token equals the given type but does not remove the token from the source + int PeekTokenType( int type, int subtype, idToken *token ); + // skip tokens until the given token string is read + int SkipUntilString( const char *string ); + // skip the rest of the current line + int SkipRestOfLine( void ); + // skip the braced section + int SkipBracedSection( bool parseFirstBrace = true ); + // parse a braced section into a string + const char * ParseBracedSection( idStr &out, int tabs = -1 ); + // parse a braced section into a string, maintaining indents and newlines + const char * ParseBracedSectionExact( idStr &out, int tabs = -1 ); + // parse the rest of the line + const char * ParseRestOfLine( idStr &out ); + // unread the given token + void UnreadToken( idToken *token ); + // read a token only if on the current line + int ReadTokenOnLine( idToken *token ); + // read a signed integer + int ParseInt( void ); + // read a boolean + bool ParseBool( void ); + // read a floating point number + float ParseFloat( void ); + // parse matrices with floats + int Parse1DMatrix( int x, float *m ); + int Parse2DMatrix( int y, int x, float *m ); + int Parse3DMatrix( int z, int y, int x, float *m ); + // get the white space before the last read token + int GetLastWhiteSpace( idStr &whiteSpace ) const; + // Set a marker in the source file (there is only one marker) + void SetMarker( void ); + // Get the string from the marker to the current position + void GetStringFromMarker( idStr& out, bool clean = false ); + // add a define to the source + int AddDefine( const char *string ); + // add builtin defines + void AddBuiltinDefines( void ); + // set the source include path + void SetIncludePath( const char *path ); + // set the punctuation set + void SetPunctuations( const punctuation_t *p ); + // returns a pointer to the punctuation with the given id + const char * GetPunctuationFromId( int id ); + // get the id for the given punctuation + int GetPunctuationId( const char *p ); + // set lexer flags + void SetFlags( int flags ); + // get lexer flags + int GetFlags( void ) const; + // returns the current filename + const char * GetFileName( void ) const; + // get current offset in current script + const int GetFileOffset( void ) const; + // get file time for current script + const ID_TIME_T GetFileTime( void ) const; + // returns the current line number + const int GetLineNum( void ) const; + // print an error message + void Error( const char *str, ... ) const id_attribute((format(printf,2,3))); + // print a warning message + void Warning( const char *str, ... ) const id_attribute((format(printf,2,3))); + + // add a global define that will be added to all opened sources + static int AddGlobalDefine( const char *string ); + // remove the given global define + static int RemoveGlobalDefine( const char *name ); + // remove all global defines + static void RemoveAllGlobalDefines( void ); + // set the base folder to load files from + static void SetBaseFolder( const char *path ); + +private: + int loaded; // set when a source file is loaded from file or memory + idStr filename; // file name of the script + idStr includepath; // path to include files + bool OSPath; // true if the file was loaded from an OS path + const punctuation_t *punctuations; // punctuations to use + int flags; // flags used for script parsing + idLexer * scriptstack; // stack with scripts of the source + idToken * tokens; // tokens to read first + define_t * defines; // list with macro definitions + define_t ** definehash; // hash chain with defines + indent_t * indentstack; // stack with indents + int skip; // > 0 if skipping conditional code + const char* marker_p; + + static define_t *globaldefines; // list with global defines added to every source loaded + +private: + void PushIndent( int type, int skip ); + void PopIndent( int *type, int *skip ); + void PushScript( idLexer *script ); + int ReadSourceToken( idToken *token ); + int ReadLine( idToken *token ); + int UnreadSourceToken( idToken *token ); + int ReadDefineParms( define_t *define, idToken **parms, int maxparms ); + int StringizeTokens( idToken *tokens, idToken *token ); + int MergeTokens( idToken *t1, idToken *t2 ); + int ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); + int ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); + int ExpandDefineIntoSource( idToken *deftoken, define_t *define ); + void AddGlobalDefinesToSource( void ); + define_t * CopyDefine( define_t *define ); + define_t * FindHashedDefine(define_t **definehash, const char *name); + int FindDefineParm( define_t *define, const char *name ); + void AddDefineToHash(define_t *define, define_t **definehash); + static void PrintDefine( define_t *define ); + static void FreeDefine( define_t *define ); + static define_t *FindDefine( define_t *defines, const char *name ); + static define_t *DefineFromString( const char *string); + define_t * CopyFirstDefine( void ); + int Directive_include( void ); + int Directive_undef( void ); + int Directive_if_def( int type ); + int Directive_ifdef( void ); + int Directive_ifndef( void ); + int Directive_else( void ); + int Directive_endif( void ); + int EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ); + int Evaluate( signed long int *intvalue, double *floatvalue, int integer ); + int DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer); + int Directive_define( void ); + int Directive_elif( void ); + int Directive_if( void ); + int Directive_line( void ); + int Directive_error( void ); + int Directive_warning( void ); + int Directive_pragma( void ); + void UnreadSignToken( void ); + int Directive_eval( void ); + int Directive_evalfloat( void ); + int ReadDirective( void ); + int DollarDirective_evalint( void ); + int DollarDirective_evalfloat( void ); + int ReadDollarDirective( void ); +}; + +ID_INLINE const char *idParser::GetFileName( void ) const { + if ( idParser::scriptstack ) { + return idParser::scriptstack->GetFileName(); + } + else { + return ""; + } +} + +ID_INLINE const int idParser::GetFileOffset( void ) const { + if ( idParser::scriptstack ) { + return idParser::scriptstack->GetFileOffset(); + } + else { + return 0; + } +} + +ID_INLINE const ID_TIME_T idParser::GetFileTime( void ) const { + if ( idParser::scriptstack ) { + return idParser::scriptstack->GetFileTime(); + } + else { + return 0; + } +} + +ID_INLINE const int idParser::GetLineNum( void ) const { + if ( idParser::scriptstack ) { + return idParser::scriptstack->GetLineNum(); + } + else { + return 0; + } +} + +#endif /* !__PARSER_H__ */ diff --git a/idlib/Str.cpp b/idlib/Str.cpp new file mode 100644 index 000000000..000a5352f --- /dev/null +++ b/idlib/Str.cpp @@ -0,0 +1,1859 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + + +#if !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X ) + #define USE_STRING_DATA_ALLOCATOR +#endif + +#ifdef USE_STRING_DATA_ALLOCATOR +static idDynamicBlockAlloc stringDataAllocator; +#endif + +idVec4 g_color_table[16] = +{ + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(1.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_RED + idVec4(0.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_GREEN + idVec4(1.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_YELLOW + idVec4(0.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_BLUE + idVec4(0.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_CYAN + idVec4(1.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_MAGENTA + idVec4(1.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_WHITE + idVec4(0.5f, 0.5f, 0.5f, 1.0f), // S_COLOR_GRAY + idVec4(0.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_BLACK + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(0.0f, 0.0f, 0.0f, 1.0f), + idVec4(0.0f, 0.0f, 0.0f, 1.0f), +}; + +const char *units[2][4] = +{ + { "B", "KB", "MB", "GB" }, + { "B/s", "KB/s", "MB/s", "GB/s" } +}; + +/* +============ +idStr::ColorForIndex +============ +*/ +idVec4 & idStr::ColorForIndex( int i ) { + return g_color_table[ i & 15 ]; +} + +/* +============ +idStr::ReAllocate +============ +*/ +void idStr::ReAllocate( int amount, bool keepold ) { + char *newbuffer; + int newsize; + int mod; + + //assert( data ); + assert( amount > 0 ); + + mod = amount % STR_ALLOC_GRAN; + if ( !mod ) { + newsize = amount; + } + else { + newsize = amount + STR_ALLOC_GRAN - mod; + } + alloced = newsize; + +#ifdef USE_STRING_DATA_ALLOCATOR + newbuffer = stringDataAllocator.Alloc( alloced ); +#else + newbuffer = new char[ alloced ]; +#endif + if ( keepold && data ) { + data[ len ] = '\0'; + strcpy( newbuffer, data ); + } + + if ( data && data != baseBuffer ) { +#ifdef USE_STRING_DATA_ALLOCATOR + stringDataAllocator.Free( data ); +#else + delete [] data; +#endif + } + + data = newbuffer; +} + +/* +============ +idStr::FreeData +============ +*/ +void idStr::FreeData( void ) { + if ( data && data != baseBuffer ) { +#ifdef USE_STRING_DATA_ALLOCATOR + stringDataAllocator.Free( data ); +#else + delete[] data; +#endif + data = baseBuffer; + } +} + +/* +============ +idStr::operator= +============ +*/ +void idStr::operator=( const char *text ) { + int l; + int diff; + int i; + + if ( !text ) { + // safe behaviour if NULL + EnsureAlloced( 1, false ); + data[ 0 ] = '\0'; + len = 0; + return; + } + + if ( text == data ) { + return; // copying same thing + } + + // check if we're aliasing + if ( text >= data && text <= data + len ) { + diff = text - data; + + assert( strlen( text ) < (unsigned)len ); + + for ( i = 0; text[ i ]; i++ ) { + data[ i ] = text[ i ]; + } + + data[ i ] = '\0'; + + len -= diff; + + return; + } + + l = strlen( text ); + EnsureAlloced( l + 1, false ); + strcpy( data, text ); + len = l; +} + +idStr idStr::RandomPart( const float rand, const char c ) const { + idStr part; + + // check for list and if found, use random part + int seps = Count(c); + if (seps > 0) { + // if we have X commata, we have X+1 pieces, so select one at random + seps ++; + //gameLocal.Printf("Found random list with %i parts.\n", seps); + + int idx = (int) (rand * (float)seps); + //gameLocal.Printf("random part #%i\n", idx); + // split string into pieces, and select idx + int i = 0; int d = 0; + int start = 0; int end = len; + while (d < len) { + if (data[d] == c) { + i++; + } + if (i == idx) { + // found start, find end + start = d; + if (i > 0) + { + // on first part, start at 0, other parts skip "c" + start ++; + } + end = start; + while (end < len && data[end] != c) + { + end++; + } + break; + } + d++; + } + //gameLocal.Printf("Cutting %s between %i and %i.\n", data, start, end); + part = Mid(start, end - start); + // left-over separator + part.Strip(c); + // and spaces + part.Strip(' '); + if (part == "''") { + // default + part = ""; + } + //gameLocal.Printf("Result: '%s'.\n", part.c_str() ); + // end for random + } + else { + // copy + part.Append( data ); + } + + return part; +} + +/* +============ +idStr::CountChar + +returns count of c between start and end +============ +*/ +int idStr::CountChar( const char *str, const char c, int start, int end ) { + int i; + int count = 0; + + if ( end == -1 ) { + end = strlen( str ) - 1; + } + + for ( i = start; i <= end; i++ ) { + if ( str[i] == c ) { + count++; + } + } + return count; +} + +/* +============ +idStr::FindChar + +returns -1 if not found otherwise the index of the char +============ +*/ +int idStr::FindChar( const char *str, const char c, int start, int end ) { + int i; + + if ( end == -1 ) { + end = strlen( str ) - 1; + } + for ( i = start; i <= end; i++ ) { + if ( str[i] == c ) { + return i; + } + } + return -1; +} + +/* +============ +idStr::FindText + +returns -1 if not found otherwise the index of the text +============ +*/ +int idStr::FindText( const char *str, const char *text, bool casesensitive, int start, int end ) { + int l, i, j; + + if ( end == -1 ) { + end = strlen( str ); + } + l = end - strlen( text ); + for ( i = start; i <= l; i++ ) { + if ( casesensitive ) { + for ( j = 0; text[j]; j++ ) { + if ( str[i+j] != text[j] ) { + break; + } + } + } else { + for ( j = 0; text[j]; j++ ) { + if ( ::toupper( str[i+j] ) != ::toupper( text[j] ) ) { + break; + } + } + } + if ( !text[j] ) { + return i; + } + } + return -1; +} + +/* +============ +idStr::Filter + +Returns true if the string conforms the given filter. +Several metacharacter may be used in the filter. + +* match any string of zero or more characters +? match any single character +[abc...] match any of the enclosed characters; a hyphen can + be used to specify a range (e.g. a-z, A-Z, 0-9) + +============ +*/ +bool idStr::Filter( const char *filter, const char *name, bool casesensitive ) { + idStr buf; + int i, found, index; + + while(*filter) { + if (*filter == '*') { + filter++; + buf.Empty(); + for (i = 0; *filter; i++) { + if ( *filter == '*' || *filter == '?' || (*filter == '[' && *(filter+1) != '[') ) { + break; + } + buf += *filter; + if ( *filter == '[' ) { + filter++; + } + filter++; + } + if ( buf.Length() ) { + index = idStr(name).Find( buf.c_str(), casesensitive ); + if ( index == -1 ) { + return false; + } + name += index + strlen(buf); + } + } + else if (*filter == '?') { + filter++; + name++; + } + else if (*filter == '[') { + if ( *(filter+1) == '[' ) { + if ( *name != '[' ) { + return false; + } + filter += 2; + name++; + } + else { + filter++; + found = false; + while(*filter && !found) { + if (*filter == ']' && *(filter+1) != ']') { + break; + } + if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']')) { + if (casesensitive) { + if (*name >= *filter && *name <= *(filter+2)) { + found = true; + } + } + else { + if ( ::toupper(*name) >= ::toupper(*filter) && ::toupper(*name) <= ::toupper(*(filter+2)) ) { + found = true; + } + } + filter += 3; + } + else { + if (casesensitive) { + if (*filter == *name) { + found = true; + } + } + else { + if ( ::toupper(*filter) == ::toupper(*name) ) { + found = true; + } + } + filter++; + } + } + if (!found) { + return false; + } + while(*filter) { + if ( *filter == ']' && *(filter+1) != ']' ) { + break; + } + filter++; + } + filter++; + name++; + } + } + else { + if (casesensitive) { + if (*filter != *name) { + return false; + } + } + else { + if ( ::toupper(*filter) != ::toupper(*name) ) { + return false; + } + } + filter++; + name++; + } + } + return true; +} + +/* +============= +idStr::StripMediaName + + makes the string lower case, replaces backslashes with forward slashes, and removes extension +============= +*/ +void idStr::StripMediaName( const char *name, idStr &mediaName ) { + char c; + + mediaName.Empty(); + + for ( c = *name; c; c = *(++name) ) { + // truncate at an extension + if ( c == '.' ) { + break; + } + // convert backslashes to forward slashes + if ( c == '\\' ) { + mediaName.Append( '/' ); + } else { + mediaName.Append( idStr::ToLower( c ) ); + } + } +} + +/* +============= +idStr::CheckExtension +============= +*/ +bool idStr::CheckExtension( const char *name, const char *ext ) { + const char *s1 = name + Length( name ) - 1; + const char *s2 = ext + Length( ext ) - 1; + int c1, c2, d; + + do { + c1 = *s1--; + c2 = *s2--; + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + return false; + } + } while( s1 > name && s2 > ext ); + + return ( s1 >= name ); +} + +/* +============= +idStr::FloatArrayToString +============= +*/ +const char *idStr::FloatArrayToString( const float *array, const int length, const int precision ) { + static int index = 0; + static char str[4][16384]; // in case called by nested functions + int i, n; + char format[16], *s; + + // use an array of string so that multiple calls won't collide + s = str[ index ]; + index = (index + 1) & 3; + + idStr::snPrintf( format, sizeof( format ), "%%.%df", precision ); + n = idStr::snPrintf( s, sizeof( str[0] ), format, array[0] ); + if ( precision > 0 ) { + while( n > 0 && s[n-1] == '0' ) s[--n] = '\0'; + while( n > 0 && s[n-1] == '.' ) s[--n] = '\0'; + } + idStr::snPrintf( format, sizeof( format ), " %%.%df", precision ); + for ( i = 1; i < length; i++ ) { + n += idStr::snPrintf( s + n, sizeof( str[0] ) - n, format, array[i] ); + if ( precision > 0 ) { + while( n > 0 && s[n-1] == '0' ) s[--n] = '\0'; + while( n > 0 && s[n-1] == '.' ) s[--n] = '\0'; + } + } + return s; +} + +/* +============ +idStr::Last + +returns -1 if not found otherwise the index of the char +============ +*/ +int idStr::Last( const char c ) const { + int i; + + for( i = Length(); i > 0; i-- ) { + if ( data[ i - 1 ] == c ) { + return i - 1; + } + } + + return -1; +} + +/* +============ +idStr::StripLeading +============ +*/ +void idStr::StripLeading( const char c ) { + // Tels: The string is zero-terminated, so exit if trying to remove zeros + if (c == 0x00) { + return; + } + // Tels: first count how many chars to remove, then move only once + int remove = 0; + while( data[ remove ] == c ) { + remove ++; + } + len -= remove; + // +1 to copy the 0x00 at the end + memmove( &data[ 0 ], &data[ remove ], len + 1 ); +} + +/* +============ +idStr::StripLeadingWhitespace +============ +*/ +void idStr::StripLeadingWhitespace( void ) { + // Tels: first count how many chars to remove, then move the data only once + int remove = 0; + // cast to unsigned char to prevent stripping off high-ASCII characters + while( (unsigned char)data[ remove ] <= ' ' ) { + remove ++; + } + len -= remove; + // +1 to copy the 0x00 at the end + memmove( &data[ 0 ], &data[ remove ], len + 1 ); +} +/* +============ +idStr::StripLeading +============ +*/ +void idStr::StripLeading( const char *string ) { + int l; + + l = strlen( string ); + if ( l > 0 ) { + while ( !Cmpn( string, l ) ) { + memmove( data, data + l, len - l + 1 ); + len -= l; + } + } +} + +/* +============ +idStr::StripLeadingOnce +============ +*/ +bool idStr::StripLeadingOnce( const char *string ) { + int l; + + l = strlen( string ); + if ( ( l > 0 ) && !Cmpn( string, l ) ) { + memmove( data, data + l, len - l + 1 ); + len -= l; + return true; + } + return false; +} + +/* +============ +idStr::StripTrailing +============ +*/ +void idStr::StripTrailing( const char c ) { + int i; + + for( i = Length(); i > 0 && data[ i - 1 ] == c; i-- ) { + data[ i - 1 ] = '\0'; + len--; + } +} + +/* +============ +idStr::StripLeading +============ +*/ +void idStr::StripTrailing( const char *string ) { + int l; + + l = strlen( string ); + if ( l > 0 ) { + while ( ( len >= l ) && !Cmpn( string, data + len - l, l ) ) { + len -= l; + data[len] = '\0'; + } + } +} + +/* +============ +idStr::StripTrailingOnce +============ +*/ +bool idStr::StripTrailingOnce( const char *string ) { + int l; + + l = strlen( string ); + if ( ( l > 0 ) && ( len >= l ) && !Cmpn( string, data + len - l, l ) ) { + len -= l; + data[len] = '\0'; + return true; + } + return false; +} + +/* +============ +idStr::Replace +============ +*/ +void idStr::Replace( const char *old, const char *nw ) { + int oldLen, newLen, i, j, count; + idStr oldString( data ); + + assert(old); + assert(nw); + + oldLen = strlen( old ); + newLen = strlen( nw ); + + // Work out how big the new string will be + count = 0; + for( i = 0; i < oldString.Length(); i++ ) { + if( !idStr::Cmpn( &oldString[i], old, oldLen ) ) { + count++; + i += oldLen - 1; + } + } + + if( count ) { + EnsureAlloced( len + ( ( newLen - oldLen ) * count ) + 2, false ); + + // Replace the old data with the new data + for( i = 0, j = 0; i < oldString.Length(); i++ ) { + if( !idStr::Cmpn( &oldString[i], old, oldLen ) ) { + memcpy( data + j, nw, newLen ); + i += oldLen - 1; + j += newLen; + } else { + data[j] = oldString[i]; + j++; + } + } + data[j] = 0; + len = strlen( data ); + } +} + +/* +============ +idStr::Replace +============ +*/ +void idStr::Replace( const char old, const char nw ) { + // cannot replace 0x00 or swap 0xXX to 0x00 + assert(old); + assert(nw); + + for( int i = 0; i < len; i++ ) { + if (data[i] == old) { data[i] = nw; } + } +} + +/* +============ +idStr::Mid +============ +*/ +const char *idStr::Mid( int start, int len, idStr &result ) const { + int i; + + result.Empty(); + + i = Length(); + if ( i == 0 || len <= 0 || start >= i ) { + return NULL; + } + + if ( start + len >= i ) { + len = i - start; + } + + result.Append( &data[ start ], len ); + return result; +} + +/* +============ +idStr::Mid +============ +*/ +idStr idStr::Mid( int start, int len ) const { + int i; + idStr result; + + i = Length(); + if ( i == 0 || len <= 0 || start >= i ) { + return result; + } + + if ( start + len >= i ) { + len = i - start; + } + + result.Append( &data[ start ], len ); + return result; +} + +/* +============ +idStr::StripTrailingWhitespace +============ +*/ +void idStr::StripTrailingWhitespace( void ) { + int i; + + // cast to unsigned char to prevent stripping off high-ASCII characters + for( i = Length(); i > 0 && (unsigned char)(data[ i - 1 ]) <= ' '; i-- ) { + data[ i - 1 ] = '\0'; + len--; + } +} + +/* +============ +idStr::StripQuotes + +Removes the quotes from the beginning and end of the string +============ +*/ +idStr& idStr::StripQuotes ( void ) +{ + if ( data[0] != '\"' ) + { + return *this; + } + + // Remove the trailing quote first + if ( data[len-1] == '\"' ) + { + data[len-1] = '\0'; + len--; + } + + // Strip the leading quote now + len--; + memmove( &data[ 0 ], &data[ 1 ], len ); + data[len] = '\0'; + + return *this; +} + +/* +===================================================================== + + filename methods + +===================================================================== +*/ + +/* +============ +idStr::FileNameHash +============ +*/ +int idStr::FileNameHash( void ) const { + int i; + long hash; + char letter; + + hash = 0; + i = 0; + while( data[i] != '\0' ) { + letter = idStr::ToLower( data[i] ); + if ( letter == '.' ) { + break; // don't include extension + } + if ( letter =='\\' ) { + letter = '/'; + } + hash += (long)(letter)*(i+119); + i++; + } + hash &= (FILE_HASH_SIZE-1); + return hash; +} + +/* +============ +idStr::BackSlashesToSlashes +============ +*/ +idStr &idStr::BackSlashesToSlashes( void ) { + int i; + + for ( i = 0; i < len; i++ ) { + if ( data[ i ] == '\\' ) { + data[ i ] = '/'; + } + } + return *this; +} + +/* +============ +idStr::SetFileExtension +============ +*/ +idStr &idStr::SetFileExtension( const char *extension ) { + StripFileExtension(); + if ( *extension != '.' ) { + Append( '.' ); + } + Append( extension ); + return *this; +} + +/* +============ +idStr::StripFileExtension +============ +*/ +idStr &idStr::StripFileExtension( void ) { + int i; + + for ( i = len-1; i >= 0; i-- ) { + if ( data[i] == '.' ) { + data[i] = '\0'; + len = i; + break; + } + } + return *this; +} + +/* +============ +idStr::StripAbsoluteFileExtension +============ +*/ +idStr &idStr::StripAbsoluteFileExtension( void ) { + int i; + + for ( i = 0; i < len; i++ ) { + if ( data[i] == '.' ) { + data[i] = '\0'; + len = i; + break; + } + } + + return *this; +} + +/* +================== +idStr::DefaultFileExtension +================== +*/ +idStr &idStr::DefaultFileExtension( const char *extension ) { + int i; + + // do nothing if the string already has an extension + for ( i = len-1; i >= 0; i-- ) { + if ( data[i] == '.' ) { + return *this; + } + } + if ( *extension != '.' ) { + Append( '.' ); + } + Append( extension ); + return *this; +} + +/* +================== +idStr::DefaultPath +================== +*/ +idStr &idStr::DefaultPath( const char *basepath ) { + if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) { + // absolute path location + return *this; + } + + *this = basepath + *this; + return *this; +} + +/* +==================== +idStr::AppendPath +==================== +*/ +void idStr::AppendPath( const char *text ) { + int pos; + int i = 0; + + if ( text && text[i] ) { + pos = len; + EnsureAlloced( len + strlen( text ) + 2 ); + + if ( pos ) { + if ( data[ pos-1 ] != '/' ) { + data[ pos++ ] = '/'; + } + } + if ( text[i] == '/' ) { + i++; + } + + for ( ; text[ i ]; i++ ) { + if ( text[ i ] == '\\' ) { + data[ pos++ ] = '/'; + } else { + data[ pos++ ] = text[ i ]; + } + } + len = pos; + data[ pos ] = '\0'; + } +} + +/* +================== +idStr::StripFilename +================== +*/ +idStr &idStr::StripFilename( void ) { + int pos; + + pos = Length() - 1; + while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) { + pos--; + } + + if ( pos < 0 ) { + pos = 0; + } + + CapLength( pos ); + return *this; +} + +/* +================== +idStr::StripPath +================== +*/ +idStr &idStr::StripPath( void ) { + int pos; + + pos = Length(); + while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { + pos--; + } + + *this = Right( Length() - pos ); + return *this; +} + +/* +==================== +idStr::ExtractFilePath +==================== +*/ +void idStr::ExtractFilePath( idStr &dest ) const { + int pos; + + // + // back up until a \ or the start + // + pos = Length(); + while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { + pos--; + } + + Left( pos, dest ); +} + +/* +==================== +idStr::ExtractFileName +==================== +*/ +void idStr::ExtractFileName( idStr &dest ) const { + int pos; + + // + // back up until a \ or the start + // + pos = Length() - 1; + while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { + pos--; + } + + Right( Length() - pos, dest ); +} + +/* +==================== +idStr::ExtractFileBase +==================== +*/ +void idStr::ExtractFileBase( idStr &dest ) const { + int pos; + int start; + + // + // back up until a \ or the start + // + pos = Length() - 1; + while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { + pos--; + } + + start = pos; + while( ( pos < Length() ) && ( ( *this )[ pos ] != '.' ) ) { + pos++; + } + + Mid( start, pos - start, dest ); +} + +/* +==================== +idStr::ExtractFileExtension +==================== +*/ +void idStr::ExtractFileExtension( idStr &dest ) const { + int pos; + + // + // back up until a . or the start + // + pos = Length() - 1; + while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '.' ) ) { + pos--; + } + + if ( !pos ) { + // no extension + dest.Empty(); + } else { + Right( Length() - pos, dest ); + } +} + + +/* +===================================================================== + + char * methods to replace library functions + +===================================================================== +*/ + +/* +============ +idStr::IsNumeric + +Checks a string to see if it contains only numerical values. +============ +*/ +bool idStr::IsNumeric( const char *s ) { + int i; + bool dot; + + if ( *s == '-' ) { + s++; + } + + dot = false; + for ( i = 0; s[i]; i++ ) { + if ( !isdigit( s[i] ) ) { + if ( ( s[ i ] == '.' ) && !dot ) { + dot = true; + continue; + } + return false; + } + } + + return true; +} + +/* +============ +idStr::HasLower + +Checks if a string has any lowercase chars +============ +*/ +bool idStr::HasLower( const char *s ) { + if ( !s ) { + return false; + } + + while ( *s ) { + if ( CharIsLower( *s ) ) { + return true; + } + s++; + } + + return false; +} + +/* +============ +idStr::HasUpper + +Checks if a string has any uppercase chars +============ +*/ +bool idStr::HasUpper( const char *s ) { + if ( !s ) { + return false; + } + + while ( *s ) { + if ( CharIsUpper( *s ) ) { + return true; + } + s++; + } + + return false; +} + +/* +================ +idStr::Cmp +================ +*/ +int idStr::Cmp( const char *s1, const char *s2 ) { + int c1, c2, d; + + do { + c1 = *s1++; + c2 = *s2++; + + d = c1 - c2; + if ( d ) { + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; // strings are equal +} + +/* +================ +idStr::Cmpn +================ +*/ +int idStr::Cmpn( const char *s1, const char *s2, int n ) { + int c1, c2, d; + + assert( n >= 0 ); + + do { + c1 = *s1++; + c2 = *s2++; + + if ( !n-- ) { + return 0; // strings are equal until end point + } + + d = c1 - c2; + if ( d ) { + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; // strings are equal +} + +/* +================ +idStr::Icmp +================ +*/ +int idStr::Icmp( const char *s1, const char *s2 ) { + int c1, c2, d; + + do { + c1 = *s1++; + c2 = *s2++; + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; // strings are equal +} + +/* +================ +idStr::Icmpn +================ +*/ +int idStr::Icmpn( const char *s1, const char *s2, int n ) { + int c1, c2, d; + + assert( n >= 0 ); + + do { + c1 = *s1++; + c2 = *s2++; + + if ( !n-- ) { + return 0; // strings are equal until end point + } + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; // strings are equal +} + +/* +================ +idStr::Icmp +================ +*/ +int idStr::IcmpNoColor( const char *s1, const char *s2 ) { + int c1, c2, d; + + do { + while ( idStr::IsColor( s1 ) ) { + s1 += 2; + } + while ( idStr::IsColor( s2 ) ) { + s2 += 2; + } + c1 = *s1++; + c2 = *s2++; + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; // strings are equal +} + +/* +================ +idStr::IcmpPath +================ +*/ +int idStr::IcmpPath( const char *s1, const char *s2 ) { + int c1, c2, d; + +#if 0 +//#if !defined( _WIN32 ) + idLib::common->Printf( "WARNING: IcmpPath used on a case-sensitive filesystem?\n" ); +#endif + + do { + c1 = *s1++; + c2 = *s2++; + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c1 == '\\' ) { + d += ('/' - '\\'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 == '\\' ) { + d -= ('/' - '\\'); + if ( !d ) { + break; + } + } + // make sure folders come first + while( c1 ) { + if ( c1 == '/' || c1 == '\\' ) { + break; + } + c1 = *s1++; + } + while( c2 ) { + if ( c2 == '/' || c2 == '\\' ) { + break; + } + c2 = *s2++; + } + if ( c1 && !c2 ) { + return -1; + } else if ( !c1 && c2 ) { + return 1; + } + // same folder depth so use the regular compare + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; +} + +/* +================ +idStr::IcmpnPath +================ +*/ +int idStr::IcmpnPath( const char *s1, const char *s2, int n ) { + int c1, c2, d; + +#if 0 +//#if !defined( _WIN32 ) + idLib::common->Printf( "WARNING: IcmpPath used on a case-sensitive filesystem?\n" ); +#endif + + assert( n >= 0 ); + + do { + c1 = *s1++; + c2 = *s2++; + + if ( !n-- ) { + return 0; // strings are equal until end point + } + + d = c1 - c2; + while( d ) { + if ( c1 <= 'Z' && c1 >= 'A' ) { + d += ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c1 == '\\' ) { + d += ('/' - '\\'); + if ( !d ) { + break; + } + } + if ( c2 <= 'Z' && c2 >= 'A' ) { + d -= ('a' - 'A'); + if ( !d ) { + break; + } + } + if ( c2 == '\\' ) { + d -= ('/' - '\\'); + if ( !d ) { + break; + } + } + // make sure folders come first + while( c1 ) { + if ( c1 == '/' || c1 == '\\' ) { + break; + } + c1 = *s1++; + } + while( c2 ) { + if ( c2 == '/' || c2 == '\\' ) { + break; + } + c2 = *s2++; + } + if ( c1 && !c2 ) { + return -1; + } else if ( !c1 && c2 ) { + return 1; + } + // same folder depth so use the regular compare + return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; + } + } while( c1 ); + + return 0; +} + +/* +============= +idStr::Copynz + +Safe strncpy that ensures a trailing zero +============= +*/ +void idStr::Copynz( char *dest, const char *src, int destsize ) { + if ( !src ) { + idLib::common->Warning( "idStr::Copynz: NULL src" ); + return; + } + if ( destsize < 1 ) { + idLib::common->Warning( "idStr::Copynz: destsize < 1" ); + return; + } + + strncpy( dest, src, destsize-1 ); + dest[destsize-1] = 0; +} + +/* +================ +idStr::Append + + never goes past bounds or leaves without a terminating 0 +================ +*/ +void idStr::Append( char *dest, int size, const char *src ) { + int l1; + + l1 = strlen( dest ); + if ( l1 >= size ) { + idLib::common->Error( "idStr::Append: already overflowed" ); + } + idStr::Copynz( dest + l1, src, size - l1 ); +} + +/* +================ +idStr::LengthWithoutColors +================ +*/ +int idStr::LengthWithoutColors( const char *s ) { + int len; + const char *p; + + if ( !s ) { + return 0; + } + + len = 0; + p = s; + while( *p ) { + if ( idStr::IsColor( p ) ) { + p += 2; + continue; + } + p++; + len++; + } + + return len; +} + +/* +================ +idStr::RemoveColors +================ +*/ +char *idStr::RemoveColors( char *string ) { + char *d; + char *s; + int c; + + s = string; + d = string; + while( (c = *s) != 0 ) { + if ( idStr::IsColor( s ) ) { + s++; + } + else { + *d++ = c; + } + s++; + } + *d = '\0'; + + return string; +} + +/* +================ +idStr::snPrintf +================ +*/ +int idStr::snPrintf( char *dest, int size, const char *fmt, ...) { + int len; + va_list argptr; + char buffer[32000]; // big, but small enough to fit in PPC stack + + va_start( argptr, fmt ); + len = vsprintf( buffer, fmt, argptr ); + va_end( argptr ); + if ( len >= sizeof( buffer ) ) { + idLib::common->Error( "idStr::snPrintf: overflowed buffer" ); + } + if ( len >= size ) { + idLib::common->Warning( "idStr::snPrintf: overflow of %i in %i\n", len, size ); + len = size; + } + idStr::Copynz( dest, buffer, size ); + return len; +} + +/* +============ +idStr::vsnPrintf + +vsnprintf portability: + +C99 standard: vsnprintf returns the number of characters (excluding the trailing +'\0') which would have been written to the final string if enough space had been available +snprintf and vsnprintf do not write more than size bytes (including the trailing '\0') + +win32: _vsnprintf returns the number of characters written, not including the terminating null character, +or a negative value if an output error occurs. If the number of characters to write exceeds count, then count +characters are written and -1 is returned and no trailing '\0' is added. + +idStr::vsnPrintf: always appends a trailing '\0', returns number of characters written (not including terminal \0) +or returns -1 on failure or if the buffer would be overflowed. +============ +*/ +int idStr::vsnPrintf( char *dest, int size, const char *fmt, va_list argptr ) { + int ret; + +#ifdef _WIN32 +#undef _vsnprintf + ret = _vsnprintf( dest, size-1, fmt, argptr ); +#define _vsnprintf use_idStr_vsnPrintf +#else +#undef vsnprintf + ret = vsnprintf( dest, size, fmt, argptr ); +#define vsnprintf use_idStr_vsnPrintf +#endif + dest[size-1] = '\0'; + if ( ret < 0 || ret >= size ) { + return -1; + } + return ret; +} + +/* +============ +sprintf + +Sets the value of the string using a printf interface. +============ +*/ +int sprintf( idStr &string, const char *fmt, ... ) { + int l; + va_list argptr; + char buffer[32000]; + + va_start( argptr, fmt ); + l = idStr::vsnPrintf( buffer, sizeof(buffer)-1, fmt, argptr ); + va_end( argptr ); + buffer[sizeof(buffer)-1] = '\0'; + + string = buffer; + return l; +} + +/* +============ +vsprintf + +Sets the value of the string using a vprintf interface. +============ +*/ +int vsprintf( idStr &string, const char *fmt, va_list argptr ) { + int l; + char buffer[32000]; + + l = idStr::vsnPrintf( buffer, sizeof(buffer)-1, fmt, argptr ); + buffer[sizeof(buffer)-1] = '\0'; + + string = buffer; + return l; +} + +/* +============ +va + +does a varargs printf into a temp buffer +NOTE: not thread safe +============ +*/ +char *va( const char *fmt, ... ) { + va_list argptr; + static int index = 0; + static char string[4][16384]; // in case called by nested functions + char *buf; + + buf = string[index]; + index = (index + 1) & 3; + + va_start( argptr, fmt ); + vsprintf( buf, fmt, argptr ); + va_end( argptr ); + + return buf; +} + + + +/* +============ +idStr::BestUnit +============ +*/ +int idStr::BestUnit( const char *format, float value, Measure_t measure ) { + int unit = 1; + while ( unit <= 3 && ( 1 << ( unit * 10 ) < value ) ) { + unit++; + } + unit--; + value /= 1 << ( unit * 10 ); + sprintf( *this, format, value ); + *this += " "; + *this += units[ measure ][ unit ]; + return unit; +} + +/* +============ +idStr::SetUnit +============ +*/ +void idStr::SetUnit( const char *format, float value, int unit, Measure_t measure ) { + value /= 1 << ( unit * 10 ); + sprintf( *this, format, value ); + *this += " "; + *this += units[ measure ][ unit ]; +} + +/* +================ +idStr::InitMemory +================ +*/ +void idStr::InitMemory( void ) { +#ifdef USE_STRING_DATA_ALLOCATOR + stringDataAllocator.Init(); +#endif +} + +/* +================ +idStr::ShutdownMemory +================ +*/ +void idStr::ShutdownMemory( void ) { +#ifdef USE_STRING_DATA_ALLOCATOR + stringDataAllocator.Shutdown(); +#endif +} + +/* +================ +idStr::PurgeMemory +================ +*/ +void idStr::PurgeMemory( void ) { +#ifdef USE_STRING_DATA_ALLOCATOR + stringDataAllocator.FreeEmptyBaseBlocks(); +#endif +} + +/* +================ +idStr::ShowMemoryUsage_f +================ +*/ +void idStr::ShowMemoryUsage_f( const idCmdArgs &args ) { +#ifdef USE_STRING_DATA_ALLOCATOR + idLib::common->Printf( "%6d KB string memory (%d KB free in %d blocks, %d empty base blocks)\n", + stringDataAllocator.GetBaseBlockMemory() >> 10, stringDataAllocator.GetFreeBlockMemory() >> 10, + stringDataAllocator.GetNumFreeBlocks(), stringDataAllocator.GetNumEmptyBaseBlocks() ); +#endif +} + +/* +================ +idStr::FormatNumber +================ +*/ +struct formatList_t { + int gran; + int count; +}; + +// elements of list need to decend in size +formatList_t formatList[] = { + { 1000000000, 0 }, + { 1000000, 0 }, + { 1000, 0 } +}; + +int numFormatList = sizeof(formatList) / sizeof( formatList[0] ); + + +idStr idStr::FormatNumber( int number ) { + idStr string; + bool hit; + + // reset + for ( int i = 0; i < numFormatList; i++ ) { + formatList_t *li = formatList + i; + li->count = 0; + } + + // main loop + do { + hit = false; + + for ( int i = 0; i < numFormatList; i++ ) { + formatList_t *li = formatList + i; + + if ( number >= li->gran ) { + li->count++; + number -= li->gran; + hit = true; + break; + } + } + } while ( hit ); + + // print out + bool found = false; + + for ( int i = 0; i < numFormatList; i++ ) { + formatList_t *li = formatList + i; + + if ( li->count ) { + if ( !found ) { + string += va( "%i,", li->count ); + } else { + string += va( "%3.3i,", li->count ); + } + found = true; + } + else if ( found ) { + string += va( "%3.3i,", li->count ); + } + } + + if ( found ) { + string += va( "%3.3i", number ); + } + else { + string += va( "%i", number ); + } + + // pad to proper size + int count = 11 - string.Length(); + + for ( int i = 0; i < count; i++ ) { + string.Insert( " ", 0 ); + } + + return string; +} + diff --git a/idlib/Str.h b/idlib/Str.h new file mode 100644 index 000000000..41694958b --- /dev/null +++ b/idlib/Str.h @@ -0,0 +1,1022 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STR_H__ +#define __STR_H__ + +#ifdef __linux__ +#include +#endif + +/* +=============================================================================== + + Character string + +=============================================================================== +*/ + +class idVec4; + +#ifndef FILE_HASH_SIZE +#define FILE_HASH_SIZE 1024 +#endif + +// color escape character +const int C_COLOR_ESCAPE = '^'; +const int C_COLOR_DEFAULT = '0'; +const int C_COLOR_RED = '1'; +const int C_COLOR_GREEN = '2'; +const int C_COLOR_YELLOW = '3'; +const int C_COLOR_BLUE = '4'; +const int C_COLOR_CYAN = '5'; +const int C_COLOR_MAGENTA = '6'; +const int C_COLOR_WHITE = '7'; +const int C_COLOR_GRAY = '8'; +const int C_COLOR_BLACK = '9'; + +// color escape string +#define S_COLOR_DEFAULT "^0" +#define S_COLOR_RED "^1" +#define S_COLOR_GREEN "^2" +#define S_COLOR_YELLOW "^3" +#define S_COLOR_BLUE "^4" +#define S_COLOR_CYAN "^5" +#define S_COLOR_MAGENTA "^6" +#define S_COLOR_WHITE "^7" +#define S_COLOR_GRAY "^8" +#define S_COLOR_BLACK "^9" + +// make idStr a multiple of 32 bytes long +// don't make too large to keep memory requirements to a minimum +const int STR_ALLOC_BASE = 20; +const int STR_ALLOC_GRAN = 32; + +typedef enum { + MEASURE_SIZE = 0, + MEASURE_BANDWIDTH +} Measure_t; + +class idStr { + +public: + idStr( void ); + idStr( const idStr &text ); + idStr( const idStr &text, int start, int end ); + idStr( const char *text ); + idStr( const char *text, int start, int end ); + explicit idStr( const bool b ); + explicit idStr( const char c ); + explicit idStr( const int i ); + explicit idStr( const unsigned u ); + explicit idStr( const float f ); + ~idStr( void ); + + size_t Size( void ) const; + const char * c_str( void ) const; + operator const char *( void ) const; + operator const char *( void ); + + char operator[]( int index ) const; + char & operator[]( int index ); + + void operator=( const idStr &text ); + void operator=( const char *text ); + + friend idStr operator+( const idStr &a, const idStr &b ); + friend idStr operator+( const idStr &a, const char *b ); + friend idStr operator+( const char *a, const idStr &b ); + + friend idStr operator+( const idStr &a, const float b ); + friend idStr operator+( const idStr &a, const int b ); + friend idStr operator+( const idStr &a, const unsigned b ); + friend idStr operator+( const idStr &a, const bool b ); + friend idStr operator+( const idStr &a, const char b ); + + idStr & operator+=( const idStr &a ); + idStr & operator+=( const char *a ); + idStr & operator+=( const float a ); + idStr & operator+=( const char a ); + idStr & operator+=( const int a ); + idStr & operator+=( const unsigned a ); + idStr & operator+=( const bool a ); + + // case sensitive compare + friend bool operator==( const idStr &a, const idStr &b ); + friend bool operator==( const idStr &a, const char *b ); + friend bool operator==( const char *a, const idStr &b ); + + // case sensitive compare + friend bool operator!=( const idStr &a, const idStr &b ); + friend bool operator!=( const idStr &a, const char *b ); + friend bool operator!=( const char *a, const idStr &b ); + + // case sensitive compare + int Cmp( const char *text ) const; + int Cmpn( const char *text, int n ) const; + int CmpPrefix( const char *text ) const; + + // case insensitive compare + int Icmp( const char *text ) const; + int Icmpn( const char *text, int n ) const; + int IcmpPrefix( const char *text ) const; + + // case insensitive compare ignoring color + int IcmpNoColor( const char *text ) const; + + // compares paths and makes sure folders come first + int IcmpPath( const char *text ) const; + int IcmpnPath( const char *text, int n ) const; + int IcmpPrefixPath( const char *text ) const; + + int Length( void ) const; + int Allocated( void ) const; + void Empty( void ); + bool IsEmpty( void ) const; + void Clear( void ); + void Append( const char a ); + void Append( const idStr &text ); + void Append( const char *text ); + void Append( const char *text, int len ); + void Insert( const char a, int index ); + void Insert( const char *text, int index ); + void ToLower( void ); + void ToUpper( void ); + bool IsNumeric( void ) const; + bool IsColor( void ) const; + bool HasLower( void ) const; + bool HasUpper( void ) const; + int LengthWithoutColors( void ) const; + idStr & RemoveColors( void ); + void CapLength( int ); + void Fill( const char ch, int newlen ); + + // returns -1 if not found otherwise the index of the char + int Find( const char c, int start = 0, int end = -1 ) const; + int Find( const char *text, bool casesensitive = true, int start = 0, int end = -1 ) const; + // Tels: Count how often c occurs between start and end + int Count( const char c, int start = 0, int end = -1 ) const; + // Tels: Given a list like "abcXdef" (where X = ',' but can be changed), returns one part of it randomly. + // Needs to be given a random value between 0.0 < x <= 1.0 + idStr RandomPart(const float rand, const char c = ',') const; + bool Filter( const char *filter, bool casesensitive ) const; + int Last( const char c ) const; // return the index to the last occurance of 'c', returns -1 if not found + const char * Left( int len, idStr &result ) const; // store the leftmost 'len' characters in the result + const char * Right( int len, idStr &result ) const; // store the rightmost 'len' characters in the result + const char * Mid( int start, int len, idStr &result ) const; // store 'len' characters starting at 'start' in result + idStr Left( int len ) const; // return the leftmost 'len' characters + idStr Right( int len ) const; // return the rightmost 'len' characters + idStr Mid( int start, int len ) const; // return 'len' characters starting at 'start' + void StripLeading( const char c ); // strip char from front as many times as the char occurs + void StripLeading( const char *string ); // strip string from front as many times as the string occurs + bool StripLeadingOnce( const char *string ); // strip string from front just once if it occurs + void StripLeadingWhitespace( void ); // tels: strip leading white space characters (c <= 0x20) + void StripTrailing( const char c ); // strip char from end as many times as the char occurs + void StripTrailing( const char *string ); // strip string from end as many times as the string occurs + bool StripTrailingOnce( const char *string ); // strip string from end just once if it occurs + void Strip( const char c ); // strip char from front and end as many times as the char occurs + void Strip( const char *string ); // strip string from front and end as many times as the string occurs + void StripTrailingWhitespace( void ); // strip trailing white space characters (c <= 0x20) + idStr & StripQuotes( void ); // strip quotes around string + void Replace( const char *old, const char *nw ); + void Replace( const char old, const char nw ); // faster version of Repace() if you want to swap only one char + + // file name methods + int FileNameHash( void ) const; // hash key for the filename (skips extension) + idStr & BackSlashesToSlashes( void ); // convert slashes + idStr & SetFileExtension( const char *extension ); // set the given file extension + idStr & StripFileExtension( void ); // remove any file extension + idStr & StripAbsoluteFileExtension( void ); // remove any file extension looking from front (useful if there are multiple .'s) + idStr & DefaultFileExtension( const char *extension ); // if there's no file extension use the default + idStr & DefaultPath( const char *basepath ); // if there's no path use the default + void AppendPath( const char *text ); // append a partial path + idStr & StripFilename( void ); // remove the filename from a path + idStr & StripPath( void ); // remove the path from the filename + void ExtractFilePath( idStr &dest ) const; // copy the file path to another string + void ExtractFileName( idStr &dest ) const; // copy the filename to another string + void ExtractFileBase( idStr &dest ) const; // copy the filename minus the extension to another string + void ExtractFileExtension( idStr &dest ) const; // copy the file extension to another string + bool CheckExtension( const char *ext ); + + // char * methods to replace library functions + static int Length( const char *s ); + static char * ToLower( char *s ); + static char * ToUpper( char *s ); + static bool IsNumeric( const char *s ); + static bool IsColor( const char *s ); + static bool HasLower( const char *s ); + static bool HasUpper( const char *s ); + static int LengthWithoutColors( const char *s ); + static char * RemoveColors( char *s ); + static int Cmp( const char *s1, const char *s2 ); + static int Cmpn( const char *s1, const char *s2, int n ); + static int Icmp( const char *s1, const char *s2 ); + static int Icmpn( const char *s1, const char *s2, int n ); + static int IcmpNoColor( const char *s1, const char *s2 ); + static int IcmpPath( const char *s1, const char *s2 ); // compares paths and makes sure folders come first + static int IcmpnPath( const char *s1, const char *s2, int n ); // compares paths and makes sure folders come first + static void Append( char *dest, int size, const char *src ); + static void Copynz( char *dest, const char *src, int destsize ); + static int snPrintf( char *dest, int size, const char *fmt, ... ) id_attribute((format(printf,3,4))); + static int vsnPrintf( char *dest, int size, const char *fmt, va_list argptr ); + // returns -1 if not found otherwise the index of the char + static int FindChar( const char *str, const char c, int start = 0, int end = -1 ); + static int CountChar( const char *str, const char c, int start = 0, int end = -1 ); + static int FindText( const char *str, const char *text, bool casesensitive = true, int start = 0, int end = -1 ); + static bool Filter( const char *filter, const char *name, bool casesensitive ); + static void StripMediaName( const char *name, idStr &mediaName ); + static bool CheckExtension( const char *name, const char *ext ); + static const char * FloatArrayToString( const float *array, const int length, const int precision ); + + // hash keys + static int Hash( const char *string ); + static int Hash( const char *string, int length ); + static int IHash( const char *string ); // case insensitive + static int IHash( const char *string, int length ); // case insensitive + + // character methods + static char ToLower( char c ); + static char ToUpper( char c ); + static bool CharIsPrintable( int c ); + static bool CharIsLower( int c ); + static bool CharIsUpper( int c ); + static bool CharIsAlpha( int c ); + static bool CharIsNumeric( int c ); + static bool CharIsNewLine( char c ); + static bool CharIsTab( char c ); + static int ColorIndex( int c ); + static idVec4 & ColorForIndex( int i ); + + friend int sprintf( idStr &dest, const char *fmt, ... ); + friend int vsprintf( idStr &dest, const char *fmt, va_list ap ); + + void ReAllocate( int amount, bool keepold ); // reallocate string data buffer + void FreeData( void ); // free allocated string memory + + // format value in the given measurement with the best unit, returns the best unit + int BestUnit( const char *format, float value, Measure_t measure ); + // format value in the requested unit and measurement + void SetUnit( const char *format, float value, int unit, Measure_t measure ); + + static void InitMemory( void ); + static void ShutdownMemory( void ); + static void PurgeMemory( void ); + static void ShowMemoryUsage_f( const idCmdArgs &args ); + + int DynamicMemoryUsed() const; + static idStr FormatNumber( int number ); + +protected: + int len; + char * data; + int alloced; + char baseBuffer[ STR_ALLOC_BASE ]; + + void Init( void ); // initialize string using base buffer + void EnsureAlloced( int amount, bool keepold = true ); // ensure string data buffer is large anough +}; + +char * va( const char *fmt, ... ) id_attribute((format(printf,1,2))); + + +ID_INLINE void idStr::EnsureAlloced( int amount, bool keepold ) { + if ( amount > alloced ) { + ReAllocate( amount, keepold ); + } +} + +ID_INLINE void idStr::Init( void ) { + len = 0; + alloced = STR_ALLOC_BASE; + data = baseBuffer; + data[ 0 ] = '\0'; +#ifdef ID_DEBUG_UNINITIALIZED_MEMORY + memset( baseBuffer, 0, sizeof( baseBuffer ) ); +#endif +} + +ID_INLINE idStr::idStr( void ) { + Init(); +} + +ID_INLINE idStr::idStr( const idStr &text ) { + int l; + + Init(); + l = text.Length(); + EnsureAlloced( l + 1 ); + strcpy( data, text.data ); + len = l; +} + +ID_INLINE idStr::idStr( const idStr &text, int start, int end ) { + int i; + int l; + + Init(); + if ( end > text.Length() ) { + end = text.Length(); + } + if ( start > text.Length() ) { + start = text.Length(); + } else if ( start < 0 ) { + start = 0; + } + + l = end - start; + if ( l < 0 ) { + l = 0; + } + + EnsureAlloced( l + 1 ); + + for ( i = 0; i < l; i++ ) { + data[ i ] = text[ start + i ]; + } + + data[ l ] = '\0'; + len = l; +} + +ID_INLINE idStr::idStr( const char *text ) { + int l; + + Init(); + if ( text ) { + l = strlen( text ); + EnsureAlloced( l + 1 ); + strcpy( data, text ); + len = l; + } +} + +ID_INLINE idStr::idStr( const char *text, int start, int end ) { + int i; + int l = strlen( text ); + + Init(); + if ( end > l ) { + end = l; + } + if ( start > l ) { + start = l; + } else if ( start < 0 ) { + start = 0; + } + + l = end - start; + if ( l < 0 ) { + l = 0; + } + + EnsureAlloced( l + 1 ); + + for ( i = 0; i < l; i++ ) { + data[ i ] = text[ start + i ]; + } + + data[ l ] = '\0'; + len = l; +} + +ID_INLINE idStr::idStr( const bool b ) { + Init(); + EnsureAlloced( 2 ); + data[ 0 ] = b ? '1' : '0'; + data[ 1 ] = '\0'; + len = 1; +} + +ID_INLINE idStr::idStr( const char c ) { + Init(); + EnsureAlloced( 2 ); + data[ 0 ] = c; + data[ 1 ] = '\0'; + len = 1; +} + +ID_INLINE idStr::idStr( const int i ) { + char text[ 64 ]; + int l; + + Init(); + l = sprintf( text, "%d", i ); + EnsureAlloced( l + 1 ); + strcpy( data, text ); + len = l; +} + +ID_INLINE idStr::idStr( const unsigned u ) { + char text[ 64 ]; + int l; + + Init(); + l = sprintf( text, "%u", u ); + EnsureAlloced( l + 1 ); + strcpy( data, text ); + len = l; +} + +ID_INLINE idStr::idStr( const float f ) { + char text[ 64 ]; + int l; + + Init(); + l = idStr::snPrintf( text, sizeof( text ), "%f", f ); + while( l > 0 && text[l-1] == '0' ) text[--l] = '\0'; + while( l > 0 && text[l-1] == '.' ) text[--l] = '\0'; + EnsureAlloced( l + 1 ); + strcpy( data, text ); + len = l; +} + +ID_INLINE idStr::~idStr( void ) { + FreeData(); +} + +ID_INLINE size_t idStr::Size( void ) const { + return sizeof( *this ) + Allocated(); +} + +ID_INLINE const char *idStr::c_str( void ) const { + return data; +} + +ID_INLINE idStr::operator const char *( void ) { + return c_str(); +} + +ID_INLINE idStr::operator const char *( void ) const { + return c_str(); +} + +ID_INLINE char idStr::operator[]( int index ) const { + assert( ( index >= 0 ) && ( index <= len ) ); + return data[ index ]; +} + +ID_INLINE char &idStr::operator[]( int index ) { + assert( ( index >= 0 ) && ( index <= len ) ); + return data[ index ]; +} + +ID_INLINE void idStr::operator=( const idStr &text ) { + int l; + + l = text.Length(); + EnsureAlloced( l + 1, false ); + memcpy( data, text.data, l ); + data[l] = '\0'; + len = l; +} + +ID_INLINE idStr operator+( const idStr &a, const idStr &b ) { + idStr result( a ); + result.Append( b ); + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const char *b ) { + idStr result( a ); + result.Append( b ); + return result; +} + +ID_INLINE idStr operator+( const char *a, const idStr &b ) { + idStr result( a ); + result.Append( b ); + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const bool b ) { + idStr result( a ); + result.Append( b ? "true" : "false" ); + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const char b ) { + idStr result( a ); + result.Append( b ); + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const float b ) { + char text[ 64 ]; + idStr result( a ); + + sprintf( text, "%f", b ); + result.Append( text ); + + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const int b ) { + char text[ 64 ]; + idStr result( a ); + + sprintf( text, "%d", b ); + result.Append( text ); + + return result; +} + +ID_INLINE idStr operator+( const idStr &a, const unsigned b ) { + char text[ 64 ]; + idStr result( a ); + + sprintf( text, "%u", b ); + result.Append( text ); + + return result; +} + +ID_INLINE idStr &idStr::operator+=( const float a ) { + char text[ 64 ]; + + sprintf( text, "%f", a ); + Append( text ); + + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const int a ) { + char text[ 64 ]; + + sprintf( text, "%d", a ); + Append( text ); + + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const unsigned a ) { + char text[ 64 ]; + + sprintf( text, "%u", a ); + Append( text ); + + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const idStr &a ) { + Append( a ); + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const char *a ) { + Append( a ); + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const char a ) { + Append( a ); + return *this; +} + +ID_INLINE idStr &idStr::operator+=( const bool a ) { + Append( a ? "true" : "false" ); + return *this; +} + +ID_INLINE bool operator==( const idStr &a, const idStr &b ) { + return ( !idStr::Cmp( a.data, b.data ) ); +} + +ID_INLINE bool operator==( const idStr &a, const char *b ) { + assert( b ); + return ( !idStr::Cmp( a.data, b ) ); +} + +ID_INLINE bool operator==( const char *a, const idStr &b ) { + assert( a ); + return ( !idStr::Cmp( a, b.data ) ); +} + +ID_INLINE bool operator!=( const idStr &a, const idStr &b ) { + return !( a == b ); +} + +ID_INLINE bool operator!=( const idStr &a, const char *b ) { + return !( a == b ); +} + +ID_INLINE bool operator!=( const char *a, const idStr &b ) { + return !( a == b ); +} + +ID_INLINE int idStr::Cmp( const char *text ) const { + assert( text ); + return idStr::Cmp( data, text ); +} + +ID_INLINE int idStr::Cmpn( const char *text, int n ) const { + assert( text ); + return idStr::Cmpn( data, text, n ); +} + +ID_INLINE int idStr::CmpPrefix( const char *text ) const { + assert( text ); + return idStr::Cmpn( data, text, strlen( text ) ); +} + +ID_INLINE int idStr::Icmp( const char *text ) const { + assert( text ); + return idStr::Icmp( data, text ); +} + +ID_INLINE int idStr::Icmpn( const char *text, int n ) const { + assert( text ); + return idStr::Icmpn( data, text, n ); +} + +ID_INLINE int idStr::IcmpPrefix( const char *text ) const { + assert( text ); + return idStr::Icmpn( data, text, strlen( text ) ); +} + +ID_INLINE int idStr::IcmpNoColor( const char *text ) const { + assert( text ); + return idStr::IcmpNoColor( data, text ); +} + +ID_INLINE int idStr::IcmpPath( const char *text ) const { + assert( text ); + return idStr::IcmpPath( data, text ); +} + +ID_INLINE int idStr::IcmpnPath( const char *text, int n ) const { + assert( text ); + return idStr::IcmpnPath( data, text, n ); +} + +ID_INLINE int idStr::IcmpPrefixPath( const char *text ) const { + assert( text ); + return idStr::IcmpnPath( data, text, strlen( text ) ); +} + +ID_INLINE int idStr::Length( void ) const { + return len; +} + +ID_INLINE int idStr::Allocated( void ) const { + if ( data != baseBuffer ) { + return alloced; + } else { + return 0; + } +} + +ID_INLINE void idStr::Empty( void ) { + EnsureAlloced( 1 ); + data[ 0 ] = '\0'; + len = 0; +} + +ID_INLINE bool idStr::IsEmpty( void ) const { + return ( idStr::Cmp( data, "" ) == 0 ); +} + +ID_INLINE void idStr::Clear( void ) { + FreeData(); + Init(); +} + +ID_INLINE void idStr::Append( const char a ) { + EnsureAlloced( len + 2 ); + data[ len ] = a; + len++; + data[ len ] = '\0'; +} + +ID_INLINE void idStr::Append( const idStr &text ) { + int newLen; + int i; + + newLen = len + text.Length(); + EnsureAlloced( newLen + 1 ); + for ( i = 0; i < text.len; i++ ) { + data[ len + i ] = text[ i ]; + } + len = newLen; + data[ len ] = '\0'; +} + +ID_INLINE void idStr::Append( const char *text ) { + int newLen; + int i; + + if ( text ) { + newLen = len + strlen( text ); + EnsureAlloced( newLen + 1 ); + for ( i = 0; text[ i ]; i++ ) { + data[ len + i ] = text[ i ]; + } + len = newLen; + data[ len ] = '\0'; + } +} + +ID_INLINE void idStr::Append( const char *text, int l ) { + int newLen; + int i; + + if ( text && l ) { + newLen = len + l; + EnsureAlloced( newLen + 1 ); + for ( i = 0; text[ i ] && i < l; i++ ) { + data[ len + i ] = text[ i ]; + } + len = newLen; + data[ len ] = '\0'; + } +} + +ID_INLINE void idStr::Insert( const char a, int index ) { + int i, l; + + if ( index < 0 ) { + index = 0; + } else if ( index > len ) { + index = len; + } + + l = 1; + EnsureAlloced( len + l + 1 ); + for ( i = len; i >= index; i-- ) { + data[i+l] = data[i]; + } + data[index] = a; + len++; +} + +ID_INLINE void idStr::Insert( const char *text, int index ) { + int i, l; + + if ( index < 0 ) { + index = 0; + } else if ( index > len ) { + index = len; + } + + l = strlen( text ); + EnsureAlloced( len + l + 1 ); + for ( i = len; i >= index; i-- ) { + data[i+l] = data[i]; + } + for ( i = 0; i < l; i++ ) { + data[index+i] = text[i]; + } + len += l; +} + +ID_INLINE void idStr::ToLower( void ) { + for (int i = 0; data[i]; i++ ) { + if ( CharIsUpper( data[i] ) ) { + data[i] += ( 'a' - 'A' ); + } + } +} + +ID_INLINE void idStr::ToUpper( void ) { + for (int i = 0; data[i]; i++ ) { + if ( CharIsLower( data[i] ) ) { + data[i] -= ( 'a' - 'A' ); + } + } +} + +ID_INLINE bool idStr::IsNumeric( void ) const { + return idStr::IsNumeric( data ); +} + +ID_INLINE bool idStr::IsColor( void ) const { + return idStr::IsColor( data ); +} + +ID_INLINE bool idStr::HasLower( void ) const { + return idStr::HasLower( data ); +} + +ID_INLINE bool idStr::HasUpper( void ) const { + return idStr::HasUpper( data ); +} + +ID_INLINE idStr &idStr::RemoveColors( void ) { + idStr::RemoveColors( data ); + len = Length( data ); + return *this; +} + +ID_INLINE int idStr::LengthWithoutColors( void ) const { + return idStr::LengthWithoutColors( data ); +} + +ID_INLINE void idStr::CapLength( int newlen ) { + if ( len <= newlen ) { + return; + } + data[ newlen ] = 0; + len = newlen; +} + +ID_INLINE void idStr::Fill( const char ch, int newlen ) { + EnsureAlloced( newlen + 1 ); + len = newlen; + memset( data, ch, len ); + data[ len ] = 0; +} + +ID_INLINE int idStr::Count( const char c, int start, int end ) const { + if ( end == -1 ) { + end = len; + } + return idStr::CountChar( data, c, start, end ); +} + +ID_INLINE int idStr::Find( const char c, int start, int end ) const { + if ( end == -1 ) { + end = len; + } + return idStr::FindChar( data, c, start, end ); +} + +ID_INLINE int idStr::Find( const char *text, bool casesensitive, int start, int end ) const { + if ( end == -1 ) { + end = len; + } + return idStr::FindText( data, text, casesensitive, start, end ); +} + +ID_INLINE bool idStr::Filter( const char *filter, bool casesensitive ) const { + return idStr::Filter( filter, data, casesensitive ); +} + +ID_INLINE const char *idStr::Left( int len, idStr &result ) const { + return Mid( 0, len, result ); +} + +ID_INLINE const char *idStr::Right( int len, idStr &result ) const { + if ( len >= Length() ) { + result = *this; + return result; + } + return Mid( Length() - len, len, result ); +} + +ID_INLINE idStr idStr::Left( int len ) const { + return Mid( 0, len ); +} + +ID_INLINE idStr idStr::Right( int len ) const { + if ( len >= Length() ) { + return *this; + } + return Mid( Length() - len, len ); +} + +ID_INLINE void idStr::Strip( const char c ) { + StripLeading( c ); + StripTrailing( c ); +} + +ID_INLINE void idStr::Strip( const char *string ) { + StripLeading( string ); + StripTrailing( string ); +} + +ID_INLINE bool idStr::CheckExtension( const char *ext ) { + return idStr::CheckExtension( data, ext ); +} + +ID_INLINE int idStr::Length( const char *s ) { + int i; + for ( i = 0; s[i]; i++ ) {} + return i; +} + +ID_INLINE char *idStr::ToLower( char *s ) { + for ( int i = 0; s[i]; i++ ) { + if ( CharIsUpper( s[i] ) ) { + s[i] += ( 'a' - 'A' ); + } + } + return s; +} + +ID_INLINE char *idStr::ToUpper( char *s ) { + for ( int i = 0; s[i]; i++ ) { + if ( CharIsLower( s[i] ) ) { + s[i] -= ( 'a' - 'A' ); + } + } + return s; +} + +ID_INLINE int idStr::Hash( const char *string ) { + int i, hash = 0; + for ( i = 0; *string != '\0'; i++ ) { + hash += ( *string++ ) * ( i + 119 ); + } + return hash; +} + +ID_INLINE int idStr::Hash( const char *string, int length ) { + int i, hash = 0; + for ( i = 0; i < length; i++ ) { + hash += ( *string++ ) * ( i + 119 ); + } + return hash; +} + +ID_INLINE int idStr::IHash( const char *string ) { + int i, hash = 0; + for( i = 0; *string != '\0'; i++ ) { + hash += ToLower( *string++ ) * ( i + 119 ); + } + return hash; +} + +ID_INLINE int idStr::IHash( const char *string, int length ) { + int i, hash = 0; + for ( i = 0; i < length; i++ ) { + hash += ToLower( *string++ ) * ( i + 119 ); + } + return hash; +} + +ID_INLINE bool idStr::IsColor( const char *s ) { + return ( s[0] == C_COLOR_ESCAPE && s[1] != '\0' && s[1] != ' ' ); +} + +ID_INLINE char idStr::ToLower( char c ) { + if ( c <= 'Z' && c >= 'A' ) { + return ( c + ( 'a' - 'A' ) ); + } + return c; +} + +ID_INLINE char idStr::ToUpper( char c ) { + if ( c >= 'a' && c <= 'z' ) { + return ( c - ( 'a' - 'A' ) ); + } + return c; +} + +ID_INLINE bool idStr::CharIsPrintable( int c ) { + // test for regular ascii and western European high-ascii chars + return ( c >= 0x20 && c <= 0x7E ) || ( c >= 0xA1 && c <= 0xFF ); +} + +ID_INLINE bool idStr::CharIsLower( int c ) { + // test for regular ascii and western European high-ascii chars + return ( c >= 'a' && c <= 'z' ) || ( c >= 0xE0 && c <= 0xFF ); +} + +ID_INLINE bool idStr::CharIsUpper( int c ) { + // test for regular ascii and western European high-ascii chars + return ( c <= 'Z' && c >= 'A' ) || ( c >= 0xC0 && c <= 0xDF ); +} + +ID_INLINE bool idStr::CharIsAlpha( int c ) { + // test for regular ascii and western European high-ascii chars + return ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || + ( c >= 0xC0 && c <= 0xFF ) ); +} + +ID_INLINE bool idStr::CharIsNumeric( int c ) { + return ( c <= '9' && c >= '0' ); +} + +ID_INLINE bool idStr::CharIsNewLine( char c ) { + return ( c == '\n' || c == '\r' || c == '\v' ); +} + +ID_INLINE bool idStr::CharIsTab( char c ) { + return ( c == '\t' ); +} + +ID_INLINE int idStr::ColorIndex( int c ) { + return ( c & 15 ); +} + +ID_INLINE int idStr::DynamicMemoryUsed() const { + return ( data == baseBuffer ) ? 0 : alloced; +} + +#endif /* !__STR_H__ */ diff --git a/idlib/Timer.cpp b/idlib/Timer.cpp new file mode 100644 index 000000000..05e63965e --- /dev/null +++ b/idlib/Timer.cpp @@ -0,0 +1,156 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + + +double idTimer::base = -1.0; + +/* +================= +idTimer::InitBaseClockTicks +================= +*/ +void idTimer::InitBaseClockTicks( void ) const { + idTimer timer; + double ct, b; + int i; + + base = 0.0; + b = -1.0; + for ( i = 0; i < 1000; i++ ) { + timer.Clear(); + timer.Start(); + timer.Stop(); + ct = timer.ClockTicks(); + if ( b < 0.0 || ct < b ) { + b = ct; + } + } + base = b; +} + + +/* +================= +idTimerReport::idTimerReport +================= +*/ +idTimerReport::idTimerReport() { +} + +/* +================= +idTimerReport::SetReportName +================= +*/ +void idTimerReport::SetReportName( const char *name ) { + reportName = ( name ) ? name : "Timer Report"; +} + +/* +================= +idTimerReport::~idTimerReport +================= +*/ +idTimerReport::~idTimerReport() { + Clear(); +} + +/* +================= +idTimerReport::AddReport +================= +*/ +int idTimerReport::AddReport( const char *name ) { + if ( name && *name ) { + names.Append( name ); + return timers.Append( new idTimer() ); + } + return -1; +} + +/* +================= +idTimerReport::Clear +================= +*/ +void idTimerReport::Clear() { + timers.DeleteContents( true ); + names.Clear(); + reportName.Clear(); +} + +/* +================= +idTimerReport::Reset +================= +*/ +void idTimerReport::Reset() { + assert ( timers.Num() == names.Num() ); + for ( int i = 0; i < timers.Num(); i++ ) { + timers[i]->Clear(); + } +} + +/* +================= +idTimerReport::AddTime +================= +*/ +void idTimerReport::AddTime( const char *name, idTimer *time ) { + assert ( timers.Num() == names.Num() ); + int i; + for ( i = 0; i < names.Num(); i++ ) { + if ( names[i].Icmp( name ) == 0 ) { + *timers[i] += *time; + break; + } + } + if ( i == names.Num() ) { + int index = AddReport( name ); + if ( index >= 0 ) { + timers[index]->Clear(); + *timers[index] += *time; + } + } +} + +/* +================= +idTimerReport::PrintReport +================= +*/ +void idTimerReport::PrintReport() { + assert( timers.Num() == names.Num() ); + idLib::common->Printf( "Timing Report for %s\n", reportName.c_str() ); + idLib::common->Printf( "-------------------------------\n" ); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Timing Report for %s\n", reportName.c_str()); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("-------------------------------\n"); + float total = 0.0f; + for ( int i = 0; i < names.Num(); i++ ) { + idLib::common->Printf( "%s consumed %5.2f seconds\n", names[i].c_str(), timers[i]->Milliseconds() * 0.001f ); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("%s consumed %5.2f seconds\n", names[i].c_str(), timers[i]->Milliseconds() * 0.001f); + total += timers[i]->Milliseconds(); + } + idLib::common->Printf( "Total time for report %s was %5.2f\n\n", reportName.c_str(), total * 0.001f ); + //DM_LOG(LC_AI, LT_INFO)LOGSTRING("Total time for report %s was %5.2f\n\n", reportName.c_str(), total * 0.001f); +} diff --git a/idlib/Timer.h b/idlib/Timer.h new file mode 100644 index 000000000..1f56fa8b2 --- /dev/null +++ b/idlib/Timer.h @@ -0,0 +1,227 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +/* +=============================================================================== + + Clock tick counter. Should only be used for profiling. + +=============================================================================== +*/ + +class idTimer { +public: + idTimer( void ); + idTimer( double clockTicks ); + ~idTimer( void ); + + idTimer operator+( const idTimer &t ) const; + idTimer operator-( const idTimer &t ) const; + idTimer & operator+=( const idTimer &t ); + idTimer & operator-=( const idTimer &t ); + + void Start( void ); + void Stop( void ); + void Clear( void ); + + bool Running() const; + + double ClockTicks( void ) const; + double Milliseconds( void ) const; + +private: + static double base; + enum { + TS_STARTED, + TS_STOPPED + } state; + double start; + double clockTicks; + + void InitBaseClockTicks( void ) const; +}; + +/* +================= +idTimer::idTimer +================= +*/ +ID_INLINE idTimer::idTimer( void ) { + state = TS_STOPPED; + clockTicks = 0.0; +} + +/* +================= +idTimer::idTimer +================= +*/ +ID_INLINE idTimer::idTimer( double _clockTicks ) { + state = TS_STOPPED; + clockTicks = _clockTicks; +} + +/* +================= +idTimer::~idTimer +================= +*/ +ID_INLINE idTimer::~idTimer( void ) { +} + +/* +================= +idTimer::operator+ +================= +*/ +ID_INLINE idTimer idTimer::operator+( const idTimer &t ) const { + assert( state == TS_STOPPED && t.state == TS_STOPPED ); + return idTimer( clockTicks + t.clockTicks ); +} + +/* +================= +idTimer::operator- +================= +*/ +ID_INLINE idTimer idTimer::operator-( const idTimer &t ) const { + assert( state == TS_STOPPED && t.state == TS_STOPPED ); + return idTimer( clockTicks - t.clockTicks ); +} + +/* +================= +idTimer::operator+= +================= +*/ +ID_INLINE idTimer &idTimer::operator+=( const idTimer &t ) { + assert( state == TS_STOPPED && t.state == TS_STOPPED ); + clockTicks += t.clockTicks; + return *this; +} + +/* +================= +idTimer::operator-= +================= +*/ +ID_INLINE idTimer &idTimer::operator-=( const idTimer &t ) { + assert( state == TS_STOPPED && t.state == TS_STOPPED ); + clockTicks -= t.clockTicks; + return *this; +} + +/* +================= +idTimer::Start +================= +*/ +ID_INLINE void idTimer::Start( void ) { + assert( state == TS_STOPPED ); + state = TS_STARTED; + start = idLib::sys->GetClockTicks(); +} + +/* +================= +idTimer::Stop +================= +*/ +ID_INLINE void idTimer::Stop( void ) { + assert( state == TS_STARTED ); + clockTicks += idLib::sys->GetClockTicks() - start; + if ( base < 0.0 ) { + InitBaseClockTicks(); + } + if ( clockTicks > base ) { + clockTicks -= base; + } + state = TS_STOPPED; +} + +/* +================= +TDM: idTimer::Clear +================= +*/ +ID_INLINE bool idTimer::Running() const +{ + return state == TS_STARTED; +} + +/* +================= +idTimer::Clear +================= +*/ +ID_INLINE void idTimer::Clear( void ) { + clockTicks = 0.0; +} + +/* +================= +idTimer::ClockTicks +================= +*/ +ID_INLINE double idTimer::ClockTicks( void ) const { + assert( state == TS_STOPPED ); + return clockTicks; +} + +/* +================= +idTimer::Milliseconds +================= +*/ +ID_INLINE double idTimer::Milliseconds( void ) const { + assert( state == TS_STOPPED ); + return clockTicks / ( idLib::sys->ClockTicksPerSecond() * 0.001 ); +} + + +/* +=============================================================================== + + Report of multiple named timers. + +=============================================================================== +*/ + +class idTimerReport { +public: + idTimerReport( void ); + ~idTimerReport( void ); + + void SetReportName( const char *name ); + int AddReport( const char *name ); + void Clear( void ); + void Reset( void ); + void PrintReport( void ); + void AddTime( const char *name, idTimer *time ); + +private: + idListtimers; + idStrList names; + idStr reportName; +}; + +#endif /* !__TIMER_H__ */ diff --git a/idlib/Token.cpp b/idlib/Token.cpp new file mode 100644 index 000000000..028388bb4 --- /dev/null +++ b/idlib/Token.cpp @@ -0,0 +1,170 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "precompiled.h" +#pragma hdrstop + + +/* +================ +idToken::NumberValue +================ +*/ +void idToken::NumberValue( void ) { + int i, pow, div, c; + const char *p; + double m; + + assert( type == TT_NUMBER ); + p = c_str(); + floatvalue = 0; + intvalue = 0; + // floating point number + if ( subtype & TT_FLOAT ) { + if ( subtype & ( TT_INFINITE | TT_INDEFINITE | TT_NAN ) ) { + if ( subtype & TT_INFINITE ) { // 1.#INF + unsigned int inf = 0x7f800000; + floatvalue = (double) *(float*)&inf; + } + else if ( subtype & TT_INDEFINITE ) { // 1.#IND + unsigned int ind = 0xffc00000; + floatvalue = (double) *(float*)&ind; + } + else if ( subtype & TT_NAN ) { // 1.#QNAN + unsigned int nan = 0x7fc00000; + floatvalue = (double) *(float*)&nan; + } + } + else { + while( *p && *p != '.' && *p != 'e' ) { + floatvalue = floatvalue * 10.0 + (double) (*p - '0'); + p++; + } + if ( *p == '.' ) { + p++; + for( m = 0.1; *p && *p != 'e'; p++ ) { + floatvalue = floatvalue + (double) (*p - '0') * m; + m *= 0.1; + } + } + if ( *p == 'e' ) { + p++; + if ( *p == '-' ) { + div = true; + p++; + } + else if ( *p == '+' ) { + div = false; + p++; + } + else { + div = false; + } + pow = 0; + for ( pow = 0; *p; p++ ) { + pow = pow * 10 + (int) (*p - '0'); + } + for ( m = 1.0, i = 0; i < pow; i++ ) { + m *= 10.0; + } + if ( div ) { + floatvalue /= m; + } + else { + floatvalue *= m; + } + } + } + intvalue = idMath::Ftol( floatvalue ); + } + else if ( subtype & TT_DECIMAL ) { + while( *p ) { + intvalue = intvalue * 10 + (*p - '0'); + p++; + } + floatvalue = intvalue; + } + else if ( subtype & TT_IPADDRESS ) { + c = 0; + while( *p && *p != ':' ) { + if ( *p == '.' ) { + while( c != 3 ) { + intvalue = intvalue * 10; + c++; + } + c = 0; + } + else { + intvalue = intvalue * 10 + (*p - '0'); + c++; + } + p++; + } + while( c != 3 ) { + intvalue = intvalue * 10; + c++; + } + floatvalue = intvalue; + } + else if ( subtype & TT_OCTAL ) { + // step over the first zero + p += 1; + while( *p ) { + intvalue = (intvalue << 3) + (*p - '0'); + p++; + } + floatvalue = intvalue; + } + else if ( subtype & TT_HEX ) { + // step over the leading 0x or 0X + p += 2; + while( *p ) { + intvalue <<= 4; + if (*p >= 'a' && *p <= 'f') + intvalue += *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + intvalue += *p - 'A' + 10; + else + intvalue += *p - '0'; + p++; + } + floatvalue = intvalue; + } + else if ( subtype & TT_BINARY ) { + // step over the leading 0b or 0B + p += 2; + while( *p ) { + intvalue = (intvalue << 1) + (*p - '0'); + p++; + } + floatvalue = intvalue; + } + subtype |= TT_VALUESVALID; +} + +/* +================ +idToken::ClearTokenWhiteSpace +================ +*/ +void idToken::ClearTokenWhiteSpace( void ) { + whiteSpaceStart_p = NULL; + whiteSpaceEnd_p = NULL; + linesCrossed = 0; +} diff --git a/idlib/Token.h b/idlib/Token.h new file mode 100644 index 000000000..803f207da --- /dev/null +++ b/idlib/Token.h @@ -0,0 +1,156 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __TOKEN_H__ +#define __TOKEN_H__ + +/* +=============================================================================== + + idToken is a token read from a file or memory with idLexer or idParser + +=============================================================================== +*/ + +// token types +#define TT_STRING 1 // string +#define TT_LITERAL 2 // literal +#define TT_NUMBER 3 // number +#define TT_NAME 4 // name +#define TT_PUNCTUATION 5 // punctuation + +// number sub types +#define TT_INTEGER 0x00001 // integer +#define TT_DECIMAL 0x00002 // decimal number +#define TT_HEX 0x00004 // hexadecimal number +#define TT_OCTAL 0x00008 // octal number +#define TT_BINARY 0x00010 // binary number +#define TT_LONG 0x00020 // long int +#define TT_UNSIGNED 0x00040 // unsigned int +#define TT_FLOAT 0x00080 // floating point number +#define TT_SINGLE_PRECISION 0x00100 // float +#define TT_DOUBLE_PRECISION 0x00200 // double +#define TT_EXTENDED_PRECISION 0x00400 // long double +#define TT_INFINITE 0x00800 // infinite 1.#INF +#define TT_INDEFINITE 0x01000 // indefinite 1.#IND +#define TT_NAN 0x02000 // NaN +#define TT_IPADDRESS 0x04000 // ip address +#define TT_IPPORT 0x08000 // ip port +#define TT_VALUESVALID 0x10000 // set if intvalue and floatvalue are valid + +// string sub type is the length of the string +// literal sub type is the ASCII code +// punctuation sub type is the punctuation id +// name sub type is the length of the name + +class idToken : public idStr { + + friend class idParser; + friend class idLexer; + +public: + int type; // token type + int subtype; // token sub type + int line; // line in script the token was on + int linesCrossed; // number of lines crossed in white space before token + int flags; // token flags, used for recursive defines + +public: + idToken( void ); + idToken( const idToken *token ); + ~idToken( void ); + + void operator=( const idStr& text ); + void operator=( const char *text ); + + double GetDoubleValue( void ); // double value of TT_NUMBER + float GetFloatValue( void ); // float value of TT_NUMBER + unsigned long GetUnsignedLongValue( void ); // unsigned long value of TT_NUMBER + int GetIntValue( void ); // int value of TT_NUMBER + int WhiteSpaceBeforeToken( void ) const;// returns length of whitespace before token + void ClearTokenWhiteSpace( void ); // forget whitespace before token + + void NumberValue( void ); // calculate values for a TT_NUMBER + +private: + unsigned long intvalue; // integer value + double floatvalue; // floating point value + const char * whiteSpaceStart_p; // start of white space before token, only used by idLexer + const char * whiteSpaceEnd_p; // end of white space before token, only used by idLexer + idToken * next; // next token in chain, only used by idParser + + void AppendDirty( const char a ); // append character without adding trailing zero +}; + +ID_INLINE idToken::idToken( void ) { +} + +ID_INLINE idToken::idToken( const idToken *token ) { + *this = *token; +} + +ID_INLINE idToken::~idToken( void ) { +} + +ID_INLINE void idToken::operator=( const char *text) { + *static_cast(this) = text; +} + +ID_INLINE void idToken::operator=( const idStr& text ) { + *static_cast(this) = text; +} + +ID_INLINE double idToken::GetDoubleValue( void ) { + if ( type != TT_NUMBER ) { + return 0.0; + } + if ( !(subtype & TT_VALUESVALID) ) { + NumberValue(); + } + return floatvalue; +} + +ID_INLINE float idToken::GetFloatValue( void ) { + return (float) GetDoubleValue(); +} + +ID_INLINE unsigned long idToken::GetUnsignedLongValue( void ) { + if ( type != TT_NUMBER ) { + return 0; + } + if ( !(subtype & TT_VALUESVALID) ) { + NumberValue(); + } + return intvalue; +} + +ID_INLINE int idToken::GetIntValue( void ) { + return (int) GetUnsignedLongValue(); +} + +ID_INLINE int idToken::WhiteSpaceBeforeToken( void ) const { + return ( whiteSpaceEnd_p > whiteSpaceStart_p ); +} + +ID_INLINE void idToken::AppendDirty( const char a ) { + EnsureAlloced( len + 2, true ); + data[len++] = a; +} + +#endif /* !__TOKEN_H__ */ diff --git a/idlib/base64.cpp b/idlib/base64.cpp deleted file mode 100644 index 21e19bd3f..000000000 --- a/idlib/base64.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -Copyright (c) 1996 Lars Wirzenius. All rights reserved. - -June 14 2003: TTimo - modified + endian bug fixes - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=197039 - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -/* -============ -idBase64::Encode -============ -*/ -static const char sixtet_to_base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -void idBase64::Encode( const byte *from, int size ) { - int i, j; - unsigned long w; - byte *to; - - EnsureAlloced( 4*(size+3)/3 + 2 ); // ratio and padding + trailing \0 - to = data; - - w = 0; - i = 0; - while (size > 0) { - w |= *from << i*8; - ++from; - --size; - ++i; - if (size == 0 || i == 3) { - byte out[4]; - SixtetsForInt( out, w ); - for (j = 0; j*6 < i*8; ++j) { - *to++ = sixtet_to_base64[ out[j] ]; - } - if (size == 0) { - for (j = i; j < 3; ++j) { - *to++ = '='; - } - } - w = 0; - i = 0; - } - } - - *to++ = '\0'; - len = to - data; -} - -/* -============ -idBase64::DecodeLength -returns the minimum size in bytes of the target buffer for decoding -4 base64 digits <-> 3 bytes -============ -*/ -int idBase64::DecodeLength( void ) const { - return 3*len/4; -} - -/* -============ -idBase64::Decode -============ -*/ -int idBase64::Decode( byte *to ) const { - unsigned long w; - int i, j; - size_t n; - static char base64_to_sixtet[256]; - static int tab_init = 0; - byte *from = data; - - if (!tab_init) { - memset( base64_to_sixtet, 0, 256 ); - for (i = 0; (j = sixtet_to_base64[i]) != '\0'; ++i) { - base64_to_sixtet[j] = i; - } - tab_init = 1; - } - - w = 0; - i = 0; - n = 0; - byte in[4] = {0,0,0,0}; - while (*from != '\0' && *from != '=' ) { - if (*from == ' ' || *from == '\n') { - ++from; - continue; - } - in[i] = base64_to_sixtet[* (unsigned char *) from]; - ++i; - ++from; - if (*from == '\0' || *from == '=' || i == 4) { - w = IntForSixtets( in ); - for (j = 0; j*8 < i*6; ++j) { - *to++ = w & 0xff; - ++n; - w >>= 8; - } - i = 0; - w = 0; - } - } - return n; -} - -/* -============ -idBase64::Encode -============ -*/ -void idBase64::Encode( const idStr &src ) { - Encode( (const byte *)src.c_str(), src.Length() ); -} - -/* -============ -idBase64::Decode -============ -*/ -void idBase64::Decode( idStr &dest ) const { - byte *buf = new byte[ DecodeLength()+1 ]; // +1 for trailing \0 - int out = Decode( buf ); - buf[out] = '\0'; - dest = (const char *)buf; - delete[] buf; -} - -/* -============ -idBase64::Decode -============ -*/ -void idBase64::Decode( idFile *dest ) const { - byte *buf = new byte[ DecodeLength()+1 ]; // +1 for trailing \0 - int out = Decode( buf ); - dest->Write( buf, out ); - delete[] buf; -} - -#if 0 - -void idBase64_TestBase64() { - - idStr src; - idBase64 dest; - src = "Encode me in base64"; - dest.Encode( src ); - idLib::common->Printf( "%s -> %s\n", src.c_str(), dest.c_str() ); - dest.Decode( src ); - idLib::common->Printf( "%s -> %s\n", dest.c_str(), src.c_str() ); - - idDict src_dict; - src_dict.SetFloat("float", 0.5f); - src_dict.SetBool("bool", true); - src_dict.Set("value", "foo"); - idFile_Memory src_fmem("serialize_dict"); - src_dict.WriteToFileHandle( &src_fmem ); - dest.Encode( (const byte *)src_fmem.GetDataPtr(), src_fmem.Length() ); - idLib::common->Printf( "idDict encoded to %s\n", dest.c_str()); - - // now decode to another stream and build back - idFile_Memory dest_fmem( "build_back" ); - dest.Decode( &dest_fmem ); - dest_fmem.MakeReadOnly(); - idDict dest_dict; - dest_dict.ReadFromFileHandle( &dest_fmem ); - idLib::common->Printf( "idDict reconstructed after base64 decode\n"); - dest_dict.Print(); - - // test idDict read from file - from python generated files, see idDict.py - idFile *file = idLib::fileSystem->OpenFileRead("idDict.test"); - if (file) { - idDict test_dict; - test_dict.ReadFromFileHandle( file ); - // - idLib::common->Printf( "read idDict.test:\n"); - test_dict.Print(); - idLib::fileSystem->CloseFile(file); - file = NULL; - } else { - idLib::common->Printf( "idDict.test not found\n" ); - } - - idBase64 base64_src; - void *buffer; - if ( idLib::fileSystem->ReadFile( "idDict.base64.test", &buffer ) != -1 ) { - idFile_Memory mem_src( "dict" ); - idLib::common->Printf( "read: %d %s\n", idStr::Length( (char*)buffer ), buffer ); - base64_src = (char *)buffer; - base64_src.Decode( &mem_src ); - mem_src.MakeReadOnly(); - idDict test_dict; - test_dict.ReadFromFileHandle( &mem_src ); - idLib::common->Printf( "read idDict.base64.test:\n"); - test_dict.Print(); - idLib::fileSystem->FreeFile( buffer ); - } else { - idLib::common->Printf( "idDict.base64.test not found\n" ); - } -} - -#endif diff --git a/idlib/base64.h b/idlib/base64.h deleted file mode 100644 index c0bf7afe5..000000000 --- a/idlib/base64.h +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - - -#ifndef __BASE64_H__ -#define __BASE64_H__ - -/* -=============================================================================== - - base64 - -=============================================================================== -*/ - -class idBase64 { -public: - idBase64( void ); - idBase64( const idStr &s ); - ~idBase64( void ); - - void Encode( const byte *from, int size ); - void Encode( const idStr &src ); - int DecodeLength( void ) const; // minimum size in bytes of destination buffer for decoding - int Decode( byte *to ) const; // does not append a \0 - needs a DecodeLength() bytes buffer - void Decode( idStr &dest ) const; // decodes the binary content to an idStr (a bit dodgy, \0 and other non-ascii are possible in the decoded content) - void Decode( idFile *dest ) const; - - const char *c_str() const; - - void operator=( const idStr &s ); - -private: - byte * data; - int len; - int alloced; - - void Init( void ); - void Release( void ); - void EnsureAlloced( int size ); -}; - -ID_INLINE idBase64::idBase64( void ) { - Init(); -} - -ID_INLINE idBase64::idBase64( const idStr &s ) { - Init(); - *this = s; -} - -ID_INLINE idBase64::~idBase64( void ) { - Release(); -} - -ID_INLINE const char *idBase64::c_str( void ) const { - return (const char *)data; -} - -ID_INLINE void idBase64::Init( void ) { - len = 0; - alloced = 0; - data = NULL; -} - -ID_INLINE void idBase64::Release( void ) { - if ( data ) { - delete[] data; - } - Init(); -} - -ID_INLINE void idBase64::EnsureAlloced( int size ) { - if ( size > alloced ) { - Release(); - } - data = new byte[size]; - alloced = size; -} - -ID_INLINE void idBase64::operator=( const idStr &s ) { - EnsureAlloced( s.Length()+1 ); // trailing \0 - beware, this does a Release - strcpy( (char *)data, s.c_str() ); - len = s.Length(); -} - -#endif /* !__BASE64_H__ */ diff --git a/idlib/bitmsg.cpp b/idlib/bitmsg.cpp deleted file mode 100644 index c708e42a3..000000000 --- a/idlib/bitmsg.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============================================================================== - - idBitMsg - -============================================================================== -*/ - -/* -================ -idBitMsg::idBitMsg -================ -*/ -idBitMsg::idBitMsg() { - writeData = NULL; - readData = NULL; - maxSize = 0; - curSize = 0; - writeBit = 0; - readCount = 0; - readBit = 0; - allowOverflow = false; - overflowed = false; -} - -/* -================ -idBitMsg::CheckOverflow -================ -*/ -bool idBitMsg::CheckOverflow( int numBits ) { - assert( numBits >= 0 ); - if ( numBits > GetRemainingWriteBits() ) { - if ( !allowOverflow ) { - idLib::common->FatalError( "idBitMsg: overflow without allowOverflow set" ); - } - if ( numBits > ( maxSize << 3 ) ) { - idLib::common->FatalError( "idBitMsg: %i bits is > full message size", numBits ); - } - idLib::common->Printf( "idBitMsg: overflow\n" ); - BeginWriting(); - overflowed = true; - return true; - } - return false; -} - -/* -================ -idBitMsg::GetByteSpace -================ -*/ -byte *idBitMsg::GetByteSpace( int length ) { - byte *ptr; - - if ( !writeData ) { - idLib::common->FatalError( "idBitMsg::GetByteSpace: cannot write to message" ); - } - - // round up to the next byte - WriteByteAlign(); - - // check for overflow - CheckOverflow( length << 3 ); - - ptr = writeData + curSize; - curSize += length; - return ptr; -} - -/* -================ -idBitMsg::WriteBits - - If the number of bits is negative a sign is included. -================ -*/ -void idBitMsg::WriteBits( int value, int numBits ) { - int put; - int fraction; - - if ( !writeData ) { - idLib::common->Error( "idBitMsg::WriteBits: cannot write to message" ); - } - - // check if the number of bits is valid - if ( numBits == 0 || numBits < -31 || numBits > 32 ) { - idLib::common->Error( "idBitMsg::WriteBits: bad numBits %i", numBits ); - } - - // check for value overflows - // this should be an error really, as it can go unnoticed and cause either bandwidth or corrupted data transmitted - if ( numBits != 32 ) { - if ( numBits > 0 ) { - if ( value > ( 1 << numBits ) - 1 ) { - idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); - } else if ( value < 0 ) { - idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); - } - } else { - int r = 1 << ( - 1 - numBits ); - if ( value > r - 1 ) { - idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); - } else if ( value < -r ) { - idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits ); - } - } - } - - if ( numBits < 0 ) { - numBits = -numBits; - } - - // check for msg overflow - if ( CheckOverflow( numBits ) ) { - return; - } - - // write the bits - while( numBits ) { - if ( writeBit == 0 ) { - writeData[curSize] = 0; - curSize++; - } - put = 8 - writeBit; - if ( put > numBits ) { - put = numBits; - } - fraction = value & ( ( 1 << put ) - 1 ); - writeData[curSize - 1] |= fraction << writeBit; - numBits -= put; - value >>= put; - writeBit = ( writeBit + put ) & 7; - } -} - -/* -================ -idBitMsg::WriteString -================ -*/ -void idBitMsg::WriteString( const char *s, int maxLength, bool make7Bit ) { - if ( !s ) { - WriteData( "", 1 ); - } else { - int i, l; - byte *dataPtr; - const byte *bytePtr; - - l = idStr::Length( s ); - if ( maxLength >= 0 && l >= maxLength ) { - l = maxLength - 1; - } - dataPtr = GetByteSpace( l + 1 ); - bytePtr = reinterpret_cast(s); - if ( make7Bit ) { - for ( i = 0; i < l; i++ ) { - if ( bytePtr[i] > 127 ) { - dataPtr[i] = '.'; - } else { - dataPtr[i] = bytePtr[i]; - } - } - } else { - for ( i = 0; i < l; i++ ) { - dataPtr[i] = bytePtr[i]; - } - } - dataPtr[i] = '\0'; - } -} - -/* -================ -idBitMsg::WriteData -================ -*/ -void idBitMsg::WriteData( const void *data, int length ) { - memcpy( GetByteSpace( length ), data, length ); -} - -/* -================ -idBitMsg::WriteNetadr -================ -*/ -void idBitMsg::WriteNetadr( const netadr_t adr ) { - byte *dataPtr; - dataPtr = GetByteSpace( 4 ); - memcpy( dataPtr, adr.ip, 4 ); - WriteUShort( adr.port ); -} - -/* -================ -idBitMsg::WriteDelta -================ -*/ -void idBitMsg::WriteDelta( int oldValue, int newValue, int numBits ) { - if ( oldValue == newValue ) { - WriteBits( 0, 1 ); - return; - } - WriteBits( 1, 1 ); - WriteBits( newValue, numBits ); -} - -/* -================ -idBitMsg::WriteDeltaByteCounter -================ -*/ -void idBitMsg::WriteDeltaByteCounter( int oldValue, int newValue ) { - int i, x; - - x = oldValue ^ newValue; - for ( i = 7; i > 0; i-- ) { - if ( x & ( 1 << i ) ) { - i++; - break; - } - } - WriteBits( i, 3 ); - if ( i ) { - WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); - } -} - -/* -================ -idBitMsg::WriteDeltaShortCounter -================ -*/ -void idBitMsg::WriteDeltaShortCounter( int oldValue, int newValue ) { - int i, x; - - x = oldValue ^ newValue; - for ( i = 15; i > 0; i-- ) { - if ( x & ( 1 << i ) ) { - i++; - break; - } - } - WriteBits( i, 4 ); - if ( i ) { - WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); - } -} - -/* -================ -idBitMsg::WriteDeltaLongCounter -================ -*/ -void idBitMsg::WriteDeltaLongCounter( int oldValue, int newValue ) { - int i, x; - - x = oldValue ^ newValue; - for ( i = 31; i > 0; i-- ) { - if ( x & ( 1 << i ) ) { - i++; - break; - } - } - WriteBits( i, 5 ); - if ( i ) { - WriteBits( ( ( 1 << i ) - 1 ) & newValue, i ); - } -} - -/* -================== -idBitMsg::WriteDeltaDict -================== -*/ -bool idBitMsg::WriteDeltaDict( const idDict &dict, const idDict *base ) { - int i; - const idKeyValue *kv, *basekv; - bool changed = false; - - if ( base != NULL ) { - - for ( i = 0; i < dict.GetNumKeyVals(); i++ ) { - kv = dict.GetKeyVal( i ); - basekv = base->FindKey( kv->GetKey() ); - if ( basekv == NULL || basekv->GetValue().Icmp( kv->GetValue() ) != 0 ) { - WriteString( kv->GetKey() ); - WriteString( kv->GetValue() ); - changed = true; - } - } - - WriteString( "" ); - - for ( i = 0; i < base->GetNumKeyVals(); i++ ) { - basekv = base->GetKeyVal( i ); - kv = dict.FindKey( basekv->GetKey() ); - if ( kv == NULL ) { - WriteString( basekv->GetKey() ); - changed = true; - } - } - - WriteString( "" ); - - } else { - - for ( i = 0; i < dict.GetNumKeyVals(); i++ ) { - kv = dict.GetKeyVal( i ); - WriteString( kv->GetKey() ); - WriteString( kv->GetValue() ); - changed = true; - } - WriteString( "" ); - - WriteString( "" ); - - } - - return changed; -} - -/* -================ -idBitMsg::ReadBits - - If the number of bits is negative a sign is included. -================ -*/ -int idBitMsg::ReadBits( int numBits ) const { - int value; - int valueBits; - int get; - int fraction; - bool sgn; - - if ( !readData ) { - idLib::common->FatalError( "idBitMsg::ReadBits: cannot read from message" ); - } - - // check if the number of bits is valid - if ( numBits == 0 || numBits < -31 || numBits > 32 ) { - idLib::common->FatalError( "idBitMsg::ReadBits: bad numBits %i", numBits ); - } - - value = 0; - valueBits = 0; - - if ( numBits < 0 ) { - numBits = -numBits; - sgn = true; - } else { - sgn = false; - } - - // check for overflow - if ( numBits > GetRemainingReadBits() ) { - return -1; - } - - while ( valueBits < numBits ) { - if ( readBit == 0 ) { - readCount++; - } - get = 8 - readBit; - if ( get > (numBits - valueBits) ) { - get = numBits - valueBits; - } - fraction = readData[readCount - 1]; - fraction >>= readBit; - fraction &= ( 1 << get ) - 1; - value |= fraction << valueBits; - - valueBits += get; - readBit = ( readBit + get ) & 7; - } - - if ( sgn ) { - if ( value & ( 1 << ( numBits - 1 ) ) ) { - value |= -1 ^ ( ( 1 << numBits ) - 1 ); - } - } - - return value; -} - -/* -================ -idBitMsg::ReadString -================ -*/ -int idBitMsg::ReadString( char *buffer, int bufferSize ) const { - int l, c; - - ReadByteAlign(); - l = 0; -#pragma warning( push ) -#pragma warning(disable : 4127 ) - while( 1 ) { - c = ReadByte(); - if ( c <= 0 || c >= 255 ) { - break; - } - // translate all fmt spec to avoid crash bugs in string routines - if ( c == '%' ) { - c = '.'; - } - - // we will read past any excessively long string, so - // the following data can be read, but the string will - // be truncated - if ( l < bufferSize - 1 ) { - buffer[l] = c; - l++; - } - } -#pragma warning( pop ) - buffer[l] = 0; - return l; -} - -/* -================ -idBitMsg::ReadData -================ -*/ -int idBitMsg::ReadData( void *data, int length ) const { - int cnt; - - ReadByteAlign(); - cnt = readCount; - - if ( readCount + length > curSize ) { - if ( data ) { - memcpy( data, readData + readCount, GetRemaingData() ); - } - readCount = curSize; - } else { - if ( data ) { - memcpy( data, readData + readCount, length ); - } - readCount += length; - } - - return ( readCount - cnt ); -} - -/* -================ -idBitMsg::ReadNetadr -================ -*/ -void idBitMsg::ReadNetadr( netadr_t *adr ) const { - int i; - - adr->type = NA_IP; - for ( i = 0; i < 4; i++ ) { - adr->ip[ i ] = ReadByte(); - } - adr->port = ReadUShort(); -} - -/* -================ -idBitMsg::ReadDelta -================ -*/ -int idBitMsg::ReadDelta( int oldValue, int numBits ) const { - if ( ReadBits( 1 ) ) { - return ReadBits( numBits ); - } - return oldValue; -} - -/* -================ -idBitMsg::ReadDeltaByteCounter -================ -*/ -int idBitMsg::ReadDeltaByteCounter( int oldValue ) const { - int i, newValue; - - i = ReadBits( 3 ); - if ( !i ) { - return oldValue; - } - newValue = ReadBits( i ); - return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); -} - -/* -================ -idBitMsg::ReadDeltaShortCounter -================ -*/ -int idBitMsg::ReadDeltaShortCounter( int oldValue ) const { - int i, newValue; - - i = ReadBits( 4 ); - if ( !i ) { - return oldValue; - } - newValue = ReadBits( i ); - return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); -} - -/* -================ -idBitMsg::ReadDeltaLongCounter -================ -*/ -int idBitMsg::ReadDeltaLongCounter( int oldValue ) const { - int i, newValue; - - i = ReadBits( 5 ); - if ( !i ) { - return oldValue; - } - newValue = ReadBits( i ); - return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue ); -} - -/* -================== -idBitMsg::ReadDeltaDict -================== -*/ -bool idBitMsg::ReadDeltaDict( idDict &dict, const idDict *base ) const { - char key[MAX_STRING_CHARS]; - char value[MAX_STRING_CHARS]; - bool changed = false; - - if ( base != NULL ) { - dict = *base; - } else { - dict.Clear(); - } - - while( ReadString( key, sizeof( key ) ) != 0 ) { - ReadString( value, sizeof( value ) ); - dict.Set( key, value ); - changed = true; - } - - while( ReadString( key, sizeof( key ) ) != 0 ) { - dict.Delete( key ); - changed = true; - } - - return changed; -} - -/* -================ -idBitMsg::DirToBits -================ -*/ -int idBitMsg::DirToBits( const idVec3 &dir, int numBits ) { - int max, bits; - float bias; - - assert( numBits >= 6 && numBits <= 32 ); - assert( dir.LengthSqr() - 1.0f < 0.01f ); - - numBits /= 3; - max = ( 1 << ( numBits - 1 ) ) - 1; - bias = 0.5f / max; - - bits = FLOATSIGNBITSET( dir.x ) << ( numBits * 3 - 1 ); - bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.x ) + bias ) * max ) ) << ( numBits * 2 ); - bits |= FLOATSIGNBITSET( dir.y ) << ( numBits * 2 - 1 ); - bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.y ) + bias ) * max ) ) << ( numBits * 1 ); - bits |= FLOATSIGNBITSET( dir.z ) << ( numBits * 1 - 1 ); - bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.z ) + bias ) * max ) ) << ( numBits * 0 ); - return bits; -} - -/* -================ -idBitMsg::BitsToDir -================ -*/ -idVec3 idBitMsg::BitsToDir( int bits, int numBits ) { - static float sign[2] = { 1.0f, -1.0f }; - int max; - float invMax; - idVec3 dir; - - assert( numBits >= 6 && numBits <= 32 ); - - numBits /= 3; - max = ( 1 << ( numBits - 1 ) ) - 1; - invMax = 1.0f / max; - - dir.x = sign[( bits >> ( numBits * 3 - 1 ) ) & 1] * ( ( bits >> ( numBits * 2 ) ) & max ) * invMax; - dir.y = sign[( bits >> ( numBits * 2 - 1 ) ) & 1] * ( ( bits >> ( numBits * 1 ) ) & max ) * invMax; - dir.z = sign[( bits >> ( numBits * 1 - 1 ) ) & 1] * ( ( bits >> ( numBits * 0 ) ) & max ) * invMax; - dir.NormalizeFast(); - return dir; -} - - -/* -============================================================================== - - idBitMsgDelta - -============================================================================== -*/ - -const int MAX_DATA_BUFFER = 1024; - -/* -================ -idBitMsgDelta::WriteBits -================ -*/ -void idBitMsgDelta::WriteBits( int value, int numBits ) { - if ( newBase ) { - newBase->WriteBits( value, numBits ); - } - - if ( !base ) { - writeDelta->WriteBits( value, numBits ); - changed = true; - } else { - int baseValue = base->ReadBits( numBits ); - if ( baseValue == value ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteBits( value, numBits ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::WriteDelta -================ -*/ -void idBitMsgDelta::WriteDelta( int oldValue, int newValue, int numBits ) { - if ( newBase ) { - newBase->WriteBits( newValue, numBits ); - } - - if ( !base ) { - if ( oldValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteBits( newValue, numBits ); - } - changed = true; - } else { - int baseValue = base->ReadBits( numBits ); - if ( baseValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - if ( oldValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - changed = true; - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteBits( newValue, numBits ); - changed = true; - } - } - } -} - -/* -================ -idBitMsgDelta::ReadBits -================ -*/ -int idBitMsgDelta::ReadBits( int numBits ) const { - int value; - - if ( !base ) { - value = readDelta->ReadBits( numBits ); - changed = true; - } else { - int baseValue = base->ReadBits( numBits ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - value = baseValue; - } else { - value = readDelta->ReadBits( numBits ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteBits( value, numBits ); - } - return value; -} - -/* -================ -idBitMsgDelta::ReadDelta -================ -*/ -int idBitMsgDelta::ReadDelta( int oldValue, int numBits ) const { - int value; - - if ( !base ) { - if ( readDelta->ReadBits( 1 ) == 0 ) { - value = oldValue; - } else { - value = readDelta->ReadBits( numBits ); - } - changed = true; - } else { - int baseValue = base->ReadBits( numBits ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - value = baseValue; - } else if ( readDelta->ReadBits( 1 ) == 0 ) { - value = oldValue; - changed = true; - } else { - value = readDelta->ReadBits( numBits ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteBits( value, numBits ); - } - return value; -} - -/* -================ -idBitMsgDelta::WriteString -================ -*/ -void idBitMsgDelta::WriteString( const char *s, int maxLength ) { - if ( newBase ) { - newBase->WriteString( s, maxLength ); - } - - if ( !base ) { - writeDelta->WriteString( s, maxLength ); - changed = true; - } else { - char baseString[MAX_DATA_BUFFER]; - base->ReadString( baseString, sizeof( baseString ) ); - if ( idStr::Cmp( s, baseString ) == 0 ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteString( s, maxLength ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::WriteData -================ -*/ -void idBitMsgDelta::WriteData( const void *data, int length ) { - if ( newBase ) { - newBase->WriteData( data, length ); - } - - if ( !base ) { - writeDelta->WriteData( data, length ); - changed = true; - } else { - byte baseData[MAX_DATA_BUFFER]; - assert( length < sizeof( baseData ) ); - base->ReadData( baseData, length ); - if ( memcmp( data, baseData, length ) == 0 ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteData( data, length ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::WriteDict -================ -*/ -void idBitMsgDelta::WriteDict( const idDict &dict ) { - if ( newBase ) { - newBase->WriteDeltaDict( dict, NULL ); - } - - if ( !base ) { - writeDelta->WriteDeltaDict( dict, NULL ); - changed = true; - } else { - idDict baseDict; - base->ReadDeltaDict( baseDict, NULL ); - changed = writeDelta->WriteDeltaDict( dict, &baseDict ); - } -} - -/* -================ -idBitMsgDelta::WriteDeltaByteCounter -================ -*/ -void idBitMsgDelta::WriteDeltaByteCounter( int oldValue, int newValue ) { - if ( newBase ) { - newBase->WriteBits( newValue, 8 ); - } - - if ( !base ) { - writeDelta->WriteDeltaByteCounter( oldValue, newValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 8 ); - if ( baseValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteDeltaByteCounter( oldValue, newValue ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::WriteDeltaShortCounter -================ -*/ -void idBitMsgDelta::WriteDeltaShortCounter( int oldValue, int newValue ) { - if ( newBase ) { - newBase->WriteBits( newValue, 16 ); - } - - if ( !base ) { - writeDelta->WriteDeltaShortCounter( oldValue, newValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 16 ); - if ( baseValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteDeltaShortCounter( oldValue, newValue ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::WriteDeltaLongCounter -================ -*/ -void idBitMsgDelta::WriteDeltaLongCounter( int oldValue, int newValue ) { - if ( newBase ) { - newBase->WriteBits( newValue, 32 ); - } - - if ( !base ) { - writeDelta->WriteDeltaLongCounter( oldValue, newValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 32 ); - if ( baseValue == newValue ) { - writeDelta->WriteBits( 0, 1 ); - } else { - writeDelta->WriteBits( 1, 1 ); - writeDelta->WriteDeltaLongCounter( oldValue, newValue ); - changed = true; - } - } -} - -/* -================ -idBitMsgDelta::ReadString -================ -*/ -void idBitMsgDelta::ReadString( char *buffer, int bufferSize ) const { - if ( !base ) { - readDelta->ReadString( buffer, bufferSize ); - changed = true; - } else { - char baseString[MAX_DATA_BUFFER]; - base->ReadString( baseString, sizeof( baseString ) ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - idStr::Copynz( buffer, baseString, bufferSize ); - } else { - readDelta->ReadString( buffer, bufferSize ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteString( buffer ); - } -} - -/* -================ -idBitMsgDelta::ReadData -================ -*/ -void idBitMsgDelta::ReadData( void *data, int length ) const { - if ( !base ) { - readDelta->ReadData( data, length ); - changed = true; - } else { - char baseData[MAX_DATA_BUFFER]; - assert( length < sizeof( baseData ) ); - base->ReadData( baseData, length ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - memcpy( data, baseData, length ); - } else { - readDelta->ReadData( data, length ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteData( data, length ); - } -} - -/* -================ -idBitMsgDelta::ReadDict -================ -*/ -void idBitMsgDelta::ReadDict( idDict &dict ) { - if ( !base ) { - readDelta->ReadDeltaDict( dict, NULL ); - changed = true; - } else { - idDict baseDict; - base->ReadDeltaDict( baseDict, NULL ); - if ( !readDelta ) { - dict = baseDict; - } else { - changed = readDelta->ReadDeltaDict( dict, &baseDict ); - } - } - - if ( newBase ) { - newBase->WriteDeltaDict( dict, NULL ); - } -} - -/* -================ -idBitMsgDelta::ReadDeltaByteCounter -================ -*/ -int idBitMsgDelta::ReadDeltaByteCounter( int oldValue ) const { - int value; - - if ( !base ) { - value = readDelta->ReadDeltaByteCounter( oldValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 8 ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - value = baseValue; - } else { - value = readDelta->ReadDeltaByteCounter( oldValue ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteBits( value, 8 ); - } - return value; -} - -/* -================ -idBitMsgDelta::ReadDeltaShortCounter -================ -*/ -int idBitMsgDelta::ReadDeltaShortCounter( int oldValue ) const { - int value; - - if ( !base ) { - value = readDelta->ReadDeltaShortCounter( oldValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 16 ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - value = baseValue; - } else { - value = readDelta->ReadDeltaShortCounter( oldValue ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteBits( value, 16 ); - } - return value; -} - -/* -================ -idBitMsgDelta::ReadDeltaLongCounter -================ -*/ -int idBitMsgDelta::ReadDeltaLongCounter( int oldValue ) const { - int value; - - if ( !base ) { - value = readDelta->ReadDeltaLongCounter( oldValue ); - changed = true; - } else { - int baseValue = base->ReadBits( 32 ); - if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) { - value = baseValue; - } else { - value = readDelta->ReadDeltaLongCounter( oldValue ); - changed = true; - } - } - - if ( newBase ) { - newBase->WriteBits( value, 32 ); - } - return value; -} diff --git a/idlib/bitmsg.h b/idlib/bitmsg.h deleted file mode 100644 index 151dc2fb3..000000000 --- a/idlib/bitmsg.h +++ /dev/null @@ -1,660 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BITMSG_H__ -#define __BITMSG_H__ - -/* -=============================================================================== - - idBitMsg - - Handles byte ordering and avoids alignment errors. - Allows concurrent writing and reading. - The data set with Init is never freed. - -=============================================================================== -*/ - -class idBitMsg { -public: - idBitMsg(); - ~idBitMsg() {} - - void Init( byte *data, int length ); - void Init( const byte *data, int length ); - byte * GetData( void ); // get data for writing - const byte * GetData( void ) const; // get data for reading - int GetMaxSize( void ) const; // get the maximum message size - void SetAllowOverflow( bool set ); // generate error if not set and message is overflowed - bool IsOverflowed( void ) const; // returns true if the message was overflowed - - int GetSize( void ) const; // size of the message in bytes - void SetSize( int size ); // set the message size - int GetWriteBit( void ) const; // get current write bit - void SetWriteBit( int bit ); // set current write bit - int GetNumBitsWritten( void ) const; // returns number of bits written - int GetRemainingWriteBits( void ) const; // space left in bits for writing - void SaveWriteState( int &s, int &b ) const; // save the write state - void RestoreWriteState( int s, int b ); // restore the write state - - int GetReadCount( void ) const; // bytes read so far - void SetReadCount( int bytes ); // set the number of bytes and bits read - int GetReadBit( void ) const; // get current read bit - void SetReadBit( int bit ); // set current read bit - int GetNumBitsRead( void ) const; // returns number of bits read - int GetRemainingReadBits( void ) const; // number of bits left to read - void SaveReadState( int &c, int &b ) const; // save the read state - void RestoreReadState( int c, int b ); // restore the read state - - void BeginWriting( void ); // begin writing - int GetRemainingSpace( void ) const; // space left in bytes - void WriteByteAlign( void ); // write up to the next byte boundary - void WriteBits( int value, int numBits ); // write the specified number of bits - void WriteChar( int c ); - void WriteByte( int c ); - void WriteShort( int c ); - void WriteUShort( int c ); - void WriteLong( int c ); - void WriteFloat( float f ); - void WriteFloat( float f, int exponentBits, int mantissaBits ); - void WriteAngle8( float f ); - void WriteAngle16( float f ); - void WriteDir( const idVec3 &dir, int numBits ); - void WriteString( const char *s, int maxLength = -1, bool make7Bit = true ); - void WriteData( const void *data, int length ); - void WriteNetadr( const netadr_t adr ); - - void WriteDeltaChar( int oldValue, int newValue ); - void WriteDeltaByte( int oldValue, int newValue ); - void WriteDeltaShort( int oldValue, int newValue ); - void WriteDeltaLong( int oldValue, int newValue ); - void WriteDeltaFloat( float oldValue, float newValue ); - void WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ); - void WriteDeltaByteCounter( int oldValue, int newValue ); - void WriteDeltaShortCounter( int oldValue, int newValue ); - void WriteDeltaLongCounter( int oldValue, int newValue ); - bool WriteDeltaDict( const idDict &dict, const idDict *base ); - - void BeginReading( void ) const; // begin reading. - int GetRemaingData( void ) const; // number of bytes left to read - void ReadByteAlign( void ) const; // read up to the next byte boundary - int ReadBits( int numBits ) const; // read the specified number of bits - int ReadChar( void ) const; - int ReadByte( void ) const; - int ReadShort( void ) const; - int ReadUShort( void ) const; - int ReadLong( void ) const; - float ReadFloat( void ) const; - float ReadFloat( int exponentBits, int mantissaBits ) const; - float ReadAngle8( void ) const; - float ReadAngle16( void ) const; - idVec3 ReadDir( int numBits ) const; - int ReadString( char *buffer, int bufferSize ) const; - int ReadData( void *data, int length ) const; - void ReadNetadr( netadr_t *adr ) const; - - int ReadDeltaChar( int oldValue ) const; - int ReadDeltaByte( int oldValue ) const; - int ReadDeltaShort( int oldValue ) const; - int ReadDeltaLong( int oldValue ) const; - float ReadDeltaFloat( float oldValue ) const; - float ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const; - int ReadDeltaByteCounter( int oldValue ) const; - int ReadDeltaShortCounter( int oldValue ) const; - int ReadDeltaLongCounter( int oldValue ) const; - bool ReadDeltaDict( idDict &dict, const idDict *base ) const; - - static int DirToBits( const idVec3 &dir, int numBits ); - static idVec3 BitsToDir( int bits, int numBits ); - -private: - byte * writeData; // pointer to data for writing - const byte * readData; // pointer to data for reading - int maxSize; // maximum size of message in bytes - int curSize; // current size of message in bytes - int writeBit; // number of bits written to the last written byte - mutable int readCount; // number of bytes read so far - mutable int readBit; // number of bits read from the last read byte - bool allowOverflow; // if false, generate an error when the message is overflowed - bool overflowed; // set to true if the buffer size failed (with allowOverflow set) - -private: - bool CheckOverflow( int numBits ); - byte * GetByteSpace( int length ); - void WriteDelta( int oldValue, int newValue, int numBits ); - int ReadDelta( int oldValue, int numBits ) const; -}; - - -ID_INLINE void idBitMsg::Init( byte *data, int length ) { - writeData = data; - readData = data; - maxSize = length; -} - -ID_INLINE void idBitMsg::Init( const byte *data, int length ) { - writeData = NULL; - readData = data; - maxSize = length; -} - -ID_INLINE byte *idBitMsg::GetData( void ) { - return writeData; -} - -ID_INLINE const byte *idBitMsg::GetData( void ) const { - return readData; -} - -ID_INLINE int idBitMsg::GetMaxSize( void ) const { - return maxSize; -} - -ID_INLINE void idBitMsg::SetAllowOverflow( bool set ) { - allowOverflow = set; -} - -ID_INLINE bool idBitMsg::IsOverflowed( void ) const { - return overflowed; -} - -ID_INLINE int idBitMsg::GetSize( void ) const { - return curSize; -} - -ID_INLINE void idBitMsg::SetSize( int size ) { - if ( size > maxSize ) { - curSize = maxSize; - } else { - curSize = size; - } -} - -ID_INLINE int idBitMsg::GetWriteBit( void ) const { - return writeBit; -} - -ID_INLINE void idBitMsg::SetWriteBit( int bit ) { - writeBit = bit & 7; - if ( writeBit ) { - writeData[curSize - 1] &= ( 1 << writeBit ) - 1; - } -} - -ID_INLINE int idBitMsg::GetNumBitsWritten( void ) const { - return ( ( curSize << 3 ) - ( ( 8 - writeBit ) & 7 ) ); -} - -ID_INLINE int idBitMsg::GetRemainingWriteBits( void ) const { - return ( maxSize << 3 ) - GetNumBitsWritten(); -} - -ID_INLINE void idBitMsg::SaveWriteState( int &s, int &b ) const { - s = curSize; - b = writeBit; -} - -ID_INLINE void idBitMsg::RestoreWriteState( int s, int b ) { - curSize = s; - writeBit = b & 7; - if ( writeBit ) { - writeData[curSize - 1] &= ( 1 << writeBit ) - 1; - } -} - -ID_INLINE int idBitMsg::GetReadCount( void ) const { - return readCount; -} - -ID_INLINE void idBitMsg::SetReadCount( int bytes ) { - readCount = bytes; -} - -ID_INLINE int idBitMsg::GetReadBit( void ) const { - return readBit; -} - -ID_INLINE void idBitMsg::SetReadBit( int bit ) { - readBit = bit & 7; -} - -ID_INLINE int idBitMsg::GetNumBitsRead( void ) const { - return ( ( readCount << 3 ) - ( ( 8 - readBit ) & 7 ) ); -} - -ID_INLINE int idBitMsg::GetRemainingReadBits( void ) const { - return ( curSize << 3 ) - GetNumBitsRead(); -} - -ID_INLINE void idBitMsg::SaveReadState( int &c, int &b ) const { - c = readCount; - b = readBit; -} - -ID_INLINE void idBitMsg::RestoreReadState( int c, int b ) { - readCount = c; - readBit = b & 7; -} - -ID_INLINE void idBitMsg::BeginWriting( void ) { - curSize = 0; - overflowed = false; - writeBit = 0; -} - -ID_INLINE int idBitMsg::GetRemainingSpace( void ) const { - return maxSize - curSize; -} - -ID_INLINE void idBitMsg::WriteByteAlign( void ) { - writeBit = 0; -} - -ID_INLINE void idBitMsg::WriteChar( int c ) { - WriteBits( c, -8 ); -} - -ID_INLINE void idBitMsg::WriteByte( int c ) { - WriteBits( c, 8 ); -} - -ID_INLINE void idBitMsg::WriteShort( int c ) { - WriteBits( c, -16 ); -} - -ID_INLINE void idBitMsg::WriteUShort( int c ) { - WriteBits( c, 16 ); -} - -ID_INLINE void idBitMsg::WriteLong( int c ) { - WriteBits( c, 32 ); -} - -ID_INLINE void idBitMsg::WriteFloat( float f ) { - WriteBits( *reinterpret_cast(&f), 32 ); -} - -ID_INLINE void idBitMsg::WriteFloat( float f, int exponentBits, int mantissaBits ) { - int bits = idMath::FloatToBits( f, exponentBits, mantissaBits ); - WriteBits( bits, 1 + exponentBits + mantissaBits ); -} - -ID_INLINE void idBitMsg::WriteAngle8( float f ) { - WriteByte( ANGLE2BYTE( f ) ); -} - -ID_INLINE void idBitMsg::WriteAngle16( float f ) { - WriteShort( ANGLE2SHORT(f) ); -} - -ID_INLINE void idBitMsg::WriteDir( const idVec3 &dir, int numBits ) { - WriteBits( DirToBits( dir, numBits ), numBits ); -} - -ID_INLINE void idBitMsg::WriteDeltaChar( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, -8 ); -} - -ID_INLINE void idBitMsg::WriteDeltaByte( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, 8 ); -} - -ID_INLINE void idBitMsg::WriteDeltaShort( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, -16 ); -} - -ID_INLINE void idBitMsg::WriteDeltaLong( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, 32 ); -} - -ID_INLINE void idBitMsg::WriteDeltaFloat( float oldValue, float newValue ) { - WriteDelta( *reinterpret_cast(&oldValue), *reinterpret_cast(&newValue), 32 ); -} - -ID_INLINE void idBitMsg::WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ) { - int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); - int newBits = idMath::FloatToBits( newValue, exponentBits, mantissaBits ); - WriteDelta( oldBits, newBits, 1 + exponentBits + mantissaBits ); -} - -ID_INLINE void idBitMsg::BeginReading( void ) const { - readCount = 0; - readBit = 0; -} - -ID_INLINE int idBitMsg::GetRemaingData( void ) const { - return curSize - readCount; -} - -ID_INLINE void idBitMsg::ReadByteAlign( void ) const { - readBit = 0; -} - -ID_INLINE int idBitMsg::ReadChar( void ) const { - return (signed char)ReadBits( -8 ); -} - -ID_INLINE int idBitMsg::ReadByte( void ) const { - return (unsigned char)ReadBits( 8 ); -} - -ID_INLINE int idBitMsg::ReadShort( void ) const { - return (short)ReadBits( -16 ); -} - -ID_INLINE int idBitMsg::ReadUShort( void ) const { - return (unsigned short)ReadBits( 16 ); -} - -ID_INLINE int idBitMsg::ReadLong( void ) const { - return ReadBits( 32 ); -} - -ID_INLINE float idBitMsg::ReadFloat( void ) const { - float value; - *reinterpret_cast(&value) = ReadBits( 32 ); - return value; -} - -ID_INLINE float idBitMsg::ReadFloat( int exponentBits, int mantissaBits ) const { - int bits = ReadBits( 1 + exponentBits + mantissaBits ); - return idMath::BitsToFloat( bits, exponentBits, mantissaBits ); -} - -ID_INLINE float idBitMsg::ReadAngle8( void ) const { - return BYTE2ANGLE( ReadByte() ); -} - -ID_INLINE float idBitMsg::ReadAngle16( void ) const { - return SHORT2ANGLE( ReadShort() ); -} - -ID_INLINE idVec3 idBitMsg::ReadDir( int numBits ) const { - return BitsToDir( ReadBits( numBits ), numBits ); -} - -ID_INLINE int idBitMsg::ReadDeltaChar( int oldValue ) const { - return (signed char)ReadDelta( oldValue, -8 ); -} - -ID_INLINE int idBitMsg::ReadDeltaByte( int oldValue ) const { - return (unsigned char)ReadDelta( oldValue, 8 ); -} - -ID_INLINE int idBitMsg::ReadDeltaShort( int oldValue ) const { - return (short)ReadDelta( oldValue, -16 ); -} - -ID_INLINE int idBitMsg::ReadDeltaLong( int oldValue ) const { - return ReadDelta( oldValue, 32 ); -} - -ID_INLINE float idBitMsg::ReadDeltaFloat( float oldValue ) const { - float value; - *reinterpret_cast(&value) = ReadDelta( *reinterpret_cast(&oldValue), 32 ); - return value; -} - -ID_INLINE float idBitMsg::ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const { - int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); - int newBits = ReadDelta( oldBits, 1 + exponentBits + mantissaBits ); - return idMath::BitsToFloat( newBits, exponentBits, mantissaBits ); -} - - -/* -=============================================================================== - - idBitMsgDelta - -=============================================================================== -*/ - -class idBitMsgDelta { -public: - idBitMsgDelta(); - ~idBitMsgDelta() {} - - void Init( const idBitMsg *base, idBitMsg *newBase, idBitMsg *delta ); - void Init( const idBitMsg *base, idBitMsg *newBase, const idBitMsg *delta ); - bool HasChanged( void ) const; - - void WriteBits( int value, int numBits ); - void WriteChar( int c ); - void WriteByte( int c ); - void WriteShort( int c ); - void WriteUShort( int c ); - void WriteLong( int c ); - void WriteFloat( float f ); - void WriteFloat( float f, int exponentBits, int mantissaBits ); - void WriteAngle8( float f ); - void WriteAngle16( float f ); - void WriteDir( const idVec3 &dir, int numBits ); - void WriteString( const char *s, int maxLength = -1 ); - void WriteData( const void *data, int length ); - void WriteDict( const idDict &dict ); - - void WriteDeltaChar( int oldValue, int newValue ); - void WriteDeltaByte( int oldValue, int newValue ); - void WriteDeltaShort( int oldValue, int newValue ); - void WriteDeltaLong( int oldValue, int newValue ); - void WriteDeltaFloat( float oldValue, float newValue ); - void WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ); - void WriteDeltaByteCounter( int oldValue, int newValue ); - void WriteDeltaShortCounter( int oldValue, int newValue ); - void WriteDeltaLongCounter( int oldValue, int newValue ); - - int ReadBits( int numBits ) const; - int ReadChar( void ) const; - int ReadByte( void ) const; - int ReadShort( void ) const; - int ReadUShort( void ) const; - int ReadLong( void ) const; - float ReadFloat( void ) const; - float ReadFloat( int exponentBits, int mantissaBits ) const; - float ReadAngle8( void ) const; - float ReadAngle16( void ) const; - idVec3 ReadDir( int numBits ) const; - void ReadString( char *buffer, int bufferSize ) const; - void ReadData( void *data, int length ) const; - void ReadDict( idDict &dict ); - - int ReadDeltaChar( int oldValue ) const; - int ReadDeltaByte( int oldValue ) const; - int ReadDeltaShort( int oldValue ) const; - int ReadDeltaLong( int oldValue ) const; - float ReadDeltaFloat( float oldValue ) const; - float ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const; - int ReadDeltaByteCounter( int oldValue ) const; - int ReadDeltaShortCounter( int oldValue ) const; - int ReadDeltaLongCounter( int oldValue ) const; - -private: - const idBitMsg *base; // base - idBitMsg * newBase; // new base - idBitMsg * writeDelta; // delta from base to new base for writing - const idBitMsg *readDelta; // delta from base to new base for reading - mutable bool changed; // true if the new base is different from the base - -private: - void WriteDelta( int oldValue, int newValue, int numBits ); - int ReadDelta( int oldValue, int numBits ) const; -}; - -ID_INLINE idBitMsgDelta::idBitMsgDelta() { - base = NULL; - newBase = NULL; - writeDelta = NULL; - readDelta = NULL; - changed = false; -} - -ID_INLINE void idBitMsgDelta::Init( const idBitMsg *base, idBitMsg *newBase, idBitMsg *delta ) { - this->base = base; - this->newBase = newBase; - this->writeDelta = delta; - this->readDelta = delta; - this->changed = false; -} - -ID_INLINE void idBitMsgDelta::Init( const idBitMsg *base, idBitMsg *newBase, const idBitMsg *delta ) { - this->base = base; - this->newBase = newBase; - this->writeDelta = NULL; - this->readDelta = delta; - this->changed = false; -} - -ID_INLINE bool idBitMsgDelta::HasChanged( void ) const { - return changed; -} - -ID_INLINE void idBitMsgDelta::WriteChar( int c ) { - WriteBits( c, -8 ); -} - -ID_INLINE void idBitMsgDelta::WriteByte( int c ) { - WriteBits( c, 8 ); -} - -ID_INLINE void idBitMsgDelta::WriteShort( int c ) { - WriteBits( c, -16 ); -} - -ID_INLINE void idBitMsgDelta::WriteUShort( int c ) { - WriteBits( c, 16 ); -} - -ID_INLINE void idBitMsgDelta::WriteLong( int c ) { - WriteBits( c, 32 ); -} - -ID_INLINE void idBitMsgDelta::WriteFloat( float f ) { - WriteBits( *reinterpret_cast(&f), 32 ); -} - -ID_INLINE void idBitMsgDelta::WriteFloat( float f, int exponentBits, int mantissaBits ) { - int bits = idMath::FloatToBits( f, exponentBits, mantissaBits ); - WriteBits( bits, 1 + exponentBits + mantissaBits ); -} - -ID_INLINE void idBitMsgDelta::WriteAngle8( float f ) { - WriteBits( ANGLE2BYTE( f ), 8 ); -} - -ID_INLINE void idBitMsgDelta::WriteAngle16( float f ) { - WriteBits( ANGLE2SHORT(f), 16 ); -} - -ID_INLINE void idBitMsgDelta::WriteDir( const idVec3 &dir, int numBits ) { - WriteBits( idBitMsg::DirToBits( dir, numBits ), numBits ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaChar( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, -8 ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaByte( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, 8 ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaShort( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, -16 ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaLong( int oldValue, int newValue ) { - WriteDelta( oldValue, newValue, 32 ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaFloat( float oldValue, float newValue ) { - WriteDelta( *reinterpret_cast(&oldValue), *reinterpret_cast(&newValue), 32 ); -} - -ID_INLINE void idBitMsgDelta::WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ) { - int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); - int newBits = idMath::FloatToBits( newValue, exponentBits, mantissaBits ); - WriteDelta( oldBits, newBits, 1 + exponentBits + mantissaBits ); -} - -ID_INLINE int idBitMsgDelta::ReadChar( void ) const { - return (signed char)ReadBits( -8 ); -} - -ID_INLINE int idBitMsgDelta::ReadByte( void ) const { - return (unsigned char)ReadBits( 8 ); -} - -ID_INLINE int idBitMsgDelta::ReadShort( void ) const { - return (short)ReadBits( -16 ); -} - -ID_INLINE int idBitMsgDelta::ReadUShort( void ) const { - return (unsigned short)ReadBits( 16 ); -} - -ID_INLINE int idBitMsgDelta::ReadLong( void ) const { - return ReadBits( 32 ); -} - -ID_INLINE float idBitMsgDelta::ReadFloat( void ) const { - float value; - *reinterpret_cast(&value) = ReadBits( 32 ); - return value; -} - -ID_INLINE float idBitMsgDelta::ReadFloat( int exponentBits, int mantissaBits ) const { - int bits = ReadBits( 1 + exponentBits + mantissaBits ); - return idMath::BitsToFloat( bits, exponentBits, mantissaBits ); -} - -ID_INLINE float idBitMsgDelta::ReadAngle8( void ) const { - return BYTE2ANGLE( ReadByte() ); -} - -ID_INLINE float idBitMsgDelta::ReadAngle16( void ) const { - return SHORT2ANGLE( ReadShort() ); -} - -ID_INLINE idVec3 idBitMsgDelta::ReadDir( int numBits ) const { - return idBitMsg::BitsToDir( ReadBits( numBits ), numBits ); -} - -ID_INLINE int idBitMsgDelta::ReadDeltaChar( int oldValue ) const { - return (signed char)ReadDelta( oldValue, -8 ); -} - -ID_INLINE int idBitMsgDelta::ReadDeltaByte( int oldValue ) const { - return (unsigned char)ReadDelta( oldValue, 8 ); -} - -ID_INLINE int idBitMsgDelta::ReadDeltaShort( int oldValue ) const { - return (short)ReadDelta( oldValue, -16 ); -} - -ID_INLINE int idBitMsgDelta::ReadDeltaLong( int oldValue ) const { - return ReadDelta( oldValue, 32 ); -} - -ID_INLINE float idBitMsgDelta::ReadDeltaFloat( float oldValue ) const { - float value; - *reinterpret_cast(&value) = ReadDelta( *reinterpret_cast(&oldValue), 32 ); - return value; -} - -ID_INLINE float idBitMsgDelta::ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const { - int oldBits = idMath::FloatToBits( oldValue, exponentBits, mantissaBits ); - int newBits = ReadDelta( oldBits, 1 + exponentBits + mantissaBits ); - return idMath::BitsToFloat( newBits, exponentBits, mantissaBits ); -} - -#endif /* !__BITMSG_H__ */ diff --git a/idlib/bv/Bounds.cpp b/idlib/bv/Bounds.cpp new file mode 100644 index 000000000..229280391 --- /dev/null +++ b/idlib/bv/Bounds.cpp @@ -0,0 +1,427 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +idBounds bounds_zero( vec3_zero, vec3_zero ); + +/* +============ +idBounds::GetRadius +============ +*/ +float idBounds::GetRadius( void ) const { + int i; + float total, b0, b1; + + total = 0.0f; + for ( i = 0; i < 3; i++ ) { + b0 = (float)idMath::Fabs( b[0][i] ); + b1 = (float)idMath::Fabs( b[1][i] ); + if ( b0 > b1 ) { + total += b0 * b0; + } else { + total += b1 * b1; + } + } + return idMath::Sqrt( total ); +} + +/* +============ +idBounds::GetRadius +============ +*/ +float idBounds::GetRadius( const idVec3 ¢er ) const { + int i; + float total, b0, b1; + + total = 0.0f; + for ( i = 0; i < 3; i++ ) { + b0 = (float)idMath::Fabs( center[i] - b[0][i] ); + b1 = (float)idMath::Fabs( b[1][i] - center[i] ); + if ( b0 > b1 ) { + total += b0 * b0; + } else { + total += b1 * b1; + } + } + return idMath::Sqrt( total ); +} + +/* +================ +idBounds::PlaneDistance +================ +*/ +float idBounds::PlaneDistance( const idPlane &plane ) const { + idVec3 center; + float d1, d2; + + center = ( b[0] + b[1] ) * 0.5f; + + d1 = plane.Distance( center ); + d2 = idMath::Fabs( ( b[1][0] - center[0] ) * plane.Normal()[0] ) + + idMath::Fabs( ( b[1][1] - center[1] ) * plane.Normal()[1] ) + + idMath::Fabs( ( b[1][2] - center[2] ) * plane.Normal()[2] ); + + if ( d1 - d2 > 0.0f ) { + return d1 - d2; + } + if ( d1 + d2 < 0.0f ) { + return d1 + d2; + } + return 0.0f; +} + +/* +================ +idBounds::PlaneSide +================ +*/ +int idBounds::PlaneSide( const idPlane &plane, const float epsilon ) const { + idVec3 center; + float d1, d2; + + center = ( b[0] + b[1] ) * 0.5f; + + d1 = plane.Distance( center ); + d2 = idMath::Fabs( ( b[1][0] - center[0] ) * plane.Normal()[0] ) + + idMath::Fabs( ( b[1][1] - center[1] ) * plane.Normal()[1] ) + + idMath::Fabs( ( b[1][2] - center[2] ) * plane.Normal()[2] ); + + if ( d1 - d2 > epsilon ) { + return PLANESIDE_FRONT; + } + if ( d1 + d2 < -epsilon ) { + return PLANESIDE_BACK; + } + return PLANESIDE_CROSS; +} + +/* +============ +idBounds::LineIntersection + + Returns true if the line intersects the bounds between the start and end point. +============ +*/ +bool idBounds::LineIntersection( const idVec3 &start, const idVec3 &end ) const { + float ld[3]; + idVec3 center = ( b[0] + b[1] ) * 0.5f; + idVec3 extents = b[1] - center; + idVec3 lineDir = 0.5f * ( end - start ); + idVec3 lineCenter = start + lineDir; + idVec3 dir = lineCenter - center; + + ld[0] = idMath::Fabs( lineDir[0] ); + if ( idMath::Fabs( dir[0] ) > extents[0] + ld[0] ) { + return false; + } + + ld[1] = idMath::Fabs( lineDir[1] ); + if ( idMath::Fabs( dir[1] ) > extents[1] + ld[1] ) { + return false; + } + + ld[2] = idMath::Fabs( lineDir[2] ); + if ( idMath::Fabs( dir[2] ) > extents[2] + ld[2] ) { + return false; + } + + idVec3 cross = lineDir.Cross( dir ); + + if ( idMath::Fabs( cross[0] ) > extents[1] * ld[2] + extents[2] * ld[1] ) { + return false; + } + + if ( idMath::Fabs( cross[1] ) > extents[0] * ld[2] + extents[2] * ld[0] ) { + return false; + } + + if ( idMath::Fabs( cross[2] ) > extents[0] * ld[1] + extents[1] * ld[0] ) { + return false; + } + + return true; +} + +/* +============ +idBounds::RayIntersection + + Returns true if the ray intersects the bounds. + The ray can intersect the bounds in both directions from the start point. + If start is inside the bounds it is considered an intersection with scale = 0 +============ +*/ +bool idBounds::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const { + int i, ax0, ax1, ax2, side, inside; + float f; + idVec3 hit; + + ax0 = -1; + inside = 0; + for ( i = 0; i < 3; i++ ) { + if ( start[i] < b[0][i] ) { + side = 0; + } + else if ( start[i] > b[1][i] ) { + side = 1; + } + else { + inside++; + continue; + } + if ( dir[i] == 0.0f ) { + continue; + } + f = ( start[i] - b[side][i] ); + if ( ax0 < 0 || idMath::Fabs( f ) > idMath::Fabs( scale * dir[i] ) ) { + scale = - ( f / dir[i] ); + ax0 = i; + } + } + + if ( ax0 < 0 ) { + scale = 0.0f; + // return true if the start point is inside the bounds + return ( inside == 3 ); + } + + ax1 = (ax0+1)%3; + ax2 = (ax0+2)%3; + hit[ax1] = start[ax1] + scale * dir[ax1]; + hit[ax2] = start[ax2] + scale * dir[ax2]; + + return ( hit[ax1] >= b[0][ax1] && hit[ax1] <= b[1][ax1] && + hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] ); +} + +/* +============ +idBounds::FromTransformedBounds +============ +*/ +void idBounds::FromTransformedBounds( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) { + int i; + idVec3 center, extents, rotatedExtents; + + center = (bounds[0] + bounds[1]) * 0.5f; + extents = bounds[1] - center; + + for ( i = 0; i < 3; i++ ) { + rotatedExtents[i] = idMath::Fabs( extents[0] * axis[0][i] ) + + idMath::Fabs( extents[1] * axis[1][i] ) + + idMath::Fabs( extents[2] * axis[2][i] ); + } + + center = origin + center * axis; + b[0] = center - rotatedExtents; + b[1] = center + rotatedExtents; +} + +/* +============ +idBounds::FromPoints + + Most tight bounds for a point set. +============ +*/ +void idBounds::FromPoints( const idVec3 *points, const int numPoints ) { + SIMDProcessor->MinMax( b[0], b[1], points, numPoints ); +} + +/* +============ +idBounds::FromPointTranslation + + Most tight bounds for the translational movement of the given point. +============ +*/ +void idBounds::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { + int i; + + for ( i = 0; i < 3; i++ ) { + if ( translation[i] < 0.0f ) { + b[0][i] = point[i] + translation[i]; + b[1][i] = point[i]; + } + else { + b[0][i] = point[i]; + b[1][i] = point[i] + translation[i]; + } + } +} + +/* +============ +idBounds::FromBoundsTranslation + + Most tight bounds for the translational movement of the given bounds. +============ +*/ +void idBounds::FromBoundsTranslation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation ) { + int i; + + if ( axis.IsRotated() ) { + FromTransformedBounds( bounds, origin, axis ); + } + else { + b[0] = bounds[0] + origin; + b[1] = bounds[1] + origin; + } + for ( i = 0; i < 3; i++ ) { + if ( translation[i] < 0.0f ) { + b[0][i] += translation[i]; + } + else { + b[1][i] += translation[i]; + } + } +} + +/* +================ +BoundsForPointRotation + + only for rotations < 180 degrees +================ +*/ +idBounds BoundsForPointRotation( const idVec3 &start, const idRotation &rotation ) { + int i; + float radiusSqr; + idVec3 v1, v2; + idVec3 origin, axis, end; + idBounds bounds; + + end = start * rotation; + axis = rotation.GetVec(); + origin = rotation.GetOrigin() + axis * ( axis * ( start - rotation.GetOrigin() ) ); + radiusSqr = ( start - origin ).LengthSqr(); + v1 = ( start - origin ).Cross( axis ); + v2 = ( end - origin ).Cross( axis ); + + for ( i = 0; i < 3; i++ ) { + // if the derivative changes sign along this axis during the rotation from start to end + if ( ( v1[i] > 0.0f && v2[i] < 0.0f ) || ( v1[i] < 0.0f && v2[i] > 0.0f ) ) { + if ( ( 0.5f * (start[i] + end[i]) - origin[i] ) > 0.0f ) { + bounds[0][i] = Min( start[i], end[i] ); + bounds[1][i] = origin[i] + idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); + } + else { + bounds[0][i] = origin[i] - idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); + bounds[1][i] = Max( start[i], end[i] ); + } + } + else if ( start[i] > end[i] ) { + bounds[0][i] = end[i]; + bounds[1][i] = start[i]; + } + else { + bounds[0][i] = start[i]; + bounds[1][i] = end[i]; + } + } + + return bounds; +} + +/* +============ +idBounds::FromPointRotation + + Most tight bounds for the rotational movement of the given point. +============ +*/ +void idBounds::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { + float radius; + + if ( idMath::Fabs( rotation.GetAngle() ) < 180.0f ) { + (*this) = BoundsForPointRotation( point, rotation ); + } + else { + + radius = ( point - rotation.GetOrigin() ).Length(); + + // FIXME: these bounds are usually way larger + b[0].Set( -radius, -radius, -radius ); + b[1].Set( radius, radius, radius ); + } +} + +/* +============ +idBounds::FromBoundsRotation + + Most tight bounds for the rotational movement of the given bounds. +============ +*/ +void idBounds::FromBoundsRotation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation ) { + int i; + float radius; + idVec3 point; + idBounds rBounds; + + if ( idMath::Fabs( rotation.GetAngle() ) < 180.0f ) { + + (*this) = BoundsForPointRotation( bounds[0] * axis + origin, rotation ); + for ( i = 1; i < 8; i++ ) { + point[0] = bounds[(i^(i>>1))&1][0]; + point[1] = bounds[(i>>1)&1][1]; + point[2] = bounds[(i>>2)&1][2]; + (*this) += BoundsForPointRotation( point * axis + origin, rotation ); + } + } + else { + + point = (bounds[1] - bounds[0]) * 0.5f; + radius = (bounds[1] - point).Length() + (point - rotation.GetOrigin()).Length(); + + // FIXME: these bounds are usually way larger + b[0].Set( -radius, -radius, -radius ); + b[1].Set( radius, radius, radius ); + } +} + +/* +============ +idBounds::ToPoints +============ +*/ +void idBounds::ToPoints( idVec3 points[8] ) const { + for ( int i = 0; i < 8; i++ ) { + points[i][0] = b[(i^(i>>1))&1][0]; + points[i][1] = b[(i>>1)&1][1]; + points[i][2] = b[(i>>2)&1][2]; + } +} + +/* +============ +idBounds::ToString +============ +*/ +const char * idBounds::ToString( const int precision ) const { + return idStr( b[0].ToString( precision ) ) + " -> " + idStr( b[1].ToString( precision ) ); +} + diff --git a/idlib/bv/Bounds.h b/idlib/bv/Bounds.h new file mode 100644 index 000000000..507cb6f04 --- /dev/null +++ b/idlib/bv/Bounds.h @@ -0,0 +1,449 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BV_BOUNDS_H__ +#define __BV_BOUNDS_H__ + +/* +=============================================================================== + + Axis Aligned Bounding Box + +=============================================================================== +*/ + +class idBounds { +public: + idBounds( void ); + explicit idBounds( const idVec3 &mins, const idVec3 &maxs ); + explicit idBounds( const idVec3 &point ); + + const idVec3 & operator[]( const int index ) const; + idVec3 & operator[]( const int index ); + idBounds operator+( const idVec3 &t ) const; // returns translated bounds + idBounds & operator+=( const idVec3 &t ); // translate the bounds + idBounds operator*( const idMat3 &r ) const; // returns rotated bounds + idBounds & operator*=( const idMat3 &r ); // rotate the bounds + idBounds operator+( const idBounds &a ) const; + idBounds & operator+=( const idBounds &a ); + idBounds operator-( const idBounds &a ) const; + idBounds & operator-=( const idBounds &a ); + + bool Compare( const idBounds &a ) const; // exact compare, no epsilon + bool Compare( const idBounds &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idBounds &a ) const; // exact compare, no epsilon + bool operator!=( const idBounds &a ) const; // exact compare, no epsilon + + void Clear( void ); // inside out bounds + void Zero( void ); // single point at origin + + idVec3 GetCenter( void ) const; // returns center of bounds + float GetRadius( void ) const; // returns the radius relative to the bounds origin + // greebo: Note that this does NOT return 0.0 for a + // idBounds object with b[0] == b[1] as one might suspect. + // I don't know what the intention for this code is, so I'll leave it. + // Use GetVolume() instead. + float GetRadius( const idVec3 ¢er ) const; // returns the radius relative to the given center + float GetVolume( void ) const; // returns the volume of the bounds + + /** + * Tels: Get the size of the bounds, that is b1 - b0 + */ + idVec3 GetSize( void ) const; + + bool IsCleared( void ) const; // returns true if bounds are inside out + + bool AddPoint( const idVec3 &v ); // add the point, returns true if the bounds expanded + bool AddBounds( const idBounds &a ); // add the bounds, returns true if the bounds expanded + idBounds Intersect( const idBounds &a ) const; // return intersection of this bounds with the given bounds + idBounds & IntersectSelf( const idBounds &a ); // intersect this bounds with the given bounds + idBounds Expand( const float d ) const; // return bounds expanded in all directions with the given value + idBounds & ExpandSelf( const float d ); // expand bounds in all directions with the given value + idBounds Translate( const idVec3 &translation ) const; // return translated bounds + idBounds & TranslateSelf( const idVec3 &translation ); // translate this bounds + idBounds Rotate( const idMat3 &rotation ) const; // return rotated bounds + idBounds & RotateSelf( const idMat3 &rotation ); // rotate this bounds + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + bool ContainsPoint( const idVec3 &p ) const; // includes touching + bool IntersectsBounds( const idBounds &a ) const; // includes touching + bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; + // intersection point is start + dir * scale + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const; + + // most tight bounds for the given transformed bounds + void FromTransformedBounds( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ); + // most tight bounds for a point set + void FromPoints( const idVec3 *points, const int numPoints ); + // most tight bounds for a translation + void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); + void FromBoundsTranslation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation ); + // most tight bounds for a rotation + void FromPointRotation( const idVec3 &point, const idRotation &rotation ); + void FromBoundsRotation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation ); + + void ToPoints( idVec3 points[8] ) const; + idSphere ToSphere( void ) const; + + const char * ToString( const int precision = 2 ) const; + + void AxisProjection( const idVec3 &dir, float &min, float &max ) const; + void AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const; + +private: + idVec3 b[2]; +}; + +extern idBounds bounds_zero; + +ID_INLINE idBounds::idBounds( void ) { +} + +ID_INLINE idBounds::idBounds( const idVec3 &mins, const idVec3 &maxs ) { + b[0] = mins; + b[1] = maxs; +} + +ID_INLINE idBounds::idBounds( const idVec3 &point ) { + b[0] = point; + b[1] = point; +} + +ID_INLINE const idVec3 &idBounds::operator[]( const int index ) const { + return b[index]; +} + +ID_INLINE idVec3 &idBounds::operator[]( const int index ) { + return b[index]; +} + +ID_INLINE idBounds idBounds::operator+( const idVec3 &t ) const { + return idBounds( b[0] + t, b[1] + t ); +} + +ID_INLINE idBounds &idBounds::operator+=( const idVec3 &t ) { + b[0] += t; + b[1] += t; + return *this; +} + +ID_INLINE idBounds idBounds::operator*( const idMat3 &r ) const { + idBounds bounds; + bounds.FromTransformedBounds( *this, vec3_origin, r ); + return bounds; +} + +ID_INLINE idBounds &idBounds::operator*=( const idMat3 &r ) { + this->FromTransformedBounds( *this, vec3_origin, r ); + return *this; +} + +ID_INLINE idBounds idBounds::operator+( const idBounds &a ) const { + idBounds newBounds; + newBounds = *this; + newBounds.AddBounds( a ); + return newBounds; +} + +ID_INLINE idBounds &idBounds::operator+=( const idBounds &a ) { + idBounds::AddBounds( a ); + return *this; +} + +ID_INLINE idBounds idBounds::operator-( const idBounds &a ) const { + assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] && + b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] && + b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] ); + return idBounds( idVec3( b[0][0] + a.b[1][0], b[0][1] + a.b[1][1], b[0][2] + a.b[1][2] ), + idVec3( b[1][0] + a.b[0][0], b[1][1] + a.b[0][1], b[1][2] + a.b[0][2] ) ); +} + +ID_INLINE idBounds &idBounds::operator-=( const idBounds &a ) { + assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] && + b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] && + b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] ); + b[0] += a.b[1]; + b[1] += a.b[0]; + return *this; +} + +ID_INLINE bool idBounds::Compare( const idBounds &a ) const { + return ( b[0].Compare( a.b[0] ) && b[1].Compare( a.b[1] ) ); +} + +ID_INLINE bool idBounds::Compare( const idBounds &a, const float epsilon ) const { + return ( b[0].Compare( a.b[0], epsilon ) && b[1].Compare( a.b[1], epsilon ) ); +} + +ID_INLINE bool idBounds::operator==( const idBounds &a ) const { + return Compare( a ); +} + +ID_INLINE bool idBounds::operator!=( const idBounds &a ) const { + return !Compare( a ); +} + +ID_INLINE void idBounds::Clear( void ) { + b[0][0] = b[0][1] = b[0][2] = idMath::INFINITY; + b[1][0] = b[1][1] = b[1][2] = -idMath::INFINITY; +} + +ID_INLINE void idBounds::Zero( void ) { + b[0][0] = b[0][1] = b[0][2] = + b[1][0] = b[1][1] = b[1][2] = 0; +} + +ID_INLINE idVec3 idBounds::GetCenter( void ) const { + return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f ); +} + +ID_INLINE float idBounds::GetVolume( void ) const { + if ( b[0][0] >= b[1][0] || b[0][1] >= b[1][1] || b[0][2] >= b[1][2] ) { + return 0.0f; + } + return ( ( b[1][0] - b[0][0] ) * ( b[1][1] - b[0][1] ) * ( b[1][2] - b[0][2] ) ); +} + +/** +* Tels: Get the size of the bounds, that is b1 - b0 +*/ +ID_INLINE idVec3 idBounds::GetSize( void ) const { + return idVec3( b[1][0] - b[0][0], b[1][1] - b[0][1], b[1][2] - b[0][2] ); +} + +ID_INLINE bool idBounds::IsCleared( void ) const { + return b[0][0] > b[1][0]; +} + +ID_INLINE bool idBounds::AddPoint( const idVec3 &v ) { + bool expanded = false; + if ( v[0] < b[0][0]) { + b[0][0] = v[0]; + expanded = true; + } + if ( v[0] > b[1][0]) { + b[1][0] = v[0]; + expanded = true; + } + if ( v[1] < b[0][1] ) { + b[0][1] = v[1]; + expanded = true; + } + if ( v[1] > b[1][1]) { + b[1][1] = v[1]; + expanded = true; + } + if ( v[2] < b[0][2] ) { + b[0][2] = v[2]; + expanded = true; + } + if ( v[2] > b[1][2]) { + b[1][2] = v[2]; + expanded = true; + } + return expanded; +} + +ID_INLINE bool idBounds::AddBounds( const idBounds &a ) { + bool expanded = false; + if ( a.b[0][0] < b[0][0] ) { + b[0][0] = a.b[0][0]; + expanded = true; + } + if ( a.b[0][1] < b[0][1] ) { + b[0][1] = a.b[0][1]; + expanded = true; + } + if ( a.b[0][2] < b[0][2] ) { + b[0][2] = a.b[0][2]; + expanded = true; + } + if ( a.b[1][0] > b[1][0] ) { + b[1][0] = a.b[1][0]; + expanded = true; + } + if ( a.b[1][1] > b[1][1] ) { + b[1][1] = a.b[1][1]; + expanded = true; + } + if ( a.b[1][2] > b[1][2] ) { + b[1][2] = a.b[1][2]; + expanded = true; + } + return expanded; +} + +ID_INLINE idBounds idBounds::Intersect( const idBounds &a ) const { + idBounds n; + + // grayman #2734 - Check for intersecting first. Note that if there's + // no intersection, a bounds with zero min/max points is returned, so + // if that matters, you should check for that at the spot where this + // is called. + + n.Zero(); + if (IntersectsBounds(a)) + { + n.b[0][0] = ( a.b[0][0] > b[0][0] ) ? a.b[0][0] : b[0][0]; + n.b[0][1] = ( a.b[0][1] > b[0][1] ) ? a.b[0][1] : b[0][1]; + n.b[0][2] = ( a.b[0][2] > b[0][2] ) ? a.b[0][2] : b[0][2]; + n.b[1][0] = ( a.b[1][0] < b[1][0] ) ? a.b[1][0] : b[1][0]; + n.b[1][1] = ( a.b[1][1] < b[1][1] ) ? a.b[1][1] : b[1][1]; + n.b[1][2] = ( a.b[1][2] < b[1][2] ) ? a.b[1][2] : b[1][2]; + } + return n; +} + +ID_INLINE idBounds &idBounds::IntersectSelf( const idBounds &a ) { + + // grayman #2734 - Check for intersecting first. Note that if there's + // no intersection, "this" bounds' max point is set to the min point, so + // if that matters, you should check for that at the spot where this + // is called. As of this writing, IntersectSelf() isn't used anywhere. + + if (IntersectsBounds(a)) + { + if ( a.b[0][0] > b[0][0] ) + { + b[0][0] = a.b[0][0]; + } + if ( a.b[0][1] > b[0][1] ) + { + b[0][1] = a.b[0][1]; + } + if ( a.b[0][2] > b[0][2] ) + { + b[0][2] = a.b[0][2]; + } + if ( a.b[1][0] < b[1][0] ) + { + b[1][0] = a.b[1][0]; + } + if ( a.b[1][1] < b[1][1] ) + { + b[1][1] = a.b[1][1]; + } + if ( a.b[1][2] < b[1][2] ) + { + b[1][2] = a.b[1][2]; + } + } + else + { + b[1] = b[0]; // no intersection, so collapse the bounds + } + + return *this; +} + +ID_INLINE idBounds idBounds::Expand( const float d ) const { + return idBounds( idVec3( b[0][0] - d, b[0][1] - d, b[0][2] - d ), + idVec3( b[1][0] + d, b[1][1] + d, b[1][2] + d ) ); +} + +ID_INLINE idBounds &idBounds::ExpandSelf( const float d ) { + b[0][0] -= d; + b[0][1] -= d; + b[0][2] -= d; + b[1][0] += d; + b[1][1] += d; + b[1][2] += d; + return *this; +} + +ID_INLINE idBounds idBounds::Translate( const idVec3 &translation ) const { + return idBounds( b[0] + translation, b[1] + translation ); +} + +ID_INLINE idBounds &idBounds::TranslateSelf( const idVec3 &translation ) { + b[0] += translation; + b[1] += translation; + return *this; +} + +ID_INLINE idBounds idBounds::Rotate( const idMat3 &rotation ) const { + idBounds bounds; + bounds.FromTransformedBounds( *this, vec3_origin, rotation ); + return bounds; +} + +ID_INLINE idBounds &idBounds::RotateSelf( const idMat3 &rotation ) { + FromTransformedBounds( *this, vec3_origin, rotation ); + return *this; +} + +ID_INLINE bool idBounds::ContainsPoint( const idVec3 &p ) const { + if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] + || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) { + return false; + } + return true; +} + +ID_INLINE bool idBounds::IntersectsBounds( const idBounds &a ) const { + if ( a.b[1][0] < b[0][0] || a.b[1][1] < b[0][1] || a.b[1][2] < b[0][2] + || a.b[0][0] > b[1][0] || a.b[0][1] > b[1][1] || a.b[0][2] > b[1][2] ) { + return false; + } + return true; +} + +ID_INLINE idSphere idBounds::ToSphere( void ) const { + idSphere sphere; + sphere.SetOrigin( ( b[0] + b[1] ) * 0.5f ); + sphere.SetRadius( ( b[1] - sphere.GetOrigin() ).Length() ); + return sphere; +} + +ID_INLINE void idBounds::AxisProjection( const idVec3 &dir, float &min, float &max ) const { + float d1, d2; + idVec3 center, extents; + + center = ( b[0] + b[1] ) * 0.5f; + extents = b[1] - center; + + d1 = dir * center; + d2 = idMath::Fabs( extents[0] * dir[0] ) + + idMath::Fabs( extents[1] * dir[1] ) + + idMath::Fabs( extents[2] * dir[2] ); + + min = d1 - d2; + max = d1 + d2; +} + +ID_INLINE void idBounds::AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const { + float d1, d2; + idVec3 center, extents; + + center = ( b[0] + b[1] ) * 0.5f; + extents = b[1] - center; + center = origin + center * axis; + + d1 = dir * center; + d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) + + idMath::Fabs( extents[1] * ( dir * axis[1] ) ) + + idMath::Fabs( extents[2] * ( dir * axis[2] ) ); + + min = d1 - d2; + max = d1 + d2; +} + +#endif /* !__BV_BOUNDS_H__ */ diff --git a/idlib/bv/Box.cpp b/idlib/bv/Box.cpp new file mode 100644 index 000000000..4a7834049 --- /dev/null +++ b/idlib/bv/Box.cpp @@ -0,0 +1,853 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +idBox box_zero( vec3_zero, vec3_zero, mat3_identity ); + +/* + 4---{4}---5 + + /| /| + Z {7} {8} {5} | + - / | / {9} + 7--{6}----6 | + | | | | + {11} 0---|-{0}-1 + | / | / - + | {3} {10} {1} Y + |/ |/ + + 3---{2}---2 + + - X + + + plane bits: + 0 = min x + 1 = max x + 2 = min y + 3 = max y + 4 = min z + 5 = max z + +*/ + +static int boxVertPlanes[8] = { + ( (1<<0) | (1<<2) | (1<<4) ), + ( (1<<1) | (1<<2) | (1<<4) ), + ( (1<<1) | (1<<3) | (1<<4) ), + ( (1<<0) | (1<<3) | (1<<4) ), + ( (1<<0) | (1<<2) | (1<<5) ), + ( (1<<1) | (1<<2) | (1<<5) ), + ( (1<<1) | (1<<3) | (1<<5) ), + ( (1<<0) | (1<<3) | (1<<5) ) +}; + +static int boxVertEdges[8][3] = { + // bottom + { 3, 0, 8 }, + { 0, 1, 9 }, + { 1, 2, 10 }, + { 2, 3, 11 }, + // top + { 7, 4, 8 }, + { 4, 5, 9 }, + { 5, 6, 10 }, + { 6, 7, 11 } +}; + +static int boxEdgePlanes[12][2] = { + // bottom + { 4, 2 }, + { 4, 1 }, + { 4, 3 }, + { 4, 0 }, + // top + { 5, 2 }, + { 5, 1 }, + { 5, 3 }, + { 5, 0 }, + // sides + { 0, 2 }, + { 2, 1 }, + { 1, 3 }, + { 3, 0 } +}; + +static int boxEdgeVerts[12][2] = { + // bottom + { 0, 1 }, + { 1, 2 }, + { 2, 3 }, + { 3, 0 }, + // top + { 4, 5 }, + { 5, 6 }, + { 6, 7 }, + { 7, 4 }, + // sides + { 0, 4 }, + { 1, 5 }, + { 2, 6 }, + { 3, 7 } +}; + +static int boxPlaneBitsSilVerts[64][7] = { + { 0, 0, 0, 0, 0, 0, 0 }, // 000000 = 0 + { 4, 7, 4, 0, 3, 0, 0 }, // 000001 = 1 + { 4, 5, 6, 2, 1, 0, 0 }, // 000010 = 2 + { 0, 0, 0, 0, 0, 0, 0 }, // 000011 = 3 + { 4, 4, 5, 1, 0, 0, 0 }, // 000100 = 4 + { 6, 3, 7, 4, 5, 1, 0 }, // 000101 = 5 + { 6, 4, 5, 6, 2, 1, 0 }, // 000110 = 6 + { 0, 0, 0, 0, 0, 0, 0 }, // 000111 = 7 + { 4, 6, 7, 3, 2, 0, 0 }, // 001000 = 8 + { 6, 6, 7, 4, 0, 3, 2 }, // 001001 = 9 + { 6, 5, 6, 7, 3, 2, 1 }, // 001010 = 10 + { 0, 0, 0, 0, 0, 0, 0 }, // 001011 = 11 + { 0, 0, 0, 0, 0, 0, 0 }, // 001100 = 12 + { 0, 0, 0, 0, 0, 0, 0 }, // 001101 = 13 + { 0, 0, 0, 0, 0, 0, 0 }, // 001110 = 14 + { 0, 0, 0, 0, 0, 0, 0 }, // 001111 = 15 + { 4, 0, 1, 2, 3, 0, 0 }, // 010000 = 16 + { 6, 0, 1, 2, 3, 7, 4 }, // 010001 = 17 + { 6, 3, 2, 6, 5, 1, 0 }, // 010010 = 18 + { 0, 0, 0, 0, 0, 0, 0 }, // 010011 = 19 + { 6, 1, 2, 3, 0, 4, 5 }, // 010100 = 20 + { 6, 1, 2, 3, 7, 4, 5 }, // 010101 = 21 + { 6, 2, 3, 0, 4, 5, 6 }, // 010110 = 22 + { 0, 0, 0, 0, 0, 0, 0 }, // 010111 = 23 + { 6, 0, 1, 2, 6, 7, 3 }, // 011000 = 24 + { 6, 0, 1, 2, 6, 7, 4 }, // 011001 = 25 + { 6, 0, 1, 5, 6, 7, 3 }, // 011010 = 26 + { 0, 0, 0, 0, 0, 0, 0 }, // 011011 = 27 + { 0, 0, 0, 0, 0, 0, 0 }, // 011100 = 28 + { 0, 0, 0, 0, 0, 0, 0 }, // 011101 = 29 + { 0, 0, 0, 0, 0, 0, 0 }, // 011110 = 30 + { 0, 0, 0, 0, 0, 0, 0 }, // 011111 = 31 + { 4, 7, 6, 5, 4, 0, 0 }, // 100000 = 32 + { 6, 7, 6, 5, 4, 0, 3 }, // 100001 = 33 + { 6, 5, 4, 7, 6, 2, 1 }, // 100010 = 34 + { 0, 0, 0, 0, 0, 0, 0 }, // 100011 = 35 + { 6, 4, 7, 6, 5, 1, 0 }, // 100100 = 36 + { 6, 3, 7, 6, 5, 1, 0 }, // 100101 = 37 + { 6, 4, 7, 6, 2, 1, 0 }, // 100110 = 38 + { 0, 0, 0, 0, 0, 0, 0 }, // 100111 = 39 + { 6, 6, 5, 4, 7, 3, 2 }, // 101000 = 40 + { 6, 6, 5, 4, 0, 3, 2 }, // 101001 = 41 + { 6, 5, 4, 7, 3, 2, 1 }, // 101010 = 42 + { 0, 0, 0, 0, 0, 0, 0 }, // 101011 = 43 + { 0, 0, 0, 0, 0, 0, 0 }, // 101100 = 44 + { 0, 0, 0, 0, 0, 0, 0 }, // 101101 = 45 + { 0, 0, 0, 0, 0, 0, 0 }, // 101110 = 46 + { 0, 0, 0, 0, 0, 0, 0 }, // 101111 = 47 + { 0, 0, 0, 0, 0, 0, 0 }, // 110000 = 48 + { 0, 0, 0, 0, 0, 0, 0 }, // 110001 = 49 + { 0, 0, 0, 0, 0, 0, 0 }, // 110010 = 50 + { 0, 0, 0, 0, 0, 0, 0 }, // 110011 = 51 + { 0, 0, 0, 0, 0, 0, 0 }, // 110100 = 52 + { 0, 0, 0, 0, 0, 0, 0 }, // 110101 = 53 + { 0, 0, 0, 0, 0, 0, 0 }, // 110110 = 54 + { 0, 0, 0, 0, 0, 0, 0 }, // 110111 = 55 + { 0, 0, 0, 0, 0, 0, 0 }, // 111000 = 56 + { 0, 0, 0, 0, 0, 0, 0 }, // 111001 = 57 + { 0, 0, 0, 0, 0, 0, 0 }, // 111010 = 58 + { 0, 0, 0, 0, 0, 0, 0 }, // 111011 = 59 + { 0, 0, 0, 0, 0, 0, 0 }, // 111100 = 60 + { 0, 0, 0, 0, 0, 0, 0 }, // 111101 = 61 + { 0, 0, 0, 0, 0, 0, 0 }, // 111110 = 62 + { 0, 0, 0, 0, 0, 0, 0 }, // 111111 = 63 +}; + + +/* +============ +idBox::AddPoint +============ +*/ +bool idBox::AddPoint( const idVec3 &v ) { + idMat3 axis2; + idBounds bounds1, bounds2; + + if ( extents[0] < 0.0f ) { + extents.Zero(); + center = v; + axis.Identity(); + return true; + } + + bounds1[0][0] = bounds1[1][0] = center * axis[0]; + bounds1[0][1] = bounds1[1][1] = center * axis[1]; + bounds1[0][2] = bounds1[1][2] = center * axis[2]; + bounds1[0] -= extents; + bounds1[1] += extents; + if ( !bounds1.AddPoint( idVec3( v * axis[0], v * axis[1], v * axis[2] ) ) ) { + // point is contained in the box + return false; + } + + axis2[0] = v - center; + axis2[0].Normalize(); + axis2[1] = axis[ Min3Index( axis2[0] * axis[0], axis2[0] * axis[1], axis2[0] * axis[2] ) ]; + axis2[1] = axis2[1] - ( axis2[1] * axis2[0] ) * axis2[0]; + axis2[1].Normalize(); + axis2[2].Cross( axis2[0], axis2[1] ); + + AxisProjection( axis2, bounds2 ); + bounds2.AddPoint( idVec3( v * axis2[0], v * axis2[1], v * axis2[2] ) ); + + // create new box based on the smallest bounds + if ( bounds1.GetVolume() < bounds2.GetVolume() ) { + center = ( bounds1[0] + bounds1[1] ) * 0.5f; + extents = bounds1[1] - center; + center *= axis; + } + else { + center = ( bounds2[0] + bounds2[1] ) * 0.5f; + extents = bounds2[1] - center; + center *= axis2; + axis = axis2; + } + return true; +} + +/* +============ +idBox::AddBox +============ +*/ +bool idBox::AddBox( const idBox &a ) { + int i, besti; + float v, bestv; + idVec3 dir; + idMat3 ax[4]; + idBounds bounds[4], b; + + if ( a.extents[0] < 0.0f ) { + return false; + } + + if ( extents[0] < 0.0f ) { + center = a.center; + extents = a.extents; + axis = a.axis; + return true; + } + + // test axis of this box + ax[0] = axis; + bounds[0][0][0] = bounds[0][1][0] = center * ax[0][0]; + bounds[0][0][1] = bounds[0][1][1] = center * ax[0][1]; + bounds[0][0][2] = bounds[0][1][2] = center * ax[0][2]; + bounds[0][0] -= extents; + bounds[0][1] += extents; + a.AxisProjection( ax[0], b ); + if ( !bounds[0].AddBounds( b ) ) { + // the other box is contained in this box + return false; + } + + // test axis of other box + ax[1] = a.axis; + bounds[1][0][0] = bounds[1][1][0] = a.center * ax[1][0]; + bounds[1][0][1] = bounds[1][1][1] = a.center * ax[1][1]; + bounds[1][0][2] = bounds[1][1][2] = a.center * ax[1][2]; + bounds[1][0] -= a.extents; + bounds[1][1] += a.extents; + AxisProjection( ax[1], b ); + if ( !bounds[1].AddBounds( b ) ) { + // this box is contained in the other box + center = a.center; + extents = a.extents; + axis = a.axis; + return true; + } + + // test axes aligned with the vector between the box centers and one of the box axis + dir = a.center - center; + dir.Normalize(); + for ( i = 2; i < 4; i++ ) { + ax[i][0] = dir; + ax[i][1] = ax[i-2][ Min3Index( dir * ax[i-2][0], dir * ax[i-2][1], dir * ax[i-2][2] ) ]; + ax[i][1] = ax[i][1] - ( ax[i][1] * dir ) * dir; + ax[i][1].Normalize(); + ax[i][2].Cross( dir, ax[i][1] ); + + AxisProjection( ax[i], bounds[i] ); + a.AxisProjection( ax[i], b ); + bounds[i].AddBounds( b ); + } + + // get the bounds with the smallest volume + bestv = idMath::INFINITY; + besti = 0; + for ( i = 0; i < 4; i++ ) { + v = bounds[i].GetVolume(); + if ( v < bestv ) { + bestv = v; + besti = i; + } + } + + // create a box from the smallest bounds axis pair + center = ( bounds[besti][0] + bounds[besti][1] ) * 0.5f; + extents = bounds[besti][1] - center; + center *= ax[besti]; + axis = ax[besti]; + + return false; +} + +/* +================ +idBox::PlaneDistance +================ +*/ +float idBox::PlaneDistance( const idPlane &plane ) const { + float d1, d2; + + d1 = plane.Distance( center ); + d2 = idMath::Fabs( extents[0] * plane.Normal()[0] ) + + idMath::Fabs( extents[1] * plane.Normal()[1] ) + + idMath::Fabs( extents[2] * plane.Normal()[2] ); + + if ( d1 - d2 > 0.0f ) { + return d1 - d2; + } + if ( d1 + d2 < 0.0f ) { + return d1 + d2; + } + return 0.0f; +} + +/* +================ +idBox::PlaneSide +================ +*/ +int idBox::PlaneSide( const idPlane &plane, const float epsilon ) const { + float d1, d2; + + d1 = plane.Distance( center ); + d2 = idMath::Fabs( extents[0] * plane.Normal()[0] ) + + idMath::Fabs( extents[1] * plane.Normal()[1] ) + + idMath::Fabs( extents[2] * plane.Normal()[2] ); + + if ( d1 - d2 > epsilon ) { + return PLANESIDE_FRONT; + } + if ( d1 + d2 < -epsilon ) { + return PLANESIDE_BACK; + } + return PLANESIDE_CROSS; +} + +/* +============ +idBox::IntersectsBox +============ +*/ +bool idBox::IntersectsBox( const idBox &a ) const { + idVec3 dir; // vector between centers + float c[3][3]; // matrix c = axis.Transpose() * a.axis + float ac[3][3]; // absolute values of c + float axisdir[3]; // axis[i] * dir + float d, e0, e1; // distance between centers and projected extents + + dir = a.center - center; + + // axis C0 + t * A0 + c[0][0] = axis[0] * a.axis[0]; + c[0][1] = axis[0] * a.axis[1]; + c[0][2] = axis[0] * a.axis[2]; + axisdir[0] = axis[0] * dir; + ac[0][0] = idMath::Fabs( c[0][0] ); + ac[0][1] = idMath::Fabs( c[0][1] ); + ac[0][2] = idMath::Fabs( c[0][2] ); + + d = idMath::Fabs( axisdir[0] ); + e0 = extents[0]; + e1 = a.extents[0] * ac[0][0] + a.extents[1] * ac[0][1] + a.extents[2] * ac[0][2]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A1 + c[1][0] = axis[1] * a.axis[0]; + c[1][1] = axis[1] * a.axis[1]; + c[1][2] = axis[1] * a.axis[2]; + axisdir[1] = axis[1] * dir; + ac[1][0] = idMath::Fabs( c[1][0] ); + ac[1][1] = idMath::Fabs( c[1][1] ); + ac[1][2] = idMath::Fabs( c[1][2] ); + + d = idMath::Fabs( axisdir[1] ); + e0 = extents[1]; + e1 = a.extents[0] * ac[1][0] + a.extents[1] * ac[1][1] + a.extents[2] * ac[1][2]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A2 + c[2][0] = axis[2] * a.axis[0]; + c[2][1] = axis[2] * a.axis[1]; + c[2][2] = axis[2] * a.axis[2]; + axisdir[2] = axis[2] * dir; + ac[2][0] = idMath::Fabs( c[2][0] ); + ac[2][1] = idMath::Fabs( c[2][1] ); + ac[2][2] = idMath::Fabs( c[2][2] ); + + d = idMath::Fabs( axisdir[2] ); + e0 = extents[2]; + e1 = a.extents[0] * ac[2][0] + a.extents[1] * ac[2][1] + a.extents[2] * ac[2][2]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * B0 + d = idMath::Fabs( a.axis[0] * dir ); + e0 = extents[0] * ac[0][0] + extents[1] * ac[1][0] + extents[2] * ac[2][0]; + e1 = a.extents[0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * B1 + d = idMath::Fabs( a.axis[1] * dir ); + e0 = extents[0] * ac[0][1] + extents[1] * ac[1][1] + extents[2] * ac[2][1]; + e1 = a.extents[1]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * B2 + d = idMath::Fabs( a.axis[2] * dir ); + e0 = extents[0] * ac[0][2] + extents[1] * ac[1][2] + extents[2] * ac[2][2]; + e1 = a.extents[2]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A0xB0 + d = idMath::Fabs( axisdir[2] * c[1][0] - axisdir[1] * c[2][0] ); + e0 = extents[1] * ac[2][0] + extents[2] * ac[1][0]; + e1 = a.extents[1] * ac[0][2] + a.extents[2] * ac[0][1]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A0xB1 + d = idMath::Fabs( axisdir[2] * c[1][1] - axisdir[1] * c[2][1] ); + e0 = extents[1] * ac[2][1] + extents[2] * ac[1][1]; + e1 = a.extents[0] * ac[0][2] + a.extents[2] * ac[0][0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A0xB2 + d = idMath::Fabs( axisdir[2] * c[1][2] - axisdir[1] * c[2][2] ); + e0 = extents[1] * ac[2][2] + extents[2] * ac[1][2]; + e1 = a.extents[0] * ac[0][1] + a.extents[1] * ac[0][0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A1xB0 + d = idMath::Fabs( axisdir[0] * c[2][0] - axisdir[2] * c[0][0] ); + e0 = extents[0] * ac[2][0] + extents[2] * ac[0][0]; + e1 = a.extents[1] * ac[1][2] + a.extents[2] * ac[1][1]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A1xB1 + d = idMath::Fabs( axisdir[0] * c[2][1] - axisdir[2] * c[0][1] ); + e0 = extents[0] * ac[2][1] + extents[2] * ac[0][1]; + e1 = a.extents[0] * ac[1][2] + a.extents[2] * ac[1][0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A1xB2 + d = idMath::Fabs( axisdir[0] * c[2][2] - axisdir[2] * c[0][2] ); + e0 = extents[0] * ac[2][2] + extents[2] * ac[0][2]; + e1 = a.extents[0] * ac[1][1] + a.extents[1] * ac[1][0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A2xB0 + d = idMath::Fabs( axisdir[1] * c[0][0] - axisdir[0] * c[1][0] ); + e0 = extents[0] * ac[1][0] + extents[1] * ac[0][0]; + e1 = a.extents[1] * ac[2][2] + a.extents[2] * ac[2][1]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A2xB1 + d = idMath::Fabs( axisdir[1] * c[0][1] - axisdir[0] * c[1][1] ); + e0 = extents[0] * ac[1][1] + extents[1] * ac[0][1]; + e1 = a.extents[0] * ac[2][2] + a.extents[2] * ac[2][0]; + if ( d > e0 + e1 ) { + return false; + } + + // axis C0 + t * A2xB2 + d = idMath::Fabs( axisdir[1] * c[0][2] - axisdir[0] * c[1][2] ); + e0 = extents[0] * ac[1][2] + extents[1] * ac[0][2]; + e1 = a.extents[0] * ac[2][1] + a.extents[1] * ac[2][0]; + if ( d > e0 + e1 ) { + return false; + } + return true; +} + +/* +============ +idBox::LineIntersection + + Returns true if the line intersects the box between the start and end point. +============ +*/ +bool idBox::LineIntersection( const idVec3 &start, const idVec3 &end ) const { + float ld[3]; + idVec3 lineDir = 0.5f * ( end - start ); + idVec3 lineCenter = start + lineDir; + idVec3 dir = lineCenter - center; + + ld[0] = idMath::Fabs( lineDir * axis[0] ); + if ( idMath::Fabs( dir * axis[0] ) > extents[0] + ld[0] ) { + return false; + } + + ld[1] = idMath::Fabs( lineDir * axis[1] ); + if ( idMath::Fabs( dir * axis[1] ) > extents[1] + ld[1] ) { + return false; + } + + ld[2] = idMath::Fabs( lineDir * axis[2] ); + if ( idMath::Fabs( dir * axis[2] ) > extents[2] + ld[2] ) { + return false; + } + + idVec3 cross = lineDir.Cross( dir ); + + if ( idMath::Fabs( cross * axis[0] ) > extents[1] * ld[2] + extents[2] * ld[1] ) { + return false; + } + + if ( idMath::Fabs( cross * axis[1] ) > extents[0] * ld[2] + extents[2] * ld[0] ) { + return false; + } + + if ( idMath::Fabs( cross * axis[2] ) > extents[0] * ld[1] + extents[1] * ld[0] ) { + return false; + } + + return true; +} + +/* +============ +BoxPlaneClip +============ +*/ +static bool BoxPlaneClip( const float denom, const float numer, float &scale0, float &scale1 ) { + if ( denom > 0.0f ) { + if ( numer > denom * scale1 ) { + return false; + } + if ( numer > denom * scale0 ) { + scale0 = numer / denom; + } + return true; + } + else if ( denom < 0.0f ) { + if ( numer > denom * scale0 ) { + return false; + } + if ( numer > denom * scale1 ) { + scale1 = numer / denom; + } + return true; + } + else { + return ( numer <= 0.0f ); + } +} + +/* +============ +idBox::RayIntersection + + Returns true if the ray intersects the box. + The ray can intersect the box in both directions from the start point. + If start is inside the box then scale1 < 0 and scale2 > 0. +============ +*/ +bool idBox::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { + idVec3 localStart, localDir; + + localStart = ( start - center ) * axis.Transpose(); + localDir = dir * axis.Transpose(); + + scale1 = -idMath::INFINITY; + scale2 = idMath::INFINITY; + return BoxPlaneClip( localDir.x, -localStart.x - extents[0], scale1, scale2 ) && + BoxPlaneClip( -localDir.x, localStart.x - extents[0], scale1, scale2 ) && + BoxPlaneClip( localDir.y, -localStart.y - extents[1], scale1, scale2 ) && + BoxPlaneClip( -localDir.y, localStart.y - extents[1], scale1, scale2 ) && + BoxPlaneClip( localDir.z, -localStart.z - extents[2], scale1, scale2 ) && + BoxPlaneClip( -localDir.z, localStart.z - extents[2], scale1, scale2 ); +} + +/* +============ +idBox::FromPoints + + Tight box for a collection of points. +============ +*/ +void idBox::FromPoints( const idVec3 *points, const int numPoints ) { + int i; + float invNumPoints, sumXX, sumXY, sumXZ, sumYY, sumYZ, sumZZ; + idVec3 dir; + idBounds bounds; + idMatX eigenVectors; + idVecX eigenValues; + + // compute mean of points + center = points[0]; + for ( i = 1; i < numPoints; i++ ) { + center += points[i]; + } + invNumPoints = 1.0f / numPoints; + center *= invNumPoints; + + // compute covariances of points + sumXX = 0.0f; sumXY = 0.0f; sumXZ = 0.0f; + sumYY = 0.0f; sumYZ = 0.0f; sumZZ = 0.0f; + for ( i = 0; i < numPoints; i++ ) { + dir = points[i] - center; + sumXX += dir.x * dir.x; + sumXY += dir.x * dir.y; + sumXZ += dir.x * dir.z; + sumYY += dir.y * dir.y; + sumYZ += dir.y * dir.z; + sumZZ += dir.z * dir.z; + } + sumXX *= invNumPoints; + sumXY *= invNumPoints; + sumXZ *= invNumPoints; + sumYY *= invNumPoints; + sumYZ *= invNumPoints; + sumZZ *= invNumPoints; + + // compute eigenvectors for covariance matrix + eigenValues.SetData( 3, VECX_ALLOCA( 3 ) ); + eigenVectors.SetData( 3, 3, MATX_ALLOCA( 3 * 3 ) ); + + eigenVectors[0][0] = sumXX; + eigenVectors[0][1] = sumXY; + eigenVectors[0][2] = sumXZ; + eigenVectors[1][0] = sumXY; + eigenVectors[1][1] = sumYY; + eigenVectors[1][2] = sumYZ; + eigenVectors[2][0] = sumXZ; + eigenVectors[2][1] = sumYZ; + eigenVectors[2][2] = sumZZ; + eigenVectors.Eigen_SolveSymmetric( eigenValues ); + eigenVectors.Eigen_SortIncreasing( eigenValues ); + + axis[0][0] = eigenVectors[0][0]; + axis[0][1] = eigenVectors[0][1]; + axis[0][2] = eigenVectors[0][2]; + axis[1][0] = eigenVectors[1][0]; + axis[1][1] = eigenVectors[1][1]; + axis[1][2] = eigenVectors[1][2]; + axis[2][0] = eigenVectors[2][0]; + axis[2][1] = eigenVectors[2][1]; + axis[2][2] = eigenVectors[2][2]; + + extents[0] = eigenValues[0]; + extents[1] = eigenValues[0]; + extents[2] = eigenValues[0]; + + // refine by calculating the bounds of the points projected onto the axis and adjusting the center and extents + bounds.Clear(); + for ( i = 0; i < numPoints; i++ ) { + bounds.AddPoint( idVec3( points[i] * axis[0], points[i] * axis[1], points[i] * axis[2] ) ); + } + center = ( bounds[0] + bounds[1] ) * 0.5f; + extents = bounds[1] - center; + center *= axis; +} + +/* +============ +idBox::FromPointTranslation + + Most tight box for the translational movement of the given point. +============ +*/ +void idBox::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { + // FIXME: implement +} + +/* +============ +idBox::FromBoxTranslation + + Most tight box for the translational movement of the given box. +============ +*/ +void idBox::FromBoxTranslation( const idBox &box, const idVec3 &translation ) { + // FIXME: implement +} + +/* +============ +idBox::FromPointRotation + + Most tight bounds for the rotational movement of the given point. +============ +*/ +void idBox::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { + // FIXME: implement +} + +/* +============ +idBox::FromBoxRotation + + Most tight box for the rotational movement of the given box. +============ +*/ +void idBox::FromBoxRotation( const idBox &box, const idRotation &rotation ) { + // FIXME: implement +} + +/* +============ +idBox::ToPoints +============ +*/ +void idBox::ToPoints( idVec3 points[8] ) const { + idMat3 ax; + idVec3 temp[4]; + + ax[0] = extents[0] * axis[0]; + ax[1] = extents[1] * axis[1]; + ax[2] = extents[2] * axis[2]; + temp[0] = center - ax[0]; + temp[1] = center + ax[0]; + temp[2] = ax[1] - ax[2]; + temp[3] = ax[1] + ax[2]; + points[0] = temp[0] - temp[3]; + points[1] = temp[1] - temp[3]; + points[2] = temp[1] + temp[2]; + points[3] = temp[0] + temp[2]; + points[4] = temp[0] - temp[2]; + points[5] = temp[1] - temp[2]; + points[6] = temp[1] + temp[3]; + points[7] = temp[0] + temp[3]; +} + +/* +============ +idBox::GetProjectionSilhouetteVerts +============ +*/ +int idBox::GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const { + float f; + int i, planeBits, *index; + idVec3 points[8], dir1, dir2; + + ToPoints( points ); + + dir1 = points[0] - projectionOrigin; + dir2 = points[6] - projectionOrigin; + f = dir1 * axis[0]; + planeBits = FLOATSIGNBITNOTSET( f ); + f = dir2 * axis[0]; + planeBits |= FLOATSIGNBITSET( f ) << 1; + f = dir1 * axis[1]; + planeBits |= FLOATSIGNBITNOTSET( f ) << 2; + f = dir2 * axis[1]; + planeBits |= FLOATSIGNBITSET( f ) << 3; + f = dir1 * axis[2]; + planeBits |= FLOATSIGNBITNOTSET( f ) << 4; + f = dir2 * axis[2]; + planeBits |= FLOATSIGNBITSET( f ) << 5; + + index = boxPlaneBitsSilVerts[planeBits]; + for ( i = 0; i < index[0]; i++ ) { + silVerts[i] = points[index[i+1]]; + } + + return index[0]; +} + +/* +============ +idBox::GetParallelProjectionSilhouetteVerts +============ +*/ +int idBox::GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const { + float f; + int i, planeBits, *index; + idVec3 points[8]; + + ToPoints( points ); + + planeBits = 0; + f = projectionDir * axis[0]; + if ( FLOATNOTZERO( f ) ) { + planeBits = 1 << FLOATSIGNBITSET( f ); + } + f = projectionDir * axis[1]; + if ( FLOATNOTZERO( f ) ) { + planeBits |= 4 << FLOATSIGNBITSET( f ); + } + f = projectionDir * axis[2]; + if ( FLOATNOTZERO( f ) ) { + planeBits |= 16 << FLOATSIGNBITSET( f ); + } + + index = boxPlaneBitsSilVerts[planeBits]; + for ( i = 0; i < index[0]; i++ ) { + silVerts[i] = points[index[i+1]]; + } + + return index[0]; +} + +/* +============ +idBox::ToString +============ +*/ +const char * idBox::ToString( const int precision ) const { + idVec3 min = center - extents; + idVec3 max = center + extents; + return idStr( min.ToString( precision ) ) + " -> " + idStr( max.ToString( precision ) ) + " (" + idStr( axis.ToString() ) + ")"; +} + + diff --git a/idlib/bv/Box.h b/idlib/bv/Box.h new file mode 100644 index 000000000..fbd8655a4 --- /dev/null +++ b/idlib/bv/Box.h @@ -0,0 +1,314 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BV_BOX_H__ +#define __BV_BOX_H__ + +/* +=============================================================================== + + Oriented Bounding Box + +=============================================================================== +*/ + +class idBox { +public: + idBox( void ); + explicit idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ); + explicit idBox( const idVec3 &point ); + explicit idBox( const idBounds &bounds ); + explicit idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ); + + idBox operator+( const idVec3 &t ) const; // returns translated box + idBox & operator+=( const idVec3 &t ); // translate the box + idBox operator*( const idMat3 &r ) const; // returns rotated box + idBox & operator*=( const idMat3 &r ); // rotate the box + idBox operator+( const idBox &a ) const; + idBox & operator+=( const idBox &a ); + idBox operator-( const idBox &a ) const; + idBox & operator-=( const idBox &a ); + + bool Compare( const idBox &a ) const; // exact compare, no epsilon + bool Compare( const idBox &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idBox &a ) const; // exact compare, no epsilon + bool operator!=( const idBox &a ) const; // exact compare, no epsilon + + void Clear( void ); // inside out box + void Zero( void ); // single point at origin + + const idVec3 & GetCenter( void ) const; // returns center of the box + const idVec3 & GetExtents( void ) const; // returns extents of the box + const idMat3 & GetAxis( void ) const; // returns the axis of the box + float GetVolume( void ) const; // returns the volume of the box + bool IsCleared( void ) const; // returns true if box are inside out + + bool AddPoint( const idVec3 &v ); // add the point, returns true if the box expanded + bool AddBox( const idBox &a ); // add the box, returns true if the box expanded + idBox Expand( const float d ) const; // return box expanded in all directions with the given value + idBox & ExpandSelf( const float d ); // expand box in all directions with the given value + idBox Translate( const idVec3 &translation ) const; // return translated box + idBox & TranslateSelf( const idVec3 &translation ); // translate this box + idBox Rotate( const idMat3 &rotation ) const; // return rotated box + idBox & RotateSelf( const idMat3 &rotation ); // rotate this box around the origin + idBox & RotateSelfAroundCenter( const idMat3 &rotation ); // rotate this box around the center of the box + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + bool ContainsPoint( const idVec3 &p ) const; // includes touching + bool IntersectsBox( const idBox &a ) const; // includes touching + bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; + // intersection points are (start + dir * scale1) and (start + dir * scale2) + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; + + // tight box for a collection of points + void FromPoints( const idVec3 *points, const int numPoints ); + // most tight box for a translation + void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); + void FromBoxTranslation( const idBox &box, const idVec3 &translation ); + // most tight box for a rotation + void FromPointRotation( const idVec3 &point, const idRotation &rotation ); + void FromBoxRotation( const idBox &box, const idRotation &rotation ); + + void ToPoints( idVec3 points[8] ) const; + idSphere ToSphere( void ) const; + + // calculates the projection of this box onto the given axis + void AxisProjection( const idVec3 &dir, float &min, float &max ) const; + void AxisProjection( const idMat3 &ax, idBounds &bounds ) const; + + // calculates the silhouette of the box + int GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const; + int GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const; + + // angua: fills in the 8 corner vertices of the box + // verts must be an array of 8 idVec3s. + void GetVerts(idVec3* verts) const; + + // Tels: added + const char * ToString( const int precision = 2 ) const; + + +private: + idVec3 center; + idVec3 extents; + idMat3 axis; +}; + +extern idBox box_zero; + +ID_INLINE idBox::idBox( void ) { +} + +ID_INLINE idBox::idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ) { + this->center = center; + this->extents = extents; + this->axis = axis; +} + +ID_INLINE idBox::idBox( const idVec3 &point ) { + this->center = point; + this->extents.Zero(); + this->axis.Identity(); +} + +ID_INLINE idBox::idBox( const idBounds &bounds ) { + this->center = ( bounds[0] + bounds[1] ) * 0.5f; + this->extents = bounds[1] - this->center; + this->axis.Identity(); +} + +ID_INLINE idBox::idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) { + this->center = ( bounds[0] + bounds[1] ) * 0.5f; + this->extents = bounds[1] - this->center; + this->center = origin + this->center * axis; + this->axis = axis; +} + +ID_INLINE idBox idBox::operator+( const idVec3 &t ) const { + return idBox( center + t, extents, axis ); +} + +ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) { + center += t; + return *this; +} + +ID_INLINE idBox idBox::operator*( const idMat3 &r ) const { + return idBox( center * r, extents, axis * r ); +} + +ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) { + center *= r; + axis *= r; + return *this; +} + +ID_INLINE idBox idBox::operator+( const idBox &a ) const { + idBox newBox; + newBox = *this; + newBox.AddBox( a ); + return newBox; +} + +ID_INLINE idBox &idBox::operator+=( const idBox &a ) { + idBox::AddBox( a ); + return *this; +} + +ID_INLINE idBox idBox::operator-( const idBox &a ) const { + return idBox( center, extents - a.extents, axis ); +} + +ID_INLINE idBox &idBox::operator-=( const idBox &a ) { + extents -= a.extents; + return *this; +} + +ID_INLINE bool idBox::Compare( const idBox &a ) const { + return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) ); +} + +ID_INLINE bool idBox::Compare( const idBox &a, const float epsilon ) const { + return ( center.Compare( a.center, epsilon ) && extents.Compare( a.extents, epsilon ) && axis.Compare( a.axis, epsilon ) ); +} + +ID_INLINE bool idBox::operator==( const idBox &a ) const { + return Compare( a ); +} + +ID_INLINE bool idBox::operator!=( const idBox &a ) const { + return !Compare( a ); +} + +ID_INLINE void idBox::Clear( void ) { + center.Zero(); + extents[0] = extents[1] = extents[2] = -idMath::INFINITY; + axis.Identity(); +} + +ID_INLINE void idBox::Zero( void ) { + center.Zero(); + extents.Zero(); + axis.Identity(); +} + +ID_INLINE const idVec3 &idBox::GetCenter( void ) const { + return center; +} + +ID_INLINE const idVec3 &idBox::GetExtents( void ) const { + return extents; +} + +ID_INLINE const idMat3 &idBox::GetAxis( void ) const { + return axis; +} + +ID_INLINE float idBox::GetVolume( void ) const { + return ( extents * 2.0f ).LengthSqr(); +} + +ID_INLINE bool idBox::IsCleared( void ) const { + return extents[0] < 0.0f; +} + +ID_INLINE idBox idBox::Expand( const float d ) const { + return idBox( center, extents + idVec3( d, d, d ), axis ); +} + +ID_INLINE idBox &idBox::ExpandSelf( const float d ) { + extents[0] += d; + extents[1] += d; + extents[2] += d; + return *this; +} + +ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const { + return idBox( center + translation, extents, axis ); +} + +ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) { + center += translation; + return *this; +} + +ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const { + return idBox( center * rotation, extents, axis * rotation ); +} + +ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) { + center *= rotation; + axis *= rotation; + return *this; +} + +ID_INLINE idBox &idBox::RotateSelfAroundCenter( const idMat3 &rotation ) { + axis *= rotation; + return *this; +} + +ID_INLINE bool idBox::ContainsPoint( const idVec3 &p ) const { + idVec3 lp = p - center; + if ( idMath::Fabs( lp * axis[0] ) > extents[0] || + idMath::Fabs( lp * axis[1] ) > extents[1] || + idMath::Fabs( lp * axis[2] ) > extents[2] ) { + return false; + } + return true; +} + +ID_INLINE idSphere idBox::ToSphere( void ) const { + return idSphere( center, extents.Length() ); +} + +ID_INLINE void idBox::AxisProjection( const idVec3 &dir, float &min, float &max ) const { + float d1 = dir * center; + float d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) + + idMath::Fabs( extents[1] * ( dir * axis[1] ) ) + + idMath::Fabs( extents[2] * ( dir * axis[2] ) ); + min = d1 - d2; + max = d1 + d2; +} + +ID_INLINE void idBox::AxisProjection( const idMat3 &ax, idBounds &bounds ) const { + for ( int i = 0; i < 3; i++ ) { + float d1 = ax[i] * center; + float d2 = idMath::Fabs( extents[0] * ( ax[i] * axis[0] ) ) + + idMath::Fabs( extents[1] * ( ax[i] * axis[1] ) ) + + idMath::Fabs( extents[2] * ( ax[i] * axis[2] ) ); + bounds[0][i] = d1 - d2; + bounds[1][i] = d1 + d2; + } +} + +ID_INLINE void idBox::GetVerts(idVec3* verts) const +{ + verts[0] = center + idVec3(extents.x, -extents.y, -extents.z) * axis; + verts[1] = center + idVec3(extents.x, extents.y, -extents.z) * axis; + verts[2] = center + idVec3(-extents.x, extents.y, -extents.z) * axis; + verts[3] = center + idVec3(-extents.x, -extents.y, -extents.z) * axis; + verts[4] = center + idVec3(extents.x, -extents.y, extents.z) * axis; + verts[5] = center + idVec3(extents.x, extents.y, extents.z) * axis; + verts[6] = center + idVec3(-extents.x, extents.y, extents.z) * axis; + verts[7] = center + idVec3(-extents.x, -extents.y, extents.z) * axis; +} + +#endif /* !__BV_BOX_H__ */ diff --git a/idlib/bv/Frustum.cpp b/idlib/bv/Frustum.cpp new file mode 100644 index 000000000..12cc061c0 --- /dev/null +++ b/idlib/bv/Frustum.cpp @@ -0,0 +1,2836 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +//#define FRUSTUM_DEBUG + +/* + bit 0 = min x + bit 1 = max x + bit 2 = min y + bit 3 = max y + bit 4 = min z + bit 5 = max z +*/ +static int boxVertPlanes[8] = { + ( (1<<0) | (1<<2) | (1<<4) ), + ( (1<<1) | (1<<2) | (1<<4) ), + ( (1<<1) | (1<<3) | (1<<4) ), + ( (1<<0) | (1<<3) | (1<<4) ), + ( (1<<0) | (1<<2) | (1<<5) ), + ( (1<<1) | (1<<2) | (1<<5) ), + ( (1<<1) | (1<<3) | (1<<5) ), + ( (1<<0) | (1<<3) | (1<<5) ), +}; + +/* +============ +BoxToPoints +============ +*/ +void BoxToPoints( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis, idVec3 points[8] ) { + idMat3 ax; + idVec3 temp[4]; + + ax[0] = extents[0] * axis[0]; + ax[1] = extents[1] * axis[1]; + ax[2] = extents[2] * axis[2]; + temp[0] = center - ax[0]; + temp[1] = center + ax[0]; + temp[2] = ax[1] - ax[2]; + temp[3] = ax[1] + ax[2]; + points[0] = temp[0] - temp[3]; + points[1] = temp[1] - temp[3]; + points[2] = temp[1] + temp[2]; + points[3] = temp[0] + temp[2]; + points[4] = temp[0] - temp[2]; + points[5] = temp[1] - temp[2]; + points[6] = temp[1] + temp[3]; + points[7] = temp[0] + temp[3]; +} + +/* +================ +idFrustum::PlaneDistance +================ +*/ +float idFrustum::PlaneDistance( const idPlane &plane ) const { + float min, max; + + AxisProjection( plane.Normal(), min, max ); + if ( min + plane[3] > 0.0f ) { + return min + plane[3]; + } + if ( max + plane[3] < 0.0f ) { + return max + plane[3]; + } + return 0.0f; +} + +/* +================ +idFrustum::PlaneSide +================ +*/ +int idFrustum::PlaneSide( const idPlane &plane, const float epsilon ) const { + float min, max; + + AxisProjection( plane.Normal(), min, max ); + if ( min + plane[3] > epsilon ) { + return PLANESIDE_FRONT; + } + if ( max + plane[3] < epsilon ) { + return PLANESIDE_BACK; + } + return PLANESIDE_CROSS; +} + +/* +============ +idFrustum::CullPoint +============ +*/ +bool idFrustum::CullPoint( const idVec3 &point ) const { + idVec3 p; + float scale; + + // transform point to frustum space + p = ( point - origin ) * axis.Transpose(); + // test whether or not the point is within the frustum + if ( p.x < dNear || p.x > dFar ) { + return true; + } + scale = p.x * invFar; + if ( idMath::Fabs( p.y ) > dLeft * scale ) { + return true; + } + if ( idMath::Fabs( p.z ) > dUp * scale ) { + return true; + } + return false; +} + +/* +============ +idFrustum::CullLocalBox + + Tests if any of the planes of the frustum can be used as a separating plane. + + 3 muls best case + 25 muls worst case +============ +*/ +bool idFrustum::CullLocalBox( const idVec3 &localOrigin, const idVec3 &extents, const idMat3 &localAxis ) const { + float d1, d2; + idVec3 testOrigin; + idMat3 testAxis; + + // near plane + d1 = dNear - localOrigin.x; + d2 = idMath::Fabs( extents[0] * localAxis[0][0] ) + + idMath::Fabs( extents[1] * localAxis[1][0] ) + + idMath::Fabs( extents[2] * localAxis[2][0] ); + if ( d1 - d2 > 0.0f ) { + return true; + } + + // far plane + d1 = localOrigin.x - dFar; + if ( d1 - d2 > 0.0f ) { + return true; + } + + testOrigin = localOrigin; + testAxis = localAxis; + + if ( testOrigin.y < 0.0f ) { + testOrigin.y = -testOrigin.y; + testAxis[0][1] = -testAxis[0][1]; + testAxis[1][1] = -testAxis[1][1]; + testAxis[2][1] = -testAxis[2][1]; + } + + // test left/right planes + d1 = dFar * testOrigin.y - dLeft * testOrigin.x; + d2 = idMath::Fabs( extents[0] * ( dFar * testAxis[0][1] - dLeft * testAxis[0][0] ) ) + + idMath::Fabs( extents[1] * ( dFar * testAxis[1][1] - dLeft * testAxis[1][0] ) ) + + idMath::Fabs( extents[2] * ( dFar * testAxis[2][1] - dLeft * testAxis[2][0] ) ); + if ( d1 - d2 > 0.0f ) { + return true; + } + + if ( testOrigin.z < 0.0f ) { + testOrigin.z = -testOrigin.z; + testAxis[0][2] = -testAxis[0][2]; + testAxis[1][2] = -testAxis[1][2]; + testAxis[2][2] = -testAxis[2][2]; + } + + // test up/down planes + d1 = dFar * testOrigin.z - dUp * testOrigin.x; + d2 = idMath::Fabs( extents[0] * ( dFar * testAxis[0][2] - dUp * testAxis[0][0] ) ) + + idMath::Fabs( extents[1] * ( dFar * testAxis[1][2] - dUp * testAxis[1][0] ) ) + + idMath::Fabs( extents[2] * ( dFar * testAxis[2][2] - dUp * testAxis[2][0] ) ); + if ( d1 - d2 > 0.0f ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::CullBounds + + Tests if any of the planes of the frustum can be used as a separating plane. + + 24 muls best case + 37 muls worst case +============ +*/ +bool idFrustum::CullBounds( const idBounds &bounds ) const { + idVec3 localOrigin, center, extents; + idMat3 localAxis; + + center = ( bounds[0] + bounds[1] ) * 0.5f; + extents = bounds[1] - center; + + // transform the bounds into the space of this frustum + localOrigin = ( center - origin ) * axis.Transpose(); + localAxis = axis.Transpose(); + + return CullLocalBox( localOrigin, extents, localAxis ); +} + +/* +============ +idFrustum::CullBounds + + Tests if any of the planes of the frustum can be used as a separating plane. + + 39 muls best case + 61 muls worst case +============ +*/ +bool idFrustum::CullBox( const idBox &box ) const { + idVec3 localOrigin; + idMat3 localAxis; + + // transform the box into the space of this frustum + localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); + localAxis = box.GetAxis() * axis.Transpose(); + + return CullLocalBox( localOrigin, box.GetExtents(), localAxis ); +} + +/* +============ +idFrustum::CullSphere + + Tests if any of the planes of the frustum can be used as a separating plane. + + 9 muls best case + 21 muls worst case +============ +*/ +bool idFrustum::CullSphere( const idSphere &sphere ) const { + float d, r, rs, sFar; + idVec3 center; + + center = ( sphere.GetOrigin() - origin ) * axis.Transpose(); + r = sphere.GetRadius(); + + // test near plane + if ( dNear - center.x > r ) { + return true; + } + + // test far plane + if ( center.x - dFar > r ) { + return true; + } + + rs = r * r; + sFar = dFar * dFar; + + // test left/right planes + d = dFar * idMath::Fabs( center.y ) - dLeft * center.x; + if ( ( d * d ) > rs * ( sFar + dLeft * dLeft ) ) { + return true; + } + + // test up/down planes + d = dFar * idMath::Fabs( center.z ) - dUp * center.x; + if ( ( d * d ) > rs * ( sFar + dUp * dUp ) ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::CullLocalFrustum + + Tests if any of the planes of this frustum can be used as a separating plane. + + 0 muls best case + 30 muls worst case +============ +*/ +bool idFrustum::CullLocalFrustum( const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const { + int index; + float dx, dy, dz, leftScale, upScale; + + // test near plane + dy = -localFrustum.axis[1].x; + dz = -localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].x < dNear ) { + return true; + } + + // test far plane + dy = localFrustum.axis[1].x; + dz = localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].x > dFar ) { + return true; + } + + leftScale = dLeft * invFar; + + // test left plane + dy = dFar * localFrustum.axis[1].y - dLeft * localFrustum.axis[1].x; + dz = dFar * localFrustum.axis[2].y - dLeft * localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = dFar * cornerVecs[index].y - dLeft * cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].y > indexPoints[index].x * leftScale ) { + return true; + } + + // test right plane + dy = -dFar * localFrustum.axis[1].y - dLeft * localFrustum.axis[1].x; + dz = -dFar * localFrustum.axis[2].y - dLeft * localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -dFar * cornerVecs[index].y - dLeft * cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].y < -indexPoints[index].x * leftScale ) { + return true; + } + + upScale = dUp * invFar; + + // test up plane + dy = dFar * localFrustum.axis[1].z - dUp * localFrustum.axis[1].x; + dz = dFar * localFrustum.axis[2].z - dUp * localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = dFar * cornerVecs[index].z - dUp * cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].z > indexPoints[index].x * upScale ) { + return true; + } + + // test down plane + dy = -dFar * localFrustum.axis[1].z - dUp * localFrustum.axis[1].x; + dz = -dFar * localFrustum.axis[2].z - dUp * localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -dFar * cornerVecs[index].z - dUp * cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].z < -indexPoints[index].x * upScale ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::CullFrustum + + Tests if any of the planes of this frustum can be used as a separating plane. + + 58 muls best case + 88 muls worst case +============ +*/ +bool idFrustum::CullFrustum( const idFrustum &frustum ) const { + idFrustum localFrustum; + idVec3 indexPoints[8], cornerVecs[4]; + + // transform the given frustum into the space of this frustum + localFrustum = frustum; + localFrustum.origin = ( frustum.origin - origin ) * axis.Transpose(); + localFrustum.axis = frustum.axis * axis.Transpose(); + + localFrustum.ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + + return CullLocalFrustum( localFrustum, indexPoints, cornerVecs ); +} + +/* +============ +idFrustum::CullLocalWinding +============ +*/ +bool idFrustum::CullLocalWinding( const idVec3 *points, const int numPoints, int *pointCull ) const { + int i, pCull, culled; + float leftScale, upScale; + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + + culled = -1; + for ( i = 0; i < numPoints; i++ ) { + const idVec3 &p = points[i]; + pCull = 0; + if ( p.x < dNear ) { + pCull = 1; + } + else if ( p.x > dFar ) { + pCull = 2; + } + if ( idMath::Fabs( p.y ) > p.x * leftScale ) { + pCull |= 4 << FLOATSIGNBITSET( p.y ); + } + if ( idMath::Fabs( p.z ) > p.x * upScale ) { + pCull |= 16 << FLOATSIGNBITSET( p.z ); + } + culled &= pCull; + pointCull[i] = pCull; + } + + return ( culled != 0 ); +} + +/* +============ +idFrustum::CullWinding +============ +*/ +bool idFrustum::CullWinding( const idWinding &winding ) const { + int i, *pointCull; + idVec3 *localPoints; + idMat3 transpose; + + localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); + pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); + + transpose = axis.Transpose(); + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; + } + + return CullLocalWinding( localPoints, winding.GetNumPoints(), pointCull ); +} + +/* +============ +idFrustum::BoundsCullLocalFrustum + + Tests if any of the bounding box planes can be used as a separating plane. +============ +*/ +bool idFrustum::BoundsCullLocalFrustum( const idBounds &bounds, const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const { + int index; + float dx, dy, dz; + + dy = -localFrustum.axis[1].x; + dz = -localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].x < bounds[0].x ) { + return true; + } + + dy = localFrustum.axis[1].x; + dz = localFrustum.axis[2].x; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = cornerVecs[index].x; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].x > bounds[1].x ) { + return true; + } + + dy = -localFrustum.axis[1].y; + dz = -localFrustum.axis[2].y; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -cornerVecs[index].y; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].y < bounds[0].y ) { + return true; + } + + dy = localFrustum.axis[1].y; + dz = localFrustum.axis[2].y; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = cornerVecs[index].y; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].y > bounds[1].y ) { + return true; + } + + dy = -localFrustum.axis[1].z; + dz = -localFrustum.axis[2].z; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = -cornerVecs[index].z; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].z < bounds[0].z ) { + return true; + } + + dy = localFrustum.axis[1].z; + dz = localFrustum.axis[2].z; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = cornerVecs[index].z; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + + if ( indexPoints[index].z > bounds[1].z ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::LocalLineIntersection + + 7 divs + 30 muls +============ +*/ +bool idFrustum::LocalLineIntersection( const idVec3 &start, const idVec3 &end ) const { + idVec3 dir; + float d1, d2, fstart, fend, lstart, lend, f, x; + float leftScale, upScale; + int startInside = 1; + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + dir = end - start; + + // test near plane + if ( dNear > 0.0f ) { + d1 = dNear - start.x; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = dNear - end.x; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + if ( idMath::Fabs( start.y + f * dir.y ) <= dNear * leftScale ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= dNear * upScale ) { + return true; + } + } + } + } + } + + // test far plane + d1 = start.x - dFar; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = end.x - dFar; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + if ( idMath::Fabs( start.y + f * dir.y ) <= dFar * leftScale ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= dFar * upScale ) { + return true; + } + } + } + } + + fstart = dFar * start.y; + fend = dFar * end.y; + lstart = dLeft * start.x; + lend = dLeft * end.x; + + // test left plane + d1 = fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = fend - lend; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { + return true; + } + } + } + } + + // test right plane + d1 = -fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = -fend - lend; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { + return true; + } + } + } + } + + fstart = dFar * start.z; + fend = dFar * end.z; + lstart = dUp * start.x; + lend = dUp * end.x; + + // test up plane + d1 = fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = fend - lend; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { + return true; + } + } + } + } + + // test down plane + d1 = -fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + if ( FLOATNOTZERO( d1 ) ) { + d2 = -fend - lend; + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { + return true; + } + } + } + } + + return ( startInside != 0 ); +} + +/* +============ +idFrustum::LocalRayIntersection + + Returns true if the ray starts inside the frustum. + If there was an intersection scale1 <= scale2 +============ +*/ +bool idFrustum::LocalRayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { + idVec3 end; + float d1, d2, fstart, fend, lstart, lend, f, x; + float leftScale, upScale; + int startInside = 1; + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + end = start + dir; + + scale1 = idMath::INFINITY; + scale2 = -idMath::INFINITY; + + // test near plane + if ( dNear > 0.0f ) { + d1 = dNear - start.x; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = dNear - end.x; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + if ( idMath::Fabs( start.y + f * dir.y ) <= dNear * leftScale ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= dNear * upScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + } + + // test far plane + d1 = start.x - dFar; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = end.x - dFar; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + if ( idMath::Fabs( start.y + f * dir.y ) <= dFar * leftScale ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= dFar * upScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + fstart = dFar * start.y; + fend = dFar * end.y; + lstart = dLeft * start.x; + lend = dLeft * end.x; + + // test left plane + d1 = fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = fend - lend; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + // test right plane + d1 = -fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = -fend - lend; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + fstart = dFar * start.z; + fend = dFar * end.z; + lstart = dUp * start.x; + lend = dUp * end.x; + + // test up plane + d1 = fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = fend - lend; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + // test down plane + d1 = -fstart - lstart; + startInside &= FLOATSIGNBITSET( d1 ); + d2 = -fend - lend; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + x = start.x + f * dir.x; + if ( x >= dNear && x <= dFar ) { + if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + return ( startInside != 0 ); +} + +/* +============ +idFrustum::ContainsPoint +============ +*/ +bool idFrustum::ContainsPoint( const idVec3 &point ) const { + return !CullPoint( point ); +} + +/* +============ +idFrustum::LocalFrustumIntersectsFrustum +============ +*/ +bool idFrustum::LocalFrustumIntersectsFrustum( const idVec3 points[8], const bool testFirstSide ) const { + int i; + + // test if any edges of the other frustum intersect this frustum + for ( i = 0; i < 4; i++ ) { + if ( LocalLineIntersection( points[i], points[4+i] ) ) { + return true; + } + } + if ( testFirstSide ) { + for ( i = 0; i < 4; i++ ) { + if ( LocalLineIntersection( points[i], points[(i+1)&3] ) ) { + return true; + } + } + } + for ( i = 0; i < 4; i++ ) { + if ( LocalLineIntersection( points[4+i], points[4+((i+1)&3)] ) ) { + return true; + } + } + + return false; +} + +/* +============ +idFrustum::LocalFrustumIntersectsBounds +============ +*/ +bool idFrustum::LocalFrustumIntersectsBounds( const idVec3 points[8], const idBounds &bounds ) const { + int i; + + // test if any edges of the other frustum intersect this frustum + for ( i = 0; i < 4; i++ ) { + if ( bounds.LineIntersection( points[i], points[4+i] ) ) { + return true; + } + } + if ( dNear > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + if ( bounds.LineIntersection( points[i], points[(i+1)&3] ) ) { + return true; + } + } + } + for ( i = 0; i < 4; i++ ) { + if ( bounds.LineIntersection( points[4+i], points[4+((i+1)&3)] ) ) { + return true; + } + } + + return false; +} + +/* +============ +idFrustum::IntersectsBounds +============ +*/ +bool idFrustum::IntersectsBounds( const idBounds &bounds ) const { + idVec3 localOrigin, center, extents; + idMat3 localAxis; + + center = ( bounds[0] + bounds[1] ) * 0.5f; + extents = bounds[1] - center; + + localOrigin = ( center - origin ) * axis.Transpose(); + localAxis = axis.Transpose(); + + if ( CullLocalBox( localOrigin, extents, localAxis ) ) { + return false; + } + + idVec3 indexPoints[8], cornerVecs[4]; + + ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + + if ( BoundsCullLocalFrustum( bounds, *this, indexPoints, cornerVecs ) ) { + return false; + } + + idSwap( indexPoints[2], indexPoints[3] ); + idSwap( indexPoints[6], indexPoints[7] ); + + if ( LocalFrustumIntersectsBounds( indexPoints, bounds ) ) { + return true; + } + + BoxToPoints( localOrigin, extents, localAxis, indexPoints ); + + if ( LocalFrustumIntersectsFrustum( indexPoints, true ) ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::IntersectsBox +============ +*/ +bool idFrustum::IntersectsBox( const idBox &box ) const { + idVec3 localOrigin; + idMat3 localAxis; + + localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); + localAxis = box.GetAxis() * axis.Transpose(); + + if ( CullLocalBox( localOrigin, box.GetExtents(), localAxis ) ) { + return false; + } + + idVec3 indexPoints[8], cornerVecs[4]; + idFrustum localFrustum; + + localFrustum = *this; + localFrustum.origin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); + localFrustum.axis = axis * box.GetAxis().Transpose(); + localFrustum.ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + + if ( BoundsCullLocalFrustum( idBounds( -box.GetExtents(), box.GetExtents() ), localFrustum, indexPoints, cornerVecs ) ) { + return false; + } + + idSwap( indexPoints[2], indexPoints[3] ); + idSwap( indexPoints[6], indexPoints[7] ); + + if ( LocalFrustumIntersectsBounds( indexPoints, idBounds( -box.GetExtents(), box.GetExtents() ) ) ) { + return true; + } + + BoxToPoints( localOrigin, box.GetExtents(), localAxis, indexPoints ); + + if ( LocalFrustumIntersectsFrustum( indexPoints, true ) ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::IntersectsSphere + + FIXME: test this +============ +*/ +#define VORONOI_INDEX( x, y, z ) ( x + y * 3 + z * 9 ) + +bool idFrustum::IntersectsSphere( const idSphere &sphere ) const { + int index, x, y, z; + float scale, r, d; + idVec3 p, dir, points[8]; + + if ( CullSphere( sphere ) ) { + return false; + } + + x = y = z = 0; + dir.Zero(); + + p = ( sphere.GetOrigin() - origin ) * axis.Transpose(); + + if ( p.x <= dNear ) { + scale = dNear * invFar; + dir.y = idMath::Fabs( p.y ) - dLeft * scale; + dir.z = idMath::Fabs( p.z ) - dUp * scale; + } + else if ( p.x >= dFar ) { + dir.y = idMath::Fabs( p.y ) - dLeft; + dir.z = idMath::Fabs( p.z ) - dUp; + } + else { + scale = p.x * invFar; + dir.y = idMath::Fabs( p.y ) - dLeft * scale; + dir.z = idMath::Fabs( p.z ) - dUp * scale; + } + if ( dir.y > 0.0f ) { + y = ( 1 + FLOATSIGNBITNOTSET( p.y ) ); + } + if ( dir.z > 0.0f ) { + z = ( 1 + FLOATSIGNBITNOTSET( p.z ) ); + } + if ( p.x < dNear ) { + scale = dLeft * dNear * invFar; + if ( p.x < dNear + ( scale - p.y ) * scale * invFar ) { + scale = dUp * dNear * invFar; + if ( p.x < dNear + ( scale - p.z ) * scale * invFar ) { + x = 1; + } + } + } + else { + if ( p.x > dFar ) { + x = 2; + } + else if ( p.x > dFar + ( dLeft - p.y ) * dLeft * invFar ) { + x = 2; + } + else if ( p.x > dFar + ( dUp - p.z ) * dUp * invFar ) { + x = 2; + } + } + + r = sphere.GetRadius(); + index = VORONOI_INDEX( x, y, z ); + switch( index ) { + case VORONOI_INDEX( 0, 0, 0 ): return true; + case VORONOI_INDEX( 1, 0, 0 ): return ( dNear - p.x < r ); + case VORONOI_INDEX( 2, 0, 0 ): return ( p.x - dFar < r ); + case VORONOI_INDEX( 0, 1, 0 ): d = dFar * p.y - dLeft * p.x; return ( d * d < r * r * ( dFar * dFar + dLeft * dLeft ) ); + case VORONOI_INDEX( 0, 2, 0 ): d = -dFar * p.z - dLeft * p.x; return ( d * d < r * r * ( dFar * dFar + dLeft * dLeft ) ); + case VORONOI_INDEX( 0, 0, 1 ): d = dFar * p.z - dUp * p.x; return ( d * d < r * r * ( dFar * dFar + dUp * dUp ) ); + case VORONOI_INDEX( 0, 0, 2 ): d = -dFar * p.z - dUp * p.x; return ( d * d < r * r * ( dFar * dFar + dUp * dUp ) ); + default: { + ToIndexPoints( points ); + switch( index ) { + case VORONOI_INDEX( 1, 1, 1 ): return sphere.ContainsPoint( points[0] ); + case VORONOI_INDEX( 2, 1, 1 ): return sphere.ContainsPoint( points[4] ); + case VORONOI_INDEX( 1, 2, 1 ): return sphere.ContainsPoint( points[1] ); + case VORONOI_INDEX( 2, 2, 1 ): return sphere.ContainsPoint( points[5] ); + case VORONOI_INDEX( 1, 1, 2 ): return sphere.ContainsPoint( points[2] ); + case VORONOI_INDEX( 2, 1, 2 ): return sphere.ContainsPoint( points[6] ); + case VORONOI_INDEX( 1, 2, 2 ): return sphere.ContainsPoint( points[3] ); + case VORONOI_INDEX( 2, 2, 2 ): return sphere.ContainsPoint( points[7] ); + case VORONOI_INDEX( 1, 1, 0 ): return sphere.LineIntersection( points[0], points[2] ); + case VORONOI_INDEX( 2, 1, 0 ): return sphere.LineIntersection( points[4], points[6] ); + case VORONOI_INDEX( 1, 2, 0 ): return sphere.LineIntersection( points[1], points[3] ); + case VORONOI_INDEX( 2, 2, 0 ): return sphere.LineIntersection( points[5], points[7] ); + case VORONOI_INDEX( 1, 0, 1 ): return sphere.LineIntersection( points[0], points[1] ); + case VORONOI_INDEX( 2, 0, 1 ): return sphere.LineIntersection( points[4], points[5] ); + case VORONOI_INDEX( 0, 1, 1 ): return sphere.LineIntersection( points[0], points[4] ); + case VORONOI_INDEX( 0, 2, 1 ): return sphere.LineIntersection( points[1], points[5] ); + case VORONOI_INDEX( 1, 0, 2 ): return sphere.LineIntersection( points[2], points[3] ); + case VORONOI_INDEX( 2, 0, 2 ): return sphere.LineIntersection( points[6], points[7] ); + case VORONOI_INDEX( 0, 1, 2 ): return sphere.LineIntersection( points[2], points[6] ); + case VORONOI_INDEX( 0, 2, 2 ): return sphere.LineIntersection( points[3], points[7] ); + } + break; + } + } + return false; +} + +/* +============ +idFrustum::IntersectsFrustum +============ +*/ +bool idFrustum::IntersectsFrustum( const idFrustum &frustum ) const { + idVec3 indexPoints2[8], cornerVecs2[4]; + idFrustum localFrustum2; + + localFrustum2 = frustum; + localFrustum2.origin = ( frustum.origin - origin ) * axis.Transpose(); + localFrustum2.axis = frustum.axis * axis.Transpose(); + localFrustum2.ToIndexPointsAndCornerVecs( indexPoints2, cornerVecs2 ); + + if ( CullLocalFrustum( localFrustum2, indexPoints2, cornerVecs2 ) ) { + return false; + } + + idVec3 indexPoints1[8], cornerVecs1[4]; + idFrustum localFrustum1; + + localFrustum1 = *this; + localFrustum1.origin = ( origin - frustum.origin ) * frustum.axis.Transpose(); + localFrustum1.axis = axis * frustum.axis.Transpose(); + localFrustum1.ToIndexPointsAndCornerVecs( indexPoints1, cornerVecs1 ); + + if ( frustum.CullLocalFrustum( localFrustum1, indexPoints1, cornerVecs1 ) ) { + return false; + } + + idSwap( indexPoints2[2], indexPoints2[3] ); + idSwap( indexPoints2[6], indexPoints2[7] ); + + if ( LocalFrustumIntersectsFrustum( indexPoints2, ( localFrustum2.dNear > 0.0f ) ) ) { + return true; + } + + idSwap( indexPoints1[2], indexPoints1[3] ); + idSwap( indexPoints1[6], indexPoints1[7] ); + + if ( frustum.LocalFrustumIntersectsFrustum( indexPoints1, ( localFrustum1.dNear > 0.0f ) ) ) { + return true; + } + + return false; +} + +/* +============ +idFrustum::IntersectsWinding +============ +*/ +bool idFrustum::IntersectsWinding( const idWinding &winding ) const { + int i, j, *pointCull; + float min, max; + idVec3 *localPoints, indexPoints[8], cornerVecs[4]; + idMat3 transpose; + idPlane plane; + + localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); + pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); + + transpose = axis.Transpose(); + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; + } + + // if the winding is culled + if ( CullLocalWinding( localPoints, winding.GetNumPoints(), pointCull ) ) { + return false; + } + + winding.GetPlane( plane ); + + ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + AxisProjection( indexPoints, cornerVecs, plane.Normal(), min, max ); + + // if the frustum does not cross the winding plane + if ( min + plane[3] > 0.0f || max + plane[3] < 0.0f ) { + return false; + } + + // test if any of the winding edges goes through the frustum + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + j = (i+1)%winding.GetNumPoints(); + if ( !( pointCull[i] & pointCull[j] ) ) { + if ( LocalLineIntersection( localPoints[i], localPoints[j] ) ) { + return true; + } + } + } + + idSwap( indexPoints[2], indexPoints[3] ); + idSwap( indexPoints[6], indexPoints[7] ); + + // test if any edges of the frustum intersect the winding + for ( i = 0; i < 4; i++ ) { + if ( winding.LineIntersection( plane, indexPoints[i], indexPoints[4+i] ) ) { + return true; + } + } + if ( dNear > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + if ( winding.LineIntersection( plane, indexPoints[i], indexPoints[(i+1)&3] ) ) { + return true; + } + } + } + for ( i = 0; i < 4; i++ ) { + if ( winding.LineIntersection( plane, indexPoints[4+i], indexPoints[4+((i+1)&3)] ) ) { + return true; + } + } + + return false; +} + +/* +============ +idFrustum::LineIntersection + + Returns true if the line intersects the box between the start and end point. +============ +*/ +bool idFrustum::LineIntersection( const idVec3 &start, const idVec3 &end ) const { + return LocalLineIntersection( ( start - origin ) * axis.Transpose(), ( end - origin ) * axis.Transpose() ); +} + +/* +============ +idFrustum::RayIntersection + + Returns true if the ray intersects the bounds. + The ray can intersect the bounds in both directions from the start point. + If start is inside the frustum then scale1 < 0 and scale2 > 0. +============ +*/ +bool idFrustum::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { + if ( LocalRayIntersection( ( start - origin ) * axis.Transpose(), dir * axis.Transpose(), scale1, scale2 ) ) { + return true; + } + if ( scale1 <= scale2 ) { + return true; + } + return false; +} + +/* +============ +idFrustum::FromProjection + + Creates a frustum which contains the projection of the bounds. +============ +*/ +bool idFrustum::FromProjection( const idBounds &bounds, const idVec3 &projectionOrigin, const float dFar ) { + return FromProjection( idBox( bounds, vec3_origin, mat3_identity ), projectionOrigin, dFar ); +} + +/* +============ +idFrustum::FromProjection + + Creates a frustum which contains the projection of the box. +============ +*/ +bool idFrustum::FromProjection( const idBox &box, const idVec3 &projectionOrigin, const float dFar ) { + int i, bestAxis; + float value, bestValue; + idVec3 dir; + + assert( dFar > 0.0f ); + + this->dNear = this->dFar = this->invFar = 0.0f; + + dir = box.GetCenter() - projectionOrigin; + if ( dir.Normalize() == 0.0f ) { + return false; + } + + bestAxis = 0; + bestValue = idMath::Fabs( box.GetAxis()[0] * dir ); + for ( i = 1; i < 3; i++ ) { + value = idMath::Fabs( box.GetAxis()[i] * dir ); + if ( value * box.GetExtents()[bestAxis] * box.GetExtents()[bestAxis] < bestValue * box.GetExtents()[i] * box.GetExtents()[i] ) { + bestValue = value; + bestAxis = i; + } + } + +#if 1 + + int j, minX, minY, maxY, minZ, maxZ; + idVec3 points[8]; + + minX = minY = maxY = minZ = maxZ = 0; + + for ( j = 0; j < 2; j++ ) { + + axis[0] = dir; + axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; + axis[1].Normalize(); + axis[2].Cross( axis[0], axis[1] ); + + BoxToPoints( ( box.GetCenter() - projectionOrigin ) * axis.Transpose(), box.GetExtents(), box.GetAxis() * axis.Transpose(), points ); + + if ( points[0].x <= 1.0f ) { + return false; + } + + minX = minY = maxY = minZ = maxZ = 0; + for ( i = 1; i < 8; i++ ) { + if ( points[i].x <= 1.0f ) { + return false; + } + if ( points[i].x < points[minX].x ) { + minX = i; + } + if ( points[minY].x * points[i].y < points[i].x * points[minY].y ) { + minY = i; + } else if ( points[maxY].x * points[i].y > points[i].x * points[maxY].y ) { + maxY = i; + } + if ( points[minZ].x * points[i].z < points[i].x * points[minZ].z ) { + minZ = i; + } else if ( points[maxZ].x * points[i].z > points[i].x * points[maxZ].z ) { + maxZ = i; + } + } + + if ( j == 0 ) { + dir += idMath::Tan16( 0.5f * ( idMath::ATan16( points[minY].y, points[minY].x ) + idMath::ATan16( points[maxY].y, points[maxY].x ) ) ) * axis[1]; + dir += idMath::Tan16( 0.5f * ( idMath::ATan16( points[minZ].z, points[minZ].x ) + idMath::ATan16( points[maxZ].z, points[maxZ].x ) ) ) * axis[2]; + dir.Normalize(); + } + } + + this->origin = projectionOrigin; + this->dNear = points[minX].x; + this->dFar = dFar; + this->dLeft = Max( idMath::Fabs( points[minY].y / points[minY].x ), idMath::Fabs( points[maxY].y / points[maxY].x ) ) * dFar; + this->dUp = Max( idMath::Fabs( points[minZ].z / points[minZ].x ), idMath::Fabs( points[maxZ].z / points[maxZ].x ) ) * dFar; + this->invFar = 1.0f / dFar; + +#elif 1 + + int j; + float f, x; + idBounds b; + idVec3 points[8]; + + for ( j = 0; j < 2; j++ ) { + + axis[0] = dir; + axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; + axis[1].Normalize(); + axis[2].Cross( axis[0], axis[1] ); + + BoxToPoints( ( box.GetCenter() - projectionOrigin ) * axis.Transpose(), box.GetExtents(), box.GetAxis() * axis.Transpose(), points ); + + b.Clear(); + for ( i = 0; i < 8; i++ ) { + x = points[i].x; + if ( x <= 1.0f ) { + return false; + } + f = 1.0f / x; + points[i].y *= f; + points[i].z *= f; + b.AddPoint( points[i] ); + } + + if ( j == 0 ) { + dir += idMath::Tan16( 0.5f * ( idMath::ATan16( b[1][1] ) + idMath::ATan16( b[0][1] ) ) ) * axis[1]; + dir += idMath::Tan16( 0.5f * ( idMath::ATan16( b[1][2] ) + idMath::ATan16( b[0][2] ) ) ) * axis[2]; + dir.Normalize(); + } + } + + this->origin = projectionOrigin; + this->dNear = b[0][0]; + this->dFar = dFar; + this->dLeft = Max( idMath::Fabs( b[0][1] ), idMath::Fabs( b[1][1] ) ) * dFar; + this->dUp = Max( idMath::Fabs( b[0][2] ), idMath::Fabs( b[1][2] ) ) * dFar; + this->invFar = 1.0f / dFar; + +#else + + float dist; + idVec3 org; + + axis[0] = dir; + axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; + axis[1].Normalize(); + axis[2].Cross( axis[0], axis[1] ); + + for ( i = 0; i < 3; i++ ) { + dist[i] = idMath::Fabs( box.GetExtents()[0] * ( axis[i] * box.GetAxis()[0] ) ) + + idMath::Fabs( box.GetExtents()[1] * ( axis[i] * box.GetAxis()[1] ) ) + + idMath::Fabs( box.GetExtents()[2] * ( axis[i] * box.GetAxis()[2] ) ); + } + + dist[0] = axis[0] * ( box.GetCenter() - projectionOrigin ) - dist[0]; + if ( dist[0] <= 1.0f ) { + return false; + } + float invDist = 1.0f / dist[0]; + + this->origin = projectionOrigin; + this->dNear = dist[0]; + this->dFar = dFar; + this->dLeft = dist[1] * invDist * dFar; + this->dUp = dist[2] * invDist * dFar; + this->invFar = 1.0f / dFar; + +#endif + + return true; +} + +/* +============ +idFrustum::FromProjection + + Creates a frustum which contains the projection of the sphere. +============ +*/ +bool idFrustum::FromProjection( const idSphere &sphere, const idVec3 &projectionOrigin, const float dFar ) { + idVec3 dir; + float d, r, s, x, y; + + assert( dFar > 0.0f ); + + dir = sphere.GetOrigin() - projectionOrigin; + d = dir.Normalize(); + r = sphere.GetRadius(); + + if ( d <= r + 1.0f ) { + this->dNear = this->dFar = this->invFar = 0.0f; + return false; + } + + origin = projectionOrigin; + axis = dir.ToMat3(); + + s = idMath::Sqrt( d * d - r * r ); + x = r / d * s; + y = idMath::Sqrt( s * s - x * x ); + + this->dNear = d - r; + this->dFar = dFar; + this->dLeft = x / y * dFar; + this->dUp = dLeft; + this->invFar = 1.0f / dFar; + + return true; +} + +/* +============ +idFrustum::ConstrainToBounds + + Returns false if no part of the bounds extends beyond the near plane. +============ +*/ +bool idFrustum::ConstrainToBounds( const idBounds &bounds ) { + float min, max, newdFar; + + bounds.AxisProjection( axis[0], min, max ); + newdFar = max - axis[0] * origin; + if ( newdFar <= dNear ) { + MoveFarDistance( dNear + 1.0f ); + return false; + } + MoveFarDistance( newdFar ); + return true; +} + +/* +============ +idFrustum::ConstrainToBox + + Returns false if no part of the box extends beyond the near plane. +============ +*/ +bool idFrustum::ConstrainToBox( const idBox &box ) { + float min, max, newdFar; + + box.AxisProjection( axis[0], min, max ); + newdFar = max - axis[0] * origin; + if ( newdFar <= dNear ) { + MoveFarDistance( dNear + 1.0f ); + return false; + } + MoveFarDistance( newdFar ); + return true; +} + +/* +============ +idFrustum::ConstrainToSphere + + Returns false if no part of the sphere extends beyond the near plane. +============ +*/ +bool idFrustum::ConstrainToSphere( const idSphere &sphere ) { + float min, max, newdFar; + + sphere.AxisProjection( axis[0], min, max ); + newdFar = max - axis[0] * origin; + if ( newdFar <= dNear ) { + MoveFarDistance( dNear + 1.0f ); + return false; + } + MoveFarDistance( newdFar ); + return true; +} + +/* +============ +idFrustum::ConstrainToFrustum + + Returns false if no part of the frustum extends beyond the near plane. +============ +*/ +bool idFrustum::ConstrainToFrustum( const idFrustum &frustum ) { + float min, max, newdFar; + + frustum.AxisProjection( axis[0], min, max ); + newdFar = max - axis[0] * origin; + if ( newdFar <= dNear ) { + MoveFarDistance( dNear + 1.0f ); + return false; + } + MoveFarDistance( newdFar ); + return true; +} + +/* +============ +idFrustum::ToPlanes + + planes point outwards +============ +*/ +void idFrustum::ToPlanes( idPlane planes[6] ) const { + int i; + idVec3 scaled[2]; + idVec3 points[4]; + + planes[0].Normal() = -axis[0]; + planes[0].SetDist( -dNear ); + planes[1].Normal() = axis[0]; + planes[1].SetDist( dFar ); + + scaled[0] = axis[1] * dLeft; + scaled[1] = axis[2] * dUp; + points[0] = scaled[0] + scaled[1]; + points[1] = -scaled[0] + scaled[1]; + points[2] = -scaled[0] - scaled[1]; + points[3] = scaled[0] - scaled[1]; + + for ( i = 0; i < 4; i++ ) { + planes[i+2].Normal() = points[i].Cross( points[(i+1)&3] - points[i] ); + planes[i+2].Normalize(); + planes[i+2].FitThroughPoint( points[i] ); + } +} + +/* +============ +idFrustum::ToPoints +============ +*/ +void idFrustum::ToPoints( idVec3 points[8] ) const { + idMat3 scaled; + + scaled[0] = origin + axis[0] * dNear; + scaled[1] = axis[1] * ( dLeft * dNear * invFar ); + scaled[2] = axis[2] * ( dUp * dNear * invFar ); + + points[0] = scaled[0] + scaled[1]; + points[1] = scaled[0] - scaled[1]; + points[2] = points[1] - scaled[2]; + points[3] = points[0] - scaled[2]; + points[0] += scaled[2]; + points[1] += scaled[2]; + + scaled[0] = origin + axis[0] * dFar; + scaled[1] = axis[1] * dLeft; + scaled[2] = axis[2] * dUp; + + points[4] = scaled[0] + scaled[1]; + points[5] = scaled[0] - scaled[1]; + points[6] = points[5] - scaled[2]; + points[7] = points[4] - scaled[2]; + points[4] += scaled[2]; + points[5] += scaled[2]; +} + +/* +============ +idFrustum::ToClippedPoints +============ +*/ +void idFrustum::ToClippedPoints( const float fractions[4], idVec3 points[8] ) const { + idMat3 scaled; + + scaled[0] = origin + axis[0] * dNear; + scaled[1] = axis[1] * ( dLeft * dNear * invFar ); + scaled[2] = axis[2] * ( dUp * dNear * invFar ); + + points[0] = scaled[0] + scaled[1]; + points[1] = scaled[0] - scaled[1]; + points[2] = points[1] - scaled[2]; + points[3] = points[0] - scaled[2]; + points[0] += scaled[2]; + points[1] += scaled[2]; + + scaled[0] = axis[0] * dFar; + scaled[1] = axis[1] * dLeft; + scaled[2] = axis[2] * dUp; + + points[4] = scaled[0] + scaled[1]; + points[5] = scaled[0] - scaled[1]; + points[6] = points[5] - scaled[2]; + points[7] = points[4] - scaled[2]; + points[4] += scaled[2]; + points[5] += scaled[2]; + + points[4] = origin + fractions[0] * points[4]; + points[5] = origin + fractions[1] * points[5]; + points[6] = origin + fractions[2] * points[6]; + points[7] = origin + fractions[3] * points[7]; +} + +/* +============ +idFrustum::ToIndexPoints +============ +*/ +void idFrustum::ToIndexPoints( idVec3 indexPoints[8] ) const { + idMat3 scaled; + + scaled[0] = origin + axis[0] * dNear; + scaled[1] = axis[1] * ( dLeft * dNear * invFar ); + scaled[2] = axis[2] * ( dUp * dNear * invFar ); + + indexPoints[0] = scaled[0] - scaled[1]; + indexPoints[2] = scaled[0] + scaled[1]; + indexPoints[1] = indexPoints[0] + scaled[2]; + indexPoints[3] = indexPoints[2] + scaled[2]; + indexPoints[0] -= scaled[2]; + indexPoints[2] -= scaled[2]; + + scaled[0] = origin + axis[0] * dFar; + scaled[1] = axis[1] * dLeft; + scaled[2] = axis[2] * dUp; + + indexPoints[4] = scaled[0] - scaled[1]; + indexPoints[6] = scaled[0] + scaled[1]; + indexPoints[5] = indexPoints[4] + scaled[2]; + indexPoints[7] = indexPoints[6] + scaled[2]; + indexPoints[4] -= scaled[2]; + indexPoints[6] -= scaled[2]; +} + +/* +============ +idFrustum::ToIndexPointsAndCornerVecs + + 22 muls +============ +*/ +void idFrustum::ToIndexPointsAndCornerVecs( idVec3 indexPoints[8], idVec3 cornerVecs[4] ) const { + idMat3 scaled; + + scaled[0] = origin + axis[0] * dNear; + scaled[1] = axis[1] * ( dLeft * dNear * invFar ); + scaled[2] = axis[2] * ( dUp * dNear * invFar ); + + indexPoints[0] = scaled[0] - scaled[1]; + indexPoints[2] = scaled[0] + scaled[1]; + indexPoints[1] = indexPoints[0] + scaled[2]; + indexPoints[3] = indexPoints[2] + scaled[2]; + indexPoints[0] -= scaled[2]; + indexPoints[2] -= scaled[2]; + + scaled[0] = axis[0] * dFar; + scaled[1] = axis[1] * dLeft; + scaled[2] = axis[2] * dUp; + + cornerVecs[0] = scaled[0] - scaled[1]; + cornerVecs[2] = scaled[0] + scaled[1]; + cornerVecs[1] = cornerVecs[0] + scaled[2]; + cornerVecs[3] = cornerVecs[2] + scaled[2]; + cornerVecs[0] -= scaled[2]; + cornerVecs[2] -= scaled[2]; + + indexPoints[4] = cornerVecs[0] + origin; + indexPoints[5] = cornerVecs[1] + origin; + indexPoints[6] = cornerVecs[2] + origin; + indexPoints[7] = cornerVecs[3] + origin; +} + +/* +============ +idFrustum::AxisProjection + + 18 muls +============ +*/ +void idFrustum::AxisProjection( const idVec3 indexPoints[8], const idVec3 cornerVecs[4], const idVec3 &dir, float &min, float &max ) const { + float dx, dy, dz; + int index; + + dy = dir.x * axis[1].x + dir.y * axis[1].y + dir.z * axis[1].z; + dz = dir.x * axis[2].x + dir.y * axis[2].y + dir.z * axis[2].z; + index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); + dx = dir.x * cornerVecs[index].x + dir.y * cornerVecs[index].y + dir.z * cornerVecs[index].z; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + min = indexPoints[index] * dir; + index = ~index & 3; + dx = -dir.x * cornerVecs[index].x - dir.y * cornerVecs[index].y - dir.z * cornerVecs[index].z; + index |= ( FLOATSIGNBITSET( dx ) << 2 ); + max = indexPoints[index] * dir; +} + +/* +============ +idFrustum::AxisProjection + + 40 muls +============ +*/ +void idFrustum::AxisProjection( const idVec3 &dir, float &min, float &max ) const { + idVec3 indexPoints[8], cornerVecs[4]; + + ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + AxisProjection( indexPoints, cornerVecs, dir, min, max ); +} + +/* +============ +idFrustum::AxisProjection + + 76 muls +============ +*/ +void idFrustum::AxisProjection( const idMat3 &ax, idBounds &bounds ) const { + idVec3 indexPoints[8], cornerVecs[4]; + + ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); + AxisProjection( indexPoints, cornerVecs, ax[0], bounds[0][0], bounds[1][0] ); + AxisProjection( indexPoints, cornerVecs, ax[1], bounds[0][1], bounds[1][1] ); + AxisProjection( indexPoints, cornerVecs, ax[2], bounds[0][2], bounds[1][2] ); +} + +/* +============ +idFrustum::AddLocalLineToProjectionBoundsSetCull +============ +*/ +void idFrustum::AddLocalLineToProjectionBoundsSetCull( const idVec3 &start, const idVec3 &end, int &startCull, int &endCull, idBounds &bounds ) const { + idVec3 dir, p; + float d1, d2, fstart, fend, lstart, lend, f; + float leftScale, upScale; + int cull1, cull2; + +#ifdef FRUSTUM_DEBUG + static idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); + if ( r_showInteractionScissors.GetInteger() > 1 ) { + session->rw->DebugLine( colorGreen, origin + start * axis, origin + end * axis ); + } +#endif + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + dir = end - start; + + fstart = dFar * start.y; + fend = dFar * end.y; + lstart = dLeft * start.x; + lend = dLeft * end.x; + + // test left plane + d1 = -fstart + lstart; + d2 = -fend + lend; + cull1 = FLOATSIGNBITSET( d1 ); + cull2 = FLOATSIGNBITSET( d2 ); + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.z = start.z + f * dir.z; + if ( idMath::Fabs( p.z ) <= p.x * upScale ) { + p.y = 1.0f; + p.z = p.z * dFar / ( p.x * dUp ); + bounds.AddPoint( p ); + } + } + } + } + + // test right plane + d1 = fstart + lstart; + d2 = fend + lend; + cull1 |= FLOATSIGNBITSET( d1 ) << 1; + cull2 |= FLOATSIGNBITSET( d2 ) << 1; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.z = start.z + f * dir.z; + if ( idMath::Fabs( p.z ) <= p.x * upScale ) { + p.y = -1.0f; + p.z = p.z * dFar / ( p.x * dUp ); + bounds.AddPoint( p ); + } + } + } + } + + fstart = dFar * start.z; + fend = dFar * end.z; + lstart = dUp * start.x; + lend = dUp * end.x; + + // test up plane + d1 = -fstart + lstart; + d2 = -fend + lend; + cull1 |= FLOATSIGNBITSET( d1 ) << 2; + cull2 |= FLOATSIGNBITSET( d2 ) << 2; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.y = start.y + f * dir.y; + if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { + p.y = p.y * dFar / ( p.x * dLeft ); + p.z = 1.0f; + bounds.AddPoint( p ); + } + } + } + } + + // test down plane + d1 = fstart + lstart; + d2 = fend + lend; + cull1 |= FLOATSIGNBITSET( d1 ) << 3; + cull2 |= FLOATSIGNBITSET( d2 ) << 3; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.y = start.y + f * dir.y; + if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { + p.y = p.y * dFar / ( p.x * dLeft ); + p.z = -1.0f; + bounds.AddPoint( p ); + } + } + } + } + + if ( cull1 == 0 && start.x > 0.0f ) { + // add start point to projection bounds + p.x = start.x; + p.y = start.y * dFar / ( start.x * dLeft ); + p.z = start.z * dFar / ( start.x * dUp ); + bounds.AddPoint( p ); + } + + if ( cull2 == 0 && end.x > 0.0f ) { + // add end point to projection bounds + p.x = end.x; + p.y = end.y * dFar / ( end.x * dLeft ); + p.z = end.z * dFar / ( end.x * dUp ); + bounds.AddPoint( p ); + } + + if ( start.x < bounds[0].x ) { + bounds[0].x = start.x < 0.0f ? 0.0f : start.x; + } + if ( end.x < bounds[0].x ) { + bounds[0].x = end.x < 0.0f ? 0.0f : end.x; + } + + startCull = cull1; + endCull = cull2; +} + +/* +============ +idFrustum::AddLocalLineToProjectionBoundsUseCull +============ +*/ +void idFrustum::AddLocalLineToProjectionBoundsUseCull( const idVec3 &start, const idVec3 &end, int startCull, int endCull, idBounds &bounds ) const { + idVec3 dir, p; + float d1, d2, fstart, fend, lstart, lend, f; + float leftScale, upScale; + int clip; + + clip = startCull ^ endCull; + if ( !clip ) { + return; + } + +#ifdef FRUSTUM_DEBUG + static idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); + if ( r_showInteractionScissors.GetInteger() > 1 ) { + session->rw->DebugLine( colorGreen, origin + start * axis, origin + end * axis ); + } +#endif + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + dir = end - start; + + if ( clip & (1|2) ) { + + fstart = dFar * start.y; + fend = dFar * end.y; + lstart = dLeft * start.x; + lend = dLeft * end.x; + + if ( clip & 1 ) { + // test left plane + d1 = -fstart + lstart; + d2 = -fend + lend; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.z = start.z + f * dir.z; + if ( idMath::Fabs( p.z ) <= p.x * upScale ) { + p.y = 1.0f; + p.z = p.z * dFar / ( p.x * dUp ); + bounds.AddPoint( p ); + } + } + } + } + } + + if ( clip & 2 ) { + // test right plane + d1 = fstart + lstart; + d2 = fend + lend; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.z = start.z + f * dir.z; + if ( idMath::Fabs( p.z ) <= p.x * upScale ) { + p.y = -1.0f; + p.z = p.z * dFar / ( p.x * dUp ); + bounds.AddPoint( p ); + } + } + } + } + } + } + + if ( clip & (4|8) ) { + + fstart = dFar * start.z; + fend = dFar * end.z; + lstart = dUp * start.x; + lend = dUp * end.x; + + if ( clip & 4 ) { + // test up plane + d1 = -fstart + lstart; + d2 = -fend + lend; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.y = start.y + f * dir.y; + if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { + p.y = p.y * dFar / ( p.x * dLeft ); + p.z = 1.0f; + bounds.AddPoint( p ); + } + } + } + } + } + + if ( clip & 8 ) { + // test down plane + d1 = fstart + lstart; + d2 = fend + lend; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( p.x > 0.0f ) { + p.y = start.y + f * dir.y; + if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { + p.y = p.y * dFar / ( p.x * dLeft ); + p.z = -1.0f; + bounds.AddPoint( p ); + } + } + } + } + } + } +} + +/* +============ +idFrustum::BoundsRayIntersection + + Returns true if the ray starts inside the bounds. + If there was an intersection scale1 <= scale2 +============ +*/ +bool idFrustum::BoundsRayIntersection( const idBounds &bounds, const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { + idVec3 end, p; + float d1, d2, f; + int i, startInside = 1; + + scale1 = idMath::INFINITY; + scale2 = -idMath::INFINITY; + + end = start + dir; + + for ( i = 0; i < 2; i++ ) { + d1 = start.x - bounds[i].x; + startInside &= FLOATSIGNBITSET( d1 ) ^ i; + d2 = end.x - bounds[i].x; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + p.y = start.y + f * dir.y; + if ( bounds[0].y <= p.y && p.y <= bounds[1].y ) { + p.z = start.z + f * dir.z; + if ( bounds[0].z <= p.z && p.z <= bounds[1].z ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + d1 = start.y - bounds[i].y; + startInside &= FLOATSIGNBITSET( d1 ) ^ i; + d2 = end.y - bounds[i].y; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( bounds[0].x <= p.x && p.x <= bounds[1].x ) { + p.z = start.z + f * dir.z; + if ( bounds[0].z <= p.z && p.z <= bounds[1].z ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + + d1 = start.z - bounds[i].z; + startInside &= FLOATSIGNBITSET( d1 ) ^ i; + d2 = end.z - bounds[i].z; + if ( d1 != d2 ) { + f = d1 / ( d1 - d2 ); + p.x = start.x + f * dir.x; + if ( bounds[0].x <= p.x && p.x <= bounds[1].x ) { + p.y = start.y + f * dir.y; + if ( bounds[0].y <= p.y && p.y <= bounds[1].y ) { + if ( f < scale1 ) scale1 = f; + if ( f > scale2 ) scale2 = f; + } + } + } + } + + return ( startInside != 0 ); +} + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idBounds &bounds, idBounds &projectionBounds ) const { + return ProjectionBounds( idBox( bounds, vec3_origin, mat3_identity ), projectionBounds ); +} + +#if !defined(__linux__) && !defined(MACOS_X) + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const { + int i, p1, p2, pointCull[8], culled, outside; + float scale1, scale2; + idFrustum localFrustum; + idVec3 points[8], localOrigin; + idMat3 localAxis, localScaled; + idBounds bounds( -box.GetExtents(), box.GetExtents() ); + + // if the frustum origin is inside the bounds + if ( bounds.ContainsPoint( ( origin - box.GetCenter() ) * box.GetAxis().Transpose() ) ) { + // bounds that cover the whole frustum + float boxMin, boxMax, base; + + base = origin * axis[0]; + box.AxisProjection( axis[0], boxMin, boxMax ); + + projectionBounds[0].x = boxMin - base; + projectionBounds[1].x = boxMax - base; + projectionBounds[0].y = projectionBounds[0].z = -1.0f; + projectionBounds[1].y = projectionBounds[1].z = 1.0f; + + return true; + } + + projectionBounds.Clear(); + + // transform the bounds into the space of this frustum + localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); + localAxis = box.GetAxis() * axis.Transpose(); + BoxToPoints( localOrigin, box.GetExtents(), localAxis, points ); + + // test outer four edges of the bounds + culled = -1; + outside = 0; + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = 4 + i; + AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + culled &= pointCull[p1] & pointCull[p2]; + outside |= pointCull[p1] | pointCull[p2]; + } + + // if the bounds are completely outside this frustum + if ( culled ) { + return false; + } + + // if the bounds are completely inside this frustum + if ( !outside ) { + return true; + } + + // test the remaining edges of the bounds + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = (i+1)&3; + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + for ( i = 0; i < 4; i++ ) { + p1 = 4 + i; + p2 = 4 + ((i+1)&3); + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + // if the bounds extend beyond two or more boundaries of this frustum + if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { + + localOrigin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); + localScaled = axis * box.GetAxis().Transpose(); + localScaled[0] *= dFar; + localScaled[1] *= dLeft; + localScaled[2] *= dUp; + + // test the outer edges of this frustum for intersection with the bounds + if ( (outside & 2) && (outside & 8) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); + } + } + if ( (outside & 2) && (outside & 4) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); + } + } + if ( (outside & 1) && (outside & 8) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); + } + } + if ( (outside & 1) && (outside & 2) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); + } + } + } + + return true; +} + +#endif + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idSphere &sphere, idBounds &projectionBounds ) const { + float d, r, rs, sFar; + idVec3 center; + + projectionBounds.Clear(); + + center = ( sphere.GetOrigin() - origin ) * axis.Transpose(); + r = sphere.GetRadius(); + rs = r * r; + sFar = dFar * dFar; + + // test left/right planes + d = dFar * idMath::Fabs( center.y ) - dLeft * center.x; + if ( ( d * d ) > rs * ( sFar + dLeft * dLeft ) ) { + return false; + } + + // test up/down planes + d = dFar * idMath::Fabs( center.z ) - dUp * center.x; + if ( ( d * d ) > rs * ( sFar + dUp * dUp ) ) { + return false; + } + + // bounds that cover the whole frustum + projectionBounds[0].x = 0.0f; + projectionBounds[1].x = dFar; + projectionBounds[0].y = projectionBounds[0].z = -1.0f; + projectionBounds[1].y = projectionBounds[1].z = 1.0f; + return true; +} + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idFrustum &frustum, idBounds &projectionBounds ) const { + int i, p1, p2, pointCull[8], culled, outside; + float scale1, scale2; + idFrustum localFrustum; + idVec3 points[8], localOrigin; + idMat3 localScaled; + + // if the frustum origin is inside the other frustum + if ( frustum.ContainsPoint( origin ) ) { + // bounds that cover the whole frustum + float frustumMin, frustumMax, base; + + base = origin * axis[0]; + frustum.AxisProjection( axis[0], frustumMin, frustumMax ); + + projectionBounds[0].x = frustumMin - base; + projectionBounds[1].x = frustumMax - base; + projectionBounds[0].y = projectionBounds[0].z = -1.0f; + projectionBounds[1].y = projectionBounds[1].z = 1.0f; + return true; + } + + projectionBounds.Clear(); + + // transform the given frustum into the space of this frustum + localFrustum = frustum; + localFrustum.origin = ( frustum.origin - origin ) * axis.Transpose(); + localFrustum.axis = frustum.axis * axis.Transpose(); + localFrustum.ToPoints( points ); + + // test outer four edges of the other frustum + culled = -1; + outside = 0; + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = 4 + i; + AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + culled &= pointCull[p1] & pointCull[p2]; + outside |= pointCull[p1] | pointCull[p2]; + } + + // if the other frustum is completely outside this frustum + if ( culled ) { + return false; + } + + // if the other frustum is completely inside this frustum + if ( !outside ) { + return true; + } + + // test the remaining edges of the other frustum + if ( localFrustum.dNear > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = (i+1)&3; + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + } + + for ( i = 0; i < 4; i++ ) { + p1 = 4 + i; + p2 = 4 + ((i+1)&3); + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + // if the other frustum extends beyond two or more boundaries of this frustum + if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { + + localOrigin = ( origin - frustum.origin ) * frustum.axis.Transpose(); + localScaled = axis * frustum.axis.Transpose(); + localScaled[0] *= dFar; + localScaled[1] *= dLeft; + localScaled[2] *= dUp; + + // test the outer edges of this frustum for intersection with the other frustum + if ( (outside & 2) && (outside & 8) ) { + frustum.LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); + } + } + if ( (outside & 2) && (outside & 4) ) { + frustum.LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); + } + } + if ( (outside & 1) && (outside & 8) ) { + frustum.LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); + } + } + if ( (outside & 1) && (outside & 2) ) { + frustum.LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); + } + } + } + + return true; +} + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idWinding &winding, idBounds &projectionBounds ) const { + int i, p1, p2, *pointCull, culled, outside; + float scale; + idVec3 *localPoints; + idMat3 transpose, scaled; + idPlane plane; + + projectionBounds.Clear(); + + // transform the winding points into the space of this frustum + localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); + transpose = axis.Transpose(); + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; + } + + // test the winding edges + culled = -1; + outside = 0; + pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); + for ( i = 0; i < winding.GetNumPoints(); i += 2 ) { + p1 = i; + p2 = (i+1)%winding.GetNumPoints(); + AddLocalLineToProjectionBoundsSetCull( localPoints[p1], localPoints[p2], pointCull[p1], pointCull[p2], projectionBounds ); + culled &= pointCull[p1] & pointCull[p2]; + outside |= pointCull[p1] | pointCull[p2]; + } + + // if completely culled + if ( culled ) { + return false; + } + + // if completely inside + if ( !outside ) { + return true; + } + + // test remaining winding edges + for ( i = 1; i < winding.GetNumPoints(); i += 2 ) { + p1 = i; + p2 = (i+1)%winding.GetNumPoints(); + AddLocalLineToProjectionBoundsUseCull( localPoints[p1], localPoints[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + // if the winding extends beyond two or more boundaries of this frustum + if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { + + winding.GetPlane( plane ); + scaled[0] = axis[0] * dFar; + scaled[1] = axis[1] * dLeft; + scaled[2] = axis[2] * dUp; + + // test the outer edges of this frustum for intersection with the winding + if ( (outside & 2) && (outside & 8) ) { + if ( winding.RayIntersection( plane, origin, scaled[0] - scaled[1] - scaled[2], scale ) ) { + projectionBounds.AddPoint( idVec3( scale * dFar, -1.0f, -1.0f ) ); + } + } + if ( (outside & 2) && (outside & 4) ) { + if ( winding.RayIntersection( plane, origin, scaled[0] - scaled[1] + scaled[2], scale ) ) { + projectionBounds.AddPoint( idVec3( scale * dFar, -1.0f, 1.0f ) ); + } + } + if ( (outside & 1) && (outside & 8) ) { + if ( winding.RayIntersection( plane, origin, scaled[0] + scaled[1] - scaled[2], scale ) ) { + projectionBounds.AddPoint( idVec3( scale * dFar, 1.0f, -1.0f ) ); + } + } + if ( (outside & 1) && (outside & 2) ) { + if ( winding.RayIntersection( plane, origin, scaled[0] + scaled[1] + scaled[2], scale ) ) { + projectionBounds.AddPoint( idVec3( scale * dFar, 1.0f, 1.0f ) ); + } + } + } + + return true; +} + +/* +============ +idFrustum::ClipFrustumToBox + + Clips the frustum far extents to the box. +============ +*/ +void idFrustum::ClipFrustumToBox( const idBox &box, float clipFractions[4], int clipPlanes[4] ) const { + int i, index; + float f, minf; + idMat3 scaled, localAxis, transpose; + idVec3 localOrigin, cornerVecs[4]; + idBounds bounds; + + transpose = box.GetAxis(); + transpose.TransposeSelf(); + localOrigin = ( origin - box.GetCenter() ) * transpose; + localAxis = axis * transpose; + + scaled[0] = localAxis[0] * dFar; + scaled[1] = localAxis[1] * dLeft; + scaled[2] = localAxis[2] * dUp; + cornerVecs[0] = scaled[0] + scaled[1]; + cornerVecs[1] = scaled[0] - scaled[1]; + cornerVecs[2] = cornerVecs[1] - scaled[2]; + cornerVecs[3] = cornerVecs[0] - scaled[2]; + cornerVecs[0] += scaled[2]; + cornerVecs[1] += scaled[2]; + + bounds[0] = -box.GetExtents(); + bounds[1] = box.GetExtents(); + + minf = ( dNear + 1.0f ) * invFar; + + for ( i = 0; i < 4; i++ ) { + + index = FLOATSIGNBITNOTSET( cornerVecs[i].x ); + f = ( bounds[index].x - localOrigin.x ) / cornerVecs[i].x; + clipFractions[i] = f; + clipPlanes[i] = 1 << index; + + index = FLOATSIGNBITNOTSET( cornerVecs[i].y ); + f = ( bounds[index].y - localOrigin.y ) / cornerVecs[i].y; + if ( f < clipFractions[i] ) { + clipFractions[i] = f; + clipPlanes[i] = 4 << index; + } + + index = FLOATSIGNBITNOTSET( cornerVecs[i].z ); + f = ( bounds[index].z - localOrigin.z ) / cornerVecs[i].z; + if ( f < clipFractions[i] ) { + clipFractions[i] = f; + clipPlanes[i] = 16 << index; + } + + // make sure the frustum is not clipped between the frustum origin and the near plane + if ( clipFractions[i] < minf ) { + clipFractions[i] = minf; + } + } +} + +/* +============ +idFrustum::ClipLine + + Returns true if part of the line is inside the frustum. + Does not clip to the near and far plane. +============ +*/ +bool idFrustum::ClipLine( const idVec3 localPoints[8], const idVec3 points[8], int startIndex, int endIndex, idVec3 &start, idVec3 &end, int &startClip, int &endClip ) const { + float d1, d2, fstart, fend, lstart, lend, f, x; + float leftScale, upScale; + float scale1, scale2; + int startCull, endCull; + idVec3 localStart, localEnd, localDir; + + leftScale = dLeft * invFar; + upScale = dUp * invFar; + + localStart = localPoints[startIndex]; + localEnd = localPoints[endIndex]; + localDir = localEnd - localStart; + + startClip = endClip = -1; + scale1 = idMath::INFINITY; + scale2 = -idMath::INFINITY; + + fstart = dFar * localStart.y; + fend = dFar * localEnd.y; + lstart = dLeft * localStart.x; + lend = dLeft * localEnd.x; + + // test left plane + d1 = -fstart + lstart; + d2 = -fend + lend; + startCull = FLOATSIGNBITSET( d1 ); + endCull = FLOATSIGNBITSET( d2 ); + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = localStart.x + f * localDir.x; + if ( x >= 0.0f ) { + if ( idMath::Fabs( localStart.z + f * localDir.z ) <= x * upScale ) { + if ( f < scale1 ) { scale1 = f; startClip = 0; } + if ( f > scale2 ) { scale2 = f; endClip = 0; } + } + } + } + } + + // test right plane + d1 = fstart + lstart; + d2 = fend + lend; + startCull |= FLOATSIGNBITSET( d1 ) << 1; + endCull |= FLOATSIGNBITSET( d2 ) << 1; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = localStart.x + f * localDir.x; + if ( x >= 0.0f ) { + if ( idMath::Fabs( localStart.z + f * localDir.z ) <= x * upScale ) { + if ( f < scale1 ) { scale1 = f; startClip = 1; } + if ( f > scale2 ) { scale2 = f; endClip = 1; } + } + } + } + } + + fstart = dFar * localStart.z; + fend = dFar * localEnd.z; + lstart = dUp * localStart.x; + lend = dUp * localEnd.x; + + // test up plane + d1 = -fstart + lstart; + d2 = -fend + lend; + startCull |= FLOATSIGNBITSET( d1 ) << 2; + endCull |= FLOATSIGNBITSET( d2 ) << 2; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = localStart.x + f * localDir.x; + if ( x >= 0.0f ) { + if ( idMath::Fabs( localStart.y + f * localDir.y ) <= x * leftScale ) { + if ( f < scale1 ) { scale1 = f; startClip = 2; } + if ( f > scale2 ) { scale2 = f; endClip = 2; } + } + } + } + } + + // test down plane + d1 = fstart + lstart; + d2 = fend + lend; + startCull |= FLOATSIGNBITSET( d1 ) << 3; + endCull |= FLOATSIGNBITSET( d2 ) << 3; + if ( FLOATNOTZERO( d1 ) ) { + if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { + f = d1 / ( d1 - d2 ); + x = localStart.x + f * localDir.x; + if ( x >= 0.0f ) { + if ( idMath::Fabs( localStart.y + f * localDir.y ) <= x * leftScale ) { + if ( f < scale1 ) { scale1 = f; startClip = 3; } + if ( f > scale2 ) { scale2 = f; endClip = 3; } + } + } + } + } + + // if completely inside + if ( !( startCull | endCull ) ) { + start = points[startIndex]; + end = points[endIndex]; + return true; + } + else if ( scale1 <= scale2 ) { + if ( !startCull ) { + start = points[startIndex]; + startClip = -1; + } + else { + start = points[startIndex] + scale1 * ( points[endIndex] - points[startIndex] ); + } + if ( !endCull ) { + end = points[endIndex]; + endClip = -1; + } + else { + end = points[startIndex] + scale2 * ( points[endIndex] - points[startIndex] ); + } + return true; + } + return false; +} + +/* +============ +idFrustum::AddLocalCapsToProjectionBounds +============ +*/ +static int capPointIndex[4][2] = { + { 0, 3 }, + { 1, 2 }, + { 0, 1 }, + { 2, 3 } +}; + +ID_INLINE bool idFrustum::AddLocalCapsToProjectionBounds( const idVec3 endPoints[4], const int endPointCull[4], const idVec3 &point, int pointCull, int pointClip, idBounds &projectionBounds ) const { + int *p; + + if ( pointClip < 0 ) { + return false; + } + p = capPointIndex[pointClip]; + AddLocalLineToProjectionBoundsUseCull( endPoints[p[0]], point, endPointCull[p[0]], pointCull, projectionBounds ); + AddLocalLineToProjectionBoundsUseCull( endPoints[p[1]], point, endPointCull[p[1]], pointCull, projectionBounds ); + return true; +} + +/* +============ +idFrustum::ClippedProjectionBounds +============ +*/ +bool idFrustum::ClippedProjectionBounds( const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds ) const { + int i, p1, p2, clipPointCull[8], clipPlanes[4], usedClipPlanes, nearCull, farCull, outside; + int pointCull[2], startClip, endClip, boxPointCull[8]; + float clipFractions[4], s1, s2, t1, t2, leftScale, upScale; + idFrustum localFrustum; + idVec3 clipPoints[8], localPoints1[8], localPoints2[8], localOrigin1, localOrigin2, start, end; + idMat3 localAxis1, localAxis2, transpose; + idBounds clipBounds; + + // if the frustum origin is inside the other frustum + if ( frustum.ContainsPoint( origin ) ) { + // bounds that cover the whole frustum + float clipBoxMin, clipBoxMax, frustumMin, frustumMax, base; + + base = origin * axis[0]; + clipBox.AxisProjection( axis[0], clipBoxMin, clipBoxMax ); + frustum.AxisProjection( axis[0], frustumMin, frustumMax ); + + projectionBounds[0].x = Max( clipBoxMin, frustumMin ) - base; + projectionBounds[1].x = Min( clipBoxMax, frustumMax ) - base; + projectionBounds[0].y = projectionBounds[0].z = -1.0f; + projectionBounds[1].y = projectionBounds[1].z = 1.0f; + return true; + } + + projectionBounds.Clear(); + + // clip the outer edges of the given frustum to the clip bounds + frustum.ClipFrustumToBox( clipBox, clipFractions, clipPlanes ); + usedClipPlanes = clipPlanes[0] | clipPlanes[1] | clipPlanes[2] | clipPlanes[3]; + + // transform the clipped frustum to the space of this frustum + transpose = axis; + transpose.TransposeSelf(); + localFrustum = frustum; + localFrustum.origin = ( frustum.origin - origin ) * transpose; + localFrustum.axis = frustum.axis * transpose; + localFrustum.ToClippedPoints( clipFractions, clipPoints ); + + // test outer four edges of the clipped frustum + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = 4 + i; + AddLocalLineToProjectionBoundsSetCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); + } + + // get cull bits for the clipped frustum + outside = clipPointCull[0] | clipPointCull[1] | clipPointCull[2] | clipPointCull[3] | + clipPointCull[4] | clipPointCull[5] | clipPointCull[6] | clipPointCull[7]; + nearCull = clipPointCull[0] & clipPointCull[1] & clipPointCull[2] & clipPointCull[3]; + farCull = clipPointCull[4] & clipPointCull[5] & clipPointCull[6] & clipPointCull[7]; + + // if the clipped frustum is not completely inside this frustum + if ( outside ) { + + // test the remaining edges of the clipped frustum + if ( !nearCull && localFrustum.dNear > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = (i+1)&3; + AddLocalLineToProjectionBoundsUseCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); + } + } + + if ( !farCull ) { + for ( i = 0; i < 4; i++ ) { + p1 = 4 + i; + p2 = 4 + ((i+1)&3); + AddLocalLineToProjectionBoundsUseCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); + } + } + } + + // if the clipped frustum far end points are inside this frustum + if ( !( farCull && !( nearCull & farCull ) ) && + // if the clipped frustum is not clipped to a single plane of the clip bounds + ( clipPlanes[0] != clipPlanes[1] || clipPlanes[1] != clipPlanes[2] || clipPlanes[2] != clipPlanes[3] ) ) { + + // transform the clip box into the space of the other frustum + transpose = frustum.axis; + transpose.TransposeSelf(); + localOrigin1 = ( clipBox.GetCenter() - frustum.origin ) * transpose; + localAxis1 = clipBox.GetAxis() * transpose; + BoxToPoints( localOrigin1, clipBox.GetExtents(), localAxis1, localPoints1 ); + + // cull the box corners with the other frustum + leftScale = frustum.dLeft * frustum.invFar; + upScale = frustum.dUp * frustum.invFar; + for ( i = 0; i < 8; i++ ) { + idVec3 &p = localPoints1[i]; + if ( !( boxVertPlanes[i] & usedClipPlanes ) || p.x <= 0.0f ) { + boxPointCull[i] = 1|2|4|8; + } + else { + boxPointCull[i] = 0; + if ( idMath::Fabs( p.y ) > p.x * leftScale ) { + boxPointCull[i] |= 1 << FLOATSIGNBITSET( p.y ); + } + if ( idMath::Fabs( p.z ) > p.x * upScale ) { + boxPointCull[i] |= 4 << FLOATSIGNBITSET( p.z ); + } + } + } + + // transform the clip box into the space of this frustum + transpose = axis; + transpose.TransposeSelf(); + localOrigin2 = ( clipBox.GetCenter() - origin ) * transpose; + localAxis2 = clipBox.GetAxis() * transpose; + BoxToPoints( localOrigin2, clipBox.GetExtents(), localAxis2, localPoints2 ); + + // clip the edges of the clip bounds to the other frustum and add the clipped edges to the projection bounds + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = 4 + i; + if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { + if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { + AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); + outside |= pointCull[0] | pointCull[1]; + } + } + } + + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = (i+1)&3; + if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { + if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { + AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); + outside |= pointCull[0] | pointCull[1]; + } + } + } + + for ( i = 0; i < 4; i++ ) { + p1 = 4 + i; + p2 = 4 + ((i+1)&3); + if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { + if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { + AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); + AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); + outside |= pointCull[0] | pointCull[1]; + } + } + } + } + + // if the clipped frustum extends beyond two or more boundaries of this frustum + if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { + + // transform this frustum into the space of the other frustum + transpose = frustum.axis; + transpose.TransposeSelf(); + localOrigin1 = ( origin - frustum.origin ) * transpose; + localAxis1 = axis * transpose; + localAxis1[0] *= dFar; + localAxis1[1] *= dLeft; + localAxis1[2] *= dUp; + + // transform this frustum into the space of the clip bounds + transpose = clipBox.GetAxis(); + transpose.TransposeSelf(); + localOrigin2 = ( origin - clipBox.GetCenter() ) * transpose; + localAxis2 = axis * transpose; + localAxis2[0] *= dFar; + localAxis2[1] *= dLeft; + localAxis2[2] *= dUp; + + clipBounds[0] = -clipBox.GetExtents(); + clipBounds[1] = clipBox.GetExtents(); + + // test the outer edges of this frustum for intersection with both the other frustum and the clip bounds + if ( (outside & 2) && (outside & 8) ) { + frustum.LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] - localAxis1[2], s1, s2 ); + if ( s1 <= s2 && s1 >= 0.0f ) { + BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] - localAxis2[2], t1, t2 ); + if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { + projectionBounds.AddPoint( idVec3( s1 * dFar, -1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( s2 * dFar, -1.0f, -1.0f ) ); + } + } + } + if ( (outside & 2) && (outside & 4) ) { + frustum.LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] + localAxis1[2], s1, s2 ); + if ( s1 <= s2 && s1 >= 0.0f ) { + BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] + localAxis2[2], t1, t2 ); + if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { + projectionBounds.AddPoint( idVec3( s1 * dFar, -1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( s2 * dFar, -1.0f, 1.0f ) ); + } + } + } + if ( (outside & 1) && (outside & 8) ) { + frustum.LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] - localAxis1[2], s1, s2 ); + if ( s1 <= s2 && s1 >= 0.0f ) { + BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] - localAxis2[2], t1, t2 ); + if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { + projectionBounds.AddPoint( idVec3( s1 * dFar, 1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( s2 * dFar, 1.0f, -1.0f ) ); + } + } + } + if ( (outside & 1) && (outside & 2) ) { + frustum.LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] + localAxis1[2], s1, s2 ); + if ( s1 <= s2 && s1 >= 0.0f ) { + BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] + localAxis2[2], t1, t2 ); + if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { + projectionBounds.AddPoint( idVec3( s1 * dFar, 1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( s2 * dFar, 1.0f, 1.0f ) ); + } + } + } + } + + return true; +} diff --git a/idlib/bv/Frustum.h b/idlib/bv/Frustum.h new file mode 100644 index 000000000..1f31a140d --- /dev/null +++ b/idlib/bv/Frustum.h @@ -0,0 +1,260 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BV_FRUSTUM_H__ +#define __BV_FRUSTUM_H__ + +#ifdef __linux__ +#include +#endif + +/* +=============================================================================== + + Orthogonal Frustum + +=============================================================================== +*/ + +class idFrustum { +public: + idFrustum( void ); + + void SetOrigin( const idVec3 &origin ); + void SetAxis( const idMat3 &axis ); + void SetSize( float dNear, float dFar, float dLeft, float dUp ); + void SetPyramid( float dNear, float dFar ); + void MoveNearDistance( float dNear ); + void MoveFarDistance( float dFar ); + + const idVec3 & GetOrigin( void ) const; // returns frustum origin + const idMat3 & GetAxis( void ) const; // returns frustum orientation + idVec3 GetCenter( void ) const; // returns center of frustum + + bool IsValid( void ) const; // returns true if the frustum is valid + float GetNearDistance( void ) const; // returns distance to near plane + float GetFarDistance( void ) const; // returns distance to far plane + float GetLeft( void ) const; // returns left vector length + float GetUp( void ) const; // returns up vector length + + idFrustum Expand( const float d ) const; // returns frustum expanded in all directions with the given value + idFrustum & ExpandSelf( const float d ); // expands frustum in all directions with the given value + idFrustum Translate( const idVec3 &translation ) const; // returns translated frustum + idFrustum & TranslateSelf( const idVec3 &translation ); // translates frustum + idFrustum Rotate( const idMat3 &rotation ) const; // returns rotated frustum + idFrustum & RotateSelf( const idMat3 &rotation ); // rotates frustum + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + // fast culling but might not cull everything outside the frustum + bool CullPoint( const idVec3 &point ) const; + bool CullBounds( const idBounds &bounds ) const; + bool CullBox( const idBox &box ) const; + bool CullSphere( const idSphere &sphere ) const; + bool CullFrustum( const idFrustum &frustum ) const; + bool CullWinding( const class idWinding &winding ) const; + + // exact intersection tests + bool ContainsPoint( const idVec3 &point ) const; + bool IntersectsBounds( const idBounds &bounds ) const; + bool IntersectsBox( const idBox &box ) const; + bool IntersectsSphere( const idSphere &sphere ) const; + bool IntersectsFrustum( const idFrustum &frustum ) const; + bool IntersectsWinding( const idWinding &winding ) const; + bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; + + // returns true if the projection origin is far enough away from the bounding volume to create a valid frustum + bool FromProjection( const idBounds &bounds, const idVec3 &projectionOrigin, const float dFar ); + bool FromProjection( const idBox &box, const idVec3 &projectionOrigin, const float dFar ); + bool FromProjection( const idSphere &sphere, const idVec3 &projectionOrigin, const float dFar ); + + // moves the far plane so it extends just beyond the bounding volume + bool ConstrainToBounds( const idBounds &bounds ); + bool ConstrainToBox( const idBox &box ); + bool ConstrainToSphere( const idSphere &sphere ); + bool ConstrainToFrustum( const idFrustum &frustum ); + + void ToPlanes( idPlane planes[6] ) const; // planes point outwards + void ToPoints( idVec3 points[8] ) const; // 8 corners of the frustum + + // calculates the projection of this frustum onto the given axis + void AxisProjection( const idVec3 &dir, float &min, float &max ) const; + void AxisProjection( const idMat3 &ax, idBounds &bounds ) const; + + // calculates the bounds for the projection in this frustum + bool ProjectionBounds( const idBounds &bounds, idBounds &projectionBounds ) const; + bool ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const; + bool ProjectionBounds( const idSphere &sphere, idBounds &projectionBounds ) const; + bool ProjectionBounds( const idFrustum &frustum, idBounds &projectionBounds ) const; + bool ProjectionBounds( const idWinding &winding, idBounds &projectionBounds ) const; + + // calculates the bounds for the projection in this frustum of the given frustum clipped to the given box + bool ClippedProjectionBounds( const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds ) const; + +private: + idVec3 origin; // frustum origin + idMat3 axis; // frustum orientation + float dNear; // distance of near plane, dNear >= 0.0f + float dFar; // distance of far plane, dFar > dNear + float dLeft; // half the width at the far plane + float dUp; // half the height at the far plane + float invFar; // 1.0f / dFar + +private: + bool CullLocalBox( const idVec3 &localOrigin, const idVec3 &extents, const idMat3 &localAxis ) const; + bool CullLocalFrustum( const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const; + bool CullLocalWinding( const idVec3 *points, const int numPoints, int *pointCull ) const; + bool BoundsCullLocalFrustum( const idBounds &bounds, const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const; + bool LocalLineIntersection( const idVec3 &start, const idVec3 &end ) const; + bool LocalRayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; + bool LocalFrustumIntersectsFrustum( const idVec3 points[8], const bool testFirstSide ) const; + bool LocalFrustumIntersectsBounds( const idVec3 points[8], const idBounds &bounds ) const; + void ToClippedPoints( const float fractions[4], idVec3 points[8] ) const; + void ToIndexPoints( idVec3 indexPoints[8] ) const; + void ToIndexPointsAndCornerVecs( idVec3 indexPoints[8], idVec3 cornerVecs[4] ) const; + void AxisProjection( const idVec3 indexPoints[8], const idVec3 cornerVecs[4], const idVec3 &dir, float &min, float &max ) const; + void AddLocalLineToProjectionBoundsSetCull( const idVec3 &start, const idVec3 &end, int &startCull, int &endCull, idBounds &bounds ) const; + void AddLocalLineToProjectionBoundsUseCull( const idVec3 &start, const idVec3 &end, int startCull, int endCull, idBounds &bounds ) const; + bool AddLocalCapsToProjectionBounds( const idVec3 endPoints[4], const int endPointCull[4], const idVec3 &point, int pointCull, int pointClip, idBounds &projectionBounds ) const; + bool BoundsRayIntersection( const idBounds &bounds, const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; + void ClipFrustumToBox( const idBox &box, float clipFractions[4], int clipPlanes[4] ) const; + bool ClipLine( const idVec3 localPoints[8], const idVec3 points[8], int startIndex, int endIndex, idVec3 &start, idVec3 &end, int &startClip, int &endClip ) const; +}; + + +ID_INLINE idFrustum::idFrustum( void ) { + dNear = dFar = 0.0f; +} + +ID_INLINE void idFrustum::SetOrigin( const idVec3 &origin ) { + this->origin = origin; +} + +ID_INLINE void idFrustum::SetAxis( const idMat3 &axis ) { + this->axis = axis; +} + +ID_INLINE void idFrustum::SetSize( float dNear, float dFar, float dLeft, float dUp ) { + assert( dNear >= 0.0f && dFar > dNear && dLeft > 0.0f && dUp > 0.0f ); + this->dNear = dNear; + this->dFar = dFar; + this->dLeft = dLeft; + this->dUp = dUp; + this->invFar = 1.0f / dFar; +} + +ID_INLINE void idFrustum::SetPyramid( float dNear, float dFar ) { + assert( dNear >= 0.0f && dFar > dNear ); + this->dNear = dNear; + this->dFar = dFar; + this->dLeft = dFar; + this->dUp = dFar; + this->invFar = 1.0f / dFar; +} + +ID_INLINE void idFrustum::MoveNearDistance( float dNear ) { + assert( dNear >= 0.0f ); + this->dNear = dNear; +} + +ID_INLINE void idFrustum::MoveFarDistance( float dFar ) { + assert( dFar > this->dNear ); + float scale = dFar / this->dFar; + this->dFar = dFar; + this->dLeft *= scale; + this->dUp *= scale; + this->invFar = 1.0f / dFar; +} + +ID_INLINE const idVec3 &idFrustum::GetOrigin( void ) const { + return origin; +} + +ID_INLINE const idMat3 &idFrustum::GetAxis( void ) const { + return axis; +} + +ID_INLINE idVec3 idFrustum::GetCenter( void ) const { + return ( origin + axis[0] * ( ( dFar - dNear ) * 0.5f ) ); +} + +ID_INLINE bool idFrustum::IsValid( void ) const { + return ( dFar > dNear ); +} + +ID_INLINE float idFrustum::GetNearDistance( void ) const { + return dNear; +} + +ID_INLINE float idFrustum::GetFarDistance( void ) const { + return dFar; +} + +ID_INLINE float idFrustum::GetLeft( void ) const { + return dLeft; +} + +ID_INLINE float idFrustum::GetUp( void ) const { + return dUp; +} + +ID_INLINE idFrustum idFrustum::Expand( const float d ) const { + idFrustum f = *this; + f.origin -= d * f.axis[0]; + f.dFar += 2.0f * d; + f.dLeft = f.dFar * dLeft * invFar; + f.dUp = f.dFar * dUp * invFar; + f.invFar = 1.0f / dFar; + return f; +} + +ID_INLINE idFrustum &idFrustum::ExpandSelf( const float d ) { + origin -= d * axis[0]; + dFar += 2.0f * d; + dLeft = dFar * dLeft * invFar; + dUp = dFar * dUp * invFar; + invFar = 1.0f / dFar; + return *this; +} + +ID_INLINE idFrustum idFrustum::Translate( const idVec3 &translation ) const { + idFrustum f = *this; + f.origin += translation; + return f; +} + +ID_INLINE idFrustum &idFrustum::TranslateSelf( const idVec3 &translation ) { + origin += translation; + return *this; +} + +ID_INLINE idFrustum idFrustum::Rotate( const idMat3 &rotation ) const { + idFrustum f = *this; + f.axis *= rotation; + return f; +} + +ID_INLINE idFrustum &idFrustum::RotateSelf( const idMat3 &rotation ) { + axis *= rotation; + return *this; +} + +#endif /* !__BV_FRUSTUM_H__ */ diff --git a/idlib/bv/Frustum_gcc.cpp b/idlib/bv/Frustum_gcc.cpp new file mode 100644 index 000000000..220fac5d7 --- /dev/null +++ b/idlib/bv/Frustum_gcc.cpp @@ -0,0 +1,134 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../precompiled.h" + +void BoxToPoints( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis, idVec3 points[8] ); + +/* +============ +idFrustum::ProjectionBounds +============ +*/ +bool idFrustum::ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const { + int i, p1, p2, pointCull[8], culled, outside; + float scale1, scale2; + idFrustum localFrustum; + idVec3 points[8], localOrigin; + idMat3 localAxis, localScaled; + idBounds bounds( -box.GetExtents(), box.GetExtents() ); + + // if the frustum origin is inside the bounds + if ( bounds.ContainsPoint( ( origin - box.GetCenter() ) * box.GetAxis().Transpose() ) ) { + // bounds that cover the whole frustum + float boxMin, boxMax, base; + + base = origin * axis[0]; + box.AxisProjection( axis[0], boxMin, boxMax ); + + projectionBounds[0].x = boxMin - base; + projectionBounds[1].x = boxMax - base; + projectionBounds[0].y = projectionBounds[0].z = -1.0f; + projectionBounds[1].y = projectionBounds[1].z = 1.0f; + + return true; + } + + projectionBounds.Clear(); + + // transform the bounds into the space of this frustum + localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); + localAxis = box.GetAxis() * axis.Transpose(); + BoxToPoints( localOrigin, box.GetExtents(), localAxis, points ); + + // test outer four edges of the bounds + culled = -1; + outside = 0; + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = 4 + i; + AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + culled &= pointCull[p1] & pointCull[p2]; + outside |= pointCull[p1] | pointCull[p2]; + } + + // if the bounds are completely outside this frustum + if ( culled ) { + return false; + } + + // if the bounds are completely inside this frustum + if ( !outside ) { + return true; + } + + // test the remaining edges of the bounds + for ( i = 0; i < 4; i++ ) { + p1 = i; + p2 = (i+1)&3; + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + for ( i = 0; i < 4; i++ ) { + p1 = 4 + i; + p2 = 4 + ((i+1)&3); + AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); + } + + // if the bounds extend beyond two or more boundaries of this frustum + if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { + + localOrigin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); + localScaled = axis * box.GetAxis().Transpose(); + localScaled[0] *= dFar; + localScaled[1] *= dLeft; + localScaled[2] *= dUp; + + // test the outer edges of this frustum for intersection with the bounds + if ( (outside & 2) && (outside & 8) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); + } + } + if ( (outside & 2) && (outside & 4) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); + } + } + if ( (outside & 1) && (outside & 8) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); + } + } + if ( (outside & 1) && (outside & 2) ) { + BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); + if ( scale1 <= scale2 && scale1 >= 0.0f ) { + projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); + projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); + } + } + } + + return true; +} diff --git a/idlib/bv/Sphere.cpp b/idlib/bv/Sphere.cpp new file mode 100644 index 000000000..f0f8ffa5a --- /dev/null +++ b/idlib/bv/Sphere.cpp @@ -0,0 +1,146 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +idSphere sphere_zero( vec3_zero, 0.0f ); + + +/* +================ +idSphere::PlaneDistance +================ +*/ +float idSphere::PlaneDistance( const idPlane &plane ) const { + float d; + + d = plane.Distance( origin ); + if ( d > radius ) { + return d - radius; + } + if ( d < -radius ) { + return d + radius; + } + return 0.0f; +} + +/* +================ +idSphere::PlaneSide +================ +*/ +int idSphere::PlaneSide( const idPlane &plane, const float epsilon ) const { + float d; + + d = plane.Distance( origin ); + if ( d > radius + epsilon ) { + return PLANESIDE_FRONT; + } + if ( d < -radius - epsilon ) { + return PLANESIDE_BACK; + } + return PLANESIDE_CROSS; +} + +/* +============ +idSphere::LineIntersection + + Returns true if the line intersects the sphere between the start and end point. +============ +*/ +bool idSphere::LineIntersection( const idVec3 &start, const idVec3 &end ) const { + idVec3 r, s, e; + float a; + + s = start - origin; + e = end - origin; + r = e - s; + a = -s * r; + if ( a <= 0 ) { + return ( s * s < radius * radius ); + } + else if ( a >= r * r ) { + return ( e * e < radius * radius ); + } + else { + r = s + ( a / ( r * r ) ) * r; + return ( r * r < radius * radius ); + } +} + +/* +============ +idSphere::RayIntersection + + Returns true if the ray intersects the sphere. + The ray can intersect the sphere in both directions from the start point. + If start is inside the sphere then scale1 < 0 and scale2 > 0. +============ +*/ +bool idSphere::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { + double a, b, c, d, sqrtd; + idVec3 p; + + p = start - origin; + a = dir * dir; + b = dir * p; + c = p * p - radius * radius; + d = b * b - c * a; + + if ( d < 0.0f ) { + return false; + } + + sqrtd = idMath::Sqrt( d ); + a = 1.0f / a; + + scale1 = ( -b + sqrtd ) * a; + scale2 = ( -b - sqrtd ) * a; + + return true; +} + +/* +============ +idSphere::FromPoints + + Tight sphere for a point set. +============ +*/ +void idSphere::FromPoints( const idVec3 *points, const int numPoints ) { + int i; + float radiusSqr, dist; + idVec3 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, points, numPoints ); + + origin = ( mins + maxs ) * 0.5f; + + radiusSqr = 0.0f; + for ( i = 0; i < numPoints; i++ ) { + dist = ( points[i] - origin ).LengthSqr(); + if ( dist > radiusSqr ) { + radiusSqr = dist; + } + } + radius = idMath::Sqrt( radiusSqr ); +} diff --git a/idlib/bv/Sphere.h b/idlib/bv/Sphere.h new file mode 100644 index 000000000..fff9ed50e --- /dev/null +++ b/idlib/bv/Sphere.h @@ -0,0 +1,266 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BV_SPHERE_H__ +#define __BV_SPHERE_H__ + +/* +=============================================================================== + + Sphere + +=============================================================================== +*/ + +class idSphere { +public: + idSphere( void ); + explicit idSphere( const idVec3 &point ); + explicit idSphere( const idVec3 &point, const float r ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idSphere operator+( const idVec3 &t ) const; // returns tranlated sphere + idSphere & operator+=( const idVec3 &t ); // translate the sphere + idSphere operator+( const idSphere &s ) const; + idSphere & operator+=( const idSphere &s ); + + bool Compare( const idSphere &a ) const; // exact compare, no epsilon + bool Compare( const idSphere &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idSphere &a ) const; // exact compare, no epsilon + bool operator!=( const idSphere &a ) const; // exact compare, no epsilon + + void Clear( void ); // inside out sphere + void Zero( void ); // single point at origin + void SetOrigin( const idVec3 &o ); // set origin of sphere + void SetRadius( const float r ); // set square radius + + const idVec3 & GetOrigin( void ) const; // returns origin of sphere + float GetRadius( void ) const; // returns sphere radius + bool IsCleared( void ) const; // returns true if sphere is inside out + + bool AddPoint( const idVec3 &p ); // add the point, returns true if the sphere expanded + bool AddSphere( const idSphere &s ); // add the sphere, returns true if the sphere expanded + idSphere Expand( const float d ) const; // return bounds expanded in all directions with the given value + idSphere & ExpandSelf( const float d ); // expand bounds in all directions with the given value + idSphere Translate( const idVec3 &translation ) const; + idSphere & TranslateSelf( const idVec3 &translation ); + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + bool ContainsPoint( const idVec3 &p ) const; // includes touching + bool IntersectsSphere( const idSphere &s ) const; // includes touching + bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; + // intersection points are (start + dir * scale1) and (start + dir * scale2) + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; + + // Tight sphere for a point set. + void FromPoints( const idVec3 *points, const int numPoints ); + // Most tight sphere for a translation. + void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); + void FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation ); + // Most tight sphere for a rotation. + void FromPointRotation( const idVec3 &point, const idRotation &rotation ); + void FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation ); + + void AxisProjection( const idVec3 &dir, float &min, float &max ) const; + +private: + idVec3 origin; + float radius; +}; + +extern idSphere sphere_zero; + +ID_INLINE idSphere::idSphere( void ) { +} + +ID_INLINE idSphere::idSphere( const idVec3 &point ) { + origin = point; + radius = 0.0f; +} + +ID_INLINE idSphere::idSphere( const idVec3 &point, const float r ) { + origin = point; + radius = r; +} + +ID_INLINE float idSphere::operator[]( const int index ) const { + return ((float *) &origin)[index]; +} + +ID_INLINE float &idSphere::operator[]( const int index ) { + return ((float *) &origin)[index]; +} + +ID_INLINE idSphere idSphere::operator+( const idVec3 &t ) const { + return idSphere( origin + t, radius ); +} + +ID_INLINE idSphere &idSphere::operator+=( const idVec3 &t ) { + origin += t; + return *this; +} + +ID_INLINE bool idSphere::Compare( const idSphere &a ) const { + return ( origin.Compare( a.origin ) && radius == a.radius ); +} + +ID_INLINE bool idSphere::Compare( const idSphere &a, const float epsilon ) const { + return ( origin.Compare( a.origin, epsilon ) && idMath::Fabs( radius - a.radius ) <= epsilon ); +} + +ID_INLINE bool idSphere::operator==( const idSphere &a ) const { + return Compare( a ); +} + +ID_INLINE bool idSphere::operator!=( const idSphere &a ) const { + return !Compare( a ); +} + +ID_INLINE void idSphere::Clear( void ) { + origin.Zero(); + radius = -1.0f; +} + +ID_INLINE void idSphere::Zero( void ) { + origin.Zero(); + radius = 0.0f; +} + +ID_INLINE void idSphere::SetOrigin( const idVec3 &o ) { + origin = o; +} + +ID_INLINE void idSphere::SetRadius( const float r ) { + radius = r; +} + +ID_INLINE const idVec3 &idSphere::GetOrigin( void ) const { + return origin; +} + +ID_INLINE float idSphere::GetRadius( void ) const { + return radius; +} + +ID_INLINE bool idSphere::IsCleared( void ) const { + return ( radius < 0.0f ); +} + +ID_INLINE bool idSphere::AddPoint( const idVec3 &p ) { + if ( radius < 0.0f ) { + origin = p; + radius = 0.0f; + return true; + } + else { + float r = ( p - origin ).LengthSqr(); + if ( r > radius * radius ) { + r = idMath::Sqrt( r ); + origin += ( p - origin ) * 0.5f * (1.0f - radius / r ); + radius += 0.5f * ( r - radius ); + return true; + } + return false; + } +} + +ID_INLINE bool idSphere::AddSphere( const idSphere &s ) { + if ( radius < 0.0f ) { + origin = s.origin; + radius = s.radius; + return true; + } + else { + float r = ( s.origin - origin ).LengthSqr(); + if ( r > ( radius + s.radius ) * ( radius + s.radius ) ) { + r = idMath::Sqrt( r ); + origin += ( s.origin - origin ) * 0.5f * (1.0f - radius / ( r + s.radius ) ); + radius += 0.5f * ( ( r + s.radius ) - radius ); + return true; + } + return false; + } +} + +ID_INLINE idSphere idSphere::Expand( const float d ) const { + return idSphere( origin, radius + d ); +} + +ID_INLINE idSphere &idSphere::ExpandSelf( const float d ) { + radius += d; + return *this; +} + +ID_INLINE idSphere idSphere::Translate( const idVec3 &translation ) const { + return idSphere( origin + translation, radius ); +} + +ID_INLINE idSphere &idSphere::TranslateSelf( const idVec3 &translation ) { + origin += translation; + return *this; +} + +ID_INLINE bool idSphere::ContainsPoint( const idVec3 &p ) const { + if ( ( p - origin ).LengthSqr() > radius * radius ) { + return false; + } + return true; +} + +ID_INLINE bool idSphere::IntersectsSphere( const idSphere &s ) const { + float r = s.radius + radius; + if ( ( s.origin - origin ).LengthSqr() > r * r ) { + return false; + } + return true; +} + +ID_INLINE void idSphere::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { + origin = point + 0.5f * translation; + radius = idMath::Sqrt( 0.5f * translation.LengthSqr() ); +} + +ID_INLINE void idSphere::FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation ) { + origin = start + sphere.origin + 0.5f * translation; + radius = idMath::Sqrt( 0.5f * translation.LengthSqr() ) + sphere.radius; +} + +ID_INLINE void idSphere::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { + idVec3 end = rotation * point; + origin = ( point + end ) * 0.5f; + radius = idMath::Sqrt( 0.5f * ( end - point ).LengthSqr() ); +} + +ID_INLINE void idSphere::FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation ) { + idVec3 end = rotation * sphere.origin; + origin = start + ( sphere.origin + end ) * 0.5f; + radius = idMath::Sqrt( 0.5f * ( end - sphere.origin ).LengthSqr() ) + sphere.radius; +} + +ID_INLINE void idSphere::AxisProjection( const idVec3 &dir, float &min, float &max ) const { + float d; + d = dir * origin; + min = d - radius; + max = d + radius; +} + +#endif /* !__BV_SPHERE_H__ */ diff --git a/idlib/bv/bounds.cpp b/idlib/bv/bounds.cpp deleted file mode 100644 index 8d6f4766f..000000000 --- a/idlib/bv/bounds.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idBounds bounds_zero( vec3_zero, vec3_zero ); - -/* -============ -idBounds::GetRadius -============ -*/ -float idBounds::GetRadius( void ) const { - int i; - float total, b0, b1; - - total = 0.0f; - for ( i = 0; i < 3; i++ ) { - b0 = (float)idMath::Fabs( b[0][i] ); - b1 = (float)idMath::Fabs( b[1][i] ); - if ( b0 > b1 ) { - total += b0 * b0; - } else { - total += b1 * b1; - } - } - return idMath::Sqrt( total ); -} - -/* -============ -idBounds::GetRadius -============ -*/ -float idBounds::GetRadius( const idVec3 ¢er ) const { - int i; - float total, b0, b1; - - total = 0.0f; - for ( i = 0; i < 3; i++ ) { - b0 = (float)idMath::Fabs( center[i] - b[0][i] ); - b1 = (float)idMath::Fabs( b[1][i] - center[i] ); - if ( b0 > b1 ) { - total += b0 * b0; - } else { - total += b1 * b1; - } - } - return idMath::Sqrt( total ); -} - -/* -================ -idBounds::PlaneDistance -================ -*/ -float idBounds::PlaneDistance( const idPlane &plane ) const { - idVec3 center; - float d1, d2; - - center = ( b[0] + b[1] ) * 0.5f; - - d1 = plane.Distance( center ); - d2 = idMath::Fabs( ( b[1][0] - center[0] ) * plane.Normal()[0] ) + - idMath::Fabs( ( b[1][1] - center[1] ) * plane.Normal()[1] ) + - idMath::Fabs( ( b[1][2] - center[2] ) * plane.Normal()[2] ); - - if ( d1 - d2 > 0.0f ) { - return d1 - d2; - } - if ( d1 + d2 < 0.0f ) { - return d1 + d2; - } - return 0.0f; -} - -/* -================ -idBounds::PlaneSide -================ -*/ -int idBounds::PlaneSide( const idPlane &plane, const float epsilon ) const { - idVec3 center; - float d1, d2; - - center = ( b[0] + b[1] ) * 0.5f; - - d1 = plane.Distance( center ); - d2 = idMath::Fabs( ( b[1][0] - center[0] ) * plane.Normal()[0] ) + - idMath::Fabs( ( b[1][1] - center[1] ) * plane.Normal()[1] ) + - idMath::Fabs( ( b[1][2] - center[2] ) * plane.Normal()[2] ); - - if ( d1 - d2 > epsilon ) { - return PLANESIDE_FRONT; - } - if ( d1 + d2 < -epsilon ) { - return PLANESIDE_BACK; - } - return PLANESIDE_CROSS; -} - -/* -============ -idBounds::LineIntersection - - Returns true if the line intersects the bounds between the start and end point. -============ -*/ -bool idBounds::LineIntersection( const idVec3 &start, const idVec3 &end ) const { - float ld[3]; - idVec3 center = ( b[0] + b[1] ) * 0.5f; - idVec3 extents = b[1] - center; - idVec3 lineDir = 0.5f * ( end - start ); - idVec3 lineCenter = start + lineDir; - idVec3 dir = lineCenter - center; - - ld[0] = idMath::Fabs( lineDir[0] ); - if ( idMath::Fabs( dir[0] ) > extents[0] + ld[0] ) { - return false; - } - - ld[1] = idMath::Fabs( lineDir[1] ); - if ( idMath::Fabs( dir[1] ) > extents[1] + ld[1] ) { - return false; - } - - ld[2] = idMath::Fabs( lineDir[2] ); - if ( idMath::Fabs( dir[2] ) > extents[2] + ld[2] ) { - return false; - } - - idVec3 cross = lineDir.Cross( dir ); - - if ( idMath::Fabs( cross[0] ) > extents[1] * ld[2] + extents[2] * ld[1] ) { - return false; - } - - if ( idMath::Fabs( cross[1] ) > extents[0] * ld[2] + extents[2] * ld[0] ) { - return false; - } - - if ( idMath::Fabs( cross[2] ) > extents[0] * ld[1] + extents[1] * ld[0] ) { - return false; - } - - return true; -} - -/* -============ -idBounds::RayIntersection - - Returns true if the ray intersects the bounds. - The ray can intersect the bounds in both directions from the start point. - If start is inside the bounds it is considered an intersection with scale = 0 -============ -*/ -bool idBounds::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const { - int i, ax0, ax1, ax2, side, inside; - float f; - idVec3 hit; - - ax0 = -1; - inside = 0; - for ( i = 0; i < 3; i++ ) { - if ( start[i] < b[0][i] ) { - side = 0; - } - else if ( start[i] > b[1][i] ) { - side = 1; - } - else { - inside++; - continue; - } - if ( dir[i] == 0.0f ) { - continue; - } - f = ( start[i] - b[side][i] ); - if ( ax0 < 0 || idMath::Fabs( f ) > idMath::Fabs( scale * dir[i] ) ) { - scale = - ( f / dir[i] ); - ax0 = i; - } - } - - if ( ax0 < 0 ) { - scale = 0.0f; - // return true if the start point is inside the bounds - return ( inside == 3 ); - } - - ax1 = (ax0+1)%3; - ax2 = (ax0+2)%3; - hit[ax1] = start[ax1] + scale * dir[ax1]; - hit[ax2] = start[ax2] + scale * dir[ax2]; - - return ( hit[ax1] >= b[0][ax1] && hit[ax1] <= b[1][ax1] && - hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] ); -} - -/* -============ -idBounds::FromTransformedBounds -============ -*/ -void idBounds::FromTransformedBounds( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) { - int i; - idVec3 center, extents, rotatedExtents; - - center = (bounds[0] + bounds[1]) * 0.5f; - extents = bounds[1] - center; - - for ( i = 0; i < 3; i++ ) { - rotatedExtents[i] = idMath::Fabs( extents[0] * axis[0][i] ) + - idMath::Fabs( extents[1] * axis[1][i] ) + - idMath::Fabs( extents[2] * axis[2][i] ); - } - - center = origin + center * axis; - b[0] = center - rotatedExtents; - b[1] = center + rotatedExtents; -} - -/* -============ -idBounds::FromPoints - - Most tight bounds for a point set. -============ -*/ -void idBounds::FromPoints( const idVec3 *points, const int numPoints ) { - SIMDProcessor->MinMax( b[0], b[1], points, numPoints ); -} - -/* -============ -idBounds::FromPointTranslation - - Most tight bounds for the translational movement of the given point. -============ -*/ -void idBounds::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { - int i; - - for ( i = 0; i < 3; i++ ) { - if ( translation[i] < 0.0f ) { - b[0][i] = point[i] + translation[i]; - b[1][i] = point[i]; - } - else { - b[0][i] = point[i]; - b[1][i] = point[i] + translation[i]; - } - } -} - -/* -============ -idBounds::FromBoundsTranslation - - Most tight bounds for the translational movement of the given bounds. -============ -*/ -void idBounds::FromBoundsTranslation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation ) { - int i; - - if ( axis.IsRotated() ) { - FromTransformedBounds( bounds, origin, axis ); - } - else { - b[0] = bounds[0] + origin; - b[1] = bounds[1] + origin; - } - for ( i = 0; i < 3; i++ ) { - if ( translation[i] < 0.0f ) { - b[0][i] += translation[i]; - } - else { - b[1][i] += translation[i]; - } - } -} - -/* -================ -BoundsForPointRotation - - only for rotations < 180 degrees -================ -*/ -idBounds BoundsForPointRotation( const idVec3 &start, const idRotation &rotation ) { - int i; - float radiusSqr; - idVec3 v1, v2; - idVec3 origin, axis, end; - idBounds bounds; - - end = start * rotation; - axis = rotation.GetVec(); - origin = rotation.GetOrigin() + axis * ( axis * ( start - rotation.GetOrigin() ) ); - radiusSqr = ( start - origin ).LengthSqr(); - v1 = ( start - origin ).Cross( axis ); - v2 = ( end - origin ).Cross( axis ); - - for ( i = 0; i < 3; i++ ) { - // if the derivative changes sign along this axis during the rotation from start to end - if ( ( v1[i] > 0.0f && v2[i] < 0.0f ) || ( v1[i] < 0.0f && v2[i] > 0.0f ) ) { - if ( ( 0.5f * (start[i] + end[i]) - origin[i] ) > 0.0f ) { - bounds[0][i] = Min( start[i], end[i] ); - bounds[1][i] = origin[i] + idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); - } - else { - bounds[0][i] = origin[i] - idMath::Sqrt( radiusSqr * ( 1.0f - axis[i] * axis[i] ) ); - bounds[1][i] = Max( start[i], end[i] ); - } - } - else if ( start[i] > end[i] ) { - bounds[0][i] = end[i]; - bounds[1][i] = start[i]; - } - else { - bounds[0][i] = start[i]; - bounds[1][i] = end[i]; - } - } - - return bounds; -} - -/* -============ -idBounds::FromPointRotation - - Most tight bounds for the rotational movement of the given point. -============ -*/ -void idBounds::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { - float radius; - - if ( idMath::Fabs( rotation.GetAngle() ) < 180.0f ) { - (*this) = BoundsForPointRotation( point, rotation ); - } - else { - - radius = ( point - rotation.GetOrigin() ).Length(); - - // FIXME: these bounds are usually way larger - b[0].Set( -radius, -radius, -radius ); - b[1].Set( radius, radius, radius ); - } -} - -/* -============ -idBounds::FromBoundsRotation - - Most tight bounds for the rotational movement of the given bounds. -============ -*/ -void idBounds::FromBoundsRotation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation ) { - int i; - float radius; - idVec3 point; - idBounds rBounds; - - if ( idMath::Fabs( rotation.GetAngle() ) < 180.0f ) { - - (*this) = BoundsForPointRotation( bounds[0] * axis + origin, rotation ); - for ( i = 1; i < 8; i++ ) { - point[0] = bounds[(i^(i>>1))&1][0]; - point[1] = bounds[(i>>1)&1][1]; - point[2] = bounds[(i>>2)&1][2]; - (*this) += BoundsForPointRotation( point * axis + origin, rotation ); - } - } - else { - - point = (bounds[1] - bounds[0]) * 0.5f; - radius = (bounds[1] - point).Length() + (point - rotation.GetOrigin()).Length(); - - // FIXME: these bounds are usually way larger - b[0].Set( -radius, -radius, -radius ); - b[1].Set( radius, radius, radius ); - } -} - -/* -============ -idBounds::ToPoints -============ -*/ -void idBounds::ToPoints( idVec3 points[8] ) const { - for ( int i = 0; i < 8; i++ ) { - points[i][0] = b[(i^(i>>1))&1][0]; - points[i][1] = b[(i>>1)&1][1]; - points[i][2] = b[(i>>2)&1][2]; - } -} - -/* -============ -idBounds::ToString -============ -*/ -const char * idBounds::ToString( const int precision ) const { - return idStr( b[0].ToString( precision ) ) + " -> " + idStr( b[1].ToString( precision ) ); -} - diff --git a/idlib/bv/bounds.h b/idlib/bv/bounds.h deleted file mode 100644 index 6391bbc7a..000000000 --- a/idlib/bv/bounds.h +++ /dev/null @@ -1,442 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BV_BOUNDS_H__ -#define __BV_BOUNDS_H__ - -/* -=============================================================================== - - Axis Aligned Bounding Box - -=============================================================================== -*/ - -class idBounds { -public: - idBounds( void ); - explicit idBounds( const idVec3 &mins, const idVec3 &maxs ); - explicit idBounds( const idVec3 &point ); - - const idVec3 & operator[]( const int index ) const; - idVec3 & operator[]( const int index ); - idBounds operator+( const idVec3 &t ) const; // returns translated bounds - idBounds & operator+=( const idVec3 &t ); // translate the bounds - idBounds operator*( const idMat3 &r ) const; // returns rotated bounds - idBounds & operator*=( const idMat3 &r ); // rotate the bounds - idBounds operator+( const idBounds &a ) const; - idBounds & operator+=( const idBounds &a ); - idBounds operator-( const idBounds &a ) const; - idBounds & operator-=( const idBounds &a ); - - bool Compare( const idBounds &a ) const; // exact compare, no epsilon - bool Compare( const idBounds &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idBounds &a ) const; // exact compare, no epsilon - bool operator!=( const idBounds &a ) const; // exact compare, no epsilon - - void Clear( void ); // inside out bounds - void Zero( void ); // single point at origin - - idVec3 GetCenter( void ) const; // returns center of bounds - float GetRadius( void ) const; // returns the radius relative to the bounds origin - // greebo: Note that this does NOT return 0.0 for a - // idBounds object with b[0] == b[1] as one might suspect. - // I don't know what the intention for this code is, so I'll leave it. - // Use GetVolume() instead. - float GetRadius( const idVec3 ¢er ) const; // returns the radius relative to the given center - float GetVolume( void ) const; // returns the volume of the bounds - - /** - * Tels: Get the size of the bounds, that is b1 - b0 - */ - idVec3 GetSize( void ) const; - - bool IsCleared( void ) const; // returns true if bounds are inside out - - bool AddPoint( const idVec3 &v ); // add the point, returns true if the bounds expanded - bool AddBounds( const idBounds &a ); // add the bounds, returns true if the bounds expanded - idBounds Intersect( const idBounds &a ) const; // return intersection of this bounds with the given bounds - idBounds & IntersectSelf( const idBounds &a ); // intersect this bounds with the given bounds - idBounds Expand( const float d ) const; // return bounds expanded in all directions with the given value - idBounds & ExpandSelf( const float d ); // expand bounds in all directions with the given value - idBounds Translate( const idVec3 &translation ) const; // return translated bounds - idBounds & TranslateSelf( const idVec3 &translation ); // translate this bounds - idBounds Rotate( const idMat3 &rotation ) const; // return rotated bounds - idBounds & RotateSelf( const idMat3 &rotation ); // rotate this bounds - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - bool ContainsPoint( const idVec3 &p ) const; // includes touching - bool IntersectsBounds( const idBounds &a ) const; // includes touching - bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; - // intersection point is start + dir * scale - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const; - - // most tight bounds for the given transformed bounds - void FromTransformedBounds( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ); - // most tight bounds for a point set - void FromPoints( const idVec3 *points, const int numPoints ); - // most tight bounds for a translation - void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); - void FromBoundsTranslation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation ); - // most tight bounds for a rotation - void FromPointRotation( const idVec3 &point, const idRotation &rotation ); - void FromBoundsRotation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation ); - - void ToPoints( idVec3 points[8] ) const; - idSphere ToSphere( void ) const; - - const char * ToString( const int precision = 2 ) const; - - void AxisProjection( const idVec3 &dir, float &min, float &max ) const; - void AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const; - -private: - idVec3 b[2]; -}; - -extern idBounds bounds_zero; - -ID_INLINE idBounds::idBounds( void ) { -} - -ID_INLINE idBounds::idBounds( const idVec3 &mins, const idVec3 &maxs ) { - b[0] = mins; - b[1] = maxs; -} - -ID_INLINE idBounds::idBounds( const idVec3 &point ) { - b[0] = point; - b[1] = point; -} - -ID_INLINE const idVec3 &idBounds::operator[]( const int index ) const { - return b[index]; -} - -ID_INLINE idVec3 &idBounds::operator[]( const int index ) { - return b[index]; -} - -ID_INLINE idBounds idBounds::operator+( const idVec3 &t ) const { - return idBounds( b[0] + t, b[1] + t ); -} - -ID_INLINE idBounds &idBounds::operator+=( const idVec3 &t ) { - b[0] += t; - b[1] += t; - return *this; -} - -ID_INLINE idBounds idBounds::operator*( const idMat3 &r ) const { - idBounds bounds; - bounds.FromTransformedBounds( *this, vec3_origin, r ); - return bounds; -} - -ID_INLINE idBounds &idBounds::operator*=( const idMat3 &r ) { - this->FromTransformedBounds( *this, vec3_origin, r ); - return *this; -} - -ID_INLINE idBounds idBounds::operator+( const idBounds &a ) const { - idBounds newBounds; - newBounds = *this; - newBounds.AddBounds( a ); - return newBounds; -} - -ID_INLINE idBounds &idBounds::operator+=( const idBounds &a ) { - idBounds::AddBounds( a ); - return *this; -} - -ID_INLINE idBounds idBounds::operator-( const idBounds &a ) const { - assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] && - b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] && - b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] ); - return idBounds( idVec3( b[0][0] + a.b[1][0], b[0][1] + a.b[1][1], b[0][2] + a.b[1][2] ), - idVec3( b[1][0] + a.b[0][0], b[1][1] + a.b[0][1], b[1][2] + a.b[0][2] ) ); -} - -ID_INLINE idBounds &idBounds::operator-=( const idBounds &a ) { - assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] && - b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] && - b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] ); - b[0] += a.b[1]; - b[1] += a.b[0]; - return *this; -} - -ID_INLINE bool idBounds::Compare( const idBounds &a ) const { - return ( b[0].Compare( a.b[0] ) && b[1].Compare( a.b[1] ) ); -} - -ID_INLINE bool idBounds::Compare( const idBounds &a, const float epsilon ) const { - return ( b[0].Compare( a.b[0], epsilon ) && b[1].Compare( a.b[1], epsilon ) ); -} - -ID_INLINE bool idBounds::operator==( const idBounds &a ) const { - return Compare( a ); -} - -ID_INLINE bool idBounds::operator!=( const idBounds &a ) const { - return !Compare( a ); -} - -ID_INLINE void idBounds::Clear( void ) { - b[0][0] = b[0][1] = b[0][2] = idMath::INFINITY; - b[1][0] = b[1][1] = b[1][2] = -idMath::INFINITY; -} - -ID_INLINE void idBounds::Zero( void ) { - b[0][0] = b[0][1] = b[0][2] = - b[1][0] = b[1][1] = b[1][2] = 0; -} - -ID_INLINE idVec3 idBounds::GetCenter( void ) const { - return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f ); -} - -ID_INLINE float idBounds::GetVolume( void ) const { - if ( b[0][0] >= b[1][0] || b[0][1] >= b[1][1] || b[0][2] >= b[1][2] ) { - return 0.0f; - } - return ( ( b[1][0] - b[0][0] ) * ( b[1][1] - b[0][1] ) * ( b[1][2] - b[0][2] ) ); -} - -/** -* Tels: Get the size of the bounds, that is b1 - b0 -*/ -ID_INLINE idVec3 idBounds::GetSize( void ) const { - return idVec3( b[1][0] - b[0][0], b[1][1] - b[0][1], b[1][2] - b[0][2] ); -} - -ID_INLINE bool idBounds::IsCleared( void ) const { - return b[0][0] > b[1][0]; -} - -ID_INLINE bool idBounds::AddPoint( const idVec3 &v ) { - bool expanded = false; - if ( v[0] < b[0][0]) { - b[0][0] = v[0]; - expanded = true; - } - if ( v[0] > b[1][0]) { - b[1][0] = v[0]; - expanded = true; - } - if ( v[1] < b[0][1] ) { - b[0][1] = v[1]; - expanded = true; - } - if ( v[1] > b[1][1]) { - b[1][1] = v[1]; - expanded = true; - } - if ( v[2] < b[0][2] ) { - b[0][2] = v[2]; - expanded = true; - } - if ( v[2] > b[1][2]) { - b[1][2] = v[2]; - expanded = true; - } - return expanded; -} - -ID_INLINE bool idBounds::AddBounds( const idBounds &a ) { - bool expanded = false; - if ( a.b[0][0] < b[0][0] ) { - b[0][0] = a.b[0][0]; - expanded = true; - } - if ( a.b[0][1] < b[0][1] ) { - b[0][1] = a.b[0][1]; - expanded = true; - } - if ( a.b[0][2] < b[0][2] ) { - b[0][2] = a.b[0][2]; - expanded = true; - } - if ( a.b[1][0] > b[1][0] ) { - b[1][0] = a.b[1][0]; - expanded = true; - } - if ( a.b[1][1] > b[1][1] ) { - b[1][1] = a.b[1][1]; - expanded = true; - } - if ( a.b[1][2] > b[1][2] ) { - b[1][2] = a.b[1][2]; - expanded = true; - } - return expanded; -} - -ID_INLINE idBounds idBounds::Intersect( const idBounds &a ) const { - idBounds n; - - // grayman #2734 - Check for intersecting first. Note that if there's - // no intersection, a bounds with zero min/max points is returned, so - // if that matters, you should check for that at the spot where this - // is called. - - n.Zero(); - if (IntersectsBounds(a)) - { - n.b[0][0] = ( a.b[0][0] > b[0][0] ) ? a.b[0][0] : b[0][0]; - n.b[0][1] = ( a.b[0][1] > b[0][1] ) ? a.b[0][1] : b[0][1]; - n.b[0][2] = ( a.b[0][2] > b[0][2] ) ? a.b[0][2] : b[0][2]; - n.b[1][0] = ( a.b[1][0] < b[1][0] ) ? a.b[1][0] : b[1][0]; - n.b[1][1] = ( a.b[1][1] < b[1][1] ) ? a.b[1][1] : b[1][1]; - n.b[1][2] = ( a.b[1][2] < b[1][2] ) ? a.b[1][2] : b[1][2]; - } - return n; -} - -ID_INLINE idBounds &idBounds::IntersectSelf( const idBounds &a ) { - - // grayman #2734 - Check for intersecting first. Note that if there's - // no intersection, "this" bounds' max point is set to the min point, so - // if that matters, you should check for that at the spot where this - // is called. As of this writing, IntersectSelf() isn't used anywhere. - - if (IntersectsBounds(a)) - { - if ( a.b[0][0] > b[0][0] ) - { - b[0][0] = a.b[0][0]; - } - if ( a.b[0][1] > b[0][1] ) - { - b[0][1] = a.b[0][1]; - } - if ( a.b[0][2] > b[0][2] ) - { - b[0][2] = a.b[0][2]; - } - if ( a.b[1][0] < b[1][0] ) - { - b[1][0] = a.b[1][0]; - } - if ( a.b[1][1] < b[1][1] ) - { - b[1][1] = a.b[1][1]; - } - if ( a.b[1][2] < b[1][2] ) - { - b[1][2] = a.b[1][2]; - } - } - else - { - b[1] = b[0]; // no intersection, so collapse the bounds - } - - return *this; -} - -ID_INLINE idBounds idBounds::Expand( const float d ) const { - return idBounds( idVec3( b[0][0] - d, b[0][1] - d, b[0][2] - d ), - idVec3( b[1][0] + d, b[1][1] + d, b[1][2] + d ) ); -} - -ID_INLINE idBounds &idBounds::ExpandSelf( const float d ) { - b[0][0] -= d; - b[0][1] -= d; - b[0][2] -= d; - b[1][0] += d; - b[1][1] += d; - b[1][2] += d; - return *this; -} - -ID_INLINE idBounds idBounds::Translate( const idVec3 &translation ) const { - return idBounds( b[0] + translation, b[1] + translation ); -} - -ID_INLINE idBounds &idBounds::TranslateSelf( const idVec3 &translation ) { - b[0] += translation; - b[1] += translation; - return *this; -} - -ID_INLINE idBounds idBounds::Rotate( const idMat3 &rotation ) const { - idBounds bounds; - bounds.FromTransformedBounds( *this, vec3_origin, rotation ); - return bounds; -} - -ID_INLINE idBounds &idBounds::RotateSelf( const idMat3 &rotation ) { - FromTransformedBounds( *this, vec3_origin, rotation ); - return *this; -} - -ID_INLINE bool idBounds::ContainsPoint( const idVec3 &p ) const { - if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] - || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE bool idBounds::IntersectsBounds( const idBounds &a ) const { - if ( a.b[1][0] < b[0][0] || a.b[1][1] < b[0][1] || a.b[1][2] < b[0][2] - || a.b[0][0] > b[1][0] || a.b[0][1] > b[1][1] || a.b[0][2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE idSphere idBounds::ToSphere( void ) const { - idSphere sphere; - sphere.SetOrigin( ( b[0] + b[1] ) * 0.5f ); - sphere.SetRadius( ( b[1] - sphere.GetOrigin() ).Length() ); - return sphere; -} - -ID_INLINE void idBounds::AxisProjection( const idVec3 &dir, float &min, float &max ) const { - float d1, d2; - idVec3 center, extents; - - center = ( b[0] + b[1] ) * 0.5f; - extents = b[1] - center; - - d1 = dir * center; - d2 = idMath::Fabs( extents[0] * dir[0] ) + - idMath::Fabs( extents[1] * dir[1] ) + - idMath::Fabs( extents[2] * dir[2] ); - - min = d1 - d2; - max = d1 + d2; -} - -ID_INLINE void idBounds::AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const { - float d1, d2; - idVec3 center, extents; - - center = ( b[0] + b[1] ) * 0.5f; - extents = b[1] - center; - center = origin + center * axis; - - d1 = dir * center; - d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) + - idMath::Fabs( extents[1] * ( dir * axis[1] ) ) + - idMath::Fabs( extents[2] * ( dir * axis[2] ) ); - - min = d1 - d2; - max = d1 + d2; -} - -#endif /* !__BV_BOUNDS_H__ */ diff --git a/idlib/bv/box.cpp b/idlib/bv/box.cpp deleted file mode 100644 index a72893627..000000000 --- a/idlib/bv/box.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idBox box_zero( vec3_zero, vec3_zero, mat3_identity ); - -/* - 4---{4}---5 - + /| /| - Z {7} {8} {5} | - - / | / {9} - 7--{6}----6 | - | | | | - {11} 0---|-{0}-1 - | / | / - - | {3} {10} {1} Y - |/ |/ + - 3---{2}---2 - - - X + - - plane bits: - 0 = min x - 1 = max x - 2 = min y - 3 = max y - 4 = min z - 5 = max z - -*/ - -static int boxVertPlanes[8] = { - ( (1<<0) | (1<<2) | (1<<4) ), - ( (1<<1) | (1<<2) | (1<<4) ), - ( (1<<1) | (1<<3) | (1<<4) ), - ( (1<<0) | (1<<3) | (1<<4) ), - ( (1<<0) | (1<<2) | (1<<5) ), - ( (1<<1) | (1<<2) | (1<<5) ), - ( (1<<1) | (1<<3) | (1<<5) ), - ( (1<<0) | (1<<3) | (1<<5) ) -}; - -static int boxVertEdges[8][3] = { - // bottom - { 3, 0, 8 }, - { 0, 1, 9 }, - { 1, 2, 10 }, - { 2, 3, 11 }, - // top - { 7, 4, 8 }, - { 4, 5, 9 }, - { 5, 6, 10 }, - { 6, 7, 11 } -}; - -static int boxEdgePlanes[12][2] = { - // bottom - { 4, 2 }, - { 4, 1 }, - { 4, 3 }, - { 4, 0 }, - // top - { 5, 2 }, - { 5, 1 }, - { 5, 3 }, - { 5, 0 }, - // sides - { 0, 2 }, - { 2, 1 }, - { 1, 3 }, - { 3, 0 } -}; - -static int boxEdgeVerts[12][2] = { - // bottom - { 0, 1 }, - { 1, 2 }, - { 2, 3 }, - { 3, 0 }, - // top - { 4, 5 }, - { 5, 6 }, - { 6, 7 }, - { 7, 4 }, - // sides - { 0, 4 }, - { 1, 5 }, - { 2, 6 }, - { 3, 7 } -}; - -static int boxPlaneBitsSilVerts[64][7] = { - { 0, 0, 0, 0, 0, 0, 0 }, // 000000 = 0 - { 4, 7, 4, 0, 3, 0, 0 }, // 000001 = 1 - { 4, 5, 6, 2, 1, 0, 0 }, // 000010 = 2 - { 0, 0, 0, 0, 0, 0, 0 }, // 000011 = 3 - { 4, 4, 5, 1, 0, 0, 0 }, // 000100 = 4 - { 6, 3, 7, 4, 5, 1, 0 }, // 000101 = 5 - { 6, 4, 5, 6, 2, 1, 0 }, // 000110 = 6 - { 0, 0, 0, 0, 0, 0, 0 }, // 000111 = 7 - { 4, 6, 7, 3, 2, 0, 0 }, // 001000 = 8 - { 6, 6, 7, 4, 0, 3, 2 }, // 001001 = 9 - { 6, 5, 6, 7, 3, 2, 1 }, // 001010 = 10 - { 0, 0, 0, 0, 0, 0, 0 }, // 001011 = 11 - { 0, 0, 0, 0, 0, 0, 0 }, // 001100 = 12 - { 0, 0, 0, 0, 0, 0, 0 }, // 001101 = 13 - { 0, 0, 0, 0, 0, 0, 0 }, // 001110 = 14 - { 0, 0, 0, 0, 0, 0, 0 }, // 001111 = 15 - { 4, 0, 1, 2, 3, 0, 0 }, // 010000 = 16 - { 6, 0, 1, 2, 3, 7, 4 }, // 010001 = 17 - { 6, 3, 2, 6, 5, 1, 0 }, // 010010 = 18 - { 0, 0, 0, 0, 0, 0, 0 }, // 010011 = 19 - { 6, 1, 2, 3, 0, 4, 5 }, // 010100 = 20 - { 6, 1, 2, 3, 7, 4, 5 }, // 010101 = 21 - { 6, 2, 3, 0, 4, 5, 6 }, // 010110 = 22 - { 0, 0, 0, 0, 0, 0, 0 }, // 010111 = 23 - { 6, 0, 1, 2, 6, 7, 3 }, // 011000 = 24 - { 6, 0, 1, 2, 6, 7, 4 }, // 011001 = 25 - { 6, 0, 1, 5, 6, 7, 3 }, // 011010 = 26 - { 0, 0, 0, 0, 0, 0, 0 }, // 011011 = 27 - { 0, 0, 0, 0, 0, 0, 0 }, // 011100 = 28 - { 0, 0, 0, 0, 0, 0, 0 }, // 011101 = 29 - { 0, 0, 0, 0, 0, 0, 0 }, // 011110 = 30 - { 0, 0, 0, 0, 0, 0, 0 }, // 011111 = 31 - { 4, 7, 6, 5, 4, 0, 0 }, // 100000 = 32 - { 6, 7, 6, 5, 4, 0, 3 }, // 100001 = 33 - { 6, 5, 4, 7, 6, 2, 1 }, // 100010 = 34 - { 0, 0, 0, 0, 0, 0, 0 }, // 100011 = 35 - { 6, 4, 7, 6, 5, 1, 0 }, // 100100 = 36 - { 6, 3, 7, 6, 5, 1, 0 }, // 100101 = 37 - { 6, 4, 7, 6, 2, 1, 0 }, // 100110 = 38 - { 0, 0, 0, 0, 0, 0, 0 }, // 100111 = 39 - { 6, 6, 5, 4, 7, 3, 2 }, // 101000 = 40 - { 6, 6, 5, 4, 0, 3, 2 }, // 101001 = 41 - { 6, 5, 4, 7, 3, 2, 1 }, // 101010 = 42 - { 0, 0, 0, 0, 0, 0, 0 }, // 101011 = 43 - { 0, 0, 0, 0, 0, 0, 0 }, // 101100 = 44 - { 0, 0, 0, 0, 0, 0, 0 }, // 101101 = 45 - { 0, 0, 0, 0, 0, 0, 0 }, // 101110 = 46 - { 0, 0, 0, 0, 0, 0, 0 }, // 101111 = 47 - { 0, 0, 0, 0, 0, 0, 0 }, // 110000 = 48 - { 0, 0, 0, 0, 0, 0, 0 }, // 110001 = 49 - { 0, 0, 0, 0, 0, 0, 0 }, // 110010 = 50 - { 0, 0, 0, 0, 0, 0, 0 }, // 110011 = 51 - { 0, 0, 0, 0, 0, 0, 0 }, // 110100 = 52 - { 0, 0, 0, 0, 0, 0, 0 }, // 110101 = 53 - { 0, 0, 0, 0, 0, 0, 0 }, // 110110 = 54 - { 0, 0, 0, 0, 0, 0, 0 }, // 110111 = 55 - { 0, 0, 0, 0, 0, 0, 0 }, // 111000 = 56 - { 0, 0, 0, 0, 0, 0, 0 }, // 111001 = 57 - { 0, 0, 0, 0, 0, 0, 0 }, // 111010 = 58 - { 0, 0, 0, 0, 0, 0, 0 }, // 111011 = 59 - { 0, 0, 0, 0, 0, 0, 0 }, // 111100 = 60 - { 0, 0, 0, 0, 0, 0, 0 }, // 111101 = 61 - { 0, 0, 0, 0, 0, 0, 0 }, // 111110 = 62 - { 0, 0, 0, 0, 0, 0, 0 }, // 111111 = 63 -}; - - -/* -============ -idBox::AddPoint -============ -*/ -bool idBox::AddPoint( const idVec3 &v ) { - idMat3 axis2; - idBounds bounds1, bounds2; - - if ( extents[0] < 0.0f ) { - extents.Zero(); - center = v; - axis.Identity(); - return true; - } - - bounds1[0][0] = bounds1[1][0] = center * axis[0]; - bounds1[0][1] = bounds1[1][1] = center * axis[1]; - bounds1[0][2] = bounds1[1][2] = center * axis[2]; - bounds1[0] -= extents; - bounds1[1] += extents; - if ( !bounds1.AddPoint( idVec3( v * axis[0], v * axis[1], v * axis[2] ) ) ) { - // point is contained in the box - return false; - } - - axis2[0] = v - center; - axis2[0].Normalize(); - axis2[1] = axis[ Min3Index( axis2[0] * axis[0], axis2[0] * axis[1], axis2[0] * axis[2] ) ]; - axis2[1] = axis2[1] - ( axis2[1] * axis2[0] ) * axis2[0]; - axis2[1].Normalize(); - axis2[2].Cross( axis2[0], axis2[1] ); - - AxisProjection( axis2, bounds2 ); - bounds2.AddPoint( idVec3( v * axis2[0], v * axis2[1], v * axis2[2] ) ); - - // create new box based on the smallest bounds - if ( bounds1.GetVolume() < bounds2.GetVolume() ) { - center = ( bounds1[0] + bounds1[1] ) * 0.5f; - extents = bounds1[1] - center; - center *= axis; - } - else { - center = ( bounds2[0] + bounds2[1] ) * 0.5f; - extents = bounds2[1] - center; - center *= axis2; - axis = axis2; - } - return true; -} - -/* -============ -idBox::AddBox -============ -*/ -bool idBox::AddBox( const idBox &a ) { - int i, besti; - float v, bestv; - idVec3 dir; - idMat3 ax[4]; - idBounds bounds[4], b; - - if ( a.extents[0] < 0.0f ) { - return false; - } - - if ( extents[0] < 0.0f ) { - center = a.center; - extents = a.extents; - axis = a.axis; - return true; - } - - // test axis of this box - ax[0] = axis; - bounds[0][0][0] = bounds[0][1][0] = center * ax[0][0]; - bounds[0][0][1] = bounds[0][1][1] = center * ax[0][1]; - bounds[0][0][2] = bounds[0][1][2] = center * ax[0][2]; - bounds[0][0] -= extents; - bounds[0][1] += extents; - a.AxisProjection( ax[0], b ); - if ( !bounds[0].AddBounds( b ) ) { - // the other box is contained in this box - return false; - } - - // test axis of other box - ax[1] = a.axis; - bounds[1][0][0] = bounds[1][1][0] = a.center * ax[1][0]; - bounds[1][0][1] = bounds[1][1][1] = a.center * ax[1][1]; - bounds[1][0][2] = bounds[1][1][2] = a.center * ax[1][2]; - bounds[1][0] -= a.extents; - bounds[1][1] += a.extents; - AxisProjection( ax[1], b ); - if ( !bounds[1].AddBounds( b ) ) { - // this box is contained in the other box - center = a.center; - extents = a.extents; - axis = a.axis; - return true; - } - - // test axes aligned with the vector between the box centers and one of the box axis - dir = a.center - center; - dir.Normalize(); - for ( i = 2; i < 4; i++ ) { - ax[i][0] = dir; - ax[i][1] = ax[i-2][ Min3Index( dir * ax[i-2][0], dir * ax[i-2][1], dir * ax[i-2][2] ) ]; - ax[i][1] = ax[i][1] - ( ax[i][1] * dir ) * dir; - ax[i][1].Normalize(); - ax[i][2].Cross( dir, ax[i][1] ); - - AxisProjection( ax[i], bounds[i] ); - a.AxisProjection( ax[i], b ); - bounds[i].AddBounds( b ); - } - - // get the bounds with the smallest volume - bestv = idMath::INFINITY; - besti = 0; - for ( i = 0; i < 4; i++ ) { - v = bounds[i].GetVolume(); - if ( v < bestv ) { - bestv = v; - besti = i; - } - } - - // create a box from the smallest bounds axis pair - center = ( bounds[besti][0] + bounds[besti][1] ) * 0.5f; - extents = bounds[besti][1] - center; - center *= ax[besti]; - axis = ax[besti]; - - return false; -} - -/* -================ -idBox::PlaneDistance -================ -*/ -float idBox::PlaneDistance( const idPlane &plane ) const { - float d1, d2; - - d1 = plane.Distance( center ); - d2 = idMath::Fabs( extents[0] * plane.Normal()[0] ) + - idMath::Fabs( extents[1] * plane.Normal()[1] ) + - idMath::Fabs( extents[2] * plane.Normal()[2] ); - - if ( d1 - d2 > 0.0f ) { - return d1 - d2; - } - if ( d1 + d2 < 0.0f ) { - return d1 + d2; - } - return 0.0f; -} - -/* -================ -idBox::PlaneSide -================ -*/ -int idBox::PlaneSide( const idPlane &plane, const float epsilon ) const { - float d1, d2; - - d1 = plane.Distance( center ); - d2 = idMath::Fabs( extents[0] * plane.Normal()[0] ) + - idMath::Fabs( extents[1] * plane.Normal()[1] ) + - idMath::Fabs( extents[2] * plane.Normal()[2] ); - - if ( d1 - d2 > epsilon ) { - return PLANESIDE_FRONT; - } - if ( d1 + d2 < -epsilon ) { - return PLANESIDE_BACK; - } - return PLANESIDE_CROSS; -} - -/* -============ -idBox::IntersectsBox -============ -*/ -bool idBox::IntersectsBox( const idBox &a ) const { - idVec3 dir; // vector between centers - float c[3][3]; // matrix c = axis.Transpose() * a.axis - float ac[3][3]; // absolute values of c - float axisdir[3]; // axis[i] * dir - float d, e0, e1; // distance between centers and projected extents - - dir = a.center - center; - - // axis C0 + t * A0 - c[0][0] = axis[0] * a.axis[0]; - c[0][1] = axis[0] * a.axis[1]; - c[0][2] = axis[0] * a.axis[2]; - axisdir[0] = axis[0] * dir; - ac[0][0] = idMath::Fabs( c[0][0] ); - ac[0][1] = idMath::Fabs( c[0][1] ); - ac[0][2] = idMath::Fabs( c[0][2] ); - - d = idMath::Fabs( axisdir[0] ); - e0 = extents[0]; - e1 = a.extents[0] * ac[0][0] + a.extents[1] * ac[0][1] + a.extents[2] * ac[0][2]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A1 - c[1][0] = axis[1] * a.axis[0]; - c[1][1] = axis[1] * a.axis[1]; - c[1][2] = axis[1] * a.axis[2]; - axisdir[1] = axis[1] * dir; - ac[1][0] = idMath::Fabs( c[1][0] ); - ac[1][1] = idMath::Fabs( c[1][1] ); - ac[1][2] = idMath::Fabs( c[1][2] ); - - d = idMath::Fabs( axisdir[1] ); - e0 = extents[1]; - e1 = a.extents[0] * ac[1][0] + a.extents[1] * ac[1][1] + a.extents[2] * ac[1][2]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A2 - c[2][0] = axis[2] * a.axis[0]; - c[2][1] = axis[2] * a.axis[1]; - c[2][2] = axis[2] * a.axis[2]; - axisdir[2] = axis[2] * dir; - ac[2][0] = idMath::Fabs( c[2][0] ); - ac[2][1] = idMath::Fabs( c[2][1] ); - ac[2][2] = idMath::Fabs( c[2][2] ); - - d = idMath::Fabs( axisdir[2] ); - e0 = extents[2]; - e1 = a.extents[0] * ac[2][0] + a.extents[1] * ac[2][1] + a.extents[2] * ac[2][2]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * B0 - d = idMath::Fabs( a.axis[0] * dir ); - e0 = extents[0] * ac[0][0] + extents[1] * ac[1][0] + extents[2] * ac[2][0]; - e1 = a.extents[0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * B1 - d = idMath::Fabs( a.axis[1] * dir ); - e0 = extents[0] * ac[0][1] + extents[1] * ac[1][1] + extents[2] * ac[2][1]; - e1 = a.extents[1]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * B2 - d = idMath::Fabs( a.axis[2] * dir ); - e0 = extents[0] * ac[0][2] + extents[1] * ac[1][2] + extents[2] * ac[2][2]; - e1 = a.extents[2]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A0xB0 - d = idMath::Fabs( axisdir[2] * c[1][0] - axisdir[1] * c[2][0] ); - e0 = extents[1] * ac[2][0] + extents[2] * ac[1][0]; - e1 = a.extents[1] * ac[0][2] + a.extents[2] * ac[0][1]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A0xB1 - d = idMath::Fabs( axisdir[2] * c[1][1] - axisdir[1] * c[2][1] ); - e0 = extents[1] * ac[2][1] + extents[2] * ac[1][1]; - e1 = a.extents[0] * ac[0][2] + a.extents[2] * ac[0][0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A0xB2 - d = idMath::Fabs( axisdir[2] * c[1][2] - axisdir[1] * c[2][2] ); - e0 = extents[1] * ac[2][2] + extents[2] * ac[1][2]; - e1 = a.extents[0] * ac[0][1] + a.extents[1] * ac[0][0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A1xB0 - d = idMath::Fabs( axisdir[0] * c[2][0] - axisdir[2] * c[0][0] ); - e0 = extents[0] * ac[2][0] + extents[2] * ac[0][0]; - e1 = a.extents[1] * ac[1][2] + a.extents[2] * ac[1][1]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A1xB1 - d = idMath::Fabs( axisdir[0] * c[2][1] - axisdir[2] * c[0][1] ); - e0 = extents[0] * ac[2][1] + extents[2] * ac[0][1]; - e1 = a.extents[0] * ac[1][2] + a.extents[2] * ac[1][0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A1xB2 - d = idMath::Fabs( axisdir[0] * c[2][2] - axisdir[2] * c[0][2] ); - e0 = extents[0] * ac[2][2] + extents[2] * ac[0][2]; - e1 = a.extents[0] * ac[1][1] + a.extents[1] * ac[1][0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A2xB0 - d = idMath::Fabs( axisdir[1] * c[0][0] - axisdir[0] * c[1][0] ); - e0 = extents[0] * ac[1][0] + extents[1] * ac[0][0]; - e1 = a.extents[1] * ac[2][2] + a.extents[2] * ac[2][1]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A2xB1 - d = idMath::Fabs( axisdir[1] * c[0][1] - axisdir[0] * c[1][1] ); - e0 = extents[0] * ac[1][1] + extents[1] * ac[0][1]; - e1 = a.extents[0] * ac[2][2] + a.extents[2] * ac[2][0]; - if ( d > e0 + e1 ) { - return false; - } - - // axis C0 + t * A2xB2 - d = idMath::Fabs( axisdir[1] * c[0][2] - axisdir[0] * c[1][2] ); - e0 = extents[0] * ac[1][2] + extents[1] * ac[0][2]; - e1 = a.extents[0] * ac[2][1] + a.extents[1] * ac[2][0]; - if ( d > e0 + e1 ) { - return false; - } - return true; -} - -/* -============ -idBox::LineIntersection - - Returns true if the line intersects the box between the start and end point. -============ -*/ -bool idBox::LineIntersection( const idVec3 &start, const idVec3 &end ) const { - float ld[3]; - idVec3 lineDir = 0.5f * ( end - start ); - idVec3 lineCenter = start + lineDir; - idVec3 dir = lineCenter - center; - - ld[0] = idMath::Fabs( lineDir * axis[0] ); - if ( idMath::Fabs( dir * axis[0] ) > extents[0] + ld[0] ) { - return false; - } - - ld[1] = idMath::Fabs( lineDir * axis[1] ); - if ( idMath::Fabs( dir * axis[1] ) > extents[1] + ld[1] ) { - return false; - } - - ld[2] = idMath::Fabs( lineDir * axis[2] ); - if ( idMath::Fabs( dir * axis[2] ) > extents[2] + ld[2] ) { - return false; - } - - idVec3 cross = lineDir.Cross( dir ); - - if ( idMath::Fabs( cross * axis[0] ) > extents[1] * ld[2] + extents[2] * ld[1] ) { - return false; - } - - if ( idMath::Fabs( cross * axis[1] ) > extents[0] * ld[2] + extents[2] * ld[0] ) { - return false; - } - - if ( idMath::Fabs( cross * axis[2] ) > extents[0] * ld[1] + extents[1] * ld[0] ) { - return false; - } - - return true; -} - -/* -============ -BoxPlaneClip -============ -*/ -static bool BoxPlaneClip( const float denom, const float numer, float &scale0, float &scale1 ) { - if ( denom > 0.0f ) { - if ( numer > denom * scale1 ) { - return false; - } - if ( numer > denom * scale0 ) { - scale0 = numer / denom; - } - return true; - } - else if ( denom < 0.0f ) { - if ( numer > denom * scale0 ) { - return false; - } - if ( numer > denom * scale1 ) { - scale1 = numer / denom; - } - return true; - } - else { - return ( numer <= 0.0f ); - } -} - -/* -============ -idBox::RayIntersection - - Returns true if the ray intersects the box. - The ray can intersect the box in both directions from the start point. - If start is inside the box then scale1 < 0 and scale2 > 0. -============ -*/ -bool idBox::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { - idVec3 localStart, localDir; - - localStart = ( start - center ) * axis.Transpose(); - localDir = dir * axis.Transpose(); - - scale1 = -idMath::INFINITY; - scale2 = idMath::INFINITY; - return BoxPlaneClip( localDir.x, -localStart.x - extents[0], scale1, scale2 ) && - BoxPlaneClip( -localDir.x, localStart.x - extents[0], scale1, scale2 ) && - BoxPlaneClip( localDir.y, -localStart.y - extents[1], scale1, scale2 ) && - BoxPlaneClip( -localDir.y, localStart.y - extents[1], scale1, scale2 ) && - BoxPlaneClip( localDir.z, -localStart.z - extents[2], scale1, scale2 ) && - BoxPlaneClip( -localDir.z, localStart.z - extents[2], scale1, scale2 ); -} - -/* -============ -idBox::FromPoints - - Tight box for a collection of points. -============ -*/ -void idBox::FromPoints( const idVec3 *points, const int numPoints ) { - int i; - float invNumPoints, sumXX, sumXY, sumXZ, sumYY, sumYZ, sumZZ; - idVec3 dir; - idBounds bounds; - idMatX eigenVectors; - idVecX eigenValues; - - // compute mean of points - center = points[0]; - for ( i = 1; i < numPoints; i++ ) { - center += points[i]; - } - invNumPoints = 1.0f / numPoints; - center *= invNumPoints; - - // compute covariances of points - sumXX = 0.0f; sumXY = 0.0f; sumXZ = 0.0f; - sumYY = 0.0f; sumYZ = 0.0f; sumZZ = 0.0f; - for ( i = 0; i < numPoints; i++ ) { - dir = points[i] - center; - sumXX += dir.x * dir.x; - sumXY += dir.x * dir.y; - sumXZ += dir.x * dir.z; - sumYY += dir.y * dir.y; - sumYZ += dir.y * dir.z; - sumZZ += dir.z * dir.z; - } - sumXX *= invNumPoints; - sumXY *= invNumPoints; - sumXZ *= invNumPoints; - sumYY *= invNumPoints; - sumYZ *= invNumPoints; - sumZZ *= invNumPoints; - - // compute eigenvectors for covariance matrix - eigenValues.SetData( 3, VECX_ALLOCA( 3 ) ); - eigenVectors.SetData( 3, 3, MATX_ALLOCA( 3 * 3 ) ); - - eigenVectors[0][0] = sumXX; - eigenVectors[0][1] = sumXY; - eigenVectors[0][2] = sumXZ; - eigenVectors[1][0] = sumXY; - eigenVectors[1][1] = sumYY; - eigenVectors[1][2] = sumYZ; - eigenVectors[2][0] = sumXZ; - eigenVectors[2][1] = sumYZ; - eigenVectors[2][2] = sumZZ; - eigenVectors.Eigen_SolveSymmetric( eigenValues ); - eigenVectors.Eigen_SortIncreasing( eigenValues ); - - axis[0][0] = eigenVectors[0][0]; - axis[0][1] = eigenVectors[0][1]; - axis[0][2] = eigenVectors[0][2]; - axis[1][0] = eigenVectors[1][0]; - axis[1][1] = eigenVectors[1][1]; - axis[1][2] = eigenVectors[1][2]; - axis[2][0] = eigenVectors[2][0]; - axis[2][1] = eigenVectors[2][1]; - axis[2][2] = eigenVectors[2][2]; - - extents[0] = eigenValues[0]; - extents[1] = eigenValues[0]; - extents[2] = eigenValues[0]; - - // refine by calculating the bounds of the points projected onto the axis and adjusting the center and extents - bounds.Clear(); - for ( i = 0; i < numPoints; i++ ) { - bounds.AddPoint( idVec3( points[i] * axis[0], points[i] * axis[1], points[i] * axis[2] ) ); - } - center = ( bounds[0] + bounds[1] ) * 0.5f; - extents = bounds[1] - center; - center *= axis; -} - -/* -============ -idBox::FromPointTranslation - - Most tight box for the translational movement of the given point. -============ -*/ -void idBox::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { - // FIXME: implement -} - -/* -============ -idBox::FromBoxTranslation - - Most tight box for the translational movement of the given box. -============ -*/ -void idBox::FromBoxTranslation( const idBox &box, const idVec3 &translation ) { - // FIXME: implement -} - -/* -============ -idBox::FromPointRotation - - Most tight bounds for the rotational movement of the given point. -============ -*/ -void idBox::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { - // FIXME: implement -} - -/* -============ -idBox::FromBoxRotation - - Most tight box for the rotational movement of the given box. -============ -*/ -void idBox::FromBoxRotation( const idBox &box, const idRotation &rotation ) { - // FIXME: implement -} - -/* -============ -idBox::ToPoints -============ -*/ -void idBox::ToPoints( idVec3 points[8] ) const { - idMat3 ax; - idVec3 temp[4]; - - ax[0] = extents[0] * axis[0]; - ax[1] = extents[1] * axis[1]; - ax[2] = extents[2] * axis[2]; - temp[0] = center - ax[0]; - temp[1] = center + ax[0]; - temp[2] = ax[1] - ax[2]; - temp[3] = ax[1] + ax[2]; - points[0] = temp[0] - temp[3]; - points[1] = temp[1] - temp[3]; - points[2] = temp[1] + temp[2]; - points[3] = temp[0] + temp[2]; - points[4] = temp[0] - temp[2]; - points[5] = temp[1] - temp[2]; - points[6] = temp[1] + temp[3]; - points[7] = temp[0] + temp[3]; -} - -/* -============ -idBox::GetProjectionSilhouetteVerts -============ -*/ -int idBox::GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const { - float f; - int i, planeBits, *index; - idVec3 points[8], dir1, dir2; - - ToPoints( points ); - - dir1 = points[0] - projectionOrigin; - dir2 = points[6] - projectionOrigin; - f = dir1 * axis[0]; - planeBits = FLOATSIGNBITNOTSET( f ); - f = dir2 * axis[0]; - planeBits |= FLOATSIGNBITSET( f ) << 1; - f = dir1 * axis[1]; - planeBits |= FLOATSIGNBITNOTSET( f ) << 2; - f = dir2 * axis[1]; - planeBits |= FLOATSIGNBITSET( f ) << 3; - f = dir1 * axis[2]; - planeBits |= FLOATSIGNBITNOTSET( f ) << 4; - f = dir2 * axis[2]; - planeBits |= FLOATSIGNBITSET( f ) << 5; - - index = boxPlaneBitsSilVerts[planeBits]; - for ( i = 0; i < index[0]; i++ ) { - silVerts[i] = points[index[i+1]]; - } - - return index[0]; -} - -/* -============ -idBox::GetParallelProjectionSilhouetteVerts -============ -*/ -int idBox::GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const { - float f; - int i, planeBits, *index; - idVec3 points[8]; - - ToPoints( points ); - - planeBits = 0; - f = projectionDir * axis[0]; - if ( FLOATNOTZERO( f ) ) { - planeBits = 1 << FLOATSIGNBITSET( f ); - } - f = projectionDir * axis[1]; - if ( FLOATNOTZERO( f ) ) { - planeBits |= 4 << FLOATSIGNBITSET( f ); - } - f = projectionDir * axis[2]; - if ( FLOATNOTZERO( f ) ) { - planeBits |= 16 << FLOATSIGNBITSET( f ); - } - - index = boxPlaneBitsSilVerts[planeBits]; - for ( i = 0; i < index[0]; i++ ) { - silVerts[i] = points[index[i+1]]; - } - - return index[0]; -} - -/* -============ -idBox::ToString -============ -*/ -const char * idBox::ToString( const int precision ) const { - idVec3 min = center - extents; - idVec3 max = center + extents; - return idStr( min.ToString( precision ) ) + " -> " + idStr( max.ToString( precision ) ) + " (" + idStr( axis.ToString() ) + ")"; -} - - diff --git a/idlib/bv/box.h b/idlib/bv/box.h deleted file mode 100644 index 8c1b7aeb8..000000000 --- a/idlib/bv/box.h +++ /dev/null @@ -1,307 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BV_BOX_H__ -#define __BV_BOX_H__ - -/* -=============================================================================== - - Oriented Bounding Box - -=============================================================================== -*/ - -class idBox { -public: - idBox( void ); - explicit idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ); - explicit idBox( const idVec3 &point ); - explicit idBox( const idBounds &bounds ); - explicit idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ); - - idBox operator+( const idVec3 &t ) const; // returns translated box - idBox & operator+=( const idVec3 &t ); // translate the box - idBox operator*( const idMat3 &r ) const; // returns rotated box - idBox & operator*=( const idMat3 &r ); // rotate the box - idBox operator+( const idBox &a ) const; - idBox & operator+=( const idBox &a ); - idBox operator-( const idBox &a ) const; - idBox & operator-=( const idBox &a ); - - bool Compare( const idBox &a ) const; // exact compare, no epsilon - bool Compare( const idBox &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idBox &a ) const; // exact compare, no epsilon - bool operator!=( const idBox &a ) const; // exact compare, no epsilon - - void Clear( void ); // inside out box - void Zero( void ); // single point at origin - - const idVec3 & GetCenter( void ) const; // returns center of the box - const idVec3 & GetExtents( void ) const; // returns extents of the box - const idMat3 & GetAxis( void ) const; // returns the axis of the box - float GetVolume( void ) const; // returns the volume of the box - bool IsCleared( void ) const; // returns true if box are inside out - - bool AddPoint( const idVec3 &v ); // add the point, returns true if the box expanded - bool AddBox( const idBox &a ); // add the box, returns true if the box expanded - idBox Expand( const float d ) const; // return box expanded in all directions with the given value - idBox & ExpandSelf( const float d ); // expand box in all directions with the given value - idBox Translate( const idVec3 &translation ) const; // return translated box - idBox & TranslateSelf( const idVec3 &translation ); // translate this box - idBox Rotate( const idMat3 &rotation ) const; // return rotated box - idBox & RotateSelf( const idMat3 &rotation ); // rotate this box around the origin - idBox & RotateSelfAroundCenter( const idMat3 &rotation ); // rotate this box around the center of the box - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - bool ContainsPoint( const idVec3 &p ) const; // includes touching - bool IntersectsBox( const idBox &a ) const; // includes touching - bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; - // intersection points are (start + dir * scale1) and (start + dir * scale2) - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; - - // tight box for a collection of points - void FromPoints( const idVec3 *points, const int numPoints ); - // most tight box for a translation - void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); - void FromBoxTranslation( const idBox &box, const idVec3 &translation ); - // most tight box for a rotation - void FromPointRotation( const idVec3 &point, const idRotation &rotation ); - void FromBoxRotation( const idBox &box, const idRotation &rotation ); - - void ToPoints( idVec3 points[8] ) const; - idSphere ToSphere( void ) const; - - // calculates the projection of this box onto the given axis - void AxisProjection( const idVec3 &dir, float &min, float &max ) const; - void AxisProjection( const idMat3 &ax, idBounds &bounds ) const; - - // calculates the silhouette of the box - int GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const; - int GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const; - - // angua: fills in the 8 corner vertices of the box - // verts must be an array of 8 idVec3s. - void GetVerts(idVec3* verts) const; - - // Tels: added - const char * ToString( const int precision = 2 ) const; - - -private: - idVec3 center; - idVec3 extents; - idMat3 axis; -}; - -extern idBox box_zero; - -ID_INLINE idBox::idBox( void ) { -} - -ID_INLINE idBox::idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ) { - this->center = center; - this->extents = extents; - this->axis = axis; -} - -ID_INLINE idBox::idBox( const idVec3 &point ) { - this->center = point; - this->extents.Zero(); - this->axis.Identity(); -} - -ID_INLINE idBox::idBox( const idBounds &bounds ) { - this->center = ( bounds[0] + bounds[1] ) * 0.5f; - this->extents = bounds[1] - this->center; - this->axis.Identity(); -} - -ID_INLINE idBox::idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) { - this->center = ( bounds[0] + bounds[1] ) * 0.5f; - this->extents = bounds[1] - this->center; - this->center = origin + this->center * axis; - this->axis = axis; -} - -ID_INLINE idBox idBox::operator+( const idVec3 &t ) const { - return idBox( center + t, extents, axis ); -} - -ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) { - center += t; - return *this; -} - -ID_INLINE idBox idBox::operator*( const idMat3 &r ) const { - return idBox( center * r, extents, axis * r ); -} - -ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) { - center *= r; - axis *= r; - return *this; -} - -ID_INLINE idBox idBox::operator+( const idBox &a ) const { - idBox newBox; - newBox = *this; - newBox.AddBox( a ); - return newBox; -} - -ID_INLINE idBox &idBox::operator+=( const idBox &a ) { - idBox::AddBox( a ); - return *this; -} - -ID_INLINE idBox idBox::operator-( const idBox &a ) const { - return idBox( center, extents - a.extents, axis ); -} - -ID_INLINE idBox &idBox::operator-=( const idBox &a ) { - extents -= a.extents; - return *this; -} - -ID_INLINE bool idBox::Compare( const idBox &a ) const { - return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) ); -} - -ID_INLINE bool idBox::Compare( const idBox &a, const float epsilon ) const { - return ( center.Compare( a.center, epsilon ) && extents.Compare( a.extents, epsilon ) && axis.Compare( a.axis, epsilon ) ); -} - -ID_INLINE bool idBox::operator==( const idBox &a ) const { - return Compare( a ); -} - -ID_INLINE bool idBox::operator!=( const idBox &a ) const { - return !Compare( a ); -} - -ID_INLINE void idBox::Clear( void ) { - center.Zero(); - extents[0] = extents[1] = extents[2] = -idMath::INFINITY; - axis.Identity(); -} - -ID_INLINE void idBox::Zero( void ) { - center.Zero(); - extents.Zero(); - axis.Identity(); -} - -ID_INLINE const idVec3 &idBox::GetCenter( void ) const { - return center; -} - -ID_INLINE const idVec3 &idBox::GetExtents( void ) const { - return extents; -} - -ID_INLINE const idMat3 &idBox::GetAxis( void ) const { - return axis; -} - -ID_INLINE float idBox::GetVolume( void ) const { - return ( extents * 2.0f ).LengthSqr(); -} - -ID_INLINE bool idBox::IsCleared( void ) const { - return extents[0] < 0.0f; -} - -ID_INLINE idBox idBox::Expand( const float d ) const { - return idBox( center, extents + idVec3( d, d, d ), axis ); -} - -ID_INLINE idBox &idBox::ExpandSelf( const float d ) { - extents[0] += d; - extents[1] += d; - extents[2] += d; - return *this; -} - -ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const { - return idBox( center + translation, extents, axis ); -} - -ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) { - center += translation; - return *this; -} - -ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const { - return idBox( center * rotation, extents, axis * rotation ); -} - -ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) { - center *= rotation; - axis *= rotation; - return *this; -} - -ID_INLINE idBox &idBox::RotateSelfAroundCenter( const idMat3 &rotation ) { - axis *= rotation; - return *this; -} - -ID_INLINE bool idBox::ContainsPoint( const idVec3 &p ) const { - idVec3 lp = p - center; - if ( idMath::Fabs( lp * axis[0] ) > extents[0] || - idMath::Fabs( lp * axis[1] ) > extents[1] || - idMath::Fabs( lp * axis[2] ) > extents[2] ) { - return false; - } - return true; -} - -ID_INLINE idSphere idBox::ToSphere( void ) const { - return idSphere( center, extents.Length() ); -} - -ID_INLINE void idBox::AxisProjection( const idVec3 &dir, float &min, float &max ) const { - float d1 = dir * center; - float d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) + - idMath::Fabs( extents[1] * ( dir * axis[1] ) ) + - idMath::Fabs( extents[2] * ( dir * axis[2] ) ); - min = d1 - d2; - max = d1 + d2; -} - -ID_INLINE void idBox::AxisProjection( const idMat3 &ax, idBounds &bounds ) const { - for ( int i = 0; i < 3; i++ ) { - float d1 = ax[i] * center; - float d2 = idMath::Fabs( extents[0] * ( ax[i] * axis[0] ) ) + - idMath::Fabs( extents[1] * ( ax[i] * axis[1] ) ) + - idMath::Fabs( extents[2] * ( ax[i] * axis[2] ) ); - bounds[0][i] = d1 - d2; - bounds[1][i] = d1 + d2; - } -} - -ID_INLINE void idBox::GetVerts(idVec3* verts) const -{ - verts[0] = center + idVec3(extents.x, -extents.y, -extents.z) * axis; - verts[1] = center + idVec3(extents.x, extents.y, -extents.z) * axis; - verts[2] = center + idVec3(-extents.x, extents.y, -extents.z) * axis; - verts[3] = center + idVec3(-extents.x, -extents.y, -extents.z) * axis; - verts[4] = center + idVec3(extents.x, -extents.y, extents.z) * axis; - verts[5] = center + idVec3(extents.x, extents.y, extents.z) * axis; - verts[6] = center + idVec3(-extents.x, extents.y, extents.z) * axis; - verts[7] = center + idVec3(-extents.x, -extents.y, extents.z) * axis; -} - -#endif /* !__BV_BOX_H__ */ diff --git a/idlib/bv/frustum.cpp b/idlib/bv/frustum.cpp deleted file mode 100644 index 3faefb9bf..000000000 --- a/idlib/bv/frustum.cpp +++ /dev/null @@ -1,2829 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -//#define FRUSTUM_DEBUG - -/* - bit 0 = min x - bit 1 = max x - bit 2 = min y - bit 3 = max y - bit 4 = min z - bit 5 = max z -*/ -static int boxVertPlanes[8] = { - ( (1<<0) | (1<<2) | (1<<4) ), - ( (1<<1) | (1<<2) | (1<<4) ), - ( (1<<1) | (1<<3) | (1<<4) ), - ( (1<<0) | (1<<3) | (1<<4) ), - ( (1<<0) | (1<<2) | (1<<5) ), - ( (1<<1) | (1<<2) | (1<<5) ), - ( (1<<1) | (1<<3) | (1<<5) ), - ( (1<<0) | (1<<3) | (1<<5) ), -}; - -/* -============ -BoxToPoints -============ -*/ -void BoxToPoints( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis, idVec3 points[8] ) { - idMat3 ax; - idVec3 temp[4]; - - ax[0] = extents[0] * axis[0]; - ax[1] = extents[1] * axis[1]; - ax[2] = extents[2] * axis[2]; - temp[0] = center - ax[0]; - temp[1] = center + ax[0]; - temp[2] = ax[1] - ax[2]; - temp[3] = ax[1] + ax[2]; - points[0] = temp[0] - temp[3]; - points[1] = temp[1] - temp[3]; - points[2] = temp[1] + temp[2]; - points[3] = temp[0] + temp[2]; - points[4] = temp[0] - temp[2]; - points[5] = temp[1] - temp[2]; - points[6] = temp[1] + temp[3]; - points[7] = temp[0] + temp[3]; -} - -/* -================ -idFrustum::PlaneDistance -================ -*/ -float idFrustum::PlaneDistance( const idPlane &plane ) const { - float min, max; - - AxisProjection( plane.Normal(), min, max ); - if ( min + plane[3] > 0.0f ) { - return min + plane[3]; - } - if ( max + plane[3] < 0.0f ) { - return max + plane[3]; - } - return 0.0f; -} - -/* -================ -idFrustum::PlaneSide -================ -*/ -int idFrustum::PlaneSide( const idPlane &plane, const float epsilon ) const { - float min, max; - - AxisProjection( plane.Normal(), min, max ); - if ( min + plane[3] > epsilon ) { - return PLANESIDE_FRONT; - } - if ( max + plane[3] < epsilon ) { - return PLANESIDE_BACK; - } - return PLANESIDE_CROSS; -} - -/* -============ -idFrustum::CullPoint -============ -*/ -bool idFrustum::CullPoint( const idVec3 &point ) const { - idVec3 p; - float scale; - - // transform point to frustum space - p = ( point - origin ) * axis.Transpose(); - // test whether or not the point is within the frustum - if ( p.x < dNear || p.x > dFar ) { - return true; - } - scale = p.x * invFar; - if ( idMath::Fabs( p.y ) > dLeft * scale ) { - return true; - } - if ( idMath::Fabs( p.z ) > dUp * scale ) { - return true; - } - return false; -} - -/* -============ -idFrustum::CullLocalBox - - Tests if any of the planes of the frustum can be used as a separating plane. - - 3 muls best case - 25 muls worst case -============ -*/ -bool idFrustum::CullLocalBox( const idVec3 &localOrigin, const idVec3 &extents, const idMat3 &localAxis ) const { - float d1, d2; - idVec3 testOrigin; - idMat3 testAxis; - - // near plane - d1 = dNear - localOrigin.x; - d2 = idMath::Fabs( extents[0] * localAxis[0][0] ) + - idMath::Fabs( extents[1] * localAxis[1][0] ) + - idMath::Fabs( extents[2] * localAxis[2][0] ); - if ( d1 - d2 > 0.0f ) { - return true; - } - - // far plane - d1 = localOrigin.x - dFar; - if ( d1 - d2 > 0.0f ) { - return true; - } - - testOrigin = localOrigin; - testAxis = localAxis; - - if ( testOrigin.y < 0.0f ) { - testOrigin.y = -testOrigin.y; - testAxis[0][1] = -testAxis[0][1]; - testAxis[1][1] = -testAxis[1][1]; - testAxis[2][1] = -testAxis[2][1]; - } - - // test left/right planes - d1 = dFar * testOrigin.y - dLeft * testOrigin.x; - d2 = idMath::Fabs( extents[0] * ( dFar * testAxis[0][1] - dLeft * testAxis[0][0] ) ) + - idMath::Fabs( extents[1] * ( dFar * testAxis[1][1] - dLeft * testAxis[1][0] ) ) + - idMath::Fabs( extents[2] * ( dFar * testAxis[2][1] - dLeft * testAxis[2][0] ) ); - if ( d1 - d2 > 0.0f ) { - return true; - } - - if ( testOrigin.z < 0.0f ) { - testOrigin.z = -testOrigin.z; - testAxis[0][2] = -testAxis[0][2]; - testAxis[1][2] = -testAxis[1][2]; - testAxis[2][2] = -testAxis[2][2]; - } - - // test up/down planes - d1 = dFar * testOrigin.z - dUp * testOrigin.x; - d2 = idMath::Fabs( extents[0] * ( dFar * testAxis[0][2] - dUp * testAxis[0][0] ) ) + - idMath::Fabs( extents[1] * ( dFar * testAxis[1][2] - dUp * testAxis[1][0] ) ) + - idMath::Fabs( extents[2] * ( dFar * testAxis[2][2] - dUp * testAxis[2][0] ) ); - if ( d1 - d2 > 0.0f ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::CullBounds - - Tests if any of the planes of the frustum can be used as a separating plane. - - 24 muls best case - 37 muls worst case -============ -*/ -bool idFrustum::CullBounds( const idBounds &bounds ) const { - idVec3 localOrigin, center, extents; - idMat3 localAxis; - - center = ( bounds[0] + bounds[1] ) * 0.5f; - extents = bounds[1] - center; - - // transform the bounds into the space of this frustum - localOrigin = ( center - origin ) * axis.Transpose(); - localAxis = axis.Transpose(); - - return CullLocalBox( localOrigin, extents, localAxis ); -} - -/* -============ -idFrustum::CullBounds - - Tests if any of the planes of the frustum can be used as a separating plane. - - 39 muls best case - 61 muls worst case -============ -*/ -bool idFrustum::CullBox( const idBox &box ) const { - idVec3 localOrigin; - idMat3 localAxis; - - // transform the box into the space of this frustum - localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); - localAxis = box.GetAxis() * axis.Transpose(); - - return CullLocalBox( localOrigin, box.GetExtents(), localAxis ); -} - -/* -============ -idFrustum::CullSphere - - Tests if any of the planes of the frustum can be used as a separating plane. - - 9 muls best case - 21 muls worst case -============ -*/ -bool idFrustum::CullSphere( const idSphere &sphere ) const { - float d, r, rs, sFar; - idVec3 center; - - center = ( sphere.GetOrigin() - origin ) * axis.Transpose(); - r = sphere.GetRadius(); - - // test near plane - if ( dNear - center.x > r ) { - return true; - } - - // test far plane - if ( center.x - dFar > r ) { - return true; - } - - rs = r * r; - sFar = dFar * dFar; - - // test left/right planes - d = dFar * idMath::Fabs( center.y ) - dLeft * center.x; - if ( ( d * d ) > rs * ( sFar + dLeft * dLeft ) ) { - return true; - } - - // test up/down planes - d = dFar * idMath::Fabs( center.z ) - dUp * center.x; - if ( ( d * d ) > rs * ( sFar + dUp * dUp ) ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::CullLocalFrustum - - Tests if any of the planes of this frustum can be used as a separating plane. - - 0 muls best case - 30 muls worst case -============ -*/ -bool idFrustum::CullLocalFrustum( const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const { - int index; - float dx, dy, dz, leftScale, upScale; - - // test near plane - dy = -localFrustum.axis[1].x; - dz = -localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].x < dNear ) { - return true; - } - - // test far plane - dy = localFrustum.axis[1].x; - dz = localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].x > dFar ) { - return true; - } - - leftScale = dLeft * invFar; - - // test left plane - dy = dFar * localFrustum.axis[1].y - dLeft * localFrustum.axis[1].x; - dz = dFar * localFrustum.axis[2].y - dLeft * localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = dFar * cornerVecs[index].y - dLeft * cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].y > indexPoints[index].x * leftScale ) { - return true; - } - - // test right plane - dy = -dFar * localFrustum.axis[1].y - dLeft * localFrustum.axis[1].x; - dz = -dFar * localFrustum.axis[2].y - dLeft * localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -dFar * cornerVecs[index].y - dLeft * cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].y < -indexPoints[index].x * leftScale ) { - return true; - } - - upScale = dUp * invFar; - - // test up plane - dy = dFar * localFrustum.axis[1].z - dUp * localFrustum.axis[1].x; - dz = dFar * localFrustum.axis[2].z - dUp * localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = dFar * cornerVecs[index].z - dUp * cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].z > indexPoints[index].x * upScale ) { - return true; - } - - // test down plane - dy = -dFar * localFrustum.axis[1].z - dUp * localFrustum.axis[1].x; - dz = -dFar * localFrustum.axis[2].z - dUp * localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -dFar * cornerVecs[index].z - dUp * cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].z < -indexPoints[index].x * upScale ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::CullFrustum - - Tests if any of the planes of this frustum can be used as a separating plane. - - 58 muls best case - 88 muls worst case -============ -*/ -bool idFrustum::CullFrustum( const idFrustum &frustum ) const { - idFrustum localFrustum; - idVec3 indexPoints[8], cornerVecs[4]; - - // transform the given frustum into the space of this frustum - localFrustum = frustum; - localFrustum.origin = ( frustum.origin - origin ) * axis.Transpose(); - localFrustum.axis = frustum.axis * axis.Transpose(); - - localFrustum.ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - - return CullLocalFrustum( localFrustum, indexPoints, cornerVecs ); -} - -/* -============ -idFrustum::CullLocalWinding -============ -*/ -bool idFrustum::CullLocalWinding( const idVec3 *points, const int numPoints, int *pointCull ) const { - int i, pCull, culled; - float leftScale, upScale; - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - - culled = -1; - for ( i = 0; i < numPoints; i++ ) { - const idVec3 &p = points[i]; - pCull = 0; - if ( p.x < dNear ) { - pCull = 1; - } - else if ( p.x > dFar ) { - pCull = 2; - } - if ( idMath::Fabs( p.y ) > p.x * leftScale ) { - pCull |= 4 << FLOATSIGNBITSET( p.y ); - } - if ( idMath::Fabs( p.z ) > p.x * upScale ) { - pCull |= 16 << FLOATSIGNBITSET( p.z ); - } - culled &= pCull; - pointCull[i] = pCull; - } - - return ( culled != 0 ); -} - -/* -============ -idFrustum::CullWinding -============ -*/ -bool idFrustum::CullWinding( const idWinding &winding ) const { - int i, *pointCull; - idVec3 *localPoints; - idMat3 transpose; - - localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); - pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); - - transpose = axis.Transpose(); - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; - } - - return CullLocalWinding( localPoints, winding.GetNumPoints(), pointCull ); -} - -/* -============ -idFrustum::BoundsCullLocalFrustum - - Tests if any of the bounding box planes can be used as a separating plane. -============ -*/ -bool idFrustum::BoundsCullLocalFrustum( const idBounds &bounds, const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const { - int index; - float dx, dy, dz; - - dy = -localFrustum.axis[1].x; - dz = -localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].x < bounds[0].x ) { - return true; - } - - dy = localFrustum.axis[1].x; - dz = localFrustum.axis[2].x; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = cornerVecs[index].x; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].x > bounds[1].x ) { - return true; - } - - dy = -localFrustum.axis[1].y; - dz = -localFrustum.axis[2].y; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -cornerVecs[index].y; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].y < bounds[0].y ) { - return true; - } - - dy = localFrustum.axis[1].y; - dz = localFrustum.axis[2].y; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = cornerVecs[index].y; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].y > bounds[1].y ) { - return true; - } - - dy = -localFrustum.axis[1].z; - dz = -localFrustum.axis[2].z; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = -cornerVecs[index].z; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].z < bounds[0].z ) { - return true; - } - - dy = localFrustum.axis[1].z; - dz = localFrustum.axis[2].z; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = cornerVecs[index].z; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - - if ( indexPoints[index].z > bounds[1].z ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::LocalLineIntersection - - 7 divs - 30 muls -============ -*/ -bool idFrustum::LocalLineIntersection( const idVec3 &start, const idVec3 &end ) const { - idVec3 dir; - float d1, d2, fstart, fend, lstart, lend, f, x; - float leftScale, upScale; - int startInside = 1; - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - dir = end - start; - - // test near plane - if ( dNear > 0.0f ) { - d1 = dNear - start.x; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = dNear - end.x; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - if ( idMath::Fabs( start.y + f * dir.y ) <= dNear * leftScale ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= dNear * upScale ) { - return true; - } - } - } - } - } - - // test far plane - d1 = start.x - dFar; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = end.x - dFar; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - if ( idMath::Fabs( start.y + f * dir.y ) <= dFar * leftScale ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= dFar * upScale ) { - return true; - } - } - } - } - - fstart = dFar * start.y; - fend = dFar * end.y; - lstart = dLeft * start.x; - lend = dLeft * end.x; - - // test left plane - d1 = fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = fend - lend; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { - return true; - } - } - } - } - - // test right plane - d1 = -fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = -fend - lend; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { - return true; - } - } - } - } - - fstart = dFar * start.z; - fend = dFar * end.z; - lstart = dUp * start.x; - lend = dUp * end.x; - - // test up plane - d1 = fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = fend - lend; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { - return true; - } - } - } - } - - // test down plane - d1 = -fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - if ( FLOATNOTZERO( d1 ) ) { - d2 = -fend - lend; - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { - return true; - } - } - } - } - - return ( startInside != 0 ); -} - -/* -============ -idFrustum::LocalRayIntersection - - Returns true if the ray starts inside the frustum. - If there was an intersection scale1 <= scale2 -============ -*/ -bool idFrustum::LocalRayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { - idVec3 end; - float d1, d2, fstart, fend, lstart, lend, f, x; - float leftScale, upScale; - int startInside = 1; - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - end = start + dir; - - scale1 = idMath::INFINITY; - scale2 = -idMath::INFINITY; - - // test near plane - if ( dNear > 0.0f ) { - d1 = dNear - start.x; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = dNear - end.x; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - if ( idMath::Fabs( start.y + f * dir.y ) <= dNear * leftScale ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= dNear * upScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - } - - // test far plane - d1 = start.x - dFar; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = end.x - dFar; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - if ( idMath::Fabs( start.y + f * dir.y ) <= dFar * leftScale ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= dFar * upScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - fstart = dFar * start.y; - fend = dFar * end.y; - lstart = dLeft * start.x; - lend = dLeft * end.x; - - // test left plane - d1 = fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = fend - lend; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - // test right plane - d1 = -fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = -fend - lend; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.z + f * dir.z ) <= x * upScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - fstart = dFar * start.z; - fend = dFar * end.z; - lstart = dUp * start.x; - lend = dUp * end.x; - - // test up plane - d1 = fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = fend - lend; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - // test down plane - d1 = -fstart - lstart; - startInside &= FLOATSIGNBITSET( d1 ); - d2 = -fend - lend; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - x = start.x + f * dir.x; - if ( x >= dNear && x <= dFar ) { - if ( idMath::Fabs( start.y + f * dir.y ) <= x * leftScale ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - return ( startInside != 0 ); -} - -/* -============ -idFrustum::ContainsPoint -============ -*/ -bool idFrustum::ContainsPoint( const idVec3 &point ) const { - return !CullPoint( point ); -} - -/* -============ -idFrustum::LocalFrustumIntersectsFrustum -============ -*/ -bool idFrustum::LocalFrustumIntersectsFrustum( const idVec3 points[8], const bool testFirstSide ) const { - int i; - - // test if any edges of the other frustum intersect this frustum - for ( i = 0; i < 4; i++ ) { - if ( LocalLineIntersection( points[i], points[4+i] ) ) { - return true; - } - } - if ( testFirstSide ) { - for ( i = 0; i < 4; i++ ) { - if ( LocalLineIntersection( points[i], points[(i+1)&3] ) ) { - return true; - } - } - } - for ( i = 0; i < 4; i++ ) { - if ( LocalLineIntersection( points[4+i], points[4+((i+1)&3)] ) ) { - return true; - } - } - - return false; -} - -/* -============ -idFrustum::LocalFrustumIntersectsBounds -============ -*/ -bool idFrustum::LocalFrustumIntersectsBounds( const idVec3 points[8], const idBounds &bounds ) const { - int i; - - // test if any edges of the other frustum intersect this frustum - for ( i = 0; i < 4; i++ ) { - if ( bounds.LineIntersection( points[i], points[4+i] ) ) { - return true; - } - } - if ( dNear > 0.0f ) { - for ( i = 0; i < 4; i++ ) { - if ( bounds.LineIntersection( points[i], points[(i+1)&3] ) ) { - return true; - } - } - } - for ( i = 0; i < 4; i++ ) { - if ( bounds.LineIntersection( points[4+i], points[4+((i+1)&3)] ) ) { - return true; - } - } - - return false; -} - -/* -============ -idFrustum::IntersectsBounds -============ -*/ -bool idFrustum::IntersectsBounds( const idBounds &bounds ) const { - idVec3 localOrigin, center, extents; - idMat3 localAxis; - - center = ( bounds[0] + bounds[1] ) * 0.5f; - extents = bounds[1] - center; - - localOrigin = ( center - origin ) * axis.Transpose(); - localAxis = axis.Transpose(); - - if ( CullLocalBox( localOrigin, extents, localAxis ) ) { - return false; - } - - idVec3 indexPoints[8], cornerVecs[4]; - - ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - - if ( BoundsCullLocalFrustum( bounds, *this, indexPoints, cornerVecs ) ) { - return false; - } - - idSwap( indexPoints[2], indexPoints[3] ); - idSwap( indexPoints[6], indexPoints[7] ); - - if ( LocalFrustumIntersectsBounds( indexPoints, bounds ) ) { - return true; - } - - BoxToPoints( localOrigin, extents, localAxis, indexPoints ); - - if ( LocalFrustumIntersectsFrustum( indexPoints, true ) ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::IntersectsBox -============ -*/ -bool idFrustum::IntersectsBox( const idBox &box ) const { - idVec3 localOrigin; - idMat3 localAxis; - - localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); - localAxis = box.GetAxis() * axis.Transpose(); - - if ( CullLocalBox( localOrigin, box.GetExtents(), localAxis ) ) { - return false; - } - - idVec3 indexPoints[8], cornerVecs[4]; - idFrustum localFrustum; - - localFrustum = *this; - localFrustum.origin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); - localFrustum.axis = axis * box.GetAxis().Transpose(); - localFrustum.ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - - if ( BoundsCullLocalFrustum( idBounds( -box.GetExtents(), box.GetExtents() ), localFrustum, indexPoints, cornerVecs ) ) { - return false; - } - - idSwap( indexPoints[2], indexPoints[3] ); - idSwap( indexPoints[6], indexPoints[7] ); - - if ( LocalFrustumIntersectsBounds( indexPoints, idBounds( -box.GetExtents(), box.GetExtents() ) ) ) { - return true; - } - - BoxToPoints( localOrigin, box.GetExtents(), localAxis, indexPoints ); - - if ( LocalFrustumIntersectsFrustum( indexPoints, true ) ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::IntersectsSphere - - FIXME: test this -============ -*/ -#define VORONOI_INDEX( x, y, z ) ( x + y * 3 + z * 9 ) - -bool idFrustum::IntersectsSphere( const idSphere &sphere ) const { - int index, x, y, z; - float scale, r, d; - idVec3 p, dir, points[8]; - - if ( CullSphere( sphere ) ) { - return false; - } - - x = y = z = 0; - dir.Zero(); - - p = ( sphere.GetOrigin() - origin ) * axis.Transpose(); - - if ( p.x <= dNear ) { - scale = dNear * invFar; - dir.y = idMath::Fabs( p.y ) - dLeft * scale; - dir.z = idMath::Fabs( p.z ) - dUp * scale; - } - else if ( p.x >= dFar ) { - dir.y = idMath::Fabs( p.y ) - dLeft; - dir.z = idMath::Fabs( p.z ) - dUp; - } - else { - scale = p.x * invFar; - dir.y = idMath::Fabs( p.y ) - dLeft * scale; - dir.z = idMath::Fabs( p.z ) - dUp * scale; - } - if ( dir.y > 0.0f ) { - y = ( 1 + FLOATSIGNBITNOTSET( p.y ) ); - } - if ( dir.z > 0.0f ) { - z = ( 1 + FLOATSIGNBITNOTSET( p.z ) ); - } - if ( p.x < dNear ) { - scale = dLeft * dNear * invFar; - if ( p.x < dNear + ( scale - p.y ) * scale * invFar ) { - scale = dUp * dNear * invFar; - if ( p.x < dNear + ( scale - p.z ) * scale * invFar ) { - x = 1; - } - } - } - else { - if ( p.x > dFar ) { - x = 2; - } - else if ( p.x > dFar + ( dLeft - p.y ) * dLeft * invFar ) { - x = 2; - } - else if ( p.x > dFar + ( dUp - p.z ) * dUp * invFar ) { - x = 2; - } - } - - r = sphere.GetRadius(); - index = VORONOI_INDEX( x, y, z ); - switch( index ) { - case VORONOI_INDEX( 0, 0, 0 ): return true; - case VORONOI_INDEX( 1, 0, 0 ): return ( dNear - p.x < r ); - case VORONOI_INDEX( 2, 0, 0 ): return ( p.x - dFar < r ); - case VORONOI_INDEX( 0, 1, 0 ): d = dFar * p.y - dLeft * p.x; return ( d * d < r * r * ( dFar * dFar + dLeft * dLeft ) ); - case VORONOI_INDEX( 0, 2, 0 ): d = -dFar * p.z - dLeft * p.x; return ( d * d < r * r * ( dFar * dFar + dLeft * dLeft ) ); - case VORONOI_INDEX( 0, 0, 1 ): d = dFar * p.z - dUp * p.x; return ( d * d < r * r * ( dFar * dFar + dUp * dUp ) ); - case VORONOI_INDEX( 0, 0, 2 ): d = -dFar * p.z - dUp * p.x; return ( d * d < r * r * ( dFar * dFar + dUp * dUp ) ); - default: { - ToIndexPoints( points ); - switch( index ) { - case VORONOI_INDEX( 1, 1, 1 ): return sphere.ContainsPoint( points[0] ); - case VORONOI_INDEX( 2, 1, 1 ): return sphere.ContainsPoint( points[4] ); - case VORONOI_INDEX( 1, 2, 1 ): return sphere.ContainsPoint( points[1] ); - case VORONOI_INDEX( 2, 2, 1 ): return sphere.ContainsPoint( points[5] ); - case VORONOI_INDEX( 1, 1, 2 ): return sphere.ContainsPoint( points[2] ); - case VORONOI_INDEX( 2, 1, 2 ): return sphere.ContainsPoint( points[6] ); - case VORONOI_INDEX( 1, 2, 2 ): return sphere.ContainsPoint( points[3] ); - case VORONOI_INDEX( 2, 2, 2 ): return sphere.ContainsPoint( points[7] ); - case VORONOI_INDEX( 1, 1, 0 ): return sphere.LineIntersection( points[0], points[2] ); - case VORONOI_INDEX( 2, 1, 0 ): return sphere.LineIntersection( points[4], points[6] ); - case VORONOI_INDEX( 1, 2, 0 ): return sphere.LineIntersection( points[1], points[3] ); - case VORONOI_INDEX( 2, 2, 0 ): return sphere.LineIntersection( points[5], points[7] ); - case VORONOI_INDEX( 1, 0, 1 ): return sphere.LineIntersection( points[0], points[1] ); - case VORONOI_INDEX( 2, 0, 1 ): return sphere.LineIntersection( points[4], points[5] ); - case VORONOI_INDEX( 0, 1, 1 ): return sphere.LineIntersection( points[0], points[4] ); - case VORONOI_INDEX( 0, 2, 1 ): return sphere.LineIntersection( points[1], points[5] ); - case VORONOI_INDEX( 1, 0, 2 ): return sphere.LineIntersection( points[2], points[3] ); - case VORONOI_INDEX( 2, 0, 2 ): return sphere.LineIntersection( points[6], points[7] ); - case VORONOI_INDEX( 0, 1, 2 ): return sphere.LineIntersection( points[2], points[6] ); - case VORONOI_INDEX( 0, 2, 2 ): return sphere.LineIntersection( points[3], points[7] ); - } - break; - } - } - return false; -} - -/* -============ -idFrustum::IntersectsFrustum -============ -*/ -bool idFrustum::IntersectsFrustum( const idFrustum &frustum ) const { - idVec3 indexPoints2[8], cornerVecs2[4]; - idFrustum localFrustum2; - - localFrustum2 = frustum; - localFrustum2.origin = ( frustum.origin - origin ) * axis.Transpose(); - localFrustum2.axis = frustum.axis * axis.Transpose(); - localFrustum2.ToIndexPointsAndCornerVecs( indexPoints2, cornerVecs2 ); - - if ( CullLocalFrustum( localFrustum2, indexPoints2, cornerVecs2 ) ) { - return false; - } - - idVec3 indexPoints1[8], cornerVecs1[4]; - idFrustum localFrustum1; - - localFrustum1 = *this; - localFrustum1.origin = ( origin - frustum.origin ) * frustum.axis.Transpose(); - localFrustum1.axis = axis * frustum.axis.Transpose(); - localFrustum1.ToIndexPointsAndCornerVecs( indexPoints1, cornerVecs1 ); - - if ( frustum.CullLocalFrustum( localFrustum1, indexPoints1, cornerVecs1 ) ) { - return false; - } - - idSwap( indexPoints2[2], indexPoints2[3] ); - idSwap( indexPoints2[6], indexPoints2[7] ); - - if ( LocalFrustumIntersectsFrustum( indexPoints2, ( localFrustum2.dNear > 0.0f ) ) ) { - return true; - } - - idSwap( indexPoints1[2], indexPoints1[3] ); - idSwap( indexPoints1[6], indexPoints1[7] ); - - if ( frustum.LocalFrustumIntersectsFrustum( indexPoints1, ( localFrustum1.dNear > 0.0f ) ) ) { - return true; - } - - return false; -} - -/* -============ -idFrustum::IntersectsWinding -============ -*/ -bool idFrustum::IntersectsWinding( const idWinding &winding ) const { - int i, j, *pointCull; - float min, max; - idVec3 *localPoints, indexPoints[8], cornerVecs[4]; - idMat3 transpose; - idPlane plane; - - localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); - pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); - - transpose = axis.Transpose(); - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; - } - - // if the winding is culled - if ( CullLocalWinding( localPoints, winding.GetNumPoints(), pointCull ) ) { - return false; - } - - winding.GetPlane( plane ); - - ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - AxisProjection( indexPoints, cornerVecs, plane.Normal(), min, max ); - - // if the frustum does not cross the winding plane - if ( min + plane[3] > 0.0f || max + plane[3] < 0.0f ) { - return false; - } - - // test if any of the winding edges goes through the frustum - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - j = (i+1)%winding.GetNumPoints(); - if ( !( pointCull[i] & pointCull[j] ) ) { - if ( LocalLineIntersection( localPoints[i], localPoints[j] ) ) { - return true; - } - } - } - - idSwap( indexPoints[2], indexPoints[3] ); - idSwap( indexPoints[6], indexPoints[7] ); - - // test if any edges of the frustum intersect the winding - for ( i = 0; i < 4; i++ ) { - if ( winding.LineIntersection( plane, indexPoints[i], indexPoints[4+i] ) ) { - return true; - } - } - if ( dNear > 0.0f ) { - for ( i = 0; i < 4; i++ ) { - if ( winding.LineIntersection( plane, indexPoints[i], indexPoints[(i+1)&3] ) ) { - return true; - } - } - } - for ( i = 0; i < 4; i++ ) { - if ( winding.LineIntersection( plane, indexPoints[4+i], indexPoints[4+((i+1)&3)] ) ) { - return true; - } - } - - return false; -} - -/* -============ -idFrustum::LineIntersection - - Returns true if the line intersects the box between the start and end point. -============ -*/ -bool idFrustum::LineIntersection( const idVec3 &start, const idVec3 &end ) const { - return LocalLineIntersection( ( start - origin ) * axis.Transpose(), ( end - origin ) * axis.Transpose() ); -} - -/* -============ -idFrustum::RayIntersection - - Returns true if the ray intersects the bounds. - The ray can intersect the bounds in both directions from the start point. - If start is inside the frustum then scale1 < 0 and scale2 > 0. -============ -*/ -bool idFrustum::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { - if ( LocalRayIntersection( ( start - origin ) * axis.Transpose(), dir * axis.Transpose(), scale1, scale2 ) ) { - return true; - } - if ( scale1 <= scale2 ) { - return true; - } - return false; -} - -/* -============ -idFrustum::FromProjection - - Creates a frustum which contains the projection of the bounds. -============ -*/ -bool idFrustum::FromProjection( const idBounds &bounds, const idVec3 &projectionOrigin, const float dFar ) { - return FromProjection( idBox( bounds, vec3_origin, mat3_identity ), projectionOrigin, dFar ); -} - -/* -============ -idFrustum::FromProjection - - Creates a frustum which contains the projection of the box. -============ -*/ -bool idFrustum::FromProjection( const idBox &box, const idVec3 &projectionOrigin, const float dFar ) { - int i, bestAxis; - float value, bestValue; - idVec3 dir; - - assert( dFar > 0.0f ); - - this->dNear = this->dFar = this->invFar = 0.0f; - - dir = box.GetCenter() - projectionOrigin; - if ( dir.Normalize() == 0.0f ) { - return false; - } - - bestAxis = 0; - bestValue = idMath::Fabs( box.GetAxis()[0] * dir ); - for ( i = 1; i < 3; i++ ) { - value = idMath::Fabs( box.GetAxis()[i] * dir ); - if ( value * box.GetExtents()[bestAxis] * box.GetExtents()[bestAxis] < bestValue * box.GetExtents()[i] * box.GetExtents()[i] ) { - bestValue = value; - bestAxis = i; - } - } - -#if 1 - - int j, minX, minY, maxY, minZ, maxZ; - idVec3 points[8]; - - minX = minY = maxY = minZ = maxZ = 0; - - for ( j = 0; j < 2; j++ ) { - - axis[0] = dir; - axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; - axis[1].Normalize(); - axis[2].Cross( axis[0], axis[1] ); - - BoxToPoints( ( box.GetCenter() - projectionOrigin ) * axis.Transpose(), box.GetExtents(), box.GetAxis() * axis.Transpose(), points ); - - if ( points[0].x <= 1.0f ) { - return false; - } - - minX = minY = maxY = minZ = maxZ = 0; - for ( i = 1; i < 8; i++ ) { - if ( points[i].x <= 1.0f ) { - return false; - } - if ( points[i].x < points[minX].x ) { - minX = i; - } - if ( points[minY].x * points[i].y < points[i].x * points[minY].y ) { - minY = i; - } else if ( points[maxY].x * points[i].y > points[i].x * points[maxY].y ) { - maxY = i; - } - if ( points[minZ].x * points[i].z < points[i].x * points[minZ].z ) { - minZ = i; - } else if ( points[maxZ].x * points[i].z > points[i].x * points[maxZ].z ) { - maxZ = i; - } - } - - if ( j == 0 ) { - dir += idMath::Tan16( 0.5f * ( idMath::ATan16( points[minY].y, points[minY].x ) + idMath::ATan16( points[maxY].y, points[maxY].x ) ) ) * axis[1]; - dir += idMath::Tan16( 0.5f * ( idMath::ATan16( points[minZ].z, points[minZ].x ) + idMath::ATan16( points[maxZ].z, points[maxZ].x ) ) ) * axis[2]; - dir.Normalize(); - } - } - - this->origin = projectionOrigin; - this->dNear = points[minX].x; - this->dFar = dFar; - this->dLeft = Max( idMath::Fabs( points[minY].y / points[minY].x ), idMath::Fabs( points[maxY].y / points[maxY].x ) ) * dFar; - this->dUp = Max( idMath::Fabs( points[minZ].z / points[minZ].x ), idMath::Fabs( points[maxZ].z / points[maxZ].x ) ) * dFar; - this->invFar = 1.0f / dFar; - -#elif 1 - - int j; - float f, x; - idBounds b; - idVec3 points[8]; - - for ( j = 0; j < 2; j++ ) { - - axis[0] = dir; - axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; - axis[1].Normalize(); - axis[2].Cross( axis[0], axis[1] ); - - BoxToPoints( ( box.GetCenter() - projectionOrigin ) * axis.Transpose(), box.GetExtents(), box.GetAxis() * axis.Transpose(), points ); - - b.Clear(); - for ( i = 0; i < 8; i++ ) { - x = points[i].x; - if ( x <= 1.0f ) { - return false; - } - f = 1.0f / x; - points[i].y *= f; - points[i].z *= f; - b.AddPoint( points[i] ); - } - - if ( j == 0 ) { - dir += idMath::Tan16( 0.5f * ( idMath::ATan16( b[1][1] ) + idMath::ATan16( b[0][1] ) ) ) * axis[1]; - dir += idMath::Tan16( 0.5f * ( idMath::ATan16( b[1][2] ) + idMath::ATan16( b[0][2] ) ) ) * axis[2]; - dir.Normalize(); - } - } - - this->origin = projectionOrigin; - this->dNear = b[0][0]; - this->dFar = dFar; - this->dLeft = Max( idMath::Fabs( b[0][1] ), idMath::Fabs( b[1][1] ) ) * dFar; - this->dUp = Max( idMath::Fabs( b[0][2] ), idMath::Fabs( b[1][2] ) ) * dFar; - this->invFar = 1.0f / dFar; - -#else - - float dist; - idVec3 org; - - axis[0] = dir; - axis[1] = box.GetAxis()[bestAxis] - ( box.GetAxis()[bestAxis] * axis[0] ) * axis[0]; - axis[1].Normalize(); - axis[2].Cross( axis[0], axis[1] ); - - for ( i = 0; i < 3; i++ ) { - dist[i] = idMath::Fabs( box.GetExtents()[0] * ( axis[i] * box.GetAxis()[0] ) ) + - idMath::Fabs( box.GetExtents()[1] * ( axis[i] * box.GetAxis()[1] ) ) + - idMath::Fabs( box.GetExtents()[2] * ( axis[i] * box.GetAxis()[2] ) ); - } - - dist[0] = axis[0] * ( box.GetCenter() - projectionOrigin ) - dist[0]; - if ( dist[0] <= 1.0f ) { - return false; - } - float invDist = 1.0f / dist[0]; - - this->origin = projectionOrigin; - this->dNear = dist[0]; - this->dFar = dFar; - this->dLeft = dist[1] * invDist * dFar; - this->dUp = dist[2] * invDist * dFar; - this->invFar = 1.0f / dFar; - -#endif - - return true; -} - -/* -============ -idFrustum::FromProjection - - Creates a frustum which contains the projection of the sphere. -============ -*/ -bool idFrustum::FromProjection( const idSphere &sphere, const idVec3 &projectionOrigin, const float dFar ) { - idVec3 dir; - float d, r, s, x, y; - - assert( dFar > 0.0f ); - - dir = sphere.GetOrigin() - projectionOrigin; - d = dir.Normalize(); - r = sphere.GetRadius(); - - if ( d <= r + 1.0f ) { - this->dNear = this->dFar = this->invFar = 0.0f; - return false; - } - - origin = projectionOrigin; - axis = dir.ToMat3(); - - s = idMath::Sqrt( d * d - r * r ); - x = r / d * s; - y = idMath::Sqrt( s * s - x * x ); - - this->dNear = d - r; - this->dFar = dFar; - this->dLeft = x / y * dFar; - this->dUp = dLeft; - this->invFar = 1.0f / dFar; - - return true; -} - -/* -============ -idFrustum::ConstrainToBounds - - Returns false if no part of the bounds extends beyond the near plane. -============ -*/ -bool idFrustum::ConstrainToBounds( const idBounds &bounds ) { - float min, max, newdFar; - - bounds.AxisProjection( axis[0], min, max ); - newdFar = max - axis[0] * origin; - if ( newdFar <= dNear ) { - MoveFarDistance( dNear + 1.0f ); - return false; - } - MoveFarDistance( newdFar ); - return true; -} - -/* -============ -idFrustum::ConstrainToBox - - Returns false if no part of the box extends beyond the near plane. -============ -*/ -bool idFrustum::ConstrainToBox( const idBox &box ) { - float min, max, newdFar; - - box.AxisProjection( axis[0], min, max ); - newdFar = max - axis[0] * origin; - if ( newdFar <= dNear ) { - MoveFarDistance( dNear + 1.0f ); - return false; - } - MoveFarDistance( newdFar ); - return true; -} - -/* -============ -idFrustum::ConstrainToSphere - - Returns false if no part of the sphere extends beyond the near plane. -============ -*/ -bool idFrustum::ConstrainToSphere( const idSphere &sphere ) { - float min, max, newdFar; - - sphere.AxisProjection( axis[0], min, max ); - newdFar = max - axis[0] * origin; - if ( newdFar <= dNear ) { - MoveFarDistance( dNear + 1.0f ); - return false; - } - MoveFarDistance( newdFar ); - return true; -} - -/* -============ -idFrustum::ConstrainToFrustum - - Returns false if no part of the frustum extends beyond the near plane. -============ -*/ -bool idFrustum::ConstrainToFrustum( const idFrustum &frustum ) { - float min, max, newdFar; - - frustum.AxisProjection( axis[0], min, max ); - newdFar = max - axis[0] * origin; - if ( newdFar <= dNear ) { - MoveFarDistance( dNear + 1.0f ); - return false; - } - MoveFarDistance( newdFar ); - return true; -} - -/* -============ -idFrustum::ToPlanes - - planes point outwards -============ -*/ -void idFrustum::ToPlanes( idPlane planes[6] ) const { - int i; - idVec3 scaled[2]; - idVec3 points[4]; - - planes[0].Normal() = -axis[0]; - planes[0].SetDist( -dNear ); - planes[1].Normal() = axis[0]; - planes[1].SetDist( dFar ); - - scaled[0] = axis[1] * dLeft; - scaled[1] = axis[2] * dUp; - points[0] = scaled[0] + scaled[1]; - points[1] = -scaled[0] + scaled[1]; - points[2] = -scaled[0] - scaled[1]; - points[3] = scaled[0] - scaled[1]; - - for ( i = 0; i < 4; i++ ) { - planes[i+2].Normal() = points[i].Cross( points[(i+1)&3] - points[i] ); - planes[i+2].Normalize(); - planes[i+2].FitThroughPoint( points[i] ); - } -} - -/* -============ -idFrustum::ToPoints -============ -*/ -void idFrustum::ToPoints( idVec3 points[8] ) const { - idMat3 scaled; - - scaled[0] = origin + axis[0] * dNear; - scaled[1] = axis[1] * ( dLeft * dNear * invFar ); - scaled[2] = axis[2] * ( dUp * dNear * invFar ); - - points[0] = scaled[0] + scaled[1]; - points[1] = scaled[0] - scaled[1]; - points[2] = points[1] - scaled[2]; - points[3] = points[0] - scaled[2]; - points[0] += scaled[2]; - points[1] += scaled[2]; - - scaled[0] = origin + axis[0] * dFar; - scaled[1] = axis[1] * dLeft; - scaled[2] = axis[2] * dUp; - - points[4] = scaled[0] + scaled[1]; - points[5] = scaled[0] - scaled[1]; - points[6] = points[5] - scaled[2]; - points[7] = points[4] - scaled[2]; - points[4] += scaled[2]; - points[5] += scaled[2]; -} - -/* -============ -idFrustum::ToClippedPoints -============ -*/ -void idFrustum::ToClippedPoints( const float fractions[4], idVec3 points[8] ) const { - idMat3 scaled; - - scaled[0] = origin + axis[0] * dNear; - scaled[1] = axis[1] * ( dLeft * dNear * invFar ); - scaled[2] = axis[2] * ( dUp * dNear * invFar ); - - points[0] = scaled[0] + scaled[1]; - points[1] = scaled[0] - scaled[1]; - points[2] = points[1] - scaled[2]; - points[3] = points[0] - scaled[2]; - points[0] += scaled[2]; - points[1] += scaled[2]; - - scaled[0] = axis[0] * dFar; - scaled[1] = axis[1] * dLeft; - scaled[2] = axis[2] * dUp; - - points[4] = scaled[0] + scaled[1]; - points[5] = scaled[0] - scaled[1]; - points[6] = points[5] - scaled[2]; - points[7] = points[4] - scaled[2]; - points[4] += scaled[2]; - points[5] += scaled[2]; - - points[4] = origin + fractions[0] * points[4]; - points[5] = origin + fractions[1] * points[5]; - points[6] = origin + fractions[2] * points[6]; - points[7] = origin + fractions[3] * points[7]; -} - -/* -============ -idFrustum::ToIndexPoints -============ -*/ -void idFrustum::ToIndexPoints( idVec3 indexPoints[8] ) const { - idMat3 scaled; - - scaled[0] = origin + axis[0] * dNear; - scaled[1] = axis[1] * ( dLeft * dNear * invFar ); - scaled[2] = axis[2] * ( dUp * dNear * invFar ); - - indexPoints[0] = scaled[0] - scaled[1]; - indexPoints[2] = scaled[0] + scaled[1]; - indexPoints[1] = indexPoints[0] + scaled[2]; - indexPoints[3] = indexPoints[2] + scaled[2]; - indexPoints[0] -= scaled[2]; - indexPoints[2] -= scaled[2]; - - scaled[0] = origin + axis[0] * dFar; - scaled[1] = axis[1] * dLeft; - scaled[2] = axis[2] * dUp; - - indexPoints[4] = scaled[0] - scaled[1]; - indexPoints[6] = scaled[0] + scaled[1]; - indexPoints[5] = indexPoints[4] + scaled[2]; - indexPoints[7] = indexPoints[6] + scaled[2]; - indexPoints[4] -= scaled[2]; - indexPoints[6] -= scaled[2]; -} - -/* -============ -idFrustum::ToIndexPointsAndCornerVecs - - 22 muls -============ -*/ -void idFrustum::ToIndexPointsAndCornerVecs( idVec3 indexPoints[8], idVec3 cornerVecs[4] ) const { - idMat3 scaled; - - scaled[0] = origin + axis[0] * dNear; - scaled[1] = axis[1] * ( dLeft * dNear * invFar ); - scaled[2] = axis[2] * ( dUp * dNear * invFar ); - - indexPoints[0] = scaled[0] - scaled[1]; - indexPoints[2] = scaled[0] + scaled[1]; - indexPoints[1] = indexPoints[0] + scaled[2]; - indexPoints[3] = indexPoints[2] + scaled[2]; - indexPoints[0] -= scaled[2]; - indexPoints[2] -= scaled[2]; - - scaled[0] = axis[0] * dFar; - scaled[1] = axis[1] * dLeft; - scaled[2] = axis[2] * dUp; - - cornerVecs[0] = scaled[0] - scaled[1]; - cornerVecs[2] = scaled[0] + scaled[1]; - cornerVecs[1] = cornerVecs[0] + scaled[2]; - cornerVecs[3] = cornerVecs[2] + scaled[2]; - cornerVecs[0] -= scaled[2]; - cornerVecs[2] -= scaled[2]; - - indexPoints[4] = cornerVecs[0] + origin; - indexPoints[5] = cornerVecs[1] + origin; - indexPoints[6] = cornerVecs[2] + origin; - indexPoints[7] = cornerVecs[3] + origin; -} - -/* -============ -idFrustum::AxisProjection - - 18 muls -============ -*/ -void idFrustum::AxisProjection( const idVec3 indexPoints[8], const idVec3 cornerVecs[4], const idVec3 &dir, float &min, float &max ) const { - float dx, dy, dz; - int index; - - dy = dir.x * axis[1].x + dir.y * axis[1].y + dir.z * axis[1].z; - dz = dir.x * axis[2].x + dir.y * axis[2].y + dir.z * axis[2].z; - index = ( FLOATSIGNBITSET( dy ) << 1 ) | FLOATSIGNBITSET( dz ); - dx = dir.x * cornerVecs[index].x + dir.y * cornerVecs[index].y + dir.z * cornerVecs[index].z; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - min = indexPoints[index] * dir; - index = ~index & 3; - dx = -dir.x * cornerVecs[index].x - dir.y * cornerVecs[index].y - dir.z * cornerVecs[index].z; - index |= ( FLOATSIGNBITSET( dx ) << 2 ); - max = indexPoints[index] * dir; -} - -/* -============ -idFrustum::AxisProjection - - 40 muls -============ -*/ -void idFrustum::AxisProjection( const idVec3 &dir, float &min, float &max ) const { - idVec3 indexPoints[8], cornerVecs[4]; - - ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - AxisProjection( indexPoints, cornerVecs, dir, min, max ); -} - -/* -============ -idFrustum::AxisProjection - - 76 muls -============ -*/ -void idFrustum::AxisProjection( const idMat3 &ax, idBounds &bounds ) const { - idVec3 indexPoints[8], cornerVecs[4]; - - ToIndexPointsAndCornerVecs( indexPoints, cornerVecs ); - AxisProjection( indexPoints, cornerVecs, ax[0], bounds[0][0], bounds[1][0] ); - AxisProjection( indexPoints, cornerVecs, ax[1], bounds[0][1], bounds[1][1] ); - AxisProjection( indexPoints, cornerVecs, ax[2], bounds[0][2], bounds[1][2] ); -} - -/* -============ -idFrustum::AddLocalLineToProjectionBoundsSetCull -============ -*/ -void idFrustum::AddLocalLineToProjectionBoundsSetCull( const idVec3 &start, const idVec3 &end, int &startCull, int &endCull, idBounds &bounds ) const { - idVec3 dir, p; - float d1, d2, fstart, fend, lstart, lend, f; - float leftScale, upScale; - int cull1, cull2; - -#ifdef FRUSTUM_DEBUG - static idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); - if ( r_showInteractionScissors.GetInteger() > 1 ) { - session->rw->DebugLine( colorGreen, origin + start * axis, origin + end * axis ); - } -#endif - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - dir = end - start; - - fstart = dFar * start.y; - fend = dFar * end.y; - lstart = dLeft * start.x; - lend = dLeft * end.x; - - // test left plane - d1 = -fstart + lstart; - d2 = -fend + lend; - cull1 = FLOATSIGNBITSET( d1 ); - cull2 = FLOATSIGNBITSET( d2 ); - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.z = start.z + f * dir.z; - if ( idMath::Fabs( p.z ) <= p.x * upScale ) { - p.y = 1.0f; - p.z = p.z * dFar / ( p.x * dUp ); - bounds.AddPoint( p ); - } - } - } - } - - // test right plane - d1 = fstart + lstart; - d2 = fend + lend; - cull1 |= FLOATSIGNBITSET( d1 ) << 1; - cull2 |= FLOATSIGNBITSET( d2 ) << 1; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.z = start.z + f * dir.z; - if ( idMath::Fabs( p.z ) <= p.x * upScale ) { - p.y = -1.0f; - p.z = p.z * dFar / ( p.x * dUp ); - bounds.AddPoint( p ); - } - } - } - } - - fstart = dFar * start.z; - fend = dFar * end.z; - lstart = dUp * start.x; - lend = dUp * end.x; - - // test up plane - d1 = -fstart + lstart; - d2 = -fend + lend; - cull1 |= FLOATSIGNBITSET( d1 ) << 2; - cull2 |= FLOATSIGNBITSET( d2 ) << 2; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.y = start.y + f * dir.y; - if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { - p.y = p.y * dFar / ( p.x * dLeft ); - p.z = 1.0f; - bounds.AddPoint( p ); - } - } - } - } - - // test down plane - d1 = fstart + lstart; - d2 = fend + lend; - cull1 |= FLOATSIGNBITSET( d1 ) << 3; - cull2 |= FLOATSIGNBITSET( d2 ) << 3; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.y = start.y + f * dir.y; - if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { - p.y = p.y * dFar / ( p.x * dLeft ); - p.z = -1.0f; - bounds.AddPoint( p ); - } - } - } - } - - if ( cull1 == 0 && start.x > 0.0f ) { - // add start point to projection bounds - p.x = start.x; - p.y = start.y * dFar / ( start.x * dLeft ); - p.z = start.z * dFar / ( start.x * dUp ); - bounds.AddPoint( p ); - } - - if ( cull2 == 0 && end.x > 0.0f ) { - // add end point to projection bounds - p.x = end.x; - p.y = end.y * dFar / ( end.x * dLeft ); - p.z = end.z * dFar / ( end.x * dUp ); - bounds.AddPoint( p ); - } - - if ( start.x < bounds[0].x ) { - bounds[0].x = start.x < 0.0f ? 0.0f : start.x; - } - if ( end.x < bounds[0].x ) { - bounds[0].x = end.x < 0.0f ? 0.0f : end.x; - } - - startCull = cull1; - endCull = cull2; -} - -/* -============ -idFrustum::AddLocalLineToProjectionBoundsUseCull -============ -*/ -void idFrustum::AddLocalLineToProjectionBoundsUseCull( const idVec3 &start, const idVec3 &end, int startCull, int endCull, idBounds &bounds ) const { - idVec3 dir, p; - float d1, d2, fstart, fend, lstart, lend, f; - float leftScale, upScale; - int clip; - - clip = startCull ^ endCull; - if ( !clip ) { - return; - } - -#ifdef FRUSTUM_DEBUG - static idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); - if ( r_showInteractionScissors.GetInteger() > 1 ) { - session->rw->DebugLine( colorGreen, origin + start * axis, origin + end * axis ); - } -#endif - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - dir = end - start; - - if ( clip & (1|2) ) { - - fstart = dFar * start.y; - fend = dFar * end.y; - lstart = dLeft * start.x; - lend = dLeft * end.x; - - if ( clip & 1 ) { - // test left plane - d1 = -fstart + lstart; - d2 = -fend + lend; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.z = start.z + f * dir.z; - if ( idMath::Fabs( p.z ) <= p.x * upScale ) { - p.y = 1.0f; - p.z = p.z * dFar / ( p.x * dUp ); - bounds.AddPoint( p ); - } - } - } - } - } - - if ( clip & 2 ) { - // test right plane - d1 = fstart + lstart; - d2 = fend + lend; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.z = start.z + f * dir.z; - if ( idMath::Fabs( p.z ) <= p.x * upScale ) { - p.y = -1.0f; - p.z = p.z * dFar / ( p.x * dUp ); - bounds.AddPoint( p ); - } - } - } - } - } - } - - if ( clip & (4|8) ) { - - fstart = dFar * start.z; - fend = dFar * end.z; - lstart = dUp * start.x; - lend = dUp * end.x; - - if ( clip & 4 ) { - // test up plane - d1 = -fstart + lstart; - d2 = -fend + lend; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.y = start.y + f * dir.y; - if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { - p.y = p.y * dFar / ( p.x * dLeft ); - p.z = 1.0f; - bounds.AddPoint( p ); - } - } - } - } - } - - if ( clip & 8 ) { - // test down plane - d1 = fstart + lstart; - d2 = fend + lend; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( p.x > 0.0f ) { - p.y = start.y + f * dir.y; - if ( idMath::Fabs( p.y ) <= p.x * leftScale ) { - p.y = p.y * dFar / ( p.x * dLeft ); - p.z = -1.0f; - bounds.AddPoint( p ); - } - } - } - } - } - } -} - -/* -============ -idFrustum::BoundsRayIntersection - - Returns true if the ray starts inside the bounds. - If there was an intersection scale1 <= scale2 -============ -*/ -bool idFrustum::BoundsRayIntersection( const idBounds &bounds, const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { - idVec3 end, p; - float d1, d2, f; - int i, startInside = 1; - - scale1 = idMath::INFINITY; - scale2 = -idMath::INFINITY; - - end = start + dir; - - for ( i = 0; i < 2; i++ ) { - d1 = start.x - bounds[i].x; - startInside &= FLOATSIGNBITSET( d1 ) ^ i; - d2 = end.x - bounds[i].x; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - p.y = start.y + f * dir.y; - if ( bounds[0].y <= p.y && p.y <= bounds[1].y ) { - p.z = start.z + f * dir.z; - if ( bounds[0].z <= p.z && p.z <= bounds[1].z ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - d1 = start.y - bounds[i].y; - startInside &= FLOATSIGNBITSET( d1 ) ^ i; - d2 = end.y - bounds[i].y; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( bounds[0].x <= p.x && p.x <= bounds[1].x ) { - p.z = start.z + f * dir.z; - if ( bounds[0].z <= p.z && p.z <= bounds[1].z ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - - d1 = start.z - bounds[i].z; - startInside &= FLOATSIGNBITSET( d1 ) ^ i; - d2 = end.z - bounds[i].z; - if ( d1 != d2 ) { - f = d1 / ( d1 - d2 ); - p.x = start.x + f * dir.x; - if ( bounds[0].x <= p.x && p.x <= bounds[1].x ) { - p.y = start.y + f * dir.y; - if ( bounds[0].y <= p.y && p.y <= bounds[1].y ) { - if ( f < scale1 ) scale1 = f; - if ( f > scale2 ) scale2 = f; - } - } - } - } - - return ( startInside != 0 ); -} - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idBounds &bounds, idBounds &projectionBounds ) const { - return ProjectionBounds( idBox( bounds, vec3_origin, mat3_identity ), projectionBounds ); -} - -#if !defined(__linux__) && !defined(MACOS_X) - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const { - int i, p1, p2, pointCull[8], culled, outside; - float scale1, scale2; - idFrustum localFrustum; - idVec3 points[8], localOrigin; - idMat3 localAxis, localScaled; - idBounds bounds( -box.GetExtents(), box.GetExtents() ); - - // if the frustum origin is inside the bounds - if ( bounds.ContainsPoint( ( origin - box.GetCenter() ) * box.GetAxis().Transpose() ) ) { - // bounds that cover the whole frustum - float boxMin, boxMax, base; - - base = origin * axis[0]; - box.AxisProjection( axis[0], boxMin, boxMax ); - - projectionBounds[0].x = boxMin - base; - projectionBounds[1].x = boxMax - base; - projectionBounds[0].y = projectionBounds[0].z = -1.0f; - projectionBounds[1].y = projectionBounds[1].z = 1.0f; - - return true; - } - - projectionBounds.Clear(); - - // transform the bounds into the space of this frustum - localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); - localAxis = box.GetAxis() * axis.Transpose(); - BoxToPoints( localOrigin, box.GetExtents(), localAxis, points ); - - // test outer four edges of the bounds - culled = -1; - outside = 0; - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = 4 + i; - AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - culled &= pointCull[p1] & pointCull[p2]; - outside |= pointCull[p1] | pointCull[p2]; - } - - // if the bounds are completely outside this frustum - if ( culled ) { - return false; - } - - // if the bounds are completely inside this frustum - if ( !outside ) { - return true; - } - - // test the remaining edges of the bounds - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = (i+1)&3; - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - for ( i = 0; i < 4; i++ ) { - p1 = 4 + i; - p2 = 4 + ((i+1)&3); - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - // if the bounds extend beyond two or more boundaries of this frustum - if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { - - localOrigin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); - localScaled = axis * box.GetAxis().Transpose(); - localScaled[0] *= dFar; - localScaled[1] *= dLeft; - localScaled[2] *= dUp; - - // test the outer edges of this frustum for intersection with the bounds - if ( (outside & 2) && (outside & 8) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); - } - } - if ( (outside & 2) && (outside & 4) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); - } - } - if ( (outside & 1) && (outside & 8) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); - } - } - if ( (outside & 1) && (outside & 2) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); - } - } - } - - return true; -} - -#endif - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idSphere &sphere, idBounds &projectionBounds ) const { - float d, r, rs, sFar; - idVec3 center; - - projectionBounds.Clear(); - - center = ( sphere.GetOrigin() - origin ) * axis.Transpose(); - r = sphere.GetRadius(); - rs = r * r; - sFar = dFar * dFar; - - // test left/right planes - d = dFar * idMath::Fabs( center.y ) - dLeft * center.x; - if ( ( d * d ) > rs * ( sFar + dLeft * dLeft ) ) { - return false; - } - - // test up/down planes - d = dFar * idMath::Fabs( center.z ) - dUp * center.x; - if ( ( d * d ) > rs * ( sFar + dUp * dUp ) ) { - return false; - } - - // bounds that cover the whole frustum - projectionBounds[0].x = 0.0f; - projectionBounds[1].x = dFar; - projectionBounds[0].y = projectionBounds[0].z = -1.0f; - projectionBounds[1].y = projectionBounds[1].z = 1.0f; - return true; -} - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idFrustum &frustum, idBounds &projectionBounds ) const { - int i, p1, p2, pointCull[8], culled, outside; - float scale1, scale2; - idFrustum localFrustum; - idVec3 points[8], localOrigin; - idMat3 localScaled; - - // if the frustum origin is inside the other frustum - if ( frustum.ContainsPoint( origin ) ) { - // bounds that cover the whole frustum - float frustumMin, frustumMax, base; - - base = origin * axis[0]; - frustum.AxisProjection( axis[0], frustumMin, frustumMax ); - - projectionBounds[0].x = frustumMin - base; - projectionBounds[1].x = frustumMax - base; - projectionBounds[0].y = projectionBounds[0].z = -1.0f; - projectionBounds[1].y = projectionBounds[1].z = 1.0f; - return true; - } - - projectionBounds.Clear(); - - // transform the given frustum into the space of this frustum - localFrustum = frustum; - localFrustum.origin = ( frustum.origin - origin ) * axis.Transpose(); - localFrustum.axis = frustum.axis * axis.Transpose(); - localFrustum.ToPoints( points ); - - // test outer four edges of the other frustum - culled = -1; - outside = 0; - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = 4 + i; - AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - culled &= pointCull[p1] & pointCull[p2]; - outside |= pointCull[p1] | pointCull[p2]; - } - - // if the other frustum is completely outside this frustum - if ( culled ) { - return false; - } - - // if the other frustum is completely inside this frustum - if ( !outside ) { - return true; - } - - // test the remaining edges of the other frustum - if ( localFrustum.dNear > 0.0f ) { - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = (i+1)&3; - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - } - - for ( i = 0; i < 4; i++ ) { - p1 = 4 + i; - p2 = 4 + ((i+1)&3); - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - // if the other frustum extends beyond two or more boundaries of this frustum - if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { - - localOrigin = ( origin - frustum.origin ) * frustum.axis.Transpose(); - localScaled = axis * frustum.axis.Transpose(); - localScaled[0] *= dFar; - localScaled[1] *= dLeft; - localScaled[2] *= dUp; - - // test the outer edges of this frustum for intersection with the other frustum - if ( (outside & 2) && (outside & 8) ) { - frustum.LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); - } - } - if ( (outside & 2) && (outside & 4) ) { - frustum.LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); - } - } - if ( (outside & 1) && (outside & 8) ) { - frustum.LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); - } - } - if ( (outside & 1) && (outside & 2) ) { - frustum.LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); - } - } - } - - return true; -} - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idWinding &winding, idBounds &projectionBounds ) const { - int i, p1, p2, *pointCull, culled, outside; - float scale; - idVec3 *localPoints; - idMat3 transpose, scaled; - idPlane plane; - - projectionBounds.Clear(); - - // transform the winding points into the space of this frustum - localPoints = (idVec3 *) _alloca16( winding.GetNumPoints() * sizeof( idVec3 ) ); - transpose = axis.Transpose(); - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - localPoints[i] = ( winding[i].ToVec3() - origin ) * transpose; - } - - // test the winding edges - culled = -1; - outside = 0; - pointCull = (int *) _alloca16( winding.GetNumPoints() * sizeof( int ) ); - for ( i = 0; i < winding.GetNumPoints(); i += 2 ) { - p1 = i; - p2 = (i+1)%winding.GetNumPoints(); - AddLocalLineToProjectionBoundsSetCull( localPoints[p1], localPoints[p2], pointCull[p1], pointCull[p2], projectionBounds ); - culled &= pointCull[p1] & pointCull[p2]; - outside |= pointCull[p1] | pointCull[p2]; - } - - // if completely culled - if ( culled ) { - return false; - } - - // if completely inside - if ( !outside ) { - return true; - } - - // test remaining winding edges - for ( i = 1; i < winding.GetNumPoints(); i += 2 ) { - p1 = i; - p2 = (i+1)%winding.GetNumPoints(); - AddLocalLineToProjectionBoundsUseCull( localPoints[p1], localPoints[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - // if the winding extends beyond two or more boundaries of this frustum - if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { - - winding.GetPlane( plane ); - scaled[0] = axis[0] * dFar; - scaled[1] = axis[1] * dLeft; - scaled[2] = axis[2] * dUp; - - // test the outer edges of this frustum for intersection with the winding - if ( (outside & 2) && (outside & 8) ) { - if ( winding.RayIntersection( plane, origin, scaled[0] - scaled[1] - scaled[2], scale ) ) { - projectionBounds.AddPoint( idVec3( scale * dFar, -1.0f, -1.0f ) ); - } - } - if ( (outside & 2) && (outside & 4) ) { - if ( winding.RayIntersection( plane, origin, scaled[0] - scaled[1] + scaled[2], scale ) ) { - projectionBounds.AddPoint( idVec3( scale * dFar, -1.0f, 1.0f ) ); - } - } - if ( (outside & 1) && (outside & 8) ) { - if ( winding.RayIntersection( plane, origin, scaled[0] + scaled[1] - scaled[2], scale ) ) { - projectionBounds.AddPoint( idVec3( scale * dFar, 1.0f, -1.0f ) ); - } - } - if ( (outside & 1) && (outside & 2) ) { - if ( winding.RayIntersection( plane, origin, scaled[0] + scaled[1] + scaled[2], scale ) ) { - projectionBounds.AddPoint( idVec3( scale * dFar, 1.0f, 1.0f ) ); - } - } - } - - return true; -} - -/* -============ -idFrustum::ClipFrustumToBox - - Clips the frustum far extents to the box. -============ -*/ -void idFrustum::ClipFrustumToBox( const idBox &box, float clipFractions[4], int clipPlanes[4] ) const { - int i, index; - float f, minf; - idMat3 scaled, localAxis, transpose; - idVec3 localOrigin, cornerVecs[4]; - idBounds bounds; - - transpose = box.GetAxis(); - transpose.TransposeSelf(); - localOrigin = ( origin - box.GetCenter() ) * transpose; - localAxis = axis * transpose; - - scaled[0] = localAxis[0] * dFar; - scaled[1] = localAxis[1] * dLeft; - scaled[2] = localAxis[2] * dUp; - cornerVecs[0] = scaled[0] + scaled[1]; - cornerVecs[1] = scaled[0] - scaled[1]; - cornerVecs[2] = cornerVecs[1] - scaled[2]; - cornerVecs[3] = cornerVecs[0] - scaled[2]; - cornerVecs[0] += scaled[2]; - cornerVecs[1] += scaled[2]; - - bounds[0] = -box.GetExtents(); - bounds[1] = box.GetExtents(); - - minf = ( dNear + 1.0f ) * invFar; - - for ( i = 0; i < 4; i++ ) { - - index = FLOATSIGNBITNOTSET( cornerVecs[i].x ); - f = ( bounds[index].x - localOrigin.x ) / cornerVecs[i].x; - clipFractions[i] = f; - clipPlanes[i] = 1 << index; - - index = FLOATSIGNBITNOTSET( cornerVecs[i].y ); - f = ( bounds[index].y - localOrigin.y ) / cornerVecs[i].y; - if ( f < clipFractions[i] ) { - clipFractions[i] = f; - clipPlanes[i] = 4 << index; - } - - index = FLOATSIGNBITNOTSET( cornerVecs[i].z ); - f = ( bounds[index].z - localOrigin.z ) / cornerVecs[i].z; - if ( f < clipFractions[i] ) { - clipFractions[i] = f; - clipPlanes[i] = 16 << index; - } - - // make sure the frustum is not clipped between the frustum origin and the near plane - if ( clipFractions[i] < minf ) { - clipFractions[i] = minf; - } - } -} - -/* -============ -idFrustum::ClipLine - - Returns true if part of the line is inside the frustum. - Does not clip to the near and far plane. -============ -*/ -bool idFrustum::ClipLine( const idVec3 localPoints[8], const idVec3 points[8], int startIndex, int endIndex, idVec3 &start, idVec3 &end, int &startClip, int &endClip ) const { - float d1, d2, fstart, fend, lstart, lend, f, x; - float leftScale, upScale; - float scale1, scale2; - int startCull, endCull; - idVec3 localStart, localEnd, localDir; - - leftScale = dLeft * invFar; - upScale = dUp * invFar; - - localStart = localPoints[startIndex]; - localEnd = localPoints[endIndex]; - localDir = localEnd - localStart; - - startClip = endClip = -1; - scale1 = idMath::INFINITY; - scale2 = -idMath::INFINITY; - - fstart = dFar * localStart.y; - fend = dFar * localEnd.y; - lstart = dLeft * localStart.x; - lend = dLeft * localEnd.x; - - // test left plane - d1 = -fstart + lstart; - d2 = -fend + lend; - startCull = FLOATSIGNBITSET( d1 ); - endCull = FLOATSIGNBITSET( d2 ); - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = localStart.x + f * localDir.x; - if ( x >= 0.0f ) { - if ( idMath::Fabs( localStart.z + f * localDir.z ) <= x * upScale ) { - if ( f < scale1 ) { scale1 = f; startClip = 0; } - if ( f > scale2 ) { scale2 = f; endClip = 0; } - } - } - } - } - - // test right plane - d1 = fstart + lstart; - d2 = fend + lend; - startCull |= FLOATSIGNBITSET( d1 ) << 1; - endCull |= FLOATSIGNBITSET( d2 ) << 1; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = localStart.x + f * localDir.x; - if ( x >= 0.0f ) { - if ( idMath::Fabs( localStart.z + f * localDir.z ) <= x * upScale ) { - if ( f < scale1 ) { scale1 = f; startClip = 1; } - if ( f > scale2 ) { scale2 = f; endClip = 1; } - } - } - } - } - - fstart = dFar * localStart.z; - fend = dFar * localEnd.z; - lstart = dUp * localStart.x; - lend = dUp * localEnd.x; - - // test up plane - d1 = -fstart + lstart; - d2 = -fend + lend; - startCull |= FLOATSIGNBITSET( d1 ) << 2; - endCull |= FLOATSIGNBITSET( d2 ) << 2; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = localStart.x + f * localDir.x; - if ( x >= 0.0f ) { - if ( idMath::Fabs( localStart.y + f * localDir.y ) <= x * leftScale ) { - if ( f < scale1 ) { scale1 = f; startClip = 2; } - if ( f > scale2 ) { scale2 = f; endClip = 2; } - } - } - } - } - - // test down plane - d1 = fstart + lstart; - d2 = fend + lend; - startCull |= FLOATSIGNBITSET( d1 ) << 3; - endCull |= FLOATSIGNBITSET( d2 ) << 3; - if ( FLOATNOTZERO( d1 ) ) { - if ( FLOATSIGNBITSET( d1 ) ^ FLOATSIGNBITSET( d2 ) ) { - f = d1 / ( d1 - d2 ); - x = localStart.x + f * localDir.x; - if ( x >= 0.0f ) { - if ( idMath::Fabs( localStart.y + f * localDir.y ) <= x * leftScale ) { - if ( f < scale1 ) { scale1 = f; startClip = 3; } - if ( f > scale2 ) { scale2 = f; endClip = 3; } - } - } - } - } - - // if completely inside - if ( !( startCull | endCull ) ) { - start = points[startIndex]; - end = points[endIndex]; - return true; - } - else if ( scale1 <= scale2 ) { - if ( !startCull ) { - start = points[startIndex]; - startClip = -1; - } - else { - start = points[startIndex] + scale1 * ( points[endIndex] - points[startIndex] ); - } - if ( !endCull ) { - end = points[endIndex]; - endClip = -1; - } - else { - end = points[startIndex] + scale2 * ( points[endIndex] - points[startIndex] ); - } - return true; - } - return false; -} - -/* -============ -idFrustum::AddLocalCapsToProjectionBounds -============ -*/ -static int capPointIndex[4][2] = { - { 0, 3 }, - { 1, 2 }, - { 0, 1 }, - { 2, 3 } -}; - -ID_INLINE bool idFrustum::AddLocalCapsToProjectionBounds( const idVec3 endPoints[4], const int endPointCull[4], const idVec3 &point, int pointCull, int pointClip, idBounds &projectionBounds ) const { - int *p; - - if ( pointClip < 0 ) { - return false; - } - p = capPointIndex[pointClip]; - AddLocalLineToProjectionBoundsUseCull( endPoints[p[0]], point, endPointCull[p[0]], pointCull, projectionBounds ); - AddLocalLineToProjectionBoundsUseCull( endPoints[p[1]], point, endPointCull[p[1]], pointCull, projectionBounds ); - return true; -} - -/* -============ -idFrustum::ClippedProjectionBounds -============ -*/ -bool idFrustum::ClippedProjectionBounds( const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds ) const { - int i, p1, p2, clipPointCull[8], clipPlanes[4], usedClipPlanes, nearCull, farCull, outside; - int pointCull[2], startClip, endClip, boxPointCull[8]; - float clipFractions[4], s1, s2, t1, t2, leftScale, upScale; - idFrustum localFrustum; - idVec3 clipPoints[8], localPoints1[8], localPoints2[8], localOrigin1, localOrigin2, start, end; - idMat3 localAxis1, localAxis2, transpose; - idBounds clipBounds; - - // if the frustum origin is inside the other frustum - if ( frustum.ContainsPoint( origin ) ) { - // bounds that cover the whole frustum - float clipBoxMin, clipBoxMax, frustumMin, frustumMax, base; - - base = origin * axis[0]; - clipBox.AxisProjection( axis[0], clipBoxMin, clipBoxMax ); - frustum.AxisProjection( axis[0], frustumMin, frustumMax ); - - projectionBounds[0].x = Max( clipBoxMin, frustumMin ) - base; - projectionBounds[1].x = Min( clipBoxMax, frustumMax ) - base; - projectionBounds[0].y = projectionBounds[0].z = -1.0f; - projectionBounds[1].y = projectionBounds[1].z = 1.0f; - return true; - } - - projectionBounds.Clear(); - - // clip the outer edges of the given frustum to the clip bounds - frustum.ClipFrustumToBox( clipBox, clipFractions, clipPlanes ); - usedClipPlanes = clipPlanes[0] | clipPlanes[1] | clipPlanes[2] | clipPlanes[3]; - - // transform the clipped frustum to the space of this frustum - transpose = axis; - transpose.TransposeSelf(); - localFrustum = frustum; - localFrustum.origin = ( frustum.origin - origin ) * transpose; - localFrustum.axis = frustum.axis * transpose; - localFrustum.ToClippedPoints( clipFractions, clipPoints ); - - // test outer four edges of the clipped frustum - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = 4 + i; - AddLocalLineToProjectionBoundsSetCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); - } - - // get cull bits for the clipped frustum - outside = clipPointCull[0] | clipPointCull[1] | clipPointCull[2] | clipPointCull[3] | - clipPointCull[4] | clipPointCull[5] | clipPointCull[6] | clipPointCull[7]; - nearCull = clipPointCull[0] & clipPointCull[1] & clipPointCull[2] & clipPointCull[3]; - farCull = clipPointCull[4] & clipPointCull[5] & clipPointCull[6] & clipPointCull[7]; - - // if the clipped frustum is not completely inside this frustum - if ( outside ) { - - // test the remaining edges of the clipped frustum - if ( !nearCull && localFrustum.dNear > 0.0f ) { - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = (i+1)&3; - AddLocalLineToProjectionBoundsUseCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); - } - } - - if ( !farCull ) { - for ( i = 0; i < 4; i++ ) { - p1 = 4 + i; - p2 = 4 + ((i+1)&3); - AddLocalLineToProjectionBoundsUseCull( clipPoints[p1], clipPoints[p2], clipPointCull[p1], clipPointCull[p2], projectionBounds ); - } - } - } - - // if the clipped frustum far end points are inside this frustum - if ( !( farCull && !( nearCull & farCull ) ) && - // if the clipped frustum is not clipped to a single plane of the clip bounds - ( clipPlanes[0] != clipPlanes[1] || clipPlanes[1] != clipPlanes[2] || clipPlanes[2] != clipPlanes[3] ) ) { - - // transform the clip box into the space of the other frustum - transpose = frustum.axis; - transpose.TransposeSelf(); - localOrigin1 = ( clipBox.GetCenter() - frustum.origin ) * transpose; - localAxis1 = clipBox.GetAxis() * transpose; - BoxToPoints( localOrigin1, clipBox.GetExtents(), localAxis1, localPoints1 ); - - // cull the box corners with the other frustum - leftScale = frustum.dLeft * frustum.invFar; - upScale = frustum.dUp * frustum.invFar; - for ( i = 0; i < 8; i++ ) { - idVec3 &p = localPoints1[i]; - if ( !( boxVertPlanes[i] & usedClipPlanes ) || p.x <= 0.0f ) { - boxPointCull[i] = 1|2|4|8; - } - else { - boxPointCull[i] = 0; - if ( idMath::Fabs( p.y ) > p.x * leftScale ) { - boxPointCull[i] |= 1 << FLOATSIGNBITSET( p.y ); - } - if ( idMath::Fabs( p.z ) > p.x * upScale ) { - boxPointCull[i] |= 4 << FLOATSIGNBITSET( p.z ); - } - } - } - - // transform the clip box into the space of this frustum - transpose = axis; - transpose.TransposeSelf(); - localOrigin2 = ( clipBox.GetCenter() - origin ) * transpose; - localAxis2 = clipBox.GetAxis() * transpose; - BoxToPoints( localOrigin2, clipBox.GetExtents(), localAxis2, localPoints2 ); - - // clip the edges of the clip bounds to the other frustum and add the clipped edges to the projection bounds - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = 4 + i; - if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { - if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { - AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); - outside |= pointCull[0] | pointCull[1]; - } - } - } - - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = (i+1)&3; - if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { - if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { - AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); - outside |= pointCull[0] | pointCull[1]; - } - } - } - - for ( i = 0; i < 4; i++ ) { - p1 = 4 + i; - p2 = 4 + ((i+1)&3); - if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) { - if ( frustum.ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) { - AddLocalLineToProjectionBoundsSetCull( start, end, pointCull[0], pointCull[1], projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, start, pointCull[0], startClip, projectionBounds ); - AddLocalCapsToProjectionBounds( clipPoints+4, clipPointCull+4, end, pointCull[1], endClip, projectionBounds ); - outside |= pointCull[0] | pointCull[1]; - } - } - } - } - - // if the clipped frustum extends beyond two or more boundaries of this frustum - if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { - - // transform this frustum into the space of the other frustum - transpose = frustum.axis; - transpose.TransposeSelf(); - localOrigin1 = ( origin - frustum.origin ) * transpose; - localAxis1 = axis * transpose; - localAxis1[0] *= dFar; - localAxis1[1] *= dLeft; - localAxis1[2] *= dUp; - - // transform this frustum into the space of the clip bounds - transpose = clipBox.GetAxis(); - transpose.TransposeSelf(); - localOrigin2 = ( origin - clipBox.GetCenter() ) * transpose; - localAxis2 = axis * transpose; - localAxis2[0] *= dFar; - localAxis2[1] *= dLeft; - localAxis2[2] *= dUp; - - clipBounds[0] = -clipBox.GetExtents(); - clipBounds[1] = clipBox.GetExtents(); - - // test the outer edges of this frustum for intersection with both the other frustum and the clip bounds - if ( (outside & 2) && (outside & 8) ) { - frustum.LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] - localAxis1[2], s1, s2 ); - if ( s1 <= s2 && s1 >= 0.0f ) { - BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] - localAxis2[2], t1, t2 ); - if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { - projectionBounds.AddPoint( idVec3( s1 * dFar, -1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( s2 * dFar, -1.0f, -1.0f ) ); - } - } - } - if ( (outside & 2) && (outside & 4) ) { - frustum.LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] + localAxis1[2], s1, s2 ); - if ( s1 <= s2 && s1 >= 0.0f ) { - BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] + localAxis2[2], t1, t2 ); - if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { - projectionBounds.AddPoint( idVec3( s1 * dFar, -1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( s2 * dFar, -1.0f, 1.0f ) ); - } - } - } - if ( (outside & 1) && (outside & 8) ) { - frustum.LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] - localAxis1[2], s1, s2 ); - if ( s1 <= s2 && s1 >= 0.0f ) { - BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] - localAxis2[2], t1, t2 ); - if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { - projectionBounds.AddPoint( idVec3( s1 * dFar, 1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( s2 * dFar, 1.0f, -1.0f ) ); - } - } - } - if ( (outside & 1) && (outside & 2) ) { - frustum.LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] + localAxis1[2], s1, s2 ); - if ( s1 <= s2 && s1 >= 0.0f ) { - BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] + localAxis2[2], t1, t2 ); - if ( t1 <= t2 && t2 > s1 && t1 < s2 ) { - projectionBounds.AddPoint( idVec3( s1 * dFar, 1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( s2 * dFar, 1.0f, 1.0f ) ); - } - } - } - } - - return true; -} diff --git a/idlib/bv/frustum.h b/idlib/bv/frustum.h deleted file mode 100644 index e22a974f0..000000000 --- a/idlib/bv/frustum.h +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BV_FRUSTUM_H__ -#define __BV_FRUSTUM_H__ - -#ifdef __linux__ -#include -#endif - -/* -=============================================================================== - - Orthogonal Frustum - -=============================================================================== -*/ - -class idFrustum { -public: - idFrustum( void ); - - void SetOrigin( const idVec3 &origin ); - void SetAxis( const idMat3 &axis ); - void SetSize( float dNear, float dFar, float dLeft, float dUp ); - void SetPyramid( float dNear, float dFar ); - void MoveNearDistance( float dNear ); - void MoveFarDistance( float dFar ); - - const idVec3 & GetOrigin( void ) const; // returns frustum origin - const idMat3 & GetAxis( void ) const; // returns frustum orientation - idVec3 GetCenter( void ) const; // returns center of frustum - - bool IsValid( void ) const; // returns true if the frustum is valid - float GetNearDistance( void ) const; // returns distance to near plane - float GetFarDistance( void ) const; // returns distance to far plane - float GetLeft( void ) const; // returns left vector length - float GetUp( void ) const; // returns up vector length - - idFrustum Expand( const float d ) const; // returns frustum expanded in all directions with the given value - idFrustum & ExpandSelf( const float d ); // expands frustum in all directions with the given value - idFrustum Translate( const idVec3 &translation ) const; // returns translated frustum - idFrustum & TranslateSelf( const idVec3 &translation ); // translates frustum - idFrustum Rotate( const idMat3 &rotation ) const; // returns rotated frustum - idFrustum & RotateSelf( const idMat3 &rotation ); // rotates frustum - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - // fast culling but might not cull everything outside the frustum - bool CullPoint( const idVec3 &point ) const; - bool CullBounds( const idBounds &bounds ) const; - bool CullBox( const idBox &box ) const; - bool CullSphere( const idSphere &sphere ) const; - bool CullFrustum( const idFrustum &frustum ) const; - bool CullWinding( const class idWinding &winding ) const; - - // exact intersection tests - bool ContainsPoint( const idVec3 &point ) const; - bool IntersectsBounds( const idBounds &bounds ) const; - bool IntersectsBox( const idBox &box ) const; - bool IntersectsSphere( const idSphere &sphere ) const; - bool IntersectsFrustum( const idFrustum &frustum ) const; - bool IntersectsWinding( const idWinding &winding ) const; - bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; - - // returns true if the projection origin is far enough away from the bounding volume to create a valid frustum - bool FromProjection( const idBounds &bounds, const idVec3 &projectionOrigin, const float dFar ); - bool FromProjection( const idBox &box, const idVec3 &projectionOrigin, const float dFar ); - bool FromProjection( const idSphere &sphere, const idVec3 &projectionOrigin, const float dFar ); - - // moves the far plane so it extends just beyond the bounding volume - bool ConstrainToBounds( const idBounds &bounds ); - bool ConstrainToBox( const idBox &box ); - bool ConstrainToSphere( const idSphere &sphere ); - bool ConstrainToFrustum( const idFrustum &frustum ); - - void ToPlanes( idPlane planes[6] ) const; // planes point outwards - void ToPoints( idVec3 points[8] ) const; // 8 corners of the frustum - - // calculates the projection of this frustum onto the given axis - void AxisProjection( const idVec3 &dir, float &min, float &max ) const; - void AxisProjection( const idMat3 &ax, idBounds &bounds ) const; - - // calculates the bounds for the projection in this frustum - bool ProjectionBounds( const idBounds &bounds, idBounds &projectionBounds ) const; - bool ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const; - bool ProjectionBounds( const idSphere &sphere, idBounds &projectionBounds ) const; - bool ProjectionBounds( const idFrustum &frustum, idBounds &projectionBounds ) const; - bool ProjectionBounds( const idWinding &winding, idBounds &projectionBounds ) const; - - // calculates the bounds for the projection in this frustum of the given frustum clipped to the given box - bool ClippedProjectionBounds( const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds ) const; - -private: - idVec3 origin; // frustum origin - idMat3 axis; // frustum orientation - float dNear; // distance of near plane, dNear >= 0.0f - float dFar; // distance of far plane, dFar > dNear - float dLeft; // half the width at the far plane - float dUp; // half the height at the far plane - float invFar; // 1.0f / dFar - -private: - bool CullLocalBox( const idVec3 &localOrigin, const idVec3 &extents, const idMat3 &localAxis ) const; - bool CullLocalFrustum( const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const; - bool CullLocalWinding( const idVec3 *points, const int numPoints, int *pointCull ) const; - bool BoundsCullLocalFrustum( const idBounds &bounds, const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4] ) const; - bool LocalLineIntersection( const idVec3 &start, const idVec3 &end ) const; - bool LocalRayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; - bool LocalFrustumIntersectsFrustum( const idVec3 points[8], const bool testFirstSide ) const; - bool LocalFrustumIntersectsBounds( const idVec3 points[8], const idBounds &bounds ) const; - void ToClippedPoints( const float fractions[4], idVec3 points[8] ) const; - void ToIndexPoints( idVec3 indexPoints[8] ) const; - void ToIndexPointsAndCornerVecs( idVec3 indexPoints[8], idVec3 cornerVecs[4] ) const; - void AxisProjection( const idVec3 indexPoints[8], const idVec3 cornerVecs[4], const idVec3 &dir, float &min, float &max ) const; - void AddLocalLineToProjectionBoundsSetCull( const idVec3 &start, const idVec3 &end, int &startCull, int &endCull, idBounds &bounds ) const; - void AddLocalLineToProjectionBoundsUseCull( const idVec3 &start, const idVec3 &end, int startCull, int endCull, idBounds &bounds ) const; - bool AddLocalCapsToProjectionBounds( const idVec3 endPoints[4], const int endPointCull[4], const idVec3 &point, int pointCull, int pointClip, idBounds &projectionBounds ) const; - bool BoundsRayIntersection( const idBounds &bounds, const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; - void ClipFrustumToBox( const idBox &box, float clipFractions[4], int clipPlanes[4] ) const; - bool ClipLine( const idVec3 localPoints[8], const idVec3 points[8], int startIndex, int endIndex, idVec3 &start, idVec3 &end, int &startClip, int &endClip ) const; -}; - - -ID_INLINE idFrustum::idFrustum( void ) { - dNear = dFar = 0.0f; -} - -ID_INLINE void idFrustum::SetOrigin( const idVec3 &origin ) { - this->origin = origin; -} - -ID_INLINE void idFrustum::SetAxis( const idMat3 &axis ) { - this->axis = axis; -} - -ID_INLINE void idFrustum::SetSize( float dNear, float dFar, float dLeft, float dUp ) { - assert( dNear >= 0.0f && dFar > dNear && dLeft > 0.0f && dUp > 0.0f ); - this->dNear = dNear; - this->dFar = dFar; - this->dLeft = dLeft; - this->dUp = dUp; - this->invFar = 1.0f / dFar; -} - -ID_INLINE void idFrustum::SetPyramid( float dNear, float dFar ) { - assert( dNear >= 0.0f && dFar > dNear ); - this->dNear = dNear; - this->dFar = dFar; - this->dLeft = dFar; - this->dUp = dFar; - this->invFar = 1.0f / dFar; -} - -ID_INLINE void idFrustum::MoveNearDistance( float dNear ) { - assert( dNear >= 0.0f ); - this->dNear = dNear; -} - -ID_INLINE void idFrustum::MoveFarDistance( float dFar ) { - assert( dFar > this->dNear ); - float scale = dFar / this->dFar; - this->dFar = dFar; - this->dLeft *= scale; - this->dUp *= scale; - this->invFar = 1.0f / dFar; -} - -ID_INLINE const idVec3 &idFrustum::GetOrigin( void ) const { - return origin; -} - -ID_INLINE const idMat3 &idFrustum::GetAxis( void ) const { - return axis; -} - -ID_INLINE idVec3 idFrustum::GetCenter( void ) const { - return ( origin + axis[0] * ( ( dFar - dNear ) * 0.5f ) ); -} - -ID_INLINE bool idFrustum::IsValid( void ) const { - return ( dFar > dNear ); -} - -ID_INLINE float idFrustum::GetNearDistance( void ) const { - return dNear; -} - -ID_INLINE float idFrustum::GetFarDistance( void ) const { - return dFar; -} - -ID_INLINE float idFrustum::GetLeft( void ) const { - return dLeft; -} - -ID_INLINE float idFrustum::GetUp( void ) const { - return dUp; -} - -ID_INLINE idFrustum idFrustum::Expand( const float d ) const { - idFrustum f = *this; - f.origin -= d * f.axis[0]; - f.dFar += 2.0f * d; - f.dLeft = f.dFar * dLeft * invFar; - f.dUp = f.dFar * dUp * invFar; - f.invFar = 1.0f / dFar; - return f; -} - -ID_INLINE idFrustum &idFrustum::ExpandSelf( const float d ) { - origin -= d * axis[0]; - dFar += 2.0f * d; - dLeft = dFar * dLeft * invFar; - dUp = dFar * dUp * invFar; - invFar = 1.0f / dFar; - return *this; -} - -ID_INLINE idFrustum idFrustum::Translate( const idVec3 &translation ) const { - idFrustum f = *this; - f.origin += translation; - return f; -} - -ID_INLINE idFrustum &idFrustum::TranslateSelf( const idVec3 &translation ) { - origin += translation; - return *this; -} - -ID_INLINE idFrustum idFrustum::Rotate( const idMat3 &rotation ) const { - idFrustum f = *this; - f.axis *= rotation; - return f; -} - -ID_INLINE idFrustum &idFrustum::RotateSelf( const idMat3 &rotation ) { - axis *= rotation; - return *this; -} - -#endif /* !__BV_FRUSTUM_H__ */ diff --git a/idlib/bv/frustum_gcc.cpp b/idlib/bv/frustum_gcc.cpp deleted file mode 100644 index 7bc9d9206..000000000 --- a/idlib/bv/frustum_gcc.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../precompiled.h" - -static bool init_version = FileVersionList("$Id$", init_version); - -void BoxToPoints( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis, idVec3 points[8] ); - -/* -============ -idFrustum::ProjectionBounds -============ -*/ -bool idFrustum::ProjectionBounds( const idBox &box, idBounds &projectionBounds ) const { - int i, p1, p2, pointCull[8], culled, outside; - float scale1, scale2; - idFrustum localFrustum; - idVec3 points[8], localOrigin; - idMat3 localAxis, localScaled; - idBounds bounds( -box.GetExtents(), box.GetExtents() ); - - // if the frustum origin is inside the bounds - if ( bounds.ContainsPoint( ( origin - box.GetCenter() ) * box.GetAxis().Transpose() ) ) { - // bounds that cover the whole frustum - float boxMin, boxMax, base; - - base = origin * axis[0]; - box.AxisProjection( axis[0], boxMin, boxMax ); - - projectionBounds[0].x = boxMin - base; - projectionBounds[1].x = boxMax - base; - projectionBounds[0].y = projectionBounds[0].z = -1.0f; - projectionBounds[1].y = projectionBounds[1].z = 1.0f; - - return true; - } - - projectionBounds.Clear(); - - // transform the bounds into the space of this frustum - localOrigin = ( box.GetCenter() - origin ) * axis.Transpose(); - localAxis = box.GetAxis() * axis.Transpose(); - BoxToPoints( localOrigin, box.GetExtents(), localAxis, points ); - - // test outer four edges of the bounds - culled = -1; - outside = 0; - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = 4 + i; - AddLocalLineToProjectionBoundsSetCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - culled &= pointCull[p1] & pointCull[p2]; - outside |= pointCull[p1] | pointCull[p2]; - } - - // if the bounds are completely outside this frustum - if ( culled ) { - return false; - } - - // if the bounds are completely inside this frustum - if ( !outside ) { - return true; - } - - // test the remaining edges of the bounds - for ( i = 0; i < 4; i++ ) { - p1 = i; - p2 = (i+1)&3; - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - for ( i = 0; i < 4; i++ ) { - p1 = 4 + i; - p2 = 4 + ((i+1)&3); - AddLocalLineToProjectionBoundsUseCull( points[p1], points[p2], pointCull[p1], pointCull[p2], projectionBounds ); - } - - // if the bounds extend beyond two or more boundaries of this frustum - if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) { - - localOrigin = ( origin - box.GetCenter() ) * box.GetAxis().Transpose(); - localScaled = axis * box.GetAxis().Transpose(); - localScaled[0] *= dFar; - localScaled[1] *= dLeft; - localScaled[2] *= dUp; - - // test the outer edges of this frustum for intersection with the bounds - if ( (outside & 2) && (outside & 8) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, -1.0f ) ); - } - } - if ( (outside & 2) && (outside & 4) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, -1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, -1.0f, 1.0f ) ); - } - } - if ( (outside & 1) && (outside & 8) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, -1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, -1.0f ) ); - } - } - if ( (outside & 1) && (outside & 2) ) { - BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 ); - if ( scale1 <= scale2 && scale1 >= 0.0f ) { - projectionBounds.AddPoint( idVec3( scale1 * dFar, 1.0f, 1.0f ) ); - projectionBounds.AddPoint( idVec3( scale2 * dFar, 1.0f, 1.0f ) ); - } - } - } - - return true; -} diff --git a/idlib/bv/sphere.cpp b/idlib/bv/sphere.cpp deleted file mode 100644 index 9c8bd5716..000000000 --- a/idlib/bv/sphere.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idSphere sphere_zero( vec3_zero, 0.0f ); - - -/* -================ -idSphere::PlaneDistance -================ -*/ -float idSphere::PlaneDistance( const idPlane &plane ) const { - float d; - - d = plane.Distance( origin ); - if ( d > radius ) { - return d - radius; - } - if ( d < -radius ) { - return d + radius; - } - return 0.0f; -} - -/* -================ -idSphere::PlaneSide -================ -*/ -int idSphere::PlaneSide( const idPlane &plane, const float epsilon ) const { - float d; - - d = plane.Distance( origin ); - if ( d > radius + epsilon ) { - return PLANESIDE_FRONT; - } - if ( d < -radius - epsilon ) { - return PLANESIDE_BACK; - } - return PLANESIDE_CROSS; -} - -/* -============ -idSphere::LineIntersection - - Returns true if the line intersects the sphere between the start and end point. -============ -*/ -bool idSphere::LineIntersection( const idVec3 &start, const idVec3 &end ) const { - idVec3 r, s, e; - float a; - - s = start - origin; - e = end - origin; - r = e - s; - a = -s * r; - if ( a <= 0 ) { - return ( s * s < radius * radius ); - } - else if ( a >= r * r ) { - return ( e * e < radius * radius ); - } - else { - r = s + ( a / ( r * r ) ) * r; - return ( r * r < radius * radius ); - } -} - -/* -============ -idSphere::RayIntersection - - Returns true if the ray intersects the sphere. - The ray can intersect the sphere in both directions from the start point. - If start is inside the sphere then scale1 < 0 and scale2 > 0. -============ -*/ -bool idSphere::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const { - double a, b, c, d, sqrtd; - idVec3 p; - - p = start - origin; - a = dir * dir; - b = dir * p; - c = p * p - radius * radius; - d = b * b - c * a; - - if ( d < 0.0f ) { - return false; - } - - sqrtd = idMath::Sqrt( d ); - a = 1.0f / a; - - scale1 = ( -b + sqrtd ) * a; - scale2 = ( -b - sqrtd ) * a; - - return true; -} - -/* -============ -idSphere::FromPoints - - Tight sphere for a point set. -============ -*/ -void idSphere::FromPoints( const idVec3 *points, const int numPoints ) { - int i; - float radiusSqr, dist; - idVec3 mins, maxs; - - SIMDProcessor->MinMax( mins, maxs, points, numPoints ); - - origin = ( mins + maxs ) * 0.5f; - - radiusSqr = 0.0f; - for ( i = 0; i < numPoints; i++ ) { - dist = ( points[i] - origin ).LengthSqr(); - if ( dist > radiusSqr ) { - radiusSqr = dist; - } - } - radius = idMath::Sqrt( radiusSqr ); -} diff --git a/idlib/bv/sphere.h b/idlib/bv/sphere.h deleted file mode 100644 index c3ac62774..000000000 --- a/idlib/bv/sphere.h +++ /dev/null @@ -1,259 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BV_SPHERE_H__ -#define __BV_SPHERE_H__ - -/* -=============================================================================== - - Sphere - -=============================================================================== -*/ - -class idSphere { -public: - idSphere( void ); - explicit idSphere( const idVec3 &point ); - explicit idSphere( const idVec3 &point, const float r ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idSphere operator+( const idVec3 &t ) const; // returns tranlated sphere - idSphere & operator+=( const idVec3 &t ); // translate the sphere - idSphere operator+( const idSphere &s ) const; - idSphere & operator+=( const idSphere &s ); - - bool Compare( const idSphere &a ) const; // exact compare, no epsilon - bool Compare( const idSphere &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idSphere &a ) const; // exact compare, no epsilon - bool operator!=( const idSphere &a ) const; // exact compare, no epsilon - - void Clear( void ); // inside out sphere - void Zero( void ); // single point at origin - void SetOrigin( const idVec3 &o ); // set origin of sphere - void SetRadius( const float r ); // set square radius - - const idVec3 & GetOrigin( void ) const; // returns origin of sphere - float GetRadius( void ) const; // returns sphere radius - bool IsCleared( void ) const; // returns true if sphere is inside out - - bool AddPoint( const idVec3 &p ); // add the point, returns true if the sphere expanded - bool AddSphere( const idSphere &s ); // add the sphere, returns true if the sphere expanded - idSphere Expand( const float d ) const; // return bounds expanded in all directions with the given value - idSphere & ExpandSelf( const float d ); // expand bounds in all directions with the given value - idSphere Translate( const idVec3 &translation ) const; - idSphere & TranslateSelf( const idVec3 &translation ); - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - bool ContainsPoint( const idVec3 &p ) const; // includes touching - bool IntersectsSphere( const idSphere &s ) const; // includes touching - bool LineIntersection( const idVec3 &start, const idVec3 &end ) const; - // intersection points are (start + dir * scale1) and (start + dir * scale2) - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const; - - // Tight sphere for a point set. - void FromPoints( const idVec3 *points, const int numPoints ); - // Most tight sphere for a translation. - void FromPointTranslation( const idVec3 &point, const idVec3 &translation ); - void FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation ); - // Most tight sphere for a rotation. - void FromPointRotation( const idVec3 &point, const idRotation &rotation ); - void FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation ); - - void AxisProjection( const idVec3 &dir, float &min, float &max ) const; - -private: - idVec3 origin; - float radius; -}; - -extern idSphere sphere_zero; - -ID_INLINE idSphere::idSphere( void ) { -} - -ID_INLINE idSphere::idSphere( const idVec3 &point ) { - origin = point; - radius = 0.0f; -} - -ID_INLINE idSphere::idSphere( const idVec3 &point, const float r ) { - origin = point; - radius = r; -} - -ID_INLINE float idSphere::operator[]( const int index ) const { - return ((float *) &origin)[index]; -} - -ID_INLINE float &idSphere::operator[]( const int index ) { - return ((float *) &origin)[index]; -} - -ID_INLINE idSphere idSphere::operator+( const idVec3 &t ) const { - return idSphere( origin + t, radius ); -} - -ID_INLINE idSphere &idSphere::operator+=( const idVec3 &t ) { - origin += t; - return *this; -} - -ID_INLINE bool idSphere::Compare( const idSphere &a ) const { - return ( origin.Compare( a.origin ) && radius == a.radius ); -} - -ID_INLINE bool idSphere::Compare( const idSphere &a, const float epsilon ) const { - return ( origin.Compare( a.origin, epsilon ) && idMath::Fabs( radius - a.radius ) <= epsilon ); -} - -ID_INLINE bool idSphere::operator==( const idSphere &a ) const { - return Compare( a ); -} - -ID_INLINE bool idSphere::operator!=( const idSphere &a ) const { - return !Compare( a ); -} - -ID_INLINE void idSphere::Clear( void ) { - origin.Zero(); - radius = -1.0f; -} - -ID_INLINE void idSphere::Zero( void ) { - origin.Zero(); - radius = 0.0f; -} - -ID_INLINE void idSphere::SetOrigin( const idVec3 &o ) { - origin = o; -} - -ID_INLINE void idSphere::SetRadius( const float r ) { - radius = r; -} - -ID_INLINE const idVec3 &idSphere::GetOrigin( void ) const { - return origin; -} - -ID_INLINE float idSphere::GetRadius( void ) const { - return radius; -} - -ID_INLINE bool idSphere::IsCleared( void ) const { - return ( radius < 0.0f ); -} - -ID_INLINE bool idSphere::AddPoint( const idVec3 &p ) { - if ( radius < 0.0f ) { - origin = p; - radius = 0.0f; - return true; - } - else { - float r = ( p - origin ).LengthSqr(); - if ( r > radius * radius ) { - r = idMath::Sqrt( r ); - origin += ( p - origin ) * 0.5f * (1.0f - radius / r ); - radius += 0.5f * ( r - radius ); - return true; - } - return false; - } -} - -ID_INLINE bool idSphere::AddSphere( const idSphere &s ) { - if ( radius < 0.0f ) { - origin = s.origin; - radius = s.radius; - return true; - } - else { - float r = ( s.origin - origin ).LengthSqr(); - if ( r > ( radius + s.radius ) * ( radius + s.radius ) ) { - r = idMath::Sqrt( r ); - origin += ( s.origin - origin ) * 0.5f * (1.0f - radius / ( r + s.radius ) ); - radius += 0.5f * ( ( r + s.radius ) - radius ); - return true; - } - return false; - } -} - -ID_INLINE idSphere idSphere::Expand( const float d ) const { - return idSphere( origin, radius + d ); -} - -ID_INLINE idSphere &idSphere::ExpandSelf( const float d ) { - radius += d; - return *this; -} - -ID_INLINE idSphere idSphere::Translate( const idVec3 &translation ) const { - return idSphere( origin + translation, radius ); -} - -ID_INLINE idSphere &idSphere::TranslateSelf( const idVec3 &translation ) { - origin += translation; - return *this; -} - -ID_INLINE bool idSphere::ContainsPoint( const idVec3 &p ) const { - if ( ( p - origin ).LengthSqr() > radius * radius ) { - return false; - } - return true; -} - -ID_INLINE bool idSphere::IntersectsSphere( const idSphere &s ) const { - float r = s.radius + radius; - if ( ( s.origin - origin ).LengthSqr() > r * r ) { - return false; - } - return true; -} - -ID_INLINE void idSphere::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) { - origin = point + 0.5f * translation; - radius = idMath::Sqrt( 0.5f * translation.LengthSqr() ); -} - -ID_INLINE void idSphere::FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation ) { - origin = start + sphere.origin + 0.5f * translation; - radius = idMath::Sqrt( 0.5f * translation.LengthSqr() ) + sphere.radius; -} - -ID_INLINE void idSphere::FromPointRotation( const idVec3 &point, const idRotation &rotation ) { - idVec3 end = rotation * point; - origin = ( point + end ) * 0.5f; - radius = idMath::Sqrt( 0.5f * ( end - point ).LengthSqr() ); -} - -ID_INLINE void idSphere::FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation ) { - idVec3 end = rotation * sphere.origin; - origin = start + ( sphere.origin + end ) * 0.5f; - radius = idMath::Sqrt( 0.5f * ( end - sphere.origin ).LengthSqr() ) + sphere.radius; -} - -ID_INLINE void idSphere::AxisProjection( const idVec3 &dir, float &min, float &max ) const { - float d; - d = dir * origin; - min = d - radius; - max = d + radius; -} - -#endif /* !__BV_SPHERE_H__ */ diff --git a/idlib/cmdargs.cpp b/idlib/cmdargs.cpp deleted file mode 100644 index 588c86767..000000000 --- a/idlib/cmdargs.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============ -idCmdArgs::operator= -============ -*/ -void idCmdArgs::operator=( const idCmdArgs &args ) { - int i; - - argc = args.argc; - memcpy( tokenized, args.tokenized, MAX_COMMAND_STRING ); - for ( i = 0; i < argc; i++ ) { - argv[ i ] = tokenized + ( args.argv[ i ] - args.tokenized ); - } -} - -/* -============ -idCmdArgs::Args -============ -*/ -const char *idCmdArgs::Args( int start, int end, bool escapeArgs ) const { - static char cmd_args[MAX_COMMAND_STRING]; - int i; - - if ( end < 0 ) { - end = argc - 1; - } else if ( end >= argc ) { - end = argc - 1; - } - cmd_args[0] = '\0'; - if ( escapeArgs ) { - strcat( cmd_args, "\"" ); - } - for ( i = start; i <= end; i++ ) { - if ( i > start ) { - if ( escapeArgs ) { - strcat( cmd_args, "\" \"" ); - } else { - strcat( cmd_args, " " ); - } - } - if ( escapeArgs && strchr( argv[i], '\\' ) ) { - char *p = argv[i]; - while ( *p != '\0' ) { - if ( *p == '\\' ) { - strcat( cmd_args, "\\\\" ); - } else { - int l = strlen( cmd_args ); - cmd_args[ l ] = *p; - cmd_args[ l+1 ] = '\0'; - } - p++; - } - } else { - strcat( cmd_args, argv[i] ); - } - } - if ( escapeArgs ) { - strcat( cmd_args, "\"" ); - } - - return cmd_args; -} - -/* -============ -idCmdArgs::TokenizeString - -Parses the given string into command line tokens. -The text is copied to a separate buffer and 0 characters -are inserted in the appropriate place. The argv array -will point into this temporary buffer. -============ -*/ -void idCmdArgs::TokenizeString( const char *text, bool keepAsStrings ) { - idLexer lex; - idToken token, number; - int len, totalLen; - - // clear previous args - argc = 0; - - if ( !text ) { - return; - } - - lex.LoadMemory( text, strlen( text ), "idCmdSystemLocal::TokenizeString" ); - lex.SetFlags( LEXFL_NOERRORS - | LEXFL_NOWARNINGS - | LEXFL_NOSTRINGCONCAT - | LEXFL_ALLOWPATHNAMES - | LEXFL_NOSTRINGESCAPECHARS - | LEXFL_ALLOWIPADDRESSES | ( keepAsStrings ? LEXFL_ONLYSTRINGS : 0 ) ); - - totalLen = 0; -#pragma warning( push ) -#pragma warning( disable : 4127 ) - while ( 1 ) { - if ( argc == MAX_COMMAND_ARGS ) { - return; // this is usually something malicious - } - - if ( !lex.ReadToken( &token ) ) { - return; - } - - // check for negative numbers - if ( !keepAsStrings && ( token == "-" ) ) { - if ( lex.CheckTokenType( TT_NUMBER, 0, &number ) ) { - token = "-" + number; - } - } - - // check for cvar expansion - if ( token == "$" ) { - if ( !lex.ReadToken( &token ) ) { - return; - } - if ( idLib::cvarSystem ) { - token = idLib::cvarSystem->GetCVarString( token.c_str() ); - } else { - token = ""; - } - } - - len = token.Length(); - - if ( totalLen + len + 1 > sizeof( tokenized ) ) { - return; // this is usually something malicious - } - - // regular token - argv[argc] = tokenized + totalLen; - argc++; - - idStr::Copynz( tokenized + totalLen, token.c_str(), sizeof( tokenized ) - totalLen ); - - totalLen += len + 1; - } -#pragma warning( pop ) -} - -/* -============ -idCmdArgs::AppendArg -============ -*/ -void idCmdArgs::AppendArg( const char *text ) { - if ( !argc ) { - argc = 1; - argv[ 0 ] = tokenized; - idStr::Copynz( tokenized, text, sizeof( tokenized ) ); - } else { - argv[ argc ] = argv[ argc-1 ] + strlen( argv[ argc-1 ] ) + 1; - idStr::Copynz( argv[ argc ], text, sizeof( tokenized ) - ( argv[ argc ] - tokenized ) ); - argc++; - } -} - -/* -============ -idCmdArgs::GetArgs -============ -*/ -const char **idCmdArgs::GetArgs( int *_argc ) { - *_argc = argc; - return (const char **)&argv[0]; -} - diff --git a/idlib/cmdargs.h b/idlib/cmdargs.h deleted file mode 100644 index 280328f26..000000000 --- a/idlib/cmdargs.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CMDARGS_H__ -#define __CMDARGS_H__ - -/* -=============================================================================== - - Command arguments. - -=============================================================================== -*/ - -class idCmdArgs { -public: - idCmdArgs( void ) { argc = 0; } - idCmdArgs( const char *text, bool keepAsStrings ) { TokenizeString( text, keepAsStrings ); } - - void operator=( const idCmdArgs &args ); - - // The functions that execute commands get their parameters with these functions. - int Argc( void ) const { return argc; } - // Argv() will return an empty string, not NULL if arg >= argc. - const char * Argv( int arg ) const { return ( arg >= 0 && arg < argc ) ? argv[arg] : ""; } - // Returns a single string containing argv(start) to argv(end) - // escapeArgs is a fugly way to put the string back into a state ready to tokenize again - const char * Args( int start = 1, int end = -1, bool escapeArgs = false ) const; - - // Takes a null terminated string and breaks the string up into arg tokens. - // Does not need to be /n terminated. - // Set keepAsStrings to true to only seperate tokens from whitespace and comments, ignoring punctuation - void TokenizeString( const char *text, bool keepAsStrings ); - - void AppendArg( const char *text ); - void Clear( void ) { argc = 0; } - const char ** GetArgs( int *argc ); - -private: - static const int MAX_COMMAND_ARGS = 64; - static const int MAX_COMMAND_STRING = 2 * MAX_STRING_CHARS; - - int argc; // number of arguments - char * argv[MAX_COMMAND_ARGS]; // points into tokenized - char tokenized[MAX_COMMAND_STRING]; // will have 0 bytes inserted -}; - -#endif /* !__CMDARGS_H__ */ diff --git a/idlib/containers/BTree.h b/idlib/containers/BTree.h new file mode 100644 index 000000000..3edf80d95 --- /dev/null +++ b/idlib/containers/BTree.h @@ -0,0 +1,517 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BTREE_H__ +#define __BTREE_H__ + +#ifdef __linux__ +#include "../../sys/sys_public.h" +#endif + +/* +=============================================================================== + + Balanced Search Tree + +=============================================================================== +*/ + +//#define BTREE_CHECK + +template< class objType, class keyType > +class idBTreeNode { +public: + keyType key; // key used for sorting + objType * object; // if != NULL pointer to object stored in leaf node + idBTreeNode * parent; // parent node + idBTreeNode * next; // next sibling + idBTreeNode * prev; // prev sibling + int numChildren; // number of children + idBTreeNode * firstChild; // first child + idBTreeNode * lastChild; // last child +}; + + +template< class objType, class keyType, int maxChildrenPerNode > +class idBTree { +public: + idBTree( void ); + ~idBTree( void ); + + void Init( void ); + void Shutdown( void ); + + idBTreeNode * Add( objType *object, keyType key ); // add an object to the tree + void Remove( idBTreeNode *node ); // remove an object node from the tree + + objType * Find( keyType key ) const; // find an object using the given key + objType * FindSmallestLargerEqual( keyType key ) const; // find an object with the smallest key larger equal the given key + objType * FindLargestSmallerEqual( keyType key ) const; // find an object with the largest key smaller equal the given key + + idBTreeNode * GetRoot( void ) const; // returns the root node of the tree + int GetNodeCount( void ) const; // returns the total number of nodes in the tree + idBTreeNode * GetNext( idBTreeNode *node ) const; // goes through all nodes of the tree + idBTreeNode * GetNextLeaf( idBTreeNode *node ) const; // goes through all leaf nodes of the tree + +private: + idBTreeNode * root; + idBlockAlloc,128> nodeAllocator; + + idBTreeNode * AllocNode( void ); + void FreeNode( idBTreeNode *node ); + void SplitNode( idBTreeNode *node ); + idBTreeNode * MergeNodes( idBTreeNode *node1, idBTreeNode *node2 ); + + void CheckTree_r( idBTreeNode *node, int &numNodes ) const; + void CheckTree( void ) const; +}; + +#pragma warning( push ) +#pragma warning( disable : 4533 4127 ) +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTree::idBTree( void ) { + assert( maxChildrenPerNode >= 4 ); + root = NULL; +} +#pragma warning( pop ) + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTree::~idBTree( void ) { + Shutdown(); +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::Init( void ) { + root = AllocNode(); +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::Shutdown( void ) { + nodeAllocator.Shutdown(); + root = NULL; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::Add( objType *object, keyType key ) { + idBTreeNode *node, *child, *newNode; + + if ( root->numChildren >= maxChildrenPerNode ) { + newNode = AllocNode(); + newNode->key = root->key; + newNode->firstChild = root; + newNode->lastChild = root; + newNode->numChildren = 1; + root->parent = newNode; + SplitNode( root ); + root = newNode; + } + + newNode = AllocNode(); + newNode->key = key; + newNode->object = object; + + for ( node = root; node->firstChild != NULL; node = child ) { + + if ( key > node->key ) { + node->key = key; + } + + // find the first child with a key larger equal to the key of the new node + for( child = node->firstChild; child->next; child = child->next ) { + if ( key <= child->key ) { + break; + } + } + + if ( child->object ) { + + if ( key <= child->key ) { + // insert new node before child + if ( child->prev ) { + child->prev->next = newNode; + } else { + node->firstChild = newNode; + } + newNode->prev = child->prev; + newNode->next = child; + child->prev = newNode; + } else { + // insert new node after child + if ( child->next ) { + child->next->prev = newNode; + } else { + node->lastChild = newNode; + } + newNode->prev = child; + newNode->next = child->next; + child->next = newNode; + } + + newNode->parent = node; + node->numChildren++; + +#ifdef BTREE_CHECK + CheckTree(); +#endif + + return newNode; + } + + // make sure the child has room to store another node + if ( child->numChildren >= maxChildrenPerNode ) { + SplitNode( child ); + if ( key <= child->prev->key ) { + child = child->prev; + } + } + } + + // we only end up here if the root node is empty + newNode->parent = root; + root->key = key; + root->firstChild = newNode; + root->lastChild = newNode; + root->numChildren++; + +#ifdef BTREE_CHECK + CheckTree(); +#endif + + return newNode; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::Remove( idBTreeNode *node ) { + idBTreeNode *parent; + + assert( node->object != NULL ); + + // unlink the node from it's parent + if ( node->prev ) { + node->prev->next = node->next; + } else { + node->parent->firstChild = node->next; + } + if ( node->next ) { + node->next->prev = node->prev; + } else { + node->parent->lastChild = node->prev; + } + node->parent->numChildren--; + + // make sure there are no parent nodes with a single child + for ( parent = node->parent; parent != root && parent->numChildren <= 1; parent = parent->parent ) { + + if ( parent->next ) { + parent = MergeNodes( parent, parent->next ); + } else if ( parent->prev ) { + parent = MergeNodes( parent->prev, parent ); + } + + // a parent may not use a key higher than the key of it's last child + if ( parent->key > parent->lastChild->key ) { + parent->key = parent->lastChild->key; + } + + if ( parent->numChildren > maxChildrenPerNode ) { + SplitNode( parent ); + break; + } + } + for ( ; parent != NULL && parent->lastChild != NULL; parent = parent->parent ) { + // a parent may not use a key higher than the key of it's last child + if ( parent->key > parent->lastChild->key ) { + parent->key = parent->lastChild->key; + } + } + + // free the node + FreeNode( node ); + + // remove the root node if it has a single internal node as child + if ( root->numChildren == 1 && root->firstChild->object == NULL ) { + idBTreeNode *oldRoot = root; + root->firstChild->parent = NULL; + root = root->firstChild; + FreeNode( oldRoot ); + } + +#ifdef BTREE_CHECK + CheckTree(); +#endif +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE objType *idBTree::Find( keyType key ) const { + idBTreeNode *node; + + for ( node = root->firstChild; node != NULL; node = node->firstChild ) { + while( node->next ) { + if ( node->key >= key ) { + break; + } + node = node->next; + } + if ( node->object ) { + if ( node->key == key ) { + return node->object; + } else { + return NULL; + } + } + } + return NULL; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE objType *idBTree::FindSmallestLargerEqual( keyType key ) const { + idBTreeNode *node; + + for ( node = root->firstChild; node != NULL; node = node->firstChild ) { + while( node->next ) { + if ( node->key >= key ) { + break; + } + node = node->next; + } + if ( node->object ) { + if ( node->key >= key ) { + return node->object; + } else { + return NULL; + } + } + } + return NULL; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE objType *idBTree::FindLargestSmallerEqual( keyType key ) const { + idBTreeNode *node; + + for ( node = root->lastChild; node != NULL; node = node->lastChild ) { + while( node->prev ) { + if ( node->key <= key ) { + break; + } + node = node->prev; + } + if ( node->object ) { + if ( node->key <= key ) { + return node->object; + } else { + return NULL; + } + } + } + return NULL; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::GetRoot( void ) const { + return root; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE int idBTree::GetNodeCount( void ) const { + return nodeAllocator.GetAllocCount(); +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::GetNext( idBTreeNode *node ) const { + if ( node->firstChild ) { + return node->firstChild; + } else { + while( node && node->next == NULL ) { + node = node->parent; + } + return node; + } +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::GetNextLeaf( idBTreeNode *node ) const { + if ( node->firstChild ) { + while ( node->firstChild ) { + node = node->firstChild; + } + return node; + } else { + while( node && node->next == NULL ) { + node = node->parent; + } + if ( node ) { + node = node->next; + while ( node->firstChild ) { + node = node->firstChild; + } + return node; + } else { + return NULL; + } + } +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::AllocNode( void ) { + idBTreeNode *node = nodeAllocator.Alloc(); + node->key = 0; + node->parent = NULL; + node->next = NULL; + node->prev = NULL; + node->numChildren = 0; + node->firstChild = NULL; + node->lastChild = NULL; + node->object = NULL; + return node; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::FreeNode( idBTreeNode *node ) { + nodeAllocator.Free( node ); +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::SplitNode( idBTreeNode *node ) { + int i; + idBTreeNode *child, *newNode; + + // allocate a new node + newNode = AllocNode(); + newNode->parent = node->parent; + + // divide the children over the two nodes + child = node->firstChild; + child->parent = newNode; + for ( i = 3; i < node->numChildren; i += 2 ) { + child = child->next; + child->parent = newNode; + } + + newNode->key = child->key; + newNode->numChildren = node->numChildren / 2; + newNode->firstChild = node->firstChild; + newNode->lastChild = child; + + node->numChildren -= newNode->numChildren; + node->firstChild = child->next; + + child->next->prev = NULL; + child->next = NULL; + + // add the new child to the parent before the split node + assert( node->parent->numChildren < maxChildrenPerNode ); + + if ( node->prev ) { + node->prev->next = newNode; + } else { + node->parent->firstChild = newNode; + } + newNode->prev = node->prev; + newNode->next = node; + node->prev = newNode; + + node->parent->numChildren++; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE idBTreeNode *idBTree::MergeNodes( idBTreeNode *node1, idBTreeNode *node2 ) { + idBTreeNode *child; + + assert( node1->parent == node2->parent ); + assert( node1->next == node2 && node2->prev == node1 ); + assert( node1->object == NULL && node2->object == NULL ); + assert( node1->numChildren >= 1 && node2->numChildren >= 1 ); + + for ( child = node1->firstChild; child->next; child = child->next ) { + child->parent = node2; + } + child->parent = node2; + child->next = node2->firstChild; + node2->firstChild->prev = child; + node2->firstChild = node1->firstChild; + node2->numChildren += node1->numChildren; + + // unlink the first node from the parent + if ( node1->prev ) { + node1->prev->next = node2; + } else { + node1->parent->firstChild = node2; + } + node2->prev = node1->prev; + node2->parent->numChildren--; + + FreeNode( node1 ); + + return node2; +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::CheckTree_r( idBTreeNode *node, int &numNodes ) const { + int numChildren; + idBTreeNode *child; + + numNodes++; + + // the root node may have zero children and leaf nodes always have zero children, all other nodes should have at least 2 and at most maxChildrenPerNode children + assert( ( node == root ) || ( node->object != NULL && node->numChildren == 0 ) || ( node->numChildren >= 2 && node->numChildren <= maxChildrenPerNode ) ); + // the key of a node may never be larger than the key of it's last child + assert( ( node->lastChild == NULL ) || ( node->key <= node->lastChild->key ) ); + + numChildren = 0; + for ( child = node->firstChild; child; child = child->next ) { + numChildren++; + // make sure the children are properly linked + if ( child->prev == NULL ) { + assert( node->firstChild == child ); + } else { + assert( child->prev->next == child ); + } + if ( child->next == NULL ) { + assert( node->lastChild == child ); + } else { + assert( child->next->prev == child ); + } + // recurse down the tree + CheckTree_r( child, numNodes ); + } + // the number of children should equal the number of linked children + assert( numChildren == node->numChildren ); +} + +template< class objType, class keyType, int maxChildrenPerNode > +ID_INLINE void idBTree::CheckTree( void ) const { + int numNodes = 0; + idBTreeNode *node, *lastNode; + + CheckTree_r( root, numNodes ); + + // the number of nodes in the tree should equal the number of allocated nodes + assert( numNodes == nodeAllocator.GetAllocCount() ); + + // all the leaf nodes should be ordered + lastNode = GetNextLeaf( GetRoot() ); + if ( lastNode ) { + for ( node = GetNextLeaf( lastNode ); node; lastNode = node, node = GetNextLeaf( node ) ) { + assert( lastNode->key <= node->key ); + } + } +} + +#endif /* !__BTREE_H__ */ diff --git a/idlib/containers/BinSearch.h b/idlib/containers/BinSearch.h new file mode 100644 index 000000000..003f0f166 --- /dev/null +++ b/idlib/containers/BinSearch.h @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BINSEARCH_H__ +#define __BINSEARCH_H__ + +/* +=============================================================================== + + Binary Search templates + + The array elements have to be ordered in increasing order. + +=============================================================================== +*/ + +/* +==================== +idBinSearch_GreaterEqual + + Finds the last array element which is smaller than the given value. +==================== +*/ +template< class type > +ID_INLINE int idBinSearch_Less( const type *array, const int arraySize, const type &value ) { + int len = arraySize; + int mid = len; + int offset = 0; + while( mid > 0 ) { + mid = len >> 1; + if ( array[offset+mid] < value ) { + offset += mid; + } + len -= mid; + } + return offset; +} + +/* +==================== +idBinSearch_GreaterEqual + + Finds the last array element which is smaller than or equal to the given value. +==================== +*/ +template< class type > +ID_INLINE int idBinSearch_LessEqual( const type *array, const int arraySize, const type &value ) { + int len = arraySize; + int mid = len; + int offset = 0; + while( mid > 0 ) { + mid = len >> 1; + if ( array[offset+mid] <= value ) { + offset += mid; + } + len -= mid; + } + return offset; +} + +/* +==================== +idBinSearch_Greater + + Finds the first array element which is greater than the given value. +==================== +*/ +template< class type > +ID_INLINE int idBinSearch_Greater( const type *array, const int arraySize, const type &value ) { + int len = arraySize; + int mid = len; + int offset = 0; + int res = 0; + while( mid > 0 ) { + mid = len >> 1; + if ( array[offset+mid] > value ) { + res = 0; + } else { + offset += mid; + res = 1; + } + len -= mid; + } + return offset+res; +} + +/* +==================== +idBinSearch_GreaterEqual + + Finds the first array element which is greater than or equal to the given value. +==================== +*/ +template< class type > +ID_INLINE int idBinSearch_GreaterEqual( const type *array, const int arraySize, const type &value ) { + int len = arraySize; + int mid = len; + int offset = 0; + int res = 0; + while( mid > 0 ) { + mid = len >> 1; + if ( array[offset+mid] >= value ) { + res = 0; + } else { + offset += mid; + res = 1; + } + len -= mid; + } + return offset+res; +} + +#endif /* !__BINSEARCH_H__ */ diff --git a/idlib/containers/HashIndex.cpp b/idlib/containers/HashIndex.cpp new file mode 100644 index 000000000..5e5e6febc --- /dev/null +++ b/idlib/containers/HashIndex.cpp @@ -0,0 +1,148 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +int idHashIndex::INVALID_INDEX[1] = { -1 }; + +/* +================ +idHashIndex::Init +================ +*/ +void idHashIndex::Init( const int initialHashSize, const int initialIndexSize ) { + assert( idMath::IsPowerOfTwo( initialHashSize ) ); + + hashSize = initialHashSize; + hash = INVALID_INDEX; + indexSize = initialIndexSize; + indexChain = INVALID_INDEX; + granularity = DEFAULT_HASH_GRANULARITY; + hashMask = hashSize - 1; + lookupMask = 0; +} + +/* +================ +idHashIndex::Allocate +================ +*/ +void idHashIndex::Allocate( const int newHashSize, const int newIndexSize ) { + assert( idMath::IsPowerOfTwo( newHashSize ) ); + + Free(); + hashSize = newHashSize; + hash = new int[hashSize]; + memset( hash, 0xff, hashSize * sizeof( hash[0] ) ); + indexSize = newIndexSize; + indexChain = new int[indexSize]; + memset( indexChain, 0xff, indexSize * sizeof( indexChain[0] ) ); + hashMask = hashSize - 1; + lookupMask = -1; +} + +/* +================ +idHashIndex::Free +================ +*/ +void idHashIndex::Free( void ) { + if ( hash != INVALID_INDEX ) { + delete[] hash; + hash = INVALID_INDEX; + } + if ( indexChain != INVALID_INDEX ) { + delete[] indexChain; + indexChain = INVALID_INDEX; + } + lookupMask = 0; +} + +/* +================ +idHashIndex::ResizeIndex +================ +*/ +void idHashIndex::ResizeIndex( const int newIndexSize ) { + int *oldIndexChain, mod, newSize; + + if ( newIndexSize <= indexSize ) { + return; + } + + mod = newIndexSize % granularity; + if ( !mod ) { + newSize = newIndexSize; + } else { + newSize = newIndexSize + granularity - mod; + } + + if ( indexChain == INVALID_INDEX ) { + indexSize = newSize; + return; + } + + oldIndexChain = indexChain; + indexChain = new int[newSize]; + memcpy( indexChain, oldIndexChain, indexSize * sizeof(int) ); + memset( indexChain + indexSize, 0xff, (newSize - indexSize) * sizeof(int) ); + delete[] oldIndexChain; + indexSize = newSize; +} + +/* +================ +idHashIndex::GetSpread +================ +*/ +int idHashIndex::GetSpread( void ) const { + int i, index, totalItems, *numHashItems, average, error, e; + + if ( hash == INVALID_INDEX ) { + return 100; + } + + totalItems = 0; + numHashItems = new int[hashSize]; + for ( i = 0; i < hashSize; i++ ) { + numHashItems[i] = 0; + for ( index = hash[i]; index >= 0; index = indexChain[index] ) { + numHashItems[i]++; + } + totalItems += numHashItems[i]; + } + // if no items in hash + if ( totalItems <= 1 ) { + delete[] numHashItems; + return 100; + } + average = totalItems / hashSize; + error = 0; + for ( i = 0; i < hashSize; i++ ) { + e = abs( numHashItems[i] - average ); + if ( e > 1 ) { + error += e - 1; + } + } + delete[] numHashItems; + return 100 - (error * 100 / totalItems); +} diff --git a/idlib/containers/HashIndex.h b/idlib/containers/HashIndex.h new file mode 100644 index 000000000..f27e82ba6 --- /dev/null +++ b/idlib/containers/HashIndex.h @@ -0,0 +1,403 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __HASHINDEX_H__ +#define __HASHINDEX_H__ + +/* +=============================================================================== + + Fast hash table for indexes and arrays. + Does not allocate memory until the first key/index pair is added. + +=============================================================================== +*/ + +#define DEFAULT_HASH_SIZE 1024 +#define DEFAULT_HASH_GRANULARITY 1024 + +class idHashIndex { +public: + idHashIndex( void ); + idHashIndex( const int initialHashSize, const int initialIndexSize ); + ~idHashIndex( void ); + + // returns total size of allocated memory + size_t Allocated( void ) const; + // returns total size of allocated memory including size of hash index type + size_t Size( void ) const; + + idHashIndex & operator=( const idHashIndex &other ); + // add an index to the hash, assumes the index has not yet been added to the hash + void Add( const int key, const int index ); + // remove an index from the hash + void Remove( const int key, const int index ); + // get the first index from the hash, returns -1 if empty hash entry + int First( const int key ) const; + // get the next index from the hash, returns -1 if at the end of the hash chain + int Next( const int index ) const; + // insert an entry into the index and add it to the hash, increasing all indexes >= index + void InsertIndex( const int key, const int index ); + // remove an entry from the index and remove it from the hash, decreasing all indexes >= index + void RemoveIndex( const int key, const int index ); + // clear the hash + void Clear( void ); + // clear and resize + void Clear( const int newHashSize, const int newIndexSize ); + // free allocated memory + void Free( void ); + // get size of hash table + int GetHashSize( void ) const; + // get size of the index + int GetIndexSize( void ) const; + // set granularity + void SetGranularity( const int newGranularity ); + // force resizing the index, current hash table stays intact + void ResizeIndex( const int newIndexSize ); + // returns number in the range [0-100] representing the spread over the hash table + int GetSpread( void ) const; + // returns a key for a string + int GenerateKey( const char *string, bool caseSensitive = true ) const; + // returns a key for a vector + int GenerateKey( const idVec3 &v ) const; + // returns a key for two integers + int GenerateKey( const int n1, const int n2 ) const; + +private: + int hashSize; + int * hash; + int indexSize; + int * indexChain; + int granularity; + int hashMask; + int lookupMask; + + static int INVALID_INDEX[1]; + + void Init( const int initialHashSize, const int initialIndexSize ); + void Allocate( const int newHashSize, const int newIndexSize ); +}; + +/* +================ +idHashIndex::idHashIndex +================ +*/ +ID_INLINE idHashIndex::idHashIndex( void ) { + Init( DEFAULT_HASH_SIZE, DEFAULT_HASH_SIZE ); +} + +/* +================ +idHashIndex::idHashIndex +================ +*/ +ID_INLINE idHashIndex::idHashIndex( const int initialHashSize, const int initialIndexSize ) { + Init( initialHashSize, initialIndexSize ); +} + +/* +================ +idHashIndex::~idHashIndex +================ +*/ +ID_INLINE idHashIndex::~idHashIndex( void ) { + Free(); +} + +/* +================ +idHashIndex::Allocated +================ +*/ +ID_INLINE size_t idHashIndex::Allocated( void ) const { + return hashSize * sizeof( int ) + indexSize * sizeof( int ); +} + +/* +================ +idHashIndex::Size +================ +*/ +ID_INLINE size_t idHashIndex::Size( void ) const { + return sizeof( *this ) + Allocated(); +} + +/* +================ +idHashIndex::operator= +================ +*/ +ID_INLINE idHashIndex &idHashIndex::operator=( const idHashIndex &other ) { + granularity = other.granularity; + hashMask = other.hashMask; + lookupMask = other.lookupMask; + + if ( other.lookupMask == 0 ) { + hashSize = other.hashSize; + indexSize = other.indexSize; + Free(); + } + else { + if ( other.hashSize != hashSize || hash == INVALID_INDEX ) { + if ( hash != INVALID_INDEX ) { + delete[] hash; + } + hashSize = other.hashSize; + hash = new int[hashSize]; + } + if ( other.indexSize != indexSize || indexChain == INVALID_INDEX ) { + if ( indexChain != INVALID_INDEX ) { + delete[] indexChain; + } + indexSize = other.indexSize; + indexChain = new int[indexSize]; + } + memcpy( hash, other.hash, hashSize * sizeof( hash[0] ) ); + memcpy( indexChain, other.indexChain, indexSize * sizeof( indexChain[0] ) ); + } + + return *this; +} + +/* +================ +idHashIndex::Add +================ +*/ +ID_INLINE void idHashIndex::Add( const int key, const int index ) { + int h; + + assert( index >= 0 ); + if ( hash == INVALID_INDEX ) { + Allocate( hashSize, index >= indexSize ? index + 1 : indexSize ); + } + else if ( index >= indexSize ) { + ResizeIndex( index + 1 ); + } + h = key & hashMask; + indexChain[index] = hash[h]; + hash[h] = index; +} + +/* +================ +idHashIndex::Remove +================ +*/ +ID_INLINE void idHashIndex::Remove( const int key, const int index ) { + int k = key & hashMask; + + if ( hash == INVALID_INDEX ) { + return; + } + if ( hash[k] == index ) { + hash[k] = indexChain[index]; + } + else { + for ( int i = hash[k]; i != -1; i = indexChain[i] ) { + if ( indexChain[i] == index ) { + indexChain[i] = indexChain[index]; + break; + } + } + } + indexChain[index] = -1; +} + +/* +================ +idHashIndex::First +================ +*/ +ID_INLINE int idHashIndex::First( const int key ) const { + return hash[key & hashMask & lookupMask]; +} + +/* +================ +idHashIndex::Next +================ +*/ +ID_INLINE int idHashIndex::Next( const int index ) const { + assert( index >= 0 && index < indexSize ); + return indexChain[index & lookupMask]; +} + +/* +================ +idHashIndex::InsertIndex +================ +*/ +ID_INLINE void idHashIndex::InsertIndex( const int key, const int index ) { + int i, max; + + if ( hash != INVALID_INDEX ) { + max = index; + for ( i = 0; i < hashSize; i++ ) { + if ( hash[i] >= index ) { + hash[i]++; + if ( hash[i] > max ) { + max = hash[i]; + } + } + } + for ( i = 0; i < indexSize; i++ ) { + if ( indexChain[i] >= index ) { + indexChain[i]++; + if ( indexChain[i] > max ) { + max = indexChain[i]; + } + } + } + if ( max >= indexSize ) { + ResizeIndex( max + 1 ); + } + for ( i = max; i > index; i-- ) { + indexChain[i] = indexChain[i-1]; + } + indexChain[index] = -1; + } + Add( key, index ); +} + +/* +================ +idHashIndex::RemoveIndex +================ +*/ +ID_INLINE void idHashIndex::RemoveIndex( const int key, const int index ) { + int i, max; + + Remove( key, index ); + if ( hash != INVALID_INDEX ) { + max = index; + for ( i = 0; i < hashSize; i++ ) { + if ( hash[i] >= index ) { + if ( hash[i] > max ) { + max = hash[i]; + } + hash[i]--; + } + } + for ( i = 0; i < indexSize; i++ ) { + if ( indexChain[i] >= index ) { + if ( indexChain[i] > max ) { + max = indexChain[i]; + } + indexChain[i]--; + } + } + for ( i = index; i < max; i++ ) { + indexChain[i] = indexChain[i+1]; + } + indexChain[max] = -1; + } +} + +/* +================ +idHashIndex::Clear +================ +*/ +ID_INLINE void idHashIndex::Clear( void ) { + // only clear the hash table because clearing the indexChain is not really needed + if ( hash != INVALID_INDEX ) { + memset( hash, 0xff, hashSize * sizeof( hash[0] ) ); + } +} + +/* +================ +idHashIndex::Clear +================ +*/ +ID_INLINE void idHashIndex::Clear( const int newHashSize, const int newIndexSize ) { + Free(); + hashSize = newHashSize; + indexSize = newIndexSize; +} + +/* +================ +idHashIndex::GetHashSize +================ +*/ +ID_INLINE int idHashIndex::GetHashSize( void ) const { + return hashSize; +} + +/* +================ +idHashIndex::GetIndexSize +================ +*/ +ID_INLINE int idHashIndex::GetIndexSize( void ) const { + return indexSize; +} + +/* +================ +idHashIndex::SetGranularity +================ +*/ +ID_INLINE void idHashIndex::SetGranularity( const int newGranularity ) { + assert( newGranularity > 0 ); + granularity = newGranularity; +} + +/* +================ +idHashIndex::GenerateKey +================ +*/ +ID_INLINE int idHashIndex::GenerateKey( const char *string, bool caseSensitive ) const { + if ( caseSensitive ) { + return ( idStr::Hash( string ) & hashMask ); + } else { + return ( idStr::IHash( string ) & hashMask ); + } +} + +/* +================ +idHashIndex::GenerateKey +================ +*/ +ID_INLINE int idHashIndex::GenerateKey( const idVec3 &v ) const { + return ( (((int) v[0]) + ((int) v[1]) + ((int) v[2])) & hashMask ); +} + +/* +================ +idHashIndex::GenerateKey +================ +*/ +ID_INLINE int idHashIndex::GenerateKey( const int n1, const int n2 ) const { + return ( ( n1 + n2 ) & hashMask ); +} + +// stgatilov: class for displaying hash + index arrays of idHashIndex +// in MSVC debug watch (look "autoexp.dat") +struct _idHashIndex_showarray_helper { + int size; + int *ptr; +}; + +#endif /* !__HASHINDEX_H__ */ diff --git a/idlib/containers/HashTable.h b/idlib/containers/HashTable.h new file mode 100644 index 000000000..a181e913f --- /dev/null +++ b/idlib/containers/HashTable.h @@ -0,0 +1,387 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __HASHTABLE_H__ +#define __HASHTABLE_H__ + +/* +=============================================================================== + + General hash table. Slower than idHashIndex but it can also be used for + linked lists and other data structures than just indexes or arrays. + +=============================================================================== +*/ + +template< class Type > +class idHashTable { +public: + idHashTable( int newtablesize = 256 ); + idHashTable( const idHashTable &map ); + ~idHashTable( void ); + + // returns total size of allocated memory + size_t Allocated( void ) const; + // returns total size of allocated memory including size of hash table type + size_t Size( void ) const; + + void Set( const char *key, Type &value ); + bool Get( const char *key, Type **value = NULL ) const; + bool Remove( const char *key ); + + void Clear( void ); + void DeleteContents( void ); + + // the entire contents can be itterated over, but note that the + // exact index for a given element may change when new elements are added + int Num( void ) const; + Type * GetIndex( int index ) const; + + int GetSpread( void ) const; + +private: + struct hashnode_s { + idStr key; + Type value; + hashnode_s *next; + + hashnode_s( const idStr &k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {}; + hashnode_s( const char *k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {}; + }; + + hashnode_s ** heads; + + int tablesize; + int numentries; + int tablesizemask; + + int GetHash( const char *key ) const; +}; + +/* +================ +idHashTable::idHashTable +================ +*/ +template< class Type > +ID_INLINE idHashTable::idHashTable( int newtablesize ) { + + assert( idMath::IsPowerOfTwo( newtablesize ) ); + + tablesize = newtablesize; + assert( tablesize > 0 ); + + heads = new hashnode_s *[ tablesize ]; + memset( heads, 0, sizeof( *heads ) * tablesize ); + + numentries = 0; + + tablesizemask = tablesize - 1; +} + +/* +================ +idHashTable::idHashTable +================ +*/ +template< class Type > +ID_INLINE idHashTable::idHashTable( const idHashTable &map ) { + int i; + hashnode_s *node; + hashnode_s **prev; + + assert( map.tablesize > 0 ); + + tablesize = map.tablesize; + heads = new hashnode_s *[ tablesize ]; + numentries = map.numentries; + tablesizemask = map.tablesizemask; + + for( i = 0; i < tablesize; i++ ) { + if ( !map.heads[ i ] ) { + heads[ i ] = NULL; + continue; + } + + prev = &heads[ i ]; + for( node = map.heads[ i ]; node != NULL; node = node->next ) { + *prev = new hashnode_s( node->key, node->value, NULL ); + prev = &( *prev )->next; + } + } +} + +/* +================ +idHashTable::~idHashTable +================ +*/ +template< class Type > +ID_INLINE idHashTable::~idHashTable( void ) { + Clear(); + delete[] heads; +} + +/* +================ +idHashTable::Allocated +================ +*/ +template< class Type > +ID_INLINE size_t idHashTable::Allocated( void ) const { + return sizeof( heads ) * tablesize + sizeof( *heads ) * numentries; +} + +/* +================ +idHashTable::Size +================ +*/ +template< class Type > +ID_INLINE size_t idHashTable::Size( void ) const { + return sizeof( idHashTable ) + sizeof( heads ) * tablesize + sizeof( *heads ) * numentries; +} + +/* +================ +idHashTable::GetHash +================ +*/ +template< class Type > +ID_INLINE int idHashTable::GetHash( const char *key ) const { + return ( idStr::Hash( key ) & tablesizemask ); +} + +/* +================ +idHashTable::Set +================ +*/ +template< class Type > +ID_INLINE void idHashTable::Set( const char *key, Type &value ) { + hashnode_s *node, **nextPtr; + int hash, s; + + hash = GetHash( key ); + for( nextPtr = &(heads[hash]), node = *nextPtr; node != NULL; nextPtr = &(node->next), node = *nextPtr ) { + s = node->key.Cmp( key ); + if ( s == 0 ) { + node->value = value; + return; + } + if ( s > 0 ) { + break; + } + } + + numentries++; + + *nextPtr = new hashnode_s( key, value, heads[ hash ] ); + (*nextPtr)->next = node; +} + +/* +================ +idHashTable::Get +================ +*/ +template< class Type > +ID_INLINE bool idHashTable::Get( const char *key, Type **value ) const { + hashnode_s *node; + int hash, s; + + hash = GetHash( key ); + for( node = heads[ hash ]; node != NULL; node = node->next ) { + s = node->key.Cmp( key ); + if ( s == 0 ) { + if ( value ) { + *value = &node->value; + } + return true; + } + if ( s > 0 ) { + break; + } + } + + if ( value ) { + *value = NULL; + } + + return false; +} + +/* +================ +idHashTable::GetIndex + +the entire contents can be itterated over, but note that the +exact index for a given element may change when new elements are added +================ +*/ +template< class Type > +ID_INLINE Type *idHashTable::GetIndex( int index ) const { + hashnode_s *node; + int count; + int i; + + if ( ( index < 0 ) || ( index > numentries ) ) { + assert( 0 ); + return NULL; + } + + count = 0; + for( i = 0; i < tablesize; i++ ) { + for( node = heads[ i ]; node != NULL; node = node->next ) { + if ( count == index ) { + return &node->value; + } + count++; + } + } + + return NULL; +} + +/* +================ +idHashTable::Remove +================ +*/ +template< class Type > +ID_INLINE bool idHashTable::Remove( const char *key ) { + hashnode_s **head; + hashnode_s *node; + hashnode_s *prev; + int hash; + + hash = GetHash( key ); + head = &heads[ hash ]; + if ( *head ) { + for( prev = NULL, node = *head; node != NULL; prev = node, node = node->next ) { + if ( node->key == key ) { + if ( prev ) { + prev->next = node->next; + } else { + *head = node->next; + } + + delete node; + numentries--; + return true; + } + } + } + + return false; +} + +/* +================ +idHashTable::Clear +================ +*/ +template< class Type > +ID_INLINE void idHashTable::Clear( void ) { + int i; + hashnode_s *node; + hashnode_s *next; + + for( i = 0; i < tablesize; i++ ) { + next = heads[ i ]; + while( next != NULL ) { + node = next; + next = next->next; + delete node; + } + + heads[ i ] = NULL; + } + + numentries = 0; +} + +/* +================ +idHashTable::DeleteContents +================ +*/ +template< class Type > +ID_INLINE void idHashTable::DeleteContents( void ) { + int i; + hashnode_s *node; + hashnode_s *next; + + for( i = 0; i < tablesize; i++ ) { + next = heads[ i ]; + while( next != NULL ) { + node = next; + next = next->next; + delete node->value; + delete node; + } + + heads[ i ] = NULL; + } + + numentries = 0; +} + +/* +================ +idHashTable::Num +================ +*/ +template< class Type > +ID_INLINE int idHashTable::Num( void ) const { + return numentries; +} + +#if !defined(__GNUC__) || __GNUC__ < 4 +/* +================ +idHashTable::GetSpread +================ +*/ +template< class Type > +int idHashTable::GetSpread( void ) const { + int i, average, error, e; + hashnode_s *node; + + // if no items in hash + if ( !numentries ) { + return 100; + } + average = numentries / tablesize; + error = 0; + for ( i = 0; i < tablesize; i++ ) { + numItems = 0; + for( node = heads[ i ]; node != NULL; node = node->next ) { + numItems++; + } + e = abs( numItems - average ); + if ( e > 1 ) { + error += e - 1; + } + } + return 100 - (error * 100 / numentries); +} +#endif + +#endif /* !__HASHTABLE_H__ */ diff --git a/idlib/containers/Hierarchy.h b/idlib/containers/Hierarchy.h new file mode 100644 index 000000000..c767a86dd --- /dev/null +++ b/idlib/containers/Hierarchy.h @@ -0,0 +1,353 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __HIERARCHY_H__ +#define __HIERARCHY_H__ + +/* +============================================================================== + + idHierarchy + +============================================================================== +*/ + +template< class type > +class idHierarchy { +public: + + idHierarchy(); + ~idHierarchy(); + + void SetOwner( type *object ); + type * Owner( void ) const; + void ParentTo( idHierarchy &node ); + void MakeSiblingAfter( idHierarchy &node ); + bool ParentedBy( const idHierarchy &node ) const; + void RemoveFromParent( void ); + void RemoveFromHierarchy( void ); + + type * GetParent( void ) const; // parent of this node + type * GetChild( void ) const; // first child of this node + type * GetSibling( void ) const; // next node with the same parent + type * GetPriorSibling( void ) const; // previous node with the same parent + type * GetNext( void ) const; // goes through all nodes of the hierarchy + type * GetNextLeaf( void ) const; // goes through all leaf nodes of the hierarchy + +private: + idHierarchy * parent; + idHierarchy * sibling; + idHierarchy * child; + type * owner; + + idHierarchy *GetPriorSiblingNode( void ) const; // previous node with the same parent +}; + +/* +================ +idHierarchy::idHierarchy +================ +*/ +template< class type > +idHierarchy::idHierarchy() { + owner = NULL; + parent = NULL; + sibling = NULL; + child = NULL; +} + +/* +================ +idHierarchy::~idHierarchy +================ +*/ +template< class type > +idHierarchy::~idHierarchy() { + RemoveFromHierarchy(); +} + +/* +================ +idHierarchy::Owner + +Gets the object that is associated with this node. +================ +*/ +template< class type > +type *idHierarchy::Owner( void ) const { + return owner; +} + +/* +================ +idHierarchy::SetOwner + +Sets the object that this node is associated with. +================ +*/ +template< class type > +void idHierarchy::SetOwner( type *object ) { + owner = object; +} + +/* +================ +idHierarchy::ParentedBy +================ +*/ +template< class type > +bool idHierarchy::ParentedBy( const idHierarchy &node ) const { + if ( parent == &node ) { + return true; + } else if ( parent ) { + return parent->ParentedBy( node ); + } + return false; +} + +/* +================ +idHierarchy::ParentTo + +Makes the given node the parent. +================ +*/ +template< class type > +void idHierarchy::ParentTo( idHierarchy &node ) { + RemoveFromParent(); + + parent = &node; + sibling = node.child; + node.child = this; +} + +/* +================ +idHierarchy::MakeSiblingAfter + +Makes the given node a sibling after the passed in node. +================ +*/ +template< class type > +void idHierarchy::MakeSiblingAfter( idHierarchy &node ) { + RemoveFromParent(); + parent = node.parent; + sibling = node.sibling; + node.sibling = this; +} + +/* +================ +idHierarchy::RemoveFromParent +================ +*/ +template< class type > +void idHierarchy::RemoveFromParent( void ) { + idHierarchy *prev; + + if ( parent ) { + prev = GetPriorSiblingNode(); + if ( prev ) { + prev->sibling = sibling; + } else { + parent->child = sibling; + } + } + + parent = NULL; + sibling = NULL; +} + +/* +================ +idHierarchy::RemoveFromHierarchy + +Removes the node from the hierarchy and adds it's children to the parent. +================ +*/ +template< class type > +void idHierarchy::RemoveFromHierarchy( void ) { + idHierarchy *parentNode; + idHierarchy *node; + + parentNode = parent; + RemoveFromParent(); + + if ( parentNode ) { + while( child ) { + node = child; + node->RemoveFromParent(); + node->ParentTo( *parentNode ); + } + } else { + while( child ) { + child->RemoveFromParent(); + } + } +} + +/* +================ +idHierarchy::GetParent +================ +*/ +template< class type > +type *idHierarchy::GetParent( void ) const { + if ( parent ) { + return parent->owner; + } + return NULL; +} + +/* +================ +idHierarchy::GetChild +================ +*/ +template< class type > +type *idHierarchy::GetChild( void ) const { + if ( child ) { + return child->owner; + } + return NULL; +} + +/* +================ +idHierarchy::GetSibling +================ +*/ +template< class type > +type *idHierarchy::GetSibling( void ) const { + if ( sibling ) { + return sibling->owner; + } + return NULL; +} + +/* +================ +idHierarchy::GetPriorSiblingNode + +Returns NULL if no parent, or if it is the first child. +================ +*/ +template< class type > +idHierarchy *idHierarchy::GetPriorSiblingNode( void ) const { + if ( !parent || ( parent->child == this ) ) { + return NULL; + } + + idHierarchy *prev; + idHierarchy *node; + + node = parent->child; + prev = NULL; + while( ( node != this ) && ( node != NULL ) ) { + prev = node; + node = node->sibling; + } + + if ( node != this ) { + idLib::Error( "idHierarchy::GetPriorSibling: could not find node in parent's list of children" ); + } + + return prev; +} + +/* +================ +idHierarchy::GetPriorSibling + +Returns NULL if no parent, or if it is the first child. +================ +*/ +template< class type > +type *idHierarchy::GetPriorSibling( void ) const { + idHierarchy *prior; + + prior = GetPriorSiblingNode(); + if ( prior ) { + return prior->owner; + } + + return NULL; +} + +/* +================ +idHierarchy::GetNext + +Goes through all nodes of the hierarchy. +================ +*/ +template< class type > +type *idHierarchy::GetNext( void ) const { + const idHierarchy *node; + + if ( child ) { + return child->owner; + } else { + node = this; + while( node && node->sibling == NULL ) { + node = node->parent; + } + if ( node ) { + return node->sibling->owner; + } else { + return NULL; + } + } +} + +/* +================ +idHierarchy::GetNextLeaf + +Goes through all leaf nodes of the hierarchy. +================ +*/ +template< class type > +type *idHierarchy::GetNextLeaf( void ) const { + const idHierarchy *node; + + if ( child ) { + node = child; + while ( node->child ) { + node = node->child; + } + return node->owner; + } else { + node = this; + while( node && node->sibling == NULL ) { + node = node->parent; + } + if ( node ) { + node = node->sibling; + while ( node->child ) { + node = node->child; + } + return node->owner; + } else { + return NULL; + } + } +} + +#endif /* !__HIERARCHY_H__ */ diff --git a/idlib/containers/LinkList.h b/idlib/containers/LinkList.h new file mode 100644 index 000000000..df220398e --- /dev/null +++ b/idlib/containers/LinkList.h @@ -0,0 +1,401 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LINKLIST_H__ +#define __LINKLIST_H__ + +/* +============================================================================== + +idLinkList + +Circular linked list template + +============================================================================== +*/ + +template< class type > +class idLinkList { +public: + idLinkList(); + ~idLinkList(); + + bool IsListEmpty( void ) const; + bool InList( void ) const; + int Num( void ) const; + void Clear( void ); + + void InsertBefore( idLinkList &node ); + void InsertAfter( idLinkList &node ); + void AddToEnd( idLinkList &node ); + void AddToFront( idLinkList &node ); + + void Remove( void ); + + // Added by SophisticatedZombie for DarkMod + // This method removes a node from the list and updates the head pointer of + // every node in the list to prevent the list form becoming circular when the head + // is removed. + void RemoveHeadsafe( void ); + + type * Next( void ) const; + type * Prev( void ) const; + + type * Owner( void ) const; + void SetOwner( type *object ); + + idLinkList * ListHead( void ) const; + idLinkList * NextNode( void ) const; + idLinkList * PrevNode( void ) const; + idLinkList * NextNodeCircular( void ) const; + idLinkList * PrevNodeCircular( void ) const; + +private: + idLinkList * head; + idLinkList * next; + idLinkList * prev; + type * owner; +}; + +/* +================ +idLinkList::idLinkList + +Node is initialized to be the head of an empty list +================ +*/ +template< class type > +idLinkList::idLinkList() { + owner = NULL; + head = this; + next = this; + prev = this; +} + +/* +================ +idLinkList::~idLinkList + +Removes the node from the list, or if it's the head of a list, removes +all the nodes from the list. +================ +*/ +template< class type > +idLinkList::~idLinkList() { + Clear(); +} + +/* +================ +idLinkList::IsListEmpty + +Returns true if the list is empty. +================ +*/ +template< class type > +bool idLinkList::IsListEmpty( void ) const { + return head->next == head; +} + +/* +================ +idLinkList::InList + +Returns true if the node is in a list. If called on the head of a list, will always return false. +================ +*/ +template< class type > +bool idLinkList::InList( void ) const { + return head != this; +} + +/* +================ +idLinkList::Num + +Returns the number of nodes in the list. +================ +*/ +template< class type > +int idLinkList::Num( void ) const { + idLinkList *node; + int num; + + num = 0; + for( node = head->next; node != head; node = node->next ) { + num++; + } + + return num; +} + +/* +================ +idLinkList::Clear + +If node is the head of the list, clears the list. Otherwise it just removes the node from the list. +================ +*/ +template< class type > +void idLinkList::Clear( void ) { + if ( head == this ) { + while( next != this ) { + next->Remove(); + } + } else { + Remove(); + } +} + +/* +================ +idLinkList::Remove + +Removes node from list +================ +*/ +template< class type > +void idLinkList::Remove( void ) { + prev->next = next; + next->prev = prev; + + next = this; + prev = this; + head = this; +} + +/* +================ +idLinkList::RemoveHeadsafe + +Removes node from list and updates +the list's head pointer if this was the head +================ +*/ +template< class type > +void idLinkList::RemoveHeadsafe( void ) { + + // If this is the head, must walk list and tell all our little buddies + // that we are no longer the head, and that the next node now is. + if (head == this) + { + idLinkList* p_cursor = next; + + while ((p_cursor != NULL) && (p_cursor != this)) + { + p_cursor->head = next; + p_cursor = p_cursor->next; + } + } + + // Now back to ID's original code + prev->next = next; + next->prev = prev; + + next = this; + prev = this; + head = this; + + +} + +/* +================ +idLinkList::InsertBefore + +Places the node before the existing node in the list. If the existing node is the head, +then the new node is placed at the end of the list. +================ +*/ +template< class type > +void idLinkList::InsertBefore( idLinkList &node ) { + Remove(); + + next = &node; + prev = node.prev; + node.prev = this; + prev->next = this; + head = node.head; +} + +/* +================ +idLinkList::InsertAfter + +Places the node after the existing node in the list. If the existing node is the head, +then the new node is placed at the beginning of the list. +================ +*/ +template< class type > +void idLinkList::InsertAfter( idLinkList &node ) { + Remove(); + + prev = &node; + next = node.next; + node.next = this; + next->prev = this; + head = node.head; +} + +/* +================ +idLinkList::AddToEnd + +Adds node at the end of the list +================ +*/ +template< class type > +void idLinkList::AddToEnd( idLinkList &node ) { + InsertBefore( *node.head ); +} + +/* +================ +idLinkList::AddToFront + +Adds node at the beginning of the list +================ +*/ +template< class type > +void idLinkList::AddToFront( idLinkList &node ) { + InsertAfter( *node.head ); +} + +/* +================ +idLinkList::ListHead + +Returns the head of the list. If the node isn't in a list, it returns +a pointer to itself. +================ +*/ +template< class type > +idLinkList *idLinkList::ListHead( void ) const { + return head; +} + +/* +================ +idLinkList::Next + +Returns the next object in the list, or NULL if at the end. +================ +*/ +template< class type > +type *idLinkList::Next( void ) const { + if ( !next || ( next == head ) ) { + return NULL; + } + return next->owner; +} + +/* +================ +idLinkList::Prev + +Returns the previous object in the list, or NULL if at the beginning. +================ +*/ +template< class type > +type *idLinkList::Prev( void ) const { + if ( !prev || ( prev == head ) ) { + return NULL; + } + return prev->owner; +} + +/* +================ +idLinkList::NextNode + +Returns the next node in the list, or NULL if at the end. +================ +*/ +template< class type > +idLinkList *idLinkList::NextNode( void ) const { + if ( next == head ) { + return NULL; + } + return next; +} + +/* +================ +idLinkList::PrevNode + +Returns the previous node in the list, or NULL if at the beginning. +================ +*/ +template< class type > +idLinkList *idLinkList::PrevNode( void ) const { + if ( prev == head ) { + return NULL; + } + return prev; +} + +/* +================ +idLinkList::NextNodeCircular + +Returns the next node in the list, possibly returning the head. +================ +*/ +template< class type > +idLinkList *idLinkList::NextNodeCircular( void ) const { + return next; +} + +/* +================ +idLinkList::PrevNodeCircular + +Returns the previous node in the list, possibly returning the head. +================ +*/ +template< class type > +idLinkList *idLinkList::PrevNodeCircular( void ) const { + return prev; +} + +/* +================ +idLinkList::Owner + +Gets the object that is associated with this node. +================ +*/ +template< class type > +type *idLinkList::Owner( void ) const { + return owner; +} + +/* +================ +idLinkList::SetOwner + +Sets the object that this node is associated with. +================ +*/ +template< class type > +void idLinkList::SetOwner( type *object ) { + owner = object; +} + +#endif /* !__LINKLIST_H__ */ diff --git a/idlib/containers/List.h b/idlib/containers/List.h new file mode 100644 index 000000000..96adb08b3 --- /dev/null +++ b/idlib/containers/List.h @@ -0,0 +1,1017 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LIST_H__ +#define __LIST_H__ + +#ifdef __linux__ +#include +#endif + +/* +=============================================================================== + + List template + Does not allocate memory until the first item is added. + +=============================================================================== +*/ + + +/* +================ +idListSortCompare +================ +*/ +#ifdef __INTEL_COMPILER +// the intel compiler doesn't do the right thing here +template< class type > +ID_INLINE int idListSortCompare( const type *a, const type *b ) { + assert( 0 ); + return 0; +} +#else +template< class type > +ID_INLINE int idListSortCompare( const type *a, const type *b ) { + return *a - *b; +} +#endif + +/* +================ +idListNewElement +================ +*/ +template< class type > +ID_INLINE type *idListNewElement( void ) { + return new type; +} + +/* +================ +idSwap +================ +*/ +template< class type > +ID_INLINE void idSwap( type &a, type &b ) { + type c = a; + a = b; + b = c; +} + +template< class type > +class idList { +public: + + typedef int cmp_t( const type *, const type * ); + typedef type new_t( void ); + + idList( int newgranularity = 16 ); + idList( const idList &other ); + ~idList( void ); + + void Clear( void ); // clear the list + int Num( void ) const; // returns number of elements in list + int NumAllocated( void ) const; // returns number of elements allocated for + void SetGranularity( int newgranularity ); // set new granularity + int GetGranularity( void ) const; // get the current granularity + + size_t Allocated( void ) const; // returns total size of allocated memory + size_t Size( void ) const; // returns total size of allocated memory including size of list type + size_t MemoryUsed( void ) const; // returns size of the used elements in the list + + idList & operator=( const idList &other ); + const type & operator[]( int index ) const; + type & operator[]( int index ); + + void Condense( void ); // resizes list to exactly the number of elements it contains + void Resize( int newsize ); // resizes list to the given number of elements + void Resize( int newsize, int newgranularity ); // resizes list and sets new granularity + void SetNum( int newnum, bool resize = true ); // set number of elements in list and resize to exactly this number if necessary + void AssureSize( int newSize); // assure list has given number of elements, but leave them uninitialized + void AssureSize( int newSize, const type &initValue ); // assure list has given number of elements and initialize any new elements + void AssureSizeAlloc( int newSize, new_t *allocator ); // assure the pointer list has the given number of elements and allocate any new elements + + type * Ptr( void ); // returns a pointer to the list + const type * Ptr( void ) const; // returns a pointer to the list + type & Alloc( void ); // returns reference to a new data element at the end of the list + int Append( const type & obj ); // append element + int Append( const idList &other ); // append list + int AddUnique( const type & obj ); // add unique element + int Insert( const type & obj, int index = 0 ); // insert the element at the given index + int FindIndex( const type & obj ) const; // find the index for the given element + type * Find( type const & obj ) const; // find pointer to the given element + int FindNull( void ) const; // find the index for the first NULL pointer in the list + int IndexOf( const type *obj ) const; // returns the index for the pointer to an element in the list + bool RemoveIndex( const int index ); // remove the element at the given index and keep items sorted + bool RemoveIndex( const int index, bool keepSorted ); // Tels: remove the element at the given index, keep sorted only if wanted + bool Remove( const type & obj ); // remove the element + void Sort( cmp_t *compare = ( cmp_t * )&idListSortCompare ); + void SortSubSection( int startIndex, int endIndex, cmp_t *compare = ( cmp_t * )&idListSortCompare ); + void Swap( idList &other ); // swap the contents of the lists + void DeleteContents( bool clear ); // delete the contents of the list + +private: + int num; + int size; + int granularity; + type * list; +}; + +/* +================ +idList::idList( int ) +================ +*/ +template< class type > +ID_INLINE idList::idList( int newgranularity ) { + assert( newgranularity > 0 ); + + list = NULL; + granularity = newgranularity; + Clear(); +} + +/* +================ +idList::idList( const idList &other ) +================ +*/ +template< class type > +ID_INLINE idList::idList( const idList &other ) { + list = NULL; + *this = other; +} + +/* +================ +idList::~idList +================ +*/ +template< class type > +ID_INLINE idList::~idList( void ) { + Clear(); +} + +/* +================ +idList::Clear + +Frees up the memory allocated by the list. Assumes that type automatically handles freeing up memory. +================ +*/ +template< class type > +ID_INLINE void idList::Clear( void ) { + if ( list ) { + delete[] list; + } + + list = NULL; + num = 0; + size = 0; +} + +/* +================ +idList::DeleteContents + +Calls the destructor of all elements in the list. Conditionally frees up memory used by the list. +Note that this only works on lists containing pointers to objects and will cause a compiler error +if called with non-pointers. Since the list was not responsible for allocating the object, it has +no information on whether the object still exists or not, so care must be taken to ensure that +the pointers are still valid when this function is called. Function will set all pointers in the +list to NULL. +================ +*/ +template< class type > +ID_INLINE void idList::DeleteContents( bool clear ) { + int i; + + for( i = 0; i < num; i++ ) { + delete list[ i ]; + list[ i ] = NULL; + } + + if ( clear ) { + Clear(); + } else { + memset( list, 0, size * sizeof( type ) ); + } +} + +/* +================ +idList::Allocated + +return total memory allocated for the list in bytes, but doesn't take into account additional memory allocated by type +================ +*/ +template< class type > +ID_INLINE size_t idList::Allocated( void ) const { + return size * sizeof( type ); +} + +/* +================ +idList::Size + +return total size of list in bytes, but doesn't take into account additional memory allocated by type +================ +*/ +template< class type > +ID_INLINE size_t idList::Size( void ) const { + return sizeof( idList ) + Allocated(); +} + +/* +================ +idList::MemoryUsed +================ +*/ +template< class type > +ID_INLINE size_t idList::MemoryUsed( void ) const { + return num * sizeof( *list ); +} + +/* +================ +idList::Num + +Returns the number of elements currently contained in the list. +Note that this is NOT an indication of the memory allocated. +================ +*/ +template< class type > +ID_INLINE int idList::Num( void ) const { + return num; +} + +/* +================ +idList::NumAllocated + +Returns the number of elements currently allocated for. +================ +*/ +template< class type > +ID_INLINE int idList::NumAllocated( void ) const { + return size; +} + +/* +================ +idList::SetNum + +Resize to the exact size specified irregardless of granularity +================ +*/ +template< class type > +ID_INLINE void idList::SetNum( int newnum, bool resize ) { + assert( newnum >= 0 ); + if ( resize || newnum > size ) { + Resize( newnum ); + } + num = newnum; +} + +/* +================ +idList::SetGranularity + +Sets the base size of the array and resizes the array to match. +================ +*/ +template< class type > +ID_INLINE void idList::SetGranularity( int newgranularity ) { + int newsize; + + assert( newgranularity > 0 ); + granularity = newgranularity; + + if ( list ) { + // resize it to the closest level of granularity + newsize = num + granularity - 1; + newsize -= newsize % granularity; + if ( newsize != size ) { + Resize( newsize ); + } + } +} + +/* +================ +idList::GetGranularity + +Get the current granularity. +================ +*/ +template< class type > +ID_INLINE int idList::GetGranularity( void ) const { + return granularity; +} + +/* +================ +idList::Condense + +Resizes the array to exactly the number of elements it contains or frees up memory if empty. +================ +*/ +template< class type > +ID_INLINE void idList::Condense( void ) { + if ( list ) { + if ( num ) { + Resize( num ); + } else { + Clear(); + } + } +} + +/* +================ +idList::Resize + +Allocates memory for the amount of elements requested while keeping the contents intact. +Contents are copied using their = operator so that data is correnctly instantiated. +================ +*/ +template< class type > +ID_INLINE void idList::Resize( int newsize ) { + type *temp; + int i; + + assert( newsize >= 0 ); + + // free up the list if no data is being reserved + if ( newsize <= 0 ) { + Clear(); + return; + } + + if ( newsize == size ) { + // not changing the size, so just exit + return; + } + + temp = list; + size = newsize; + if ( size < num ) { + num = size; + } + + // copy the old list into our new one + list = new type[ size ]; + for( i = 0; i < num; i++ ) { + list[ i ] = temp[ i ]; + } + + // delete the old list if it exists + if ( temp ) { + delete[] temp; + } +} + +/* +================ +idList::Resize + +Allocates memory for the amount of elements requested while keeping the contents intact. +Contents are copied using their = operator so that data is correnctly instantiated. +================ +*/ +template< class type > +ID_INLINE void idList::Resize( int newsize, int newgranularity ) { + type *temp; + int i; + + assert( newsize >= 0 ); + + assert( newgranularity > 0 ); + granularity = newgranularity; + + // free up the list if no data is being reserved + if ( newsize <= 0 ) { + Clear(); + return; + } + + temp = list; + size = newsize; + if ( size < num ) { + num = size; + } + + // copy the old list into our new one + list = new type[ size ]; + for( i = 0; i < num; i++ ) { + list[ i ] = temp[ i ]; + } + + // delete the old list if it exists + if ( temp ) { + delete[] temp; + } +} + +/* +================ +idList::AssureSize + +Makes sure the list has at least the given number of elements. +================ +*/ +template< class type > +ID_INLINE void idList::AssureSize( int newSize ) { + int newNum = newSize; + + if ( newSize > size ) { + + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + + newSize += granularity - 1; + newSize -= newSize % granularity; + Resize( newSize ); + } + + num = newNum; +} + +/* +================ +idList::AssureSize + +Makes sure the list has at least the given number of elements and initialize any elements not yet initialized. +================ +*/ +template< class type > +ID_INLINE void idList::AssureSize( int newSize, const type &initValue ) { + int newNum = newSize; + + if ( newSize > size ) { + + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + + newSize += granularity - 1; + newSize -= newSize % granularity; + num = size; + Resize( newSize ); + + for ( int i = num; i < newSize; i++ ) { + list[i] = initValue; + } + } + + num = newNum; +} + +/* +================ +idList::AssureSizeAlloc + +Makes sure the list has at least the given number of elements and allocates any elements using the allocator. + +NOTE: This function can only be called on lists containing pointers. Calling it +on non-pointer lists will cause a compiler error. +================ +*/ +template< class type > +ID_INLINE void idList::AssureSizeAlloc( int newSize, new_t *allocator ) { + int newNum = newSize; + + if ( newSize > size ) { + + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + + newSize += granularity - 1; + newSize -= newSize % granularity; + num = size; + Resize( newSize ); + + for ( int i = num; i < newSize; i++ ) { + list[i] = (*allocator)(); + } + } + + num = newNum; +} + +/* +================ +idList::operator= + +Copies the contents and size attributes of another list. +================ +*/ +template< class type > +ID_INLINE idList &idList::operator=( const idList &other ) { + int i; + + Clear(); + + num = other.num; + size = other.size; + granularity = other.granularity; + + if ( size ) { + list = new type[ size ]; + for( i = 0; i < num; i++ ) { + list[ i ] = other.list[ i ]; + } + } + + return *this; +} + +/* +================ +idList::operator[] const + +Access operator. Index must be within range or an assert will be issued in debug builds. +Release builds do no range checking. +================ +*/ +template< class type > +ID_INLINE const type &idList::operator[]( int index ) const { + assert( index >= 0 ); + assert( index < num ); + + return list[ index ]; +} + +/* +================ +idList::operator[] + +Access operator. Index must be within range or an assert will be issued in debug builds. +Release builds do no range checking. +================ +*/ +template< class type > +ID_INLINE type &idList::operator[]( int index ) { + assert( index >= 0 ); + assert( index < num ); + + return list[ index ]; +} + +/* +================ +idList::Ptr + +Returns a pointer to the beginning of the array. Useful for iterating through the list in loops. + +Note: may return NULL if the list is empty. + +FIXME: Create an iterator template for this kind of thing. +================ +*/ +template< class type > +ID_INLINE type *idList::Ptr( void ) { + return list; +} + +/* +================ +idList::Ptr + +Returns a pointer to the begining of the array. Useful for iterating through the list in loops. + +Note: may return NULL if the list is empty. + +FIXME: Create an iterator template for this kind of thing. +================ +*/ +template< class type > +const ID_INLINE type *idList::Ptr( void ) const { + return list; +} + +/* +================ +idList::Alloc + +Returns a reference to a new data element at the end of the list. +================ +*/ +template< class type > +ID_INLINE type &idList::Alloc( void ) { + if ( !list ) { + Resize( granularity ); + } + + if ( num == size ) { + Resize( size + granularity ); + } + + return list[ num++ ]; +} + +/* +================ +idList::Append + +Increases the size of the list by one element and copies the supplied data into it. + +Returns the index of the new element. + +greebo: Important: Don't do this: spotList.Append( spotList[randomLocation] )! + +Don't call idList::Append() or idList::Alloc() with a reference to a current +list element. The operator[] will return a reference to the memory BEFORE a +possible Resize() call, which will relocate the entire list. The reference +to the "old" memory location will be invalid and crashes are ahead. +================ +*/ +template< class type > +ID_INLINE int idList::Append( type const & obj ) { + if ( !list ) { + Resize( granularity ); + } + + if ( num == size ) { + int newsize; + + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + newsize = size + granularity; + Resize( newsize - newsize % granularity ); + } + + list[ num ] = obj; + num++; + + return num - 1; +} + + +/* +================ +idList::Insert + +Increases the size of the list by at leat one element if necessary +and inserts the supplied data into it. + +Returns the index of the new element. +================ +*/ +template< class type > +ID_INLINE int idList::Insert( type const & obj, int index ) { + if ( !list ) { + Resize( granularity ); + } + + if ( num == size ) { + int newsize; + + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + newsize = size + granularity; + Resize( newsize - newsize % granularity ); + } + + if ( index < 0 ) { + index = 0; + } + else if ( index > num ) { + index = num; + } + for ( int i = num; i > index; --i ) { + list[i] = list[i-1]; + } + num++; + list[index] = obj; + return index; +} + +/* +================ +idList::Append + +adds the other list to this one + +Returns the size of the new combined list +================ +*/ +template< class type > +ID_INLINE int idList::Append( const idList &other ) { + + // Tels: Old code, with quadratic (O(N*N) performance, it would call Resize + // every so often, which is a O(N) copy operation. +/* if ( !list ) { + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + Resize( granularity ); + } + + int n = other.Num(); + for (int i = 0; i < n; i++) { + Append(other[i]); + } + + return Num(); +*/ + + // Tels 2010-07-21: new code, resize only once, then copy data over O(N) + if ( granularity == 0 ) { // this is a hack to fix our memset classes + granularity = 16; + } + int n = other.Num(); + int newsize = size + granularity + n; + Resize( newsize - newsize % granularity ); + + for (int i = 0; i < n; i++) { + // simply copy data over + list[num + i] = other[i]; + } + num += n; + return num; +} + +/* +================ +idList::AddUnique + +Adds the data to the list if it doesn't already exist. Returns the index of the data in the list. +================ +*/ +template< class type > +ID_INLINE int idList::AddUnique( type const & obj ) { + int index; + + index = FindIndex( obj ); + if ( index < 0 ) { + index = Append( obj ); + } + + return index; +} + +/* +================ +idList::FindIndex + +Searches for the specified data in the list and returns it's index. Returns -1 if the data is not found. +================ +*/ +template< class type > +ID_INLINE int idList::FindIndex( type const & obj ) const { + int i; + + for( i = 0; i < num; i++ ) { + if ( list[ i ] == obj ) { + return i; + } + } + + // Not found + return -1; +} + +/* +================ +idList::Find + +Searches for the specified data in the list and returns it's address. Returns NULL if the data is not found. +================ +*/ +template< class type > +ID_INLINE type *idList::Find( type const & obj ) const { + int i; + + i = FindIndex( obj ); + if ( i >= 0 ) { + return &list[ i ]; + } + + return NULL; +} + +/* +================ +idList::FindNull + +Searches for a NULL pointer in the list. Returns -1 if NULL is not found. + +NOTE: This function can only be called on lists containing pointers. Calling it +on non-pointer lists will cause a compiler error. +================ +*/ +template< class type > +ID_INLINE int idList::FindNull( void ) const { + int i; + + for( i = 0; i < num; i++ ) { + if ( list[ i ] == NULL ) { + return i; + } + } + + // Not found + return -1; +} + +/* +================ +idList::IndexOf + +Takes a pointer to an element in the list and returns the index of the element. +This is NOT a guarantee that the object is really in the list. +Function will assert in debug builds if pointer is outside the bounds of the list, +but remains silent in release builds. +================ +*/ +template< class type > +ID_INLINE int idList::IndexOf( type const *objptr ) const { + int index; + + index = objptr - list; + + assert( index >= 0 ); + assert( index < num ); + + return index; +} + +/* +================ +idList::RemoveIndex + +Removes the element at the specified index and moves all data following the element down to fill in the gap. +The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. +Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. +================ +*/ +template< class type > +ID_INLINE bool idList::RemoveIndex( int index ) { + int i; + + assert( list != NULL ); + assert( index >= 0 ); + assert( index < num ); + + if ( ( index < 0 ) || ( index >= num ) ) { + return false; + } + + num--; + for( i = index; i < num; i++ ) { + list[ i ] = list[ i + 1 ]; + } + + return true; +} + +/* +================ +idList::RemoveIndex + +Removes the element at the specified index and if keepSorted is true, moves all data following the element down to +fill in the gap. If keepSorted is false, just fills the gap with the last element in the list (if any). +The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. +Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. +================ +*/ +template< class type > +ID_INLINE bool idList::RemoveIndex( const int index, const bool keepSorted ) { + + assert( list != NULL ); + assert( index >= 0 ); + assert( index < num ); + + if ( ( index < 0 ) || ( index >= num ) ) { + return false; + } + + num--; + if (keepSorted) + { + //gameLocal.Printf("Moving %i list entries (index = %i)\n", num - index, index ); + for( int i = index; i < num; i++ ) { + list[ i ] = list[ i + 1 ]; + } + } + else + { + // [1,2,3,4] (remove 2, num was 4, is now 3, index = 1) => (num = 2), [1,4,3] + // if index == num, we removed the last element, so nothing to do + if ( index < num ) + { + list[ index ] = list[ num ]; + } + } + + return true; +} + +/* +================ +idList::Remove + +Removes the element if it is found within the list and moves all data following the element down to fill in the gap. +The number of elements in the list is reduced by one. Returns false if the data is not found in the list. Note that +the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. +================ +*/ +template< class type > +ID_INLINE bool idList::Remove( type const & obj ) { + int index; + + index = FindIndex( obj ); + if ( index >= 0 ) { + return RemoveIndex( index ); + } + + return false; +} + +/* +================ +idList::Sort + +Performs a qsort on the list using the supplied comparison function. Note that the data is merely moved around the +list, so any pointers to data within the list may no longer be valid. +================ +*/ +template< class type > +ID_INLINE void idList::Sort( cmp_t *compare ) { + if ( !list ) { + return; + } + typedef int cmp_c(const void *, const void *); + + cmp_c *vCompare = (cmp_c *)compare; + qsort( ( void * )list, ( size_t )num, sizeof( type ), vCompare ); +} + +/* +================ +idList::SortSubSection + +Sorts a subsection of the list. +================ +*/ +template< class type > +ID_INLINE void idList::SortSubSection( int startIndex, int endIndex, cmp_t *compare ) { + if ( !list ) { + return; + } + if ( startIndex < 0 ) { + startIndex = 0; + } + if ( endIndex >= num ) { + endIndex = num - 1; + } + if ( startIndex >= endIndex ) { + return; + } + typedef int cmp_c(const void *, const void *); + + cmp_c *vCompare = (cmp_c *)compare; + qsort( ( void * )( &list[startIndex] ), ( size_t )( endIndex - startIndex + 1 ), sizeof( type ), vCompare ); +} + +/* +================ +idList::Swap + +Swaps the contents of two lists +================ +*/ +template< class type > +ID_INLINE void idList::Swap( idList &other ) { + idSwap( num, other.num ); + idSwap( size, other.size ); + idSwap( granularity, other.granularity ); + idSwap( list, other.list ); +} + +typedef idList idStringList; + +#endif /* !__LIST_H__ */ diff --git a/idlib/containers/PlaneSet.h b/idlib/containers/PlaneSet.h new file mode 100644 index 000000000..8dcc68a3c --- /dev/null +++ b/idlib/containers/PlaneSet.h @@ -0,0 +1,72 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PLANESET_H__ +#define __PLANESET_H__ + +/* +=============================================================================== + + Plane Set + +=============================================================================== +*/ + +class idPlaneSet : public idList { +public: + + void Clear( void ) { idList::Clear(); hash.Free(); } + + int FindPlane( const idPlane &plane, const float normalEps, const float distEps ); + +private: + idHashIndex hash; +}; + +ID_INLINE int idPlaneSet::FindPlane( const idPlane &plane, const float normalEps, const float distEps ) { + int i, border, hashKey; + + assert( distEps <= 0.125f ); + + hashKey = (int)( idMath::Fabs( plane.Dist() ) * 0.125f ); + for ( border = -1; border <= 1; border++ ) { + for ( i = hash.First( hashKey + border ); i >= 0; i = hash.Next( i ) ) { + if ( (*this)[i].Compare( plane, normalEps, distEps ) ) { + return i; + } + } + } + + if ( plane.Type() >= PLANETYPE_NEGX && plane.Type() < PLANETYPE_TRUEAXIAL ) { + Append( -plane ); + hash.Add( hashKey, Num()-1 ); + Append( plane ); + hash.Add( hashKey, Num()-1 ); + return ( Num() - 1 ); + } + else { + Append( plane ); + hash.Add( hashKey, Num()-1 ); + Append( -plane ); + hash.Add( hashKey, Num()-1 ); + return ( Num() - 2 ); + } +} + +#endif /* !__PLANESET_H__ */ diff --git a/idlib/containers/Queue.h b/idlib/containers/Queue.h new file mode 100644 index 000000000..47e7412d4 --- /dev/null +++ b/idlib/containers/Queue.h @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __QUEUE_H__ +#define __QUEUE_H__ + +/* +=============================================================================== + + Queue template + +=============================================================================== +*/ + +#define idQueue( type, next ) idQueueTemplatenext)> + +template< class type, int nextOffset > +class idQueueTemplate { +public: + idQueueTemplate( void ); + + void Add( type *element ); + type * Get( void ); + +private: + type * first; + type * last; +}; + +#define QUEUE_NEXT_PTR( element ) (*((type**)(((byte*)element)+nextOffset))) + +template< class type, int nextOffset > +idQueueTemplate::idQueueTemplate( void ) { + first = last = NULL; +} + +template< class type, int nextOffset > +void idQueueTemplate::Add( type *element ) { + QUEUE_NEXT_PTR(element) = NULL; + if ( last ) { + QUEUE_NEXT_PTR(last) = element; + } else { + first = element; + } + last = element; +} + +template< class type, int nextOffset > +type *idQueueTemplate::Get( void ) { + type *element; + + element = first; + if ( element ) { + first = QUEUE_NEXT_PTR(first); + if ( last == element ) { + last = NULL; + } + QUEUE_NEXT_PTR(element) = NULL; + } + return element; +} + +#endif /* !__QUEUE_H__ */ diff --git a/idlib/containers/Stack.h b/idlib/containers/Stack.h new file mode 100644 index 000000000..c64aca7d9 --- /dev/null +++ b/idlib/containers/Stack.h @@ -0,0 +1,77 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STACK_H__ +#define __STACK_H__ + +/* +=============================================================================== + + Stack template + +=============================================================================== +*/ + +#define idStack( type, next ) idStackTemplatenext)> + +template< class type, int nextOffset > +class idStackTemplate { +public: + idStackTemplate( void ); + + void Add( type *element ); + type * Get( void ); + +private: + type * top; + type * bottom; +}; + +#define STACK_NEXT_PTR( element ) (*(type**)(((byte*)element)+nextOffset)) + +template< class type, int nextOffset > +idStackTemplate::idStackTemplate( void ) { + top = bottom = NULL; +} + +template< class type, int nextOffset > +void idStackTemplate::Add( type *element ) { + STACK_NEXT_PTR(element) = top; + top = element; + if ( !bottom ) { + bottom = element; + } +} + +template< class type, int nextOffset > +type *idStackTemplate::Get( void ) { + type *element; + + element = top; + if ( element ) { + top = STACK_NEXT_PTR(top); + if ( bottom == element ) { + bottom = NULL; + } + STACK_NEXT_PTR(element) = NULL; + } + return element; +} + +#endif /* !__STACK_H__ */ diff --git a/idlib/containers/StaticList.h b/idlib/containers/StaticList.h new file mode 100644 index 000000000..7654c4b0a --- /dev/null +++ b/idlib/containers/StaticList.h @@ -0,0 +1,539 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STATICLIST_H__ +#define __STATICLIST_H__ + +/* +=============================================================================== + + Static list template + A non-growing, memset-able list using no memory allocation. + +=============================================================================== +*/ + +template +class idStaticList { +public: + + idStaticList(); + idStaticList( const idStaticList &other ); + ~idStaticList( void ); + + void Clear( void ); // marks the list as empty. does not deallocate or intialize data. + int Num( void ) const; // returns number of elements in list + int Max( void ) const; // returns the maximum number of elements in the list + void SetNum( int newnum ); // set number of elements in list + + size_t Allocated( void ) const; // returns total size of allocated memory + size_t Size( void ) const; // returns total size of allocated memory including size of list type + size_t MemoryUsed( void ) const; // returns size of the used elements in the list + + const type & operator[]( int index ) const; + type & operator[]( int index ); + + type * Ptr( void ); // returns a pointer to the list + const type * Ptr( void ) const; // returns a pointer to the list + type * Alloc( void ); // returns reference to a new data element at the end of the list. returns NULL when full. + int Append( const type & obj ); // append element + int Append( const idStaticList &other ); // append list + int AddUnique( const type & obj ); // add unique element + int Insert( const type & obj, int index ); // insert the element at the given index + int FindIndex( const type & obj ) const; // find the index for the given element + type * Find( type const & obj ) const; // find pointer to the given element + int FindNull( void ) const; // find the index for the first NULL pointer in the list + int IndexOf( const type *obj ) const; // returns the index for the pointer to an element in the list + bool RemoveIndex( int index ); // remove the element at the given index + bool Remove( const type & obj ); // remove the element + void Swap( idStaticList &other ); // swap the contents of the lists + void DeleteContents( bool clear ); // delete the contents of the list + +private: + int num; + type list[ size ]; +}; + +/* +================ +idStaticList::idStaticList() +================ +*/ +template +ID_INLINE idStaticList::idStaticList() { + num = 0; +} + +/* +================ +idStaticList::idStaticList( const idStaticList &other ) +================ +*/ +template +ID_INLINE idStaticList::idStaticList( const idStaticList &other ) { + *this = other; +} + +/* +================ +idStaticList::~idStaticList +================ +*/ +template +ID_INLINE idStaticList::~idStaticList( void ) { +} + +/* +================ +idStaticList::Clear + +Sets the number of elements in the list to 0. Assumes that type automatically handles freeing up memory. +================ +*/ +template +ID_INLINE void idStaticList::Clear( void ) { + num = 0; +} + +/* +================ +idStaticList::DeleteContents + +Calls the destructor of all elements in the list. Conditionally frees up memory used by the list. +Note that this only works on lists containing pointers to objects and will cause a compiler error +if called with non-pointers. Since the list was not responsible for allocating the object, it has +no information on whether the object still exists or not, so care must be taken to ensure that +the pointers are still valid when this function is called. Function will set all pointers in the +list to NULL. +================ +*/ +template +ID_INLINE void idStaticList::DeleteContents( bool clear ) { + int i; + + for( i = 0; i < size; i++ ) { + delete list[ i ]; + list[ i ] = NULL; + } + + if ( clear ) { + Clear(); + } else { + memset( list, 0, sizeof( list ) ); + } +} + +/* +================ +idStaticList::Num + +Returns the number of elements currently contained in the list. +================ +*/ +template +ID_INLINE int idStaticList::Num( void ) const { + return num; +} + +/* +================ +idStaticList::Num + +Returns the maximum number of elements in the list. +================ +*/ +template +ID_INLINE int idStaticList::Max( void ) const { + return size; +} + +/* +================ +idStaticList::Allocated +================ +*/ +template +ID_INLINE size_t idStaticList::Allocated( void ) const { + return size * sizeof( type ); +} + +/* +================ +idStaticList::Size +================ +*/ +template +ID_INLINE size_t idStaticList::Size( void ) const { + return sizeof( idStaticList ) + Allocated(); +} + +/* +================ +idStaticList::Num +================ +*/ +template +ID_INLINE size_t idStaticList::MemoryUsed( void ) const { + return num * sizeof( list[ 0 ] ); +} + +/* +================ +idStaticList::SetNum + +Set number of elements in list. +================ +*/ +template +ID_INLINE void idStaticList::SetNum( int newnum ) { + assert( newnum >= 0 ); + assert( newnum <= size ); + num = newnum; +} + +/* +================ +idStaticList::operator[] const + +Access operator. Index must be within range or an assert will be issued in debug builds. +Release builds do no range checking. +================ +*/ +template +ID_INLINE const type &idStaticList::operator[]( int index ) const { + assert( index >= 0 ); + assert( index < num ); + + return list[ index ]; +} + +/* +================ +idStaticList::operator[] + +Access operator. Index must be within range or an assert will be issued in debug builds. +Release builds do no range checking. +================ +*/ +template +ID_INLINE type &idStaticList::operator[]( int index ) { + assert( index >= 0 ); + assert( index < num ); + + return list[ index ]; +} + +/* +================ +idStaticList::Ptr + +Returns a pointer to the begining of the array. Useful for iterating through the list in loops. + +Note: may return NULL if the list is empty. + +FIXME: Create an iterator template for this kind of thing. +================ +*/ +template +ID_INLINE type *idStaticList::Ptr( void ) { + return &list[ 0 ]; +} + +/* +================ +idStaticList::Ptr + +Returns a pointer to the begining of the array. Useful for iterating through the list in loops. + +Note: may return NULL if the list is empty. + +FIXME: Create an iterator template for this kind of thing. +================ +*/ +template +ID_INLINE const type *idStaticList::Ptr( void ) const { + return &list[ 0 ]; +} + +/* +================ +idStaticList::Alloc + +Returns a pointer to a new data element at the end of the list. +================ +*/ +template +ID_INLINE type *idStaticList::Alloc( void ) { + if ( num >= size ) { + return NULL; + } + + return &list[ num++ ]; +} + +/* +================ +idStaticList::Append + +Increases the size of the list by one element and copies the supplied data into it. + +Returns the index of the new element, or -1 when list is full. +================ +*/ +template +ID_INLINE int idStaticList::Append( type const & obj ) { + assert( num < size ); + if ( num < size ) { + list[ num ] = obj; + num++; + return num - 1; + } + + return -1; +} + + +/* +================ +idStaticList::Insert + +Increases the size of the list by at leat one element if necessary +and inserts the supplied data into it. + +Returns the index of the new element, or -1 when list is full. +================ +*/ +template +ID_INLINE int idStaticList::Insert( type const & obj, int index ) { + int i; + + assert( num < size ); + if ( num >= size ) { + return -1; + } + + assert( index >= 0 ); + if ( index < 0 ) { + index = 0; + } else if ( index > num ) { + index = num; + } + + for( i = num; i > index; --i ) { + list[i] = list[i-1]; + } + + num++; + list[index] = obj; + return index; +} + +/* +================ +idStaticList::Append + +adds the other list to this one + +Returns the size of the new combined list +================ +*/ +template +ID_INLINE int idStaticList::Append( const idStaticList &other ) { + int i; + int n = other.Num(); + + if ( num + n > size ) { + n = size - num; + } + for( i = 0; i < n; i++ ) { + list[i + num] = other.list[i]; + } + num += n; + return Num(); +} + +/* +================ +idStaticList::AddUnique + +Adds the data to the list if it doesn't already exist. Returns the index of the data in the list. +================ +*/ +template +ID_INLINE int idStaticList::AddUnique( type const & obj ) { + int index; + + index = FindIndex( obj ); + if ( index < 0 ) { + index = Append( obj ); + } + + return index; +} + +/* +================ +idStaticList::FindIndex + +Searches for the specified data in the list and returns it's index. Returns -1 if the data is not found. +================ +*/ +template +ID_INLINE int idStaticList::FindIndex( type const & obj ) const { + int i; + + for( i = 0; i < num; i++ ) { + if ( list[ i ] == obj ) { + return i; + } + } + + // Not found + return -1; +} + +/* +================ +idStaticList::Find + +Searches for the specified data in the list and returns it's address. Returns NULL if the data is not found. +================ +*/ +template +ID_INLINE type *idStaticList::Find( type const & obj ) const { + int i; + + i = FindIndex( obj ); + if ( i >= 0 ) { + return &list[ i ]; + } + + return NULL; +} + +/* +================ +idStaticList::FindNull + +Searches for a NULL pointer in the list. Returns -1 if NULL is not found. + +NOTE: This function can only be called on lists containing pointers. Calling it +on non-pointer lists will cause a compiler error. +================ +*/ +template +ID_INLINE int idStaticList::FindNull( void ) const { + int i; + + for( i = 0; i < num; i++ ) { + if ( list[ i ] == NULL ) { + return i; + } + } + + // Not found + return -1; +} + +/* +================ +idStaticList::IndexOf + +Takes a pointer to an element in the list and returns the index of the element. +This is NOT a guarantee that the object is really in the list. +Function will assert in debug builds if pointer is outside the bounds of the list, +but remains silent in release builds. +================ +*/ +template +ID_INLINE int idStaticList::IndexOf( type const *objptr ) const { + int index; + + index = objptr - list; + + assert( index >= 0 ); + assert( index < num ); + + return index; +} + +/* +================ +idStaticList::RemoveIndex + +Removes the element at the specified index and moves all data following the element down to fill in the gap. +The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. +Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. +================ +*/ +template +ID_INLINE bool idStaticList::RemoveIndex( int index ) { + int i; + + assert( index >= 0 ); + assert( index < num ); + + if ( ( index < 0 ) || ( index >= num ) ) { + return false; + } + + num--; + for( i = index; i < num; i++ ) { + list[ i ] = list[ i + 1 ]; + } + + return true; +} + +/* +================ +idStaticList::Remove + +Removes the element if it is found within the list and moves all data following the element down to fill in the gap. +The number of elements in the list is reduced by one. Returns false if the data is not found in the list. Note that +the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. +================ +*/ +template +ID_INLINE bool idStaticList::Remove( type const & obj ) { + int index; + + index = FindIndex( obj ); + if ( index >= 0 ) { + return RemoveIndex( index ); + } + + return false; +} + +/* +================ +idStaticList::Swap + +Swaps the contents of two lists +================ +*/ +template +ID_INLINE void idStaticList::Swap( idStaticList &other ) { + idStaticList temp = *this; + *this = other; + other = temp; +} + +#endif /* !__STATICLIST_H__ */ diff --git a/idlib/containers/StrList.h b/idlib/containers/StrList.h new file mode 100644 index 000000000..208456ad7 --- /dev/null +++ b/idlib/containers/StrList.h @@ -0,0 +1,195 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STRLIST_H__ +#define __STRLIST_H__ + +/* +=============================================================================== + + idStrList + +=============================================================================== +*/ + +typedef idList idStrList; +typedef idList idStrPtrList; +typedef idStr *idStrPtr; + +/* +================ +idListSortCompare + +Compares two pointers to strings. Used to sort a list of string pointers alphabetically in idList::Sort. +================ +*/ +template<> +ID_INLINE int idListSortCompare( const idStrPtr *a, const idStrPtr *b ) { + return ( *a )->Icmp( **b ); +} + +/* +================ +idStrList::Sort + +Sorts the list of strings alphabetically. Creates a list of pointers to the actual strings and sorts the +pointer list. Then copies the strings into another list using the ordered list of pointers. +================ +*/ +template<> +ID_INLINE void idStrList::Sort( cmp_t *compare ) { + int i; + + if ( !num ) { + return; + } + + idList other; + idList pointerList; + + pointerList.SetNum( num ); + for( i = 0; i < num; i++ ) { + pointerList[ i ] = &( *this )[ i ]; + } + + pointerList.Sort(); + + other.SetNum( num ); + other.SetGranularity( granularity ); + for( i = 0; i < other.Num(); i++ ) { + other[ i ] = *pointerList[ i ]; + } + + this->Swap( other ); +} + +/* +================ +idStrList::SortSubSection + +Sorts a subsection of the list of strings alphabetically. +================ +*/ +template<> +ID_INLINE void idStrList::SortSubSection( int startIndex, int endIndex, cmp_t *compare ) { + int i, s; + + if ( !num ) { + return; + } + if ( startIndex < 0 ) { + startIndex = 0; + } + if ( endIndex >= num ) { + endIndex = num - 1; + } + if ( startIndex >= endIndex ) { + return; + } + + idList other; + idList pointerList; + + s = endIndex - startIndex + 1; + other.SetNum( s ); + pointerList.SetNum( s ); + for( i = 0; i < s; i++ ) { + other[ i ] = ( *this )[ startIndex + i ]; + pointerList[ i ] = &other[ i ]; + } + + pointerList.Sort(); + + for( i = 0; i < s; i++ ) { + (*this)[ startIndex + i ] = *pointerList[ i ]; + } +} + +/* +================ +idStrList::Size +================ +*/ +template<> +ID_INLINE size_t idStrList::Size( void ) const { + size_t s; + int i; + + s = sizeof( *this ); + for( i = 0; i < Num(); i++ ) { + s += ( *this )[ i ].Size(); + } + + return s; +} + +/* +=============================================================================== + + idStrList path sorting + +=============================================================================== +*/ + +/* +================ +idListSortComparePaths + +Compares two pointers to strings. Used to sort a list of string pointers alphabetically in idList::Sort. +================ +*/ +template +ID_INLINE int idListSortComparePaths( const idStrPtr *a, const idStrPtr *b ) { + return ( *a )->IcmpPath( **b ); +} + +/* +================ +idStrListSortPaths + +Sorts the list of path strings alphabetically and makes sure folders come first. +================ +*/ +ID_INLINE void idStrListSortPaths( idStrList &list ) { + int i; + + if ( !list.Num() ) { + return; + } + + idList other; + idList pointerList; + + pointerList.SetNum( list.Num() ); + for( i = 0; i < list.Num(); i++ ) { + pointerList[ i ] = &list[ i ]; + } + + pointerList.Sort( idListSortComparePaths ); + + other.SetNum( list.Num() ); + other.SetGranularity( list.GetGranularity() ); + for( i = 0; i < other.Num(); i++ ) { + other[ i ] = *pointerList[ i ]; + } + + list.Swap( other ); +} + +#endif /* !__STRLIST_H__ */ diff --git a/idlib/containers/StrPool.h b/idlib/containers/StrPool.h new file mode 100644 index 000000000..908a79142 --- /dev/null +++ b/idlib/containers/StrPool.h @@ -0,0 +1,219 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __STRPOOL_H__ +#define __STRPOOL_H__ + +/* +=============================================================================== + + idStrPool + +=============================================================================== +*/ + +class idStrPool; + +class idPoolStr : public idStr { + friend class idStrPool; + +public: + idPoolStr() { numUsers = 0; } + ~idPoolStr() { assert( numUsers == 0 ); } + + // returns total size of allocated memory + size_t Allocated( void ) const { return idStr::Allocated(); } + // returns total size of allocated memory including size of string pool type + size_t Size( void ) const { return sizeof( *this ) + Allocated(); } + // returns a pointer to the pool this string was allocated from + const idStrPool * GetPool( void ) const { return pool; } + +private: + idStrPool * pool; + mutable int numUsers; +}; + +class idStrPool { +public: + idStrPool() { caseSensitive = true; } + + void SetCaseSensitive( bool caseSensitive ); + + int Num( void ) const { return pool.Num(); } + size_t Allocated( void ) const; + size_t Size( void ) const; + + const idPoolStr * operator[]( int index ) const { return pool[index]; } + + const idPoolStr * AllocString( const char *string ); + void FreeString( const idPoolStr *poolStr ); + const idPoolStr * CopyString( const idPoolStr *poolStr ); + void Clear( void ); + +private: + bool caseSensitive; + idList pool; + idHashIndex poolHash; +}; + +/* +================ +idStrPool::SetCaseSensitive +================ +*/ +ID_INLINE void idStrPool::SetCaseSensitive( bool caseSensitive ) { + this->caseSensitive = caseSensitive; +} + +/* +================ +idStrPool::AllocString +================ +*/ +ID_INLINE const idPoolStr *idStrPool::AllocString( const char *string ) { + int i, hash; + idPoolStr *poolStr; + + hash = poolHash.GenerateKey( string, caseSensitive ); + if ( caseSensitive ) { + for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { + if ( pool[i]->Cmp( string ) == 0 ) { + pool[i]->numUsers++; + return pool[i]; + } + } + } else { + for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { + if ( pool[i]->Icmp( string ) == 0 ) { + pool[i]->numUsers++; + return pool[i]; + } + } + } + + poolStr = new idPoolStr; + *static_cast(poolStr) = string; + poolStr->pool = this; + poolStr->numUsers = 1; + poolHash.Add( hash, pool.Append( poolStr ) ); + return poolStr; +} + +/* +================ +idStrPool::FreeString +================ +*/ +ID_INLINE void idStrPool::FreeString( const idPoolStr *poolStr ) { + int i, hash; + + assert( poolStr->numUsers >= 1 ); + assert( poolStr->pool == this ); + + poolStr->numUsers--; + if ( poolStr->numUsers <= 0 ) { + hash = poolHash.GenerateKey( poolStr->c_str(), caseSensitive ); + if ( caseSensitive ) { + for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { + if ( pool[i]->Cmp( poolStr->c_str() ) == 0 ) { + break; + } + } + } else { + for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { + if ( pool[i]->Icmp( poolStr->c_str() ) == 0 ) { + break; + } + } + } + assert( i != -1 ); + assert( pool[i] == poolStr ); + delete pool[i]; + pool.RemoveIndex( i ); + poolHash.RemoveIndex( hash, i ); + } +} + +/* +================ +idStrPool::CopyString +================ +*/ +ID_INLINE const idPoolStr *idStrPool::CopyString( const idPoolStr *poolStr ) { + + assert( poolStr->numUsers >= 1 ); + + if ( poolStr->pool == this ) { + // the string is from this pool so just increase the user count + poolStr->numUsers++; + return poolStr; + } else { + // the string is from another pool so it needs to be re-allocated from this pool. + return AllocString( poolStr->c_str() ); + } +} + +/* +================ +idStrPool::Clear +================ +*/ +ID_INLINE void idStrPool::Clear( void ) { + int i; + + for ( i = 0; i < pool.Num(); i++ ) { + pool[i]->numUsers = 0; + } + pool.DeleteContents( true ); + poolHash.Free(); +} + +/* +================ +idStrPool::Allocated +================ +*/ +ID_INLINE size_t idStrPool::Allocated( void ) const { + int i; + size_t size; + + size = pool.Allocated() + poolHash.Allocated(); + for ( i = 0; i < pool.Num(); i++ ) { + size += pool[i]->Allocated(); + } + return size; +} + +/* +================ +idStrPool::Size +================ +*/ +ID_INLINE size_t idStrPool::Size( void ) const { + int i; + size_t size; + + size = pool.Size() + poolHash.Size(); + for ( i = 0; i < pool.Num(); i++ ) { + size += pool[i]->Size(); + } + return size; +} + +#endif /* !__STRPOOL_H__ */ diff --git a/idlib/containers/VectorSet.h b/idlib/containers/VectorSet.h new file mode 100644 index 000000000..da3a8416f --- /dev/null +++ b/idlib/containers/VectorSet.h @@ -0,0 +1,261 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __VECTORSET_H__ +#define __VECTORSET_H__ + +/* +=============================================================================== + + Vector Set + + Creates a set of vectors without duplicates. + +=============================================================================== +*/ + +template< class type, int dimension > +class idVectorSet : public idList { +public: + idVectorSet( void ); + idVectorSet( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); + + // returns total size of allocated memory + size_t Allocated( void ) const { return idList::Allocated() + hash.Allocated(); } + // returns total size of allocated memory including size of type + size_t Size( void ) const { return sizeof( *this ) + Allocated(); } + + void Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); + void ResizeIndex( const int newSize ); + void Clear( void ); + + int FindVector( const type &v, const float epsilon ); + +private: + idHashIndex hash; + type mins; + type maxs; + int boxHashSize; + float boxInvSize[dimension]; + float boxHalfSize[dimension]; +}; + +template< class type, int dimension > +ID_INLINE idVectorSet::idVectorSet( void ) { + hash.Clear( idMath::IPow( boxHashSize, dimension ), 128 ); + boxHashSize = 16; + memset( boxInvSize, 0, dimension * sizeof( boxInvSize[0] ) ); + memset( boxHalfSize, 0, dimension * sizeof( boxHalfSize[0] ) ); +} + +template< class type, int dimension > +ID_INLINE idVectorSet::idVectorSet( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { + Init( mins, maxs, boxHashSize, initialSize ); +} + +template< class type, int dimension > +ID_INLINE void idVectorSet::Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { + int i; + float boxSize; + + idList::AssureSize( initialSize ); + idList::SetNum( 0, false ); + + hash.Clear( idMath::IPow( boxHashSize, dimension ), initialSize ); + + this->mins = mins; + this->maxs = maxs; + this->boxHashSize = boxHashSize; + + for ( i = 0; i < dimension; i++ ) { + boxSize = ( maxs[i] - mins[i] ) / (float) boxHashSize; + boxInvSize[i] = 1.0f / boxSize; + boxHalfSize[i] = boxSize * 0.5f; + } +} + +template< class type, int dimension > +ID_INLINE void idVectorSet::ResizeIndex( const int newSize ) { + idList::Resize( newSize ); + hash.ResizeIndex( newSize ); +} + +template< class type, int dimension > +ID_INLINE void idVectorSet::Clear( void ) { + idList::Clear(); + hash.Clear(); +} + +template< class type, int dimension > +ID_INLINE int idVectorSet::FindVector( const type &v, const float epsilon ) { + int i, j, k, hashKey, partialHashKey[dimension]; + + for ( i = 0; i < dimension; i++ ) { + assert( epsilon <= boxHalfSize[i] ); + partialHashKey[i] = (int) ( ( v[i] - mins[i] - boxHalfSize[i] ) * boxInvSize[i] ); + } + + for ( i = 0; i < ( 1 << dimension ); i++ ) { + + hashKey = 0; + for ( j = 0; j < dimension; j++ ) { + hashKey *= boxHashSize; + hashKey += partialHashKey[j] + ( ( i >> j ) & 1 ); + } + + for ( j = hash.First( hashKey ); j >= 0; j = hash.Next( j ) ) { + const type &lv = (*this)[j]; + for ( k = 0; k < dimension; k++ ) { + if ( idMath::Fabs( lv[k] - v[k] ) > epsilon ) { + break; + } + } + if ( k >= dimension ) { + return j; + } + } + } + + hashKey = 0; + for ( i = 0; i < dimension; i++ ) { + hashKey *= boxHashSize; + hashKey += (int) ( ( v[i] - mins[i] ) * boxInvSize[i] ); + } + + hash.Add( hashKey, idList::Num() ); + Append( v ); + return idList::Num()-1; +} + + +/* +=============================================================================== + + Vector Subset + + Creates a subset without duplicates from an existing list with vectors. + +=============================================================================== +*/ + +template< class type, int dimension > +class idVectorSubset { +public: + idVectorSubset( void ); + idVectorSubset( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); + + // returns total size of allocated memory + size_t Allocated( void ) const { return idList::Allocated() + hash.Allocated(); } + // returns total size of allocated memory including size of type + size_t Size( void ) const { return sizeof( *this ) + Allocated(); } + + void Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); + void Clear( void ); + + // returns either vectorNum or an index to a previously found vector + int FindVector( const type *vectorList, const int vectorNum, const float epsilon ); + +private: + idHashIndex hash; + type mins; + type maxs; + int boxHashSize; + float boxInvSize[dimension]; + float boxHalfSize[dimension]; +}; + +template< class type, int dimension > +ID_INLINE idVectorSubset::idVectorSubset( void ) { + hash.Clear( idMath::IPow( boxHashSize, dimension ), 128 ); + boxHashSize = 16; + memset( boxInvSize, 0, dimension * sizeof( boxInvSize[0] ) ); + memset( boxHalfSize, 0, dimension * sizeof( boxHalfSize[0] ) ); +} + +template< class type, int dimension > +ID_INLINE idVectorSubset::idVectorSubset( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { + Init( mins, maxs, boxHashSize, initialSize ); +} + +template< class type, int dimension > +ID_INLINE void idVectorSubset::Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { + int i; + float boxSize; + + hash.Clear( idMath::IPow( boxHashSize, dimension ), initialSize ); + + this->mins = mins; + this->maxs = maxs; + this->boxHashSize = boxHashSize; + + for ( i = 0; i < dimension; i++ ) { + boxSize = ( maxs[i] - mins[i] ) / (float) boxHashSize; + boxInvSize[i] = 1.0f / boxSize; + boxHalfSize[i] = boxSize * 0.5f; + } +} + +template< class type, int dimension > +ID_INLINE void idVectorSubset::Clear( void ) { + idList::Clear(); + hash.Clear(); +} + +template< class type, int dimension > +ID_INLINE int idVectorSubset::FindVector( const type *vectorList, const int vectorNum, const float epsilon ) { + int i, j, k, hashKey, partialHashKey[dimension]; + const type &v = vectorList[vectorNum]; + + for ( i = 0; i < dimension; i++ ) { + assert( epsilon <= boxHalfSize[i] ); + partialHashKey[i] = (int) ( ( v[i] - mins[i] - boxHalfSize[i] ) * boxInvSize[i] ); + } + + for ( i = 0; i < ( 1 << dimension ); i++ ) { + + hashKey = 0; + for ( j = 0; j < dimension; j++ ) { + hashKey *= boxHashSize; + hashKey += partialHashKey[j] + ( ( i >> j ) & 1 ); + } + + for ( j = hash.First( hashKey ); j >= 0; j = hash.Next( j ) ) { + const type &lv = vectorList[j]; + for ( k = 0; k < dimension; k++ ) { + if ( idMath::Fabs( lv[k] - v[k] ) > epsilon ) { + break; + } + } + if ( k >= dimension ) { + return j; + } + } + } + + hashKey = 0; + for ( i = 0; i < dimension; i++ ) { + hashKey *= boxHashSize; + hashKey += (int) ( ( v[i] - mins[i] ) * boxInvSize[i] ); + } + + hash.Add( hashKey, vectorNum ); + return vectorNum; +} + +#endif /* !__VECTORSET_H__ */ diff --git a/idlib/containers/binsearch.h b/idlib/containers/binsearch.h deleted file mode 100644 index 5ea31335d..000000000 --- a/idlib/containers/binsearch.h +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BINSEARCH_H__ -#define __BINSEARCH_H__ - -/* -=============================================================================== - - Binary Search templates - - The array elements have to be ordered in increasing order. - -=============================================================================== -*/ - -/* -==================== -idBinSearch_GreaterEqual - - Finds the last array element which is smaller than the given value. -==================== -*/ -template< class type > -ID_INLINE int idBinSearch_Less( const type *array, const int arraySize, const type &value ) { - int len = arraySize; - int mid = len; - int offset = 0; - while( mid > 0 ) { - mid = len >> 1; - if ( array[offset+mid] < value ) { - offset += mid; - } - len -= mid; - } - return offset; -} - -/* -==================== -idBinSearch_GreaterEqual - - Finds the last array element which is smaller than or equal to the given value. -==================== -*/ -template< class type > -ID_INLINE int idBinSearch_LessEqual( const type *array, const int arraySize, const type &value ) { - int len = arraySize; - int mid = len; - int offset = 0; - while( mid > 0 ) { - mid = len >> 1; - if ( array[offset+mid] <= value ) { - offset += mid; - } - len -= mid; - } - return offset; -} - -/* -==================== -idBinSearch_Greater - - Finds the first array element which is greater than the given value. -==================== -*/ -template< class type > -ID_INLINE int idBinSearch_Greater( const type *array, const int arraySize, const type &value ) { - int len = arraySize; - int mid = len; - int offset = 0; - int res = 0; - while( mid > 0 ) { - mid = len >> 1; - if ( array[offset+mid] > value ) { - res = 0; - } else { - offset += mid; - res = 1; - } - len -= mid; - } - return offset+res; -} - -/* -==================== -idBinSearch_GreaterEqual - - Finds the first array element which is greater than or equal to the given value. -==================== -*/ -template< class type > -ID_INLINE int idBinSearch_GreaterEqual( const type *array, const int arraySize, const type &value ) { - int len = arraySize; - int mid = len; - int offset = 0; - int res = 0; - while( mid > 0 ) { - mid = len >> 1; - if ( array[offset+mid] >= value ) { - res = 0; - } else { - offset += mid; - res = 1; - } - len -= mid; - } - return offset+res; -} - -#endif /* !__BINSEARCH_H__ */ diff --git a/idlib/containers/btree.h b/idlib/containers/btree.h deleted file mode 100644 index 1d6736f99..000000000 --- a/idlib/containers/btree.h +++ /dev/null @@ -1,510 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __BTREE_H__ -#define __BTREE_H__ - -#ifdef __linux__ -#include "sys/sys_public.h" -#endif - -/* -=============================================================================== - - Balanced Search Tree - -=============================================================================== -*/ - -//#define BTREE_CHECK - -template< class objType, class keyType > -class idBTreeNode { -public: - keyType key; // key used for sorting - objType * object; // if != NULL pointer to object stored in leaf node - idBTreeNode * parent; // parent node - idBTreeNode * next; // next sibling - idBTreeNode * prev; // prev sibling - int numChildren; // number of children - idBTreeNode * firstChild; // first child - idBTreeNode * lastChild; // last child -}; - - -template< class objType, class keyType, int maxChildrenPerNode > -class idBTree { -public: - idBTree( void ); - ~idBTree( void ); - - void Init( void ); - void Shutdown( void ); - - idBTreeNode * Add( objType *object, keyType key ); // add an object to the tree - void Remove( idBTreeNode *node ); // remove an object node from the tree - - objType * Find( keyType key ) const; // find an object using the given key - objType * FindSmallestLargerEqual( keyType key ) const; // find an object with the smallest key larger equal the given key - objType * FindLargestSmallerEqual( keyType key ) const; // find an object with the largest key smaller equal the given key - - idBTreeNode * GetRoot( void ) const; // returns the root node of the tree - int GetNodeCount( void ) const; // returns the total number of nodes in the tree - idBTreeNode * GetNext( idBTreeNode *node ) const; // goes through all nodes of the tree - idBTreeNode * GetNextLeaf( idBTreeNode *node ) const; // goes through all leaf nodes of the tree - -private: - idBTreeNode * root; - idBlockAlloc,128> nodeAllocator; - - idBTreeNode * AllocNode( void ); - void FreeNode( idBTreeNode *node ); - void SplitNode( idBTreeNode *node ); - idBTreeNode * MergeNodes( idBTreeNode *node1, idBTreeNode *node2 ); - - void CheckTree_r( idBTreeNode *node, int &numNodes ) const; - void CheckTree( void ) const; -}; - -#pragma warning( push ) -#pragma warning( disable : 4533 4127 ) -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTree::idBTree( void ) { - assert( maxChildrenPerNode >= 4 ); - root = NULL; -} -#pragma warning( pop ) - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTree::~idBTree( void ) { - Shutdown(); -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::Init( void ) { - root = AllocNode(); -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::Shutdown( void ) { - nodeAllocator.Shutdown(); - root = NULL; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::Add( objType *object, keyType key ) { - idBTreeNode *node, *child, *newNode; - - if ( root->numChildren >= maxChildrenPerNode ) { - newNode = AllocNode(); - newNode->key = root->key; - newNode->firstChild = root; - newNode->lastChild = root; - newNode->numChildren = 1; - root->parent = newNode; - SplitNode( root ); - root = newNode; - } - - newNode = AllocNode(); - newNode->key = key; - newNode->object = object; - - for ( node = root; node->firstChild != NULL; node = child ) { - - if ( key > node->key ) { - node->key = key; - } - - // find the first child with a key larger equal to the key of the new node - for( child = node->firstChild; child->next; child = child->next ) { - if ( key <= child->key ) { - break; - } - } - - if ( child->object ) { - - if ( key <= child->key ) { - // insert new node before child - if ( child->prev ) { - child->prev->next = newNode; - } else { - node->firstChild = newNode; - } - newNode->prev = child->prev; - newNode->next = child; - child->prev = newNode; - } else { - // insert new node after child - if ( child->next ) { - child->next->prev = newNode; - } else { - node->lastChild = newNode; - } - newNode->prev = child; - newNode->next = child->next; - child->next = newNode; - } - - newNode->parent = node; - node->numChildren++; - -#ifdef BTREE_CHECK - CheckTree(); -#endif - - return newNode; - } - - // make sure the child has room to store another node - if ( child->numChildren >= maxChildrenPerNode ) { - SplitNode( child ); - if ( key <= child->prev->key ) { - child = child->prev; - } - } - } - - // we only end up here if the root node is empty - newNode->parent = root; - root->key = key; - root->firstChild = newNode; - root->lastChild = newNode; - root->numChildren++; - -#ifdef BTREE_CHECK - CheckTree(); -#endif - - return newNode; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::Remove( idBTreeNode *node ) { - idBTreeNode *parent; - - assert( node->object != NULL ); - - // unlink the node from it's parent - if ( node->prev ) { - node->prev->next = node->next; - } else { - node->parent->firstChild = node->next; - } - if ( node->next ) { - node->next->prev = node->prev; - } else { - node->parent->lastChild = node->prev; - } - node->parent->numChildren--; - - // make sure there are no parent nodes with a single child - for ( parent = node->parent; parent != root && parent->numChildren <= 1; parent = parent->parent ) { - - if ( parent->next ) { - parent = MergeNodes( parent, parent->next ); - } else if ( parent->prev ) { - parent = MergeNodes( parent->prev, parent ); - } - - // a parent may not use a key higher than the key of it's last child - if ( parent->key > parent->lastChild->key ) { - parent->key = parent->lastChild->key; - } - - if ( parent->numChildren > maxChildrenPerNode ) { - SplitNode( parent ); - break; - } - } - for ( ; parent != NULL && parent->lastChild != NULL; parent = parent->parent ) { - // a parent may not use a key higher than the key of it's last child - if ( parent->key > parent->lastChild->key ) { - parent->key = parent->lastChild->key; - } - } - - // free the node - FreeNode( node ); - - // remove the root node if it has a single internal node as child - if ( root->numChildren == 1 && root->firstChild->object == NULL ) { - idBTreeNode *oldRoot = root; - root->firstChild->parent = NULL; - root = root->firstChild; - FreeNode( oldRoot ); - } - -#ifdef BTREE_CHECK - CheckTree(); -#endif -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE objType *idBTree::Find( keyType key ) const { - idBTreeNode *node; - - for ( node = root->firstChild; node != NULL; node = node->firstChild ) { - while( node->next ) { - if ( node->key >= key ) { - break; - } - node = node->next; - } - if ( node->object ) { - if ( node->key == key ) { - return node->object; - } else { - return NULL; - } - } - } - return NULL; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE objType *idBTree::FindSmallestLargerEqual( keyType key ) const { - idBTreeNode *node; - - for ( node = root->firstChild; node != NULL; node = node->firstChild ) { - while( node->next ) { - if ( node->key >= key ) { - break; - } - node = node->next; - } - if ( node->object ) { - if ( node->key >= key ) { - return node->object; - } else { - return NULL; - } - } - } - return NULL; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE objType *idBTree::FindLargestSmallerEqual( keyType key ) const { - idBTreeNode *node; - - for ( node = root->lastChild; node != NULL; node = node->lastChild ) { - while( node->prev ) { - if ( node->key <= key ) { - break; - } - node = node->prev; - } - if ( node->object ) { - if ( node->key <= key ) { - return node->object; - } else { - return NULL; - } - } - } - return NULL; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::GetRoot( void ) const { - return root; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE int idBTree::GetNodeCount( void ) const { - return nodeAllocator.GetAllocCount(); -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::GetNext( idBTreeNode *node ) const { - if ( node->firstChild ) { - return node->firstChild; - } else { - while( node && node->next == NULL ) { - node = node->parent; - } - return node; - } -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::GetNextLeaf( idBTreeNode *node ) const { - if ( node->firstChild ) { - while ( node->firstChild ) { - node = node->firstChild; - } - return node; - } else { - while( node && node->next == NULL ) { - node = node->parent; - } - if ( node ) { - node = node->next; - while ( node->firstChild ) { - node = node->firstChild; - } - return node; - } else { - return NULL; - } - } -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::AllocNode( void ) { - idBTreeNode *node = nodeAllocator.Alloc(); - node->key = 0; - node->parent = NULL; - node->next = NULL; - node->prev = NULL; - node->numChildren = 0; - node->firstChild = NULL; - node->lastChild = NULL; - node->object = NULL; - return node; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::FreeNode( idBTreeNode *node ) { - nodeAllocator.Free( node ); -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::SplitNode( idBTreeNode *node ) { - int i; - idBTreeNode *child, *newNode; - - // allocate a new node - newNode = AllocNode(); - newNode->parent = node->parent; - - // divide the children over the two nodes - child = node->firstChild; - child->parent = newNode; - for ( i = 3; i < node->numChildren; i += 2 ) { - child = child->next; - child->parent = newNode; - } - - newNode->key = child->key; - newNode->numChildren = node->numChildren / 2; - newNode->firstChild = node->firstChild; - newNode->lastChild = child; - - node->numChildren -= newNode->numChildren; - node->firstChild = child->next; - - child->next->prev = NULL; - child->next = NULL; - - // add the new child to the parent before the split node - assert( node->parent->numChildren < maxChildrenPerNode ); - - if ( node->prev ) { - node->prev->next = newNode; - } else { - node->parent->firstChild = newNode; - } - newNode->prev = node->prev; - newNode->next = node; - node->prev = newNode; - - node->parent->numChildren++; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE idBTreeNode *idBTree::MergeNodes( idBTreeNode *node1, idBTreeNode *node2 ) { - idBTreeNode *child; - - assert( node1->parent == node2->parent ); - assert( node1->next == node2 && node2->prev == node1 ); - assert( node1->object == NULL && node2->object == NULL ); - assert( node1->numChildren >= 1 && node2->numChildren >= 1 ); - - for ( child = node1->firstChild; child->next; child = child->next ) { - child->parent = node2; - } - child->parent = node2; - child->next = node2->firstChild; - node2->firstChild->prev = child; - node2->firstChild = node1->firstChild; - node2->numChildren += node1->numChildren; - - // unlink the first node from the parent - if ( node1->prev ) { - node1->prev->next = node2; - } else { - node1->parent->firstChild = node2; - } - node2->prev = node1->prev; - node2->parent->numChildren--; - - FreeNode( node1 ); - - return node2; -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::CheckTree_r( idBTreeNode *node, int &numNodes ) const { - int numChildren; - idBTreeNode *child; - - numNodes++; - - // the root node may have zero children and leaf nodes always have zero children, all other nodes should have at least 2 and at most maxChildrenPerNode children - assert( ( node == root ) || ( node->object != NULL && node->numChildren == 0 ) || ( node->numChildren >= 2 && node->numChildren <= maxChildrenPerNode ) ); - // the key of a node may never be larger than the key of it's last child - assert( ( node->lastChild == NULL ) || ( node->key <= node->lastChild->key ) ); - - numChildren = 0; - for ( child = node->firstChild; child; child = child->next ) { - numChildren++; - // make sure the children are properly linked - if ( child->prev == NULL ) { - assert( node->firstChild == child ); - } else { - assert( child->prev->next == child ); - } - if ( child->next == NULL ) { - assert( node->lastChild == child ); - } else { - assert( child->next->prev == child ); - } - // recurse down the tree - CheckTree_r( child, numNodes ); - } - // the number of children should equal the number of linked children - assert( numChildren == node->numChildren ); -} - -template< class objType, class keyType, int maxChildrenPerNode > -ID_INLINE void idBTree::CheckTree( void ) const { - int numNodes = 0; - idBTreeNode *node, *lastNode; - - CheckTree_r( root, numNodes ); - - // the number of nodes in the tree should equal the number of allocated nodes - assert( numNodes == nodeAllocator.GetAllocCount() ); - - // all the leaf nodes should be ordered - lastNode = GetNextLeaf( GetRoot() ); - if ( lastNode ) { - for ( node = GetNextLeaf( lastNode ); node; lastNode = node, node = GetNextLeaf( node ) ) { - assert( lastNode->key <= node->key ); - } - } -} - -#endif /* !__BTREE_H__ */ diff --git a/idlib/containers/hashindex.cpp b/idlib/containers/hashindex.cpp deleted file mode 100644 index f9846c646..000000000 --- a/idlib/containers/hashindex.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -int idHashIndex::INVALID_INDEX[1] = { -1 }; - -/* -================ -idHashIndex::Init -================ -*/ -void idHashIndex::Init( const int initialHashSize, const int initialIndexSize ) { - assert( idMath::IsPowerOfTwo( initialHashSize ) ); - - hashSize = initialHashSize; - hash = INVALID_INDEX; - indexSize = initialIndexSize; - indexChain = INVALID_INDEX; - granularity = DEFAULT_HASH_GRANULARITY; - hashMask = hashSize - 1; - lookupMask = 0; -} - -/* -================ -idHashIndex::Allocate -================ -*/ -void idHashIndex::Allocate( const int newHashSize, const int newIndexSize ) { - assert( idMath::IsPowerOfTwo( newHashSize ) ); - - Free(); - hashSize = newHashSize; - hash = new int[hashSize]; - memset( hash, 0xff, hashSize * sizeof( hash[0] ) ); - indexSize = newIndexSize; - indexChain = new int[indexSize]; - memset( indexChain, 0xff, indexSize * sizeof( indexChain[0] ) ); - hashMask = hashSize - 1; - lookupMask = -1; -} - -/* -================ -idHashIndex::Free -================ -*/ -void idHashIndex::Free( void ) { - if ( hash != INVALID_INDEX ) { - delete[] hash; - hash = INVALID_INDEX; - } - if ( indexChain != INVALID_INDEX ) { - delete[] indexChain; - indexChain = INVALID_INDEX; - } - lookupMask = 0; -} - -/* -================ -idHashIndex::ResizeIndex -================ -*/ -void idHashIndex::ResizeIndex( const int newIndexSize ) { - int *oldIndexChain, mod, newSize; - - if ( newIndexSize <= indexSize ) { - return; - } - - mod = newIndexSize % granularity; - if ( !mod ) { - newSize = newIndexSize; - } else { - newSize = newIndexSize + granularity - mod; - } - - if ( indexChain == INVALID_INDEX ) { - indexSize = newSize; - return; - } - - oldIndexChain = indexChain; - indexChain = new int[newSize]; - memcpy( indexChain, oldIndexChain, indexSize * sizeof(int) ); - memset( indexChain + indexSize, 0xff, (newSize - indexSize) * sizeof(int) ); - delete[] oldIndexChain; - indexSize = newSize; -} - -/* -================ -idHashIndex::GetSpread -================ -*/ -int idHashIndex::GetSpread( void ) const { - int i, index, totalItems, *numHashItems, average, error, e; - - if ( hash == INVALID_INDEX ) { - return 100; - } - - totalItems = 0; - numHashItems = new int[hashSize]; - for ( i = 0; i < hashSize; i++ ) { - numHashItems[i] = 0; - for ( index = hash[i]; index >= 0; index = indexChain[index] ) { - numHashItems[i]++; - } - totalItems += numHashItems[i]; - } - // if no items in hash - if ( totalItems <= 1 ) { - delete[] numHashItems; - return 100; - } - average = totalItems / hashSize; - error = 0; - for ( i = 0; i < hashSize; i++ ) { - e = abs( numHashItems[i] - average ); - if ( e > 1 ) { - error += e - 1; - } - } - delete[] numHashItems; - return 100 - (error * 100 / totalItems); -} diff --git a/idlib/containers/hashindex.h b/idlib/containers/hashindex.h deleted file mode 100644 index 4ec1fa3e1..000000000 --- a/idlib/containers/hashindex.h +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __HASHINDEX_H__ -#define __HASHINDEX_H__ - -/* -=============================================================================== - - Fast hash table for indexes and arrays. - Does not allocate memory until the first key/index pair is added. - -=============================================================================== -*/ - -#define DEFAULT_HASH_SIZE 1024 -#define DEFAULT_HASH_GRANULARITY 1024 - -class idHashIndex { -public: - idHashIndex( void ); - idHashIndex( const int initialHashSize, const int initialIndexSize ); - ~idHashIndex( void ); - - // returns total size of allocated memory - size_t Allocated( void ) const; - // returns total size of allocated memory including size of hash index type - size_t Size( void ) const; - - idHashIndex & operator=( const idHashIndex &other ); - // add an index to the hash, assumes the index has not yet been added to the hash - void Add( const int key, const int index ); - // remove an index from the hash - void Remove( const int key, const int index ); - // get the first index from the hash, returns -1 if empty hash entry - int First( const int key ) const; - // get the next index from the hash, returns -1 if at the end of the hash chain - int Next( const int index ) const; - // insert an entry into the index and add it to the hash, increasing all indexes >= index - void InsertIndex( const int key, const int index ); - // remove an entry from the index and remove it from the hash, decreasing all indexes >= index - void RemoveIndex( const int key, const int index ); - // clear the hash - void Clear( void ); - // clear and resize - void Clear( const int newHashSize, const int newIndexSize ); - // free allocated memory - void Free( void ); - // get size of hash table - int GetHashSize( void ) const; - // get size of the index - int GetIndexSize( void ) const; - // set granularity - void SetGranularity( const int newGranularity ); - // force resizing the index, current hash table stays intact - void ResizeIndex( const int newIndexSize ); - // returns number in the range [0-100] representing the spread over the hash table - int GetSpread( void ) const; - // returns a key for a string - int GenerateKey( const char *string, bool caseSensitive = true ) const; - // returns a key for a vector - int GenerateKey( const idVec3 &v ) const; - // returns a key for two integers - int GenerateKey( const int n1, const int n2 ) const; - -private: - int hashSize; - int * hash; - int indexSize; - int * indexChain; - int granularity; - int hashMask; - int lookupMask; - - static int INVALID_INDEX[1]; - - void Init( const int initialHashSize, const int initialIndexSize ); - void Allocate( const int newHashSize, const int newIndexSize ); -}; - -/* -================ -idHashIndex::idHashIndex -================ -*/ -ID_INLINE idHashIndex::idHashIndex( void ) { - Init( DEFAULT_HASH_SIZE, DEFAULT_HASH_SIZE ); -} - -/* -================ -idHashIndex::idHashIndex -================ -*/ -ID_INLINE idHashIndex::idHashIndex( const int initialHashSize, const int initialIndexSize ) { - Init( initialHashSize, initialIndexSize ); -} - -/* -================ -idHashIndex::~idHashIndex -================ -*/ -ID_INLINE idHashIndex::~idHashIndex( void ) { - Free(); -} - -/* -================ -idHashIndex::Allocated -================ -*/ -ID_INLINE size_t idHashIndex::Allocated( void ) const { - return hashSize * sizeof( int ) + indexSize * sizeof( int ); -} - -/* -================ -idHashIndex::Size -================ -*/ -ID_INLINE size_t idHashIndex::Size( void ) const { - return sizeof( *this ) + Allocated(); -} - -/* -================ -idHashIndex::operator= -================ -*/ -ID_INLINE idHashIndex &idHashIndex::operator=( const idHashIndex &other ) { - granularity = other.granularity; - hashMask = other.hashMask; - lookupMask = other.lookupMask; - - if ( other.lookupMask == 0 ) { - hashSize = other.hashSize; - indexSize = other.indexSize; - Free(); - } - else { - if ( other.hashSize != hashSize || hash == INVALID_INDEX ) { - if ( hash != INVALID_INDEX ) { - delete[] hash; - } - hashSize = other.hashSize; - hash = new int[hashSize]; - } - if ( other.indexSize != indexSize || indexChain == INVALID_INDEX ) { - if ( indexChain != INVALID_INDEX ) { - delete[] indexChain; - } - indexSize = other.indexSize; - indexChain = new int[indexSize]; - } - memcpy( hash, other.hash, hashSize * sizeof( hash[0] ) ); - memcpy( indexChain, other.indexChain, indexSize * sizeof( indexChain[0] ) ); - } - - return *this; -} - -/* -================ -idHashIndex::Add -================ -*/ -ID_INLINE void idHashIndex::Add( const int key, const int index ) { - int h; - - assert( index >= 0 ); - if ( hash == INVALID_INDEX ) { - Allocate( hashSize, index >= indexSize ? index + 1 : indexSize ); - } - else if ( index >= indexSize ) { - ResizeIndex( index + 1 ); - } - h = key & hashMask; - indexChain[index] = hash[h]; - hash[h] = index; -} - -/* -================ -idHashIndex::Remove -================ -*/ -ID_INLINE void idHashIndex::Remove( const int key, const int index ) { - int k = key & hashMask; - - if ( hash == INVALID_INDEX ) { - return; - } - if ( hash[k] == index ) { - hash[k] = indexChain[index]; - } - else { - for ( int i = hash[k]; i != -1; i = indexChain[i] ) { - if ( indexChain[i] == index ) { - indexChain[i] = indexChain[index]; - break; - } - } - } - indexChain[index] = -1; -} - -/* -================ -idHashIndex::First -================ -*/ -ID_INLINE int idHashIndex::First( const int key ) const { - return hash[key & hashMask & lookupMask]; -} - -/* -================ -idHashIndex::Next -================ -*/ -ID_INLINE int idHashIndex::Next( const int index ) const { - assert( index >= 0 && index < indexSize ); - return indexChain[index & lookupMask]; -} - -/* -================ -idHashIndex::InsertIndex -================ -*/ -ID_INLINE void idHashIndex::InsertIndex( const int key, const int index ) { - int i, max; - - if ( hash != INVALID_INDEX ) { - max = index; - for ( i = 0; i < hashSize; i++ ) { - if ( hash[i] >= index ) { - hash[i]++; - if ( hash[i] > max ) { - max = hash[i]; - } - } - } - for ( i = 0; i < indexSize; i++ ) { - if ( indexChain[i] >= index ) { - indexChain[i]++; - if ( indexChain[i] > max ) { - max = indexChain[i]; - } - } - } - if ( max >= indexSize ) { - ResizeIndex( max + 1 ); - } - for ( i = max; i > index; i-- ) { - indexChain[i] = indexChain[i-1]; - } - indexChain[index] = -1; - } - Add( key, index ); -} - -/* -================ -idHashIndex::RemoveIndex -================ -*/ -ID_INLINE void idHashIndex::RemoveIndex( const int key, const int index ) { - int i, max; - - Remove( key, index ); - if ( hash != INVALID_INDEX ) { - max = index; - for ( i = 0; i < hashSize; i++ ) { - if ( hash[i] >= index ) { - if ( hash[i] > max ) { - max = hash[i]; - } - hash[i]--; - } - } - for ( i = 0; i < indexSize; i++ ) { - if ( indexChain[i] >= index ) { - if ( indexChain[i] > max ) { - max = indexChain[i]; - } - indexChain[i]--; - } - } - for ( i = index; i < max; i++ ) { - indexChain[i] = indexChain[i+1]; - } - indexChain[max] = -1; - } -} - -/* -================ -idHashIndex::Clear -================ -*/ -ID_INLINE void idHashIndex::Clear( void ) { - // only clear the hash table because clearing the indexChain is not really needed - if ( hash != INVALID_INDEX ) { - memset( hash, 0xff, hashSize * sizeof( hash[0] ) ); - } -} - -/* -================ -idHashIndex::Clear -================ -*/ -ID_INLINE void idHashIndex::Clear( const int newHashSize, const int newIndexSize ) { - Free(); - hashSize = newHashSize; - indexSize = newIndexSize; -} - -/* -================ -idHashIndex::GetHashSize -================ -*/ -ID_INLINE int idHashIndex::GetHashSize( void ) const { - return hashSize; -} - -/* -================ -idHashIndex::GetIndexSize -================ -*/ -ID_INLINE int idHashIndex::GetIndexSize( void ) const { - return indexSize; -} - -/* -================ -idHashIndex::SetGranularity -================ -*/ -ID_INLINE void idHashIndex::SetGranularity( const int newGranularity ) { - assert( newGranularity > 0 ); - granularity = newGranularity; -} - -/* -================ -idHashIndex::GenerateKey -================ -*/ -ID_INLINE int idHashIndex::GenerateKey( const char *string, bool caseSensitive ) const { - if ( caseSensitive ) { - return ( idStr::Hash( string ) & hashMask ); - } else { - return ( idStr::IHash( string ) & hashMask ); - } -} - -/* -================ -idHashIndex::GenerateKey -================ -*/ -ID_INLINE int idHashIndex::GenerateKey( const idVec3 &v ) const { - return ( (((int) v[0]) + ((int) v[1]) + ((int) v[2])) & hashMask ); -} - -/* -================ -idHashIndex::GenerateKey -================ -*/ -ID_INLINE int idHashIndex::GenerateKey( const int n1, const int n2 ) const { - return ( ( n1 + n2 ) & hashMask ); -} - -// stgatilov: class for displaying hash + index arrays of idHashIndex -// in MSVC debug watch (look "autoexp.dat") -struct _idHashIndex_showarray_helper { - int size; - int *ptr; -}; - -#endif /* !__HASHINDEX_H__ */ diff --git a/idlib/containers/hashtable.h b/idlib/containers/hashtable.h deleted file mode 100644 index 7827ce631..000000000 --- a/idlib/containers/hashtable.h +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __HASHTABLE_H__ -#define __HASHTABLE_H__ - -/* -=============================================================================== - - General hash table. Slower than idHashIndex but it can also be used for - linked lists and other data structures than just indexes or arrays. - -=============================================================================== -*/ - -template< class Type > -class idHashTable { -public: - idHashTable( int newtablesize = 256 ); - idHashTable( const idHashTable &map ); - ~idHashTable( void ); - - // returns total size of allocated memory - size_t Allocated( void ) const; - // returns total size of allocated memory including size of hash table type - size_t Size( void ) const; - - void Set( const char *key, Type &value ); - bool Get( const char *key, Type **value = NULL ) const; - bool Remove( const char *key ); - - void Clear( void ); - void DeleteContents( void ); - - // the entire contents can be itterated over, but note that the - // exact index for a given element may change when new elements are added - int Num( void ) const; - Type * GetIndex( int index ) const; - - int GetSpread( void ) const; - -private: - struct hashnode_s { - idStr key; - Type value; - hashnode_s *next; - - hashnode_s( const idStr &k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {}; - hashnode_s( const char *k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {}; - }; - - hashnode_s ** heads; - - int tablesize; - int numentries; - int tablesizemask; - - int GetHash( const char *key ) const; -}; - -/* -================ -idHashTable::idHashTable -================ -*/ -template< class Type > -ID_INLINE idHashTable::idHashTable( int newtablesize ) { - - assert( idMath::IsPowerOfTwo( newtablesize ) ); - - tablesize = newtablesize; - assert( tablesize > 0 ); - - heads = new hashnode_s *[ tablesize ]; - memset( heads, 0, sizeof( *heads ) * tablesize ); - - numentries = 0; - - tablesizemask = tablesize - 1; -} - -/* -================ -idHashTable::idHashTable -================ -*/ -template< class Type > -ID_INLINE idHashTable::idHashTable( const idHashTable &map ) { - int i; - hashnode_s *node; - hashnode_s **prev; - - assert( map.tablesize > 0 ); - - tablesize = map.tablesize; - heads = new hashnode_s *[ tablesize ]; - numentries = map.numentries; - tablesizemask = map.tablesizemask; - - for( i = 0; i < tablesize; i++ ) { - if ( !map.heads[ i ] ) { - heads[ i ] = NULL; - continue; - } - - prev = &heads[ i ]; - for( node = map.heads[ i ]; node != NULL; node = node->next ) { - *prev = new hashnode_s( node->key, node->value, NULL ); - prev = &( *prev )->next; - } - } -} - -/* -================ -idHashTable::~idHashTable -================ -*/ -template< class Type > -ID_INLINE idHashTable::~idHashTable( void ) { - Clear(); - delete[] heads; -} - -/* -================ -idHashTable::Allocated -================ -*/ -template< class Type > -ID_INLINE size_t idHashTable::Allocated( void ) const { - return sizeof( heads ) * tablesize + sizeof( *heads ) * numentries; -} - -/* -================ -idHashTable::Size -================ -*/ -template< class Type > -ID_INLINE size_t idHashTable::Size( void ) const { - return sizeof( idHashTable ) + sizeof( heads ) * tablesize + sizeof( *heads ) * numentries; -} - -/* -================ -idHashTable::GetHash -================ -*/ -template< class Type > -ID_INLINE int idHashTable::GetHash( const char *key ) const { - return ( idStr::Hash( key ) & tablesizemask ); -} - -/* -================ -idHashTable::Set -================ -*/ -template< class Type > -ID_INLINE void idHashTable::Set( const char *key, Type &value ) { - hashnode_s *node, **nextPtr; - int hash, s; - - hash = GetHash( key ); - for( nextPtr = &(heads[hash]), node = *nextPtr; node != NULL; nextPtr = &(node->next), node = *nextPtr ) { - s = node->key.Cmp( key ); - if ( s == 0 ) { - node->value = value; - return; - } - if ( s > 0 ) { - break; - } - } - - numentries++; - - *nextPtr = new hashnode_s( key, value, heads[ hash ] ); - (*nextPtr)->next = node; -} - -/* -================ -idHashTable::Get -================ -*/ -template< class Type > -ID_INLINE bool idHashTable::Get( const char *key, Type **value ) const { - hashnode_s *node; - int hash, s; - - hash = GetHash( key ); - for( node = heads[ hash ]; node != NULL; node = node->next ) { - s = node->key.Cmp( key ); - if ( s == 0 ) { - if ( value ) { - *value = &node->value; - } - return true; - } - if ( s > 0 ) { - break; - } - } - - if ( value ) { - *value = NULL; - } - - return false; -} - -/* -================ -idHashTable::GetIndex - -the entire contents can be itterated over, but note that the -exact index for a given element may change when new elements are added -================ -*/ -template< class Type > -ID_INLINE Type *idHashTable::GetIndex( int index ) const { - hashnode_s *node; - int count; - int i; - - if ( ( index < 0 ) || ( index > numentries ) ) { - assert( 0 ); - return NULL; - } - - count = 0; - for( i = 0; i < tablesize; i++ ) { - for( node = heads[ i ]; node != NULL; node = node->next ) { - if ( count == index ) { - return &node->value; - } - count++; - } - } - - return NULL; -} - -/* -================ -idHashTable::Remove -================ -*/ -template< class Type > -ID_INLINE bool idHashTable::Remove( const char *key ) { - hashnode_s **head; - hashnode_s *node; - hashnode_s *prev; - int hash; - - hash = GetHash( key ); - head = &heads[ hash ]; - if ( *head ) { - for( prev = NULL, node = *head; node != NULL; prev = node, node = node->next ) { - if ( node->key == key ) { - if ( prev ) { - prev->next = node->next; - } else { - *head = node->next; - } - - delete node; - numentries--; - return true; - } - } - } - - return false; -} - -/* -================ -idHashTable::Clear -================ -*/ -template< class Type > -ID_INLINE void idHashTable::Clear( void ) { - int i; - hashnode_s *node; - hashnode_s *next; - - for( i = 0; i < tablesize; i++ ) { - next = heads[ i ]; - while( next != NULL ) { - node = next; - next = next->next; - delete node; - } - - heads[ i ] = NULL; - } - - numentries = 0; -} - -/* -================ -idHashTable::DeleteContents -================ -*/ -template< class Type > -ID_INLINE void idHashTable::DeleteContents( void ) { - int i; - hashnode_s *node; - hashnode_s *next; - - for( i = 0; i < tablesize; i++ ) { - next = heads[ i ]; - while( next != NULL ) { - node = next; - next = next->next; - delete node->value; - delete node; - } - - heads[ i ] = NULL; - } - - numentries = 0; -} - -/* -================ -idHashTable::Num -================ -*/ -template< class Type > -ID_INLINE int idHashTable::Num( void ) const { - return numentries; -} - -#if !defined(__GNUC__) || __GNUC__ < 4 -/* -================ -idHashTable::GetSpread -================ -*/ -template< class Type > -int idHashTable::GetSpread( void ) const { - int i, average, error, e; - hashnode_s *node; - - // if no items in hash - if ( !numentries ) { - return 100; - } - average = numentries / tablesize; - error = 0; - for ( i = 0; i < tablesize; i++ ) { - numItems = 0; - for( node = heads[ i ]; node != NULL; node = node->next ) { - numItems++; - } - e = abs( numItems - average ); - if ( e > 1 ) { - error += e - 1; - } - } - return 100 - (error * 100 / numentries); -} -#endif - -#endif /* !__HASHTABLE_H__ */ diff --git a/idlib/containers/hierarchy.h b/idlib/containers/hierarchy.h deleted file mode 100644 index 19f1cabd2..000000000 --- a/idlib/containers/hierarchy.h +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __HIERARCHY_H__ -#define __HIERARCHY_H__ - -/* -============================================================================== - - idHierarchy - -============================================================================== -*/ - -template< class type > -class idHierarchy { -public: - - idHierarchy(); - ~idHierarchy(); - - void SetOwner( type *object ); - type * Owner( void ) const; - void ParentTo( idHierarchy &node ); - void MakeSiblingAfter( idHierarchy &node ); - bool ParentedBy( const idHierarchy &node ) const; - void RemoveFromParent( void ); - void RemoveFromHierarchy( void ); - - type * GetParent( void ) const; // parent of this node - type * GetChild( void ) const; // first child of this node - type * GetSibling( void ) const; // next node with the same parent - type * GetPriorSibling( void ) const; // previous node with the same parent - type * GetNext( void ) const; // goes through all nodes of the hierarchy - type * GetNextLeaf( void ) const; // goes through all leaf nodes of the hierarchy - -private: - idHierarchy * parent; - idHierarchy * sibling; - idHierarchy * child; - type * owner; - - idHierarchy *GetPriorSiblingNode( void ) const; // previous node with the same parent -}; - -/* -================ -idHierarchy::idHierarchy -================ -*/ -template< class type > -idHierarchy::idHierarchy() { - owner = NULL; - parent = NULL; - sibling = NULL; - child = NULL; -} - -/* -================ -idHierarchy::~idHierarchy -================ -*/ -template< class type > -idHierarchy::~idHierarchy() { - RemoveFromHierarchy(); -} - -/* -================ -idHierarchy::Owner - -Gets the object that is associated with this node. -================ -*/ -template< class type > -type *idHierarchy::Owner( void ) const { - return owner; -} - -/* -================ -idHierarchy::SetOwner - -Sets the object that this node is associated with. -================ -*/ -template< class type > -void idHierarchy::SetOwner( type *object ) { - owner = object; -} - -/* -================ -idHierarchy::ParentedBy -================ -*/ -template< class type > -bool idHierarchy::ParentedBy( const idHierarchy &node ) const { - if ( parent == &node ) { - return true; - } else if ( parent ) { - return parent->ParentedBy( node ); - } - return false; -} - -/* -================ -idHierarchy::ParentTo - -Makes the given node the parent. -================ -*/ -template< class type > -void idHierarchy::ParentTo( idHierarchy &node ) { - RemoveFromParent(); - - parent = &node; - sibling = node.child; - node.child = this; -} - -/* -================ -idHierarchy::MakeSiblingAfter - -Makes the given node a sibling after the passed in node. -================ -*/ -template< class type > -void idHierarchy::MakeSiblingAfter( idHierarchy &node ) { - RemoveFromParent(); - parent = node.parent; - sibling = node.sibling; - node.sibling = this; -} - -/* -================ -idHierarchy::RemoveFromParent -================ -*/ -template< class type > -void idHierarchy::RemoveFromParent( void ) { - idHierarchy *prev; - - if ( parent ) { - prev = GetPriorSiblingNode(); - if ( prev ) { - prev->sibling = sibling; - } else { - parent->child = sibling; - } - } - - parent = NULL; - sibling = NULL; -} - -/* -================ -idHierarchy::RemoveFromHierarchy - -Removes the node from the hierarchy and adds it's children to the parent. -================ -*/ -template< class type > -void idHierarchy::RemoveFromHierarchy( void ) { - idHierarchy *parentNode; - idHierarchy *node; - - parentNode = parent; - RemoveFromParent(); - - if ( parentNode ) { - while( child ) { - node = child; - node->RemoveFromParent(); - node->ParentTo( *parentNode ); - } - } else { - while( child ) { - child->RemoveFromParent(); - } - } -} - -/* -================ -idHierarchy::GetParent -================ -*/ -template< class type > -type *idHierarchy::GetParent( void ) const { - if ( parent ) { - return parent->owner; - } - return NULL; -} - -/* -================ -idHierarchy::GetChild -================ -*/ -template< class type > -type *idHierarchy::GetChild( void ) const { - if ( child ) { - return child->owner; - } - return NULL; -} - -/* -================ -idHierarchy::GetSibling -================ -*/ -template< class type > -type *idHierarchy::GetSibling( void ) const { - if ( sibling ) { - return sibling->owner; - } - return NULL; -} - -/* -================ -idHierarchy::GetPriorSiblingNode - -Returns NULL if no parent, or if it is the first child. -================ -*/ -template< class type > -idHierarchy *idHierarchy::GetPriorSiblingNode( void ) const { - if ( !parent || ( parent->child == this ) ) { - return NULL; - } - - idHierarchy *prev; - idHierarchy *node; - - node = parent->child; - prev = NULL; - while( ( node != this ) && ( node != NULL ) ) { - prev = node; - node = node->sibling; - } - - if ( node != this ) { - idLib::Error( "idHierarchy::GetPriorSibling: could not find node in parent's list of children" ); - } - - return prev; -} - -/* -================ -idHierarchy::GetPriorSibling - -Returns NULL if no parent, or if it is the first child. -================ -*/ -template< class type > -type *idHierarchy::GetPriorSibling( void ) const { - idHierarchy *prior; - - prior = GetPriorSiblingNode(); - if ( prior ) { - return prior->owner; - } - - return NULL; -} - -/* -================ -idHierarchy::GetNext - -Goes through all nodes of the hierarchy. -================ -*/ -template< class type > -type *idHierarchy::GetNext( void ) const { - const idHierarchy *node; - - if ( child ) { - return child->owner; - } else { - node = this; - while( node && node->sibling == NULL ) { - node = node->parent; - } - if ( node ) { - return node->sibling->owner; - } else { - return NULL; - } - } -} - -/* -================ -idHierarchy::GetNextLeaf - -Goes through all leaf nodes of the hierarchy. -================ -*/ -template< class type > -type *idHierarchy::GetNextLeaf( void ) const { - const idHierarchy *node; - - if ( child ) { - node = child; - while ( node->child ) { - node = node->child; - } - return node->owner; - } else { - node = this; - while( node && node->sibling == NULL ) { - node = node->parent; - } - if ( node ) { - node = node->sibling; - while ( node->child ) { - node = node->child; - } - return node->owner; - } else { - return NULL; - } - } -} - -#endif /* !__HIERARCHY_H__ */ diff --git a/idlib/containers/linklist.h b/idlib/containers/linklist.h deleted file mode 100644 index 94abc97aa..000000000 --- a/idlib/containers/linklist.h +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LINKLIST_H__ -#define __LINKLIST_H__ - -/* -============================================================================== - -idLinkList - -Circular linked list template - -============================================================================== -*/ - -template< class type > -class idLinkList { -public: - idLinkList(); - ~idLinkList(); - - bool IsListEmpty( void ) const; - bool InList( void ) const; - int Num( void ) const; - void Clear( void ); - - void InsertBefore( idLinkList &node ); - void InsertAfter( idLinkList &node ); - void AddToEnd( idLinkList &node ); - void AddToFront( idLinkList &node ); - - void Remove( void ); - - // Added by SophisticatedZombie for DarkMod - // This method removes a node from the list and updates the head pointer of - // every node in the list to prevent the list form becoming circular when the head - // is removed. - void RemoveHeadsafe( void ); - - type * Next( void ) const; - type * Prev( void ) const; - - type * Owner( void ) const; - void SetOwner( type *object ); - - idLinkList * ListHead( void ) const; - idLinkList * NextNode( void ) const; - idLinkList * PrevNode( void ) const; - idLinkList * NextNodeCircular( void ) const; - idLinkList * PrevNodeCircular( void ) const; - -private: - idLinkList * head; - idLinkList * next; - idLinkList * prev; - type * owner; -}; - -/* -================ -idLinkList::idLinkList - -Node is initialized to be the head of an empty list -================ -*/ -template< class type > -idLinkList::idLinkList() { - owner = NULL; - head = this; - next = this; - prev = this; -} - -/* -================ -idLinkList::~idLinkList - -Removes the node from the list, or if it's the head of a list, removes -all the nodes from the list. -================ -*/ -template< class type > -idLinkList::~idLinkList() { - Clear(); -} - -/* -================ -idLinkList::IsListEmpty - -Returns true if the list is empty. -================ -*/ -template< class type > -bool idLinkList::IsListEmpty( void ) const { - return head->next == head; -} - -/* -================ -idLinkList::InList - -Returns true if the node is in a list. If called on the head of a list, will always return false. -================ -*/ -template< class type > -bool idLinkList::InList( void ) const { - return head != this; -} - -/* -================ -idLinkList::Num - -Returns the number of nodes in the list. -================ -*/ -template< class type > -int idLinkList::Num( void ) const { - idLinkList *node; - int num; - - num = 0; - for( node = head->next; node != head; node = node->next ) { - num++; - } - - return num; -} - -/* -================ -idLinkList::Clear - -If node is the head of the list, clears the list. Otherwise it just removes the node from the list. -================ -*/ -template< class type > -void idLinkList::Clear( void ) { - if ( head == this ) { - while( next != this ) { - next->Remove(); - } - } else { - Remove(); - } -} - -/* -================ -idLinkList::Remove - -Removes node from list -================ -*/ -template< class type > -void idLinkList::Remove( void ) { - prev->next = next; - next->prev = prev; - - next = this; - prev = this; - head = this; -} - -/* -================ -idLinkList::RemoveHeadsafe - -Removes node from list and updates -the list's head pointer if this was the head -================ -*/ -template< class type > -void idLinkList::RemoveHeadsafe( void ) { - - // If this is the head, must walk list and tell all our little buddies - // that we are no longer the head, and that the next node now is. - if (head == this) - { - idLinkList* p_cursor = next; - - while ((p_cursor != NULL) && (p_cursor != this)) - { - p_cursor->head = next; - p_cursor = p_cursor->next; - } - } - - // Now back to ID's original code - prev->next = next; - next->prev = prev; - - next = this; - prev = this; - head = this; - - -} - -/* -================ -idLinkList::InsertBefore - -Places the node before the existing node in the list. If the existing node is the head, -then the new node is placed at the end of the list. -================ -*/ -template< class type > -void idLinkList::InsertBefore( idLinkList &node ) { - Remove(); - - next = &node; - prev = node.prev; - node.prev = this; - prev->next = this; - head = node.head; -} - -/* -================ -idLinkList::InsertAfter - -Places the node after the existing node in the list. If the existing node is the head, -then the new node is placed at the beginning of the list. -================ -*/ -template< class type > -void idLinkList::InsertAfter( idLinkList &node ) { - Remove(); - - prev = &node; - next = node.next; - node.next = this; - next->prev = this; - head = node.head; -} - -/* -================ -idLinkList::AddToEnd - -Adds node at the end of the list -================ -*/ -template< class type > -void idLinkList::AddToEnd( idLinkList &node ) { - InsertBefore( *node.head ); -} - -/* -================ -idLinkList::AddToFront - -Adds node at the beginning of the list -================ -*/ -template< class type > -void idLinkList::AddToFront( idLinkList &node ) { - InsertAfter( *node.head ); -} - -/* -================ -idLinkList::ListHead - -Returns the head of the list. If the node isn't in a list, it returns -a pointer to itself. -================ -*/ -template< class type > -idLinkList *idLinkList::ListHead( void ) const { - return head; -} - -/* -================ -idLinkList::Next - -Returns the next object in the list, or NULL if at the end. -================ -*/ -template< class type > -type *idLinkList::Next( void ) const { - if ( !next || ( next == head ) ) { - return NULL; - } - return next->owner; -} - -/* -================ -idLinkList::Prev - -Returns the previous object in the list, or NULL if at the beginning. -================ -*/ -template< class type > -type *idLinkList::Prev( void ) const { - if ( !prev || ( prev == head ) ) { - return NULL; - } - return prev->owner; -} - -/* -================ -idLinkList::NextNode - -Returns the next node in the list, or NULL if at the end. -================ -*/ -template< class type > -idLinkList *idLinkList::NextNode( void ) const { - if ( next == head ) { - return NULL; - } - return next; -} - -/* -================ -idLinkList::PrevNode - -Returns the previous node in the list, or NULL if at the beginning. -================ -*/ -template< class type > -idLinkList *idLinkList::PrevNode( void ) const { - if ( prev == head ) { - return NULL; - } - return prev; -} - -/* -================ -idLinkList::NextNodeCircular - -Returns the next node in the list, possibly returning the head. -================ -*/ -template< class type > -idLinkList *idLinkList::NextNodeCircular( void ) const { - return next; -} - -/* -================ -idLinkList::PrevNodeCircular - -Returns the previous node in the list, possibly returning the head. -================ -*/ -template< class type > -idLinkList *idLinkList::PrevNodeCircular( void ) const { - return prev; -} - -/* -================ -idLinkList::Owner - -Gets the object that is associated with this node. -================ -*/ -template< class type > -type *idLinkList::Owner( void ) const { - return owner; -} - -/* -================ -idLinkList::SetOwner - -Sets the object that this node is associated with. -================ -*/ -template< class type > -void idLinkList::SetOwner( type *object ) { - owner = object; -} - -#endif /* !__LINKLIST_H__ */ diff --git a/idlib/containers/list.h b/idlib/containers/list.h deleted file mode 100644 index ec65581a7..000000000 --- a/idlib/containers/list.h +++ /dev/null @@ -1,1010 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LIST_H__ -#define __LIST_H__ - -#ifdef __linux__ -#include -#endif - -/* -=============================================================================== - - List template - Does not allocate memory until the first item is added. - -=============================================================================== -*/ - - -/* -================ -idListSortCompare -================ -*/ -#ifdef __INTEL_COMPILER -// the intel compiler doesn't do the right thing here -template< class type > -ID_INLINE int idListSortCompare( const type *a, const type *b ) { - assert( 0 ); - return 0; -} -#else -template< class type > -ID_INLINE int idListSortCompare( const type *a, const type *b ) { - return *a - *b; -} -#endif - -/* -================ -idListNewElement -================ -*/ -template< class type > -ID_INLINE type *idListNewElement( void ) { - return new type; -} - -/* -================ -idSwap -================ -*/ -template< class type > -ID_INLINE void idSwap( type &a, type &b ) { - type c = a; - a = b; - b = c; -} - -template< class type > -class idList { -public: - - typedef int cmp_t( const type *, const type * ); - typedef type new_t( void ); - - idList( int newgranularity = 16 ); - idList( const idList &other ); - ~idList( void ); - - void Clear( void ); // clear the list - int Num( void ) const; // returns number of elements in list - int NumAllocated( void ) const; // returns number of elements allocated for - void SetGranularity( int newgranularity ); // set new granularity - int GetGranularity( void ) const; // get the current granularity - - size_t Allocated( void ) const; // returns total size of allocated memory - size_t Size( void ) const; // returns total size of allocated memory including size of list type - size_t MemoryUsed( void ) const; // returns size of the used elements in the list - - idList & operator=( const idList &other ); - const type & operator[]( int index ) const; - type & operator[]( int index ); - - void Condense( void ); // resizes list to exactly the number of elements it contains - void Resize( int newsize ); // resizes list to the given number of elements - void Resize( int newsize, int newgranularity ); // resizes list and sets new granularity - void SetNum( int newnum, bool resize = true ); // set number of elements in list and resize to exactly this number if necessary - void AssureSize( int newSize); // assure list has given number of elements, but leave them uninitialized - void AssureSize( int newSize, const type &initValue ); // assure list has given number of elements and initialize any new elements - void AssureSizeAlloc( int newSize, new_t *allocator ); // assure the pointer list has the given number of elements and allocate any new elements - - type * Ptr( void ); // returns a pointer to the list - const type * Ptr( void ) const; // returns a pointer to the list - type & Alloc( void ); // returns reference to a new data element at the end of the list - int Append( const type & obj ); // append element - int Append( const idList &other ); // append list - int AddUnique( const type & obj ); // add unique element - int Insert( const type & obj, int index = 0 ); // insert the element at the given index - int FindIndex( const type & obj ) const; // find the index for the given element - type * Find( type const & obj ) const; // find pointer to the given element - int FindNull( void ) const; // find the index for the first NULL pointer in the list - int IndexOf( const type *obj ) const; // returns the index for the pointer to an element in the list - bool RemoveIndex( const int index ); // remove the element at the given index and keep items sorted - bool RemoveIndex( const int index, bool keepSorted ); // Tels: remove the element at the given index, keep sorted only if wanted - bool Remove( const type & obj ); // remove the element - void Sort( cmp_t *compare = ( cmp_t * )&idListSortCompare ); - void SortSubSection( int startIndex, int endIndex, cmp_t *compare = ( cmp_t * )&idListSortCompare ); - void Swap( idList &other ); // swap the contents of the lists - void DeleteContents( bool clear ); // delete the contents of the list - -private: - int num; - int size; - int granularity; - type * list; -}; - -/* -================ -idList::idList( int ) -================ -*/ -template< class type > -ID_INLINE idList::idList( int newgranularity ) { - assert( newgranularity > 0 ); - - list = NULL; - granularity = newgranularity; - Clear(); -} - -/* -================ -idList::idList( const idList &other ) -================ -*/ -template< class type > -ID_INLINE idList::idList( const idList &other ) { - list = NULL; - *this = other; -} - -/* -================ -idList::~idList -================ -*/ -template< class type > -ID_INLINE idList::~idList( void ) { - Clear(); -} - -/* -================ -idList::Clear - -Frees up the memory allocated by the list. Assumes that type automatically handles freeing up memory. -================ -*/ -template< class type > -ID_INLINE void idList::Clear( void ) { - if ( list ) { - delete[] list; - } - - list = NULL; - num = 0; - size = 0; -} - -/* -================ -idList::DeleteContents - -Calls the destructor of all elements in the list. Conditionally frees up memory used by the list. -Note that this only works on lists containing pointers to objects and will cause a compiler error -if called with non-pointers. Since the list was not responsible for allocating the object, it has -no information on whether the object still exists or not, so care must be taken to ensure that -the pointers are still valid when this function is called. Function will set all pointers in the -list to NULL. -================ -*/ -template< class type > -ID_INLINE void idList::DeleteContents( bool clear ) { - int i; - - for( i = 0; i < num; i++ ) { - delete list[ i ]; - list[ i ] = NULL; - } - - if ( clear ) { - Clear(); - } else { - memset( list, 0, size * sizeof( type ) ); - } -} - -/* -================ -idList::Allocated - -return total memory allocated for the list in bytes, but doesn't take into account additional memory allocated by type -================ -*/ -template< class type > -ID_INLINE size_t idList::Allocated( void ) const { - return size * sizeof( type ); -} - -/* -================ -idList::Size - -return total size of list in bytes, but doesn't take into account additional memory allocated by type -================ -*/ -template< class type > -ID_INLINE size_t idList::Size( void ) const { - return sizeof( idList ) + Allocated(); -} - -/* -================ -idList::MemoryUsed -================ -*/ -template< class type > -ID_INLINE size_t idList::MemoryUsed( void ) const { - return num * sizeof( *list ); -} - -/* -================ -idList::Num - -Returns the number of elements currently contained in the list. -Note that this is NOT an indication of the memory allocated. -================ -*/ -template< class type > -ID_INLINE int idList::Num( void ) const { - return num; -} - -/* -================ -idList::NumAllocated - -Returns the number of elements currently allocated for. -================ -*/ -template< class type > -ID_INLINE int idList::NumAllocated( void ) const { - return size; -} - -/* -================ -idList::SetNum - -Resize to the exact size specified irregardless of granularity -================ -*/ -template< class type > -ID_INLINE void idList::SetNum( int newnum, bool resize ) { - assert( newnum >= 0 ); - if ( resize || newnum > size ) { - Resize( newnum ); - } - num = newnum; -} - -/* -================ -idList::SetGranularity - -Sets the base size of the array and resizes the array to match. -================ -*/ -template< class type > -ID_INLINE void idList::SetGranularity( int newgranularity ) { - int newsize; - - assert( newgranularity > 0 ); - granularity = newgranularity; - - if ( list ) { - // resize it to the closest level of granularity - newsize = num + granularity - 1; - newsize -= newsize % granularity; - if ( newsize != size ) { - Resize( newsize ); - } - } -} - -/* -================ -idList::GetGranularity - -Get the current granularity. -================ -*/ -template< class type > -ID_INLINE int idList::GetGranularity( void ) const { - return granularity; -} - -/* -================ -idList::Condense - -Resizes the array to exactly the number of elements it contains or frees up memory if empty. -================ -*/ -template< class type > -ID_INLINE void idList::Condense( void ) { - if ( list ) { - if ( num ) { - Resize( num ); - } else { - Clear(); - } - } -} - -/* -================ -idList::Resize - -Allocates memory for the amount of elements requested while keeping the contents intact. -Contents are copied using their = operator so that data is correnctly instantiated. -================ -*/ -template< class type > -ID_INLINE void idList::Resize( int newsize ) { - type *temp; - int i; - - assert( newsize >= 0 ); - - // free up the list if no data is being reserved - if ( newsize <= 0 ) { - Clear(); - return; - } - - if ( newsize == size ) { - // not changing the size, so just exit - return; - } - - temp = list; - size = newsize; - if ( size < num ) { - num = size; - } - - // copy the old list into our new one - list = new type[ size ]; - for( i = 0; i < num; i++ ) { - list[ i ] = temp[ i ]; - } - - // delete the old list if it exists - if ( temp ) { - delete[] temp; - } -} - -/* -================ -idList::Resize - -Allocates memory for the amount of elements requested while keeping the contents intact. -Contents are copied using their = operator so that data is correnctly instantiated. -================ -*/ -template< class type > -ID_INLINE void idList::Resize( int newsize, int newgranularity ) { - type *temp; - int i; - - assert( newsize >= 0 ); - - assert( newgranularity > 0 ); - granularity = newgranularity; - - // free up the list if no data is being reserved - if ( newsize <= 0 ) { - Clear(); - return; - } - - temp = list; - size = newsize; - if ( size < num ) { - num = size; - } - - // copy the old list into our new one - list = new type[ size ]; - for( i = 0; i < num; i++ ) { - list[ i ] = temp[ i ]; - } - - // delete the old list if it exists - if ( temp ) { - delete[] temp; - } -} - -/* -================ -idList::AssureSize - -Makes sure the list has at least the given number of elements. -================ -*/ -template< class type > -ID_INLINE void idList::AssureSize( int newSize ) { - int newNum = newSize; - - if ( newSize > size ) { - - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - - newSize += granularity - 1; - newSize -= newSize % granularity; - Resize( newSize ); - } - - num = newNum; -} - -/* -================ -idList::AssureSize - -Makes sure the list has at least the given number of elements and initialize any elements not yet initialized. -================ -*/ -template< class type > -ID_INLINE void idList::AssureSize( int newSize, const type &initValue ) { - int newNum = newSize; - - if ( newSize > size ) { - - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - - newSize += granularity - 1; - newSize -= newSize % granularity; - num = size; - Resize( newSize ); - - for ( int i = num; i < newSize; i++ ) { - list[i] = initValue; - } - } - - num = newNum; -} - -/* -================ -idList::AssureSizeAlloc - -Makes sure the list has at least the given number of elements and allocates any elements using the allocator. - -NOTE: This function can only be called on lists containing pointers. Calling it -on non-pointer lists will cause a compiler error. -================ -*/ -template< class type > -ID_INLINE void idList::AssureSizeAlloc( int newSize, new_t *allocator ) { - int newNum = newSize; - - if ( newSize > size ) { - - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - - newSize += granularity - 1; - newSize -= newSize % granularity; - num = size; - Resize( newSize ); - - for ( int i = num; i < newSize; i++ ) { - list[i] = (*allocator)(); - } - } - - num = newNum; -} - -/* -================ -idList::operator= - -Copies the contents and size attributes of another list. -================ -*/ -template< class type > -ID_INLINE idList &idList::operator=( const idList &other ) { - int i; - - Clear(); - - num = other.num; - size = other.size; - granularity = other.granularity; - - if ( size ) { - list = new type[ size ]; - for( i = 0; i < num; i++ ) { - list[ i ] = other.list[ i ]; - } - } - - return *this; -} - -/* -================ -idList::operator[] const - -Access operator. Index must be within range or an assert will be issued in debug builds. -Release builds do no range checking. -================ -*/ -template< class type > -ID_INLINE const type &idList::operator[]( int index ) const { - assert( index >= 0 ); - assert( index < num ); - - return list[ index ]; -} - -/* -================ -idList::operator[] - -Access operator. Index must be within range or an assert will be issued in debug builds. -Release builds do no range checking. -================ -*/ -template< class type > -ID_INLINE type &idList::operator[]( int index ) { - assert( index >= 0 ); - assert( index < num ); - - return list[ index ]; -} - -/* -================ -idList::Ptr - -Returns a pointer to the beginning of the array. Useful for iterating through the list in loops. - -Note: may return NULL if the list is empty. - -FIXME: Create an iterator template for this kind of thing. -================ -*/ -template< class type > -ID_INLINE type *idList::Ptr( void ) { - return list; -} - -/* -================ -idList::Ptr - -Returns a pointer to the begining of the array. Useful for iterating through the list in loops. - -Note: may return NULL if the list is empty. - -FIXME: Create an iterator template for this kind of thing. -================ -*/ -template< class type > -const ID_INLINE type *idList::Ptr( void ) const { - return list; -} - -/* -================ -idList::Alloc - -Returns a reference to a new data element at the end of the list. -================ -*/ -template< class type > -ID_INLINE type &idList::Alloc( void ) { - if ( !list ) { - Resize( granularity ); - } - - if ( num == size ) { - Resize( size + granularity ); - } - - return list[ num++ ]; -} - -/* -================ -idList::Append - -Increases the size of the list by one element and copies the supplied data into it. - -Returns the index of the new element. - -greebo: Important: Don't do this: spotList.Append( spotList[randomLocation] )! - -Don't call idList::Append() or idList::Alloc() with a reference to a current -list element. The operator[] will return a reference to the memory BEFORE a -possible Resize() call, which will relocate the entire list. The reference -to the "old" memory location will be invalid and crashes are ahead. -================ -*/ -template< class type > -ID_INLINE int idList::Append( type const & obj ) { - if ( !list ) { - Resize( granularity ); - } - - if ( num == size ) { - int newsize; - - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - newsize = size + granularity; - Resize( newsize - newsize % granularity ); - } - - list[ num ] = obj; - num++; - - return num - 1; -} - - -/* -================ -idList::Insert - -Increases the size of the list by at leat one element if necessary -and inserts the supplied data into it. - -Returns the index of the new element. -================ -*/ -template< class type > -ID_INLINE int idList::Insert( type const & obj, int index ) { - if ( !list ) { - Resize( granularity ); - } - - if ( num == size ) { - int newsize; - - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - newsize = size + granularity; - Resize( newsize - newsize % granularity ); - } - - if ( index < 0 ) { - index = 0; - } - else if ( index > num ) { - index = num; - } - for ( int i = num; i > index; --i ) { - list[i] = list[i-1]; - } - num++; - list[index] = obj; - return index; -} - -/* -================ -idList::Append - -adds the other list to this one - -Returns the size of the new combined list -================ -*/ -template< class type > -ID_INLINE int idList::Append( const idList &other ) { - - // Tels: Old code, with quadratic (O(N*N) performance, it would call Resize - // every so often, which is a O(N) copy operation. -/* if ( !list ) { - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - Resize( granularity ); - } - - int n = other.Num(); - for (int i = 0; i < n; i++) { - Append(other[i]); - } - - return Num(); -*/ - - // Tels 2010-07-21: new code, resize only once, then copy data over O(N) - if ( granularity == 0 ) { // this is a hack to fix our memset classes - granularity = 16; - } - int n = other.Num(); - int newsize = size + granularity + n; - Resize( newsize - newsize % granularity ); - - for (int i = 0; i < n; i++) { - // simply copy data over - list[num + i] = other[i]; - } - num += n; - return num; -} - -/* -================ -idList::AddUnique - -Adds the data to the list if it doesn't already exist. Returns the index of the data in the list. -================ -*/ -template< class type > -ID_INLINE int idList::AddUnique( type const & obj ) { - int index; - - index = FindIndex( obj ); - if ( index < 0 ) { - index = Append( obj ); - } - - return index; -} - -/* -================ -idList::FindIndex - -Searches for the specified data in the list and returns it's index. Returns -1 if the data is not found. -================ -*/ -template< class type > -ID_INLINE int idList::FindIndex( type const & obj ) const { - int i; - - for( i = 0; i < num; i++ ) { - if ( list[ i ] == obj ) { - return i; - } - } - - // Not found - return -1; -} - -/* -================ -idList::Find - -Searches for the specified data in the list and returns it's address. Returns NULL if the data is not found. -================ -*/ -template< class type > -ID_INLINE type *idList::Find( type const & obj ) const { - int i; - - i = FindIndex( obj ); - if ( i >= 0 ) { - return &list[ i ]; - } - - return NULL; -} - -/* -================ -idList::FindNull - -Searches for a NULL pointer in the list. Returns -1 if NULL is not found. - -NOTE: This function can only be called on lists containing pointers. Calling it -on non-pointer lists will cause a compiler error. -================ -*/ -template< class type > -ID_INLINE int idList::FindNull( void ) const { - int i; - - for( i = 0; i < num; i++ ) { - if ( list[ i ] == NULL ) { - return i; - } - } - - // Not found - return -1; -} - -/* -================ -idList::IndexOf - -Takes a pointer to an element in the list and returns the index of the element. -This is NOT a guarantee that the object is really in the list. -Function will assert in debug builds if pointer is outside the bounds of the list, -but remains silent in release builds. -================ -*/ -template< class type > -ID_INLINE int idList::IndexOf( type const *objptr ) const { - int index; - - index = objptr - list; - - assert( index >= 0 ); - assert( index < num ); - - return index; -} - -/* -================ -idList::RemoveIndex - -Removes the element at the specified index and moves all data following the element down to fill in the gap. -The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. -Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. -================ -*/ -template< class type > -ID_INLINE bool idList::RemoveIndex( int index ) { - int i; - - assert( list != NULL ); - assert( index >= 0 ); - assert( index < num ); - - if ( ( index < 0 ) || ( index >= num ) ) { - return false; - } - - num--; - for( i = index; i < num; i++ ) { - list[ i ] = list[ i + 1 ]; - } - - return true; -} - -/* -================ -idList::RemoveIndex - -Removes the element at the specified index and if keepSorted is true, moves all data following the element down to -fill in the gap. If keepSorted is false, just fills the gap with the last element in the list (if any). -The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. -Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. -================ -*/ -template< class type > -ID_INLINE bool idList::RemoveIndex( const int index, const bool keepSorted ) { - - assert( list != NULL ); - assert( index >= 0 ); - assert( index < num ); - - if ( ( index < 0 ) || ( index >= num ) ) { - return false; - } - - num--; - if (keepSorted) - { - //gameLocal.Printf("Moving %i list entries (index = %i)\n", num - index, index ); - for( int i = index; i < num; i++ ) { - list[ i ] = list[ i + 1 ]; - } - } - else - { - // [1,2,3,4] (remove 2, num was 4, is now 3, index = 1) => (num = 2), [1,4,3] - // if index == num, we removed the last element, so nothing to do - if ( index < num ) - { - list[ index ] = list[ num ]; - } - } - - return true; -} - -/* -================ -idList::Remove - -Removes the element if it is found within the list and moves all data following the element down to fill in the gap. -The number of elements in the list is reduced by one. Returns false if the data is not found in the list. Note that -the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. -================ -*/ -template< class type > -ID_INLINE bool idList::Remove( type const & obj ) { - int index; - - index = FindIndex( obj ); - if ( index >= 0 ) { - return RemoveIndex( index ); - } - - return false; -} - -/* -================ -idList::Sort - -Performs a qsort on the list using the supplied comparison function. Note that the data is merely moved around the -list, so any pointers to data within the list may no longer be valid. -================ -*/ -template< class type > -ID_INLINE void idList::Sort( cmp_t *compare ) { - if ( !list ) { - return; - } - typedef int cmp_c(const void *, const void *); - - cmp_c *vCompare = (cmp_c *)compare; - qsort( ( void * )list, ( size_t )num, sizeof( type ), vCompare ); -} - -/* -================ -idList::SortSubSection - -Sorts a subsection of the list. -================ -*/ -template< class type > -ID_INLINE void idList::SortSubSection( int startIndex, int endIndex, cmp_t *compare ) { - if ( !list ) { - return; - } - if ( startIndex < 0 ) { - startIndex = 0; - } - if ( endIndex >= num ) { - endIndex = num - 1; - } - if ( startIndex >= endIndex ) { - return; - } - typedef int cmp_c(const void *, const void *); - - cmp_c *vCompare = (cmp_c *)compare; - qsort( ( void * )( &list[startIndex] ), ( size_t )( endIndex - startIndex + 1 ), sizeof( type ), vCompare ); -} - -/* -================ -idList::Swap - -Swaps the contents of two lists -================ -*/ -template< class type > -ID_INLINE void idList::Swap( idList &other ) { - idSwap( num, other.num ); - idSwap( size, other.size ); - idSwap( granularity, other.granularity ); - idSwap( list, other.list ); -} - -typedef idList idStringList; - -#endif /* !__LIST_H__ */ diff --git a/idlib/containers/planeset.h b/idlib/containers/planeset.h deleted file mode 100644 index 8dee46b3f..000000000 --- a/idlib/containers/planeset.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PLANESET_H__ -#define __PLANESET_H__ - -/* -=============================================================================== - - Plane Set - -=============================================================================== -*/ - -class idPlaneSet : public idList { -public: - - void Clear( void ) { idList::Clear(); hash.Free(); } - - int FindPlane( const idPlane &plane, const float normalEps, const float distEps ); - -private: - idHashIndex hash; -}; - -ID_INLINE int idPlaneSet::FindPlane( const idPlane &plane, const float normalEps, const float distEps ) { - int i, border, hashKey; - - assert( distEps <= 0.125f ); - - hashKey = (int)( idMath::Fabs( plane.Dist() ) * 0.125f ); - for ( border = -1; border <= 1; border++ ) { - for ( i = hash.First( hashKey + border ); i >= 0; i = hash.Next( i ) ) { - if ( (*this)[i].Compare( plane, normalEps, distEps ) ) { - return i; - } - } - } - - if ( plane.Type() >= PLANETYPE_NEGX && plane.Type() < PLANETYPE_TRUEAXIAL ) { - Append( -plane ); - hash.Add( hashKey, Num()-1 ); - Append( plane ); - hash.Add( hashKey, Num()-1 ); - return ( Num() - 1 ); - } - else { - Append( plane ); - hash.Add( hashKey, Num()-1 ); - Append( -plane ); - hash.Add( hashKey, Num()-1 ); - return ( Num() - 2 ); - } -} - -#endif /* !__PLANESET_H__ */ diff --git a/idlib/containers/queue.h b/idlib/containers/queue.h deleted file mode 100644 index cb8ed486b..000000000 --- a/idlib/containers/queue.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __QUEUE_H__ -#define __QUEUE_H__ - -/* -=============================================================================== - - Queue template - -=============================================================================== -*/ - -#define idQueue( type, next ) idQueueTemplatenext)> - -template< class type, int nextOffset > -class idQueueTemplate { -public: - idQueueTemplate( void ); - - void Add( type *element ); - type * Get( void ); - -private: - type * first; - type * last; -}; - -#define QUEUE_NEXT_PTR( element ) (*((type**)(((byte*)element)+nextOffset))) - -template< class type, int nextOffset > -idQueueTemplate::idQueueTemplate( void ) { - first = last = NULL; -} - -template< class type, int nextOffset > -void idQueueTemplate::Add( type *element ) { - QUEUE_NEXT_PTR(element) = NULL; - if ( last ) { - QUEUE_NEXT_PTR(last) = element; - } else { - first = element; - } - last = element; -} - -template< class type, int nextOffset > -type *idQueueTemplate::Get( void ) { - type *element; - - element = first; - if ( element ) { - first = QUEUE_NEXT_PTR(first); - if ( last == element ) { - last = NULL; - } - QUEUE_NEXT_PTR(element) = NULL; - } - return element; -} - -#endif /* !__QUEUE_H__ */ diff --git a/idlib/containers/stack.h b/idlib/containers/stack.h deleted file mode 100644 index 28bc8fec9..000000000 --- a/idlib/containers/stack.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __STACK_H__ -#define __STACK_H__ - -/* -=============================================================================== - - Stack template - -=============================================================================== -*/ - -#define idStack( type, next ) idStackTemplatenext)> - -template< class type, int nextOffset > -class idStackTemplate { -public: - idStackTemplate( void ); - - void Add( type *element ); - type * Get( void ); - -private: - type * top; - type * bottom; -}; - -#define STACK_NEXT_PTR( element ) (*(type**)(((byte*)element)+nextOffset)) - -template< class type, int nextOffset > -idStackTemplate::idStackTemplate( void ) { - top = bottom = NULL; -} - -template< class type, int nextOffset > -void idStackTemplate::Add( type *element ) { - STACK_NEXT_PTR(element) = top; - top = element; - if ( !bottom ) { - bottom = element; - } -} - -template< class type, int nextOffset > -type *idStackTemplate::Get( void ) { - type *element; - - element = top; - if ( element ) { - top = STACK_NEXT_PTR(top); - if ( bottom == element ) { - bottom = NULL; - } - STACK_NEXT_PTR(element) = NULL; - } - return element; -} - -#endif /* !__STACK_H__ */ diff --git a/idlib/containers/staticlist.h b/idlib/containers/staticlist.h deleted file mode 100644 index 3c95b5006..000000000 --- a/idlib/containers/staticlist.h +++ /dev/null @@ -1,532 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __STATICLIST_H__ -#define __STATICLIST_H__ - -/* -=============================================================================== - - Static list template - A non-growing, memset-able list using no memory allocation. - -=============================================================================== -*/ - -template -class idStaticList { -public: - - idStaticList(); - idStaticList( const idStaticList &other ); - ~idStaticList( void ); - - void Clear( void ); // marks the list as empty. does not deallocate or intialize data. - int Num( void ) const; // returns number of elements in list - int Max( void ) const; // returns the maximum number of elements in the list - void SetNum( int newnum ); // set number of elements in list - - size_t Allocated( void ) const; // returns total size of allocated memory - size_t Size( void ) const; // returns total size of allocated memory including size of list type - size_t MemoryUsed( void ) const; // returns size of the used elements in the list - - const type & operator[]( int index ) const; - type & operator[]( int index ); - - type * Ptr( void ); // returns a pointer to the list - const type * Ptr( void ) const; // returns a pointer to the list - type * Alloc( void ); // returns reference to a new data element at the end of the list. returns NULL when full. - int Append( const type & obj ); // append element - int Append( const idStaticList &other ); // append list - int AddUnique( const type & obj ); // add unique element - int Insert( const type & obj, int index ); // insert the element at the given index - int FindIndex( const type & obj ) const; // find the index for the given element - type * Find( type const & obj ) const; // find pointer to the given element - int FindNull( void ) const; // find the index for the first NULL pointer in the list - int IndexOf( const type *obj ) const; // returns the index for the pointer to an element in the list - bool RemoveIndex( int index ); // remove the element at the given index - bool Remove( const type & obj ); // remove the element - void Swap( idStaticList &other ); // swap the contents of the lists - void DeleteContents( bool clear ); // delete the contents of the list - -private: - int num; - type list[ size ]; -}; - -/* -================ -idStaticList::idStaticList() -================ -*/ -template -ID_INLINE idStaticList::idStaticList() { - num = 0; -} - -/* -================ -idStaticList::idStaticList( const idStaticList &other ) -================ -*/ -template -ID_INLINE idStaticList::idStaticList( const idStaticList &other ) { - *this = other; -} - -/* -================ -idStaticList::~idStaticList -================ -*/ -template -ID_INLINE idStaticList::~idStaticList( void ) { -} - -/* -================ -idStaticList::Clear - -Sets the number of elements in the list to 0. Assumes that type automatically handles freeing up memory. -================ -*/ -template -ID_INLINE void idStaticList::Clear( void ) { - num = 0; -} - -/* -================ -idStaticList::DeleteContents - -Calls the destructor of all elements in the list. Conditionally frees up memory used by the list. -Note that this only works on lists containing pointers to objects and will cause a compiler error -if called with non-pointers. Since the list was not responsible for allocating the object, it has -no information on whether the object still exists or not, so care must be taken to ensure that -the pointers are still valid when this function is called. Function will set all pointers in the -list to NULL. -================ -*/ -template -ID_INLINE void idStaticList::DeleteContents( bool clear ) { - int i; - - for( i = 0; i < size; i++ ) { - delete list[ i ]; - list[ i ] = NULL; - } - - if ( clear ) { - Clear(); - } else { - memset( list, 0, sizeof( list ) ); - } -} - -/* -================ -idStaticList::Num - -Returns the number of elements currently contained in the list. -================ -*/ -template -ID_INLINE int idStaticList::Num( void ) const { - return num; -} - -/* -================ -idStaticList::Num - -Returns the maximum number of elements in the list. -================ -*/ -template -ID_INLINE int idStaticList::Max( void ) const { - return size; -} - -/* -================ -idStaticList::Allocated -================ -*/ -template -ID_INLINE size_t idStaticList::Allocated( void ) const { - return size * sizeof( type ); -} - -/* -================ -idStaticList::Size -================ -*/ -template -ID_INLINE size_t idStaticList::Size( void ) const { - return sizeof( idStaticList ) + Allocated(); -} - -/* -================ -idStaticList::Num -================ -*/ -template -ID_INLINE size_t idStaticList::MemoryUsed( void ) const { - return num * sizeof( list[ 0 ] ); -} - -/* -================ -idStaticList::SetNum - -Set number of elements in list. -================ -*/ -template -ID_INLINE void idStaticList::SetNum( int newnum ) { - assert( newnum >= 0 ); - assert( newnum <= size ); - num = newnum; -} - -/* -================ -idStaticList::operator[] const - -Access operator. Index must be within range or an assert will be issued in debug builds. -Release builds do no range checking. -================ -*/ -template -ID_INLINE const type &idStaticList::operator[]( int index ) const { - assert( index >= 0 ); - assert( index < num ); - - return list[ index ]; -} - -/* -================ -idStaticList::operator[] - -Access operator. Index must be within range or an assert will be issued in debug builds. -Release builds do no range checking. -================ -*/ -template -ID_INLINE type &idStaticList::operator[]( int index ) { - assert( index >= 0 ); - assert( index < num ); - - return list[ index ]; -} - -/* -================ -idStaticList::Ptr - -Returns a pointer to the begining of the array. Useful for iterating through the list in loops. - -Note: may return NULL if the list is empty. - -FIXME: Create an iterator template for this kind of thing. -================ -*/ -template -ID_INLINE type *idStaticList::Ptr( void ) { - return &list[ 0 ]; -} - -/* -================ -idStaticList::Ptr - -Returns a pointer to the begining of the array. Useful for iterating through the list in loops. - -Note: may return NULL if the list is empty. - -FIXME: Create an iterator template for this kind of thing. -================ -*/ -template -ID_INLINE const type *idStaticList::Ptr( void ) const { - return &list[ 0 ]; -} - -/* -================ -idStaticList::Alloc - -Returns a pointer to a new data element at the end of the list. -================ -*/ -template -ID_INLINE type *idStaticList::Alloc( void ) { - if ( num >= size ) { - return NULL; - } - - return &list[ num++ ]; -} - -/* -================ -idStaticList::Append - -Increases the size of the list by one element and copies the supplied data into it. - -Returns the index of the new element, or -1 when list is full. -================ -*/ -template -ID_INLINE int idStaticList::Append( type const & obj ) { - assert( num < size ); - if ( num < size ) { - list[ num ] = obj; - num++; - return num - 1; - } - - return -1; -} - - -/* -================ -idStaticList::Insert - -Increases the size of the list by at leat one element if necessary -and inserts the supplied data into it. - -Returns the index of the new element, or -1 when list is full. -================ -*/ -template -ID_INLINE int idStaticList::Insert( type const & obj, int index ) { - int i; - - assert( num < size ); - if ( num >= size ) { - return -1; - } - - assert( index >= 0 ); - if ( index < 0 ) { - index = 0; - } else if ( index > num ) { - index = num; - } - - for( i = num; i > index; --i ) { - list[i] = list[i-1]; - } - - num++; - list[index] = obj; - return index; -} - -/* -================ -idStaticList::Append - -adds the other list to this one - -Returns the size of the new combined list -================ -*/ -template -ID_INLINE int idStaticList::Append( const idStaticList &other ) { - int i; - int n = other.Num(); - - if ( num + n > size ) { - n = size - num; - } - for( i = 0; i < n; i++ ) { - list[i + num] = other.list[i]; - } - num += n; - return Num(); -} - -/* -================ -idStaticList::AddUnique - -Adds the data to the list if it doesn't already exist. Returns the index of the data in the list. -================ -*/ -template -ID_INLINE int idStaticList::AddUnique( type const & obj ) { - int index; - - index = FindIndex( obj ); - if ( index < 0 ) { - index = Append( obj ); - } - - return index; -} - -/* -================ -idStaticList::FindIndex - -Searches for the specified data in the list and returns it's index. Returns -1 if the data is not found. -================ -*/ -template -ID_INLINE int idStaticList::FindIndex( type const & obj ) const { - int i; - - for( i = 0; i < num; i++ ) { - if ( list[ i ] == obj ) { - return i; - } - } - - // Not found - return -1; -} - -/* -================ -idStaticList::Find - -Searches for the specified data in the list and returns it's address. Returns NULL if the data is not found. -================ -*/ -template -ID_INLINE type *idStaticList::Find( type const & obj ) const { - int i; - - i = FindIndex( obj ); - if ( i >= 0 ) { - return &list[ i ]; - } - - return NULL; -} - -/* -================ -idStaticList::FindNull - -Searches for a NULL pointer in the list. Returns -1 if NULL is not found. - -NOTE: This function can only be called on lists containing pointers. Calling it -on non-pointer lists will cause a compiler error. -================ -*/ -template -ID_INLINE int idStaticList::FindNull( void ) const { - int i; - - for( i = 0; i < num; i++ ) { - if ( list[ i ] == NULL ) { - return i; - } - } - - // Not found - return -1; -} - -/* -================ -idStaticList::IndexOf - -Takes a pointer to an element in the list and returns the index of the element. -This is NOT a guarantee that the object is really in the list. -Function will assert in debug builds if pointer is outside the bounds of the list, -but remains silent in release builds. -================ -*/ -template -ID_INLINE int idStaticList::IndexOf( type const *objptr ) const { - int index; - - index = objptr - list; - - assert( index >= 0 ); - assert( index < num ); - - return index; -} - -/* -================ -idStaticList::RemoveIndex - -Removes the element at the specified index and moves all data following the element down to fill in the gap. -The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list. -Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. -================ -*/ -template -ID_INLINE bool idStaticList::RemoveIndex( int index ) { - int i; - - assert( index >= 0 ); - assert( index < num ); - - if ( ( index < 0 ) || ( index >= num ) ) { - return false; - } - - num--; - for( i = index; i < num; i++ ) { - list[ i ] = list[ i + 1 ]; - } - - return true; -} - -/* -================ -idStaticList::Remove - -Removes the element if it is found within the list and moves all data following the element down to fill in the gap. -The number of elements in the list is reduced by one. Returns false if the data is not found in the list. Note that -the element is not destroyed, so any memory used by it may not be freed until the destruction of the list. -================ -*/ -template -ID_INLINE bool idStaticList::Remove( type const & obj ) { - int index; - - index = FindIndex( obj ); - if ( index >= 0 ) { - return RemoveIndex( index ); - } - - return false; -} - -/* -================ -idStaticList::Swap - -Swaps the contents of two lists -================ -*/ -template -ID_INLINE void idStaticList::Swap( idStaticList &other ) { - idStaticList temp = *this; - *this = other; - other = temp; -} - -#endif /* !__STATICLIST_H__ */ diff --git a/idlib/containers/strlist.h b/idlib/containers/strlist.h deleted file mode 100644 index 80e5decc5..000000000 --- a/idlib/containers/strlist.h +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __STRLIST_H__ -#define __STRLIST_H__ - -/* -=============================================================================== - - idStrList - -=============================================================================== -*/ - -typedef idList idStrList; -typedef idList idStrPtrList; -typedef idStr *idStrPtr; - -/* -================ -idListSortCompare - -Compares two pointers to strings. Used to sort a list of string pointers alphabetically in idList::Sort. -================ -*/ -template<> -ID_INLINE int idListSortCompare( const idStrPtr *a, const idStrPtr *b ) { - return ( *a )->Icmp( **b ); -} - -/* -================ -idStrList::Sort - -Sorts the list of strings alphabetically. Creates a list of pointers to the actual strings and sorts the -pointer list. Then copies the strings into another list using the ordered list of pointers. -================ -*/ -template<> -ID_INLINE void idStrList::Sort( cmp_t *compare ) { - int i; - - if ( !num ) { - return; - } - - idList other; - idList pointerList; - - pointerList.SetNum( num ); - for( i = 0; i < num; i++ ) { - pointerList[ i ] = &( *this )[ i ]; - } - - pointerList.Sort(); - - other.SetNum( num ); - other.SetGranularity( granularity ); - for( i = 0; i < other.Num(); i++ ) { - other[ i ] = *pointerList[ i ]; - } - - this->Swap( other ); -} - -/* -================ -idStrList::SortSubSection - -Sorts a subsection of the list of strings alphabetically. -================ -*/ -template<> -ID_INLINE void idStrList::SortSubSection( int startIndex, int endIndex, cmp_t *compare ) { - int i, s; - - if ( !num ) { - return; - } - if ( startIndex < 0 ) { - startIndex = 0; - } - if ( endIndex >= num ) { - endIndex = num - 1; - } - if ( startIndex >= endIndex ) { - return; - } - - idList other; - idList pointerList; - - s = endIndex - startIndex + 1; - other.SetNum( s ); - pointerList.SetNum( s ); - for( i = 0; i < s; i++ ) { - other[ i ] = ( *this )[ startIndex + i ]; - pointerList[ i ] = &other[ i ]; - } - - pointerList.Sort(); - - for( i = 0; i < s; i++ ) { - (*this)[ startIndex + i ] = *pointerList[ i ]; - } -} - -/* -================ -idStrList::Size -================ -*/ -template<> -ID_INLINE size_t idStrList::Size( void ) const { - size_t s; - int i; - - s = sizeof( *this ); - for( i = 0; i < Num(); i++ ) { - s += ( *this )[ i ].Size(); - } - - return s; -} - -/* -=============================================================================== - - idStrList path sorting - -=============================================================================== -*/ - -/* -================ -idListSortComparePaths - -Compares two pointers to strings. Used to sort a list of string pointers alphabetically in idList::Sort. -================ -*/ -template -ID_INLINE int idListSortComparePaths( const idStrPtr *a, const idStrPtr *b ) { - return ( *a )->IcmpPath( **b ); -} - -/* -================ -idStrListSortPaths - -Sorts the list of path strings alphabetically and makes sure folders come first. -================ -*/ -ID_INLINE void idStrListSortPaths( idStrList &list ) { - int i; - - if ( !list.Num() ) { - return; - } - - idList other; - idList pointerList; - - pointerList.SetNum( list.Num() ); - for( i = 0; i < list.Num(); i++ ) { - pointerList[ i ] = &list[ i ]; - } - - pointerList.Sort( idListSortComparePaths ); - - other.SetNum( list.Num() ); - other.SetGranularity( list.GetGranularity() ); - for( i = 0; i < other.Num(); i++ ) { - other[ i ] = *pointerList[ i ]; - } - - list.Swap( other ); -} - -#endif /* !__STRLIST_H__ */ diff --git a/idlib/containers/strpool.h b/idlib/containers/strpool.h deleted file mode 100644 index c047283d1..000000000 --- a/idlib/containers/strpool.h +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __STRPOOL_H__ -#define __STRPOOL_H__ - -/* -=============================================================================== - - idStrPool - -=============================================================================== -*/ - -class idStrPool; - -class idPoolStr : public idStr { - friend class idStrPool; - -public: - idPoolStr() { numUsers = 0; } - ~idPoolStr() { assert( numUsers == 0 ); } - - // returns total size of allocated memory - size_t Allocated( void ) const { return idStr::Allocated(); } - // returns total size of allocated memory including size of string pool type - size_t Size( void ) const { return sizeof( *this ) + Allocated(); } - // returns a pointer to the pool this string was allocated from - const idStrPool * GetPool( void ) const { return pool; } - -private: - idStrPool * pool; - mutable int numUsers; -}; - -class idStrPool { -public: - idStrPool() { caseSensitive = true; } - - void SetCaseSensitive( bool caseSensitive ); - - int Num( void ) const { return pool.Num(); } - size_t Allocated( void ) const; - size_t Size( void ) const; - - const idPoolStr * operator[]( int index ) const { return pool[index]; } - - const idPoolStr * AllocString( const char *string ); - void FreeString( const idPoolStr *poolStr ); - const idPoolStr * CopyString( const idPoolStr *poolStr ); - void Clear( void ); - -private: - bool caseSensitive; - idList pool; - idHashIndex poolHash; -}; - -/* -================ -idStrPool::SetCaseSensitive -================ -*/ -ID_INLINE void idStrPool::SetCaseSensitive( bool caseSensitive ) { - this->caseSensitive = caseSensitive; -} - -/* -================ -idStrPool::AllocString -================ -*/ -ID_INLINE const idPoolStr *idStrPool::AllocString( const char *string ) { - int i, hash; - idPoolStr *poolStr; - - hash = poolHash.GenerateKey( string, caseSensitive ); - if ( caseSensitive ) { - for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { - if ( pool[i]->Cmp( string ) == 0 ) { - pool[i]->numUsers++; - return pool[i]; - } - } - } else { - for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { - if ( pool[i]->Icmp( string ) == 0 ) { - pool[i]->numUsers++; - return pool[i]; - } - } - } - - poolStr = new idPoolStr; - *static_cast(poolStr) = string; - poolStr->pool = this; - poolStr->numUsers = 1; - poolHash.Add( hash, pool.Append( poolStr ) ); - return poolStr; -} - -/* -================ -idStrPool::FreeString -================ -*/ -ID_INLINE void idStrPool::FreeString( const idPoolStr *poolStr ) { - int i, hash; - - assert( poolStr->numUsers >= 1 ); - assert( poolStr->pool == this ); - - poolStr->numUsers--; - if ( poolStr->numUsers <= 0 ) { - hash = poolHash.GenerateKey( poolStr->c_str(), caseSensitive ); - if ( caseSensitive ) { - for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { - if ( pool[i]->Cmp( poolStr->c_str() ) == 0 ) { - break; - } - } - } else { - for ( i = poolHash.First( hash ); i != -1; i = poolHash.Next( i ) ) { - if ( pool[i]->Icmp( poolStr->c_str() ) == 0 ) { - break; - } - } - } - assert( i != -1 ); - assert( pool[i] == poolStr ); - delete pool[i]; - pool.RemoveIndex( i ); - poolHash.RemoveIndex( hash, i ); - } -} - -/* -================ -idStrPool::CopyString -================ -*/ -ID_INLINE const idPoolStr *idStrPool::CopyString( const idPoolStr *poolStr ) { - - assert( poolStr->numUsers >= 1 ); - - if ( poolStr->pool == this ) { - // the string is from this pool so just increase the user count - poolStr->numUsers++; - return poolStr; - } else { - // the string is from another pool so it needs to be re-allocated from this pool. - return AllocString( poolStr->c_str() ); - } -} - -/* -================ -idStrPool::Clear -================ -*/ -ID_INLINE void idStrPool::Clear( void ) { - int i; - - for ( i = 0; i < pool.Num(); i++ ) { - pool[i]->numUsers = 0; - } - pool.DeleteContents( true ); - poolHash.Free(); -} - -/* -================ -idStrPool::Allocated -================ -*/ -ID_INLINE size_t idStrPool::Allocated( void ) const { - int i; - size_t size; - - size = pool.Allocated() + poolHash.Allocated(); - for ( i = 0; i < pool.Num(); i++ ) { - size += pool[i]->Allocated(); - } - return size; -} - -/* -================ -idStrPool::Size -================ -*/ -ID_INLINE size_t idStrPool::Size( void ) const { - int i; - size_t size; - - size = pool.Size() + poolHash.Size(); - for ( i = 0; i < pool.Num(); i++ ) { - size += pool[i]->Size(); - } - return size; -} - -#endif /* !__STRPOOL_H__ */ diff --git a/idlib/containers/vectorset.h b/idlib/containers/vectorset.h deleted file mode 100644 index 45b807d32..000000000 --- a/idlib/containers/vectorset.h +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __VECTORSET_H__ -#define __VECTORSET_H__ - -/* -=============================================================================== - - Vector Set - - Creates a set of vectors without duplicates. - -=============================================================================== -*/ - -template< class type, int dimension > -class idVectorSet : public idList { -public: - idVectorSet( void ); - idVectorSet( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); - - // returns total size of allocated memory - size_t Allocated( void ) const { return idList::Allocated() + hash.Allocated(); } - // returns total size of allocated memory including size of type - size_t Size( void ) const { return sizeof( *this ) + Allocated(); } - - void Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); - void ResizeIndex( const int newSize ); - void Clear( void ); - - int FindVector( const type &v, const float epsilon ); - -private: - idHashIndex hash; - type mins; - type maxs; - int boxHashSize; - float boxInvSize[dimension]; - float boxHalfSize[dimension]; -}; - -template< class type, int dimension > -ID_INLINE idVectorSet::idVectorSet( void ) { - hash.Clear( idMath::IPow( boxHashSize, dimension ), 128 ); - boxHashSize = 16; - memset( boxInvSize, 0, dimension * sizeof( boxInvSize[0] ) ); - memset( boxHalfSize, 0, dimension * sizeof( boxHalfSize[0] ) ); -} - -template< class type, int dimension > -ID_INLINE idVectorSet::idVectorSet( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { - Init( mins, maxs, boxHashSize, initialSize ); -} - -template< class type, int dimension > -ID_INLINE void idVectorSet::Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { - int i; - float boxSize; - - idList::AssureSize( initialSize ); - idList::SetNum( 0, false ); - - hash.Clear( idMath::IPow( boxHashSize, dimension ), initialSize ); - - this->mins = mins; - this->maxs = maxs; - this->boxHashSize = boxHashSize; - - for ( i = 0; i < dimension; i++ ) { - boxSize = ( maxs[i] - mins[i] ) / (float) boxHashSize; - boxInvSize[i] = 1.0f / boxSize; - boxHalfSize[i] = boxSize * 0.5f; - } -} - -template< class type, int dimension > -ID_INLINE void idVectorSet::ResizeIndex( const int newSize ) { - idList::Resize( newSize ); - hash.ResizeIndex( newSize ); -} - -template< class type, int dimension > -ID_INLINE void idVectorSet::Clear( void ) { - idList::Clear(); - hash.Clear(); -} - -template< class type, int dimension > -ID_INLINE int idVectorSet::FindVector( const type &v, const float epsilon ) { - int i, j, k, hashKey, partialHashKey[dimension]; - - for ( i = 0; i < dimension; i++ ) { - assert( epsilon <= boxHalfSize[i] ); - partialHashKey[i] = (int) ( ( v[i] - mins[i] - boxHalfSize[i] ) * boxInvSize[i] ); - } - - for ( i = 0; i < ( 1 << dimension ); i++ ) { - - hashKey = 0; - for ( j = 0; j < dimension; j++ ) { - hashKey *= boxHashSize; - hashKey += partialHashKey[j] + ( ( i >> j ) & 1 ); - } - - for ( j = hash.First( hashKey ); j >= 0; j = hash.Next( j ) ) { - const type &lv = (*this)[j]; - for ( k = 0; k < dimension; k++ ) { - if ( idMath::Fabs( lv[k] - v[k] ) > epsilon ) { - break; - } - } - if ( k >= dimension ) { - return j; - } - } - } - - hashKey = 0; - for ( i = 0; i < dimension; i++ ) { - hashKey *= boxHashSize; - hashKey += (int) ( ( v[i] - mins[i] ) * boxInvSize[i] ); - } - - hash.Add( hashKey, idList::Num() ); - Append( v ); - return idList::Num()-1; -} - - -/* -=============================================================================== - - Vector Subset - - Creates a subset without duplicates from an existing list with vectors. - -=============================================================================== -*/ - -template< class type, int dimension > -class idVectorSubset { -public: - idVectorSubset( void ); - idVectorSubset( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); - - // returns total size of allocated memory - size_t Allocated( void ) const { return idList::Allocated() + hash.Allocated(); } - // returns total size of allocated memory including size of type - size_t Size( void ) const { return sizeof( *this ) + Allocated(); } - - void Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ); - void Clear( void ); - - // returns either vectorNum or an index to a previously found vector - int FindVector( const type *vectorList, const int vectorNum, const float epsilon ); - -private: - idHashIndex hash; - type mins; - type maxs; - int boxHashSize; - float boxInvSize[dimension]; - float boxHalfSize[dimension]; -}; - -template< class type, int dimension > -ID_INLINE idVectorSubset::idVectorSubset( void ) { - hash.Clear( idMath::IPow( boxHashSize, dimension ), 128 ); - boxHashSize = 16; - memset( boxInvSize, 0, dimension * sizeof( boxInvSize[0] ) ); - memset( boxHalfSize, 0, dimension * sizeof( boxHalfSize[0] ) ); -} - -template< class type, int dimension > -ID_INLINE idVectorSubset::idVectorSubset( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { - Init( mins, maxs, boxHashSize, initialSize ); -} - -template< class type, int dimension > -ID_INLINE void idVectorSubset::Init( const type &mins, const type &maxs, const int boxHashSize, const int initialSize ) { - int i; - float boxSize; - - hash.Clear( idMath::IPow( boxHashSize, dimension ), initialSize ); - - this->mins = mins; - this->maxs = maxs; - this->boxHashSize = boxHashSize; - - for ( i = 0; i < dimension; i++ ) { - boxSize = ( maxs[i] - mins[i] ) / (float) boxHashSize; - boxInvSize[i] = 1.0f / boxSize; - boxHalfSize[i] = boxSize * 0.5f; - } -} - -template< class type, int dimension > -ID_INLINE void idVectorSubset::Clear( void ) { - idList::Clear(); - hash.Clear(); -} - -template< class type, int dimension > -ID_INLINE int idVectorSubset::FindVector( const type *vectorList, const int vectorNum, const float epsilon ) { - int i, j, k, hashKey, partialHashKey[dimension]; - const type &v = vectorList[vectorNum]; - - for ( i = 0; i < dimension; i++ ) { - assert( epsilon <= boxHalfSize[i] ); - partialHashKey[i] = (int) ( ( v[i] - mins[i] - boxHalfSize[i] ) * boxInvSize[i] ); - } - - for ( i = 0; i < ( 1 << dimension ); i++ ) { - - hashKey = 0; - for ( j = 0; j < dimension; j++ ) { - hashKey *= boxHashSize; - hashKey += partialHashKey[j] + ( ( i >> j ) & 1 ); - } - - for ( j = hash.First( hashKey ); j >= 0; j = hash.Next( j ) ) { - const type &lv = vectorList[j]; - for ( k = 0; k < dimension; k++ ) { - if ( idMath::Fabs( lv[k] - v[k] ) > epsilon ) { - break; - } - } - if ( k >= dimension ) { - return j; - } - } - } - - hashKey = 0; - for ( i = 0; i < dimension; i++ ) { - hashKey *= boxHashSize; - hashKey += (int) ( ( v[i] - mins[i] ) * boxInvSize[i] ); - } - - hash.Add( hashKey, vectorNum ); - return vectorNum; -} - -#endif /* !__VECTORSET_H__ */ diff --git a/idlib/dict.cpp b/idlib/dict.cpp deleted file mode 100644 index 9257b6f7c..000000000 --- a/idlib/dict.cpp +++ /dev/null @@ -1,725 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - - -idStrPool idDict::globalKeys; -idStrPool idDict::globalValues; - -/* -================ -idDict::operator= - - clear existing key/value pairs and copy all key/value pairs from other -================ -*/ -idDict &idDict::operator=( const idDict &other ) { - int i; - - // check for assignment to self - if ( this == &other ) { - return *this; - } - - Clear(); - - args = other.args; - argHash = other.argHash; - - for ( i = 0; i < args.Num(); i++ ) { - args[i].key = globalKeys.CopyString( args[i].key ); - args[i].value = globalValues.CopyString( args[i].value ); - } - - return *this; -} - -/* -================ -idDict::Copy - - copy all key value pairs without removing existing key/value pairs not present in the other dict -================ -*/ -void idDict::Copy( const idDict &other ) { - int i, n, *found; - idKeyValue kv; - - // check for assignment to self - if ( this == &other ) { - return; - } - - n = other.args.Num(); - - if ( args.Num() ) { - found = (int *) _alloca16( other.args.Num() * sizeof( int ) ); - for ( i = 0; i < n; i++ ) { - found[i] = FindKeyIndex( other.args[i].GetKey() ); - } - } else { - found = NULL; - } - - for ( i = 0; i < n; i++ ) { - if ( found && found[i] != -1 ) { - // first set the new value and then free the old value to allow proper self copying - const idPoolStr *oldValue = args[found[i]].value; - args[found[i]].value = globalValues.CopyString( other.args[i].value ); - globalValues.FreeString( oldValue ); - } else { - kv.key = globalKeys.CopyString( other.args[i].key ); - kv.value = globalValues.CopyString( other.args[i].value ); - argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) ); - } - } -} - -/* -================ -idDict::TransferKeyValues - - clear existing key/value pairs and transfer key/value pairs from other -================ -*/ -void idDict::TransferKeyValues( idDict &other ) { - int i, n; - - if ( this == &other ) { - return; - } - - if ( other.args.Num() && other.args[0].key->GetPool() != &globalKeys ) { - common->FatalError( "idDict::TransferKeyValues: can't transfer values across a DLL boundary" ); - return; - } - - Clear(); - - n = other.args.Num(); - args.SetNum( n ); - for ( i = 0; i < n; i++ ) { - args[i].key = other.args[i].key; - args[i].value = other.args[i].value; - } - argHash = other.argHash; - - other.args.Clear(); - other.argHash.Free(); -} - -/* -================ -idDict::Parse -================ -*/ -bool idDict::Parse( idParser &parser ) { - idToken token; - idToken token2; - bool errors; - - errors = false; - - parser.ExpectTokenString( "{" ); - parser.ReadToken( &token ); - while( ( token.type != TT_PUNCTUATION ) || ( token != "}" ) ) { - if ( token.type != TT_STRING ) { - parser.Error( "Expected quoted string, but found '%s'", token.c_str() ); - } - - if ( !parser.ReadToken( &token2 ) ) { - parser.Error( "Unexpected end of file" ); - } - - if ( FindKey( token ) ) { - parser.Warning( "'%s' already defined", token.c_str() ); - errors = true; - } - Set( token, token2 ); - - if ( !parser.ReadToken( &token ) ) { - parser.Error( "Unexpected end of file" ); - } - } - - return !errors; -} - -/* -================ -idDict::SetDefaults -================ -*/ -void idDict::SetDefaults( const idDict *dict ) { - int i, n; - const idKeyValue *kv, *def; - idKeyValue newkv; - - n = dict->args.Num(); - for( i = 0; i < n; i++ ) { - def = &dict->args[i]; - kv = FindKey( def->GetKey() ); - if ( !kv ) { - newkv.key = globalKeys.CopyString( def->key ); - newkv.value = globalValues.CopyString( def->value ); - argHash.Add( argHash.GenerateKey( newkv.GetKey(), false ), args.Append( newkv ) ); - } - } -} - -/* -================ -idDict::SetDefaults - -Tels: Like SetDefaults(), but skips all entries starting with skip: -================ -*/ -void idDict::SetDefaults( const idDict *dict, const idStr &skip ) { - int i, n, l; - const idKeyValue *kv, *def; - idKeyValue newkv; - - n = dict->args.Num(); - l = skip.Length(); - for( i = 0; i < n; i++ ) { - def = &dict->args[i]; - if (def->GetKey().Icmpn(skip, l) == 0) - { - continue; - } - kv = FindKey( def->GetKey() ); - if ( !kv ) { - newkv.key = globalKeys.CopyString( def->key ); - newkv.value = globalValues.CopyString( def->value ); - argHash.Add( argHash.GenerateKey( newkv.GetKey(), false ), args.Append( newkv ) ); - } - } -} - -/* -================ -idDict::Clear -================ -*/ -void idDict::Clear( void ) { - int i; - - for( i = 0; i < args.Num(); i++ ) { - globalKeys.FreeString( args[i].key ); - globalValues.FreeString( args[i].value ); - } - - args.Clear(); - argHash.Free(); -} - -/* -================ -idDict::Print -================ -*/ -void idDict::Print() const { - int i; - int n; - - n = args.Num(); - for( i = 0; i < n; i++ ) { - idLib::common->Printf( "%s = %s\n", args[i].GetKey().c_str(), args[i].GetValue().c_str() ); - } -} - -int KeyCompare( const idKeyValue *a, const idKeyValue *b ) { - return idStr::Cmp( a->GetKey(), b->GetKey() ); -} - -/* -================ -idDict::Checksum -================ -*/ -int idDict::Checksum( void ) const { - unsigned long ret; - int i, n; - - idList sorted = args; - sorted.Sort( KeyCompare ); - n = sorted.Num(); - CRC32_InitChecksum( ret ); - for( i = 0; i < n; i++ ) { - CRC32_UpdateChecksum( ret, sorted[i].GetKey().c_str(), sorted[i].GetKey().Length() ); - CRC32_UpdateChecksum( ret, sorted[i].GetValue().c_str(), sorted[i].GetValue().Length() ); - } - CRC32_FinishChecksum( ret ); - return ret; -} - -/* -================ -idDict::Allocated -================ -*/ -size_t idDict::Allocated( void ) const { - int i; - size_t size; - - size = args.Allocated() + argHash.Allocated(); - for( i = 0; i < args.Num(); i++ ) { - size += args[i].Size(); - } - - return size; -} - -/* -================ -idDict::Set -================ -*/ -void idDict::Set( const char *key, const char *value ) { - int i; - idKeyValue kv; - - if ( key == NULL || key[0] == '\0' ) { - return; - } - - i = FindKeyIndex( key ); - if ( i != -1 ) { - // first set the new value and then free the old value to allow proper self copying - const idPoolStr *oldValue = args[i].value; - args[i].value = globalValues.AllocString( value ); - globalValues.FreeString( oldValue ); - } else { - kv.key = globalKeys.AllocString( key ); - kv.value = globalValues.AllocString( value ); - argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) ); - } -} - -/* -================ -idDict::GetFloat -================ -*/ -bool idDict::GetFloat( const char *key, const char *defaultString, float &out ) const { - const char *s; - bool found; - - found = GetString( key, defaultString, &s ); - out = atof( s ); - return found; -} - -/* -================ -idDict::GetInt -================ -*/ -bool idDict::GetInt( const char *key, const char *defaultString, int &out ) const { - const char *s; - bool found; - - found = GetString( key, defaultString, &s ); - out = atoi( s ); - return found; -} - -/* -================ -idDict::GetBool -================ -*/ -bool idDict::GetBool( const char *key, const char *defaultString, bool &out ) const { - const char *s; - bool found; - - found = GetString( key, defaultString, &s ); - out = ( atoi( s ) != 0 ); - return found; -} - -/* -================ -idDict::GetAngles -================ -*/ -bool idDict::GetAngles( const char *key, const char *defaultString, idAngles &out ) const { - bool found; - const char *s; - - if ( !defaultString ) { - defaultString = "0 0 0"; - } - - found = GetString( key, defaultString, &s ); - out.Zero(); - sscanf( s, "%f %f %f", &out.pitch, &out.yaw, &out.roll ); - return found; -} - -/* -================ -idDict::GetVector -================ -*/ -bool idDict::GetVector( const char *key, const char *defaultString, idVec3 &out ) const { - bool found; - const char *s; - - if ( !defaultString ) { - defaultString = "0 0 0"; - } - - found = GetString( key, defaultString, &s ); - out.Zero(); - sscanf( s, "%f %f %f", &out.x, &out.y, &out.z ); - return found; -} - -/* -================ -idDict::GetVec2 -================ -*/ -bool idDict::GetVec2( const char *key, const char *defaultString, idVec2 &out ) const { - bool found; - const char *s; - - if ( !defaultString ) { - defaultString = "0 0"; - } - - found = GetString( key, defaultString, &s ); - out.Zero(); - sscanf( s, "%f %f", &out.x, &out.y ); - return found; -} - -/* -================ -idDict::GetVec4 -================ -*/ -bool idDict::GetVec4( const char *key, const char *defaultString, idVec4 &out ) const { - bool found; - const char *s; - - if ( !defaultString ) { - defaultString = "0 0 0 0"; - } - - found = GetString( key, defaultString, &s ); - out.Zero(); - sscanf( s, "%f %f %f %f", &out.x, &out.y, &out.z, &out.w ); - return found; -} - -/* -================ -idDict::GetMatrix -================ -*/ -bool idDict::GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const { - const char *s; - bool found; - - if ( !defaultString ) { - defaultString = "1 0 0 0 1 0 0 0 1"; - } - - found = GetString( key, defaultString, &s ); - out.Identity(); // sccanf has a bug in it on Mac OS 9. Sigh. - sscanf( s, "%f %f %f %f %f %f %f %f %f", &out[0].x, &out[0].y, &out[0].z, &out[1].x, &out[1].y, &out[1].z, &out[2].x, &out[2].y, &out[2].z ); - return found; -} - -/* -================ -WriteString -================ -*/ -static void WriteString( const char *s, idFile *f ) { - int len = strlen( s ); - if ( len >= MAX_STRING_CHARS-1 ) { - idLib::common->Error( "idDict::WriteToFileHandle: bad string" ); - } - f->Write( s, strlen(s) + 1 ); -} - -/* -================ -idDict::FindKey -================ -*/ -const idKeyValue *idDict::FindKey( const char *key ) const { - int i, hash; - - if ( key == NULL || key[0] == '\0' ) { - idLib::common->DWarning( "idDict::FindKey: empty key" ); - return NULL; - } - - hash = argHash.GenerateKey( key, false ); - for ( i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { - if ( args[i].GetKey().Icmp( key ) == 0 ) { - return &args[i]; - } - } - - return NULL; -} - -/* -================ -idDict::FindKeyIndex -================ -*/ -int idDict::FindKeyIndex( const char *key ) const { - - if ( key == NULL || key[0] == '\0' ) { - idLib::common->DWarning( "idDict::FindKeyIndex: empty key" ); - return 0; - } - - int hash = argHash.GenerateKey( key, false ); - for ( int i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { - if ( args[i].GetKey().Icmp( key ) == 0 ) { - return i; - } - } - - return -1; -} - -/* -================ -idDict::Delete -================ -*/ -void idDict::Delete( const char *key ) { - int hash, i; - - hash = argHash.GenerateKey( key, false ); - for ( i = argHash.First( hash ); i != -1; i = argHash.Next( i ) ) { - if ( args[i].GetKey().Icmp( key ) == 0 ) { - globalKeys.FreeString( args[i].key ); - globalValues.FreeString( args[i].value ); - args.RemoveIndex( i ); - argHash.RemoveIndex( hash, i ); - break; - } - } - -#if 0 - // make sure all keys can still be found in the hash index - for ( i = 0; i < args.Num(); i++ ) { - assert( FindKey( args[i].GetKey() ) != NULL ); - } -#endif -} - -/* -================ -idDict::MatchPrefix -================ -*/ -const idKeyValue *idDict::MatchPrefix( const char *prefix, const idKeyValue *lastMatch ) const { - int i; - int len; - int start; - - assert( prefix ); - len = strlen( prefix ); - - start = -1; - if ( lastMatch ) { - start = args.FindIndex( *lastMatch ); - assert( start >= 0 ); - if ( start < 1 ) { - start = 0; - } - } - - for( i = start + 1; i < args.Num(); i++ ) { - if ( !args[i].GetKey().Icmpn( prefix, len ) ) { - return &args[i]; - } - } - return NULL; -} - -/* -================ -idDict::RandomPrefix -================ -*/ -const char *idDict::RandomPrefix( const char *prefix, idRandom &random ) const { - int count; - const int MAX_RANDOM_KEYS = 2048; - const char *list[MAX_RANDOM_KEYS]; - const idKeyValue *kv; - - list[0] = ""; - for ( count = 0, kv = MatchPrefix( prefix ); kv && count < MAX_RANDOM_KEYS; kv = MatchPrefix( prefix, kv ) ) { - list[count++] = kv->GetValue().c_str(); - } - return list[random.RandomInt( count )]; -} - -/* -================ -idDict::WriteToFileHandle -================ -*/ -void idDict::WriteToFileHandle( idFile *f ) const { - int c = LittleLong( args.Num() ); - f->Write( &c, sizeof( c ) ); - for ( int i = 0; i < args.Num(); i++ ) { // don't loop on the swapped count use the original - WriteString( args[i].GetKey().c_str(), f ); - WriteString( args[i].GetValue().c_str(), f ); - } -} - -/* -================ -ReadString -================ -*/ -static idStr ReadString( idFile *f ) { - char str[MAX_STRING_CHARS]; - int len; - - for ( len = 0; len < MAX_STRING_CHARS; len++ ) { - f->Read( (void *)&str[len], 1 ); - if ( str[len] == 0 ) { - break; - } - } - if ( len == MAX_STRING_CHARS ) { - idLib::common->Error( "idDict::ReadFromFileHandle: bad string" ); - } - - return idStr( str ); -} - -/* -================ -idDict::ReadFromFileHandle -================ -*/ -void idDict::ReadFromFileHandle( idFile *f ) { - int c; - idStr key, val; - - Clear(); - - f->Read( &c, sizeof( c ) ); - c = LittleLong( c ); - for ( int i = 0; i < c; i++ ) { - key = ReadString( f ); - val = ReadString( f ); - Set( key, val ); - } -} - -/* -================ -idDict::Init -================ -*/ -void idDict::Init( void ) { - globalKeys.SetCaseSensitive( false ); - globalValues.SetCaseSensitive( true ); -} - -/* -================ -idDict::Shutdown -================ -*/ -void idDict::Shutdown( void ) { - globalKeys.Clear(); - globalValues.Clear(); -} - -/* -================ -idDict::ShowMemoryUsage_f -================ -*/ -void idDict::ShowMemoryUsage_f( const idCmdArgs &args ) { - idLib::common->Printf( "%5d KB in %d keys\n", globalKeys.Size() >> 10, globalKeys.Num() ); - idLib::common->Printf( "%5d KB in %d values\n", globalValues.Size() >> 10, globalValues.Num() ); -} - -/* -================ -idDict::PrintMemory -================ -*/ -void idDict::PrintMemory( void ) const { - idLib::common->Printf( "%d KB in %d keys, %d KB in %d values.\n", - globalKeys.Size() >> 10, globalKeys.Num(), globalValues.Size() >> 10, globalValues.Num() ); -} - -/* -================ -idDictStringSortCmp -================ -*/ -// NOTE: the const wonkyness is required to make msvc happy -template<> -ID_INLINE int idListSortCompare( const idPoolStr * const *a, const idPoolStr * const *b ) { - return (*a)->Icmp( **b ); -} - -/* -================ -idDict::ListKeys_f -================ -*/ -void idDict::ListKeys_f( const idCmdArgs &args ) { - int i; - idList keyStrings; - - for ( i = 0; i < globalKeys.Num(); i++ ) { - keyStrings.Append( globalKeys[i] ); - } - keyStrings.Sort(); - for ( i = 0; i < keyStrings.Num(); i++ ) { - idLib::common->Printf( "%s\n", keyStrings[i]->c_str() ); - } - idLib::common->Printf( "%5d keys\n", keyStrings.Num() ); -} - -/* -================ -idDict::ListValues_f -================ -*/ -void idDict::ListValues_f( const idCmdArgs &args ) { - int i; - idList valueStrings; - - for ( i = 0; i < globalValues.Num(); i++ ) { - valueStrings.Append( globalValues[i] ); - } - valueStrings.Sort(); - for ( i = 0; i < valueStrings.Num(); i++ ) { - idLib::common->Printf( "%s\n", valueStrings[i]->c_str() ); - } - idLib::common->Printf( "%5d values\n", valueStrings.Num() ); -} diff --git a/idlib/dict.h b/idlib/dict.h deleted file mode 100644 index 69ba82be6..000000000 --- a/idlib/dict.h +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DICT_H__ -#define __DICT_H__ - -#include - -/* -=============================================================================== - -Key/value dictionary - -This is a dictionary class that tracks an arbitrary number of key / value -pair combinations. It is used for map entity spawning, GUI state management, -and other things. - -Keys are compared case-insensitive. - -Does not allocate memory until the first key/value pair is added. - -=============================================================================== -*/ - -class idKeyValue { - friend class idDict; - -public: - const idStr & GetKey( void ) const { return *key; } - const idStr & GetValue( void ) const { return *value; } - - size_t Allocated( void ) const { return key->Allocated() + value->Allocated(); } - size_t Size( void ) const { return sizeof( *this ) + key->Size() + value->Size(); } - - bool operator==( const idKeyValue &kv ) const { return ( key == kv.key && value == kv.value ); } - -private: - const idPoolStr * key; - const idPoolStr * value; -}; - -class idDict { -public: - idDict( void ); - idDict( const idDict &other ); // allow declaration with assignment - ~idDict( void ); - - // set the granularity for the index - void SetGranularity( int granularity ); - // set hash size - void SetHashSize( int hashSize ); - // clear existing key/value pairs and copy all key/value pairs from other - idDict & operator=( const idDict &other ); - // copy from other while leaving existing key/value pairs in place - void Copy( const idDict &other ); - // clear existing key/value pairs and transfer key/value pairs from other - void TransferKeyValues( idDict &other ); - // parse dict from parser - bool Parse( idParser &parser ); - // copy key/value pairs from other dict not present in this dict - void SetDefaults( const idDict *dict ); - // Tels: like SetDefaults(), but skip all keys starting with "skip" - void SetDefaults( const idDict *dict, const idStr &skip ); - // clear dict freeing up memory - void Clear( void ); - // print the dict - void Print() const; - - size_t Allocated( void ) const; - size_t Size( void ) const { return sizeof( *this ) + Allocated(); } - - void Set( const char *key, const char *value ); - void SetFloat( const char *key, float val ); - void SetInt( const char *key, int val ); - void SetBool( const char *key, bool val ); - void SetVector( const char *key, const idVec3 &val ); - void SetVec2( const char *key, const idVec2 &val ); - void SetVec4( const char *key, const idVec4 &val ); - void SetAngles( const char *key, const idAngles &val ); - void SetMatrix( const char *key, const idMat3 &val ); - - // these return default values of 0.0, 0 and false - const char * GetString( const char *key, const char *defaultString = "" ) const; - float GetFloat( const char *key, const char *defaultString = "0" ) const; - int GetInt( const char *key, const char *defaultString = "0" ) const; - bool GetBool( const char *key, const char *defaultString = "0" ) const; - idVec3 GetVector( const char *key, const char *defaultString = NULL ) const; - idVec2 GetVec2( const char *key, const char *defaultString = NULL ) const; - idVec4 GetVec4( const char *key, const char *defaultString = NULL ) const; - idAngles GetAngles( const char *key, const char *defaultString = NULL ) const; - idMat3 GetMatrix( const char *key, const char *defaultString = NULL ) const; - - bool GetString( const char *key, const char *defaultString, const char **out ) const; - bool GetString( const char *key, const char *defaultString, idStr &out ) const; - bool GetFloat( const char *key, const char *defaultString, float &out ) const; - bool GetInt( const char *key, const char *defaultString, int &out ) const; - bool GetBool( const char *key, const char *defaultString, bool &out ) const; - bool GetVector( const char *key, const char *defaultString, idVec3 &out ) const; - bool GetVec2( const char *key, const char *defaultString, idVec2 &out ) const; - bool GetVec4( const char *key, const char *defaultString, idVec4 &out ) const; - bool GetAngles( const char *key, const char *defaultString, idAngles &out ) const; - bool GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const; - - int GetNumKeyVals( void ) const; - const idKeyValue * GetKeyVal( int index ) const; - // returns the key/value pair with the given key - // returns NULL if the key/value pair does not exist - const idKeyValue * FindKey( const char *key ) const; - // returns the index to the key/value pair with the given key - // returns -1 if the key/value pair does not exist - int FindKeyIndex( const char *key ) const; - // delete the key/value pair with the given key - void Delete( const char *key ); - // finds the next key/value pair with the given key prefix. - // lastMatch can be used to do additional searches past the first match. - const idKeyValue * MatchPrefix( const char *prefix, const idKeyValue *lastMatch = NULL ) const; - // randomly chooses one of the key/value pairs with the given key prefix and returns it's value - const char * RandomPrefix( const char *prefix, idRandom &random ) const; - - void WriteToFileHandle( idFile *f ) const; - void ReadFromFileHandle( idFile *f ); - - // returns a unique checksum for this dictionary's content - int Checksum( void ) const; - - static void Init( void ); - static void Shutdown( void ); - - static void ShowMemoryUsage_f( const idCmdArgs &args ); - void PrintMemory( void ) const; - static void ListKeys_f( const idCmdArgs &args ); - static void ListValues_f( const idCmdArgs &args ); - -private: - idList args; - idHashIndex argHash; - - static idStrPool globalKeys; - static idStrPool globalValues; -}; - - -ID_INLINE idDict::idDict( void ) { - args.SetGranularity( 16 ); - argHash.SetGranularity( 16 ); - argHash.Clear( 128, 16 ); -} - -ID_INLINE idDict::idDict( const idDict &other ) { - *this = other; -} - -ID_INLINE idDict::~idDict( void ) { - Clear(); -} - -ID_INLINE void idDict::SetGranularity( int granularity ) { - args.SetGranularity( granularity ); - argHash.SetGranularity( granularity ); -} - -ID_INLINE void idDict::SetHashSize( int hashSize ) { - if ( args.Num() == 0 ) { - argHash.Clear( hashSize, 16 ); - } -} - -ID_INLINE void idDict::SetFloat( const char *key, float val ) { - Set( key, va( "%f", val ) ); -} - -ID_INLINE void idDict::SetInt( const char *key, int val ) { - Set( key, va( "%i", val ) ); -} - -ID_INLINE void idDict::SetBool( const char *key, bool val ) { - Set( key, va( "%i", val ) ); -} - -ID_INLINE void idDict::SetVector( const char *key, const idVec3 &val ) { - Set( key, val.ToString() ); -} - -ID_INLINE void idDict::SetVec4( const char *key, const idVec4 &val ) { - Set( key, val.ToString() ); -} - -ID_INLINE void idDict::SetVec2( const char *key, const idVec2 &val ) { - Set( key, val.ToString() ); -} - -ID_INLINE void idDict::SetAngles( const char *key, const idAngles &val ) { - Set( key, val.ToString() ); -} - -ID_INLINE void idDict::SetMatrix( const char *key, const idMat3 &val ) { - Set( key, val.ToString() ); -} - -ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, const char **out ) const { - const idKeyValue *kv = FindKey( key ); - if ( kv ) { - *out = kv->GetValue(); - return true; - } - *out = defaultString; - return false; -} - -ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, idStr &out ) const { - const idKeyValue *kv = FindKey( key ); - if ( kv ) { - out = kv->GetValue(); - return true; - } - out = defaultString; - return false; -} - -ID_INLINE const char *idDict::GetString( const char *key, const char *defaultString ) const { - const idKeyValue *kv = FindKey( key ); - if ( kv ) { - return kv->GetValue(); - } - return defaultString; -} - -ID_INLINE float idDict::GetFloat( const char *key, const char *defaultString ) const { - return atof( GetString( key, defaultString ) ); -} - -ID_INLINE int idDict::GetInt( const char *key, const char *defaultString ) const { - return atoi( GetString( key, defaultString ) ); -} - -ID_INLINE bool idDict::GetBool( const char *key, const char *defaultString ) const { - return ( atoi( GetString( key, defaultString ) ) != 0 ); -} - -ID_INLINE idVec3 idDict::GetVector( const char *key, const char *defaultString ) const { - idVec3 out; - GetVector( key, defaultString, out ); - return out; -} - -ID_INLINE idVec2 idDict::GetVec2( const char *key, const char *defaultString ) const { - idVec2 out; - GetVec2( key, defaultString, out ); - return out; -} - -ID_INLINE idVec4 idDict::GetVec4( const char *key, const char *defaultString ) const { - idVec4 out; - GetVec4( key, defaultString, out ); - return out; -} - -ID_INLINE idAngles idDict::GetAngles( const char *key, const char *defaultString ) const { - idAngles out; - GetAngles( key, defaultString, out ); - return out; -} - -ID_INLINE idMat3 idDict::GetMatrix( const char *key, const char *defaultString ) const { - idMat3 out; - GetMatrix( key, defaultString, out ); - return out; -} - -ID_INLINE int idDict::GetNumKeyVals( void ) const { - return args.Num(); -} - -ID_INLINE const idKeyValue *idDict::GetKeyVal( int index ) const { - if ( index >= 0 && index < args.Num() ) { - return &args[ index ]; - } - return NULL; -} - -#endif /* !__DICT_H__ */ diff --git a/idlib/geometry/DrawVert.cpp b/idlib/geometry/DrawVert.cpp new file mode 100644 index 000000000..fe11db5a8 --- /dev/null +++ b/idlib/geometry/DrawVert.cpp @@ -0,0 +1,35 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +============= +idDrawVert::Normalize +============= +*/ +void idDrawVert::Normalize( void ) { + normal.Normalize(); + tangents[1].Cross( normal, tangents[0] ); + tangents[1].Normalize(); + tangents[0].Cross( tangents[1], normal ); + tangents[0].Normalize(); +} diff --git a/idlib/geometry/DrawVert.h b/idlib/geometry/DrawVert.h new file mode 100644 index 000000000..436632fa1 --- /dev/null +++ b/idlib/geometry/DrawVert.h @@ -0,0 +1,109 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DRAWVERT_H__ +#define __DRAWVERT_H__ + +/* +=============================================================================== + + Draw Vertex. + +=============================================================================== +*/ + +class idDrawVert { +public: + idVec3 xyz; + idVec2 st; + idVec3 normal; + idVec3 tangents[2]; + byte color[4]; +#if 0 // was MACOS_X see comments concerning DRAWVERT_PADDED in Simd_Altivec.h + float padding; +#endif + float operator[]( const int index ) const; + float & operator[]( const int index ); + + void Clear( void ); + + void Lerp( const idDrawVert &a, const idDrawVert &b, const float f ); + void LerpAll( const idDrawVert &a, const idDrawVert &b, const float f ); + + void Normalize( void ); + // stgatilov: this normalization scales normal/tangents by common factor, so that normal becomes unit length. + void ScaleToUnitNormal( void ); + + void SetColor( dword color ); + dword GetColor( void ) const; +}; + +ID_INLINE float idDrawVert::operator[]( const int index ) const { + assert( index >= 0 && index < 5 ); + return ((float *)(&xyz))[index]; +} +ID_INLINE float &idDrawVert::operator[]( const int index ) { + assert( index >= 0 && index < 5 ); + return ((float *)(&xyz))[index]; +} + +ID_INLINE void idDrawVert::Clear( void ) { + xyz.Zero(); + st.Zero(); + normal.Zero(); + tangents[0].Zero(); + tangents[1].Zero(); + color[0] = color[1] = color[2] = color[3] = 0; +} + +ID_INLINE void idDrawVert::Lerp( const idDrawVert &a, const idDrawVert &b, const float f ) { + xyz = a.xyz + f * ( b.xyz - a.xyz ); + st = a.st + f * ( b.st - a.st ); +} + +ID_INLINE void idDrawVert::LerpAll( const idDrawVert &a, const idDrawVert &b, const float f ) { + xyz = a.xyz + f * ( b.xyz - a.xyz ); + st = a.st + f * ( b.st - a.st ); + normal = a.normal + f * ( b.normal - a.normal ); + tangents[0] = a.tangents[0] + f * ( b.tangents[0] - a.tangents[0] ); + tangents[1] = a.tangents[1] + f * ( b.tangents[1] - a.tangents[1] ); + color[0] = (byte)( a.color[0] + f * ( b.color[0] - a.color[0] ) ); + color[1] = (byte)( a.color[1] + f * ( b.color[1] - a.color[1] ) ); + color[2] = (byte)( a.color[2] + f * ( b.color[2] - a.color[2] ) ); + color[3] = (byte)( a.color[3] + f * ( b.color[3] - a.color[3] ) ); +} + +ID_INLINE void idDrawVert::SetColor( dword color ) { + *reinterpret_cast(this->color) = color; +} + +ID_INLINE dword idDrawVert::GetColor( void ) const { + return *reinterpret_cast(this->color); +} + +ID_INLINE void idDrawVert::ScaleToUnitNormal( void ) { + float invNormLen = idMath::RSqrt(normal.LengthSqr()); + if (invNormLen == 1.0f) return; + normal *= invNormLen; + tangents[0] *= invNormLen; + tangents[1] *= invNormLen; +} + + +#endif /* !__DRAWVERT_H__ */ diff --git a/idlib/geometry/JointTransform.cpp b/idlib/geometry/JointTransform.cpp new file mode 100644 index 000000000..f7e4b89de --- /dev/null +++ b/idlib/geometry/JointTransform.cpp @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +============= +idJointMat::ToJointQuat +============= +*/ +idJointQuat idJointMat::ToJointQuat( void ) const { + idJointQuat jq; + float trace; + float s; + float t; + int i; + int j; + int k; + + static int next[3] = { 1, 2, 0 }; + + trace = mat[0 * 4 + 0] + mat[1 * 4 + 1] + mat[2 * 4 + 2]; + + if ( trace > 0.0f ) { + + t = trace + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + jq.q[3] = s * t; + jq.q[0] = ( mat[1 * 4 + 2] - mat[2 * 4 + 1] ) * s; + jq.q[1] = ( mat[2 * 4 + 0] - mat[0 * 4 + 2] ) * s; + jq.q[2] = ( mat[0 * 4 + 1] - mat[1 * 4 + 0] ) * s; + + } else { + + i = 0; + if ( mat[1 * 4 + 1] > mat[0 * 4 + 0] ) { + i = 1; + } + if ( mat[2 * 4 + 2] > mat[i * 4 + i] ) { + i = 2; + } + j = next[i]; + k = next[j]; + + t = ( mat[i * 4 + i] - ( mat[j * 4 + j] + mat[k * 4 + k] ) ) + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + jq.q[i] = s * t; + jq.q[3] = ( mat[j * 4 + k] - mat[k * 4 + j] ) * s; + jq.q[j] = ( mat[i * 4 + j] + mat[j * 4 + i] ) * s; + jq.q[k] = ( mat[i * 4 + k] + mat[k * 4 + i] ) * s; + } + + jq.t[0] = mat[0 * 4 + 3]; + jq.t[1] = mat[1 * 4 + 3]; + jq.t[2] = mat[2 * 4 + 3]; + + return jq; +} diff --git a/idlib/geometry/JointTransform.h b/idlib/geometry/JointTransform.h new file mode 100644 index 000000000..b3812c1c2 --- /dev/null +++ b/idlib/geometry/JointTransform.h @@ -0,0 +1,236 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __JOINTTRANSFORM_H__ +#define __JOINTTRANSFORM_H__ + +/* +=============================================================================== + + Joint Quaternion + +=============================================================================== +*/ + +class idJointQuat { +public: + + idQuat q; + idVec3 t; +}; + + +/* +=============================================================================== + + Joint Matrix + + idMat3 m; + idVec3 t; + + m[0][0], m[1][0], m[2][0], t[0] + m[0][1], m[1][1], m[2][1], t[1] + m[0][2], m[1][2], m[2][2], t[2] + +=============================================================================== +*/ + +class idJointMat { +public: + + void SetRotation( const idMat3 &m ); + void SetTranslation( const idVec3 &t ); + + idVec3 operator*( const idVec3 &v ) const; // only rotate + idVec3 operator*( const idVec4 &v ) const; // rotate and translate + + idJointMat & operator*=( const idJointMat &a ); // transform + idJointMat & operator/=( const idJointMat &a ); // untransform + + bool Compare( const idJointMat &a ) const; // exact compare, no epsilon + bool Compare( const idJointMat &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idJointMat &a ) const; // exact compare, no epsilon + bool operator!=( const idJointMat &a ) const; // exact compare, no epsilon + + idMat3 ToMat3( void ) const; + idVec3 ToVec3( void ) const; + idJointQuat ToJointQuat( void ) const; + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + +private: + float mat[3*4]; +}; + +ID_INLINE void idJointMat::SetRotation( const idMat3 &m ) { + // NOTE: idMat3 is transposed because it is column-major + mat[0 * 4 + 0] = m[0][0]; + mat[0 * 4 + 1] = m[1][0]; + mat[0 * 4 + 2] = m[2][0]; + mat[1 * 4 + 0] = m[0][1]; + mat[1 * 4 + 1] = m[1][1]; + mat[1 * 4 + 2] = m[2][1]; + mat[2 * 4 + 0] = m[0][2]; + mat[2 * 4 + 1] = m[1][2]; + mat[2 * 4 + 2] = m[2][2]; +} + +ID_INLINE void idJointMat::SetTranslation( const idVec3 &t ) { + mat[0 * 4 + 3] = t[0]; + mat[1 * 4 + 3] = t[1]; + mat[2 * 4 + 3] = t[2]; +} + +ID_INLINE idVec3 idJointMat::operator*( const idVec3 &v ) const { + return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2], + mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2], + mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] ); +} + +ID_INLINE idVec3 idJointMat::operator*( const idVec4 &v ) const { + return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2] + mat[0 * 4 + 3] * v[3], + mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2] + mat[1 * 4 + 3] * v[3], + mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] + mat[2 * 4 + 3] * v[3] ); +} + +ID_INLINE idJointMat &idJointMat::operator*=( const idJointMat &a ) { + float dst[3]; + + dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[0 * 4 + 1] + mat[2 * 4 + 0] * a.mat[0 * 4 + 2]; + dst[1] = mat[0 * 4 + 0] * a.mat[1 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[1 * 4 + 2]; + dst[2] = mat[0 * 4 + 0] * a.mat[2 * 4 + 0] + mat[1 * 4 + 0] * a.mat[2 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 0] = dst[0]; + mat[1 * 4 + 0] = dst[1]; + mat[2 * 4 + 0] = dst[2]; + + dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[0 * 4 + 1] + mat[2 * 4 + 1] * a.mat[0 * 4 + 2]; + dst[1] = mat[0 * 4 + 1] * a.mat[1 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[1 * 4 + 2]; + dst[2] = mat[0 * 4 + 1] * a.mat[2 * 4 + 0] + mat[1 * 4 + 1] * a.mat[2 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 1] = dst[0]; + mat[1 * 4 + 1] = dst[1]; + mat[2 * 4 + 1] = dst[2]; + + dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[0 * 4 + 1] + mat[2 * 4 + 2] * a.mat[0 * 4 + 2]; + dst[1] = mat[0 * 4 + 2] * a.mat[1 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[1 * 4 + 2]; + dst[2] = mat[0 * 4 + 2] * a.mat[2 * 4 + 0] + mat[1 * 4 + 2] * a.mat[2 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 2] = dst[0]; + mat[1 * 4 + 2] = dst[1]; + mat[2 * 4 + 2] = dst[2]; + + dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[0 * 4 + 1] + mat[2 * 4 + 3] * a.mat[0 * 4 + 2]; + dst[1] = mat[0 * 4 + 3] * a.mat[1 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[1 * 4 + 2]; + dst[2] = mat[0 * 4 + 3] * a.mat[2 * 4 + 0] + mat[1 * 4 + 3] * a.mat[2 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 3] = dst[0]; + mat[1 * 4 + 3] = dst[1]; + mat[2 * 4 + 3] = dst[2]; + + mat[0 * 4 + 3] += a.mat[0 * 4 + 3]; + mat[1 * 4 + 3] += a.mat[1 * 4 + 3]; + mat[2 * 4 + 3] += a.mat[2 * 4 + 3]; + + return *this; +} + +ID_INLINE idJointMat &idJointMat::operator/=( const idJointMat &a ) { + float dst[3]; + + mat[0 * 4 + 3] -= a.mat[0 * 4 + 3]; + mat[1 * 4 + 3] -= a.mat[1 * 4 + 3]; + mat[2 * 4 + 3] -= a.mat[2 * 4 + 3]; + + dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 0] + mat[2 * 4 + 0] * a.mat[2 * 4 + 0]; + dst[1] = mat[0 * 4 + 0] * a.mat[0 * 4 + 1] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 1]; + dst[2] = mat[0 * 4 + 0] * a.mat[0 * 4 + 2] + mat[1 * 4 + 0] * a.mat[1 * 4 + 2] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 0] = dst[0]; + mat[1 * 4 + 0] = dst[1]; + mat[2 * 4 + 0] = dst[2]; + + dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 0] + mat[2 * 4 + 1] * a.mat[2 * 4 + 0]; + dst[1] = mat[0 * 4 + 1] * a.mat[0 * 4 + 1] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 1]; + dst[2] = mat[0 * 4 + 1] * a.mat[0 * 4 + 2] + mat[1 * 4 + 1] * a.mat[1 * 4 + 2] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 1] = dst[0]; + mat[1 * 4 + 1] = dst[1]; + mat[2 * 4 + 1] = dst[2]; + + dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 0] + mat[2 * 4 + 2] * a.mat[2 * 4 + 0]; + dst[1] = mat[0 * 4 + 2] * a.mat[0 * 4 + 1] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 1]; + dst[2] = mat[0 * 4 + 2] * a.mat[0 * 4 + 2] + mat[1 * 4 + 2] * a.mat[1 * 4 + 2] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 2] = dst[0]; + mat[1 * 4 + 2] = dst[1]; + mat[2 * 4 + 2] = dst[2]; + + dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 0] + mat[2 * 4 + 3] * a.mat[2 * 4 + 0]; + dst[1] = mat[0 * 4 + 3] * a.mat[0 * 4 + 1] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 1]; + dst[2] = mat[0 * 4 + 3] * a.mat[0 * 4 + 2] + mat[1 * 4 + 3] * a.mat[1 * 4 + 2] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; + mat[0 * 4 + 3] = dst[0]; + mat[1 * 4 + 3] = dst[1]; + mat[2 * 4 + 3] = dst[2]; + + return *this; +} + +ID_INLINE bool idJointMat::Compare( const idJointMat &a ) const { + int i; + + for ( i = 0; i < 12; i++ ) { + if ( mat[i] != a.mat[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idJointMat::Compare( const idJointMat &a, const float epsilon ) const { + int i; + + for ( i = 0; i < 12; i++ ) { + if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idJointMat::operator==( const idJointMat &a ) const { + return Compare( a ); +} + +ID_INLINE bool idJointMat::operator!=( const idJointMat &a ) const { + return !Compare( a ); +} + +ID_INLINE idMat3 idJointMat::ToMat3( void ) const { + return idMat3( mat[0 * 4 + 0], mat[1 * 4 + 0], mat[2 * 4 + 0], + mat[0 * 4 + 1], mat[1 * 4 + 1], mat[2 * 4 + 1], + mat[0 * 4 + 2], mat[1 * 4 + 2], mat[2 * 4 + 2] ); +} + +ID_INLINE idVec3 idJointMat::ToVec3( void ) const { + return idVec3( mat[0 * 4 + 3], mat[1 * 4 + 3], mat[2 * 4 + 3] ); +} + +ID_INLINE const float *idJointMat::ToFloatPtr( void ) const { + return mat; +} + +ID_INLINE float *idJointMat::ToFloatPtr( void ) { + return mat; +} + +#endif /* !__JOINTTRANSFORM_H__ */ diff --git a/idlib/geometry/Surface.cpp b/idlib/geometry/Surface.cpp new file mode 100644 index 000000000..3a84c8ea0 --- /dev/null +++ b/idlib/geometry/Surface.cpp @@ -0,0 +1,921 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +================= +UpdateVertexIndex +================= +*/ +ID_INLINE int UpdateVertexIndex( int vertexIndexNum[2], int *vertexRemap, int *vertexCopyIndex, int vertNum ) { + int s = INTSIGNBITSET( vertexRemap[vertNum] ); + vertexIndexNum[0] = vertexRemap[vertNum]; + vertexRemap[vertNum] = vertexIndexNum[s]; + vertexIndexNum[1] += s; + vertexCopyIndex[vertexRemap[vertNum]] = vertNum; + return vertexRemap[vertNum]; +} + +/* +================= +idSurface::Split +================= +*/ +int idSurface::Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges, int *backOnPlaneEdges ) const { + float * dists; + float f; + byte * sides; + int counts[3]; + int * edgeSplitVertex; + int numEdgeSplitVertexes; + int * vertexRemap[2]; + int vertexIndexNum[2][2]; + int * vertexCopyIndex[2]; + int * indexPtr[2]; + int indexNum[2]; + int * index; + int * onPlaneEdges[2]; + int numOnPlaneEdges[2]; + int maxOnPlaneEdges; + int i; + idSurface * surface[2]; + idDrawVert v; + + dists = (float *) _alloca( verts.Num() * sizeof( float ) ); + sides = (byte *) _alloca( verts.Num() * sizeof( byte ) ); + + counts[0] = counts[1] = counts[2] = 0; + + // determine side for each vertex + for ( i = 0; i < verts.Num(); i++ ) { + dists[i] = f = plane.Distance( verts[i].xyz ); + if ( f > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( f < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + + *front = *back = NULL; + + // if coplanar, put on the front side if the normals match + if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + + f = ( verts[indexes[1]].xyz - verts[indexes[0]].xyz ).Cross( verts[indexes[0]].xyz - verts[indexes[2]].xyz ) * plane.Normal(); + if ( FLOATSIGNBITSET( f ) ) { + *back = new idSurface( *this ); + return SIDE_BACK; + } else { + *front = new idSurface( *this ); + return SIDE_FRONT; + } + } + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + *back = new idSurface( *this ); + return SIDE_BACK; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + *front = new idSurface( *this ); + return SIDE_FRONT; + } + + // allocate front and back surface + *front = surface[0] = new idSurface(); + *back = surface[1] = new idSurface(); + + edgeSplitVertex = (int *) _alloca( edges.Num() * sizeof( int ) ); + numEdgeSplitVertexes = 0; + + maxOnPlaneEdges = 4 * counts[SIDE_ON]; + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + // split edges + for ( i = 0; i < edges.Num(); i++ ) { + int v0 = edges[i].verts[0]; + int v1 = edges[i].verts[1]; + int sidesOr = ( sides[v0] | sides[v1] ); + + // if both vertexes are on the same side or one is on the clipping plane + if ( !( sides[v0] ^ sides[v1] ) || ( sidesOr & SIDE_ON ) ) { + edgeSplitVertex[i] = -1; + counts[sidesOr & SIDE_BACK]++; + counts[SIDE_ON] += ( sidesOr & SIDE_ON ) >> 1; + } else { + f = dists[v0] / ( dists[v0] - dists[v1] ); + v.LerpAll( verts[v0], verts[v1], f ); + edgeSplitVertex[i] = numEdgeSplitVertexes++; + surface[0]->verts.Append( v ); + surface[1]->verts.Append( v ); + } + } + + // each edge is shared by at most two triangles, as such there can never be more indexes than twice the number of edges + surface[0]->indexes.Resize( ( ( counts[SIDE_FRONT] + counts[SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) ); + surface[1]->indexes.Resize( ( ( counts[SIDE_BACK] + counts[SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) ); + + // allocate indexes to construct the triangle indexes for the front and back surface + vertexRemap[0] = (int *) _alloca( verts.Num() * sizeof( int ) ); + memset( vertexRemap[0], -1, verts.Num() * sizeof( int ) ); + vertexRemap[1] = (int *) _alloca( verts.Num() * sizeof( int ) ); + memset( vertexRemap[1], -1, verts.Num() * sizeof( int ) ); + + vertexCopyIndex[0] = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); + vertexCopyIndex[1] = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); + + vertexIndexNum[0][0] = vertexIndexNum[1][0] = 0; + vertexIndexNum[0][1] = vertexIndexNum[1][1] = numEdgeSplitVertexes; + + indexPtr[0] = surface[0]->indexes.Ptr(); + indexPtr[1] = surface[1]->indexes.Ptr(); + indexNum[0] = surface[0]->indexes.Num(); + indexNum[1] = surface[1]->indexes.Num(); + + maxOnPlaneEdges += 4 * numEdgeSplitVertexes; + // allocate one more in case no triangles are actually split which may happen for a disconnected surface + onPlaneEdges[0] = (int *) _alloca( ( maxOnPlaneEdges + 1 ) * sizeof( int ) ); + onPlaneEdges[1] = (int *) _alloca( ( maxOnPlaneEdges + 1 ) * sizeof( int ) ); + numOnPlaneEdges[0] = numOnPlaneEdges[1] = 0; + + // split surface triangles + for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { + int e0, e1, e2, v0, v1, v2, s, n; + + e0 = abs( edgeIndexes[i+0] ); + e1 = abs( edgeIndexes[i+1] ); + e2 = abs( edgeIndexes[i+2] ); + + v0 = indexes[i+0]; + v1 = indexes[i+1]; + v2 = indexes[i+2]; + + switch( ( INTSIGNBITSET( edgeSplitVertex[e0] ) | ( INTSIGNBITSET( edgeSplitVertex[e1] ) << 1 ) | ( INTSIGNBITSET( edgeSplitVertex[e2] ) << 2 ) ) ^ 7 ) { + case 0: { // no edges split + if ( ( sides[v0] & sides[v1] & sides[v2] ) & SIDE_ON ) { + // coplanar + f = ( verts[v1].xyz - verts[v0].xyz ).Cross( verts[v0].xyz - verts[v2].xyz ) * plane.Normal(); + s = FLOATSIGNBITSET( f ); + } else { + s = ( sides[v0] | sides[v1] | sides[v2] ) & SIDE_BACK; + } + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]] = n; + numOnPlaneEdges[s] += ( sides[v0] & sides[v1] ) >> 1; + onPlaneEdges[s][numOnPlaneEdges[s]] = n+1; + numOnPlaneEdges[s] += ( sides[v1] & sides[v2] ) >> 1; + onPlaneEdges[s][numOnPlaneEdges[s]] = n+2; + numOnPlaneEdges[s] += ( sides[v2] & sides[v0] ) >> 1; + index = indexPtr[s]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + indexNum[s] = n; + break; + } + case 1: { // first edge split + s = sides[v0] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e0]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + index[n++] = edgeSplitVertex[e0]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + indexNum[s] = n; + break; + } + case 2: { // second edge split + s = sides[v1] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e1]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + index[n++] = edgeSplitVertex[e1]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + indexNum[s] = n; + break; + } + case 3: { // first and second edge split + s = sides[v1] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e1]; + index[n++] = edgeSplitVertex[e0]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e0]; + index[n++] = edgeSplitVertex[e1]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + index[n++] = edgeSplitVertex[e1]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + indexNum[s] = n; + break; + } + case 4: { // third edge split + s = sides[v2] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e2]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = edgeSplitVertex[e2]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + indexNum[s] = n; + break; + } + case 5: { // first and third edge split + s = sides[v0] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e0]; + index[n++] = edgeSplitVertex[e2]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e2]; + index[n++] = edgeSplitVertex[e0]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + index[n++] = edgeSplitVertex[e2]; + indexNum[s] = n; + break; + } + case 6: { // second and third edge split + s = sides[v2] & SIDE_BACK; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e2]; + index[n++] = edgeSplitVertex[e1]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); + indexNum[s] = n; + s ^= 1; + n = indexNum[s]; + onPlaneEdges[s][numOnPlaneEdges[s]++] = n; + index = indexPtr[s]; + index[n++] = edgeSplitVertex[e1]; + index[n++] = edgeSplitVertex[e2]; + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); + index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); + index[n++] = edgeSplitVertex[e2]; + indexNum[s] = n; + break; + } + } + } + + surface[0]->indexes.SetNum( indexNum[0], false ); + surface[1]->indexes.SetNum( indexNum[1], false ); + + // copy vertexes + surface[0]->verts.SetNum( vertexIndexNum[0][1], false ); + index = vertexCopyIndex[0]; + for ( i = numEdgeSplitVertexes; i < surface[0]->verts.Num(); i++ ) { + surface[0]->verts[i] = verts[index[i]]; + } + surface[1]->verts.SetNum( vertexIndexNum[1][1], false ); + index = vertexCopyIndex[1]; + for ( i = numEdgeSplitVertexes; i < surface[1]->verts.Num(); i++ ) { + surface[1]->verts[i] = verts[index[i]]; + } + + // generate edge indexes + surface[0]->GenerateEdgeIndexes(); + surface[1]->GenerateEdgeIndexes(); + + if ( frontOnPlaneEdges ) { + memcpy( frontOnPlaneEdges, onPlaneEdges[0], numOnPlaneEdges[0] * sizeof( int ) ); + frontOnPlaneEdges[numOnPlaneEdges[0]] = -1; + } + + if ( backOnPlaneEdges ) { + memcpy( backOnPlaneEdges, onPlaneEdges[1], numOnPlaneEdges[1] * sizeof( int ) ); + backOnPlaneEdges[numOnPlaneEdges[1]] = -1; + } + + return SIDE_CROSS; +} + +/* +================= +idSurface::ClipInPlace +================= +*/ +bool idSurface::ClipInPlace( const idPlane &plane, const float epsilon, const bool keepOn ) { + float * dists; + float f; + byte * sides; + int counts[3]; + int i; + int * edgeSplitVertex; + int * vertexRemap; + int vertexIndexNum[2]; + int * vertexCopyIndex; + int * indexPtr; + int indexNum; + int numEdgeSplitVertexes; + idDrawVert v; + idList newVerts; + idList newIndexes; + + dists = (float *) _alloca( verts.Num() * sizeof( float ) ); + sides = (byte *) _alloca( verts.Num() * sizeof( byte ) ); + + counts[0] = counts[1] = counts[2] = 0; + + // determine side for each vertex + for ( i = 0; i < verts.Num(); i++ ) { + dists[i] = f = plane.Distance( verts[i].xyz ); + if ( f > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( f < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + + // if coplanar, put on the front side if the normals match + if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + + f = ( verts[indexes[1]].xyz - verts[indexes[0]].xyz ).Cross( verts[indexes[0]].xyz - verts[indexes[2]].xyz ) * plane.Normal(); + if ( FLOATSIGNBITSET( f ) ) { + Clear(); + return false; + } else { + return true; + } + } + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + Clear(); + return false; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + return true; + } + + edgeSplitVertex = (int *) _alloca( edges.Num() * sizeof( int ) ); + numEdgeSplitVertexes = 0; + + counts[SIDE_FRONT] = counts[SIDE_BACK] = 0; + + // split edges + for ( i = 0; i < edges.Num(); i++ ) { + int v0 = edges[i].verts[0]; + int v1 = edges[i].verts[1]; + + // if both vertexes are on the same side or one is on the clipping plane + if ( !( sides[v0] ^ sides[v1] ) || ( ( sides[v0] | sides[v1] ) & SIDE_ON ) ) { + edgeSplitVertex[i] = -1; + counts[(sides[v0]|sides[v1]) & SIDE_BACK]++; + } else { + f = dists[v0] / ( dists[v0] - dists[v1] ); + v.LerpAll( verts[v0], verts[v1], f ); + edgeSplitVertex[i] = numEdgeSplitVertexes++; + newVerts.Append( v ); + } + } + + // each edge is shared by at most two triangles, as such there can never be + // more indexes than twice the number of edges + newIndexes.Resize( ( counts[SIDE_FRONT] << 1 ) + ( numEdgeSplitVertexes << 2 ) ); + + // allocate indexes to construct the triangle indexes for the front and back surface + vertexRemap = (int *) _alloca( verts.Num() * sizeof( int ) ); + memset( vertexRemap, -1, verts.Num() * sizeof( int ) ); + + vertexCopyIndex = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); + + vertexIndexNum[0] = 0; + vertexIndexNum[1] = numEdgeSplitVertexes; + + indexPtr = newIndexes.Ptr(); + indexNum = newIndexes.Num(); + + // split surface triangles + for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { + int e0, e1, e2, v0, v1, v2; + + e0 = abs( edgeIndexes[i+0] ); + e1 = abs( edgeIndexes[i+1] ); + e2 = abs( edgeIndexes[i+2] ); + + v0 = indexes[i+0]; + v1 = indexes[i+1]; + v2 = indexes[i+2]; + + switch( ( INTSIGNBITSET( edgeSplitVertex[e0] ) | ( INTSIGNBITSET( edgeSplitVertex[e1] ) << 1 ) | ( INTSIGNBITSET( edgeSplitVertex[e2] ) << 2 ) ) ^ 7 ) { + case 0: { // no edges split + if ( ( sides[v0] | sides[v1] | sides[v2] ) & SIDE_BACK ) { + break; + } + if ( ( sides[v0] & sides[v1] & sides[v2] ) & SIDE_ON ) { + // coplanar + if ( !keepOn ) { + break; + } + f = ( verts[v1].xyz - verts[v0].xyz ).Cross( verts[v0].xyz - verts[v2].xyz ) * plane.Normal(); + if ( FLOATSIGNBITSET( f ) ) { + break; + } + } + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + break; + } + case 1: { // first edge split + if ( !( sides[v0] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = edgeSplitVertex[e0]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + } else { + indexPtr[indexNum++] = edgeSplitVertex[e0]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + } + break; + } + case 2: { // second edge split + if ( !( sides[v1] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + } else { + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + } + break; + } + case 3: { // first and second edge split + if ( !( sides[v1] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = edgeSplitVertex[e0]; + } else { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = edgeSplitVertex[e0]; + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + } + break; + } + case 4: { // third edge split + if ( !( sides[v2] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + indexPtr[indexNum++] = edgeSplitVertex[e2]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + } else { + indexPtr[indexNum++] = edgeSplitVertex[e2]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + } + break; + } + case 5: { // first and third edge split + if ( !( sides[v0] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = edgeSplitVertex[e0]; + indexPtr[indexNum++] = edgeSplitVertex[e2]; + } else { + indexPtr[indexNum++] = edgeSplitVertex[e0]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = edgeSplitVertex[e2]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + indexPtr[indexNum++] = edgeSplitVertex[e2]; + } + break; + } + case 6: { // second and third edge split + if ( !( sides[v2] & SIDE_BACK ) ) { + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); + indexPtr[indexNum++] = edgeSplitVertex[e2]; + indexPtr[indexNum++] = edgeSplitVertex[e1]; + } else { + indexPtr[indexNum++] = edgeSplitVertex[e2]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = edgeSplitVertex[e1]; + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); + indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); + indexPtr[indexNum++] = edgeSplitVertex[e2]; + } + break; + } + } + } + + newIndexes.SetNum( indexNum, false ); + + // copy vertexes + newVerts.SetNum( vertexIndexNum[1], false ); + for ( i = numEdgeSplitVertexes; i < newVerts.Num(); i++ ) { + newVerts[i] = verts[vertexCopyIndex[i]]; + } + + // copy back to this surface + indexes = newIndexes; + verts = newVerts; + + GenerateEdgeIndexes(); + + return true; +} + +/* +============= +idSurface::IsConnected +============= +*/ +bool idSurface::IsConnected( void ) const { + int i, j, numIslands, numTris; + int queueStart, queueEnd; + int *queue, *islandNum; + int curTri, nextTri, edgeNum; + const int *index; + + numIslands = 0; + numTris = indexes.Num() / 3; + islandNum = (int *) _alloca16( numTris * sizeof( int ) ); + memset( islandNum, -1, numTris * sizeof( int ) ); + queue = (int *) _alloca16( numTris * sizeof( int ) ); + + for ( i = 0; i < numTris; i++ ) { + + if ( islandNum[i] != -1 ) { + continue; + } + + queueStart = 0; + queueEnd = 1; + queue[0] = i; + islandNum[i] = numIslands; + + for ( curTri = queue[queueStart]; queueStart < queueEnd; curTri = queue[++queueStart] ) { + + index = &edgeIndexes[curTri * 3]; + + for ( j = 0; j < 3; j++ ) { + + edgeNum = index[j]; + nextTri = edges[abs(edgeNum)].tris[INTSIGNBITNOTSET(edgeNum)]; + + if ( nextTri == -1 ) { + continue; + } + + nextTri /= 3; + + if ( islandNum[nextTri] != -1 ) { + continue; + } + + queue[queueEnd++] = nextTri; + islandNum[nextTri] = numIslands; + } + } + numIslands++; + } + + return ( numIslands == 1 ); +} + +/* +================= +idSurface::IsClosed +================= +*/ +bool idSurface::IsClosed( void ) const { + for ( int i = 0; i < edges.Num(); i++ ) { + if ( edges[i].tris[0] < 0 || edges[i].tris[1] < 0 ) { + return false; + } + } + return true; +} + +/* +============= +idSurface::IsPolytope +============= +*/ +bool idSurface::IsPolytope( const float epsilon ) const { + int i, j; + idPlane plane; + + if ( !IsClosed() ) { + return false; + } + + for ( i = 0; i < indexes.Num(); i += 3 ) { + plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); + + for ( j = 0; j < verts.Num(); j++ ) { + if ( plane.Side( verts[j].xyz, epsilon ) == SIDE_FRONT ) { + return false; + } + } + } + return true; +} + +/* +============= +idSurface::PlaneDistance +============= +*/ +float idSurface::PlaneDistance( const idPlane &plane ) const { + int i; + float d, min, max; + + min = idMath::INFINITY; + max = -min; + for ( i = 0; i < verts.Num(); i++ ) { + d = plane.Distance( verts[i].xyz ); + if ( d < min ) { + min = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + if ( d > max ) { + max = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + } + if ( FLOATSIGNBITNOTSET( min ) ) { + return min; + } + if ( FLOATSIGNBITSET( max ) ) { + return max; + } + return 0.0f; +} + +/* +============= +idSurface::PlaneSide +============= +*/ +int idSurface::PlaneSide( const idPlane &plane, const float epsilon ) const { + bool front, back; + int i; + float d; + + front = false; + back = false; + for ( i = 0; i < verts.Num(); i++ ) { + d = plane.Distance( verts[i].xyz ); + if ( d < -epsilon ) { + if ( front ) { + return SIDE_CROSS; + } + back = true; + continue; + } + else if ( d > epsilon ) { + if ( back ) { + return SIDE_CROSS; + } + front = true; + continue; + } + } + + if ( back ) { + return SIDE_BACK; + } + if ( front ) { + return SIDE_FRONT; + } + return SIDE_ON; +} + +/* +================= +idSurface::LineIntersection +================= +*/ +bool idSurface::LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull ) const { + float scale; + + RayIntersection( start, end - start, scale, false ); + return ( scale >= 0.0f && scale <= 1.0f ); +} + +/* +================= +idSurface::RayIntersection +================= +*/ +bool idSurface::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull ) const { + int i, i0, i1, i2, s0, s1, s2; + float d, s; + byte *sidedness; + idPluecker rayPl, pl; + idPlane plane; + + sidedness = (byte *)_alloca( edges.Num() * sizeof(byte) ); + scale = idMath::INFINITY; + + rayPl.FromRay( start, dir ); + + // ray sidedness for edges + for ( i = 0; i < edges.Num(); i++ ) { + pl.FromLine( verts[ edges[i].verts[1] ].xyz, verts[ edges[i].verts[0] ].xyz ); + d = pl.PermutedInnerProduct( rayPl ); + sidedness[ i ] = FLOATSIGNBITSET( d ); + } + + // test triangles + for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { + i0 = edgeIndexes[i+0]; + i1 = edgeIndexes[i+1]; + i2 = edgeIndexes[i+2]; + s0 = sidedness[abs(i0)] ^ INTSIGNBITSET( i0 ); + s1 = sidedness[abs(i1)] ^ INTSIGNBITSET( i1 ); + s2 = sidedness[abs(i2)] ^ INTSIGNBITSET( i2 ); + + if ( s0 & s1 & s2 ) { + plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); + plane.RayIntersection( start, dir, s ); + if ( idMath::Fabs( s ) < idMath::Fabs( scale ) ) { + scale = s; + } + } else if ( !backFaceCull && !(s0 | s1 | s2) ) { + plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); + plane.RayIntersection( start, dir, s ); + if ( idMath::Fabs( s ) < idMath::Fabs( scale ) ) { + scale = s; + } + } + } + + if ( idMath::Fabs( scale ) < idMath::INFINITY ) { + return true; + } + return false; +} + +/* +================= +idSurface::GenerateEdgeIndexes + + Assumes each edge is shared by at most two triangles. +================= +*/ +void idSurface::GenerateEdgeIndexes( void ) { + int i, j, i0, i1, i2, s, v0, v1, edgeNum; + int *index, *vertexEdges, *edgeChain; + surfaceEdge_t e[3]; + + vertexEdges = (int *) _alloca16( verts.Num() * sizeof( int ) ); + memset( vertexEdges, -1, verts.Num() * sizeof( int ) ); + edgeChain = (int *) _alloca16( indexes.Num() * sizeof( int ) ); + + edgeIndexes.SetNum( indexes.Num(), true ); + + edges.Clear(); + + // the first edge is a dummy + e[0].verts[0] = e[0].verts[1] = e[0].tris[0] = e[0].tris[1] = 0; + edges.Append( e[0] ); + + for ( i = 0; i < indexes.Num(); i += 3 ) { + index = indexes.Ptr() + i; + // vertex numbers + i0 = index[0]; + i1 = index[1]; + i2 = index[2]; + // setup edges each with smallest vertex number first + s = INTSIGNBITSET(i1 - i0); + e[0].verts[0] = index[s]; + e[0].verts[1] = index[s^1]; + s = INTSIGNBITSET(i2 - i1) + 1; + e[1].verts[0] = index[s]; + e[1].verts[1] = index[s^3]; + s = INTSIGNBITSET(i2 - i0) << 1; + e[2].verts[0] = index[s]; + e[2].verts[1] = index[s^2]; + // get edges + for ( j = 0; j < 3; j++ ) { + v0 = e[j].verts[0]; + v1 = e[j].verts[1]; + for ( edgeNum = vertexEdges[v0]; edgeNum >= 0; edgeNum = edgeChain[edgeNum] ) { + if ( edges[edgeNum].verts[1] == v1 ) { + break; + } + } + // if the edge does not yet exist + if ( edgeNum < 0 ) { + e[j].tris[0] = e[j].tris[1] = -1; + edgeNum = edges.Append( e[j] ); + edgeChain[edgeNum] = vertexEdges[v0]; + vertexEdges[v0] = edgeNum; + } + // update edge index and edge tri references + if ( index[j] == v0 ) { + assert( edges[edgeNum].tris[0] == -1 ); // edge may not be shared by more than two triangles + edges[edgeNum].tris[0] = i; + edgeIndexes[i+j] = edgeNum; + } else { + assert( edges[edgeNum].tris[1] == -1 ); // edge may not be shared by more than two triangles + edges[edgeNum].tris[1] = i; + edgeIndexes[i+j] = -edgeNum; + } + } + } +} + +/* +================= +idSurface::FindEdge +================= +*/ +int idSurface::FindEdge( int v1, int v2 ) const { + int i, firstVert, secondVert; + + if ( v1 < v2 ) { + firstVert = v1; + secondVert = v2; + } else { + firstVert = v2; + secondVert = v1; + } + for ( i = 1; i < edges.Num(); i++ ) { + if ( edges[i].verts[0] == firstVert ) { + if ( edges[i].verts[1] == secondVert ) { + break; + } + } + } + if ( i < edges.Num() ) { + return v1 < v2 ? i : -i; + } + return 0; +} diff --git a/idlib/geometry/Surface.h b/idlib/geometry/Surface.h new file mode 100644 index 000000000..cafb8475a --- /dev/null +++ b/idlib/geometry/Surface.h @@ -0,0 +1,224 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SURFACE_H__ +#define __SURFACE_H__ + +/* +=============================================================================== + + Surface base class. + + A surface is tesselated to a triangle mesh with each edge shared by + at most two triangles. + +=============================================================================== +*/ + +typedef struct surfaceEdge_s { + int verts[2]; // edge vertices always with ( verts[0] < verts[1] ) + int tris[2]; // edge triangles +} surfaceEdge_t; + + +class idSurface { +public: + idSurface( void ); + explicit idSurface( const idSurface &surf ); + explicit idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + ~idSurface( void ); + + const idDrawVert & operator[]( const int index ) const; + idDrawVert & operator[]( const int index ); + idSurface & operator+=( const idSurface &surf ); + + int GetNumIndexes( void ) const { return indexes.Num(); } + const int * GetIndexes( void ) const { return indexes.Ptr(); } + int GetNumVertices( void ) const { return verts.Num(); } + const idDrawVert * GetVertices( void ) const { return verts.Ptr(); } + const int * GetEdgeIndexes( void ) const { return edgeIndexes.Ptr(); } + const surfaceEdge_t * GetEdges( void ) const { return edges.Ptr(); } + + void Clear( void ); + void SwapTriangles( idSurface &surf ); + void TranslateSelf( const idVec3 &translation ); + void RotateSelf( const idMat3 &rotation ); + + // splits the surface into a front and back surface, the surface itself stays unchanged + // frontOnPlaneEdges and backOnPlaneEdges optionally store the indexes to the edges that lay on the split plane + // returns a SIDE_? + int Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges = NULL, int *backOnPlaneEdges = NULL ) const; + // cuts off the part at the back side of the plane, returns true if some part was at the front + // if there is nothing at the front the number of points is set to zero + bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); + + // returns true if each triangle can be reached from any other triangle by a traversal + bool IsConnected( void ) const; + // returns true if the surface is closed + bool IsClosed( void ) const; + // returns true if the surface is a convex hull + bool IsPolytope( const float epsilon = 0.1f ) const; + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + // returns true if the line intersects one of the surface triangles + bool LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const; + // intersection point is start + dir * scale + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const; + +protected: + idList verts; // vertices + idList indexes; // 3 references to vertices for each triangle + idList edges; // edges + idList edgeIndexes; // 3 references to edges for each triangle, may be negative for reversed edge + +protected: + void GenerateEdgeIndexes( void ); + int FindEdge( int v1, int v2 ) const; +}; + +/* +==================== +idSurface::idSurface +==================== +*/ +ID_INLINE idSurface::idSurface( void ) { +} + +/* +================= +idSurface::idSurface +================= +*/ +ID_INLINE idSurface::idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + assert( verts != NULL && indexes != NULL && numVerts > 0 && numIndexes > 0 ); + this->verts.SetNum( numVerts ); + memcpy( this->verts.Ptr(), verts, numVerts * sizeof( verts[0] ) ); + this->indexes.SetNum( numIndexes ); + memcpy( this->indexes.Ptr(), indexes, numIndexes * sizeof( indexes[0] ) ); + GenerateEdgeIndexes(); +} + +/* +==================== +idSurface::idSurface +==================== +*/ +ID_INLINE idSurface::idSurface( const idSurface &surf ) { + this->verts = surf.verts; + this->indexes = surf.indexes; + this->edges = surf.edges; + this->edgeIndexes = surf.edgeIndexes; +} + +/* +==================== +idSurface::~idSurface +==================== +*/ +ID_INLINE idSurface::~idSurface( void ) { +} + +/* +================= +idSurface::operator[] +================= +*/ +ID_INLINE const idDrawVert &idSurface::operator[]( const int index ) const { + return verts[ index ]; +}; + +/* +================= +idSurface::operator[] +================= +*/ +ID_INLINE idDrawVert &idSurface::operator[]( const int index ) { + return verts[ index ]; +}; + +/* +================= +idSurface::operator+= +================= +*/ +ID_INLINE idSurface &idSurface::operator+=( const idSurface &surf ) { + int i, m, n; + n = verts.Num(); + m = indexes.Num(); + verts.Append( surf.verts ); // merge verts where possible ? + indexes.Append( surf.indexes ); + for ( i = m; i < indexes.Num(); i++ ) { + indexes[i] += n; + } + GenerateEdgeIndexes(); + return *this; +} + +/* +================= +idSurface::Clear +================= +*/ +ID_INLINE void idSurface::Clear( void ) { + verts.Clear(); + indexes.Clear(); + edges.Clear(); + edgeIndexes.Clear(); +} + +/* +================= +idSurface::SwapTriangles +================= +*/ +ID_INLINE void idSurface::SwapTriangles( idSurface &surf ) { + verts.Swap( surf.verts ); + indexes.Swap( surf.indexes ); + edges.Swap( surf.edges ); + edgeIndexes.Swap( surf.edgeIndexes ); +} + +/* +================= +idSurface::TranslateSelf +================= +*/ +ID_INLINE void idSurface::TranslateSelf( const idVec3 &translation ) { + for ( int i = 0; i < verts.Num(); i++ ) { + verts[i].xyz += translation; + } +} + +/* +================= +idSurface::RotateSelf +================= +*/ +ID_INLINE void idSurface::RotateSelf( const idMat3 &rotation ) { + for ( int i = 0; i < verts.Num(); i++ ) { + verts[i].xyz *= rotation; + verts[i].normal *= rotation; + verts[i].tangents[0] *= rotation; + verts[i].tangents[1] *= rotation; + } +} + +#endif /* !__SURFACE_H__ */ diff --git a/idlib/geometry/Surface_Patch.cpp b/idlib/geometry/Surface_Patch.cpp new file mode 100644 index 000000000..326d2660d --- /dev/null +++ b/idlib/geometry/Surface_Patch.cpp @@ -0,0 +1,682 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +================= +idSurface_Patch::SetSize +================= +*/ +void idSurface_Patch::SetSize( int patchWidth, int patchHeight ) { + if ( patchWidth < 1 || patchWidth > maxWidth ) { + idLib::common->FatalError("idSurface_Patch::SetSize: invalid patchWidth"); + } + if ( patchHeight < 1 || patchHeight > maxHeight ) { + idLib::common->FatalError("idSurface_Patch::SetSize: invalid patchHeight"); + } + width = patchWidth; + height = patchHeight; + verts.SetNum( width * height, false ); +} + +/* +================= +idSurface_Patch::PutOnCurve + +Expects an expanded patch. +================= +*/ +void idSurface_Patch::PutOnCurve( void ) { + int i, j; + idDrawVert prev, next; + + assert( expanded == true ); + // put all the approximating points on the curve + for ( i = 0; i < width; i++ ) { + for ( j = 1; j < height; j += 2 ) { + LerpVert( verts[j*maxWidth+i], verts[(j+1)*maxWidth+i], prev ); + LerpVert( verts[j*maxWidth+i], verts[(j-1)*maxWidth+i], next ); + LerpVert( prev, next, verts[j*maxWidth+i] ); + } + } + + for ( j = 0; j < height; j++ ) { + for ( i = 1; i < width; i += 2 ) { + LerpVert( verts[j*maxWidth+i], verts[j*maxWidth+i+1], prev ); + LerpVert( verts[j*maxWidth+i], verts[j*maxWidth+i-1], next ); + LerpVert( prev, next, verts[j*maxWidth+i] ); + } + } +} + +/* +================ +idSurface_Patch::ProjectPointOntoVector +================ +*/ +void idSurface_Patch::ProjectPointOntoVector( const idVec3 &point, const idVec3 &vStart, const idVec3 &vEnd, idVec3 &vProj ) { + idVec3 pVec, vec; + + pVec = point - vStart; + vec = vEnd - vStart; + vec.Normalize(); + // project onto the directional vector for this segment + vProj = vStart + (pVec * vec) * vec; +} + +/* +================ +idSurface_Patch::RemoveLinearColumnsRows + +Expects an expanded patch. +================ +*/ +void idSurface_Patch::RemoveLinearColumnsRows( void ) { + int i, j, k; + float len, maxLength; + idVec3 proj, dir; + + assert( expanded == true ); + for ( j = 1; j < width - 1; j++ ) { + maxLength = 0; + for ( i = 0; i < height; i++ ) { + idSurface_Patch::ProjectPointOntoVector( verts[i*maxWidth + j].xyz, + verts[i*maxWidth + j-1].xyz, verts[i*maxWidth + j+1].xyz, proj); + dir = verts[i*maxWidth + j].xyz - proj; + len = dir.LengthSqr(); + if ( len > maxLength ) { + maxLength = len; + } + } + if ( maxLength < Square( 0.2f ) ) { + width--; + for ( i = 0; i < height; i++ ) { + for ( k = j; k < width; k++ ) { + verts[i*maxWidth + k] = verts[i*maxWidth + k+1]; + } + } + j--; + } + } + for ( j = 1; j < height - 1; j++ ) { + maxLength = 0; + for ( i = 0; i < width; i++ ) { + idSurface_Patch::ProjectPointOntoVector( verts[j*maxWidth + i].xyz, + verts[(j-1)*maxWidth + i].xyz, verts[(j+1)*maxWidth + i].xyz, proj); + dir = verts[j*maxWidth + i].xyz - proj; + len = dir.LengthSqr(); + if ( len > maxLength ) { + maxLength = len; + } + } + if ( maxLength < Square( 0.2f ) ) { + height--; + for ( i = 0; i < width; i++ ) { + for ( k = j; k < height; k++ ) { + verts[k*maxWidth + i] = verts[(k+1)*maxWidth + i]; + } + } + j--; + } + } +} + +/* +================ +idSurface_Patch::ResizeExpanded +================ +*/ +void idSurface_Patch::ResizeExpanded( int newHeight, int newWidth ) { + int i, j; + + assert( expanded == true ); + if ( newHeight <= maxHeight && newWidth <= maxWidth ) { + return; + } + if ( newHeight * newWidth > maxHeight * maxWidth ) { + verts.SetNum( newHeight * newWidth ); + } + // space out verts for new height and width + for ( j = maxHeight-1; j >= 0; j-- ) { + for ( i = maxWidth-1; i >= 0; i-- ) { + verts[j*newWidth + i] = verts[j*maxWidth + i]; + } + } + maxHeight = newHeight; + maxWidth = newWidth; +} + +/* +================ +idSurface_Patch::Collapse +================ +*/ +void idSurface_Patch::Collapse( void ) { + int i, j; + + if ( !expanded ) { + idLib::common->FatalError("idSurface_Patch::Collapse: patch not expanded"); + } + expanded = false; + if ( width != maxWidth ) { + for ( j = 0; j < height; j++ ) { + for ( i = 0; i < width; i++ ) { + verts[j*width + i] = verts[j*maxWidth + i]; + } + } + } + verts.SetNum( width * height, false ); +} + +/* +================ +idSurface_Patch::Expand +================ +*/ +void idSurface_Patch::Expand( void ) { + int i, j; + + if ( expanded ) { + idLib::common->FatalError("idSurface_Patch::Expand: patch alread expanded"); + } + expanded = true; + verts.SetNum( maxWidth * maxHeight, false ); + if ( width != maxWidth ) { + for ( j = height-1; j >= 0; j-- ) { + for ( i = width-1; i >= 0; i-- ) { + verts[j*maxWidth + i] = verts[j*width + i]; + } + } + } +} + +/* +============ +idSurface_Patch::LerpVert +============ +*/ +void idSurface_Patch::LerpVert( const idDrawVert &a, const idDrawVert &b, idDrawVert &out ) const { + out.xyz[0] = 0.5f * ( a.xyz[0] + b.xyz[0] ); + out.xyz[1] = 0.5f * ( a.xyz[1] + b.xyz[1] ); + out.xyz[2] = 0.5f * ( a.xyz[2] + b.xyz[2] ); + out.normal[0] = 0.5f * ( a.normal[0] + b.normal[0] ); + out.normal[1] = 0.5f * ( a.normal[1] + b.normal[1] ); + out.normal[2] = 0.5f * ( a.normal[2] + b.normal[2] ); + out.st[0] = 0.5f * ( a.st[0] + b.st[0] ); + out.st[1] = 0.5f * ( a.st[1] + b.st[1] ); +} + +/* +================= +idSurface_Patch::GenerateNormals + +Handles all the complicated wrapping and degenerate cases +Expects a Not expanded patch. +================= +*/ +#define COPLANAR_EPSILON 0.1f + +void idSurface_Patch::GenerateNormals( void ) { + int i, j, k, dist; + idVec3 norm; + idVec3 sum; + int count; + idVec3 base; + idVec3 delta; + int x, y; + idVec3 around[8], temp; + bool good[8]; + bool wrapWidth, wrapHeight; + static int neighbors[8][2] = { + {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1} + }; + + assert( expanded == false ); + + // + // if all points are coplanar, set all normals to that plane + // + idVec3 extent[3]; + float offset; + + extent[0] = verts[width - 1].xyz - verts[0].xyz; + extent[1] = verts[(height-1) * width + width - 1].xyz - verts[0].xyz; + extent[2] = verts[(height-1) * width].xyz - verts[0].xyz; + + norm = extent[0].Cross( extent[1] ); + if ( norm.LengthSqr() == 0.0f ) { + norm = extent[0].Cross( extent[2] ); + if ( norm.LengthSqr() == 0.0f ) { + norm = extent[1].Cross( extent[2] ); + } + } + + // wrapped patched may not get a valid normal here + if ( norm.Normalize() != 0.0f ) { + + offset = verts[0].xyz * norm; + for ( i = 1; i < width * height; i++ ) { + float d = verts[i].xyz * norm; + if ( idMath::Fabs( d - offset ) > COPLANAR_EPSILON ) { + break; + } + } + + if ( i == width * height ) { + // all are coplanar + for ( i = 0; i < width * height; i++ ) { + verts[i].normal = norm; + } + return; + } + } + + // check for wrapped edge cases, which should smooth across themselves + wrapWidth = false; + for ( i = 0; i < height; i++ ) { + delta = verts[i * width].xyz - verts[i * width + width-1].xyz; + if ( delta.LengthSqr() > Square( 1.0f ) ) { + break; + } + } + if ( i == height ) { + wrapWidth = true; + } + + wrapHeight = false; + for ( i = 0; i < width; i++ ) { + delta = verts[i].xyz - verts[(height-1) * width + i].xyz; + if ( delta.LengthSqr() > Square( 1.0f ) ) { + break; + } + } + if ( i == width ) { + wrapHeight = true; + } + + for ( i = 0; i < width; i++ ) { + for ( j = 0; j < height; j++ ) { + count = 0; + base = verts[j * width + i].xyz; + for ( k = 0; k < 8; k++ ) { + around[k] = vec3_origin; + good[k] = false; + + for ( dist = 1; dist <= 3; dist++ ) { + x = i + neighbors[k][0] * dist; + y = j + neighbors[k][1] * dist; + if ( wrapWidth ) { + if ( x < 0 ) { + x = width - 1 + x; + } else if ( x >= width ) { + x = 1 + x - width; + } + } + if ( wrapHeight ) { + if ( y < 0 ) { + y = height - 1 + y; + } else if ( y >= height ) { + y = 1 + y - height; + } + } + + if ( x < 0 || x >= width || y < 0 || y >= height ) { + break; // edge of patch + } + temp = verts[y * width + x].xyz - base; + if ( temp.Normalize() == 0.0f ) { + continue; // degenerate edge, get more dist + } else { + good[k] = true; + around[k] = temp; + break; // good edge + } + } + } + + sum = vec3_origin; + for ( k = 0; k < 8; k++ ) { + if ( !good[k] || !good[(k+1)&7] ) { + continue; // didn't get two points + } + norm = around[(k+1)&7].Cross( around[k] ); + if ( norm.Normalize() == 0.0f ) { + continue; + } + sum += norm; + count++; + } + if ( count == 0 ) { + //idLib::common->Printf("bad normal\n"); + count = 1; + } + verts[j * width + i].normal = sum; + verts[j * width + i].normal.Normalize(); + } + } +} + +/* +================= +idSurface_Patch::GenerateIndexes +================= +*/ +void idSurface_Patch::GenerateIndexes( void ) { + int i, j, v1, v2, v3, v4, index; + + indexes.SetNum( (width-1) * (height-1) * 2 * 3, false ); + index = 0; + for ( i = 0; i < width - 1; i++ ) { + for ( j = 0; j < height - 1; j++ ) { + v1 = j * width + i; + v2 = v1 + 1; + v3 = v1 + width + 1; + v4 = v1 + width; + indexes[index++] = v1; + indexes[index++] = v3; + indexes[index++] = v2; + indexes[index++] = v1; + indexes[index++] = v4; + indexes[index++] = v3; + } + } + + GenerateEdgeIndexes(); +} + +/* +=============== +idSurface_Patch::SampleSinglePatchPoint +=============== +*/ +void idSurface_Patch::SampleSinglePatchPoint( const idDrawVert ctrl[3][3], float u, float v, idDrawVert *out ) const { + float vCtrl[3][8]; + int vPoint; + int axis; + + // find the control points for the v coordinate + for ( vPoint = 0; vPoint < 3; vPoint++ ) { + for ( axis = 0; axis < 8; axis++ ) { + float a, b, c; + float qA, qB, qC; + if ( axis < 3 ) { + a = ctrl[0][vPoint].xyz[axis]; + b = ctrl[1][vPoint].xyz[axis]; + c = ctrl[2][vPoint].xyz[axis]; + } else if ( axis < 6 ) { + a = ctrl[0][vPoint].normal[axis-3]; + b = ctrl[1][vPoint].normal[axis-3]; + c = ctrl[2][vPoint].normal[axis-3]; + } else { + a = ctrl[0][vPoint].st[axis-6]; + b = ctrl[1][vPoint].st[axis-6]; + c = ctrl[2][vPoint].st[axis-6]; + } + qA = a - 2.0f * b + c; + qB = 2.0f * b - 2.0f * a; + qC = a; + vCtrl[vPoint][axis] = qA * u * u + qB * u + qC; + } + } + + // interpolate the v value + for ( axis = 0; axis < 8; axis++ ) { + float a, b, c; + float qA, qB, qC; + + a = vCtrl[0][axis]; + b = vCtrl[1][axis]; + c = vCtrl[2][axis]; + qA = a - 2.0f * b + c; + qB = 2.0f * b - 2.0f * a; + qC = a; + + if ( axis < 3 ) { + out->xyz[axis] = qA * v * v + qB * v + qC; + } else if ( axis < 6 ) { + out->normal[axis-3] = qA * v * v + qB * v + qC; + } else { + out->st[axis-6] = qA * v * v + qB * v + qC; + } + } +} + +/* +=================== +idSurface_Patch::SampleSinglePatch +=================== +*/ +void idSurface_Patch::SampleSinglePatch( const idDrawVert ctrl[3][3], int baseCol, int baseRow, int width, int horzSub, int vertSub, idDrawVert *outVerts ) const { + int i, j; + float u, v; + + horzSub++; + vertSub++; + for ( i = 0; i < horzSub; i++ ) { + for ( j = 0; j < vertSub; j++ ) { + u = (float) i / ( horzSub - 1 ); + v = (float) j / ( vertSub - 1 ); + SampleSinglePatchPoint( ctrl, u, v, &outVerts[((baseRow + j) * width) + i + baseCol] ); + } + } +} + +/* +================= +idSurface_Patch::SubdivideExplicit +================= +*/ +void idSurface_Patch::SubdivideExplicit( int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear ) { + int i, j, k, l; + idDrawVert sample[3][3]; + int outWidth = ((width - 1) / 2 * horzSubdivisions) + 1; + int outHeight = ((height - 1) / 2 * vertSubdivisions) + 1; + idDrawVert *dv = new idDrawVert[ outWidth * outHeight ]; + + // generate normals for the control mesh + if ( genNormals ) { + GenerateNormals(); + } + + int baseCol = 0; + for ( i = 0; i + 2 < width; i += 2 ) { + int baseRow = 0; + for ( j = 0; j + 2 < height; j += 2 ) { + for ( k = 0; k < 3; k++ ) { + for ( l = 0; l < 3; l++ ) { + sample[k][l] = verts[ ((j + l) * width) + i + k ]; + } + } + SampleSinglePatch( sample, baseCol, baseRow, outWidth, horzSubdivisions, vertSubdivisions, dv ); + baseRow += vertSubdivisions; + } + baseCol += horzSubdivisions; + } + verts.SetNum( outWidth * outHeight ); + for ( i = 0; i < outWidth * outHeight; i++ ) { + verts[i] = dv[i]; + } + + delete[] dv; + + width = maxWidth = outWidth; + height = maxHeight = outHeight; + expanded = false; + + if ( removeLinear ) { + Expand(); + RemoveLinearColumnsRows(); + Collapse(); + } + + // normalize all the lerped normals + if ( genNormals ) { + for ( i = 0; i < width * height; i++ ) { + verts[i].normal.Normalize(); + } + } + + GenerateIndexes(); +} + +/* +================= +idSurface_Patch::Subdivide +================= +*/ +void idSurface_Patch::Subdivide( float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals ) { + int i, j, k, l; + idDrawVert prev, next, mid; + idVec3 prevxyz, nextxyz, midxyz; + idVec3 delta; + float maxHorizontalErrorSqr, maxVerticalErrorSqr, maxLengthSqr; + + // generate normals for the control mesh + if ( genNormals ) { + GenerateNormals(); + } + + maxHorizontalErrorSqr = Square( maxHorizontalError ); + maxVerticalErrorSqr = Square( maxVerticalError ); + maxLengthSqr = Square( maxLength ); + + Expand(); + + // horizontal subdivisions + for ( j = 0; j + 2 < width; j += 2 ) { + // check subdivided midpoints against control points + for ( i = 0; i < height; i++ ) { + for ( l = 0; l < 3; l++ ) { + prevxyz[l] = verts[i*maxWidth + j+1].xyz[l] - verts[i*maxWidth + j ].xyz[l]; + nextxyz[l] = verts[i*maxWidth + j+2].xyz[l] - verts[i*maxWidth + j+1].xyz[l]; + midxyz[l] = (verts[i*maxWidth + j ].xyz[l] + verts[i*maxWidth + j+1].xyz[l] * 2.0f + + verts[i*maxWidth + j+2].xyz[l] ) * 0.25f; + } + + if ( maxLength > 0.0f ) { + // if the span length is too long, force a subdivision + if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) { + break; + } + } + // see if this midpoint is off far enough to subdivide + delta = verts[i*maxWidth + j+1].xyz - midxyz; + if ( delta.LengthSqr() > maxHorizontalErrorSqr ) { + break; + } + } + + if ( i == height ) { + continue; // didn't need subdivision + } + + if ( width + 2 >= maxWidth ) { + ResizeExpanded( maxHeight, maxWidth + 4 ); + } + + // insert two columns and replace the peak + width += 2; + + for ( i = 0; i < height; i++ ) { + idSurface_Patch::LerpVert( verts[i*maxWidth + j ], verts[i*maxWidth + j+1], prev ); + idSurface_Patch::LerpVert( verts[i*maxWidth + j+1], verts[i*maxWidth + j+2], next ); + idSurface_Patch::LerpVert( prev, next, mid ); + + for ( k = width - 1; k > j + 3; k-- ) { + verts[i*maxWidth + k] = verts[i*maxWidth + k-2]; + } + verts[i*maxWidth + j+1] = prev; + verts[i*maxWidth + j+2] = mid; + verts[i*maxWidth + j+3] = next; + } + + // back up and recheck this set again, it may need more subdivision + j -= 2; + } + + // vertical subdivisions + for ( j = 0; j + 2 < height; j += 2 ) { + // check subdivided midpoints against control points + for ( i = 0; i < width; i++ ) { + for ( l = 0; l < 3; l++ ) { + prevxyz[l] = verts[(j+1)*maxWidth + i].xyz[l] - verts[j*maxWidth + i].xyz[l]; + nextxyz[l] = verts[(j+2)*maxWidth + i].xyz[l] - verts[(j+1)*maxWidth + i].xyz[l]; + midxyz[l] = (verts[j*maxWidth + i].xyz[l] + verts[(j+1)*maxWidth + i].xyz[l] * 2.0f + + verts[(j+2)*maxWidth + i].xyz[l] ) * 0.25f; + } + + if ( maxLength > 0.0f ) { + // if the span length is too long, force a subdivision + if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) { + break; + } + } + // see if this midpoint is off far enough to subdivide + delta = verts[(j+1)*maxWidth + i].xyz - midxyz; + if ( delta.LengthSqr() > maxVerticalErrorSqr ) { + break; + } + } + + if ( i == width ) { + continue; // didn't need subdivision + } + + if ( height + 2 >= maxHeight ) { + ResizeExpanded( maxHeight + 4, maxWidth ); + } + + // insert two columns and replace the peak + height += 2; + + for ( i = 0; i < width; i++ ) { + LerpVert( verts[j*maxWidth + i], verts[(j+1)*maxWidth + i], prev ); + LerpVert( verts[(j+1)*maxWidth + i], verts[(j+2)*maxWidth + i], next ); + LerpVert( prev, next, mid ); + + for ( k = height - 1; k > j + 3; k-- ) { + verts[k*maxWidth + i] = verts[(k-2)*maxWidth + i]; + } + verts[(j+1)*maxWidth + i] = prev; + verts[(j+2)*maxWidth + i] = mid; + verts[(j+3)*maxWidth + i] = next; + } + + // back up and recheck this set again, it may need more subdivision + j -= 2; + } + + PutOnCurve(); + + RemoveLinearColumnsRows(); + + Collapse(); + + // normalize all the lerped normals + if ( genNormals ) { + for ( i = 0; i < width * height; i++ ) { + verts[i].normal.Normalize(); + } + } + + GenerateIndexes(); +} diff --git a/idlib/geometry/Surface_Patch.h b/idlib/geometry/Surface_Patch.h new file mode 100644 index 000000000..6a3ddfb4c --- /dev/null +++ b/idlib/geometry/Surface_Patch.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SURFACE_PATCH_H__ +#define __SURFACE_PATCH_H__ + +/* +=============================================================================== + + Bezier patch surface. + +=============================================================================== +*/ + +class idSurface_Patch : public idSurface { + +public: + idSurface_Patch( void ); + idSurface_Patch( int maxPatchWidth, int maxPatchHeight ); + idSurface_Patch( const idSurface_Patch &patch ); + ~idSurface_Patch( void ); + + void SetSize( int patchWidth, int patchHeight ); + int GetWidth( void ) const; + int GetHeight( void ) const; + + // subdivide the patch mesh based on error + void Subdivide( float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals = false ); + // subdivide the patch up to an explicit number of horizontal and vertical subdivisions + void SubdivideExplicit( int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear = false ); + +protected: + int width; // width of patch + int height; // height of patch + int maxWidth; // maximum width allocated for + int maxHeight; // maximum height allocated for + bool expanded; // true if vertices are spaced out + +private: + // put the approximation points on the curve + void PutOnCurve( void ); + // remove columns and rows with all points on one line + void RemoveLinearColumnsRows( void ); + // resize verts buffer + void ResizeExpanded( int height, int width ); + // space points out over maxWidth * maxHeight buffer + void Expand( void ); + // move all points to the start of the verts buffer + void Collapse( void ); + // project a point onto a vector to calculate maximum curve error + void ProjectPointOntoVector( const idVec3 &point, const idVec3 &vStart, const idVec3 &vEnd, idVec3 &vProj ); + // generate normals + void GenerateNormals( void ); + // generate triangle indexes + void GenerateIndexes( void ); + // lerp point from two patch point + void LerpVert( const idDrawVert &a, const idDrawVert &b, idDrawVert &out ) const; + // sample a single 3x3 patch + void SampleSinglePatchPoint( const idDrawVert ctrl[3][3], float u, float v, idDrawVert *out ) const; + void SampleSinglePatch( const idDrawVert ctrl[3][3], int baseCol, int baseRow, int width, int horzSub, int vertSub, idDrawVert *outVerts ) const; +}; + +/* +================= +idSurface_Patch::idSurface_Patch +================= +*/ +ID_INLINE idSurface_Patch::idSurface_Patch( void ) { + height = width = maxHeight = maxWidth = 0; + expanded = false; +} + +/* +================= +idSurface_Patch::idSurface_Patch +================= +*/ +ID_INLINE idSurface_Patch::idSurface_Patch( int maxPatchWidth, int maxPatchHeight ) { + width = height = 0; + maxWidth = maxPatchWidth; + maxHeight = maxPatchHeight; + verts.SetNum( maxWidth * maxHeight ); + expanded = false; +} + +/* +================= +idSurface_Patch::idSurface_Patch +================= +*/ +ID_INLINE idSurface_Patch::idSurface_Patch( const idSurface_Patch &patch ) { + (*this) = patch; +} + +/* +================= +idSurface_Patch::~idSurface_Patch +================= +*/ +ID_INLINE idSurface_Patch::~idSurface_Patch() { +} + +/* +================= +idSurface_Patch::GetWidth +================= +*/ +ID_INLINE int idSurface_Patch::GetWidth( void ) const { + return width; +} + +/* +================= +idSurface_Patch::GetHeight +================= +*/ +ID_INLINE int idSurface_Patch::GetHeight( void ) const { + return height; +} + +#endif /* !__SURFACE_PATCH_H__ */ diff --git a/idlib/geometry/Surface_Polytope.cpp b/idlib/geometry/Surface_Polytope.cpp new file mode 100644 index 000000000..336320cc6 --- /dev/null +++ b/idlib/geometry/Surface_Polytope.cpp @@ -0,0 +1,327 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#define POLYTOPE_VERTEX_EPSILON 0.1f + + +/* +==================== +idSurface_Polytope::FromPlanes +==================== +*/ +void idSurface_Polytope::FromPlanes( const idPlane *planes, const int numPlanes ) { + int i, j, k, *windingVerts; + idFixedWinding w; + idDrawVert newVert; + + windingVerts = (int *) _alloca( MAX_POINTS_ON_WINDING * sizeof( int ) ); + memset( &newVert, 0, sizeof( newVert ) ); + + for ( i = 0; i < numPlanes; i++ ) { + + w.BaseForPlane( planes[i] ); + + for ( j = 0; j < numPlanes; j++ ) { + if ( j == i ) { + continue; + } + if ( !w.ClipInPlace( -planes[j], ON_EPSILON, true ) ) { + break; + } + } + if ( !w.GetNumPoints() ) { + continue; + } + + for ( j = 0; j < w.GetNumPoints(); j++ ) { + for ( k = 0; k < verts.Num(); j++ ) { + if ( verts[k].xyz.Compare( w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON ) ) { + break; + } + } + if ( k >= verts.Num() ) { + newVert.xyz = w[j].ToVec3(); + k = verts.Append( newVert ); + } + windingVerts[j] = k; + } + + for ( j = 2; j < w.GetNumPoints(); j++ ) { + indexes.Append( windingVerts[0] ); + indexes.Append( windingVerts[j-1] ); + indexes.Append( windingVerts[j] ); + } + } + + GenerateEdgeIndexes(); +} + +/* +==================== +idSurface_Polytope::SetupTetrahedron +==================== +*/ +void idSurface_Polytope::SetupTetrahedron( const idBounds &bounds ) { + idVec3 center, scale; + float c1, c2, c3; + + c1 = 0.4714045207f; + c2 = 0.8164965809f; + c3 = -0.3333333333f; + + center = bounds.GetCenter(); + scale = bounds[1] - center; + + verts.SetNum( 4 ); + verts[0].xyz = center + idVec3( 0.0f, 0.0f, scale.z ); + verts[1].xyz = center + idVec3( 2.0f * c1 * scale.x, 0.0f, c3 * scale.z ); + verts[2].xyz = center + idVec3( -c1 * scale.x, c2 * scale.y, c3 * scale.z ); + verts[3].xyz = center + idVec3( -c1 * scale.x, -c2 * scale.y, c3 * scale.z ); + + indexes.SetNum( 4*3 ); + indexes[0*3+0] = 0; + indexes[0*3+1] = 1; + indexes[0*3+2] = 2; + indexes[1*3+0] = 0; + indexes[1*3+1] = 2; + indexes[1*3+2] = 3; + indexes[2*3+0] = 0; + indexes[2*3+1] = 3; + indexes[2*3+2] = 1; + indexes[3*3+0] = 1; + indexes[3*3+1] = 3; + indexes[3*3+2] = 2; + + GenerateEdgeIndexes(); +} + +/* +==================== +idSurface_Polytope::SetupHexahedron +==================== +*/ +void idSurface_Polytope::SetupHexahedron( const idBounds &bounds ) { + idVec3 center, scale; + + center = bounds.GetCenter(); + scale = bounds[1] - center; + + verts.SetNum( 8 ); + verts[0].xyz = center + idVec3( -scale.x, -scale.y, -scale.z ); + verts[1].xyz = center + idVec3( scale.x, -scale.y, -scale.z ); + verts[2].xyz = center + idVec3( scale.x, scale.y, -scale.z ); + verts[3].xyz = center + idVec3( -scale.x, scale.y, -scale.z ); + verts[4].xyz = center + idVec3( -scale.x, -scale.y, scale.z ); + verts[5].xyz = center + idVec3( scale.x, -scale.y, scale.z ); + verts[6].xyz = center + idVec3( scale.x, scale.y, scale.z ); + verts[7].xyz = center + idVec3( -scale.x, scale.y, scale.z ); + + indexes.SetNum( 12*3 ); + indexes[ 0*3+0] = 0; + indexes[ 0*3+1] = 3; + indexes[ 0*3+2] = 2; + indexes[ 1*3+0] = 0; + indexes[ 1*3+1] = 2; + indexes[ 1*3+2] = 1; + indexes[ 2*3+0] = 0; + indexes[ 2*3+1] = 1; + indexes[ 2*3+2] = 5; + indexes[ 3*3+0] = 0; + indexes[ 3*3+1] = 5; + indexes[ 3*3+2] = 4; + indexes[ 4*3+0] = 0; + indexes[ 4*3+1] = 4; + indexes[ 4*3+2] = 7; + indexes[ 5*3+0] = 0; + indexes[ 5*3+1] = 7; + indexes[ 5*3+2] = 3; + indexes[ 6*3+0] = 6; + indexes[ 6*3+1] = 5; + indexes[ 6*3+2] = 1; + indexes[ 7*3+0] = 6; + indexes[ 7*3+1] = 1; + indexes[ 7*3+2] = 2; + indexes[ 8*3+0] = 6; + indexes[ 8*3+1] = 2; + indexes[ 8*3+2] = 3; + indexes[ 9*3+0] = 6; + indexes[ 9*3+1] = 3; + indexes[ 9*3+2] = 7; + indexes[10*3+0] = 6; + indexes[10*3+1] = 7; + indexes[10*3+2] = 4; + indexes[11*3+0] = 6; + indexes[11*3+1] = 4; + indexes[11*3+2] = 5; + + GenerateEdgeIndexes(); +} + +/* +==================== +idSurface_Polytope::SetupOctahedron +==================== +*/ +void idSurface_Polytope::SetupOctahedron( const idBounds &bounds ) { + idVec3 center, scale; + + center = bounds.GetCenter(); + scale = bounds[1] - center; + + verts.SetNum( 6 ); + verts[0].xyz = center + idVec3( scale.x, 0.0f, 0.0f ); + verts[1].xyz = center + idVec3( -scale.x, 0.0f, 0.0f ); + verts[2].xyz = center + idVec3( 0.0f, scale.y, 0.0f ); + verts[3].xyz = center + idVec3( 0.0f, -scale.y, 0.0f ); + verts[4].xyz = center + idVec3( 0.0f, 0.0f, scale.z ); + verts[5].xyz = center + idVec3( 0.0f, 0.0f, -scale.z ); + + indexes.SetNum( 8*3 ); + indexes[0*3+0] = 4; + indexes[0*3+1] = 0; + indexes[0*3+2] = 2; + indexes[1*3+0] = 4; + indexes[1*3+1] = 2; + indexes[1*3+2] = 1; + indexes[2*3+0] = 4; + indexes[2*3+1] = 1; + indexes[2*3+2] = 3; + indexes[3*3+0] = 4; + indexes[3*3+1] = 3; + indexes[3*3+2] = 0; + indexes[4*3+0] = 5; + indexes[4*3+1] = 2; + indexes[4*3+2] = 0; + indexes[5*3+0] = 5; + indexes[5*3+1] = 1; + indexes[5*3+2] = 2; + indexes[6*3+0] = 5; + indexes[6*3+1] = 3; + indexes[6*3+2] = 1; + indexes[7*3+0] = 5; + indexes[7*3+1] = 0; + indexes[7*3+2] = 3; + + GenerateEdgeIndexes(); +} + +/* +==================== +idSurface_Polytope::SetupDodecahedron +==================== +*/ +void idSurface_Polytope::SetupDodecahedron( const idBounds &bounds ) { +} + +/* +==================== +idSurface_Polytope::SetupIcosahedron +==================== +*/ +void idSurface_Polytope::SetupIcosahedron( const idBounds &bounds ) { +} + +/* +==================== +idSurface_Polytope::SetupCylinder +==================== +*/ +void idSurface_Polytope::SetupCylinder( const idBounds &bounds, const int numSides ) { +} + +/* +==================== +idSurface_Polytope::SetupCone +==================== +*/ +void idSurface_Polytope::SetupCone( const idBounds &bounds, const int numSides ) { +} + +/* +==================== +idSurface_Polytope::SplitPolytope +==================== +*/ +int idSurface_Polytope::SplitPolytope( const idPlane &plane, const float epsilon, idSurface_Polytope **front, idSurface_Polytope **back ) const { + int side, i, j, s, v0, v1, v2, edgeNum; + idSurface *surface[2]; + idSurface_Polytope *polytopeSurfaces[2], *surf; + int *onPlaneEdges[2]; + + onPlaneEdges[0] = (int *) _alloca( indexes.Num() / 3 * sizeof( int ) ); + onPlaneEdges[1] = (int *) _alloca( indexes.Num() / 3 * sizeof( int ) ); + + side = Split( plane, epsilon, &surface[0], &surface[1], onPlaneEdges[0], onPlaneEdges[1] ); + + *front = polytopeSurfaces[0] = new idSurface_Polytope; + *back = polytopeSurfaces[1] = new idSurface_Polytope; + + for ( s = 0; s < 2; s++ ) { + if ( surface[s] ) { + polytopeSurfaces[s] = new idSurface_Polytope; + polytopeSurfaces[s]->SwapTriangles( *surface[s] ); + delete surface[s]; + surface[s] = NULL; + } + } + + *front = polytopeSurfaces[0]; + *back = polytopeSurfaces[1]; + + if ( side != SIDE_CROSS ) { + return side; + } + + // add triangles to close off the front and back polytope + for ( s = 0; s < 2; s++ ) { + + surf = polytopeSurfaces[s]; + + edgeNum = surf->edgeIndexes[onPlaneEdges[s][0]]; + v0 = surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)]; + v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; + + for ( i = 1; onPlaneEdges[s][i] >= 0; i++ ) { + for ( j = i+1; onPlaneEdges[s][j] >= 0; j++ ) { + edgeNum = surf->edgeIndexes[onPlaneEdges[s][j]]; + if ( v1 == surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)] ) { + v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; + idSwap( onPlaneEdges[s][i], onPlaneEdges[s][j] ); + break; + } + } + } + + for ( i = 2; onPlaneEdges[s][i] >= 0; i++ ) { + edgeNum = surf->edgeIndexes[onPlaneEdges[s][i]]; + v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; + v2 = surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)]; + surf->indexes.Append( v0 ); + surf->indexes.Append( v1 ); + surf->indexes.Append( v2 ); + } + + surf->GenerateEdgeIndexes(); + } + + return side; +} diff --git a/idlib/geometry/Surface_Polytope.h b/idlib/geometry/Surface_Polytope.h new file mode 100644 index 000000000..558f82048 --- /dev/null +++ b/idlib/geometry/Surface_Polytope.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SURFACE_POLYTOPE_H__ +#define __SURFACE_POLYTOPE_H__ + +/* +=============================================================================== + + Polytope surface. + + NOTE: vertexes are not duplicated for texture coordinates. + +=============================================================================== +*/ + +class idSurface_Polytope : public idSurface { +public: + idSurface_Polytope( void ); + + void FromPlanes( const idPlane *planes, const int numPlanes ); + + void SetupTetrahedron( const idBounds &bounds ); + void SetupHexahedron( const idBounds &bounds ); + void SetupOctahedron( const idBounds &bounds ); + void SetupDodecahedron( const idBounds &bounds ); + void SetupIcosahedron( const idBounds &bounds ); + void SetupCylinder( const idBounds &bounds, const int numSides ); + void SetupCone( const idBounds &bounds, const int numSides ); + + int SplitPolytope( const idPlane &plane, const float epsilon, idSurface_Polytope **front, idSurface_Polytope **back ) const; + +protected: + +}; + +/* +==================== +idSurface_Polytope::idSurface_Polytope +==================== +*/ +ID_INLINE idSurface_Polytope::idSurface_Polytope( void ) { +} + +#endif /* !__SURFACE_POLYTOPE_H__ */ diff --git a/idlib/geometry/Surface_SweptSpline.cpp b/idlib/geometry/Surface_SweptSpline.cpp new file mode 100644 index 000000000..0b772a143 --- /dev/null +++ b/idlib/geometry/Surface_SweptSpline.cpp @@ -0,0 +1,214 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +==================== +idSurface_SweptSpline::SetSpline +==================== +*/ +void idSurface_SweptSpline::SetSpline( idCurve_Spline *spline ) { + if ( this->spline ) { + delete this->spline; + } + this->spline = spline; +} + +/* +==================== +idSurface_SweptSpline::SetSweptSpline +==================== +*/ +void idSurface_SweptSpline::SetSweptSpline( idCurve_Spline *sweptSpline ) { + if ( this->sweptSpline ) { + delete this->sweptSpline; + } + this->sweptSpline = sweptSpline; +} + +/* +==================== +idSurface_SweptSpline::SetSweptCircle + + Sets the swept spline to a NURBS circle. +==================== +*/ +void idSurface_SweptSpline::SetSweptCircle( const float radius ) { + idCurve_NURBS *nurbs = new idCurve_NURBS(); + nurbs->Clear(); + nurbs->AddValue( 0.0f, idVec4( radius, radius, 0.0f, 0.00f ) ); + nurbs->AddValue( 100.0f, idVec4( -radius, radius, 0.0f, 0.25f ) ); + nurbs->AddValue( 200.0f, idVec4( -radius, -radius, 0.0f, 0.50f ) ); + nurbs->AddValue( 300.0f, idVec4( radius, -radius, 0.0f, 0.75f ) ); + nurbs->SetBoundaryType( idCurve_NURBS::BT_CLOSED ); + nurbs->SetCloseTime( 100.0f ); + if ( sweptSpline ) { + delete sweptSpline; + } + sweptSpline = nurbs; +} + +/* +==================== +idSurface_SweptSpline::GetFrame +==================== +*/ +void idSurface_SweptSpline::GetFrame( const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame ) { + float wx, wy, wz; + float xx, yy, yz; + float xy, xz, zz; + float x2, y2, z2; + float a, c, s, x, y, z; + idVec3 d, v; + idMat3 axis; + + d = dir; + d.Normalize(); + v = d.Cross( previousFrame[2] ); + v.Normalize(); + + a = idMath::ACos( previousFrame[2] * d ) * 0.5f; + c = idMath::Cos( a ); + s = idMath::Sqrt( 1.0f - c * c ); + + x = v[0] * s; + y = v[1] * s; + z = v[2] * s; + + x2 = x + x; + y2 = y + y; + z2 = z + z; + xx = x * x2; + xy = x * y2; + xz = x * z2; + yy = y * y2; + yz = y * z2; + zz = z * z2; + wx = c * x2; + wy = c * y2; + wz = c * z2; + + axis[0][0] = 1.0f - ( yy + zz ); + axis[0][1] = xy - wz; + axis[0][2] = xz + wy; + axis[1][0] = xy + wz; + axis[1][1] = 1.0f - ( xx + zz ); + axis[1][2] = yz - wx; + axis[2][0] = xz - wy; + axis[2][1] = yz + wx; + axis[2][2] = 1.0f - ( xx + yy ); + + newFrame = previousFrame * axis; + + newFrame[2] = dir; + newFrame[2].Normalize(); + newFrame[1].Cross( newFrame[ 2 ], newFrame[ 0 ] ); + newFrame[1].Normalize(); + newFrame[0].Cross( newFrame[ 1 ], newFrame[ 2 ] ); + newFrame[0].Normalize(); +} + +/* +==================== +idSurface_SweptSpline::Tessellate + + tesselate the surface +==================== +*/ +void idSurface_SweptSpline::Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ) { + int i, j, offset, baseOffset, splineDiv, sweptSplineDiv; + int i0, i1, j0, j1; + float totalTime, t; + idVec4 splinePos, splineD1; + idMat3 splineMat; + + if ( !spline || !sweptSpline ) { + idSurface::Clear(); + return; + } + + verts.SetNum( splineSubdivisions * sweptSplineSubdivisions, false ); + + // calculate the points and first derivatives for the swept spline + totalTime = sweptSpline->GetTime( sweptSpline->GetNumValues() - 1 ) - sweptSpline->GetTime( 0 ) + sweptSpline->GetCloseTime(); + sweptSplineDiv = sweptSpline->GetBoundaryType() == idCurve_Spline::BT_CLOSED ? sweptSplineSubdivisions : sweptSplineSubdivisions - 1; + baseOffset = (splineSubdivisions-1) * sweptSplineSubdivisions; + for ( i = 0; i < sweptSplineSubdivisions; i++ ) { + t = totalTime * i / sweptSplineDiv; + splinePos = sweptSpline->GetCurrentValue( t ); + splineD1 = sweptSpline->GetCurrentFirstDerivative( t ); + verts[baseOffset+i].xyz = splinePos.ToVec3(); + verts[baseOffset+i].st[0] = splinePos.w; + verts[baseOffset+i].tangents[0] = splineD1.ToVec3(); + } + + // sweep the spline + totalTime = spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 ) + spline->GetCloseTime(); + splineDiv = spline->GetBoundaryType() == idCurve_Spline::BT_CLOSED ? splineSubdivisions : splineSubdivisions - 1; + splineMat.Identity(); + for ( i = 0; i < splineSubdivisions; i++ ) { + t = totalTime * i / splineDiv; + + splinePos = spline->GetCurrentValue( t ); + splineD1 = spline->GetCurrentFirstDerivative( t ); + + GetFrame( splineMat, splineD1.ToVec3(), splineMat ); + + offset = i * sweptSplineSubdivisions; + for ( j = 0; j < sweptSplineSubdivisions; j++ ) { + idDrawVert *v = &verts[offset+j]; + v->xyz = splinePos.ToVec3() + verts[baseOffset+j].xyz * splineMat; + v->st[0] = verts[baseOffset+j].st[0]; + v->st[1] = splinePos.w; + v->tangents[0] = verts[baseOffset+j].tangents[0] * splineMat; + v->tangents[1] = splineD1.ToVec3(); + v->normal = v->tangents[1].Cross( v->tangents[0] ); + v->normal.Normalize(); + v->color[0] = v->color[1] = v->color[2] = v->color[3] = 0; + } + } + + indexes.SetNum( splineDiv * sweptSplineDiv * 2 * 3, false ); + + // create indexes for the triangles + for ( offset = i = 0; i < splineDiv; i++ ) { + + i0 = (i+0) * sweptSplineSubdivisions; + i1 = (i+1) % splineSubdivisions * sweptSplineSubdivisions; + + for ( j = 0; j < sweptSplineDiv; j++ ) { + + j0 = (j+0); + j1 = (j+1) % sweptSplineSubdivisions; + + indexes[offset++] = i0 + j0; + indexes[offset++] = i0 + j1; + indexes[offset++] = i1 + j1; + + indexes[offset++] = i1 + j1; + indexes[offset++] = i1 + j0; + indexes[offset++] = i0 + j0; + } + } + + GenerateEdgeIndexes(); +} diff --git a/idlib/geometry/Surface_SweptSpline.h b/idlib/geometry/Surface_SweptSpline.h new file mode 100644 index 000000000..b7a19a927 --- /dev/null +++ b/idlib/geometry/Surface_SweptSpline.h @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SURFACE_SWEPTSPLINE_H__ +#define __SURFACE_SWEPTSPLINE_H__ + +/* +=============================================================================== + + Swept Spline surface. + +=============================================================================== +*/ + +class idSurface_SweptSpline : public idSurface { +public: + idSurface_SweptSpline( void ); + ~idSurface_SweptSpline( void ); + + void SetSpline( idCurve_Spline *spline ); + void SetSweptSpline( idCurve_Spline *sweptSpline ); + void SetSweptCircle( const float radius ); + + void Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ); + + void Clear( void ); + +protected: + idCurve_Spline *spline; + idCurve_Spline *sweptSpline; + + void GetFrame( const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame ); +}; + +/* +==================== +idSurface_SweptSpline::idSurface_SweptSpline +==================== +*/ +ID_INLINE idSurface_SweptSpline::idSurface_SweptSpline( void ) { + spline = NULL; + sweptSpline = NULL; +} + +/* +==================== +idSurface_SweptSpline::~idSurface_SweptSpline +==================== +*/ +ID_INLINE idSurface_SweptSpline::~idSurface_SweptSpline( void ) { + delete spline; + delete sweptSpline; +} + +/* +==================== +idSurface_SweptSpline::Clear +==================== +*/ +ID_INLINE void idSurface_SweptSpline::Clear( void ) { + idSurface::Clear(); + delete spline; + spline = NULL; + delete sweptSpline; + sweptSpline = NULL; +} + +#endif /* !__SURFACE_SWEPTSPLINE_H__ */ diff --git a/idlib/geometry/TraceModel.cpp b/idlib/geometry/TraceModel.cpp new file mode 100644 index 000000000..6cd8ea4a3 --- /dev/null +++ b/idlib/geometry/TraceModel.cpp @@ -0,0 +1,1560 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + + + +#include "TraceModel.h" + + +/* +============ +idTraceModel::SetupBox +============ +*/ +void idTraceModel::SetupBox( const idBounds &boxBounds ) { + int i; + + if ( type != TRM_BOX ) { + InitBox(); + } + // offset to center + offset = ( boxBounds[0] + boxBounds[1] ) * 0.5f; + // set box vertices + for ( i = 0; i < 8; i++ ) { + verts[i][0] = boxBounds[(i^(i>>1))&1][0]; + verts[i][1] = boxBounds[(i>>1)&1][1]; + verts[i][2] = boxBounds[(i>>2)&1][2]; + } + // set polygon plane distances + polys[0].dist = -boxBounds[0][2]; + polys[1].dist = boxBounds[1][2]; + polys[2].dist = -boxBounds[0][1]; + polys[3].dist = boxBounds[1][0]; + polys[4].dist = boxBounds[1][1]; + polys[5].dist = -boxBounds[0][0]; + // set polygon bounds + for ( i = 0; i < 6; i++ ) { + polys[i].bounds = boxBounds; + } + polys[0].bounds[1][2] = boxBounds[0][2]; + polys[1].bounds[0][2] = boxBounds[1][2]; + polys[2].bounds[1][1] = boxBounds[0][1]; + polys[3].bounds[0][0] = boxBounds[1][0]; + polys[4].bounds[0][1] = boxBounds[1][1]; + polys[5].bounds[1][0] = boxBounds[0][0]; + + bounds = boxBounds; +} + +/* +============ +idTraceModel::SetupBox + + The origin is placed at the center of the cube. +============ +*/ +void idTraceModel::SetupBox( const float size ) { + idBounds boxBounds; + float halfSize; + + halfSize = size * 0.5f; + boxBounds[0].Set( -halfSize, -halfSize, -halfSize ); + boxBounds[1].Set( halfSize, halfSize, halfSize ); + SetupBox( boxBounds ); +} + +/* +============ +idTraceModel::InitBox + + Initialize size independent box. +============ +*/ +void idTraceModel::InitBox( void ) { + int i; + + type = TRM_BOX; + numVerts = 8; + numEdges = 12; + numPolys = 6; + + // set box edges + for ( i = 0; i < 4; i++ ) { + edges[ i + 1 ].v[0] = i; + edges[ i + 1 ].v[1] = (i + 1) & 3; + edges[ i + 5 ].v[0] = 4 + i; + edges[ i + 5 ].v[1] = 4 + ((i + 1) & 3); + edges[ i + 9 ].v[0] = i; + edges[ i + 9 ].v[1] = 4 + i; + } + + // all edges of a polygon go counter clockwise + polys[0].numEdges = 4; + polys[0].edges[0] = -4; + polys[0].edges[1] = -3; + polys[0].edges[2] = -2; + polys[0].edges[3] = -1; + polys[0].normal.Set( 0.0f, 0.0f, -1.0f ); + + polys[1].numEdges = 4; + polys[1].edges[0] = 5; + polys[1].edges[1] = 6; + polys[1].edges[2] = 7; + polys[1].edges[3] = 8; + polys[1].normal.Set( 0.0f, 0.0f, 1.0f ); + + polys[2].numEdges = 4; + polys[2].edges[0] = 1; + polys[2].edges[1] = 10; + polys[2].edges[2] = -5; + polys[2].edges[3] = -9; + polys[2].normal.Set( 0.0f, -1.0f, 0.0f ); + + polys[3].numEdges = 4; + polys[3].edges[0] = 2; + polys[3].edges[1] = 11; + polys[3].edges[2] = -6; + polys[3].edges[3] = -10; + polys[3].normal.Set( 1.0f, 0.0f, 0.0f ); + + polys[4].numEdges = 4; + polys[4].edges[0] = 3; + polys[4].edges[1] = 12; + polys[4].edges[2] = -7; + polys[4].edges[3] = -11; + polys[4].normal.Set( 0.0f, 1.0f, 0.0f ); + + polys[5].numEdges = 4; + polys[5].edges[0] = 4; + polys[5].edges[1] = 9; + polys[5].edges[2] = -8; + polys[5].edges[3] = -12; + polys[5].normal.Set( -1.0f, 0.0f, 0.0f ); + + // convex model + isConvex = true; + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::SetupOctahedron +============ +*/ +void idTraceModel::SetupOctahedron( const idBounds &octBounds ) { + int i, e0, e1, v0, v1, v2; + idVec3 v; + + if ( type != TRM_OCTAHEDRON ) { + InitOctahedron(); + } + + offset = ( octBounds[0] + octBounds[1] ) * 0.5f; + v[0] = octBounds[1][0] - offset[0]; + v[1] = octBounds[1][1] - offset[1]; + v[2] = octBounds[1][2] - offset[2]; + + // set vertices + verts[0].Set( offset.x + v[0], offset.y, offset.z ); + verts[1].Set( offset.x - v[0], offset.y, offset.z ); + verts[2].Set( offset.x, offset.y + v[1], offset.z ); + verts[3].Set( offset.x, offset.y - v[1], offset.z ); + verts[4].Set( offset.x, offset.y, offset.z + v[2] ); + verts[5].Set( offset.x, offset.y, offset.z - v[2] ); + + // set polygons + for ( i = 0; i < numPolys; i++ ) { + e0 = polys[i].edges[0]; + e1 = polys[i].edges[1]; + v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; + v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; + v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; + // polygon plane + polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); + polys[i].normal.Normalize(); + polys[i].dist = polys[i].normal * verts[v0]; + // polygon bounds + polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; + polys[i].bounds.AddPoint( verts[v1] ); + polys[i].bounds.AddPoint( verts[v2] ); + } + + // trm bounds + bounds = octBounds; + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::SetupOctahedron + + The origin is placed at the center of the octahedron. +============ +*/ +void idTraceModel::SetupOctahedron( const float size ) { + idBounds octBounds; + float halfSize; + + halfSize = size * 0.5f; + octBounds[0].Set( -halfSize, -halfSize, -halfSize ); + octBounds[1].Set( halfSize, halfSize, halfSize ); + SetupOctahedron( octBounds ); +} + +/* +============ +idTraceModel::InitOctahedron + + Initialize size independent octahedron. +============ +*/ +void idTraceModel::InitOctahedron( void ) { + + type = TRM_OCTAHEDRON; + numVerts = 6; + numEdges = 12; + numPolys = 8; + + // set edges + edges[ 1].v[0] = 4; edges[ 1].v[1] = 0; + edges[ 2].v[0] = 0; edges[ 2].v[1] = 2; + edges[ 3].v[0] = 2; edges[ 3].v[1] = 4; + edges[ 4].v[0] = 2; edges[ 4].v[1] = 1; + edges[ 5].v[0] = 1; edges[ 5].v[1] = 4; + edges[ 6].v[0] = 1; edges[ 6].v[1] = 3; + edges[ 7].v[0] = 3; edges[ 7].v[1] = 4; + edges[ 8].v[0] = 3; edges[ 8].v[1] = 0; + edges[ 9].v[0] = 5; edges[ 9].v[1] = 2; + edges[10].v[0] = 0; edges[10].v[1] = 5; + edges[11].v[0] = 5; edges[11].v[1] = 1; + edges[12].v[0] = 5; edges[12].v[1] = 3; + + // all edges of a polygon go counter clockwise + polys[0].numEdges = 3; + polys[0].edges[0] = 1; + polys[0].edges[1] = 2; + polys[0].edges[2] = 3; + + polys[1].numEdges = 3; + polys[1].edges[0] = -3; + polys[1].edges[1] = 4; + polys[1].edges[2] = 5; + + polys[2].numEdges = 3; + polys[2].edges[0] = -5; + polys[2].edges[1] = 6; + polys[2].edges[2] = 7; + + polys[3].numEdges = 3; + polys[3].edges[0] = -7; + polys[3].edges[1] = 8; + polys[3].edges[2] = -1; + + polys[4].numEdges = 3; + polys[4].edges[0] = 9; + polys[4].edges[1] = -2; + polys[4].edges[2] = 10; + + polys[5].numEdges = 3; + polys[5].edges[0] = 11; + polys[5].edges[1] = -4; + polys[5].edges[2] = -9; + + polys[6].numEdges = 3; + polys[6].edges[0] = 12; + polys[6].edges[1] = -6; + polys[6].edges[2] = -11; + + polys[7].numEdges = 3; + polys[7].edges[0] = -10; + polys[7].edges[1] = -8; + polys[7].edges[2] = -12; + + // convex model + isConvex = true; +} + +/* +============ +idTraceModel::SetupDodecahedron +============ +*/ +void idTraceModel::SetupDodecahedron( const idBounds &dodBounds ) { + int i, e0, e1, e2, e3, v0, v1, v2, v3, v4; + float s, d; + idVec3 a, b, c; + + if ( type != TRM_DODECAHEDRON ) { + InitDodecahedron(); + } + + a[0] = a[1] = a[2] = 0.5773502691896257f; // 1.0f / ( 3.0f ) ^ 0.5f; + b[0] = b[1] = b[2] = 0.3568220897730899f; // ( ( 3.0f - ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; + c[0] = c[1] = c[2] = 0.9341723589627156f; // ( ( 3.0f + ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; + d = 0.5f / c[0]; + s = ( dodBounds[1][0] - dodBounds[0][0] ) * d; + a[0] *= s; + b[0] *= s; + c[0] *= s; + s = ( dodBounds[1][1] - dodBounds[0][1] ) * d; + a[1] *= s; + b[1] *= s; + c[1] *= s; + s = ( dodBounds[1][2] - dodBounds[0][2] ) * d; + a[2] *= s; + b[2] *= s; + c[2] *= s; + + offset = ( dodBounds[0] + dodBounds[1] ) * 0.5f; + + // set vertices + verts[ 0].Set( offset.x + a[0], offset.y + a[1], offset.z + a[2] ); + verts[ 1].Set( offset.x + a[0], offset.y + a[1], offset.z - a[2] ); + verts[ 2].Set( offset.x + a[0], offset.y - a[1], offset.z + a[2] ); + verts[ 3].Set( offset.x + a[0], offset.y - a[1], offset.z - a[2] ); + verts[ 4].Set( offset.x - a[0], offset.y + a[1], offset.z + a[2] ); + verts[ 5].Set( offset.x - a[0], offset.y + a[1], offset.z - a[2] ); + verts[ 6].Set( offset.x - a[0], offset.y - a[1], offset.z + a[2] ); + verts[ 7].Set( offset.x - a[0], offset.y - a[1], offset.z - a[2] ); + verts[ 8].Set( offset.x + b[0], offset.y + c[1], offset.z ); + verts[ 9].Set( offset.x - b[0], offset.y + c[1], offset.z ); + verts[10].Set( offset.x + b[0], offset.y - c[1], offset.z ); + verts[11].Set( offset.x - b[0], offset.y - c[1], offset.z ); + verts[12].Set( offset.x + c[0], offset.y , offset.z + b[2] ); + verts[13].Set( offset.x + c[0], offset.y , offset.z - b[2] ); + verts[14].Set( offset.x - c[0], offset.y , offset.z + b[2] ); + verts[15].Set( offset.x - c[0], offset.y , offset.z - b[2] ); + verts[16].Set( offset.x , offset.y + b[1], offset.z + c[2] ); + verts[17].Set( offset.x , offset.y - b[1], offset.z + c[2] ); + verts[18].Set( offset.x , offset.y + b[1], offset.z - c[2] ); + verts[19].Set( offset.x , offset.y - b[1], offset.z - c[2] ); + + // set polygons + for ( i = 0; i < numPolys; i++ ) { + e0 = polys[i].edges[0]; + e1 = polys[i].edges[1]; + e2 = polys[i].edges[2]; + e3 = polys[i].edges[3]; + v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; + v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; + v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; + v3 = edges[abs(e2)].v[INTSIGNBITNOTSET(e2)]; + v4 = edges[abs(e3)].v[INTSIGNBITNOTSET(e3)]; + // polygon plane + polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); + polys[i].normal.Normalize(); + polys[i].dist = polys[i].normal * verts[v0]; + // polygon bounds + polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; + polys[i].bounds.AddPoint( verts[v1] ); + polys[i].bounds.AddPoint( verts[v2] ); + polys[i].bounds.AddPoint( verts[v3] ); + polys[i].bounds.AddPoint( verts[v4] ); + } + + // trm bounds + bounds = dodBounds; + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::SetupDodecahedron + + The origin is placed at the center of the octahedron. +============ +*/ +void idTraceModel::SetupDodecahedron( const float size ) { + idBounds dodBounds; + float halfSize; + + halfSize = size * 0.5f; + dodBounds[0].Set( -halfSize, -halfSize, -halfSize ); + dodBounds[1].Set( halfSize, halfSize, halfSize ); + SetupDodecahedron( dodBounds ); +} + +/* +============ +idTraceModel::InitDodecahedron + + Initialize size independent dodecahedron. +============ +*/ +void idTraceModel::InitDodecahedron( void ) { + + type = TRM_DODECAHEDRON; + numVerts = 20; + numEdges = 30; + numPolys = 12; + + // set edges + edges[ 1].v[0] = 0; edges[ 1].v[1] = 8; + edges[ 2].v[0] = 8; edges[ 2].v[1] = 9; + edges[ 3].v[0] = 9; edges[ 3].v[1] = 4; + edges[ 4].v[0] = 4; edges[ 4].v[1] = 16; + edges[ 5].v[0] = 16; edges[ 5].v[1] = 0; + edges[ 6].v[0] = 16; edges[ 6].v[1] = 17; + edges[ 7].v[0] = 17; edges[ 7].v[1] = 2; + edges[ 8].v[0] = 2; edges[ 8].v[1] = 12; + edges[ 9].v[0] = 12; edges[ 9].v[1] = 0; + edges[10].v[0] = 2; edges[10].v[1] = 10; + edges[11].v[0] = 10; edges[11].v[1] = 3; + edges[12].v[0] = 3; edges[12].v[1] = 13; + edges[13].v[0] = 13; edges[13].v[1] = 12; + edges[14].v[0] = 9; edges[14].v[1] = 5; + edges[15].v[0] = 5; edges[15].v[1] = 15; + edges[16].v[0] = 15; edges[16].v[1] = 14; + edges[17].v[0] = 14; edges[17].v[1] = 4; + edges[18].v[0] = 3; edges[18].v[1] = 19; + edges[19].v[0] = 19; edges[19].v[1] = 18; + edges[20].v[0] = 18; edges[20].v[1] = 1; + edges[21].v[0] = 1; edges[21].v[1] = 13; + edges[22].v[0] = 7; edges[22].v[1] = 11; + edges[23].v[0] = 11; edges[23].v[1] = 6; + edges[24].v[0] = 6; edges[24].v[1] = 14; + edges[25].v[0] = 15; edges[25].v[1] = 7; + edges[26].v[0] = 1; edges[26].v[1] = 8; + edges[27].v[0] = 18; edges[27].v[1] = 5; + edges[28].v[0] = 6; edges[28].v[1] = 17; + edges[29].v[0] = 11; edges[29].v[1] = 10; + edges[30].v[0] = 19; edges[30].v[1] = 7; + + // all edges of a polygon go counter clockwise + polys[0].numEdges = 5; + polys[0].edges[0] = 1; + polys[0].edges[1] = 2; + polys[0].edges[2] = 3; + polys[0].edges[3] = 4; + polys[0].edges[4] = 5; + + polys[1].numEdges = 5; + polys[1].edges[0] = -5; + polys[1].edges[1] = 6; + polys[1].edges[2] = 7; + polys[1].edges[3] = 8; + polys[1].edges[4] = 9; + + polys[2].numEdges = 5; + polys[2].edges[0] = -8; + polys[2].edges[1] = 10; + polys[2].edges[2] = 11; + polys[2].edges[3] = 12; + polys[2].edges[4] = 13; + + polys[3].numEdges = 5; + polys[3].edges[0] = 14; + polys[3].edges[1] = 15; + polys[3].edges[2] = 16; + polys[3].edges[3] = 17; + polys[3].edges[4] = -3; + + polys[4].numEdges = 5; + polys[4].edges[0] = 18; + polys[4].edges[1] = 19; + polys[4].edges[2] = 20; + polys[4].edges[3] = 21; + polys[4].edges[4] = -12; + + polys[5].numEdges = 5; + polys[5].edges[0] = 22; + polys[5].edges[1] = 23; + polys[5].edges[2] = 24; + polys[5].edges[3] = -16; + polys[5].edges[4] = 25; + + polys[6].numEdges = 5; + polys[6].edges[0] = -9; + polys[6].edges[1] = -13; + polys[6].edges[2] = -21; + polys[6].edges[3] = 26; + polys[6].edges[4] = -1; + + polys[7].numEdges = 5; + polys[7].edges[0] = -26; + polys[7].edges[1] = -20; + polys[7].edges[2] = 27; + polys[7].edges[3] = -14; + polys[7].edges[4] = -2; + + polys[8].numEdges = 5; + polys[8].edges[0] = -4; + polys[8].edges[1] = -17; + polys[8].edges[2] = -24; + polys[8].edges[3] = 28; + polys[8].edges[4] = -6; + + polys[9].numEdges = 5; + polys[9].edges[0] = -23; + polys[9].edges[1] = 29; + polys[9].edges[2] = -10; + polys[9].edges[3] = -7; + polys[9].edges[4] = -28; + + polys[10].numEdges = 5; + polys[10].edges[0] = -25; + polys[10].edges[1] = -15; + polys[10].edges[2] = -27; + polys[10].edges[3] = -19; + polys[10].edges[4] = 30; + + polys[11].numEdges = 5; + polys[11].edges[0] = -30; + polys[11].edges[1] = -18; + polys[11].edges[2] = -11; + polys[11].edges[3] = -29; + polys[11].edges[4] = -22; + + // convex model + isConvex = true; +} + +/* +============ +idTraceModel::SetupCylinder +============ +*/ +void idTraceModel::SetupCylinder( const idBounds &cylBounds, const int numSides ) { + int i, n, ii, n2; + float angle; + idVec3 halfSize; + + n = numSides; + if ( n < 3 ) { + n = 3; + } + if ( n * 2 > MAX_TRACEMODEL_VERTS ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many vertices\n" ); + n = MAX_TRACEMODEL_VERTS / 2; + } + if ( n * 3 > MAX_TRACEMODEL_EDGES ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many sides\n" ); + n = MAX_TRACEMODEL_EDGES / 3; + } + if ( n + 2 > MAX_TRACEMODEL_POLYS ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many polygons\n" ); + n = MAX_TRACEMODEL_POLYS - 2; + } + + type = TRM_CYLINDER; + numVerts = n * 2; + numEdges = n * 3; + numPolys = n + 2; + offset = ( cylBounds[0] + cylBounds[1] ) * 0.5f; + halfSize = cylBounds[1] - offset; + for ( i = 0; i < n; i++ ) { + // verts + angle = idMath::TWO_PI * i / n; + verts[i].x = cos( angle ) * halfSize.x + offset.x; + verts[i].y = sin( angle ) * halfSize.y + offset.y; + verts[i].z = -halfSize.z + offset.z; + verts[n+i].x = verts[i].x; + verts[n+i].y = verts[i].y; + verts[n+i].z = halfSize.z + offset.z; + // edges + ii = i + 1; + n2 = n << 1; + edges[ii].v[0] = i; + edges[ii].v[1] = ii % n; + edges[n+ii].v[0] = edges[ii].v[0] + n; + edges[n+ii].v[1] = edges[ii].v[1] + n; + edges[n2+ii].v[0] = i; + edges[n2+ii].v[1] = n + i; + // vertical polygon edges + polys[i].numEdges = 4; + polys[i].edges[0] = ii; + polys[i].edges[1] = n2 + (ii % n) + 1; + polys[i].edges[2] = -(n + ii); + polys[i].edges[3] = -(n2 + ii); + // bottom and top polygon edges + polys[n].edges[i] = -(n - i); + polys[n+1].edges[i] = n + ii; + } + // bottom and top polygon numEdges + polys[n].numEdges = n; + polys[n+1].numEdges = n; + // polygons + for ( i = 0; i < n; i++ ) { + // vertical polygon plane + polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n+i] - verts[i] ); + polys[i].normal.Normalize(); + polys[i].dist = polys[i].normal * verts[i]; + // vertical polygon bounds + polys[i].bounds.Clear(); + polys[i].bounds.AddPoint( verts[i] ); + polys[i].bounds.AddPoint( verts[(i+1)%n] ); + polys[i].bounds[0][2] = -halfSize.z + offset.z; + polys[i].bounds[1][2] = halfSize.z + offset.z; + } + // bottom and top polygon plane + polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); + polys[n].dist = -cylBounds[0][2]; + polys[n+1].normal.Set( 0.0f, 0.0f, 1.0f ); + polys[n+1].dist = cylBounds[1][2]; + // trm bounds + bounds = cylBounds; + // bottom and top polygon bounds + polys[n].bounds = bounds; + polys[n].bounds[1][2] = bounds[0][2]; + polys[n+1].bounds = bounds; + polys[n+1].bounds[0][2] = bounds[1][2]; + // convex model + isConvex = true; + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::SetupCylinder + + The origin is placed at the center of the cylinder. +============ +*/ +void idTraceModel::SetupCylinder( const float height, const float width, const int numSides ) { + idBounds cylBounds; + float halfHeight, halfWidth; + + halfHeight = height * 0.5f; + halfWidth = width * 0.5f; + cylBounds[0].Set( -halfWidth, -halfWidth, -halfHeight ); + cylBounds[1].Set( halfWidth, halfWidth, halfHeight ); + SetupCylinder( cylBounds, numSides ); +} + +/* +============ +idTraceModel::SetupCone +============ +*/ +void idTraceModel::SetupCone( const idBounds &coneBounds, const int numSides ) { + int i, n, ii; + float angle; + idVec3 halfSize; + + n = numSides; + if ( n < 2 ) { + n = 3; + } + if ( n + 1 > MAX_TRACEMODEL_VERTS ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many vertices\n" ); + n = MAX_TRACEMODEL_VERTS - 1; + } + if ( n * 2 > MAX_TRACEMODEL_EDGES ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many edges\n" ); + n = MAX_TRACEMODEL_EDGES / 2; + } + if ( n + 1 > MAX_TRACEMODEL_POLYS ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many polygons\n" ); + n = MAX_TRACEMODEL_POLYS - 1; + } + + type = TRM_CONE; + numVerts = n + 1; + numEdges = n * 2; + numPolys = n + 1; + offset = ( coneBounds[0] + coneBounds[1] ) * 0.5f; + halfSize = coneBounds[1] - offset; + verts[n].Set( 0.0f, 0.0f, halfSize.z + offset.z ); + for ( i = 0; i < n; i++ ) { + // verts + angle = idMath::TWO_PI * i / n; + verts[i].x = cos( angle ) * halfSize.x + offset.x; + verts[i].y = sin( angle ) * halfSize.y + offset.y; + verts[i].z = -halfSize.z + offset.z; + // edges + ii = i + 1; + edges[ii].v[0] = i; + edges[ii].v[1] = ii % n; + edges[n+ii].v[0] = i; + edges[n+ii].v[1] = n; + // vertical polygon edges + polys[i].numEdges = 3; + polys[i].edges[0] = ii; + polys[i].edges[1] = n + (ii % n) + 1; + polys[i].edges[2] = -(n + ii); + // bottom polygon edges + polys[n].edges[i] = -(n - i); + } + // bottom polygon numEdges + polys[n].numEdges = n; + + // polygons + for ( i = 0; i < n; i++ ) { + // polygon plane + polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n] - verts[i] ); + polys[i].normal.Normalize(); + polys[i].dist = polys[i].normal * verts[i]; + // polygon bounds + polys[i].bounds.Clear(); + polys[i].bounds.AddPoint( verts[i] ); + polys[i].bounds.AddPoint( verts[(i+1)%n] ); + polys[i].bounds.AddPoint( verts[n] ); + } + // bottom polygon plane + polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); + polys[n].dist = -coneBounds[0][2]; + // trm bounds + bounds = coneBounds; + // bottom polygon bounds + polys[n].bounds = bounds; + polys[n].bounds[1][2] = bounds[0][2]; + // convex model + isConvex = true; + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::SetupCone + + The origin is placed at the apex of the cone. +============ +*/ +void idTraceModel::SetupCone( const float height, const float width, const int numSides ) { + idBounds coneBounds; + float halfWidth; + + halfWidth = width * 0.5f; + coneBounds[0].Set( -halfWidth, -halfWidth, -height ); + coneBounds[1].Set( halfWidth, halfWidth, 0.0f ); + SetupCone( coneBounds, numSides ); +} + +/* +============ +idTraceModel::SetupBone + + The origin is placed at the center of the bone. +============ +*/ +void idTraceModel::SetupBone( const float length, const float width ) { + int i, j, edgeNum; + float halfLength = length * 0.5f; + + if ( type != TRM_BONE ) { + InitBone(); + } + // offset to center + offset.Set( 0.0f, 0.0f, 0.0f ); + // set vertices + verts[0].Set( 0.0f, 0.0f, -halfLength ); + verts[1].Set( 0.0f, width * -0.5f, 0.0f ); + verts[2].Set( width * 0.5f, width * 0.25f, 0.0f ); + verts[3].Set( width * -0.5f, width * 0.25f, 0.0f ); + verts[4].Set( 0.0f, 0.0f, halfLength ); + // set bounds + bounds[0].Set( width * -0.5f, width * -0.5f, -halfLength ); + bounds[1].Set( width * 0.5f, width * 0.25f, halfLength ); + // poly plane normals + polys[0].normal = ( verts[2] - verts[0] ).Cross( verts[1] - verts[0] ); + polys[0].normal.Normalize(); + polys[2].normal.Set( -polys[0].normal[0], polys[0].normal[1], polys[0].normal[2] ); + polys[3].normal.Set( polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); + polys[5].normal.Set( -polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); + polys[1].normal = (verts[3] - verts[0]).Cross(verts[2] - verts[0]); + polys[1].normal.Normalize(); + polys[4].normal.Set( polys[1].normal[0], polys[1].normal[1], -polys[1].normal[2] ); + // poly plane distances + for ( i = 0; i < 6; i++ ) { + polys[i].dist = polys[i].normal * verts[ edges[ abs(polys[i].edges[0]) ].v[0] ]; + polys[i].bounds.Clear(); + for ( j = 0; j < 3; j++ ) { + edgeNum = polys[i].edges[ j ]; + polys[i].bounds.AddPoint( verts[ edges[abs(edgeNum)].v[edgeNum < 0] ] ); + } + } + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::InitBone + + Initialize size independent bone. +============ +*/ +void idTraceModel::InitBone( void ) { + int i; + + type = TRM_BONE; + numVerts = 5; + numEdges = 9; + numPolys = 6; + + // set bone edges + for ( i = 0; i < 3; i++ ) { + edges[ i + 1 ].v[0] = 0; + edges[ i + 1 ].v[1] = i + 1; + edges[ i + 4 ].v[0] = 1 + i; + edges[ i + 4 ].v[1] = 1 + ((i + 1) % 3); + edges[ i + 7 ].v[0] = i + 1; + edges[ i + 7 ].v[1] = 4; + } + + // all edges of a polygon go counter clockwise + polys[0].numEdges = 3; + polys[0].edges[0] = 2; + polys[0].edges[1] = -4; + polys[0].edges[2] = -1; + + polys[1].numEdges = 3; + polys[1].edges[0] = 3; + polys[1].edges[1] = -5; + polys[1].edges[2] = -2; + + polys[2].numEdges = 3; + polys[2].edges[0] = 1; + polys[2].edges[1] = -6; + polys[2].edges[2] = -3; + + polys[3].numEdges = 3; + polys[3].edges[0] = 4; + polys[3].edges[1] = 8; + polys[3].edges[2] = -7; + + polys[4].numEdges = 3; + polys[4].edges[0] = 5; + polys[4].edges[1] = 9; + polys[4].edges[2] = -8; + + polys[5].numEdges = 3; + polys[5].edges[0] = 6; + polys[5].edges[1] = 7; + polys[5].edges[2] = -9; + + // convex model + isConvex = true; +} + +/* +============ +idTraceModel::SetupPolygon +============ +*/ +void idTraceModel::SetupPolygon( const idVec3 *v, const int count ) { + int i, j; + idVec3 mid; + + type = TRM_POLYGON; + numVerts = count; + // times three because we need to be able to turn the polygon into a volume + if ( numVerts * 3 > MAX_TRACEMODEL_EDGES ) { + idLib::common->Printf( "WARNING: idTraceModel::SetupPolygon: too many vertices\n" ); + numVerts = MAX_TRACEMODEL_EDGES / 3; + } + + numEdges = numVerts; + numPolys = 2; + // set polygon planes + polys[0].numEdges = numEdges; + polys[0].normal = ( v[1] - v[0] ).Cross( v[2] - v[0] ); + polys[0].normal.Normalize(); + polys[0].dist = polys[0].normal * v[0]; + polys[1].numEdges = numEdges; + polys[1].normal = -polys[0].normal; + polys[1].dist = -polys[0].dist; + // setup verts, edges and polygons + polys[0].bounds.Clear(); + mid = vec3_origin; + for ( i = 0, j = 1; i < numVerts; i++, j++ ) { + if ( j >= numVerts ) { + j = 0; + } + verts[i] = v[i]; + edges[i+1].v[0] = i; + edges[i+1].v[1] = j; + edges[i+1].normal = polys[0].normal.Cross( v[i] - v[j] ); + edges[i+1].normal.Normalize(); + polys[0].edges[i] = i + 1; + polys[1].edges[i] = -(numVerts - i); + polys[0].bounds.AddPoint( verts[i] ); + mid += v[i]; + } + polys[1].bounds = polys[0].bounds; + // offset to center + offset = mid * (1.0f / numVerts); + // total bounds + bounds = polys[0].bounds; + // considered non convex because the model has no volume + isConvex = false; +} + +/* +============ +idTraceModel::SetupPolygon +============ +*/ +void idTraceModel::SetupPolygon( const idWinding &w ) { + int i; + idVec3 *verts; + + verts = (idVec3 *) _alloca16( w.GetNumPoints() * sizeof( idVec3 ) ); + for ( i = 0; i < w.GetNumPoints(); i++ ) { + verts[i] = w[i].ToVec3(); + } + SetupPolygon( verts, w.GetNumPoints() ); +} + +/* +============ +idTraceModel::VolumeFromPolygon +============ +*/ +void idTraceModel::VolumeFromPolygon( idTraceModel &trm, float thickness ) const { + int i; + + trm = *this; + trm.type = TRM_POLYGONVOLUME; + trm.numVerts = numVerts * 2; + trm.numEdges = numEdges * 3; + trm.numPolys = numEdges + 2; + for ( i = 0; i < numEdges; i++ ) { + trm.verts[ numVerts + i ] = verts[i] - thickness * polys[0].normal; + trm.edges[ numEdges + i + 1 ].v[0] = numVerts + i; + trm.edges[ numEdges + i + 1 ].v[1] = numVerts + (i+1) % numVerts; + trm.edges[ numEdges * 2 + i + 1 ].v[0] = i; + trm.edges[ numEdges * 2 + i + 1 ].v[1] = numVerts + i; + trm.polys[1].edges[i] = -(numEdges + i + 1); + trm.polys[2+i].numEdges = 4; + trm.polys[2+i].edges[0] = -(i + 1); + trm.polys[2+i].edges[1] = numEdges*2 + i + 1; + trm.polys[2+i].edges[2] = numEdges + i + 1; + trm.polys[2+i].edges[3] = -(numEdges*2 + (i+1) % numEdges + 1); + trm.polys[2+i].normal = (verts[(i + 1) % numVerts] - verts[i]).Cross( polys[0].normal ); + trm.polys[2+i].normal.Normalize(); + trm.polys[2+i].dist = trm.polys[2+i].normal * verts[i]; + } + trm.polys[1].dist = trm.polys[1].normal * trm.verts[ numEdges ]; + + trm.GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::GenerateEdgeNormals +============ +*/ +#define SHARP_EDGE_DOT -0.7f + +int idTraceModel::GenerateEdgeNormals( void ) { + int i, j, edgeNum, numSharpEdges; + float dot; + idVec3 dir; + traceModelPoly_t *poly; + traceModelEdge_t *edge; + + for ( i = 0; i <= numEdges; i++ ) { + edges[i].normal.Zero(); + } + + numSharpEdges = 0; + for ( i = 0; i < numPolys; i++ ) { + poly = polys + i; + for ( j = 0; j < poly->numEdges; j++ ) { + edgeNum = poly->edges[j]; + edge = edges + abs( edgeNum ); + if ( edge->normal[0] == 0.0f && edge->normal[1] == 0.0f && edge->normal[2] == 0.0f ) { + edge->normal = poly->normal; + } + else { + dot = edge->normal * poly->normal; + // if the two planes make a very sharp edge + if ( dot < SHARP_EDGE_DOT ) { + // max length normal pointing outside both polygons + dir = verts[ edge->v[edgeNum > 0]] - verts[ edge->v[edgeNum < 0]]; + edge->normal = edge->normal.Cross( dir ) + poly->normal.Cross( -dir ); + edge->normal *= ( 0.5f / ( 0.5f + 0.5f * SHARP_EDGE_DOT ) ) / edge->normal.Length(); + numSharpEdges++; + } + else { + edge->normal = ( 0.5f / ( 0.5f + 0.5f * dot ) ) * ( edge->normal + poly->normal ); + } + } + } + } + return numSharpEdges; +} + +/* +============ +idTraceModel::Translate +============ +*/ +void idTraceModel::Translate( const idVec3 &translation ) { + int i; + + for ( i = 0; i < numVerts; i++ ) { + verts[i] += translation; + } + for ( i = 0; i < numPolys; i++ ) { + polys[i].dist += polys[i].normal * translation; + polys[i].bounds[0] += translation; + polys[i].bounds[1] += translation; + } + offset += translation; + bounds[0] += translation; + bounds[1] += translation; +} + +/* +============ +idTraceModel::Rotate +============ +*/ +void idTraceModel::Rotate( const idMat3 &rotation, bool isRotationOrthogonal ) { + int i, j, edgeNum; + + idMat3 normalRotation = rotation; + if (!isRotationOrthogonal) { + bool nonSingular = normalRotation.InverseSelf(); + nonSingular; //eliminates "never used" warning in release + assert(nonSingular); + normalRotation.TransposeSelf(); + } + + for ( i = 0; i < numVerts; i++ ) { + verts[i] *= rotation; + } + + bounds.Clear(); + for ( i = 0; i < numPolys; i++ ) { + polys[i].normal *= normalRotation; + if (!isRotationOrthogonal) + polys[i].normal.Normalize(); + polys[i].bounds.Clear(); + edgeNum = 0; + for ( j = 0; j < polys[i].numEdges; j++ ) { + edgeNum = polys[i].edges[j]; + polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); + } + polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; + bounds += polys[i].bounds; + } + + GenerateEdgeNormals(); +} + +/* +============ +idTraceModel::Scale +============ +*/ +void idTraceModel::Scale( const idVec3 &scale ) { + int i, j, edgeNum, d; + const float *scalePtr = scale.ToFloatPtr(); + for ( d = 0; d < 3; d++ ) + assert(scalePtr[d] != 0.0f); + + for ( i = 0; i < numVerts; i++ ) { + for ( d = 0; d < 3; d++ ) + verts[i].ToFloatPtr()[d] *= scalePtr[d]; + } + + bounds.Clear(); + for ( i = 0; i < numPolys; i++ ) { + for ( d = 0; d < 3; d++ ) + polys[i].normal.ToFloatPtr()[d] /= scalePtr[d]; + polys[i].normal.Normalize(); + polys[i].bounds.Clear(); + edgeNum = 0; + for ( j = 0; j < polys[i].numEdges; j++ ) { + edgeNum = polys[i].edges[j]; + polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); + } + polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; + bounds += polys[i].bounds; + } + + GenerateEdgeNormals(); +} + +/* Old code, commented out tels 2011-01-13 +============ +idTraceModel::Rotate +============ +void idTraceModel::Rotate( const idMat3 &rotation ) { + int i, j, edgeNum; + + for ( i = 0; i < numVerts; i++ ) { + verts[i] *= rotation; + } + + bounds.Clear(); + for ( i = 0; i < numPolys; i++ ) { + polys[i].normal *= rotation; + polys[i].bounds.Clear(); + edgeNum = 0; + for ( j = 0; j < polys[i].numEdges; j++ ) { + edgeNum = polys[i].edges[j]; + polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); + } + polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; + bounds += polys[i].bounds; + } + + GenerateEdgeNormals(); +} +*/ + +/* +============ +idTraceModel::Shrink +============ +*/ +void idTraceModel::Shrink( const float m ) { + int i, j, edgeNum; + traceModelEdge_t *edge; + idVec3 dir; + + if ( type == TRM_POLYGON ) { + for ( i = 0; i < numEdges; i++ ) { + edgeNum = polys[0].edges[i]; + edge = &edges[abs(edgeNum)]; + dir = verts[ edge->v[ INTSIGNBITSET(edgeNum) ] ] - verts[ edge->v[ INTSIGNBITNOTSET(edgeNum) ] ]; + if ( dir.Normalize() < 2.0f * m ) { + continue; + } + dir *= m; + verts[ edge->v[ 0 ] ] -= dir; + verts[ edge->v[ 1 ] ] += dir; + } + return; + } + + for ( i = 0; i < numPolys; i++ ) { + polys[i].dist -= m; + + for ( j = 0; j < polys[i].numEdges; j++ ) { + edgeNum = polys[i].edges[j]; + edge = &edges[abs(edgeNum)]; + verts[ edge->v[ INTSIGNBITSET(edgeNum) ] ] -= polys[i].normal * m; + } + } +} + +/* +============ +idTraceModel::Compare +============ +*/ +bool idTraceModel::Compare( const idTraceModel &trm ) const { + int i; + + if ( type != trm.type || numVerts != trm.numVerts || + numEdges != trm.numEdges || numPolys != trm.numPolys ) { + return false; + } + if ( bounds != trm.bounds || offset != trm.offset ) { + return false; + } + + switch( type ) { + case TRM_INVALID: + case TRM_BOX: + case TRM_OCTAHEDRON: + case TRM_DODECAHEDRON: + case TRM_CYLINDER: + case TRM_CONE: + break; + case TRM_BONE: + case TRM_POLYGON: + case TRM_POLYGONVOLUME: + case TRM_CUSTOM: + for ( i = 0; i < trm.numVerts; i++ ) { + if ( verts[i] != trm.verts[i] ) { + return false; + } + } + break; + } + return true; +} + +/* +============ +idTraceModel::GetPolygonArea +============ +*/ +float idTraceModel::GetPolygonArea( int polyNum ) const { + int i; + idVec3 base, v1, v2, cross; + float total; + const traceModelPoly_t *poly; + + if ( polyNum < 0 || polyNum >= numPolys ) { + return 0.0f; + } + poly = &polys[polyNum]; + total = 0.0f; + base = verts[ edges[ abs(poly->edges[0]) ].v[ INTSIGNBITSET( poly->edges[0] ) ] ]; + for ( i = 0; i < poly->numEdges; i++ ) { + v1 = verts[ edges[ abs(poly->edges[i]) ].v[ INTSIGNBITSET( poly->edges[i] ) ] ] - base; + v2 = verts[ edges[ abs(poly->edges[i]) ].v[ INTSIGNBITNOTSET( poly->edges[i] ) ] ] - base; + cross = v1.Cross( v2 ); + total += cross.Length(); + } + return total * 0.5f; +} + +/* +============ +idTraceModel::GetOrderedSilhouetteEdges +============ +*/ +int idTraceModel::GetOrderedSilhouetteEdges( const int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1], int silEdges[MAX_TRACEMODEL_EDGES] ) const { + int i, j, edgeNum, numSilEdges, nextSilVert; + int unsortedSilEdges[MAX_TRACEMODEL_EDGES]; + + numSilEdges = 0; + for ( i = 1; i <= numEdges; i++ ) { + if ( edgeIsSilEdge[i] ) { + unsortedSilEdges[numSilEdges++] = i; + } + } + + silEdges[0] = unsortedSilEdges[0]; + unsortedSilEdges[0] = -1; + nextSilVert = edges[silEdges[0]].v[0]; + for ( i = 1; i < numSilEdges; i++ ) { + for ( j = 1; j < numSilEdges; j++ ) { + edgeNum = unsortedSilEdges[j]; + if ( edgeNum >= 0 ) { + if ( edges[edgeNum].v[0] == nextSilVert ) { + nextSilVert = edges[edgeNum].v[1]; + silEdges[i] = edgeNum; + break; + } + if ( edges[edgeNum].v[1] == nextSilVert ) { + nextSilVert = edges[edgeNum].v[0]; + silEdges[i] = -edgeNum; + break; + } + } + } + if ( j >= numSilEdges ) { + silEdges[i] = 1; // shouldn't happen + } + unsortedSilEdges[j] = -1; + } + return numSilEdges; +} + +/* +============ +idTraceModel::GetProjectionSilhouetteEdges +============ +*/ +int idTraceModel::GetProjectionSilhouetteEdges( const idVec3 &projectionOrigin, int silEdges[MAX_TRACEMODEL_EDGES] ) const { + int i, j, edgeNum; + int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1]; + const traceModelPoly_t *poly; + idVec3 dir; + + memset( edgeIsSilEdge, 0, sizeof( edgeIsSilEdge ) ); + + for ( i = 0; i < numPolys; i++ ) { + poly = &polys[i]; + edgeNum = poly->edges[0]; + dir = verts[ edges[abs(edgeNum)].v[ INTSIGNBITSET(edgeNum) ] ] - projectionOrigin; + if ( dir * poly->normal < 0.0f ) { + for ( j = 0; j < poly->numEdges; j++ ) { + edgeNum = poly->edges[j]; + edgeIsSilEdge[abs(edgeNum)] ^= 1; + } + } + } + + return GetOrderedSilhouetteEdges( edgeIsSilEdge, silEdges ); +} + +/* +============ +idTraceModel::GetParallelProjectionSilhouetteEdges +============ +*/ +int idTraceModel::GetParallelProjectionSilhouetteEdges( const idVec3 &projectionDir, int silEdges[MAX_TRACEMODEL_EDGES] ) const { + int i, j, edgeNum; + int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1]; + const traceModelPoly_t *poly; + + memset( edgeIsSilEdge, 0, sizeof( edgeIsSilEdge ) ); + + for ( i = 0; i < numPolys; i++ ) { + poly = &polys[i]; + if ( projectionDir * poly->normal < 0.0f ) { + for ( j = 0; j < poly->numEdges; j++ ) { + edgeNum = poly->edges[j]; + edgeIsSilEdge[abs(edgeNum)] ^= 1; + } + } + } + + return GetOrderedSilhouetteEdges( edgeIsSilEdge, silEdges ); +} + + +/* + + credits to Brian Mirtich for his paper "Fast and Accurate Computation of Polyhedral Mass Properties" + +*/ + +typedef struct projectionIntegrals_s { + float P1; + float Pa, Pb; + float Paa, Pab, Pbb; + float Paaa, Paab, Pabb, Pbbb; +} projectionIntegrals_t; + +/* +============ +idTraceModel::ProjectionIntegrals +============ +*/ +void idTraceModel::ProjectionIntegrals( int polyNum, int a, int b, struct projectionIntegrals_s &integrals ) const { + const traceModelPoly_t *poly; + int i, edgeNum; + idVec3 v1, v2; + float a0, a1, da; + float b0, b1, db; + float a0_2, a0_3, a0_4, b0_2, b0_3, b0_4; + float a1_2, a1_3, b1_2, b1_3; + float C1, Ca, Caa, Caaa, Cb, Cbb, Cbbb; + float Cab, Kab, Caab, Kaab, Cabb, Kabb; + + memset(&integrals, 0, sizeof(projectionIntegrals_t)); + poly = &polys[polyNum]; + for ( i = 0; i < poly->numEdges; i++ ) { + edgeNum = poly->edges[i]; + v1 = verts[ edges[ abs(edgeNum) ].v[ edgeNum < 0 ] ]; + v2 = verts[ edges[ abs(edgeNum) ].v[ edgeNum > 0 ] ]; + a0 = v1[a]; + b0 = v1[b]; + a1 = v2[a]; + b1 = v2[b]; + da = a1 - a0; + db = b1 - b0; + a0_2 = a0 * a0; + a0_3 = a0_2 * a0; + a0_4 = a0_3 * a0; + b0_2 = b0 * b0; + b0_3 = b0_2 * b0; + b0_4 = b0_3 * b0; + a1_2 = a1 * a1; + a1_3 = a1_2 * a1; + b1_2 = b1 * b1; + b1_3 = b1_2 * b1; + + C1 = a1 + a0; + Ca = a1 * C1 + a0_2; + Caa = a1 * Ca + a0_3; + Caaa = a1 * Caa + a0_4; + Cb = b1 * (b1 + b0) + b0_2; + Cbb = b1 * Cb + b0_3; + Cbbb = b1 * Cbb + b0_4; + Cab = 3 * a1_2 + 2 * a1 * a0 + a0_2; + Kab = a1_2 + 2 * a1 * a0 + 3 * a0_2; + Caab = a0 * Cab + 4 * a1_3; + Kaab = a1 * Kab + 4 * a0_3; + Cabb = 4 * b1_3 + 3 * b1_2 * b0 + 2 * b1 * b0_2 + b0_3; + Kabb = b1_3 + 2 * b1_2 * b0 + 3 * b1 * b0_2 + 4 * b0_3; + + integrals.P1 += db * C1; + integrals.Pa += db * Ca; + integrals.Paa += db * Caa; + integrals.Paaa += db * Caaa; + integrals.Pb += da * Cb; + integrals.Pbb += da * Cbb; + integrals.Pbbb += da * Cbbb; + integrals.Pab += db * (b1 * Cab + b0 * Kab); + integrals.Paab += db * (b1 * Caab + b0 * Kaab); + integrals.Pabb += da * (a1 * Cabb + a0 * Kabb); + } + + integrals.P1 *= (1.0f / 2.0f); + integrals.Pa *= (1.0f / 6.0f); + integrals.Paa *= (1.0f / 12.0f); + integrals.Paaa *= (1.0f / 20.0f); + integrals.Pb *= (1.0f / -6.0f); + integrals.Pbb *= (1.0f / -12.0f); + integrals.Pbbb *= (1.0f / -20.0f); + integrals.Pab *= (1.0f / 24.0f); + integrals.Paab *= (1.0f / 60.0f); + integrals.Pabb *= (1.0f / -60.0f); +} + +typedef struct polygonIntegrals_s { + float Fa, Fb, Fc; + float Faa, Fbb, Fcc; + float Faaa, Fbbb, Fccc; + float Faab, Fbbc, Fcca; +} polygonIntegrals_t; + +/* +============ +idTraceModel::PolygonIntegrals +============ +*/ +void idTraceModel::PolygonIntegrals( int polyNum, int a, int b, int c, struct polygonIntegrals_s &integrals ) const { + projectionIntegrals_t pi; + idVec3 n; + float w; + float k1, k2, k3, k4; + + ProjectionIntegrals( polyNum, a, b, pi ); + + n = polys[polyNum].normal; + w = -polys[polyNum].dist; + k1 = 1 / n[c]; + k2 = k1 * k1; + k3 = k2 * k1; + k4 = k3 * k1; + + integrals.Fa = k1 * pi.Pa; + integrals.Fb = k1 * pi.Pb; + integrals.Fc = -k2 * (n[a] * pi.Pa + n[b] * pi.Pb + w * pi.P1); + + integrals.Faa = k1 * pi.Paa; + integrals.Fbb = k1 * pi.Pbb; + integrals.Fcc = k3 * (Square(n[a]) * pi.Paa + 2 * n[a] * n[b] * pi.Pab + Square(n[b]) * pi.Pbb + + w * (2 * (n[a] * pi.Pa + n[b] * pi.Pb) + w * pi.P1)); + + integrals.Faaa = k1 * pi.Paaa; + integrals.Fbbb = k1 * pi.Pbbb; + integrals.Fccc = -k4 * (Cube(n[a]) * pi.Paaa + 3 * Square(n[a]) * n[b] * pi.Paab + + 3 * n[a] * Square(n[b]) * pi.Pabb + Cube(n[b]) * pi.Pbbb + + 3 * w * (Square(n[a]) * pi.Paa + 2 * n[a] * n[b] * pi.Pab + Square(n[b]) * pi.Pbb) + + w * w * (3 * (n[a] * pi.Pa + n[b] * pi.Pb) + w * pi.P1)); + + integrals.Faab = k1 * pi.Paab; + integrals.Fbbc = -k2 * (n[a] * pi.Pabb + n[b] * pi.Pbbb + w * pi.Pbb); + integrals.Fcca = k3 * (Square(n[a]) * pi.Paaa + 2 * n[a] * n[b] * pi.Paab + Square(n[b]) * pi.Pabb + + w * (2 * (n[a] * pi.Paa + n[b] * pi.Pab) + w * pi.Pa)); +} + +typedef struct volumeIntegrals_s { + float T0; + idVec3 T1; + idVec3 T2; + idVec3 TP; +} volumeIntegrals_t; + +/* +============ +idTraceModel::VolumeIntegrals +============ +*/ +void idTraceModel::VolumeIntegrals( struct volumeIntegrals_s &integrals ) const { + const traceModelPoly_t *poly; + polygonIntegrals_t pi; + int i, a, b, c; + float nx, ny, nz; + + memset( &integrals, 0, sizeof(volumeIntegrals_t) ); + for ( i = 0; i < numPolys; i++ ) { + poly = &polys[i]; + + nx = idMath::Fabs( poly->normal[0] ); + ny = idMath::Fabs( poly->normal[1] ); + nz = idMath::Fabs( poly->normal[2] ); + if ( nx > ny && nx > nz ) { + c = 0; + } + else { + c = (ny > nz) ? 1 : 2; + } + a = (c + 1) % 3; + b = (a + 1) % 3; + + PolygonIntegrals( i, a, b, c, pi ); + + integrals.T0 += poly->normal[0] * ((a == 0) ? pi.Fa : ((b == 0) ? pi.Fb : pi.Fc)); + + integrals.T1[a] += poly->normal[a] * pi.Faa; + integrals.T1[b] += poly->normal[b] * pi.Fbb; + integrals.T1[c] += poly->normal[c] * pi.Fcc; + integrals.T2[a] += poly->normal[a] * pi.Faaa; + integrals.T2[b] += poly->normal[b] * pi.Fbbb; + integrals.T2[c] += poly->normal[c] * pi.Fccc; + integrals.TP[a] += poly->normal[a] * pi.Faab; + integrals.TP[b] += poly->normal[b] * pi.Fbbc; + integrals.TP[c] += poly->normal[c] * pi.Fcca; + } + + integrals.T1 *= 0.5f; + integrals.T2 *= (1.0f / 3.0f); + integrals.TP *= 0.5f; +} + +/* +============ +idTraceModel::GetMassProperties +============ +*/ +void idTraceModel::GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const { + volumeIntegrals_t integrals; + + // if polygon trace model + if ( type == TRM_POLYGON ) { + idTraceModel trm; + + VolumeFromPolygon( trm, 1.0f ); + trm.GetMassProperties( density, mass, centerOfMass, inertiaTensor ); + return; + } + + VolumeIntegrals( integrals ); + + // if very small or no volume + if ( integrals.T0 < 0.1f ) // grayman #2283 - this was a comparison to 0.0f, which allows very small numbers to wreak havoc + { + mass = 1.0f; + centerOfMass.Zero(); + inertiaTensor.Identity(); + return; + } + + // mass of model + mass = density * integrals.T0; + // center of mass + centerOfMass = integrals.T1 / integrals.T0; + // compute inertia tensor + inertiaTensor[0][0] = density * (integrals.T2[1] + integrals.T2[2]); + inertiaTensor[1][1] = density * (integrals.T2[2] + integrals.T2[0]); + inertiaTensor[2][2] = density * (integrals.T2[0] + integrals.T2[1]); + inertiaTensor[0][1] = inertiaTensor[1][0] = - density * integrals.TP[0]; + inertiaTensor[1][2] = inertiaTensor[2][1] = - density * integrals.TP[1]; + inertiaTensor[2][0] = inertiaTensor[0][2] = - density * integrals.TP[2]; + // translate inertia tensor to center of mass + inertiaTensor[0][0] -= mass * (centerOfMass[1]*centerOfMass[1] + centerOfMass[2]*centerOfMass[2]); + inertiaTensor[1][1] -= mass * (centerOfMass[2]*centerOfMass[2] + centerOfMass[0]*centerOfMass[0]); + inertiaTensor[2][2] -= mass * (centerOfMass[0]*centerOfMass[0] + centerOfMass[1]*centerOfMass[1]); + inertiaTensor[0][1] = inertiaTensor[1][0] += mass * centerOfMass[0] * centerOfMass[1]; + inertiaTensor[1][2] = inertiaTensor[2][1] += mass * centerOfMass[1] * centerOfMass[2]; + inertiaTensor[2][0] = inertiaTensor[0][2] += mass * centerOfMass[2] * centerOfMass[0]; +} diff --git a/idlib/geometry/TraceModel.h b/idlib/geometry/TraceModel.h new file mode 100644 index 000000000..99d7a7b51 --- /dev/null +++ b/idlib/geometry/TraceModel.h @@ -0,0 +1,183 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __TRACEMODEL_H__ +#define __TRACEMODEL_H__ + +/* +=============================================================================== + + A trace model is an arbitrary polygonal model which is used by the + collision detection system to find collisions, contacts or the contents + of a volume. For collision detection speed reasons the number of vertices + and edges are limited. The trace model can have any shape. However convex + models are usually preferred. + +=============================================================================== +*/ + +class idVec3; +class idMat3; +class idBounds; + +// trace model type +typedef enum { + TRM_INVALID, // invalid trm + TRM_BOX, // box + TRM_OCTAHEDRON, // octahedron + TRM_DODECAHEDRON, // dodecahedron + TRM_CYLINDER, // cylinder approximation + TRM_CONE, // cone approximation + TRM_BONE, // two tetrahedrons attached to each other + TRM_POLYGON, // arbitrary convex polygon + TRM_POLYGONVOLUME, // volume for arbitrary convex polygon + TRM_CUSTOM // loaded from map model or ASE/LWO +} traceModel_t; + +// these are bit cache limits +#define MAX_TRACEMODEL_VERTS 32 +#define MAX_TRACEMODEL_EDGES 32 +#define MAX_TRACEMODEL_POLYS 16 +#define MAX_TRACEMODEL_POLYEDGES 16 + +typedef idVec3 traceModelVert_t; + +typedef struct { + int v[2]; + idVec3 normal; +} traceModelEdge_t; + +typedef struct { + idVec3 normal; + float dist; + idBounds bounds; + int numEdges; + int edges[MAX_TRACEMODEL_POLYEDGES]; +} traceModelPoly_t; + +class idTraceModel { + +public: + traceModel_t type; + int numVerts; + traceModelVert_t verts[MAX_TRACEMODEL_VERTS]; + int numEdges; + traceModelEdge_t edges[MAX_TRACEMODEL_EDGES+1]; + int numPolys; + traceModelPoly_t polys[MAX_TRACEMODEL_POLYS]; + idVec3 offset; // offset to center of model + idBounds bounds; // bounds of model + bool isConvex; // true when model is convex + +public: + idTraceModel( void ); + // axial bounding box + idTraceModel( const idBounds &boxBounds ); + // cylinder approximation + idTraceModel( const idBounds &cylBounds, const int numSides ); + // bone + idTraceModel( const float length, const float width ); + + // axial box + void SetupBox( const idBounds &boxBounds ); + void SetupBox( const float size ); + // octahedron + void SetupOctahedron( const idBounds &octBounds ); + void SetupOctahedron( const float size ); + // dodecahedron + void SetupDodecahedron( const idBounds &dodBounds ); + void SetupDodecahedron( const float size ); + // cylinder approximation + void SetupCylinder( const idBounds &cylBounds, const int numSides ); + void SetupCylinder( const float height, const float width, const int numSides ); + // cone approximation + void SetupCone( const idBounds &coneBounds, const int numSides ); + void SetupCone( const float height, const float width, const int numSides ); + // two tetrahedrons attached to each other + void SetupBone( const float length, const float width ); + // arbitrary convex polygon + void SetupPolygon( const idVec3 *v, const int count ); + void SetupPolygon( const idWinding &w ); + // generate edge normals + int GenerateEdgeNormals( void ); + // translate the trm + void Translate( const idVec3 &translation ); + // rotate the trm + // rotate the trm or apply non-singular linear transform + void Rotate( const idMat3 &rotation, bool isRotationOrthogonal = true ); + // scale the trm + void Scale( const idVec3 &scale ); + // shrink the model m units on all sides + void Shrink( const float m ); + // compare + bool Compare( const idTraceModel &trm ) const; + bool operator==( const idTraceModel &trm ) const; + bool operator!=( const idTraceModel &trm ) const; + // get the area of one of the polygons + float GetPolygonArea( int polyNum ) const; + // get the silhouette edges + int GetProjectionSilhouetteEdges( const idVec3 &projectionOrigin, int silEdges[MAX_TRACEMODEL_EDGES] ) const; + int GetParallelProjectionSilhouetteEdges( const idVec3 &projectionDir, int silEdges[MAX_TRACEMODEL_EDGES] ) const; + // calculate mass properties assuming an uniform density + void GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const; + +private: + void InitBox( void ); + void InitOctahedron( void ); + void InitDodecahedron( void ); + void InitBone( void ); + + void ProjectionIntegrals( int polyNum, int a, int b, struct projectionIntegrals_s &integrals ) const; + void PolygonIntegrals( int polyNum, int a, int b, int c, struct polygonIntegrals_s &integrals ) const; + void VolumeIntegrals( struct volumeIntegrals_s &integrals ) const; + void VolumeFromPolygon( idTraceModel &trm, float thickness ) const; + int GetOrderedSilhouetteEdges( const int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1], int silEdges[MAX_TRACEMODEL_EDGES] ) const; +}; + + +ID_INLINE idTraceModel::idTraceModel( void ) { + type = TRM_INVALID; + numVerts = numEdges = numPolys = 0; + bounds.Zero(); +} + +ID_INLINE idTraceModel::idTraceModel( const idBounds &boxBounds ) { + InitBox(); + SetupBox( boxBounds ); +} + +ID_INLINE idTraceModel::idTraceModel( const idBounds &cylBounds, const int numSides ) { + SetupCylinder( cylBounds, numSides ); +} + +ID_INLINE idTraceModel::idTraceModel( const float length, const float width ) { + InitBone(); + SetupBone( length, width ); +} + +ID_INLINE bool idTraceModel::operator==( const idTraceModel &trm ) const { + return Compare( trm ); +} + +ID_INLINE bool idTraceModel::operator!=( const idTraceModel &trm ) const { + return !Compare( trm ); +} + +#endif /* !__TRACEMODEL_H__ */ + diff --git a/idlib/geometry/Winding.cpp b/idlib/geometry/Winding.cpp new file mode 100644 index 000000000..3dd82e20e --- /dev/null +++ b/idlib/geometry/Winding.cpp @@ -0,0 +1,1592 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +//=============================================================== +// +// idWinding +// +//=============================================================== + +/* +============= +idWinding::ReAllocate +============= +*/ +bool idWinding::ReAllocate( int n, bool keep ) { + idVec5 *oldP; + + oldP = p; + n = (n+3) & ~3; // align up to multiple of four + p = new idVec5[n]; + if ( oldP ) { + if ( keep ) { + memcpy( p, oldP, numPoints * sizeof(p[0]) ); + } + delete[] oldP; + } + allocedSize = n; + + return true; +} + +/* +============= +idWinding::BaseForPlane +============= +*/ +void idWinding::BaseForPlane( const idVec3 &normal, const float dist ) { + idVec3 org, vright, vup; + + org = normal * dist; + + normal.NormalVectors( vup, vright ); + vup *= MAX_WORLD_SIZE; + vright *= MAX_WORLD_SIZE; + + EnsureAlloced( 4 ); + numPoints = 4; + p[0].ToVec3() = org - vright + vup; + p[0].s = p[0].t = 0.0f; + p[1].ToVec3() = org + vright + vup; + p[1].s = p[1].t = 0.0f; + p[2].ToVec3() = org + vright - vup; + p[2].s = p[2].t = 0.0f; + p[3].ToVec3() = org - vright - vup; + p[3].s = p[3].t = 0.0f; +} + +/* +============= +idWinding::Split +============= +*/ +int idWinding::Split( const idPlane &plane, const float epsilon, idWinding **front, idWinding **back ) const { + float * dists; + byte * sides; + int counts[3]; + float dot; + int i, j; + const idVec5 * p1, *p2; + idVec5 mid; + idWinding * f, *b; + int maxpts; + + assert( this ); + + dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); + sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); + + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.Distance( p[i].ToVec3() ); + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + *front = *back = NULL; + + // if coplanar, put on the front side if the normals match + if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + idPlane windingPlane; + + GetPlane( windingPlane ); + if ( windingPlane.Normal() * plane.Normal() > 0.0f ) { + *front = Copy(); + return SIDE_FRONT; + } else { + *back = Copy(); + return SIDE_BACK; + } + } + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + *back = Copy(); + return SIDE_BACK; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + *front = Copy(); + return SIDE_FRONT; + } + + maxpts = numPoints+4; // cant use counts[0]+2 because of fp grouping errors + + *front = f = new idWinding(maxpts); + *back = b = new idWinding(maxpts); + + for (i = 0; i < numPoints; i++) { + p1 = &p[i]; + + if ( sides[i] == SIDE_ON ) { + f->p[f->numPoints] = *p1; + f->numPoints++; + b->p[b->numPoints] = *p1; + b->numPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + f->p[f->numPoints] = *p1; + f->numPoints++; + } + + if ( sides[i] == SIDE_BACK ) { + b->p[b->numPoints] = *p1; + b->numPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + // generate a split point + p2 = &p[(i+1)%numPoints]; + + // always calculate the split going from the same side + // or minor epsilon issues can happen + if ( sides[i] == SIDE_FRONT ) { + dot = dists[i] / ( dists[i] - dists[i+1] ); + for ( j = 0; j < 3; j++ ) { + // avoid round off error when possible + if ( plane.Normal()[j] == 1.0f ) { + mid[j] = plane.Dist(); + } else if ( plane.Normal()[j] == -1.0f ) { + mid[j] = -plane.Dist(); + } else { + mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); + } + } + mid.s = p1->s + dot * ( p2->s - p1->s ); + mid.t = p1->t + dot * ( p2->t - p1->t ); + } else { + dot = dists[i+1] / ( dists[i+1] - dists[i] ); + for ( j = 0; j < 3; j++ ) { + // avoid round off error when possible + if ( plane.Normal()[j] == 1.0f ) { + mid[j] = plane.Dist(); + } else if ( plane.Normal()[j] == -1.0f ) { + mid[j] = -plane.Dist(); + } else { + mid[j] = (*p2)[j] + dot * ( (*p1)[j] - (*p2)[j] ); + } + } + mid.s = p2->s + dot * ( p1->s - p2->s ); + mid.t = p2->t + dot * ( p1->t - p2->t ); + } + + f->p[f->numPoints] = mid; + f->numPoints++; + b->p[b->numPoints] = mid; + b->numPoints++; + } + + if ( f->numPoints > maxpts || b->numPoints > maxpts ) { + idLib::common->FatalError( "idWinding::Split: points exceeded estimate." ); + } + + return SIDE_CROSS; +} + +/* +============= +idWinding::Clip +============= +*/ +idWinding *idWinding::Clip( const idPlane &plane, const float epsilon, const bool keepOn ) { + float * dists; + byte * sides; + idVec5 * newPoints; + int newNumPoints; + int counts[3]; + float dot; + int i, j; + idVec5 * p1, *p2; + idVec5 mid; + int maxpts; + + assert( this ); + + dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); + sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); + + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + // determine sides for each point + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.Distance( p[i].ToVec3() ); + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + // if the winding is on the plane and we should keep it + if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + return this; + } + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + delete this; + return NULL; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + return this; + } + + maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors + + newPoints = (idVec5 *) _alloca16( maxpts * sizeof( idVec5 ) ); + newNumPoints = 0; + + for ( i = 0; i < numPoints; i++ ) { + p1 = &p[i]; + + if ( newNumPoints+1 > maxpts ) { + return this; // can't split -- fall back to original + } + + if ( sides[i] == SIDE_ON ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + if ( newNumPoints+1 > maxpts ) { + return this; // can't split -- fall back to original + } + + // generate a split point + p2 = &p[(i+1)%numPoints]; + + dot = dists[i] / (dists[i] - dists[i+1]); + for ( j = 0; j < 3; j++ ) { + // avoid round off error when possible + if ( plane.Normal()[j] == 1.0f ) { + mid[j] = plane.Dist(); + } else if ( plane.Normal()[j] == -1.0f ) { + mid[j] = -plane.Dist(); + } else { + mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); + } + } + mid.s = p1->s + dot * ( p2->s - p1->s ); + mid.t = p1->t + dot * ( p2->t - p1->t ); + + newPoints[newNumPoints] = mid; + newNumPoints++; + } + + if ( !EnsureAlloced( newNumPoints, false ) ) { + return this; + } + + numPoints = newNumPoints; + memcpy( p, newPoints, newNumPoints * sizeof(idVec5) ); + + return this; +} + +/* +============= +idWinding::ClipInPlace +============= +*/ +bool idWinding::ClipInPlace( const idPlane &plane, const float epsilon, const bool keepOn ) { + float* dists; + byte * sides; + idVec5 * newPoints; + int newNumPoints; + int counts[3]; + float dot; + int i, j; + idVec5 * p1, *p2; + idVec5 mid; + int maxpts; + + assert( this ); + + dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); + sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); + + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + // determine sides for each point + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.Distance( p[i].ToVec3() ); + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + // if the winding is on the plane and we should keep it + if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + return true; + } + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + numPoints = 0; + return false; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + return true; + } + + maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors + + newPoints = (idVec5 *) _alloca16( maxpts * sizeof( idVec5 ) ); + newNumPoints = 0; + + for ( i = 0; i < numPoints; i++ ) { + p1 = &p[i]; + + if ( newNumPoints+1 > maxpts ) { + return true; // can't split -- fall back to original + } + + if ( sides[i] == SIDE_ON ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + if ( newNumPoints+1 > maxpts ) { + return true; // can't split -- fall back to original + } + + // generate a split point + p2 = &p[(i+1)%numPoints]; + + dot = dists[i] / (dists[i] - dists[i+1]); + for ( j = 0; j < 3; j++ ) { + // avoid round off error when possible + if ( plane.Normal()[j] == 1.0f ) { + mid[j] = plane.Dist(); + } else if ( plane.Normal()[j] == -1.0f ) { + mid[j] = -plane.Dist(); + } else { + mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); + } + } + mid.s = p1->s + dot * ( p2->s - p1->s ); + mid.t = p1->t + dot * ( p2->t - p1->t ); + + newPoints[newNumPoints] = mid; + newNumPoints++; + } + + if ( !EnsureAlloced( newNumPoints, false ) ) { + return true; + } + + numPoints = newNumPoints; + memcpy( p, newPoints, newNumPoints * sizeof(idVec5) ); + + return true; +} + +/* +============= +idWinding::Copy +============= +*/ +idWinding *idWinding::Copy( void ) const { + idWinding *w; + + w = new idWinding( numPoints ); + w->numPoints = numPoints; + memcpy( w->p, p, numPoints * sizeof(p[0]) ); + return w; +} + +/* +============= +idWinding::Reverse +============= +*/ +idWinding *idWinding::Reverse( void ) const { + idWinding *w; + int i; + + w = new idWinding( numPoints ); + w->numPoints = numPoints; + for ( i = 0; i < numPoints; i++ ) { + w->p[ numPoints - i - 1 ] = p[i]; + } + return w; +} + +/* +============= +idWinding::ReverseSelf +============= +*/ +void idWinding::ReverseSelf( void ) { + idVec5 v; + int i; + + for ( i = 0; i < (numPoints>>1); i++ ) { + v = p[i]; + p[i] = p[numPoints - i - 1]; + p[numPoints - i - 1] = v; + } +} + +/* +============= +idWinding::Check +============= +*/ +bool idWinding::Check( bool print ) const { + int i, j; + float d, edgedist; + idVec3 dir, edgenormal; + float area; + idPlane plane; + + if ( numPoints < 3 ) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: only %i points.", numPoints ); + } + return false; + } + + area = GetArea(); + if ( area < 1.0f ) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: tiny area: %f", area ); + } + return false; + } + + GetPlane( plane ); + + for ( i = 0; i < numPoints; i++ ) { + const idVec3 &p1 = p[i].ToVec3(); + + // check if the winding is huge + for ( j = 0; j < 3; j++ ) { + if ( p1[j] >= MAX_WORLD_COORD || p1[j] <= MIN_WORLD_COORD ) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: point %d outside world %c-axis: %f", i, 'X'+j, p1[j] ); + } + return false; + } + } + + j = i + 1 == numPoints ? 0 : i + 1; + + // check if the point is on the face plane + d = p1 * plane.Normal() + plane[3]; + if ( d < -ON_EPSILON || d > ON_EPSILON ) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: point %d off plane.", i ); + } + return false; + } + + // check if the edge isn't degenerate + const idVec3 &p2 = p[j].ToVec3(); + dir = p2 - p1; + + if ( dir.Length() < ON_EPSILON) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: edge %d is degenerate.", i ); + } + return false; + } + + // check if the winding is convex + edgenormal = plane.Normal().Cross( dir ); + edgenormal.Normalize(); + edgedist = p1 * edgenormal; + edgedist += ON_EPSILON; + + // all other points must be on front side + for ( j = 0; j < numPoints; j++ ) { + if ( j == i ) { + continue; + } + d = p[j].ToVec3() * edgenormal; + if ( d > edgedist ) { + if ( print ) { + idLib::common->Printf( "idWinding::Check: non-convex." ); + } + return false; + } + } + } + return true; +} + +/* +============= +idWinding::GetArea +============= +*/ +float idWinding::GetArea( void ) const { + int i; + idVec3 d1, d2, cross; + float total; + + total = 0.0f; + for ( i = 2; i < numPoints; i++ ) { + d1 = p[i-1].ToVec3() - p[0].ToVec3(); + d2 = p[i].ToVec3() - p[0].ToVec3(); + cross = d1.Cross( d2 ); + total += cross.Length(); + } + return total * 0.5f; +} + +/* +============= +idWinding::GetRadius +============= +*/ +float idWinding::GetRadius( const idVec3 ¢er ) const { + int i; + float radius, r; + idVec3 dir; + + radius = 0.0f; + for ( i = 0; i < numPoints; i++ ) { + dir = p[i].ToVec3() - center; + r = dir * dir; + if ( r > radius ) { + radius = r; + } + } + return idMath::Sqrt( radius ); +} + +/* +============= +idWinding::GetCenter +============= +*/ +idVec3 idWinding::GetCenter( void ) const { + int i; + idVec3 center; + + center.Zero(); + for ( i = 0; i < numPoints; i++ ) { + center += p[i].ToVec3(); + } + center *= ( 1.0f / numPoints ); + return center; +} + +/* +============= +idWinding::GetPlane +============= +*/ +void idWinding::GetPlane( idVec3 &normal, float &dist ) const { + idVec3 v1, v2, center; + + if ( numPoints < 3 ) { + normal.Zero(); + dist = 0.0f; + return; + } + + center = GetCenter(); + v1 = p[0].ToVec3() - center; + v2 = p[1].ToVec3() - center; + normal = v2.Cross( v1 ); + normal.Normalize(); + dist = p[0].ToVec3() * normal; +} + +/* +============= +idWinding::GetPlane +============= +*/ +void idWinding::GetPlane( idPlane &plane ) const { + idVec3 v1, v2; + idVec3 center; + + if ( numPoints < 3 ) { + plane.Zero(); + return; + } + + center = GetCenter(); + v1 = p[0].ToVec3() - center; + v2 = p[1].ToVec3() - center; + plane.SetNormal( v2.Cross( v1 ) ); + plane.Normalize(); + plane.FitThroughPoint( p[0].ToVec3() ); +} + +/* +============= +idWinding::GetBounds +============= +*/ +void idWinding::GetBounds( idBounds &bounds ) const { + int i; + + if ( !numPoints ) { + bounds.Clear(); + return; + } + + bounds[0] = bounds[1] = p[0].ToVec3(); + for ( i = 1; i < numPoints; i++ ) { + if ( p[i].x < bounds[0].x ) { + bounds[0].x = p[i].x; + } else if ( p[i].x > bounds[1].x ) { + bounds[1].x = p[i].x; + } + if ( p[i].y < bounds[0].y ) { + bounds[0].y = p[i].y; + } else if ( p[i].y > bounds[1].y ) { + bounds[1].y = p[i].y; + } + if ( p[i].z < bounds[0].z ) { + bounds[0].z = p[i].z; + } else if ( p[i].z > bounds[1].z ) { + bounds[1].z = p[i].z; + } + } +} + +/* +============= +idWinding::RemoveEqualPoints +============= +*/ +void idWinding::RemoveEqualPoints( const float epsilon ) { + int i, j; + + for ( i = 0; i < numPoints; i++ ) { + if ( (p[i].ToVec3() - p[(i+numPoints-1)%numPoints].ToVec3()).LengthSqr() >= Square( epsilon ) ) { + continue; + } + numPoints--; + for ( j = i; j < numPoints; j++ ) { + p[j] = p[j+1]; + } + i--; + } +} + +/* +============= +idWinding::RemoveColinearPoints +============= +*/ +void idWinding::RemoveColinearPoints( const idVec3 &normal, const float epsilon ) { + int i, j; + idVec3 edgeNormal; + float dist; + + if ( numPoints <= 3 ) { + return; + } + + for ( i = 0; i < numPoints; i++ ) { + + // create plane through edge orthogonal to winding plane + edgeNormal = (p[i].ToVec3() - p[(i+numPoints-1)%numPoints].ToVec3()).Cross( normal ); + edgeNormal.Normalize(); + dist = edgeNormal * p[i].ToVec3(); + + if ( idMath::Fabs( edgeNormal * p[(i+1)%numPoints].ToVec3() - dist ) > epsilon ) { + continue; + } + + numPoints--; + for ( j = i; j < numPoints; j++ ) { + p[j] = p[j+1]; + } + i--; + } +} + +/* +============= +idWinding::AddToConvexHull + + Adds the given winding to the convex hull. + Assumes the current winding already is a convex hull with three or more points. +============= +*/ +void idWinding::AddToConvexHull( const idWinding *winding, const idVec3 &normal, const float epsilon ) { + int i, j, k; + idVec3 dir; + float d; + int maxPts; + idVec3 * hullDirs; + bool * hullSide; + bool outside; + int numNewHullPoints; + idVec5 * newHullPoints; + + if ( !winding ) { + return; + } + + maxPts = this->numPoints + winding->numPoints; + + if ( !this->EnsureAlloced( maxPts, true ) ) { + return; + } + + newHullPoints = (idVec5 *) _alloca( maxPts * sizeof( idVec5 ) ); + hullDirs = (idVec3 *) _alloca( maxPts * sizeof( idVec3 ) ); + hullSide = (bool *) _alloca( maxPts * sizeof( bool ) ); + + for ( i = 0; i < winding->numPoints; i++ ) { + const idVec5 &p1 = winding->p[i]; + + // calculate hull edge vectors + for ( j = 0; j < this->numPoints; j++ ) { + dir = this->p[ (j + 1) % this->numPoints ].ToVec3() - this->p[ j ].ToVec3(); + dir.Normalize(); + hullDirs[j] = normal.Cross( dir ); + } + + // calculate side for each hull edge + outside = false; + for ( j = 0; j < this->numPoints; j++ ) { + dir = p1.ToVec3() - this->p[j].ToVec3(); + d = dir * hullDirs[j]; + if ( d >= epsilon ) { + outside = true; + } + if ( d >= -epsilon ) { + hullSide[j] = true; + } else { + hullSide[j] = false; + } + } + + // if the point is effectively inside, do nothing + if ( !outside ) { + continue; + } + + // find the back side to front side transition + for ( j = 0; j < this->numPoints; j++ ) { + if ( !hullSide[ j ] && hullSide[ (j + 1) % this->numPoints ] ) { + break; + } + } + if ( j >= this->numPoints ) { + continue; + } + + // insert the point here + newHullPoints[0] = p1; + numNewHullPoints = 1; + + // copy over all points that aren't double fronts + j = (j+1) % this->numPoints; + for ( k = 0; k < this->numPoints; k++ ) { + if ( hullSide[ (j+k) % this->numPoints ] && hullSide[ (j+k+1) % this->numPoints ] ) { + continue; + } + newHullPoints[numNewHullPoints] = this->p[ (j+k+1) % this->numPoints ]; + numNewHullPoints++; + } + + this->numPoints = numNewHullPoints; + memcpy( this->p, newHullPoints, numNewHullPoints * sizeof(idVec5) ); + } +} + +/* +============= +idWinding::AddToConvexHull + + Add a point to the convex hull. + The current winding must be convex but may be degenerate and can have less than three points. +============= +*/ +void idWinding::AddToConvexHull( const idVec3 &point, const idVec3 &normal, const float epsilon ) { + int j, k, numHullPoints; + idVec3 dir; + float d; + idVec3 * hullDirs; + bool * hullSide; + idVec5 * hullPoints; + bool outside; + + switch( numPoints ) { + case 0: { + p[0] = point; + numPoints++; + return; + } + case 1: { + // don't add the same point second + if ( p[0].ToVec3().Compare( point, epsilon ) ) { + return; + } + p[1].ToVec3() = point; + numPoints++; + return; + } + case 2: { + // don't add a point if it already exists + if ( p[0].ToVec3().Compare( point, epsilon ) || p[1].ToVec3().Compare( point, epsilon ) ) { + return; + } + // if only two points make sure we have the right ordering according to the normal + dir = point - p[0].ToVec3(); + dir = dir.Cross( p[1].ToVec3() - p[0].ToVec3() ); + if ( dir[0] == 0.0f && dir[1] == 0.0f && dir[2] == 0.0f ) { + // points don't make a plane + return; + } + if ( dir * normal > 0.0f ) { + p[2].ToVec3() = point; + } + else { + p[2] = p[1]; + p[1].ToVec3() = point; + } + numPoints++; + return; + } + } + + hullDirs = (idVec3 *) _alloca( numPoints * sizeof( idVec3 ) ); + hullSide = (bool *) _alloca( numPoints * sizeof( bool ) ); + + // calculate hull edge vectors + for ( j = 0; j < numPoints; j++ ) { + dir = p[(j + 1) % numPoints].ToVec3() - p[j].ToVec3(); + hullDirs[j] = normal.Cross( dir ); + } + + // calculate side for each hull edge + outside = false; + for ( j = 0; j < numPoints; j++ ) { + dir = point - p[j].ToVec3(); + d = dir * hullDirs[j]; + if ( d >= epsilon ) { + outside = true; + } + if ( d >= -epsilon ) { + hullSide[j] = true; + } else { + hullSide[j] = false; + } + } + + // if the point is effectively inside, do nothing + if ( !outside ) { + return; + } + + // find the back side to front side transition + for ( j = 0; j < numPoints; j++ ) { + if ( !hullSide[ j ] && hullSide[ (j + 1) % numPoints ] ) { + break; + } + } + if ( j >= numPoints ) { + return; + } + + hullPoints = (idVec5 *) _alloca( (numPoints+1) * sizeof( idVec5 ) ); + + // insert the point here + hullPoints[0] = point; + numHullPoints = 1; + + // copy over all points that aren't double fronts + j = (j+1) % numPoints; + for ( k = 0; k < numPoints; k++ ) { + if ( hullSide[ (j+k) % numPoints ] && hullSide[ (j+k+1) % numPoints ] ) { + continue; + } + hullPoints[numHullPoints] = p[ (j+k+1) % numPoints ]; + numHullPoints++; + } + + if ( !EnsureAlloced( numHullPoints, false ) ) { + return; + } + numPoints = numHullPoints; + memcpy( p, hullPoints, numHullPoints * sizeof(idVec5) ); +} + +/* +============= +idWinding::TryMerge +============= +*/ +#define CONTINUOUS_EPSILON 0.005f + +idWinding *idWinding::TryMerge( const idWinding &w, const idVec3 &planenormal, int keep ) const { + idVec3 *p1, *p2, *p3, *p4, *back; + idWinding *newf; + const idWinding *f1, *f2; + int i, j, k, l; + idVec3 normal, delta; + float dot; + bool keep1, keep2; + + f1 = this; + f2 = &w; + // + // find a idLib::common edge + // + p1 = p2 = NULL; // stop compiler warning + j = 0; + + for ( i = 0; i < f1->numPoints; i++ ) { + p1 = &f1->p[i].ToVec3(); + p2 = &f1->p[(i+1) % f1->numPoints].ToVec3(); + for ( j = 0; j < f2->numPoints; j++ ) { + p3 = &f2->p[j].ToVec3(); + p4 = &f2->p[(j+1) % f2->numPoints].ToVec3(); + for (k = 0; k < 3; k++ ) { + if ( idMath::Fabs((*p1)[k] - (*p4)[k]) > 0.1f ) { + break; + } + if ( idMath::Fabs((*p2)[k] - (*p3)[k]) > 0.1f ) { + break; + } + } + if ( k == 3 ) { + break; + } + } + if ( j < f2->numPoints ) { + break; + } + } + + if ( i == f1->numPoints ) { + return NULL; // no matching edges + } + + // + // check slope of connected lines + // if the slopes are colinear, the point can be removed + // + back = &f1->p[(i+f1->numPoints-1)%f1->numPoints].ToVec3(); + delta = (*p1) - (*back); + normal = planenormal.Cross(delta); + normal.Normalize(); + + back = &f2->p[(j+2)%f2->numPoints].ToVec3(); + delta = (*back) - (*p1); + dot = delta * normal; + if ( dot > CONTINUOUS_EPSILON ) { + return NULL; // not a convex polygon + } + + keep1 = (bool)(dot < -CONTINUOUS_EPSILON); + + back = &f1->p[(i+2)%f1->numPoints].ToVec3(); + delta = (*back) - (*p2); + normal = planenormal.Cross( delta ); + normal.Normalize(); + + back = &f2->p[(j+f2->numPoints-1)%f2->numPoints].ToVec3(); + delta = (*back) - (*p2); + dot = delta * normal; + if ( dot > CONTINUOUS_EPSILON ) { + return NULL; // not a convex polygon + } + + keep2 = (bool)(dot < -CONTINUOUS_EPSILON); + + // + // build the new polygon + // + newf = new idWinding( f1->numPoints + f2->numPoints ); + + // copy first polygon + for ( k = (i+1) % f1->numPoints; k != i; k = (k+1) % f1->numPoints ) { + if ( !keep && k == (i+1) % f1->numPoints && !keep2 ) { + continue; + } + + newf->p[newf->numPoints] = f1->p[k]; + newf->numPoints++; + } + + // copy second polygon + for ( l = (j+1) % f2->numPoints; l != j; l = (l+1) % f2->numPoints ) { + if ( !keep && l == (j+1) % f2->numPoints && !keep1 ) { + continue; + } + newf->p[newf->numPoints] = f2->p[l]; + newf->numPoints++; + } + + return newf; +} + +/* +============= +idWinding::RemovePoint +============= +*/ +void idWinding::RemovePoint( int point ) { + if ( point < 0 || point >= numPoints ) { + idLib::common->FatalError( "idWinding::removePoint: point out of range" ); + } + if ( point < numPoints - 1) { + memmove(&p[point], &p[point+1], (numPoints - point - 1) * sizeof(p[0]) ); + } + numPoints--; +} + +/* +============= +idWinding::InsertPoint +============= +*/ +void idWinding::InsertPoint( const idVec3 &point, int spot ) { + int i; + + if ( spot > numPoints ) { + idLib::common->FatalError( "idWinding::insertPoint: spot > numPoints" ); + } + + if ( spot < 0 ) { + idLib::common->FatalError( "idWinding::insertPoint: spot < 0" ); + } + + EnsureAlloced( numPoints+1, true ); + for ( i = numPoints; i > spot; i-- ) { + p[i] = p[i-1]; + } + p[spot] = point; + numPoints++; +} + +/* +============= +idWinding::InsertPointIfOnEdge +============= +*/ +bool idWinding::InsertPointIfOnEdge( const idVec3 &point, const idPlane &plane, const float epsilon ) { + int i; + float dist, dot; + idVec3 normal; + + // point may not be too far from the winding plane + if ( idMath::Fabs( plane.Distance( point ) ) > epsilon ) { + return false; + } + + for ( i = 0; i < numPoints; i++ ) { + + // create plane through edge orthogonal to winding plane + normal = (p[(i+1)%numPoints].ToVec3() - p[i].ToVec3()).Cross( plane.Normal() ); + normal.Normalize(); + dist = normal * p[i].ToVec3(); + + if ( idMath::Fabs( normal * point - dist ) > epsilon ) { + continue; + } + + normal = plane.Normal().Cross( normal ); + dot = normal * point; + + dist = dot - normal * p[i].ToVec3(); + + if ( dist < epsilon ) { + // if the winding already has the point + if ( dist > -epsilon ) { + return false; + } + continue; + } + + dist = dot - normal * p[(i+1)%numPoints].ToVec3(); + + if ( dist > -epsilon ) { + // if the winding already has the point + if ( dist < epsilon ) { + return false; + } + continue; + } + + InsertPoint( point, i+1 ); + return true; + } + return false; +} + +/* +============= +idWinding::IsTiny +============= +*/ +#define EDGE_LENGTH 0.2f + +bool idWinding::IsTiny( void ) const { + int i; + float len; + idVec3 delta; + int edges; + + edges = 0; + for ( i = 0; i < numPoints; i++ ) { + delta = p[(i+1)%numPoints].ToVec3() - p[i].ToVec3(); + len = delta.Length(); + if ( len > EDGE_LENGTH ) { + if ( ++edges == 3 ) { + return false; + } + } + } + return true; +} + +/* +============= +idWinding::IsHuge +============= +*/ +bool idWinding::IsHuge( void ) const { + int i, j; + + for ( i = 0; i < numPoints; i++ ) { + for ( j = 0; j < 3; j++ ) { + if ( p[i][j] <= MIN_WORLD_COORD || p[i][j] >= MAX_WORLD_COORD ) { + return true; + } + } + } + return false; +} + +/* +============= +idWinding::Print +============= +*/ +void idWinding::Print( void ) const { + int i; + + for ( i = 0; i < numPoints; i++ ) { + idLib::common->Printf( "(%5.1f, %5.1f, %5.1f)\n", p[i][0], p[i][1], p[i][2] ); + } +} + +/* +============= +idWinding::PlaneDistance +============= +*/ +float idWinding::PlaneDistance( const idPlane &plane ) const { + int i; + float d, min, max; + + min = idMath::INFINITY; + max = -min; + for ( i = 0; i < numPoints; i++ ) { + d = plane.Distance( p[i].ToVec3() ); + if ( d < min ) { + min = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + if ( d > max ) { + max = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + } + if ( FLOATSIGNBITNOTSET( min ) ) { + return min; + } + if ( FLOATSIGNBITSET( max ) ) { + return max; + } + return 0.0f; +} + +/* +============= +idWinding::PlaneSide +============= +*/ +int idWinding::PlaneSide( const idPlane &plane, const float epsilon ) const { + bool front, back; + int i; + float d; + + front = false; + back = false; + for ( i = 0; i < numPoints; i++ ) { + d = plane.Distance( p[i].ToVec3() ); + if ( d < -epsilon ) { + if ( front ) { + return SIDE_CROSS; + } + back = true; + continue; + } + else if ( d > epsilon ) { + if ( back ) { + return SIDE_CROSS; + } + front = true; + continue; + } + } + + if ( back ) { + return SIDE_BACK; + } + if ( front ) { + return SIDE_FRONT; + } + return SIDE_ON; +} + +/* +============= +idWinding::PlanesConcave +============= +*/ +#define WCONVEX_EPSILON 0.2f + +bool idWinding::PlanesConcave( const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2 ) const { + int i; + + // check if one of the points of winding 1 is at the back of the plane of winding 2 + for ( i = 0; i < numPoints; i++ ) { + if ( normal2 * p[i].ToVec3() - dist2 > WCONVEX_EPSILON ) { + return true; + } + } + // check if one of the points of winding 2 is at the back of the plane of winding 1 + for ( i = 0; i < w2.numPoints; i++ ) { + if ( normal1 * w2.p[i].ToVec3() - dist1 > WCONVEX_EPSILON ) { + return true; + } + } + + return false; +} + +/* +============= +idWinding::PointInside +============= +*/ +bool idWinding::PointInside( const idVec3 &normal, const idVec3 &point, const float epsilon ) const { + int i; + idVec3 dir, n, pointvec; + + for ( i = 0; i < numPoints; i++ ) { + dir = p[(i+1) % numPoints].ToVec3() - p[i].ToVec3(); + pointvec = point - p[i].ToVec3(); + + n = dir.Cross( normal ); + + if ( pointvec * n < -epsilon ) { + return false; + } + } + return true; +} + +/* +============= +idWinding::LineIntersection +============= +*/ +bool idWinding::LineIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull ) const { + float front, back, frac; + idVec3 mid; + + front = windingPlane.Distance( start ); + back = windingPlane.Distance( end ); + + // if both points at the same side of the plane + if ( front < 0.0f && back < 0.0f ) { + return false; + } + + if ( front > 0.0f && back > 0.0f ) { + return false; + } + + // if back face culled + if ( backFaceCull && front < 0.0f ) { + return false; + } + + // get point of intersection with winding plane + if ( idMath::Fabs(front - back) < 0.0001f ) { + mid = end; + } + else { + frac = front / (front - back); + mid[0] = start[0] + (end[0] - start[0]) * frac; + mid[1] = start[1] + (end[1] - start[1]) * frac; + mid[2] = start[2] + (end[2] - start[2]) * frac; + } + + return PointInside( windingPlane.Normal(), mid, 0.0f ); +} + +/* +============= +idWinding::RayIntersection +============= +*/ +bool idWinding::RayIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull ) const { + int i; + bool side, lastside = false; + idPluecker pl1, pl2; + + scale = 0.0f; + pl1.FromRay( start, dir ); + for ( i = 0; i < numPoints; i++ ) { + pl2.FromLine( p[i].ToVec3(), p[(i+1)%numPoints].ToVec3() ); + side = pl1.PermutedInnerProduct( pl2 ) > 0.0f; + if ( i && side != lastside ) { + return false; + } + lastside = side; + } + if ( !backFaceCull || lastside ) { + windingPlane.RayIntersection( start, dir, scale ); + return true; + } + return false; +} + +/* +================= +idWinding::TriangleArea +================= +*/ +float idWinding::TriangleArea( const idVec3 &a, const idVec3 &b, const idVec3 &c ) { + idVec3 v1, v2; + idVec3 cross; + + v1 = b - a; + v2 = c - a; + cross = v1.Cross( v2 ); + return 0.5f * cross.Length(); +} + + +//=============================================================== +// +// idFixedWinding +// +//=============================================================== + +/* +============= +idFixedWinding::ReAllocate +============= +*/ +bool idFixedWinding::ReAllocate( int n, bool keep ) { + + assert( n <= MAX_POINTS_ON_WINDING ); + + if ( n > MAX_POINTS_ON_WINDING ) { + idLib::common->Printf("WARNING: idFixedWinding -> MAX_POINTS_ON_WINDING overflowed\n"); + return false; + } + return true; +} + +/* +============= +idFixedWinding::Split +============= +*/ +int idFixedWinding::Split( idFixedWinding *back, const idPlane &plane, const float epsilon ) { + int counts[3]; + float dists[MAX_POINTS_ON_WINDING+4]; + byte sides[MAX_POINTS_ON_WINDING+4]; + float dot; + int i, j; + idVec5 *p1, *p2; + idVec5 mid; + idFixedWinding out; + + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + // determine sides for each point + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.Distance( p[i].ToVec3() ); + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + + if ( !counts[SIDE_BACK] ) { + if ( !counts[SIDE_FRONT] ) { + return SIDE_ON; + } + else { + return SIDE_FRONT; + } + } + + if ( !counts[SIDE_FRONT] ) { + return SIDE_BACK; + } + + sides[i] = sides[0]; + dists[i] = dists[0]; + + out.numPoints = 0; + back->numPoints = 0; + + for ( i = 0; i < numPoints; i++ ) { + p1 = &p[i]; + + if ( !out.EnsureAlloced( out.numPoints+1, true ) ) { + return SIDE_FRONT; // can't split -- fall back to original + } + if ( !back->EnsureAlloced( back->numPoints+1, true ) ) { + return SIDE_FRONT; // can't split -- fall back to original + } + + if ( sides[i] == SIDE_ON ) { + out.p[out.numPoints] = *p1; + out.numPoints++; + back->p[back->numPoints] = *p1; + back->numPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + out.p[out.numPoints] = *p1; + out.numPoints++; + } + if ( sides[i] == SIDE_BACK ) { + back->p[back->numPoints] = *p1; + back->numPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + if ( !out.EnsureAlloced( out.numPoints+1, true ) ) { + return SIDE_FRONT; // can't split -- fall back to original + } + + if ( !back->EnsureAlloced( back->numPoints+1, true ) ) { + return SIDE_FRONT; // can't split -- fall back to original + } + + // generate a split point + j = i + 1; + if ( j >= numPoints ) { + p2 = &p[0]; + } + else { + p2 = &p[j]; + } + + dot = dists[i] / (dists[i] - dists[i+1]); + for ( j = 0; j < 3; j++ ) { + // avoid round off error when possible + if ( plane.Normal()[j] == 1.0f ) { + mid[j] = plane.Dist(); + } else if ( plane.Normal()[j] == -1.0f ) { + mid[j] = -plane.Dist(); + } else { + mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); + } + } + mid.s = p1->s + dot * ( p2->s - p1->s ); + mid.t = p1->t + dot * ( p2->t - p1->t ); + + out.p[out.numPoints] = mid; + out.numPoints++; + back->p[back->numPoints] = mid; + back->numPoints++; + } + for ( i = 0; i < out.numPoints; i++ ) { + p[i] = out.p[i]; + } + numPoints = out.numPoints; + + return SIDE_CROSS; +} diff --git a/idlib/geometry/Winding.h b/idlib/geometry/Winding.h new file mode 100644 index 000000000..394214cc3 --- /dev/null +++ b/idlib/geometry/Winding.h @@ -0,0 +1,392 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __WINDING_H__ +#define __WINDING_H__ + +/* +=============================================================================== + + A winding is an arbitrary convex polygon defined by an array of points. + +=============================================================================== +*/ + +class idWinding { + +public: + idWinding( void ); + explicit idWinding( const int n ); // allocate for n points + explicit idWinding( const idVec3 *verts, const int n ); // winding from points + explicit idWinding( const idVec3 &normal, const float dist ); // base winding for plane + explicit idWinding( const idPlane &plane ); // base winding for plane + explicit idWinding( const idWinding &winding ); + virtual ~idWinding( void ); + + idWinding & operator=( const idWinding &winding ); + const idVec5 & operator[]( const int index ) const; + idVec5 & operator[]( const int index ); + + // add a point to the end of the winding point array + idWinding & operator+=( const idVec3 &v ); + idWinding & operator+=( const idVec5 &v ); + void AddPoint( const idVec3 &v ); + void AddPoint( const idVec5 &v ); + + // number of points on winding + int GetNumPoints( void ) const; + void SetNumPoints( int n ); + virtual void Clear( void ); + + // huge winding for plane, the points go counter clockwise when facing the front of the plane + void BaseForPlane( const idVec3 &normal, const float dist ); + void BaseForPlane( const idPlane &plane ); + + // splits the winding into a front and back winding, the winding itself stays unchanged + // returns a SIDE_? + int Split( const idPlane &plane, const float epsilon, idWinding **front, idWinding **back ) const; + // returns the winding fragment at the front of the clipping plane, + // if there is nothing at the front the winding itself is destroyed and NULL is returned + idWinding * Clip( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); + // cuts off the part at the back side of the plane, returns true if some part was at the front + // if there is nothing at the front the number of points is set to zero + bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); + + // returns a copy of the winding + idWinding * Copy( void ) const; + idWinding * Reverse( void ) const; + void ReverseSelf( void ); + void RemoveEqualPoints( const float epsilon = ON_EPSILON ); + void RemoveColinearPoints( const idVec3 &normal, const float epsilon = ON_EPSILON ); + void RemovePoint( int point ); + void InsertPoint( const idVec3 &point, int spot ); + bool InsertPointIfOnEdge( const idVec3 &point, const idPlane &plane, const float epsilon = ON_EPSILON ); + // add a winding to the convex hull + void AddToConvexHull( const idWinding *winding, const idVec3 &normal, const float epsilon = ON_EPSILON ); + // add a point to the convex hull + void AddToConvexHull( const idVec3 &point, const idVec3 &normal, const float epsilon = ON_EPSILON ); + // tries to merge 'this' with the given winding, returns NULL if merge fails, both 'this' and 'w' stay intact + // 'keep' tells if the contacting points should stay even if they create colinear edges + idWinding * TryMerge( const idWinding &w, const idVec3 &normal, int keep = false ) const; + // check whether the winding is valid or not + bool Check( bool print = true ) const; + + float GetArea( void ) const; + idVec3 GetCenter( void ) const; + float GetRadius( const idVec3 ¢er ) const; + void GetPlane( idVec3 &normal, float &dist ) const; + void GetPlane( idPlane &plane ) const; + void GetBounds( idBounds &bounds ) const; + + bool IsTiny( void ) const; + bool IsHuge( void ) const; // base winding for a plane is typically huge + void Print( void ) const; + + float PlaneDistance( const idPlane &plane ) const; + int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; + + bool PlanesConcave( const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2 ) const; + + bool PointInside( const idVec3 &normal, const idVec3 &point, const float epsilon ) const; + // returns true if the line or ray intersects the winding + bool LineIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const; + // intersection point is start + dir * scale + bool RayIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const; + + static float TriangleArea( const idVec3 &a, const idVec3 &b, const idVec3 &c ); + +protected: + int numPoints; // number of points + idVec5 * p; // pointer to point data + int allocedSize; + + bool EnsureAlloced( int n, bool keep = false ); + virtual bool ReAllocate( int n, bool keep = false ); +}; + +ID_INLINE idWinding::idWinding( void ) { + numPoints = allocedSize = 0; + p = NULL; +} + +ID_INLINE idWinding::idWinding( int n ) { + numPoints = allocedSize = 0; + p = NULL; + EnsureAlloced( n ); +} + +ID_INLINE idWinding::idWinding( const idVec3 *verts, const int n ) { + int i; + + numPoints = allocedSize = 0; + p = NULL; + if ( !EnsureAlloced( n ) ) { + numPoints = 0; + return; + } + for ( i = 0; i < n; i++ ) { + p[i].ToVec3() = verts[i]; + p[i].s = p[i].t = 0.0f; + } + numPoints = n; +} + +ID_INLINE idWinding::idWinding( const idVec3 &normal, const float dist ) { + numPoints = allocedSize = 0; + p = NULL; + BaseForPlane( normal, dist ); +} + +ID_INLINE idWinding::idWinding( const idPlane &plane ) { + numPoints = allocedSize = 0; + p = NULL; + BaseForPlane( plane ); +} + +ID_INLINE idWinding::idWinding( const idWinding &winding ) { + int i; + if ( !EnsureAlloced( winding.GetNumPoints() ) ) { + numPoints = 0; + return; + } + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + p[i] = winding[i]; + } + numPoints = winding.GetNumPoints(); +} + +ID_INLINE idWinding::~idWinding( void ) { + delete[] p; + p = NULL; +} + +ID_INLINE idWinding &idWinding::operator=( const idWinding &winding ) { + int i; + + if ( !EnsureAlloced( winding.numPoints ) ) { + numPoints = 0; + return *this; + } + for ( i = 0; i < winding.numPoints; i++ ) { + p[i] = winding.p[i]; + } + numPoints = winding.numPoints; + return *this; +} + +ID_INLINE const idVec5 &idWinding::operator[]( const int index ) const { + //assert( index >= 0 && index < numPoints ); + return p[ index ]; +} + +ID_INLINE idVec5 &idWinding::operator[]( const int index ) { + //assert( index >= 0 && index < numPoints ); + return p[ index ]; +} + +ID_INLINE idWinding &idWinding::operator+=( const idVec3 &v ) { + AddPoint( v ); + return *this; +} + +ID_INLINE idWinding &idWinding::operator+=( const idVec5 &v ) { + AddPoint( v ); + return *this; +} + +ID_INLINE void idWinding::AddPoint( const idVec3 &v ) { + if ( !EnsureAlloced(numPoints+1, true) ) { + return; + } + p[numPoints] = v; + numPoints++; +} + +ID_INLINE void idWinding::AddPoint( const idVec5 &v ) { + if ( !EnsureAlloced(numPoints+1, true) ) { + return; + } + p[numPoints] = v; + numPoints++; +} + +ID_INLINE int idWinding::GetNumPoints( void ) const { + return numPoints; +} + +ID_INLINE void idWinding::SetNumPoints( int n ) { + if ( !EnsureAlloced( n, true ) ) { + return; + } + numPoints = n; +} + +ID_INLINE void idWinding::Clear( void ) { + numPoints = 0; + delete[] p; + p = NULL; +} + +ID_INLINE void idWinding::BaseForPlane( const idPlane &plane ) { + BaseForPlane( plane.Normal(), plane.Dist() ); +} + +ID_INLINE bool idWinding::EnsureAlloced( int n, bool keep ) { + if ( n > allocedSize ) { + return ReAllocate( n, keep ); + } + return true; +} + + +/* +=============================================================================== + + idFixedWinding is a fixed buffer size winding not using + memory allocations. + + When an operation would overflow the fixed buffer a warning + is printed and the operation is safely cancelled. + +=============================================================================== +*/ + +#define MAX_POINTS_ON_WINDING 64 + +class idFixedWinding : public idWinding { + +public: + idFixedWinding( void ); + explicit idFixedWinding( const int n ); + explicit idFixedWinding( const idVec3 *verts, const int n ); + explicit idFixedWinding( const idVec3 &normal, const float dist ); + explicit idFixedWinding( const idPlane &plane ); + explicit idFixedWinding( const idWinding &winding ); + explicit idFixedWinding( const idFixedWinding &winding ); + virtual ~idFixedWinding( void ); + + idFixedWinding &operator=( const idWinding &winding ); + + virtual void Clear( void ); + + // splits the winding in a back and front part, 'this' becomes the front part + // returns a SIDE_? + int Split( idFixedWinding *back, const idPlane &plane, const float epsilon = ON_EPSILON ); + +protected: + idVec5 data[MAX_POINTS_ON_WINDING]; // point data + + virtual bool ReAllocate( int n, bool keep = false ); +}; + +ID_INLINE idFixedWinding::idFixedWinding( void ) { + numPoints = 0; + p = data; + allocedSize = MAX_POINTS_ON_WINDING; +} + +ID_INLINE idFixedWinding::idFixedWinding( int n ) { + numPoints = 0; + p = data; + allocedSize = MAX_POINTS_ON_WINDING; +} + +ID_INLINE idFixedWinding::idFixedWinding( const idVec3 *verts, const int n ) { + int i; + + numPoints = 0; + p = data; + allocedSize = MAX_POINTS_ON_WINDING; + if ( !EnsureAlloced( n ) ) { + numPoints = 0; + return; + } + for ( i = 0; i < n; i++ ) { + p[i].ToVec3() = verts[i]; + p[i].s = p[i].t = 0; + } + numPoints = n; +} + +ID_INLINE idFixedWinding::idFixedWinding( const idVec3 &normal, const float dist ) { + numPoints = 0; + p = data; + allocedSize = MAX_POINTS_ON_WINDING; + BaseForPlane( normal, dist ); +} + +ID_INLINE idFixedWinding::idFixedWinding( const idPlane &plane ) { + numPoints = 0; + p = data; + allocedSize = MAX_POINTS_ON_WINDING; + BaseForPlane( plane ); +} + +ID_INLINE idFixedWinding::idFixedWinding( const idWinding &winding ) { + int i; + + p = data; + allocedSize = MAX_POINTS_ON_WINDING; + if ( !EnsureAlloced( winding.GetNumPoints() ) ) { + numPoints = 0; + return; + } + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + p[i] = winding[i]; + } + numPoints = winding.GetNumPoints(); +} + +ID_INLINE idFixedWinding::idFixedWinding( const idFixedWinding &winding ) { + int i; + + p = data; + allocedSize = MAX_POINTS_ON_WINDING; + if ( !EnsureAlloced( winding.GetNumPoints() ) ) { + numPoints = 0; + return; + } + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + p[i] = winding[i]; + } + numPoints = winding.GetNumPoints(); +} + +ID_INLINE idFixedWinding::~idFixedWinding( void ) { + p = NULL; // otherwise it tries to free the fixed buffer +} + +ID_INLINE idFixedWinding &idFixedWinding::operator=( const idWinding &winding ) { + int i; + + if ( !EnsureAlloced( winding.GetNumPoints() ) ) { + numPoints = 0; + return *this; + } + for ( i = 0; i < winding.GetNumPoints(); i++ ) { + p[i] = winding[i]; + } + numPoints = winding.GetNumPoints(); + return *this; +} + +ID_INLINE void idFixedWinding::Clear( void ) { + numPoints = 0; +} +#endif /* !__WINDING_H__ */ diff --git a/idlib/geometry/Winding2D.cpp b/idlib/geometry/Winding2D.cpp new file mode 100644 index 000000000..9384cbebc --- /dev/null +++ b/idlib/geometry/Winding2D.cpp @@ -0,0 +1,745 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Winding2D.h" + + +/* +============ +GetAxialBevel +============ +*/ +bool GetAxialBevel( const idVec3 &plane1, const idVec3 &plane2, const idVec2 &point, idVec3 &bevel ) { + if ( FLOATSIGNBITSET( plane1.x ) ^ FLOATSIGNBITSET( plane2.x ) ) { + if ( idMath::Fabs( plane1.x ) > 0.1f && idMath::Fabs( plane2.x ) > 0.1f ) { + bevel.x = 0.0f; + if ( FLOATSIGNBITSET( plane1.y ) ) { + bevel.y = -1.0f; + } + else { + bevel.y = 1.0f; + } + bevel.z = - ( point.x * bevel.x + point.y * bevel.y ); + return true; + } + } + if ( FLOATSIGNBITSET( plane1.y ) ^ FLOATSIGNBITSET( plane2.y ) ) { + if ( idMath::Fabs( plane1.y ) > 0.1f && idMath::Fabs( plane2.y ) > 0.1f ) { + bevel.y = 0.0f; + if ( FLOATSIGNBITSET( plane1.x ) ) { + bevel.x = -1.0f; + } + else { + bevel.x = 1.0f; + } + bevel.z = - ( point.x * bevel.x + point.y * bevel.y ); + return true; + } + } + return false; +} + +/* +============ +idWinding2D::ExpandForAxialBox +============ +*/ +void idWinding2D::ExpandForAxialBox( const idVec2 bounds[2] ) { + int i, j, numPlanes; + idVec2 v; + idVec3 planes[MAX_POINTS_ON_WINDING_2D], plane, bevel; + + // get planes for the edges and add bevels + for ( numPlanes = i = 0; i < numPoints; i++ ) { + j = (i+1) % numPoints; + if ( ( p[j] - p[i] ).LengthSqr() < 0.01f ) { + continue; + } + plane = Plane2DFromPoints( p[i], p[j], true ); + if ( i ) { + if ( GetAxialBevel( planes[numPlanes-1], plane, p[i], bevel ) ) { + planes[numPlanes++] = bevel; + } + } + assert( numPlanes < MAX_POINTS_ON_WINDING_2D ); + planes[numPlanes++] = plane; + } + if ( GetAxialBevel( planes[numPlanes-1], planes[0], p[0], bevel ) ) { + planes[numPlanes++] = bevel; + } + + // expand the planes + for ( i = 0; i < numPlanes; i++ ) { + v.x = bounds[ FLOATSIGNBITSET( planes[i].x ) ].x; + v.y = bounds[ FLOATSIGNBITSET( planes[i].y ) ].y; + planes[i].z += v.x * planes[i].x + v.y * planes[i].y; + } + + // get intersection points of the planes + for ( numPoints = i = 0; i < numPlanes; i++ ) { + if ( Plane2DIntersection( planes[(i+numPlanes-1) % numPlanes], planes[i], p[numPoints] ) ) { + numPoints++; + } + } +} + +/* +============ +idWinding2D::Expand +============ +*/ +void idWinding2D::Expand( const float d ) { + int i; + idVec2 edgeNormals[MAX_POINTS_ON_WINDING_2D]; + + for ( i = 0; i < numPoints; i++ ) { + idVec2 &start = p[i]; + idVec2 &end = p[(i+1)%numPoints]; + edgeNormals[i].x = start.y - end.y; + edgeNormals[i].y = end.x - start.x; + edgeNormals[i].Normalize(); + edgeNormals[i] *= d; + } + + for ( i = 0; i < numPoints; i++ ) { + p[i] += edgeNormals[i] + edgeNormals[(i+numPoints-1)%numPoints]; + } +} + +/* +============= +idWinding2D::Split +============= +*/ +int idWinding2D::Split( const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back ) const { + float dists[MAX_POINTS_ON_WINDING_2D]; + byte sides[MAX_POINTS_ON_WINDING_2D]; + int counts[3]; + float dot; + int i, j; + const idVec2 * p1, *p2; + idVec2 mid; + idWinding2D * f; + idWinding2D * b; + int maxpts; + + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + *front = *back = NULL; + + // if nothing at the front of the clipping plane + if ( !counts[SIDE_FRONT] ) { + *back = Copy(); + return SIDE_BACK; + } + // if nothing at the back of the clipping plane + if ( !counts[SIDE_BACK] ) { + *front = Copy(); + return SIDE_FRONT; + } + + maxpts = numPoints+4; // cant use counts[0]+2 because of fp grouping errors + + *front = f = new idWinding2D; + *back = b = new idWinding2D; + + for ( i = 0; i < numPoints; i++ ) { + p1 = &p[i]; + + if ( sides[i] == SIDE_ON ) { + f->p[f->numPoints] = *p1; + f->numPoints++; + b->p[b->numPoints] = *p1; + b->numPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + f->p[f->numPoints] = *p1; + f->numPoints++; + } + + if ( sides[i] == SIDE_BACK ) { + b->p[b->numPoints] = *p1; + b->numPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + // generate a split point + p2 = &p[(i+1)%numPoints]; + + // always calculate the split going from the same side + // or minor epsilon issues can happen + if ( sides[i] == SIDE_FRONT ) { + dot = dists[i] / ( dists[i] - dists[i+1] ); + for ( j = 0; j < 2; j++ ) { + // avoid round off error when possible + if ( plane[j] == 1.0f ) { + mid[j] = plane.z; + } else if ( plane[j] == -1.0f ) { + mid[j] = -plane.z; + } else { + mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]); + } + } + } else { + dot = dists[i+1] / ( dists[i+1] - dists[i] ); + for ( j = 0; j < 2; j++ ) { + // avoid round off error when possible + if ( plane[j] == 1.0f ) { + mid[j] = plane.z; + } else if ( plane[j] == -1.0f ) { + mid[j] = -plane.z; + } else { + mid[j] = (*p2)[j] + dot * ( (*p1)[j] - (*p2)[j] ); + } + } + } + + f->p[f->numPoints] = mid; + f->numPoints++; + b->p[b->numPoints] = mid; + b->numPoints++; + } + + return SIDE_CROSS; +} + +/* +============ +idWinding2D::ClipInPlace +============ +*/ +bool idWinding2D::ClipInPlace( const idVec3 &plane, const float epsilon, const bool keepOn ) { + int i, j, maxpts, newNumPoints; + int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; + float dot, dists[MAX_POINTS_ON_WINDING_2D+1]; + idVec2 *p1, *p2, mid, newPoints[MAX_POINTS_ON_WINDING_2D+4]; + + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + for ( i = 0; i < numPoints; i++ ) { + dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( dot > epsilon ) { + sides[i] = SIDE_FRONT; + } else if ( dot < -epsilon ) { + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + // if the winding is on the plane and we should keep it + if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { + return true; + } + if ( !counts[SIDE_FRONT] ) { + numPoints = 0; + return false; + } + if ( !counts[SIDE_BACK] ) { + return true; + } + + maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors + newNumPoints = 0; + + for ( i = 0; i < numPoints; i++ ) { + p1 = &p[i]; + + if ( newNumPoints+1 > maxpts ) { + return true; // can't split -- fall back to original + } + + if ( sides[i] == SIDE_ON ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + continue; + } + + if ( sides[i] == SIDE_FRONT ) { + newPoints[newNumPoints] = *p1; + newNumPoints++; + } + + if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { + continue; + } + + if ( newNumPoints+1 > maxpts ) { + return true; // can't split -- fall back to original + } + + // generate a split point + p2 = &p[(i+1)%numPoints]; + + dot = dists[i] / (dists[i] - dists[i+1]); + for ( j = 0; j < 2; j++ ) { + // avoid round off error when possible + if ( plane[j] == 1.0f ) { + mid[j] = plane.z; + } else if ( plane[j] == -1.0f ) { + mid[j] = -plane.z; + } else { + mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]); + } + } + + newPoints[newNumPoints] = mid; + newNumPoints++; + } + + if ( newNumPoints >= MAX_POINTS_ON_WINDING_2D ) { + return true; + } + + numPoints = newNumPoints; + memcpy( p, newPoints, newNumPoints * sizeof(idVec2) ); + + return true; +} + +/* +============= +idWinding2D::Copy +============= +*/ +idWinding2D *idWinding2D::Copy( void ) const { + idWinding2D *w; + + w = new idWinding2D; + w->numPoints = numPoints; + memcpy( w->p, p, numPoints * sizeof( p[0] ) ); + return w; +} + +/* +============= +idWinding2D::Reverse +============= +*/ +idWinding2D *idWinding2D::Reverse( void ) const { + idWinding2D *w; + int i; + + w = new idWinding2D; + w->numPoints = numPoints; + for ( i = 0; i < numPoints; i++ ) { + w->p[ numPoints - i - 1 ] = p[i]; + } + return w; +} + +/* +============ +idWinding2D::GetArea +============ +*/ +float idWinding2D::GetArea( void ) const { + int i; + idVec2 d1, d2; + float total; + + total = 0.0f; + for ( i = 2; i < numPoints; i++ ) { + d1 = p[i-1] - p[0]; + d2 = p[i] - p[0]; + total += d1.x * d2.y - d1.y * d2.x; + } + return total * 0.5f; +} + +/* +============ +idWinding2D::GetCenter +============ +*/ +idVec2 idWinding2D::GetCenter( void ) const { + int i; + idVec2 center; + + center.Zero(); + for ( i = 0; i < numPoints; i++ ) { + center += p[i]; + } + center *= ( 1.0f / numPoints ); + return center; +} + +/* +============ +idWinding2D::GetRadius +============ +*/ +float idWinding2D::GetRadius( const idVec2 ¢er ) const { + int i; + float radius, r; + idVec2 dir; + + radius = 0.0f; + for ( i = 0; i < numPoints; i++ ) { + dir = p[i] - center; + r = dir * dir; + if ( r > radius ) { + radius = r; + } + } + return idMath::Sqrt( radius ); +} + +/* +============ +idWinding2D::GetBounds +============ +*/ +void idWinding2D::GetBounds( idVec2 bounds[2] ) const { + int i; + + if ( !numPoints ) { + bounds[0].x = bounds[0].y = idMath::INFINITY; + bounds[1].x = bounds[1].y = -idMath::INFINITY; + return; + } + bounds[0] = bounds[1] = p[0]; + for ( i = 1; i < numPoints; i++ ) { + if ( p[i].x < bounds[0].x ) { + bounds[0].x = p[i].x; + } else if ( p[i].x > bounds[1].x ) { + bounds[1].x = p[i].x; + } + if ( p[i].y < bounds[0].y ) { + bounds[0].y = p[i].y; + } else if ( p[i].y > bounds[1].y ) { + bounds[1].y = p[i].y; + } + } +} + +/* +============= +idWinding2D::IsTiny +============= +*/ +#define EDGE_LENGTH 0.2f + +bool idWinding2D::IsTiny( void ) const { + int i; + float len; + idVec2 delta; + int edges; + + edges = 0; + for ( i = 0; i < numPoints; i++ ) { + delta = p[(i+1)%numPoints] - p[i]; + len = delta.Length(); + if ( len > EDGE_LENGTH ) { + if ( ++edges == 3 ) { + return false; + } + } + } + return true; +} + +/* +============= +idWinding2D::IsHuge +============= +*/ +bool idWinding2D::IsHuge( void ) const { + int i, j; + + for ( i = 0; i < numPoints; i++ ) { + for ( j = 0; j < 2; j++ ) { + if ( p[i][j] <= MIN_WORLD_COORD || p[i][j] >= MAX_WORLD_COORD ) { + return true; + } + } + } + return false; +} + +/* +============= +idWinding2D::Print +============= +*/ +void idWinding2D::Print( void ) const { + int i; + + for ( i = 0; i < numPoints; i++ ) { + idLib::common->Printf( "(%5.1f, %5.1f)\n", p[i][0], p[i][1] ); + } +} + +/* +============= +idWinding2D::PlaneDistance +============= +*/ +float idWinding2D::PlaneDistance( const idVec3 &plane ) const { + int i; + float d, min, max; + + min = idMath::INFINITY; + max = -min; + for ( i = 0; i < numPoints; i++ ) { + d = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( d < min ) { + min = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + if ( d > max ) { + max = d; + if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { + return 0.0f; + } + } + } + if ( FLOATSIGNBITNOTSET( min ) ) { + return min; + } + if ( FLOATSIGNBITSET( max ) ) { + return max; + } + return 0.0f; +} + +/* +============= +idWinding2D::PlaneSide +============= +*/ +int idWinding2D::PlaneSide( const idVec3 &plane, const float epsilon ) const { + bool front, back; + int i; + float d; + + front = false; + back = false; + for ( i = 0; i < numPoints; i++ ) { + d = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( d < -epsilon ) { + if ( front ) { + return SIDE_CROSS; + } + back = true; + continue; + } + else if ( d > epsilon ) { + if ( back ) { + return SIDE_CROSS; + } + front = true; + continue; + } + } + + if ( back ) { + return SIDE_BACK; + } + if ( front ) { + return SIDE_FRONT; + } + return SIDE_ON; +} + +/* +============ +idWinding2D::PointInside +============ +*/ +bool idWinding2D::PointInside( const idVec2 &point, const float epsilon ) const { + int i; + float d; + idVec3 plane; + + for ( i = 0; i < numPoints; i++ ) { + plane = Plane2DFromPoints( p[i], p[(i+1) % numPoints] ); + d = plane.x * point.x + plane.y * point.y + plane.z; + if ( d > epsilon ) { + return false; + } + } + return true; +} + +/* +============ +idWinding2D::LineIntersection +============ +*/ +bool idWinding2D::LineIntersection( const idVec2 &start, const idVec2 &end ) const { + int i, numEdges; + int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; + float d1, d2, epsilon = 0.1f; + idVec3 plane, edges[2]; + + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + plane = Plane2DFromPoints( start, end ); + for ( i = 0; i < numPoints; i++ ) { + d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( d1 > epsilon ) { + sides[i] = SIDE_FRONT; + } + else if ( d1 < -epsilon ) { + sides[i] = SIDE_BACK; + } + else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + + if ( !counts[SIDE_FRONT] ) { + return false; + } + if ( !counts[SIDE_BACK] ) { + return false; + } + + numEdges = 0; + for ( i = 0; i < numPoints; i++ ) { + if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) { + edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] ); + if ( numEdges >= 2 ) { + break; + } + } + } + if ( numEdges < 2 ) { + return false; + } + + d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z; + d2 = edges[0].x * end.x + edges[0].y * end.y + edges[0].z; + if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) { + return false; + } + d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z; + d2 = edges[1].x * end.x + edges[1].y * end.y + edges[1].z; + if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) { + return false; + } + return true; +} + +/* +============ +idWinding2D::RayIntersection +============ +*/ +bool idWinding2D::RayIntersection( const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums ) const { + int i, numEdges, localEdgeNums[2]; + int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; + float d1, d2, epsilon = 0.1f; + idVec3 plane, edges[2]; + + scale1 = scale2 = 0.0f; + counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; + + plane = Plane2DFromVecs( start, dir ); + for ( i = 0; i < numPoints; i++ ) { + d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z; + if ( d1 > epsilon ) { + sides[i] = SIDE_FRONT; + } + else if ( d1 < -epsilon ) { + sides[i] = SIDE_BACK; + } + else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + + if ( !counts[SIDE_FRONT] ) { + return false; + } + if ( !counts[SIDE_BACK] ) { + return false; + } + + numEdges = 0; + for ( i = 0; i < numPoints; i++ ) { + if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) { + localEdgeNums[numEdges] = i; + edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] ); + if ( numEdges >= 2 ) { + break; + } + } + } + if ( numEdges < 2 ) { + return false; + } + + d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z; + d2 = - ( edges[0].x * dir.x + edges[0].y * dir.y ); + if ( d2 == 0.0f ) { + return false; + } + scale1 = d1 / d2; + d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z; + d2 = - ( edges[1].x * dir.x + edges[1].y * dir.y ); + if ( d2 == 0.0f ) { + return false; + } + scale2 = d1 / d2; + + if ( idMath::Fabs( scale1 ) > idMath::Fabs( scale2 ) ) { + idSwap( scale1, scale2 ); + idSwap( localEdgeNums[0], localEdgeNums[1] ); + } + + if ( edgeNums ) { + edgeNums[0] = localEdgeNums[0]; + edgeNums[1] = localEdgeNums[1]; + } + return true; +} diff --git a/idlib/geometry/Winding2D.h b/idlib/geometry/Winding2D.h new file mode 100644 index 000000000..b5c26dccb --- /dev/null +++ b/idlib/geometry/Winding2D.h @@ -0,0 +1,160 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __WINDING2D_H__ +#define __WINDING2D_H__ + +/* +=============================================================================== + + A 2D winding is an arbitrary convex 2D polygon defined by an array of points. + +=============================================================================== +*/ + +#define MAX_POINTS_ON_WINDING_2D 16 + + +class idWinding2D { +public: + idWinding2D( void ); + + idWinding2D & operator=( const idWinding2D &winding ); + const idVec2 & operator[]( const int index ) const; + idVec2 & operator[]( const int index ); + + void Clear( void ); + void AddPoint( const idVec2 &point ); + int GetNumPoints( void ) const; + + void Expand( const float d ); + void ExpandForAxialBox( const idVec2 bounds[2] ); + + // splits the winding into a front and back winding, the winding itself stays unchanged + // returns a SIDE_? + int Split( const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back ) const; + // cuts off the part at the back side of the plane, returns true if some part was at the front + // if there is nothing at the front the number of points is set to zero + bool ClipInPlace( const idVec3 &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); + + idWinding2D * Copy( void ) const; + idWinding2D * Reverse( void ) const; + + float GetArea( void ) const; + idVec2 GetCenter( void ) const; + float GetRadius( const idVec2 ¢er ) const; + void GetBounds( idVec2 bounds[2] ) const; + + bool IsTiny( void ) const; + bool IsHuge( void ) const; // base winding for a plane is typically huge + void Print( void ) const; + + float PlaneDistance( const idVec3 &plane ) const; + int PlaneSide( const idVec3 &plane, const float epsilon = ON_EPSILON ) const; + + bool PointInside( const idVec2 &point, const float epsilon ) const; + bool LineIntersection( const idVec2 &start, const idVec2 &end ) const; + bool RayIntersection( const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums = NULL ) const; + + static idVec3 Plane2DFromPoints( const idVec2 &start, const idVec2 &end, const bool normalize = false ); + static idVec3 Plane2DFromVecs( const idVec2 &start, const idVec2 &dir, const bool normalize = false ); + static bool Plane2DIntersection( const idVec3 &plane1, const idVec3 &plane2, idVec2 &point ); + +private: + int numPoints; + idVec2 p[MAX_POINTS_ON_WINDING_2D]; +}; + +ID_INLINE idWinding2D::idWinding2D( void ) { + numPoints = 0; +} + +ID_INLINE idWinding2D &idWinding2D::operator=( const idWinding2D &winding ) { + int i; + + for ( i = 0; i < winding.numPoints; i++ ) { + p[i] = winding.p[i]; + } + numPoints = winding.numPoints; + return *this; +} + +ID_INLINE const idVec2 &idWinding2D::operator[]( const int index ) const { + return p[ index ]; +} + +ID_INLINE idVec2 &idWinding2D::operator[]( const int index ) { + return p[ index ]; +} + +ID_INLINE void idWinding2D::Clear( void ) { + numPoints = 0; +} + +ID_INLINE void idWinding2D::AddPoint( const idVec2 &point ) { + p[numPoints++] = point; +} + +ID_INLINE int idWinding2D::GetNumPoints( void ) const { + return numPoints; +} + +ID_INLINE idVec3 idWinding2D::Plane2DFromPoints( const idVec2 &start, const idVec2 &end, const bool normalize ) { + idVec3 plane; + plane.x = start.y - end.y; + plane.y = end.x - start.x; + if ( normalize ) { + plane.ToVec2().Normalize(); + } + plane.z = - ( start.x * plane.x + start.y * plane.y ); + return plane; +} + +ID_INLINE idVec3 idWinding2D::Plane2DFromVecs( const idVec2 &start, const idVec2 &dir, const bool normalize ) { + idVec3 plane; + plane.x = -dir.y; + plane.y = dir.x; + if ( normalize ) { + plane.ToVec2().Normalize(); + } + plane.z = - ( start.x * plane.x + start.y * plane.y ); + return plane; +} + +ID_INLINE bool idWinding2D::Plane2DIntersection( const idVec3 &plane1, const idVec3 &plane2, idVec2 &point ) { + float n00, n01, n11, det, invDet, f0, f1; + + n00 = plane1.x * plane1.x + plane1.y * plane1.y; + n01 = plane1.x * plane2.x + plane1.y * plane2.y; + n11 = plane2.x * plane2.x + plane2.y * plane2.y; + det = n00 * n11 - n01 * n01; + + if ( idMath::Fabs(det) < 1e-6f ) { + return false; + } + + invDet = 1.0f / det; + f0 = ( n01 * plane2.z - n11 * plane1.z ) * invDet; + f1 = ( n01 * plane1.z - n00 * plane2.z ) * invDet; + point.x = f0 * plane1.x + f1 * plane2.x; + point.y = f0 * plane1.y + f1 * plane2.y; + return true; +} + +#endif /* !__WINDING2D_H__ */ diff --git a/idlib/geometry/drawvert.cpp b/idlib/geometry/drawvert.cpp deleted file mode 100644 index ad4b8db92..000000000 --- a/idlib/geometry/drawvert.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============= -idDrawVert::Normalize -============= -*/ -void idDrawVert::Normalize( void ) { - normal.Normalize(); - tangents[1].Cross( normal, tangents[0] ); - tangents[1].Normalize(); - tangents[0].Cross( tangents[1], normal ); - tangents[0].Normalize(); -} diff --git a/idlib/geometry/drawvert.h b/idlib/geometry/drawvert.h deleted file mode 100644 index 3fd28ddcd..000000000 --- a/idlib/geometry/drawvert.h +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __DRAWVERT_H__ -#define __DRAWVERT_H__ - -/* -=============================================================================== - - Draw Vertex. - -=============================================================================== -*/ - -class idDrawVert { -public: - idVec3 xyz; - idVec2 st; - idVec3 normal; - idVec3 tangents[2]; - byte color[4]; -#if 0 // was MACOS_X see comments concerning DRAWVERT_PADDED in Simd_Altivec.h - float padding; -#endif - float operator[]( const int index ) const; - float & operator[]( const int index ); - - void Clear( void ); - - void Lerp( const idDrawVert &a, const idDrawVert &b, const float f ); - void LerpAll( const idDrawVert &a, const idDrawVert &b, const float f ); - - void Normalize( void ); - // stgatilov: this normalization scales normal/tangents by common factor, so that normal becomes unit length. - void ScaleToUnitNormal( void ); - - void SetColor( dword color ); - dword GetColor( void ) const; -}; - -ID_INLINE float idDrawVert::operator[]( const int index ) const { - assert( index >= 0 && index < 5 ); - return ((float *)(&xyz))[index]; -} -ID_INLINE float &idDrawVert::operator[]( const int index ) { - assert( index >= 0 && index < 5 ); - return ((float *)(&xyz))[index]; -} - -ID_INLINE void idDrawVert::Clear( void ) { - xyz.Zero(); - st.Zero(); - normal.Zero(); - tangents[0].Zero(); - tangents[1].Zero(); - color[0] = color[1] = color[2] = color[3] = 0; -} - -ID_INLINE void idDrawVert::Lerp( const idDrawVert &a, const idDrawVert &b, const float f ) { - xyz = a.xyz + f * ( b.xyz - a.xyz ); - st = a.st + f * ( b.st - a.st ); -} - -ID_INLINE void idDrawVert::LerpAll( const idDrawVert &a, const idDrawVert &b, const float f ) { - xyz = a.xyz + f * ( b.xyz - a.xyz ); - st = a.st + f * ( b.st - a.st ); - normal = a.normal + f * ( b.normal - a.normal ); - tangents[0] = a.tangents[0] + f * ( b.tangents[0] - a.tangents[0] ); - tangents[1] = a.tangents[1] + f * ( b.tangents[1] - a.tangents[1] ); - color[0] = (byte)( a.color[0] + f * ( b.color[0] - a.color[0] ) ); - color[1] = (byte)( a.color[1] + f * ( b.color[1] - a.color[1] ) ); - color[2] = (byte)( a.color[2] + f * ( b.color[2] - a.color[2] ) ); - color[3] = (byte)( a.color[3] + f * ( b.color[3] - a.color[3] ) ); -} - -ID_INLINE void idDrawVert::SetColor( dword color ) { - *reinterpret_cast(this->color) = color; -} - -ID_INLINE dword idDrawVert::GetColor( void ) const { - return *reinterpret_cast(this->color); -} - -ID_INLINE void idDrawVert::ScaleToUnitNormal( void ) { - float invNormLen = idMath::RSqrt(normal.LengthSqr()); - if (invNormLen == 1.0f) return; - normal *= invNormLen; - tangents[0] *= invNormLen; - tangents[1] *= invNormLen; -} - - -#endif /* !__DRAWVERT_H__ */ diff --git a/idlib/geometry/jointtransform.cpp b/idlib/geometry/jointtransform.cpp deleted file mode 100644 index 2c157739a..000000000 --- a/idlib/geometry/jointtransform.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============= -idJointMat::ToJointQuat -============= -*/ -idJointQuat idJointMat::ToJointQuat( void ) const { - idJointQuat jq; - float trace; - float s; - float t; - int i; - int j; - int k; - - static int next[3] = { 1, 2, 0 }; - - trace = mat[0 * 4 + 0] + mat[1 * 4 + 1] + mat[2 * 4 + 2]; - - if ( trace > 0.0f ) { - - t = trace + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - jq.q[3] = s * t; - jq.q[0] = ( mat[1 * 4 + 2] - mat[2 * 4 + 1] ) * s; - jq.q[1] = ( mat[2 * 4 + 0] - mat[0 * 4 + 2] ) * s; - jq.q[2] = ( mat[0 * 4 + 1] - mat[1 * 4 + 0] ) * s; - - } else { - - i = 0; - if ( mat[1 * 4 + 1] > mat[0 * 4 + 0] ) { - i = 1; - } - if ( mat[2 * 4 + 2] > mat[i * 4 + i] ) { - i = 2; - } - j = next[i]; - k = next[j]; - - t = ( mat[i * 4 + i] - ( mat[j * 4 + j] + mat[k * 4 + k] ) ) + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - jq.q[i] = s * t; - jq.q[3] = ( mat[j * 4 + k] - mat[k * 4 + j] ) * s; - jq.q[j] = ( mat[i * 4 + j] + mat[j * 4 + i] ) * s; - jq.q[k] = ( mat[i * 4 + k] + mat[k * 4 + i] ) * s; - } - - jq.t[0] = mat[0 * 4 + 3]; - jq.t[1] = mat[1 * 4 + 3]; - jq.t[2] = mat[2 * 4 + 3]; - - return jq; -} diff --git a/idlib/geometry/jointtransform.h b/idlib/geometry/jointtransform.h deleted file mode 100644 index 16f481b56..000000000 --- a/idlib/geometry/jointtransform.h +++ /dev/null @@ -1,229 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __JOINTTRANSFORM_H__ -#define __JOINTTRANSFORM_H__ - -/* -=============================================================================== - - Joint Quaternion - -=============================================================================== -*/ - -class idJointQuat { -public: - - idQuat q; - idVec3 t; -}; - - -/* -=============================================================================== - - Joint Matrix - - idMat3 m; - idVec3 t; - - m[0][0], m[1][0], m[2][0], t[0] - m[0][1], m[1][1], m[2][1], t[1] - m[0][2], m[1][2], m[2][2], t[2] - -=============================================================================== -*/ - -class idJointMat { -public: - - void SetRotation( const idMat3 &m ); - void SetTranslation( const idVec3 &t ); - - idVec3 operator*( const idVec3 &v ) const; // only rotate - idVec3 operator*( const idVec4 &v ) const; // rotate and translate - - idJointMat & operator*=( const idJointMat &a ); // transform - idJointMat & operator/=( const idJointMat &a ); // untransform - - bool Compare( const idJointMat &a ) const; // exact compare, no epsilon - bool Compare( const idJointMat &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idJointMat &a ) const; // exact compare, no epsilon - bool operator!=( const idJointMat &a ) const; // exact compare, no epsilon - - idMat3 ToMat3( void ) const; - idVec3 ToVec3( void ) const; - idJointQuat ToJointQuat( void ) const; - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - -private: - float mat[3*4]; -}; - -ID_INLINE void idJointMat::SetRotation( const idMat3 &m ) { - // NOTE: idMat3 is transposed because it is column-major - mat[0 * 4 + 0] = m[0][0]; - mat[0 * 4 + 1] = m[1][0]; - mat[0 * 4 + 2] = m[2][0]; - mat[1 * 4 + 0] = m[0][1]; - mat[1 * 4 + 1] = m[1][1]; - mat[1 * 4 + 2] = m[2][1]; - mat[2 * 4 + 0] = m[0][2]; - mat[2 * 4 + 1] = m[1][2]; - mat[2 * 4 + 2] = m[2][2]; -} - -ID_INLINE void idJointMat::SetTranslation( const idVec3 &t ) { - mat[0 * 4 + 3] = t[0]; - mat[1 * 4 + 3] = t[1]; - mat[2 * 4 + 3] = t[2]; -} - -ID_INLINE idVec3 idJointMat::operator*( const idVec3 &v ) const { - return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2], - mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2], - mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] ); -} - -ID_INLINE idVec3 idJointMat::operator*( const idVec4 &v ) const { - return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2] + mat[0 * 4 + 3] * v[3], - mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2] + mat[1 * 4 + 3] * v[3], - mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] + mat[2 * 4 + 3] * v[3] ); -} - -ID_INLINE idJointMat &idJointMat::operator*=( const idJointMat &a ) { - float dst[3]; - - dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[0 * 4 + 1] + mat[2 * 4 + 0] * a.mat[0 * 4 + 2]; - dst[1] = mat[0 * 4 + 0] * a.mat[1 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[1 * 4 + 2]; - dst[2] = mat[0 * 4 + 0] * a.mat[2 * 4 + 0] + mat[1 * 4 + 0] * a.mat[2 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 0] = dst[0]; - mat[1 * 4 + 0] = dst[1]; - mat[2 * 4 + 0] = dst[2]; - - dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[0 * 4 + 1] + mat[2 * 4 + 1] * a.mat[0 * 4 + 2]; - dst[1] = mat[0 * 4 + 1] * a.mat[1 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[1 * 4 + 2]; - dst[2] = mat[0 * 4 + 1] * a.mat[2 * 4 + 0] + mat[1 * 4 + 1] * a.mat[2 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 1] = dst[0]; - mat[1 * 4 + 1] = dst[1]; - mat[2 * 4 + 1] = dst[2]; - - dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[0 * 4 + 1] + mat[2 * 4 + 2] * a.mat[0 * 4 + 2]; - dst[1] = mat[0 * 4 + 2] * a.mat[1 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[1 * 4 + 2]; - dst[2] = mat[0 * 4 + 2] * a.mat[2 * 4 + 0] + mat[1 * 4 + 2] * a.mat[2 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 2] = dst[0]; - mat[1 * 4 + 2] = dst[1]; - mat[2 * 4 + 2] = dst[2]; - - dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[0 * 4 + 1] + mat[2 * 4 + 3] * a.mat[0 * 4 + 2]; - dst[1] = mat[0 * 4 + 3] * a.mat[1 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[1 * 4 + 2]; - dst[2] = mat[0 * 4 + 3] * a.mat[2 * 4 + 0] + mat[1 * 4 + 3] * a.mat[2 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 3] = dst[0]; - mat[1 * 4 + 3] = dst[1]; - mat[2 * 4 + 3] = dst[2]; - - mat[0 * 4 + 3] += a.mat[0 * 4 + 3]; - mat[1 * 4 + 3] += a.mat[1 * 4 + 3]; - mat[2 * 4 + 3] += a.mat[2 * 4 + 3]; - - return *this; -} - -ID_INLINE idJointMat &idJointMat::operator/=( const idJointMat &a ) { - float dst[3]; - - mat[0 * 4 + 3] -= a.mat[0 * 4 + 3]; - mat[1 * 4 + 3] -= a.mat[1 * 4 + 3]; - mat[2 * 4 + 3] -= a.mat[2 * 4 + 3]; - - dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 0] + mat[2 * 4 + 0] * a.mat[2 * 4 + 0]; - dst[1] = mat[0 * 4 + 0] * a.mat[0 * 4 + 1] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 1]; - dst[2] = mat[0 * 4 + 0] * a.mat[0 * 4 + 2] + mat[1 * 4 + 0] * a.mat[1 * 4 + 2] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 0] = dst[0]; - mat[1 * 4 + 0] = dst[1]; - mat[2 * 4 + 0] = dst[2]; - - dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 0] + mat[2 * 4 + 1] * a.mat[2 * 4 + 0]; - dst[1] = mat[0 * 4 + 1] * a.mat[0 * 4 + 1] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 1]; - dst[2] = mat[0 * 4 + 1] * a.mat[0 * 4 + 2] + mat[1 * 4 + 1] * a.mat[1 * 4 + 2] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 1] = dst[0]; - mat[1 * 4 + 1] = dst[1]; - mat[2 * 4 + 1] = dst[2]; - - dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 0] + mat[2 * 4 + 2] * a.mat[2 * 4 + 0]; - dst[1] = mat[0 * 4 + 2] * a.mat[0 * 4 + 1] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 1]; - dst[2] = mat[0 * 4 + 2] * a.mat[0 * 4 + 2] + mat[1 * 4 + 2] * a.mat[1 * 4 + 2] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 2] = dst[0]; - mat[1 * 4 + 2] = dst[1]; - mat[2 * 4 + 2] = dst[2]; - - dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 0] + mat[2 * 4 + 3] * a.mat[2 * 4 + 0]; - dst[1] = mat[0 * 4 + 3] * a.mat[0 * 4 + 1] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 1]; - dst[2] = mat[0 * 4 + 3] * a.mat[0 * 4 + 2] + mat[1 * 4 + 3] * a.mat[1 * 4 + 2] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; - mat[0 * 4 + 3] = dst[0]; - mat[1 * 4 + 3] = dst[1]; - mat[2 * 4 + 3] = dst[2]; - - return *this; -} - -ID_INLINE bool idJointMat::Compare( const idJointMat &a ) const { - int i; - - for ( i = 0; i < 12; i++ ) { - if ( mat[i] != a.mat[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idJointMat::Compare( const idJointMat &a, const float epsilon ) const { - int i; - - for ( i = 0; i < 12; i++ ) { - if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idJointMat::operator==( const idJointMat &a ) const { - return Compare( a ); -} - -ID_INLINE bool idJointMat::operator!=( const idJointMat &a ) const { - return !Compare( a ); -} - -ID_INLINE idMat3 idJointMat::ToMat3( void ) const { - return idMat3( mat[0 * 4 + 0], mat[1 * 4 + 0], mat[2 * 4 + 0], - mat[0 * 4 + 1], mat[1 * 4 + 1], mat[2 * 4 + 1], - mat[0 * 4 + 2], mat[1 * 4 + 2], mat[2 * 4 + 2] ); -} - -ID_INLINE idVec3 idJointMat::ToVec3( void ) const { - return idVec3( mat[0 * 4 + 3], mat[1 * 4 + 3], mat[2 * 4 + 3] ); -} - -ID_INLINE const float *idJointMat::ToFloatPtr( void ) const { - return mat; -} - -ID_INLINE float *idJointMat::ToFloatPtr( void ) { - return mat; -} - -#endif /* !__JOINTTRANSFORM_H__ */ diff --git a/idlib/geometry/surface.cpp b/idlib/geometry/surface.cpp deleted file mode 100644 index 3e9135f9d..000000000 --- a/idlib/geometry/surface.cpp +++ /dev/null @@ -1,915 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -================= -UpdateVertexIndex -================= -*/ -ID_INLINE int UpdateVertexIndex( int vertexIndexNum[2], int *vertexRemap, int *vertexCopyIndex, int vertNum ) { - int s = INTSIGNBITSET( vertexRemap[vertNum] ); - vertexIndexNum[0] = vertexRemap[vertNum]; - vertexRemap[vertNum] = vertexIndexNum[s]; - vertexIndexNum[1] += s; - vertexCopyIndex[vertexRemap[vertNum]] = vertNum; - return vertexRemap[vertNum]; -} - -/* -================= -idSurface::Split -================= -*/ -int idSurface::Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges, int *backOnPlaneEdges ) const { - float * dists; - float f; - byte * sides; - int counts[3]; - int * edgeSplitVertex; - int numEdgeSplitVertexes; - int * vertexRemap[2]; - int vertexIndexNum[2][2]; - int * vertexCopyIndex[2]; - int * indexPtr[2]; - int indexNum[2]; - int * index; - int * onPlaneEdges[2]; - int numOnPlaneEdges[2]; - int maxOnPlaneEdges; - int i; - idSurface * surface[2]; - idDrawVert v; - - dists = (float *) _alloca( verts.Num() * sizeof( float ) ); - sides = (byte *) _alloca( verts.Num() * sizeof( byte ) ); - - counts[0] = counts[1] = counts[2] = 0; - - // determine side for each vertex - for ( i = 0; i < verts.Num(); i++ ) { - dists[i] = f = plane.Distance( verts[i].xyz ); - if ( f > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( f < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - - *front = *back = NULL; - - // if coplanar, put on the front side if the normals match - if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - - f = ( verts[indexes[1]].xyz - verts[indexes[0]].xyz ).Cross( verts[indexes[0]].xyz - verts[indexes[2]].xyz ) * plane.Normal(); - if ( FLOATSIGNBITSET( f ) ) { - *back = new idSurface( *this ); - return SIDE_BACK; - } else { - *front = new idSurface( *this ); - return SIDE_FRONT; - } - } - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - *back = new idSurface( *this ); - return SIDE_BACK; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - *front = new idSurface( *this ); - return SIDE_FRONT; - } - - // allocate front and back surface - *front = surface[0] = new idSurface(); - *back = surface[1] = new idSurface(); - - edgeSplitVertex = (int *) _alloca( edges.Num() * sizeof( int ) ); - numEdgeSplitVertexes = 0; - - maxOnPlaneEdges = 4 * counts[SIDE_ON]; - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - // split edges - for ( i = 0; i < edges.Num(); i++ ) { - int v0 = edges[i].verts[0]; - int v1 = edges[i].verts[1]; - int sidesOr = ( sides[v0] | sides[v1] ); - - // if both vertexes are on the same side or one is on the clipping plane - if ( !( sides[v0] ^ sides[v1] ) || ( sidesOr & SIDE_ON ) ) { - edgeSplitVertex[i] = -1; - counts[sidesOr & SIDE_BACK]++; - counts[SIDE_ON] += ( sidesOr & SIDE_ON ) >> 1; - } else { - f = dists[v0] / ( dists[v0] - dists[v1] ); - v.LerpAll( verts[v0], verts[v1], f ); - edgeSplitVertex[i] = numEdgeSplitVertexes++; - surface[0]->verts.Append( v ); - surface[1]->verts.Append( v ); - } - } - - // each edge is shared by at most two triangles, as such there can never be more indexes than twice the number of edges - surface[0]->indexes.Resize( ( ( counts[SIDE_FRONT] + counts[SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) ); - surface[1]->indexes.Resize( ( ( counts[SIDE_BACK] + counts[SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) ); - - // allocate indexes to construct the triangle indexes for the front and back surface - vertexRemap[0] = (int *) _alloca( verts.Num() * sizeof( int ) ); - memset( vertexRemap[0], -1, verts.Num() * sizeof( int ) ); - vertexRemap[1] = (int *) _alloca( verts.Num() * sizeof( int ) ); - memset( vertexRemap[1], -1, verts.Num() * sizeof( int ) ); - - vertexCopyIndex[0] = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); - vertexCopyIndex[1] = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); - - vertexIndexNum[0][0] = vertexIndexNum[1][0] = 0; - vertexIndexNum[0][1] = vertexIndexNum[1][1] = numEdgeSplitVertexes; - - indexPtr[0] = surface[0]->indexes.Ptr(); - indexPtr[1] = surface[1]->indexes.Ptr(); - indexNum[0] = surface[0]->indexes.Num(); - indexNum[1] = surface[1]->indexes.Num(); - - maxOnPlaneEdges += 4 * numEdgeSplitVertexes; - // allocate one more in case no triangles are actually split which may happen for a disconnected surface - onPlaneEdges[0] = (int *) _alloca( ( maxOnPlaneEdges + 1 ) * sizeof( int ) ); - onPlaneEdges[1] = (int *) _alloca( ( maxOnPlaneEdges + 1 ) * sizeof( int ) ); - numOnPlaneEdges[0] = numOnPlaneEdges[1] = 0; - - // split surface triangles - for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { - int e0, e1, e2, v0, v1, v2, s, n; - - e0 = abs( edgeIndexes[i+0] ); - e1 = abs( edgeIndexes[i+1] ); - e2 = abs( edgeIndexes[i+2] ); - - v0 = indexes[i+0]; - v1 = indexes[i+1]; - v2 = indexes[i+2]; - - switch( ( INTSIGNBITSET( edgeSplitVertex[e0] ) | ( INTSIGNBITSET( edgeSplitVertex[e1] ) << 1 ) | ( INTSIGNBITSET( edgeSplitVertex[e2] ) << 2 ) ) ^ 7 ) { - case 0: { // no edges split - if ( ( sides[v0] & sides[v1] & sides[v2] ) & SIDE_ON ) { - // coplanar - f = ( verts[v1].xyz - verts[v0].xyz ).Cross( verts[v0].xyz - verts[v2].xyz ) * plane.Normal(); - s = FLOATSIGNBITSET( f ); - } else { - s = ( sides[v0] | sides[v1] | sides[v2] ) & SIDE_BACK; - } - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]] = n; - numOnPlaneEdges[s] += ( sides[v0] & sides[v1] ) >> 1; - onPlaneEdges[s][numOnPlaneEdges[s]] = n+1; - numOnPlaneEdges[s] += ( sides[v1] & sides[v2] ) >> 1; - onPlaneEdges[s][numOnPlaneEdges[s]] = n+2; - numOnPlaneEdges[s] += ( sides[v2] & sides[v0] ) >> 1; - index = indexPtr[s]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - indexNum[s] = n; - break; - } - case 1: { // first edge split - s = sides[v0] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e0]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - index[n++] = edgeSplitVertex[e0]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - indexNum[s] = n; - break; - } - case 2: { // second edge split - s = sides[v1] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e1]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - index[n++] = edgeSplitVertex[e1]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - indexNum[s] = n; - break; - } - case 3: { // first and second edge split - s = sides[v1] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e1]; - index[n++] = edgeSplitVertex[e0]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e0]; - index[n++] = edgeSplitVertex[e1]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - index[n++] = edgeSplitVertex[e1]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - indexNum[s] = n; - break; - } - case 4: { // third edge split - s = sides[v2] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e2]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = edgeSplitVertex[e2]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - indexNum[s] = n; - break; - } - case 5: { // first and third edge split - s = sides[v0] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e0]; - index[n++] = edgeSplitVertex[e2]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e2]; - index[n++] = edgeSplitVertex[e0]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - index[n++] = edgeSplitVertex[e2]; - indexNum[s] = n; - break; - } - case 6: { // second and third edge split - s = sides[v2] & SIDE_BACK; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e2]; - index[n++] = edgeSplitVertex[e1]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 ); - indexNum[s] = n; - s ^= 1; - n = indexNum[s]; - onPlaneEdges[s][numOnPlaneEdges[s]++] = n; - index = indexPtr[s]; - index[n++] = edgeSplitVertex[e1]; - index[n++] = edgeSplitVertex[e2]; - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 ); - index[n++] = UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 ); - index[n++] = edgeSplitVertex[e2]; - indexNum[s] = n; - break; - } - } - } - - surface[0]->indexes.SetNum( indexNum[0], false ); - surface[1]->indexes.SetNum( indexNum[1], false ); - - // copy vertexes - surface[0]->verts.SetNum( vertexIndexNum[0][1], false ); - index = vertexCopyIndex[0]; - for ( i = numEdgeSplitVertexes; i < surface[0]->verts.Num(); i++ ) { - surface[0]->verts[i] = verts[index[i]]; - } - surface[1]->verts.SetNum( vertexIndexNum[1][1], false ); - index = vertexCopyIndex[1]; - for ( i = numEdgeSplitVertexes; i < surface[1]->verts.Num(); i++ ) { - surface[1]->verts[i] = verts[index[i]]; - } - - // generate edge indexes - surface[0]->GenerateEdgeIndexes(); - surface[1]->GenerateEdgeIndexes(); - - if ( frontOnPlaneEdges ) { - memcpy( frontOnPlaneEdges, onPlaneEdges[0], numOnPlaneEdges[0] * sizeof( int ) ); - frontOnPlaneEdges[numOnPlaneEdges[0]] = -1; - } - - if ( backOnPlaneEdges ) { - memcpy( backOnPlaneEdges, onPlaneEdges[1], numOnPlaneEdges[1] * sizeof( int ) ); - backOnPlaneEdges[numOnPlaneEdges[1]] = -1; - } - - return SIDE_CROSS; -} - -/* -================= -idSurface::ClipInPlace -================= -*/ -bool idSurface::ClipInPlace( const idPlane &plane, const float epsilon, const bool keepOn ) { - float * dists; - float f; - byte * sides; - int counts[3]; - int i; - int * edgeSplitVertex; - int * vertexRemap; - int vertexIndexNum[2]; - int * vertexCopyIndex; - int * indexPtr; - int indexNum; - int numEdgeSplitVertexes; - idDrawVert v; - idList newVerts; - idList newIndexes; - - dists = (float *) _alloca( verts.Num() * sizeof( float ) ); - sides = (byte *) _alloca( verts.Num() * sizeof( byte ) ); - - counts[0] = counts[1] = counts[2] = 0; - - // determine side for each vertex - for ( i = 0; i < verts.Num(); i++ ) { - dists[i] = f = plane.Distance( verts[i].xyz ); - if ( f > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( f < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - - // if coplanar, put on the front side if the normals match - if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - - f = ( verts[indexes[1]].xyz - verts[indexes[0]].xyz ).Cross( verts[indexes[0]].xyz - verts[indexes[2]].xyz ) * plane.Normal(); - if ( FLOATSIGNBITSET( f ) ) { - Clear(); - return false; - } else { - return true; - } - } - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - Clear(); - return false; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - return true; - } - - edgeSplitVertex = (int *) _alloca( edges.Num() * sizeof( int ) ); - numEdgeSplitVertexes = 0; - - counts[SIDE_FRONT] = counts[SIDE_BACK] = 0; - - // split edges - for ( i = 0; i < edges.Num(); i++ ) { - int v0 = edges[i].verts[0]; - int v1 = edges[i].verts[1]; - - // if both vertexes are on the same side or one is on the clipping plane - if ( !( sides[v0] ^ sides[v1] ) || ( ( sides[v0] | sides[v1] ) & SIDE_ON ) ) { - edgeSplitVertex[i] = -1; - counts[(sides[v0]|sides[v1]) & SIDE_BACK]++; - } else { - f = dists[v0] / ( dists[v0] - dists[v1] ); - v.LerpAll( verts[v0], verts[v1], f ); - edgeSplitVertex[i] = numEdgeSplitVertexes++; - newVerts.Append( v ); - } - } - - // each edge is shared by at most two triangles, as such there can never be - // more indexes than twice the number of edges - newIndexes.Resize( ( counts[SIDE_FRONT] << 1 ) + ( numEdgeSplitVertexes << 2 ) ); - - // allocate indexes to construct the triangle indexes for the front and back surface - vertexRemap = (int *) _alloca( verts.Num() * sizeof( int ) ); - memset( vertexRemap, -1, verts.Num() * sizeof( int ) ); - - vertexCopyIndex = (int *) _alloca( ( numEdgeSplitVertexes + verts.Num() ) * sizeof( int ) ); - - vertexIndexNum[0] = 0; - vertexIndexNum[1] = numEdgeSplitVertexes; - - indexPtr = newIndexes.Ptr(); - indexNum = newIndexes.Num(); - - // split surface triangles - for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { - int e0, e1, e2, v0, v1, v2; - - e0 = abs( edgeIndexes[i+0] ); - e1 = abs( edgeIndexes[i+1] ); - e2 = abs( edgeIndexes[i+2] ); - - v0 = indexes[i+0]; - v1 = indexes[i+1]; - v2 = indexes[i+2]; - - switch( ( INTSIGNBITSET( edgeSplitVertex[e0] ) | ( INTSIGNBITSET( edgeSplitVertex[e1] ) << 1 ) | ( INTSIGNBITSET( edgeSplitVertex[e2] ) << 2 ) ) ^ 7 ) { - case 0: { // no edges split - if ( ( sides[v0] | sides[v1] | sides[v2] ) & SIDE_BACK ) { - break; - } - if ( ( sides[v0] & sides[v1] & sides[v2] ) & SIDE_ON ) { - // coplanar - if ( !keepOn ) { - break; - } - f = ( verts[v1].xyz - verts[v0].xyz ).Cross( verts[v0].xyz - verts[v2].xyz ) * plane.Normal(); - if ( FLOATSIGNBITSET( f ) ) { - break; - } - } - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - break; - } - case 1: { // first edge split - if ( !( sides[v0] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = edgeSplitVertex[e0]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - } else { - indexPtr[indexNum++] = edgeSplitVertex[e0]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - } - break; - } - case 2: { // second edge split - if ( !( sides[v1] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - } else { - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - } - break; - } - case 3: { // first and second edge split - if ( !( sides[v1] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = edgeSplitVertex[e0]; - } else { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = edgeSplitVertex[e0]; - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - } - break; - } - case 4: { // third edge split - if ( !( sides[v2] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - indexPtr[indexNum++] = edgeSplitVertex[e2]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - } else { - indexPtr[indexNum++] = edgeSplitVertex[e2]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - } - break; - } - case 5: { // first and third edge split - if ( !( sides[v0] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = edgeSplitVertex[e0]; - indexPtr[indexNum++] = edgeSplitVertex[e2]; - } else { - indexPtr[indexNum++] = edgeSplitVertex[e0]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = edgeSplitVertex[e2]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - indexPtr[indexNum++] = edgeSplitVertex[e2]; - } - break; - } - case 6: { // second and third edge split - if ( !( sides[v2] & SIDE_BACK ) ) { - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 ); - indexPtr[indexNum++] = edgeSplitVertex[e2]; - indexPtr[indexNum++] = edgeSplitVertex[e1]; - } else { - indexPtr[indexNum++] = edgeSplitVertex[e2]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = edgeSplitVertex[e1]; - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 ); - indexPtr[indexNum++] = UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 ); - indexPtr[indexNum++] = edgeSplitVertex[e2]; - } - break; - } - } - } - - newIndexes.SetNum( indexNum, false ); - - // copy vertexes - newVerts.SetNum( vertexIndexNum[1], false ); - for ( i = numEdgeSplitVertexes; i < newVerts.Num(); i++ ) { - newVerts[i] = verts[vertexCopyIndex[i]]; - } - - // copy back to this surface - indexes = newIndexes; - verts = newVerts; - - GenerateEdgeIndexes(); - - return true; -} - -/* -============= -idSurface::IsConnected -============= -*/ -bool idSurface::IsConnected( void ) const { - int i, j, numIslands, numTris; - int queueStart, queueEnd; - int *queue, *islandNum; - int curTri, nextTri, edgeNum; - const int *index; - - numIslands = 0; - numTris = indexes.Num() / 3; - islandNum = (int *) _alloca16( numTris * sizeof( int ) ); - memset( islandNum, -1, numTris * sizeof( int ) ); - queue = (int *) _alloca16( numTris * sizeof( int ) ); - - for ( i = 0; i < numTris; i++ ) { - - if ( islandNum[i] != -1 ) { - continue; - } - - queueStart = 0; - queueEnd = 1; - queue[0] = i; - islandNum[i] = numIslands; - - for ( curTri = queue[queueStart]; queueStart < queueEnd; curTri = queue[++queueStart] ) { - - index = &edgeIndexes[curTri * 3]; - - for ( j = 0; j < 3; j++ ) { - - edgeNum = index[j]; - nextTri = edges[abs(edgeNum)].tris[INTSIGNBITNOTSET(edgeNum)]; - - if ( nextTri == -1 ) { - continue; - } - - nextTri /= 3; - - if ( islandNum[nextTri] != -1 ) { - continue; - } - - queue[queueEnd++] = nextTri; - islandNum[nextTri] = numIslands; - } - } - numIslands++; - } - - return ( numIslands == 1 ); -} - -/* -================= -idSurface::IsClosed -================= -*/ -bool idSurface::IsClosed( void ) const { - for ( int i = 0; i < edges.Num(); i++ ) { - if ( edges[i].tris[0] < 0 || edges[i].tris[1] < 0 ) { - return false; - } - } - return true; -} - -/* -============= -idSurface::IsPolytope -============= -*/ -bool idSurface::IsPolytope( const float epsilon ) const { - int i, j; - idPlane plane; - - if ( !IsClosed() ) { - return false; - } - - for ( i = 0; i < indexes.Num(); i += 3 ) { - plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); - - for ( j = 0; j < verts.Num(); j++ ) { - if ( plane.Side( verts[j].xyz, epsilon ) == SIDE_FRONT ) { - return false; - } - } - } - return true; -} - -/* -============= -idSurface::PlaneDistance -============= -*/ -float idSurface::PlaneDistance( const idPlane &plane ) const { - int i; - float d, min, max; - - min = idMath::INFINITY; - max = -min; - for ( i = 0; i < verts.Num(); i++ ) { - d = plane.Distance( verts[i].xyz ); - if ( d < min ) { - min = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - if ( d > max ) { - max = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - } - if ( FLOATSIGNBITNOTSET( min ) ) { - return min; - } - if ( FLOATSIGNBITSET( max ) ) { - return max; - } - return 0.0f; -} - -/* -============= -idSurface::PlaneSide -============= -*/ -int idSurface::PlaneSide( const idPlane &plane, const float epsilon ) const { - bool front, back; - int i; - float d; - - front = false; - back = false; - for ( i = 0; i < verts.Num(); i++ ) { - d = plane.Distance( verts[i].xyz ); - if ( d < -epsilon ) { - if ( front ) { - return SIDE_CROSS; - } - back = true; - continue; - } - else if ( d > epsilon ) { - if ( back ) { - return SIDE_CROSS; - } - front = true; - continue; - } - } - - if ( back ) { - return SIDE_BACK; - } - if ( front ) { - return SIDE_FRONT; - } - return SIDE_ON; -} - -/* -================= -idSurface::LineIntersection -================= -*/ -bool idSurface::LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull ) const { - float scale; - - RayIntersection( start, end - start, scale, false ); - return ( scale >= 0.0f && scale <= 1.0f ); -} - -/* -================= -idSurface::RayIntersection -================= -*/ -bool idSurface::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull ) const { - int i, i0, i1, i2, s0, s1, s2; - float d, s; - byte *sidedness; - idPluecker rayPl, pl; - idPlane plane; - - sidedness = (byte *)_alloca( edges.Num() * sizeof(byte) ); - scale = idMath::INFINITY; - - rayPl.FromRay( start, dir ); - - // ray sidedness for edges - for ( i = 0; i < edges.Num(); i++ ) { - pl.FromLine( verts[ edges[i].verts[1] ].xyz, verts[ edges[i].verts[0] ].xyz ); - d = pl.PermutedInnerProduct( rayPl ); - sidedness[ i ] = FLOATSIGNBITSET( d ); - } - - // test triangles - for ( i = 0; i < edgeIndexes.Num(); i += 3 ) { - i0 = edgeIndexes[i+0]; - i1 = edgeIndexes[i+1]; - i2 = edgeIndexes[i+2]; - s0 = sidedness[abs(i0)] ^ INTSIGNBITSET( i0 ); - s1 = sidedness[abs(i1)] ^ INTSIGNBITSET( i1 ); - s2 = sidedness[abs(i2)] ^ INTSIGNBITSET( i2 ); - - if ( s0 & s1 & s2 ) { - plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); - plane.RayIntersection( start, dir, s ); - if ( idMath::Fabs( s ) < idMath::Fabs( scale ) ) { - scale = s; - } - } else if ( !backFaceCull && !(s0 | s1 | s2) ) { - plane.FromPoints( verts[indexes[i+0]].xyz, verts[indexes[i+1]].xyz, verts[indexes[i+2]].xyz ); - plane.RayIntersection( start, dir, s ); - if ( idMath::Fabs( s ) < idMath::Fabs( scale ) ) { - scale = s; - } - } - } - - if ( idMath::Fabs( scale ) < idMath::INFINITY ) { - return true; - } - return false; -} - -/* -================= -idSurface::GenerateEdgeIndexes - - Assumes each edge is shared by at most two triangles. -================= -*/ -void idSurface::GenerateEdgeIndexes( void ) { - int i, j, i0, i1, i2, s, v0, v1, edgeNum; - int *index, *vertexEdges, *edgeChain; - surfaceEdge_t e[3]; - - vertexEdges = (int *) _alloca16( verts.Num() * sizeof( int ) ); - memset( vertexEdges, -1, verts.Num() * sizeof( int ) ); - edgeChain = (int *) _alloca16( indexes.Num() * sizeof( int ) ); - - edgeIndexes.SetNum( indexes.Num(), true ); - - edges.Clear(); - - // the first edge is a dummy - e[0].verts[0] = e[0].verts[1] = e[0].tris[0] = e[0].tris[1] = 0; - edges.Append( e[0] ); - - for ( i = 0; i < indexes.Num(); i += 3 ) { - index = indexes.Ptr() + i; - // vertex numbers - i0 = index[0]; - i1 = index[1]; - i2 = index[2]; - // setup edges each with smallest vertex number first - s = INTSIGNBITSET(i1 - i0); - e[0].verts[0] = index[s]; - e[0].verts[1] = index[s^1]; - s = INTSIGNBITSET(i2 - i1) + 1; - e[1].verts[0] = index[s]; - e[1].verts[1] = index[s^3]; - s = INTSIGNBITSET(i2 - i0) << 1; - e[2].verts[0] = index[s]; - e[2].verts[1] = index[s^2]; - // get edges - for ( j = 0; j < 3; j++ ) { - v0 = e[j].verts[0]; - v1 = e[j].verts[1]; - for ( edgeNum = vertexEdges[v0]; edgeNum >= 0; edgeNum = edgeChain[edgeNum] ) { - if ( edges[edgeNum].verts[1] == v1 ) { - break; - } - } - // if the edge does not yet exist - if ( edgeNum < 0 ) { - e[j].tris[0] = e[j].tris[1] = -1; - edgeNum = edges.Append( e[j] ); - edgeChain[edgeNum] = vertexEdges[v0]; - vertexEdges[v0] = edgeNum; - } - // update edge index and edge tri references - if ( index[j] == v0 ) { - assert( edges[edgeNum].tris[0] == -1 ); // edge may not be shared by more than two triangles - edges[edgeNum].tris[0] = i; - edgeIndexes[i+j] = edgeNum; - } else { - assert( edges[edgeNum].tris[1] == -1 ); // edge may not be shared by more than two triangles - edges[edgeNum].tris[1] = i; - edgeIndexes[i+j] = -edgeNum; - } - } - } -} - -/* -================= -idSurface::FindEdge -================= -*/ -int idSurface::FindEdge( int v1, int v2 ) const { - int i, firstVert, secondVert; - - if ( v1 < v2 ) { - firstVert = v1; - secondVert = v2; - } else { - firstVert = v2; - secondVert = v1; - } - for ( i = 1; i < edges.Num(); i++ ) { - if ( edges[i].verts[0] == firstVert ) { - if ( edges[i].verts[1] == secondVert ) { - break; - } - } - } - if ( i < edges.Num() ) { - return v1 < v2 ? i : -i; - } - return 0; -} diff --git a/idlib/geometry/surface.h b/idlib/geometry/surface.h deleted file mode 100644 index 9e8e139d2..000000000 --- a/idlib/geometry/surface.h +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SURFACE_H__ -#define __SURFACE_H__ - -/* -=============================================================================== - - Surface base class. - - A surface is tesselated to a triangle mesh with each edge shared by - at most two triangles. - -=============================================================================== -*/ - -typedef struct surfaceEdge_s { - int verts[2]; // edge vertices always with ( verts[0] < verts[1] ) - int tris[2]; // edge triangles -} surfaceEdge_t; - - -class idSurface { -public: - idSurface( void ); - explicit idSurface( const idSurface &surf ); - explicit idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - ~idSurface( void ); - - const idDrawVert & operator[]( const int index ) const; - idDrawVert & operator[]( const int index ); - idSurface & operator+=( const idSurface &surf ); - - int GetNumIndexes( void ) const { return indexes.Num(); } - const int * GetIndexes( void ) const { return indexes.Ptr(); } - int GetNumVertices( void ) const { return verts.Num(); } - const idDrawVert * GetVertices( void ) const { return verts.Ptr(); } - const int * GetEdgeIndexes( void ) const { return edgeIndexes.Ptr(); } - const surfaceEdge_t * GetEdges( void ) const { return edges.Ptr(); } - - void Clear( void ); - void SwapTriangles( idSurface &surf ); - void TranslateSelf( const idVec3 &translation ); - void RotateSelf( const idMat3 &rotation ); - - // splits the surface into a front and back surface, the surface itself stays unchanged - // frontOnPlaneEdges and backOnPlaneEdges optionally store the indexes to the edges that lay on the split plane - // returns a SIDE_? - int Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges = NULL, int *backOnPlaneEdges = NULL ) const; - // cuts off the part at the back side of the plane, returns true if some part was at the front - // if there is nothing at the front the number of points is set to zero - bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); - - // returns true if each triangle can be reached from any other triangle by a traversal - bool IsConnected( void ) const; - // returns true if the surface is closed - bool IsClosed( void ) const; - // returns true if the surface is a convex hull - bool IsPolytope( const float epsilon = 0.1f ) const; - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - // returns true if the line intersects one of the surface triangles - bool LineIntersection( const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const; - // intersection point is start + dir * scale - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const; - -protected: - idList verts; // vertices - idList indexes; // 3 references to vertices for each triangle - idList edges; // edges - idList edgeIndexes; // 3 references to edges for each triangle, may be negative for reversed edge - -protected: - void GenerateEdgeIndexes( void ); - int FindEdge( int v1, int v2 ) const; -}; - -/* -==================== -idSurface::idSurface -==================== -*/ -ID_INLINE idSurface::idSurface( void ) { -} - -/* -================= -idSurface::idSurface -================= -*/ -ID_INLINE idSurface::idSurface( const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - assert( verts != NULL && indexes != NULL && numVerts > 0 && numIndexes > 0 ); - this->verts.SetNum( numVerts ); - memcpy( this->verts.Ptr(), verts, numVerts * sizeof( verts[0] ) ); - this->indexes.SetNum( numIndexes ); - memcpy( this->indexes.Ptr(), indexes, numIndexes * sizeof( indexes[0] ) ); - GenerateEdgeIndexes(); -} - -/* -==================== -idSurface::idSurface -==================== -*/ -ID_INLINE idSurface::idSurface( const idSurface &surf ) { - this->verts = surf.verts; - this->indexes = surf.indexes; - this->edges = surf.edges; - this->edgeIndexes = surf.edgeIndexes; -} - -/* -==================== -idSurface::~idSurface -==================== -*/ -ID_INLINE idSurface::~idSurface( void ) { -} - -/* -================= -idSurface::operator[] -================= -*/ -ID_INLINE const idDrawVert &idSurface::operator[]( const int index ) const { - return verts[ index ]; -}; - -/* -================= -idSurface::operator[] -================= -*/ -ID_INLINE idDrawVert &idSurface::operator[]( const int index ) { - return verts[ index ]; -}; - -/* -================= -idSurface::operator+= -================= -*/ -ID_INLINE idSurface &idSurface::operator+=( const idSurface &surf ) { - int i, m, n; - n = verts.Num(); - m = indexes.Num(); - verts.Append( surf.verts ); // merge verts where possible ? - indexes.Append( surf.indexes ); - for ( i = m; i < indexes.Num(); i++ ) { - indexes[i] += n; - } - GenerateEdgeIndexes(); - return *this; -} - -/* -================= -idSurface::Clear -================= -*/ -ID_INLINE void idSurface::Clear( void ) { - verts.Clear(); - indexes.Clear(); - edges.Clear(); - edgeIndexes.Clear(); -} - -/* -================= -idSurface::SwapTriangles -================= -*/ -ID_INLINE void idSurface::SwapTriangles( idSurface &surf ) { - verts.Swap( surf.verts ); - indexes.Swap( surf.indexes ); - edges.Swap( surf.edges ); - edgeIndexes.Swap( surf.edgeIndexes ); -} - -/* -================= -idSurface::TranslateSelf -================= -*/ -ID_INLINE void idSurface::TranslateSelf( const idVec3 &translation ) { - for ( int i = 0; i < verts.Num(); i++ ) { - verts[i].xyz += translation; - } -} - -/* -================= -idSurface::RotateSelf -================= -*/ -ID_INLINE void idSurface::RotateSelf( const idMat3 &rotation ) { - for ( int i = 0; i < verts.Num(); i++ ) { - verts[i].xyz *= rotation; - verts[i].normal *= rotation; - verts[i].tangents[0] *= rotation; - verts[i].tangents[1] *= rotation; - } -} - -#endif /* !__SURFACE_H__ */ diff --git a/idlib/geometry/surface_patch.cpp b/idlib/geometry/surface_patch.cpp deleted file mode 100644 index 9b2890327..000000000 --- a/idlib/geometry/surface_patch.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -================= -idSurface_Patch::SetSize -================= -*/ -void idSurface_Patch::SetSize( int patchWidth, int patchHeight ) { - if ( patchWidth < 1 || patchWidth > maxWidth ) { - idLib::common->FatalError("idSurface_Patch::SetSize: invalid patchWidth"); - } - if ( patchHeight < 1 || patchHeight > maxHeight ) { - idLib::common->FatalError("idSurface_Patch::SetSize: invalid patchHeight"); - } - width = patchWidth; - height = patchHeight; - verts.SetNum( width * height, false ); -} - -/* -================= -idSurface_Patch::PutOnCurve - -Expects an expanded patch. -================= -*/ -void idSurface_Patch::PutOnCurve( void ) { - int i, j; - idDrawVert prev, next; - - assert( expanded == true ); - // put all the approximating points on the curve - for ( i = 0; i < width; i++ ) { - for ( j = 1; j < height; j += 2 ) { - LerpVert( verts[j*maxWidth+i], verts[(j+1)*maxWidth+i], prev ); - LerpVert( verts[j*maxWidth+i], verts[(j-1)*maxWidth+i], next ); - LerpVert( prev, next, verts[j*maxWidth+i] ); - } - } - - for ( j = 0; j < height; j++ ) { - for ( i = 1; i < width; i += 2 ) { - LerpVert( verts[j*maxWidth+i], verts[j*maxWidth+i+1], prev ); - LerpVert( verts[j*maxWidth+i], verts[j*maxWidth+i-1], next ); - LerpVert( prev, next, verts[j*maxWidth+i] ); - } - } -} - -/* -================ -idSurface_Patch::ProjectPointOntoVector -================ -*/ -void idSurface_Patch::ProjectPointOntoVector( const idVec3 &point, const idVec3 &vStart, const idVec3 &vEnd, idVec3 &vProj ) { - idVec3 pVec, vec; - - pVec = point - vStart; - vec = vEnd - vStart; - vec.Normalize(); - // project onto the directional vector for this segment - vProj = vStart + (pVec * vec) * vec; -} - -/* -================ -idSurface_Patch::RemoveLinearColumnsRows - -Expects an expanded patch. -================ -*/ -void idSurface_Patch::RemoveLinearColumnsRows( void ) { - int i, j, k; - float len, maxLength; - idVec3 proj, dir; - - assert( expanded == true ); - for ( j = 1; j < width - 1; j++ ) { - maxLength = 0; - for ( i = 0; i < height; i++ ) { - idSurface_Patch::ProjectPointOntoVector( verts[i*maxWidth + j].xyz, - verts[i*maxWidth + j-1].xyz, verts[i*maxWidth + j+1].xyz, proj); - dir = verts[i*maxWidth + j].xyz - proj; - len = dir.LengthSqr(); - if ( len > maxLength ) { - maxLength = len; - } - } - if ( maxLength < Square( 0.2f ) ) { - width--; - for ( i = 0; i < height; i++ ) { - for ( k = j; k < width; k++ ) { - verts[i*maxWidth + k] = verts[i*maxWidth + k+1]; - } - } - j--; - } - } - for ( j = 1; j < height - 1; j++ ) { - maxLength = 0; - for ( i = 0; i < width; i++ ) { - idSurface_Patch::ProjectPointOntoVector( verts[j*maxWidth + i].xyz, - verts[(j-1)*maxWidth + i].xyz, verts[(j+1)*maxWidth + i].xyz, proj); - dir = verts[j*maxWidth + i].xyz - proj; - len = dir.LengthSqr(); - if ( len > maxLength ) { - maxLength = len; - } - } - if ( maxLength < Square( 0.2f ) ) { - height--; - for ( i = 0; i < width; i++ ) { - for ( k = j; k < height; k++ ) { - verts[k*maxWidth + i] = verts[(k+1)*maxWidth + i]; - } - } - j--; - } - } -} - -/* -================ -idSurface_Patch::ResizeExpanded -================ -*/ -void idSurface_Patch::ResizeExpanded( int newHeight, int newWidth ) { - int i, j; - - assert( expanded == true ); - if ( newHeight <= maxHeight && newWidth <= maxWidth ) { - return; - } - if ( newHeight * newWidth > maxHeight * maxWidth ) { - verts.SetNum( newHeight * newWidth ); - } - // space out verts for new height and width - for ( j = maxHeight-1; j >= 0; j-- ) { - for ( i = maxWidth-1; i >= 0; i-- ) { - verts[j*newWidth + i] = verts[j*maxWidth + i]; - } - } - maxHeight = newHeight; - maxWidth = newWidth; -} - -/* -================ -idSurface_Patch::Collapse -================ -*/ -void idSurface_Patch::Collapse( void ) { - int i, j; - - if ( !expanded ) { - idLib::common->FatalError("idSurface_Patch::Collapse: patch not expanded"); - } - expanded = false; - if ( width != maxWidth ) { - for ( j = 0; j < height; j++ ) { - for ( i = 0; i < width; i++ ) { - verts[j*width + i] = verts[j*maxWidth + i]; - } - } - } - verts.SetNum( width * height, false ); -} - -/* -================ -idSurface_Patch::Expand -================ -*/ -void idSurface_Patch::Expand( void ) { - int i, j; - - if ( expanded ) { - idLib::common->FatalError("idSurface_Patch::Expand: patch alread expanded"); - } - expanded = true; - verts.SetNum( maxWidth * maxHeight, false ); - if ( width != maxWidth ) { - for ( j = height-1; j >= 0; j-- ) { - for ( i = width-1; i >= 0; i-- ) { - verts[j*maxWidth + i] = verts[j*width + i]; - } - } - } -} - -/* -============ -idSurface_Patch::LerpVert -============ -*/ -void idSurface_Patch::LerpVert( const idDrawVert &a, const idDrawVert &b, idDrawVert &out ) const { - out.xyz[0] = 0.5f * ( a.xyz[0] + b.xyz[0] ); - out.xyz[1] = 0.5f * ( a.xyz[1] + b.xyz[1] ); - out.xyz[2] = 0.5f * ( a.xyz[2] + b.xyz[2] ); - out.normal[0] = 0.5f * ( a.normal[0] + b.normal[0] ); - out.normal[1] = 0.5f * ( a.normal[1] + b.normal[1] ); - out.normal[2] = 0.5f * ( a.normal[2] + b.normal[2] ); - out.st[0] = 0.5f * ( a.st[0] + b.st[0] ); - out.st[1] = 0.5f * ( a.st[1] + b.st[1] ); -} - -/* -================= -idSurface_Patch::GenerateNormals - -Handles all the complicated wrapping and degenerate cases -Expects a Not expanded patch. -================= -*/ -#define COPLANAR_EPSILON 0.1f - -void idSurface_Patch::GenerateNormals( void ) { - int i, j, k, dist; - idVec3 norm; - idVec3 sum; - int count; - idVec3 base; - idVec3 delta; - int x, y; - idVec3 around[8], temp; - bool good[8]; - bool wrapWidth, wrapHeight; - static int neighbors[8][2] = { - {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1} - }; - - assert( expanded == false ); - - // - // if all points are coplanar, set all normals to that plane - // - idVec3 extent[3]; - float offset; - - extent[0] = verts[width - 1].xyz - verts[0].xyz; - extent[1] = verts[(height-1) * width + width - 1].xyz - verts[0].xyz; - extent[2] = verts[(height-1) * width].xyz - verts[0].xyz; - - norm = extent[0].Cross( extent[1] ); - if ( norm.LengthSqr() == 0.0f ) { - norm = extent[0].Cross( extent[2] ); - if ( norm.LengthSqr() == 0.0f ) { - norm = extent[1].Cross( extent[2] ); - } - } - - // wrapped patched may not get a valid normal here - if ( norm.Normalize() != 0.0f ) { - - offset = verts[0].xyz * norm; - for ( i = 1; i < width * height; i++ ) { - float d = verts[i].xyz * norm; - if ( idMath::Fabs( d - offset ) > COPLANAR_EPSILON ) { - break; - } - } - - if ( i == width * height ) { - // all are coplanar - for ( i = 0; i < width * height; i++ ) { - verts[i].normal = norm; - } - return; - } - } - - // check for wrapped edge cases, which should smooth across themselves - wrapWidth = false; - for ( i = 0; i < height; i++ ) { - delta = verts[i * width].xyz - verts[i * width + width-1].xyz; - if ( delta.LengthSqr() > Square( 1.0f ) ) { - break; - } - } - if ( i == height ) { - wrapWidth = true; - } - - wrapHeight = false; - for ( i = 0; i < width; i++ ) { - delta = verts[i].xyz - verts[(height-1) * width + i].xyz; - if ( delta.LengthSqr() > Square( 1.0f ) ) { - break; - } - } - if ( i == width ) { - wrapHeight = true; - } - - for ( i = 0; i < width; i++ ) { - for ( j = 0; j < height; j++ ) { - count = 0; - base = verts[j * width + i].xyz; - for ( k = 0; k < 8; k++ ) { - around[k] = vec3_origin; - good[k] = false; - - for ( dist = 1; dist <= 3; dist++ ) { - x = i + neighbors[k][0] * dist; - y = j + neighbors[k][1] * dist; - if ( wrapWidth ) { - if ( x < 0 ) { - x = width - 1 + x; - } else if ( x >= width ) { - x = 1 + x - width; - } - } - if ( wrapHeight ) { - if ( y < 0 ) { - y = height - 1 + y; - } else if ( y >= height ) { - y = 1 + y - height; - } - } - - if ( x < 0 || x >= width || y < 0 || y >= height ) { - break; // edge of patch - } - temp = verts[y * width + x].xyz - base; - if ( temp.Normalize() == 0.0f ) { - continue; // degenerate edge, get more dist - } else { - good[k] = true; - around[k] = temp; - break; // good edge - } - } - } - - sum = vec3_origin; - for ( k = 0; k < 8; k++ ) { - if ( !good[k] || !good[(k+1)&7] ) { - continue; // didn't get two points - } - norm = around[(k+1)&7].Cross( around[k] ); - if ( norm.Normalize() == 0.0f ) { - continue; - } - sum += norm; - count++; - } - if ( count == 0 ) { - //idLib::common->Printf("bad normal\n"); - count = 1; - } - verts[j * width + i].normal = sum; - verts[j * width + i].normal.Normalize(); - } - } -} - -/* -================= -idSurface_Patch::GenerateIndexes -================= -*/ -void idSurface_Patch::GenerateIndexes( void ) { - int i, j, v1, v2, v3, v4, index; - - indexes.SetNum( (width-1) * (height-1) * 2 * 3, false ); - index = 0; - for ( i = 0; i < width - 1; i++ ) { - for ( j = 0; j < height - 1; j++ ) { - v1 = j * width + i; - v2 = v1 + 1; - v3 = v1 + width + 1; - v4 = v1 + width; - indexes[index++] = v1; - indexes[index++] = v3; - indexes[index++] = v2; - indexes[index++] = v1; - indexes[index++] = v4; - indexes[index++] = v3; - } - } - - GenerateEdgeIndexes(); -} - -/* -=============== -idSurface_Patch::SampleSinglePatchPoint -=============== -*/ -void idSurface_Patch::SampleSinglePatchPoint( const idDrawVert ctrl[3][3], float u, float v, idDrawVert *out ) const { - float vCtrl[3][8]; - int vPoint; - int axis; - - // find the control points for the v coordinate - for ( vPoint = 0; vPoint < 3; vPoint++ ) { - for ( axis = 0; axis < 8; axis++ ) { - float a, b, c; - float qA, qB, qC; - if ( axis < 3 ) { - a = ctrl[0][vPoint].xyz[axis]; - b = ctrl[1][vPoint].xyz[axis]; - c = ctrl[2][vPoint].xyz[axis]; - } else if ( axis < 6 ) { - a = ctrl[0][vPoint].normal[axis-3]; - b = ctrl[1][vPoint].normal[axis-3]; - c = ctrl[2][vPoint].normal[axis-3]; - } else { - a = ctrl[0][vPoint].st[axis-6]; - b = ctrl[1][vPoint].st[axis-6]; - c = ctrl[2][vPoint].st[axis-6]; - } - qA = a - 2.0f * b + c; - qB = 2.0f * b - 2.0f * a; - qC = a; - vCtrl[vPoint][axis] = qA * u * u + qB * u + qC; - } - } - - // interpolate the v value - for ( axis = 0; axis < 8; axis++ ) { - float a, b, c; - float qA, qB, qC; - - a = vCtrl[0][axis]; - b = vCtrl[1][axis]; - c = vCtrl[2][axis]; - qA = a - 2.0f * b + c; - qB = 2.0f * b - 2.0f * a; - qC = a; - - if ( axis < 3 ) { - out->xyz[axis] = qA * v * v + qB * v + qC; - } else if ( axis < 6 ) { - out->normal[axis-3] = qA * v * v + qB * v + qC; - } else { - out->st[axis-6] = qA * v * v + qB * v + qC; - } - } -} - -/* -=================== -idSurface_Patch::SampleSinglePatch -=================== -*/ -void idSurface_Patch::SampleSinglePatch( const idDrawVert ctrl[3][3], int baseCol, int baseRow, int width, int horzSub, int vertSub, idDrawVert *outVerts ) const { - int i, j; - float u, v; - - horzSub++; - vertSub++; - for ( i = 0; i < horzSub; i++ ) { - for ( j = 0; j < vertSub; j++ ) { - u = (float) i / ( horzSub - 1 ); - v = (float) j / ( vertSub - 1 ); - SampleSinglePatchPoint( ctrl, u, v, &outVerts[((baseRow + j) * width) + i + baseCol] ); - } - } -} - -/* -================= -idSurface_Patch::SubdivideExplicit -================= -*/ -void idSurface_Patch::SubdivideExplicit( int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear ) { - int i, j, k, l; - idDrawVert sample[3][3]; - int outWidth = ((width - 1) / 2 * horzSubdivisions) + 1; - int outHeight = ((height - 1) / 2 * vertSubdivisions) + 1; - idDrawVert *dv = new idDrawVert[ outWidth * outHeight ]; - - // generate normals for the control mesh - if ( genNormals ) { - GenerateNormals(); - } - - int baseCol = 0; - for ( i = 0; i + 2 < width; i += 2 ) { - int baseRow = 0; - for ( j = 0; j + 2 < height; j += 2 ) { - for ( k = 0; k < 3; k++ ) { - for ( l = 0; l < 3; l++ ) { - sample[k][l] = verts[ ((j + l) * width) + i + k ]; - } - } - SampleSinglePatch( sample, baseCol, baseRow, outWidth, horzSubdivisions, vertSubdivisions, dv ); - baseRow += vertSubdivisions; - } - baseCol += horzSubdivisions; - } - verts.SetNum( outWidth * outHeight ); - for ( i = 0; i < outWidth * outHeight; i++ ) { - verts[i] = dv[i]; - } - - delete[] dv; - - width = maxWidth = outWidth; - height = maxHeight = outHeight; - expanded = false; - - if ( removeLinear ) { - Expand(); - RemoveLinearColumnsRows(); - Collapse(); - } - - // normalize all the lerped normals - if ( genNormals ) { - for ( i = 0; i < width * height; i++ ) { - verts[i].normal.Normalize(); - } - } - - GenerateIndexes(); -} - -/* -================= -idSurface_Patch::Subdivide -================= -*/ -void idSurface_Patch::Subdivide( float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals ) { - int i, j, k, l; - idDrawVert prev, next, mid; - idVec3 prevxyz, nextxyz, midxyz; - idVec3 delta; - float maxHorizontalErrorSqr, maxVerticalErrorSqr, maxLengthSqr; - - // generate normals for the control mesh - if ( genNormals ) { - GenerateNormals(); - } - - maxHorizontalErrorSqr = Square( maxHorizontalError ); - maxVerticalErrorSqr = Square( maxVerticalError ); - maxLengthSqr = Square( maxLength ); - - Expand(); - - // horizontal subdivisions - for ( j = 0; j + 2 < width; j += 2 ) { - // check subdivided midpoints against control points - for ( i = 0; i < height; i++ ) { - for ( l = 0; l < 3; l++ ) { - prevxyz[l] = verts[i*maxWidth + j+1].xyz[l] - verts[i*maxWidth + j ].xyz[l]; - nextxyz[l] = verts[i*maxWidth + j+2].xyz[l] - verts[i*maxWidth + j+1].xyz[l]; - midxyz[l] = (verts[i*maxWidth + j ].xyz[l] + verts[i*maxWidth + j+1].xyz[l] * 2.0f + - verts[i*maxWidth + j+2].xyz[l] ) * 0.25f; - } - - if ( maxLength > 0.0f ) { - // if the span length is too long, force a subdivision - if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) { - break; - } - } - // see if this midpoint is off far enough to subdivide - delta = verts[i*maxWidth + j+1].xyz - midxyz; - if ( delta.LengthSqr() > maxHorizontalErrorSqr ) { - break; - } - } - - if ( i == height ) { - continue; // didn't need subdivision - } - - if ( width + 2 >= maxWidth ) { - ResizeExpanded( maxHeight, maxWidth + 4 ); - } - - // insert two columns and replace the peak - width += 2; - - for ( i = 0; i < height; i++ ) { - idSurface_Patch::LerpVert( verts[i*maxWidth + j ], verts[i*maxWidth + j+1], prev ); - idSurface_Patch::LerpVert( verts[i*maxWidth + j+1], verts[i*maxWidth + j+2], next ); - idSurface_Patch::LerpVert( prev, next, mid ); - - for ( k = width - 1; k > j + 3; k-- ) { - verts[i*maxWidth + k] = verts[i*maxWidth + k-2]; - } - verts[i*maxWidth + j+1] = prev; - verts[i*maxWidth + j+2] = mid; - verts[i*maxWidth + j+3] = next; - } - - // back up and recheck this set again, it may need more subdivision - j -= 2; - } - - // vertical subdivisions - for ( j = 0; j + 2 < height; j += 2 ) { - // check subdivided midpoints against control points - for ( i = 0; i < width; i++ ) { - for ( l = 0; l < 3; l++ ) { - prevxyz[l] = verts[(j+1)*maxWidth + i].xyz[l] - verts[j*maxWidth + i].xyz[l]; - nextxyz[l] = verts[(j+2)*maxWidth + i].xyz[l] - verts[(j+1)*maxWidth + i].xyz[l]; - midxyz[l] = (verts[j*maxWidth + i].xyz[l] + verts[(j+1)*maxWidth + i].xyz[l] * 2.0f + - verts[(j+2)*maxWidth + i].xyz[l] ) * 0.25f; - } - - if ( maxLength > 0.0f ) { - // if the span length is too long, force a subdivision - if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) { - break; - } - } - // see if this midpoint is off far enough to subdivide - delta = verts[(j+1)*maxWidth + i].xyz - midxyz; - if ( delta.LengthSqr() > maxVerticalErrorSqr ) { - break; - } - } - - if ( i == width ) { - continue; // didn't need subdivision - } - - if ( height + 2 >= maxHeight ) { - ResizeExpanded( maxHeight + 4, maxWidth ); - } - - // insert two columns and replace the peak - height += 2; - - for ( i = 0; i < width; i++ ) { - LerpVert( verts[j*maxWidth + i], verts[(j+1)*maxWidth + i], prev ); - LerpVert( verts[(j+1)*maxWidth + i], verts[(j+2)*maxWidth + i], next ); - LerpVert( prev, next, mid ); - - for ( k = height - 1; k > j + 3; k-- ) { - verts[k*maxWidth + i] = verts[(k-2)*maxWidth + i]; - } - verts[(j+1)*maxWidth + i] = prev; - verts[(j+2)*maxWidth + i] = mid; - verts[(j+3)*maxWidth + i] = next; - } - - // back up and recheck this set again, it may need more subdivision - j -= 2; - } - - PutOnCurve(); - - RemoveLinearColumnsRows(); - - Collapse(); - - // normalize all the lerped normals - if ( genNormals ) { - for ( i = 0; i < width * height; i++ ) { - verts[i].normal.Normalize(); - } - } - - GenerateIndexes(); -} diff --git a/idlib/geometry/surface_patch.h b/idlib/geometry/surface_patch.h deleted file mode 100644 index b43f28557..000000000 --- a/idlib/geometry/surface_patch.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SURFACE_PATCH_H__ -#define __SURFACE_PATCH_H__ - -/* -=============================================================================== - - Bezier patch surface. - -=============================================================================== -*/ - -class idSurface_Patch : public idSurface { - -public: - idSurface_Patch( void ); - idSurface_Patch( int maxPatchWidth, int maxPatchHeight ); - idSurface_Patch( const idSurface_Patch &patch ); - ~idSurface_Patch( void ); - - void SetSize( int patchWidth, int patchHeight ); - int GetWidth( void ) const; - int GetHeight( void ) const; - - // subdivide the patch mesh based on error - void Subdivide( float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals = false ); - // subdivide the patch up to an explicit number of horizontal and vertical subdivisions - void SubdivideExplicit( int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear = false ); - -protected: - int width; // width of patch - int height; // height of patch - int maxWidth; // maximum width allocated for - int maxHeight; // maximum height allocated for - bool expanded; // true if vertices are spaced out - -private: - // put the approximation points on the curve - void PutOnCurve( void ); - // remove columns and rows with all points on one line - void RemoveLinearColumnsRows( void ); - // resize verts buffer - void ResizeExpanded( int height, int width ); - // space points out over maxWidth * maxHeight buffer - void Expand( void ); - // move all points to the start of the verts buffer - void Collapse( void ); - // project a point onto a vector to calculate maximum curve error - void ProjectPointOntoVector( const idVec3 &point, const idVec3 &vStart, const idVec3 &vEnd, idVec3 &vProj ); - // generate normals - void GenerateNormals( void ); - // generate triangle indexes - void GenerateIndexes( void ); - // lerp point from two patch point - void LerpVert( const idDrawVert &a, const idDrawVert &b, idDrawVert &out ) const; - // sample a single 3x3 patch - void SampleSinglePatchPoint( const idDrawVert ctrl[3][3], float u, float v, idDrawVert *out ) const; - void SampleSinglePatch( const idDrawVert ctrl[3][3], int baseCol, int baseRow, int width, int horzSub, int vertSub, idDrawVert *outVerts ) const; -}; - -/* -================= -idSurface_Patch::idSurface_Patch -================= -*/ -ID_INLINE idSurface_Patch::idSurface_Patch( void ) { - height = width = maxHeight = maxWidth = 0; - expanded = false; -} - -/* -================= -idSurface_Patch::idSurface_Patch -================= -*/ -ID_INLINE idSurface_Patch::idSurface_Patch( int maxPatchWidth, int maxPatchHeight ) { - width = height = 0; - maxWidth = maxPatchWidth; - maxHeight = maxPatchHeight; - verts.SetNum( maxWidth * maxHeight ); - expanded = false; -} - -/* -================= -idSurface_Patch::idSurface_Patch -================= -*/ -ID_INLINE idSurface_Patch::idSurface_Patch( const idSurface_Patch &patch ) { - (*this) = patch; -} - -/* -================= -idSurface_Patch::~idSurface_Patch -================= -*/ -ID_INLINE idSurface_Patch::~idSurface_Patch() { -} - -/* -================= -idSurface_Patch::GetWidth -================= -*/ -ID_INLINE int idSurface_Patch::GetWidth( void ) const { - return width; -} - -/* -================= -idSurface_Patch::GetHeight -================= -*/ -ID_INLINE int idSurface_Patch::GetHeight( void ) const { - return height; -} - -#endif /* !__SURFACE_PATCH_H__ */ diff --git a/idlib/geometry/surface_polytope.cpp b/idlib/geometry/surface_polytope.cpp deleted file mode 100644 index 70f8dc7af..000000000 --- a/idlib/geometry/surface_polytope.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#define POLYTOPE_VERTEX_EPSILON 0.1f - - -/* -==================== -idSurface_Polytope::FromPlanes -==================== -*/ -void idSurface_Polytope::FromPlanes( const idPlane *planes, const int numPlanes ) { - int i, j, k, *windingVerts; - idFixedWinding w; - idDrawVert newVert; - - windingVerts = (int *) _alloca( MAX_POINTS_ON_WINDING * sizeof( int ) ); - memset( &newVert, 0, sizeof( newVert ) ); - - for ( i = 0; i < numPlanes; i++ ) { - - w.BaseForPlane( planes[i] ); - - for ( j = 0; j < numPlanes; j++ ) { - if ( j == i ) { - continue; - } - if ( !w.ClipInPlace( -planes[j], ON_EPSILON, true ) ) { - break; - } - } - if ( !w.GetNumPoints() ) { - continue; - } - - for ( j = 0; j < w.GetNumPoints(); j++ ) { - for ( k = 0; k < verts.Num(); j++ ) { - if ( verts[k].xyz.Compare( w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON ) ) { - break; - } - } - if ( k >= verts.Num() ) { - newVert.xyz = w[j].ToVec3(); - k = verts.Append( newVert ); - } - windingVerts[j] = k; - } - - for ( j = 2; j < w.GetNumPoints(); j++ ) { - indexes.Append( windingVerts[0] ); - indexes.Append( windingVerts[j-1] ); - indexes.Append( windingVerts[j] ); - } - } - - GenerateEdgeIndexes(); -} - -/* -==================== -idSurface_Polytope::SetupTetrahedron -==================== -*/ -void idSurface_Polytope::SetupTetrahedron( const idBounds &bounds ) { - idVec3 center, scale; - float c1, c2, c3; - - c1 = 0.4714045207f; - c2 = 0.8164965809f; - c3 = -0.3333333333f; - - center = bounds.GetCenter(); - scale = bounds[1] - center; - - verts.SetNum( 4 ); - verts[0].xyz = center + idVec3( 0.0f, 0.0f, scale.z ); - verts[1].xyz = center + idVec3( 2.0f * c1 * scale.x, 0.0f, c3 * scale.z ); - verts[2].xyz = center + idVec3( -c1 * scale.x, c2 * scale.y, c3 * scale.z ); - verts[3].xyz = center + idVec3( -c1 * scale.x, -c2 * scale.y, c3 * scale.z ); - - indexes.SetNum( 4*3 ); - indexes[0*3+0] = 0; - indexes[0*3+1] = 1; - indexes[0*3+2] = 2; - indexes[1*3+0] = 0; - indexes[1*3+1] = 2; - indexes[1*3+2] = 3; - indexes[2*3+0] = 0; - indexes[2*3+1] = 3; - indexes[2*3+2] = 1; - indexes[3*3+0] = 1; - indexes[3*3+1] = 3; - indexes[3*3+2] = 2; - - GenerateEdgeIndexes(); -} - -/* -==================== -idSurface_Polytope::SetupHexahedron -==================== -*/ -void idSurface_Polytope::SetupHexahedron( const idBounds &bounds ) { - idVec3 center, scale; - - center = bounds.GetCenter(); - scale = bounds[1] - center; - - verts.SetNum( 8 ); - verts[0].xyz = center + idVec3( -scale.x, -scale.y, -scale.z ); - verts[1].xyz = center + idVec3( scale.x, -scale.y, -scale.z ); - verts[2].xyz = center + idVec3( scale.x, scale.y, -scale.z ); - verts[3].xyz = center + idVec3( -scale.x, scale.y, -scale.z ); - verts[4].xyz = center + idVec3( -scale.x, -scale.y, scale.z ); - verts[5].xyz = center + idVec3( scale.x, -scale.y, scale.z ); - verts[6].xyz = center + idVec3( scale.x, scale.y, scale.z ); - verts[7].xyz = center + idVec3( -scale.x, scale.y, scale.z ); - - indexes.SetNum( 12*3 ); - indexes[ 0*3+0] = 0; - indexes[ 0*3+1] = 3; - indexes[ 0*3+2] = 2; - indexes[ 1*3+0] = 0; - indexes[ 1*3+1] = 2; - indexes[ 1*3+2] = 1; - indexes[ 2*3+0] = 0; - indexes[ 2*3+1] = 1; - indexes[ 2*3+2] = 5; - indexes[ 3*3+0] = 0; - indexes[ 3*3+1] = 5; - indexes[ 3*3+2] = 4; - indexes[ 4*3+0] = 0; - indexes[ 4*3+1] = 4; - indexes[ 4*3+2] = 7; - indexes[ 5*3+0] = 0; - indexes[ 5*3+1] = 7; - indexes[ 5*3+2] = 3; - indexes[ 6*3+0] = 6; - indexes[ 6*3+1] = 5; - indexes[ 6*3+2] = 1; - indexes[ 7*3+0] = 6; - indexes[ 7*3+1] = 1; - indexes[ 7*3+2] = 2; - indexes[ 8*3+0] = 6; - indexes[ 8*3+1] = 2; - indexes[ 8*3+2] = 3; - indexes[ 9*3+0] = 6; - indexes[ 9*3+1] = 3; - indexes[ 9*3+2] = 7; - indexes[10*3+0] = 6; - indexes[10*3+1] = 7; - indexes[10*3+2] = 4; - indexes[11*3+0] = 6; - indexes[11*3+1] = 4; - indexes[11*3+2] = 5; - - GenerateEdgeIndexes(); -} - -/* -==================== -idSurface_Polytope::SetupOctahedron -==================== -*/ -void idSurface_Polytope::SetupOctahedron( const idBounds &bounds ) { - idVec3 center, scale; - - center = bounds.GetCenter(); - scale = bounds[1] - center; - - verts.SetNum( 6 ); - verts[0].xyz = center + idVec3( scale.x, 0.0f, 0.0f ); - verts[1].xyz = center + idVec3( -scale.x, 0.0f, 0.0f ); - verts[2].xyz = center + idVec3( 0.0f, scale.y, 0.0f ); - verts[3].xyz = center + idVec3( 0.0f, -scale.y, 0.0f ); - verts[4].xyz = center + idVec3( 0.0f, 0.0f, scale.z ); - verts[5].xyz = center + idVec3( 0.0f, 0.0f, -scale.z ); - - indexes.SetNum( 8*3 ); - indexes[0*3+0] = 4; - indexes[0*3+1] = 0; - indexes[0*3+2] = 2; - indexes[1*3+0] = 4; - indexes[1*3+1] = 2; - indexes[1*3+2] = 1; - indexes[2*3+0] = 4; - indexes[2*3+1] = 1; - indexes[2*3+2] = 3; - indexes[3*3+0] = 4; - indexes[3*3+1] = 3; - indexes[3*3+2] = 0; - indexes[4*3+0] = 5; - indexes[4*3+1] = 2; - indexes[4*3+2] = 0; - indexes[5*3+0] = 5; - indexes[5*3+1] = 1; - indexes[5*3+2] = 2; - indexes[6*3+0] = 5; - indexes[6*3+1] = 3; - indexes[6*3+2] = 1; - indexes[7*3+0] = 5; - indexes[7*3+1] = 0; - indexes[7*3+2] = 3; - - GenerateEdgeIndexes(); -} - -/* -==================== -idSurface_Polytope::SetupDodecahedron -==================== -*/ -void idSurface_Polytope::SetupDodecahedron( const idBounds &bounds ) { -} - -/* -==================== -idSurface_Polytope::SetupIcosahedron -==================== -*/ -void idSurface_Polytope::SetupIcosahedron( const idBounds &bounds ) { -} - -/* -==================== -idSurface_Polytope::SetupCylinder -==================== -*/ -void idSurface_Polytope::SetupCylinder( const idBounds &bounds, const int numSides ) { -} - -/* -==================== -idSurface_Polytope::SetupCone -==================== -*/ -void idSurface_Polytope::SetupCone( const idBounds &bounds, const int numSides ) { -} - -/* -==================== -idSurface_Polytope::SplitPolytope -==================== -*/ -int idSurface_Polytope::SplitPolytope( const idPlane &plane, const float epsilon, idSurface_Polytope **front, idSurface_Polytope **back ) const { - int side, i, j, s, v0, v1, v2, edgeNum; - idSurface *surface[2]; - idSurface_Polytope *polytopeSurfaces[2], *surf; - int *onPlaneEdges[2]; - - onPlaneEdges[0] = (int *) _alloca( indexes.Num() / 3 * sizeof( int ) ); - onPlaneEdges[1] = (int *) _alloca( indexes.Num() / 3 * sizeof( int ) ); - - side = Split( plane, epsilon, &surface[0], &surface[1], onPlaneEdges[0], onPlaneEdges[1] ); - - *front = polytopeSurfaces[0] = new idSurface_Polytope; - *back = polytopeSurfaces[1] = new idSurface_Polytope; - - for ( s = 0; s < 2; s++ ) { - if ( surface[s] ) { - polytopeSurfaces[s] = new idSurface_Polytope; - polytopeSurfaces[s]->SwapTriangles( *surface[s] ); - delete surface[s]; - surface[s] = NULL; - } - } - - *front = polytopeSurfaces[0]; - *back = polytopeSurfaces[1]; - - if ( side != SIDE_CROSS ) { - return side; - } - - // add triangles to close off the front and back polytope - for ( s = 0; s < 2; s++ ) { - - surf = polytopeSurfaces[s]; - - edgeNum = surf->edgeIndexes[onPlaneEdges[s][0]]; - v0 = surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)]; - v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; - - for ( i = 1; onPlaneEdges[s][i] >= 0; i++ ) { - for ( j = i+1; onPlaneEdges[s][j] >= 0; j++ ) { - edgeNum = surf->edgeIndexes[onPlaneEdges[s][j]]; - if ( v1 == surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)] ) { - v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; - idSwap( onPlaneEdges[s][i], onPlaneEdges[s][j] ); - break; - } - } - } - - for ( i = 2; onPlaneEdges[s][i] >= 0; i++ ) { - edgeNum = surf->edgeIndexes[onPlaneEdges[s][i]]; - v1 = surf->edges[abs(edgeNum)].verts[INTSIGNBITNOTSET(edgeNum)]; - v2 = surf->edges[abs(edgeNum)].verts[INTSIGNBITSET(edgeNum)]; - surf->indexes.Append( v0 ); - surf->indexes.Append( v1 ); - surf->indexes.Append( v2 ); - } - - surf->GenerateEdgeIndexes(); - } - - return side; -} diff --git a/idlib/geometry/surface_polytope.h b/idlib/geometry/surface_polytope.h deleted file mode 100644 index edd943bda..000000000 --- a/idlib/geometry/surface_polytope.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SURFACE_POLYTOPE_H__ -#define __SURFACE_POLYTOPE_H__ - -/* -=============================================================================== - - Polytope surface. - - NOTE: vertexes are not duplicated for texture coordinates. - -=============================================================================== -*/ - -class idSurface_Polytope : public idSurface { -public: - idSurface_Polytope( void ); - - void FromPlanes( const idPlane *planes, const int numPlanes ); - - void SetupTetrahedron( const idBounds &bounds ); - void SetupHexahedron( const idBounds &bounds ); - void SetupOctahedron( const idBounds &bounds ); - void SetupDodecahedron( const idBounds &bounds ); - void SetupIcosahedron( const idBounds &bounds ); - void SetupCylinder( const idBounds &bounds, const int numSides ); - void SetupCone( const idBounds &bounds, const int numSides ); - - int SplitPolytope( const idPlane &plane, const float epsilon, idSurface_Polytope **front, idSurface_Polytope **back ) const; - -protected: - -}; - -/* -==================== -idSurface_Polytope::idSurface_Polytope -==================== -*/ -ID_INLINE idSurface_Polytope::idSurface_Polytope( void ) { -} - -#endif /* !__SURFACE_POLYTOPE_H__ */ diff --git a/idlib/geometry/surface_sweptspline.cpp b/idlib/geometry/surface_sweptspline.cpp deleted file mode 100644 index 6cbb1e0a7..000000000 --- a/idlib/geometry/surface_sweptspline.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -==================== -idSurface_SweptSpline::SetSpline -==================== -*/ -void idSurface_SweptSpline::SetSpline( idCurve_Spline *spline ) { - if ( this->spline ) { - delete this->spline; - } - this->spline = spline; -} - -/* -==================== -idSurface_SweptSpline::SetSweptSpline -==================== -*/ -void idSurface_SweptSpline::SetSweptSpline( idCurve_Spline *sweptSpline ) { - if ( this->sweptSpline ) { - delete this->sweptSpline; - } - this->sweptSpline = sweptSpline; -} - -/* -==================== -idSurface_SweptSpline::SetSweptCircle - - Sets the swept spline to a NURBS circle. -==================== -*/ -void idSurface_SweptSpline::SetSweptCircle( const float radius ) { - idCurve_NURBS *nurbs = new idCurve_NURBS(); - nurbs->Clear(); - nurbs->AddValue( 0.0f, idVec4( radius, radius, 0.0f, 0.00f ) ); - nurbs->AddValue( 100.0f, idVec4( -radius, radius, 0.0f, 0.25f ) ); - nurbs->AddValue( 200.0f, idVec4( -radius, -radius, 0.0f, 0.50f ) ); - nurbs->AddValue( 300.0f, idVec4( radius, -radius, 0.0f, 0.75f ) ); - nurbs->SetBoundaryType( idCurve_NURBS::BT_CLOSED ); - nurbs->SetCloseTime( 100.0f ); - if ( sweptSpline ) { - delete sweptSpline; - } - sweptSpline = nurbs; -} - -/* -==================== -idSurface_SweptSpline::GetFrame -==================== -*/ -void idSurface_SweptSpline::GetFrame( const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame ) { - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - float a, c, s, x, y, z; - idVec3 d, v; - idMat3 axis; - - d = dir; - d.Normalize(); - v = d.Cross( previousFrame[2] ); - v.Normalize(); - - a = idMath::ACos( previousFrame[2] * d ) * 0.5f; - c = idMath::Cos( a ); - s = idMath::Sqrt( 1.0f - c * c ); - - x = v[0] * s; - y = v[1] * s; - z = v[2] * s; - - x2 = x + x; - y2 = y + y; - z2 = z + z; - xx = x * x2; - xy = x * y2; - xz = x * z2; - yy = y * y2; - yz = y * z2; - zz = z * z2; - wx = c * x2; - wy = c * y2; - wz = c * z2; - - axis[0][0] = 1.0f - ( yy + zz ); - axis[0][1] = xy - wz; - axis[0][2] = xz + wy; - axis[1][0] = xy + wz; - axis[1][1] = 1.0f - ( xx + zz ); - axis[1][2] = yz - wx; - axis[2][0] = xz - wy; - axis[2][1] = yz + wx; - axis[2][2] = 1.0f - ( xx + yy ); - - newFrame = previousFrame * axis; - - newFrame[2] = dir; - newFrame[2].Normalize(); - newFrame[1].Cross( newFrame[ 2 ], newFrame[ 0 ] ); - newFrame[1].Normalize(); - newFrame[0].Cross( newFrame[ 1 ], newFrame[ 2 ] ); - newFrame[0].Normalize(); -} - -/* -==================== -idSurface_SweptSpline::Tessellate - - tesselate the surface -==================== -*/ -void idSurface_SweptSpline::Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ) { - int i, j, offset, baseOffset, splineDiv, sweptSplineDiv; - int i0, i1, j0, j1; - float totalTime, t; - idVec4 splinePos, splineD1; - idMat3 splineMat; - - if ( !spline || !sweptSpline ) { - idSurface::Clear(); - return; - } - - verts.SetNum( splineSubdivisions * sweptSplineSubdivisions, false ); - - // calculate the points and first derivatives for the swept spline - totalTime = sweptSpline->GetTime( sweptSpline->GetNumValues() - 1 ) - sweptSpline->GetTime( 0 ) + sweptSpline->GetCloseTime(); - sweptSplineDiv = sweptSpline->GetBoundaryType() == idCurve_Spline::BT_CLOSED ? sweptSplineSubdivisions : sweptSplineSubdivisions - 1; - baseOffset = (splineSubdivisions-1) * sweptSplineSubdivisions; - for ( i = 0; i < sweptSplineSubdivisions; i++ ) { - t = totalTime * i / sweptSplineDiv; - splinePos = sweptSpline->GetCurrentValue( t ); - splineD1 = sweptSpline->GetCurrentFirstDerivative( t ); - verts[baseOffset+i].xyz = splinePos.ToVec3(); - verts[baseOffset+i].st[0] = splinePos.w; - verts[baseOffset+i].tangents[0] = splineD1.ToVec3(); - } - - // sweep the spline - totalTime = spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 ) + spline->GetCloseTime(); - splineDiv = spline->GetBoundaryType() == idCurve_Spline::BT_CLOSED ? splineSubdivisions : splineSubdivisions - 1; - splineMat.Identity(); - for ( i = 0; i < splineSubdivisions; i++ ) { - t = totalTime * i / splineDiv; - - splinePos = spline->GetCurrentValue( t ); - splineD1 = spline->GetCurrentFirstDerivative( t ); - - GetFrame( splineMat, splineD1.ToVec3(), splineMat ); - - offset = i * sweptSplineSubdivisions; - for ( j = 0; j < sweptSplineSubdivisions; j++ ) { - idDrawVert *v = &verts[offset+j]; - v->xyz = splinePos.ToVec3() + verts[baseOffset+j].xyz * splineMat; - v->st[0] = verts[baseOffset+j].st[0]; - v->st[1] = splinePos.w; - v->tangents[0] = verts[baseOffset+j].tangents[0] * splineMat; - v->tangents[1] = splineD1.ToVec3(); - v->normal = v->tangents[1].Cross( v->tangents[0] ); - v->normal.Normalize(); - v->color[0] = v->color[1] = v->color[2] = v->color[3] = 0; - } - } - - indexes.SetNum( splineDiv * sweptSplineDiv * 2 * 3, false ); - - // create indexes for the triangles - for ( offset = i = 0; i < splineDiv; i++ ) { - - i0 = (i+0) * sweptSplineSubdivisions; - i1 = (i+1) % splineSubdivisions * sweptSplineSubdivisions; - - for ( j = 0; j < sweptSplineDiv; j++ ) { - - j0 = (j+0); - j1 = (j+1) % sweptSplineSubdivisions; - - indexes[offset++] = i0 + j0; - indexes[offset++] = i0 + j1; - indexes[offset++] = i1 + j1; - - indexes[offset++] = i1 + j1; - indexes[offset++] = i1 + j0; - indexes[offset++] = i0 + j0; - } - } - - GenerateEdgeIndexes(); -} diff --git a/idlib/geometry/surface_sweptspline.h b/idlib/geometry/surface_sweptspline.h deleted file mode 100644 index 2849ed435..000000000 --- a/idlib/geometry/surface_sweptspline.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __SURFACE_SWEPTSPLINE_H__ -#define __SURFACE_SWEPTSPLINE_H__ - -/* -=============================================================================== - - Swept Spline surface. - -=============================================================================== -*/ - -class idSurface_SweptSpline : public idSurface { -public: - idSurface_SweptSpline( void ); - ~idSurface_SweptSpline( void ); - - void SetSpline( idCurve_Spline *spline ); - void SetSweptSpline( idCurve_Spline *sweptSpline ); - void SetSweptCircle( const float radius ); - - void Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ); - - void Clear( void ); - -protected: - idCurve_Spline *spline; - idCurve_Spline *sweptSpline; - - void GetFrame( const idMat3 &previousFrame, const idVec3 dir, idMat3 &newFrame ); -}; - -/* -==================== -idSurface_SweptSpline::idSurface_SweptSpline -==================== -*/ -ID_INLINE idSurface_SweptSpline::idSurface_SweptSpline( void ) { - spline = NULL; - sweptSpline = NULL; -} - -/* -==================== -idSurface_SweptSpline::~idSurface_SweptSpline -==================== -*/ -ID_INLINE idSurface_SweptSpline::~idSurface_SweptSpline( void ) { - delete spline; - delete sweptSpline; -} - -/* -==================== -idSurface_SweptSpline::Clear -==================== -*/ -ID_INLINE void idSurface_SweptSpline::Clear( void ) { - idSurface::Clear(); - delete spline; - spline = NULL; - delete sweptSpline; - sweptSpline = NULL; -} - -#endif /* !__SURFACE_SWEPTSPLINE_H__ */ diff --git a/idlib/geometry/tracemodel.cpp b/idlib/geometry/tracemodel.cpp deleted file mode 100644 index 78ee75468..000000000 --- a/idlib/geometry/tracemodel.cpp +++ /dev/null @@ -1,1553 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "tracemodel.h" - - -/* -============ -idTraceModel::SetupBox -============ -*/ -void idTraceModel::SetupBox( const idBounds &boxBounds ) { - int i; - - if ( type != TRM_BOX ) { - InitBox(); - } - // offset to center - offset = ( boxBounds[0] + boxBounds[1] ) * 0.5f; - // set box vertices - for ( i = 0; i < 8; i++ ) { - verts[i][0] = boxBounds[(i^(i>>1))&1][0]; - verts[i][1] = boxBounds[(i>>1)&1][1]; - verts[i][2] = boxBounds[(i>>2)&1][2]; - } - // set polygon plane distances - polys[0].dist = -boxBounds[0][2]; - polys[1].dist = boxBounds[1][2]; - polys[2].dist = -boxBounds[0][1]; - polys[3].dist = boxBounds[1][0]; - polys[4].dist = boxBounds[1][1]; - polys[5].dist = -boxBounds[0][0]; - // set polygon bounds - for ( i = 0; i < 6; i++ ) { - polys[i].bounds = boxBounds; - } - polys[0].bounds[1][2] = boxBounds[0][2]; - polys[1].bounds[0][2] = boxBounds[1][2]; - polys[2].bounds[1][1] = boxBounds[0][1]; - polys[3].bounds[0][0] = boxBounds[1][0]; - polys[4].bounds[0][1] = boxBounds[1][1]; - polys[5].bounds[1][0] = boxBounds[0][0]; - - bounds = boxBounds; -} - -/* -============ -idTraceModel::SetupBox - - The origin is placed at the center of the cube. -============ -*/ -void idTraceModel::SetupBox( const float size ) { - idBounds boxBounds; - float halfSize; - - halfSize = size * 0.5f; - boxBounds[0].Set( -halfSize, -halfSize, -halfSize ); - boxBounds[1].Set( halfSize, halfSize, halfSize ); - SetupBox( boxBounds ); -} - -/* -============ -idTraceModel::InitBox - - Initialize size independent box. -============ -*/ -void idTraceModel::InitBox( void ) { - int i; - - type = TRM_BOX; - numVerts = 8; - numEdges = 12; - numPolys = 6; - - // set box edges - for ( i = 0; i < 4; i++ ) { - edges[ i + 1 ].v[0] = i; - edges[ i + 1 ].v[1] = (i + 1) & 3; - edges[ i + 5 ].v[0] = 4 + i; - edges[ i + 5 ].v[1] = 4 + ((i + 1) & 3); - edges[ i + 9 ].v[0] = i; - edges[ i + 9 ].v[1] = 4 + i; - } - - // all edges of a polygon go counter clockwise - polys[0].numEdges = 4; - polys[0].edges[0] = -4; - polys[0].edges[1] = -3; - polys[0].edges[2] = -2; - polys[0].edges[3] = -1; - polys[0].normal.Set( 0.0f, 0.0f, -1.0f ); - - polys[1].numEdges = 4; - polys[1].edges[0] = 5; - polys[1].edges[1] = 6; - polys[1].edges[2] = 7; - polys[1].edges[3] = 8; - polys[1].normal.Set( 0.0f, 0.0f, 1.0f ); - - polys[2].numEdges = 4; - polys[2].edges[0] = 1; - polys[2].edges[1] = 10; - polys[2].edges[2] = -5; - polys[2].edges[3] = -9; - polys[2].normal.Set( 0.0f, -1.0f, 0.0f ); - - polys[3].numEdges = 4; - polys[3].edges[0] = 2; - polys[3].edges[1] = 11; - polys[3].edges[2] = -6; - polys[3].edges[3] = -10; - polys[3].normal.Set( 1.0f, 0.0f, 0.0f ); - - polys[4].numEdges = 4; - polys[4].edges[0] = 3; - polys[4].edges[1] = 12; - polys[4].edges[2] = -7; - polys[4].edges[3] = -11; - polys[4].normal.Set( 0.0f, 1.0f, 0.0f ); - - polys[5].numEdges = 4; - polys[5].edges[0] = 4; - polys[5].edges[1] = 9; - polys[5].edges[2] = -8; - polys[5].edges[3] = -12; - polys[5].normal.Set( -1.0f, 0.0f, 0.0f ); - - // convex model - isConvex = true; - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::SetupOctahedron -============ -*/ -void idTraceModel::SetupOctahedron( const idBounds &octBounds ) { - int i, e0, e1, v0, v1, v2; - idVec3 v; - - if ( type != TRM_OCTAHEDRON ) { - InitOctahedron(); - } - - offset = ( octBounds[0] + octBounds[1] ) * 0.5f; - v[0] = octBounds[1][0] - offset[0]; - v[1] = octBounds[1][1] - offset[1]; - v[2] = octBounds[1][2] - offset[2]; - - // set vertices - verts[0].Set( offset.x + v[0], offset.y, offset.z ); - verts[1].Set( offset.x - v[0], offset.y, offset.z ); - verts[2].Set( offset.x, offset.y + v[1], offset.z ); - verts[3].Set( offset.x, offset.y - v[1], offset.z ); - verts[4].Set( offset.x, offset.y, offset.z + v[2] ); - verts[5].Set( offset.x, offset.y, offset.z - v[2] ); - - // set polygons - for ( i = 0; i < numPolys; i++ ) { - e0 = polys[i].edges[0]; - e1 = polys[i].edges[1]; - v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; - v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; - v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; - // polygon plane - polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); - polys[i].normal.Normalize(); - polys[i].dist = polys[i].normal * verts[v0]; - // polygon bounds - polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; - polys[i].bounds.AddPoint( verts[v1] ); - polys[i].bounds.AddPoint( verts[v2] ); - } - - // trm bounds - bounds = octBounds; - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::SetupOctahedron - - The origin is placed at the center of the octahedron. -============ -*/ -void idTraceModel::SetupOctahedron( const float size ) { - idBounds octBounds; - float halfSize; - - halfSize = size * 0.5f; - octBounds[0].Set( -halfSize, -halfSize, -halfSize ); - octBounds[1].Set( halfSize, halfSize, halfSize ); - SetupOctahedron( octBounds ); -} - -/* -============ -idTraceModel::InitOctahedron - - Initialize size independent octahedron. -============ -*/ -void idTraceModel::InitOctahedron( void ) { - - type = TRM_OCTAHEDRON; - numVerts = 6; - numEdges = 12; - numPolys = 8; - - // set edges - edges[ 1].v[0] = 4; edges[ 1].v[1] = 0; - edges[ 2].v[0] = 0; edges[ 2].v[1] = 2; - edges[ 3].v[0] = 2; edges[ 3].v[1] = 4; - edges[ 4].v[0] = 2; edges[ 4].v[1] = 1; - edges[ 5].v[0] = 1; edges[ 5].v[1] = 4; - edges[ 6].v[0] = 1; edges[ 6].v[1] = 3; - edges[ 7].v[0] = 3; edges[ 7].v[1] = 4; - edges[ 8].v[0] = 3; edges[ 8].v[1] = 0; - edges[ 9].v[0] = 5; edges[ 9].v[1] = 2; - edges[10].v[0] = 0; edges[10].v[1] = 5; - edges[11].v[0] = 5; edges[11].v[1] = 1; - edges[12].v[0] = 5; edges[12].v[1] = 3; - - // all edges of a polygon go counter clockwise - polys[0].numEdges = 3; - polys[0].edges[0] = 1; - polys[0].edges[1] = 2; - polys[0].edges[2] = 3; - - polys[1].numEdges = 3; - polys[1].edges[0] = -3; - polys[1].edges[1] = 4; - polys[1].edges[2] = 5; - - polys[2].numEdges = 3; - polys[2].edges[0] = -5; - polys[2].edges[1] = 6; - polys[2].edges[2] = 7; - - polys[3].numEdges = 3; - polys[3].edges[0] = -7; - polys[3].edges[1] = 8; - polys[3].edges[2] = -1; - - polys[4].numEdges = 3; - polys[4].edges[0] = 9; - polys[4].edges[1] = -2; - polys[4].edges[2] = 10; - - polys[5].numEdges = 3; - polys[5].edges[0] = 11; - polys[5].edges[1] = -4; - polys[5].edges[2] = -9; - - polys[6].numEdges = 3; - polys[6].edges[0] = 12; - polys[6].edges[1] = -6; - polys[6].edges[2] = -11; - - polys[7].numEdges = 3; - polys[7].edges[0] = -10; - polys[7].edges[1] = -8; - polys[7].edges[2] = -12; - - // convex model - isConvex = true; -} - -/* -============ -idTraceModel::SetupDodecahedron -============ -*/ -void idTraceModel::SetupDodecahedron( const idBounds &dodBounds ) { - int i, e0, e1, e2, e3, v0, v1, v2, v3, v4; - float s, d; - idVec3 a, b, c; - - if ( type != TRM_DODECAHEDRON ) { - InitDodecahedron(); - } - - a[0] = a[1] = a[2] = 0.5773502691896257f; // 1.0f / ( 3.0f ) ^ 0.5f; - b[0] = b[1] = b[2] = 0.3568220897730899f; // ( ( 3.0f - ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; - c[0] = c[1] = c[2] = 0.9341723589627156f; // ( ( 3.0f + ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; - d = 0.5f / c[0]; - s = ( dodBounds[1][0] - dodBounds[0][0] ) * d; - a[0] *= s; - b[0] *= s; - c[0] *= s; - s = ( dodBounds[1][1] - dodBounds[0][1] ) * d; - a[1] *= s; - b[1] *= s; - c[1] *= s; - s = ( dodBounds[1][2] - dodBounds[0][2] ) * d; - a[2] *= s; - b[2] *= s; - c[2] *= s; - - offset = ( dodBounds[0] + dodBounds[1] ) * 0.5f; - - // set vertices - verts[ 0].Set( offset.x + a[0], offset.y + a[1], offset.z + a[2] ); - verts[ 1].Set( offset.x + a[0], offset.y + a[1], offset.z - a[2] ); - verts[ 2].Set( offset.x + a[0], offset.y - a[1], offset.z + a[2] ); - verts[ 3].Set( offset.x + a[0], offset.y - a[1], offset.z - a[2] ); - verts[ 4].Set( offset.x - a[0], offset.y + a[1], offset.z + a[2] ); - verts[ 5].Set( offset.x - a[0], offset.y + a[1], offset.z - a[2] ); - verts[ 6].Set( offset.x - a[0], offset.y - a[1], offset.z + a[2] ); - verts[ 7].Set( offset.x - a[0], offset.y - a[1], offset.z - a[2] ); - verts[ 8].Set( offset.x + b[0], offset.y + c[1], offset.z ); - verts[ 9].Set( offset.x - b[0], offset.y + c[1], offset.z ); - verts[10].Set( offset.x + b[0], offset.y - c[1], offset.z ); - verts[11].Set( offset.x - b[0], offset.y - c[1], offset.z ); - verts[12].Set( offset.x + c[0], offset.y , offset.z + b[2] ); - verts[13].Set( offset.x + c[0], offset.y , offset.z - b[2] ); - verts[14].Set( offset.x - c[0], offset.y , offset.z + b[2] ); - verts[15].Set( offset.x - c[0], offset.y , offset.z - b[2] ); - verts[16].Set( offset.x , offset.y + b[1], offset.z + c[2] ); - verts[17].Set( offset.x , offset.y - b[1], offset.z + c[2] ); - verts[18].Set( offset.x , offset.y + b[1], offset.z - c[2] ); - verts[19].Set( offset.x , offset.y - b[1], offset.z - c[2] ); - - // set polygons - for ( i = 0; i < numPolys; i++ ) { - e0 = polys[i].edges[0]; - e1 = polys[i].edges[1]; - e2 = polys[i].edges[2]; - e3 = polys[i].edges[3]; - v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; - v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; - v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; - v3 = edges[abs(e2)].v[INTSIGNBITNOTSET(e2)]; - v4 = edges[abs(e3)].v[INTSIGNBITNOTSET(e3)]; - // polygon plane - polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); - polys[i].normal.Normalize(); - polys[i].dist = polys[i].normal * verts[v0]; - // polygon bounds - polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; - polys[i].bounds.AddPoint( verts[v1] ); - polys[i].bounds.AddPoint( verts[v2] ); - polys[i].bounds.AddPoint( verts[v3] ); - polys[i].bounds.AddPoint( verts[v4] ); - } - - // trm bounds - bounds = dodBounds; - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::SetupDodecahedron - - The origin is placed at the center of the octahedron. -============ -*/ -void idTraceModel::SetupDodecahedron( const float size ) { - idBounds dodBounds; - float halfSize; - - halfSize = size * 0.5f; - dodBounds[0].Set( -halfSize, -halfSize, -halfSize ); - dodBounds[1].Set( halfSize, halfSize, halfSize ); - SetupDodecahedron( dodBounds ); -} - -/* -============ -idTraceModel::InitDodecahedron - - Initialize size independent dodecahedron. -============ -*/ -void idTraceModel::InitDodecahedron( void ) { - - type = TRM_DODECAHEDRON; - numVerts = 20; - numEdges = 30; - numPolys = 12; - - // set edges - edges[ 1].v[0] = 0; edges[ 1].v[1] = 8; - edges[ 2].v[0] = 8; edges[ 2].v[1] = 9; - edges[ 3].v[0] = 9; edges[ 3].v[1] = 4; - edges[ 4].v[0] = 4; edges[ 4].v[1] = 16; - edges[ 5].v[0] = 16; edges[ 5].v[1] = 0; - edges[ 6].v[0] = 16; edges[ 6].v[1] = 17; - edges[ 7].v[0] = 17; edges[ 7].v[1] = 2; - edges[ 8].v[0] = 2; edges[ 8].v[1] = 12; - edges[ 9].v[0] = 12; edges[ 9].v[1] = 0; - edges[10].v[0] = 2; edges[10].v[1] = 10; - edges[11].v[0] = 10; edges[11].v[1] = 3; - edges[12].v[0] = 3; edges[12].v[1] = 13; - edges[13].v[0] = 13; edges[13].v[1] = 12; - edges[14].v[0] = 9; edges[14].v[1] = 5; - edges[15].v[0] = 5; edges[15].v[1] = 15; - edges[16].v[0] = 15; edges[16].v[1] = 14; - edges[17].v[0] = 14; edges[17].v[1] = 4; - edges[18].v[0] = 3; edges[18].v[1] = 19; - edges[19].v[0] = 19; edges[19].v[1] = 18; - edges[20].v[0] = 18; edges[20].v[1] = 1; - edges[21].v[0] = 1; edges[21].v[1] = 13; - edges[22].v[0] = 7; edges[22].v[1] = 11; - edges[23].v[0] = 11; edges[23].v[1] = 6; - edges[24].v[0] = 6; edges[24].v[1] = 14; - edges[25].v[0] = 15; edges[25].v[1] = 7; - edges[26].v[0] = 1; edges[26].v[1] = 8; - edges[27].v[0] = 18; edges[27].v[1] = 5; - edges[28].v[0] = 6; edges[28].v[1] = 17; - edges[29].v[0] = 11; edges[29].v[1] = 10; - edges[30].v[0] = 19; edges[30].v[1] = 7; - - // all edges of a polygon go counter clockwise - polys[0].numEdges = 5; - polys[0].edges[0] = 1; - polys[0].edges[1] = 2; - polys[0].edges[2] = 3; - polys[0].edges[3] = 4; - polys[0].edges[4] = 5; - - polys[1].numEdges = 5; - polys[1].edges[0] = -5; - polys[1].edges[1] = 6; - polys[1].edges[2] = 7; - polys[1].edges[3] = 8; - polys[1].edges[4] = 9; - - polys[2].numEdges = 5; - polys[2].edges[0] = -8; - polys[2].edges[1] = 10; - polys[2].edges[2] = 11; - polys[2].edges[3] = 12; - polys[2].edges[4] = 13; - - polys[3].numEdges = 5; - polys[3].edges[0] = 14; - polys[3].edges[1] = 15; - polys[3].edges[2] = 16; - polys[3].edges[3] = 17; - polys[3].edges[4] = -3; - - polys[4].numEdges = 5; - polys[4].edges[0] = 18; - polys[4].edges[1] = 19; - polys[4].edges[2] = 20; - polys[4].edges[3] = 21; - polys[4].edges[4] = -12; - - polys[5].numEdges = 5; - polys[5].edges[0] = 22; - polys[5].edges[1] = 23; - polys[5].edges[2] = 24; - polys[5].edges[3] = -16; - polys[5].edges[4] = 25; - - polys[6].numEdges = 5; - polys[6].edges[0] = -9; - polys[6].edges[1] = -13; - polys[6].edges[2] = -21; - polys[6].edges[3] = 26; - polys[6].edges[4] = -1; - - polys[7].numEdges = 5; - polys[7].edges[0] = -26; - polys[7].edges[1] = -20; - polys[7].edges[2] = 27; - polys[7].edges[3] = -14; - polys[7].edges[4] = -2; - - polys[8].numEdges = 5; - polys[8].edges[0] = -4; - polys[8].edges[1] = -17; - polys[8].edges[2] = -24; - polys[8].edges[3] = 28; - polys[8].edges[4] = -6; - - polys[9].numEdges = 5; - polys[9].edges[0] = -23; - polys[9].edges[1] = 29; - polys[9].edges[2] = -10; - polys[9].edges[3] = -7; - polys[9].edges[4] = -28; - - polys[10].numEdges = 5; - polys[10].edges[0] = -25; - polys[10].edges[1] = -15; - polys[10].edges[2] = -27; - polys[10].edges[3] = -19; - polys[10].edges[4] = 30; - - polys[11].numEdges = 5; - polys[11].edges[0] = -30; - polys[11].edges[1] = -18; - polys[11].edges[2] = -11; - polys[11].edges[3] = -29; - polys[11].edges[4] = -22; - - // convex model - isConvex = true; -} - -/* -============ -idTraceModel::SetupCylinder -============ -*/ -void idTraceModel::SetupCylinder( const idBounds &cylBounds, const int numSides ) { - int i, n, ii, n2; - float angle; - idVec3 halfSize; - - n = numSides; - if ( n < 3 ) { - n = 3; - } - if ( n * 2 > MAX_TRACEMODEL_VERTS ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many vertices\n" ); - n = MAX_TRACEMODEL_VERTS / 2; - } - if ( n * 3 > MAX_TRACEMODEL_EDGES ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many sides\n" ); - n = MAX_TRACEMODEL_EDGES / 3; - } - if ( n + 2 > MAX_TRACEMODEL_POLYS ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many polygons\n" ); - n = MAX_TRACEMODEL_POLYS - 2; - } - - type = TRM_CYLINDER; - numVerts = n * 2; - numEdges = n * 3; - numPolys = n + 2; - offset = ( cylBounds[0] + cylBounds[1] ) * 0.5f; - halfSize = cylBounds[1] - offset; - for ( i = 0; i < n; i++ ) { - // verts - angle = idMath::TWO_PI * i / n; - verts[i].x = cos( angle ) * halfSize.x + offset.x; - verts[i].y = sin( angle ) * halfSize.y + offset.y; - verts[i].z = -halfSize.z + offset.z; - verts[n+i].x = verts[i].x; - verts[n+i].y = verts[i].y; - verts[n+i].z = halfSize.z + offset.z; - // edges - ii = i + 1; - n2 = n << 1; - edges[ii].v[0] = i; - edges[ii].v[1] = ii % n; - edges[n+ii].v[0] = edges[ii].v[0] + n; - edges[n+ii].v[1] = edges[ii].v[1] + n; - edges[n2+ii].v[0] = i; - edges[n2+ii].v[1] = n + i; - // vertical polygon edges - polys[i].numEdges = 4; - polys[i].edges[0] = ii; - polys[i].edges[1] = n2 + (ii % n) + 1; - polys[i].edges[2] = -(n + ii); - polys[i].edges[3] = -(n2 + ii); - // bottom and top polygon edges - polys[n].edges[i] = -(n - i); - polys[n+1].edges[i] = n + ii; - } - // bottom and top polygon numEdges - polys[n].numEdges = n; - polys[n+1].numEdges = n; - // polygons - for ( i = 0; i < n; i++ ) { - // vertical polygon plane - polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n+i] - verts[i] ); - polys[i].normal.Normalize(); - polys[i].dist = polys[i].normal * verts[i]; - // vertical polygon bounds - polys[i].bounds.Clear(); - polys[i].bounds.AddPoint( verts[i] ); - polys[i].bounds.AddPoint( verts[(i+1)%n] ); - polys[i].bounds[0][2] = -halfSize.z + offset.z; - polys[i].bounds[1][2] = halfSize.z + offset.z; - } - // bottom and top polygon plane - polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); - polys[n].dist = -cylBounds[0][2]; - polys[n+1].normal.Set( 0.0f, 0.0f, 1.0f ); - polys[n+1].dist = cylBounds[1][2]; - // trm bounds - bounds = cylBounds; - // bottom and top polygon bounds - polys[n].bounds = bounds; - polys[n].bounds[1][2] = bounds[0][2]; - polys[n+1].bounds = bounds; - polys[n+1].bounds[0][2] = bounds[1][2]; - // convex model - isConvex = true; - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::SetupCylinder - - The origin is placed at the center of the cylinder. -============ -*/ -void idTraceModel::SetupCylinder( const float height, const float width, const int numSides ) { - idBounds cylBounds; - float halfHeight, halfWidth; - - halfHeight = height * 0.5f; - halfWidth = width * 0.5f; - cylBounds[0].Set( -halfWidth, -halfWidth, -halfHeight ); - cylBounds[1].Set( halfWidth, halfWidth, halfHeight ); - SetupCylinder( cylBounds, numSides ); -} - -/* -============ -idTraceModel::SetupCone -============ -*/ -void idTraceModel::SetupCone( const idBounds &coneBounds, const int numSides ) { - int i, n, ii; - float angle; - idVec3 halfSize; - - n = numSides; - if ( n < 2 ) { - n = 3; - } - if ( n + 1 > MAX_TRACEMODEL_VERTS ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many vertices\n" ); - n = MAX_TRACEMODEL_VERTS - 1; - } - if ( n * 2 > MAX_TRACEMODEL_EDGES ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many edges\n" ); - n = MAX_TRACEMODEL_EDGES / 2; - } - if ( n + 1 > MAX_TRACEMODEL_POLYS ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many polygons\n" ); - n = MAX_TRACEMODEL_POLYS - 1; - } - - type = TRM_CONE; - numVerts = n + 1; - numEdges = n * 2; - numPolys = n + 1; - offset = ( coneBounds[0] + coneBounds[1] ) * 0.5f; - halfSize = coneBounds[1] - offset; - verts[n].Set( 0.0f, 0.0f, halfSize.z + offset.z ); - for ( i = 0; i < n; i++ ) { - // verts - angle = idMath::TWO_PI * i / n; - verts[i].x = cos( angle ) * halfSize.x + offset.x; - verts[i].y = sin( angle ) * halfSize.y + offset.y; - verts[i].z = -halfSize.z + offset.z; - // edges - ii = i + 1; - edges[ii].v[0] = i; - edges[ii].v[1] = ii % n; - edges[n+ii].v[0] = i; - edges[n+ii].v[1] = n; - // vertical polygon edges - polys[i].numEdges = 3; - polys[i].edges[0] = ii; - polys[i].edges[1] = n + (ii % n) + 1; - polys[i].edges[2] = -(n + ii); - // bottom polygon edges - polys[n].edges[i] = -(n - i); - } - // bottom polygon numEdges - polys[n].numEdges = n; - - // polygons - for ( i = 0; i < n; i++ ) { - // polygon plane - polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n] - verts[i] ); - polys[i].normal.Normalize(); - polys[i].dist = polys[i].normal * verts[i]; - // polygon bounds - polys[i].bounds.Clear(); - polys[i].bounds.AddPoint( verts[i] ); - polys[i].bounds.AddPoint( verts[(i+1)%n] ); - polys[i].bounds.AddPoint( verts[n] ); - } - // bottom polygon plane - polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); - polys[n].dist = -coneBounds[0][2]; - // trm bounds - bounds = coneBounds; - // bottom polygon bounds - polys[n].bounds = bounds; - polys[n].bounds[1][2] = bounds[0][2]; - // convex model - isConvex = true; - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::SetupCone - - The origin is placed at the apex of the cone. -============ -*/ -void idTraceModel::SetupCone( const float height, const float width, const int numSides ) { - idBounds coneBounds; - float halfWidth; - - halfWidth = width * 0.5f; - coneBounds[0].Set( -halfWidth, -halfWidth, -height ); - coneBounds[1].Set( halfWidth, halfWidth, 0.0f ); - SetupCone( coneBounds, numSides ); -} - -/* -============ -idTraceModel::SetupBone - - The origin is placed at the center of the bone. -============ -*/ -void idTraceModel::SetupBone( const float length, const float width ) { - int i, j, edgeNum; - float halfLength = length * 0.5f; - - if ( type != TRM_BONE ) { - InitBone(); - } - // offset to center - offset.Set( 0.0f, 0.0f, 0.0f ); - // set vertices - verts[0].Set( 0.0f, 0.0f, -halfLength ); - verts[1].Set( 0.0f, width * -0.5f, 0.0f ); - verts[2].Set( width * 0.5f, width * 0.25f, 0.0f ); - verts[3].Set( width * -0.5f, width * 0.25f, 0.0f ); - verts[4].Set( 0.0f, 0.0f, halfLength ); - // set bounds - bounds[0].Set( width * -0.5f, width * -0.5f, -halfLength ); - bounds[1].Set( width * 0.5f, width * 0.25f, halfLength ); - // poly plane normals - polys[0].normal = ( verts[2] - verts[0] ).Cross( verts[1] - verts[0] ); - polys[0].normal.Normalize(); - polys[2].normal.Set( -polys[0].normal[0], polys[0].normal[1], polys[0].normal[2] ); - polys[3].normal.Set( polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); - polys[5].normal.Set( -polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); - polys[1].normal = (verts[3] - verts[0]).Cross(verts[2] - verts[0]); - polys[1].normal.Normalize(); - polys[4].normal.Set( polys[1].normal[0], polys[1].normal[1], -polys[1].normal[2] ); - // poly plane distances - for ( i = 0; i < 6; i++ ) { - polys[i].dist = polys[i].normal * verts[ edges[ abs(polys[i].edges[0]) ].v[0] ]; - polys[i].bounds.Clear(); - for ( j = 0; j < 3; j++ ) { - edgeNum = polys[i].edges[ j ]; - polys[i].bounds.AddPoint( verts[ edges[abs(edgeNum)].v[edgeNum < 0] ] ); - } - } - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::InitBone - - Initialize size independent bone. -============ -*/ -void idTraceModel::InitBone( void ) { - int i; - - type = TRM_BONE; - numVerts = 5; - numEdges = 9; - numPolys = 6; - - // set bone edges - for ( i = 0; i < 3; i++ ) { - edges[ i + 1 ].v[0] = 0; - edges[ i + 1 ].v[1] = i + 1; - edges[ i + 4 ].v[0] = 1 + i; - edges[ i + 4 ].v[1] = 1 + ((i + 1) % 3); - edges[ i + 7 ].v[0] = i + 1; - edges[ i + 7 ].v[1] = 4; - } - - // all edges of a polygon go counter clockwise - polys[0].numEdges = 3; - polys[0].edges[0] = 2; - polys[0].edges[1] = -4; - polys[0].edges[2] = -1; - - polys[1].numEdges = 3; - polys[1].edges[0] = 3; - polys[1].edges[1] = -5; - polys[1].edges[2] = -2; - - polys[2].numEdges = 3; - polys[2].edges[0] = 1; - polys[2].edges[1] = -6; - polys[2].edges[2] = -3; - - polys[3].numEdges = 3; - polys[3].edges[0] = 4; - polys[3].edges[1] = 8; - polys[3].edges[2] = -7; - - polys[4].numEdges = 3; - polys[4].edges[0] = 5; - polys[4].edges[1] = 9; - polys[4].edges[2] = -8; - - polys[5].numEdges = 3; - polys[5].edges[0] = 6; - polys[5].edges[1] = 7; - polys[5].edges[2] = -9; - - // convex model - isConvex = true; -} - -/* -============ -idTraceModel::SetupPolygon -============ -*/ -void idTraceModel::SetupPolygon( const idVec3 *v, const int count ) { - int i, j; - idVec3 mid; - - type = TRM_POLYGON; - numVerts = count; - // times three because we need to be able to turn the polygon into a volume - if ( numVerts * 3 > MAX_TRACEMODEL_EDGES ) { - idLib::common->Printf( "WARNING: idTraceModel::SetupPolygon: too many vertices\n" ); - numVerts = MAX_TRACEMODEL_EDGES / 3; - } - - numEdges = numVerts; - numPolys = 2; - // set polygon planes - polys[0].numEdges = numEdges; - polys[0].normal = ( v[1] - v[0] ).Cross( v[2] - v[0] ); - polys[0].normal.Normalize(); - polys[0].dist = polys[0].normal * v[0]; - polys[1].numEdges = numEdges; - polys[1].normal = -polys[0].normal; - polys[1].dist = -polys[0].dist; - // setup verts, edges and polygons - polys[0].bounds.Clear(); - mid = vec3_origin; - for ( i = 0, j = 1; i < numVerts; i++, j++ ) { - if ( j >= numVerts ) { - j = 0; - } - verts[i] = v[i]; - edges[i+1].v[0] = i; - edges[i+1].v[1] = j; - edges[i+1].normal = polys[0].normal.Cross( v[i] - v[j] ); - edges[i+1].normal.Normalize(); - polys[0].edges[i] = i + 1; - polys[1].edges[i] = -(numVerts - i); - polys[0].bounds.AddPoint( verts[i] ); - mid += v[i]; - } - polys[1].bounds = polys[0].bounds; - // offset to center - offset = mid * (1.0f / numVerts); - // total bounds - bounds = polys[0].bounds; - // considered non convex because the model has no volume - isConvex = false; -} - -/* -============ -idTraceModel::SetupPolygon -============ -*/ -void idTraceModel::SetupPolygon( const idWinding &w ) { - int i; - idVec3 *verts; - - verts = (idVec3 *) _alloca16( w.GetNumPoints() * sizeof( idVec3 ) ); - for ( i = 0; i < w.GetNumPoints(); i++ ) { - verts[i] = w[i].ToVec3(); - } - SetupPolygon( verts, w.GetNumPoints() ); -} - -/* -============ -idTraceModel::VolumeFromPolygon -============ -*/ -void idTraceModel::VolumeFromPolygon( idTraceModel &trm, float thickness ) const { - int i; - - trm = *this; - trm.type = TRM_POLYGONVOLUME; - trm.numVerts = numVerts * 2; - trm.numEdges = numEdges * 3; - trm.numPolys = numEdges + 2; - for ( i = 0; i < numEdges; i++ ) { - trm.verts[ numVerts + i ] = verts[i] - thickness * polys[0].normal; - trm.edges[ numEdges + i + 1 ].v[0] = numVerts + i; - trm.edges[ numEdges + i + 1 ].v[1] = numVerts + (i+1) % numVerts; - trm.edges[ numEdges * 2 + i + 1 ].v[0] = i; - trm.edges[ numEdges * 2 + i + 1 ].v[1] = numVerts + i; - trm.polys[1].edges[i] = -(numEdges + i + 1); - trm.polys[2+i].numEdges = 4; - trm.polys[2+i].edges[0] = -(i + 1); - trm.polys[2+i].edges[1] = numEdges*2 + i + 1; - trm.polys[2+i].edges[2] = numEdges + i + 1; - trm.polys[2+i].edges[3] = -(numEdges*2 + (i+1) % numEdges + 1); - trm.polys[2+i].normal = (verts[(i + 1) % numVerts] - verts[i]).Cross( polys[0].normal ); - trm.polys[2+i].normal.Normalize(); - trm.polys[2+i].dist = trm.polys[2+i].normal * verts[i]; - } - trm.polys[1].dist = trm.polys[1].normal * trm.verts[ numEdges ]; - - trm.GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::GenerateEdgeNormals -============ -*/ -#define SHARP_EDGE_DOT -0.7f - -int idTraceModel::GenerateEdgeNormals( void ) { - int i, j, edgeNum, numSharpEdges; - float dot; - idVec3 dir; - traceModelPoly_t *poly; - traceModelEdge_t *edge; - - for ( i = 0; i <= numEdges; i++ ) { - edges[i].normal.Zero(); - } - - numSharpEdges = 0; - for ( i = 0; i < numPolys; i++ ) { - poly = polys + i; - for ( j = 0; j < poly->numEdges; j++ ) { - edgeNum = poly->edges[j]; - edge = edges + abs( edgeNum ); - if ( edge->normal[0] == 0.0f && edge->normal[1] == 0.0f && edge->normal[2] == 0.0f ) { - edge->normal = poly->normal; - } - else { - dot = edge->normal * poly->normal; - // if the two planes make a very sharp edge - if ( dot < SHARP_EDGE_DOT ) { - // max length normal pointing outside both polygons - dir = verts[ edge->v[edgeNum > 0]] - verts[ edge->v[edgeNum < 0]]; - edge->normal = edge->normal.Cross( dir ) + poly->normal.Cross( -dir ); - edge->normal *= ( 0.5f / ( 0.5f + 0.5f * SHARP_EDGE_DOT ) ) / edge->normal.Length(); - numSharpEdges++; - } - else { - edge->normal = ( 0.5f / ( 0.5f + 0.5f * dot ) ) * ( edge->normal + poly->normal ); - } - } - } - } - return numSharpEdges; -} - -/* -============ -idTraceModel::Translate -============ -*/ -void idTraceModel::Translate( const idVec3 &translation ) { - int i; - - for ( i = 0; i < numVerts; i++ ) { - verts[i] += translation; - } - for ( i = 0; i < numPolys; i++ ) { - polys[i].dist += polys[i].normal * translation; - polys[i].bounds[0] += translation; - polys[i].bounds[1] += translation; - } - offset += translation; - bounds[0] += translation; - bounds[1] += translation; -} - -/* -============ -idTraceModel::Rotate -============ -*/ -void idTraceModel::Rotate( const idMat3 &rotation, bool isRotationOrthogonal ) { - int i, j, edgeNum; - - idMat3 normalRotation = rotation; - if (!isRotationOrthogonal) { - bool nonSingular = normalRotation.InverseSelf(); - nonSingular; //eliminates "never used" warning in release - assert(nonSingular); - normalRotation.TransposeSelf(); - } - - for ( i = 0; i < numVerts; i++ ) { - verts[i] *= rotation; - } - - bounds.Clear(); - for ( i = 0; i < numPolys; i++ ) { - polys[i].normal *= normalRotation; - if (!isRotationOrthogonal) - polys[i].normal.Normalize(); - polys[i].bounds.Clear(); - edgeNum = 0; - for ( j = 0; j < polys[i].numEdges; j++ ) { - edgeNum = polys[i].edges[j]; - polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); - } - polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; - bounds += polys[i].bounds; - } - - GenerateEdgeNormals(); -} - -/* -============ -idTraceModel::Scale -============ -*/ -void idTraceModel::Scale( const idVec3 &scale ) { - int i, j, edgeNum, d; - const float *scalePtr = scale.ToFloatPtr(); - for ( d = 0; d < 3; d++ ) - assert(scalePtr[d] != 0.0f); - - for ( i = 0; i < numVerts; i++ ) { - for ( d = 0; d < 3; d++ ) - verts[i].ToFloatPtr()[d] *= scalePtr[d]; - } - - bounds.Clear(); - for ( i = 0; i < numPolys; i++ ) { - for ( d = 0; d < 3; d++ ) - polys[i].normal.ToFloatPtr()[d] /= scalePtr[d]; - polys[i].normal.Normalize(); - polys[i].bounds.Clear(); - edgeNum = 0; - for ( j = 0; j < polys[i].numEdges; j++ ) { - edgeNum = polys[i].edges[j]; - polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); - } - polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; - bounds += polys[i].bounds; - } - - GenerateEdgeNormals(); -} - -/* Old code, commented out tels 2011-01-13 -============ -idTraceModel::Rotate -============ -void idTraceModel::Rotate( const idMat3 &rotation ) { - int i, j, edgeNum; - - for ( i = 0; i < numVerts; i++ ) { - verts[i] *= rotation; - } - - bounds.Clear(); - for ( i = 0; i < numPolys; i++ ) { - polys[i].normal *= rotation; - polys[i].bounds.Clear(); - edgeNum = 0; - for ( j = 0; j < polys[i].numEdges; j++ ) { - edgeNum = polys[i].edges[j]; - polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); - } - polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; - bounds += polys[i].bounds; - } - - GenerateEdgeNormals(); -} -*/ - -/* -============ -idTraceModel::Shrink -============ -*/ -void idTraceModel::Shrink( const float m ) { - int i, j, edgeNum; - traceModelEdge_t *edge; - idVec3 dir; - - if ( type == TRM_POLYGON ) { - for ( i = 0; i < numEdges; i++ ) { - edgeNum = polys[0].edges[i]; - edge = &edges[abs(edgeNum)]; - dir = verts[ edge->v[ INTSIGNBITSET(edgeNum) ] ] - verts[ edge->v[ INTSIGNBITNOTSET(edgeNum) ] ]; - if ( dir.Normalize() < 2.0f * m ) { - continue; - } - dir *= m; - verts[ edge->v[ 0 ] ] -= dir; - verts[ edge->v[ 1 ] ] += dir; - } - return; - } - - for ( i = 0; i < numPolys; i++ ) { - polys[i].dist -= m; - - for ( j = 0; j < polys[i].numEdges; j++ ) { - edgeNum = polys[i].edges[j]; - edge = &edges[abs(edgeNum)]; - verts[ edge->v[ INTSIGNBITSET(edgeNum) ] ] -= polys[i].normal * m; - } - } -} - -/* -============ -idTraceModel::Compare -============ -*/ -bool idTraceModel::Compare( const idTraceModel &trm ) const { - int i; - - if ( type != trm.type || numVerts != trm.numVerts || - numEdges != trm.numEdges || numPolys != trm.numPolys ) { - return false; - } - if ( bounds != trm.bounds || offset != trm.offset ) { - return false; - } - - switch( type ) { - case TRM_INVALID: - case TRM_BOX: - case TRM_OCTAHEDRON: - case TRM_DODECAHEDRON: - case TRM_CYLINDER: - case TRM_CONE: - break; - case TRM_BONE: - case TRM_POLYGON: - case TRM_POLYGONVOLUME: - case TRM_CUSTOM: - for ( i = 0; i < trm.numVerts; i++ ) { - if ( verts[i] != trm.verts[i] ) { - return false; - } - } - break; - } - return true; -} - -/* -============ -idTraceModel::GetPolygonArea -============ -*/ -float idTraceModel::GetPolygonArea( int polyNum ) const { - int i; - idVec3 base, v1, v2, cross; - float total; - const traceModelPoly_t *poly; - - if ( polyNum < 0 || polyNum >= numPolys ) { - return 0.0f; - } - poly = &polys[polyNum]; - total = 0.0f; - base = verts[ edges[ abs(poly->edges[0]) ].v[ INTSIGNBITSET( poly->edges[0] ) ] ]; - for ( i = 0; i < poly->numEdges; i++ ) { - v1 = verts[ edges[ abs(poly->edges[i]) ].v[ INTSIGNBITSET( poly->edges[i] ) ] ] - base; - v2 = verts[ edges[ abs(poly->edges[i]) ].v[ INTSIGNBITNOTSET( poly->edges[i] ) ] ] - base; - cross = v1.Cross( v2 ); - total += cross.Length(); - } - return total * 0.5f; -} - -/* -============ -idTraceModel::GetOrderedSilhouetteEdges -============ -*/ -int idTraceModel::GetOrderedSilhouetteEdges( const int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1], int silEdges[MAX_TRACEMODEL_EDGES] ) const { - int i, j, edgeNum, numSilEdges, nextSilVert; - int unsortedSilEdges[MAX_TRACEMODEL_EDGES]; - - numSilEdges = 0; - for ( i = 1; i <= numEdges; i++ ) { - if ( edgeIsSilEdge[i] ) { - unsortedSilEdges[numSilEdges++] = i; - } - } - - silEdges[0] = unsortedSilEdges[0]; - unsortedSilEdges[0] = -1; - nextSilVert = edges[silEdges[0]].v[0]; - for ( i = 1; i < numSilEdges; i++ ) { - for ( j = 1; j < numSilEdges; j++ ) { - edgeNum = unsortedSilEdges[j]; - if ( edgeNum >= 0 ) { - if ( edges[edgeNum].v[0] == nextSilVert ) { - nextSilVert = edges[edgeNum].v[1]; - silEdges[i] = edgeNum; - break; - } - if ( edges[edgeNum].v[1] == nextSilVert ) { - nextSilVert = edges[edgeNum].v[0]; - silEdges[i] = -edgeNum; - break; - } - } - } - if ( j >= numSilEdges ) { - silEdges[i] = 1; // shouldn't happen - } - unsortedSilEdges[j] = -1; - } - return numSilEdges; -} - -/* -============ -idTraceModel::GetProjectionSilhouetteEdges -============ -*/ -int idTraceModel::GetProjectionSilhouetteEdges( const idVec3 &projectionOrigin, int silEdges[MAX_TRACEMODEL_EDGES] ) const { - int i, j, edgeNum; - int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1]; - const traceModelPoly_t *poly; - idVec3 dir; - - memset( edgeIsSilEdge, 0, sizeof( edgeIsSilEdge ) ); - - for ( i = 0; i < numPolys; i++ ) { - poly = &polys[i]; - edgeNum = poly->edges[0]; - dir = verts[ edges[abs(edgeNum)].v[ INTSIGNBITSET(edgeNum) ] ] - projectionOrigin; - if ( dir * poly->normal < 0.0f ) { - for ( j = 0; j < poly->numEdges; j++ ) { - edgeNum = poly->edges[j]; - edgeIsSilEdge[abs(edgeNum)] ^= 1; - } - } - } - - return GetOrderedSilhouetteEdges( edgeIsSilEdge, silEdges ); -} - -/* -============ -idTraceModel::GetParallelProjectionSilhouetteEdges -============ -*/ -int idTraceModel::GetParallelProjectionSilhouetteEdges( const idVec3 &projectionDir, int silEdges[MAX_TRACEMODEL_EDGES] ) const { - int i, j, edgeNum; - int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1]; - const traceModelPoly_t *poly; - - memset( edgeIsSilEdge, 0, sizeof( edgeIsSilEdge ) ); - - for ( i = 0; i < numPolys; i++ ) { - poly = &polys[i]; - if ( projectionDir * poly->normal < 0.0f ) { - for ( j = 0; j < poly->numEdges; j++ ) { - edgeNum = poly->edges[j]; - edgeIsSilEdge[abs(edgeNum)] ^= 1; - } - } - } - - return GetOrderedSilhouetteEdges( edgeIsSilEdge, silEdges ); -} - - -/* - - credits to Brian Mirtich for his paper "Fast and Accurate Computation of Polyhedral Mass Properties" - -*/ - -typedef struct projectionIntegrals_s { - float P1; - float Pa, Pb; - float Paa, Pab, Pbb; - float Paaa, Paab, Pabb, Pbbb; -} projectionIntegrals_t; - -/* -============ -idTraceModel::ProjectionIntegrals -============ -*/ -void idTraceModel::ProjectionIntegrals( int polyNum, int a, int b, struct projectionIntegrals_s &integrals ) const { - const traceModelPoly_t *poly; - int i, edgeNum; - idVec3 v1, v2; - float a0, a1, da; - float b0, b1, db; - float a0_2, a0_3, a0_4, b0_2, b0_3, b0_4; - float a1_2, a1_3, b1_2, b1_3; - float C1, Ca, Caa, Caaa, Cb, Cbb, Cbbb; - float Cab, Kab, Caab, Kaab, Cabb, Kabb; - - memset(&integrals, 0, sizeof(projectionIntegrals_t)); - poly = &polys[polyNum]; - for ( i = 0; i < poly->numEdges; i++ ) { - edgeNum = poly->edges[i]; - v1 = verts[ edges[ abs(edgeNum) ].v[ edgeNum < 0 ] ]; - v2 = verts[ edges[ abs(edgeNum) ].v[ edgeNum > 0 ] ]; - a0 = v1[a]; - b0 = v1[b]; - a1 = v2[a]; - b1 = v2[b]; - da = a1 - a0; - db = b1 - b0; - a0_2 = a0 * a0; - a0_3 = a0_2 * a0; - a0_4 = a0_3 * a0; - b0_2 = b0 * b0; - b0_3 = b0_2 * b0; - b0_4 = b0_3 * b0; - a1_2 = a1 * a1; - a1_3 = a1_2 * a1; - b1_2 = b1 * b1; - b1_3 = b1_2 * b1; - - C1 = a1 + a0; - Ca = a1 * C1 + a0_2; - Caa = a1 * Ca + a0_3; - Caaa = a1 * Caa + a0_4; - Cb = b1 * (b1 + b0) + b0_2; - Cbb = b1 * Cb + b0_3; - Cbbb = b1 * Cbb + b0_4; - Cab = 3 * a1_2 + 2 * a1 * a0 + a0_2; - Kab = a1_2 + 2 * a1 * a0 + 3 * a0_2; - Caab = a0 * Cab + 4 * a1_3; - Kaab = a1 * Kab + 4 * a0_3; - Cabb = 4 * b1_3 + 3 * b1_2 * b0 + 2 * b1 * b0_2 + b0_3; - Kabb = b1_3 + 2 * b1_2 * b0 + 3 * b1 * b0_2 + 4 * b0_3; - - integrals.P1 += db * C1; - integrals.Pa += db * Ca; - integrals.Paa += db * Caa; - integrals.Paaa += db * Caaa; - integrals.Pb += da * Cb; - integrals.Pbb += da * Cbb; - integrals.Pbbb += da * Cbbb; - integrals.Pab += db * (b1 * Cab + b0 * Kab); - integrals.Paab += db * (b1 * Caab + b0 * Kaab); - integrals.Pabb += da * (a1 * Cabb + a0 * Kabb); - } - - integrals.P1 *= (1.0f / 2.0f); - integrals.Pa *= (1.0f / 6.0f); - integrals.Paa *= (1.0f / 12.0f); - integrals.Paaa *= (1.0f / 20.0f); - integrals.Pb *= (1.0f / -6.0f); - integrals.Pbb *= (1.0f / -12.0f); - integrals.Pbbb *= (1.0f / -20.0f); - integrals.Pab *= (1.0f / 24.0f); - integrals.Paab *= (1.0f / 60.0f); - integrals.Pabb *= (1.0f / -60.0f); -} - -typedef struct polygonIntegrals_s { - float Fa, Fb, Fc; - float Faa, Fbb, Fcc; - float Faaa, Fbbb, Fccc; - float Faab, Fbbc, Fcca; -} polygonIntegrals_t; - -/* -============ -idTraceModel::PolygonIntegrals -============ -*/ -void idTraceModel::PolygonIntegrals( int polyNum, int a, int b, int c, struct polygonIntegrals_s &integrals ) const { - projectionIntegrals_t pi; - idVec3 n; - float w; - float k1, k2, k3, k4; - - ProjectionIntegrals( polyNum, a, b, pi ); - - n = polys[polyNum].normal; - w = -polys[polyNum].dist; - k1 = 1 / n[c]; - k2 = k1 * k1; - k3 = k2 * k1; - k4 = k3 * k1; - - integrals.Fa = k1 * pi.Pa; - integrals.Fb = k1 * pi.Pb; - integrals.Fc = -k2 * (n[a] * pi.Pa + n[b] * pi.Pb + w * pi.P1); - - integrals.Faa = k1 * pi.Paa; - integrals.Fbb = k1 * pi.Pbb; - integrals.Fcc = k3 * (Square(n[a]) * pi.Paa + 2 * n[a] * n[b] * pi.Pab + Square(n[b]) * pi.Pbb - + w * (2 * (n[a] * pi.Pa + n[b] * pi.Pb) + w * pi.P1)); - - integrals.Faaa = k1 * pi.Paaa; - integrals.Fbbb = k1 * pi.Pbbb; - integrals.Fccc = -k4 * (Cube(n[a]) * pi.Paaa + 3 * Square(n[a]) * n[b] * pi.Paab - + 3 * n[a] * Square(n[b]) * pi.Pabb + Cube(n[b]) * pi.Pbbb - + 3 * w * (Square(n[a]) * pi.Paa + 2 * n[a] * n[b] * pi.Pab + Square(n[b]) * pi.Pbb) - + w * w * (3 * (n[a] * pi.Pa + n[b] * pi.Pb) + w * pi.P1)); - - integrals.Faab = k1 * pi.Paab; - integrals.Fbbc = -k2 * (n[a] * pi.Pabb + n[b] * pi.Pbbb + w * pi.Pbb); - integrals.Fcca = k3 * (Square(n[a]) * pi.Paaa + 2 * n[a] * n[b] * pi.Paab + Square(n[b]) * pi.Pabb - + w * (2 * (n[a] * pi.Paa + n[b] * pi.Pab) + w * pi.Pa)); -} - -typedef struct volumeIntegrals_s { - float T0; - idVec3 T1; - idVec3 T2; - idVec3 TP; -} volumeIntegrals_t; - -/* -============ -idTraceModel::VolumeIntegrals -============ -*/ -void idTraceModel::VolumeIntegrals( struct volumeIntegrals_s &integrals ) const { - const traceModelPoly_t *poly; - polygonIntegrals_t pi; - int i, a, b, c; - float nx, ny, nz; - - memset( &integrals, 0, sizeof(volumeIntegrals_t) ); - for ( i = 0; i < numPolys; i++ ) { - poly = &polys[i]; - - nx = idMath::Fabs( poly->normal[0] ); - ny = idMath::Fabs( poly->normal[1] ); - nz = idMath::Fabs( poly->normal[2] ); - if ( nx > ny && nx > nz ) { - c = 0; - } - else { - c = (ny > nz) ? 1 : 2; - } - a = (c + 1) % 3; - b = (a + 1) % 3; - - PolygonIntegrals( i, a, b, c, pi ); - - integrals.T0 += poly->normal[0] * ((a == 0) ? pi.Fa : ((b == 0) ? pi.Fb : pi.Fc)); - - integrals.T1[a] += poly->normal[a] * pi.Faa; - integrals.T1[b] += poly->normal[b] * pi.Fbb; - integrals.T1[c] += poly->normal[c] * pi.Fcc; - integrals.T2[a] += poly->normal[a] * pi.Faaa; - integrals.T2[b] += poly->normal[b] * pi.Fbbb; - integrals.T2[c] += poly->normal[c] * pi.Fccc; - integrals.TP[a] += poly->normal[a] * pi.Faab; - integrals.TP[b] += poly->normal[b] * pi.Fbbc; - integrals.TP[c] += poly->normal[c] * pi.Fcca; - } - - integrals.T1 *= 0.5f; - integrals.T2 *= (1.0f / 3.0f); - integrals.TP *= 0.5f; -} - -/* -============ -idTraceModel::GetMassProperties -============ -*/ -void idTraceModel::GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const { - volumeIntegrals_t integrals; - - // if polygon trace model - if ( type == TRM_POLYGON ) { - idTraceModel trm; - - VolumeFromPolygon( trm, 1.0f ); - trm.GetMassProperties( density, mass, centerOfMass, inertiaTensor ); - return; - } - - VolumeIntegrals( integrals ); - - // if very small or no volume - if ( integrals.T0 < 0.1f ) // grayman #2283 - this was a comparison to 0.0f, which allows very small numbers to wreak havoc - { - mass = 1.0f; - centerOfMass.Zero(); - inertiaTensor.Identity(); - return; - } - - // mass of model - mass = density * integrals.T0; - // center of mass - centerOfMass = integrals.T1 / integrals.T0; - // compute inertia tensor - inertiaTensor[0][0] = density * (integrals.T2[1] + integrals.T2[2]); - inertiaTensor[1][1] = density * (integrals.T2[2] + integrals.T2[0]); - inertiaTensor[2][2] = density * (integrals.T2[0] + integrals.T2[1]); - inertiaTensor[0][1] = inertiaTensor[1][0] = - density * integrals.TP[0]; - inertiaTensor[1][2] = inertiaTensor[2][1] = - density * integrals.TP[1]; - inertiaTensor[2][0] = inertiaTensor[0][2] = - density * integrals.TP[2]; - // translate inertia tensor to center of mass - inertiaTensor[0][0] -= mass * (centerOfMass[1]*centerOfMass[1] + centerOfMass[2]*centerOfMass[2]); - inertiaTensor[1][1] -= mass * (centerOfMass[2]*centerOfMass[2] + centerOfMass[0]*centerOfMass[0]); - inertiaTensor[2][2] -= mass * (centerOfMass[0]*centerOfMass[0] + centerOfMass[1]*centerOfMass[1]); - inertiaTensor[0][1] = inertiaTensor[1][0] += mass * centerOfMass[0] * centerOfMass[1]; - inertiaTensor[1][2] = inertiaTensor[2][1] += mass * centerOfMass[1] * centerOfMass[2]; - inertiaTensor[2][0] = inertiaTensor[0][2] += mass * centerOfMass[2] * centerOfMass[0]; -} diff --git a/idlib/geometry/tracemodel.h b/idlib/geometry/tracemodel.h deleted file mode 100644 index a794dc47f..000000000 --- a/idlib/geometry/tracemodel.h +++ /dev/null @@ -1,176 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __TRACEMODEL_H__ -#define __TRACEMODEL_H__ - -/* -=============================================================================== - - A trace model is an arbitrary polygonal model which is used by the - collision detection system to find collisions, contacts or the contents - of a volume. For collision detection speed reasons the number of vertices - and edges are limited. The trace model can have any shape. However convex - models are usually preferred. - -=============================================================================== -*/ - -class idVec3; -class idMat3; -class idBounds; - -// trace model type -typedef enum { - TRM_INVALID, // invalid trm - TRM_BOX, // box - TRM_OCTAHEDRON, // octahedron - TRM_DODECAHEDRON, // dodecahedron - TRM_CYLINDER, // cylinder approximation - TRM_CONE, // cone approximation - TRM_BONE, // two tetrahedrons attached to each other - TRM_POLYGON, // arbitrary convex polygon - TRM_POLYGONVOLUME, // volume for arbitrary convex polygon - TRM_CUSTOM // loaded from map model or ASE/LWO -} traceModel_t; - -// these are bit cache limits -#define MAX_TRACEMODEL_VERTS 32 -#define MAX_TRACEMODEL_EDGES 32 -#define MAX_TRACEMODEL_POLYS 16 -#define MAX_TRACEMODEL_POLYEDGES 16 - -typedef idVec3 traceModelVert_t; - -typedef struct { - int v[2]; - idVec3 normal; -} traceModelEdge_t; - -typedef struct { - idVec3 normal; - float dist; - idBounds bounds; - int numEdges; - int edges[MAX_TRACEMODEL_POLYEDGES]; -} traceModelPoly_t; - -class idTraceModel { - -public: - traceModel_t type; - int numVerts; - traceModelVert_t verts[MAX_TRACEMODEL_VERTS]; - int numEdges; - traceModelEdge_t edges[MAX_TRACEMODEL_EDGES+1]; - int numPolys; - traceModelPoly_t polys[MAX_TRACEMODEL_POLYS]; - idVec3 offset; // offset to center of model - idBounds bounds; // bounds of model - bool isConvex; // true when model is convex - -public: - idTraceModel( void ); - // axial bounding box - idTraceModel( const idBounds &boxBounds ); - // cylinder approximation - idTraceModel( const idBounds &cylBounds, const int numSides ); - // bone - idTraceModel( const float length, const float width ); - - // axial box - void SetupBox( const idBounds &boxBounds ); - void SetupBox( const float size ); - // octahedron - void SetupOctahedron( const idBounds &octBounds ); - void SetupOctahedron( const float size ); - // dodecahedron - void SetupDodecahedron( const idBounds &dodBounds ); - void SetupDodecahedron( const float size ); - // cylinder approximation - void SetupCylinder( const idBounds &cylBounds, const int numSides ); - void SetupCylinder( const float height, const float width, const int numSides ); - // cone approximation - void SetupCone( const idBounds &coneBounds, const int numSides ); - void SetupCone( const float height, const float width, const int numSides ); - // two tetrahedrons attached to each other - void SetupBone( const float length, const float width ); - // arbitrary convex polygon - void SetupPolygon( const idVec3 *v, const int count ); - void SetupPolygon( const idWinding &w ); - // generate edge normals - int GenerateEdgeNormals( void ); - // translate the trm - void Translate( const idVec3 &translation ); - // rotate the trm - // rotate the trm or apply non-singular linear transform - void Rotate( const idMat3 &rotation, bool isRotationOrthogonal = true ); - // scale the trm - void Scale( const idVec3 &scale ); - // shrink the model m units on all sides - void Shrink( const float m ); - // compare - bool Compare( const idTraceModel &trm ) const; - bool operator==( const idTraceModel &trm ) const; - bool operator!=( const idTraceModel &trm ) const; - // get the area of one of the polygons - float GetPolygonArea( int polyNum ) const; - // get the silhouette edges - int GetProjectionSilhouetteEdges( const idVec3 &projectionOrigin, int silEdges[MAX_TRACEMODEL_EDGES] ) const; - int GetParallelProjectionSilhouetteEdges( const idVec3 &projectionDir, int silEdges[MAX_TRACEMODEL_EDGES] ) const; - // calculate mass properties assuming an uniform density - void GetMassProperties( const float density, float &mass, idVec3 ¢erOfMass, idMat3 &inertiaTensor ) const; - -private: - void InitBox( void ); - void InitOctahedron( void ); - void InitDodecahedron( void ); - void InitBone( void ); - - void ProjectionIntegrals( int polyNum, int a, int b, struct projectionIntegrals_s &integrals ) const; - void PolygonIntegrals( int polyNum, int a, int b, int c, struct polygonIntegrals_s &integrals ) const; - void VolumeIntegrals( struct volumeIntegrals_s &integrals ) const; - void VolumeFromPolygon( idTraceModel &trm, float thickness ) const; - int GetOrderedSilhouetteEdges( const int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1], int silEdges[MAX_TRACEMODEL_EDGES] ) const; -}; - - -ID_INLINE idTraceModel::idTraceModel( void ) { - type = TRM_INVALID; - numVerts = numEdges = numPolys = 0; - bounds.Zero(); -} - -ID_INLINE idTraceModel::idTraceModel( const idBounds &boxBounds ) { - InitBox(); - SetupBox( boxBounds ); -} - -ID_INLINE idTraceModel::idTraceModel( const idBounds &cylBounds, const int numSides ) { - SetupCylinder( cylBounds, numSides ); -} - -ID_INLINE idTraceModel::idTraceModel( const float length, const float width ) { - InitBone(); - SetupBone( length, width ); -} - -ID_INLINE bool idTraceModel::operator==( const idTraceModel &trm ) const { - return Compare( trm ); -} - -ID_INLINE bool idTraceModel::operator!=( const idTraceModel &trm ) const { - return !Compare( trm ); -} - -#endif /* !__TRACEMODEL_H__ */ - diff --git a/idlib/geometry/winding.cpp b/idlib/geometry/winding.cpp deleted file mode 100644 index f51aee5af..000000000 --- a/idlib/geometry/winding.cpp +++ /dev/null @@ -1,1586 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -//=============================================================== -// -// idWinding -// -//=============================================================== - -/* -============= -idWinding::ReAllocate -============= -*/ -bool idWinding::ReAllocate( int n, bool keep ) { - idVec5 *oldP; - - oldP = p; - n = (n+3) & ~3; // align up to multiple of four - p = new idVec5[n]; - if ( oldP ) { - if ( keep ) { - memcpy( p, oldP, numPoints * sizeof(p[0]) ); - } - delete[] oldP; - } - allocedSize = n; - - return true; -} - -/* -============= -idWinding::BaseForPlane -============= -*/ -void idWinding::BaseForPlane( const idVec3 &normal, const float dist ) { - idVec3 org, vright, vup; - - org = normal * dist; - - normal.NormalVectors( vup, vright ); - vup *= MAX_WORLD_SIZE; - vright *= MAX_WORLD_SIZE; - - EnsureAlloced( 4 ); - numPoints = 4; - p[0].ToVec3() = org - vright + vup; - p[0].s = p[0].t = 0.0f; - p[1].ToVec3() = org + vright + vup; - p[1].s = p[1].t = 0.0f; - p[2].ToVec3() = org + vright - vup; - p[2].s = p[2].t = 0.0f; - p[3].ToVec3() = org - vright - vup; - p[3].s = p[3].t = 0.0f; -} - -/* -============= -idWinding::Split -============= -*/ -int idWinding::Split( const idPlane &plane, const float epsilon, idWinding **front, idWinding **back ) const { - float * dists; - byte * sides; - int counts[3]; - float dot; - int i, j; - const idVec5 * p1, *p2; - idVec5 mid; - idWinding * f, *b; - int maxpts; - - assert( this ); - - dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); - sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); - - counts[0] = counts[1] = counts[2] = 0; - - // determine sides for each point - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.Distance( p[i].ToVec3() ); - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - dists[i] = dists[0]; - - *front = *back = NULL; - - // if coplanar, put on the front side if the normals match - if ( !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - idPlane windingPlane; - - GetPlane( windingPlane ); - if ( windingPlane.Normal() * plane.Normal() > 0.0f ) { - *front = Copy(); - return SIDE_FRONT; - } else { - *back = Copy(); - return SIDE_BACK; - } - } - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - *back = Copy(); - return SIDE_BACK; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - *front = Copy(); - return SIDE_FRONT; - } - - maxpts = numPoints+4; // cant use counts[0]+2 because of fp grouping errors - - *front = f = new idWinding(maxpts); - *back = b = new idWinding(maxpts); - - for (i = 0; i < numPoints; i++) { - p1 = &p[i]; - - if ( sides[i] == SIDE_ON ) { - f->p[f->numPoints] = *p1; - f->numPoints++; - b->p[b->numPoints] = *p1; - b->numPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - f->p[f->numPoints] = *p1; - f->numPoints++; - } - - if ( sides[i] == SIDE_BACK ) { - b->p[b->numPoints] = *p1; - b->numPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - // generate a split point - p2 = &p[(i+1)%numPoints]; - - // always calculate the split going from the same side - // or minor epsilon issues can happen - if ( sides[i] == SIDE_FRONT ) { - dot = dists[i] / ( dists[i] - dists[i+1] ); - for ( j = 0; j < 3; j++ ) { - // avoid round off error when possible - if ( plane.Normal()[j] == 1.0f ) { - mid[j] = plane.Dist(); - } else if ( plane.Normal()[j] == -1.0f ) { - mid[j] = -plane.Dist(); - } else { - mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); - } - } - mid.s = p1->s + dot * ( p2->s - p1->s ); - mid.t = p1->t + dot * ( p2->t - p1->t ); - } else { - dot = dists[i+1] / ( dists[i+1] - dists[i] ); - for ( j = 0; j < 3; j++ ) { - // avoid round off error when possible - if ( plane.Normal()[j] == 1.0f ) { - mid[j] = plane.Dist(); - } else if ( plane.Normal()[j] == -1.0f ) { - mid[j] = -plane.Dist(); - } else { - mid[j] = (*p2)[j] + dot * ( (*p1)[j] - (*p2)[j] ); - } - } - mid.s = p2->s + dot * ( p1->s - p2->s ); - mid.t = p2->t + dot * ( p1->t - p2->t ); - } - - f->p[f->numPoints] = mid; - f->numPoints++; - b->p[b->numPoints] = mid; - b->numPoints++; - } - - if ( f->numPoints > maxpts || b->numPoints > maxpts ) { - idLib::common->FatalError( "idWinding::Split: points exceeded estimate." ); - } - - return SIDE_CROSS; -} - -/* -============= -idWinding::Clip -============= -*/ -idWinding *idWinding::Clip( const idPlane &plane, const float epsilon, const bool keepOn ) { - float * dists; - byte * sides; - idVec5 * newPoints; - int newNumPoints; - int counts[3]; - float dot; - int i, j; - idVec5 * p1, *p2; - idVec5 mid; - int maxpts; - - assert( this ); - - dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); - sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); - - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - // determine sides for each point - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.Distance( p[i].ToVec3() ); - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - dists[i] = dists[0]; - - // if the winding is on the plane and we should keep it - if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - return this; - } - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - delete this; - return NULL; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - return this; - } - - maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors - - newPoints = (idVec5 *) _alloca16( maxpts * sizeof( idVec5 ) ); - newNumPoints = 0; - - for ( i = 0; i < numPoints; i++ ) { - p1 = &p[i]; - - if ( newNumPoints+1 > maxpts ) { - return this; // can't split -- fall back to original - } - - if ( sides[i] == SIDE_ON ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - if ( newNumPoints+1 > maxpts ) { - return this; // can't split -- fall back to original - } - - // generate a split point - p2 = &p[(i+1)%numPoints]; - - dot = dists[i] / (dists[i] - dists[i+1]); - for ( j = 0; j < 3; j++ ) { - // avoid round off error when possible - if ( plane.Normal()[j] == 1.0f ) { - mid[j] = plane.Dist(); - } else if ( plane.Normal()[j] == -1.0f ) { - mid[j] = -plane.Dist(); - } else { - mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); - } - } - mid.s = p1->s + dot * ( p2->s - p1->s ); - mid.t = p1->t + dot * ( p2->t - p1->t ); - - newPoints[newNumPoints] = mid; - newNumPoints++; - } - - if ( !EnsureAlloced( newNumPoints, false ) ) { - return this; - } - - numPoints = newNumPoints; - memcpy( p, newPoints, newNumPoints * sizeof(idVec5) ); - - return this; -} - -/* -============= -idWinding::ClipInPlace -============= -*/ -bool idWinding::ClipInPlace( const idPlane &plane, const float epsilon, const bool keepOn ) { - float* dists; - byte * sides; - idVec5 * newPoints; - int newNumPoints; - int counts[3]; - float dot; - int i, j; - idVec5 * p1, *p2; - idVec5 mid; - int maxpts; - - assert( this ); - - dists = (float *) _alloca( (numPoints+4) * sizeof( float ) ); - sides = (byte *) _alloca( (numPoints+4) * sizeof( byte ) ); - - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - // determine sides for each point - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.Distance( p[i].ToVec3() ); - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - dists[i] = dists[0]; - - // if the winding is on the plane and we should keep it - if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - return true; - } - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - numPoints = 0; - return false; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - return true; - } - - maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors - - newPoints = (idVec5 *) _alloca16( maxpts * sizeof( idVec5 ) ); - newNumPoints = 0; - - for ( i = 0; i < numPoints; i++ ) { - p1 = &p[i]; - - if ( newNumPoints+1 > maxpts ) { - return true; // can't split -- fall back to original - } - - if ( sides[i] == SIDE_ON ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - if ( newNumPoints+1 > maxpts ) { - return true; // can't split -- fall back to original - } - - // generate a split point - p2 = &p[(i+1)%numPoints]; - - dot = dists[i] / (dists[i] - dists[i+1]); - for ( j = 0; j < 3; j++ ) { - // avoid round off error when possible - if ( plane.Normal()[j] == 1.0f ) { - mid[j] = plane.Dist(); - } else if ( plane.Normal()[j] == -1.0f ) { - mid[j] = -plane.Dist(); - } else { - mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); - } - } - mid.s = p1->s + dot * ( p2->s - p1->s ); - mid.t = p1->t + dot * ( p2->t - p1->t ); - - newPoints[newNumPoints] = mid; - newNumPoints++; - } - - if ( !EnsureAlloced( newNumPoints, false ) ) { - return true; - } - - numPoints = newNumPoints; - memcpy( p, newPoints, newNumPoints * sizeof(idVec5) ); - - return true; -} - -/* -============= -idWinding::Copy -============= -*/ -idWinding *idWinding::Copy( void ) const { - idWinding *w; - - w = new idWinding( numPoints ); - w->numPoints = numPoints; - memcpy( w->p, p, numPoints * sizeof(p[0]) ); - return w; -} - -/* -============= -idWinding::Reverse -============= -*/ -idWinding *idWinding::Reverse( void ) const { - idWinding *w; - int i; - - w = new idWinding( numPoints ); - w->numPoints = numPoints; - for ( i = 0; i < numPoints; i++ ) { - w->p[ numPoints - i - 1 ] = p[i]; - } - return w; -} - -/* -============= -idWinding::ReverseSelf -============= -*/ -void idWinding::ReverseSelf( void ) { - idVec5 v; - int i; - - for ( i = 0; i < (numPoints>>1); i++ ) { - v = p[i]; - p[i] = p[numPoints - i - 1]; - p[numPoints - i - 1] = v; - } -} - -/* -============= -idWinding::Check -============= -*/ -bool idWinding::Check( bool print ) const { - int i, j; - float d, edgedist; - idVec3 dir, edgenormal; - float area; - idPlane plane; - - if ( numPoints < 3 ) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: only %i points.", numPoints ); - } - return false; - } - - area = GetArea(); - if ( area < 1.0f ) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: tiny area: %f", area ); - } - return false; - } - - GetPlane( plane ); - - for ( i = 0; i < numPoints; i++ ) { - const idVec3 &p1 = p[i].ToVec3(); - - // check if the winding is huge - for ( j = 0; j < 3; j++ ) { - if ( p1[j] >= MAX_WORLD_COORD || p1[j] <= MIN_WORLD_COORD ) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: point %d outside world %c-axis: %f", i, 'X'+j, p1[j] ); - } - return false; - } - } - - j = i + 1 == numPoints ? 0 : i + 1; - - // check if the point is on the face plane - d = p1 * plane.Normal() + plane[3]; - if ( d < -ON_EPSILON || d > ON_EPSILON ) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: point %d off plane.", i ); - } - return false; - } - - // check if the edge isn't degenerate - const idVec3 &p2 = p[j].ToVec3(); - dir = p2 - p1; - - if ( dir.Length() < ON_EPSILON) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: edge %d is degenerate.", i ); - } - return false; - } - - // check if the winding is convex - edgenormal = plane.Normal().Cross( dir ); - edgenormal.Normalize(); - edgedist = p1 * edgenormal; - edgedist += ON_EPSILON; - - // all other points must be on front side - for ( j = 0; j < numPoints; j++ ) { - if ( j == i ) { - continue; - } - d = p[j].ToVec3() * edgenormal; - if ( d > edgedist ) { - if ( print ) { - idLib::common->Printf( "idWinding::Check: non-convex." ); - } - return false; - } - } - } - return true; -} - -/* -============= -idWinding::GetArea -============= -*/ -float idWinding::GetArea( void ) const { - int i; - idVec3 d1, d2, cross; - float total; - - total = 0.0f; - for ( i = 2; i < numPoints; i++ ) { - d1 = p[i-1].ToVec3() - p[0].ToVec3(); - d2 = p[i].ToVec3() - p[0].ToVec3(); - cross = d1.Cross( d2 ); - total += cross.Length(); - } - return total * 0.5f; -} - -/* -============= -idWinding::GetRadius -============= -*/ -float idWinding::GetRadius( const idVec3 ¢er ) const { - int i; - float radius, r; - idVec3 dir; - - radius = 0.0f; - for ( i = 0; i < numPoints; i++ ) { - dir = p[i].ToVec3() - center; - r = dir * dir; - if ( r > radius ) { - radius = r; - } - } - return idMath::Sqrt( radius ); -} - -/* -============= -idWinding::GetCenter -============= -*/ -idVec3 idWinding::GetCenter( void ) const { - int i; - idVec3 center; - - center.Zero(); - for ( i = 0; i < numPoints; i++ ) { - center += p[i].ToVec3(); - } - center *= ( 1.0f / numPoints ); - return center; -} - -/* -============= -idWinding::GetPlane -============= -*/ -void idWinding::GetPlane( idVec3 &normal, float &dist ) const { - idVec3 v1, v2, center; - - if ( numPoints < 3 ) { - normal.Zero(); - dist = 0.0f; - return; - } - - center = GetCenter(); - v1 = p[0].ToVec3() - center; - v2 = p[1].ToVec3() - center; - normal = v2.Cross( v1 ); - normal.Normalize(); - dist = p[0].ToVec3() * normal; -} - -/* -============= -idWinding::GetPlane -============= -*/ -void idWinding::GetPlane( idPlane &plane ) const { - idVec3 v1, v2; - idVec3 center; - - if ( numPoints < 3 ) { - plane.Zero(); - return; - } - - center = GetCenter(); - v1 = p[0].ToVec3() - center; - v2 = p[1].ToVec3() - center; - plane.SetNormal( v2.Cross( v1 ) ); - plane.Normalize(); - plane.FitThroughPoint( p[0].ToVec3() ); -} - -/* -============= -idWinding::GetBounds -============= -*/ -void idWinding::GetBounds( idBounds &bounds ) const { - int i; - - if ( !numPoints ) { - bounds.Clear(); - return; - } - - bounds[0] = bounds[1] = p[0].ToVec3(); - for ( i = 1; i < numPoints; i++ ) { - if ( p[i].x < bounds[0].x ) { - bounds[0].x = p[i].x; - } else if ( p[i].x > bounds[1].x ) { - bounds[1].x = p[i].x; - } - if ( p[i].y < bounds[0].y ) { - bounds[0].y = p[i].y; - } else if ( p[i].y > bounds[1].y ) { - bounds[1].y = p[i].y; - } - if ( p[i].z < bounds[0].z ) { - bounds[0].z = p[i].z; - } else if ( p[i].z > bounds[1].z ) { - bounds[1].z = p[i].z; - } - } -} - -/* -============= -idWinding::RemoveEqualPoints -============= -*/ -void idWinding::RemoveEqualPoints( const float epsilon ) { - int i, j; - - for ( i = 0; i < numPoints; i++ ) { - if ( (p[i].ToVec3() - p[(i+numPoints-1)%numPoints].ToVec3()).LengthSqr() >= Square( epsilon ) ) { - continue; - } - numPoints--; - for ( j = i; j < numPoints; j++ ) { - p[j] = p[j+1]; - } - i--; - } -} - -/* -============= -idWinding::RemoveColinearPoints -============= -*/ -void idWinding::RemoveColinearPoints( const idVec3 &normal, const float epsilon ) { - int i, j; - idVec3 edgeNormal; - float dist; - - if ( numPoints <= 3 ) { - return; - } - - for ( i = 0; i < numPoints; i++ ) { - - // create plane through edge orthogonal to winding plane - edgeNormal = (p[i].ToVec3() - p[(i+numPoints-1)%numPoints].ToVec3()).Cross( normal ); - edgeNormal.Normalize(); - dist = edgeNormal * p[i].ToVec3(); - - if ( idMath::Fabs( edgeNormal * p[(i+1)%numPoints].ToVec3() - dist ) > epsilon ) { - continue; - } - - numPoints--; - for ( j = i; j < numPoints; j++ ) { - p[j] = p[j+1]; - } - i--; - } -} - -/* -============= -idWinding::AddToConvexHull - - Adds the given winding to the convex hull. - Assumes the current winding already is a convex hull with three or more points. -============= -*/ -void idWinding::AddToConvexHull( const idWinding *winding, const idVec3 &normal, const float epsilon ) { - int i, j, k; - idVec3 dir; - float d; - int maxPts; - idVec3 * hullDirs; - bool * hullSide; - bool outside; - int numNewHullPoints; - idVec5 * newHullPoints; - - if ( !winding ) { - return; - } - - maxPts = this->numPoints + winding->numPoints; - - if ( !this->EnsureAlloced( maxPts, true ) ) { - return; - } - - newHullPoints = (idVec5 *) _alloca( maxPts * sizeof( idVec5 ) ); - hullDirs = (idVec3 *) _alloca( maxPts * sizeof( idVec3 ) ); - hullSide = (bool *) _alloca( maxPts * sizeof( bool ) ); - - for ( i = 0; i < winding->numPoints; i++ ) { - const idVec5 &p1 = winding->p[i]; - - // calculate hull edge vectors - for ( j = 0; j < this->numPoints; j++ ) { - dir = this->p[ (j + 1) % this->numPoints ].ToVec3() - this->p[ j ].ToVec3(); - dir.Normalize(); - hullDirs[j] = normal.Cross( dir ); - } - - // calculate side for each hull edge - outside = false; - for ( j = 0; j < this->numPoints; j++ ) { - dir = p1.ToVec3() - this->p[j].ToVec3(); - d = dir * hullDirs[j]; - if ( d >= epsilon ) { - outside = true; - } - if ( d >= -epsilon ) { - hullSide[j] = true; - } else { - hullSide[j] = false; - } - } - - // if the point is effectively inside, do nothing - if ( !outside ) { - continue; - } - - // find the back side to front side transition - for ( j = 0; j < this->numPoints; j++ ) { - if ( !hullSide[ j ] && hullSide[ (j + 1) % this->numPoints ] ) { - break; - } - } - if ( j >= this->numPoints ) { - continue; - } - - // insert the point here - newHullPoints[0] = p1; - numNewHullPoints = 1; - - // copy over all points that aren't double fronts - j = (j+1) % this->numPoints; - for ( k = 0; k < this->numPoints; k++ ) { - if ( hullSide[ (j+k) % this->numPoints ] && hullSide[ (j+k+1) % this->numPoints ] ) { - continue; - } - newHullPoints[numNewHullPoints] = this->p[ (j+k+1) % this->numPoints ]; - numNewHullPoints++; - } - - this->numPoints = numNewHullPoints; - memcpy( this->p, newHullPoints, numNewHullPoints * sizeof(idVec5) ); - } -} - -/* -============= -idWinding::AddToConvexHull - - Add a point to the convex hull. - The current winding must be convex but may be degenerate and can have less than three points. -============= -*/ -void idWinding::AddToConvexHull( const idVec3 &point, const idVec3 &normal, const float epsilon ) { - int j, k, numHullPoints; - idVec3 dir; - float d; - idVec3 * hullDirs; - bool * hullSide; - idVec5 * hullPoints; - bool outside; - - switch( numPoints ) { - case 0: { - p[0] = point; - numPoints++; - return; - } - case 1: { - // don't add the same point second - if ( p[0].ToVec3().Compare( point, epsilon ) ) { - return; - } - p[1].ToVec3() = point; - numPoints++; - return; - } - case 2: { - // don't add a point if it already exists - if ( p[0].ToVec3().Compare( point, epsilon ) || p[1].ToVec3().Compare( point, epsilon ) ) { - return; - } - // if only two points make sure we have the right ordering according to the normal - dir = point - p[0].ToVec3(); - dir = dir.Cross( p[1].ToVec3() - p[0].ToVec3() ); - if ( dir[0] == 0.0f && dir[1] == 0.0f && dir[2] == 0.0f ) { - // points don't make a plane - return; - } - if ( dir * normal > 0.0f ) { - p[2].ToVec3() = point; - } - else { - p[2] = p[1]; - p[1].ToVec3() = point; - } - numPoints++; - return; - } - } - - hullDirs = (idVec3 *) _alloca( numPoints * sizeof( idVec3 ) ); - hullSide = (bool *) _alloca( numPoints * sizeof( bool ) ); - - // calculate hull edge vectors - for ( j = 0; j < numPoints; j++ ) { - dir = p[(j + 1) % numPoints].ToVec3() - p[j].ToVec3(); - hullDirs[j] = normal.Cross( dir ); - } - - // calculate side for each hull edge - outside = false; - for ( j = 0; j < numPoints; j++ ) { - dir = point - p[j].ToVec3(); - d = dir * hullDirs[j]; - if ( d >= epsilon ) { - outside = true; - } - if ( d >= -epsilon ) { - hullSide[j] = true; - } else { - hullSide[j] = false; - } - } - - // if the point is effectively inside, do nothing - if ( !outside ) { - return; - } - - // find the back side to front side transition - for ( j = 0; j < numPoints; j++ ) { - if ( !hullSide[ j ] && hullSide[ (j + 1) % numPoints ] ) { - break; - } - } - if ( j >= numPoints ) { - return; - } - - hullPoints = (idVec5 *) _alloca( (numPoints+1) * sizeof( idVec5 ) ); - - // insert the point here - hullPoints[0] = point; - numHullPoints = 1; - - // copy over all points that aren't double fronts - j = (j+1) % numPoints; - for ( k = 0; k < numPoints; k++ ) { - if ( hullSide[ (j+k) % numPoints ] && hullSide[ (j+k+1) % numPoints ] ) { - continue; - } - hullPoints[numHullPoints] = p[ (j+k+1) % numPoints ]; - numHullPoints++; - } - - if ( !EnsureAlloced( numHullPoints, false ) ) { - return; - } - numPoints = numHullPoints; - memcpy( p, hullPoints, numHullPoints * sizeof(idVec5) ); -} - -/* -============= -idWinding::TryMerge -============= -*/ -#define CONTINUOUS_EPSILON 0.005f - -idWinding *idWinding::TryMerge( const idWinding &w, const idVec3 &planenormal, int keep ) const { - idVec3 *p1, *p2, *p3, *p4, *back; - idWinding *newf; - const idWinding *f1, *f2; - int i, j, k, l; - idVec3 normal, delta; - float dot; - bool keep1, keep2; - - f1 = this; - f2 = &w; - // - // find a idLib::common edge - // - p1 = p2 = NULL; // stop compiler warning - j = 0; - - for ( i = 0; i < f1->numPoints; i++ ) { - p1 = &f1->p[i].ToVec3(); - p2 = &f1->p[(i+1) % f1->numPoints].ToVec3(); - for ( j = 0; j < f2->numPoints; j++ ) { - p3 = &f2->p[j].ToVec3(); - p4 = &f2->p[(j+1) % f2->numPoints].ToVec3(); - for (k = 0; k < 3; k++ ) { - if ( idMath::Fabs((*p1)[k] - (*p4)[k]) > 0.1f ) { - break; - } - if ( idMath::Fabs((*p2)[k] - (*p3)[k]) > 0.1f ) { - break; - } - } - if ( k == 3 ) { - break; - } - } - if ( j < f2->numPoints ) { - break; - } - } - - if ( i == f1->numPoints ) { - return NULL; // no matching edges - } - - // - // check slope of connected lines - // if the slopes are colinear, the point can be removed - // - back = &f1->p[(i+f1->numPoints-1)%f1->numPoints].ToVec3(); - delta = (*p1) - (*back); - normal = planenormal.Cross(delta); - normal.Normalize(); - - back = &f2->p[(j+2)%f2->numPoints].ToVec3(); - delta = (*back) - (*p1); - dot = delta * normal; - if ( dot > CONTINUOUS_EPSILON ) { - return NULL; // not a convex polygon - } - - keep1 = (bool)(dot < -CONTINUOUS_EPSILON); - - back = &f1->p[(i+2)%f1->numPoints].ToVec3(); - delta = (*back) - (*p2); - normal = planenormal.Cross( delta ); - normal.Normalize(); - - back = &f2->p[(j+f2->numPoints-1)%f2->numPoints].ToVec3(); - delta = (*back) - (*p2); - dot = delta * normal; - if ( dot > CONTINUOUS_EPSILON ) { - return NULL; // not a convex polygon - } - - keep2 = (bool)(dot < -CONTINUOUS_EPSILON); - - // - // build the new polygon - // - newf = new idWinding( f1->numPoints + f2->numPoints ); - - // copy first polygon - for ( k = (i+1) % f1->numPoints; k != i; k = (k+1) % f1->numPoints ) { - if ( !keep && k == (i+1) % f1->numPoints && !keep2 ) { - continue; - } - - newf->p[newf->numPoints] = f1->p[k]; - newf->numPoints++; - } - - // copy second polygon - for ( l = (j+1) % f2->numPoints; l != j; l = (l+1) % f2->numPoints ) { - if ( !keep && l == (j+1) % f2->numPoints && !keep1 ) { - continue; - } - newf->p[newf->numPoints] = f2->p[l]; - newf->numPoints++; - } - - return newf; -} - -/* -============= -idWinding::RemovePoint -============= -*/ -void idWinding::RemovePoint( int point ) { - if ( point < 0 || point >= numPoints ) { - idLib::common->FatalError( "idWinding::removePoint: point out of range" ); - } - if ( point < numPoints - 1) { - memmove(&p[point], &p[point+1], (numPoints - point - 1) * sizeof(p[0]) ); - } - numPoints--; -} - -/* -============= -idWinding::InsertPoint -============= -*/ -void idWinding::InsertPoint( const idVec3 &point, int spot ) { - int i; - - if ( spot > numPoints ) { - idLib::common->FatalError( "idWinding::insertPoint: spot > numPoints" ); - } - - if ( spot < 0 ) { - idLib::common->FatalError( "idWinding::insertPoint: spot < 0" ); - } - - EnsureAlloced( numPoints+1, true ); - for ( i = numPoints; i > spot; i-- ) { - p[i] = p[i-1]; - } - p[spot] = point; - numPoints++; -} - -/* -============= -idWinding::InsertPointIfOnEdge -============= -*/ -bool idWinding::InsertPointIfOnEdge( const idVec3 &point, const idPlane &plane, const float epsilon ) { - int i; - float dist, dot; - idVec3 normal; - - // point may not be too far from the winding plane - if ( idMath::Fabs( plane.Distance( point ) ) > epsilon ) { - return false; - } - - for ( i = 0; i < numPoints; i++ ) { - - // create plane through edge orthogonal to winding plane - normal = (p[(i+1)%numPoints].ToVec3() - p[i].ToVec3()).Cross( plane.Normal() ); - normal.Normalize(); - dist = normal * p[i].ToVec3(); - - if ( idMath::Fabs( normal * point - dist ) > epsilon ) { - continue; - } - - normal = plane.Normal().Cross( normal ); - dot = normal * point; - - dist = dot - normal * p[i].ToVec3(); - - if ( dist < epsilon ) { - // if the winding already has the point - if ( dist > -epsilon ) { - return false; - } - continue; - } - - dist = dot - normal * p[(i+1)%numPoints].ToVec3(); - - if ( dist > -epsilon ) { - // if the winding already has the point - if ( dist < epsilon ) { - return false; - } - continue; - } - - InsertPoint( point, i+1 ); - return true; - } - return false; -} - -/* -============= -idWinding::IsTiny -============= -*/ -#define EDGE_LENGTH 0.2f - -bool idWinding::IsTiny( void ) const { - int i; - float len; - idVec3 delta; - int edges; - - edges = 0; - for ( i = 0; i < numPoints; i++ ) { - delta = p[(i+1)%numPoints].ToVec3() - p[i].ToVec3(); - len = delta.Length(); - if ( len > EDGE_LENGTH ) { - if ( ++edges == 3 ) { - return false; - } - } - } - return true; -} - -/* -============= -idWinding::IsHuge -============= -*/ -bool idWinding::IsHuge( void ) const { - int i, j; - - for ( i = 0; i < numPoints; i++ ) { - for ( j = 0; j < 3; j++ ) { - if ( p[i][j] <= MIN_WORLD_COORD || p[i][j] >= MAX_WORLD_COORD ) { - return true; - } - } - } - return false; -} - -/* -============= -idWinding::Print -============= -*/ -void idWinding::Print( void ) const { - int i; - - for ( i = 0; i < numPoints; i++ ) { - idLib::common->Printf( "(%5.1f, %5.1f, %5.1f)\n", p[i][0], p[i][1], p[i][2] ); - } -} - -/* -============= -idWinding::PlaneDistance -============= -*/ -float idWinding::PlaneDistance( const idPlane &plane ) const { - int i; - float d, min, max; - - min = idMath::INFINITY; - max = -min; - for ( i = 0; i < numPoints; i++ ) { - d = plane.Distance( p[i].ToVec3() ); - if ( d < min ) { - min = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - if ( d > max ) { - max = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - } - if ( FLOATSIGNBITNOTSET( min ) ) { - return min; - } - if ( FLOATSIGNBITSET( max ) ) { - return max; - } - return 0.0f; -} - -/* -============= -idWinding::PlaneSide -============= -*/ -int idWinding::PlaneSide( const idPlane &plane, const float epsilon ) const { - bool front, back; - int i; - float d; - - front = false; - back = false; - for ( i = 0; i < numPoints; i++ ) { - d = plane.Distance( p[i].ToVec3() ); - if ( d < -epsilon ) { - if ( front ) { - return SIDE_CROSS; - } - back = true; - continue; - } - else if ( d > epsilon ) { - if ( back ) { - return SIDE_CROSS; - } - front = true; - continue; - } - } - - if ( back ) { - return SIDE_BACK; - } - if ( front ) { - return SIDE_FRONT; - } - return SIDE_ON; -} - -/* -============= -idWinding::PlanesConcave -============= -*/ -#define WCONVEX_EPSILON 0.2f - -bool idWinding::PlanesConcave( const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2 ) const { - int i; - - // check if one of the points of winding 1 is at the back of the plane of winding 2 - for ( i = 0; i < numPoints; i++ ) { - if ( normal2 * p[i].ToVec3() - dist2 > WCONVEX_EPSILON ) { - return true; - } - } - // check if one of the points of winding 2 is at the back of the plane of winding 1 - for ( i = 0; i < w2.numPoints; i++ ) { - if ( normal1 * w2.p[i].ToVec3() - dist1 > WCONVEX_EPSILON ) { - return true; - } - } - - return false; -} - -/* -============= -idWinding::PointInside -============= -*/ -bool idWinding::PointInside( const idVec3 &normal, const idVec3 &point, const float epsilon ) const { - int i; - idVec3 dir, n, pointvec; - - for ( i = 0; i < numPoints; i++ ) { - dir = p[(i+1) % numPoints].ToVec3() - p[i].ToVec3(); - pointvec = point - p[i].ToVec3(); - - n = dir.Cross( normal ); - - if ( pointvec * n < -epsilon ) { - return false; - } - } - return true; -} - -/* -============= -idWinding::LineIntersection -============= -*/ -bool idWinding::LineIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull ) const { - float front, back, frac; - idVec3 mid; - - front = windingPlane.Distance( start ); - back = windingPlane.Distance( end ); - - // if both points at the same side of the plane - if ( front < 0.0f && back < 0.0f ) { - return false; - } - - if ( front > 0.0f && back > 0.0f ) { - return false; - } - - // if back face culled - if ( backFaceCull && front < 0.0f ) { - return false; - } - - // get point of intersection with winding plane - if ( idMath::Fabs(front - back) < 0.0001f ) { - mid = end; - } - else { - frac = front / (front - back); - mid[0] = start[0] + (end[0] - start[0]) * frac; - mid[1] = start[1] + (end[1] - start[1]) * frac; - mid[2] = start[2] + (end[2] - start[2]) * frac; - } - - return PointInside( windingPlane.Normal(), mid, 0.0f ); -} - -/* -============= -idWinding::RayIntersection -============= -*/ -bool idWinding::RayIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull ) const { - int i; - bool side, lastside = false; - idPluecker pl1, pl2; - - scale = 0.0f; - pl1.FromRay( start, dir ); - for ( i = 0; i < numPoints; i++ ) { - pl2.FromLine( p[i].ToVec3(), p[(i+1)%numPoints].ToVec3() ); - side = pl1.PermutedInnerProduct( pl2 ) > 0.0f; - if ( i && side != lastside ) { - return false; - } - lastside = side; - } - if ( !backFaceCull || lastside ) { - windingPlane.RayIntersection( start, dir, scale ); - return true; - } - return false; -} - -/* -================= -idWinding::TriangleArea -================= -*/ -float idWinding::TriangleArea( const idVec3 &a, const idVec3 &b, const idVec3 &c ) { - idVec3 v1, v2; - idVec3 cross; - - v1 = b - a; - v2 = c - a; - cross = v1.Cross( v2 ); - return 0.5f * cross.Length(); -} - - -//=============================================================== -// -// idFixedWinding -// -//=============================================================== - -/* -============= -idFixedWinding::ReAllocate -============= -*/ -bool idFixedWinding::ReAllocate( int n, bool keep ) { - - assert( n <= MAX_POINTS_ON_WINDING ); - - if ( n > MAX_POINTS_ON_WINDING ) { - idLib::common->Printf("WARNING: idFixedWinding -> MAX_POINTS_ON_WINDING overflowed\n"); - return false; - } - return true; -} - -/* -============= -idFixedWinding::Split -============= -*/ -int idFixedWinding::Split( idFixedWinding *back, const idPlane &plane, const float epsilon ) { - int counts[3]; - float dists[MAX_POINTS_ON_WINDING+4]; - byte sides[MAX_POINTS_ON_WINDING+4]; - float dot; - int i, j; - idVec5 *p1, *p2; - idVec5 mid; - idFixedWinding out; - - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - // determine sides for each point - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.Distance( p[i].ToVec3() ); - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - - if ( !counts[SIDE_BACK] ) { - if ( !counts[SIDE_FRONT] ) { - return SIDE_ON; - } - else { - return SIDE_FRONT; - } - } - - if ( !counts[SIDE_FRONT] ) { - return SIDE_BACK; - } - - sides[i] = sides[0]; - dists[i] = dists[0]; - - out.numPoints = 0; - back->numPoints = 0; - - for ( i = 0; i < numPoints; i++ ) { - p1 = &p[i]; - - if ( !out.EnsureAlloced( out.numPoints+1, true ) ) { - return SIDE_FRONT; // can't split -- fall back to original - } - if ( !back->EnsureAlloced( back->numPoints+1, true ) ) { - return SIDE_FRONT; // can't split -- fall back to original - } - - if ( sides[i] == SIDE_ON ) { - out.p[out.numPoints] = *p1; - out.numPoints++; - back->p[back->numPoints] = *p1; - back->numPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - out.p[out.numPoints] = *p1; - out.numPoints++; - } - if ( sides[i] == SIDE_BACK ) { - back->p[back->numPoints] = *p1; - back->numPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - if ( !out.EnsureAlloced( out.numPoints+1, true ) ) { - return SIDE_FRONT; // can't split -- fall back to original - } - - if ( !back->EnsureAlloced( back->numPoints+1, true ) ) { - return SIDE_FRONT; // can't split -- fall back to original - } - - // generate a split point - j = i + 1; - if ( j >= numPoints ) { - p2 = &p[0]; - } - else { - p2 = &p[j]; - } - - dot = dists[i] / (dists[i] - dists[i+1]); - for ( j = 0; j < 3; j++ ) { - // avoid round off error when possible - if ( plane.Normal()[j] == 1.0f ) { - mid[j] = plane.Dist(); - } else if ( plane.Normal()[j] == -1.0f ) { - mid[j] = -plane.Dist(); - } else { - mid[j] = (*p1)[j] + dot * ( (*p2)[j] - (*p1)[j] ); - } - } - mid.s = p1->s + dot * ( p2->s - p1->s ); - mid.t = p1->t + dot * ( p2->t - p1->t ); - - out.p[out.numPoints] = mid; - out.numPoints++; - back->p[back->numPoints] = mid; - back->numPoints++; - } - for ( i = 0; i < out.numPoints; i++ ) { - p[i] = out.p[i]; - } - numPoints = out.numPoints; - - return SIDE_CROSS; -} diff --git a/idlib/geometry/winding.h b/idlib/geometry/winding.h deleted file mode 100644 index 395e93892..000000000 --- a/idlib/geometry/winding.h +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __WINDING_H__ -#define __WINDING_H__ - -/* -=============================================================================== - - A winding is an arbitrary convex polygon defined by an array of points. - -=============================================================================== -*/ - -class idWinding { - -public: - idWinding( void ); - explicit idWinding( const int n ); // allocate for n points - explicit idWinding( const idVec3 *verts, const int n ); // winding from points - explicit idWinding( const idVec3 &normal, const float dist ); // base winding for plane - explicit idWinding( const idPlane &plane ); // base winding for plane - explicit idWinding( const idWinding &winding ); - virtual ~idWinding( void ); - - idWinding & operator=( const idWinding &winding ); - const idVec5 & operator[]( const int index ) const; - idVec5 & operator[]( const int index ); - - // add a point to the end of the winding point array - idWinding & operator+=( const idVec3 &v ); - idWinding & operator+=( const idVec5 &v ); - void AddPoint( const idVec3 &v ); - void AddPoint( const idVec5 &v ); - - // number of points on winding - int GetNumPoints( void ) const; - void SetNumPoints( int n ); - virtual void Clear( void ); - - // huge winding for plane, the points go counter clockwise when facing the front of the plane - void BaseForPlane( const idVec3 &normal, const float dist ); - void BaseForPlane( const idPlane &plane ); - - // splits the winding into a front and back winding, the winding itself stays unchanged - // returns a SIDE_? - int Split( const idPlane &plane, const float epsilon, idWinding **front, idWinding **back ) const; - // returns the winding fragment at the front of the clipping plane, - // if there is nothing at the front the winding itself is destroyed and NULL is returned - idWinding * Clip( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); - // cuts off the part at the back side of the plane, returns true if some part was at the front - // if there is nothing at the front the number of points is set to zero - bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); - - // returns a copy of the winding - idWinding * Copy( void ) const; - idWinding * Reverse( void ) const; - void ReverseSelf( void ); - void RemoveEqualPoints( const float epsilon = ON_EPSILON ); - void RemoveColinearPoints( const idVec3 &normal, const float epsilon = ON_EPSILON ); - void RemovePoint( int point ); - void InsertPoint( const idVec3 &point, int spot ); - bool InsertPointIfOnEdge( const idVec3 &point, const idPlane &plane, const float epsilon = ON_EPSILON ); - // add a winding to the convex hull - void AddToConvexHull( const idWinding *winding, const idVec3 &normal, const float epsilon = ON_EPSILON ); - // add a point to the convex hull - void AddToConvexHull( const idVec3 &point, const idVec3 &normal, const float epsilon = ON_EPSILON ); - // tries to merge 'this' with the given winding, returns NULL if merge fails, both 'this' and 'w' stay intact - // 'keep' tells if the contacting points should stay even if they create colinear edges - idWinding * TryMerge( const idWinding &w, const idVec3 &normal, int keep = false ) const; - // check whether the winding is valid or not - bool Check( bool print = true ) const; - - float GetArea( void ) const; - idVec3 GetCenter( void ) const; - float GetRadius( const idVec3 ¢er ) const; - void GetPlane( idVec3 &normal, float &dist ) const; - void GetPlane( idPlane &plane ) const; - void GetBounds( idBounds &bounds ) const; - - bool IsTiny( void ) const; - bool IsHuge( void ) const; // base winding for a plane is typically huge - void Print( void ) const; - - float PlaneDistance( const idPlane &plane ) const; - int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const; - - bool PlanesConcave( const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2 ) const; - - bool PointInside( const idVec3 &normal, const idVec3 &point, const float epsilon ) const; - // returns true if the line or ray intersects the winding - bool LineIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const; - // intersection point is start + dir * scale - bool RayIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const; - - static float TriangleArea( const idVec3 &a, const idVec3 &b, const idVec3 &c ); - -protected: - int numPoints; // number of points - idVec5 * p; // pointer to point data - int allocedSize; - - bool EnsureAlloced( int n, bool keep = false ); - virtual bool ReAllocate( int n, bool keep = false ); -}; - -ID_INLINE idWinding::idWinding( void ) { - numPoints = allocedSize = 0; - p = NULL; -} - -ID_INLINE idWinding::idWinding( int n ) { - numPoints = allocedSize = 0; - p = NULL; - EnsureAlloced( n ); -} - -ID_INLINE idWinding::idWinding( const idVec3 *verts, const int n ) { - int i; - - numPoints = allocedSize = 0; - p = NULL; - if ( !EnsureAlloced( n ) ) { - numPoints = 0; - return; - } - for ( i = 0; i < n; i++ ) { - p[i].ToVec3() = verts[i]; - p[i].s = p[i].t = 0.0f; - } - numPoints = n; -} - -ID_INLINE idWinding::idWinding( const idVec3 &normal, const float dist ) { - numPoints = allocedSize = 0; - p = NULL; - BaseForPlane( normal, dist ); -} - -ID_INLINE idWinding::idWinding( const idPlane &plane ) { - numPoints = allocedSize = 0; - p = NULL; - BaseForPlane( plane ); -} - -ID_INLINE idWinding::idWinding( const idWinding &winding ) { - int i; - if ( !EnsureAlloced( winding.GetNumPoints() ) ) { - numPoints = 0; - return; - } - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - p[i] = winding[i]; - } - numPoints = winding.GetNumPoints(); -} - -ID_INLINE idWinding::~idWinding( void ) { - delete[] p; - p = NULL; -} - -ID_INLINE idWinding &idWinding::operator=( const idWinding &winding ) { - int i; - - if ( !EnsureAlloced( winding.numPoints ) ) { - numPoints = 0; - return *this; - } - for ( i = 0; i < winding.numPoints; i++ ) { - p[i] = winding.p[i]; - } - numPoints = winding.numPoints; - return *this; -} - -ID_INLINE const idVec5 &idWinding::operator[]( const int index ) const { - //assert( index >= 0 && index < numPoints ); - return p[ index ]; -} - -ID_INLINE idVec5 &idWinding::operator[]( const int index ) { - //assert( index >= 0 && index < numPoints ); - return p[ index ]; -} - -ID_INLINE idWinding &idWinding::operator+=( const idVec3 &v ) { - AddPoint( v ); - return *this; -} - -ID_INLINE idWinding &idWinding::operator+=( const idVec5 &v ) { - AddPoint( v ); - return *this; -} - -ID_INLINE void idWinding::AddPoint( const idVec3 &v ) { - if ( !EnsureAlloced(numPoints+1, true) ) { - return; - } - p[numPoints] = v; - numPoints++; -} - -ID_INLINE void idWinding::AddPoint( const idVec5 &v ) { - if ( !EnsureAlloced(numPoints+1, true) ) { - return; - } - p[numPoints] = v; - numPoints++; -} - -ID_INLINE int idWinding::GetNumPoints( void ) const { - return numPoints; -} - -ID_INLINE void idWinding::SetNumPoints( int n ) { - if ( !EnsureAlloced( n, true ) ) { - return; - } - numPoints = n; -} - -ID_INLINE void idWinding::Clear( void ) { - numPoints = 0; - delete[] p; - p = NULL; -} - -ID_INLINE void idWinding::BaseForPlane( const idPlane &plane ) { - BaseForPlane( plane.Normal(), plane.Dist() ); -} - -ID_INLINE bool idWinding::EnsureAlloced( int n, bool keep ) { - if ( n > allocedSize ) { - return ReAllocate( n, keep ); - } - return true; -} - - -/* -=============================================================================== - - idFixedWinding is a fixed buffer size winding not using - memory allocations. - - When an operation would overflow the fixed buffer a warning - is printed and the operation is safely cancelled. - -=============================================================================== -*/ - -#define MAX_POINTS_ON_WINDING 64 - -class idFixedWinding : public idWinding { - -public: - idFixedWinding( void ); - explicit idFixedWinding( const int n ); - explicit idFixedWinding( const idVec3 *verts, const int n ); - explicit idFixedWinding( const idVec3 &normal, const float dist ); - explicit idFixedWinding( const idPlane &plane ); - explicit idFixedWinding( const idWinding &winding ); - explicit idFixedWinding( const idFixedWinding &winding ); - virtual ~idFixedWinding( void ); - - idFixedWinding &operator=( const idWinding &winding ); - - virtual void Clear( void ); - - // splits the winding in a back and front part, 'this' becomes the front part - // returns a SIDE_? - int Split( idFixedWinding *back, const idPlane &plane, const float epsilon = ON_EPSILON ); - -protected: - idVec5 data[MAX_POINTS_ON_WINDING]; // point data - - virtual bool ReAllocate( int n, bool keep = false ); -}; - -ID_INLINE idFixedWinding::idFixedWinding( void ) { - numPoints = 0; - p = data; - allocedSize = MAX_POINTS_ON_WINDING; -} - -ID_INLINE idFixedWinding::idFixedWinding( int n ) { - numPoints = 0; - p = data; - allocedSize = MAX_POINTS_ON_WINDING; -} - -ID_INLINE idFixedWinding::idFixedWinding( const idVec3 *verts, const int n ) { - int i; - - numPoints = 0; - p = data; - allocedSize = MAX_POINTS_ON_WINDING; - if ( !EnsureAlloced( n ) ) { - numPoints = 0; - return; - } - for ( i = 0; i < n; i++ ) { - p[i].ToVec3() = verts[i]; - p[i].s = p[i].t = 0; - } - numPoints = n; -} - -ID_INLINE idFixedWinding::idFixedWinding( const idVec3 &normal, const float dist ) { - numPoints = 0; - p = data; - allocedSize = MAX_POINTS_ON_WINDING; - BaseForPlane( normal, dist ); -} - -ID_INLINE idFixedWinding::idFixedWinding( const idPlane &plane ) { - numPoints = 0; - p = data; - allocedSize = MAX_POINTS_ON_WINDING; - BaseForPlane( plane ); -} - -ID_INLINE idFixedWinding::idFixedWinding( const idWinding &winding ) { - int i; - - p = data; - allocedSize = MAX_POINTS_ON_WINDING; - if ( !EnsureAlloced( winding.GetNumPoints() ) ) { - numPoints = 0; - return; - } - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - p[i] = winding[i]; - } - numPoints = winding.GetNumPoints(); -} - -ID_INLINE idFixedWinding::idFixedWinding( const idFixedWinding &winding ) { - int i; - - p = data; - allocedSize = MAX_POINTS_ON_WINDING; - if ( !EnsureAlloced( winding.GetNumPoints() ) ) { - numPoints = 0; - return; - } - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - p[i] = winding[i]; - } - numPoints = winding.GetNumPoints(); -} - -ID_INLINE idFixedWinding::~idFixedWinding( void ) { - p = NULL; // otherwise it tries to free the fixed buffer -} - -ID_INLINE idFixedWinding &idFixedWinding::operator=( const idWinding &winding ) { - int i; - - if ( !EnsureAlloced( winding.GetNumPoints() ) ) { - numPoints = 0; - return *this; - } - for ( i = 0; i < winding.GetNumPoints(); i++ ) { - p[i] = winding[i]; - } - numPoints = winding.GetNumPoints(); - return *this; -} - -ID_INLINE void idFixedWinding::Clear( void ) { - numPoints = 0; -} -#endif /* !__WINDING_H__ */ diff --git a/idlib/geometry/winding2d.cpp b/idlib/geometry/winding2d.cpp deleted file mode 100644 index 016981fbc..000000000 --- a/idlib/geometry/winding2d.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "winding2d.h" - -/* -============ -GetAxialBevel -============ -*/ -bool GetAxialBevel( const idVec3 &plane1, const idVec3 &plane2, const idVec2 &point, idVec3 &bevel ) { - if ( FLOATSIGNBITSET( plane1.x ) ^ FLOATSIGNBITSET( plane2.x ) ) { - if ( idMath::Fabs( plane1.x ) > 0.1f && idMath::Fabs( plane2.x ) > 0.1f ) { - bevel.x = 0.0f; - if ( FLOATSIGNBITSET( plane1.y ) ) { - bevel.y = -1.0f; - } - else { - bevel.y = 1.0f; - } - bevel.z = - ( point.x * bevel.x + point.y * bevel.y ); - return true; - } - } - if ( FLOATSIGNBITSET( plane1.y ) ^ FLOATSIGNBITSET( plane2.y ) ) { - if ( idMath::Fabs( plane1.y ) > 0.1f && idMath::Fabs( plane2.y ) > 0.1f ) { - bevel.y = 0.0f; - if ( FLOATSIGNBITSET( plane1.x ) ) { - bevel.x = -1.0f; - } - else { - bevel.x = 1.0f; - } - bevel.z = - ( point.x * bevel.x + point.y * bevel.y ); - return true; - } - } - return false; -} - -/* -============ -idWinding2D::ExpandForAxialBox -============ -*/ -void idWinding2D::ExpandForAxialBox( const idVec2 bounds[2] ) { - int i, j, numPlanes; - idVec2 v; - idVec3 planes[MAX_POINTS_ON_WINDING_2D], plane, bevel; - - // get planes for the edges and add bevels - for ( numPlanes = i = 0; i < numPoints; i++ ) { - j = (i+1) % numPoints; - if ( ( p[j] - p[i] ).LengthSqr() < 0.01f ) { - continue; - } - plane = Plane2DFromPoints( p[i], p[j], true ); - if ( i ) { - if ( GetAxialBevel( planes[numPlanes-1], plane, p[i], bevel ) ) { - planes[numPlanes++] = bevel; - } - } - assert( numPlanes < MAX_POINTS_ON_WINDING_2D ); - planes[numPlanes++] = plane; - } - if ( GetAxialBevel( planes[numPlanes-1], planes[0], p[0], bevel ) ) { - planes[numPlanes++] = bevel; - } - - // expand the planes - for ( i = 0; i < numPlanes; i++ ) { - v.x = bounds[ FLOATSIGNBITSET( planes[i].x ) ].x; - v.y = bounds[ FLOATSIGNBITSET( planes[i].y ) ].y; - planes[i].z += v.x * planes[i].x + v.y * planes[i].y; - } - - // get intersection points of the planes - for ( numPoints = i = 0; i < numPlanes; i++ ) { - if ( Plane2DIntersection( planes[(i+numPlanes-1) % numPlanes], planes[i], p[numPoints] ) ) { - numPoints++; - } - } -} - -/* -============ -idWinding2D::Expand -============ -*/ -void idWinding2D::Expand( const float d ) { - int i; - idVec2 edgeNormals[MAX_POINTS_ON_WINDING_2D]; - - for ( i = 0; i < numPoints; i++ ) { - idVec2 &start = p[i]; - idVec2 &end = p[(i+1)%numPoints]; - edgeNormals[i].x = start.y - end.y; - edgeNormals[i].y = end.x - start.x; - edgeNormals[i].Normalize(); - edgeNormals[i] *= d; - } - - for ( i = 0; i < numPoints; i++ ) { - p[i] += edgeNormals[i] + edgeNormals[(i+numPoints-1)%numPoints]; - } -} - -/* -============= -idWinding2D::Split -============= -*/ -int idWinding2D::Split( const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back ) const { - float dists[MAX_POINTS_ON_WINDING_2D]; - byte sides[MAX_POINTS_ON_WINDING_2D]; - int counts[3]; - float dot; - int i, j; - const idVec2 * p1, *p2; - idVec2 mid; - idWinding2D * f; - idWinding2D * b; - int maxpts; - - counts[0] = counts[1] = counts[2] = 0; - - // determine sides for each point - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - dists[i] = dists[0]; - - *front = *back = NULL; - - // if nothing at the front of the clipping plane - if ( !counts[SIDE_FRONT] ) { - *back = Copy(); - return SIDE_BACK; - } - // if nothing at the back of the clipping plane - if ( !counts[SIDE_BACK] ) { - *front = Copy(); - return SIDE_FRONT; - } - - maxpts = numPoints+4; // cant use counts[0]+2 because of fp grouping errors - - *front = f = new idWinding2D; - *back = b = new idWinding2D; - - for ( i = 0; i < numPoints; i++ ) { - p1 = &p[i]; - - if ( sides[i] == SIDE_ON ) { - f->p[f->numPoints] = *p1; - f->numPoints++; - b->p[b->numPoints] = *p1; - b->numPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - f->p[f->numPoints] = *p1; - f->numPoints++; - } - - if ( sides[i] == SIDE_BACK ) { - b->p[b->numPoints] = *p1; - b->numPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - // generate a split point - p2 = &p[(i+1)%numPoints]; - - // always calculate the split going from the same side - // or minor epsilon issues can happen - if ( sides[i] == SIDE_FRONT ) { - dot = dists[i] / ( dists[i] - dists[i+1] ); - for ( j = 0; j < 2; j++ ) { - // avoid round off error when possible - if ( plane[j] == 1.0f ) { - mid[j] = plane.z; - } else if ( plane[j] == -1.0f ) { - mid[j] = -plane.z; - } else { - mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]); - } - } - } else { - dot = dists[i+1] / ( dists[i+1] - dists[i] ); - for ( j = 0; j < 2; j++ ) { - // avoid round off error when possible - if ( plane[j] == 1.0f ) { - mid[j] = plane.z; - } else if ( plane[j] == -1.0f ) { - mid[j] = -plane.z; - } else { - mid[j] = (*p2)[j] + dot * ( (*p1)[j] - (*p2)[j] ); - } - } - } - - f->p[f->numPoints] = mid; - f->numPoints++; - b->p[b->numPoints] = mid; - b->numPoints++; - } - - return SIDE_CROSS; -} - -/* -============ -idWinding2D::ClipInPlace -============ -*/ -bool idWinding2D::ClipInPlace( const idVec3 &plane, const float epsilon, const bool keepOn ) { - int i, j, maxpts, newNumPoints; - int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; - float dot, dists[MAX_POINTS_ON_WINDING_2D+1]; - idVec2 *p1, *p2, mid, newPoints[MAX_POINTS_ON_WINDING_2D+4]; - - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - for ( i = 0; i < numPoints; i++ ) { - dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; - } else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; - } else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - dists[i] = dists[0]; - - // if the winding is on the plane and we should keep it - if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) { - return true; - } - if ( !counts[SIDE_FRONT] ) { - numPoints = 0; - return false; - } - if ( !counts[SIDE_BACK] ) { - return true; - } - - maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors - newNumPoints = 0; - - for ( i = 0; i < numPoints; i++ ) { - p1 = &p[i]; - - if ( newNumPoints+1 > maxpts ) { - return true; // can't split -- fall back to original - } - - if ( sides[i] == SIDE_ON ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - continue; - } - - if ( sides[i] == SIDE_FRONT ) { - newPoints[newNumPoints] = *p1; - newNumPoints++; - } - - if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) { - continue; - } - - if ( newNumPoints+1 > maxpts ) { - return true; // can't split -- fall back to original - } - - // generate a split point - p2 = &p[(i+1)%numPoints]; - - dot = dists[i] / (dists[i] - dists[i+1]); - for ( j = 0; j < 2; j++ ) { - // avoid round off error when possible - if ( plane[j] == 1.0f ) { - mid[j] = plane.z; - } else if ( plane[j] == -1.0f ) { - mid[j] = -plane.z; - } else { - mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]); - } - } - - newPoints[newNumPoints] = mid; - newNumPoints++; - } - - if ( newNumPoints >= MAX_POINTS_ON_WINDING_2D ) { - return true; - } - - numPoints = newNumPoints; - memcpy( p, newPoints, newNumPoints * sizeof(idVec2) ); - - return true; -} - -/* -============= -idWinding2D::Copy -============= -*/ -idWinding2D *idWinding2D::Copy( void ) const { - idWinding2D *w; - - w = new idWinding2D; - w->numPoints = numPoints; - memcpy( w->p, p, numPoints * sizeof( p[0] ) ); - return w; -} - -/* -============= -idWinding2D::Reverse -============= -*/ -idWinding2D *idWinding2D::Reverse( void ) const { - idWinding2D *w; - int i; - - w = new idWinding2D; - w->numPoints = numPoints; - for ( i = 0; i < numPoints; i++ ) { - w->p[ numPoints - i - 1 ] = p[i]; - } - return w; -} - -/* -============ -idWinding2D::GetArea -============ -*/ -float idWinding2D::GetArea( void ) const { - int i; - idVec2 d1, d2; - float total; - - total = 0.0f; - for ( i = 2; i < numPoints; i++ ) { - d1 = p[i-1] - p[0]; - d2 = p[i] - p[0]; - total += d1.x * d2.y - d1.y * d2.x; - } - return total * 0.5f; -} - -/* -============ -idWinding2D::GetCenter -============ -*/ -idVec2 idWinding2D::GetCenter( void ) const { - int i; - idVec2 center; - - center.Zero(); - for ( i = 0; i < numPoints; i++ ) { - center += p[i]; - } - center *= ( 1.0f / numPoints ); - return center; -} - -/* -============ -idWinding2D::GetRadius -============ -*/ -float idWinding2D::GetRadius( const idVec2 ¢er ) const { - int i; - float radius, r; - idVec2 dir; - - radius = 0.0f; - for ( i = 0; i < numPoints; i++ ) { - dir = p[i] - center; - r = dir * dir; - if ( r > radius ) { - radius = r; - } - } - return idMath::Sqrt( radius ); -} - -/* -============ -idWinding2D::GetBounds -============ -*/ -void idWinding2D::GetBounds( idVec2 bounds[2] ) const { - int i; - - if ( !numPoints ) { - bounds[0].x = bounds[0].y = idMath::INFINITY; - bounds[1].x = bounds[1].y = -idMath::INFINITY; - return; - } - bounds[0] = bounds[1] = p[0]; - for ( i = 1; i < numPoints; i++ ) { - if ( p[i].x < bounds[0].x ) { - bounds[0].x = p[i].x; - } else if ( p[i].x > bounds[1].x ) { - bounds[1].x = p[i].x; - } - if ( p[i].y < bounds[0].y ) { - bounds[0].y = p[i].y; - } else if ( p[i].y > bounds[1].y ) { - bounds[1].y = p[i].y; - } - } -} - -/* -============= -idWinding2D::IsTiny -============= -*/ -#define EDGE_LENGTH 0.2f - -bool idWinding2D::IsTiny( void ) const { - int i; - float len; - idVec2 delta; - int edges; - - edges = 0; - for ( i = 0; i < numPoints; i++ ) { - delta = p[(i+1)%numPoints] - p[i]; - len = delta.Length(); - if ( len > EDGE_LENGTH ) { - if ( ++edges == 3 ) { - return false; - } - } - } - return true; -} - -/* -============= -idWinding2D::IsHuge -============= -*/ -bool idWinding2D::IsHuge( void ) const { - int i, j; - - for ( i = 0; i < numPoints; i++ ) { - for ( j = 0; j < 2; j++ ) { - if ( p[i][j] <= MIN_WORLD_COORD || p[i][j] >= MAX_WORLD_COORD ) { - return true; - } - } - } - return false; -} - -/* -============= -idWinding2D::Print -============= -*/ -void idWinding2D::Print( void ) const { - int i; - - for ( i = 0; i < numPoints; i++ ) { - idLib::common->Printf( "(%5.1f, %5.1f)\n", p[i][0], p[i][1] ); - } -} - -/* -============= -idWinding2D::PlaneDistance -============= -*/ -float idWinding2D::PlaneDistance( const idVec3 &plane ) const { - int i; - float d, min, max; - - min = idMath::INFINITY; - max = -min; - for ( i = 0; i < numPoints; i++ ) { - d = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( d < min ) { - min = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - if ( d > max ) { - max = d; - if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) { - return 0.0f; - } - } - } - if ( FLOATSIGNBITNOTSET( min ) ) { - return min; - } - if ( FLOATSIGNBITSET( max ) ) { - return max; - } - return 0.0f; -} - -/* -============= -idWinding2D::PlaneSide -============= -*/ -int idWinding2D::PlaneSide( const idVec3 &plane, const float epsilon ) const { - bool front, back; - int i; - float d; - - front = false; - back = false; - for ( i = 0; i < numPoints; i++ ) { - d = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( d < -epsilon ) { - if ( front ) { - return SIDE_CROSS; - } - back = true; - continue; - } - else if ( d > epsilon ) { - if ( back ) { - return SIDE_CROSS; - } - front = true; - continue; - } - } - - if ( back ) { - return SIDE_BACK; - } - if ( front ) { - return SIDE_FRONT; - } - return SIDE_ON; -} - -/* -============ -idWinding2D::PointInside -============ -*/ -bool idWinding2D::PointInside( const idVec2 &point, const float epsilon ) const { - int i; - float d; - idVec3 plane; - - for ( i = 0; i < numPoints; i++ ) { - plane = Plane2DFromPoints( p[i], p[(i+1) % numPoints] ); - d = plane.x * point.x + plane.y * point.y + plane.z; - if ( d > epsilon ) { - return false; - } - } - return true; -} - -/* -============ -idWinding2D::LineIntersection -============ -*/ -bool idWinding2D::LineIntersection( const idVec2 &start, const idVec2 &end ) const { - int i, numEdges; - int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; - float d1, d2, epsilon = 0.1f; - idVec3 plane, edges[2]; - - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - plane = Plane2DFromPoints( start, end ); - for ( i = 0; i < numPoints; i++ ) { - d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( d1 > epsilon ) { - sides[i] = SIDE_FRONT; - } - else if ( d1 < -epsilon ) { - sides[i] = SIDE_BACK; - } - else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - - if ( !counts[SIDE_FRONT] ) { - return false; - } - if ( !counts[SIDE_BACK] ) { - return false; - } - - numEdges = 0; - for ( i = 0; i < numPoints; i++ ) { - if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) { - edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] ); - if ( numEdges >= 2 ) { - break; - } - } - } - if ( numEdges < 2 ) { - return false; - } - - d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z; - d2 = edges[0].x * end.x + edges[0].y * end.y + edges[0].z; - if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) { - return false; - } - d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z; - d2 = edges[1].x * end.x + edges[1].y * end.y + edges[1].z; - if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) { - return false; - } - return true; -} - -/* -============ -idWinding2D::RayIntersection -============ -*/ -bool idWinding2D::RayIntersection( const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums ) const { - int i, numEdges, localEdgeNums[2]; - int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; - float d1, d2, epsilon = 0.1f; - idVec3 plane, edges[2]; - - scale1 = scale2 = 0.0f; - counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; - - plane = Plane2DFromVecs( start, dir ); - for ( i = 0; i < numPoints; i++ ) { - d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z; - if ( d1 > epsilon ) { - sides[i] = SIDE_FRONT; - } - else if ( d1 < -epsilon ) { - sides[i] = SIDE_BACK; - } - else { - sides[i] = SIDE_ON; - } - counts[sides[i]]++; - } - sides[i] = sides[0]; - - if ( !counts[SIDE_FRONT] ) { - return false; - } - if ( !counts[SIDE_BACK] ) { - return false; - } - - numEdges = 0; - for ( i = 0; i < numPoints; i++ ) { - if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) { - localEdgeNums[numEdges] = i; - edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] ); - if ( numEdges >= 2 ) { - break; - } - } - } - if ( numEdges < 2 ) { - return false; - } - - d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z; - d2 = - ( edges[0].x * dir.x + edges[0].y * dir.y ); - if ( d2 == 0.0f ) { - return false; - } - scale1 = d1 / d2; - d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z; - d2 = - ( edges[1].x * dir.x + edges[1].y * dir.y ); - if ( d2 == 0.0f ) { - return false; - } - scale2 = d1 / d2; - - if ( idMath::Fabs( scale1 ) > idMath::Fabs( scale2 ) ) { - idSwap( scale1, scale2 ); - idSwap( localEdgeNums[0], localEdgeNums[1] ); - } - - if ( edgeNums ) { - edgeNums[0] = localEdgeNums[0]; - edgeNums[1] = localEdgeNums[1]; - } - return true; -} diff --git a/idlib/geometry/winding2d.h b/idlib/geometry/winding2d.h deleted file mode 100644 index 5d470e069..000000000 --- a/idlib/geometry/winding2d.h +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __WINDING2D_H__ -#define __WINDING2D_H__ - -/* -=============================================================================== - - A 2D winding is an arbitrary convex 2D polygon defined by an array of points. - -=============================================================================== -*/ - -#define MAX_POINTS_ON_WINDING_2D 16 - - -class idWinding2D { -public: - idWinding2D( void ); - - idWinding2D & operator=( const idWinding2D &winding ); - const idVec2 & operator[]( const int index ) const; - idVec2 & operator[]( const int index ); - - void Clear( void ); - void AddPoint( const idVec2 &point ); - int GetNumPoints( void ) const; - - void Expand( const float d ); - void ExpandForAxialBox( const idVec2 bounds[2] ); - - // splits the winding into a front and back winding, the winding itself stays unchanged - // returns a SIDE_? - int Split( const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back ) const; - // cuts off the part at the back side of the plane, returns true if some part was at the front - // if there is nothing at the front the number of points is set to zero - bool ClipInPlace( const idVec3 &plane, const float epsilon = ON_EPSILON, const bool keepOn = false ); - - idWinding2D * Copy( void ) const; - idWinding2D * Reverse( void ) const; - - float GetArea( void ) const; - idVec2 GetCenter( void ) const; - float GetRadius( const idVec2 ¢er ) const; - void GetBounds( idVec2 bounds[2] ) const; - - bool IsTiny( void ) const; - bool IsHuge( void ) const; // base winding for a plane is typically huge - void Print( void ) const; - - float PlaneDistance( const idVec3 &plane ) const; - int PlaneSide( const idVec3 &plane, const float epsilon = ON_EPSILON ) const; - - bool PointInside( const idVec2 &point, const float epsilon ) const; - bool LineIntersection( const idVec2 &start, const idVec2 &end ) const; - bool RayIntersection( const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums = NULL ) const; - - static idVec3 Plane2DFromPoints( const idVec2 &start, const idVec2 &end, const bool normalize = false ); - static idVec3 Plane2DFromVecs( const idVec2 &start, const idVec2 &dir, const bool normalize = false ); - static bool Plane2DIntersection( const idVec3 &plane1, const idVec3 &plane2, idVec2 &point ); - -private: - int numPoints; - idVec2 p[MAX_POINTS_ON_WINDING_2D]; -}; - -ID_INLINE idWinding2D::idWinding2D( void ) { - numPoints = 0; -} - -ID_INLINE idWinding2D &idWinding2D::operator=( const idWinding2D &winding ) { - int i; - - for ( i = 0; i < winding.numPoints; i++ ) { - p[i] = winding.p[i]; - } - numPoints = winding.numPoints; - return *this; -} - -ID_INLINE const idVec2 &idWinding2D::operator[]( const int index ) const { - return p[ index ]; -} - -ID_INLINE idVec2 &idWinding2D::operator[]( const int index ) { - return p[ index ]; -} - -ID_INLINE void idWinding2D::Clear( void ) { - numPoints = 0; -} - -ID_INLINE void idWinding2D::AddPoint( const idVec2 &point ) { - p[numPoints++] = point; -} - -ID_INLINE int idWinding2D::GetNumPoints( void ) const { - return numPoints; -} - -ID_INLINE idVec3 idWinding2D::Plane2DFromPoints( const idVec2 &start, const idVec2 &end, const bool normalize ) { - idVec3 plane; - plane.x = start.y - end.y; - plane.y = end.x - start.x; - if ( normalize ) { - plane.ToVec2().Normalize(); - } - plane.z = - ( start.x * plane.x + start.y * plane.y ); - return plane; -} - -ID_INLINE idVec3 idWinding2D::Plane2DFromVecs( const idVec2 &start, const idVec2 &dir, const bool normalize ) { - idVec3 plane; - plane.x = -dir.y; - plane.y = dir.x; - if ( normalize ) { - plane.ToVec2().Normalize(); - } - plane.z = - ( start.x * plane.x + start.y * plane.y ); - return plane; -} - -ID_INLINE bool idWinding2D::Plane2DIntersection( const idVec3 &plane1, const idVec3 &plane2, idVec2 &point ) { - float n00, n01, n11, det, invDet, f0, f1; - - n00 = plane1.x * plane1.x + plane1.y * plane1.y; - n01 = plane1.x * plane2.x + plane1.y * plane2.y; - n11 = plane2.x * plane2.x + plane2.y * plane2.y; - det = n00 * n11 - n01 * n01; - - if ( idMath::Fabs(det) < 1e-6f ) { - return false; - } - - invDet = 1.0f / det; - f0 = ( n01 * plane2.z - n11 * plane1.z ) * invDet; - f1 = ( n01 * plane1.z - n00 * plane2.z ) * invDet; - point.x = f0 * plane1.x + f1 * plane2.x; - point.y = f0 * plane1.y + f1 * plane2.y; - return true; -} - -#endif /* !__WINDING2D_H__ */ diff --git a/idlib/hashing/CRC32.cpp b/idlib/hashing/CRC32.cpp new file mode 100644 index 000000000..c8c402695 --- /dev/null +++ b/idlib/hashing/CRC32.cpp @@ -0,0 +1,167 @@ + +#include "../precompiled.h" +#pragma hdrstop + +/* + CRC-32 + Copyright (C) 1995-1998 Mark Adler +*/ + +#define CRC32_INIT_VALUE 0xffffffffL +#define CRC32_XOR_VALUE 0xffffffffL + +#ifdef CREATE_CRC_TABLE + +static unsigned long crctable[256]; + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^1+x^0), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+x^0), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ + +void make_crc_table( void ) { + int i, j; + unsigned long c, poly; + /* terms of polynomial defining this crc (except x^32): */ + static const byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for ( i = 0; i < sizeof( p ) / sizeof( byte ); i++ ) { + poly |= 1L << ( 31 - p[i] ); + } + + for ( i = 0; i < 256; i++ ) { + c = (unsigned long)i; + for ( j = 0; j < 8; j++ ) { + c = ( c & 1 ) ? poly ^ ( c >> 1 ) : ( c >> 1 ); + } + crctable[i] = c; + } +} + +#else + +/* + Table of CRC-32's of all single-byte values (made by make_crc_table) +*/ +static unsigned long crctable[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, + 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, + 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, + 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, + 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, + 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, + 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, + 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, + 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, + 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, + 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, + 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, + 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, + 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, + 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, + 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, + 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, + 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, + 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, + 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, + 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, + 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, + 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, + 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, + 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, + 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, + 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, + 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, + 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, + 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, + 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, + 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, + 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, + 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, + 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, + 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, + 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, + 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, + 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, + 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, + 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, + 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, + 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, + 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, + 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, + 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, + 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, + 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, + 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, + 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, + 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, + 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL +}; + +#endif + +void CRC32_InitChecksum( unsigned long &crcvalue ) { + crcvalue = CRC32_INIT_VALUE; +} + +void CRC32_Update( unsigned long &crcvalue, const byte data ) { + crcvalue = crctable[ ( crcvalue ^ data ) & 0xff ] ^ ( crcvalue >> 8 ); +} + +void CRC32_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ) { + unsigned long crc; + const unsigned char *buf = (const unsigned char *) data; + + crc = crcvalue; + while( length-- ) { + crc = crctable[ ( crc ^ ( *buf++ ) ) & 0xff ] ^ ( crc >> 8 ); + } + crcvalue = crc; +} + +void CRC32_FinishChecksum( unsigned long &crcvalue ) { + crcvalue ^= CRC32_XOR_VALUE; +} + +unsigned long CRC32_BlockChecksum( const void *data, int length ) { + unsigned long crc; + + CRC32_InitChecksum( crc ); + CRC32_UpdateChecksum( crc, data, length ); + CRC32_FinishChecksum( crc ); + return crc; +} diff --git a/idlib/hashing/CRC32.h b/idlib/hashing/CRC32.h new file mode 100644 index 000000000..63f0cc327 --- /dev/null +++ b/idlib/hashing/CRC32.h @@ -0,0 +1,18 @@ +#ifndef __CRC32_H__ +#define __CRC32_H__ + +/* +=============================================================================== + + Calculates a checksum for a block of data + using the CRC-32. + +=============================================================================== +*/ + +void CRC32_InitChecksum( unsigned long &crcvalue ); +void CRC32_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ); +void CRC32_FinishChecksum( unsigned long &crcvalue ); +unsigned long CRC32_BlockChecksum( const void *data, int length ); + +#endif /* !__CRC32_H__ */ diff --git a/idlib/hashing/MD4.cpp b/idlib/hashing/MD4.cpp new file mode 100644 index 000000000..f2139e604 --- /dev/null +++ b/idlib/hashing/MD4.cpp @@ -0,0 +1,259 @@ + +#include "../precompiled.h" +#pragma hdrstop + +/* + RSA Data Security, Inc., MD4 message-digest algorithm. (RFC1320) +*/ + +/* + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD4 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD4 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +/* MD4 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD4_CTX; + +/* Constants for MD4Transform routine. */ +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +static unsigned char PADDING[64] = { +0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G and H are basic MD4 functions. */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));} + +#define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; (a) = ROTATE_LEFT ((a), (s));} + +#define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; (a) = ROTATE_LEFT ((a), (s));} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ +static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) { + unsigned int i, j; + + for ( i = 0, j = 0; j < len; i++, j += 4 ) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ +static void Decode( UINT4 *output, const unsigned char *input, unsigned int len ) { + unsigned int i, j; + + for ( i = 0, j = 0; j < len; i++, j += 4 ) { + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); + } +} + +/* MD4 basic transformation. Transforms state based on block. */ +static void MD4_Transform( UINT4 state[4], const unsigned char block[64] ) { + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information.*/ + memset ((POINTER)x, 0, sizeof (x)); +} + +/* MD4 initialization. Begins an MD4 operation, writing a new context. */ +void MD4_Init( MD4_CTX *context ) { + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants.*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */ +void MD4_Update( MD4_CTX *context, const unsigned char *input, unsigned int inputLen ) { + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3)) { + context->count[1]++; + } + + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible.*/ + if ( inputLen >= partLen ) { + memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD4_Transform (context->state, context->buffer); + + for ( i = partLen; i + 63 < inputLen; i += 64 ) { + MD4_Transform (context->state, &input[i]); + } + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); +} + +/* MD4 finalization. Ends an MD4 message-digest operation, writing the message digest and zeroizing the context. */ +void MD4_Final( MD4_CTX *context, unsigned char digest[16] ) { + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode( bits, context->count, 8 ); + + /* Pad out to 56 mod 64.*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD4_Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD4_Update( context, bits, 8 ); + + /* Store state in digest */ + Encode( digest, context->state, 16 ); + + /* Zeroize sensitive information.*/ + memset ((POINTER)context, 0, sizeof (*context)); +} + +/* +=============== +MD4_BlockChecksum +=============== +*/ +unsigned long MD4_BlockChecksum( const void *data, int length ) { + unsigned long digest[4]; + unsigned long val; + MD4_CTX ctx; + + MD4_Init( &ctx ); + MD4_Update( &ctx, (unsigned char *)data, length ); + MD4_Final( &ctx, (unsigned char *)digest ); + + val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; + + return val; +} diff --git a/idlib/hashing/MD4.h b/idlib/hashing/MD4.h new file mode 100644 index 000000000..8b5eb907f --- /dev/null +++ b/idlib/hashing/MD4.h @@ -0,0 +1,15 @@ +#ifndef __MD4_H__ +#define __MD4_H__ + +/* +=============================================================================== + + Calculates a checksum for a block of data + using the MD4 message-digest algorithm. + +=============================================================================== +*/ + +unsigned long MD4_BlockChecksum( const void *data, int length ); + +#endif /* !__MD4_H__ */ diff --git a/idlib/hashing/MD5.cpp b/idlib/hashing/MD5.cpp new file mode 100644 index 000000000..890008921 --- /dev/null +++ b/idlib/hashing/MD5.cpp @@ -0,0 +1,272 @@ + +#include "../precompiled.h" +#pragma hdrstop + +/* + MD5 Message Digest Algorithm. (RFC1321) +*/ + +/* + +This code implements the MD5 message-digest algorithm. +The algorithm is due to Ron Rivest. This code was +written by Colin Plumb in 1993, no copyright is claimed. +This code is in the public domain; do with it what you wish. + +Equivalent code is available from RSA Data Security, Inc. +This code has been tested against that, and is equivalent, +except that you don't need to include two pages of legalese +with every copy. + +To compute the message digest of a chunk of bytes, declare an +MD5Context structure, pass it to MD5Init, call MD5Update as +needed on buffers full of bytes, and then call MD5Final, which +will fill a supplied 16-byte array with the digest. + +*/ + +/* MD5 context. */ +typedef struct +{ + unsigned int state[4]; + unsigned int bits[2]; + unsigned char in[64]; +} MD5_CTX; + +/* The four core functions - F1 is optimized somewhat */ +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* +================= +MD5_Transform + +The core of the MD5 algorithm, this alters an existing MD5 hash to +reflect the addition of 16 longwords of new data. MD5Update blocks +the data and converts bytes into longwords for this routine. +================= +*/ +void MD5_Transform( unsigned int state[4], unsigned int in[16] ) { + register unsigned int a, b, c, d; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + LittleRevBytes( in, sizeof(unsigned int), 16 ); + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + LittleRevBytes( in, sizeof(unsigned int), 16 ); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} + +/* +================== +MD5_Init + +MD5 initialization. Begins an MD5 operation, writing a new context. +================== +*/ +void MD5_Init( MD5_CTX *ctx ) { + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* +=================== +MD5_Update + +MD5 block update operation. Continues an MD5 message-digest operation, +processing another message block, and updating the context. +=================== +*/ +void MD5_Update( MD5_CTX *ctx, unsigned char const *buf, unsigned int len ) { + unsigned int t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ( ( ctx->bits[0] = t + ( (unsigned int) len << 3 ) ) < t ) { + ctx->bits[1]++; /* Carry from low to high */ + } + ctx->bits[1] += len >> 29; + + t = ( t >> 3 ) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if ( t ) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if ( len < t ) { + memcpy( p, buf, len ); + return; + } + memcpy( p, buf, t ); + MD5_Transform( ctx->state, (unsigned int *) ctx->in ); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while( len >= 64 ) { + memcpy( ctx->in, buf, 64 ); + MD5_Transform( ctx->state, (unsigned int *) ctx->in ); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy( ctx->in, buf, len ); +} + +/* +=============== +MD5_Final + +MD5 finalization. Ends an MD5 message-digest operation, +writing the message digest and zeroizing the context. +=============== +*/ +void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) { + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = ( ctx->bits[0] >> 3 ) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if ( count < 8 ) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset( p, 0, count ); + MD5_Transform( ctx->state, (unsigned int *) ctx->in ); + + /* Now fill the next block with 56 bytes */ + memset( ctx->in, 0, 56 ); + } else { + /* Pad block to 56 bytes */ + memset( p, 0, count - 8 ); + } + + /* Append length in bits and transform */ + unsigned int val0 = ctx->bits[0]; + unsigned int val1 = ctx->bits[1]; + + ((unsigned int *) ctx->in)[14] = LittleLong( val0 ); + ((unsigned int *) ctx->in)[15] = LittleLong( val1 ); + + MD5_Transform( ctx->state, (unsigned int *) ctx->in ); + memcpy( digest, ctx->state, 16 ); + memset( ctx, 0, sizeof( ctx ) ); /* In case it's sensitive */ +} + +/* +=============== +MD5_BlockChecksum +=============== +*/ +unsigned long MD5_BlockChecksum( const void *data, int length ) { + unsigned long digest[4]; + unsigned long val; + MD5_CTX ctx; + + MD5_Init( &ctx ); + MD5_Update( &ctx, (unsigned char *)data, length ); + MD5_Final( &ctx, (unsigned char *)digest ); + + val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; + + return val; +} diff --git a/idlib/hashing/MD5.h b/idlib/hashing/MD5.h new file mode 100644 index 000000000..e187e56fd --- /dev/null +++ b/idlib/hashing/MD5.h @@ -0,0 +1,15 @@ +#ifndef __MD5_H__ +#define __MD5_H__ + +/* +=============================================================================== + + Calculates a checksum for a block of data + using the MD5 message-digest algorithm. + +=============================================================================== +*/ + +unsigned long MD5_BlockChecksum( const void *data, int length ); + +#endif /* !__MD5_H__ */ diff --git a/idlib/hashing/crc16.cpp b/idlib/hashing/crc16.cpp deleted file mode 100644 index b57eb6a51..000000000 --- a/idlib/hashing/crc16.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* - CRC-16 - - 16 bit, non-reflected CRC using the polynomial 0x1021 - and the initial and final xor values shown below. - in other words, the CCITT standard CRC-16 -*/ - -#define CRC16_INIT_VALUE 0xffff -#define CRC16_XOR_VALUE 0x0000 - -#ifdef CREATE_CRC_TABLE - -static unsigned short crctable[256]; - -/* - Generate a table for a byte-wise 16-bit CRC calculation on the polynomial: - x^16 + x^12 + x^5 + x^0 -*/ - -void make_crc_table( void ) { - int i, j; - unsigned long poly, c; - /* terms of polynomial defining this crc (except x^16): */ - static const byte p[] = {0,5,12}; - - /* make exclusive-or pattern from polynomial (0x1021) */ - poly = 0L; - for ( i = 0; i < sizeof( p ) / sizeof( byte ); i++ ) { - poly |= 1L << p[i]; - } - - for ( i = 0; i < 256; i++ ) { - c = i << 8; - for ( j = 0; j < 8; j++ ) { - c = ( c & 0x8000 ) ? poly ^ ( c << 1 ) : ( c << 1 ); - } - crctable[i] = (unsigned short) c; - } -} - -#else - -/* - Table of CRC-16's of all single-byte values (made by make_crc_table) -*/ -static unsigned short crctable[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 -}; - -#endif - -void CRC16_InitChecksum( unsigned short &crcvalue ) { - crcvalue = CRC16_INIT_VALUE; -} - -void CRC16_Update( unsigned short &crcvalue, const byte data ) { - crcvalue = ( crcvalue << 8 ) ^ crctable[ ( crcvalue >> 8 ) ^ data ]; -} - -void CRC16_UpdateChecksum( unsigned short &crcvalue, const void *data, int length ) { - unsigned short crc; - const unsigned char *buf = (const unsigned char *) data; - - crc = crcvalue; - while( length-- ) { - crc = ( crc << 8 ) ^ crctable[ ( crc >> 8 ) ^ *buf++ ]; - } - crcvalue = crc; -} - -void CRC16_FinishChecksum( unsigned short &crcvalue ) { - crcvalue ^= CRC16_XOR_VALUE; -} - -unsigned short CRC16_BlockChecksum( const void *data, int length ) { - unsigned short crc; - - CRC16_InitChecksum( crc ); - CRC16_UpdateChecksum( crc, data, length ); - CRC16_FinishChecksum( crc ); - return crc; -} diff --git a/idlib/hashing/crc16.h b/idlib/hashing/crc16.h deleted file mode 100644 index 4bc9b4729..000000000 --- a/idlib/hashing/crc16.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CRC16_H__ -#define __CRC16_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the CCITT standard CRC-16. - -=============================================================================== -*/ - -void CRC16_InitChecksum( unsigned short &crcvalue ); -void CRC16_UpdateChecksum( unsigned short &crcvalue, const void *data, int length ); -void CRC16_FinishChecksum( unsigned short &crcvalue ); -unsigned short CRC16_BlockChecksum( const void *data, int length ); - -#endif /* !__CRC16_H__ */ diff --git a/idlib/hashing/crc32.cpp b/idlib/hashing/crc32.cpp deleted file mode 100644 index 6e590e77a..000000000 --- a/idlib/hashing/crc32.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* - CRC-32 - Copyright (C) 1995-1998 Mark Adler -*/ - -#define CRC32_INIT_VALUE 0xffffffffL -#define CRC32_XOR_VALUE 0xffffffffL - -#ifdef CREATE_CRC_TABLE - -static unsigned long crctable[256]; - -/* - Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^1+x^0), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+x^0), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all - the information needed to generate CRC's on data a byte at a time for all - combinations of CRC register values and incoming bytes. -*/ - -void make_crc_table( void ) { - int i, j; - unsigned long c, poly; - /* terms of polynomial defining this crc (except x^32): */ - static const byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* make exclusive-or pattern from polynomial (0xedb88320L) */ - poly = 0L; - for ( i = 0; i < sizeof( p ) / sizeof( byte ); i++ ) { - poly |= 1L << ( 31 - p[i] ); - } - - for ( i = 0; i < 256; i++ ) { - c = (unsigned long)i; - for ( j = 0; j < 8; j++ ) { - c = ( c & 1 ) ? poly ^ ( c >> 1 ) : ( c >> 1 ); - } - crctable[i] = c; - } -} - -#else - -/* - Table of CRC-32's of all single-byte values (made by make_crc_table) -*/ -static unsigned long crctable[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, - 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, - 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, - 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, - 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, - 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, - 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, - 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, - 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, - 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, - 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, - 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, - 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, - 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, - 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, - 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, - 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, - 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, - 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, - 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, - 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, - 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, - 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, - 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, - 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, - 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, - 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, - 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, - 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, - 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, - 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, - 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, - 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, - 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, - 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, - 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, - 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, - 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, - 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, - 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, - 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, - 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, - 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, - 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, - 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, - 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, - 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, - 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, - 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, - 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, - 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, - 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL -}; - -#endif - -void CRC32_InitChecksum( unsigned long &crcvalue ) { - crcvalue = CRC32_INIT_VALUE; -} - -void CRC32_Update( unsigned long &crcvalue, const byte data ) { - crcvalue = crctable[ ( crcvalue ^ data ) & 0xff ] ^ ( crcvalue >> 8 ); -} - -void CRC32_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ) { - unsigned long crc; - const unsigned char *buf = (const unsigned char *) data; - - crc = crcvalue; - while( length-- ) { - crc = crctable[ ( crc ^ ( *buf++ ) ) & 0xff ] ^ ( crc >> 8 ); - } - crcvalue = crc; -} - -void CRC32_FinishChecksum( unsigned long &crcvalue ) { - crcvalue ^= CRC32_XOR_VALUE; -} - -unsigned long CRC32_BlockChecksum( const void *data, int length ) { - unsigned long crc; - - CRC32_InitChecksum( crc ); - CRC32_UpdateChecksum( crc, data, length ); - CRC32_FinishChecksum( crc ); - return crc; -} diff --git a/idlib/hashing/crc32.h b/idlib/hashing/crc32.h deleted file mode 100644 index 770bf6af3..000000000 --- a/idlib/hashing/crc32.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __CRC32_H__ -#define __CRC32_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the CRC-32. - -=============================================================================== -*/ - -void CRC32_InitChecksum( unsigned long &crcvalue ); -void CRC32_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ); -void CRC32_FinishChecksum( unsigned long &crcvalue ); -unsigned long CRC32_BlockChecksum( const void *data, int length ); - -#endif /* !__CRC32_H__ */ diff --git a/idlib/hashing/crc8.cpp b/idlib/hashing/crc8.cpp deleted file mode 100644 index f128b90cd..000000000 --- a/idlib/hashing/crc8.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* - CRC-8 -*/ - -#define CRC8_INIT_VALUE 0x0000 -#define CRC8_XOR_VALUE 0x0000 - -#ifdef CREATE_CRC_TABLE - -static byte crctable[256]; - -/* - Generate a table for a byte-wise 8-bit CRC calculation on the polynomial: - x^8 + x^2 + x^1 + x^0 -*/ - -void make_crc_table( void ) { - int i, j; - unsigned long poly, c; - /* terms of polynomial defining this crc (except x^8): */ - static const byte p[] = {0,1,2}; - - /* make exclusive-or pattern from polynomial (0x07) */ - poly = 0L; - for ( i = 0; i < sizeof( p ) / sizeof( byte ); i++ ) { - poly |= 1L << p[i]; - } - - for ( i = 0; i < 256; i++ ) { - c = i; - for ( j = 0; j < 8; j++ ) { - c = ( c & 0x80 ) ? poly ^ ( c << 1 ) : ( c << 1 ); - } - crctable[i] = (byte) c; - } -} - -#else - -/* - Table of CRC-8's of all single-byte values (made by make_crc_table) -*/ -static byte crctable[256] = { - 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, - 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, - 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, - 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, - 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, - 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, - 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, - 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, - 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, - 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, - 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, - 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, - 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, - 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, - 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, - 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, - 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, - 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, - 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, - 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, - 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, - 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, - 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, - 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, - 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, - 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, - 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, - 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, - 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, - 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, - 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, - 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 -}; - -#endif - -void CRC8_InitChecksum( unsigned char &crcvalue ) { - crcvalue = CRC8_INIT_VALUE; -} - -void CRC8_Update( unsigned char &crcvalue, const byte data ) { - crcvalue = crctable[crcvalue ^ data]; -} - -void CRC8_UpdateChecksum( unsigned char &crcvalue, const void *data, int length ) { - unsigned char crc; - const unsigned char *buf = (const unsigned char *) data; - - crc = crcvalue; - while( length-- ) { - crc = crctable[crc ^ *buf++]; - } - crcvalue = crc; -} - -void CRC8_FinishChecksum( unsigned char &crcvalue ) { - crcvalue ^= CRC8_XOR_VALUE; -} - -unsigned char CRC8_BlockChecksum( const void *data, int length ) { - unsigned char crc; - - CRC8_InitChecksum( crc ); - CRC8_UpdateChecksum( crc, data, length ); - CRC8_FinishChecksum( crc ); - return crc; -} diff --git a/idlib/hashing/crc8.h b/idlib/hashing/crc8.h deleted file mode 100644 index 851953c08..000000000 --- a/idlib/hashing/crc8.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CRC8_H__ -#define __CRC8_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the CRC-8. - -=============================================================================== -*/ - -void CRC8_InitChecksum( unsigned char &crcvalue ); -void CRC8_UpdateChecksum( unsigned char &crcvalue, const void *data, int length ); -void CRC8_FinishChecksum( unsigned char &crcvalue ); -unsigned char CRC8_BlockChecksum( const void *data, int length ); - -#endif /* !__CRC8_H__ */ diff --git a/idlib/hashing/honeyman.cpp b/idlib/hashing/honeyman.cpp deleted file mode 100644 index dccea92c2..000000000 --- a/idlib/hashing/honeyman.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#define HONEYMAN_INIT_VALUE 0x00000000L -#define HONEYMAN_XOR_VALUE 0x00000000L - -#ifdef CREATE_CRC_TABLE - -static unsigned long crctable[256]; - -/* - Create the CRC table for the simplified version of the pathalias hashing function. - Thanks to Steve Belovin and Peter Honeyman - - This fast table calculation works only if POLY is a prime polynomial - in the field of integers modulo 2. Since the coefficients of a - 32-bit polynomial won't fit in a 32-bit word, the high-order bit is - implicit. IT MUST ALSO BE THE CASE that the coefficients of orders - 31 down to 25 are zero. Happily, we have candidates, from - E. J. Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962): - x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0 - x^31 + x^3 + x^0 - - We reverse the bits to get: - 111101010000000000000000000000001 but drop the last 1 - f 5 0 0 0 0 0 0 - 010010000000000000000000000000001 ditto, for 31-bit crc - 4 8 0 0 0 0 0 0 -*/ - -void make_crc_table( void ) { - - #define POLY 0x48000000L /* 31-bit polynomial (avoids sign problems) */ - - for ( int i = 0; i < 128; i++ ) { - int sum = 0; - for ( int j = 7 - 1; j >= 0; --j ) { - if ( i & ( 1 << j ) ) { - sum ^= POLY >> j; - } - } - crctable[i] = sum; - } -} - -#else - -static unsigned long crctable[256] = { - 0x00000000L, 0x48000000L, 0x24000000L, 0x6c000000L, - 0x12000000L, 0x5a000000L, 0x36000000L, 0x7e000000L, - 0x09000000L, 0x41000000L, 0x2d000000L, 0x65000000L, - 0x1b000000L, 0x53000000L, 0x3f000000L, 0x77000000L, - 0x04800000L, 0x4c800000L, 0x20800000L, 0x68800000L, - 0x16800000L, 0x5e800000L, 0x32800000L, 0x7a800000L, - 0x0d800000L, 0x45800000L, 0x29800000L, 0x61800000L, - 0x1f800000L, 0x57800000L, 0x3b800000L, 0x73800000L, - 0x02400000L, 0x4a400000L, 0x26400000L, 0x6e400000L, - 0x10400000L, 0x58400000L, 0x34400000L, 0x7c400000L, - 0x0b400000L, 0x43400000L, 0x2f400000L, 0x67400000L, - 0x19400000L, 0x51400000L, 0x3d400000L, 0x75400000L, - 0x06c00000L, 0x4ec00000L, 0x22c00000L, 0x6ac00000L, - 0x14c00000L, 0x5cc00000L, 0x30c00000L, 0x78c00000L, - 0x0fc00000L, 0x47c00000L, 0x2bc00000L, 0x63c00000L, - 0x1dc00000L, 0x55c00000L, 0x39c00000L, 0x71c00000L, - 0x01200000L, 0x49200000L, 0x25200000L, 0x6d200000L, - 0x13200000L, 0x5b200000L, 0x37200000L, 0x7f200000L, - 0x08200000L, 0x40200000L, 0x2c200000L, 0x64200000L, - 0x1a200000L, 0x52200000L, 0x3e200000L, 0x76200000L, - 0x05a00000L, 0x4da00000L, 0x21a00000L, 0x69a00000L, - 0x17a00000L, 0x5fa00000L, 0x33a00000L, 0x7ba00000L, - 0x0ca00000L, 0x44a00000L, 0x28a00000L, 0x60a00000L, - 0x1ea00000L, 0x56a00000L, 0x3aa00000L, 0x72a00000L, - 0x03600000L, 0x4b600000L, 0x27600000L, 0x6f600000L, - 0x11600000L, 0x59600000L, 0x35600000L, 0x7d600000L, - 0x0a600000L, 0x42600000L, 0x2e600000L, 0x66600000L, - 0x18600000L, 0x50600000L, 0x3c600000L, 0x74600000L, - 0x07e00000L, 0x4fe00000L, 0x23e00000L, 0x6be00000L, - 0x15e00000L, 0x5de00000L, 0x31e00000L, 0x79e00000L, - 0x0ee00000L, 0x46e00000L, 0x2ae00000L, 0x62e00000L, - 0x1ce00000L, 0x54e00000L, 0x38e00000L, 0x70e00000L -}; - -#endif - -void Honeyman_InitChecksum( unsigned long &crcvalue ) { - crcvalue = HONEYMAN_INIT_VALUE; -} - -void Honeyman_Update( unsigned long &crcvalue, const byte data ) { - crcvalue = ( ( crcvalue >> 7 ) ^ crctable[ ( crcvalue ^ data ) & 0x7f ] ); -} - -void Honeyman_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ) { - unsigned long crc; - const unsigned char *buf = (const unsigned char *) data; - - crc = crcvalue; - while( length-- ) { - crc = ( ( crc >> 7 ) ^ crctable[ ( crc ^ *buf++ ) & 0x7f ] ); - } - crcvalue = crc; -} - -void Honeyman_FinishChecksum( unsigned long &crcvalue ) { - crcvalue ^= HONEYMAN_XOR_VALUE; -} - -unsigned long Honeyman_BlockChecksum( const void *data, int length ) { - unsigned long crc; - - Honeyman_InitChecksum( crc ); - Honeyman_UpdateChecksum( crc, data, length ); - Honeyman_FinishChecksum( crc ); - return crc; -} diff --git a/idlib/hashing/honeyman.h b/idlib/hashing/honeyman.h deleted file mode 100644 index d76ff9317..000000000 --- a/idlib/hashing/honeyman.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __HONEYMAN_H__ -#define __HONEYMAN_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the simplified version of the pathalias hashing - function by Steve Belovin and Peter Honeyman. - -=============================================================================== -*/ - -void Honeyman_InitChecksum( unsigned long &crcvalue ); -void Honeyman_UpdateChecksum( unsigned long &crcvalue, const void *data, int length ); -void Honeyman_FinishChecksum( unsigned long &crcvalue ); -unsigned long Honeyman_BlockChecksum( const void *data, int length ); - -#endif /* !__HONEYMAN_H__ */ diff --git a/idlib/hashing/md4.cpp b/idlib/hashing/md4.cpp deleted file mode 100644 index 3c858108b..000000000 --- a/idlib/hashing/md4.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* - RSA Data Security, Inc., MD4 message-digest algorithm. (RFC1320) -*/ - -/* - -Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD4 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD4 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - -*/ - -/* POINTER defines a generic pointer type */ -typedef unsigned char *POINTER; - -/* UINT2 defines a two byte word */ -typedef unsigned short int UINT2; - -/* UINT4 defines a four byte word */ -typedef unsigned long int UINT4; - -/* MD4 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD4_CTX; - -/* Constants for MD4Transform routine. */ -#define S11 3 -#define S12 7 -#define S13 11 -#define S14 19 -#define S21 3 -#define S22 5 -#define S23 9 -#define S24 13 -#define S31 3 -#define S32 9 -#define S33 11 -#define S34 15 - -static unsigned char PADDING[64] = { -0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G and H are basic MD4 functions. */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) - -/* ROTATE_LEFT rotates x left n bits. */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));} - -#define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; (a) = ROTATE_LEFT ((a), (s));} - -#define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; (a) = ROTATE_LEFT ((a), (s));} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ -static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) { - unsigned int i, j; - - for ( i = 0, j = 0; j < len; i++, j += 4 ) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ -static void Decode( UINT4 *output, const unsigned char *input, unsigned int len ) { - unsigned int i, j; - - for ( i = 0, j = 0; j < len; i++, j += 4 ) { - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); - } -} - -/* MD4 basic transformation. Transforms state based on block. */ -static void MD4_Transform( UINT4 state[4], const unsigned char block[64] ) { - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11); /* 1 */ - FF (d, a, b, c, x[ 1], S12); /* 2 */ - FF (c, d, a, b, x[ 2], S13); /* 3 */ - FF (b, c, d, a, x[ 3], S14); /* 4 */ - FF (a, b, c, d, x[ 4], S11); /* 5 */ - FF (d, a, b, c, x[ 5], S12); /* 6 */ - FF (c, d, a, b, x[ 6], S13); /* 7 */ - FF (b, c, d, a, x[ 7], S14); /* 8 */ - FF (a, b, c, d, x[ 8], S11); /* 9 */ - FF (d, a, b, c, x[ 9], S12); /* 10 */ - FF (c, d, a, b, x[10], S13); /* 11 */ - FF (b, c, d, a, x[11], S14); /* 12 */ - FF (a, b, c, d, x[12], S11); /* 13 */ - FF (d, a, b, c, x[13], S12); /* 14 */ - FF (c, d, a, b, x[14], S13); /* 15 */ - FF (b, c, d, a, x[15], S14); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 0], S21); /* 17 */ - GG (d, a, b, c, x[ 4], S22); /* 18 */ - GG (c, d, a, b, x[ 8], S23); /* 19 */ - GG (b, c, d, a, x[12], S24); /* 20 */ - GG (a, b, c, d, x[ 1], S21); /* 21 */ - GG (d, a, b, c, x[ 5], S22); /* 22 */ - GG (c, d, a, b, x[ 9], S23); /* 23 */ - GG (b, c, d, a, x[13], S24); /* 24 */ - GG (a, b, c, d, x[ 2], S21); /* 25 */ - GG (d, a, b, c, x[ 6], S22); /* 26 */ - GG (c, d, a, b, x[10], S23); /* 27 */ - GG (b, c, d, a, x[14], S24); /* 28 */ - GG (a, b, c, d, x[ 3], S21); /* 29 */ - GG (d, a, b, c, x[ 7], S22); /* 30 */ - GG (c, d, a, b, x[11], S23); /* 31 */ - GG (b, c, d, a, x[15], S24); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 0], S31); /* 33 */ - HH (d, a, b, c, x[ 8], S32); /* 34 */ - HH (c, d, a, b, x[ 4], S33); /* 35 */ - HH (b, c, d, a, x[12], S34); /* 36 */ - HH (a, b, c, d, x[ 2], S31); /* 37 */ - HH (d, a, b, c, x[10], S32); /* 38 */ - HH (c, d, a, b, x[ 6], S33); /* 39 */ - HH (b, c, d, a, x[14], S34); /* 40 */ - HH (a, b, c, d, x[ 1], S31); /* 41 */ - HH (d, a, b, c, x[ 9], S32); /* 42 */ - HH (c, d, a, b, x[ 5], S33); /* 43 */ - HH (b, c, d, a, x[13], S34); /* 44 */ - HH (a, b, c, d, x[ 3], S31); /* 45 */ - HH (d, a, b, c, x[11], S32); /* 46 */ - HH (c, d, a, b, x[ 7], S33); /* 47 */ - HH (b, c, d, a, x[15], S34); /* 48 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information.*/ - memset ((POINTER)x, 0, sizeof (x)); -} - -/* MD4 initialization. Begins an MD4 operation, writing a new context. */ -void MD4_Init( MD4_CTX *context ) { - context->count[0] = context->count[1] = 0; - - /* Load magic initialization constants.*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */ -void MD4_Update( MD4_CTX *context, const unsigned char *input, unsigned int inputLen ) { - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3)) { - context->count[1]++; - } - - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - index; - - /* Transform as many times as possible.*/ - if ( inputLen >= partLen ) { - memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD4_Transform (context->state, context->buffer); - - for ( i = partLen; i + 63 < inputLen; i += 64 ) { - MD4_Transform (context->state, &input[i]); - } - - index = 0; - } else { - i = 0; - } - - /* Buffer remaining input */ - memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); -} - -/* MD4 finalization. Ends an MD4 message-digest operation, writing the message digest and zeroizing the context. */ -void MD4_Final( MD4_CTX *context, unsigned char digest[16] ) { - unsigned char bits[8]; - unsigned int index, padLen; - - /* Save number of bits */ - Encode( bits, context->count, 8 ); - - /* Pad out to 56 mod 64.*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD4_Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD4_Update( context, bits, 8 ); - - /* Store state in digest */ - Encode( digest, context->state, 16 ); - - /* Zeroize sensitive information.*/ - memset ((POINTER)context, 0, sizeof (*context)); -} - -/* -=============== -MD4_BlockChecksum -=============== -*/ -unsigned long MD4_BlockChecksum( const void *data, int length ) { - unsigned long digest[4]; - unsigned long val; - MD4_CTX ctx; - - MD4_Init( &ctx ); - MD4_Update( &ctx, (unsigned char *)data, length ); - MD4_Final( &ctx, (unsigned char *)digest ); - - val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; - - return val; -} diff --git a/idlib/hashing/md4.h b/idlib/hashing/md4.h deleted file mode 100644 index ca7202786..000000000 --- a/idlib/hashing/md4.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __MD4_H__ -#define __MD4_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the MD4 message-digest algorithm. - -=============================================================================== -*/ - -unsigned long MD4_BlockChecksum( const void *data, int length ); - -#endif /* !__MD4_H__ */ diff --git a/idlib/hashing/md5.cpp b/idlib/hashing/md5.cpp deleted file mode 100644 index 58e7517d0..000000000 --- a/idlib/hashing/md5.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* - MD5 Message Digest Algorithm. (RFC1321) -*/ - -/* - -This code implements the MD5 message-digest algorithm. -The algorithm is due to Ron Rivest. This code was -written by Colin Plumb in 1993, no copyright is claimed. -This code is in the public domain; do with it what you wish. - -Equivalent code is available from RSA Data Security, Inc. -This code has been tested against that, and is equivalent, -except that you don't need to include two pages of legalese -with every copy. - -To compute the message digest of a chunk of bytes, declare an -MD5Context structure, pass it to MD5Init, call MD5Update as -needed on buffers full of bytes, and then call MD5Final, which -will fill a supplied 16-byte array with the digest. - -*/ - -/* MD5 context. */ -typedef struct -{ - unsigned int state[4]; - unsigned int bits[2]; - unsigned char in[64]; -} MD5_CTX; - -/* The four core functions - F1 is optimized somewhat */ -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* -================= -MD5_Transform - -The core of the MD5 algorithm, this alters an existing MD5 hash to -reflect the addition of 16 longwords of new data. MD5Update blocks -the data and converts bytes into longwords for this routine. -================= -*/ -void MD5_Transform( unsigned int state[4], unsigned int in[16] ) { - register unsigned int a, b, c, d; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - - LittleRevBytes( in, sizeof(unsigned int), 16 ); - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - LittleRevBytes( in, sizeof(unsigned int), 16 ); - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; -} - -/* -================== -MD5_Init - -MD5 initialization. Begins an MD5 operation, writing a new context. -================== -*/ -void MD5_Init( MD5_CTX *ctx ) { - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xefcdab89; - ctx->state[2] = 0x98badcfe; - ctx->state[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* -=================== -MD5_Update - -MD5 block update operation. Continues an MD5 message-digest operation, -processing another message block, and updating the context. -=================== -*/ -void MD5_Update( MD5_CTX *ctx, unsigned char const *buf, unsigned int len ) { - unsigned int t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ( ( ctx->bits[0] = t + ( (unsigned int) len << 3 ) ) < t ) { - ctx->bits[1]++; /* Carry from low to high */ - } - ctx->bits[1] += len >> 29; - - t = ( t >> 3 ) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if ( t ) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if ( len < t ) { - memcpy( p, buf, len ); - return; - } - memcpy( p, buf, t ); - MD5_Transform( ctx->state, (unsigned int *) ctx->in ); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while( len >= 64 ) { - memcpy( ctx->in, buf, 64 ); - MD5_Transform( ctx->state, (unsigned int *) ctx->in ); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - memcpy( ctx->in, buf, len ); -} - -/* -=============== -MD5_Final - -MD5 finalization. Ends an MD5 message-digest operation, -writing the message digest and zeroizing the context. -=============== -*/ -void MD5_Final( MD5_CTX *ctx, unsigned char digest[16] ) { - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = ( ctx->bits[0] >> 3 ) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if ( count < 8 ) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset( p, 0, count ); - MD5_Transform( ctx->state, (unsigned int *) ctx->in ); - - /* Now fill the next block with 56 bytes */ - memset( ctx->in, 0, 56 ); - } else { - /* Pad block to 56 bytes */ - memset( p, 0, count - 8 ); - } - - /* Append length in bits and transform */ - unsigned int val0 = ctx->bits[0]; - unsigned int val1 = ctx->bits[1]; - - ((unsigned int *) ctx->in)[14] = LittleLong( val0 ); - ((unsigned int *) ctx->in)[15] = LittleLong( val1 ); - - MD5_Transform( ctx->state, (unsigned int *) ctx->in ); - memcpy( digest, ctx->state, 16 ); - memset( ctx, 0, sizeof( ctx ) ); /* In case it's sensitive */ -} - -/* -=============== -MD5_BlockChecksum -=============== -*/ -unsigned long MD5_BlockChecksum( const void *data, int length ) { - unsigned long digest[4]; - unsigned long val; - MD5_CTX ctx; - - MD5_Init( &ctx ); - MD5_Update( &ctx, (unsigned char *)data, length ); - MD5_Final( &ctx, (unsigned char *)digest ); - - val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; - - return val; -} diff --git a/idlib/hashing/md5.h b/idlib/hashing/md5.h deleted file mode 100644 index 52674ca6e..000000000 --- a/idlib/hashing/md5.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -#ifndef __MD5_H__ -#define __MD5_H__ - -/* -=============================================================================== - - Calculates a checksum for a block of data - using the MD5 message-digest algorithm. - -=============================================================================== -*/ - -unsigned long MD5_BlockChecksum( const void *data, int length ); - -#endif /* !__MD5_H__ */ diff --git a/idlib/heap.cpp b/idlib/heap.cpp deleted file mode 100644 index 32efa3e49..000000000 --- a/idlib/heap.cpp +++ /dev/null @@ -1,1759 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../idlib/precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#ifndef USE_LIBC_MALLOC - #define USE_LIBC_MALLOC 0 -#endif - -#ifndef CRASH_ON_STATIC_ALLOCATION -// #define CRASH_ON_STATIC_ALLOCATION -#endif - -//=============================================================== -// -// idHeap -// -//=============================================================== - -#define SMALL_HEADER_SIZE ( (int) ( sizeof( byte ) + sizeof( byte ) ) ) -#define MEDIUM_HEADER_SIZE ( (int) ( sizeof( mediumHeapEntry_s ) + sizeof( byte ) ) ) -#define LARGE_HEADER_SIZE ( (int) ( sizeof( dword * ) + sizeof( byte ) ) ) - -#define ALIGN_SIZE( bytes ) ( ( (bytes) + ALIGN - 1 ) & ~(ALIGN - 1) ) -#define SMALL_ALIGN( bytes ) ( ALIGN_SIZE( (bytes) + SMALL_HEADER_SIZE ) - SMALL_HEADER_SIZE ) -#define MEDIUM_SMALLEST_SIZE ( ALIGN_SIZE( 256 ) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ) ) - - -class idHeap { - -public: - idHeap( void ); - ~idHeap( void ); // frees all associated data - void Init( void ); // initialize - void * Allocate( const dword bytes ); // allocate memory - void Free( void *p ); // free memory - void * Allocate16( const dword bytes );// allocate 16 byte aligned memory - void Free16( void *p ); // free 16 byte aligned memory - dword Msize( void *p ); // return size of data block - void Dump( void ); - - void AllocDefragBlock( void ); // hack for huge renderbumps - -private: - - enum { - ALIGN = 8 // memory alignment in bytes - }; - - enum { - INVALID_ALLOC = 0xdd, - SMALL_ALLOC = 0xaa, // small allocation - MEDIUM_ALLOC = 0xbb, // medium allocaction - LARGE_ALLOC = 0xcc // large allocaction - }; - - struct page_s { // allocation page - void * data; // data pointer to allocated memory - dword dataSize; // number of bytes of memory 'data' points to - page_s * next; // next free page in same page manager - page_s * prev; // used only when allocated - dword largestFree; // this data used by the medium-size heap manager - void * firstFree; // pointer to first free entry - }; - - struct mediumHeapEntry_s { - page_s * page; // pointer to page - dword size; // size of block - mediumHeapEntry_s * prev; // previous block - mediumHeapEntry_s * next; // next block - mediumHeapEntry_s * prevFree; // previous free block - mediumHeapEntry_s * nextFree; // next free block - dword freeBlock; // non-zero if free block - }; - - // variables - void * smallFirstFree[256/ALIGN+1]; // small heap allocator lists (for allocs of 1-255 bytes) - page_s * smallCurPage; // current page for small allocations - dword smallCurPageOffset; // byte offset in current page - page_s * smallFirstUsedPage; // first used page of the small heap manager - - page_s * mediumFirstFreePage; // first partially free page - page_s * mediumLastFreePage; // last partially free page - page_s * mediumFirstUsedPage; // completely used page - - page_s * largeFirstUsedPage; // first page used by the large heap manager - - page_s * swapPage; - - dword pagesAllocated; // number of pages currently allocated - dword pageSize; // size of one alloc page in bytes - - dword pageRequests; // page requests - dword OSAllocs; // number of allocs made to the OS - - int c_heapAllocRunningCount; - - void *defragBlock; // a single huge block that can be allocated - // at startup, then freed when needed - - // methods - page_s * AllocatePage( dword bytes ); // allocate page from the OS - void FreePage( idHeap::page_s *p ); // free an OS allocated page - - void * SmallAllocate( dword bytes ); // allocate memory (1-255 bytes) from small heap manager - void SmallFree( void *ptr ); // free memory allocated by small heap manager - - void * MediumAllocateFromPage( idHeap::page_s *p, dword sizeNeeded ); - void * MediumAllocate( dword bytes ); // allocate memory (256-32768 bytes) from medium heap manager - void MediumFree( void *ptr ); // free memory allocated by medium heap manager - - void * LargeAllocate( dword bytes ); // allocate large block from OS directly - void LargeFree( void *ptr ); // free memory allocated by large heap manager - - void ReleaseSwappedPages( void ); - void FreePageReal( idHeap::page_s *p ); -}; - - -/* -================ -idHeap::Init -================ -*/ -void idHeap::Init () { - OSAllocs = 0; - pageRequests = 0; - pageSize = 65536 - sizeof( idHeap::page_s ); - pagesAllocated = 0; // reset page allocation counter - - largeFirstUsedPage = NULL; // init large heap manager - swapPage = NULL; - - memset( smallFirstFree, 0, sizeof(smallFirstFree) ); // init small heap manager - smallFirstUsedPage = NULL; - smallCurPage = AllocatePage( pageSize ); - assert( smallCurPage ); - smallCurPageOffset = SMALL_ALIGN( 0 ); - - defragBlock = NULL; - - mediumFirstFreePage = NULL; // init medium heap manager - mediumLastFreePage = NULL; - mediumFirstUsedPage = NULL; - - c_heapAllocRunningCount = 0; -} - -/* -================ -idHeap::idHeap -================ -*/ -idHeap::idHeap( void ) { - Init(); -} - -/* -================ -idHeap::~idHeap - - returns all allocated memory back to OS -================ -*/ -idHeap::~idHeap( void ) { - - idHeap::page_s *p; - - if ( smallCurPage ) { - FreePage( smallCurPage ); // free small-heap current allocation page - } - p = smallFirstUsedPage; // free small-heap allocated pages - while( p ) { - idHeap::page_s *next = p->next; - FreePage( p ); - p= next; - } - - p = largeFirstUsedPage; // free large-heap allocated pages - while( p ) { - idHeap::page_s *next = p->next; - FreePage( p ); - p = next; - } - - p = mediumFirstFreePage; // free medium-heap allocated pages - while( p ) { - idHeap::page_s *next = p->next; - FreePage( p ); - p = next; - } - - p = mediumFirstUsedPage; // free medium-heap allocated completely used pages - while( p ) { - idHeap::page_s *next = p->next; - FreePage( p ); - p = next; - } - - ReleaseSwappedPages(); - - if ( defragBlock ) { - free( defragBlock ); - } - - assert( pagesAllocated == 0 ); -} - -/* -================ -idHeap::AllocDefragBlock -================ -*/ -void idHeap::AllocDefragBlock( void ) { - int size = 0x40000000; - - if ( defragBlock ) { - return; - } -#pragma warning( push ) -#pragma warning( disable : 4127 ) - while( true ) { - defragBlock = malloc( size ); - if ( defragBlock ) { - break; - } - size >>= 1; - } -#pragma warning( pop ) - idLib::common->Printf( "Allocated a %i mb defrag block\n", size / (1024*1024) ); -} - -/* -================ -idHeap::Allocate -================ -*/ -void *idHeap::Allocate( const dword bytes ) { - if ( !bytes ) { - return NULL; - } - c_heapAllocRunningCount++; - -#if USE_LIBC_MALLOC - return malloc( bytes ); -#else - if ( !(bytes & ~255) ) { - return SmallAllocate( bytes ); - } - if ( !(bytes & ~32767) ) { - return MediumAllocate( bytes ); - } - return LargeAllocate( bytes ); -#endif -} - -/* -================ -idHeap::Free -================ -*/ -void idHeap::Free( void *p ) { - if ( !p ) { - return; - } - c_heapAllocRunningCount--; - -#if USE_LIBC_MALLOC - free( p ); -#else - switch( ((byte *)(p))[-1] ) { - case SMALL_ALLOC: { - SmallFree( p ); - break; - } - case MEDIUM_ALLOC: { - MediumFree( p ); - break; - } - case LARGE_ALLOC: { - LargeFree( p ); - break; - } - default: { - idLib::common->FatalError( "idHeap::Free: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) ); - break; - } - } -#endif -} - -/* -================ -idHeap::Allocate16 -================ -*/ -void *idHeap::Allocate16( const dword bytes ) { - byte *ptr, *alignedPtr; - - ptr = (byte *) malloc( bytes + 16 + 4 ); - if ( !ptr ) { - if ( defragBlock ) { - idLib::common->Printf( "Freeing defragBlock on alloc of %i.\n", bytes ); - free( defragBlock ); - defragBlock = NULL; - ptr = (byte *) malloc( bytes + 16 + 4 ); - AllocDefragBlock(); - } - if ( !ptr ) { - common->FatalError( "malloc failure for %i", bytes ); - } - } - alignedPtr = (byte *) ( ( (int) ptr ) + 15 & ~15 ); - if ( alignedPtr - ptr < 4 ) { - alignedPtr += 16; - } - *((int *)(alignedPtr - 4)) = (int) ptr; - return (void *) alignedPtr; -} - -/* -================ -idHeap::Free16 -================ -*/ -void idHeap::Free16( void *p ) { - free( (void *) *((int *) (( (byte *) p ) - 4)) ); -} - -/* -================ -idHeap::Msize - - returns size of allocated memory block - p = pointer to memory block - Notes: size may not be the same as the size in the original - allocation request (due to block alignment reasons). -================ -*/ -dword idHeap::Msize( void *p ) { - - if ( !p ) { - return 0; - } - -#if USE_LIBC_MALLOC - #ifdef _WIN32 - return _msize( p ); - #else - return 0; - #endif -#else - switch( ((byte *)(p))[-1] ) { - case SMALL_ALLOC: { - return SMALL_ALIGN( ((byte *)(p))[-SMALL_HEADER_SIZE] * ALIGN ); - } - case MEDIUM_ALLOC: { - return ((mediumHeapEntry_s *)(((byte *)(p)) - ALIGN_SIZE( MEDIUM_HEADER_SIZE )))->size - ALIGN_SIZE( MEDIUM_HEADER_SIZE ); - } - case LARGE_ALLOC: { - return ((idHeap::page_s*)(*((dword *)(((byte *)p) - ALIGN_SIZE( LARGE_HEADER_SIZE )))))->dataSize - ALIGN_SIZE( LARGE_HEADER_SIZE ); - } - default: { - idLib::common->FatalError( "idHeap::Msize: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) ); - return 0; - } - } -#endif -} - -/* -================ -idHeap::Dump - - dump contents of the heap -================ -*/ -void idHeap::Dump( void ) { - idHeap::page_s *pg; - - for ( pg = smallFirstUsedPage; pg; pg = pg->next ) { - idLib::common->Printf( "%p bytes %-8d (in use by small heap)\n", pg->data, pg->dataSize); - } - - if ( smallCurPage ) { - pg = smallCurPage; - idLib::common->Printf( "%p bytes %-8d (small heap active page)\n", pg->data, pg->dataSize ); - } - - for ( pg = mediumFirstUsedPage; pg; pg = pg->next ) { - idLib::common->Printf( "%p bytes %-8d (completely used by medium heap)\n", pg->data, pg->dataSize ); - } - - for ( pg = mediumFirstFreePage; pg; pg = pg->next ) { - idLib::common->Printf( "%p bytes %-8d (partially used by medium heap)\n", pg->data, pg->dataSize ); - } - - for ( pg = largeFirstUsedPage; pg; pg = pg->next ) { - idLib::common->Printf( "%p bytes %-8d (fully used by large heap)\n", pg->data, pg->dataSize ); - } - - idLib::common->Printf( "pages allocated : %d\n", pagesAllocated ); -} - -/* -================ -idHeap::FreePageReal - - frees page to be used by the OS - p = page to free -================ -*/ -void idHeap::FreePageReal( idHeap::page_s *p ) { - assert( p ); - ::free( p ); -} - -/* -================ -idHeap::ReleaseSwappedPages - - releases the swap page to OS -================ -*/ -void idHeap::ReleaseSwappedPages () { - if ( swapPage ) { - FreePageReal( swapPage ); - } - swapPage = NULL; -} - -/* -================ -idHeap::AllocatePage - - allocates memory from the OS - bytes = page size in bytes - returns pointer to page -================ -*/ -idHeap::page_s* idHeap::AllocatePage( dword bytes ) { - idHeap::page_s* p; - - pageRequests++; - - if ( swapPage && swapPage->dataSize == bytes ) { // if we've got a swap page somewhere - p = swapPage; - swapPage = NULL; - } - else { - dword size; - - size = bytes + sizeof(idHeap::page_s); - - p = (idHeap::page_s *) ::malloc( size + ALIGN - 1 ); - if ( !p ) { - if ( defragBlock ) { - idLib::common->Printf( "Freeing defragBlock on alloc of %i.\n", size + ALIGN - 1 ); - free( defragBlock ); - defragBlock = NULL; - p = (idHeap::page_s *) ::malloc( size + ALIGN - 1 ); - AllocDefragBlock(); - } - if ( !p ) { - common->FatalError( "malloc failure for %i", bytes ); - } - } - - p->data = (void *) ALIGN_SIZE( (int)((byte *)(p)) + sizeof( idHeap::page_s ) ); - p->dataSize = size - sizeof(idHeap::page_s); - p->firstFree = NULL; - p->largestFree = 0; - OSAllocs++; - } - - p->prev = NULL; - p->next = NULL; - - pagesAllocated++; - - return p; -} - -/* -================ -idHeap::FreePage - - frees a page back to the operating system - p = pointer to page -================ -*/ -void idHeap::FreePage( idHeap::page_s *p ) { - assert( p ); - - if ( p->dataSize == pageSize && !swapPage ) { // add to swap list? - swapPage = p; - } - else { - FreePageReal( p ); - } - - pagesAllocated--; -} - -//=============================================================== -// -// small heap code -// -//=============================================================== - -/* -================ -idHeap::SmallAllocate - - allocate memory (1-255 bytes) from the small heap manager - bytes = number of bytes to allocate - returns pointer to allocated memory -================ -*/ -void *idHeap::SmallAllocate( dword bytes ) { - // we need the at least sizeof( dword ) bytes for the free list - if ( bytes < sizeof( dword ) ) { - bytes = sizeof( dword ); - } - - // increase the number of bytes if necessary to make sure the next small allocation is aligned - bytes = SMALL_ALIGN( bytes ); - - byte *smallBlock = (byte *)(smallFirstFree[bytes / ALIGN]); - if ( smallBlock ) { - dword *link = (dword *)(smallBlock + SMALL_HEADER_SIZE); - smallBlock[1] = SMALL_ALLOC; // allocation identifier - smallFirstFree[bytes / ALIGN] = (void *)(*link); - return (void *)(link); - } - - dword bytesLeft = (long)(pageSize) - smallCurPageOffset; - // if we need to allocate a new page - if ( bytes >= bytesLeft ) { - - smallCurPage->next = smallFirstUsedPage; - smallFirstUsedPage = smallCurPage; - smallCurPage = AllocatePage( pageSize ); - if ( !smallCurPage ) { - return NULL; - } - // make sure the first allocation is aligned - smallCurPageOffset = SMALL_ALIGN( 0 ); - } - - smallBlock = ((byte *)smallCurPage->data) + smallCurPageOffset; - smallBlock[0] = (byte)(bytes / ALIGN); // write # of bytes/ALIGN - smallBlock[1] = SMALL_ALLOC; // allocation identifier - smallCurPageOffset += bytes + SMALL_HEADER_SIZE; // increase the offset on the current page - return ( smallBlock + SMALL_HEADER_SIZE ); // skip the first two bytes -} - -/* -================ -idHeap::SmallFree - - frees a block of memory allocated by SmallAllocate() call - data = pointer to block of memory -================ -*/ -void idHeap::SmallFree( void *ptr ) { - ((byte *)(ptr))[-1] = INVALID_ALLOC; - - byte *d = ( (byte *)ptr ) - SMALL_HEADER_SIZE; - dword *dt = (dword *)ptr; - // index into the table with free small memory blocks - dword ix = *d; - - // check if the index is correct - if ( ix > (256 / ALIGN) ) { - idLib::common->FatalError( "SmallFree: invalid memory block" ); - } - - *dt = (dword)smallFirstFree[ix]; // write next index - smallFirstFree[ix] = (void *)d; // link -} - -//=============================================================== -// -// medium heap code -// -// Medium-heap allocated pages not returned to OS until heap destructor -// called (re-used instead on subsequent medium-size malloc requests). -// -//=============================================================== - -/* -================ -idHeap::MediumAllocateFromPage - - performs allocation using the medium heap manager from a given page - p = page - sizeNeeded = # of bytes needed - returns pointer to allocated memory -================ -*/ -void *idHeap::MediumAllocateFromPage( idHeap::page_s *p, dword sizeNeeded ) { - - mediumHeapEntry_s *best,*nw = NULL; - byte *ret; - - best = (mediumHeapEntry_s *)(p->firstFree); // first block is largest - - assert( best ); - assert( best->size == p->largestFree ); - assert( best->size >= sizeNeeded ); - - // if we can allocate another block from this page after allocating sizeNeeded bytes - if ( best->size >= (dword)( sizeNeeded + MEDIUM_SMALLEST_SIZE ) ) { - nw = (mediumHeapEntry_s *)((byte *)best + best->size - sizeNeeded); - nw->page = p; - nw->prev = best; - nw->next = best->next; - nw->prevFree = NULL; - nw->nextFree = NULL; - nw->size = sizeNeeded; - nw->freeBlock = 0; // used block - if ( best->next ) { - best->next->prev = nw; - } - best->next = nw; - best->size -= sizeNeeded; - - p->largestFree = best->size; - } - else { - if ( best->prevFree ) { - best->prevFree->nextFree = best->nextFree; - } - else { - p->firstFree = (void *)best->nextFree; - } - if ( best->nextFree ) { - best->nextFree->prevFree = best->prevFree; - } - - best->prevFree = NULL; - best->nextFree = NULL; - best->freeBlock = 0; // used block - nw = best; - - p->largestFree = 0; - } - - ret = (byte *)(nw) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ); - ret[-1] = MEDIUM_ALLOC; // allocation identifier - - return (void *)(ret); -} - -/* -================ -idHeap::MediumAllocate - - allocate memory (256-32768 bytes) from medium heap manager - bytes = number of bytes to allocate - returns pointer to allocated memory -================ -*/ -void *idHeap::MediumAllocate( dword bytes ) { - idHeap::page_s *p; - void *data; - - dword sizeNeeded = ALIGN_SIZE( bytes ) + ALIGN_SIZE( MEDIUM_HEADER_SIZE ); - - // find first page with enough space - for ( p = mediumFirstFreePage; p; p = p->next ) { - if ( p->largestFree >= sizeNeeded ) { - break; - } - } - - if ( !p ) { // need to allocate new page? - p = AllocatePage( pageSize ); - if ( !p ) { - return NULL; // malloc failure! - } - p->prev = NULL; - p->next = mediumFirstFreePage; - if (p->next) { - p->next->prev = p; - } - else { - mediumLastFreePage = p; - } - - mediumFirstFreePage = p; - - p->largestFree = pageSize; - p->firstFree = (void *)p->data; - - mediumHeapEntry_s *e; - e = (mediumHeapEntry_s *)(p->firstFree); - e->page = p; - // make sure ((byte *)e + e->size) is aligned - e->size = pageSize & ~(ALIGN - 1); - e->prev = NULL; - e->next = NULL; - e->prevFree = NULL; - e->nextFree = NULL; - e->freeBlock = 1; - } - - data = MediumAllocateFromPage( p, sizeNeeded ); // allocate data from page - - // if the page can no longer serve memory, move it away from free list - // (so that it won't slow down the later alloc queries) - // this modification speeds up the pageWalk from O(N) to O(sqrt(N)) - // a call to free may swap this page back to the free list - - if ( p->largestFree < MEDIUM_SMALLEST_SIZE ) { - if ( p == mediumLastFreePage ) { - mediumLastFreePage = p->prev; - } - - if ( p == mediumFirstFreePage ) { - mediumFirstFreePage = p->next; - } - - if ( p->prev ) { - p->prev->next = p->next; - } - if ( p->next ) { - p->next->prev = p->prev; - } - - // link to "completely used" list - p->prev = NULL; - p->next = mediumFirstUsedPage; - if ( p->next ) { - p->next->prev = p; - } - mediumFirstUsedPage = p; - return data; - } - - // re-order linked list (so that next malloc query starts from current - // matching block) -- this speeds up both the page walks and block walks - - if ( p != mediumFirstFreePage ) { - assert( mediumLastFreePage ); - assert( mediumFirstFreePage ); - assert( p->prev); - - mediumLastFreePage->next = mediumFirstFreePage; - mediumFirstFreePage->prev = mediumLastFreePage; - mediumLastFreePage = p->prev; - p->prev->next = NULL; - p->prev = NULL; - mediumFirstFreePage = p; - } - - return data; -} - -/* -================ -idHeap::MediumFree - - frees a block allocated by the medium heap manager - ptr = pointer to data block -================ -*/ -void idHeap::MediumFree( void *ptr ) { - ((byte *)(ptr))[-1] = INVALID_ALLOC; - - mediumHeapEntry_s *e = (mediumHeapEntry_s *)((byte *)ptr - ALIGN_SIZE( MEDIUM_HEADER_SIZE )); - idHeap::page_s *p = e->page; - bool isInFreeList; - - isInFreeList = p->largestFree >= MEDIUM_SMALLEST_SIZE; - - assert( e->size ); - assert( e->freeBlock == 0 ); - - mediumHeapEntry_s *prev = e->prev; - - // if the previous block is free we can merge - if ( prev && prev->freeBlock ) { - prev->size += e->size; - prev->next = e->next; - if ( e->next ) { - e->next->prev = prev; - } - e = prev; - } - else { - e->prevFree = NULL; // link to beginning of free list - e->nextFree = (mediumHeapEntry_s *)p->firstFree; - if ( e->nextFree ) { - assert( !(e->nextFree->prevFree) ); - e->nextFree->prevFree = e; - } - - p->firstFree = e; - p->largestFree = e->size; - e->freeBlock = 1; // mark block as free - } - - mediumHeapEntry_s *next = e->next; - - // if the next block is free we can merge - if ( next && next->freeBlock ) { - e->size += next->size; - e->next = next->next; - - if ( next->next ) { - next->next->prev = e; - } - - if ( next->prevFree ) { - next->prevFree->nextFree = next->nextFree; - } - else { - assert( next == p->firstFree ); - p->firstFree = next->nextFree; - } - - if ( next->nextFree ) { - next->nextFree->prevFree = next->prevFree; - } - } - - if ( p->firstFree ) { - p->largestFree = ((mediumHeapEntry_s *)(p->firstFree))->size; - } - else { - p->largestFree = 0; - } - - // did e become the largest block of the page ? - - if ( e->size > p->largestFree ) { - assert( e != p->firstFree ); - p->largestFree = e->size; - - if ( e->prevFree ) { - e->prevFree->nextFree = e->nextFree; - } - if ( e->nextFree ) { - e->nextFree->prevFree = e->prevFree; - } - - e->nextFree = (mediumHeapEntry_s *)p->firstFree; - e->prevFree = NULL; - if ( e->nextFree ) { - e->nextFree->prevFree = e; - } - p->firstFree = e; - } - - // if page wasn't in free list (because it was near-full), move it back there - if ( !isInFreeList ) { - - // remove from "completely used" list - if ( p->prev ) { - p->prev->next = p->next; - } - if ( p->next ) { - p->next->prev = p->prev; - } - if ( p == mediumFirstUsedPage ) { - mediumFirstUsedPage = p->next; - } - - p->next = NULL; - p->prev = mediumLastFreePage; - - if ( mediumLastFreePage ) { - mediumLastFreePage->next = p; - } - mediumLastFreePage = p; - if ( !mediumFirstFreePage ) { - mediumFirstFreePage = p; - } - } -} - -//=============================================================== -// -// large heap code -// -//=============================================================== - -/* -================ -idHeap::LargeAllocate - - allocates a block of memory from the operating system - bytes = number of bytes to allocate - returns pointer to allocated memory -================ -*/ -void *idHeap::LargeAllocate( dword bytes ) { - idHeap::page_s *p = AllocatePage( bytes + ALIGN_SIZE( LARGE_HEADER_SIZE ) ); - - assert( p ); - - if ( !p ) { - return NULL; - } - - byte * d = (byte*)(p->data) + ALIGN_SIZE( LARGE_HEADER_SIZE ); - dword * dw = (dword*)(d - ALIGN_SIZE( LARGE_HEADER_SIZE )); - dw[0] = (dword)p; // write pointer back to page table - d[-1] = LARGE_ALLOC; // allocation identifier - - // link to 'large used page list' - p->prev = NULL; - p->next = largeFirstUsedPage; - if ( p->next ) { - p->next->prev = p; - } - largeFirstUsedPage = p; - - return (void *)(d); -} - -/* -================ -idHeap::LargeFree - - frees a block of memory allocated by the 'large memory allocator' - p = pointer to allocated memory -================ -*/ -void idHeap::LargeFree( void *ptr) { - idHeap::page_s* pg; - - ((byte *)(ptr))[-1] = INVALID_ALLOC; - - // get page pointer - pg = (idHeap::page_s *)(*((dword *)(((byte *)ptr) - ALIGN_SIZE( LARGE_HEADER_SIZE )))); - - // unlink from doubly linked list - if ( pg->prev ) { - pg->prev->next = pg->next; - } - if ( pg->next ) { - pg->next->prev = pg->prev; - } - if ( pg == largeFirstUsedPage ) { - largeFirstUsedPage = pg->next; - } - pg->next = pg->prev = NULL; - - FreePage(pg); -} - -//=============================================================== -// -// memory allocation all in one place -// -//=============================================================== - -#undef new - -static idHeap * mem_heap = NULL; -static memoryStats_t mem_total_allocs = { 0, 0x0fffffff, -1, 0 }; -static memoryStats_t mem_frame_allocs; -static memoryStats_t mem_frame_frees; - -/* -================== -Mem_ClearFrameStats -================== -*/ -void Mem_ClearFrameStats( void ) { - mem_frame_allocs.num = mem_frame_frees.num = 0; - mem_frame_allocs.minSize = mem_frame_frees.minSize = 0x0fffffff; - mem_frame_allocs.maxSize = mem_frame_frees.maxSize = -1; - mem_frame_allocs.totalSize = mem_frame_frees.totalSize = 0; -} - -/* -================== -Mem_GetFrameStats -================== -*/ -void Mem_GetFrameStats( memoryStats_t &allocs, memoryStats_t &frees ) { - allocs = mem_frame_allocs; - frees = mem_frame_frees; -} - -/* -================== -Mem_GetStats -================== -*/ -void Mem_GetStats( memoryStats_t &stats ) { - stats = mem_total_allocs; -} - -/* -================== -Mem_UpdateStats -================== -*/ -void Mem_UpdateStats( memoryStats_t &stats, int size ) { - stats.num++; - if ( size < stats.minSize ) { - stats.minSize = size; - } - if ( size > stats.maxSize ) { - stats.maxSize = size; - } - stats.totalSize += size; -} - -/* -================== -Mem_UpdateAllocStats -================== -*/ -void Mem_UpdateAllocStats( int size ) { - Mem_UpdateStats( mem_frame_allocs, size ); - Mem_UpdateStats( mem_total_allocs, size ); -} - -/* -================== -Mem_UpdateFreeStats -================== -*/ -void Mem_UpdateFreeStats( int size ) { - Mem_UpdateStats( mem_frame_frees, size ); - mem_total_allocs.num--; - mem_total_allocs.totalSize -= size; -} - - -#ifndef ID_DEBUG_MEMORY - -/* -================== -Mem_Alloc -================== -*/ -void *Mem_Alloc( const int size ) { - if ( !size ) { - return NULL; - } - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - return malloc( size ); - } - void *mem = mem_heap->Allocate( size ); - Mem_UpdateAllocStats( mem_heap->Msize( mem ) ); - return mem; -} - -/* -================== -Mem_Free -================== -*/ -void Mem_Free( void *ptr ) { - if ( !ptr ) { - return; - } - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - free( ptr ); - return; - } - Mem_UpdateFreeStats( mem_heap->Msize( ptr ) ); - mem_heap->Free( ptr ); -} - -/* -================== -Mem_Alloc16 -================== -*/ -void *Mem_Alloc16( const int size ) { - if ( !size ) { - return NULL; - } - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - return malloc( size ); - } - void *mem = mem_heap->Allocate16( size ); - // make sure the memory is 16 byte aligned - assert( ( ((int)mem) & 15) == 0 ); - return mem; -} - -/* -================== -Mem_Free16 -================== -*/ -void Mem_Free16( void *ptr ) { - if ( !ptr ) { - return; - } - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - free( ptr ); - return; - } - // make sure the memory is 16 byte aligned - assert( ( ((int)ptr) & 15) == 0 ); - mem_heap->Free16( ptr ); -} - -/* -================== -Mem_ClearedAlloc -================== -*/ -void *Mem_ClearedAlloc( const int size ) { - void *mem = Mem_Alloc( size ); - SIMDProcessor->Memset( mem, 0, size ); - return mem; -} - -/* -================== -Mem_ClearedAlloc -================== -*/ -void Mem_AllocDefragBlock( void ) { - mem_heap->AllocDefragBlock(); -} - -/* -================== -Mem_CopyString -================== -*/ -char *Mem_CopyString( const char *in ) { - char *out; - - out = (char *)Mem_Alloc( strlen(in) + 1 ); - strcpy( out, in ); - return out; -} - -/* -================== -Mem_Dump_f -================== -*/ -void Mem_Dump_f( const idCmdArgs &args ) { -} - -/* -================== -Mem_DumpCompressed_f -================== -*/ -void Mem_DumpCompressed_f( const idCmdArgs &args ) { -} - -/* -================== -Mem_Init -================== -*/ -void Mem_Init( void ) { - mem_heap = new idHeap; - Mem_ClearFrameStats(); -} - -/* -================== -Mem_Shutdown -================== -*/ -void Mem_Shutdown( void ) { - idHeap *m = mem_heap; - mem_heap = NULL; - delete m; -} - -/* -================== -Mem_EnableLeakTest -================== -*/ -void Mem_EnableLeakTest( const char *name ) { -} - - -#else /* !ID_DEBUG_MEMORY */ - -#undef Mem_Alloc -#undef Mem_ClearedAlloc -#undef Com_ClearedReAlloc -#undef Mem_Free -#undef Mem_CopyString -#undef Mem_Alloc16 -#undef Mem_Free16 - -#define MAX_CALLSTACK_DEPTH 6 - -// size of this struct must be a multiple of 16 bytes -typedef struct debugMemory_s { - const char * fileName; - int lineNumber; - int frameNumber; - int size; - address_t callStack[MAX_CALLSTACK_DEPTH]; - struct debugMemory_s * prev; - struct debugMemory_s * next; -} debugMemory_t; - -static debugMemory_t * mem_debugMemory = NULL; -static char mem_leakName[256] = ""; - -/* -================== -Mem_CleanupFileName -================== -*/ -const char *Mem_CleanupFileName( const char *fileName ) { - int i1, i2; - idStr newFileName; - static char newFileNames[4][MAX_STRING_CHARS]; - static int index; - - newFileName = fileName; - newFileName.BackSlashesToSlashes(); - i1 = newFileName.Find( "neo", false ); - if ( i1 >= 0 ) { - i1 = newFileName.Find( "/", false, i1 ); - newFileName = newFileName.Right( newFileName.Length() - ( i1 + 1 ) ); - } - while( 1 ) { - i1 = newFileName.Find( "/../" ); - if ( i1 <= 0 ) { - break; - } - i2 = i1 - 1; - while( i2 > 1 && newFileName[i2-1] != '/' ) { - i2--; - } - newFileName = newFileName.Left( i2 - 1 ) + newFileName.Right( newFileName.Length() - ( i1 + 4 ) ); - } - index = ( index + 1 ) & 3; - strncpy( newFileNames[index], newFileName.c_str(), sizeof( newFileNames[index] ) ); - return newFileNames[index]; -} - -/* -================== -Mem_Dump -================== -*/ -void Mem_Dump( const char *fileName ) { - int i, numBlocks, totalSize; - char dump[32], *ptr; - debugMemory_t *b; - idStr module, funcName; - FILE *f; - - f = fopen( fileName, "wb" ); - if ( !f ) { - return; - } - - totalSize = 0; - for ( numBlocks = 0, b = mem_debugMemory; b; b = b->next, numBlocks++ ) { - ptr = ((char *) b) + sizeof(debugMemory_t); - totalSize += b->size; - for ( i = 0; i < (sizeof(dump)-1) && i < b->size; i++) { - if ( ptr[i] >= 32 && ptr[i] < 127 ) { - dump[i] = ptr[i]; - } else { - dump[i] = '_'; - } - } - dump[i] = '\0'; - if ( ( b->size >> 10 ) != 0 ) { - fprintf( f, "size: %6d KB: %s, line: %d [%s], call stack: %s\r\n", ( b->size >> 10 ), Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) ); - } - else { - fprintf( f, "size: %7d B: %s, line: %d [%s], call stack: %s\r\n", b->size, Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) ); - } - } - - idLib::sys->ShutdownSymbols(); - - fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks ); - fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) ); - - fclose( f ); -} - -/* -================== -Mem_Dump_f -================== -*/ -void Mem_Dump_f( const idCmdArgs &args ) { - const char *fileName; - - if ( args.Argc() >= 2 ) { - fileName = args.Argv( 1 ); - } - else { - fileName = "memorydump.txt"; - } - Mem_Dump( fileName ); -} - -/* -================== -Mem_DumpCompressed -================== -*/ -typedef struct allocInfo_s { - const char * fileName; - int lineNumber; - int size; - int numAllocs; - address_t callStack[MAX_CALLSTACK_DEPTH]; - struct allocInfo_s * next; -} allocInfo_t; - -typedef enum { - MEMSORT_SIZE, - MEMSORT_LOCATION, - MEMSORT_NUMALLOCS, - MEMSORT_CALLSTACK -} memorySortType_t; - -void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sortCallStack, int numFrames ) { - int numBlocks, totalSize, r, j; - debugMemory_t *b; - allocInfo_t *a, *nexta, *allocInfo = NULL, *sortedAllocInfo = NULL, *prevSorted = NULL, *nextSorted = NULL; - idStr module, funcName; - FILE *f; - - // build list with memory allocations - totalSize = 0; - numBlocks = 0; - for ( b = mem_debugMemory; b; b = b->next ) { - - if ( numFrames && b->frameNumber < idLib::frameNumber - numFrames ) { - continue; - } - - numBlocks++; - totalSize += b->size; - - // search for an allocation from the same source location - for ( a = allocInfo; a; a = a->next ) { - if ( a->lineNumber != b->lineNumber ) { - continue; - } - for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) { - if ( a->callStack[j] != b->callStack[j] ) { - break; - } - } - if ( j < MAX_CALLSTACK_DEPTH ) { - continue; - } - if ( idStr::Cmp( a->fileName, b->fileName ) != 0 ) { - continue; - } - a->numAllocs++; - a->size += b->size; - break; - } - - // if this is an allocation from a new source location - if ( !a ) { - a = (allocInfo_t *) ::malloc( sizeof( allocInfo_t ) ); - a->fileName = b->fileName; - a->lineNumber = b->lineNumber; - a->size = b->size; - a->numAllocs = 1; - for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) { - a->callStack[j] = b->callStack[j]; - } - a->next = allocInfo; - allocInfo = a; - } - } - - // sort list - for ( a = allocInfo; a; a = nexta ) { - nexta = a->next; - - prevSorted = NULL; - switch( memSort ) { - // sort on size - case MEMSORT_SIZE: { - for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { - if ( a->size > nextSorted->size ) { - break; - } - prevSorted = nextSorted; - } - break; - } - // sort on file name and line number - case MEMSORT_LOCATION: { - for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { - r = idStr::Cmp( Mem_CleanupFileName( a->fileName ), Mem_CleanupFileName( nextSorted->fileName ) ); - if ( r < 0 || ( r == 0 && a->lineNumber < nextSorted->lineNumber ) ) { - break; - } - prevSorted = nextSorted; - } - break; - } - // sort on the number of allocations - case MEMSORT_NUMALLOCS: { - for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { - if ( a->numAllocs > nextSorted->numAllocs ) { - break; - } - prevSorted = nextSorted; - } - break; - } - // sort on call stack - case MEMSORT_CALLSTACK: { - for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) { - if ( a->callStack[sortCallStack] < nextSorted->callStack[sortCallStack] ) { - break; - } - prevSorted = nextSorted; - } - break; - } - } - if ( !prevSorted ) { - a->next = sortedAllocInfo; - sortedAllocInfo = a; - } - else { - prevSorted->next = a; - a->next = nextSorted; - } - } - - f = fopen( fileName, "wb" ); - if ( !f ) { - return; - } - - // write list to file - for ( a = sortedAllocInfo; a; a = nexta ) { - nexta = a->next; - fprintf( f, "size: %6d KB, allocs: %5d: %s, line: %d, call stack: %s\r\n", - (a->size >> 10), a->numAllocs, Mem_CleanupFileName(a->fileName), - a->lineNumber, idLib::sys->GetCallStackStr( a->callStack, MAX_CALLSTACK_DEPTH ) ); - ::free( a ); - } - - idLib::sys->ShutdownSymbols(); - - fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks ); - fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) ); - - fclose( f ); -} - -/* -================== -Mem_DumpCompressed_f -================== -*/ -void Mem_DumpCompressed_f( const idCmdArgs &args ) { - int argNum; - const char *arg, *fileName; - memorySortType_t memSort = MEMSORT_LOCATION; - int sortCallStack = 0, numFrames = 0; - - // get cmd-line options - argNum = 1; - arg = args.Argv( argNum ); - while( arg[0] == '-' ) { - arg = args.Argv( ++argNum ); - if ( idStr::Icmp( arg, "s" ) == 0 ) { - memSort = MEMSORT_SIZE; - } else if ( idStr::Icmp( arg, "l" ) == 0 ) { - memSort = MEMSORT_LOCATION; - } else if ( idStr::Icmp( arg, "a" ) == 0 ) { - memSort = MEMSORT_NUMALLOCS; - } else if ( idStr::Icmp( arg, "cs1" ) == 0 ) { - memSort = MEMSORT_CALLSTACK; - sortCallStack = 2; - } else if ( idStr::Icmp( arg, "cs2" ) == 0 ) { - memSort = MEMSORT_CALLSTACK; - sortCallStack = 1; - } else if ( idStr::Icmp( arg, "cs3" ) == 0 ) { - memSort = MEMSORT_CALLSTACK; - sortCallStack = 0; - } else if ( arg[0] == 'f' ) { - numFrames = atoi( arg + 1 ); - } else { - idLib::common->Printf( "memoryDumpCompressed [options] [filename]\n" - "options:\n" - " -s sort on size\n" - " -l sort on location\n" - " -a sort on the number of allocations\n" - " -cs1 sort on first function on call stack\n" - " -cs2 sort on second function on call stack\n" - " -cs3 sort on third function on call stack\n" - " -f only report allocations the last X frames\n" - "By default the memory allocations are sorted on location.\n" - "By default a 'memorydump.txt' is written if no file name is specified.\n" ); - return; - } - arg = args.Argv( ++argNum ); - } - if ( argNum >= args.Argc() ) { - fileName = "memorydump.txt"; - } else { - fileName = arg; - } - Mem_DumpCompressed( fileName, memSort, sortCallStack, numFrames ); -} - -/* -================== -Mem_AllocDebugMemory -================== -*/ -void *Mem_AllocDebugMemory( const int size, const char *fileName, const int lineNumber, const bool align16 ) { - void *p; - debugMemory_t *m; - - if ( !size ) { - return NULL; - } - - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - // NOTE: set a breakpoint here to find memory allocations before mem_heap is initialized - return malloc( size ); - } - - if ( align16 ) { - p = mem_heap->Allocate16( size + sizeof( debugMemory_t ) ); - } - else { - p = mem_heap->Allocate( size + sizeof( debugMemory_t ) ); - } - - Mem_UpdateAllocStats( size ); - - m = (debugMemory_t *) p; - m->fileName = fileName; - m->lineNumber = lineNumber; - m->frameNumber = idLib::frameNumber; - m->size = size; - m->next = mem_debugMemory; - m->prev = NULL; - if ( mem_debugMemory ) { - mem_debugMemory->prev = m; - } - mem_debugMemory = m; - idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH ); - - return ( ( (byte *) p ) + sizeof( debugMemory_t ) ); -} - -/* -================== -Mem_FreeDebugMemory -================== -*/ -void Mem_FreeDebugMemory( void *p, const char *fileName, const int lineNumber, const bool align16 ) { - debugMemory_t *m; - - if ( !p ) { - return; - } - - if ( !mem_heap ) { -#ifdef CRASH_ON_STATIC_ALLOCATION - *((int*)0x0) = 1; -#endif - // NOTE: set a breakpoint here to find memory being freed before mem_heap is initialized - free( p ); - return; - } - - m = (debugMemory_t *) ( ( (byte *) p ) - sizeof( debugMemory_t ) ); - - if ( m->size < 0 ) { - idLib::common->FatalError( "memory freed twice, first from %s, now from %s", idLib::sys->GetCallStackStr( m->callStack, MAX_CALLSTACK_DEPTH ), idLib::sys->GetCallStackCurStr( MAX_CALLSTACK_DEPTH ) ); - } - - Mem_UpdateFreeStats( m->size ); - - if ( m->next ) { - m->next->prev = m->prev; - } - if ( m->prev ) { - m->prev->next = m->next; - } - else { - mem_debugMemory = m->next; - } - - m->fileName = fileName; - m->lineNumber = lineNumber; - m->frameNumber = idLib::frameNumber; - m->size = -m->size; - idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH ); - - if ( align16 ) { - mem_heap->Free16( m ); - } - else { - mem_heap->Free( m ); - } -} - -/* -================== -Mem_Alloc -================== -*/ -void *Mem_Alloc( const int size, const char *fileName, const int lineNumber ) { - if ( !size ) { - return NULL; - } - return Mem_AllocDebugMemory( size, fileName, lineNumber, false ); -} - -/* -================== -Mem_Free -================== -*/ -void Mem_Free( void *ptr, const char *fileName, const int lineNumber ) { - if ( !ptr ) { - return; - } - Mem_FreeDebugMemory( ptr, fileName, lineNumber, false ); -} - -/* -================== -Mem_Alloc16 -================== -*/ -void *Mem_Alloc16( const int size, const char *fileName, const int lineNumber ) { - if ( !size ) { - return NULL; - } - void *mem = Mem_AllocDebugMemory( size, fileName, lineNumber, true ); - // make sure the memory is 16 byte aligned - assert( ( ((int)mem) & 15) == 0 ); - return mem; -} - -/* -================== -Mem_Free16 -================== -*/ -void Mem_Free16( void *ptr, const char *fileName, const int lineNumber ) { - if ( !ptr ) { - return; - } - // make sure the memory is 16 byte aligned - assert( ( ((int)ptr) & 15) == 0 ); - Mem_FreeDebugMemory( ptr, fileName, lineNumber, true ); -} - -/* -================== -Mem_ClearedAlloc -================== -*/ -void *Mem_ClearedAlloc( const int size, const char *fileName, const int lineNumber ) { - void *mem = Mem_Alloc( size, fileName, lineNumber ); - SIMDProcessor->Memset( mem, 0, size ); - return mem; -} - -/* -================== -Mem_CopyString -================== -*/ -char *Mem_CopyString( const char *in, const char *fileName, const int lineNumber ) { - char *out; - - out = (char *)Mem_Alloc( strlen(in) + 1, fileName, lineNumber ); - strcpy( out, in ); - return out; -} - -/* -================== -Mem_Init -================== -*/ -void Mem_Init( void ) { - mem_heap = new idHeap; -} - -/* -================== -Mem_Shutdown -================== -*/ -void Mem_Shutdown( void ) { - - if ( mem_leakName[0] != '\0' ) { - Mem_DumpCompressed( va( "%s_leak_size.txt", mem_leakName ), MEMSORT_SIZE, 0, 0 ); - Mem_DumpCompressed( va( "%s_leak_location.txt", mem_leakName ), MEMSORT_LOCATION, 0, 0 ); - Mem_DumpCompressed( va( "%s_leak_cs1.txt", mem_leakName ), MEMSORT_CALLSTACK, 2, 0 ); - } - - idHeap *m = mem_heap; - mem_heap = NULL; - delete m; -} - -/* -================== -Mem_EnableLeakTest -================== -*/ -void Mem_EnableLeakTest( const char *name ) { - idStr::Copynz( mem_leakName, name, sizeof( mem_leakName ) ); -} - -#endif /* !ID_DEBUG_MEMORY */ diff --git a/idlib/heap.h b/idlib/heap.h deleted file mode 100644 index 8d04aec5c..000000000 --- a/idlib/heap.h +++ /dev/null @@ -1,876 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __HEAP_H__ -#define __HEAP_H__ - -#include "math/math.h" // OrbWeaver: Max() macro - -#include - -/* -=============================================================================== - - Memory Management - - This is a replacement for the compiler heap code (i.e. "C" malloc() and - free() calls). On average 2.5-3.0 times faster than MSVC malloc()/free(). - Worst case performance is 1.65 times faster and best case > 70 times. - -=============================================================================== -*/ - - -typedef struct { - int num; - int minSize; - int maxSize; - int totalSize; -} memoryStats_t; - - -void Mem_Init( void ); -void Mem_Shutdown( void ); -void Mem_EnableLeakTest( const char *name ); -void Mem_ClearFrameStats( void ); -void Mem_GetFrameStats( memoryStats_t &allocs, memoryStats_t &frees ); -void Mem_GetStats( memoryStats_t &stats ); -void Mem_Dump_f( const class idCmdArgs &args ); -void Mem_DumpCompressed_f( const class idCmdArgs &args ); -void Mem_AllocDefragBlock( void ); - - -#ifndef ID_DEBUG_MEMORY - -void * Mem_Alloc( const int size ); -void * Mem_ClearedAlloc( const int size ); -void Mem_Free( void *ptr ); -char * Mem_CopyString( const char *in ); -void * Mem_Alloc16( const int size ); -void Mem_Free16( void *ptr ); - -#ifdef ID_REDIRECT_NEWDELETE - -__inline void *operator new( size_t s ) { - return Mem_Alloc( s ); -} -__inline void operator delete( void *p ) { - Mem_Free( p ); -} -__inline void *operator new[]( size_t s ) { - return Mem_Alloc( s ); -} -__inline void operator delete[]( void *p ) { - Mem_Free( p ); -} - -#endif - -#else /* ID_DEBUG_MEMORY */ - -void * Mem_Alloc( const int size, const char *fileName, const int lineNumber ); -void * Mem_ClearedAlloc( const int size, const char *fileName, const int lineNumber ); -void Mem_Free( void *ptr, const char *fileName, const int lineNumber ); -char * Mem_CopyString( const char *in, const char *fileName, const int lineNumber ); -void * Mem_Alloc16( const int size, const char *fileName, const int lineNumber ); -void Mem_Free16( void *ptr, const char *fileName, const int lineNumber ); - -#ifdef ID_REDIRECT_NEWDELETE - -__inline void *operator new( size_t s, int t1, int t2, char *fileName, int lineNumber ) { - return Mem_Alloc( s, fileName, lineNumber ); -} -__inline void operator delete( void *p, int t1, int t2, char *fileName, int lineNumber ) { - Mem_Free( p, fileName, lineNumber ); -} -__inline void *operator new[]( size_t s, int t1, int t2, char *fileName, int lineNumber ) { - return Mem_Alloc( s, fileName, lineNumber ); -} -__inline void operator delete[]( void *p, int t1, int t2, char *fileName, int lineNumber ) { - Mem_Free( p, fileName, lineNumber ); -} -__inline void *operator new( size_t s ) { - return Mem_Alloc( s, "", 0 ); -} -__inline void operator delete( void *p ) { - Mem_Free( p, "", 0 ); -} -__inline void *operator new[]( size_t s ) { - return Mem_Alloc( s, "", 0 ); -} -__inline void operator delete[]( void *p ) { - Mem_Free( p, "", 0 ); -} - -#define ID_DEBUG_NEW new( 0, 0, __FILE__, __LINE__ ) -#undef new -#define new ID_DEBUG_NEW - -#endif - -#define Mem_Alloc( size ) Mem_Alloc( size, __FILE__, __LINE__ ) -#define Mem_ClearedAlloc( size ) Mem_ClearedAlloc( size, __FILE__, __LINE__ ) -#define Mem_Free( ptr ) Mem_Free( ptr, __FILE__, __LINE__ ) -#define Mem_CopyString( s ) Mem_CopyString( s, __FILE__, __LINE__ ) -#define Mem_Alloc16( size ) Mem_Alloc16( size, __FILE__, __LINE__ ) -#define Mem_Free16( ptr ) Mem_Free16( ptr, __FILE__, __LINE__ ) - -#endif /* ID_DEBUG_MEMORY */ - - -/* -=============================================================================== - - Block based allocator for fixed size objects. - - All objects of the 'type' are properly constructed. - However, the constructor is not called for re-used objects. - -=============================================================================== -*/ - -template -class idBlockAlloc { -public: - idBlockAlloc( void ); - ~idBlockAlloc( void ); - - void Shutdown( void ); - - type * Alloc( void ); - void Free( type *element ); - - int GetTotalCount( void ) const { return total; } - int GetAllocCount( void ) const { return active; } - int GetFreeCount( void ) const { return total - active; } - -private: - typedef struct element_s { - struct element_s * next; - type t; - } element_t; - typedef struct block_s { - element_t elements[blockSize]; - struct block_s * next; - } block_t; - - block_t * blocks; - element_t * free; - int total; - int active; -}; - -template -idBlockAlloc::idBlockAlloc( void ) { - blocks = NULL; - free = NULL; - total = active = 0; -} - -template -idBlockAlloc::~idBlockAlloc( void ) { - Shutdown(); -} - -template -type *idBlockAlloc::Alloc( void ) { - if ( !free ) { - block_t *block = new block_t; - block->next = blocks; - blocks = block; - for ( int i = 0; i < blockSize; i++ ) { - block->elements[i].next = free; - free = &block->elements[i]; - } - total += blockSize; - } - active++; - element_t *element = free; - free = free->next; - element->next = NULL; - return &element->t; -} - -template -void idBlockAlloc::Free( type *t ) { - element_t *element = (element_t *)( ( (unsigned char *) t ) - ( (int) &((element_t *)0)->t ) ); - element->next = free; - free = element; - active--; -} - -template -void idBlockAlloc::Shutdown( void ) { - while( blocks ) { - block_t *block = blocks; - blocks = blocks->next; - delete block; - } - blocks = NULL; - free = NULL; - total = active = 0; -} - -/* -============================================================================== - - Dynamic allocator, simple wrapper for normal allocations which can - be interchanged with idDynamicBlockAlloc. - - No constructor is called for the 'type'. - Allocated blocks are always 16 byte aligned. - -============================================================================== -*/ - -template -class idDynamicAlloc { -public: - idDynamicAlloc( void ); - ~idDynamicAlloc( void ); - - void Init( void ); - void Shutdown( void ); - void SetFixedBlocks( int numBlocks ) {} - void SetLockMemory( bool lock ) {} - void FreeEmptyBaseBlocks( void ) {} - - type * Alloc( const int num ); - type * Resize( type *ptr, const int num ); - void Free( type *ptr ); - const char * CheckMemory( const type *ptr ) const; - - int GetNumBaseBlocks( void ) const { return 0; } - int GetBaseBlockMemory( void ) const { return 0; } - int GetNumUsedBlocks( void ) const { return numUsedBlocks; } - int GetUsedBlockMemory( void ) const { return usedBlockMemory; } - int GetNumFreeBlocks( void ) const { return 0; } - int GetFreeBlockMemory( void ) const { return 0; } - int GetNumEmptyBaseBlocks( void ) const { return 0; } - -private: - int numUsedBlocks; // number of used blocks - int usedBlockMemory; // total memory in used blocks - - int numAllocs; - int numResizes; - int numFrees; - - void Clear( void ); -}; - -template -idDynamicAlloc::idDynamicAlloc( void ) { - Clear(); -} - -template -idDynamicAlloc::~idDynamicAlloc( void ) { - Shutdown(); -} - -template -void idDynamicAlloc::Init( void ) { -} - -template -void idDynamicAlloc::Shutdown( void ) { - Clear(); -} - -template -type *idDynamicAlloc::Alloc( const int num ) { - numAllocs++; - if ( num <= 0 ) { - return NULL; - } - numUsedBlocks++; - usedBlockMemory += num * sizeof( type ); - return Mem_Alloc16( num * sizeof( type ) ); -} - -template -type *idDynamicAlloc::Resize( type *ptr, const int num ) { - - numResizes++; - - if ( ptr == NULL ) { - return Alloc( num ); - } - - if ( num <= 0 ) { - Free( ptr ); - return NULL; - } - - assert( 0 ); - return ptr; -} - -template -void idDynamicAlloc::Free( type *ptr ) { - numFrees++; - if ( ptr == NULL ) { - return; - } - Mem_Free16( ptr ); -} - -template -const char *idDynamicAlloc::CheckMemory( const type *ptr ) const { - return NULL; -} - -template -void idDynamicAlloc::Clear( void ) { - numUsedBlocks = 0; - usedBlockMemory = 0; - numAllocs = 0; - numResizes = 0; - numFrees = 0; -} - - -/* -============================================================================== - - Fast dynamic block allocator. - - No constructor is called for the 'type'. - Allocated blocks are always 16 byte aligned. - -============================================================================== -*/ - -#include "containers/btree.h" - -//#define DYNAMIC_BLOCK_ALLOC_CHECK - -template -class idDynamicBlock { -public: - type * GetMemory( void ) const { return (type *)( ( (byte *) this ) + sizeof( idDynamicBlock ) ); } - int GetSize( void ) const { return abs( size ); } - void SetSize( int s, bool isBaseBlock ) { size = isBaseBlock ? -s : s; } - bool IsBaseBlock( void ) const { return ( size < 0 ); } - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - int id[3]; - void * allocator; -#endif - - int size; // size in bytes of the block - idDynamicBlock * prev; // previous memory block - idDynamicBlock * next; // next memory block - idBTreeNode,int> *node; // node in the B-Tree with free blocks -}; - -template -class idDynamicBlockAlloc { -public: - idDynamicBlockAlloc( void ); - ~idDynamicBlockAlloc( void ); - - void Init( void ); - void Shutdown( void ); - void SetFixedBlocks( int numBlocks ); - void SetLockMemory( bool lock ); - void FreeEmptyBaseBlocks( void ); - - type * Alloc( const int num ); - type * Resize( type *ptr, const int num ); - void Free( type *ptr ); - const char * CheckMemory( const type *ptr ) const; - - int GetNumBaseBlocks( void ) const { return numBaseBlocks; } - int GetBaseBlockMemory( void ) const { return baseBlockMemory; } - int GetNumUsedBlocks( void ) const { return numUsedBlocks; } - int GetUsedBlockMemory( void ) const { return usedBlockMemory; } - int GetNumFreeBlocks( void ) const { return numFreeBlocks; } - int GetFreeBlockMemory( void ) const { return freeBlockMemory; } - int GetNumEmptyBaseBlocks( void ) const; - -private: - idDynamicBlock * firstBlock; // first block in list in order of increasing address - idDynamicBlock * lastBlock; // last block in list in order of increasing address - idBTree,int,4>freeTree; // B-Tree with free memory blocks - bool allowAllocs; // allow base block allocations - bool lockMemory; // lock memory so it cannot get swapped out - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - int blockId[3]; -#endif - - int numBaseBlocks; // number of base blocks - int baseBlockMemory; // total memory in base blocks - int numUsedBlocks; // number of used blocks - int usedBlockMemory; // total memory in used blocks - int numFreeBlocks; // number of free blocks - int freeBlockMemory; // total memory in free blocks - - int numAllocs; - int numResizes; - int numFrees; - - void Clear( void ); - idDynamicBlock * AllocInternal( const int num ); - idDynamicBlock * ResizeInternal( idDynamicBlock *block, const int num ); - void FreeInternal( idDynamicBlock *block ); - void LinkFreeInternal( idDynamicBlock *block ); - void UnlinkFreeInternal( idDynamicBlock *block ); - void CheckMemory( void ) const; -}; - -template -idDynamicBlockAlloc::idDynamicBlockAlloc( void ) { - Clear(); -} - -template -idDynamicBlockAlloc::~idDynamicBlockAlloc( void ) { - Shutdown(); -} - -template -void idDynamicBlockAlloc::Init( void ) { - freeTree.Init(); -} - -template -void idDynamicBlockAlloc::Shutdown( void ) { - idDynamicBlock *block; - - for ( block = firstBlock; block != NULL; block = block->next ) { - if ( block->node == NULL ) { - FreeInternal( block ); - } - } - - for ( block = firstBlock; block != NULL; block = firstBlock ) { - firstBlock = block->next; - assert( block->IsBaseBlock() ); - if ( lockMemory ) { - idLib::sys->UnlockMemory( block, block->GetSize() + (int)sizeof( idDynamicBlock ) ); - } - Mem_Free16( block ); - } - - freeTree.Shutdown(); - - Clear(); -} - -template -void idDynamicBlockAlloc::SetFixedBlocks( int numBlocks ) { - idDynamicBlock *block; - - for ( int i = numBaseBlocks; i < numBlocks; i++ ) { - block = ( idDynamicBlock * ) Mem_Alloc16( baseBlockSize ); - if ( lockMemory ) { - idLib::sys->LockMemory( block, baseBlockSize ); - } -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - memcpy( block->id, blockId, sizeof( block->id ) ); - block->allocator = (void*)this; -#endif - block->SetSize( baseBlockSize - (int)sizeof( idDynamicBlock ), true ); - block->next = NULL; - block->prev = lastBlock; - if ( lastBlock ) { - lastBlock->next = block; - } else { - firstBlock = block; - } - lastBlock = block; - block->node = NULL; - - FreeInternal( block ); - - numBaseBlocks++; - baseBlockMemory += baseBlockSize; - } - - allowAllocs = false; -} - -template -void idDynamicBlockAlloc::SetLockMemory( bool lock ) { - lockMemory = lock; -} - -template -void idDynamicBlockAlloc::FreeEmptyBaseBlocks( void ) { - idDynamicBlock *block, *next; - - for ( block = firstBlock; block != NULL; block = next ) { - next = block->next; - - if ( block->IsBaseBlock() && block->node != NULL && ( next == NULL || next->IsBaseBlock() ) ) { - UnlinkFreeInternal( block ); - if ( block->prev ) { - block->prev->next = block->next; - } else { - firstBlock = block->next; - } - if ( block->next ) { - block->next->prev = block->prev; - } else { - lastBlock = block->prev; - } - if ( lockMemory ) { - idLib::sys->UnlockMemory( block, block->GetSize() + (int)sizeof( idDynamicBlock ) ); - } - numBaseBlocks--; - baseBlockMemory -= block->GetSize() + (int)sizeof( idDynamicBlock ); - Mem_Free16( block ); - } - } - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - CheckMemory(); -#endif -} - -template -int idDynamicBlockAlloc::GetNumEmptyBaseBlocks( void ) const { - int numEmptyBaseBlocks; - idDynamicBlock *block; - - numEmptyBaseBlocks = 0; - for ( block = firstBlock; block != NULL; block = block->next ) { - if ( block->IsBaseBlock() && block->node != NULL && ( block->next == NULL || block->next->IsBaseBlock() ) ) { - numEmptyBaseBlocks++; - } - } - return numEmptyBaseBlocks; -} - -template -type *idDynamicBlockAlloc::Alloc( const int num ) { - idDynamicBlock *block; - - numAllocs++; - - if ( num <= 0 ) { - return NULL; - } - - block = AllocInternal( num ); - if ( block == NULL ) { - return NULL; - } - block = ResizeInternal( block, num ); - if ( block == NULL ) { - return NULL; - } - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - CheckMemory(); -#endif - - numUsedBlocks++; - usedBlockMemory += block->GetSize(); - - return block->GetMemory(); -} - -template -type *idDynamicBlockAlloc::Resize( type *ptr, const int num ) { - - numResizes++; - - if ( ptr == NULL ) { - return Alloc( num ); - } - - if ( num <= 0 ) { - Free( ptr ); - return NULL; - } - - idDynamicBlock *block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); - - usedBlockMemory -= block->GetSize(); - - block = ResizeInternal( block, num ); - if ( block == NULL ) { - return NULL; - } - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - CheckMemory(); -#endif - - usedBlockMemory += block->GetSize(); - - return block->GetMemory(); -} - -template -void idDynamicBlockAlloc::Free( type *ptr ) { - - numFrees++; - - if ( ptr == NULL ) { - return; - } - - idDynamicBlock *block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); - - numUsedBlocks--; - usedBlockMemory -= block->GetSize(); - - FreeInternal( block ); - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - CheckMemory(); -#endif -} - -template -const char *idDynamicBlockAlloc::CheckMemory( const type *ptr ) const { - idDynamicBlock *block; - - if ( ptr == NULL ) { - return NULL; - } - - block = ( idDynamicBlock * ) ( ( (byte *) ptr ) - (int)sizeof( idDynamicBlock ) ); - - if ( block->node != NULL ) { - return "memory has been freed"; - } - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - if ( block->id[0] != 0x11111111 || block->id[1] != 0x22222222 || block->id[2] != 0x33333333 ) { - return "memory has invalid id"; - } - if ( block->allocator != (void*)this ) { - return "memory was allocated with different allocator"; - } -#endif - - /* base blocks can be larger than baseBlockSize which can cause this code to fail - idDynamicBlock *base; - for ( base = firstBlock; base != NULL; base = base->next ) { - if ( base->IsBaseBlock() ) { - if ( ((int)block) >= ((int)base) && ((int)block) < ((int)base) + baseBlockSize ) { - break; - } - } - } - if ( base == NULL ) { - return "no base block found for memory"; - } - */ - - return NULL; -} - -template -void idDynamicBlockAlloc::Clear( void ) { - firstBlock = lastBlock = NULL; - allowAllocs = true; - lockMemory = false; - numBaseBlocks = 0; - baseBlockMemory = 0; - numUsedBlocks = 0; - usedBlockMemory = 0; - numFreeBlocks = 0; - freeBlockMemory = 0; - numAllocs = 0; - numResizes = 0; - numFrees = 0; - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - blockId[0] = 0x11111111; - blockId[1] = 0x22222222; - blockId[2] = 0x33333333; -#endif -} - -template -idDynamicBlock *idDynamicBlockAlloc::AllocInternal( const int num ) { - idDynamicBlock *block; - int alignedBytes = ( num * sizeof( type ) + 15 ) & ~15; - - block = freeTree.FindSmallestLargerEqual( alignedBytes ); - if ( block != NULL ) { - UnlinkFreeInternal( block ); - } else if ( allowAllocs ) { - int allocSize = Max( baseBlockSize, alignedBytes + (int)sizeof( idDynamicBlock ) ); - block = ( idDynamicBlock * ) Mem_Alloc16( allocSize ); - if ( lockMemory ) { - idLib::sys->LockMemory( block, baseBlockSize ); - } -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - memcpy( block->id, blockId, sizeof( block->id ) ); - block->allocator = (void*)this; -#endif - block->SetSize( allocSize - (int)sizeof( idDynamicBlock ), true ); - block->next = NULL; - block->prev = lastBlock; - if ( lastBlock ) { - lastBlock->next = block; - } else { - firstBlock = block; - } - lastBlock = block; - block->node = NULL; - - numBaseBlocks++; - baseBlockMemory += allocSize; - } - - return block; -} - -template -idDynamicBlock *idDynamicBlockAlloc::ResizeInternal( idDynamicBlock *block, const int num ) { - int alignedBytes = ( num * sizeof( type ) + 15 ) & ~15; - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - assert( block->id[0] == 0x11111111 && block->id[1] == 0x22222222 && block->id[2] == 0x33333333 && block->allocator == (void*)this ); -#endif - - // if the new size is larger - if ( alignedBytes > block->GetSize() ) { - - idDynamicBlock *nextBlock = block->next; - - // try to annexate the next block if it's free - if ( nextBlock && !nextBlock->IsBaseBlock() && nextBlock->node != NULL && - block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize() >= alignedBytes ) { - - UnlinkFreeInternal( nextBlock ); - block->SetSize( block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize(), block->IsBaseBlock() ); - block->next = nextBlock->next; - if ( nextBlock->next ) { - nextBlock->next->prev = block; - } else { - lastBlock = block; - } - } else { - // allocate a new block and copy - idDynamicBlock *oldBlock = block; - block = AllocInternal( num ); - if ( block == NULL ) { - return NULL; - } - memcpy( block->GetMemory(), oldBlock->GetMemory(), oldBlock->GetSize() ); - FreeInternal( oldBlock ); - } - } - - // if the unused space at the end of this block is large enough to hold a block with at least one element - if ( block->GetSize() - alignedBytes - (int)sizeof( idDynamicBlock ) < Max( minBlockSize, (int)sizeof( type ) ) ) { - return block; - } - - idDynamicBlock *newBlock; - - newBlock = ( idDynamicBlock * ) ( ( (byte *) block ) + (int)sizeof( idDynamicBlock ) + alignedBytes ); -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - memcpy( newBlock->id, blockId, sizeof( newBlock->id ) ); - newBlock->allocator = (void*)this; -#endif - newBlock->SetSize( block->GetSize() - alignedBytes - (int)sizeof( idDynamicBlock ), false ); - newBlock->next = block->next; - newBlock->prev = block; - if ( newBlock->next ) { - newBlock->next->prev = newBlock; - } else { - lastBlock = newBlock; - } - newBlock->node = NULL; - block->next = newBlock; - block->SetSize( alignedBytes, block->IsBaseBlock() ); - - FreeInternal( newBlock ); - - return block; -} - -template -void idDynamicBlockAlloc::FreeInternal( idDynamicBlock *block ) { - - assert( block->node == NULL ); - -#ifdef DYNAMIC_BLOCK_ALLOC_CHECK - assert( block->id[0] == 0x11111111 && block->id[1] == 0x22222222 && block->id[2] == 0x33333333 && block->allocator == (void*)this ); -#endif - - // try to merge with a next free block - idDynamicBlock *nextBlock = block->next; - if ( nextBlock && !nextBlock->IsBaseBlock() && nextBlock->node != NULL ) { - UnlinkFreeInternal( nextBlock ); - block->SetSize( block->GetSize() + (int)sizeof( idDynamicBlock ) + nextBlock->GetSize(), block->IsBaseBlock() ); - block->next = nextBlock->next; - if ( nextBlock->next ) { - nextBlock->next->prev = block; - } else { - lastBlock = block; - } - } - - // try to merge with a previous free block - idDynamicBlock *prevBlock = block->prev; - if ( prevBlock && !block->IsBaseBlock() && prevBlock->node != NULL ) { - UnlinkFreeInternal( prevBlock ); - prevBlock->SetSize( prevBlock->GetSize() + (int)sizeof( idDynamicBlock ) + block->GetSize(), prevBlock->IsBaseBlock() ); - prevBlock->next = block->next; - if ( block->next ) { - block->next->prev = prevBlock; - } else { - lastBlock = prevBlock; - } - LinkFreeInternal( prevBlock ); - } else { - LinkFreeInternal( block ); - } -} - -template -ID_INLINE void idDynamicBlockAlloc::LinkFreeInternal( idDynamicBlock *block ) { - block->node = freeTree.Add( block, block->GetSize() ); - numFreeBlocks++; - freeBlockMemory += block->GetSize(); -} - -template -ID_INLINE void idDynamicBlockAlloc::UnlinkFreeInternal( idDynamicBlock *block ) { - freeTree.Remove( block->node ); - block->node = NULL; - numFreeBlocks--; - freeBlockMemory -= block->GetSize(); -} - -template -void idDynamicBlockAlloc::CheckMemory( void ) const { - idDynamicBlock *block; - - for ( block = firstBlock; block != NULL; block = block->next ) { - // make sure the block is properly linked - if ( block->prev == NULL ) { - assert( firstBlock == block ); - } else { - assert( block->prev->next == block ); - } - if ( block->next == NULL ) { - assert( lastBlock == block ); - } else { - assert( block->next->prev == block ); - } - } -} - -#endif /* !__HEAP_H__ */ diff --git a/idlib/langdict.cpp b/idlib/langdict.cpp deleted file mode 100644 index 43be90d33..000000000 --- a/idlib/langdict.cpp +++ /dev/null @@ -1,319 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============ -idLangDict::idLangDict -============ -*/ -idLangDict::idLangDict( void ) { - args.SetGranularity( 256 ); - hash.SetGranularity( 256 ); - hash.Clear( 4096, 8192 ); - baseID = 0; -} - -/* -============ -idLangDict::~idLangDict -============ -*/ -idLangDict::~idLangDict( void ) { - Clear(); -} - -/* -============ -idLangDict::Clear -============ -*/ -void idLangDict::Clear( void ) { - args.Clear(); - hash.Clear(); -} - -/* -============ -idLangDict::Load -============ -*/ -bool idLangDict::Load( const char *fileName, const bool clear /* _D3XP */, const unsigned int remapcount, const char *remap ) { - - if ( clear ) { - Clear(); - } - - const char *buffer = NULL; - idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); - - int len = idLib::fileSystem->ReadFile( fileName, (void**)&buffer ); - if ( len <= 0 ) { - // let whoever called us deal with the failure (so sys_lang can be reset) - return false; - } - src.LoadMemory( buffer, strlen( buffer ), fileName ); - if ( !src.IsLoaded() ) { - return false; - } - - idToken tok, tok2; - src.ExpectTokenString( "{" ); - while ( src.ReadToken( &tok ) ) { - if ( tok == "}" ) { - break; - } - if ( src.ReadToken( &tok2 ) ) { - if ( tok2 == "}" ) { - break; - } - idLangKeyValue kv; - kv.key = tok; - kv.value = tok2; - if (NULL != remap && remapcount > 0) - { - // Tels: fix #2812, some characters like 0xFF ("Ñ" in russian) are not rendered - // in the GUI, so replace them (as the font contains the characters elsewhere). - // If we were given a replacement table, use it to exchange the characters: - for (int i = 0; i < remapcount; i ++) - { - kv.value.Replace( remap[i*2], remap[i*2+1] ); - } - } - assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); - hash.Add( GetHashKey( kv.key ), args.Append( kv ) ); - } - } - idLib::common->Printf( "%i strings read from %s\n", args.Num(), fileName ); - idLib::fileSystem->FreeFile( (void*)buffer ); - - return true; -} - -/* -============ -idLangDict::Save -============ -*/ -void idLangDict::Save( const char *fileName ) { - idFile *outFile = idLib::fileSystem->OpenFileWrite( fileName ); - outFile->WriteFloatString( "// string table\n// english\n//\n\n{\n" ); - for ( int j = 0; j < args.Num(); j++ ) { - outFile->WriteFloatString( "\t\"%s\"\t\"", args[j].key.c_str() ); - int l = args[j].value.Length(); - char slash = '\\'; - char tab = 't'; - char nl = 'n'; - for ( int k = 0; k < l; k++ ) { - char ch = args[j].value[k]; - if ( ch == '\t' ) { - outFile->Write( &slash, 1 ); - outFile->Write( &tab, 1 ); - } else if ( ch == '\n' || ch == '\r' ) { - outFile->Write( &slash, 1 ); - outFile->Write( &nl, 1 ); - } else { - outFile->Write( &ch, 1 ); - } - } - outFile->WriteFloatString( "\"\n" ); - } - outFile->WriteFloatString( "\n}\n" ); - idLib::fileSystem->CloseFile( outFile ); -} - -/* -============ -idLangDict::GetString -============ -*/ -const char *idLangDict::GetString( const char *str, const bool dowarn ) const { - - if ( str == NULL || str[0] == '\0' ) { - return ""; - } - - if ( idStr::Cmpn( str, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) { - return str; - } - - int hashKey = GetHashKey( str ); - for ( int i = hash.First( hashKey ); i != -1; i = hash.Next( i ) ) { - if ( args[i].key.Cmp( str ) == 0 ) { - return args[i].value; - } - } - - if (dowarn) - { - idLib::common->Warning( "Unknown string id %s", str ); - } - return str; -} - -/* -============ -idLangDict::AddString -============ -*/ -const char *idLangDict::AddString( const char *str ) { - - if ( ExcludeString( str ) ) { - return str; - } - - int c = args.Num(); - for ( int j = 0; j < c; j++ ) { - if ( idStr::Cmp( args[j].value, str ) == 0 ){ - return args[j].key; - } - } - - int id = GetNextId(); - idLangKeyValue kv; - // _D3XP - kv.key = va( "#str_%08i", id ); - // kv.key = va( "#str_%05i", id ); - kv.value = str; - c = args.Append( kv ); - assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); - hash.Add( GetHashKey( kv.key ), c ); - return args[c].key; -} - -/* -============ -idLangDict::GetNumKeyVals -============ -*/ -int idLangDict::GetNumKeyVals( void ) const { - return args.Num(); -} - -/* -============ -idLangDict::GetKeyVal -============ -*/ -const idLangKeyValue * idLangDict::GetKeyVal( const int i ) const { - return &args[i]; -} - -/* -============ -idLangDict::AddKeyVal -============ -*/ -void idLangDict::AddKeyVal( const char *key, const char *val ) { - idLangKeyValue kv; - kv.key = key; - kv.value = val; - assert( kv.key.Cmpn( STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ); - hash.Add( GetHashKey( kv.key ), args.Append( kv ) ); -} - -/* -============ -idLangDict::ExcludeString -============ -*/ -bool idLangDict::ExcludeString( const char *str ) const { - if ( str == NULL ) { - return true; - } - - int c = strlen( str ); - if ( c <= 1 ) { - return true; - } - - if ( idStr::Cmpn( str, STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ) { - return true; - } - - if ( idStr::Icmpn( str, "gui::", strlen( "gui::" ) ) == 0 ) { - return true; - } - - if ( str[0] == '$' ) { - return true; - } - - int i; - for ( i = 0; i < c; i++ ) { - if ( isalpha( str[i] ) ) { - break; - } - } - if ( i == c ) { - return true; - } - - return false; -} - -/* -============ -idLangDict::GetNextId -============ -*/ -int idLangDict::GetNextId( void ) const { - int c = args.Num(); - - // Let an external user supply the base id for this dictionary - int id = baseID; - - if ( c == 0 ) { - return id; - } - - idStr work; - for ( int j = 0; j < c; j++ ) { - work = args[j].key; - work.StripLeading( STRTABLE_ID ); - int test = atoi( work ); - if ( test > id ) { - id = test; - } - } - return id + 1; -} - -/* -============ -idLangDict::GetHashKey -============ -*/ -int idLangDict::GetHashKey( const char *str ) const { - int hashKey = 0; - for ( str += STRTABLE_ID_LENGTH; str[0] != '\0'; str++ ) { - assert( str[0] >= '0' && str[0] <= '9' ); - hashKey = hashKey * 10 + str[0] - '0'; - } - return hashKey; -} - -/* -============ -idLangDict::Print -============ -*/ -void idLangDict::Print( void ) const { - int c = args.Num(); - gameLocal.Printf("idLangDict: %li KB in %i entries.\n", static_cast(args.Size() + hash.Size()) >> 10l, c); - //hash.Print(); -} diff --git a/idlib/langdict.h b/idlib/langdict.h deleted file mode 100644 index 813d73397..000000000 --- a/idlib/langdict.h +++ /dev/null @@ -1,68 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LANGDICT_H__ -#define __LANGDICT_H__ - -/* -=============================================================================== - - Simple dictionary specifically for the localized string tables. - -=============================================================================== -*/ - -class idLangKeyValue { -public: - idStr key; - idStr value; -}; - -class idLangDict { -public: - idLangDict( void ); - ~idLangDict( void ); - - void Clear( void ); - // Tels: #2812: if remapcount and remap are given, use these to replace characters (remap containts two entries for - // each "remapcount", the first is the one to replace, the second the replacement. - bool Load( const char *fileName, const bool clear = true, const unsigned int remapcount = 0, const char *remap = NULL ); - void Save( const char *fileName ); - - const char * AddString( const char *str ); - const char * GetString( const char *str, const bool dowarn = true ) const; - - /** - * Tels: Print some statistics about memory usage. - */ - void Print( void ) const; - // adds the value and key as passed (doesn't generate a "#str_xxxxx" key or ensure the key/value pair is unique) - void AddKeyVal( const char *key, const char *val ); - - int GetNumKeyVals( void ) const; - const idLangKeyValue * GetKeyVal(const int i) const; - - void SetBaseID(const int id) { baseID = id; }; - -private: - idList args; - idHashIndex hash; - - bool ExcludeString( const char *str ) const; - int GetNextId( void ) const; - int GetHashKey( const char *str ) const; - - int baseID; -}; - -#endif /* !__LANGDICT_H__ */ diff --git a/idlib/lexer.cpp b/idlib/lexer.cpp deleted file mode 100644 index 3ec31f85f..000000000 --- a/idlib/lexer.cpp +++ /dev/null @@ -1,1852 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning( push ) -#pragma warning( disable : 4127 ) -#define PUNCTABLE - -//longer punctuations first -punctuation_t default_punctuations[] = { - //binary operators - {">>=",P_RSHIFT_ASSIGN}, - {"<<=",P_LSHIFT_ASSIGN}, - // - {"...",P_PARMS}, - //define merge operator - {"##",P_PRECOMPMERGE}, // pre-compiler - //logic operators - {"&&",P_LOGIC_AND}, // pre-compiler - {"||",P_LOGIC_OR}, // pre-compiler - {">=",P_LOGIC_GEQ}, // pre-compiler - {"<=",P_LOGIC_LEQ}, // pre-compiler - {"==",P_LOGIC_EQ}, // pre-compiler - {"!=",P_LOGIC_UNEQ}, // pre-compiler - //arithmatic operators - {"*=",P_MUL_ASSIGN}, - {"/=",P_DIV_ASSIGN}, - {"%=",P_MOD_ASSIGN}, - {"+=",P_ADD_ASSIGN}, - {"-=",P_SUB_ASSIGN}, - {"++",P_INC}, - {"--",P_DEC}, - //binary operators - {"&=",P_BIN_AND_ASSIGN}, - {"|=",P_BIN_OR_ASSIGN}, - {"^=",P_BIN_XOR_ASSIGN}, - {">>",P_RSHIFT}, // pre-compiler - {"<<",P_LSHIFT}, // pre-compiler - //reference operators - {"->",P_POINTERREF}, - //C++ - {"::",P_CPP1}, - {".*",P_CPP2}, - //arithmatic operators - {"*",P_MUL}, // pre-compiler - {"/",P_DIV}, // pre-compiler - {"%",P_MOD}, // pre-compiler - {"+",P_ADD}, // pre-compiler - {"-",P_SUB}, // pre-compiler - {"=",P_ASSIGN}, - //binary operators - {"&",P_BIN_AND}, // pre-compiler - {"|",P_BIN_OR}, // pre-compiler - {"^",P_BIN_XOR}, // pre-compiler - {"~",P_BIN_NOT}, // pre-compiler - //logic operators - {"!",P_LOGIC_NOT}, // pre-compiler - {">",P_LOGIC_GREATER}, // pre-compiler - {"<",P_LOGIC_LESS}, // pre-compiler - //reference operator - {".",P_REF}, - //seperators - {",",P_COMMA}, // pre-compiler - {";",P_SEMICOLON}, - //label indication - {":",P_COLON}, // pre-compiler - //if statement - {"?",P_QUESTIONMARK}, // pre-compiler - //embracements - {"(",P_PARENTHESESOPEN}, // pre-compiler - {")",P_PARENTHESESCLOSE}, // pre-compiler - {"{",P_BRACEOPEN}, // pre-compiler - {"}",P_BRACECLOSE}, // pre-compiler - {"[",P_SQBRACKETOPEN}, - {"]",P_SQBRACKETCLOSE}, - // - {"\\",P_BACKSLASH}, - //precompiler operator - {"#",P_PRECOMP}, // pre-compiler - {"$",P_DOLLAR}, - {NULL, 0} -}; - -int default_punctuationtable[256]; -int default_nextpunctuation[sizeof(default_punctuations) / sizeof(punctuation_t)]; -int default_setup; - -char idLexer::baseFolder[ 256 ]; - -/* -================ -idLexer::CreatePunctuationTable -================ -*/ -void idLexer::CreatePunctuationTable( const punctuation_t *punctuations ) { - int i, n, lastp; - const punctuation_t *p, *newp; - - //get memory for the table - if ( punctuations == default_punctuations ) { - idLexer::punctuationtable = default_punctuationtable; - idLexer::nextpunctuation = default_nextpunctuation; - if ( default_setup ) { - return; - } - default_setup = true; - i = sizeof(default_punctuations) / sizeof(punctuation_t); - } - else { - if ( !idLexer::punctuationtable || idLexer::punctuationtable == default_punctuationtable ) { - idLexer::punctuationtable = (int *) Mem_Alloc(256 * sizeof(int)); - } - if ( idLexer::nextpunctuation && idLexer::nextpunctuation != default_nextpunctuation ) { - Mem_Free( idLexer::nextpunctuation ); - } - for (i = 0; punctuations[i].p; i++) { - } - idLexer::nextpunctuation = (int *) Mem_Alloc(i * sizeof(int)); - } - memset(idLexer::punctuationtable, 0xFF, 256 * sizeof(int)); - memset(idLexer::nextpunctuation, 0xFF, i * sizeof(int)); - //add the punctuations in the list to the punctuation table - for (i = 0; punctuations[i].p; i++) { - newp = &punctuations[i]; - lastp = -1; - //sort the punctuations in this table entry on length (longer punctuations first) - for (n = idLexer::punctuationtable[(unsigned int) newp->p[0]]; n >= 0; n = idLexer::nextpunctuation[n] ) { - p = &punctuations[n]; - if (strlen(p->p) < strlen(newp->p)) { - idLexer::nextpunctuation[i] = n; - if (lastp >= 0) { - idLexer::nextpunctuation[lastp] = i; - } - else { - idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; - } - break; - } - lastp = n; - } - if (n < 0) { - idLexer::nextpunctuation[i] = -1; - if (lastp >= 0) { - idLexer::nextpunctuation[lastp] = i; - } - else { - idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; - } - } - } -} - -/* -================ -idLexer::GetPunctuationFromId -================ -*/ -const char *idLexer::GetPunctuationFromId( int id ) { - int i; - - for (i = 0; idLexer::punctuations[i].p; i++) { - if ( idLexer::punctuations[i].n == id ) { - return idLexer::punctuations[i].p; - } - } - return "unkown punctuation"; -} - -/* -================ -idLexer::GetPunctuationId -================ -*/ -int idLexer::GetPunctuationId( const char *p ) { - int i; - - for (i = 0; idLexer::punctuations[i].p; i++) { - if ( !strcmp(idLexer::punctuations[i].p, p) ) { - return idLexer::punctuations[i].n; - } - } - return 0; -} - -/* -================ -idLexer::Error -================ -*/ -void idLexer::Error( const char *str, ... ) { - char text[MAX_STRING_CHARS]; - va_list ap; - - hadError = true; - - if ( idLexer::flags & LEXFL_NOERRORS ) { - return; - } - - va_start(ap, str); - vsprintf(text, str, ap); - va_end(ap); - - if ( idLexer::flags & LEXFL_NOFATALERRORS ) { - idLib::common->Warning( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); - } else { - idLib::common->Error( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); - } -} - -/* -================ -idLexer::Warning -================ -*/ -void idLexer::Warning( const char *str, ... ) { - char text[MAX_STRING_CHARS]; - va_list ap; - - if ( idLexer::flags & LEXFL_NOWARNINGS ) { - return; - } - - va_start( ap, str ); - vsprintf( text, str, ap ); - va_end( ap ); - idLib::common->Warning( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); -} - -/* -================ -idLexer::SetPunctuations -================ -*/ -void idLexer::SetPunctuations( const punctuation_t *p ) { -#ifdef PUNCTABLE - if (p) { - idLexer::CreatePunctuationTable( p ); - } - else { - idLexer::CreatePunctuationTable( default_punctuations ); - } -#endif //PUNCTABLE - if (p) { - idLexer::punctuations = p; - } - else { - idLexer::punctuations = default_punctuations; - } -} - -/* -================ -idLexer::ReadWhiteSpace - -Reads spaces, tabs, C-like comments etc. -When a newline character is found the scripts line counter is increased. -================ -*/ -int idLexer::ReadWhiteSpace( void ) { - while(1) { - // skip white space - while(*idLexer::script_p <= ' ') { - if (!*idLexer::script_p) { - return 0; - } - if (*idLexer::script_p == '\n') { - idLexer::line++; - } - idLexer::script_p++; - } - // skip comments - if (*idLexer::script_p == '/') { - // comments // - if (*(idLexer::script_p+1) == '/') { - idLexer::script_p++; - do { - idLexer::script_p++; - if ( !*idLexer::script_p ) { - return 0; - } - } - while( *idLexer::script_p != '\n' ); - idLexer::line++; - idLexer::script_p++; - if ( !*idLexer::script_p ) { - return 0; - } - continue; - } - // comments /* */ - else if (*(idLexer::script_p+1) == '*') { - idLexer::script_p++; - while( 1 ) { - idLexer::script_p++; - if ( !*idLexer::script_p ) { - return 0; - } - if ( *idLexer::script_p == '\n' ) { - idLexer::line++; - } - else if ( *idLexer::script_p == '/' ) { - if ( *(idLexer::script_p-1) == '*' ) { - break; - } - if ( *(idLexer::script_p+1) == '*' ) { - idLexer::Warning( "nested comment" ); - } - } - } - idLexer::script_p++; - if ( !*idLexer::script_p ) { - return 0; - } - continue; - } - } - break; - } - return 1; -} - -/* -================ -idLexer::ReadEscapeCharacter -================ -*/ -int idLexer::ReadEscapeCharacter( char *ch ) { - int c, val, i; - - // step over the leading '\\' - idLexer::script_p++; - // determine the escape character - switch(*idLexer::script_p) { - case '\\': c = '\\'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'a': c = '\a'; break; - case '\'': c = '\''; break; - case '\"': c = '\"'; break; - case '\?': c = '\?'; break; - case 'x': - { - idLexer::script_p++; - for (i = 0, val = 0; ; i++, idLexer::script_p++) { - c = *idLexer::script_p; - if (c >= '0' && c <= '9') - c = c - '0'; - else if (c >= 'A' && c <= 'Z') - c = c - 'A' + 10; - else if (c >= 'a' && c <= 'z') - c = c - 'a' + 10; - else - break; - val = (val << 4) + c; - } - idLexer::script_p--; - if (val > 0xFF) { - idLexer::Warning( "too large value in escape character" ); - val = 0xFF; - } - c = val; - break; - } - default: //NOTE: decimal ASCII code, NOT octal - { - if (*idLexer::script_p < '0' || *idLexer::script_p > '9') { - idLexer::Error("unknown escape char"); - } - for (i = 0, val = 0; ; i++, idLexer::script_p++) { - c = *idLexer::script_p; - if (c >= '0' && c <= '9') - c = c - '0'; - else - break; - val = val * 10 + c; - } - idLexer::script_p--; - if (val > 0xFF) { - idLexer::Warning( "too large value in escape character" ); - val = 0xFF; - } - c = val; - break; - } - } - // step over the escape character or the last digit of the number - idLexer::script_p++; - // store the escape character - *ch = c; - // succesfully read escape character - return 1; -} - -/* -================ -idLexer::ReadString - -Escape characters are interpretted. -Reads two strings with only a white space between them as one string. -================ -*/ -int idLexer::ReadString( idToken *token, int quote ) { - int tmpline; - const char *tmpscript_p; - char ch; - - if ( quote == '\"' ) { - token->type = TT_STRING; - } else { - token->type = TT_LITERAL; - } - - // leading quote - idLexer::script_p++; - - while(1) { - // if there is an escape character and escape characters are allowed - if (*idLexer::script_p == '\\' && !(idLexer::flags & LEXFL_NOSTRINGESCAPECHARS)) { - if ( !idLexer::ReadEscapeCharacter( &ch ) ) { - return 0; - } - token->AppendDirty( ch ); - } - // if a trailing quote - else if (*idLexer::script_p == quote) { - // step over the quote - idLexer::script_p++; - // if consecutive strings should not be concatenated - if ( (idLexer::flags & LEXFL_NOSTRINGCONCAT) && - (!(idLexer::flags & LEXFL_ALLOWBACKSLASHSTRINGCONCAT) || (quote != '\"')) ) { - break; - } - - tmpscript_p = idLexer::script_p; - tmpline = idLexer::line; - // read white space between possible two consecutive strings - if ( !idLexer::ReadWhiteSpace() ) { - idLexer::script_p = tmpscript_p; - idLexer::line = tmpline; - break; - } - - if ( idLexer::flags & LEXFL_NOSTRINGCONCAT ) { - if ( *idLexer::script_p != '\\' ) { - idLexer::script_p = tmpscript_p; - idLexer::line = tmpline; - break; - } - // step over the '\\' - idLexer::script_p++; - if ( !idLexer::ReadWhiteSpace() || ( *idLexer::script_p != quote ) ) { - idLexer::Error( "expecting string after '\' terminated line" ); - return 0; - } - } - - // if there's no leading qoute - if ( *idLexer::script_p != quote ) { - idLexer::script_p = tmpscript_p; - idLexer::line = tmpline; - break; - } - // step over the new leading quote - idLexer::script_p++; - } - else { - if (*idLexer::script_p == '\0') { - idLexer::Error( "missing trailing quote" ); - return 0; - } - if (*idLexer::script_p == '\n') { - idLexer::Error( "newline inside string" ); - return 0; - } - token->AppendDirty( *idLexer::script_p++ ); - } - } - token->data[token->len] = '\0'; - - if ( token->type == TT_LITERAL ) { - if ( !(idLexer::flags & LEXFL_ALLOWMULTICHARLITERALS) ) { - if ( token->Length() != 1 ) { - idLexer::Warning( "literal is not one character long" ); - } - } - token->subtype = (*token)[0]; - } - else { - // the sub type is the length of the string - token->subtype = token->Length(); - } - return 1; -} - -/* -================ -idLexer::ReadName -================ -*/ -int idLexer::ReadName( idToken *token ) { - char c; - - token->type = TT_NAME; - do { - token->AppendDirty( *idLexer::script_p++ ); - c = *idLexer::script_p; - } while ((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == '_' || - // if treating all tokens as strings, don't parse '-' as a seperate token - ((idLexer::flags & LEXFL_ONLYSTRINGS) && (c == '-')) || - // if special path name characters are allowed - ((idLexer::flags & LEXFL_ALLOWPATHNAMES) && (c == '/' || c == '\\' || c == ':' || c == '.')) ); - token->data[token->len] = '\0'; - //the sub type is the length of the name - token->subtype = token->Length(); - return 1; -} - -/* -================ -idLexer::CheckString -================ -*/ -ID_INLINE int idLexer::CheckString( const char *str ) const { - int i; - - for ( i = 0; str[i]; i++ ) { - if ( idLexer::script_p[i] != str[i] ) { - return false; - } - } - return true; -} - -/* -================ -idLexer::ReadNumber -================ -*/ -int idLexer::ReadNumber( idToken *token ) { - int i; - int dot; - char c, c2; - - token->type = TT_NUMBER; - token->subtype = 0; - token->intvalue = 0; - token->floatvalue = 0; - - c = *idLexer::script_p; - c2 = *(idLexer::script_p + 1); - - if ( c == '0' && c2 != '.' ) { - // check for a hexadecimal number - if ( c2 == 'x' || c2 == 'X' ) { - token->AppendDirty( *idLexer::script_p++ ); - token->AppendDirty( *idLexer::script_p++ ); - c = *idLexer::script_p; - while((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F')) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - token->subtype = TT_HEX | TT_INTEGER; - } - // check for a binary number - else if ( c2 == 'b' || c2 == 'B' ) { - token->AppendDirty( *idLexer::script_p++ ); - token->AppendDirty( *idLexer::script_p++ ); - c = *idLexer::script_p; - while( c == '0' || c == '1' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - token->subtype = TT_BINARY | TT_INTEGER; - } - // its an octal number - else { - token->AppendDirty( *idLexer::script_p++ ); - c = *idLexer::script_p; - while( c >= '0' && c <= '7' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - token->subtype = TT_OCTAL | TT_INTEGER; - } - } - else { - // decimal integer or floating point number or ip address - dot = 0; - while( 1 ) { - if ( c >= '0' && c <= '9' ) { - } - else if ( c == '.' ) { - dot++; - } - else { - break; - } - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - if( c == 'e' && dot == 0) { - - //We have scientific notation without a decimal point - - dot++; - - } - - // if a floating point number - if ( dot == 1 ) { - token->subtype = TT_DECIMAL | TT_FLOAT; - // check for floating point exponent - if ( c == 'e' ) { - //Append the e so that GetFloatValue code works - - token->AppendDirty( c ); - - c = *(++idLexer::script_p); - if ( c == '-' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - else if ( c == '+' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - while( c >= '0' && c <= '9' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - } - // check for floating point exception infinite 1.#INF or indefinite 1.#IND or NaN - else if ( c == '#' ) { - c2 = 4; - if ( CheckString( "INF" ) ) { - token->subtype |= TT_INFINITE; - } - else if ( CheckString( "IND" ) ) { - token->subtype |= TT_INDEFINITE; - } - else if ( CheckString( "NAN" ) ) { - token->subtype |= TT_NAN; - } - else if ( CheckString( "QNAN" ) ) { - token->subtype |= TT_NAN; - c2++; - } - else if ( CheckString( "SNAN" ) ) { - token->subtype |= TT_NAN; - c2++; - } - for ( i = 0; i < c2; i++ ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - while( c >= '0' && c <= '9' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - if ( !(idLexer::flags & LEXFL_ALLOWFLOATEXCEPTIONS) ) { - token->AppendDirty( 0 ); // zero terminate for c_str - idLexer::Error( "parsed %s", token->c_str() ); - } - } - } - else if ( dot > 1 ) { - if ( !( idLexer::flags & LEXFL_ALLOWIPADDRESSES ) ) { - idLexer::Error( "more than one dot in number" ); - return 0; - } - if ( dot != 3 ) { - idLexer::Error( "ip address should have three dots" ); - return 0; - } - token->subtype = TT_IPADDRESS; - } - else { - token->subtype = TT_DECIMAL | TT_INTEGER; - } - } - - if ( token->subtype & TT_FLOAT ) { - if ( c > ' ' ) { - // single-precision: float - if ( c == 'f' || c == 'F' ) { - token->subtype |= TT_SINGLE_PRECISION; - idLexer::script_p++; - } - // extended-precision: long double - else if ( c == 'l' || c == 'L' ) { - token->subtype |= TT_EXTENDED_PRECISION; - idLexer::script_p++; - } - // default is double-precision: double - else { - token->subtype |= TT_DOUBLE_PRECISION; - } - } - else { - token->subtype |= TT_DOUBLE_PRECISION; - } - } - else if ( token->subtype & TT_INTEGER ) { - if ( c > ' ' ) { - // default: signed long - for ( i = 0; i < 2; i++ ) { - // long integer - if ( c == 'l' || c == 'L' ) { - token->subtype |= TT_LONG; - } - // unsigned integer - else if ( c == 'u' || c == 'U' ) { - token->subtype |= TT_UNSIGNED; - } - else { - break; - } - c = *(++idLexer::script_p); - } - } - } - else if ( token->subtype & TT_IPADDRESS ) { - if ( c == ':' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - while( c >= '0' && c <= '9' ) { - token->AppendDirty( c ); - c = *(++idLexer::script_p); - } - token->subtype |= TT_IPPORT; - } - } - token->data[token->len] = '\0'; - return 1; -} - -/* -================ -idLexer::ReadPunctuation -================ -*/ -int idLexer::ReadPunctuation( idToken *token ) { - int l, n, i; - const char *p; - const punctuation_t *punc; - -#ifdef PUNCTABLE - for (n = idLexer::punctuationtable[(unsigned int)*(idLexer::script_p)]; n >= 0; n = idLexer::nextpunctuation[n]) - { - punc = &(idLexer::punctuations[n]); -#else - int i; - - for (i = 0; idLexer::punctuations[i].p; i++) { - punc = &idLexer::punctuations[i]; -#endif - p = punc->p; - // check for this punctuation in the script - for ( l = 0; p[l] && idLexer::script_p[l]; l++ ) { - if ( idLexer::script_p[l] != p[l] ) { - break; - } - } - if ( !p[l] ) { - // - token->EnsureAlloced( l+1, false ); - for ( i = 0; i <= l; i++ ) { - token->data[i] = p[i]; - } - token->len = l; - // - idLexer::script_p += l; - token->type = TT_PUNCTUATION; - // sub type is the punctuation id - token->subtype = punc->n; - return 1; - } - } - return 0; -} - -/* -================ -idLexer::ReadToken -================ -*/ -int idLexer::ReadToken( idToken *token ) { - int c; - - if ( !loaded ) { - idLib::common->Error( "idLexer::ReadToken: no file loaded" ); - return 0; - } - - // if there is a token available (from unreadToken) - if ( tokenavailable ) { - tokenavailable = 0; - *token = idLexer::token; - return 1; - } - // save script pointer - lastScript_p = script_p; - // save line counter - lastline = line; - // clear the token stuff - token->data[0] = '\0'; - token->len = 0; - // start of the white space - whiteSpaceStart_p = script_p; - token->whiteSpaceStart_p = script_p; - // read white space before token - if ( !ReadWhiteSpace() ) { - return 0; - } - // end of the white space - idLexer::whiteSpaceEnd_p = script_p; - token->whiteSpaceEnd_p = script_p; - // line the token is on - token->line = line; - // number of lines crossed before token - token->linesCrossed = line - lastline; - // clear token flags - token->flags = 0; - - c = *idLexer::script_p; - - // if we're keeping everything as whitespace deliminated strings - if ( idLexer::flags & LEXFL_ONLYSTRINGS ) { - // if there is a leading quote - if ( c == '\"' || c == '\'' ) { - if (!idLexer::ReadString( token, c )) { - return 0; - } - } else if ( !idLexer::ReadName( token ) ) { - return 0; - } - } - // if there is a number - else if ( (c >= '0' && c <= '9') || - (c == '.' && (*(idLexer::script_p + 1) >= '0' && *(idLexer::script_p + 1) <= '9')) ) { - if ( !idLexer::ReadNumber( token ) ) { - return 0; - } - // if names are allowed to start with a number - if ( idLexer::flags & LEXFL_ALLOWNUMBERNAMES ) { - c = *idLexer::script_p; - if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ) { - if ( !idLexer::ReadName( token ) ) { - return 0; - } - } - } - } - // if there is a leading quote - else if ( c == '\"' || c == '\'' ) { - if (!idLexer::ReadString( token, c )) { - return 0; - } - } - // if there is a name - else if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ) { - if ( !idLexer::ReadName( token ) ) { - return 0; - } - } - // names may also start with a slash when pathnames are allowed - else if ( ( idLexer::flags & LEXFL_ALLOWPATHNAMES ) && ( (c == '/' || c == '\\') || c == '.' ) ) { - if ( !idLexer::ReadName( token ) ) { - return 0; - } - } - // check for punctuations - else if ( !idLexer::ReadPunctuation( token ) ) { - idLexer::Error( "unknown punctuation %c", c ); - return 0; - } - // succesfully read a token - return 1; -} - -/* -================ -idLexer::ExpectTokenString -================ -*/ -int idLexer::ExpectTokenString( const char *string ) { - idToken token; - - if (!idLexer::ReadToken( &token )) { - idLexer::Error( "couldn't find expected '%s'", string ); - return 0; - } - if ( token != string ) { - idLexer::Error( "expected '%s' but found '%s'", string, token.c_str() ); - return 0; - } - return 1; -} - -/* -================ -idLexer::ExpectTokenType -================ -*/ -int idLexer::ExpectTokenType( int type, int subtype, idToken *token ) { - idStr str; - - if ( !idLexer::ReadToken( token ) ) { - idLexer::Error( "couldn't read expected token" ); - return 0; - } - - if ( token->type != type ) { - switch( type ) { - case TT_STRING: str = "string"; break; - case TT_LITERAL: str = "literal"; break; - case TT_NUMBER: str = "number"; break; - case TT_NAME: str = "name"; break; - case TT_PUNCTUATION: str = "punctuation"; break; - default: str = "unknown type"; break; - } - idLexer::Error( "expected a %s but found '%s'", str.c_str(), token->c_str() ); - return 0; - } - if ( token->type == TT_NUMBER ) { - if ( (token->subtype & subtype) != subtype ) { - str.Clear(); - if ( subtype & TT_DECIMAL ) str = "decimal "; - if ( subtype & TT_HEX ) str = "hex "; - if ( subtype & TT_OCTAL ) str = "octal "; - if ( subtype & TT_BINARY ) str = "binary "; - if ( subtype & TT_UNSIGNED ) str += "unsigned "; - if ( subtype & TT_LONG ) str += "long "; - if ( subtype & TT_FLOAT ) str += "float "; - if ( subtype & TT_INTEGER ) str += "integer "; - str.StripTrailing( ' ' ); - idLexer::Error( "expected %s but found '%s'", str.c_str(), token->c_str() ); - return 0; - } - } - else if ( token->type == TT_PUNCTUATION ) { - if ( subtype < 0 ) { - idLexer::Error( "BUG: wrong punctuation subtype" ); - return 0; - } - if ( token->subtype != subtype ) { - idLexer::Error( "expected '%s' but found '%s'", GetPunctuationFromId( subtype ), token->c_str() ); - return 0; - } - } - return 1; -} - -/* -================ -idLexer::ExpectAnyToken -================ -*/ -int idLexer::ExpectAnyToken( idToken *token ) { - if (!idLexer::ReadToken( token )) { - idLexer::Error( "couldn't read expected token" ); - return 0; - } - else { - return 1; - } -} - -/* -================ -idLexer::CheckTokenString -================ -*/ -int idLexer::CheckTokenString( const char *string ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return 0; - } - // if the given string is available - if ( tok == string ) { - return 1; - } - // unread token - script_p = lastScript_p; - line = lastline; - return 0; -} - -/* -================ -idLexer::CheckTokenType -================ -*/ -int idLexer::CheckTokenType( int type, int subtype, idToken *token ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return 0; - } - // if the type matches - if (tok.type == type && (tok.subtype & subtype) == subtype) { - *token = tok; - return 1; - } - // unread token - script_p = lastScript_p; - line = lastline; - return 0; -} - -/* -================ -idLexer::PeekTokenString -================ -*/ -int idLexer::PeekTokenString( const char *string ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return 0; - } - - // unread token - script_p = lastScript_p; - line = lastline; - - // if the given string is available - if ( tok == string ) { - return 1; - } - return 0; -} - -/* -================ -idLexer::PeekTokenType -================ -*/ -int idLexer::PeekTokenType( int type, int subtype, idToken *token ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return 0; - } - - // unread token - script_p = lastScript_p; - line = lastline; - - // if the type matches - if ( tok.type == type && ( tok.subtype & subtype ) == subtype ) { - *token = tok; - return 1; - } - return 0; -} - -/* -================ -idLexer::SkipUntilString -================ -*/ -int idLexer::SkipUntilString( const char *string ) { - idToken token; - - while(idLexer::ReadToken( &token )) { - if ( token == string ) { - return 1; - } - } - return 0; -} - -/* -================ -idLexer::SkipRestOfLine -================ -*/ -int idLexer::SkipRestOfLine( void ) { - idToken token; - - while(idLexer::ReadToken( &token )) { - if ( token.linesCrossed ) { - idLexer::script_p = lastScript_p; - idLexer::line = lastline; - return 1; - } - } - return 0; -} - -/* -================= -idLexer::SkipBracedSection - -Skips until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -int idLexer::SkipBracedSection( bool parseFirstBrace ) { - idToken token; - int depth; - - depth = parseFirstBrace ? 0 : 1; - do { - if ( !ReadToken( &token ) ) { - return false; - } - if ( token.type == TT_PUNCTUATION ) { - if ( token == "{" ) { - depth++; - } else if ( token == "}" ) { - depth--; - } - } - } while( depth ); - return true; -} - -/* -================ -idLexer::UnreadToken -================ -*/ -void idLexer::UnreadToken( const idToken *token ) { - if ( idLexer::tokenavailable ) { - idLib::common->FatalError( "idLexer::unreadToken, unread token twice\n" ); - } - idLexer::token = *token; - idLexer::tokenavailable = 1; -} - -/* -================ -idLexer::ReadTokenOnLine -================ -*/ -int idLexer::ReadTokenOnLine( idToken *token ) { - idToken tok; - - if (!idLexer::ReadToken( &tok )) { - idLexer::script_p = lastScript_p; - idLexer::line = lastline; - return false; - } - // if no lines were crossed before this token - if ( !tok.linesCrossed ) { - *token = tok; - return true; - } - // restore our position - idLexer::script_p = lastScript_p; - idLexer::line = lastline; - token->Clear(); - return false; -} - -/* - -================ - -idLexer::ReadRestOfLine - -================ - -*/ - -const char* idLexer::ReadRestOfLine(idStr& out) { - - while(1) { - - - if(*idLexer::script_p == '\n') { - - idLexer::line++; - - break; - - } - - - if(!*idLexer::script_p) { - - break; - - } - - - if(*idLexer::script_p <= ' ') { - - out += " "; - - } else { - - out += *idLexer::script_p; - - } - - idLexer::script_p++; - - - } - - - out.Strip(' '); - - return out.c_str(); - -} - - -/* -================ -idLexer::ParseInt -================ -*/ -int idLexer::ParseInt( void ) { - idToken token; - - if ( !idLexer::ReadToken( &token ) ) { - idLexer::Error( "couldn't read expected integer" ); - return 0; - } - if ( token.type == TT_PUNCTUATION && token == "-" ) { - idLexer::ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); - return -((signed int) token.GetIntValue()); - } - else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { - idLexer::Error( "expected integer value, found '%s'", token.c_str() ); - } - return token.GetIntValue(); -} - -/* -================ -idLexer::ParseBool -================ -*/ -bool idLexer::ParseBool( void ) { - idToken token; - - if ( !idLexer::ExpectTokenType( TT_NUMBER, 0, &token ) ) { - idLexer::Error( "couldn't read expected boolean" ); - return false; - } - return ( token.GetIntValue() != 0 ); -} - -/* -================ -idLexer::ParseFloat -================ -*/ -float idLexer::ParseFloat( bool *errorFlag ) { - idToken token; - - if ( errorFlag ) { - *errorFlag = false; - } - - if ( !idLexer::ReadToken( &token ) ) { - if ( errorFlag ) { - idLexer::Warning( "couldn't read expected floating point number" ); - *errorFlag = true; - } else { - idLexer::Error( "couldn't read expected floating point number" ); - } - return 0; - } - if ( token.type == TT_PUNCTUATION && token == "-" ) { - idLexer::ExpectTokenType( TT_NUMBER, 0, &token ); - return -token.GetFloatValue(); - } - else if ( token.type != TT_NUMBER ) { - if ( errorFlag ) { - idLexer::Warning( "expected float value, found '%s'", token.c_str() ); - *errorFlag = true; - } else { - idLexer::Error( "expected float value, found '%s'", token.c_str() ); - } - } - return token.GetFloatValue(); -} - -/* -================ -idLexer::Parse1DMatrix -================ -*/ -int idLexer::Parse1DMatrix( int x, float *m, bool bIntsOnly ) { - int i; - - if ( !idLexer::ExpectTokenString( "(" ) ) { - return false; - } - for ( i = 0; i < x; i++ ) { - if(bIntsOnly) - { - m[i] = idLexer::ParseInt(); - continue; - } - m[i] = idLexer::ParseFloat(); - } - - if ( !idLexer::ExpectTokenString( ")" ) ) { - return false; - } - return true; -} - -/* -================ -idLexer::Parse1DMatrix - -Overloaded to write an integer matrix instead of float. - -Added by Ishtvan @ The Dark Mod -================ -*/ -int idLexer::Parse1DMatrix( int x, int *m ) -{ - bool returnval; - int i; - float *mTemp; - if ((mTemp = new float[x]) == NULL) - { - Error( "Out of memory allocating for float to int conversion" ); - returnval = false; - goto Quit; - } - if (!Parse1DMatrix( x, mTemp, true )) - { - returnval = false; - goto Quit; - } - for (i=0; i= 0; - - while( depth && *idLexer::script_p ) { - char c = *(idLexer::script_p++); - - switch ( c ) { - case '\t': - case ' ': { - if ( skipWhite ) { - continue; - } - break; - } - case '\n': { - if ( doTabs ) { - skipWhite = true; - out += c; - continue; - } - break; - } - case '{': { - depth++; - tabs++; - break; - } - case '}': { - depth--; - tabs--; - break; - } - } - - if ( skipWhite ) { - int i = tabs; - if ( c == '{' ) { - i--; - } - skipWhite = false; - for ( ; i > 0; i-- ) { - out += '\t'; - } - } - out += c; - } - return out.c_str(); -} - -/* -================= -idLexer::ParseBracedSection - -The next token should be an open brace. -Parses until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -const char *idLexer::ParseBracedSection( idStr &out ) { - idToken token; - int i, depth; - - out.Empty(); - if ( !idLexer::ExpectTokenString( "{" ) ) { - return out.c_str(); - } - out = "{"; - depth = 1; - do { - if ( !idLexer::ReadToken( &token ) ) { - Error( "missing closing brace" ); - return out.c_str(); - } - - // if the token is on a new line - for ( i = 0; i < token.linesCrossed; i++ ) { - out += "\r\n"; - } - - if ( token.type == TT_PUNCTUATION ) { - if ( token[0] == '{' ) { - depth++; - } - else if ( token[0] == '}' ) { - depth--; - } - } - - if ( token.type == TT_STRING ) { - out += "\"" + token + "\""; - } - else { - out += token; - } - out += " "; - } while( depth ); - - return out.c_str(); -} - -/* -================= -idLexer::ParseRestOfLine - - parse the rest of the line -================= -*/ -const char *idLexer::ParseRestOfLine( idStr &out ) { - idToken token; - - out.Empty(); - while(idLexer::ReadToken( &token )) { - if ( token.linesCrossed ) { - idLexer::script_p = lastScript_p; - idLexer::line = lastline; - break; - } - if ( out.Length() ) { - out += " "; - } - out += token; - } - return out.c_str(); -} - -/* -================ -idLexer::GetLastWhiteSpace -================ -*/ -int idLexer::GetLastWhiteSpace( idStr &whiteSpace ) const { - whiteSpace.Clear(); - for ( const char *p = whiteSpaceStart_p; p < whiteSpaceEnd_p; p++ ) { - whiteSpace.Append( *p ); - } - return whiteSpace.Length(); -} - -/* -================ -idLexer::GetLastWhiteSpaceStart -================ -*/ -int idLexer::GetLastWhiteSpaceStart( void ) const { - return whiteSpaceStart_p - buffer; -} - -/* -================ -idLexer::GetLastWhiteSpaceEnd -================ -*/ -int idLexer::GetLastWhiteSpaceEnd( void ) const { - return whiteSpaceEnd_p - buffer; -} - -/* -================ -idLexer::Reset -================ -*/ -void idLexer::Reset( void ) { - // pointer in script buffer - idLexer::script_p = idLexer::buffer; - // pointer in script buffer before reading token - idLexer::lastScript_p = idLexer::buffer; - // begin of white space - idLexer::whiteSpaceStart_p = NULL; - // end of white space - idLexer::whiteSpaceEnd_p = NULL; - // set if there's a token available in idLexer::token - idLexer::tokenavailable = 0; - - idLexer::line = 1; - idLexer::lastline = 1; - // clear the saved token - idLexer::token = ""; -} - -/* -================ -idLexer::EndOfFile -================ -*/ -int idLexer::EndOfFile( void ) { - return idLexer::script_p >= idLexer::end_p; -} - -/* -================ -idLexer::NumLinesCrossed -================ -*/ -int idLexer::NumLinesCrossed( void ) { - return idLexer::line - idLexer::lastline; -} - -/* -================ -idLexer::LoadFile -================ -*/ -int idLexer::LoadFile( const char *filename, bool OSPath ) { - idFile *fp; - idStr pathname; - int length; - char *buf; - - if ( idLexer::loaded ) { - idLib::common->Error("idLexer::LoadFile: another script already loaded"); - return false; - } - - if ( !OSPath && ( baseFolder[0] != '\0' ) ) { - pathname = va( "%s/%s", baseFolder, filename ); - } else { - pathname = filename; - } - if ( OSPath ) { - fp = idLib::fileSystem->OpenExplicitFileRead( pathname ); - } else { - fp = idLib::fileSystem->OpenFileRead( pathname ); - } - if ( !fp ) { - return false; - } - length = fp->Length(); - buf = (char *) Mem_Alloc( length + 1 ); - buf[length] = '\0'; - fp->Read( buf, length ); - idLexer::fileTime = fp->Timestamp(); - idLexer::filename = fp->GetFullPath(); - idLib::fileSystem->CloseFile( fp ); - - idLexer::buffer = buf; - idLexer::length = length; - // pointer in script buffer - idLexer::script_p = idLexer::buffer; - // pointer in script buffer before reading token - idLexer::lastScript_p = idLexer::buffer; - // pointer to end of script buffer - idLexer::end_p = &(idLexer::buffer[length]); - - idLexer::tokenavailable = 0; - idLexer::line = 1; - idLexer::lastline = 1; - idLexer::allocated = true; - idLexer::loaded = true; - - return true; -} - -/* -================ -idLexer::LoadMemory -================ -*/ -int idLexer::LoadMemory( const char *ptr, int length, const char *name, int startLine ) { - if ( idLexer::loaded ) { - idLib::common->Error("idLexer::LoadMemory: another script already loaded"); - return false; - } - idLexer::filename = name; - idLexer::buffer = ptr; - idLexer::fileTime = 0; - idLexer::length = length; - // pointer in script buffer - idLexer::script_p = idLexer::buffer; - // pointer in script buffer before reading token - idLexer::lastScript_p = idLexer::buffer; - // pointer to end of script buffer - idLexer::end_p = &(idLexer::buffer[length]); - - idLexer::tokenavailable = 0; - idLexer::line = startLine; - idLexer::lastline = startLine; - idLexer::allocated = false; - idLexer::loaded = true; - - return true; -} - -/* -================ -idLexer::FreeSource -================ -*/ -void idLexer::FreeSource( void ) { -#ifdef PUNCTABLE - if ( idLexer::punctuationtable && idLexer::punctuationtable != default_punctuationtable ) { - Mem_Free( (void *) idLexer::punctuationtable ); - idLexer::punctuationtable = NULL; - } - if ( idLexer::nextpunctuation && idLexer::nextpunctuation != default_nextpunctuation ) { - Mem_Free( (void *) idLexer::nextpunctuation ); - idLexer::nextpunctuation = NULL; - } -#endif //PUNCTABLE - if ( idLexer::allocated ) { - Mem_Free( (void *) idLexer::buffer ); - idLexer::buffer = NULL; - idLexer::allocated = false; - } - idLexer::tokenavailable = 0; - idLexer::token = ""; - idLexer::loaded = false; -} - -/* -================ -idLexer::idLexer -================ -*/ -idLexer::idLexer( void ) { - idLexer::loaded = false; - idLexer::filename = ""; - idLexer::flags = 0; - idLexer::SetPunctuations( NULL ); - idLexer::allocated = false; - idLexer::fileTime = 0; - idLexer::length = 0; - idLexer::line = 0; - idLexer::lastline = 0; - idLexer::tokenavailable = 0; - idLexer::token = ""; - idLexer::next = NULL; - idLexer::hadError = false; -} - -/* -================ -idLexer::idLexer -================ -*/ -idLexer::idLexer( int flags ) { - idLexer::loaded = false; - idLexer::filename = ""; - idLexer::flags = flags; - idLexer::SetPunctuations( NULL ); - idLexer::allocated = false; - idLexer::fileTime = 0; - idLexer::length = 0; - idLexer::line = 0; - idLexer::lastline = 0; - idLexer::tokenavailable = 0; - idLexer::token = ""; - idLexer::next = NULL; - idLexer::hadError = false; -} - -/* -================ -idLexer::idLexer -================ -*/ -idLexer::idLexer( const char *filename, int flags, bool OSPath ) { - idLexer::loaded = false; - idLexer::flags = flags; - idLexer::SetPunctuations( NULL ); - idLexer::allocated = false; - idLexer::token = ""; - idLexer::next = NULL; - idLexer::hadError = false; - idLexer::LoadFile( filename, OSPath ); -} - -/* -================ -idLexer::idLexer -================ -*/ -idLexer::idLexer( const char *ptr, int length, const char *name, int flags ) { - idLexer::loaded = false; - idLexer::flags = flags; - idLexer::SetPunctuations( NULL ); - idLexer::allocated = false; - idLexer::token = ""; - idLexer::next = NULL; - idLexer::hadError = false; - idLexer::LoadMemory( ptr, length, name ); -} - -/* -================ -idLexer::~idLexer -================ -*/ -idLexer::~idLexer( void ) { - idLexer::FreeSource(); -} - -/* -================ -idLexer::SetBaseFolder -================ -*/ -void idLexer::SetBaseFolder( const char *path ) { - idStr::Copynz( baseFolder, path, sizeof( baseFolder ) ); -} - -/* -================ -idLexer::HadError -================ -*/ -bool idLexer::HadError( void ) const { - return hadError; -} - -#pragma warning( pop ) diff --git a/idlib/lexer.h b/idlib/lexer.h deleted file mode 100644 index 4c45d0b4c..000000000 --- a/idlib/lexer.h +++ /dev/null @@ -1,367 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LEXER_H__ -#define __LEXER_H__ - -/* -=============================================================================== - - Lexicographical parser - - Does not use memory allocation during parsing. The lexer uses no - memory allocation if a source is loaded with LoadMemory(). - However, idToken may still allocate memory for large strings. - - A number directly following the escape character '\' in a string is - assumed to be in decimal format instead of octal. Binary numbers of - the form 0b.. or 0B.. can also be used. - -=============================================================================== -*/ - -// lexer flags -typedef enum { - LEXFL_NOERRORS = BIT(0), // don't print any errors - LEXFL_NOWARNINGS = BIT(1), // don't print any warnings - LEXFL_NOFATALERRORS = BIT(2), // errors aren't fatal - LEXFL_NOSTRINGCONCAT = BIT(3), // multiple strings seperated by whitespaces are not concatenated - LEXFL_NOSTRINGESCAPECHARS = BIT(4), // no escape characters inside strings - LEXFL_NODOLLARPRECOMPILE = BIT(5), // don't use the $ sign for precompilation - LEXFL_NOBASEINCLUDES = BIT(6), // don't include files embraced with < > - LEXFL_ALLOWPATHNAMES = BIT(7), // allow path seperators in names - LEXFL_ALLOWNUMBERNAMES = BIT(8), // allow names to start with a number - LEXFL_ALLOWIPADDRESSES = BIT(9), // allow ip addresses to be parsed as numbers - LEXFL_ALLOWFLOATEXCEPTIONS = BIT(10), // allow float exceptions like 1.#INF or 1.#IND to be parsed - LEXFL_ALLOWMULTICHARLITERALS = BIT(11), // allow multi character literals - LEXFL_ALLOWBACKSLASHSTRINGCONCAT = BIT(12), // allow multiple strings seperated by '\' to be concatenated - LEXFL_ONLYSTRINGS = BIT(13) // parse as whitespace deliminated strings (quoted strings keep quotes) -} lexerFlags_t; - -// punctuation ids -#define P_RSHIFT_ASSIGN 1 -#define P_LSHIFT_ASSIGN 2 -#define P_PARMS 3 -#define P_PRECOMPMERGE 4 - -#define P_LOGIC_AND 5 -#define P_LOGIC_OR 6 -#define P_LOGIC_GEQ 7 -#define P_LOGIC_LEQ 8 -#define P_LOGIC_EQ 9 -#define P_LOGIC_UNEQ 10 - -#define P_MUL_ASSIGN 11 -#define P_DIV_ASSIGN 12 -#define P_MOD_ASSIGN 13 -#define P_ADD_ASSIGN 14 -#define P_SUB_ASSIGN 15 -#define P_INC 16 -#define P_DEC 17 - -#define P_BIN_AND_ASSIGN 18 -#define P_BIN_OR_ASSIGN 19 -#define P_BIN_XOR_ASSIGN 20 -#define P_RSHIFT 21 -#define P_LSHIFT 22 - -#define P_POINTERREF 23 -#define P_CPP1 24 -#define P_CPP2 25 -#define P_MUL 26 -#define P_DIV 27 -#define P_MOD 28 -#define P_ADD 29 -#define P_SUB 30 -#define P_ASSIGN 31 - -#define P_BIN_AND 32 -#define P_BIN_OR 33 -#define P_BIN_XOR 34 -#define P_BIN_NOT 35 - -#define P_LOGIC_NOT 36 -#define P_LOGIC_GREATER 37 -#define P_LOGIC_LESS 38 - -#define P_REF 39 -#define P_COMMA 40 -#define P_SEMICOLON 41 -#define P_COLON 42 -#define P_QUESTIONMARK 43 - -#define P_PARENTHESESOPEN 44 -#define P_PARENTHESESCLOSE 45 -#define P_BRACEOPEN 46 -#define P_BRACECLOSE 47 -#define P_SQBRACKETOPEN 48 -#define P_SQBRACKETCLOSE 49 -#define P_BACKSLASH 50 - -#define P_PRECOMP 51 -#define P_DOLLAR 52 - -// punctuation -typedef struct punctuation_s -{ - const char *p; // punctuation character(s) - int n; // punctuation id -} punctuation_t; - -/// A lexer created by ID software. -/** This is a lexer for C-like languages. Whitespace and C-style comments are - * ignored. The input line is broken up into tokens which consist of string - * literals, numeric literals, identifiers and operators. - * - * String literals are of the form "blah blah blah" or 'c', just like in C. - * Double-quoted strings can be of any length, but single-quoted strings are - * expected to contain a single character. (escape sequences are considered - * to form a single character, so '\n' is a valid string literal) The same - * escape characters as C are allowed. Adjacent (ignoring whitespace) string - * literals are considered to represent one long string literal who's - * contents is the concatenation of the smaller strings. For example, - * "foo" "bar" is equivelant to "foobar", and will be returned as a single - * token. - * Lexer flags relavent to string literals: - * LEXFL_NOSTRINGCONCAT: Adjacent string literals aren't considered to form - * one long string. Instead, each string is considered its own token. - * This will cause "foo" "bar" to be treated as two tokens instead of one. - * LEXFL_ALLOWBACKSLASHSTRINGCONCAT: Backslashes may be used to concatenate - * string literals. (whitespace is ignored) For example "foo" \ "bar" is - * equivelant to "foobar". If LEXFL_NOSTRINGCONCAT is also turned on, then - * "foo" "bar" is treated as two tokens, but "foo" \ "bar" is treated as - * one. - * LEXFL_ALLOWMULTICHARLITERALS: Single-quoted string literals such as 'x' - * may to contain multiple characters. So 'blah' is considered a valid - * string literal. 'foo' 'bar' is equivelant to 'foobar' unless - * LEXFL_NOSTRINGCONCAT is turned on. LEXFL_ALLOWBACKSLASHSTRINGCONCAT - * does not have an effect on single-quoted string literals. - * LEXFL_NOSTRINGESCAPECHARS: Escape characters aren't allowed in strings. - * Instead, backslashes are treated as the contents of the string. - * For example, "\\" would be a string of two characters, not one. - * Because of this, '\n' would no longer be a valid string literal, - * unless LEXFL_ALLOWMULTICHARLITERALS is turned on. - * - * I haven't learned much about numeric literals. As such, this section is a - * stub. - * Lexer flags relavent to numeric literals: - * LEXFL_ALLOWIPADDRESSES: allow ip addresses to be parsed as numbers - * LEXFL_ALLOWFLOATEXCEPTIONS: allow float exceptions like 1.#INF or 1.#IND to be parsed - * - * Identifiers (names) are the same as in C. They may contain letters, - * numbers and underscores, but may not start with numbers. - * Lexer flags relavent to identifiers: - * LEXFL_ALLOWPATHNAMES: Identifiers are also allowed to have slashes, - * backslashes, colons and periods in them. - * LEXFL_ALLOWNUMBERNAMES: An identifier may start with a numeric literal. - * LEXFL_ONLYSTRINGS: Tokens are only returned as strings and identifiers. - * Identifiers may contain dashes in them. I beleive this flag is buggy, - * since it looks like +blah is considered a single token, but blah+ is - * considered two. - * - * Generic lexer flags: - * LEXFL_NOERRORS: Errors are disabled. - * LEXFL_NOWARNINGS: Warnings are disabled. - * LEXFL_NOFATALERRORS: Errors are converted to warnings. This flag is - * redundant if LEXFL_NOERRORS is turned on. Even if LEXFL_NOWARNINGS is - * turned on, warnings that were converted from errors will not be ignored. - * - * Lexer flags that are used by the parser instead of the lexer: - * LEXFL_NODOLLARPRECOMPILE: don't use the $ sign for precompilation - * LEXFL_NOBASEINCLUDES: don't include files embraced with < > - * - * Other notes: UnreadToken() appears to be incompatible with many other - * functions, such as the Check or Peek functions. You should Either use - * UnreadToken() or the Peek/Check functions but not both. - * - */ -class idLexer { - - friend class idParser; - -public: - // constructor - idLexer(); - idLexer( int flags ); - idLexer( const char *filename, int flags = 0, bool OSPath = false ); - idLexer( const char *ptr, int length, const char *name, int flags = 0 ); - // destructor - ~idLexer(); - // load a script from the given file at the given offset with the given length - int LoadFile( const char *filename, bool OSPath = false ); - // load a script from the given memory with the given length and a specified line offset, - // so source strings extracted from a file can still refer to proper line numbers in the file - // NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0' - int LoadMemory( const char *ptr, int length, const char *name, int startLine = 1 ); - // free the script - void FreeSource( void ); - // returns true if a script is loaded - int IsLoaded( void ) { return idLexer::loaded; }; - // read a token - int ReadToken( idToken *token ); - // expect a certain token, reads the token when available - int ExpectTokenString( const char *string ); - // expect a certain token type - int ExpectTokenType( int type, int subtype, idToken *token ); - // expect a token - int ExpectAnyToken( idToken *token ); - // returns true when the token is available - int CheckTokenString( const char *string ); - // returns true an reads the token when a token with the given type is available - int CheckTokenType( int type, int subtype, idToken *token ); - // returns true if the next token equals the given string but does not remove the token from the source - int PeekTokenString( const char *string ); - // returns true if the next token equals the given type but does not remove the token from the source - int PeekTokenType( int type, int subtype, idToken *token ); - // skip tokens until the given token string is read - int SkipUntilString( const char *string ); - // skip the rest of the current line - int SkipRestOfLine( void ); - // skip the braced section - int SkipBracedSection( bool parseFirstBrace = true ); - // unread the given token - void UnreadToken( const idToken *token ); - // read a token only if on the same line - int ReadTokenOnLine( idToken *token ); - - //Returns the rest of the current line - const char* ReadRestOfLine(idStr& out); - - // read a signed integer - int ParseInt( void ); - // read a boolean - bool ParseBool( void ); - // read a floating point number. If errorFlag is NULL, a non-numeric token will - // issue an Error(). If it isn't NULL, it will issue a Warning() and set *errorFlag = true - float ParseFloat( bool *errorFlag = NULL ); - /** - * Parse a 1d float matrix of length x and store it in m. - * If bIntsOnly is TRUE, a non-integer token will issue an Error(). - **/ - int Parse1DMatrix( int x, float *m, bool bIntsOnly = false ); - /** - * Parse 1d integer matrix by overloading parse1DMatrix - **/ - int Parse1DMatrix( int x, int *m ); - int Parse2DMatrix( int y, int x, float *m ); - int Parse3DMatrix( int z, int y, int x, float *m ); - // parse a braced section into a string - const char * ParseBracedSection( idStr &out ); - // parse a braced section into a string, maintaining indents and newlines - const char * ParseBracedSectionExact ( idStr &out, int tabs = -1 ); - // parse the rest of the line - const char * ParseRestOfLine( idStr &out ); - // retrieves the white space characters before the last read token - int GetLastWhiteSpace( idStr &whiteSpace ) const; - // returns start index into text buffer of last white space - int GetLastWhiteSpaceStart( void ) const; - // returns end index into text buffer of last white space - int GetLastWhiteSpaceEnd( void ) const; - // set an array with punctuations, NULL restores default C/C++ set, see default_punctuations for an example - void SetPunctuations( const punctuation_t *p ); - // returns a pointer to the punctuation with the given id - const char * GetPunctuationFromId( int id ); - // get the id for the given punctuation - int GetPunctuationId( const char *p ); - // set lexer flags - void SetFlags( int flags ); - // get lexer flags - int GetFlags( void ); - // reset the lexer - void Reset( void ); - // returns true if at the end of the file - int EndOfFile( void ); - // returns the current filename - const char * GetFileName( void ); - // get offset in script - const int GetFileOffset( void ); - // get file time - const unsigned int GetFileTime( void ); - // returns the current line number - const int GetLineNum( void ); - // print an error message - void Error( const char *str, ... ) id_attribute((format(printf,2,3))); - - // print a warning message - - void Warning( const char *str, ... ) id_attribute((format(printf,2,3))); - - // returns true if Error() was called with LEXFL_NOFATALERRORS or LEXFL_NOERRORS set - bool HadError( void ) const; - - // set the base folder to load files from - static void SetBaseFolder( const char *path ); - -private: - int loaded; // set when a script file is loaded from file or memory - idStr filename; // file name of the script - int allocated; // true if buffer memory was allocated - const char * buffer; // buffer containing the script - const char * script_p; // current pointer in the script - const char * end_p; // pointer to the end of the script - const char * lastScript_p; // script pointer before reading token - const char * whiteSpaceStart_p; // start of last white space - const char * whiteSpaceEnd_p; // end of last white space - unsigned int fileTime; // file time - int length; // length of the script in bytes - int line; // current line in script - int lastline; // line before reading token - int tokenavailable; // set by unreadToken - int flags; // several script flags - const punctuation_t *punctuations; // the punctuations used in the script - int * punctuationtable; // ASCII table with punctuations - int * nextpunctuation; // next punctuation in chain - idToken token; // available token - idLexer * next; // next script in a chain - bool hadError; // set by idLexer::Error, even if the error is supressed - - static char baseFolder[ 256 ]; // base folder to load files from - -private: - void CreatePunctuationTable( const punctuation_t *punctuations ); - int ReadWhiteSpace( void ); - int ReadEscapeCharacter( char *ch ); - int ReadString( idToken *token, int quote ); - int ReadName( idToken *token ); - int ReadNumber( idToken *token ); - int ReadPunctuation( idToken *token ); - int ReadPrimitive( idToken *token ); - int CheckString( const char *str ) const; - int NumLinesCrossed( void ); -}; - -ID_INLINE const char *idLexer::GetFileName( void ) { - return idLexer::filename; -} - -ID_INLINE const int idLexer::GetFileOffset( void ) { - return idLexer::script_p - idLexer::buffer; -} - -ID_INLINE const unsigned int idLexer::GetFileTime( void ) { - return idLexer::fileTime; -} - -ID_INLINE const int idLexer::GetLineNum( void ) { - return idLexer::line; -} - -ID_INLINE void idLexer::SetFlags( int flags ) { - idLexer::flags = flags; -} - -ID_INLINE int idLexer::GetFlags( void ) { - return idLexer::flags; -} - -#endif /* !__LEXER_H__ */ - diff --git a/idlib/lib.cpp b/idlib/lib.cpp deleted file mode 100644 index 3451d53f9..000000000 --- a/idlib/lib.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#if defined( MACOS_X ) -#include -#include -#include -#endif - -/* -=============================================================================== - - idLib - -=============================================================================== -*/ - -idSys * idLib::sys = NULL; -idCommon * idLib::common = NULL; -idCVarSystem * idLib::cvarSystem = NULL; -idFileSystem * idLib::fileSystem = NULL; -int idLib::frameNumber = 0; - -/* -================ -idLib::Init -================ -*/ -void idLib::Init( void ) { - - assert( sizeof( bool ) == 1 ); - - // initialize little/big endian conversion - Swap_Init(); - - // initialize memory manager - Mem_Init(); - - // init string memory allocator - idStr::InitMemory(); - - // initialize generic SIMD implementation - idSIMD::Init(); - - // initialize math - idMath::Init(); - - // test idMatX - //idMatX::Test(); - - // test idPolynomial - idPolynomial::Test(); - - // initialize the dictionary string pools - idDict::Init(); -} - -/* -================ -idLib::ShutDown -================ -*/ -void idLib::ShutDown( void ) { - - // shut down the dictionary string pools - idDict::Shutdown(); - - // shut down the string memory allocator - idStr::ShutdownMemory(); - - // shut down the SIMD engine - idSIMD::Shutdown(); - - // shut down the memory manager - Mem_Shutdown(); -} - - -/* -=============================================================================== - - Colors - -=============================================================================== -*/ - -idVec4 colorBlack = idVec4( 0.00f, 0.00f, 0.00f, 1.00f ); -idVec4 colorWhite = idVec4( 1.00f, 1.00f, 1.00f, 1.00f ); -idVec4 colorRed = idVec4( 1.00f, 0.00f, 0.00f, 1.00f ); -idVec4 colorGreen = idVec4( 0.00f, 1.00f, 0.00f, 1.00f ); -idVec4 colorBlue = idVec4( 0.00f, 0.00f, 1.00f, 1.00f ); -idVec4 colorYellow = idVec4( 1.00f, 1.00f, 0.00f, 1.00f ); -idVec4 colorMagenta= idVec4( 1.00f, 0.00f, 1.00f, 1.00f ); -idVec4 colorCyan = idVec4( 0.00f, 1.00f, 1.00f, 1.00f ); -idVec4 colorOrange = idVec4( 1.00f, 0.50f, 0.00f, 1.00f ); -idVec4 colorPurple = idVec4( 0.60f, 0.00f, 0.60f, 1.00f ); -idVec4 colorPink = idVec4( 0.73f, 0.40f, 0.48f, 1.00f ); -idVec4 colorBrown = idVec4( 0.40f, 0.35f, 0.08f, 1.00f ); -idVec4 colorLtGrey = idVec4( 0.75f, 0.75f, 0.75f, 1.00f ); -idVec4 colorMdGrey = idVec4( 0.50f, 0.50f, 0.50f, 1.00f ); -idVec4 colorDkGrey = idVec4( 0.25f, 0.25f, 0.25f, 1.00f ); - -static dword colorMask[2] = { 255, 0 }; - -/* -================ -ColorFloatToByte -================ -*/ -ID_INLINE static byte ColorFloatToByte( float c ) { - return (byte) ( ( (dword) ( c * 255.0f ) ) & colorMask[FLOATSIGNBITSET(c)] ); -} - -/* -================ -PackColor -================ -*/ -dword PackColor( const idVec4 &color ) { - dword dw, dx, dy, dz; - - dx = ColorFloatToByte( color.x ); - dy = ColorFloatToByte( color.y ); - dz = ColorFloatToByte( color.z ); - dw = ColorFloatToByte( color.w ); - -#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) - return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 ) | ( dw << 24 ); -#elif (defined(MACOS_X) && defined(__ppc__)) - return ( dx << 24 ) | ( dy << 16 ) | ( dz << 8 ) | ( dw << 0 ); -#else -#error OS define is required! -#endif -} - -/* -================ -UnpackColor -================ -*/ -void UnpackColor( const dword color, idVec4 &unpackedColor ) { -#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) - unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ) ); -#elif (defined(MACOS_X) && defined(__ppc__)) - unpackedColor.Set( ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) ); -#else -#error OS define is required! -#endif -} - -/* -================ -PackColor -================ -*/ -dword PackColor( const idVec3 &color ) { - dword dx, dy, dz; - - dx = ColorFloatToByte( color.x ); - dy = ColorFloatToByte( color.y ); - dz = ColorFloatToByte( color.z ); - -#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) - return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 ); -#elif (defined(MACOS_X) && defined(__ppc__)) - return ( dy << 16 ) | ( dz << 8 ) | ( dx << 0 ); -#else -#error OS define is required! -#endif -} - -/* -================ -UnpackColor -================ -*/ -void UnpackColor( const dword color, idVec3 &unpackedColor ) { -#if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__)) - unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ) ); -#elif (defined(MACOS_X) && defined(__ppc__)) - unpackedColor.Set( ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ), - ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) ); -#else -#error OS define is required! -#endif -} - -/* -=============== -idLib::Error -=============== -*/ -void idLib::Error( const char *fmt, ... ) { - va_list argptr; - char text[MAX_STRING_CHARS]; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - common->Error( "%s", text ); -} - -/* -=============== -idLib::Warning -=============== -*/ -void idLib::Warning( const char *fmt, ... ) { - va_list argptr; - char text[MAX_STRING_CHARS]; - - va_start( argptr, fmt ); - idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - common->Warning( "%s", text ); -} - -/* -=============================================================================== - - Byte order functions - -=============================================================================== -*/ - -// can't just use function pointers, or dll linkage can mess up -static short (*_BigShort)( short l ); -static short (*_LittleShort)( short l ); -static int (*_BigLong)( int l ); -static int (*_LittleLong)( int l ); -static float (*_BigFloat)( float l ); -static float (*_LittleFloat)( float l ); -static void (*_BigRevBytes)( void *bp, int elsize, int elcount ); -static void (*_LittleRevBytes)( void *bp, int elsize, int elcount ); -static void (*_LittleBitField)( void *bp, int elsize ); -static void (*_SixtetsForInt)( byte *out, int src ); -static int (*_IntForSixtets)( byte *in ); - -short BigShort( short l ) { return _BigShort( l ); } -short LittleShort( short l ) { return _LittleShort( l ); } -int BigLong( int l ) { return _BigLong( l ); } -int LittleLong( int l ) { return _LittleLong( l ); } -float BigFloat( float l ) { return _BigFloat( l ); } -float LittleFloat( float l ) { return _LittleFloat( l ); } -void BigRevBytes( void *bp, int elsize, int elcount ) { _BigRevBytes( bp, elsize, elcount ); } -void LittleRevBytes( void *bp, int elsize, int elcount ){ _LittleRevBytes( bp, elsize, elcount ); } -void LittleBitField( void *bp, int elsize ){ _LittleBitField( bp, elsize ); } - -void SixtetsForInt( byte *out, int src) { _SixtetsForInt( out, src ); } -int IntForSixtets( byte *in ) { return _IntForSixtets( in ); } - -/* -================ -ShortSwap -================ -*/ -short ShortSwap( short l ) { - byte b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; -} - -/* -================ -ShortNoSwap -================ -*/ -short ShortNoSwap( short l ) { - return l; -} - -/* -================ -LongSwap -================ -*/ -int LongSwap ( int l ) { - byte b1,b2,b3,b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; -} - -/* -================ -LongNoSwap -================ -*/ -int LongNoSwap( int l ) { - return l; -} - -/* -================ -FloatSwap -================ -*/ -float FloatSwap( float f ) { - union { - float f; - byte b[4]; - } dat1, dat2; - - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; -} - -/* -================ -FloatNoSwap -================ -*/ -float FloatNoSwap( float f ) { - return f; -} - -/* -===================================================================== -RevBytesSwap - -Reverses byte order in place. - -INPUTS - bp bytes to reverse - elsize size of the underlying data type - elcount number of elements to swap - -RESULTS - Reverses the byte order in each of elcount elements. -===================================================================== */ -void RevBytesSwap( void *bp, int elsize, int elcount ) { - register unsigned char *p, *q; - - p = ( unsigned char * ) bp; - - if ( elsize == 2 ) { - q = p + 1; - while ( elcount-- ) { - *p ^= *q; - *q ^= *p; - *p ^= *q; - p += 2; - q += 2; - } - return; - } - - while ( elcount-- ) { - q = p + elsize - 1; - while ( p < q ) { - *p ^= *q; - *q ^= *p; - *p ^= *q; - ++p; - --q; - } - p += elsize >> 1; - } -} - -/* - ===================================================================== - RevBytesSwap - - Reverses byte order in place, then reverses bits in those bytes - - INPUTS - bp bitfield structure to reverse - elsize size of the underlying data type - - RESULTS - Reverses the bitfield of size elsize. - ===================================================================== */ -void RevBitFieldSwap( void *bp, int elsize) { - int i; - unsigned char *p, t, v; - - LittleRevBytes( bp, elsize, 1 ); - - p = (unsigned char *) bp; - while ( elsize-- ) { - v = *p; - t = 0; - for (i = 7; i; i--) { - t <<= 1; - v >>= 1; - t |= v & 1; - } - *p++ = t; - } -} - -/* -================ -RevBytesNoSwap -================ -*/ -void RevBytesNoSwap( void *bp, int elsize, int elcount ) { - return; -} - -/* - ================ - RevBytesNoSwap - ================ - */ -void RevBitFieldNoSwap( void *bp, int elsize ) { - return; -} - -/* -================ -SixtetsForIntLittle -================ -*/ -void SixtetsForIntLittle( byte *out, int src) { - byte *b = (byte *)&src; - out[0] = ( b[0] & 0xfc ) >> 2; - out[1] = ( ( b[0] & 0x3 ) << 4 ) + ( ( b[1] & 0xf0 ) >> 4 ); - out[2] = ( ( b[1] & 0xf ) << 2 ) + ( ( b[2] & 0xc0 ) >> 6 ); - out[3] = b[2] & 0x3f; -} - -/* -================ -SixtetsForIntBig -TTimo: untested - that's the version from initial base64 encode -================ -*/ -void SixtetsForIntBig( byte *out, int src) { - for( int i = 0 ; i < 4 ; i++ ) { - out[i] = src & 0x3f; - src >>= 6; - } -} - -/* -================ -IntForSixtetsLittle -================ -*/ -int IntForSixtetsLittle( byte *in ) { - int ret = 0; - byte *b = (byte *)&ret; - b[0] |= in[0] << 2; - b[0] |= ( in[1] & 0x30 ) >> 4; - b[1] |= ( in[1] & 0xf ) << 4; - b[1] |= ( in[2] & 0x3c ) >> 2; - b[2] |= ( in[2] & 0x3 ) << 6; - b[2] |= in[3]; - return ret; -} - -/* -================ -IntForSixtetsBig -TTimo: untested - that's the version from initial base64 decode -================ -*/ -int IntForSixtetsBig( byte *in ) { - int ret = 0; - ret |= in[0]; - ret |= in[1] << 6; - ret |= in[2] << 2*6; - ret |= in[3] << 3*6; - return ret; -} - -/* -================ -Swap_Init -================ -*/ -void Swap_Init( void ) { - byte swaptest[2] = {1,0}; - - // set the byte swapping variables in a portable manner - if ( *(short *)swaptest == 1) { - // little endian ex: x86 - _BigShort = ShortSwap; - _LittleShort = ShortNoSwap; - _BigLong = LongSwap; - _LittleLong = LongNoSwap; - _BigFloat = FloatSwap; - _LittleFloat = FloatNoSwap; - _BigRevBytes = RevBytesSwap; - _LittleRevBytes = RevBytesNoSwap; - _LittleBitField = RevBitFieldNoSwap; - _SixtetsForInt = SixtetsForIntLittle; - _IntForSixtets = IntForSixtetsLittle; - } else { - // big endian ex: ppc - _BigShort = ShortNoSwap; - _LittleShort = ShortSwap; - _BigLong = LongNoSwap; - _LittleLong = LongSwap; - _BigFloat = FloatNoSwap; - _LittleFloat = FloatSwap; - _BigRevBytes = RevBytesNoSwap; - _LittleRevBytes = RevBytesSwap; - _LittleBitField = RevBitFieldSwap; - _SixtetsForInt = SixtetsForIntBig; - _IntForSixtets = IntForSixtetsBig; - } -} - -/* -========== -Swap_IsBigEndian -========== -*/ -bool Swap_IsBigEndian( void ) { - byte swaptest[2] = {1,0}; - return *(short *)swaptest != 1; -} - -/* -=============================================================================== - - Assertion - -=============================================================================== -*/ - -void AssertFailed( const char *file, int line, const char *expression ) { - idLib::sys->DebugPrintf( "\n\nASSERTION FAILED!\n%s(%d): '%s'\n", file, line, expression ); -#ifdef _WIN32 - __asm int 0x03 -#elif defined( __linux__ ) - __asm__ __volatile__ ("int $0x03"); -#elif defined( MACOS_X ) - kill( getpid(), SIGINT ); -#endif -} diff --git a/idlib/lib.h b/idlib/lib.h deleted file mode 100644 index abdeeabd9..000000000 --- a/idlib/lib.h +++ /dev/null @@ -1,236 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LIB_H__ -#define __LIB_H__ -/* -=============================================================================== - - idLib contains stateless support classes and concrete types. Some classes - do have static variables, but such variables are initialized once and - read-only after initialization (they do not maintain a modifiable state). - - The interface pointers idSys, idCommon, idCVarSystem and idFileSystem - should be set before using idLib. The pointers stored here should not - be used by any part of the engine except for idLib. - - The frameNumber should be continuously set to the number of the current - frame if frame base memory logging is required. - -=============================================================================== -*/ - -#include - -class idLib { -public: - static class idSys * sys; - static class idCommon * common; - static class idCVarSystem * cvarSystem; - static class idFileSystem * fileSystem; - static int frameNumber; - - static void Init( void ); - static void ShutDown( void ); - - // wrapper to idCommon functions - static void Error( const char *fmt, ... ); - static void Warning( const char *fmt, ... ); -}; - - -/* -=============================================================================== - - Types and defines used throughout the engine. - -=============================================================================== -*/ - -typedef unsigned char byte; // 8 bits -typedef unsigned short word; // 16 bits -typedef unsigned int dword; // 32 bits -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef int qhandle_t; - -class idFile; -class idVec3; -class idVec4; - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef BIT -#define BIT( num ) ( 1 << ( num ) ) -#endif - -/* Bit operations */ -#define BITCHK(flag,bit) (((flag)&(bit))==(bit)) /* if all the bits are set */ -#define BITANY(flag,bit) ((flag)&(bit)) /* if any bit is set */ -#define BITSET(flag,bit) flag|=(bit) -#define BITCLR(flag,bit) flag&=(~(bit)) -#define BITFLIP(flag,bit) if (BIT( (flag),(bit) )) BITCLR( (flag),(bit) ); else BITSET( (flag),(bit) ) - - -#define MAX_STRING_CHARS 1024 // max length of a string - -// maximum world size -#define MAX_WORLD_COORD ( 128 * 1024 ) -#define MIN_WORLD_COORD ( -128 * 1024 ) -#define MAX_WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD ) - -// basic colors -extern idVec4 colorBlack; -extern idVec4 colorWhite; -extern idVec4 colorRed; -extern idVec4 colorGreen; -extern idVec4 colorBlue; -extern idVec4 colorYellow; -extern idVec4 colorMagenta; -extern idVec4 colorCyan; -extern idVec4 colorOrange; -extern idVec4 colorPurple; -extern idVec4 colorPink; -extern idVec4 colorBrown; -extern idVec4 colorLtGrey; -extern idVec4 colorMdGrey; -extern idVec4 colorDkGrey; - -// packs color floats in the range [0,1] into an integer -dword PackColor( const idVec3 &color ); -void UnpackColor( const dword color, idVec3 &unpackedColor ); -dword PackColor( const idVec4 &color ); -void UnpackColor( const dword color, idVec4 &unpackedColor ); - -// little/big endian conversion -short BigShort( short l ); -short LittleShort( short l ); -int BigLong( int l ); -int LittleLong( int l ); -float BigFloat( float l ); -float LittleFloat( float l ); -void BigRevBytes( void *bp, int elsize, int elcount ); -void LittleRevBytes( void *bp, int elsize, int elcount ); -void LittleBitField( void *bp, int elsize ); -void Swap_Init( void ); - -bool Swap_IsBigEndian( void ); - -// for base64 -void SixtetsForInt( byte *out, int src); -int IntForSixtets( byte *in ); - - -#ifdef _DEBUG -void AssertFailed( const char *file, int line, const char *expression ); -#undef assert -#define assert( X ) if ( X ) { } else AssertFailed( __FILE__, __LINE__, #X ) -#endif - -class idException { -public: - char error[MAX_STRING_CHARS]; - - idException( const char *text = "" ) { strcpy( error, text ); } -}; - - -/* -=============================================================================== - - idLib headers. - -=============================================================================== -*/ - -// memory management and arrays -#include "heap.h" -#include "containers/list.h" - -// math -#include "math/simd.h" -#include "math/math.h" -#include "math/random.h" -#include "math/complex.h" -#include "math/vector.h" -#include "math/matrix.h" -#include "math/angles.h" -#include "math/quat.h" -#include "math/rotation.h" -#include "math/plane.h" -#include "math/pluecker.h" -#include "math/polynomial.h" -#include "math/extrapolate.h" -#include "math/interpolate.h" -#include "math/curve.h" -#include "math/ode.h" -#include "math/lcp.h" - -// bounding volumes -#include "bv/sphere.h" -#include "bv/bounds.h" -#include "bv/box.h" -#include "bv/frustum.h" - -// geometry -#include "geometry/drawvert.h" -#include "geometry/jointtransform.h" -#include "geometry/winding.h" -#include "geometry/winding2d.h" -#include "geometry/surface.h" -#include "geometry/surface_patch.h" -#include "geometry/surface_polytope.h" -#include "geometry/surface_sweptspline.h" -#include "geometry/tracemodel.h" - -// text manipulation -#include "str.h" -#include "token.h" -#include "lexer.h" -#include "parser.h" -#include "base64.h" -#include "cmdargs.h" - -// containers -#include "containers/btree.h" -#include "containers/binsearch.h" -#include "containers/hashindex.h" -#include "containers/hashtable.h" -#include "containers/staticlist.h" -#include "containers/linklist.h" -#include "containers/hierarchy.h" -#include "containers/queue.h" -#include "containers/stack.h" -#include "containers/strlist.h" -#include "containers/strpool.h" -#include "containers/vectorset.h" -#include "containers/planeset.h" - -// hashing -#include "hashing/crc8.h" -#include "hashing/crc16.h" -#include "hashing/crc32.h" -#include "hashing/honeyman.h" -#include "hashing/md4.h" -#include "hashing/md5.h" - -// misc -#include "dict.h" -#include "langdict.h" -#include "bitmsg.h" -#include "mapfile.h" -#include "timer.h" - -#endif /* !__LIB_H__ */ diff --git a/idlib/mapfile.cpp b/idlib/mapfile.cpp deleted file mode 100644 index 739a19ef2..000000000 --- a/idlib/mapfile.cpp +++ /dev/null @@ -1,956 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning( push ) -#pragma warning( disable : 4127 ) -/* -=============== -FloatCRC -=============== -*/ -ID_INLINE unsigned int FloatCRC( float f ) { - return *(unsigned int *)&f; -} - -/* -=============== -StringCRC -=============== -*/ -ID_INLINE unsigned int StringCRC( const char *str ) { - unsigned int i, crc; - const unsigned char *ptr; - - crc = 0; - ptr = reinterpret_cast(str); - for ( i = 0; str[i]; i++ ) { - crc ^= str[i] << (i & 3); - } - return crc; -} - -/* -================= -ComputeAxisBase - -WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0 -rotation by (0,RotY,RotZ) assigns X to normal -================= -*/ -static void ComputeAxisBase( const idVec3 &normal, idVec3 &texS, idVec3 &texT ) { - float RotY, RotZ; - idVec3 n; - - // do some cleaning - n[0] = ( idMath::Fabs( normal[0] ) < 1e-6f ) ? 0.0f : normal[0]; - n[1] = ( idMath::Fabs( normal[1] ) < 1e-6f ) ? 0.0f : normal[1]; - n[2] = ( idMath::Fabs( normal[2] ) < 1e-6f ) ? 0.0f : normal[2]; - - RotY = -atan2( n[2], idMath::Sqrt( n[1] * n[1] + n[0] * n[0]) ); - RotZ = atan2( n[1], n[0] ); - // rotate (0,1,0) and (0,0,1) to compute texS and texT - texS[0] = -sin(RotZ); - texS[1] = cos(RotZ); - texS[2] = 0; - // the texT vector is along -Z ( T texture coorinates axis ) - texT[0] = -sin(RotY) * cos(RotZ); - texT[1] = -sin(RotY) * sin(RotZ); - texT[2] = -cos(RotY); -} - -/* -================= -idMapBrushSide::GetTextureVectors -================= -*/ -void idMapBrushSide::GetTextureVectors( idVec4 v[2] ) const { - int i; - idVec3 texX, texY; - - ComputeAxisBase( plane.Normal(), texX, texY ); - for ( i = 0; i < 2; i++ ) { - v[i][0] = texX[0] * texMat[i][0] + texY[0] * texMat[i][1]; - v[i][1] = texX[1] * texMat[i][0] + texY[1] * texMat[i][1]; - v[i][2] = texX[2] * texMat[i][0] + texY[2] * texMat[i][1]; - v[i][3] = texMat[i][2] + ( origin * v[i].ToVec3() ); - } -} - -/* -================= -idMapPatch::Parse -================= -*/ -idMapPatch *idMapPatch::Parse( idLexer &src, const idVec3 &origin, bool patchDef3, float version ) { - float info[7]; - idDrawVert *vert; - idToken token; - int i, j; - - if ( !src.ExpectTokenString( "{" ) ) { - return NULL; - } - - // read the material (we had an implicit 'textures/' in the old format...) - if ( !src.ReadToken( &token ) ) { - src.Error( "idMapPatch::Parse: unexpected EOF" ); - return NULL; - } - - // Parse it - if (patchDef3) { - if ( !src.Parse1DMatrix( 7, info ) ) { - src.Error( "idMapPatch::Parse: unable to Parse patchDef3 info" ); - return NULL; - } - } else { - if ( !src.Parse1DMatrix( 5, info ) ) { - src.Error( "idMapPatch::Parse: unable to parse patchDef2 info" ); - return NULL; - } - } - - idMapPatch *patch = new idMapPatch( static_cast(info[0]), static_cast(info[1]) ); - patch->SetSize( static_cast(info[0]), static_cast(info[1]) ); - if ( version < 2.0f ) { - patch->SetMaterial( "textures/" + token ); - } else { - patch->SetMaterial( token ); - } - - if ( patchDef3 ) { - patch->SetHorzSubdivisions( static_cast(info[2]) ); - patch->SetVertSubdivisions( static_cast(info[3]) ); - patch->SetExplicitlySubdivided( true ); - } - - if ( patch->GetWidth() < 0 || patch->GetHeight() < 0 ) { - src.Error( "idMapPatch::Parse: bad size" ); - delete patch; - return NULL; - } - - // these were written out in the wrong order, IMHO - if ( !src.ExpectTokenString( "(" ) ) { - src.Error( "idMapPatch::Parse: bad patch vertex data" ); - delete patch; - return NULL; - } - for ( j = 0; j < patch->GetWidth(); j++ ) { - if ( !src.ExpectTokenString( "(" ) ) { - src.Error( "idMapPatch::Parse: bad vertex row data" ); - delete patch; - return NULL; - } - for ( i = 0; i < patch->GetHeight(); i++ ) { - float v[5]; - - if ( !src.Parse1DMatrix( 5, v ) ) { - src.Error( "idMapPatch::Parse: bad vertex column data" ); - delete patch; - return NULL; - } - - vert = &((*patch)[i * patch->GetWidth() + j]); - vert->xyz[0] = v[0] - origin[0]; - vert->xyz[1] = v[1] - origin[1]; - vert->xyz[2] = v[2] - origin[2]; - vert->st[0] = v[3]; - vert->st[1] = v[4]; - } - if ( !src.ExpectTokenString( ")" ) ) { - delete patch; - src.Error( "idMapPatch::Parse: unable to parse patch control points" ); - return NULL; - } - } - if ( !src.ExpectTokenString( ")" ) ) { - src.Error( "idMapPatch::Parse: unable to parse patch control points, no closure" ); - delete patch; - return NULL; - } - - // read any key/value pairs - while( src.ReadToken( &token ) ) { - if ( token == "}" ) { - src.ExpectTokenString( "}" ); - break; - } - if ( token.type == TT_STRING ) { - idStr key = token; - src.ExpectTokenType( TT_STRING, 0, &token ); - patch->epairs.Set( key, token ); - } - } - - return patch; -} - -/* -============ -idMapPatch::Write -============ -*/ -bool idMapPatch::Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const { - int i, j; - const idDrawVert *v; - - if ( GetExplicitlySubdivided() ) { - fp->WriteFloatString( "// primitive %d\n{\n patchDef3\n {\n", primitiveNum ); - fp->WriteFloatString( " \"%s\"\n ( %d %d %d %d 0 0 0 )\n", GetMaterial(), GetWidth(), GetHeight(), GetHorzSubdivisions(), GetVertSubdivisions()); - } else { - fp->WriteFloatString( "// primitive %d\n{\n patchDef2\n {\n", primitiveNum ); - fp->WriteFloatString( " \"%s\"\n ( %d %d 0 0 0 )\n", GetMaterial(), GetWidth(), GetHeight()); - } - - fp->WriteFloatString( " (\n" ); - for ( i = 0; i < GetWidth(); i++ ) { - fp->WriteFloatString( " ( " ); - for ( j = 0; j < GetHeight(); j++ ) { - v = &verts[ j * GetWidth() + i ]; - fp->WriteFloatString( " ( %f %f %f %f %f )", v->xyz[0] + origin[0], - v->xyz[1] + origin[1], v->xyz[2] + origin[2], v->st[0], v->st[1] ); - } - fp->WriteFloatString( " )\n" ); - } - fp->WriteFloatString( " )\n }\n}\n" ); - - return true; -} - -/* -=============== -idMapPatch::GetGeometryCRC -=============== -*/ -unsigned int idMapPatch::GetGeometryCRC( void ) const { - int i, j; - unsigned int crc; - - crc = GetHorzSubdivisions() ^ GetVertSubdivisions(); - for ( i = 0; i < GetWidth(); i++ ) { - for ( j = 0; j < GetHeight(); j++ ) { - crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.x ); - crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.y ); - crc ^= FloatCRC( verts[j * GetWidth() + i].xyz.z ); - } - } - - crc ^= StringCRC( GetMaterial() ); - - return crc; -} - -/* -================= -idMapBrush::Parse -================= -*/ -idMapBrush *idMapBrush::Parse( idLexer &src, const idVec3 &origin, bool newFormat, float version ) { - int i; - idVec3 planepts[3]; - idToken token; - idList sides; - idMapBrushSide *side; - idDict epairs; - - if ( !src.ExpectTokenString( "{" ) ) { - return NULL; - } - - do { - if ( !src.ReadToken( &token ) ) { - src.Error( "idMapBrush::Parse: unexpected EOF" ); - sides.DeleteContents( true ); - return NULL; - } - if ( token == "}" ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is a brace - if ( token == "(" ) { - break; - } - // the token should be a key string for a key/value pair - if ( token.type != TT_STRING ) { - src.Error( "idMapBrush::Parse: unexpected %s, expected ( or epair key string", token.c_str() ); - sides.DeleteContents( true ); - return NULL; - } - - idStr key = token; - - if ( !src.ReadTokenOnLine( &token ) || token.type != TT_STRING ) { - src.Error( "idMapBrush::Parse: expected epair value string not found" ); - sides.DeleteContents( true ); - return NULL; - } - - epairs.Set( key, token ); - - // try to read the next key - if ( !src.ReadToken( &token ) ) { - src.Error( "idMapBrush::Parse: unexpected EOF" ); - sides.DeleteContents( true ); - return NULL; - } - } while (1); - - src.UnreadToken( &token ); - - side = new idMapBrushSide(); - sides.Append(side); - - if ( newFormat ) { - if ( !src.Parse1DMatrix( 4, side->plane.ToFloatPtr() ) ) { - src.Error( "idMapBrush::Parse: unable to read brush side plane definition" ); - sides.DeleteContents( true ); - return NULL; - } - } else { - // read the three point plane definition - if (!src.Parse1DMatrix( 3, planepts[0].ToFloatPtr() ) || - !src.Parse1DMatrix( 3, planepts[1].ToFloatPtr() ) || - !src.Parse1DMatrix( 3, planepts[2].ToFloatPtr() ) ) { - src.Error( "idMapBrush::Parse: unable to read brush side plane definition" ); - sides.DeleteContents( true ); - return NULL; - } - - planepts[0] -= origin; - planepts[1] -= origin; - planepts[2] -= origin; - - side->plane.FromPoints( planepts[0], planepts[1], planepts[2] ); - } - - // read the texture matrix - // this is odd, because the texmat is 2D relative to default planar texture axis - if ( !src.Parse2DMatrix( 2, 3, side->texMat[0].ToFloatPtr() ) ) { - src.Error( "idMapBrush::Parse: unable to read brush side texture matrix" ); - sides.DeleteContents( true ); - return NULL; - } - side->origin = origin; - - // read the material - if ( !src.ReadTokenOnLine( &token ) ) { - src.Error( "idMapBrush::Parse: unable to read brush side material" ); - sides.DeleteContents( true ); - return NULL; - } - - // we had an implicit 'textures/' in the old format... - if ( version < 2.0f ) { - side->material = "textures/" + token; - } else { - side->material = token; - } - - // Q2 allowed override of default flags and values, but we don't any more - if ( src.ReadTokenOnLine( &token ) ) { - if ( src.ReadTokenOnLine( &token ) ) { - if ( src.ReadTokenOnLine( &token ) ) { - } - } - } - } while( 1 ); - - if ( !src.ExpectTokenString( "}" ) ) { - sides.DeleteContents( true ); - return NULL; - } - - idMapBrush *brush = new idMapBrush(); - for ( i = 0; i < sides.Num(); i++ ) { - brush->AddSide( sides[i] ); - } - - brush->epairs = epairs; - - return brush; -} - -/* -================= -idMapBrush::ParseQ3 -================= -*/ -idMapBrush *idMapBrush::ParseQ3( idLexer &src, const idVec3 &origin ) { - int i, shift[2], rotate; - float scale[2]; - idVec3 planepts[3]; - idToken token; - idList sides; - idMapBrushSide *side; - idDict epairs; - - do { - if ( src.CheckTokenString( "}" ) ) { - break; - } - - side = new idMapBrushSide(); - sides.Append( side ); - - // read the three point plane definition - if (!src.Parse1DMatrix( 3, planepts[0].ToFloatPtr() ) || - !src.Parse1DMatrix( 3, planepts[1].ToFloatPtr() ) || - !src.Parse1DMatrix( 3, planepts[2].ToFloatPtr() ) ) { - src.Error( "idMapBrush::ParseQ3: unable to read brush side plane definition" ); - sides.DeleteContents( true ); - return NULL; - } - - planepts[0] -= origin; - planepts[1] -= origin; - planepts[2] -= origin; - - side->plane.FromPoints( planepts[0], planepts[1], planepts[2] ); - - // read the material - if ( !src.ReadTokenOnLine( &token ) ) { - src.Error( "idMapBrush::ParseQ3: unable to read brush side material" ); - sides.DeleteContents( true ); - return NULL; - } - - // we have an implicit 'textures/' in the old format - side->material = "textures/" + token; - - // read the texture shift, rotate and scale - shift[0] = src.ParseInt(); - shift[1] = src.ParseInt(); - rotate = src.ParseInt(); - scale[0] = src.ParseFloat(); - scale[1] = src.ParseFloat(); - side->texMat[0] = idVec3( 0.03125f, 0.0f, 0.0f ); - side->texMat[1] = idVec3( 0.0f, 0.03125f, 0.0f ); - side->origin = origin; - - // Q2 allowed override of default flags and values, but we don't any more - if ( src.ReadTokenOnLine( &token ) ) { - if ( src.ReadTokenOnLine( &token ) ) { - if ( src.ReadTokenOnLine( &token ) ) { - } - } - } - } while( 1 ); - - idMapBrush *brush = new idMapBrush(); - for ( i = 0; i < sides.Num(); i++ ) { - brush->AddSide( sides[i] ); - } - - brush->epairs = epairs; - - return brush; -} - -/* -============ -idMapBrush::Write -============ -*/ -bool idMapBrush::Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const { - int i; - idMapBrushSide *side; - - fp->WriteFloatString( "// primitive %d\n{\n brushDef3\n {\n", primitiveNum ); - - // write brush epairs - for ( i = 0; i < epairs.GetNumKeyVals(); i++) { - fp->WriteFloatString( " \"%s\" \"%s\"\n", epairs.GetKeyVal(i)->GetKey().c_str(), epairs.GetKeyVal(i)->GetValue().c_str()); - } - - // write brush sides - for ( i = 0; i < GetNumSides(); i++ ) { - side = GetSide( i ); - fp->WriteFloatString( " ( %f %f %f %f ) ", side->plane[0], side->plane[1], side->plane[2], side->plane[3] ); - fp->WriteFloatString( "( ( %f %f %f ) ( %f %f %f ) ) \"%s\" 0 0 0\n", - side->texMat[0][0], side->texMat[0][1], side->texMat[0][2], - side->texMat[1][0], side->texMat[1][1], side->texMat[1][2], - side->material.c_str() ); - } - - fp->WriteFloatString( " }\n}\n" ); - - return true; -} - -/* -=============== -idMapBrush::GetGeometryCRC -=============== -*/ -unsigned int idMapBrush::GetGeometryCRC( void ) const { - int i, j; - idMapBrushSide *mapSide; - unsigned int crc; - - crc = 0; - for ( i = 0; i < GetNumSides(); i++ ) { - mapSide = GetSide(i); - for ( j = 0; j < 4; j++ ) { - crc ^= FloatCRC( mapSide->GetPlane()[j] ); - } - crc ^= StringCRC( mapSide->GetMaterial() ); - } - - return crc; -} - -/* -================ -idMapEntity::Parse -================ -*/ -idMapEntity *idMapEntity::Parse( idLexer &src, bool worldSpawn, float version ) { - idToken token; - idMapEntity *mapEnt; - idMapPatch *mapPatch; - idMapBrush *mapBrush; - bool worldent; - idVec3 origin; - double v1, v2, v3; - - if ( !src.ReadToken(&token) ) { - return NULL; - } - - if ( token != "{" ) { - src.Error( "idMapEntity::Parse: { not found, found %s", token.c_str() ); - return NULL; - } - - mapEnt = new idMapEntity(); - - if ( worldSpawn ) { - mapEnt->primitives.Resize( 1024, 256 ); - } - - origin.Zero(); - worldent = false; - do { - if ( !src.ReadToken(&token) ) { - src.Error( "idMapEntity::Parse: EOF without closing brace" ); - return NULL; - } - if ( token == "}" ) { - break; - } - - if ( token == "{" ) { - // parse a brush or patch - if ( !src.ReadToken( &token ) ) { - src.Error( "idMapEntity::Parse: unexpected EOF" ); - return NULL; - } - - if ( worldent ) { - origin.Zero(); - } - - // if is it a brush: brush, brushDef, brushDef2, brushDef3 - if ( token.Icmpn( "brush", 5 ) == 0 ) { - mapBrush = idMapBrush::Parse( src, origin, ( !token.Icmp( "brushDef2" ) || !token.Icmp( "brushDef3" ) ), version ); - if ( !mapBrush ) { - return NULL; - } - mapEnt->AddPrimitive( mapBrush ); - } - // if is it a patch: patchDef2, patchDef3 - else if ( token.Icmpn( "patch", 5 ) == 0 ) { - mapPatch = idMapPatch::Parse( src, origin, !token.Icmp( "patchDef3" ), version ); - if ( !mapPatch ) { - return NULL; - } - mapEnt->AddPrimitive( mapPatch ); - } - // assume it's a brush in Q3 or older style - else { - src.UnreadToken( &token ); - mapBrush = idMapBrush::ParseQ3( src, origin ); - if ( !mapBrush ) { - return NULL; - } - mapEnt->AddPrimitive( mapBrush ); - } - } else { - idStr key, value; - - // parse a key / value pair - key = token; - src.ReadTokenOnLine( &token ); - value = token; - - // strip trailing spaces that sometimes get accidentally - // added in the editor - value.StripTrailingWhitespace(); - key.StripTrailingWhitespace(); - - mapEnt->epairs.Set( key, value ); - - if ( !idStr::Icmp( key, "origin" ) ) { - // scanf into doubles, then assign, so it is idVec size independent - v1 = v2 = v3 = 0; - sscanf( value, "%lf %lf %lf", &v1, &v2, &v3 ); - origin.x = v1; - origin.y = v2; - origin.z = v3; - } - else if ( !idStr::Icmp( key, "classname" ) && !idStr::Icmp( value, "worldspawn" ) ) { - worldent = true; - } - } - } while( 1 ); - - return mapEnt; -} - -/* -============ -idMapEntity::Write -============ -*/ -bool idMapEntity::Write( idFile *fp, int entityNum ) const { - int i; - idMapPrimitive *mapPrim; - idVec3 origin; - - fp->WriteFloatString( "// entity %d\n{\n", entityNum ); - - // write entity epairs - for ( i = 0; i < epairs.GetNumKeyVals(); i++) { - fp->WriteFloatString( "\"%s\" \"%s\"\n", epairs.GetKeyVal(i)->GetKey().c_str(), epairs.GetKeyVal(i)->GetValue().c_str()); - } - - epairs.GetVector( "origin", "0 0 0", origin ); - - // write pritimives - for ( i = 0; i < GetNumPrimitives(); i++ ) { - mapPrim = GetPrimitive( i ); - - switch( mapPrim->GetType() ) { - case idMapPrimitive::TYPE_BRUSH: - static_cast(mapPrim)->Write( fp, i, origin ); - break; - case idMapPrimitive::TYPE_PATCH: - static_cast(mapPrim)->Write( fp, i, origin ); - break; - } - } - - fp->WriteFloatString( "}\n" ); - - return true; -} - -/* -=============== -idMapEntity::RemovePrimitiveData -=============== -*/ -void idMapEntity::RemovePrimitiveData() { - primitives.DeleteContents(true); -} - -/* -=============== -idMapEntity::GetGeometryCRC -=============== -*/ -unsigned int idMapEntity::GetGeometryCRC( void ) const { - int i; - unsigned int crc; - idMapPrimitive *mapPrim; - - crc = 0; - for ( i = 0; i < GetNumPrimitives(); i++ ) { - mapPrim = GetPrimitive( i ); - - switch( mapPrim->GetType() ) { - case idMapPrimitive::TYPE_BRUSH: - crc ^= static_cast(mapPrim)->GetGeometryCRC(); - break; - case idMapPrimitive::TYPE_PATCH: - crc ^= static_cast(mapPrim)->GetGeometryCRC(); - break; - } - } - - return crc; -} - -/* -=============== -idMapFile::Parse -=============== -*/ -bool idMapFile::Parse( const char *filename, bool ignoreRegion, bool osPath ) { - // no string concatenation for epairs and allow path names for materials - idLexer src( LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); - idToken token; - idStr fullName; - idMapEntity *mapEnt; - int i, j, k; - - name = filename; - name.StripFileExtension(); - fullName = name; - hasPrimitiveData = false; - - if ( !ignoreRegion ) { - // try loading a .reg file first - fullName.SetFileExtension( "reg" ); - src.LoadFile( fullName, osPath ); - } - - if ( !src.IsLoaded() ) { - // now try a .map file - fullName.SetFileExtension( "map" ); - src.LoadFile( fullName, osPath ); - if ( !src.IsLoaded() ) { - // didn't get anything at all - return false; - } - } - - version = OLD_MAP_VERSION; - fileTime = src.GetFileTime(); - entities.DeleteContents( true ); - - if ( src.CheckTokenString( "Version" ) ) { - src.ReadTokenOnLine( &token ); - version = token.GetFloatValue(); - } - - while( 1 ) { - mapEnt = idMapEntity::Parse( src, ( entities.Num() == 0 ), version ); - if ( !mapEnt ) { - break; - } - entities.Append( mapEnt ); - } - - SetGeometryCRC(); - - // if the map has a worldspawn - if ( entities.Num() ) { - - // "removeEntities" "classname" can be set in the worldspawn to remove all entities with the given classname - const idKeyValue *removeEntities = entities[0]->epairs.MatchPrefix( "removeEntities", NULL ); - while ( removeEntities ) { - RemoveEntities( removeEntities->GetValue() ); - removeEntities = entities[0]->epairs.MatchPrefix( "removeEntities", removeEntities ); - } - - // "overrideMaterial" "material" can be set in the worldspawn to reset all materials - idStr material; - if ( entities[0]->epairs.GetString( "overrideMaterial", "", material ) ) { - for ( i = 0; i < entities.Num(); i++ ) { - mapEnt = entities[i]; - for ( j = 0; j < mapEnt->GetNumPrimitives(); j++ ) { - idMapPrimitive *mapPrimitive = mapEnt->GetPrimitive( j ); - switch( mapPrimitive->GetType() ) { - case idMapPrimitive::TYPE_BRUSH: { - idMapBrush *mapBrush = static_cast(mapPrimitive); - for ( k = 0; k < mapBrush->GetNumSides(); k++ ) { - mapBrush->GetSide( k )->SetMaterial( material ); - } - break; - } - case idMapPrimitive::TYPE_PATCH: { - static_cast(mapPrimitive)->SetMaterial( material ); - break; - } - } - } - } - } - - // force all entities to have a name key/value pair - if ( entities[0]->epairs.GetBool( "forceEntityNames" ) ) { - for ( i = 1; i < entities.Num(); i++ ) { - mapEnt = entities[i]; - if ( !mapEnt->epairs.FindKey( "name" ) ) { - mapEnt->epairs.Set( "name", va( "%s%d", mapEnt->epairs.GetString( "classname", "forcedName" ), i ) ); - } - } - } - - // move the primitives of any func_group entities to the worldspawn - if ( entities[0]->epairs.GetBool( "moveFuncGroups" ) ) { - for ( i = 1; i < entities.Num(); i++ ) { - mapEnt = entities[i]; - if ( idStr::Icmp( mapEnt->epairs.GetString( "classname" ), "func_group" ) == 0 ) { - entities[0]->primitives.Append( mapEnt->primitives ); - mapEnt->primitives.Clear(); - } - } - } - } - - hasPrimitiveData = true; - return true; -} - -/* -============ -idMapFile::Write -============ -*/ -bool idMapFile::Write( const char *fileName, const char *ext, bool fromBasePath ) { - int i; - idStr qpath; - idFile *fp; - - qpath = fileName; - qpath.SetFileExtension( ext ); - - idLib::common->Printf( "writing %s...\n", qpath.c_str() ); - - if ( fromBasePath ) { - fp = idLib::fileSystem->OpenFileWrite( qpath, "fs_devpath" ); - } - else { - fp = idLib::fileSystem->OpenExplicitFileWrite( qpath ); - } - - if ( !fp ) { - idLib::common->Warning( "Couldn't open %s\n", qpath.c_str() ); - return false; - } - - fp->WriteFloatString( "Version %f\n", (float) CURRENT_MAP_VERSION ); - - for ( i = 0; i < entities.Num(); i++ ) { - entities[i]->Write( fp, i ); - } - - idLib::fileSystem->CloseFile( fp ); - - return true; -} - -/* -=============== -idMapFile::SetGeometryCRC -=============== -*/ -void idMapFile::SetGeometryCRC( void ) { - int i; - - geometryCRC = 0; - for ( i = 0; i < entities.Num(); i++ ) { - geometryCRC ^= entities[i]->GetGeometryCRC(); - } -} - -/* -=============== -idMapFile::AddEntity -=============== -*/ -int idMapFile::AddEntity( idMapEntity *mapEnt ) { - int ret = entities.Append( mapEnt ); - return ret; -} - -/* -=============== -idMapFile::FindEntity -=============== -*/ -idMapEntity *idMapFile::FindEntity( const char *name ) { - for ( int i = 0; i < entities.Num(); i++ ) { - idMapEntity *ent = entities[i]; - if ( idStr::Icmp( ent->epairs.GetString( "name" ), name ) == 0 ) { - return ent; - } - } - return NULL; -} - -/* -=============== -idMapFile::RemoveEntity -=============== -*/ -void idMapFile::RemoveEntity( idMapEntity *mapEnt ) { - entities.Remove( mapEnt ); - delete mapEnt; -} - -/* -=============== -idMapFile::RemoveEntity -=============== -*/ -void idMapFile::RemoveEntities( const char *classname ) { - for ( int i = 0; i < entities.Num(); i++ ) { - idMapEntity *ent = entities[i]; - if ( idStr::Icmp( ent->epairs.GetString( "classname" ), classname ) == 0 ) { - delete entities[i]; - entities.RemoveIndex( i ); - i--; - } - } -} - -/* -=============== -idMapFile::RemoveAllEntities -=============== -*/ -void idMapFile::RemoveAllEntities() { - entities.DeleteContents( true ); - hasPrimitiveData = false; -} - -/* -=============== -idMapFile::RemovePrimitiveData -=============== -*/ -void idMapFile::RemovePrimitiveData() { - for ( int i = 0; i < entities.Num(); i++ ) { - idMapEntity *ent = entities[i]; - ent->RemovePrimitiveData(); - } - hasPrimitiveData = false; -} - -/* -=============== -idMapFile::NeedsReload -=============== -*/ -bool idMapFile::NeedsReload() { - if ( name.Length() ) { - unsigned int time = (unsigned int)-1; - if ( idLib::fileSystem->ReadFile( name, NULL, &time ) > 0 ) { - return ( time > fileTime ); - } - } - return true; -} - -#pragma warning( pop ) diff --git a/idlib/mapfile.h b/idlib/mapfile.h deleted file mode 100644 index cf3180af8..000000000 --- a/idlib/mapfile.h +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MAPFILE_H__ -#define __MAPFILE_H__ - -/* -=============================================================================== - - Reads or writes the contents of .map files into a standard internal - format, which can then be moved into private formats for collision - detection, map processing, or editor use. - - No validation (duplicate planes, null area brushes, etc) is performed. - There are no limits to the number of any of the elements in maps. - The order of entities, brushes, and sides is maintained. - -=============================================================================== -*/ - -const int OLD_MAP_VERSION = 1; -const int CURRENT_MAP_VERSION = 2; -const int DEFAULT_CURVE_SUBDIVISION = 4; -const float DEFAULT_CURVE_MAX_ERROR = 4.0f; -const float DEFAULT_CURVE_MAX_ERROR_CD = 24.0f; -const float DEFAULT_CURVE_MAX_LENGTH = -1.0f; -const float DEFAULT_CURVE_MAX_LENGTH_CD = -1.0f; - - -class idMapPrimitive { -public: - enum { TYPE_INVALID = -1, TYPE_BRUSH, TYPE_PATCH }; - - idDict epairs; - - idMapPrimitive( void ) { type = TYPE_INVALID; } - virtual ~idMapPrimitive( void ) { } - int GetType( void ) const { return type; } - -protected: - int type; -}; - - -class idMapBrushSide { - friend class idMapBrush; - -public: - idMapBrushSide( void ); - ~idMapBrushSide( void ) { } - const char * GetMaterial( void ) const { return material; } - void SetMaterial( const char *p ) { material = p; } - const idPlane & GetPlane( void ) const { return plane; } - void SetPlane( const idPlane &p ) { plane = p; } - void SetTextureMatrix( const idVec3 mat[2] ) { texMat[0] = mat[0]; texMat[1] = mat[1]; } - void GetTextureMatrix( idVec3 &mat1, idVec3 &mat2 ) { mat1 = texMat[0]; mat2 = texMat[1]; } - void GetTextureVectors( idVec4 v[2] ) const; - -protected: - idStr material; - idPlane plane; - idVec3 texMat[2]; - idVec3 origin; -}; - -ID_INLINE idMapBrushSide::idMapBrushSide( void ) { - plane.Zero(); - texMat[0].Zero(); - texMat[1].Zero(); - origin.Zero(); -} - - -class idMapBrush : public idMapPrimitive { -public: - idMapBrush( void ) { type = TYPE_BRUSH; sides.Resize( 8, 4 ); } - ~idMapBrush( void ) { sides.DeleteContents( true ); } - static idMapBrush * Parse( idLexer &src, const idVec3 &origin, bool newFormat = true, float version = CURRENT_MAP_VERSION ); - static idMapBrush * ParseQ3( idLexer &src, const idVec3 &origin ); - bool Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const; - int GetNumSides( void ) const { return sides.Num(); } - int AddSide( idMapBrushSide *side ) { return sides.Append( side ); } - idMapBrushSide * GetSide( int i ) const { return sides[i]; } - unsigned int GetGeometryCRC( void ) const; - -protected: - int numSides; - idList sides; -}; - - -class idMapPatch : public idMapPrimitive, public idSurface_Patch { -public: - idMapPatch( void ); - idMapPatch( int maxPatchWidth, int maxPatchHeight ); - ~idMapPatch( void ) { } - static idMapPatch * Parse( idLexer &src, const idVec3 &origin, bool patchDef3 = true, float version = CURRENT_MAP_VERSION ); - bool Write( idFile *fp, int primitiveNum, const idVec3 &origin ) const; - const char * GetMaterial( void ) const { return material; } - void SetMaterial( const char *p ) { material = p; } - int GetHorzSubdivisions( void ) const { return horzSubdivisions; } - int GetVertSubdivisions( void ) const { return vertSubdivisions; } - bool GetExplicitlySubdivided( void ) const { return explicitSubdivisions; } - void SetHorzSubdivisions( int n ) { horzSubdivisions = n; } - void SetVertSubdivisions( int n ) { vertSubdivisions = n; } - void SetExplicitlySubdivided( bool b ) { explicitSubdivisions = b; } - unsigned int GetGeometryCRC( void ) const; - -protected: - idStr material; - int horzSubdivisions; - int vertSubdivisions; - bool explicitSubdivisions; -}; - -ID_INLINE idMapPatch::idMapPatch( void ) { - type = TYPE_PATCH; - horzSubdivisions = vertSubdivisions = 0; - explicitSubdivisions = false; - width = height = 0; - maxWidth = maxHeight = 0; - expanded = false; -} - -ID_INLINE idMapPatch::idMapPatch( int maxPatchWidth, int maxPatchHeight ) { - type = TYPE_PATCH; - horzSubdivisions = vertSubdivisions = 0; - explicitSubdivisions = false; - width = height = 0; - maxWidth = maxPatchWidth; - maxHeight = maxPatchHeight; - verts.SetNum( maxWidth * maxHeight ); - expanded = false; -} - - -class idMapEntity { - friend class idMapFile; - -public: - idDict epairs; - -public: - idMapEntity( void ) { epairs.SetHashSize( 64 ); } - ~idMapEntity( void ) { primitives.DeleteContents( true ); } - static idMapEntity * Parse( idLexer &src, bool worldSpawn = false, float version = CURRENT_MAP_VERSION ); - bool Write( idFile *fp, int entityNum ) const; - int GetNumPrimitives( void ) const { return primitives.Num(); } - idMapPrimitive * GetPrimitive( int i ) const { return primitives[i]; } - void AddPrimitive( idMapPrimitive *p ) { primitives.Append( p ); } - unsigned int GetGeometryCRC( void ) const; - void RemovePrimitiveData(); - -protected: - idList primitives; -}; - - -class idMapFile { -public: - idMapFile( void ); - ~idMapFile( void ) { entities.DeleteContents( true ); } - - // filename does not require an extension - // normally this will use a .reg file instead of a .map file if it exists, - // which is what the game and dmap want, but the editor will want to always - // load a .map file - bool Parse( const char *filename, bool ignoreRegion = false, bool osPath = false ); - bool Write( const char *fileName, const char *ext, bool fromBasePath = true ); - // get the number of entities in the map - int GetNumEntities( void ) const { return entities.Num(); } - // get the specified entity - idMapEntity * GetEntity( int i ) const { return entities[i]; } - // get the name without file extension - const char * GetName( void ) const { return name; } - // get the file time - unsigned int GetFileTime( void ) const { return fileTime; } - // get CRC for the map geometry - // texture coordinates and entity key/value pairs are not taken into account - unsigned int GetGeometryCRC( void ) const { return geometryCRC; } - // returns true if the file on disk changed - bool NeedsReload(); - - int AddEntity( idMapEntity *mapentity ); - idMapEntity * FindEntity( const char *name ); - void RemoveEntity( idMapEntity *mapEnt ); - void RemoveEntities( const char *classname ); - void RemoveAllEntities(); - void RemovePrimitiveData(); - bool HasPrimitiveData() { return hasPrimitiveData; } - -protected: - float version; - unsigned int fileTime; - unsigned int geometryCRC; - idList entities; - idStr name; - bool hasPrimitiveData; - -private: - void SetGeometryCRC( void ); -}; - -ID_INLINE idMapFile::idMapFile( void ) { - version = CURRENT_MAP_VERSION; - fileTime = 0; - geometryCRC = 0; - entities.Resize( 1024, 256 ); - hasPrimitiveData = false; -} - -#endif /* !__MAPFILE_H__ */ diff --git a/idlib/math/Angles.cpp b/idlib/math/Angles.cpp new file mode 100644 index 000000000..20064372a --- /dev/null +++ b/idlib/math/Angles.cpp @@ -0,0 +1,233 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +#include + +idAngles ang_zero( 0.0f, 0.0f, 0.0f ); + + +/* +================= +idAngles::Normalize360 + +returns angles normalized to the range [0 <= angle < 360] +================= +*/ +idAngles& idAngles::Normalize360( void ) { + int i; + + for ( i = 0; i < 3; i++ ) { + if ( ( (*this)[i] >= 360.0f ) || ( (*this)[i] < 0.0f ) ) { + (*this)[i] -= floor( (*this)[i] / 360.0f ) * 360.0f; + + if ( (*this)[i] >= 360.0f ) { + (*this)[i] -= 360.0f; + } + if ( (*this)[i] < 0.0f ) { + (*this)[i] += 360.0f; + } + } + } + + return *this; +} + +/* +================= +idAngles::Normalize180 + +returns angles normalized to the range [-180 < angle <= 180] +================= +*/ +idAngles& idAngles::Normalize180( void ) { + Normalize360(); + + if ( pitch > 180.0f ) { + pitch -= 360.0f; + } + + if ( yaw > 180.0f ) { + yaw -= 360.0f; + } + + if ( roll > 180.0f ) { + roll -= 360.0f; + } + return *this; +} + +/* +================= +idAngles::ToVectors +================= +*/ +void idAngles::ToVectors( idVec3 *forward, idVec3 *right, idVec3 *up ) const { + float sr, sp, sy, cr, cp, cy; + + idMath::SinCos( DEG2RAD( yaw ), sy, cy ); + idMath::SinCos( DEG2RAD( pitch ), sp, cp ); + idMath::SinCos( DEG2RAD( roll ), sr, cr ); + + if ( forward ) { + forward->Set( cp * cy, cp * sy, -sp ); + } + + if ( right ) { + right->Set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp ); + } + + if ( up ) { + up->Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); + } +} + +/* +================= +idAngles::ToForward +================= +*/ +idVec3 idAngles::ToForward( void ) const { + float sp, sy, cp, cy; + + idMath::SinCos( DEG2RAD( yaw ), sy, cy ); + idMath::SinCos( DEG2RAD( pitch ), sp, cp ); + + return idVec3( cp * cy, cp * sy, -sp ); +} + +/* +================= +idAngles::ToQuat +================= +*/ +idQuat idAngles::ToQuat( void ) const { + float sx, cx, sy, cy, sz, cz; + float sxcy, cxcy, sxsy, cxsy; + + idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz ); + idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy ); + idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx ); + + sxcy = sx * cy; + cxcy = cx * cy; + sxsy = sx * sy; + cxsy = cx * sy; + + return idQuat( cxsy*sz - sxcy*cz, -cxsy*cz - sxcy*sz, sxsy*cz - cxcy*sz, cxcy*cz + sxsy*sz ); +} + +/* +================= +idAngles::ToRotation +================= +*/ +idRotation idAngles::ToRotation( void ) const { + idVec3 vec; + float angle, w; + float sx, cx, sy, cy, sz, cz; + float sxcy, cxcy, sxsy, cxsy; + + if ( pitch == 0.0f ) { + if ( yaw == 0.0f ) { + return idRotation( vec3_origin, idVec3( -1.0f, 0.0f, 0.0f ), roll ); + } + if ( roll == 0.0f ) { + return idRotation( vec3_origin, idVec3( 0.0f, 0.0f, -1.0f ), yaw ); + } + } else if ( yaw == 0.0f && roll == 0.0f ) { + return idRotation( vec3_origin, idVec3( 0.0f, -1.0f, 0.0f ), pitch ); + } + + idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz ); + idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy ); + idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx ); + + sxcy = sx * cy; + cxcy = cx * cy; + sxsy = sx * sy; + cxsy = cx * sy; + + vec.x = cxsy * sz - sxcy * cz; + vec.y = -cxsy * cz - sxcy * sz; + vec.z = sxsy * cz - cxcy * sz; + w = cxcy * cz + sxsy * sz; + angle = idMath::ACos( w ); + if ( angle == 0.0f ) { + vec.Set( 0.0f, 0.0f, 1.0f ); + } else { + //vec *= (1.0f / sin( angle )); + vec.Normalize(); + vec.FixDegenerateNormal(); + angle *= 2.0f * idMath::M_RAD2DEG; + } + return idRotation( vec3_origin, vec, angle ); +} + +/* +================= +idAngles::ToMat3 +================= +*/ +idMat3 idAngles::ToMat3( void ) const { + idMat3 mat; + float sr, sp, sy, cr, cp, cy; + + idMath::SinCos( DEG2RAD( yaw ), sy, cy ); + idMath::SinCos( DEG2RAD( pitch ), sp, cp ); + idMath::SinCos( DEG2RAD( roll ), sr, cr ); + + mat[ 0 ].Set( cp * cy, cp * sy, -sp ); + mat[ 1 ].Set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); + mat[ 2 ].Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); + + return mat; +} + +/* +================= +idAngles::ToMat4 +================= +*/ +idMat4 idAngles::ToMat4( void ) const { + return ToMat3().ToMat4(); +} + +/* +================= +idAngles::ToAngularVelocity +================= +*/ +idVec3 idAngles::ToAngularVelocity( void ) const { + idRotation rotation = idAngles::ToRotation(); + return rotation.GetVec() * DEG2RAD( rotation.GetAngle() ); +} + +/* +============= +idAngles::ToString +============= +*/ +const char *idAngles::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Angles.h b/idlib/math/Angles.h new file mode 100644 index 000000000..0c7efb4ec --- /dev/null +++ b/idlib/math/Angles.h @@ -0,0 +1,261 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_ANGLES_H__ +#define __MATH_ANGLES_H__ + +/* +=============================================================================== + + Euler angles + +TDM NOTE: +idAngles uses the "yaw, pitch, roll" convention, in which the yaw rotation occurs +first, then pitch occurs relative to the yawed axes, and finally roll +occurs relative to the yawed and pitched axes. Also known as the "zyx" convention. + +=============================================================================== +*/ + +// angle indexes +#define PITCH 0 // up / down +#define YAW 1 // left / right +#define ROLL 2 // fall over + +class idVec3; +class idQuat; +class idRotation; +class idMat3; +class idMat4; + +class idAngles { +public: + float pitch; + float yaw; + float roll; + + idAngles( void ); + idAngles( float pitch, float yaw, float roll ); + explicit idAngles( const idVec3 &v ); + + void Set( float pitch, float yaw, float roll ); + idAngles & Zero( void ); + + float operator[]( int index ) const; + float & operator[]( int index ); + idAngles operator-() const; // negate angles, in general not the inverse rotation + idAngles & operator=( const idAngles &a ); + idAngles operator+( const idAngles &a ) const; + idAngles & operator+=( const idAngles &a ); + idAngles operator-( const idAngles &a ) const; + idAngles & operator-=( const idAngles &a ); + idAngles operator*( const float a ) const; + idAngles & operator*=( const float a ); + idAngles operator/( const float a ) const; + idAngles & operator/=( const float a ); + + friend idAngles operator*( const float a, const idAngles &b ); + + bool Compare( const idAngles &a ) const; // exact compare, no epsilon + bool Compare( const idAngles &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idAngles &a ) const; // exact compare, no epsilon + bool operator!=( const idAngles &a ) const; // exact compare, no epsilon + + idAngles & Normalize360( void ); // normalizes 'this' + idAngles & Normalize180( void ); // normalizes 'this' + + void Clamp( const idAngles &min, const idAngles &max ); + + int GetDimension( void ) const; + + void ToVectors( idVec3 *forward, idVec3 *right = NULL, idVec3 *up = NULL ) const; + idVec3 ToForward( void ) const; + idQuat ToQuat( void ) const; + idRotation ToRotation( void ) const; + idMat3 ToMat3( void ) const; + idMat4 ToMat4( void ) const; + idVec3 ToAngularVelocity( void ) const; + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; +}; + +extern idAngles ang_zero; + +// Default constructor +ID_INLINE idAngles::idAngles( void ) +: pitch(0), yaw(0), roll(0) +{ +} + +ID_INLINE idAngles::idAngles( float pitch, float yaw, float roll ) { + this->pitch = pitch; + this->yaw = yaw; + this->roll = roll; +} + +ID_INLINE idAngles::idAngles( const idVec3 &v ) { + this->pitch = v[0]; + this->yaw = v[1]; + this->roll = v[2]; +} + +ID_INLINE void idAngles::Set( float pitch, float yaw, float roll ) { + this->pitch = pitch; + this->yaw = yaw; + this->roll = roll; +} + +ID_INLINE idAngles &idAngles::Zero( void ) { + pitch = yaw = roll = 0.0f; + return *this; +} + +ID_INLINE float idAngles::operator[]( int index ) const { + assert( ( index >= 0 ) && ( index < 3 ) ); + return ( &pitch )[ index ]; +} + +ID_INLINE float &idAngles::operator[]( int index ) { + assert( ( index >= 0 ) && ( index < 3 ) ); + return ( &pitch )[ index ]; +} + +ID_INLINE idAngles idAngles::operator-() const { + return idAngles( -pitch, -yaw, -roll ); +} + +ID_INLINE idAngles &idAngles::operator=( const idAngles &a ) { + pitch = a.pitch; + yaw = a.yaw; + roll = a.roll; + return *this; +} + +ID_INLINE idAngles idAngles::operator+( const idAngles &a ) const { + return idAngles( pitch + a.pitch, yaw + a.yaw, roll + a.roll ); +} + +ID_INLINE idAngles& idAngles::operator+=( const idAngles &a ) { + pitch += a.pitch; + yaw += a.yaw; + roll += a.roll; + + return *this; +} + +ID_INLINE idAngles idAngles::operator-( const idAngles &a ) const { + return idAngles( pitch - a.pitch, yaw - a.yaw, roll - a.roll ); +} + +ID_INLINE idAngles& idAngles::operator-=( const idAngles &a ) { + pitch -= a.pitch; + yaw -= a.yaw; + roll -= a.roll; + + return *this; +} + +ID_INLINE idAngles idAngles::operator*( const float a ) const { + return idAngles( pitch * a, yaw * a, roll * a ); +} + +ID_INLINE idAngles& idAngles::operator*=( float a ) { + pitch *= a; + yaw *= a; + roll *= a; + return *this; +} + +ID_INLINE idAngles idAngles::operator/( const float a ) const { + float inva = 1.0f / a; + return idAngles( pitch * inva, yaw * inva, roll * inva ); +} + +ID_INLINE idAngles& idAngles::operator/=( float a ) { + float inva = 1.0f / a; + pitch *= inva; + yaw *= inva; + roll *= inva; + return *this; +} + +ID_INLINE idAngles operator*( const float a, const idAngles &b ) { + return idAngles( a * b.pitch, a * b.yaw, a * b.roll ); +} + +ID_INLINE bool idAngles::Compare( const idAngles &a ) const { + return ( ( a.pitch == pitch ) && ( a.yaw == yaw ) && ( a.roll == roll ) ); +} + +ID_INLINE bool idAngles::Compare( const idAngles &a, const float epsilon ) const { + if ( idMath::Fabs( pitch - a.pitch ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( yaw - a.yaw ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( roll - a.roll ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idAngles::operator==( const idAngles &a ) const { + return Compare( a ); +} + +ID_INLINE bool idAngles::operator!=( const idAngles &a ) const { + return !Compare( a ); +} + +ID_INLINE void idAngles::Clamp( const idAngles &min, const idAngles &max ) { + if ( pitch < min.pitch ) { + pitch = min.pitch; + } else if ( pitch > max.pitch ) { + pitch = max.pitch; + } + if ( yaw < min.yaw ) { + yaw = min.yaw; + } else if ( yaw > max.yaw ) { + yaw = max.yaw; + } + if ( roll < min.roll ) { + roll = min.roll; + } else if ( roll > max.roll ) { + roll = max.roll; + } +} + +ID_INLINE int idAngles::GetDimension( void ) const { + return 3; +} + +ID_INLINE const float *idAngles::ToFloatPtr( void ) const { + return &pitch; +} + +ID_INLINE float *idAngles::ToFloatPtr( void ) { + return &pitch; +} + +#endif /* !__MATH_ANGLES_H__ */ diff --git a/idlib/math/Complex.cpp b/idlib/math/Complex.cpp new file mode 100644 index 000000000..10367f54a --- /dev/null +++ b/idlib/math/Complex.cpp @@ -0,0 +1,32 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +idComplex complex_origin( 0.0f, 0.0f ); + +/* +============= +idComplex::ToString +============= +*/ +const char *idComplex::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Complex.h b/idlib/math/Complex.h new file mode 100644 index 000000000..7a772ed75 --- /dev/null +++ b/idlib/math/Complex.h @@ -0,0 +1,339 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_COMPLEX_H__ +#define __MATH_COMPLEX_H__ + +/* +=============================================================================== + + Complex number + +=============================================================================== +*/ + +class idComplex { +public: + float r; // real part + float i; // imaginary part + + idComplex( void ); + idComplex( const float r, const float i ); + + void Set( const float r, const float i ); + void Zero( void ); + + float operator[]( int index ) const; + float & operator[]( int index ); + + idComplex operator-() const; + idComplex & operator=( const idComplex &a ); + + idComplex operator*( const idComplex &a ) const; + idComplex operator/( const idComplex &a ) const; + idComplex operator+( const idComplex &a ) const; + idComplex operator-( const idComplex &a ) const; + + idComplex & operator*=( const idComplex &a ); + idComplex & operator/=( const idComplex &a ); + idComplex & operator+=( const idComplex &a ); + idComplex & operator-=( const idComplex &a ); + + idComplex operator*( const float a ) const; + idComplex operator/( const float a ) const; + idComplex operator+( const float a ) const; + idComplex operator-( const float a ) const; + + idComplex & operator*=( const float a ); + idComplex & operator/=( const float a ); + idComplex & operator+=( const float a ); + idComplex & operator-=( const float a ); + + friend idComplex operator*( const float a, const idComplex &b ); + friend idComplex operator/( const float a, const idComplex &b ); + friend idComplex operator+( const float a, const idComplex &b ); + friend idComplex operator-( const float a, const idComplex &b ); + + bool Compare( const idComplex &a ) const; // exact compare, no epsilon + bool Compare( const idComplex &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idComplex &a ) const; // exact compare, no epsilon + bool operator!=( const idComplex &a ) const; // exact compare, no epsilon + + idComplex Reciprocal( void ) const; + idComplex Sqrt( void ) const; + float Abs( void ) const; + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; +}; + +extern idComplex complex_origin; +#define complex_zero complex_origin + +ID_INLINE idComplex::idComplex( void ) { +} + +ID_INLINE idComplex::idComplex( const float r, const float i ) { + this->r = r; + this->i = i; +} + +ID_INLINE void idComplex::Set( const float r, const float i ) { + this->r = r; + this->i = i; +} + +ID_INLINE void idComplex::Zero( void ) { + r = i = 0.0f; +} + +ID_INLINE float idComplex::operator[]( int index ) const { + assert( index >= 0 && index < 2 ); + return ( &r )[ index ]; +} + +ID_INLINE float& idComplex::operator[]( int index ) { + assert( index >= 0 && index < 2 ); + return ( &r )[ index ]; +} + +ID_INLINE idComplex idComplex::operator-() const { + return idComplex( -r, -i ); +} + +ID_INLINE idComplex &idComplex::operator=( const idComplex &a ) { + r = a.r; + i = a.i; + return *this; +} + +ID_INLINE idComplex idComplex::operator*( const idComplex &a ) const { + return idComplex( r * a.r - i * a.i, i * a.r + r * a.i ); +} + +ID_INLINE idComplex idComplex::operator/( const idComplex &a ) const { + float s, t; + if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) { + s = a.i / a.r; + t = 1.0f / ( a.r + s * a.i ); + return idComplex( ( r + s * i ) * t, ( i - s * r ) * t ); + } else { + s = a.r / a.i; + t = 1.0f / ( s * a.r + a.i ); + return idComplex( ( r * s + i ) * t, ( i * s - r ) * t ); + } +} + +ID_INLINE idComplex idComplex::operator+( const idComplex &a ) const { + return idComplex( r + a.r, i + a.i ); +} + +ID_INLINE idComplex idComplex::operator-( const idComplex &a ) const { + return idComplex( r - a.r, i - a.i ); +} + +ID_INLINE idComplex &idComplex::operator*=( const idComplex &a ) { + *this = idComplex( r * a.r - i * a.i, i * a.r + r * a.i ); + return *this; +} + +ID_INLINE idComplex &idComplex::operator/=( const idComplex &a ) { + float s, t; + if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) { + s = a.i / a.r; + t = 1.0f / ( a.r + s * a.i ); + *this = idComplex( ( r + s * i ) * t, ( i - s * r ) * t ); + } else { + s = a.r / a.i; + t = 1.0f / ( s * a.r + a.i ); + *this = idComplex( ( r * s + i ) * t, ( i * s - r ) * t ); + } + return *this; +} + +ID_INLINE idComplex &idComplex::operator+=( const idComplex &a ) { + r += a.r; + i += a.i; + return *this; +} + +ID_INLINE idComplex &idComplex::operator-=( const idComplex &a ) { + r -= a.r; + i -= a.i; + return *this; +} + +ID_INLINE idComplex idComplex::operator*( const float a ) const { + return idComplex( r * a, i * a ); +} + +ID_INLINE idComplex idComplex::operator/( const float a ) const { + float s = 1.0f / a; + return idComplex( r * s, i * s ); +} + +ID_INLINE idComplex idComplex::operator+( const float a ) const { + return idComplex( r + a, i ); +} + +ID_INLINE idComplex idComplex::operator-( const float a ) const { + return idComplex( r - a, i ); +} + +ID_INLINE idComplex &idComplex::operator*=( const float a ) { + r *= a; + i *= a; + return *this; +} + +ID_INLINE idComplex &idComplex::operator/=( const float a ) { + float s = 1.0f / a; + r *= s; + i *= s; + return *this; +} + +ID_INLINE idComplex &idComplex::operator+=( const float a ) { + r += a; + return *this; +} + +ID_INLINE idComplex &idComplex::operator-=( const float a ) { + r -= a; + return *this; +} + +ID_INLINE idComplex operator*( const float a, const idComplex &b ) { + return idComplex( a * b.r, a * b.i ); +} + +ID_INLINE idComplex operator/( const float a, const idComplex &b ) { + float s, t; + if ( idMath::Fabs( b.r ) >= idMath::Fabs( b.i ) ) { + s = b.i / b.r; + t = a / ( b.r + s * b.i ); + return idComplex( t, - s * t ); + } else { + s = b.r / b.i; + t = a / ( s * b.r + b.i ); + return idComplex( s * t, - t ); + } +} + +ID_INLINE idComplex operator+( const float a, const idComplex &b ) { + return idComplex( a + b.r, b.i ); +} + +ID_INLINE idComplex operator-( const float a, const idComplex &b ) { + return idComplex( a - b.r, -b.i ); +} + +ID_INLINE idComplex idComplex::Reciprocal( void ) const { + float s, t; + if ( idMath::Fabs( r ) >= idMath::Fabs( i ) ) { + s = i / r; + t = 1.0f / ( r + s * i ); + return idComplex( t, - s * t ); + } else { + s = r / i; + t = 1.0f / ( s * r + i ); + return idComplex( s * t, - t ); + } +} + +ID_INLINE idComplex idComplex::Sqrt( void ) const { + float x, y, w; + + if ( r == 0.0f && i == 0.0f ) { + return idComplex( 0.0f, 0.0f ); + } + x = idMath::Fabs( r ); + y = idMath::Fabs( i ); + if ( x >= y ) { + w = y / x; + w = idMath::Sqrt( x ) * idMath::Sqrt( 0.5f * ( 1.0f + idMath::Sqrt( 1.0f + w * w ) ) ); + } else { + w = x / y; + w = idMath::Sqrt( y ) * idMath::Sqrt( 0.5f * ( w + idMath::Sqrt( 1.0f + w * w ) ) ); + } + if ( w == 0.0f ) { + return idComplex( 0.0f, 0.0f ); + } + if ( r >= 0.0f ) { + return idComplex( w, 0.5f * i / w ); + } else { + return idComplex( 0.5f * y / w, ( i >= 0.0f ) ? w : -w ); + } +} + +ID_INLINE float idComplex::Abs( void ) const { + float x, y, t; + x = idMath::Fabs( r ); + y = idMath::Fabs( i ); + if ( x == 0.0f ) { + return y; + } else if ( y == 0.0f ) { + return x; + } else if ( x > y ) { + t = y / x; + return x * idMath::Sqrt( 1.0f + t * t ); + } else { + t = x / y; + return y * idMath::Sqrt( 1.0f + t * t ); + } +} + +ID_INLINE bool idComplex::Compare( const idComplex &a ) const { + return ( ( r == a.r ) && ( i == a.i ) ); +} + +ID_INLINE bool idComplex::Compare( const idComplex &a, const float epsilon ) const { + if ( idMath::Fabs( r - a.r ) > epsilon ) { + return false; + } + if ( idMath::Fabs( i - a.i ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE bool idComplex::operator==( const idComplex &a ) const { + return Compare( a ); +} + +ID_INLINE bool idComplex::operator!=( const idComplex &a ) const { + return !Compare( a ); +} + +ID_INLINE int idComplex::GetDimension( void ) const { + return 2; +} + +ID_INLINE const float *idComplex::ToFloatPtr( void ) const { + return &r; +} + +ID_INLINE float *idComplex::ToFloatPtr( void ) { + return &r; +} + +#endif /* !__MATH_COMPLEX_H__ */ diff --git a/idlib/math/Curve.h b/idlib/math/Curve.h new file mode 100644 index 000000000..0cfc4f7ef --- /dev/null +++ b/idlib/math/Curve.h @@ -0,0 +1,2533 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_CURVE_H__ +#define __MATH_CURVE_H__ + +/* +=============================================================================== + + Curve base template. + +=============================================================================== +*/ + +template< class type > +class idCurve { +public: + idCurve( void ); + virtual ~idCurve( void ); + + virtual int AddValue( const float time, const type &value ); + virtual void RemoveIndex( const int index ) { values.RemoveIndex(index); times.RemoveIndex(index); changed = true; } + virtual void Clear( void ) { values.Clear(); times.Clear(); currentIndex = -1; changed = true; } + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + + virtual bool IsDone( const float time ) const; + + int GetNumValues( void ) const { return values.Num(); } + void SetValue( const int index, const type &value ) { values[index] = value; changed = true; } + type GetValue( const int index ) const { return values[index]; } + type * GetValueAddress( const int index ) { return &values[index]; } + float GetTime( const int index ) const { return times[index]; } + + float GetLengthForTime( const float time ) const; + float GetTimeForLength( const float length, const float epsilon = 0.1f ) const; + float GetLengthBetweenKnots( const int i0, const int i1 ) const; + + void MakeUniform( const float totalTime ); + void SetConstantSpeed( const float totalTime ); + void ShiftTime( const float deltaTime ); + void Translate( const type &translation ); + +protected: + + idList times; // knots + idList values; // knot values + + mutable int currentIndex; // cached index for fast lookup + mutable bool changed; // set whenever the curve changes + + int IndexForTime( const float time ) const; + float TimeForIndex( const int index ) const; + type ValueForIndex( const int index ) const; + + float GetSpeed( const float time ) const; + float RombergIntegral( const float t0, const float t1, const int order ) const; +}; + +/* +==================== +idCurve::idCurve +==================== +*/ +template< class type > +ID_INLINE idCurve::idCurve( void ) { + currentIndex = -1; + changed = false; +} + +/* +==================== +idCurve::~idCurve +==================== +*/ +template< class type > +ID_INLINE idCurve::~idCurve( void ) { +} + +/* +==================== +idCurve::AddValue + + add a timed/value pair to the spline + returns the index to the inserted pair +==================== +*/ +template< class type > +ID_INLINE int idCurve::AddValue( const float time, const type &value ) { + int i; + + i = IndexForTime( time ); + times.Insert( time, i ); + values.Insert( value, i ); + changed = true; + return i; +} + +/* +==================== +idCurve::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve::GetCurrentValue( const float time ) const { + int i; + + i = IndexForTime( time ); + if ( i >= values.Num() ) { + return values[values.Num() - 1]; + } else { + return values[i]; + } +} + +/* +==================== +idCurve::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve::GetCurrentFirstDerivative( const float time ) const { + return ( values[0] - values[0] ); +} + +/* +==================== +idCurve::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve::GetCurrentSecondDerivative( const float time ) const { + return ( values[0] - values[0] ); +} + +/* +==================== +idCurve::IsDone +==================== +*/ +template< class type > +ID_INLINE bool idCurve::IsDone( const float time ) const { + return ( time >= times[ times.Num() - 1 ] ); +} + +/* +==================== +idCurve::GetSpeed +==================== +*/ +template< class type > +ID_INLINE float idCurve::GetSpeed( const float time ) const { + int i; + float speed; + type value; + + value = GetCurrentFirstDerivative( time ); + for ( speed = 0.0f, i = 0; i < value.GetDimension(); i++ ) { + speed += value[i] * value[i]; + } + return idMath::Sqrt( speed ); +} + +/* +==================== +idCurve::RombergIntegral +==================== +*/ +template< class type > +ID_INLINE float idCurve::RombergIntegral( const float t0, const float t1, const int order ) const { + int i, j, k, m, n; + float sum, delta; + float *temp[2]; + + temp[0] = (float *) _alloca16( order * sizeof( float ) ); + temp[1] = (float *) _alloca16( order * sizeof( float ) ); + + delta = t1 - t0; + temp[0][0] = 0.5f * delta * ( GetSpeed( t0 ) + GetSpeed( t1 ) ); + + for ( i = 2, m = 1; i <= order; i++, m *= 2, delta *= 0.5f ) { + + // approximate using the trapezoid rule + sum = 0.0f; + for ( j = 1; j <= m; j++ ) { + sum += GetSpeed( t0 + delta * ( j - 0.5f ) ); + } + + // Richardson extrapolation + temp[1][0] = 0.5f * ( temp[0][0] + delta * sum ); + for ( k = 1, n = 4; k < i; k++, n *= 4 ) { + temp[1][k] = ( n * temp[1][k-1] - temp[0][k-1] ) / ( n - 1 ); + } + + for ( j = 0; j < i; j++ ) { + temp[0][j] = temp[1][j]; + } + } + return temp[0][order-1]; +} + +/* +==================== +idCurve::GetLengthBetweenKnots +==================== +*/ +template< class type > +ID_INLINE float idCurve::GetLengthBetweenKnots( const int i0, const int i1 ) const { + float length = 0.0f; + for ( int i = i0; i < i1; i++ ) { + length += RombergIntegral( times[i], times[i+1], 5 ); + } + return length; +} + +/* +==================== +idCurve::GetLengthForTime +==================== +*/ +template< class type > +ID_INLINE float idCurve::GetLengthForTime( const float time ) const { + float length = 0.0f; + int index = IndexForTime( time ); + for ( int i = 0; i < index; i++ ) { + length += RombergIntegral( times[i], times[i+1], 5 ); + } + length += RombergIntegral( times[index], time, 5 ); + return length; +} + +/* +==================== +idCurve::GetTimeForLength +==================== +*/ +template< class type > +ID_INLINE float idCurve::GetTimeForLength( const float length, const float epsilon ) const { + int i, index; + float *accumLength, totalLength, len0, len1, t, diff; + + if ( length <= 0.0f ) { + return times[0]; + } + + accumLength = (float *) _alloca16( values.Num() * sizeof( float ) ); + totalLength = 0.0f; + for ( index = 0; index < values.Num() - 1; index++ ) { + totalLength += GetLengthBetweenKnots( index, index + 1 ); + accumLength[index] = totalLength; + if ( length < accumLength[index] ) { + break; + } + } + + if ( index >= values.Num() - 1 ) { + return times[times.Num() - 1]; + } + + if ( index == 0 ) { + len0 = length; + len1 = accumLength[0]; + } else { + len0 = length - accumLength[index-1]; + len1 = accumLength[index] - accumLength[index-1]; + } + + // invert the arc length integral using Newton's method + t = ( times[index+1] - times[index] ) * len0 / len1; + for ( i = 0; i < 32; i++ ) { + diff = RombergIntegral( times[index], times[index] + t, 5 ) - len0; + if ( idMath::Fabs( diff ) <= epsilon ) { + return times[index] + t; + } + t -= diff / GetSpeed( times[index] + t ); + } + return times[index] + t; +} + +/* +==================== +idCurve::MakeUniform +==================== +*/ +template< class type > +ID_INLINE void idCurve::MakeUniform( const float totalTime ) { + int i, n; + + n = times.Num() - 1; + for ( i = 0; i <= n; i++ ) { + times[i] = i * totalTime / n; + } + changed = true; +} + +/* +==================== +idCurve::SetConstantSpeed +==================== +*/ +template< class type > +ID_INLINE void idCurve::SetConstantSpeed( const float totalTime ) { + int i, j; + float *length, totalLength, scale, t; + + length = (float *) _alloca16( values.Num() * sizeof( float ) ); + totalLength = 0.0f; + for ( i = 0; i < values.Num() - 1; i++ ) { + length[i] = GetLengthBetweenKnots( i, i + 1 ); + totalLength += length[i]; + } + scale = totalTime / totalLength; + for ( t = 0.0f, i = 0; i < times.Num() - 1; i++ ) { + times[i] = t; + t += scale * length[i]; + } + times[times.Num() - 1] = totalTime; + changed = true; +} + +/* +==================== +idCurve::ShiftTime +==================== +*/ +template< class type > +ID_INLINE void idCurve::ShiftTime( const float deltaTime ) { + for ( int i = 0; i < times.Num(); i++ ) { + times[i] += deltaTime; + } + changed = true; +} + +/* +==================== +idCurve::Translate +==================== +*/ +template< class type > +ID_INLINE void idCurve::Translate( const type &translation ) { + for ( int i = 0; i < values.Num(); i++ ) { + values[i] += translation; + } + changed = true; +} + +/* +==================== +idCurve::IndexForTime + + find the index for the first time greater than or equal to the given time +==================== +*/ +template< class type > +ID_INLINE int idCurve::IndexForTime( const float time ) const { + int len, mid, offset, res; + + if ( currentIndex >= 0 && currentIndex <= times.Num() ) { + // use the cached index if it is still valid + if ( currentIndex == 0 ) { + if ( time <= times[currentIndex] ) { + return currentIndex; + } + } else if ( currentIndex == times.Num() ) { + if ( time > times[currentIndex-1] ) { + return currentIndex; + } + } else if ( time > times[currentIndex-1] && time <= times[currentIndex] ) { + return currentIndex; + } else if ( time > times[currentIndex] && ( currentIndex+1 == times.Num() || time <= times[currentIndex+1] ) ) { + // use the next index + currentIndex++; + return currentIndex; + } + } + + // use binary search to find the index for the given time + len = times.Num(); + mid = len; + offset = 0; + res = 0; + while( mid > 0 ) { + mid = len >> 1; + if ( time == times[offset+mid] ) { + return offset+mid; + } else if ( time > times[offset+mid] ) { + offset += mid; + len -= mid; + res = 1; + } else { + len -= mid; + res = 0; + } + } + currentIndex = offset+res; + return currentIndex; +} + +/* +==================== +idCurve::ValueForIndex + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve::ValueForIndex( const int index ) const { + int n = values.Num()-1; + + if ( index < 0 ) { + return values[0] + index * ( values[1] - values[0] ); + } else if ( index > n ) { + return values[n] + ( index - n ) * ( values[n] - values[n-1] ); + } + return values[index]; +} + +/* +==================== +idCurve::TimeForIndex + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE float idCurve::TimeForIndex( const int index ) const { + int n = times.Num()-1; + + if ( index < 0 ) { + return times[0] + index * ( times[1] - times[0] ); + } else if ( index > n ) { + return times[n] + ( index - n ) * ( times[n] - times[n-1] ); + } + return times[index]; +} + + +/* +=============================================================================== + + Bezier Curve template. + The degree of the polynomial equals the number of knots minus one. + +=============================================================================== +*/ + +template< class type > +class idCurve_Bezier : public idCurve { +public: + idCurve_Bezier( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const int order, const float t, float *bvals ) const; + void BasisFirstDerivative( const int order, const float t, float *bvals ) const; + void BasisSecondDerivative( const int order, const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_Bezier::idCurve_Bezier +==================== +*/ +template< class type > +ID_INLINE idCurve_Bezier::idCurve_Bezier( void ) { +} + +/* +==================== +idCurve_Bezier::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_Bezier::GetCurrentValue( const float time ) const { + int i; + float *bvals; + type v; + + bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); + + Basis( this->values.Num(), time, bvals ); + v = bvals[0] * this->values[0]; + for ( i = 1; i < this->values.Num(); i++ ) { + v += bvals[i] * this->values[i]; + } + return v; +} + +/* +==================== +idCurve_Bezier::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_Bezier::GetCurrentFirstDerivative( const float time ) const { + int i; + float *bvals, d; + type v; + + bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); + + BasisFirstDerivative( this->values.Num(), time, bvals ); + v = bvals[0] * this->values[0]; + for ( i = 1; i < this->values.Num(); i++ ) { + v += bvals[i] * this->values[i]; + } + d = ( this->times[this->times.Num()-1] - this->times[0] ); + return ( (float) (this->values.Num()-1) / d ) * v; +} + +/* +==================== +idCurve_Bezier::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_Bezier::GetCurrentSecondDerivative( const float time ) const { + int i; + float *bvals, d; + type v; + + bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); + + BasisSecondDerivative( this->values.Num(), time, bvals ); + v = bvals[0] * this->values[0]; + for ( i = 1; i < this->values.Num(); i++ ) { + v += bvals[i] * this->values[i]; + } + d = ( this->times[this->times.Num()-1] - this->times[0] ); + return ( (float) (this->values.Num()-2) * (this->values.Num()-1) / ( d * d ) ) * v; +} + +/* +==================== +idCurve_Bezier::Basis + + bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_Bezier::Basis( const int order, const float t, float *bvals ) const { + int i, j, d; + float *c, c1, c2, s, o, ps, po; + + bvals[0] = 1.0f; + d = order - 1; + if ( d <= 0 ) { + return; + } + + c = (float *) _alloca16( (d+1) * sizeof( float ) ); + s = (float) ( t - this->times[0] ) / ( this->times[this->times.Num()-1] - this->times[0] ); + o = 1.0f - s; + ps = s; + po = o; + + for ( i = 1; i < d; i++ ) { + c[i] = 1.0f; + } + for ( i = 1; i < d; i++ ) { + c[i-1] = 0.0f; + c1 = c[i]; + c[i] = 1.0f; + for ( j = i+1; j <= d; j++ ) { + c2 = c[j]; + c[j] = c1 + c[j-1]; + c1 = c2; + } + bvals[i] = c[d] * ps; + ps *= s; + } + for ( i = d-1; i >= 0; i-- ) { + bvals[i] *= po; + po *= o; + } + bvals[d] = ps; +} + +/* +==================== +idCurve_Bezier::BasisFirstDerivative + + first derivative of bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_Bezier::BasisFirstDerivative( const int order, const float t, float *bvals ) const { + int i; + + Basis( order-1, t, bvals+1 ); + bvals[0] = 0.0f; + for ( i = 0; i < order-1; i++ ) { + bvals[i] -= bvals[i+1]; + } +} + +/* +==================== +idCurve_Bezier::BasisSecondDerivative + + second derivative of bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_Bezier::BasisSecondDerivative( const int order, const float t, float *bvals ) const { + int i; + + BasisFirstDerivative( order-1, t, bvals+1 ); + bvals[0] = 0.0f; + for ( i = 0; i < order-1; i++ ) { + bvals[i] -= bvals[i+1]; + } +} + + +/* +=============================================================================== + + Quadratic Bezier Curve template. + Should always have exactly three knots. + +=============================================================================== +*/ + +template< class type > +class idCurve_QuadraticBezier : public idCurve { + +public: + idCurve_QuadraticBezier( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const float t, float *bvals ) const; + void BasisFirstDerivative( const float t, float *bvals ) const; + void BasisSecondDerivative( const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_QuadraticBezier::idCurve_QuadraticBezier +==================== +*/ +template< class type > +ID_INLINE idCurve_QuadraticBezier::idCurve_QuadraticBezier( void ) { +} + + +/* +==================== +idCurve_QuadraticBezier::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_QuadraticBezier::GetCurrentValue( const float time ) const { + float bvals[3]; + assert( this->values.Num() == 3 ); + Basis( time, bvals ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ); +} + +/* +==================== +idCurve_QuadraticBezier::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_QuadraticBezier::GetCurrentFirstDerivative( const float time ) const { + float bvals[3], d; + assert( this->values.Num() == 3 ); + BasisFirstDerivative( time, bvals ); + d = ( this->times[2] - this->times[0] ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / d; +} + +/* +==================== +idCurve_QuadraticBezier::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_QuadraticBezier::GetCurrentSecondDerivative( const float time ) const { + float bvals[3], d; + assert( this->values.Num() == 3 ); + BasisSecondDerivative( time, bvals ); + d = ( this->times[2] - this->times[0] ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / ( d * d ); +} + +/* +==================== +idCurve_QuadraticBezier::Basis + + quadratic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_QuadraticBezier::Basis( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); + float s2 = s1 * s1; + bvals[0] = s2 - 2.0f * s1 + 1.0f; + bvals[1] = -2.0f * s2 + 2.0f * s1; + bvals[2] = s2; +} + +/* +==================== +idCurve_QuadraticBezier::BasisFirstDerivative + + first derivative of quadratic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_QuadraticBezier::BasisFirstDerivative( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); + bvals[0] = 2.0f * s1 - 2.0f; + bvals[1] = -4.0f * s1 + 2.0f; + bvals[2] = 2.0f * s1; +} + +/* +==================== +idCurve_QuadraticBezier::BasisSecondDerivative + + second derivative of quadratic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_QuadraticBezier::BasisSecondDerivative( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); + bvals[0] = 2.0f; + bvals[1] = -4.0f; + bvals[2] = 2.0f; +} + + +/* +=============================================================================== + + Cubic Bezier Curve template. + Should always have exactly four knots. + +=============================================================================== +*/ + +template< class type > +class idCurve_CubicBezier : public idCurve { + +public: + idCurve_CubicBezier( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const float t, float *bvals ) const; + void BasisFirstDerivative( const float t, float *bvals ) const; + void BasisSecondDerivative( const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_CubicBezier::idCurve_CubicBezier +==================== +*/ +template< class type > +ID_INLINE idCurve_CubicBezier::idCurve_CubicBezier( void ) { +} + + +/* +==================== +idCurve_CubicBezier::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CubicBezier::GetCurrentValue( const float time ) const { + float bvals[4]; + assert( this->values.Num() == 4 ); + Basis( time, bvals ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ); +} + +/* +==================== +idCurve_CubicBezier::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CubicBezier::GetCurrentFirstDerivative( const float time ) const { + float bvals[4], d; + assert( this->values.Num() == 4 ); + BasisFirstDerivative( time, bvals ); + d = ( this->times[3] - this->times[0] ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / d; +} + +/* +==================== +idCurve_CubicBezier::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CubicBezier::GetCurrentSecondDerivative( const float time ) const { + float bvals[4], d; + assert( this->values.Num() == 4 ); + BasisSecondDerivative( time, bvals ); + d = ( this->times[3] - this->times[0] ); + return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / ( d * d ); +} + +/* +==================== +idCurve_CubicBezier::Basis + + cubic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CubicBezier::Basis( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); + float s2 = s1 * s1; + float s3 = s2 * s1; + bvals[0] = -s3 + 3.0f * s2 - 3.0f * s1 + 1.0f; + bvals[1] = 3.0f * s3 - 6.0f * s2 + 3.0f * s1; + bvals[2] = -3.0f * s3 + 3.0f * s2; + bvals[3] = s3; +} + +/* +==================== +idCurve_CubicBezier::BasisFirstDerivative + + first derivative of cubic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CubicBezier::BasisFirstDerivative( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); + float s2 = s1 * s1; + bvals[0] = -3.0f * s2 + 6.0f * s1 - 3.0f; + bvals[1] = 9.0f * s2 - 12.0f * s1 + 3.0f; + bvals[2] = -9.0f * s2 + 6.0f * s1; + bvals[3] = 3.0f * s2; +} + +/* +==================== +idCurve_CubicBezier::BasisSecondDerivative + + second derivative of cubic bezier basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CubicBezier::BasisSecondDerivative( const float t, float *bvals ) const { + float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); + bvals[0] = -6.0f * s1 + 6.0f; + bvals[1] = 18.0f * s1 - 12.0f; + bvals[2] = -18.0f * s1 + 6.0f; + bvals[3] = 6.0f * s1; +} + + +/* +=============================================================================== + + Spline base template. + +=============================================================================== +*/ + +template< class type > +class idCurve_Spline : public idCurve { + +public: + enum boundary_t { BT_FREE, BT_CLAMPED, BT_CLOSED }; + + idCurve_Spline( void ); + + virtual bool IsDone( const float time ) const; + + virtual void SetBoundaryType( const boundary_t bt ) { boundaryType = bt; this->changed = true; } + virtual boundary_t GetBoundaryType( void ) const { return boundaryType; } + + virtual void SetCloseTime( const float t ) { closeTime = t; this->changed = true; } + virtual float GetCloseTime( void ) { return boundaryType == BT_CLOSED ? closeTime : 0.0f; } + +protected: + boundary_t boundaryType; + float closeTime; + + type ValueForIndex( const int index ) const; + float TimeForIndex( const int index ) const; + float ClampedTime( const float t ) const; +}; + +/* +==================== +idCurve_Spline::idCurve_Spline +==================== +*/ +template< class type > +ID_INLINE idCurve_Spline::idCurve_Spline( void ) { + boundaryType = BT_FREE; + closeTime = 0.0f; +} + +/* +==================== +idCurve_Spline::ValueForIndex + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_Spline::ValueForIndex( const int index ) const { + int n = this->values.Num()-1; + + if ( index < 0 ) { + if ( boundaryType == BT_CLOSED ) { + return this->values[ this->values.Num() + index % this->values.Num() ]; + } + else { + return this->values[0] + index * ( this->values[1] - this->values[0] ); + } + } + else if ( index > n ) { + if ( boundaryType == BT_CLOSED ) { + return this->values[ index % this->values.Num() ]; + } + else { + return this->values[n] + ( index - n ) * ( this->values[n] - this->values[n-1] ); + } + } + return this->values[index]; +} + +/* +==================== +idCurve_Spline::TimeForIndex + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE float idCurve_Spline::TimeForIndex( const int index ) const { + int n = this->times.Num()-1; + + if ( index < 0 ) { + if ( boundaryType == BT_CLOSED ) { + return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) - ( this->times[n] + closeTime - this->times[this->times.Num() + index % this->times.Num()] ); + } + else { + return this->times[0] + index * ( this->times[1] - this->times[0] ); + } + } + else if ( index > n ) { + if ( boundaryType == BT_CLOSED ) { + return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) + this->times[index % this->times.Num()]; + } + else { + return this->times[n] + ( index - n ) * ( this->times[n] - this->times[n-1] ); + } + } + return this->times[index]; +} + +/* +==================== +idCurve_Spline::ClampedTime + + return the clamped time based on the boundary type +==================== +*/ +template< class type > +ID_INLINE float idCurve_Spline::ClampedTime( const float t ) const { + if ( boundaryType == BT_CLAMPED ) { + if ( t < this->times[0] ) { + return this->times[0]; + } + else if ( t >= this->times[this->times.Num()-1] ) { + return this->times[this->times.Num()-1]; + } + } + return t; +} + +/* +==================== +idCurve_Spline::IsDone +==================== +*/ +template< class type > +ID_INLINE bool idCurve_Spline::IsDone( const float time ) const { + return ( boundaryType != BT_CLOSED && time >= this->times[ this->times.Num() - 1 ] ); +} + + +/* +=============================================================================== + + Cubic Interpolating Spline template. + The curve goes through all the knots. + +=============================================================================== +*/ + +template< class type > +class idCurve_NaturalCubicSpline : public idCurve_Spline { +public: + idCurve_NaturalCubicSpline( void ); + + virtual void Clear( void ) { idCurve_Spline::Clear(); this->values.Clear(); b.Clear(); c.Clear(); d.Clear(); } + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + mutable idListb; + mutable idListc; + mutable idListd; + + void Setup( void ) const; + void SetupFree( void ) const; + void SetupClamped( void ) const; + void SetupClosed( void ) const; +}; + +/* +==================== +idCurve_NaturalCubicSpline::idCurve_NaturalCubicSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_NaturalCubicSpline::idCurve_NaturalCubicSpline( void ) { +} + +/* +==================== +idCurve_NaturalCubicSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentValue( const float time ) const { + float clampedTime = this->ClampedTime( time ); + int i = this->IndexForTime( clampedTime ); + float s = time - this->TimeForIndex( i ); + Setup(); + return ( this->values[i] + s * ( b[i] + s * ( c[i] + s * d[i] ) ) ); +} + +/* +==================== +idCurve_NaturalCubicSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentFirstDerivative( const float time ) const { + float clampedTime = this->ClampedTime( time ); + int i = this->IndexForTime( clampedTime ); + float s = time - this->TimeForIndex( i ); + Setup(); + return ( b[i] + s * ( 2.0f * c[i] + 3.0f * s * d[i] ) ); +} + +/* +==================== +idCurve_NaturalCubicSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentSecondDerivative( const float time ) const { + float clampedTime = this->ClampedTime( time ); + int i = this->IndexForTime( clampedTime ); + float s = time - this->TimeForIndex( i ); + Setup(); + return ( 2.0f * c[i] + 6.0f * s * d[i] ); +} + +/* +==================== +idCurve_NaturalCubicSpline::Setup +==================== +*/ +template< class type > +ID_INLINE void idCurve_NaturalCubicSpline::Setup( void ) const { + if ( this->changed ) { + switch( this->boundaryType ) { + case idCurve_Spline::BT_FREE: SetupFree(); break; + case idCurve_Spline::BT_CLAMPED: SetupClamped(); break; + case idCurve_Spline::BT_CLOSED: SetupClosed(); break; + } + this->changed = false; + } +} + +/* +==================== +idCurve_NaturalCubicSpline::SetupFree +==================== +*/ +template< class type > +ID_INLINE void idCurve_NaturalCubicSpline::SetupFree( void ) const { + int i; + float inv; + float *d0, *d1, *beta, *gamma; + type *alpha, *delta; + + d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) ); + beta = (float *) _alloca16( this->values.Num() * sizeof( float ) ); + gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + delta = (type *) _alloca16( this->values.Num() * sizeof( type ) ); + + for ( i = 0; i < this->values.Num() - 1; i++ ) { + d0[i] = this->times[i+1] - this->times[i]; + } + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + d1[i] = this->times[i+1] - this->times[i-1]; + } + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] ); + inv = 1.0f / ( d0[i-1] * d0[i] ); + alpha[i] = inv * sum; + } + + beta[0] = 1.0f; + gamma[0] = 0.0f; + delta[0] = this->values[0] - this->values[0]; + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1]; + inv = 1.0f / beta[i]; + gamma[i] = inv * d0[i]; + delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] ); + } + beta[this->values.Num() - 1] = 1.0f; + delta[this->values.Num() - 1] = this->values[0] - this->values[0]; + + b.AssureSize( this->values.Num() ); + c.AssureSize( this->values.Num() ); + d.AssureSize( this->values.Num() ); + + c[this->values.Num() - 1] = this->values[0] - this->values[0]; + + for ( i = this->values.Num() - 2; i >= 0; i-- ) { + c[i] = delta[i] - gamma[i] * c[i+1]; + inv = 1.0f / d0[i]; + b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i] * ( c[i+1] + 2.0f * c[i] ); + d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] ); + } +} + +/* +==================== +idCurve_NaturalCubicSpline::SetupClamped +==================== +*/ +template< class type > +ID_INLINE void idCurve_NaturalCubicSpline::SetupClamped( void ) const { + int i; + float inv; + float *d0, *d1, *beta, *gamma; + type *alpha, *delta; + + d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) ); + beta = (float *) _alloca16( this->values.Num() * sizeof( float ) ); + gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + delta = (type *) _alloca16( this->values.Num() * sizeof( type ) ); + + for ( i = 0; i < this->values.Num() - 1; i++ ) { + d0[i] = this->times[i+1] - this->times[i]; + } + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + d1[i] = this->times[i+1] - this->times[i-1]; + } + + inv = 1.0f / d0[0]; + alpha[0] = 3.0f * ( inv - 1.0f ) * ( this->values[1] - this->values[0] ); + inv = 1.0f / d0[this->values.Num() - 2]; + alpha[this->values.Num() - 1] = 3.0f * ( 1.0f - inv ) * ( this->values[this->values.Num() - 1] - this->values[this->values.Num() - 2] ); + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] ); + inv = 1.0f / ( d0[i-1] * d0[i] ); + alpha[i] = inv * sum; + } + + beta[0] = 2.0f * d0[0]; + gamma[0] = 0.5f; + inv = 1.0f / beta[0]; + delta[0] = inv * alpha[0]; + + for ( i = 1; i < this->values.Num() - 1; i++ ) { + beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1]; + inv = 1.0f / beta[i]; + gamma[i] = inv * d0[i]; + delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] ); + } + + beta[this->values.Num() - 1] = d0[this->values.Num() - 2] * ( 2.0f - gamma[this->values.Num() - 2] ); + inv = 1.0f / beta[this->values.Num() - 1]; + delta[this->values.Num() - 1] = inv * ( alpha[this->values.Num() - 1] - d0[this->values.Num() - 2] * delta[this->values.Num() - 2] ); + + b.AssureSize( this->values.Num() ); + c.AssureSize( this->values.Num() ); + d.AssureSize( this->values.Num() ); + + c[this->values.Num() - 1] = delta[this->values.Num() - 1]; + + for ( i = this->values.Num() - 2; i >= 0; i-- ) { + c[i] = delta[i] - gamma[i] * c[i+1]; + inv = 1.0f / d0[i]; + b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i]* ( c[i+1] + 2.0f * c[i] ); + d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] ); + } +} + +/* +==================== +idCurve_NaturalCubicSpline::SetupClosed +==================== +*/ +template< class type > +ID_INLINE void idCurve_NaturalCubicSpline::SetupClosed( void ) const { + int i, j; + float c0, c1; + float *d0; + idMatX mat; + idVecX x; + + d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); + x.SetData( this->values.Num(), VECX_ALLOCA( this->values.Num() ) ); + mat.SetData( this->values.Num(), this->values.Num(), MATX_ALLOCA( this->values.Num() * this->values.Num() ) ); + + b.AssureSize( this->values.Num() ); + c.AssureSize( this->values.Num() ); + d.AssureSize( this->values.Num() ); + + for ( i = 0; i < this->values.Num() - 1; i++ ) { + d0[i] = this->times[i+1] - this->times[i]; + } + + // matrix of system + mat[0][0] = 1.0f; + mat[0][this->values.Num() - 1] = -1.0f; + for ( i = 1; i <= this->values.Num() - 2; i++ ) { + mat[i][i-1] = d0[i-1]; + mat[i][i ] = 2.0f * ( d0[i-1] + d0[i] ); + mat[i][i+1] = d0[i]; + } + mat[this->values.Num() - 1][this->values.Num() - 2] = d0[this->values.Num() - 2]; + mat[this->values.Num() - 1][0] = 2.0f * ( d0[this->values.Num() - 2] + d0[0] ); + mat[this->values.Num() - 1][1] = d0[0]; + + // right-hand side + c[0].Zero(); + for ( i = 1; i <= this->values.Num() - 2; i++ ) { + c0 = 1.0f / d0[i]; + c1 = 1.0f / d0[i-1]; + c[i] = 3.0f * ( c0 * ( this->values[i + 1] - this->values[i] ) - c1 * ( this->values[i] - this->values[i - 1] ) ); + } + c0 = 1.0f / d0[0]; + c1 = 1.0f / d0[this->values.Num() - 2]; + c[this->values.Num() - 1] = 3.0f * ( c0 * ( this->values[1] - this->values[0] ) - c1 * ( this->values[0] - this->values[this->values.Num() - 2] ) ); + + // solve system for each dimension + mat.LU_Factor( NULL ); + for ( i = 0; i < this->values[0].GetDimension(); i++ ) { + for ( j = 0; j < this->values.Num(); j++ ) { + x[j] = c[j][i]; + } + mat.LU_Solve( x, x, NULL ); + for ( j = 0; j < this->values.Num(); j++ ) { + c[j][i] = x[j]; + } + } + + for ( i = 0; i < this->values.Num() - 1; i++ ) { + c0 = 1.0f / d0[i]; + b[i] = c0 * ( this->values[i + 1] - this->values[i] ) - ( 1.0f / 3.0f ) * ( c[i+1] + 2.0f * c[i] ) * d0[i]; + d[i] = ( 1.0f / 3.0f ) * c0 * ( c[i + 1] - c[i] ); + } +} + + +/* +=============================================================================== + + Uniform Cubic Interpolating Spline template. + The curve goes through all the knots. + +=============================================================================== +*/ + +template< class type > +class idCurve_CatmullRomSpline : public idCurve_Spline { + +public: + idCurve_CatmullRomSpline( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const int index, const float t, float *bvals ) const; + void BasisFirstDerivative( const int index, const float t, float *bvals ) const; + void BasisSecondDerivative( const int index, const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_CatmullRomSpline::idCurve_CatmullRomSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_CatmullRomSpline::idCurve_CatmullRomSpline( void ) { +} + +/* +==================== +idCurve_CatmullRomSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CatmullRomSpline::GetCurrentValue( const float time ) const { + int i, j, k; + float bvals[4], clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + Basis( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_CatmullRomSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CatmullRomSpline::GetCurrentFirstDerivative( const float time ) const { + int i, j, k; + float bvals[4], d, clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisFirstDerivative( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / d; +} + +/* +==================== +idCurve_CatmullRomSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_CatmullRomSpline::GetCurrentSecondDerivative( const float time ) const { + int i, j, k; + float bvals[4], d, clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisSecondDerivative( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / ( d * d ); +} + +/* +==================== +idCurve_CatmullRomSpline::Basis + + spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CatmullRomSpline::Basis( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = ( ( -s + 2.0f ) * s - 1.0f ) * s * 0.5f; // -0.5f s * s * s + s * s - 0.5f * s + bvals[1] = ( ( ( 3.0f * s - 5.0f ) * s ) * s + 2.0f ) * 0.5f; // 1.5f * s * s * s - 2.5f * s * s + 1.0f + bvals[2] = ( ( -3.0f * s + 4.0f ) * s + 1.0f ) * s * 0.5f; // -1.5f * s * s * s - 2.0f * s * s + 0.5f s + bvals[3] = ( ( s - 1.0f ) * s * s ) * 0.5f; // 0.5f * s * s * s - 0.5f * s * s +} + +/* +==================== +idCurve_CatmullRomSpline::BasisFirstDerivative + + first derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CatmullRomSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = ( -1.5f * s + 2.0f ) * s - 0.5f; // -1.5f * s * s + 2.0f * s - 0.5f + bvals[1] = ( 4.5f * s - 5.0f ) * s; // 4.5f * s * s - 5.0f * s + bvals[2] = ( -4.5 * s + 4.0f ) * s + 0.5f; // -4.5 * s * s + 4.0f * s + 0.5f + bvals[3] = 1.5f * s * s - s; // 1.5f * s * s - s +} + +/* +==================== +idCurve_CatmullRomSpline::BasisSecondDerivative + + second derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_CatmullRomSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = -3.0f * s + 2.0f; + bvals[1] = 9.0f * s - 5.0f; + bvals[2] = -9.0f * s + 4.0f; + bvals[3] = 3.0f * s - 1.0f; +} + + +/* +=============================================================================== + + Cubic Interpolating Spline template. + The curve goes through all the knots. + The curve becomes the Catmull-Rom spline if the tension, + continuity and bias are all set to zero. + +=============================================================================== +*/ + +template< class type > +class idCurve_KochanekBartelsSpline : public idCurve_Spline { + +public: + idCurve_KochanekBartelsSpline( void ); + + virtual int AddValue( const float time, const type &value ); + virtual int AddValue( const float time, const type &value, const float tension, const float continuity, const float bias ); + virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); tension.RemoveIndex(index); continuity.RemoveIndex(index); bias.RemoveIndex(index); } + virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); tension.Clear(); continuity.Clear(); bias.Clear(); this->currentIndex = -1; } + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + idList tension; + idList continuity; + idList bias; + + void TangentsForIndex( const int index, type &t0, type &t1 ) const; + + void Basis( const int index, const float t, float *bvals ) const; + void BasisFirstDerivative( const int index, const float t, float *bvals ) const; + void BasisSecondDerivative( const int index, const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_KochanekBartelsSpline::idCurve_KochanekBartelsSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_KochanekBartelsSpline::idCurve_KochanekBartelsSpline( void ) { +} + +/* +==================== +idCurve_KochanekBartelsSpline::AddValue + + add a timed/value pair to the spline + returns the index to the inserted pair +==================== +*/ +template< class type > +ID_INLINE int idCurve_KochanekBartelsSpline::AddValue( const float time, const type &value ) { + int i; + + i = this->IndexForTime( time ); + this->times.Insert( time, i ); + this->values.Insert( value, i ); + tension.Insert( 0.0f, i ); + continuity.Insert( 0.0f, i ); + bias.Insert( 0.0f, i ); + return i; +} + +/* +==================== +idCurve_KochanekBartelsSpline::AddValue + + add a timed/value pair to the spline + returns the index to the inserted pair +==================== +*/ +template< class type > +ID_INLINE int idCurve_KochanekBartelsSpline::AddValue( const float time, const type &value, const float tension, const float continuity, const float bias ) { + int i; + + i = this->IndexForTime( time ); + this->times.Insert( time, i ); + this->values.Insert( value, i ); + this->tension.Insert( tension, i ); + this->continuity.Insert( continuity, i ); + this->bias.Insert( bias, i ); + return i; +} + +/* +==================== +idCurve_KochanekBartelsSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentValue( const float time ) const { + int i; + float bvals[4], clampedTime; + type v, t0, t1; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + TangentsForIndex( i - 1, t0, t1 ); + Basis( i - 1, clampedTime, bvals ); + v = bvals[0] * this->ValueForIndex( i - 1 ); + v += bvals[1] * this->ValueForIndex( i ); + v += bvals[2] * t0; + v += bvals[3] * t1; + return v; +} + +/* +==================== +idCurve_KochanekBartelsSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentFirstDerivative( const float time ) const { + int i; + float bvals[4], d, clampedTime; + type v, t0, t1; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + TangentsForIndex( i - 1, t0, t1 ); + BasisFirstDerivative( i - 1, clampedTime, bvals ); + v = bvals[0] * this->ValueForIndex( i - 1 ); + v += bvals[1] * this->ValueForIndex( i ); + v += bvals[2] * t0; + v += bvals[3] * t1; + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / d; +} + +/* +==================== +idCurve_KochanekBartelsSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentSecondDerivative( const float time ) const { + int i; + float bvals[4], d, clampedTime; + type v, t0, t1; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + TangentsForIndex( i - 1, t0, t1 ); + BasisSecondDerivative( i - 1, clampedTime, bvals ); + v = bvals[0] * this->ValueForIndex( i - 1 ); + v += bvals[1] * this->ValueForIndex( i ); + v += bvals[2] * t0; + v += bvals[3] * t1; + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / ( d * d ); +} + +/* +==================== +idCurve_KochanekBartelsSpline::TangentsForIndex +==================== +*/ +template< class type > +ID_INLINE void idCurve_KochanekBartelsSpline::TangentsForIndex( const int index, type &t0, type &t1 ) const { + float dt, omt, omc, opc, omb, opb, adj, s0, s1; + type delta; + + delta = this->ValueForIndex( index + 1 ) - this->ValueForIndex( index ); + dt = this->TimeForIndex( index + 1 ) - this->TimeForIndex( index ); + + omt = 1.0f - tension[index]; + omc = 1.0f - continuity[index]; + opc = 1.0f + continuity[index]; + omb = 1.0f - bias[index]; + opb = 1.0f + bias[index]; + adj = 2.0f * dt / ( this->TimeForIndex( index + 1 ) - this->TimeForIndex( index - 1 ) ); + s0 = 0.5f * adj * omt * opc * opb; + s1 = 0.5f * adj * omt * omc * omb; + + // outgoing tangent at first point + t0 = s1 * delta + s0 * ( this->ValueForIndex( index ) - this->ValueForIndex( index - 1 ) ); + + omt = 1.0f - tension[index + 1]; + omc = 1.0f - continuity[index + 1]; + opc = 1.0f + continuity[index + 1]; + omb = 1.0f - bias[index + 1]; + opb = 1.0f + bias[index + 1]; + adj = 2.0f * dt / ( this->TimeForIndex( index + 2 ) - this->TimeForIndex( index ) ); + s0 = 0.5f * adj * omt * omc * opb; + s1 = 0.5f * adj * omt * opc * omb; + + // incoming tangent at second point + t1 = s1 * ( this->ValueForIndex( index + 2 ) - this->ValueForIndex( index + 1 ) ) + s0 * delta; +} + +/* +==================== +idCurve_KochanekBartelsSpline::Basis + + spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_KochanekBartelsSpline::Basis( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = ( ( 2.0f * s - 3.0f ) * s ) * s + 1.0f; // 2.0f * s * s * s - 3.0f * s * s + 1.0f + bvals[1] = ( ( -2.0f * s + 3.0f ) * s ) * s; // -2.0f * s * s * s + 3.0f * s * s + bvals[2] = ( ( s - 2.0f ) * s ) * s + s; // s * s * s - 2.0f * s * s + s + bvals[3] = ( ( s - 1.0f ) * s ) * s; // s * s * s - s * s +} + +/* +==================== +idCurve_KochanekBartelsSpline::BasisFirstDerivative + + first derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_KochanekBartelsSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = ( 6.0f * s - 6.0f ) * s; // 6.0f * s * s - 6.0f * s + bvals[1] = ( -6.0f * s + 6.0f ) * s; // -6.0f * s * s + 6.0f * s + bvals[2] = ( 3.0f * s - 4.0f ) * s + 1.0f; // 3.0f * s * s - 4.0f * s + 1.0f + bvals[3] = ( 3.0f * s - 2.0f ) * s; // 3.0f * s * s - 2.0f * s +} + +/* +==================== +idCurve_KochanekBartelsSpline::BasisSecondDerivative + + second derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_KochanekBartelsSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = 12.0f * s - 6.0f; + bvals[1] = -12.0f * s + 6.0f; + bvals[2] = 6.0f * s - 4.0f; + bvals[3] = 6.0f * s - 2.0f; +} + + +/* +=============================================================================== + + B-Spline base template. Uses recursive definition and is slow. + Use idCurve_UniformCubicBSpline or idCurve_NonUniformBSpline instead. + +=============================================================================== +*/ + +template< class type > +class idCurve_BSpline : public idCurve_Spline { + +public: + idCurve_BSpline( void ); + + virtual int GetOrder( void ) const { return order; } + virtual void SetOrder( const int i ) { assert( i > 0 && i < 10 ); order = i; } + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + int order; + + float Basis( const int index, const int order, const float t ) const; + float BasisFirstDerivative( const int index, const int order, const float t ) const; + float BasisSecondDerivative( const int index, const int order, const float t ) const; +}; + +/* +==================== +idCurve_BSpline::idCurve_NaturalCubicSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_BSpline::idCurve_BSpline( void ) { + order = 4; // default to cubic +} + +/* +==================== +idCurve_BSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_BSpline::GetCurrentValue( const float time ) const { + int i, j, k; + float clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < order; j++ ) { + k = i + j - ( order >> 1 ); + v += Basis( k-2, order, clampedTime ) * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_BSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_BSpline::GetCurrentFirstDerivative( const float time ) const { + int i, j, k; + float clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < order; j++ ) { + k = i + j - ( order >> 1 ); + v += BasisFirstDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_BSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_BSpline::GetCurrentSecondDerivative( const float time ) const { + int i, j, k; + float clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < order; j++ ) { + k = i + j - ( order >> 1 ); + v += BasisSecondDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_BSpline::Basis + + spline basis function +==================== +*/ +template< class type > +ID_INLINE float idCurve_BSpline::Basis( const int index, const int order, const float t ) const { + if ( order <= 1 ) { + if ( this->TimeForIndex( index ) < t && t <= this->TimeForIndex( index + 1 ) ) { + return 1.0f; + } else { + return 0.0f; + } + } else { + float sum = 0.0f; + float d1 = this->TimeForIndex( index+order-1 ) - this->TimeForIndex( index ); + if ( d1 != 0.0f ) { + sum += (float) ( t - this->TimeForIndex( index ) ) * Basis( index, order-1, t ) / d1; + } + + float d2 = this->TimeForIndex( index+order ) - this->TimeForIndex( index+1 ); + if ( d2 != 0.0f ) { + sum += (float) ( this->TimeForIndex( index+order ) - t ) * Basis( index+1, order-1, t ) / d2; + } + return sum; + } +} + +/* +==================== +idCurve_BSpline::BasisFirstDerivative + + first derivative of spline basis function +==================== +*/ +template< class type > +ID_INLINE float idCurve_BSpline::BasisFirstDerivative( const int index, const int order, const float t ) const { + return ( Basis( index, order-1, t ) - Basis( index+1, order-1, t ) ) * + (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) ); +} + +/* +==================== +idCurve_BSpline::BasisSecondDerivative + + second derivative of spline basis function +==================== +*/ +template< class type > +ID_INLINE float idCurve_BSpline::BasisSecondDerivative( const int index, const int order, const float t ) const { + return ( BasisFirstDerivative( index, order-1, t ) - BasisFirstDerivative( index+1, order-1, t ) ) * + (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) ); +} + + +/* +=============================================================================== + + Uniform Non-Rational Cubic B-Spline template. + +=============================================================================== +*/ + +template< class type > +class idCurve_UniformCubicBSpline : public idCurve_BSpline { + +public: + idCurve_UniformCubicBSpline( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const int index, const float t, float *bvals ) const; + void BasisFirstDerivative( const int index, const float t, float *bvals ) const; + void BasisSecondDerivative( const int index, const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_UniformCubicBSpline::idCurve_UniformCubicBSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_UniformCubicBSpline::idCurve_UniformCubicBSpline( void ) { + this->order = 4; // always cubic +} + +/* +==================== +idCurve_UniformCubicBSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentValue( const float time ) const { + int i, j, k; + float bvals[4], clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + Basis( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_UniformCubicBSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentFirstDerivative( const float time ) const { + int i, j, k; + float bvals[4], d, clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisFirstDerivative( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / d; +} + +/* +==================== +idCurve_UniformCubicBSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentSecondDerivative( const float time ) const { + int i, j, k; + float bvals[4], d, clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisSecondDerivative( i-1, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < 4; j++ ) { + k = i + j - 2; + v += bvals[j] * this->ValueForIndex( k ); + } + d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); + return v / ( d * d ); +} + +/* +==================== +idCurve_UniformCubicBSpline::Basis + + spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_UniformCubicBSpline::Basis( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = ( ( ( -s + 3.0f ) * s - 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f ); + bvals[1] = ( ( ( 3.0f * s - 6.0f ) * s ) * s + 4.0f ) * ( 1.0f / 6.0f ); + bvals[2] = ( ( ( -3.0f * s + 3.0f ) * s + 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f ); + bvals[3] = ( s * s * s ) * ( 1.0f / 6.0f ); +} + +/* +==================== +idCurve_UniformCubicBSpline::BasisFirstDerivative + + first derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_UniformCubicBSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = -0.5f * s * s + s - 0.5f; + bvals[1] = 1.5f * s * s - 2.0f * s; + bvals[2] = -1.5f * s * s + s + 0.5f; + bvals[3] = 0.5f * s * s; +} + +/* +==================== +idCurve_UniformCubicBSpline::BasisSecondDerivative + + second derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_UniformCubicBSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { + float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); + bvals[0] = -s + 1.0f; + bvals[1] = 3.0f * s - 2.0f; + bvals[2] = -3.0f * s + 1.0f; + bvals[3] = s; +} + + +/* +=============================================================================== + + Non-Uniform Non-Rational B-Spline (NUBS) template. + +=============================================================================== +*/ + +template< class type > +class idCurve_NonUniformBSpline : public idCurve_BSpline { + +public: + idCurve_NonUniformBSpline( void ); + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + void Basis( const int index, const int order, const float t, float *bvals ) const; + void BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const; + void BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const; +}; + +/* +==================== +idCurve_NonUniformBSpline::idCurve_NonUniformBSpline +==================== +*/ +template< class type > +ID_INLINE idCurve_NonUniformBSpline::idCurve_NonUniformBSpline( void ) { +} + +/* +==================== +idCurve_NonUniformBSpline::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NonUniformBSpline::GetCurrentValue( const float time ) const { + int i, j, k; + float clampedTime; + type v; + float *bvals = (float *) _alloca16( this->order * sizeof(float) ); + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + Basis( i-1, this->order, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + v += bvals[j] * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_NonUniformBSpline::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NonUniformBSpline::GetCurrentFirstDerivative( const float time ) const { + int i, j, k; + float clampedTime; + type v; + float *bvals = (float *) _alloca16( this->order * sizeof(float) ); + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisFirstDerivative( i-1, this->order, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + v += bvals[j] * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_NonUniformBSpline::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NonUniformBSpline::GetCurrentSecondDerivative( const float time ) const { + int i, j, k; + float clampedTime; + type v; + float *bvals = (float *) _alloca16( this->order * sizeof(float) ); + + if ( this->times.Num() == 1 ) { + return ( this->values[0] - this->values[0] ); + } + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + BasisSecondDerivative( i-1, this->order, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + v += bvals[j] * this->ValueForIndex( k ); + } + return v; +} + +/* +==================== +idCurve_NonUniformBSpline::Basis + + spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_NonUniformBSpline::Basis( const int index, const int order, const float t, float *bvals ) const { + int r, s, i; + float omega; + + bvals[order-1] = 1.0f; + for ( r = 2; r <= order; r++ ) { + i = index - r + 1; + bvals[order - r] = 0.0f; + for ( s = order - r + 1; s < order; s++ ) { + i++; + omega = (float) ( t - this->TimeForIndex( i ) ) / ( this->TimeForIndex( i + r - 1 ) - this->TimeForIndex( i ) ); + bvals[s - 1] += ( 1.0f - omega ) * bvals[s]; + bvals[s] *= omega; + } + } +} + +/* +==================== +idCurve_NonUniformBSpline::BasisFirstDerivative + + first derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_NonUniformBSpline::BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const { + int i; + + Basis( index, order-1, t, bvals+1 ); + bvals[0] = 0.0f; + for ( i = 0; i < order-1; i++ ) { + bvals[i] -= bvals[i+1]; + bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); + } + bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); +} + +/* +==================== +idCurve_NonUniformBSpline::BasisSecondDerivative + + second derivative of spline basis functions +==================== +*/ +template< class type > +ID_INLINE void idCurve_NonUniformBSpline::BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const { + int i; + + BasisFirstDerivative( index, order-1, t, bvals+1 ); + bvals[0] = 0.0f; + for ( i = 0; i < order-1; i++ ) { + bvals[i] -= bvals[i+1]; + bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); + } + bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); +} + + +/* +=============================================================================== + + Non-Uniform Rational B-Spline (NURBS) template. + +=============================================================================== +*/ + +template< class type > +class idCurve_NURBS : public idCurve_NonUniformBSpline { + +public: + idCurve_NURBS( void ); + + virtual int AddValue( const float time, const type &value ); + virtual int AddValue( const float time, const type &value, const float weight ); + virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); weights.RemoveIndex(index); } + virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); weights.Clear(); this->currentIndex = -1; } + + virtual type GetCurrentValue( const float time ) const; + virtual type GetCurrentFirstDerivative( const float time ) const; + virtual type GetCurrentSecondDerivative( const float time ) const; + +protected: + idList weights; + + float WeightForIndex( const int index ) const; +}; + +/* +==================== +idCurve_NURBS::idCurve_NURBS +==================== +*/ +template< class type > +ID_INLINE idCurve_NURBS::idCurve_NURBS( void ) { +} + +/* +==================== +idCurve_NURBS::AddValue + + add a timed/value pair to the spline + returns the index to the inserted pair +==================== +*/ +template< class type > +ID_INLINE int idCurve_NURBS::AddValue( const float time, const type &value ) { + int i; + + i = this->IndexForTime( time ); + this->times.Insert( time, i ); + this->values.Insert( value, i ); + weights.Insert( 1.0f, i ); + return i; +} + +/* +==================== +idCurve_NURBS::AddValue + + add a timed/value pair to the spline + returns the index to the inserted pair +==================== +*/ +template< class type > +ID_INLINE int idCurve_NURBS::AddValue( const float time, const type &value, const float weight ) { + int i; + + i = this->IndexForTime( time ); + this->times.Insert( time, i ); + this->values.Insert( value, i ); + weights.Insert( weight, i ); + return i; +} + +/* +==================== +idCurve_NURBS::GetCurrentValue + + get the value for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NURBS::GetCurrentValue( const float time ) const { + int i, j, k; + float w, b, *bvals, clampedTime; + type v; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + bvals = (float *) _alloca16( this->order * sizeof(float) ); + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + this->Basis( i-1, this->order, clampedTime, bvals ); + v = this->values[0] - this->values[0]; + w = 0.0f; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + b = bvals[j] * WeightForIndex( k ); + w += b; + v += b * this->ValueForIndex( k ); + } + return v / w; +} + +/* +==================== +idCurve_NURBS::GetCurrentFirstDerivative + + get the first derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NURBS::GetCurrentFirstDerivative( const float time ) const { + int i, j, k; + float w, wb, wd1, b, d1, *bvals, *d1vals, clampedTime; + type v, vb, vd1; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + bvals = (float *) _alloca16( this->order * sizeof(float) ); + d1vals = (float *) _alloca16( this->order * sizeof(float) ); + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + this->Basis( i-1, this->order, clampedTime, bvals ); + this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals ); + vb = vd1 = this->values[0] - this->values[0]; + wb = wd1 = 0.0f; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + w = WeightForIndex( k ); + b = bvals[j] * w; + d1 = d1vals[j] * w; + wb += b; + wd1 += d1; + v = this->ValueForIndex( k ); + vb += b * v; + vd1 += d1 * v; + } + return ( wb * vd1 - vb * wd1 ) / ( wb * wb ); +} + +/* +==================== +idCurve_NURBS::GetCurrentSecondDerivative + + get the second derivative for the given time +==================== +*/ +template< class type > +ID_INLINE type idCurve_NURBS::GetCurrentSecondDerivative( const float time ) const { + int i, j, k; + float w, wb, wd1, wd2, b, d1, d2, *bvals, *d1vals, *d2vals, clampedTime; + type v, vb, vd1, vd2; + + if ( this->times.Num() == 1 ) { + return this->values[0]; + } + + bvals = (float *) _alloca16( this->order * sizeof(float) ); + d1vals = (float *) _alloca16( this->order * sizeof(float) ); + d2vals = (float *) _alloca16( this->order * sizeof(float) ); + + clampedTime = this->ClampedTime( time ); + i = this->IndexForTime( clampedTime ); + this->Basis( i-1, this->order, clampedTime, bvals ); + this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals ); + this->BasisSecondDerivative( i-1, this->order, clampedTime, d2vals ); + vb = vd1 = vd2 = this->values[0] - this->values[0]; + wb = wd1 = wd2 = 0.0f; + for ( j = 0; j < this->order; j++ ) { + k = i + j - ( this->order >> 1 ); + w = WeightForIndex( k ); + b = bvals[j] * w; + d1 = d1vals[j] * w; + d2 = d2vals[j] * w; + wb += b; + wd1 += d1; + wd2 += d2; + v = this->ValueForIndex( k ); + vb += b * v; + vd1 += d1 * v; + vd2 += d2 * v; + } + return ( ( wb * wb ) * ( wb * vd2 - vb * wd2 ) - ( wb * vd1 - vb * wd1 ) * 2.0f * wb * wd1 ) / ( wb * wb * wb * wb ); +} + +/* +==================== +idCurve_NURBS::WeightForIndex + + get the weight for the given index +==================== +*/ +template< class type > +ID_INLINE float idCurve_NURBS::WeightForIndex( const int index ) const { + int n = weights.Num()-1; + + if ( index < 0 ) { + if ( this->boundaryType == idCurve_Spline::BT_CLOSED ) { + return weights[ weights.Num() + index % weights.Num() ]; + } else { + return weights[0] + index * ( weights[1] - weights[0] ); + } + } else if ( index > n ) { + if ( this->boundaryType == idCurve_Spline::BT_CLOSED ) { + return weights[ index % weights.Num() ]; + } else { + return weights[n] + ( index - n ) * ( weights[n] - weights[n-1] ); + } + } + return weights[index]; +} + +#endif /* !__MATH_CURVE_H__ */ diff --git a/idlib/math/Extrapolate.h b/idlib/math/Extrapolate.h new file mode 100644 index 000000000..df7549f8f --- /dev/null +++ b/idlib/math/Extrapolate.h @@ -0,0 +1,232 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_EXTRAPOLATE_H__ +#define __MATH_EXTRAPOLATE_H__ + +/* +============================================================================================== + + Extrapolation + +============================================================================================== +*/ + +typedef enum { + EXTRAPOLATION_NONE = 0x01, // no extrapolation, covered distance = duration * 0.001 * ( baseSpeed ) + EXTRAPOLATION_LINEAR = 0x02, // linear extrapolation, covered distance = duration * 0.001 * ( baseSpeed + speed ) + EXTRAPOLATION_ACCELLINEAR = 0x04, // linear acceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed ) + EXTRAPOLATION_DECELLINEAR = 0x08, // linear deceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed ) + EXTRAPOLATION_ACCELSINE = 0x10, // sinusoidal acceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed ) + EXTRAPOLATION_DECELSINE = 0x20, // sinusoidal deceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed ) + EXTRAPOLATION_NOSTOP = 0x40 // do not stop at startTime + duration +} extrapolation_t; + +template< class type > +class idExtrapolate { +public: + idExtrapolate(); + + void Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType ); + type GetCurrentValue( float time ) const; + type GetCurrentSpeed( float time ) const; + bool IsDone( float time ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && time >= startTime + duration ); } + void SetStartTime( float time ) { startTime = time; currentTime = -1; } + float GetStartTime( void ) const { return startTime; } + float GetEndTime( void ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && duration > 0 ) ? startTime + duration : 0; } + float GetDuration( void ) const { return duration; } + void SetStartValue( const type &value ) { startValue = value; currentTime = -1; } + const type & GetStartValue( void ) const { return startValue; } + const type & GetBaseSpeed( void ) const { return baseSpeed; } + const type & GetSpeed( void ) const { return speed; } + extrapolation_t GetExtrapolationType( void ) const { return extrapolationType; } + +private: + extrapolation_t extrapolationType; + float startTime; + float duration; + type startValue; + type baseSpeed; + type speed; + mutable float currentTime; + mutable type currentValue; +}; + +/* +==================== +idExtrapolate::idExtrapolate +==================== +*/ +template< class type > +ID_INLINE idExtrapolate::idExtrapolate() { + extrapolationType = EXTRAPOLATION_NONE; + startTime = duration = 0.0f; + memset( &startValue, 0, sizeof( startValue ) ); + memset( &baseSpeed, 0, sizeof( baseSpeed ) ); + memset( &speed, 0, sizeof( speed ) ); + currentTime = -1; + currentValue = startValue; +} + +/* +==================== +idExtrapolate::Init +==================== +*/ +template< class type > +ID_INLINE void idExtrapolate::Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType ) { + this->extrapolationType = extrapolationType; + this->startTime = startTime; + this->duration = duration; + this->startValue = startValue; + this->baseSpeed = baseSpeed; + this->speed = speed; + currentTime = -1; + currentValue = startValue; +} + +/* +==================== +idExtrapolate::GetCurrentValue +==================== +*/ +template< class type > +ID_INLINE type idExtrapolate::GetCurrentValue( float time ) const { + float deltaTime, s; + + if ( time == currentTime ) { + return currentValue; + } + + currentTime = time; + + if ( time < startTime ) { + return startValue; + } + + if ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) { + time = startTime + duration; + } + + switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) { + case EXTRAPOLATION_NONE: { + deltaTime = ( time - startTime ) * 0.001f; + currentValue = startValue + deltaTime * baseSpeed; + break; + } + case EXTRAPOLATION_LINEAR: { + deltaTime = ( time - startTime ) * 0.001f; + currentValue = startValue + deltaTime * ( baseSpeed + speed ); + break; + } + case EXTRAPOLATION_ACCELLINEAR: { + if ( !duration ) { + currentValue = startValue; + } else { + deltaTime = ( time - startTime ) / duration; + s = ( 0.5f * deltaTime * deltaTime ) * ( duration * 0.001f ); + currentValue = startValue + deltaTime * baseSpeed + s * speed; + } + break; + } + case EXTRAPOLATION_DECELLINEAR: { + if ( !duration ) { + currentValue = startValue; + } else { + deltaTime = ( time - startTime ) / duration; + s = ( deltaTime - ( 0.5f * deltaTime * deltaTime ) ) * ( duration * 0.001f ); + currentValue = startValue + deltaTime * baseSpeed + s * speed; + } + break; + } + case EXTRAPOLATION_ACCELSINE: { + if ( !duration ) { + currentValue = startValue; + } else { + deltaTime = ( time - startTime ) / duration; + s = ( 1.0f - idMath::Cos( deltaTime * idMath::HALF_PI ) ) * duration * 0.001f * idMath::SQRT_1OVER2; + currentValue = startValue + deltaTime * baseSpeed + s * speed; + } + break; + } + case EXTRAPOLATION_DECELSINE: { + if ( !duration ) { + currentValue = startValue; + } else { + deltaTime = ( time - startTime ) / duration; + s = idMath::Sin( deltaTime * idMath::HALF_PI ) * duration * 0.001f * idMath::SQRT_1OVER2; + currentValue = startValue + deltaTime * baseSpeed + s * speed; + } + break; + } + } + return currentValue; +} + +/* +==================== +idExtrapolate::GetCurrentSpeed +==================== +*/ +template< class type > +ID_INLINE type idExtrapolate::GetCurrentSpeed( float time ) const { + float deltaTime, s; + + if ( time < startTime || !duration ) { + return ( startValue - startValue ); + } + + if ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) { + return ( startValue - startValue ); + } + + switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) { + case EXTRAPOLATION_NONE: { + return baseSpeed; + } + case EXTRAPOLATION_LINEAR: { + return baseSpeed + speed; + } + case EXTRAPOLATION_ACCELLINEAR: { + deltaTime = ( time - startTime ) / duration; + s = deltaTime; + return baseSpeed + s * speed; + } + case EXTRAPOLATION_DECELLINEAR: { + deltaTime = ( time - startTime ) / duration; + s = 1.0f - deltaTime; + return baseSpeed + s * speed; + } + case EXTRAPOLATION_ACCELSINE: { + deltaTime = ( time - startTime ) / duration; + s = idMath::Sin( deltaTime * idMath::HALF_PI ); + return baseSpeed + s * speed; + } + case EXTRAPOLATION_DECELSINE: { + deltaTime = ( time - startTime ) / duration; + s = idMath::Cos( deltaTime * idMath::HALF_PI ); + return baseSpeed + s * speed; + } + default: { + return baseSpeed; + } + } +} + +#endif /* !__MATH_EXTRAPOLATE_H__ */ diff --git a/idlib/math/Interpolate.h b/idlib/math/Interpolate.h new file mode 100644 index 000000000..cd7f44dca --- /dev/null +++ b/idlib/math/Interpolate.h @@ -0,0 +1,416 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_INTERPOLATE_H__ +#define __MATH_INTERPOLATE_H__ + +/* +============================================================================================== + + Linear interpolation. + +============================================================================================== +*/ + +template< class type > +class idInterpolate { +public: + idInterpolate(); + + // Start a transition, this automatically sets the idInterpolate to "enabled" + void Init( const float startTime, const float duration, const type &startValue, const type &endValue ); + void SetStartTime( float time ) { this->startTime = time; } + void SetDuration( float duration ) { this->duration = duration; } + void SetStartValue( const type &startValue ) { this->startValue = startValue; } + void SetEndValue( const type &endValue ) { this->endValue = endValue; } + + type GetCurrentValue( float time ) const; + bool IsDone( float time ) const { return ( time >= startTime + duration ); } + + float GetStartTime( void ) const { return startTime; } + float GetEndTime( void ) const { return startTime + duration; } + float GetDuration( void ) const { return duration; } + const type & GetStartValue( void ) const { return startValue; } + const type & GetEndValue( void ) const { return endValue; } + + // greebo: Returns TRUE if this interpolation is active. + inline bool Enabled() const { return enabled; }; + void SetEnabled(bool isEnabled) { enabled = isEnabled; }; + +private: + bool enabled; + float startTime; + float duration; + type startValue; + type endValue; + mutable float currentTime; + mutable type currentValue; +}; + +/* +==================== +idInterpolate::idInterpolate +==================== +*/ +template< class type > +ID_INLINE idInterpolate::idInterpolate() : + enabled(true) +{ + currentTime = startTime = duration = 0; + memset( ¤tValue, 0, sizeof( currentValue ) ); + startValue = endValue = currentValue; +} + +/* +==================== +idInterpolate::Init +==================== +*/ +template< class type > +ID_INLINE void idInterpolate::Init( const float startTime, const float duration, const type &startValue, const type &endValue ) { + this->startTime = startTime; + this->duration = duration; + this->startValue = startValue; + this->endValue = endValue; + this->currentTime = startTime - 1; + this->currentValue = startValue; + this->enabled = true; +} + +/* +==================== +idInterpolate::GetCurrentValue +==================== +*/ +template< class type > +ID_INLINE type idInterpolate::GetCurrentValue( float time ) const { + float deltaTime; + + deltaTime = time - startTime; + if ( time != currentTime ) { + currentTime = time; + if ( deltaTime <= 0 ) { + currentValue = startValue; + } else if ( deltaTime >= duration ) { + currentValue = endValue; + } else { + currentValue = static_cast(startValue + ( endValue - startValue ) * ( (float) deltaTime / duration )); + } + } + return currentValue; +} + +/* +============================================================================================== + + Continuous interpolation with linear acceleration and deceleration phase. + The velocity is continuous but the acceleration is not. + +============================================================================================== +*/ + +template< class type > +class idInterpolateAccelDecelLinear { +public: + idInterpolateAccelDecelLinear(); + + void Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ); + void SetStartTime( float time ) { startTime = time; Invalidate(); } + void SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); } + void SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); } + + type GetCurrentValue( float time ) const; + type GetCurrentSpeed( float time ) const; + bool IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); } + + float GetStartTime( void ) const { return startTime; } + float GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; } + float GetDuration( void ) const { return accelTime + linearTime + decelTime; } + float GetAcceleration( void ) const { return accelTime; } + float GetDeceleration( void ) const { return decelTime; } + const type & GetStartValue( void ) const { return startValue; } + const type & GetEndValue( void ) const { return endValue; } + +private: + float startTime; + float accelTime; + float linearTime; + float decelTime; + type startValue; + type endValue; + mutable idExtrapolate extrapolate; + + void Invalidate( void ); + void SetPhase( float time ) const; +}; + +/* +==================== +idInterpolateAccelDecelLinear::idInterpolateAccelDecelLinear +==================== +*/ +template< class type > +ID_INLINE idInterpolateAccelDecelLinear::idInterpolateAccelDecelLinear() { + startTime = accelTime = linearTime = decelTime = 0; + memset( &startValue, 0, sizeof( startValue ) ); + endValue = startValue; +} + +/* +==================== +idInterpolateAccelDecelLinear::Init +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelLinear::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) { + type speed; + + this->startTime = startTime; + this->accelTime = accelTime; + this->decelTime = decelTime; + this->startValue = startValue; + this->endValue = endValue; + + if ( duration <= 0.0f ) { + return; + } + + if ( this->accelTime + this->decelTime > duration ) { + this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime ); + this->decelTime = duration - this->accelTime; + } + this->linearTime = duration - this->accelTime - this->decelTime; + speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * 0.5f ) ); + + if ( this->accelTime ) { + extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELLINEAR ); + } else if ( this->linearTime ) { + extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR ); + } else { + extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELLINEAR ); + } +} + +/* +==================== +idInterpolateAccelDecelLinear::Invalidate +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelLinear::Invalidate( void ) { + extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE ); +} + +/* +==================== +idInterpolateAccelDecelLinear::SetPhase +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelLinear::SetPhase( float time ) const { + float deltaTime; + + deltaTime = time - startTime; + if ( deltaTime < accelTime ) { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELLINEAR ) { + extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELLINEAR ); + } + } else if ( deltaTime < accelTime + linearTime ) { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) { + extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * 0.5f ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR ); + } + } else { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELLINEAR ) { + extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * 0.5f ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELLINEAR ); + } + } +} + +/* +==================== +idInterpolateAccelDecelLinear::GetCurrentValue +==================== +*/ +template< class type > +ID_INLINE type idInterpolateAccelDecelLinear::GetCurrentValue( float time ) const { + SetPhase( time ); + return extrapolate.GetCurrentValue( time ); +} + +/* +==================== +idInterpolateAccelDecelLinear::GetCurrentSpeed +==================== +*/ +template< class type > +ID_INLINE type idInterpolateAccelDecelLinear::GetCurrentSpeed( float time ) const { + SetPhase( time ); + return extrapolate.GetCurrentSpeed( time ); +} + + +/* +============================================================================================== + + Continuous interpolation with sinusoidal acceleration and deceleration phase. + Both the velocity and acceleration are continuous. + +============================================================================================== +*/ + +template< class type > +class idInterpolateAccelDecelSine { +public: + idInterpolateAccelDecelSine(); + + void Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ); + void SetStartTime( float time ) { startTime = time; Invalidate(); } + void SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); } + void SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); } + + type GetCurrentValue( float time ) const; + type GetCurrentSpeed( float time ) const; + bool IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); } + + float GetStartTime( void ) const { return startTime; } + float GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; } + float GetDuration( void ) const { return accelTime + linearTime + decelTime; } + float GetAcceleration( void ) const { return accelTime; } + float GetDeceleration( void ) const { return decelTime; } + const type & GetStartValue( void ) const { return startValue; } + const type & GetEndValue( void ) const { return endValue; } + +private: + float startTime; + float accelTime; + float linearTime; + float decelTime; + type startValue; + type endValue; + mutable idExtrapolate extrapolate; + + void Invalidate( void ); + void SetPhase( float time ) const; +}; + +/* +==================== +idInterpolateAccelDecelSine::idInterpolateAccelDecelSine +==================== +*/ +template< class type > +ID_INLINE idInterpolateAccelDecelSine::idInterpolateAccelDecelSine() { + startTime = accelTime = linearTime = decelTime = 0; + memset( &startValue, 0, sizeof( startValue ) ); + endValue = startValue; +} + +/* +==================== +idInterpolateAccelDecelSine::Init +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelSine::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) { + type speed; + + this->startTime = startTime; + this->accelTime = accelTime; + this->decelTime = decelTime; + this->startValue = startValue; + this->endValue = endValue; + + if ( duration <= 0.0f ) { + return; + } + + if ( this->accelTime + this->decelTime > duration ) { + this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime ); + this->decelTime = duration - this->accelTime; + } + this->linearTime = duration - this->accelTime - this->decelTime; + speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * idMath::SQRT_1OVER2 ) ); + + if ( this->accelTime ) { + extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELSINE ); + } else if ( this->linearTime ) { + extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR ); + } else { + extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELSINE ); + } +} + +/* +==================== +idInterpolateAccelDecelSine::Invalidate +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelSine::Invalidate( void ) { + extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE ); +} + +/* +==================== +idInterpolateAccelDecelSine::SetPhase +==================== +*/ +template< class type > +ID_INLINE void idInterpolateAccelDecelSine::SetPhase( float time ) const { + float deltaTime; + + deltaTime = time - startTime; + if ( deltaTime < accelTime ) { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELSINE ) { + extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELSINE ); + } + } else if ( deltaTime < accelTime + linearTime ) { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) { + extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * idMath::SQRT_1OVER2 ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR ); + } + } else { + if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELSINE ) { + extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * idMath::SQRT_1OVER2 ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELSINE ); + } + } +} + +/* +==================== +idInterpolateAccelDecelSine::GetCurrentValue +==================== +*/ +template< class type > +ID_INLINE type idInterpolateAccelDecelSine::GetCurrentValue( float time ) const { + SetPhase( time ); + return extrapolate.GetCurrentValue( time ); +} + +/* +==================== +idInterpolateAccelDecelSine::GetCurrentSpeed +==================== +*/ +template< class type > +ID_INLINE type idInterpolateAccelDecelSine::GetCurrentSpeed( float time ) const { + SetPhase( time ); + return extrapolate.GetCurrentSpeed( time ); +} + +#endif /* !__MATH_INTERPOLATE_H__ */ diff --git a/idlib/math/Lcp.cpp b/idlib/math/Lcp.cpp new file mode 100644 index 000000000..e6e1b9ecc --- /dev/null +++ b/idlib/math/Lcp.cpp @@ -0,0 +1,1635 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +static idCVar lcp_showFailures( "lcp_showFailures", "0", CVAR_SYSTEM | CVAR_BOOL, "show LCP solver failures" ); + +const float LCP_BOUND_EPSILON = 1e-5f; +const float LCP_ACCEL_EPSILON = 1e-5f; +const float LCP_DELTA_ACCEL_EPSILON = 1e-9f; +const float LCP_DELTA_FORCE_EPSILON = 1e-9f; + +#define IGNORE_UNSATISFIABLE_VARIABLES + +//=============================================================== +// M +// idLCP_Square MrE +// E +//=============================================================== + +class idLCP_Square : public idLCP { +public: + virtual bool Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ); + +private: + idMatX m; // original matrix + idVecX b; // right hand side + idVecX lo, hi; // low and high bounds + idVecX f, a; // force and acceleration + idVecX delta_f, delta_a; // delta force and delta acceleration + idMatX clamped; // LU factored sub matrix for clamped variables + idVecX diagonal; // reciprocal of diagonal of U of the LU factored sub matrix for clamped variables + int numUnbounded; // number of unbounded variables + int numClamped; // number of clamped variables + float ** rowPtrs; // pointers to the rows of m + int * boxIndex; // box index + int * side; // tells if a variable is at the low boundary = -1, high boundary = 1 or inbetween = 0 + int * permuted; // index to keep track of the permutation + bool padded; // set to true if the rows of the initial matrix are 16 byte padded + +private: + bool FactorClamped( void ); + void SolveClamped( idVecX &x, const float *b ); + void Swap( int i, int j ); + void AddClamped( int r ); + void RemoveClamped( int r ); + void CalcForceDelta( int d, float dir ); + void CalcAccelDelta( int d ); + void ChangeForce( int d, float step ); + void ChangeAccel( int d, float step ); + void GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const; +}; + +/* +============ +idLCP_Square::FactorClamped +============ +*/ +bool idLCP_Square::FactorClamped( void ) { + int i, j, k; + float s, d; + + for ( i = 0; i < numClamped; i++ ) { + memcpy( clamped[i], rowPtrs[i], numClamped * sizeof( float ) ); + } + + for ( i = 0; i < numClamped; i++ ) { + + s = idMath::Fabs( clamped[i][i] ); + + if ( s == 0.0f ) { + return false; + } + + diagonal[i] = d = 1.0f / clamped[i][i]; + for ( j = i + 1; j < numClamped; j++ ) { + clamped[j][i] *= d; + } + + for ( j = i + 1; j < numClamped; j++ ) { + d = clamped[j][i]; + for ( k = i + 1; k < numClamped; k++ ) { + clamped[j][k] -= d * clamped[i][k]; + } + } + } + + return true; +} + +/* +============ +idLCP_Square::SolveClamped +============ +*/ +void idLCP_Square::SolveClamped( idVecX &x, const float *b ) { + int i, j; + float sum; + + // solve L + for ( i = 0; i < numClamped; i++ ) { + sum = b[i]; + for ( j = 0; j < i; j++ ) { + sum -= clamped[i][j] * x[j]; + } + x[i] = sum; + } + + // solve U + for ( i = numClamped - 1; i >= 0; i-- ) { + sum = x[i]; + for ( j = i + 1; j < numClamped; j++ ) { + sum -= clamped[i][j] * x[j]; + } + x[i] = sum * diagonal[i]; + } +} + +/* +============ +idLCP_Square::Swap +============ +*/ +void idLCP_Square::Swap( int i, int j ) { + + if ( i == j ) { + return; + } + + idSwap( rowPtrs[i], rowPtrs[j] ); + m.SwapColumns( i, j ); + b.SwapElements( i, j ); + lo.SwapElements( i, j ); + hi.SwapElements( i, j ); + a.SwapElements( i, j ); + f.SwapElements( i, j ); + if ( boxIndex ) { + idSwap( boxIndex[i], boxIndex[j] ); + } + idSwap( side[i], side[j] ); + idSwap( permuted[i], permuted[j] ); +} + +/* +============ +idLCP_Square::AddClamped +============ +*/ +void idLCP_Square::AddClamped( int r ) { + int i, j; + float sum; + + assert( r >= numClamped ); + + // add a row at the bottom and a column at the right of the factored + // matrix for the clamped variables + + Swap( numClamped, r ); + + // add row to L + for ( i = 0; i < numClamped; i++ ) { + sum = rowPtrs[numClamped][i]; + for ( j = 0; j < i; j++ ) { + sum -= clamped[numClamped][j] * clamped[j][i]; + } + clamped[numClamped][i] = sum * diagonal[i]; + } + + // add column to U + for ( i = 0; i <= numClamped; i++ ) { + sum = rowPtrs[i][numClamped]; + for ( j = 0; j < i; j++ ) { + sum -= clamped[i][j] * clamped[j][numClamped]; + } + clamped[i][numClamped] = sum; + } + + diagonal[numClamped] = 1.0f / clamped[numClamped][numClamped]; + + numClamped++; +} + +/* +============ +idLCP_Square::RemoveClamped +============ +*/ +void idLCP_Square::RemoveClamped( int r ) { + int i, j; + float *y0, *y1, *z0, *z1; + double diag, beta0, beta1, p0, p1, q0, q1, d; + + assert( r < numClamped ); + + numClamped--; + + // no need to swap and update the factored matrix when the last row and column are removed + if ( r == numClamped ) { + return; + } + + y0 = (float *) _alloca16( numClamped * sizeof( float ) ); + z0 = (float *) _alloca16( numClamped * sizeof( float ) ); + y1 = (float *) _alloca16( numClamped * sizeof( float ) ); + z1 = (float *) _alloca16( numClamped * sizeof( float ) ); + + // the row/column need to be subtracted from the factorization + for ( i = 0; i < numClamped; i++ ) { + y0[i] = -rowPtrs[i][r]; + } + + memset( y1, 0, numClamped * sizeof( float ) ); + y1[r] = 1.0f; + + memset( z0, 0, numClamped * sizeof( float ) ); + z0[r] = 1.0f; + + for ( i = 0; i < numClamped; i++ ) { + z1[i] = -rowPtrs[r][i]; + } + + // swap the to be removed row/column with the last row/column + Swap( r, numClamped ); + + // the swapped last row/column need to be added to the factorization + for ( i = 0; i < numClamped; i++ ) { + y0[i] += rowPtrs[i][r]; + } + + for ( i = 0; i < numClamped; i++ ) { + z1[i] += rowPtrs[r][i]; + } + z1[r] = 0.0f; + + // update the beginning of the to be updated row and column + for ( i = 0; i < r; i++ ) { + p0 = y0[i]; + beta1 = z1[i] * diagonal[i]; + + clamped[i][r] += p0; + for ( j = i+1; j < numClamped; j++ ) { + z1[j] -= beta1 * clamped[i][j]; + } + for ( j = i+1; j < numClamped; j++ ) { + y0[j] -= p0 * clamped[j][i]; + } + clamped[r][i] += beta1; + } + + // update the lower right corner starting at r,r + for ( i = r; i < numClamped; i++ ) { + diag = clamped[i][i]; + + p0 = y0[i]; + p1 = z0[i]; + diag += p0 * p1; + + if ( diag == 0.0f ) { + idLib::common->Printf( "idLCP_Square::RemoveClamped: updating factorization failed\n" ); + return; + } + + beta0 = p1 / diag; + + q0 = y1[i]; + q1 = z1[i]; + diag += q0 * q1; + + if ( diag == 0.0f ) { + idLib::common->Printf( "idLCP_Square::RemoveClamped: updating factorization failed\n" ); + return; + } + + d = 1.0f / diag; + beta1 = q1 * d; + + clamped[i][i] = diag; + diagonal[i] = d; + + for ( j = i+1; j < numClamped; j++ ) { + + d = clamped[i][j]; + + d += p0 * z0[j]; + z0[j] -= beta0 * d; + + d += q0 * z1[j]; + z1[j] -= beta1 * d; + + clamped[i][j] = d; + } + + for ( j = i+1; j < numClamped; j++ ) { + + d = clamped[j][i]; + + y0[j] -= p0 * d; + d += beta0 * y0[j]; + + y1[j] -= q0 * d; + d += beta1 * y1[j]; + + clamped[j][i] = d; + } + } + return; +} + +/* +============ +idLCP_Square::CalcForceDelta + + modifies this->delta_f +============ +*/ +ID_INLINE void idLCP_Square::CalcForceDelta( int d, float dir ) { + int i; + float *ptr; + + delta_f[d] = dir; + + if ( numClamped == 0 ) { + return; + } + + // get column d of matrix + ptr = (float *) _alloca16( numClamped * sizeof( float ) ); + for ( i = 0; i < numClamped; i++ ) { + ptr[i] = rowPtrs[i][d]; + } + + // solve force delta + SolveClamped( delta_f, ptr ); + + // flip force delta based on direction + if ( dir > 0.0f ) { + ptr = delta_f.ToFloatPtr(); + for ( i = 0; i < numClamped; i++ ) { + ptr[i] = - ptr[i]; + } + } +} + +/* +============ +idLCP_Square::CalcAccelDelta + + modifies this->delta_a and uses this->delta_f +============ +*/ +ID_INLINE void idLCP_Square::CalcAccelDelta( int d ) { + int j; + float dot; + + // only the not clamped variables, including the current variable, can have a change in acceleration + for ( j = numClamped; j <= d; j++ ) { + // only the clamped variables and the current variable have a force delta unequal zero + SIMDProcessor->Dot( dot, rowPtrs[j], delta_f.ToFloatPtr(), numClamped ); + delta_a[j] = dot + rowPtrs[j][d] * delta_f[d]; + } +} + +/* +============ +idLCP_Square::ChangeForce + + modifies this->f and uses this->delta_f +============ +*/ +ID_INLINE void idLCP_Square::ChangeForce( int d, float step ) { + // only the clamped variables and current variable have a force delta unequal zero + SIMDProcessor->MulAdd( f.ToFloatPtr(), step, delta_f.ToFloatPtr(), numClamped ); + f[d] += step * delta_f[d]; +} + +/* +============ +idLCP_Square::ChangeAccel + + modifies this->a and uses this->delta_a +============ +*/ +ID_INLINE void idLCP_Square::ChangeAccel( int d, float step ) { + // only the not clamped variables, including the current variable, can have an acceleration unequal zero + SIMDProcessor->MulAdd( a.ToFloatPtr() + numClamped, step, delta_a.ToFloatPtr() + numClamped, d - numClamped + 1 ); +} + +/* +============ +idLCP_Square::GetMaxStep +============ +*/ +void idLCP_Square::GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const { + int i; + float s; + + // default to a full step for the current variable + if ( idMath::Fabs( delta_a[d] ) > LCP_DELTA_ACCEL_EPSILON ) { + maxStep = -a[d] / delta_a[d]; + } else { + maxStep = 0.0f; + } + limit = d; + limitSide = 0; + + // test the current variable + if ( dir < 0.0f ) { + if ( lo[d] != -idMath::INFINITY ) { + s = ( lo[d] - f[d] ) / dir; + if ( s < maxStep ) { + maxStep = s; + limitSide = -1; + } + } + } else { + if ( hi[d] != idMath::INFINITY ) { + s = ( hi[d] - f[d] ) / dir; + if ( s < maxStep ) { + maxStep = s; + limitSide = 1; + } + } + } + + // test the clamped bounded variables + for ( i = numUnbounded; i < numClamped; i++ ) { + if ( delta_f[i] < -LCP_DELTA_FORCE_EPSILON ) { + // if there is a low boundary + if ( lo[i] != -idMath::INFINITY ) { + s = ( lo[i] - f[i] ) / delta_f[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = -1; + } + } + } else if ( delta_f[i] > LCP_DELTA_FORCE_EPSILON ) { + // if there is a high boundary + if ( hi[i] != idMath::INFINITY ) { + s = ( hi[i] - f[i] ) / delta_f[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = 1; + } + } + } + } + + // test the not clamped bounded variables + for ( i = numClamped; i < d; i++ ) { + if ( side[i] == -1 ) { + if ( delta_a[i] >= -LCP_DELTA_ACCEL_EPSILON ) { + continue; + } + } else if ( side[i] == 1 ) { + if ( delta_a[i] <= LCP_DELTA_ACCEL_EPSILON ) { + continue; + } + } else { + continue; + } + // ignore variables for which the force is not allowed to take any substantial value + if ( lo[i] >= -LCP_BOUND_EPSILON && hi[i] <= LCP_BOUND_EPSILON ) { + continue; + } + s = -a[i] / delta_a[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = 0; + } + } +} + +/* +============ +idLCP_Square::Solve +============ +*/ +bool idLCP_Square::Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ) { + int i, j, n, limit, limitSide, boxStartIndex; + float dir, maxStep, dot, s; + char *failed; + + // true when the matrix rows are 16 byte padded + padded = ((o_m.GetNumRows()+3)&~3) == o_m.GetNumColumns(); + + assert( padded || o_m.GetNumRows() == o_m.GetNumColumns() ); + assert( o_x.GetSize() == o_m.GetNumRows() ); + assert( o_b.GetSize() == o_m.GetNumRows() ); + assert( o_lo.GetSize() == o_m.GetNumRows() ); + assert( o_hi.GetSize() == o_m.GetNumRows() ); + + // allocate memory for permuted input + f.SetData( o_m.GetNumRows(), VECX_ALLOCA( o_m.GetNumRows() ) ); + a.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); + b.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); + lo.SetData( o_lo.GetSize(), VECX_ALLOCA( o_lo.GetSize() ) ); + hi.SetData( o_hi.GetSize(), VECX_ALLOCA( o_hi.GetSize() ) ); + if ( o_boxIndex ) { + boxIndex = (int *)_alloca16( o_x.GetSize() * sizeof( int ) ); + memcpy( boxIndex, o_boxIndex, o_x.GetSize() * sizeof( int ) ); + } else { + boxIndex = NULL; + } + + // we override the const on o_m here but on exit the matrix is unchanged + m.SetData( o_m.GetNumRows(), o_m.GetNumColumns(), const_cast(o_m[0]) ); + f.Zero(); + a.Zero(); + b = o_b; + lo = o_lo; + hi = o_hi; + + // pointers to the rows of m + rowPtrs = (float **) _alloca16( m.GetNumRows() * sizeof( float * ) ); + for ( i = 0; i < m.GetNumRows(); i++ ) { + rowPtrs[i] = m[i]; + } + + // tells if a variable is at the low boundary, high boundary or inbetween + side = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); + + // index to keep track of the permutation + permuted = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); + for ( i = 0; i < m.GetNumRows(); i++ ) { + permuted[i] = i; + } + + // permute input so all unbounded variables come first + numUnbounded = 0; + for ( i = 0; i < m.GetNumRows(); i++ ) { + if ( lo[i] == -idMath::INFINITY && hi[i] == idMath::INFINITY ) { + if ( numUnbounded != i ) { + Swap( numUnbounded, i ); + } + numUnbounded++; + } + } + + // permute input so all variables using the boxIndex come last + boxStartIndex = m.GetNumRows(); + if ( boxIndex ) { + for ( i = m.GetNumRows() - 1; i >= numUnbounded; i-- ) { + if ( boxIndex[i] >= 0 && ( lo[i] != -idMath::INFINITY || hi[i] != idMath::INFINITY ) ) { + boxStartIndex--; + if ( boxStartIndex != i ) { + Swap( boxStartIndex, i ); + } + } + } + } + + // sub matrix for factorization + clamped.SetData( m.GetNumRows(), m.GetNumColumns(), MATX_ALLOCA( m.GetNumRows() * m.GetNumColumns() ) ); + diagonal.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + + // all unbounded variables are clamped + numClamped = numUnbounded; + + // if there are unbounded variables + if ( numUnbounded ) { + + // factor and solve for unbounded variables + if ( !FactorClamped() ) { + idLib::common->Printf( "idLCP_Square::Solve: unbounded factorization failed\n" ); + return false; + } + SolveClamped( f, b.ToFloatPtr() ); + + // if there are no bounded variables we are done + if ( numUnbounded == m.GetNumRows() ) { + o_x = f; // the vector is not permuted + return true; + } + } + +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + int numIgnored = 0; +#endif + + // allocate for delta force and delta acceleration + delta_f.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + delta_a.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + + // solve for bounded variables + failed = NULL; + for ( i = numUnbounded; i < m.GetNumRows(); i++ ) { + + // once we hit the box start index we can initialize the low and high boundaries of the variables using the box index + if ( i == boxStartIndex ) { + for ( j = 0; j < boxStartIndex; j++ ) { + o_x[permuted[j]] = f[j]; + } + for ( j = boxStartIndex; j < m.GetNumRows(); j++ ) { + s = o_x[boxIndex[j]]; + if ( lo[j] != -idMath::INFINITY ) { + lo[j] = - idMath::Fabs( lo[j] * s ); + } + if ( hi[j] != idMath::INFINITY ) { + hi[j] = idMath::Fabs( hi[j] * s ); + } + } + } + + // calculate acceleration for current variable + SIMDProcessor->Dot( dot, rowPtrs[i], f.ToFloatPtr(), i ); + a[i] = dot - b[i]; + + // if already at the low boundary + if ( lo[i] >= -LCP_BOUND_EPSILON && a[i] >= -LCP_ACCEL_EPSILON ) { + side[i] = -1; + continue; + } + + // if already at the high boundary + if ( hi[i] <= LCP_BOUND_EPSILON && a[i] <= LCP_ACCEL_EPSILON ) { + side[i] = 1; + continue; + } + + // if inside the clamped region + if ( idMath::Fabs( a[i] ) <= LCP_ACCEL_EPSILON ) { + side[i] = 0; + AddClamped( i ); + continue; + } + + // drive the current variable into a valid region + for ( n = 0; n < maxIterations; n++ ) { + + // direction to move + if ( a[i] <= 0.0f ) { + dir = 1.0f; + } else { + dir = -1.0f; + } + + // calculate force delta + CalcForceDelta( i, dir ); + + // calculate acceleration delta: delta_a = m * delta_f; + CalcAccelDelta( i ); + + // maximum step we can take + GetMaxStep( i, dir, maxStep, limit, limitSide ); + + if ( maxStep <= 0.0f ) { +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + // ignore the current variable completely + lo[i] = hi[i] = 0.0f; + f[i] = 0.0f; + side[i] = -1; + numIgnored++; +#else + failed = va( "invalid step size %.4f", maxStep ); +#endif + break; + } + + // change force + ChangeForce( i, maxStep ); + + // change acceleration + ChangeAccel( i, maxStep ); + + // clamp/unclamp the variable that limited this step + side[limit] = limitSide; + switch( limitSide ) { + case 0: { + a[limit] = 0.0f; + AddClamped( limit ); + break; + } + case -1: { + f[limit] = lo[limit]; + if ( limit != i ) { + RemoveClamped( limit ); + } + break; + } + case 1: { + f[limit] = hi[limit]; + if ( limit != i ) { + RemoveClamped( limit ); + } + break; + } + } + + // if the current variable limited the step we can continue with the next variable + if ( limit == i ) { + break; + } + } + + if ( n >= maxIterations ) { + failed = va( "max iterations %d", maxIterations ); + break; + } + + if ( failed ) { + break; + } + } + +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + if ( numIgnored ) { + if ( lcp_showFailures.GetBool() ) { + idLib::common->Printf( "idLCP_Symmetric::Solve: %d of %d bounded variables ignored\n", numIgnored, m.GetNumRows() - numUnbounded ); + } + } +#endif + + // if failed clear remaining forces + if ( failed ) { + if ( lcp_showFailures.GetBool() ) { + idLib::common->Printf( "idLCP_Square::Solve: %s (%d of %d bounded variables ignored)\n", failed, m.GetNumRows() - i, m.GetNumRows() - numUnbounded ); + } + for ( j = i; j < m.GetNumRows(); j++ ) { + f[j] = 0.0f; + } + } + +#if defined(_DEBUG) && 0 + if ( !failed ) { + // test whether or not the solution satisfies the complementarity conditions + for ( i = 0; i < m.GetNumRows(); i++ ) { + a[i] = -b[i]; + for ( j = 0; j < m.GetNumRows(); j++ ) { + a[i] += rowPtrs[i][j] * f[j]; + } + + if ( f[i] == lo[i] ) { + if ( lo[i] != hi[i] && a[i] < -LCP_ACCEL_EPSILON ) { + int bah1 = 1; + } + } else if ( f[i] == hi[i] ) { + if ( lo[i] != hi[i] && a[i] > LCP_ACCEL_EPSILON ) { + int bah2 = 1; + } + } else if ( f[i] < lo[i] || f[i] > hi[i] || idMath::Fabs( a[i] ) > 1.0f ) { + int bah3 = 1; + } + } + } +#endif + + // unpermute result + for ( i = 0; i < f.GetSize(); i++ ) { + o_x[permuted[i]] = f[i]; + } + + // unpermute original matrix + for ( i = 0; i < m.GetNumRows(); i++ ) { + for ( j = 0; j < m.GetNumRows(); j++ ) { + if ( permuted[j] == i ) { + break; + } + } + if ( i != j ) { + m.SwapColumns( i, j ); + idSwap( permuted[i], permuted[j] ); + } + } + + return true; +} + + +//=============================================================== +// M +// idLCP_Symmetric MrE +// E +//=============================================================== + +class idLCP_Symmetric : public idLCP { +public: + virtual bool Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ); + +private: + idMatX m; // original matrix + idVecX b; // right hand side + idVecX lo, hi; // low and high bounds + idVecX f, a; // force and acceleration + idVecX delta_f, delta_a; // delta force and delta acceleration + idMatX clamped; // LDLt factored sub matrix for clamped variables + idVecX diagonal; // reciprocal of diagonal of LDLt factored sub matrix for clamped variables + idVecX solveCache1; // intermediate result cached in SolveClamped + idVecX solveCache2; // " + int numUnbounded; // number of unbounded variables + int numClamped; // number of clamped variables + int clampedChangeStart; // lowest row/column changed in the clamped matrix during an iteration + float ** rowPtrs; // pointers to the rows of m + int * boxIndex; // box index + int * side; // tells if a variable is at the low boundary = -1, high boundary = 1 or inbetween = 0 + int * permuted; // index to keep track of the permutation + bool padded; // set to true if the rows of the initial matrix are 16 byte padded + +private: + bool FactorClamped( void ); + void SolveClamped( idVecX &x, const float *b ); + void Swap( int i, int j ); + void AddClamped( int r, bool useSolveCache ); + void RemoveClamped( int r ); + void CalcForceDelta( int d, float dir ); + void CalcAccelDelta( int d ); + void ChangeForce( int d, float step ); + void ChangeAccel( int d, float step ); + void GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const; +}; + +/* +============ +idLCP_Symmetric::FactorClamped +============ +*/ +bool idLCP_Symmetric::FactorClamped( void ) { + + clampedChangeStart = 0; + + for ( int i = 0; i < numClamped; i++ ) { + memcpy( clamped[i], rowPtrs[i], numClamped * sizeof( float ) ); + } + return SIMDProcessor->MatX_LDLTFactor( clamped, diagonal, numClamped ); +} + +/* +============ +idLCP_Symmetric::SolveClamped +============ +*/ +void idLCP_Symmetric::SolveClamped( idVecX &x, const float *b ) { + + // solve L + SIMDProcessor->MatX_LowerTriangularSolve( clamped, solveCache1.ToFloatPtr(), b, numClamped, clampedChangeStart ); + + // solve D + SIMDProcessor->Mul( solveCache2.ToFloatPtr(), solveCache1.ToFloatPtr(), diagonal.ToFloatPtr(), numClamped ); + + // solve Lt + SIMDProcessor->MatX_LowerTriangularSolveTranspose( clamped, x.ToFloatPtr(), solveCache2.ToFloatPtr(), numClamped ); + + clampedChangeStart = numClamped; +} + +/* +============ +idLCP_Symmetric::Swap +============ +*/ +void idLCP_Symmetric::Swap( int i, int j ) { + + if ( i == j ) { + return; + } + + idSwap( rowPtrs[i], rowPtrs[j] ); + m.SwapColumns( i, j ); + b.SwapElements( i, j ); + lo.SwapElements( i, j ); + hi.SwapElements( i, j ); + a.SwapElements( i, j ); + f.SwapElements( i, j ); + if ( boxIndex ) { + idSwap( boxIndex[i], boxIndex[j] ); + } + idSwap( side[i], side[j] ); + idSwap( permuted[i], permuted[j] ); +} + +/* +============ +idLCP_Symmetric::AddClamped +============ +*/ +void idLCP_Symmetric::AddClamped( int r, bool useSolveCache ) { + float d, dot; + + assert( r >= numClamped ); + + if ( numClamped < clampedChangeStart ) { + clampedChangeStart = numClamped; + } + + // add a row at the bottom and a column at the right of the factored + // matrix for the clamped variables + + Swap( numClamped, r ); + + // solve for v in L * v = rowPtr[numClamped] + if ( useSolveCache ) { + + // the lower triangular solve was cached in SolveClamped called by CalcForceDelta + memcpy( clamped[numClamped], solveCache2.ToFloatPtr(), numClamped * sizeof( float ) ); + // calculate row dot product + SIMDProcessor->Dot( dot, solveCache2.ToFloatPtr(), solveCache1.ToFloatPtr(), numClamped ); + + } else { + + float *v = (float *) _alloca16( numClamped * sizeof( float ) ); + + SIMDProcessor->MatX_LowerTriangularSolve( clamped, v, rowPtrs[numClamped], numClamped ); + // add bottom row to L + SIMDProcessor->Mul( clamped[numClamped], v, diagonal.ToFloatPtr(), numClamped ); + // calculate row dot product + SIMDProcessor->Dot( dot, clamped[numClamped], v, numClamped ); + } + + // update diagonal[numClamped] + d = rowPtrs[numClamped][numClamped] - dot; + + if ( d == 0.0f ) { + idLib::common->Printf( "idLCP_Symmetric::AddClamped: updating factorization failed\n" ); + numClamped++; + return; + } + + clamped[numClamped][numClamped] = d; + diagonal[numClamped] = 1.0f / d; + + numClamped++; +} + +/* +============ +idLCP_Symmetric::RemoveClamped +============ +*/ +void idLCP_Symmetric::RemoveClamped( int r ) { + int i, j, n; + float *addSub, *original, *v, *ptr, *v1, *v2, dot; + double sum, diag, newDiag, invNewDiag, p1, p2, alpha1, alpha2, beta1, beta2; + + assert( r < numClamped ); + + if ( r < clampedChangeStart ) { + clampedChangeStart = r; + } + + numClamped--; + + // no need to swap and update the factored matrix when the last row and column are removed + if ( r == numClamped ) { + return; + } + + // swap the to be removed row/column with the last row/column + Swap( r, numClamped ); + + // update the factored matrix + addSub = (float *) _alloca16( numClamped * sizeof( float ) ); + + if ( r == 0 ) { + + if ( numClamped == 1 ) { + diag = rowPtrs[0][0]; + if ( diag == 0.0f ) { + idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); + return; + } + clamped[0][0] = diag; + diagonal[0] = 1.0f / diag; + return; + } + + // calculate the row/column to be added to the lower right sub matrix starting at (r, r) + original = rowPtrs[numClamped]; + ptr = rowPtrs[r]; + addSub[0] = ptr[0] - original[numClamped]; + for ( i = 1; i < numClamped; i++ ) { + addSub[i] = ptr[i] - original[i]; + } + + } else { + + v = (float *) _alloca16( numClamped * sizeof( float ) ); + + // solve for v in L * v = rowPtr[r] + SIMDProcessor->MatX_LowerTriangularSolve( clamped, v, rowPtrs[r], r ); + + // update removed row + SIMDProcessor->Mul( clamped[r], v, diagonal.ToFloatPtr(), r ); + + // if the last row/column of the matrix is updated + if ( r == numClamped - 1 ) { + // only calculate new diagonal + SIMDProcessor->Dot( dot, clamped[r], v, r ); + diag = rowPtrs[r][r] - dot; + if ( diag == 0.0f ) { + idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); + return; + } + clamped[r][r] = diag; + diagonal[r] = 1.0f / diag; + return; + } + + // calculate the row/column to be added to the lower right sub matrix starting at (r, r) + for ( i = 0; i < r; i++ ) { + v[i] = clamped[r][i] * clamped[i][i]; + } + for ( i = r; i < numClamped; i++ ) { + if ( i == r ) { + sum = clamped[r][r]; + } else { + sum = clamped[r][r] * clamped[i][r]; + } + ptr = clamped[i]; + for ( j = 0; j < r; j++ ) { + sum += ptr[j] * v[j]; + } + addSub[i] = rowPtrs[r][i] - sum; + } + } + + // add row/column to the lower right sub matrix starting at (r, r) + + v1 = (float *) _alloca16( numClamped * sizeof( float ) ); + v2 = (float *) _alloca16( numClamped * sizeof( float ) ); + + diag = idMath::SQRT_1OVER2; + v1[r] = ( 0.5f * addSub[r] + 1.0f ) * diag; + v2[r] = ( 0.5f * addSub[r] - 1.0f ) * diag; + for ( i = r+1; i < numClamped; i++ ) { + v1[i] = v2[i] = addSub[i] * diag; + } + + alpha1 = 1.0f; + alpha2 = -1.0f; + + // simultaneous update/downdate of the sub matrix starting at (r, r) + n = clamped.GetNumColumns(); + for ( i = r; i < numClamped; i++ ) { + + diag = clamped[i][i]; + p1 = v1[i]; + newDiag = diag + alpha1 * p1 * p1; + + if ( newDiag == 0.0f ) { + idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); + return; + } + + alpha1 /= newDiag; + beta1 = p1 * alpha1; + alpha1 *= diag; + + diag = newDiag; + p2 = v2[i]; + newDiag = diag + alpha2 * p2 * p2; + + if ( newDiag == 0.0f ) { + idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); + return; + } + + clamped[i][i] = newDiag; + diagonal[i] = invNewDiag = 1.0f / newDiag; + + alpha2 *= invNewDiag; + beta2 = p2 * alpha2; + alpha2 *= diag; + + // update column below diagonal (i,i) + ptr = clamped.ToFloatPtr() + i; + + for ( j = i+1; j < numClamped - 1; j += 2 ) { + + float sum0 = ptr[(j+0)*n]; + float sum1 = ptr[(j+1)*n]; + + v1[j+0] -= p1 * sum0; + v1[j+1] -= p1 * sum1; + + sum0 += beta1 * v1[j+0]; + sum1 += beta1 * v1[j+1]; + + v2[j+0] -= p2 * sum0; + v2[j+1] -= p2 * sum1; + + sum0 += beta2 * v2[j+0]; + sum1 += beta2 * v2[j+1]; + + ptr[(j+0)*n] = sum0; + ptr[(j+1)*n] = sum1; + } + + for ( ; j < numClamped; j++ ) { + + sum = ptr[j*n]; + + v1[j] -= p1 * sum; + sum += beta1 * v1[j]; + + v2[j] -= p2 * sum; + sum += beta2 * v2[j]; + + ptr[j*n] = sum; + } + } +} + +/* +============ +idLCP_Symmetric::CalcForceDelta + + modifies this->delta_f +============ +*/ +ID_INLINE void idLCP_Symmetric::CalcForceDelta( int d, float dir ) { + int i; + float *ptr; + + delta_f[d] = dir; + + if ( numClamped == 0 ) { + return; + } + + // solve force delta + SolveClamped( delta_f, rowPtrs[d] ); + + // flip force delta based on direction + if ( dir > 0.0f ) { + ptr = delta_f.ToFloatPtr(); + for ( i = 0; i < numClamped; i++ ) { + ptr[i] = - ptr[i]; + } + } +} + +/* +============ +idLCP_Symmetric::CalcAccelDelta + + modifies this->delta_a and uses this->delta_f +============ +*/ +ID_INLINE void idLCP_Symmetric::CalcAccelDelta( int d ) { + int j; + float dot; + + // only the not clamped variables, including the current variable, can have a change in acceleration + for ( j = numClamped; j <= d; j++ ) { + // only the clamped variables and the current variable have a force delta unequal zero + SIMDProcessor->Dot( dot, rowPtrs[j], delta_f.ToFloatPtr(), numClamped ); + delta_a[j] = dot + rowPtrs[j][d] * delta_f[d]; + } +} + +/* +============ +idLCP_Symmetric::ChangeForce + + modifies this->f and uses this->delta_f +============ +*/ +ID_INLINE void idLCP_Symmetric::ChangeForce( int d, float step ) { + // only the clamped variables and current variable have a force delta unequal zero + SIMDProcessor->MulAdd( f.ToFloatPtr(), step, delta_f.ToFloatPtr(), numClamped ); + f[d] += step * delta_f[d]; +} + +/* +============ +idLCP_Symmetric::ChangeAccel + + modifies this->a and uses this->delta_a +============ +*/ +ID_INLINE void idLCP_Symmetric::ChangeAccel( int d, float step ) { + // only the not clamped variables, including the current variable, can have an acceleration unequal zero + SIMDProcessor->MulAdd( a.ToFloatPtr() + numClamped, step, delta_a.ToFloatPtr() + numClamped, d - numClamped + 1 ); +} + +/* +============ +idLCP_Symmetric::GetMaxStep +============ +*/ +void idLCP_Symmetric::GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const { + int i; + float s; + + // default to a full step for the current variable + if ( idMath::Fabs( delta_a[d] ) > LCP_DELTA_ACCEL_EPSILON ) { + maxStep = -a[d] / delta_a[d]; + } else { + maxStep = 0.0f; + } + limit = d; + limitSide = 0; + + // test the current variable + if ( dir < 0.0f ) { + if ( lo[d] != -idMath::INFINITY ) { + s = ( lo[d] - f[d] ) / dir; + if ( s < maxStep ) { + maxStep = s; + limitSide = -1; + } + } + } else { + if ( hi[d] != idMath::INFINITY ) { + s = ( hi[d] - f[d] ) / dir; + if ( s < maxStep ) { + maxStep = s; + limitSide = 1; + } + } + } + + // test the clamped bounded variables + for ( i = numUnbounded; i < numClamped; i++ ) { + if ( delta_f[i] < -LCP_DELTA_FORCE_EPSILON ) { + // if there is a low boundary + if ( lo[i] != -idMath::INFINITY ) { + s = ( lo[i] - f[i] ) / delta_f[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = -1; + } + } + } else if ( delta_f[i] > LCP_DELTA_FORCE_EPSILON ) { + // if there is a high boundary + if ( hi[i] != idMath::INFINITY ) { + s = ( hi[i] - f[i] ) / delta_f[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = 1; + } + } + } + } + + // test the not clamped bounded variables + for ( i = numClamped; i < d; i++ ) { + if ( side[i] == -1 ) { + if ( delta_a[i] >= -LCP_DELTA_ACCEL_EPSILON ) { + continue; + } + } else if ( side[i] == 1 ) { + if ( delta_a[i] <= LCP_DELTA_ACCEL_EPSILON ) { + continue; + } + } else { + continue; + } + // ignore variables for which the force is not allowed to take any substantial value + if ( lo[i] >= -LCP_BOUND_EPSILON && hi[i] <= LCP_BOUND_EPSILON ) { + continue; + } + s = -a[i] / delta_a[i]; + if ( s < maxStep ) { + maxStep = s; + limit = i; + limitSide = 0; + } + } +} + +/* +============ +idLCP_Symmetric::Solve +============ +*/ +bool idLCP_Symmetric::Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ) { + int i, j, n, limit, limitSide, boxStartIndex; + float dir, maxStep, dot, s; + char *failed; + + // true when the matrix rows are 16 byte padded + padded = ((o_m.GetNumRows()+3)&~3) == o_m.GetNumColumns(); + + assert( padded || o_m.GetNumRows() == o_m.GetNumColumns() ); + assert( o_x.GetSize() == o_m.GetNumRows() ); + assert( o_b.GetSize() == o_m.GetNumRows() ); + assert( o_lo.GetSize() == o_m.GetNumRows() ); + assert( o_hi.GetSize() == o_m.GetNumRows() ); + + // allocate memory for permuted input + f.SetData( o_m.GetNumRows(), VECX_ALLOCA( o_m.GetNumRows() ) ); + a.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); + b.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); + lo.SetData( o_lo.GetSize(), VECX_ALLOCA( o_lo.GetSize() ) ); + hi.SetData( o_hi.GetSize(), VECX_ALLOCA( o_hi.GetSize() ) ); + if ( o_boxIndex ) { + boxIndex = (int *)_alloca16( o_x.GetSize() * sizeof( int ) ); + memcpy( boxIndex, o_boxIndex, o_x.GetSize() * sizeof( int ) ); + } else { + boxIndex = NULL; + } + + // we override the const on o_m here but on exit the matrix is unchanged + m.SetData( o_m.GetNumRows(), o_m.GetNumColumns(), const_cast(o_m[0]) ); + f.Zero(); + a.Zero(); + b = o_b; + lo = o_lo; + hi = o_hi; + + // pointers to the rows of m + rowPtrs = (float **) _alloca16( m.GetNumRows() * sizeof( float * ) ); + for ( i = 0; i < m.GetNumRows(); i++ ) { + rowPtrs[i] = m[i]; + } + + // tells if a variable is at the low boundary, high boundary or inbetween + side = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); + + // index to keep track of the permutation + permuted = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); + for ( i = 0; i < m.GetNumRows(); i++ ) { + permuted[i] = i; + } + + // permute input so all unbounded variables come first + numUnbounded = 0; + for ( i = 0; i < m.GetNumRows(); i++ ) { + if ( lo[i] == -idMath::INFINITY && hi[i] == idMath::INFINITY ) { + if ( numUnbounded != i ) { + Swap( numUnbounded, i ); + } + numUnbounded++; + } + } + + // permute input so all variables using the boxIndex come last + boxStartIndex = m.GetNumRows(); + if ( boxIndex ) { + for ( i = m.GetNumRows() - 1; i >= numUnbounded; i-- ) { + if ( boxIndex[i] >= 0 && ( lo[i] != -idMath::INFINITY || hi[i] != idMath::INFINITY ) ) { + boxStartIndex--; + if ( boxStartIndex != i ) { + Swap( boxStartIndex, i ); + } + } + } + } + + // sub matrix for factorization + clamped.SetData( m.GetNumRows(), m.GetNumColumns(), MATX_ALLOCA( m.GetNumRows() * m.GetNumColumns() ) ); + diagonal.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + solveCache1.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + solveCache2.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + + // all unbounded variables are clamped + numClamped = numUnbounded; + + // if there are unbounded variables + if ( numUnbounded ) { + + // factor and solve for unbounded variables + if ( !FactorClamped() ) { + idLib::common->Printf( "idLCP_Symmetric::Solve: unbounded factorization failed\n" ); + return false; + } + SolveClamped( f, b.ToFloatPtr() ); + + // if there are no bounded variables we are done + if ( numUnbounded == m.GetNumRows() ) { + o_x = f; // the vector is not permuted + return true; + } + } + +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + int numIgnored = 0; +#endif + + // allocate for delta force and delta acceleration + delta_f.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + delta_a.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); + + // solve for bounded variables + failed = NULL; + for ( i = numUnbounded; i < m.GetNumRows(); i++ ) { + + clampedChangeStart = 0; + + // once we hit the box start index we can initialize the low and high boundaries of the variables using the box index + if ( i == boxStartIndex ) { + for ( j = 0; j < boxStartIndex; j++ ) { + o_x[permuted[j]] = f[j]; + } + for ( j = boxStartIndex; j < m.GetNumRows(); j++ ) { + s = o_x[boxIndex[j]]; + if ( lo[j] != -idMath::INFINITY ) { + lo[j] = - idMath::Fabs( lo[j] * s ); + } + if ( hi[j] != idMath::INFINITY ) { + hi[j] = idMath::Fabs( hi[j] * s ); + } + } + } + + // calculate acceleration for current variable + SIMDProcessor->Dot( dot, rowPtrs[i], f.ToFloatPtr(), i ); + a[i] = dot - b[i]; + + // if already at the low boundary + if ( lo[i] >= -LCP_BOUND_EPSILON && a[i] >= -LCP_ACCEL_EPSILON ) { + side[i] = -1; + continue; + } + + // if already at the high boundary + if ( hi[i] <= LCP_BOUND_EPSILON && a[i] <= LCP_ACCEL_EPSILON ) { + side[i] = 1; + continue; + } + + // if inside the clamped region + if ( idMath::Fabs( a[i] ) <= LCP_ACCEL_EPSILON ) { + side[i] = 0; + AddClamped( i, false ); + continue; + } + + // drive the current variable into a valid region + for ( n = 0; n < maxIterations; n++ ) { + + // direction to move + if ( a[i] <= 0.0f ) { + dir = 1.0f; + } else { + dir = -1.0f; + } + + // calculate force delta + CalcForceDelta( i, dir ); + + // calculate acceleration delta: delta_a = m * delta_f; + CalcAccelDelta( i ); + + // maximum step we can take + GetMaxStep( i, dir, maxStep, limit, limitSide ); + + if ( maxStep <= 0.0f ) { +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + // ignore the current variable completely + lo[i] = hi[i] = 0.0f; + f[i] = 0.0f; + side[i] = -1; + numIgnored++; +#else + failed = va( "invalid step size %.4f", maxStep ); +#endif + break; + } + + // change force + ChangeForce( i, maxStep ); + + // change acceleration + ChangeAccel( i, maxStep ); + + // clamp/unclamp the variable that limited this step + side[limit] = limitSide; + switch( limitSide ) { + case 0: { + a[limit] = 0.0f; + AddClamped( limit, ( limit == i ) ); + break; + } + case -1: { + f[limit] = lo[limit]; + if ( limit != i ) { + RemoveClamped( limit ); + } + break; + } + case 1: { + f[limit] = hi[limit]; + if ( limit != i ) { + RemoveClamped( limit ); + } + break; + } + } + + // if the current variable limited the step we can continue with the next variable + if ( limit == i ) { + break; + } + } + + if ( n >= maxIterations ) { + failed = va( "max iterations %d", maxIterations ); + break; + } + + if ( failed ) { + break; + } + } + +#ifdef IGNORE_UNSATISFIABLE_VARIABLES + if ( numIgnored ) { + if ( lcp_showFailures.GetBool() ) { + idLib::common->Printf( "idLCP_Symmetric::Solve: %d of %d bounded variables ignored\n", numIgnored, m.GetNumRows() - numUnbounded ); + } + } +#endif + + // if failed clear remaining forces + if ( failed ) { + if ( lcp_showFailures.GetBool() ) { + idLib::common->Printf( "idLCP_Symmetric::Solve: %s (%d of %d bounded variables ignored)\n", failed, m.GetNumRows() - i, m.GetNumRows() - numUnbounded ); + } + for ( j = i; j < m.GetNumRows(); j++ ) { + f[j] = 0.0f; + } + } + +#if defined(_DEBUG) && 0 + if ( !failed ) { + // test whether or not the solution satisfies the complementarity conditions + for ( i = 0; i < m.GetNumRows(); i++ ) { + a[i] = -b[i]; + for ( j = 0; j < m.GetNumRows(); j++ ) { + a[i] += rowPtrs[i][j] * f[j]; + } + + if ( f[i] == lo[i] ) { + if ( lo[i] != hi[i] && a[i] < -LCP_ACCEL_EPSILON ) { + int bah1 = 1; + } + } else if ( f[i] == hi[i] ) { + if ( lo[i] != hi[i] && a[i] > LCP_ACCEL_EPSILON ) { + int bah2 = 1; + } + } else if ( f[i] < lo[i] || f[i] > hi[i] || idMath::Fabs( a[i] ) > 1.0f ) { + int bah3 = 1; + } + } + } +#endif + + // unpermute result + for ( i = 0; i < f.GetSize(); i++ ) { + o_x[permuted[i]] = f[i]; + } + + // unpermute original matrix + for ( i = 0; i < m.GetNumRows(); i++ ) { + for ( j = 0; j < m.GetNumRows(); j++ ) { + if ( permuted[j] == i ) { + break; + } + } + if ( i != j ) { + m.SwapColumns( i, j ); + idSwap( permuted[i], permuted[j] ); + } + } + + return true; +} + + +//=============================================================== +// +// idLCP +// +//=============================================================== + +/* +============ +idLCP::AllocSquare +============ +*/ +idLCP *idLCP::AllocSquare( void ) { + idLCP *lcp = new idLCP_Square; + lcp->SetMaxIterations( 32 ); + return lcp; +} + +/* +============ +idLCP::AllocSymmetric +============ +*/ +idLCP *idLCP::AllocSymmetric( void ) { + idLCP *lcp = new idLCP_Symmetric; + lcp->SetMaxIterations( 32 ); + return lcp; +} + +/* +============ +idLCP::~idLCP +============ +*/ +idLCP::~idLCP( void ) { +} + +/* +============ +idLCP::SetMaxIterations +============ +*/ +void idLCP::SetMaxIterations( int max ) { + maxIterations = max; +} + +/* +============ +idLCP::GetMaxIterations +============ +*/ +int idLCP::GetMaxIterations( void ) { + return maxIterations; +} diff --git a/idlib/math/Lcp.h b/idlib/math/Lcp.h new file mode 100644 index 000000000..c180d9ed1 --- /dev/null +++ b/idlib/math/Lcp.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_LCP_H__ +#define __MATH_LCP_H__ + +/* +=============================================================================== + + Box Constrained Mixed Linear Complementarity Problem solver + + A is a matrix of dimension n*n and x, b, lo, hi are vectors of dimension n + + Solve: Ax = b + t, where t is a vector of dimension n, with + complementarity condition: (x[i] - lo[i]) * (x[i] - hi[i]) * t[i] = 0 + such that for each 0 <= i < n one of the following holds: + + 1. lo[i] < x[i] < hi[i], t[i] == 0 + 2. x[i] == lo[i], t[i] >= 0 + 3. x[i] == hi[i], t[i] <= 0 + + Partly bounded or unbounded variables can have lo[i] and/or hi[i] + set to negative/positive idMath::INFITITY respectively. + + If boxIndex != NULL and boxIndex[i] != -1 then + + lo[i] = - fabs( lo[i] * x[boxIndex[i]] ) + hi[i] = fabs( hi[i] * x[boxIndex[i]] ) + boxIndex[boxIndex[i]] must be -1 + + Before calculating any of the bounded x[i] with boxIndex[i] != -1 the + solver calculates all unbounded x[i] and all x[i] with boxIndex[i] == -1. + +=============================================================================== +*/ + +class idLCP { +public: + static idLCP * AllocSquare( void ); // A must be a square matrix + static idLCP * AllocSymmetric( void ); // A must be a symmetric matrix + + virtual ~idLCP( void ); + + virtual bool Solve( const idMatX &A, idVecX &x, const idVecX &b, const idVecX &lo, const idVecX &hi, const int *boxIndex = NULL ) = 0; + virtual void SetMaxIterations( int max ); + virtual int GetMaxIterations( void ); + +protected: + int maxIterations; +}; + +#endif /* !__MATH_LCP_H__ */ diff --git a/idlib/math/Math.cpp b/idlib/math/Math.cpp new file mode 100644 index 000000000..c8d9f45cb --- /dev/null +++ b/idlib/math/Math.cpp @@ -0,0 +1,122 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +const float idMath::PI = 3.14159265358979323846f; +const float idMath::TWO_PI = 2.0f * PI; +const float idMath::HALF_PI = 0.5f * PI; +const float idMath::ONEFOURTH_PI = 0.25f * PI; +const float idMath::E = 2.71828182845904523536f; +const float idMath::SQRT_TWO = 1.41421356237309504880f; +const float idMath::SQRT_THREE = 1.73205080756887729352f; +const float idMath::SQRT_1OVER2 = 0.70710678118654752440f; +const float idMath::SQRT_1OVER3 = 0.57735026918962576450f; +const float idMath::M_DEG2RAD = PI / 180.0f; +const float idMath::M_RAD2DEG = 180.0f / PI; +const float idMath::M_SEC2MS = 1000.0f; +const float idMath::M_MS2SEC = 0.001f; +const float idMath::INFINITY = 1e30f; +const float idMath::FLT_EPSILON = 1.192092896e-07f; + +bool idMath::initialized = false; +dword idMath::iSqrt[SQRT_TABLE_SIZE]; // inverse square root lookup table + +/* +=============== +idMath::Init +=============== +*/ +void idMath::Init( void ) { + union _flint fi, fo; + + for ( int i = 0; i < SQRT_TABLE_SIZE; i++ ) { + fi.i = ((EXP_BIAS-1) << EXP_POS) | (i << LOOKUP_POS); + fo.f = (float)( 1.0 / sqrt( fi.f ) ); + iSqrt[i] = ((dword)(((fo.i + (1<<(SEED_POS-2))) >> SEED_POS) & 0xFF))<= 2 && exponentBits <= 8 ); + assert( mantissaBits >= 2 && mantissaBits <= 23 ); + + int maxBits = ( ( ( 1 << ( exponentBits - 1 ) ) - 1 ) << mantissaBits ) | ( ( 1 << mantissaBits ) - 1 ); + int minBits = ( ( ( 1 << exponentBits ) - 2 ) << mantissaBits ) | 1; + + float max = BitsToFloat( maxBits, exponentBits, mantissaBits ); + float min = BitsToFloat( minBits, exponentBits, mantissaBits ); + + if ( f >= 0.0f ) { + if ( f >= max ) { + return maxBits; + } else if ( f <= min ) { + return minBits; + } + } else { + if ( f <= -max ) { + return ( maxBits | ( 1 << ( exponentBits + mantissaBits ) ) ); + } else if ( f >= -min ) { + return ( minBits | ( 1 << ( exponentBits + mantissaBits ) ) ); + } + } + + exponentBits--; + i = *reinterpret_cast(&f); + sign = ( i >> IEEE_FLT_SIGN_BIT ) & 1; + exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; + mantissa = i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ); + value = sign << ( 1 + exponentBits + mantissaBits ); + value |= ( ( INTSIGNBITSET( exponent ) << exponentBits ) | ( abs( exponent ) & ( ( 1 << exponentBits ) - 1 ) ) ) << mantissaBits; + value |= mantissa >> ( IEEE_FLT_MANTISSA_BITS - mantissaBits ); + return value; +} + +/* +================ +idMath::BitsToFloat +================ +*/ +float idMath::BitsToFloat( int i, int exponentBits, int mantissaBits ) { + static int exponentSign[2] = { 1, -1 }; + int sign, exponent, mantissa, value; + + assert( exponentBits >= 2 && exponentBits <= 8 ); + assert( mantissaBits >= 2 && mantissaBits <= 23 ); + + exponentBits--; + sign = i >> ( 1 + exponentBits + mantissaBits ); + exponent = ( ( i >> mantissaBits ) & ( ( 1 << exponentBits ) - 1 ) ) * exponentSign[( i >> ( exponentBits + mantissaBits ) ) & 1]; + mantissa = ( i & ( ( 1 << mantissaBits ) - 1 ) ) << ( IEEE_FLT_MANTISSA_BITS - mantissaBits ); + value = sign << IEEE_FLT_SIGN_BIT | ( exponent + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS | mantissa; + return *reinterpret_cast(&value); +} diff --git a/idlib/math/Math.h b/idlib/math/Math.h new file mode 100644 index 000000000..4b58778ef --- /dev/null +++ b/idlib/math/Math.h @@ -0,0 +1,935 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_MATH_H__ +#define __MATH_MATH_H__ + +#include +#include // before FLT_EPSILON is #undefined + +#ifdef __linux__ +#include "../../sys/sys_public.h" +#include +#endif + +#ifdef MACOS_X +// greebo: Include this for ID_INLINE +#include "../../sys/sys_public.h" + +// for square root estimate instruction +#include +// for FLT_MIN +#include +#endif +/* +=============================================================================== + + Math + +=============================================================================== +*/ + +#ifdef INFINITY +#undef INFINITY +#endif + +#ifdef FLT_EPSILON +#undef FLT_EPSILON +#endif + +#define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD ) +#define RAD2DEG(a) ( (a) * idMath::M_RAD2DEG ) + +#define SEC2MS(t) ( idMath::FtoiFast( (t) * idMath::M_SEC2MS ) ) +#define MS2SEC(t) ( (t) * idMath::M_MS2SEC ) + +#define ANGLE2SHORT(x) ( idMath::FtoiFast( (x) * 65536.0f / 360.0f ) & 65535 ) +#define SHORT2ANGLE(x) ( (x) * ( 360.0f / 65536.0f ) ) + +#define ANGLE2BYTE(x) ( idMath::FtoiFast( (x) * 256.0f / 360.0f ) & 255 ) +#define BYTE2ANGLE(x) ( (x) * ( 360.0f / 256.0f ) ) + +#define FLOATSIGNBITSET(f) ((*(const unsigned long *)&(f)) >> 31) +#define FLOATSIGNBITNOTSET(f) ((~(*(const unsigned long *)&(f))) >> 31) +#define FLOATNOTZERO(f) ((*(const unsigned long *)&(f)) & ~(1<<31) ) +#define INTSIGNBITSET(i) (((const unsigned long)(i)) >> 31) +#define INTSIGNBITNOTSET(i) ((~((const unsigned long)(i))) >> 31) + +#define FLOAT_IS_NAN(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x7f800000) +#define FLOAT_IS_INF(x) (((*(const unsigned long *)&x) & 0x7fffffff) == 0x7f800000) +#define FLOAT_IS_IND(x) ((*(const unsigned long *)&x) == 0xffc00000) +#define FLOAT_IS_DENORMAL(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x00000000 && \ + ((*(const unsigned long *)&x) & 0x007fffff) != 0x00000000 ) + +#define IEEE_FLT_MANTISSA_BITS 23 +#define IEEE_FLT_EXPONENT_BITS 8 +#define IEEE_FLT_EXPONENT_BIAS 127 +#define IEEE_FLT_SIGN_BIT 31 + +#define IEEE_DBL_MANTISSA_BITS 52 +#define IEEE_DBL_EXPONENT_BITS 11 +#define IEEE_DBL_EXPONENT_BIAS 1023 +#define IEEE_DBL_SIGN_BIT 63 + +#define IEEE_DBLE_MANTISSA_BITS 63 +#define IEEE_DBLE_EXPONENT_BITS 15 +#define IEEE_DBLE_EXPONENT_BIAS 0 +#define IEEE_DBLE_SIGN_BIT 79 + +template ID_INLINE T Max( T x, T y ) { return ( x > y ) ? x : y; } +template ID_INLINE T Min( T x, T y ) { return ( x < y ) ? x : y; } +template ID_INLINE int MaxIndex( T x, T y ) { return ( x > y ) ? 0 : 1; } +template ID_INLINE int MinIndex( T x, T y ) { return ( x < y ) ? 0 : 1; } + +template ID_INLINE T Max3( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? x : z ) : ( ( y > z ) ? y : z ); } +template ID_INLINE T Min3( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? x : z ) : ( ( y < z ) ? y : z ); } +template ID_INLINE int Max3Index( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? 0 : 2 ) : ( ( y > z ) ? 1 : 2 ); } +template ID_INLINE int Min3Index( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? 0 : 2 ) : ( ( y < z ) ? 1 : 2 ); } + +template ID_INLINE T Sign( T f ) { return ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ); } +template ID_INLINE T Square( T x ) { return x * x; } +template ID_INLINE T Cube( T x ) { return x * x * x; } + + +class idMath { +public: + + static void Init( void ); + + static float RSqrt( float x ); // reciprocal square root, returns huge number when x == 0.0 + + static float InvSqrt( float x ); // inverse square root with 32 bits precision, returns huge number when x == 0.0 + static float InvSqrt16( float x ); // inverse square root with 16 bits precision, returns huge number when x == 0.0 + static double InvSqrt64( float x ); // inverse square root with 64 bits precision, returns huge number when x == 0.0 + + static float Sqrt( float x ); // square root with 32 bits precision + static float Sqrt16( float x ); // square root with 16 bits precision + static double Sqrt64( float x ); // square root with 64 bits precision + + static float Sin( float a ); // sine with 32 bits precision + static float Sin16( float a ); // sine with 16 bits precision, maximum absolute error is 2.3082e-09 + static double Sin64( float a ); // sine with 64 bits precision + + static float Cos( float a ); // cosine with 32 bits precision + static float Cos16( float a ); // cosine with 16 bits precision, maximum absolute error is 2.3082e-09 + static double Cos64( float a ); // cosine with 64 bits precision + + static void SinCos( float a, float &s, float &c ); // sine and cosine with 32 bits precision + static void SinCos16( float a, float &s, float &c ); // sine and cosine with 16 bits precision + static void SinCos64( float a, double &s, double &c ); // sine and cosine with 64 bits precision + + static float Tan( float a ); // tangent with 32 bits precision + static float Tan16( float a ); // tangent with 16 bits precision, maximum absolute error is 1.8897e-08 + static double Tan64( float a ); // tangent with 64 bits precision + + static float ASin( float a ); // arc sine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN + static float ASin16( float a ); // arc sine with 16 bits precision, maximum absolute error is 6.7626e-05 + static double ASin64( float a ); // arc sine with 64 bits precision + + static float ACos( float a ); // arc cosine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN + static float ACos16( float a ); // arc cosine with 16 bits precision, maximum absolute error is 6.7626e-05 + static double ACos64( float a ); // arc cosine with 64 bits precision + + static float ATan( float a ); // arc tangent with 32 bits precision + static float ATan16( float a ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 + static double ATan64( float a ); // arc tangent with 64 bits precision + + static float ATan( float y, float x ); // arc tangent with 32 bits precision + static float ATan16( float y, float x ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 + static double ATan64( float y, float x ); // arc tangent with 64 bits precision + + static float Pow( float x, float y ); // x raised to the power y with 32 bits precision + static float Pow16( float x, float y ); // x raised to the power y with 16 bits precision + static double Pow64( float x, float y ); // x raised to the power y with 64 bits precision + + static float Exp( float f ); // e raised to the power f with 32 bits precision + static float Exp16( float f ); // e raised to the power f with 16 bits precision + static double Exp64( float f ); // e raised to the power f with 64 bits precision + + static float Log( float f ); // natural logarithm with 32 bits precision + static float Log16( float f ); // natural logarithm with 16 bits precision + static double Log64( float f ); // natural logarithm with 64 bits precision + + static int IPow( int x, int y ); // integral x raised to the power y + static int ILog2( float f ); // integral base-2 logarithm of the floating point value + static int ILog2( int i ); // integral base-2 logarithm of the integer value + + static int BitsForFloat( float f ); // minimum number of bits required to represent ceil( f ) + static int BitsForInteger( int i ); // minimum number of bits required to represent i + static int MaskForFloatSign( float f );// returns 0x00000000 if x >= 0.0f and returns 0xFFFFFFFF if x <= -0.0f + static int MaskForIntegerSign( int i );// returns 0x00000000 if x >= 0 and returns 0xFFFFFFFF if x < 0 + static int FloorPowerOfTwo( int x ); // round x down to the nearest power of 2 + static int CeilPowerOfTwo( int x ); // round x up to the nearest power of 2 + static bool IsPowerOfTwo( int x ); // returns true if x is a power of 2 + static int BitCount( int x ); // returns the number of 1 bits in x + static int BitReverse( int x ); // returns the bit reverse of x + + static int Abs( int x ); // returns the absolute value of the integer value (for reference only) + static float Fabs( float f ); // returns the absolute value of the floating point value + static float Floor( float f ); // returns the largest integer that is less than or equal to the given value + static float Ceil( float f ); // returns the smallest integer that is greater than or equal to the given value + static float Rint( float f ); // returns the nearest integer + static int Ftoi( float f ); // float to int conversion + static int FtoiFast( float f ); // fast float to int conversion but uses current FPU round mode (default round nearest) + static unsigned long Ftol( float f ); // float to long conversion + static unsigned long FtolFast( float ); // fast float to long conversion but uses current FPU round mode (default round nearest) + + static signed char ClampChar( int i ); + static signed short ClampShort( int i ); + static int ClampInt( int min, int max, int value ); + static float ClampFloat( float min, float max, float value ); + + static float AngleNormalize360( float angle ); + static float AngleNormalize180( float angle ); + static float AngleDelta( float angle1, float angle2 ); + + static int FloatToBits( float f, int exponentBits, int mantissaBits ); + static float BitsToFloat( int i, int exponentBits, int mantissaBits ); + + static int FloatHash( const float *array, const int numFloats ); + + static const float PI; // pi + static const float TWO_PI; // pi * 2 + static const float HALF_PI; // pi / 2 + static const float ONEFOURTH_PI; // pi / 4 + static const float E; // e + static const float SQRT_TWO; // sqrt( 2 ) + static const float SQRT_THREE; // sqrt( 3 ) + static const float SQRT_1OVER2; // sqrt( 1 / 2 ) + static const float SQRT_1OVER3; // sqrt( 1 / 3 ) + static const float M_DEG2RAD; // degrees to radians multiplier + static const float M_RAD2DEG; // radians to degrees multiplier + static const float M_SEC2MS; // seconds to milliseconds multiplier + static const float M_MS2SEC; // milliseconds to seconds multiplier + static const float INFINITY; // huge number which should be larger than any valid number used + static const float FLT_EPSILON; // smallest positive number such that 1.0+FLT_EPSILON != 1.0 + +private: + enum { + LOOKUP_BITS = 8, + EXP_POS = 23, + EXP_BIAS = 127, + LOOKUP_POS = (EXP_POS-LOOKUP_BITS), + SEED_POS = (EXP_POS-8), + SQRT_TABLE_SIZE = (2<( &x ); + i = 0x5f3759df - ( i >> 1 ); + r = *reinterpret_cast( &i ); + r = r * ( 1.5f - r * r * y ); + return r; +} + +ID_INLINE float idMath::InvSqrt16( float x ) { + + dword a = ((union _flint*)(&x))->i; + union _flint seed; + + assert( initialized ); + + double y = x * 0.5f; + seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; + double r = seed.f; + r = r * ( 1.5f - r * r * y ); + return (float) r; +} + +ID_INLINE float idMath::InvSqrt( float x ) { + + dword a = ((union _flint*)(&x))->i; + union _flint seed; + + assert( initialized ); + + double y = x * 0.5f; + seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; + double r = seed.f; + r = r * ( 1.5f - r * r * y ); + r = r * ( 1.5f - r * r * y ); + return (float) r; +} + +ID_INLINE double idMath::InvSqrt64( float x ) { + dword a = ((union _flint*)(&x))->i; + union _flint seed; + + assert( initialized ); + + double y = x * 0.5f; + seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; + double r = seed.f; + r = r * ( 1.5f - r * r * y ); + r = r * ( 1.5f - r * r * y ); + r = r * ( 1.5f - r * r * y ); + return r; +} + +ID_INLINE float idMath::Sqrt16( float x ) { + return x * InvSqrt16( x ); +} + +ID_INLINE float idMath::Sqrt( float x ) { + return x * InvSqrt( x ); +} + +ID_INLINE double idMath::Sqrt64( float x ) { + return x * InvSqrt64( x ); +} + +ID_INLINE float idMath::Sin( float a ) { + return sinf( a ); +} + +ID_INLINE float idMath::Sin16( float a ) { + float s; + + if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { + a -= floorf( a / TWO_PI ) * TWO_PI; + } +#if 1 + if ( a < PI ) { + if ( a > HALF_PI ) { + a = PI - a; + } + } else { + if ( a > PI + HALF_PI ) { + a = a - TWO_PI; + } else { + a = PI - a; + } + } +#else + a = PI - a; + if ( fabs( a ) >= HALF_PI ) { + a = ( ( a < 0.0f ) ? -PI : PI ) - a; + } +#endif + s = a * a; + return a * ( ( ( ( ( -2.39e-08f * s + 2.7526e-06f ) * s - 1.98409e-04f ) * s + 8.3333315e-03f ) * s - 1.666666664e-01f ) * s + 1.0f ); +} + +ID_INLINE double idMath::Sin64( float a ) { + return sin( a ); +} + +ID_INLINE float idMath::Cos( float a ) { + return cosf( a ); +} + +ID_INLINE float idMath::Cos16( float a ) { + float s, d; + + if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { + a -= floorf( a / TWO_PI ) * TWO_PI; + } +#if 1 + if ( a < PI ) { + if ( a > HALF_PI ) { + a = PI - a; + d = -1.0f; + } else { + d = 1.0f; + } + } else { + if ( a > PI + HALF_PI ) { + a = a - TWO_PI; + d = 1.0f; + } else { + a = PI - a; + d = -1.0f; + } + } +#else + a = PI - a; + if ( fabs( a ) >= HALF_PI ) { + a = ( ( a < 0.0f ) ? -PI : PI ) - a; + d = 1.0f; + } else { + d = -1.0f; + } +#endif + s = a * a; + return d * ( ( ( ( ( -2.605e-07f * s + 2.47609e-05f ) * s - 1.3888397e-03f ) * s + 4.16666418e-02f ) * s - 4.999999963e-01f ) * s + 1.0f ); +} + +ID_INLINE double idMath::Cos64( float a ) { + return cos( a ); +} + +ID_INLINE void idMath::SinCos( float a, float &s, float &c ) { +#ifdef _WIN32 + _asm { + fld a + fsincos + mov ecx, c + mov edx, s + fstp dword ptr [ecx] + fstp dword ptr [edx] + } +#else + s = sinf( a ); + c = cosf( a ); +#endif +} + +ID_INLINE void idMath::SinCos16( float a, float &s, float &c ) { + float t, d; + + if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { + a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; + } +#if 1 + if ( a < PI ) { + if ( a > HALF_PI ) { + a = PI - a; + d = -1.0f; + } else { + d = 1.0f; + } + } else { + if ( a > PI + HALF_PI ) { + a = a - TWO_PI; + d = 1.0f; + } else { + a = PI - a; + d = -1.0f; + } + } +#else + a = PI - a; + if ( fabs( a ) >= HALF_PI ) { + a = ( ( a < 0.0f ) ? -PI : PI ) - a; + d = 1.0f; + } else { + d = -1.0f; + } +#endif + t = a * a; + s = a * ( ( ( ( ( -2.39e-08f * t + 2.7526e-06f ) * t - 1.98409e-04f ) * t + 8.3333315e-03f ) * t - 1.666666664e-01f ) * t + 1.0f ); + c = d * ( ( ( ( ( -2.605e-07f * t + 2.47609e-05f ) * t - 1.3888397e-03f ) * t + 4.16666418e-02f ) * t - 4.999999963e-01f ) * t + 1.0f ); +} + +ID_INLINE void idMath::SinCos64( float a, double &s, double &c ) { +#ifdef _WIN32 + _asm { + fld a + fsincos + mov ecx, c + mov edx, s + fstp qword ptr [ecx] + fstp qword ptr [edx] + } +#else + s = sin( a ); + c = cos( a ); +#endif +} + +ID_INLINE float idMath::Tan( float a ) { + return tanf( a ); +} + +ID_INLINE float idMath::Tan16( float a ) { + float s; + bool reciprocal; + + if ( ( a < 0.0f ) || ( a >= PI ) ) { + a -= floorf( a / PI ) * PI; + } +#if 1 + if ( a < HALF_PI ) { + if ( a > ONEFOURTH_PI ) { + a = HALF_PI - a; + reciprocal = true; + } else { + reciprocal = false; + } + } else { + if ( a > HALF_PI + ONEFOURTH_PI ) { + a = a - PI; + reciprocal = false; + } else { + a = HALF_PI - a; + reciprocal = true; + } + } +#else + a = HALF_PI - a; + if ( fabs( a ) >= ONEFOURTH_PI ) { + a = ( ( a < 0.0f ) ? -HALF_PI : HALF_PI ) - a; + reciprocal = false; + } else { + reciprocal = true; + } +#endif + s = a * a; + s = a * ( ( ( ( ( ( 9.5168091e-03f * s + 2.900525e-03f ) * s + 2.45650893e-02f ) * s + 5.33740603e-02f ) * s + 1.333923995e-01f ) * s + 3.333314036e-01f ) * s + 1.0f ); + if ( reciprocal ) { + return 1.0f / s; + } else { + return s; + } +} + +ID_INLINE double idMath::Tan64( float a ) { + return tan( a ); +} + +ID_INLINE float idMath::ASin( float a ) { + if ( a <= -1.0f ) { + return -HALF_PI; + } + if ( a >= 1.0f ) { + return HALF_PI; + } + return asinf( a ); +} + +ID_INLINE float idMath::ASin16( float a ) { + if ( FLOATSIGNBITSET( a ) ) { + if ( a <= -1.0f ) { + return -HALF_PI; + } + a = fabs( a ); + return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ) - HALF_PI; + } else { + if ( a >= 1.0f ) { + return HALF_PI; + } + return HALF_PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); + } +} + +ID_INLINE double idMath::ASin64( float a ) { + if ( a <= -1.0f ) { + return -HALF_PI; + } + if ( a >= 1.0f ) { + return HALF_PI; + } + return asin( a ); +} + +ID_INLINE float idMath::ACos( float a ) { + if ( a <= -1.0f ) { + return PI; + } + if ( a >= 1.0f ) { + return 0.0f; + } + return acosf( a ); +} + +ID_INLINE float idMath::ACos16( float a ) { + if ( FLOATSIGNBITSET( a ) ) { + if ( a <= -1.0f ) { + return PI; + } + a = fabs( a ); + return PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); + } else { + if ( a >= 1.0f ) { + return 0.0f; + } + return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); + } +} + +ID_INLINE double idMath::ACos64( float a ) { + if ( a <= -1.0f ) { + return PI; + } + if ( a >= 1.0f ) { + return 0.0f; + } + return acos( a ); +} + +ID_INLINE float idMath::ATan( float a ) { + return atanf( a ); +} + +ID_INLINE float idMath::ATan16( float a ) { + float s; + + if ( fabs( a ) > 1.0f ) { + a = 1.0f / a; + s = a * a; + s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) + * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; + if ( FLOATSIGNBITSET( a ) ) { + return s - HALF_PI; + } else { + return s + HALF_PI; + } + } else { + s = a * a; + return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) + * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; + } +} + +ID_INLINE double idMath::ATan64( float a ) { + return atan( a ); +} + +ID_INLINE float idMath::ATan( float y, float x ) { + return atan2f( y, x ); +} + +ID_INLINE float idMath::ATan16( float y, float x ) { + float a, s; + + if ( fabs( y ) > fabs( x ) ) { + a = x / y; + s = a * a; + s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) + * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; + if ( FLOATSIGNBITSET( a ) ) { + return s - HALF_PI; + } else { + return s + HALF_PI; + } + } else { + a = y / x; + s = a * a; + return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) + * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; + } +} + +ID_INLINE double idMath::ATan64( float y, float x ) { + return atan2( y, x ); +} + +ID_INLINE float idMath::Pow( float x, float y ) { + return powf( x, y ); +} + +ID_INLINE float idMath::Pow16( float x, float y ) { + return Exp16( y * Log16( x ) ); +} + +ID_INLINE double idMath::Pow64( float x, float y ) { + return pow( x, y ); +} + +ID_INLINE float idMath::Exp( float f ) { + return expf( f ); +} + +ID_INLINE float idMath::Exp16( float f ) { + int i, s, e, m, exponent; + float x, x2, y, p, q; + + x = f * 1.44269504088896340f; // multiply with ( 1 / log( 2 ) ) +#if 1 + i = *reinterpret_cast(&x); + s = ( i >> IEEE_FLT_SIGN_BIT ); + e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; + m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); + i = ( ( m >> ( IEEE_FLT_MANTISSA_BITS - e ) ) & ~( e >> 31 ) ) ^ s; +#else + i = (int) x; + if ( x < 0.0f ) { + i--; + } +#endif + exponent = ( i + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS; + y = *reinterpret_cast(&exponent); + x -= (float) i; + if ( x >= 0.5f ) { + x -= 0.5f; + y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) + } + x2 = x * x; + p = x * ( 7.2152891511493f + x2 * 0.0576900723731f ); + q = 20.8189237930062f + x2; + x = y * ( q + p ) / ( q - p ); + return x; +} + +ID_INLINE double idMath::Exp64( float f ) { + return exp( f ); +} + +ID_INLINE float idMath::Log( float f ) { + return logf( f ); +} + +ID_INLINE float idMath::Log16( float f ) { + int i, exponent; + float y, y2; + + i = *reinterpret_cast(&f); + exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; + i -= ( exponent + 1 ) << IEEE_FLT_MANTISSA_BITS; // get value in the range [.5, 1> + y = *reinterpret_cast(&i); + y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) + y = ( y - 1.0f ) / ( y + 1.0f ); + y2 = y * y; + y = y * ( 2.000000000046727f + y2 * ( 0.666666635059382f + y2 * ( 0.4000059794795f + y2 * ( 0.28525381498f + y2 * 0.2376245609f ) ) ) ); + y += 0.693147180559945f * ( (float)exponent + 0.5f ); + return y; +} + +ID_INLINE double idMath::Log64( float f ) { + return log( f ); +} + +ID_INLINE int idMath::IPow( int x, int y ) { + int r; for( r = x; y > 1; y-- ) { r *= x; } return r; +} + +ID_INLINE int idMath::ILog2( float f ) { + return ( ( (*reinterpret_cast(&f)) >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; +} + +ID_INLINE int idMath::ILog2( int i ) { + return ILog2( (float)i ); +} + +ID_INLINE int idMath::BitsForFloat( float f ) { + return ILog2( f ) + 1; +} + +ID_INLINE int idMath::BitsForInteger( int i ) { + return ILog2( (float)i ) + 1; +} + +ID_INLINE int idMath::MaskForFloatSign( float f ) { + return ( (*reinterpret_cast(&f)) >> 31 ); +} + +ID_INLINE int idMath::MaskForIntegerSign( int i ) { + return ( i >> 31 ); +} + +ID_INLINE int idMath::FloorPowerOfTwo( int x ) { + return CeilPowerOfTwo( x ) >> 1; +} + +ID_INLINE int idMath::CeilPowerOfTwo( int x ) { + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return x; +} + +ID_INLINE bool idMath::IsPowerOfTwo( int x ) { + return ( x & ( x - 1 ) ) == 0 && x > 0; +} + +ID_INLINE int idMath::BitCount( int x ) { + x -= ( ( x >> 1 ) & 0x55555555 ); + x = ( ( ( x >> 2 ) & 0x33333333 ) + ( x & 0x33333333 ) ); + x = ( ( ( x >> 4 ) + x ) & 0x0f0f0f0f ); + x += ( x >> 8 ); + return ( ( x + ( x >> 16 ) ) & 0x0000003f ); +} + +ID_INLINE int idMath::BitReverse( int x ) { + x = ( ( ( x >> 1 ) & 0x55555555 ) | ( ( x & 0x55555555 ) << 1 ) ); + x = ( ( ( x >> 2 ) & 0x33333333 ) | ( ( x & 0x33333333 ) << 2 ) ); + x = ( ( ( x >> 4 ) & 0x0f0f0f0f ) | ( ( x & 0x0f0f0f0f ) << 4 ) ); + x = ( ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x & 0x00ff00ff ) << 8 ) ); + return ( ( x >> 16 ) | ( x << 16 ) ); +} + +ID_INLINE int idMath::Abs( int x ) { + int y = x >> 31; + return ( ( x ^ y ) - y ); +} + +ID_INLINE float idMath::Fabs( float f ) { + int tmp = *reinterpret_cast( &f ); + tmp &= 0x7FFFFFFF; + return *reinterpret_cast( &tmp ); +} + +ID_INLINE float idMath::Floor( float f ) { + return floorf( f ); +} + +ID_INLINE float idMath::Ceil( float f ) { + return ceilf( f ); +} + +ID_INLINE float idMath::Rint( float f ) { + return floorf( f + 0.5f ); +} + +ID_INLINE int idMath::Ftoi( float f ) { + return (int) f; +} + +ID_INLINE int idMath::FtoiFast( float f ) { +#ifdef _WIN32 + int i; + __asm fld f + __asm fistp i // use default rouding mode (round nearest) + return i; +#elif 0 // round chop (C/C++ standard) + int i, s, e, m, shift; + i = *reinterpret_cast(&f); + s = i >> IEEE_FLT_SIGN_BIT; + e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; + m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); + shift = e - IEEE_FLT_MANTISSA_BITS; + return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; +//#elif defined( __i386__ ) +#elif 0 + int i = 0; + __asm__ __volatile__ ( + "fld %1\n" \ + "fistp %0\n" \ + : "=m" (i) \ + : "m" (f) ); + return i; +#else + return (int) f; +#endif +} + +ID_INLINE unsigned long idMath::Ftol( float f ) { + return (unsigned long) f; +} + +ID_INLINE unsigned long idMath::FtolFast( float f ) { +#ifdef _WIN32 + // FIXME: this overflows on 31bits still .. same as FtoiFast + unsigned long i; + __asm fld f + __asm fistp i // use default rouding mode (round nearest) + return i; +#elif 0 // round chop (C/C++ standard) + int i, s, e, m, shift; + i = *reinterpret_cast(&f); + s = i >> IEEE_FLT_SIGN_BIT; + e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; + m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); + shift = e - IEEE_FLT_MANTISSA_BITS; + return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; +//#elif defined( __i386__ ) +#elif 0 + // for some reason, on gcc I need to make sure i == 0 before performing a fistp + int i = 0; + __asm__ __volatile__ ( + "fld %1\n" \ + "fistp %0\n" \ + : "=m" (i) \ + : "m" (f) ); + return i; +#else + return (unsigned long) f; +#endif +} + +ID_INLINE signed char idMath::ClampChar( int i ) { + if ( i < -128 ) { + return -128; + } + if ( i > 127 ) { + return 127; + } + return i; +} + +ID_INLINE signed short idMath::ClampShort( int i ) { + if ( i < -32768 ) { + return -32768; + } + if ( i > 32767 ) { + return 32767; + } + return i; +} + +ID_INLINE int idMath::ClampInt( int min, int max, int value ) { + if ( value < min ) { + return min; + } + if ( value > max ) { + return max; + } + return value; +} + +ID_INLINE float idMath::ClampFloat( float min, float max, float value ) { + if ( value < min ) { + return min; + } + if ( value > max ) { + return max; + } + return value; +} + +ID_INLINE float idMath::AngleNormalize360( float angle ) { + if ( ( angle >= 360.0f ) || ( angle < 0.0f ) ) { + angle -= floor( angle / 360.0f ) * 360.0f; + } + return angle; +} + +ID_INLINE float idMath::AngleNormalize180( float angle ) { + angle = AngleNormalize360( angle ); + if ( angle > 180.0f ) { + angle -= 360.0f; + } + return angle; +} + +ID_INLINE float idMath::AngleDelta( float angle1, float angle2 ) { + return AngleNormalize180( angle1 - angle2 ); +} + +ID_INLINE int idMath::FloatHash( const float *array, const int numFloats ) { + int i, hash = 0; + const int *ptr; + + ptr = reinterpret_cast( array ); + for ( i = 0; i < numFloats; i++ ) { + hash ^= ptr[i]; + } + return hash; +} + +#endif /* !__MATH_MATH_H__ */ diff --git a/idlib/math/Matrix.cpp b/idlib/math/Matrix.cpp new file mode 100644 index 000000000..fe49354de --- /dev/null +++ b/idlib/math/Matrix.cpp @@ -0,0 +1,8100 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +#pragma warning( push ) +#pragma warning( disable: 4127 ) +//=============================================================== +// +// idMat2 +// +//=============================================================== + +idMat2 mat2_zero( idVec2( 0, 0 ), idVec2( 0, 0 ) ); +idMat2 mat2_identity( idVec2( 1, 0 ), idVec2( 0, 1 ) ); + +/* +============ +idMat2::InverseSelf +============ +*/ +bool idMat2::InverseSelf( void ) { + // 2+4 = 6 multiplications + // 1 division + double det, invDet, a; + + det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + a = mat[0][0]; + mat[0][0] = mat[1][1] * invDet; + mat[0][1] = - mat[0][1] * invDet; + mat[1][0] = - mat[1][0] * invDet; + mat[1][1] = a * invDet; + + return true; +} + +/* +============ +idMat2::InverseFastSelf +============ +*/ +bool idMat2::InverseFastSelf( void ) { +#if 1 + // 2+4 = 6 multiplications + // 1 division + double det, invDet, a; + + det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + a = mat[0][0]; + mat[0][0] = mat[1][1] * invDet; + mat[0][1] = - mat[0][1] * invDet; + mat[1][0] = - mat[1][0] * invDet; + mat[1][1] = a * invDet; + + return true; +#else + // 2*4 = 8 multiplications + // 2 division + float *mat = reinterpret_cast(this); + double d, di; + float s; + + di = mat[0]; + s = di; + mat[0*2+0] = d = 1.0f / di; + mat[0*2+1] *= d; + d = -d; + mat[1*2+0] *= d; + d = mat[1*2+0] * di; + mat[1*2+1] += mat[0*2+1] * d; + di = mat[1*2+1]; + s *= di; + mat[1*2+1] = d = 1.0f / di; + mat[1*2+0] *= d; + d = -d; + mat[0*2+1] *= d; + d = mat[0*2+1] * di; + mat[0*2+0] += mat[1*2+0] * d; + + return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); +#endif +} + +/* +============= +idMat2::ToString +============= +*/ +const char *idMat2::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idMat3 +// +//=============================================================== + +idMat3 mat3_zero( idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ) ); +idMat3 mat3_identity( idVec3( 1, 0, 0 ), idVec3( 0, 1, 0 ), idVec3( 0, 0, 1 ) ); + +/* +============ +idMat3::ToAngles +============ +*/ +idAngles idMat3::ToAngles( void ) const { + idAngles angles; + double theta; + double cp; + float sp; + + sp = mat[ 0 ][ 2 ]; + + // cap off our sin value so that we don't get any NANs + if ( sp > 1.0f ) { + sp = 1.0f; + } else if ( sp < -1.0f ) { + sp = -1.0f; + } + + theta = -asin( sp ); + cp = cos( theta ); + + if ( cp > 8192.0f * idMath::FLT_EPSILON ) { + angles.pitch = RAD2DEG( theta ); + angles.yaw = RAD2DEG( atan2( mat[ 0 ][ 1 ], mat[ 0 ][ 0 ] ) ); + angles.roll = RAD2DEG( atan2( mat[ 1 ][ 2 ], mat[ 2 ][ 2 ] ) ); + } else { + angles.pitch = RAD2DEG( theta ); + angles.yaw = RAD2DEG( -atan2( mat[ 1 ][ 0 ], mat[ 1 ][ 1 ] ) ); + angles.roll = 0; + } + return angles; +} + +/* +============ +idMat3::ToQuat +============ +*/ +idQuat idMat3::ToQuat( void ) const { + idQuat q; + float trace; + float s; + float t; + int i; + int j; + int k; + + static int next[ 3 ] = { 1, 2, 0 }; + + trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ]; + + if ( trace > 0.0f ) { + + t = trace + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + q[3] = s * t; + q[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s; + q[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s; + q[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s; + + } else { + + i = 0; + if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) { + i = 1; + } + if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) { + i = 2; + } + j = next[ i ]; + k = next[ j ]; + + t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + q[i] = s * t; + q[3] = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s; + q[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s; + q[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s; + } + return q; +} + +/* +============ +idMat3::ToCQuat +============ +*/ +idCQuat idMat3::ToCQuat( void ) const { + idQuat q = ToQuat(); + if ( q.w < 0.0f ) { + return idCQuat( -q.x, -q.y, -q.z ); + } + return idCQuat( q.x, q.y, q.z ); +} + +/* +============ +idMat3::ToRotation +============ +*/ +idRotation idMat3::ToRotation( void ) const { + idRotation r; + float trace; + float s; + float t; + int i; + int j; + int k; + static int next[ 3 ] = { 1, 2, 0 }; + + trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ]; + if ( trace > 0.0f ) { + + t = trace + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + r.angle = s * t; + r.vec[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s; + r.vec[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s; + r.vec[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s; + + } else { + + i = 0; + if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) { + i = 1; + } + if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) { + i = 2; + } + j = next[ i ]; + k = next[ j ]; + + t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f; + s = idMath::InvSqrt( t ) * 0.5f; + + r.vec[i] = s * t; + r.angle = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s; + r.vec[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s; + r.vec[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s; + } + r.angle = idMath::ACos( r.angle ); + if ( idMath::Fabs( r.angle ) < 1e-10f ) { + r.vec.Set( 0.0f, 0.0f, 1.0f ); + r.angle = 0.0f; + } else { + //vec *= (1.0f / sin( angle )); + r.vec.Normalize(); + r.vec.FixDegenerateNormal(); + r.angle *= 2.0f * idMath::M_RAD2DEG; + } + + r.origin.Zero(); + r.axis = *this; + r.axisValid = true; + return r; +} + +/* +================= +idMat3::ToAngularVelocity +================= +*/ +idVec3 idMat3::ToAngularVelocity( void ) const { + idRotation rotation = ToRotation(); + return rotation.GetVec() * DEG2RAD( rotation.GetAngle() ); +} + +/* +============ +idMat3::Determinant +============ +*/ +float idMat3::Determinant( void ) const { + + float det2_12_01 = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; + float det2_12_02 = mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]; + float det2_12_12 = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; + + return mat[0][0] * det2_12_12 - mat[0][1] * det2_12_02 + mat[0][2] * det2_12_01; +} + +/* +============ +idMat3::InverseSelf +============ +*/ +bool idMat3::InverseSelf( void ) { + // 18+3+9 = 30 multiplications + // 1 division + idMat3 inverse; + double det, invDet; + + inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; + inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; + inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; + + det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; + inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; + inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; + inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1]; + inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + + mat[0][0] = inverse[0][0] * invDet; + mat[0][1] = inverse[0][1] * invDet; + mat[0][2] = inverse[0][2] * invDet; + + mat[1][0] = inverse[1][0] * invDet; + mat[1][1] = inverse[1][1] * invDet; + mat[1][2] = inverse[1][2] * invDet; + + mat[2][0] = inverse[2][0] * invDet; + mat[2][1] = inverse[2][1] * invDet; + mat[2][2] = inverse[2][2] * invDet; + + return true; +} + +/* +============ +idMat3::InverseFastSelf +============ +*/ +bool idMat3::InverseFastSelf( void ) { +#if 1 + // 18+3+9 = 30 multiplications + // 1 division + idMat3 inverse; + double det, invDet; + + inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; + inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; + inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; + + det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; + inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; + inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; + inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1]; + inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + + mat[0][0] = inverse[0][0] * invDet; + mat[0][1] = inverse[0][1] * invDet; + mat[0][2] = inverse[0][2] * invDet; + + mat[1][0] = inverse[1][0] * invDet; + mat[1][1] = inverse[1][1] * invDet; + mat[1][2] = inverse[1][2] * invDet; + + mat[2][0] = inverse[2][0] * invDet; + mat[2][1] = inverse[2][1] * invDet; + mat[2][2] = inverse[2][2] * invDet; + + return true; +#elif 0 + // 3*10 = 30 multiplications + // 3 divisions + float *mat = reinterpret_cast(this); + float s; + double d, di; + + di = mat[0]; + s = di; + mat[0] = d = 1.0f / di; + mat[1] *= d; + mat[2] *= d; + d = -d; + mat[3] *= d; + mat[6] *= d; + d = mat[3] * di; + mat[4] += mat[1] * d; + mat[5] += mat[2] * d; + d = mat[6] * di; + mat[7] += mat[1] * d; + mat[8] += mat[2] * d; + di = mat[4]; + s *= di; + mat[4] = d = 1.0f / di; + mat[3] *= d; + mat[5] *= d; + d = -d; + mat[1] *= d; + mat[7] *= d; + d = mat[1] * di; + mat[0] += mat[3] * d; + mat[2] += mat[5] * d; + d = mat[7] * di; + mat[6] += mat[3] * d; + mat[8] += mat[5] * d; + di = mat[8]; + s *= di; + mat[8] = d = 1.0f / di; + mat[6] *= d; + mat[7] *= d; + d = -d; + mat[2] *= d; + mat[5] *= d; + d = mat[2] * di; + mat[0] += mat[6] * d; + mat[1] += mat[7] * d; + d = mat[5] * di; + mat[3] += mat[6] * d; + mat[4] += mat[7] * d; + + return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); +#else + // 4*2+4*4 = 24 multiplications + // 2*1 = 2 divisions + idMat2 r0; + float r1[2], r2[2], r3; + float det, invDet; + float *mat = reinterpret_cast(this); + + // r0 = m0.Inverse(); // 2x2 + det = mat[0*3+0] * mat[1*3+1] - mat[0*3+1] * mat[1*3+0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + r0[0][0] = mat[1*3+1] * invDet; + r0[0][1] = - mat[0*3+1] * invDet; + r0[1][0] = - mat[1*3+0] * invDet; + r0[1][1] = mat[0*3+0] * invDet; + + // r1 = r0 * m1; // 2x1 = 2x2 * 2x1 + r1[0] = r0[0][0] * mat[0*3+2] + r0[0][1] * mat[1*3+2]; + r1[1] = r0[1][0] * mat[0*3+2] + r0[1][1] * mat[1*3+2]; + + // r2 = m2 * r1; // 1x1 = 1x2 * 2x1 + r2[0] = mat[2*3+0] * r1[0] + mat[2*3+1] * r1[1]; + + // r3 = r2 - m3; // 1x1 = 1x1 - 1x1 + r3 = r2[0] - mat[2*3+2]; + + // r3.InverseSelf(); + if ( idMath::Fabs( r3 ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + r3 = 1.0f / r3; + + // r2 = m2 * r0; // 1x2 = 1x2 * 2x2 + r2[0] = mat[2*3+0] * r0[0][0] + mat[2*3+1] * r0[1][0]; + r2[1] = mat[2*3+0] * r0[0][1] + mat[2*3+1] * r0[1][1]; + + // m2 = r3 * r2; // 1x2 = 1x1 * 1x2 + mat[2*3+0] = r3 * r2[0]; + mat[2*3+1] = r3 * r2[1]; + + // m0 = r0 - r1 * m2; // 2x2 - 2x1 * 1x2 + mat[0*3+0] = r0[0][0] - r1[0] * mat[2*3+0]; + mat[0*3+1] = r0[0][1] - r1[0] * mat[2*3+1]; + mat[1*3+0] = r0[1][0] - r1[1] * mat[2*3+0]; + mat[1*3+1] = r0[1][1] - r1[1] * mat[2*3+1]; + + // m1 = r1 * r3; // 2x1 = 2x1 * 1x1 + mat[0*3+2] = r1[0] * r3; + mat[1*3+2] = r1[1] * r3; + + // m3 = -r3; + mat[2*3+2] = -r3; + + return true; +#endif +} + +/* +============ +idMat3::InertiaTranslate +============ +*/ +idMat3 idMat3::InertiaTranslate( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) const { + idMat3 m; + idVec3 newCenter; + + newCenter = centerOfMass + translation; + + m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] ) + - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) ); + m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] ) + - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) ); + m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] ) + - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) ); + + m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] ); + m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] ); + m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] ); + + return (*this) + m; +} + +/* +============ +idMat3::InertiaTranslateSelf +============ +*/ +idMat3 &idMat3::InertiaTranslateSelf( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) { + idMat3 m; + idVec3 newCenter; + + newCenter = centerOfMass + translation; + + m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] ) + - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) ); + m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] ) + - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) ); + m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] ) + - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) ); + + m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] ); + m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] ); + m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] ); + + (*this) += m; + + return (*this); +} + +/* +============ +idMat3::InertiaRotate +============ +*/ +idMat3 idMat3::InertiaRotate( const idMat3 &rotation ) const { + // NOTE: the rotation matrix is stored column-major + return rotation.Transpose() * (*this) * rotation; +} + +/* +============ +idMat3::InertiaRotateSelf +============ +*/ +idMat3 &idMat3::InertiaRotateSelf( const idMat3 &rotation ) { + // NOTE: the rotation matrix is stored column-major + *this = rotation.Transpose() * (*this) * rotation; + return *this; +} + +/* +============= +idMat3::ToString +============= +*/ +const char *idMat3::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idMat4 +// +//=============================================================== + +idMat4 mat4_zero( idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ) ); +idMat4 mat4_identity( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ), idVec4( 0, 0, 1, 0 ), idVec4( 0, 0, 0, 1 ) ); + +/* +============ +idMat4::Transpose +============ +*/ +idMat4 idMat4::Transpose( void ) const { + idMat4 transpose; + int i, j; + + for( i = 0; i < 4; i++ ) { + for( j = 0; j < 4; j++ ) { + transpose[ i ][ j ] = mat[ j ][ i ]; + } + } + return transpose; +} + +/* +============ +idMat4::TransposeSelf +============ +*/ +idMat4 &idMat4::TransposeSelf( void ) { + float temp; + int i, j; + + for( i = 0; i < 4; i++ ) { + for( j = i + 1; j < 4; j++ ) { + temp = mat[ i ][ j ]; + mat[ i ][ j ] = mat[ j ][ i ]; + mat[ j ][ i ] = temp; + } + } + return *this; +} + +/* +============ +idMat4::Determinant +============ +*/ +float idMat4::Determinant( void ) const { + + // 2x2 sub-determinants + float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; + float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; + float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; + float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; + + // 3x3 sub-determinants + float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; + float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; + float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; + float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; + + return ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); +} + +/* +============ +idMat4::InverseSelf +============ +*/ +bool idMat4::InverseSelf( void ) { + // 84+4+16 = 104 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 4x4 determinant + float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; + float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; + float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; + float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; + + // 3x3 sub-determinants required to calculate 4x4 determinant + float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; + float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; + float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; + float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; + + det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0]; + float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0]; + float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0]; + float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1]; + float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1]; + float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2]; + + float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0]; + float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0]; + float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0]; + float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1]; + float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1]; + float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2]; + + // remaining 3x3 sub-determinants + float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01; + float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01; + float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02; + float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12; + + float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01; + float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01; + float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02; + float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12; + + float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01; + float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01; + float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02; + float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12; + + mat[0][0] = - det3_213_123 * invDet; + mat[1][0] = + det3_213_023 * invDet; + mat[2][0] = - det3_213_013 * invDet; + mat[3][0] = + det3_213_012 * invDet; + + mat[0][1] = + det3_203_123 * invDet; + mat[1][1] = - det3_203_023 * invDet; + mat[2][1] = + det3_203_013 * invDet; + mat[3][1] = - det3_203_012 * invDet; + + mat[0][2] = + det3_301_123 * invDet; + mat[1][2] = - det3_301_023 * invDet; + mat[2][2] = + det3_301_013 * invDet; + mat[3][2] = - det3_301_012 * invDet; + + mat[0][3] = - det3_201_123 * invDet; + mat[1][3] = + det3_201_023 * invDet; + mat[2][3] = - det3_201_013 * invDet; + mat[3][3] = + det3_201_012 * invDet; + + return true; +} + +/* +============ +idMat4::InverseFastSelf +============ +*/ +bool idMat4::InverseFastSelf( void ) { +#if 0 + // 84+4+16 = 104 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 4x4 determinant + float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; + float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; + float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; + float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; + float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; + + // 3x3 sub-determinants required to calculate 4x4 determinant + float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; + float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; + float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; + float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; + + det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0]; + float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0]; + float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0]; + float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1]; + float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1]; + float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2]; + + float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0]; + float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0]; + float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0]; + float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1]; + float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1]; + float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2]; + + // remaining 3x3 sub-determinants + float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01; + float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01; + float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02; + float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12; + + float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01; + float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01; + float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02; + float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12; + + float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01; + float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01; + float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02; + float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12; + + mat[0][0] = - det3_213_123 * invDet; + mat[1][0] = + det3_213_023 * invDet; + mat[2][0] = - det3_213_013 * invDet; + mat[3][0] = + det3_213_012 * invDet; + + mat[0][1] = + det3_203_123 * invDet; + mat[1][1] = - det3_203_023 * invDet; + mat[2][1] = + det3_203_013 * invDet; + mat[3][1] = - det3_203_012 * invDet; + + mat[0][2] = + det3_301_123 * invDet; + mat[1][2] = - det3_301_023 * invDet; + mat[2][2] = + det3_301_013 * invDet; + mat[3][2] = - det3_301_012 * invDet; + + mat[0][3] = - det3_201_123 * invDet; + mat[1][3] = + det3_201_023 * invDet; + mat[2][3] = - det3_201_013 * invDet; + mat[3][3] = + det3_201_012 * invDet; + + return true; +#elif 0 + // 4*18 = 72 multiplications + // 4 divisions + float *mat = reinterpret_cast(this); + float s; + double d, di; + + di = mat[0]; + s = di; + mat[0] = d = 1.0f / di; + mat[1] *= d; + mat[2] *= d; + mat[3] *= d; + d = -d; + mat[4] *= d; + mat[8] *= d; + mat[12] *= d; + d = mat[4] * di; + mat[5] += mat[1] * d; + mat[6] += mat[2] * d; + mat[7] += mat[3] * d; + d = mat[8] * di; + mat[9] += mat[1] * d; + mat[10] += mat[2] * d; + mat[11] += mat[3] * d; + d = mat[12] * di; + mat[13] += mat[1] * d; + mat[14] += mat[2] * d; + mat[15] += mat[3] * d; + di = mat[5]; + s *= di; + mat[5] = d = 1.0f / di; + mat[4] *= d; + mat[6] *= d; + mat[7] *= d; + d = -d; + mat[1] *= d; + mat[9] *= d; + mat[13] *= d; + d = mat[1] * di; + mat[0] += mat[4] * d; + mat[2] += mat[6] * d; + mat[3] += mat[7] * d; + d = mat[9] * di; + mat[8] += mat[4] * d; + mat[10] += mat[6] * d; + mat[11] += mat[7] * d; + d = mat[13] * di; + mat[12] += mat[4] * d; + mat[14] += mat[6] * d; + mat[15] += mat[7] * d; + di = mat[10]; + s *= di; + mat[10] = d = 1.0f / di; + mat[8] *= d; + mat[9] *= d; + mat[11] *= d; + d = -d; + mat[2] *= d; + mat[6] *= d; + mat[14] *= d; + d = mat[2] * di; + mat[0] += mat[8] * d; + mat[1] += mat[9] * d; + mat[3] += mat[11] * d; + d = mat[6] * di; + mat[4] += mat[8] * d; + mat[5] += mat[9] * d; + mat[7] += mat[11] * d; + d = mat[14] * di; + mat[12] += mat[8] * d; + mat[13] += mat[9] * d; + mat[15] += mat[11] * d; + di = mat[15]; + s *= di; + mat[15] = d = 1.0f / di; + mat[12] *= d; + mat[13] *= d; + mat[14] *= d; + d = -d; + mat[3] *= d; + mat[7] *= d; + mat[11] *= d; + d = mat[3] * di; + mat[0] += mat[12] * d; + mat[1] += mat[13] * d; + mat[2] += mat[14] * d; + d = mat[7] * di; + mat[4] += mat[12] * d; + mat[5] += mat[13] * d; + mat[6] += mat[14] * d; + d = mat[11] * di; + mat[8] += mat[12] * d; + mat[9] += mat[13] * d; + mat[10] += mat[14] * d; + + return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); +#else + // 6*8+2*6 = 60 multiplications + // 2*1 = 2 divisions + idMat2 r0, r1, r2, r3; + float a, det, invDet; + float *mat = reinterpret_cast(this); + + // r0 = m0.Inverse(); + det = mat[0*4+0] * mat[1*4+1] - mat[0*4+1] * mat[1*4+0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + r0[0][0] = mat[1*4+1] * invDet; + r0[0][1] = - mat[0*4+1] * invDet; + r0[1][0] = - mat[1*4+0] * invDet; + r0[1][1] = mat[0*4+0] * invDet; + + // r1 = r0 * m1; + r1[0][0] = r0[0][0] * mat[0*4+2] + r0[0][1] * mat[1*4+2]; + r1[0][1] = r0[0][0] * mat[0*4+3] + r0[0][1] * mat[1*4+3]; + r1[1][0] = r0[1][0] * mat[0*4+2] + r0[1][1] * mat[1*4+2]; + r1[1][1] = r0[1][0] * mat[0*4+3] + r0[1][1] * mat[1*4+3]; + + // r2 = m2 * r1; + r2[0][0] = mat[2*4+0] * r1[0][0] + mat[2*4+1] * r1[1][0]; + r2[0][1] = mat[2*4+0] * r1[0][1] + mat[2*4+1] * r1[1][1]; + r2[1][0] = mat[3*4+0] * r1[0][0] + mat[3*4+1] * r1[1][0]; + r2[1][1] = mat[3*4+0] * r1[0][1] + mat[3*4+1] * r1[1][1]; + + // r3 = r2 - m3; + r3[0][0] = r2[0][0] - mat[2*4+2]; + r3[0][1] = r2[0][1] - mat[2*4+3]; + r3[1][0] = r2[1][0] - mat[3*4+2]; + r3[1][1] = r2[1][1] - mat[3*4+3]; + + // r3.InverseSelf(); + det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + a = r3[0][0]; + r3[0][0] = r3[1][1] * invDet; + r3[0][1] = - r3[0][1] * invDet; + r3[1][0] = - r3[1][0] * invDet; + r3[1][1] = a * invDet; + + // r2 = m2 * r0; + r2[0][0] = mat[2*4+0] * r0[0][0] + mat[2*4+1] * r0[1][0]; + r2[0][1] = mat[2*4+0] * r0[0][1] + mat[2*4+1] * r0[1][1]; + r2[1][0] = mat[3*4+0] * r0[0][0] + mat[3*4+1] * r0[1][0]; + r2[1][1] = mat[3*4+0] * r0[0][1] + mat[3*4+1] * r0[1][1]; + + // m2 = r3 * r2; + mat[2*4+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0]; + mat[2*4+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1]; + mat[3*4+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0]; + mat[3*4+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1]; + + // m0 = r0 - r1 * m2; + mat[0*4+0] = r0[0][0] - r1[0][0] * mat[2*4+0] - r1[0][1] * mat[3*4+0]; + mat[0*4+1] = r0[0][1] - r1[0][0] * mat[2*4+1] - r1[0][1] * mat[3*4+1]; + mat[1*4+0] = r0[1][0] - r1[1][0] * mat[2*4+0] - r1[1][1] * mat[3*4+0]; + mat[1*4+1] = r0[1][1] - r1[1][0] * mat[2*4+1] - r1[1][1] * mat[3*4+1]; + + // m1 = r1 * r3; + mat[0*4+2] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0]; + mat[0*4+3] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1]; + mat[1*4+2] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0]; + mat[1*4+3] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1]; + + // m3 = -r3; + mat[2*4+2] = -r3[0][0]; + mat[2*4+3] = -r3[0][1]; + mat[3*4+2] = -r3[1][0]; + mat[3*4+3] = -r3[1][1]; + + return true; +#endif +} + +/* +============= +idMat4::ToString +============= +*/ +const char *idMat4::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idMat5 +// +//=============================================================== + +idMat5 mat5_zero( idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ) ); +idMat5 mat5_identity( idVec5( 1, 0, 0, 0, 0 ), idVec5( 0, 1, 0, 0, 0 ), idVec5( 0, 0, 1, 0, 0 ), idVec5( 0, 0, 0, 1, 0 ), idVec5( 0, 0, 0, 0, 1 ) ); + +/* +============ +idMat5::Transpose +============ +*/ +idMat5 idMat5::Transpose( void ) const { + idMat5 transpose; + int i, j; + + for( i = 0; i < 5; i++ ) { + for( j = 0; j < 5; j++ ) { + transpose[ i ][ j ] = mat[ j ][ i ]; + } + } + return transpose; +} + +/* +============ +idMat5::TransposeSelf +============ +*/ +idMat5 &idMat5::TransposeSelf( void ) { + float temp; + int i, j; + + for( i = 0; i < 5; i++ ) { + for( j = i + 1; j < 5; j++ ) { + temp = mat[ i ][ j ]; + mat[ i ][ j ] = mat[ j ][ i ]; + mat[ j ][ i ] = temp; + } + } + return *this; +} + +/* +============ +idMat5::Determinant +============ +*/ +float idMat5::Determinant( void ) const { + + // 2x2 sub-determinants required to calculate 5x5 determinant + float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; + float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; + float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; + float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; + float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; + float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; + float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; + float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; + float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; + float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; + + // 3x3 sub-determinants required to calculate 5x5 determinant + float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; + float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; + float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; + float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; + float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; + float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; + float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; + float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; + float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; + float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; + + // 4x4 sub-determinants required to calculate 5x5 determinant + float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; + float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; + float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; + float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; + float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; + + // determinant of 5x5 matrix + return mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; +} + +/* +============ +idMat5::InverseSelf +============ +*/ +bool idMat5::InverseSelf( void ) { + // 280+5+25 = 310 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 5x5 determinant + float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; + float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; + float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; + float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; + float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; + float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; + float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; + float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; + float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; + float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; + + // 3x3 sub-determinants required to calculate 5x5 determinant + float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; + float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; + float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; + float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; + float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; + float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; + float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; + float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; + float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; + float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; + + // 4x4 sub-determinants required to calculate 5x5 determinant + float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; + float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; + float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; + float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; + float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; + + // determinant of 5x5 matrix + det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; + + if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0]; + float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0]; + float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0]; + float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0]; + float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1]; + float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1]; + float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1]; + float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2]; + float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2]; + float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3]; + float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0]; + float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0]; + float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0]; + float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0]; + float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1]; + float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1]; + float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1]; + float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2]; + float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2]; + float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3]; + + // remaining 3x3 sub-determinants + float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01; + float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01; + float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01; + float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02; + float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02; + float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03; + float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12; + float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12; + float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13; + float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23; + float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01; + float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01; + float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01; + float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02; + float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02; + float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03; + float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12; + float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12; + float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13; + float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23; + float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01; + float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01; + float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01; + float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02; + float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02; + float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03; + float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12; + float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12; + float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13; + float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23; + + // remaining 4x4 sub-determinants + float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012; + float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012; + float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013; + float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023; + float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123; + float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012; + float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012; + float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013; + float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023; + float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123; + float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012; + float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012; + float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013; + float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023; + float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123; + float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012; + float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012; + float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013; + float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023; + float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123; + + mat[0][0] = det4_1234_1234 * invDet; + mat[0][1] = -det4_0234_1234 * invDet; + mat[0][2] = det4_0134_1234 * invDet; + mat[0][3] = -det4_0124_1234 * invDet; + mat[0][4] = det4_0123_1234 * invDet; + + mat[1][0] = -det4_1234_0234 * invDet; + mat[1][1] = det4_0234_0234 * invDet; + mat[1][2] = -det4_0134_0234 * invDet; + mat[1][3] = det4_0124_0234 * invDet; + mat[1][4] = -det4_0123_0234 * invDet; + + mat[2][0] = det4_1234_0134 * invDet; + mat[2][1] = -det4_0234_0134 * invDet; + mat[2][2] = det4_0134_0134 * invDet; + mat[2][3] = -det4_0124_0134 * invDet; + mat[2][4] = det4_0123_0134 * invDet; + + mat[3][0] = -det4_1234_0124 * invDet; + mat[3][1] = det4_0234_0124 * invDet; + mat[3][2] = -det4_0134_0124 * invDet; + mat[3][3] = det4_0124_0124 * invDet; + mat[3][4] = -det4_0123_0124 * invDet; + + mat[4][0] = det4_1234_0123 * invDet; + mat[4][1] = -det4_0234_0123 * invDet; + mat[4][2] = det4_0134_0123 * invDet; + mat[4][3] = -det4_0124_0123 * invDet; + mat[4][4] = det4_0123_0123 * invDet; + + return true; +} + +/* +============ +idMat5::InverseFastSelf +============ +*/ +bool idMat5::InverseFastSelf( void ) { +#if 0 + // 280+5+25 = 310 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 5x5 determinant + float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; + float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; + float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; + float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; + float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; + float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; + float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; + float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; + float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; + float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; + + // 3x3 sub-determinants required to calculate 5x5 determinant + float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; + float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; + float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; + float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; + float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; + float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; + float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; + float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; + float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; + float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; + + // 4x4 sub-determinants required to calculate 5x5 determinant + float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; + float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; + float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; + float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; + float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; + + // determinant of 5x5 matrix + det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; + + if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0]; + float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0]; + float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0]; + float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0]; + float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1]; + float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1]; + float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1]; + float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2]; + float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2]; + float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3]; + float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0]; + float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0]; + float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0]; + float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0]; + float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1]; + float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1]; + float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1]; + float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2]; + float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2]; + float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3]; + + // remaining 3x3 sub-determinants + float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01; + float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01; + float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01; + float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02; + float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02; + float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03; + float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12; + float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12; + float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13; + float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23; + float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01; + float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01; + float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01; + float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02; + float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02; + float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03; + float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12; + float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12; + float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13; + float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23; + float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01; + float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01; + float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01; + float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02; + float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02; + float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03; + float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12; + float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12; + float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13; + float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23; + + // remaining 4x4 sub-determinants + float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012; + float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012; + float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013; + float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023; + float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123; + float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012; + float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012; + float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013; + float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023; + float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123; + float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012; + float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012; + float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013; + float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023; + float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123; + float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012; + float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012; + float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013; + float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023; + float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123; + + mat[0][0] = det4_1234_1234 * invDet; + mat[0][1] = -det4_0234_1234 * invDet; + mat[0][2] = det4_0134_1234 * invDet; + mat[0][3] = -det4_0124_1234 * invDet; + mat[0][4] = det4_0123_1234 * invDet; + + mat[1][0] = -det4_1234_0234 * invDet; + mat[1][1] = det4_0234_0234 * invDet; + mat[1][2] = -det4_0134_0234 * invDet; + mat[1][3] = det4_0124_0234 * invDet; + mat[1][4] = -det4_0123_0234 * invDet; + + mat[2][0] = det4_1234_0134 * invDet; + mat[2][1] = -det4_0234_0134 * invDet; + mat[2][2] = det4_0134_0134 * invDet; + mat[2][3] = -det4_0124_0134 * invDet; + mat[2][4] = det4_0123_0134 * invDet; + + mat[3][0] = -det4_1234_0124 * invDet; + mat[3][1] = det4_0234_0124 * invDet; + mat[3][2] = -det4_0134_0124 * invDet; + mat[3][3] = det4_0124_0124 * invDet; + mat[3][4] = -det4_0123_0124 * invDet; + + mat[4][0] = det4_1234_0123 * invDet; + mat[4][1] = -det4_0234_0123 * invDet; + mat[4][2] = det4_0134_0123 * invDet; + mat[4][3] = -det4_0124_0123 * invDet; + mat[4][4] = det4_0123_0123 * invDet; + + return true; +#elif 0 + // 5*28 = 140 multiplications + // 5 divisions + float *mat = reinterpret_cast(this); + float s; + double d, di; + + di = mat[0]; + s = di; + mat[0] = d = 1.0f / di; + mat[1] *= d; + mat[2] *= d; + mat[3] *= d; + mat[4] *= d; + d = -d; + mat[5] *= d; + mat[10] *= d; + mat[15] *= d; + mat[20] *= d; + d = mat[5] * di; + mat[6] += mat[1] * d; + mat[7] += mat[2] * d; + mat[8] += mat[3] * d; + mat[9] += mat[4] * d; + d = mat[10] * di; + mat[11] += mat[1] * d; + mat[12] += mat[2] * d; + mat[13] += mat[3] * d; + mat[14] += mat[4] * d; + d = mat[15] * di; + mat[16] += mat[1] * d; + mat[17] += mat[2] * d; + mat[18] += mat[3] * d; + mat[19] += mat[4] * d; + d = mat[20] * di; + mat[21] += mat[1] * d; + mat[22] += mat[2] * d; + mat[23] += mat[3] * d; + mat[24] += mat[4] * d; + di = mat[6]; + s *= di; + mat[6] = d = 1.0f / di; + mat[5] *= d; + mat[7] *= d; + mat[8] *= d; + mat[9] *= d; + d = -d; + mat[1] *= d; + mat[11] *= d; + mat[16] *= d; + mat[21] *= d; + d = mat[1] * di; + mat[0] += mat[5] * d; + mat[2] += mat[7] * d; + mat[3] += mat[8] * d; + mat[4] += mat[9] * d; + d = mat[11] * di; + mat[10] += mat[5] * d; + mat[12] += mat[7] * d; + mat[13] += mat[8] * d; + mat[14] += mat[9] * d; + d = mat[16] * di; + mat[15] += mat[5] * d; + mat[17] += mat[7] * d; + mat[18] += mat[8] * d; + mat[19] += mat[9] * d; + d = mat[21] * di; + mat[20] += mat[5] * d; + mat[22] += mat[7] * d; + mat[23] += mat[8] * d; + mat[24] += mat[9] * d; + di = mat[12]; + s *= di; + mat[12] = d = 1.0f / di; + mat[10] *= d; + mat[11] *= d; + mat[13] *= d; + mat[14] *= d; + d = -d; + mat[2] *= d; + mat[7] *= d; + mat[17] *= d; + mat[22] *= d; + d = mat[2] * di; + mat[0] += mat[10] * d; + mat[1] += mat[11] * d; + mat[3] += mat[13] * d; + mat[4] += mat[14] * d; + d = mat[7] * di; + mat[5] += mat[10] * d; + mat[6] += mat[11] * d; + mat[8] += mat[13] * d; + mat[9] += mat[14] * d; + d = mat[17] * di; + mat[15] += mat[10] * d; + mat[16] += mat[11] * d; + mat[18] += mat[13] * d; + mat[19] += mat[14] * d; + d = mat[22] * di; + mat[20] += mat[10] * d; + mat[21] += mat[11] * d; + mat[23] += mat[13] * d; + mat[24] += mat[14] * d; + di = mat[18]; + s *= di; + mat[18] = d = 1.0f / di; + mat[15] *= d; + mat[16] *= d; + mat[17] *= d; + mat[19] *= d; + d = -d; + mat[3] *= d; + mat[8] *= d; + mat[13] *= d; + mat[23] *= d; + d = mat[3] * di; + mat[0] += mat[15] * d; + mat[1] += mat[16] * d; + mat[2] += mat[17] * d; + mat[4] += mat[19] * d; + d = mat[8] * di; + mat[5] += mat[15] * d; + mat[6] += mat[16] * d; + mat[7] += mat[17] * d; + mat[9] += mat[19] * d; + d = mat[13] * di; + mat[10] += mat[15] * d; + mat[11] += mat[16] * d; + mat[12] += mat[17] * d; + mat[14] += mat[19] * d; + d = mat[23] * di; + mat[20] += mat[15] * d; + mat[21] += mat[16] * d; + mat[22] += mat[17] * d; + mat[24] += mat[19] * d; + di = mat[24]; + s *= di; + mat[24] = d = 1.0f / di; + mat[20] *= d; + mat[21] *= d; + mat[22] *= d; + mat[23] *= d; + d = -d; + mat[4] *= d; + mat[9] *= d; + mat[14] *= d; + mat[19] *= d; + d = mat[4] * di; + mat[0] += mat[20] * d; + mat[1] += mat[21] * d; + mat[2] += mat[22] * d; + mat[3] += mat[23] * d; + d = mat[9] * di; + mat[5] += mat[20] * d; + mat[6] += mat[21] * d; + mat[7] += mat[22] * d; + mat[8] += mat[23] * d; + d = mat[14] * di; + mat[10] += mat[20] * d; + mat[11] += mat[21] * d; + mat[12] += mat[22] * d; + mat[13] += mat[23] * d; + d = mat[19] * di; + mat[15] += mat[20] * d; + mat[16] += mat[21] * d; + mat[17] += mat[22] * d; + mat[18] += mat[23] * d; + + return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); +#else + // 86+30+6 = 122 multiplications + // 2*1 = 2 divisions + idMat3 r0, r1, r2, r3; + float c0, c1, c2, det, invDet; + float *mat = reinterpret_cast(this); + + // r0 = m0.Inverse(); // 3x3 + c0 = mat[1*5+1] * mat[2*5+2] - mat[1*5+2] * mat[2*5+1]; + c1 = mat[1*5+2] * mat[2*5+0] - mat[1*5+0] * mat[2*5+2]; + c2 = mat[1*5+0] * mat[2*5+1] - mat[1*5+1] * mat[2*5+0]; + + det = mat[0*5+0] * c0 + mat[0*5+1] * c1 + mat[0*5+2] * c2; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + r0[0][0] = c0 * invDet; + r0[0][1] = ( mat[0*5+2] * mat[2*5+1] - mat[0*5+1] * mat[2*5+2] ) * invDet; + r0[0][2] = ( mat[0*5+1] * mat[1*5+2] - mat[0*5+2] * mat[1*5+1] ) * invDet; + r0[1][0] = c1 * invDet; + r0[1][1] = ( mat[0*5+0] * mat[2*5+2] - mat[0*5+2] * mat[2*5+0] ) * invDet; + r0[1][2] = ( mat[0*5+2] * mat[1*5+0] - mat[0*5+0] * mat[1*5+2] ) * invDet; + r0[2][0] = c2 * invDet; + r0[2][1] = ( mat[0*5+1] * mat[2*5+0] - mat[0*5+0] * mat[2*5+1] ) * invDet; + r0[2][2] = ( mat[0*5+0] * mat[1*5+1] - mat[0*5+1] * mat[1*5+0] ) * invDet; + + // r1 = r0 * m1; // 3x2 = 3x3 * 3x2 + r1[0][0] = r0[0][0] * mat[0*5+3] + r0[0][1] * mat[1*5+3] + r0[0][2] * mat[2*5+3]; + r1[0][1] = r0[0][0] * mat[0*5+4] + r0[0][1] * mat[1*5+4] + r0[0][2] * mat[2*5+4]; + r1[1][0] = r0[1][0] * mat[0*5+3] + r0[1][1] * mat[1*5+3] + r0[1][2] * mat[2*5+3]; + r1[1][1] = r0[1][0] * mat[0*5+4] + r0[1][1] * mat[1*5+4] + r0[1][2] * mat[2*5+4]; + r1[2][0] = r0[2][0] * mat[0*5+3] + r0[2][1] * mat[1*5+3] + r0[2][2] * mat[2*5+3]; + r1[2][1] = r0[2][0] * mat[0*5+4] + r0[2][1] * mat[1*5+4] + r0[2][2] * mat[2*5+4]; + + // r2 = m2 * r1; // 2x2 = 2x3 * 3x2 + r2[0][0] = mat[3*5+0] * r1[0][0] + mat[3*5+1] * r1[1][0] + mat[3*5+2] * r1[2][0]; + r2[0][1] = mat[3*5+0] * r1[0][1] + mat[3*5+1] * r1[1][1] + mat[3*5+2] * r1[2][1]; + r2[1][0] = mat[4*5+0] * r1[0][0] + mat[4*5+1] * r1[1][0] + mat[4*5+2] * r1[2][0]; + r2[1][1] = mat[4*5+0] * r1[0][1] + mat[4*5+1] * r1[1][1] + mat[4*5+2] * r1[2][1]; + + // r3 = r2 - m3; // 2x2 = 2x2 - 2x2 + r3[0][0] = r2[0][0] - mat[3*5+3]; + r3[0][1] = r2[0][1] - mat[3*5+4]; + r3[1][0] = r2[1][0] - mat[4*5+3]; + r3[1][1] = r2[1][1] - mat[4*5+4]; + + // r3.InverseSelf(); // 2x2 + det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + c0 = r3[0][0]; + r3[0][0] = r3[1][1] * invDet; + r3[0][1] = - r3[0][1] * invDet; + r3[1][0] = - r3[1][0] * invDet; + r3[1][1] = c0 * invDet; + + // r2 = m2 * r0; // 2x3 = 2x3 * 3x3 + r2[0][0] = mat[3*5+0] * r0[0][0] + mat[3*5+1] * r0[1][0] + mat[3*5+2] * r0[2][0]; + r2[0][1] = mat[3*5+0] * r0[0][1] + mat[3*5+1] * r0[1][1] + mat[3*5+2] * r0[2][1]; + r2[0][2] = mat[3*5+0] * r0[0][2] + mat[3*5+1] * r0[1][2] + mat[3*5+2] * r0[2][2]; + r2[1][0] = mat[4*5+0] * r0[0][0] + mat[4*5+1] * r0[1][0] + mat[4*5+2] * r0[2][0]; + r2[1][1] = mat[4*5+0] * r0[0][1] + mat[4*5+1] * r0[1][1] + mat[4*5+2] * r0[2][1]; + r2[1][2] = mat[4*5+0] * r0[0][2] + mat[4*5+1] * r0[1][2] + mat[4*5+2] * r0[2][2]; + + // m2 = r3 * r2; // 2x3 = 2x2 * 2x3 + mat[3*5+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0]; + mat[3*5+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1]; + mat[3*5+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2]; + mat[4*5+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0]; + mat[4*5+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1]; + mat[4*5+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2]; + + // m0 = r0 - r1 * m2; // 3x3 = 3x3 - 3x2 * 2x3 + mat[0*5+0] = r0[0][0] - r1[0][0] * mat[3*5+0] - r1[0][1] * mat[4*5+0]; + mat[0*5+1] = r0[0][1] - r1[0][0] * mat[3*5+1] - r1[0][1] * mat[4*5+1]; + mat[0*5+2] = r0[0][2] - r1[0][0] * mat[3*5+2] - r1[0][1] * mat[4*5+2]; + mat[1*5+0] = r0[1][0] - r1[1][0] * mat[3*5+0] - r1[1][1] * mat[4*5+0]; + mat[1*5+1] = r0[1][1] - r1[1][0] * mat[3*5+1] - r1[1][1] * mat[4*5+1]; + mat[1*5+2] = r0[1][2] - r1[1][0] * mat[3*5+2] - r1[1][1] * mat[4*5+2]; + mat[2*5+0] = r0[2][0] - r1[2][0] * mat[3*5+0] - r1[2][1] * mat[4*5+0]; + mat[2*5+1] = r0[2][1] - r1[2][0] * mat[3*5+1] - r1[2][1] * mat[4*5+1]; + mat[2*5+2] = r0[2][2] - r1[2][0] * mat[3*5+2] - r1[2][1] * mat[4*5+2]; + + // m1 = r1 * r3; // 3x2 = 3x2 * 2x2 + mat[0*5+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0]; + mat[0*5+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1]; + mat[1*5+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0]; + mat[1*5+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1]; + mat[2*5+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0]; + mat[2*5+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1]; + + // m3 = -r3; // 2x2 = - 2x2 + mat[3*5+3] = -r3[0][0]; + mat[3*5+4] = -r3[0][1]; + mat[4*5+3] = -r3[1][0]; + mat[4*5+4] = -r3[1][1]; + + return true; +#endif +} + +/* +============= +idMat5::ToString +============= +*/ +const char *idMat5::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idMat6 +// +//=============================================================== + +idMat6 mat6_zero( idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ) ); +idMat6 mat6_identity( idVec6( 1, 0, 0, 0, 0, 0 ), idVec6( 0, 1, 0, 0, 0, 0 ), idVec6( 0, 0, 1, 0, 0, 0 ), idVec6( 0, 0, 0, 1, 0, 0 ), idVec6( 0, 0, 0, 0, 1, 0 ), idVec6( 0, 0, 0, 0, 0, 1 ) ); + +/* +============ +idMat6::Transpose +============ +*/ +idMat6 idMat6::Transpose( void ) const { + idMat6 transpose; + int i, j; + + for( i = 0; i < 6; i++ ) { + for( j = 0; j < 6; j++ ) { + transpose[ i ][ j ] = mat[ j ][ i ]; + } + } + return transpose; +} + +/* +============ +idMat6::TransposeSelf +============ +*/ +idMat6 &idMat6::TransposeSelf( void ) { + float temp; + int i, j; + + for( i = 0; i < 6; i++ ) { + for( j = i + 1; j < 6; j++ ) { + temp = mat[ i ][ j ]; + mat[ i ][ j ] = mat[ j ][ i ]; + mat[ j ][ i ] = temp; + } + } + return *this; +} + +/* +============ +idMat6::Determinant +============ +*/ +float idMat6::Determinant( void ) const { + + // 2x2 sub-determinants required to calculate 6x6 determinant + float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; + float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; + float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; + float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; + float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; + float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; + float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; + float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; + float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; + float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; + float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; + float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; + float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; + float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; + float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; + + // 3x3 sub-determinants required to calculate 6x6 determinant + float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; + float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; + float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; + float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; + float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; + float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; + float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; + float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; + float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; + float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; + float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; + float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; + float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; + float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; + float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; + float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; + float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; + float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; + float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; + float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; + + // 4x4 sub-determinants required to calculate 6x6 determinant + float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; + float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; + float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; + float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; + float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; + float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; + float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; + float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; + float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; + float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; + float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; + float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; + float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; + float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; + float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; + + // 5x5 sub-determinants required to calculate 6x6 determinant + float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; + float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; + float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; + float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; + float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; + float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; + + // determinant of 6x6 matrix + return mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - + mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; +} + +/* +============ +idMat6::InverseSelf +============ +*/ +bool idMat6::InverseSelf( void ) { + // 810+6+36 = 852 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 6x6 determinant + float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; + float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; + float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; + float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; + float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; + float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; + float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; + float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; + float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; + float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; + float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; + float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; + float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; + float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; + float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; + + // 3x3 sub-determinants required to calculate 6x6 determinant + float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; + float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; + float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; + float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; + float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; + float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; + float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; + float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; + float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; + float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; + float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; + float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; + float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; + float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; + float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; + float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; + float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; + float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; + float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; + float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; + + // 4x4 sub-determinants required to calculate 6x6 determinant + float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; + float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; + float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; + float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; + float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; + float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; + float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; + float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; + float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; + float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; + float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; + float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; + float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; + float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; + float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; + + // 5x5 sub-determinants required to calculate 6x6 determinant + float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; + float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; + float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; + float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; + float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; + float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; + + // determinant of 6x6 matrix + det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - + mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; + float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; + float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; + float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; + float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0]; + float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; + float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; + float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; + float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1]; + float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; + float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; + float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2]; + float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; + float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3]; + float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4]; + float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0]; + float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0]; + float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0]; + float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0]; + float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0]; + float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1]; + float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1]; + float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1]; + float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1]; + float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2]; + float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2]; + float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2]; + float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3]; + float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3]; + float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4]; + + // remaining 3x3 sub-determinants + float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; + float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; + float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; + float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01; + float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; + float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; + float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02; + float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; + float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03; + float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04; + float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; + float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; + float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12; + float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; + float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13; + float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14; + float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; + float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23; + float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24; + float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34; + float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01; + float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01; + float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01; + float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01; + float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02; + float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02; + float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02; + float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03; + float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03; + float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04; + float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12; + float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12; + float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12; + float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13; + float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13; + float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14; + float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23; + float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23; + float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24; + float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34; + float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01; + float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01; + float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01; + float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01; + float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02; + float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02; + float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02; + float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03; + float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03; + float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04; + float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12; + float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12; + float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12; + float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13; + float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13; + float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14; + float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23; + float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23; + float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24; + float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34; + + // remaining 4x4 sub-determinants + float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; + float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; + float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012; + float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; + float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013; + float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014; + float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; + float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023; + float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024; + float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034; + float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; + float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123; + float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124; + float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134; + float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234; + float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012; + float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012; + float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012; + float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013; + float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013; + float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014; + float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023; + float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023; + float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024; + float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034; + float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123; + float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123; + float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124; + float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134; + float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234; + float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012; + float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012; + float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012; + float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013; + float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013; + float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014; + float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023; + float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023; + float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024; + float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034; + float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123; + float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123; + float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124; + float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134; + float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234; + float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012; + float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012; + float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012; + float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013; + float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013; + float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014; + float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023; + float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023; + float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024; + float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034; + float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123; + float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123; + float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124; + float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134; + float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234; + + // remaining 5x5 sub-determinants + float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; + float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123; + float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124; + float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134; + float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234; + float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234; + float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123; + float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123; + float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124; + float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134; + float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234; + float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234; + float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123; + float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123; + float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124; + float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134; + float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234; + float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234; + float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123; + float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123; + float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124; + float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134; + float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234; + float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234; + float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123; + float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123; + float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124; + float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134; + float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234; + float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234; + + mat[0][0] = det5_12345_12345 * invDet; + mat[0][1] = -det5_02345_12345 * invDet; + mat[0][2] = det5_01345_12345 * invDet; + mat[0][3] = -det5_01245_12345 * invDet; + mat[0][4] = det5_01235_12345 * invDet; + mat[0][5] = -det5_01234_12345 * invDet; + + mat[1][0] = -det5_12345_02345 * invDet; + mat[1][1] = det5_02345_02345 * invDet; + mat[1][2] = -det5_01345_02345 * invDet; + mat[1][3] = det5_01245_02345 * invDet; + mat[1][4] = -det5_01235_02345 * invDet; + mat[1][5] = det5_01234_02345 * invDet; + + mat[2][0] = det5_12345_01345 * invDet; + mat[2][1] = -det5_02345_01345 * invDet; + mat[2][2] = det5_01345_01345 * invDet; + mat[2][3] = -det5_01245_01345 * invDet; + mat[2][4] = det5_01235_01345 * invDet; + mat[2][5] = -det5_01234_01345 * invDet; + + mat[3][0] = -det5_12345_01245 * invDet; + mat[3][1] = det5_02345_01245 * invDet; + mat[3][2] = -det5_01345_01245 * invDet; + mat[3][3] = det5_01245_01245 * invDet; + mat[3][4] = -det5_01235_01245 * invDet; + mat[3][5] = det5_01234_01245 * invDet; + + mat[4][0] = det5_12345_01235 * invDet; + mat[4][1] = -det5_02345_01235 * invDet; + mat[4][2] = det5_01345_01235 * invDet; + mat[4][3] = -det5_01245_01235 * invDet; + mat[4][4] = det5_01235_01235 * invDet; + mat[4][5] = -det5_01234_01235 * invDet; + + mat[5][0] = -det5_12345_01234 * invDet; + mat[5][1] = det5_02345_01234 * invDet; + mat[5][2] = -det5_01345_01234 * invDet; + mat[5][3] = det5_01245_01234 * invDet; + mat[5][4] = -det5_01235_01234 * invDet; + mat[5][5] = det5_01234_01234 * invDet; + + return true; +} + +/* +============ +idMat6::InverseFastSelf +============ +*/ +bool idMat6::InverseFastSelf( void ) { +#if 0 + // 810+6+36 = 852 multiplications + // 1 division + double det, invDet; + + // 2x2 sub-determinants required to calculate 6x6 determinant + float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; + float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; + float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; + float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; + float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; + float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; + float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; + float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; + float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; + float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; + float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; + float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; + float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; + float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; + float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; + + // 3x3 sub-determinants required to calculate 6x6 determinant + float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; + float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; + float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; + float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; + float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; + float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; + float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; + float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; + float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; + float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; + float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; + float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; + float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; + float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; + float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; + float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; + float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; + float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; + float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; + float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; + + // 4x4 sub-determinants required to calculate 6x6 determinant + float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; + float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; + float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; + float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; + float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; + float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; + float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; + float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; + float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; + float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; + float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; + float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; + float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; + float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; + float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; + + // 5x5 sub-determinants required to calculate 6x6 determinant + float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; + float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; + float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; + float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; + float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; + float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; + + // determinant of 6x6 matrix + det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - + mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + // remaining 2x2 sub-determinants + float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; + float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; + float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; + float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; + float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0]; + float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; + float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; + float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; + float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1]; + float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; + float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; + float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2]; + float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; + float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3]; + float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4]; + float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0]; + float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0]; + float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0]; + float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0]; + float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0]; + float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1]; + float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1]; + float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1]; + float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1]; + float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2]; + float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2]; + float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2]; + float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3]; + float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3]; + float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4]; + + // remaining 3x3 sub-determinants + float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; + float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; + float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; + float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01; + float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; + float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; + float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02; + float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; + float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03; + float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04; + float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; + float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; + float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12; + float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; + float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13; + float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14; + float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; + float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23; + float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24; + float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34; + float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01; + float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01; + float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01; + float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01; + float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02; + float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02; + float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02; + float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03; + float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03; + float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04; + float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12; + float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12; + float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12; + float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13; + float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13; + float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14; + float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23; + float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23; + float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24; + float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34; + float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01; + float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01; + float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01; + float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01; + float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02; + float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02; + float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02; + float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03; + float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03; + float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04; + float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12; + float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12; + float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12; + float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13; + float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13; + float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14; + float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23; + float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23; + float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24; + float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34; + + // remaining 4x4 sub-determinants + float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; + float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; + float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012; + float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; + float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013; + float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014; + float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; + float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023; + float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024; + float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034; + float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; + float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123; + float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124; + float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134; + float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234; + float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012; + float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012; + float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012; + float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013; + float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013; + float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014; + float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023; + float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023; + float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024; + float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034; + float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123; + float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123; + float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124; + float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134; + float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234; + float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012; + float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012; + float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012; + float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013; + float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013; + float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014; + float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023; + float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023; + float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024; + float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034; + float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123; + float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123; + float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124; + float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134; + float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234; + float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012; + float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012; + float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012; + float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013; + float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013; + float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014; + float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023; + float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023; + float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024; + float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034; + float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123; + float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123; + float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124; + float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134; + float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234; + + // remaining 5x5 sub-determinants + float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; + float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123; + float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124; + float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134; + float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234; + float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234; + float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123; + float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123; + float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124; + float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134; + float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234; + float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234; + float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123; + float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123; + float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124; + float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134; + float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234; + float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234; + float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123; + float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123; + float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124; + float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134; + float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234; + float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234; + float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123; + float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123; + float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124; + float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134; + float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234; + float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234; + + mat[0][0] = det5_12345_12345 * invDet; + mat[0][1] = -det5_02345_12345 * invDet; + mat[0][2] = det5_01345_12345 * invDet; + mat[0][3] = -det5_01245_12345 * invDet; + mat[0][4] = det5_01235_12345 * invDet; + mat[0][5] = -det5_01234_12345 * invDet; + + mat[1][0] = -det5_12345_02345 * invDet; + mat[1][1] = det5_02345_02345 * invDet; + mat[1][2] = -det5_01345_02345 * invDet; + mat[1][3] = det5_01245_02345 * invDet; + mat[1][4] = -det5_01235_02345 * invDet; + mat[1][5] = det5_01234_02345 * invDet; + + mat[2][0] = det5_12345_01345 * invDet; + mat[2][1] = -det5_02345_01345 * invDet; + mat[2][2] = det5_01345_01345 * invDet; + mat[2][3] = -det5_01245_01345 * invDet; + mat[2][4] = det5_01235_01345 * invDet; + mat[2][5] = -det5_01234_01345 * invDet; + + mat[3][0] = -det5_12345_01245 * invDet; + mat[3][1] = det5_02345_01245 * invDet; + mat[3][2] = -det5_01345_01245 * invDet; + mat[3][3] = det5_01245_01245 * invDet; + mat[3][4] = -det5_01235_01245 * invDet; + mat[3][5] = det5_01234_01245 * invDet; + + mat[4][0] = det5_12345_01235 * invDet; + mat[4][1] = -det5_02345_01235 * invDet; + mat[4][2] = det5_01345_01235 * invDet; + mat[4][3] = -det5_01245_01235 * invDet; + mat[4][4] = det5_01235_01235 * invDet; + mat[4][5] = -det5_01234_01235 * invDet; + + mat[5][0] = -det5_12345_01234 * invDet; + mat[5][1] = det5_02345_01234 * invDet; + mat[5][2] = -det5_01345_01234 * invDet; + mat[5][3] = det5_01245_01234 * invDet; + mat[5][4] = -det5_01235_01234 * invDet; + mat[5][5] = det5_01234_01234 * invDet; + + return true; +#elif 0 + // 6*40 = 240 multiplications + // 6 divisions + float *mat = reinterpret_cast(this); + float s; + double d, di; + + di = mat[0]; + s = di; + mat[0] = d = 1.0f / di; + mat[1] *= d; + mat[2] *= d; + mat[3] *= d; + mat[4] *= d; + mat[5] *= d; + d = -d; + mat[6] *= d; + mat[12] *= d; + mat[18] *= d; + mat[24] *= d; + mat[30] *= d; + d = mat[6] * di; + mat[7] += mat[1] * d; + mat[8] += mat[2] * d; + mat[9] += mat[3] * d; + mat[10] += mat[4] * d; + mat[11] += mat[5] * d; + d = mat[12] * di; + mat[13] += mat[1] * d; + mat[14] += mat[2] * d; + mat[15] += mat[3] * d; + mat[16] += mat[4] * d; + mat[17] += mat[5] * d; + d = mat[18] * di; + mat[19] += mat[1] * d; + mat[20] += mat[2] * d; + mat[21] += mat[3] * d; + mat[22] += mat[4] * d; + mat[23] += mat[5] * d; + d = mat[24] * di; + mat[25] += mat[1] * d; + mat[26] += mat[2] * d; + mat[27] += mat[3] * d; + mat[28] += mat[4] * d; + mat[29] += mat[5] * d; + d = mat[30] * di; + mat[31] += mat[1] * d; + mat[32] += mat[2] * d; + mat[33] += mat[3] * d; + mat[34] += mat[4] * d; + mat[35] += mat[5] * d; + di = mat[7]; + s *= di; + mat[7] = d = 1.0f / di; + mat[6] *= d; + mat[8] *= d; + mat[9] *= d; + mat[10] *= d; + mat[11] *= d; + d = -d; + mat[1] *= d; + mat[13] *= d; + mat[19] *= d; + mat[25] *= d; + mat[31] *= d; + d = mat[1] * di; + mat[0] += mat[6] * d; + mat[2] += mat[8] * d; + mat[3] += mat[9] * d; + mat[4] += mat[10] * d; + mat[5] += mat[11] * d; + d = mat[13] * di; + mat[12] += mat[6] * d; + mat[14] += mat[8] * d; + mat[15] += mat[9] * d; + mat[16] += mat[10] * d; + mat[17] += mat[11] * d; + d = mat[19] * di; + mat[18] += mat[6] * d; + mat[20] += mat[8] * d; + mat[21] += mat[9] * d; + mat[22] += mat[10] * d; + mat[23] += mat[11] * d; + d = mat[25] * di; + mat[24] += mat[6] * d; + mat[26] += mat[8] * d; + mat[27] += mat[9] * d; + mat[28] += mat[10] * d; + mat[29] += mat[11] * d; + d = mat[31] * di; + mat[30] += mat[6] * d; + mat[32] += mat[8] * d; + mat[33] += mat[9] * d; + mat[34] += mat[10] * d; + mat[35] += mat[11] * d; + di = mat[14]; + s *= di; + mat[14] = d = 1.0f / di; + mat[12] *= d; + mat[13] *= d; + mat[15] *= d; + mat[16] *= d; + mat[17] *= d; + d = -d; + mat[2] *= d; + mat[8] *= d; + mat[20] *= d; + mat[26] *= d; + mat[32] *= d; + d = mat[2] * di; + mat[0] += mat[12] * d; + mat[1] += mat[13] * d; + mat[3] += mat[15] * d; + mat[4] += mat[16] * d; + mat[5] += mat[17] * d; + d = mat[8] * di; + mat[6] += mat[12] * d; + mat[7] += mat[13] * d; + mat[9] += mat[15] * d; + mat[10] += mat[16] * d; + mat[11] += mat[17] * d; + d = mat[20] * di; + mat[18] += mat[12] * d; + mat[19] += mat[13] * d; + mat[21] += mat[15] * d; + mat[22] += mat[16] * d; + mat[23] += mat[17] * d; + d = mat[26] * di; + mat[24] += mat[12] * d; + mat[25] += mat[13] * d; + mat[27] += mat[15] * d; + mat[28] += mat[16] * d; + mat[29] += mat[17] * d; + d = mat[32] * di; + mat[30] += mat[12] * d; + mat[31] += mat[13] * d; + mat[33] += mat[15] * d; + mat[34] += mat[16] * d; + mat[35] += mat[17] * d; + di = mat[21]; + s *= di; + mat[21] = d = 1.0f / di; + mat[18] *= d; + mat[19] *= d; + mat[20] *= d; + mat[22] *= d; + mat[23] *= d; + d = -d; + mat[3] *= d; + mat[9] *= d; + mat[15] *= d; + mat[27] *= d; + mat[33] *= d; + d = mat[3] * di; + mat[0] += mat[18] * d; + mat[1] += mat[19] * d; + mat[2] += mat[20] * d; + mat[4] += mat[22] * d; + mat[5] += mat[23] * d; + d = mat[9] * di; + mat[6] += mat[18] * d; + mat[7] += mat[19] * d; + mat[8] += mat[20] * d; + mat[10] += mat[22] * d; + mat[11] += mat[23] * d; + d = mat[15] * di; + mat[12] += mat[18] * d; + mat[13] += mat[19] * d; + mat[14] += mat[20] * d; + mat[16] += mat[22] * d; + mat[17] += mat[23] * d; + d = mat[27] * di; + mat[24] += mat[18] * d; + mat[25] += mat[19] * d; + mat[26] += mat[20] * d; + mat[28] += mat[22] * d; + mat[29] += mat[23] * d; + d = mat[33] * di; + mat[30] += mat[18] * d; + mat[31] += mat[19] * d; + mat[32] += mat[20] * d; + mat[34] += mat[22] * d; + mat[35] += mat[23] * d; + di = mat[28]; + s *= di; + mat[28] = d = 1.0f / di; + mat[24] *= d; + mat[25] *= d; + mat[26] *= d; + mat[27] *= d; + mat[29] *= d; + d = -d; + mat[4] *= d; + mat[10] *= d; + mat[16] *= d; + mat[22] *= d; + mat[34] *= d; + d = mat[4] * di; + mat[0] += mat[24] * d; + mat[1] += mat[25] * d; + mat[2] += mat[26] * d; + mat[3] += mat[27] * d; + mat[5] += mat[29] * d; + d = mat[10] * di; + mat[6] += mat[24] * d; + mat[7] += mat[25] * d; + mat[8] += mat[26] * d; + mat[9] += mat[27] * d; + mat[11] += mat[29] * d; + d = mat[16] * di; + mat[12] += mat[24] * d; + mat[13] += mat[25] * d; + mat[14] += mat[26] * d; + mat[15] += mat[27] * d; + mat[17] += mat[29] * d; + d = mat[22] * di; + mat[18] += mat[24] * d; + mat[19] += mat[25] * d; + mat[20] += mat[26] * d; + mat[21] += mat[27] * d; + mat[23] += mat[29] * d; + d = mat[34] * di; + mat[30] += mat[24] * d; + mat[31] += mat[25] * d; + mat[32] += mat[26] * d; + mat[33] += mat[27] * d; + mat[35] += mat[29] * d; + di = mat[35]; + s *= di; + mat[35] = d = 1.0f / di; + mat[30] *= d; + mat[31] *= d; + mat[32] *= d; + mat[33] *= d; + mat[34] *= d; + d = -d; + mat[5] *= d; + mat[11] *= d; + mat[17] *= d; + mat[23] *= d; + mat[29] *= d; + d = mat[5] * di; + mat[0] += mat[30] * d; + mat[1] += mat[31] * d; + mat[2] += mat[32] * d; + mat[3] += mat[33] * d; + mat[4] += mat[34] * d; + d = mat[11] * di; + mat[6] += mat[30] * d; + mat[7] += mat[31] * d; + mat[8] += mat[32] * d; + mat[9] += mat[33] * d; + mat[10] += mat[34] * d; + d = mat[17] * di; + mat[12] += mat[30] * d; + mat[13] += mat[31] * d; + mat[14] += mat[32] * d; + mat[15] += mat[33] * d; + mat[16] += mat[34] * d; + d = mat[23] * di; + mat[18] += mat[30] * d; + mat[19] += mat[31] * d; + mat[20] += mat[32] * d; + mat[21] += mat[33] * d; + mat[22] += mat[34] * d; + d = mat[29] * di; + mat[24] += mat[30] * d; + mat[25] += mat[31] * d; + mat[26] += mat[32] * d; + mat[27] += mat[33] * d; + mat[28] += mat[34] * d; + + return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); +#else + // 6*27+2*30 = 222 multiplications + // 2*1 = 2 divisions + idMat3 r0, r1, r2, r3; + float c0, c1, c2, det, invDet; + float *mat = reinterpret_cast(this); + + // r0 = m0.Inverse(); + c0 = mat[1*6+1] * mat[2*6+2] - mat[1*6+2] * mat[2*6+1]; + c1 = mat[1*6+2] * mat[2*6+0] - mat[1*6+0] * mat[2*6+2]; + c2 = mat[1*6+0] * mat[2*6+1] - mat[1*6+1] * mat[2*6+0]; + + det = mat[0*6+0] * c0 + mat[0*6+1] * c1 + mat[0*6+2] * c2; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + r0[0][0] = c0 * invDet; + r0[0][1] = ( mat[0*6+2] * mat[2*6+1] - mat[0*6+1] * mat[2*6+2] ) * invDet; + r0[0][2] = ( mat[0*6+1] * mat[1*6+2] - mat[0*6+2] * mat[1*6+1] ) * invDet; + r0[1][0] = c1 * invDet; + r0[1][1] = ( mat[0*6+0] * mat[2*6+2] - mat[0*6+2] * mat[2*6+0] ) * invDet; + r0[1][2] = ( mat[0*6+2] * mat[1*6+0] - mat[0*6+0] * mat[1*6+2] ) * invDet; + r0[2][0] = c2 * invDet; + r0[2][1] = ( mat[0*6+1] * mat[2*6+0] - mat[0*6+0] * mat[2*6+1] ) * invDet; + r0[2][2] = ( mat[0*6+0] * mat[1*6+1] - mat[0*6+1] * mat[1*6+0] ) * invDet; + + // r1 = r0 * m1; + r1[0][0] = r0[0][0] * mat[0*6+3] + r0[0][1] * mat[1*6+3] + r0[0][2] * mat[2*6+3]; + r1[0][1] = r0[0][0] * mat[0*6+4] + r0[0][1] * mat[1*6+4] + r0[0][2] * mat[2*6+4]; + r1[0][2] = r0[0][0] * mat[0*6+5] + r0[0][1] * mat[1*6+5] + r0[0][2] * mat[2*6+5]; + r1[1][0] = r0[1][0] * mat[0*6+3] + r0[1][1] * mat[1*6+3] + r0[1][2] * mat[2*6+3]; + r1[1][1] = r0[1][0] * mat[0*6+4] + r0[1][1] * mat[1*6+4] + r0[1][2] * mat[2*6+4]; + r1[1][2] = r0[1][0] * mat[0*6+5] + r0[1][1] * mat[1*6+5] + r0[1][2] * mat[2*6+5]; + r1[2][0] = r0[2][0] * mat[0*6+3] + r0[2][1] * mat[1*6+3] + r0[2][2] * mat[2*6+3]; + r1[2][1] = r0[2][0] * mat[0*6+4] + r0[2][1] * mat[1*6+4] + r0[2][2] * mat[2*6+4]; + r1[2][2] = r0[2][0] * mat[0*6+5] + r0[2][1] * mat[1*6+5] + r0[2][2] * mat[2*6+5]; + + // r2 = m2 * r1; + r2[0][0] = mat[3*6+0] * r1[0][0] + mat[3*6+1] * r1[1][0] + mat[3*6+2] * r1[2][0]; + r2[0][1] = mat[3*6+0] * r1[0][1] + mat[3*6+1] * r1[1][1] + mat[3*6+2] * r1[2][1]; + r2[0][2] = mat[3*6+0] * r1[0][2] + mat[3*6+1] * r1[1][2] + mat[3*6+2] * r1[2][2]; + r2[1][0] = mat[4*6+0] * r1[0][0] + mat[4*6+1] * r1[1][0] + mat[4*6+2] * r1[2][0]; + r2[1][1] = mat[4*6+0] * r1[0][1] + mat[4*6+1] * r1[1][1] + mat[4*6+2] * r1[2][1]; + r2[1][2] = mat[4*6+0] * r1[0][2] + mat[4*6+1] * r1[1][2] + mat[4*6+2] * r1[2][2]; + r2[2][0] = mat[5*6+0] * r1[0][0] + mat[5*6+1] * r1[1][0] + mat[5*6+2] * r1[2][0]; + r2[2][1] = mat[5*6+0] * r1[0][1] + mat[5*6+1] * r1[1][1] + mat[5*6+2] * r1[2][1]; + r2[2][2] = mat[5*6+0] * r1[0][2] + mat[5*6+1] * r1[1][2] + mat[5*6+2] * r1[2][2]; + + // r3 = r2 - m3; + r3[0][0] = r2[0][0] - mat[3*6+3]; + r3[0][1] = r2[0][1] - mat[3*6+4]; + r3[0][2] = r2[0][2] - mat[3*6+5]; + r3[1][0] = r2[1][0] - mat[4*6+3]; + r3[1][1] = r2[1][1] - mat[4*6+4]; + r3[1][2] = r2[1][2] - mat[4*6+5]; + r3[2][0] = r2[2][0] - mat[5*6+3]; + r3[2][1] = r2[2][1] - mat[5*6+4]; + r3[2][2] = r2[2][2] - mat[5*6+5]; + + // r3.InverseSelf(); + r2[0][0] = r3[1][1] * r3[2][2] - r3[1][2] * r3[2][1]; + r2[1][0] = r3[1][2] * r3[2][0] - r3[1][0] * r3[2][2]; + r2[2][0] = r3[1][0] * r3[2][1] - r3[1][1] * r3[2][0]; + + det = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0]; + + if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + + invDet = 1.0f / det; + + r2[0][1] = r3[0][2] * r3[2][1] - r3[0][1] * r3[2][2]; + r2[0][2] = r3[0][1] * r3[1][2] - r3[0][2] * r3[1][1]; + r2[1][1] = r3[0][0] * r3[2][2] - r3[0][2] * r3[2][0]; + r2[1][2] = r3[0][2] * r3[1][0] - r3[0][0] * r3[1][2]; + r2[2][1] = r3[0][1] * r3[2][0] - r3[0][0] * r3[2][1]; + r2[2][2] = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; + + r3[0][0] = r2[0][0] * invDet; + r3[0][1] = r2[0][1] * invDet; + r3[0][2] = r2[0][2] * invDet; + r3[1][0] = r2[1][0] * invDet; + r3[1][1] = r2[1][1] * invDet; + r3[1][2] = r2[1][2] * invDet; + r3[2][0] = r2[2][0] * invDet; + r3[2][1] = r2[2][1] * invDet; + r3[2][2] = r2[2][2] * invDet; + + // r2 = m2 * r0; + r2[0][0] = mat[3*6+0] * r0[0][0] + mat[3*6+1] * r0[1][0] + mat[3*6+2] * r0[2][0]; + r2[0][1] = mat[3*6+0] * r0[0][1] + mat[3*6+1] * r0[1][1] + mat[3*6+2] * r0[2][1]; + r2[0][2] = mat[3*6+0] * r0[0][2] + mat[3*6+1] * r0[1][2] + mat[3*6+2] * r0[2][2]; + r2[1][0] = mat[4*6+0] * r0[0][0] + mat[4*6+1] * r0[1][0] + mat[4*6+2] * r0[2][0]; + r2[1][1] = mat[4*6+0] * r0[0][1] + mat[4*6+1] * r0[1][1] + mat[4*6+2] * r0[2][1]; + r2[1][2] = mat[4*6+0] * r0[0][2] + mat[4*6+1] * r0[1][2] + mat[4*6+2] * r0[2][2]; + r2[2][0] = mat[5*6+0] * r0[0][0] + mat[5*6+1] * r0[1][0] + mat[5*6+2] * r0[2][0]; + r2[2][1] = mat[5*6+0] * r0[0][1] + mat[5*6+1] * r0[1][1] + mat[5*6+2] * r0[2][1]; + r2[2][2] = mat[5*6+0] * r0[0][2] + mat[5*6+1] * r0[1][2] + mat[5*6+2] * r0[2][2]; + + // m2 = r3 * r2; + mat[3*6+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0]; + mat[3*6+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1] + r3[0][2] * r2[2][1]; + mat[3*6+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2] + r3[0][2] * r2[2][2]; + mat[4*6+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0] + r3[1][2] * r2[2][0]; + mat[4*6+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1] + r3[1][2] * r2[2][1]; + mat[4*6+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2] + r3[1][2] * r2[2][2]; + mat[5*6+0] = r3[2][0] * r2[0][0] + r3[2][1] * r2[1][0] + r3[2][2] * r2[2][0]; + mat[5*6+1] = r3[2][0] * r2[0][1] + r3[2][1] * r2[1][1] + r3[2][2] * r2[2][1]; + mat[5*6+2] = r3[2][0] * r2[0][2] + r3[2][1] * r2[1][2] + r3[2][2] * r2[2][2]; + + // m0 = r0 - r1 * m2; + mat[0*6+0] = r0[0][0] - r1[0][0] * mat[3*6+0] - r1[0][1] * mat[4*6+0] - r1[0][2] * mat[5*6+0]; + mat[0*6+1] = r0[0][1] - r1[0][0] * mat[3*6+1] - r1[0][1] * mat[4*6+1] - r1[0][2] * mat[5*6+1]; + mat[0*6+2] = r0[0][2] - r1[0][0] * mat[3*6+2] - r1[0][1] * mat[4*6+2] - r1[0][2] * mat[5*6+2]; + mat[1*6+0] = r0[1][0] - r1[1][0] * mat[3*6+0] - r1[1][1] * mat[4*6+0] - r1[1][2] * mat[5*6+0]; + mat[1*6+1] = r0[1][1] - r1[1][0] * mat[3*6+1] - r1[1][1] * mat[4*6+1] - r1[1][2] * mat[5*6+1]; + mat[1*6+2] = r0[1][2] - r1[1][0] * mat[3*6+2] - r1[1][1] * mat[4*6+2] - r1[1][2] * mat[5*6+2]; + mat[2*6+0] = r0[2][0] - r1[2][0] * mat[3*6+0] - r1[2][1] * mat[4*6+0] - r1[2][2] * mat[5*6+0]; + mat[2*6+1] = r0[2][1] - r1[2][0] * mat[3*6+1] - r1[2][1] * mat[4*6+1] - r1[2][2] * mat[5*6+1]; + mat[2*6+2] = r0[2][2] - r1[2][0] * mat[3*6+2] - r1[2][1] * mat[4*6+2] - r1[2][2] * mat[5*6+2]; + + // m1 = r1 * r3; + mat[0*6+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0] + r1[0][2] * r3[2][0]; + mat[0*6+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1] + r1[0][2] * r3[2][1]; + mat[0*6+5] = r1[0][0] * r3[0][2] + r1[0][1] * r3[1][2] + r1[0][2] * r3[2][2]; + mat[1*6+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0] + r1[1][2] * r3[2][0]; + mat[1*6+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1] + r1[1][2] * r3[2][1]; + mat[1*6+5] = r1[1][0] * r3[0][2] + r1[1][1] * r3[1][2] + r1[1][2] * r3[2][2]; + mat[2*6+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0] + r1[2][2] * r3[2][0]; + mat[2*6+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1] + r1[2][2] * r3[2][1]; + mat[2*6+5] = r1[2][0] * r3[0][2] + r1[2][1] * r3[1][2] + r1[2][2] * r3[2][2]; + + // m3 = -r3; + mat[3*6+3] = -r3[0][0]; + mat[3*6+4] = -r3[0][1]; + mat[3*6+5] = -r3[0][2]; + mat[4*6+3] = -r3[1][0]; + mat[4*6+4] = -r3[1][1]; + mat[4*6+5] = -r3[1][2]; + mat[5*6+3] = -r3[2][0]; + mat[5*6+4] = -r3[2][1]; + mat[5*6+5] = -r3[2][2]; + + return true; +#endif +} + +/* +============= +idMat6::ToString +============= +*/ +const char *idMat6::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idMatX +// +//=============================================================== + +float idMatX::temp[MATX_MAX_TEMP+4]; +float * idMatX::tempPtr = (float *) ( ( (int) idMatX::temp + 15 ) & ~15 ); +int idMatX::tempIndex = 0; + + +/* +============ +idMatX::ChangeSize +============ +*/ +void idMatX::ChangeSize( int rows, int columns, bool makeZero ) { + int alloc = ( rows * columns + 3 ) & ~3; + if ( alloc > alloced && alloced != -1 ) { + float *oldMat = mat; + mat = (float *) Mem_Alloc16( alloc * sizeof( float ) ); + if ( makeZero ) { + memset( mat, 0, alloc * sizeof( float ) ); + } + alloced = alloc; + if ( oldMat ) { + int minRow = Min( numRows, rows ); + int minColumn = Min( numColumns, columns ); + for ( int i = 0; i < minRow; i++ ) { + for ( int j = 0; j < minColumn; j++ ) { + mat[ i * columns + j ] = oldMat[ i * numColumns + j ]; + } + } + Mem_Free16( oldMat ); + } + } else { + if ( columns < numColumns ) { + int minRow = Min( numRows, rows ); + for ( int i = 0; i < minRow; i++ ) { + for ( int j = 0; j < columns; j++ ) { + mat[ i * columns + j ] = mat[ i * numColumns + j ]; + } + } + } else if ( columns > numColumns ) { + for ( int i = Min( numRows, rows ) - 1; i >= 0; i-- ) { + if ( makeZero ) { + for ( int j = columns - 1; j >= numColumns; j-- ) { + mat[ i * columns + j ] = 0.0f; + } + } + for ( int j = numColumns - 1; j >= 0; j-- ) { + mat[ i * columns + j ] = mat[ i * numColumns + j ]; + } + } + } + if ( makeZero && rows > numRows ) { + memset( mat + numRows * columns, 0, ( rows - numRows ) * columns * sizeof( float ) ); + } + } + numRows = rows; + numColumns = columns; + MATX_CLEAREND(); +} + +/* +============ +idMatX::RemoveRow +============ +*/ +idMatX &idMatX::RemoveRow( int r ) { + int i; + + assert( r < numRows ); + + numRows--; + + for ( i = r; i < numRows; i++ ) { + memcpy( &mat[i * numColumns], &mat[( i + 1 ) * numColumns], numColumns * sizeof( float ) ); + } + + return *this; +} + +/* +============ +idMatX::RemoveColumn +============ +*/ +idMatX &idMatX::RemoveColumn( int r ) { + int i; + + assert( r < numColumns ); + + numColumns--; + + for ( i = 0; i < numRows - 1; i++ ) { + memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); + } + memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); + + return *this; +} + +/* +============ +idMatX::RemoveRowColumn +============ +*/ +idMatX &idMatX::RemoveRowColumn( int r ) { + int i; + + assert( r < numRows && r < numColumns ); + + numRows--; + numColumns--; + + if ( r > 0 ) { + for ( i = 0; i < r - 1; i++ ) { + memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); + } + memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); + } + + memcpy( &mat[r * numColumns], &mat[( r + 1 ) * ( numColumns + 1 )], r * sizeof( float ) ); + + for ( i = r; i < numRows - 1; i++ ) { + memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); + } + memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); + + return *this; +} + +/* +============ +idMatX::IsOrthogonal + + returns true if (*this) * this->Transpose() == Identity +============ +*/ +bool idMatX::IsOrthogonal( const float epsilon ) const { + float *ptr1, *ptr2, sum; + + if ( !IsSquare() ) { + return false; + } + + ptr1 = mat; + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + ptr2 = mat + j; + sum = ptr1[0] * ptr2[0] - (float) ( i == j ); + for ( int n = 1; n < numColumns; n++ ) { + ptr2 += numColumns; + sum += ptr1[n] * ptr2[0]; + } + if ( idMath::Fabs( sum ) > epsilon ) { + return false; + } + } + ptr1 += numColumns; + } + return true; +} + +/* +============ +idMatX::IsOrthonormal + + returns true if (*this) * this->Transpose() == Identity and the length of each column vector is 1 +============ +*/ +bool idMatX::IsOrthonormal( const float epsilon ) const { + float *ptr1, *ptr2, sum; + + if ( !IsSquare() ) { + return false; + } + + ptr1 = mat; + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + ptr2 = mat + j; + sum = ptr1[0] * ptr2[0] - (float) ( i == j ); + for ( int n = 1; n < numColumns; n++ ) { + ptr2 += numColumns; + sum += ptr1[n] * ptr2[0]; + } + if ( idMath::Fabs( sum ) > epsilon ) { + return false; + } + } + ptr1 += numColumns; + + ptr2 = mat + i; + sum = ptr2[0] * ptr2[0] - 1.0f; + for ( i = 1; i < numRows; i++ ) { + ptr2 += numColumns; + sum += ptr2[i] * ptr2[i]; + } + if ( idMath::Fabs( sum ) > epsilon ) { + return false; + } + } + return true; +} + +/* +============ +idMatX::IsPMatrix + + returns true if the matrix is a P-matrix + A square matrix is a P-matrix if all its principal minors are positive. +============ +*/ +bool idMatX::IsPMatrix( const float epsilon ) const { + int i, j; + float d; + idMatX m; + + if ( !IsSquare() ) { + return false; + } + + if ( numRows <= 0 ) { + return true; + } + + if ( (*this)[0][0] <= epsilon ) { + return false; + } + + if ( numRows <= 1 ) { + return true; + } + + m.SetData( numRows - 1, numColumns - 1, MATX_ALLOCA( ( numRows - 1 ) * ( numColumns - 1 ) ) ); + + for ( i = 1; i < numRows; i++ ) { + for ( j = 1; j < numColumns; j++ ) { + m[i-1][j-1] = (*this)[i][j]; + } + } + + if ( !m.IsPMatrix( epsilon ) ) { + return false; + } + + for ( i = 1; i < numRows; i++ ) { + d = (*this)[i][0] / (*this)[0][0]; + for ( j = 1; j < numColumns; j++ ) { + m[i-1][j-1] = (*this)[i][j] - d * (*this)[0][j]; + } + } + + if ( !m.IsPMatrix( epsilon ) ) { + return false; + } + + return true; +} + +/* +============ +idMatX::IsZMatrix + + returns true if the matrix is a Z-matrix + A square matrix M is a Z-matrix if M[i][j] <= 0 for all i != j. +============ +*/ +bool idMatX::IsZMatrix( const float epsilon ) const { + int i, j; + + if ( !IsSquare() ) { + return false; + } + + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + if ( (*this)[i][j] > epsilon && i != j ) { + return false; + } + } + } + return true; +} + +/* +============ +idMatX::IsPositiveDefinite + + returns true if the matrix is Positive Definite (PD) + A square matrix M of order n is said to be PD if y'My > 0 for all vectors y of dimension n, y != 0. +============ +*/ +bool idMatX::IsPositiveDefinite( const float epsilon ) const { + int i, j, k; + float d, s; + idMatX m; + + // the matrix must be square + if ( !IsSquare() ) { + return false; + } + + // copy matrix + m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); + m = *this; + + // add transpose + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + m[i][j] += (*this)[j][i]; + } + } + + // test Positive Definiteness with Gaussian pivot steps + for ( i = 0; i < numRows; i++ ) { + + for ( j = i; j < numColumns; j++ ) { + if ( m[j][j] <= epsilon ) { + return false; + } + } + + d = 1.0f / m[i][i]; + for ( j = i + 1; j < numColumns; j++ ) { + s = d * m[j][i]; + m[j][i] = 0.0f; + for ( k = i + 1; k < numRows; k++ ) { + m[j][k] -= s * m[i][k]; + } + } + } + + return true; +} + +/* +============ +idMatX::IsSymmetricPositiveDefinite + + returns true if the matrix is Symmetric Positive Definite (PD) +============ +*/ +bool idMatX::IsSymmetricPositiveDefinite( const float epsilon ) const { + idMatX m; + + // the matrix must be symmetric + if ( !IsSymmetric( epsilon ) ) { + return false; + } + + // copy matrix + m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); + m = *this; + + // being able to obtain Cholesky factors is both a necessary and sufficient condition for positive definiteness + return m.Cholesky_Factor(); +} + +/* +============ +idMatX::IsPositiveSemiDefinite + + returns true if the matrix is Positive Semi Definite (PSD) + A square matrix M of order n is said to be PSD if y'My >= 0 for all vectors y of dimension n, y != 0. +============ +*/ +bool idMatX::IsPositiveSemiDefinite( const float epsilon ) const { + int i, j, k; + float d, s; + idMatX m; + + // the matrix must be square + if ( !IsSquare() ) { + return false; + } + + // copy original matrix + m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); + m = *this; + + // add transpose + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + m[i][j] += (*this)[j][i]; + } + } + + // test Positive Semi Definiteness with Gaussian pivot steps + for ( i = 0; i < numRows; i++ ) { + + for ( j = i; j < numColumns; j++ ) { + if ( m[j][j] < -epsilon ) { + return false; + } + if ( m[j][j] > epsilon ) { + continue; + } + for ( k = 0; k < numRows; k++ ) { + if ( idMath::Fabs( m[k][j] ) > epsilon ) { + return false; + } + if ( idMath::Fabs( m[j][k] ) > epsilon ) { + return false; + } + } + } + + if ( m[i][i] <= epsilon ) { + continue; + } + + d = 1.0f / m[i][i]; + for ( j = i + 1; j < numColumns; j++ ) { + s = d * m[j][i]; + m[j][i] = 0.0f; + for ( k = i + 1; k < numRows; k++ ) { + m[j][k] -= s * m[i][k]; + } + } + } + + return true; +} + +/* +============ +idMatX::IsSymmetricPositiveSemiDefinite + + returns true if the matrix is Symmetric Positive Semi Definite (PSD) +============ +*/ +bool idMatX::IsSymmetricPositiveSemiDefinite( const float epsilon ) const { + + // the matrix must be symmetric + if ( !IsSymmetric( epsilon ) ) { + return false; + } + + return IsPositiveSemiDefinite( epsilon ); +} + +/* +============ +idMatX::LowerTriangularInverse + + in-place inversion of the lower triangular matrix +============ +*/ +bool idMatX::LowerTriangularInverse( void ) { + int i, j, k; + double d, sum; + + for ( i = 0; i < numRows; i++ ) { + d = (*this)[i][i]; + if ( d == 0.0f ) { + return false; + } + (*this)[i][i] = d = 1.0f / d; + + for ( j = 0; j < i; j++ ) { + sum = 0.0f; + for ( k = j; k < i; k++ ) { + sum -= (*this)[i][k] * (*this)[k][j]; + } + (*this)[i][j] = sum * d; + } + } + return true; +} + +/* +============ +idMatX::UpperTriangularInverse + + in-place inversion of the upper triangular matrix +============ +*/ +bool idMatX::UpperTriangularInverse( void ) { + int i, j, k; + double d, sum; + + for ( i = numRows-1; i >= 0; i-- ) { + d = (*this)[i][i]; + if ( d == 0.0f ) { + return false; + } + (*this)[i][i] = d = 1.0f / d; + + for ( j = numRows-1; j > i; j-- ) { + sum = 0.0f; + for ( k = j; k > i; k-- ) { + sum -= (*this)[i][k] * (*this)[k][j]; + } + (*this)[i][j] = sum * d; + } + } + return true; +} + +/* +============= +idMatX::ToString +============= +*/ +const char *idMatX::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============ +idMatX::Update_RankOne + + Updates the matrix to obtain the matrix: A + alpha * v * w' +============ +*/ +void idMatX::Update_RankOne( const idVecX &v, const idVecX &w, float alpha ) { + int i, j; + float s; + + assert( v.GetSize() >= numRows ); + assert( w.GetSize() >= numColumns ); + + for ( i = 0; i < numRows; i++ ) { + s = alpha * v[i]; + for ( j = 0; j < numColumns; j++ ) { + (*this)[i][j] += s * w[j]; + } + } +} + +/* +============ +idMatX::Update_RankOneSymmetric + + Updates the matrix to obtain the matrix: A + alpha * v * v' +============ +*/ +void idMatX::Update_RankOneSymmetric( const idVecX &v, float alpha ) { + int i, j; + float s; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + + for ( i = 0; i < numRows; i++ ) { + s = alpha * v[i]; + for ( j = 0; j < numColumns; j++ ) { + (*this)[i][j] += s * v[j]; + } + } +} + +/* +============ +idMatX::Update_RowColumn + + Updates the matrix to obtain the matrix: + + [ 0 a 0 ] + A + [ d b e ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] +============ +*/ +void idMatX::Update_RowColumn( const idVecX &v, const idVecX &w, int r ) { + int i; + + assert( w[r] == 0.0f ); + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + + for ( i = 0; i < numRows; i++ ) { + (*this)[i][r] += v[i]; + } + for ( i = 0; i < numColumns; i++ ) { + (*this)[r][i] += w[i]; + } +} + +/* +============ +idMatX::Update_RowColumnSymmetric + + Updates the matrix to obtain the matrix: + + [ 0 a 0 ] + A + [ a b c ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] +============ +*/ +void idMatX::Update_RowColumnSymmetric( const idVecX &v, int r ) { + int i; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + + for ( i = 0; i < r; i++ ) { + (*this)[i][r] += v[i]; + (*this)[r][i] += v[i]; + } + (*this)[r][r] += v[r]; + for ( i = r+1; i < numRows; i++ ) { + (*this)[i][r] += v[i]; + (*this)[r][i] += v[i]; + } +} + +/* +============ +idMatX::Update_Increment + + Updates the matrix to obtain the matrix: + + [ A a ] + [ c b ] + + where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1]], w[numColumns] = 0 +============ +*/ +void idMatX::Update_Increment( const idVecX &v, const idVecX &w ) { + int i; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + assert( w.GetSize() >= numColumns+1 ); + + ChangeSize( numRows+1, numColumns+1, false ); + + for ( i = 0; i < numRows; i++ ) { + (*this)[i][numColumns-1] = v[i]; + } + for ( i = 0; i < numColumns-1; i++ ) { + (*this)[numRows-1][i] = w[i]; + } +} + +/* +============ +idMatX::Update_IncrementSymmetric + + Updates the matrix to obtain the matrix: + + [ A a ] + [ a b ] + + where: a = v[0,numRows-1], b = v[numRows] +============ +*/ +void idMatX::Update_IncrementSymmetric( const idVecX &v ) { + int i; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + + ChangeSize( numRows+1, numColumns+1, false ); + + for ( i = 0; i < numRows-1; i++ ) { + (*this)[i][numColumns-1] = v[i]; + } + for ( i = 0; i < numColumns; i++ ) { + (*this)[numRows-1][i] = v[i]; + } +} + +/* +============ +idMatX::Update_Decrement + + Updates the matrix to obtain a matrix with row r and column r removed. +============ +*/ +void idMatX::Update_Decrement( int r ) { + RemoveRowColumn( r ); +} + +/* +============ +idMatX::Inverse_GaussJordan + + in-place inversion using Gauss-Jordan elimination +============ +*/ +bool idMatX::Inverse_GaussJordan( void ) { + int i, j, k, r, c; + float d, max; + + assert( numRows == numColumns ); + + int *columnIndex = (int *) _alloca16( numRows * sizeof( int ) ); + int *rowIndex = (int *) _alloca16( numRows * sizeof( int ) ); + bool *pivot = (bool *) _alloca16( numRows * sizeof( bool ) ); + + memset( pivot, 0, numRows * sizeof( bool ) ); + + // elimination with full pivoting + for ( i = 0; i < numRows; i++ ) { + + // search the whole matrix except for pivoted rows for the maximum absolute value + max = 0.0f; + r = c = 0; + for ( j = 0; j < numRows; j++ ) { + if ( !pivot[j] ) { + for ( k = 0; k < numRows; k++ ) { + if ( !pivot[k] ) { + d = idMath::Fabs( (*this)[j][k] ); + if ( d > max ) { + max = d; + r = j; + c = k; + } + } + } + } + } + + if ( max == 0.0f ) { + // matrix is not invertible + return false; + } + + pivot[c] = true; + + // swap rows such that entry (c,c) has the pivot entry + if ( r != c ) { + SwapRows( r, c ); + } + + // keep track of the row permutation + rowIndex[i] = r; + columnIndex[i] = c; + + // scale the row to make the pivot entry equal to 1 + d = 1.0f / (*this)[c][c]; + (*this)[c][c] = 1.0f; + for ( k = 0; k < numRows; k++ ) { + (*this)[c][k] *= d; + } + + // zero out the pivot column entries in the other rows + for ( j = 0; j < numRows; j++ ) { + if ( j != c ) { + d = (*this)[j][c]; + (*this)[j][c] = 0.0f; + for ( k = 0; k < numRows; k++ ) { + (*this)[j][k] -= (*this)[c][k] * d; + } + } + } + } + + // reorder rows to store the inverse of the original matrix + for ( j = numRows - 1; j >= 0; j-- ) { + if ( rowIndex[j] != columnIndex[j] ) { + for ( k = 0; k < numRows; k++ ) { + d = (*this)[k][rowIndex[j]]; + (*this)[k][rowIndex[j]] = (*this)[k][columnIndex[j]]; + (*this)[k][columnIndex[j]] = d; + } + } + } + + return true; +} + +/* +============ +idMatX::Inverse_UpdateRankOne + + Updates the in-place inverse using the Sherman-Morrison formula to obtain the inverse for the matrix: A + alpha * v * w' +============ +*/ +bool idMatX::Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha ) { + int i, j; + float beta, s; + idVecX y, z; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + + y.SetData( numRows, VECX_ALLOCA( numRows ) ); + z.SetData( numRows, VECX_ALLOCA( numRows ) ); + + Multiply( y, v ); + TransposeMultiply( z, w ); + beta = 1.0f + ( w * y ); + + if ( beta == 0.0f ) { + return false; + } + + alpha /= beta; + + for ( i = 0; i < numRows; i++ ) { + s = y[i] * alpha; + for ( j = 0; j < numColumns; j++ ) { + (*this)[i][j] -= s * z[j]; + } + } + return true; +} + +/* +============ +idMatX::Inverse_UpdateRowColumn + + Updates the in-place inverse to obtain the inverse for the matrix: + + [ 0 a 0 ] + A + [ d b e ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] +============ +*/ +bool idMatX::Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r ) { + idVecX s; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + assert( r >= 0 && r < numRows && r < numColumns ); + assert( w[r] == 0.0f ); + + s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); + s.Zero(); + s[r] = 1.0f; + + if ( !Inverse_UpdateRankOne( v, s, 1.0f ) ) { + return false; + } + if ( !Inverse_UpdateRankOne( s, w, 1.0f ) ) { + return false; + } + return true; +} + +/* +============ +idMatX::Inverse_UpdateIncrement + + Updates the in-place inverse to obtain the inverse for the matrix: + + [ A a ] + [ c b ] + + where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 +============ +*/ +bool idMatX::Inverse_UpdateIncrement( const idVecX &v, const idVecX &w ) { + idVecX v2; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + assert( w.GetSize() >= numColumns+1 ); + + ChangeSize( numRows+1, numColumns+1, true ); + (*this)[numRows-1][numRows-1] = 1.0f; + + v2.SetData( numRows, VECX_ALLOCA( numRows ) ); + v2 = v; + v2[numRows-1] -= 1.0f; + + return Inverse_UpdateRowColumn( v2, w, numRows-1 ); +} + +/* +============ +idMatX::Inverse_UpdateDecrement + + Updates the in-place inverse to obtain the inverse of the matrix with row r and column r removed. + v and w should store the column and row of the original matrix respectively. +============ +*/ +bool idMatX::Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r ) { + idVecX v1, w1; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( w.GetSize() >= numColumns ); + assert( r >= 0 && r < numRows && r < numColumns ); + + v1.SetData( numRows, VECX_ALLOCA( numRows ) ); + w1.SetData( numRows, VECX_ALLOCA( numRows ) ); + + // update the row and column to identity + v1 = -v; + w1 = -w; + v1[r] += 1.0f; + w1[r] = 0.0f; + + if ( !Inverse_UpdateRowColumn( v1, w1, r ) ) { + return false; + } + + // physically remove the row and column + Update_Decrement( r ); + + return true; +} + +/* +============ +idMatX::Inverse_Solve + + Solve Ax = b with A inverted +============ +*/ +void idMatX::Inverse_Solve( idVecX &x, const idVecX &b ) const { + Multiply( x, b ); +} + +/* +============ +idMatX::LU_Factor + + in-place factorization: LU + L is a triangular matrix stored in the lower triangle. + L has ones on the diagonal that are not stored. + U is a triangular matrix stored in the upper triangle. + If index != NULL partial pivoting is used for numerical stability. + If index != NULL it must point to an array of numRow integers and is used to keep track of the row permutation. + If det != NULL the determinant of the matrix is calculated and stored. +============ +*/ +bool idMatX::LU_Factor( int *index, float *det ) { + int i, j, k, newi, min; + double s, t, d, w; + + // if partial pivoting should be used + if ( index ) { + for ( i = 0; i < numRows; i++ ) { + index[i] = i; + } + } + + w = 1.0f; + min = Min( numRows, numColumns ); + for ( i = 0; i < min; i++ ) { + + newi = i; + s = idMath::Fabs( (*this)[i][i] ); + + if ( index ) { + // find the largest absolute pivot + for ( j = i + 1; j < numRows; j++ ) { + t = idMath::Fabs( (*this)[j][i] ); + if ( t > s ) { + newi = j; + s = t; + } + } + } + + if ( s == 0.0f ) { + return false; + } + + if ( newi != i ) { + + w = -w; + + // swap index elements + k = index[i]; + index[i] = index[newi]; + index[newi] = k; + + // swap rows + for ( j = 0; j < numColumns; j++ ) { + t = (*this)[newi][j]; + (*this)[newi][j] = (*this)[i][j]; + (*this)[i][j] = t; + } + } + + if ( i < numRows ) { + d = 1.0f / (*this)[i][i]; + for ( j = i + 1; j < numRows; j++ ) { + (*this)[j][i] *= d; + } + } + + if ( i < min-1 ) { + for ( j = i + 1; j < numRows; j++ ) { + d = (*this)[j][i]; + for ( k = i + 1; k < numColumns; k++ ) { + (*this)[j][k] -= d * (*this)[i][k]; + } + } + } + } + + if ( det ) { + for ( i = 0; i < numRows; i++ ) { + w *= (*this)[i][i]; + } + *det = w; + } + + return true; +} + +/* +============ +idMatX::LU_UpdateRankOne + + Updates the in-place LU factorization to obtain the factors for the matrix: LU + alpha * v * w' +============ +*/ +bool idMatX::LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index ) { + int i, j, max; + float *y, *z; + double diag, beta, p0, p1, d; + + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + + y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); + z = (float *) _alloca16( w.GetSize() * sizeof( float ) ); + + if ( index != NULL ) { + for ( i = 0; i < numRows; i++ ) { + y[i] = alpha * v[index[i]]; + } + } else { + for ( i = 0; i < numRows; i++ ) { + y[i] = alpha * v[i]; + } + } + + memcpy( z, w.ToFloatPtr(), w.GetSize() * sizeof( float ) ); + + max = Min( numRows, numColumns ); + for ( i = 0; i < max; i++ ) { + diag = (*this)[i][i]; + + p0 = y[i]; + p1 = z[i]; + diag += p0 * p1; + + if ( diag == 0.0f ) { + return false; + } + + beta = p1 / diag; + + (*this)[i][i] = diag; + + for ( j = i+1; j < numColumns; j++ ) { + + d = (*this)[i][j]; + + d += p0 * z[j]; + z[j] -= beta * d; + + (*this)[i][j] = d; + } + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i]; + + y[j] -= p0 * d; + d += beta * y[j]; + + (*this)[j][i] = d; + } + } + return true; +} + +/* +============ +idMatX::LU_UpdateRowColumn + + Updates the in-place LU factorization to obtain the factors for the matrix: + + [ 0 a 0 ] + LU + [ d b e ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] +============ +*/ +bool idMatX::LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index ) { +#if 0 + + idVecX s; + + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + assert( r >= 0 && r < numRows && r < numColumns ); + assert( w[r] == 0.0f ); + + s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); + s.Zero(); + s[r] = 1.0f; + + if ( !LU_UpdateRankOne( v, s, 1.0f, index ) ) { + return false; + } + if ( !LU_UpdateRankOne( s, w, 1.0f, index ) ) { + return false; + } + return true; + +#else + + int i, j, min, max, rp; + float *y0, *y1, *z0, *z1; + double diag, beta0, beta1, p0, p1, q0, q1, d; + + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + assert( r >= 0 && r < numColumns && r < numRows ); + assert( w[r] == 0.0f ); + + y0 = (float *) _alloca16( v.GetSize() * sizeof( float ) ); + z0 = (float *) _alloca16( w.GetSize() * sizeof( float ) ); + y1 = (float *) _alloca16( v.GetSize() * sizeof( float ) ); + z1 = (float *) _alloca16( w.GetSize() * sizeof( float ) ); + + if ( index != NULL ) { + for ( i = 0; i < numRows; i++ ) { + y0[i] = v[index[i]]; + } + rp = r; + for ( i = 0; i < numRows; i++ ) { + if ( index[i] == r ) { + rp = i; + break; + } + } + } else { + memcpy( y0, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); + rp = r; + } + + memset( y1, 0, v.GetSize() * sizeof( float ) ); + y1[rp] = 1.0f; + + memset( z0, 0, w.GetSize() * sizeof( float ) ); + z0[r] = 1.0f; + + memcpy( z1, w.ToFloatPtr(), w.GetSize() * sizeof( float ) ); + + // update the beginning of the to be updated row and column + min = Min( r, rp ); + for ( i = 0; i < min; i++ ) { + p0 = y0[i]; + beta1 = z1[i] / (*this)[i][i]; + + (*this)[i][r] += p0; + for ( j = i+1; j < numColumns; j++ ) { + z1[j] -= beta1 * (*this)[i][j]; + } + for ( j = i+1; j < numRows; j++ ) { + y0[j] -= p0 * (*this)[j][i]; + } + (*this)[rp][i] += beta1; + } + + // update the lower right corner starting at r,r + max = Min( numRows, numColumns ); + for ( i = min; i < max; i++ ) { + diag = (*this)[i][i]; + + p0 = y0[i]; + p1 = z0[i]; + diag += p0 * p1; + + if ( diag == 0.0f ) { + return false; + } + + beta0 = p1 / diag; + + q0 = y1[i]; + q1 = z1[i]; + diag += q0 * q1; + + if ( diag == 0.0f ) { + return false; + } + + beta1 = q1 / diag; + + (*this)[i][i] = diag; + + for ( j = i+1; j < numColumns; j++ ) { + + d = (*this)[i][j]; + + d += p0 * z0[j]; + z0[j] -= beta0 * d; + + d += q0 * z1[j]; + z1[j] -= beta1 * d; + + (*this)[i][j] = d; + } + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i]; + + y0[j] -= p0 * d; + d += beta0 * y0[j]; + + y1[j] -= q0 * d; + d += beta1 * y1[j]; + + (*this)[j][i] = d; + } + } + return true; + +#endif +} + +/* +============ +idMatX::LU_UpdateIncrement + + Updates the in-place LU factorization to obtain the factors for the matrix: + + [ A a ] + [ c b ] + + where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 +============ +*/ +bool idMatX::LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index ) { + int i, j; + float sum; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + assert( w.GetSize() >= numColumns+1 ); + + ChangeSize( numRows+1, numColumns+1, true ); + + // add row to L + for ( i = 0; i < numRows - 1; i++ ) { + sum = w[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[numRows - 1][j] * (*this)[j][i]; + } + (*this)[numRows - 1 ][i] = sum / (*this)[i][i]; + } + + // add row to the permutation index + if ( index != NULL ) { + index[numRows - 1] = numRows - 1; + } + + // add column to U + for ( i = 0; i < numRows; i++ ) { + if ( index != NULL ) { + sum = v[index[i]]; + } else { + sum = v[i]; + } + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * (*this)[j][numRows - 1]; + } + (*this)[i][numRows - 1] = sum; + } + + return true; +} + +/* +============ +idMatX::LU_UpdateDecrement + + Updates the in-place LU factorization to obtain the factors for the matrix with row r and column r removed. + v and w should store the column and row of the original matrix respectively. + If index != NULL then u should store row index[r] of the original matrix. If index == NULL then u = w. +============ +*/ +bool idMatX::LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index ) { + int i, p; + idVecX v1, w1; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + assert( r >= 0 && r < numRows && r < numColumns ); + + v1.SetData( numRows, VECX_ALLOCA( numRows ) ); + w1.SetData( numRows, VECX_ALLOCA( numRows ) ); + + if ( index != NULL ) { + + // find the pivot row + for ( p = i = 0; i < numRows; i++ ) { + if ( index[i] == r ) { + p = i; + break; + } + } + + // update the row and column to identity + v1 = -v; + w1 = -u; + + if ( p != r ) { + idSwap( v1[index[r]], v1[index[p]] ); + idSwap( index[r], index[p] ); + } + + v1[r] += 1.0f; + w1[r] = 0.0f; + + if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) { + return false; + } + + if ( p != r ) { + + if ( idMath::Fabs( u[p] ) < 1e-4f ) { + // NOTE: an additional row interchange is required for numerical stability + } + + // move row index[r] of the original matrix to row index[p] of the original matrix + v1.Zero(); + v1[index[p]] = 1.0f; + w1 = u - w; + + if ( !LU_UpdateRankOne( v1, w1, 1.0f, index ) ) { + return false; + } + } + + // remove the row from the permutation index + for ( i = r; i < numRows - 1; i++ ) { + index[i] = index[i+1]; + } + for ( i = 0; i < numRows - 1; i++ ) { + if ( index[i] > r ) { + index[i]--; + } + } + + } else { + + v1 = -v; + w1 = -w; + v1[r] += 1.0f; + w1[r] = 0.0f; + + if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) { + return false; + } + } + + // physically remove the row and column + Update_Decrement( r ); + + return true; +} + +/* +============ +idMatX::LU_Solve + + Solve Ax = b with A factored in-place as: LU +============ +*/ +void idMatX::LU_Solve( idVecX &x, const idVecX &b, const int *index ) const { + int i, j; + double sum; + + assert( x.GetSize() == numColumns && b.GetSize() == numRows ); + + // solve L + for ( i = 0; i < numRows; i++ ) { + if ( index != NULL ) { + sum = b[index[i]]; + } else { + sum = b[i]; + } + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum; + } + + // solve U + for ( i = numRows - 1; i >= 0; i-- ) { + sum = x[i]; + for ( j = i + 1; j < numRows; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum / (*this)[i][i]; + } +} + +/* +============ +idMatX::LU_Inverse + + Calculates the inverse of the matrix which is factored in-place as LU +============ +*/ +void idMatX::LU_Inverse( idMatX &inv, const int *index ) const { + int i, j; + idVecX x, b; + + assert( numRows == numColumns ); + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + inv.SetSize( numRows, numColumns ); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + LU_Solve( x, b, index ); + for ( j = 0; j < numRows; j++ ) { + inv[j][i] = x[j]; + } + b[i] = 0.0f; + } +} + +/* +============ +idMatX::LU_UnpackFactors + + Unpacks the in-place LU factorization. +============ +*/ +void idMatX::LU_UnpackFactors( idMatX &L, idMatX &U ) const { + int i, j; + + L.Zero( numRows, numColumns ); + U.Zero( numRows, numColumns ); + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < i; j++ ) { + L[i][j] = (*this)[i][j]; + } + L[i][i] = 1.0f; + for ( j = i; j < numColumns; j++ ) { + U[i][j] = (*this)[i][j]; + } + } +} + +/* +============ +idMatX::LU_MultiplyFactors + + Multiplies the factors of the in-place LU factorization to form the original matrix. +============ +*/ +void idMatX::LU_MultiplyFactors( idMatX &m, const int *index ) const { + int r, rp, i, j; + double sum; + + m.SetSize( numRows, numColumns ); + + for ( r = 0; r < numRows; r++ ) { + + if ( index != NULL ) { + rp = index[r]; + } else { + rp = r; + } + + // calculate row of matrix + for ( i = 0; i < numColumns; i++ ) { + if ( i >= r ) { + sum = (*this)[r][i]; + } else { + sum = 0.0f; + } + for ( j = 0; j <= i && j < r; j++ ) { + sum += (*this)[r][j] * (*this)[j][i]; + } + m[rp][i] = sum; + } + } +} + +/* +============ +idMatX::QR_Factor + + in-place factorization: QR + Q is an orthogonal matrix represented as a product of Householder matrices stored in the lower triangle and c. + R is a triangular matrix stored in the upper triangle except for the diagonal elements which are stored in d. + The initial matrix has to be square. +============ +*/ +bool idMatX::QR_Factor( idVecX &c, idVecX &d ) { + int i, j, k; + double scale, s, t, sum; + bool singular = false; + + assert( numRows == numColumns ); + assert( c.GetSize() >= numRows && d.GetSize() >= numRows ); + + for ( k = 0; k < numRows-1; k++ ) { + + scale = 0.0f; + for ( i = k; i < numRows; i++ ) { + s = idMath::Fabs( (*this)[i][k] ); + if ( s > scale ) { + scale = s; + } + } + if ( scale == 0.0f ) { + singular = true; + c[k] = d[k] = 0.0f; + } else { + + s = 1.0f / scale; + for ( i = k; i < numRows; i++ ) { + (*this)[i][k] *= s; + } + + sum = 0.0f; + for ( i = k; i < numRows; i++ ) { + s = (*this)[i][k]; + sum += s * s; + } + + s = idMath::Sqrt( sum ); + if ( (*this)[k][k] < 0.0f ) { + s = -s; + } + (*this)[k][k] += s; + c[k] = s * (*this)[k][k]; + d[k] = -scale * s; + + for ( j = k+1; j < numRows; j++ ) { + + sum = 0.0f; + for ( i = k; i < numRows; i++ ) { + sum += (*this)[i][k] * (*this)[i][j]; + } + t = sum / c[k]; + for ( i = k; i < numRows; i++ ) { + (*this)[i][j] -= t * (*this)[i][k]; + } + } + } + } + d[numRows-1] = (*this)[ (numRows-1) ][ (numRows-1) ]; + if ( d[numRows-1] == 0.0f ) { + singular = true; + } + + return !singular; +} + +/* +============ +idMatX::QR_Rotate + + Performs a Jacobi rotation on the rows i and i+1 of the unpacked QR factors. +============ +*/ +void idMatX::QR_Rotate( idMatX &R, int i, float a, float b ) { + int j; + float f, c, s, w, y; + + if ( a == 0.0f ) { + c = 0.0f; + s = ( b >= 0.0f ) ? 1.0f : -1.0f; + } else if ( idMath::Fabs( a ) > idMath::Fabs( b ) ) { + f = b / a; + c = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) ); + if ( a < 0.0f ) { + c = -c; + } + s = f * c; + } else { + f = a / b; + s = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) ); + if ( b < 0.0f ) { + s = -s; + } + c = f * s; + } + for ( j = i; j < numRows; j++ ) { + y = R[i][j]; + w = R[i+1][j]; + R[i][j] = c * y - s * w; + R[i+1][j] = s * y + c * w; + } + for ( j = 0; j < numRows; j++ ) { + y = (*this)[j][i]; + w = (*this)[j][i+1]; + (*this)[j][i] = c * y - s * w; + (*this)[j][i+1] = s * y + c * w; + } +} + +/* +============ +idMatX::QR_UpdateRankOne + + Updates the unpacked QR factorization to obtain the factors for the matrix: QR + alpha * v * w' +============ +*/ +bool idMatX::QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha ) { + int i, k; + float f; + idVecX u; + + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + + u.SetData( v.GetSize(), VECX_ALLOCA( v.GetSize() ) ); + TransposeMultiply( u, v ); + u *= alpha; + + for ( k = v.GetSize()-1; k > 0; k-- ) { + if ( u[k] != 0.0f ) { + break; + } + } + for ( i = k-1; i >= 0; i-- ) { + QR_Rotate( R, i, u[i], -u[i+1] ); + if ( u[i] == 0.0f ) { + u[i] = idMath::Fabs( u[i+1] ); + } else if ( idMath::Fabs( u[i] ) > idMath::Fabs( u[i+1] ) ) { + f = u[i+1] / u[i]; + u[i] = idMath::Fabs( u[i] ) * idMath::Sqrt( 1.0f + f * f ); + } else { + f = u[i] / u[i+1]; + u[i] = idMath::Fabs( u[i+1] ) * idMath::Sqrt( 1.0f + f * f ); + } + } + for ( i = 0; i < v.GetSize(); i++ ) { + R[0][i] += u[0] * w[i]; + } + for ( i = 0; i < k; i++ ) { + QR_Rotate( R, i, -R[i][i], R[i+1][i] ); + } + return true; +} + +/* +============ +idMatX::QR_UpdateRowColumn + + Updates the unpacked QR factorization to obtain the factors for the matrix: + + [ 0 a 0 ] + QR + [ d b e ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] +============ +*/ +bool idMatX::QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r ) { + idVecX s; + + assert( v.GetSize() >= numColumns ); + assert( w.GetSize() >= numRows ); + assert( r >= 0 && r < numRows && r < numColumns ); + assert( w[r] == 0.0f ); + + s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); + s.Zero(); + s[r] = 1.0f; + + if ( !QR_UpdateRankOne( R, v, s, 1.0f ) ) { + return false; + } + if ( !QR_UpdateRankOne( R, s, w, 1.0f ) ) { + return false; + } + return true; +} + +/* +============ +idMatX::QR_UpdateIncrement + + Updates the unpacked QR factorization to obtain the factors for the matrix: + + [ A a ] + [ c b ] + + where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 +============ +*/ +bool idMatX::QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w ) { + idVecX v2; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + assert( w.GetSize() >= numColumns+1 ); + + ChangeSize( numRows+1, numColumns+1, true ); + (*this)[numRows-1][numRows-1] = 1.0f; + + R.ChangeSize( R.numRows+1, R.numColumns+1, true ); + R[R.numRows-1][R.numRows-1] = 1.0f; + + v2.SetData( numRows, VECX_ALLOCA( numRows ) ); + v2 = v; + v2[numRows-1] -= 1.0f; + + return QR_UpdateRowColumn( R, v2, w, numRows-1 ); +} + +/* +============ +idMatX::QR_UpdateDecrement + + Updates the unpacked QR factorization to obtain the factors for the matrix with row r and column r removed. + v and w should store the column and row of the original matrix respectively. +============ +*/ +bool idMatX::QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r ) { + idVecX v1, w1; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( w.GetSize() >= numColumns ); + assert( r >= 0 && r < numRows && r < numColumns ); + + v1.SetData( numRows, VECX_ALLOCA( numRows ) ); + w1.SetData( numRows, VECX_ALLOCA( numRows ) ); + + // update the row and column to identity + v1 = -v; + w1 = -w; + v1[r] += 1.0f; + w1[r] = 0.0f; + + if ( !QR_UpdateRowColumn( R, v1, w1, r ) ) { + return false; + } + + // physically remove the row and column + Update_Decrement( r ); + R.Update_Decrement( r ); + + return true; +} + +/* +============ +idMatX::QR_Solve + + Solve Ax = b with A factored in-place as: QR +============ +*/ +void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const { + int i, j; + double sum, t; + + assert( numRows == numColumns ); + assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); + assert( c.GetSize() >= numRows && d.GetSize() >= numRows ); + + for ( i = 0; i < numRows; i++ ) { + x[i] = b[i]; + } + + // multiply b with transpose of Q + for ( i = 0; i < numRows-1; i++ ) { + + sum = 0.0f; + for ( j = i; j < numRows; j++ ) { + sum += (*this)[j][i] * x[j]; + } + t = sum / c[i]; + for ( j = i; j < numRows; j++ ) { + x[j] -= t * (*this)[j][i]; + } + } + + // backsubstitution with R + for ( i = numRows-1; i >= 0; i-- ) { + + sum = x[i]; + for ( j = i + 1; j < numRows; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum / d[i]; + } +} + +/* +============ +idMatX::QR_Solve + + Solve Ax = b with A factored as: QR +============ +*/ +void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const { + int i, j; + double sum; + + assert( numRows == numColumns ); + + // multiply b with transpose of Q + TransposeMultiply( x, b ); + + // backsubstitution with R + for ( i = numRows-1; i >= 0; i-- ) { + + sum = x[i]; + for ( j = i + 1; j < numRows; j++ ) { + sum -= R[i][j] * x[j]; + } + x[i] = sum / R[i][i]; + } +} + +/* +============ +idMatX::QR_Inverse + + Calculates the inverse of the matrix which is factored in-place as: QR +============ +*/ +void idMatX::QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const { + int i, j; + idVecX x, b; + + assert( numRows == numColumns ); + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + inv.SetSize( numRows, numColumns ); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + QR_Solve( x, b, c, d ); + for ( j = 0; j < numRows; j++ ) { + inv[j][i] = x[j]; + } + b[i] = 0.0f; + } +} + +/* +============ +idMatX::QR_UnpackFactors + + Unpacks the in-place QR factorization. +============ +*/ +void idMatX::QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const { + int i, j, k; + double sum; + + Q.Identity( numRows, numColumns ); + for ( i = 0; i < numColumns-1; i++ ) { + if ( c[i] == 0.0f ) { + continue; + } + for ( j = 0; j < numRows; j++ ) { + sum = 0.0f; + for ( k = i; k < numColumns; k++ ) { + sum += (*this)[k][i] * Q[j][k]; + } + sum /= c[i]; + for ( k = i; k < numColumns; k++ ) { + Q[j][k] -= sum * (*this)[k][i]; + } + } + } + + R.Zero( numRows, numColumns ); + for ( i = 0; i < numRows; i++ ) { + R[i][i] = d[i]; + for ( j = i+1; j < numColumns; j++ ) { + R[i][j] = (*this)[i][j]; + } + } +} + +/* +============ +idMatX::QR_MultiplyFactors + + Multiplies the factors of the in-place QR factorization to form the original matrix. +============ +*/ +void idMatX::QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const { + int i, j, k; + double sum; + idMatX Q; + + Q.Identity( numRows, numColumns ); + for ( i = 0; i < numColumns-1; i++ ) { + if ( c[i] == 0.0f ) { + continue; + } + for ( j = 0; j < numRows; j++ ) { + sum = 0.0f; + for ( k = i; k < numColumns; k++ ) { + sum += (*this)[k][i] * Q[j][k]; + } + sum /= c[i]; + for ( k = i; k < numColumns; k++ ) { + Q[j][k] -= sum * (*this)[k][i]; + } + } + } + + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + sum = Q[i][j] * d[i]; + for ( k = 0; k < i; k++ ) { + sum += Q[i][k] * (*this)[j][k]; + } + m[i][j] = sum; + } + } +} + +/* +============ +idMatX::Pythag + + Computes (a^2 + b^2)^1/2 without underflow or overflow. +============ +*/ +float idMatX::Pythag( float a, float b ) const { + double at, bt, ct; + + at = idMath::Fabs( a ); + bt = idMath::Fabs( b ); + if ( at > bt ) { + ct = bt / at; + return at * idMath::Sqrt( 1.0f + ct * ct ); + } else { + if ( bt ) { + ct = at / bt; + return bt * idMath::Sqrt( 1.0f + ct * ct ); + } else { + return 0.0f; + } + } +} + +/* +============ +idMatX::SVD_BiDiag +============ +*/ +void idMatX::SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm ) { + int i, j, k, l; + double f, h, r, g, s, scale; + + anorm = 0.0f; + g = s = scale = 0.0f; + for ( i = 0; i < numColumns; i++ ) { + l = i + 1; + rv1[i] = scale * g; + g = s = scale = 0.0f; + if ( i < numRows ) { + for ( k = i; k < numRows; k++ ) { + scale += idMath::Fabs( (*this)[k][i] ); + } + if ( scale ) { + for ( k = i; k < numRows; k++ ) { + (*this)[k][i] /= scale; + s += (*this)[k][i] * (*this)[k][i]; + } + f = (*this)[i][i]; + g = idMath::Sqrt( s ); + if ( f >= 0.0f ) { + g = -g; + } + h = f * g - s; + (*this)[i][i] = f - g; + if ( i != (numColumns-1) ) { + for ( j = l; j < numColumns; j++ ) { + for ( s = 0.0f, k = i; k < numRows; k++ ) { + s += (*this)[k][i] * (*this)[k][j]; + } + f = s / h; + for ( k = i; k < numRows; k++ ) { + (*this)[k][j] += f * (*this)[k][i]; + } + } + } + for ( k = i; k < numRows; k++ ) { + (*this)[k][i] *= scale; + } + } + } + w[i] = scale * g; + g = s = scale = 0.0f; + if ( i < numRows && i != (numColumns-1) ) { + for ( k = l; k < numColumns; k++ ) { + scale += idMath::Fabs( (*this)[i][k] ); + } + if ( scale ) { + for ( k = l; k < numColumns; k++ ) { + (*this)[i][k] /= scale; + s += (*this)[i][k] * (*this)[i][k]; + } + f = (*this)[i][l]; + g = idMath::Sqrt( s ); + if ( f >= 0.0f ) { + g = -g; + } + h = 1.0f / ( f * g - s ); + (*this)[i][l] = f - g; + for ( k = l; k < numColumns; k++ ) { + rv1[k] = (*this)[i][k] * h; + } + if ( i != (numRows-1) ) { + for ( j = l; j < numRows; j++ ) { + for ( s = 0.0f, k = l; k < numColumns; k++ ) { + s += (*this)[j][k] * (*this)[i][k]; + } + for ( k = l; k < numColumns; k++ ) { + (*this)[j][k] += s * rv1[k]; + } + } + } + for ( k = l; k < numColumns; k++ ) { + (*this)[i][k] *= scale; + } + } + } + r = idMath::Fabs( w[i] ) + idMath::Fabs( rv1[i] ); + if ( r > anorm ) { + anorm = r; + } + } +} + +/* +============ +idMatX::SVD_InitialWV +============ +*/ +void idMatX::SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 ) { + int i, j, k, l; + double f, g, s; + + g = 0.0f; + for ( i = (numColumns-1); i >= 0; i-- ) { + l = i + 1; + if ( i < ( numColumns - 1 ) ) { + if ( g ) { + for ( j = l; j < numColumns; j++ ) { + V[j][i] = ((*this)[i][j] / (*this)[i][l]) / g; + } + // double division to reduce underflow + for ( j = l; j < numColumns; j++ ) { + for ( s = 0.0f, k = l; k < numColumns; k++ ) { + s += (*this)[i][k] * V[k][j]; + } + for ( k = l; k < numColumns; k++ ) { + V[k][j] += s * V[k][i]; + } + } + } + for ( j = l; j < numColumns; j++ ) { + V[i][j] = V[j][i] = 0.0f; + } + } + V[i][i] = 1.0f; + g = rv1[i]; + } + for ( i = numColumns - 1 ; i >= 0; i-- ) { + l = i + 1; + g = w[i]; + if ( i < (numColumns-1) ) { + for ( j = l; j < numColumns; j++ ) { + (*this)[i][j] = 0.0f; + } + } + if ( g ) { + g = 1.0f / g; + if ( i != (numColumns-1) ) { + for ( j = l; j < numColumns; j++ ) { + for ( s = 0.0f, k = l; k < numRows; k++ ) { + s += (*this)[k][i] * (*this)[k][j]; + } + f = (s / (*this)[i][i]) * g; + for ( k = i; k < numRows; k++ ) { + (*this)[k][j] += f * (*this)[k][i]; + } + } + } + for ( j = i; j < numRows; j++ ) { + (*this)[j][i] *= g; + } + } + else { + for ( j = i; j < numRows; j++ ) { + (*this)[j][i] = 0.0f; + } + } + (*this)[i][i] += 1.0f; + } +} + +/* +============ +idMatX::SVD_Factor + + in-place factorization: U * Diag(w) * V.Transpose() + known as the Singular Value Decomposition. + U is a column-orthogonal matrix which overwrites the original matrix. + w is a diagonal matrix with all elements >= 0 which are the singular values. + V is the transpose of an orthogonal matrix. +============ +*/ +bool idMatX::SVD_Factor( idVecX &w, idMatX &V ) { + int flag, i, its, j, jj, k, l, nm; + double c, f, h, s, x, y, z, r, g = 0.0f; + float anorm = 0.0f; + idVecX rv1; + + if ( numRows < numColumns ) { + return false; + } + + rv1.SetData( numColumns, VECX_ALLOCA( numColumns ) ); + rv1.Zero(); + w.Zero( numColumns ); + V.Zero( numColumns, numColumns ); + + SVD_BiDiag( w, rv1, anorm ); + SVD_InitialWV( w, V, rv1 ); + + for ( k = numColumns - 1; k >= 0; k-- ) { + for ( its = 1; its <= 30; its++ ) { + flag = 1; + nm = 0; + for ( l = k; l >= 0; l-- ) { + nm = l - 1; + if ( ( idMath::Fabs( rv1[l] ) + anorm ) == anorm /* idMath::Fabs( rv1[l] ) < idMath::FLT_EPSILON */ ) { + flag = 0; + break; + } + if ( ( idMath::Fabs( w[nm] ) + anorm ) == anorm /* idMath::Fabs( w[nm] ) < idMath::FLT_EPSILON */ ) { + break; + } + } + if ( flag ) { + c = 0.0f; + s = 1.0f; + for ( i = l; i <= k; i++ ) { + f = s * rv1[i]; + + if ( ( idMath::Fabs( f ) + anorm ) != anorm /* idMath::Fabs( f ) > idMath::FLT_EPSILON */ ) { + g = w[i]; + h = Pythag( f, g ); + w[i] = h; + h = 1.0f / h; + c = g * h; + s = -f * h; + for ( j = 0; j < numRows; j++ ) { + y = (*this)[j][nm]; + z = (*this)[j][i]; + (*this)[j][nm] = y * c + z * s; + (*this)[j][i] = z * c - y * s; + } + } + } + } + z = w[k]; + if ( l == k ) { + if ( z < 0.0f ) { + w[k] = -z; + for ( j = 0; j < numColumns; j++ ) { + V[j][k] = -V[j][k]; + } + } + break; + } + if ( its == 30 ) { + return false; // no convergence + } + x = w[l]; + nm = k - 1; + y = w[nm]; + g = rv1[nm]; + h = rv1[k]; + f = ( ( y - z ) * ( y + z ) + ( g - h ) * ( g + h ) ) / ( 2.0f * h * y ); + g = Pythag( f, 1.0f ); + r = ( f >= 0.0f ? g : - g ); + f= ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + r ) ) - h ) ) / x; + c = s = 1.0f; + for ( j = l; j <= nm; j++ ) { + i = j + 1; + g = rv1[i]; + y = w[i]; + h = s * g; + g = c * g; + z = Pythag( f, h ); + rv1[j] = z; + c = f / z; + s = h / z; + f = x * c + g * s; + g = g * c - x * s; + h = y * s; + y = y * c; + for ( jj = 0; jj < numColumns; jj++ ) { + x = V[jj][j]; + z = V[jj][i]; + V[jj][j] = x * c + z * s; + V[jj][i] = z * c - x * s; + } + z = Pythag( f, h ); + w[j] = z; + if ( z ) { + z = 1.0f / z; + c = f * z; + s = h * z; + } + f = ( c * g ) + ( s * y ); + x = ( c * y ) - ( s * g ); + for ( jj = 0; jj < numRows; jj++ ) { + y = (*this)[jj][j]; + z = (*this)[jj][i]; + (*this)[jj][j] = y * c + z * s; + (*this)[jj][i] = z * c - y * s; + } + } + rv1[l] = 0.0f; + rv1[k] = f; + w[k] = x; + } + } + return true; +} + +/* +============ +idMatX::SVD_Solve + + Solve Ax = b with A factored as: U * Diag(w) * V.Transpose() +============ +*/ +void idMatX::SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const { + int i, j; + double sum; + idVecX tmp; + + assert( x.GetSize() >= numColumns ); + assert( b.GetSize() >= numColumns ); + assert( w.GetSize() == numColumns ); + assert( V.GetNumRows() == numColumns && V.GetNumColumns() == numColumns ); + + tmp.SetData( numColumns, VECX_ALLOCA( numColumns ) ); + + for ( i = 0; i < numColumns; i++ ) { + sum = 0.0f; + if ( w[i] >= idMath::FLT_EPSILON ) { + for ( j = 0; j < numRows; j++ ) { + sum += (*this)[j][i] * b[j]; + } + sum /= w[i]; + } + tmp[i] = sum; + } + for ( i = 0; i < numColumns; i++ ) { + sum = 0.0f; + for ( j = 0; j < numColumns; j++ ) { + sum += V[i][j] * tmp[j]; + } + x[i] = sum; + } +} + +/* +============ +idMatX::SVD_Inverse + + Calculates the inverse of the matrix which is factored in-place as: U * Diag(w) * V.Transpose() +============ +*/ +void idMatX::SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const { + int i, j, k; + double wi, sum; + idMatX V2; + + assert( numRows == numColumns ); + + V2 = V; + + // V * [diag(1/w[i])] + for ( i = 0; i < numRows; i++ ) { + wi = w[i]; + wi = ( wi < idMath::FLT_EPSILON ) ? 0.0f : 1.0f / wi; + for ( j = 0; j < numColumns; j++ ) { + V2[j][i] *= wi; + } + } + + // V * [diag(1/w[i])] * Ut + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + sum = V2[i][0] * (*this)[j][0]; + for ( k = 1; k < numColumns; k++ ) { + sum += V2[i][k] * (*this)[j][k]; + } + inv[i][j] = sum; + } + } +} + +/* +============ +idMatX::SVD_MultiplyFactors + + Multiplies the factors of the in-place SVD factorization to form the original matrix. +============ +*/ +void idMatX::SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const { + int r, i, j; + double sum; + + m.SetSize( numRows, V.GetNumRows() ); + + for ( r = 0; r < numRows; r++ ) { + // calculate row of matrix + if ( w[r] >= idMath::FLT_EPSILON ) { + for ( i = 0; i < V.GetNumRows(); i++ ) { + sum = 0.0f; + for ( j = 0; j < numColumns; j++ ) { + sum += (*this)[r][j] * V[i][j]; + } + m[r][i] = sum * w[r]; + } + } else { + for ( i = 0; i < V.GetNumRows(); i++ ) { + m[r][i] = 0.0f; + } + } + } +} + +/* +============ +idMatX::Cholesky_Factor + + in-place Cholesky factorization: LL' + L is a triangular matrix stored in the lower triangle. + The upper triangle is not cleared. + The initial matrix has to be symmetric positive definite. +============ +*/ +bool idMatX::Cholesky_Factor( void ) { + int i, j, k; + float *invSqrt; + double sum; + + assert( numRows == numColumns ); + + invSqrt = (float *) _alloca16( numRows * sizeof( float ) ); + + for ( i = 0; i < numRows; i++ ) { + + for ( j = 0; j < i; j++ ) { + + sum = (*this)[i][j]; + for ( k = 0; k < j; k++ ) { + sum -= (*this)[i][k] * (*this)[j][k]; + } + (*this)[i][j] = sum * invSqrt[j]; + } + + sum = (*this)[i][i]; + for ( k = 0; k < i; k++ ) { + sum -= (*this)[i][k] * (*this)[i][k]; + } + + if ( sum <= 0.0f ) { + return false; + } + + invSqrt[i] = idMath::InvSqrt( sum ); + (*this)[i][i] = invSqrt[i] * sum; + } + return true; +} + +/* +============ +idMatX::Cholesky_UpdateRankOne + + Updates the in-place Cholesky factorization to obtain the factors for the matrix: LL' + alpha * v * v' + If offset > 0 only the lower right corner starting at (offset, offset) is updated. +============ +*/ +bool idMatX::Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset ) { + int i, j; + float *y; + double diag, invDiag, diagSqr, newDiag, newDiagSqr, beta, p, d; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( offset >= 0 && offset < numRows ); + + y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); + memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); + + for ( i = offset; i < numColumns; i++ ) { + p = y[i]; + diag = (*this)[i][i]; + invDiag = 1.0f / diag; + diagSqr = diag * diag; + newDiagSqr = diagSqr + alpha * p * p; + + if ( newDiagSqr <= 0.0f ) { + return false; + } + + (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr ); + + alpha /= newDiagSqr; + beta = p * alpha; + alpha *= diagSqr; + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i] * invDiag; + + y[j] -= p * d; + d += beta * y[j]; + + (*this)[j][i] = d * newDiag; + } + } + return true; +} + +/* +============ +idMatX::Cholesky_UpdateRowColumn + + Updates the in-place Cholesky factorization to obtain the factors for the matrix: + + [ 0 a 0 ] + LL' + [ a b c ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] +============ +*/ +#pragma optimize( "", off ) + +bool idMatX::Cholesky_UpdateRowColumn( const idVecX &v, int r ) { + int i, j; + double sum; + float *original, *y; + idVecX addSub; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( r >= 0 && r < numRows ); + + addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + + if ( r == 0 ) { + + if ( numColumns == 1 ) { + double v0 = v[0]; + sum = (*this)[0][0]; + sum = sum * sum; + sum = sum + v0; + if ( sum <= 0.0f ) { + return false; + } + (*this)[0][0] = idMath::Sqrt( sum ); + return true; + } + for ( i = 0; i < numColumns; i++ ) { + addSub[i] = v[i]; + } + + } else { + + original = (float *) _alloca16( numColumns * sizeof( float ) ); + y = (float *) _alloca16( numColumns * sizeof( float ) ); + + // calculate original row/column of matrix + for ( i = 0; i < numRows; i++ ) { + sum = 0.0f; + for ( j = 0; j <= i; j++ ) { + sum += (*this)[r][j] * (*this)[i][j]; + } + original[i] = sum; + } + + // solve for y in L * y = original + v + for ( i = 0; i < r; i++ ) { + sum = original[i] + v[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[r][j] * (*this)[i][j]; + } + (*this)[r][i] = sum / (*this)[i][i]; + } + + // if the last row/column of the matrix is updated + if ( r == numColumns - 1 ) { + // only calculate new diagonal + sum = original[r] + v[r]; + for ( j = 0; j < r; j++) { + sum -= (*this)[r][j] * (*this)[r][j]; + } + if ( sum <= 0.0f ) { + return false; + } + (*this)[r][r] = idMath::Sqrt( sum ); + return true; + } + + // calculate the row/column to be added to the lower right sub matrix starting at (r, r) + for ( i = r; i < numColumns; i++ ) { + sum = 0.0f; + for ( j = 0; j <= r; j++ ) { + sum += (*this)[r][j] * (*this)[i][j]; + } + addSub[i] = v[i] - ( sum - original[i] ); + } + } + + // add row/column to the lower right sub matrix starting at (r, r) + +#if 0 + + idVecX v1, v2; + double d; + + v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + + d = idMath::SQRT_1OVER2; + v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; + v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; + for ( i = r+1; i < numColumns; i++ ) { + v1[i] = v2[i] = addSub[i] * d; + } + + // update + if ( !Cholesky_UpdateRankOne( v1, 1.0f, r ) ) { + return false; + } + // downdate + if ( !Cholesky_UpdateRankOne( v2, -1.0f, r ) ) { + return false; + } + +#else + + float *v1, *v2; + double diag, invDiag, diagSqr, newDiag, newDiagSqr; + double alpha1, alpha2, beta1, beta2, p1, p2, d; + + v1 = (float *) _alloca16( numColumns * sizeof( float ) ); + v2 = (float *) _alloca16( numColumns * sizeof( float ) ); + + d = idMath::SQRT_1OVER2; + v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; + v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; + for ( i = r+1; i < numColumns; i++ ) { + v1[i] = v2[i] = addSub[i] * d; + } + + alpha1 = 1.0f; + alpha2 = -1.0f; + + // simultaneous update/downdate of the sub matrix starting at (r, r) + for ( i = r; i < numColumns; i++ ) { + p1 = v1[i]; + diag = (*this)[i][i]; + invDiag = 1.0f / diag; + diagSqr = diag * diag; + newDiagSqr = diagSqr + alpha1 * p1 * p1; + + if ( newDiagSqr <= 0.0f ) { + return false; + } + + alpha1 /= newDiagSqr; + beta1 = p1 * alpha1; + alpha1 *= diagSqr; + + p2 = v2[i]; + diagSqr = newDiagSqr; + newDiagSqr = diagSqr + alpha2 * p2 * p2; + + if ( newDiagSqr <= 0.0f ) { + return false; + } + + (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr ); + + alpha2 /= newDiagSqr; + beta2 = p2 * alpha2; + alpha2 *= diagSqr; + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i] * invDiag; + + v1[j] -= p1 * d; + d += beta1 * v1[j]; + + v2[j] -= p2 * d; + d += beta2 * v2[j]; + + (*this)[j][i] = d * newDiag; + } + } + +#endif + + return true; +} + +#pragma optimize( "", off ) + +/* +============ +idMatX::Cholesky_UpdateIncrement + + Updates the in-place Cholesky factorization to obtain the factors for the matrix: + + [ A a ] + [ a b ] + + where: a = v[0,numRows-1], b = v[numRows] +============ +*/ +bool idMatX::Cholesky_UpdateIncrement( const idVecX &v ) { + int i, j; + float *x; + double sum; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + + ChangeSize( numRows+1, numColumns+1, false ); + + x = (float *) _alloca16( numRows * sizeof( float ) ); + + // solve for x in L * x = v + for ( i = 0; i < numRows - 1; i++ ) { + sum = v[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum / (*this)[i][i]; + } + + // calculate new row of L and calculate the square of the diagonal entry + sum = v[numRows - 1]; + for ( i = 0; i < numRows - 1; i++ ) { + (*this)[numRows - 1][i] = x[i]; + sum -= x[i] * x[i]; + } + + if ( sum <= 0.0f ) { + return false; + } + + // store the diagonal entry + (*this)[numRows - 1][numRows - 1] = idMath::Sqrt( sum ); + + return true; +} + +/* +============ +idMatX::Cholesky_UpdateDecrement + + Updates the in-place Cholesky factorization to obtain the factors for the matrix with row r and column r removed. + v should store the row of the original matrix. +============ +*/ +bool idMatX::Cholesky_UpdateDecrement( const idVecX &v, int r ) { + idVecX v1; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( r >= 0 && r < numRows ); + + v1.SetData( numRows, VECX_ALLOCA( numRows ) ); + + // update the row and column to identity + v1 = -v; + v1[r] += 1.0f; + + // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay + // untouched when calling Cholesky_UpdateRowColumn in the if statement +#if 0 + if ( !Cholesky_UpdateRowColumn( v1, r ) ) { +#else + bool ret = Cholesky_UpdateRowColumn( v1, r ); + if ( !ret ) { +#endif + return false; + } + + // physically remove the row and column + Update_Decrement( r ); + + return true; +} + +/* +============ +idMatX::Cholesky_Solve + + Solve Ax = b with A factored in-place as: LL' +============ +*/ +void idMatX::Cholesky_Solve( idVecX &x, const idVecX &b ) const { + int i, j; + double sum; + + assert( numRows == numColumns ); + assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); + + // solve L + for ( i = 0; i < numRows; i++ ) { + sum = b[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum / (*this)[i][i]; + } + + // solve Lt + for ( i = numRows - 1; i >= 0; i-- ) { + sum = x[i]; + for ( j = i + 1; j < numRows; j++ ) { + sum -= (*this)[j][i] * x[j]; + } + x[i] = sum / (*this)[i][i]; + } +} + +/* +============ +idMatX::Cholesky_Inverse + + Calculates the inverse of the matrix which is factored in-place as: LL' +============ +*/ +void idMatX::Cholesky_Inverse( idMatX &inv ) const { + int i, j; + idVecX x, b; + + assert( numRows == numColumns ); + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + inv.SetSize( numRows, numColumns ); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + Cholesky_Solve( x, b ); + for ( j = 0; j < numRows; j++ ) { + inv[j][i] = x[j]; + } + b[i] = 0.0f; + } +} + +/* +============ +idMatX::Cholesky_MultiplyFactors + + Multiplies the factors of the in-place Cholesky factorization to form the original matrix. +============ +*/ +void idMatX::Cholesky_MultiplyFactors( idMatX &m ) const { + int r, i, j; + double sum; + + m.SetSize( numRows, numColumns ); + + for ( r = 0; r < numRows; r++ ) { + + // calculate row of matrix + for ( i = 0; i < numRows; i++ ) { + sum = 0.0f; + for ( j = 0; j <= i && j <= r; j++ ) { + sum += (*this)[r][j] * (*this)[i][j]; + } + m[r][i] = sum; + } + } +} + +/* +============ +idMatX::LDLT_Factor + + in-place factorization: LDL' + L is a triangular matrix stored in the lower triangle. + L has ones on the diagonal that are not stored. + D is a diagonal matrix stored on the diagonal. + The upper triangle is not cleared. + The initial matrix has to be symmetric. +============ +*/ +bool idMatX::LDLT_Factor( void ) { + int i, j, k; + float *v; + double d, sum; + + assert( numRows == numColumns ); + + v = (float *) _alloca16( numRows * sizeof( float ) ); + + for ( i = 0; i < numRows; i++ ) { + + sum = (*this)[i][i]; + for ( j = 0; j < i; j++ ) { + d = (*this)[i][j]; + v[j] = (*this)[j][j] * d; + sum -= v[j] * d; + } + + if ( sum == 0.0f ) { + return false; + } + + (*this)[i][i] = sum; + d = 1.0f / sum; + + for ( j = i + 1; j < numRows; j++ ) { + sum = (*this)[j][i]; + for ( k = 0; k < i; k++ ) { + sum -= (*this)[j][k] * v[k]; + } + (*this)[j][i] = sum * d; + } + } + + return true; +} + +/* +============ +idMatX::LDLT_UpdateRankOne + + Updates the in-place LDL' factorization to obtain the factors for the matrix: LDL' + alpha * v * v' + If offset > 0 only the lower right corner starting at (offset, offset) is updated. +============ +*/ +bool idMatX::LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset ) { + int i, j; + float *y; + double diag, newDiag, beta, p, d; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( offset >= 0 && offset < numRows ); + + y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); + memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); + + for ( i = offset; i < numColumns; i++ ) { + p = y[i]; + diag = (*this)[i][i]; + (*this)[i][i] = newDiag = diag + alpha * p * p; + + if ( newDiag == 0.0f ) { + return false; + } + + alpha /= newDiag; + beta = p * alpha; + alpha *= diag; + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i]; + + y[j] -= p * d; + d += beta * y[j]; + + (*this)[j][i] = d; + } + } + + return true; +} + +/* +============ +idMatX::LDLT_UpdateRowColumn + + Updates the in-place LDL' factorization to obtain the factors for the matrix: + + [ 0 a 0 ] + LDL' + [ a b c ] + [ 0 c 0 ] + + where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] +============ +*/ +bool idMatX::LDLT_UpdateRowColumn( const idVecX &v, int r ) { + int i, j; + double sum; + float *original, *y; + idVecX addSub; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( r >= 0 && r < numRows ); + + addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + + if ( r == 0 ) { + + if ( numColumns == 1 ) { + (*this)[0][0] += v[0]; + return true; + } + for ( i = 0; i < numColumns; i++ ) { + addSub[i] = v[i]; + } + + } else { + + original = (float *) _alloca16( numColumns * sizeof( float ) ); + y = (float *) _alloca16( numColumns * sizeof( float ) ); + + // calculate original row/column of matrix + for ( i = 0; i < r; i++ ) { + y[i] = (*this)[r][i] * (*this)[i][i]; + } + for ( i = 0; i < numColumns; i++ ) { + if ( i < r ) { + sum = (*this)[i][i] * (*this)[r][i]; + } else if ( i == r ) { + sum = (*this)[r][r]; + } else { + sum = (*this)[r][r] * (*this)[i][r]; + } + for ( j = 0; j < i && j < r; j++ ) { + sum += (*this)[i][j] * y[j]; + } + original[i] = sum; + } + + // solve for y in L * y = original + v + for ( i = 0; i < r; i++ ) { + sum = original[i] + v[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * y[j]; + } + y[i] = sum; + } + + // calculate new row of L + for ( i = 0; i < r; i++ ) { + (*this)[r][i] = y[i] / (*this)[i][i]; + } + + // if the last row/column of the matrix is updated + if ( r == numColumns - 1 ) { + // only calculate new diagonal + sum = original[r] + v[r]; + for ( j = 0; j < r; j++ ) { + sum -= (*this)[r][j] * y[j]; + } + if ( sum == 0.0f ) { + return false; + } + (*this)[r][r] = sum; + return true; + } + + // calculate the row/column to be added to the lower right sub matrix starting at (r, r) + for ( i = 0; i < r; i++ ) { + y[i] = (*this)[r][i] * (*this)[i][i]; + } + for ( i = r; i < numColumns; i++ ) { + if ( i == r ) { + sum = (*this)[r][r]; + } else { + sum = (*this)[r][r] * (*this)[i][r]; + } + for ( j = 0; j < r; j++ ) { + sum += (*this)[i][j] * y[j]; + } + addSub[i] = v[i] - ( sum - original[i] ); + } + } + + // add row/column to the lower right sub matrix starting at (r, r) + +#if 0 + + idVecX v1, v2; + double d; + + v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); + + d = idMath::SQRT_1OVER2; + v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; + v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; + for ( i = r+1; i < numColumns; i++ ) { + v1[i] = v2[i] = addSub[i] * d; + } + + // update + if ( !LDLT_UpdateRankOne( v1, 1.0f, r ) ) { + return false; + } + // downdate + if ( !LDLT_UpdateRankOne( v2, -1.0f, r ) ) { + return false; + } + +#else + + float *v1, *v2; + double d, diag, newDiag, p1, p2, alpha1, alpha2, beta1, beta2; + + v1 = (float *) _alloca16( numColumns * sizeof( float ) ); + v2 = (float *) _alloca16( numColumns * sizeof( float ) ); + + d = idMath::SQRT_1OVER2; + v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; + v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; + for ( i = r+1; i < numColumns; i++ ) { + v1[i] = v2[i] = addSub[i] * d; + } + + alpha1 = 1.0f; + alpha2 = -1.0f; + + // simultaneous update/downdate of the sub matrix starting at (r, r) + for ( i = r; i < numColumns; i++ ) { + + diag = (*this)[i][i]; + p1 = v1[i]; + newDiag = diag + alpha1 * p1 * p1; + + if ( newDiag == 0.0f ) { + return false; + } + + alpha1 /= newDiag; + beta1 = p1 * alpha1; + alpha1 *= diag; + + diag = newDiag; + p2 = v2[i]; + newDiag = diag + alpha2 * p2 * p2; + + if ( newDiag == 0.0f ) { + return false; + } + + alpha2 /= newDiag; + beta2 = p2 * alpha2; + alpha2 *= diag; + + (*this)[i][i] = newDiag; + + for ( j = i+1; j < numRows; j++ ) { + + d = (*this)[j][i]; + + v1[j] -= p1 * d; + d += beta1 * v1[j]; + + v2[j] -= p2 * d; + d += beta2 * v2[j]; + + (*this)[j][i] = d; + } + } + +#endif + + return true; +} + +/* +============ +idMatX::LDLT_UpdateIncrement + + Updates the in-place LDL' factorization to obtain the factors for the matrix: + + [ A a ] + [ a b ] + + where: a = v[0,numRows-1], b = v[numRows] +============ +*/ +bool idMatX::LDLT_UpdateIncrement( const idVecX &v ) { + int i, j; + float *x; + double sum, d; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows+1 ); + + ChangeSize( numRows+1, numColumns+1, false ); + + x = (float *) _alloca16( numRows * sizeof( float ) ); + + // solve for x in L * x = v + for ( i = 0; i < numRows - 1; i++ ) { + sum = v[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum; + } + + // calculate new row of L and calculate the diagonal entry + sum = v[numRows - 1]; + for ( i = 0; i < numRows - 1; i++ ) { + (*this)[numRows - 1][i] = d = x[i] / (*this)[i][i]; + sum -= d * x[i]; + } + + if ( sum == 0.0f ) { + return false; + } + + // store the diagonal entry + (*this)[numRows - 1][numRows - 1] = sum; + + return true; +} + +/* +============ +idMatX::LDLT_UpdateDecrement + + Updates the in-place LDL' factorization to obtain the factors for the matrix with row r and column r removed. + v should store the row of the original matrix. +============ +*/ +bool idMatX::LDLT_UpdateDecrement( const idVecX &v, int r ) { + idVecX v1; + + assert( numRows == numColumns ); + assert( v.GetSize() >= numRows ); + assert( r >= 0 && r < numRows ); + + v1.SetData( numRows, VECX_ALLOCA( numRows ) ); + + // update the row and column to identity + v1 = -v; + v1[r] += 1.0f; + + // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay + // untouched when calling LDLT_UpdateRowColumn in the if statement +#if 0 + if ( !LDLT_UpdateRowColumn( v1, r ) ) { +#else + bool ret = LDLT_UpdateRowColumn( v1, r ); + if ( !ret ) { +#endif + return false; + } + + // physically remove the row and column + Update_Decrement( r ); + + return true; +} + +/* +============ +idMatX::LDLT_Solve + + Solve Ax = b with A factored in-place as: LDL' +============ +*/ +void idMatX::LDLT_Solve( idVecX &x, const idVecX &b ) const { + int i, j; + double sum; + + assert( numRows == numColumns ); + assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); + + // solve L + for ( i = 0; i < numRows; i++ ) { + sum = b[i]; + for ( j = 0; j < i; j++ ) { + sum -= (*this)[i][j] * x[j]; + } + x[i] = sum; + } + + // solve D + for ( i = 0; i < numRows; i++ ) { + x[i] /= (*this)[i][i]; + } + + // solve Lt + for ( i = numRows - 2; i >= 0; i-- ) { + sum = x[i]; + for ( j = i + 1; j < numRows; j++ ) { + sum -= (*this)[j][i] * x[j]; + } + x[i] = sum; + } +} + +/* +============ +idMatX::LDLT_Inverse + + Calculates the inverse of the matrix which is factored in-place as: LDL' +============ +*/ +void idMatX::LDLT_Inverse( idMatX &inv ) const { + int i, j; + idVecX x, b; + + assert( numRows == numColumns ); + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + inv.SetSize( numRows, numColumns ); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + LDLT_Solve( x, b ); + for ( j = 0; j < numRows; j++ ) { + inv[j][i] = x[j]; + } + b[i] = 0.0f; + } +} + +/* +============ +idMatX::LDLT_UnpackFactors + + Unpacks the in-place LDL' factorization. +============ +*/ +void idMatX::LDLT_UnpackFactors( idMatX &L, idMatX &D ) const { + int i, j; + + L.Zero( numRows, numColumns ); + D.Zero( numRows, numColumns ); + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < i; j++ ) { + L[i][j] = (*this)[i][j]; + } + L[i][i] = 1.0f; + D[i][i] = (*this)[i][i]; + } +} + +/* +============ +idMatX::LDLT_MultiplyFactors + + Multiplies the factors of the in-place LDL' factorization to form the original matrix. +============ +*/ +void idMatX::LDLT_MultiplyFactors( idMatX &m ) const { + int r, i, j; + float *v; + double sum; + + v = (float *) _alloca16( numRows * sizeof( float ) ); + m.SetSize( numRows, numColumns ); + + for ( r = 0; r < numRows; r++ ) { + + // calculate row of matrix + for ( i = 0; i < r; i++ ) { + v[i] = (*this)[r][i] * (*this)[i][i]; + } + for ( i = 0; i < numColumns; i++ ) { + if ( i < r ) { + sum = (*this)[i][i] * (*this)[r][i]; + } else if ( i == r ) { + sum = (*this)[r][r]; + } else { + sum = (*this)[r][r] * (*this)[i][r]; + } + for ( j = 0; j < i && j < r; j++ ) { + sum += (*this)[i][j] * v[j]; + } + m[r][i] = sum; + } + } +} + +/* +============ +idMatX::TriDiagonal_ClearTriangles +============ +*/ +void idMatX::TriDiagonal_ClearTriangles( void ) { + int i, j; + + assert( numRows == numColumns ); + for ( i = 0; i < numRows-2; i++ ) { + for ( j = i+2; j < numColumns; j++ ) { + (*this)[i][j] = 0.0f; + (*this)[j][i] = 0.0f; + } + } +} + +/* +============ +idMatX::TriDiagonal_Solve + + Solve Ax = b with A being tridiagonal. +============ +*/ +bool idMatX::TriDiagonal_Solve( idVecX &x, const idVecX &b ) const { + int i; + float d; + idVecX tmp; + + assert( numRows == numColumns ); + assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); + + tmp.SetData( numRows, VECX_ALLOCA( numRows ) ); + + d = (*this)[0][0]; + if ( d == 0.0f ) { + return false; + } + d = 1.0f / d; + x[0] = b[0] * d; + for ( i = 1; i < numRows; i++ ) { + tmp[i] = (*this)[i-1][i] * d; + d = (*this)[i][i] - (*this)[i][i-1] * tmp[i]; + if ( d == 0.0f ) { + return false; + } + d = 1.0f / d; + x[i] = ( b[i] - (*this)[i][i-1] * x[i-1] ) * d; + } + for ( i = numRows - 2; i >= 0; i-- ) { + x[i] -= tmp[i+1] * x[i+1]; + } + return true; +} + +/* +============ +idMatX::TriDiagonal_Inverse + + Calculates the inverse of a tri-diagonal matrix. +============ +*/ +void idMatX::TriDiagonal_Inverse( idMatX &inv ) const { + int i, j; + idVecX x, b; + + assert( numRows == numColumns ); + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + inv.SetSize( numRows, numColumns ); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + TriDiagonal_Solve( x, b ); + for ( j = 0; j < numRows; j++ ) { + inv[j][i] = x[j]; + } + b[i] = 0.0f; + } +} + +/* +============ +idMatX::HouseholderReduction + + Householder reduction to symmetric tri-diagonal form. + The original matrix is replaced by an orthogonal matrix effecting the accumulated householder transformations. + The diagonal elements of the diagonal matrix are stored in diag. + The off-diagonal elements of the diagonal matrix are stored in subd. + The initial matrix has to be symmetric. +============ +*/ +void idMatX::HouseholderReduction( idVecX &diag, idVecX &subd ) { + int i0, i1, i2, i3; + float h, f, g, invH, halfFdivH, scale, invScale, sum; + + assert( numRows == numColumns ); + + diag.SetSize( numRows ); + subd.SetSize( numRows ); + + for ( i0 = numRows-1, i3 = numRows-2; i0 >= 1; i0--, i3-- ) { + h = 0.0f; + scale = 0.0f; + + if ( i3 > 0 ) { + for ( i2 = 0; i2 <= i3; i2++ ) { + scale += idMath::Fabs( (*this)[i0][i2] ); + } + if ( scale == 0 ) { + subd[i0] = (*this)[i0][i3]; + } else { + invScale = 1.0f / scale; + for (i2 = 0; i2 <= i3; i2++) + { + (*this)[i0][i2] *= invScale; + h += (*this)[i0][i2] * (*this)[i0][i2]; + } + f = (*this)[i0][i3]; + g = idMath::Sqrt( h ); + if ( f > 0.0f ) { + g = -g; + } + subd[i0] = scale * g; + h -= f * g; + (*this)[i0][i3] = f - g; + f = 0.0f; + invH = 1.0f / h; + for (i1 = 0; i1 <= i3; i1++) { + (*this)[i1][i0] = (*this)[i0][i1] * invH; + g = 0.0f; + for (i2 = 0; i2 <= i1; i2++) { + g += (*this)[i1][i2] * (*this)[i0][i2]; + } + for (i2 = i1+1; i2 <= i3; i2++) { + g += (*this)[i2][i1] * (*this)[i0][i2]; + } + subd[i1] = g * invH; + f += subd[i1] * (*this)[i0][i1]; + } + halfFdivH = 0.5f * f * invH; + for ( i1 = 0; i1 <= i3; i1++ ) { + f = (*this)[i0][i1]; + g = subd[i1] - halfFdivH * f; + subd[i1] = g; + for ( i2 = 0; i2 <= i1; i2++ ) { + (*this)[i1][i2] -= f * subd[i2] + g * (*this)[i0][i2]; + } + } + } + } else { + subd[i0] = (*this)[i0][i3]; + } + + diag[i0] = h; + } + + diag[0] = 0.0f; + subd[0] = 0.0f; + for ( i0 = 0, i3 = -1; i0 <= numRows-1; i0++, i3++ ) { + if ( diag[i0] ) { + for ( i1 = 0; i1 <= i3; i1++ ) { + sum = 0.0f; + for (i2 = 0; i2 <= i3; i2++) { + sum += (*this)[i0][i2] * (*this)[i2][i1]; + } + for ( i2 = 0; i2 <= i3; i2++ ) { + (*this)[i2][i1] -= sum * (*this)[i2][i0]; + } + } + } + diag[i0] = (*this)[i0][i0]; + (*this)[i0][i0] = 1.0f; + for ( i1 = 0; i1 <= i3; i1++ ) { + (*this)[i1][i0] = 0.0f; + (*this)[i0][i1] = 0.0f; + } + } + + // re-order + for ( i0 = 1, i3 = 0; i0 < numRows; i0++, i3++ ) { + subd[i3] = subd[i0]; + } + subd[numRows-1] = 0.0f; +} + +/* +============ +idMatX::QL + + QL algorithm with implicit shifts to determine the eigenvalues and eigenvectors of a symmetric tri-diagonal matrix. + diag contains the diagonal elements of the symmetric tri-diagonal matrix on input and is overwritten with the eigenvalues. + subd contains the off-diagonal elements of the symmetric tri-diagonal matrix and is destroyed. + This matrix has to be either the identity matrix to determine the eigenvectors for a symmetric tri-diagonal matrix, + or the matrix returned by the Householder reduction to determine the eigenvalues for the original symmetric matrix. +============ +*/ +bool idMatX::QL( idVecX &diag, idVecX &subd ) { + const int maxIter = 32; + int i0, i1, i2, i3; + float a, b, f, g, r, p, s, c; + + assert( numRows == numColumns ); + + for ( i0 = 0; i0 < numRows; i0++ ) { + for ( i1 = 0; i1 < maxIter; i1++ ) { + for ( i2 = i0; i2 <= numRows - 2; i2++ ) { + a = idMath::Fabs( diag[i2] ) + idMath::Fabs( diag[i2+1] ); + if ( idMath::Fabs( subd[i2] ) + a == a ) { + break; + } + } + if ( i2 == i0 ) { + break; + } + + g = ( diag[i0+1] - diag[i0] ) / ( 2.0f * subd[i0] ); + r = idMath::Sqrt( g * g + 1.0f ); + if ( g < 0.0f ) { + g = diag[i2] - diag[i0] + subd[i0] / ( g - r ); + } else { + g = diag[i2] - diag[i0] + subd[i0] / ( g + r ); + } + s = 1.0f; + c = 1.0f; + p = 0.0f; + for ( i3 = i2 - 1; i3 >= i0; i3-- ) { + f = s * subd[i3]; + b = c * subd[i3]; + if ( idMath::Fabs( f ) >= idMath::Fabs( g ) ) { + c = g / f; + r = idMath::Sqrt( c * c + 1.0f ); + subd[i3+1] = f * r; + s = 1.0f / r; + c *= s; + } else { + s = f / g; + r = idMath::Sqrt( s * s + 1.0f ); + subd[i3+1] = g * r; + c = 1.0f / r; + s *= c; + } + g = diag[i3+1] - p; + r = ( diag[i3] - g ) * s + 2.0f * b * c; + p = s * r; + diag[i3+1] = g + p; + g = c * r - b; + + for ( int i4 = 0; i4 < numRows; i4++ ) { + f = (*this)[i4][i3+1]; + (*this)[i4][i3+1] = s * (*this)[i4][i3] + c * f; + (*this)[i4][i3] = c * (*this)[i4][i3] - s * f; + } + } + diag[i0] -= p; + subd[i0] = g; + subd[i2] = 0.0f; + } + if ( i1 == maxIter ) { + return false; + } + } + return true; +} + +/* +============ +idMatX::Eigen_SolveSymmetricTriDiagonal + + Determine eigen values and eigen vectors for a symmetric tri-diagonal matrix. + The eigen values are stored in 'eigenValues'. + Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i]. + The initial matrix has to be symmetric tri-diagonal. +============ +*/ +bool idMatX::Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues ) { + int i; + idVecX subd; + + assert( numRows == numColumns ); + + subd.SetData( numRows, VECX_ALLOCA( numRows ) ); + eigenValues.SetSize( numRows ); + + for ( i = 0; i < numRows-1; i++ ) { + eigenValues[i] = (*this)[i][i]; + subd[i] = (*this)[i+1][i]; + } + eigenValues[numRows-1] = (*this)[numRows-1][numRows-1]; + + Identity(); + + return QL( eigenValues, subd ); +} + +/* +============ +idMatX::Eigen_SolveSymmetric + + Determine eigen values and eigen vectors for a symmetric matrix. + The eigen values are stored in 'eigenValues'. + Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i]. + The initial matrix has to be symmetric. +============ +*/ +bool idMatX::Eigen_SolveSymmetric( idVecX &eigenValues ) { + idVecX subd; + + assert( numRows == numColumns ); + + subd.SetData( numRows, VECX_ALLOCA( numRows ) ); + eigenValues.SetSize( numRows ); + + HouseholderReduction( eigenValues, subd ); + return QL( eigenValues, subd ); +} + +/* +============ +idMatX::HessenbergReduction + + Reduction to Hessenberg form. +============ +*/ +void idMatX::HessenbergReduction( idMatX &H ) { + int i, j, m; + int low = 0; + int high = numRows - 1; + float scale, f, g, h; + idVecX v; + + v.SetData( numRows, VECX_ALLOCA( numRows ) ); + + for ( m = low + 1; m <= high - 1; m++ ) { + + scale = 0.0f; + for ( i = m; i <= high; i++ ) { + scale = scale + idMath::Fabs( H[i][m-1] ); + } + if ( scale != 0.0f ) { + + // compute Householder transformation. + h = 0.0f; + for ( i = high; i >= m; i-- ) { + v[i] = H[i][m-1] / scale; + h += v[i] * v[i]; + } + g = idMath::Sqrt( h ); + if ( v[m] > 0.0f ) { + g = -g; + } + h = h - v[m] * g; + v[m] = v[m] - g; + + // apply Householder similarity transformation + // H = (I-u*u'/h)*H*(I-u*u')/h) + for ( j = m; j < numRows; j++) { + f = 0.0f; + for ( i = high; i >= m; i-- ) { + f += v[i] * H[i][j]; + } + f = f / h; + for ( i = m; i <= high; i++ ) { + H[i][j] -= f * v[i]; + } + } + + for ( i = 0; i <= high; i++ ) { + f = 0.0f; + for ( j = high; j >= m; j-- ) { + f += v[j] * H[i][j]; + } + f = f / h; + for ( j = m; j <= high; j++ ) { + H[i][j] -= f * v[j]; + } + } + v[m] = scale * v[m]; + H[m][m-1] = scale * g; + } + } + + // accumulate transformations + Identity(); + for ( int m = high - 1; m >= low + 1; m-- ) { + if ( H[m][m-1] != 0.0f ) { + for ( i = m + 1; i <= high; i++ ) { + v[i] = H[i][m-1]; + } + for ( j = m; j <= high; j++ ) { + g = 0.0f; + for ( i = m; i <= high; i++ ) { + g += v[i] * (*this)[i][j]; + } + // float division to avoid possible underflow + g = ( g / v[m] ) / H[m][m-1]; + for ( i = m; i <= high; i++ ) { + (*this)[i][j] += g * v[i]; + } + } + } + } +} + +/* +============ +idMatX::ComplexDivision + + Complex scalar division. +============ +*/ +void idMatX::ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi ) { + float r, d; + if ( idMath::Fabs( yr ) > idMath::Fabs( yi ) ) { + r = yi / yr; + d = yr + r * yi; + cdivr = ( xr + r * xi ) / d; + cdivi = ( xi - r * xr ) / d; + } else { + r = yr / yi; + d = yi + r * yr; + cdivr = ( r * xr + xi ) / d; + cdivi = ( r * xi - xr ) / d; + } +} + +/* +============ +idMatX::HessenbergToRealSchur + + Reduction from Hessenberg to real Schur form. +============ +*/ +bool idMatX::HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues ) { + int i, j, k; + int n = numRows - 1; + int low = 0; + int high = numRows - 1; + float eps = 2e-16f, exshift = 0.0f; + float p = 0.0f, q = 0.0f, r = 0.0f, s = 0.0f, z = 0.0f, t, w, x, y; + + // store roots isolated by balanc and compute matrix norm + float norm = 0.0f; + for ( i = 0; i < numRows; i++ ) { + if ( i < low || i > high ) { + realEigenValues[i] = H[i][i]; + imaginaryEigenValues[i] = 0.0f; + } + for ( j = Max( i - 1, 0 ); j < numRows; j++ ) { + norm = norm + idMath::Fabs( H[i][j] ); + } + } + + int iter = 0; + while( n >= low ) { + + // look for single small sub-diagonal element + int l = n; + while ( l > low ) { + s = idMath::Fabs( H[l-1][l-1] ) + idMath::Fabs( H[l][l] ); + if ( s == 0.0f ) { + s = norm; + } + if ( idMath::Fabs( H[l][l-1] ) < eps * s ) { + break; + } + l--; + } + + // check for convergence + if ( l == n ) { // one root found + H[n][n] = H[n][n] + exshift; + realEigenValues[n] = H[n][n]; + imaginaryEigenValues[n] = 0.0f; + n--; + iter = 0; + } else if ( l == n-1 ) { // two roots found + w = H[n][n-1] * H[n-1][n]; + p = ( H[n-1][n-1] - H[n][n] ) / 2.0f; + q = p * p + w; + z = idMath::Sqrt( idMath::Fabs( q ) ); + H[n][n] = H[n][n] + exshift; + H[n-1][n-1] = H[n-1][n-1] + exshift; + x = H[n][n]; + + if ( q >= 0.0f ) { // real pair + if ( p >= 0.0f ) { + z = p + z; + } else { + z = p - z; + } + realEigenValues[n-1] = x + z; + realEigenValues[n] = realEigenValues[n-1]; + if ( z != 0.0f ) { + realEigenValues[n] = x - w / z; + } + imaginaryEigenValues[n-1] = 0.0f; + imaginaryEigenValues[n] = 0.0f; + x = H[n][n-1]; + s = idMath::Fabs( x ) + idMath::Fabs( z ); + p = x / s; + q = z / s; + r = idMath::Sqrt( p * p + q * q ); + p = p / r; + q = q / r; + + // modify row + for ( j = n-1; j < numRows; j++ ) { + z = H[n-1][j]; + H[n-1][j] = q * z + p * H[n][j]; + H[n][j] = q * H[n][j] - p * z; + } + + // modify column + for ( i = 0; i <= n; i++ ) { + z = H[i][n-1]; + H[i][n-1] = q * z + p * H[i][n]; + H[i][n] = q * H[i][n] - p * z; + } + + // accumulate transformations + for ( i = low; i <= high; i++ ) { + z = (*this)[i][n-1]; + (*this)[i][n-1] = q * z + p * (*this)[i][n]; + (*this)[i][n] = q * (*this)[i][n] - p * z; + } + } else { // complex pair + realEigenValues[n-1] = x + p; + realEigenValues[n] = x + p; + imaginaryEigenValues[n-1] = z; + imaginaryEigenValues[n] = -z; + } + n = n - 2; + iter = 0; + + } else { // no convergence yet + + // form shift + x = H[n][n]; + y = 0.0f; + w = 0.0f; + if ( l < n ) { + y = H[n-1][n-1]; + w = H[n][n-1] * H[n-1][n]; + } + + // Wilkinson's original ad hoc shift + if ( iter == 10 ) { + exshift += x; + for ( i = low; i <= n; i++ ) { + H[i][i] -= x; + } + s = idMath::Fabs( H[n][n-1] ) + idMath::Fabs( H[n-1][n-2] ); + x = y = 0.75f * s; + w = -0.4375f * s * s; + } + + // new ad hoc shift + if ( iter == 30 ) { + s = ( y - x ) / 2.0f; + s = s * s + w; + if ( s > 0 ) { + s = idMath::Sqrt( s ); + if ( y < x ) { + s = -s; + } + s = x - w / ( ( y - x ) / 2.0f + s ); + for ( i = low; i <= n; i++ ) { + H[i][i] -= s; + } + exshift += s; + x = y = w = 0.964f; + } + } + + iter = iter + 1; + + // look for two consecutive small sub-diagonal elements + int m; + for( m = n-2; m >= l; m-- ) { + z = H[m][m]; + r = x - z; + s = y - z; + p = ( r * s - w ) / H[m+1][m] + H[m][m+1]; + q = H[m+1][m+1] - z - r - s; + r = H[m+2][m+1]; + s = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r ); + p = p / s; + q = q / s; + r = r / s; + if ( m == l ) { + break; + } + if ( idMath::Fabs( H[m][m-1] ) * ( idMath::Fabs( q ) + idMath::Fabs( r ) ) < + eps * ( idMath::Fabs( p ) * ( idMath::Fabs( H[m-1][m-1] ) + idMath::Fabs( z ) + idMath::Fabs( H[m+1][m+1] ) ) ) ) { + break; + } + } + + for ( i = m+2; i <= n; i++ ) { + H[i][i-2] = 0.0f; + if ( i > m+2 ) { + H[i][i-3] = 0.0f; + } + } + + // double QR step involving rows l:n and columns m:n + for ( k = m; k <= n-1; k++ ) { + bool notlast = ( k != n-1 ); + if ( k != m ) { + p = H[k][k-1]; + q = H[k+1][k-1]; + r = ( notlast ? H[k+2][k-1] : 0.0f ); + x = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r ); + if ( x != 0.0f ) { + p = p / x; + q = q / x; + r = r / x; + } + } + if ( x == 0.0f ) { + break; + } + s = idMath::Sqrt( p * p + q * q + r * r ); + if ( p < 0.0f ) { + s = -s; + } + if ( s != 0.0f ) { + if ( k != m ) { + H[k][k-1] = -s * x; + } else if ( l != m ) { + H[k][k-1] = -H[k][k-1]; + } + p = p + s; + x = p / s; + y = q / s; + z = r / s; + q = q / p; + r = r / p; + + // modify row + for ( j = k; j < numRows; j++ ) { + p = H[k][j] + q * H[k+1][j]; + if ( notlast ) { + p = p + r * H[k+2][j]; + H[k+2][j] = H[k+2][j] - p * z; + } + H[k][j] = H[k][j] - p * x; + H[k+1][j] = H[k+1][j] - p * y; + } + + // modify column + for ( i = 0; i <= Min( n, k + 3 ); i++ ) { + p = x * H[i][k] + y * H[i][k+1]; + if ( notlast ) { + p = p + z * H[i][k+2]; + H[i][k+2] = H[i][k+2] - p * r; + } + H[i][k] = H[i][k] - p; + H[i][k+1] = H[i][k+1] - p * q; + } + + // accumulate transformations + for ( i = low; i <= high; i++ ) { + p = x * (*this)[i][k] + y * (*this)[i][k+1]; + if ( notlast ) { + p = p + z * (*this)[i][k+2]; + (*this)[i][k+2] = (*this)[i][k+2] - p * r; + } + (*this)[i][k] = (*this)[i][k] - p; + (*this)[i][k+1] = (*this)[i][k+1] - p * q; + } + } + } + } + } + + // backsubstitute to find vectors of upper triangular form + if ( norm == 0.0f ) { + return false; + } + + for ( n = numRows-1; n >= 0; n-- ) { + p = realEigenValues[n]; + q = imaginaryEigenValues[n]; + + if ( q == 0.0f ) { // real vector + int l = n; + H[n][n] = 1.0f; + for ( i = n-1; i >= 0; i-- ) { + w = H[i][i] - p; + r = 0.0f; + for ( j = l; j <= n; j++ ) { + r = r + H[i][j] * H[j][n]; + } + if ( imaginaryEigenValues[i] < 0.0f ) { + z = w; + s = r; + } else { + l = i; + if ( imaginaryEigenValues[i] == 0.0f ) { + if ( w != 0.0f ) { + H[i][n] = -r / w; + } else { + H[i][n] = -r / ( eps * norm ); + } + } else { // solve real equations + x = H[i][i+1]; + y = H[i+1][i]; + q = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i]; + t = ( x * s - z * r ) / q; + H[i][n] = t; + if ( idMath::Fabs(x) > idMath::Fabs( z ) ) { + H[i+1][n] = ( -r - w * t ) / x; + } else { + H[i+1][n] = ( -s - y * t ) / z; + } + } + + // overflow control + t = idMath::Fabs(H[i][n]); + if ( ( eps * t ) * t > 1 ) { + for ( j = i; j <= n; j++ ) { + H[j][n] = H[j][n] / t; + } + } + } + } + } else if ( q < 0.0f ) { // complex vector + int l = n-1; + + // last vector component imaginary so matrix is triangular + if ( idMath::Fabs( H[n][n-1] ) > idMath::Fabs( H[n-1][n] ) ) { + H[n-1][n-1] = q / H[n][n-1]; + H[n-1][n] = -( H[n][n] - p ) / H[n][n-1]; + } else { + ComplexDivision( 0.0f, -H[n-1][n], H[n-1][n-1]-p, q, H[n-1][n-1], H[n-1][n] ); + } + H[n][n-1] = 0.0f; + H[n][n] = 1.0f; + for ( i = n-2; i >= 0; i-- ) { + float ra, sa, vr, vi; + ra = 0.0f; + sa = 0.0f; + for ( j = l; j <= n; j++ ) { + ra = ra + H[i][j] * H[j][n-1]; + sa = sa + H[i][j] * H[j][n]; + } + w = H[i][i] - p; + + if ( imaginaryEigenValues[i] < 0.0f ) { + z = w; + r = ra; + s = sa; + } else { + l = i; + if ( imaginaryEigenValues[i] == 0.0f ) { + ComplexDivision( -ra, -sa, w, q, H[i][n-1], H[i][n] ); + } else { + // solve complex equations + x = H[i][i+1]; + y = H[i+1][i]; + vr = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i] - q * q; + vi = ( realEigenValues[i] - p ) * 2.0f * q; + if ( vr == 0.0f && vi == 0.0f ) { + vr = eps * norm * ( idMath::Fabs( w ) + idMath::Fabs( q ) + idMath::Fabs( x ) + idMath::Fabs( y ) + idMath::Fabs( z ) ); + } + ComplexDivision( x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi, H[i][n-1], H[i][n] ); + if ( idMath::Fabs( x ) > ( idMath::Fabs( z ) + idMath::Fabs( q ) ) ) { + H[i+1][n-1] = ( -ra - w * H[i][n-1] + q * H[i][n] ) / x; + H[i+1][n] = ( -sa - w * H[i][n] - q * H[i][n-1] ) / x; + } else { + ComplexDivision( -r - y * H[i][n-1], -s - y * H[i][n], z, q, H[i+1][n-1], H[i+1][n] ); + } + } + + // overflow control + t = Max( idMath::Fabs( H[i][n-1] ), idMath::Fabs( H[i][n] ) ); + if ( ( eps * t ) * t > 1 ) { + for ( j = i; j <= n; j++ ) { + H[j][n-1] = H[j][n-1] / t; + H[j][n] = H[j][n] / t; + } + } + } + } + } + } + + // vectors of isolated roots + for ( i = 0; i < numRows; i++ ) { + if ( i < low || i > high ) { + for ( j = i; j < numRows; j++ ) { + (*this)[i][j] = H[i][j]; + } + } + } + + // back transformation to get eigenvectors of original matrix + for ( j = numRows - 1; j >= low; j-- ) { + for ( i = low; i <= high; i++ ) { + z = 0.0f; + for ( k = low; k <= Min( j, high ); k++ ) { + z = z + (*this)[i][k] * H[k][j]; + } + (*this)[i][j] = z; + } + } + + return true; +} + +/* +============ +idMatX::Eigen_Solve + + Determine eigen values and eigen vectors for a square matrix. + The eigen values are stored in 'realEigenValues' and 'imaginaryEigenValues'. + Column i of the original matrix will store the eigen vector corresponding to the realEigenValues[i] and imaginaryEigenValues[i]. +============ +*/ +bool idMatX::Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues ) { + idMatX H; + + assert( numRows == numColumns ); + + realEigenValues.SetSize( numRows ); + imaginaryEigenValues.SetSize( numRows ); + + H = *this; + + // reduce to Hessenberg form + HessenbergReduction( H ); + + // reduce Hessenberg to real Schur form + return HessenbergToRealSchur( H, realEigenValues, imaginaryEigenValues ); +} + +/* +============ +idMatX::Eigen_SortIncreasing +============ +*/ +void idMatX::Eigen_SortIncreasing( idVecX &eigenValues ) { + int i, j, k; + float min; + + for ( i = 0; i <= numRows - 2; i++ ) { + j = i; + min = eigenValues[j]; + for ( k = i + 1; k < numRows; k++ ) { + if ( eigenValues[k] < min ) { + j = k; + min = eigenValues[j]; + } + } + if ( j != i ) { + eigenValues.SwapElements( i, j ); + SwapColumns( i, j ); + } + } +} + +/* +============ +idMatX::Eigen_SortDecreasing +============ +*/ +void idMatX::Eigen_SortDecreasing( idVecX &eigenValues ) { + int i, j, k; + float max; + + for ( i = 0; i <= numRows - 2; i++ ) { + j = i; + max = eigenValues[j]; + for ( k = i + 1; k < numRows; k++ ) { + if ( eigenValues[k] > max ) { + j = k; + max = eigenValues[j]; + } + } + if ( j != i ) { + eigenValues.SwapElements( i, j ); + SwapColumns( i, j ); + } + } +} + +/* +============ +idMatX::DeterminantGeneric +============ +*/ +float idMatX::DeterminantGeneric( void ) const { + int *index; + float det; + idMatX tmp; + + index = (int *) _alloca16( numRows * sizeof( int ) ); + tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); + tmp = *this; + + if ( !tmp.LU_Factor( index, &det ) ) { + return 0.0f; + } + + return det; +} + +/* +============ +idMatX::InverseSelfGeneric +============ +*/ +bool idMatX::InverseSelfGeneric( void ) { + int i, j, *index; + idMatX tmp; + idVecX x, b; + + index = (int *) _alloca16( numRows * sizeof( int ) ); + tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); + tmp = *this; + + if ( !tmp.LU_Factor( index ) ) { + return false; + } + + x.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.SetData( numRows, VECX_ALLOCA( numRows ) ); + b.Zero(); + + for ( i = 0; i < numRows; i++ ) { + + b[i] = 1.0f; + tmp.LU_Solve( x, b, index ); + for ( j = 0; j < numRows; j++ ) { + (*this)[j][i] = x[j]; + } + b[i] = 0.0f; + } + return true; +} + +/* +============ +idMatX::Test +============ +*/ +void idMatX::Test( void ) { + idMatX original, m1, m2, m3, q1, q2, r1, r2; + idVecX v, w, u, c, d; + int offset, size, *index1, *index2; + + size = 6; + original.Random( size, size, 0 ); + original = original * original.Transpose(); + + index1 = (int *) _alloca16( ( size + 1 ) * sizeof( index1[0] ) ); + index2 = (int *) _alloca16( ( size + 1 ) * sizeof( index2[0] ) ); + + /* + idMatX::LowerTriangularInverse + */ + + m1 = original; + m1.ClearUpperTriangle(); + m2 = m1; + + m2.InverseSelf(); + m1.LowerTriangularInverse(); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LowerTriangularInverse failed" ); + } + + /* + idMatX::UpperTriangularInverse + */ + + m1 = original; + m1.ClearLowerTriangle(); + m2 = m1; + + m2.InverseSelf(); + m1.UpperTriangularInverse(); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::UpperTriangularInverse failed" ); + } + + /* + idMatX::Inverse_GaussJordan + */ + + m1 = original; + + m1.Inverse_GaussJordan(); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::Inverse_GaussJordan failed" ); + } + + /* + idMatX::Inverse_UpdateRankOne + */ + + m1 = original; + m2 = original; + + w.Random( size, 1 ); + v.Random( size, 2 ); + + // invert m1 + m1.Inverse_GaussJordan(); + + // modify and invert m2 + m2.Update_RankOne( v, w, 1.0f ); + if ( !m2.Inverse_GaussJordan() ) { + assert( 0 ); + } + + // update inverse of m1 + m1.Inverse_UpdateRankOne( v, w, 1.0f ); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Inverse_UpdateRankOne failed" ); + } + + /* + idMatX::Inverse_UpdateRowColumn + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + v.Random( size, 1 ); + w.Random( size, 2 ); + w[offset] = 0.0f; + + // invert m1 + m1.Inverse_GaussJordan(); + + // modify and invert m2 + m2.Update_RowColumn( v, w, offset ); + if ( !m2.Inverse_GaussJordan() ) { + assert( 0 ); + } + + // update inverse of m1 + m1.Inverse_UpdateRowColumn( v, w, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::Inverse_UpdateRowColumn failed" ); + } + } + + /* + idMatX::Inverse_UpdateIncrement + */ + + m1 = original; + m2 = original; + + v.Random( size + 1, 1 ); + w.Random( size + 1, 2 ); + w[size] = 0.0f; + + // invert m1 + m1.Inverse_GaussJordan(); + + // modify and invert m2 + m2.Update_Increment( v, w ); + if ( !m2.Inverse_GaussJordan() ) { + assert( 0 ); + } + + // update inverse of m1 + m1.Inverse_UpdateIncrement( v, w ); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Inverse_UpdateIncrement failed" ); + } + + /* + idMatX::Inverse_UpdateDecrement + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + v.SetSize( 6 ); + w.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + v[i] = original[i][offset]; + w[i] = original[offset][i]; + } + + // invert m1 + m1.Inverse_GaussJordan(); + + // modify and invert m2 + m2.Update_Decrement( offset ); + if ( !m2.Inverse_GaussJordan() ) { + assert( 0 ); + } + + // update inverse of m1 + m1.Inverse_UpdateDecrement( v, w, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::Inverse_UpdateDecrement failed" ); + } + } + + /* + idMatX::LU_Factor + */ + + m1 = original; + + m1.LU_Factor( NULL ); // no pivoting + m1.LU_UnpackFactors( m2, m3 ); + m1 = m2 * m3; + + if ( !original.Compare( m1, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LU_Factor failed" ); + } + + /* + idMatX::LU_UpdateRankOne + */ + + m1 = original; + m2 = original; + + w.Random( size, 1 ); + v.Random( size, 2 ); + + // factor m1 + m1.LU_Factor( index1 ); + + // modify and factor m2 + m2.Update_RankOne( v, w, 1.0f ); + if ( !m2.LU_Factor( index2 ) ) { + assert( 0 ); + } + m2.LU_MultiplyFactors( m3, index2 ); + m2 = m3; + + // update factored m1 + m1.LU_UpdateRankOne( v, w, 1.0f, index1 ); + m1.LU_MultiplyFactors( m3, index1 ); + m1 = m3; + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LU_UpdateRankOne failed" ); + } + + /* + idMatX::LU_UpdateRowColumn + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + v.Random( size, 1 ); + w.Random( size, 2 ); + w[offset] = 0.0f; + + // factor m1 + m1.LU_Factor( index1 ); + + // modify and factor m2 + m2.Update_RowColumn( v, w, offset ); + if ( !m2.LU_Factor( index2 ) ) { + assert( 0 ); + } + m2.LU_MultiplyFactors( m3, index2 ); + m2 = m3; + + // update m1 + m1.LU_UpdateRowColumn( v, w, offset, index1 ); + m1.LU_MultiplyFactors( m3, index1 ); + m1 = m3; + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::LU_UpdateRowColumn failed" ); + } + } + + /* + idMatX::LU_UpdateIncrement + */ + + m1 = original; + m2 = original; + + v.Random( size + 1, 1 ); + w.Random( size + 1, 2 ); + w[size] = 0.0f; + + // factor m1 + m1.LU_Factor( index1 ); + + // modify and factor m2 + m2.Update_Increment( v, w ); + if ( !m2.LU_Factor( index2 ) ) { + assert( 0 ); + } + m2.LU_MultiplyFactors( m3, index2 ); + m2 = m3; + + // update factored m1 + m1.LU_UpdateIncrement( v, w, index1 ); + m1.LU_MultiplyFactors( m3, index1 ); + m1 = m3; + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LU_UpdateIncrement failed" ); + } + + /* + idMatX::LU_UpdateDecrement + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + v.SetSize( 6 ); + w.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + v[i] = original[i][offset]; + w[i] = original[offset][i]; + } + + // factor m1 + m1.LU_Factor( index1 ); + + // modify and factor m2 + m2.Update_Decrement( offset ); + if ( !m2.LU_Factor( index2 ) ) { + assert( 0 ); + } + m2.LU_MultiplyFactors( m3, index2 ); + m2 = m3; + + u.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + u[i] = original[index1[offset]][i]; + } + + // update factors of m1 + m1.LU_UpdateDecrement( v, w, u, offset, index1 ); + m1.LU_MultiplyFactors( m3, index1 ); + m1 = m3; + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::LU_UpdateDecrement failed" ); + } + } + + /* + idMatX::LU_Inverse + */ + + m2 = original; + + m2.LU_Factor( NULL ); + m2.LU_Inverse( m1, NULL ); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::LU_Inverse failed" ); + } + + /* + idMatX::QR_Factor + */ + + c.SetSize( size ); + d.SetSize( size ); + + m1 = original; + + m1.QR_Factor( c, d ); + m1.QR_UnpackFactors( q1, r1, c, d ); + m1 = q1 * r1; + + if ( !original.Compare( m1, 1e-4f ) ) { + idLib::common->Warning( "idMatX::QR_Factor failed" ); + } + + /* + idMatX::QR_UpdateRankOne + */ + + c.SetSize( size ); + d.SetSize( size ); + + m1 = original; + m2 = original; + + w.Random( size, 0 ); + v = w; + + // factor m1 + m1.QR_Factor( c, d ); + m1.QR_UnpackFactors( q1, r1, c, d ); + + // modify and factor m2 + m2.Update_RankOne( v, w, 1.0f ); + if ( !m2.QR_Factor( c, d ) ) { + assert( 0 ); + } + m2.QR_UnpackFactors( q2, r2, c, d ); + m2 = q2 * r2; + + // update factored m1 + q1.QR_UpdateRankOne( r1, v, w, 1.0f ); + m1 = q1 * r1; + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::QR_UpdateRankOne failed" ); + } + + /* + idMatX::QR_UpdateRowColumn + */ + + for ( offset = 0; offset < size; offset++ ) { + c.SetSize( size ); + d.SetSize( size ); + + m1 = original; + m2 = original; + + v.Random( size, 1 ); + w.Random( size, 2 ); + w[offset] = 0.0f; + + // factor m1 + m1.QR_Factor( c, d ); + m1.QR_UnpackFactors( q1, r1, c, d ); + + // modify and factor m2 + m2.Update_RowColumn( v, w, offset ); + if ( !m2.QR_Factor( c, d ) ) { + assert( 0 ); + } + m2.QR_UnpackFactors( q2, r2, c, d ); + m2 = q2 * r2; + + // update m1 + q1.QR_UpdateRowColumn( r1, v, w, offset ); + m1 = q1 * r1; + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::QR_UpdateRowColumn failed" ); + } + } + + /* + idMatX::QR_UpdateIncrement + */ + + c.SetSize( size+1 ); + d.SetSize( size+1 ); + + m1 = original; + m2 = original; + + v.Random( size + 1, 1 ); + w.Random( size + 1, 2 ); + w[size] = 0.0f; + + // factor m1 + m1.QR_Factor( c, d ); + m1.QR_UnpackFactors( q1, r1, c, d ); + + // modify and factor m2 + m2.Update_Increment( v, w ); + if ( !m2.QR_Factor( c, d ) ) { + assert( 0 ); + } + m2.QR_UnpackFactors( q2, r2, c, d ); + m2 = q2 * r2; + + // update factored m1 + q1.QR_UpdateIncrement( r1, v, w ); + m1 = q1 * r1; + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::QR_UpdateIncrement failed" ); + } + + /* + idMatX::QR_UpdateDecrement + */ + + for ( offset = 0; offset < size; offset++ ) { + c.SetSize( size+1 ); + d.SetSize( size+1 ); + + m1 = original; + m2 = original; + + v.SetSize( 6 ); + w.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + v[i] = original[i][offset]; + w[i] = original[offset][i]; + } + + // factor m1 + m1.QR_Factor( c, d ); + m1.QR_UnpackFactors( q1, r1, c, d ); + + // modify and factor m2 + m2.Update_Decrement( offset ); + if ( !m2.QR_Factor( c, d ) ) { + assert( 0 ); + } + m2.QR_UnpackFactors( q2, r2, c, d ); + m2 = q2 * r2; + + // update factors of m1 + q1.QR_UpdateDecrement( r1, v, w, offset ); + m1 = q1 * r1; + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::QR_UpdateDecrement failed" ); + } + } + + /* + idMatX::QR_Inverse + */ + + m2 = original; + + m2.QR_Factor( c, d ); + m2.QR_Inverse( m1, c, d ); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::QR_Inverse failed" ); + } + + /* + idMatX::SVD_Factor + */ + + m1 = original; + m3.Zero( size, size ); + w.Zero( size ); + + m1.SVD_Factor( w, m3 ); + m2.Diag( w ); + m3.TransposeSelf(); + m1 = m1 * m2 * m3; + + if ( !original.Compare( m1, 1e-4f ) ) { + idLib::common->Warning( "idMatX::SVD_Factor failed" ); + } + + /* + idMatX::SVD_Inverse + */ + + m2 = original; + + m2.SVD_Factor( w, m3 ); + m2.SVD_Inverse( m1, w, m3 ); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::SVD_Inverse failed" ); + } + + /* + idMatX::Cholesky_Factor + */ + + m1 = original; + + m1.Cholesky_Factor(); + m1.Cholesky_MultiplyFactors( m2 ); + + if ( !original.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Cholesky_Factor failed" ); + } + + /* + idMatX::Cholesky_UpdateRankOne + */ + + m1 = original; + m2 = original; + + w.Random( size, 0 ); + + // factor m1 + m1.Cholesky_Factor(); + m1.ClearUpperTriangle(); + + // modify and factor m2 + m2.Update_RankOneSymmetric( w, 1.0f ); + if ( !m2.Cholesky_Factor() ) { + assert( 0 ); + } + m2.ClearUpperTriangle(); + + // update factored m1 + m1.Cholesky_UpdateRankOne( w, 1.0f, 0 ); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Cholesky_UpdateRankOne failed" ); + } + + /* + idMatX::Cholesky_UpdateRowColumn + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + // factor m1 + m1.Cholesky_Factor(); + m1.ClearUpperTriangle(); + + int pdtable[] = { 1, 0, 1, 0, 0, 0 }; + w.Random( size, pdtable[offset] ); + w *= 0.1f; + + // modify and factor m2 + m2.Update_RowColumnSymmetric( w, offset ); + if ( !m2.Cholesky_Factor() ) { + assert( 0 ); + } + m2.ClearUpperTriangle(); + + // update m1 + m1.Cholesky_UpdateRowColumn( w, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::Cholesky_UpdateRowColumn failed" ); + } + } + + /* + idMatX::Cholesky_UpdateIncrement + */ + + m1.Random( size + 1, size + 1, 0 ); + m3 = m1 * m1.Transpose(); + + m1.SquareSubMatrix( m3, size ); + m2 = m1; + + w.SetSize( size + 1 ); + for ( int i = 0; i < size + 1; i++ ) { + w[i] = m3[size][i]; + } + + // factor m1 + m1.Cholesky_Factor(); + + // modify and factor m2 + m2.Update_IncrementSymmetric( w ); + if ( !m2.Cholesky_Factor() ) { + assert( 0 ); + } + + // update factored m1 + m1.Cholesky_UpdateIncrement( w ); + + m1.ClearUpperTriangle(); + m2.ClearUpperTriangle(); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Cholesky_UpdateIncrement failed" ); + } + + /* + idMatX::Cholesky_UpdateDecrement + */ + + for ( offset = 0; offset < size; offset += size - 1 ) { + m1 = original; + m2 = original; + + v.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + v[i] = original[i][offset]; + } + + // factor m1 + m1.Cholesky_Factor(); + + // modify and factor m2 + m2.Update_Decrement( offset ); + if ( !m2.Cholesky_Factor() ) { + assert( 0 ); + } + + // update factors of m1 + m1.Cholesky_UpdateDecrement( v, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::Cholesky_UpdateDecrement failed" ); + } + } + + /* + idMatX::Cholesky_Inverse + */ + + m2 = original; + + m2.Cholesky_Factor(); + m2.Cholesky_Inverse( m1 ); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::Cholesky_Inverse failed" ); + } + + /* + idMatX::LDLT_Factor + */ + + m1 = original; + + m1.LDLT_Factor(); + m1.LDLT_MultiplyFactors( m2 ); + + if ( !original.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LDLT_Factor failed" ); + } + + m1.LDLT_UnpackFactors( m2, m3 ); + m2 = m2 * m3 * m2.Transpose(); + + if ( !original.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LDLT_Factor failed" ); + } + + /* + idMatX::LDLT_UpdateRankOne + */ + + m1 = original; + m2 = original; + + w.Random( size, 0 ); + + // factor m1 + m1.LDLT_Factor(); + m1.ClearUpperTriangle(); + + // modify and factor m2 + m2.Update_RankOneSymmetric( w, 1.0f ); + if ( !m2.LDLT_Factor() ) { + assert( 0 ); + } + m2.ClearUpperTriangle(); + + // update factored m1 + m1.LDLT_UpdateRankOne( w, 1.0f, 0 ); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LDLT_UpdateRankOne failed" ); + } + + /* + idMatX::LDLT_UpdateRowColumn + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + w.Random( size, 0 ); + + // factor m1 + m1.LDLT_Factor(); + m1.ClearUpperTriangle(); + + // modify and factor m2 + m2.Update_RowColumnSymmetric( w, offset ); + if ( !m2.LDLT_Factor() ) { + assert( 0 ); + } + m2.ClearUpperTriangle(); + + // update m1 + m1.LDLT_UpdateRowColumn( w, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::LDLT_UpdateRowColumn failed" ); + } + } + + /* + idMatX::LDLT_UpdateIncrement + */ + + m1.Random( size + 1, size + 1, 0 ); + m3 = m1 * m1.Transpose(); + + m1.SquareSubMatrix( m3, size ); + m2 = m1; + + w.SetSize( size + 1 ); + for ( int i = 0; i < size + 1; i++ ) { + w[i] = m3[size][i]; + } + + // factor m1 + m1.LDLT_Factor(); + + // modify and factor m2 + m2.Update_IncrementSymmetric( w ); + if ( !m2.LDLT_Factor() ) { + assert( 0 ); + } + + // update factored m1 + m1.LDLT_UpdateIncrement( w ); + + m1.ClearUpperTriangle(); + m2.ClearUpperTriangle(); + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::LDLT_UpdateIncrement failed" ); + } + + /* + idMatX::LDLT_UpdateDecrement + */ + + for ( offset = 0; offset < size; offset++ ) { + m1 = original; + m2 = original; + + v.SetSize( 6 ); + for ( int i = 0; i < size; i++ ) { + v[i] = original[i][offset]; + } + + // factor m1 + m1.LDLT_Factor(); + + // modify and factor m2 + m2.Update_Decrement( offset ); + if ( !m2.LDLT_Factor() ) { + assert( 0 ); + } + + // update factors of m1 + m1.LDLT_UpdateDecrement( v, offset ); + + if ( !m1.Compare( m2, 1e-3f ) ) { + idLib::common->Warning( "idMatX::LDLT_UpdateDecrement failed" ); + } + } + + /* + idMatX::LDLT_Inverse + */ + + m2 = original; + + m2.LDLT_Factor(); + m2.LDLT_Inverse( m1 ); + m1 *= original; + + if ( !m1.IsIdentity( 1e-4f ) ) { + idLib::common->Warning( "idMatX::LDLT_Inverse failed" ); + } + + /* + idMatX::Eigen_SolveSymmetricTriDiagonal + */ + + m3 = original; + m3.TriDiagonal_ClearTriangles(); + m1 = m3; + + v.SetSize( size ); + + m1.Eigen_SolveSymmetricTriDiagonal( v ); + + m3.TransposeMultiply( m2, m1 ); + + for ( int i = 0; i < size; i++ ) { + for ( int j = 0; j < size; j++ ) { + m1[i][j] *= v[j]; + } + } + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Eigen_SolveSymmetricTriDiagonal failed" ); + } + + /* + idMatX::Eigen_SolveSymmetric + */ + + m3 = original; + m1 = m3; + + v.SetSize( size ); + + m1.Eigen_SolveSymmetric( v ); + + m3.TransposeMultiply( m2, m1 ); + + for ( int i = 0; i < size; i++ ) { + for ( int j = 0; j < size; j++ ) { + m1[i][j] *= v[j]; + } + } + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Eigen_SolveSymmetric failed" ); + } + + /* + idMatX::Eigen_Solve + */ + + m3 = original; + m1 = m3; + + v.SetSize( size ); + w.SetSize( size ); + + m1.Eigen_Solve( v, w ); + + m3.TransposeMultiply( m2, m1 ); + + for ( int i = 0; i < size; i++ ) { + for ( int j = 0; j < size; j++ ) { + m1[i][j] *= v[j]; + } + } + + if ( !m1.Compare( m2, 1e-4f ) ) { + idLib::common->Warning( "idMatX::Eigen_Solve failed" ); + } +} +#pragma warning( pop ) diff --git a/idlib/math/Matrix.h b/idlib/math/Matrix.h new file mode 100644 index 000000000..55b06a708 --- /dev/null +++ b/idlib/math/Matrix.h @@ -0,0 +1,3013 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_MATRIX_H__ +#define __MATH_MATRIX_H__ + +#ifdef __linux__ +#include "../../sys/sys_public.h" +#include +#endif + +/* +=============================================================================== + + Matrix classes, all matrices are row-major except idMat3 + +=============================================================================== +*/ + +#define MATRIX_INVERSE_EPSILON 1e-14 +#define MATRIX_EPSILON 1e-6 + +class idAngles; +class idQuat; +class idCQuat; +class idRotation; +class idMat4; + +//=============================================================== +// +// idMat2 - 2x2 matrix +// +//=============================================================== + +class idMat2 { +public: + idMat2( void ); + explicit idMat2( const idVec2 &x, const idVec2 &y ); + explicit idMat2( const float xx, const float xy, const float yx, const float yy ); + explicit idMat2( const float src[ 2 ][ 2 ] ); + + const idVec2 & operator[]( int index ) const; + idVec2 & operator[]( int index ); + idMat2 operator-() const; + idMat2 operator*( const float a ) const; + idVec2 operator*( const idVec2 &vec ) const; + idMat2 operator*( const idMat2 &a ) const; + idMat2 operator+( const idMat2 &a ) const; + idMat2 operator-( const idMat2 &a ) const; + idMat2 & operator*=( const float a ); + idMat2 & operator*=( const idMat2 &a ); + idMat2 & operator+=( const idMat2 &a ); + idMat2 & operator-=( const idMat2 &a ); + + friend idMat2 operator*( const float a, const idMat2 &mat ); + friend idVec2 operator*( const idVec2 &vec, const idMat2 &mat ); + friend idVec2 & operator*=( idVec2 &vec, const idMat2 &mat ); + + bool Compare( const idMat2 &a ) const; // exact compare, no epsilon + bool Compare( const idMat2 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMat2 &a ) const; // exact compare, no epsilon + bool operator!=( const idMat2 &a ) const; // exact compare, no epsilon + + void Zero( void ); + void Identity( void ); + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + + float Trace( void ) const; + float Determinant( void ) const; + idMat2 Transpose( void ) const; // returns transpose + idMat2 & TransposeSelf( void ); + idMat2 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMat2 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + idVec2 mat[ 2 ]; +}; + +extern idMat2 mat2_zero; +extern idMat2 mat2_identity; +#define mat2_default mat2_identity + +ID_INLINE idMat2::idMat2( void ) { +} + +ID_INLINE idMat2::idMat2( const idVec2 &x, const idVec2 &y ) { + mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; + mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; +} + +ID_INLINE idMat2::idMat2( const float xx, const float xy, const float yx, const float yy ) { + mat[ 0 ].x = xx; mat[ 0 ].y = xy; + mat[ 1 ].x = yx; mat[ 1 ].y = yy; +} + +ID_INLINE idMat2::idMat2( const float src[ 2 ][ 2 ] ) { + memcpy( mat, src, 2 * 2 * sizeof( float ) ); +} + +ID_INLINE const idVec2 &idMat2::operator[]( int index ) const { + //assert( ( index >= 0 ) && ( index < 2 ) ); + return mat[ index ]; +} + +ID_INLINE idVec2 &idMat2::operator[]( int index ) { + //assert( ( index >= 0 ) && ( index < 2 ) ); + return mat[ index ]; +} + +ID_INLINE idMat2 idMat2::operator-() const { + return idMat2( -mat[0][0], -mat[0][1], + -mat[1][0], -mat[1][1] ); +} + +ID_INLINE idVec2 idMat2::operator*( const idVec2 &vec ) const { + return idVec2( + mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y, + mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y ); +} + +ID_INLINE idMat2 idMat2::operator*( const idMat2 &a ) const { + return idMat2( + mat[0].x * a[0].x + mat[0].y * a[1].x, + mat[0].x * a[0].y + mat[0].y * a[1].y, + mat[1].x * a[0].x + mat[1].y * a[1].x, + mat[1].x * a[0].y + mat[1].y * a[1].y ); +} + +ID_INLINE idMat2 idMat2::operator*( const float a ) const { + return idMat2( + mat[0].x * a, mat[0].y * a, + mat[1].x * a, mat[1].y * a ); +} + +ID_INLINE idMat2 idMat2::operator+( const idMat2 &a ) const { + return idMat2( + mat[0].x + a[0].x, mat[0].y + a[0].y, + mat[1].x + a[1].x, mat[1].y + a[1].y ); +} + +ID_INLINE idMat2 idMat2::operator-( const idMat2 &a ) const { + return idMat2( + mat[0].x - a[0].x, mat[0].y - a[0].y, + mat[1].x - a[1].x, mat[1].y - a[1].y ); +} + +ID_INLINE idMat2 &idMat2::operator*=( const float a ) { + mat[0].x *= a; mat[0].y *= a; + mat[1].x *= a; mat[1].y *= a; + + return *this; +} + +ID_INLINE idMat2 &idMat2::operator*=( const idMat2 &a ) { + float x, y; + x = mat[0].x; y = mat[0].y; + mat[0].x = x * a[0].x + y * a[1].x; + mat[0].y = x * a[0].y + y * a[1].y; + x = mat[1].x; y = mat[1].y; + mat[1].x = x * a[0].x + y * a[1].x; + mat[1].y = x * a[0].y + y * a[1].y; + return *this; +} + +ID_INLINE idMat2 &idMat2::operator+=( const idMat2 &a ) { + mat[0].x += a[0].x; mat[0].y += a[0].y; + mat[1].x += a[1].x; mat[1].y += a[1].y; + + return *this; +} + +ID_INLINE idMat2 &idMat2::operator-=( const idMat2 &a ) { + mat[0].x -= a[0].x; mat[0].y -= a[0].y; + mat[1].x -= a[1].x; mat[1].y -= a[1].y; + + return *this; +} + +ID_INLINE idVec2 operator*( const idVec2 &vec, const idMat2 &mat ) { + return mat * vec; +} + +ID_INLINE idMat2 operator*( const float a, idMat2 const &mat ) { + return mat * a; +} + +ID_INLINE idVec2 &operator*=( idVec2 &vec, const idMat2 &mat ) { + vec = mat * vec; + return vec; +} + +ID_INLINE bool idMat2::Compare( const idMat2 &a ) const { + if ( mat[0].Compare( a[0] ) && + mat[1].Compare( a[1] ) ) { + return true; + } + return false; +} + +ID_INLINE bool idMat2::Compare( const idMat2 &a, const float epsilon ) const { + if ( mat[0].Compare( a[0], epsilon ) && + mat[1].Compare( a[1], epsilon ) ) { + return true; + } + return false; +} + +ID_INLINE bool idMat2::operator==( const idMat2 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMat2::operator!=( const idMat2 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMat2::Zero( void ) { + mat[0].Zero(); + mat[1].Zero(); +} + +ID_INLINE void idMat2::Identity( void ) { + *this = mat2_identity; +} + +ID_INLINE bool idMat2::IsIdentity( const float epsilon ) const { + return Compare( mat2_identity, epsilon ); +} + +ID_INLINE bool idMat2::IsSymmetric( const float epsilon ) const { + return ( idMath::Fabs( mat[0][1] - mat[1][0] ) < epsilon ); +} + +ID_INLINE bool idMat2::IsDiagonal( const float epsilon ) const { + if ( idMath::Fabs( mat[0][1] ) > epsilon || + idMath::Fabs( mat[1][0] ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE float idMat2::Trace( void ) const { + return ( mat[0][0] + mat[1][1] ); +} + +ID_INLINE float idMat2::Determinant( void ) const { + return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; +} + +ID_INLINE idMat2 idMat2::Transpose( void ) const { + return idMat2( mat[0][0], mat[1][0], + mat[0][1], mat[1][1] ); +} + +ID_INLINE idMat2 &idMat2::TransposeSelf( void ) { + float tmp; + + tmp = mat[0][1]; + mat[0][1] = mat[1][0]; + mat[1][0] = tmp; + + return *this; +} + +ID_INLINE idMat2 idMat2::Inverse( void ) const { + idMat2 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat2 idMat2::InverseFast( void ) const { + idMat2 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE int idMat2::GetDimension( void ) const { + return 4; +} + +ID_INLINE const float *idMat2::ToFloatPtr( void ) const { + return mat[0].ToFloatPtr(); +} + +ID_INLINE float *idMat2::ToFloatPtr( void ) { + return mat[0].ToFloatPtr(); +} + + +//=============================================================== +// +// idMat3 - 3x3 matrix +// +// NOTE: matrix is column-major +// +//=============================================================== + +class idMat3 { +public: + idMat3( void ); + explicit idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z ); + explicit idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ); + explicit idMat3( const float src[ 3 ][ 3 ] ); + + const idVec3 & operator[]( int index ) const; + idVec3 & operator[]( int index ); + idMat3 operator-() const; + idMat3 operator*( const float a ) const; + idVec3 operator*( const idVec3 &vec ) const; + idMat3 operator*( const idMat3 &a ) const; + idMat3 operator+( const idMat3 &a ) const; + idMat3 operator-( const idMat3 &a ) const; + idMat3 & operator*=( const float a ); + idMat3 & operator*=( const idMat3 &a ); + idMat3 & operator+=( const idMat3 &a ); + idMat3 & operator-=( const idMat3 &a ); + + friend idMat3 operator*( const float a, const idMat3 &mat ); + friend idVec3 operator*( const idVec3 &vec, const idMat3 &mat ); + friend idVec3 & operator*=( idVec3 &vec, const idMat3 &mat ); + + bool Compare( const idMat3 &a ) const; // exact compare, no epsilon + bool Compare( const idMat3 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMat3 &a ) const; // exact compare, no epsilon + bool operator!=( const idMat3 &a ) const; // exact compare, no epsilon + + void Zero( void ); + void Identity( void ); + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + bool IsRotated( void ) const; + + void ProjectVector( const idVec3 &src, idVec3 &dst ) const; + void UnprojectVector( const idVec3 &src, idVec3 &dst ) const; + + bool FixDegeneracies( void ); // fix degenerate axial cases + bool FixDenormals( void ); // change tiny numbers to zero + + float Trace( void ) const; + float Determinant( void ) const; + idMat3 OrthoNormalize( void ) const; + idMat3 & OrthoNormalizeSelf( void ); + idMat3 Transpose( void ) const; // returns transpose + idMat3 & TransposeSelf( void ); + idMat3 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMat3 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + idMat3 TransposeMultiply( const idMat3 &b ) const; + + idMat3 InertiaTranslate( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) const; + idMat3 & InertiaTranslateSelf( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ); + idMat3 InertiaRotate( const idMat3 &rotation ) const; + idMat3 & InertiaRotateSelf( const idMat3 &rotation ); + + int GetDimension( void ) const; + + idAngles ToAngles( void ) const; + idQuat ToQuat( void ) const; + idCQuat ToCQuat( void ) const; + idRotation ToRotation( void ) const; + idMat4 ToMat4( void ) const; + idVec3 ToAngularVelocity( void ) const; + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + friend void TransposeMultiply( const idMat3 &inv, const idMat3 &b, idMat3 &dst ); + friend idMat3 SkewSymmetric( idVec3 const &src ); + + void GetMat3Params(idVec3 &a, idVec3 &b, idVec3 &c) const { a = mat[0]; b = mat[1], c = mat[2]; }; + +private: + idVec3 mat[ 3 ]; +}; + +extern idMat3 mat3_zero; +extern idMat3 mat3_identity; +#define mat3_default mat3_identity + +ID_INLINE idMat3::idMat3( void ) { +} + +ID_INLINE idMat3::idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z ) { + mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z; + mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z; + mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z; +} + +ID_INLINE idMat3::idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) { + mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz; + mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz; + mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz; +} + +ID_INLINE idMat3::idMat3( const float src[ 3 ][ 3 ] ) { + memcpy( mat, src, 3 * 3 * sizeof( float ) ); +} + +ID_INLINE const idVec3 &idMat3::operator[]( int index ) const { + //assert( ( index >= 0 ) && ( index < 3 ) ); + return mat[ index ]; +} + +ID_INLINE idVec3 &idMat3::operator[]( int index ) { + //assert( ( index >= 0 ) && ( index < 3 ) ); + return mat[ index ]; +} + +ID_INLINE idMat3 idMat3::operator-() const { + return idMat3( -mat[0][0], -mat[0][1], -mat[0][2], + -mat[1][0], -mat[1][1], -mat[1][2], + -mat[2][0], -mat[2][1], -mat[2][2] ); +} + +ID_INLINE idVec3 idMat3::operator*( const idVec3 &vec ) const { + return idVec3( + mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, + mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, + mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); +} + +ID_INLINE idMat3 idMat3::operator*( const idMat3 &a ) const { + int i, j; + const float *m1Ptr, *m2Ptr; + float *dstPtr; + idMat3 dst; + + m1Ptr = reinterpret_cast(this); + m2Ptr = reinterpret_cast(&a); + dstPtr = reinterpret_cast(&dst); + + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 3 + j ]; + dstPtr++; + } + m1Ptr += 3; + } + return dst; +} + +ID_INLINE idMat3 idMat3::operator*( const float a ) const { + return idMat3( + mat[0].x * a, mat[0].y * a, mat[0].z * a, + mat[1].x * a, mat[1].y * a, mat[1].z * a, + mat[2].x * a, mat[2].y * a, mat[2].z * a ); +} + +ID_INLINE idMat3 idMat3::operator+( const idMat3 &a ) const { + return idMat3( + mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, + mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, + mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z ); +} + +ID_INLINE idMat3 idMat3::operator-( const idMat3 &a ) const { + return idMat3( + mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, + mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, + mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z ); +} + +ID_INLINE idMat3 &idMat3::operator*=( const float a ) { + mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; + mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; + mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; + + return *this; +} + +ID_INLINE idMat3 &idMat3::operator*=( const idMat3 &a ) { + int i, j; + const float *m2Ptr; + float *m1Ptr, dst[3]; + + m1Ptr = reinterpret_cast(this); + m2Ptr = reinterpret_cast(&a); + + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + dst[j] = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 3 + j ]; + } + m1Ptr[0] = dst[0]; m1Ptr[1] = dst[1]; m1Ptr[2] = dst[2]; + m1Ptr += 3; + } + return *this; +} + +ID_INLINE idMat3 &idMat3::operator+=( const idMat3 &a ) { + mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; + mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; + mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; + + return *this; +} + +ID_INLINE idMat3 &idMat3::operator-=( const idMat3 &a ) { + mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; + mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; + mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; + + return *this; +} + +ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat3 &mat ) { + return mat * vec; +} + +ID_INLINE idMat3 operator*( const float a, const idMat3 &mat ) { + return mat * a; +} + +ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat3 &mat ) { + float x = mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z; + float y = mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z; + vec.z = mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z; + vec.x = x; + vec.y = y; + return vec; +} + +ID_INLINE bool idMat3::Compare( const idMat3 &a ) const { + if ( mat[0].Compare( a[0] ) && + mat[1].Compare( a[1] ) && + mat[2].Compare( a[2] ) ) { + return true; + } + return false; +} + +ID_INLINE bool idMat3::Compare( const idMat3 &a, const float epsilon ) const { + if ( mat[0].Compare( a[0], epsilon ) && + mat[1].Compare( a[1], epsilon ) && + mat[2].Compare( a[2], epsilon ) ) { + return true; + } + return false; +} + +ID_INLINE bool idMat3::operator==( const idMat3 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMat3::operator!=( const idMat3 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMat3::Zero( void ) { + memset( mat, 0, sizeof( idMat3 ) ); +} + +ID_INLINE void idMat3::Identity( void ) { + *this = mat3_identity; +} + +ID_INLINE bool idMat3::IsIdentity( const float epsilon ) const { + return Compare( mat3_identity, epsilon ); +} + +ID_INLINE bool idMat3::IsSymmetric( const float epsilon ) const { + if ( idMath::Fabs( mat[0][1] - mat[1][0] ) > epsilon ) { + return false; + } + if ( idMath::Fabs( mat[0][2] - mat[2][0] ) > epsilon ) { + return false; + } + if ( idMath::Fabs( mat[1][2] - mat[2][1] ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE bool idMat3::IsDiagonal( const float epsilon ) const { + if ( idMath::Fabs( mat[0][1] ) > epsilon || + idMath::Fabs( mat[0][2] ) > epsilon || + idMath::Fabs( mat[1][0] ) > epsilon || + idMath::Fabs( mat[1][2] ) > epsilon || + idMath::Fabs( mat[2][0] ) > epsilon || + idMath::Fabs( mat[2][1] ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE bool idMat3::IsRotated( void ) const { + return !Compare( mat3_identity ); +} + +ID_INLINE void idMat3::ProjectVector( const idVec3 &src, idVec3 &dst ) const { + dst.x = src * mat[ 0 ]; + dst.y = src * mat[ 1 ]; + dst.z = src * mat[ 2 ]; +} + +ID_INLINE void idMat3::UnprojectVector( const idVec3 &src, idVec3 &dst ) const { + dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z; +} + +ID_INLINE bool idMat3::FixDegeneracies( void ) { + bool r = mat[0].FixDegenerateNormal(); + r |= mat[1].FixDegenerateNormal(); + r |= mat[2].FixDegenerateNormal(); + return r; +} + +ID_INLINE bool idMat3::FixDenormals( void ) { + bool r = mat[0].FixDenormals(); + r |= mat[1].FixDenormals(); + r |= mat[2].FixDenormals(); + return r; +} + +ID_INLINE float idMat3::Trace( void ) const { + return ( mat[0][0] + mat[1][1] + mat[2][2] ); +} + +ID_INLINE idMat3 idMat3::OrthoNormalize( void ) const { + idMat3 ortho; + + ortho = *this; + ortho[ 0 ].Normalize(); + ortho[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); + ortho[ 2 ].Normalize(); + ortho[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); + ortho[ 1 ].Normalize(); + return ortho; +} + +ID_INLINE idMat3 &idMat3::OrthoNormalizeSelf( void ) { + mat[ 0 ].Normalize(); + mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); + mat[ 2 ].Normalize(); + mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); + mat[ 1 ].Normalize(); + return *this; +} + +ID_INLINE idMat3 idMat3::Transpose( void ) const { + return idMat3( mat[0][0], mat[1][0], mat[2][0], + mat[0][1], mat[1][1], mat[2][1], + mat[0][2], mat[1][2], mat[2][2] ); +} + +ID_INLINE idMat3 &idMat3::TransposeSelf( void ) { + float tmp0, tmp1, tmp2; + + tmp0 = mat[0][1]; + mat[0][1] = mat[1][0]; + mat[1][0] = tmp0; + tmp1 = mat[0][2]; + mat[0][2] = mat[2][0]; + mat[2][0] = tmp1; + tmp2 = mat[1][2]; + mat[1][2] = mat[2][1]; + mat[2][1] = tmp2; + + return *this; +} + +ID_INLINE idMat3 idMat3::Inverse( void ) const { + idMat3 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat3 idMat3::InverseFast( void ) const { + idMat3 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat3 idMat3::TransposeMultiply( const idMat3 &b ) const { + return idMat3( mat[0].x * b[0].x + mat[1].x * b[1].x + mat[2].x * b[2].x, + mat[0].x * b[0].y + mat[1].x * b[1].y + mat[2].x * b[2].y, + mat[0].x * b[0].z + mat[1].x * b[1].z + mat[2].x * b[2].z, + mat[0].y * b[0].x + mat[1].y * b[1].x + mat[2].y * b[2].x, + mat[0].y * b[0].y + mat[1].y * b[1].y + mat[2].y * b[2].y, + mat[0].y * b[0].z + mat[1].y * b[1].z + mat[2].y * b[2].z, + mat[0].z * b[0].x + mat[1].z * b[1].x + mat[2].z * b[2].x, + mat[0].z * b[0].y + mat[1].z * b[1].y + mat[2].z * b[2].y, + mat[0].z * b[0].z + mat[1].z * b[1].z + mat[2].z * b[2].z ); +} + +ID_INLINE void TransposeMultiply( const idMat3 &transpose, const idMat3 &b, idMat3 &dst ) { + dst[0].x = transpose[0].x * b[0].x + transpose[1].x * b[1].x + transpose[2].x * b[2].x; + dst[0].y = transpose[0].x * b[0].y + transpose[1].x * b[1].y + transpose[2].x * b[2].y; + dst[0].z = transpose[0].x * b[0].z + transpose[1].x * b[1].z + transpose[2].x * b[2].z; + dst[1].x = transpose[0].y * b[0].x + transpose[1].y * b[1].x + transpose[2].y * b[2].x; + dst[1].y = transpose[0].y * b[0].y + transpose[1].y * b[1].y + transpose[2].y * b[2].y; + dst[1].z = transpose[0].y * b[0].z + transpose[1].y * b[1].z + transpose[2].y * b[2].z; + dst[2].x = transpose[0].z * b[0].x + transpose[1].z * b[1].x + transpose[2].z * b[2].x; + dst[2].y = transpose[0].z * b[0].y + transpose[1].z * b[1].y + transpose[2].z * b[2].y; + dst[2].z = transpose[0].z * b[0].z + transpose[1].z * b[1].z + transpose[2].z * b[2].z; +} + +ID_INLINE idMat3 SkewSymmetric( idVec3 const &src ) { + return idMat3( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f ); +} + +ID_INLINE int idMat3::GetDimension( void ) const { + return 9; +} + +ID_INLINE const float *idMat3::ToFloatPtr( void ) const { + return mat[0].ToFloatPtr(); +} + +ID_INLINE float *idMat3::ToFloatPtr( void ) { + return mat[0].ToFloatPtr(); +} + + +//=============================================================== +// +// idMat4 - 4x4 matrix +// +//=============================================================== + +class idMat4 { +public: + idMat4( void ); + explicit idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w ); + explicit idMat4(const float xx, const float xy, const float xz, const float xw, + const float yx, const float yy, const float yz, const float yw, + const float zx, const float zy, const float zz, const float zw, + const float wx, const float wy, const float wz, const float ww ); + explicit idMat4( const idMat3 &rotation, const idVec3 &translation ); + explicit idMat4( const float src[ 4 ][ 4 ] ); + + const idVec4 & operator[]( int index ) const; + idVec4 & operator[]( int index ); + idMat4 operator*( const float a ) const; + idVec4 operator*( const idVec4 &vec ) const; + idVec3 operator*( const idVec3 &vec ) const; + idMat4 operator*( const idMat4 &a ) const; + idMat4 operator+( const idMat4 &a ) const; + idMat4 operator-( const idMat4 &a ) const; + idMat4 & operator*=( const float a ); + idMat4 & operator*=( const idMat4 &a ); + idMat4 & operator+=( const idMat4 &a ); + idMat4 & operator-=( const idMat4 &a ); + + friend idMat4 operator*( const float a, const idMat4 &mat ); + friend idVec4 operator*( const idVec4 &vec, const idMat4 &mat ); + friend idVec3 operator*( const idVec3 &vec, const idMat4 &mat ); + friend idVec4 & operator*=( idVec4 &vec, const idMat4 &mat ); + friend idVec3 & operator*=( idVec3 &vec, const idMat4 &mat ); + + bool Compare( const idMat4 &a ) const; // exact compare, no epsilon + bool Compare( const idMat4 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMat4 &a ) const; // exact compare, no epsilon + bool operator!=( const idMat4 &a ) const; // exact compare, no epsilon + + void Zero( void ); + void Identity( void ); + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + bool IsRotated( void ) const; + + void ProjectVector( const idVec4 &src, idVec4 &dst ) const; + void UnprojectVector( const idVec4 &src, idVec4 &dst ) const; + + float Trace( void ) const; + float Determinant( void ) const; + idMat4 Transpose( void ) const; // returns transpose + idMat4 & TransposeSelf( void ); + idMat4 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMat4 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + idMat4 TransposeMultiply( const idMat4 &b ) const; + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + idVec4 mat[ 4 ]; +}; + +extern idMat4 mat4_zero; +extern idMat4 mat4_identity; +#define mat4_default mat4_identity + +ID_INLINE idMat4::idMat4( void ) { +} + +ID_INLINE idMat4::idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w ) { + mat[ 0 ] = x; + mat[ 1 ] = y; + mat[ 2 ] = z; + mat[ 3 ] = w; +} + +ID_INLINE idMat4::idMat4( const float xx, const float xy, const float xz, const float xw, + const float yx, const float yy, const float yz, const float yw, + const float zx, const float zy, const float zz, const float zw, + const float wx, const float wy, const float wz, const float ww ) { + mat[0][0] = xx; mat[0][1] = xy; mat[0][2] = xz; mat[0][3] = xw; + mat[1][0] = yx; mat[1][1] = yy; mat[1][2] = yz; mat[1][3] = yw; + mat[2][0] = zx; mat[2][1] = zy; mat[2][2] = zz; mat[2][3] = zw; + mat[3][0] = wx; mat[3][1] = wy; mat[3][2] = wz; mat[3][3] = ww; +} + +ID_INLINE idMat4::idMat4( const idMat3 &rotation, const idVec3 &translation ) { + // NOTE: idMat3 is transposed because it is column-major + mat[ 0 ][ 0 ] = rotation[0][0]; + mat[ 0 ][ 1 ] = rotation[1][0]; + mat[ 0 ][ 2 ] = rotation[2][0]; + mat[ 0 ][ 3 ] = translation[0]; + mat[ 1 ][ 0 ] = rotation[0][1]; + mat[ 1 ][ 1 ] = rotation[1][1]; + mat[ 1 ][ 2 ] = rotation[2][1]; + mat[ 1 ][ 3 ] = translation[1]; + mat[ 2 ][ 0 ] = rotation[0][2]; + mat[ 2 ][ 1 ] = rotation[1][2]; + mat[ 2 ][ 2 ] = rotation[2][2]; + mat[ 2 ][ 3 ] = translation[2]; + mat[ 3 ][ 0 ] = 0.0f; + mat[ 3 ][ 1 ] = 0.0f; + mat[ 3 ][ 2 ] = 0.0f; + mat[ 3 ][ 3 ] = 1.0f; +} + +ID_INLINE idMat4::idMat4( const float src[ 4 ][ 4 ] ) { + memcpy( mat, src, 4 * 4 * sizeof( float ) ); +} + +ID_INLINE const idVec4 &idMat4::operator[]( int index ) const { + //assert( ( index >= 0 ) && ( index < 4 ) ); + return mat[ index ]; +} + +ID_INLINE idVec4 &idMat4::operator[]( int index ) { + //assert( ( index >= 0 ) && ( index < 4 ) ); + return mat[ index ]; +} + +ID_INLINE idMat4 idMat4::operator*( const float a ) const { + return idMat4( + mat[0].x * a, mat[0].y * a, mat[0].z * a, mat[0].w * a, + mat[1].x * a, mat[1].y * a, mat[1].z * a, mat[1].w * a, + mat[2].x * a, mat[2].y * a, mat[2].z * a, mat[2].w * a, + mat[3].x * a, mat[3].y * a, mat[3].z * a, mat[3].w * a ); +} + +ID_INLINE idVec4 idMat4::operator*( const idVec4 &vec ) const { + return idVec4( + mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w * vec.w, + mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w * vec.w, + mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w * vec.w, + mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w * vec.w ); +} + +ID_INLINE idVec3 idMat4::operator*( const idVec3 &vec ) const { + float s = mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w; + if ( s == 0.0f ) { + return idVec3( 0.0f, 0.0f, 0.0f ); + } + if ( s == 1.0f ) { + return idVec3( + mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w, + mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w, + mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w ); + } + else { + float invS = 1.0f / s; + return idVec3( + (mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w) * invS, + (mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w) * invS, + (mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w) * invS ); + } +} + +ID_INLINE idMat4 idMat4::operator*( const idMat4 &a ) const { + int i, j; + const float *m1Ptr, *m2Ptr; + float *dstPtr; + idMat4 dst; + + m1Ptr = reinterpret_cast(this); + m2Ptr = reinterpret_cast(&a); + dstPtr = reinterpret_cast(&dst); + + for ( i = 0; i < 4; i++ ) { + for ( j = 0; j < 4; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 4 + j ]; + dstPtr++; + } + m1Ptr += 4; + } + return dst; +} + +ID_INLINE idMat4 idMat4::operator+( const idMat4 &a ) const { + return idMat4( + mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, mat[0].w + a[0].w, + mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, mat[1].w + a[1].w, + mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z, mat[2].w + a[2].w, + mat[3].x + a[3].x, mat[3].y + a[3].y, mat[3].z + a[3].z, mat[3].w + a[3].w ); +} + +ID_INLINE idMat4 idMat4::operator-( const idMat4 &a ) const { + return idMat4( + mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, mat[0].w - a[0].w, + mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, mat[1].w - a[1].w, + mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z, mat[2].w - a[2].w, + mat[3].x - a[3].x, mat[3].y - a[3].y, mat[3].z - a[3].z, mat[3].w - a[3].w ); +} + +ID_INLINE idMat4 &idMat4::operator*=( const float a ) { + mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; mat[0].w *= a; + mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; mat[1].w *= a; + mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; mat[2].w *= a; + mat[3].x *= a; mat[3].y *= a; mat[3].z *= a; mat[3].w *= a; + return *this; +} + +ID_INLINE idMat4 &idMat4::operator*=( const idMat4 &a ) { + *this = (*this) * a; + return *this; +} + +ID_INLINE idMat4 &idMat4::operator+=( const idMat4 &a ) { + mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; mat[0].w += a[0].w; + mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; mat[1].w += a[1].w; + mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; mat[2].w += a[2].w; + mat[3].x += a[3].x; mat[3].y += a[3].y; mat[3].z += a[3].z; mat[3].w += a[3].w; + return *this; +} + +ID_INLINE idMat4 &idMat4::operator-=( const idMat4 &a ) { + mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; mat[0].w -= a[0].w; + mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; mat[1].w -= a[1].w; + mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; mat[2].w -= a[2].w; + mat[3].x -= a[3].x; mat[3].y -= a[3].y; mat[3].z -= a[3].z; mat[3].w -= a[3].w; + return *this; +} + +ID_INLINE idMat4 operator*( const float a, const idMat4 &mat ) { + return mat * a; +} + +ID_INLINE idVec4 operator*( const idVec4 &vec, const idMat4 &mat ) { + return mat * vec; +} + +ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat4 &mat ) { + return mat * vec; +} + +ID_INLINE idVec4 &operator*=( idVec4 &vec, const idMat4 &mat ) { + vec = mat * vec; + return vec; +} + +ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat4 &mat ) { + vec = mat * vec; + return vec; +} + +ID_INLINE bool idMat4::Compare( const idMat4 &a ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 4*4; i++ ) { + if ( ptr1[i] != ptr2[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat4::Compare( const idMat4 &a, const float epsilon ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 4*4; i++ ) { + if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat4::operator==( const idMat4 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMat4::operator!=( const idMat4 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMat4::Zero( void ) { + memset( mat, 0, sizeof( idMat4 ) ); +} + +ID_INLINE void idMat4::Identity( void ) { + *this = mat4_identity; +} + +ID_INLINE bool idMat4::IsIdentity( const float epsilon ) const { + return Compare( mat4_identity, epsilon ); +} + +ID_INLINE bool idMat4::IsSymmetric( const float epsilon ) const { + for ( int i = 1; i < 4; i++ ) { + for ( int j = 0; j < i; j++ ) { + if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMat4::IsDiagonal( const float epsilon ) const { + for ( int i = 0; i < 4; i++ ) { + for ( int j = 0; j < 4; j++ ) { + if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMat4::IsRotated( void ) const { + if ( !mat[ 0 ][ 1 ] && !mat[ 0 ][ 2 ] && + !mat[ 1 ][ 0 ] && !mat[ 1 ][ 2 ] && + !mat[ 2 ][ 0 ] && !mat[ 2 ][ 1 ] ) { + return false; + } + return true; +} + +ID_INLINE void idMat4::ProjectVector( const idVec4 &src, idVec4 &dst ) const { + dst.x = src * mat[ 0 ]; + dst.y = src * mat[ 1 ]; + dst.z = src * mat[ 2 ]; + dst.w = src * mat[ 3 ]; +} + +ID_INLINE void idMat4::UnprojectVector( const idVec4 &src, idVec4 &dst ) const { + dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z + mat[ 3 ] * src.w; +} + +ID_INLINE float idMat4::Trace( void ) const { + return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] ); +} + +ID_INLINE idMat4 idMat4::Inverse( void ) const { + idMat4 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat4 idMat4::InverseFast( void ) const { + idMat4 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat4 idMat3::ToMat4( void ) const { + // NOTE: idMat3 is transposed because it is column-major + return idMat4( mat[0][0], mat[1][0], mat[2][0], 0.0f, + mat[0][1], mat[1][1], mat[2][1], 0.0f, + mat[0][2], mat[1][2], mat[2][2], 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); +} + +ID_INLINE int idMat4::GetDimension( void ) const { + return 16; +} + +ID_INLINE const float *idMat4::ToFloatPtr( void ) const { + return mat[0].ToFloatPtr(); +} + +ID_INLINE float *idMat4::ToFloatPtr( void ) { + return mat[0].ToFloatPtr(); +} + + +//=============================================================== +// +// idMat5 - 5x5 matrix +// +//=============================================================== + +class idMat5 { +public: + idMat5( void ); + explicit idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 ); + explicit idMat5( const float src[ 5 ][ 5 ] ); + + const idVec5 & operator[]( int index ) const; + idVec5 & operator[]( int index ); + idMat5 operator*( const float a ) const; + idVec5 operator*( const idVec5 &vec ) const; + idMat5 operator*( const idMat5 &a ) const; + idMat5 operator+( const idMat5 &a ) const; + idMat5 operator-( const idMat5 &a ) const; + idMat5 & operator*=( const float a ); + idMat5 & operator*=( const idMat5 &a ); + idMat5 & operator+=( const idMat5 &a ); + idMat5 & operator-=( const idMat5 &a ); + + friend idMat5 operator*( const float a, const idMat5 &mat ); + friend idVec5 operator*( const idVec5 &vec, const idMat5 &mat ); + friend idVec5 & operator*=( idVec5 &vec, const idMat5 &mat ); + + bool Compare( const idMat5 &a ) const; // exact compare, no epsilon + bool Compare( const idMat5 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMat5 &a ) const; // exact compare, no epsilon + bool operator!=( const idMat5 &a ) const; // exact compare, no epsilon + + void Zero( void ); + void Identity( void ); + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + + float Trace( void ) const; + float Determinant( void ) const; + idMat5 Transpose( void ) const; // returns transpose + idMat5 & TransposeSelf( void ); + idMat5 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMat5 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + idVec5 mat[ 5 ]; +}; + +extern idMat5 mat5_zero; +extern idMat5 mat5_identity; +#define mat5_default mat5_identity + +ID_INLINE idMat5::idMat5( void ) { +} + +ID_INLINE idMat5::idMat5( const float src[ 5 ][ 5 ] ) { + memcpy( mat, src, 5 * 5 * sizeof( float ) ); +} + +ID_INLINE idMat5::idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 ) { + mat[0] = v0; + mat[1] = v1; + mat[2] = v2; + mat[3] = v3; + mat[4] = v4; +} + +ID_INLINE const idVec5 &idMat5::operator[]( int index ) const { + //assert( ( index >= 0 ) && ( index < 5 ) ); + return mat[ index ]; +} + +ID_INLINE idVec5 &idMat5::operator[]( int index ) { + //assert( ( index >= 0 ) && ( index < 5 ) ); + return mat[ index ]; +} + +ID_INLINE idMat5 idMat5::operator*( const idMat5 &a ) const { + int i, j; + const float *m1Ptr, *m2Ptr; + float *dstPtr; + idMat5 dst; + + m1Ptr = reinterpret_cast(this); + m2Ptr = reinterpret_cast(&a); + dstPtr = reinterpret_cast(&dst); + + for ( i = 0; i < 5; i++ ) { + for ( j = 0; j < 5; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 5 + j ]; + dstPtr++; + } + m1Ptr += 5; + } + return dst; +} + +ID_INLINE idMat5 idMat5::operator*( const float a ) const { + return idMat5( + idVec5( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a ), + idVec5( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a ), + idVec5( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a ), + idVec5( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a ), + idVec5( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a ) ); +} + +ID_INLINE idVec5 idMat5::operator*( const idVec5 &vec ) const { + return idVec5( + mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4], + mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4], + mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4], + mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4], + mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] ); +} + +ID_INLINE idMat5 idMat5::operator+( const idMat5 &a ) const { + return idMat5( + idVec5( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4] ), + idVec5( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4] ), + idVec5( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4] ), + idVec5( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4] ), + idVec5( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4] ) ); +} + +ID_INLINE idMat5 idMat5::operator-( const idMat5 &a ) const { + return idMat5( + idVec5( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4] ), + idVec5( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4] ), + idVec5( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4] ), + idVec5( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4] ), + idVec5( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4] ) ); +} + +ID_INLINE idMat5 &idMat5::operator*=( const float a ) { + mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a; + mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a; + mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a; + mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a; + mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a; + return *this; +} + +ID_INLINE idMat5 &idMat5::operator*=( const idMat5 &a ) { + *this = *this * a; + return *this; +} + +ID_INLINE idMat5 &idMat5::operator+=( const idMat5 &a ) { + mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4]; + mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4]; + mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4]; + mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4]; + mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4]; + return *this; +} + +ID_INLINE idMat5 &idMat5::operator-=( const idMat5 &a ) { + mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4]; + mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4]; + mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4]; + mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4]; + mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4]; + return *this; +} + +ID_INLINE idVec5 operator*( const idVec5 &vec, const idMat5 &mat ) { + return mat * vec; +} + +ID_INLINE idMat5 operator*( const float a, idMat5 const &mat ) { + return mat * a; +} + +ID_INLINE idVec5 &operator*=( idVec5 &vec, const idMat5 &mat ) { + vec = mat * vec; + return vec; +} + +ID_INLINE bool idMat5::Compare( const idMat5 &a ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 5*5; i++ ) { + if ( ptr1[i] != ptr2[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat5::Compare( const idMat5 &a, const float epsilon ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 5*5; i++ ) { + if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat5::operator==( const idMat5 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMat5::operator!=( const idMat5 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMat5::Zero( void ) { + memset( mat, 0, sizeof( idMat5 ) ); +} + +ID_INLINE void idMat5::Identity( void ) { + *this = mat5_identity; +} + +ID_INLINE bool idMat5::IsIdentity( const float epsilon ) const { + return Compare( mat5_identity, epsilon ); +} + +ID_INLINE bool idMat5::IsSymmetric( const float epsilon ) const { + for ( int i = 1; i < 5; i++ ) { + for ( int j = 0; j < i; j++ ) { + if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMat5::IsDiagonal( const float epsilon ) const { + for ( int i = 0; i < 5; i++ ) { + for ( int j = 0; j < 5; j++ ) { + if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE float idMat5::Trace( void ) const { + return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] ); +} + +ID_INLINE idMat5 idMat5::Inverse( void ) const { + idMat5 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat5 idMat5::InverseFast( void ) const { + idMat5 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE int idMat5::GetDimension( void ) const { + return 25; +} + +ID_INLINE const float *idMat5::ToFloatPtr( void ) const { + return mat[0].ToFloatPtr(); +} + +ID_INLINE float *idMat5::ToFloatPtr( void ) { + return mat[0].ToFloatPtr(); +} + + +//=============================================================== +// +// idMat6 - 6x6 matrix +// +//=============================================================== + +class idMat6 { +public: + idMat6( void ); + explicit idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 ); + explicit idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 ); + explicit idMat6( const float src[ 6 ][ 6 ] ); + + const idVec6 & operator[]( int index ) const; + idVec6 & operator[]( int index ); + idMat6 operator*( const float a ) const; + idVec6 operator*( const idVec6 &vec ) const; + idMat6 operator*( const idMat6 &a ) const; + idMat6 operator+( const idMat6 &a ) const; + idMat6 operator-( const idMat6 &a ) const; + idMat6 & operator*=( const float a ); + idMat6 & operator*=( const idMat6 &a ); + idMat6 & operator+=( const idMat6 &a ); + idMat6 & operator-=( const idMat6 &a ); + + friend idMat6 operator*( const float a, const idMat6 &mat ); + friend idVec6 operator*( const idVec6 &vec, const idMat6 &mat ); + friend idVec6 & operator*=( idVec6 &vec, const idMat6 &mat ); + + bool Compare( const idMat6 &a ) const; // exact compare, no epsilon + bool Compare( const idMat6 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMat6 &a ) const; // exact compare, no epsilon + bool operator!=( const idMat6 &a ) const; // exact compare, no epsilon + + void Zero( void ); + void Identity( void ); + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + + idMat3 SubMat3( int n ) const; + float Trace( void ) const; + float Determinant( void ) const; + idMat6 Transpose( void ) const; // returns transpose + idMat6 & TransposeSelf( void ); + idMat6 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMat6 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + idVec6 mat[ 6 ]; +}; + +extern idMat6 mat6_zero; +extern idMat6 mat6_identity; +#define mat6_default mat6_identity + +ID_INLINE idMat6::idMat6( void ) { +} + +ID_INLINE idMat6::idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 ) { + mat[0] = idVec6( m0[0][0], m0[0][1], m0[0][2], m1[0][0], m1[0][1], m1[0][2] ); + mat[1] = idVec6( m0[1][0], m0[1][1], m0[1][2], m1[1][0], m1[1][1], m1[1][2] ); + mat[2] = idVec6( m0[2][0], m0[2][1], m0[2][2], m1[2][0], m1[2][1], m1[2][2] ); + mat[3] = idVec6( m2[0][0], m2[0][1], m2[0][2], m3[0][0], m3[0][1], m3[0][2] ); + mat[4] = idVec6( m2[1][0], m2[1][1], m2[1][2], m3[1][0], m3[1][1], m3[1][2] ); + mat[5] = idVec6( m2[2][0], m2[2][1], m2[2][2], m3[2][0], m3[2][1], m3[2][2] ); +} + +ID_INLINE idMat6::idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 ) { + mat[0] = v0; + mat[1] = v1; + mat[2] = v2; + mat[3] = v3; + mat[4] = v4; + mat[5] = v5; +} + +ID_INLINE idMat6::idMat6( const float src[ 6 ][ 6 ] ) { + memcpy( mat, src, 6 * 6 * sizeof( float ) ); +} + +ID_INLINE const idVec6 &idMat6::operator[]( int index ) const { + //assert( ( index >= 0 ) && ( index < 6 ) ); + return mat[ index ]; +} + +ID_INLINE idVec6 &idMat6::operator[]( int index ) { + //assert( ( index >= 0 ) && ( index < 6 ) ); + return mat[ index ]; +} + +ID_INLINE idMat6 idMat6::operator*( const idMat6 &a ) const { + int i, j; + const float *m1Ptr, *m2Ptr; + float *dstPtr; + idMat6 dst; + + m1Ptr = reinterpret_cast(this); + m2Ptr = reinterpret_cast(&a); + dstPtr = reinterpret_cast(&dst); + + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 6; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 6 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 6 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 6 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 6 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 6 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 6 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return dst; +} + +ID_INLINE idMat6 idMat6::operator*( const float a ) const { + return idMat6( + idVec6( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a, mat[0][5] * a ), + idVec6( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a, mat[1][5] * a ), + idVec6( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a, mat[2][5] * a ), + idVec6( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a, mat[3][5] * a ), + idVec6( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a, mat[4][5] * a ), + idVec6( mat[5][0] * a, mat[5][1] * a, mat[5][2] * a, mat[5][3] * a, mat[5][4] * a, mat[5][5] * a ) ); +} + +ID_INLINE idVec6 idMat6::operator*( const idVec6 &vec ) const { + return idVec6( + mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4] + mat[0][5] * vec[5], + mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4] + mat[1][5] * vec[5], + mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4] + mat[2][5] * vec[5], + mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4] + mat[3][5] * vec[5], + mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] + mat[4][5] * vec[5], + mat[5][0] * vec[0] + mat[5][1] * vec[1] + mat[5][2] * vec[2] + mat[5][3] * vec[3] + mat[5][4] * vec[4] + mat[5][5] * vec[5] ); +} + +ID_INLINE idMat6 idMat6::operator+( const idMat6 &a ) const { + return idMat6( + idVec6( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4], mat[0][5] + a[0][5] ), + idVec6( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4], mat[1][5] + a[1][5] ), + idVec6( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4], mat[2][5] + a[2][5] ), + idVec6( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4], mat[3][5] + a[3][5] ), + idVec6( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4], mat[4][5] + a[4][5] ), + idVec6( mat[5][0] + a[5][0], mat[5][1] + a[5][1], mat[5][2] + a[5][2], mat[5][3] + a[5][3], mat[5][4] + a[5][4], mat[5][5] + a[5][5] ) ); +} + +ID_INLINE idMat6 idMat6::operator-( const idMat6 &a ) const { + return idMat6( + idVec6( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4], mat[0][5] - a[0][5] ), + idVec6( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4], mat[1][5] - a[1][5] ), + idVec6( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4], mat[2][5] - a[2][5] ), + idVec6( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4], mat[3][5] - a[3][5] ), + idVec6( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4], mat[4][5] - a[4][5] ), + idVec6( mat[5][0] - a[5][0], mat[5][1] - a[5][1], mat[5][2] - a[5][2], mat[5][3] - a[5][3], mat[5][4] - a[5][4], mat[5][5] - a[5][5] ) ); +} + +ID_INLINE idMat6 &idMat6::operator*=( const float a ) { + mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a; mat[0][5] *= a; + mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a; mat[1][5] *= a; + mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a; mat[2][5] *= a; + mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a; mat[3][5] *= a; + mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a; mat[4][5] *= a; + mat[5][0] *= a; mat[5][1] *= a; mat[5][2] *= a; mat[5][3] *= a; mat[5][4] *= a; mat[5][5] *= a; + return *this; +} + +ID_INLINE idMat6 &idMat6::operator*=( const idMat6 &a ) { + *this = *this * a; + return *this; +} + +ID_INLINE idMat6 &idMat6::operator+=( const idMat6 &a ) { + mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4]; mat[0][5] += a[0][5]; + mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4]; mat[1][5] += a[1][5]; + mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4]; mat[2][5] += a[2][5]; + mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4]; mat[3][5] += a[3][5]; + mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4]; mat[4][5] += a[4][5]; + mat[5][0] += a[5][0]; mat[5][1] += a[5][1]; mat[5][2] += a[5][2]; mat[5][3] += a[5][3]; mat[5][4] += a[5][4]; mat[5][5] += a[5][5]; + return *this; +} + +ID_INLINE idMat6 &idMat6::operator-=( const idMat6 &a ) { + mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4]; mat[0][5] -= a[0][5]; + mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4]; mat[1][5] -= a[1][5]; + mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4]; mat[2][5] -= a[2][5]; + mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4]; mat[3][5] -= a[3][5]; + mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4]; mat[4][5] -= a[4][5]; + mat[5][0] -= a[5][0]; mat[5][1] -= a[5][1]; mat[5][2] -= a[5][2]; mat[5][3] -= a[5][3]; mat[5][4] -= a[5][4]; mat[5][5] -= a[5][5]; + return *this; +} + +ID_INLINE idVec6 operator*( const idVec6 &vec, const idMat6 &mat ) { + return mat * vec; +} + +ID_INLINE idMat6 operator*( const float a, idMat6 const &mat ) { + return mat * a; +} + +ID_INLINE idVec6 &operator*=( idVec6 &vec, const idMat6 &mat ) { + vec = mat * vec; + return vec; +} + +ID_INLINE bool idMat6::Compare( const idMat6 &a ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 6*6; i++ ) { + if ( ptr1[i] != ptr2[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat6::Compare( const idMat6 &a, const float epsilon ) const { + dword i; + const float *ptr1, *ptr2; + + ptr1 = reinterpret_cast(mat); + ptr2 = reinterpret_cast(a.mat); + for ( i = 0; i < 6*6; i++ ) { + if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMat6::operator==( const idMat6 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMat6::operator!=( const idMat6 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMat6::Zero( void ) { + memset( mat, 0, sizeof( idMat6 ) ); +} + +ID_INLINE void idMat6::Identity( void ) { + *this = mat6_identity; +} + +ID_INLINE bool idMat6::IsIdentity( const float epsilon ) const { + return Compare( mat6_identity, epsilon ); +} + +ID_INLINE bool idMat6::IsSymmetric( const float epsilon ) const { + for ( int i = 1; i < 6; i++ ) { + for ( int j = 0; j < i; j++ ) { + if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMat6::IsDiagonal( const float epsilon ) const { + for ( int i = 0; i < 6; i++ ) { + for ( int j = 0; j < 6; j++ ) { + if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE idMat3 idMat6::SubMat3( int n ) const { + assert( n >= 0 && n < 4 ); + int b0 = ((n & 2) >> 1) * 3; + int b1 = (n & 1) * 3; + return idMat3( + mat[b0 + 0][b1 + 0], mat[b0 + 0][b1 + 1], mat[b0 + 0][b1 + 2], + mat[b0 + 1][b1 + 0], mat[b0 + 1][b1 + 1], mat[b0 + 1][b1 + 2], + mat[b0 + 2][b1 + 0], mat[b0 + 2][b1 + 1], mat[b0 + 2][b1 + 2] ); +} + +ID_INLINE float idMat6::Trace( void ) const { + return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] + mat[5][5] ); +} + +ID_INLINE idMat6 idMat6::Inverse( void ) const { + idMat6 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE idMat6 idMat6::InverseFast( void ) const { + idMat6 invMat; + + invMat = *this; + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE int idMat6::GetDimension( void ) const { + return 36; +} + +ID_INLINE const float *idMat6::ToFloatPtr( void ) const { + return mat[0].ToFloatPtr(); +} + +ID_INLINE float *idMat6::ToFloatPtr( void ) { + return mat[0].ToFloatPtr(); +} + + +//=============================================================== +// +// idMatX - arbitrary sized dense real matrix +// +// The matrix lives on 16 byte aligned and 16 byte padded memory. +// +// NOTE: due to the temporary memory pool idMatX cannot be used by multiple threads. +// +//=============================================================== + +#define MATX_MAX_TEMP 1024 +#define MATX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) ) +#define MATX_CLEAREND() int s = numRows * numColumns; while( s < ( ( s + 3 ) & ~3 ) ) { mat[s++] = 0.0f; } +#define MATX_ALLOCA( n ) ( (float *) _alloca16( MATX_QUAD( n ) ) ) +#define MATX_SIMD + +class idMatX { +public: + idMatX( void ); + explicit idMatX( int rows, int columns ); + explicit idMatX( int rows, int columns, float *src ); + ~idMatX( void ); + + void Set( int rows, int columns, const float *src ); + void Set( const idMat3 &m1, const idMat3 &m2 ); + void Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 ); + + const float * operator[]( int index ) const; + float * operator[]( int index ); + idMatX & operator=( const idMatX &a ); + idMatX operator*( const float a ) const; + idVecX operator*( const idVecX &vec ) const; + idMatX operator*( const idMatX &a ) const; + idMatX operator+( const idMatX &a ) const; + idMatX operator-( const idMatX &a ) const; + idMatX & operator*=( const float a ); + idMatX & operator*=( const idMatX &a ); + idMatX & operator+=( const idMatX &a ); + idMatX & operator-=( const idMatX &a ); + + friend idMatX operator*( const float a, const idMatX &m ); + friend idVecX operator*( const idVecX &vec, const idMatX &m ); + friend idVecX & operator*=( idVecX &vec, const idMatX &m ); + + bool Compare( const idMatX &a ) const; // exact compare, no epsilon + bool Compare( const idMatX &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idMatX &a ) const; // exact compare, no epsilon + bool operator!=( const idMatX &a ) const; // exact compare, no epsilon + + void SetSize( int rows, int columns ); // set the number of rows/columns + void ChangeSize( int rows, int columns, bool makeZero = false ); // change the size keeping data intact where possible + int GetNumRows( void ) const { return numRows; } // get the number of rows + int GetNumColumns( void ) const { return numColumns; } // get the number of columns + void SetData( int rows, int columns, float *data ); // set float array pointer + void Zero( void ); // clear matrix + void Zero( int rows, int columns ); // set size and clear matrix + void Identity( void ); // clear to identity matrix + void Identity( int rows, int columns ); // set size and clear to identity matrix + void Diag( const idVecX &v ); // create diagonal matrix from vector + void Random( int seed, float l = 0.0f, float u = 1.0f ); // fill matrix with random values + void Random( int rows, int columns, int seed, float l = 0.0f, float u = 1.0f ); + void Negate( void ); // (*this) = - (*this) + void Clamp( float min, float max ); // clamp all values + idMatX & SwapRows( int r1, int r2 ); // swap rows + idMatX & SwapColumns( int r1, int r2 ); // swap columns + idMatX & SwapRowsColumns( int r1, int r2 ); // swap rows and columns + idMatX & RemoveRow( int r ); // remove a row + idMatX & RemoveColumn( int r ); // remove a column + idMatX & RemoveRowColumn( int r ); // remove a row and column + void ClearUpperTriangle( void ); // clear the upper triangle + void ClearLowerTriangle( void ); // clear the lower triangle + void SquareSubMatrix( const idMatX &m, int size ); // get square sub-matrix from 0,0 to size,size + float MaxDifference( const idMatX &m ) const; // return maximum element difference between this and m + + bool IsSquare( void ) const { return ( numRows == numColumns ); } + bool IsZero( const float epsilon = MATRIX_EPSILON ) const; + bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; + bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; + bool IsTriDiagonal( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; + bool IsOrthogonal( const float epsilon = MATRIX_EPSILON ) const; + bool IsOrthonormal( const float epsilon = MATRIX_EPSILON ) const; + bool IsPMatrix( const float epsilon = MATRIX_EPSILON ) const; + bool IsZMatrix( const float epsilon = MATRIX_EPSILON ) const; + bool IsPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetricPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const; + bool IsPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const; + bool IsSymmetricPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const; + + float Trace( void ) const; // returns product of diagonal elements + float Determinant( void ) const; // returns determinant of matrix + idMatX Transpose( void ) const; // returns transpose + idMatX & TransposeSelf( void ); // transposes the matrix itself + idMatX Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseSelf( void ); // returns false if determinant is zero + idMatX InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) + bool InverseFastSelf( void ); // returns false if determinant is zero + + bool LowerTriangularInverse( void ); // in-place inversion, returns false if determinant is zero + bool UpperTriangularInverse( void ); // in-place inversion, returns false if determinant is zero + + idVecX Multiply( const idVecX &vec ) const; // (*this) * vec + idVecX TransposeMultiply( const idVecX &vec ) const; // this->Transpose() * vec + + idMatX Multiply( const idMatX &a ) const; // (*this) * a + idMatX TransposeMultiply( const idMatX &a ) const; // this->Transpose() * a + + void Multiply( idVecX &dst, const idVecX &vec ) const; // dst = (*this) * vec + void MultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += (*this) * vec + void MultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= (*this) * vec + void TransposeMultiply( idVecX &dst, const idVecX &vec ) const; // dst = this->Transpose() * vec + void TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += this->Transpose() * vec + void TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= this->Transpose() * vec + + void Multiply( idMatX &dst, const idMatX &a ) const; // dst = (*this) * a + void TransposeMultiply( idMatX &dst, const idMatX &a ) const; // dst = this->Transpose() * a + + int GetDimension( void ) const; // returns total number of values in matrix + + const idVec6 & SubVec6( int row ) const; // interpret beginning of row as a const idVec6 + idVec6 & SubVec6( int row ); // interpret beginning of row as an idVec6 + const idVecX SubVecX( int row ) const; // interpret complete row as a const idVecX + idVecX SubVecX( int row ); // interpret complete row as an idVecX + const float * ToFloatPtr( void ) const; // pointer to const matrix float array + float * ToFloatPtr( void ); // pointer to matrix float array + const char * ToString( int precision = 2 ) const; + + void Update_RankOne( const idVecX &v, const idVecX &w, float alpha ); + void Update_RankOneSymmetric( const idVecX &v, float alpha ); + void Update_RowColumn( const idVecX &v, const idVecX &w, int r ); + void Update_RowColumnSymmetric( const idVecX &v, int r ); + void Update_Increment( const idVecX &v, const idVecX &w ); + void Update_IncrementSymmetric( const idVecX &v ); + void Update_Decrement( int r ); + + bool Inverse_GaussJordan( void ); // invert in-place with Gauss-Jordan elimination + bool Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha ); + bool Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r ); + bool Inverse_UpdateIncrement( const idVecX &v, const idVecX &w ); + bool Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r ); + void Inverse_Solve( idVecX &x, const idVecX &b ) const; + + bool LU_Factor( int *index, float *det = NULL ); // factor in-place: L * U + bool LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index ); + bool LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index ); + bool LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index ); + bool LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index ); + void LU_Solve( idVecX &x, const idVecX &b, const int *index ) const; + void LU_Inverse( idMatX &inv, const int *index ) const; + void LU_UnpackFactors( idMatX &L, idMatX &U ) const; + void LU_MultiplyFactors( idMatX &m, const int *index ) const; + + bool QR_Factor( idVecX &c, idVecX &d ); // factor in-place: Q * R + bool QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha ); + bool QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r ); + bool QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w ); + bool QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r ); + void QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const; + void QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const; + void QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const; + void QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const; + void QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const; + + bool SVD_Factor( idVecX &w, idMatX &V ); // factor in-place: U * Diag(w) * V.Transpose() + void SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const; + void SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const; + void SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const; + + bool Cholesky_Factor( void ); // factor in-place: L * L.Transpose() + bool Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 ); + bool Cholesky_UpdateRowColumn( const idVecX &v, int r ); + bool Cholesky_UpdateIncrement( const idVecX &v ); + bool Cholesky_UpdateDecrement( const idVecX &v, int r ); + void Cholesky_Solve( idVecX &x, const idVecX &b ) const; + void Cholesky_Inverse( idMatX &inv ) const; + void Cholesky_MultiplyFactors( idMatX &m ) const; + + bool LDLT_Factor( void ); // factor in-place: L * D * L.Transpose() + bool LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 ); + bool LDLT_UpdateRowColumn( const idVecX &v, int r ); + bool LDLT_UpdateIncrement( const idVecX &v ); + bool LDLT_UpdateDecrement( const idVecX &v, int r ); + void LDLT_Solve( idVecX &x, const idVecX &b ) const; + void LDLT_Inverse( idMatX &inv ) const; + void LDLT_UnpackFactors( idMatX &L, idMatX &D ) const; + void LDLT_MultiplyFactors( idMatX &m ) const; + + void TriDiagonal_ClearTriangles( void ); + bool TriDiagonal_Solve( idVecX &x, const idVecX &b ) const; + void TriDiagonal_Inverse( idMatX &inv ) const; + + bool Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues ); + bool Eigen_SolveSymmetric( idVecX &eigenValues ); + bool Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues ); + void Eigen_SortIncreasing( idVecX &eigenValues ); + void Eigen_SortDecreasing( idVecX &eigenValues ); + + static void Test( void ); + +private: + int numRows; // number of rows + int numColumns; // number of columns + int alloced; // floats allocated, if -1 then mat points to data set with SetData + float * mat; // memory the matrix is stored + + static float temp[MATX_MAX_TEMP+4]; // used to store intermediate results + static float * tempPtr; // pointer to 16 byte aligned temporary memory + static int tempIndex; // index into memory pool, wraps around + +private: + void SetTempSize( int rows, int columns ); + float DeterminantGeneric( void ) const; + bool InverseSelfGeneric( void ); + void QR_Rotate( idMatX &R, int i, float a, float b ); + float Pythag( float a, float b ) const; + void SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm ); + void SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 ); + void HouseholderReduction( idVecX &diag, idVecX &subd ); + bool QL( idVecX &diag, idVecX &subd ); + void HessenbergReduction( idMatX &H ); + void ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi ); + bool HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues ); +}; + +ID_INLINE idMatX::idMatX( void ) { + numRows = numColumns = alloced = 0; + mat = NULL; +} + +ID_INLINE idMatX::~idMatX( void ) { + // if not temp memory + if ( mat != NULL && ( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ) && alloced != -1 ) { + Mem_Free16( mat ); + } +} + +ID_INLINE idMatX::idMatX( int rows, int columns ) { + numRows = numColumns = alloced = 0; + mat = NULL; + SetSize( rows, columns ); +} + +ID_INLINE idMatX::idMatX( int rows, int columns, float *src ) { + numRows = numColumns = alloced = 0; + mat = NULL; + SetData( rows, columns, src ); +} + +ID_INLINE void idMatX::Set( int rows, int columns, const float *src ) { + SetSize( rows, columns ); + memcpy( this->mat, src, rows * columns * sizeof( float ) ); +} + +ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2 ) { + int i, j; + + SetSize( 3, 6 ); + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + mat[(i+0) * numColumns + (j+0)] = m1[i][j]; + mat[(i+0) * numColumns + (j+3)] = m2[i][j]; + } + } +} + +ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 ) { + int i, j; + + SetSize( 6, 6 ); + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + mat[(i+0) * numColumns + (j+0)] = m1[i][j]; + mat[(i+0) * numColumns + (j+3)] = m2[i][j]; + mat[(i+3) * numColumns + (j+0)] = m3[i][j]; + mat[(i+3) * numColumns + (j+3)] = m4[i][j]; + } + } +} + +ID_INLINE const float *idMatX::operator[]( int index ) const { + assert( ( index >= 0 ) && ( index < numRows ) ); + return mat + index * numColumns; +} + +ID_INLINE float *idMatX::operator[]( int index ) { + assert( ( index >= 0 ) && ( index < numRows ) ); + return mat + index * numColumns; +} + +ID_INLINE idMatX &idMatX::operator=( const idMatX &a ) { + SetSize( a.numRows, a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->Copy16( mat, a.mat, a.numRows * a.numColumns ); +#else + memcpy( mat, a.mat, a.numRows * a.numColumns * sizeof( float ) ); +#endif + idMatX::tempIndex = 0; + return *this; +} + +ID_INLINE idMatX idMatX::operator*( const float a ) const { + idMatX m; + + m.SetTempSize( numRows, numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->Mul16( m.mat, mat, a, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + m.mat[i] = mat[i] * a; + } +#endif + return m; +} + +ID_INLINE idVecX idMatX::operator*( const idVecX &vec ) const { + idVecX dst; + + assert( numColumns == vec.GetSize() ); + + dst.SetTempSize( numRows ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); +#else + Multiply( dst, vec ); +#endif + return dst; +} + +ID_INLINE idMatX idMatX::operator*( const idMatX &a ) const { + idMatX dst; + + assert( numColumns == a.numRows ); + + dst.SetTempSize( numRows, a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); +#else + Multiply( dst, a ); +#endif + return dst; +} + +ID_INLINE idMatX idMatX::operator+( const idMatX &a ) const { + idMatX m; + + assert( numRows == a.numRows && numColumns == a.numColumns ); + m.SetTempSize( numRows, numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->Add16( m.mat, mat, a.mat, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + m.mat[i] = mat[i] + a.mat[i]; + } +#endif + return m; +} + +ID_INLINE idMatX idMatX::operator-( const idMatX &a ) const { + idMatX m; + + assert( numRows == a.numRows && numColumns == a.numColumns ); + m.SetTempSize( numRows, numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->Sub16( m.mat, mat, a.mat, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + m.mat[i] = mat[i] - a.mat[i]; + } +#endif + return m; +} + +ID_INLINE idMatX &idMatX::operator*=( const float a ) { +#ifdef MATX_SIMD + SIMDProcessor->MulAssign16( mat, a, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] *= a; + } +#endif + idMatX::tempIndex = 0; + return *this; +} + +ID_INLINE idMatX &idMatX::operator*=( const idMatX &a ) { + *this = *this * a; + idMatX::tempIndex = 0; + return *this; +} + +ID_INLINE idMatX &idMatX::operator+=( const idMatX &a ) { + assert( numRows == a.numRows && numColumns == a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->AddAssign16( mat, a.mat, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] += a.mat[i]; + } +#endif + idMatX::tempIndex = 0; + return *this; +} + +ID_INLINE idMatX &idMatX::operator-=( const idMatX &a ) { + assert( numRows == a.numRows && numColumns == a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->SubAssign16( mat, a.mat, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] -= a.mat[i]; + } +#endif + idMatX::tempIndex = 0; + return *this; +} + +ID_INLINE idMatX operator*( const float a, idMatX const &m ) { + return m * a; +} + +ID_INLINE idVecX operator*( const idVecX &vec, const idMatX &m ) { + return m * vec; +} + +ID_INLINE idVecX &operator*=( idVecX &vec, const idMatX &m ) { + vec = m * vec; + return vec; +} + +ID_INLINE bool idMatX::Compare( const idMatX &a ) const { + int i, s; + + assert( numRows == a.numRows && numColumns == a.numColumns ); + + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + if ( mat[i] != a.mat[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMatX::Compare( const idMatX &a, const float epsilon ) const { + int i, s; + + assert( numRows == a.numRows && numColumns == a.numColumns ); + + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idMatX::operator==( const idMatX &a ) const { + return Compare( a ); +} + +ID_INLINE bool idMatX::operator!=( const idMatX &a ) const { + return !Compare( a ); +} + +ID_INLINE void idMatX::SetSize( int rows, int columns ) { + assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ); + int alloc = ( rows * columns + 3 ) & ~3; + if ( alloc > alloced && alloced != -1 ) { + if ( mat != NULL ) { + Mem_Free16( mat ); + } + mat = (float *) Mem_Alloc16( alloc * sizeof( float ) ); + alloced = alloc; + } + numRows = rows; + numColumns = columns; + MATX_CLEAREND(); +} + +ID_INLINE void idMatX::SetTempSize( int rows, int columns ) { + int newSize; + + newSize = ( rows * columns + 3 ) & ~3; + assert( newSize < MATX_MAX_TEMP ); + if ( idMatX::tempIndex + newSize > MATX_MAX_TEMP ) { + idMatX::tempIndex = 0; + } + mat = idMatX::tempPtr + idMatX::tempIndex; + idMatX::tempIndex += newSize; + alloced = newSize; + numRows = rows; + numColumns = columns; + MATX_CLEAREND(); +} + +ID_INLINE void idMatX::SetData( int rows, int columns, float *data ) { + assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ); + if ( mat != NULL && alloced != -1 ) { + Mem_Free16( mat ); + } + assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned + mat = data; + alloced = -1; + numRows = rows; + numColumns = columns; + MATX_CLEAREND(); +} + +ID_INLINE void idMatX::Zero( void ) { +#ifdef MATX_SIMD + SIMDProcessor->Zero16( mat, numRows * numColumns ); +#else + memset( mat, 0, numRows * numColumns * sizeof( float ) ); +#endif +} + +ID_INLINE void idMatX::Zero( int rows, int columns ) { + SetSize( rows, columns ); +#ifdef MATX_SIMD + SIMDProcessor->Zero16( mat, numRows * numColumns ); +#else + memset( mat, 0, rows * columns * sizeof( float ) ); +#endif +} + +ID_INLINE void idMatX::Identity( void ) { + assert( numRows == numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->Zero16( mat, numRows * numColumns ); +#else + memset( mat, 0, numRows * numColumns * sizeof( float ) ); +#endif + for ( int i = 0; i < numRows; i++ ) { + mat[i * numColumns + i] = 1.0f; + } +} + +ID_INLINE void idMatX::Identity( int rows, int columns ) { + assert( rows == columns ); + SetSize( rows, columns ); + idMatX::Identity(); +} + +ID_INLINE void idMatX::Diag( const idVecX &v ) { + Zero( v.GetSize(), v.GetSize() ); + for ( int i = 0; i < v.GetSize(); i++ ) { + mat[i * numColumns + i] = v[i]; + } +} + +ID_INLINE void idMatX::Random( int seed, float l, float u ) { + int i, s; + float c; + idRandom rnd(seed); + + c = u - l; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] = l + rnd.RandomFloat() * c; + } +} + +ID_INLINE void idMatX::Random( int rows, int columns, int seed, float l, float u ) { + int i, s; + float c; + idRandom rnd(seed); + + SetSize( rows, columns ); + c = u - l; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] = l + rnd.RandomFloat() * c; + } +} + +ID_INLINE void idMatX::Negate( void ) { +#ifdef MATX_SIMD + SIMDProcessor->Negate16( mat, numRows * numColumns ); +#else + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + mat[i] = -mat[i]; + } +#endif +} + +ID_INLINE void idMatX::Clamp( float min, float max ) { + int i, s; + s = numRows * numColumns; + for ( i = 0; i < s; i++ ) { + if ( mat[i] < min ) { + mat[i] = min; + } else if ( mat[i] > max ) { + mat[i] = max; + } + } +} + +inline idMatX &idMatX::SwapRows( int r1, int r2 ) { + float *ptr; + + ptr = (float *) _alloca16( numColumns * sizeof( float ) ); + memcpy( ptr, mat + r1 * numColumns, numColumns * sizeof( float ) ); + memcpy( mat + r1 * numColumns, mat + r2 * numColumns, numColumns * sizeof( float ) ); + memcpy( mat + r2 * numColumns, ptr, numColumns * sizeof( float ) ); + + return *this; +} + +ID_INLINE idMatX &idMatX::SwapColumns( int r1, int r2 ) { + int i; + float tmp, *ptr; + + for ( i = 0; i < numRows; i++ ) { + ptr = mat + i * numColumns; + tmp = ptr[r1]; + ptr[r1] = ptr[r2]; + ptr[r2] = tmp; + } + + return *this; +} + +ID_INLINE idMatX &idMatX::SwapRowsColumns( int r1, int r2 ) { + + SwapRows( r1, r2 ); + SwapColumns( r1, r2 ); + return *this; +} + +ID_INLINE void idMatX::ClearUpperTriangle( void ) { + assert( numRows == numColumns ); + for ( int i = numRows-2; i >= 0; i-- ) { + memset( mat + i * numColumns + i + 1, 0, (numColumns - 1 - i) * sizeof(float) ); + } +} + +ID_INLINE void idMatX::ClearLowerTriangle( void ) { + assert( numRows == numColumns ); + for ( int i = 1; i < numRows; i++ ) { + memset( mat + i * numColumns, 0, i * sizeof(float) ); + } +} + +ID_INLINE void idMatX::SquareSubMatrix( const idMatX &m, int size ) { + int i; + assert( size <= m.numRows && size <= m.numColumns ); + SetSize( size, size ); + for ( i = 0; i < size; i++ ) { + memcpy( mat + i * numColumns, m.mat + i * m.numColumns, size * sizeof( float ) ); + } +} + +ID_INLINE float idMatX::MaxDifference( const idMatX &m ) const { + int i, j; + float diff, maxDiff; + + assert( numRows == m.numRows && numColumns == m.numColumns ); + + maxDiff = -1.0f; + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + diff = idMath::Fabs( mat[ i * numColumns + j ] - m[i][j] ); + if ( maxDiff < 0.0f || diff > maxDiff ) { + maxDiff = diff; + } + } + } + return maxDiff; +} + +ID_INLINE bool idMatX::IsZero( const float epsilon ) const { + // returns true if (*this) == Zero + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + if ( idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMatX::IsIdentity( const float epsilon ) const { + // returns true if (*this) == Identity + assert( numRows == numColumns ); + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + if ( idMath::Fabs( mat[i * numColumns + j] - (float)( i == j ) ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMatX::IsDiagonal( const float epsilon ) const { + // returns true if all elements are zero except for the elements on the diagonal + assert( numRows == numColumns ); + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + if ( i != j && idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMatX::IsTriDiagonal( const float epsilon ) const { + // returns true if all elements are zero except for the elements on the diagonal plus or minus one column + + if ( numRows != numColumns ) { + return false; + } + for ( int i = 0; i < numRows-2; i++ ) { + for ( int j = i+2; j < numColumns; j++ ) { + if ( idMath::Fabs( (*this)[i][j] ) > epsilon ) { + return false; + } + if ( idMath::Fabs( (*this)[j][i] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE bool idMatX::IsSymmetric( const float epsilon ) const { + // (*this)[i][j] == (*this)[j][i] + if ( numRows != numColumns ) { + return false; + } + for ( int i = 0; i < numRows; i++ ) { + for ( int j = 0; j < numColumns; j++ ) { + if ( idMath::Fabs( mat[ i * numColumns + j ] - mat[ j * numColumns + i ] ) > epsilon ) { + return false; + } + } + } + return true; +} + +ID_INLINE float idMatX::Trace( void ) const { + float trace = 0.0f; + + assert( numRows == numColumns ); + + // sum of elements on the diagonal + for ( int i = 0; i < numRows; i++ ) { + trace += mat[i * numRows + i]; + } + return trace; +} + +ID_INLINE float idMatX::Determinant( void ) const { + + assert( numRows == numColumns ); + + switch( numRows ) { + case 1: + return mat[0]; + case 2: + return reinterpret_cast(mat)->Determinant(); + case 3: + return reinterpret_cast(mat)->Determinant(); + case 4: + return reinterpret_cast(mat)->Determinant(); + case 5: + return reinterpret_cast(mat)->Determinant(); + case 6: + return reinterpret_cast(mat)->Determinant(); + default: + return DeterminantGeneric(); + } + return 0.0f; +} + +ID_INLINE idMatX idMatX::Transpose( void ) const { + idMatX transpose; + int i, j; + + transpose.SetTempSize( numColumns, numRows ); + + for ( i = 0; i < numRows; i++ ) { + for ( j = 0; j < numColumns; j++ ) { + transpose.mat[j * transpose.numColumns + i] = mat[i * numColumns + j]; + } + } + + return transpose; +} + +ID_INLINE idMatX &idMatX::TransposeSelf( void ) { + *this = Transpose(); + return *this; +} + +ID_INLINE idMatX idMatX::Inverse( void ) const { + idMatX invMat; + + invMat.SetTempSize( numRows, numColumns ); + memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) ); + +#ifdef DEBUG + int r = invMat.InverseSelf(); + assert( r ); +#else + invMat.InverseSelf(); +#endif + + return invMat; +} + +ID_INLINE bool idMatX::InverseSelf( void ) { + + assert( numRows == numColumns ); + + switch( numRows ) { + case 1: + if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + mat[0] = 1.0f / mat[0]; + return true; + case 2: + return reinterpret_cast(mat)->InverseSelf(); + case 3: + return reinterpret_cast(mat)->InverseSelf(); + case 4: + return reinterpret_cast(mat)->InverseSelf(); + case 5: + return reinterpret_cast(mat)->InverseSelf(); + case 6: + return reinterpret_cast(mat)->InverseSelf(); + default: + return InverseSelfGeneric(); + } +} + +ID_INLINE idMatX idMatX::InverseFast( void ) const { + idMatX invMat; + + invMat.SetTempSize( numRows, numColumns ); + memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) ); + +#ifdef DEBUG + int r = invMat.InverseFastSelf(); + assert( r ); +#else + invMat.InverseFastSelf(); +#endif + + return invMat; +} + +ID_INLINE bool idMatX::InverseFastSelf( void ) { + + assert( numRows == numColumns ); + + switch( numRows ) { + case 1: + if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) { + return false; + } + mat[0] = 1.0f / mat[0]; + return true; + case 2: + return reinterpret_cast(mat)->InverseFastSelf(); + case 3: + return reinterpret_cast(mat)->InverseFastSelf(); + case 4: + return reinterpret_cast(mat)->InverseFastSelf(); + case 5: + return reinterpret_cast(mat)->InverseFastSelf(); + case 6: + return reinterpret_cast(mat)->InverseFastSelf(); + default: + return InverseSelfGeneric(); + } +// return false; +} + +ID_INLINE idVecX idMatX::Multiply( const idVecX &vec ) const { + idVecX dst; + + assert( numColumns == vec.GetSize() ); + + dst.SetTempSize( numRows ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); +#else + Multiply( dst, vec ); +#endif + return dst; +} + +ID_INLINE idMatX idMatX::Multiply( const idMatX &a ) const { + idMatX dst; + + assert( numColumns == a.numRows ); + + dst.SetTempSize( numRows, a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); +#else + Multiply( dst, a ); +#endif + return dst; +} + +ID_INLINE idVecX idMatX::TransposeMultiply( const idVecX &vec ) const { + idVecX dst; + + assert( numRows == vec.GetSize() ); + + dst.SetTempSize( numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec ); +#else + TransposeMultiply( dst, vec ); +#endif + return dst; +} + +ID_INLINE idMatX idMatX::TransposeMultiply( const idMatX &a ) const { + idMatX dst; + + assert( numRows == a.numRows ); + + dst.SetTempSize( numColumns, a.numColumns ); +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a ); +#else + TransposeMultiply( dst, a ); +#endif + return dst; +} + +ID_INLINE void idMatX::Multiply( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + mPtr = mat; + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] = sum; + mPtr += numColumns; + } +#endif +} + +ID_INLINE void idMatX::MultiplyAdd( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyAddVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + mPtr = mat; + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] += sum; + mPtr += numColumns; + } +#endif +} + +ID_INLINE void idMatX::MultiplySub( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplySubVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + mPtr = mat; + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] -= sum; + mPtr += numColumns; + } +#endif +} + +ID_INLINE void idMatX::TransposeMultiply( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat + i; + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] = sum; + } +#endif +} + +ID_INLINE void idMatX::TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplyAddVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat + i; + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] += sum; + } +#endif +} + +ID_INLINE void idMatX::TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplySubVecX( dst, *this, vec ); +#else + int i, j; + const float *mPtr, *vPtr; + float *dstPtr; + + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat + i; + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] -= sum; + } +#endif +} + +ID_INLINE void idMatX::Multiply( idMatX &dst, const idMatX &a ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); +#else + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( numColumns == a.numRows ); + + dstPtr = dst.ToFloatPtr(); + m1Ptr = ToFloatPtr(); + m2Ptr = a.ToFloatPtr(); + k = numRows; + l = a.GetNumColumns(); + + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m2Ptr = a.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < numColumns; n++ ) { + m2Ptr += l; + sum += m1Ptr[n] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + m1Ptr += numColumns; + } +#endif +} + +ID_INLINE void idMatX::TransposeMultiply( idMatX &dst, const idMatX &a ) const { +#ifdef MATX_SIMD + SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a ); +#else + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( numRows == a.numRows ); + + dstPtr = dst.ToFloatPtr(); + m1Ptr = ToFloatPtr(); + k = numColumns; + l = a.numColumns; + + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m1Ptr = ToFloatPtr() + i; + m2Ptr = a.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < numRows; n++ ) { + m1Ptr += numColumns; + m2Ptr += a.numColumns; + sum += m1Ptr[0] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + } +#endif +} + +ID_INLINE int idMatX::GetDimension( void ) const { + return numRows * numColumns; +} + +ID_INLINE const idVec6 &idMatX::SubVec6( int row ) const { + assert( numColumns >= 6 && row >= 0 && row < numRows ); + return *reinterpret_cast(mat + row * numColumns); +} + +ID_INLINE idVec6 &idMatX::SubVec6( int row ) { + assert( numColumns >= 6 && row >= 0 && row < numRows ); + return *reinterpret_cast(mat + row * numColumns); +} + +ID_INLINE const idVecX idMatX::SubVecX( int row ) const { + idVecX v; + assert( row >= 0 && row < numRows ); + v.SetData( numColumns, mat + row * numColumns ); + return v; +} + +ID_INLINE idVecX idMatX::SubVecX( int row ) { + idVecX v; + assert( row >= 0 && row < numRows ); + v.SetData( numColumns, mat + row * numColumns ); + return v; +} + +ID_INLINE const float *idMatX::ToFloatPtr( void ) const { + return mat; +} + +ID_INLINE float *idMatX::ToFloatPtr( void ) { + return mat; +} + +#endif /* !__MATH_MATRIX_H__ */ diff --git a/idlib/math/Ode.cpp b/idlib/math/Ode.cpp new file mode 100644 index 000000000..6e8dc6ddf --- /dev/null +++ b/idlib/math/Ode.cpp @@ -0,0 +1,346 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +//=============================================================== +// +// idODE_Euler +// +//=============================================================== + +/* +============= +idODE_Euler::idODE_Euler +============= +*/ +idODE_Euler::idODE_Euler( const int dim, deriveFunction_t dr, const void *ud ) { + dimension = dim; + derivatives = new float[dim]; + derive = dr; + userData = ud; +} + +/* +============= +idODE_Euler::~idODE_Euler +============= +*/ +idODE_Euler::~idODE_Euler( void ) { + delete[] derivatives; +} + +/* +============= +idODE_Euler::Evaluate +============= +*/ +float idODE_Euler::Evaluate( const float *state, float *newState, float t0, float t1 ) { + float delta; + int i; + + derive( t0, userData, state, derivatives ); + delta = t1 - t0; + for ( i = 0; i < dimension; i++ ) { + newState[i] = state[i] + delta * derivatives[i]; + } + return delta; +} + +//=============================================================== +// +// idODE_Midpoint +// +//=============================================================== + +/* +============= +idODE_Midpoint::idODE_Midpoint +============= +*/ +idODE_Midpoint::idODE_Midpoint( const int dim, deriveFunction_t dr, const void *ud ) { + dimension = dim; + tmpState = new float[dim]; + derivatives = new float[dim]; + derive = dr; + userData = ud; +} + +/* +============= +idODE_Midpoint::~idODE_Midpoint +============= +*/ +idODE_Midpoint::~idODE_Midpoint( void ) { + delete tmpState; + delete derivatives; +} + +/* +============= +idODE_Midpoint::~Evaluate +============= +*/ +float idODE_Midpoint::Evaluate( const float *state, float *newState, float t0, float t1 ) { + double delta, halfDelta; + int i; + + delta = t1 - t0; + halfDelta = delta * 0.5; + // first step + derive( t0, userData, state, derivatives ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * derivatives[i]; + } + // second step + derive( t0 + halfDelta, userData, tmpState, derivatives ); + + for ( i = 0; i < dimension; i++ ) { + newState[i] = state[i] + delta * derivatives[i]; + } + return delta; +} + +//=============================================================== +// +// idODE_RK4 +// +//=============================================================== + +/* +============= +idODE_RK4::idODE_RK4 +============= +*/ +idODE_RK4::idODE_RK4( const int dim, deriveFunction_t dr, const void *ud ) { + dimension = dim; + derive = dr; + userData = ud; + tmpState = new float[dim]; + d1 = new float[dim]; + d2 = new float[dim]; + d3 = new float[dim]; + d4 = new float[dim]; +} + +/* +============= +idODE_RK4::~idODE_RK4 +============= +*/ +idODE_RK4::~idODE_RK4( void ) { + delete tmpState; + delete d1; + delete d2; + delete d3; + delete d4; +} + +/* +============= +idODE_RK4::Evaluate +============= +*/ +float idODE_RK4::Evaluate( const float *state, float *newState, float t0, float t1 ) { + double delta, halfDelta, sixthDelta; + int i; + + delta = t1 - t0; + halfDelta = delta * 0.5; + // first step + derive( t0, userData, state, d1 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d1[i]; + } + // second step + derive( t0 + halfDelta, userData, tmpState, d2 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d2[i]; + } + // third step + derive( t0 + halfDelta, userData, tmpState, d3 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + delta * d3[i]; + } + // fourth step + derive( t0 + delta, userData, tmpState, d4 ); + + sixthDelta = delta * (1.0/6.0); + for ( i = 0; i < dimension; i++ ) { + newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); + } + return delta; +} + +//=============================================================== +// +// idODE_RK4Adaptive +// +//=============================================================== + +/* +============= +idODE_RK4Adaptive::idODE_RK4Adaptive +============= +*/ +idODE_RK4Adaptive::idODE_RK4Adaptive( const int dim, deriveFunction_t dr, const void *ud ) { + dimension = dim; + derive = dr; + userData = ud; + maxError = 0.01f; + tmpState = new float[dim]; + d1 = new float[dim]; + d1half = new float [dim]; + d2 = new float[dim]; + d3 = new float[dim]; + d4 = new float[dim]; +} + +/* +============= +idODE_RK4Adaptive::~idODE_RK4Adaptive +============= +*/ +idODE_RK4Adaptive::~idODE_RK4Adaptive( void ) { + delete tmpState; + delete d1; + delete d1half; + delete d2; + delete d3; + delete d4; +} + +/* +============= +idODE_RK4Adaptive::SetMaxError +============= +*/ +void idODE_RK4Adaptive::SetMaxError( const float err ) { + if ( err > 0.0f ) { + maxError = err; + } +} + +/* +============= +idODE_RK4Adaptive::Evaluate +============= +*/ +float idODE_RK4Adaptive::Evaluate( const float *state, float *newState, float t0, float t1 ) { + double delta, halfDelta, fourthDelta, sixthDelta; + double error, max; + int i, n; + + delta = t1 - t0; + + for ( n = 0; n < 4; n++ ) { + + halfDelta = delta * 0.5; + fourthDelta = delta * 0.25; + + // first step of first half delta + derive( t0, userData, state, d1 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + fourthDelta * d1[i]; + } + // second step of first half delta + derive( t0 + fourthDelta, userData, tmpState, d2 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + fourthDelta * d2[i]; + } + // third step of first half delta + derive( t0 + fourthDelta, userData, tmpState, d3 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d3[i]; + } + // fourth step of first half delta + derive( t0 + halfDelta, userData, tmpState, d4 ); + + sixthDelta = halfDelta * (1.0/6.0); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); + } + + // first step of second half delta + derive( t0 + halfDelta, userData, tmpState, d1half ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + fourthDelta * d1half[i]; + } + // second step of second half delta + derive( t0 + halfDelta + fourthDelta, userData, tmpState, d2 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + fourthDelta * d2[i]; + } + // third step of second half delta + derive( t0 + halfDelta + fourthDelta, userData, tmpState, d3 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d3[i]; + } + // fourth step of second half delta + derive( t0 + delta, userData, tmpState, d4 ); + + sixthDelta = halfDelta * (1.0/6.0); + for ( i = 0; i < dimension; i++ ) { + newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); + } + + // first step of full delta + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d1[i]; + } + // second step of full delta + derive( t0 + halfDelta, userData, tmpState, d2 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + halfDelta * d2[i]; + } + // third step of full delta + derive( t0 + halfDelta, userData, tmpState, d3 ); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + delta * d3[i]; + } + // fourth step of full delta + derive( t0 + delta, userData, tmpState, d4 ); + + sixthDelta = delta * (1.0/6.0); + for ( i = 0; i < dimension; i++ ) { + tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); + } + + // get max estimated error + max = 0.0; + for ( i = 0; i < dimension; i++ ) { + error = idMath::Fabs( (newState[i] - tmpState[i]) / (delta * d1[i] + 1e-10) ); + if ( error > max ) { + max = error; + } + } + error = max / maxError; + + if ( error <= 1.0f ) { + return delta * 4.0; + } + if ( delta <= 1e-7 ) { + return delta; + } + delta *= 0.25; + } + return delta; +} + diff --git a/idlib/math/Ode.h b/idlib/math/Ode.h new file mode 100644 index 000000000..2ea15861a --- /dev/null +++ b/idlib/math/Ode.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_ODE_H__ +#define __MATH_ODE_H__ + +/* +=============================================================================== + + Numerical solvers for ordinary differential equations. + +=============================================================================== +*/ + + +//=============================================================== +// +// idODE +// +//=============================================================== + +typedef void (*deriveFunction_t)( const float t, const void *userData, const float *state, float *derivatives ); + +class idODE { + +public: + virtual ~idODE( void ) {} + + virtual float Evaluate( const float *state, float *newState, float t0, float t1 ) = 0; + +protected: + int dimension; // dimension in floats allocated for + deriveFunction_t derive; // derive function + const void * userData; // client data +}; + +//=============================================================== +// +// idODE_Euler +// +//=============================================================== + +class idODE_Euler : public idODE { + +public: + idODE_Euler( const int dim, const deriveFunction_t dr, const void *ud ); + virtual ~idODE_Euler( void ); + + virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); + +protected: + float * derivatives; // space to store derivatives +}; + +//=============================================================== +// +// idODE_Midpoint +// +//=============================================================== + +class idODE_Midpoint : public idODE { + +public: + idODE_Midpoint( const int dim, const deriveFunction_t dr, const void *ud ); + virtual ~idODE_Midpoint( void ); + + virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); + +protected: + float * tmpState; + float * derivatives; // space to store derivatives +}; + +//=============================================================== +// +// idODE_RK4 +// +//=============================================================== + +class idODE_RK4 : public idODE { + +public: + idODE_RK4( const int dim, const deriveFunction_t dr, const void *ud ); + virtual ~idODE_RK4( void ); + + virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); + +protected: + float * tmpState; + float * d1; // derivatives + float * d2; + float * d3; + float * d4; +}; + +//=============================================================== +// +// idODE_RK4Adaptive +// +//=============================================================== + +class idODE_RK4Adaptive : public idODE { + +public: + idODE_RK4Adaptive( const int dim, const deriveFunction_t dr, const void *ud ); + virtual ~idODE_RK4Adaptive( void ); + + virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); + void SetMaxError( const float err ); + +protected: + float maxError; // maximum allowed error + float * tmpState; + float * d1; // derivatives + float * d1half; + float * d2; + float * d3; + float * d4; +}; + +#endif /* !__MATH_ODE_H__ */ diff --git a/idlib/math/Plane.cpp b/idlib/math/Plane.cpp new file mode 100644 index 000000000..2594b7629 --- /dev/null +++ b/idlib/math/Plane.cpp @@ -0,0 +1,145 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +idPlane plane_origin( 0.0f, 0.0f, 0.0f, 0.0f ); + +/* +================ +idPlane::Type +================ +*/ +int idPlane::Type( void ) const { + if ( Normal()[0] == 0.0f ) { + if ( Normal()[1] == 0.0f ) { + return Normal()[2] > 0.0f ? PLANETYPE_Z : PLANETYPE_NEGZ; + } + else if ( Normal()[2] == 0.0f ) { + return Normal()[1] > 0.0f ? PLANETYPE_Y : PLANETYPE_NEGY; + } + else { + return PLANETYPE_ZEROX; + } + } + else if ( Normal()[1] == 0.0f ) { + if ( Normal()[2] == 0.0f ) { + return Normal()[0] > 0.0f ? PLANETYPE_X : PLANETYPE_NEGX; + } + else { + return PLANETYPE_ZEROY; + } + } + else if ( Normal()[2] == 0.0f ) { + return PLANETYPE_ZEROZ; + } + else { + return PLANETYPE_NONAXIAL; + } +} + +/* +================ +idPlane::HeightFit +================ +*/ +bool idPlane::HeightFit( const idVec3 *points, const int numPoints ) { + int i; + float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f; + float sumYY = 0.0f, sumYZ = 0.0f; + idVec3 sum, average, dir; + + if ( numPoints == 1 ) { + a = 0.0f; + b = 0.0f; + c = 1.0f; + d = -points[0].z; + return true; + } + if ( numPoints == 2 ) { + dir = points[1] - points[0]; + Normal() = dir.Cross( idVec3( 0, 0, 1 ) ).Cross( dir ); + Normalize(); + d = -( Normal() * points[0] ); + return true; + } + + sum.Zero(); + for ( i = 0; i < numPoints; i++) { + sum += points[i]; + } + average = sum / numPoints; + + for ( i = 0; i < numPoints; i++ ) { + dir = points[i] - average; + sumXX += dir.x * dir.x; + sumXY += dir.x * dir.y; + sumXZ += dir.x * dir.z; + sumYY += dir.y * dir.y; + sumYZ += dir.y * dir.z; + } + + idMat2 m( sumXX, sumXY, sumXY, sumYY ); + if ( !m.InverseSelf() ) { + return false; + } + + a = - sumXZ * m[0][0] - sumYZ * m[0][1]; + b = - sumXZ * m[1][0] - sumYZ * m[1][1]; + c = 1.0f; + Normalize(); + d = -( a * average.x + b * average.y + c * average.z ); + return true; +} + +/* +================ +idPlane::PlaneIntersection +================ +*/ +bool idPlane::PlaneIntersection( const idPlane &plane, idVec3 &start, idVec3 &dir ) const { + double n00, n01, n11, det, invDet, f0, f1; + + n00 = Normal().LengthSqr(); + n01 = Normal() * plane.Normal(); + n11 = plane.Normal().LengthSqr(); + det = n00 * n11 - n01 * n01; + + if ( idMath::Fabs(det) < 1e-6f ) { + return false; + } + + invDet = 1.0f / det; + f0 = ( n01 * plane.d - n11 * d ) * invDet; + f1 = ( n01 * d - n00 * plane.d ) * invDet; + + dir = Normal().Cross( plane.Normal() ); + start = f0 * Normal() + f1 * plane.Normal(); + return true; +} + +/* +============= +idPlane::ToString +============= +*/ +const char *idPlane::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Plane.h b/idlib/math/Plane.h new file mode 100644 index 000000000..0d567ac9b --- /dev/null +++ b/idlib/math/Plane.h @@ -0,0 +1,403 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_PLANE_H__ +#define __MATH_PLANE_H__ + +/* +=============================================================================== + + 3D plane with equation: a * x + b * y + c * z + d = 0 + +=============================================================================== +*/ + + +class idVec3; +class idMat3; + +#define ON_EPSILON 0.1f +#define DEGENERATE_DIST_EPSILON 1e-4f + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 +#define SIDE_CROSS 3 + +// plane sides +#define PLANESIDE_FRONT 0 +#define PLANESIDE_BACK 1 +#define PLANESIDE_ON 2 +#define PLANESIDE_CROSS 3 + +// plane types +#define PLANETYPE_X 0 +#define PLANETYPE_Y 1 +#define PLANETYPE_Z 2 +#define PLANETYPE_NEGX 3 +#define PLANETYPE_NEGY 4 +#define PLANETYPE_NEGZ 5 +#define PLANETYPE_TRUEAXIAL 6 // all types < 6 are true axial planes +#define PLANETYPE_ZEROX 6 +#define PLANETYPE_ZEROY 7 +#define PLANETYPE_ZEROZ 8 +#define PLANETYPE_NONAXIAL 9 + +class idPlane { +public: + idPlane( void ); + idPlane( float a, float b, float c, float d ); + idPlane( const idVec3 &normal, const float dist ); + + float operator[]( int index ) const; + float & operator[]( int index ); + idPlane operator-() const; // flips plane + idPlane & operator=( const idVec3 &v ); // sets normal and sets idPlane::d to zero + idPlane operator+( const idPlane &p ) const; // add plane equations + idPlane operator-( const idPlane &p ) const; // subtract plane equations + idPlane & operator*=( const idMat3 &m ); // Normal() *= m + + bool Compare( const idPlane &p ) const; // exact compare, no epsilon + bool Compare( const idPlane &p, const float epsilon ) const; // compare with epsilon + bool Compare( const idPlane &p, const float normalEps, const float distEps ) const; // compare with epsilon + bool operator==( const idPlane &p ) const; // exact compare, no epsilon + bool operator!=( const idPlane &p ) const; // exact compare, no epsilon + + void Zero( void ); // zero plane + void SetNormal( const idVec3 &normal ); // sets the normal + const idVec3 & Normal( void ) const; // reference to const normal + idVec3 & Normal( void ); // reference to normal + float Normalize( bool fixDegenerate = true ); // only normalizes the plane normal, does not adjust d + bool FixDegenerateNormal( void ); // fix degenerate normal + bool FixDegeneracies( float distEpsilon ); // fix degenerate normal and dist + float Dist( void ) const; // returns: -d + void SetDist( const float dist ); // sets: d = -dist + int Type( void ) const; // returns plane type + + bool FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate = true ); + bool FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate = true ); + void FitThroughPoint( const idVec3 &p ); // assumes normal is valid + bool HeightFit( const idVec3 *points, const int numPoints ); + idPlane Translate( const idVec3 &translation ) const; + idPlane & TranslateSelf( const idVec3 &translation ); + idPlane Rotate( const idVec3 &origin, const idMat3 &axis ) const; + idPlane & RotateSelf( const idVec3 &origin, const idMat3 &axis ); + + float Distance( const idVec3 &v ) const; + int Side( const idVec3 &v, const float epsilon = 0.0f ) const; + + bool LineIntersection( const idVec3 &start, const idVec3 &end, float *Fraction = NULL ) const; + // intersection point is start + dir * scale + bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const; + bool PlaneIntersection( const idPlane &plane, idVec3 &start, idVec3 &dir ) const; + + int GetDimension( void ) const; + + const idVec4 & ToVec4( void ) const; + idVec4 & ToVec4( void ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + void GetPlaneParams(float &a, float &b, float &c, float &d) const; +private: + float a; + float b; + float c; + float d; +}; + +extern idPlane plane_origin; +#define plane_zero plane_origin + +ID_INLINE idPlane::idPlane( void ) { +} + +ID_INLINE idPlane::idPlane( float a, float b, float c, float d ) { + this->a = a; + this->b = b; + this->c = c; + this->d = d; +} + +ID_INLINE idPlane::idPlane( const idVec3 &normal, const float dist ) { + this->a = normal.x; + this->b = normal.y; + this->c = normal.z; + this->d = -dist; +} + +ID_INLINE void idPlane::GetPlaneParams(float &fa, float &fb, float &fc, float &fd) const +{ + fa = a; + fb = b; + fc = c; + fd = d; +} + + +ID_INLINE float idPlane::operator[]( int index ) const { + return ( &a )[ index ]; +} + +ID_INLINE float& idPlane::operator[]( int index ) { + return ( &a )[ index ]; +} + +ID_INLINE idPlane idPlane::operator-() const { + return idPlane( -a, -b, -c, -d ); +} + +ID_INLINE idPlane &idPlane::operator=( const idVec3 &v ) { + a = v.x; + b = v.y; + c = v.z; + d = 0; + return *this; +} + +ID_INLINE idPlane idPlane::operator+( const idPlane &p ) const { + return idPlane( a + p.a, b + p.b, c + p.c, d + p.d ); +} + +ID_INLINE idPlane idPlane::operator-( const idPlane &p ) const { + return idPlane( a - p.a, b - p.b, c - p.c, d - p.d ); +} + +ID_INLINE idPlane &idPlane::operator*=( const idMat3 &m ) { + Normal() *= m; + return *this; +} + +ID_INLINE bool idPlane::Compare( const idPlane &p ) const { + return ( a == p.a && b == p.b && c == p.c && d == p.d ); +} + +ID_INLINE bool idPlane::Compare( const idPlane &p, const float epsilon ) const { + if ( idMath::Fabs( a - p.a ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( b - p.b ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( c - p.c ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( d - p.d ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idPlane::Compare( const idPlane &p, const float normalEps, const float distEps ) const { + if ( idMath::Fabs( d - p.d ) > distEps ) { + return false; + } + if ( !Normal().Compare( p.Normal(), normalEps ) ) { + return false; + } + return true; +} + +ID_INLINE bool idPlane::operator==( const idPlane &p ) const { + return Compare( p ); +} + +ID_INLINE bool idPlane::operator!=( const idPlane &p ) const { + return !Compare( p ); +} + +ID_INLINE void idPlane::Zero( void ) { + a = b = c = d = 0.0f; +} + +ID_INLINE void idPlane::SetNormal( const idVec3 &normal ) { + a = normal.x; + b = normal.y; + c = normal.z; +} + +ID_INLINE const idVec3 &idPlane::Normal( void ) const { + return *reinterpret_cast(&a); +} + +ID_INLINE idVec3 &idPlane::Normal( void ) { + return *reinterpret_cast(&a); +} + +ID_INLINE float idPlane::Normalize( bool fixDegenerate ) { + float length = reinterpret_cast(&a)->Normalize(); + + if ( fixDegenerate ) { + FixDegenerateNormal(); + } + return length; +} + +ID_INLINE bool idPlane::FixDegenerateNormal( void ) { + return Normal().FixDegenerateNormal(); +} + +ID_INLINE bool idPlane::FixDegeneracies( float distEpsilon ) { + bool fixedNormal = FixDegenerateNormal(); + // only fix dist if the normal was degenerate + if ( fixedNormal ) { + if ( idMath::Fabs( d - idMath::Rint( d ) ) < distEpsilon ) { + d = idMath::Rint( d ); + } + } + return fixedNormal; +} + +ID_INLINE float idPlane::Dist( void ) const { + return -d; +} + +ID_INLINE void idPlane::SetDist( const float dist ) { + d = -dist; +} + +ID_INLINE bool idPlane::FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate ) { + Normal() = (p1 - p2).Cross( p3 - p2 ); + if ( Normalize( fixDegenerate ) == 0.0f ) { + return false; + } + d = -( Normal() * p2 ); + return true; +} + +ID_INLINE bool idPlane::FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate ) { + Normal() = dir1.Cross( dir2 ); + if ( Normalize( fixDegenerate ) == 0.0f ) { + return false; + } + d = -( Normal() * p ); + return true; +} + +ID_INLINE void idPlane::FitThroughPoint( const idVec3 &p ) { + d = -( Normal() * p ); +} + +ID_INLINE idPlane idPlane::Translate( const idVec3 &translation ) const { + return idPlane( a, b, c, d - translation * Normal() ); +} + +ID_INLINE idPlane &idPlane::TranslateSelf( const idVec3 &translation ) { + d -= translation * Normal(); + return *this; +} + +ID_INLINE idPlane idPlane::Rotate( const idVec3 &origin, const idMat3 &axis ) const { + idPlane p; + p.Normal() = Normal() * axis; + p.d = d + origin * Normal() - origin * p.Normal(); + return p; +} + +ID_INLINE idPlane &idPlane::RotateSelf( const idVec3 &origin, const idMat3 &axis ) { + d += origin * Normal(); + Normal() *= axis; + d -= origin * Normal(); + return *this; +} + +ID_INLINE float idPlane::Distance( const idVec3 &v ) const { + return a * v.x + b * v.y + c * v.z + d; +} + +ID_INLINE int idPlane::Side( const idVec3 &v, const float epsilon ) const { + float dist = Distance( v ); + if ( dist > epsilon ) { + return PLANESIDE_FRONT; + } + else if ( dist < -epsilon ) { + return PLANESIDE_BACK; + } + else { + return PLANESIDE_ON; + } +} + +ID_INLINE bool idPlane::LineIntersection( const idVec3 &start, const idVec3 &end, float *fract ) const{ + float d1, d2, fraction; + + // This code is a copy of the lineintersection code from Id. Because of a bug + // Because of a bug in the calcualtion it doesn't always correctly report the intersection. Until + // it is confirmed that it can be fixed in the plane.h file, without braking any existing code that + // might rely on the current behaviour I keep this code here as a copy. + // Update: According to a mail from Brian (id) he says that the code is correct and is based on + // a slightly different assumption. I don't think so, because the exact same code doesn't work in + // some cases while my fix does, so I keep my version instead. + // d1 = Normal() * start + d; + d1 = -(Normal() * start + d); + d2 = Normal() * end + d; + if ( d1 == d2 ) { + return false; + } + if ( d1 > 0.0f && d2 > 0.0f ) { + return false; + } + if ( d1 < 0.0f && d2 < 0.0f ) { + return false; + } + fraction = ( d1 / ( d1 - d2 ) ); + if(fract != NULL) + *fract = fraction; + + return ( fraction >= 0.0f && fraction <= 1.0f ); +} + +ID_INLINE bool idPlane::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const { + float d1, d2; + + d1 = Normal() * start + d; + d2 = Normal() * dir; + if ( d2 == 0.0f ) { + return false; + } + scale = -( d1 / d2 ); + return true; +} + +ID_INLINE int idPlane::GetDimension( void ) const { + return 4; +} + +ID_INLINE const idVec4 &idPlane::ToVec4( void ) const { + return *reinterpret_cast(&a); +} + +ID_INLINE idVec4 &idPlane::ToVec4( void ) { + return *reinterpret_cast(&a); +} + +ID_INLINE const float *idPlane::ToFloatPtr( void ) const { + return reinterpret_cast(&a); +} + +ID_INLINE float *idPlane::ToFloatPtr( void ) { + return reinterpret_cast(&a); +} + +#endif /* !__MATH_PLANE_H__ */ diff --git a/idlib/math/Pluecker.cpp b/idlib/math/Pluecker.cpp new file mode 100644 index 000000000..e769ffa83 --- /dev/null +++ b/idlib/math/Pluecker.cpp @@ -0,0 +1,77 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +idPluecker pluecker_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); + +/* +================ +idPluecker::FromPlanes + + pluecker coordinate for the intersection of two planes +================ +*/ +bool idPluecker::FromPlanes( const idPlane &p1, const idPlane &p2 ) { + + p[0] = -( p1[2] * -p2[3] - p2[2] * -p1[3] ); + p[1] = -( p2[1] * -p1[3] - p1[1] * -p2[3] ); + p[2] = p1[1] * p2[2] - p2[1] * p1[2]; + + p[3] = -( p1[0] * -p2[3] - p2[0] * -p1[3] ); + p[4] = p1[0] * p2[1] - p2[0] * p1[1]; + p[5] = p1[0] * p2[2] - p2[0] * p1[2]; + + return ( p[2] != 0.0f || p[5] != 0.0f || p[4] != 0.0f ); +} + +/* +================ +idPluecker::Distance3DSqr + + calculates square of shortest distance between the two + 3D lines represented by their pluecker coordinates +================ +*/ +float idPluecker::Distance3DSqr( const idPluecker &a ) const { + float d, s; + idVec3 dir; + + dir[0] = -a.p[5] * p[4] - a.p[4] * -p[5]; + dir[1] = a.p[4] * p[2] - a.p[2] * p[4]; + dir[2] = a.p[2] * -p[5] - -a.p[5] * p[2]; + if ( dir[0] == 0.0f && dir[1] == 0.0f && dir[2] == 0.0f ) { + return -1.0f; // FIXME: implement for parallel lines + } + d = a.p[4] * ( p[2]*dir[1] - -p[5]*dir[0]) + + a.p[5] * ( p[2]*dir[2] - p[4]*dir[0]) + + a.p[2] * (-p[5]*dir[2] - p[4]*dir[1]); + s = PermutedInnerProduct( a ) / d; + return ( dir * dir ) * ( s * s ); +} + +/* +============= +idPluecker::ToString +============= +*/ +const char *idPluecker::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Pluecker.h b/idlib/math/Pluecker.h new file mode 100644 index 000000000..e0595adf2 --- /dev/null +++ b/idlib/math/Pluecker.h @@ -0,0 +1,359 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_PLUECKER_H__ +#define __MATH_PLUECKER_H__ + +/* +=============================================================================== + + Pluecker coordinate + +=============================================================================== +*/ + +class idPluecker { +public: + idPluecker( void ); + explicit idPluecker( const float *a ); + explicit idPluecker( const idVec3 &start, const idVec3 &end ); + explicit idPluecker( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idPluecker operator-() const; // flips the direction + idPluecker operator*( const float a ) const; + idPluecker operator/( const float a ) const; + float operator*( const idPluecker &a ) const; // permuted inner product + idPluecker operator-( const idPluecker &a ) const; + idPluecker operator+( const idPluecker &a ) const; + idPluecker & operator*=( const float a ); + idPluecker & operator/=( const float a ); + idPluecker & operator+=( const idPluecker &a ); + idPluecker & operator-=( const idPluecker &a ); + + bool Compare( const idPluecker &a ) const; // exact compare, no epsilon + bool Compare( const idPluecker &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idPluecker &a ) const; // exact compare, no epsilon + bool operator!=( const idPluecker &a ) const; // exact compare, no epsilon + + void Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); + void Zero( void ); + + void FromLine( const idVec3 &start, const idVec3 &end ); // pluecker from line + void FromRay( const idVec3 &start, const idVec3 &dir ); // pluecker from ray + bool FromPlanes( const idPlane &p1, const idPlane &p2 ); // pluecker from intersection of planes + bool ToLine( idVec3 &start, idVec3 &end ) const; // pluecker to line + bool ToRay( idVec3 &start, idVec3 &dir ) const; // pluecker to ray + void ToDir( idVec3 &dir ) const; // pluecker to direction + float PermutedInnerProduct( const idPluecker &a ) const; // pluecker permuted inner product + float Distance3DSqr( const idPluecker &a ) const; // pluecker line distance + + float Length( void ) const; // pluecker length + float LengthSqr( void ) const; // pluecker squared length + idPluecker Normalize( void ) const; // pluecker normalize + float NormalizeSelf( void ); // pluecker normalize + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + float p[6]; +}; + +extern idPluecker pluecker_origin; +#define pluecker_zero pluecker_origin + +ID_INLINE idPluecker::idPluecker( void ) { +} + +ID_INLINE idPluecker::idPluecker( const float *a ) { + memcpy( p, a, 6 * sizeof( float ) ); +} + +ID_INLINE idPluecker::idPluecker( const idVec3 &start, const idVec3 &end ) { + FromLine( start, end ); +} + +ID_INLINE idPluecker::idPluecker( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { + p[0] = a1; + p[1] = a2; + p[2] = a3; + p[3] = a4; + p[4] = a5; + p[5] = a6; +} + +ID_INLINE idPluecker idPluecker::operator-() const { + return idPluecker( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] ); +} + +ID_INLINE float idPluecker::operator[]( const int index ) const { + return p[index]; +} + +ID_INLINE float &idPluecker::operator[]( const int index ) { + return p[index]; +} + +ID_INLINE idPluecker idPluecker::operator*( const float a ) const { + return idPluecker( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a ); +} + +ID_INLINE float idPluecker::operator*( const idPluecker &a ) const { + return p[0] * a.p[4] + p[1] * a.p[5] + p[2] * a.p[3] + p[4] * a.p[0] + p[5] * a.p[1] + p[3] * a.p[2]; +} + +ID_INLINE idPluecker idPluecker::operator/( const float a ) const { + float inva; + + assert( a != 0.0f ); + inva = 1.0f / a; + return idPluecker( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva ); +} + +ID_INLINE idPluecker idPluecker::operator+( const idPluecker &a ) const { + return idPluecker( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] ); +} + +ID_INLINE idPluecker idPluecker::operator-( const idPluecker &a ) const { + return idPluecker( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] ); +} + +ID_INLINE idPluecker &idPluecker::operator*=( const float a ) { + p[0] *= a; + p[1] *= a; + p[2] *= a; + p[3] *= a; + p[4] *= a; + p[5] *= a; + return *this; +} + +ID_INLINE idPluecker &idPluecker::operator/=( const float a ) { + float inva; + + assert( a != 0.0f ); + inva = 1.0f / a; + p[0] *= inva; + p[1] *= inva; + p[2] *= inva; + p[3] *= inva; + p[4] *= inva; + p[5] *= inva; + return *this; +} + +ID_INLINE idPluecker &idPluecker::operator+=( const idPluecker &a ) { + p[0] += a[0]; + p[1] += a[1]; + p[2] += a[2]; + p[3] += a[3]; + p[4] += a[4]; + p[5] += a[5]; + return *this; +} + +ID_INLINE idPluecker &idPluecker::operator-=( const idPluecker &a ) { + p[0] -= a[0]; + p[1] -= a[1]; + p[2] -= a[2]; + p[3] -= a[3]; + p[4] -= a[4]; + p[5] -= a[5]; + return *this; +} + +ID_INLINE bool idPluecker::Compare( const idPluecker &a ) const { + return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) && + ( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) ); +} + +ID_INLINE bool idPluecker::Compare( const idPluecker &a, const float epsilon ) const { + if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idPluecker::operator==( const idPluecker &a ) const { + return Compare( a ); +} + +ID_INLINE bool idPluecker::operator!=( const idPluecker &a ) const { + return !Compare( a ); +} + +ID_INLINE void idPluecker::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { + p[0] = a1; + p[1] = a2; + p[2] = a3; + p[3] = a4; + p[4] = a5; + p[5] = a6; +} + +ID_INLINE void idPluecker::Zero( void ) { + p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f; +} + +ID_INLINE void idPluecker::FromLine( const idVec3 &start, const idVec3 &end ) { + p[0] = start[0] * end[1] - end[0] * start[1]; + p[1] = start[0] * end[2] - end[0] * start[2]; + p[2] = start[0] - end[0]; + p[3] = start[1] * end[2] - end[1] * start[2]; + p[4] = start[2] - end[2]; + p[5] = end[1] - start[1]; +} + +ID_INLINE void idPluecker::FromRay( const idVec3 &start, const idVec3 &dir ) { + p[0] = start[0] * dir[1] - dir[0] * start[1]; + p[1] = start[0] * dir[2] - dir[0] * start[2]; + p[2] = -dir[0]; + p[3] = start[1] * dir[2] - dir[1] * start[2]; + p[4] = -dir[2]; + p[5] = dir[1]; +} + +ID_INLINE bool idPluecker::ToLine( idVec3 &start, idVec3 &end ) const { + idVec3 dir1, dir2; + float d; + + dir1[0] = p[3]; + dir1[1] = -p[1]; + dir1[2] = p[0]; + + dir2[0] = -p[2]; + dir2[1] = p[5]; + dir2[2] = -p[4]; + + d = dir2 * dir2; + if ( d == 0.0f ) { + return false; // pluecker coordinate does not represent a line + } + + start = dir2.Cross(dir1) * (1.0f / d); + end = start + dir2; + return true; +} + +ID_INLINE bool idPluecker::ToRay( idVec3 &start, idVec3 &dir ) const { + idVec3 dir1; + float d; + + dir1[0] = p[3]; + dir1[1] = -p[1]; + dir1[2] = p[0]; + + dir[0] = -p[2]; + dir[1] = p[5]; + dir[2] = -p[4]; + + d = dir * dir; + if ( d == 0.0f ) { + return false; // pluecker coordinate does not represent a line + } + + start = dir.Cross(dir1) * (1.0f / d); + return true; +} + +ID_INLINE void idPluecker::ToDir( idVec3 &dir ) const { + dir[0] = -p[2]; + dir[1] = p[5]; + dir[2] = -p[4]; +} + +ID_INLINE float idPluecker::PermutedInnerProduct( const idPluecker &a ) const { + return p[0] * a.p[4] + p[1] * a.p[5] + p[2] * a.p[3] + p[4] * a.p[0] + p[5] * a.p[1] + p[3] * a.p[2]; +} + +ID_INLINE float idPluecker::Length( void ) const { + return ( float )idMath::Sqrt( p[5] * p[5] + p[4] * p[4] + p[2] * p[2] ); +} + +ID_INLINE float idPluecker::LengthSqr( void ) const { + return ( p[5] * p[5] + p[4] * p[4] + p[2] * p[2] ); +} + +ID_INLINE float idPluecker::NormalizeSelf( void ) { + float l, d; + + l = LengthSqr(); + if ( l == 0.0f ) { + return l; // pluecker coordinate does not represent a line + } + d = idMath::InvSqrt( l ); + p[0] *= d; + p[1] *= d; + p[2] *= d; + p[3] *= d; + p[4] *= d; + p[5] *= d; + return d * l; +} + +ID_INLINE idPluecker idPluecker::Normalize( void ) const { + float d; + + d = LengthSqr(); + if ( d == 0.0f ) { + return *this; // pluecker coordinate does not represent a line + } + d = idMath::InvSqrt( d ); + return idPluecker( p[0]*d, p[1]*d, p[2]*d, p[3]*d, p[4]*d, p[5]*d ); +} + +ID_INLINE int idPluecker::GetDimension( void ) const { + return 6; +} + +ID_INLINE const float *idPluecker::ToFloatPtr( void ) const { + return p; +} + +ID_INLINE float *idPluecker::ToFloatPtr( void ) { + return p; +} + +#endif /* !__MATH_PLUECKER_H__ */ diff --git a/idlib/math/Polynomial.cpp b/idlib/math/Polynomial.cpp new file mode 100644 index 000000000..47f7c8e04 --- /dev/null +++ b/idlib/math/Polynomial.cpp @@ -0,0 +1,233 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +const float EPSILON = 1e-6f; + +/* +============= +idPolynomial::Laguer +============= +*/ +int idPolynomial::Laguer( const idComplex *coef, const int degree, idComplex &x ) const { + const int MT = 10, MAX_ITERATIONS = MT * 8; + static const float frac[] = { 0.0f, 0.5f, 0.25f, 0.75f, 0.13f, 0.38f, 0.62f, 0.88f, 1.0f }; + int i, j; + float abx, abp, abm, err; + idComplex dx, cx, b, d, f, g, s, gps, gms, g2; + + for ( i = 1; i <= MAX_ITERATIONS; i++ ) { + b = coef[degree]; + err = b.Abs(); + d.Zero(); + f.Zero(); + abx = x.Abs(); + for ( j = degree - 1; j >= 0; j-- ) { + f = x * f + d; + d = x * d + b; + b = x * b + coef[j]; + err = b.Abs() + abx * err; + } + if ( b.Abs() < err * EPSILON ) { + return i; + } + g = d / b; + g2 = g * g; + s = ( ( degree - 1 ) * ( degree * ( g2 - 2.0f * f / b ) - g2 ) ).Sqrt(); + gps = g + s; + gms = g - s; + abp = gps.Abs(); + abm = gms.Abs(); + if ( abp < abm ) { + gps = gms; + } + if ( Max( abp, abm ) > 0.0f ) { + dx = degree / gps; + } else { + dx = idMath::Exp( idMath::Log( 1.0f + abx ) ) * idComplex( idMath::Cos( i ), idMath::Sin( i ) ); + } + cx = x - dx; + if ( x == cx ) { + return i; + } + if ( i % MT == 0 ) { + x = cx; + } else { + x -= frac[i/MT] * dx; + } + } + return i; +} + +/* +============= +idPolynomial::GetRoots +============= +*/ +int idPolynomial::GetRoots( idComplex *roots ) const { + int i, j; + idComplex x, b, c, *coef; + + coef = (idComplex *) _alloca16( ( degree + 1 ) * sizeof( idComplex ) ); + for ( i = 0; i <= degree; i++ ) { + coef[i].Set( coefficient[i], 0.0f ); + } + + for ( i = degree - 1; i >= 0; i-- ) { + x.Zero(); + Laguer( coef, i + 1, x ); + if ( idMath::Fabs( x.i ) < 2.0f * EPSILON * idMath::Fabs( x.r ) ) { + x.i = 0.0f; + } + roots[i] = x; + b = coef[i+1]; + for ( j = i; j >= 0; j-- ) { + c = coef[j]; + coef[j] = b; + b = x * b + c; + } + } + + for ( i = 0; i <= degree; i++ ) { + coef[i].Set( coefficient[i], 0.0f ); + } + for ( i = 0; i < degree; i++ ) { + Laguer( coef, degree, roots[i] ); + } + + for ( i = 1; i < degree; i++ ) { + x = roots[i]; + for ( j = i - 1; j >= 0; j-- ) { + if ( roots[j].r <= x.r ) { + break; + } + roots[j+1] = roots[j]; + } + roots[j+1] = x; + } + + return degree; +} + +/* +============= +idPolynomial::GetRoots +============= +*/ +int idPolynomial::GetRoots( float *roots ) const { + int i, num; + idComplex *complexRoots; + + switch( degree ) { + case 0: return 0; + case 1: return GetRoots1( coefficient[1], coefficient[0], roots ); + case 2: return GetRoots2( coefficient[2], coefficient[1], coefficient[0], roots ); + case 3: return GetRoots3( coefficient[3], coefficient[2], coefficient[1], coefficient[0], roots ); + case 4: return GetRoots4( coefficient[4], coefficient[3], coefficient[2], coefficient[1], coefficient[0], roots ); + } + + // The Abel-Ruffini theorem states that there is no general solution + // in radicals to polynomial equations of degree five or higher. + // A polynomial equation can be solved by radicals if and only if + // its Galois group is a solvable group. + + complexRoots = (idComplex *) _alloca16( degree * sizeof( idComplex ) ); + + GetRoots( complexRoots ); + + for ( num = i = 0; i < degree; i++ ) { + if ( complexRoots[i].i == 0.0f ) { + roots[i] = complexRoots[i].r; + num++; + } + } + return num; +} + +/* +============= +idPolynomial::ToString +============= +*/ +const char *idPolynomial::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============= +idPolynomial::Test +============= +*/ +void idPolynomial::Test( void ) { + int i, num; + float roots[4], value; + idComplex complexRoots[4], complexValue; + idPolynomial p; + + p = idPolynomial( -5.0f, 4.0f ); + num = p.GetRoots( roots ); + for ( i = 0; i < num; i++ ) { + value = p.GetValue( roots[i] ); + assert( idMath::Fabs( value ) < 1e-4f ); + } + + p = idPolynomial( -5.0f, 4.0f, 3.0f ); + num = p.GetRoots( roots ); + for ( i = 0; i < num; i++ ) { + value = p.GetValue( roots[i] ); + assert( idMath::Fabs( value ) < 1e-4f ); + } + + p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); + num = p.GetRoots( roots ); + for ( i = 0; i < num; i++ ) { + value = p.GetValue( roots[i] ); + assert( idMath::Fabs( value ) < 1e-4f ); + } + + p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); + num = p.GetRoots( roots ); + for ( i = 0; i < num; i++ ) { + value = p.GetValue( roots[i] ); + assert( idMath::Fabs( value ) < 1e-4f ); + } + + p = idPolynomial( -5.0f, 4.0f, 3.0f, 2.0f, 1.0f ); + num = p.GetRoots( roots ); + for ( i = 0; i < num; i++ ) { + value = p.GetValue( roots[i] ); + assert( idMath::Fabs( value ) < 1e-4f ); + } + + p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); + num = p.GetRoots( complexRoots ); + for ( i = 0; i < num; i++ ) { + complexValue = p.GetValue( complexRoots[i] ); + assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); + } + + p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); + num = p.GetRoots( complexRoots ); + for ( i = 0; i < num; i++ ) { + complexValue = p.GetValue( complexRoots[i] ); + assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); + } +} diff --git a/idlib/math/Polynomial.h b/idlib/math/Polynomial.h new file mode 100644 index 000000000..9078472e3 --- /dev/null +++ b/idlib/math/Polynomial.h @@ -0,0 +1,620 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_POLYNOMIAL_H__ +#define __MATH_POLYNOMIAL_H__ + +/* +=============================================================================== + + Polynomial of arbitrary degree with real coefficients. + +=============================================================================== +*/ + + +class idPolynomial { +public: + idPolynomial( void ); + explicit idPolynomial( int d ); + explicit idPolynomial( float a, float b ); + explicit idPolynomial( float a, float b, float c ); + explicit idPolynomial( float a, float b, float c, float d ); + explicit idPolynomial( float a, float b, float c, float d, float e ); + + float operator[]( int index ) const; + float & operator[]( int index ); + + idPolynomial operator-() const; + idPolynomial & operator=( const idPolynomial &p ); + + idPolynomial operator+( const idPolynomial &p ) const; + idPolynomial operator-( const idPolynomial &p ) const; + idPolynomial operator*( const float s ) const; + idPolynomial operator/( const float s ) const; + + idPolynomial & operator+=( const idPolynomial &p ); + idPolynomial & operator-=( const idPolynomial &p ); + idPolynomial & operator*=( const float s ); + idPolynomial & operator/=( const float s ); + + bool Compare( const idPolynomial &p ) const; // exact compare, no epsilon + bool Compare( const idPolynomial &p, const float epsilon ) const;// compare with epsilon + bool operator==( const idPolynomial &p ) const; // exact compare, no epsilon + bool operator!=( const idPolynomial &p ) const; // exact compare, no epsilon + + void Zero( void ); + void Zero( int d ); + + int GetDimension( void ) const; // get the degree of the polynomial + int GetDegree( void ) const; // get the degree of the polynomial + float GetValue( const float x ) const; // evaluate the polynomial with the given real value + idComplex GetValue( const idComplex &x ) const; // evaluate the polynomial with the given complex value + idPolynomial GetDerivative( void ) const; // get the first derivative of the polynomial + idPolynomial GetAntiDerivative( void ) const; // get the anti derivative of the polynomial + + int GetRoots( idComplex *roots ) const; // get all roots + int GetRoots( float *roots ) const; // get the real roots + + static int GetRoots1( float a, float b, float *roots ); + static int GetRoots2( float a, float b, float c, float *roots ); + static int GetRoots3( float a, float b, float c, float d, float *roots ); + static int GetRoots4( float a, float b, float c, float d, float e, float *roots ); + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + static void Test( void ); + +private: + int degree; + int allocated; + float * coefficient; + + void Resize( int d, bool keep ); + int Laguer( const idComplex *coef, const int degree, idComplex &r ) const; +}; + +ID_INLINE idPolynomial::idPolynomial( void ) { + degree = -1; + allocated = 0; + coefficient = NULL; +} + +ID_INLINE idPolynomial::idPolynomial( int d ) { + degree = -1; + allocated = 0; + coefficient = NULL; + Resize( d, false ); +} + +ID_INLINE idPolynomial::idPolynomial( float a, float b ) { + degree = -1; + allocated = 0; + coefficient = NULL; + Resize( 1, false ); + coefficient[0] = b; + coefficient[1] = a; +} + +ID_INLINE idPolynomial::idPolynomial( float a, float b, float c ) { + degree = -1; + allocated = 0; + coefficient = NULL; + Resize( 2, false ); + coefficient[0] = c; + coefficient[1] = b; + coefficient[2] = a; +} + +ID_INLINE idPolynomial::idPolynomial( float a, float b, float c, float d ) { + degree = -1; + allocated = 0; + coefficient = NULL; + Resize( 3, false ); + coefficient[0] = d; + coefficient[1] = c; + coefficient[2] = b; + coefficient[3] = a; +} + +ID_INLINE idPolynomial::idPolynomial( float a, float b, float c, float d, float e ) { + degree = -1; + allocated = 0; + coefficient = NULL; + Resize( 4, false ); + coefficient[0] = e; + coefficient[1] = d; + coefficient[2] = c; + coefficient[3] = b; + coefficient[4] = a; +} + +ID_INLINE float idPolynomial::operator[]( int index ) const { + assert( index >= 0 && index <= degree ); + return coefficient[ index ]; +} + +ID_INLINE float& idPolynomial::operator[]( int index ) { + assert( index >= 0 && index <= degree ); + return coefficient[ index ]; +} + +ID_INLINE idPolynomial idPolynomial::operator-() const { + int i; + idPolynomial n; + + n = *this; + for ( i = 0; i <= degree; i++ ) { + n[i] = -n[i]; + } + return n; +} + +ID_INLINE idPolynomial &idPolynomial::operator=( const idPolynomial &p ) { + Resize( p.degree, false ); + for ( int i = 0; i <= degree; i++ ) { + coefficient[i] = p.coefficient[i]; + } + return *this; +} + +ID_INLINE idPolynomial idPolynomial::operator+( const idPolynomial &p ) const { + int i; + idPolynomial n; + + if ( degree > p.degree ) { + n.Resize( degree, false ); + for ( i = 0; i <= p.degree; i++ ) { + n.coefficient[i] = coefficient[i] + p.coefficient[i]; + } + for ( ; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i]; + } + n.degree = degree; + } else if ( p.degree > degree ) { + n.Resize( p.degree, false ); + for ( i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] + p.coefficient[i]; + } + for ( ; i <= p.degree; i++ ) { + n.coefficient[i] = p.coefficient[i]; + } + n.degree = p.degree; + } else { + n.Resize( degree, false ); + n.degree = 0; + for ( i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] + p.coefficient[i]; + if ( n.coefficient[i] != 0.0f ) { + n.degree = i; + } + } + } + return n; +} + +ID_INLINE idPolynomial idPolynomial::operator-( const idPolynomial &p ) const { + int i; + idPolynomial n; + + if ( degree > p.degree ) { + n.Resize( degree, false ); + for ( i = 0; i <= p.degree; i++ ) { + n.coefficient[i] = coefficient[i] - p.coefficient[i]; + } + for ( ; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i]; + } + n.degree = degree; + } else if ( p.degree >= degree ) { + n.Resize( p.degree, false ); + for ( i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] - p.coefficient[i]; + } + for ( ; i <= p.degree; i++ ) { + n.coefficient[i] = - p.coefficient[i]; + } + n.degree = p.degree; + } else { + n.Resize( degree, false ); + n.degree = 0; + for ( i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] - p.coefficient[i]; + if ( n.coefficient[i] != 0.0f ) { + n.degree = i; + } + } + } + return n; +} + +ID_INLINE idPolynomial idPolynomial::operator*( const float s ) const { + idPolynomial n; + + if ( s == 0.0f ) { + n.degree = 0; + } else { + n.Resize( degree, false ); + for ( int i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] * s; + } + } + return n; +} + +ID_INLINE idPolynomial idPolynomial::operator/( const float s ) const { + float invs; + idPolynomial n; + + assert( s != 0.0f ); + n.Resize( degree, false ); + invs = 1.0f / s; + for ( int i = 0; i <= degree; i++ ) { + n.coefficient[i] = coefficient[i] * invs; + } + return n; +} + +ID_INLINE idPolynomial &idPolynomial::operator+=( const idPolynomial &p ) { + int i; + + if ( degree > p.degree ) { + for ( i = 0; i <= p.degree; i++ ) { + coefficient[i] += p.coefficient[i]; + } + } else if ( p.degree > degree ) { + Resize( p.degree, true ); + for ( i = 0; i <= degree; i++ ) { + coefficient[i] += p.coefficient[i]; + } + for ( ; i <= p.degree; i++ ) { + coefficient[i] = p.coefficient[i]; + } + } else { + for ( i = 0; i <= degree; i++ ) { + coefficient[i] += p.coefficient[i]; + if ( coefficient[i] != 0.0f ) { + degree = i; + } + } + } + return *this; +} + +ID_INLINE idPolynomial &idPolynomial::operator-=( const idPolynomial &p ) { + int i; + + if ( degree > p.degree ) { + for ( i = 0; i <= p.degree; i++ ) { + coefficient[i] -= p.coefficient[i]; + } + } else if ( p.degree > degree ) { + Resize( p.degree, true ); + for ( i = 0; i <= degree; i++ ) { + coefficient[i] -= p.coefficient[i]; + } + for ( ; i <= p.degree; i++ ) { + coefficient[i] = - p.coefficient[i]; + } + } else { + for ( i = 0; i <= degree; i++ ) { + coefficient[i] -= p.coefficient[i]; + if ( coefficient[i] != 0.0f ) { + degree = i; + } + } + } + return *this; +} + +ID_INLINE idPolynomial &idPolynomial::operator*=( const float s ) { + if ( s == 0.0f ) { + degree = 0; + } else { + for ( int i = 0; i <= degree; i++ ) { + coefficient[i] *= s; + } + } + return *this; +} + +ID_INLINE idPolynomial &idPolynomial::operator/=( const float s ) { + float invs; + + assert( s != 0.0f ); + invs = 1.0f / s; + for ( int i = 0; i <= degree; i++ ) { + coefficient[i] = invs; + } + return *this;; +} + +ID_INLINE bool idPolynomial::Compare( const idPolynomial &p ) const { + if ( degree != p.degree ) { + return false; + } + for ( int i = 0; i <= degree; i++ ) { + if ( coefficient[i] != p.coefficient[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idPolynomial::Compare( const idPolynomial &p, const float epsilon ) const { + if ( degree != p.degree ) { + return false; + } + for ( int i = 0; i <= degree; i++ ) { + if ( idMath::Fabs( coefficient[i] - p.coefficient[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idPolynomial::operator==( const idPolynomial &p ) const { + return Compare( p ); +} + +ID_INLINE bool idPolynomial::operator!=( const idPolynomial &p ) const { + return !Compare( p ); +} + +ID_INLINE void idPolynomial::Zero( void ) { + degree = 0; +} + +ID_INLINE void idPolynomial::Zero( int d ) { + Resize( d, false ); + for ( int i = 0; i <= degree; i++ ) { + coefficient[i] = 0.0f; + } +} + +ID_INLINE int idPolynomial::GetDimension( void ) const { + return degree; +} + +ID_INLINE int idPolynomial::GetDegree( void ) const { + return degree; +} + +ID_INLINE float idPolynomial::GetValue( const float x ) const { + float y, z; + y = coefficient[0]; + z = x; + for ( int i = 1; i <= degree; i++ ) { + y += coefficient[i] * z; + z *= x; + } + return y; +} + +ID_INLINE idComplex idPolynomial::GetValue( const idComplex &x ) const { + idComplex y, z; + y.Set( coefficient[0], 0.0f ); + z = x; + for ( int i = 1; i <= degree; i++ ) { + y += coefficient[i] * z; + z *= x; + } + return y; +} + +ID_INLINE idPolynomial idPolynomial::GetDerivative( void ) const { + idPolynomial n; + + if ( degree == 0 ) { + return n; + } + n.Resize( degree - 1, false ); + for ( int i = 1; i <= degree; i++ ) { + n.coefficient[i-1] = i * coefficient[i]; + } + return n; +} + +ID_INLINE idPolynomial idPolynomial::GetAntiDerivative( void ) const { + idPolynomial n; + + if ( degree == 0 ) { + return n; + } + n.Resize( degree + 1, false ); + n.coefficient[0] = 0.0f; + for ( int i = 0; i <= degree; i++ ) { + n.coefficient[i+1] = coefficient[i] / ( i + 1 ); + } + return n; +} + +ID_INLINE int idPolynomial::GetRoots1( float a, float b, float *roots ) { + assert( a != 0.0f ); + roots[0] = - b / a; + return 1; +} + +ID_INLINE int idPolynomial::GetRoots2( float a, float b, float c, float *roots ) { + float inva, ds; + + if ( a != 1.0f ) { + assert( a != 0.0f ); + inva = 1.0f / a; + c *= inva; + b *= inva; + } + ds = b * b - 4.0f * c; + if ( ds < 0.0f ) { + return 0; + } else if ( ds > 0.0f ) { + ds = idMath::Sqrt( ds ); + roots[0] = 0.5f * ( -b - ds ); + roots[1] = 0.5f * ( -b + ds ); + return 2; + } else { + roots[0] = 0.5f * -b; + return 1; + } +} + +ID_INLINE int idPolynomial::GetRoots3( float a, float b, float c, float d, float *roots ) { + float inva, f, g, halfg, ofs, ds, dist, angle, cs, ss, t; + + if ( a != 1.0f ) { + assert( a != 0.0f ); + inva = 1.0f / a; + d *= inva; + c *= inva; + b *= inva; + } + + f = ( 1.0f / 3.0f ) * ( 3.0f * c - b * b ); + g = ( 1.0f / 27.0f ) * ( 2.0f * b * b * b - 9.0f * c * b + 27.0f * d ); + halfg = 0.5f * g; + ofs = ( 1.0f / 3.0f ) * b; + ds = 0.25f * g * g + ( 1.0f / 27.0f ) * f * f * f; + + if ( ds < 0.0f ) { + dist = idMath::Sqrt( ( -1.0f / 3.0f ) * f ); + angle = ( 1.0f / 3.0f ) * idMath::ATan( idMath::Sqrt( -ds ), -halfg ); + cs = idMath::Cos( angle ); + ss = idMath::Sin( angle ); + roots[0] = 2.0f * dist * cs - ofs; + roots[1] = -dist * ( cs + idMath::SQRT_THREE * ss ) - ofs; + roots[2] = -dist * ( cs - idMath::SQRT_THREE * ss ) - ofs; + return 3; + } else if ( ds > 0.0f ) { + ds = idMath::Sqrt( ds ); + t = -halfg + ds; + if ( t >= 0.0f ) { + roots[0] = idMath::Pow( t, ( 1.0f / 3.0f ) ); + } else { + roots[0] = -idMath::Pow( -t, ( 1.0f / 3.0f ) ); + } + t = -halfg - ds; + if ( t >= 0.0f ) { + roots[0] += idMath::Pow( t, ( 1.0f / 3.0f ) ); + } else { + roots[0] -= idMath::Pow( -t, ( 1.0f / 3.0f ) ); + } + roots[0] -= ofs; + return 1; + } else { + if ( halfg >= 0.0f ) { + t = -idMath::Pow( halfg, ( 1.0f / 3.0f ) ); + } else { + t = idMath::Pow( -halfg, ( 1.0f / 3.0f ) ); + } + roots[0] = 2.0f * t - ofs; + roots[1] = -t - ofs; + roots[2] = roots[1]; + return 3; + } +} + +ID_INLINE int idPolynomial::GetRoots4( float a, float b, float c, float d, float e, float *roots ) { + int count; + float inva, y, ds, r, s1, s2, t1, t2, tp, tm; + float roots3[3]; + + if ( a != 1.0f ) { + assert( a != 0.0f ); + inva = 1.0f / a; + e *= inva; + d *= inva; + c *= inva; + b *= inva; + } + + count = 0; + + GetRoots3( 1.0f, -c, b * d - 4.0f * e, -b * b * e + 4.0f * c * e - d * d, roots3 ); + y = roots3[0]; + ds = 0.25f * b * b - c + y; + + if ( ds < 0.0f ) { + return 0; + } else if ( ds > 0.0f ) { + r = idMath::Sqrt( ds ); + t1 = 0.75f * b * b - r * r - 2.0f * c; + t2 = ( 4.0f * b * c - 8.0f * d - b * b * b ) / ( 4.0f * r ); + tp = t1 + t2; + tm = t1 - t2; + + if ( tp >= 0.0f ) { + s1 = idMath::Sqrt( tp ); + roots[count++] = -0.25f * b + 0.5f * ( r + s1 ); + roots[count++] = -0.25f * b + 0.5f * ( r - s1 ); + } + if ( tm >= 0.0f ) { + s2 = idMath::Sqrt( tm ); + roots[count++] = -0.25f * b + 0.5f * ( s2 - r ); + roots[count++] = -0.25f * b - 0.5f * ( s2 + r ); + } + return count; + } else { + t2 = y * y - 4.0f * e; + if ( t2 >= 0.0f ) { + t2 = 2.0f * idMath::Sqrt( t2 ); + t1 = 0.75f * b * b - 2.0f * c; + if ( t1 + t2 >= 0.0f ) { + s1 = idMath::Sqrt( t1 + t2 ); + roots[count++] = -0.25f * b + 0.5f * s1; + roots[count++] = -0.25f * b - 0.5f * s1; + } + if ( t1 - t2 >= 0.0f ) { + s2 = idMath::Sqrt( t1 - t2 ); + roots[count++] = -0.25f * b + 0.5f * s2; + roots[count++] = -0.25f * b - 0.5f * s2; + } + } + return count; + } +} + +ID_INLINE const float *idPolynomial::ToFloatPtr( void ) const { + return coefficient; +} + +ID_INLINE float *idPolynomial::ToFloatPtr( void ) { + return coefficient; +} + +ID_INLINE void idPolynomial::Resize( int d, bool keep ) { + int alloc = ( d + 1 + 3 ) & ~3; + if ( alloc > allocated ) { + float *ptr = (float *) Mem_Alloc16( alloc * sizeof( float ) ); + if ( coefficient != NULL ) { + if ( keep ) { + for ( int i = 0; i <= degree; i++ ) { + ptr[i] = coefficient[i]; + } + } + Mem_Free16( coefficient ); + } + allocated = alloc; + coefficient = ptr; + } + degree = d; +} + +#endif /* !__MATH_POLYNOMIAL_H__ */ diff --git a/idlib/math/Quat.cpp b/idlib/math/Quat.cpp new file mode 100644 index 000000000..26bebf856 --- /dev/null +++ b/idlib/math/Quat.cpp @@ -0,0 +1,243 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +/* +===================== +idQuat::ToAngles +===================== +*/ +idAngles idQuat::ToAngles( void ) const { + return ToMat3().ToAngles(); +} + +/* +===================== +idQuat::ToRotation +===================== +*/ +idRotation idQuat::ToRotation( void ) const { + idVec3 vec; + float angle; + + vec.x = x; + vec.y = y; + vec.z = z; + angle = idMath::ACos( w ); + if ( angle == 0.0f ) { + vec.Set( 0.0f, 0.0f, 1.0f ); + } else { + //vec *= (1.0f / sin( angle )); + vec.Normalize(); + vec.FixDegenerateNormal(); + angle *= 2.0f * idMath::M_RAD2DEG; + } + return idRotation( vec3_origin, vec, angle ); +} + +/* +===================== +idQuat::ToMat3 +===================== +*/ +idMat3 idQuat::ToMat3( void ) const { + idMat3 mat; + float wx, wy, wz; + float xx, yy, yz; + float xy, xz, zz; + float x2, y2, z2; + + x2 = x + x; + y2 = y + y; + z2 = z + z; + + xx = x * x2; + xy = x * y2; + xz = x * z2; + + yy = y * y2; + yz = y * z2; + zz = z * z2; + + wx = w * x2; + wy = w * y2; + wz = w * z2; + + mat[ 0 ][ 0 ] = 1.0f - ( yy + zz ); + mat[ 0 ][ 1 ] = xy - wz; + mat[ 0 ][ 2 ] = xz + wy; + + mat[ 1 ][ 0 ] = xy + wz; + mat[ 1 ][ 1 ] = 1.0f - ( xx + zz ); + mat[ 1 ][ 2 ] = yz - wx; + + mat[ 2 ][ 0 ] = xz - wy; + mat[ 2 ][ 1 ] = yz + wx; + mat[ 2 ][ 2 ] = 1.0f - ( xx + yy ); + + return mat; +} + +/* +===================== +idQuat::ToMat4 +===================== +*/ +idMat4 idQuat::ToMat4( void ) const { + return ToMat3().ToMat4(); +} + +/* +===================== +idQuat::ToCQuat +===================== +*/ +idCQuat idQuat::ToCQuat( void ) const { + if ( w < 0.0f ) { + return idCQuat( -x, -y, -z ); + } + return idCQuat( x, y, z ); +} + +/* +============ +idQuat::ToAngularVelocity +============ +*/ +idVec3 idQuat::ToAngularVelocity( void ) const { + idVec3 vec; + + vec.x = x; + vec.y = y; + vec.z = z; + vec.Normalize(); + return vec * idMath::ACos( w ); +} + +/* +============= +idQuat::ToString +============= +*/ +const char *idQuat::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +===================== +idQuat::Slerp + +Spherical linear interpolation between two quaternions. +===================== +*/ +idQuat &idQuat::Slerp( const idQuat &from, const idQuat &to, float t ) { + idQuat temp; + float omega, cosom, sinom, scale0, scale1; + + if ( t <= 0.0f ) { + *this = from; + return *this; + } + + if ( t >= 1.0f ) { + *this = to; + return *this; + } + + if ( from == to ) { + *this = to; + return *this; + } + + cosom = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w; + if ( cosom < 0.0f ) { + temp = -to; + cosom = -cosom; + } else { + temp = to; + } + + if ( ( 1.0f - cosom ) > 1e-6f ) { +#if 0 + omega = acos( cosom ); + sinom = 1.0f / sin( omega ); + scale0 = sin( ( 1.0f - t ) * omega ) * sinom; + scale1 = sin( t * omega ) * sinom; +#else + scale0 = 1.0f - cosom * cosom; + sinom = idMath::InvSqrt( scale0 ); + omega = idMath::ATan16( scale0 * sinom, cosom ); + scale0 = idMath::Sin16( ( 1.0f - t ) * omega ) * sinom; + scale1 = idMath::Sin16( t * omega ) * sinom; +#endif + } else { + scale0 = 1.0f - t; + scale1 = t; + } + + *this = ( scale0 * from ) + ( scale1 * temp ); + return *this; +} + +/* +============= +idCQuat::ToAngles +============= +*/ +idAngles idCQuat::ToAngles( void ) const { + return ToQuat().ToAngles(); +} + +/* +============= +idCQuat::ToRotation +============= +*/ +idRotation idCQuat::ToRotation( void ) const { + return ToQuat().ToRotation(); +} + +/* +============= +idCQuat::ToMat3 +============= +*/ +idMat3 idCQuat::ToMat3( void ) const { + return ToQuat().ToMat3(); +} + +/* +============= +idCQuat::ToMat4 +============= +*/ +idMat4 idCQuat::ToMat4( void ) const { + return ToQuat().ToMat4(); +} + +/* +============= +idCQuat::ToString +============= +*/ +const char *idCQuat::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Quat.h b/idlib/math/Quat.h new file mode 100644 index 000000000..957957897 --- /dev/null +++ b/idlib/math/Quat.h @@ -0,0 +1,395 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_QUAT_H__ +#define __MATH_QUAT_H__ + +/* +=============================================================================== + + Quaternion + +=============================================================================== +*/ + + +class idVec3; +class idAngles; +class idRotation; +class idMat3; +class idMat4; +class idCQuat; + +class idQuat { +public: + float x; + float y; + float z; + float w; + + idQuat( void ); + idQuat( float x, float y, float z, float w ); + + void Set( float x, float y, float z, float w ); + + float operator[]( int index ) const; + float & operator[]( int index ); + idQuat operator-() const; + idQuat & operator=( const idQuat &a ); + idQuat operator+( const idQuat &a ) const; + idQuat & operator+=( const idQuat &a ); + idQuat operator-( const idQuat &a ) const; + idQuat & operator-=( const idQuat &a ); + idQuat operator*( const idQuat &a ) const; + idVec3 operator*( const idVec3 &a ) const; + idQuat operator*( float a ) const; + idQuat & operator*=( const idQuat &a ); + idQuat & operator*=( float a ); + + friend idQuat operator*( const float a, const idQuat &b ); + friend idVec3 operator*( const idVec3 &a, const idQuat &b ); + + bool Compare( const idQuat &a ) const; // exact compare, no epsilon + bool Compare( const idQuat &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idQuat &a ) const; // exact compare, no epsilon + bool operator!=( const idQuat &a ) const; // exact compare, no epsilon + + idQuat Inverse( void ) const; + float Length( void ) const; + idQuat & Normalize( void ); + + float CalcW( void ) const; + int GetDimension( void ) const; + + idAngles ToAngles( void ) const; + idRotation ToRotation( void ) const; + idMat3 ToMat3( void ) const; + idMat4 ToMat4( void ) const; + idCQuat ToCQuat( void ) const; + idVec3 ToAngularVelocity( void ) const; + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + idQuat & Slerp( const idQuat &from, const idQuat &to, float t ); +}; + +ID_INLINE idQuat::idQuat( void ) { +} + +ID_INLINE idQuat::idQuat( float x, float y, float z, float w ) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +ID_INLINE float idQuat::operator[]( int index ) const { + assert( ( index >= 0 ) && ( index < 4 ) ); + return ( &x )[ index ]; +} + +ID_INLINE float& idQuat::operator[]( int index ) { + assert( ( index >= 0 ) && ( index < 4 ) ); + return ( &x )[ index ]; +} + +ID_INLINE idQuat idQuat::operator-() const { + return idQuat( -x, -y, -z, -w ); +} + +ID_INLINE idQuat &idQuat::operator=( const idQuat &a ) { + x = a.x; + y = a.y; + z = a.z; + w = a.w; + + return *this; +} + +ID_INLINE idQuat idQuat::operator+( const idQuat &a ) const { + return idQuat( x + a.x, y + a.y, z + a.z, w + a.w ); +} + +ID_INLINE idQuat& idQuat::operator+=( const idQuat &a ) { + x += a.x; + y += a.y; + z += a.z; + w += a.w; + + return *this; +} + +ID_INLINE idQuat idQuat::operator-( const idQuat &a ) const { + return idQuat( x - a.x, y - a.y, z - a.z, w - a.w ); +} + +ID_INLINE idQuat& idQuat::operator-=( const idQuat &a ) { + x -= a.x; + y -= a.y; + z -= a.z; + w -= a.w; + + return *this; +} + +ID_INLINE idQuat idQuat::operator*( const idQuat &a ) const { + return idQuat( w*a.x + x*a.w + y*a.z - z*a.y, + w*a.y + y*a.w + z*a.x - x*a.z, + w*a.z + z*a.w + x*a.y - y*a.x, + w*a.w - x*a.x - y*a.y - z*a.z ); +} + +ID_INLINE idVec3 idQuat::operator*( const idVec3 &a ) const { +#if 0 + // it's faster to do the conversion to a 3x3 matrix and multiply the vector by this 3x3 matrix + return ( ToMat3() * a ); +#else + // result = this->Inverse() * idQuat( a.x, a.y, a.z, 0.0f ) * (*this) + float xxzz = x*x - z*z; + float wwyy = w*w - y*y; + + float xw2 = x*w*2.0f; + float xy2 = x*y*2.0f; + float xz2 = x*z*2.0f; + float yw2 = y*w*2.0f; + float yz2 = y*z*2.0f; + float zw2 = z*w*2.0f; + + return idVec3( + (xxzz + wwyy)*a.x + (xy2 + zw2)*a.y + (xz2 - yw2)*a.z, + (xy2 - zw2)*a.x + (y*y+w*w-x*x-z*z)*a.y + (yz2 + xw2)*a.z, + (xz2 + yw2)*a.x + (yz2 - xw2)*a.y + (wwyy - xxzz)*a.z + ); +#endif +} + +ID_INLINE idQuat idQuat::operator*( float a ) const { + return idQuat( x * a, y * a, z * a, w * a ); +} + +ID_INLINE idQuat operator*( const float a, const idQuat &b ) { + return b * a; +} + +ID_INLINE idVec3 operator*( const idVec3 &a, const idQuat &b ) { + return b * a; +} + +ID_INLINE idQuat& idQuat::operator*=( const idQuat &a ) { + *this = *this * a; + + return *this; +} + +ID_INLINE idQuat& idQuat::operator*=( float a ) { + x *= a; + y *= a; + z *= a; + w *= a; + + return *this; +} + +ID_INLINE bool idQuat::Compare( const idQuat &a ) const { + return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && ( w == a.w ) ); +} + +ID_INLINE bool idQuat::Compare( const idQuat &a, const float epsilon ) const { + if ( idMath::Fabs( x - a.x ) > epsilon ) { + return false; + } + if ( idMath::Fabs( y - a.y ) > epsilon ) { + return false; + } + if ( idMath::Fabs( z - a.z ) > epsilon ) { + return false; + } + if ( idMath::Fabs( w - a.w ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE bool idQuat::operator==( const idQuat &a ) const { + return Compare( a ); +} + +ID_INLINE bool idQuat::operator!=( const idQuat &a ) const { + return !Compare( a ); +} + +ID_INLINE void idQuat::Set( float x, float y, float z, float w ) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +ID_INLINE idQuat idQuat::Inverse( void ) const { + return idQuat( -x, -y, -z, w ); +} + +ID_INLINE float idQuat::Length( void ) const { + float len; + + len = x * x + y * y + z * z + w * w; + return idMath::Sqrt( len ); +} + +ID_INLINE idQuat& idQuat::Normalize( void ) { + float len; + float ilength; + + len = this->Length(); + if ( len ) { + ilength = 1 / len; + x *= ilength; + y *= ilength; + z *= ilength; + w *= ilength; + } + return *this; +} + +ID_INLINE float idQuat::CalcW( void ) const { + // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1 + return sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ); +} + +ID_INLINE int idQuat::GetDimension( void ) const { + return 4; +} + +ID_INLINE const float *idQuat::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idQuat::ToFloatPtr( void ) { + return &x; +} + + +/* +=============================================================================== + + Compressed quaternion + +=============================================================================== +*/ + +class idCQuat { +public: + float x; + float y; + float z; + + idCQuat( void ); + idCQuat( float x, float y, float z ); + + void Set( float x, float y, float z ); + + float operator[]( int index ) const; + float & operator[]( int index ); + + bool Compare( const idCQuat &a ) const; // exact compare, no epsilon + bool Compare( const idCQuat &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idCQuat &a ) const; // exact compare, no epsilon + bool operator!=( const idCQuat &a ) const; // exact compare, no epsilon + + int GetDimension( void ) const; + + idAngles ToAngles( void ) const; + idRotation ToRotation( void ) const; + idMat3 ToMat3( void ) const; + idMat4 ToMat4( void ) const; + idQuat ToQuat( void ) const; + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; +}; + +ID_INLINE idCQuat::idCQuat( void ) { +} + +ID_INLINE idCQuat::idCQuat( float x, float y, float z ) { + this->x = x; + this->y = y; + this->z = z; +} + +ID_INLINE void idCQuat::Set( float x, float y, float z ) { + this->x = x; + this->y = y; + this->z = z; +} + +ID_INLINE float idCQuat::operator[]( int index ) const { + assert( ( index >= 0 ) && ( index < 3 ) ); + return ( &x )[ index ]; +} + +ID_INLINE float& idCQuat::operator[]( int index ) { + assert( ( index >= 0 ) && ( index < 3 ) ); + return ( &x )[ index ]; +} + +ID_INLINE bool idCQuat::Compare( const idCQuat &a ) const { + return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) ); +} + +ID_INLINE bool idCQuat::Compare( const idCQuat &a, const float epsilon ) const { + if ( idMath::Fabs( x - a.x ) > epsilon ) { + return false; + } + if ( idMath::Fabs( y - a.y ) > epsilon ) { + return false; + } + if ( idMath::Fabs( z - a.z ) > epsilon ) { + return false; + } + return true; +} + +ID_INLINE bool idCQuat::operator==( const idCQuat &a ) const { + return Compare( a ); +} + +ID_INLINE bool idCQuat::operator!=( const idCQuat &a ) const { + return !Compare( a ); +} + +ID_INLINE int idCQuat::GetDimension( void ) const { + return 3; +} + +ID_INLINE idQuat idCQuat::ToQuat( void ) const { + // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1 + return idQuat( x, y, z, sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ) ); +} + +ID_INLINE const float *idCQuat::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idCQuat::ToFloatPtr( void ) { + return &x; +} + +#endif /* !__MATH_QUAT_H__ */ diff --git a/idlib/math/Random.h b/idlib/math/Random.h new file mode 100644 index 000000000..499d33168 --- /dev/null +++ b/idlib/math/Random.h @@ -0,0 +1,149 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_RANDOM_H__ +#define __MATH_RANDOM_H__ + +/* +=============================================================================== + + Random number generator + +=============================================================================== +*/ + +class idRandom { +public: + idRandom( int seed = 0 ); + + void SetSeed( int seed ); + int GetSeed( void ) const; + + int RandomInt( void ); // random integer in the range [0, MAX_RAND] + int RandomInt( int max ); // random integer in the range [0, max[ + float RandomFloat( void ); // random number in the range [0.0f, 1.0f] + float CRandomFloat( void ); // random number in the range [-1.0f, 1.0f] + + static const int MAX_RAND = 0x7fff; + +private: + int seed; +}; + +ID_INLINE idRandom::idRandom( int seed ) { + this->seed = seed; +} + +ID_INLINE void idRandom::SetSeed( int seed ) { + this->seed = seed; +} + +ID_INLINE int idRandom::GetSeed( void ) const { + return seed; +} + +ID_INLINE int idRandom::RandomInt( void ) { + seed = 69069 * seed + 1; + return ( seed & idRandom::MAX_RAND ); +} + +ID_INLINE int idRandom::RandomInt( int max ) { + if ( max == 0 ) { + return 0; // avoid divide by zero error + } + return RandomInt() % max; +} + +ID_INLINE float idRandom::RandomFloat( void ) { + return ( RandomInt() / ( float )( idRandom::MAX_RAND + 1 ) ); +} + +ID_INLINE float idRandom::CRandomFloat( void ) { + return ( 2.0f * ( RandomFloat() - 0.5f ) ); +} + + +/* +=============================================================================== + + Random number generator + +=============================================================================== +*/ + +class idRandom2 { +public: + idRandom2( unsigned long seed = 0 ); + + void SetSeed( unsigned long seed ); + unsigned long GetSeed( void ) const; + + int RandomInt( void ); // random integer in the range [0, MAX_RAND] + int RandomInt( int max ); // random integer in the range [0, max] + float RandomFloat( void ); // random number in the range [0.0f, 1.0f] + float CRandomFloat( void ); // random number in the range [-1.0f, 1.0f] + + static const int MAX_RAND = 0x7fff; + +private: + unsigned long seed; + + static const unsigned long IEEE_ONE = 0x3f800000; + static const unsigned long IEEE_MASK = 0x007fffff; +}; + +ID_INLINE idRandom2::idRandom2( unsigned long seed ) { + this->seed = seed; +} + +ID_INLINE void idRandom2::SetSeed( unsigned long seed ) { + this->seed = seed; +} + +ID_INLINE unsigned long idRandom2::GetSeed( void ) const { + return seed; +} + +ID_INLINE int idRandom2::RandomInt( void ) { + seed = 1664525L * seed + 1013904223L; + return ( (int) seed & idRandom2::MAX_RAND ); +} + +ID_INLINE int idRandom2::RandomInt( int max ) { + if ( max == 0 ) { + return 0; // avoid divide by zero error + } + return ( RandomInt() >> ( 16 - idMath::BitsForInteger( max ) ) ) % max; +} + +ID_INLINE float idRandom2::RandomFloat( void ) { + unsigned long i; + seed = 1664525L * seed + 1013904223L; + i = idRandom2::IEEE_ONE | ( seed & idRandom2::IEEE_MASK ); + return ( ( *(float *)&i ) - 1.0f ); +} + +ID_INLINE float idRandom2::CRandomFloat( void ) { + unsigned long i; + seed = 1664525L * seed + 1013904223L; + i = idRandom2::IEEE_ONE | ( seed & idRandom2::IEEE_MASK ); + return ( 2.0f * ( *(float *)&i ) - 3.0f ); +} + +#endif /* !__MATH_RANDOM_H__ */ diff --git a/idlib/math/Rotation.cpp b/idlib/math/Rotation.cpp new file mode 100644 index 000000000..9d1244d13 --- /dev/null +++ b/idlib/math/Rotation.cpp @@ -0,0 +1,148 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + +/* +============ +idRotation::ToAngles +============ +*/ +idAngles idRotation::ToAngles( void ) const { + return ToMat3().ToAngles(); +} + +/* +============ +idRotation::ToQuat +============ +*/ +idQuat idRotation::ToQuat( void ) const { + float a, s, c; + + a = angle * ( idMath::M_DEG2RAD * 0.5f ); + idMath::SinCos( a, s, c ); + return idQuat( vec.x * s, vec.y * s, vec.z * s, c ); +} + +/* +============ +idRotation::toMat3 +============ +*/ +const idMat3 &idRotation::ToMat3( void ) const { + float wx, wy, wz; + float xx, yy, yz; + float xy, xz, zz; + float x2, y2, z2; + float a, c, s, x, y, z; + + if ( axisValid ) { + return axis; + } + + a = angle * ( idMath::M_DEG2RAD * 0.5f ); + idMath::SinCos( a, s, c ); + + x = vec[0] * s; + y = vec[1] * s; + z = vec[2] * s; + + x2 = x + x; + y2 = y + y; + z2 = z + z; + + xx = x * x2; + xy = x * y2; + xz = x * z2; + + yy = y * y2; + yz = y * z2; + zz = z * z2; + + wx = c * x2; + wy = c * y2; + wz = c * z2; + + axis[ 0 ][ 0 ] = 1.0f - ( yy + zz ); + axis[ 0 ][ 1 ] = xy - wz; + axis[ 0 ][ 2 ] = xz + wy; + + axis[ 1 ][ 0 ] = xy + wz; + axis[ 1 ][ 1 ] = 1.0f - ( xx + zz ); + axis[ 1 ][ 2 ] = yz - wx; + + axis[ 2 ][ 0 ] = xz - wy; + axis[ 2 ][ 1 ] = yz + wx; + axis[ 2 ][ 2 ] = 1.0f - ( xx + yy ); + + axisValid = true; + + return axis; +} + +/* +============ +idRotation::ToMat4 +============ +*/ +idMat4 idRotation::ToMat4( void ) const { + return ToMat3().ToMat4(); +} + +/* +============ +idRotation::ToAngularVelocity +============ +*/ +idVec3 idRotation::ToAngularVelocity( void ) const { + return vec * DEG2RAD( angle ); +} + +/* +============ +idRotation::Normalize180 +============ +*/ +void idRotation::Normalize180( void ) { + angle -= floor( angle / 360.0f ) * 360.0f; + if ( angle > 180.0f ) { + angle -= 360.0f; + } + else if ( angle < -180.0f ) { + angle += 360.0f; + } +} + +/* +============ +idRotation::Normalize360 +============ +*/ +void idRotation::Normalize360( void ) { + angle -= floor( angle / 360.0f ) * 360.0f; + if ( angle > 360.0f ) { + angle -= 360.0f; + } + else if ( angle < 0.0f ) { + angle += 360.0f; + } +} diff --git a/idlib/math/Rotation.h b/idlib/math/Rotation.h new file mode 100644 index 000000000..f1a042ae1 --- /dev/null +++ b/idlib/math/Rotation.h @@ -0,0 +1,202 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_ROTATION_H__ +#define __MATH_ROTATION_H__ + +/* +=============================================================================== + + Describes a complete rotation in degrees about an abritray axis. + A local rotation matrix is stored for fast rotation of multiple points. + +=============================================================================== +*/ + + +class idAngles; +class idQuat; +class idMat3; + +class idRotation { + + friend class idAngles; + friend class idQuat; + friend class idMat3; + +public: + idRotation( void ); + idRotation( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ); + + void Set( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ); + void SetOrigin( const idVec3 &rotationOrigin ); + void SetVec( const idVec3 &rotationVec ); // has to be normalized + void SetVec( const float x, const float y, const float z ); // has to be normalized + void SetAngle( const float rotationAngle ); + void Scale( const float s ); + void ReCalculateMatrix( void ); + const idVec3 & GetOrigin( void ) const; + const idVec3 & GetVec( void ) const; + float GetAngle( void ) const; + + idRotation operator-() const; // flips rotation + idRotation operator*( const float s ) const; // scale rotation + idRotation operator/( const float s ) const; // scale rotation + idRotation & operator*=( const float s ); // scale rotation + idRotation & operator/=( const float s ); // scale rotation + idVec3 operator*( const idVec3 &v ) const; // rotate vector + + friend idRotation operator*( const float s, const idRotation &r ); // scale rotation + friend idVec3 operator*( const idVec3 &v, const idRotation &r ); // rotate vector + friend idVec3 & operator*=( idVec3 &v, const idRotation &r ); // rotate vector + + idAngles ToAngles( void ) const; + idQuat ToQuat( void ) const; + const idMat3 & ToMat3( void ) const; + idMat4 ToMat4( void ) const; + idVec3 ToAngularVelocity( void ) const; + + void RotatePoint( idVec3 &point ) const; + + void Normalize180( void ); + void Normalize360( void ); + +private: + idVec3 origin; // origin of rotation + idVec3 vec; // normalized vector to rotate around + float angle; // angle of rotation in degrees + mutable idMat3 axis; // rotation axis + mutable bool axisValid; // true if rotation axis is valid +}; + + +ID_INLINE idRotation::idRotation( void ) { +} + +ID_INLINE idRotation::idRotation( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ) { + origin = rotationOrigin; + vec = rotationVec; + angle = rotationAngle; + axisValid = false; +} + +ID_INLINE void idRotation::Set( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ) { + origin = rotationOrigin; + vec = rotationVec; + angle = rotationAngle; + axisValid = false; +} + +ID_INLINE void idRotation::SetOrigin( const idVec3 &rotationOrigin ) { + origin = rotationOrigin; +} + +ID_INLINE void idRotation::SetVec( const idVec3 &rotationVec ) { + vec = rotationVec; + axisValid = false; +} + +ID_INLINE void idRotation::SetVec( float x, float y, float z ) { + vec[0] = x; + vec[1] = y; + vec[2] = z; + axisValid = false; +} + +ID_INLINE void idRotation::SetAngle( const float rotationAngle ) { + angle = rotationAngle; + axisValid = false; +} + +ID_INLINE void idRotation::Scale( const float s ) { + angle *= s; + axisValid = false; +} + +ID_INLINE void idRotation::ReCalculateMatrix( void ) { + axisValid = false; + ToMat3(); +} + +ID_INLINE const idVec3 &idRotation::GetOrigin( void ) const { + return origin; +} + +ID_INLINE const idVec3 &idRotation::GetVec( void ) const { + return vec; +} + +ID_INLINE float idRotation::GetAngle( void ) const { + return angle; +} + +ID_INLINE idRotation idRotation::operator-() const { + return idRotation( origin, vec, -angle ); +} + +ID_INLINE idRotation idRotation::operator*( const float s ) const { + return idRotation( origin, vec, angle * s ); +} + +ID_INLINE idRotation idRotation::operator/( const float s ) const { + assert( s != 0.0f ); + return idRotation( origin, vec, angle / s ); +} + +ID_INLINE idRotation &idRotation::operator*=( const float s ) { + angle *= s; + axisValid = false; + return *this; +} + +ID_INLINE idRotation &idRotation::operator/=( const float s ) { + assert( s != 0.0f ); + angle /= s; + axisValid = false; + return *this; +} + +ID_INLINE idVec3 idRotation::operator*( const idVec3 &v ) const { + if ( !axisValid ) { + ToMat3(); + } + return ((v - origin) * axis + origin); +} + +ID_INLINE idRotation operator*( const float s, const idRotation &r ) { + return r * s; +} + +ID_INLINE idVec3 operator*( const idVec3 &v, const idRotation &r ) { + return r * v; +} + +ID_INLINE idVec3 &operator*=( idVec3 &v, const idRotation &r ) { + v = r * v; + return v; +} + +ID_INLINE void idRotation::RotatePoint( idVec3 &point ) const { + if ( !axisValid ) { + ToMat3(); + } + point = ((point - origin) * axis + origin); +} + +#endif /* !__MATH_ROTATION_H__ */ diff --git a/idlib/math/Simd.cpp b/idlib/math/Simd.cpp new file mode 100644 index 000000000..1f8ea8f51 --- /dev/null +++ b/idlib/math/Simd.cpp @@ -0,0 +1,4325 @@ +// vim:ts=4:sw=4:cindent +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + + + +#include "Simd_Generic.h" +#include "Simd_MMX.h" +#include "Simd_3DNow.h" +#include "Simd_SSE.h" +#include "Simd_SSE2.h" +#include "Simd_SSE3.h" +#include "Simd_AltiVec.h" + +idSIMDProcessor * processor = NULL; // pointer to SIMD processor +idSIMDProcessor * generic = NULL; // pointer to generic SIMD implementation +idSIMDProcessor * SIMDProcessor = NULL; + + +/* +================ +idSIMD::Init +================ +*/ +void idSIMD::Init( void ) { + generic = new idSIMD_Generic; + generic->cpuid = CPUID_GENERIC; + processor = NULL; + SIMDProcessor = generic; +} + +/* +============ +idSIMD::InitProcessor +============ +*/ +void idSIMD::InitProcessor( const char *module, bool forceGeneric ) { + cpuid_t cpuid; + idSIMDProcessor *newProcessor; + + cpuid = idLib::sys->GetProcessorId(); + + /* + * Tels: Bug #2413: Under Linux, cpuid_t is 0, so use inline assembly to get + * the correct flags: + */ +#ifdef __linux__ + int cores = 0; + dword a,c,d, result; + + /* Check for AMD or Intel first */ + __asm__ __volatile__ ( + " pushl %%ebx;" // Save ebx (needed for PIC (position independend code) + " movl $0, %%eax;" // CPUID with EAX = 0 + " cpuid;" // Returns data into eax, ebx, ecx, edx + " movl %%ebx, %%eax;" // EAX => EBX + " popl %%ebx;" // Restore EBX + : "=d" (d), "=c" (c), "=a" (a) // EDX => d, ECX => c, EAX => a + : // no inputs + : ); // clobbers no additional registers (except EAX, ECX and EDX) + + //idLib::common->Printf( "cpuid result is a=%x, c=%x, d=%x\n", a,c,d ); + + result = CPUID_GENERIC; + // "AuthenticAMD" + if (( 0x68747541l == a ) && ( 0x444d4163l == c ) && ( 0x69746e65l == d ) ) + { + result = CPUID_AMD; + } + else + // "GenuineIntel" + if (( 0x756e6547l == a ) && ( 0x6c65746el == c ) && ( 0x49656e69l == d ) ) + { + result = CPUID_INTEL; + } + + __asm__ __volatile__ ( + " pushl %%ebx;" // Save ebx (needed for PIC (position independend code) + " movl $1, %%eax;" // CPUID with EAX = 1 + " cpuid;" // Returns data into eax, ebx, ecx, edx + " movl %%ebx, %%eax;" // Put EBX value into EAX (so we can return it) + " popl %%ebx;" // Restore ebx + : "=d" (d), "=c" (c), "=a" (a) // EDX => d, ECX => c, EAX => a + : // no inputs + : ); // clobbers no extra registers beside the outputs + + // This can only be checked on AMD CPUs + if ( (result & CPUID_AMD) && (d & 0x10000000l) ) // >> 31 does not work here + { + result += CPUID_3DNOW; + } + // The calculation how many physical/logical CPUs the machine has is rather + // convuluted and differes between AMD and Intel, so we don't attempt it, we + // only check bits 16..23 of EBX to see if it is > 1: + cores = (a >> 16) & 0xFF; + // Only on Intel we can have Hyper-Threading + if ( (result & CPUID_INTEL) && ((d >> 28) & 0x1) && cores > 1 ) + { + result += CPUID_HTT; + } + + // These tests are the same for AMD and Intel + if ((d >> 23) & 0x1) + { + result += CPUID_MMX; + } + if ((d >> 25) & 0x1) + { + result += CPUID_SSE; + } + if ((d >> 26) & 0x1) + { + result += CPUID_SSE2; + } + if ((d >> 15) & 0x1) + { + result += CPUID_CMOV; + } + if (c & 0x1) + { + result += CPUID_SSE3; + } + + //idLib::common->Printf( "cpuid result is %i (c = %i d = %i)\n", result, c, d); + cpuid = (cpuid_t)result; +#endif + + // Print what we found to console + idLib::common->Printf( "Found %s CPU%s, features:%s%s%s%s%s%s\n", + // Vendor + cpuid & CPUID_AMD ? "AMD" : + cpuid & CPUID_INTEL ? "Intel" : + cpuid & CPUID_GENERIC ? "Generic" : + "Unsupported", + // Hyper-Threading? + cpuid & CPUID_HTT ? " with Hyper-Threading enabled" : "", + + // the calculation how many physical/logical CPUs the machine has is rather + // convuluted and differes between AMD and Intel, so we don't attempt it: +// cores, +// cores > 1 ? "cores" : "core", + // Flags + cpuid & CPUID_MMX ? " MMX" : "", + cpuid & CPUID_SSE ? " SSE" : "", + cpuid & CPUID_SSE2 ? " SSE2" : "", + cpuid & CPUID_SSE3 ? " SSE3" : "", + cpuid & CPUID_3DNOW ? " 3DNow!" : "", + cpuid & CPUID_CMOV ? " CMOV" : "" ); + + if ( forceGeneric ) { + + newProcessor = generic; + + } else { + + if ( !processor ) { + if ( ( cpuid & CPUID_ALTIVEC ) ) { + processor = new idSIMD_AltiVec; + } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) && ( cpuid & CPUID_SSE2 ) && ( cpuid & CPUID_SSE3 ) ) { + processor = new idSIMD_SSE3; + } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) && ( cpuid & CPUID_SSE2 ) ) { + processor = new idSIMD_SSE2; + } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) ) { + processor = new idSIMD_SSE; + } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_3DNOW ) ) { + processor = new idSIMD_3DNow; + } else if ( ( cpuid & CPUID_MMX ) ) { + processor = new idSIMD_MMX; + } else { + processor = generic; + } + processor->cpuid = cpuid; + } + + newProcessor = processor; + } + + if ( newProcessor != SIMDProcessor ) { + SIMDProcessor = newProcessor; + } + idLib::common->Printf( "%s using %s for SIMD processing.\n", module, SIMDProcessor->GetName() ); + + if ( cpuid & CPUID_FTZ ) { + idLib::sys->FPU_SetFTZ( true ); + idLib::common->Printf( "enabled Flush-To-Zero mode\n" ); + } + + if ( cpuid & CPUID_DAZ ) { + idLib::sys->FPU_SetDAZ( true ); + idLib::common->Printf( "enabled Denormals-Are-Zero mode\n" ); + } +} + +/* +================ +idSIMD::Shutdown +================ +*/ +void idSIMD::Shutdown( void ) { + if ( processor != generic ) { + delete processor; + } + delete generic; + generic = NULL; + processor = NULL; + SIMDProcessor = NULL; +} + + +//=============================================================== +// +// Test code +// +//=============================================================== + +#define COUNT 1024 // data count +#define NUMTESTS 2048 // number of tests + +#define RANDOM_SEED 1013904223L //((int)idLib::sys->GetClockTicks()) + +idSIMDProcessor *p_simd; +idSIMDProcessor *p_generic; +long baseClocks = 0; + +#ifdef _WIN32 + +#define TIME_TYPE int + +#pragma warning(disable : 4731) // frame pointer register 'ebx' modified by inline assembly code + +long saved_ebx = 0; + +#define StartRecordTime( start ) \ + __asm mov saved_ebx, ebx \ + __asm xor eax, eax \ + __asm cpuid \ + __asm rdtsc \ + __asm mov start, eax \ + __asm xor eax, eax \ + __asm cpuid + +#define StopRecordTime( end ) \ + __asm xor eax, eax \ + __asm cpuid \ + __asm rdtsc \ + __asm mov end, eax \ + __asm mov ebx, saved_ebx \ + __asm xor eax, eax \ + __asm cpuid + +#elif MACOS_X + +#include +#include // this is for sleep() +#include +#include +#include + +double ticksPerNanosecond; + +#define TIME_TYPE uint64_t + +#ifdef __MWERKS__ //time_in_millisec is missing +/* + + .text + .align 2 + .globl _GetTB +_GetTB: + +loop: + mftbu r4 ; load from TBU + mftb r5 ; load from TBL + mftbu r6 ; load from TBU + cmpw r6, r4 ; see if old == new + bne loop ; if not, carry occured, therefore loop + + stw r4, 0(r3) + stw r5, 4(r3) + +done: + blr ; return + +*/ +typedef struct { + unsigned int hi; + unsigned int lo; +} U64; + + +asm void GetTB(U64 *in) +{ + nofralloc // suppress prolog + machine 603 // allows the use of mftb & mftbu functions + +loop: + mftbu r5 // grab the upper time base register (TBU) + mftb r4 // grab the lower time base register (TBL) + mftbu r6 // grab the upper time base register (TBU) again + + cmpw r6,r5 // see if old TBU == new TBU + bne- loop // loop if carry occurred (predict branch not taken) + + stw r4,4(r3) // store TBL in the low 32 bits of the return value + stw r5,0(r3) // store TBU in the high 32 bits of the return value + + blr +} + + + + +double TBToDoubleNano( U64 startTime, U64 stopTime, double ticksPerNanosecond ); + +#if __MWERKS__ +asm void GetTB( U64 * ); +#else +void GetTB( U64 * ); +#endif + +double TBToDoubleNano( U64 startTime, U64 stopTime, double ticksPerNanosecond ) { + #define K_2POWER32 4294967296.0 + #define TICKS_PER_NANOSECOND 0.025 + double nanoTime; + U64 diffTime; + + // calc the difference in TB ticks + diffTime.hi = stopTime.hi - startTime.hi; + diffTime.lo = stopTime.lo - startTime.lo; + + // convert TB ticks into time + nanoTime = (double)(diffTime.hi)*((double)K_2POWER32) + (double)(diffTime.lo); + nanoTime = nanoTime/ticksPerNanosecond; + return (nanoTime); +} + +TIME_TYPE time_in_millisec( void ) { + #define K_2POWER32 4294967296.0 + #define TICKS_PER_NANOSECOND 0.025 + + U64 the_time; + double nanoTime, milliTime; + + GetTB( &the_time ); + + // convert TB ticks into time + nanoTime = (double)(the_time.hi)*((double)K_2POWER32) + (double)(the_time.lo); + nanoTime = nanoTime/ticksPerNanosecond; + + // nanoseconds are 1 billionth of a second. I want milliseconds + milliTime = nanoTime * 1000000.0; + + printf( "ticks per nanosec -- %lf\n", ticksPerNanosecond ); + printf( "nanoTime is %lf -- milliTime is %lf -- as int is %i\n", nanoTime, milliTime, (int)milliTime ); + + return (int)milliTime; +} + +#define StartRecordTime( start ) \ + start = time_in_millisec(); + +#define StopRecordTime( end ) \ + end = time_in_millisec(); + + +#else +#define StartRecordTime( start ) \ + start = mach_absolute_time(); + +#define StopRecordTime( end ) \ + end = mach_absolute_time(); +#endif +#else + +#define TIME_TYPE int + +#define StartRecordTime( start ) \ + start = 0; + +#define StopRecordTime( end ) \ + end = 1; + +#endif + +#define GetBest( start, end, best ) \ + if ( !best || end - start < best ) { \ + best = end - start; \ + } + + +/* +============ +PrintClocks +============ +*/ +void PrintClocks( char *string, int dataCount, int clocks, int otherClocks = 0 ) { + int i; + + idLib::common->Printf( string ); + for ( i = idStr::LengthWithoutColors(string); i < 48; i++ ) { + idLib::common->Printf(" "); + } + clocks -= baseClocks; + if ( otherClocks && clocks ) { + otherClocks -= baseClocks; + int p = (int) ( (float) ( otherClocks - clocks ) * 100.0f / (float) otherClocks ); + idLib::common->Printf( "c = %4d, clcks = %5d, %d%%\n", dataCount, clocks, p ); + } else { + idLib::common->Printf( "c = %4d, clcks = %5d\n", dataCount, clocks ); + } +} + +/* +============ +GetBaseClocks +============ +*/ +void GetBaseClocks( void ) { + int i, start, end, bestClocks; + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + baseClocks = bestClocks; +} + +/* +============ +TestAdd +============ +*/ +void TestAdd( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + fsrc1[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Add( fdst0, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Add( float + float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Add( fdst1, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Add( float + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Add( fdst0, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Add( float[] + float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Add( fdst1, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Add( float[] + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestSub +============ +*/ +void TestSub( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + fsrc1[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Sub( fdst0, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Sub( float + float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Sub( fdst1, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Sub( float + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Sub( fdst0, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Sub( float[] + float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Sub( fdst1, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Sub( float[] + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestMul +============ +*/ +void TestMul( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + fsrc1[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Mul( fdst0, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Mul( float * float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Mul( fdst1, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Mul( float * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Mul( fdst0, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Mul( float[] * float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Mul( fdst1, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Mul( float[] * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestDiv +============ +*/ +void TestDiv( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + do { + fsrc1[i] = srnd.CRandomFloat() * 10.0f; + } while( idMath::Fabs( fsrc1[i] ) < 0.1f ); + } + + idLib::common->Printf("====================================\n" ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Div( fdst0, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Div( float * float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Div( fdst1, 4.0f, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Div( float * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Div( fdst0, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Div( float[] * float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Div( fdst1, fsrc0, fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-3f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Div( float[] * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestMulAdd +============ +*/ +void TestMulAdd( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + for ( j = 0; j < 50 && j < COUNT; j++ ) { + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( int k = 0; k < COUNT; k++ ) { + fdst0[k] = k; + } + StartRecordTime( start ); + p_generic->MulAdd( fdst0, 0.123f, fsrc0, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( va( "generic->MulAdd( float * float[%2d] )", j ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( int k = 0; k < COUNT; k++ ) { + fdst1[k] = k; + } + StartRecordTime( start ); + p_simd->MulAdd( fdst1, 0.123f, fsrc0, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MulAdd( float * float[%2d] ) %s", j, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMulSub +============ +*/ +void TestMulSub( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + for ( j = 0; j < 50 && j < COUNT; j++ ) { + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( int k = 0; k < COUNT; k++ ) { + fdst0[k] = k; + } + StartRecordTime( start ); + p_generic->MulSub( fdst0, 0.123f, fsrc0, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( va( "generic->MulSub( float * float[%2d] )", j ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( int k = 0; k < COUNT; k++ ) { + fdst1[k] = k; + } + StartRecordTime( start ); + p_simd->MulSub( fdst1, 0.123f, fsrc0, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MulSub( float * float[%2d] ) %s", j, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestDot +============ +*/ +void TestDot( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + ALIGN16( idVec3 v3src0[COUNT] ); + ALIGN16( idVec3 v3src1[COUNT] ); + ALIGN16( idVec3 v3constant ) ( 1.0f, 2.0f, 3.0f ); + ALIGN16( idPlane v4src0[COUNT] ); + ALIGN16( idPlane v4constant ) (1.0f, 2.0f, 3.0f, 4.0f); + ALIGN16( idDrawVert drawVerts[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + fsrc1[i] = srnd.CRandomFloat() * 10.0f; + v3src0[i][0] = srnd.CRandomFloat() * 10.0f; + v3src0[i][1] = srnd.CRandomFloat() * 10.0f; + v3src0[i][2] = srnd.CRandomFloat() * 10.0f; + v3src1[i][0] = srnd.CRandomFloat() * 10.0f; + v3src1[i][1] = srnd.CRandomFloat() * 10.0f; + v3src1[i][2] = srnd.CRandomFloat() * 10.0f; + v4src0[i] = v3src0[i]; + v4src0[i][3] = srnd.CRandomFloat() * 10.0f; + drawVerts[i].xyz = v3src0[i]; + } + + idLib::common->Printf("====================================\n" ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v3constant, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idVec3 * idVec3[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v3constant, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idVec3 * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v3constant, v4src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idVec3 * idPlane[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v3constant, v4src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idVec3 * idPlane[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v3constant, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idVec3 * idDrawVert[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v3constant, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idVec3 * idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v4constant, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idPlane * idVec3[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v4constant, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idPlane * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v4constant, v4src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idPlane * idPlane[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v4constant, v4src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idPlane * idPlane[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v4constant, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idPlane * idDrawVert[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v4constant, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idPlane * idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( fdst0, v3src0, v3src1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Dot( idVec3[] * idVec3[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( fdst1, v3src0, v3src1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-4f ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( idVec3[] * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + idLib::common->Printf("====================================\n" ); + + float dot1 = 0.0f, dot2 = 0.0f; + for ( j = 0; j < 50 && j < COUNT; j++ ) { + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Dot( dot1, fsrc0, fsrc1, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( va( "generic->Dot( float[%2d] * float[%2d] )", j, j ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Dot( dot2, fsrc0, fsrc1, j ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + result = idMath::Fabs( dot1 - dot2 ) < 1e-4f ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Dot( float[%2d] * float[%2d] ) %s", j, j, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestCompare +============ +*/ +void TestCompare( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( byte bytedst[COUNT] ); + ALIGN16( byte bytedst2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CmpGT( bytedst, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpGT( float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CmpGT( bytedst2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpGT( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst, 0, COUNT ); + StartRecordTime( start ); + p_generic->CmpGT( bytedst, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpGT( 2, float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst2, 0, COUNT ); + StartRecordTime( start ); + p_simd->CmpGT( bytedst2, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpGT( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + // ====================== + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CmpGE( bytedst, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpGE( float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CmpGE( bytedst2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpGE( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst, 0, COUNT ); + StartRecordTime( start ); + p_generic->CmpGE( bytedst, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpGE( 2, float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst2, 0, COUNT ); + StartRecordTime( start ); + p_simd->CmpGE( bytedst2, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpGE( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + // ====================== + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CmpLT( bytedst, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpLT( float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CmpLT( bytedst2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpLT( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst, 0, COUNT ); + StartRecordTime( start ); + p_generic->CmpLT( bytedst, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpLT( 2, float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst2, 0, COUNT ); + StartRecordTime( start ); + p_simd->CmpLT( bytedst2, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpLT( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + // ====================== + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CmpLE( bytedst, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpLE( float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CmpLE( bytedst2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpLE( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst, 0, COUNT ); + StartRecordTime( start ); + p_generic->CmpLE( bytedst, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CmpLE( 2, float[] >= float )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + memset( bytedst2, 0, COUNT ); + StartRecordTime( start ); + p_simd->CmpLE( bytedst2, 2, fsrc0, 0.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( bytedst[i] != bytedst2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CmpLE( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestMinMax +============ +*/ +void TestMinMax( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( idVec2 v2src0[COUNT] ); + ALIGN16( idVec3 v3src0[COUNT] ); + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( int indexes[COUNT] ); + float min = 0.0f, max = 0.0f, min2 = 0.0f, max2 = 0.0f; + idVec2 v2min, v2max, v2min2, v2max2; + idVec3 vmin, vmax, vmin2, vmax2; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + v2src0[i][0] = srnd.CRandomFloat() * 10.0f; + v2src0[i][1] = srnd.CRandomFloat() * 10.0f; + v3src0[i][0] = srnd.CRandomFloat() * 10.0f; + v3src0[i][1] = srnd.CRandomFloat() * 10.0f; + v3src0[i][2] = srnd.CRandomFloat() * 10.0f; + drawVerts[i].xyz = v3src0[i]; + indexes[i] = i; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + min = idMath::INFINITY; + max = -idMath::INFINITY; + StartRecordTime( start ); + p_generic->MinMax( min, max, fsrc0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MinMax( float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->MinMax( min2, max2, fsrc0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = ( min == min2 && max == max2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MinMax( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->MinMax( v2min, v2max, v2src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MinMax( idVec2[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->MinMax( v2min2, v2max2, v2src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = ( v2min == v2min2 && v2max == v2max2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MinMax( idVec2[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->MinMax( vmin, vmax, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MinMax( idVec3[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->MinMax( vmin2, vmax2, v3src0, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MinMax( idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->MinMax( vmin, vmax, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MinMax( idDrawVert[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->MinMax( vmin2, vmax2, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MinMax( idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->MinMax( vmin, vmax, drawVerts, indexes, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MinMax( idDrawVert[], indexes[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->MinMax( vmin2, vmax2, drawVerts, indexes, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MinMax( idDrawVert[], indexes[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestClamp +============ +*/ +void TestClamp( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fdst0[COUNT] ); + ALIGN16( float fdst1[COUNT] ); + ALIGN16( float fsrc0[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->Clamp( fdst0, fsrc0, -1.0f, 1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Clamp( float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->Clamp( fdst1, fsrc0, -1.0f, 1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( fdst0[i] != fdst1[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Clamp( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->ClampMin( fdst0, fsrc0, -1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->ClampMin( float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->ClampMin( fdst1, fsrc0, -1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( fdst0[i] != fdst1[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->ClampMin( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->ClampMax( fdst0, fsrc0, 1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->ClampMax( float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->ClampMax( fdst1, fsrc0, 1.0f, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( fdst0[i] != fdst1[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->ClampMax( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestMemcpy +============ +*/ +void TestMemcpy( void ) { + int i, j; + byte test0[8192]; + byte test1[8192]; + + idRandom random( RANDOM_SEED ); + + idLib::common->Printf("====================================\n" ); + + for ( i = 5; i < 8192; i += 31 ) { + for ( j = 0; j < i; j++ ) { + test0[j] = random.RandomInt( 255 ); + } + p_simd->Memcpy( test1, test0, 8192 ); + for ( j = 0; j < i; j++ ) { + if ( test1[j] != test0[j] ) { + idLib::common->Printf( " simd->Memcpy() "S_COLOR_RED"X\n" ); + return; + } + } + } + idLib::common->Printf( " simd->Memcpy() ok\n" ); +} + +/* +============ +TestMemset +============ +*/ +void TestMemset( void ) { + int i, j, k; + byte test[8192]; + + for ( i = 0; i < 8192; i++ ) { + test[i] = 0; + } + + for ( i = 5; i < 8192; i += 31 ) { + for ( j = -1; j <= 1; j++ ) { + p_simd->Memset( test, j, i ); + for ( k = 0; k < i; k++ ) { + if ( test[k] != (byte)j ) { + idLib::common->Printf( " simd->Memset() "S_COLOR_RED"X\n" ); + return; + } + } + } + } + idLib::common->Printf( " simd->Memset() ok\n" ); +} + +#define MATX_SIMD_EPSILON 1e-5f + +/* +============ +TestMatXMultiplyVecX +============ +*/ +void TestMatXMultiplyVecX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX mat; + idVecX src(6); + idVecX dst(6); + idVecX tst(6); + + src[0] = 1.0f; + src[1] = 2.0f; + src[2] = 3.0f; + src[3] = 4.0f; + src[4] = 5.0f; + src[5] = 6.0f; + + idLib::common->Printf("================= NxN * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyVecX %dx%d*%dx1", i, i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyVecX %dx%d*%dx1 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= Nx6 * 6x1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyVecX %dx6*6x1", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyVecX %dx6*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyVecX 6x%d*%dx1", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_MultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyVecX 6x%d*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXMultiplyAddVecX +============ +*/ +void TestMatXMultiplyAddVecX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX mat; + idVecX src(6); + idVecX dst(6); + idVecX tst(6); + + src[0] = 1.0f; + src[1] = 2.0f; + src[2] = 3.0f; + src[3] = 4.0f; + src[4] = 5.0f; + src[5] = 6.0f; + + idLib::common->Printf("================= NxN * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyAddVecX %dx%d*%dx1", i, i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyAddVecX %dx%d*%dx1 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= Nx6 * 6x1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyAddVecX %dx6*6x1", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyAddVecX %dx6*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyAddVecX 6x%d*%dx1", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_MultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyAddVecX 6x%d*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXTransposeMultiplyVecX +============ +*/ +void TestMatXTransposeMultiplyVecX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX mat; + idVecX src(6); + idVecX dst(6); + idVecX tst(6); + + src[0] = 1.0f; + src[1] = 2.0f; + src[2] = 3.0f; + src[3] = 4.0f; + src[4] = 5.0f; + src[5] = 6.0f; + + idLib::common->Printf("================= Nx6 * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransposeMulVecX %dx6*%dx1", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransposeMulVecX %dx6*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * 6x1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransposeMulVecX 6x%d*6x1", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransposeMulVecX 6x%d*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXTransposeMultiplyAddVecX +============ +*/ +void TestMatXTransposeMultiplyAddVecX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX mat; + idVecX src(6); + idVecX dst(6); + idVecX tst(6); + + src[0] = 1.0f; + src[1] = 2.0f; + src[2] = 3.0f; + src[3] = 4.0f; + src[4] = 5.0f; + src[5] = 6.0f; + + idLib::common->Printf("================= Nx6 * Nx1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransposeMulAddVecX %dx6*%dx1", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransposeMulAddVecX %dx6*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * 6x1 ===================\n" ); + + for ( i = 1; i <= 6; i++ ) { + mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransposeMulAddVecX 6x%d*6x1", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + dst.Zero(); + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyAddVecX( dst, mat, src ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransposeMulAddVecX 6x%d*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXMultiplyMatX +============ +*/ +#define TEST_VALUE_RANGE 10.0f +#define MATX_MATX_SIMD_EPSILON 1e-4f + +void TestMatXMultiplyMatX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX m1, m2, dst, tst; + + idLib::common->Printf("================= NxN * Nx6 ===================\n" ); + + // NxN * Nx6 + for ( i = 1; i <= 5; i++ ) { + m1.Random( i, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( i, 6 ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyMatX %dx%d*%dx6", i, i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyMatX %dx%d*%dx6 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * Nx6 ===================\n" ); + + // 6xN * Nx6 + for ( i = 1; i <= 5; i++ ) { + m1.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( 6, 6 ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyMatX 6x%d*%dx6", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyMatX 6x%d*%dx6 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= Nx6 * 6xN ===================\n" ); + + // Nx6 * 6xN + for ( i = 1; i <= 5; i++ ) { + m1.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( i, i ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyMatX %dx6*6x%d", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyMatX %dx6*6x%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6x6 * 6xN ===================\n" ); + + // 6x6 * 6xN + for ( i = 1; i <= 6; i++ ) { + m1.Random( 6, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( 6, i ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_MultiplyMatX 6x6*6x%d", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_MultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_MultiplyMatX 6x6*6x%d %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXTransposeMultiplyMatX +============ +*/ +void TestMatXTransposeMultiplyMatX( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX m1, m2, dst, tst; + + idLib::common->Printf("================= Nx6 * NxN ===================\n" ); + + // Nx6 * NxN + for ( i = 1; i <= 5; i++ ) { + m1.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( i, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( 6, i ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransMultiplyMatX %dx6*%dx%d", i, i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransMultiplyMatX %dx6*%dx%d %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } + + idLib::common->Printf("================= 6xN * 6x6 ===================\n" ); + + // 6xN * 6x6 + for ( i = 1; i <= 6; i++ ) { + m1.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + m2.Random( 6, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); + dst.SetSize( i, 6 ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_TransposeMultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = dst; + + PrintClocks( va( "generic->MatX_TransMultiplyMatX 6x%d*6x6", i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_TransposeMultiplyMatX( dst, m1, m2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_TransMultiplyMatX 6x%d*6x6 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +#define MATX_LTS_SIMD_EPSILON 1.0f +#define MATX_LTS_SOLVE_SIZE 100 + +/* +============ +TestMatXLowerTriangularSolve +============ +*/ +void TestMatXLowerTriangularSolve( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX L; + idVecX x, b, tst; + + idLib::common->Printf("====================================\n" ); + + L.Random( MATX_LTS_SOLVE_SIZE, MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); + x.SetSize( MATX_LTS_SOLVE_SIZE ); + b.Random( MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); + + for ( i = 1; i < MATX_LTS_SOLVE_SIZE; i++ ) { + + x.Zero( i ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_LowerTriangularSolve( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = x; + x.Zero(); + + PrintClocks( va( "generic->MatX_LowerTriangularSolve %dx%d", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_LowerTriangularSolve( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = x.Compare( tst, MATX_LTS_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_LowerTriangularSolve %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestMatXLowerTriangularSolveTranspose +============ +*/ +void TestMatXLowerTriangularSolveTranspose( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX L; + idVecX x, b, tst; + + idLib::common->Printf("====================================\n" ); + + L.Random( MATX_LTS_SOLVE_SIZE, MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); + x.SetSize( MATX_LTS_SOLVE_SIZE ); + b.Random( MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); + + for ( i = 1; i < MATX_LTS_SOLVE_SIZE; i++ ) { + + x.Zero( i ); + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_generic->MatX_LowerTriangularSolveTranspose( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + tst = x; + x.Zero(); + + PrintClocks( va( "generic->MatX_LowerTriangularSolveT %dx%d", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + StartRecordTime( start ); + p_simd->MatX_LowerTriangularSolveTranspose( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = x.Compare( tst, MATX_LTS_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_LowerTriangularSolveT %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +#define MATX_LDLT_SIMD_EPSILON 0.1f +#define MATX_LDLT_FACTOR_SOLVE_SIZE 64 + +/* +============ +TestMatXLDLTFactor +============ +*/ +void TestMatXLDLTFactor( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + const char *result; + idMatX src, original, mat1, mat2; + idVecX invDiag1, invDiag2; + + idLib::common->Printf("====================================\n" ); + + original.SetSize( MATX_LDLT_FACTOR_SOLVE_SIZE, MATX_LDLT_FACTOR_SOLVE_SIZE ); + src.Random( MATX_LDLT_FACTOR_SOLVE_SIZE, MATX_LDLT_FACTOR_SOLVE_SIZE, 0, -1.0f, 1.0f ); + src.TransposeMultiply( original, src ); + + for ( i = 1; i < MATX_LDLT_FACTOR_SOLVE_SIZE; i++ ) { + + bestClocksGeneric = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + mat1 = original; + invDiag1.Zero( MATX_LDLT_FACTOR_SOLVE_SIZE ); + StartRecordTime( start ); + p_generic->MatX_LDLTFactor( mat1, invDiag1, i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + + PrintClocks( va( "generic->MatX_LDLTFactor %dx%d", i, i ), 1, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( j = 0; j < NUMTESTS; j++ ) { + mat2 = original; + invDiag2.Zero( MATX_LDLT_FACTOR_SOLVE_SIZE ); + StartRecordTime( start ); + p_simd->MatX_LDLTFactor( mat2, invDiag2, i ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + result = mat1.Compare( mat2, MATX_LDLT_SIMD_EPSILON ) && invDiag1.Compare( invDiag2, MATX_LDLT_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MatX_LDLTFactor %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); + } +} + +/* +============ +TestBlendJoints +============ +*/ +void TestBlendJoints( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idJointQuat baseJoints[COUNT] ); + ALIGN16( idJointQuat joints1[COUNT] ); + ALIGN16( idJointQuat joints2[COUNT] ); + ALIGN16( idJointQuat blendJoints[COUNT] ); + ALIGN16( int index[COUNT] ); + float lerp = 0.3f; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + baseJoints[i].q = angles.ToQuat(); + baseJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; + baseJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; + baseJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + blendJoints[i].q = angles.ToQuat(); + blendJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; + blendJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; + blendJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; + index[i] = i; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < COUNT; j++ ) { + joints1[j] = baseJoints[j]; + } + StartRecordTime( start ); + p_generic->BlendJoints( joints1, blendJoints, lerp, index, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->BlendJoints()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < COUNT; j++ ) { + joints2[j] = baseJoints[j]; + } + StartRecordTime( start ); + p_simd->BlendJoints( joints2, blendJoints, lerp, index, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !joints1[i].t.Compare( joints2[i].t, 1e-3f ) ) { + break; + } + if ( !joints1[i].q.Compare( joints2[i].q, 1e-2f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->BlendJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestConvertJointQuatsToJointMats +============ +*/ +void TestConvertJointQuatsToJointMats( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idJointQuat baseJoints[COUNT] ); + ALIGN16( idJointMat joints1[COUNT] ); + ALIGN16( idJointMat joints2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + baseJoints[i].q = angles.ToQuat(); + baseJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; + baseJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; + baseJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->ConvertJointQuatsToJointMats( joints1, baseJoints, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->ConvertJointQuatsToJointMats()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->ConvertJointQuatsToJointMats( joints2, baseJoints, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !joints1[i].Compare( joints2[i], 1e-4f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->ConvertJointQuatsToJointMats() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestConvertJointMatsToJointQuats +============ +*/ +void TestConvertJointMatsToJointQuats( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idJointMat baseJoints[COUNT] ); + ALIGN16( idJointQuat joints1[COUNT] ); + ALIGN16( idJointQuat joints2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + baseJoints[i].SetRotation( angles.ToMat3() ); + idVec3 v; + v[0] = srnd.CRandomFloat() * 10.0f; + v[1] = srnd.CRandomFloat() * 10.0f; + v[2] = srnd.CRandomFloat() * 10.0f; + baseJoints[i].SetTranslation( v ); + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->ConvertJointMatsToJointQuats( joints1, baseJoints, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->ConvertJointMatsToJointQuats()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->ConvertJointMatsToJointQuats( joints2, baseJoints, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !joints1[i].q.Compare( joints2[i].q, 1e-4f ) ) { + idLib::common->Printf("ConvertJointMatsToJointQuats: broken q %i\n", i ); + break; + } + if ( !joints1[i].t.Compare( joints2[i].t, 1e-4f ) ) { + idLib::common->Printf("ConvertJointMatsToJointQuats: broken t %i\n", i ); + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->ConvertJointMatsToJointQuats() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestTransformJoints +============ +*/ +void TestTransformJoints( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idJointMat joints[COUNT+1] ); + ALIGN16( idJointMat joints1[COUNT+1] ); + ALIGN16( idJointMat joints2[COUNT+1] ); + ALIGN16( int parents[COUNT+1] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i <= COUNT; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + joints[i].SetRotation( angles.ToMat3() ); + idVec3 v; + v[0] = srnd.CRandomFloat() * 2.0f; + v[1] = srnd.CRandomFloat() * 2.0f; + v[2] = srnd.CRandomFloat() * 2.0f; + joints[i].SetTranslation( v ); + parents[i] = i - 1; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j <= COUNT; j++ ) { + joints1[j] = joints[j]; + } + StartRecordTime( start ); + p_generic->TransformJoints( joints1, parents, 1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->TransformJoints()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j <= COUNT; j++ ) { + joints2[j] = joints[j]; + } + StartRecordTime( start ); + p_simd->TransformJoints( joints2, parents, 1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !joints1[i+1].Compare( joints2[i+1], 1e-4f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->TransformJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestUntransformJoints +============ +*/ +void TestUntransformJoints( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idJointMat joints[COUNT+1] ); + ALIGN16( idJointMat joints1[COUNT+1] ); + ALIGN16( idJointMat joints2[COUNT+1] ); + ALIGN16( int parents[COUNT+1] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i <= COUNT; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + joints[i].SetRotation( angles.ToMat3() ); + idVec3 v; + v[0] = srnd.CRandomFloat() * 2.0f; + v[1] = srnd.CRandomFloat() * 2.0f; + v[2] = srnd.CRandomFloat() * 2.0f; + joints[i].SetTranslation( v ); + parents[i] = i - 1; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j <= COUNT; j++ ) { + joints1[j] = joints[j]; + } + StartRecordTime( start ); + p_generic->UntransformJoints( joints1, parents, 1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->UntransformJoints()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j <= COUNT; j++ ) { + joints2[j] = joints[j]; + } + StartRecordTime( start ); + p_simd->UntransformJoints( joints2, parents, 1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !joints1[i+1].Compare( joints2[i+1], 1e-4f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->UntransformJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestTransformVerts +============ +*/ +#define NUMJOINTS 64 +#define NUMVERTS COUNT/2 +void TestTransformVerts( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts1[NUMVERTS] ); + ALIGN16( idDrawVert drawVerts2[NUMVERTS] ); + ALIGN16( idJointMat joints[NUMJOINTS] ); + ALIGN16( idVec4 weights[COUNT] ); + ALIGN16( int weightIndex[COUNT*2] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < NUMJOINTS; i++ ) { + idAngles angles; + angles[0] = srnd.CRandomFloat() * 180.0f; + angles[1] = srnd.CRandomFloat() * 180.0f; + angles[2] = srnd.CRandomFloat() * 180.0f; + joints[i].SetRotation( angles.ToMat3() ); + idVec3 v; + v[0] = srnd.CRandomFloat() * 2.0f; + v[1] = srnd.CRandomFloat() * 2.0f; + v[2] = srnd.CRandomFloat() * 2.0f; + joints[i].SetTranslation( v ); + } + + for ( i = 0; i < COUNT; i++ ) { + weights[i][0] = srnd.CRandomFloat() * 2.0f; + weights[i][1] = srnd.CRandomFloat() * 2.0f; + weights[i][2] = srnd.CRandomFloat() * 2.0f; + weights[i][3] = srnd.CRandomFloat(); + weightIndex[i*2+0] = ( i * NUMJOINTS / COUNT ) * sizeof( idJointMat ); + weightIndex[i*2+1] = i & 1; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->TransformVerts( drawVerts1, NUMVERTS, joints, weights, weightIndex, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->TransformVerts()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->TransformVerts( drawVerts2, NUMVERTS, joints, weights, weightIndex, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < NUMVERTS; i++ ) { + if ( !drawVerts1[i].xyz.Compare( drawVerts2[i].xyz, 0.5f ) ) { + break; + } + } + result = ( i >= NUMVERTS ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->TransformVerts() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestTracePointCull +============ +*/ +void TestTracePointCull( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idPlane planes[4] ); + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( byte cullBits1[COUNT] ); + ALIGN16( byte cullBits2[COUNT] ); + byte totalOr1 = 0, totalOr2 = 0; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + planes[0].SetNormal( idVec3( 1, 0, 0 ) ); + planes[1].SetNormal( idVec3( -1, 0, 0 ) ); + planes[2].SetNormal( idVec3( 0, 1, 0 ) ); + planes[3].SetNormal( idVec3( 0, -1, 0 ) ); + planes[0][3] = -5.3f; + planes[1][3] = 5.3f; + planes[2][3] = -3.4f; + planes[3][3] = 3.4f; + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->TracePointCull( cullBits1, totalOr1, 0.0f, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->TracePointCull()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->TracePointCull( cullBits2, totalOr2, 0.0f, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( cullBits1[i] != cullBits2[i] ) { + break; + } + } + result = ( i >= COUNT && totalOr1 == totalOr2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->TracePointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestDecalPointCull +============ +*/ +void TestDecalPointCull( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idPlane planes[6] ); + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( byte cullBits1[COUNT] ); + ALIGN16( byte cullBits2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + planes[0].SetNormal( idVec3( 1, 0, 0 ) ); + planes[1].SetNormal( idVec3( -1, 0, 0 ) ); + planes[2].SetNormal( idVec3( 0, 1, 0 ) ); + planes[3].SetNormal( idVec3( 0, -1, 0 ) ); + planes[4].SetNormal( idVec3( 0, 0, 1 ) ); + planes[5].SetNormal( idVec3( 0, 0, -1 ) ); + planes[0][3] = -5.3f; + planes[1][3] = 5.3f; + planes[2][3] = -4.4f; + planes[3][3] = 4.4f; + planes[4][3] = -3.5f; + planes[5][3] = 3.5f; + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->DecalPointCull( cullBits1, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->DecalPointCull()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->DecalPointCull( cullBits2, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( cullBits1[i] != cullBits2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->DecalPointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestOverlayPointCull +============ +*/ +void TestOverlayPointCull( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idPlane planes[2] ); + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( byte cullBits1[COUNT] ); + ALIGN16( byte cullBits2[COUNT] ); + ALIGN16( idVec2 texCoords1[COUNT] ); + ALIGN16( idVec2 texCoords2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + planes[0].SetNormal( idVec3( 0.3f, 0.2f, 0.9f ) ); + planes[1].SetNormal( idVec3( 0.9f, 0.2f, 0.3f ) ); + planes[0][3] = -5.3f; + planes[1][3] = -4.3f; + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->OverlayPointCull( cullBits1, texCoords1, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->OverlayPointCull()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->OverlayPointCull( cullBits2, texCoords2, planes, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( cullBits1[i] != cullBits2[i] ) { + break; + } + if ( !texCoords1[i].Compare( texCoords2[i], 1e-4f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->OverlayPointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestDeriveTriPlanes +============ +*/ +void TestDeriveTriPlanes( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts1[COUNT] ); + ALIGN16( idDrawVert drawVerts2[COUNT] ); + ALIGN16( idPlane planes1[COUNT] ); + ALIGN16( idPlane planes2[COUNT] ); + ALIGN16( int indexes[COUNT*3] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + for ( j = 0; j < 2; j++ ) { + drawVerts1[i].st[j] = srnd.CRandomFloat(); + } + drawVerts2[i] = drawVerts1[i]; + } + + for ( i = 0; i < COUNT; i++ ) { + indexes[i*3+0] = ( i + 0 ) % COUNT; + indexes[i*3+1] = ( i + 1 ) % COUNT; + indexes[i*3+2] = ( i + 2 ) % COUNT; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->DeriveTriPlanes( planes1, drawVerts1, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->DeriveTriPlanes()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->DeriveTriPlanes( planes2, drawVerts2, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !planes1[i].Compare( planes2[i], 1e-1f, 1e-1f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->DeriveTriPlanes() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestDeriveTangents +============ +*/ +void TestDeriveTangents( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts1[COUNT] ); + ALIGN16( idDrawVert drawVerts2[COUNT] ); + ALIGN16( idPlane planes1[COUNT] ); + ALIGN16( idPlane planes2[COUNT] ); + ALIGN16( int indexes[COUNT*3] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + for ( j = 0; j < 2; j++ ) { + drawVerts1[i].st[j] = srnd.CRandomFloat(); + } + drawVerts2[i] = drawVerts1[i]; + } + + for ( i = 0; i < COUNT; i++ ) { + indexes[i*3+0] = ( i + 0 ) % COUNT; + indexes[i*3+1] = ( i + 1 ) % COUNT; + indexes[i*3+2] = ( i + 2 ) % COUNT; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->DeriveTangents( planes1, drawVerts1, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->DeriveTangents()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->DeriveTangents( planes2, drawVerts2, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + idVec3 v1, v2; + + v1 = drawVerts1[i].normal; + v1.Normalize(); + v2 = drawVerts2[i].normal; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + idLib::common->Printf("DeriveTangents: broken at normal %i\n -- expecting %s got %s", i, v1.ToString(), v2.ToString()); + break; + } + v1 = drawVerts1[i].tangents[0]; + v1.Normalize(); + v2 = drawVerts2[i].tangents[0]; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + idLib::common->Printf("DeriveTangents: broken at tangent0 %i -- expecting %s got %s\n", i, v1.ToString(), v2.ToString() ); + break; + } + v1 = drawVerts1[i].tangents[1]; + v1.Normalize(); + v2 = drawVerts2[i].tangents[1]; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + idLib::common->Printf("DeriveTangents: broken at tangent1 %i -- expecting %s got %s\n", i, v1.ToString(), v2.ToString() ); + break; + } + if ( !planes1[i].Compare( planes2[i], 1e-1f, 1e-1f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->DeriveTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestDeriveUnsmoothedTangents +============ +*/ +void TestDeriveUnsmoothedTangents( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts1[COUNT] ); + ALIGN16( idDrawVert drawVerts2[COUNT] ); + ALIGN16( dominantTri_s dominantTris[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; + } + for ( j = 0; j < 2; j++ ) { + drawVerts1[i].st[j] = srnd.CRandomFloat(); + } + drawVerts2[i] = drawVerts1[i]; + + dominantTris[i].v2 = ( i + 1 + srnd.RandomInt( 8 ) ) % COUNT; + dominantTris[i].v3 = ( i + 9 + srnd.RandomInt( 8 ) ) % COUNT; + dominantTris[i].normalizationScale[0] = srnd.CRandomFloat(); + dominantTris[i].normalizationScale[1] = srnd.CRandomFloat(); + dominantTris[i].normalizationScale[2] = srnd.CRandomFloat(); + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->DeriveUnsmoothedTangents( drawVerts1, dominantTris, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->DeriveUnsmoothedTangents()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->DeriveUnsmoothedTangents( drawVerts2, dominantTris, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + idVec3 v1, v2; + + v1 = drawVerts1[i].normal; + v1.Normalize(); + v2 = drawVerts2[i].normal; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + break; + } + v1 = drawVerts1[i].tangents[0]; + v1.Normalize(); + v2 = drawVerts2[i].tangents[0]; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + break; + } + v1 = drawVerts1[i].tangents[1]; + v1.Normalize(); + v2 = drawVerts2[i].tangents[1]; + v2.Normalize(); + if ( !v1.Compare( v2, 1e-1f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->DeriveUnsmoothedTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestNormalizeTangents +============ +*/ +void TestNormalizeTangents( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts1[COUNT] ); + ALIGN16( idDrawVert drawVerts2[COUNT] ); + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts1[i].normal[j] = srnd.CRandomFloat() * 10.0f; + drawVerts1[i].tangents[0][j] = srnd.CRandomFloat() * 10.0f; + drawVerts1[i].tangents[1][j] = srnd.CRandomFloat() * 10.0f; + } + drawVerts2[i] = drawVerts1[i]; + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->NormalizeTangents( drawVerts1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->NormalizeTangents()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->NormalizeTangents( drawVerts2, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !drawVerts1[i].normal.Compare( drawVerts2[i].normal, 1e-2f ) ) { + break; + } + if ( !drawVerts1[i].tangents[0].Compare( drawVerts2[i].tangents[0], 1e-2f ) ) { + break; + } + if ( !drawVerts1[i].tangents[1].Compare( drawVerts2[i].tangents[1], 1e-2f ) ) { + break; + } + + // since we're doing a lot of unaligned work, added this check to + // make sure xyz wasn't getting overwritten + if ( !drawVerts1[i].xyz.Compare( drawVerts2[i].xyz, 1e-2f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->NormalizeTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestGetTextureSpaceLightVectors +============ +*/ +void TestGetTextureSpaceLightVectors( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( idVec4 texCoords1[COUNT] ); + ALIGN16( idVec4 texCoords2[COUNT] ); + ALIGN16( int indexes[COUNT*3] ); + ALIGN16( idVec3 lightVectors1[COUNT] ); + ALIGN16( idVec3 lightVectors2[COUNT] ); + idVec3 lightOrigin; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts[i].xyz[j] = srnd.CRandomFloat() * 100.0f; + drawVerts[i].normal[j] = srnd.CRandomFloat(); + drawVerts[i].tangents[0][j] = srnd.CRandomFloat(); + drawVerts[i].tangents[1][j] = srnd.CRandomFloat(); + } + } + + for ( i = 0; i < COUNT; i++ ) { + indexes[i*3+0] = ( i + 0 ) % COUNT; + indexes[i*3+1] = ( i + 1 ) % COUNT; + indexes[i*3+2] = ( i + 2 ) % COUNT; + } + + lightOrigin[0] = srnd.CRandomFloat() * 100.0f; + lightOrigin[1] = srnd.CRandomFloat() * 100.0f; + lightOrigin[2] = srnd.CRandomFloat() * 100.0f; + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CreateTextureSpaceLightVectors( lightVectors1, lightOrigin, drawVerts, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CreateTextureSpaceLightVectors()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CreateTextureSpaceLightVectors( lightVectors2, lightOrigin, drawVerts, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !lightVectors1[i].Compare( lightVectors2[i], 1e-4f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CreateTextureSpaceLightVectors() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestGetSpecularTextureCoords +============ +*/ +void TestGetSpecularTextureCoords( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( idVec4 texCoords1[COUNT] ); + ALIGN16( idVec4 texCoords2[COUNT] ); + ALIGN16( int indexes[COUNT*3] ); + ALIGN16( idVec3 lightVectors1[COUNT] ); + ALIGN16( idVec3 lightVectors2[COUNT] ); + idVec3 lightOrigin, viewOrigin; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + for ( j = 0; j < 3; j++ ) { + drawVerts[i].xyz[j] = srnd.CRandomFloat() * 100.0f; + drawVerts[i].normal[j] = srnd.CRandomFloat(); + drawVerts[i].tangents[0][j] = srnd.CRandomFloat(); + drawVerts[i].tangents[1][j] = srnd.CRandomFloat(); + } + } + + for ( i = 0; i < COUNT; i++ ) { + indexes[i*3+0] = ( i + 0 ) % COUNT; + indexes[i*3+1] = ( i + 1 ) % COUNT; + indexes[i*3+2] = ( i + 2 ) % COUNT; + } + + lightOrigin[0] = srnd.CRandomFloat() * 100.0f; + lightOrigin[1] = srnd.CRandomFloat() * 100.0f; + lightOrigin[2] = srnd.CRandomFloat() * 100.0f; + viewOrigin[0] = srnd.CRandomFloat() * 100.0f; + viewOrigin[1] = srnd.CRandomFloat() * 100.0f; + viewOrigin[2] = srnd.CRandomFloat() * 100.0f; + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CreateSpecularTextureCoords( texCoords1, lightOrigin, viewOrigin, drawVerts, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CreateSpecularTextureCoords()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CreateSpecularTextureCoords( texCoords2, lightOrigin, viewOrigin, drawVerts, COUNT, indexes, COUNT*3 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !texCoords1[i].Compare( texCoords2[i], 1e-2f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CreateSpecularTextureCoords() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestCreateShadowCache +============ +*/ +void TestCreateShadowCache( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( idDrawVert drawVerts[COUNT] ); + ALIGN16( idVec4 vertexCache1[COUNT*2] ); + ALIGN16( idVec4 vertexCache2[COUNT*2] ); + ALIGN16( int originalVertRemap[COUNT] ); + ALIGN16( int vertRemap1[COUNT] ); + ALIGN16( int vertRemap2[COUNT] ); + ALIGN16( idVec3 lightOrigin ); + int numVerts1 = 0, numVerts2 = 0; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + drawVerts[i].xyz[0] = srnd.CRandomFloat() * 100.0f; + drawVerts[i].xyz[1] = srnd.CRandomFloat() * 100.0f; + drawVerts[i].xyz[2] = srnd.CRandomFloat() * 100.0f; + originalVertRemap[i] = ( srnd.CRandomFloat() > 0.0f ) ? -1 : 0; + } + lightOrigin[0] = srnd.CRandomFloat() * 100.0f; + lightOrigin[1] = srnd.CRandomFloat() * 100.0f; + lightOrigin[2] = srnd.CRandomFloat() * 100.0f; + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < COUNT; j++ ) { + vertRemap1[j] = originalVertRemap[j]; + } + StartRecordTime( start ); + numVerts1 =p_generic->CreateShadowCache( vertexCache1, vertRemap1, lightOrigin, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CreateShadowCache()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < COUNT; j++ ) { + vertRemap2[j] = originalVertRemap[j]; + } + StartRecordTime( start ); + numVerts2 = p_simd->CreateShadowCache( vertexCache2, vertRemap2, lightOrigin, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( i < ( numVerts1 / 2 ) ) { + if ( !vertexCache1[i*2+0].Compare( vertexCache2[i*2+0], 1e-2f ) ) { + break; + } + if ( !vertexCache1[i*2+1].Compare( vertexCache2[i*2+1], 1e-2f ) ) { + break; + } + } + if ( vertRemap1[i] != vertRemap2[i] ) { + break; + } + } + + result = ( i >= COUNT && numVerts1 == numVerts2 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CreateShadowCache() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->CreateVertexProgramShadowCache( vertexCache1, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->CreateVertexProgramShadowCache()", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->CreateVertexProgramShadowCache( vertexCache2, drawVerts, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( !vertexCache1[i*2+0].Compare( vertexCache2[i*2+0], 1e-2f ) ) { + break; + } + if ( !vertexCache1[i*2+1].Compare( vertexCache2[i*2+1], 1e-2f ) ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->CreateVertexProgramShadowCache() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestSoundUpSampling +============ +*/ +#define SOUND_UPSAMPLE_EPSILON 1.0f + +void TestSoundUpSampling( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( short pcm[MIXBUFFER_SAMPLES*2] ); + ALIGN16( float ogg0[MIXBUFFER_SAMPLES*2] ); + ALIGN16( float ogg1[MIXBUFFER_SAMPLES*2] ); + ALIGN16( float samples1[MIXBUFFER_SAMPLES*2] ); + ALIGN16( float samples2[MIXBUFFER_SAMPLES*2] ); + float *ogg[2]; + int kHz, numSpeakers; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < MIXBUFFER_SAMPLES*2; i++ ) { + pcm[i] = srnd.RandomInt( (1<<16) ) - (1<<15); + ogg0[i] = srnd.RandomFloat(); + ogg1[i] = srnd.RandomFloat(); + } + + ogg[0] = ogg0; + ogg[1] = ogg1; + + for ( numSpeakers = 1; numSpeakers <= 2; numSpeakers++ ) { + + for ( kHz = 11025; kHz <= 44100; kHz *= 2 ) { + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->UpSamplePCMTo44kHz( samples1, pcm, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( va( "generic->UpSamplePCMTo44kHz( %d, %d )", kHz, numSpeakers ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->UpSamplePCMTo44kHz( samples2, pcm, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*numSpeakers; i++ ) { + if ( idMath::Fabs( samples1[i] - samples2[i] ) > SOUND_UPSAMPLE_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*numSpeakers ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->UpSamplePCMTo44kHz( %d, %d ) %s", kHz, numSpeakers, result ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksSIMD, bestClocksGeneric ); + } + } + + for ( numSpeakers = 1; numSpeakers <= 2; numSpeakers++ ) { + + for ( kHz = 11025; kHz <= 44100; kHz *= 2 ) { + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_generic->UpSampleOGGTo44kHz( samples1, ogg, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( va( "generic->UpSampleOGGTo44kHz( %d, %d )", kHz, numSpeakers ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + p_simd->UpSampleOGGTo44kHz( samples2, ogg, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*numSpeakers; i++ ) { + if ( idMath::Fabs( samples1[i] - samples2[i] ) > SOUND_UPSAMPLE_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->UpSampleOGGTo44kHz( %d, %d ) %s", kHz, numSpeakers, result ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksSIMD, bestClocksGeneric ); + } + } +} + +/* +============ +TestSoundMixing +============ +*/ +#define SOUND_MIX_EPSILON 2.0f + +void TestSoundMixing( void ) { + int i, j; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float origMixBuffer[MIXBUFFER_SAMPLES*6] ); + ALIGN16( float mixBuffer1[MIXBUFFER_SAMPLES*6] ); + ALIGN16( float mixBuffer2[MIXBUFFER_SAMPLES*6] ); + ALIGN16( float samples[MIXBUFFER_SAMPLES*6] ); + ALIGN16( short outSamples1[MIXBUFFER_SAMPLES*6] ); + ALIGN16( short outSamples2[MIXBUFFER_SAMPLES*6] ); + float lastV[6]; + float currentV[6]; + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < 6; i++ ) { + lastV[i] = srnd.CRandomFloat(); + currentV[i] = srnd.CRandomFloat(); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + origMixBuffer[i] = srnd.CRandomFloat(); + samples[i] = srnd.RandomInt( (1<<16) ) - (1<<15); + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer1[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_generic->MixSoundTwoSpeakerMono( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MixSoundTwoSpeakerMono()", MIXBUFFER_SAMPLES, bestClocksGeneric ); + + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer2[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_simd->MixSoundTwoSpeakerMono( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MixSoundTwoSpeakerMono() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer1[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_generic->MixSoundTwoSpeakerStereo( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MixSoundTwoSpeakerStereo()", MIXBUFFER_SAMPLES, bestClocksGeneric ); + + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer2[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_simd->MixSoundTwoSpeakerStereo( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MixSoundTwoSpeakerStereo() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); + + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer1[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_generic->MixSoundSixSpeakerMono( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MixSoundSixSpeakerMono()", MIXBUFFER_SAMPLES, bestClocksGeneric ); + + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer2[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_simd->MixSoundSixSpeakerMono( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MixSoundSixSpeakerMono() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer1[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_generic->MixSoundSixSpeakerStereo( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MixSoundSixSpeakerStereo()", MIXBUFFER_SAMPLES, bestClocksGeneric ); + + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer2[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_simd->MixSoundSixSpeakerStereo( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MixSoundSixSpeakerStereo() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); + + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + origMixBuffer[i] = srnd.RandomInt( (1<<17) ) - (1<<16); + } + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer1[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_generic->MixedSoundToSamples( outSamples1, mixBuffer1, MIXBUFFER_SAMPLES*6 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->MixedSoundToSamples()", MIXBUFFER_SAMPLES, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { + mixBuffer2[j] = origMixBuffer[j]; + } + StartRecordTime( start ); + p_simd->MixedSoundToSamples( outSamples2, mixBuffer2, MIXBUFFER_SAMPLES*6 ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { + if ( outSamples1[i] != outSamples2[i] ) { + break; + } + } + result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->MixedSoundToSamples() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); +} + +/* +============ +TestMath +============ +*/ +void TestMath( void ) { + int i; + TIME_TYPE start, end, bestClocks; + + idLib::common->Printf("====================================\n" ); + + float tst = -1.0f; + float tst2 = 1.0f; + float testvar = 1.0f; + idRandom rnd; + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = fabs( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " fabs( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + int tmp = * ( int * ) &tst; + tmp &= 0x7FFFFFFF; + tst = * ( float * ) &tmp; + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Fabs( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = 10.0f + 100.0f * rnd.RandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = sqrt( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * 0.01f; + tst = 10.0f + 100.0f * rnd.RandomFloat(); + } + PrintClocks( " sqrt( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.RandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Sqrt( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.RandomFloat(); + } + PrintClocks( " idMath::Sqrt( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.RandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Sqrt16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.RandomFloat(); + } + PrintClocks( " idMath::Sqrt16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.RandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Sqrt64( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.RandomFloat(); + } + PrintClocks( " idMath::Sqrt64( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.RandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = tst * idMath::RSqrt( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.RandomFloat(); + } + PrintClocks( " idMath::RSqrt( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Sin( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Sin( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Sin16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Sin16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Cos( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Cos( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Cos16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Cos16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + idMath::SinCos( tst, tst, tst2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::SinCos( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + idMath::SinCos16( tst, tst, tst2 ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( "idMath::SinCos16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Tan( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Tan( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Tan16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Tan16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ASin( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ASin( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ASin16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ASin16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ACos( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ACos( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ACos16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ACos16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ATan( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ATan( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::ATan16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::ATan16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Pow( 2.7f, tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * 0.1f; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Pow( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Pow16( 2.7f, tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * 0.1f; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Pow16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Exp( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * 0.1f; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Exp( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + tst = idMath::Exp16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst * 0.1f; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Exp16( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + tst = fabs( tst ) + 1.0f; + StartRecordTime( start ); + tst = idMath::Log( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Log( tst )", 1, bestClocks ); + + bestClocks = 0; + tst = rnd.CRandomFloat(); + for ( i = 0; i < NUMTESTS; i++ ) { + tst = fabs( tst ) + 1.0f; + StartRecordTime( start ); + tst = idMath::Log16( tst ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + testvar = ( testvar + tst ) * tst; + tst = rnd.CRandomFloat(); + } + PrintClocks( " idMath::Log16( tst )", 1, bestClocks ); + + idLib::common->Printf( "testvar = %f\n", testvar ); + + idMat3 resultMat3; + idQuat fromQuat, toQuat, resultQuat; + idCQuat cq; + idAngles ang; + + fromQuat = idAngles( 30, 45, 0 ).ToQuat(); + toQuat = idAngles( 45, 0, 0 ).ToQuat(); + cq = idAngles( 30, 45, 0 ).ToQuat().ToCQuat(); + ang = idAngles( 30, 40, 50 ); + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + resultMat3 = fromQuat.ToMat3(); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + PrintClocks( " idQuat::ToMat3()", 1, bestClocks ); + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + resultQuat.Slerp( fromQuat, toQuat, 0.3f ); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + PrintClocks( " idQuat::Slerp()", 1, bestClocks ); + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + resultQuat = cq.ToQuat(); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + PrintClocks( " idCQuat::ToQuat()", 1, bestClocks ); + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + resultQuat = ang.ToQuat(); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + PrintClocks( " idAngles::ToQuat()", 1, bestClocks ); + + bestClocks = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + StartRecordTime( start ); + resultMat3 = ang.ToMat3(); + StopRecordTime( end ); + GetBest( start, end, bestClocks ); + } + PrintClocks( " idAngles::ToMat3()", 1, bestClocks ); +} + +/* +============ +TestNegate +============ +*/ + +// this wasn't previously in the test +void TestNegate( void ) { + int i; + TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; + ALIGN16( float fsrc0[COUNT] ); + ALIGN16( float fsrc1[COUNT] ); + ALIGN16( float fsrc2[COUNT] ); + + const char *result; + + idRandom srnd( RANDOM_SEED ); + + for ( i = 0; i < COUNT; i++ ) { + fsrc0[i] = fsrc1[i] = fsrc2[i] = srnd.CRandomFloat() * 10.0f; + //fsrc1[i] = srnd.CRandomFloat() * 10.0f; + } + + idLib::common->Printf("====================================\n" ); + + bestClocksGeneric = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + + memcpy( &fsrc1[0], &fsrc0[0], COUNT * sizeof(float) ); + + StartRecordTime( start ); + p_generic->Negate16( fsrc1, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksGeneric ); + } + PrintClocks( "generic->Negate16( float[] )", COUNT, bestClocksGeneric ); + + bestClocksSIMD = 0; + for ( i = 0; i < NUMTESTS; i++ ) { + + memcpy( &fsrc2[0], &fsrc0[0], COUNT * sizeof(float) ); + + StartRecordTime( start ); + p_simd->Negate16( fsrc2, COUNT ); + StopRecordTime( end ); + GetBest( start, end, bestClocksSIMD ); + } + + for ( i = 0; i < COUNT; i++ ) { + if ( fsrc1[i] != fsrc2[i] ) { + break; + } + } + result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; + PrintClocks( va( " simd->Negate16( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); +} + + +/* +============ +idSIMD::Test_f +============ +*/ +void idSIMD::Test_f( const idCmdArgs &args ) { + +#ifdef _WIN32 + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); +#endif /* _WIN32 */ + + p_simd = processor; + p_generic = generic; + + if ( idStr::Length( args.Argv( 1 ) ) != 0 ) { + cpuid_t cpuid = idLib::sys->GetProcessorId(); + idStr argString = args.Args(); + + argString.Replace( " ", "" ); + + if ( idStr::Icmp( argString, "MMX" ) == 0 ) { + if ( !( cpuid & CPUID_MMX ) ) { + common->Printf( "CPU does not support MMX\n" ); + return; + } + p_simd = new idSIMD_MMX; + } else if ( idStr::Icmp( argString, "3DNow" ) == 0 ) { + if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_3DNOW ) ) { + common->Printf( "CPU does not support MMX & 3DNow\n" ); + return; + } + p_simd = new idSIMD_3DNow; + } else if ( idStr::Icmp( argString, "SSE" ) == 0 ) { + if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) ) { + common->Printf( "CPU does not support MMX & SSE\n" ); + return; + } + p_simd = new idSIMD_SSE; + } else if ( idStr::Icmp( argString, "SSE2" ) == 0 ) { + if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) || !( cpuid & CPUID_SSE2 ) ) { + common->Printf( "CPU does not support MMX & SSE & SSE2\n" ); + return; + } + p_simd = new idSIMD_SSE2; + } else if ( idStr::Icmp( argString, "SSE3" ) == 0 ) { + if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) || !( cpuid & CPUID_SSE2 ) || !( cpuid & CPUID_SSE3 ) ) { + common->Printf( "CPU does not support MMX & SSE & SSE2 & SSE3\n" ); + return; + } + p_simd = new idSIMD_SSE3(); + } else if ( idStr::Icmp( argString, "AltiVec" ) == 0 ) { + if ( !( cpuid & CPUID_ALTIVEC ) ) { + common->Printf( "CPU does not support AltiVec\n" ); + return; + } + p_simd = new idSIMD_AltiVec(); + } else { + common->Printf( "invalid argument, use: MMX, 3DNow, SSE, SSE2, SSE3, AltiVec\n" ); + return; + } + } + + idLib::common->SetRefreshOnPrint( true ); + + idLib::common->Printf( "using %s for SIMD processing\n", p_simd->GetName() ); + + GetBaseClocks(); + + TestMath(); + TestAdd(); + TestSub(); + TestMul(); + TestDiv(); + TestMulAdd(); + TestMulSub(); + TestDot(); + TestCompare(); + TestMinMax(); + TestClamp(); + TestMemcpy(); + TestMemset(); + TestNegate(); + + TestMatXMultiplyVecX(); + TestMatXMultiplyAddVecX(); + TestMatXTransposeMultiplyVecX(); + TestMatXTransposeMultiplyAddVecX(); + TestMatXMultiplyMatX(); + TestMatXTransposeMultiplyMatX(); + TestMatXLowerTriangularSolve(); + TestMatXLowerTriangularSolveTranspose(); + TestMatXLDLTFactor(); + + idLib::common->Printf("====================================\n" ); + + TestBlendJoints(); + TestConvertJointQuatsToJointMats(); + TestConvertJointMatsToJointQuats(); + TestTransformJoints(); + TestUntransformJoints(); + TestTransformVerts(); + TestTracePointCull(); + TestDecalPointCull(); + TestOverlayPointCull(); + TestDeriveTriPlanes(); + TestDeriveTangents(); + TestDeriveUnsmoothedTangents(); + TestNormalizeTangents(); + TestGetTextureSpaceLightVectors(); + TestGetSpecularTextureCoords(); + TestCreateShadowCache(); + + idLib::common->Printf("====================================\n" ); + + TestSoundUpSampling(); + TestSoundMixing(); + + idLib::common->SetRefreshOnPrint( false ); + + if ( p_simd != processor ) { + delete p_simd; + } + p_simd = NULL; + p_generic = NULL; + +#ifdef _WIN32 + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL ); +#endif /* _WIN32 */ +} diff --git a/idlib/math/Simd.h b/idlib/math/Simd.h new file mode 100644 index 000000000..1b1b35008 --- /dev/null +++ b/idlib/math/Simd.h @@ -0,0 +1,195 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_H__ +#define __MATH_SIMD_H__ + +/* +=============================================================================== + + Single Instruction Multiple Data (SIMD) + + For optimal use data should be aligned on a 16 byte boundary. + All idSIMDProcessor routines are thread safe. + +=============================================================================== +*/ + +class idSIMD { +public: + static void Init( void ); + static void InitProcessor( const char *module, bool forceGeneric ); + static void Shutdown( void ); + static void Test_f( const class idCmdArgs &args ); +}; + + +/* +=============================================================================== + + virtual base class for different SIMD processors + +=============================================================================== +*/ + +#ifdef _WIN32 +#define VPCALL __fastcall +#else +#define VPCALL +#endif + +class idVec2; +class idVec3; +class idVec4; +class idVec5; +class idVec6; +class idVecX; +class idMat2; +class idMat3; +class idMat4; +class idMat5; +class idMat6; +class idMatX; +class idPlane; +class idDrawVert; +class idJointQuat; +class idJointMat; +struct dominantTri_s; + +const int MIXBUFFER_SAMPLES = 4096; + +typedef enum { + SPEAKER_LEFT = 0, + SPEAKER_RIGHT, + SPEAKER_CENTER, + SPEAKER_LFE, + SPEAKER_BACKLEFT, + SPEAKER_BACKRIGHT +} speakerLabel; + + +class idSIMDProcessor { +public: + idSIMDProcessor( void ) { cpuid = CPUID_NONE; } + + cpuid_t cpuid; + + virtual const char * VPCALL GetName( void ) const = 0; + + virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ) = 0; + virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ) = 0; + virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ) = 0; + virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ) = 0; + virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ) = 0; + virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ) = 0; + virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ) = 0; + + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ) = 0; + virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) = 0; + virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ) = 0; + + virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ) = 0; + virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; + + virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ) = 0; + virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) = 0; + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) = 0; + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) = 0; + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) = 0; + + virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ) = 0; + virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ) = 0; + virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ) = 0; + + virtual void VPCALL Memcpy( void *dst, const void *src, const int count ) = 0; + virtual void VPCALL Memset( void *dst, const int val, const int count ) = 0; + + // these assume 16 byte aligned and 16 byte padded memory + virtual void VPCALL Zero16( float *dst, const int count ) = 0; + virtual void VPCALL Negate16( float *dst, const int count ) = 0; + virtual void VPCALL Copy16( float *dst, const float *src, const int count ) = 0; + virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ) = 0; + virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ) = 0; + virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ) = 0; + virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ) = 0; + virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ) = 0; + virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ) = 0; + + // idMatX operations + virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; + virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) = 0; + virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) = 0; + virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ) = 0; + virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) = 0; + virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) = 0; + + // rendering + virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) = 0; + virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) = 0; + virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) = 0; + virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) = 0; + virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) = 0; + virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) = 0; + virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; + virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; + virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; + virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; + virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; + virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) = 0; + virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ) = 0; + virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; + virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; + virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) = 0; + virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) = 0; + + // sound mixing + virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ) = 0; + virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) = 0; + virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) = 0; + virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) = 0; + virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) = 0; + virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) = 0; + virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) = 0; +}; + +// pointer to SIMD processor +extern idSIMDProcessor *SIMDProcessor; + +#endif /* !__MATH_SIMD_H__ */ diff --git a/idlib/math/Simd_3DNow.cpp b/idlib/math/Simd_3DNow.cpp new file mode 100644 index 000000000..0a26f93ee --- /dev/null +++ b/idlib/math/Simd_3DNow.cpp @@ -0,0 +1,288 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_MMX.h" +#include "Simd_3DNow.h" + + +//=============================================================== +// +// 3DNow! implementation of idSIMDProcessor +// +//=============================================================== + +#ifdef _WIN32 + +/* +============ +idSIMD_3DNow::GetName +============ +*/ +const char * idSIMD_3DNow::GetName( void ) const { + return "MMX & 3DNow!"; +} + +// Very optimized memcpy() routine for all AMD Athlon and Duron family. +// This code uses any of FOUR different basic copy methods, depending +// on the transfer size. +// NOTE: Since this code uses MOVNTQ (also known as "Non-Temporal MOV" or +// "Streaming Store"), and also uses the software prefetchnta instructions, +// be sure you're running on Athlon/Duron or other recent CPU before calling! + +#define TINY_BLOCK_COPY 64 // upper limit for movsd type copy +// The smallest copy uses the X86 "movsd" instruction, in an optimized +// form which is an "unrolled loop". + +#define IN_CACHE_COPY 64 * 1024 // upper limit for movq/movq copy w/SW prefetch +// Next is a copy that uses the MMX registers to copy 8 bytes at a time, +// also using the "unrolled loop" optimization. This code uses +// the software prefetch instruction to get the data into the cache. + +#define UNCACHED_COPY 197 * 1024 // upper limit for movq/movntq w/SW prefetch +// For larger blocks, which will spill beyond the cache, it's faster to +// use the Streaming Store instruction MOVNTQ. This write instruction +// bypasses the cache and writes straight to main memory. This code also +// uses the software prefetch instruction to pre-read the data. +// USE 64 * 1024 FOR THIS VALUE IF YOU'RE ALWAYS FILLING A "CLEAN CACHE" + +#define BLOCK_PREFETCH_COPY infinity // no limit for movq/movntq w/block prefetch +#define CACHEBLOCK 80h // number of 64-byte blocks (cache lines) for block prefetch +// For the largest size blocks, a special technique called Block Prefetch +// can be used to accelerate the read operations. Block Prefetch reads +// one address per cache line, for a series of cache lines, in a short loop. +// This is faster than using software prefetch. The technique is great for +// getting maximum read bandwidth, especially in DDR memory systems. + +/* +================ +idSIMD_3DNow::Memcpy + + optimized memory copy routine that handles all alignment cases and block sizes efficiently +================ +*/ +void VPCALL idSIMD_3DNow::Memcpy( void *dest, const void *src, const int n ) { + __asm { + + mov ecx, [n] // number of bytes to copy + mov edi, [dest] // destination + mov esi, [src] // source + mov ebx, ecx // keep a copy of count + + cld + cmp ecx, TINY_BLOCK_COPY + jb $memcpy_ic_3 // tiny? skip mmx copy + + cmp ecx, 32*1024 // don't align between 32k-64k because + jbe $memcpy_do_align // it appears to be slower + cmp ecx, 64*1024 + jbe $memcpy_align_done +$memcpy_do_align: + mov ecx, 8 // a trick that's faster than rep movsb... + sub ecx, edi // align destination to qword + and ecx, 111b // get the low bits + sub ebx, ecx // update copy count + neg ecx // set up to jump into the array + add ecx, offset $memcpy_align_done + jmp ecx // jump to array of movsb's + +align 4 + movsb + movsb + movsb + movsb + movsb + movsb + movsb + movsb + +$memcpy_align_done: // destination is dword aligned + mov ecx, ebx // number of bytes left to copy + shr ecx, 6 // get 64-byte block count + jz $memcpy_ic_2 // finish the last few bytes + + cmp ecx, IN_CACHE_COPY/64 // too big 4 cache? use uncached copy + jae $memcpy_uc_test + +// This is small block copy that uses the MMX registers to copy 8 bytes +// at a time. It uses the "unrolled loop" optimization, and also uses +// the software prefetch instruction to get the data into the cache. +align 16 +$memcpy_ic_1: // 64-byte block copies, in-cache copy + + prefetchnta [esi + (200*64/34+192)] // start reading ahead + + movq mm0, [esi+0] // read 64 bits + movq mm1, [esi+8] + movq [edi+0], mm0 // write 64 bits + movq [edi+8], mm1 // note: the normal movq writes the + movq mm2, [esi+16] // data to cache; a cache line will be + movq mm3, [esi+24] // allocated as needed, to store the data + movq [edi+16], mm2 + movq [edi+24], mm3 + movq mm0, [esi+32] + movq mm1, [esi+40] + movq [edi+32], mm0 + movq [edi+40], mm1 + movq mm2, [esi+48] + movq mm3, [esi+56] + movq [edi+48], mm2 + movq [edi+56], mm3 + + add esi, 64 // update source pointer + add edi, 64 // update destination pointer + dec ecx // count down + jnz $memcpy_ic_1 // last 64-byte block? + +$memcpy_ic_2: + mov ecx, ebx // has valid low 6 bits of the byte count +$memcpy_ic_3: + shr ecx, 2 // dword count + and ecx, 1111b // only look at the "remainder" bits + neg ecx // set up to jump into the array + add ecx, offset $memcpy_last_few + jmp ecx // jump to array of movsd's + +$memcpy_uc_test: + cmp ecx, UNCACHED_COPY/64 // big enough? use block prefetch copy + jae $memcpy_bp_1 + +$memcpy_64_test: + or ecx, ecx // tail end of block prefetch will jump here + jz $memcpy_ic_2 // no more 64-byte blocks left + +// For larger blocks, which will spill beyond the cache, it's faster to +// use the Streaming Store instruction MOVNTQ. This write instruction +// bypasses the cache and writes straight to main memory. This code also +// uses the software prefetch instruction to pre-read the data. +align 16 +$memcpy_uc_1: // 64-byte blocks, uncached copy + + prefetchnta [esi + (200*64/34+192)] // start reading ahead + + movq mm0,[esi+0] // read 64 bits + add edi,64 // update destination pointer + movq mm1,[esi+8] + add esi,64 // update source pointer + movq mm2,[esi-48] + movntq [edi-64], mm0 // write 64 bits, bypassing the cache + movq mm0,[esi-40] // note: movntq also prevents the CPU + movntq [edi-56], mm1 // from READING the destination address + movq mm1,[esi-32] // into the cache, only to be over-written + movntq [edi-48], mm2 // so that also helps performance + movq mm2,[esi-24] + movntq [edi-40], mm0 + movq mm0,[esi-16] + movntq [edi-32], mm1 + movq mm1,[esi-8] + movntq [edi-24], mm2 + movntq [edi-16], mm0 + dec ecx + movntq [edi-8], mm1 + jnz $memcpy_uc_1 // last 64-byte block? + + jmp $memcpy_ic_2 // almost done + +// For the largest size blocks, a special technique called Block Prefetch +// can be used to accelerate the read operations. Block Prefetch reads +// one address per cache line, for a series of cache lines, in a short loop. +// This is faster than using software prefetch, in this case. +// The technique is great for getting maximum read bandwidth, +// especially in DDR memory systems. +$memcpy_bp_1: // large blocks, block prefetch copy + + cmp ecx, CACHEBLOCK // big enough to run another prefetch loop? + jl $memcpy_64_test // no, back to regular uncached copy + + mov eax, CACHEBLOCK / 2 // block prefetch loop, unrolled 2X + add esi, CACHEBLOCK * 64 // move to the top of the block +align 16 +$memcpy_bp_2: + mov edx, [esi-64] // grab one address per cache line + mov edx, [esi-128] // grab one address per cache line + sub esi, 128 // go reverse order + dec eax // count down the cache lines + jnz $memcpy_bp_2 // keep grabbing more lines into cache + + mov eax, CACHEBLOCK // now that it's in cache, do the copy +align 16 +$memcpy_bp_3: + movq mm0, [esi ] // read 64 bits + movq mm1, [esi+ 8] + movq mm2, [esi+16] + movq mm3, [esi+24] + movq mm4, [esi+32] + movq mm5, [esi+40] + movq mm6, [esi+48] + movq mm7, [esi+56] + add esi, 64 // update source pointer + movntq [edi ], mm0 // write 64 bits, bypassing cache + movntq [edi+ 8], mm1 // note: movntq also prevents the CPU + movntq [edi+16], mm2 // from READING the destination address + movntq [edi+24], mm3 // into the cache, only to be over-written, + movntq [edi+32], mm4 // so that also helps performance + movntq [edi+40], mm5 + movntq [edi+48], mm6 + movntq [edi+56], mm7 + add edi, 64 // update dest pointer + + dec eax // count down + + jnz $memcpy_bp_3 // keep copying + sub ecx, CACHEBLOCK // update the 64-byte block count + jmp $memcpy_bp_1 // keep processing chunks + +// The smallest copy uses the X86 "movsd" instruction, in an optimized +// form which is an "unrolled loop". Then it handles the last few bytes. +align 4 + movsd + movsd // perform last 1-15 dword copies + movsd + movsd + movsd + movsd + movsd + movsd + movsd + movsd // perform last 1-7 dword copies + movsd + movsd + movsd + movsd + movsd + movsd + +$memcpy_last_few: // dword aligned from before movsd's + mov ecx, ebx // has valid low 2 bits of the byte count + and ecx, 11b // the last few cows must come home + jz $memcpy_final // no more, let's leave + rep movsb // the last 1, 2, or 3 bytes + +$memcpy_final: + emms // clean up the MMX state + sfence // flush the write buffer + mov eax, [dest] // ret value = destination pointer + + } +} + +#endif /* _WIN32 */ diff --git a/idlib/math/Simd_3DNow.h b/idlib/math/Simd_3DNow.h new file mode 100644 index 000000000..e0508b324 --- /dev/null +++ b/idlib/math/Simd_3DNow.h @@ -0,0 +1,41 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_3DNOW_H__ +#define __MATH_SIMD_3DNOW_H__ + +/* +=============================================================================== + + 3DNow! implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_3DNow : public idSIMD_MMX { +#ifdef _WIN32 +public: + virtual const char * VPCALL GetName( void ) const; + + virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); + +#endif +}; + +#endif /* !__MATH_SIMD_3DNOW_H__ */ diff --git a/idlib/math/Simd_AltiVec.cpp b/idlib/math/Simd_AltiVec.cpp new file mode 100644 index 000000000..2936d51e6 --- /dev/null +++ b/idlib/math/Simd_AltiVec.cpp @@ -0,0 +1,11230 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_AltiVec.h" +#include +#include + +#ifdef PPC_INTRINSICS + #include +#endif + +// Doom3 SIMD Library version 0.5 +// Patrick Flanagan (pflanagan@apple.com) +// Sanjay Patel (spatel@apple.com) +// Architecture & Performance Group, Apple Computer + + +//=============================================================== +// +// AltiVec implementation of idSIMDProcessor +// +//=============================================================== + +#if defined(MACOS_X) && defined(__ppc__) + +// Data struct sizes + +#ifndef DRAWVERT_PADDED + // 60 bytes, 15 floats at 4 bytes each + #define DRAWVERT_OFFSET 15 +#else + // 64 bytes, 16 floats + #define DRAWVERT_OFFSET 16 +#endif +// 16 bytes each, 4 floats +#define PLANE_OFFSET 4 +// 16 bytes each, 4 floats +#define IDVEC4_OFFSET 4 + +// Alignment tests +#define IS_16BYTE_ALIGNED( x ) ( ( (unsigned long)&x & 0x0F ) == 0 ) +#define NOT_16BYTE_ALIGNED( x ) ( ( (unsigned long)&x & 0x0F) != 0 ) + +// Aligned storing floats +#define ALIGNED_STORE2( ADDR, V0, V1 ) \ + vec_st( V0, 0, ADDR ); \ + vec_st( V1, 16, ADDR ) + +#define ALIGNED_STORE3( ADDR, V0, V1, V2 ) \ + vec_st( V0, 0, ADDR ); \ + vec_st( V1, 16, ADDR ); \ + vec_st( V2, 32, ADDR ) + +#define ALIGNED_STORE4( ADDR, V0, V1, V2, V3 ) \ + vec_st( V0, 0, ADDR ); \ + vec_st( V1, 16, ADDR ); \ + vec_st( V2, 32, ADDR ); \ + vec_st( V3, 48, ADDR ) + +#define ALIGNED_STORE6( ADDR, V0, V1, V2, V3, V4, V5 ) \ + vec_st( V0, 0, ADDR ); \ + vec_st( V1, 16, ADDR ); \ + vec_st( V2, 32, ADDR ); \ + vec_st( V3, 48, ADDR ); \ + vec_st( V4, 64, ADDR ); \ + vec_st( V5, 80, ADDR ) + +#define ALIGNED_STORE8( ADDR, V0, V1, V2, V3, V4, V5, V6, V7 ) \ + vec_st( V0, 0, ADDR ); \ + vec_st( V1, 16, ADDR ); \ + vec_st( V2, 32, ADDR ); \ + vec_st( V3, 48, ADDR ); \ + vec_st( V4, 64, ADDR ); \ + vec_st( V5, 80, ADDR ); \ + vec_st( V6, 96, ADDR ); \ + vec_st( V7, 112, ADDR ) + +// Unaligned storing floats. These assume that we can trash the input +#define UNALIGNED_STORE1( ADDR, V0 ) { \ + /* use store element */ \ + vector unsigned char ULStoreMacroPerm = vec_lvsr( 0, ADDR ); \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + vec_ste( V0, 0, ADDR ); \ + vec_ste( V0, 4, ADDR ); \ + vec_ste( V0, 8, ADDR ); \ + vec_ste( V0, 12, ADDR ); \ + } + +#define UNALIGNED_STORE2( ADDR, V0, V1 ) { \ + /* load up the values that are there now */ \ + vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ + vector float ULStoreMacro2 = vec_ld( 31, ADDR ); \ + /* generate permute vector and mask */ \ + vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ + vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ + /* right rotate input data */ \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ + /* setup the output vectors */ \ + vector float ULStoreVal1, ULStoreVal2, ULStoreVal3; \ + ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ + ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ + ULStoreVal3 = vec_sel( V1, ULStoreMacro2, ULStoreMacroMask ); \ + /* store results */ \ + vec_st( ULStoreVal1, 0, ADDR ); \ + vec_st( ULStoreVal2, 15, ADDR ); \ + vec_st( ULStoreVal3, 31, ADDR ); } + +#define UNALIGNED_STORE3( ADDR, V0, V1, V2 ) { \ + /* load up the values that are there now */ \ + vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ + vector float ULStoreMacro2 = vec_ld( 47, ADDR ); \ + /* generate permute vector and mask */ \ + vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ + vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ + /* right rotate input data */ \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ + V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ + /* setup the output vectors */ \ + vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4; \ + ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ + ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ + ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ + ULStoreVal4 = vec_sel( V2, ULStoreMacro2, ULStoreMacroMask ); \ + /* store results */ \ + vec_st( ULStoreVal1, 0, ADDR ); \ + vec_st( ULStoreVal2, 15, ADDR ); \ + vec_st( ULStoreVal3, 31, ADDR ); \ + vec_st( ULStoreVal4, 47, ADDR ); } + +#define UNALIGNED_STORE4( ADDR, V0, V1, V2, V3 ) { \ + /* load up the values that are there now */ \ + vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ + vector float ULStoreMacro2 = vec_ld( 63, ADDR ); \ + /* generate permute vector and mask */ \ + vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ + vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ + /* right rotate input data */ \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ + V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ + V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ + /* setup the output vectors */ \ + vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5; \ + ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ + ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ + ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ + ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ + ULStoreVal5 = vec_sel( V3, ULStoreMacro2, ULStoreMacroMask ); \ + /* store results */ \ + vec_st( ULStoreVal1, 0, ADDR ); \ + vec_st( ULStoreVal2, 15, ADDR ); \ + vec_st( ULStoreVal3, 31, ADDR ); \ + vec_st( ULStoreVal4, 47, ADDR ); \ + vec_st( ULStoreVal5, 63, ADDR ); } + +#define UNALIGNED_STORE6( ADDR, V0, V1, V2, V3, V4, V5 ) { \ + /* load up the values that are there now */ \ + vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ + vector float ULStoreMacro2 = vec_ld( 95, ADDR ); \ + /* generate permute vector and mask */ \ + vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ + vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ + /* right rotate input data */ \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ + V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ + V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ + V4 = vec_perm( V4, V4, ULStoreMacroPerm ); \ + V5 = vec_perm( V5, V5, ULStoreMacroPerm ); \ + /* setup the output vectors */ \ + vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5, ULStoreVal6, ULStoreVal7; \ + ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ + ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ + ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ + ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ + ULStoreVal5 = vec_sel( V3, V4, ULStoreMacroMask ); \ + ULStoreVal6 = vec_sel( V4, V5, ULStoreMacroMask ); \ + ULStoreVal7 = vec_sel( V5, ULStoreMacro2, ULStoreMacroMask ); \ + /* store results */ \ + vec_st( ULStoreVal1, 0, ADDR ); \ + vec_st( ULStoreVal2, 15, ADDR ); \ + vec_st( ULStoreVal3, 31, ADDR ); \ + vec_st( ULStoreVal4, 47, ADDR ); \ + vec_st( ULStoreVal5, 63, ADDR ); \ + vec_st( ULStoreVal6, 79, ADDR ); \ + vec_st( ULStoreVal7, 95, ADDR ); } + +#define UNALIGNED_STORE9( ADDR, V0, V1, V2, V3, V4, V5, V6, V7, V8 ) { \ + /* load up the values that are there now */ \ + vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ + vector float ULStoreMacro2 = vec_ld( 143, ADDR ); \ + /* generate permute vector and mask */ \ + vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ + vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ + /* right rotate input data */ \ + V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ + V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ + V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ + V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ + V4 = vec_perm( V4, V4, ULStoreMacroPerm ); \ + V5 = vec_perm( V5, V5, ULStoreMacroPerm ); \ + V6 = vec_perm( V6, V6, ULStoreMacroPerm ); \ + V7 = vec_perm( V7, V7, ULStoreMacroPerm ); \ + V8 = vec_perm( V8, V8, ULStoreMacroPerm ); \ + /* setup the output vectors */ \ + vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5, ULStoreVal6, ULStoreVal7; \ + vector float ULStoreVal8, ULStoreVal9, ULStoreVal10; \ + ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ + ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ + ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ + ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ + ULStoreVal5 = vec_sel( V3, V4, ULStoreMacroMask ); \ + ULStoreVal6 = vec_sel( V4, V5, ULStoreMacroMask ); \ + ULStoreVal7 = vec_sel( V5, V6, ULStoreMacroMask ); \ + ULStoreVal8 = vec_sel( V6, V7, ULStoreMacroMask ); \ + ULStoreVal9 = vec_sel( V7, V8, ULStoreMacroMask ); \ + ULStoreVal10 = vec_sel( V8, ULStoreMacro2, ULStoreMacroMask ); \ + /* store results */ \ + vec_st( ULStoreVal1, 0, ADDR ); \ + vec_st( ULStoreVal2, 15, ADDR ); \ + vec_st( ULStoreVal3, 31, ADDR ); \ + vec_st( ULStoreVal4, 47, ADDR ); \ + vec_st( ULStoreVal5, 63, ADDR ); \ + vec_st( ULStoreVal6, 79, ADDR ); \ + vec_st( ULStoreVal7, 95, ADDR ); \ + vec_st( ULStoreVal8, 111, ADDR ); \ + vec_st( ULStoreVal9, 127, ADDR ); \ + vec_st( ULStoreVal10, 143, ADDR ); } + +/* +============ +idSIMD_AltiVec::GetName +============ +*/ +const char *idSIMD_AltiVec::GetName( void ) const { + return "AltiVec"; +} + +/* + Helper Functions +*/ +#if 0 +// Prints the values of a vector, useful for debugging but +// should never be called in real code +inline void debugPrintVector( vector float v, char *msg ) { + printf("%s -- %vf\n", msg, v ); +} + +inline void debugPrintVector( vector unsigned int v, char *msg ) { + printf("%s -- %vd\n", msg, v ); +} + +inline void debugPrintVector( vector bool int v, char *msg ) { + printf("%s -- %vi\n", msg, v ); +} + +inline void debugPrintVector( vector unsigned char v, char *msg ) { + printf("%s -- %vuc\n", msg, v ); +} + +inline void debugPrintVector( vector unsigned short v, char *msg ) { + printf("%s -- %vs\n", msg, v ); +} +#endif +/* +=============== + Reciprocal + + For each element in vector: + n = 1 / n +=============== +*/ + +// Use Newton-Raphson to calculate reciprocal of a vector +inline vector float Reciprocal( vector float v ) { + //Get the reciprocal estimate + vector float estimate = vec_re( v ); + //One round of Newton-Raphson refinement + return vec_madd( vec_nmsub( estimate, v, (vector float) (1.0) ), estimate, estimate ); +} + +/* +=============== + ReciprocalSquareRoot + + For each element in vector: + n = 1 / sqrt(n) +=============== +*/ +// Reciprocal square root estimate of a vector +inline vector float ReciprocalSquareRoot( vector float v ) { + //Get the square root reciprocal estimate + vector float zero = (vector float)(0); + vector float oneHalf = (vector float)(0.5); + vector float one = (vector float)(1.0); + vector float estimate = vec_rsqrte( vec_max( v, (vector float)(FLT_MIN) ) ); + + //One round of Newton-Raphson refinement + vector float estimateSquared = vec_madd( estimate, estimate, zero ); + vector float halfEstimate = vec_madd( estimate, oneHalf, zero ); + return vec_madd( vec_nmsub( v, estimateSquared, one ), halfEstimate, estimate ); +} + + +/* +=============== + Divide + + For each element in vectors: + n = a / b +=============== +*/ +// Use reciprocal estimate and multiply to divide a vector +inline vector float Divide( vector float a, vector float b ) { + return vec_madd( a, Reciprocal( b ), (vector float)(0) ); +} + +/* +=============== + loadSplatUnalignedScalar + + For each element in vector: + n = s +=============== +*/ +inline vector float loadSplatUnalignedScalar( const float *s ) { + vector unsigned char splatMap = vec_lvsl( 0, s ); + vector float v = vec_ld( 0, s ); + splatMap = (vector unsigned char) vec_splat( (vector float) splatMap, 0 ); + return vec_perm( v, v, splatMap ); +} + +/* +=============== + VectorATan16 + + For each element in vector: + n = idMath::ATan16( x, y ) +=============== +*/ +// calculates arc tangent of a vector with 16 bits of precision, based on atan16 in idMath +inline vector float VectorATan16( vector float x, vector float y ) { + + vector float xDivY = Divide( x, y ); + vector float yDivX = Divide( y, x ); + vector float zeroVector = (vector float)(0); + + vector bool int vecCmp = vec_cmpgt( vec_abs( y ), vec_abs( x ) ); + vector float vecA = vec_sel( yDivX, xDivY, vecCmp ); + vector bool int vecCmp2 = vec_cmplt( vecA, zeroVector ); + vector float vecS = vec_madd( vecA, vecA, (vector float)(0) ); + + // do calculation for S + vector float vecWork1 = vec_madd( (vector float)(0.0028662257f), vecS, (vector float)(-0.0161657367f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.0429096138f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.0752896400f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.1065626393f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.1420889944f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.1999355085f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.3333314528f) ); + vecWork1 = vec_madd( vecWork1, vecS, (vector float)(1) ); + + // get the regular S value + vecS = vec_madd( vecWork1, vecA, (vector float)(0) ); + + // calculate what to return if y > x + vector float negSPlusHalfPI = vec_madd( vecS, (vector float)(-1), (vector float)(0.5f * 3.14159265358979323846f) ); + vector float negSMinusHalfPI = vec_madd( vecS, (vector float)(-1), (vector float)(-0.5f * 3.14159265358979323846f) ); + vector float modRet = vec_sel( negSPlusHalfPI, negSMinusHalfPI, vecCmp2 ); + + return vec_sel( modRet, vecS, vecCmp ); +} + +/* +=============== + VectorSin16 + + For each element in vector: + n = idMath::Sin16( v ) +=============== +*/ +inline vector float VectorSin16( vector float v ) { + vector float zero = (vector float)(0); + +#if 0 + // load up half PI and use it to calculate the rest of the values. This is + // sometimes cheaper than loading them from memory + + vector float halfPI = (vector float) ( 0.5f * 3.14159265358979323846f ); + vector float PI = vec_add( halfPI, halfPI ); + vector float oneandhalfPI = vec_add( PI, halfPI ); + vector float twoPI = vec_add( oneandhalfPI, halfPI ); +#else + vector float halfPI = (vector float) ( 0.5f * 3.14159265358979323846f ); + vector float PI = (vector float)(3.14159265358979323846f); + vector float oneandhalfPI = (vector float)(3.14159265358979323846f + ( 0.5f * 3.14159265358979323846f ) ); + vector float twoPI = (vector float)( 2.0f * 3.14159265358979323846f); +#endif + + vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4; + + vector float vecMod; + vector float vecResult; + + // fix the range if needbe + vecMod = vec_floor( Divide( v, twoPI ) ); + vecResult = vec_nmsub( vecMod, twoPI, v ); + + vector float vecPIminusA = vec_sub( PI, vecResult ); + vector float vecAminus2PI = vec_sub( vecResult, twoPI ); + + vecCmp1 = vec_cmplt( vecResult, PI ); + vecCmp2 = vec_cmpgt( vecResult, halfPI ); + + // these are the ones where a > PI + HALF_PI so set a = a - TWO_PI + vecCmp3 = vec_cmpgt( vecResult, oneandhalfPI ); + + // we also want to set a = PI - a everywhere that !(a < PI) and !(a > PI + HALF_PI) + vecCmp4 = vec_and( vec_xor( vecCmp3, (vector bool int)(1) ), vec_xor( vecCmp1, (vector bool int)(1) ) ); // everywhere that both of those are false + + // these are ones where a < PI and a > HALF_PI so we set a = PI - a + vecCmp1 = vec_and( vecCmp1, vecCmp2 ); + vecCmp1 = vec_or( vecCmp1, vecCmp4 ); + + // put the correct values into place + vecResult = vec_sel( vecResult, vecPIminusA, vecCmp1 ); + vecResult = vec_sel( vecResult, vecAminus2PI, vecCmp3 ); + + // calculate answer + vector float vecASquared = vec_madd( vecResult, vecResult, zero ); + vector float vecEst = vec_madd( (vector float)(-2.39e-08f), vecASquared, (vector float)(2.7526e-06f) ); + vecEst = vec_madd( vecEst, vecASquared, (vector float)(-1.98409e-04f) ); + vecEst = vec_madd( vecEst, vecASquared, (vector float)(8.3333315e-03f) ); + vecEst = vec_madd( vecEst, vecASquared, (vector float)(-1.666666664e-01f) ); + vecEst = vec_madd( vecEst, vecASquared, (vector float)(1.0f) ); + return vec_madd( vecResult, vecEst, zero ); +} + +/* +=============== + vecSplatWithRunTime + + For each element in vector: + n = v(i) +=============== +*/ +// splats an element across a vector using a runtime variable +inline vector float vecSplatWithRunTime( vector float v, int i ) { + vector unsigned char rotate = vec_lvsl( i * sizeof( float ), (int*) 0L ); + v = vec_perm( v, v, rotate ); + return vec_splat( v, 0 ); +} + + +/* +=============== + FastScalarInvSqrt + + n = 1 / sqrt( f ) +=============== +*/ +inline float FastScalarInvSqrt( float f ) { +#ifdef PPC_INTRINSICS + float estimate; + const float kSmallestFloat = FLT_MIN; + + //Calculate a 5 bit starting estimate for the reciprocal sqrt + estimate = __frsqrte ( f + kSmallestFloat ); + + //if you require less precision, you may reduce the number of loop iterations. + // This will do 2 rounds of NR + estimate = estimate + 0.5f * estimate * ( 1.0f - f * estimate * estimate ); + estimate = estimate + 0.5f * estimate * ( 1.0f - f * estimate * estimate ); + return estimate; +#else + return idMath::InvSqrt( f ); +#endif +} + +/* +=============== + FastScalarInvSqrt_x3 + + arg1 = 1 / sqrt( arg1 ) + arg2 = 1 / sqrt( arg2 ) + arg3 = 1 / sqrt( arg3 ) +=============== +*/ +inline void FastScalarInvSqrt_x3( float *arg1, float *arg2, float *arg3 ) { +#ifdef PPC_INTRINSICS + register float estimate1, estimate2, estimate3; + const float kSmallestFloat = FLT_MIN; + + //Calculate a 5 bit starting estimate for the reciprocal sqrt of each + estimate1 = __frsqrte ( *arg1 + kSmallestFloat ); + estimate2 = __frsqrte ( *arg2 + kSmallestFloat ); + estimate3 = __frsqrte ( *arg3 + kSmallestFloat ); + + // two rounds newton-raphson + estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); + estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); + estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); + estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); + estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); + estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); + + *arg1 = estimate1; + *arg2 = estimate2; + *arg3 = estimate3; +#else + *arg1 = idMath::InvSqrt( *arg1 ); + *arg2 = idMath::InvSqrt( *arg2 ); + *arg3 = idMath::InvSqrt( *arg3 ); +#endif +} + +/* +=============== + FastScalarInvSqrt_x6 + + arg1 = 1 / sqrt( arg1 ) + arg2 = 1 / sqrt( arg2 ) + arg3 = 1 / sqrt( arg3 ) + arg4 = 1 / sqrt( arg4 ) + arg5 = 1 / sqrt( arg5 ) + arg6 = 1 / sqrt( arg6 ) + + On a G5, you've got 2 pipeline stages to fill. (2 FPU's with 6 stages each) +=============== +*/ +inline void FastScalarInvSqrt_x6( float *arg1, float *arg2, float *arg3, float *arg4, float *arg5, float *arg6 ) { +#ifdef PPC_INTRINSICS + register float estimate1, estimate2, estimate3, estimate4, estimate5, estimate6; + const float kSmallestFloat = FLT_MIN; + + //Calculate a 5 bit starting estimate for the reciprocal sqrt of each + estimate1 = __frsqrte ( *arg1 + kSmallestFloat ); + estimate2 = __frsqrte ( *arg2 + kSmallestFloat ); + estimate3 = __frsqrte ( *arg3 + kSmallestFloat ); + estimate4 = __frsqrte ( *arg4 + kSmallestFloat ); + estimate5 = __frsqrte ( *arg5 + kSmallestFloat ); + estimate6 = __frsqrte ( *arg6 + kSmallestFloat ); + + // two rounds newton-raphson + estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); + estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); + estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); + estimate4 = estimate4 + 0.5f * estimate4 * ( 1.0f - *arg4 * estimate4 * estimate4 ); + estimate5 = estimate5 + 0.5f * estimate5 * ( 1.0f - *arg5 * estimate5 * estimate5 ); + estimate6 = estimate6 + 0.5f * estimate6 * ( 1.0f - *arg6 * estimate6 * estimate6 ); + + estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); + estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); + estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); + estimate4 = estimate4 + 0.5f * estimate4 * ( 1.0f - *arg4 * estimate4 * estimate4 ); + estimate5 = estimate5 + 0.5f * estimate5 * ( 1.0f - *arg5 * estimate5 * estimate5 ); + estimate6 = estimate6 + 0.5f * estimate6 * ( 1.0f - *arg6 * estimate6 * estimate6 ); + + *arg1 = estimate1; + *arg2 = estimate2; + *arg3 = estimate3; + *arg4 = estimate4; + *arg5 = estimate5; + *arg6 = estimate6; +#else + *arg1 = idMath::InvSqrt( *arg1 ); + *arg2 = idMath::InvSqrt( *arg2 ); + *arg3 = idMath::InvSqrt( *arg3 ); + *arg4 = idMath::InvSqrt( *arg4 ); + *arg5 = idMath::InvSqrt( *arg5 ); + *arg6 = idMath::InvSqrt( *arg6 ); +#endif +} + + +// End Helper Functions + +#ifdef ENABLE_SIMPLE_MATH + +/* +============ +idSIMD_AltiVec::Add + + dst[i] = constant + src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Add( float *dst, const float constant, const float *src, const int count ) { + vector float v0, v1, v2, v3; + vector float v0_low, v0_hi, v1_hi; + vector unsigned char permVec; + vector float constVec; + int i; + + // handle unaligned cases at beginning + for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant + src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do first load + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), (vector unsigned char)(1) ); + v1_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v0_hi, v1_hi, permVec ); + + v2 = vec_add( v0, constVec ); + v3 = vec_add( v1, constVec ); + + // store results + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = constant + src[i]; + } +} + +/* +============ +idSIMD_AltiVec::Add + + dst[i] = src0[i] + src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Add( float *dst, const float *src0, const float *src1, const int count ) { + + register vector float v0, v1, v2, v3, v4, v5; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + + int i; + + //unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src0[i] + src1[i]; + } + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + v4 = vec_add( v0, v1 ); + v5 = vec_add( v2, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] + src1[i]; + } +} + +/* +============ +idSIMD_AltiVec::Sub + + dst[i] = constant - src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Sub( float *dst, const float constant, const float *src, const int count ) { + + register vector float v0, v1, v2, v3; + register vector float v0_low, v0_hi, v1_low, v1_hi; + register vector unsigned char permVec; + register vector float constVec; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant - src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute vector and do first load + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); + v1_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + v2 = vec_sub( constVec, v0 ); + v3 = vec_sub( constVec, v1 ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = constant - src[i]; + } +} + +/* +============ +idSIMD_AltiVec::Sub + + dst[i] = src0[i] - src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Sub( float *dst, const float *src0, const float *src1, const int count ) { + register vector float v0, v1, v2, v3, v4, v5; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src0[i] - src1[i]; + } + + //calculate permute and do first loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + v4 = vec_sub( v0, v1 ); + v5 = vec_sub( v2, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] - src1[i]; + } +} + +/* +============ +idSIMD_AltiVec::Mul + + dst[i] = constant * src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Mul( float *dst, const float constant, const float *src, const int count) { + register vector float v0, v0_low, v0_hi, v1_low, v1_hi, v1, v2, v3; + register vector float constVec; + register vector unsigned char permVec; + vector unsigned char oneCharVector = (vector unsigned char)(1); + register vector float zeroVector = (vector float)(0.0); + int i; + + // handle unaligned data at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = constant * src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); + v1_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + v2 = vec_madd( constVec, v0, zeroVector ); + v3 = vec_madd( constVec, v1, zeroVector ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = constant * src[i]; + } +} + +/* +============ +idSIMD_AltiVec::Mul + + dst[i] = src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Mul( float *dst, const float *src0, const float *src1, const int count ) { + register vector float v0, v1, v2, v3, v4, v5; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + register vector float constVec = (vector float)(0.0); + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] * src1[i]; + } + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + //no such thing as regular multiply so we do + //multiply then add zero + v4 = vec_madd( v0, v1, constVec ); + v5 = vec_madd( v2, v3, constVec ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] * src1[i]; + } +} + +/* +============ +idSIMD_AltiVec::Div + + dst[i] = constant / divisor[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Div( float *dst, const float constant, const float *divisor, const int count ) { + register vector float v0, v1, v2, v3; + register vector float v0_low, v0_hi, v1_low, v1_hi; + register vector unsigned char permVec; + register vector float constVec; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = constant / divisor[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do first loads + permVec = vec_add( vec_lvsl( -1, (int*) &divisor[i] ), oneCharVector ); + v1_hi = vec_ld( 0, &divisor[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &divisor[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &divisor[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + v2 = Divide( constVec, v0 ); + v3 = Divide( constVec, v1 ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = constant / divisor[i]; + } +} + +/* +============ +idSIMD_AltiVec::Div + + dst[i] = src0[i] / src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Div( float *dst, const float *src0, const float *src1, const int count ) { + register vector float v0, v1, v2, v3, v4, v5; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] / src1[i]; + } + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + v4 = Divide( v0, v1 ); + v5 = Divide( v2, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] / src1[i]; + } +} + +/* +============ +idSIMD_AltiVec::MulAdd + + dst[i] += constant * src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::MulAdd( float *dst, const float constant, const float *src, const int count ) { + + register vector float v0, v1, v2, v3, v4, v5; + register vector float constVec; + //src + register vector float v0_low, v0_hi, v2_low, v2_hi; + //permute vectors + register vector unsigned char permVec1; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] += constant * src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + + // at this point, dst is known to be aligned + v1 = vec_ld( 0, &dst[i] ); + v3 = vec_ld( 16, &dst[i] ); + + v4 = vec_madd( constVec, v0, v1 ); + v5 = vec_madd( constVec, v2, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] += constant * src[i]; + } +} + +/* +============ +idSIMD_AltiVec::MulAdd + + dst[i] += src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::MulAdd( float *dst, const float *src0, const float *src1, const int count ) { + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + + int i; + + //unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] += src0[i] * src1[i]; + } + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + // load sources + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + //we know dst is aligned because we handled unaligned cases + //up front + v4 = vec_ld( 0, &dst[i] ); + v5 = vec_ld( 16, &dst[i] ); + + v6 = vec_madd( v0, v1, v4 ); + v7 = vec_madd( v2, v3, v5 ); + + ALIGNED_STORE2( &dst[i], v6, v7 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] += src0[i] * src1[i]; + } +} + +/* +============ +idSIMD_AltiVec::MulSub + + dst[i] -= constant * src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::MulSub( float *dst, const float constant, const float *src, const int count ) { + register vector float v0, v1, v2, v3, v4, v5; + register vector float constVec; + //src + register vector float v0_low, v0_hi, v2_low, v2_hi; + //permute vectors + register vector unsigned char permVec1; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] -= constant * src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + + //we know dst will be aligned here because we already handled the preceeding + //unaligned cases + v1 = vec_ld( 0, &dst[i] ); + v3 = vec_ld( 16, &dst[i] ); + + v4 = vec_nmsub( v0, constVec, v1 ); + v5 = vec_nmsub( v2, constVec, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] -= constant * src[i]; + } +} + +/* +============ +idSIMD_AltiVec::MulSub + + dst[i] -= src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::MulSub( float *dst, const float *src0, const float *src1, const int count ) { + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i; + + //unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] -= src0[i] * src1[i]; + } + + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src0[i] ); + v3_hi = vec_ld( 0, &src1[i] ); + + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + // load sources + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src0[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src1[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src1[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + //we know dst is aligned because we handled unaligned cases + //up front + v4 = vec_ld( 0, &dst[i] ); + v5 = vec_ld( 16, &dst[i] ); + + v6 = vec_nmsub( v0, v1, v4 ); + v7 = vec_nmsub( v2, v3, v5 ); + + ALIGNED_STORE2( &dst[i], v6, v7 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] -= src0[i] * src1[i]; + } +} + +#endif /* ENABLE_SIMPLE_MATH */ + +#ifdef ENABLE_DOT +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant * src[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) { + + register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; + register vector float vecX, vecY, vecZ; + vector float vecX2, vecY2, vecZ2; + const float *addr = src[0].ToFloatPtr(); + float tempVal[4]; + float constVal[4]; + register vector float zeroVector = (vector float)(0.0); + register vector float vecConstX, vecConstY, vecConstZ; + + // permute vectors + register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk + register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); + + register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk + register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); + + register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk + register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); + + int i; + + // for scalar cleanup, if necessary + constVal[0] = constant[0]; + constVal[1] = constant[1]; + constVal[2] = constant[2]; + constVal[3] = 0; + + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + vecLd1 = vec_ld( 0, constant.ToFloatPtr() ); + vecLd2 = vec_ld( 11, constant.ToFloatPtr() ); + vecLd1 = vec_perm( vecLd1, vecLd2, constPerm ); + + + // populate const vectors + vecConstX = vec_splat( vecLd1, 0 ); + vecConstY = vec_splat( vecLd1, 1 ); + vecConstZ = vec_splat( vecLd1, 2 ); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, addr ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant * src[i]; + } + + for ( ; i + 7 < count; i += 8 ) { + float *vecPtr = (float*)( addr + (i*3) ); + vector float v0, v1, v2, v3, v4, v5; + + v0 = vecOld; //vec_ld( 0, vecPtr ); + v1 = vec_ld( 15, vecPtr ); + v2 = vec_ld( 31, vecPtr ); + v3 = vec_ld( 47, vecPtr ); + v4 = vec_ld( 63, vecPtr ); + v5 = vec_ld( 79, vecPtr ); + vecOld = vec_ld( 95, vecPtr ); + + vecLd1 = vec_perm( v0, v1, permVec ); + vecLd2 = vec_perm( v1, v2, permVec ); + vecLd3 = vec_perm( v2, v3, permVec ); + + vecLd4 = vec_perm( v3, v4, permVec ); + vecLd5 = vec_perm( v4, v5, permVec ); + vecLd6 = vec_perm( v5, vecOld, permVec ); + + // permute into X Y Z vectors + vecX = vec_perm( vecLd1, vecLd2, permX1 ); + vecY = vec_perm( vecLd1, vecLd2, permY1 ); + vecZ = vec_perm( vecLd1, vecLd2, permZ1 ); + vecX = vec_perm( vecX, vecLd3, permX2 ); + vecY = vec_perm( vecY, vecLd3, permY2 ); + vecZ = vec_perm( vecZ, vecLd3, permZ2 ); + + vecX2 = vec_perm( vecLd4, vecLd5, permX1 ); + vecY2 = vec_perm( vecLd4, vecLd5, permY1 ); + vecZ2 = vec_perm( vecLd4, vecLd5, permZ1 ); + vecX2 = vec_perm( vecX2, vecLd6, permX2 ); + vecY2 = vec_perm( vecY2, vecLd6, permY2 ); + vecZ2 = vec_perm( vecZ2, vecLd6, permZ2 ); + + // do multiply + vecX = vec_madd( vecX, vecConstX, zeroVector ); + vecY = vec_madd( vecY, vecConstY, vecX ); + vecZ = vec_madd( vecZ, vecConstZ, vecY ); + + vecX2 = vec_madd( vecX2, vecConstX, zeroVector ); + vecY2 = vec_madd( vecY2, vecConstY, vecX2 ); + vecZ2 = vec_madd( vecZ2, vecConstZ, vecY2 ); + + // store out results + ALIGNED_STORE2( &dst[i], vecZ, vecZ2 ); + } + + //cleanup + for ( ; i < count; i++ ) { + // look up whats at the address we want, cast it as float pointer, then + // dereference that pointer + tempVal[0] = *( addr + (i*3) + 0 ); + tempVal[1] = *( addr + (i*3) + 1 ); + tempVal[2] = *( addr + (i*3) + 2 ); + dst[i] = constVal[0] * tempVal[0] + constVal[1] * tempVal[1] + constVal[2] * tempVal[2]; + } +} + + +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant * src[i].Normal() + src[i][3]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { +//#define OPER(X) dst[(X)] = constant * src[(X)].Normal() + src[(X)][3]; + + assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); + + int i; + float constVal[4]; + float srcVal[3]; + float srcI3; + float tempVal; + + vector float vecPlaneLd1, vecPlaneLd2, vecPlaneLd3, vecPlaneLd4; + vector float vecPlaneLd5, vecPlaneLd6, vecPlaneLd7, vecPlaneLd8; + vector float vecX, vecY, vecZ, vecI3; + vector float vecX2, vecY2, vecZ2, vecI32; + vector float vecConstX, vecConstY, vecConstZ; + + constVal[0] = constant[0]; + constVal[1] = constant[1]; + constVal[2] = constant[2]; + constVal[3] = 1; + + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + vector float v0 = vec_ld( 0, constant.ToFloatPtr() ); + vector float v1 = vec_ld( 11, constant.ToFloatPtr() ); + vector float vecConst = vec_perm( v0, v1, constPerm ); + + vecConstX = vec_splat( vecConst, 0 ); + vecConstY = vec_splat( vecConst, 1 ); + vecConstZ = vec_splat( vecConst, 2 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant * src[i].Normal() + src[i][3]; + } + + const float *addr = src[i].ToFloatPtr(); + vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, addr ); + + for ( ; i + 7 < count; i += 8 ) { + float *planePtr = (float*)( addr + (i*PLANE_OFFSET) ); + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + v0 = vecOld; //vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + v2 = vec_ld( 31, planePtr ); + v3 = vec_ld( 47, planePtr ); + v4 = vec_ld( 63, planePtr ); + v5 = vec_ld( 79, planePtr ); + v6 = vec_ld( 95, planePtr ); + v7 = vec_ld( 111, planePtr ); + vecOld = vec_ld( 127, planePtr ); + + vecPlaneLd1 = vec_perm( v0, v1, permVec ); + vecPlaneLd2 = vec_perm( v1, v2, permVec ); + vecPlaneLd3 = vec_perm( v2, v3, permVec ); + vecPlaneLd4 = vec_perm( v3, v4, permVec ); + + vecPlaneLd5 = vec_perm( v4, v5, permVec ); + vecPlaneLd6 = vec_perm( v5, v6, permVec ); + vecPlaneLd7 = vec_perm( v6, v7, permVec ); + vecPlaneLd8 = vec_perm( v7, vecOld, permVec ); + + // permute into X Y Z vectors, since this is square its basically + // a matrix transpose + v0 = vec_mergeh( vecPlaneLd1, vecPlaneLd3 ); + v1 = vec_mergeh( vecPlaneLd2, vecPlaneLd4 ); + v2 = vec_mergel( vecPlaneLd1, vecPlaneLd3 ); + v3 = vec_mergel( vecPlaneLd2, vecPlaneLd4 ); + + vecX = vec_mergeh( v0, v1 ); + vecY = vec_mergel( v0, v1 ); + vecZ = vec_mergeh( v2, v3 ); + vecI3 = vec_mergel( v2, v3 ); + + v4 = vec_mergeh( vecPlaneLd5, vecPlaneLd7 ); + v5 = vec_mergeh( vecPlaneLd6, vecPlaneLd8 ); + v6 = vec_mergel( vecPlaneLd5, vecPlaneLd7 ); + v7 = vec_mergel( vecPlaneLd6, vecPlaneLd8 ); + + vecX2 = vec_mergeh( v4, v5 ); + vecY2 = vec_mergel( v4, v5 ); + vecZ2 = vec_mergeh( v6, v7 ); + vecI32 = vec_mergel( v6, v7 ); + + // do calculation + v6 = vec_madd( vecZ, vecConstZ, vecI3 ); + v5 = vec_madd( vecY, vecConstY, v6 ); + v4 = vec_madd( vecX, vecConstX, v5 ); + + v0 = vec_madd( vecZ2, vecConstZ, vecI32 ); + v1 = vec_madd( vecY2, vecConstY, v0 ); + v2 = vec_madd( vecX2, vecConstX, v1 ); + + // store results + ALIGNED_STORE2( &dst[i], v4, v2 ); + } + + // cleanup + for ( ; i < count; i++ ) { + // populate srcVal with src X Y Z + srcVal[0] = *(addr + (i*PLANE_OFFSET) + 0 ); + srcVal[1] = *(addr + (i*PLANE_OFFSET) + 1 ); + srcVal[2] = *(addr + (i*PLANE_OFFSET) + 2 ); + + // put src[i][3] into srcI3 + srcI3 = *(addr + (i*PLANE_OFFSET) + 3 ); + + tempVal = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; + dst[i] = tempVal + srcI3; + } +} + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant * src[i].xyz; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { +//#define OPER(X) dst[(X)] = constant * src[(X)].xyz; + + // idDrawVert size is 60 bytes + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + int i; + register vector float vecConstX, vecConstY, vecConstZ; + register vector float vecSrcX1, vecSrcY1, vecSrcZ1; + register vector float zeroVector = (vector float)(0.0); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + v0 = vec_ld( 0, constant.ToFloatPtr() ); + v1 = vec_ld( 11, constant.ToFloatPtr() ); + v0 = vec_perm( v0, v1, constPerm ); + + // permute into constant vectors + vecConstX = vec_splat( v0, 0 ); + vecConstY = vec_splat( v0, 1 ); + vecConstZ = vec_splat( v0, 2 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant * src[i].xyz; + } + + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < count ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } + + for ( ; i+3 < count; i += 4 ) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 11, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 11, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 11, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 11, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v2 = vec_perm( v2, v3, vertPerm2 ); + v4 = vec_perm( v4, v5, vertPerm3 ); + v6 = vec_perm( v6, v7, vertPerm4 ); + + // transpose into X Y Z vectors + v1 = vec_mergeh( v0, v4 ); + v3 = vec_mergeh( v2, v6 ); + v5 = vec_mergel( v0, v4 ); + v7 = vec_mergel( v2, v6 ); + + vecSrcX1 = vec_mergeh( v1, v3 ); + vecSrcY1 = vec_mergel( v1, v3 ); + vecSrcZ1 = vec_mergeh( v5, v7 ); + + // now calculate dot product + vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); + vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); + vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); + + // store results + vec_st( vecSrcZ1, 0, &dst[i] ); + } + + for ( ; i < count; i++ ) { + dst[i] = constant * src[i].xyz; + } +} +#else +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant * src[i].xyz; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { +//#define OPER(X) dst[(X)] = constant * src[(X)].xyz; + + // idDrawVert size is 64 bytes + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + int i; + register vector float vecConstX, vecConstY, vecConstZ; + register vector float vecSrcX1, vecSrcY1, vecSrcZ1; + register vector float zeroVector = (vector float)(0.0); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + v0 = vec_ld( 0, constant.ToFloatPtr() ); + v1 = vec_ld( 11, constant.ToFloatPtr() ); + v0 = vec_perm( v0, v1, constPerm ); + + // permute into constant vectors + vecConstX = vec_splat( v0, 0 ); + vecConstY = vec_splat( v0, 1 ); + vecConstZ = vec_splat( v0, 2 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant * src[i].xyz; + } + + for ( ; i+3 < count; i += 4 ) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + + // transpose into X Y Z vectors + v1 = vec_mergeh( v0, v4 ); + v3 = vec_mergeh( v2, v6 ); + v5 = vec_mergel( v0, v4 ); + v7 = vec_mergel( v2, v6 ); + + vecSrcX1 = vec_mergeh( v1, v3 ); + vecSrcY1 = vec_mergel( v1, v3 ); + vecSrcZ1 = vec_mergeh( v5, v7 ); + + // now calculate dot product + vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); + vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); + vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); + + // store results + vec_st( vecSrcZ1, 0, &dst[i] ); + } + + for ( ; i < count; i++ ) { + dst[i] = constant * src[i].xyz; + } +} + +#endif /* DRAWVERT_PADDED */ + +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant.Normal() * src[i] + constant[3]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idVec3 *src, const int count ) { +//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)] + constant[3]; + + register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; + register vector float vecX, vecY, vecZ, vecX2, vecY2, vecZ2; + register vector float zeroVector = (vector float)(0.0); + register vector float vecConstX, vecConstY, vecConstZ; + register vector float vecConst3; + + idVec3 constNormal = constant.Normal(); + float const3 = constant[3]; + + // permute vectors + register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk + register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); + + register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk + register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); + + register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk + register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); + + int i; + + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + vecLd1 = vec_ld( 0, constant.ToFloatPtr() ); + vecLd2 = vec_ld( 15, constant.ToFloatPtr() ); + vecLd1 = vec_perm( vecLd1, vecLd2, constPerm ); + + // populate const vec + vecConstX = vec_splat( vecLd1, 0 ); + vecConstY = vec_splat( vecLd1, 1 ); + vecConstZ = vec_splat( vecLd1, 2 ); + + // put constant to add in vector + vecConst3 = loadSplatUnalignedScalar( &const3 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant.Normal() * src[i] + constant[3]; + } + + const float *addr = src[i].ToFloatPtr(); + vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, addr ); + + for ( ; i+7 < count; i += 8 ) { + float *vecPtr = (float*)( addr + (i*3) ); + vector float v0, v1, v2, v3, v4, v5; + + v0 = vecOld; //vec_ld( 0, vecPtr ); + v1 = vec_ld( 15, vecPtr ); + v2 = vec_ld( 31, vecPtr ); + v3 = vec_ld( 47, vecPtr ); + v4 = vec_ld( 63, vecPtr ); + v5 = vec_ld( 79, vecPtr ); + vecOld = vec_ld( 95, vecPtr ); + + vecLd1 = vec_perm( v0, v1, permVec ); + vecLd2 = vec_perm( v1, v2, permVec ); + vecLd3 = vec_perm( v2, v3, permVec ); + + vecLd4 = vec_perm( v3, v4, permVec ); + vecLd5 = vec_perm( v4, v5, permVec ); + vecLd6 = vec_perm( v5, vecOld, permVec ); + + // permute into X Y Z vectors + vecX = vec_perm( vecLd1, vecLd2, permX1 ); + vecY = vec_perm( vecLd1, vecLd2, permY1 ); + vecZ = vec_perm( vecLd1, vecLd2, permZ1 ); + vecX = vec_perm( vecX, vecLd3, permX2 ); + vecY = vec_perm( vecY, vecLd3, permY2 ); + vecZ = vec_perm( vecZ, vecLd3, permZ2 ); + + vecX2 = vec_perm( vecLd4, vecLd5, permX1 ); + vecY2 = vec_perm( vecLd4, vecLd5, permY1 ); + vecZ2 = vec_perm( vecLd4, vecLd5, permZ1 ); + vecX2 = vec_perm( vecX2, vecLd6, permX2 ); + vecY2 = vec_perm( vecY2, vecLd6, permY2 ); + vecZ2 = vec_perm( vecZ2, vecLd6, permZ2 ); + + // calculate dot product + vecX = vec_madd( vecX, vecConstX, zeroVector ); + vecY = vec_madd( vecY, vecConstY, vecX ); + vecZ = vec_madd( vecZ, vecConstZ, vecY ); + + vecX2 = vec_madd( vecX2, vecConstX, zeroVector ); + vecY2 = vec_madd( vecY2, vecConstY, vecX2 ); + vecZ2 = vec_madd( vecZ2, vecConstZ, vecY2 ); + + // add in constant[3] + vecZ = vec_add( vecZ, vecConst3 ); + vecZ2 = vec_add( vecZ2, vecConst3 ); + + // store out results + ALIGNED_STORE2( &dst[i], vecZ, vecZ2 ); + } + + //cleanup + for ( ; i < count; i++ ) { + dst[i] = constNormal * src[i] + const3; + } +} + +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idPlane *src, const int count ) { +//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].Normal() + constant[3] * src[(X)][3]; + + // check plane size + assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); + + float constVal[4]; + float srcVal[4]; + + int i; + const float *constPtr = constant.ToFloatPtr(); + + register vector float vecX, vecY, vecZ, vecI3; + register vector float vecX2, vecY2, vecZ2, vecI32; + + vector float vecPlaneLd1, vecPlaneLd2, vecPlaneLd3, vecPlaneLd4; + vector float vecPlaneLd5, vecPlaneLd6, vecPlaneLd7, vecPlaneLd8; + register vector float zeroVector = (vector float)(0.0); + register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; + + constVal[0] = *(constPtr); + constVal[1] = *(constPtr+1); + constVal[2] = *(constPtr+2); + constVal[3] = *(constPtr+3); + + // populate const vector + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + vector float v0 = vec_ld( 0, constant.ToFloatPtr() ); + vector float v1 = vec_ld( 15, constant.ToFloatPtr() ); + vector float vecConst = vec_perm( v0, v1, constPerm ); + + vecConstX = vec_splat( vecConst, 0 ); + vecConstY = vec_splat( vecConst, 1 ); + vecConstZ = vec_splat( vecConst, 2 ); + vecConstI3 = vec_splat( vecConst, 3 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; + } + + const float *srcPtr = src[i].ToFloatPtr(); + vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr ), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, srcPtr ); + + for ( ; i+7 < count; i += 8 ) { + float *planePtr = (float*)( srcPtr + (i*PLANE_OFFSET) ); + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + v0 = vecOld; // vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + v2 = vec_ld( 31, planePtr ); + v3 = vec_ld( 47, planePtr ); + v4 = vec_ld( 63, planePtr ); + v5 = vec_ld( 79, planePtr ); + v6 = vec_ld( 95, planePtr ); + v7 = vec_ld( 111, planePtr ); + vecOld = vec_ld( 127, planePtr ); + + vecPlaneLd1 = vec_perm( v0, v1, permVec ); + vecPlaneLd2 = vec_perm( v1, v2, permVec ); + vecPlaneLd3 = vec_perm( v2, v3, permVec ); + vecPlaneLd4 = vec_perm( v3, v4, permVec ); + + vecPlaneLd5 = vec_perm( v4, v5, permVec ); + vecPlaneLd6 = vec_perm( v5, v6, permVec ); + vecPlaneLd7 = vec_perm( v6, v7, permVec ); + vecPlaneLd8 = vec_perm( v7, vecOld, permVec ); + + // permute into X Y Z vectors, since this is square its basically + // a matrix transpose + v0 = vec_mergeh( vecPlaneLd1, vecPlaneLd3 ); + v1 = vec_mergeh( vecPlaneLd2, vecPlaneLd4 ); + v2 = vec_mergel( vecPlaneLd1, vecPlaneLd3 ); + v3 = vec_mergel( vecPlaneLd2, vecPlaneLd4 ); + + vecX = vec_mergeh( v0, v1 ); + vecY = vec_mergel( v0, v1 ); + vecZ = vec_mergeh( v2, v3 ); + vecI3 = vec_mergel( v2, v3 ); + + v4 = vec_mergeh( vecPlaneLd5, vecPlaneLd7 ); + v5 = vec_mergeh( vecPlaneLd6, vecPlaneLd8 ); + v6 = vec_mergel( vecPlaneLd5, vecPlaneLd7 ); + v7 = vec_mergel( vecPlaneLd6, vecPlaneLd8 ); + + vecX2 = vec_mergeh( v4, v5 ); + vecY2 = vec_mergel( v4, v5 ); + vecZ2 = vec_mergeh( v6, v7 ); + vecI32 = vec_mergel( v6, v7 ); + + // do calculation + v4 = vec_madd( vecConstX, vecX, zeroVector ); + v5 = vec_madd( vecConstY, vecY, v4 ); + v6 = vec_madd( vecConstZ, vecZ, v5 ); + v7 = vec_madd( vecConstI3, vecI3, v6 ); + + v0 = vec_madd( vecConstX, vecX2, zeroVector ); + v1 = vec_madd( vecConstY, vecY2, v0 ); + v2 = vec_madd( vecConstZ, vecZ2, v1 ); + v3 = vec_madd( vecConstI3, vecI32, v2 ); + + //store result + ALIGNED_STORE2( &dst[i], v7, v3 ); + } + + // cleanup + for ( ; i < count; i++ ) { + //dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; + srcVal[0] = *(srcPtr + (i*PLANE_OFFSET) + 0 ); + srcVal[1] = *(srcPtr + (i*PLANE_OFFSET) + 1 ); + srcVal[2] = *(srcPtr + (i*PLANE_OFFSET) + 2 ); + srcVal[3] = *(srcPtr + (i*PLANE_OFFSET) + 3 ); + dst[i] = srcVal[0] * constVal[0] + srcVal[1] * constVal[1] + srcVal[2] * constVal[2] + constVal[3] * srcVal[3]; + } +} + + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant.Normal() * src[i].xyz + constant[3]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { +//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].xyz + constant[3]; + + // idDrawVert size is 60 bytes + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); + + int i; + const float *constPtr = constant.ToFloatPtr(); + const float *srcPtr = src[0].xyz.ToFloatPtr(); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; + register vector float vecSrcX1, vecSrcY1, vecSrcZ1; + register vector float vecDest1; + register vector float zeroVector = (vector float)(0.0); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + float constVal[4]; + float srcVal[3]; + + constVal[0] = *(constPtr+0); + constVal[1] = *(constPtr+1); + constVal[2] = *(constPtr+2); + constVal[3] = *(constPtr+3); + + // populate const vec + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + v0 = vec_ld( 0, constant.ToFloatPtr() ); + v1 = vec_ld( 15, constant.ToFloatPtr() ); + v0 = vec_perm( v0, v1, constPerm ); + + vecConstX = vec_splat( v0, 0 ); + vecConstY = vec_splat( v0, 1 ); + vecConstZ = vec_splat( v0, 2 ); + vecConstI3 = vec_splat( v0, 3 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant.Normal() * src[i].xyz + constant[3]; + } + + // every fourth one will have the same alignment, so can store these. Make sure we + // have enough so we don't run off the end of the array + if ( i+3 < count ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } + + for ( ; i+3 < count; i+=4 ) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 11, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 11, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 11, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 11, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v2 = vec_perm( v2, v3, vertPerm2 ); + v4 = vec_perm( v4, v5, vertPerm3 ); + v6 = vec_perm( v6, v7, vertPerm4 ); + + // transpose into X Y Z vectors + v1 = vec_mergeh( v0, v4 ); + v3 = vec_mergeh( v2, v6 ); + v5 = vec_mergel( v0, v4 ); + v7 = vec_mergel( v2, v6 ); + + vecSrcX1 = vec_mergeh( v1, v3 ); + vecSrcY1 = vec_mergel( v1, v3 ); + vecSrcZ1 = vec_mergeh( v5, v7 ); + + // now calculate dot product + vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); + vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); + vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); + vecDest1 = vec_add( vecSrcZ1, vecConstI3 ); + + // store results + vec_st( vecDest1, 0, &dst[i] ); + } + + // cleanup + for ( ; i < count; i++ ) { + srcVal[0] = *(srcPtr + (i*DRAWVERT_OFFSET) + 0 ); + srcVal[1] = *(srcPtr + (i*DRAWVERT_OFFSET) + 1 ); + srcVal[2] = *(srcPtr + (i*DRAWVERT_OFFSET) + 2 ); + // dst[i] = constant.Normal() * src[i].xyz + constant[3]; + + dst[i] = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; + dst[i] += constVal[3]; + } +} +#else +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = constant.Normal() * src[i].xyz + constant[3]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { +//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].xyz + constant[3]; + + // idDrawVert size is 60 bytes + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); + + int i; + const float *constPtr = constant.ToFloatPtr(); + const float *srcPtr = src[0].xyz.ToFloatPtr(); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; + register vector float vecSrcX1, vecSrcY1, vecSrcZ1; + register vector float vecDest1; + register vector float zeroVector = (vector float)(0.0); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + float constVal[4]; + float srcVal[3]; + + constVal[0] = *(constPtr+0); + constVal[1] = *(constPtr+1); + constVal[2] = *(constPtr+2); + constVal[3] = *(constPtr+3); + + // populate const vec + vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); + v0 = vec_ld( 0, constant.ToFloatPtr() ); + v1 = vec_ld( 15, constant.ToFloatPtr() ); + v0 = vec_perm( v0, v1, constPerm ); + + vecConstX = vec_splat( v0, 0 ); + vecConstY = vec_splat( v0, 1 ); + vecConstZ = vec_splat( v0, 2 ); + vecConstI3 = vec_splat( v0, 3 ); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = constant.Normal() * src[i].xyz + constant[3]; + } + + for ( ; i+3 < count; i+=4 ) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + + // transpose into X Y Z vectors + v1 = vec_mergeh( v0, v4 ); + v3 = vec_mergeh( v2, v6 ); + v5 = vec_mergel( v0, v4 ); + v7 = vec_mergel( v2, v6 ); + + vecSrcX1 = vec_mergeh( v1, v3 ); + vecSrcY1 = vec_mergel( v1, v3 ); + vecSrcZ1 = vec_mergeh( v5, v7 ); + + // now calculate dot product + vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); + vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); + vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); + vecDest1 = vec_add( vecSrcZ1, vecConstI3 ); + + // store results + vec_st( vecDest1, 0, &dst[i] ); + } + + // cleanup + for ( ; i < count; i++ ) { + srcVal[0] = *(srcPtr + (i*DRAWVERT_OFFSET) + 0 ); + srcVal[1] = *(srcPtr + (i*DRAWVERT_OFFSET) + 1 ); + srcVal[2] = *(srcPtr + (i*DRAWVERT_OFFSET) + 2 ); + // dst[i] = constant.Normal() * src[i].xyz + constant[3]; + + dst[i] = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; + dst[i] += constVal[3]; + } +} + +#endif /* DRAWVERT_PADDED */ + +/* +============ +idSIMD_AltiVec::Dot + + dst[i] = src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) { +//#define OPER(X) dst[(X)] = src0[(X)] * src1[(X)]; + + int i; + float src0Val[3]; + float src1Val[3]; + + register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; + vector float vecLd7, vecLd8, vecLd9, vecLd10, vecLd11, vecLd12; + register vector float vecX0, vecY0, vecZ0, vecX1, vecY1, vecZ1; + register vector float vecX02, vecY02, vecZ02, vecX12, vecY12, vecZ12; + register vector float zeroVector = (vector float)(0.0); + // permute vectors + register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk + register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); + register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk + register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); + register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk + register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); + + // handle unaligned case at beginning + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src0[i] * src1[i]; + } + + const float *src0Ptr = src0[i].ToFloatPtr(); + const float *src1Ptr = src1[i].ToFloatPtr(); + vector unsigned char permVec1 = vec_add( vec_lvsl( -1, src0Ptr ), (vector unsigned char)(1) ); + vector unsigned char permVec2 = vec_add( vec_lvsl( -1, src1Ptr ), (vector unsigned char)(1) ); + vector float vecOld0 = vec_ld( 0, src0Ptr ); + vector float vecOld1 = vec_ld( 0, src1Ptr ); + + for ( i = 0; i+7 < count; i += 8 ) { + float *s0Ptr = (float*)( src0Ptr + (i*3) ); + float *s1Ptr = (float*)( src1Ptr + (i*3) ); + + vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; + v0 = vecOld0; + v1 = vec_ld( 15, s0Ptr ); + v2 = vec_ld( 31, s0Ptr ); + v3 = vec_ld( 47, s0Ptr ); + v4 = vec_ld( 63, s0Ptr ); + v5 = vec_ld( 79, s0Ptr ); + vecOld0 = vec_ld( 95, s0Ptr ); + + v6 = vecOld1; + v7 = vec_ld( 15, s1Ptr ); + v8 = vec_ld( 31, s1Ptr ); + v9 = vec_ld( 47, s1Ptr ); + v10 = vec_ld( 63, s1Ptr ); + v11 = vec_ld( 79, s1Ptr ); + vecOld1 = vec_ld( 95, s1Ptr ); + + vecLd1 = vec_perm( v0, v1, permVec1 ); + vecLd2 = vec_perm( v1, v2, permVec1 ); + vecLd3 = vec_perm( v2, v3, permVec1 ); + vecLd4 = vec_perm( v3, v4, permVec1 ); + vecLd5 = vec_perm( v4, v5, permVec1 ); + vecLd6 = vec_perm( v5, vecOld0, permVec1 ); + + vecLd7 = vec_perm( v6, v7, permVec2 ); + vecLd8 = vec_perm( v7, v8, permVec2 ); + vecLd9 = vec_perm( v8, v9, permVec2 ); + vecLd10 = vec_perm( v9, v10, permVec2 ); + vecLd11 = vec_perm( v10, v11, permVec2 ); + vecLd12 = vec_perm( v11, vecOld1, permVec2 ); + + // permute into X Y Z vectors + vecX0 = vec_perm( vecLd1, vecLd2, permX1 ); + vecY0 = vec_perm( vecLd1, vecLd2, permY1 ); + vecZ0 = vec_perm( vecLd1, vecLd2, permZ1 ); + vecX0 = vec_perm( vecX0, vecLd3, permX2 ); + vecY0 = vec_perm( vecY0, vecLd3, permY2 ); + vecZ0 = vec_perm( vecZ0, vecLd3, permZ2 ); + + vecX02 = vec_perm( vecLd4, vecLd5, permX1 ); + vecY02 = vec_perm( vecLd4, vecLd5, permY1 ); + vecZ02 = vec_perm( vecLd4, vecLd5, permZ1 ); + vecX02 = vec_perm( vecX02, vecLd6, permX2 ); + vecY02 = vec_perm( vecY02, vecLd6, permY2 ); + vecZ02 = vec_perm( vecZ02, vecLd6, permZ2 ); + + vecX1 = vec_perm( vecLd7, vecLd8, permX1 ); + vecY1 = vec_perm( vecLd7, vecLd8, permY1 ); + vecZ1 = vec_perm( vecLd7, vecLd8, permZ1 ); + vecX1 = vec_perm( vecX1, vecLd9, permX2 ); + vecY1 = vec_perm( vecY1, vecLd9, permY2 ); + vecZ1 = vec_perm( vecZ1, vecLd9, permZ2 ); + + vecX12 = vec_perm( vecLd10, vecLd11, permX1 ); + vecY12 = vec_perm( vecLd10, vecLd11, permY1 ); + vecZ12 = vec_perm( vecLd10, vecLd11, permZ1 ); + vecX12 = vec_perm( vecX12, vecLd12, permX2 ); + vecY12 = vec_perm( vecY12, vecLd12, permY2 ); + vecZ12 = vec_perm( vecZ12, vecLd12, permZ2 ); + + // do multiply + vecX0 = vec_madd( vecX0, vecX1, zeroVector ); + vecY0 = vec_madd( vecY0, vecY1, vecX0 ); + vecZ0 = vec_madd( vecZ0, vecZ1, vecY0 ); + vecX02 = vec_madd( vecX02, vecX12, zeroVector ); + vecY02 = vec_madd( vecY02, vecY12, vecX02 ); + vecZ02 = vec_madd( vecZ02, vecZ12, vecY02 ); + + // store out results + ALIGNED_STORE2( &dst[i], vecZ0, vecZ02 ); + } + + // cleanup + for ( ; i < count; i++ ) { + // dst[i] = src0[i] * src1[i]; + src0Val[0] = *( src0Ptr + (i*3) + 0 ); + src0Val[1] = *( src0Ptr + (i*3) + 1 ); + src0Val[2] = *( src0Ptr + (i*3) + 2 ); + + src1Val[0] = *( src1Ptr + (i*3) + 0 ); + src1Val[1] = *( src1Ptr + (i*3) + 1 ); + src1Val[2] = *( src1Ptr + (i*3) + 2 ); + + dst[i] = src0Val[0] * src1Val[0] + src0Val[1] * src1Val[1] + src0Val[2] * src1Val[2]; + } +} + +/* +============ +idSIMD_AltiVec::Dot + + dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2] + ... +============ +*/ +void VPCALL idSIMD_AltiVec::Dot( float &dot, const float *src1, const float *src2, const int count ) { + dot = 0.0f; + + register vector float v0, v1, v2, v3; + register vector float zeroVector; + register vector float runningTotal1, runningTotal2; + //src0 + register vector float v0_low, v0_hi, v2_low, v2_hi; + //src1 + register vector float v1_low, v1_hi, v3_low, v3_hi; + //permute vectors + register vector unsigned char permVec1, permVec2; + vector unsigned char oneCharVector = (vector unsigned char)(1); + + int i = 0; + + runningTotal1 = (vector float)(0.0); + runningTotal2 = (vector float)(0.0); + zeroVector = (vector float)(0.0); + + if ( count >= 8 ) { + //calculate permute and do loads + permVec1 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); + permVec2 = vec_add( vec_lvsl( -1, (int*) &src2[i] ), oneCharVector ); + v2_hi = vec_ld( 0, &src1[i] ); + v3_hi = vec_ld( 0, &src2[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load sources + v0_low = v2_hi; + v0_hi = vec_ld( 15, &src1[i] ); + v2_low = v0_hi; + v2_hi = vec_ld( 31, &src1[i] ); + + v1_low = v3_hi; + v1_hi = vec_ld( 15, &src2[i] ); + v3_low = v1_hi; + v3_hi = vec_ld( 31, &src2[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec1 ); + v1 = vec_perm( v1_low, v1_hi, permVec2 ); + v2 = vec_perm( v2_low, v2_hi, permVec1 ); + v3 = vec_perm( v3_low, v3_hi, permVec2 ); + + //multiply together and keep running sum + runningTotal1 = vec_madd( v0, v1, runningTotal1 ); + runningTotal2 = vec_madd( v2, v3, runningTotal2 ); + } + + runningTotal1 = vec_add( runningTotal1, runningTotal2 ); + + // sum accross vector + v0 = vec_add( runningTotal1, vec_sld( runningTotal1, runningTotal1, 8 ) ); + v1 = vec_add( v0, vec_sld( v0, v0, 4 ) ); + runningTotal1 = vec_splat( v1, 0 ); + vec_ste( runningTotal1, 0, &dot ); + } + + //handle cleanup. when profiling the game, we found that most of the counts to this function were small, so it + // spends a lot of time in this scalar code. It's already really really fast (eg 1 TB tick) for scalar code for + // counts less than 50, so not much point in trying to get vector code in on the action + for ( ; i < count ; i++ ) { + dot += src1[i] * src2[i]; + } + +} +#endif /* ENABLE_DOT */ + +#ifdef ENABLE_COMPARES + +/* +============ +idSIMD_AltiVec::CmpGT + + dst[i] = src0[i] > constant; +============ +*/ + +void VPCALL idSIMD_AltiVec::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] = src0[(X)] > constant; + + register vector float v0, v1, v2, v3; + register vector bool int vr1, vr2, vr3, vr4; + register vector bool short vs1, vs2; + register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; + register vector unsigned char vc1; + register vector bool char vbc1; + register vector float constVec; + register vector unsigned char oneVector = (vector unsigned char)(1); + register vector unsigned char permVec; + int i; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] > constant; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + v3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + // load values + v0_low = v3_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src0[i] ); + v2_low = v1_hi; + v2_hi = vec_ld( 47, &src0[i] ); + v3_low = v2_hi; + v3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + v2 = vec_perm( v2_low, v2_hi, permVec ); + v3 = vec_perm( v3_low, v3_hi, permVec ); + + //do comparison + vr1 = vec_cmpgt( v0, constVec ); + vr2 = vec_cmpgt( v1, constVec ); + vr3 = vec_cmpgt( v2, constVec ); + vr4 = vec_cmpgt( v3, constVec ); + + // pack results into shorts + vs1 = vec_pack(vr1, vr2); + vs2 = vec_pack(vr3, vr4); + + // pack results into byte + vbc1 = vec_pack(vs1, vs2); + + //AND with 1 to get true=1 not true=255 + vc1 = vec_and( vbc1, oneVector ); + + //store results + vec_st( vc1, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] > constant; + } +} + + +/* +============ +idSIMD_AltiVec::CmpGT + + dst[i] |= ( src0[i] > constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] |= ( src0[(X)] > constant ) << bitNum; + + // Temp vector registers + register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; + register vector bool short vtbs0, vtbs1; + register vector bool char vtbc0; + register vector unsigned char vtuc0; + register vector unsigned char permVec, permVec2; + + // dest vectors + register vector unsigned char vd; + // bitNum vectors + register vector unsigned char bitNumVec; + // src0 vectors + register vector float vs0, vs1, vs2, vs3; + register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; + // constant vector + register vector float constVec; + // all one's + register vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] |= ( src0[i] > constant ) << bitNum; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //bitNum is unaligned. + permVec2 = vec_lvsl( 0, &bitNum ); + vtuc0 = vec_ld( 0, &bitNum ); + bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); + bitNumVec = vec_splat( bitNumVec, 0 ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + vs3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + //load sources (floats) + vs0_low = vs3_hi; + vs0_hi = vec_ld( 15, &src0[i] ); + vs1_low = vs0_hi; + vs1_hi = vec_ld( 31, &src0[i] ); + vs2_low = vs1_hi; + vs2_hi = vec_ld( 47, &src0[i] ); + vs3_low = vs2_hi; + vs3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + vs0 = vec_perm( vs0_low, vs0_hi, permVec ); + vs1 = vec_perm( vs1_low, vs1_hi, permVec ); + vs2 = vec_perm( vs2_low, vs2_hi, permVec ); + vs3 = vec_perm( vs3_low, vs3_hi, permVec ); + + //load dest (bytes) as unsigned char + vd = vec_ld( 0, &dst[i] ); + + // do comparison and get bool int result + vtbi0 = vec_cmpgt( vs0, constVec ); + vtbi1 = vec_cmpgt( vs1, constVec ); + vtbi2 = vec_cmpgt( vs2, constVec ); + vtbi3 = vec_cmpgt( vs3, constVec ); + + // pack results into shorts + vtbs0 = vec_pack(vtbi0, vtbi1); + vtbs1 = vec_pack(vtbi2, vtbi3); + + // pack results into byte + vtbc0 = vec_pack(vtbs0, vtbs1); + + //and with 1 to get true=1 instead of true=255 + vtuc0 = vec_and(vtbc0, oneVector); + vtuc0 = vec_sl(vtuc0, bitNumVec ); + + //or with original + vd = vec_or( vd, vtuc0 ); + + vec_st( vd, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] |= ( src0[i] > constant ) << bitNum; + } +} + +/* +============ +idSIMD_AltiVec::CmpGE + + dst[i] = src0[i] >= constant; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { + + register vector float v0, v1, v2, v3; + register vector bool int vr1, vr2, vr3, vr4; + register vector bool short vs1, vs2; + register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; + register vector unsigned char vc1; + register vector bool char vbc1; + register vector float constVec; + register vector unsigned char oneVector = (vector unsigned char)(1); + register vector unsigned char permVec; + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] >= constant; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + v3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + // load values + v0_low = v3_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src0[i] ); + v2_low = v1_hi; + v2_hi = vec_ld( 47, &src0[i] ); + v3_low = v2_hi; + v3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + v2 = vec_perm( v2_low, v2_hi, permVec ); + v3 = vec_perm( v3_low, v3_hi, permVec ); + + //do comparison + vr1 = vec_cmpge( v0, constVec ); + vr2 = vec_cmpge( v1, constVec ); + vr3 = vec_cmpge( v2, constVec ); + vr4 = vec_cmpge( v3, constVec ); + + // pack results into shorts + vs1 = vec_pack(vr1, vr2); + vs2 = vec_pack(vr3, vr4); + + // pack results into byte + vbc1 = vec_pack(vs1, vs2); + + //AND with 1 to get true=1 not true=255 + vc1 = vec_and( vbc1, oneVector ); + + //store results + vec_st( vc1, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] >= constant; + } +} + +/* +============ +idSIMD_AltiVec::CmpGE + + dst[i] |= ( src0[i] >= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; + register vector bool short vtbs0, vtbs1; + register vector bool char vtbc0; + register vector unsigned char vtuc0; + register vector unsigned char permVec, permVec2; + + // dest vectors + register vector unsigned char vd; + // bitNum vectors + register vector unsigned char bitNumVec; + // src0 vectors + register vector float vs0, vs1, vs2, vs3; + register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; + // constant vector + register vector float constVec; + // all one's + register vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] |= ( src0[i] >= constant ) << bitNum; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //bitNum is unaligned. + permVec2 = vec_lvsl( 0, &bitNum ); + vtuc0 = vec_ld( 0, &bitNum ); + bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); + bitNumVec = vec_splat( bitNumVec, 0 ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + vs3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + //load sources (floats) + vs0_low = vs3_hi; + vs0_hi = vec_ld( 15, &src0[i] ); + vs1_low = vs0_hi; + vs1_hi = vec_ld( 31, &src0[i] ); + vs2_low = vs1_hi; + vs2_hi = vec_ld( 47, &src0[i] ); + vs3_low = vs2_hi; + vs3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + vs0 = vec_perm( vs0_low, vs0_hi, permVec ); + vs1 = vec_perm( vs1_low, vs1_hi, permVec ); + vs2 = vec_perm( vs2_low, vs2_hi, permVec ); + vs3 = vec_perm( vs3_low, vs3_hi, permVec ); + + //load dest (bytes) as unsigned char + vd = vec_ld( 0, &dst[i] ); + + // do comparison and get bool int result + vtbi0 = vec_cmpge( vs0, constVec ); + vtbi1 = vec_cmpge( vs1, constVec ); + vtbi2 = vec_cmpge( vs2, constVec ); + vtbi3 = vec_cmpge( vs3, constVec ); + + // pack results into shorts + vtbs0 = vec_pack(vtbi0, vtbi1); + vtbs1 = vec_pack(vtbi2, vtbi3); + + // pack results into byte + vtbc0 = vec_pack(vtbs0, vtbs1); + + //and with 1L to get true=1 instead of true=255 + vtuc0 = vec_and(vtbc0, oneVector); + vtuc0 = vec_sl(vtuc0, bitNumVec ); + + //or with original + vd = vec_or( vd, vtuc0 ); + + vec_st( vd, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] |= ( src0[i] >= constant ) << bitNum; + } +} + + +/* +============ +idSIMD_AltiVec::CmpLT + + dst[i] = src0[i] < constant; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] = src0[(X)] < constant; + register vector float v0, v1, v2, v3; + register vector bool int vr1, vr2, vr3, vr4; + register vector bool short vs1, vs2; + register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; + register vector unsigned char vc1; + register vector bool char vbc1; + register vector float constVec; + register vector unsigned char oneVector = (vector unsigned char)(1); + register vector unsigned char permVec; + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] < constant; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + v3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + // load values + v0_low = v3_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src0[i] ); + v2_low = v1_hi; + v2_hi = vec_ld( 47, &src0[i] ); + v3_low = v2_hi; + v3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + v2 = vec_perm( v2_low, v2_hi, permVec ); + v3 = vec_perm( v3_low, v3_hi, permVec ); + + //do comparison + vr1 = vec_cmplt( v0, constVec ); + vr2 = vec_cmplt( v1, constVec ); + vr3 = vec_cmplt( v2, constVec ); + vr4 = vec_cmplt( v3, constVec ); + + // pack results into shorts + vs1 = vec_pack(vr1, vr2); + vs2 = vec_pack(vr3, vr4); + + // pack results into byte + vbc1 = vec_pack(vs1, vs2); + + //AND with 1 to get true=1 not true=255 + vc1 = vec_and( vbc1, oneVector ); + + //store results + vec_st( vc1, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] < constant; + } +} + +/* +============ +idSIMD_AltiVec::CmpLT + + dst[i] |= ( src0[i] < constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] |= ( src0[(X)] < constant ) << bitNum; + register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; + register vector bool short vtbs0, vtbs1; + register vector bool char vtbc0; + register vector unsigned char vtuc0; + register vector unsigned char permVec, permVec2; + + // dest vectors + register vector unsigned char vd; + // bitNum vectors + register vector unsigned char bitNumVec; + // src0 vectors + register vector float vs0, vs1, vs2, vs3; + register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; + // constant vector + register vector float constVec; + // all one's + register vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] |= ( src0[i] < constant ) << bitNum; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //bitNum is unaligned. + permVec2 = vec_lvsl( 0, &bitNum ); + vtuc0 = vec_ld( 0, &bitNum ); + bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); + bitNumVec = vec_splat( bitNumVec, 0 ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + vs3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + //load sources (floats) + vs0_low = vs3_hi; + vs0_hi = vec_ld( 15, &src0[i] ); + vs1_low = vs0_hi; + vs1_hi = vec_ld( 31, &src0[i] ); + vs2_low = vs1_hi; + vs2_hi = vec_ld( 47, &src0[i] ); + vs3_low = vs2_hi; + vs3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + vs0 = vec_perm( vs0_low, vs0_hi, permVec ); + vs1 = vec_perm( vs1_low, vs1_hi, permVec ); + vs2 = vec_perm( vs2_low, vs2_hi, permVec ); + vs3 = vec_perm( vs3_low, vs3_hi, permVec ); + + //load dest (bytes) as unsigned char + vd = vec_ld( 0, &dst[i] ); + + // do comparison and get bool int result + vtbi0 = vec_cmplt( vs0, constVec ); + vtbi1 = vec_cmplt( vs1, constVec ); + vtbi2 = vec_cmplt( vs2, constVec ); + vtbi3 = vec_cmplt( vs3, constVec ); + + // pack results into shorts + vtbs0 = vec_pack(vtbi0, vtbi1); + vtbs1 = vec_pack(vtbi2, vtbi3); + + // pack results into byte + vtbc0 = vec_pack(vtbs0, vtbs1); + + //and with 1L to get true=1 instead of true=255 + vtuc0 = vec_and(vtbc0, oneVector); + vtuc0 = vec_sl(vtuc0, bitNumVec ); + + //or with original + vd = vec_or( vd, vtuc0 ); + + vec_st( vd, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] |= ( src0[i] < constant ) << bitNum; + } + +} +//#endif + +/* +============ +idSIMD_AltiVec::CmpLE + + dst[i] = src0[i] <= constant; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] = src0[(X)] <= constant; + register vector float v0, v1, v2, v3; + register vector bool int vr1, vr2, vr3, vr4; + register vector bool short vs1, vs2; + register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; + register vector unsigned char vc1; + register vector bool char vbc1; + register vector float constVec; + register vector unsigned char oneVector = (vector unsigned char)(1); + register vector unsigned char permVec; + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] = src0[i] <= constant; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + v3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + // load values + v0_low = v3_hi; + v0_hi = vec_ld( 15, &src0[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src0[i] ); + v2_low = v1_hi; + v2_hi = vec_ld( 47, &src0[i] ); + v3_low = v2_hi; + v3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + v2 = vec_perm( v2_low, v2_hi, permVec ); + v3 = vec_perm( v3_low, v3_hi, permVec ); + + //do comparison + vr1 = vec_cmple( v0, constVec ); + vr2 = vec_cmple( v1, constVec ); + vr3 = vec_cmple( v2, constVec ); + vr4 = vec_cmple( v3, constVec ); + + // pack results into shorts + vs1 = vec_pack(vr1, vr2); + vs2 = vec_pack(vr3, vr4); + + // pack results into byte + vbc1 = vec_pack(vs1, vs2); + + //AND with 1 to get true=1 not true=255 + vc1 = vec_and( vbc1, oneVector ); + + //store results + vec_st( vc1, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src0[i] <= constant; + } +} + +/* +============ +idSIMD_AltiVec::CmpLE + + dst[i] |= ( src0[i] <= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_AltiVec::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +//#define OPER(X) dst[(X)] |= ( src0[(X)] <= constant ) << bitNum; + register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; + register vector bool short vtbs0, vtbs1; + register vector bool char vtbc0; + register vector unsigned char vtuc0; + register vector unsigned char permVec, permVec2; + + // dest vectors + register vector unsigned char vd; + // bitNum vectors + register vector unsigned char bitNumVec; + // src0 vectors + register vector float vs0, vs1, vs2, vs3; + register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; + // constant vector + register vector float constVec; + // all one's + register vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { + dst[i] |= ( src0[i] <= constant ) << bitNum; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //bitNum is unaligned. + permVec2 = vec_lvsl( 0, &bitNum ); + vtuc0 = vec_ld( 0, &bitNum ); + bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); + bitNumVec = vec_splat( bitNumVec, 0 ); + + //calculate permute and do loads + permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); + vs3_hi = vec_ld( 0, &src0[i] ); + + //vectorize! + for ( ; i+15 < count; i += 16 ) { + //load sources (floats) + vs0_low = vs3_hi; + vs0_hi = vec_ld( 15, &src0[i] ); + vs1_low = vs0_hi; + vs1_hi = vec_ld( 31, &src0[i] ); + vs2_low = vs1_hi; + vs2_hi = vec_ld( 47, &src0[i] ); + vs3_low = vs2_hi; + vs3_hi = vec_ld( 63, &src0[i] ); + + //permute into the vectors we want + vs0 = vec_perm( vs0_low, vs0_hi, permVec ); + vs1 = vec_perm( vs1_low, vs1_hi, permVec ); + vs2 = vec_perm( vs2_low, vs2_hi, permVec ); + vs3 = vec_perm( vs3_low, vs3_hi, permVec ); + + //load dest (bytes) as unsigned char + vd = vec_ld( 0, &dst[i] ); + + // do comparison and get bool int result + vtbi0 = vec_cmple( vs0, constVec ); + vtbi1 = vec_cmple( vs1, constVec ); + vtbi2 = vec_cmple( vs2, constVec ); + vtbi3 = vec_cmple( vs3, constVec ); + + // pack results into shorts + vtbs0 = vec_pack(vtbi0, vtbi1); + vtbs1 = vec_pack(vtbi2, vtbi3); + + // pack results into byte + vtbc0 = vec_pack(vtbs0, vtbs1); + + //and with 1L to get true=1 instead of true=255 + vtuc0 = vec_and(vtbc0, oneVector); + vtuc0 = vec_sl(vtuc0, bitNumVec ); + + //or with original + vd = vec_or( vd, vtuc0 ); + + vec_st( vd, 0, &dst[i] ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] |= ( src0[i] <= constant ) << bitNum; + } +} +#endif /* ENABLE_COMPARES */ + +#ifdef ENABLE_MINMAX + +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( float &min, float &max, const float *src, const int count ) { + min = idMath::INFINITY; max = -idMath::INFINITY; +//#define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];} + + register vector float v0, v1, v2, v3; + register vector float maxVec, minVec, tempMin, tempMax; + register vector unsigned char permVec; + register vector float v0_low, v0_hi, v1_low, v1_hi; + vector unsigned char oneCharVector = (vector unsigned char)(1); + int i = 0; + + if ( count >= 4 ) { + + //calculate permute and do first load to + //get a starting point for min and max + permVec = vec_add( vec_lvsl( -1, (int*) &src[0] ), oneCharVector ); + v1_hi = vec_ld( 0, &src[0] ); + + maxVec = loadSplatUnalignedScalar( &max ); + minVec = loadSplatUnalignedScalar( &min ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load sources + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + // minimum + v2 = vec_min( v0, v1 ); + minVec = vec_min( minVec, v2 ); + // maximum + v3 = vec_max( v0, v1 ); + maxVec = vec_max( maxVec, v3 ); + } + + //minVec and maxVec hold the min/max elements from the array, but now + //we need to figure out which particular element it is + + tempMin = minVec; + tempMax = maxVec; + + // rotate vector around and compare to itself to find the real min/max + tempMin = vec_min( tempMin, vec_sld( tempMin, tempMin, 8 ) ); + tempMax = vec_max( tempMax, vec_sld( tempMax, tempMax, 8 ) ); + tempMin = vec_min( tempMin, vec_sld( tempMin, tempMin, 4 ) ); + tempMax = vec_max( tempMax, vec_sld( tempMax, tempMax, 4 ) ); + minVec = vec_splat( tempMin, 0 ); + maxVec = vec_splat( tempMax, 0 ); + vec_ste( minVec, 0, &min ); + vec_ste( maxVec, 0, &max ); + } + + //cleanup + for ( ; i < count; i++ ) { + if ( src[i] < min ) { + min = src[i]; + } + if ( src[i] > max ) { + max = src[i]; + } + } +} + +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { + min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY; +//#define OPER(X) const idVec2 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } + + idVec2 v; + int i = 0; + int j; + + const float *srcPtr = src[0].ToFloatPtr(); + register vector float vecLd1, vecLd2, vecLd3, vecLd4; + register vector float vecMin, vecMax; + + register vector float v0, v1, v2, v3; + + if ( count > 4 ) { + + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr ), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, srcPtr ); + + for ( i = 0, j = 0; i+7 < count; i += 8, j += 4) { + // load data + float *vecPtr = (float*)( srcPtr + (j*4) ); + vector float v0, v1, v2, v3; + + v0 = vecOld; + v1 = vec_ld( 15, vecPtr ); + v2 = vec_ld( 31, vecPtr ); + v3 = vec_ld( 47, vecPtr ); + vecOld = vec_ld( 63, vecPtr ); + + vecLd1 = vec_perm( v0, v1, permVec ); + vecLd2 = vec_perm( v1, v2, permVec ); + vecLd3 = vec_perm( v2, v3, permVec ); + vecLd4 = vec_perm( v3, vecOld, permVec ); + + // each of these vectors contains 2 elements + // looks like | X Y X Y | X Y X Y + v0 = vec_min( vecLd1, vecLd2 ); + v1 = vec_min( vecLd3, vecLd4 ); + v0 = vec_min( v0, v1 ); + + v2 = vec_max( vecLd1, vecLd2 ); + v3 = vec_max( vecLd3, vecLd4 ); + v2 = vec_max( v2, v3 ); + + // since its always X Y X Y we don't have to re-merge each time. we can wait + // until the end + vecMin = vec_min( v0, vecMin ); + vecMax = vec_max( v2, vecMax ); + } + + vecMin = vec_min( vecMin, vec_sld( vecMin, vecMin, 8 ) ); + vecMax = vec_max( vecMax, vec_sld( vecMax, vecMax, 8 ) ); + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMax, 0 ); + v3 = vec_splat( vecMax, 1 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &max[0] ); + vec_ste( v3, 0, &max[1] ); + } + + // cleanup + for ( ; i < count; i++ ) { + v = src[i]; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + } +} + +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; +//#define OPER(X) const idVec3 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } + + int i = 0; + const float *srcPtr = src[0].ToFloatPtr(); + idVec3 v; + + register vector float vecLd1, vecLd2, vecLd3; + register vector float vecMin, vecMax; + register vector float vecSrc1, vecSrc2, vecSrc3, vecSrc4; + register vector float vecMin1, vecMin2, vecMax1, vecMax2; + + if ( count >= 4 ) { + + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr), (vector unsigned char)(1) ); + vector float vecOld = vec_ld( 0, srcPtr ); + + // 4 elements at a time + for ( ; i+3 < count; i += 4 ) { + float *vecPtr = (float*)( srcPtr + (i*3) ); + vector float v0, v1, v2; + + v0 = vecOld; + v1 = vec_ld( 15, vecPtr ); + v2 = vec_ld( 31, vecPtr ); + vecOld = vec_ld( 47, vecPtr ); + + vecLd1 = vec_perm( v0, v1, permVec ); + vecLd2 = vec_perm( v1, v2, permVec ); + vecLd3 = vec_perm( v2, vecOld, permVec ); + + // put each idVec3 into its own vector as X Y Z (crap) + vecSrc1 = vecLd1; + vecSrc2 = vec_sld( vecLd1, vecLd2, 12 ); + vecSrc3 = vec_sld( vecLd2, vecLd3, 8 ); + vecSrc4 = vec_sld( vecLd3, vecLd3, 4 ); + + // do min and max + vecMin1 = vec_min( vecSrc1, vecSrc2 ); + vecMin2 = vec_min( vecSrc3, vecSrc4 ); + vecMin1 = vec_min( vecMin1, vecMin2 ); + vecMin = vec_min( vecMin, vecMin1 ); + + vecMax1 = vec_max( vecSrc1, vecSrc2 ); + vecMax2 = vec_max( vecSrc3, vecSrc4 ); + vecMax1 = vec_max( vecMax1, vecMax2 ); + vecMax = vec_max( vecMax1, vecMax ); + } + + // store results + vector float v0, v1, v2, v3, v4, v5; + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMin, 2 ); + v3 = vec_splat( vecMax, 0 ); + v4 = vec_splat( vecMax, 1 ); + v5 = vec_splat( vecMax, 2 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &min[2] ); + vec_ste( v3, 0, &max[0] ); + vec_ste( v4, 0, &max[1] ); + vec_ste( v5, 0, &max[2] ); + } + + // cleanup + for ( ; i < count; i ++ ) { + v = src[i]; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + if ( v[2] < min[2] ) { + min[2] = v[2]; + } + if ( v[2] > max[2] ) { + max[2] = v[2]; + } + } +} + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { + + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; + idVec3 v; + int i = 0; + register vector float vecMin, vecMax; + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecMin1, vecMin2, vecMax1, vecMax2; + + if ( count >= 4 ) { + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + vector unsigned char vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vector unsigned char vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vector unsigned char vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vector unsigned char vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + + for ( ; i+3 < count; i += 4) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 11, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 11, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 11, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 11, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v2 = vec_perm( v2, v3, vertPerm2 ); + v4 = vec_perm( v4, v5, vertPerm3 ); + v6 = vec_perm( v6, v7, vertPerm4 ); + + vecMin1 = vec_min( v0, v2 ); + vecMin2 = vec_min( v4, v6 ); + vecMin1 = vec_min( vecMin1, vecMin2 ); + vecMin = vec_min( vecMin, vecMin1 ); + + vecMax1 = vec_max( v0, v2 ); + vecMax2 = vec_max( v4, v6 ); + vecMax1 = vec_max( vecMax1, vecMax2 ); + vecMax = vec_max( vecMax, vecMax1 ); + } + + // now we have min/max vectors in X Y Z form, store out + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMin, 2 ); + v3 = vec_splat( vecMax, 0 ); + v4 = vec_splat( vecMax, 1 ); + v5 = vec_splat( vecMax, 2 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &min[2] ); + vec_ste( v3, 0, &max[0] ); + vec_ste( v4, 0, &max[1] ); + vec_ste( v5, 0, &max[2] ); + } + + // cleanup + for ( ; i < count; i++ ) { + v = src[i].xyz; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + + if ( v[2] > max[2] ) { + max[2] = v[2]; + } + + if ( v[2] < min[2] ) { + min[2] = v[2]; + } + } +} +#else +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { + + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; + idVec3 v; + int i = 0; + register vector float vecMin, vecMax; + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecMin1, vecMin2, vecMax1, vecMax2; + + if ( count >= 4 ) { + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + for ( ; i+3 < count; i += 4) { + const float *vertPtr = src[i].xyz.ToFloatPtr(); + const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + + vecMin1 = vec_min( v0, v2 ); + vecMin2 = vec_min( v4, v6 ); + vecMin1 = vec_min( vecMin1, vecMin2 ); + vecMin = vec_min( vecMin, vecMin1 ); + + vecMax1 = vec_max( v0, v2 ); + vecMax2 = vec_max( v4, v6 ); + vecMax1 = vec_max( vecMax1, vecMax2 ); + vecMax = vec_max( vecMax, vecMax1 ); + } + + // now we have min/max vectors in X Y Z form, store out + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMin, 2 ); + v3 = vec_splat( vecMax, 0 ); + v4 = vec_splat( vecMax, 1 ); + v5 = vec_splat( vecMax, 2 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &min[2] ); + vec_ste( v3, 0, &max[0] ); + vec_ste( v4, 0, &max[1] ); + vec_ste( v5, 0, &max[2] ); + } + + // cleanup + for ( ; i < count; i++ ) { + v = src[i].xyz; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + + if ( v[2] > max[2] ) { + max[2] = v[2]; + } + + if ( v[2] < min[2] ) { + min[2] = v[2]; + } + } +} + +#endif /* DRAWVERT_PADDED */ + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; + + idVec3 v; + int i = 0; + + register vector float vecMin, vecMax; + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecMin1, vecMin2, vecMax1, vecMax2; + + if ( count >= 4 ) { + + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + vector unsigned char vertPerm1; + vector unsigned char vertPerm2; + vector unsigned char vertPerm3; + vector unsigned char vertPerm4; + + for ( ; i+3 < count; i += 4) { + const float *vertPtr = src[indexes[i]].xyz.ToFloatPtr(); + const float *vertPtr2 = src[indexes[i+1]].xyz.ToFloatPtr(); + const float *vertPtr3 = src[indexes[i+2]].xyz.ToFloatPtr(); + const float *vertPtr4 = src[indexes[i+3]].xyz.ToFloatPtr(); + + vertPerm1 = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, vertPtr2 ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, vertPtr3 ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, vertPtr4 ), (vector unsigned char)(1) ); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v2 = vec_perm( v2, v3, vertPerm2 ); + v4 = vec_perm( v4, v5, vertPerm3 ); + v6 = vec_perm( v6, v7, vertPerm4 ); + + vecMin1 = vec_min( v0, v2 ); + vecMin2 = vec_min( v4, v6 ); + vecMin1 = vec_min( vecMin1, vecMin2 ); + vecMin = vec_min( vecMin, vecMin1 ); + + vecMax1 = vec_max( v0, v2 ); + vecMax2 = vec_max( v4, v6 ); + vecMax1 = vec_max( vecMax1, vecMax2 ); + vecMax = vec_max( vecMax, vecMax1 ); + } + + // now we have min/max vectors in X Y Z form, store out + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMin, 2 ); + v3 = vec_splat( vecMax, 0 ); + v4 = vec_splat( vecMax, 1 ); + v5 = vec_splat( vecMax, 2 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &min[2] ); + vec_ste( v3, 0, &max[0] ); + vec_ste( v4, 0, &max[1] ); + vec_ste( v5, 0, &max[2] ); + } + + // cleanup + for ( ; i < count; i++ ) { + v = src[indexes[i]].xyz; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + + if ( v[2] > max[2] ) { + max[2] = v[2]; + } + + if ( v[2] < min[2] ) { + min[2] = v[2]; + } + } +} +#else +/* +============ +idSIMD_AltiVec::MinMax +============ +*/ +void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; + + idVec3 v; + int i = 0; + + register vector float vecMin, vecMax; + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float vecMin1, vecMin2, vecMax1, vecMax2; + + if ( count >= 4 ) { + + vecMin = (vector float)(FLT_MAX); + vecMax = (vector float)(FLT_MIN); + + vector unsigned char vertPerm1; + vector unsigned char vertPerm2; + vector unsigned char vertPerm3; + vector unsigned char vertPerm4; + + for ( ; i+3 < count; i += 4) { + const float *vertPtr = src[indexes[i]].xyz.ToFloatPtr(); + const float *vertPtr2 = src[indexes[i+1]].xyz.ToFloatPtr(); + const float *vertPtr3 = src[indexes[i+2]].xyz.ToFloatPtr(); + const float *vertPtr4 = src[indexes[i+3]].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + + vecMin1 = vec_min( v0, v2 ); + vecMin2 = vec_min( v4, v6 ); + vecMin1 = vec_min( vecMin1, vecMin2 ); + vecMin = vec_min( vecMin, vecMin1 ); + + vecMax1 = vec_max( v0, v2 ); + vecMax2 = vec_max( v4, v6 ); + vecMax1 = vec_max( vecMax1, vecMax2 ); + vecMax = vec_max( vecMax, vecMax1 ); + } + + // now we have min/max vectors in X Y Z form, store out + v0 = vec_splat( vecMin, 0 ); + v1 = vec_splat( vecMin, 1 ); + v2 = vec_splat( vecMin, 2 ); + v3 = vec_splat( vecMax, 0 ); + v4 = vec_splat( vecMax, 1 ); + v5 = vec_splat( vecMax, 2 ); + + vec_ste( v0, 0, &min[0] ); + vec_ste( v1, 0, &min[1] ); + vec_ste( v2, 0, &min[2] ); + vec_ste( v3, 0, &max[0] ); + vec_ste( v4, 0, &max[1] ); + vec_ste( v5, 0, &max[2] ); + } + + // cleanup + for ( ; i < count; i++ ) { + v = src[indexes[i]].xyz; + + if ( v[0] < min[0] ) { + min[0] = v[0]; + } + if ( v[0] > max[0] ) { + max[0] = v[0]; + } + + if ( v[1] < min[1] ) { + min[1] = v[1]; + } + if ( v[1] > max[1] ) { + max[1] = v[1]; + } + + if ( v[2] > max[2] ) { + max[2] = v[2]; + } + + if ( v[2] < min[2] ) { + min[2] = v[2]; + } + } +} + + +#endif /* DRAWVERT_PADDED */ + +#endif /* ENABLE_MINMAX */ + +#ifdef ENABLE_CLAMP + +/* +============ +idSIMD_AltiVec::Clamp +============ +*/ +void VPCALL idSIMD_AltiVec::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { +//#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)] > max ? max : src[(X)]; + register vector float v0, v1, v2, v3, v4, v5; + register vector unsigned char permVec; + register vector float v0_low, v0_hi, v1_low, v1_hi; + vector unsigned char oneVector = (vector unsigned char)(1); + register vector float minVec, maxVec; + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src[i] < min ? min : src[i] > max ? max : src[i]; + } + + //splat min/max into a vector + minVec = loadSplatUnalignedScalar( &min ); + maxVec = loadSplatUnalignedScalar( &max ); + + //calculate permute and do first load + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); + v1_hi = vec_ld( 0, &src[i] ); + + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + //apply minimum + v2 = vec_max( v0, minVec ); + v3 = vec_max( v1, minVec ); + + //apply maximum + v4 = vec_min( v2, maxVec ); + v5 = vec_min( v3, maxVec ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src[i] < min ? min : src[i] > max ? max : src[i]; + } +} + +/* +============ +idSIMD_AltiVec::ClampMin +============ +*/ +void VPCALL idSIMD_AltiVec::ClampMin( float *dst, const float *src, const float min, const int count ) { +//#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)]; + register vector float v0, v1, v2, v3; + register vector unsigned char permVec; + register vector float v0_low, v0_hi, v1_low, v1_hi; + register vector float constVec; + vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src[i] < min ? min : src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &min ); + + //calculate permute and do first load + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); + v1_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + + v2 = vec_max( v0, constVec ); + v3 = vec_max( v1, constVec ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src[i] < min ? min : src[i]; + } + } + +/* +============ +idSIMD_AltiVec::ClampMax +============ +*/ +void VPCALL idSIMD_AltiVec::ClampMax( float *dst, const float *src, const float max, const int count ) { +//#define OPER(X) dst[(X)] = src[(X)] > max ? max : src[(X)]; + register vector float v0, v1, v2, v3; + register vector unsigned char permVec; + register vector float constVec; + register vector float v0_low, v0_hi, v1_low, v1_hi; + vector unsigned char oneVector = (vector unsigned char)(1); + int i = 0; + + //handle unaligned at start + for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { + dst[i] = src[i] < max ? max : src[i]; + } + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &max ); + + //calculate permute and do first load + permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); + v1_hi = vec_ld( 0, &src[i] ); + + //vectorize! + for ( ; i+7 < count; i += 8 ) { + //load source + v0_low = v1_hi; + v0_hi = vec_ld( 15, &src[i] ); + v1_low = v0_hi; + v1_hi = vec_ld( 31, &src[i] ); + + v0 = vec_perm( v0_low, v0_hi, permVec ); + v1 = vec_perm( v1_low, v1_hi, permVec ); + v2 = vec_min( v0, constVec ); + v3 = vec_min( v1, constVec ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + //handle cleanup + for ( ; i < count ; i++ ) { + dst[i] = src[i] < max ? max : src[i]; + } +} + +#endif /* ENABLE_CLAMP */ + +#ifdef ENABLE_16ROUTINES + +/* +============ +idSIMD_AltiVec::Zero16 +============ +*/ +void VPCALL idSIMD_AltiVec::Zero16( float *dst, const int count ) { + memset( dst, 0, count * sizeof( float ) ); +} + +/* +============ +idSIMD_AltiVec::Negate16 + + Assumptions: + dst is aligned +============ +*/ +void VPCALL idSIMD_AltiVec::Negate16( float *dst, const int count ) { +//#define OPER(X) ptr[(X)] ^= ( 1 << 31 ) // IEEE 32 bits float sign bit + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + int i = 0; + vector float v0, v1, v2, v3; + + //know its 16-byte aligned + for ( ; i + 7 < count2; i += 8 ) { + v0 = vec_ld( 0, &dst[i] ); + v1 = vec_ld( 16, &dst[i] ); + + v2 = vec_sub( (vector float)(0), v0 ); + v3 = vec_sub( (vector float)(0), v1 ); + + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &dst[i] ); + v1 = vec_sub( (vector float)(0), v0 ); + vec_st( v1, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::Copy16 +============ +*/ +void VPCALL idSIMD_AltiVec::Copy16( float *dst, const float *src, const int count ) { +//#define OPER(X) dst[(X)] = src[(X)] + memcpy( dst, src, sizeof(float) * count ); +} + +/* +============ +idSIMD_AltiVec::Add16 + + Assumptions: + Assumes dst, src1, src2 all start at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::Add16( float *dst, const float *src1, const float *src2, const int count ) { +//#define OPER(X) dst[(X)] = src1[(X)] + src2[(X)] + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // src1 is aligned + assert( IS_16BYTE_ALIGNED( src1[0] ) ); + // src2 is aligned + assert( IS_16BYTE_ALIGNED( src2[0] ) ); + + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + register vector float v0, v1, v2, v3, v4, v5; + int i = 0; + + //know all data is 16-byte aligned, so vectorize! + for ( ; i+7 < count2; i += 8 ) { + //load sources + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_ld( 16, &src1[i] ); + v2 = vec_ld( 0, &src2[i] ); + v3 = vec_ld( 16, &src2[i] ); + v4 = vec_add( v0, v2 ); + v5 = vec_add( v1, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_ld( 0, &src2[i] ); + v2 = vec_add( v0, v1 ); + vec_st( v2, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::Sub16 + + Assumptions: + Assumes that dst, src1, and src2 all start at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::Sub16( float *dst, const float *src1, const float *src2, const int count ) { +//#define OPER(X) dst[(X)] = src1[(X)] - src2[(X)] + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // src1 is aligned + assert( IS_16BYTE_ALIGNED( src1[0] ) ); + // src2 is aligned + assert( IS_16BYTE_ALIGNED( src2[0] ) ); + + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + register vector float v0, v1, v2, v3, v4, v5; + int i = 0; + + //know data is aligned, so vectorize! + for ( ; i+7 < count2; i += 8 ) { + //load sources + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_ld( 16, &src1[i] ); + v2 = vec_ld( 0, &src2[i] ); + v3 = vec_ld( 16, &src2[i] ); + v4 = vec_sub( v0, v2 ); + v5 = vec_sub( v1, v3 ); + + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_ld( 0, &src2[i] ); + v2 = vec_sub( v0, v1 ); + vec_st( v2, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::Mul16 + + Assumptions: + Assumes that dst and src1 start at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::Mul16( float *dst, const float *src1, const float constant, const int count ) { +//#define OPER(X) dst[(X)] = src1[(X)] * constant + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // src1 is aligned + assert( IS_16BYTE_ALIGNED( src1[0] ) ); + + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + register vector float v0, v1, v2, v3; + register vector float constVec; + register vector float zeroVector = (vector float)(0.0); + int i = 0; + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //know data is aligned, so vectorize! + for ( ; i+7 < count2; i += 8 ) { + //load source + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_ld( 16, &src1[i] ); + v2 = vec_madd( constVec, v0, zeroVector ); + v3 = vec_madd( constVec, v1, zeroVector ); + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &src1[i] ); + v1 = vec_madd( constVec, v0, zeroVector ); + vec_st( v1, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::AddAssign16 + + Assumptions: + Assumes that dst and src start at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::AddAssign16( float *dst, const float *src, const int count ) { +//#define OPER(X) dst[(X)] += src[(X)] + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // src is aligned + assert( IS_16BYTE_ALIGNED( src[0] ) ); + + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + register vector float v0, v1, v2, v3, v4, v5; + int i = 0; + + //vectorize! + for ( ; i+7 < count2; i += 8 ) { + v0 = vec_ld( 0, &src[i] ); + v1 = vec_ld( 16, &src[i] ); + v2 = vec_ld( 0, &dst[i] ); + v3 = vec_ld( 16, &dst[i] ); + v4 = vec_add( v0, v2 ); + v5 = vec_add( v1, v3 ); + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &src[i] ); + v1 = vec_ld( 0, &dst[i] ); + v2 = vec_add( v0, v1 ); + vec_st( v2, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::SubAssign16 + + Assumptions: + Assumes that dst and src start at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::SubAssign16( float *dst, const float *src, const int count ) { +//#define OPER(X) dst[(X)] -= src[(X)] + register vector float v0, v1, v2, v3, v4, v5; + int i=0; + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // src is aligned + assert( IS_16BYTE_ALIGNED( src[0] ) ); + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + //vectorize! + for ( ; i+7 < count2; i += 8 ) { + v0 = vec_ld( 0, &src[i] ); + v1 = vec_ld( 16, &src[i] ); + v2 = vec_ld( 0, &dst[i] ); + v3 = vec_ld( 16, &dst[i] ); + v4 = vec_sub( v2, v0 ); + v5 = vec_sub( v3, v1 ); + ALIGNED_STORE2( &dst[i], v4, v5 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &src[i] ); + v1 = vec_ld( 0, &dst[i] ); + v2 = vec_sub( v1, v0 ); + vec_st( v2, 0, &dst[i] ); + } +} + +/* +============ +idSIMD_AltiVec::MulAssign16 + + Assumptions: + Assumes that dst starts at aligned address and count is multiple of 4 +============ +*/ +void VPCALL idSIMD_AltiVec::MulAssign16( float *dst, const float constant, const int count ) { +//#define OPER(X) dst[(X)] *= constant + + // dst is aligned + assert( IS_16BYTE_ALIGNED( dst[0] ) ); + // round count up to next 4 if needbe + int count2 = ( count + 3 ) & ~3; + + register vector float v0, v1, v2, v3; + register vector float constVec; + int i = 0; + register vector float zeroVector = (vector float)(0.0); + + //splat constant into a vector + constVec = loadSplatUnalignedScalar( &constant ); + + //vectorize! + for ( ; i+7 < count2; i += 8 ) { + v0 = vec_ld( 0, &dst[i] ); + v1 = vec_ld( 16, &dst[i] ); + v2 = vec_madd( v0, constVec, zeroVector ); + v3 = vec_madd( v1, constVec, zeroVector ); + ALIGNED_STORE2( &dst[i], v2, v3 ); + } + + for ( ; i < count2; i += 4 ) { + v0 = vec_ld( 0, &dst[i] ); + v1 = vec_madd( v0, constVec, zeroVector ); + vec_st( v1, 0, &dst[i] ); + } +} + +#endif /* ENABLE_16ROUTINES */ + +#ifdef ENABLE_LOWER_TRIANGULAR + +/* +============ +idSIMD_AltiVec::MatX_LowerTriangularSolve + + solves x in L * x = b for the first n rows of L + if skip > 0 the first skip elements of x are assumed to be valid already + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ + +void VPCALL idSIMD_AltiVec::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { + + int i, j; + const float *lptr; + const float *lptr2; + const float *lptr3; + const float *lptr4; + float sum; + float sum2; + float sum3; + float sum4; + float tempSum; + float tempSum2; + float tempSum3; + float tempSum4; + vector float vecSum1 = (vector float)(0.0); + vector float vecSum2 = (vector float)(0.0); + vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; + vector float zeroVector = (vector float)(0.0); + vector float vecSum3, vecSum4, vecSum5, vecSum6, vecSum7, vecSum8; + + vector unsigned char vecPermX = vec_add( vec_lvsl( -1, &x[0] ), (vector unsigned char)(1) ); + + // unrolled this loop a bit + for ( i = skip; i+3 < n; i+=4 ) { + sum = b[i]; + sum2 = b[i+1]; + sum3 = b[i+2]; + sum4 = b[i+3]; + + vecSum1 = zeroVector; + vecSum2 = zeroVector; + vecSum3 = vecSum4 = vecSum5 = vecSum6 = vecSum7 = vecSum8 = zeroVector; + lptr = L[i]; + lptr2 = L[i+1]; + lptr3 = L[i+2]; + lptr4 = L[i+3]; + + vector unsigned char vecPermLptr1 = vec_add( vec_lvsl( -1, lptr ), (vector unsigned char)(1) ); + vector unsigned char vecPermLptr2 = vec_add( vec_lvsl( -1, lptr2 ), (vector unsigned char)(1) ); + vector unsigned char vecPermLptr3 = vec_add( vec_lvsl( -1, lptr3 ), (vector unsigned char)(1) ); + vector unsigned char vecPermLptr4 = vec_add( vec_lvsl( -1, lptr4 ), (vector unsigned char)(1) ); + + for ( j = 0 ; j+7 < i; j+=8 ) { + + v0 = vec_ld( 0, &x[j] ); + v1 = vec_ld( 15, &x[j] ); + vector float vecExtraX = vec_ld( 31, &x[j] ); + v0 = vec_perm( v0, v1, vecPermX ); + v1 = vec_perm( v1, vecExtraX, vecPermX ); + + v2 = vec_ld( 0, lptr + j ); + v3 = vec_ld( 15, lptr + j ); + vector float vecExtra1 = vec_ld( 31, lptr + j ); + v2 = vec_perm( v2, v3, vecPermLptr1 ); + v3 = vec_perm( v3, vecExtra1, vecPermLptr1 ); + + v4 = vec_ld( 0, lptr2 + j ); + v5 = vec_ld( 15, lptr2 + j ); + vector float vecExtra2 = vec_ld( 31, lptr2 + j ); + v4 = vec_perm( v4, v5, vecPermLptr2 ); + v5 = vec_perm( v5, vecExtra2, vecPermLptr2 ); + + v6 = vec_ld( 0, lptr3 + j ); + v7 = vec_ld( 15, lptr3 + j ); + vector float vecExtra3 = vec_ld( 31, lptr3 + j ); + v6 = vec_perm( v6, v7, vecPermLptr3 ); + v7 = vec_perm( v7, vecExtra3, vecPermLptr3 ); + + v8 = vec_ld( 0, lptr4 + j ); + v9 = vec_ld( 15, lptr4 + j ); + vector float vecExtra4 = vec_ld( 31, lptr4 + j ); + v8 = vec_perm( v8, v9, vecPermLptr4 ); + v9 = vec_perm( v9, vecExtra4, vecPermLptr4 ); + + vecSum1 = vec_madd( v2, v0, vecSum1 ); + vecSum2 = vec_madd( v3, v1, vecSum2 ); + + vecSum3 = vec_madd( v4, v0, vecSum3 ); + vecSum4 = vec_madd( v5, v1, vecSum4 ); + + vecSum5 = vec_madd( v6, v0, vecSum5 ); + vecSum6 = vec_madd( v7, v1, vecSum6 ); + + vecSum7 = vec_madd( v8, v0, vecSum7 ); + vecSum8 = vec_madd( v9, v1, vecSum8 ); + } + + // if we ran the unrolled code, we need to sum accross the vectors + // to find out how much to subtract from sum + if ( j > 0 ) { + vecSum1 = vec_add( vecSum1, vecSum2 ); + vecSum3 = vec_add( vecSum3, vecSum4 ); + vecSum5 = vec_add( vecSum5, vecSum6 ); + vecSum7 = vec_add( vecSum7, vecSum8 ); + //sum accross the vectors + vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 8 ) ); + vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 4 ) ); + + vecSum3 = vec_add( vecSum3, vec_sld( vecSum3, vecSum3, 8 ) ); + vecSum3 = vec_add( vecSum3, vec_sld( vecSum3, vecSum3, 4 ) ); + + vecSum5 = vec_add( vecSum5, vec_sld( vecSum5, vecSum5, 8 ) ); + vecSum5 = vec_add( vecSum5, vec_sld( vecSum5, vecSum5, 4 ) ); + + vecSum7 = vec_add( vecSum7, vec_sld( vecSum7, vecSum7, 8 ) ); + vecSum7 = vec_add( vecSum7, vec_sld( vecSum7, vecSum7, 4 ) ); + + //move the result to the FPU + vec_ste( vec_splat( vecSum1, 0 ), 0, &tempSum ); + vec_ste( vec_splat( vecSum3, 0 ), 0, &tempSum2 ); + vec_ste( vec_splat( vecSum5, 0 ), 0, &tempSum3 ); + vec_ste( vec_splat( vecSum7, 0 ), 0, &tempSum4 ); + + sum -= tempSum; + sum2 -= tempSum2; + sum3 -= tempSum3; + sum4 -= tempSum4; + } + + //cleanup + for ( ; j < i; j++ ) { + sum -= lptr[j] * x[j]; + sum2 -= lptr2[j] * x[j]; + sum3 -= lptr3[j] * x[j]; + sum4 -= lptr4[j] * x[j]; + } + + // store the 4 results at a time + sum2 -= ( lptr2[i] * sum ); + sum3 = sum3 - ( lptr3[i+1] * sum2 ) - ( lptr3[i] * sum ); + sum4 = sum4 - ( lptr4[i+2] * sum3 ) - ( lptr4[i+1] * sum2 ) - ( lptr4[i] * sum ); + + x[i] = sum; + x[i+1] = sum2; + x[i+2] = sum3; + x[i+3] = sum4; + } + + // cleanup + for ( ; i < n; i++ ) { + sum = b[i]; + vecSum1 = zeroVector; + vecSum2 = zeroVector; + lptr = L[i]; + vector unsigned char vecPermLptr = vec_add( vec_lvsl( -1, lptr ), (vector unsigned char)(1) ); + + for ( j = 0 ; j+7 < i; j+=8 ) { + + v0 = vec_ld( 0, &x[j] ); + v2 = vec_ld( 15, &x[j] ); + vector float vecExtraX = vec_ld( 31, &x[j] ); + v0 = vec_perm( v0, v2, vecPermX ); + v2 = vec_perm( v2, vecExtraX, vecPermX ); + + v1 = vec_ld( 0, lptr + j ); + v3 = vec_ld( 15, lptr + j ); + vector float vecExtra = vec_ld( 31, lptr + j ); + v1 = vec_perm( v1, v3, vecPermLptr ); + v3 = vec_perm( v3, vecExtra, vecPermLptr ); + + vecSum1 = vec_madd( v1, v0, vecSum1 ); + vecSum2 = vec_madd( v3, v2, vecSum2 ); + } + + // if we ran the unrolled code, we need to sum accross the vectors + // to find out how much to subtract from sum + if ( j > 0 ) { + //sum accross the vectors + vecSum1 = vec_add( vecSum1, vecSum2 ); + vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 8 ) ); + vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 4 ) ); + + //move the result to the FPU + vec_ste( vec_splat( vecSum1, 0 ), 0, &tempSum ); + sum -= tempSum; + } + + //cleanup + for ( ; j < i; j++ ) { + sum -= lptr[j] * x[j]; + } + x[i] = sum; + } +} + +/* +============ +idSIMD_AltiVec::MatX_LowerTriangularSolveTranspose + + solves x in L.Transpose() * x = b for the first n rows of L + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_AltiVec::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { + + int nc; + const float *lptr; + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + float x0, x1, x2, x3, x4, x5, x6; + // unrolled cases for n < 8 + if ( n < 8 ) { + switch( n ) { + // using local variables to avoid aliasing issues + case 0: + return; + case 1: + x[0] = b[0]; + return; + case 2: + x1 = b[1]; + x0 = b[0] - lptr[1*nc+0] * x1; + + x[1] = x1; + x[0] = x0; + return; + case 3: + x2 = b[2]; + x1 = b[1] - lptr[2*nc+1] * x2; + x0 = b[0] - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; + + x[2] = x2; + x[1] = x1; + x[0] = x0; + return; + case 4: + x3 = b[3]; + x2 = b[2] - lptr[3*nc+2] * x3; + x1 = b[1] - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; + x0 = b[0] - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; + + x[3] = x3; + x[2] = x2; + x[1] = x1; + x[0] = x0; + + return; + case 5: + x4 = b[4]; + x3 = b[3] - lptr[4*nc+3] * x4; + x2 = b[2] - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; + x1 = b[1] - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; + x0 = b[0] - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; + + x[4] = x4; + x[3] = x3; + x[2] = x2; + x[1] = x1; + x[0] = x0; + return; + case 6: + x5 = b[5]; + x4 = b[4] - lptr[5*nc+4] * x5; + x3 = b[3] - lptr[5*nc+3] * x5 - lptr[4*nc+3] * x4; + x2 = b[2] - lptr[5*nc+2] * x5 - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; + x1 = b[1] - lptr[5*nc+1] * x5 - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; + x0 = b[0] - lptr[5*nc+0] * x5 - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; + + x[5] = x5; + x[4] = x4; + x[3] = x3; + x[2] = x2; + x[1] = x1; + x[0] = x0; + + return; + case 7: + x6 = b[6]; + x5 = b[5] - lptr[6*nc+5] * x6; + x4 = b[4] - lptr[6*nc+4] * x6 - lptr[5*nc+4] * x5; + x3 = b[3] - lptr[6*nc+3] * x6 - lptr[5*nc+3] * x5 - lptr[4*nc+3] * x4; + x2 = b[2] - lptr[6*nc+2] * x6 - lptr[5*nc+2] * x5 - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; + x1 = b[1] - lptr[6*nc+1] * x6 - lptr[5*nc+1] * x5 - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; + x0 = b[0] - lptr[6*nc+0] * x6 - lptr[5*nc+0] * x5 - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; + + x[6] = x6; + x[5] = x5; + x[4] = x4; + x[3] = x3; + x[2] = x2; + x[1] = x1; + x[0] = x0; + return; + } + return; + } + + int i, j; + register float s0, s1, s2, s3; + float *xptr; + + lptr = L.ToFloatPtr() + n * nc + n - 4; + xptr = x + n; + + // process 4 rows at a time + for ( i = n; i >= 4; i -= 4 ) { + s0 = b[i-4]; + s1 = b[i-3]; + s2 = b[i-2]; + s3 = b[i-1]; + // process 4x4 blocks + for ( j = 0; j < n-i; j += 4 ) { + s0 -= lptr[(j+0)*nc+0] * xptr[j+0]; + s1 -= lptr[(j+0)*nc+1] * xptr[j+0]; + s2 -= lptr[(j+0)*nc+2] * xptr[j+0]; + s3 -= lptr[(j+0)*nc+3] * xptr[j+0]; + s0 -= lptr[(j+1)*nc+0] * xptr[j+1]; + s1 -= lptr[(j+1)*nc+1] * xptr[j+1]; + s2 -= lptr[(j+1)*nc+2] * xptr[j+1]; + s3 -= lptr[(j+1)*nc+3] * xptr[j+1]; + s0 -= lptr[(j+2)*nc+0] * xptr[j+2]; + s1 -= lptr[(j+2)*nc+1] * xptr[j+2]; + s2 -= lptr[(j+2)*nc+2] * xptr[j+2]; + s3 -= lptr[(j+2)*nc+3] * xptr[j+2]; + s0 -= lptr[(j+3)*nc+0] * xptr[j+3]; + s1 -= lptr[(j+3)*nc+1] * xptr[j+3]; + s2 -= lptr[(j+3)*nc+2] * xptr[j+3]; + s3 -= lptr[(j+3)*nc+3] * xptr[j+3]; + } + // process left over of the 4 rows + s0 -= lptr[0-1*nc] * s3; + s1 -= lptr[1-1*nc] * s3; + s2 -= lptr[2-1*nc] * s3; + s0 -= lptr[0-2*nc] * s2; + s1 -= lptr[1-2*nc] * s2; + s0 -= lptr[0-3*nc] * s1; + // store result + xptr[-4] = s0; + xptr[-3] = s1; + xptr[-2] = s2; + xptr[-1] = s3; + // update pointers for next four rows + lptr -= 4 + 4 * nc; + xptr -= 4; + } + // process left over rows + for ( i--; i >= 0; i-- ) { + s0 = b[i]; + lptr = L[0] + i; + for ( j = i + 1; j < n; j++ ) { + s0 -= lptr[j*nc] * x[j]; + } + x[i] = s0; + } +} + +/* +============ +idSIMD_AltiVec::MatX_LDLTFactor +============ +*/ +bool VPCALL idSIMD_AltiVec::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { + int i, j, k, nc; + float *v, *diag, *mptr; + float s0, s1, s2, s3, sum, d; + float s0_2, s1_2, s2_2, s3_2, sum_2; + float *mptr2; + + v = (float *) _alloca16( n * sizeof( float ) ); + diag = (float *) _alloca16( n * sizeof( float ) ); + + nc = mat.GetNumColumns(); + + if ( n <= 0 ) { + return true; + } + + mptr = mat[0]; + + sum = mptr[0]; + + if ( sum == 0.0f ) { + return false; + } + + diag[0] = sum; + invDiag[0] = d = 1.0f / sum; + + if ( n <= 1 ) { + return true; + } + + mptr = mat[0]; + for ( j = 1; j < n; j++ ) { + mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; + } + + mptr = mat[1]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + sum = mptr[1] - s0; + + if ( sum == 0.0f ) { + return false; + } + + mat[1][1] = sum; + diag[1] = sum; + invDiag[1] = d = 1.0f / sum; + + if ( n <= 2 ) { + return true; + } + + mptr = mat[0]; + for ( j = 2; j < n; j++ ) { + mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; + } + + mptr = mat[2]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + sum = mptr[2] - s0 - s1; + + if ( sum == 0.0f ) { + return false; + } + + mat[2][2] = sum; + diag[2] = sum; + invDiag[2] = d = 1.0f / sum; + + if ( n <= 3 ) { + return true; + } + + mptr = mat[0]; + for ( j = 3; j < n; j++ ) { + mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; + } + + mptr = mat[3]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + sum = mptr[3] - s0 - s1 - s2; + + if ( sum == 0.0f ) { + return false; + } + + mat[3][3] = sum; + diag[3] = sum; + invDiag[3] = d = 1.0f / sum; + + if ( n <= 4 ) { + return true; + } + + mptr = mat[0]; + for ( j = 4; j < n; j++ ) { + mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; + } + + for ( i = 4; i < n; i++ ) { + + mptr = mat[i]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; + for ( k = 4; k < i-3; k += 4 ) { + v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; + v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; + v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; + } + switch( i - k ) { + case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; + case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; + } + sum = s3; + sum += s2; + sum += s1; + sum += s0; + sum = mptr[i] - sum; + + if ( sum == 0.0f ) { + return false; + } + + mat[i][i] = sum; + diag[i] = sum; + invDiag[i] = d = 1.0f / sum; + + if ( i + 1 >= n ) { + return true; + } + + // unrolling madness! + mptr = mat[i+1]; + mptr2 = mat[i+1] + nc; + + for ( j = i+1; j+1 < n; j+=2 ) { + s0 = mptr[0] * v[0]; + s1 = mptr[1] * v[1]; + s2 = mptr[2] * v[2]; + s3 = mptr[3] * v[3]; + + s0_2 = mptr2[0] * v[0]; + s1_2 = mptr2[1] * v[1]; + s2_2 = mptr2[2] * v[2]; + s3_2 = mptr2[3] * v[3]; + + for ( k = 4; k < i-7; k += 8 ) { + s0 += mptr[k+0] * v[k+0]; + s1 += mptr[k+1] * v[k+1]; + s2 += mptr[k+2] * v[k+2]; + s3 += mptr[k+3] * v[k+3]; + s0 += mptr[k+4] * v[k+4]; + s1 += mptr[k+5] * v[k+5]; + s2 += mptr[k+6] * v[k+6]; + s3 += mptr[k+7] * v[k+7]; + + s0_2 += mptr2[k+0] * v[k+0]; + s1_2 += mptr2[k+1] * v[k+1]; + s2_2 += mptr2[k+2] * v[k+2]; + s3_2 += mptr2[k+3] * v[k+3]; + s0_2 += mptr2[k+4] * v[k+4]; + s1_2 += mptr2[k+5] * v[k+5]; + s2_2 += mptr2[k+6] * v[k+6]; + s3_2 += mptr2[k+7] * v[k+7]; + } + + switch( i - k ) { + case 7: s0 += mptr[k+6] * v[k+6]; s0_2 += mptr2[k+6] * v[k+6]; + case 6: s1 += mptr[k+5] * v[k+5]; s1_2 += mptr2[k+5] * v[k+5]; + case 5: s2 += mptr[k+4] * v[k+4]; s2_2 += mptr2[k+4] * v[k+4]; + case 4: s3 += mptr[k+3] * v[k+3]; s3_2 += mptr2[k+3] * v[k+3]; + case 3: s0 += mptr[k+2] * v[k+2]; s0_2 += mptr2[k+2] * v[k+2]; + case 2: s1 += mptr[k+1] * v[k+1]; s1_2 += mptr2[k+1] * v[k+1]; + case 1: s2 += mptr[k+0] * v[k+0]; s2_2 += mptr2[k+0] * v[k+0]; + } + // disassociate these adds + s3 += s2; + s1 += s0; + sum = s1 + s3; + + s3_2 += s2_2; + s1_2 += s0_2; + sum_2 = s1_2 + s3_2; + + mptr[i] = ( mptr[i] - sum ) * d; + mptr2[i] = ( mptr2[i] - sum_2 ) * d; + + mptr += nc*2; + mptr2 += nc*2; + } + + // cleanup + for ( ; j < n; j++ ) { + s0 = mptr[0] * v[0]; + s1 = mptr[1] * v[1]; + s2 = mptr[2] * v[2]; + s3 = mptr[3] * v[3]; + for ( k = 4; k < i-7; k += 8 ) { + s0 += mptr[k+0] * v[k+0]; + s1 += mptr[k+1] * v[k+1]; + s2 += mptr[k+2] * v[k+2]; + s3 += mptr[k+3] * v[k+3]; + s0 += mptr[k+4] * v[k+4]; + s1 += mptr[k+5] * v[k+5]; + s2 += mptr[k+6] * v[k+6]; + s3 += mptr[k+7] * v[k+7]; + } + switch( i - k ) { + case 7: s0 += mptr[k+6] * v[k+6]; + case 6: s1 += mptr[k+5] * v[k+5]; + case 5: s2 += mptr[k+4] * v[k+4]; + case 4: s3 += mptr[k+3] * v[k+3]; + case 3: s0 += mptr[k+2] * v[k+2]; + case 2: s1 += mptr[k+1] * v[k+1]; + case 1: s2 += mptr[k+0] * v[k+0]; + } + // disassociate these adds + s3 += s2; + s1 += s0; + sum = s1 + s3; + mptr[i] = ( mptr[i] - sum ) * d; + mptr += nc; + } + } + return true; +} +#endif /* ENABLE_LOWER_TRIANGULAR */ + + +#ifdef LIVE_VICARIOUSLY +/* +============ +idSIMD_AltiVec::BlendJoints +============ +*/ +void VPCALL idSIMD_AltiVec::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { + int i; + + // since lerp is a constant, we can special case the two cases if they're true + if ( lerp <= 0.0f ) { + // this sets joints back to joints. No sense in doing no work, so just return + return; + } + + if ( lerp >= 1.0f ) { + // this copies each q from blendJoints to joints and copies each t from blendJoints to joints + memcpy( joints[0].q.ToFloatPtr(), blendJoints[0].q.ToFloatPtr(), sizeof(idJointQuat) * numJoints ); + return; + } + + vector float vecLerp = loadSplatUnalignedScalar( &lerp ); + vector float zeroVector = (vector float)(0); + + for ( i = 0; i+3 < numJoints; i+=4 ) { + int j = index[i]; + int j2 = index[i+1]; + int j3 = index[i+2]; + int j4 = index[i+3]; + + // slerp + const float *jointPtr = joints[j].q.ToFloatPtr(); + const float *blendPtr = blendJoints[j].q.ToFloatPtr(); + const float *jointPtr2 = joints[j2].q.ToFloatPtr(); + const float *blendPtr2 = blendJoints[j2].q.ToFloatPtr(); + const float *jointPtr3 = joints[j3].q.ToFloatPtr(); + const float *blendPtr3 = blendJoints[j3].q.ToFloatPtr(); + const float *jointPtr4 = joints[j4].q.ToFloatPtr(); + const float *blendPtr4 = blendJoints[j4].q.ToFloatPtr(); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); + vector unsigned char permVec2 = vec_add( vec_lvsl( -1, jointPtr2 ), (vector unsigned char)(1) ); + vector unsigned char permVec3 = vec_add( vec_lvsl( -1, jointPtr3 ), (vector unsigned char)(1) ); + vector unsigned char permVec4 = vec_add( vec_lvsl( -1, jointPtr4 ), (vector unsigned char)(1) ); + + vector unsigned char permVec5 = vec_add( vec_lvsl( -1, blendPtr ), (vector unsigned char)(1) ); + vector unsigned char permVec6 = vec_add( vec_lvsl( -1, blendPtr2 ), (vector unsigned char)(1) ); + vector unsigned char permVec7 = vec_add( vec_lvsl( -1, blendPtr3 ), (vector unsigned char)(1) ); + vector unsigned char permVec8 = vec_add( vec_lvsl( -1, blendPtr4 ), (vector unsigned char)(1) ); + + vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; + vector float v12, v13, v14, v15, v16; + vector float vecFromX, vecFromY, vecFromZ, vecFromW; + vector float vecToX, vecToY, vecToZ, vecToW; + + // load up the the idJointQuats from joints + v0 = vec_ld( 0, jointPtr ); + v1 = vec_ld( 15, jointPtr ); + v2 = vec_perm( v0, v1, permVec ); + + v3 = vec_ld( 0, jointPtr2 ); + v4 = vec_ld( 15, jointPtr2 ); + v5 = vec_perm( v3, v4, permVec2 ); + + v6 = vec_ld( 0, jointPtr3 ); + v7 = vec_ld( 15, jointPtr3 ); + v8 = vec_perm( v6, v7, permVec3 ); + + v9 = vec_ld( 0, jointPtr4 ); + v10 = vec_ld( 15, jointPtr4 ); + v11 = vec_perm( v9, v10, permVec4 ); + + // planarizing, so put each x y z w into its own vector + v0 = vec_mergeh( v2, v8 ); + v1 = vec_mergeh( v5, v11 ); + v3 = vec_mergel( v2, v8 ); + v4 = vec_mergel( v5, v11 ); + + vecFromX = vec_mergeh( v0, v1 ); + vecFromY = vec_mergel( v0, v1 ); + vecFromZ = vec_mergeh( v3, v4 ); + vecFromW = vec_mergel( v3, v4 ); + + // load up idJointQuats from blendJoints + v5 = vec_ld( 0, blendPtr ); + v6 = vec_ld( 15, blendPtr ); + v7 = vec_perm( v5, v6, permVec5 ); + + v8 = vec_ld( 0, blendPtr2 ); + v9 = vec_ld( 15, blendPtr2 ); + v10 = vec_perm( v8, v9, permVec6 ); + + v11 = vec_ld( 0, blendPtr3 ); + v12 = vec_ld( 15, blendPtr3 ); + v13 = vec_perm( v11, v12, permVec7 ); + + v14 = vec_ld( 0, blendPtr4 ); + v15 = vec_ld( 15, blendPtr4 ); + v16 = vec_perm( v14, v15, permVec8 ); + + // put these into their own vectors too + v5 = vec_mergeh( v7, v13 ); + v6 = vec_mergeh( v10, v16 ); + v8 = vec_mergel( v7, v13 ); + v9 = vec_mergel( v10, v16 ); + + vecToX = vec_mergeh( v5, v6 ); + vecToY = vec_mergel( v5, v6 ); + vecToZ = vec_mergeh( v8, v9 ); + vecToW = vec_mergel( v8, v9 ); + + // calculate cosom + vector float vecCosom = vec_madd( vecFromX, vecToX, (vector float)(0) ); + vecCosom = vec_madd( vecFromY, vecToY, vecCosom ); + vecCosom = vec_madd( vecFromZ, vecToZ, vecCosom ); + vecCosom = vec_madd( vecFromW, vecToW, vecCosom ); + + // if cosom is < 0, negate it and set temp to negated elements in to. otherwise, set temp to + // to + vector bool int vecCmp, vecCmp2; + vecCmp = vec_cmplt( vecCosom, zeroVector ); + + // negate if needed + vecToX = vec_sel( vecToX, vec_madd( vecToX, (vector float)(-1), zeroVector ), vecCmp ); + vecToY = vec_sel( vecToY, vec_madd( vecToY, (vector float)(-1), zeroVector ), vecCmp ); + vecToZ = vec_sel( vecToZ, vec_madd( vecToZ, (vector float)(-1), zeroVector ), vecCmp ); + vecToW = vec_sel( vecToW, vec_madd( vecToW, (vector float)(-1), zeroVector ), vecCmp ); + vecCosom = vec_sel( vecCosom, vec_madd( vecCosom, (vector float)(-1), zeroVector ), vecCmp ); + + // check if we need to calculate scale + vecCmp2 = vec_cmpgt( vec_sub( (vector float)(1), vecCosom ), (vector float)(1e-6f) ); + vector float vecScale0 = vec_sub( (vector float)(1), vecLerp ); + vector float vecScale1 = vec_splat( vecLerp, 0 ); + + vector float vecWork1 = vec_sub( (vector float)(1), vec_madd( vecCosom, vecCosom, zeroVector ) ); + vector float vecWork2 = ReciprocalSquareRoot( vecWork1 ); + vector float vecWork3 = VectorATan16( vec_madd( vecWork1, vecWork2, zeroVector ), vecCosom ); + + vecWork1 = vec_madd( VectorSin16( vec_madd( vecScale0, vecWork3, zeroVector ) ), vecWork2, zeroVector ); + vecWork2 = vec_madd( VectorSin16( vec_madd( vecLerp, vecWork3, zeroVector ) ), vecWork2, zeroVector ); + + // see which ones we have to insert into our scale0 and scale1 vectors + vecScale0 = vec_sel( vecScale0, vecWork1, vecCmp2 ); + vecScale1 = vec_sel( vecScale1, vecWork2, vecCmp2 ); + + // multiply each element by the scale + vecFromX = vec_madd( vecFromX, vecScale0, zeroVector ); + vecFromY = vec_madd( vecFromY, vecScale0, zeroVector ); + vecFromZ = vec_madd( vecFromZ, vecScale0, zeroVector ); + vecFromW = vec_madd( vecFromW, vecScale0, zeroVector ); + + // multiply temp by scale and add to result + vecFromX = vec_madd( vecToX, vecScale1, vecFromX ); + vecFromY = vec_madd( vecToY, vecScale1, vecFromY ); + vecFromZ = vec_madd( vecToZ, vecScale1, vecFromZ ); + vecFromW = vec_madd( vecToW, vecScale1, vecFromW ); + + // do a transform again to get the results back to vectors we can store out + v5 = vec_mergeh( vecFromX, vecFromZ ); + v6 = vec_mergeh( vecFromY, vecFromW ); + v8 = vec_mergel( vecFromX, vecFromZ ); + v9 = vec_mergel( vecFromY, vecFromW ); + + vecToX = vec_mergeh( v5, v6 ); + vecToY = vec_mergel( v5, v6 ); + vecToZ = vec_mergeh( v8, v9 ); + vecToW = vec_mergel( v8, v9 ); + + vector unsigned char storePerm1 = vec_lvsr( 0, jointPtr ); + vector unsigned char storePerm2 = vec_lvsr( 0, jointPtr2 ); + vector unsigned char storePerm3 = vec_lvsr( 0, jointPtr3 ); + vector unsigned char storePerm4 = vec_lvsr( 0, jointPtr4 ); + + // right rotate the input data + vecToX = vec_perm( vecToX, vecToX, storePerm1 ); + vecToY = vec_perm( vecToY, vecToY, storePerm2 ); + vecToZ = vec_perm( vecToZ, vecToZ, storePerm3 ); + vecToW = vec_perm( vecToW, vecToW, storePerm4 ); + + vec_ste( vecToX, 0, (float*) jointPtr ); + vec_ste( vecToX, 4, (float*) jointPtr ); + vec_ste( vecToX, 8, (float*) jointPtr ); + vec_ste( vecToX, 12, (float*) jointPtr ); + + vec_ste( vecToY, 0, (float*) jointPtr2 ); + vec_ste( vecToY, 4, (float*) jointPtr2 ); + vec_ste( vecToY, 8, (float*) jointPtr2 ); + vec_ste( vecToY, 12, (float*) jointPtr2 ); + + vec_ste( vecToZ, 0, (float*) jointPtr3 ); + vec_ste( vecToZ, 4, (float*) jointPtr3 ); + vec_ste( vecToZ, 8, (float*) jointPtr3 ); + vec_ste( vecToZ, 12, (float*) jointPtr3 ); + + vec_ste( vecToW, 0, (float*) jointPtr4 ); + vec_ste( vecToW, 4, (float*) jointPtr4 ); + vec_ste( vecToW, 8, (float*) jointPtr4 ); + vec_ste( vecToW, 12, (float*) jointPtr4 ); + + // lerp is v1 + l * ( v2 - v1 ); + // the idVec3 T is going to be 12 bytes after the Q, so we can do this without calling ToFloatPtr() again. since its + float *jointVecPtr = (float*)( jointPtr + 4 ); + float *jointVecPtr2 = (float*)( jointPtr2 + 4 ); + float *jointVecPtr3 = (float*)( jointPtr3 + 4 ); + float *jointVecPtr4 = (float*)( jointPtr4 + 4 ); + + v0 = vec_ld( 0, jointVecPtr ); + v1 = vec_ld( 11, jointVecPtr ); + vector float vecLd1 = vec_perm( v0, v1, vec_add( vec_lvsl( -1, jointVecPtr ), (vector unsigned char)(1) ) ); + + v2 = vec_ld( 0, jointVecPtr2 ); + v3 = vec_ld( 11, jointVecPtr2 ); + vector float vecLd2 = vec_perm( v2, v3, vec_add( vec_lvsl( -1, jointVecPtr2 ), (vector unsigned char)(1) ) ); + + v4 = vec_ld( 0, jointVecPtr3 ); + v5 = vec_ld( 11, jointVecPtr3 ); + vector float vecLd3 = vec_perm( v4, v5, vec_add( vec_lvsl( -1, jointVecPtr3 ), (vector unsigned char)(1) ) ); + + v6 = vec_ld( 0, jointVecPtr4 ); + v7 = vec_ld( 11, jointVecPtr4 ); + vector float vecLd4 = vec_perm( v6, v7, vec_add( vec_lvsl( -1, jointVecPtr4 ), (vector unsigned char)(1) ) ); + + vector float vecVecX, vecVecY, vecVecZ; + vecVecX = vecVecY = vecVecZ = zeroVector; + + // planarize + v0 = vec_mergeh( vecLd1, vecLd3 ); + v1 = vec_mergeh( vecLd2, vecLd4 ); + v3 = vec_mergel( vecLd1, vecLd3 ); + v4 = vec_mergel( vecLd2, vecLd4 ); + + vecVecX = vec_mergeh( v0, v1 ); + vecVecY = vec_mergel( v0, v1 ); + vecVecZ = vec_mergeh( v3, v4 ); + + // load blend joint idvec3's + float *blendVecPtr = (float*)( blendPtr + 4 ); + float *blendVecPtr2 =(float*)( blendPtr2 + 4 ); + float *blendVecPtr3 = (float*)( blendPtr3 + 4 ); + float *blendVecPtr4 = (float*)( blendPtr4 + 4 ); + + v0 = vec_ld( 0, blendVecPtr ); + v1 = vec_ld( 11, blendVecPtr ); + vector float vecLd5 = vec_perm( v0, v1, vec_add( vec_lvsl( -1, blendVecPtr ), (vector unsigned char)(1) ) ); + + v2 = vec_ld( 0, blendVecPtr2 ); + v3 = vec_ld( 11, blendVecPtr2 ); + vector float vecLd6 = vec_perm( v2, v3, vec_add( vec_lvsl( -1, blendVecPtr2 ), (vector unsigned char)(1) ) ); + + v4 = vec_ld( 0, blendVecPtr3 ); + v5 = vec_ld( 11, blendVecPtr3 ); + vector float vecLd7 = vec_perm( v4, v5, vec_add( vec_lvsl( -1, blendVecPtr3 ), (vector unsigned char)(1) ) ); + + v6 = vec_ld( 0, blendVecPtr4 ); + v7 = vec_ld( 11, blendVecPtr4 ); + vector float vecLd8 = vec_perm( v6, v7, vec_add( vec_lvsl( -1, blendVecPtr4 ), (vector unsigned char)(1) ) ); + + vector float vecBlendX, vecBlendY, vecBlendZ; + vecBlendX = vecBlendY = vecBlendZ = zeroVector; + + // planarize + v0 = vec_mergeh( vecLd5, vecLd7 ); + v1 = vec_mergeh( vecLd6, vecLd8 ); + v3 = vec_mergel( vecLd5, vecLd7 ); + v4 = vec_mergel( vecLd6, vecLd8 ); + + vecBlendX = vec_mergeh( v0, v1 ); + vecBlendY = vec_mergel( v0, v1 ); + vecBlendZ = vec_mergeh( v3, v4 ); + + // do subtraction + vecWork1 = vec_sub( vecBlendX, vecVecX ); + vecWork2 = vec_sub( vecBlendY, vecVecY ); + vecWork3 = vec_sub( vecBlendZ, vecVecZ ); + + // multiply by lerp and add to v1 + vecVecX = vec_madd( vecWork1, vecLerp, vecVecX ); + vecVecY = vec_madd( vecWork2, vecLerp, vecVecY ); + vecVecZ = vec_madd( vecWork3, vecLerp, vecVecZ ); + + // put it back in original form + v0 = vec_mergeh( vecVecX, vecVecZ ); + v1 = vec_mergeh( vecVecY, zeroVector ); + v3 = vec_mergel( vecVecX, vecVecZ ); + v4 = vec_mergel( vecVecY, zeroVector ); + + // generate vectors to store + vecWork1 = vec_mergeh( v0, v1 ); + vecWork2 = vec_mergel( v0, v1 ); + vecWork3 = vec_mergeh( v3, v4 ); + vector float vecWork4 = vec_mergel( v3, v4 ); + + // store the T values + storePerm1 = vec_lvsr( 0, jointVecPtr ); + storePerm2 = vec_lvsr( 0, jointVecPtr2 ); + storePerm3 = vec_lvsr( 0, jointVecPtr3 ); + storePerm4 = vec_lvsr( 0, jointVecPtr4 ); + + // right rotate the input data + vecWork1 = vec_perm( vecWork1, vecWork1, storePerm1 ); + vecWork2 = vec_perm( vecWork2, vecWork2, storePerm2 ); + vecWork3 = vec_perm( vecWork3, vecWork3, storePerm3 ); + vecWork4 = vec_perm( vecWork4, vecWork4, storePerm4 ); + + vec_ste( vecWork1, 0, (float*) jointVecPtr ); + vec_ste( vecWork1, 4, (float*) jointVecPtr ); + vec_ste( vecWork1, 8, (float*) jointVecPtr ); + + vec_ste( vecWork2, 0, (float*) jointVecPtr2 ); + vec_ste( vecWork2, 4, (float*) jointVecPtr2 ); + vec_ste( vecWork2, 8, (float*) jointVecPtr2 ); + + vec_ste( vecWork3, 0, (float*) jointVecPtr3 ); + vec_ste( vecWork3, 4, (float*) jointVecPtr3 ); + vec_ste( vecWork3, 8, (float*) jointVecPtr3 ); + + vec_ste( vecWork4, 0, (float*) jointVecPtr4 ); + vec_ste( vecWork4, 4, (float*) jointVecPtr4 ); + vec_ste( vecWork4, 8, (float*) jointVecPtr4 ); + } + + // cleanup + for ( ; i < numJoints; i++ ) { + int j = index[i]; + joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp ); + joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); + } +} + +/* +============ +idSIMD_AltiVec::ConvertJointQuatsToJointMats +============ +*/ + +// SSE doesn't vectorize this, and I don't think we should either. Its mainly just copying data, there's very little math involved and +// it's not easily parallelizable +void VPCALL idSIMD_AltiVec::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { + + for ( int i = 0; i < numJoints; i++ ) { + + const float *q = jointQuats[i].q.ToFloatPtr(); + float *m = jointMats[i].ToFloatPtr(); + + m[0*4+3] = q[4]; + m[1*4+3] = q[5]; + m[2*4+3] = q[6]; + + float x2 = q[0] + q[0]; + float y2 = q[1] + q[1]; + float z2 = q[2] + q[2]; + + { + float xx = q[0] * x2; + float yy = q[1] * y2; + float zz = q[2] * z2; + + m[0*4+0] = 1.0f - yy - zz; + m[1*4+1] = 1.0f - xx - zz; + m[2*4+2] = 1.0f - xx - yy; + } + + { + float yz = q[1] * z2; + float wx = q[3] * x2; + + m[2*4+1] = yz - wx; + m[1*4+2] = yz + wx; + } + + { + float xy = q[0] * y2; + float wz = q[3] * z2; + + m[1*4+0] = xy - wz; + m[0*4+1] = xy + wz; + } + + { + float xz = q[0] * z2; + float wy = q[3] * y2; + + m[0*4+2] = xz - wy; + m[2*4+0] = xz + wy; + } + } +} + +/* +============ +idSIMD_AltiVec::ConvertJointMatsToJointQuats +============ +*/ +void VPCALL idSIMD_AltiVec::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { + + int index; + + // Since we use very little of the data we have to pull in for the altivec version, we end up with + // a lot of wasted math. Rather than try to force it to use altivec, I wrote an optimized version + // of InvSqrt for the G5, and made it use that instead. With only this change, we get a little + // bigger than 50% speedup, which is not too shabby. Should really replace idMath::InvSqrt with + // my function so everyone can benefit on G5. + + for ( index = 0; index < numJoints; index++ ) { + + idJointQuat jq; + float trace; + float s; + float t; + int i; + int j; + int k; + + static int next[3] = { 1, 2, 0 }; + + float *mat = (float*)( jointMats[index].ToFloatPtr() ); + trace = mat[0 * 4 + 0] + mat[1 * 4 + 1] + mat[2 * 4 + 2]; + + if ( trace > 0.0f ) { + + t = trace + 1.0f; + //s = idMath::InvSqrt( t ) * 0.5f; + s = FastScalarInvSqrt( t ) * 0.5f; + + jq.q[3] = s * t; + jq.q[0] = ( mat[1 * 4 + 2] - mat[2 * 4 + 1] ) * s; + jq.q[1] = ( mat[2 * 4 + 0] - mat[0 * 4 + 2] ) * s; + jq.q[2] = ( mat[0 * 4 + 1] - mat[1 * 4 + 0] ) * s; + + } else { + + i = 0; + if ( mat[1 * 4 + 1] > mat[0 * 4 + 0] ) { + i = 1; + } + if ( mat[2 * 4 + 2] > mat[i * 4 + i] ) { + i = 2; + } + j = next[i]; + k = next[j]; + + t = ( mat[i * 4 + i] - ( mat[j * 4 + j] + mat[k * 4 + k] ) ) + 1.0f; + //s = idMath::InvSqrt( t ) * 0.5f; + s = FastScalarInvSqrt( t ) * 0.5f; + + jq.q[i] = s * t; + jq.q[3] = ( mat[j * 4 + k] - mat[k * 4 + j] ) * s; + jq.q[j] = ( mat[i * 4 + j] + mat[j * 4 + i] ) * s; + jq.q[k] = ( mat[i * 4 + k] + mat[k * 4 + i] ) * s; + } + + jq.t[0] = mat[0 * 4 + 3]; + jq.t[1] = mat[1 * 4 + 3]; + jq.t[2] = mat[2 * 4 + 3]; + jointQuats[index] = jq; + } +} + +/* +============ +idSIMD_AltiVec::TransformJoints +============ +*/ +void VPCALL idSIMD_AltiVec::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { + int i; +#if 0 + for( i = firstJoint; i <= lastJoint; i++ ) { + assert( parents[i] < i ); + jointMats[i] *= jointMats[parents[i]]; + } +#else + + // I don't think you can unroll this since the next iteration of the loop might depending on the previous iteration, depending + // on what the parents array looks like. This is true in the test code. + for ( i = firstJoint; i <= lastJoint; i++ ) { + assert( parents[i] < i ); + float *jointPtr = jointMats[i].ToFloatPtr(); + float *parentPtr = jointMats[parents[i]].ToFloatPtr(); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); + vector unsigned char permVec2 = vec_add( vec_lvsl( -1, parentPtr ), (vector unsigned char)(1) ); + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + // we need to load up 12 float elements that make up the Mat + v0 = vec_ld( 0, jointPtr ); + v1 = vec_ld( 15, jointPtr ); + v2 = vec_ld( 31, jointPtr ); + v3 = vec_ld( 47, jointPtr ); + + // load parents + v4 = vec_ld( 0, parentPtr ); + v5 = vec_ld( 15, parentPtr ); + v6 = vec_ld( 31, parentPtr ); + v7 = vec_ld( 47, parentPtr ); + + // permute into vectors + vector float vecJointMat1 = vec_perm( v0, v1, permVec ); + vector float vecJointMat2 = vec_perm( v1, v2, permVec ); + vector float vecJointMat3 = vec_perm( v2, v3, permVec ); + + vector float vecParentMat1 = vec_perm( v4, v5, permVec2 ); + vector float vecParentMat2 = vec_perm( v5, v6, permVec2 ); + vector float vecParentMat3 = vec_perm( v6, v7, permVec2 ); + + vector float zero = (vector float)(0); + vector float C1, C2, C3; + + // matrix multiply + C1 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 0 ), zero ); // m(0 to 3) * a(0) + C2 = vec_madd( vecJointMat1, vec_splat( vecParentMat2, 0 ), zero ); // m(4 to 7) * a(4) + C3 = vec_madd( vecJointMat1, vec_splat( vecParentMat3, 0 ), zero ); // m(8 to 11) * a(8) + + C1 = vec_madd( vecJointMat2, vec_splat( vecParentMat1, 1 ), C1 ); // add in m(4 to 7) * a(1) + C2 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 1 ), C2 ); // add in m(4 to 7) * a(5) + C3 = vec_madd( vecJointMat2, vec_splat( vecParentMat3, 1 ), C3 ); // add in m(4 to 7) * a(9) + + C1 = vec_madd( vecJointMat3, vec_splat( vecParentMat1, 2 ), C1 ); + C2 = vec_madd( vecJointMat3, vec_splat( vecParentMat2, 2 ), C2 ); + C3 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 2 ), C3 ); + + // do the addition at the end + vector unsigned char permZeroAndLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,28,29,30,31); + C1 = vec_add( C1, vec_perm( zero, vecParentMat1, permZeroAndLast ) ); + C2 = vec_add( C2, vec_perm( zero, vecParentMat2, permZeroAndLast ) ); + C3 = vec_add( C3, vec_perm( zero, vecParentMat3, permZeroAndLast ) ); + + // store results + UNALIGNED_STORE3( (float*) jointPtr, C1, C2, C3 ); + } +#endif +} + +/* +============ +idSIMD_AltiVec::UntransformJoints +============ +*/ +void VPCALL idSIMD_AltiVec::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { + int i; +#if 0 + for( i = lastJoint; i >= firstJoint; i-- ) { + assert( parents[i] < i ); + jointMats[i] /= jointMats[parents[i]]; + } +#else + // I don't think you can unroll this since the next iteration of the loop might depending on the previous iteration, depending + // on what the parents array looks like. This is true in the test code. + for ( i = lastJoint; i >= firstJoint; i-- ) { + assert( parents[i] < i ); + float *jointPtr = jointMats[i].ToFloatPtr(); + float *parentPtr = jointMats[parents[i]].ToFloatPtr(); + + vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); + vector unsigned char permVec2 = vec_add( vec_lvsl( -1, parentPtr ), (vector unsigned char)(1) ); + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + // we need to load up 12 float elements that make up the Mat + v0 = vec_ld( 0, jointPtr ); + v1 = vec_ld( 15, jointPtr ); + v2 = vec_ld( 31, jointPtr ); + v3 = vec_ld( 47, jointPtr ); + + // load parents + v4 = vec_ld( 0, parentPtr ); + v5 = vec_ld( 15, parentPtr ); + v6 = vec_ld( 31, parentPtr ); + v7 = vec_ld( 47, parentPtr ); + + // permute into vectors + vector float vecJointMat1 = vec_perm( v0, v1, permVec ); + vector float vecJointMat2 = vec_perm( v1, v2, permVec ); + vector float vecJointMat3 = vec_perm( v2, v3, permVec ); + + vector float vecParentMat1 = vec_perm( v4, v5, permVec2 ); + vector float vecParentMat2 = vec_perm( v5, v6, permVec2 ); + vector float vecParentMat3 = vec_perm( v6, v7, permVec2 ); + + vector float zero = (vector float)(0); + vector float C1, C2, C3; + + // do subtraction at the beginning + vector unsigned char permZeroAndLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,28,29,30,31); + vecJointMat1 = vec_sub( vecJointMat1, vec_perm( zero, vecParentMat1, permZeroAndLast ) ); + vecJointMat2 = vec_sub( vecJointMat2, vec_perm( zero, vecParentMat2, permZeroAndLast ) ); + vecJointMat3 = vec_sub( vecJointMat3, vec_perm( zero, vecParentMat3, permZeroAndLast ) ); + + // matrix multiply + C1 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 0 ), zero ); + C2 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 1 ), zero ); + C3 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 2 ), zero ); + + C1 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 0 ), C1 ); + C2 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 1 ), C2 ); + C3 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 2 ), C3 ); + + C1 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 0 ), C1 ); + C2 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 1 ), C2 ); + C3 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 2 ), C3 ); + + // store results back + vector unsigned char storePerm = vec_lvsr( 0, jointPtr ); + + // right rotate the input data + C1 = vec_perm( C1, C1, storePerm ); + C2 = vec_perm( C2, C2, storePerm ); + C3 = vec_perm( C3, C3, storePerm ); + + vec_ste( C1, 0, (float*) jointPtr ); + vec_ste( C1, 4, (float*) jointPtr ); + vec_ste( C1, 8, (float*) jointPtr ); + vec_ste( C1, 12, (float*) jointPtr ); + + vec_ste( C2, 16, (float*) jointPtr ); + vec_ste( C2, 20, (float*) jointPtr ); + vec_ste( C2, 24, (float*) jointPtr ); + vec_ste( C2, 28, (float*) jointPtr ); + + vec_ste( C3, 32, (float*) jointPtr ); + vec_ste( C3, 36, (float*) jointPtr ); + vec_ste( C3, 40, (float*) jointPtr ); + vec_ste( C3, 44, (float*) jointPtr ); + } + +#endif +} + +/* +============ +idSIMD_AltiVec::TransformVerts +============ +*/ + +// Here we don't have much for the vector unit to do, and the gain we get from doing the math +// in parallel is eaten by doing unaligned stores. +void VPCALL idSIMD_AltiVec::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, int numWeights ) { + int i, j; + const byte *jointsPtr = (byte *)joints; + + for( j = i = 0; i < numVerts; i++ ) { + idVec3 v; + + float *matPtrOrig = ( *(idJointMat *)( jointsPtr + index[j*2] ) ).ToFloatPtr(); + float *weightPtr = (float*) weights[j].ToFloatPtr(); + + v[0] = matPtrOrig[0] * weightPtr[0]; + v[0] += matPtrOrig[1] * weightPtr[1]; + v[0] += matPtrOrig[2] * weightPtr[2]; + v[0] += matPtrOrig[3] * weightPtr[3]; + + v[1] = matPtrOrig[4] * weightPtr[0]; + v[1] += matPtrOrig[5] * weightPtr[1]; + v[1] += matPtrOrig[6] * weightPtr[2]; + v[1] += matPtrOrig[7] * weightPtr[3]; + + v[2] = matPtrOrig[8] * weightPtr[0]; + v[2] += matPtrOrig[9] * weightPtr[1]; + v[2] += matPtrOrig[10] * weightPtr[2]; + v[2] += matPtrOrig[11] * weightPtr[3]; + + while( index[j*2+1] == 0 ) { + j++; + float *matPtr = ( *(idJointMat *)( jointsPtr + index[j*2] ) ).ToFloatPtr(); + weightPtr = (float*) weights[j].ToFloatPtr(); + + v[0] += matPtr[0] * weightPtr[0]; + v[0] += matPtr[1] * weightPtr[1]; + v[0] += matPtr[2] * weightPtr[2]; + v[0] += matPtr[3] * weightPtr[3]; + + v[1] += matPtr[4] * weightPtr[0]; + v[1] += matPtr[5] * weightPtr[1]; + v[1] += matPtr[6] * weightPtr[2]; + v[1] += matPtr[7] * weightPtr[3]; + + v[2] += matPtr[8] * weightPtr[0]; + v[2] += matPtr[9] * weightPtr[1]; + v[2] += matPtr[10] * weightPtr[2]; + v[2] += matPtr[11] * weightPtr[3]; + } + j++; + + verts[i].xyz = v; + } +} +#endif /* LIVE_VICARIOUSLY */ + +#ifdef ENABLE_CULL + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::TracePointCull +============ +*/ +void VPCALL idSIMD_AltiVec::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + byte tOr; + tOr = 0; + + // pointers + const float *planePtr = planes[0].ToFloatPtr(); + + vector unsigned int vecShift1 = (vector unsigned int)(0,1,2,3); + vector unsigned int vecShift2 = (vector unsigned int)(4,5,6,7); + vector unsigned int vecFlipBits = (vector unsigned int)(0x0F); + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; + vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; + vector unsigned char vecPerm; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + vector float zeroVector = (vector float)(0); + vector float vecRadius; + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector float vec1Sum1, vec1Sum2, vec1Sum3, vec1Sum4; + vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + vector float vecDPlusRadius1, vecDPlusRadius2, vecDPlusRadius3, vecDPlusRadius4; + vector float vecDMinusRadius1, vecDMinusRadius2, vecDMinusRadius3, vecDMinusRadius4; + vector bool int oneIntVector = (vector bool int)(1); + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4, vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; + vector unsigned int vecTotals; + vector unsigned int tempIntSum; + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + + // populate planes + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 4 ); + v3 = vec_ld( 15, planePtr + 4 ); + vecPlane1 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 8 ); + v1 = vec_ld( 15, planePtr + 8 ); + vecPlane2 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 12 ); + v3 = vec_ld( 15, planePtr + 12 ); + vecPlane3 = vec_perm( v2, v3, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane2 ); + v1 = vec_mergeh( vecPlane1, vecPlane3 ); + v2 = vec_mergel( vecPlane0, vecPlane2 ); + v3 = vec_mergel( vecPlane1, vecPlane3 ); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + // load constants + vecRadius = loadSplatUnalignedScalar( &radius ); + + unsigned int cullBitVal[4]; + vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); + int i = 0; + + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < numVerts ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } + + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); + vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); + vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); + vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); + + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); + vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); + + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec1Sum2 ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec1Sum2 ); + vec1Sum2 = vec_add( vec1Sum2, vecPlane3 ); + + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec1Sum3 ); + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec1Sum3 ); + vec1Sum3 = vec_add( vec1Sum3, vecPlane3 ); + + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec1Sum4 ); + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec1Sum4 ); + vec1Sum4 = vec_add( vec1Sum4, vecPlane3 ); + + // vec1Sum1 now holds d0, d1, d2, d3. calculate the + // difference with +radius and -radius + vecDPlusRadius1 = vec_add( vec1Sum1, vecRadius ); + vecDMinusRadius1 = vec_sub( vec1Sum1, vecRadius ); + vecDPlusRadius2 = vec_add( vec1Sum2, vecRadius ); + vecDMinusRadius2 = vec_sub( vec1Sum2, vecRadius ); + vecDPlusRadius3 = vec_add( vec1Sum3, vecRadius ); + vecDMinusRadius3 = vec_sub( vec1Sum3, vecRadius ); + vecDPlusRadius4 = vec_add( vec1Sum4, vecRadius ); + vecDMinusRadius4 = vec_sub( vec1Sum4, vecRadius ); + + // do compare + vecCmp1 = vec_cmplt( vecDPlusRadius1, zeroVector ); + vecCmp2 = vec_cmplt( vecDMinusRadius1, zeroVector ); + vecCmp3 = vec_cmplt( vecDPlusRadius2, zeroVector ); + vecCmp4 = vec_cmplt( vecDMinusRadius2, zeroVector ); + vecCmp5 = vec_cmplt( vecDPlusRadius3, zeroVector ); + vecCmp6 = vec_cmplt( vecDMinusRadius3, zeroVector ); + vecCmp7 = vec_cmplt( vecDPlusRadius4, zeroVector ); + vecCmp8 = vec_cmplt( vecDMinusRadius4, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + vecCmp3 = vec_and( vecCmp3, oneIntVector ); + vecCmp4 = vec_and( vecCmp4, oneIntVector ); + vecCmp5 = vec_and( vecCmp5, oneIntVector ); + vecCmp6 = vec_and( vecCmp6, oneIntVector ); + vecCmp7 = vec_and( vecCmp7, oneIntVector ); + vecCmp8 = vec_and( vecCmp8, oneIntVector ); + + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); + vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); + vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); + vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); + vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); + vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); + vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); + + // OR (add) them all together + vecBitShifted1 = vec_add( vecBitShifted1, vecBitShifted2 ); + vecBitShifted3 = vec_add( vecBitShifted3, vecBitShifted4 ); + vecBitShifted5 = vec_add( vecBitShifted5, vecBitShifted6 ); + vecBitShifted7 = vec_add( vecBitShifted7, vecBitShifted8 ); + + vecTotals = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); + vecTotals = vec_add( vecTotals, vec_sld( vecTotals, vecTotals, 4 ) ); + tempIntSum = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_mergeh( vecTotals, tempIntSum ); + tempIntSum = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_perm( vecTotals, tempIntSum, vecPermHalves ); + tempIntSum = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_perm( vecTotals, tempIntSum, vecPermLast ); + + // store out results + vector unsigned int tempSt = vec_xor( vecTotals, vecFlipBits ); + tempSt = vec_perm( tempSt, tempSt, cullBitPerm ); + vec_ste( tempSt, 0, &cullBitVal[0] ); + vec_ste( tempSt, 4, &cullBitVal[0] ); + vec_ste( tempSt, 8, &cullBitVal[0] ); + vec_ste( tempSt, 12, &cullBitVal[0] ); + + tOr |= cullBitVal[0]; + tOr |= cullBitVal[1]; + tOr |= cullBitVal[2]; + tOr |= cullBitVal[3]; + + cullBits[i] = cullBitVal[0]; + cullBits[i+1] = cullBitVal[1]; + cullBits[i+2] = cullBitVal[2]; + cullBits[i+3] = cullBitVal[3]; + } + + // cleanup + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, t; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + + t = d0 + radius; + bits = FLOATSIGNBITSET( t ) << 0; + t = d1 + radius; + bits |= FLOATSIGNBITSET( t ) << 1; + t = d2 + radius; + bits |= FLOATSIGNBITSET( t ) << 2; + t = d3 + radius; + bits |= FLOATSIGNBITSET( t ) << 3; + + t = d0 - radius; + bits |= FLOATSIGNBITSET( t ) << 4; + t = d1 - radius; + bits |= FLOATSIGNBITSET( t ) << 5; + t = d2 - radius; + bits |= FLOATSIGNBITSET( t ) << 6; + t = d3 - radius; + bits |= FLOATSIGNBITSET( t ) << 7; + + bits ^= 0x0F; // flip lower four bits + + tOr |= bits; + cullBits[i] = bits; + } + + totalOr = tOr; +} +#else + +/* +============ +idSIMD_AltiVec::TracePointCull +============ +*/ +void VPCALL idSIMD_AltiVec::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + byte tOr; + tOr = 0; + + // pointers + const float *planePtr = planes[0].ToFloatPtr(); + + vector unsigned int vecShift1 = (vector unsigned int)(0,1,2,3); + vector unsigned int vecShift2 = (vector unsigned int)(4,5,6,7); + vector unsigned int vecFlipBits = (vector unsigned int)(0x0F); + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; + vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; + vector unsigned char vecPerm; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + vector float zeroVector = (vector float)(0); + vector float vecRadius; + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector float vec1Sum1, vec1Sum2, vec1Sum3, vec1Sum4; + vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + vector float vecDPlusRadius1, vecDPlusRadius2, vecDPlusRadius3, vecDPlusRadius4; + vector float vecDMinusRadius1, vecDMinusRadius2, vecDMinusRadius3, vecDMinusRadius4; + vector bool int oneIntVector = (vector bool int)(1); + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4, vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; + vector unsigned int vecTotals; + vector unsigned int tempIntSum; + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + + // populate planes + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 4 ); + v3 = vec_ld( 15, planePtr + 4 ); + vecPlane1 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 8 ); + v1 = vec_ld( 15, planePtr + 8 ); + vecPlane2 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 12 ); + v3 = vec_ld( 15, planePtr + 12 ); + vecPlane3 = vec_perm( v2, v3, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane2 ); + v1 = vec_mergeh( vecPlane1, vecPlane3 ); + v2 = vec_mergel( vecPlane0, vecPlane2 ); + v3 = vec_mergel( vecPlane1, vecPlane3 ); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + // load constants + vecRadius = loadSplatUnalignedScalar( &radius ); + + unsigned int cullBitVal[4]; + vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); + int i = 0; + + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + vecXYZ1 = vec_ld( 0, vertPtr ); + vecXYZ2 = vec_ld( 0, vertPtr2 ); + vecXYZ3 = vec_ld( 0, vertPtr3 ); + vecXYZ4 = vec_ld( 0, vertPtr4 ); + + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); + vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); + + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec1Sum2 ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec1Sum2 ); + vec1Sum2 = vec_add( vec1Sum2, vecPlane3 ); + + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec1Sum3 ); + vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec1Sum3 ); + vec1Sum3 = vec_add( vec1Sum3, vecPlane3 ); + + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec1Sum4 ); + vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec1Sum4 ); + vec1Sum4 = vec_add( vec1Sum4, vecPlane3 ); + + // vec1Sum1 now holds d0, d1, d2, d3. calculate the + // difference with +radius and -radius + vecDPlusRadius1 = vec_add( vec1Sum1, vecRadius ); + vecDMinusRadius1 = vec_sub( vec1Sum1, vecRadius ); + vecDPlusRadius2 = vec_add( vec1Sum2, vecRadius ); + vecDMinusRadius2 = vec_sub( vec1Sum2, vecRadius ); + vecDPlusRadius3 = vec_add( vec1Sum3, vecRadius ); + vecDMinusRadius3 = vec_sub( vec1Sum3, vecRadius ); + vecDPlusRadius4 = vec_add( vec1Sum4, vecRadius ); + vecDMinusRadius4 = vec_sub( vec1Sum4, vecRadius ); + + // do compare + vecCmp1 = vec_cmplt( vecDPlusRadius1, zeroVector ); + vecCmp2 = vec_cmplt( vecDMinusRadius1, zeroVector ); + vecCmp3 = vec_cmplt( vecDPlusRadius2, zeroVector ); + vecCmp4 = vec_cmplt( vecDMinusRadius2, zeroVector ); + vecCmp5 = vec_cmplt( vecDPlusRadius3, zeroVector ); + vecCmp6 = vec_cmplt( vecDMinusRadius3, zeroVector ); + vecCmp7 = vec_cmplt( vecDPlusRadius4, zeroVector ); + vecCmp8 = vec_cmplt( vecDMinusRadius4, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + vecCmp3 = vec_and( vecCmp3, oneIntVector ); + vecCmp4 = vec_and( vecCmp4, oneIntVector ); + vecCmp5 = vec_and( vecCmp5, oneIntVector ); + vecCmp6 = vec_and( vecCmp6, oneIntVector ); + vecCmp7 = vec_and( vecCmp7, oneIntVector ); + vecCmp8 = vec_and( vecCmp8, oneIntVector ); + + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); + vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); + vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); + vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); + vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); + vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); + vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); + + // OR (add) them all together + vecBitShifted1 = vec_add( vecBitShifted1, vecBitShifted2 ); + vecBitShifted3 = vec_add( vecBitShifted3, vecBitShifted4 ); + vecBitShifted5 = vec_add( vecBitShifted5, vecBitShifted6 ); + vecBitShifted7 = vec_add( vecBitShifted7, vecBitShifted8 ); + + vecTotals = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); + vecTotals = vec_add( vecTotals, vec_sld( vecTotals, vecTotals, 4 ) ); + tempIntSum = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_mergeh( vecTotals, tempIntSum ); + tempIntSum = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_perm( vecTotals, tempIntSum, vecPermHalves ); + tempIntSum = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); + tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); + vecTotals = vec_perm( vecTotals, tempIntSum, vecPermLast ); + + // store out results + vector unsigned int tempSt = vec_xor( vecTotals, vecFlipBits ); + tempSt = vec_perm( tempSt, tempSt, cullBitPerm ); + vec_ste( tempSt, 0, &cullBitVal[0] ); + vec_ste( tempSt, 4, &cullBitVal[0] ); + vec_ste( tempSt, 8, &cullBitVal[0] ); + vec_ste( tempSt, 12, &cullBitVal[0] ); + + tOr |= cullBitVal[0]; + tOr |= cullBitVal[1]; + tOr |= cullBitVal[2]; + tOr |= cullBitVal[3]; + + cullBits[i] = cullBitVal[0]; + cullBits[i+1] = cullBitVal[1]; + cullBits[i+2] = cullBitVal[2]; + cullBits[i+3] = cullBitVal[3]; + } + + // cleanup + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, t; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + + t = d0 + radius; + bits = FLOATSIGNBITSET( t ) << 0; + t = d1 + radius; + bits |= FLOATSIGNBITSET( t ) << 1; + t = d2 + radius; + bits |= FLOATSIGNBITSET( t ) << 2; + t = d3 + radius; + bits |= FLOATSIGNBITSET( t ) << 3; + + t = d0 - radius; + bits |= FLOATSIGNBITSET( t ) << 4; + t = d1 - radius; + bits |= FLOATSIGNBITSET( t ) << 5; + t = d2 - radius; + bits |= FLOATSIGNBITSET( t ) << 6; + t = d3 - radius; + bits |= FLOATSIGNBITSET( t ) << 7; + + bits ^= 0x0F; // flip lower four bits + + tOr |= bits; + cullBits[i] = bits; + } + + totalOr = tOr; +} + +#endif /* DRAWVERT_PADDED */ + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::DecalPointCull +============ +*/ +void VPCALL idSIMD_AltiVec::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + int i; + const float *planePtr = planes[0].ToFloatPtr(); + + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3, vecPlane4, vecPlane5, vecPlane6, vecPlane7; + vector float zeroVector = (vector float)(0.0); + vector unsigned char vecPerm; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + + // populate planes + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 4 ); + v3 = vec_ld( 15, planePtr + 4 ); + vecPlane1 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 8 ); + v1 = vec_ld( 15, planePtr + 8 ); + vecPlane2 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 12 ); + v3 = vec_ld( 15, planePtr + 12 ); + vecPlane3 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 16 ); + v1 = vec_ld( 15, planePtr + 16 ); + vecPlane4 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 20 ); + v3 = vec_ld( 15, planePtr + 20 ); + vecPlane5 = vec_perm( v2, v3, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane2 ); + v1 = vec_mergeh( vecPlane1, vecPlane3 ); + v2 = vec_mergel( vecPlane0, vecPlane2 ); + v3 = vec_mergel( vecPlane1, vecPlane3 ); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + v0 = vec_mergeh( vecPlane4, zeroVector ); + v1 = vec_mergeh( vecPlane5, zeroVector ); + v2 = vec_mergel( vecPlane4, zeroVector ); + v3 = vec_mergel( vecPlane5, zeroVector ); + + vecPlane4 = vec_mergeh( v0, v1 ); + vecPlane5 = vec_mergel( v0, v1 ); + vecPlane6 = vec_mergeh( v2, v3 ); + vecPlane7 = vec_mergel( v2, v3 ); + + + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector bool int oneIntVector = (vector bool int)(1); + vector float vec1Sum1, vec1Sum2, vec2Sum1, vec2Sum2, vec3Sum1, vec3Sum2, vec4Sum1, vec4Sum2; + vector unsigned int vecShift1 = (vector unsigned int)(0, 1, 2, 3 ); + vector unsigned int vecShift2 = (vector unsigned int)(4, 5, 0, 0 ); + + vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4; + vector unsigned int vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; + vector unsigned int vecFlipBits = (vector unsigned int)( 0x3F, 0x3F, 0x3F, 0x3F ); + vector unsigned int vecR1, vecR2, vecR3, vecR4; + vector unsigned char permHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + unsigned int vBits[4]; + vector unsigned char vBitPerm = vec_lvsr( 0, &vBits[4] ); + + i = 0; + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < numVerts ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } + + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); + vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); + vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); + vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); + + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); + vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); + + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane4, zeroVector ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane5, vec1Sum2 ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane6, vec1Sum2 ); + vec1Sum2 = vec_add( vec1Sum2, vecPlane7 ); + + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec2Sum1 ); + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec2Sum1 ); + vec2Sum1 = vec_add( vec2Sum1, vecPlane3 ); + + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane4, zeroVector ); + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane5, vec2Sum2 ); + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane6, vec2Sum2 ); + vec2Sum2 = vec_add( vec2Sum2, vecPlane7 ); + + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec3Sum1 ); + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec3Sum1 ); + vec3Sum1 = vec_add( vec3Sum1, vecPlane3 ); + + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane4, zeroVector ); + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane5, vec3Sum2 ); + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane6, vec3Sum2 ); + vec3Sum2 = vec_add( vec3Sum2, vecPlane7 ); + + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec4Sum1 ); + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec4Sum1 ); + vec4Sum1 = vec_add( vec4Sum1, vecPlane3 ); + + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane4, zeroVector ); + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane5, vec4Sum2 ); + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane6, vec4Sum2 ); + vec4Sum2 = vec_add( vec4Sum2, vecPlane7 ); + + vecCmp1 = vec_cmplt( vec1Sum1, zeroVector ); + vecCmp2 = vec_cmplt( vec1Sum2, zeroVector ); + vecCmp3 = vec_cmplt( vec2Sum1, zeroVector ); + vecCmp4 = vec_cmplt( vec2Sum2, zeroVector ); + vecCmp5 = vec_cmplt( vec3Sum1, zeroVector ); + vecCmp6 = vec_cmplt( vec3Sum2, zeroVector ); + vecCmp7 = vec_cmplt( vec4Sum1, zeroVector ); + vecCmp8 = vec_cmplt( vec4Sum2, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + vecCmp3 = vec_and( vecCmp3, oneIntVector ); + vecCmp4 = vec_and( vecCmp4, oneIntVector ); + vecCmp5 = vec_and( vecCmp5, oneIntVector ); + vecCmp6 = vec_and( vecCmp6, oneIntVector ); + vecCmp7 = vec_and( vecCmp7, oneIntVector ); + vecCmp8 = vec_and( vecCmp8, oneIntVector ); + + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); + vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); + vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); + vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); + vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); + vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); + vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); + + //OR them all together (this is the same as adding them, since they're all only 1 bit set) + vecR1 = (vector unsigned int)(0); //zeroIntVector; + vecR1 = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); + vecR1 = vec_add( vecR1, vec_sld( vecR1, vecR1, 4 ) ); + vecR1 = vec_add(vecR1, vecBitShifted2 ); + vecR1 = vec_or( vecR1, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); + + vecR2 = (vector unsigned int)(0); //zeroIntVector; + vecR2 = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); + vecR2 = vec_add( vecR2, vec_sld( vecR2, vecR2, 4 ) ); + vecR2 = vec_add(vecR2, vecBitShifted4 ); + vecR2 = vec_or( vecR2, vec_sld( vecBitShifted4, vecBitShifted4, 4 ) ); + + vecR3 = (vector unsigned int)(0); //zeroIntVector; + vecR3 = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); + vecR3 = vec_add( vecR3, vec_sld( vecR3, vecR3, 4 ) ); + vecR3 = vec_add(vecR3, vecBitShifted6 ); + vecR3 = vec_or( vecR3, vec_sld( vecBitShifted6, vecBitShifted6, 4 ) ); + + vecR4 = (vector unsigned int)(0); //zeroIntVector; + vecR4 = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); + vecR4 = vec_add( vecR4, vec_sld( vecR4, vecR4, 4 ) ); + vecR4 = vec_add(vecR4, vecBitShifted8 ); + vecR4 = vec_or( vecR4, vec_sld( vecBitShifted8, vecBitShifted8, 4 ) ); + + // take the first element from each vector and put them into vecR1 + vecR1 = vec_mergeh( vecR1, vecR2 ); + vecR3 = vec_mergeh( vecR3, vecR4 ); + vecR1 = vec_perm( vecR1, vecR3, permHalves ); + + // XOR with 0x3F to flip lower 6 bits + vecR1 = vec_xor( vecR1, vecFlipBits ); + + // store out results. don't have 16 at a time so let's just + // do this and avoid alignment concerns + vecR1 = vec_perm( vecR1, vecR1, vBitPerm ); + vec_ste( vecR1, 0, &vBits[0] ); + vec_ste( vecR1, 4, &vBits[0] ); + vec_ste( vecR1, 8, &vBits[0] ); + vec_ste( vecR1, 12, &vBits[0] ); + + cullBits[i] = vBits[0]; + cullBits[i+1] = vBits[1]; + cullBits[i+2] = vBits[2]; + cullBits[i+3] = vBits[3]; + } + + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, d4, d5; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + d4 = planes[4].Distance( v ); + d5 = planes[5].Distance( v ); + + // they check if the sign bit is set by casting as long and shifting right 31 places. + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + bits |= FLOATSIGNBITSET( d2 ) << 2; + bits |= FLOATSIGNBITSET( d3 ) << 3; + bits |= FLOATSIGNBITSET( d4 ) << 4; + bits |= FLOATSIGNBITSET( d5 ) << 5; + + cullBits[i] = bits ^ 0x3F; // flip lower 6 bits + } +} + +#else + +/* +============ +idSIMD_AltiVec::DecalPointCull +============ +*/ +void VPCALL idSIMD_AltiVec::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + int i; + const float *planePtr = planes[0].ToFloatPtr(); + + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3, vecPlane4, vecPlane5, vecPlane6, vecPlane7; + vector float zeroVector = (vector float)(0.0); + vector unsigned char vecPerm; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + + // populate planes + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 4 ); + v3 = vec_ld( 15, planePtr + 4 ); + vecPlane1 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 8 ); + v1 = vec_ld( 15, planePtr + 8 ); + vecPlane2 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 12 ); + v3 = vec_ld( 15, planePtr + 12 ); + vecPlane3 = vec_perm( v2, v3, vecPerm ); + + v0 = vec_ld( 0, planePtr + 16 ); + v1 = vec_ld( 15, planePtr + 16 ); + vecPlane4 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 0, planePtr + 20 ); + v3 = vec_ld( 15, planePtr + 20 ); + vecPlane5 = vec_perm( v2, v3, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane2 ); + v1 = vec_mergeh( vecPlane1, vecPlane3 ); + v2 = vec_mergel( vecPlane0, vecPlane2 ); + v3 = vec_mergel( vecPlane1, vecPlane3 ); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + v0 = vec_mergeh( vecPlane4, zeroVector ); + v1 = vec_mergeh( vecPlane5, zeroVector ); + v2 = vec_mergel( vecPlane4, zeroVector ); + v3 = vec_mergel( vecPlane5, zeroVector ); + + vecPlane4 = vec_mergeh( v0, v1 ); + vecPlane5 = vec_mergel( v0, v1 ); + vecPlane6 = vec_mergeh( v2, v3 ); + vecPlane7 = vec_mergel( v2, v3 ); + + + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector bool int oneIntVector = (vector bool int)(1); + vector float vec1Sum1, vec1Sum2, vec2Sum1, vec2Sum2, vec3Sum1, vec3Sum2, vec4Sum1, vec4Sum2; + vector unsigned int vecShift1 = (vector unsigned int)(0, 1, 2, 3 ); + vector unsigned int vecShift2 = (vector unsigned int)(4, 5, 0, 0 ); + + vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4; + vector unsigned int vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; + vector unsigned int vecFlipBits = (vector unsigned int)( 0x3F, 0x3F, 0x3F, 0x3F ); + vector unsigned int vecR1, vecR2, vecR3, vecR4; + vector unsigned char permHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + unsigned int vBits[4]; + vector unsigned char vBitPerm = vec_lvsr( 0, &vBits[4] ); + + i = 0; + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); + vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); + vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); + + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane4, zeroVector ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane5, vec1Sum2 ); + vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane6, vec1Sum2 ); + vec1Sum2 = vec_add( vec1Sum2, vecPlane7 ); + + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec2Sum1 ); + vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec2Sum1 ); + vec2Sum1 = vec_add( vec2Sum1, vecPlane3 ); + + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane4, zeroVector ); + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane5, vec2Sum2 ); + vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane6, vec2Sum2 ); + vec2Sum2 = vec_add( vec2Sum2, vecPlane7 ); + + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec3Sum1 ); + vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec3Sum1 ); + vec3Sum1 = vec_add( vec3Sum1, vecPlane3 ); + + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane4, zeroVector ); + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane5, vec3Sum2 ); + vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane6, vec3Sum2 ); + vec3Sum2 = vec_add( vec3Sum2, vecPlane7 ); + + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec4Sum1 ); + vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec4Sum1 ); + vec4Sum1 = vec_add( vec4Sum1, vecPlane3 ); + + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane4, zeroVector ); + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane5, vec4Sum2 ); + vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane6, vec4Sum2 ); + vec4Sum2 = vec_add( vec4Sum2, vecPlane7 ); + + vecCmp1 = vec_cmplt( vec1Sum1, zeroVector ); + vecCmp2 = vec_cmplt( vec1Sum2, zeroVector ); + vecCmp3 = vec_cmplt( vec2Sum1, zeroVector ); + vecCmp4 = vec_cmplt( vec2Sum2, zeroVector ); + vecCmp5 = vec_cmplt( vec3Sum1, zeroVector ); + vecCmp6 = vec_cmplt( vec3Sum2, zeroVector ); + vecCmp7 = vec_cmplt( vec4Sum1, zeroVector ); + vecCmp8 = vec_cmplt( vec4Sum2, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + vecCmp3 = vec_and( vecCmp3, oneIntVector ); + vecCmp4 = vec_and( vecCmp4, oneIntVector ); + vecCmp5 = vec_and( vecCmp5, oneIntVector ); + vecCmp6 = vec_and( vecCmp6, oneIntVector ); + vecCmp7 = vec_and( vecCmp7, oneIntVector ); + vecCmp8 = vec_and( vecCmp8, oneIntVector ); + + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); + vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); + vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); + vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); + vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); + vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); + vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); + + //OR them all together (this is the same as adding them, since they're all only 1 bit set) + vecR1 = (vector unsigned int)(0); //zeroIntVector; + vecR1 = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); + vecR1 = vec_add( vecR1, vec_sld( vecR1, vecR1, 4 ) ); + vecR1 = vec_add(vecR1, vecBitShifted2 ); + vecR1 = vec_or( vecR1, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); + + vecR2 = (vector unsigned int)(0); //zeroIntVector; + vecR2 = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); + vecR2 = vec_add( vecR2, vec_sld( vecR2, vecR2, 4 ) ); + vecR2 = vec_add(vecR2, vecBitShifted4 ); + vecR2 = vec_or( vecR2, vec_sld( vecBitShifted4, vecBitShifted4, 4 ) ); + + vecR3 = (vector unsigned int)(0); //zeroIntVector; + vecR3 = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); + vecR3 = vec_add( vecR3, vec_sld( vecR3, vecR3, 4 ) ); + vecR3 = vec_add(vecR3, vecBitShifted6 ); + vecR3 = vec_or( vecR3, vec_sld( vecBitShifted6, vecBitShifted6, 4 ) ); + + vecR4 = (vector unsigned int)(0); //zeroIntVector; + vecR4 = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); + vecR4 = vec_add( vecR4, vec_sld( vecR4, vecR4, 4 ) ); + vecR4 = vec_add(vecR4, vecBitShifted8 ); + vecR4 = vec_or( vecR4, vec_sld( vecBitShifted8, vecBitShifted8, 4 ) ); + + // take the first element from each vector and put them into vecR1 + vecR1 = vec_mergeh( vecR1, vecR2 ); + vecR3 = vec_mergeh( vecR3, vecR4 ); + vecR1 = vec_perm( vecR1, vecR3, permHalves ); + + // XOR with 0x3F to flip lower 6 bits + vecR1 = vec_xor( vecR1, vecFlipBits ); + + // store out results. don't have 16 at a time so let's just + // do this and avoid alignment concerns + vecR1 = vec_perm( vecR1, vecR1, vBitPerm ); + vec_ste( vecR1, 0, &vBits[0] ); + vec_ste( vecR1, 4, &vBits[0] ); + vec_ste( vecR1, 8, &vBits[0] ); + vec_ste( vecR1, 12, &vBits[0] ); + + cullBits[i] = vBits[0]; + cullBits[i+1] = vBits[1]; + cullBits[i+2] = vBits[2]; + cullBits[i+3] = vBits[3]; + } + + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, d4, d5; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + d4 = planes[4].Distance( v ); + d5 = planes[5].Distance( v ); + + // they check if the sign bit is set by casting as long and shifting right 31 places. + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + bits |= FLOATSIGNBITSET( d2 ) << 2; + bits |= FLOATSIGNBITSET( d3 ) << 3; + bits |= FLOATSIGNBITSET( d4 ) << 4; + bits |= FLOATSIGNBITSET( d5 ) << 5; + + cullBits[i] = bits ^ 0x3F; // flip lower 6 bits + } +} + + +#endif /*DRAWVERT_PADDED */ + +#ifndef DRAWVERT_PADDED +/* +============ +idSIMD_AltiVec::OverlayPointCull +============ +*/ +void VPCALL idSIMD_AltiVec::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + int i; + + float p0x, p0y, p0z, p0d; + float p1x, p1y, p1z, p1d; + + const float *planePtr = planes[0].ToFloatPtr(); + const float *vertPtr = verts[0].xyz.ToFloatPtr(); + + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + vector unsigned char vecPerm; + vector float zeroVector = (vector float)(0); + + p0x = *(planePtr + 0); + p0y = *(planePtr + 1); + p0z = *(planePtr + 2); + p0d = *(planePtr + 3); + p1x = *(planePtr + 4); + p1y = *(planePtr + 5); + p1z = *(planePtr + 6); + p1d = *(planePtr + 7); + + // populate the planes + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 31, planePtr ); + vecPlane1 = vec_perm( v1, v2, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane0 ); + v1 = vec_mergeh( vecPlane1, vecPlane1 ); + v2 = vec_mergel( vecPlane0, vecPlane0 ); + v3 = vec_mergel( vecPlane1, vecPlane1); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector float oneVector = (vector float)(1); + + vector float vecSum1, vecSum2, vecSum1Inv,vecSum2Inv; + + vector bool int vecCmp1, vecCmp2, vecCmp1Inv, vecCmp2Inv; + vector float negTwoVector = (vector float)(-2); + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted1Inv, vecBitShifted2Inv; + vector unsigned int vecShift = (vector unsigned int)( 0, 1, 0, 1 ); + vector unsigned int vecShiftInv = (vector unsigned int)( 2, 3, 2, 3 ); + vector unsigned char vecPermFirstThird = (vector unsigned char)(0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27); + vector bool int oneIntVector = (vector bool int)(1); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + unsigned int cullBitVal[4]; + vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); + + i = 0; + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < numVerts ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } + + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); + vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); + vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); + vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); + + // like a splat, but only doing halves + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum1 ); + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum1 ); + vecSum1 = vec_add( vecSum1, vecPlane3 ); + + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum2 ); + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum2 ); + vecSum2 = vec_add( vecSum2, vecPlane3 ); + + // store out results + UNALIGNED_STORE2( &texCoords[i][0], vecSum1, vecSum2 ); + + // bit manipulation + vecCmp1 = vec_cmplt( vecSum1, zeroVector ); + vecCmp2 = vec_cmplt( vecSum2, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + + // store out and write to cullBits + // finally, a use for algebra! 1-x = x + 1 - 2x + vecSum1Inv = vec_madd( vecSum1, negTwoVector, vecSum1 ); + vecSum2Inv = vec_madd( vecSum2, negTwoVector, vecSum2 ); + vecSum1Inv = vec_add( vecSum1Inv, oneVector ); + vecSum2Inv = vec_add( vecSum2Inv, oneVector ); + + // do the same comparisons for the inverted d0/d1 + vecCmp1Inv = vec_cmplt( vecSum1Inv, zeroVector ); + vecCmp2Inv = vec_cmplt( vecSum2Inv, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1Inv = vec_and( vecCmp1Inv, oneIntVector ); + vecCmp2Inv = vec_and( vecCmp2Inv, oneIntVector ); + + // shift them as needed + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift ); + vecBitShifted1Inv = vec_sl( (vector unsigned int)vecCmp1Inv, vecShiftInv ); + vecBitShifted2Inv = vec_sl( (vector unsigned int)vecCmp2Inv, vecShiftInv ); + + // OR them all together. since only 1 bit is set for each value, thats + // the same as adding them. add up d0 + d1 + d0Inv + d1Inv + vector unsigned int vecResult; + vector unsigned int vecResult2; + vector unsigned int vecResult3; + vecResult = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 4 ) ); + + vecResult2 = vec_add( vecBitShifted2, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); + + // vecResult now holds the values without the inverses yet, so add those + vecResult = vec_perm( vecResult, vecResult2, vecPermFirstThird ); + vecResult2 = vec_add( vecBitShifted1Inv, vec_sld( vecBitShifted1Inv, vecBitShifted1Inv, 4 ) ); + vecResult3 = vec_add( vecBitShifted2Inv, vec_sld( vecBitShifted2Inv, vecBitShifted2Inv, 4 ) ); + vecResult2 = vec_perm( vecResult2, vecResult3, vecPermFirstThird ); + + vecResult = vec_add( vecResult, vecResult2 ); + + //store out results + vecResult = vec_perm( vecResult, vecResult, cullBitPerm ); + vec_ste( vecResult, 0, &cullBitVal[0] ); + vec_ste( vecResult, 4, &cullBitVal[0] ); + vec_ste( vecResult, 8, &cullBitVal[0] ); + vec_ste( vecResult, 12, &cullBitVal[0] ); + + cullBits[i] = cullBitVal[0]; + cullBits[i+1] = cullBitVal[1]; + cullBits[i+2] = cullBitVal[2]; + cullBits[i+3] = cullBitVal[3]; + } + + // cleanup + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1; + float vx, vy, vz; + + vx = *( vertPtr + (i*DRAWVERT_OFFSET) + 0 ); + vy = *( vertPtr + (i*DRAWVERT_OFFSET) + 1 ); + vz = *( vertPtr + (i*DRAWVERT_OFFSET) + 2 ); + + d0 = p0x * vx + p0y * vy + p0z * vz + p0d; + d1 = p1x * vx + p1y * vy + p1z * vz + p1d; + texCoords[i][0] = d0; + texCoords[i][1] = d1; + + bits = ( d0 >= 0 ) ? 0 : 1; + d0 = 1.0f - d0; + bits |= ( d1 >= 0 ) ? 0 : 1*2; + d1 = 1.0f - d1; + + bits |= ( d0 >= 0 ) ? 0: 1*4; + bits |= ( d1 >= 0 ) ? 0: 1*8; + + cullBits[i] = bits; + } +} +#else + +/* +============ +idSIMD_AltiVec::OverlayPointCull +============ +*/ +void VPCALL idSIMD_AltiVec::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + int i; + + float p0x, p0y, p0z, p0d; + float p1x, p1y, p1z, p1d; + + const float *planePtr = planes[0].ToFloatPtr(); + const float *vertPtr = verts[0].xyz.ToFloatPtr(); + + vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; + vector float v0, v1, v2, v3, v4, v5, v6, v7; + vector unsigned char vecPerm; + vector float zeroVector = (vector float)(0); + + p0x = *(planePtr + 0); + p0y = *(planePtr + 1); + p0z = *(planePtr + 2); + p0d = *(planePtr + 3); + p1x = *(planePtr + 4); + p1y = *(planePtr + 5); + p1z = *(planePtr + 6); + p1d = *(planePtr + 7); + + // populate the planes + vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); + v0 = vec_ld( 0, planePtr ); + v1 = vec_ld( 15, planePtr ); + vecPlane0 = vec_perm( v0, v1, vecPerm ); + + v2 = vec_ld( 31, planePtr ); + vecPlane1 = vec_perm( v1, v2, vecPerm ); + + // transpose + v0 = vec_mergeh( vecPlane0, vecPlane0 ); + v1 = vec_mergeh( vecPlane1, vecPlane1 ); + v2 = vec_mergel( vecPlane0, vecPlane0 ); + v3 = vec_mergel( vecPlane1, vecPlane1); + + vecPlane0 = vec_mergeh( v0, v1 ); + vecPlane1 = vec_mergel( v0, v1 ); + vecPlane2 = vec_mergeh( v2, v3 ); + vecPlane3 = vec_mergel( v2, v3 ); + + vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; + vector float oneVector = (vector float)(1); + + vector float vecSum1, vecSum2, vecSum1Inv,vecSum2Inv; + + vector bool int vecCmp1, vecCmp2, vecCmp1Inv, vecCmp2Inv; + vector float negTwoVector = (vector float)(-2); + vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted1Inv, vecBitShifted2Inv; + vector unsigned int vecShift = (vector unsigned int)( 0, 1, 0, 1 ); + vector unsigned int vecShiftInv = (vector unsigned int)( 2, 3, 2, 3 ); + vector unsigned char vecPermFirstThird = (vector unsigned char)(0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27); + vector bool int oneIntVector = (vector bool int)(1); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + unsigned int cullBitVal[4]; + vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); + + i = 0; + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + + vecXYZ1 = vec_ld( 0, vertPtr ); + vecXYZ2 = vec_ld( 0, vertPtr2 ); + vecXYZ3 = vec_ld( 0, vertPtr3 ); + vecXYZ4 = vec_ld( 0, vertPtr4 ); + + // like a splat, but only doing halves + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum1 ); + vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum1 ); + vecSum1 = vec_add( vecSum1, vecPlane3 ); + + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum2 ); + vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum2 ); + vecSum2 = vec_add( vecSum2, vecPlane3 ); + + // store out results + UNALIGNED_STORE2( &texCoords[i][0], vecSum1, vecSum2 ); + + // bit manipulation + vecCmp1 = vec_cmplt( vecSum1, zeroVector ); + vecCmp2 = vec_cmplt( vecSum2, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1 = vec_and( vecCmp1, oneIntVector ); + vecCmp2 = vec_and( vecCmp2, oneIntVector ); + + // store out and write to cullBits + // finally, a use for algebra! 1-x = x + 1 - 2x + vecSum1Inv = vec_madd( vecSum1, negTwoVector, vecSum1 ); + vecSum2Inv = vec_madd( vecSum2, negTwoVector, vecSum2 ); + vecSum1Inv = vec_add( vecSum1Inv, oneVector ); + vecSum2Inv = vec_add( vecSum2Inv, oneVector ); + + // do the same comparisons for the inverted d0/d1 + vecCmp1Inv = vec_cmplt( vecSum1Inv, zeroVector ); + vecCmp2Inv = vec_cmplt( vecSum2Inv, zeroVector ); + + //and it with 1 so we multiply by 1 not 1111's + vecCmp1Inv = vec_and( vecCmp1Inv, oneIntVector ); + vecCmp2Inv = vec_and( vecCmp2Inv, oneIntVector ); + + // shift them as needed + vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift ); + vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift ); + vecBitShifted1Inv = vec_sl( (vector unsigned int)vecCmp1Inv, vecShiftInv ); + vecBitShifted2Inv = vec_sl( (vector unsigned int)vecCmp2Inv, vecShiftInv ); + + // OR them all together. since only 1 bit is set for each value, thats + // the same as adding them. add up d0 + d1 + d0Inv + d1Inv + vector unsigned int vecResult; + vector unsigned int vecResult2; + vector unsigned int vecResult3; + vecResult = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 4 ) ); + + vecResult2 = vec_add( vecBitShifted2, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); + + // vecResult now holds the values without the inverses yet, so add those + vecResult = vec_perm( vecResult, vecResult2, vecPermFirstThird ); + vecResult2 = vec_add( vecBitShifted1Inv, vec_sld( vecBitShifted1Inv, vecBitShifted1Inv, 4 ) ); + vecResult3 = vec_add( vecBitShifted2Inv, vec_sld( vecBitShifted2Inv, vecBitShifted2Inv, 4 ) ); + vecResult2 = vec_perm( vecResult2, vecResult3, vecPermFirstThird ); + + vecResult = vec_add( vecResult, vecResult2 ); + + //store out results + vecResult = vec_perm( vecResult, vecResult, cullBitPerm ); + vec_ste( vecResult, 0, &cullBitVal[0] ); + vec_ste( vecResult, 4, &cullBitVal[0] ); + vec_ste( vecResult, 8, &cullBitVal[0] ); + vec_ste( vecResult, 12, &cullBitVal[0] ); + + cullBits[i] = cullBitVal[0]; + cullBits[i+1] = cullBitVal[1]; + cullBits[i+2] = cullBitVal[2]; + cullBits[i+3] = cullBitVal[3]; + } + + // cleanup + for ( ; i < numVerts; i++ ) { + byte bits; + float d0, d1; + float vx, vy, vz; + + vx = *( vertPtr + (i*DRAWVERT_OFFSET) + 0 ); + vy = *( vertPtr + (i*DRAWVERT_OFFSET) + 1 ); + vz = *( vertPtr + (i*DRAWVERT_OFFSET) + 2 ); + + d0 = p0x * vx + p0y * vy + p0z * vz + p0d; + d1 = p1x * vx + p1y * vy + p1z * vz + p1d; + texCoords[i][0] = d0; + texCoords[i][1] = d1; + + bits = ( d0 >= 0 ) ? 0 : 1; + d0 = 1.0f - d0; + bits |= ( d1 >= 0 ) ? 0 : 1*2; + d1 = 1.0f - d1; + + bits |= ( d0 >= 0 ) ? 0: 1*4; + bits |= ( d1 >= 0 ) ? 0: 1*8; + + cullBits[i] = bits; + } +} + + +#endif /* DRAWVERT_PADDED */ + +#endif /* ENABLE_CULL */ + +#ifdef ENABLE_DERIVE +/* +============ +idSIMD_AltiVec::DeriveTriPlanes + + Derives a plane equation for each triangle. +============ +*/ +void VPCALL idSIMD_AltiVec::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + // idPlane size + assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); + int i; + + vector float vecD0, vecD1, vecD2, vecD3, vecD4, vecD5, vecD6, vecD7; + vector float vecVertA, vecVertB, vecVertC; + vector float vecVertA2, vecVertB2, vecVertC2; + vector float vecVertA3, vecVertB3, vecVertC3; + vector float vecVertA4, vecVertB4, vecVertC4; + + vector float vecN, vecN2, vecN3, vecN4; + vector float vecWork1, vecWork2, vecWork3, vecWork4, vecWork5, vecWork6, vecWork7, vecWork8; + vector unsigned char vecPerm1 = (vector unsigned char)(4,5,6,7,8,9,10,11,0,1,2,3,12,13,14,15); + vector unsigned char vecPerm2 = (vector unsigned char)(8,9,10,11,0,1,2,3,4,5,6,7,12,13,14,15); + vector float vecF; + vector float vecF1, vecF2, vecF3, vecF4; + vector float zeroVector = (vector float)(0); + vector float vecNegOne = (vector float)(-1); + vector float vecSecondHalf, vecFirstHalf, vecSecondHalf2, vecFirstHalf2, vecSecondHalf3, vecFirstHalf3, vecFirstHalf4, vecSecondHalf4; + + vector unsigned char vecPermA, vecPermA2, vecPermA3, vecPermA4; + vector unsigned char vecPermB, vecPermB2, vecPermB3, vecPermB4; + vector unsigned char vecPermC, vecPermC2, vecPermC3, vecPermC4; + + vector unsigned char oneVector = (vector unsigned char)(1); + vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; + vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + + const float *xyzPtr = verts[0].xyz.ToFloatPtr(); + float *planePtr = planes[0].ToFloatPtr(); + + int j; + for ( j = 0, i = 0; i+11 < numIndexes; i += 12, j += 4 ) { + +#ifndef DRAWVERT_PADDED + // calculate permute vectors to load as needed. these are all + // triangle indexes and are usaully pretty close together but + // not guaranteed to be in any particular order + vecPermA = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermB = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermC = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermA2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermB2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermC2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermA3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermB3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermC3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermA4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermB4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ), oneVector ); + vecPermC4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ), oneVector ); +#endif + +#ifndef DRAWVERT_PADDED + // load first A B C + vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); + vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); + vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); + vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); + vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); + vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); + + vecVertA = vec_perm( vecLd1, vecLd2, vecPermA ); + vecVertB = vec_perm( vecLd3, vecLd4, vecPermB ); + vecVertC = vec_perm( vecLd5, vecLd6, vecPermC ); + + // set the last element to 0 + vecVertA = vec_perm( vecVertA, zeroVector, vecPermZeroLast ); + vecVertB = vec_perm( vecVertB, zeroVector, vecPermZeroLast ); + vecVertC = vec_perm( vecVertC, zeroVector, vecPermZeroLast ); + + // load second A B C + vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); + vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); + vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); + vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); + vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); + vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); + + vecVertA2 = vec_perm( vecLd1, vecLd2, vecPermA2 ); + vecVertB2 = vec_perm( vecLd3, vecLd4, vecPermB2 ); + vecVertC2 = vec_perm( vecLd5, vecLd6, vecPermC2 ); + + // set the last element to 0 + vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); + vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); + vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); + + // load third A B C + vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); + vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); + vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); + vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); + vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); + vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); + + vecVertA3 = vec_perm( vecLd1, vecLd2, vecPermA3 ); + vecVertB3 = vec_perm( vecLd3, vecLd4, vecPermB3 ); + vecVertC3 = vec_perm( vecLd5, vecLd6, vecPermC3 ); + + // set the last element to 0 + vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); + vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); + vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); + + // load the fourth A B C + vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); + vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); + vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); + vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); + vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); + vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); + + vecVertA4 = vec_perm( vecLd1, vecLd2, vecPermA4 ); + vecVertB4 = vec_perm( vecLd3, vecLd4, vecPermB4 ); + vecVertC4 = vec_perm( vecLd5, vecLd6, vecPermC4 ); + + // set the last element to 0 + vecVertA4 = vec_perm( vecVertA4, zeroVector, vecPermZeroLast ); + vecVertB4 = vec_perm( vecVertB4, zeroVector, vecPermZeroLast ); + vecVertC4 = vec_perm( vecVertC4, zeroVector, vecPermZeroLast ); +#else + // load first A B C + vecVertA = vec_ld( 0, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); + vecVertB = vec_ld( 0, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); + vecVertC = vec_ld( 0, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); + + // set the last element to 0 + vecVertA = vec_perm( vecVertA, zeroVector, vecPermZeroLast ); + vecVertB = vec_perm( vecVertB, zeroVector, vecPermZeroLast ); + vecVertC = vec_perm( vecVertC, zeroVector, vecPermZeroLast ); + + // load second A B C + vecVertA2 = vec_ld( 0, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); + vecVertB2 = vec_ld( 0, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); + vecVertC2 = vec_ld( 0, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); + + // set the last element to 0 + vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); + vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); + vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); + + // load third A B C + vecVertA3 = vec_ld( 0, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); + vecVertB3 = vec_ld( 0, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); + vecVertC3 = vec_ld( 0, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); + + // set the last element to 0 + vecVertA3 = vec_perm( vecVertA3, zeroVector, vecPermZeroLast ); + vecVertB3 = vec_perm( vecVertB3, zeroVector, vecPermZeroLast ); + vecVertC3 = vec_perm( vecVertC3, zeroVector, vecPermZeroLast ); + + // load the fourth A B C + vecVertA4 = vec_ld( 0, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); + vecVertB4 = vec_ld( 0, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); + vecVertC4 = vec_ld( 0, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); + + // set the last element to 0 + vecVertA4 = vec_perm( vecVertA4, zeroVector, vecPermZeroLast ); + vecVertB4 = vec_perm( vecVertB4, zeroVector, vecPermZeroLast ); + vecVertC4 = vec_perm( vecVertC4, zeroVector, vecPermZeroLast ); +#endif + // calculate d0 and d1 for each + vecD0 = vec_sub( vecVertB, vecVertA ); + vecD1 = vec_sub( vecVertC, vecVertA ); + + vecD2 = vec_sub( vecVertB2, vecVertA2 ); + vecD3 = vec_sub( vecVertC2, vecVertA2 ); + + vecD4 = vec_sub( vecVertB3, vecVertA3 ); + vecD5 = vec_sub( vecVertC3, vecVertA3 ); + + vecD6 = vec_sub( vecVertB4, vecVertA4 ); + vecD7 = vec_sub( vecVertC4, vecVertA4 ); + + vecWork1 = vec_perm( vecD0, vecD0, vecPerm1 ); + vecWork2 = vec_perm( vecD1, vecD1, vecPerm2 ); + vecWork3 = vec_perm( vecD2, vecD2, vecPerm1 ); + vecWork4 = vec_perm( vecD3, vecD3, vecPerm2 ); + vecWork5 = vec_perm( vecD4, vecD4, vecPerm1 ); + vecWork6 = vec_perm( vecD5, vecD5, vecPerm2 ); + vecWork7 = vec_perm( vecD6, vecD6, vecPerm1 ); + vecWork8 = vec_perm( vecD7, vecD7, vecPerm2 ); + + vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecWork1 = vec_perm( vecD1, vecD1, vecPerm1 ); + vecWork2 = vec_perm( vecD0, vecD0, vecPerm2 ); + vecWork3 = vec_perm( vecD3, vecD3, vecPerm1 ); + vecWork4 = vec_perm( vecD2, vecD2, vecPerm2 ); + vecWork5 = vec_perm( vecD5, vecD5, vecPerm1 ); + vecWork6 = vec_perm( vecD4, vecD4, vecPerm2 ); + vecWork7 = vec_perm( vecD7, vecD7, vecPerm1 ); + vecWork8 = vec_perm( vecD6, vecD6, vecPerm2 ); + + vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecN = vec_madd( vecSecondHalf, vecNegOne, vecFirstHalf ); + vecN2 = vec_madd( vecSecondHalf2, vecNegOne, vecFirstHalf2 ); + vecN3 = vec_madd( vecSecondHalf3, vecNegOne, vecFirstHalf3 ); + vecN4 = vec_madd( vecSecondHalf4, vecNegOne, vecFirstHalf4 ); + + // transpose vecNs + vector float v0, v1, v2, v3; + v0 = vec_mergeh( vecN, vecN3 ); + v1 = vec_mergeh( vecN2, vecN4 ); + v2 = vec_mergel( vecN, vecN3 ); + v3 = vec_mergel( vecN2, vecN4 ); + + vecN = vec_mergeh( v0, v1 ); + vecN2 = vec_mergel( v0, v1 ); + vecN3 = vec_mergeh( v2, v3 ); + vecN4 = vec_mergel( v2, v3 ); + + vecF = vec_madd( vecN, vecN, zeroVector ); + vecF = vec_madd( vecN2, vecN2, vecF ); + vecF = vec_madd( vecN3, vecN3, vecF ); + + vecF = ReciprocalSquareRoot( vecF ); + + vecF1 = vec_madd( vecF, vecN, zeroVector ); + vecF2 = vec_madd( vecF, vecN2, zeroVector ); + vecF3 = vec_madd( vecF, vecN3, zeroVector ); + vecF4 = vec_madd( vecF, vecN4, zeroVector ); + + vector float v8, v9, v10, v11; + v8 = vecF1; + v9 = vecF2; + v10 = vecF3; + v11 = vecF4; + + // transpose vecVerts + v0 = vec_mergeh( vecVertA, vecVertA3 ); + v1 = vec_mergeh( vecVertA2, vecVertA4 ); + v2 = vec_mergel( vecVertA, vecVertA3 ); + v3 = vec_mergel( vecVertA2, vecVertA4 ); + + vecVertA = vec_mergeh( v0, v1 ); + vecVertA2 = vec_mergel( v0, v1 ); + vecVertA3 = vec_mergeh( v2, v3 ); + vecVertA4 = vec_mergel( v2, v3 ); + + vector float vecTotals; + vecTotals = vec_madd( vecVertA, v8, zeroVector ); + vecTotals = vec_madd( vecVertA2, v9, vecTotals ); + vecTotals = vec_madd( vecVertA3, v10, vecTotals ); + vecTotals = vec_madd( vecVertA4, v11, vecTotals ); + vecF = vec_madd( vecTotals, vecNegOne, zeroVector ); + + // transpose vecFs + v0 = vec_mergeh( vecF1, vecF3 ); + v1 = vec_mergeh( vecF2, vecF ); + v2 = vec_mergel( vecF1, vecF3 ); + v3 = vec_mergel( vecF2, vecF ); + + vecF1 = vec_mergeh( v0, v1 ); + vecF2 = vec_mergel( v0, v1 ); + vecF3 = vec_mergeh( v2, v3 ); + vecF4 = vec_mergel( v2, v3 ); + + // store results + UNALIGNED_STORE4( planePtr + ( j * PLANE_OFFSET ), vecF1, vecF2, vecF3, vecF4 ); + } + + // cleanup + for ( ; i < numIndexes; i += 3, j++ ) { + const idDrawVert *a, *b, *c; + float d0[3], d1[3], f; + idVec3 n; + + a = verts + indexes[i + 0]; + b = verts + indexes[i + 1]; + c = verts + indexes[i + 2]; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + + n[0] = d1[1] * d0[2] - d1[2] * d0[1]; + n[1] = d1[2] * d0[0] - d1[0] * d0[2]; + n[2] = d1[0] * d0[1] - d1[1] * d0[0]; + + f = FastScalarInvSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); + //idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); + + n.x *= f; + n.y *= f; + n.z *= f; + + planes[j].SetNormal( n ); + planes[j].FitThroughPoint( a->xyz ); + } +} + +/* +============ +idSIMD_AltiVec::DeriveTangents + + Derives the normal and orthogonal tangent vectors for the triangle vertices. + For each vertex the normal and tangent vectors are derived from all triangles + using the vertex which results in smooth tangents across the mesh. + In the process the triangle planes are calculated as well. + +============ +*/ +void VPCALL idSIMD_AltiVec::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + int i; + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + idPlane *planesPtr = planes; + for ( i = 0; i < numIndexes; i += 3 ) { + idDrawVert *a, *b, *c; + // unsigned long signBit; + float d0[5], d1[5], area; + idVec3 n, t0, t1; + float f1, f2, f3; + + int v0 = indexes[i + 0]; + int v1 = indexes[i + 1]; + int v2 = indexes[i + 2]; + + a = verts + v0; + b = verts + v1; + c = verts + v2; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + // normal + n[0] = d1[1] * d0[2] - d1[2] * d0[1]; + n[1] = d1[2] * d0[0] - d1[0] * d0[2]; + n[2] = d1[0] * d0[1] - d1[1] * d0[0]; + + f1 = n.x * n.x + n.y * n.y + n.z * n.z; + + // area sign bit + area = d0[3] * d1[4] - d0[4] * d1[3]; + + // first tangent + t0[0] = d0[0] * d1[4] - d0[4] * d1[0]; + t0[1] = d0[1] * d1[4] - d0[4] * d1[1]; + t0[2] = d0[2] * d1[4] - d0[4] * d1[2]; + + f2 = t0.x * t0.x + t0.y * t0.y + t0.z * t0.z; + + // second tangent + t1[0] = d0[3] * d1[0] - d0[0] * d1[3]; + t1[1] = d0[3] * d1[1] - d0[1] * d1[3]; + t1[2] = d0[3] * d1[2] - d0[2] * d1[3]; + + f3 = t1.x * t1.x + t1.y * t1.y + t1.z * t1.z; + + // Behold! The power of the pipeline + FastScalarInvSqrt_x3( &f1, &f2, &f3 ); +#ifdef PPC_INTRINSICS + f2 = __fsel( area, f2, -f2 ); + f3 = __fsel( area, f3, -f3 ); +#else + f2 = ( area < 0.0f ) ? -f2 : f2; + f3 = ( area < 0.0f ) ? -f3 : f3; +#endif + t0.x *= f2; + t0.y *= f2; + t0.z *= f2; + + n.x *= f1; + n.y *= f1; + n.z *= f1; + + planesPtr->SetNormal( n ); + planesPtr->FitThroughPoint( a->xyz ); + planesPtr++; + + t1.x *= f3; + t1.y *= f3; + t1.z *= f3; + + if ( used[v0] ) { + a->normal += n; + a->tangents[0] += t0; + a->tangents[1] += t1; + } else { + a->normal = n; + a->tangents[0] = t0; + a->tangents[1] = t1; + used[v0] = true; + } + + if ( used[v1] ) { + b->normal += n; + b->tangents[0] += t0; + b->tangents[1] += t1; + } else { + b->normal = n; + b->tangents[0] = t0; + b->tangents[1] = t1; + used[v1] = true; + } + + if ( used[v2] ) { + c->normal += n; + c->tangents[0] += t0; + c->tangents[1] += t1; + } else { + c->normal = n; + c->tangents[0] = t0; + c->tangents[1] = t1; + used[v2] = true; + } + } +} + + +#ifdef DERIVE_UNSMOOTH_DRAWVERT_ALIGNED + +/* +============ +idSIMD_AltiVec::DeriveUnsmoothedTangents + + Derives the normal and orthogonal tangent vectors for the triangle vertices. + For each vertex the normal and tangent vectors are derived from a single dominant triangle. +============ +*/ +#define DERIVE_UNSMOOTHED_BITANGENT +void VPCALL idSIMD_AltiVec::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { + + int i; + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + // drawverts aligned + assert( IS_16BYTE_ALIGNED( verts[0] ) ); + + vector float vecVertA, vecVertB, vecVertC; + vector float vecVertA2, vecVertB2, vecVertC2; + vector float vecVertA3, vecVertB3, vecVertC3; + vector float vecVertA4, vecVertB4, vecVertC4; + + vector float v0, v1, v2, v3, v4, v5, v6, v7, v8; + vector float vecS0, vecS1, vecS2; + vector float vecS0_2, vecS1_2, vecS2_2; + vector float vecS0_3, vecS1_3, vecS2_3; + vector float vecS0_4, vecS1_4, vecS2_4; + + vector float vecD1, vecD2, vecD3, vecD4, vecD5, vecD6; + vector float vecD7, vecD8, vecD9, vecD10, vecD11, vecD12; + vector float vecT1, vecT1_2, vecT1_3, vecT1_4, vecT2, vecT2_2, vecT2_3, vecT2_4; + vector float vecWork1, vecWork2, vecWork3, vecWork4, vecWork5, vecWork6, vecWork7, vecWork8; + vector float vecN, vecN2, vecN3, vecN4; + + vector unsigned char vecPermN0 = (vector unsigned char)(8,9,10,11,0,1,2,3,4,5,6,7,12,13,14,15); + vector unsigned char vecPermN1 = (vector unsigned char)(4,5,6,7,8,9,10,11,0,1,2,3,12,13,14,15); + vector unsigned char vecPermT0 = (vector unsigned char)(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3); + vector unsigned char vecPermT1 = (vector unsigned char)(8,9,10,11,8,9,10,11,8,9,10,11,8,9,10,11); + vector float zeroVector = (vector float)(0); + + vector float vecNegOne = (vector float)(-1.0); + + vector float vecStore1, vecStore2, vecStore3; + vector unsigned char vecPermFirstThreeLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vecPermStoreSecond = (vector unsigned char)(4,5,6,7,8,9,10,11,16,17,18,19,20,21,22,23); + vector unsigned char vecPermLeadAndThree = (vector unsigned char)(0,1,2,3,16,17,18,19,20,21,22,23,24,25,26,27); + vector unsigned char vecPermStore2 = (vector unsigned char)(4,5,6,7,8,9,10,11,24,25,26,27,28,29,30,31); + vector unsigned char vecPermStore3 = (vector unsigned char)(4,5,6,7,8,9,10,11,16,17,18,19,20,21,22,23); + vector unsigned char vecPermStore4 = (vector unsigned char)(8,9,10,11,16,17,18,19,20,21,22,23,24,25,26,27); + vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + + vector float vecLd1, vecLd2, vecLd3; + vector unsigned char vecPerm0, vecPerm1, vecPerm2, vecPerm3, vecPerm4; + + float *normalPtr = verts[0].normal.ToFloatPtr(); + float *xyzPtr = verts[0].xyz.ToFloatPtr(); + + vector float vecFirstHalf, vecSecondHalf; + vector float vecFirstHalf2, vecSecondHalf2; + vector float vecFirstHalf3, vecSecondHalf3; + vector float vecFirstHalf4, vecSecondHalf4; + + for ( i = 0; i+3 < numVerts; i+=4 ) { + int bOffset1, bOffset2, bOffset3, bOffset4; + int cOffset1, cOffset2, cOffset3, cOffset4; + + bOffset1 = dominantTris[i].v2; + cOffset1 = dominantTris[i].v3; + bOffset2 = dominantTris[i+1].v2; + cOffset2 = dominantTris[i+1].v3; + bOffset3 = dominantTris[i+2].v2; + cOffset3 = dominantTris[i+2].v3; + bOffset4 = dominantTris[i+3].v2; + cOffset4 = dominantTris[i+3].v3; + + vecPerm0 = vec_lvsl( 0, xyzPtr + ( i * DRAWVERT_OFFSET ) ); + v0 = vec_ld( 0, xyzPtr + (i * DRAWVERT_OFFSET ) ); + v1 = vec_ld( 16, xyzPtr + (i * DRAWVERT_OFFSET ) ); + vecVertA = vec_perm( v0, v1, vecPerm0 ); + + vecPerm1 = vec_lvsl( 0, xyzPtr + (bOffset1 * DRAWVERT_OFFSET ) ); + v2 = vec_ld( 0, xyzPtr + ( bOffset1 * DRAWVERT_OFFSET ) ); + v3 = vec_ld( 16, xyzPtr + ( bOffset1 * DRAWVERT_OFFSET ) ); + vecVertB = vec_perm( v2, v3, vecPerm1 ); + + vecPerm2 = vec_lvsl( 0, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); + v4 = vec_ld( 0, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); + v5 = vec_ld( 16, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); + vecVertC = vec_perm( v4, v5, vecPerm2 ); + + // put remainder into v2 + v1 = vec_perm( v1, v1, vecPerm0 ); + v3 = vec_perm( v3, v3, vecPerm1 ); + v5 = vec_perm( v5, v5, vecPerm2 ); + + v1 = vec_mergeh( v1, v5 ); + v2 = vec_mergeh( v3, zeroVector ); + v2 = vec_mergeh( v1, v2 ); + v2 = vec_perm( v2, v2, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); + + // load second one + vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); + v0 = vec_ld( 0, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); + v1 = vec_ld( 16, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); + vecVertA2 = vec_perm( v0, v1, vecPerm0 ); + + vecPerm3 = vec_lvsl( 0, xyzPtr + (bOffset2 * DRAWVERT_OFFSET ) ); + v3 = vec_ld( 0, xyzPtr + ( bOffset2 * DRAWVERT_OFFSET ) ); + v4 = vec_ld( 16, xyzPtr + ( bOffset2 * DRAWVERT_OFFSET ) ); + vecVertB2 = vec_perm( v3, v4, vecPerm3 ); + + vecPerm4 = vec_lvsl( 0, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); + v5 = vec_ld( 0, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); + v6 = vec_ld( 16, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); + vecVertC2 = vec_perm( v5, v6, vecPerm4 ); + + // put remainder into v3 + v1 = vec_perm( v1, v1, vecPerm0 ); + v4 = vec_perm( v4, v4, vecPerm3 ); + v5 = vec_perm( v6, v6, vecPerm4 ); + + v1 = vec_mergeh( v1, v5 ); + v3 = vec_mergeh( v4, zeroVector ); + v3 = vec_mergeh( v1, v3 ); + v3 = vec_perm( v3, v3, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); + + // load third one + vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); + v0 = vec_ld( 0, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); + v1 = vec_ld( 16, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); + vecVertA3 = vec_perm( v0, v1, vecPerm0 ); + + vecPerm1 = vec_lvsl( 0, xyzPtr + (bOffset3 * DRAWVERT_OFFSET ) ); + v4 = vec_ld( 0, xyzPtr + ( bOffset3 * DRAWVERT_OFFSET ) ); + v5 = vec_ld( 16, xyzPtr + ( bOffset3 * DRAWVERT_OFFSET ) ); + vecVertB3 = vec_perm( v4, v5, vecPerm1 ); + + vecPerm2 = vec_lvsl( 0, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); + v6 = vec_ld( 0, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); + v7 = vec_ld( 16, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); + vecVertC3 = vec_perm( v6, v7, vecPerm2 ); + + // put remainder into v4 + v1 = vec_perm( v1, v1, vecPerm0 ); + v5 = vec_perm( v5, v5, vecPerm1 ); + v7 = vec_perm( v7, v7, vecPerm2 ); + + v1 = vec_mergeh( v1, v7 ); + v4 = vec_mergeh( v5, zeroVector ); + v4 = vec_mergeh( v1, v4 ); + v4 = vec_perm( v4, v4, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); + + // load fourth one + vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); + v0 = vec_ld( 0, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); + v1 = vec_ld( 16, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); + vecVertA4 = vec_perm( v0, v1, vecPerm0 ); + + vecPerm3 = vec_lvsl( 0, xyzPtr + (bOffset4 * DRAWVERT_OFFSET ) ); + v5 = vec_ld( 0, xyzPtr + ( bOffset4 * DRAWVERT_OFFSET ) ); + v6 = vec_ld( 16, xyzPtr + ( bOffset4 * DRAWVERT_OFFSET ) ); + vecVertB4 = vec_perm( v5, v6, vecPerm3 ); + + vecPerm4 = vec_lvsl( 0, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); + v7 = vec_ld( 0, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); + v8 = vec_ld( 16, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); + vecVertC4 = vec_perm( v7, v8, vecPerm4 ); + + // put remainder into v5 + v1 = vec_perm( v1, v1, vecPerm0 ); + v6 = vec_perm( v6, v6, vecPerm3 ); + v8 = vec_perm( v8, v8, vecPerm4 ); + + v1 = vec_mergeh( v1, v8 ); + v5 = vec_mergeh( v6, zeroVector ); + v5 = vec_mergeh( v1, v5 ); + v5 = vec_perm( v5, v5, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); + + // remainder vectors look like b->st[1], a->st[1], c->st[1], a->st[1] + + //vecD1 now holds d0, d1, d2, d3 + vecD1 = vec_sub( vecVertB, vecVertA ); + vecD4 = vec_sub( vecVertB2, vecVertA2 ); + vecD7 = vec_sub( vecVertB3, vecVertA3 ); + vecD10 = vec_sub( vecVertB4, vecVertA4 ); + + // vecD2 how holds d5, d6, d7, d8 + vecD2 = vec_sub( vecVertC, vecVertA ); + vecD5 = vec_sub( vecVertC2, vecVertA2 ); + vecD8 = vec_sub( vecVertC3, vecVertA3 ); + vecD11 = vec_sub( vecVertC4, vecVertA4 ); + + // vecD3 now holds d4, crap, d9, crap + vecD3 = vec_sub( v2, vec_sld( v2, v2, 4 ) ); + vecD6 = vec_sub( v3, vec_sld( v3, v3, 4 ) ); + vecD9 = vec_sub( v4, vec_sld( v4, v4, 4 ) ); + vecD12 = vec_sub( v5, vec_sld( v5, v5, 4 ) ); + + // get permute vectors for loading from dt + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i].normalizationScale[0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+1].normalizationScale[0] ), (vector unsigned char)(1) ); + vecPerm3 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+2].normalizationScale[0] ), (vector unsigned char)(1) ); + vecPerm4 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+3].normalizationScale[0] ), (vector unsigned char)(1) ); + + // load S values from dominantTris + v0 = vec_ld( 0, &dominantTris[i].normalizationScale[0] ); + v1 = vec_ld( 11, &dominantTris[i].normalizationScale[0] ); + v2 = vec_ld( 0, &dominantTris[i+1].normalizationScale[0] ); + v3 = vec_ld( 11, &dominantTris[i+1].normalizationScale[0] ); + v4 = vec_ld( 0, &dominantTris[i+2].normalizationScale[0] ); + v5 = vec_ld( 11, &dominantTris[i+2].normalizationScale[0] ); + v6 = vec_ld( 0, &dominantTris[i+3].normalizationScale[0] ); + v7 = vec_ld( 11, &dominantTris[i+3].normalizationScale[0] ); + + v0 = vec_perm( v0, v1, vecPerm1 ); + v2 = vec_perm( v2, v3, vecPerm2 ); + v4 = vec_perm( v4, v5, vecPerm3 ); + v6 = vec_perm( v6, v7, vecPerm4 ); + + vecS0 = vec_splat( v0, 0 ); + vecS1 = vec_splat( v0, 1 ); + vecS2 = vec_splat( v0, 2 ); + + vecS0_2 = vec_splat( v2, 0); + vecS1_2 = vec_splat( v2, 1 ); + vecS2_2 = vec_splat( v2, 2 ); + + vecS0_3 = vec_splat( v4, 0 ); + vecS1_3 = vec_splat( v4, 1 ); + vecS2_3 = vec_splat( v4, 2 ); + + vecS0_4 = vec_splat( v6, 0 ); + vecS1_4 = vec_splat( v6, 1 ); + vecS2_4 = vec_splat( v6, 2 ); + + // do calculation + vecWork1 = vec_perm( vecD2, vecD2, vecPermN1 ); + vecWork2 = vec_perm( vecD1, vecD1, vecPermN0 ); + vecWork3 = vec_perm( vecD5, vecD5, vecPermN1 ); + vecWork4 = vec_perm( vecD4, vecD4, vecPermN0 ); + vecWork5 = vec_perm( vecD8, vecD8, vecPermN1 ); + vecWork6 = vec_perm( vecD7, vecD7, vecPermN0 ); + vecWork7 = vec_perm( vecD11, vecD11, vecPermN1 ); + vecWork8 = vec_perm( vecD10, vecD10, vecPermN0 ); + + vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecWork1 = vec_perm( vecD2, vecD2, vecPermN0 ); + vecWork2 = vec_perm( vecD1, vecD1, vecPermN1 ); + vecWork3 = vec_perm( vecD5, vecD5, vecPermN0 ); + vecWork4 = vec_perm( vecD4, vecD4, vecPermN1 ); + vecWork5 = vec_perm( vecD8, vecD8, vecPermN0 ); + vecWork6 = vec_perm( vecD7, vecD7, vecPermN1 ); + vecWork7 = vec_perm( vecD11, vecD11, vecPermN0 ); + vecWork8 = vec_perm( vecD10, vecD10, vecPermN1 ); + + vecSecondHalf = vec_nmsub( vecWork1, vecWork2, vecFirstHalf ); + vecSecondHalf2 = vec_nmsub( vecWork3, vecWork4, vecFirstHalf2 ); + vecSecondHalf3 = vec_nmsub( vecWork5, vecWork6, vecFirstHalf3 ); + vecSecondHalf4 = vec_nmsub( vecWork7, vecWork8, vecFirstHalf4 ); + + + // calculate N values + vecN = vec_madd( vecS2, vecSecondHalf, zeroVector ); + vecN2 = vec_madd( vecS2_2, vecSecondHalf2, zeroVector ); + vecN3 = vec_madd( vecS2_3, vecSecondHalf3, zeroVector ); + vecN4 = vec_madd( vecS2_4, vecSecondHalf4, zeroVector ); + + // calculate both halves of the calculation for t + vecWork1 = vecD1; + vecWork2 = vec_perm( vecD3, vecD3, vecPermT1 ); + vecWork3 = vecD4; + vecWork4 = vec_perm( vecD6, vecD6, vecPermT1 ); + vecWork5 = vecD7; + vecWork6 = vec_perm( vecD9, vecD9, vecPermT1 ); + vecWork7 = vecD10; + vecWork8 = vec_perm( vecD12, vecD12, vecPermT1 ); + + vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecWork1 = vecD2; + vecWork2 = vec_perm( vecD3, vecD3, vecPermT0 ); + vecWork3 = vecD5; + vecWork4 = vec_perm( vecD6, vecD6, vecPermT0 ); + vecWork5 = vecD8; + vecWork6 = vec_perm( vecD9, vecD9, vecPermT0 ); + vecWork7 = vecD11; + vecWork8 = vec_perm( vecD12, vecD12, vecPermT0 ); + + vecSecondHalf = vec_nmsub( vecWork1, vecWork2, vecFirstHalf ); + vecSecondHalf2 = vec_nmsub( vecWork3, vecWork4, vecFirstHalf2 ); + vecSecondHalf3 = vec_nmsub( vecWork5, vecWork6, vecFirstHalf3 ); + vecSecondHalf4 = vec_nmsub( vecWork7, vecWork8, vecFirstHalf4 ); + + // calculate T values + vecT1 = vec_madd( vecS0, vecSecondHalf, zeroVector ); + vecT1_2 = vec_madd( vecS0_2, vecSecondHalf2, zeroVector ); + vecT1_3 = vec_madd( vecS0_3, vecSecondHalf3, zeroVector ); + vecT1_4 = vec_madd( vecS0_4, vecSecondHalf4, zeroVector ); + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + vecWork1 = vecD1; + vecWork2 = vec_perm( vecD2, vecD2, vecPermT2 ); + vecWork3 = vecD4; + vecWork4 = vec_perm( vecD5, vecD5, vecPermT2 ); + vecWork5 = vecD7; + vecWork6 = vec_perm( vecD8, vecD8, vecPermT2 ); + vecWork7 = vecD10; + vecWork8 = vec_perm( vecD11, vecD11, vecPermT2 ); + + vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecWork1 = vec_perm( vecD1, vecD1, vecPermT2 ); + vecWork2 = vecD2; + vecWork3 = vec_perm( vecD4, vecD4, vecPermT2 ); + vecWork4 = vecD5; + vecWork5 = vec_perm( vecD7, vecD7, vecPermT2 ); + vecWork6 = vecD8; + vecWork7 = vec_perm( vecD10, vecD10, vecPermT2 ); + vecWork8 = vecD11; + + vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + +#else + vecWork1 = vec_perm( vecN, vecN, vecPermN1 ); + vecWork2 = vec_perm( vecT1, vecT1, vecPermN0 ); + vecWork3 = vec_perm( vecN2, vecN2, vecPermN1 ); + vecWork4 = vec_perm( vecT1_2, vecT1_2, vecPermN0 ); + vecWork5 = vec_perm( vecN3, vecN3, vecPermN1 ); + vecWork6 = vec_perm( vecT1_3, vecT1_3, vecPermN0 ); + vecWork7 = vec_perm( vecN4, vecN4, vecPermN1 ); + vecWork8 = vec_perm( vecT1_4, vecT1_4, vecPermN0 ); + + vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); + + vecWork1 = vec_perm( vecN, vecN, vecPermN0 ); + vecWork2 = vec_perm( vecT1, vecT1, vecPermN1 ); + vecWork3 = vec_perm( vecN2, vecN2, vecPermN0 ); + vecWork4 = vec_perm( vecT1_2, vecT1_2, vecPermN1 ); + vecWork5 = vec_perm( vecN3, vecN3, vecPermN0 ); + vecWork6 = vec_perm( vecT1_3, vecT1_3, vecPermN1 ); + vecWork7 = vec_perm( vecN4, vecN4, vecPermN0 ); + vecWork8 = vec_perm( vecT1_4, vecT1_4, vecPermN1 ); + + vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); + vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); + vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); + vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); +#endif + // finish the calculation + vecSecondHalf = vec_madd( vecSecondHalf, vecNegOne, vecFirstHalf ); + vecSecondHalf2 = vec_madd( vecSecondHalf2, vecNegOne, vecFirstHalf2 ); + vecSecondHalf3 = vec_madd( vecSecondHalf3, vecNegOne, vecFirstHalf3 ); + vecSecondHalf4 = vec_madd( vecSecondHalf4, vecNegOne, vecFirstHalf4 ); + + vecT2 = vec_madd( vecS1, vecSecondHalf, zeroVector ); + vecT2_2 = vec_madd( vecS1_2, vecSecondHalf2, zeroVector ); + vecT2_3 = vec_madd( vecS1_3, vecSecondHalf3, zeroVector ); + vecT2_4 = vec_madd( vecS1_4, vecSecondHalf4, zeroVector ); + + // Store results + + // read values that we need to preserve + vecLd1 = vec_ld( 0, normalPtr + ( i * DRAWVERT_OFFSET ) ); + vecLd2 = vec_ld( 32, normalPtr + ( i * DRAWVERT_OFFSET ) ); + + //generate vectors to store + vecStore1 = vec_perm( vecLd1, vecN, vecPermLeadAndThree ); + vecStore2 = vec_perm( vecT1, vecT2, vecPermFirstThreeLast ); + vecStore3 = vec_perm( vecT2, vecLd2, vecPermStore2 ); + + // store out results + ALIGNED_STORE3( normalPtr + ( i * DRAWVERT_OFFSET ), vecStore1, vecStore2, vecStore3 ); + + // read values that we need to preserve + vecLd3 = vec_ld( 32, normalPtr + ( (i+1) * DRAWVERT_OFFSET )); + + // generate vectors to store + vecStore1 = vec_perm( vecN2, vecT1_2, vecPermFirstThreeLast ); + vecStore2 = vec_perm( vecT1_2, vecT2_2, vecPermStoreSecond ); + vecStore3 = vec_perm( vecT2_2, vecLd3, (vector unsigned char)(8,9,10,11,20,21,22,23,24,25,26,27,28,29,30,31) ); + + // instead of doing permute, shift it where it needs to be and use vec_ste + // store out vectors + ALIGNED_STORE3( normalPtr + ((i+1) * DRAWVERT_OFFSET), vecStore1, vecStore2, vecStore3 ); + + // read values that we need to preserve + vecLd1 = vec_ld( 0, normalPtr + ( (i+2) * DRAWVERT_OFFSET ) ); + + // generate vectors to store + vecStore1 = vec_perm( vecLd1, vecN3, vecPermFirstThreeLast ); + vecStore2 = vec_perm( vecN3, vecT1_3, vecPermStore3 ); + vecStore3 = vec_perm( vecT1_3, vecT2_3, vecPermStore4 ); + + // store out vectors + ALIGNED_STORE3( normalPtr + ((i+2) * DRAWVERT_OFFSET), vecStore1, vecStore2, vecStore3 ); + + // read values that we need to preserve + vecLd2 = vec_ld( 0, normalPtr + ((i+3) * DRAWVERT_OFFSET ) ); + vecLd3 = vec_ld( 32, normalPtr + ((i+3) * DRAWVERT_OFFSET ) ); + + // generate vectors to store + vecStore1 = vec_perm( vecLd2, vecN4, vecPermHalves ); + vecStore2 = vec_perm( vecN4, vecT1_4, vecPermStore4 ); + vecStore3 = vec_perm( vecT2_4, vecLd3, vecPermFirstThreeLast ); + + // store out vectors + ALIGNED_STORE3( normalPtr + ((i+3) * DRAWVERT_OFFSET ), vecStore1, vecStore2, vecStore3 ); + } + + // cleanup + for ( ; i < numVerts; i++ ) { + idDrawVert *a, *b, *c; + float d0, d1, d2, d3, d4; + float d5, d6, d7, d8, d9; + float s0, s1, s2; + float n0, n1, n2; + float t0, t1, t2; + float t3, t4, t5; + + const dominantTri_s &dt = dominantTris[i]; + + a = verts + i; + b = verts + dt.v2; + c = verts + dt.v3; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + d3 = b->st[0] - a->st[0]; + + d4 = b->st[1] - a->st[1]; + + d5 = c->xyz[0] - a->xyz[0]; + d6 = c->xyz[1] - a->xyz[1]; + d7 = c->xyz[2] - a->xyz[2]; + d8 = c->st[0] - a->st[0]; + + d9 = c->st[1] - a->st[1]; + + s0 = dt.normalizationScale[0]; + s1 = dt.normalizationScale[1]; + s2 = dt.normalizationScale[2]; + + n0 = s2 * ( d6 * d2 - d7 * d1 ); + n1 = s2 * ( d7 * d0 - d5 * d2 ); + n2 = s2 * ( d5 * d1 - d6 * d0 ); + + t0 = s0 * ( d0 * d9 - d4 * d5 ); + t1 = s0 * ( d1 * d9 - d4 * d6 ); + t2 = s0 * ( d2 * d9 - d4 * d7 ); + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + t3 = s1 * ( d3 * d5 - d0 * d8 ); + t4 = s1 * ( d3 * d6 - d1 * d8 ); + t5 = s1 * ( d3 * d7 - d2 * d8 ); +#else + t3 = s1 * ( n2 * t1 - n1 * t2 ); + t4 = s1 * ( n0 * t2 - n2 * t0 ); + t5 = s1 * ( n1 * t0 - n0 * t1 ); +#endif + + a->normal[0] = n0; + a->normal[1] = n1; + a->normal[2] = n2; + + a->tangents[0][0] = t0; + a->tangents[0][1] = t1; + a->tangents[0][2] = t2; + + a->tangents[1][0] = t3; + a->tangents[1][1] = t4; + a->tangents[1][2] = t5; + } +} + +#else +/* +============ +idSIMD_AltiVec::DeriveUnsmoothedTangents + + Derives the normal and orthogonal tangent vectors for the triangle vertices. + For each vertex the normal and tangent vectors are derived from a single dominant triangle. +============ +*/ +#define DERIVE_UNSMOOTHED_BITANGENT + +void VPCALL idSIMD_AltiVec::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { + int i; + + for ( i = 0; i < numVerts; i++ ) { + idDrawVert *a, *b, *c; + float d0, d1, d2, d3, d4; + float d5, d6, d7, d8, d9; + float s0, s1, s2; + float n0, n1, n2; + float t0, t1, t2; + float t3, t4, t5; + + const dominantTri_s &dt = dominantTris[i]; + + a = verts + i; + b = verts + dt.v2; + c = verts + dt.v3; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + d3 = b->st[0] - a->st[0]; + + d4 = b->st[1] - a->st[1]; + + d5 = c->xyz[0] - a->xyz[0]; + d6 = c->xyz[1] - a->xyz[1]; + d7 = c->xyz[2] - a->xyz[2]; + d8 = c->st[0] - a->st[0]; + + d9 = c->st[1] - a->st[1]; + + s0 = dt.normalizationScale[0]; + s1 = dt.normalizationScale[1]; + s2 = dt.normalizationScale[2]; + + n0 = s2 * ( d6 * d2 - d7 * d1 ); + n1 = s2 * ( d7 * d0 - d5 * d2 ); + n2 = s2 * ( d5 * d1 - d6 * d0 ); + + t0 = s0 * ( d0 * d9 - d4 * d5 ); + t1 = s0 * ( d1 * d9 - d4 * d6 ); + t2 = s0 * ( d2 * d9 - d4 * d7 ); + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + t3 = s1 * ( d3 * d5 - d0 * d8 ); + t4 = s1 * ( d3 * d6 - d1 * d8 ); + t5 = s1 * ( d3 * d7 - d2 * d8 ); +#else + t3 = s1 * ( n2 * t1 - n1 * t2 ); + t4 = s1 * ( n0 * t2 - n2 * t0 ); + t5 = s1 * ( n1 * t0 - n0 * t1 ); +#endif + + a->normal[0] = n0; + a->normal[1] = n1; + a->normal[2] = n2; + + a->tangents[0][0] = t0; + a->tangents[0][1] = t1; + a->tangents[0][2] = t2; + + a->tangents[1][0] = t3; + a->tangents[1][1] = t4; + a->tangents[1][2] = t5; + } + +} +#endif /* DERIVE_UNSMOOTH_DRAWVERT_ALIGNED */ + +/* +============ +idSIMD_AltiVec::NormalizeTangents + + Normalizes each vertex normal and projects and normalizes the + tangent vectors onto the plane orthogonal to the vertex normal. +============ +*/ +void VPCALL idSIMD_AltiVec::NormalizeTangents( idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + + float *addr = verts[0].normal.ToFloatPtr(); + float *tAddr = verts[0].tangents[0].ToFloatPtr(); + + // v0 through v3 maintain originally loaded values so we don't take + // as much hit for unaligned stores + vector float v0, v1, v2, v3; + // v5 through v8 are the "working" values of the vectors + vector float v5, v6, v7, v8; + // working values + vector float vec1T0, vec1T1, vec2T0, vec2T1, vec3T0, vec3T1, vec4T0, vec4T1; + vector float vecSum, vecTSum1, vecTSum2, tempSum, tempSum2, tempSum3; + vector float vecF, vecF2; + vector float vecTemp, vecTemp2, vecTemp3, vecTemp4; + + register vector float zeroVector = (vector float)(0.0); + + vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); + vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vecPermSplatFirstWithZero = (vector unsigned char)(0,1,2,3,0,1,2,3,0,1,2,3,16,17,18,19); + vector unsigned char vecPerm0, vecPerm1, vecPerm2, vecPerm3; + vector unsigned char storePerm0, storePerm1, storePerm2, storePerm3; + + vector float vecTan11, vecTan12, vecTan13, vecTan21, vecTan22, vecTan23; + vector float vecTan31, vecTan32, vecTan33, vecTan41, vecTan42, vecTan43; + + vector unsigned char vec1T0Perm, vec1T1Perm, vec2T0Perm, vec2T1Perm, vec3T0Perm, vec3T1Perm, vec4T0Perm, vec4T1Perm; + vector unsigned char storeT11, storeT12, storeT21, storeT22, storeT31, storeT32; + vector unsigned char storeT41, storeT42; + + int i = 0; + + if ( i+3 < numVerts ) { + // for loading normal from idDrawVert + vecPerm0 = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); + vecPerm1 = vec_add( vec_lvsl( -1, addr + ( 1 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, addr + ( 2 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vecPerm3 = vec_add( vec_lvsl( -1, addr + ( 3 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + + // for loading tangents from idDrawVert + vec1T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 0 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vec1T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 0 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); + vec2T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 1 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vec2T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 1 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); + vec3T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 2 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vec3T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 2 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); + vec4T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 3 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); + vec4T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 3 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); + + // generate permute vectors to store normals + storePerm0 = vec_lvsr( 0, addr ); + storePerm1 = vec_lvsr( 0, addr + ( 1 * DRAWVERT_OFFSET ) ); + storePerm2 = vec_lvsr( 0, addr + ( 2 * DRAWVERT_OFFSET ) ); + storePerm3 = vec_lvsr( 0, addr + ( 3 * DRAWVERT_OFFSET ) ); + + // generate permute vectors to store tangents + storeT11 = vec_lvsr( 0, tAddr + ( 0 * DRAWVERT_OFFSET ) ); + storeT12 = vec_lvsr( 12, tAddr + ( 0 * DRAWVERT_OFFSET ) ); + + storeT21 = vec_lvsr( 0, tAddr + ( 1 * DRAWVERT_OFFSET ) ); + storeT22 = vec_lvsr( 12, tAddr + ( 1 * DRAWVERT_OFFSET ) ); + + storeT31 = vec_lvsr( 0, tAddr + ( 2 * DRAWVERT_OFFSET ) ); + storeT32 = vec_lvsr( 12, tAddr + ( 2 * DRAWVERT_OFFSET ) ); + + storeT41 = vec_lvsr( 0, tAddr + ( 3 * DRAWVERT_OFFSET ) ); + storeT42 = vec_lvsr( 12, tAddr + ( 3 * DRAWVERT_OFFSET ) ); + } + + for ( ; i+3 < numVerts; i+=4 ) { + + // load normals + vector float vecNormal11 = vec_ld( 0, addr + ( i * DRAWVERT_OFFSET ) ); + vector float vecNormal12 = vec_ld( 15, addr + ( i * DRAWVERT_OFFSET ) ); + v0 = vec_perm( vecNormal11, vecNormal12, vecPerm0 ); + + vector float vecNormal21 = vec_ld( 0, addr + ((i+1) * DRAWVERT_OFFSET ) ); + vector float vecNormal22 = vec_ld( 15, addr + ((i+1) * DRAWVERT_OFFSET ) ); + v1 = vec_perm( vecNormal21, vecNormal22, vecPerm1 ); + + vector float vecNormal31 = vec_ld( 0, addr + ( (i+2) * DRAWVERT_OFFSET ) ); + vector float vecNormal32 = vec_ld( 15, addr + ( (i+2) * DRAWVERT_OFFSET ) ); + v2 = vec_perm( vecNormal31, vecNormal32, vecPerm2 ); + + vector float vecNormal41 = vec_ld( 0, addr + ((i+3) * DRAWVERT_OFFSET ) ); + vector float vecNormal42 = vec_ld( 15, addr + ((i+3) * DRAWVERT_OFFSET ) ); + v3 = vec_perm( vecNormal41, vecNormal42, vecPerm3 ); + + // zero out the last element of each useless vector + v0 = vec_perm( v0, zeroVector, vecPermLast ); + v1 = vec_perm( v1, zeroVector, vecPermLast ); + v2 = vec_perm( v2, zeroVector, vecPermLast ); + v3 = vec_perm( v3, zeroVector, vecPermLast ); + + // got 4 vectors in v0 through v3, sum them each accross + // and put into one vector + vecTemp = vec_madd( v0, v0, zeroVector ); + + vecSum = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + vecSum = vec_add( vecSum, vec_sld( vecSum, vecSum, 4 ) ); + // element 0 of vecSum now has sum of v0 + + vecTemp2 = vec_madd( v1, v1, zeroVector ); + tempSum = vec_add( vecTemp2, vec_sld( vecTemp2, vecTemp2, 8 ) ); + tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); + // put this into vecSum + vecSum = vec_mergeh( vecSum, tempSum ); + + vecTemp3 = vec_madd( v2, v2, zeroVector ); + tempSum = vec_add( vecTemp3, vec_sld( vecTemp3, vecTemp3, 8 ) ); + tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); + // put this into vecSum + vecSum = vec_perm( vecSum, tempSum, vecPermHalves ); + + vecTemp4 = vec_madd( v3, v3, zeroVector ); + tempSum = vec_add( vecTemp4, vec_sld( vecTemp4, vecTemp4, 8 ) ); + tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); + // put this into vecSum + vecSum = vec_perm( vecSum, tempSum, vecPermLast ); + + // take reciprocal square roots of these + vecF = ReciprocalSquareRoot( vecSum ); + + // multiply each vector by f + v5 = vec_madd( v0, vec_splat( vecF, 0 ), zeroVector ); + v6 = vec_madd( v1, vec_splat( vecF, 1 ), zeroVector ); + v7 = vec_madd( v2, vec_splat( vecF, 2 ), zeroVector ); + v8 = vec_madd( v3, vec_splat( vecF, 3 ), zeroVector ); + + // load tangents as unaligned + vecTan11 = vec_ld( 0, tAddr + ( i * DRAWVERT_OFFSET ) ); + vecTan12 = vec_ld( 11, tAddr + ( i * DRAWVERT_OFFSET ) ); + vecTan13 = vec_ld( 23, tAddr + ( i * DRAWVERT_OFFSET ) ); + + vecTan21 = vec_ld( 0, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); + vecTan22 = vec_ld( 11, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); + vecTan23 = vec_ld( 23, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); + + vecTan31 = vec_ld( 0, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); + vecTan32 = vec_ld( 11, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); + vecTan33 = vec_ld( 23, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); + + vecTan41 = vec_ld( 0, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); + vecTan42 = vec_ld( 11, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); + vecTan43 = vec_ld( 23, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); + + vec1T0 = vec_perm( vecTan11, vecTan12, vec1T0Perm ); + vec1T1 = vec_perm( vecTan12, vecTan13, vec1T1Perm ); + vec2T0 = vec_perm( vecTan21, vecTan22, vec2T0Perm ); + vec2T1 = vec_perm( vecTan22, vecTan23, vec2T1Perm ); + vec3T0 = vec_perm( vecTan31, vecTan32, vec3T0Perm ); + vec3T1 = vec_perm( vecTan32, vecTan33, vec3T1Perm ); + vec4T0 = vec_perm( vecTan41, vecTan42, vec4T0Perm ); + vec4T1 = vec_perm( vecTan42, vecTan43, vec4T1Perm ); + + //zero out last element of tangents + vec1T0 = vec_perm( vec1T0, zeroVector, vecPermLast ); + vec1T1 = vec_perm( vec1T1, zeroVector, vecPermLast ); + vec2T0 = vec_perm( vec2T0, zeroVector, vecPermLast ); + vec2T1 = vec_perm( vec2T1, zeroVector, vecPermLast ); + vec3T0 = vec_perm( vec3T0, zeroVector, vecPermLast ); + vec3T1 = vec_perm( vec3T1, zeroVector, vecPermLast ); + vec4T0 = vec_perm( vec4T0, zeroVector, vecPermLast ); + vec4T1 = vec_perm( vec4T1, zeroVector, vecPermLast ); + + // all tangents[0] + tempSum = zeroVector; + tempSum = vec_madd( vec1T0, v5, tempSum ); + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + // put tempSum splatted accross vecTSum1 + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v5, zeroVector ); + + //vec1T0 now contains what needs to be rsqrt'd and multiplied by f + vec1T0 = vec_sub( vec1T0, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec2T0, v6, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v6, zeroVector ); + vec2T0 = vec_sub( vec2T0, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec3T0, v7, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v7, zeroVector ); + vec3T0 = vec_sub( vec3T0, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec4T0, v8, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v8, zeroVector ); + vec4T0 = vec_sub( vec4T0, vecTSum1 ); + + // all tangents[1] + tempSum = zeroVector; + tempSum = vec_madd( vec1T1, v5, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v5, zeroVector ); + + //vec1T0 now contains what needs to be rsqrt'd and multiplied by f + vec1T1 = vec_sub( vec1T1, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec2T1, v6, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v6, zeroVector ); + vec2T1 = vec_sub( vec2T1, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec3T1, v7, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v7, zeroVector ); + vec3T1 = vec_sub( vec3T1, vecTSum1 ); + + tempSum = zeroVector; + tempSum = vec_madd( vec4T1, v8, tempSum ); + + //sum accross tempSum + vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); + vecTSum1 = vec_madd( vecTSum1, v8, zeroVector ); + vec4T1 = vec_sub( vec4T1, vecTSum1 ); + + + // sum accross vectors and put into one vector + vecTemp = vec_madd( vec1T0, vec1T0, zeroVector ); + vecTSum1 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); + + // element 0 of vecSum now has sum of v0 + vecTemp = vec_madd( vec2T0, vec2T0, zeroVector ); + tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); + // put this into vecSum + vecTemp = vec_madd( vec3T0, vec3T0, zeroVector ); + vecTSum1 = vec_mergeh( vecTSum1, tempSum2 ); + tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); + // put this into vecSum + vecTSum1 = vec_perm( vecTSum1, tempSum2, vecPermHalves ); + vecTemp = vec_madd( vec4T0, vec4T0, zeroVector ); + tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); + // put this into vecSum + vecTSum1 = vec_perm( vecTSum1, tempSum2, vecPermLast ); + + vecTemp = vec_madd( vec1T1, vec1T1, zeroVector ); + vecTSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + vecTSum2 = vec_add( vecTSum2, vec_sld( vecTSum2, vecTSum2, 4 ) ); + // element 0 of vecSum now has sum of v0 + vecTemp = vec_madd( vec2T1, vec2T1, zeroVector ); + tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); + // put this into vecSum + vecTSum2 = vec_mergeh( vecTSum2, tempSum3 ); + vecTemp = vec_madd( vec3T1, vec3T1, zeroVector ); + tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); + // put this into vecSum + vecTSum2 = vec_perm( vecTSum2, tempSum3, vecPermHalves ); + vecTemp = vec_madd( vec4T1, vec4T1, zeroVector ); + tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); + tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); + // put this into vecSum + vecTSum2 = vec_perm( vecTSum2, tempSum3, vecPermLast ); + + // tangents[0] + vecF = ReciprocalSquareRoot( vecTSum1 ); + // tangents[1] + vecF2 = ReciprocalSquareRoot( vecTSum2 ); + + // multiply each tangent vector by f + + vec1T0 = vec_madd( vec1T0, vec_splat( vecF, 0 ), zeroVector ); + vec2T0 = vec_madd( vec2T0, vec_splat( vecF, 1 ), zeroVector ); + vec3T0 = vec_madd( vec3T0, vec_splat( vecF, 2 ), zeroVector ); + vec4T0 = vec_madd( vec4T0, vec_splat( vecF, 3 ), zeroVector ); + + vec1T1 = vec_madd( vec1T1, vec_splat( vecF2, 0 ), zeroVector ); + vec2T1 = vec_madd( vec2T1, vec_splat( vecF2, 1 ), zeroVector ); + vec3T1 = vec_madd( vec3T1, vec_splat( vecF2, 2 ), zeroVector ); + vec4T1 = vec_madd( vec4T1, vec_splat( vecF2, 3 ), zeroVector ); + + // rotate input data + v5 = vec_perm( v5, v5, storePerm0 ); + v6 = vec_perm( v6, v6, storePerm1 ); + v7 = vec_perm( v7, v7, storePerm2 ); + v8 = vec_perm( v8, v8, storePerm3 ); + + vec_ste( v5, 0, addr + ( (i+0) * DRAWVERT_OFFSET ) ); + vec_ste( v5, 4, addr + ( (i+0) * DRAWVERT_OFFSET ) ); + vec_ste( v5, 8, addr + ( (i+0) * DRAWVERT_OFFSET ) ); + + vec_ste( v6, 0, addr + ( (i+1) * DRAWVERT_OFFSET ) ); + vec_ste( v6, 4, addr + ( (i+1) * DRAWVERT_OFFSET ) ); + vec_ste( v6, 8, addr + ( (i+1) * DRAWVERT_OFFSET ) ); + + vec_ste( v7, 0, addr + ( (i+2) * DRAWVERT_OFFSET ) ); + vec_ste( v7, 4, addr + ( (i+2) * DRAWVERT_OFFSET ) ); + vec_ste( v7, 8, addr + ( (i+2) * DRAWVERT_OFFSET ) ); + + vec_ste( v8, 0, addr + ( (i+3) * DRAWVERT_OFFSET ) ); + vec_ste( v8, 4, addr + ( (i+3) * DRAWVERT_OFFSET ) ); + vec_ste( v8, 8, addr + ( (i+3) * DRAWVERT_OFFSET ) ); + + // store tangents[0] and tangents[1] + vec1T0 = vec_perm( vec1T0, vec1T0, storeT11 ); + vec1T1 = vec_perm( vec1T1, vec1T1, storeT12 ); + + vec_ste( vec1T0, 0, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + vec_ste( vec1T0, 4, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + vec_ste( vec1T0, 8, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + vec_ste( vec1T1, 12, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + vec_ste( vec1T1, 16, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + vec_ste( vec1T1, 20, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); + + // store second tangents[0] and tangents[1] + vec2T0 = vec_perm( vec2T0, vec2T0, storeT21 ); + vec2T1 = vec_perm( vec2T1, vec2T1, storeT22 ); + + vec_ste( vec2T0, 0, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + vec_ste( vec2T0, 4, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + vec_ste( vec2T0, 8, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + vec_ste( vec2T1, 12, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + vec_ste( vec2T1, 16, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + vec_ste( vec2T1, 20, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); + + // store third tangents[0] and tangents[1] + vec3T0 = vec_perm( vec3T0, vec3T0, storeT31 ); + vec3T1 = vec_perm( vec3T1, vec3T1, storeT32 ); + + vec_ste( vec3T0, 0, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + vec_ste( vec3T0, 4, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + vec_ste( vec3T0, 8, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + vec_ste( vec3T1, 12, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + vec_ste( vec3T1, 16, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + vec_ste( vec3T1, 20, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); + + // store fourth tangents[0] and tangents[1] + vec4T0 = vec_perm( vec4T0, vec4T0, storeT41 ); + vec4T1 = vec_perm( vec4T1, vec4T1, storeT42 ); + + vec_ste( vec4T0, 0, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + vec_ste( vec4T0, 4, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + vec_ste( vec4T0, 8, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + vec_ste( vec4T1, 12, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + vec_ste( vec4T1, 16, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + vec_ste( vec4T1, 20, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); + } + + // cleanup + for ( ; i < numVerts; i++ ) { + idVec3 &v = verts[i].normal; + float f; + + //f = idMath::RSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); + f = FastScalarInvSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); + v.x *= f; v.y *= f; v.z *= f; + + for ( int j = 0; j < 2; j++ ) { + idVec3 &t = verts[i].tangents[j]; + + t -= ( t * v ) * v; + // f = idMath::RSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); + f = FastScalarInvSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); + t.x *= f; t.y *= f; t.z *= f; + } + } +} +#endif /* ENABLE_DERIVE */ + +#ifdef ENABLE_CREATE + +/* +============ +idSIMD_AltiVec::CreateTextureSpaceLightVectors + + Calculates light vectors in texture space for the given triangle vertices. + For each vertex the direction towards the light origin is projected onto texture space. + The light vectors are only calculated for the vertices referenced by the indexes. +============ +*/ + +void VPCALL idSIMD_AltiVec::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + int i; + for ( i = 0; i+7 < numIndexes; i+= 8 ) { + used[indexes[i]] = true; + used[indexes[i+1]] = true; + used[indexes[i+2]] = true; + used[indexes[i+3]] = true; + used[indexes[i+4]] = true; + used[indexes[i+5]] = true; + used[indexes[i+6]] = true; + used[indexes[i+7]] = true; + } + + for ( ; i < numIndexes; i++ ) { + used[indexes[i]] = true; + } + + for ( i = 0; i+1 < numVerts; i+=2 ) { + + const idDrawVert *v = &verts[i]; + const idDrawVert *v2 = &verts[i+1]; + + float x, y, z; + float x2, y2, z2; + idVec3 lightDir, lightDir2; + + lightDir[0] = lightOrigin[0] - v->xyz[0]; + lightDir[1] = lightOrigin[1] - v->xyz[1]; + lightDir[2] = lightOrigin[2] - v->xyz[2]; + + lightDir2[0] = lightOrigin[0] - v2->xyz[0]; + lightDir2[1] = lightOrigin[1] - v2->xyz[1]; + lightDir2[2] = lightOrigin[2] - v2->xyz[2]; + + x = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; + y = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; + z = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; + + x2 = lightDir2[0] * v2->tangents[0][0] + lightDir2[1] * v2->tangents[0][1] + lightDir2[2] * v2->tangents[0][2]; + y2 = lightDir2[0] * v2->tangents[1][0] + lightDir2[1] * v2->tangents[1][1] + lightDir2[2] * v2->tangents[1][2]; + z2 = lightDir2[0] * v2->normal[0] + lightDir2[1] * v2->normal[1] + lightDir2[2] * v2->normal[2]; + + if ( used[i] ) { + lightVectors[i][0] = x; + lightVectors[i][1] = y; + lightVectors[i][2] = z; + } + + if ( used[i+1] ) { + lightVectors[i+1][0] = x2; + lightVectors[i+1][1] = y2; + lightVectors[i+1][2] = z2; + } + } + + // cleanup + for ( ; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + idVec3 lightDir; + + lightDir[0] = lightOrigin[0] - v->xyz[0]; + lightDir[1] = lightOrigin[1] - v->xyz[1]; + lightDir[2] = lightOrigin[2] - v->xyz[2]; + + lightVectors[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; + lightVectors[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; + lightVectors[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; + } +} + +#if 1 +/* +============ +idSIMD_AltiVec::CreateSpecularTextureCoords + + Calculates specular texture coordinates for the given triangle vertices. + For each vertex the normalized direction towards the light origin is added to the + normalized direction towards the view origin and the result is projected onto texture space. + The texture coordinates are only calculated for the vertices referenced by the indexes. +============ +*/ +void VPCALL idSIMD_AltiVec::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + int i; + for ( i = 0; i+7 < numIndexes; i+= 8 ) { + used[indexes[i]] = true; + used[indexes[i+1]] = true; + used[indexes[i+2]] = true; + used[indexes[i+3]] = true; + used[indexes[i+4]] = true; + used[indexes[i+5]] = true; + used[indexes[i+6]] = true; + used[indexes[i+7]] = true; + } + + for ( ; i < numIndexes; i++ ) { + used[indexes[i]] = true; + } + + // load lightOrigin and viewOrigin into vectors + const float *lightOriginPtr = lightOrigin.ToFloatPtr(); + const float *viewOriginPtr = viewOrigin.ToFloatPtr(); + vector unsigned char permVec = vec_lvsl( 0, lightOriginPtr ); + vector unsigned char permVec2 = vec_lvsl( 0, viewOriginPtr ); + vector float v0 = vec_ld( 0, lightOriginPtr ); + vector float v1 = vec_ld( 15, lightOriginPtr ); + vector float v2 = vec_ld( 0, viewOriginPtr ); + vector float v3 = vec_ld( 15, viewOriginPtr ); + vector float vecLightOrigin = vec_perm( v0, v1, permVec ); + vector float vecViewOrigin = vec_perm( v2, v3, permVec2 ); + const vector float zeroVector = (vector float)(0); + int index; + + for ( index = 0; index+1 < numVerts; index+=2 ) { + const float *vertPtr = verts[index].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[index+1].xyz.ToFloatPtr(); + + permVec = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); + permVec2 = vec_add( vec_lvsl( -1, vertPtr2 ), (vector unsigned char)(1) ); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + vector float v2 = vec_ld( 31, vertPtr ); + vector float v3 = vec_ld( 47, vertPtr ); + vector float v4 = vec_ld( 63, vertPtr ); + + vector float v5 = vec_ld( 0, vertPtr2 ); + vector float v6 = vec_ld( 15, vertPtr2 ); + vector float v7 = vec_ld( 31, vertPtr2 ); + vector float v8 = vec_ld( 47, vertPtr2 ); + vector float v9 = vec_ld( 63, vertPtr2 ); + + // figure out what values go where + vector float vecXYZ = vec_perm( v0, v1, permVec ); + vector float vecNormal = vec_perm( v1, v2, permVec ); + vecNormal = vec_sld( vecNormal, vecNormal, 4 ); + const vector float vecTangent0 = vec_perm( v2, v3, permVec ); + permVec = vec_add( permVec, (vector unsigned char)(-4) ); //shift permute right 3 elements + const vector float vecTangent1 = vec_perm( v3, v4, permVec ); + + vector float vecXYZ2 = vec_perm( v5, v6, permVec2 ); + vector float vecNormal2 = vec_perm( v6, v7, permVec2 ); + vecNormal2 = vec_sld( vecNormal2, vecNormal2, 4 ); + const vector float vecTangent02 = vec_perm( v7, v8, permVec2 ); + permVec2 = vec_add( permVec2, (vector unsigned char)(-4) ); + const vector float vecTangent12 = vec_perm( v8, v9, permVec2 ); + + // calculate lightDir + vector float vecLightDir = vec_sub( vecLightOrigin, vecXYZ ); + vector float vecViewDir = vec_sub( vecViewOrigin, vecXYZ ); + + vector float vecLightDir2 = vec_sub( vecLightOrigin, vecXYZ2 ); + vector float vecViewDir2 = vec_sub( vecViewOrigin, vecXYZ2 ); + + // calculate distance + vector float vecTempLight = vec_madd( vecLightDir, vecLightDir, zeroVector ); + vector float vecTempView = vec_madd( vecViewDir, vecViewDir, zeroVector ); + + vector float vecTempLight2 = vec_madd( vecLightDir2, vecLightDir2, zeroVector ); + vector float vecTempView2 = vec_madd( vecViewDir2, vecViewDir2, zeroVector ); + + // sum accross first 3 elements of vector + vector float tempSum = vec_add( vecTempLight, vec_sld( vecTempLight, vecTempLight, 4 ) ); + vecTempLight = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vector float tempSum2 = vec_add( vecTempView, vec_sld( vecTempView, vecTempView, 4 ) ); + vecTempView = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 8 ) ); + + vector float tempSum4 = vec_add( vecTempLight2, vec_sld( vecTempLight2, vecTempLight2, 4 ) ); + vecTempLight2 = vec_add( tempSum4, vec_sld( tempSum4, tempSum4, 8 ) ); + vector float tempSum5 = vec_add( vecTempView2, vec_sld( vecTempView2, vecTempView2, 4 ) ); + vecTempView2 = vec_add( tempSum5, vec_sld( tempSum5, tempSum5, 8 ) ); + + // splat sum accross the whole vector + vecTempLight = vec_splat( vecTempLight, 0 ); + vecTempView = vec_splat( vecTempView, 0 ); + + vecTempLight2 = vec_splat( vecTempLight2, 0 ); + vecTempView2 = vec_splat( vecTempView2, 0 ); + + vecTempLight = ReciprocalSquareRoot( vecTempLight ); + vecTempView = ReciprocalSquareRoot( vecTempView ); + + vecTempLight2 = ReciprocalSquareRoot( vecTempLight2 ); + vecTempView2 = ReciprocalSquareRoot( vecTempView2 ); + + // modify light and view vectors based on ilength + vecViewDir = vec_madd( vecViewDir, vecTempView, zeroVector ); + vecLightDir = vec_madd( vecLightDir, vecTempLight, vecViewDir ); + + vecViewDir2 = vec_madd( vecViewDir2, vecTempView2, zeroVector ); + vecLightDir2 = vec_madd( vecLightDir2, vecTempLight2, vecViewDir2 ); + + // calculate what to store in each texture coord + vector float vecTC0 = vec_madd( vecLightDir, vecTangent0, zeroVector ); + vector float vecTC1 = vec_madd( vecLightDir, vecTangent1, zeroVector ); + vector float vecTC2 = vec_madd( vecLightDir, vecNormal, zeroVector ); + + vector float vecTC3 = vec_madd( vecLightDir2, vecTangent02, zeroVector ); + vector float vecTC4 = vec_madd( vecLightDir2, vecTangent12, zeroVector ); + vector float vecTC5 = vec_madd( vecLightDir2, vecNormal2, zeroVector ); + + // sum accross first 3 elements of vector + vector float tempSum3; + tempSum = vec_add( vecTC0, vec_sld( vecTC0, vecTC0, 4 ) ); + vecTC0 = vec_add( tempSum, vec_sld( vecTC0, vecTC0, 8 ) ); + tempSum2 = vec_add( vecTC1, vec_sld( vecTC1, vecTC1, 4 ) ); + vecTC1 = vec_add( tempSum2, vec_sld( vecTC1, vecTC1, 8 ) ); + tempSum3 = vec_add( vecTC2, vec_sld( vecTC2, vecTC2, 4 ) ); + vecTC2 = vec_add( tempSum3, vec_sld( vecTC2, vecTC2, 8 ) ); + + tempSum4 = vec_add( vecTC3, vec_sld( vecTC3, vecTC3, 4 ) ); + vecTC3 = vec_add( tempSum4, vec_sld( vecTC3, vecTC3, 8 ) ); + tempSum5 = vec_add( vecTC4, vec_sld( vecTC4, vecTC4, 4 ) ); + vecTC4 = vec_add( tempSum5, vec_sld( vecTC4, vecTC4, 8 ) ); + vector float tempSum6 = vec_add( vecTC5, vec_sld( vecTC5, vecTC5, 4 ) ); + vecTC5 = vec_add( tempSum6, vec_sld( vecTC5, vecTC5, 8 ) ); + + vecTC0 = vec_splat( vecTC0, 0 ); + vecTC1 = vec_splat( vecTC1, 0 ); + vecTC2 = vec_splat( vecTC2, 0 ); + + vecTC3 = vec_splat( vecTC3, 0 ); + vecTC4 = vec_splat( vecTC4, 0 ); + vecTC5 = vec_splat( vecTC5, 0 ); + + if ( used[index] ) { + // store out results + vec_ste( vecTC0, 0, &texCoords[index][0] ); + vec_ste( vecTC1, 0, &texCoords[index][1] ); + vec_ste( vecTC2, 0, &texCoords[index][2] ); + vec_ste( (vector float)(1.0), 0, &texCoords[index][3] ); + } + + if ( used[index+1] ) { + vec_ste( vecTC3, 0, &texCoords[index+1][0] ); + vec_ste( vecTC4, 0, &texCoords[index+1][1] ); + vec_ste( vecTC5, 0, &texCoords[index+1][2] ); + vec_ste( (vector float)(1.0), 0, &texCoords[index+1][3] ); + } + } + + // cleanup + for ( ; index < numVerts; index++ ) { + if ( !used[index] ) { + continue; + } + + const float *vertPtr = verts[index].xyz.ToFloatPtr(); + + permVec = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); + + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + vector float v2 = vec_ld( 31, vertPtr ); + vector float v3 = vec_ld( 47, vertPtr ); + vector float v4 = vec_ld( 63, vertPtr ); + + // figure out what values go where + vector float vecXYZ = vec_perm( v0, v1, permVec ); + vector float vecNormal = vec_perm( v1, v2, permVec ); + vecNormal = vec_sld( vecNormal, vecNormal, 4 ); + const vector float vecTangent0 = vec_perm( v2, v3, permVec ); + permVec = vec_add( permVec, (vector unsigned char)(-4) ); //shift permute right 3 elements + const vector float vecTangent1 = vec_perm( v3, v4, permVec ); + + // calculate lightDir + vector float vecLightDir = vec_sub( vecLightOrigin, vecXYZ ); + vector float vecViewDir = vec_sub( vecViewOrigin, vecXYZ ); + + // calculate distance + vector float vecTempLight = vec_madd( vecLightDir, vecLightDir, zeroVector ); + vector float vecTempView = vec_madd( vecViewDir, vecViewDir, zeroVector ); + + // sum accross first 3 elements of vector + vector float tempSum = vec_add( vecTempLight, vec_sld( vecTempLight, vecTempLight, 4 ) ); + vecTempLight = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); + vector float tempSum2 = vec_add( vecTempView, vec_sld( vecTempView, vecTempView, 4 ) ); + vecTempView = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 8 ) ); + + // splat sum accross the whole vector + vecTempLight = vec_splat( vecTempLight, 0 ); + vecTempView = vec_splat( vecTempView, 0 ); + + vecTempLight = ReciprocalSquareRoot( vecTempLight ); + vecTempView = ReciprocalSquareRoot( vecTempView ); + + // modify light and view vectors based on ilength + vecViewDir = vec_madd( vecViewDir, vecTempView, zeroVector ); + vecLightDir = vec_madd( vecLightDir, vecTempLight, vecViewDir ); + + // calculate what to store in each texture coord + vector float vecTC0 = vec_madd( vecLightDir, vecTangent0, zeroVector ); + vector float vecTC1 = vec_madd( vecLightDir, vecTangent1, zeroVector ); + vector float vecTC2 = vec_madd( vecLightDir, vecNormal, zeroVector ); + + // sum accross first 3 elements of vector + vector float tempSum3; + tempSum = vec_add( vecTC0, vec_sld( vecTC0, vecTC0, 4 ) ); + vecTC0 = vec_add( tempSum, vec_sld( vecTC0, vecTC0, 8 ) ); + tempSum2 = vec_add( vecTC1, vec_sld( vecTC1, vecTC1, 4 ) ); + vecTC1 = vec_add( tempSum2, vec_sld( vecTC1, vecTC1, 8 ) ); + tempSum3 = vec_add( vecTC2, vec_sld( vecTC2, vecTC2, 4 ) ); + vecTC2 = vec_add( tempSum3, vec_sld( vecTC2, vecTC2, 8 ) ); + + vecTC0 = vec_splat( vecTC0, 0 ); + vecTC1 = vec_splat( vecTC1, 0 ); + vecTC2 = vec_splat( vecTC2, 0 ); + + // store out results + vec_ste( vecTC0, 0, &texCoords[index][0] ); + vec_ste( vecTC1, 0, &texCoords[index][1] ); + vec_ste( vecTC2, 0, &texCoords[index][2] ); + vec_ste( (vector float)(1.0), 0, &texCoords[index][3] ); + + } +} +#endif /* 0 for disable spec coord */ + +#if 1 + +#ifdef VERTEXCACHE_ALIGNED +/* +============ +idSIMD_AltiVec::CreateShadowCache +============ +*/ +int VPCALL idSIMD_AltiVec::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { + int outVerts = 0; + int i = 0; + + assert( IS_16BYTE_ALIGNED( vertexCache[0] ) ); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector unsigned char vecPerm, vecPerm2, vecPerm3, vecPerm4, vecPerm5; + register vector float zeroVector = (vector float)(0.0); + register vector float oneVector = (vector float)(1); + register vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + + const float *lPtr = lightOrigin.ToFloatPtr(); + const float *vPtr; + const float *vPtr2; + const float *vPtr3; + const float *vPtr4; + + // put values into a vector + vecPerm = vec_add( vec_lvsl( -1, lPtr ), (vector unsigned char)(1) ); + v0 = vec_ld( 0, lPtr ); + v1 = vec_ld( 15, lPtr ); + v0 = vec_perm( v0, v1, vecPerm ); + v0 = vec_perm( v0, zeroVector, vecPermZeroLast ); + + //v0 now contains lightOrigin[0], lightOrigin[1], lightOrigin[2], 0 + for ( ; i+3 < numVerts; i+= 4 ) { + if ( ! vertRemap[i] ) { + vPtr = verts[i].xyz.ToFloatPtr(); + +#ifndef DRAWVERT_PADDED + vecPerm2 = vec_add( vec_lvsl( -1, vPtr ), (vector unsigned char)(1) ); + v2 = vec_ld( 0, vPtr ); + v3 = vec_ld( 15, vPtr ); + v7 = vec_perm( v2, v3, vecPerm2 ); +#else + v7 = vec_ld( 0, vPtr ); +#endif + v2 = vec_perm( v7, zeroVector, vecPermZeroLast ); + v3 = vec_perm( v7, oneVector, vecPermZeroLast ); + v1 = vec_sub( v2, v0 ); + + vec_st( v3, 0, &vertexCache[outVerts][0] ); + vec_st( v1, 0, &vertexCache[outVerts+1][0] ); + + vertRemap[i] = outVerts; + outVerts += 2; + } + + if ( ! vertRemap[i+1] ) { + vPtr2 = verts[i+1].xyz.ToFloatPtr(); + +#ifndef DRAWVERT_PADDED + vecPerm3 = vec_add( vec_lvsl( -1, vPtr2 ), (vector unsigned char)(1) ); + v4 = vec_ld( 0, vPtr2 ); + v5 = vec_ld( 15, vPtr2 ); + v6 = vec_perm( v4, v5, vecPerm3 ); +#else + v6 = vec_ld( 0, vPtr2 ); +#endif + v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); + v5 = vec_perm( v6, oneVector, vecPermZeroLast ); + v6 = vec_sub( v4, v0 ); + + vec_st( v5, 0, &vertexCache[outVerts][0] ); + vec_st( v6, 0, &vertexCache[outVerts+1][0] ); + + vertRemap[i+1] = outVerts; + outVerts += 2; + } + + if ( ! vertRemap[i+2] ) { + vPtr3 = verts[i+2].xyz.ToFloatPtr(); + +#ifndef DRAWVERT_PADDED + vecPerm4 = vec_add( vec_lvsl( -1, vPtr3 ), (vector unsigned char)(1) ); + v1 = vec_ld( 0, vPtr3 ); + v2 = vec_ld( 15, vPtr3 ); + v3 = vec_perm( v1, v2, vecPerm4 ); +#else + v3 = vec_ld( 0, vPtr3 ); +#endif + v1 = vec_perm( v3, zeroVector, vecPermZeroLast ); + v2 = vec_perm( v3, oneVector, vecPermZeroLast ); + v3 = vec_sub( v1, v0 ); + + vec_st( v2, 0, &vertexCache[outVerts][0] ); + vec_st( v3, 0, &vertexCache[outVerts+1][0] ); + + vertRemap[i+2] = outVerts; + outVerts += 2; + } + + if ( ! vertRemap[i+3] ) { + vPtr4 = verts[i+3].xyz.ToFloatPtr(); +#ifndef DRAWVERT_PADDED + vecPerm5 = vec_add( vec_lvsl( -1, vPtr4 ), (vector unsigned char)(1) ); + v4 = vec_ld( 0, vPtr4 ); + v5 = vec_ld( 16, vPtr4 ); + v6 = vec_perm( v4, v5, vecPerm5 ); +#else + v6 = vec_ld( 0, vPtr4 ); +#endif + v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); + v5 = vec_perm( v6, oneVector, vecPermZeroLast ); + v6 = vec_sub( v4, v0 ); + + vec_st( v5, 0, &vertexCache[outVerts][0] ); + vec_st( v6, 0, &vertexCache[outVerts+1][0] ); + + vertRemap[i+3] = outVerts; + outVerts += 2; + } + } + + // cleanup + for (; i < numVerts; i++ ) { + if ( vertRemap[i] ) { + continue; + } + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[outVerts+0][0] = v[0]; + vertexCache[outVerts+0][1] = v[1]; + vertexCache[outVerts+0][2] = v[2]; + vertexCache[outVerts+0][3] = 1.0f; + + // R_SetupProjection() builds the projection matrix with a slight crunch + // for depth, which keeps this w=0 division from rasterizing right at the + // wrap around point and causing depth fighting with the rear caps + vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; + vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; + vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; + vertexCache[outVerts+1][3] = 0.0f; + vertRemap[i] = outVerts; + outVerts += 2; + } + return outVerts; +} + +#else + +/* +============ +idSIMD_AltiVec::CreateShadowCache +============ +*/ +int VPCALL idSIMD_AltiVec::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { + int outVerts = 0; + int i = 0; + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector unsigned char vecPerm, vecPerm2, vecPerm3, vecPerm4, vecPerm5; + register vector float zeroVector = (vector float)(0.0); + register vector float oneVector = (vector float)(1); + register vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + + const float *lPtr = lightOrigin.ToFloatPtr(); + const float *vPtr; + const float *vPtr2; + const float *vPtr3; + const float *vPtr4; + + // put values into a vector + vecPerm = vec_add( vec_lvsl( -1, lPtr ), (vector unsigned char)(1) ); + v0 = vec_ld( 0, lPtr ); + v1 = vec_ld( 15, lPtr ); + v0 = vec_perm( v0, v1, vecPerm ); + v0 = vec_perm( v0, zeroVector, vecPermZeroLast ); + + //v0 now contains lightOrigin[0], lightOrigin[1], lightOrigin[2], 0 + for ( ; i+3 < numVerts; i+= 4 ) { + if ( ! vertRemap[i] ) { + vPtr = verts[i].xyz.ToFloatPtr(); +#ifndef DRAWVERT_PADDED + vecPerm2 = vec_add( vec_lvsl( -1, vPtr ), (vector unsigned char)(1) ); + v2 = vec_ld( 0, vPtr ); + v3 = vec_ld( 15, vPtr ); + v7 = vec_perm( v2, v3, vecPerm2 ); +#else + v7 = vec_ld( 0, vPtr ); +#endif + v2 = vec_perm( v7, zeroVector, vecPermZeroLast ); + v3 = vec_perm( v7, oneVector, vecPermZeroLast ); + v1 = vec_sub( v2, v0 ); + + // store results + UNALIGNED_STORE2( &vertexCache[outVerts][0], v3, v1 ); + + vertRemap[i] = outVerts; + outVerts += 2; + } + + if ( ! vertRemap[i+1] ) { + vPtr2 = verts[i+1].xyz.ToFloatPtr(); +#ifndef DRAWVERT_PADDED + vecPerm3 = vec_add( vec_lvsl( -1, vPtr2 ), (vector unsigned char)(1) ); + v4 = vec_ld( 0, vPtr2 ); + v5 = vec_ld( 15, vPtr2 ); + v6 = vec_perm( v4, v5, vecPerm3 ); +#else + v6 = vec_ld( 0, vPtr2 ); +#endif + v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); + v5 = vec_perm( v6, oneVector, vecPermZeroLast ); + v6 = vec_sub( v4, v0 ); + + // store results + UNALIGNED_STORE2( &vertexCache[outVerts][0], v5, v6 ); + + vertRemap[i+1] = outVerts; + outVerts += 2; + } + + if ( ! vertRemap[i+2] ) { + vPtr3 = verts[i+2].xyz.ToFloatPtr(); +#ifndef DRAWVERT_PADDED + vecPerm4 = vec_add( vec_lvsl( -1, vPtr3 ), (vector unsigned char)(1) ); + v1 = vec_ld( 0, vPtr3 ); + v2 = vec_ld( 15, vPtr3 ); + v3 = vec_perm( v1, v2, vecPerm4 ); +#else + v3 = vec_ld( 0, vPtr3 ); +#endif + v1 = vec_perm( v3, zeroVector, vecPermZeroLast ); + v2 = vec_perm( v3, oneVector, vecPermZeroLast ); + v3 = vec_sub( v1, v0 ); + + // store results + UNALIGNED_STORE2( &vertexCache[outVerts][0], v2, v3 ); + + vertRemap[i+2] = outVerts; + outVerts += 2; + } + if ( ! vertRemap[i+3] ) { + vPtr4 = verts[i+3].xyz.ToFloatPtr(); +#ifndef DRAWVERT_PADDED + vecPerm5 = vec_add( vec_lvsl( -1, vPtr4 ), (vector unsigned char)(1) ); + v4 = vec_ld( 0, vPtr4 ); + v5 = vec_ld( 16, vPtr4 ); + v6 = vec_perm( v4, v5, vecPerm5 ); +#else + v6 = vec_ld( 0, vPtr4 ); +#endif + + v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); + v5 = vec_perm( v6, oneVector, vecPermZeroLast ); + v6 = vec_sub( v4, v0 ); + + // store results + UNALIGNED_STORE2( &vertexCache[outVerts][0], v5, v6 ); + + + vertRemap[i+3] = outVerts; + outVerts += 2; + } + } + + // cleanup + for (; i < numVerts; i++ ) { + if ( vertRemap[i] ) { + continue; + } + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[outVerts+0][0] = v[0]; + vertexCache[outVerts+0][1] = v[1]; + vertexCache[outVerts+0][2] = v[2]; + vertexCache[outVerts+0][3] = 1.0f; + + // R_SetupProjection() builds the projection matrix with a slight crunch + // for depth, which keeps this w=0 division from rasterizing right at the + // wrap around point and causing depth fighting with the rear caps + vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; + vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; + vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; + vertexCache[outVerts+1][3] = 0.0f; + vertRemap[i] = outVerts; + outVerts += 2; + } + return outVerts; +} +#endif /* VERTEXCACHE_ALIGNED */ + +#endif /* 0 to disable shadow cache */ + +#if 1 + +#ifdef VERTEXCACHE_ALIGNED +/* +============ +idSIMD_AltiVec::CreateVertexProgramShadowCache +============ +*/ +int VPCALL idSIMD_AltiVec::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { + + // vertexCache aligned + assert( IS_16BYTE_ALIGNED( vertexCache[0] ) ); + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + // idVec4 size + assert( sizeof(idVec4) == IDVEC4_OFFSET * sizeof(float) ); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float zeroVector = (vector float)(0.0); + register vector float oneVector = (vector float)(1); + register vector unsigned char vecPermThreeOne = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + int i = 0; + +#ifndef DRAWVERT_PADDED + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < numVerts ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } +#endif + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + +#ifndef DRAWVERT_PADDED + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v1 = vec_perm( v2, v3, vertPerm2 ); + v2 = vec_perm( v4, v5, vertPerm3 ); + v3 = vec_perm( v6, v7, vertPerm4 ); +#else + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 0, vertPtr2 ); + v2 = vec_ld( 0, vertPtr3 ); + v3 = vec_ld( 0, vertPtr4 ); +#endif + + v0 = vec_perm( v0, oneVector, vecPermThreeOne ); + v4 = vec_perm( v0, zeroVector, vecPermThreeOne ); + + v1 = vec_perm( v1, oneVector, vecPermThreeOne ); + v5 = vec_perm( v1, zeroVector, vecPermThreeOne ); + + v2 = vec_perm( v2, oneVector, vecPermThreeOne ); + v6 = vec_perm( v2, zeroVector, vecPermThreeOne ); + + v3 = vec_perm( v3, oneVector, vecPermThreeOne ); + v7 = vec_perm( v3, zeroVector, vecPermThreeOne ); + + // store results + ALIGNED_STORE4( &vertexCache[i*2][0], v0, v4, v1, v5 ); + ALIGNED_STORE4( &vertexCache[(i+2)*2][0], v2, v6, v3, v7 ); + + } + + // cleanup + for ( ; i < numVerts; i++ ) { + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[i*2+0][0] = v[0]; + vertexCache[i*2+1][0] = v[0]; + vertexCache[i*2+0][1] = v[1]; + vertexCache[i*2+1][1] = v[1]; + vertexCache[i*2+0][2] = v[2]; + vertexCache[i*2+1][2] = v[2]; + vertexCache[i*2+0][3] = 1.0f; + vertexCache[i*2+1][3] = 0.0f; + } + return numVerts * 2; +} + +#else +/* +============ +idSIMD_AltiVec::CreateVertexProgramShadowCache +============ +*/ +int VPCALL idSIMD_AltiVec::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { + + // idDrawVert size + assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); + // idVec4 size + assert( sizeof(idVec4) == IDVEC4_OFFSET * sizeof(float) ); + + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector float zeroVector = (vector float)(0.0); + register vector float oneVector = (vector float)(1); + register vector unsigned char vecPermThreeOne = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); + vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; + int i = 0; + +#ifndef DRAWVERT_PADDED + // every fourth one will have the same alignment. Make sure we've got enough here + if ( i+3 < numVerts ) { + vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); + } +#endif + + for ( ; i+3 < numVerts; i+=4 ) { + const float *vertPtr = verts[i].xyz.ToFloatPtr(); + const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); + const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); + const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); + +#ifndef DRAWVERT_PADDED + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 15, vertPtr ); + v2 = vec_ld( 0, vertPtr2 ); + v3 = vec_ld( 15, vertPtr2 ); + v4 = vec_ld( 0, vertPtr3 ); + v5 = vec_ld( 15, vertPtr3 ); + v6 = vec_ld( 0, vertPtr4 ); + v7 = vec_ld( 15, vertPtr4 ); + + v0 = vec_perm( v0, v1, vertPerm1 ); + v1 = vec_perm( v2, v3, vertPerm2 ); + v2 = vec_perm( v4, v5, vertPerm3 ); + v3 = vec_perm( v6, v7, vertPerm4 ); +#else + v0 = vec_ld( 0, vertPtr ); + v1 = vec_ld( 0, vertPtr2 ); + v2 = vec_ld( 0, vertPtr3 ); + v3 = vec_ld( 0, vertPtr4 ); +#endif + + v0 = vec_perm( v0, oneVector, vecPermThreeOne ); + v4 = vec_perm( v0, zeroVector, vecPermThreeOne ); + + v1 = vec_perm( v1, oneVector, vecPermThreeOne ); + v5 = vec_perm( v1, zeroVector, vecPermThreeOne ); + + v2 = vec_perm( v2, oneVector, vecPermThreeOne ); + v6 = vec_perm( v2, zeroVector, vecPermThreeOne ); + + v3 = vec_perm( v3, oneVector, vecPermThreeOne ); + v7 = vec_perm( v3, zeroVector, vecPermThreeOne ); + + // store results as unaligned + vector unsigned char storePerm = vec_sub( vec_lvsr( 15, &vertexCache[i*2][0] ), (vector unsigned char)(1) ); + vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); + vector float vc1 = vec_ld( 0, &vertexCache[i*2][0] ); + vector float vc2 = vec_ld( 127, &vertexCache[i*2][0] ); + + // right rotate input data + v0 = vec_perm( v0, v0, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v1 = vec_perm( v1, v1, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + v2 = vec_perm( v2, v2, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v7 = vec_perm( v7, v7, storePerm ); + + vec_st( vec_sel( vc1, v0, mask ), 0 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v0, v4, mask ), 15 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v4, v1, mask ), 31 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v1, v5, mask ), 47 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v5, v2, mask ), 63 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v2, v6, mask ), 79 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v6, v3, mask ), 95 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v3, v7, mask ), 111 , &vertexCache[i*2][0] ); + vec_st( vec_sel( v7, vc2, mask ), 127 , &vertexCache[i*2][0] ); + } + + // cleanup + for ( ; i < numVerts; i++ ) { + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[i*2+0][0] = v[0]; + vertexCache[i*2+1][0] = v[0]; + vertexCache[i*2+0][1] = v[1]; + vertexCache[i*2+1][1] = v[1]; + vertexCache[i*2+0][2] = v[2]; + vertexCache[i*2+1][2] = v[2]; + vertexCache[i*2+0][3] = 1.0f; + vertexCache[i*2+1][3] = 0.0f; + } + return numVerts * 2; +} + +#endif /* VERTEXCACHE_ALIGNED */ + +#endif /* 0 to kill VP shader cache */ + +#endif /* ENABLE_CREATE */ + +#ifdef ENABLE_SOUND_ROUTINES + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::UpSamplePCMTo44kHz + + Duplicate samples for 44kHz output. + + Assumptions: + Assumes that dest starts at aligned address +============ +*/ +void idSIMD_AltiVec::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { + + // dest is aligned + assert( IS_16BYTE_ALIGNED( dest[0] ) ); + + vector signed short vs0, vs1; + register vector signed int vi0, vi1; + register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; + // permute vectors + register vector unsigned char vecFirstHalf = (vector unsigned char)(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7); + register vector unsigned char vecSecondHalf = (vector unsigned char)(8,9,10,11,12,13,14,15,8,9,10,11,12,13,14,15); + + register vector unsigned char vecBottom = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + register vector unsigned char vecTop = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + + // If this can be assumed true, we can eliminate another conditional that checks to see if we can + // load up a vector before the loop + assert( numSamples >= 12 ); + + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + // 8 at a time + int i = 0; + + vector signed short vsOld = vec_ld( 0, &src[i] ); + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[i] ), (vector unsigned char)(1) ); + + for ( ; i+7 < numSamples; i+= 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // permute into vectors in the order to store + + v2 = vec_splat( v0, 0 ); + v3 = vec_splat( v0, 1 ); + v4 = vec_splat( v0, 2 ); + v5 = vec_splat( v0, 3 ); + v6 = vec_splat( v1, 0 ); + v7 = vec_splat( v1, 1 ); + v8 = vec_splat( v1, 2 ); + v9 = vec_splat( v1, 3 ); + + // store results + ALIGNED_STORE8( &dest[i*4], v2, v3, v4, v5, v6, v7, v8, v9 ); + } + // cleanup + for (; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; + } + } else { + int i = 0; + + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( ; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecFirstHalf ); + v3 = v2; + v4 = vec_perm( v0, v0, vecSecondHalf ); + v5 = v4; + v6 = vec_perm( v1, v1, vecFirstHalf ); + v7 = v6; + v8 = vec_perm (v1, v1, vecSecondHalf ); + v9 = v8; + + // store results + ALIGNED_STORE8( &dest[i*4], v2, v3, v4, v5, v6, v7, v8, v9 ); + } + + for ( ; i < numSamples; i += 2 ) { + dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; + dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 0, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecBottom ); + v3 = vec_perm( v0, v0, vecTop ); + v4 = vec_perm( v1, v1, vecBottom ); + v5 = vec_perm (v1, v1, vecTop ); + + // store results + ALIGNED_STORE4( &dest[i*2], v2, v3, v4, v5 ); + } + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; + } + } else { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecFirstHalf ); + v3 = vec_perm( v0, v0, vecSecondHalf ); + v4 = vec_perm( v1, v1, vecFirstHalf ); + v5 = vec_perm (v1, v1, vecSecondHalf ); + + // store results + ALIGNED_STORE4( &dest[i*2], v2, v3, v4, v5 ); + } + // cleanup + for ( ; i < numSamples; i += 2 ) { + dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; + dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; + } + } + } else if ( kHz == 44100 ) { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + + //unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + + //convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + + //store results + ALIGNED_STORE2( &dest[i], v0, v1 ); + } + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i] = (float) src[i]; + } + } else { + assert( 0 ); + } +} + +#else + +/* +============ +idSIMD_AltiVec::UpSamplePCMTo44kHz + + Duplicate samples for 44kHz output. + + Assumptions: + No assumptions +============ +*/ +void idSIMD_AltiVec::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { + + vector signed short vs0, vs1; + register vector signed int vi0, vi1; + register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; + // permute vectors + register vector unsigned char vecFirstHalf = (vector unsigned char)(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7); + register vector unsigned char vecSecondHalf = (vector unsigned char)(8,9,10,11,12,13,14,15,8,9,10,11,12,13,14,15); + + register vector unsigned char vecBottom = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + register vector unsigned char vecTop = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + + // calculate perm vector and masks for stores + vector unsigned char storePerm = vec_sub( vec_lvsr( 15, &dest[0] ), (vector unsigned char)(1) ); + // original values of dest + vector float vecDest = vec_ld( 0, &dest[0] ); + vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); + + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + // 8 at a time + int i = 0; + + vector signed short vsOld = vec_ld( 0, &src[i] ); + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[i] ), (vector unsigned char)(1) ); + + for ( ; i+7 < numSamples; i+= 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // permute into vectors in the order to store + + v2 = vec_splat( v0, 0 ); + v3 = vec_splat( v0, 1 ); + v4 = vec_splat( v0, 2 ); + v5 = vec_splat( v0, 3 ); + v6 = vec_splat( v1, 0 ); + v7 = vec_splat( v1, 1 ); + v8 = vec_splat( v1, 2 ); + v9 = vec_splat( v1, 3 ); + + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v7 = vec_perm( v7, v7, storePerm ); + v8 = vec_perm( v8, v8, storePerm ); + v9 = vec_perm( v9, v9, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); + vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); + vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); + vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); + vec_st( vec_sel( v5, v6, mask ), 63, &dest[i*4] ); + vec_st( vec_sel( v6, v7, mask ), 79, &dest[i*4] ); + vec_st( vec_sel( v7, v8, mask ), 95, &dest[i*4] ); + vec_st( vec_sel( v8, v9, mask ), 111, &dest[i*4] ); + vecDest = vec_sel( v9, vecDestEnd, mask ); + vec_st( vecDest, 127, &dest[i*4] ); + } + // cleanup + for (; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; + } + } else { + int i = 0; + + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( ; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecFirstHalf ); + v3 = v2; + v4 = vec_perm( v0, v0, vecSecondHalf ); + v5 = v4; + v6 = vec_perm( v1, v1, vecFirstHalf ); + v7 = v6; + v8 = vec_perm (v1, v1, vecSecondHalf ); + v9 = v8; + + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v7 = vec_perm( v7, v7, storePerm ); + v8 = vec_perm( v8, v8, storePerm ); + v9 = vec_perm( v9, v9, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); + vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); + vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); + vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); + vec_st( vec_sel( v5, v6, mask ), 63, &dest[i*4] ); + vec_st( vec_sel( v6, v7, mask ), 79, &dest[i*4] ); + vec_st( vec_sel( v7, v8, mask ), 95, &dest[i*4] ); + vec_st( vec_sel( v8, v9, mask ), 111, &dest[i*4] ); + vecDest = vec_sel( v9, vecDestEnd, mask ); + vec_st( vecDest, 127, &dest[i*4] ); + } + + for ( ; i < numSamples; i += 2 ) { + dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; + dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 0, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecBottom ); + v3 = vec_perm( v0, v0, vecTop ); + v4 = vec_perm( v1, v1, vecBottom ); + v5 = vec_perm (v1, v1, vecTop ); + + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*2] ); + vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*2] ); + vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*2] ); + vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*2] ); + vecDest = vec_sel( v5, vecDestEnd, mask ); + vec_st( vecDest, 63, &dest[i*2] ); + + } + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; + } + } else { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load src + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); + + // unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + // convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + // put into vectors in order to store + v2 = vec_perm( v0, v0, vecFirstHalf ); + v3 = vec_perm( v0, v0, vecSecondHalf ); + v4 = vec_perm( v1, v1, vecFirstHalf ); + v5 = vec_perm (v1, v1, vecSecondHalf ); + + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*2] ); + vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*2] ); + vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*2] ); + vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*2] ); + vecDest = vec_sel( v5, vecDestEnd, mask ); + vec_st( vecDest, 63, &dest[i*2] ); + } + // cleanup + for ( ; i < numSamples; i += 2 ) { + dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; + dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; + } + } + } else if ( kHz == 44100 ) { + int i; + vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); + vector signed short vsOld = vec_ld( 0, &src[0] ); + + for ( i = 0; i+7 < numSamples; i += 8 ) { + //vs0 = vec_ld( 0, &src[i] ); + vs1 = vec_ld( 15, &src[i] ); + vs0 = vec_perm( vsOld, vs1, permVec ); + vsOld = vs1; + vector float vecDestEnd = vec_ld( 31, &dest[i] ); + + //unpack shorts to ints + vi0 = vec_unpackh( vs0 ); + vi1 = vec_unpackl( vs0 ); + + //convert ints to floats + v0 = vec_ctf( vi0, 0 ); + v1 = vec_ctf( vi1, 0 ); + + v0 = vec_perm( v0, v0, storePerm ); + v1 = vec_perm( v1, v1, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i] ); + vec_st( vec_sel( v0, v1, mask ), 15, &dest[i] ); + vecDest = vec_sel( v1, vecDestEnd, mask ); + vec_st( vecDest, 31, &dest[i] ); + } + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i] = (float) src[i]; + } + } else { + assert( 0 ); + } +} + +#endif + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::UpSampleOGGTo44kHz + + Duplicate samples for 44kHz output. + + Assumptions: + Assumes that dest starts at aligned address +============ +*/ +void idSIMD_AltiVec::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { + // dest is aligned + assert( IS_16BYTE_ALIGNED( dest[0] ) ); + + register vector float oggVec1, oggVec2, oggVec3, oggVec4, oggVec5, oggVec6, oggVec7, oggVec8; + register vector float constVec, zeroVector; + register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; + vector unsigned char vecPerm1; + vector unsigned char vecPerm2; + + vector unsigned char vecOneTwo = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + vector unsigned char vecThreeFour = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + vector unsigned char vecFirst = (vector unsigned char)(0,1,2,3,16,17,18,19,0,1,2,3,16,17,18,19); + vector unsigned char vecSecond = (vector unsigned char)(4,5,6,7,20,21,22,23,4,5,6,7,20,21,22,23); + vector unsigned char vecThird = (vector unsigned char)(8,9,10,11,24,25,26,27,8,9,10,11,24,25,26,27); + vector unsigned char vecFourth = (vector unsigned char)(12,13,14,15,28,29,30,31,12,13,14,15,28,29,30,31); + + constVec = (vector float)(32768.0f); + zeroVector = (vector float)(0.0); + + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + v10 = vec_ld( 0, &ogg[0][0] ); + + int i; + for ( i = 0; i+7 < numSamples; i += 8 ) { + // as it happens, ogg[0][i] through ogg[0][i+3] are contiguous in memory + v8 = v10; + v9 = vec_ld( 15, &ogg[0][i] ); + v10 = vec_ld( 31, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + v1 = vec_perm( v9, v10, vecPerm1 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec1 = vec_splat( v0, 0 ); + oggVec2 = vec_splat( v0, 1 ); + oggVec3 = vec_splat( v0, 2 ); + oggVec4 = vec_splat( v0, 3 ); + oggVec5 = vec_splat( v1, 0 ); + oggVec6 = vec_splat( v1, 1 ); + oggVec7 = vec_splat( v1, 2 ); + oggVec8 = vec_splat( v1, 3 ); + + v0 = vec_madd( oggVec1, constVec, zeroVector ); + v1 = vec_madd( oggVec2, constVec, zeroVector ); + v2 = vec_madd( oggVec3, constVec, zeroVector ); + v3 = vec_madd( oggVec4, constVec, zeroVector ); + v4 = vec_madd( oggVec5, constVec, zeroVector ); + v5 = vec_madd( oggVec6, constVec, zeroVector ); + v6 = vec_madd( oggVec7, constVec, zeroVector ); + v7 = vec_madd( oggVec8, constVec, zeroVector ); + + //store results + ALIGNED_STORE8( &dest[i*4], v0, v1, v2, v3, v4, v5, v6, v7 ); + + } + + //cleanup + for ( ; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; + } + + } else { + + // calculate perm vec for ogg + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+3 < numSamples >> 1; i+=4 ) { // +1 += 2 + // load and splat from the array ( ogg[0][i] to ogg[0][i+3] ) + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec1 = vec_splat( v0, 0 ); + oggVec2 = vec_splat( v0, 1 ); + oggVec3 = vec_splat( v0, 2 ); + oggVec4 = vec_splat( v0, 3 ); + + // load and splat from the array ( ogg[1][i] to ogg[1][i+3] ) + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec5 = vec_splat( v1, 0 ); + oggVec6 = vec_splat( v1, 1 ); + oggVec7 = vec_splat( v1, 2 ); + oggVec8 = vec_splat( v1, 3 ); + + oggVec1 = vec_madd( oggVec1, constVec, zeroVector ); // ogg[0][i] * 32768 + oggVec2 = vec_madd( oggVec2, constVec, zeroVector ); // ogg[0][i+1] * 32768 + oggVec3 = vec_madd( oggVec3, constVec, zeroVector ); // ogg[0][i+2] * 32768 + oggVec4 = vec_madd( oggVec4, constVec, zeroVector ); // ogg[0][i+3] * 32768 + oggVec5 = vec_madd( oggVec5, constVec, zeroVector ); // ogg[1][i] * 32768 + oggVec6 = vec_madd( oggVec6, constVec, zeroVector ); // ogg[1][i+1] * 32768 + oggVec7 = vec_madd( oggVec7, constVec, zeroVector ); // ogg[1][i+2] * 32768 + oggVec8 = vec_madd( oggVec8, constVec, zeroVector ); // ogg[1][i+3] * 32768 + + //merge generates the interleaved pattern that we want and it + //doesn't require a permute vector, so use that instead + v0 = vec_mergeh( oggVec1, oggVec5 ); + v1 = vec_mergel( oggVec1, oggVec5 ); + v2 = vec_mergeh( oggVec2, oggVec6 ); + v3 = vec_mergel( oggVec2, oggVec6 ); + + v4 = vec_mergeh( oggVec3, oggVec7 ); + v5 = vec_mergel( oggVec3, oggVec7 ); + v6 = vec_mergeh( oggVec4, oggVec8 ); + v10 = vec_mergel( oggVec4, oggVec8 ); + + //store results + ALIGNED_STORE8( &dest[i*8], v0, v1, v2, v3, v4, v5, v6, v10 ); + } + + //cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; + dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + v10 = vec_ld( 0, &ogg[0][0] ); + + int i; + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load values from ogg + v8 = v10; + v9 = vec_ld( 15, &ogg[0][i] ); + v10 = vec_ld( 31, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + v1 = vec_perm( v9, v10, vecPerm1 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // permute into results vectors to store + v5 = vec_perm( v0, v0, vecOneTwo ); + v6 = vec_perm( v0, v0, vecThreeFour); + v7 = vec_perm( v1, v1, vecOneTwo ); + v8 = vec_perm( v1, v1, vecThreeFour ); + + //store results + ALIGNED_STORE4( &dest[i*2], v5, v6, v7, v8 ); + } + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; + } + } else { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + + int i; + for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { + // load ogg[0][i] to ogg[0][i+4] + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // load ogg[1][i] to ogg[1][i+3] + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // generate result vectors to store + v2 = vec_perm( v0, v1, vecFirst ); + v3 = vec_perm( v0, v1, vecSecond ); + v4 = vec_perm( v0, v1, vecThird ); + v5 = vec_perm( v0, v1, vecFourth ); + + // store results + ALIGNED_STORE4( &dest[i*4], v2, v3, v4, v5 ); + } + // cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; + dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 44100 ) { + if ( numChannels == 1 ) { + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load values from ogg + v8 = v9; + v7 = vec_ld( 15, &ogg[0][i] ); + v6 = v7; + v9 = vec_ld( 31, &ogg[0][i] ); + + v0 = vec_perm( v8, v7, vecPerm1 ); + v1 = vec_perm( v6, v9, vecPerm1 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + ALIGNED_STORE2( &dest[i], v0, v1 ); + } + + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*1+0] = ogg[0][i] * 32768.0f; + } + } else { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // load ogg[1][i] to ogg[1][i+3] + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // generate result vectors + v2 = vec_mergeh( v0, v1 ); + v3 = vec_mergel( v0, v1 ); + + // store results + ALIGNED_STORE2( &dest[i*2], v2, v3 ); + } + // cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*2+0] = ogg[0][i] * 32768.0f; + dest[i*2+1] = ogg[1][i] * 32768.0f; + } + } + } else { + assert( 0 ); + } +} + +#else + +/* +============ +idSIMD_AltiVec::UpSampleOGGTo44kHz + + Duplicate samples for 44kHz output. + + Assumptions: + No assumptions +============ +*/ +void idSIMD_AltiVec::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { + + register vector float oggVec1, oggVec2, oggVec3, oggVec4, oggVec5, oggVec6, oggVec7, oggVec8; + register vector float constVec, zeroVector; + register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; + vector unsigned char vecPerm1; + vector unsigned char vecPerm2; + + vector unsigned char vecOneTwo = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + vector unsigned char vecThreeFour = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + vector unsigned char vecFirst = (vector unsigned char)(0,1,2,3,16,17,18,19,0,1,2,3,16,17,18,19); + vector unsigned char vecSecond = (vector unsigned char)(4,5,6,7,20,21,22,23,4,5,6,7,20,21,22,23); + vector unsigned char vecThird = (vector unsigned char)(8,9,10,11,24,25,26,27,8,9,10,11,24,25,26,27); + vector unsigned char vecFourth = (vector unsigned char)(12,13,14,15,28,29,30,31,12,13,14,15,28,29,30,31); + + vector unsigned char storePerm; + + constVec = (vector float)(32768.0f); + zeroVector = (vector float)(0.0); + + // calculate perm vector and masks for stores + storePerm = vec_sub( vec_lvsr( 15, &dest[0] ), (vector unsigned char)(1) ); + // original values of dest + vector float vecDest = vec_ld( 0, &dest[0] ); + vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); + + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + v10 = vec_ld( 0, &ogg[0][0] ); + + int i; + for ( i = 0; i+7 < numSamples; i += 8 ) { + // as it happens, ogg[0][i] through ogg[0][i+3] are contiguous in memory + v8 = v10; + v9 = vec_ld( 15, &ogg[0][i] ); + v10 = vec_ld( 31, &ogg[0][i] ); + vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + v1 = vec_perm( v9, v10, vecPerm1 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec1 = vec_splat( v0, 0 ); + oggVec2 = vec_splat( v0, 1 ); + oggVec3 = vec_splat( v0, 2 ); + oggVec4 = vec_splat( v0, 3 ); + oggVec5 = vec_splat( v1, 0 ); + oggVec6 = vec_splat( v1, 1 ); + oggVec7 = vec_splat( v1, 2 ); + oggVec8 = vec_splat( v1, 3 ); + + v0 = vec_madd( oggVec1, constVec, zeroVector ); + v1 = vec_madd( oggVec2, constVec, zeroVector ); + v2 = vec_madd( oggVec3, constVec, zeroVector ); + v3 = vec_madd( oggVec4, constVec, zeroVector ); + v4 = vec_madd( oggVec5, constVec, zeroVector ); + v5 = vec_madd( oggVec6, constVec, zeroVector ); + v6 = vec_madd( oggVec7, constVec, zeroVector ); + v7 = vec_madd( oggVec8, constVec, zeroVector ); + + // rotate input data + v0 = vec_perm( v0, v0, storePerm ); + v1 = vec_perm( v1, v1, storePerm ); + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v7 = vec_perm( v7, v7, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i*4] ); + vec_st( vec_sel( v0, v1, mask ), 15, &dest[i*4] ); + vec_st( vec_sel( v1, v2, mask ), 31, &dest[i*4] ); + vec_st( vec_sel( v2, v3, mask ), 47, &dest[i*4] ); + vec_st( vec_sel( v3, v4, mask ), 63, &dest[i*4] ); + vec_st( vec_sel( v4, v5, mask ), 79, &dest[i*4] ); + vec_st( vec_sel( v5, v6, mask ), 95, &dest[i*4] ); + vec_st( vec_sel( v6, v7, mask ), 111, &dest[i*4] ); + vecDest = vec_sel( v7, vecDestEnd, mask ); + vec_st( vecDest, 127, &dest[i*4] ); + } + + //cleanup + for ( ; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; + } + + } else { + + // calculate perm vec for ogg + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+3 < numSamples >> 1; i+=4 ) { // +1 += 2 + // load and splat from the array ( ogg[0][i] to ogg[0][i+3] ) + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + vector float vecDestEnd = vec_ld( 127, &dest[i*8] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec1 = vec_splat( v0, 0 ); + oggVec2 = vec_splat( v0, 1 ); + oggVec3 = vec_splat( v0, 2 ); + oggVec4 = vec_splat( v0, 3 ); + + // load and splat from the array ( ogg[1][i] to ogg[1][i+3] ) + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // now we have the elements in a vector, we want + // to splat them each accross their own vector + oggVec5 = vec_splat( v1, 0 ); + oggVec6 = vec_splat( v1, 1 ); + oggVec7 = vec_splat( v1, 2 ); + oggVec8 = vec_splat( v1, 3 ); + + oggVec1 = vec_madd( oggVec1, constVec, zeroVector ); // ogg[0][i] * 32768 + oggVec2 = vec_madd( oggVec2, constVec, zeroVector ); // ogg[0][i+1] * 32768 + oggVec3 = vec_madd( oggVec3, constVec, zeroVector ); // ogg[0][i+2] * 32768 + oggVec4 = vec_madd( oggVec4, constVec, zeroVector ); // ogg[0][i+3] * 32768 + oggVec5 = vec_madd( oggVec5, constVec, zeroVector ); // ogg[1][i] * 32768 + oggVec6 = vec_madd( oggVec6, constVec, zeroVector ); // ogg[1][i+1] * 32768 + oggVec7 = vec_madd( oggVec7, constVec, zeroVector ); // ogg[1][i+2] * 32768 + oggVec8 = vec_madd( oggVec8, constVec, zeroVector ); // ogg[1][i+3] * 32768 + + //merge generates the interleaved pattern that we want and it + //doesn't require a permute vector, so use that instead + v0 = vec_mergeh( oggVec1, oggVec5 ); + v1 = vec_mergel( oggVec1, oggVec5 ); + v2 = vec_mergeh( oggVec2, oggVec6 ); + v3 = vec_mergel( oggVec2, oggVec6 ); + + v4 = vec_mergeh( oggVec3, oggVec7 ); + v5 = vec_mergel( oggVec3, oggVec7 ); + v6 = vec_mergeh( oggVec4, oggVec8 ); + v10 = vec_mergel( oggVec4, oggVec8 ); + + // rotate input data + v0 = vec_perm( v0, v0, storePerm ); + v1 = vec_perm( v1, v1, storePerm ); + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v10 = vec_perm( v10, v10, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i*8] ); + vec_st( vec_sel( v0, v1, mask ), 15, &dest[i*8] ); + vec_st( vec_sel( v1, v2, mask ), 31, &dest[i*8] ); + vec_st( vec_sel( v2, v3, mask ), 47, &dest[i*8] ); + vec_st( vec_sel( v3, v4, mask ), 63, &dest[i*8] ); + vec_st( vec_sel( v4, v5, mask ), 79, &dest[i*8] ); + vec_st( vec_sel( v5, v6, mask ), 95, &dest[i*8] ); + vec_st( vec_sel( v6, v10, mask ), 111, &dest[i*8] ); + vecDest = vec_sel( v10, vecDestEnd, mask ); + vec_st( vecDest, 127, &dest[i*8] ); + } + + //cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; + dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + v10 = vec_ld( 0, &ogg[0][0] ); + + int i; + + for ( i = 0; i+7 < numSamples; i += 8 ) { + + // load values from ogg + v8 = v10; + v9 = vec_ld( 15, &ogg[0][i] ); + v10 = vec_ld( 31, &ogg[0][i] ); + vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + v1 = vec_perm( v9, v10, vecPerm1 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // permute into results vectors to store + v5 = vec_perm( v0, v0, vecOneTwo ); + v6 = vec_perm( v0, v0, vecThreeFour); + v7 = vec_perm( v1, v1, vecOneTwo ); + v8 = vec_perm( v1, v1, vecThreeFour ); + + // rotate input data + v5 = vec_perm( v5, v5, storePerm ); + v6 = vec_perm( v6, v6, storePerm ); + v7 = vec_perm( v7, v7, storePerm ); + v8 = vec_perm( v8, v8, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v5, mask ), 0, &dest[i*2] ); + vec_st( vec_sel( v5, v6, mask ), 15, &dest[i*2] ); + vec_st( vec_sel( v6, v7, mask ), 31, &dest[i*2] ); + vec_st( vec_sel( v7, v8, mask ), 47, &dest[i*2] ); + vecDest = vec_sel( v8, vecDestEnd, mask ); + vec_st( vecDest, 63, &dest[i*2] ); + } + + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; + } + } else { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + + int i; + for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { + // load ogg[0][i] to ogg[0][i+4] + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + vector float vecDestEnd = vec_ld( 63, &dest[i*4] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // load ogg[1][i] to ogg[1][i+3] + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // generate result vectors to store + v2 = vec_perm( v0, v1, vecFirst ); + v3 = vec_perm( v0, v1, vecSecond ); + v4 = vec_perm( v0, v1, vecThird ); + v5 = vec_perm( v0, v1, vecFourth ); + + // rotate input data + v2 = vec_perm( v2, v2, storePerm ); + v3 = vec_perm( v3, v3, storePerm ); + v4 = vec_perm( v4, v4, storePerm ); + v5 = vec_perm( v5, v5, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); + vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); + vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); + vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); + vecDest = vec_sel( v5, vecDestEnd, mask ); + vec_st( vecDest, 63, &dest[i*4] ); + } + + // cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; + dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 44100 ) { + if ( numChannels == 1 ) { + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+7 < numSamples; i += 8 ) { + // load values from ogg + v8 = v9; + v7 = vec_ld( 15, &ogg[0][i] ); + v6 = v7; + v9 = vec_ld( 31, &ogg[0][i] ); + vector float vecDestEnd = vec_ld( 31, &dest[i] ); + + v0 = vec_perm( v8, v7, vecPerm1 ); + v1 = vec_perm( v6, v9, vecPerm1 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // rotate data + v0 = vec_perm( v0, v0, storePerm ); + v1 = vec_perm( v1, v1, storePerm ); + + // store results + vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i] ); + vec_st( vec_sel( v0, v1, mask ), 15, &dest[i] ); + vecDest = vec_sel( v1, vecDestEnd, mask ); + vec_st( vecDest, 31, &dest[i] ); + } + + // cleanup + for ( ; i < numSamples; i++ ) { + dest[i*1+0] = ogg[0][i] * 32768.0f; + } + } else { + + // calculate perm vector and do first load + vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); + vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); + v7 = vec_ld( 0, &ogg[1][0] ); + v9 = vec_ld( 0, &ogg[0][0] ); + int i; + + for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { + v8 = v9; + v9 = vec_ld( 15, &ogg[0][i] ); + v0 = vec_perm( v8, v9, vecPerm1 ); + + // load ogg[1][i] to ogg[1][i+3] + v6 = v7; + v7 = vec_ld( 15, &ogg[1][i] ); + v1 = vec_perm( v6, v7, vecPerm2 ); + + // multiply + v0 = vec_madd( v0, constVec, zeroVector ); + v1 = vec_madd( v1, constVec, zeroVector ); + + // generate result vectors + v2 = vec_mergeh( v0, v1 ); + v3 = vec_mergel( v0, v1 ); + + // store results + UNALIGNED_STORE2( &dest[i*2], v2, v3 ); + } + // cleanup + for ( ; i < numSamples >> 1; i++ ) { + dest[i*2+0] = ogg[0][i] * 32768.0f; + dest[i*2+1] = ogg[1][i] * 32768.0f; + } + } + } else { + assert( 0 ); + } +} +#endif /* SOUND_DEST_ALIGNED */ + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::MixSoundTwoSpeakerMono + + Assumptions: + Assumes that mixBuffer starts at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + + // mixBuffer is aligned + assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); + + int i; + float inc[2]; + float spkr[4]; + + register vector float vecInc; + register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; + register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; + register vector float vecSamplesLd1, vecSamplesLd2; + register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; + + register vector unsigned char permVec1 = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); //0,0,1,1 + register vector unsigned char permVec2 = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); //2,2,3,3 + register vector unsigned char permVec3 = (vector unsigned char)(16,17,18,19,16,17,18,19,20,21,22,23,20,21,22,23); //4,4,5,5 + register vector unsigned char permVec4 = (vector unsigned char)(24,25,26,27,24,25,26,27,28,29,30,31,28,29,30,31); //6,6,7,7 + + //constants + vector float fourVec = (vector float)(4.0); + vector float zeroVec = (vector float)(0.0); + + inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + spkr[0] = lastV[0]; + spkr[1] = lastV[1]; + spkr[2] = lastV[0] + inc[0]; + spkr[3] = lastV[1] + inc[1]; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + inc[0] *= 2; + inc[1] *= 2; + + //load data into registers + vector float v0 = loadSplatUnalignedScalar( &inc[0] ); + vector float v1 = loadSplatUnalignedScalar( &inc[1] ); + vecInc = vec_mergeh( v0, v1 ); + + vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); + vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); + vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); + vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); + + // load spkr array + v0 = vec_mergeh( v2, v4 ); + v1 = vec_mergeh( v3, v5 ); + vecSpeaker1 = vec_mergeh( v0, v1 ); + + vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); + vecInc = vec_madd( vecInc, fourVec, zeroVec ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 8, we don't + //need a cleanup loop + for( i=0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { + + //load samples and mix buffers + vecSamplesLd1 = vecSamplesLast; //vec_ld( 0, &samples[i] ); + vecSamplesLd2 = vec_ld( 15, &samples[i] ); + vecSamplesLast = vec_ld( 31, &samples[i] ); + + vecSamplesLd1 = vec_perm( vecSamplesLd1, vecSamplesLd2, samplesPerm ); + vecSamplesLd2 = vec_perm( vecSamplesLd2, vecSamplesLast, samplesPerm ); + + vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*2] ); + vecMixBuffer2 = vec_ld( 0, &mixBuffer[i*2+4] ); + vecMixBuffer3 = vec_ld( 0, &mixBuffer[i*2+8] ); + vecMixBuffer4 = vec_ld( 0, &mixBuffer[i*2+12] ); + + vecSamples1 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec1 ); + vecSamples2 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec2 ); + vecSamples3 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec3 ); + vecSamples4 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec4 ); + + vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); + + // store results + ALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); + + //add for next iteration + vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); + } +} + +#else + +/* +============ +idSIMD_AltiVec::MixSoundTwoSpeakerMono + + Assumptions: + No assumptions +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + + int i; + float inc[2]; + float spkr[4]; + + register vector float vecInc; + register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; + register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; + register vector float vecSamplesLd1, vecSamplesLd2; + register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; + + register vector unsigned char permVec1 = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); //0,0,1,1 + register vector unsigned char permVec2 = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); //2,2,3,3 + register vector unsigned char permVec3 = (vector unsigned char)(16,17,18,19,16,17,18,19,20,21,22,23,20,21,22,23); //4,4,5,5 + register vector unsigned char permVec4 = (vector unsigned char)(24,25,26,27,24,25,26,27,28,29,30,31,28,29,30,31); //6,6,7,7 + + //constants + vector float fourVec = (vector float)(4.0); + vector float zeroVec = (vector float)(0.0); + + inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + spkr[0] = lastV[0]; + spkr[1] = lastV[1]; + spkr[2] = lastV[0] + inc[0]; + spkr[3] = lastV[1] + inc[1]; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + inc[0] *= 2; + inc[1] *= 2; + + //load data into registers + vector float v0 = loadSplatUnalignedScalar( &inc[0] ); + vector float v1 = loadSplatUnalignedScalar( &inc[1] ); + vecInc = vec_mergeh( v0, v1 ); + + vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); + vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); + vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); + vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); + + // load spkr array + v0 = vec_mergeh( v2, v4 ); + v1 = vec_mergeh( v3, v5 ); + vecSpeaker1 = vec_mergeh( v0, v1 ); + + vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); + vecInc = vec_madd( vecInc, fourVec, zeroVec ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0]), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + vector float vecDest = vec_ld( 0, &mixBuffer[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 8, we don't + //need a cleanup loop + for( i=0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { + + //load samples and mix buffers + vecSamplesLd1 = vecSamplesLast; + vecSamplesLd2 = vec_ld( 15, &samples[i] ); + vecSamplesLast = vec_ld( 31, &samples[i] ); + + vecSamplesLd1 = vec_perm( vecSamplesLd1, vecSamplesLd2, samplesPerm ); + vecSamplesLd2 = vec_perm( vecSamplesLd2, vecSamplesLast, samplesPerm ); + + vecMixBuffer1 = vecDest; + vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*2] ); + vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*2] ); + vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*2] ); + vector float vecDestEnd = vec_ld( 63, &mixBuffer[i*2] ); + + vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); + vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); + vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); + vecMixBuffer4 = vec_perm( vecMixBuffer4, vecDestEnd, mixBufferPerm ); + + vecSamples1 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec1 ); + vecSamples2 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec2 ); + vecSamples3 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec3 ); + vecSamples4 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec4 ); + + vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); + + // store results + UNALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); + + //add for next iteration + vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); + } +} + +#endif /* SOUND_DEST_ALIGNED */ + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::MixSoundTwoSpeakerStereo + + Assumptions: + Assumes that mixBuffer starts at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + // mixBuffer is aligned + assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); + + int i, k; + float inc[2]; + float spkr[4]; + + // loading buffers + register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; + // loading buffers + register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; + register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; + register vector float vecInc; + vector float fourVec = (vector float)(4.0); + vector float zeroVec = (vector float)(0.0); + + assert( numSamples == MIXBUFFER_SAMPLES ); + + inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + spkr[0] = lastV[0]; + spkr[1] = lastV[1]; + spkr[2] = lastV[0] + inc[0]; + spkr[3] = lastV[1] + inc[1]; + + for ( k = 0; k < 2; k++ ) { + inc[k] *= 2; + } + + // load data in vectors + vector float v0 = loadSplatUnalignedScalar( &inc[0] ); + vector float v1 = loadSplatUnalignedScalar( &inc[1] ); + vecInc = vec_mergeh( v0, v1 ); + + vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); + vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); + vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); + vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); + + // load spkr array + v0 = vec_mergeh( v2, v4 ); + v1 = vec_mergeh( v3, v5 ); + vecSpeaker1 = vec_mergeh( v0, v1 ); + + vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); + vecInc = vec_madd( vecInc, fourVec, zeroVec ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 8, we don't + //need a cleanup loop + for( i = 0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { + // load mix buffers and samples + vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*2] ); + vecMixBuffer2 = vec_ld( 0, &mixBuffer[i*2+4] ); + vecMixBuffer3 = vec_ld( 0, &mixBuffer[i*2+8] ); + vecMixBuffer4 = vec_ld( 0, &mixBuffer[i*2+12] ); + + vecSamples1 = vecSamplesLast; + vecSamples2 = vec_ld( 15, &samples[i*2] ); + vecSamples3 = vec_ld( 31, &samples[i*2] ); + vecSamples4 = vec_ld( 47, &samples[i*2] ); + vecSamplesLast = vec_ld( 63, &samples[i*2] ); + + vecSamples1 = vec_perm( vecSamples1, vecSamples2, samplesPerm ); + vecSamples2 = vec_perm( vecSamples2, vecSamples3, samplesPerm ); + vecSamples3 = vec_perm( vecSamples3, vecSamples4, samplesPerm ); + vecSamples4 = vec_perm( vecSamples4, vecSamplesLast, samplesPerm ); + + vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); + + vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); + + //store results + ALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); + } +} +#else + +/* +============ +idSIMD_AltiVec::MixSoundTwoSpeakerStereo + + Assumptions: + No assumptions +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + + int i, k; + float inc[2]; + float spkr[4]; + // loading buffers + register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; + // loading buffers + register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; + register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; + register vector float vecInc; + vector float fourVec = (vector float)(4.0); + vector float zeroVec = (vector float)(0.0); + + assert( numSamples == MIXBUFFER_SAMPLES ); + + inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + spkr[0] = lastV[0]; + spkr[1] = lastV[1]; + spkr[2] = lastV[0] + inc[0]; + spkr[3] = lastV[1] + inc[1]; + + for ( k = 0; k < 2; k++ ) { + inc[k] *= 2; + } + + // load data in vectors + vector float v0 = loadSplatUnalignedScalar( &inc[0] ); + vector float v1 = loadSplatUnalignedScalar( &inc[1] ); + vecInc = vec_mergeh( v0, v1 ); + + vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); + vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); + vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); + vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); + + // load spkr array + v0 = vec_mergeh( v2, v4 ); + v1 = vec_mergeh( v3, v5 ); + vecSpeaker1 = vec_mergeh( v0, v1 ); + + vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); + vecInc = vec_madd( vecInc, fourVec, zeroVec ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + vector float vecDest = vec_ld( 0, &mixBuffer[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 8, we don't + //need a cleanup loop + for( i = 0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { + // load mix buffers and samples + vecMixBuffer1 = vecDest; + vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*2] ); + vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*2] ); + vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*2] ); + vector float vecDestEnd = vec_ld( 63, &mixBuffer[i*2] ); + + vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); + vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); + vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); + vecMixBuffer4 = vec_perm( vecMixBuffer4, vecDestEnd, mixBufferPerm ); + + vecSamples1 = vecSamplesLast; + vecSamples2 = vec_ld( 15, &samples[i*2] ); + vecSamples3 = vec_ld( 31, &samples[i*2] ); + vecSamples4 = vec_ld( 47, &samples[i*2] ); + vecSamplesLast = vec_ld( 63, &samples[i*2] ); + + vecSamples1 = vec_perm( vecSamples1, vecSamples2, samplesPerm ); + vecSamples2 = vec_perm( vecSamples2, vecSamples3, samplesPerm ); + vecSamples3 = vec_perm( vecSamples3, vecSamples4, samplesPerm ); + vecSamples4 = vec_perm( vecSamples4, vecSamplesLast, samplesPerm ); + + vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); + + vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); + vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); + vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); + vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); + + // store results + UNALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); + } +} + +#endif /* SOUND_DEST_ALIGNED */ + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::MixSoundSixSpeakerMono + + Assumptions: + Assumes that mixBuffer starts at aligned address +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + + // mixBuffer is aligned + assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); + + float incL[24]; + float sL[24]; + int i, k; + + vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4, vecIncl5, vecIncl6, vecIncl7; + vector float vecSL1, vecSL2, vecSL3, vecSL4, vecSL5, vecSL6, vecSL7; + vector float vecSamplesLd; + vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4, vecSamples5, vecSamples6; + vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6; + // permute vectors for sample + vector unsigned char samplePerm2 = (vector unsigned char)( 0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + vector unsigned char samplePerm5 = (vector unsigned char)( 8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + // incL array, 6 elements repeated + incL[0] = incL[6] = incL[12] = incL[18] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL[1] = incL[7] = incL[13] = incL[19] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL[2] = incL[8] = incL[14] = incL[20] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL[3] = incL[9] = incL[15] = incL[21] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL[4] = incL[10] = incL[16] = incL[22] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL[5] = incL[11] = incL[17] = incL[23] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + // sL array repeated + for ( k = 0; k < 6; k++ ) { + sL[k] = lastV[k]; + } + for ( k = 6; k < 12; k++ ) { + sL[k] = lastV[k-6] + incL[k]; + } + for ( k = 12; k < 18; k++ ) { + sL[k] = lastV[k-12] + incL[k] + incL[k]; + } + for ( k = 18; k < 24; k++ ) { + sL[k] = lastV[k-18] + incL[k] + incL[k] + incL[k]; + } + + // multiply by 2 since doing 12 at a time + for ( k = 0; k < 24; k++ ) { + incL[k] *= 4; + } + + //load the data + vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); + vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); + + vecIncl1 = vec_ld( 0, &incL[0] ); + vecIncl2 = vec_ld( 15, &incL[0] ); + vecIncl3 = vec_ld( 31, &incL[0] ); + vecIncl4 = vec_ld( 47, &incL[0] ); + vecIncl5 = vec_ld( 63, &incL[0] ); + vecIncl6 = vec_ld( 79, &incL[0] ); + vecIncl7 = vec_ld( 95, &incL[0] ); + + vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); + vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); + vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); + vecIncl4 = vec_perm( vecIncl4, vecIncl5, incPerm ); + vecIncl5 = vec_perm( vecIncl5, vecIncl6, incPerm ); + vecIncl6 = vec_perm( vecIncl6, vecIncl7, incPerm ); + + vecSL1 = vec_ld( 0, &sL[0] ); + vecSL2 = vec_ld( 15, &sL[0] ); + vecSL3 = vec_ld( 31, &sL[0] ); + vecSL4 = vec_ld( 47, &sL[0] ); + vecSL5 = vec_ld( 63, &sL[0] ); + vecSL6 = vec_ld( 79, &sL[0] ); + vecSL7 = vec_ld( 95, &sL[0] ); + + vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); + vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); + vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); + vecSL4 = vec_perm( vecSL4, vecSL5, slPerm ); + vecSL5 = vec_perm( vecSL5, vecSL6, slPerm ); + vecSL6 = vec_perm( vecSL6, vecSL7, slPerm ); + + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 4, we don't + //need a cleanup loop + for( i = 0; i <= MIXBUFFER_SAMPLES - 4; i += 4 ) { + //load mix buffer into vectors, assume aligned + vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*6] ); + vecMixBuffer2 = vec_ld( 0, &mixBuffer[(i*6)+4] ); + vecMixBuffer3 = vec_ld( 0, &mixBuffer[(i*6)+8] ); + vecMixBuffer4 = vec_ld( 0, &mixBuffer[(i*6)+12] ); + vecMixBuffer5 = vec_ld( 0, &mixBuffer[(i*6)+16] ); + vecMixBuffer6 = vec_ld( 0, &mixBuffer[(i*6)+20] ); + + //load samples into vector + vector float vecSamplesLd2 = vec_ld( 15, &samples[i] ); + vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); + vecSamplesLast = vecSamplesLd2; + + //permute to get them ordered how we want + vecSamples1 = vec_splat( vecSamplesLd, 0 ); + vecSamples2 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm2 ); + vecSamples3 = vec_splat( vecSamplesLd, 1 ); + vecSamples4 = vec_splat( vecSamplesLd, 2 ); + vecSamples5 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm5 ); + vecSamples6 = vec_splat( vecSamplesLd, 3 ); + + //do calculation + vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSL4, vecMixBuffer4 ); + vecMixBuffer5 = vec_madd( vecSamples5, vecSL5, vecMixBuffer5 ); + vecMixBuffer6 = vec_madd( vecSamples6, vecSL6, vecMixBuffer6 ); + + //store out results + ALIGNED_STORE6( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6 ); + + // add for next iteration + vecSL1 = vec_add( vecSL1, vecIncl1 ); + vecSL2 = vec_add( vecSL2, vecIncl2 ); + vecSL3 = vec_add( vecSL3, vecIncl3 ); + vecSL4 = vec_add( vecSL4, vecIncl4 ); + vecSL5 = vec_add( vecSL5, vecIncl5 ); + vecSL6 = vec_add( vecSL6, vecIncl6 ); + } +} +#else + +/* +============ +idSIMD_AltiVec::MixSoundSixSpeakerMono + + Assumptions: + No assumptions +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + + float incL[24]; + float sL[24]; + int i, k; + + vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4, vecIncl5, vecIncl6, vecIncl7; + vector float vecSL1, vecSL2, vecSL3, vecSL4, vecSL5, vecSL6, vecSL7; + vector float vecSamplesLd; + vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4, vecSamples5, vecSamples6; + vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6; + // permute vectors for sample + register vector unsigned char samplePerm2 = (vector unsigned char)( 0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); + register vector unsigned char samplePerm5 = (vector unsigned char)( 8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + // incL array, 6 elements repeated + incL[0] = incL[6] = incL[12] = incL[18] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL[1] = incL[7] = incL[13] = incL[19] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL[2] = incL[8] = incL[14] = incL[20] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL[3] = incL[9] = incL[15] = incL[21] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL[4] = incL[10] = incL[16] = incL[22] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL[5] = incL[11] = incL[17] = incL[23] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + // sL array repeated + for ( k = 0; k < 6; k++ ) { + sL[k] = lastV[k]; + } + for ( k = 6; k < 12; k++ ) { + sL[k] = lastV[k-6] + incL[k]; + } + for ( k = 12; k < 18; k++ ) { + sL[k] = lastV[k-12] + incL[k] + incL[k]; + } + for ( k = 18; k < 24; k++ ) { + sL[k] = lastV[k-18] + incL[k] + incL[k] + incL[k]; + } + + // multiply by 2 since doing 12 at a time + for ( k = 0; k < 24; k++ ) { + incL[k] *= 4; + } + + // load the data + vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); + vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); + + vecIncl1 = vec_ld( 0, &incL[0] ); + vecIncl2 = vec_ld( 15, &incL[0] ); + vecIncl3 = vec_ld( 31, &incL[0] ); + vecIncl4 = vec_ld( 47, &incL[0] ); + vecIncl5 = vec_ld( 63, &incL[0] ); + vecIncl6 = vec_ld( 79, &incL[0] ); + vecIncl7 = vec_ld( 95, &incL[0] ); + + vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); + vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); + vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); + vecIncl4 = vec_perm( vecIncl4, vecIncl5, incPerm ); + vecIncl5 = vec_perm( vecIncl5, vecIncl6, incPerm ); + vecIncl6 = vec_perm( vecIncl6, vecIncl7, incPerm ); + + vecSL1 = vec_ld( 0, &sL[0] ); + vecSL2 = vec_ld( 15, &sL[0] ); + vecSL3 = vec_ld( 31, &sL[0] ); + vecSL4 = vec_ld( 47, &sL[0] ); + vecSL5 = vec_ld( 63, &sL[0] ); + vecSL6 = vec_ld( 79, &sL[0] ); + vecSL7 = vec_ld( 95, &sL[0] ); + + vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); + vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); + vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); + vecSL4 = vec_perm( vecSL4, vecSL5, slPerm ); + vecSL5 = vec_perm( vecSL5, vecSL6, slPerm ); + vecSL6 = vec_perm( vecSL6, vecSL7, slPerm ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + vector float vecDest = vec_ld( 0, &mixBuffer[0] ); + + //since MIXBUFFER_SAMPLES is a multiple of 4, we don't + //need a cleanup loop + for( i = 0; i <= MIXBUFFER_SAMPLES - 4; i += 4 ) { + //load mix buffer into vectors + vecMixBuffer1 = vecDest; + vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*6] ); + vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*6] ); + vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*6] ); + vecMixBuffer5 = vec_ld( 63, &mixBuffer[i*6] ); + vecMixBuffer6 = vec_ld( 79, &mixBuffer[i*6] ); + vector float vecDestEnd = vec_ld( 95, &mixBuffer[i*6] ); + + vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); + vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); + vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); + vecMixBuffer4 = vec_perm( vecMixBuffer4, vecMixBuffer5, mixBufferPerm ); + vecMixBuffer5 = vec_perm( vecMixBuffer5, vecMixBuffer6, mixBufferPerm ); + vecMixBuffer6 = vec_perm( vecMixBuffer6, vecDestEnd, mixBufferPerm ); + + //load samples into vector + vector float vecSamplesLd2 = vec_ld( 15, &samples[i] ); + vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); + vecSamplesLast = vecSamplesLd2; + + //permute to get them ordered how we want + vecSamples1 = vec_splat( vecSamplesLd, 0 ); + vecSamples2 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm2 ); + vecSamples3 = vec_splat( vecSamplesLd, 1 ); + vecSamples4 = vec_splat( vecSamplesLd, 2 ); + vecSamples5 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm5 ); + vecSamples6 = vec_splat( vecSamplesLd, 3 ); + + //do calculation + vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); + vecMixBuffer4 = vec_madd( vecSamples4, vecSL4, vecMixBuffer4 ); + vecMixBuffer5 = vec_madd( vecSamples5, vecSL5, vecMixBuffer5 ); + vecMixBuffer6 = vec_madd( vecSamples6, vecSL6, vecMixBuffer6 ); + + // store results + UNALIGNED_STORE6( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6 ); + + // add for next iteration + vecSL1 = vec_add( vecSL1, vecIncl1 ); + vecSL2 = vec_add( vecSL2, vecIncl2 ); + vecSL3 = vec_add( vecSL3, vecIncl3 ); + vecSL4 = vec_add( vecSL4, vecIncl4 ); + vecSL5 = vec_add( vecSL5, vecIncl5 ); + vecSL6 = vec_add( vecSL6, vecIncl6 ); + } +} + +#endif /* SOUND_DEST_ALIGNED */ + +#ifdef SOUND_DEST_ALIGNED +/* +============ +idSIMD_AltiVec::MixSoundSixSpeakerStereo + + Assumptions: + Assumes that mixBuffer starts at aligned address +============ +*/ + +void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + + // mixBuffer is aligned + assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); + + float incL[12]; + float sL[12]; + int i; + vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4; + vector float vecSL1, vecSL2, vecSL3, vecSL4; + vector float vecSamplesLd; + vector float vecSamples1, vecSamples2, vecSamples3; + vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3; + // permute vectors for sample + vector unsigned char samplePerm1 = (vector unsigned char)( 0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3); + vector unsigned char samplePerm3 = (vector unsigned char)( 8,9,10,11,8,9,10,11,8,9,10,11,12,13,14,15); + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + // incL array, 6 elements repeated + incL[0] = incL[6] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL[1] = incL[7] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL[2] = incL[8] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL[3] = incL[9] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL[4] = incL[10] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL[5] = incL[11] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + // sL array repeated + sL[0] = lastV[0]; + sL[1] = lastV[1]; + sL[2] = lastV[2]; + sL[3] = lastV[3]; + sL[4] = lastV[4]; + sL[5] = lastV[5]; + sL[6] = lastV[0] + incL[0]; + sL[7] = lastV[1] + incL[1]; + sL[8] = lastV[2] + incL[2]; + sL[9] = lastV[3] + incL[3]; + sL[10] = lastV[4] + incL[4]; + sL[11] = lastV[5] + incL[5]; + + // multiply by 2 since doing 12 at a time + incL[0] *= 2; + incL[1] *= 2; + incL[2] *= 2; + incL[3] *= 2; + incL[4] *= 2; + incL[5] *= 2; + incL[6] *= 2; + incL[7] *= 2; + incL[8] *= 2; + incL[9] *= 2; + incL[10] *= 2; + incL[11] *= 2; + + //we aligned this data, so load it up + vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); + vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); + vecIncl1 = vec_ld( 0, &incL[0] ); + vecIncl2 = vec_ld( 15, &incL[0] ); + vecIncl3 = vec_ld( 31, &incL[0] ); + vecIncl4 = vec_ld( 47, &incL[0] ); + + vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); + vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); + vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); + + vecSL1 = vec_ld( 0, &sL[0] ); + vecSL2 = vec_ld( 15, &sL[0] ); + vecSL3 = vec_ld( 31, &sL[0] ); + vecSL4 = vec_ld( 47, &sL[0] ); + + vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); + vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); + vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + + for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { + + //load mix buffer into vectors, assume aligned + vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*6] ); + vecMixBuffer2 = vec_ld( 0, &mixBuffer[(i*6)+4] ); + vecMixBuffer3 = vec_ld( 0, &mixBuffer[(i*6)+8] ); + + //load samples into vector + vector float vecSamplesLd2 = vec_ld( 15, &samples[i*2] ); + vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); + vecSamplesLast = vecSamplesLd2; + + //permute to get them ordered how we want. For the 2nd vector, + //the order happens to be the same as the order we loaded them + //in, so there's no need to permute that one + vecSamples1 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm1 ); + vecSamples2 = vecSamplesLd; + vecSamples3 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm3 ); + + //do calculation + vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); + + //store out results + ALIGNED_STORE3( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3 ); + + // add for next iteration + vecSL1 = vec_add( vecSL1, vecIncl1 ); + vecSL2 = vec_add( vecSL2, vecIncl2 ); + vecSL3 = vec_add( vecSL3, vecIncl3 ); + } +} +#else + +/* +============ +idSIMD_AltiVec::MixSoundSixSpeakerStereo + + Assumptions: + No assumptions +============ +*/ +void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + + float incL[12]; + float sL[12]; + + int i; + vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4; + vector float vecSL1, vecSL2, vecSL3, vecSL4; + vector float vecSamplesLd; + vector float vecSamples1, vecSamples2, vecSamples3; + vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3; + // permute vectors for sample + vector unsigned char samplePerm1 = (vector unsigned char)( 0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3); + vector unsigned char samplePerm3 = (vector unsigned char)( 8,9,10,11,8,9,10,11,8,9,10,11,12,13,14,15); + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + // incL array, 6 elements repeated + incL[0] = incL[6] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL[1] = incL[7] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL[2] = incL[8] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL[3] = incL[9] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL[4] = incL[10] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL[5] = incL[11] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + // sL array repeated + sL[0] = lastV[0]; + sL[1] = lastV[1]; + sL[2] = lastV[2]; + sL[3] = lastV[3]; + sL[4] = lastV[4]; + sL[5] = lastV[5]; + sL[6] = lastV[0] + incL[0]; + sL[7] = lastV[1] + incL[1]; + sL[8] = lastV[2] + incL[2]; + sL[9] = lastV[3] + incL[3]; + sL[10] = lastV[4] + incL[4]; + sL[11] = lastV[5] + incL[5]; + + // multiply by 2 since doing 12 at a time + incL[0] *= 2; + incL[1] *= 2; + incL[2] *= 2; + incL[3] *= 2; + incL[4] *= 2; + incL[5] *= 2; + incL[6] *= 2; + incL[7] *= 2; + incL[8] *= 2; + incL[9] *= 2; + incL[10] *= 2; + incL[11] *= 2; + + // load the data + vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); + vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); + vecIncl1 = vec_ld( 0, &incL[0] ); + vecIncl2 = vec_ld( 15, &incL[0] ); + vecIncl3 = vec_ld( 31, &incL[0] ); + vecIncl4 = vec_ld( 47, &incL[0] ); + + vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); + vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); + vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); + + vecSL1 = vec_ld( 0, &sL[0] ); + vecSL2 = vec_ld( 15, &sL[0] ); + vecSL3 = vec_ld( 31, &sL[0] ); + vecSL4 = vec_ld( 47, &sL[0] ); + + vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); + vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); + vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); + + vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); + vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); + vector float vecSamplesLast = vec_ld( 0, &samples[0] ); + vector float vecDest = vec_ld( 0, &mixBuffer[0] ); + + for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { + + //load mix buffer into vectors + vecMixBuffer1 = vecDest; + vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*6] ); + vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*6] ); + vector float vecDestEnd = vec_ld( 47, &mixBuffer[i*6] ); + + vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); + vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); + vecMixBuffer3 = vec_perm( vecMixBuffer3, vecDestEnd, mixBufferPerm ); + + //load samples into vector + vector float vecSamplesLd2 = vec_ld( 15, &samples[i*2] ); + vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); + vecSamplesLast = vecSamplesLd2; + + //permute to get them ordered how we want. For the 2nd vector, + //the order happens to be the same as the order we loaded them + //in, so there's no need to permute that one + vecSamples1 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm1 ); + vecSamples2 = vecSamplesLd; + vecSamples3 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm3 ); + + //do calculation + vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); + vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); + vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); + + // store results + UNALIGNED_STORE3( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3 ); + + // add for next iteration + vecSL1 = vec_add( vecSL1, vecIncl1 ); + vecSL2 = vec_add( vecSL2, vecIncl2 ); + vecSL3 = vec_add( vecSL3, vecIncl3 ); + } +} + +#endif + +/* +============ +idSIMD_AltiVec::MixedSoundToSamples +============ +*/ +void VPCALL idSIMD_AltiVec::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { + //this is basically a clamp for sound mixing + register vector float v0, v1, v2, v3, v4, v5, v6, v7; + register vector signed int vi0, vi1, vi2, vi3; + register vector signed short vs0, vs1; + register vector float minVec, maxVec, constVec; + int i = 0; + + //unaligned at start, since samples is not 16-byte aligned + for ( ; NOT_16BYTE_ALIGNED( samples[i] ) && ( i < numSamples ); i++ ) { + samples[i] = mixBuffer[i] <= -32768.0f ? -32768 : mixBuffer[i] >= 32767.0f ? 32767 : (short) mixBuffer[i]; + } + + constVec = (vector float)(65536.0f); + + //splat min/max into a vector + minVec = (vector float)(-32768.0f); + maxVec = (vector float)(32767.0f); + + vector float vecOld = vec_ld( 0, &mixBuffer[i] ); + vector unsigned char permVec = vec_add( vec_lvsl( -1, &mixBuffer[i] ), (vector unsigned char)(1) ); + + //vectorize! + for ( ; i+15 < numSamples; i += 16 ) { + //load source + v0 = vecOld; + v1 = vec_ld( 15, &mixBuffer[i] ); + v2 = vec_ld( 31, &mixBuffer[i] ); + v3 = vec_ld( 31, &mixBuffer[i] ); + vecOld = vec_ld( 47, &mixBuffer[i] ); + + v0 = vec_perm( v0, v1, permVec ); + v1 = vec_perm( v1, v2, permVec ); + v2 = vec_perm( v2, v3, permVec ); + v3 = vec_perm( v3, vecOld, permVec ); + + //apply minimum + v4 = vec_max( v0, minVec ); + v5 = vec_max( v1, minVec ); + v6 = vec_max( v2, minVec ); + v7 = vec_max( v3, minVec ); + + //apply maximum + v4 = vec_min( v4, maxVec ); + v5 = vec_min( v5, maxVec ); + v6 = vec_min( v6, maxVec ); + v7 = vec_min( v7, maxVec ); + + // convert floats to ints + vi0 = vec_cts( v4, 0 ); + vi1 = vec_cts( v5, 0 ); + vi2 = vec_cts( v6, 0 ); + vi3 = vec_cts( v7, 0 ); + + // pack ints into shorts + vs0 = vec_pack( vi0, vi1 ); + vs1 = vec_pack( vi2, vi3 ); + ALIGNED_STORE2( &samples[i], vs0, vs1 ); + } + + //handle cleanup + for ( ; i < numSamples ; i++ ) { + samples[i] = mixBuffer[i] <= -32768.0f ? -32768 : mixBuffer[i] >= 32767.0f ? 32767 : (short) mixBuffer[i]; + } +} +#endif /* ENABLE_SOUND_ROUTINES */ + +#endif /* MACOS_X */ diff --git a/idlib/math/Simd_AltiVec.h b/idlib/math/Simd_AltiVec.h new file mode 100644 index 000000000..6456a15cc --- /dev/null +++ b/idlib/math/Simd_AltiVec.h @@ -0,0 +1,241 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_ALTIVEC_H__ +#define __MATH_SIMD_ALTIVEC_H__ + +/* +=============================================================================== + + AltiVec implementation of idSIMDProcessor + +=============================================================================== +*/ + +// Defines for enabling parts of the library + +// Turns on/off the simple math routines (add, sub, div, etc) +#define ENABLE_SIMPLE_MATH + +// Turns on/off the dot routines +#define ENABLE_DOT + +// Turns on/off the compare routines +#define ENABLE_COMPARES + +// The MinMax routines introduce a couple of bugs. In the bathroom of the alphalabs2 map, the +// wrong surface appears in the mirror at times. It also introduces a noticable delay when map +// data is loaded such as going through doors. +// Turns on/off MinMax routines +//#define ENABLE_MINMAX + +// Turns on/off Clamp routines +#define ENABLE_CLAMP + +// Turns on/off XXX16 routines +#define ENABLE_16ROUTINES + +// Turns on/off LowerTriangularSolve, LowerTriangularSolveTranspose, and MatX_LDLTFactor +#define ENABLE_LOWER_TRIANGULAR + +// Turns on/off TracePointCull, DecalPointCull, and OverlayPoint +// The Enable_Cull routines breaks the g_decals functionality, DecalPointCull is +// the likely suspect. Bullet holes do not appear on the walls when this optimization +// is enabled. +//#define ENABLE_CULL + +// Turns on/off DeriveTriPlanes, DeriveTangents, DeriveUnsmoothedTangents, NormalizeTangents +#define ENABLE_DERIVE + +// Turns on/off CreateTextureSpaceLightVectors, CreateShadowCache, CreateVertexProgramShadowCache +#define ENABLE_CREATE + +// Turns on/off the sound routines +#define ENABLE_SOUND_ROUTINES + +// Turns on/off the stuff that isn't on elsewhere +// Currently: BlendJoints, TransformJoints, UntransformJoints, ConvertJointQuatsToJointMats, and +// ConvertJointMatsToJointQuats +#define LIVE_VICARIOUSLY + +// This assumes that the dest (and mixBuffer) array to the sound functions is aligned. If this is not true, we take a large +// performance hit from having to do unaligned stores +//#define SOUND_DEST_ALIGNED + +// This assumes that the vertexCache array to CreateShadowCache and CreateVertexProgramShadowCache is aligned. If it's not, +// then we take a big performance hit from unaligned stores. +//#define VERTEXCACHE_ALIGNED + +// This turns on support for PPC intrinsics in the SIMD_AltiVec.cpp file. Right now it's only used for frsqrte. GCC +// supports these intrinsics but XLC does not. +#define PPC_INTRINSICS + +// This assumes that the idDrawVert array that is used in DeriveUnsmoothedTangents is aligned. If its not aligned, +// then we don't get any speedup +//#define DERIVE_UNSMOOTH_DRAWVERT_ALIGNED + +// Disable DRAWVERT_PADDED since we disabled the ENABLE_CULL optimizations and the default +// implementation does not allow for the extra padding. +// This assumes that idDrawVert has been padded by 4 bytes so that xyz always starts at an aligned +// address +//#define DRAWVERT_PADDED + +class idSIMD_AltiVec : public idSIMD_Generic { +#if defined(MACOS_X) && defined(__ppc__) +public: + + virtual const char * VPCALL GetName( void ) const; + +#ifdef ENABLE_SIMPLE_MATH + // Basic math, works for both aligned and unaligned data + virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count); + virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Div( float *dst, const float constant, const float *divisor, const int count ); + virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); +#endif + +#ifdef ENABLE_DOT + // Dot products, expects data structures in contiguous memory + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); + virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); +#endif + +#ifdef ENABLE_COMPARES + // Comparisons, works for both aligned and unaligned data + virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); +#endif + +#ifdef ENABLE_MINMAX + // Min/Max. Expects data structures in contiguous memory + virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); + virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); +#endif + +#ifdef ENABLE_CLAMP + // Clamp operations. Works for both aligned and unaligned data + virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); + virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); + virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); +#endif + + // These are already using memcpy and memset functions. Leaving default implementation +// virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); +// virtual void VPCALL Memset( void *dst, const int val, const int count ); + +#ifdef ENABLE_16ROUTINES + // Operations that expect 16-byte aligned data and 16-byte padded memory (with zeros), generally faster + virtual void VPCALL Zero16( float *dst, const int count ); + virtual void VPCALL Negate16( float *dst, const int count ); + virtual void VPCALL Copy16( float *dst, const float *src, const int count ); + virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); + virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); +#endif + +// Most of these deal with tiny matrices or vectors, generally not worth altivec'ing since +// the scalar code is already really fast + +// virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); +// virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); +// virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); + +#ifdef ENABLE_LOWER_TRIANGULAR + virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); + virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); + virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); +#endif +#ifdef LIVE_VICARIOUSLY + virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); + virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); + virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); +#endif + +#ifdef LIVE_VICARIOUSLY + virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); +#endif + +#ifdef ENABLE_CULL + virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); +#endif + +#ifdef ENABLE_DERIVE + virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); + virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); +#endif + +#ifdef ENABLE_CREATE + virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); + virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); +#endif + +#ifdef ENABLE_SOUND_ROUTINES + // Sound upsampling and mixing routines, works for aligned and unaligned data + virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); +#endif +#endif + +}; + +#endif /* !__MATH_SIMD_ALTIVEC_H__ */ diff --git a/idlib/math/Simd_Generic.cpp b/idlib/math/Simd_Generic.cpp new file mode 100644 index 000000000..d137df7f3 --- /dev/null +++ b/idlib/math/Simd_Generic.cpp @@ -0,0 +1,3051 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" + + +//=============================================================== +// +// Generic implementation of idSIMDProcessor +// +//=============================================================== + +#define UNROLL1(Y) { int _IX; for (_IX=0;_IX constant; +============ +*/ +void VPCALL idSIMD_Generic::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] = src0[(X)] > constant; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpGT + + dst[i] |= ( src0[i] > constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_Generic::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] |= ( src0[(X)] > constant ) << bitNum; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpGE + + dst[i] = src0[i] >= constant; +============ +*/ +void VPCALL idSIMD_Generic::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] = src0[(X)] >= constant; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpGE + + dst[i] |= ( src0[i] >= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_Generic::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] |= ( src0[(X)] >= constant ) << bitNum; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpLT + + dst[i] = src0[i] < constant; +============ +*/ +void VPCALL idSIMD_Generic::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] = src0[(X)] < constant; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpLT + + dst[i] |= ( src0[i] < constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_Generic::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] |= ( src0[(X)] < constant ) << bitNum; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpLE + + dst[i] = src0[i] <= constant; +============ +*/ +void VPCALL idSIMD_Generic::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] = src0[(X)] <= constant; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::CmpLE + + dst[i] |= ( src0[i] <= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_Generic::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { +#define OPER(X) dst[(X)] |= ( src0[(X)] <= constant ) << bitNum; + UNROLL4(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MinMax +============ +*/ +void VPCALL idSIMD_Generic::MinMax( float &min, float &max, const float *src, const int count ) { + min = idMath::INFINITY; max = -idMath::INFINITY; +#define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];} + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MinMax +============ +*/ +void VPCALL idSIMD_Generic::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { + min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY; +#define OPER(X) const idVec2 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MinMax +============ +*/ +void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; +#define OPER(X) const idVec3 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MinMax +============ +*/ +void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; +#define OPER(X) const idVec3 &v = src[(X)].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MinMax +============ +*/ +void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { + min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; +#define OPER(X) const idVec3 &v = src[indexes[(X)]].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::Clamp +============ +*/ +void VPCALL idSIMD_Generic::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { +#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)] > max ? max : src[(X)]; + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::ClampMin +============ +*/ +void VPCALL idSIMD_Generic::ClampMin( float *dst, const float *src, const float min, const int count ) { +#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)]; + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::ClampMax +============ +*/ +void VPCALL idSIMD_Generic::ClampMax( float *dst, const float *src, const float max, const int count ) { +#define OPER(X) dst[(X)] = src[(X)] > max ? max : src[(X)]; + UNROLL1(OPER) +#undef OPER +} + +/* +================ +idSIMD_Generic::Memcpy +================ +*/ +void VPCALL idSIMD_Generic::Memcpy( void *dst, const void *src, const int count ) { + memcpy( dst, src, count ); +} + +/* +================ +idSIMD_Generic::Memset +================ +*/ +void VPCALL idSIMD_Generic::Memset( void *dst, const int val, const int count ) { + memset( dst, val, count ); +} + +/* +============ +idSIMD_Generic::Zero16 +============ +*/ +void VPCALL idSIMD_Generic::Zero16( float *dst, const int count ) { + memset( dst, 0, count * sizeof( float ) ); +} + +/* +============ +idSIMD_Generic::Negate16 +============ +*/ +void VPCALL idSIMD_Generic::Negate16( float *dst, const int count ) { + unsigned int *ptr = reinterpret_cast(dst); +#define OPER(X) ptr[(X)] ^= ( 1 << 31 ) // IEEE 32 bits float sign bit + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::Copy16 +============ +*/ +void VPCALL idSIMD_Generic::Copy16( float *dst, const float *src, const int count ) { +#define OPER(X) dst[(X)] = src[(X)] + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::Add16 +============ +*/ +void VPCALL idSIMD_Generic::Add16( float *dst, const float *src1, const float *src2, const int count ) { +#define OPER(X) dst[(X)] = src1[(X)] + src2[(X)] + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::Sub16 +============ +*/ +void VPCALL idSIMD_Generic::Sub16( float *dst, const float *src1, const float *src2, const int count ) { +#define OPER(X) dst[(X)] = src1[(X)] - src2[(X)] + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::Mul16 +============ +*/ +void VPCALL idSIMD_Generic::Mul16( float *dst, const float *src1, const float constant, const int count ) { +#define OPER(X) dst[(X)] = src1[(X)] * constant + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::AddAssign16 +============ +*/ +void VPCALL idSIMD_Generic::AddAssign16( float *dst, const float *src, const int count ) { +#define OPER(X) dst[(X)] += src[(X)] + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::SubAssign16 +============ +*/ +void VPCALL idSIMD_Generic::SubAssign16( float *dst, const float *src, const int count ) { +#define OPER(X) dst[(X)] -= src[(X)] + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MulAssign16 +============ +*/ +void VPCALL idSIMD_Generic::MulAssign16( float *dst, const float constant, const int count ) { +#define OPER(X) dst[(X)] *= constant + UNROLL1(OPER) +#undef OPER +} + +/* +============ +idSIMD_Generic::MatX_MultiplyVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, j, numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + break; + case 3: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + break; + case 4: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3]; + mPtr += 4; + } + break; + case 5: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + break; + case 6: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + break; + default: + int numColumns = mat.GetNumColumns(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] = sum; + mPtr += numColumns; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_MultiplyAddVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, j, numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + break; + case 3: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + break; + case 4: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3]; + mPtr += 4; + } + break; + case 5: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + break; + case 6: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + break; + default: + int numColumns = mat.GetNumColumns(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] += sum; + mPtr += numColumns; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_MultiplySubVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, j, numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + break; + case 3: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + break; + case 4: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3]; + mPtr += 4; + } + break; + case 5: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + break; + case 6: + for ( i = 0; i < numRows; i++ ) { + dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + break; + default: + int numColumns = mat.GetNumColumns(); + for ( i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] -= sum; + mPtr += numColumns; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_TransposeMultiplyVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, j, numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + break; + case 3: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + break; + case 4: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + break; + case 5: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + break; + case 6: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + break; + default: + int numRows = mat.GetNumRows(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] = sum; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_TransposeMultiplyAddVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, j, numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + break; + case 3: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + break; + case 4: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + break; + case 5: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + break; + case 6: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + break; + default: + int numRows = mat.GetNumRows(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] += sum; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_TransposeMultiplySubVecX +============ +*/ +void VPCALL idSIMD_Generic::MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { + int i, numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0]; + mPtr++; + } + break; + case 2: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + break; + case 3: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + break; + case 4: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + break; + case 5: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + break; + case 6: + for ( i = 0; i < numColumns; i++ ) { + dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + break; + default: + int numRows = mat.GetNumRows(); + for ( i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] -= sum; + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_MultiplyMatX + + optimizes the following matrix multiplications: + + NxN * Nx6 + 6xN * Nx6 + Nx6 * 6xN + 6x6 * 6xN + + with N in the range [1-6]. +============ +*/ +void VPCALL idSIMD_Generic::MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( m1.GetNumColumns() == m2.GetNumRows() ); + + dstPtr = dst.ToFloatPtr(); + m1Ptr = m1.ToFloatPtr(); + m2Ptr = m2.ToFloatPtr(); + k = m1.GetNumRows(); + l = m2.GetNumColumns(); + + switch( m1.GetNumColumns() ) { + case 1: { + if ( l == 6 ) { + for ( i = 0; i < k; i++ ) { // Nx1 * 1x6 + *dstPtr++ = m1Ptr[i] * m2Ptr[0]; + *dstPtr++ = m1Ptr[i] * m2Ptr[1]; + *dstPtr++ = m1Ptr[i] * m2Ptr[2]; + *dstPtr++ = m1Ptr[i] * m2Ptr[3]; + *dstPtr++ = m1Ptr[i] * m2Ptr[4]; + *dstPtr++ = m1Ptr[i] * m2Ptr[5]; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0]; + m2Ptr++; + } + m1Ptr++; + } + break; + } + case 2: { + if ( l == 6 ) { + for ( i = 0; i < k; i++ ) { // Nx2 * 2x6 + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6]; + *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7]; + *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8]; + *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9]; + *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10]; + *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11]; + m1Ptr += 2; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l]; + m2Ptr++; + } + m1Ptr += 2; + } + break; + } + case 3: { + if ( l == 6 ) { + for ( i = 0; i < k; i++ ) { // Nx3 * 3x6 + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12]; + *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13]; + *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14]; + *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15]; + *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16]; + *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17]; + m1Ptr += 3; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l]; + m2Ptr++; + } + m1Ptr += 3; + } + break; + } + case 4: { + if ( l == 6 ) { + for ( i = 0; i < k; i++ ) { // Nx4 * 4x6 + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12] + m1Ptr[3] * m2Ptr[18]; + *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13] + m1Ptr[3] * m2Ptr[19]; + *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14] + m1Ptr[3] * m2Ptr[20]; + *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15] + m1Ptr[3] * m2Ptr[21]; + *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16] + m1Ptr[3] * m2Ptr[22]; + *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17] + m1Ptr[3] * m2Ptr[23]; + m1Ptr += 4; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l]; + m2Ptr++; + } + m1Ptr += 4; + } + break; + } + case 5: { + if ( l == 6 ) { + for ( i = 0; i < k; i++ ) { // Nx5 * 5x6 + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12] + m1Ptr[3] * m2Ptr[18] + m1Ptr[4] * m2Ptr[24]; + *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13] + m1Ptr[3] * m2Ptr[19] + m1Ptr[4] * m2Ptr[25]; + *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14] + m1Ptr[3] * m2Ptr[20] + m1Ptr[4] * m2Ptr[26]; + *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15] + m1Ptr[3] * m2Ptr[21] + m1Ptr[4] * m2Ptr[27]; + *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16] + m1Ptr[3] * m2Ptr[22] + m1Ptr[4] * m2Ptr[28]; + *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17] + m1Ptr[3] * m2Ptr[23] + m1Ptr[4] * m2Ptr[29]; + m1Ptr += 5; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l]; + m2Ptr++; + } + m1Ptr += 5; + } + break; + } + case 6: { + switch( k ) { + case 1: { + if ( l == 1 ) { // 1x6 * 6x1 + dstPtr[0] = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[1] + m1Ptr[2] * m2Ptr[2] + + m1Ptr[3] * m2Ptr[3] + m1Ptr[4] * m2Ptr[4] + m1Ptr[5] * m2Ptr[5]; + return; + } + break; + } + case 2: { + if ( l == 2 ) { // 2x6 * 6x2 + for ( i = 0; i < 2; i++ ) { + for ( j = 0; j < 2; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 2 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 2 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 2 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 2 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 2 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 2 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + break; + } + case 3: { + if ( l == 3 ) { // 3x6 * 6x3 + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 3 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 3 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 3 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 3 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + break; + } + case 4: { + if ( l == 4 ) { // 4x6 * 6x4 + for ( i = 0; i < 4; i++ ) { + for ( j = 0; j < 4; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 4 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 4 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 4 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + } + case 5: { + if ( l == 5 ) { // 5x6 * 6x5 + for ( i = 0; i < 5; i++ ) { + for ( j = 0; j < 5; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 5 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 5 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + } + case 6: { + switch( l ) { + case 1: { // 6x6 * 6x1 + for ( i = 0; i < 6; i++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 1 ] + + m1Ptr[1] * m2Ptr[ 1 * 1 ] + + m1Ptr[2] * m2Ptr[ 2 * 1 ] + + m1Ptr[3] * m2Ptr[ 3 * 1 ] + + m1Ptr[4] * m2Ptr[ 4 * 1 ] + + m1Ptr[5] * m2Ptr[ 5 * 1 ]; + dstPtr++; + m1Ptr += 6; + } + return; + } + case 2: { // 6x6 * 6x2 + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 2; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 2 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 2 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 2 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 2 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 2 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 2 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + case 3: { // 6x6 * 6x3 + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 3; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 3 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 3 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 3 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 3 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + case 4: { // 6x6 * 6x4 + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 4; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 4 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 4 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 4 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + case 5: { // 6x6 * 6x5 + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 5; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 5 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 5 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + case 6: { // 6x6 * 6x6 + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 6; j++ ) { + *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 6 + j ] + + m1Ptr[1] * m2Ptr[ 1 * 6 + j ] + + m1Ptr[2] * m2Ptr[ 2 * 6 + j ] + + m1Ptr[3] * m2Ptr[ 3 * 6 + j ] + + m1Ptr[4] * m2Ptr[ 4 * 6 + j ] + + m1Ptr[5] * m2Ptr[ 5 * 6 + j ]; + dstPtr++; + } + m1Ptr += 6; + } + return; + } + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l] + m1Ptr[5] * m2Ptr[5*l]; + m2Ptr++; + } + m1Ptr += 6; + } + break; + } + default: { + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m2Ptr = m2.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < m1.GetNumColumns(); n++ ) { + m2Ptr += l; + sum += m1Ptr[n] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + m1Ptr += m1.GetNumColumns(); + } + break; + } + } +} + +/* +============ +idSIMD_Generic::MatX_TransposeMultiplyMatX + + optimizes the following tranpose matrix multiplications: + + Nx6 * NxN + 6xN * 6x6 + + with N in the range [1-6]. +============ +*/ +void VPCALL idSIMD_Generic::MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( m1.GetNumRows() == m2.GetNumRows() ); + + m1Ptr = m1.ToFloatPtr(); + m2Ptr = m2.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + k = m1.GetNumColumns(); + l = m2.GetNumColumns(); + + switch( m1.GetNumRows() ) { + case 1: + if ( k == 6 && l == 1 ) { // 1x6 * 1x1 + for ( i = 0; i < 6; i++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0]; + m1Ptr++; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 2: + if ( k == 6 && l == 2 ) { // 2x6 * 2x2 + for ( i = 0; i < 6; i++ ) { + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*2+0] + m1Ptr[1*6] * m2Ptr[1*2+0]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*2+1] + m1Ptr[1*6] * m2Ptr[1*2+1]; + m1Ptr++; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 3: + if ( k == 6 && l == 3 ) { // 3x6 * 3x3 + for ( i = 0; i < 6; i++ ) { + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+0] + m1Ptr[1*6] * m2Ptr[1*3+0] + m1Ptr[2*6] * m2Ptr[2*3+0]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+1] + m1Ptr[1*6] * m2Ptr[1*3+1] + m1Ptr[2*6] * m2Ptr[2*3+1]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+2] + m1Ptr[1*6] * m2Ptr[1*3+2] + m1Ptr[2*6] * m2Ptr[2*3+2]; + m1Ptr++; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 4: + if ( k == 6 && l == 4 ) { // 4x6 * 4x4 + for ( i = 0; i < 6; i++ ) { + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+0] + m1Ptr[1*6] * m2Ptr[1*4+0] + m1Ptr[2*6] * m2Ptr[2*4+0] + m1Ptr[3*6] * m2Ptr[3*4+0]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+1] + m1Ptr[1*6] * m2Ptr[1*4+1] + m1Ptr[2*6] * m2Ptr[2*4+1] + m1Ptr[3*6] * m2Ptr[3*4+1]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+2] + m1Ptr[1*6] * m2Ptr[1*4+2] + m1Ptr[2*6] * m2Ptr[2*4+2] + m1Ptr[3*6] * m2Ptr[3*4+2]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+3] + m1Ptr[1*6] * m2Ptr[1*4+3] + m1Ptr[2*6] * m2Ptr[2*4+3] + m1Ptr[3*6] * m2Ptr[3*4+3]; + m1Ptr++; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 5: + if ( k == 6 && l == 5 ) { // 5x6 * 5x5 + for ( i = 0; i < 6; i++ ) { + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+0] + m1Ptr[1*6] * m2Ptr[1*5+0] + m1Ptr[2*6] * m2Ptr[2*5+0] + m1Ptr[3*6] * m2Ptr[3*5+0] + m1Ptr[4*6] * m2Ptr[4*5+0]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+1] + m1Ptr[1*6] * m2Ptr[1*5+1] + m1Ptr[2*6] * m2Ptr[2*5+1] + m1Ptr[3*6] * m2Ptr[3*5+1] + m1Ptr[4*6] * m2Ptr[4*5+1]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+2] + m1Ptr[1*6] * m2Ptr[1*5+2] + m1Ptr[2*6] * m2Ptr[2*5+2] + m1Ptr[3*6] * m2Ptr[3*5+2] + m1Ptr[4*6] * m2Ptr[4*5+2]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+3] + m1Ptr[1*6] * m2Ptr[1*5+3] + m1Ptr[2*6] * m2Ptr[2*5+3] + m1Ptr[3*6] * m2Ptr[3*5+3] + m1Ptr[4*6] * m2Ptr[4*5+3]; + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+4] + m1Ptr[1*6] * m2Ptr[1*5+4] + m1Ptr[2*6] * m2Ptr[2*5+4] + m1Ptr[3*6] * m2Ptr[3*5+4] + m1Ptr[4*6] * m2Ptr[4*5+4]; + m1Ptr++; + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 6: + if ( l == 6 ) { + switch( k ) { + case 1: // 6x1 * 6x6 + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*1] * m2Ptr[0*6] + + m1Ptr[1*1] * m2Ptr[1*6] + + m1Ptr[2*1] * m2Ptr[2*6] + + m1Ptr[3*1] * m2Ptr[3*6] + + m1Ptr[4*1] * m2Ptr[4*6] + + m1Ptr[5*1] * m2Ptr[5*6]; + m2Ptr++; + } + return; + case 2: // 6x2 * 6x6 + for ( i = 0; i < 2; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*2] * m2Ptr[0*6] + + m1Ptr[1*2] * m2Ptr[1*6] + + m1Ptr[2*2] * m2Ptr[2*6] + + m1Ptr[3*2] * m2Ptr[3*6] + + m1Ptr[4*2] * m2Ptr[4*6] + + m1Ptr[5*2] * m2Ptr[5*6]; + m2Ptr++; + } + m1Ptr++; + } + return; + case 3: // 6x3 * 6x6 + for ( i = 0; i < 3; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*3] * m2Ptr[0*6] + + m1Ptr[1*3] * m2Ptr[1*6] + + m1Ptr[2*3] * m2Ptr[2*6] + + m1Ptr[3*3] * m2Ptr[3*6] + + m1Ptr[4*3] * m2Ptr[4*6] + + m1Ptr[5*3] * m2Ptr[5*6]; + m2Ptr++; + } + m1Ptr++; + } + return; + case 4: // 6x4 * 6x6 + for ( i = 0; i < 4; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*4] * m2Ptr[0*6] + + m1Ptr[1*4] * m2Ptr[1*6] + + m1Ptr[2*4] * m2Ptr[2*6] + + m1Ptr[3*4] * m2Ptr[3*6] + + m1Ptr[4*4] * m2Ptr[4*6] + + m1Ptr[5*4] * m2Ptr[5*6]; + m2Ptr++; + } + m1Ptr++; + } + return; + case 5: // 6x5 * 6x6 + for ( i = 0; i < 5; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*5] * m2Ptr[0*6] + + m1Ptr[1*5] * m2Ptr[1*6] + + m1Ptr[2*5] * m2Ptr[2*6] + + m1Ptr[3*5] * m2Ptr[3*6] + + m1Ptr[4*5] * m2Ptr[4*6] + + m1Ptr[5*5] * m2Ptr[5*6]; + m2Ptr++; + } + m1Ptr++; + } + return; + case 6: // 6x6 * 6x6 + for ( i = 0; i < 6; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < 6; j++ ) { + *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*6] + + m1Ptr[1*6] * m2Ptr[1*6] + + m1Ptr[2*6] * m2Ptr[2*6] + + m1Ptr[3*6] * m2Ptr[3*6] + + m1Ptr[4*6] * m2Ptr[4*6] + + m1Ptr[5*6] * m2Ptr[5*6]; + m2Ptr++; + } + m1Ptr++; + } + return; + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l] + m1Ptr[5*k] * m2Ptr[5*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + default: + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m1Ptr = m1.ToFloatPtr() + i; + m2Ptr = m2.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < m1.GetNumRows(); n++ ) { + m1Ptr += k; + m2Ptr += l; + sum += m1Ptr[0] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + } + break; + } +} + +/* +============ +idSIMD_Generic::MatX_LowerTriangularSolve + + solves x in Lx = b for the n * n sub-matrix of L + if skip > 0 the first skip elements of x are assumed to be valid already + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_Generic::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { +#if 1 + + int nc; + const float *lptr; + + if ( skip >= n ) { + return; + } + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + #define NSKIP( n, s ) ((n<<3)|(s&7)) + switch( NSKIP( n, skip ) ) { + case NSKIP( 1, 0 ): x[0] = b[0]; + return; + case NSKIP( 2, 0 ): x[0] = b[0]; + case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + return; + case NSKIP( 3, 0 ): x[0] = b[0]; + case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + return; + case NSKIP( 4, 0 ): x[0] = b[0]; + case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + return; + case NSKIP( 5, 0 ): x[0] = b[0]; + case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + return; + case NSKIP( 6, 0 ): x[0] = b[0]; + case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + return; + case NSKIP( 7, 0 ): x[0] = b[0]; + case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; + return; + } + return; + } + + // process first 4 rows + switch( skip ) { + case 0: x[0] = b[0]; + case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; + case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + skip = 4; + } + + lptr = L[skip]; + + int i, j; + register double s0, s1, s2, s3; + + for ( i = skip; i < n; i++ ) { + s0 = lptr[0] * x[0]; + s1 = lptr[1] * x[1]; + s2 = lptr[2] * x[2]; + s3 = lptr[3] * x[3]; + for ( j = 4; j < i-7; j += 8 ) { + s0 += lptr[j+0] * x[j+0]; + s1 += lptr[j+1] * x[j+1]; + s2 += lptr[j+2] * x[j+2]; + s3 += lptr[j+3] * x[j+3]; + s0 += lptr[j+4] * x[j+4]; + s1 += lptr[j+5] * x[j+5]; + s2 += lptr[j+6] * x[j+6]; + s3 += lptr[j+7] * x[j+7]; + } + switch( i - j ) { + NODEFAULT; + case 7: s0 += lptr[j+6] * x[j+6]; + case 6: s1 += lptr[j+5] * x[j+5]; + case 5: s2 += lptr[j+4] * x[j+4]; + case 4: s3 += lptr[j+3] * x[j+3]; + case 3: s0 += lptr[j+2] * x[j+2]; + case 2: s1 += lptr[j+1] * x[j+1]; + case 1: s2 += lptr[j+0] * x[j+0]; + case 0: break; + } + double sum; + sum = s3; + sum += s2; + sum += s1; + sum += s0; + sum -= b[i]; + x[i] = -sum; + lptr += nc; + } + +#else + + int i, j; + const float *lptr; + double sum; + + for ( i = skip; i < n; i++ ) { + sum = b[i]; + lptr = L[i]; + for ( j = 0; j < i; j++ ) { + sum -= lptr[j] * x[j]; + } + x[i] = sum; + } + +#endif +} + +/* +============ +idSIMD_Generic::MatX_LowerTriangularSolveTranspose + + solves x in L'x = b for the n * n sub-matrix of L + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_Generic::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { +#if 1 + + int nc; + const float *lptr; + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + switch( n ) { + case 0: + return; + case 1: + x[0] = b[0]; + return; + case 2: + x[1] = b[1]; + x[0] = b[0] - lptr[1*nc+0] * x[1]; + return; + case 3: + x[2] = b[2]; + x[1] = b[1] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 4: + x[3] = b[3]; + x[2] = b[2] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 5: + x[4] = b[4]; + x[3] = b[3] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 6: + x[5] = b[5]; + x[4] = b[4] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 7: + x[6] = b[6]; + x[5] = b[5] - lptr[6*nc+5] * x[6]; + x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + } + return; + } + + int i, j; + register double s0, s1, s2, s3; + float *xptr; + + lptr = L.ToFloatPtr() + n * nc + n - 4; + xptr = x + n; + + // process 4 rows at a time + for ( i = n; i >= 4; i -= 4 ) { + s0 = b[i-4]; + s1 = b[i-3]; + s2 = b[i-2]; + s3 = b[i-1]; + // process 4x4 blocks + for ( j = 0; j < n-i; j += 4 ) { + s0 -= lptr[(j+0)*nc+0] * xptr[j+0]; + s1 -= lptr[(j+0)*nc+1] * xptr[j+0]; + s2 -= lptr[(j+0)*nc+2] * xptr[j+0]; + s3 -= lptr[(j+0)*nc+3] * xptr[j+0]; + s0 -= lptr[(j+1)*nc+0] * xptr[j+1]; + s1 -= lptr[(j+1)*nc+1] * xptr[j+1]; + s2 -= lptr[(j+1)*nc+2] * xptr[j+1]; + s3 -= lptr[(j+1)*nc+3] * xptr[j+1]; + s0 -= lptr[(j+2)*nc+0] * xptr[j+2]; + s1 -= lptr[(j+2)*nc+1] * xptr[j+2]; + s2 -= lptr[(j+2)*nc+2] * xptr[j+2]; + s3 -= lptr[(j+2)*nc+3] * xptr[j+2]; + s0 -= lptr[(j+3)*nc+0] * xptr[j+3]; + s1 -= lptr[(j+3)*nc+1] * xptr[j+3]; + s2 -= lptr[(j+3)*nc+2] * xptr[j+3]; + s3 -= lptr[(j+3)*nc+3] * xptr[j+3]; + } + // process left over of the 4 rows + s0 -= lptr[0-1*nc] * s3; + s1 -= lptr[1-1*nc] * s3; + s2 -= lptr[2-1*nc] * s3; + s0 -= lptr[0-2*nc] * s2; + s1 -= lptr[1-2*nc] * s2; + s0 -= lptr[0-3*nc] * s1; + // store result + xptr[-4] = s0; + xptr[-3] = s1; + xptr[-2] = s2; + xptr[-1] = s3; + // update pointers for next four rows + lptr -= 4 + 4 * nc; + xptr -= 4; + } + // process left over rows + for ( i--; i >= 0; i-- ) { + s0 = b[i]; + lptr = L[0] + i; + for ( j = i + 1; j < n; j++ ) { + s0 -= lptr[j*nc] * x[j]; + } + x[i] = s0; + } + +#else + + int i, j, nc; + const float *ptr; + double sum; + + nc = L.GetNumColumns(); + for ( i = n - 1; i >= 0; i-- ) { + sum = b[i]; + ptr = L[0] + i; + for ( j = i + 1; j < n; j++ ) { + sum -= ptr[j*nc] * x[j]; + } + x[i] = sum; + } + +#endif +} + +/* +============ +idSIMD_Generic::MatX_LDLTFactor + + in-place factorization LDL' of the n * n sub-matrix of mat + the reciprocal of the diagonal elements are stored in invDiag +============ +*/ +bool VPCALL idSIMD_Generic::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { +#if 1 + + int i, j, k, nc; + float *v, *diag, *mptr; + double s0, s1, s2, s3, sum, d; + + v = (float *) _alloca16( n * sizeof( float ) ); + diag = (float *) _alloca16( n * sizeof( float ) ); + + nc = mat.GetNumColumns(); + + if ( n <= 0 ) { + return true; + } + + mptr = mat[0]; + + sum = mptr[0]; + + if ( sum == 0.0f ) { + return false; + } + + diag[0] = sum; + invDiag[0] = d = 1.0f / sum; + + if ( n <= 1 ) { + return true; + } + + mptr = mat[0]; + for ( j = 1; j < n; j++ ) { + mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; + } + + mptr = mat[1]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + sum = mptr[1] - s0; + + if ( sum == 0.0f ) { + return false; + } + + mat[1][1] = sum; + diag[1] = sum; + invDiag[1] = d = 1.0f / sum; + + if ( n <= 2 ) { + return true; + } + + mptr = mat[0]; + for ( j = 2; j < n; j++ ) { + mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; + } + + mptr = mat[2]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + sum = mptr[2] - s0 - s1; + + if ( sum == 0.0f ) { + return false; + } + + mat[2][2] = sum; + diag[2] = sum; + invDiag[2] = d = 1.0f / sum; + + if ( n <= 3 ) { + return true; + } + + mptr = mat[0]; + for ( j = 3; j < n; j++ ) { + mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; + } + + mptr = mat[3]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + sum = mptr[3] - s0 - s1 - s2; + + if ( sum == 0.0f ) { + return false; + } + + mat[3][3] = sum; + diag[3] = sum; + invDiag[3] = d = 1.0f / sum; + + if ( n <= 4 ) { + return true; + } + + mptr = mat[0]; + for ( j = 4; j < n; j++ ) { + mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; + } + + for ( i = 4; i < n; i++ ) { + + mptr = mat[i]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; + for ( k = 4; k < i-3; k += 4 ) { + v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; + v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; + v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; + } + switch( i - k ) { + NODEFAULT; + case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; + case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; + case 0: break; + } + sum = s3; + sum += s2; + sum += s1; + sum += s0; + sum = mptr[i] - sum; + + if ( sum == 0.0f ) { + return false; + } + + mat[i][i] = sum; + diag[i] = sum; + invDiag[i] = d = 1.0f / sum; + + if ( i + 1 >= n ) { + return true; + } + + mptr = mat[i+1]; + for ( j = i+1; j < n; j++ ) { + s0 = mptr[0] * v[0]; + s1 = mptr[1] * v[1]; + s2 = mptr[2] * v[2]; + s3 = mptr[3] * v[3]; + for ( k = 4; k < i-7; k += 8 ) { + s0 += mptr[k+0] * v[k+0]; + s1 += mptr[k+1] * v[k+1]; + s2 += mptr[k+2] * v[k+2]; + s3 += mptr[k+3] * v[k+3]; + s0 += mptr[k+4] * v[k+4]; + s1 += mptr[k+5] * v[k+5]; + s2 += mptr[k+6] * v[k+6]; + s3 += mptr[k+7] * v[k+7]; + } + switch( i - k ) { + NODEFAULT; + case 7: s0 += mptr[k+6] * v[k+6]; + case 6: s1 += mptr[k+5] * v[k+5]; + case 5: s2 += mptr[k+4] * v[k+4]; + case 4: s3 += mptr[k+3] * v[k+3]; + case 3: s0 += mptr[k+2] * v[k+2]; + case 2: s1 += mptr[k+1] * v[k+1]; + case 1: s2 += mptr[k+0] * v[k+0]; + case 0: break; + } + sum = s3; + sum += s2; + sum += s1; + sum += s0; + mptr[i] = ( mptr[i] - sum ) * d; + mptr += nc; + } + } + + return true; + +#else + + int i, j, k, nc; + float *v, *ptr, *diagPtr; + double d, sum; + + v = (float *) _alloca16( n * sizeof( float ) ); + nc = mat.GetNumColumns(); + + for ( i = 0; i < n; i++ ) { + + ptr = mat[i]; + diagPtr = mat[0]; + sum = ptr[i]; + for ( j = 0; j < i; j++ ) { + d = ptr[j]; + v[j] = diagPtr[0] * d; + sum -= v[j] * d; + diagPtr += nc + 1; + } + + if ( sum == 0.0f ) { + return false; + } + + diagPtr[0] = sum; + invDiag[i] = d = 1.0f / sum; + + if ( i + 1 >= n ) { + continue; + } + + ptr = mat[i+1]; + for ( j = i + 1; j < n; j++ ) { + sum = ptr[i]; + for ( k = 0; k < i; k++ ) { + sum -= ptr[k] * v[k]; + } + ptr[i] = sum * d; + ptr += nc; + } + } + + return true; + +#endif +} + +/* +============ +idSIMD_Generic::BlendJoints +============ +*/ +void VPCALL idSIMD_Generic::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { + int i; + + for ( i = 0; i < numJoints; i++ ) { + int j = index[i]; + joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp ); + joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); + } +} + +/* +============ +idSIMD_Generic::ConvertJointQuatsToJointMats +============ +*/ +void VPCALL idSIMD_Generic::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { + int i; + + for ( i = 0; i < numJoints; i++ ) { + jointMats[i].SetRotation( jointQuats[i].q.ToMat3() ); + jointMats[i].SetTranslation( jointQuats[i].t ); + } +} + +/* +============ +idSIMD_Generic::ConvertJointMatsToJointQuats +============ +*/ +void VPCALL idSIMD_Generic::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { + int i; + + for ( i = 0; i < numJoints; i++ ) { + jointQuats[i] = jointMats[i].ToJointQuat(); + } +} + +/* +============ +idSIMD_Generic::TransformJoints +============ +*/ +void VPCALL idSIMD_Generic::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { + int i; + + for( i = firstJoint; i <= lastJoint; i++ ) { + assert( parents[i] < i ); + jointMats[i] *= jointMats[parents[i]]; + } +} + +/* +============ +idSIMD_Generic::UntransformJoints +============ +*/ +void VPCALL idSIMD_Generic::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { + int i; + + for( i = lastJoint; i >= firstJoint; i-- ) { + assert( parents[i] < i ); + jointMats[i] /= jointMats[parents[i]]; + } +} + +/* +============ +idSIMD_Generic::TransformVerts +============ +*/ +void VPCALL idSIMD_Generic::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, int numWeights ) { + int i, j; + const byte *jointsPtr = (byte *)joints; + + for( j = i = 0; i < numVerts; i++ ) { + idVec3 v; + + v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + while( index[j*2+1] == 0 ) { + j++; + v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + } + j++; + + verts[i].xyz = v; + } +} + +/* +============ +idSIMD_Generic::TracePointCull +============ +*/ +void VPCALL idSIMD_Generic::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + int i; + byte tOr; + + tOr = 0; + + for ( i = 0; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, t; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + + t = d0 + radius; + bits = FLOATSIGNBITSET( t ) << 0; + t = d1 + radius; + bits |= FLOATSIGNBITSET( t ) << 1; + t = d2 + radius; + bits |= FLOATSIGNBITSET( t ) << 2; + t = d3 + radius; + bits |= FLOATSIGNBITSET( t ) << 3; + + t = d0 - radius; + bits |= FLOATSIGNBITSET( t ) << 4; + t = d1 - radius; + bits |= FLOATSIGNBITSET( t ) << 5; + t = d2 - radius; + bits |= FLOATSIGNBITSET( t ) << 6; + t = d3 - radius; + bits |= FLOATSIGNBITSET( t ) << 7; + + bits ^= 0x0F; // flip lower four bits + + tOr |= bits; + cullBits[i] = bits; + } + + totalOr = tOr; +} + +/* +============ +idSIMD_Generic::DecalPointCull +============ +*/ +void VPCALL idSIMD_Generic::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + int i; + + for ( i = 0; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, d4, d5; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0].Distance( v ); + d1 = planes[1].Distance( v ); + d2 = planes[2].Distance( v ); + d3 = planes[3].Distance( v ); + d4 = planes[4].Distance( v ); + d5 = planes[5].Distance( v ); + + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + bits |= FLOATSIGNBITSET( d2 ) << 2; + bits |= FLOATSIGNBITSET( d3 ) << 3; + bits |= FLOATSIGNBITSET( d4 ) << 4; + bits |= FLOATSIGNBITSET( d5 ) << 5; + + cullBits[i] = bits ^ 0x3F; // flip lower 6 bits + } +} + +/* +============ +idSIMD_Generic::OverlayPointCull +============ +*/ +void VPCALL idSIMD_Generic::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { + int i; + + for ( i = 0; i < numVerts; i++ ) { + byte bits; + float d0, d1; + const idVec3 &v = verts[i].xyz; + + texCoords[i][0] = d0 = planes[0].Distance( v ); + texCoords[i][1] = d1 = planes[1].Distance( v ); + + bits = FLOATSIGNBITSET( d0 ) << 0; + d0 = 1.0f - d0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + d1 = 1.0f - d1; + bits |= FLOATSIGNBITSET( d0 ) << 2; + bits |= FLOATSIGNBITSET( d1 ) << 3; + + cullBits[i] = bits; + } +} + +/* +============ +idSIMD_Generic::DeriveTriPlanes + + Derives a plane equation for each triangle. +============ +*/ +void VPCALL idSIMD_Generic::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + int i; + + for ( i = 0; i < numIndexes; i += 3 ) { + const idDrawVert *a, *b, *c; + float d0[3], d1[3], f; + idVec3 n; + + a = verts + indexes[i + 0]; + b = verts + indexes[i + 1]; + c = verts + indexes[i + 2]; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + + n[0] = d1[1] * d0[2] - d1[2] * d0[1]; + n[1] = d1[2] * d0[0] - d1[0] * d0[2]; + n[2] = d1[0] * d0[1] - d1[1] * d0[0]; + + f = idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); + + n.x *= f; + n.y *= f; + n.z *= f; + + planes->SetNormal( n ); + planes->FitThroughPoint( a->xyz ); + planes++; + } +} + +/* +============ +idSIMD_Generic::DeriveTangents + + Derives the normal and orthogonal tangent vectors for the triangle vertices. + For each vertex the normal and tangent vectors are derived from all triangles + using the vertex which results in smooth tangents across the mesh. + In the process the triangle planes are calculated as well. +============ +*/ +void VPCALL idSIMD_Generic::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + int i; + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + idPlane *planesPtr = planes; + for ( i = 0; i < numIndexes; i += 3 ) { + idDrawVert *a, *b, *c; + unsigned long signBit; + float d0[5], d1[5], f, area; + idVec3 n, t0, t1; + + int v0 = indexes[i + 0]; + int v1 = indexes[i + 1]; + int v2 = indexes[i + 2]; + + a = verts + v0; + b = verts + v1; + c = verts + v2; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + // normal + n[0] = d1[1] * d0[2] - d1[2] * d0[1]; + n[1] = d1[2] * d0[0] - d1[0] * d0[2]; + n[2] = d1[0] * d0[1] - d1[1] * d0[0]; + + f = idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); + + n.x *= f; + n.y *= f; + n.z *= f; + + planesPtr->SetNormal( n ); + planesPtr->FitThroughPoint( a->xyz ); + planesPtr++; + + // area sign bit + area = d0[3] * d1[4] - d0[4] * d1[3]; + signBit = ( *(unsigned long *)&area ) & ( 1 << 31 ); + + // first tangent + t0[0] = d0[0] * d1[4] - d0[4] * d1[0]; + t0[1] = d0[1] * d1[4] - d0[4] * d1[1]; + t0[2] = d0[2] * d1[4] - d0[4] * d1[2]; + + f = idMath::RSqrt( t0.x * t0.x + t0.y * t0.y + t0.z * t0.z ); + *(unsigned long *)&f ^= signBit; + + t0.x *= f; + t0.y *= f; + t0.z *= f; + + // second tangent + t1[0] = d0[3] * d1[0] - d0[0] * d1[3]; + t1[1] = d0[3] * d1[1] - d0[1] * d1[3]; + t1[2] = d0[3] * d1[2] - d0[2] * d1[3]; + + f = idMath::RSqrt( t1.x * t1.x + t1.y * t1.y + t1.z * t1.z ); + *(unsigned long *)&f ^= signBit; + + t1.x *= f; + t1.y *= f; + t1.z *= f; + + if ( used[v0] ) { + a->normal += n; + a->tangents[0] += t0; + a->tangents[1] += t1; + } else { + a->normal = n; + a->tangents[0] = t0; + a->tangents[1] = t1; + used[v0] = true; + } + + if ( used[v1] ) { + b->normal += n; + b->tangents[0] += t0; + b->tangents[1] += t1; + } else { + b->normal = n; + b->tangents[0] = t0; + b->tangents[1] = t1; + used[v1] = true; + } + + if ( used[v2] ) { + c->normal += n; + c->tangents[0] += t0; + c->tangents[1] += t1; + } else { + c->normal = n; + c->tangents[0] = t0; + c->tangents[1] = t1; + used[v2] = true; + } + } +} + +/* +============ +idSIMD_Generic::DeriveUnsmoothedTangents + + Derives the normal and orthogonal tangent vectors for the triangle vertices. + For each vertex the normal and tangent vectors are derived from a single dominant triangle. +============ +*/ +#define DERIVE_UNSMOOTHED_BITANGENT + +void VPCALL idSIMD_Generic::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { + int i; + + for ( i = 0; i < numVerts; i++ ) { + idDrawVert *a, *b, *c; + float d0, d1, d2, d3, d4; + float d5, d6, d7, d8, d9; + float s0, s1, s2; + float n0, n1, n2; + float t0, t1, t2; + float t3, t4, t5; + + const dominantTri_s &dt = dominantTris[i]; + + a = verts + i; + b = verts + dt.v2; + c = verts + dt.v3; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + d3 = b->st[0] - a->st[0]; + d4 = b->st[1] - a->st[1]; + + d5 = c->xyz[0] - a->xyz[0]; + d6 = c->xyz[1] - a->xyz[1]; + d7 = c->xyz[2] - a->xyz[2]; + d8 = c->st[0] - a->st[0]; + d9 = c->st[1] - a->st[1]; + + s0 = dt.normalizationScale[0]; + s1 = dt.normalizationScale[1]; + s2 = dt.normalizationScale[2]; + + n0 = s2 * ( d6 * d2 - d7 * d1 ); + n1 = s2 * ( d7 * d0 - d5 * d2 ); + n2 = s2 * ( d5 * d1 - d6 * d0 ); + + t0 = s0 * ( d0 * d9 - d4 * d5 ); + t1 = s0 * ( d1 * d9 - d4 * d6 ); + t2 = s0 * ( d2 * d9 - d4 * d7 ); + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + t3 = s1 * ( d3 * d5 - d0 * d8 ); + t4 = s1 * ( d3 * d6 - d1 * d8 ); + t5 = s1 * ( d3 * d7 - d2 * d8 ); +#else + t3 = s1 * ( n2 * t1 - n1 * t2 ); + t4 = s1 * ( n0 * t2 - n2 * t0 ); + t5 = s1 * ( n1 * t0 - n0 * t1 ); +#endif + + a->normal[0] = n0; + a->normal[1] = n1; + a->normal[2] = n2; + + a->tangents[0][0] = t0; + a->tangents[0][1] = t1; + a->tangents[0][2] = t2; + + a->tangents[1][0] = t3; + a->tangents[1][1] = t4; + a->tangents[1][2] = t5; + } +} + +/* +============ +idSIMD_Generic::NormalizeTangents + + Normalizes each vertex normal and projects and normalizes the + tangent vectors onto the plane orthogonal to the vertex normal. +============ +*/ +void VPCALL idSIMD_Generic::NormalizeTangents( idDrawVert *verts, const int numVerts ) { + + for ( int i = 0; i < numVerts; i++ ) { + idVec3 &v = verts[i].normal; + float f; + + f = idMath::RSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); + v.x *= f; v.y *= f; v.z *= f; + + for ( int j = 0; j < 2; j++ ) { + idVec3 &t = verts[i].tangents[j]; + + t -= ( t * v ) * v; + f = idMath::RSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); + t.x *= f; t.y *= f; t.z *= f; + } + } +} + +/* +============ +idSIMD_Generic::CreateTextureSpaceLightVectors + + Calculates light vectors in texture space for the given triangle vertices. + For each vertex the direction towards the light origin is projected onto texture space. + The light vectors are only calculated for the vertices referenced by the indexes. +============ +*/ +void VPCALL idSIMD_Generic::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + for ( int i = numIndexes - 1; i >= 0; i-- ) { + used[indexes[i]] = true; + } + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + + idVec3 lightDir = lightOrigin - v->xyz; + + lightVectors[i][0] = lightDir * v->tangents[0]; + lightVectors[i][1] = lightDir * v->tangents[1]; + lightVectors[i][2] = lightDir * v->normal; + } +} + +/* +============ +idSIMD_Generic::CreateSpecularTextureCoords + + Calculates specular texture coordinates for the given triangle vertices. + For each vertex the normalized direction towards the light origin is added to the + normalized direction towards the view origin and the result is projected onto texture space. + The texture coordinates are only calculated for the vertices referenced by the indexes. +============ +*/ +void VPCALL idSIMD_Generic::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + for ( int i = numIndexes - 1; i >= 0; i-- ) { + used[indexes[i]] = true; + } + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + + idVec3 lightDir = lightOrigin - v->xyz; + idVec3 viewDir = viewOrigin - v->xyz; + + float ilength; + + ilength = idMath::RSqrt( lightDir * lightDir ); + lightDir[0] *= ilength; + lightDir[1] *= ilength; + lightDir[2] *= ilength; + + ilength = idMath::RSqrt( viewDir * viewDir ); + viewDir[0] *= ilength; + viewDir[1] *= ilength; + viewDir[2] *= ilength; + + lightDir += viewDir; + + texCoords[i][0] = lightDir * v->tangents[0]; + texCoords[i][1] = lightDir * v->tangents[1]; + texCoords[i][2] = lightDir * v->normal; + texCoords[i][3] = 1.0f; + } +} + +/* +============ +idSIMD_Generic::CreateShadowCache +============ +*/ +int VPCALL idSIMD_Generic::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { + int outVerts = 0; + + for ( int i = 0; i < numVerts; i++ ) { + if ( vertRemap[i] ) { + continue; + } + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[outVerts+0][0] = v[0]; + vertexCache[outVerts+0][1] = v[1]; + vertexCache[outVerts+0][2] = v[2]; + vertexCache[outVerts+0][3] = 1.0f; + + // R_SetupProjection() builds the projection matrix with a slight crunch + // for depth, which keeps this w=0 division from rasterizing right at the + // wrap around point and causing depth fighting with the rear caps + vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; + vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; + vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; + vertexCache[outVerts+1][3] = 0.0f; + vertRemap[i] = outVerts; + outVerts += 2; + } + return outVerts; +} + +/* +============ +idSIMD_Generic::CreateVertexProgramShadowCache +============ +*/ +int VPCALL idSIMD_Generic::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { + for ( int i = 0; i < numVerts; i++ ) { + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[i*2+0][0] = v[0]; + vertexCache[i*2+1][0] = v[0]; + vertexCache[i*2+0][1] = v[1]; + vertexCache[i*2+1][1] = v[1]; + vertexCache[i*2+0][2] = v[2]; + vertexCache[i*2+1][2] = v[2]; + vertexCache[i*2+0][3] = 1.0f; + vertexCache[i*2+1][3] = 0.0f; + } + return numVerts * 2; +} + +/* +============ +idSIMD_Generic::UpSamplePCMTo44kHz + + Duplicate samples for 44kHz output. +============ +*/ +void idSIMD_Generic::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; + } + } else { + for ( int i = 0; i < numSamples; i += 2 ) { + dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; + dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; + } + } else { + for ( int i = 0; i < numSamples; i += 2 ) { + dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; + dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; + } + } + } else if ( kHz == 44100 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i] = (float) src[i]; + } + } else { + assert( 0 ); + } +} + +/* +============ +idSIMD_Generic::UpSampleOGGTo44kHz + + Duplicate samples for 44kHz output. +============ +*/ +void idSIMD_Generic::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; + } + } else { + for ( int i = 0; i < numSamples >> 1; i++ ) { + dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; + dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; + } + } else { + for ( int i = 0; i < numSamples >> 1; i++ ) { + dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; + dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; + } + } + } else if ( kHz == 44100 ) { + if ( numChannels == 1 ) { + for ( int i = 0; i < numSamples; i++ ) { + dest[i*1+0] = ogg[0][i] * 32768.0f; + } + } else { + for ( int i = 0; i < numSamples >> 1; i++ ) { + dest[i*2+0] = ogg[0][i] * 32768.0f; + dest[i*2+1] = ogg[1][i] * 32768.0f; + } + } + } else { + assert( 0 ); + } +} + +/* +============ +idSIMD_Generic::MixSoundTwoSpeakerMono +============ +*/ +void VPCALL idSIMD_Generic::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + float sL = lastV[0]; + float sR = lastV[1]; + float incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + float incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + for( int j = 0; j < MIXBUFFER_SAMPLES; j++ ) { + mixBuffer[j*2+0] += samples[j] * sL; + mixBuffer[j*2+1] += samples[j] * sR; + sL += incL; + sR += incR; + } +} + +/* +============ +idSIMD_Generic::MixSoundTwoSpeakerStereo +============ +*/ +void VPCALL idSIMD_Generic::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { + float sL = lastV[0]; + float sR = lastV[1]; + float incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + float incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + for( int j = 0; j < MIXBUFFER_SAMPLES; j++ ) { + mixBuffer[j*2+0] += samples[j*2+0] * sL; + mixBuffer[j*2+1] += samples[j*2+1] * sR; + sL += incL; + sR += incR; + } +} + +/* +============ +idSIMD_Generic::MixSoundSixSpeakerMono +============ +*/ +void VPCALL idSIMD_Generic::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + float sL0 = lastV[0]; + float sL1 = lastV[1]; + float sL2 = lastV[2]; + float sL3 = lastV[3]; + float sL4 = lastV[4]; + float sL5 = lastV[5]; + + float incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + float incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + float incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + float incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + float incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + float incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + for( int i = 0; i < MIXBUFFER_SAMPLES; i++ ) { + mixBuffer[i*6+0] += samples[i] * sL0; + mixBuffer[i*6+1] += samples[i] * sL1; + mixBuffer[i*6+2] += samples[i] * sL2; + mixBuffer[i*6+3] += samples[i] * sL3; + mixBuffer[i*6+4] += samples[i] * sL4; + mixBuffer[i*6+5] += samples[i] * sL5; + sL0 += incL0; + sL1 += incL1; + sL2 += incL2; + sL3 += incL3; + sL4 += incL4; + sL5 += incL5; + } +} + +/* +============ +idSIMD_Generic::MixSoundSixSpeakerStereo +============ +*/ +void VPCALL idSIMD_Generic::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { + float sL0 = lastV[0]; + float sL1 = lastV[1]; + float sL2 = lastV[2]; + float sL3 = lastV[3]; + float sL4 = lastV[4]; + float sL5 = lastV[5]; + + float incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + float incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + float incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + float incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + float incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + float incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + for( int i = 0; i < MIXBUFFER_SAMPLES; i++ ) { + mixBuffer[i*6+0] += samples[i*2+0] * sL0; + mixBuffer[i*6+1] += samples[i*2+1] * sL1; + mixBuffer[i*6+2] += samples[i*2+0] * sL2; + mixBuffer[i*6+3] += samples[i*2+0] * sL3; + mixBuffer[i*6+4] += samples[i*2+0] * sL4; + mixBuffer[i*6+5] += samples[i*2+1] * sL5; + sL0 += incL0; + sL1 += incL1; + sL2 += incL2; + sL3 += incL3; + sL4 += incL4; + sL5 += incL5; + } +} + +/* +============ +idSIMD_Generic::MixedSoundToSamples +============ +*/ +void VPCALL idSIMD_Generic::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { + + for ( int i = 0; i < numSamples; i++ ) { + if ( mixBuffer[i] <= -32768.0f ) { + samples[i] = -32768; + } else if ( mixBuffer[i] >= 32767.0f ) { + samples[i] = 32767; + } else { + samples[i] = (short) mixBuffer[i]; + } + } +} diff --git a/idlib/math/Simd_Generic.h b/idlib/math/Simd_Generic.h new file mode 100644 index 000000000..bc9b3c8f2 --- /dev/null +++ b/idlib/math/Simd_Generic.h @@ -0,0 +1,128 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_GENERIC_H__ +#define __MATH_SIMD_GENERIC_H__ + +/* +=============================================================================== + + Generic implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_Generic : public idSIMDProcessor { +public: + virtual const char * VPCALL GetName( void ) const; + + virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); + + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); + virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); + + virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + + virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); + virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); + + virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); + virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); + virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); + + virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); + virtual void VPCALL Memset( void *dst, const int val, const int count ); + + virtual void VPCALL Zero16( float *dst, const int count ); + virtual void VPCALL Negate16( float *dst, const int count ); + virtual void VPCALL Copy16( float *dst, const float *src, const int count ); + virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); + virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); + + virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); + virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); + virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); + virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); + virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); + + virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); + virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); + virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); + virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); + virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); + virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); + virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); + virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); + + virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); +}; + +#endif /* !__MATH_SIMD_GENERIC_H__ */ diff --git a/idlib/math/Simd_MMX.cpp b/idlib/math/Simd_MMX.cpp new file mode 100644 index 000000000..433051816 --- /dev/null +++ b/idlib/math/Simd_MMX.cpp @@ -0,0 +1,358 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_MMX.h" + + +//=============================================================== +// +// MMX implementation of idSIMDProcessor +// +//=============================================================== + +#if defined(MACOS_X) && defined(__i386__) +/* +============ +idSIMD_MMX::GetName +============ +*/ +const char * idSIMD_MMX::GetName( void ) const { + return "MMX"; +} + +#elif defined(_WIN32) + +#define EMMS_INSTRUCTION __asm emms + +/* +============ +idSIMD_MMX::GetName +============ +*/ +const char * idSIMD_MMX::GetName( void ) const { + return "MMX"; +} + +/* +================ +MMX_Memcpy8B +================ +*/ +void MMX_Memcpy8B( void *dest, const void *src, const int count ) { + _asm { + mov esi, src + mov edi, dest + mov ecx, count + shr ecx, 3 // 8 bytes per iteration + +loop1: + movq mm1, 0[ESI] // Read in source data + movntq 0[EDI], mm1 // Non-temporal stores + + add esi, 8 + add edi, 8 + dec ecx + jnz loop1 + + } + EMMS_INSTRUCTION +} + +/* +================ +MMX_Memcpy64B + + 165MB/sec +================ +*/ +void MMX_Memcpy64B( void *dest, const void *src, const int count ) { + _asm { + mov esi, src + mov edi, dest + mov ecx, count + shr ecx, 6 // 64 bytes per iteration + +loop1: + prefetchnta 64[ESI] // Prefetch next loop, non-temporal + prefetchnta 96[ESI] + + movq mm1, 0[ESI] // Read in source data + movq mm2, 8[ESI] + movq mm3, 16[ESI] + movq mm4, 24[ESI] + movq mm5, 32[ESI] + movq mm6, 40[ESI] + movq mm7, 48[ESI] + movq mm0, 56[ESI] + + movntq 0[EDI], mm1 // Non-temporal stores + movntq 8[EDI], mm2 + movntq 16[EDI], mm3 + movntq 24[EDI], mm4 + movntq 32[EDI], mm5 + movntq 40[EDI], mm6 + movntq 48[EDI], mm7 + movntq 56[EDI], mm0 + + add esi, 64 + add edi, 64 + dec ecx + jnz loop1 + } + EMMS_INSTRUCTION +} + +/* +================ +MMX_Memcpy2kB + + 240MB/sec +================ +*/ +void MMX_Memcpy2kB( void *dest, const void *src, const int count ) { + byte *tbuf = (byte *)_alloca16(2048); + __asm { + push ebx + mov esi, src + mov ebx, count + shr ebx, 11 // 2048 bytes at a time + mov edi, dest + +loop2k: + push edi // copy 2k into temporary buffer + mov edi, tbuf + mov ecx, 32 + +loopMemToL1: + prefetchnta 64[ESI] // Prefetch next loop, non-temporal + prefetchnta 96[ESI] + + movq mm1, 0[ESI] // Read in source data + movq mm2, 8[ESI] + movq mm3, 16[ESI] + movq mm4, 24[ESI] + movq mm5, 32[ESI] + movq mm6, 40[ESI] + movq mm7, 48[ESI] + movq mm0, 56[ESI] + + movq 0[EDI], mm1 // Store into L1 + movq 8[EDI], mm2 + movq 16[EDI], mm3 + movq 24[EDI], mm4 + movq 32[EDI], mm5 + movq 40[EDI], mm6 + movq 48[EDI], mm7 + movq 56[EDI], mm0 + add esi, 64 + add edi, 64 + dec ecx + jnz loopMemToL1 + + pop edi // Now copy from L1 to system memory + push esi + mov esi, tbuf + mov ecx, 32 + +loopL1ToMem: + movq mm1, 0[ESI] // Read in source data from L1 + movq mm2, 8[ESI] + movq mm3, 16[ESI] + movq mm4, 24[ESI] + movq mm5, 32[ESI] + movq mm6, 40[ESI] + movq mm7, 48[ESI] + movq mm0, 56[ESI] + + movntq 0[EDI], mm1 // Non-temporal stores + movntq 8[EDI], mm2 + movntq 16[EDI], mm3 + movntq 24[EDI], mm4 + movntq 32[EDI], mm5 + movntq 40[EDI], mm6 + movntq 48[EDI], mm7 + movntq 56[EDI], mm0 + + add esi, 64 + add edi, 64 + dec ecx + jnz loopL1ToMem + + pop esi // Do next 2k block + dec ebx + jnz loop2k + pop ebx + } + EMMS_INSTRUCTION +} + + +/* +================ +idSIMD_MMX::Memcpy + + optimized memory copy routine that handles all alignment cases and block sizes efficiently +================ +*/ +void VPCALL idSIMD_MMX::Memcpy( void *dest0, const void *src0, const int count0 ) { + // if copying more than 16 bytes and we can copy 8 byte aligned + if ( count0 > 16 && !( ( (int)dest0 ^ (int)src0 ) & 7 ) ) { + byte *dest = (byte *)dest0; + byte *src = (byte *)src0; + + // copy up to the first 8 byte aligned boundary + int count = ((int)dest) & 7; + memcpy( dest, src, count ); + dest += count; + src += count; + count = count0 - count; + + // if there are multiple blocks of 2kB + if ( count & ~4095 ) { + MMX_Memcpy2kB( dest, src, count ); + src += (count & ~2047); + dest += (count & ~2047); + count &= 2047; + } + + // if there are blocks of 64 bytes + if ( count & ~63 ) { + MMX_Memcpy64B( dest, src, count ); + src += (count & ~63); + dest += (count & ~63); + count &= 63; + } + + // if there are blocks of 8 bytes + if ( count & ~7 ) { + MMX_Memcpy8B( dest, src, count ); + src += (count & ~7); + dest += (count & ~7); + count &= 7; + } + + // copy any remaining bytes + memcpy( dest, src, count ); + } else { + // use the regular one if we cannot copy 8 byte aligned + memcpy( dest0, src0, count0 ); + } + + // the MMX_Memcpy* functions use MOVNTQ, issue a fence operation + __asm { + sfence + } +} + +/* +================ +idSIMD_MMX::Memset +================ +*/ +void VPCALL idSIMD_MMX::Memset( void* dest0, const int val, const int count0 ) { + union { + byte bytes[8]; + word words[4]; + dword dwords[2]; + } dat; + + byte *dest = (byte *)dest0; + int count = count0; + + while ( count > 0 && (((int)dest) & 7) ) { + *dest = val; + dest++; + count--; + } + if ( !count ) { + return; + } + + dat.bytes[0] = val; + dat.bytes[1] = val; + dat.words[1] = dat.words[0]; + dat.dwords[1] = dat.dwords[0]; + + if ( count >= 64 ) { + __asm { + mov edi, dest + mov ecx, count + shr ecx, 6 // 64 bytes per iteration + movq mm1, dat // Read in source data + movq mm2, mm1 + movq mm3, mm1 + movq mm4, mm1 + movq mm5, mm1 + movq mm6, mm1 + movq mm7, mm1 + movq mm0, mm1 +loop1: + movntq 0[EDI], mm1 // Non-temporal stores + movntq 8[EDI], mm2 + movntq 16[EDI], mm3 + movntq 24[EDI], mm4 + movntq 32[EDI], mm5 + movntq 40[EDI], mm6 + movntq 48[EDI], mm7 + movntq 56[EDI], mm0 + + add edi, 64 + dec ecx + jnz loop1 + } + dest += ( count & ~63 ); + count &= 63; + } + + if ( count >= 8 ) { + __asm { + mov edi, dest + mov ecx, count + shr ecx, 3 // 8 bytes per iteration + movq mm1, dat // Read in source data +loop2: + movntq 0[EDI], mm1 // Non-temporal stores + + add edi, 8 + dec ecx + jnz loop2 + } + dest += (count & ~7); + count &= 7; + } + + while ( count > 0 ) { + *dest = val; + dest++; + count--; + } + + EMMS_INSTRUCTION + + // the MMX_Memcpy* functions use MOVNTQ, issue a fence operation + __asm { + sfence + } +} + +#endif /* _WIN32 */ diff --git a/idlib/math/Simd_MMX.h b/idlib/math/Simd_MMX.h new file mode 100644 index 000000000..027053bbd --- /dev/null +++ b/idlib/math/Simd_MMX.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_MMX_H__ +#define __MATH_SIMD_MMX_H__ + +/* +=============================================================================== + + MMX implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_MMX : public idSIMD_Generic { +public: +#if defined(MACOS_X) && defined(__i386__) + virtual const char * VPCALL GetName( void ) const; + +#elif defined(_WIN32) + virtual const char * VPCALL GetName( void ) const; + + virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); + virtual void VPCALL Memset( void *dst, const int val, const int count ); + +#endif +}; + +#endif /* !__MATH_SIMD_MMX_H__ */ diff --git a/idlib/math/Simd_SSE.cpp b/idlib/math/Simd_SSE.cpp new file mode 100644 index 000000000..b143f0442 --- /dev/null +++ b/idlib/math/Simd_SSE.cpp @@ -0,0 +1,18078 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_MMX.h" +#include "Simd_SSE.h" + + +//=============================================================== +// M +// SSE implementation of idSIMDProcessor MrE +// E +//=============================================================== + + +#if defined(MACOS_X) && defined(__i386__) + +#include + +#define DRAWVERT_SIZE 60 +#define DRAWVERT_XYZ_OFFSET (0*4) +#define DRAWVERT_ST_OFFSET (3*4) +#define DRAWVERT_NORMAL_OFFSET (5*4) +#define DRAWVERT_TANGENT0_OFFSET (8*4) +#define DRAWVERT_TANGENT1_OFFSET (11*4) +#define DRAWVERT_COLOR_OFFSET (14*4) + +#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) +#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) + +/* +============ +idSIMD_SSE::GetName +============ +*/ +const char * idSIMD_SSE::GetName( void ) const { + return "MMX & SSE"; +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant.Normal() * src[i].xyz + constant[3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { + // 0, 1, 2 + // 3, 4, 5 + // 6, 7, 8 + // 9, 10, 11 + + /* + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + */ + __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; // Declare 8 xmm registers. + int count_l4 = count; // count_l4 = eax + int count_l1 = count; // count_l1 = edx + char *constant_p = (char *)&constant; // constant_p = edi + char *src_p = (char *) src; // src_p = esi + char *dst_p = (char *) dst; // dst_p = ecx + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + /* + and eax, ~3 + movss xmm4, [edi+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [edi+4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [edi+12] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + */ + count_l4 = count_l4 & ~3; + xmm4 = _mm_load_ss((float *) (constant_p)); + xmm4 = _mm_shuffle_ps(xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm5 = _mm_load_ss((float *) (constant_p + 4)); + xmm5 = _mm_shuffle_ps(xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm6 = _mm_load_ss((float *) (constant_p + 8)); + xmm6 = _mm_shuffle_ps(xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm7 = _mm_load_ss((float *) (constant_p + 12)); + xmm7 = _mm_shuffle_ps(xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 )); + + /* + jz startVert1 + */ + if(count_l4 != 0) { + /* + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + */ + count_l4 = count_l4 * DRAWVERT_SIZE; + src_p = src_p + count_l4; + count_l4 = -count_l4; + /* + loopVert4: + */ + do { + /* + movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X + movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X + movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 + movaps xmm1, xmm0 // 3, X, 0, 1 + */ + xmm0 = _mm_load_ss((float *) (src_p+count_l4+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 3, X, X, X + xmm2 = _mm_load_ss((float *) (src_p+count_l4+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8)); // 2, X, X, X + xmm0 = _mm_loadh_pi(xmm0, (__m64 *) (src_p+count_l4+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 3, X, 0, 1 + xmm1 = xmm0; // 3, X, 0, 1 + + /* + movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 + shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 + */ + xmm1 = _mm_loadl_pi(xmm1, (__m64 *) (src_p+count_l4+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4)); // 4, 5, 0, 1 + xmm2 = _mm_shuffle_ps(xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 )); // 2, X, 4, 5 + + /* + movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 + shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 + */ + xmm3 = _mm_load_ss((float *) (src_p+count_l4+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 9, X, X, X + xmm3 = _mm_loadh_pi(xmm3, (__m64 *) (src_p+count_l4+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 9, X, 6, 7 + xmm0 = _mm_shuffle_ps(xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 )); // 0, 3, 6, 9 + /* + movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 + shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 + */ + xmm3 = _mm_loadl_pi(xmm3, (__m64 *)(src_p+count_l4+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4)); // 10, 11, 6, 7 + xmm1 = _mm_shuffle_ps(xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 )); // 1, 4, 7, 10 + /* + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 + */ + xmm3 = _mm_loadh_pi(xmm3, (__m64 *)(src_p+count_l4+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8)); // 10, 11, 8, X + xmm2 = _mm_shuffle_ps(xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 )); // 2, 5, 8, 11 + + /* + add ecx, 16 + add eax, 4*DRAWVERT_SIZE + */ + dst_p = dst_p + 16; + count_l4 = count_l4 + 4*DRAWVERT_SIZE; + + /* + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + addps xmm0, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm2 + */ + xmm0 = _mm_mul_ps(xmm0, xmm4); + xmm1 = _mm_mul_ps(xmm1, xmm5); + xmm2 = _mm_mul_ps(xmm2, xmm6); + xmm0 = _mm_add_ps(xmm0, xmm7); + xmm0 = _mm_add_ps(xmm0, xmm1); + xmm0 = _mm_add_ps(xmm0, xmm2); + + /* + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loopVert4 + */ + _mm_storel_pi((__m64 *) (dst_p-16+0), xmm0); + _mm_storeh_pi((__m64 *) (dst_p-16+8), xmm0); + } while(count_l4 < 0); + } + + /* + startVert1: + and edx, 3 + jz done + */ + count_l1 = count_l1 & 3; + if(count_l1 != 0) { + /* + loopVert1: + movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] + mulss xmm0, xmm4 + mulss xmm1, xmm5 + mulss xmm2, xmm6 + addss xmm0, xmm7 + add ecx, 4 + addss xmm0, xmm1 + add eax, DRAWVERT_SIZE + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loopVert1 + */ + do { + xmm0 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+0)); + xmm1 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+4)); + xmm2 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+8)); + xmm0 = _mm_mul_ss(xmm0, xmm4); + xmm1 = _mm_mul_ss(xmm1, xmm5); + xmm2 = _mm_mul_ss(xmm2, xmm6); + xmm0 = _mm_add_ss(xmm0, xmm7); + dst_p = dst_p + 4; + xmm0 = _mm_add_ss(xmm0, xmm1); + count_l4 = count_l4 + DRAWVERT_SIZE; + xmm0 = _mm_add_ss(xmm0, xmm2); + count_l1 = count_l1 - 1; + _mm_store_ss((float *) (dst_p-4), xmm0); + } while( count_l1 != 0); + } + /* + done: + */ +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + char *indexes_p; + char *src_p; + int count_l; + int edx; + char *min_p; + char *max_p; + + /* + movss xmm0, idMath::INFINITY + xorps xmm1, xmm1 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + subps xmm1, xmm0 + movaps xmm2, xmm0 + movaps xmm3, xmm1 + */ + xmm0 = _mm_load_ss(&idMath::INFINITY); + // To satisfy the compiler use xmm0 instead. + xmm1 = _mm_xor_ps(xmm0, xmm0); + xmm0 = _mm_shuffle_ps(xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm1 = _mm_sub_ps(xmm1, xmm0); + xmm2 = xmm0; + xmm3 = xmm1; + + /* + mov edi, indexes + mov esi, src + mov eax, count + and eax, ~3 + jz done4 + */ + indexes_p = (char *) indexes; + src_p = (char *) src; + count_l = count; + count_l = count_l & ~3; + if(count_l != 0) { + /* + shl eax, 2 + add edi, eax + neg eax + */ + count_l = count_l << 2; + indexes_p = indexes_p + count_l; + count_l = -count_l; + /* + loop4: +// prefetchnta [edi+128] +// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] + */ + do { + /* + mov edx, [edi+eax+0] + imul edx, DRAWVERT_SIZE + movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + */ + edx = *((int*)(indexes_p+count_l+0)); + edx = edx * DRAWVERT_SIZE; + xmm4 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); + xmm4 = _mm_loadh_pi(xmm4, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); + xmm0 = _mm_min_ps(xmm0, xmm4); + xmm1 = _mm_max_ps(xmm1, xmm4); + + /* + mov edx, [edi+eax+4] + imul edx, DRAWVERT_SIZE + movss xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + movhps xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm5 + maxps xmm3, xmm5 + */ + edx = *((int*)(indexes_p+count_l+4)); + edx = edx * DRAWVERT_SIZE; + xmm5 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0)); + xmm5 = _mm_loadh_pi(xmm5, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+4) ); + xmm2 = _mm_min_ps(xmm2, xmm5); + xmm3 = _mm_max_ps(xmm3, xmm5); + + /* + mov edx, [edi+eax+8] + imul edx, DRAWVERT_SIZE + movss xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm6 + maxps xmm1, xmm6 + */ + edx = *((int*)(indexes_p+count_l+8)); + edx = edx * DRAWVERT_SIZE; + xmm6 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); + xmm6 = _mm_loadh_pi(xmm6, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); + xmm0 = _mm_min_ps(xmm0, xmm6); + xmm1 = _mm_max_ps(xmm1, xmm6); + + /* + mov edx, [edi+eax+12] + imul edx, DRAWVERT_SIZE + movss xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + movhps xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm7 + maxps xmm3, xmm7 + */ + edx = *((int*)(indexes_p+count_l+12)); + edx = edx * DRAWVERT_SIZE; + xmm7 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0)); + xmm7 = _mm_loadh_pi(xmm7, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+4) ); + xmm2 = _mm_min_ps(xmm2, xmm7); + xmm3 = _mm_max_ps(xmm3, xmm7); + + /* + add eax, 4*4 + jl loop4 + */ + count_l = count_l + 4*4; + } while (count_l < 0); + } + /* + done4: + mov eax, count + and eax, 3 + jz done1 + */ + count_l = count; + count_l = count_l & 3; + if(count_l != 0) { + /* + shl eax, 2 + add edi, eax + neg eax + */ + count_l = count_l << 2; + indexes_p = indexes_p + count_l; + count_l = -count_l; + /* + loop1: + */ + do{ + /* + mov edx, [edi+eax+0] + imul edx, DRAWVERT_SIZE; + movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + */ + edx = *((int*)(indexes_p+count_l+0)); + edx = edx * DRAWVERT_SIZE; + xmm4 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); + xmm4 = _mm_loadh_pi(xmm4, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); + xmm0 = _mm_min_ps(xmm0, xmm4); + xmm1 = _mm_max_ps(xmm1, xmm4); + + /* + add eax, 4 + jl loop1 + */ + count_l = count_l + 4; + } while (count_l < 0); + + } + + /* + done1: + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) + minps xmm0, xmm2 + maxps xmm1, xmm3 + mov esi, min + movhps [esi], xmm0 + movss [esi+8], xmm0 + mov edi, max + movhps [edi], xmm1 + movss [edi+8], xmm1 + */ + xmm2 = _mm_shuffle_ps(xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 )); + xmm3 = _mm_shuffle_ps(xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 )); + xmm0 = _mm_min_ps(xmm0, xmm2); + xmm1 = _mm_max_ps(xmm1, xmm3); + min_p = (char *) &min; + _mm_storeh_pi((__m64 *)(min_p), xmm0); + _mm_store_ss((float *)(min_p+8), xmm0); + max_p = (char *) &max; + _mm_storeh_pi((__m64 *)(max_p), xmm1); + _mm_store_ss((float *)(max_p+8), xmm1); +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant * src[i].Normal() + src[i][3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { + int count_l4; + int count_l1; + char *constant_p; + char *src_p; + char *dst_p; + __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + + /* + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + */ + count_l4 = count; + constant_p = (char *) &constant; + count_l1 = count_l4; + src_p = (char *) src; + dst_p = (char *) dst; + count_l4 = count_l4 & ~3; + + /* + movss xmm5, [edi+0] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [edi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + */ + xmm5 = _mm_load_ss((float *) (constant_p+0)); + xmm5 = _mm_shuffle_ps(xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm6 = _mm_load_ss((float *) (constant_p+4)); + xmm6 = _mm_shuffle_ps(xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 )); + xmm7 = _mm_load_ss((float *) (constant_p+8)); + xmm7 = _mm_shuffle_ps(xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 )); + + /* + jz startVert1 + */ + if (count != 0) { + /* + imul eax, 16 + add esi, eax + neg eax + */ + count_l4 = count_l4 * 16; + src_p = src_p + count_l4; + count_l4 = -count_l4; + /* + loopVert4: + */ + do { + /* + movlps xmm1, [esi+eax+ 0] + movlps xmm3, [esi+eax+ 8] + movhps xmm1, [esi+eax+16] + movhps xmm3, [esi+eax+24] + movlps xmm2, [esi+eax+32] + movlps xmm4, [esi+eax+40] + movhps xmm2, [esi+eax+48] + movhps xmm4, [esi+eax+56] + movaps xmm0, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) + movaps xmm2, xmm3 + shufps xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) + */ + xmm1 = _mm_loadl_pi(xmm1, (__m64 *)(src_p+count_l4+ 0)); + xmm3 = _mm_loadl_pi(xmm3, (__m64 *)(src_p+count_l4+ 8)); + xmm1 = _mm_loadh_pi(xmm1, (__m64 *)(src_p+count_l4+16)); + xmm3 = _mm_loadh_pi(xmm3, (__m64 *)(src_p+count_l4+24)); + xmm2 = _mm_loadl_pi(xmm2, (__m64 *)(src_p+count_l4+32)); + xmm4 = _mm_loadl_pi(xmm4, (__m64 *)(src_p+count_l4+40)); + xmm2 = _mm_loadh_pi(xmm2, (__m64 *)(src_p+count_l4+48)); + xmm4 = _mm_loadh_pi(xmm4, (__m64 *)(src_p+count_l4+56)); + + xmm0 = xmm1; + xmm0 = _mm_shuffle_ps(xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 )); + xmm1 = _mm_shuffle_ps(xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 )); + xmm2 = xmm3; + xmm2 = _mm_shuffle_ps(xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 )); + xmm3 = _mm_shuffle_ps(xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 )); + + /* + add ecx, 16 + add eax, 4*16 + */ + dst_p = dst_p + 16; + count_l4 = count_l4 + 4*16; + + /* + mulps xmm0, xmm5 + mulps xmm1, xmm6 + mulps xmm2, xmm7 + addps xmm0, xmm3 + addps xmm0, xmm1 + addps xmm0, xmm2 + */ + xmm0 = _mm_mul_ps(xmm0, xmm5); + xmm1 = _mm_mul_ps(xmm1, xmm6); + xmm2 = _mm_mul_ps(xmm2, xmm7); + xmm0 = _mm_add_ps(xmm0, xmm3); + xmm0 = _mm_add_ps(xmm0, xmm1); + xmm0 = _mm_add_ps(xmm0, xmm2); + + /* + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loopVert4 + */ + _mm_storel_pi((__m64 *) (dst_p-16+0), xmm0); + _mm_storeh_pi((__m64 *) (dst_p-16+8), xmm0); + } while (count_l4 < 0); + } + + /* + startVert1: + and edx, 3 + jz done + */ + count_l1 = count_l1 & 3; + + if(count_l1 != 0) { + /* + loopVert1: + */ + do { + /* + movss xmm0, [esi+eax+0] + movss xmm1, [esi+eax+4] + movss xmm2, [esi+eax+8] + mulss xmm0, xmm5 + mulss xmm1, xmm6 + mulss xmm2, xmm7 + addss xmm0, [esi+eax+12] + add ecx, 4 + addss xmm0, xmm1 + add eax, 16 + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loopVert1 + */ + xmm0 = _mm_load_ss((float *) (src_p+count_l4+ 0)); + xmm1 = _mm_load_ss((float *) (src_p+count_l4+ 4)); + xmm2 = _mm_load_ss((float *) (src_p+count_l4+ 8)); + xmm3 = _mm_load_ss((float *) (src_p+count_l4+12)); + + xmm0 = _mm_mul_ss(xmm0, xmm5); + xmm1 = _mm_mul_ss(xmm1, xmm6); + xmm2 = _mm_mul_ss(xmm2, xmm7); + + xmm0 = _mm_add_ss(xmm0, xmm3); + dst_p = dst_p + 4; + xmm0 = _mm_add_ss(xmm0, xmm1); + count_l4 = count_l4 + 16; + xmm0 = _mm_add_ss(xmm0, xmm2); + count_l1 = count_l1 - 1; + _mm_store_ss((float *) (dst_p-4), xmm0); + } while (count_l1 != 0); + } + /* + done: + */ +} + +#elif defined(_WIN32) + +#include + +#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) +#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) + +// transpose a 4x4 matrix loaded into 4 xmm registers (reg4 is temporary) +#define TRANSPOSE_4x4( reg0, reg1, reg2, reg3, reg4 ) \ + __asm movaps reg4, reg2 /* reg4 = 8, 9, 10, 11 */ \ + __asm unpcklps reg2, reg3 /* reg2 = 8, 12, 9, 13 */ \ + __asm unpckhps reg4, reg3 /* reg4 = 10, 14, 11, 15 */ \ + __asm movaps reg3, reg0 /* reg3 = 0, 1, 2, 3 */ \ + __asm unpcklps reg0, reg1 /* reg0 = 0, 4, 1, 5 */ \ + __asm unpckhps reg3, reg1 /* reg3 = 2, 6, 3, 7 */ \ + __asm movaps reg1, reg0 /* reg1 = 0, 4, 1, 5 */ \ + __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 1, 0, 1 ) /* reg0 = 0, 4, 8, 12 */ \ + __asm shufps reg1, reg2, R_SHUFFLEPS( 2, 3, 2, 3 ) /* reg1 = 1, 5, 9, 13 */ \ + __asm movaps reg2, reg3 /* reg2 = 2, 6, 3, 7 */ \ + __asm shufps reg2, reg4, R_SHUFFLEPS( 0, 1, 0, 1 ) /* reg2 = 2, 6, 10, 14 */ \ + __asm shufps reg3, reg4, R_SHUFFLEPS( 2, 3, 2, 3 ) /* reg3 = 3, 7, 11, 15 */ + +// transpose a 4x4 matrix from memory into 4 xmm registers (reg4 is temporary) +#define TRANPOSE_4x4_FROM_MEMORY( address, reg0, reg1, reg2, reg3, reg4 ) \ + __asm movlps reg1, [address+ 0] /* reg1 = 0, 1, X, X */ \ + __asm movlps reg3, [address+ 8] /* reg3 = 2, 3, X, X */ \ + __asm movhps reg1, [address+16] /* reg1 = 0, 1, 4, 5 */ \ + __asm movhps reg3, [address+24] /* reg3 = 2, 3, 6, 7 */ \ + __asm movlps reg2, [address+32] /* reg2 = 8, 9, X, X */ \ + __asm movlps reg4, [address+40] /* reg4 = 10, 11, X, X */ \ + __asm movhps reg2, [address+48] /* reg2 = 8, 9, 12, 13 */ \ + __asm movhps reg4, [address+56] /* reg4 = 10, 11, 14, 15 */ \ + __asm movaps reg0, reg1 /* reg0 = 0, 1, 4, 5 */ \ + __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 2, 0, 2 ) /* reg0 = 0, 4, 8, 12 */ \ + __asm shufps reg1, reg2, R_SHUFFLEPS( 1, 3, 1, 3 ) /* reg1 = 1, 5, 9, 13 */ \ + __asm movaps reg2, reg3 /* reg2 = 2, 3, 6, 7 */ \ + __asm shufps reg2, reg4, R_SHUFFLEPS( 0, 2, 0, 2 ) /* reg2 = 2, 6, 10, 14 */ \ + __asm shufps reg3, reg4, R_SHUFFLEPS( 1, 3, 1, 3 ) /* reg3 = 3, 7, 11, 15 */ + +// transpose a 4x4 matrix to memory from 4 xmm registers (reg4 is temporary) +#define TRANPOSE_4x4_TO_MEMORY( address, reg0, reg1, reg2, reg3, reg4 ) \ + __asm movaps reg4, reg0 /* reg4 = 0, 4, 8, 12 */ \ + __asm unpcklps reg0, reg1 /* reg0 = 0, 1, 4, 5 */ \ + __asm unpckhps reg4, reg1 /* reg4 = 8, 9, 12, 13 */ \ + __asm movaps reg1, reg2 /* reg1 = 2, 6, 10, 14 */ \ + __asm unpcklps reg2, reg3 /* reg2 = 2, 3, 6, 7 */ \ + __asm unpckhps reg1, reg3 /* reg1 = 10, 11, 14, 15 */ \ + __asm movlps [address+ 0], reg0 /* mem0 = 0, 1, X, X */ \ + __asm movlps [address+ 8], reg2 /* mem0 = 0, 1, 2, 3 */ \ + __asm movhps [address+16], reg0 /* mem1 = 4, 5, X, X */ \ + __asm movhps [address+24], reg2 /* mem1 = 4, 5, 6, 7 */ \ + __asm movlps [address+32], reg4 /* mem2 = 8, 9, X, X */ \ + __asm movlps [address+40], reg1 /* mem2 = 8, 9, 10, 11 */ \ + __asm movhps [address+48], reg4 /* mem3 = 12, 13, X, X */ \ + __asm movhps [address+56], reg1 /* mem3 = 12, 13, 14, 15 */ + +// transpose a 4x3 matrix loaded into 3 xmm registers (reg3 is temporary) +#define TRANSPOSE_4x3( reg0, reg1, reg2, reg3 ) \ + __asm movaps reg3, reg2 /* reg3 = 8, 9, 10, 11 */ \ + __asm shufps reg3, reg1, R_SHUFFLEPS( 2, 3, 0, 1 ) /* reg3 = 10, 11, 4, 5 */ \ + __asm shufps reg2, reg0, R_SHUFFLEPS( 0, 1, 2, 3 ) /* reg2 = 8, 9, 2, 3 */ \ + __asm shufps reg1, reg0, R_SHUFFLEPS( 2, 3, 0, 1 ) /* reg1 = 6, 7, 0, 1 */ \ + __asm movaps reg0, reg1 /* reg0 = 6, 7, 0, 1 */ \ + __asm shufps reg0, reg2, R_SHUFFLEPS( 2, 0, 3, 1 ) /* reg0 = 0, 6, 3, 9 */ \ + __asm shufps reg1, reg3, R_SHUFFLEPS( 3, 1, 2, 0 ) /* reg1 = 1, 7, 4, 10 */ \ + __asm shufps reg2, reg3, R_SHUFFLEPS( 2, 0, 3, 1 ) /* reg2 = 2, 8, 5, 11 */ + +// transpose a 4x3 matrix from memory into 3 xmm registers (reg3 is temporary) +#define TRANSPOSE_4x3_FROM_MEMORY( address, reg0, reg1, reg2, reg3 ) \ + __asm movlps reg1, [address+ 0] /* reg1 = 0, 1, X, X */ \ + __asm movlps reg2, [address+ 8] /* reg2 = 2, 3, X, X */ \ + __asm movlps reg3, [address+16] /* reg3 = 4, 5, X, X */ \ + __asm movhps reg1, [address+24] /* reg1 = 0, 1, 6, 7 */ \ + __asm movhps reg2, [address+32] /* reg2 = 2, 3, 8, 9 */ \ + __asm movhps reg3, [address+40] /* reg3 = 4, 5, 10, 11 */ \ + __asm movaps reg0, reg1 /* reg0 = 0, 1, 6, 7 */ \ + __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 2, 1, 3 ) /* reg0 = 0, 6, 3, 9 */ \ + __asm shufps reg1, reg3, R_SHUFFLEPS( 1, 3, 0, 2 ) /* reg1 = 1, 7, 4, 10 */ \ + __asm shufps reg2, reg3, R_SHUFFLEPS( 0, 2, 1, 3 ) /* reg2 = 2, 8, 5, 11 */ + +// transpose a 4x3 matrix to memory from 3 xmm registers (reg3 is temporary) +#define TRANSPOSE_4x3_TO_MEMORY( address, reg0, reg1, reg2, reg3 ) \ + __asm movhlps reg3, reg0 /* reg3 = 3, 9, X, X */ \ + __asm unpcklps reg0, reg1 /* reg0 = 0, 1, 6, 7 */ \ + __asm unpckhps reg1, reg2 /* reg1 = 4, 5, 10, 11 */ \ + __asm unpcklps reg2, reg3 /* reg2 = 2, 3, 8, 9 */ \ + __asm movlps [address+ 0], reg0 /* mem0 = 0, 1, X, X */ \ + __asm movlps [address+ 8], reg2 /* mem0 = 0, 1, 2, 3 */ \ + __asm movlps [address+16], reg1 /* mem1 = 4, 5, X, X */ \ + __asm movhps [address+24], reg0 /* mem1 = 4, 5, 6, 7 */ \ + __asm movhps [address+32], reg2 /* mem2 = 8, 9, X, X */ \ + __asm movhps [address+40], reg1 /* mem2 = 8, 9, 10, 11 */ + + +// with alignment +#define KFLOATINITS( SRC0, COUNT, PRE, POST ) KFLOATINITDSS( SRC0,SRC0,SRC0,COUNT,PRE,POST ) +#define KFLOATINITD( DST, COUNT, PRE, POST ) KFLOATINITDSS( DST,DST,DST,COUNT,PRE,POST ) +#define KFLOATINITDS( DST, SRC0, COUNT, PRE, POST ) KFLOATINITDSS( DST,SRC0,SRC0,COUNT,PRE,POST ) + +#define KFLOATINITDSS( DST, SRC0, SRC1, COUNT, PRE, POST )\ + __asm mov ecx,DST \ + __asm shr ecx,2 \ + __asm mov ebx,COUNT \ + __asm neg ecx \ + __asm mov edx,SRC0 \ + __asm and ecx,3 \ + __asm mov esi,SRC1 \ + __asm sub ebx,ecx \ + __asm jge noUnderFlow \ + __asm xor ebx,ebx \ + __asm mov ecx,COUNT \ + __asm noUnderFlow: \ + __asm mov PRE,ecx \ + __asm mov eax,ebx \ + __asm mov edi,DST \ + __asm and eax,8-1 \ + __asm mov POST,eax \ + __asm and ebx,0xfffffff8 \ + __asm jle done \ + __asm shl ebx,2 \ + __asm lea ecx,[ecx*4+ebx] \ + __asm neg ebx \ + __asm add edx,ecx \ + __asm add esi,ecx \ + __asm add edi,ecx \ + __asm mov eax,edx \ + __asm or eax,esi + +// without alignment (pre==0) +#define KFLOATINITS_NA( SRC0, COUNT, PRE, POST ) KFLOATINITDSS_NA( SRC0,SRC0,SRC0,COUNT,PRE,POST ) +#define KFLOATINITD_NA( DST, COUNT, PRE, POST ) KFLOATINITDSS_NA( DST,DST,DST,COUNT,PRE,POST ) +#define KFLOATINITDS_NA( DST, SRC0, COUNT, PRE, POST ) KFLOATINITDSS_NA( DST,SRC0,SRC0,COUNT,PRE,POST ) +#define KFLOATINITDSS_NA( DST, SRC0, SRC1, COUNT, PRE, POST )\ + __asm mov eax,COUNT \ + __asm mov PRE,0 \ + __asm and eax,8-1 \ + __asm mov ebx,COUNT \ + __asm mov POST,eax \ + __asm and ebx,0xfffffff8 \ + __asm je done \ + __asm shl ebx,2 \ + __asm mov edx,SRC0 \ + __asm mov esi,SRC1 \ + __asm mov edi,DST \ + __asm add edx,ebx \ + __asm add esi,ebx \ + __asm add edi,ebx \ + __asm mov eax,edx \ + __asm or eax,esi \ + __asm or eax,edi \ + __asm neg ebx \ + +/* + when OPER is called: + edx = s0 + esi = s1 + edi = d + ebx = index*4 + + xmm0 & xmm1 must not be trashed +*/ +#define KMOVDS1( DST, SRC0 ) \ + __asm movss xmm2,SRC0 \ + __asm movss DST,xmm2 +#define KMOVDS4( DST, SRC0 ) \ + __asm movups xmm2,SRC0 \ + __asm movups DST,xmm2 +#define KMINDS1( DST, SRC0 ) \ + __asm movss xmm2,SRC0 \ + __asm minss DST,xmm2 +#define KMAXDS1( DST, SRC0 ) \ + __asm movss xmm2,SRC0 \ + __asm maxss DST,xmm2 + +// general ALU operation +#define KALUDSS1( OP, DST, SRC0, SRC1 ) \ + __asm movss xmm2,SRC0 \ + __asm OP##ss xmm2,SRC1 \ + __asm movss DST,xmm2 +#define KALUDSS4( OP, DST, SRC0, SRC1 ) \ + __asm movups xmm2,SRC0 \ + __asm movups xmm3,SRC1 \ + __asm OP##ps xmm2,xmm3 \ + __asm movups DST,xmm2 + +#define KADDDSS1( DST, SRC0, SRC1 ) KALUDSS1( add, DST,SRC0,SRC1 ) +#define KADDDSS4( DST, SRC0, SRC1 ) KALUDSS4( add, DST,SRC0,SRC1 ) +#define KSUBDSS1( DST, SRC0, SRC1 ) KALUDSS1( sub, DST,SRC0,SRC1 ) +#define KSUBDSS4( DST, SRC0, SRC1 ) KALUDSS4( sub, DST,SRC0,SRC1 ) +#define KMULDSS1( DST, SRC0, SRC1 ) KALUDSS1( mul, DST,SRC0,SRC1 ) +#define KMULDSS4( DST, SRC0, SRC1 ) KALUDSS4( mul, DST,SRC0,SRC1 ) + +#define KDIVDSS1( DST, SRC0, SRC1 ) \ + __asm movss xmm2,SRC1 \ + __asm rcpss xmm3,xmm2 \ + __asm mulss xmm2,xmm3 \ + __asm mulss xmm2,xmm3 \ + __asm addss xmm3,xmm3 \ + __asm subss xmm3,xmm2 \ + __asm mulss xmm3,SRC0 \ + __asm movss DST,xmm3 +#define KDIVDSS4( DST, SRC0, SRC1 ) \ + __asm movups xmm2,SRC1 \ + __asm rcpps xmm3,xmm2 \ + __asm mulps xmm2,xmm3 \ + __asm mulps xmm2,xmm3 \ + __asm addps xmm3,xmm3 \ + __asm subps xmm3,xmm2 \ + __asm movups xmm2,SRC0 \ + __asm mulps xmm3,xmm2 \ + __asm movups DST,xmm3 +#define KF2IDS1( SRC0 ) \ + __asm movss xmm2,SRC0 \ + __asm cvttps2pi mm2,xmm2 \ + __asm movd [edi+ebx],mm2 +#define KF2IDS4( SRC0 ) \ + __asm movups xmm2,SRC0 \ + __asm cvttps2pi mm2,xmm2 \ + __asm movq [edi+ebx+0],mm2 \ + __asm shufps xmm2,xmm2,SHUFFLEPS(1,0,3,2) \ + __asm cvttps2pi mm2,xmm2 \ + __asm movq [edi+ebx+8],mm2 +#define KISQRTDS1( DST,SRC0 ) \ + __asm movss xmm2,SRC0 \ + __asm rsqrtss xmm3,xmm2 \ + __asm mulss xmm2,xmm3 \ + __asm mulss xmm2,xmm3 \ + __asm subss xmm2,xmm1 \ + __asm mulss xmm3,xmm0 \ + __asm mulss xmm3,xmm2 \ + __asm movss DST,xmm3 +#define KISQRTDS4( DST,SRC0 ) \ + __asm movups xmm2,SRC0 \ + __asm rsqrtps xmm3,xmm2 \ + __asm mulps xmm2,xmm3 \ + __asm mulps xmm2,xmm3 \ + __asm subps xmm2,xmm1 \ + __asm mulps xmm3,xmm0 \ + __asm mulps xmm3,xmm2 \ + __asm movups DST,xmm3 + +// this is used in vector4 implementation to shift constant V4 +#define KANDREGDSV( DST, SRC0, VALUE ) \ + __asm mov DST,SRC0 \ + __asm and DST,VALUE + +// this is used in vector4 code to operate with float arrays as sources +#define KEXPANDFLOAT( DST, SRC ) \ + __asm movss DST,SRC \ + __asm shufps DST,DST,0 + +#define KADDDS1( DST,SRC ) KADDDSS1( DST,DST,SRC ) +#define KADDDS4( DST,SRC ) KADDDSS4( DST,DST,SRC ) +#define KSUBDS1( DST,SRC ) KSUBDSS1( DST,DST,SRC ) +#define KSUBDS4( DST,SRC ) KSUBDSS4( DST,DST,SRC ) +#define KMULDS1( DST,SRC ) KMULDSS1( DST,DST,SRC ) +#define KMULDS4( DST,SRC ) KMULDSS4( DST,DST,SRC ) +#define KDIVDS1( DST,SRC ) KDIVDSS1( DST,DST,SRC ) +#define KDIVDS4( DST,SRC ) KDIVDSS4( DST,DST,SRC ) + +// handles pre & post leftovers +#define KFLOATOPER( OPER, OPER4, COUNT ) \ + __asm mov ecx,pre \ + __asm mov ebx,COUNT \ + __asm cmp ebx,ecx \ + __asm cmovl ecx,COUNT \ + __asm test ecx,ecx \ + __asm je preDone \ + __asm xor ebx,ebx \ + __asm lpPre: \ + OPER \ + __asm add ebx,4 \ + __asm dec ecx \ + __asm jg lpPre \ + __asm preDone: \ + __asm mov ecx,post \ + __asm mov ebx,COUNT \ + __asm sub ebx,ecx \ + __asm shl ebx,2 \ + __asm cmp ecx,4 \ + __asm jl post4Done \ + OPER4 \ + __asm sub ecx,4 \ + __asm add ebx,4*4 \ + __asm post4Done: \ + __asm test ecx,ecx \ + __asm je postDone \ + __asm lpPost: \ + OPER \ + __asm add ebx,4 \ + __asm dec ecx \ + __asm jg lpPost \ + __asm postDone: + +// operate on a constant and a float array +#define KFLOAT_CA( ALUOP, DST, SRC, CONSTANT, COUNT ) \ + int pre,post; \ + __asm movss xmm0,CONSTANT \ + __asm shufps xmm0,xmm0,0 \ + KFLOATINITDS( DST, SRC, COUNT, pre, post ) \ + __asm and eax,15 \ + __asm jne lpNA \ + __asm jmp lpA \ + __asm align 16 \ + __asm lpA: \ + __asm prefetchnta [edx+ebx+64] \ + __asm movaps xmm1,xmm0 \ + __asm movaps xmm2,xmm0 \ + __asm ALUOP##ps xmm1,[edx+ebx] \ + __asm ALUOP##ps xmm2,[edx+ebx+16] \ + __asm movaps [edi+ebx],xmm1 \ + __asm movaps [edi+ebx+16],xmm2 \ + __asm add ebx,16*2 \ + __asm jl lpA \ + __asm jmp done \ + __asm align 16 \ + __asm lpNA: \ + __asm prefetchnta [edx+ebx+64] \ + __asm movaps xmm1,xmm0 \ + __asm movaps xmm2,xmm0 \ + __asm movups xmm3,[edx+ebx] \ + __asm movups xmm4,[edx+ebx+16] \ + __asm ALUOP##ps xmm1,xmm3 \ + __asm ALUOP##ps xmm2,xmm4 \ + __asm movaps [edi+ebx],xmm1 \ + __asm movaps [edi+ebx+16],xmm2 \ + __asm add ebx,16*2 \ + __asm jl lpNA \ + __asm done: \ + __asm mov edx,SRC \ + __asm mov edi,DST \ + __asm KFLOATOPER( KALUDSS1( ALUOP, [edi+ebx],xmm0,[edx+ebx] ), \ + __asm KALUDSS4( ALUOP, [edi+ebx],xmm0,[edx+ebx] ), COUNT ) + +// operate on two float arrays +#define KFLOAT_AA( ALUOP, DST, SRC0, SRC1, COUNT ) \ + int pre,post; \ + KFLOATINITDSS( DST, SRC0, SRC1, COUNT, pre, post ) \ + __asm and eax,15 \ + __asm jne lpNA \ + __asm jmp lpA \ + __asm align 16 \ + __asm lpA: \ + __asm movaps xmm1,[edx+ebx] \ + __asm movaps xmm2,[edx+ebx+16] \ + __asm ALUOP##ps xmm1,[esi+ebx] \ + __asm ALUOP##ps xmm2,[esi+ebx+16] \ + __asm prefetchnta [edx+ebx+64] \ + __asm prefetchnta [esi+ebx+64] \ + __asm movaps [edi+ebx],xmm1 \ + __asm movaps [edi+ebx+16],xmm2 \ + __asm add ebx,16*2 \ + __asm jl lpA \ + __asm jmp done \ + __asm align 16 \ + __asm lpNA: \ + __asm movups xmm1,[edx+ebx] \ + __asm movups xmm2,[edx+ebx+16] \ + __asm movups xmm3,[esi+ebx] \ + __asm movups xmm4,[esi+ebx+16] \ + __asm prefetchnta [edx+ebx+64] \ + __asm prefetchnta [esi+ebx+64] \ + __asm ALUOP##ps xmm1,xmm3 \ + __asm ALUOP##ps xmm2,xmm4 \ + __asm movaps [edi+ebx],xmm1 \ + __asm movaps [edi+ebx+16],xmm2 \ + __asm add ebx,16*2 \ + __asm jl lpNA \ + __asm done: \ + __asm mov edx,SRC0 \ + __asm mov esi,SRC1 \ + __asm mov edi,DST \ + KFLOATOPER( KALUDSS1( ALUOP, [edi+ebx],[edx+ebx],[esi+ebx] ), \ + KALUDSS4( ALUOP, [edi+ebx],[edx+ebx],[esi+ebx] ), COUNT ) + + +#define DRAWVERT_SIZE 60 +#define DRAWVERT_XYZ_OFFSET (0*4) +#define DRAWVERT_ST_OFFSET (3*4) +#define DRAWVERT_NORMAL_OFFSET (5*4) +#define DRAWVERT_TANGENT0_OFFSET (8*4) +#define DRAWVERT_TANGENT1_OFFSET (11*4) +#define DRAWVERT_COLOR_OFFSET (14*4) + +#define JOINTQUAT_SIZE (7*4) +#define JOINTMAT_SIZE (4*3*4) +#define JOINTWEIGHT_SIZE (4*4) + + +#define ALIGN4_INIT1( X, INIT ) ALIGN16( static X[4] ) = { INIT, INIT, INIT, INIT } +#define ALIGN4_INIT4( X, I0, I1, I2, I3 ) ALIGN16( static X[4] ) = { I0, I1, I2, I3 } +#define ALIGN8_INIT1( X, INIT ) ALIGN16( static X[8] ) = { INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT } + +ALIGN8_INIT1( unsigned short SIMD_W_zero, 0 ); +ALIGN8_INIT1( unsigned short SIMD_W_maxShort, 1<<15 ); + +ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle0, (3<<0)|(2<<8)|(1<<16)|(0<<24) ); +ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle1, (0<<0)|(1<<8)|(2<<16)|(3<<24) ); +ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle2, (1<<0)|(0<<8)|(3<<16)|(2<<24) ); +ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle3, (2<<0)|(3<<8)|(0<<16)|(1<<24) ); + +ALIGN4_INIT4( unsigned long SIMD_SP_singleSignBitMask, (unsigned long) ( 1 << 31 ), 0, 0, 0 ); +ALIGN4_INIT1( unsigned long SIMD_SP_signBitMask, (unsigned long) ( 1 << 31 ) ); +ALIGN4_INIT1( unsigned long SIMD_SP_absMask, (unsigned long) ~( 1 << 31 ) ); +ALIGN4_INIT1( unsigned long SIMD_SP_infinityMask, (unsigned long) ~( 1 << 23 ) ); +ALIGN4_INIT1( unsigned long SIMD_SP_not, 0xFFFFFFFF ); + +ALIGN4_INIT1( float SIMD_SP_zero, 0.0f ); +ALIGN4_INIT1( float SIMD_SP_half, 0.5f ); +ALIGN4_INIT1( float SIMD_SP_one, 1.0f ); +ALIGN4_INIT1( float SIMD_SP_two, 2.0f ); +ALIGN4_INIT1( float SIMD_SP_three, 3.0f ); +ALIGN4_INIT1( float SIMD_SP_four, 4.0f ); +ALIGN4_INIT1( float SIMD_SP_maxShort, (1<<15) ); +ALIGN4_INIT1( float SIMD_SP_tiny, 1e-10f ); +ALIGN4_INIT1( float SIMD_SP_PI, idMath::PI ); +ALIGN4_INIT1( float SIMD_SP_halfPI, idMath::HALF_PI ); +ALIGN4_INIT1( float SIMD_SP_twoPI, idMath::TWO_PI ); +ALIGN4_INIT1( float SIMD_SP_oneOverTwoPI, 1.0f / idMath::TWO_PI ); +ALIGN4_INIT1( float SIMD_SP_infinity, idMath::INFINITY ); +ALIGN4_INIT4( float SIMD_SP_lastOne, 0.0f, 0.0f, 0.0f, 1.0f ); + +ALIGN4_INIT1( float SIMD_SP_rsqrt_c0, 3.0f ); +ALIGN4_INIT1( float SIMD_SP_rsqrt_c1, -0.5f ); +ALIGN4_INIT1( float SIMD_SP_mat2quat_rsqrt_c1, -0.5f*0.5f ); + +ALIGN4_INIT1( float SIMD_SP_sin_c0, -2.39e-08f ); +ALIGN4_INIT1( float SIMD_SP_sin_c1, 2.7526e-06f ); +ALIGN4_INIT1( float SIMD_SP_sin_c2, -1.98409e-04f ); +ALIGN4_INIT1( float SIMD_SP_sin_c3, 8.3333315e-03f ); +ALIGN4_INIT1( float SIMD_SP_sin_c4, -1.666666664e-01f ); + +ALIGN4_INIT1( float SIMD_SP_cos_c0, -2.605e-07f ); +ALIGN4_INIT1( float SIMD_SP_cos_c1, 2.47609e-05f ); +ALIGN4_INIT1( float SIMD_SP_cos_c2, -1.3888397e-03f ); +ALIGN4_INIT1( float SIMD_SP_cos_c3, 4.16666418e-02f ); +ALIGN4_INIT1( float SIMD_SP_cos_c4, -4.999999963e-01f ); + +ALIGN4_INIT1( float SIMD_SP_atan_c0, 0.0028662257f ); +ALIGN4_INIT1( float SIMD_SP_atan_c1, -0.0161657367f ); +ALIGN4_INIT1( float SIMD_SP_atan_c2, 0.0429096138f ); +ALIGN4_INIT1( float SIMD_SP_atan_c3, -0.0752896400f ); +ALIGN4_INIT1( float SIMD_SP_atan_c4, 0.1065626393f ); +ALIGN4_INIT1( float SIMD_SP_atan_c5, -0.1420889944f ); +ALIGN4_INIT1( float SIMD_SP_atan_c6, 0.1999355085f ); +ALIGN4_INIT1( float SIMD_SP_atan_c7, -0.3333314528f ); + +/* +============ +SSE_InvSqrt +============ +*/ +float SSE_InvSqrt( float x ) { + float y; + + __asm { + movss xmm0, x + rsqrtss xmm1, xmm0 + mulss xmm0, xmm1 + mulss xmm0, xmm1 + subss xmm0, SIMD_SP_rsqrt_c0 + mulss xmm1, SIMD_SP_rsqrt_c1 + mulss xmm0, xmm1 + movss y, xmm0 + } + return y; +} + +/* +============ +SSE_InvSqrt4 +============ +*/ +void SSE_InvSqrt4( float x[4] ) { + __asm { + mov edi, x + movaps xmm0, [edi] + rsqrtps xmm1, xmm0 + mulps xmm0, xmm1 + mulps xmm0, xmm1 + subps xmm0, SIMD_SP_rsqrt_c0 + mulps xmm1, SIMD_SP_rsqrt_c1 + mulps xmm0, xmm1 + movaps [edi], xmm0 + } +} + +/* +============ +SSE_SinZeroHalfPI + + The angle must be between zero and half PI. +============ +*/ +float SSE_SinZeroHalfPI( float a ) { +#if 1 + + float t; + + assert( a >= 0.0f && a <= idMath::HALF_PI ); + + __asm { + movss xmm0, a + movss xmm1, xmm0 + mulss xmm1, xmm1 + movss xmm2, SIMD_SP_sin_c0 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c1 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c2 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c3 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c4 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_one + mulss xmm2, xmm0 + movss t, xmm2 + } + + return t; + +#else + + float s, t; + + assert( a >= 0.0f && a <= idMath::HALF_PI ); + + s = a * a; + t = -2.39e-08f; + t *= s; + t += 2.7526e-06f; + t *= s; + t += -1.98409e-04f; + t *= s; + t += 8.3333315e-03f; + t *= s; + t += -1.666666664e-01f; + t *= s; + t += 1.0f; + t *= a; + + return t; + +#endif +} + +/* +============ +SSE_Sin4ZeroHalfPI + + The angle must be between zero and half PI. +============ +*/ +void SSE_Sin4ZeroHalfPI( float a[4], float s[4] ) { + __asm { + mov edi, a + mov esi, s + movaps xmm0, [edi] + movaps xmm1, xmm0 + mulps xmm1, xmm1 + movaps xmm2, SIMD_SP_sin_c0 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c1 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c2 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c3 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c4 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_one + mulps xmm2, xmm0 + movaps [esi], xmm2 + } +} + +/* +============ +SSE_Sin +============ +*/ +float SSE_Sin( float a ) { +#if 1 + + float t; + + __asm { + movss xmm1, a + movss xmm2, xmm1 + movss xmm3, xmm1 + mulss xmm2, SIMD_SP_oneOverTwoPI + cvttss2si ecx, xmm2 + cmpltss xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + cvtsi2ss xmm2, ecx + subss xmm2, xmm3 + mulss xmm2, SIMD_SP_twoPI + subss xmm1, xmm2 + + movss xmm0, SIMD_SP_PI // xmm0 = PI + subss xmm0, xmm1 // xmm0 = PI - a + movss xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movss xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movss xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + movss xmm1, xmm0 + mulss xmm1, xmm1 + movss xmm2, SIMD_SP_sin_c0 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c1 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c2 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c3 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_sin_c4 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_one + mulss xmm2, xmm0 + movss t, xmm2 + } + + return t; + +#else + + float s, t; + + if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { + a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; + } + + a = idMath::PI - a; + if ( fabs( a ) >= idMath::HALF_PI ) { + a = ( ( a < 0.0f ) ? -idMath::PI : idMath::PI ) - a; + } + + s = a * a; + t = -2.39e-08f; + t *= s; + t += 2.7526e-06f; + t *= s; + t += -1.98409e-04f; + t *= s; + t += 8.3333315e-03f; + t *= s; + t += -1.666666664e-01f; + t *= s; + t += 1.0f; + t *= a; + + return t; + +#endif +} + +/* +============ +SSE_Sin4 +============ +*/ +void SSE_Sin4( float a[4], float s[4] ) { + __asm { + mov edi, a + mov esi, s + movaps xmm1, [edi] + movaps xmm2, xmm1 + mulps xmm2, SIMD_SP_oneOverTwoPI + movhlps xmm3, xmm2 + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) + movaps xmm3, xmm1 + cmpltps xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + subps xmm2, xmm3 + mulps xmm2, SIMD_SP_twoPI + subps xmm1, xmm2 + + movaps xmm0, SIMD_SP_PI // xmm0 = PI + subps xmm0, xmm1 // xmm0 = PI - a + movaps xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movaps xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movaps xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + movaps xmm1, xmm0 + mulps xmm1, xmm1 + movaps xmm2, SIMD_SP_sin_c0 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c1 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c2 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c3 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_sin_c4 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_one + mulps xmm2, xmm0 + movaps [esi], xmm2 + } +} + +/* +============ +SSE_CosZeroHalfPI + + The angle must be between zero and half PI. +============ +*/ +float SSE_CosZeroHalfPI( float a ) { +#if 1 + + float t; + + assert( a >= 0.0f && a <= idMath::HALF_PI ); + + __asm { + movss xmm0, a + mulss xmm0, xmm0 + movss xmm1, SIMD_SP_cos_c0 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c1 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c2 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c3 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c4 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_one + movss t, xmm1 + } + + return t; + +#else + + float s, t; + + assert( a >= 0.0f && a <= idMath::HALF_PI ); + + s = a * a; + t = -2.605e-07f; + t *= s; + t += 2.47609e-05f; + t *= s; + t += -1.3888397e-03f; + t *= s; + t += 4.16666418e-02f; + t *= s; + t += -4.999999963e-01f; + t *= s; + t += 1.0f; + + return t; + +#endif +} + +/* +============ +SSE_Cos4ZeroHalfPI + + The angle must be between zero and half PI. +============ +*/ +void SSE_Cos4ZeroHalfPI( float a[4], float c[4] ) { + __asm { + mov edi, a + mov esi, c + movaps xmm0, [edi] + mulps xmm0, xmm0 + movaps xmm1, SIMD_SP_cos_c0 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c1 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c2 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c3 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c4 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_one + movaps [esi], xmm2 + } +} + +/* +============ +SSE_Cos +============ +*/ +float SSE_Cos( float a ) { +#if 1 + + float t; + + __asm { + movss xmm1, a + movss xmm2, xmm1 + movss xmm3, xmm1 + mulss xmm2, SIMD_SP_oneOverTwoPI + cvttss2si ecx, xmm2 + cmpltss xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + cvtsi2ss xmm2, ecx + subss xmm2, xmm3 + mulss xmm2, SIMD_SP_twoPI + subss xmm1, xmm2 + + movss xmm0, SIMD_SP_PI // xmm0 = PI + subss xmm0, xmm1 // xmm0 = PI - a + movss xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movss xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movss xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + mulss xmm0, xmm0 + movss xmm1, SIMD_SP_cos_c0 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c1 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c2 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c3 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_cos_c4 + mulss xmm1, xmm0 + addss xmm1, SIMD_SP_one + xorps xmm2, SIMD_SP_signBitMask + xorps xmm1, xmm2 + movss t, xmm1 + } + + return t; + +#else + + float s, t; + + if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { + a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; + } + + a = idMath::PI - a; + if ( fabs( a ) >= idMath::HALF_PI ) { + a = ( ( a < 0.0f ) ? -idMath::PI : idMath::PI ) - a; + d = 1.0f; + } else { + d = -1.0f; + } + + s = a * a; + t = -2.605e-07f; + t *= s; + t += 2.47609e-05f; + t *= s; + t += -1.3888397e-03f; + t *= s; + t += 4.16666418e-02f; + t *= s; + t += -4.999999963e-01f; + t *= s; + t += 1.0f; + t *= d; + + return t; + +#endif +} + +/* +============ +SSE_Cos4 +============ +*/ +void SSE_Cos4( float a[4], float c[4] ) { + __asm { + mov edi, a + mov esi, c + movaps xmm1, [edi] + movaps xmm2, xmm1 + mulps xmm2, SIMD_SP_oneOverTwoPI + movhlps xmm3, xmm2 + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) + movaps xmm3, xmm1 + cmpltps xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + subps xmm2, xmm3 + mulps xmm2, SIMD_SP_twoPI + subps xmm1, xmm2 + + movaps xmm0, SIMD_SP_PI // xmm0 = PI + subps xmm0, xmm1 // xmm0 = PI - a + movaps xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movaps xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movaps xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + mulps xmm0, xmm0 + movaps xmm1, SIMD_SP_cos_c0 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c1 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c2 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c3 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_cos_c4 + mulps xmm1, xmm0 + addps xmm1, SIMD_SP_one + xorps xmm2, SIMD_SP_signBitMask + xorps xmm1, xmm2 + movaps [esi], xmm1 + } +} + +/* +============ +SSE_SinCos +============ +*/ +void SSE_SinCos( float a, float &s, float &c ) { + __asm { + mov edi, s + mov esi, c + movss xmm1, a + movss xmm2, xmm1 + movss xmm3, xmm1 + mulss xmm2, SIMD_SP_oneOverTwoPI + cvttss2si ecx, xmm2 + cmpltss xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + cvtsi2ss xmm2, ecx + subss xmm2, xmm3 + mulss xmm2, SIMD_SP_twoPI + subss xmm1, xmm2 + + movss xmm0, SIMD_SP_PI // xmm0 = PI + subss xmm0, xmm1 // xmm0 = PI - a + movss xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movss xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movss xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + movss xmm1, xmm0 + mulss xmm1, xmm1 + movss xmm3, SIMD_SP_sin_c0 + movss xmm4, SIMD_SP_cos_c0 + mulss xmm3, xmm1 + mulss xmm4, xmm1 + addss xmm3, SIMD_SP_sin_c1 + addss xmm4, SIMD_SP_cos_c1 + mulss xmm3, xmm1 + mulss xmm4, xmm1 + addss xmm3, SIMD_SP_sin_c2 + addss xmm4, SIMD_SP_cos_c2 + mulss xmm3, xmm1 + mulss xmm4, xmm1 + addss xmm3, SIMD_SP_sin_c3 + addss xmm4, SIMD_SP_cos_c3 + mulss xmm3, xmm1 + mulss xmm4, xmm1 + addss xmm3, SIMD_SP_sin_c4 + addss xmm4, SIMD_SP_cos_c4 + mulss xmm3, xmm1 + mulss xmm4, xmm1 + addss xmm3, SIMD_SP_one + addss xmm4, SIMD_SP_one + mulss xmm3, xmm0 + xorps xmm2, SIMD_SP_signBitMask + xorps xmm4, xmm2 + movss [edi], xmm2 + movss [esi], xmm3 + } +} + +/* +============ +SSE_SinCos4 +============ +*/ +void SSE_SinCos4( float a[4], float s[4], float c[4] ) { + __asm { + mov eax, a + mov edi, s + mov esi, c + movaps xmm1, [eax] + movaps xmm2, xmm1 + mulps xmm2, SIMD_SP_oneOverTwoPI + movhlps xmm3, xmm2 + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) + cvttss2si ecx, xmm2 + cvtsi2ss xmm2, ecx + cvttss2si edx, xmm3 + cvtsi2ss xmm3, edx + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) + movaps xmm3, xmm1 + cmpltps xmm3, SIMD_SP_zero + andps xmm3, SIMD_SP_one + subps xmm2, xmm3 + mulps xmm2, SIMD_SP_twoPI + subps xmm1, xmm2 + + movaps xmm0, SIMD_SP_PI // xmm0 = PI + subps xmm0, xmm1 // xmm0 = PI - a + movaps xmm1, xmm0 // xmm1 = PI - a + andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) + movaps xmm2, xmm0 // xmm2 = PI - a + xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) + cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 + movaps xmm3, SIMD_SP_PI // xmm3 = PI + xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) + andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f + andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f + xorps xmm0, xmm2 + addps xmm0, xmm3 + + movaps xmm0, [eax] + movaps xmm1, xmm0 + mulps xmm1, xmm1 + movaps xmm3, SIMD_SP_sin_c0 + movaps xmm4, SIMD_SP_cos_c0 + mulps xmm3, xmm1 + mulps xmm4, xmm1 + addps xmm3, SIMD_SP_sin_c1 + addps xmm4, SIMD_SP_cos_c1 + mulps xmm3, xmm1 + mulps xmm4, xmm1 + addps xmm3, SIMD_SP_sin_c2 + addps xmm4, SIMD_SP_cos_c2 + mulps xmm3, xmm1 + mulps xmm4, xmm1 + addps xmm3, SIMD_SP_sin_c3 + addps xmm4, SIMD_SP_cos_c3 + mulps xmm3, xmm1 + mulps xmm4, xmm1 + addps xmm3, SIMD_SP_sin_c4 + addps xmm4, SIMD_SP_cos_c4 + mulps xmm3, xmm1 + mulps xmm4, xmm1 + addps xmm3, SIMD_SP_one + addps xmm4, SIMD_SP_one + mulps xmm3, xmm0 + xorps xmm2, SIMD_SP_signBitMask + xorps xmm4, xmm2 + movaps [edi], xmm3 + movaps [esi], xmm4 + } +} + +/* +============ +SSE_ATanPositive + + Both 'x' and 'y' must be positive. +============ +*/ +float SSE_ATanPositive( float y, float x ) { +#if 1 + + float t; + + assert( y >= 0.0f && x >= 0.0f ); + + __asm { + movss xmm0, x + movss xmm3, xmm0 + movss xmm1, y + minss xmm0, xmm1 + maxss xmm1, xmm3 + cmpeqss xmm3, xmm0 + rcpss xmm2, xmm1 + mulss xmm1, xmm2 + mulss xmm1, xmm2 + addss xmm2, xmm2 + subss xmm2, xmm1 // xmm2 = 1 / y or 1 / x + mulss xmm0, xmm2 // xmm0 = x / y or y / x + movss xmm1, xmm3 + andps xmm1, SIMD_SP_signBitMask + xorps xmm0, xmm1 // xmm0 = -x / y or y / x + andps xmm3, SIMD_SP_halfPI // xmm3 = HALF_PI or 0.0f + movss xmm1, xmm0 + mulss xmm1, xmm1 // xmm1 = s + movss xmm2, SIMD_SP_atan_c0 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c1 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c2 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c3 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c4 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c5 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c6 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c7 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_one + mulss xmm2, xmm0 + addss xmm2, xmm3 + movss t, xmm2 + } + + return t; + +#else + + float a, d, s, t; + + assert( y >= 0.0f && x >= 0.0f ); + + if ( y > x ) { + a = -x / y; + d = idMath::HALF_PI; + } else { + a = y / x; + d = 0.0f; + } + s = a * a; + t = 0.0028662257f; + t *= s; + t += -0.0161657367f; + t *= s; + t += 0.0429096138f; + t *= s; + t += -0.0752896400f; + t *= s; + t += 0.1065626393f; + t *= s; + t += -0.1420889944f; + t *= s; + t += 0.1999355085f; + t *= s; + t += -0.3333314528f; + t *= s; + t += 1.0f; + t *= a; + t += d; + + return t; + +#endif +} + +/* +============ +SSE_ATan4Positive + + Both 'x' and 'y' must be positive. +============ +*/ +void SSE_ATan4Positive( float y[4], float x[4], float at[4] ) { + __asm { + mov esi, x + mov edi, y + mov edx, at + movaps xmm0, [esi] + movaps xmm3, xmm0 + movaps xmm1, [edi] + minps xmm0, xmm1 + maxps xmm1, xmm3 + cmpeqps xmm3, xmm0 + rcpps xmm2, xmm1 + mulps xmm1, xmm2 + mulps xmm1, xmm2 + addps xmm2, xmm2 + subps xmm2, xmm1 // xmm2 = 1 / y or 1 / x + mulps xmm0, xmm2 // xmm0 = x / y or y / x + movaps xmm1, xmm3 + andps xmm1, SIMD_SP_signBitMask + xorps xmm0, xmm1 // xmm0 = -x / y or y / x + andps xmm3, SIMD_SP_halfPI // xmm3 = HALF_PI or 0.0f + movaps xmm1, xmm0 + mulps xmm1, xmm1 // xmm1 = s + movaps xmm2, SIMD_SP_atan_c0 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c1 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c2 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c3 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c4 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c5 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c6 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c7 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_one + mulps xmm2, xmm0 + addps xmm2, xmm3 + movaps [edx], xmm2 + } +} + +/* +============ +SSE_ATan +============ +*/ +float SSE_ATan( float y, float x ) { +#if 1 + + float t; + + __asm { + movss xmm0, x + movss xmm3, xmm0 + movss xmm4, xmm0 + andps xmm0, SIMD_SP_absMask + movss xmm1, y + xorps xmm4, xmm1 + andps xmm1, SIMD_SP_absMask + andps xmm4, SIMD_SP_signBitMask + minss xmm0, xmm1 + maxss xmm1, xmm3 + cmpeqss xmm3, xmm0 + rcpss xmm2, xmm1 + mulss xmm1, xmm2 + mulss xmm1, xmm2 + addss xmm2, xmm2 + subss xmm2, xmm1 // xmm2 = 1 / y or 1 / x + mulss xmm0, xmm2 // xmm0 = x / y or y / x + xorps xmm0, xmm4 + movss xmm1, xmm3 + andps xmm1, SIMD_SP_signBitMask + xorps xmm0, xmm1 // xmm0 = -x / y or y / x + orps xmm4, SIMD_SP_halfPI // xmm4 = +/- HALF_PI + andps xmm3, xmm4 // xmm3 = +/- HALF_PI or 0.0f + movss xmm1, xmm0 + mulss xmm1, xmm1 // xmm1 = s + movss xmm2, SIMD_SP_atan_c0 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c1 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c2 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c3 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c4 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c5 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c6 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_atan_c7 + mulss xmm2, xmm1 + addss xmm2, SIMD_SP_one + mulss xmm2, xmm0 + addss xmm2, xmm3 + movss t, xmm2 + } + + return t; + +#else + + float a, d, s, t; + + if ( fabs( y ) > fabs( x ) ) { + a = -x / y; + d = idMath::HALF_PI; + *((unsigned long *)&d) ^= ( *((unsigned long *)&x) ^ *((unsigned long *)&y) ) & (1<<31); + } else { + a = y / x; + d = 0.0f; + } + + s = a * a; + t = 0.0028662257f; + t *= s; + t += -0.0161657367f; + t *= s; + t += 0.0429096138f; + t *= s; + t += -0.0752896400f; + t *= s; + t += 0.1065626393f; + t *= s; + t += -0.1420889944f; + t *= s; + t += 0.1999355085f; + t *= s; + t += -0.3333314528f; + t *= s; + t += 1.0f; + t *= a; + t += d; + + return t; + +#endif +} + +/* +============ +SSE_ATan4 +============ +*/ +void SSE_ATan4( float y[4], float x[4], float at[4] ) { + __asm { + mov esi, x + mov edi, y + mov edx, at + movaps xmm0, [esi] + movaps xmm3, xmm0 + movaps xmm4, xmm0 + andps xmm0, SIMD_SP_absMask + movaps xmm1, [edi] + xorps xmm4, xmm1 + andps xmm1, SIMD_SP_absMask + andps xmm4, SIMD_SP_signBitMask + minps xmm0, xmm1 + maxps xmm1, xmm3 + cmpeqps xmm3, xmm0 + rcpps xmm2, xmm1 + mulps xmm1, xmm2 + mulps xmm1, xmm2 + addps xmm2, xmm2 + subps xmm2, xmm1 // xmm2 = 1 / y or 1 / x + mulps xmm0, xmm2 // xmm0 = x / y or y / x + xorps xmm0, xmm4 + movaps xmm1, xmm3 + andps xmm1, SIMD_SP_signBitMask + xorps xmm0, xmm1 // xmm0 = -x / y or y / x + orps xmm4, SIMD_SP_halfPI // xmm4 = +/- HALF_PI + andps xmm3, xmm4 // xmm3 = +/- HALF_PI or 0.0f + movaps xmm1, xmm0 + mulps xmm1, xmm1 // xmm1 = s + movaps xmm2, SIMD_SP_atan_c0 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c1 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c2 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c3 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c4 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c5 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c6 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_atan_c7 + mulps xmm2, xmm1 + addps xmm2, SIMD_SP_one + mulps xmm2, xmm0 + addps xmm2, xmm3 + movaps [edx], xmm2 + } +} + +/* +============ +SSE_TestTrigonometry +============ +*/ +void SSE_TestTrigonometry( void ) { + int i; + float a, s1, s2, c1, c2; + + for ( i = 0; i < 100; i++ ) { + a = i * idMath::HALF_PI / 100.0f; + + s1 = sin( a ); + s2 = SSE_SinZeroHalfPI( a ); + + if ( fabs( s1 - s2 ) > 1e-7f ) { + assert( 0 ); + } + + c1 = cos( a ); + c2 = SSE_CosZeroHalfPI( a ); + + if ( fabs( c1 - c2 ) > 1e-7f ) { + assert( 0 ); + } + } + + for ( i = -200; i < 200; i++ ) { + a = i * idMath::TWO_PI / 100.0f; + + s1 = sin( a ); + s2 = SSE_Sin( a ); + + if ( fabs( s1 - s2 ) > 1e-6f ) { + assert( 0 ); + } + + c1 = cos( a ); + c2 = SSE_Cos( a ); + + if ( fabs( c1 - c2 ) > 1e-6f ) { + assert( 0 ); + } + + SSE_SinCos( a, s2, c2 ); + if ( fabs( s1 - s2 ) > 1e-6f || fabs( c1 - c2 ) > 1e-6f ) { + assert( 0 ); + } + } +} + +/* +============ +idSIMD_SSE::GetName +============ +*/ +const char * idSIMD_SSE::GetName( void ) const { + return "MMX & SSE"; +} + +/* +============ +idSIMD_SSE::Add + + dst[i] = constant + src[i]; +============ +*/ +void VPCALL idSIMD_SSE::Add( float *dst, const float constant, const float *src, const int count ) { + KFLOAT_CA( add, dst, src, constant, count ) +} + +/* +============ +idSIMD_SSE::Add + + dst[i] = src0[i] + src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::Add( float *dst, const float *src0, const float *src1, const int count ) { + KFLOAT_AA( add, dst, src0, src1, count ) +} + +/* +============ +idSIMD_SSE::Sub + + dst[i] = constant - src[i]; +============ +*/ +void VPCALL idSIMD_SSE::Sub( float *dst, const float constant, const float *src, const int count ) { + KFLOAT_CA( sub, dst, src, constant, count ) +} + +/* +============ +idSIMD_SSE::Sub + + dst[i] = src0[i] - src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::Sub( float *dst, const float *src0, const float *src1, const int count ) { + KFLOAT_AA( sub, dst, src0, src1, count ) +} + +/* +============ +idSIMD_SSE::Mul + + dst[i] = constant * src[i]; +============ +*/ +void VPCALL idSIMD_SSE::Mul( float *dst, const float constant, const float *src, const int count ) { + KFLOAT_CA( mul, dst, src, constant, count ) +} + +/* +============ +idSIMD_SSE::Mul + + dst[i] = src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::Mul( float *dst, const float *src0, const float *src1, const int count ) { + KFLOAT_AA( mul, dst, src0, src1, count ) +} + +/* +============ +idSIMD_SSE::Div + + dst[i] = constant / src[i]; +============ +*/ +void VPCALL idSIMD_SSE::Div( float *dst, const float constant, const float *src, const int count ) { + int pre, post; + + // 1 / x = 2 * rcpps(x) - (x * rcpps(x) * rcpps(x)); + __asm + { + movss xmm1,constant + shufps xmm1,xmm1,0 + + KFLOATINITDS( dst, src, count, pre, post ) + and eax,15 + jne lpNA + jmp lpA + align 16 +lpA: + movaps xmm2,[edx+ebx] + movaps xmm3,[edx+ebx+16] + rcpps xmm4,xmm2 + rcpps xmm5,xmm3 + prefetchnta [edx+ebx+64] + mulps xmm2,xmm4 + mulps xmm2,xmm4 + mulps xmm3,xmm5 + mulps xmm3,xmm5 + addps xmm4,xmm4 + addps xmm5,xmm5 + subps xmm4,xmm2 + subps xmm5,xmm3 + mulps xmm4,xmm1 + mulps xmm5,xmm1 + movaps [edi+ebx],xmm4 + movaps [edi+ebx+16],xmm5 + add ebx,16*2 + jl lpA + jmp done + align 16 +lpNA: + movups xmm2,[edx+ebx] + movups xmm3,[edx+ebx+16] + rcpps xmm4,xmm2 + rcpps xmm5,xmm3 + prefetchnta [edx+ebx+64] + mulps xmm2,xmm4 + mulps xmm2,xmm4 + mulps xmm3,xmm5 + mulps xmm3,xmm5 + addps xmm4,xmm4 + addps xmm5,xmm5 + subps xmm4,xmm2 + subps xmm5,xmm3 + mulps xmm4,xmm1 + mulps xmm5,xmm1 + movaps [edi+ebx],xmm4 + movaps [edi+ebx+16],xmm5 + add ebx,16*2 + jl lpNA +done: + mov edx,src + mov edi,dst + KFLOATOPER( KDIVDSS1( [edi+ebx],xmm1,[edx+ebx] ), + KDIVDSS4( [edi+ebx],xmm1,[edx+ebx] ), count ) + } +} + +/* +============ +idSIMD_SSE::Div + + dst[i] = src0[i] / src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::Div( float *dst, const float *src0, const float *src1, const int count ) { + int pre,post; + + // 1 / x = 2 * rcpps(x) - (x * rcpps(x) * rcpps(x)); + __asm + { + KFLOATINITDSS( dst, src0, src1, count, pre, post ) + and eax,15 + jne lpNA + jmp lpA + align 16 +lpA: + movaps xmm2,[esi+ebx] + movaps xmm3,[esi+ebx+16] + rcpps xmm4,xmm2 + rcpps xmm5,xmm3 + prefetchnta [esi+ebx+64] + mulps xmm2,xmm4 + mulps xmm2,xmm4 + mulps xmm3,xmm5 + mulps xmm3,xmm5 + addps xmm4,xmm4 + addps xmm5,xmm5 + subps xmm4,xmm2 + subps xmm5,xmm3 + mulps xmm4,[edx+ebx] + mulps xmm5,[edx+ebx+16] + movaps [edi+ebx],xmm4 + movaps [edi+ebx+16],xmm5 + add ebx,16*2 + jl lpA + jmp done + align 16 +lpNA: + movups xmm2,[esi+ebx] + movups xmm3,[esi+ebx+16] + rcpps xmm4,xmm2 + rcpps xmm5,xmm3 + prefetchnta [esi+ebx+64] + mulps xmm2,xmm4 + mulps xmm2,xmm4 + mulps xmm3,xmm5 + mulps xmm3,xmm5 + addps xmm4,xmm4 + addps xmm5,xmm5 + subps xmm4,xmm2 + subps xmm5,xmm3 + movups xmm2,[edx+ebx] + movups xmm3,[edx+ebx+16] + mulps xmm4,xmm2 + mulps xmm5,xmm3 + movaps [edi+ebx],xmm4 + movaps [edi+ebx+16],xmm5 + add ebx,16*2 + jl lpNA +done: + mov edx,src0 + mov esi,src1 + mov edi,dst + KFLOATOPER( KDIVDSS1( [edi+ebx],[edx+ebx],[esi+ebx] ), + KDIVDSS4( [edi+ebx],[edx+ebx],[esi+ebx] ), count ) + } +} +/* +============ +Simd_MulAdd + + assumes count >= 7 +============ +*/ +static void Simd_MulAdd( float *dst, const float constant, const float *src, const int count ) { + __asm mov esi, dst + __asm mov edi, src + __asm mov eax, count + __asm shl eax, 2 + __asm mov ecx, esi + __asm mov edx, eax + __asm or ecx, edi + __asm fld constant + __asm and ecx, 15 + __asm jz SimdMulAdd16 + __asm and ecx, 3 + __asm jnz SimdMulAdd8 + __asm mov ecx, esi + __asm xor ecx, edi + __asm and ecx, 15 + __asm jnz MulAdd8 + __asm mov ecx, esi + __asm and ecx, 15 + __asm neg ecx + __asm add ecx, 16 + __asm sub eax, ecx + __asm add edi, ecx + __asm add esi, ecx + __asm neg ecx + __asm mov edx, eax + __asm loopPreMulAdd16: + __asm fld st + __asm fmul dword ptr [edi+ecx] + __asm fadd dword ptr [esi+ecx] + __asm fstp dword ptr [esi+ecx] + __asm add ecx, 4 + __asm jl loopPreMulAdd16 + __asm SimdMulAdd16: + __asm and eax, ~15 + __asm movss xmm1, constant + __asm shufps xmm1, xmm1, 0x00 + __asm add esi, eax + __asm add edi, eax + __asm neg eax + __asm align 16 + __asm loopMulAdd16: + __asm movaps xmm0, [edi+eax] + __asm mulps xmm0, xmm1 + __asm addps xmm0, [esi+eax] + __asm movaps [esi+eax], xmm0 + __asm add eax, 16 + __asm jl loopMulAdd16 + __asm jmp postMulAdd + __asm MulAdd8: + __asm mov ecx, esi + __asm and ecx, 7 + __asm jz SimdMulAdd8 + __asm sub eax, ecx + __asm add esi, ecx + __asm add edi, ecx + __asm neg ecx + __asm mov edx, eax + __asm loopPreMulAdd8: + __asm fld st + __asm fmul dword ptr [edi+ecx] + __asm fadd dword ptr [esi+ecx] + __asm fstp dword ptr [esi+ecx] + __asm add ecx, 4 + __asm jl loopPreMulAdd8 + __asm SimdMulAdd8: + __asm and eax, ~15 + __asm movss xmm1, constant + __asm shufps xmm1, xmm1, 0x00 + __asm add esi, eax + __asm add edi, eax + __asm neg eax + __asm align 16 + __asm loopMulAdd8: + __asm movlps xmm0, [edi+eax] + __asm movhps xmm0, [edi+eax+8] + __asm mulps xmm0, xmm1 + __asm movlps xmm2, [esi+eax] + __asm movhps xmm2, [esi+eax+8] + __asm addps xmm0, xmm2 + __asm movlps [esi+eax], xmm0 + __asm movhps [esi+eax+8], xmm0 + __asm add eax, 16 + __asm jl loopMulAdd8 + __asm jmp postMulAdd + __asm postMulAdd: + __asm and edx, 15 + __asm jz MulAddDone + __asm add esi, edx + __asm add edi, edx + __asm neg edx + __asm loopPostMulAdd: + __asm fld st + __asm fmul dword ptr [edi+edx] + __asm fadd dword ptr [esi+edx] + __asm fstp dword ptr [esi+edx] + __asm add edx, 4 + __asm jl loopPostMulAdd + __asm MulAddDone: + __asm fstp st +} + +#define MULADD_FEW( OPER ) \ +switch( count ) { \ + case 0: \ + return; \ + case 1: \ + dst[0] OPER c * src[0]; \ + return; \ + case 2: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; \ + return; \ + case 3: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; \ + return; \ + case 4: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + return; \ + case 5: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; \ + return; \ + case 6: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; \ + return; \ + case 7: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; \ + return; \ + case 8: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ + return; \ + case 9: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ + dst[8] OPER c * src[8]; \ + return; \ + case 10: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ + dst[8] OPER c * src[8]; dst[9] OPER c * src[9]; \ + return; \ + case 11: \ + dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ + dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ + dst[8] OPER c * src[8]; dst[9] OPER c * src[9]; dst[10] OPER c * src[10]; \ + return; \ +} + +/* +============ +idSIMD_SSE::MulAdd + + dst[i] += constant * src[i]; +============ +*/ +void VPCALL idSIMD_SSE::MulAdd( float *dst, const float constant, const float *src, const int count ) { + float c = constant; + MULADD_FEW( += ) + Simd_MulAdd( dst, constant, src, count ); +} + +/* +============ +idSIMD_SSE::MulAdd + + dst[i] += src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::MulAdd( float *dst, const float *src0, const float *src1, const int count ) { + for ( int i = 0; i < count; i++ ) { + dst[i] += src0[i] + src1[i]; + } +} + +/* +============ +idSIMD_SSE::MulSub + + dst[i] -= constant * src[i]; +============ +*/ +void VPCALL idSIMD_SSE::MulSub( float *dst, const float constant, const float *src, const int count ) { + float c = constant; + MULADD_FEW( -= ) + Simd_MulAdd( dst, -constant, src, count ); +} + +/* +============ +idSIMD_SSE::MulSub + + dst[i] -= src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::MulSub( float *dst, const float *src0, const float *src1, const int count ) { + for ( int i = 0; i < count; i++ ) { + dst[i] -= src0[i] + src1[i]; + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant * src[i]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) { + __asm + { + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + + movss xmm4, [edi+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [edi+4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + + jz done4 + imul eax, 12 + add esi, eax + neg eax + + loop4: + movlps xmm1, [esi+eax+ 0] + movlps xmm2, [esi+eax+ 8] + movlps xmm3, [esi+eax+16] + movhps xmm1, [esi+eax+24] + movhps xmm2, [esi+eax+32] + movhps xmm3, [esi+eax+40] + movaps xmm0, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) + shufps xmm1, xmm3, R_SHUFFLEPS( 1, 3, 0, 2 ) + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) + add ecx, 16 + add eax, 4*12 + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + addps xmm0, xmm1 + addps xmm0, xmm2 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 1, 3 ) + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loop4 + + done4: + and edx, 3 + jz done1 + + loop1: + movss xmm0, [esi+eax+0] + movss xmm1, [esi+eax+4] + movss xmm2, [esi+eax+8] + mulss xmm0, xmm4 + mulss xmm1, xmm5 + mulss xmm2, xmm6 + add ecx, 4 + addss xmm0, xmm1 + add eax, 12 + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loop1 + + done1: + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant * src[i].Normal() + src[i][3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { + __asm { + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + + movss xmm5, [edi+0] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [edi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + jz startVert1 + imul eax, 16 + add esi, eax + neg eax + + loopVert4: + + movlps xmm1, [esi+eax+ 0] + movlps xmm3, [esi+eax+ 8] + movhps xmm1, [esi+eax+16] + movhps xmm3, [esi+eax+24] + movlps xmm2, [esi+eax+32] + movlps xmm4, [esi+eax+40] + movhps xmm2, [esi+eax+48] + movhps xmm4, [esi+eax+56] + movaps xmm0, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) + movaps xmm2, xmm3 + shufps xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) + + add ecx, 16 + add eax, 4*16 + + mulps xmm0, xmm5 + mulps xmm1, xmm6 + mulps xmm2, xmm7 + addps xmm0, xmm3 + addps xmm0, xmm1 + addps xmm0, xmm2 + + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loopVert4 + + startVert1: + and edx, 3 + jz done + + loopVert1: + movss xmm0, [esi+eax+0] + movss xmm1, [esi+eax+4] + movss xmm2, [esi+eax+8] + mulss xmm0, xmm5 + mulss xmm1, xmm6 + mulss xmm2, xmm7 + addss xmm0, [esi+eax+12] + add ecx, 4 + addss xmm0, xmm1 + add eax, 16 + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loopVert1 + + done: + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant * src[i].xyz; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + // 0, 1, 2 + // 3, 4, 5 + // 6, 7, 8 + // 9, 10, 11 + + __asm { + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + + movss xmm4, [edi+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [edi+4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + + jz startVert1 + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loopVert4: + movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X + movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X + movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 + movaps xmm1, xmm0 // 3, X, 0, 1 + + movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 + shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 + + movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 + shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 + + movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 + shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 + + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 + + add ecx, 16 + add eax, 4*DRAWVERT_SIZE + + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + addps xmm0, xmm1 + addps xmm0, xmm2 + + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loopVert4 + + startVert1: + and edx, 3 + jz done + + loopVert1: + movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] + mulss xmm0, xmm4 + mulss xmm1, xmm5 + mulss xmm2, xmm6 + add ecx, 4 + addss xmm0, xmm1 + add eax, DRAWVERT_SIZE + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loopVert1 + + done: + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant.Normal() * src[i] + constant[3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idVec3 *src, const int count ) { + __asm + { + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + + movss xmm4, [edi+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [edi+4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [edi+12] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + jz done4 + imul eax, 12 + add esi, eax + neg eax + + loop4: + movlps xmm1, [esi+eax+ 0] + movlps xmm2, [esi+eax+ 8] + movlps xmm3, [esi+eax+16] + movhps xmm1, [esi+eax+24] + movhps xmm2, [esi+eax+32] + movhps xmm3, [esi+eax+40] + movaps xmm0, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) + shufps xmm1, xmm3, R_SHUFFLEPS( 1, 3, 0, 2 ) + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) + + add ecx, 16 + add eax, 4*12 + + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + addps xmm0, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm2 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 1, 3 ) + + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loop4 + + done4: + and edx, 3 + jz done1 + + loop1: + movss xmm0, [esi+eax+0] + movss xmm1, [esi+eax+4] + movss xmm2, [esi+eax+8] + mulss xmm0, xmm4 + mulss xmm1, xmm5 + mulss xmm2, xmm6 + addss xmm0, xmm7 + add ecx, 4 + addss xmm0, xmm1 + add eax, 12 + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loop1 + + done1: + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idPlane *src, const int count ) { + +#define SINGLE_OP(SRC, DEST) \ + __asm movlps xmm0,[SRC] \ + __asm movlps xmm1,[SRC+8] \ + __asm mulps xmm0,xmm4 \ + __asm mulps xmm1,xmm5 \ + __asm addps xmm0,xmm1 \ + __asm movaps xmm1,xmm0 \ + __asm shufps xmm1,xmm1,SHUFFLEPS(1,1,1,1) \ + __asm addss xmm0,xmm1 \ + __asm movss [DEST],xmm0 \ + __asm add SRC,16 \ + __asm add DEST,4 + +#define DUAL_OP(SRC, DEST) \ + __asm movlps xmm0,[SRC] \ + __asm movlps xmm1,[SRC+8] \ + __asm movhps xmm0,[SRC+16] \ + __asm movhps xmm1,[SRC+24] \ + __asm mulps xmm0,xmm4 \ + __asm mulps xmm1,xmm5 \ + __asm addps xmm0,xmm1 \ + __asm shufps xmm1,xmm0,SHUFFLEPS(2,0,1,0) \ + __asm shufps xmm0,xmm0,SHUFFLEPS(3,1,2,0) \ + __asm addps xmm0,xmm1 \ + __asm movhps [DEST],xmm0 \ + __asm add SRC,32 \ + __asm add DEST,8 + + __asm { + mov edx, dst + mov eax, src + mov ebx, constant + mov ecx, count + + movlps xmm4, [ebx] + shufps xmm4, xmm4, SHUFFLEPS(1,0,1,0) + movlps xmm5, [ebx+8] + shufps xmm5, xmm5, SHUFFLEPS(1,0,1,0) + + xorps xmm0, xmm0 + xorps xmm1, xmm1 + + _lpAlignDest: + test edx, 0x0f + jz _destAligned + SINGLE_OP(eax,edx) + dec ecx + jnz _lpAlignDest + jmp _vpExit + + _destAligned: + push ecx + + cmp ecx, 4 + jl _post + + and ecx, ~3 + shl ecx, 2 + lea eax, [eax+ecx*4] + add edx, ecx + neg ecx + + movlps xmm0, [eax+ecx*4] + movhps xmm0, [eax+ecx*4+16] + movlps xmm2, [eax+ecx*4+32] + movhps xmm2, [eax+ecx*4+48] + jmp _lpStart + + align 16 + _lp: + prefetchnta [eax+ecx*4+128] + addps xmm1, xmm0 + movlps xmm0, [eax+ecx*4] + movhps xmm0, [eax+ecx*4+16] + movlps xmm2, [eax+ecx*4+32] + movhps xmm2, [eax+ecx*4+48] + movaps [edx+ecx-16],xmm1 + _lpStart: + movlps xmm1, [eax+ecx*4+8] + movhps xmm1, [eax+ecx*4+24] + movlps xmm3, [eax+ecx*4+40] + movhps xmm3, [eax+ecx*4+56] + add ecx, 16 + mulps xmm1, xmm5 + mulps xmm2, xmm4 + mulps xmm3, xmm5 + addps xmm2, xmm3 // y3+w3 x3+z3 y2+w2 x2+z2 + mulps xmm0, xmm4 + addps xmm0, xmm1 // y1+w1 x1+z1 y0+w0 x0+z0 + movaps xmm1, xmm0 + shufps xmm0, xmm2, SHUFFLEPS(2,0,2,0) // x3+z3 x2+z2 x1+z1 x0+z0 + shufps xmm1, xmm2, SHUFFLEPS(3,1,3,1) // y3+w3 y2+w2 y1+w1 y0+w0 + js _lp + addps xmm1, xmm0 + movaps [edx+ecx-16], xmm1 + _post: + pop ecx + and ecx, 0x3 + cmp ecx, 2 + jl _post1 + DUAL_OP(eax,edx) + sub ecx, 2 + _post1: + cmp ecx, 1 + jne _vpExit + SINGLE_OP(eax,edx) + _vpExit: + } + +#undef DUAL_OP +#undef SINGLE_OP + +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = constant.Normal() * src[i].xyz + constant[3]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + // 0, 1, 2 + // 3, 4, 5 + // 6, 7, 8 + // 9, 10, 11 + + __asm { + mov eax, count + mov edi, constant + mov edx, eax + mov esi, src + mov ecx, dst + and eax, ~3 + + movss xmm4, [edi+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [edi+4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [edi+8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [edi+12] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + jz startVert1 + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loopVert4: + movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X + movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X + movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 + movaps xmm1, xmm0 // 3, X, 0, 1 + + movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 + shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 + + movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 + shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 + + movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 + shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 + + movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 + + add ecx, 16 + add eax, 4*DRAWVERT_SIZE + + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + addps xmm0, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm2 + + movlps [ecx-16+0], xmm0 + movhps [ecx-16+8], xmm0 + jl loopVert4 + + startVert1: + and edx, 3 + jz done + + loopVert1: + movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] + mulss xmm0, xmm4 + mulss xmm1, xmm5 + mulss xmm2, xmm6 + addss xmm0, xmm7 + add ecx, 4 + addss xmm0, xmm1 + add eax, DRAWVERT_SIZE + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loopVert1 + + done: + } +} + +/* +============ +idSIMD_SSE::Dot + + dst[i] = src0[i] * src1[i]; +============ +*/ +void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) { + __asm + { + mov eax, count + mov edi, src0 + mov edx, eax + mov esi, src1 + mov ecx, dst + and eax, ~3 + + jz done4 + imul eax, 12 + add edi, eax + add esi, eax + neg eax + + loop4: + movlps xmm0, [esi+eax] // 0, 1, X, X + movlps xmm3, [edi+eax] // 0, 1, X, X + movlps xmm1, [esi+eax+8] // 2, 3, X, X + movlps xmm4, [edi+eax+8] // 2, 3, X, X + movhps xmm0, [esi+eax+24] // 0, 1, 6, 7 + movhps xmm3, [edi+eax+24] // 0, 1, 6, 7 + movhps xmm1, [esi+eax+32] // 2, 3, 8, 9 + movhps xmm4, [edi+eax+32] // 2, 3, 8, 9 + movlps xmm2, [esi+eax+16] // 4, 5, X, X + movlps xmm5, [edi+eax+16] // 4, 5, X, X + movhps xmm2, [esi+eax+40] // 4, 5, 10, 11 + movhps xmm5, [edi+eax+40] // 4, 5, 10, 11 + + add ecx, 16 + add eax, 48 + + mulps xmm0, xmm3 + mulps xmm1, xmm4 + mulps xmm2, xmm5 + movaps xmm7, xmm0 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) // 0, 6, 3, 9 + shufps xmm0, xmm2, R_SHUFFLEPS( 1, 3, 0, 2 ) // 1, 7, 4, 10 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) // 2, 8, 5, 11 + addps xmm7, xmm0 + addps xmm7, xmm1 + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 2, 1, 3 ) + + movlps [ecx-16+0], xmm7 + movhps [ecx-16+8], xmm7 + jl loop4 + + done4: + and edx, 3 + jz done1 + + loop1: + movss xmm0, [esi+eax+0] + movss xmm3, [edi+eax+0] + movss xmm1, [esi+eax+4] + movss xmm4, [edi+eax+4] + movss xmm2, [esi+eax+8] + movss xmm5, [edi+eax+8] + mulss xmm0, xmm3 + mulss xmm1, xmm4 + mulss xmm2, xmm5 + add ecx, 4 + addss xmm0, xmm1 + add eax, 12 + addss xmm0, xmm2 + dec edx + movss [ecx-4], xmm0 + jnz loop1 + + done1: + } +} + +/* +============ +idSIMD_SSE::Dot + + dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2] + ... +============ +*/ +void VPCALL idSIMD_SSE::Dot( float &dot, const float *src1, const float *src2, const int count ) { + switch( count ) { + case 0: + dot = 0.0f; + return; + case 1: + dot = src1[0] * src2[0]; + return; + case 2: + dot = src1[0] * src2[0] + src1[1] * src2[1]; + return; + case 3: + dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2]; + return; + default: + __asm { + mov ecx, src1 + mov edx, src2 + mov eax, ecx + or eax, edx + and eax, 15 + jz alignedDot + // unaligned + mov eax, count + shr eax, 2 + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + movups xmm0, [ecx+eax] + movups xmm1, [edx+eax] + mulps xmm0, xmm1 + add eax, 16 + jz doneDot + loopUnalignedDot: + movups xmm1, [ecx+eax] + movups xmm2, [edx+eax] + mulps xmm1, xmm2 + addps xmm0, xmm1 + add eax, 16 + jl loopUnalignedDot + jmp doneDot + // aligned + alignedDot: + mov eax, count + shr eax, 2 + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + movaps xmm0, [ecx+eax] + movaps xmm1, [edx+eax] + mulps xmm0, xmm1 + add eax, 16 + jz doneDot + loopAlignedDot: + movaps xmm1, [ecx+eax] + movaps xmm2, [edx+eax] + mulps xmm1, xmm2 + addps xmm0, xmm1 + add eax, 16 + jl loopAlignedDot + doneDot: + } + switch( count & 3 ) { + case 1: + __asm { + movss xmm1, [ecx] + movss xmm2, [edx] + mulss xmm1, xmm2 + addss xmm0, xmm1 + } + break; + case 2: + __asm { + xorps xmm2, xmm2 + movlps xmm1, [ecx] + movlps xmm2, [edx] + mulps xmm1, xmm2 + addps xmm0, xmm1 + } + break; + case 3: + __asm { + movss xmm1, [ecx] + movhps xmm1, [ecx+4] + movss xmm2, [edx] + movhps xmm2, [edx+4] + mulps xmm1, xmm2 + addps xmm0, xmm1 + } + break; + } + __asm { + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + mov eax, dot + movss [eax], xmm0 + } + return; + } +} + +// +// cmpeqps == Equal +// cmpneqps != Not Equal +// cmpltps < Less Than +// cmpnltps >= Not Less Than +// cmpnleps > Not Less Or Equal +// +#define FLIP not al +#define NOFLIP + +#define COMPARECONSTANT( DST, SRC0, CONSTANT, COUNT, CMP, CMPSIMD, DOFLIP ) \ + int i, cnt, pre, post; \ + float *aligned; \ + \ + /* if the float array is not aligned on a 4 byte boundary */ \ + if ( ((int) SRC0) & 3 ) { \ + /* unaligned memory access */ \ + pre = 0; \ + cnt = COUNT >> 2; \ + post = COUNT - (cnt<<2); \ + __asm mov edx, cnt \ + __asm test edx, edx \ + __asm je doneCmp \ + __asm push ebx \ + __asm neg edx \ + __asm mov esi, SRC0 \ + __asm prefetchnta [esi+64] \ + __asm movss xmm1, CONSTANT \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mov edi, DST \ + __asm mov ecx, 0x01010101 \ + __asm loopNA: \ + __asm movups xmm0, [esi] \ + __asm prefetchnta [esi+128] \ + __asm CMPSIMD xmm0, xmm1 \ + __asm movmskps eax, xmm0 \ + __asm DOFLIP \ + __asm mov ah, al \ + __asm shr ah, 1 \ + __asm mov bx, ax \ + __asm shl ebx, 14 \ + __asm mov bx, ax \ + __asm and ebx, ecx \ + __asm mov dword ptr [edi], ebx \ + __asm add esi, 16 \ + __asm add edi, 4 \ + __asm inc edx \ + __asm jl loopNA \ + __asm pop ebx \ + } \ + else { \ + /* aligned memory access */ \ + aligned = (float *) ((((int) SRC0) + 15) & ~15); \ + if ( (int)aligned > ((int)src0) + COUNT ) { \ + pre = COUNT; \ + post = 0; \ + } \ + else { \ + pre = aligned - SRC0; \ + cnt = (COUNT - pre) >> 2; \ + post = COUNT - pre - (cnt<<2); \ + __asm mov edx, cnt \ + __asm test edx, edx \ + __asm je doneCmp \ + __asm push ebx \ + __asm neg edx \ + __asm mov esi, aligned \ + __asm prefetchnta [esi+64] \ + __asm movss xmm1, CONSTANT \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mov edi, DST \ + __asm add edi, pre \ + __asm mov ecx, 0x01010101 \ + __asm loopA: \ + __asm movaps xmm0, [esi] \ + __asm prefetchnta [esi+128] \ + __asm CMPSIMD xmm0, xmm1 \ + __asm movmskps eax, xmm0 \ + __asm DOFLIP \ + __asm mov ah, al \ + __asm shr ah, 1 \ + __asm mov bx, ax \ + __asm shl ebx, 14 \ + __asm mov bx, ax \ + __asm and ebx, ecx \ + __asm mov dword ptr [edi], ebx \ + __asm add esi, 16 \ + __asm add edi, 4 \ + __asm inc edx \ + __asm jl loopA \ + __asm pop ebx \ + } \ + } \ + doneCmp: \ + double c = constant; \ + for ( i = 0; i < pre; i++ ) { \ + dst[i] = src0[i] CMP c; \ + } \ + for ( i = count - post; i < count; i++ ) { \ + dst[i] = src0[i] CMP c; \ + } + +#define COMPAREBITCONSTANT( DST, BITNUM, SRC0, CONSTANT, COUNT, CMP, CMPSIMD, DOFLIP ) \ + int i, cnt, pre, post; \ + float *aligned; \ + \ + /* if the float array is not aligned on a 4 byte boundary */ \ + if ( ((int) SRC0) & 3 ) { \ + /* unaligned memory access */ \ + pre = 0; \ + cnt = COUNT >> 2; \ + post = COUNT - (cnt<<2); \ + __asm mov edx, cnt \ + __asm test edx, edx \ + __asm je doneCmp \ + __asm push ebx \ + __asm neg edx \ + __asm mov esi, SRC0 \ + __asm prefetchnta [esi+64] \ + __asm movss xmm1, CONSTANT \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mov edi, DST \ + __asm mov cl, bitNum \ + __asm loopNA: \ + __asm movups xmm0, [esi] \ + __asm prefetchnta [esi+128] \ + __asm CMPSIMD xmm0, xmm1 \ + __asm movmskps eax, xmm0 \ + __asm DOFLIP \ + __asm mov ah, al \ + __asm shr ah, 1 \ + __asm mov bx, ax \ + __asm shl ebx, 14 \ + __asm mov bx, ax \ + __asm and ebx, 0x01010101 \ + __asm shl ebx, cl \ + __asm or ebx, dword ptr [edi] \ + __asm mov dword ptr [edi], ebx \ + __asm add esi, 16 \ + __asm add edi, 4 \ + __asm inc edx \ + __asm jl loopNA \ + __asm pop ebx \ + } \ + else { \ + /* aligned memory access */ \ + aligned = (float *) ((((int) SRC0) + 15) & ~15); \ + if ( (int)aligned > ((int)src0) + COUNT ) { \ + pre = COUNT; \ + post = 0; \ + } \ + else { \ + pre = aligned - SRC0; \ + cnt = (COUNT - pre) >> 2; \ + post = COUNT - pre - (cnt<<2); \ + __asm mov edx, cnt \ + __asm test edx, edx \ + __asm je doneCmp \ + __asm push ebx \ + __asm neg edx \ + __asm mov esi, aligned \ + __asm prefetchnta [esi+64] \ + __asm movss xmm1, CONSTANT \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mov edi, DST \ + __asm add edi, pre \ + __asm mov cl, bitNum \ + __asm loopA: \ + __asm movaps xmm0, [esi] \ + __asm prefetchnta [esi+128] \ + __asm CMPSIMD xmm0, xmm1 \ + __asm movmskps eax, xmm0 \ + __asm DOFLIP \ + __asm mov ah, al \ + __asm shr ah, 1 \ + __asm mov bx, ax \ + __asm shl ebx, 14 \ + __asm mov bx, ax \ + __asm and ebx, 0x01010101 \ + __asm shl ebx, cl \ + __asm or ebx, dword ptr [edi] \ + __asm mov dword ptr [edi], ebx \ + __asm add esi, 16 \ + __asm add edi, 4 \ + __asm inc edx \ + __asm jl loopA \ + __asm pop ebx \ + } \ + } \ + doneCmp: \ + float c = constant; \ + for ( i = 0; i < pre; i++ ) { \ + dst[i] |= ( src0[i] CMP c ) << BITNUM; \ + } \ + for ( i = count - post; i < count; i++ ) { \ + dst[i] |= ( src0[i] CMP c ) << BITNUM; \ + } + +/* +============ +idSIMD_SSE::CmpGT + + dst[i] = src0[i] > constant; +============ +*/ +void VPCALL idSIMD_SSE::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { + COMPARECONSTANT( dst, src0, constant, count, >, cmpnleps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpGT + + dst[i] |= ( src0[i] > constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_SSE::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, >, cmpnleps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpGE + + dst[i] = src0[i] >= constant; +============ +*/ +void VPCALL idSIMD_SSE::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { + COMPARECONSTANT( dst, src0, constant, count, >=, cmpnltps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpGE + + dst[i] |= ( src0[i] >= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_SSE::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, >=, cmpnltps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpLT + + dst[i] = src0[i] < constant; +============ +*/ +void VPCALL idSIMD_SSE::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { + COMPARECONSTANT( dst, src0, constant, count, <, cmpltps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpLT + + dst[i] |= ( src0[i] < constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_SSE::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, <, cmpltps, NOFLIP ) +} + +/* +============ +idSIMD_SSE::CmpLE + + dst[i] = src0[i] <= constant; +============ +*/ +void VPCALL idSIMD_SSE::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { + COMPARECONSTANT( dst, src0, constant, count, <=, cmpnleps, FLIP ) +} + +/* +============ +idSIMD_SSE::CmpLE + + dst[i] |= ( src0[i] <= constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_SSE::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, <=, cmpnleps, FLIP ) +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( float &min, float &max, const float *src, const int count ) { + int i, pre, post; + + min = idMath::INFINITY; max = -idMath::INFINITY; + + __asm + { + push ebx + mov eax, min + mov ebx, max + movss xmm0, [eax] + movss xmm1, [ebx] + shufps xmm0, xmm0, 0 + shufps xmm1, xmm1, 0 + + KFLOATINITS( src, count, pre, post ) + and eax, 15 + jz lpA + jmp lpNA + align 16 +lpNA: + movups xmm2, [edx+ebx] + movups xmm3, [edx+ebx+16] + minps xmm0, xmm2 + maxps xmm1, xmm2 + prefetchnta [edx+ebx+64] + minps xmm0, xmm3 + maxps xmm1, xmm3 + add ebx, 16*2 + jl lpNA + jmp done2 +lpA: + movaps xmm2, [edx+ebx] + movaps xmm3, [edx+ebx+16] + minps xmm0, xmm2 + maxps xmm1, xmm2 + prefetchnta [edx+ebx+64] + minps xmm0, xmm3 + maxps xmm1, xmm3 + add ebx, 16*2 + jl lpA + jmp done2 + align 16 +done2: + movaps xmm2, xmm0 + movaps xmm3, xmm1 + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) + minss xmm0, xmm2 + maxss xmm1, xmm3 + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) + minss xmm0, xmm2 + maxss xmm1, xmm3 + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) + minss xmm0, xmm2 + maxss xmm1, xmm3 + mov eax, min + mov ebx, max + movss [eax], xmm0 + movss [ebx], xmm1 +done: + pop ebx + } + + for ( i = 0; i < pre; i++ ) { + float tmp = src[i]; + if ( tmp > max ) { + max = tmp; + } + if ( tmp < min ) { + min = tmp; + } + } + for ( i = count - post; i < count; i++ ) { + float tmp = src[i]; + if ( tmp > max ) { + max = tmp; + } + if ( tmp < min ) { + min = tmp; + } + } +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { + __asm { + mov eax, count + test eax, eax + movss xmm0, idMath::INFINITY + xorps xmm1, xmm1 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + subps xmm1, xmm0 + jz done + mov ecx, eax + and ecx, 1 + mov esi, src + jz startLoop + movlps xmm2, [esi] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + dec eax + add esi, 2*4 + minps xmm0, xmm2 + maxps xmm1, xmm2 + startLoop: + imul eax, 2*4 + add esi, eax + neg eax + loopVert: + movlps xmm2, [esi+eax] + movhps xmm2, [esi+eax+8] + add eax, 4*4 + minps xmm0, xmm2 + maxps xmm1, xmm2 + jl loopVert + done: + movaps xmm2, xmm0 + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ) + minps xmm0, xmm2 + mov esi, min + movlps [esi], xmm0 + movaps xmm3, xmm1 + shufps xmm3, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) + maxps xmm1, xmm3 + mov edi, max + movlps [edi], xmm1 + } +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { + __asm { + + movss xmm0, idMath::INFINITY + xorps xmm1, xmm1 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + subps xmm1, xmm0 + movaps xmm2, xmm0 + movaps xmm3, xmm1 + + mov esi, src + mov eax, count + and eax, ~3 + jz done4 + imul eax, 12 + add esi, eax + neg eax + + loop4: +// prefetchnta [esi+4*12] + + movss xmm4, [esi+eax+0*12+8] + movhps xmm4, [esi+eax+0*12+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + movss xmm5, [esi+eax+1*12+0] + movhps xmm5, [esi+eax+1*12+4] + minps xmm2, xmm5 + maxps xmm3, xmm5 + + movss xmm6, [esi+eax+2*12+8] + movhps xmm6, [esi+eax+2*12+0] + minps xmm0, xmm6 + maxps xmm1, xmm6 + + movss xmm7, [esi+eax+3*12+0] + movhps xmm7, [esi+eax+3*12+4] + minps xmm2, xmm7 + maxps xmm3, xmm7 + + add eax, 4*12 + jl loop4 + + done4: + mov eax, count + and eax, 3 + jz done1 + imul eax, 12 + add esi, eax + neg eax + + loop1: + movss xmm4, [esi+eax+0*12+8] + movhps xmm4, [esi+eax+0*12+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + add eax, 12 + jl loop1 + + done1: + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) + minps xmm0, xmm2 + maxps xmm1, xmm3 + mov esi, min + movhps [esi], xmm0 + movss [esi+8], xmm0 + mov edi, max + movhps [edi], xmm1 + movss [edi+8], xmm1 + } +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + + movss xmm0, idMath::INFINITY + xorps xmm1, xmm1 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + subps xmm1, xmm0 + movaps xmm2, xmm0 + movaps xmm3, xmm1 + + mov esi, src + mov eax, count + and eax, ~3 + jz done4 + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loop4: +// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] + + movss xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + movss xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm5 + maxps xmm3, xmm5 + + movss xmm6, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm6, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm6 + maxps xmm1, xmm6 + + movss xmm7, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm7, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm7 + maxps xmm3, xmm7 + + add eax, 4*DRAWVERT_SIZE + jl loop4 + + done4: + mov eax, count + and eax, 3 + jz done1 + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loop1: + movss xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + add eax, DRAWVERT_SIZE + jl loop1 + + done1: + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) + minps xmm0, xmm2 + maxps xmm1, xmm3 + mov esi, min + movhps [esi], xmm0 + movss [esi+8], xmm0 + mov edi, max + movhps [edi], xmm1 + movss [edi+8], xmm1 + } +} + +/* +============ +idSIMD_SSE::MinMax +============ +*/ +void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + + movss xmm0, idMath::INFINITY + xorps xmm1, xmm1 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + subps xmm1, xmm0 + movaps xmm2, xmm0 + movaps xmm3, xmm1 + + mov edi, indexes + mov esi, src + mov eax, count + and eax, ~3 + jz done4 + shl eax, 2 + add edi, eax + neg eax + + loop4: +// prefetchnta [edi+128] +// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] + + mov edx, [edi+eax+0] + imul edx, DRAWVERT_SIZE + movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + mov edx, [edi+eax+4] + imul edx, DRAWVERT_SIZE + movss xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + movhps xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm5 + maxps xmm3, xmm5 + + mov edx, [edi+eax+8] + imul edx, DRAWVERT_SIZE + movss xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm6 + maxps xmm1, xmm6 + + mov edx, [edi+eax+12] + imul edx, DRAWVERT_SIZE + movss xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + movhps xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+4] + minps xmm2, xmm7 + maxps xmm3, xmm7 + + add eax, 4*4 + jl loop4 + + done4: + mov eax, count + and eax, 3 + jz done1 + shl eax, 2 + add edi, eax + neg eax + + loop1: + mov edx, [edi+eax+0] + imul edx, DRAWVERT_SIZE; + movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] + movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] + minps xmm0, xmm4 + maxps xmm1, xmm4 + + add eax, 4 + jl loop1 + + done1: + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) + minps xmm0, xmm2 + maxps xmm1, xmm3 + mov esi, min + movhps [esi], xmm0 + movss [esi+8], xmm0 + mov edi, max + movhps [edi], xmm1 + movss [edi+8], xmm1 + } +} + +/* +============ +idSIMD_SSE::Clamp +============ +*/ +void VPCALL idSIMD_SSE::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { + int i, pre, post; + + __asm + { + movss xmm0,min + movss xmm1,max + shufps xmm0,xmm0,0 + shufps xmm1,xmm1,0 + + KFLOATINITDS( dst, src, count, pre, post ) + and eax,15 + jne lpNA + jmp lpA + align 16 +lpA: + movaps xmm2,[edx+ebx] + movaps xmm3,[edx+ebx+16] + maxps xmm2,xmm0 + maxps xmm3,xmm0 + prefetchnta [edx+ebx+64] + minps xmm2,xmm1 + minps xmm3,xmm1 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpA + jmp done + + align 16 +lpNA: + movups xmm2,[edx+ebx] + movups xmm3,[edx+ebx+16] + maxps xmm2,xmm0 + maxps xmm3,xmm0 + prefetchnta [edx+ebx+64] + minps xmm2,xmm1 + minps xmm3,xmm1 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpNA +done: + } + + for ( i = 0; i < pre; i++ ) { + if ( src[i] < min ) + dst[i] = min; + else if ( src[i] > max ) + dst[i] = max; + else + dst[i] = src[i]; + } + + for( i = count - post; i < count; i++ ) { + if ( src[i] < min ) + dst[i] = min; + else if ( src[i] > max ) + dst[i] = max; + else + dst[i] = src[i]; + } +} + +/* +============ +idSIMD_SSE::ClampMin +============ +*/ +void VPCALL idSIMD_SSE::ClampMin( float *dst, const float *src, const float min, const int count ) { + int i, pre, post; + + __asm + { + movss xmm0,min + shufps xmm0,xmm0,0 + + KFLOATINITDS( dst, src, count, pre, post ) + and eax,15 + jne lpNA + jmp lpA + align 16 +lpA: + movaps xmm2,[edx+ebx] + movaps xmm3,[edx+ebx+16] + maxps xmm2,xmm0 + prefetchnta [edx+ebx+64] + maxps xmm3,xmm0 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpA + jmp done + + align 16 +lpNA: + movups xmm2,[edx+ebx] + movups xmm3,[edx+ebx+16] + maxps xmm2,xmm0 + prefetchnta [edx+ebx+64] + maxps xmm3,xmm0 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpNA +done: + } + + for( i = 0; i < pre; i++ ) { + if ( src[i] < min ) + dst[i] = min; + else + dst[i] = src[i]; + } + for( i = count - post; i < count; i++ ) { + if ( src[i] < min ) + dst[i] = min; + else + dst[i] = src[i]; + } +} + +/* +============ +idSIMD_SSE::ClampMax +============ +*/ +void VPCALL idSIMD_SSE::ClampMax( float *dst, const float *src, const float max, const int count ) { + int i, pre, post; + + __asm + { + movss xmm1,max + shufps xmm1,xmm1,0 + + KFLOATINITDS( dst, src, count, pre, post ) + and eax,15 + jne lpNA + jmp lpA + align 16 +lpA: + movaps xmm2,[edx+ebx] + movaps xmm3,[edx+ebx+16] + minps xmm2,xmm1 + prefetchnta [edx+ebx+64] + minps xmm3,xmm1 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpA + jmp done + + align 16 +lpNA: + movups xmm2,[edx+ebx] + movups xmm3,[edx+ebx+16] + minps xmm2,xmm1 + prefetchnta [edx+ebx+64] + minps xmm3,xmm1 + movaps [edi+ebx],xmm2 + movaps [edi+ebx+16],xmm3 + add ebx,16*2 + jl lpNA +done: + } + + for( i = 0; i < pre; i++ ) { + if ( src[i] > max ) + dst[i] = max; + else + dst[i] = src[i]; + } + + for( i = count - post; i < count; i++ ) { + if ( src[i] > max ) + dst[i] = max; + else + dst[i] = src[i]; + } +} + +/* +============ +idSIMD_SSE::Zero16 +============ +*/ +void VPCALL idSIMD_SSE::Zero16( float *dst, const int count ) { + __asm { + mov edx, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneZero16 + shl eax, 4 + add edx, eax + neg eax + xorps xmm0, xmm0 + loopZero16: + movaps [edx+eax], xmm0 + add eax, 16 + jl loopZero16 + doneZero16: + } +} + +/* +============ +idSIMD_SSE::Negate16 +============ +*/ +void VPCALL idSIMD_SSE::Negate16( float *dst, const int count ) { + __asm { + mov edx, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneNegate16 + shl eax, 4 + add edx, eax + neg eax + movss xmm0, SIMD_SP_signBitMask + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + loopNegate16: + movaps xmm1, [edx+eax] + xorps xmm1, xmm0 + movaps [edx+eax], xmm1 + add eax, 16 + jl loopNegate16 + doneNegate16: + } +} + +/* +============ +idSIMD_SSE::Copy16 +============ +*/ +void VPCALL idSIMD_SSE::Copy16( float *dst, const float *src, const int count ) { + __asm { + mov ecx, src + mov edx, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneCopy16 + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + loopCopy16: + movaps xmm0, [ecx+eax] + movaps [edx+eax], xmm0 + add eax, 16 + jl loopCopy16 + doneCopy16: + } +} + +/* +============ +idSIMD_SSE::Add16 +============ +*/ +void VPCALL idSIMD_SSE::Add16( float *dst, const float *src1, const float *src2, const int count ) { + __asm { + mov ecx, src1 + mov edx, src2 + mov esi, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneAdd16 + shl eax, 4 + add esi, eax + add ecx, eax + add edx, eax + neg eax + loopAdd16: + movaps xmm0, [ecx+eax] + addps xmm0, [edx+eax] + movaps [esi+eax], xmm0 + add eax, 16 + jl loopAdd16 + doneAdd16: + } +} + +/* +============ +idSIMD_SSE::Sub16 +============ +*/ +void VPCALL idSIMD_SSE::Sub16( float *dst, const float *src1, const float *src2, const int count ) { + __asm { + mov ecx, src1 + mov edx, src2 + mov esi, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneSub16 + shl eax, 4 + add esi, eax + add ecx, eax + add edx, eax + neg eax + loopSub16: + movaps xmm0, [ecx+eax] + subps xmm0, [edx+eax] + movaps [esi+eax], xmm0 + add eax, 16 + jl loopSub16 + doneSub16: + } +} + +/* +============ +idSIMD_SSE::Mul16 +============ +*/ +void VPCALL idSIMD_SSE::Mul16( float *dst, const float *src1, const float constant, const int count ) { + __asm { + mov ecx, dst + mov edx, src1 + mov eax, count + add eax, 3 + shr eax, 2 + jz doneMulScalar16 + movss xmm1, constant + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + shufps xmm1, xmm1, 0x00 + loopMulScalar16: + movaps xmm0, [edx+eax] + mulps xmm0, xmm1 + movaps [ecx+eax], xmm0 + add eax, 16 + jl loopMulScalar16 + doneMulScalar16: + } +} + +/* +============ +idSIMD_SSE::AddAssign16 +============ +*/ +void VPCALL idSIMD_SSE::AddAssign16( float *dst, const float *src, const int count ) { + __asm { + mov ecx, dst + mov edx, src + mov eax, count + add eax, 3 + shr eax, 2 + jz doneAddAssign16 + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + loopAddAssign16: + movaps xmm0, [ecx+eax] + addps xmm0, [edx+eax] + movaps [ecx+eax], xmm0 + add eax, 16 + jl loopAddAssign16 + doneAddAssign16: + } +} + +/* +============ +idSIMD_SSE::SubAssign16 +============ +*/ +void VPCALL idSIMD_SSE::SubAssign16( float *dst, const float *src, const int count ) { + __asm { + mov ecx, dst + mov edx, src + mov eax, count + add eax, 3 + shr eax, 2 + jz doneSubAssign16 + shl eax, 4 + add ecx, eax + add edx, eax + neg eax + loopSubAssign16: + movaps xmm0, [ecx+eax] + subps xmm0, [edx+eax] + movaps [ecx+eax], xmm0 + add eax, 16 + jl loopSubAssign16 + doneSubAssign16: + } +} + +/* +============ +idSIMD_SSE::MulAssign16 +============ +*/ +void VPCALL idSIMD_SSE::MulAssign16( float *dst, const float constant, const int count ) { + __asm { + mov ecx, dst + mov eax, count + add eax, 3 + shr eax, 2 + jz doneMulAssign16 + movss xmm1, constant + shl eax, 4 + add ecx, eax + neg eax + shufps xmm1, xmm1, 0x00 + loopMulAssign16: + movaps xmm0, [ecx+eax] + mulps xmm0, xmm1 + movaps [ecx+eax], xmm0 + add eax, 16 + jl loopMulAssign16 + doneMulAssign16: + } +} + +/* +============ +idSIMD_SSE::MatX_MultiplyVecX + + optimizes the following matrix multiplications: + + NxN * Nx1 + Nx6 * 6x1 + 6xN * Nx1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss [eax+offset], reg1 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps [eax+offset], reg1 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps [eax+offset], reg1 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps [eax+offset], reg1 \ + __asm movhps [eax+offset+8], reg1 +#define STOREC = + + int numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: { + switch( numRows ) { + case 1: { // 1x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + STORE1( 0, xmm0, xmm1 ) + } + return; + } + case 6: { // 6x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0]; + mPtr++; + } + return; + } + } + break; + } + case 2: { + switch( numRows ) { + case 2: { // 2x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm1, [esi+4] + movss xmm2, [edi] + mulss xmm2, xmm0 + movss xmm3, [edi+4] + mulss xmm3, xmm1 + addss xmm2, xmm3 + STORE1( 0, xmm2, xmm4 ) + mulss xmm0, [edi+8] + mulss xmm1, [edi+8+4] + addss xmm0, xmm1 + STORE1( 4, xmm0, xmm4 ) + } + return; + } + case 6: { // 6x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, [esi] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movaps xmm0, [edi] + mulps xmm0, xmm7 + movaps xmm1, [edi+16] + mulps xmm1, xmm7 + movaps xmm2, xmm0 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + movaps xmm3, [edi+32] + addps xmm0, xmm2 + mulps xmm3, xmm7 + STORE4( 0, xmm0, xmm4 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm1, xmm3 + addps xmm3, xmm1 + STORE2LO( 16, xmm3, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + return; + } + } + break; + } + case 3: { + switch( numRows ) { + case 3: { // 3x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm4, [edi] + mulss xmm4, xmm0 + movss xmm1, [esi+4] + movss xmm5, [edi+4] + mulss xmm5, xmm1 + addss xmm4, xmm5 + movss xmm2, [esi+8] + movss xmm6, [edi+8] + mulss xmm6, xmm2 + addss xmm4, xmm6 + movss xmm3, [edi+12] + mulss xmm3, xmm0 + STORE1( 0, xmm4, xmm7 ); + movss xmm5, [edi+12+4] + mulss xmm5, xmm1 + addss xmm3, xmm5 + movss xmm6, [edi+12+8] + mulss xmm6, xmm2 + addss xmm3, xmm6 + mulss xmm0, [edi+24] + mulss xmm1, [edi+24+4] + STORE1( 4, xmm3, xmm7 ); + addss xmm0, xmm1 + mulss xmm2, [edi+24+8] + addss xmm0, xmm2 + STORE1( 8, xmm0, xmm7 ); + } + return; + } + case 6: { // 6x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm5, [esi] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [esi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 + movlps xmm1, [edi+4*4] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 + movlps xmm2, [edi+6*4] + movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 + mulps xmm0, xmm5 + movlps xmm3, [edi+10*4] + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 + movaps xmm3, xmm1 + shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 + mulps xmm1, xmm6 + shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 + mulps xmm3, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm3 + STORE4( 0, xmm0, xmm4 ) + movss xmm1, [edi+12*4] + mulss xmm1, xmm5 + movss xmm2, [edi+13*4] + mulss xmm2, xmm6 + movss xmm3, [edi+14*4] + mulss xmm3, xmm7 + addss xmm1, xmm2 + addss xmm1, xmm3 + STORE1( 16, xmm1, xmm4 ) + mulss xmm5, [edi+15*4] + mulss xmm6, [edi+16*4] + mulss xmm7, [edi+17*4] + addss xmm5, xmm6 + addss xmm5, xmm7 + STORE1( 20, xmm5, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + return; + } + } + break; + } + case 4: { + switch( numRows ) { + case 4: { // 4x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi ] + movlps xmm0, qword ptr [edi ] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + STORE4( 0, xmm0, xmm2 ) + } + return; + } + case 6: { // 6x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi+ 0] + movlps xmm0, qword ptr [edi+ 0] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + movlps xmm1, qword ptr [edi+64] + movhps xmm1, qword ptr [edi+80] + STORE4( 0, xmm0, xmm4 ) + mulps xmm1, xmm6 + movlps xmm2, qword ptr [edi+72] + movhps xmm2, qword ptr [edi+88] + mulps xmm2, xmm7 + addps xmm1, xmm2 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm3, xmm1 + addps xmm1, xmm3 + STORE2LO( 16, xmm1, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; + mPtr += 4; + } + return; + } + } + break; + } + case 5: { + switch( numRows ) { + case 5: { // 5x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X + movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 + movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X + movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 + movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 + shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 + movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 + movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 + movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 + movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 + movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 + movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 + shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 + movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 + movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 + movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X + movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 + shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 + movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 + shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 + movss xmm7, [esi+0*4] + shufps xmm7, xmm7, 0 + mulps xmm0, xmm7 + movss xmm5, [esi+1*4] + shufps xmm5, xmm5, 0 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, 0 + mulps xmm2, xmm6 + addps xmm0, xmm2 + movss xmm1, [esi+3*4] + shufps xmm1, xmm1, 0 + mulps xmm3, xmm1 + addps xmm0, xmm3 + movss xmm2, [esi+4*4] + shufps xmm2, xmm2, 0 + mulps xmm4, xmm2 + addps xmm0, xmm4 + mulss xmm7, [edi+20*4] + mulss xmm5, [edi+21*4] + addps xmm7, xmm5 + mulss xmm6, [edi+22*4] + addps xmm7, xmm6 + mulss xmm1, [edi+23*4] + addps xmm7, xmm1 + mulss xmm2, [edi+24*4] + addps xmm7, xmm2 + STORE4( 0, xmm0, xmm3 ) + STORE1( 16, xmm7, xmm4 ) + } + return; + } + case 6: { // 6x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [esi] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm0, [edi] + movhps xmm3, [edi+8] + movaps xmm1, [edi+16] + movlps xmm2, [edi+32] + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 + mulps xmm0, xmm6 + mulps xmm3, xmm7 + movlps xmm2, [edi+40] + addps xmm0, xmm3 // xmm0 + xmm1 + movhps xmm5, [edi+40+8] + movlps xmm3, [edi+40+16] + movhps xmm3, [edi+40+24] + movlps xmm4, [edi+40+32] + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 + shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 + shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 + mulps xmm2, xmm6 + mulps xmm5, xmm7 + addps xmm2, xmm5 // xmm2 + xmm3 + movss xmm5, [esi+16] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm0 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) + shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) + addps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + STORE4( 0, xmm0, xmm2 ) + movlps xmm4, [edi+80] + movhps xmm3, [edi+80+8] + movaps xmm1, [edi+80+16] + movlps xmm2, [edi+80+32] + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 + mulps xmm4, xmm6 + mulps xmm3, xmm7 + mulps xmm1, xmm5 + addps xmm4, xmm3 // xmm4 + xmm1 + shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) + addps xmm4, xmm1 + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) + addps xmm4, xmm1 + STORE2LO( 16, xmm4, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + return; + } + } + break; + } + case 6: { + switch( numRows ) { + case 1: { // 1x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + movss xmm1, [esi+4] + mulss xmm1, [edi+4] + movss xmm2, [esi+8] + addss xmm0, xmm1 + mulss xmm2, [edi+8] + movss xmm3, [esi+12] + addss xmm0, xmm2 + mulss xmm3, [edi+12] + movss xmm4, [esi+16] + addss xmm0, xmm3 + mulss xmm4, [edi+16] + movss xmm5, [esi+20] + addss xmm0, xmm4 + mulss xmm5, [edi+20] + movss xmm6, [esi+24] + addss xmm0, xmm5 + mulss xmm6, [edi+24] + addss xmm0, xmm6 + STORE1( 0, xmm0, xmm7 ) + } + return; + } + case 2: { // 2x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + } + return; + } + case 3: { // 3x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + // row 2 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + STORE1( 8, xmm0, xmm3 ) + } + return; + } + case 4: { // 4x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm4 ) + } + return; + } + case 5: { // 5x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm3 ) + // row 5 + movaps xmm0, [edi+96] + movaps xmm1, [edi+96+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, 0x01 + addss xmm0, xmm1 + STORE1( 16, xmm0, xmm3 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, qword ptr [esi] + movlps xmm6, qword ptr [esi+8] + shufps xmm7, xmm7, 0x44 + shufps xmm6, xmm6, 0x44 + movlps xmm0, qword ptr [edi ] + movhps xmm0, qword ptr [edi+ 24] + mulps xmm0, xmm7 + movlps xmm3, qword ptr [edi+ 8] + movhps xmm3, qword ptr [edi+ 32] + mulps xmm3, xmm6 + movlps xmm1, qword ptr [edi+ 48] + movhps xmm1, qword ptr [edi+ 72] + mulps xmm1, xmm7 + movlps xmm2, qword ptr [edi+ 96] + movhps xmm2, qword ptr [edi+120] + mulps xmm2, xmm7 + movlps xmm4, qword ptr [edi+ 56] + movhps xmm4, qword ptr [edi+ 80] + movlps xmm5, qword ptr [edi+104] + movhps xmm5, qword ptr [edi+128] + mulps xmm4, xmm6 + movlps xmm7, qword ptr [esi+16] + addps xmm0, xmm3 + shufps xmm7, xmm7, 0x44 + mulps xmm5, xmm6 + addps xmm1, xmm4 + movlps xmm3, qword ptr [edi+ 16] + movhps xmm3, qword ptr [edi+ 40] + addps xmm2, xmm5 + movlps xmm4, qword ptr [edi+ 64] + movhps xmm4, qword ptr [edi+ 88] + mulps xmm3, xmm7 + movlps xmm5, qword ptr [edi+112] + movhps xmm5, qword ptr [edi+136] + addps xmm0, xmm3 + mulps xmm4, xmm7 + mulps xmm5, xmm7 + addps xmm1, xmm4 + addps xmm2, xmm5 + movaps xmm6, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm6, xmm1, 0xDD + movaps xmm7, xmm2 + shufps xmm7, xmm2, 0x88 + shufps xmm2, xmm2, 0xDD + addps xmm0, xmm6 + addps xmm2, xmm7 + STORE4( 0, xmm0, xmm3 ) + STORE2LO( 16, xmm2, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + return; + } + } + break; + } + default: { + int numColumns = mat.GetNumColumns(); + for ( int i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] STOREC sum; + mPtr += numColumns; + } + break; + } + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +idSIMD_SSE::MatX_MultiplyAddVecX + + optimizes the following matrix multiplications: + + NxN * Nx1 + Nx6 * 6x1 + 6xN * Nx1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss reg2, [eax+offset] \ + __asm addss reg2, reg1 \ + __asm movss [eax+offset], reg2 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm addps reg2, reg1 \ + __asm movlps [eax+offset], reg2 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps reg2, [eax+offset] \ + __asm addps reg2, reg1 \ + __asm movhps [eax+offset], reg2 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm movhps reg2, [eax+offset+8] \ + __asm addps reg2, reg1 \ + __asm movlps [eax+offset], reg2 \ + __asm movhps [eax+offset+8], reg2 +#define STOREC += + + int numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: { + switch( numRows ) { + case 1: { // 1x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + STORE1( 0, xmm0, xmm1 ) + } + return; + } + case 6: { // 6x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0]; + mPtr++; + } + return; + } + } + break; + } + case 2: { + switch( numRows ) { + case 2: { // 2x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm1, [esi+4] + movss xmm2, [edi] + mulss xmm2, xmm0 + movss xmm3, [edi+4] + mulss xmm3, xmm1 + addss xmm2, xmm3 + STORE1( 0, xmm2, xmm4 ) + mulss xmm0, [edi+8] + mulss xmm1, [edi+8+4] + addss xmm0, xmm1 + STORE1( 4, xmm0, xmm4 ) + } + return; + } + case 6: { // 6x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, [esi] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movaps xmm0, [edi] + mulps xmm0, xmm7 + movaps xmm1, [edi+16] + mulps xmm1, xmm7 + movaps xmm2, xmm0 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + movaps xmm3, [edi+32] + addps xmm0, xmm2 + mulps xmm3, xmm7 + STORE4( 0, xmm0, xmm4 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm1, xmm3 + addps xmm3, xmm1 + STORE2LO( 16, xmm3, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + return; + } + } + break; + } + case 3: { + switch( numRows ) { + case 3: { // 3x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm4, [edi] + mulss xmm4, xmm0 + movss xmm1, [esi+4] + movss xmm5, [edi+4] + mulss xmm5, xmm1 + addss xmm4, xmm5 + movss xmm2, [esi+8] + movss xmm6, [edi+8] + mulss xmm6, xmm2 + addss xmm4, xmm6 + movss xmm3, [edi+12] + mulss xmm3, xmm0 + STORE1( 0, xmm4, xmm7 ); + movss xmm5, [edi+12+4] + mulss xmm5, xmm1 + addss xmm3, xmm5 + movss xmm6, [edi+12+8] + mulss xmm6, xmm2 + addss xmm3, xmm6 + mulss xmm0, [edi+24] + mulss xmm1, [edi+24+4] + STORE1( 4, xmm3, xmm7 ); + addss xmm0, xmm1 + mulss xmm2, [edi+24+8] + addss xmm0, xmm2 + STORE1( 8, xmm0, xmm7 ); + } + return; + } + case 6: { // 6x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm5, [esi] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [esi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 + movlps xmm1, [edi+4*4] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 + movlps xmm2, [edi+6*4] + movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 + mulps xmm0, xmm5 + movlps xmm3, [edi+10*4] + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 + movaps xmm3, xmm1 + shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 + mulps xmm1, xmm6 + shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 + mulps xmm3, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm3 + STORE4( 0, xmm0, xmm4 ) + movss xmm1, [edi+12*4] + mulss xmm1, xmm5 + movss xmm2, [edi+13*4] + mulss xmm2, xmm6 + movss xmm3, [edi+14*4] + mulss xmm3, xmm7 + addss xmm1, xmm2 + addss xmm1, xmm3 + STORE1( 16, xmm1, xmm4 ) + mulss xmm5, [edi+15*4] + mulss xmm6, [edi+16*4] + mulss xmm7, [edi+17*4] + addss xmm5, xmm6 + addss xmm5, xmm7 + STORE1( 20, xmm5, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + return; + } + } + break; + } + case 4: { + switch( numRows ) { + case 4: { // 4x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi ] + movlps xmm0, qword ptr [edi ] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + STORE4( 0, xmm0, xmm2 ) + } + return; + } + case 6: { // 6x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi+ 0] + movlps xmm0, qword ptr [edi+ 0] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + movlps xmm1, qword ptr [edi+64] + movhps xmm1, qword ptr [edi+80] + STORE4( 0, xmm0, xmm4 ) + mulps xmm1, xmm6 + movlps xmm2, qword ptr [edi+72] + movhps xmm2, qword ptr [edi+88] + mulps xmm2, xmm7 + addps xmm1, xmm2 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm3, xmm1 + addps xmm1, xmm3 + STORE2LO( 16, xmm1, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; + mPtr += 4; + } + return; + } + } + break; + } + case 5: { + switch( numRows ) { + case 5: { // 5x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X + movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 + movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X + movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 + movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 + shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 + movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 + movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 + movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 + movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 + movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 + movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 + shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 + movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 + movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 + movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X + movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 + shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 + movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 + shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 + movss xmm7, [esi+0*4] + shufps xmm7, xmm7, 0 + mulps xmm0, xmm7 + movss xmm5, [esi+1*4] + shufps xmm5, xmm5, 0 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, 0 + mulps xmm2, xmm6 + addps xmm0, xmm2 + movss xmm1, [esi+3*4] + shufps xmm1, xmm1, 0 + mulps xmm3, xmm1 + addps xmm0, xmm3 + movss xmm2, [esi+4*4] + shufps xmm2, xmm2, 0 + mulps xmm4, xmm2 + addps xmm0, xmm4 + mulss xmm7, [edi+20*4] + mulss xmm5, [edi+21*4] + addps xmm7, xmm5 + mulss xmm6, [edi+22*4] + addps xmm7, xmm6 + mulss xmm1, [edi+23*4] + addps xmm7, xmm1 + mulss xmm2, [edi+24*4] + addps xmm7, xmm2 + STORE4( 0, xmm0, xmm3 ) + STORE1( 16, xmm7, xmm4 ) + } + return; + } + case 6: { // 6x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [esi] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm0, [edi] + movhps xmm3, [edi+8] + movaps xmm1, [edi+16] + movlps xmm2, [edi+32] + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 + mulps xmm0, xmm6 + mulps xmm3, xmm7 + movlps xmm2, [edi+40] + addps xmm0, xmm3 // xmm0 + xmm1 + movhps xmm5, [edi+40+8] + movlps xmm3, [edi+40+16] + movhps xmm3, [edi+40+24] + movlps xmm4, [edi+40+32] + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 + shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 + shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 + mulps xmm2, xmm6 + mulps xmm5, xmm7 + addps xmm2, xmm5 // xmm2 + xmm3 + movss xmm5, [esi+16] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm0 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) + shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) + addps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + STORE4( 0, xmm0, xmm2 ) + movlps xmm4, [edi+80] + movhps xmm3, [edi+80+8] + movaps xmm1, [edi+80+16] + movlps xmm2, [edi+80+32] + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 + mulps xmm4, xmm6 + mulps xmm3, xmm7 + mulps xmm1, xmm5 + addps xmm4, xmm3 // xmm4 + xmm1 + shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) + addps xmm4, xmm1 + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) + addps xmm4, xmm1 + STORE2LO( 16, xmm4, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + return; + } + } + break; + } + case 6: { + switch( numRows ) { + case 1: { // 1x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + movss xmm1, [esi+4] + mulss xmm1, [edi+4] + movss xmm2, [esi+8] + addss xmm0, xmm1 + mulss xmm2, [edi+8] + movss xmm3, [esi+12] + addss xmm0, xmm2 + mulss xmm3, [edi+12] + movss xmm4, [esi+16] + addss xmm0, xmm3 + mulss xmm4, [edi+16] + movss xmm5, [esi+20] + addss xmm0, xmm4 + mulss xmm5, [edi+20] + movss xmm6, [esi+24] + addss xmm0, xmm5 + mulss xmm6, [edi+24] + addss xmm0, xmm6 + STORE1( 0, xmm0, xmm7 ) + } + return; + } + case 2: { // 2x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + } + return; + } + case 3: { // 3x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + // row 2 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + STORE1( 8, xmm0, xmm3 ) + } + return; + } + case 4: { // 4x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm4 ) + } + return; + } + case 5: { // 5x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm3 ) + // row 5 + movaps xmm0, [edi+96] + movaps xmm1, [edi+96+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, 0x01 + addss xmm0, xmm1 + STORE1( 16, xmm0, xmm3 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, qword ptr [esi] + movlps xmm6, qword ptr [esi+8] + shufps xmm7, xmm7, 0x44 + shufps xmm6, xmm6, 0x44 + movlps xmm0, qword ptr [edi ] + movhps xmm0, qword ptr [edi+ 24] + mulps xmm0, xmm7 + movlps xmm3, qword ptr [edi+ 8] + movhps xmm3, qword ptr [edi+ 32] + mulps xmm3, xmm6 + movlps xmm1, qword ptr [edi+ 48] + movhps xmm1, qword ptr [edi+ 72] + mulps xmm1, xmm7 + movlps xmm2, qword ptr [edi+ 96] + movhps xmm2, qword ptr [edi+120] + mulps xmm2, xmm7 + movlps xmm4, qword ptr [edi+ 56] + movhps xmm4, qword ptr [edi+ 80] + movlps xmm5, qword ptr [edi+104] + movhps xmm5, qword ptr [edi+128] + mulps xmm4, xmm6 + movlps xmm7, qword ptr [esi+16] + addps xmm0, xmm3 + shufps xmm7, xmm7, 0x44 + mulps xmm5, xmm6 + addps xmm1, xmm4 + movlps xmm3, qword ptr [edi+ 16] + movhps xmm3, qword ptr [edi+ 40] + addps xmm2, xmm5 + movlps xmm4, qword ptr [edi+ 64] + movhps xmm4, qword ptr [edi+ 88] + mulps xmm3, xmm7 + movlps xmm5, qword ptr [edi+112] + movhps xmm5, qword ptr [edi+136] + addps xmm0, xmm3 + mulps xmm4, xmm7 + mulps xmm5, xmm7 + addps xmm1, xmm4 + addps xmm2, xmm5 + movaps xmm6, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm6, xmm1, 0xDD + movaps xmm7, xmm2 + shufps xmm7, xmm2, 0x88 + shufps xmm2, xmm2, 0xDD + addps xmm0, xmm6 + addps xmm2, xmm7 + STORE4( 0, xmm0, xmm3 ) + STORE2LO( 16, xmm2, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + return; + } + } + break; + } + default: { + int numColumns = mat.GetNumColumns(); + for ( int i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] STOREC sum; + mPtr += numColumns; + } + break; + } + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +idSIMD_SSE::MatX_MultiplySubVecX + + optimizes the following matrix multiplications: + + NxN * Nx1 + Nx6 * 6x1 + 6xN * Nx1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss reg2, [eax+offset] \ + __asm subss reg2, reg1 \ + __asm movss [eax+offset], reg2 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm subps reg2, reg1 \ + __asm movlps [eax+offset], reg2 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps reg2, [eax+offset] \ + __asm subps reg2, reg1 \ + __asm movhps [eax+offset], reg2 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm movhps reg2, [eax+offset+8] \ + __asm subps reg2, reg1 \ + __asm movlps [eax+offset], reg2 \ + __asm movhps [eax+offset+8], reg2 +#define STOREC -= + + int numRows; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumColumns() ); + assert( dst.GetSize() >= mat.GetNumRows() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numRows = mat.GetNumRows(); + switch( mat.GetNumColumns() ) { + case 1: { + switch( numRows ) { + case 1: { // 1x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + STORE1( 0, xmm0, xmm1 ) + } + return; + } + case 6: { // 6x1 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0]; + mPtr++; + } + return; + } + } + break; + } + case 2: { + switch( numRows ) { + case 2: { // 2x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm1, [esi+4] + movss xmm2, [edi] + mulss xmm2, xmm0 + movss xmm3, [edi+4] + mulss xmm3, xmm1 + addss xmm2, xmm3 + STORE1( 0, xmm2, xmm4 ) + mulss xmm0, [edi+8] + mulss xmm1, [edi+8+4] + addss xmm0, xmm1 + STORE1( 4, xmm0, xmm4 ) + } + return; + } + case 6: { // 6x2 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, [esi] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movaps xmm0, [edi] + mulps xmm0, xmm7 + movaps xmm1, [edi+16] + mulps xmm1, xmm7 + movaps xmm2, xmm0 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + movaps xmm3, [edi+32] + addps xmm0, xmm2 + mulps xmm3, xmm7 + STORE4( 0, xmm0, xmm4 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm1, xmm3 + addps xmm3, xmm1 + STORE2LO( 16, xmm3, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; + mPtr += 2; + } + return; + } + } + break; + } + case 3: { + switch( numRows ) { + case 3: { // 3x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + movss xmm4, [edi] + mulss xmm4, xmm0 + movss xmm1, [esi+4] + movss xmm5, [edi+4] + mulss xmm5, xmm1 + addss xmm4, xmm5 + movss xmm2, [esi+8] + movss xmm6, [edi+8] + mulss xmm6, xmm2 + addss xmm4, xmm6 + movss xmm3, [edi+12] + mulss xmm3, xmm0 + STORE1( 0, xmm4, xmm7 ); + movss xmm5, [edi+12+4] + mulss xmm5, xmm1 + addss xmm3, xmm5 + movss xmm6, [edi+12+8] + mulss xmm6, xmm2 + addss xmm3, xmm6 + mulss xmm0, [edi+24] + mulss xmm1, [edi+24+4] + STORE1( 4, xmm3, xmm7 ); + addss xmm0, xmm1 + mulss xmm2, [edi+24+8] + addss xmm0, xmm2 + STORE1( 8, xmm0, xmm7 ); + } + return; + } + case 6: { // 6x3 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm5, [esi] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [esi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 + movlps xmm1, [edi+4*4] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 + movlps xmm2, [edi+6*4] + movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 + mulps xmm0, xmm5 + movlps xmm3, [edi+10*4] + shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 + movaps xmm3, xmm1 + shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 + mulps xmm1, xmm6 + shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 + mulps xmm3, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm3 + STORE4( 0, xmm0, xmm4 ) + movss xmm1, [edi+12*4] + mulss xmm1, xmm5 + movss xmm2, [edi+13*4] + mulss xmm2, xmm6 + movss xmm3, [edi+14*4] + mulss xmm3, xmm7 + addss xmm1, xmm2 + addss xmm1, xmm3 + STORE1( 16, xmm1, xmm4 ) + mulss xmm5, [edi+15*4] + mulss xmm6, [edi+16*4] + mulss xmm7, [edi+17*4] + addss xmm5, xmm6 + addss xmm5, xmm7 + STORE1( 20, xmm5, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; + mPtr += 3; + } + return; + } + } + break; + } + case 4: { + switch( numRows ) { + case 4: { // 4x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi ] + movlps xmm0, qword ptr [edi ] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + STORE4( 0, xmm0, xmm2 ) + } + return; + } + case 6: { // 6x4 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, qword ptr [esi+ 0] + movlps xmm0, qword ptr [edi+ 0] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm0, qword ptr [edi+16] + mulps xmm0, xmm6 + movlps xmm7, qword ptr [esi+ 8] + movlps xmm2, qword ptr [edi+ 8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movhps xmm2, qword ptr [edi+24] + mulps xmm2, xmm7 + movlps xmm1, qword ptr [edi+32] + movhps xmm1, qword ptr [edi+48] + mulps xmm1, xmm6 + movlps xmm3, qword ptr [edi+40] + addps xmm0, xmm2 + movhps xmm3, qword ptr [edi+56] + mulps xmm3, xmm7 + movaps xmm4, xmm0 + addps xmm1, xmm3 + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm4 + movlps xmm1, qword ptr [edi+64] + movhps xmm1, qword ptr [edi+80] + STORE4( 0, xmm0, xmm4 ) + mulps xmm1, xmm6 + movlps xmm2, qword ptr [edi+72] + movhps xmm2, qword ptr [edi+88] + mulps xmm2, xmm7 + addps xmm1, xmm2 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm3, xmm1 + addps xmm1, xmm3 + STORE2LO( 16, xmm1, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; + mPtr += 4; + } + return; + } + } + break; + } + case 5: { + switch( numRows ) { + case 5: { // 5x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X + movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 + movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X + movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 + movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 + shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 + movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 + movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 + movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 + movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 + movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 + movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 + shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 + movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 + movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 + movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X + movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 + shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 + movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 + shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 + movss xmm7, [esi+0*4] + shufps xmm7, xmm7, 0 + mulps xmm0, xmm7 + movss xmm5, [esi+1*4] + shufps xmm5, xmm5, 0 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, 0 + mulps xmm2, xmm6 + addps xmm0, xmm2 + movss xmm1, [esi+3*4] + shufps xmm1, xmm1, 0 + mulps xmm3, xmm1 + addps xmm0, xmm3 + movss xmm2, [esi+4*4] + shufps xmm2, xmm2, 0 + mulps xmm4, xmm2 + addps xmm0, xmm4 + mulss xmm7, [edi+20*4] + mulss xmm5, [edi+21*4] + addps xmm7, xmm5 + mulss xmm6, [edi+22*4] + addps xmm7, xmm6 + mulss xmm1, [edi+23*4] + addps xmm7, xmm1 + mulss xmm2, [edi+24*4] + addps xmm7, xmm2 + STORE4( 0, xmm0, xmm3 ) + STORE1( 16, xmm7, xmm4 ) + } + return; + } + case 6: { // 6x5 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [esi] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm7, [esi+8] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) + movlps xmm0, [edi] + movhps xmm3, [edi+8] + movaps xmm1, [edi+16] + movlps xmm2, [edi+32] + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 + mulps xmm0, xmm6 + mulps xmm3, xmm7 + movlps xmm2, [edi+40] + addps xmm0, xmm3 // xmm0 + xmm1 + movhps xmm5, [edi+40+8] + movlps xmm3, [edi+40+16] + movhps xmm3, [edi+40+24] + movlps xmm4, [edi+40+32] + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 + shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 + shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 + mulps xmm2, xmm6 + mulps xmm5, xmm7 + addps xmm2, xmm5 // xmm2 + xmm3 + movss xmm5, [esi+16] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm0 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) + shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) + addps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + STORE4( 0, xmm0, xmm2 ) + movlps xmm4, [edi+80] + movhps xmm3, [edi+80+8] + movaps xmm1, [edi+80+16] + movlps xmm2, [edi+80+32] + shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 + shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 + mulps xmm4, xmm6 + mulps xmm3, xmm7 + mulps xmm1, xmm5 + addps xmm4, xmm3 // xmm4 + xmm1 + shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) + addps xmm4, xmm1 + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) + addps xmm4, xmm1 + STORE2LO( 16, xmm4, xmm2 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; + mPtr += 5; + } + return; + } + } + break; + } + case 6: { + switch( numRows ) { + case 1: { // 1x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + mulss xmm0, [edi] + movss xmm1, [esi+4] + mulss xmm1, [edi+4] + movss xmm2, [esi+8] + addss xmm0, xmm1 + mulss xmm2, [edi+8] + movss xmm3, [esi+12] + addss xmm0, xmm2 + mulss xmm3, [edi+12] + movss xmm4, [esi+16] + addss xmm0, xmm3 + mulss xmm4, [edi+16] + movss xmm5, [esi+20] + addss xmm0, xmm4 + mulss xmm5, [edi+20] + movss xmm6, [esi+24] + addss xmm0, xmm5 + mulss xmm6, [edi+24] + addss xmm0, xmm6 + STORE1( 0, xmm0, xmm7 ) + } + return; + } + case 2: { // 2x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + } + return; + } + case 3: { // 3x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) + movhlps xmm0, xmm1 + addps xmm0, xmm1 + STORE2LO( 0, xmm0, xmm3 ) + // row 2 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + STORE1( 8, xmm0, xmm3 ) + } + return; + } + case 4: { // 4x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm4 ) + } + return; + } + case 5: { // 5x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + // load idVecX + movlps xmm4, [esi] + movhps xmm4, [esi+8] + movlps xmm5, [esi+16] + movlhps xmm5, xmm4 + movhlps xmm6, xmm4 + movlhps xmm6, xmm5 + // row 0 and 1 + movaps xmm0, [edi] + movaps xmm1, [edi+16] + movaps xmm2, [edi+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm7, xmm0 + movlhps xmm7, xmm2 + addps xmm7, xmm1 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm7, xmm0 + // row 2 and 3 + movaps xmm0, [edi+48] + movaps xmm1, [edi+48+16] + movaps xmm2, [edi+48+32] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + mulps xmm2, xmm6 + movhlps xmm3, xmm0 + movlhps xmm3, xmm2 + addps xmm1, xmm3 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) + addps xmm1, xmm0 + // last 4 additions for the first 4 rows and store result + movaps xmm0, xmm7 + shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) + shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) + addps xmm0, xmm7 + STORE4( 0, xmm0, xmm3 ) + // row 5 + movaps xmm0, [edi+96] + movaps xmm1, [edi+96+16] + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, 0x01 + addss xmm0, xmm1 + STORE1( 16, xmm0, xmm3 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm7, qword ptr [esi] + movlps xmm6, qword ptr [esi+8] + shufps xmm7, xmm7, 0x44 + shufps xmm6, xmm6, 0x44 + movlps xmm0, qword ptr [edi ] + movhps xmm0, qword ptr [edi+ 24] + mulps xmm0, xmm7 + movlps xmm3, qword ptr [edi+ 8] + movhps xmm3, qword ptr [edi+ 32] + mulps xmm3, xmm6 + movlps xmm1, qword ptr [edi+ 48] + movhps xmm1, qword ptr [edi+ 72] + mulps xmm1, xmm7 + movlps xmm2, qword ptr [edi+ 96] + movhps xmm2, qword ptr [edi+120] + mulps xmm2, xmm7 + movlps xmm4, qword ptr [edi+ 56] + movhps xmm4, qword ptr [edi+ 80] + movlps xmm5, qword ptr [edi+104] + movhps xmm5, qword ptr [edi+128] + mulps xmm4, xmm6 + movlps xmm7, qword ptr [esi+16] + addps xmm0, xmm3 + shufps xmm7, xmm7, 0x44 + mulps xmm5, xmm6 + addps xmm1, xmm4 + movlps xmm3, qword ptr [edi+ 16] + movhps xmm3, qword ptr [edi+ 40] + addps xmm2, xmm5 + movlps xmm4, qword ptr [edi+ 64] + movhps xmm4, qword ptr [edi+ 88] + mulps xmm3, xmm7 + movlps xmm5, qword ptr [edi+112] + movhps xmm5, qword ptr [edi+136] + addps xmm0, xmm3 + mulps xmm4, xmm7 + mulps xmm5, xmm7 + addps xmm1, xmm4 + addps xmm2, xmm5 + movaps xmm6, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm6, xmm1, 0xDD + movaps xmm7, xmm2 + shufps xmm7, xmm2, 0x88 + shufps xmm2, xmm2, 0xDD + addps xmm0, xmm6 + addps xmm2, xmm7 + STORE4( 0, xmm0, xmm3 ) + STORE2LO( 16, xmm2, xmm4 ) + } + return; + } + default: { + for ( int i = 0; i < numRows; i++ ) { + dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; + mPtr += 6; + } + return; + } + } + break; + } + default: { + int numColumns = mat.GetNumColumns(); + for ( int i = 0; i < numRows; i++ ) { + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numColumns; j++ ) { + sum += mPtr[j] * vPtr[j]; + } + dstPtr[i] STOREC sum; + mPtr += numColumns; + } + break; + } + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +idSIMD_SSE::MatX_TransposeMultiplyVecX + + optimizes the following matrix multiplications: + + Nx6 * Nx1 + 6xN * 6x1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss [eax+offset], reg1 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps [eax+offset], reg1 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps [eax+offset], reg1 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps [eax+offset], reg1 \ + __asm movhps [eax+offset+8], reg1 +#define STOREC = + + int numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + switch( numColumns ) { + case 6: { // 1x6 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm3 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0]; + mPtr++; + } + return; + } + } + break; + case 2: + switch( numColumns ) { + case 6: { // 2x6 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movaps xmm1, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + movaps xmm2, [edi] + mulps xmm2, xmm0 + movlps xmm3, [edi+24] + movhps xmm3, [edi+32] + mulps xmm3, xmm1 + addps xmm2, xmm3 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm4, [edi+16] + movhps xmm4, [edi+40] + mulps xmm4, xmm0 + movhlps xmm3, xmm4 + addps xmm3, xmm4 + STORE4( 0, xmm2, xmm5 ) + STORE2LO( 16, xmm3, xmm6 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + return; + } + } + break; + case 3: + switch( numColumns ) { + case 6: { // 3x6 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movss xmm1, [esi+2*4] + movlps xmm3, [edi+(0*6+0)*4] + movhps xmm3, [edi+(0*6+2)*4] + movaps xmm4, xmm0 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm1 + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(2*6+4)*4] + mulps xmm5, xmm1 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + return; + } + } + break; + case 4: + switch( numColumns ) { + case 6: { // 4x6 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + return; + } + } + break; + case 5: + switch( numColumns ) { + case 6: { // 5x6 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movss xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm2 + mulps xmm4, [edi+(4*6+0)*4] + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + return; + } + } + break; + case 6: + switch( numColumns ) { + case 1: { // 6x1 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movhps xmm0, [esi+8] + movlps xmm1, [esi+16] + mulps xmm0, [edi] + mulps xmm1, [edi+16] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) + addps xmm0, xmm1 + movhlps xmm2, xmm0 + addss xmm2, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm2, xmm0 + STORE1( 0, xmm2, xmm3 ) + } + return; + } + case 2: { // 6x2 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm6, [edi+0*4] + mulps xmm6, xmm0 + movlps xmm1, [esi+2*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+4*4] + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm2, [esi+4*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+8*4] + mulps xmm7, xmm2 + addps xmm6, xmm7 + movhlps xmm3, xmm6 + addps xmm3, xmm6 + STORE2LO( 0, xmm3, xmm7 ) + } + return; + } + case 3: { // 6x3 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+(0*3+2)*4] + movhps xmm0, [edi+(0*3+0)*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm6, [esi+0*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movss xmm1, [edi+(1*3+0)*4] + movhps xmm1, [edi+(1*3+1)*4] + movss xmm7, [esi+1*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movss xmm2, [edi+(2*3+2)*4] + movhps xmm2, [edi+(2*3+0)*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+2*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movss xmm3, [edi+(3*3+0)*4] + movhps xmm3, [edi+(3*3+1)*4] + movss xmm7, [esi+3*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movss xmm4, [edi+(4*3+2)*4] + movhps xmm4, [edi+(4*3+0)*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+4*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movss xmm5, [edi+(5*3+0)*4] + movhps xmm5, [edi+(5*3+1)*4] + movss xmm7, [esi+5*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE1( 0, xmm6, xmm7 ) + STORE2HI( 4, xmm6, xmm7 ) + } + return; + } + case 4: { // 6x4 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm3, [edi+(0*4+0)*4] + movhps xmm3, [edi+(0*4+2)*4] + movss xmm4, [esi+0*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*4+0)*4] + movhps xmm5, [edi+(1*4+2)*4] + movss xmm6, [esi+1*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*4+0)*4] + movhps xmm4, [edi+(2*4+2)*4] + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*4+0)*4] + movhps xmm5, [edi+(3*4+2)*4] + movss xmm6, [esi+3*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(4*4+0)*4] + movhps xmm4, [edi+(4*4+2)*4] + movss xmm6, [esi+4*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(5*4+0)*4] + movhps xmm5, [edi+(5*4+2)*4] + movss xmm6, [esi+5*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + } + return; + } + case 5: { // 6x5 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [edi+(0*5+0)*4] + movhps xmm6, [edi+(0*5+2)*4] + movss xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movlps xmm7, [edi+(1*5+0)*4] + movhps xmm7, [edi+(1*5+2)*4] + movss xmm1, [esi+1*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm7, [edi+(2*5+0)*4] + movhps xmm7, [edi+(2*5+2)*4] + movss xmm2, [esi+2*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movlps xmm7, [edi+(3*5+0)*4] + movhps xmm7, [edi+(3*5+2)*4] + movss xmm3, [esi+3*4] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movlps xmm7, [edi+(4*5+0)*4] + movhps xmm7, [edi+(4*5+2)*4] + movss xmm4, [esi+4*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movlps xmm7, [edi+(5*5+0)*4] + movhps xmm7, [edi+(5*5+2)*4] + movss xmm5, [esi+5*4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE4( 0, xmm6, xmm7 ) + movss xmm6, [edi+(0*5+4)*4] + mulss xmm6, xmm0 + movss xmm7, [edi+(1*5+4)*4] + mulss xmm7, xmm1 + addss xmm6, xmm7 + movss xmm7, [edi+(2*5+4)*4] + mulss xmm7, xmm2 + addss xmm6, xmm7 + movss xmm7, [edi+(3*5+4)*4] + mulss xmm7, xmm3 + addss xmm6, xmm7 + movss xmm7, [edi+(4*5+4)*4] + mulss xmm7, xmm4 + addss xmm6, xmm7 + movss xmm7, [edi+(5*5+4)*4] + mulss xmm7, xmm5 + addss xmm6, xmm7 + STORE1( 16, xmm6, xmm7 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movlps xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(4*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(5*6+0)*4] + movhps xmm5, [edi+(5*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + movhps xmm5, [edi+(5*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + return; + } + } + break; + default: + int numRows = mat.GetNumRows(); + for ( int i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] STOREC sum; + } + break; + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +idSIMD_SSE::MatX_TransposeMultiplyAddVecX + + optimizes the following matrix multiplications: + + Nx6 * Nx1 + 6xN * 6x1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss reg2, [eax+offset] \ + __asm addss reg2, reg1 \ + __asm movss [eax+offset], reg2 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm addps reg2, reg1 \ + __asm movlps [eax+offset], reg2 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps reg2, [eax+offset] \ + __asm addps reg2, reg1 \ + __asm movhps [eax+offset], reg2 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm movhps reg2, [eax+offset+8] \ + __asm addps reg2, reg1 \ + __asm movlps [eax+offset], reg2 \ + __asm movhps [eax+offset+8], reg2 +#define STOREC += + + int numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + switch( numColumns ) { + case 6: { // 1x6 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm3 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0]; + mPtr++; + } + return; + } + } + break; + case 2: + switch( numColumns ) { + case 6: { // 2x6 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movaps xmm1, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + movaps xmm2, [edi] + mulps xmm2, xmm0 + movlps xmm3, [edi+24] + movhps xmm3, [edi+32] + mulps xmm3, xmm1 + addps xmm2, xmm3 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm4, [edi+16] + movhps xmm4, [edi+40] + mulps xmm4, xmm0 + movhlps xmm3, xmm4 + addps xmm3, xmm4 + STORE4( 0, xmm2, xmm5 ) + STORE2LO( 16, xmm3, xmm6 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + return; + } + } + break; + case 3: + switch( numColumns ) { + case 6: { // 3x6 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movss xmm1, [esi+2*4] + movlps xmm3, [edi+(0*6+0)*4] + movhps xmm3, [edi+(0*6+2)*4] + movaps xmm4, xmm0 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm1 + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(2*6+4)*4] + mulps xmm5, xmm1 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + return; + } + } + break; + case 4: + switch( numColumns ) { + case 6: { // 4x6 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + return; + } + } + break; + case 5: + switch( numColumns ) { + case 6: { // 5x6 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movss xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm2 + mulps xmm4, [edi+(4*6+0)*4] + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + return; + } + } + break; + case 6: + switch( numColumns ) { + case 1: { // 6x1 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movhps xmm0, [esi+8] + movlps xmm1, [esi+16] + mulps xmm0, [edi] + mulps xmm1, [edi+16] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) + addps xmm0, xmm1 + movhlps xmm2, xmm0 + addss xmm2, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm2, xmm0 + STORE1( 0, xmm2, xmm3 ) + } + return; + } + case 2: { // 6x2 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm6, [edi+0*4] + mulps xmm6, xmm0 + movlps xmm1, [esi+2*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+4*4] + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm2, [esi+4*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+8*4] + mulps xmm7, xmm2 + addps xmm6, xmm7 + movhlps xmm3, xmm6 + addps xmm3, xmm6 + STORE2LO( 0, xmm3, xmm7 ) + } + return; + } + case 3: { // 6x3 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+(0*3+2)*4] + movhps xmm0, [edi+(0*3+0)*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm6, [esi+0*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movss xmm1, [edi+(1*3+0)*4] + movhps xmm1, [edi+(1*3+1)*4] + movss xmm7, [esi+1*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movss xmm2, [edi+(2*3+2)*4] + movhps xmm2, [edi+(2*3+0)*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+2*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movss xmm3, [edi+(3*3+0)*4] + movhps xmm3, [edi+(3*3+1)*4] + movss xmm7, [esi+3*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movss xmm4, [edi+(4*3+2)*4] + movhps xmm4, [edi+(4*3+0)*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+4*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movss xmm5, [edi+(5*3+0)*4] + movhps xmm5, [edi+(5*3+1)*4] + movss xmm7, [esi+5*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE1( 0, xmm6, xmm7 ) + STORE2HI( 4, xmm6, xmm7 ) + } + return; + } + case 4: { // 6x4 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm3, [edi+(0*4+0)*4] + movhps xmm3, [edi+(0*4+2)*4] + movss xmm4, [esi+0*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*4+0)*4] + movhps xmm5, [edi+(1*4+2)*4] + movss xmm6, [esi+1*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*4+0)*4] + movhps xmm4, [edi+(2*4+2)*4] + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*4+0)*4] + movhps xmm5, [edi+(3*4+2)*4] + movss xmm6, [esi+3*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(4*4+0)*4] + movhps xmm4, [edi+(4*4+2)*4] + movss xmm6, [esi+4*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(5*4+0)*4] + movhps xmm5, [edi+(5*4+2)*4] + movss xmm6, [esi+5*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + } + return; + } + case 5: { // 6x5 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [edi+(0*5+0)*4] + movhps xmm6, [edi+(0*5+2)*4] + movss xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movlps xmm7, [edi+(1*5+0)*4] + movhps xmm7, [edi+(1*5+2)*4] + movss xmm1, [esi+1*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm7, [edi+(2*5+0)*4] + movhps xmm7, [edi+(2*5+2)*4] + movss xmm2, [esi+2*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movlps xmm7, [edi+(3*5+0)*4] + movhps xmm7, [edi+(3*5+2)*4] + movss xmm3, [esi+3*4] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movlps xmm7, [edi+(4*5+0)*4] + movhps xmm7, [edi+(4*5+2)*4] + movss xmm4, [esi+4*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movlps xmm7, [edi+(5*5+0)*4] + movhps xmm7, [edi+(5*5+2)*4] + movss xmm5, [esi+5*4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE4( 0, xmm6, xmm7 ) + movss xmm6, [edi+(0*5+4)*4] + mulss xmm6, xmm0 + movss xmm7, [edi+(1*5+4)*4] + mulss xmm7, xmm1 + addss xmm6, xmm7 + movss xmm7, [edi+(2*5+4)*4] + mulss xmm7, xmm2 + addss xmm6, xmm7 + movss xmm7, [edi+(3*5+4)*4] + mulss xmm7, xmm3 + addss xmm6, xmm7 + movss xmm7, [edi+(4*5+4)*4] + mulss xmm7, xmm4 + addss xmm6, xmm7 + movss xmm7, [edi+(5*5+4)*4] + mulss xmm7, xmm5 + addss xmm6, xmm7 + STORE1( 16, xmm6, xmm7 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movlps xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(4*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(5*6+0)*4] + movhps xmm5, [edi+(5*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + movhps xmm5, [edi+(5*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + return; + } + } + break; + default: + int numRows = mat.GetNumRows(); + for ( int i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] STOREC sum; + } + break; + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +void idSIMD_SSE::MatX_TransposeMultiplySubVecX + + optimizes the following matrix multiplications: + + Nx6 * Nx1 + 6xN * 6x1 + + with N in the range [1-6] +============ +*/ +void VPCALL idSIMD_SSE::MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { +#define STORE1( offset, reg1, reg2 ) \ + __asm movss reg2, [eax+offset] \ + __asm subss reg2, reg1 \ + __asm movss [eax+offset], reg2 +#define STORE2LO( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm subps reg2, reg1 \ + __asm movlps [eax+offset], reg2 +#define STORE2HI( offset, reg1, reg2 ) \ + __asm movhps reg2, [eax+offset] \ + __asm subps reg2, reg1 \ + __asm movhps [eax+offset], reg2 +#define STORE4( offset, reg1, reg2 ) \ + __asm movlps reg2, [eax+offset] \ + __asm movhps reg2, [eax+offset+8] \ + __asm subps reg2, reg1 \ + __asm movlps [eax+offset], reg2 \ + __asm movhps [eax+offset+8], reg2 +#define STOREC -= + + int numColumns; + const float *mPtr, *vPtr; + float *dstPtr; + + assert( vec.GetSize() >= mat.GetNumRows() ); + assert( dst.GetSize() >= mat.GetNumColumns() ); + + mPtr = mat.ToFloatPtr(); + vPtr = vec.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + numColumns = mat.GetNumColumns(); + switch( mat.GetNumRows() ) { + case 1: + switch( numColumns ) { + case 6: { // 1x6 * 1x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + STORE4( 0, xmm0, xmm2 ) + STORE2LO( 16, xmm1, xmm3 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0]; + mPtr++; + } + return; + } + } + break; + case 2: + switch( numColumns ) { + case 6: { // 2x6 * 2x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movaps xmm1, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + movaps xmm2, [edi] + mulps xmm2, xmm0 + movlps xmm3, [edi+24] + movhps xmm3, [edi+32] + mulps xmm3, xmm1 + addps xmm2, xmm3 + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm4, [edi+16] + movhps xmm4, [edi+40] + mulps xmm4, xmm0 + movhlps xmm3, xmm4 + addps xmm3, xmm4 + STORE4( 0, xmm2, xmm5 ) + STORE2LO( 16, xmm3, xmm6 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; + mPtr++; + } + return; + } + } + break; + case 3: + switch( numColumns ) { + case 6: { // 3x6 * 3x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movss xmm1, [esi+2*4] + movlps xmm3, [edi+(0*6+0)*4] + movhps xmm3, [edi+(0*6+2)*4] + movaps xmm4, xmm0 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm1 + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(2*6+4)*4] + mulps xmm5, xmm1 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; + mPtr++; + } + return; + } + } + break; + case 4: + switch( numColumns ) { + case 6: { // 4x6 * 4x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*6+0)*4] + movhps xmm4, [edi+(2*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3]; + mPtr++; + } + return; + } + } + break; + case 5: + switch( numColumns ) { + case 6: { // 5x6 * 5x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movss xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm4, xmm2 + mulps xmm4, [edi+(4*6+0)*4] + addps xmm3, xmm4 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; + mPtr++; + } + return; + } + } + break; + case 6: + switch( numColumns ) { + case 1: { // 6x1 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi] + movhps xmm0, [esi+8] + movlps xmm1, [esi+16] + mulps xmm0, [edi] + mulps xmm1, [edi+16] + shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) + addps xmm0, xmm1 + movhlps xmm2, xmm0 + addss xmm2, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm2, xmm0 + STORE1( 0, xmm2, xmm3 ) + } + return; + } + case 2: { // 6x2 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm6, [edi+0*4] + mulps xmm6, xmm0 + movlps xmm1, [esi+2*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+4*4] + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm2, [esi+4*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm7, [edi+8*4] + mulps xmm7, xmm2 + addps xmm6, xmm7 + movhlps xmm3, xmm6 + addps xmm3, xmm6 + STORE2LO( 0, xmm3, xmm7 ) + } + return; + } + case 3: { // 6x3 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movss xmm0, [edi+(0*3+2)*4] + movhps xmm0, [edi+(0*3+0)*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm6, [esi+0*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movss xmm1, [edi+(1*3+0)*4] + movhps xmm1, [edi+(1*3+1)*4] + movss xmm7, [esi+1*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movss xmm2, [edi+(2*3+2)*4] + movhps xmm2, [edi+(2*3+0)*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+2*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movss xmm3, [edi+(3*3+0)*4] + movhps xmm3, [edi+(3*3+1)*4] + movss xmm7, [esi+3*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movss xmm4, [edi+(4*3+2)*4] + movhps xmm4, [edi+(4*3+0)*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) + movss xmm7, [esi+4*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movss xmm5, [edi+(5*3+0)*4] + movhps xmm5, [edi+(5*3+1)*4] + movss xmm7, [esi+5*4] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE1( 0, xmm6, xmm7 ) + STORE2HI( 4, xmm6, xmm7 ) + } + return; + } + case 4: { // 6x4 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm3, [edi+(0*4+0)*4] + movhps xmm3, [edi+(0*4+2)*4] + movss xmm4, [esi+0*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm4 + movlps xmm5, [edi+(1*4+0)*4] + movhps xmm5, [edi+(1*4+2)*4] + movss xmm6, [esi+1*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(2*4+0)*4] + movhps xmm4, [edi+(2*4+2)*4] + movss xmm6, [esi+2*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(3*4+0)*4] + movhps xmm5, [edi+(3*4+2)*4] + movss xmm6, [esi+3*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movlps xmm4, [edi+(4*4+0)*4] + movhps xmm4, [edi+(4*4+2)*4] + movss xmm6, [esi+4*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm6 + addps xmm3, xmm4 + movlps xmm5, [edi+(5*4+0)*4] + movhps xmm5, [edi+(5*4+2)*4] + movss xmm6, [esi+5*4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + } + return; + } + case 5: { // 6x5 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm6, [edi+(0*5+0)*4] + movhps xmm6, [edi+(0*5+2)*4] + movss xmm0, [esi+0*4] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movlps xmm7, [edi+(1*5+0)*4] + movhps xmm7, [edi+(1*5+2)*4] + movss xmm1, [esi+1*4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movlps xmm7, [edi+(2*5+0)*4] + movhps xmm7, [edi+(2*5+2)*4] + movss xmm2, [esi+2*4] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + movlps xmm7, [edi+(3*5+0)*4] + movhps xmm7, [edi+(3*5+2)*4] + movss xmm3, [esi+3*4] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm3 + addps xmm6, xmm7 + movlps xmm7, [edi+(4*5+0)*4] + movhps xmm7, [edi+(4*5+2)*4] + movss xmm4, [esi+4*4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movlps xmm7, [edi+(5*5+0)*4] + movhps xmm7, [edi+(5*5+2)*4] + movss xmm5, [esi+5*4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + STORE4( 0, xmm6, xmm7 ) + movss xmm6, [edi+(0*5+4)*4] + mulss xmm6, xmm0 + movss xmm7, [edi+(1*5+4)*4] + mulss xmm7, xmm1 + addss xmm6, xmm7 + movss xmm7, [edi+(2*5+4)*4] + mulss xmm7, xmm2 + addss xmm6, xmm7 + movss xmm7, [edi+(3*5+4)*4] + mulss xmm7, xmm3 + addss xmm6, xmm7 + movss xmm7, [edi+(4*5+4)*4] + mulss xmm7, xmm4 + addss xmm6, xmm7 + movss xmm7, [edi+(5*5+4)*4] + mulss xmm7, xmm5 + addss xmm6, xmm7 + STORE1( 16, xmm6, xmm7 ) + } + return; + } + case 6: { // 6x6 * 6x1 + __asm { + mov esi, vPtr + mov edi, mPtr + mov eax, dstPtr + movlps xmm0, [esi+0*4] + movlps xmm1, [esi+2*4] + movlps xmm2, [esi+4*4] + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, [edi+(0*6+0)*4] + movlps xmm5, [edi+(1*6+0)*4] + movhps xmm5, [edi+(1*6+2)*4] + movaps xmm6, xmm0 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(2*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(3*6+0)*4] + movhps xmm5, [edi+(3*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, [edi+(4*6+0)*4] + addps xmm3, xmm6 + movaps xmm6, xmm2 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + movlps xmm5, [edi+(5*6+0)*4] + movhps xmm5, [edi+(5*6+2)*4] + mulps xmm5, xmm6 + addps xmm3, xmm5 + STORE4( 0, xmm3, xmm7 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + movlps xmm3, [edi+(0*6+4)*4] + movhps xmm3, [edi+(1*6+4)*4] + mulps xmm3, xmm0 + movlps xmm4, [edi+(2*6+4)*4] + movhps xmm4, [edi+(3*6+4)*4] + mulps xmm4, xmm1 + addps xmm3, xmm4 + movlps xmm5, [edi+(4*6+4)*4] + movhps xmm5, [edi+(5*6+4)*4] + mulps xmm5, xmm2 + addps xmm3, xmm5 + movhlps xmm4, xmm3 + addps xmm3, xmm4 + STORE2LO( 16, xmm3, xmm7 ) + } + return; + } + default: { + for ( int i = 0; i < numColumns; i++ ) { + dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + + *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; + mPtr++; + } + return; + } + } + break; + default: + int numRows = mat.GetNumRows(); + for ( int i = 0; i < numColumns; i++ ) { + mPtr = mat.ToFloatPtr() + i; + float sum = mPtr[0] * vPtr[0]; + for ( int j = 1; j < numRows; j++ ) { + mPtr += numColumns; + sum += mPtr[0] * vPtr[j]; + } + dstPtr[i] STOREC sum; + } + break; + } + +#undef STOREC +#undef STORE4 +#undef STORE2HI +#undef STORE2LO +#undef STORE1 +} + +/* +============ +idSIMD_SSE::MatX_MultiplyMatX + + optimizes the following matrix multiplications: + + NxN * Nx6 + 6xN * Nx6 + Nx6 * 6xN + 6x6 * 6xN + + with N in the range [1-6]. + + The hot cache clock cycle counts are generally better for the SIMD version than the + FPU version. At times up to 40% less clock cycles on a P3. In practise however, + the results are poor probably due to memory access. +============ +*/ +void VPCALL idSIMD_SSE::MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( m1.GetNumColumns() == m2.GetNumRows() ); + + dstPtr = dst.ToFloatPtr(); + m1Ptr = m1.ToFloatPtr(); + m2Ptr = m2.ToFloatPtr(); + k = m1.GetNumRows(); + l = m2.GetNumColumns(); + n = m1.GetNumColumns(); + + switch( n ) { + case 1: { + if ( !(l^6) ) { + switch( k ) { + case 1: { // 1x1 * 1x6, no precision loss compared to FPU version + __asm { + mov esi, m2Ptr + mov edi, m1Ptr + mov eax, dstPtr + movss xmm0, [edi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, [esi] + mulps xmm1, xmm0 + movaps [eax], xmm1 + movlps xmm2, [esi+16] + mulps xmm2, xmm0 + movlps [eax+16], xmm2 + } + return; + } + case 6: { // 6x1 * 1x6, no precision loss compared to FPU version + __asm { + mov esi, m2Ptr + mov edi, m1Ptr + mov eax, dstPtr + xorps xmm1, xmm1 + movaps xmm0, [edi] + movlps xmm1, [edi+16] + movlhps xmm1, xmm0 + movhlps xmm2, xmm0 + movlhps xmm2, xmm1 + // row 0 and 1 + movaps xmm3, [esi] + movaps xmm4, xmm3 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm5, xmm3 + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) + movaps xmm6, xmm3 + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + movaps [eax], xmm4 + movaps [eax+16], xmm5 + movaps [eax+32], xmm6 + // row 2 and 3 + movaps xmm4, xmm3 + shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 2, 2 ) + movaps xmm5, xmm3 + shufps xmm5, xmm5, R_SHUFFLEPS( 2, 2, 3, 3 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm3, xmm2 + movaps [eax+48], xmm4 + movaps [eax+64], xmm5 + movaps [eax+80], xmm3 + // row 4 and 5 + movlps xmm3, [esi+16] + movaps xmm4, xmm3 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm5, xmm3 + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm3, xmm2 + movaps [eax+96], xmm4 + movaps [eax+112], xmm5 + movaps [eax+128], xmm3 + } + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0]; + m2Ptr++; + } + m1Ptr++; + } + break; + } + case 2: { + if ( !(l^6) ) { + switch( k ) { + case 2: { // 2x2 * 2x6 + + #define MUL_Nx2_2x6_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movaps xmm0, [esi] \ + __asm movlps xmm1, [esi+16] \ + __asm movhps xmm1, [esi+40] \ + __asm movlps xmm2, [esi+24] \ + __asm movhps xmm2, [esi+32] + + #define MUL_Nx2_2x6_ROW2( row ) \ + __asm movaps xmm3, [edi+row*16] \ + __asm movaps xmm5, xmm0 \ + __asm movaps xmm4, xmm3 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm4 \ + __asm movaps xmm4, xmm3 \ + __asm movaps xmm6, xmm2 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 1, 1, 1, 1 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm5, xmm6 \ + __asm movaps [eax+row*48], xmm5 \ + __asm movaps xmm4, xmm3 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm movaps xmm7, xmm1 \ + __asm mulps xmm7, xmm4 \ + __asm movaps xmm4, xmm3 \ + __asm movaps xmm5, xmm0 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 2, 2 ) \ + __asm mulps xmm5, xmm4 \ + __asm movaps xmm4, xmm3 \ + __asm movaps xmm6, xmm2 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 3, 3, 3, 3 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm5, xmm6 \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 2, 2, 3, 3 ) \ + __asm movaps xmm6, xmm1 \ + __asm mulps xmm6, xmm3 \ + __asm movaps xmm4, xmm7 \ + __asm movlhps xmm7, xmm6 \ + __asm movhlps xmm6, xmm4 \ + __asm addps xmm6, xmm7 \ + __asm movlps [eax+row*48+16], xmm6 \ + __asm movlps [eax+row*48+24], xmm5 \ + __asm movhps [eax+row*48+32], xmm5 \ + __asm movhps [eax+row*48+40], xmm6 + + MUL_Nx2_2x6_INIT + MUL_Nx2_2x6_ROW2( 0 ) + + return; + } + case 6: { // 6x2 * 2x6 + + MUL_Nx2_2x6_INIT + MUL_Nx2_2x6_ROW2( 0 ) + MUL_Nx2_2x6_ROW2( 1 ) + MUL_Nx2_2x6_ROW2( 2 ) + + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l]; + m2Ptr++; + } + m1Ptr += 2; + } + break; + } + case 3: { + if ( !(l^6) ) { + switch( k ) { + case 3: { // 3x3 * 3x6 + __asm { + mov esi, m2Ptr + mov edi, m1Ptr + mov eax, dstPtr + movaps xmm5, xmmword ptr [esi] + movlps xmm6, qword ptr [esi+24] + movhps xmm6, qword ptr [esi+32] + movaps xmm7, xmmword ptr [esi+48] + movss xmm0, dword ptr [edi] + shufps xmm0, xmm0, 0 + mulps xmm0, xmm5 + movss xmm1, dword ptr [edi+4] + shufps xmm1, xmm1, 0 + mulps xmm1, xmm6 + movss xmm2, dword ptr [edi+8] + shufps xmm2, xmm2, 0 + mulps xmm2, xmm7 + addps xmm0, xmm1 + addps xmm0, xmm2 + movaps xmmword ptr [eax], xmm0 + movss xmm3, dword ptr [edi+12] + shufps xmm3, xmm3, 0 + mulps xmm3, xmm5 + movss xmm4, dword ptr [edi+16] + shufps xmm4, xmm4, 0 + mulps xmm4, xmm6 + movss xmm0, dword ptr [edi+20] + shufps xmm0, xmm0, 0 + mulps xmm0, xmm7 + addps xmm3, xmm4 + addps xmm0, xmm3 + movlps qword ptr [eax+24], xmm0 + movhps qword ptr [eax+32], xmm0 + movss xmm1, dword ptr [edi+24] + shufps xmm1, xmm1, 0 + mulps xmm1, xmm5 + movss xmm2, dword ptr [edi+28] + shufps xmm2, xmm2, 0 + mulps xmm2, xmm6 + movss xmm3, dword ptr [edi+32] + shufps xmm3, xmm3, 0 + mulps xmm3, xmm7 + addps xmm1, xmm2 + addps xmm1, xmm3 + movaps xmmword ptr [eax+48], xmm1 + movlps xmm5, qword ptr [esi+16] + movlps xmm6, qword ptr [esi+40] + movlps xmm7, qword ptr [esi+64] + shufps xmm5, xmm5, 0x44 + shufps xmm6, xmm6, 0x44 + shufps xmm7, xmm7, 0x44 + movaps xmm3, xmmword ptr [edi] + movlps xmm4, qword ptr [edi+16] + movaps xmm0, xmm3 + shufps xmm0, xmm0, 0xF0 + mulps xmm0, xmm5 + movaps xmm1, xmm3 + shufps xmm1, xmm4, 0x05 + mulps xmm1, xmm6 + shufps xmm3, xmm4, 0x5A + mulps xmm3, xmm7 + addps xmm1, xmm0 + addps xmm1, xmm3 + movlps qword ptr [eax+16], xmm1 + movhps qword ptr [eax+40], xmm1 + movss xmm0, dword ptr [edi+24] + shufps xmm0, xmm0, 0 + mulps xmm0, xmm5 + movss xmm2, dword ptr [edi+28] + shufps xmm2, xmm2, 0 + mulps xmm2, xmm6 + movss xmm4, dword ptr [edi+32] + shufps xmm4, xmm4, 0 + mulps xmm4, xmm7 + addps xmm0, xmm2 + addps xmm0, xmm4 + movlps qword ptr [eax+64], xmm0 + } + return; + } + case 6: { // 6x3 * 3x6 + #define MUL_Nx3_3x6_FIRST4COLUMNS_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 2*4] \ + __asm movlps xmm1, [esi+ 6*4] \ + __asm movhps xmm1, [esi+ 8*4] \ + __asm movlps xmm2, [esi+12*4] \ + __asm movhps xmm2, [esi+14*4] + + #define MUL_Nx3_3x6_FIRST4COLUMNS_ROW( row ) \ + __asm movss xmm3, [edi+(row*3+0)*4] \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm3, xmm0 \ + __asm movss xmm4, [edi+(row*3+1)*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm4, xmm1 \ + __asm addps xmm3, xmm4 \ + __asm movss xmm5, [edi+(row*3+2)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm5 \ + __asm movlps [eax+(row*6+0)*4], xmm3 \ + __asm movhps [eax+(row*6+2)*4], xmm3 + + #define MUL_Nx3_3x6_LAST2COLUMNS_ROW6 \ + __asm movlps xmm0, [esi+ 4*4] \ + __asm movlps xmm1, [esi+10*4] \ + __asm movlps xmm2, [esi+16*4] \ + __asm shufps xmm0, xmm0, 0x44 \ + __asm shufps xmm1, xmm1, 0x44 \ + __asm shufps xmm2, xmm2, 0x44 \ + __asm movlps xmm3, [edi+0*4] \ + __asm movhps xmm3, [edi+2*4] \ + __asm movaps xmm4, xmm3 \ + __asm movaps xmm5, xmm3 \ + __asm shufps xmm3, xmm3, 0xF0 \ + __asm mulps xmm3, xmm0 \ + __asm movlps xmm6, [edi+4*4] \ + __asm movhps xmm6, [edi+6*4] \ + __asm shufps xmm4, xmm6, 0x05 \ + __asm mulps xmm4, xmm1 \ + __asm addps xmm3, xmm4 \ + __asm shufps xmm5, xmm6, 0x5A \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm5 \ + __asm movlps [eax+4*4], xmm3 \ + __asm movhps [eax+10*4], xmm3 \ + __asm movaps xmm5, xmm6 \ + __asm movlps xmm3, [edi+8*4] \ + __asm movhps xmm3, [edi+10*4] \ + __asm movaps xmm4, xmm3 \ + __asm shufps xmm5, xmm3, 0x5A \ + __asm mulps xmm5, xmm0 \ + __asm shufps xmm6, xmm3, 0xAF \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm5, xmm6 \ + __asm shufps xmm4, xmm4, 0xF0 \ + __asm mulps xmm4, xmm2 \ + __asm addps xmm4, xmm5 \ + __asm movlps [eax+16*4], xmm4 \ + __asm movhps [eax+22*4], xmm4 \ + __asm movlps xmm6, [edi+12*4] \ + __asm movhps xmm6, [edi+14*4] \ + __asm movaps xmm5, xmm6 \ + __asm movaps xmm4, xmm6 \ + __asm shufps xmm6, xmm6, 0xF0 \ + __asm mulps xmm6, xmm0 \ + __asm movlps xmm3, [edi+16*4] \ + __asm shufps xmm5, xmm3, 0x05 \ + __asm mulps xmm5, xmm1 \ + __asm addps xmm5, xmm6 \ + __asm shufps xmm4, xmm3, 0x5A \ + __asm mulps xmm4, xmm2 \ + __asm addps xmm4, xmm5 \ + __asm movlps [eax+28*4], xmm4 \ + __asm movhps [eax+34*4], xmm4 + + MUL_Nx3_3x6_FIRST4COLUMNS_INIT + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 0 ) + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 1 ) + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 2 ) + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 3 ) + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 4 ) + MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 5 ) + MUL_Nx3_3x6_LAST2COLUMNS_ROW6 + + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l]; + m2Ptr++; + } + m1Ptr += 3; + } + break; + } + case 4: { + if ( !(l^6) ) { + switch( k ) { + case 4: { // 4x4 * 4x6 + + #define MUL_Nx4_4x6_FIRST4COLUMNS_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 2*4] \ + __asm movlps xmm1, [esi+ 6*4] \ + __asm movhps xmm1, [esi+ 8*4] \ + __asm movlps xmm2, [esi+12*4] \ + __asm movhps xmm2, [esi+14*4] \ + __asm movlps xmm3, [esi+18*4] \ + __asm movhps xmm3, [esi+20*4] + + #define MUL_Nx4_4x6_FIRST4COLUMNS_ROW( row ) \ + __asm movss xmm4, [edi+row*16+0*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm4, xmm0 \ + __asm movss xmm5, [edi+row*16+1*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm1 \ + __asm addps xmm4, xmm5 \ + __asm movss xmm6, [edi+row*16+2*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm4, xmm6 \ + __asm movss xmm7, [edi+row*16+3*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm3 \ + __asm addps xmm4, xmm7 \ + __asm movlps [eax+row*24+0], xmm4 \ + __asm movhps [eax+row*24+8], xmm4 + + #define MUL_Nx4_4x6_LAST2COLUMNS_INIT \ + __asm movlps xmm0, [esi+ 4*4] \ + __asm movlps xmm1, [esi+10*4] \ + __asm movlps xmm2, [esi+16*4] \ + __asm movlps xmm3, [esi+22*4] \ + __asm shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + + #define MUL_Nx4_4x6_LAST2COLUMNS_ROW2( row ) \ + __asm movlps xmm7, [edi+row*32+ 0*4] \ + __asm movhps xmm7, [edi+row*32+ 4*4] \ + __asm movaps xmm6, xmm7 \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 3, 3 ) \ + __asm mulps xmm6, xmm0 \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 1, 1, 2, 2 ) \ + __asm mulps xmm7, xmm1 \ + __asm addps xmm6, xmm7 \ + __asm movlps xmm4, [edi+row*32+ 2*4] \ + __asm movhps xmm4, [edi+row*32+ 6*4] \ + __asm movaps xmm5, xmm4 \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 3, 3 ) \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm6, xmm5 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 1, 1, 2, 2 ) \ + __asm mulps xmm4, xmm3 \ + __asm addps xmm6, xmm4 \ + __asm movlps [eax+row*48+ 4*4], xmm6 \ + __asm movhps [eax+row*48+10*4], xmm6 + + MUL_Nx4_4x6_FIRST4COLUMNS_INIT + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 0 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 1 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 2 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 3 ) + MUL_Nx4_4x6_LAST2COLUMNS_INIT + MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 0 ) + MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 1 ) + + return; + } + case 6: { // 6x4 * 4x6 + + MUL_Nx4_4x6_FIRST4COLUMNS_INIT + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 0 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 1 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 2 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 3 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 4 ) + MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 5 ) + MUL_Nx4_4x6_LAST2COLUMNS_INIT + MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 0 ) + MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 1 ) + MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 2 ) + + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l]; + m2Ptr++; + } + m1Ptr += 4; + } + break; + } + case 5: { + if ( !(l^6) ) { + switch( k ) { + case 5: { // 5x5 * 5x6 + + #define MUL_Nx5_5x6_FIRST4COLUMNS_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 2*4] \ + __asm movlps xmm1, [esi+ 6*4] \ + __asm movhps xmm1, [esi+ 8*4] \ + __asm movlps xmm2, [esi+12*4] \ + __asm movhps xmm2, [esi+14*4] \ + __asm movlps xmm3, [esi+18*4] \ + __asm movhps xmm3, [esi+20*4] \ + __asm movlps xmm4, [esi+24*4] \ + __asm movhps xmm4, [esi+26*4] + + #define MUL_Nx5_5x6_FIRST4COLUMNS_ROW( row ) \ + __asm movss xmm6, [edi+row*20+0*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm0 \ + __asm movss xmm5, [edi+row*20+1*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm1 \ + __asm addps xmm6, xmm5 \ + __asm movss xmm5, [edi+row*20+2*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm6, xmm5 \ + __asm movss xmm5, [edi+row*20+3*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm3 \ + __asm addps xmm6, xmm5 \ + __asm movss xmm5, [edi+row*20+4*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm4 \ + __asm addps xmm6, xmm5 \ + __asm movlps [eax+row*24+0], xmm6 \ + __asm movhps [eax+row*24+8], xmm6 + + #define MUL_Nx5_5x6_LAST2COLUMNS_INIT \ + __asm movlps xmm0, [esi+ 4*4] \ + __asm movlps xmm1, [esi+10*4] \ + __asm movlps xmm2, [esi+16*4] \ + __asm movlps xmm3, [esi+22*4] \ + __asm movlps xmm4, [esi+28*4] \ + __asm shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm1, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm3, xmm4, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm4, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) + + #define MUL_Nx5_5x6_LAST2COLUMNS_ROW2( row ) \ + __asm movlps xmm7, [edi+row*40+ 0*4] \ + __asm movhps xmm7, [edi+row*40+ 6*4] \ + __asm movaps xmm6, xmm7 \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 2, 2 ) \ + __asm mulps xmm6, xmm0 \ + __asm movaps xmm5, xmm7 \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 3, 3 ) \ + __asm mulps xmm5, xmm1 \ + __asm addps xmm6, xmm5 \ + __asm movlps xmm7, [edi+row*40+ 2*4] \ + __asm movhps xmm7, [edi+row*40+ 8*4] \ + __asm movaps xmm5, xmm7 \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 2, 2 ) \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm6, xmm5 \ + __asm movaps xmm5, xmm7 \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 3, 3 ) \ + __asm mulps xmm5, xmm3 \ + __asm addps xmm6, xmm5 \ + __asm movlps xmm5, [edi+row*40+ 4*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm5, xmm4 \ + __asm addps xmm6, xmm5 \ + __asm movlps [eax+row*48+ 4*4], xmm6 \ + __asm movhps [eax+row*48+10*4], xmm6 + + #define MUL_Nx5_5x6_LAST2COLUMNS_ROW( row ) \ + __asm movlps xmm6, [edi+20*4+0*4] \ + __asm unpcklps xmm6, xmm6 \ + __asm mulps xmm6, xmm0 \ + __asm movlps xmm5, [edi+20*4+2*4] \ + __asm unpcklps xmm5, xmm5 \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm6, xmm5 \ + __asm movss xmm5, [edi+20*4+4*4] \ + __asm unpcklps xmm5, xmm5 \ + __asm mulps xmm5, xmm4 \ + __asm addps xmm6, xmm5 \ + __asm movhlps xmm7, xmm6 \ + __asm addps xmm6, xmm7 \ + __asm movlps [eax+row*24+4*4], xmm6 + + MUL_Nx5_5x6_FIRST4COLUMNS_INIT + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 0 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 1 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 2 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 3 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 4 ) + MUL_Nx5_5x6_LAST2COLUMNS_INIT + MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 0 ) + MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 1 ) + MUL_Nx5_5x6_LAST2COLUMNS_ROW( 4 ) + + return; + } + case 6: { // 6x5 * 5x6 + + MUL_Nx5_5x6_FIRST4COLUMNS_INIT + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 0 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 1 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 2 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 3 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 4 ) + MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 5 ) + MUL_Nx5_5x6_LAST2COLUMNS_INIT + MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 0 ) + MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 1 ) + MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 2 ) + + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l]; + m2Ptr++; + } + m1Ptr += 5; + } + break; + } + case 6: { + switch( k ) { + case 1: { + if ( !(l^1) ) { // 1x6 * 6x1 + dstPtr[0] = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[1] + m1Ptr[2] * m2Ptr[2] + + m1Ptr[3] * m2Ptr[3] + m1Ptr[4] * m2Ptr[4] + m1Ptr[5] * m2Ptr[5]; + return; + } + break; + } + case 2: { + if ( !(l^2) ) { // 2x6 * 6x2 + + #define MUL_Nx6_6x2_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movaps xmm0, [esi] \ + __asm movaps xmm1, [esi+16] \ + __asm movaps xmm2, [esi+32] + + #define MUL_Nx6_6x2_ROW2( row ) \ + __asm movaps xmm7, [edi+row*48+0*4] \ + __asm movaps xmm6, xmm7 \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm7, xmm0 \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 2, 2, 3, 3 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movaps xmm6, [edi+row*48+4*4] \ + __asm movaps xmm5, xmm6 \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 2, 2, 3, 3 ) \ + __asm mulps xmm5, xmm0 \ + __asm movaps xmm6, [edi+row*48+24+2*4] \ + __asm movaps xmm4, xmm6 \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm5, xmm6 \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 3, 3 ) \ + __asm mulps xmm4, xmm2 \ + __asm addps xmm5, xmm4 \ + __asm movaps xmm4, xmm5 \ + __asm movhlps xmm5, xmm7 \ + __asm movlhps xmm7, xmm4 \ + __asm addps xmm7, xmm5 \ + __asm movaps [eax+row*16], xmm7 + + MUL_Nx6_6x2_INIT + MUL_Nx6_6x2_ROW2( 0 ) + + return; + } + break; + } + case 3: { + if ( !(l^3) ) { // 3x6 * 6x3 + + #define MUL_Nx6_6x3_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movss xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 1*4] \ + __asm movss xmm1, [esi+ 3*4] \ + __asm movhps xmm1, [esi+ 4*4] \ + __asm movss xmm2, [esi+ 6*4] \ + __asm movhps xmm2, [esi+ 7*4] \ + __asm movss xmm3, [esi+ 9*4] \ + __asm movhps xmm3, [esi+10*4] \ + __asm movss xmm4, [esi+12*4] \ + __asm movhps xmm4, [esi+13*4] \ + __asm movss xmm5, [esi+15*4] \ + __asm movhps xmm5, [esi+16*4] + + #define MUL_Nx6_6x3_ROW( row ) \ + __asm movss xmm7, [edi+row*24+0] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm movss xmm6, [edi+row*24+4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+8] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+12] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+16] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+20] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm movss [eax+row*12+0], xmm7 \ + __asm movhps [eax+row*12+4], xmm7 + + MUL_Nx6_6x3_INIT + MUL_Nx6_6x3_ROW( 0 ) + MUL_Nx6_6x3_ROW( 1 ) + MUL_Nx6_6x3_ROW( 2 ) + + return; + } + break; + } + case 4: { + if ( !(l^4) ) { // 4x6 * 6x4 + + #define MUL_Nx6_6x4_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movaps xmm0, [esi] \ + __asm movaps xmm1, [esi+16] \ + __asm movaps xmm2, [esi+32] \ + __asm movaps xmm3, [esi+48] \ + __asm movaps xmm4, [esi+64] \ + __asm movaps xmm5, [esi+80] + + #define MUL_Nx6_6x4_ROW( row ) \ + __asm movss xmm7, [edi+row*24+0] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm movss xmm6, [edi+row*24+4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+8] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+12] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+16] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+row*24+20] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm movaps [eax+row*16], xmm7 + + MUL_Nx6_6x4_INIT + MUL_Nx6_6x4_ROW( 0 ) + MUL_Nx6_6x4_ROW( 1 ) + MUL_Nx6_6x4_ROW( 2 ) + MUL_Nx6_6x4_ROW( 3 ) + + return; + } + break; + } + case 5: { + if ( !(l^5) ) { // 5x6 * 6x5 + + #define MUL_Nx6_6x5_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movaps xmm0, [esi] \ + __asm movlps xmm1, [esi+20] \ + __asm movhps xmm1, [esi+28] \ + __asm movlps xmm2, [esi+40] \ + __asm movhps xmm2, [esi+48] \ + __asm movlps xmm3, [esi+60] \ + __asm movhps xmm3, [esi+68] \ + __asm movaps xmm4, [esi+80] \ + __asm movlps xmm5, [esi+100] \ + __asm movhps xmm5, [esi+108] + + #define MUL_Nx6_6x5_ROW( row ) \ + __asm movss xmm7, [edi+row*24+0] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm fld dword ptr [edi+(row*6+0)*4] \ + __asm fmul dword ptr [esi+(4+0*5)*4] \ + __asm movss xmm6, [edi+row*24+4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm fld dword ptr [edi+(row*6+1)*4] \ + __asm fmul dword ptr [esi+(4+1*5)*4] \ + __asm faddp st(1),st \ + __asm movss xmm6, [edi+row*24+8] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm fld dword ptr [edi+(row*6+2)*4] \ + __asm fmul dword ptr [esi+(4+2*5)*4] \ + __asm faddp st(1),st \ + __asm movss xmm6, [edi+row*24+12] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm fld dword ptr [edi+(row*6+3)*4] \ + __asm fmul dword ptr [esi+(4+3*5)*4] \ + __asm faddp st(1),st \ + __asm movss xmm6, [edi+row*24+16] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm fld dword ptr [edi+(row*6+4)*4] \ + __asm fmul dword ptr [esi+(4+4*5)*4] \ + __asm faddp st(1),st \ + __asm movss xmm6, [edi+row*24+20] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm fld dword ptr [edi+(row*6+5)*4] \ + __asm fmul dword ptr [esi+(4+5*5)*4] \ + __asm faddp st(1),st \ + __asm fstp dword ptr [eax+(row*5+4)*4] \ + __asm movlps [eax+row*20], xmm7 \ + __asm movhps [eax+row*20+8], xmm7 + + MUL_Nx6_6x5_INIT + MUL_Nx6_6x5_ROW( 0 ) + MUL_Nx6_6x5_ROW( 1 ) + MUL_Nx6_6x5_ROW( 2 ) + MUL_Nx6_6x5_ROW( 3 ) + MUL_Nx6_6x5_ROW( 4 ) + + return; + } + break; + } + case 6: { + switch( l ) { + case 1: { // 6x6 * 6x1 + __asm { + mov esi, m2Ptr + mov edi, m1Ptr + mov eax, dstPtr + movlps xmm7, qword ptr [esi] + movlps xmm6, qword ptr [esi+8] + shufps xmm7, xmm7, 0x44 + shufps xmm6, xmm6, 0x44 + movlps xmm0, qword ptr [edi ] + movhps xmm0, qword ptr [edi+ 24] + mulps xmm0, xmm7 + movlps xmm3, qword ptr [edi+ 8] + movhps xmm3, qword ptr [edi+ 32] + mulps xmm3, xmm6 + movlps xmm1, qword ptr [edi+ 48] + movhps xmm1, qword ptr [edi+ 72] + mulps xmm1, xmm7 + movlps xmm2, qword ptr [edi+ 96] + movhps xmm2, qword ptr [edi+120] + mulps xmm2, xmm7 + movlps xmm4, qword ptr [edi+ 56] + movhps xmm4, qword ptr [edi+ 80] + movlps xmm5, qword ptr [edi+104] + movhps xmm5, qword ptr [edi+128] + mulps xmm4, xmm6 + movlps xmm7, qword ptr [esi+16] + addps xmm0, xmm3 + shufps xmm7, xmm7, 0x44 + mulps xmm5, xmm6 + addps xmm1, xmm4 + movlps xmm3, qword ptr [edi+ 16] + movhps xmm3, qword ptr [edi+ 40] + addps xmm2, xmm5 + movlps xmm4, qword ptr [edi+ 64] + movhps xmm4, qword ptr [edi+ 88] + mulps xmm3, xmm7 + movlps xmm5, qword ptr [edi+112] + movhps xmm5, qword ptr [edi+136] + addps xmm0, xmm3 + mulps xmm4, xmm7 + mulps xmm5, xmm7 + addps xmm1, xmm4 + addps xmm2, xmm5 + movaps xmm6, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm6, xmm1, 0xDD + movaps xmm7, xmm2 + shufps xmm7, xmm2, 0x88 + shufps xmm2, xmm2, 0xDD + addps xmm0, xmm6 + addps xmm2, xmm7 + movlps [eax], xmm0 + movhps [eax+8], xmm0 + movlps [eax+16], xmm2 + } + return; + } + case 2: { // 6x6 * 6x2 + + MUL_Nx6_6x2_INIT + MUL_Nx6_6x2_ROW2( 0 ) + MUL_Nx6_6x2_ROW2( 1 ) + MUL_Nx6_6x2_ROW2( 2 ) + + return; + } + case 3: { // 6x6 * 6x3 + + MUL_Nx6_6x3_INIT + MUL_Nx6_6x3_ROW( 0 ) + MUL_Nx6_6x3_ROW( 1 ) + MUL_Nx6_6x3_ROW( 2 ) + MUL_Nx6_6x3_ROW( 3 ) + MUL_Nx6_6x3_ROW( 4 ) + MUL_Nx6_6x3_ROW( 5 ) + + return; + } + case 4: { // 6x6 * 6x4 + + MUL_Nx6_6x4_INIT + MUL_Nx6_6x4_ROW( 0 ) + MUL_Nx6_6x4_ROW( 1 ) + MUL_Nx6_6x4_ROW( 2 ) + MUL_Nx6_6x4_ROW( 3 ) + MUL_Nx6_6x4_ROW( 4 ) + MUL_Nx6_6x4_ROW( 5 ) + + return; + } + case 5: { // 6x6 * 6x5 + + MUL_Nx6_6x5_INIT + MUL_Nx6_6x5_ROW( 0 ) + MUL_Nx6_6x5_ROW( 1 ) + MUL_Nx6_6x5_ROW( 2 ) + MUL_Nx6_6x5_ROW( 3 ) + MUL_Nx6_6x5_ROW( 4 ) + MUL_Nx6_6x5_ROW( 5 ) + + return; + } + case 6: { // 6x6 * 6x6 + __asm { + mov ecx, dword ptr m2Ptr + movlps xmm3, qword ptr [ecx+72] + mov edx, dword ptr m1Ptr + // Loading first 4 columns (upper 4 rows) of m2Ptr. + movaps xmm0, xmmword ptr [ecx] + movlps xmm1, qword ptr [ecx+24] + movhps xmm1, qword ptr [ecx+32] + movaps xmm2, xmmword ptr [ecx+48] + movhps xmm3, qword ptr [ecx+80] + // Calculating first 4 elements in the first row of the destination matrix. + movss xmm4, dword ptr [edx] + movss xmm5, dword ptr [edx+4] + mov eax, dword ptr dstPtr + shufps xmm4, xmm4, 0 + movss xmm6, dword ptr [edx+8] + shufps xmm5, xmm5, 0 + movss xmm7, dword ptr [edx+12] + mulps xmm4, xmm0 + shufps xmm6, xmm6, 0 + shufps xmm7, xmm7, 0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + addps xmm5, xmm4 + mulps xmm7, xmm3 + addps xmm6, xmm5 + addps xmm7, xmm6 + movaps xmmword ptr [eax], xmm7 + // Calculating first 4 elements in the second row of the destination matrix. + movss xmm4, dword ptr [edx+24] + shufps xmm4, xmm4, 0 + mulps xmm4, xmm0 + movss xmm5, dword ptr [edx+28] + shufps xmm5, xmm5, 0 + mulps xmm5, xmm1 + movss xmm6, dword ptr [edx+32] + shufps xmm6, xmm6, 0 + movss xmm7, dword ptr [edx+36] + shufps xmm7, xmm7, 0 + mulps xmm6, xmm2 + mulps xmm7, xmm3 + addps xmm7, xmm6 + addps xmm5, xmm4 + addps xmm7, xmm5 + // Calculating first 4 elements in the third row of the destination matrix. + movss xmm4, dword ptr [edx+48] + movss xmm5, dword ptr [edx+52] + movlps qword ptr [eax+24], xmm7 ; save 2nd + movhps qword ptr [eax+32], xmm7 ; row + movss xmm6, dword ptr [edx+56] + movss xmm7, dword ptr [edx+60] + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + shufps xmm6, xmm6, 0 + shufps xmm7, xmm7, 0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + mulps xmm7, xmm3 + addps xmm5, xmm4 + addps xmm7, xmm6 + addps xmm7, xmm5 + movaps xmmword ptr [eax+48], xmm7 + // Calculating first 4 elements in the fourth row of the destination matrix. + movss xmm4, dword ptr [edx+72] + movss xmm5, dword ptr [edx+76] + movss xmm6, dword ptr [edx+80] + movss xmm7, dword ptr [edx+84] + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + shufps xmm6, xmm6, 0 + shufps xmm7, xmm7, 0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + mulps xmm7, xmm3 + addps xmm4, xmm5 + addps xmm6, xmm4 + addps xmm7, xmm6 + movlps qword ptr [eax+72], xmm7 + movhps qword ptr [eax+80], xmm7 + // Calculating first 4 elements in the fifth row of the destination matrix. + movss xmm4, dword ptr [edx+96] + movss xmm5, dword ptr [edx+100] + movss xmm6, dword ptr [edx+104] + movss xmm7, dword ptr [edx+108] + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + shufps xmm6, xmm6, 0 + shufps xmm7, xmm7, 0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + mulps xmm7, xmm3 + addps xmm5, xmm4 + addps xmm7, xmm6 + addps xmm7, xmm5 + movaps xmmword ptr [eax+96], xmm7 + // Calculating first 4 elements in the sixth row of the destination matrix. + movss xmm4, dword ptr [edx+120] + movss xmm5, dword ptr [edx+124] + movss xmm6, dword ptr [edx+128] + movss xmm7, dword ptr [edx+132] + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + shufps xmm6, xmm6, 0 + shufps xmm7, xmm7, 0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm6, xmm2 + mulps xmm7, xmm3 + addps xmm4, xmm5 + addps xmm6, xmm4 + addps xmm7, xmm6 + movhps qword ptr [eax+128], xmm7 + movlps qword ptr [eax+120], xmm7 + // Loading first 4 columns (lower 2 rows) of m2Ptr. + movlps xmm0, qword ptr [ecx+96] + movhps xmm0, qword ptr [ecx+104] + movlps xmm1, qword ptr [ecx+120] + movhps xmm1, qword ptr [ecx+128] + // Calculating first 4 elements in the first row of the destination matrix. + movss xmm2, dword ptr [edx+16] + shufps xmm2, xmm2, 0 + movss xmm4, dword ptr [edx+40] + movss xmm3, dword ptr [edx+20] + movss xmm5, dword ptr [edx+44] + movaps xmm6, xmmword ptr [eax] + movlps xmm7, qword ptr [eax+24] + shufps xmm3, xmm3, 0 + shufps xmm5, xmm5, 0 + movhps xmm7, qword ptr [eax+32] + shufps xmm4, xmm4, 0 + mulps xmm5, xmm1 + mulps xmm2, xmm0 + mulps xmm3, xmm1 + mulps xmm4, xmm0 + addps xmm6, xmm2 + addps xmm7, xmm4 + addps xmm7, xmm5 + addps xmm6, xmm3 + movlps qword ptr [eax+24], xmm7 + movaps xmmword ptr [eax], xmm6 + movhps qword ptr [eax+32], xmm7 + // Calculating first 4 elements in the third row of the destination matrix. + movss xmm2, dword ptr [edx+64] + movss xmm4, dword ptr [edx+88] + movss xmm5, dword ptr [edx+92] + movss xmm3, dword ptr [edx+68] + movaps xmm6, xmmword ptr [eax+48] + movlps xmm7, qword ptr [eax+72] + movhps xmm7, qword ptr [eax+80] + shufps xmm2, xmm2, 0 + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + shufps xmm3, xmm3, 0 + mulps xmm2, xmm0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + mulps xmm3, xmm1 + addps xmm6, xmm2 + addps xmm6, xmm3 + addps xmm7, xmm4 + addps xmm7, xmm5 + movlps qword ptr [eax+72], xmm7 + movaps xmmword ptr [eax+48], xmm6 + movhps qword ptr [eax+80], xmm7 + // Calculating first 4 elements in the fifth row of the destination matrix. + movss xmm2, dword ptr [edx+112] + movss xmm3, dword ptr [edx+116] + movaps xmm6, xmmword ptr [eax+96] + shufps xmm2, xmm2, 0 + shufps xmm3, xmm3, 0 + mulps xmm2, xmm0 + mulps xmm3, xmm1 + addps xmm6, xmm2 + addps xmm6, xmm3 + movaps xmmword ptr [eax+96], xmm6 + // Calculating first 4 elements in the sixth row of the destination matrix. + movss xmm4, dword ptr [edx+136] + movss xmm5, dword ptr [edx+140] + movhps xmm7, qword ptr [eax+128] + movlps xmm7, qword ptr [eax+120] + shufps xmm4, xmm4, 0 + shufps xmm5, xmm5, 0 + mulps xmm4, xmm0 + mulps xmm5, xmm1 + addps xmm7, xmm4 + addps xmm7, xmm5 + // Calculating last 2 columns of the destination matrix. + movlps xmm0, qword ptr [ecx+16] + movhps xmm0, qword ptr [ecx+40] + movhps qword ptr [eax+128], xmm7 + movlps qword ptr [eax+120], xmm7 + movlps xmm2, qword ptr [ecx+64] + movhps xmm2, qword ptr [ecx+88] + movaps xmm3, xmm2 + shufps xmm3, xmm3, 4Eh + movlps xmm4, qword ptr [ecx+112] + movhps xmm4, qword ptr [ecx+136] + movaps xmm5, xmm4 + shufps xmm5, xmm5, 4Eh + movlps xmm6, qword ptr [edx] + movhps xmm6, qword ptr [edx+24] + movaps xmm7, xmm6 + shufps xmm7, xmm7, 0F0h + mulps xmm7, xmm0 + shufps xmm6, xmm6, 0A5h + movaps xmm1, xmm0 + shufps xmm1, xmm1, 4Eh + mulps xmm1, xmm6 + addps xmm7, xmm1 + movlps xmm6, qword ptr [edx+8] + movhps xmm6, qword ptr [edx+32] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm2 + mulps xmm6, xmm3 + addps xmm7, xmm1 + addps xmm7, xmm6 + movhps xmm6, qword ptr [edx+40] + movlps xmm6, qword ptr [edx+16] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm4 + mulps xmm6, xmm5 + addps xmm7, xmm1 + addps xmm7, xmm6 + movlps qword ptr [eax+16], xmm7 + movhps qword ptr [eax+40], xmm7 + movlps xmm6, qword ptr [edx+48] + movhps xmm6, qword ptr [edx+72] + movaps xmm7, xmm6 + shufps xmm7, xmm7, 0F0h + mulps xmm7, xmm0 + shufps xmm6, xmm6, 0A5h + movaps xmm1, xmm0 + shufps xmm1, xmm1, 4Eh + mulps xmm1, xmm6 + addps xmm7, xmm1 + movhps xmm6, qword ptr [edx+80] + movlps xmm6, qword ptr [edx+56] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm2 + mulps xmm6, xmm3 + addps xmm7, xmm1 + addps xmm7, xmm6 + movlps xmm6, qword ptr [edx+64] + movhps xmm6, qword ptr [edx+88] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm4 + mulps xmm6, xmm5 + addps xmm7, xmm1 + addps xmm7, xmm6 + movlps qword ptr [eax+64], xmm7 + movhps qword ptr [eax+88], xmm7 + movlps xmm6, qword ptr [edx+96] + movhps xmm6, qword ptr [edx+120] + movaps xmm7, xmm6 + shufps xmm7, xmm7, 0F0h + mulps xmm7, xmm0 + shufps xmm6, xmm6, 0A5h + movaps xmm1, xmm0 + shufps xmm1, xmm1, 4Eh + mulps xmm1, xmm6 + addps xmm7, xmm1 + movlps xmm6, qword ptr [edx+104] + movhps xmm6, qword ptr [edx+128] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm2 + mulps xmm6, xmm3 + addps xmm7, xmm1 + addps xmm7, xmm6 + movlps xmm6, qword ptr [edx+112] + movhps xmm6, qword ptr [edx+136] + movaps xmm1, xmm6 + shufps xmm1, xmm1, 0F0h + shufps xmm6, xmm6, 0A5h + mulps xmm1, xmm4 + mulps xmm6, xmm5 + addps xmm7, xmm1 + addps xmm7, xmm6 + movlps qword ptr [eax+112], xmm7 + movhps qword ptr [eax+136], xmm7 + } + return; + } + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + + m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l] + m1Ptr[5] * m2Ptr[5*l]; + m2Ptr++; + } + m1Ptr += 6; + } + break; + } + default: { + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m2Ptr = m2.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < m1.GetNumColumns(); n++ ) { + m2Ptr += l; + sum += m1Ptr[n] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + m1Ptr += m1.GetNumColumns(); + } + break; + } + } +} + +/* +============ +idSIMD_SSE::MatX_TransposeMultiplyMatX + + optimizes the following transpose matrix multiplications: + + Nx6 * NxN + 6xN * 6x6 + + with N in the range [1-6]. +============ +*/ +void VPCALL idSIMD_SSE::MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { + int i, j, k, l, n; + float *dstPtr; + const float *m1Ptr, *m2Ptr; + double sum; + + assert( m1.GetNumRows() == m2.GetNumRows() ); + + m1Ptr = m1.ToFloatPtr(); + m2Ptr = m2.ToFloatPtr(); + dstPtr = dst.ToFloatPtr(); + k = m1.GetNumColumns(); + l = m2.GetNumColumns(); + + switch( m1.GetNumRows() ) { + case 1: + if ( !((k^6)|(l^1)) ) { // 1x6 * 1x1 + __asm { + mov esi, m2Ptr + mov edi, m1Ptr + mov eax, dstPtr + movss xmm0, [esi] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm1, xmm0 + mulps xmm0, [edi] + mulps xmm1, [edi+16] + movaps [eax], xmm0 + movlps [eax+16], xmm1 + } + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 2: + if ( !((k^6)|(l^2)) ) { // 2x6 * 2x2 + #define MUL_2xN_2x2_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi] \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm movlps xmm1, [esi+8] \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) + + #define MUL_2xN_2x2_ROW2( N, row ) \ + __asm movlps xmm6, [edi+(row+0*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm movlps xmm7, [edi+(row+1*N)*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm0 \ + __asm mulps xmm7, xmm1 \ + __asm addps xmm6, xmm7 \ + __asm movaps [eax+(row*2)*4], xmm6 + + MUL_2xN_2x2_INIT + MUL_2xN_2x2_ROW2( 6, 0 ) + MUL_2xN_2x2_ROW2( 6, 2 ) + MUL_2xN_2x2_ROW2( 6, 4 ) + + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 3: + if ( !((k^6)|(l^3)) ) { // 3x6 * 3x3 + + #define MUL_3xN_3x3_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movss xmm0, [esi+(0*3+0)*4] \ + __asm movhps xmm0, [esi+(0*3+1)*4] \ + __asm movss xmm1, [esi+(1*3+0)*4] \ + __asm movhps xmm1, [esi+(1*3+1)*4] \ + __asm movss xmm2, [esi+(2*3+0)*4] \ + __asm movhps xmm2, [esi+(2*3+1)*4] + + #define MUL_3xN_3x3_INIT_ROW4 \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 3, 0 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 0 ) \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 0, 2, 3, 0 ) + + #define MUL_3xN_3x3_ROW4( N, row ) \ + __asm movlps xmm3, [edi+(row+0*N+0)*4] \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 1 ) \ + __asm movlps xmm4, [edi+(row+1*N+0)*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 1 ) \ + __asm movlps xmm5, [edi+(row+2*N+0)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 1 ) \ + __asm mulps xmm3, xmm0 \ + __asm mulps xmm4, xmm1 \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm4 \ + __asm addps xmm3, xmm5 \ + __asm movaps [eax+(row*3+0)*4], xmm3 \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm movlps xmm3, [edi+(row+0*N+1)*4] \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm movlps xmm4, [edi+(row+1*N+1)*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm movlps xmm5, [edi+(row+2*N+1)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm3, xmm0 \ + __asm mulps xmm4, xmm1 \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm4 \ + __asm addps xmm3, xmm5 \ + __asm movaps [eax+(row*3+4)*4], xmm3 \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 1 ) \ + __asm movlps xmm3, [edi+(row+0*N+2)*4] \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 1, 1, 1 ) \ + __asm movlps xmm4, [edi+(row+1*N+2)*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 1, 1, 1 ) \ + __asm movlps xmm5, [edi+(row+2*N+2)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 1, 1 ) \ + __asm mulps xmm3, xmm0 \ + __asm mulps xmm4, xmm1 \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm4 \ + __asm addps xmm3, xmm5 \ + __asm movaps [eax+(row*3+8)*4], xmm3 + + #define MUL_3xN_3x3_INIT_ROW4_ROW4 \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + #define MUL_3xN_3x3_INIT_ROW4_ROW \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 1, 2, 3 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 2, 3 ) \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 1, 2, 3 ) + + #define MUL_3xN_3x3_ROW( N, row ) \ + __asm movss xmm3, [edi+(row+0*N)*4] \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm movss xmm4, [edi+(row+1*N)*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm movss xmm5, [edi+(row+2*N)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm3, xmm0 \ + __asm mulps xmm4, xmm1 \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm3, xmm4 \ + __asm addps xmm3, xmm5 \ + __asm movss [eax+(row*3+0)*4], xmm3 \ + __asm movhps [eax+(row*3+1)*4], xmm3 + + MUL_3xN_3x3_INIT + MUL_3xN_3x3_INIT_ROW4 + MUL_3xN_3x3_ROW4( 6, 0 ) + MUL_3xN_3x3_INIT_ROW4_ROW + MUL_3xN_3x3_ROW( 6, 4 ) + MUL_3xN_3x3_ROW( 6, 5 ) + + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 4: + if ( !((k^6)|(l^4)) ) { // 4x6 * 4x4 + + #define MUL_4xN_4x4_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movaps xmm0, [esi] \ + __asm movaps xmm1, [esi+16] \ + __asm movaps xmm2, [esi+32] \ + __asm movaps xmm3, [esi+48] + + #define MUL_4xN_4x4_ROW( N, row ) \ + __asm movss xmm7, [edi+(row+0*N)*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm movss xmm6, [edi+(row+1*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+2*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+3*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movaps [eax+row*16], xmm7 + + MUL_4xN_4x4_INIT + MUL_4xN_4x4_ROW( 6, 0 ) + MUL_4xN_4x4_ROW( 6, 1 ) + MUL_4xN_4x4_ROW( 6, 2 ) + MUL_4xN_4x4_ROW( 6, 3 ) + MUL_4xN_4x4_ROW( 6, 4 ) + MUL_4xN_4x4_ROW( 6, 5 ) + + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 5: + if ( !((k^6)|(l^5)) ) { // 5x6 * 5x5 + + #define MUL_5xN_5x5_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 2*4] \ + __asm movlps xmm1, [esi+ 5*4] \ + __asm movhps xmm1, [esi+ 7*4] \ + __asm movlps xmm2, [esi+10*4] \ + __asm movhps xmm2, [esi+12*4] \ + __asm movlps xmm3, [esi+15*4] \ + __asm movhps xmm3, [esi+17*4] \ + __asm movlps xmm4, [esi+20*4] \ + __asm movhps xmm4, [esi+22*4] + + #define MUL_5xN_5x5_ROW( N, row ) \ + __asm movss xmm6, [edi+(row+0*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm0 \ + __asm fld dword ptr [edi+(row+0*N)*4] \ + __asm fmul dword ptr [esi+ 4*4] \ + __asm movss xmm5, [edi+(row+1*N)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm1 \ + __asm addps xmm6, xmm5 \ + __asm fld dword ptr [edi+(row+1*N)*4] \ + __asm fmul dword ptr [esi+ 9*4] \ + __asm faddp st(1),st \ + __asm movss xmm5, [edi+(row+2*N)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm2 \ + __asm addps xmm6, xmm5 \ + __asm fld dword ptr [edi+(row+2*N)*4] \ + __asm fmul dword ptr [esi+14*4] \ + __asm faddp st(1),st \ + __asm movss xmm5, [edi+(row+3*N)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm3 \ + __asm addps xmm6, xmm5 \ + __asm fld dword ptr [edi+(row+3*N)*4] \ + __asm fmul dword ptr [esi+19*4] \ + __asm faddp st(1),st \ + __asm movss xmm5, [edi+(row+4*N)*4] \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm5, xmm4 \ + __asm addps xmm6, xmm5 \ + __asm fld dword ptr [edi+(row+4*N)*4] \ + __asm fmul dword ptr [esi+24*4] \ + __asm faddp st(1),st \ + __asm fstp dword ptr [eax+(row*5+4)*4] \ + __asm movlps [eax+(row*5+0)*4], xmm6 \ + __asm movhps [eax+(row*5+2)*4], xmm6 + + MUL_5xN_5x5_INIT + MUL_5xN_5x5_ROW( 6, 0 ) + MUL_5xN_5x5_ROW( 6, 1 ) + MUL_5xN_5x5_ROW( 6, 2 ) + MUL_5xN_5x5_ROW( 6, 3 ) + MUL_5xN_5x5_ROW( 6, 4 ) + MUL_5xN_5x5_ROW( 6, 5 ) + + return; + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + case 6: + if ( !(l^6) ) { + switch( k ) { + case 1: { // 6x1 * 6x6 + #define MUL_6xN_6x6_FIRST4COLUMNS_INIT \ + __asm mov esi, m2Ptr \ + __asm mov edi, m1Ptr \ + __asm mov eax, dstPtr \ + __asm movlps xmm0, [esi+ 0*4] \ + __asm movhps xmm0, [esi+ 2*4] \ + __asm movlps xmm1, [esi+ 6*4] \ + __asm movhps xmm1, [esi+ 8*4] \ + __asm movlps xmm2, [esi+12*4] \ + __asm movhps xmm2, [esi+14*4] \ + __asm movlps xmm3, [esi+18*4] \ + __asm movhps xmm3, [esi+20*4] \ + __asm movlps xmm4, [esi+24*4] \ + __asm movhps xmm4, [esi+26*4] \ + __asm movlps xmm5, [esi+30*4] \ + __asm movhps xmm5, [esi+32*4] + + #define MUL_6xN_6x6_FIRST4COLUMNS_ROW( N, row ) \ + __asm movss xmm7, [edi+(row+0*N)*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm movss xmm6, [edi+(row+1*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+2*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+3*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+4*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(row+5*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm movlps [eax+(row*6+0)*4], xmm7 \ + __asm movhps [eax+(row*6+2)*4], xmm7 + + #define MUL_6xN_6x6_LAST2COLUMNS_INIT \ + __asm movlps xmm0, [esi+ 4*4] \ + __asm movlps xmm1, [esi+10*4] \ + __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm movlps xmm2, [esi+16*4] \ + __asm movlps xmm3, [esi+22*4] \ + __asm shufps xmm2, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm movlps xmm4, [esi+28*4] \ + __asm movlps xmm5, [esi+34*4] \ + __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 1, 0, 1 ) \ + __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 0, 1 ) + + #define MUL_6xN_6x6_LAST2COLUMNS_ROW2( N, row ) \ + __asm movlps xmm7, [edi+(row*2+0*N)*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm7, xmm0 \ + __asm movlps xmm6, [edi+(row*2+1*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movlps xmm6, [edi+(row*2+2*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movlps xmm6, [edi+(row*2+3*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movlps xmm6, [edi+(row*2+4*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm movlps xmm6, [edi+(row*2+5*N)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm movlps [eax+(row*12+ 4)*4], xmm7 \ + __asm movhps [eax+(row*12+10)*4], xmm7 + + #define MUL_6xN_6x6_LAST2COLUMNS_ROW( N, row ) \ + __asm movss xmm7, [edi+(1*N-1)*4] \ + __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm7, xmm0 \ + __asm movss xmm6, [edi+(2*N-1)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm1 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(3*N-1)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm2 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(4*N-1)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm3 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(5*N-1)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm4 \ + __asm addps xmm7, xmm6 \ + __asm movss xmm6, [edi+(6*N-1)*4] \ + __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ + __asm mulps xmm6, xmm5 \ + __asm addps xmm7, xmm6 \ + __asm movlps [eax+(row*6+4)*4], xmm7 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 1, 0 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW( 1, 0 ) + + return; + } + case 2: { // 6x2 * 6x6 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 2, 0 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 2, 1 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 2, 0 ) + + return; + } + case 3: { // 6x3 * 6x6 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 0 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 1 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 2 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 3, 0 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW( 3, 2 ) + + return; + } + case 4: { // 6x4 * 6x6 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 0 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 1 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 2 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 3 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 4, 0 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 4, 1 ) + + return; + } + case 5: { // 6x5 * 6x6 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 0 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 1 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 2 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 3 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 4 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 5, 0 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 5, 1 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW( 5, 4 ) + + return; + } + case 6: { // 6x6 * 6x6 + + MUL_6xN_6x6_FIRST4COLUMNS_INIT + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 0 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 1 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 2 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 3 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 4 ) + MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 5 ) + MUL_6xN_6x6_LAST2COLUMNS_INIT + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 0 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 1 ) + MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 2 ) + + return; + } + } + } + for ( i = 0; i < k; i++ ) { + m2Ptr = m2.ToFloatPtr(); + for ( j = 0; j < l; j++ ) { + *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + + m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l] + m1Ptr[5*k] * m2Ptr[5*l]; + m2Ptr++; + } + m1Ptr++; + } + break; + default: + for ( i = 0; i < k; i++ ) { + for ( j = 0; j < l; j++ ) { + m1Ptr = m1.ToFloatPtr() + i; + m2Ptr = m2.ToFloatPtr() + j; + sum = m1Ptr[0] * m2Ptr[0]; + for ( n = 1; n < m1.GetNumRows(); n++ ) { + m1Ptr += k; + m2Ptr += l; + sum += m1Ptr[0] * m2Ptr[0]; + } + *dstPtr++ = sum; + } + } + break; + } +} + +/* +============ +idSIMD_SSE::MatX_LowerTriangularSolve + + solves x in Lx = b for the n * n sub-matrix of L + if skip > 0 the first skip elements of x are assumed to be valid already + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_SSE::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { + int nc; + const float *lptr; + + if ( skip >= n ) { + return; + } + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + #define NSKIP( n, s ) ((n<<3)|(s&7)) + switch( NSKIP( n, skip ) ) { + case NSKIP( 1, 0 ): x[0] = b[0]; + return; + case NSKIP( 2, 0 ): x[0] = b[0]; + case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + return; + case NSKIP( 3, 0 ): x[0] = b[0]; + case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + return; + case NSKIP( 4, 0 ): x[0] = b[0]; + case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + return; + case NSKIP( 5, 0 ): x[0] = b[0]; + case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + return; + case NSKIP( 6, 0 ): x[0] = b[0]; + case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + return; + case NSKIP( 7, 0 ): x[0] = b[0]; + case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; + return; + } + return; + } + + // process first 4 rows + switch( skip ) { + case 0: x[0] = b[0]; + case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; + case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + skip = 4; + } + + lptr = L[skip]; + + // this code assumes n > 4 + __asm { + push ebx + mov eax, skip // eax = i + shl eax, 2 // eax = i*4 + mov edx, n // edx = n + shl edx, 2 // edx = n*4 + mov esi, x // esi = x + mov edi, lptr // edi = lptr + add esi, eax + add edi, eax + mov ebx, b // ebx = b + + // check for aligned memory + mov ecx, nc + shl ecx, 2 + or ecx, esi + or ecx, edi + and ecx, 15 + jnz loopurow + + // aligned + looprow: + mov ecx, eax + neg ecx + movaps xmm0, [esi+ecx] + mulps xmm0, [edi+ecx] + add ecx, 12*4 + jg donedot8 + dot8: + movaps xmm1, [esi+ecx-(8*4)] + mulps xmm1, [edi+ecx-(8*4)] + addps xmm0, xmm1 + movaps xmm3, [esi+ecx-(4*4)] + mulps xmm3, [edi+ecx-(4*4)] + addps xmm0, xmm3 + add ecx, 8*4 + jle dot8 + donedot8: + sub ecx, 4*4 + jg donedot4 + //dot4: + movaps xmm1, [esi+ecx-(4*4)] + mulps xmm1, [edi+ecx-(4*4)] + addps xmm0, xmm1 + add ecx, 4*4 + donedot4: + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + sub ecx, 4*4 + jz dot0 + add ecx, 4 + jz dot1 + add ecx, 4 + jz dot2 + //dot3: + movss xmm1, [esi-(3*4)] + mulss xmm1, [edi-(3*4)] + addss xmm0, xmm1 + dot2: + movss xmm3, [esi-(2*4)] + mulss xmm3, [edi-(2*4)] + addss xmm0, xmm3 + dot1: + movss xmm5, [esi-(1*4)] + mulss xmm5, [edi-(1*4)] + addss xmm0, xmm5 + dot0: + movss xmm1, [ebx+eax] + subss xmm1, xmm0 + movss [esi], xmm1 + add eax, 4 + cmp eax, edx + jge done + add esi, 4 + mov ecx, nc + shl ecx, 2 + add edi, ecx + add edi, 4 + jmp looprow + + // unaligned + loopurow: + mov ecx, eax + neg ecx + movups xmm0, [esi+ecx] + movups xmm1, [edi+ecx] + mulps xmm0, xmm1 + add ecx, 12*4 + jg doneudot8 + udot8: + movups xmm1, [esi+ecx-(8*4)] + movups xmm2, [edi+ecx-(8*4)] + mulps xmm1, xmm2 + addps xmm0, xmm1 + movups xmm3, [esi+ecx-(4*4)] + movups xmm4, [edi+ecx-(4*4)] + mulps xmm3, xmm4 + addps xmm0, xmm3 + add ecx, 8*4 + jle udot8 + doneudot8: + sub ecx, 4*4 + jg doneudot4 + //udot4: + movups xmm1, [esi+ecx-(4*4)] + movups xmm2, [edi+ecx-(4*4)] + mulps xmm1, xmm2 + addps xmm0, xmm1 + add ecx, 4*4 + doneudot4: + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm1 + sub ecx, 4*4 + jz udot0 + add ecx, 4 + jz udot1 + add ecx, 4 + jz udot2 + //udot3: + movss xmm1, [esi-(3*4)] + movss xmm2, [edi-(3*4)] + mulss xmm1, xmm2 + addss xmm0, xmm1 + udot2: + movss xmm3, [esi-(2*4)] + movss xmm4, [edi-(2*4)] + mulss xmm3, xmm4 + addss xmm0, xmm3 + udot1: + movss xmm5, [esi-(1*4)] + movss xmm6, [edi-(1*4)] + mulss xmm5, xmm6 + addss xmm0, xmm5 + udot0: + movss xmm1, [ebx+eax] + subss xmm1, xmm0 + movss [esi], xmm1 + add eax, 4 + cmp eax, edx + jge done + add esi, 4 + mov ecx, nc + shl ecx, 2 + add edi, ecx + add edi, 4 + jmp loopurow + done: + pop ebx + } +} + +/* +============ +idSIMD_SSE::MatX_LowerTriangularSolveTranspose + + solves x in L'x = b for the n * n sub-matrix of L + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_SSE::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { + int nc; + const float *lptr; + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + switch( n ) { + case 0: + return; + case 1: + x[0] = b[0]; + return; + case 2: + x[1] = b[1]; + x[0] = b[0] - lptr[1*nc+0] * x[1]; + return; + case 3: + x[2] = b[2]; + x[1] = b[1] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 4: + x[3] = b[3]; + x[2] = b[2] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 5: + x[4] = b[4]; + x[3] = b[3] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 6: + x[5] = b[5]; + x[4] = b[4] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 7: + x[6] = b[6]; + x[5] = b[5] - lptr[6*nc+5] * x[6]; + x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + } + return; + } + +#if 1 + + int i, j, m; + float *xptr; + double s0; + + // if the number of columns is not a multiple of 2 we're screwed for alignment. + // however, if the number of columns is a multiple of 2 but the number of to be + // processed rows is not a multiple of 2 we can still run 8 byte aligned + m = n; + if ( m & 1 ) { + + m--; + x[m] = b[m]; + + lptr = L.ToFloatPtr() + m * nc + m - 4; + xptr = x + m; + __asm { + push ebx + mov eax, m // eax = i + mov esi, xptr // esi = xptr + mov edi, lptr // edi = lptr + mov ebx, b // ebx = b + mov edx, nc // edx = nc*sizeof(float) + shl edx, 2 + process4rows_1: + movlps xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] + movhps xmm0, [ebx+eax*4-8] // load b[i-4], b[i-3] + xor ecx, ecx + sub eax, m + neg eax + jz done4x4_1 + process4x4_1: // process 4x4 blocks + movlps xmm2, [edi+0] + movhps xmm2, [edi+8] + add edi, edx + movss xmm1, [esi+4*ecx+0] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm3, [edi+0] + movhps xmm3, [edi+8] + add edi, edx + mulps xmm1, xmm2 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm4, [edi+0] + movhps xmm4, [edi+8] + add edi, edx + mulps xmm1, xmm3 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+8] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm5, [edi+0] + movhps xmm5, [edi+8] + add edi, edx + mulps xmm1, xmm4 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+12] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + add ecx, 4 + cmp ecx, eax + mulps xmm1, xmm5 + subps xmm0, xmm1 + jl process4x4_1 + done4x4_1: // process left over of the 4 rows + movlps xmm2, [edi+0] + movhps xmm2, [edi+8] + movss xmm1, [esi+4*ecx] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm1, xmm2 + subps xmm0, xmm1 + imul ecx, edx + sub edi, ecx + neg eax + + add eax, m + sub eax, 4 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + movaps xmm2, xmm0 + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 2, 2, 2 ) + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) + sub edi, edx + movss [esi-4], xmm3 // xptr[-1] = s3 + movss xmm4, xmm3 + movss xmm5, xmm3 + mulss xmm3, [edi+8] // lptr[-1*nc+2] * s3 + mulss xmm4, [edi+4] // lptr[-1*nc+1] * s3 + mulss xmm5, [edi+0] // lptr[-1*nc+0] * s3 + subss xmm2, xmm3 + movss [esi-8], xmm2 // xptr[-2] = s2 + movss xmm6, xmm2 + sub edi, edx + subss xmm0, xmm5 + subss xmm1, xmm4 + mulss xmm2, [edi+4] // lptr[-2*nc+1] * s2 + mulss xmm6, [edi+0] // lptr[-2*nc+0] * s2 + subss xmm1, xmm2 + movss [esi-12], xmm1 // xptr[-3] = s1 + subss xmm0, xmm6 + sub edi, edx + cmp eax, 4 + mulss xmm1, [edi+0] // lptr[-3*nc+0] * s1 + subss xmm0, xmm1 + movss [esi-16], xmm0 // xptr[-4] = s0 + jl done4rows_1 + sub edi, edx + sub edi, 16 + sub esi, 16 + jmp process4rows_1 + done4rows_1: + pop ebx + } + + } else { + + lptr = L.ToFloatPtr() + m * nc + m - 4; + xptr = x + m; + __asm { + push ebx + mov eax, m // eax = i + mov esi, xptr // esi = xptr + mov edi, lptr // edi = lptr + mov ebx, b // ebx = b + mov edx, nc // edx = nc*sizeof(float) + shl edx, 2 + process4rows: + movlps xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] + movhps xmm0, [ebx+eax*4-8] // load b[i-4], b[i-3] + sub eax, m + jz done4x4 + neg eax + xor ecx, ecx + process4x4: // process 4x4 blocks + movlps xmm2, [edi+0] + movhps xmm2, [edi+8] + add edi, edx + movss xmm1, [esi+4*ecx+0] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm3, [edi+0] + movhps xmm3, [edi+8] + add edi, edx + mulps xmm1, xmm2 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm4, [edi+0] + movhps xmm4, [edi+8] + add edi, edx + mulps xmm1, xmm3 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+8] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps xmm5, [edi+0] + movhps xmm5, [edi+8] + add edi, edx + mulps xmm1, xmm4 + subps xmm0, xmm1 + movss xmm1, [esi+4*ecx+12] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + add ecx, 4 + cmp ecx, eax + mulps xmm1, xmm5 + subps xmm0, xmm1 + jl process4x4 + imul ecx, edx + sub edi, ecx + neg eax + done4x4: // process left over of the 4 rows + add eax, m + sub eax, 4 + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + movaps xmm2, xmm0 + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 2, 2, 2 ) + movaps xmm3, xmm0 + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) + sub edi, edx + movss [esi-4], xmm3 // xptr[-1] = s3 + movss xmm4, xmm3 + movss xmm5, xmm3 + mulss xmm3, [edi+8] // lptr[-1*nc+2] * s3 + mulss xmm4, [edi+4] // lptr[-1*nc+1] * s3 + mulss xmm5, [edi+0] // lptr[-1*nc+0] * s3 + subss xmm2, xmm3 + movss [esi-8], xmm2 // xptr[-2] = s2 + movss xmm6, xmm2 + sub edi, edx + subss xmm0, xmm5 + subss xmm1, xmm4 + mulss xmm2, [edi+4] // lptr[-2*nc+1] * s2 + mulss xmm6, [edi+0] // lptr[-2*nc+0] * s2 + subss xmm1, xmm2 + movss [esi-12], xmm1 // xptr[-3] = s1 + subss xmm0, xmm6 + sub edi, edx + cmp eax, 4 + mulss xmm1, [edi+0] // lptr[-3*nc+0] * s1 + subss xmm0, xmm1 + movss [esi-16], xmm0 // xptr[-4] = s0 + jl done4rows + sub edi, edx + sub edi, 16 + sub esi, 16 + jmp process4rows + done4rows: + pop ebx + } + } + + // process left over rows + for ( i = (m&3)-1; i >= 0; i-- ) { + s0 = b[i]; + lptr = L[0] + i; + for ( j = i + 1; j < n; j++ ) { + s0 -= lptr[j*nc] * x[j]; + } + x[i] = s0; + } + +#else + + int i, j, m; + double s0, s1, s2, s3, t; + const float *lptr2; + float *xptr, *xptr2; + + m = n; + if ( m & 1 ) { + + m--; + x[m] = b[m]; + + lptr = L.ToFloatPtr() + m * nc + m - 4; + xptr = x + m; + // process 4 rows at a time + for ( i = m; i >= 4; i -= 4 ) { + s0 = b[i-4]; + s1 = b[i-3]; + s2 = b[i-2]; + s3 = b[i-1]; + // process 4x4 blocks + xptr2 = xptr; // x + i; + lptr2 = lptr; // ptr = L[i] + i - 4; + for ( j = 0; j < m-i; j += 4 ) { + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + } + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + // process left over of the 4 rows + lptr -= nc; + s0 -= lptr[0] * s3; + s1 -= lptr[1] * s3; + s2 -= lptr[2] * s3; + lptr -= nc; + s0 -= lptr[0] * s2; + s1 -= lptr[1] * s2; + lptr -= nc; + s0 -= lptr[0] * s1; + lptr -= nc; + // store result + xptr[-4] = s0; + xptr[-3] = s1; + xptr[-2] = s2; + xptr[-1] = s3; + // update pointers for next four rows + lptr -= 4; + xptr -= 4; + } + + } else { + + lptr = L.ToFloatPtr() + m * nc + m - 4; + xptr = x + m; + // process 4 rows at a time + for ( i = m; i >= 4; i -= 4 ) { + s0 = b[i-4]; + s1 = b[i-3]; + s2 = b[i-2]; + s3 = b[i-1]; + // process 4x4 blocks + xptr2 = xptr; // x + i; + lptr2 = lptr; // ptr = L[i] + i - 4; + for ( j = 0; j < m-i; j += 4 ) { + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + t = xptr2[0]; + s0 -= lptr2[0] * t; + s1 -= lptr2[1] * t; + s2 -= lptr2[2] * t; + s3 -= lptr2[3] * t; + lptr2 += nc; + xptr2++; + } + // process left over of the 4 rows + lptr -= nc; + s0 -= lptr[0] * s3; + s1 -= lptr[1] * s3; + s2 -= lptr[2] * s3; + lptr -= nc; + s0 -= lptr[0] * s2; + s1 -= lptr[1] * s2; + lptr -= nc; + s0 -= lptr[0] * s1; + lptr -= nc; + // store result + xptr[-4] = s0; + xptr[-3] = s1; + xptr[-2] = s2; + xptr[-1] = s3; + // update pointers for next four rows + lptr -= 4; + xptr -= 4; + } + } + // process left over rows + for ( i--; i >= 0; i-- ) { + s0 = b[i]; + lptr = L[0] + i; + for ( j = i + 1; j < m; j++ ) { + s0 -= lptr[j*nc] * x[j]; + } + x[i] = s0; + } + +#endif +} + +/* +============ +idSIMD_SSE::MatX_LDLTFactor + + in-place factorization LDL' of the n * n sub-matrix of mat + the reciprocal of the diagonal elements are stored in invDiag + currently assumes the number of columns of mat is a multiple of 4 +============ +*/ +bool VPCALL idSIMD_SSE::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { +#if 1 + + int j, nc; + float *v, *diag, *invDiagPtr, *mptr; + double s0, s1, s2, sum, d; + + v = (float *) _alloca16( n * sizeof( float ) ); + diag = (float *) _alloca16( n * sizeof( float ) ); + invDiagPtr = invDiag.ToFloatPtr(); + + nc = mat.GetNumColumns(); + + assert( ( nc & 3 ) == 0 ); + + if ( n <= 0 ) { + return true; + } + + mptr = mat[0]; + + sum = mptr[0]; + + if ( sum == 0.0f ) { + return false; + } + + diag[0] = sum; + invDiagPtr[0] = d = 1.0f / sum; + + if ( n <= 1 ) { + return true; + } + + mptr = mat[0]; + for ( j = 1; j < n; j++ ) { + mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; + } + + mptr = mat[1]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + sum = mptr[1] - s0; + + if ( sum == 0.0f ) { + return false; + } + + mat[1][1] = sum; + diag[1] = sum; + invDiagPtr[1] = d = 1.0f / sum; + + if ( n <= 2 ) { + return true; + } + + mptr = mat[0]; + for ( j = 2; j < n; j++ ) { + mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; + } + + mptr = mat[2]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + sum = mptr[2] - s0 - s1; + + if ( sum == 0.0f ) { + return false; + } + + mat[2][2] = sum; + diag[2] = sum; + invDiagPtr[2] = d = 1.0f / sum; + + if ( n <= 3 ) { + return true; + } + + mptr = mat[0]; + for ( j = 3; j < n; j++ ) { + mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; + } + + mptr = mat[3]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + sum = mptr[3] - s0 - s1 - s2; + + if ( sum == 0.0f ) { + return false; + } + + mat[3][3] = sum; + diag[3] = sum; + invDiagPtr[3] = d = 1.0f / sum; + + if ( n <= 4 ) { + return true; + } + + mptr = mat[0]; + for ( j = 4; j < n; j++ ) { + mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; + } + + int ncf = nc * sizeof( float ); + mptr = mat[0]; + + __asm { + xorps xmm2, xmm2 + xorps xmm3, xmm3 + xorps xmm4, xmm4 + + push ebx + mov ebx, 4 + + loopRow: + cmp ebx, n + jge done + + mov ecx, ebx // esi = i + shl ecx, 2 // esi = i * 4 + mov edx, diag // edx = diag + add edx, ecx // edx = &diag[i] + mov edi, ebx // edi = i + imul edi, ncf // edi = i * nc * sizeof( float ) + add edi, mptr // edi = mat[i] + add edi, ecx // edi = &mat[i][i] + mov esi, v // ecx = v + add esi, ecx // ecx = &v[i] + mov eax, invDiagPtr // eax = invDiagPtr + add eax, ecx // eax = &invDiagPtr[i] + neg ecx + + movaps xmm0, [edx+ecx] + mulps xmm0, [edi+ecx] + movaps [esi+ecx], xmm0 + mulps xmm0, [edi+ecx] + add ecx, 12*4 + jg doneDot8 + dot8: + movaps xmm1, [edx+ecx-(8*4)] + mulps xmm1, [edi+ecx-(8*4)] + movaps [esi+ecx-(8*4)], xmm1 + mulps xmm1, [edi+ecx-(8*4)] + addps xmm0, xmm1 + movaps xmm2, [edx+ecx-(4*4)] + mulps xmm2, [edi+ecx-(4*4)] + movaps [esi+ecx-(4*4)], xmm2 + mulps xmm2, [edi+ecx-(4*4)] + addps xmm0, xmm2 + add ecx, 8*4 + jle dot8 + doneDot8: + sub ecx, 4*4 + jg doneDot4 + movaps xmm1, [edx+ecx-(4*4)] + mulps xmm1, [edi+ecx-(4*4)] + movaps [esi+ecx-(4*4)], xmm1 + mulps xmm1, [edi+ecx-(4*4)] + addps xmm0, xmm1 + add ecx, 4*4 + doneDot4: + sub ecx, 2*4 + jg doneDot2 + movlps xmm3, [edx+ecx-(2*4)] + movlps xmm4, [edi+ecx-(2*4)] + mulps xmm3, xmm4 + movlps [esi+ecx-(2*4)], xmm3 + mulps xmm3, xmm4 + addps xmm0, xmm3 + add ecx, 2*4 + doneDot2: + sub ecx, 1*4 + jg doneDot1 + movss xmm3, [edx+ecx-(1*4)] + movss xmm4, [edi+ecx-(1*4)] + mulss xmm3, xmm4 + movss [esi+ecx-(1*4)], xmm3 + mulss xmm3, xmm4 + addss xmm0, xmm3 + doneDot1: + movhlps xmm2, xmm0 + addps xmm0, xmm2 + movaps xmm2, xmm0 + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm2 + movss xmm1, [edi] + subss xmm1, xmm0 + movss [edi], xmm1 // mptr[i] = sum; + movss [edx], xmm1 // diag[i] = sum; + + // if ( sum == 0.0f ) return false; + movaps xmm2, xmm1 + cmpeqss xmm2, SIMD_SP_zero + andps xmm2, SIMD_SP_tiny + orps xmm1, xmm2 + + rcpss xmm7, xmm1 + mulss xmm1, xmm7 + mulss xmm1, xmm7 + addss xmm7, xmm7 + subss xmm7, xmm1 + movss [eax], xmm7 // invDiagPtr[i] = 1.0f / sum; + + mov edx, n // edx = n + sub edx, ebx // edx = n - i + dec edx // edx = n - i - 1 + jle doneSubRow // if ( i + 1 >= n ) return true; + + mov eax, ebx // eax = i + shl eax, 2 // eax = i * 4 + neg eax + + loopSubRow: + add edi, ncf + mov ecx, eax + movaps xmm0, [esi+ecx] + mulps xmm0, [edi+ecx] + add ecx, 12*4 + jg doneSubDot8 + subDot8: + movaps xmm1, [esi+ecx-(8*4)] + mulps xmm1, [edi+ecx-(8*4)] + addps xmm0, xmm1 + movaps xmm2, [esi+ecx-(4*4)] + mulps xmm2, [edi+ecx-(4*4)] + addps xmm0, xmm2 + add ecx, 8*4 + jle subDot8 + doneSubDot8: + sub ecx, 4*4 + jg doneSubDot4 + movaps xmm1, [esi+ecx-(4*4)] + mulps xmm1, [edi+ecx-(4*4)] + addps xmm0, xmm1 + add ecx, 4*4 + doneSubDot4: + sub ecx, 2*4 + jg doneSubDot2 + movlps xmm3, [esi+ecx-(2*4)] + movlps xmm4, [edi+ecx-(2*4)] + mulps xmm3, xmm4 + addps xmm0, xmm3 + add ecx, 2*4 + doneSubDot2: + sub ecx, 1*4 + jg doneSubDot1 + movss xmm3, [esi+ecx-(1*4)] + movss xmm4, [edi+ecx-(1*4)] + mulss xmm3, xmm4 + addss xmm0, xmm3 + doneSubDot1: + movhlps xmm2, xmm0 + addps xmm0, xmm2 + movaps xmm2, xmm0 + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) + addss xmm0, xmm2 + movss xmm1, [edi] + subss xmm1, xmm0 + mulss xmm1, xmm7 + movss [edi], xmm1 + dec edx + jg loopSubRow + doneSubRow: + inc ebx + jmp loopRow + done: + pop ebx + } + + return true; + +#else + + int i, j, k, nc; + float *v, *diag, *mptr; + double s0, s1, s2, s3, sum, d; + + v = (float *) _alloca16( n * sizeof( float ) ); + diag = (float *) _alloca16( n * sizeof( float ) ); + + nc = mat.GetNumColumns(); + + if ( n <= 0 ) { + return true; + } + + mptr = mat[0]; + + sum = mptr[0]; + + if ( sum == 0.0f ) { + return false; + } + + diag[0] = sum; + invDiag[0] = d = 1.0f / sum; + + if ( n <= 1 ) { + return true; + } + + mptr = mat[0]; + for ( j = 1; j < n; j++ ) { + mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; + } + + mptr = mat[1]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + sum = mptr[1] - s0; + + if ( sum == 0.0f ) { + return false; + } + + mat[1][1] = sum; + diag[1] = sum; + invDiag[1] = d = 1.0f / sum; + + if ( n <= 2 ) { + return true; + } + + mptr = mat[0]; + for ( j = 2; j < n; j++ ) { + mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; + } + + mptr = mat[2]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + sum = mptr[2] - s0 - s1; + + if ( sum == 0.0f ) { + return false; + } + + mat[2][2] = sum; + diag[2] = sum; + invDiag[2] = d = 1.0f / sum; + + if ( n <= 3 ) { + return true; + } + + mptr = mat[0]; + for ( j = 3; j < n; j++ ) { + mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; + } + + mptr = mat[3]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + sum = mptr[3] - s0 - s1 - s2; + + if ( sum == 0.0f ) { + return false; + } + + mat[3][3] = sum; + diag[3] = sum; + invDiag[3] = d = 1.0f / sum; + + if ( n <= 4 ) { + return true; + } + + mptr = mat[0]; + for ( j = 4; j < n; j++ ) { + mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; + } + + for ( i = 4; i < n; i++ ) { + + mptr = mat[i]; + + v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; + v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; + v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; + v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; + for ( k = 4; k < i-3; k += 4 ) { + v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; + v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; + v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; + } + switch( i - k ) { + case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; + case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; + case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; + } + sum = s3; + sum += s2; + sum += s1; + sum += s0; + sum = mptr[i] - sum; + + if ( sum == 0.0f ) { + return false; + } + + mat[i][i] = sum; + diag[i] = sum; + invDiag[i] = d = 1.0f / sum; + + if ( i + 1 >= n ) { + return true; + } + + mptr = mat[i+1]; + for ( j = i+1; j < n; j++ ) { + s0 = mptr[0] * v[0]; + s1 = mptr[1] * v[1]; + s2 = mptr[2] * v[2]; + s3 = mptr[3] * v[3]; + for ( k = 4; k < i-7; k += 8 ) { + s0 += mptr[k+0] * v[k+0]; + s1 += mptr[k+1] * v[k+1]; + s2 += mptr[k+2] * v[k+2]; + s3 += mptr[k+3] * v[k+3]; + s0 += mptr[k+4] * v[k+4]; + s1 += mptr[k+5] * v[k+5]; + s2 += mptr[k+6] * v[k+6]; + s3 += mptr[k+7] * v[k+7]; + } + switch( i - k ) { + case 7: s0 += mptr[k+6] * v[k+6]; + case 6: s1 += mptr[k+5] * v[k+5]; + case 5: s2 += mptr[k+4] * v[k+4]; + case 4: s3 += mptr[k+3] * v[k+3]; + case 3: s0 += mptr[k+2] * v[k+2]; + case 2: s1 += mptr[k+1] * v[k+1]; + case 1: s2 += mptr[k+0] * v[k+0]; + } + sum = s3; + sum += s2; + sum += s1; + sum += s0; + mptr[i] = ( mptr[i] - sum ) * d; + mptr += nc; + } + } + + return true; + +#endif +} + +/* +============ +idSIMD_SSE::BlendJoints +============ +*/ +#define REFINE_BLENDJOINTS_RECIPROCAL + +void VPCALL idSIMD_SSE::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { + int i; + + if ( lerp <= 0.0f ) { + return; + } else if ( lerp >= 1.0f ) { + for ( i = 0; i < numJoints; i++ ) { + int j = index[i]; + joints[j] = blendJoints[j]; + } + return; + } + + for ( i = 0; i <= numJoints - 4; i += 4 ) { + ALIGN16( float jointVert0[4] ); + ALIGN16( float jointVert1[4] ); + ALIGN16( float jointVert2[4] ); + ALIGN16( float blendVert0[4] ); + ALIGN16( float blendVert1[4] ); + ALIGN16( float blendVert2[4] ); + ALIGN16( float jointQuat0[4] ); + ALIGN16( float jointQuat1[4] ); + ALIGN16( float jointQuat2[4] ); + ALIGN16( float jointQuat3[4] ); + ALIGN16( float blendQuat0[4] ); + ALIGN16( float blendQuat1[4] ); + ALIGN16( float blendQuat2[4] ); + ALIGN16( float blendQuat3[4] ); + + for ( int j = 0; j < 4; j++ ) { + int n = index[i+j]; + + jointVert0[j] = joints[n].t[0]; + jointVert1[j] = joints[n].t[1]; + jointVert2[j] = joints[n].t[2]; + + blendVert0[j] = blendJoints[n].t[0]; + blendVert1[j] = blendJoints[n].t[1]; + blendVert2[j] = blendJoints[n].t[2]; + + jointQuat0[j] = joints[n].q[0]; + jointQuat1[j] = joints[n].q[1]; + jointQuat2[j] = joints[n].q[2]; + jointQuat3[j] = joints[n].q[3]; + + blendQuat0[j] = blendJoints[n].q[0]; + blendQuat1[j] = blendJoints[n].q[1]; + blendQuat2[j] = blendJoints[n].q[2]; + blendQuat3[j] = blendJoints[n].q[3]; + } + +#if 1 + __asm { + // lerp translation + movss xmm7, lerp + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + movaps xmm0, blendVert0 + subps xmm0, jointVert0 + mulps xmm0, xmm7 + addps xmm0, jointVert0 + movaps jointVert0, xmm0 + movaps xmm1, blendVert1 + subps xmm1, jointVert1 + mulps xmm1, xmm7 + addps xmm1, jointVert1 + movaps jointVert1, xmm1 + movaps xmm2, blendVert2 + subps xmm2, jointVert2 + mulps xmm2, xmm7 + addps xmm2, jointVert2 + movaps jointVert2, xmm2 + + // lerp quaternions + movaps xmm0, jointQuat0 + mulps xmm0, blendQuat0 + movaps xmm1, jointQuat1 + mulps xmm1, blendQuat1 + addps xmm0, xmm1 + movaps xmm2, jointQuat2 + mulps xmm2, blendQuat2 + addps xmm0, xmm2 + movaps xmm3, jointQuat3 + mulps xmm3, blendQuat3 + addps xmm0, xmm3 // xmm0 = cosom + + movaps xmm1, xmm0 + movaps xmm2, xmm0 + andps xmm1, SIMD_SP_signBitMask // xmm1 = signBit + xorps xmm0, xmm1 + mulps xmm2, xmm2 + + xorps xmm4, xmm4 + movaps xmm3, SIMD_SP_one + subps xmm3, xmm2 // xmm3 = scale0 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 + +#ifdef REFINE_BLENDJOINTS_RECIPROCAL + movaps xmm2, xmm3 + rsqrtps xmm4, xmm2 + mulps xmm2, xmm4 + mulps xmm2, xmm4 + subps xmm2, SIMD_SP_rsqrt_c0 + mulps xmm4, SIMD_SP_rsqrt_c1 + mulps xmm2, xmm4 +#else + rsqrtps xmm2, xmm3 // xmm2 = sinom +#endif + mulps xmm3, xmm2 // xmm3 = sqrt( scale0 ) + + // omega0 = atan2( xmm3, xmm0 ) + movaps xmm4, xmm0 + minps xmm0, xmm3 + maxps xmm3, xmm4 + cmpeqps xmm4, xmm0 + +#ifdef REFINE_BLENDJOINTS_RECIPROCAL + rcpps xmm5, xmm3 + mulps xmm3, xmm5 + mulps xmm3, xmm5 + addps xmm5, xmm5 + subps xmm5, xmm3 // xmm5 = 1 / y or 1 / x + mulps xmm0, xmm5 // xmm0 = x / y or y / x +#else + rcpps xmm3, xmm3 // xmm3 = 1 / y or 1 / x + mulps xmm0, xmm3 // xmm0 = x / y or y / x +#endif + movaps xmm3, xmm4 + andps xmm3, SIMD_SP_signBitMask + xorps xmm0, xmm3 // xmm0 = -x / y or y / x + andps xmm4, SIMD_SP_halfPI // xmm4 = HALF_PI or 0.0f + movaps xmm3, xmm0 + mulps xmm3, xmm3 // xmm3 = s + movaps xmm5, SIMD_SP_atan_c0 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c1 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c2 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c3 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c4 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c5 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c6 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_atan_c7 + mulps xmm5, xmm3 + addps xmm5, SIMD_SP_one + mulps xmm5, xmm0 + addps xmm5, xmm4 // xmm5 = omega0 + + movaps xmm6, xmm7 // xmm6 = lerp + mulps xmm6, xmm5 // xmm6 = omega1 + subps xmm5, xmm6 // xmm5 = omega0 + + // scale0 = sin( xmm5 ) * xmm2 + // scale1 = sin( xmm6 ) * xmm2 + movaps xmm3, xmm5 + movaps xmm7, xmm6 + mulps xmm3, xmm3 + mulps xmm7, xmm7 + movaps xmm4, SIMD_SP_sin_c0 + movaps xmm0, SIMD_SP_sin_c0 + mulps xmm4, xmm3 + mulps xmm0, xmm7 + addps xmm4, SIMD_SP_sin_c1 + addps xmm0, SIMD_SP_sin_c1 + mulps xmm4, xmm3 + mulps xmm0, xmm7 + addps xmm4, SIMD_SP_sin_c2 + addps xmm0, SIMD_SP_sin_c2 + mulps xmm4, xmm3 + mulps xmm0, xmm7 + addps xmm4, SIMD_SP_sin_c3 + addps xmm0, SIMD_SP_sin_c3 + mulps xmm4, xmm3 + mulps xmm0, xmm7 + addps xmm4, SIMD_SP_sin_c4 + addps xmm0, SIMD_SP_sin_c4 + mulps xmm4, xmm3 + mulps xmm0, xmm7 + addps xmm4, SIMD_SP_one + addps xmm0, SIMD_SP_one + mulps xmm5, xmm4 + mulps xmm6, xmm0 + mulps xmm5, xmm2 // xmm5 = scale0 + mulps xmm6, xmm2 // xmm6 = scale1 + + xorps xmm6, xmm1 + + movaps xmm0, jointQuat0 + mulps xmm0, xmm5 + movaps xmm1, blendQuat0 + mulps xmm1, xmm6 + addps xmm0, xmm1 + movaps jointQuat0, xmm0 + + movaps xmm1, jointQuat1 + mulps xmm1, xmm5 + movaps xmm2, blendQuat1 + mulps xmm2, xmm6 + addps xmm1, xmm2 + movaps jointQuat1, xmm1 + + movaps xmm2, jointQuat2 + mulps xmm2, xmm5 + movaps xmm3, blendQuat2 + mulps xmm3, xmm6 + addps xmm2, xmm3 + movaps jointQuat2, xmm2 + + movaps xmm3, jointQuat3 + mulps xmm3, xmm5 + movaps xmm4, blendQuat3 + mulps xmm4, xmm6 + addps xmm3, xmm4 + movaps jointQuat3, xmm3 + } + +#else + + jointVert0[0] += lerp * ( blendVert0[0] - jointVert0[0] ); + jointVert0[1] += lerp * ( blendVert0[1] - jointVert0[1] ); + jointVert0[2] += lerp * ( blendVert0[2] - jointVert0[2] ); + jointVert0[3] += lerp * ( blendVert0[3] - jointVert0[3] ); + + jointVert1[0] += lerp * ( blendVert1[0] - jointVert1[0] ); + jointVert1[1] += lerp * ( blendVert1[1] - jointVert1[1] ); + jointVert1[2] += lerp * ( blendVert1[2] - jointVert1[2] ); + jointVert1[3] += lerp * ( blendVert1[3] - jointVert1[3] ); + + jointVert2[0] += lerp * ( blendVert2[0] - jointVert2[0] ); + jointVert2[1] += lerp * ( blendVert2[1] - jointVert2[1] ); + jointVert2[2] += lerp * ( blendVert2[2] - jointVert2[2] ); + jointVert2[3] += lerp * ( blendVert2[3] - jointVert2[3] ); + + ALIGN16( float cosom[4] ); + ALIGN16( float sinom[4] ); + ALIGN16( float omega0[4] ); + ALIGN16( float omega1[4] ); + ALIGN16( float scale0[4] ); + ALIGN16( float scale1[4] ); + ALIGN16( unsigned long signBit[4] ); + + cosom[0] = jointQuat0[0] * blendQuat0[0]; + cosom[1] = jointQuat0[1] * blendQuat0[1]; + cosom[2] = jointQuat0[2] * blendQuat0[2]; + cosom[3] = jointQuat0[3] * blendQuat0[3]; + + cosom[0] += jointQuat1[0] * blendQuat1[0]; + cosom[1] += jointQuat1[1] * blendQuat1[1]; + cosom[2] += jointQuat1[2] * blendQuat1[2]; + cosom[3] += jointQuat1[3] * blendQuat1[3]; + + cosom[0] += jointQuat2[0] * blendQuat2[0]; + cosom[1] += jointQuat2[1] * blendQuat2[1]; + cosom[2] += jointQuat2[2] * blendQuat2[2]; + cosom[3] += jointQuat2[3] * blendQuat2[3]; + + cosom[0] += jointQuat3[0] * blendQuat3[0]; + cosom[1] += jointQuat3[1] * blendQuat3[1]; + cosom[2] += jointQuat3[2] * blendQuat3[2]; + cosom[3] += jointQuat3[3] * blendQuat3[3]; + + signBit[0] = (*(unsigned long *)&cosom[0]) & ( 1 << 31 ); + signBit[1] = (*(unsigned long *)&cosom[1]) & ( 1 << 31 ); + signBit[2] = (*(unsigned long *)&cosom[2]) & ( 1 << 31 ); + signBit[3] = (*(unsigned long *)&cosom[3]) & ( 1 << 31 ); + + (*(unsigned long *)&cosom[0]) ^= signBit[0]; + (*(unsigned long *)&cosom[1]) ^= signBit[1]; + (*(unsigned long *)&cosom[2]) ^= signBit[2]; + (*(unsigned long *)&cosom[3]) ^= signBit[3]; + + scale0[0] = 1.0f - cosom[0] * cosom[0]; + scale0[1] = 1.0f - cosom[1] * cosom[1]; + scale0[2] = 1.0f - cosom[2] * cosom[2]; + scale0[3] = 1.0f - cosom[3] * cosom[3]; + + scale0[0] = ( scale0[0] <= 0.0f ) ? SIMD_SP_tiny[0] : scale0[0]; + scale0[1] = ( scale0[1] <= 0.0f ) ? SIMD_SP_tiny[1] : scale0[1]; + scale0[2] = ( scale0[2] <= 0.0f ) ? SIMD_SP_tiny[2] : scale0[2]; + scale0[3] = ( scale0[3] <= 0.0f ) ? SIMD_SP_tiny[3] : scale0[3]; + + sinom[0] = idMath::RSqrt( scale0[0] ); + sinom[1] = idMath::RSqrt( scale0[1] ); + sinom[2] = idMath::RSqrt( scale0[2] ); + sinom[3] = idMath::RSqrt( scale0[3] ); + + scale0[0] *= sinom[0]; + scale0[1] *= sinom[1]; + scale0[2] *= sinom[2]; + scale0[3] *= sinom[3]; + + omega0[0] = SSE_ATanPositive( scale0[0], cosom[0] ); + omega0[1] = SSE_ATanPositive( scale0[1], cosom[1] ); + omega0[2] = SSE_ATanPositive( scale0[2], cosom[2] ); + omega0[3] = SSE_ATanPositive( scale0[3], cosom[3] ); + + omega1[0] = lerp * omega0[0]; + omega1[1] = lerp * omega0[1]; + omega1[2] = lerp * omega0[2]; + omega1[3] = lerp * omega0[3]; + + omega0[0] -= omega1[0]; + omega0[1] -= omega1[1]; + omega0[2] -= omega1[2]; + omega0[3] -= omega1[3]; + + scale0[0] = SSE_SinZeroHalfPI( omega0[0] ) * sinom[0]; + scale0[1] = SSE_SinZeroHalfPI( omega0[1] ) * sinom[1]; + scale0[2] = SSE_SinZeroHalfPI( omega0[2] ) * sinom[2]; + scale0[3] = SSE_SinZeroHalfPI( omega0[3] ) * sinom[3]; + + scale1[0] = SSE_SinZeroHalfPI( omega1[0] ) * sinom[0]; + scale1[1] = SSE_SinZeroHalfPI( omega1[1] ) * sinom[1]; + scale1[2] = SSE_SinZeroHalfPI( omega1[2] ) * sinom[2]; + scale1[3] = SSE_SinZeroHalfPI( omega1[3] ) * sinom[3]; + + (*(unsigned long *)&scale1[0]) ^= signBit[0]; + (*(unsigned long *)&scale1[1]) ^= signBit[1]; + (*(unsigned long *)&scale1[2]) ^= signBit[2]; + (*(unsigned long *)&scale1[3]) ^= signBit[3]; + + jointQuat0[0] = scale0[0] * jointQuat0[0] + scale1[0] * blendQuat0[0]; + jointQuat0[1] = scale0[1] * jointQuat0[1] + scale1[1] * blendQuat0[1]; + jointQuat0[2] = scale0[2] * jointQuat0[2] + scale1[2] * blendQuat0[2]; + jointQuat0[3] = scale0[3] * jointQuat0[3] + scale1[3] * blendQuat0[3]; + + jointQuat1[0] = scale0[0] * jointQuat1[0] + scale1[0] * blendQuat1[0]; + jointQuat1[1] = scale0[1] * jointQuat1[1] + scale1[1] * blendQuat1[1]; + jointQuat1[2] = scale0[2] * jointQuat1[2] + scale1[2] * blendQuat1[2]; + jointQuat1[3] = scale0[3] * jointQuat1[3] + scale1[3] * blendQuat1[3]; + + jointQuat2[0] = scale0[0] * jointQuat2[0] + scale1[0] * blendQuat2[0]; + jointQuat2[1] = scale0[1] * jointQuat2[1] + scale1[1] * blendQuat2[1]; + jointQuat2[2] = scale0[2] * jointQuat2[2] + scale1[2] * blendQuat2[2]; + jointQuat2[3] = scale0[3] * jointQuat2[3] + scale1[3] * blendQuat2[3]; + + jointQuat3[0] = scale0[0] * jointQuat3[0] + scale1[0] * blendQuat3[0]; + jointQuat3[1] = scale0[1] * jointQuat3[1] + scale1[1] * blendQuat3[1]; + jointQuat3[2] = scale0[2] * jointQuat3[2] + scale1[2] * blendQuat3[2]; + jointQuat3[3] = scale0[3] * jointQuat3[3] + scale1[3] * blendQuat3[3]; + +#endif + + for ( int j = 0; j < 4; j++ ) { + int n = index[i+j]; + + joints[n].t[0] = jointVert0[j]; + joints[n].t[1] = jointVert1[j]; + joints[n].t[2] = jointVert2[j]; + + joints[n].q[0] = jointQuat0[j]; + joints[n].q[1] = jointQuat1[j]; + joints[n].q[2] = jointQuat2[j]; + joints[n].q[3] = jointQuat3[j]; + } + } + + for ( ; i < numJoints; i++ ) { + int n = index[i]; + + idVec3 &jointVert = joints[n].t; + const idVec3 &blendVert = blendJoints[n].t; + + jointVert[0] += lerp * ( blendVert[0] - jointVert[0] ); + jointVert[1] += lerp * ( blendVert[1] - jointVert[1] ); + jointVert[2] += lerp * ( blendVert[2] - jointVert[2] ); + + idQuat &jointQuat = joints[n].q; + const idQuat &blendQuat = blendJoints[n].q; + + float cosom; + float sinom; + float omega; + float scale0; + float scale1; + unsigned long signBit; + + cosom = jointQuat.x * blendQuat.x + jointQuat.y * blendQuat.y + jointQuat.z * blendQuat.z + jointQuat.w * blendQuat.w; + + signBit = (*(unsigned long *)&cosom) & ( 1 << 31 ); + + (*(unsigned long *)&cosom) ^= signBit; + + scale0 = 1.0f - cosom * cosom; + scale0 = ( scale0 <= 0.0f ) ? SIMD_SP_tiny[0] : scale0; + sinom = idMath::InvSqrt( scale0 ); + omega = idMath::ATan16( scale0 * sinom, cosom ); + scale0 = idMath::Sin16( ( 1.0f - lerp ) * omega ) * sinom; + scale1 = idMath::Sin16( lerp * omega ) * sinom; + + (*(unsigned long *)&scale1) ^= signBit; + + jointQuat.x = scale0 * jointQuat.x + scale1 * blendQuat.x; + jointQuat.y = scale0 * jointQuat.y + scale1 * blendQuat.y; + jointQuat.z = scale0 * jointQuat.z + scale1 * blendQuat.z; + jointQuat.w = scale0 * jointQuat.w + scale1 * blendQuat.w; + } +} + +/* +============ +idSIMD_SSE::ConvertJointQuatsToJointMats +============ +*/ +void VPCALL idSIMD_SSE::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { + + assert( sizeof( idJointQuat ) == JOINTQUAT_SIZE ); + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + assert( (int)(&((idJointQuat *)0)->t) == (int)(&((idJointQuat *)0)->q) + (int)sizeof( ((idJointQuat *)0)->q ) ); + + for ( int i = 0; i < numJoints; i++ ) { + + const float *q = jointQuats[i].q.ToFloatPtr(); + float *m = jointMats[i].ToFloatPtr(); + + m[0*4+3] = q[4]; + m[1*4+3] = q[5]; + m[2*4+3] = q[6]; + + float x2 = q[0] + q[0]; + float y2 = q[1] + q[1]; + float z2 = q[2] + q[2]; + + { + float xx = q[0] * x2; + float yy = q[1] * y2; + float zz = q[2] * z2; + + m[0*4+0] = 1.0f - yy - zz; + m[1*4+1] = 1.0f - xx - zz; + m[2*4+2] = 1.0f - xx - yy; + } + + { + float yz = q[1] * z2; + float wx = q[3] * x2; + + m[2*4+1] = yz - wx; + m[1*4+2] = yz + wx; + } + + { + float xy = q[0] * y2; + float wz = q[3] * z2; + + m[1*4+0] = xy - wz; + m[0*4+1] = xy + wz; + } + + { + float xz = q[0] * z2; + float wy = q[3] * y2; + + m[0*4+2] = xz - wy; + m[2*4+0] = xz + wy; + } + } +} + +/* +============ +idSIMD_SSE::ConvertJointMatsToJointQuats +============ +*/ +void VPCALL idSIMD_SSE::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { + + assert( sizeof( idJointQuat ) == JOINTQUAT_SIZE ); + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + assert( (int)(&((idJointQuat *)0)->t) == (int)(&((idJointQuat *)0)->q) + (int)sizeof( ((idJointQuat *)0)->q ) ); + +#if 1 + + ALIGN16( byte shuffle[16] ); + + __asm { + mov eax, numJoints + mov esi, jointMats + mov edi, jointQuats + and eax, ~3 + jz done4 + imul eax, JOINTMAT_SIZE + add esi, eax + neg eax + + loopMat4: + movss xmm5, [esi+eax+3*JOINTMAT_SIZE+0*16+0*4] + movss xmm6, [esi+eax+3*JOINTMAT_SIZE+1*16+1*4] + movss xmm7, [esi+eax+3*JOINTMAT_SIZE+2*16+2*4] + + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm0, [esi+eax+2*JOINTMAT_SIZE+0*16+0*4] + movss xmm1, [esi+eax+2*JOINTMAT_SIZE+1*16+1*4] + movss xmm2, [esi+eax+2*JOINTMAT_SIZE+2*16+2*4] + + movss xmm5, xmm0 + movss xmm6, xmm1 + movss xmm7, xmm2 + + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm0, [esi+eax+1*JOINTMAT_SIZE+0*16+0*4] + movss xmm1, [esi+eax+1*JOINTMAT_SIZE+1*16+1*4] + movss xmm2, [esi+eax+1*JOINTMAT_SIZE+2*16+2*4] + + movss xmm5, xmm0 + movss xmm6, xmm1 + movss xmm7, xmm2 + + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm0, [esi+eax+0*JOINTMAT_SIZE+0*16+0*4] + movss xmm1, [esi+eax+0*JOINTMAT_SIZE+1*16+1*4] + movss xmm2, [esi+eax+0*JOINTMAT_SIZE+2*16+2*4] + + movss xmm5, xmm0 + movss xmm6, xmm1 + movss xmm7, xmm2 + + // ------------------- + + movaps xmm0, xmm5 + addps xmm0, xmm6 + addps xmm0, xmm7 + cmpnltps xmm0, SIMD_SP_zero // xmm0 = m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f + + movaps xmm1, xmm5 + movaps xmm2, xmm5 + cmpnltps xmm1, xmm6 + cmpnltps xmm2, xmm7 + andps xmm2, xmm1 // xmm2 = m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] + + movaps xmm4, xmm6 + cmpnltps xmm4, xmm7 // xmm3 = m[1 * 4 + 1] > m[2 * 4 + 2] + + movaps xmm1, xmm0 + andnps xmm1, xmm2 + orps xmm2, xmm0 + movaps xmm3, xmm2 + andnps xmm2, xmm4 + orps xmm3, xmm2 + xorps xmm3, SIMD_SP_not + + andps xmm0, SIMD_DW_mat2quatShuffle0 + movaps xmm4, xmm1 + andps xmm4, SIMD_DW_mat2quatShuffle1 + orps xmm0, xmm4 + movaps xmm4, xmm2 + andps xmm4, SIMD_DW_mat2quatShuffle2 + orps xmm0, xmm4 + movaps xmm4, xmm3 + andps xmm4, SIMD_DW_mat2quatShuffle3 + orps xmm4, xmm0 + + movaps shuffle, xmm4 + + movaps xmm0, xmm2 + orps xmm0, xmm3 // xmm0 = xmm2 | xmm3 = s0 + orps xmm2, xmm1 // xmm2 = xmm1 | xmm2 = s2 + orps xmm1, xmm3 // xmm1 = xmm1 | xmm3 = s1 + + andps xmm0, SIMD_SP_signBitMask + andps xmm1, SIMD_SP_signBitMask + andps xmm2, SIMD_SP_signBitMask + + xorps xmm5, xmm0 + xorps xmm6, xmm1 + xorps xmm7, xmm2 + addps xmm5, xmm6 + addps xmm7, SIMD_SP_one + addps xmm5, xmm7 // xmm5 = t + + movaps xmm7, xmm5 // xmm7 = t + rsqrtps xmm6, xmm5 + mulps xmm5, xmm6 + mulps xmm5, xmm6 + subps xmm5, SIMD_SP_rsqrt_c0 + mulps xmm6, SIMD_SP_mat2quat_rsqrt_c1 + mulps xmm6, xmm5 // xmm5 = s + + mulps xmm7, xmm6 // xmm7 = s * t + xorps xmm6, SIMD_SP_signBitMask // xmm6 = -s + + // ------------------- + + add edi, 4*JOINTQUAT_SIZE + + movzx ecx, byte ptr shuffle[0*4+0] // ecx = k0 + movss [edi+ecx*4-4*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; + + movzx edx, byte ptr shuffle[0*4+1] // edx = k1 + movss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+0*4] + xorps xmm4, xmm2 + subss xmm4, [esi+eax+0*JOINTMAT_SIZE+0*16+1*4] + mulss xmm4, xmm6 + movss [edi+edx*4-4*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + + movzx ecx, byte ptr shuffle[0*4+2] // ecx = k2 + movss xmm3, [esi+eax+0*JOINTMAT_SIZE+0*16+2*4] + xorps xmm3, xmm1 + subss xmm3, [esi+eax+0*JOINTMAT_SIZE+2*16+0*4] + mulss xmm3, xmm6 + movss [edi+ecx*4-4*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + + movzx edx, byte ptr shuffle[0*4+3] // edx = k3 + movss xmm4, [esi+eax+0*JOINTMAT_SIZE+2*16+1*4] + xorps xmm4, xmm0 + subss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+2*4] + mulss xmm4, xmm6 + movss [edi+edx*4-4*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + mov ecx, [esi+eax+0*JOINTMAT_SIZE+0*16+3*4] + mov [edi-4*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; + mov edx, [esi+eax+0*JOINTMAT_SIZE+1*16+3*4] + mov [edi-4*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; + mov ecx, [esi+eax+0*JOINTMAT_SIZE+2*16+3*4] + mov [edi-4*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; + + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movzx ecx, byte ptr shuffle[1*4+0] // ecx = k0 + movss [edi+ecx*4-3*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; + + movzx edx, byte ptr shuffle[1*4+1] // edx = k1 + movss xmm4, [esi+eax+1*JOINTMAT_SIZE+1*16+0*4] + xorps xmm4, xmm2 + subss xmm4, [esi+eax+1*JOINTMAT_SIZE+0*16+1*4] + mulss xmm4, xmm6 + movss [edi+edx*4-3*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + + movzx ecx, byte ptr shuffle[1*4+2] // ecx = k2 + movss xmm3, [esi+eax+1*JOINTMAT_SIZE+0*16+2*4] + xorps xmm3, xmm1 + subss xmm3, [esi+eax+1*JOINTMAT_SIZE+2*16+0*4] + mulss xmm3, xmm6 + movss [edi+ecx*4-3*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + + movzx edx, byte ptr shuffle[1*4+3] // edx = k3 + movss xmm4, [esi+eax+1*JOINTMAT_SIZE+2*16+1*4] + xorps xmm4, xmm0 + subss xmm4, [esi+eax+1*JOINTMAT_SIZE+1*16+2*4] + mulss xmm4, xmm6 + movss [edi+edx*4-3*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + mov ecx, [esi+eax+1*JOINTMAT_SIZE+0*16+3*4] + mov [edi-3*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; + mov edx, [esi+eax+1*JOINTMAT_SIZE+1*16+3*4] + mov [edi-3*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; + mov ecx, [esi+eax+1*JOINTMAT_SIZE+2*16+3*4] + mov [edi-3*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; + + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movzx ecx, byte ptr shuffle[2*4+0] // ecx = k0 + movss [edi+ecx*4-2*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; + + movzx edx, byte ptr shuffle[2*4+1] // edx = k1 + movss xmm4, [esi+eax+2*JOINTMAT_SIZE+1*16+0*4] + xorps xmm4, xmm2 + subss xmm4, [esi+eax+2*JOINTMAT_SIZE+0*16+1*4] + mulss xmm4, xmm6 + movss [edi+edx*4-2*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + + movzx ecx, byte ptr shuffle[2*4+2] // ecx = k2 + movss xmm3, [esi+eax+2*JOINTMAT_SIZE+0*16+2*4] + xorps xmm3, xmm1 + subss xmm3, [esi+eax+2*JOINTMAT_SIZE+2*16+0*4] + mulss xmm3, xmm6 + movss [edi+ecx*4-2*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + + movzx edx, byte ptr shuffle[2*4+3] // edx = k3 + movss xmm4, [esi+eax+2*JOINTMAT_SIZE+2*16+1*4] + xorps xmm4, xmm0 + subss xmm4, [esi+eax+2*JOINTMAT_SIZE+1*16+2*4] + mulss xmm4, xmm6 + movss [edi+edx*4-2*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + mov ecx, [esi+eax+2*JOINTMAT_SIZE+0*16+3*4] + mov [edi-2*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; + mov edx, [esi+eax+2*JOINTMAT_SIZE+1*16+3*4] + mov [edi-2*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; + mov ecx, [esi+eax+2*JOINTMAT_SIZE+2*16+3*4] + mov [edi-2*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; + + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movzx ecx, byte ptr shuffle[3*4+0] // ecx = k0 + movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; + + movzx edx, byte ptr shuffle[3*4+1] // edx = k1 + movss xmm4, [esi+eax+3*JOINTMAT_SIZE+1*16+0*4] + xorps xmm4, xmm2 + subss xmm4, [esi+eax+3*JOINTMAT_SIZE+0*16+1*4] + mulss xmm4, xmm6 + movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + + movzx ecx, byte ptr shuffle[3*4+2] // ecx = k2 + movss xmm3, [esi+eax+3*JOINTMAT_SIZE+0*16+2*4] + xorps xmm3, xmm1 + subss xmm3, [esi+eax+3*JOINTMAT_SIZE+2*16+0*4] + mulss xmm3, xmm6 + movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + + movzx edx, byte ptr shuffle[3*4+3] // edx = k3 + movss xmm4, [esi+eax+3*JOINTMAT_SIZE+2*16+1*4] + xorps xmm4, xmm0 + subss xmm4, [esi+eax+3*JOINTMAT_SIZE+1*16+2*4] + mulss xmm4, xmm6 + movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + mov ecx, [esi+eax+3*JOINTMAT_SIZE+0*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; + mov edx, [esi+eax+3*JOINTMAT_SIZE+1*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; + mov ecx, [esi+eax+3*JOINTMAT_SIZE+2*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; + + add eax, 4*JOINTMAT_SIZE + jl loopMat4 + + done4: + mov eax, numJoints + and eax, 3 + jz done1 + imul eax, JOINTMAT_SIZE + add esi, eax + neg eax + + loopMat1: + movss xmm5, [esi+eax+0*JOINTMAT_SIZE+0*16+0*4] + movss xmm6, [esi+eax+0*JOINTMAT_SIZE+1*16+1*4] + movss xmm7, [esi+eax+0*JOINTMAT_SIZE+2*16+2*4] + + // ------------------- + + movaps xmm0, xmm5 + addss xmm0, xmm6 + addss xmm0, xmm7 + cmpnltss xmm0, SIMD_SP_zero // xmm0 = m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f + + movaps xmm1, xmm5 + movaps xmm2, xmm5 + cmpnltss xmm1, xmm6 + cmpnltss xmm2, xmm7 + andps xmm2, xmm1 // xmm2 = m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] + + movaps xmm4, xmm6 + cmpnltss xmm4, xmm7 // xmm3 = m[1 * 4 + 1] > m[2 * 4 + 2] + + movaps xmm1, xmm0 + andnps xmm1, xmm2 + orps xmm2, xmm0 + movaps xmm3, xmm2 + andnps xmm2, xmm4 + orps xmm3, xmm2 + xorps xmm3, SIMD_SP_not + + andps xmm0, SIMD_DW_mat2quatShuffle0 + movaps xmm4, xmm1 + andps xmm4, SIMD_DW_mat2quatShuffle1 + orps xmm0, xmm4 + movaps xmm4, xmm2 + andps xmm4, SIMD_DW_mat2quatShuffle2 + orps xmm0, xmm4 + movaps xmm4, xmm3 + andps xmm4, SIMD_DW_mat2quatShuffle3 + orps xmm4, xmm0 + + movss shuffle, xmm4 + + movaps xmm0, xmm2 + orps xmm0, xmm3 // xmm0 = xmm2 | xmm3 = s0 + orps xmm2, xmm1 // xmm2 = xmm1 | xmm2 = s2 + orps xmm1, xmm3 // xmm1 = xmm1 | xmm3 = s1 + + andps xmm0, SIMD_SP_signBitMask + andps xmm1, SIMD_SP_signBitMask + andps xmm2, SIMD_SP_signBitMask + + xorps xmm5, xmm0 + xorps xmm6, xmm1 + xorps xmm7, xmm2 + addss xmm5, xmm6 + addss xmm7, SIMD_SP_one + addss xmm5, xmm7 // xmm5 = t + + movss xmm7, xmm5 // xmm7 = t + rsqrtss xmm6, xmm5 + mulss xmm5, xmm6 + mulss xmm5, xmm6 + subss xmm5, SIMD_SP_rsqrt_c0 + mulss xmm6, SIMD_SP_mat2quat_rsqrt_c1 + mulss xmm6, xmm5 // xmm5 = s + + mulss xmm7, xmm6 // xmm7 = s * t + xorps xmm6, SIMD_SP_signBitMask // xmm6 = -s + + // ------------------- + + movzx ecx, byte ptr shuffle[0] // ecx = k0 + add edi, JOINTQUAT_SIZE + movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; + + movzx edx, byte ptr shuffle[1] // edx = k1 + movss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+0*4] + xorps xmm4, xmm2 + subss xmm4, [esi+eax+0*JOINTMAT_SIZE+0*16+1*4] + mulss xmm4, xmm6 + movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + + movzx ecx, byte ptr shuffle[2] // ecx = k2 + movss xmm3, [esi+eax+0*JOINTMAT_SIZE+0*16+2*4] + xorps xmm3, xmm1 + subss xmm3, [esi+eax+0*JOINTMAT_SIZE+2*16+0*4] + mulss xmm3, xmm6 + movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + + movzx edx, byte ptr shuffle[3] // edx = k3 + movss xmm4, [esi+eax+0*JOINTMAT_SIZE+2*16+1*4] + xorps xmm4, xmm0 + subss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+2*4] + mulss xmm4, xmm6 + movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + mov ecx, [esi+eax+0*JOINTMAT_SIZE+0*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; + mov edx, [esi+eax+0*JOINTMAT_SIZE+1*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; + mov ecx, [esi+eax+0*JOINTMAT_SIZE+2*16+3*4] + mov [edi-1*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; + + add eax, JOINTMAT_SIZE + jl loopMat1 + + done1: + } + +#elif 0 + + for ( int i = 0; i < numJoints; i++ ) { + float s0, s1, s2; + int k0, k1, k2, k3; + + float *q = jointQuats[i].q.ToFloatPtr(); + const float *m = jointMats[i].ToFloatPtr(); + + if ( m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f ) { + + k0 = 3; + k1 = 2; + k2 = 1; + k3 = 0; + s0 = 1.0f; + s1 = 1.0f; + s2 = 1.0f; + + } else if ( m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] ) { + + k0 = 0; + k1 = 1; + k2 = 2; + k3 = 3; + s0 = 1.0f; + s1 = -1.0f; + s2 = -1.0f; + + } else if ( m[1 * 4 + 1] > m[2 * 4 + 2] ) { + + k0 = 1; + k1 = 0; + k2 = 3; + k3 = 2; + s0 = -1.0f; + s1 = 1.0f; + s2 = -1.0f; + + } else { + + k0 = 2; + k1 = 3; + k2 = 0; + k3 = 1; + s0 = -1.0f; + s1 = -1.0f; + s2 = 1.0f; + + } + + float t = s0 * m[0 * 4 + 0] + s1 * m[1 * 4 + 1] + s2 * m[2 * 4 + 2] + 1.0f; + float s = idMath::InvSqrt( t ) * 0.5f; + + q[k0] = s * t; + q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; + q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; + q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; + + q[4] = m[0 * 4 + 3]; + q[5] = m[1 * 4 + 3]; + q[6] = m[2 * 4 + 3]; + } + +#elif 1 + + for ( int i = 0; i < numJoints; i++ ) { + + float *q = jointQuats[i].q.ToFloatPtr(); + const float *m = jointMats[i].ToFloatPtr(); + + if ( m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f ) { + + float t = + m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f; + float s = idMath::InvSqrt( t ) * 0.5f; + + q[3] = s * t; + q[2] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s; + q[1] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s; + q[0] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s; + + } else if ( m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] ) { + + float t = + m[0 * 4 + 0] - m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f; + float s = idMath::InvSqrt( t ) * 0.5f; + + q[0] = s * t; + q[1] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s; + q[2] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s; + q[3] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s; + + } else if ( m[1 * 4 + 1] > m[2 * 4 + 2] ) { + + float t = - m[0 * 4 + 0] + m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f; + float s = idMath::InvSqrt( t ) * 0.5f; + + q[1] = s * t; + q[0] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s; + q[3] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s; + q[2] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s; + + } else { + + float t = - m[0 * 4 + 0] - m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f; + float s = idMath::InvSqrt( t ) * 0.5f; + + q[2] = s * t; + q[3] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s; + q[0] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s; + q[1] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s; + + } + + q[4] = m[0 * 4 + 3]; + q[5] = m[1 * 4 + 3]; + q[6] = m[2 * 4 + 3]; + } + +#endif +} + +/* +============ +idSIMD_SSE::TransformJoints +============ +*/ +void VPCALL idSIMD_SSE::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { +#if 1 + + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + + __asm { + + mov ecx, firstJoint + mov eax, lastJoint + sub eax, ecx + jl done + imul ecx, 4 + mov edi, parents + add edi, ecx + imul ecx, 12 + mov esi, jointMats + imul eax, 4 + add edi, eax + neg eax + + loopJoint: + + movaps xmm0, [esi+ecx+ 0] // xmm0 = m0, m1, m2, t0 + mov edx, [edi+eax] + movaps xmm1, [esi+ecx+16] // xmm1 = m2, m3, m4, t1 + imul edx, JOINTMAT_SIZE + movaps xmm2, [esi+ecx+32] // xmm2 = m5, m6, m7, t2 + + movss xmm4, [esi+edx+ 0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm0 + + movss xmm5, [esi+edx+ 4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm1 + addps xmm4, xmm5 + movss xmm6, [esi+edx+ 8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm2 + addps xmm4, xmm6 + + movss xmm5, [esi+edx+16] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm0 + + movss xmm7, [esi+edx+12] + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + addps xmm4, xmm7 + + movaps [esi+ecx+ 0], xmm4 + + movss xmm6, [esi+edx+20] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm1 + addps xmm5, xmm6 + movss xmm7, [esi+edx+24] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm5, xmm7 + + movss xmm6, [esi+edx+32] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + + movss xmm3, [esi+edx+28] + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) + addps xmm5, xmm3 + + movaps [esi+ecx+16], xmm5 + + movss xmm7, [esi+edx+36] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movss xmm3, [esi+edx+40] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm2 + addps xmm6, xmm3 + + movss xmm7, [esi+edx+44] + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + addps xmm6, xmm7 + + movaps [esi+ecx+32], xmm6 + + add ecx, JOINTMAT_SIZE + add eax, 4 + jle loopJoint + done: + } + +#else + + int i; + + for( i = firstJoint; i <= lastJoint; i++ ) { + assert( parents[i] < i ); + jointMats[i] *= jointMats[parents[i]]; + } + +#endif +} + +/* +============ +idSIMD_SSE::UntransformJoints +============ +*/ +void VPCALL idSIMD_SSE::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { +#if 1 + + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + + __asm { + + mov edx, firstJoint + mov eax, lastJoint + mov ecx, eax + sub eax, edx + jl done + mov esi, jointMats + imul ecx, JOINTMAT_SIZE + imul edx, 4 + mov edi, parents + add edi, edx + imul eax, 4 + + loopJoint: + + movaps xmm0, [esi+ecx+ 0] // xmm0 = m0, m1, m2, t0 + mov edx, [edi+eax] + movaps xmm1, [esi+ecx+16] // xmm1 = m2, m3, m4, t1 + imul edx, JOINTMAT_SIZE + movaps xmm2, [esi+ecx+32] // xmm2 = m5, m6, m7, t2 + + movss xmm6, [esi+edx+12] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + subps xmm0, xmm6 + movss xmm7, [esi+edx+28] + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) + subps xmm1, xmm7 + movss xmm3, [esi+edx+44] + shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) + subps xmm2, xmm3 + + movss xmm4, [esi+edx+ 0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm4, xmm0 + movss xmm5, [esi+edx+16] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm1 + addps xmm4, xmm5 + movss xmm6, [esi+edx+32] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm2 + addps xmm4, xmm6 + + movaps [esi+ecx+ 0], xmm4 + + movss xmm5, [esi+edx+ 4] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm5, xmm0 + movss xmm6, [esi+edx+20] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm1 + addps xmm5, xmm6 + movss xmm7, [esi+edx+36] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm5, xmm7 + + movaps [esi+ecx+16], xmm5 + + movss xmm6, [esi+edx+ 8] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movss xmm7, [esi+edx+24] + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movss xmm3, [esi+edx+40] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm3, xmm2 + addps xmm6, xmm3 + + movaps [esi+ecx+32], xmm6 + + sub ecx, JOINTMAT_SIZE + sub eax, 4 + jge loopJoint + done: + } + +#else + + int i; + + for( i = lastJoint; i >= firstJoint; i-- ) { + assert( parents[i] < i ); + jointMats[i] /= jointMats[parents[i]]; + } + +#endif +} + +/* +============ +idSIMD_SSE::TransformVerts +============ +*/ +void VPCALL idSIMD_SSE::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) { +#if 1 + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + assert( sizeof( idVec4 ) == JOINTWEIGHT_SIZE ); + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + + __asm + { + mov eax, numVerts + test eax, eax + jz done + imul eax, DRAWVERT_SIZE + + mov ecx, verts + mov edx, index + mov esi, weights + mov edi, joints + + add ecx, eax + neg eax + + loopVert: + mov ebx, [edx] + movaps xmm2, [esi] + add edx, 8 + movaps xmm0, xmm2 + add esi, JOINTWEIGHT_SIZE + movaps xmm1, xmm2 + + mulps xmm0, [edi+ebx+ 0] // xmm0 = m0, m1, m2, t0 + mulps xmm1, [edi+ebx+16] // xmm1 = m3, m4, m5, t1 + mulps xmm2, [edi+ebx+32] // xmm2 = m6, m7, m8, t2 + + cmp dword ptr [edx-4], 0 + + jne doneWeight + + loopWeight: + mov ebx, [edx] + movaps xmm5, [esi] + add edx, 8 + movaps xmm3, xmm5 + add esi, JOINTWEIGHT_SIZE + movaps xmm4, xmm5 + + mulps xmm3, [edi+ebx+ 0] // xmm3 = m0, m1, m2, t0 + mulps xmm4, [edi+ebx+16] // xmm4 = m3, m4, m5, t1 + mulps xmm5, [edi+ebx+32] // xmm5 = m6, m7, m8, t2 + + cmp dword ptr [edx-4], 0 + + addps xmm0, xmm3 + addps xmm1, xmm4 + addps xmm2, xmm5 + + je loopWeight + + doneWeight: + add eax, DRAWVERT_SIZE + + movaps xmm6, xmm0 // xmm6 = m0, m1, m2, t0 + unpcklps xmm6, xmm1 // xmm6 = m0, m3, m1, m4 + unpckhps xmm0, xmm1 // xmm1 = m2, m5, t0, t1 + addps xmm6, xmm0 // xmm6 = m0+m2, m3+m5, m1+t0, m4+t1 + + movaps xmm7, xmm2 // xmm7 = m6, m7, m8, t2 + movlhps xmm2, xmm6 // xmm2 = m6, m7, m0+m2, m3+m5 + movhlps xmm6, xmm7 // xmm6 = m8, t2, m1+t0, m4+t1 + addps xmm6, xmm2 // xmm6 = m6+m8, m7+t2, m0+m1+m2+t0, m3+m4+m5+t1 + + movhps [ecx+eax-DRAWVERT_SIZE+0], xmm6 + + movaps xmm5, xmm6 // xmm5 = m6+m8, m7+t2 + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 0, 2, 3 ) // xmm5 = m7+t2, m6+m8 + addss xmm5, xmm6 // xmm5 = m6+m8+m7+t2 + + movss [ecx+eax-DRAWVERT_SIZE+8], xmm5 + + jl loopVert + done: + } + +#else + + int i, j; + const byte *jointsPtr = (byte *)joints; + + for( j = i = 0; i < numVerts; i++ ) { + idVec3 v; + + v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + while( index[j*2+1] == 0 ) { + j++; + v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + } + j++; + + verts[i].xyz = v; + } + +#endif +} + +/* +============ +idSIMD_SSE::TracePointCull +============ +*/ +void VPCALL idSIMD_SSE::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { +#if 1 + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + push ebx + mov eax, numVerts + test eax, eax + jz done + + mov edi, planes + movlps xmm1, [edi] // xmm1 = 0, 1, X, X + movhps xmm1, [edi+16] // xmm1 = 0, 1, 4, 5 + movlps xmm3, [edi+8] // xmm3 = 2, 3, X, X + movhps xmm3, [edi+24] // xmm3 = 2, 3, 6, 7 + movlps xmm4, [edi+32] // xmm4 = 8, 9, X, X + movhps xmm4, [edi+48] // xmm4 = 8, 9, 12, 13 + movlps xmm5, [edi+40] // xmm5 = 10, 11, X, X + movhps xmm5, [edi+56] // xmm5 = 10, 11, 14, 15 + movaps xmm0, xmm1 // xmm0 = 0, 1, 4, 5 + shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm0 = 0, 4, 8, 12 + shufps xmm1, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm1 = 1, 5, 9, 13 + movaps xmm2, xmm3 // xmm2 = 2, 3, 6, 7 + shufps xmm2, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm2 = 2, 6, 10, 14 + shufps xmm3, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm3 = 3, 7, 11, 15 + movss xmm7, radius + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + xor edx, edx + mov esi, verts + mov edi, cullBits + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loopVert: + movss xmm4, [esi+eax+DRAWVERT_XYZ_OFFSET+0] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm5, [esi+eax+DRAWVERT_XYZ_OFFSET+4] + mulps xmm4, xmm0 + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + movss xmm6, [esi+eax+DRAWVERT_XYZ_OFFSET+8] + mulps xmm5, xmm1 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + addps xmm4, xmm5 + mulps xmm6, xmm2 + addps xmm4, xmm3 + addps xmm4, xmm6 + movaps xmm5, xmm4 + xorps xmm5, SIMD_SP_signBitMask + cmpltps xmm4, xmm7 + movmskps ecx, xmm4 + cmpltps xmm5, xmm7 + movmskps ebx, xmm5 + shl cx, 4 + or cl, bl + inc edi + or dl, cl + add eax, DRAWVERT_SIZE + mov byte ptr [edi-1], cl + jl loopVert + + done: + mov esi, totalOr + mov byte ptr [esi], dl + pop ebx + } + +#else + + int i; + byte tOr; + + tOr = 0; + + for ( i = 0; i < numVerts; i++ ) { + byte bits; + float d0, d1, d2, d3, t; + const idVec3 &v = verts[i].xyz; + + d0 = planes[0][0] * v[0] + planes[0][1] * v[1] + planes[0][2] * v[2] + planes[0][3]; + d1 = planes[1][0] * v[0] + planes[1][1] * v[1] + planes[1][2] * v[2] + planes[1][3]; + d2 = planes[2][0] * v[0] + planes[2][1] * v[1] + planes[2][2] * v[2] + planes[2][3]; + d3 = planes[3][0] * v[0] + planes[3][1] * v[1] + planes[3][2] * v[2] + planes[3][3]; + + t = d0 + radius; + bits = FLOATSIGNBITSET( t ) << 0; + t = d1 + radius; + bits |= FLOATSIGNBITSET( t ) << 1; + t = d2 + radius; + bits |= FLOATSIGNBITSET( t ) << 2; + t = d3 + radius; + bits |= FLOATSIGNBITSET( t ) << 3; + + t = d0 - radius; + bits |= FLOATSIGNBITSET( t ) << 4; + t = d1 - radius; + bits |= FLOATSIGNBITSET( t ) << 5; + t = d2 - radius; + bits |= FLOATSIGNBITSET( t ) << 6; + t = d3 - radius; + bits |= FLOATSIGNBITSET( t ) << 7; + + bits ^= 0x0F; // flip lower four bits + + tOr |= bits; + cullBits[i] = bits; + } + + totalOr = tOr; + +#endif +} + +/* +============ +idSIMD_SSE::DecalPointCull +============ +*/ +void VPCALL idSIMD_SSE::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { +#if 1 + + ALIGN16( float p0[4] ); + ALIGN16( float p1[4] ); + ALIGN16( float p2[4] ); + ALIGN16( float p3[4] ); + ALIGN16( float p4[4] ); + ALIGN16( float p5[4] ); + ALIGN16( float p6[4] ); + ALIGN16( float p7[4] ); + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + mov ecx, planes + movlps xmm1, [ecx] // xmm1 = 0, 1, X, X + movhps xmm1, [ecx+16] // xmm1 = 0, 1, 4, 5 + movlps xmm3, [ecx+8] // xmm3 = 2, 3, X, X + movhps xmm3, [ecx+24] // xmm3 = 2, 3, 6, 7 + movlps xmm4, [ecx+32] // xmm4 = 8, 9, X, X + movhps xmm4, [ecx+48] // xmm4 = 8, 9, 12, 13 + movlps xmm5, [ecx+40] // xmm5 = 10, 11, X, X + movhps xmm5, [ecx+56] // xmm5 = 10, 11, 14, 15 + movaps xmm0, xmm1 // xmm0 = 0, 1, 4, 5 + shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm0 = 0, 4, 8, 12 + shufps xmm1, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm1 = 1, 5, 9, 13 + movaps xmm2, xmm3 // xmm2 = 2, 3, 6, 7 + shufps xmm2, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm2 = 2, 6, 10, 14 + shufps xmm3, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm3 = 3, 7, 11, 15 + + movaps p0, xmm0 + movaps p1, xmm1 + movaps p2, xmm2 + movaps p3, xmm3 + + movlps xmm4, [ecx+64] // xmm4 = p40, p41, X, X + movhps xmm4, [ecx+80] // xmm4 = p40, p41, p50, p51 + movaps xmm5, xmm4 // xmm5 = p40, p41, p50, p51 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm4 = p40, p50, p40, p50 + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm5 = p41, p51, p41, p51 + movlps xmm6, [ecx+72] // xmm6 = p42, p43, X, X + movhps xmm6, [ecx+88] // xmm6 = p42, p43, p52, p53 + movaps xmm7, xmm6 // xmm7 = p42, p43, p52, p53 + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm6 = p42, p52, p42, p52 + shufps xmm7, xmm7, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm7 = p43, p53, p43, p53 + + movaps p4, xmm4 + movaps p5, xmm5 + movaps p6, xmm6 + movaps p7, xmm7 + + mov esi, verts + mov edi, cullBits + mov eax, numVerts + and eax, ~1 + jz done2 + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + + loopVert2: + movaps xmm6, p0 + movss xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movaps xmm7, p1 + movss xmm1, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movaps xmm7, p2 + movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + addps xmm6, p3 + + cmpnltps xmm6, SIMD_SP_zero + movmskps ecx, xmm6 + + movaps xmm6, p0 + movss xmm3, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm3 + movaps xmm7, p1 + movss xmm4, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm4 + addps xmm6, xmm7 + movaps xmm7, p2 + movss xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm5 + addps xmm6, xmm7 + addps xmm6, p3 + + cmpnltps xmm6, SIMD_SP_zero + movmskps edx, xmm6 + mov ch, dl + + shufps xmm0, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm0, p4 + shufps xmm1, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm1, p5 + addps xmm0, xmm1 + shufps xmm2, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm2, p6 + addps xmm0, xmm2 + addps xmm0, p7 + + cmpnltps xmm0, SIMD_SP_zero + movmskps edx, xmm0 + + add edi, 2 + + mov dh, dl + shl dl, 4 + shl dh, 2 + and edx, (3<<4)|(3<<12) + or ecx, edx + + add eax, 2*DRAWVERT_SIZE + mov word ptr [edi-2], cx + jl loopVert2 + + done2: + + mov eax, numVerts + and eax, 1 + jz done + + movaps xmm6, p0 + movss xmm0, [esi+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm6, xmm0 + movaps xmm7, p1 + movss xmm1, [esi+DRAWVERT_XYZ_OFFSET+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm1 + addps xmm6, xmm7 + movaps xmm7, p2 + movss xmm2, [esi+DRAWVERT_XYZ_OFFSET+8] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm7, xmm2 + addps xmm6, xmm7 + addps xmm6, p3 + + cmpnltps xmm6, SIMD_SP_zero + movmskps ecx, xmm6 + + mulps xmm0, p4 + mulps xmm1, p5 + addps xmm0, xmm1 + mulps xmm2, p6 + addps xmm0, xmm2 + addps xmm0, p7 + + cmpnltps xmm0, SIMD_SP_zero + movmskps edx, xmm0 + + and edx, 3 + shl edx, 4 + or ecx, edx + + mov byte ptr [edi], cl + + done: + } + + +#else + + int i; + + for ( i = 0; i < numVerts; i += 2 ) { + unsigned short bits0, bits1; + float d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11; + const idVec3 &v0 = verts[i+0].xyz; + const idVec3 &v1 = verts[i+1].xyz; + + d0 = planes[0][0] * v0[0] + planes[0][1] * v0[1] + planes[0][2] * v0[2] + planes[0][3]; + d1 = planes[1][0] * v0[0] + planes[1][1] * v0[1] + planes[1][2] * v0[2] + planes[1][3]; + d2 = planes[2][0] * v0[0] + planes[2][1] * v0[1] + planes[2][2] * v0[2] + planes[2][3]; + d3 = planes[3][0] * v0[0] + planes[3][1] * v0[1] + planes[3][2] * v0[2] + planes[3][3]; + + d4 = planes[4][0] * v0[0] + planes[4][1] * v0[1] + planes[4][2] * v0[2] + planes[4][3]; + d5 = planes[5][0] * v0[0] + planes[5][1] * v0[1] + planes[5][2] * v0[2] + planes[5][3]; + d10 = planes[4][0] * v1[0] + planes[4][1] * v1[1] + planes[4][2] * v1[2] + planes[4][3]; + d11 = planes[5][0] * v1[0] + planes[5][1] * v1[1] + planes[5][2] * v1[2] + planes[5][3]; + + d6 = planes[0][0] * v1[0] + planes[0][1] * v1[1] + planes[0][2] * v1[2] + planes[0][3]; + d7 = planes[1][0] * v1[0] + planes[1][1] * v1[1] + planes[1][2] * v1[2] + planes[1][3]; + d8 = planes[2][0] * v1[0] + planes[2][1] * v1[1] + planes[2][2] * v1[2] + planes[2][3]; + d9 = planes[3][0] * v1[0] + planes[3][1] * v1[1] + planes[3][2] * v1[2] + planes[3][3]; + + bits0 = FLOATSIGNBITSET( d0 ) << (0+0); + bits0 |= FLOATSIGNBITSET( d1 ) << (0+1); + bits0 |= FLOATSIGNBITSET( d2 ) << (0+2); + bits0 |= FLOATSIGNBITSET( d3 ) << (0+3); + bits0 |= FLOATSIGNBITSET( d4 ) << (0+4); + bits0 |= FLOATSIGNBITSET( d5 ) << (0+5); + + bits1 = FLOATSIGNBITSET( d6 ) << (8+0); + bits1 |= FLOATSIGNBITSET( d7 ) << (8+1); + bits1 |= FLOATSIGNBITSET( d8 ) << (8+2); + bits1 |= FLOATSIGNBITSET( d9 ) << (8+3); + bits1 |= FLOATSIGNBITSET( d10 ) << (8+4); + bits1 |= FLOATSIGNBITSET( d11 ) << (8+5); + + *(unsigned short *)(cullBits + i) = ( bits0 | bits1 ) ^ 0x3F3F; + } + + if ( numVerts & 1 ) { + byte bits; + float d0, d1, d2, d3, d4, d5; + const idVec3 &v = verts[numVerts - 1].xyz; + + d0 = planes[0][0] * v[0] + planes[0][1] * v[1] + planes[0][2] * v[2] + planes[0][3]; + d1 = planes[1][0] * v[0] + planes[1][1] * v[1] + planes[1][2] * v[2] + planes[1][3]; + d2 = planes[2][0] * v[0] + planes[2][1] * v[1] + planes[2][2] * v[2] + planes[2][3]; + d3 = planes[3][0] * v[0] + planes[3][1] * v[1] + planes[3][2] * v[2] + planes[3][3]; + + d4 = planes[4][0] * v[0] + planes[4][1] * v[1] + planes[4][2] * v[2] + planes[4][3]; + d5 = planes[5][0] * v[0] + planes[5][1] * v[1] + planes[5][2] * v[2] + planes[5][3]; + + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + bits |= FLOATSIGNBITSET( d2 ) << 2; + bits |= FLOATSIGNBITSET( d3 ) << 3; + + bits |= FLOATSIGNBITSET( d4 ) << 4; + bits |= FLOATSIGNBITSET( d5 ) << 5; + + cullBits[numVerts - 1] = bits ^ 0x3F; // flip lower 6 bits + } + +#endif +} + +/* +============ +idSIMD_SSE::OverlayPointCull +============ +*/ +void VPCALL idSIMD_SSE::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { +#if 1 + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + mov eax, numVerts + mov edx, verts + mov esi, texCoords + mov edi, cullBits + + mov ecx, planes + movss xmm4, [ecx+ 0] + movss xmm5, [ecx+16] + shufps xmm4, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) + movss xmm5, [ecx+ 4] + movss xmm6, [ecx+20] + shufps xmm5, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) + movss xmm6, [ecx+ 8] + movss xmm7, [ecx+24] + shufps xmm6, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 0, 2 ) + movss xmm7, [ecx+12] + movss xmm0, [ecx+28] + shufps xmm7, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 2, 0, 2 ) + + and eax, ~1 + jz done2 + add edi, eax + neg eax + + loopVert2: + movss xmm0, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movss xmm1, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm0, xmm4 + movss xmm1, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + movss xmm2, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm1, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm1, xmm5 + movss xmm2, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movss xmm3, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + shufps xmm2, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm2, xmm6 + addps xmm0, xmm1 + addps xmm0, xmm2 + addps xmm0, xmm7 + movaps [esi], xmm0 + movaps xmm1, xmm0 + movaps xmm2, SIMD_SP_one + subps xmm2, xmm0 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + shufps xmm1, xmm2, R_SHUFFLEPS( 2, 3, 2, 3 ) + add edx, 2*DRAWVERT_SIZE + movmskps ecx, xmm0 + mov byte ptr [edi+eax+0], cl + add esi, 4*4 + movmskps ecx, xmm1 + mov byte ptr [edi+eax+1], cl + add eax, 2 + jl loopVert2 + + done2: + mov eax, numVerts + and eax, 1 + jz done + + movss xmm0, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm0, xmm4 + movss xmm1, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm1, xmm5 + movss xmm2, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm2, xmm6 + addps xmm0, xmm1 + addps xmm0, xmm2 + addps xmm0, xmm7 + movlps [esi], xmm0 + movaps xmm1, xmm0 + movaps xmm2, SIMD_SP_one + subps xmm2, xmm0 + shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + movmskps ecx, xmm0 + mov byte ptr [edi], cl + + done: + } + +#else + + const idPlane &p0 = planes[0]; + const idPlane &p1 = planes[1]; + + for ( int i = 0; i < numVerts - 1; i += 2 ) { + unsigned short bits; + float d0, d1, d2, d3; + + const idVec3 &v0 = verts[i+0].xyz; + const idVec3 &v1 = verts[i+1].xyz; + + d0 = p0[0] * v0[0] + p0[1] * v0[1] + p0[2] * v0[2] + p0[3]; + d1 = p1[0] * v0[0] + p1[1] * v0[1] + p1[2] * v0[2] + p1[3]; + d2 = p0[0] * v1[0] + p0[1] * v1[1] + p0[2] * v1[2] + p0[3]; + d3 = p1[0] * v1[0] + p1[1] * v1[1] + p1[2] * v1[2] + p1[3]; + + texCoords[i+0][0] = d0; + texCoords[i+0][1] = d1; + texCoords[i+1][0] = d2; + texCoords[i+1][1] = d3; + + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + bits |= FLOATSIGNBITSET( d2 ) << 8; + bits |= FLOATSIGNBITSET( d3 ) << 9; + + d0 = 1.0f - d0; + d1 = 1.0f - d1; + d2 = 1.0f - d2; + d3 = 1.0f - d3; + + bits |= FLOATSIGNBITSET( d0 ) << 2; + bits |= FLOATSIGNBITSET( d1 ) << 3; + bits |= FLOATSIGNBITSET( d2 ) << 10; + bits |= FLOATSIGNBITSET( d3 ) << 11; + + *(unsigned short *)(cullBits + i) = bits; + } + + if ( numVerts & 1 ) { + byte bits; + float d0, d1; + + const idPlane &p0 = planes[0]; + const idPlane &p1 = planes[1]; + const idVec3 &v0 = verts[numVerts - 1].xyz; + + d0 = p0[0] * v0[0] + p0[1] * v0[1] + p0[2] * v0[2] + p0[3]; + d1 = p1[0] * v0[0] + p1[1] * v0[1] + p1[2] * v0[2] + p1[3]; + + texCoords[i][0] = d0; + texCoords[i][1] = d1; + + bits = FLOATSIGNBITSET( d0 ) << 0; + bits |= FLOATSIGNBITSET( d1 ) << 1; + + d0 = 1.0f - d0; + d1 = 1.0f - d1; + + bits |= FLOATSIGNBITSET( d0 ) << 2; + bits |= FLOATSIGNBITSET( d1 ) << 3; + + cullBits[numVerts - 1] = bits; + } + +#endif +} + +/* +============ +idSIMD_SSE::DeriveTriPlanes +============ +*/ +void VPCALL idSIMD_SSE::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { +#if 1 + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + + __asm { + mov eax, numIndexes + shl eax, 2 + mov esi, verts + mov edi, indexes + mov edx, planes + + add edi, eax + neg eax + + add eax, 4*12 + jge done4 + + loopPlane4: + mov ebx, [edi+eax-4*12+4] + imul ebx, DRAWVERT_SIZE + mov ecx, [edi+eax-4*12+0] + imul ecx, DRAWVERT_SIZE + + movss xmm0, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + + movss xmm1, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + + movss xmm2, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + mov ebx, [edi+eax-4*12+8] + imul ebx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm3, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm3, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + + movss xmm4, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm4, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + + movss xmm5, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm5, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + mov ebx, [edi+eax-3*12+4] + imul ebx, DRAWVERT_SIZE + mov ecx, [edi+eax-3*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm0, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm1, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm2, xmm6 + + mov ebx, [edi+eax-3*12+8] + imul ebx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm3, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm4, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm5, xmm7 + + mov ebx, [edi+eax-2*12+4] + imul ebx, DRAWVERT_SIZE + mov ecx, [edi+eax-2*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm0, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm1, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm2, xmm6 + + mov ebx, [edi+eax-2*12+8] + imul ebx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm3, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm4, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm5, xmm7 + + mov ebx, [edi+eax-1*12+4] + imul ebx, DRAWVERT_SIZE + mov ecx, [edi+eax-1*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) + shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm0, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm1, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm2, xmm6 + + mov ebx, [edi+eax-1*12+8] + imul ebx, DRAWVERT_SIZE + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + movss xmm3, xmm7 + + movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + movss xmm4, xmm6 + + movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + movss xmm5, xmm7 + + movaps xmm6, xmm4 + mulps xmm6, xmm2 + movaps xmm7, xmm5 + mulps xmm7, xmm1 + subps xmm6, xmm7 + + mulps xmm5, xmm0 + mulps xmm2, xmm3 + subps xmm5, xmm2 + + mulps xmm3, xmm1 + mulps xmm4, xmm0 + subps xmm3, xmm4 + + movaps xmm0, xmm6 + mulps xmm6, xmm6 + movaps xmm1, xmm5 + mulps xmm5, xmm5 + movaps xmm2, xmm3 + mulps xmm3, xmm3 + + addps xmm3, xmm5 + addps xmm3, xmm6 + rsqrtps xmm3, xmm3 + + add edx, 4*16 + mov ecx, [edi+eax-1*12+0] + imul ecx, DRAWVERT_SIZE + + mulps xmm0, xmm3 + mulps xmm1, xmm3 + mulps xmm2, xmm3 + + movss [edx-1*16+0], xmm0 + movss [edx-1*16+4], xmm1 + movss [edx-1*16+8], xmm2 + + mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + xorps xmm0, SIMD_SP_singleSignBitMask + subss xmm0, xmm1 + subss xmm0, xmm2 + movss [edx-1*16+12], xmm0 + + mov ecx, [edi+eax-2*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [edx-2*16+0], xmm0 + movss [edx-2*16+4], xmm1 + movss [edx-2*16+8], xmm2 + + mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + xorps xmm0, SIMD_SP_singleSignBitMask + subss xmm0, xmm1 + subss xmm0, xmm2 + movss [edx-2*16+12], xmm0 + + mov ecx, [edi+eax-3*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [edx-3*16+0], xmm0 + movss [edx-3*16+4], xmm1 + movss [edx-3*16+8], xmm2 + + mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + xorps xmm0, SIMD_SP_singleSignBitMask + subss xmm0, xmm1 + subss xmm0, xmm2 + movss [edx-3*16+12], xmm0 + + mov ecx, [edi+eax-4*12+0] + imul ecx, DRAWVERT_SIZE + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [edx-4*16+0], xmm0 + movss [edx-4*16+4], xmm1 + movss [edx-4*16+8], xmm2 + + mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + xorps xmm0, SIMD_SP_singleSignBitMask + subss xmm0, xmm1 + subss xmm0, xmm2 + movss [edx-4*16+12], xmm0 + + add eax, 4*12 + jle loopPlane4 + + done4: + + sub eax, 4*12 + jge done + + loopPlane1: + mov ebx, [edi+eax+4] + imul ebx, DRAWVERT_SIZE + mov ecx, [edi+eax+0] + imul ecx, DRAWVERT_SIZE + + movss xmm0, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + + movss xmm1, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + + movss xmm2, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + mov ebx, [edi+eax+8] + imul ebx, DRAWVERT_SIZE + + movss xmm3, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] + subss xmm3, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + + movss xmm4, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] + subss xmm4, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + + movss xmm5, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] + subss xmm5, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + movss xmm6, xmm4 + mulss xmm6, xmm2 + movss xmm7, xmm5 + mulss xmm7, xmm1 + subss xmm6, xmm7 + + mulss xmm5, xmm0 + mulss xmm2, xmm3 + subss xmm5, xmm2 + + mulss xmm3, xmm1 + mulss xmm4, xmm0 + subss xmm3, xmm4 + + movss xmm0, xmm6 + mulss xmm6, xmm6 + movss xmm1, xmm5 + mulss xmm5, xmm5 + movss xmm2, xmm3 + mulss xmm3, xmm3 + + addss xmm3, xmm5 + addss xmm3, xmm6 + rsqrtss xmm3, xmm3 + + add edx, 1*16 + + mulss xmm0, xmm3 + mulss xmm1, xmm3 + mulss xmm2, xmm3 + + movss [edx-1*16+0], xmm0 + movss [edx-1*16+4], xmm1 + movss [edx-1*16+8], xmm2 + + mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] + mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] + mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] + + xorps xmm0, SIMD_SP_singleSignBitMask + subss xmm0, xmm1 + subss xmm0, xmm2 + movss [edx-1*16+12], xmm0 + + add eax, 1*12 + jl loopPlane1 + + done: + } + +#else + + int i, j; + + for ( i = 0; i <= numIndexes - 12; i += 12 ) { + ALIGN16( float d0[4] ); + ALIGN16( float d1[4] ); + ALIGN16( float d2[4] ); + ALIGN16( float d3[4] ); + ALIGN16( float d4[4] ); + ALIGN16( float d5[4] ); + ALIGN16( float n0[4] ); + ALIGN16( float n1[4] ); + ALIGN16( float n2[4] ); + + for ( j = 0; j < 4; j++ ) { + const idDrawVert *a, *b, *c; + + a = verts + indexes[i + j * 3 + 0]; + b = verts + indexes[i + j * 3 + 1]; + c = verts + indexes[i + j * 3 + 2]; + + d0[j] = b->xyz[0] - a->xyz[0]; + d1[j] = b->xyz[1] - a->xyz[1]; + d2[j] = b->xyz[2] - a->xyz[2]; + + d3[j] = c->xyz[0] - a->xyz[0]; + d4[j] = c->xyz[1] - a->xyz[1]; + d5[j] = c->xyz[2] - a->xyz[2]; + } + + ALIGN16( float tmp[4] ); + + n0[0] = d4[0] * d2[0]; + n0[1] = d4[1] * d2[1]; + n0[2] = d4[2] * d2[2]; + n0[3] = d4[3] * d2[3]; + + n0[0] -= d5[0] * d1[0]; + n0[1] -= d5[1] * d1[1]; + n0[2] -= d5[2] * d1[2]; + n0[3] -= d5[3] * d1[3]; + + n1[0] = d5[0] * d0[0]; + n1[1] = d5[1] * d0[1]; + n1[2] = d5[2] * d0[2]; + n1[3] = d5[3] * d0[3]; + + n1[0] -= d3[0] * d2[0]; + n1[1] -= d3[1] * d2[1]; + n1[2] -= d3[2] * d2[2]; + n1[3] -= d3[3] * d2[3]; + + n2[0] = d3[0] * d1[0]; + n2[1] = d3[1] * d1[1]; + n2[2] = d3[2] * d1[2]; + n2[3] = d3[3] * d1[3]; + + n2[0] -= d4[0] * d0[0]; + n2[1] -= d4[1] * d0[1]; + n2[2] -= d4[2] * d0[2]; + n2[3] -= d4[3] * d0[3]; + + tmp[0] = n0[0] * n0[0]; + tmp[1] = n0[1] * n0[1]; + tmp[2] = n0[2] * n0[2]; + tmp[3] = n0[3] * n0[3]; + + tmp[0] += n1[0] * n1[0]; + tmp[1] += n1[1] * n1[1]; + tmp[2] += n1[2] * n1[2]; + tmp[3] += n1[3] * n1[3]; + + tmp[0] += n2[0] * n2[0]; + tmp[1] += n2[1] * n2[1]; + tmp[2] += n2[2] * n2[2]; + tmp[3] += n2[3] * n2[3]; + + tmp[0] = idMath::RSqrt( tmp[0] ); + tmp[1] = idMath::RSqrt( tmp[1] ); + tmp[2] = idMath::RSqrt( tmp[2] ); + tmp[3] = idMath::RSqrt( tmp[3] ); + + n0[0] *= tmp[0]; + n0[1] *= tmp[1]; + n0[2] *= tmp[2]; + n0[3] *= tmp[3]; + + n1[0] *= tmp[0]; + n1[1] *= tmp[1]; + n1[2] *= tmp[2]; + n1[3] *= tmp[3]; + + n2[0] *= tmp[0]; + n2[1] *= tmp[1]; + n2[2] *= tmp[2]; + n2[3] *= tmp[3]; + + + for ( j = 0; j < 4; j++ ) { + const idDrawVert *a; + + a = verts + indexes[i + j * 3]; + + planes->Normal()[0] = n0[j]; + planes->Normal()[1] = n1[j]; + planes->Normal()[2] = n2[j]; + planes->FitThroughPoint( a->xyz ); + planes++; + } + } + + for ( ; i < numIndexes; i += 3 ) { + const idDrawVert *a, *b, *c; + float d0, d1, d2, d3, d4, d5; + float n0, n1, n2; + + a = verts + indexes[i + 0]; + b = verts + indexes[i + 1]; + c = verts + indexes[i + 2]; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + + d3 = c->xyz[0] - a->xyz[0]; + d4 = c->xyz[1] - a->xyz[1]; + d5 = c->xyz[2] - a->xyz[2]; + + float tmp; + + n0 = d4 * d2 - d5 * d1; + n1 = d5 * d0 - d3 * d2; + n2 = d3 * d1 - d4 * d0; + + tmp = idMath::RSqrt( n0 * n0 + n1 * n1 + n2 * n2 ); + + n0 *= tmp; + n1 *= tmp; + n2 *= tmp; + + planes->Normal()[0] = n0; + planes->Normal()[1] = n1; + planes->Normal()[2] = n2; + planes->FitThroughPoint( a->xyz ); + planes++; + } + +#endif +} + +/* +============ +idSIMD_SSE::DeriveTangents +============ +*/ +//#define REFINE_TANGENT_SQUAREROOT +#define FIX_DEGENERATE_TANGENT + +void VPCALL idSIMD_SSE::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + int i; + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); + + assert( planes != NULL ); + assert( verts != NULL ); + assert( numVerts >= 0 ); + +#ifdef REFINE_TANGENT_SQUAREROOT + __asm { + movaps xmm6, SIMD_SP_rsqrt_c0 + movaps xmm7, SIMD_SP_rsqrt_c1 + } +#endif + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + for ( i = 0; i <= numIndexes - 12; i += 12 ) { + idDrawVert *a, *b, *c; + ALIGN16( unsigned long signBit[4] ); + ALIGN16( float d0[4] ); + ALIGN16( float d1[4] ); + ALIGN16( float d2[4] ); + ALIGN16( float d3[4] ); + ALIGN16( float d4[4] ); + ALIGN16( float d5[4] ); + ALIGN16( float d6[4] ); + ALIGN16( float d7[4] ); + ALIGN16( float d8[4] ); + ALIGN16( float d9[4] ); + ALIGN16( float n0[4] ); + ALIGN16( float n1[4] ); + ALIGN16( float n2[4] ); + ALIGN16( float t0[4] ); + ALIGN16( float t1[4] ); + ALIGN16( float t2[4] ); + ALIGN16( float t3[4] ); + ALIGN16( float t4[4] ); + ALIGN16( float t5[4] ); + + for ( int j = 0; j < 4; j++ ) { + + a = verts + indexes[i + j * 3 + 0]; + b = verts + indexes[i + j * 3 + 1]; + c = verts + indexes[i + j * 3 + 2]; + + d0[j] = b->xyz[0] - a->xyz[0]; + d1[j] = b->xyz[1] - a->xyz[1]; + d2[j] = b->xyz[2] - a->xyz[2]; + d3[j] = b->st[0] - a->st[0]; + d4[j] = b->st[1] - a->st[1]; + + d5[j] = c->xyz[0] - a->xyz[0]; + d6[j] = c->xyz[1] - a->xyz[1]; + d7[j] = c->xyz[2] - a->xyz[2]; + d8[j] = c->st[0] - a->st[0]; + d9[j] = c->st[1] - a->st[1]; + } + +#if 1 + + __asm { + // normal + movaps xmm0, d6 + mulps xmm0, d2 + movaps xmm1, d7 + mulps xmm1, d1 + subps xmm0, xmm1 + + movaps xmm1, d7 + mulps xmm1, d0 + movaps xmm2, d5 + mulps xmm2, d2 + subps xmm1, xmm2 + + movaps xmm2, d5 + mulps xmm2, d1 + movaps xmm3, d6 + mulps xmm3, d0 + subps xmm2, xmm3 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + mulps xmm0, xmm3 + movaps n0, xmm0 + mulps xmm1, xmm3 + movaps n1, xmm1 + mulps xmm2, xmm3 + movaps n2, xmm2 + + // area sign bit + movaps xmm0, d3 + mulps xmm0, d9 + movaps xmm1, d4 + mulps xmm1, d8 + subps xmm0, xmm1 + andps xmm0, SIMD_SP_signBitMask + movaps signBit, xmm0 + + // first tangent + movaps xmm0, d0 + mulps xmm0, d9 + movaps xmm1, d4 + mulps xmm1, d5 + subps xmm0, xmm1 + + movaps xmm1, d1 + mulps xmm1, d9 + movaps xmm2, d4 + mulps xmm2, d6 + subps xmm1, xmm2 + + movaps xmm2, d2 + mulps xmm2, d9 + movaps xmm3, d4 + mulps xmm3, d7 + subps xmm2, xmm3 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + xorps xmm3, signBit + + mulps xmm0, xmm3 + movaps t0, xmm0 + mulps xmm1, xmm3 + movaps t1, xmm1 + mulps xmm2, xmm3 + movaps t2, xmm2 + + // second tangent + movaps xmm0, d3 + mulps xmm0, d5 + movaps xmm1, d0 + mulps xmm1, d8 + subps xmm0, xmm1 + + movaps xmm1, d3 + mulps xmm1, d6 + movaps xmm2, d1 + mulps xmm2, d8 + subps xmm1, xmm2 + + movaps xmm2, d3 + mulps xmm2, d7 + movaps xmm3, d2 + mulps xmm3, d8 + subps xmm2, xmm3 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + xorps xmm3, signBit + + mulps xmm0, xmm3 + movaps t3, xmm0 + mulps xmm1, xmm3 + movaps t4, xmm1 + mulps xmm2, xmm3 + movaps t5, xmm2 + } + +#else + + ALIGN16( float tmp[4] ); + + // normal + n0[0] = d6[0] * d2[0]; + n0[1] = d6[1] * d2[1]; + n0[2] = d6[2] * d2[2]; + n0[3] = d6[3] * d2[3]; + + n0[0] -= d7[0] * d1[0]; + n0[1] -= d7[1] * d1[1]; + n0[2] -= d7[2] * d1[2]; + n0[3] -= d7[3] * d1[3]; + + n1[0] = d7[0] * d0[0]; + n1[1] = d7[1] * d0[1]; + n1[2] = d7[2] * d0[2]; + n1[3] = d7[3] * d0[3]; + + n1[0] -= d5[0] * d2[0]; + n1[1] -= d5[1] * d2[1]; + n1[2] -= d5[2] * d2[2]; + n1[3] -= d5[3] * d2[3]; + + n2[0] = d5[0] * d1[0]; + n2[1] = d5[1] * d1[1]; + n2[2] = d5[2] * d1[2]; + n2[3] = d5[3] * d1[3]; + + n2[0] -= d6[0] * d0[0]; + n2[1] -= d6[1] * d0[1]; + n2[2] -= d6[2] * d0[2]; + n2[3] -= d6[3] * d0[3]; + + tmp[0] = n0[0] * n0[0]; + tmp[1] = n0[1] * n0[1]; + tmp[2] = n0[2] * n0[2]; + tmp[3] = n0[3] * n0[3]; + + tmp[0] += n1[0] * n1[0]; + tmp[1] += n1[1] * n1[1]; + tmp[2] += n1[2] * n1[2]; + tmp[3] += n1[3] * n1[3]; + + tmp[0] += n2[0] * n2[0]; + tmp[1] += n2[1] * n2[1]; + tmp[2] += n2[2] * n2[2]; + tmp[3] += n2[3] * n2[3]; + + tmp[0] = idMath::RSqrt( tmp[0] ); + tmp[1] = idMath::RSqrt( tmp[1] ); + tmp[2] = idMath::RSqrt( tmp[2] ); + tmp[3] = idMath::RSqrt( tmp[3] ); + + n0[0] *= tmp[0]; + n0[1] *= tmp[1]; + n0[2] *= tmp[2]; + n0[3] *= tmp[3]; + + n1[0] *= tmp[0]; + n1[1] *= tmp[1]; + n1[2] *= tmp[2]; + n1[3] *= tmp[3]; + + n2[0] *= tmp[0]; + n2[1] *= tmp[1]; + n2[2] *= tmp[2]; + n2[3] *= tmp[3]; + + // area sign bit + tmp[0] = d3[0] * d9[0]; + tmp[1] = d3[1] * d9[1]; + tmp[2] = d3[2] * d9[2]; + tmp[3] = d3[3] * d9[3]; + + tmp[0] -= d4[0] * d8[0]; + tmp[1] -= d4[1] * d8[1]; + tmp[2] -= d4[2] * d8[2]; + tmp[3] -= d4[3] * d8[3]; + + signBit[0] = ( *(unsigned long *)&tmp[0] ) & ( 1 << 31 ); + signBit[1] = ( *(unsigned long *)&tmp[1] ) & ( 1 << 31 ); + signBit[2] = ( *(unsigned long *)&tmp[2] ) & ( 1 << 31 ); + signBit[3] = ( *(unsigned long *)&tmp[3] ) & ( 1 << 31 ); + + // first tangent + t0[0] = d0[0] * d9[0]; + t0[1] = d0[1] * d9[1]; + t0[2] = d0[2] * d9[2]; + t0[3] = d0[3] * d9[3]; + + t0[0] -= d4[0] * d5[0]; + t0[1] -= d4[1] * d5[1]; + t0[2] -= d4[2] * d5[2]; + t0[3] -= d4[3] * d5[3]; + + t1[0] = d1[0] * d9[0]; + t1[1] = d1[1] * d9[1]; + t1[2] = d1[2] * d9[2]; + t1[3] = d1[3] * d9[3]; + + t1[0] -= d4[0] * d6[0]; + t1[1] -= d4[1] * d6[1]; + t1[2] -= d4[2] * d6[2]; + t1[3] -= d4[3] * d6[3]; + + t2[0] = d2[0] * d9[0]; + t2[1] = d2[1] * d9[1]; + t2[2] = d2[2] * d9[2]; + t2[3] = d2[3] * d9[3]; + + t2[0] -= d4[0] * d7[0]; + t2[1] -= d4[1] * d7[1]; + t2[2] -= d4[2] * d7[2]; + t2[3] -= d4[3] * d7[3]; + + tmp[0] = t0[0] * t0[0]; + tmp[1] = t0[1] * t0[1]; + tmp[2] = t0[2] * t0[2]; + tmp[3] = t0[3] * t0[3]; + + tmp[0] += t1[0] * t1[0]; + tmp[1] += t1[1] * t1[1]; + tmp[2] += t1[2] * t1[2]; + tmp[3] += t1[3] * t1[3]; + + tmp[0] += t2[0] * t2[0]; + tmp[1] += t2[1] * t2[1]; + tmp[2] += t2[2] * t2[2]; + tmp[3] += t2[3] * t2[3]; + + tmp[0] = idMath::RSqrt( tmp[0] ); + tmp[1] = idMath::RSqrt( tmp[1] ); + tmp[2] = idMath::RSqrt( tmp[2] ); + tmp[3] = idMath::RSqrt( tmp[3] ); + + *(unsigned long *)&tmp[0] ^= signBit[0]; + *(unsigned long *)&tmp[1] ^= signBit[1]; + *(unsigned long *)&tmp[2] ^= signBit[2]; + *(unsigned long *)&tmp[3] ^= signBit[3]; + + t0[0] *= tmp[0]; + t0[1] *= tmp[1]; + t0[2] *= tmp[2]; + t0[3] *= tmp[3]; + + t1[0] *= tmp[0]; + t1[1] *= tmp[1]; + t1[2] *= tmp[2]; + t1[3] *= tmp[3]; + + t2[0] *= tmp[0]; + t2[1] *= tmp[1]; + t2[2] *= tmp[2]; + t2[3] *= tmp[3]; + + // second tangent + t3[0] = d3[0] * d5[0]; + t3[1] = d3[1] * d5[1]; + t3[2] = d3[2] * d5[2]; + t3[3] = d3[3] * d5[3]; + + t3[0] -= d0[0] * d8[0]; + t3[1] -= d0[1] * d8[1]; + t3[2] -= d0[2] * d8[2]; + t3[3] -= d0[3] * d8[3]; + + t4[0] = d3[0] * d6[0]; + t4[1] = d3[1] * d6[1]; + t4[2] = d3[2] * d6[2]; + t4[3] = d3[3] * d6[3]; + + t4[0] -= d1[0] * d8[0]; + t4[1] -= d1[1] * d8[1]; + t4[2] -= d1[2] * d8[2]; + t4[3] -= d1[3] * d8[3]; + + t5[0] = d3[0] * d7[0]; + t5[1] = d3[1] * d7[1]; + t5[2] = d3[2] * d7[2]; + t5[3] = d3[3] * d7[3]; + + t5[0] -= d2[0] * d8[0]; + t5[1] -= d2[1] * d8[1]; + t5[2] -= d2[2] * d8[2]; + t5[3] -= d2[3] * d8[3]; + + tmp[0] = t3[0] * t3[0]; + tmp[1] = t3[1] * t3[1]; + tmp[2] = t3[2] * t3[2]; + tmp[3] = t3[3] * t3[3]; + + tmp[0] += t4[0] * t4[0]; + tmp[1] += t4[1] * t4[1]; + tmp[2] += t4[2] * t4[2]; + tmp[3] += t4[3] * t4[3]; + + tmp[0] += t5[0] * t5[0]; + tmp[1] += t5[1] * t5[1]; + tmp[2] += t5[2] * t5[2]; + tmp[3] += t5[3] * t5[3]; + + tmp[0] = idMath::RSqrt( tmp[0] ); + tmp[1] = idMath::RSqrt( tmp[1] ); + tmp[2] = idMath::RSqrt( tmp[2] ); + tmp[3] = idMath::RSqrt( tmp[3] ); + + *(unsigned long *)&tmp[0] ^= signBit[0]; + *(unsigned long *)&tmp[1] ^= signBit[1]; + *(unsigned long *)&tmp[2] ^= signBit[2]; + *(unsigned long *)&tmp[3] ^= signBit[3]; + + t3[0] *= tmp[0]; + t3[1] *= tmp[1]; + t3[2] *= tmp[2]; + t3[3] *= tmp[3]; + + t4[0] *= tmp[0]; + t4[1] *= tmp[1]; + t4[2] *= tmp[2]; + t4[3] *= tmp[3]; + + t5[0] *= tmp[0]; + t5[1] *= tmp[1]; + t5[2] *= tmp[2]; + t5[3] *= tmp[3]; + +#endif + + for ( int j = 0; j < 4; j++ ) { + + const int v0 = indexes[i + j * 3 + 0]; + const int v1 = indexes[i + j * 3 + 1]; + const int v2 = indexes[i + j * 3 + 2]; + + a = verts + v0; + b = verts + v1; + c = verts + v2; + + planes->Normal()[0] = n0[j]; + planes->Normal()[1] = n1[j]; + planes->Normal()[2] = n2[j]; + planes->FitThroughPoint( a->xyz ); + planes++; + + if ( used[v0] ) { + a->normal[0] += n0[j]; + a->normal[1] += n1[j]; + a->normal[2] += n2[j]; + + a->tangents[0][0] += t0[j]; + a->tangents[0][1] += t1[j]; + a->tangents[0][2] += t2[j]; + + a->tangents[1][0] += t3[j]; + a->tangents[1][1] += t4[j]; + a->tangents[1][2] += t5[j]; + } else { + a->normal[0] = n0[j]; + a->normal[1] = n1[j]; + a->normal[2] = n2[j]; + + a->tangents[0][0] = t0[j]; + a->tangents[0][1] = t1[j]; + a->tangents[0][2] = t2[j]; + + a->tangents[1][0] = t3[j]; + a->tangents[1][1] = t4[j]; + a->tangents[1][2] = t5[j]; + + used[v0] = true; + } + + if ( used[v1] ) { + b->normal[0] += n0[j]; + b->normal[1] += n1[j]; + b->normal[2] += n2[j]; + + b->tangents[0][0] += t0[j]; + b->tangents[0][1] += t1[j]; + b->tangents[0][2] += t2[j]; + + b->tangents[1][0] += t3[j]; + b->tangents[1][1] += t4[j]; + b->tangents[1][2] += t5[j]; + } else { + b->normal[0] = n0[j]; + b->normal[1] = n1[j]; + b->normal[2] = n2[j]; + + b->tangents[0][0] = t0[j]; + b->tangents[0][1] = t1[j]; + b->tangents[0][2] = t2[j]; + + b->tangents[1][0] = t3[j]; + b->tangents[1][1] = t4[j]; + b->tangents[1][2] = t5[j]; + + used[v1] = true; + } + + if ( used[v2] ) { + c->normal[0] += n0[j]; + c->normal[1] += n1[j]; + c->normal[2] += n2[j]; + + c->tangents[0][0] += t0[j]; + c->tangents[0][1] += t1[j]; + c->tangents[0][2] += t2[j]; + + c->tangents[1][0] += t3[j]; + c->tangents[1][1] += t4[j]; + c->tangents[1][2] += t5[j]; + } else { + c->normal[0] = n0[j]; + c->normal[1] = n1[j]; + c->normal[2] = n2[j]; + + c->tangents[0][0] = t0[j]; + c->tangents[0][1] = t1[j]; + c->tangents[0][2] = t2[j]; + + c->tangents[1][0] = t3[j]; + c->tangents[1][1] = t4[j]; + c->tangents[1][2] = t5[j]; + + used[v2] = true; + } + } + } + + for ( ; i < numIndexes; i += 3 ) { + idDrawVert *a, *b, *c; + ALIGN16( unsigned long signBit[4] ); + float d0, d1, d2, d3, d4; + float d5, d6, d7, d8, d9; + float n0, n1, n2; + float t0, t1, t2; + float t3, t4, t5; + + const int v0 = indexes[i + 0]; + const int v1 = indexes[i + 1]; + const int v2 = indexes[i + 2]; + + a = verts + v0; + b = verts + v1; + c = verts + v2; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + d3 = b->st[0] - a->st[0]; + d4 = b->st[1] - a->st[1]; + + d5 = c->xyz[0] - a->xyz[0]; + d6 = c->xyz[1] - a->xyz[1]; + d7 = c->xyz[2] - a->xyz[2]; + d8 = c->st[0] - a->st[0]; + d9 = c->st[1] - a->st[1]; + +#if 1 + + __asm { + // normal + movss xmm0, d6 + mulss xmm0, d2 + movss xmm1, d7 + mulss xmm1, d1 + subss xmm0, xmm1 + + movss xmm1, d7 + mulss xmm1, d0 + movss xmm2, d5 + mulss xmm2, d2 + subss xmm1, xmm2 + + movss xmm2, d5 + mulss xmm2, d1 + movss xmm3, d6 + mulss xmm3, d0 + subss xmm2, xmm3 + + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + mulss xmm0, xmm3 + movss n0, xmm0 + mulss xmm1, xmm3 + movss n1, xmm1 + mulss xmm2, xmm3 + movss n2, xmm2 + + // area sign bit + movss xmm0, d3 + mulss xmm0, d9 + movss xmm1, d4 + mulss xmm1, d8 + subss xmm0, xmm1 + andps xmm0, SIMD_SP_signBitMask + movaps signBit, xmm0 + + // first tangent + movss xmm0, d0 + mulss xmm0, d9 + movss xmm1, d4 + mulss xmm1, d5 + subss xmm0, xmm1 + + movss xmm1, d1 + mulss xmm1, d9 + movss xmm2, d4 + mulss xmm2, d6 + subss xmm1, xmm2 + + movss xmm2, d2 + mulss xmm2, d9 + movss xmm3, d4 + mulss xmm3, d7 + subss xmm2, xmm3 + + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + xorps xmm3, signBit + + mulss xmm0, xmm3 + movss t0, xmm0 + mulss xmm1, xmm3 + movss t1, xmm1 + mulss xmm2, xmm3 + movss t2, xmm2 + + // second tangent + movss xmm0, d3 + mulss xmm0, d5 + movss xmm1, d0 + mulss xmm1, d8 + subss xmm0, xmm1 + + movss xmm1, d3 + mulss xmm1, d6 + movss xmm2, d1 + mulss xmm2, d8 + subss xmm1, xmm2 + + movss xmm2, d3 + mulss xmm2, d7 + movss xmm3, d2 + mulss xmm3, d8 + subss xmm2, xmm3 + + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef FIX_DEGENERATE_TANGENT + xorps xmm4, xmm4 + cmpeqps xmm4, xmm3 + andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number + andps xmm3, SIMD_SP_absMask // make sure the values are positive + orps xmm3, xmm4 +#endif + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + xorps xmm3, signBit + + mulss xmm0, xmm3 + movss t3, xmm0 + mulss xmm1, xmm3 + movss t4, xmm1 + mulss xmm2, xmm3 + movss t5, xmm2 + } + +#else + + float tmp; + + // normal + n0 = d6 * d2 - d7 * d1; + n1 = d7 * d0 - d5 * d2; + n2 = d5 * d1 - d6 * d0; + + tmp = idMath::RSqrt( n0 * n0 + n1 * n1 + n2 * n2 ); + + n0 *= tmp; + n1 *= tmp; + n2 *= tmp; + + // area sign bit + tmp = d3 * d9 - d4 * d8; + signBit[0] = ( *(unsigned long *)&tmp ) & ( 1 << 31 ); + + // first tangent + t0 = d0 * d9 - d4 * d5; + t1 = d1 * d9 - d4 * d6; + t2 = d2 * d9 - d4 * d7; + + tmp = idMath::RSqrt( t0 * t0 + t1 * t1 + t2 * t2 ); + *(unsigned long *)&tmp ^= signBit[0]; + + t0 *= tmp; + t1 *= tmp; + t2 *= tmp; + + // second tangent + t3 = d3 * d5 - d0 * d8; + t4 = d3 * d6 - d1 * d8; + t5 = d3 * d7 - d2 * d8; + + tmp = idMath::RSqrt( t3 * t3 + t4 * t4 + t5 * t5 ); + *(unsigned long *)&tmp ^= signBit[0]; + + t3 *= tmp; + t4 *= tmp; + t5 *= tmp; + +#endif + + planes->Normal()[0] = n0; + planes->Normal()[1] = n1; + planes->Normal()[2] = n2; + planes->FitThroughPoint( a->xyz ); + planes++; + + if ( used[v0] ) { + a->normal[0] += n0; + a->normal[1] += n1; + a->normal[2] += n2; + + a->tangents[0][0] += t0; + a->tangents[0][1] += t1; + a->tangents[0][2] += t2; + + a->tangents[1][0] += t3; + a->tangents[1][1] += t4; + a->tangents[1][2] += t5; + } else { + a->normal[0] = n0; + a->normal[1] = n1; + a->normal[2] = n2; + + a->tangents[0][0] = t0; + a->tangents[0][1] = t1; + a->tangents[0][2] = t2; + + a->tangents[1][0] = t3; + a->tangents[1][1] = t4; + a->tangents[1][2] = t5; + + used[v0] = true; + } + + if ( used[v1] ) { + b->normal[0] += n0; + b->normal[1] += n1; + b->normal[2] += n2; + + b->tangents[0][0] += t0; + b->tangents[0][1] += t1; + b->tangents[0][2] += t2; + + b->tangents[1][0] += t3; + b->tangents[1][1] += t4; + b->tangents[1][2] += t5; + } else { + b->normal[0] = n0; + b->normal[1] = n1; + b->normal[2] = n2; + + b->tangents[0][0] = t0; + b->tangents[0][1] = t1; + b->tangents[0][2] = t2; + + b->tangents[1][0] = t3; + b->tangents[1][1] = t4; + b->tangents[1][2] = t5; + + used[v1] = true; + } + + if ( used[v2] ) { + c->normal[0] += n0; + c->normal[1] += n1; + c->normal[2] += n2; + + c->tangents[0][0] += t0; + c->tangents[0][1] += t1; + c->tangents[0][2] += t2; + + c->tangents[1][0] += t3; + c->tangents[1][1] += t4; + c->tangents[1][2] += t5; + } else { + c->normal[0] = n0; + c->normal[1] = n1; + c->normal[2] = n2; + + c->tangents[0][0] = t0; + c->tangents[0][1] = t1; + c->tangents[0][2] = t2; + + c->tangents[1][0] = t3; + c->tangents[1][1] = t4; + c->tangents[1][2] = t5; + + used[v2] = true; + } + } +} + +/* +============ +idSIMD_SSE::DeriveUnsmoothedTangents +============ +*/ +#define DERIVE_UNSMOOTHED_BITANGENT + +void VPCALL idSIMD_SSE::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { + int i, j; + + for ( i = 0; i <= numVerts - 4; i += 4 ) { + ALIGN16( float s0[4] ); + ALIGN16( float s1[4] ); + ALIGN16( float s2[4] ); + ALIGN16( float d0[4] ); + ALIGN16( float d1[4] ); + ALIGN16( float d2[4] ); + ALIGN16( float d3[4] ); + ALIGN16( float d4[4] ); + ALIGN16( float d5[4] ); + ALIGN16( float d6[4] ); + ALIGN16( float d7[4] ); + ALIGN16( float d8[4] ); + ALIGN16( float d9[4] ); + ALIGN16( float n0[4] ); + ALIGN16( float n1[4] ); + ALIGN16( float n2[4] ); + ALIGN16( float t0[4] ); + ALIGN16( float t1[4] ); + ALIGN16( float t2[4] ); + ALIGN16( float t3[4] ); + ALIGN16( float t4[4] ); + ALIGN16( float t5[4] ); + + for ( j = 0; j < 4; j++ ) { + const idDrawVert *a, *b, *c; + + const dominantTri_s &dt = dominantTris[i+j]; + + s0[j] = dt.normalizationScale[0]; + s1[j] = dt.normalizationScale[1]; + s2[j] = dt.normalizationScale[2]; + + a = verts + i + j; + b = verts + dt.v2; + c = verts + dt.v3; + + d0[j] = b->xyz[0] - a->xyz[0]; + d1[j] = b->xyz[1] - a->xyz[1]; + d2[j] = b->xyz[2] - a->xyz[2]; + d3[j] = b->st[0] - a->st[0]; + d4[j] = b->st[1] - a->st[1]; + + d5[j] = c->xyz[0] - a->xyz[0]; + d6[j] = c->xyz[1] - a->xyz[1]; + d7[j] = c->xyz[2] - a->xyz[2]; + d8[j] = c->st[0] - a->st[0]; + d9[j] = c->st[1] - a->st[1]; + } + +#if 1 + + __asm { + + movaps xmm0, d6 + mulps xmm0, d2 + movaps xmm1, d7 + mulps xmm1, d1 + + movaps xmm2, d7 + mulps xmm2, d0 + movaps xmm3, d5 + mulps xmm3, d2 + + movaps xmm4, d5 + mulps xmm4, d1 + movaps xmm5, d6 + mulps xmm5, d0 + + subps xmm0, xmm1 + subps xmm2, xmm3 + movaps xmm7, s2 + subps xmm4, xmm5 + + mulps xmm0, xmm7 + movaps n0, xmm0 + mulps xmm2, xmm7 + movaps n1, xmm2 + mulps xmm4, xmm7 + movaps n2, xmm4 + + movaps xmm0, d0 + mulps xmm0, d9 + movaps xmm1, d4 + mulps xmm1, d5 + + movaps xmm2, d1 + mulps xmm2, d9 + movaps xmm3, d4 + mulps xmm3, d6 + + movaps xmm4, d2 + mulps xmm4, d9 + movaps xmm5, d4 + mulps xmm5, d7 + + subps xmm0, xmm1 + subps xmm2, xmm3 + movaps xmm7, s0 + subps xmm4, xmm5 + + mulps xmm0, xmm7 + movaps t0, xmm0 + mulps xmm2, xmm7 + movaps t1, xmm2 + mulps xmm4, xmm7 + movaps t2, xmm4 + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + movaps xmm0, d3 + mulps xmm0, d5 + movaps xmm1, d0 + mulps xmm1, d8 + + movaps xmm2, d3 + mulps xmm2, d6 + movaps xmm3, d1 + mulps xmm3, d8 + + movaps xmm4, d3 + mulps xmm4, d7 + movaps xmm5, d2 + mulps xmm5, d8 +#else + movaps xmm0, n2 + mulps xmm0, t1 + movaps xmm1, n1 + mulps xmm1, t2 + + movaps xmm2, n0 + mulps xmm2, t2 + movaps xmm3, n2 + mulps xmm3, t0 + + movaps xmm4, n1 + mulps xmm4, t0 + movaps xmm5, n0 + mulps xmm5, t1 +#endif + subps xmm0, xmm1 + subps xmm2, xmm3 + movaps xmm7, s1 + subps xmm4, xmm5 + + mulps xmm0, xmm7 + movaps t3, xmm0 + mulps xmm2, xmm7 + movaps t4, xmm2 + mulps xmm4, xmm7 + movaps t5, xmm4 + } + +#else + + n0[0] = d6[0] * d2[0]; + n0[1] = d6[1] * d2[1]; + n0[2] = d6[2] * d2[2]; + n0[3] = d6[3] * d2[3]; + + n1[0] = d7[0] * d0[0]; + n1[1] = d7[1] * d0[1]; + n1[2] = d7[2] * d0[2]; + n1[3] = d7[3] * d0[3]; + + n2[0] = d5[0] * d1[0]; + n2[1] = d5[1] * d1[1]; + n2[2] = d5[2] * d1[2]; + n2[3] = d5[3] * d1[3]; + + n0[0] -= d7[0] * d1[0]; + n0[1] -= d7[1] * d1[1]; + n0[2] -= d7[2] * d1[2]; + n0[3] -= d7[3] * d1[3]; + + n1[0] -= d5[0] * d2[0]; + n1[1] -= d5[1] * d2[1]; + n1[2] -= d5[2] * d2[2]; + n1[3] -= d5[3] * d2[3]; + + n2[0] -= d6[0] * d0[0]; + n2[1] -= d6[1] * d0[1]; + n2[2] -= d6[2] * d0[2]; + n2[3] -= d6[3] * d0[3]; + + n0[0] *= s2[0]; + n0[1] *= s2[1]; + n0[2] *= s2[2]; + n0[3] *= s2[3]; + + n1[0] *= s2[0]; + n1[1] *= s2[1]; + n1[2] *= s2[2]; + n1[3] *= s2[3]; + + n2[0] *= s2[0]; + n2[1] *= s2[1]; + n2[2] *= s2[2]; + n2[3] *= s2[3]; + + t0[0] = d0[0] * d9[0]; + t0[1] = d0[1] * d9[1]; + t0[2] = d0[2] * d9[2]; + t0[3] = d0[3] * d9[3]; + + t1[0] = d1[0] * d9[0]; + t1[1] = d1[1] * d9[1]; + t1[2] = d1[2] * d9[2]; + t1[3] = d1[3] * d9[3]; + + t2[0] = d2[0] * d9[0]; + t2[1] = d2[1] * d9[1]; + t2[2] = d2[2] * d9[2]; + t2[3] = d2[3] * d9[3]; + + t0[0] -= d4[0] * d5[0]; + t0[1] -= d4[1] * d5[1]; + t0[2] -= d4[2] * d5[2]; + t0[3] -= d4[3] * d5[3]; + + t1[0] -= d4[0] * d6[0]; + t1[1] -= d4[1] * d6[1]; + t1[2] -= d4[2] * d6[2]; + t1[3] -= d4[3] * d6[3]; + + t2[0] -= d4[0] * d7[0]; + t2[1] -= d4[1] * d7[1]; + t2[2] -= d4[2] * d7[2]; + t2[3] -= d4[3] * d7[3]; + + t0[0] *= s0[0]; + t0[1] *= s0[1]; + t0[2] *= s0[2]; + t0[3] *= s0[3]; + + t1[0] *= s0[0]; + t1[1] *= s0[1]; + t1[2] *= s0[2]; + t1[3] *= s0[3]; + + t2[0] *= s0[0]; + t2[1] *= s0[1]; + t2[2] *= s0[2]; + t2[3] *= s0[3]; + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + t3[0] = d3[0] * d5[0]; + t3[1] = d3[1] * d5[1]; + t3[2] = d3[2] * d5[2]; + t3[3] = d3[3] * d5[3]; + + t4[0] = d3[0] * d6[0]; + t4[1] = d3[1] * d6[1]; + t4[2] = d3[2] * d6[2]; + t4[3] = d3[3] * d6[3]; + + t5[0] = d3[0] * d7[0]; + t5[1] = d3[1] * d7[1]; + t5[2] = d3[2] * d7[2]; + t5[3] = d3[3] * d7[3]; + + t3[0] -= d0[0] * d8[0]; + t3[1] -= d0[1] * d8[1]; + t3[2] -= d0[2] * d8[2]; + t3[3] -= d0[3] * d8[3]; + + t4[0] -= d1[0] * d8[0]; + t4[1] -= d1[1] * d8[1]; + t4[2] -= d1[2] * d8[2]; + t4[3] -= d1[3] * d8[3]; + + t5[0] -= d2[0] * d8[0]; + t5[1] -= d2[1] * d8[1]; + t5[2] -= d2[2] * d8[2]; + t5[3] -= d2[3] * d8[3]; +#else + t3[0] = n2[0] * t1[0]; + t3[1] = n2[1] * t1[1]; + t3[2] = n2[2] * t1[2]; + t3[3] = n2[3] * t1[3]; + + t4[0] = n0[0] * t2[0]; + t4[1] = n0[1] * t2[1]; + t4[2] = n0[2] * t2[2]; + t4[3] = n0[3] * t2[3]; + + t5[0] = n1[0] * t0[0]; + t5[1] = n1[1] * t0[1]; + t5[2] = n1[2] * t0[2]; + t5[3] = n1[3] * t0[3]; + + t3[0] -= n1[0] * t2[0]; + t3[1] -= n1[1] * t2[1]; + t3[2] -= n1[2] * t2[2]; + t3[3] -= n1[3] * t2[3]; + + t4[0] -= n2[0] * t0[0]; + t4[1] -= n2[1] * t0[1]; + t4[2] -= n2[2] * t0[2]; + t4[3] -= n2[3] * t0[3]; + + t5[0] -= n0[0] * t1[0]; + t5[1] -= n0[1] * t1[1]; + t5[2] -= n0[2] * t1[2]; + t5[3] -= n0[3] * t1[3]; +#endif + t3[0] *= s1[0]; + t3[1] *= s1[1]; + t3[2] *= s1[2]; + t3[3] *= s1[3]; + + t4[0] *= s1[0]; + t4[1] *= s1[1]; + t4[2] *= s1[2]; + t4[3] *= s1[3]; + + t5[0] *= s1[0]; + t5[1] *= s1[1]; + t5[2] *= s1[2]; + t5[3] *= s1[3]; + +#endif + + for ( j = 0; j < 4; j++ ) { + idDrawVert *a; + + a = verts + i + j; + + a->normal[0] = n0[j]; + a->normal[1] = n1[j]; + a->normal[2] = n2[j]; + + a->tangents[0][0] = t0[j]; + a->tangents[0][1] = t1[j]; + a->tangents[0][2] = t2[j]; + + a->tangents[1][0] = t3[j]; + a->tangents[1][1] = t4[j]; + a->tangents[1][2] = t5[j]; + } + } + + for ( ; i < numVerts; i++ ) { + idDrawVert *a, *b, *c; + float d0, d1, d2, d3, d4; + float d5, d6, d7, d8, d9; + float s0, s1, s2; + float n0, n1, n2; + float t0, t1, t2; + float t3, t4, t5; + + const dominantTri_s &dt = dominantTris[i]; + + s0 = dt.normalizationScale[0]; + s1 = dt.normalizationScale[1]; + s2 = dt.normalizationScale[2]; + + a = verts + i; + b = verts + dt.v2; + c = verts + dt.v3; + + d0 = b->xyz[0] - a->xyz[0]; + d1 = b->xyz[1] - a->xyz[1]; + d2 = b->xyz[2] - a->xyz[2]; + d3 = b->st[0] - a->st[0]; + d4 = b->st[1] - a->st[1]; + + d5 = c->xyz[0] - a->xyz[0]; + d6 = c->xyz[1] - a->xyz[1]; + d7 = c->xyz[2] - a->xyz[2]; + d8 = c->st[0] - a->st[0]; + d9 = c->st[1] - a->st[1]; + +#if 1 + + __asm { + + movss xmm0, d6 + mulss xmm0, d2 + movss xmm1, d7 + mulss xmm1, d1 + + movss xmm2, d7 + mulss xmm2, d0 + movss xmm3, d5 + mulss xmm3, d2 + + movss xmm4, d5 + mulss xmm4, d1 + movss xmm5, d6 + mulss xmm5, d0 + + subss xmm0, xmm1 + subss xmm2, xmm3 + movss xmm7, s2 + subss xmm4, xmm5 + + mulss xmm0, xmm7 + movss n0, xmm0 + mulss xmm2, xmm7 + movss n1, xmm2 + mulss xmm4, xmm7 + movss n2, xmm4 + + movss xmm0, d0 + mulss xmm0, d9 + movss xmm1, d4 + mulss xmm1, d5 + + movss xmm2, d1 + mulss xmm2, d9 + movss xmm3, d4 + mulss xmm3, d6 + + movss xmm4, d2 + mulss xmm4, d9 + movss xmm5, d4 + mulss xmm5, d7 + + subss xmm0, xmm1 + subss xmm2, xmm3 + movss xmm7, s0 + subss xmm4, xmm5 + + mulss xmm0, xmm7 + movss t0, xmm0 + mulss xmm2, xmm7 + movss t1, xmm2 + mulss xmm4, xmm7 + movss t2, xmm4 + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + movss xmm0, d3 + mulss xmm0, d5 + movss xmm1, d0 + mulss xmm1, d8 + + movss xmm2, d3 + mulss xmm2, d6 + movss xmm3, d1 + mulss xmm3, d8 + + movss xmm4, d3 + mulss xmm4, d7 + movss xmm5, d2 + mulss xmm5, d8 +#else + movss xmm0, n2 + mulss xmm0, t1 + movss xmm1, n1 + mulss xmm1, t2 + + movss xmm2, n0 + mulss xmm2, t2 + movss xmm3, n2 + mulss xmm3, t0 + + movss xmm4, n1 + mulss xmm4, t0 + movss xmm5, n0 + mulss xmm5, t1 +#endif + subss xmm0, xmm1 + subss xmm2, xmm3 + movss xmm7, s1 + subss xmm4, xmm5 + + mulss xmm0, xmm7 + movss t3, xmm0 + mulss xmm2, xmm7 + movss t4, xmm2 + mulss xmm4, xmm7 + movss t5, xmm4 + } + +#else + + n0 = s2 * ( d6 * d2 - d7 * d1 ); + n1 = s2 * ( d7 * d0 - d5 * d2 ); + n2 = s2 * ( d5 * d1 - d6 * d0 ); + + t0 = s0 * ( d0 * d9 - d4 * d5 ); + t1 = s0 * ( d1 * d9 - d4 * d6 ); + t2 = s0 * ( d2 * d9 - d4 * d7 ); + +#ifndef DERIVE_UNSMOOTHED_BITANGENT + t3 = s1 * ( d3 * d5 - d0 * d8 ); + t4 = s1 * ( d3 * d6 - d1 * d8 ); + t5 = s1 * ( d3 * d7 - d2 * d8 ); +#else + t3 = s1 * ( n2 * t1 - n1 * t2 ); + t4 = s1 * ( n0 * t2 - n2 * t0 ); + t5 = s1 * ( n1 * t0 - n0 * t1 ); +#endif + +#endif + + a->normal[0] = n0; + a->normal[1] = n1; + a->normal[2] = n2; + + a->tangents[0][0] = t0; + a->tangents[0][1] = t1; + a->tangents[0][2] = t2; + + a->tangents[1][0] = t3; + a->tangents[1][1] = t4; + a->tangents[1][2] = t5; + } +} + +/* +============ +idSIMD_SSE::NormalizeTangents +============ +*/ +void VPCALL idSIMD_SSE::NormalizeTangents( idDrawVert *verts, const int numVerts ) { + ALIGN16( float normal[12] ); + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); + + assert( verts != NULL ); + assert( numVerts >= 0 ); + + __asm { + mov eax, numVerts + test eax, eax + jz done +#ifdef REFINE_TANGENT_SQUAREROOT + movaps xmm6, SIMD_SP_rsqrt_c0 + movaps xmm7, SIMD_SP_rsqrt_c1 +#endif + mov esi, verts + imul eax, DRAWVERT_SIZE + add esi, eax + neg eax + add eax, DRAWVERT_SIZE*4 + jle loopVert4 + + sub eax, DRAWVERT_SIZE*4 + jl loopVert1 + + loopVert4: + + sub eax, DRAWVERT_SIZE*4 + + // normalize 4 idDrawVert::normal + + movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+0] // 0, X, X, X + movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+0] // 0, X, 3, 4 + movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+8] // 5, X, X, X + movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+4] // 5, X, 1, 2 + movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+0] // 6, X, X, X + movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+0] // 6, X, 9, 10 + movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+8] // 11, X, X, X + movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+4] // 11, X, 7, 8 + + movaps xmm1, xmm0 + movaps xmm5, xmm2 + shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 + shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 + shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 + shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + + mulps xmm0, xmm3 + mulps xmm1, xmm3 + mulps xmm2, xmm3 + + // save the 4 idDrawVert::normal to project the tangents + + movaps [normal+ 0], xmm0 + movaps [normal+16], xmm1 + movaps [normal+32], xmm2 + + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+8], xmm2 + + // project and normalize 4 idDrawVert::tangent[0] + + movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+0] // 0, X, X, X + movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+0] // 0, X, 3, 4 + movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+8] // 5, X, X, X + movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+4] // 5, X, 1, 2 + movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+0] // 6, X, X, X + movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+0] // 6, X, 9, 10 + movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+8] // 11, X, X, X + movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+4] // 11, X, 7, 8 + + movaps xmm1, xmm0 + movaps xmm5, xmm2 + shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 + shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 + shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 + shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, [normal+ 0] + mulps xmm4, [normal+16] + mulps xmm5, [normal+32] + addps xmm3, xmm4 + addps xmm3, xmm5 + + movaps xmm4, xmm3 + movaps xmm5, xmm3 + mulps xmm3, [normal+ 0] + mulps xmm4, [normal+16] + mulps xmm5, [normal+32] + subps xmm0, xmm3 + subps xmm1, xmm4 + subps xmm2, xmm5 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + + mulps xmm0, xmm3 + mulps xmm1, xmm3 + mulps xmm2, xmm3 + + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+8], xmm2 + + // project and normalize 4 idDrawVert::tangent[1] + + movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+0] // 0, X, X, X + movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+0] // 0, X, 3, 4 + movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+8] // 5, X, X, X + movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+4] // 5, X, 1, 2 + movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+0] // 6, X, X, X + movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+0] // 6, X, 9, 10 + movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+8] // 11, X, X, X + movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+4] // 11, X, 7, 8 + + movaps xmm1, xmm0 + movaps xmm5, xmm2 + shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 + shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 + shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 + shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 + shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, [normal+ 0] + mulps xmm4, [normal+16] + mulps xmm5, [normal+32] + addps xmm3, xmm4 + addps xmm3, xmm5 + + movaps xmm4, xmm3 + movaps xmm5, xmm3 + mulps xmm3, [normal+ 0] + mulps xmm4, [normal+16] + mulps xmm5, [normal+32] + subps xmm0, xmm3 + subps xmm1, xmm4 + subps xmm2, xmm5 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + movaps xmm5, xmm2 + + mulps xmm3, xmm3 + mulps xmm4, xmm4 + mulps xmm5, xmm5 + addps xmm3, xmm4 + addps xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtps xmm4, xmm3 + mulps xmm3, xmm4 + mulps xmm3, xmm4 + subps xmm3, xmm6 + mulps xmm4, xmm7 + mulps xmm3, xmm4 +#else + rsqrtps xmm3, xmm3 +#endif + + mulps xmm0, xmm3 + mulps xmm1, xmm3 + mulps xmm2, xmm3 + + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+8], xmm2 + + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) + shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+8], xmm2 + + add eax, DRAWVERT_SIZE*8 + + jle loopVert4 + + sub eax, DRAWVERT_SIZE*4 + jge done + + loopVert1: + + // normalize one idDrawVert::normal + + movss xmm0, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + + mulss xmm0, xmm3 + mulss xmm1, xmm3 + mulss xmm2, xmm3 + + movss [esi+eax+DRAWVERT_NORMAL_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_NORMAL_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_NORMAL_OFFSET+8], xmm2 + + // project and normalize one idDrawVert::tangent[0] + + movss xmm0, [esi+eax+DRAWVERT_TANGENT0_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_TANGENT0_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_TANGENT0_OFFSET+8] + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] + mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] + mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] + addss xmm3, xmm4 + addss xmm3, xmm5 + + movss xmm4, xmm3 + movss xmm5, xmm3 + mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] + mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] + mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] + subss xmm0, xmm3 + subss xmm1, xmm4 + subss xmm2, xmm5 + + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + + mulss xmm0, xmm3 + mulss xmm1, xmm3 + mulss xmm2, xmm3 + + movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+8], xmm2 + + // project and normalize one idDrawVert::tangent[1] + + movss xmm0, [esi+eax+DRAWVERT_TANGENT1_OFFSET+0] + movss xmm1, [esi+eax+DRAWVERT_TANGENT1_OFFSET+4] + movss xmm2, [esi+eax+DRAWVERT_TANGENT1_OFFSET+8] + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] + mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] + mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] + addss xmm3, xmm4 + addss xmm3, xmm5 + + movss xmm4, xmm3 + movss xmm5, xmm3 + mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] + mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] + mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] + subss xmm0, xmm3 + subss xmm1, xmm4 + subss xmm2, xmm5 + + movss xmm3, xmm0 + movss xmm4, xmm1 + movss xmm5, xmm2 + + mulss xmm3, xmm3 + mulss xmm4, xmm4 + mulss xmm5, xmm5 + addss xmm3, xmm4 + addss xmm3, xmm5 + +#ifdef REFINE_TANGENT_SQUAREROOT + rsqrtss xmm4, xmm3 + mulss xmm3, xmm4 + mulss xmm3, xmm4 + subss xmm3, xmm6 + mulss xmm4, xmm7 + mulss xmm3, xmm4 +#else + rsqrtss xmm3, xmm3 +#endif + + mulss xmm0, xmm3 + mulss xmm1, xmm3 + mulss xmm2, xmm3 + + movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+0], xmm0 + movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+4], xmm1 + movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+8], xmm2 + + add eax, DRAWVERT_SIZE + + jl loopVert1 + done: + } +} + +/* +============ +idSIMD_SSE::CreateTextureSpaceLightVectors +============ +*/ +void VPCALL idSIMD_SSE::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + for ( int i = numIndexes - 1; i >= 0; i-- ) { + used[indexes[i]] = true; + } + +#if 0 + + __asm { + + mov eax, numVerts + + mov esi, used + add esi, eax + + mov edi, verts + sub edi, DRAWVERT_SIZE + + neg eax + dec eax + + mov ecx, lightOrigin + movss xmm7, [ecx+0] + movhps xmm7, [ecx+4] + + mov ecx, lightVectors + sub ecx, 3*4 + + loopVert: + inc eax + jge done + + add edi, DRAWVERT_SIZE + add ecx, 3*4 + + cmp byte ptr [esi+eax], 0 + je loopVert + + movaps xmm0, xmm7 + movss xmm1, [edi+DRAWVERT_XYZ_OFFSET+0] + movhps xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] + subps xmm0, xmm1 + + // 0, X, 1, 2 + // 3, X, 4, 5 + // 6, X, 7, 8 + + movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+0] + movhps xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+4] + mulps xmm2, xmm0 + + movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] + movhps xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+4] + mulps xmm3, xmm0 + + movaps xmm5, xmm2 // xmm5 = 0, X, 1, 2 + unpcklps xmm5, xmm3 // xmm5 = 0, 3, X, X + unpckhps xmm2, xmm3 // xmm2 = 1, 4, 2, 5 + + movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+0] + movhps xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] + mulps xmm4, xmm0 + + movlhps xmm5, xmm4 // xmm5 = 0, 3, 6, X + movhlps xmm4, xmm2 // xmm4 = 2, 5, 7, 8 + shufps xmm2, xmm4, R_SHUFFLEPS( 0, 1, 3, 2 ) // xmm2 = 2, 5, 8, 7 + + addps xmm5, xmm4 + addps xmm5, xmm2 + movlps [ecx+0], xmm5 + shufps xmm5, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) + movss [ecx+8], xmm5 + + jmp loopVert + + done: + } + +#elif 1 + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + idVec3 lightDir; + + lightDir[0] = lightOrigin[0] - v->xyz[0]; + lightDir[1] = lightOrigin[1] - v->xyz[1]; + lightDir[2] = lightOrigin[2] - v->xyz[2]; + + lightVectors[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; + lightVectors[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; + lightVectors[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; + } + +#elif 1 + + ALIGN16( int usedVertNums[4] ); + ALIGN16( float lightDir0[4] ); + ALIGN16( float lightDir1[4] ); + ALIGN16( float lightDir2[4] ); + ALIGN16( float normal0[4] ); + ALIGN16( float normal1[4] ); + ALIGN16( float normal2[4] ); + ALIGN16( float tangent0[4] ); + ALIGN16( float tangent1[4] ); + ALIGN16( float tangent2[4] ); + ALIGN16( float tangent3[4] ); + ALIGN16( float tangent4[4] ); + ALIGN16( float tangent5[4] ); + idVec3 localLightOrigin = lightOrigin; + + __asm { + + xor ecx, ecx + mov eax, numVerts + + mov esi, used + add esi, eax + + mov edi, verts + sub edi, DRAWVERT_SIZE + + neg eax + dec eax + + loopVert4: + inc eax + jge done4 + + add edi, DRAWVERT_SIZE + + cmp byte ptr [esi+eax], 0 + je loopVert4 + + mov usedVertNums[ecx*4], eax + + inc ecx + cmp ecx, 4 + + movss xmm0, localLightOrigin[0] + movss xmm1, localLightOrigin[4] + movss xmm2, localLightOrigin[8] + + subss xmm0, [edi+DRAWVERT_XYZ_OFFSET+0] + subss xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] + subss xmm2, [edi+DRAWVERT_XYZ_OFFSET+8] + + movss lightDir0[ecx*4-4], xmm0 + movss lightDir1[ecx*4-4], xmm1 + movss lightDir2[ecx*4-4], xmm2 + + movss xmm3, [edi+DRAWVERT_NORMAL_OFFSET+0] + movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] + movss xmm5, [edi+DRAWVERT_NORMAL_OFFSET+8] + + movss normal0[ecx*4-4], xmm3 + movss normal1[ecx*4-4], xmm4 + movss normal2[ecx*4-4], xmm5 + + movss xmm0, [edi+DRAWVERT_TANGENT0_OFFSET+0] + movss xmm1, [edi+DRAWVERT_TANGENT0_OFFSET+4] + movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+8] + + movss tangent0[ecx*4-4], xmm0 + movss tangent1[ecx*4-4], xmm1 + movss tangent2[ecx*4-4], xmm2 + + movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] + movss xmm4, [edi+DRAWVERT_TANGENT1_OFFSET+4] + movss xmm5, [edi+DRAWVERT_TANGENT1_OFFSET+8] + + movss tangent3[ecx*4-4], xmm3 + movss tangent4[ecx*4-4], xmm4 + movss tangent5[ecx*4-4], xmm5 + + jl loopVert4 + + movaps xmm0, lightDir0 + movaps xmm1, lightDir1 + movaps xmm2, lightDir2 + + movaps xmm3, tangent0 + mulps xmm3, xmm0 + movaps xmm4, tangent1 + mulps xmm4, xmm1 + movaps xmm5, tangent2 + mulps xmm5, xmm2 + + addps xmm3, xmm4 + addps xmm5, xmm3 + + movaps xmm3, tangent3 + mulps xmm3, xmm0 + movaps xmm4, tangent4 + mulps xmm4, xmm1 + movaps xmm6, tangent5 + mulps xmm6, xmm2 + + addps xmm3, xmm4 + addps xmm6, xmm3 + + mulps xmm0, normal0 + mulps xmm1, normal1 + mulps xmm2, normal2 + + addps xmm0, xmm1 + addps xmm0, xmm2 + + mov ecx, numVerts + imul ecx, 12 + mov edx, usedVertNums[0] + add ecx, lightVectors + imul edx, 12 + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[4] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + imul edx, 12 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[8] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + imul edx, 12 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[12] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + imul edx, 12 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + + xor ecx, ecx + jmp loopVert4 + + done4: + test ecx, ecx + jz done + xor eax, eax + mov edi, numVerts + imul edi, 12 + add edi, lightVectors + + loopVert1: + movss xmm0, lightDir0[eax*4] + movss xmm1, lightDir1[eax*4] + movss xmm2, lightDir2[eax*4] + + mov edx, usedVertNums[eax*4] + imul edx, 12 + + movss xmm3, tangent0[eax*4] + mulss xmm3, xmm0 + movss xmm4, tangent1[eax*4] + mulss xmm4, xmm1 + movss xmm5, tangent2[eax*4] + mulss xmm5, xmm2 + + addss xmm3, xmm4 + addss xmm5, xmm3 + movss [edi+edx+0], xmm5 + + movss xmm3, tangent3[eax*4] + mulss xmm3, xmm0 + movss xmm4, tangent4[eax*4] + mulss xmm4, xmm1 + movss xmm6, tangent5[eax*4] + mulss xmm6, xmm2 + + addss xmm3, xmm4 + addss xmm6, xmm3 + movss [edi+edx+4], xmm6 + + mulss xmm0, normal0[eax*4] + mulss xmm1, normal1[eax*4] + mulss xmm2, normal2[eax*4] + + addss xmm0, xmm1 + addss xmm0, xmm2 + movss [edi+edx+8], xmm0 + + inc eax + dec ecx + jg loopVert1 + + done: + } + +#else + + ALIGN16( float lightVectors0[4] ); + ALIGN16( float lightVectors1[4] ); + ALIGN16( float lightVectors2[4] ); + int numUsedVerts = 0; + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + + lightDir0[numUsedVerts] = lightOrigin[0] - v->xyz[0]; + lightDir1[numUsedVerts] = lightOrigin[1] - v->xyz[1]; + lightDir2[numUsedVerts] = lightOrigin[2] - v->xyz[2]; + + normal0[numUsedVerts] = v->normal[0]; + normal1[numUsedVerts] = v->normal[1]; + normal2[numUsedVerts] = v->normal[2]; + + tangent0[numUsedVerts] = v->tangents[0][0]; + tangent1[numUsedVerts] = v->tangents[0][1]; + tangent2[numUsedVerts] = v->tangents[0][2]; + + tangent3[numUsedVerts] = v->tangents[1][0]; + tangent4[numUsedVerts] = v->tangents[1][1]; + tangent5[numUsedVerts] = v->tangents[1][2]; + + usedVertNums[numUsedVerts++] = i; + if ( numUsedVerts < 4 ) { + continue; + } + + lightVectors0[0] = lightDir0[0] * tangent0[0]; + lightVectors0[1] = lightDir0[1] * tangent0[1]; + lightVectors0[2] = lightDir0[2] * tangent0[2]; + lightVectors0[3] = lightDir0[3] * tangent0[3]; + + lightVectors0[0] += lightDir1[0] * tangent1[0]; + lightVectors0[1] += lightDir1[1] * tangent1[1]; + lightVectors0[2] += lightDir1[2] * tangent1[2]; + lightVectors0[3] += lightDir1[3] * tangent1[3]; + + lightVectors0[0] += lightDir2[0] * tangent2[0]; + lightVectors0[1] += lightDir2[1] * tangent2[1]; + lightVectors0[2] += lightDir2[2] * tangent2[2]; + lightVectors0[3] += lightDir2[3] * tangent2[3]; + + lightVectors1[0] = lightDir0[0] * tangent3[0]; + lightVectors1[1] = lightDir0[1] * tangent3[1]; + lightVectors1[2] = lightDir0[2] * tangent3[2]; + lightVectors1[3] = lightDir0[3] * tangent3[3]; + + lightVectors1[0] += lightDir1[0] * tangent4[0]; + lightVectors1[1] += lightDir1[1] * tangent4[1]; + lightVectors1[2] += lightDir1[2] * tangent4[2]; + lightVectors1[3] += lightDir1[3] * tangent4[3]; + + lightVectors1[0] += lightDir2[0] * tangent5[0]; + lightVectors1[1] += lightDir2[1] * tangent5[1]; + lightVectors1[2] += lightDir2[2] * tangent5[2]; + lightVectors1[3] += lightDir2[3] * tangent5[3]; + + lightVectors2[0] = lightDir0[0] * normal0[0]; + lightVectors2[1] = lightDir0[1] * normal0[1]; + lightVectors2[2] = lightDir0[2] * normal0[2]; + lightVectors2[3] = lightDir0[3] * normal0[3]; + + lightVectors2[0] += lightDir1[0] * normal1[0]; + lightVectors2[1] += lightDir1[1] * normal1[1]; + lightVectors2[2] += lightDir1[2] * normal1[2]; + lightVectors2[3] += lightDir1[3] * normal1[3]; + + lightVectors2[0] += lightDir2[0] * normal2[0]; + lightVectors2[1] += lightDir2[1] * normal2[1]; + lightVectors2[2] += lightDir2[2] * normal2[2]; + lightVectors2[3] += lightDir2[3] * normal2[3]; + + + for ( int j = 0; j < 4; j++ ) { + int n = usedVertNums[j]; + + lightVectors[n][0] = lightVectors0[j]; + lightVectors[n][1] = lightVectors1[j]; + lightVectors[n][2] = lightVectors2[j]; + } + + numUsedVerts = 0; + } + + for ( int i = 0; i < numUsedVerts; i++ ) { + + lightVectors0[i] = lightDir0[i] * tangent0[i] + lightDir1[i] * tangent1[i] + lightDir2[i] * tangent2[i]; + lightVectors1[i] = lightDir0[i] * tangent3[i] + lightDir1[i] * tangent4[i] + lightDir2[i] * tangent5[i]; + lightVectors2[i] = lightDir0[i] * normal0[i] + lightDir1[i] * normal1[i] + lightDir2[i] * normal2[i]; + + int n = usedVertNums[i]; + lightVectors[n][0] = lightVectors0[i]; + lightVectors[n][1] = lightVectors1[i]; + lightVectors[n][2] = lightVectors2[i]; + } + +#endif +} + +/* +============ +idSIMD_SSE::CreateSpecularTextureCoords +============ +*/ +void VPCALL idSIMD_SSE::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); + assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); + + bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); + memset( used, 0, numVerts * sizeof( used[0] ) ); + + for ( int i = numIndexes - 1; i >= 0; i-- ) { + used[indexes[i]] = true; + } + +#if 0 + + __asm { + + mov eax, numVerts + + mov esi, used + add esi, eax + + mov edi, verts + sub edi, DRAWVERT_SIZE + + neg eax + dec eax + + mov ecx, viewOrigin + movss xmm6, [ecx+0] + movhps xmm6, [ecx+4] + + mov ecx, lightOrigin + movss xmm7, [ecx+0] + movhps xmm7, [ecx+4] + + mov ecx, texCoords + sub ecx, 4*4 + + loopVert: + inc eax + jge done + + add edi, DRAWVERT_SIZE + add ecx, 4*4 + + cmp byte ptr [esi+eax], 0 + je loopVert + + movaps xmm0, xmm7 + movaps xmm1, xmm6 + movss xmm2, [edi+DRAWVERT_XYZ_OFFSET+0] + movhps xmm2, [edi+DRAWVERT_XYZ_OFFSET+4] + subps xmm0, xmm2 + subps xmm1, xmm2 + + movaps xmm3, xmm0 + movaps xmm4, xmm1 + mulps xmm3, xmm3 + mulps xmm4, xmm4 + + // 0, X, 1, 2 + // 3, X, 4, 5 + + movaps xmm5, xmm3 // xmm5 = 0, X, 1, 2 + unpcklps xmm5, xmm4 // xmm5 = 0, 3, X, X + unpckhps xmm3, xmm4 // xmm3 = 1, 4, 2, 5 + movhlps xmm4, xmm3 // xmm4 = 2, 5, 4, 5 + + addps xmm5, xmm3 + addps xmm5, xmm4 + shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 0, 1 ) + rsqrtps xmm5, xmm5 + + movaps xmm4, xmm5 + shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 1, 1 ) + + mulps xmm0, xmm4 + mulps xmm1, xmm5 + addps xmm0, xmm1 + + movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+0] + movhps xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+4] + mulps xmm2, xmm0 + + movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] + movhps xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+4] + mulps xmm3, xmm0 + + movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+0] + movhps xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] + mulps xmm4, xmm0 + + movaps xmm5, xmm2 // xmm5 = 0, X, 1, 2 + unpcklps xmm5, xmm3 // xmm5 = 0, 3, X, X + unpckhps xmm2, xmm3 // xmm2 = 1, 4, 2, 5 + + movlhps xmm5, xmm4 // xmm5 = 0, 3, 6, X + movhlps xmm4, xmm2 // xmm4 = 2, 5, 7, 8 + shufps xmm2, xmm4, R_SHUFFLEPS( 0, 1, 3, 2 ) // xmm2 = 2, 5, 8, 7 + + movaps xmm3, SIMD_SP_one + + addps xmm5, xmm4 + addps xmm5, xmm2 + movaps [ecx+0], xmm5 + movss [ecx+12], xmm3 + + jmp loopVert + + done: + } + +#elif 0 + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + + idVec3 lightDir = lightOrigin - v->xyz; + idVec3 viewDir = viewOrigin - v->xyz; + + float ilength; + + ilength = idMath::RSqrt( lightDir[0] * lightDir[0] + lightDir[1] * lightDir[1] + lightDir[2] * lightDir[2] ); + lightDir[0] *= ilength; + lightDir[1] *= ilength; + lightDir[2] *= ilength; + + ilength = idMath::RSqrt( viewDir[0] * viewDir[0] + viewDir[1] * viewDir[1] + viewDir[2] * viewDir[2] ); + viewDir[0] *= ilength; + viewDir[1] *= ilength; + viewDir[2] *= ilength; + + lightDir += viewDir; + + texCoords[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; + texCoords[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; + texCoords[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; + texCoords[i][3] = 1.0f; + } + + +#elif 1 + + ALIGN16( int usedVertNums[4] ); + ALIGN16( float lightDir0[4] ); + ALIGN16( float lightDir1[4] ); + ALIGN16( float lightDir2[4] ); + ALIGN16( float viewDir0[4] ); + ALIGN16( float viewDir1[4] ); + ALIGN16( float viewDir2[4] ); + ALIGN16( float normal0[4] ); + ALIGN16( float normal1[4] ); + ALIGN16( float normal2[4] ); + ALIGN16( float tangent0[4] ); + ALIGN16( float tangent1[4] ); + ALIGN16( float tangent2[4] ); + ALIGN16( float tangent3[4] ); + ALIGN16( float tangent4[4] ); + ALIGN16( float tangent5[4] ); + idVec3 localLightOrigin = lightOrigin; + idVec3 localViewOrigin = viewOrigin; + + __asm { + + xor ecx, ecx + mov eax, numVerts + + mov esi, used + add esi, eax + + mov edi, verts + sub edi, DRAWVERT_SIZE + + neg eax + dec eax + + loopVert4: + inc eax + jge done4 + + add edi, DRAWVERT_SIZE + + cmp byte ptr [esi+eax], 0 + je loopVert4 + + mov usedVertNums[ecx*4], eax + + inc ecx + cmp ecx, 4 + + movss xmm3, localLightOrigin[0] + movss xmm4, localLightOrigin[4] + movss xmm5, localLightOrigin[8] + + subss xmm3, [edi+DRAWVERT_XYZ_OFFSET+0] + subss xmm4, [edi+DRAWVERT_XYZ_OFFSET+4] + subss xmm5, [edi+DRAWVERT_XYZ_OFFSET+8] + + movss lightDir0[ecx*4-4], xmm3 + movss lightDir1[ecx*4-4], xmm4 + movss lightDir2[ecx*4-4], xmm5 + + movss xmm0, localViewOrigin[0] + movss xmm1, localViewOrigin[4] + movss xmm2, localViewOrigin[8] + + subss xmm0, [edi+DRAWVERT_XYZ_OFFSET+0] + subss xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] + subss xmm2, [edi+DRAWVERT_XYZ_OFFSET+8] + + movss viewDir0[ecx*4-4], xmm0 + movss viewDir1[ecx*4-4], xmm1 + movss viewDir2[ecx*4-4], xmm2 + + movss xmm3, [edi+DRAWVERT_NORMAL_OFFSET+0] + movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] + movss xmm5, [edi+DRAWVERT_NORMAL_OFFSET+8] + + movss normal0[ecx*4-4], xmm3 + movss normal1[ecx*4-4], xmm4 + movss normal2[ecx*4-4], xmm5 + + movss xmm0, [edi+DRAWVERT_TANGENT0_OFFSET+0] + movss xmm1, [edi+DRAWVERT_TANGENT0_OFFSET+4] + movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+8] + + movss tangent0[ecx*4-4], xmm0 + movss tangent1[ecx*4-4], xmm1 + movss tangent2[ecx*4-4], xmm2 + + movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] + movss xmm4, [edi+DRAWVERT_TANGENT1_OFFSET+4] + movss xmm5, [edi+DRAWVERT_TANGENT1_OFFSET+8] + + movss tangent3[ecx*4-4], xmm3 + movss tangent4[ecx*4-4], xmm4 + movss tangent5[ecx*4-4], xmm5 + + jl loopVert4 + + movaps xmm6, lightDir0 + movaps xmm0, xmm6 + mulps xmm6, xmm6 + movaps xmm7, lightDir1 + movaps xmm1, xmm7 + mulps xmm7, xmm7 + addps xmm6, xmm7 + movaps xmm5, lightDir2 + movaps xmm2, xmm5 + mulps xmm5, xmm5 + addps xmm6, xmm5 + rsqrtps xmm6, xmm6 + + mulps xmm0, xmm6 + mulps xmm1, xmm6 + mulps xmm2, xmm6 + + movaps xmm3, viewDir0 + movaps xmm7, xmm3 + mulps xmm7, xmm7 + movaps xmm4, viewDir1 + movaps xmm6, xmm4 + mulps xmm6, xmm6 + addps xmm7, xmm6 + movaps xmm5, viewDir2 + movaps xmm6, xmm5 + mulps xmm6, xmm6 + addps xmm7, xmm6 + rsqrtps xmm7, xmm7 + + mulps xmm3, xmm7 + addps xmm0, xmm3 + mulps xmm4, xmm7 + addps xmm1, xmm4 + mulps xmm5, xmm7 + addps xmm2, xmm5 + + movaps xmm3, tangent0 + mulps xmm3, xmm0 + movaps xmm4, tangent1 + mulps xmm4, xmm1 + addps xmm3, xmm4 + movaps xmm5, tangent2 + mulps xmm5, xmm2 + addps xmm5, xmm3 + + movaps xmm3, tangent3 + mulps xmm3, xmm0 + movaps xmm4, tangent4 + mulps xmm4, xmm1 + addps xmm3, xmm4 + movaps xmm6, tangent5 + mulps xmm6, xmm2 + addps xmm6, xmm3 + + mulps xmm0, normal0 + mulps xmm1, normal1 + addps xmm0, xmm1 + mulps xmm2, normal2 + addps xmm0, xmm2 + + mov ecx, numVerts + shl ecx, 4 + mov edx, usedVertNums[0] + add ecx, texCoords + shl edx, 4 + movss xmm3, SIMD_SP_one + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + movss [ecx+edx+12], xmm3 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[4] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shl edx, 4 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + movss [ecx+edx+12], xmm3 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[8] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shl edx, 4 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + movss [ecx+edx+12], xmm3 + + shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) + mov edx, usedVertNums[12] + shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) + shl edx, 4 + shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) + + movss [ecx+edx+0], xmm5 + movss [ecx+edx+4], xmm6 + movss [ecx+edx+8], xmm0 + movss [ecx+edx+12], xmm3 + + xor ecx, ecx + jmp loopVert4 + + done4: + test ecx, ecx + jz done + xor eax, eax + mov edi, numVerts + shl edi, 4 + add edi, texCoords + + loopVert1: + movss xmm6, lightDir0[eax*4] + movss xmm0, xmm6 + mulss xmm6, xmm6 + movss xmm7, lightDir1[eax*4] + movss xmm1, xmm7 + mulss xmm7, xmm7 + addss xmm6, xmm7 + movss xmm5, lightDir2[eax*4] + movss xmm2, xmm5 + mulss xmm5, xmm5 + addss xmm6, xmm5 + rsqrtss xmm6, xmm6 + + mulss xmm0, xmm6 + mulss xmm1, xmm6 + mulss xmm2, xmm6 + + movss xmm3, viewDir0[eax*4] + movss xmm7, xmm3 + mulss xmm7, xmm7 + movss xmm4, viewDir1[eax*4] + movss xmm6, xmm4 + mulss xmm6, xmm6 + addss xmm7, xmm6 + movss xmm5, viewDir2[eax*4] + movss xmm6, xmm5 + mulss xmm6, xmm6 + addss xmm7, xmm6 + rsqrtss xmm7, xmm7 + + mulss xmm3, xmm7 + addss xmm0, xmm3 + mulss xmm4, xmm7 + addss xmm1, xmm4 + mulss xmm5, xmm7 + addss xmm2, xmm5 + + mov edx, usedVertNums[eax*4] + shl edx, 4 + + movss xmm3, tangent0[eax*4] + mulss xmm3, xmm0 + movss xmm4, tangent1[eax*4] + mulss xmm4, xmm1 + addss xmm3, xmm4 + movss xmm5, tangent2[eax*4] + mulss xmm5, xmm2 + addss xmm5, xmm3 + movss [edi+edx+0], xmm5 + + movss xmm3, tangent3[eax*4] + mulss xmm3, xmm0 + movss xmm4, tangent4[eax*4] + mulss xmm4, xmm1 + addss xmm3, xmm4 + movss xmm6, tangent5[eax*4] + mulss xmm6, xmm2 + addss xmm6, xmm3 + movss [edi+edx+4], xmm6 + + mulss xmm0, normal0[eax*4] + mulss xmm1, normal1[eax*4] + addss xmm0, xmm1 + mulss xmm2, normal2[eax*4] + addss xmm0, xmm2 + movss [edi+edx+8], xmm0 + + movss xmm3, SIMD_SP_one + movss [edi+edx+12], xmm3 + + inc eax + dec ecx + jg loopVert1 + + done: + } + +#else + + ALIGN16( int usedVertNums[4] ); + ALIGN16( float lightDir0[4] ); + ALIGN16( float lightDir1[4] ); + ALIGN16( float lightDir2[4] ); + ALIGN16( float viewDir0[4] ); + ALIGN16( float viewDir1[4] ); + ALIGN16( float viewDir2[4] ); + ALIGN16( float normal0[4] ); + ALIGN16( float normal1[4] ); + ALIGN16( float normal2[4] ); + ALIGN16( float tangent0[4] ); + ALIGN16( float tangent1[4] ); + ALIGN16( float tangent2[4] ); + ALIGN16( float tangent3[4] ); + ALIGN16( float tangent4[4] ); + ALIGN16( float tangent5[4] ); + ALIGN16( float texCoords0[4] ); + ALIGN16( float texCoords1[4] ); + ALIGN16( float texCoords2[4] ); + idVec3 localLightOrigin = lightOrigin; + idVec3 localViewOrigin = viewOrigin; + int numUsedVerts = 0; + + for ( int i = 0; i < numVerts; i++ ) { + if ( !used[i] ) { + continue; + } + + const idDrawVert *v = &verts[i]; + + lightDir0[numUsedVerts] = localLightOrigin[0] - v->xyz[0]; + lightDir1[numUsedVerts] = localLightOrigin[1] - v->xyz[1]; + lightDir2[numUsedVerts] = localLightOrigin[2] - v->xyz[2]; + + viewDir0[numUsedVerts] = localViewOrigin[0] - v->xyz[0]; + viewDir1[numUsedVerts] = localViewOrigin[1] - v->xyz[1]; + viewDir2[numUsedVerts] = localViewOrigin[2] - v->xyz[2]; + + normal0[numUsedVerts] = v->normal[0]; + normal1[numUsedVerts] = v->normal[1]; + normal2[numUsedVerts] = v->normal[2]; + + tangent0[numUsedVerts] = v->tangents[0][0]; + tangent1[numUsedVerts] = v->tangents[0][1]; + tangent2[numUsedVerts] = v->tangents[0][2]; + + tangent3[numUsedVerts] = v->tangents[1][0]; + tangent4[numUsedVerts] = v->tangents[1][1]; + tangent5[numUsedVerts] = v->tangents[1][2]; + + usedVertNums[numUsedVerts++] = i; + if ( numUsedVerts < 4 ) { + continue; + } + + ALIGN16( float temp[4] ); + + temp[0] = lightDir0[0] * lightDir0[0]; + temp[1] = lightDir0[1] * lightDir0[1]; + temp[2] = lightDir0[2] * lightDir0[2]; + temp[3] = lightDir0[3] * lightDir0[3]; + + temp[0] += lightDir1[0] * lightDir1[0]; + temp[1] += lightDir1[1] * lightDir1[1]; + temp[2] += lightDir1[2] * lightDir1[2]; + temp[3] += lightDir1[3] * lightDir1[3]; + + temp[0] += lightDir2[0] * lightDir2[0]; + temp[1] += lightDir2[1] * lightDir2[1]; + temp[2] += lightDir2[2] * lightDir2[2]; + temp[3] += lightDir2[3] * lightDir2[3]; + + temp[0] = idMath::RSqrt( temp[0] ); + temp[1] = idMath::RSqrt( temp[1] ); + temp[2] = idMath::RSqrt( temp[2] ); + temp[3] = idMath::RSqrt( temp[3] ); + + lightDir0[0] *= temp[0]; + lightDir0[1] *= temp[1]; + lightDir0[2] *= temp[2]; + lightDir0[3] *= temp[3]; + + lightDir1[0] *= temp[0]; + lightDir1[1] *= temp[1]; + lightDir1[2] *= temp[2]; + lightDir1[3] *= temp[3]; + + lightDir2[0] *= temp[0]; + lightDir2[1] *= temp[1]; + lightDir2[2] *= temp[2]; + lightDir2[3] *= temp[3]; + + temp[0] = viewDir0[0] * viewDir0[0]; + temp[1] = viewDir0[1] * viewDir0[1]; + temp[2] = viewDir0[2] * viewDir0[2]; + temp[3] = viewDir0[3] * viewDir0[3]; + + temp[0] += viewDir1[0] * viewDir1[0]; + temp[1] += viewDir1[1] * viewDir1[1]; + temp[2] += viewDir1[2] * viewDir1[2]; + temp[3] += viewDir1[3] * viewDir1[3]; + + temp[0] += viewDir2[0] * viewDir2[0]; + temp[1] += viewDir2[1] * viewDir2[1]; + temp[2] += viewDir2[2] * viewDir2[2]; + temp[3] += viewDir2[3] * viewDir2[3]; + + temp[0] = idMath::RSqrt( temp[0] ); + temp[1] = idMath::RSqrt( temp[1] ); + temp[2] = idMath::RSqrt( temp[2] ); + temp[3] = idMath::RSqrt( temp[3] ); + + viewDir0[0] *= temp[0]; + viewDir0[1] *= temp[1]; + viewDir0[2] *= temp[2]; + viewDir0[3] *= temp[3]; + + viewDir1[0] *= temp[0]; + viewDir1[1] *= temp[1]; + viewDir1[2] *= temp[2]; + viewDir1[3] *= temp[3]; + + viewDir2[0] *= temp[0]; + viewDir2[1] *= temp[1]; + viewDir2[2] *= temp[2]; + viewDir2[3] *= temp[3]; + + lightDir0[0] += viewDir0[0]; + lightDir0[1] += viewDir0[1]; + lightDir0[2] += viewDir0[2]; + lightDir0[3] += viewDir0[3]; + + lightDir1[0] += viewDir1[0]; + lightDir1[1] += viewDir1[1]; + lightDir1[2] += viewDir1[2]; + lightDir1[3] += viewDir1[3]; + + lightDir2[0] += viewDir2[0]; + lightDir2[1] += viewDir2[1]; + lightDir2[2] += viewDir2[2]; + lightDir2[3] += viewDir2[3]; + + texCoords0[0] = lightDir0[0] * tangent0[0]; + texCoords0[1] = lightDir0[1] * tangent0[1]; + texCoords0[2] = lightDir0[2] * tangent0[2]; + texCoords0[3] = lightDir0[3] * tangent0[3]; + + texCoords0[0] += lightDir1[0] * tangent1[0]; + texCoords0[1] += lightDir1[1] * tangent1[1]; + texCoords0[2] += lightDir1[2] * tangent1[2]; + texCoords0[3] += lightDir1[3] * tangent1[3]; + + texCoords0[0] += lightDir2[0] * tangent2[0]; + texCoords0[1] += lightDir2[1] * tangent2[1]; + texCoords0[2] += lightDir2[2] * tangent2[2]; + texCoords0[3] += lightDir2[3] * tangent2[3]; + + texCoords1[0] = lightDir0[0] * tangent3[0]; + texCoords1[1] = lightDir0[1] * tangent3[1]; + texCoords1[2] = lightDir0[2] * tangent3[2]; + texCoords1[3] = lightDir0[3] * tangent3[3]; + + texCoords1[0] += lightDir1[0] * tangent4[0]; + texCoords1[1] += lightDir1[1] * tangent4[1]; + texCoords1[2] += lightDir1[2] * tangent4[2]; + texCoords1[3] += lightDir1[3] * tangent4[3]; + + texCoords1[0] += lightDir2[0] * tangent5[0]; + texCoords1[1] += lightDir2[1] * tangent5[1]; + texCoords1[2] += lightDir2[2] * tangent5[2]; + texCoords1[3] += lightDir2[3] * tangent5[3]; + + texCoords2[0] = lightDir0[0] * normal0[0]; + texCoords2[1] = lightDir0[1] * normal0[1]; + texCoords2[2] = lightDir0[2] * normal0[2]; + texCoords2[3] = lightDir0[3] * normal0[3]; + + texCoords2[0] += lightDir1[0] * normal1[0]; + texCoords2[1] += lightDir1[1] * normal1[1]; + texCoords2[2] += lightDir1[2] * normal1[2]; + texCoords2[3] += lightDir1[3] * normal1[3]; + + texCoords2[0] += lightDir2[0] * normal2[0]; + texCoords2[1] += lightDir2[1] * normal2[1]; + texCoords2[2] += lightDir2[2] * normal2[2]; + texCoords2[3] += lightDir2[3] * normal2[3]; + + for ( int j = 0; j < 4; j++ ) { + int n = usedVertNums[j]; + + texCoords[n][0] = texCoords0[j]; + texCoords[n][1] = texCoords1[j]; + texCoords[n][2] = texCoords2[j]; + texCoords[n][3] = 1.0f; + } + + numUsedVerts = 0; + } + + for ( int i = 0; i < numUsedVerts; i++ ) { + float temp; + + temp = lightDir0[i] * lightDir0[i] + lightDir1[i] * lightDir1[i] + lightDir2[i] * lightDir2[i]; + temp = idMath::RSqrt( temp ); + + lightDir0[i] *= temp; + lightDir1[i] *= temp; + lightDir2[i] *= temp; + + temp = viewDir0[i] * viewDir0[i] + viewDir1[i] * viewDir1[i] + viewDir2[i] * viewDir2[i]; + temp = idMath::RSqrt( temp ); + + viewDir0[i] *= temp; + viewDir1[i] *= temp; + viewDir2[i] *= temp; + + lightDir0[i] += viewDir0[i]; + lightDir1[i] += viewDir1[i]; + lightDir2[i] += viewDir2[i]; + + texCoords0[i] = lightDir0[i] * tangent0[i] + lightDir1[i] * tangent1[i] + lightDir2[i] * tangent2[i]; + texCoords1[i] = lightDir0[i] * tangent3[i] + lightDir1[i] * tangent4[i] + lightDir2[i] * tangent5[i]; + texCoords2[i] = lightDir0[i] * normal0[i] + lightDir1[i] * normal1[i] + lightDir2[i] * normal2[i]; + + int n = usedVertNums[i]; + texCoords[n][0] = texCoords0; + texCoords[n][1] = texCoords1; + texCoords[n][2] = texCoords2; + texCoords[n][3] = 1.0f; + } + +#endif +} + +/* +============ +idSIMD_SSE::CreateShadowCache +============ +*/ +int VPCALL idSIMD_SSE::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { +#if 1 + int outVerts; + + __asm { + push ebx + + mov esi, lightOrigin + movaps xmm5, SIMD_SP_lastOne + movss xmm6, [esi+0] + movhps xmm6, [esi+4] + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 3, 1 ) + orps xmm6, SIMD_SP_lastOne + movaps xmm7, xmm6 + + xor ebx, ebx + xor ecx, ecx + + mov edx, vertRemap + mov esi, verts + mov edi, vertexCache + mov eax, numVerts + and eax, ~3 + jz done4 + shl eax, 2 + add edx, eax + neg eax + + loop4: + prefetchnta [edx+128] + prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] + + cmp dword ptr [edx+eax+0], ebx + jne skip1 + + mov dword ptr [edx+eax+0], ecx + movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + add ecx, 2 + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); + orps xmm0, xmm5 + movaps [edi+0*16], xmm0 + subps xmm0, xmm6 + movaps [edi+1*16], xmm0 + add edi, 2*16 + + skip1: + cmp dword ptr [edx+eax+4], ebx + jne skip2 + + mov dword ptr [edx+eax+4], ecx + movss xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + add ecx, 2 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 1 ) + orps xmm1, xmm5 + movaps [edi+0*16], xmm1 + subps xmm1, xmm7 + movaps [edi+1*16], xmm1 + add edi, 2*16 + + skip2: + cmp dword ptr [edx+eax+8], ebx + jne skip3 + + mov dword ptr [edx+eax+8], ecx + movss xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + add ecx, 2 + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ); + orps xmm2, xmm5 + movaps [edi+0*16], xmm2 + subps xmm2, xmm6 + movaps [edi+1*16], xmm2 + add edi, 2*16 + + skip3: + cmp dword ptr [edx+eax+12], ebx + jne skip4 + + mov dword ptr [edx+eax+12], ecx + movss xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + add ecx, 2 + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 3, 1 ) + orps xmm3, xmm5 + movaps [edi+0*16], xmm3 + subps xmm3, xmm7 + movaps [edi+1*16], xmm3 + add edi, 2*16 + + skip4: + add esi, 4*DRAWVERT_SIZE + add eax, 4*4 + jl loop4 + + done4: + mov eax, numVerts + and eax, 3 + jz done1 + shl eax, 2 + add edx, eax + neg eax + + loop1: + cmp dword ptr [edx+eax+0], ebx + jne skip0 + + mov dword ptr [edx+eax+0], ecx + movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + add ecx, 2 + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ) + orps xmm0, xmm5 + movaps [edi+0*16], xmm0 + subps xmm0, xmm6 + movaps [edi+1*16], xmm0 + add edi, 2*16 + + skip0: + + add esi, DRAWVERT_SIZE + add eax, 4 + jl loop1 + + done1: + pop ebx + mov outVerts, ecx + } + return outVerts; + +#else + + int outVerts = 0; + for ( int i = 0; i < numVerts; i++ ) { + if ( vertRemap[i] ) { + continue; + } + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[outVerts+0][0] = v[0]; + vertexCache[outVerts+0][1] = v[1]; + vertexCache[outVerts+0][2] = v[2]; + vertexCache[outVerts+0][3] = 1.0f; + + // R_SetupProjection() builds the projection matrix with a slight crunch + // for depth, which keeps this w=0 division from rasterizing right at the + // wrap around point and causing depth fighting with the rear caps + vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; + vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; + vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; + vertexCache[outVerts+1][3] = 0.0f; + vertRemap[i] = outVerts; + outVerts += 2; + } + return outVerts; + +#endif +} + +/* +============ +idSIMD_SSE::CreateVertexProgramShadowCache +============ +*/ +int VPCALL idSIMD_SSE::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { +#if 1 + + __asm { + movaps xmm4, SIMD_SP_lastOne + movaps xmm5, xmm4 + movaps xmm6, xmm4 + movaps xmm7, xmm4 + + mov esi, verts + mov edi, vertexCache + mov eax, numVerts + and eax, ~3 + jz done4 + shl eax, 5 + add edi, eax + neg eax + + loop4: + prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] + + movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); + movaps [edi+eax+1*16], xmm0 + orps xmm0, xmm4 + movaps [edi+eax+0*16], xmm0 + + movss xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 1 ) + movaps [edi+eax+3*16], xmm1 + orps xmm1, xmm5 + movaps [edi+eax+2*16], xmm1 + + movss xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ); + movaps [edi+eax+5*16], xmm2 + orps xmm2, xmm6 + movaps [edi+eax+4*16], xmm2 + + movss xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + movhps xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] + shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 3, 1 ) + movaps [edi+eax+7*16], xmm3 + orps xmm3, xmm7 + movaps [edi+eax+6*16], xmm3 + + add esi, 4*DRAWVERT_SIZE + add eax, 4*8*4 + jl loop4 + + done4: + mov eax, numVerts + and eax, 3 + jz done1 + shl eax, 5 + add edi, eax + neg eax + + loop1: + movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] + movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); + movaps [edi+eax+1*16], xmm0 + orps xmm0, xmm4 + movaps [edi+eax+0*16], xmm0 + + add esi, DRAWVERT_SIZE + add eax, 8*4 + jl loop1 + + done1: + } + return numVerts * 2; + +#else + + for ( int i = 0; i < numVerts; i++ ) { + const float *v = verts[i].xyz.ToFloatPtr(); + vertexCache[i*2+0][0] = v[0]; + vertexCache[i*2+0][1] = v[1]; + vertexCache[i*2+0][2] = v[2]; + vertexCache[i*2+0][3] = 1.0f; + + vertexCache[i*2+1][0] = v[0]; + vertexCache[i*2+1][1] = v[1]; + vertexCache[i*2+1][2] = v[2]; + vertexCache[i*2+1][3] = 0.0f; + } + return numVerts * 2; + +#endif +} + +/* +============ +SSE_UpSample11kHzMonoPCMTo44kHz +============ +*/ +static void SSE_UpSample11kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { + __asm { + mov esi, src + mov edi, dest + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 2*4*4 + + movsx ecx, word ptr [esi+eax+0] + cvtsi2ss xmm0, ecx + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi-2*4*4+0], xmm0 + movhps [edi-2*4*4+8], xmm0 + + movsx edx, word ptr [esi+eax+2] + cvtsi2ss xmm1, edx + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi-1*4*4+0], xmm1 + movhps [edi-1*4*4+8], xmm1 + + add eax, 2*2 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movsx ecx, word ptr [esi] + cvtsi2ss xmm0, ecx + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi+0], xmm0 + movhps [edi+8], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample11kHzStereoPCMTo44kHz +============ +*/ +static void SSE_UpSample11kHzStereoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { + __asm { + mov esi, src + mov edi, dest + + mov eax, numSamples + test eax, ~1 + jz done2 + shl eax, 1 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 8*4 + + movsx ecx, word ptr [esi+eax+0] + cvtsi2ss xmm0, ecx + + movsx edx, word ptr [esi+eax+2] + cvtsi2ss xmm1, edx + + unpcklps xmm0, xmm1 + + movlps [edi-8*4+0], xmm0 + movlps [edi-8*4+8], xmm0 + movlps [edi-4*4+0], xmm0 + movlps [edi-4*4+8], xmm0 + + add eax, 2*2 + jl loop2 + + done2: + } +} + +/* +============ +SSE_UpSample22kHzMonoPCMTo44kHz +============ +*/ +static void SSE_UpSample22kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { + __asm { + mov esi, src + mov edi, dest + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 4*4 + + movsx ecx, word ptr [esi+eax+0] + cvtsi2ss xmm0, ecx + + movsx edx, word ptr [esi+eax+2] + cvtsi2ss xmm1, edx + + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi-4*4+0], xmm0 + movhps [edi-4*4+8], xmm0 + + add eax, 2*2 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movsx ecx, word ptr [esi] + cvtsi2ss xmm0, ecx + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample22kHzStereoPCMTo44kHz +============ +*/ +static void SSE_UpSample22kHzStereoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { + __asm { + mov esi, src + mov edi, dest + + mov eax, numSamples + test eax, ~1 + jz done2 + shl eax, 1 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 4*4 + + movsx ecx, word ptr [esi+eax+0] + cvtsi2ss xmm0, ecx + movss [edi-4*4], xmm0 + movss [edi-2*4], xmm0 + + movsx edx, word ptr [esi+eax+2] + cvtsi2ss xmm1, edx + movss [edi-3*4], xmm1 + movss [edi-1*4], xmm1 + + add eax, 2*2 + jl loop2 + + done2: + } +} + +/* +============ +SSE_UpSample44kHzMonoPCMTo44kHz +============ +*/ +static void SSE_UpSample44kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { + __asm { + mov esi, src + mov edi, dest + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 2*4 + + movsx ecx, word ptr [esi+eax+0] + cvtsi2ss xmm0, ecx + movss [edi-2*4], xmm0 + + movsx edx, word ptr [esi+eax+2] + cvtsi2ss xmm1, edx + movss [edi-1*4], xmm1 + + add eax, 2*2 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movsx ecx, word ptr [esi] + cvtsi2ss xmm0, ecx + movss [edi], xmm0 + + done: + } +} + +/* +============ +idSIMD_SSE::UpSamplePCMTo44kHz + + Duplicate samples for 44kHz output. +============ +*/ +void idSIMD_SSE::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + SSE_UpSample11kHzMonoPCMTo44kHz( dest, src, numSamples ); + } else { + SSE_UpSample11kHzStereoPCMTo44kHz( dest, src, numSamples ); + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + SSE_UpSample22kHzMonoPCMTo44kHz( dest, src, numSamples ); + } else { + SSE_UpSample22kHzStereoPCMTo44kHz( dest, src, numSamples ); + } + } else if ( kHz == 44100 ) { + SSE_UpSample44kHzMonoPCMTo44kHz( dest, src, numSamples ); + } else { + assert( 0 ); + } +} + +/* +============ +SSE_UpSample11kHzMonoOGGTo44kHz +============ +*/ +static void SSE_UpSample11kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { + float constant = 32768.0f; + __asm { + mov esi, src + mov edi, dest + movss xmm7, constant + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 2 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 2*16 + + movss xmm0, [esi+eax+0] + mulss xmm0, xmm7 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi-32], xmm0 + movlps [edi-24], xmm0 + + movss xmm1, [esi+eax+4] + mulss xmm1, xmm7 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi-16], xmm1 + movlps [edi- 8], xmm1 + + add eax, 2*4 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movss xmm0, [esi] + mulss xmm0, xmm7 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi+0], xmm0 + movlps [edi+8], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample11kHzStereoOGGTo44kHz +============ +*/ +static void SSE_UpSample11kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { + float constant = 32768.0f; + __asm { + mov esi, src + mov ecx, [esi+0] + mov edx, [esi+4] + mov edi, dest + movss xmm7, constant + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add ecx, eax + add edx, eax + neg eax + + align 16 + loop2: + add edi, 4*16 + + movlps xmm0, [ecx+eax] + movlps xmm1, [edx+eax] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi-8*8], xmm0 + movlps [edi-7*8], xmm0 + movlps [edi-6*8], xmm0 + movlps [edi-5*8], xmm0 + movhps [edi-4*8], xmm0 + movhps [edi-3*8], xmm0 + movhps [edi-2*8], xmm0 + movhps [edi-1*8], xmm0 + + add eax, 2*4 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movss xmm0, [ecx] + movss xmm1, [edx] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi+0*8], xmm0 + movlps [edi+1*8], xmm0 + movlps [edi+2*8], xmm0 + movlps [edi+3*8], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample22kHzMonoOGGTo44kHz +============ +*/ +static void SSE_UpSample22kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { + float constant = 32768.0f; + __asm { + mov esi, src + mov edi, dest + movss xmm7, constant + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 2 + add esi, eax + neg eax + + align 16 + loop2: + add edi, 2*8 + + movss xmm0, [esi+eax+0] + movss xmm1, [esi+eax+4] + shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm0, xmm7 + movlps [edi-16], xmm0 + movhps [edi- 8], xmm0 + + add eax, 2*4 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movss xmm0, [esi] + mulss xmm0, xmm7 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) + movlps [edi+0], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample22kHzStereoOGGTo44kHz +============ +*/ +static void SSE_UpSample22kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { + float constant = 32768.0f; + __asm { + mov esi, src + mov ecx, [esi+0] + mov edx, [esi+4] + mov edi, dest + movss xmm7, constant + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add ecx, eax + add edx, eax + neg eax + + align 16 + loop2: + add edi, 2*16 + + movlps xmm0, [ecx+eax] + movlps xmm1, [edx+eax] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi-4*8], xmm0 + movlps [edi-3*8], xmm0 + movhps [edi-2*8], xmm0 + movhps [edi-1*8], xmm0 + + add eax, 2*4 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movss xmm0, [ecx] + movss xmm1, [edx] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi+0*8], xmm0 + movlps [edi+1*8], xmm0 + + done: + } +} + +/* +============ +SSE_UpSample44kHzMonoOGGTo44kHz +============ +*/ +static void SSE_UpSample44kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { + float constant = 32768.0f; + KFLOAT_CA( mul, dest, src, constant, numSamples ) +} + +/* +============ +SSE_UpSample44kHzStereoOGGTo44kHz +============ +*/ +static void SSE_UpSample44kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { + float constant = 32768.0f; + __asm { + mov esi, src + mov ecx, [esi+0] + mov edx, [esi+4] + mov edi, dest + movss xmm7, constant + shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) + + mov eax, numSamples + and eax, ~1 + jz done2 + shl eax, 1 + add ecx, eax + add edx, eax + neg eax + + align 16 + loop2: + add edi, 16 + + movlps xmm0, [ecx+eax] + movlps xmm1, [edx+eax] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi-2*8], xmm0 + movhps [edi-1*8], xmm0 + + add eax, 2*4 + jl loop2 + + done2: + mov eax, numSamples + and eax, 1 + jz done + + movss xmm0, [ecx] + movss xmm1, [edx] + unpcklps xmm0, xmm1 + mulps xmm0, xmm7 + movlps [edi+0*8], xmm0 + + done: + } +} + +/* +============ +idSIMD_SSE::UpSampleOGGTo44kHz + + Duplicate samples for 44kHz output. +============ +*/ +void idSIMD_SSE::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { + if ( kHz == 11025 ) { + if ( numChannels == 1 ) { + SSE_UpSample11kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); + } else { + SSE_UpSample11kHzStereoOGGTo44kHz( dest, ogg, numSamples ); + } + } else if ( kHz == 22050 ) { + if ( numChannels == 1 ) { + SSE_UpSample22kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); + } else { + SSE_UpSample22kHzStereoOGGTo44kHz( dest, ogg, numSamples ); + } + } else if ( kHz == 44100 ) { + if ( numChannels == 1 ) { + SSE_UpSample44kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); + } else { + SSE_UpSample44kHzStereoOGGTo44kHz( dest, ogg, numSamples ); + } + } else { + assert( 0 ); + } +} + +/* +============ +idSIMD_SSE::MixSoundTwoSpeakerMono +============ +*/ +void VPCALL idSIMD_SSE::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { +#if 1 + + ALIGN16( float incs[2] ); + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + __asm { + mov eax, MIXBUFFER_SAMPLES + mov edi, mixBuffer + mov esi, samples + shl eax, 2 + add esi, eax + neg eax + + mov ecx, lastV + movlps xmm6, [ecx] + xorps xmm7, xmm7 + movhps xmm7, incs + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + addps xmm6, xmm7 + shufps xmm7, xmm7, R_SHUFFLEPS( 2, 3, 2, 3 ) + addps xmm7, xmm7 + + loop16: + add edi, 4*4*4 + + movaps xmm0, [esi+eax+0*4*4] + movaps xmm1, xmm0 + shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) + mulps xmm0, xmm6 + addps xmm0, [edi-4*4*4] + addps xmm6, xmm7 + movaps [edi-4*4*4], xmm0 + + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 3, 3 ) + mulps xmm1, xmm6 + addps xmm1, [edi-3*4*4] + addps xmm6, xmm7 + movaps [edi-3*4*4], xmm1 + + movaps xmm2, [esi+eax+1*4*4] + movaps xmm3, xmm2 + shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) + mulps xmm2, xmm6 + addps xmm2, [edi-2*4*4] + addps xmm6, xmm7 + movaps [edi-2*4*4], xmm2 + + shufps xmm3, xmm3, R_SHUFFLEPS( 2, 2, 3, 3 ) + mulps xmm3, xmm6 + addps xmm3, [edi-1*4*4] + addps xmm6, xmm7 + movaps [edi-1*4*4], xmm3 + + add eax, 2*4*4 + + jl loop16 + } + +#else + + int i; + float incL; + float incR; + float sL0, sL1; + float sR0, sR1; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + sL0 = lastV[0]; + sR0 = lastV[1]; + sL1 = lastV[0] + incL; + sR1 = lastV[1] + incR; + + incL *= 2; + incR *= 2; + + for( i = 0; i < MIXBUFFER_SAMPLES; i += 2 ) { + mixBuffer[i*2+0] += samples[i+0] * sL0; + mixBuffer[i*2+1] += samples[i+0] * sR0; + mixBuffer[i*2+2] += samples[i+1] * sL1; + mixBuffer[i*2+3] += samples[i+1] * sR1; + sL0 += incL; + sR0 += incR; + sL1 += incL; + sR1 += incR; + } + +#endif +} + +/* +============ +idSIMD_SSE::MixSoundTwoSpeakerStereo +============ +*/ +void VPCALL idSIMD_SSE::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { +#if 1 + + ALIGN16( float incs[2] ); + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + __asm { + mov eax, MIXBUFFER_SAMPLES + mov edi, mixBuffer + mov esi, samples + shl eax, 3 + add esi, eax + neg eax + + mov ecx, lastV + movlps xmm6, [ecx] + xorps xmm7, xmm7 + movhps xmm7, incs + shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) + addps xmm6, xmm7 + shufps xmm7, xmm7, R_SHUFFLEPS( 2, 3, 2, 3 ) + addps xmm7, xmm7 + + loop16: + add edi, 4*4*4 + + movaps xmm0, [esi+eax+0*4*4] + mulps xmm0, xmm6 + addps xmm0, [edi-4*4*4] + addps xmm6, xmm7 + movaps [edi-4*4*4], xmm0 + + movaps xmm2, [esi+eax+1*4*4] + mulps xmm2, xmm6 + addps xmm2, [edi-3*4*4] + addps xmm6, xmm7 + movaps [edi-3*4*4], xmm2 + + movaps xmm3, [esi+eax+2*4*4] + mulps xmm3, xmm6 + addps xmm3, [edi-2*4*4] + addps xmm6, xmm7 + movaps [edi-2*4*4], xmm3 + + movaps xmm4, [esi+eax+3*4*4] + mulps xmm4, xmm6 + addps xmm4, [edi-1*4*4] + addps xmm6, xmm7 + movaps [edi-1*4*4], xmm4 + + add eax, 4*4*4 + + jl loop16 + } + +#else + + int i; + float incL; + float incR; + float sL0, sL1; + float sR0, sR1; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + + sL0 = lastV[0]; + sR0 = lastV[1]; + sL1 = lastV[0] + incL; + sR1 = lastV[1] + incR; + + incL *= 2; + incR *= 2; + + for( i = 0; i < MIXBUFFER_SAMPLES; i += 2 ) { + mixBuffer[i*2+0] += samples[i*2+0] * sL0; + mixBuffer[i*2+1] += samples[i*2+1] * sR0; + mixBuffer[i*2+2] += samples[i*2+2] * sL1; + mixBuffer[i*2+3] += samples[i*2+3] * sR1; + sL0 += incL; + sR0 += incR; + sL1 += incL; + sR1 += incR; + } + +#endif +} + +/* +============ +idSIMD_SSE::MixSoundSixSpeakerMono +============ +*/ +void VPCALL idSIMD_SSE::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { +#if 1 + + ALIGN16( float incs[6] ); + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incs[2] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incs[3] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incs[4] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incs[5] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + __asm { + mov eax, MIXBUFFER_SAMPLES + mov edi, mixBuffer + mov esi, samples + shl eax, 2 + add esi, eax + neg eax + + mov ecx, lastV + movlps xmm2, [ecx+ 0] + movhps xmm2, [ecx+ 8] + movlps xmm3, [ecx+16] + movaps xmm4, xmm2 + shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + shufps xmm4, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) + + xorps xmm5, xmm5 + movhps xmm5, incs + movlps xmm7, incs+8 + movhps xmm7, incs+16 + addps xmm3, xmm5 + addps xmm4, xmm7 + shufps xmm5, xmm7, R_SHUFFLEPS( 2, 3, 0, 1 ) + movaps xmm6, xmm7 + shufps xmm6, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) + addps xmm5, xmm5 + addps xmm6, xmm6 + addps xmm7, xmm7 + + loop24: + add edi, 6*16 + + movaps xmm0, [esi+eax] + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + mulps xmm1, xmm2 + addps xmm1, [edi-6*16] + addps xmm2, xmm5 + movaps [edi-6*16], xmm1 + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) + mulps xmm1, xmm3 + addps xmm1, [edi-5*16] + addps xmm3, xmm6 + movaps [edi-5*16], xmm1 + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) + mulps xmm1, xmm4 + addps xmm1, [edi-4*16] + addps xmm4, xmm7 + movaps [edi-4*16], xmm1 + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 2, 2 ) + mulps xmm1, xmm2 + addps xmm1, [edi-3*16] + addps xmm2, xmm5 + movaps [edi-3*16], xmm1 + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 3, 3 ) + mulps xmm1, xmm3 + addps xmm1, [edi-2*16] + addps xmm3, xmm6 + movaps [edi-2*16], xmm1 + + shufps xmm0, xmm0, R_SHUFFLEPS( 3, 3, 3, 3 ) + mulps xmm0, xmm4 + addps xmm0, [edi-1*16] + addps xmm4, xmm7 + movaps [edi-1*16], xmm0 + + add eax, 4*4 + + jl loop24 + } + +#else + + int i; + float sL0, sL1, sL2, sL3, sL4, sL5, sL6, sL7, sL8, sL9, sL10, sL11; + float incL0, incL1, incL2, incL3, incL4, incL5; + + assert( numSamples == MIXBUFFER_SAMPLES ); + + incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + sL0 = lastV[0]; + sL1 = lastV[1]; + sL2 = lastV[2]; + sL3 = lastV[3]; + sL4 = lastV[4]; + sL5 = lastV[5]; + + sL6 = lastV[0] + incL0; + sL7 = lastV[1] + incL1; + sL8 = lastV[2] + incL2; + sL9 = lastV[3] + incL3; + sL10 = lastV[4] + incL4; + sL11 = lastV[5] + incL5; + + incL0 *= 2; + incL1 *= 2; + incL2 *= 2; + incL3 *= 2; + incL4 *= 2; + incL5 *= 2; + + for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { + mixBuffer[i*6+ 0] += samples[i+0] * sL0; + mixBuffer[i*6+ 1] += samples[i+0] * sL1; + mixBuffer[i*6+ 2] += samples[i+0] * sL2; + mixBuffer[i*6+ 3] += samples[i+0] * sL3; + + mixBuffer[i*6+ 4] += samples[i+0] * sL4; + mixBuffer[i*6+ 5] += samples[i+0] * sL5; + mixBuffer[i*6+ 6] += samples[i+1] * sL6; + mixBuffer[i*6+ 7] += samples[i+1] * sL7; + + mixBuffer[i*6+ 8] += samples[i+1] * sL8; + mixBuffer[i*6+ 9] += samples[i+1] * sL9; + mixBuffer[i*6+10] += samples[i+1] * sL10; + mixBuffer[i*6+11] += samples[i+1] * sL11; + + sL0 += incL0; + sL1 += incL1; + sL2 += incL2; + sL3 += incL3; + + sL4 += incL4; + sL5 += incL5; + sL6 += incL0; + sL7 += incL1; + + sL8 += incL2; + sL9 += incL3; + sL10 += incL4; + sL11 += incL5; + } + +#endif +} + +/* +============ +idSIMD_SSE::MixSoundSixSpeakerStereo +============ +*/ +void VPCALL idSIMD_SSE::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { +#if 1 + + ALIGN16( float incs[6] ); + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incs[2] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incs[3] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incs[4] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incs[5] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + __asm { + mov eax, MIXBUFFER_SAMPLES + mov edi, mixBuffer + mov esi, samples + shl eax, 3 + add esi, eax + neg eax + + mov ecx, lastV + movlps xmm2, [ecx+ 0] + movhps xmm2, [ecx+ 8] + movlps xmm3, [ecx+16] + movaps xmm4, xmm2 + shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) + shufps xmm4, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) + + xorps xmm5, xmm5 + movhps xmm5, incs + movlps xmm7, incs+ 8 + movhps xmm7, incs+16 + addps xmm3, xmm5 + addps xmm4, xmm7 + shufps xmm5, xmm7, R_SHUFFLEPS( 2, 3, 0, 1 ) + movaps xmm6, xmm7 + shufps xmm6, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) + addps xmm5, xmm5 + addps xmm6, xmm6 + addps xmm7, xmm7 + + loop12: + add edi, 3*16 + + movaps xmm0, [esi+eax+0] + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 0 ) + mulps xmm1, xmm2 + addps xmm1, [edi-3*16] + addps xmm2, xmm5 + movaps [edi-3*16], xmm1 + + movaps xmm1, xmm0 + shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 2, 3 ) + mulps xmm1, xmm3 + addps xmm1, [edi-2*16] + addps xmm3, xmm6 + movaps [edi-2*16], xmm1 + + add eax, 4*4 + + shufps xmm0, xmm0, R_SHUFFLEPS( 2, 2, 2, 3 ) + mulps xmm0, xmm4 + addps xmm0, [edi-1*16] + addps xmm4, xmm7 + movaps [edi-1*16], xmm0 + + jl loop12 + + emms + } + +#else + + int i; + float sL0, sL1, sL2, sL3, sL4, sL5, sL6, sL7, sL8, sL9, sL10, sL11; + float incL0, incL1, incL2, incL3, incL4, incL5; + + assert( numSamples == MIXBUFFER_SAMPLES ); + assert( SPEAKER_RIGHT == 1 ); + assert( SPEAKER_BACKRIGHT == 5 ); + + incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; + incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; + incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; + incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; + incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; + incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; + + sL0 = lastV[0]; + sL1 = lastV[1]; + sL2 = lastV[2]; + sL3 = lastV[3]; + sL4 = lastV[4]; + sL5 = lastV[5]; + + sL6 = lastV[0] + incL0; + sL7 = lastV[1] + incL1; + sL8 = lastV[2] + incL2; + sL9 = lastV[3] + incL3; + sL10 = lastV[4] + incL4; + sL11 = lastV[5] + incL5; + + incL0 *= 2; + incL1 *= 2; + incL2 *= 2; + incL3 *= 2; + incL4 *= 2; + incL5 *= 2; + + for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { + mixBuffer[i*6+ 0] += samples[i*2+0+0] * sL0; + mixBuffer[i*6+ 1] += samples[i*2+0+1] * sL1; + mixBuffer[i*6+ 2] += samples[i*2+0+0] * sL2; + mixBuffer[i*6+ 3] += samples[i*2+0+0] * sL3; + + mixBuffer[i*6+ 4] += samples[i*2+0+0] * sL4; + mixBuffer[i*6+ 5] += samples[i*2+0+1] * sL5; + mixBuffer[i*6+ 6] += samples[i*2+2+0] * sL6; + mixBuffer[i*6+ 7] += samples[i*2+2+1] * sL7; + + mixBuffer[i*6+ 8] += samples[i*2+2+0] * sL8; + mixBuffer[i*6+ 9] += samples[i*2+2+0] * sL9; + mixBuffer[i*6+10] += samples[i*2+2+0] * sL10; + mixBuffer[i*6+11] += samples[i*2+2+1] * sL11; + + sL0 += incL0; + sL1 += incL1; + sL2 += incL2; + sL3 += incL3; + + sL4 += incL4; + sL5 += incL5; + sL6 += incL0; + sL7 += incL1; + + sL8 += incL2; + sL9 += incL3; + sL10 += incL4; + sL11 += incL5; + } + +#endif +} + +/* +============ +idSIMD_SSE::MixedSoundToSamples +============ +*/ +void VPCALL idSIMD_SSE::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { +#if 1 + + assert( ( numSamples % MIXBUFFER_SAMPLES ) == 0 ); + + __asm { + + mov eax, numSamples + mov edi, mixBuffer + mov esi, samples + shl eax, 2 + add edi, eax + neg eax + + loop16: + + movaps xmm0, [edi+eax+0*16] + movaps xmm2, [edi+eax+1*16] + movaps xmm4, [edi+eax+2*16] + movaps xmm6, [edi+eax+3*16] + + add esi, 4*4*2 + + movhlps xmm1, xmm0 + movhlps xmm3, xmm2 + movhlps xmm5, xmm4 + movhlps xmm7, xmm6 + + prefetchnta [edi+eax+64] + + cvtps2pi mm0, xmm0 + cvtps2pi mm2, xmm2 + cvtps2pi mm4, xmm4 + cvtps2pi mm6, xmm6 + + prefetchnta [edi+eax+128] + + cvtps2pi mm1, xmm1 + cvtps2pi mm3, xmm3 + cvtps2pi mm5, xmm5 + cvtps2pi mm7, xmm7 + + add eax, 4*16 + + packssdw mm0, mm1 + packssdw mm2, mm3 + packssdw mm4, mm5 + packssdw mm6, mm7 + + movq [esi-4*4*2], mm0 + movq [esi-3*4*2], mm2 + movq [esi-2*4*2], mm4 + movq [esi-1*4*2], mm6 + + jl loop16 + + emms + } + +#else + + for ( int i = 0; i < numSamples; i++ ) { + if ( mixBuffer[i] <= -32768.0f ) { + samples[i] = -32768; + } else if ( mixBuffer[i] >= 32767.0f ) { + samples[i] = 32767; + } else { + samples[i] = (short) mixBuffer[i]; + } + } + +#endif +} + +#endif /* _WIN32 */ diff --git a/idlib/math/Simd_SSE.h b/idlib/math/Simd_SSE.h new file mode 100644 index 000000000..27b0668b3 --- /dev/null +++ b/idlib/math/Simd_SSE.h @@ -0,0 +1,134 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_SSE_H__ +#define __MATH_SIMD_SSE_H__ + +/* +=============================================================================== + + SSE implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_SSE : public idSIMD_MMX { +public: +#if defined(MACOS_X) && defined(__i386__) + virtual const char * VPCALL GetName( void ) const; + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); + +#elif defined(_WIN32) + virtual const char * VPCALL GetName( void ) const; + + virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); + virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); + virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); + + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); + virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); + virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); + virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); + + virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); + virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + + virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); + virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); + virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); + + virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); + virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); + virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); + + virtual void VPCALL Zero16( float *dst, const int count ); + virtual void VPCALL Negate16( float *dst, const int count ); + virtual void VPCALL Copy16( float *dst, const float *src, const int count ); + virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); + virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); + virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); + virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); + + virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); + virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); + virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); + virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); + virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); + virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); + + virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); + virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); + virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); + virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); + virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); + virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); + virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); + virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); + virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); + virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); + virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); + + virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); + virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); + virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); + virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); + +#endif +}; + +#endif /* !__MATH_SIMD_SSE_H__ */ diff --git a/idlib/math/Simd_SSE2.cpp b/idlib/math/Simd_SSE2.cpp new file mode 100644 index 000000000..e3a46cca1 --- /dev/null +++ b/idlib/math/Simd_SSE2.cpp @@ -0,0 +1,868 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_MMX.h" +#include "Simd_SSE.h" +#include "Simd_SSE2.h" + + +//=============================================================== +// +// SSE2 implementation of idSIMDProcessor +// +//=============================================================== +#if defined(MACOS_X) && defined(__i386__) + +#include + +#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) +#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) + +/* +============ +idSIMD_SSE2::GetName +============ +*/ +const char * idSIMD_SSE2::GetName( void ) const { + return "MMX & SSE & SSE2"; +} + +/* +============ +idSIMD_SSE::CmpLT + + dst[i] |= ( src0[i] < constant ) << bitNum; +============ +*/ +void VPCALL idSIMD_SSE2::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { + int i, cnt, pre, post; + float *aligned; + __m128 xmm0, xmm1; + __m128i xmm0i; + int cnt_l; + char *src0_p; + char *constant_p; + char *dst_p; + int mask_l; + int dst_l; + + /* if the float array is not aligned on a 4 byte boundary */ + if ( ((int) src0) & 3 ) { + /* unaligned memory access */ + pre = 0; + cnt = count >> 2; + post = count - (cnt<<2); + + /* + __asm mov edx, cnt + __asm test edx, edx + __asm je doneCmp + */ + cnt_l = cnt; + if(cnt_l != 0) { + /* + __asm push ebx + __asm neg edx + __asm mov esi, src0 + __asm prefetchnta [esi+64] + __asm movss xmm1, constant + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + __asm mov edi, dst + __asm mov cl, bitNum + */ + cnt_l = -cnt_l; + src0_p = (char *) src0; + _mm_prefetch(src0_p+64, _MM_HINT_NTA); + constant_p = (char *) &constant; + xmm1 = _mm_load_ss((float *)constant_p); + xmm1 = _mm_shuffle_ps(xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 )); + dst_p = (char *)dst; + /* + __asm loopNA: + */ + do { + /* + __asm movups xmm0, [esi] + __asm prefetchnta [esi+128] + __asm cmpltps xmm0, xmm1 + __asm movmskps eax, xmm0 \ + __asm mov ah, al + __asm shr ah, 1 + __asm mov bx, ax + __asm shl ebx, 14 + __asm mov bx, ax + __asm and ebx, 0x01010101 + __asm shl ebx, cl + __asm or ebx, dword ptr [edi] + __asm mov dword ptr [edi], ebx + __asm add esi, 16 + __asm add edi, 4 + __asm inc edx + __asm jl loopNA + __asm pop ebx + */ + xmm0 = _mm_loadu_ps((float *) src0_p); + _mm_prefetch(src0_p+128, _MM_HINT_NTA); + xmm0 = _mm_cmplt_ps(xmm0, xmm1); + // Simplify using SSE2 + xmm0i = (__m128i) xmm0; + xmm0i = _mm_packs_epi32(xmm0i, xmm0i); + xmm0i = _mm_packs_epi16(xmm0i, xmm0i); + mask_l = _mm_cvtsi128_si32(xmm0i); + // End + mask_l = mask_l & 0x01010101; + mask_l = mask_l << bitNum; + dst_l = *((int *) dst_p); + mask_l = mask_l | dst_l; + *((int *) dst_p) = mask_l; + src0_p = src0_p + 16; + dst_p = dst_p + 4; + cnt_l = cnt_l + 1; + } while (cnt_l < 0); + } + } + else { + /* aligned memory access */ + aligned = (float *) ((((int) src0) + 15) & ~15); + if ( (int)aligned > ((int)src0) + count ) { + pre = count; + post = 0; + } + else { + pre = aligned - src0; + cnt = (count - pre) >> 2; + post = count - pre - (cnt<<2); + /* + __asm mov edx, cnt + __asm test edx, edx + __asm je doneCmp + */ + cnt_l = cnt; + if(cnt_l != 0) { + /* + __asm push ebx + __asm neg edx + __asm mov esi, aligned + __asm prefetchnta [esi+64] + __asm movss xmm1, constant + __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) + __asm mov edi, dst + __asm add edi, pre + __asm mov cl, bitNum + */ + cnt_l = -cnt_l; + src0_p = (char *) src0; + _mm_prefetch(src0_p+64, _MM_HINT_NTA); + constant_p = (char *) &constant; + xmm1 = _mm_load_ss((float *)constant_p); + xmm1 = _mm_shuffle_ps(xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 )); + dst_p = (char *)dst; + dst_p = dst_p + pre; + /* + __asm loopA: + */ + do { + /* + __asm movaps xmm0, [esi] + __asm prefetchnta [esi+128] + __asm cmpltps xmm0, xmm1 + __asm movmskps eax, xmm0 \ + __asm mov ah, al + __asm shr ah, 1 + __asm mov bx, ax + __asm shl ebx, 14 + __asm mov bx, ax + __asm and ebx, 0x01010101 + __asm shl ebx, cl + __asm or ebx, dword ptr [edi] + __asm mov dword ptr [edi], ebx + __asm add esi, 16 + __asm add edi, 4 + __asm inc edx + __asm jl loopA + __asm pop ebx + */ + xmm0 = _mm_load_ps((float *) src0_p); + _mm_prefetch(src0_p+128, _MM_HINT_NTA); + xmm0 = _mm_cmplt_ps(xmm0, xmm1); + // Simplify using SSE2 + xmm0i = (__m128i) xmm0; + xmm0i = _mm_packs_epi32(xmm0i, xmm0i); + xmm0i = _mm_packs_epi16(xmm0i, xmm0i); + mask_l = _mm_cvtsi128_si32(xmm0i); + // End + mask_l = mask_l & 0x01010101; + mask_l = mask_l << bitNum; + dst_l = *((int *) dst_p); + mask_l = mask_l | dst_l; + *((int *) dst_p) = mask_l; + src0_p = src0_p + 16; + dst_p = dst_p + 4; + cnt_l = cnt_l + 1; + } while (cnt_l < 0); + } + } + } + /* + doneCmp: + */ + float c = constant; + for ( i = 0; i < pre; i++ ) { + dst[i] |= ( src0[i] < c ) << bitNum; + } + for ( i = count - post; i < count; i++ ) { + dst[i] |= ( src0[i] < c ) << bitNum; + } +} + +#elif defined(_WIN32) + +#include + +#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) +#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) +#define SHUFFLEPD( x, y ) (( (x) & 1 ) << 1 | ( (y) & 1 )) +#define R_SHUFFLEPD( x, y ) (( (y) & 1 ) << 1 | ( (x) & 1 )) + + +#define ALIGN4_INIT1( X, INIT ) ALIGN16( static X[4] ) = { INIT, INIT, INIT, INIT } +#define ALIGN4_INIT4( X, I0, I1, I2, I3 ) ALIGN16( static X[4] ) = { I0, I1, I2, I3 } +#define ALIGN8_INIT1( X, INIT ) ALIGN16( static X[8] ) = { INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT } + +ALIGN8_INIT1( unsigned short SIMD_W_zero, 0 ); +ALIGN8_INIT1( unsigned short SIMD_W_maxShort, 1<<15 ); + +ALIGN4_INIT4( unsigned long SIMD_SP_singleSignBitMask, (unsigned long) ( 1 << 31 ), 0, 0, 0 ); +ALIGN4_INIT1( unsigned long SIMD_SP_signBitMask, (unsigned long) ( 1 << 31 ) ); +ALIGN4_INIT1( unsigned long SIMD_SP_absMask, (unsigned long) ~( 1 << 31 ) ); +ALIGN4_INIT1( unsigned long SIMD_SP_infinityMask, (unsigned long) ~( 1 << 23 ) ); + +ALIGN4_INIT1( float SIMD_SP_zero, 0.0f ); +ALIGN4_INIT1( float SIMD_SP_one, 1.0f ); +ALIGN4_INIT1( float SIMD_SP_two, 2.0f ); +ALIGN4_INIT1( float SIMD_SP_three, 3.0f ); +ALIGN4_INIT1( float SIMD_SP_four, 4.0f ); +ALIGN4_INIT1( float SIMD_SP_maxShort, (1<<15) ); +ALIGN4_INIT1( float SIMD_SP_tiny, 1e-10f ); +ALIGN4_INIT1( float SIMD_SP_PI, idMath::PI ); +ALIGN4_INIT1( float SIMD_SP_halfPI, idMath::HALF_PI ); +ALIGN4_INIT1( float SIMD_SP_twoPI, idMath::TWO_PI ); +ALIGN4_INIT1( float SIMD_SP_oneOverTwoPI, 1.0f / idMath::TWO_PI ); +ALIGN4_INIT1( float SIMD_SP_infinity, idMath::INFINITY ); + + +/* +============ +idSIMD_SSE2::GetName +============ +*/ +const char * idSIMD_SSE2::GetName( void ) const { + return "MMX & SSE & SSE2"; +} + +#if 0 // the SSE2 code is ungodly slow + +/* +============ +idSIMD_SSE2::MatX_LowerTriangularSolve + + solves x in Lx = b for the n * n sub-matrix of L + if skip > 0 the first skip elements of x are assumed to be valid already + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_SSE2::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { + int nc; + const float *lptr; + + if ( skip >= n ) { + return; + } + + lptr = L[skip]; + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + #define NSKIP( n, s ) ((n<<3)|(s&7)) + switch( NSKIP( n, skip ) ) { + case NSKIP( 1, 0 ): x[0] = b[0]; + return; + case NSKIP( 2, 0 ): x[0] = b[0]; + case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + return; + case NSKIP( 3, 0 ): x[0] = b[0]; + case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + return; + case NSKIP( 4, 0 ): x[0] = b[0]; + case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + return; + case NSKIP( 5, 0 ): x[0] = b[0]; + case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + return; + case NSKIP( 6, 0 ): x[0] = b[0]; + case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + return; + case NSKIP( 7, 0 ): x[0] = b[0]; + case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; + case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; + case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; + case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; + return; + } + return; + } + + // process first 4 rows + switch( skip ) { + case 0: x[0] = b[0]; + case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; + case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; + case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; + skip = 4; + } + + lptr = L[skip]; + + __asm { + push ebx + mov eax, skip // eax = i + shl eax, 2 // eax = i*4 + mov edx, n // edx = n + shl edx, 2 // edx = n*4 + mov esi, x // esi = x + mov edi, lptr // edi = lptr + add esi, eax + add edi, eax + mov ebx, b // ebx = b + // aligned + looprow: + mov ecx, eax + neg ecx + cvtps2pd xmm0, [esi+ecx] + cvtps2pd xmm2, [edi+ecx] + mulpd xmm0, xmm2 + cvtps2pd xmm1, [esi+ecx+8] + cvtps2pd xmm3, [edi+ecx+8] + mulpd xmm1, xmm3 + add ecx, 20*4 + jg donedot16 + dot16: + cvtps2pd xmm2, [esi+ecx-(16*4)] + cvtps2pd xmm3, [edi+ecx-(16*4)] + cvtps2pd xmm4, [esi+ecx-(14*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(14*4)] + addpd xmm0, xmm2 + cvtps2pd xmm2, [esi+ecx-(12*4)] + mulpd xmm4, xmm5 + cvtps2pd xmm3, [edi+ecx-(12*4)] + addpd xmm1, xmm4 + cvtps2pd xmm4, [esi+ecx-(10*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(10*4)] + addpd xmm0, xmm2 + cvtps2pd xmm2, [esi+ecx-(8*4)] + mulpd xmm4, xmm5 + cvtps2pd xmm3, [edi+ecx-(8*4)] + addpd xmm1, xmm4 + cvtps2pd xmm4, [esi+ecx-(6*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(6*4)] + addpd xmm0, xmm2 + cvtps2pd xmm2, [esi+ecx-(4*4)] + mulpd xmm4, xmm5 + cvtps2pd xmm3, [edi+ecx-(4*4)] + addpd xmm1, xmm4 + cvtps2pd xmm4, [esi+ecx-(2*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(2*4)] + addpd xmm0, xmm2 + add ecx, 16*4 + mulpd xmm4, xmm5 + addpd xmm1, xmm4 + jle dot16 + donedot16: + sub ecx, 8*4 + jg donedot8 + dot8: + cvtps2pd xmm2, [esi+ecx-(8*4)] + cvtps2pd xmm3, [edi+ecx-(8*4)] + cvtps2pd xmm7, [esi+ecx-(6*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(6*4)] + addpd xmm0, xmm2 + cvtps2pd xmm6, [esi+ecx-(4*4)] + mulpd xmm7, xmm5 + cvtps2pd xmm3, [edi+ecx-(4*4)] + addpd xmm1, xmm7 + cvtps2pd xmm4, [esi+ecx-(2*4)] + mulpd xmm6, xmm3 + cvtps2pd xmm7, [edi+ecx-(2*4)] + addpd xmm0, xmm6 + add ecx, 8*4 + mulpd xmm4, xmm7 + addpd xmm1, xmm4 + donedot8: + sub ecx, 4*4 + jg donedot4 + dot4: + cvtps2pd xmm2, [esi+ecx-(4*4)] + cvtps2pd xmm3, [edi+ecx-(4*4)] + cvtps2pd xmm4, [esi+ecx-(2*4)] + mulpd xmm2, xmm3 + cvtps2pd xmm5, [edi+ecx-(2*4)] + addpd xmm0, xmm2 + add ecx, 4*4 + mulpd xmm4, xmm5 + addpd xmm1, xmm4 + donedot4: + addpd xmm0, xmm1 + movaps xmm1, xmm0 + shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 0 ) + addsd xmm0, xmm1 + sub ecx, 4*4 + jz dot0 + add ecx, 4 + jz dot1 + add ecx, 4 + jz dot2 + //dot3: + cvtss2sd xmm1, [esi-(3*4)] + cvtss2sd xmm2, [edi-(3*4)] + mulsd xmm1, xmm2 + addsd xmm0, xmm1 + dot2: + cvtss2sd xmm3, [esi-(2*4)] + cvtss2sd xmm4, [edi-(2*4)] + mulsd xmm3, xmm4 + addsd xmm0, xmm3 + dot1: + cvtss2sd xmm5, [esi-(1*4)] + cvtss2sd xmm6, [edi-(1*4)] + mulsd xmm5, xmm6 + addsd xmm0, xmm5 + dot0: + cvtss2sd xmm1, [ebx+eax] + subsd xmm1, xmm0 + cvtsd2ss xmm0, xmm1 + movss [esi], xmm0 + add eax, 4 + cmp eax, edx + jge done + add esi, 4 + mov ecx, nc + shl ecx, 2 + add edi, ecx + add edi, 4 + jmp looprow + // done + done: + pop ebx + } +} + +/* +============ +idSIMD_SSE2::MatX_LowerTriangularSolveTranspose + + solves x in L'x = b for the n * n sub-matrix of L + L has to be a lower triangular matrix with (implicit) ones on the diagonal + x == b is allowed +============ +*/ +void VPCALL idSIMD_SSE2::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { + int nc; + const float *lptr; + + lptr = L.ToFloatPtr(); + nc = L.GetNumColumns(); + + // unrolled cases for n < 8 + if ( n < 8 ) { + switch( n ) { + case 0: + return; + case 1: + x[0] = b[0]; + return; + case 2: + x[1] = b[1]; + x[0] = b[0] - lptr[1*nc+0] * x[1]; + return; + case 3: + x[2] = b[2]; + x[1] = b[1] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 4: + x[3] = b[3]; + x[2] = b[2] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 5: + x[4] = b[4]; + x[3] = b[3] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 6: + x[5] = b[5]; + x[4] = b[4] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + case 7: + x[6] = b[6]; + x[5] = b[5] - lptr[6*nc+5] * x[6]; + x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; + x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; + x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; + x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; + x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; + return; + } + return; + } + + int i, j, m; + float *xptr; + double s0; + + // if the number of columns is not a multiple of 2 we're screwed for alignment. + // however, if the number of columns is a multiple of 2 but the number of to be + // processed rows is not a multiple of 2 we can still run 8 byte aligned + m = n; + if ( m & 1 ) { + m--; + x[m] = b[m]; + + lptr = L[m] + m - 4; + xptr = x + m; + __asm { + push ebx + mov eax, m // eax = i + mov esi, xptr // esi = xptr + mov edi, lptr // edi = lptr + mov ebx, b // ebx = b + mov edx, nc // edx = nc*sizeof(float) + shl edx, 2 + process4rows_1: + cvtps2pd xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] + cvtps2pd xmm2, [ebx+eax*4-8] // load b[i-4], b[i-3] + xor ecx, ecx + sub eax, m + neg eax + jz done4x4_1 + process4x4_1: // process 4x4 blocks + cvtps2pd xmm3, [edi] + cvtps2pd xmm4, [edi+8] + add edi, edx + cvtss2sd xmm5, [esi+4*ecx+0] + shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) + mulpd xmm3, xmm5 + cvtps2pd xmm1, [edi] + mulpd xmm4, xmm5 + cvtps2pd xmm6, [edi+8] + subpd xmm0, xmm3 + subpd xmm2, xmm4 + add edi, edx + cvtss2sd xmm7, [esi+4*ecx+4] + shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) + mulpd xmm1, xmm7 + cvtps2pd xmm3, [edi] + mulpd xmm6, xmm7 + cvtps2pd xmm4, [edi+8] + subpd xmm0, xmm1 + subpd xmm2, xmm6 + add edi, edx + cvtss2sd xmm5, [esi+4*ecx+8] + shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) + mulpd xmm3, xmm5 + cvtps2pd xmm1, [edi] + mulpd xmm4, xmm5 + cvtps2pd xmm6, [edi+8] + subpd xmm0, xmm3 + subpd xmm2, xmm4 + add edi, edx + cvtss2sd xmm7, [esi+4*ecx+12] + shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) + mulpd xmm1, xmm7 + add ecx, 4 + mulpd xmm6, xmm7 + cmp ecx, eax + subpd xmm0, xmm1 + subpd xmm2, xmm6 + jl process4x4_1 + done4x4_1: // process left over of the 4 rows + cvtps2pd xmm3, [edi] + cvtps2pd xmm4, [edi+8] + cvtss2sd xmm5, [esi+4*ecx] + shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) + mulpd xmm3, xmm5 + mulpd xmm4, xmm5 + subpd xmm0, xmm3 + subpd xmm2, xmm4 + imul ecx, edx + sub edi, ecx + neg eax + + add eax, m + sub eax, 4 + movapd xmm1, xmm0 + shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 1 ) + movapd xmm3, xmm2 + shufpd xmm3, xmm3, R_SHUFFLEPD( 1, 1 ) + sub edi, edx + cvtsd2ss xmm7, xmm3 + movss [esi-4], xmm7 // xptr[-1] = s3 + movsd xmm4, xmm3 + movsd xmm5, xmm3 + cvtss2sd xmm7, [edi+8] + mulsd xmm3, xmm7 // lptr[-1*nc+2] * s3 + cvtss2sd xmm7, [edi+4] + mulsd xmm4, xmm7 // lptr[-1*nc+1] * s3 + cvtss2sd xmm7, [edi] + mulsd xmm5, xmm7 // lptr[-1*nc+0] * s3 + subsd xmm2, xmm3 + cvtsd2ss xmm7, xmm2 + movss [esi-8], xmm7 // xptr[-2] = s2 + movsd xmm6, xmm2 + sub edi, edx + subsd xmm0, xmm5 + subsd xmm1, xmm4 + cvtss2sd xmm7, [edi+4] + mulsd xmm2, xmm7 // lptr[-2*nc+1] * s2 + cvtss2sd xmm7, [edi] + mulsd xmm6, xmm7 // lptr[-2*nc+0] * s2 + subsd xmm1, xmm2 + cvtsd2ss xmm7, xmm1 + movss [esi-12], xmm7 // xptr[-3] = s1 + subsd xmm0, xmm6 + sub edi, edx + cmp eax, 4 + cvtss2sd xmm7, [edi] + mulsd xmm1, xmm7 // lptr[-3*nc+0] * s1 + subsd xmm0, xmm1 + cvtsd2ss xmm7, xmm0 + movss [esi-16], xmm7 // xptr[-4] = s0 + jl done4rows_1 + sub edi, edx + sub edi, 16 + sub esi, 16 + jmp process4rows_1 + done4rows_1: + pop ebx + } + } + else { + lptr = L.ToFloatPtr() + m * L.GetNumColumns() + m - 4; + xptr = x + m; + __asm { + push ebx + mov eax, m // eax = i + mov esi, xptr // esi = xptr + mov edi, lptr // edi = lptr + mov ebx, b // ebx = b + mov edx, nc // edx = nc*sizeof(float) + shl edx, 2 + process4rows: + cvtps2pd xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] + cvtps2pd xmm2, [ebx+eax*4-8] // load b[i-4], b[i-3] + sub eax, m + jz done4x4 + neg eax + xor ecx, ecx + process4x4: // process 4x4 blocks + cvtps2pd xmm3, [edi] + cvtps2pd xmm4, [edi+8] + add edi, edx + cvtss2sd xmm5, [esi+4*ecx+0] + shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) + mulpd xmm3, xmm5 + cvtps2pd xmm1, [edi] + mulpd xmm4, xmm5 + cvtps2pd xmm6, [edi+8] + subpd xmm0, xmm3 + subpd xmm2, xmm4 + add edi, edx + cvtss2sd xmm7, [esi+4*ecx+4] + shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) + mulpd xmm1, xmm7 + cvtps2pd xmm3, [edi] + mulpd xmm6, xmm7 + cvtps2pd xmm4, [edi+8] + subpd xmm0, xmm1 + subpd xmm2, xmm6 + add edi, edx + cvtss2sd xmm5, [esi+4*ecx+8] + shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) + mulpd xmm3, xmm5 + cvtps2pd xmm1, [edi] + mulpd xmm4, xmm5 + cvtps2pd xmm6, [edi+8] + subpd xmm0, xmm3 + subpd xmm2, xmm4 + add edi, edx + cvtss2sd xmm7, [esi+4*ecx+12] + shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) + mulpd xmm1, xmm7 + add ecx, 4 + mulpd xmm6, xmm7 + cmp ecx, eax + subpd xmm0, xmm1 + subpd xmm2, xmm6 + jl process4x4 + imul ecx, edx + sub edi, ecx + neg eax + done4x4: // process left over of the 4 rows + add eax, m + sub eax, 4 + movapd xmm1, xmm0 + shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 1 ) + movapd xmm3, xmm2 + shufpd xmm3, xmm3, R_SHUFFLEPD( 1, 1 ) + sub edi, edx + cvtsd2ss xmm7, xmm3 + movss [esi-4], xmm7 // xptr[-1] = s3 + movsd xmm4, xmm3 + movsd xmm5, xmm3 + cvtss2sd xmm7, [edi+8] + mulsd xmm3, xmm7 // lptr[-1*nc+2] * s3 + cvtss2sd xmm7, [edi+4] + mulsd xmm4, xmm7 // lptr[-1*nc+1] * s3 + cvtss2sd xmm7, [edi] + mulsd xmm5, xmm7 // lptr[-1*nc+0] * s3 + subsd xmm2, xmm3 + cvtsd2ss xmm7, xmm2 + movss [esi-8], xmm7 // xptr[-2] = s2 + movsd xmm6, xmm2 + sub edi, edx + subsd xmm0, xmm5 + subsd xmm1, xmm4 + cvtss2sd xmm7, [edi+4] + mulsd xmm2, xmm7 // lptr[-2*nc+1] * s2 + cvtss2sd xmm7, [edi] + mulsd xmm6, xmm7 // lptr[-2*nc+0] * s2 + subsd xmm1, xmm2 + cvtsd2ss xmm7, xmm1 + movss [esi-12], xmm7 // xptr[-3] = s1 + subsd xmm0, xmm6 + sub edi, edx + cmp eax, 4 + cvtss2sd xmm7, [edi] + mulsd xmm1, xmm7 // lptr[-3*nc+0] * s1 + subsd xmm0, xmm1 + cvtsd2ss xmm7, xmm0 + movss [esi-16], xmm7 // xptr[-4] = s0 + jl done4rows + sub edi, edx + sub edi, 16 + sub esi, 16 + jmp process4rows + done4rows: + pop ebx + } + } + + // process left over rows + for ( i = (m&3)-1; i >= 0; i-- ) { + s0 = b[i]; + lptr = L[i+1] + i; + for ( j = i + 1; j < m; j++ ) { + s0 -= lptr[0] * x[j]; + lptr += nc; + } + x[i] = s0; + } +} + +#endif + +/* +============ +idSIMD_SSE2::MixedSoundToSamples +============ +*/ +void VPCALL idSIMD_SSE2::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { + + assert( ( numSamples % MIXBUFFER_SAMPLES ) == 0 ); + + __asm { + + mov eax, numSamples + mov edi, mixBuffer + mov esi, samples + shl eax, 2 + add edi, eax + neg eax + + loop16: + + movaps xmm0, [edi+eax+0*16] + movaps xmm1, [edi+eax+1*16] + movaps xmm2, [edi+eax+2*16] + movaps xmm3, [edi+eax+3*16] + + add esi, 4*4*2 + + cvtps2dq xmm4, xmm0 + cvtps2dq xmm5, xmm1 + cvtps2dq xmm6, xmm2 + cvtps2dq xmm7, xmm3 + + prefetchnta [edi+eax+128] + + packssdw xmm4, xmm5 + packssdw xmm6, xmm7 + + add eax, 4*16 + + movlps [esi-4*4*2], xmm4 // FIXME: should not use movlps/movhps to move integer data + movhps [esi-3*4*2], xmm4 + movlps [esi-2*4*2], xmm6 + movhps [esi-1*4*2], xmm6 + + jl loop16 + } +} + +#endif /* _WIN32 */ diff --git a/idlib/math/Simd_SSE2.h b/idlib/math/Simd_SSE2.h new file mode 100644 index 000000000..2dbcfff21 --- /dev/null +++ b/idlib/math/Simd_SSE2.h @@ -0,0 +1,48 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_SSE2_H__ +#define __MATH_SIMD_SSE2_H__ + +/* +=============================================================================== + + SSE2 implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_SSE2 : public idSIMD_SSE { +public: +#if defined(MACOS_X) && defined(__i386__) + virtual const char * VPCALL GetName( void ) const; + virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); + +#elif defined(_WIN32) + virtual const char * VPCALL GetName( void ) const; + + //virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); + //virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); + + virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); + +#endif +}; + +#endif /* !__MATH_SIMD_SSE2_H__ */ diff --git a/idlib/math/Simd_SSE3.cpp b/idlib/math/Simd_SSE3.cpp new file mode 100644 index 000000000..9cb5782e6 --- /dev/null +++ b/idlib/math/Simd_SSE3.cpp @@ -0,0 +1,358 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +#include "Simd_Generic.h" +#include "Simd_MMX.h" +#include "Simd_SSE.h" +#include "Simd_SSE2.h" +#include "Simd_SSE3.h" + + +//=============================================================== +// +// SSE3 implementation of idSIMDProcessor +// +//=============================================================== + +#if defined(MACOS_X) && defined(__i386__) + +/* +============ +idSIMD_SSE3::GetName +============ +*/ +const char * idSIMD_SSE3::GetName( void ) const { + return "MMX & SSE & SSE2 & SSE3"; +} + +#elif defined(_WIN32) + +#include + +#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) +#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) +#define SHUFFLEPD( x, y ) (( (x) & 1 ) << 1 | ( (y) & 1 )) +#define R_SHUFFLEPD( x, y ) (( (y) & 1 ) << 1 | ( (x) & 1 )) + +/* + + The first argument of an instruction macro is the destination + and the second argument is the source operand. The destination + operand can be _xmm0 to _xmm7 only. The source operand can be + any one of the registers _xmm0 to _xmm7 or _eax, _ecx, _edx, _esp, + _ebp, _ebx, _esi, or _edi that contains the effective address. + + For instance: haddps xmm0, xmm1 + becomes: haddps( _xmm0, _xmm1 ) + and: haddps xmm0, [esi] + becomes: haddps( _xmm0, _esi ) + + The ADDRESS_ADDC macro can be used when the effective source address + is formed by adding a constant to a general purpose register. + For instance: haddps xmm0, [esi+48] + becomes: haddps( _xmm0, ADDRESS_ADDC( _esi, 48 ) ) + + The ADDRESS_ADDR macro can be used when the effective source address + is formed by adding two general purpose registers. + For instance: haddps xmm0, [esi+eax] + becomes: haddps( _xmm0, ADDRESS_ADDR( _esi, _eax ) ) + + The ADDRESS_ADDRC macro can be used when the effective source address + is formed by adding two general purpose registers and a constant. + The constant must be in the range [-128, 127]. + For instance: haddps xmm0, [esi+eax+48] + becomes: haddps( _xmm0, ADDRESS_ADDRC( _esi, _eax, 48 ) ) + + The ADDRESS_SCALEADDR macro can be used when the effective source address is formed + by adding a scaled general purpose register to another general purpose register. + The scale must be either 1, 2, 4 or 8. + For instance: haddps xmm0, [esi+eax*4] + becomes: haddps( _xmm0, ADDRESS_SCALEADDR( _esi, _eax, 4 ) ) + + The ADDRESS_SCALEADDRC macro can be used when the effective source address is formed + by adding a scaled general purpose register to another general purpose register and + also adding a constant. The scale must be either 1, 2, 4 or 8. The constant must + be in the range [-128, 127]. + For instance: haddps xmm0, [esi+eax*4+64] + becomes: haddps( _xmm0, ADDRESS_SCALEADDRC( _esi, _eax, 4, 64 ) ) + +*/ + +#define _eax 0x00 +#define _ecx 0x01 +#define _edx 0x02 +#define _ebx 0x03 +#define _esp 0x04 +#define _ebp 0x05 +#define _esi 0x06 +#define _edi 0x07 + +#define _xmm0 0xC0 +#define _xmm1 0xC1 +#define _xmm2 0xC2 +#define _xmm3 0xC3 +#define _xmm4 0xC4 +#define _xmm5 0xC5 +#define _xmm6 0xC6 +#define _xmm7 0xC7 + +#define RSCALE( s ) ( (s&2)<<5 ) | ( (s&4)<<5 ) | ( (s&8)<<3 ) | ( (s&8)<<4 ) + +#define ADDRESS_ADDC( reg0, constant ) 0x40 | ( reg0 & 7 ) \ + _asm _emit constant + +#define ADDRESS_ADDR( reg0, reg1 ) 0x04 \ + _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) + +#define ADDRESS_ADDRC( reg0, reg1, constant ) 0x44 \ + _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) \ + _asm _emit constant + +#define ADDRESS_SCALEADDR( reg0, reg1, scale ) 0x04 \ + _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) | RSCALE( scale ) + +#define ADDRESS_SCALEADDRC( reg0, reg1, scale, constant ) 0x44 \ + _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) | RSCALE( scale ) \ + _asm _emit constant + + +// Packed Single-FP Add/Subtract ( dst[0]=dst[0]+src[0], dst[1]=dst[1]-src[1], dst[2]=dst[2]+src[2], dst[3]=dst[3]-src[3] ) +#define addsubps( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0xD0 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Packed Double-FP Add/Subtract ( dst[0]=dst[0]+src[0], dst[1]=dst[1]-src[1] ) +#define addsubpd( dst, src ) \ + _asm _emit 0x66 \ + _asm _emit 0x0F \ + _asm _emit 0xD0 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Packed Single-FP Horizontal Add ( dst[0]=dst[0]+dst[1], dst[1]=dst[2]+dst[3], dst[2]=src[0]+src[1], dst[3]=src[2]+src[3] ) +#define haddps( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0x7C \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Packed Double-FP Horizontal Add ( dst[0]=dst[0]+dst[1], dst[1]=src[0]+src[1] ) +#define haddpd( dst, src ) \ + _asm _emit 0x66 \ + _asm _emit 0x0F \ + _asm _emit 0x7C \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Packed Single-FP Horizontal Subtract ( dst[0]=dst[0]-dst[1], dst[1]=dst[2]-dst[3], dst[2]=src[0]-src[1], dst[3]=src[2]-src[3] ) +#define hsubps( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0x7D \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Packed Double-FP Horizontal Subtract ( dst[0]=dst[0]-dst[1], dst[1]=src[0]-src[1] ) +#define hsubpd( dst, src ) \ + _asm _emit 0x66 \ + _asm _emit 0x0F \ + _asm _emit 0x7D \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Move Packed Single-FP Low and Duplicate ( dst[0]=src[0], dst[1]=src[0], dst[2]=src[2], dst[3]=src[2] ) +#define movsldup( dst, src ) \ + _asm _emit 0xF3 \ + _asm _emit 0x0F \ + _asm _emit 0x12 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Move One Double-FP Low and Duplicate ( dst[0]=src[0], dst[1]=src[0] ) +#define movdldup( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0x12 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Move Packed Single-FP High and Duplicate ( dst[0]=src[1], dst[1]=src[1], dst[2]=src[3], dst[3]=src[3] ) +#define movshdup( dst, src ) \ + _asm _emit 0xF3 \ + _asm _emit 0x0F \ + _asm _emit 0x16 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Move One Double-FP High and Duplicate ( dst[0]=src[1], dst[1]=src[1] ) +#define movdhdup( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0x16 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + +// Load Unaligned Integer 128 bits +#define lddqu( dst, src ) \ + _asm _emit 0xF2 \ + _asm _emit 0x0F \ + _asm _emit 0xF0 \ + _asm _emit ( ( dst & 7 ) << 3 ) | src + + +#define DRAWVERT_SIZE 60 +#define DRAWVERT_XYZ_OFFSET (0*4) +#define DRAWVERT_ST_OFFSET (3*4) +#define DRAWVERT_NORMAL_OFFSET (5*4) +#define DRAWVERT_TANGENT0_OFFSET (8*4) +#define DRAWVERT_TANGENT1_OFFSET (11*4) +#define DRAWVERT_COLOR_OFFSET (14*4) + +#define JOINTQUAT_SIZE (7*4) +#define JOINTMAT_SIZE (4*3*4) +#define JOINTWEIGHT_SIZE (4*4) + + +/* +============ +SSE3_Dot +============ +*/ +float SSE3_Dot( const idVec4 &v1, const idVec4 &v2 ) { + float d; + __asm { + mov esi, v1 + mov edi, v2 + movaps xmm0, [esi] + mulps xmm0, [edi] + haddps( _xmm0, _xmm0 ) + haddps( _xmm0, _xmm0 ) + movss d, xmm0 + } + return d; +} + +/* +============ +idSIMD_SSE3::GetName +============ +*/ +const char * idSIMD_SSE3::GetName( void ) const { + return "MMX & SSE & SSE2 & SSE3"; +} + +/* +============ +idSIMD_SSE3::TransformVerts +============ +*/ +void VPCALL idSIMD_SSE3::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) { +#if 1 + + assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); + assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); + assert( sizeof( idVec4 ) == JOINTWEIGHT_SIZE ); + assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); + + __asm + { + mov eax, numVerts + test eax, eax + jz done + imul eax, DRAWVERT_SIZE + + mov ecx, verts + mov edx, index + mov esi, weights + mov edi, joints + + add ecx, eax + neg eax + + loopVert: + mov ebx, [edx] + movaps xmm2, [esi] + add edx, 8 + movaps xmm0, xmm2 + add esi, JOINTWEIGHT_SIZE + movaps xmm1, xmm2 + + mulps xmm0, [edi+ebx+ 0] // xmm0 = m0, m1, m2, t0 + mulps xmm1, [edi+ebx+16] // xmm1 = m3, m4, m5, t1 + mulps xmm2, [edi+ebx+32] // xmm2 = m6, m7, m8, t2 + + cmp dword ptr [edx-4], 0 + + jne doneWeight + + loopWeight: + mov ebx, [edx] + movaps xmm5, [esi] + add edx, 8 + movaps xmm3, xmm5 + add esi, JOINTWEIGHT_SIZE + movaps xmm4, xmm5 + + mulps xmm3, [edi+ebx+ 0] // xmm3 = m0, m1, m2, t0 + mulps xmm4, [edi+ebx+16] // xmm4 = m3, m4, m5, t1 + mulps xmm5, [edi+ebx+32] // xmm5 = m6, m7, m8, t2 + + cmp dword ptr [edx-4], 0 + + addps xmm0, xmm3 + addps xmm1, xmm4 + addps xmm2, xmm5 + + je loopWeight + + doneWeight: + add eax, DRAWVERT_SIZE + + haddps( _xmm0, _xmm1 ) + haddps( _xmm2, _xmm0 ) + + movhps [ecx+eax-DRAWVERT_SIZE+0], xmm2 + + haddps( _xmm2, _xmm2 ) + + movss [ecx+eax-DRAWVERT_SIZE+8], xmm2 + + jl loopVert + done: + } + +#else + + int i, j; + const byte *jointsPtr = (byte *)joints; + + for( j = i = 0; i < numVerts; i++ ) { + idVec3 v; + + v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + while( index[j*2+1] == 0 ) { + j++; + v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; + } + j++; + + verts[i].xyz = v; + } + +#endif +} + +#endif /* _WIN32 */ diff --git a/idlib/math/Simd_SSE3.h b/idlib/math/Simd_SSE3.h new file mode 100644 index 000000000..3de041f39 --- /dev/null +++ b/idlib/math/Simd_SSE3.h @@ -0,0 +1,44 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_SIMD_SSE3_H__ +#define __MATH_SIMD_SSE3_H__ + +/* +=============================================================================== + + SSE3 implementation of idSIMDProcessor + +=============================================================================== +*/ + +class idSIMD_SSE3 : public idSIMD_SSE2 { +public: +#if defined(MACOS_X) && defined(__i386__) + virtual const char * VPCALL GetName( void ) const; + +#elif defined(_WIN32) + virtual const char * VPCALL GetName( void ) const; + + virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); + +#endif +}; + +#endif /* !__MATH_SIMD_SSE3_H__ */ diff --git a/idlib/math/Vector.cpp b/idlib/math/Vector.cpp new file mode 100644 index 000000000..f902aef4f --- /dev/null +++ b/idlib/math/Vector.cpp @@ -0,0 +1,388 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../precompiled.h" +#pragma hdrstop + +idVec2 vec2_origin( 0.0f, 0.0f ); +idVec3 vec3_origin( 0.0f, 0.0f, 0.0f ); +idVec4 vec4_origin( 0.0f, 0.0f, 0.0f, 0.0f ); +idVec5 vec5_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); +idVec6 vec6_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); +idVec6 vec6_infinity( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY ); + + +//=============================================================== +// +// idVec2 +// +//=============================================================== + +/* +============= +idVec2::ToString +============= +*/ +const char *idVec2::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============= +Lerp + +Linearly inperpolates one vector to another. +============= +*/ +void idVec2::Lerp( const idVec2 &v1, const idVec2 &v2, const float l ) { + if ( l <= 0.0f ) { + (*this) = v1; + } else if ( l >= 1.0f ) { + (*this) = v2; + } else { + (*this) = v1 + l * ( v2 - v1 ); + } +} + + +//=============================================================== +// +// idVec3 +// +//=============================================================== + +/* +============= +idVec3::ToYaw +============= +*/ +float idVec3::ToYaw( void ) const { + float yaw; + + if ( ( y == 0.0f ) && ( x == 0.0f ) ) { + yaw = 0.0f; + } else { + yaw = RAD2DEG( atan2( y, x ) ); + if ( yaw < 0.0f ) { + yaw += 360.0f; + } + } + + return yaw; +} + +/* +============= +idVec3::ToPitch +============= +*/ +float idVec3::ToPitch( void ) const { + float forward; + float pitch; + + if ( ( x == 0.0f ) && ( y == 0.0f ) ) { + if ( z > 0.0f ) { + pitch = 90.0f; + } else { + pitch = 270.0f; + } + } else { + forward = ( float )idMath::Sqrt( x * x + y * y ); + pitch = RAD2DEG( atan2( z, forward ) ); + if ( pitch < 0.0f ) { + pitch += 360.0f; + } + } + + return pitch; +} + +/* +============= +idVec3::ToAngles +============= +*/ +idAngles idVec3::ToAngles( void ) const { + float forward; + float yaw; + float pitch; + + if ( ( x == 0.0f ) && ( y == 0.0f ) ) { + yaw = 0.0f; + if ( z > 0.0f ) { + pitch = 90.0f; + } else { + pitch = 270.0f; + } + } else { + yaw = RAD2DEG( atan2( y, x ) ); + if ( yaw < 0.0f ) { + yaw += 360.0f; + } + + forward = ( float )idMath::Sqrt( x * x + y * y ); + pitch = RAD2DEG( atan2( z, forward ) ); + if ( pitch < 0.0f ) { + pitch += 360.0f; + } + } + + return idAngles( -pitch, yaw, 0.0f ); +} + +/* +============= +idVec3::ToPolar +============= +*/ +idPolar3 idVec3::ToPolar( void ) const { + float forward; + float yaw; + float pitch; + + if ( ( x == 0.0f ) && ( y == 0.0f ) ) { + yaw = 0.0f; + if ( z > 0.0f ) { + pitch = 90.0f; + } else { + pitch = 270.0f; + } + } else { + yaw = RAD2DEG( atan2( y, x ) ); + if ( yaw < 0.0f ) { + yaw += 360.0f; + } + + forward = ( float )idMath::Sqrt( x * x + y * y ); + pitch = RAD2DEG( atan2( z, forward ) ); + if ( pitch < 0.0f ) { + pitch += 360.0f; + } + } + return idPolar3( idMath::Sqrt( x * x + y * y + z * z ), yaw, -pitch ); +} + +/* +============= +idVec3::ToMat3 +============= +*/ +idMat3 idVec3::ToMat3( void ) const { + idMat3 mat; + float d; + + mat[0] = *this; + d = x * x + y * y; + if ( !d ) { + mat[1][0] = 1.0f; + mat[1][1] = 0.0f; + mat[1][2] = 0.0f; + } else { + d = idMath::InvSqrt( d ); + mat[1][0] = -y * d; + mat[1][1] = x * d; + mat[1][2] = 0.0f; + } + mat[2] = Cross( mat[1] ); + + return mat; +} + +/* +============= +idVec3::ToString +============= +*/ +const char *idVec3::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============= +Lerp + +Linearly inperpolates one vector to another. +============= +*/ +void idVec3::Lerp( const idVec3 &v1, const idVec3 &v2, const float l ) { + if ( l <= 0.0f ) { + (*this) = v1; + } else if ( l >= 1.0f ) { + (*this) = v2; + } else { + (*this) = v1 + l * ( v2 - v1 ); + } +} + +/* +============= +SLerp + +Spherical linear interpolation from v1 to v2. +Vectors are expected to be normalized. +============= +*/ +#define LERP_DELTA 1e-6 + +void idVec3::SLerp( const idVec3 &v1, const idVec3 &v2, const float t ) { + float omega, cosom, sinom, scale0, scale1; + + if ( t <= 0.0f ) { + (*this) = v1; + return; + } else if ( t >= 1.0f ) { + (*this) = v2; + return; + } + + cosom = v1 * v2; + if ( ( 1.0f - cosom ) > LERP_DELTA ) { + omega = acos( cosom ); + sinom = sin( omega ); + scale0 = sin( ( 1.0f - t ) * omega ) / sinom; + scale1 = sin( t * omega ) / sinom; + } else { + scale0 = 1.0f - t; + scale1 = t; + } + + (*this) = ( v1 * scale0 + v2 * scale1 ); +} + +/* +============= +ProjectSelfOntoSphere + +Projects the z component onto a sphere. +============= +*/ +void idVec3::ProjectSelfOntoSphere( const float radius ) { + float rsqr = radius * radius; + float len = Length(); + if ( len < rsqr * 0.5f ) { + z = sqrt( rsqr - len ); + } else { + z = rsqr / ( 2.0f * sqrt( len ) ); + } +} + + + +//=============================================================== +// +// idVec4 +// +//=============================================================== + +/* +============= +idVec4::ToString +============= +*/ +const char *idVec4::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============= +Lerp + +Linearly inperpolates one vector to another. +============= +*/ +void idVec4::Lerp( const idVec4 &v1, const idVec4 &v2, const float l ) { + if ( l <= 0.0f ) { + (*this) = v1; + } else if ( l >= 1.0f ) { + (*this) = v2; + } else { + (*this) = v1 + l * ( v2 - v1 ); + } +} + + +//=============================================================== +// +// idVec5 +// +//=============================================================== + +/* +============= +idVec5::ToString +============= +*/ +const char *idVec5::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + +/* +============= +idVec5::Lerp +============= +*/ +void idVec5::Lerp( const idVec5 &v1, const idVec5 &v2, const float l ) { + if ( l <= 0.0f ) { + (*this) = v1; + } else if ( l >= 1.0f ) { + (*this) = v2; + } else { + x = v1.x + l * ( v2.x - v1.x ); + y = v1.y + l * ( v2.y - v1.y ); + z = v1.z + l * ( v2.z - v1.z ); + s = v1.s + l * ( v2.s - v1.s ); + t = v1.t + l * ( v2.t - v1.t ); + } +} + + +//=============================================================== +// +// idVec6 +// +//=============================================================== + +/* +============= +idVec6::ToString +============= +*/ +const char *idVec6::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} + + +//=============================================================== +// +// idVecX +// +//=============================================================== + +float idVecX::temp[VECX_MAX_TEMP+4]; +float * idVecX::tempPtr = (float *) ( ( (int) idVecX::temp + 15 ) & ~15 ); +int idVecX::tempIndex = 0; + +/* +============= +idVecX::ToString +============= +*/ +const char *idVecX::ToString( int precision ) const { + return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); +} diff --git a/idlib/math/Vector.h b/idlib/math/Vector.h new file mode 100644 index 000000000..b26705cc7 --- /dev/null +++ b/idlib/math/Vector.h @@ -0,0 +1,2024 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATH_VECTOR_H__ +#define __MATH_VECTOR_H__ + +/* +=============================================================================== + + Vector classes + +=============================================================================== +*/ + +#define VECTOR_EPSILON 0.001f + +class idAngles; +class idPolar3; +class idMat3; + +//=============================================================== +// +// idVec2 - 2D vector +// +//=============================================================== + +class idVec2 { +public: + float x; + float y; + + idVec2( void ); + explicit idVec2( const float x, const float y ); + + void Set( const float x, const float y ); + void Zero( void ); + + float operator[]( int index ) const; + float & operator[]( int index ); + idVec2 operator-() const; + float operator*( const idVec2 &a ) const; + idVec2 operator*( const float a ) const; + idVec2 operator/( const float a ) const; + idVec2 operator+( const idVec2 &a ) const; + idVec2 operator-( const idVec2 &a ) const; + idVec2 & operator+=( const idVec2 &a ); + idVec2 & operator-=( const idVec2 &a ); + idVec2 & operator/=( const idVec2 &a ); + idVec2 & operator/=( const float a ); + idVec2 & operator*=( const float a ); + + friend idVec2 operator*( const float a, const idVec2 b ); + + bool Compare( const idVec2 &a ) const; // exact compare, no epsilon + bool Compare( const idVec2 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idVec2 &a ) const; // exact compare, no epsilon + bool operator!=( const idVec2 &a ) const; // exact compare, no epsilon + + float Length( void ) const; + float LengthFast( void ) const; + float LengthSqr( void ) const; + float Normalize( void ); // returns length + float NormalizeFast( void ); // returns length + idVec2 & Truncate( float length ); // cap length + void Clamp( const idVec2 &min, const idVec2 &max ); + void Snap( void ); // snap to closest integer value + void SnapInt( void ); // snap towards integer (floor) + + int GetDimension( void ) const; + + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + void Lerp( const idVec2 &v1, const idVec2 &v2, const float l ); +}; + +extern idVec2 vec2_origin; +#define vec2_zero vec2_origin + +ID_INLINE idVec2::idVec2( void ) { +} + +ID_INLINE idVec2::idVec2( const float x, const float y ) { + this->x = x; + this->y = y; +} + +ID_INLINE void idVec2::Set( const float x, const float y ) { + this->x = x; + this->y = y; +} + +ID_INLINE void idVec2::Zero( void ) { + x = y = 0.0f; +} + +ID_INLINE bool idVec2::Compare( const idVec2 &a ) const { + return ( ( x == a.x ) && ( y == a.y ) ); +} + +ID_INLINE bool idVec2::Compare( const idVec2 &a, const float epsilon ) const { + if ( idMath::Fabs( x - a.x ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( y - a.y ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idVec2::operator==( const idVec2 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idVec2::operator!=( const idVec2 &a ) const { + return !Compare( a ); +} + +ID_INLINE float idVec2::operator[]( int index ) const { + return ( &x )[ index ]; +} + +ID_INLINE float& idVec2::operator[]( int index ) { + return ( &x )[ index ]; +} + +ID_INLINE float idVec2::Length( void ) const { + return ( float )idMath::Sqrt( x * x + y * y ); +} + +ID_INLINE float idVec2::LengthFast( void ) const { + float sqrLength; + + sqrLength = x * x + y * y; + return sqrLength * idMath::RSqrt( sqrLength ); +} + +ID_INLINE float idVec2::LengthSqr( void ) const { + return ( x * x + y * y ); +} + +ID_INLINE float idVec2::Normalize( void ) { + float sqrLength, invLength; + + sqrLength = x * x + y * y; + invLength = idMath::InvSqrt( sqrLength ); + x *= invLength; + y *= invLength; + return invLength * sqrLength; +} + +ID_INLINE float idVec2::NormalizeFast( void ) { + float lengthSqr, invLength; + + lengthSqr = x * x + y * y; + invLength = idMath::RSqrt( lengthSqr ); + x *= invLength; + y *= invLength; + return invLength * lengthSqr; +} + +ID_INLINE idVec2 &idVec2::Truncate( float length ) { + float length2; + float ilength; + + if ( !length ) { + Zero(); + } + else { + length2 = LengthSqr(); + if ( length2 > length * length ) { + ilength = length * idMath::InvSqrt( length2 ); + x *= ilength; + y *= ilength; + } + } + + return *this; +} + +ID_INLINE void idVec2::Clamp( const idVec2 &min, const idVec2 &max ) { + if ( x < min.x ) { + x = min.x; + } else if ( x > max.x ) { + x = max.x; + } + if ( y < min.y ) { + y = min.y; + } else if ( y > max.y ) { + y = max.y; + } +} + +ID_INLINE void idVec2::Snap( void ) { + x = floor( x + 0.5f ); + y = floor( y + 0.5f ); +} + +ID_INLINE void idVec2::SnapInt( void ) { + x = float( int( x ) ); + y = float( int( y ) ); +} + +ID_INLINE idVec2 idVec2::operator-() const { + return idVec2( -x, -y ); +} + +ID_INLINE idVec2 idVec2::operator-( const idVec2 &a ) const { + return idVec2( x - a.x, y - a.y ); +} + +ID_INLINE float idVec2::operator*( const idVec2 &a ) const { + return x * a.x + y * a.y; +} + +ID_INLINE idVec2 idVec2::operator*( const float a ) const { + return idVec2( x * a, y * a ); +} + +ID_INLINE idVec2 idVec2::operator/( const float a ) const { + float inva = 1.0f / a; + return idVec2( x * inva, y * inva ); +} + +ID_INLINE idVec2 operator*( const float a, const idVec2 b ) { + return idVec2( b.x * a, b.y * a ); +} + +ID_INLINE idVec2 idVec2::operator+( const idVec2 &a ) const { + return idVec2( x + a.x, y + a.y ); +} + +ID_INLINE idVec2 &idVec2::operator+=( const idVec2 &a ) { + x += a.x; + y += a.y; + + return *this; +} + +ID_INLINE idVec2 &idVec2::operator/=( const idVec2 &a ) { + x /= a.x; + y /= a.y; + + return *this; +} + +ID_INLINE idVec2 &idVec2::operator/=( const float a ) { + float inva = 1.0f / a; + x *= inva; + y *= inva; + + return *this; +} + +ID_INLINE idVec2 &idVec2::operator-=( const idVec2 &a ) { + x -= a.x; + y -= a.y; + + return *this; +} + +ID_INLINE idVec2 &idVec2::operator*=( const float a ) { + x *= a; + y *= a; + + return *this; +} + +ID_INLINE int idVec2::GetDimension( void ) const { + return 2; +} + +ID_INLINE const float *idVec2::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idVec2::ToFloatPtr( void ) { + return &x; +} + + +//=============================================================== +// +// idVec3 - 3D vector +// +//=============================================================== + +class idVec3 { +public: + float x; + float y; + float z; + + idVec3( void ); + explicit idVec3( const float x, const float y, const float z ); + + void Set( const float x, const float y, const float z ); + void Zero( void ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idVec3 operator-() const; + idVec3 & operator=( const idVec3 &a ); // required because of a msvc 6 & 7 bug + float operator*( const idVec3 &a ) const; + idVec3 operator*( const float a ) const; + idVec3 operator/( const float a ) const; + idVec3 operator+( const idVec3 &a ) const; + idVec3 operator-( const idVec3 &a ) const; + idVec3 & operator+=( const idVec3 &a ); + idVec3 & operator-=( const idVec3 &a ); + idVec3 & operator/=( const idVec3 &a ); + idVec3 & operator/=( const float a ); + idVec3 & operator*=( const float a ); + idVec3 & MulCW( const idVec3 &a ); // multiply on vector component-wise + idVec3 & DivCW( const idVec3 &a ); // divide on vector component-wise + + friend idVec3 operator*( const float a, const idVec3 b ); + + bool Compare( const idVec3 &a ) const; // exact compare, no epsilon + bool Compare( const idVec3 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idVec3 &a ) const; // exact compare, no epsilon + bool operator!=( const idVec3 &a ) const; // exact compare, no epsilon + + bool FixDegenerateNormal( void ); // fix degenerate axial cases + bool FixDenormals( void ); // change tiny numbers to zero + + idVec3 Cross( const idVec3 &a ) const; + idVec3 & Cross( const idVec3 &a, const idVec3 &b ); + float Length( void ) const; + float LengthSqr( void ) const; + float LengthFast( void ) const; + float Normalize( void ); // returns length + float NormalizeFast( void ); // returns length + idVec3 & Truncate( float length ); // cap length + void Clamp( const idVec3 &min, const idVec3 &max ); + void Snap( void ); // snap to closest integer value + void SnapInt( void ); // snap towards integer (floor) + + int GetDimension( void ) const; + + float ToYaw( void ) const; + float ToPitch( void ) const; + idAngles ToAngles( void ) const; + idPolar3 ToPolar( void ) const; + idMat3 ToMat3( void ) const; // vector should be normalized + const idVec2 & ToVec2( void ) const; + idVec2 & ToVec2( void ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + void NormalVectors( idVec3 &left, idVec3 &down ) const; // vector should be normalized + void OrthogonalBasis( idVec3 &left, idVec3 &up ) const; + + void ProjectOntoPlane( const idVec3 &normal, const float overBounce = 1.0f ); + bool ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce = 1.0f ); + void ProjectSelfOntoSphere( const float radius ); + + void Lerp( const idVec3 &v1, const idVec3 &v2, const float l ); + void SLerp( const idVec3 &v1, const idVec3 &v2, const float l ); +}; + +extern idVec3 vec3_origin; +#define vec3_zero vec3_origin + +// Default constructor +ID_INLINE idVec3::idVec3( void ): + x(0.0f), // OrbWeaver: let's not leave stuff uninitialised + y(0.0f), + z(0.0f) +{ +} + +ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) { + this->x = x; + this->y = y; + this->z = z; +} + +ID_INLINE float idVec3::operator[]( const int index ) const { + return ( &x )[ index ]; +} + +ID_INLINE float &idVec3::operator[]( const int index ) { + return ( &x )[ index ]; +} + +ID_INLINE void idVec3::Set( const float x, const float y, const float z ) { + this->x = x; + this->y = y; + this->z = z; +} + +ID_INLINE void idVec3::Zero( void ) { + x = y = z = 0.0f; +} + +ID_INLINE idVec3 idVec3::operator-() const { + return idVec3( -x, -y, -z ); +} + +ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) { + x = a.x; + y = a.y; + z = a.z; + return *this; +} + +ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const { + return idVec3( x - a.x, y - a.y, z - a.z ); +} + +ID_INLINE float idVec3::operator*( const idVec3 &a ) const { + return x * a.x + y * a.y + z * a.z; +} + +ID_INLINE idVec3 idVec3::operator*( const float a ) const { + return idVec3( x * a, y * a, z * a ); +} + +ID_INLINE idVec3 idVec3::operator/( const float a ) const { + float inva = 1.0f / a; + return idVec3( x * inva, y * inva, z * inva ); +} + +ID_INLINE idVec3 operator*( const float a, const idVec3 b ) { + return idVec3( b.x * a, b.y * a, b.z * a ); +} + +ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const { + return idVec3( x + a.x, y + a.y, z + a.z ); +} + +ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) { + x += a.x; + y += a.y; + z += a.z; + + return *this; +} + +ID_INLINE idVec3 &idVec3::operator/=( const idVec3 &a ) { + x /= a.x; + y /= a.y; + z /= a.z; + + return *this; +} + +ID_INLINE idVec3 &idVec3::operator/=( const float a ) { + float inva = 1.0f / a; + x *= inva; + y *= inva; + z *= inva; + + return *this; +} + +ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) { + x -= a.x; + y -= a.y; + z -= a.z; + + return *this; +} + +ID_INLINE idVec3 &idVec3::operator*=( const float a ) { + x *= a; + y *= a; + z *= a; + + return *this; +} + +ID_INLINE idVec3 &idVec3::MulCW( const idVec3 &a ) { + x *= a.x; + y *= a.y; + z *= a.z; + + return *this; +} + +ID_INLINE idVec3 &idVec3::DivCW( const idVec3 &a ) { + x /= a.x; + y /= a.y; + z /= a.z; + + return *this; +} + +ID_INLINE bool idVec3::Compare( const idVec3 &a ) const { + return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) ); +} + +ID_INLINE bool idVec3::Compare( const idVec3 &a, const float epsilon ) const { + if ( idMath::Fabs( x - a.x ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( y - a.y ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( z - a.z ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idVec3::operator==( const idVec3 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idVec3::operator!=( const idVec3 &a ) const { + return !Compare( a ); +} + +ID_INLINE float idVec3::NormalizeFast( void ) { + float sqrLength, invLength; + + sqrLength = x * x + y * y + z * z; + invLength = idMath::RSqrt( sqrLength ); + x *= invLength; + y *= invLength; + z *= invLength; + return invLength * sqrLength; +} + +ID_INLINE bool idVec3::FixDegenerateNormal( void ) { + if ( x == 0.0f ) { + if ( y == 0.0f ) { + if ( z > 0.0f ) { + if ( z != 1.0f ) { + z = 1.0f; + return true; + } + } else { + if ( z != -1.0f ) { + z = -1.0f; + return true; + } + } + return false; + } else if ( z == 0.0f ) { + if ( y > 0.0f ) { + if ( y != 1.0f ) { + y = 1.0f; + return true; + } + } else { + if ( y != -1.0f ) { + y = -1.0f; + return true; + } + } + return false; + } + } else if ( y == 0.0f ) { + if ( z == 0.0f ) { + if ( x > 0.0f ) { + if ( x != 1.0f ) { + x = 1.0f; + return true; + } + } else { + if ( x != -1.0f ) { + x = -1.0f; + return true; + } + } + return false; + } + } + if ( idMath::Fabs( x ) == 1.0f ) { + if ( y != 0.0f || z != 0.0f ) { + y = z = 0.0f; + return true; + } + return false; + } else if ( idMath::Fabs( y ) == 1.0f ) { + if ( x != 0.0f || z != 0.0f ) { + x = z = 0.0f; + return true; + } + return false; + } else if ( idMath::Fabs( z ) == 1.0f ) { + if ( x != 0.0f || y != 0.0f ) { + x = y = 0.0f; + return true; + } + return false; + } + return false; +} + +ID_INLINE bool idVec3::FixDenormals( void ) { + bool denormal = false; + if ( fabs( x ) < 1e-30f ) { + x = 0.0f; + denormal = true; + } + if ( fabs( y ) < 1e-30f ) { + y = 0.0f; + denormal = true; + } + if ( fabs( z ) < 1e-30f ) { + z = 0.0f; + denormal = true; + } + return denormal; +} + +ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const { + return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x ); +} + +ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) { + x = a.y * b.z - a.z * b.y; + y = a.z * b.x - a.x * b.z; + z = a.x * b.y - a.y * b.x; + + return *this; +} + +ID_INLINE float idVec3::Length( void ) const { + return ( float )idMath::Sqrt( x * x + y * y + z * z ); +} + +ID_INLINE float idVec3::LengthSqr( void ) const { + return ( x * x + y * y + z * z ); +} + +ID_INLINE float idVec3::LengthFast( void ) const { + float sqrLength; + + sqrLength = x * x + y * y + z * z; + return sqrLength * idMath::RSqrt( sqrLength ); +} + +ID_INLINE float idVec3::Normalize( void ) { + float sqrLength, invLength; + + sqrLength = x * x + y * y + z * z; + invLength = idMath::InvSqrt( sqrLength ); + x *= invLength; + y *= invLength; + z *= invLength; + return invLength * sqrLength; +} + +ID_INLINE idVec3 &idVec3::Truncate( float length ) { + float length2; + float ilength; + + if ( !length ) { + Zero(); + } + else { + length2 = LengthSqr(); + if ( length2 > length * length ) { + ilength = length * idMath::InvSqrt( length2 ); + x *= ilength; + y *= ilength; + z *= ilength; + } + } + + return *this; +} + +ID_INLINE void idVec3::Clamp( const idVec3 &min, const idVec3 &max ) { + if ( x < min.x ) { + x = min.x; + } else if ( x > max.x ) { + x = max.x; + } + if ( y < min.y ) { + y = min.y; + } else if ( y > max.y ) { + y = max.y; + } + if ( z < min.z ) { + z = min.z; + } else if ( z > max.z ) { + z = max.z; + } +} + +ID_INLINE void idVec3::Snap( void ) { + x = floor( x + 0.5f ); + y = floor( y + 0.5f ); + z = floor( z + 0.5f ); +} + +ID_INLINE void idVec3::SnapInt( void ) { + x = float( int( x ) ); + y = float( int( y ) ); + z = float( int( z ) ); +} + +ID_INLINE int idVec3::GetDimension( void ) const { + return 3; +} + +ID_INLINE const idVec2 &idVec3::ToVec2( void ) const { + return *reinterpret_cast(this); +} + +ID_INLINE idVec2 &idVec3::ToVec2( void ) { + return *reinterpret_cast(this); +} + +ID_INLINE const float *idVec3::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idVec3::ToFloatPtr( void ) { + return &x; +} + +ID_INLINE void idVec3::NormalVectors( idVec3 &left, idVec3 &down ) const { + float d; + + d = x * x + y * y; + if ( !d ) { + left[0] = 1; + left[1] = 0; + left[2] = 0; + } else { + d = idMath::InvSqrt( d ); + left[0] = -y * d; + left[1] = x * d; + left[2] = 0; + } + down = left.Cross( *this ); +} + +ID_INLINE void idVec3::OrthogonalBasis( idVec3 &left, idVec3 &up ) const { + float l, s; + + if ( idMath::Fabs( z ) > 0.7f ) { + l = y * y + z * z; + s = idMath::InvSqrt( l ); + up[0] = 0; + up[1] = z * s; + up[2] = -y * s; + left[0] = l * s; + left[1] = -x * up[2]; + left[2] = x * up[1]; + } + else { + l = x * x + y * y; + s = idMath::InvSqrt( l ); + left[0] = -y * s; + left[1] = x * s; + left[2] = 0; + up[0] = -z * left[1]; + up[1] = z * left[0]; + up[2] = l * s; + } +} + +ID_INLINE void idVec3::ProjectOntoPlane( const idVec3 &normal, const float overBounce ) { + float backoff; + + backoff = *this * normal; + + if ( overBounce != 1.0 ) { + if ( backoff < 0 ) { + backoff *= overBounce; + } else { + backoff /= overBounce; + } + } + + *this -= backoff * normal; +} + +ID_INLINE bool idVec3::ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce ) { + idVec3 cross; + float len; + + cross = this->Cross( normal ).Cross( (*this) ); + // normalize so a fixed epsilon can be used + cross.Normalize(); + len = normal * cross; + if ( idMath::Fabs( len ) < epsilon ) { + return false; + } + cross *= overBounce * ( normal * (*this) ) / len; + (*this) -= cross; + return true; +} + + +//=============================================================== +// +// idVec4 - 4D vector +// +//=============================================================== + +class idVec4 { +public: + float x; + float y; + float z; + float w; + + idVec4( void ); + explicit idVec4( const float x, const float y, const float z, const float w ); + + void Set( const float x, const float y, const float z, const float w ); + void Zero( void ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idVec4 operator-() const; + float operator*( const idVec4 &a ) const; + idVec4 operator*( const float a ) const; + idVec4 operator/( const float a ) const; + idVec4 operator+( const idVec4 &a ) const; + idVec4 operator-( const idVec4 &a ) const; + idVec4 & operator+=( const idVec4 &a ); + idVec4 & operator-=( const idVec4 &a ); + idVec4 & operator/=( const idVec4 &a ); + idVec4 & operator/=( const float a ); + idVec4 & operator*=( const float a ); + + friend idVec4 operator*( const float a, const idVec4 b ); + + bool Compare( const idVec4 &a ) const; // exact compare, no epsilon + bool Compare( const idVec4 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idVec4 &a ) const; // exact compare, no epsilon + bool operator!=( const idVec4 &a ) const; // exact compare, no epsilon + + float Length( void ) const; + float LengthSqr( void ) const; + float Normalize( void ); // returns length + float NormalizeFast( void ); // returns length + + int GetDimension( void ) const; + + const idVec2 & ToVec2( void ) const; + idVec2 & ToVec2( void ); + const idVec3 & ToVec3( void ) const; + idVec3 & ToVec3( void ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + void Lerp( const idVec4 &v1, const idVec4 &v2, const float l ); +}; + +extern idVec4 vec4_origin; +#define vec4_zero vec4_origin + +ID_INLINE idVec4::idVec4( void ) { +} + +ID_INLINE idVec4::idVec4( const float x, const float y, const float z, const float w ) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +ID_INLINE void idVec4::Set( const float x, const float y, const float z, const float w ) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +ID_INLINE void idVec4::Zero( void ) { + x = y = z = w = 0.0f; +} + +ID_INLINE float idVec4::operator[]( int index ) const { + return ( &x )[ index ]; +} + +ID_INLINE float& idVec4::operator[]( int index ) { + return ( &x )[ index ]; +} + +ID_INLINE idVec4 idVec4::operator-() const { + return idVec4( -x, -y, -z, -w ); +} + +ID_INLINE idVec4 idVec4::operator-( const idVec4 &a ) const { + return idVec4( x - a.x, y - a.y, z - a.z, w - a.w ); +} + +ID_INLINE float idVec4::operator*( const idVec4 &a ) const { + return x * a.x + y * a.y + z * a.z + w * a.w; +} + +ID_INLINE idVec4 idVec4::operator*( const float a ) const { + return idVec4( x * a, y * a, z * a, w * a ); +} + +ID_INLINE idVec4 idVec4::operator/( const float a ) const { + float inva = 1.0f / a; + return idVec4( x * inva, y * inva, z * inva, w * inva ); +} + +ID_INLINE idVec4 operator*( const float a, const idVec4 b ) { + return idVec4( b.x * a, b.y * a, b.z * a, b.w * a ); +} + +ID_INLINE idVec4 idVec4::operator+( const idVec4 &a ) const { + return idVec4( x + a.x, y + a.y, z + a.z, w + a.w ); +} + +ID_INLINE idVec4 &idVec4::operator+=( const idVec4 &a ) { + x += a.x; + y += a.y; + z += a.z; + w += a.w; + + return *this; +} + +ID_INLINE idVec4 &idVec4::operator/=( const idVec4 &a ) { + x /= a.x; + y /= a.y; + z /= a.z; + w /= a.w; + + return *this; +} + +ID_INLINE idVec4 &idVec4::operator/=( const float a ) { + float inva = 1.0f / a; + x *= inva; + y *= inva; + z *= inva; + w *= inva; + + return *this; +} + +ID_INLINE idVec4 &idVec4::operator-=( const idVec4 &a ) { + x -= a.x; + y -= a.y; + z -= a.z; + w -= a.w; + + return *this; +} + +ID_INLINE idVec4 &idVec4::operator*=( const float a ) { + x *= a; + y *= a; + z *= a; + w *= a; + + return *this; +} + +ID_INLINE bool idVec4::Compare( const idVec4 &a ) const { + return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && w == a.w ); +} + +ID_INLINE bool idVec4::Compare( const idVec4 &a, const float epsilon ) const { + if ( idMath::Fabs( x - a.x ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( y - a.y ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( z - a.z ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( w - a.w ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idVec4::operator==( const idVec4 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idVec4::operator!=( const idVec4 &a ) const { + return !Compare( a ); +} + +ID_INLINE float idVec4::Length( void ) const { + return ( float )idMath::Sqrt( x * x + y * y + z * z + w * w ); +} + +ID_INLINE float idVec4::LengthSqr( void ) const { + return ( x * x + y * y + z * z + w * w ); +} + +ID_INLINE float idVec4::Normalize( void ) { + float sqrLength, invLength; + + sqrLength = x * x + y * y + z * z + w * w; + invLength = idMath::InvSqrt( sqrLength ); + x *= invLength; + y *= invLength; + z *= invLength; + w *= invLength; + return invLength * sqrLength; +} + +ID_INLINE float idVec4::NormalizeFast( void ) { + float sqrLength, invLength; + + sqrLength = x * x + y * y + z * z + w * w; + invLength = idMath::RSqrt( sqrLength ); + x *= invLength; + y *= invLength; + z *= invLength; + w *= invLength; + return invLength * sqrLength; +} + +ID_INLINE int idVec4::GetDimension( void ) const { + return 4; +} + +ID_INLINE const idVec2 &idVec4::ToVec2( void ) const { + return *reinterpret_cast(this); +} + +ID_INLINE idVec2 &idVec4::ToVec2( void ) { + return *reinterpret_cast(this); +} + +ID_INLINE const idVec3 &idVec4::ToVec3( void ) const { + return *reinterpret_cast(this); +} + +ID_INLINE idVec3 &idVec4::ToVec3( void ) { + return *reinterpret_cast(this); +} + +ID_INLINE const float *idVec4::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idVec4::ToFloatPtr( void ) { + return &x; +} + + +//=============================================================== +// +// idVec5 - 5D vector +// +//=============================================================== + +class idVec5 { +public: + float x; + float y; + float z; + float s; + float t; + + idVec5( void ); + explicit idVec5( const idVec3 &xyz, const idVec2 &st ); + explicit idVec5( const float x, const float y, const float z, const float s, const float t ); + + float operator[]( int index ) const; + float & operator[]( int index ); + idVec5 & operator=( const idVec3 &a ); + + int GetDimension( void ) const; + + const idVec3 & ToVec3( void ) const; + idVec3 & ToVec3( void ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + + void Lerp( const idVec5 &v1, const idVec5 &v2, const float l ); +}; + +extern idVec5 vec5_origin; +#define vec5_zero vec5_origin + +ID_INLINE idVec5::idVec5( void ) { +} + +ID_INLINE idVec5::idVec5( const idVec3 &xyz, const idVec2 &st ) { + x = xyz.x; + y = xyz.y; + z = xyz.z; + s = st[0]; + t = st[1]; +} + +ID_INLINE idVec5::idVec5( const float x, const float y, const float z, const float s, const float t ) { + this->x = x; + this->y = y; + this->z = z; + this->s = s; + this->t = t; +} + +ID_INLINE float idVec5::operator[]( int index ) const { + return ( &x )[ index ]; +} + +ID_INLINE float& idVec5::operator[]( int index ) { + return ( &x )[ index ]; +} + +ID_INLINE idVec5 &idVec5::operator=( const idVec3 &a ) { + x = a.x; + y = a.y; + z = a.z; + s = t = 0; + return *this; +} + +ID_INLINE int idVec5::GetDimension( void ) const { + return 5; +} + +ID_INLINE const idVec3 &idVec5::ToVec3( void ) const { + return *reinterpret_cast(this); +} + +ID_INLINE idVec3 &idVec5::ToVec3( void ) { + return *reinterpret_cast(this); +} + +ID_INLINE const float *idVec5::ToFloatPtr( void ) const { + return &x; +} + +ID_INLINE float *idVec5::ToFloatPtr( void ) { + return &x; +} + + +//=============================================================== +// +// idVec6 - 6D vector +// +//=============================================================== + +class idVec6 { +public: + idVec6( void ); + explicit idVec6( const float *a ); + explicit idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); + + void Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); + void Zero( void ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idVec6 operator-() const; + idVec6 operator*( const float a ) const; + idVec6 operator/( const float a ) const; + float operator*( const idVec6 &a ) const; + idVec6 operator-( const idVec6 &a ) const; + idVec6 operator+( const idVec6 &a ) const; + idVec6 & operator*=( const float a ); + idVec6 & operator/=( const float a ); + idVec6 & operator+=( const idVec6 &a ); + idVec6 & operator-=( const idVec6 &a ); + + friend idVec6 operator*( const float a, const idVec6 b ); + + bool Compare( const idVec6 &a ) const; // exact compare, no epsilon + bool Compare( const idVec6 &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idVec6 &a ) const; // exact compare, no epsilon + bool operator!=( const idVec6 &a ) const; // exact compare, no epsilon + + float Length( void ) const; + float LengthSqr( void ) const; + float Normalize( void ); // returns length + float NormalizeFast( void ); // returns length + + int GetDimension( void ) const; + + const idVec3 & SubVec3( int index ) const; + idVec3 & SubVec3( int index ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + float p[6]; +}; + +extern idVec6 vec6_origin; +#define vec6_zero vec6_origin +extern idVec6 vec6_infinity; + +ID_INLINE idVec6::idVec6( void ) { +} + +ID_INLINE idVec6::idVec6( const float *a ) { + memcpy( p, a, 6 * sizeof( float ) ); +} + +ID_INLINE idVec6::idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { + p[0] = a1; + p[1] = a2; + p[2] = a3; + p[3] = a4; + p[4] = a5; + p[5] = a6; +} + +ID_INLINE idVec6 idVec6::operator-() const { + return idVec6( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] ); +} + +ID_INLINE float idVec6::operator[]( const int index ) const { + return p[index]; +} + +ID_INLINE float &idVec6::operator[]( const int index ) { + return p[index]; +} + +ID_INLINE idVec6 idVec6::operator*( const float a ) const { + return idVec6( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a ); +} + +ID_INLINE float idVec6::operator*( const idVec6 &a ) const { + return p[0] * a[0] + p[1] * a[1] + p[2] * a[2] + p[3] * a[3] + p[4] * a[4] + p[5] * a[5]; +} + +ID_INLINE idVec6 idVec6::operator/( const float a ) const { + float inva; + + assert( a != 0.0f ); + inva = 1.0f / a; + return idVec6( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva ); +} + +ID_INLINE idVec6 idVec6::operator+( const idVec6 &a ) const { + return idVec6( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] ); +} + +ID_INLINE idVec6 idVec6::operator-( const idVec6 &a ) const { + return idVec6( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] ); +} + +ID_INLINE idVec6 &idVec6::operator*=( const float a ) { + p[0] *= a; + p[1] *= a; + p[2] *= a; + p[3] *= a; + p[4] *= a; + p[5] *= a; + return *this; +} + +ID_INLINE idVec6 &idVec6::operator/=( const float a ) { + float inva; + + assert( a != 0.0f ); + inva = 1.0f / a; + p[0] *= inva; + p[1] *= inva; + p[2] *= inva; + p[3] *= inva; + p[4] *= inva; + p[5] *= inva; + return *this; +} + +ID_INLINE idVec6 &idVec6::operator+=( const idVec6 &a ) { + p[0] += a[0]; + p[1] += a[1]; + p[2] += a[2]; + p[3] += a[3]; + p[4] += a[4]; + p[5] += a[5]; + return *this; +} + +ID_INLINE idVec6 &idVec6::operator-=( const idVec6 &a ) { + p[0] -= a[0]; + p[1] -= a[1]; + p[2] -= a[2]; + p[3] -= a[3]; + p[4] -= a[4]; + p[5] -= a[5]; + return *this; +} + +ID_INLINE idVec6 operator*( const float a, const idVec6 b ) { + return b * a; +} + +ID_INLINE bool idVec6::Compare( const idVec6 &a ) const { + return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) && + ( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) ); +} + +ID_INLINE bool idVec6::Compare( const idVec6 &a, const float epsilon ) const { + if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) { + return false; + } + + if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) { + return false; + } + + return true; +} + +ID_INLINE bool idVec6::operator==( const idVec6 &a ) const { + return Compare( a ); +} + +ID_INLINE bool idVec6::operator!=( const idVec6 &a ) const { + return !Compare( a ); +} + +ID_INLINE void idVec6::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { + p[0] = a1; + p[1] = a2; + p[2] = a3; + p[3] = a4; + p[4] = a5; + p[5] = a6; +} + +ID_INLINE void idVec6::Zero( void ) { + p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f; +} + +ID_INLINE float idVec6::Length( void ) const { + return ( float )idMath::Sqrt( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] ); +} + +ID_INLINE float idVec6::LengthSqr( void ) const { + return ( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] ); +} + +ID_INLINE float idVec6::Normalize( void ) { + float sqrLength, invLength; + + sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5]; + invLength = idMath::InvSqrt( sqrLength ); + p[0] *= invLength; + p[1] *= invLength; + p[2] *= invLength; + p[3] *= invLength; + p[4] *= invLength; + p[5] *= invLength; + return invLength * sqrLength; +} + +ID_INLINE float idVec6::NormalizeFast( void ) { + float sqrLength, invLength; + + sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5]; + invLength = idMath::RSqrt( sqrLength ); + p[0] *= invLength; + p[1] *= invLength; + p[2] *= invLength; + p[3] *= invLength; + p[4] *= invLength; + p[5] *= invLength; + return invLength * sqrLength; +} + +ID_INLINE int idVec6::GetDimension( void ) const { + return 6; +} + +ID_INLINE const idVec3 &idVec6::SubVec3( int index ) const { + return *reinterpret_cast(p + index * 3); +} + +ID_INLINE idVec3 &idVec6::SubVec3( int index ) { + return *reinterpret_cast(p + index * 3); +} + +ID_INLINE const float *idVec6::ToFloatPtr( void ) const { + return p; +} + +ID_INLINE float *idVec6::ToFloatPtr( void ) { + return p; +} + + +//=============================================================== +// +// idVecX - arbitrary sized vector +// +// The vector lives on 16 byte aligned and 16 byte padded memory. +// +// NOTE: due to the temporary memory pool idVecX cannot be used by multiple threads +// +//=============================================================== + +#define VECX_MAX_TEMP 1024 +#define VECX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) ) +#define VECX_CLEAREND() int s = size; while( s < ( ( s + 3) & ~3 ) ) { p[s++] = 0.0f; } +#define VECX_ALLOCA( n ) ( (float *) _alloca16( VECX_QUAD( n ) ) ) +#define VECX_SIMD + +class idVecX { + friend class idMatX; + +public: + idVecX( void ); + explicit idVecX( int length ); + explicit idVecX( int length, float *data ); + ~idVecX( void ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idVecX operator-() const; + idVecX & operator=( const idVecX &a ); + idVecX operator*( const float a ) const; + idVecX operator/( const float a ) const; + float operator*( const idVecX &a ) const; + idVecX operator-( const idVecX &a ) const; + idVecX operator+( const idVecX &a ) const; + idVecX & operator*=( const float a ); + idVecX & operator/=( const float a ); + idVecX & operator+=( const idVecX &a ); + idVecX & operator-=( const idVecX &a ); + + friend idVecX operator*( const float a, const idVecX b ); + + bool Compare( const idVecX &a ) const; // exact compare, no epsilon + bool Compare( const idVecX &a, const float epsilon ) const; // compare with epsilon + bool operator==( const idVecX &a ) const; // exact compare, no epsilon + bool operator!=( const idVecX &a ) const; // exact compare, no epsilon + + void SetSize( int size ); + void ChangeSize( int size, bool makeZero = false ); + int GetSize( void ) const { return size; } + void SetData( int length, float *data ); + void Zero( void ); + void Zero( int length ); + void Random( int seed, float l = 0.0f, float u = 1.0f ); + void Random( int length, int seed, float l = 0.0f, float u = 1.0f ); + void Negate( void ); + void Clamp( float min, float max ); + idVecX & SwapElements( int e1, int e2 ); + + float Length( void ) const; + float LengthSqr( void ) const; + idVecX Normalize( void ) const; + float NormalizeSelf( void ); + + int GetDimension( void ) const; + + const idVec3 & SubVec3( int index ) const; + idVec3 & SubVec3( int index ); + const idVec6 & SubVec6( int index ) const; + idVec6 & SubVec6( int index ); + const float * ToFloatPtr( void ) const; + float * ToFloatPtr( void ); + const char * ToString( int precision = 2 ) const; + +private: + int size; // size of the vector + int alloced; // if -1 p points to data set with SetData + float * p; // memory the vector is stored + + static float temp[VECX_MAX_TEMP+4]; // used to store intermediate results + static float * tempPtr; // pointer to 16 byte aligned temporary memory + static int tempIndex; // index into memory pool, wraps around + +private: + void SetTempSize( int size ); +}; + + +ID_INLINE idVecX::idVecX( void ) { + size = alloced = 0; + p = NULL; +} + +ID_INLINE idVecX::idVecX( int length ) { + size = alloced = 0; + p = NULL; + SetSize( length ); +} + +ID_INLINE idVecX::idVecX( int length, float *data ) { + size = alloced = 0; + p = NULL; + SetData( length, data ); +} + +ID_INLINE idVecX::~idVecX( void ) { + // if not temp memory + if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) { + Mem_Free16( p ); + } +} + +ID_INLINE float idVecX::operator[]( const int index ) const { + assert( index >= 0 && index < size ); + return p[index]; +} + +ID_INLINE float &idVecX::operator[]( const int index ) { + assert( index >= 0 && index < size ); + return p[index]; +} + +ID_INLINE idVecX idVecX::operator-() const { + int i; + idVecX m; + + m.SetTempSize( size ); + for ( i = 0; i < size; i++ ) { + m.p[i] = -p[i]; + } + return m; +} + +ID_INLINE idVecX &idVecX::operator=( const idVecX &a ) { + SetSize( a.size ); +#ifdef VECX_SIMD + SIMDProcessor->Copy16( p, a.p, a.size ); +#else + memcpy( p, a.p, a.size * sizeof( float ) ); +#endif + idVecX::tempIndex = 0; + return *this; +} + +ID_INLINE idVecX idVecX::operator+( const idVecX &a ) const { + idVecX m; + + assert( size == a.size ); + m.SetTempSize( size ); +#ifdef VECX_SIMD + SIMDProcessor->Add16( m.p, p, a.p, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + m.p[i] = p[i] + a.p[i]; + } +#endif + return m; +} + +ID_INLINE idVecX idVecX::operator-( const idVecX &a ) const { + idVecX m; + + assert( size == a.size ); + m.SetTempSize( size ); +#ifdef VECX_SIMD + SIMDProcessor->Sub16( m.p, p, a.p, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + m.p[i] = p[i] - a.p[i]; + } +#endif + return m; +} + +ID_INLINE idVecX &idVecX::operator+=( const idVecX &a ) { + assert( size == a.size ); +#ifdef VECX_SIMD + SIMDProcessor->AddAssign16( p, a.p, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + p[i] += a.p[i]; + } +#endif + idVecX::tempIndex = 0; + return *this; +} + +ID_INLINE idVecX &idVecX::operator-=( const idVecX &a ) { + assert( size == a.size ); +#ifdef VECX_SIMD + SIMDProcessor->SubAssign16( p, a.p, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + p[i] -= a.p[i]; + } +#endif + idVecX::tempIndex = 0; + return *this; +} + +ID_INLINE idVecX idVecX::operator*( const float a ) const { + idVecX m; + + m.SetTempSize( size ); +#ifdef VECX_SIMD + SIMDProcessor->Mul16( m.p, p, a, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + m.p[i] = p[i] * a; + } +#endif + return m; +} + +ID_INLINE idVecX &idVecX::operator*=( const float a ) { +#ifdef VECX_SIMD + SIMDProcessor->MulAssign16( p, a, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + p[i] *= a; + } +#endif + return *this; +} + +ID_INLINE idVecX idVecX::operator/( const float a ) const { + assert( a != 0.0f ); + return (*this) * ( 1.0f / a ); +} + +ID_INLINE idVecX &idVecX::operator/=( const float a ) { + assert( a != 0.0f ); + (*this) *= ( 1.0f / a ); + return *this; +} + +ID_INLINE idVecX operator*( const float a, const idVecX b ) { + return b * a; +} + +ID_INLINE float idVecX::operator*( const idVecX &a ) const { + int i; + float sum = 0.0f; + + assert( size == a.size ); + for ( i = 0; i < size; i++ ) { + sum += p[i] * a.p[i]; + } + return sum; +} + +ID_INLINE bool idVecX::Compare( const idVecX &a ) const { + int i; + + assert( size == a.size ); + for ( i = 0; i < size; i++ ) { + if ( p[i] != a.p[i] ) { + return false; + } + } + return true; +} + +ID_INLINE bool idVecX::Compare( const idVecX &a, const float epsilon ) const { + int i; + + assert( size == a.size ); + for ( i = 0; i < size; i++ ) { + if ( idMath::Fabs( p[i] - a.p[i] ) > epsilon ) { + return false; + } + } + return true; +} + +ID_INLINE bool idVecX::operator==( const idVecX &a ) const { + return Compare( a ); +} + +ID_INLINE bool idVecX::operator!=( const idVecX &a ) const { + return !Compare( a ); +} + +ID_INLINE void idVecX::SetSize( int newSize ) { + int alloc = ( newSize + 3 ) & ~3; + if ( alloc > alloced && alloced != -1 ) { + if ( p ) { + Mem_Free16( p ); + } + p = (float *) Mem_Alloc16( alloc * sizeof( float ) ); + alloced = alloc; + } + size = newSize; + VECX_CLEAREND(); +} + +ID_INLINE void idVecX::ChangeSize( int newSize, bool makeZero ) { + int alloc = ( newSize + 3 ) & ~3; + if ( alloc > alloced && alloced != -1 ) { + float *oldVec = p; + p = (float *) Mem_Alloc16( alloc * sizeof( float ) ); + alloced = alloc; + if ( oldVec ) { + for ( int i = 0; i < size; i++ ) { + p[i] = oldVec[i]; + } + Mem_Free16( oldVec ); + } + if ( makeZero ) { + // zero any new elements + for ( int i = size; i < newSize; i++ ) { + p[i] = 0.0f; + } + } + } + size = newSize; + VECX_CLEAREND(); +} + +ID_INLINE void idVecX::SetTempSize( int newSize ) { + + size = newSize; + alloced = ( newSize + 3 ) & ~3; + assert( alloced < VECX_MAX_TEMP ); + if ( idVecX::tempIndex + alloced > VECX_MAX_TEMP ) { + idVecX::tempIndex = 0; + } + p = idVecX::tempPtr + idVecX::tempIndex; + idVecX::tempIndex += alloced; + VECX_CLEAREND(); +} + +ID_INLINE void idVecX::SetData( int length, float *data ) { + if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) { + Mem_Free16( p ); + } + assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned + p = data; + size = length; + alloced = -1; + VECX_CLEAREND(); +} + +ID_INLINE void idVecX::Zero( void ) { +#ifdef VECX_SIMD + SIMDProcessor->Zero16( p, size ); +#else + memset( p, 0, size * sizeof( float ) ); +#endif +} + +ID_INLINE void idVecX::Zero( int length ) { + SetSize( length ); +#ifdef VECX_SIMD + SIMDProcessor->Zero16( p, length ); +#else + memset( p, 0, size * sizeof( float ) ); +#endif +} + +ID_INLINE void idVecX::Random( int seed, float l, float u ) { + int i; + float c; + idRandom rnd( seed ); + + c = u - l; + for ( i = 0; i < size; i++ ) { + p[i] = l + rnd.RandomFloat() * c; + } +} + +ID_INLINE void idVecX::Random( int length, int seed, float l, float u ) { + int i; + float c; + idRandom rnd( seed ); + + SetSize( length ); + c = u - l; + for ( i = 0; i < size; i++ ) { + p[i] = l + rnd.RandomFloat() * c; + } +} + +ID_INLINE void idVecX::Negate( void ) { +#ifdef VECX_SIMD + SIMDProcessor->Negate16( p, size ); +#else + int i; + for ( i = 0; i < size; i++ ) { + p[i] = -p[i]; + } +#endif +} + +ID_INLINE void idVecX::Clamp( float min, float max ) { + int i; + for ( i = 0; i < size; i++ ) { + if ( p[i] < min ) { + p[i] = min; + } else if ( p[i] > max ) { + p[i] = max; + } + } +} + +ID_INLINE idVecX &idVecX::SwapElements( int e1, int e2 ) { + float tmp; + tmp = p[e1]; + p[e1] = p[e2]; + p[e2] = tmp; + return *this; +} + +ID_INLINE float idVecX::Length( void ) const { + int i; + float sum = 0.0f; + + for ( i = 0; i < size; i++ ) { + sum += p[i] * p[i]; + } + return idMath::Sqrt( sum ); +} + +ID_INLINE float idVecX::LengthSqr( void ) const { + int i; + float sum = 0.0f; + + for ( i = 0; i < size; i++ ) { + sum += p[i] * p[i]; + } + return sum; +} + +ID_INLINE idVecX idVecX::Normalize( void ) const { + int i; + idVecX m; + float invSqrt, sum = 0.0f; + + m.SetTempSize( size ); + for ( i = 0; i < size; i++ ) { + sum += p[i] * p[i]; + } + invSqrt = idMath::InvSqrt( sum ); + for ( i = 0; i < size; i++ ) { + m.p[i] = p[i] * invSqrt; + } + return m; +} + +ID_INLINE float idVecX::NormalizeSelf( void ) { + float invSqrt, sum = 0.0f; + int i; + for ( i = 0; i < size; i++ ) { + sum += p[i] * p[i]; + } + invSqrt = idMath::InvSqrt( sum ); + for ( i = 0; i < size; i++ ) { + p[i] *= invSqrt; + } + return invSqrt * sum; +} + +ID_INLINE int idVecX::GetDimension( void ) const { + return size; +} + +ID_INLINE idVec3 &idVecX::SubVec3( int index ) { + assert( index >= 0 && index * 3 + 3 <= size ); + return *reinterpret_cast(p + index * 3); +} + +ID_INLINE const idVec3 &idVecX::SubVec3( int index ) const { + assert( index >= 0 && index * 3 + 3 <= size ); + return *reinterpret_cast(p + index * 3); +} + +ID_INLINE idVec6 &idVecX::SubVec6( int index ) { + assert( index >= 0 && index * 6 + 6 <= size ); + return *reinterpret_cast(p + index * 6); +} + +ID_INLINE const idVec6 &idVecX::SubVec6( int index ) const { + assert( index >= 0 && index * 6 + 6 <= size ); + return *reinterpret_cast(p + index * 6); +} + +ID_INLINE const float *idVecX::ToFloatPtr( void ) const { + return p; +} + +ID_INLINE float *idVecX::ToFloatPtr( void ) { + return p; +} + + +//=============================================================== +// +// idPolar3 +// +//=============================================================== + +class idPolar3 { +public: + float radius, theta, phi; + + idPolar3( void ); + explicit idPolar3( const float radius, const float theta, const float phi ); + explicit idPolar3( const idVec3 vec3 ); + + void Set( const float radius, const float theta, const float phi ); + + float operator[]( const int index ) const; + float & operator[]( const int index ); + idPolar3 operator-() const; + idPolar3 & operator=( const idPolar3 &a ); + + idVec3 ToVec3( void ) const; +}; + +ID_INLINE idPolar3::idPolar3( void ) { +} + +ID_INLINE idPolar3::idPolar3( const float radius, const float theta, const float phi ) { + assert( radius > 0 ); + this->radius = radius; + this->theta = theta; + this->phi = phi; +} + +ID_INLINE idPolar3::idPolar3( const idVec3 vec3 ) { + assert( vec3.x > 0 ); + this->radius = vec3.x; + this->theta = vec3.y; + this->phi = vec3.z; +} + +ID_INLINE void idPolar3::Set( const float radius, const float theta, const float phi ) { + assert( radius > 0 ); + this->radius = radius; + this->theta = theta; + this->phi = phi; +} + +ID_INLINE float idPolar3::operator[]( const int index ) const { + return ( &radius )[ index ]; +} + +ID_INLINE float &idPolar3::operator[]( const int index ) { + return ( &radius )[ index ]; +} + +ID_INLINE idPolar3 idPolar3::operator-() const { + return idPolar3( radius, -theta, -phi ); +} + +ID_INLINE idPolar3 &idPolar3::operator=( const idPolar3 &a ) { + radius = a.radius; + theta = a.theta; + phi = a.phi; + return *this; +} + +ID_INLINE idVec3 idPolar3::ToVec3( void ) const { + float sp, cp, st, ct; + idMath::SinCos( phi, sp, cp ); + idMath::SinCos( theta, st, ct ); + return idVec3( cp * radius * ct, cp * radius * st, radius * sp ); +} + + +/* +=============================================================================== + + Old 3D vector macros, should no longer be used. + +=============================================================================== +*/ + +#define DotProduct( a, b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) +#define VectorSubtract( a, b, c ) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2]) +#define VectorAdd( a, b, c ) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2]) +#define VectorScale( v, s, o ) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) +#define VectorMA( v, s, b, o ) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s)) +#define VectorCopy( a, b ) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) + + +#endif /* !__MATH_VECTOR_H__ */ diff --git a/idlib/math/angles.cpp b/idlib/math/angles.cpp deleted file mode 100644 index 09bb697e0..000000000 --- a/idlib/math/angles.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include - -idAngles ang_zero( 0.0f, 0.0f, 0.0f ); - - -/* -================= -idAngles::Normalize360 - -returns angles normalized to the range [0 <= angle < 360] -================= -*/ -idAngles& idAngles::Normalize360( void ) { - int i; - - for ( i = 0; i < 3; i++ ) { - if ( ( (*this)[i] >= 360.0f ) || ( (*this)[i] < 0.0f ) ) { - (*this)[i] -= floor( (*this)[i] / 360.0f ) * 360.0f; - - if ( (*this)[i] >= 360.0f ) { - (*this)[i] -= 360.0f; - } - if ( (*this)[i] < 0.0f ) { - (*this)[i] += 360.0f; - } - } - } - - return *this; -} - -/* -================= -idAngles::Normalize180 - -returns angles normalized to the range [-180 < angle <= 180] -================= -*/ -idAngles& idAngles::Normalize180( void ) { - Normalize360(); - - if ( pitch > 180.0f ) { - pitch -= 360.0f; - } - - if ( yaw > 180.0f ) { - yaw -= 360.0f; - } - - if ( roll > 180.0f ) { - roll -= 360.0f; - } - return *this; -} - -/* -================= -idAngles::ToVectors -================= -*/ -void idAngles::ToVectors( idVec3 *forward, idVec3 *right, idVec3 *up ) const { - float sr, sp, sy, cr, cp, cy; - - idMath::SinCos( DEG2RAD( yaw ), sy, cy ); - idMath::SinCos( DEG2RAD( pitch ), sp, cp ); - idMath::SinCos( DEG2RAD( roll ), sr, cr ); - - if ( forward ) { - forward->Set( cp * cy, cp * sy, -sp ); - } - - if ( right ) { - right->Set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp ); - } - - if ( up ) { - up->Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); - } -} - -/* -================= -idAngles::ToForward -================= -*/ -idVec3 idAngles::ToForward( void ) const { - float sp, sy, cp, cy; - - idMath::SinCos( DEG2RAD( yaw ), sy, cy ); - idMath::SinCos( DEG2RAD( pitch ), sp, cp ); - - return idVec3( cp * cy, cp * sy, -sp ); -} - -/* -================= -idAngles::ToQuat -================= -*/ -idQuat idAngles::ToQuat( void ) const { - float sx, cx, sy, cy, sz, cz; - float sxcy, cxcy, sxsy, cxsy; - - idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz ); - idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy ); - idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx ); - - sxcy = sx * cy; - cxcy = cx * cy; - sxsy = sx * sy; - cxsy = cx * sy; - - return idQuat( cxsy*sz - sxcy*cz, -cxsy*cz - sxcy*sz, sxsy*cz - cxcy*sz, cxcy*cz + sxsy*sz ); -} - -/* -================= -idAngles::ToRotation -================= -*/ -idRotation idAngles::ToRotation( void ) const { - idVec3 vec; - float angle, w; - float sx, cx, sy, cy, sz, cz; - float sxcy, cxcy, sxsy, cxsy; - - if ( pitch == 0.0f ) { - if ( yaw == 0.0f ) { - return idRotation( vec3_origin, idVec3( -1.0f, 0.0f, 0.0f ), roll ); - } - if ( roll == 0.0f ) { - return idRotation( vec3_origin, idVec3( 0.0f, 0.0f, -1.0f ), yaw ); - } - } else if ( yaw == 0.0f && roll == 0.0f ) { - return idRotation( vec3_origin, idVec3( 0.0f, -1.0f, 0.0f ), pitch ); - } - - idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz ); - idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy ); - idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx ); - - sxcy = sx * cy; - cxcy = cx * cy; - sxsy = sx * sy; - cxsy = cx * sy; - - vec.x = cxsy * sz - sxcy * cz; - vec.y = -cxsy * cz - sxcy * sz; - vec.z = sxsy * cz - cxcy * sz; - w = cxcy * cz + sxsy * sz; - angle = idMath::ACos( w ); - if ( angle == 0.0f ) { - vec.Set( 0.0f, 0.0f, 1.0f ); - } else { - //vec *= (1.0f / sin( angle )); - vec.Normalize(); - vec.FixDegenerateNormal(); - angle *= 2.0f * idMath::M_RAD2DEG; - } - return idRotation( vec3_origin, vec, angle ); -} - -/* -================= -idAngles::ToMat3 -================= -*/ -idMat3 idAngles::ToMat3( void ) const { - idMat3 mat; - float sr, sp, sy, cr, cp, cy; - - idMath::SinCos( DEG2RAD( yaw ), sy, cy ); - idMath::SinCos( DEG2RAD( pitch ), sp, cp ); - idMath::SinCos( DEG2RAD( roll ), sr, cr ); - - mat[ 0 ].Set( cp * cy, cp * sy, -sp ); - mat[ 1 ].Set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); - mat[ 2 ].Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); - - return mat; -} - -/* -================= -idAngles::ToMat4 -================= -*/ -idMat4 idAngles::ToMat4( void ) const { - return ToMat3().ToMat4(); -} - -/* -================= -idAngles::ToAngularVelocity -================= -*/ -idVec3 idAngles::ToAngularVelocity( void ) const { - idRotation rotation = idAngles::ToRotation(); - return rotation.GetVec() * DEG2RAD( rotation.GetAngle() ); -} - -/* -============= -idAngles::ToString -============= -*/ -const char *idAngles::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/angles.h b/idlib/math/angles.h deleted file mode 100644 index da42fb32c..000000000 --- a/idlib/math/angles.h +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_ANGLES_H__ -#define __MATH_ANGLES_H__ - -/* -=============================================================================== - - Euler angles - -TDM NOTE: -idAngles uses the "yaw, pitch, roll" convention, in which the yaw rotation occurs -first, then pitch occurs relative to the yawed axes, and finally roll -occurs relative to the yawed and pitched axes. Also known as the "zyx" convention. - -=============================================================================== -*/ - -// angle indexes -#define PITCH 0 // up / down -#define YAW 1 // left / right -#define ROLL 2 // fall over - -class idVec3; -class idQuat; -class idRotation; -class idMat3; -class idMat4; - -class idAngles { -public: - float pitch; - float yaw; - float roll; - - idAngles( void ); - idAngles( float pitch, float yaw, float roll ); - explicit idAngles( const idVec3 &v ); - - void Set( float pitch, float yaw, float roll ); - idAngles & Zero( void ); - - float operator[]( int index ) const; - float & operator[]( int index ); - idAngles operator-() const; // negate angles, in general not the inverse rotation - idAngles & operator=( const idAngles &a ); - idAngles operator+( const idAngles &a ) const; - idAngles & operator+=( const idAngles &a ); - idAngles operator-( const idAngles &a ) const; - idAngles & operator-=( const idAngles &a ); - idAngles operator*( const float a ) const; - idAngles & operator*=( const float a ); - idAngles operator/( const float a ) const; - idAngles & operator/=( const float a ); - - friend idAngles operator*( const float a, const idAngles &b ); - - bool Compare( const idAngles &a ) const; // exact compare, no epsilon - bool Compare( const idAngles &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idAngles &a ) const; // exact compare, no epsilon - bool operator!=( const idAngles &a ) const; // exact compare, no epsilon - - idAngles & Normalize360( void ); // normalizes 'this' - idAngles & Normalize180( void ); // normalizes 'this' - - void Clamp( const idAngles &min, const idAngles &max ); - - int GetDimension( void ) const; - - void ToVectors( idVec3 *forward, idVec3 *right = NULL, idVec3 *up = NULL ) const; - idVec3 ToForward( void ) const; - idQuat ToQuat( void ) const; - idRotation ToRotation( void ) const; - idMat3 ToMat3( void ) const; - idMat4 ToMat4( void ) const; - idVec3 ToAngularVelocity( void ) const; - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; -}; - -extern idAngles ang_zero; - -// Default constructor -ID_INLINE idAngles::idAngles( void ) -: pitch(0), yaw(0), roll(0) -{ -} - -ID_INLINE idAngles::idAngles( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -ID_INLINE idAngles::idAngles( const idVec3 &v ) { - this->pitch = v[0]; - this->yaw = v[1]; - this->roll = v[2]; -} - -ID_INLINE void idAngles::Set( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -ID_INLINE idAngles &idAngles::Zero( void ) { - pitch = yaw = roll = 0.0f; - return *this; -} - -ID_INLINE float idAngles::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -ID_INLINE float &idAngles::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -ID_INLINE idAngles idAngles::operator-() const { - return idAngles( -pitch, -yaw, -roll ); -} - -ID_INLINE idAngles &idAngles::operator=( const idAngles &a ) { - pitch = a.pitch; - yaw = a.yaw; - roll = a.roll; - return *this; -} - -ID_INLINE idAngles idAngles::operator+( const idAngles &a ) const { - return idAngles( pitch + a.pitch, yaw + a.yaw, roll + a.roll ); -} - -ID_INLINE idAngles& idAngles::operator+=( const idAngles &a ) { - pitch += a.pitch; - yaw += a.yaw; - roll += a.roll; - - return *this; -} - -ID_INLINE idAngles idAngles::operator-( const idAngles &a ) const { - return idAngles( pitch - a.pitch, yaw - a.yaw, roll - a.roll ); -} - -ID_INLINE idAngles& idAngles::operator-=( const idAngles &a ) { - pitch -= a.pitch; - yaw -= a.yaw; - roll -= a.roll; - - return *this; -} - -ID_INLINE idAngles idAngles::operator*( const float a ) const { - return idAngles( pitch * a, yaw * a, roll * a ); -} - -ID_INLINE idAngles& idAngles::operator*=( float a ) { - pitch *= a; - yaw *= a; - roll *= a; - return *this; -} - -ID_INLINE idAngles idAngles::operator/( const float a ) const { - float inva = 1.0f / a; - return idAngles( pitch * inva, yaw * inva, roll * inva ); -} - -ID_INLINE idAngles& idAngles::operator/=( float a ) { - float inva = 1.0f / a; - pitch *= inva; - yaw *= inva; - roll *= inva; - return *this; -} - -ID_INLINE idAngles operator*( const float a, const idAngles &b ) { - return idAngles( a * b.pitch, a * b.yaw, a * b.roll ); -} - -ID_INLINE bool idAngles::Compare( const idAngles &a ) const { - return ( ( a.pitch == pitch ) && ( a.yaw == yaw ) && ( a.roll == roll ) ); -} - -ID_INLINE bool idAngles::Compare( const idAngles &a, const float epsilon ) const { - if ( idMath::Fabs( pitch - a.pitch ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( yaw - a.yaw ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( roll - a.roll ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idAngles::operator==( const idAngles &a ) const { - return Compare( a ); -} - -ID_INLINE bool idAngles::operator!=( const idAngles &a ) const { - return !Compare( a ); -} - -ID_INLINE void idAngles::Clamp( const idAngles &min, const idAngles &max ) { - if ( pitch < min.pitch ) { - pitch = min.pitch; - } else if ( pitch > max.pitch ) { - pitch = max.pitch; - } - if ( yaw < min.yaw ) { - yaw = min.yaw; - } else if ( yaw > max.yaw ) { - yaw = max.yaw; - } - if ( roll < min.roll ) { - roll = min.roll; - } else if ( roll > max.roll ) { - roll = max.roll; - } -} - -ID_INLINE int idAngles::GetDimension( void ) const { - return 3; -} - -ID_INLINE const float *idAngles::ToFloatPtr( void ) const { - return &pitch; -} - -ID_INLINE float *idAngles::ToFloatPtr( void ) { - return &pitch; -} - -#endif /* !__MATH_ANGLES_H__ */ diff --git a/idlib/math/complex.cpp b/idlib/math/complex.cpp deleted file mode 100644 index 1334039c0..000000000 --- a/idlib/math/complex.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idComplex complex_origin( 0.0f, 0.0f ); - -/* -============= -idComplex::ToString -============= -*/ -const char *idComplex::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/complex.h b/idlib/math/complex.h deleted file mode 100644 index e4afdfee4..000000000 --- a/idlib/math/complex.h +++ /dev/null @@ -1,332 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_COMPLEX_H__ -#define __MATH_COMPLEX_H__ - -/* -=============================================================================== - - Complex number - -=============================================================================== -*/ - -class idComplex { -public: - float r; // real part - float i; // imaginary part - - idComplex( void ); - idComplex( const float r, const float i ); - - void Set( const float r, const float i ); - void Zero( void ); - - float operator[]( int index ) const; - float & operator[]( int index ); - - idComplex operator-() const; - idComplex & operator=( const idComplex &a ); - - idComplex operator*( const idComplex &a ) const; - idComplex operator/( const idComplex &a ) const; - idComplex operator+( const idComplex &a ) const; - idComplex operator-( const idComplex &a ) const; - - idComplex & operator*=( const idComplex &a ); - idComplex & operator/=( const idComplex &a ); - idComplex & operator+=( const idComplex &a ); - idComplex & operator-=( const idComplex &a ); - - idComplex operator*( const float a ) const; - idComplex operator/( const float a ) const; - idComplex operator+( const float a ) const; - idComplex operator-( const float a ) const; - - idComplex & operator*=( const float a ); - idComplex & operator/=( const float a ); - idComplex & operator+=( const float a ); - idComplex & operator-=( const float a ); - - friend idComplex operator*( const float a, const idComplex &b ); - friend idComplex operator/( const float a, const idComplex &b ); - friend idComplex operator+( const float a, const idComplex &b ); - friend idComplex operator-( const float a, const idComplex &b ); - - bool Compare( const idComplex &a ) const; // exact compare, no epsilon - bool Compare( const idComplex &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idComplex &a ) const; // exact compare, no epsilon - bool operator!=( const idComplex &a ) const; // exact compare, no epsilon - - idComplex Reciprocal( void ) const; - idComplex Sqrt( void ) const; - float Abs( void ) const; - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; -}; - -extern idComplex complex_origin; -#define complex_zero complex_origin - -ID_INLINE idComplex::idComplex( void ) { -} - -ID_INLINE idComplex::idComplex( const float r, const float i ) { - this->r = r; - this->i = i; -} - -ID_INLINE void idComplex::Set( const float r, const float i ) { - this->r = r; - this->i = i; -} - -ID_INLINE void idComplex::Zero( void ) { - r = i = 0.0f; -} - -ID_INLINE float idComplex::operator[]( int index ) const { - assert( index >= 0 && index < 2 ); - return ( &r )[ index ]; -} - -ID_INLINE float& idComplex::operator[]( int index ) { - assert( index >= 0 && index < 2 ); - return ( &r )[ index ]; -} - -ID_INLINE idComplex idComplex::operator-() const { - return idComplex( -r, -i ); -} - -ID_INLINE idComplex &idComplex::operator=( const idComplex &a ) { - r = a.r; - i = a.i; - return *this; -} - -ID_INLINE idComplex idComplex::operator*( const idComplex &a ) const { - return idComplex( r * a.r - i * a.i, i * a.r + r * a.i ); -} - -ID_INLINE idComplex idComplex::operator/( const idComplex &a ) const { - float s, t; - if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) { - s = a.i / a.r; - t = 1.0f / ( a.r + s * a.i ); - return idComplex( ( r + s * i ) * t, ( i - s * r ) * t ); - } else { - s = a.r / a.i; - t = 1.0f / ( s * a.r + a.i ); - return idComplex( ( r * s + i ) * t, ( i * s - r ) * t ); - } -} - -ID_INLINE idComplex idComplex::operator+( const idComplex &a ) const { - return idComplex( r + a.r, i + a.i ); -} - -ID_INLINE idComplex idComplex::operator-( const idComplex &a ) const { - return idComplex( r - a.r, i - a.i ); -} - -ID_INLINE idComplex &idComplex::operator*=( const idComplex &a ) { - *this = idComplex( r * a.r - i * a.i, i * a.r + r * a.i ); - return *this; -} - -ID_INLINE idComplex &idComplex::operator/=( const idComplex &a ) { - float s, t; - if ( idMath::Fabs( a.r ) >= idMath::Fabs( a.i ) ) { - s = a.i / a.r; - t = 1.0f / ( a.r + s * a.i ); - *this = idComplex( ( r + s * i ) * t, ( i - s * r ) * t ); - } else { - s = a.r / a.i; - t = 1.0f / ( s * a.r + a.i ); - *this = idComplex( ( r * s + i ) * t, ( i * s - r ) * t ); - } - return *this; -} - -ID_INLINE idComplex &idComplex::operator+=( const idComplex &a ) { - r += a.r; - i += a.i; - return *this; -} - -ID_INLINE idComplex &idComplex::operator-=( const idComplex &a ) { - r -= a.r; - i -= a.i; - return *this; -} - -ID_INLINE idComplex idComplex::operator*( const float a ) const { - return idComplex( r * a, i * a ); -} - -ID_INLINE idComplex idComplex::operator/( const float a ) const { - float s = 1.0f / a; - return idComplex( r * s, i * s ); -} - -ID_INLINE idComplex idComplex::operator+( const float a ) const { - return idComplex( r + a, i ); -} - -ID_INLINE idComplex idComplex::operator-( const float a ) const { - return idComplex( r - a, i ); -} - -ID_INLINE idComplex &idComplex::operator*=( const float a ) { - r *= a; - i *= a; - return *this; -} - -ID_INLINE idComplex &idComplex::operator/=( const float a ) { - float s = 1.0f / a; - r *= s; - i *= s; - return *this; -} - -ID_INLINE idComplex &idComplex::operator+=( const float a ) { - r += a; - return *this; -} - -ID_INLINE idComplex &idComplex::operator-=( const float a ) { - r -= a; - return *this; -} - -ID_INLINE idComplex operator*( const float a, const idComplex &b ) { - return idComplex( a * b.r, a * b.i ); -} - -ID_INLINE idComplex operator/( const float a, const idComplex &b ) { - float s, t; - if ( idMath::Fabs( b.r ) >= idMath::Fabs( b.i ) ) { - s = b.i / b.r; - t = a / ( b.r + s * b.i ); - return idComplex( t, - s * t ); - } else { - s = b.r / b.i; - t = a / ( s * b.r + b.i ); - return idComplex( s * t, - t ); - } -} - -ID_INLINE idComplex operator+( const float a, const idComplex &b ) { - return idComplex( a + b.r, b.i ); -} - -ID_INLINE idComplex operator-( const float a, const idComplex &b ) { - return idComplex( a - b.r, -b.i ); -} - -ID_INLINE idComplex idComplex::Reciprocal( void ) const { - float s, t; - if ( idMath::Fabs( r ) >= idMath::Fabs( i ) ) { - s = i / r; - t = 1.0f / ( r + s * i ); - return idComplex( t, - s * t ); - } else { - s = r / i; - t = 1.0f / ( s * r + i ); - return idComplex( s * t, - t ); - } -} - -ID_INLINE idComplex idComplex::Sqrt( void ) const { - float x, y, w; - - if ( r == 0.0f && i == 0.0f ) { - return idComplex( 0.0f, 0.0f ); - } - x = idMath::Fabs( r ); - y = idMath::Fabs( i ); - if ( x >= y ) { - w = y / x; - w = idMath::Sqrt( x ) * idMath::Sqrt( 0.5f * ( 1.0f + idMath::Sqrt( 1.0f + w * w ) ) ); - } else { - w = x / y; - w = idMath::Sqrt( y ) * idMath::Sqrt( 0.5f * ( w + idMath::Sqrt( 1.0f + w * w ) ) ); - } - if ( w == 0.0f ) { - return idComplex( 0.0f, 0.0f ); - } - if ( r >= 0.0f ) { - return idComplex( w, 0.5f * i / w ); - } else { - return idComplex( 0.5f * y / w, ( i >= 0.0f ) ? w : -w ); - } -} - -ID_INLINE float idComplex::Abs( void ) const { - float x, y, t; - x = idMath::Fabs( r ); - y = idMath::Fabs( i ); - if ( x == 0.0f ) { - return y; - } else if ( y == 0.0f ) { - return x; - } else if ( x > y ) { - t = y / x; - return x * idMath::Sqrt( 1.0f + t * t ); - } else { - t = x / y; - return y * idMath::Sqrt( 1.0f + t * t ); - } -} - -ID_INLINE bool idComplex::Compare( const idComplex &a ) const { - return ( ( r == a.r ) && ( i == a.i ) ); -} - -ID_INLINE bool idComplex::Compare( const idComplex &a, const float epsilon ) const { - if ( idMath::Fabs( r - a.r ) > epsilon ) { - return false; - } - if ( idMath::Fabs( i - a.i ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE bool idComplex::operator==( const idComplex &a ) const { - return Compare( a ); -} - -ID_INLINE bool idComplex::operator!=( const idComplex &a ) const { - return !Compare( a ); -} - -ID_INLINE int idComplex::GetDimension( void ) const { - return 2; -} - -ID_INLINE const float *idComplex::ToFloatPtr( void ) const { - return &r; -} - -ID_INLINE float *idComplex::ToFloatPtr( void ) { - return &r; -} - -#endif /* !__MATH_COMPLEX_H__ */ diff --git a/idlib/math/curve.h b/idlib/math/curve.h deleted file mode 100644 index 605ad56ae..000000000 --- a/idlib/math/curve.h +++ /dev/null @@ -1,2526 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_CURVE_H__ -#define __MATH_CURVE_H__ - -/* -=============================================================================== - - Curve base template. - -=============================================================================== -*/ - -template< class type > -class idCurve { -public: - idCurve( void ); - virtual ~idCurve( void ); - - virtual int AddValue( const float time, const type &value ); - virtual void RemoveIndex( const int index ) { values.RemoveIndex(index); times.RemoveIndex(index); changed = true; } - virtual void Clear( void ) { values.Clear(); times.Clear(); currentIndex = -1; changed = true; } - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - - virtual bool IsDone( const float time ) const; - - int GetNumValues( void ) const { return values.Num(); } - void SetValue( const int index, const type &value ) { values[index] = value; changed = true; } - type GetValue( const int index ) const { return values[index]; } - type * GetValueAddress( const int index ) { return &values[index]; } - float GetTime( const int index ) const { return times[index]; } - - float GetLengthForTime( const float time ) const; - float GetTimeForLength( const float length, const float epsilon = 0.1f ) const; - float GetLengthBetweenKnots( const int i0, const int i1 ) const; - - void MakeUniform( const float totalTime ); - void SetConstantSpeed( const float totalTime ); - void ShiftTime( const float deltaTime ); - void Translate( const type &translation ); - -protected: - - idList times; // knots - idList values; // knot values - - mutable int currentIndex; // cached index for fast lookup - mutable bool changed; // set whenever the curve changes - - int IndexForTime( const float time ) const; - float TimeForIndex( const int index ) const; - type ValueForIndex( const int index ) const; - - float GetSpeed( const float time ) const; - float RombergIntegral( const float t0, const float t1, const int order ) const; -}; - -/* -==================== -idCurve::idCurve -==================== -*/ -template< class type > -ID_INLINE idCurve::idCurve( void ) { - currentIndex = -1; - changed = false; -} - -/* -==================== -idCurve::~idCurve -==================== -*/ -template< class type > -ID_INLINE idCurve::~idCurve( void ) { -} - -/* -==================== -idCurve::AddValue - - add a timed/value pair to the spline - returns the index to the inserted pair -==================== -*/ -template< class type > -ID_INLINE int idCurve::AddValue( const float time, const type &value ) { - int i; - - i = IndexForTime( time ); - times.Insert( time, i ); - values.Insert( value, i ); - changed = true; - return i; -} - -/* -==================== -idCurve::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve::GetCurrentValue( const float time ) const { - int i; - - i = IndexForTime( time ); - if ( i >= values.Num() ) { - return values[values.Num() - 1]; - } else { - return values[i]; - } -} - -/* -==================== -idCurve::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve::GetCurrentFirstDerivative( const float time ) const { - return ( values[0] - values[0] ); -} - -/* -==================== -idCurve::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve::GetCurrentSecondDerivative( const float time ) const { - return ( values[0] - values[0] ); -} - -/* -==================== -idCurve::IsDone -==================== -*/ -template< class type > -ID_INLINE bool idCurve::IsDone( const float time ) const { - return ( time >= times[ times.Num() - 1 ] ); -} - -/* -==================== -idCurve::GetSpeed -==================== -*/ -template< class type > -ID_INLINE float idCurve::GetSpeed( const float time ) const { - int i; - float speed; - type value; - - value = GetCurrentFirstDerivative( time ); - for ( speed = 0.0f, i = 0; i < value.GetDimension(); i++ ) { - speed += value[i] * value[i]; - } - return idMath::Sqrt( speed ); -} - -/* -==================== -idCurve::RombergIntegral -==================== -*/ -template< class type > -inline float idCurve::RombergIntegral( const float t0, const float t1, const int order ) const { - int i, j, k, m, n; - float sum, delta; - float *temp[2]; - - temp[0] = (float *) _alloca16( order * sizeof( float ) ); - temp[1] = (float *) _alloca16( order * sizeof( float ) ); - - delta = t1 - t0; - temp[0][0] = 0.5f * delta * ( GetSpeed( t0 ) + GetSpeed( t1 ) ); - - for ( i = 2, m = 1; i <= order; i++, m *= 2, delta *= 0.5f ) { - - // approximate using the trapezoid rule - sum = 0.0f; - for ( j = 1; j <= m; j++ ) { - sum += GetSpeed( t0 + delta * ( j - 0.5f ) ); - } - - // Richardson extrapolation - temp[1][0] = 0.5f * ( temp[0][0] + delta * sum ); - for ( k = 1, n = 4; k < i; k++, n *= 4 ) { - temp[1][k] = ( n * temp[1][k-1] - temp[0][k-1] ) / ( n - 1 ); - } - - for ( j = 0; j < i; j++ ) { - temp[0][j] = temp[1][j]; - } - } - return temp[0][order-1]; -} - -/* -==================== -idCurve::GetLengthBetweenKnots -==================== -*/ -template< class type > -ID_INLINE float idCurve::GetLengthBetweenKnots( const int i0, const int i1 ) const { - float length = 0.0f; - for ( int i = i0; i < i1; i++ ) { - length += RombergIntegral( times[i], times[i+1], 5 ); - } - return length; -} - -/* -==================== -idCurve::GetLengthForTime -==================== -*/ -template< class type > -ID_INLINE float idCurve::GetLengthForTime( const float time ) const { - float length = 0.0f; - int index = IndexForTime( time ); - for ( int i = 0; i < index; i++ ) { - length += RombergIntegral( times[i], times[i+1], 5 ); - } - length += RombergIntegral( times[index], time, 5 ); - return length; -} - -/* -==================== -idCurve::GetTimeForLength -==================== -*/ -template< class type > -ID_INLINE float idCurve::GetTimeForLength( const float length, const float epsilon ) const { - int i, index; - float *accumLength, totalLength, len0, len1, t, diff; - - if ( length <= 0.0f ) { - return times[0]; - } - - accumLength = (float *) _alloca16( values.Num() * sizeof( float ) ); - totalLength = 0.0f; - for ( index = 0; index < values.Num() - 1; index++ ) { - totalLength += GetLengthBetweenKnots( index, index + 1 ); - accumLength[index] = totalLength; - if ( length < accumLength[index] ) { - break; - } - } - - if ( index >= values.Num() - 1 ) { - return times[times.Num() - 1]; - } - - if ( index == 0 ) { - len0 = length; - len1 = accumLength[0]; - } else { - len0 = length - accumLength[index-1]; - len1 = accumLength[index] - accumLength[index-1]; - } - - // invert the arc length integral using Newton's method - t = ( times[index+1] - times[index] ) * len0 / len1; - for ( i = 0; i < 32; i++ ) { - diff = RombergIntegral( times[index], times[index] + t, 5 ) - len0; - if ( idMath::Fabs( diff ) <= epsilon ) { - return times[index] + t; - } - t -= diff / GetSpeed( times[index] + t ); - } - return times[index] + t; -} - -/* -==================== -idCurve::MakeUniform -==================== -*/ -template< class type > -ID_INLINE void idCurve::MakeUniform( const float totalTime ) { - int i, n; - - n = times.Num() - 1; - for ( i = 0; i <= n; i++ ) { - times[i] = i * totalTime / n; - } - changed = true; -} - -/* -==================== -idCurve::SetConstantSpeed -==================== -*/ -template< class type > -ID_INLINE void idCurve::SetConstantSpeed( const float totalTime ) { - int i, j; - float *length, totalLength, scale, t; - - length = (float *) _alloca16( values.Num() * sizeof( float ) ); - totalLength = 0.0f; - for ( i = 0; i < values.Num() - 1; i++ ) { - length[i] = GetLengthBetweenKnots( i, i + 1 ); - totalLength += length[i]; - } - scale = totalTime / totalLength; - for ( t = 0.0f, i = 0; i < times.Num() - 1; i++ ) { - times[i] = t; - t += scale * length[i]; - } - times[times.Num() - 1] = totalTime; - changed = true; -} - -/* -==================== -idCurve::ShiftTime -==================== -*/ -template< class type > -ID_INLINE void idCurve::ShiftTime( const float deltaTime ) { - for ( int i = 0; i < times.Num(); i++ ) { - times[i] += deltaTime; - } - changed = true; -} - -/* -==================== -idCurve::Translate -==================== -*/ -template< class type > -ID_INLINE void idCurve::Translate( const type &translation ) { - for ( int i = 0; i < values.Num(); i++ ) { - values[i] += translation; - } - changed = true; -} - -/* -==================== -idCurve::IndexForTime - - find the index for the first time greater than or equal to the given time -==================== -*/ -template< class type > -ID_INLINE int idCurve::IndexForTime( const float time ) const { - int len, mid, offset, res; - - if ( currentIndex >= 0 && currentIndex <= times.Num() ) { - // use the cached index if it is still valid - if ( currentIndex == 0 ) { - if ( time <= times[currentIndex] ) { - return currentIndex; - } - } else if ( currentIndex == times.Num() ) { - if ( time > times[currentIndex-1] ) { - return currentIndex; - } - } else if ( time > times[currentIndex-1] && time <= times[currentIndex] ) { - return currentIndex; - } else if ( time > times[currentIndex] && ( currentIndex+1 == times.Num() || time <= times[currentIndex+1] ) ) { - // use the next index - currentIndex++; - return currentIndex; - } - } - - // use binary search to find the index for the given time - len = times.Num(); - mid = len; - offset = 0; - res = 0; - while( mid > 0 ) { - mid = len >> 1; - if ( time == times[offset+mid] ) { - return offset+mid; - } else if ( time > times[offset+mid] ) { - offset += mid; - len -= mid; - res = 1; - } else { - len -= mid; - res = 0; - } - } - currentIndex = offset+res; - return currentIndex; -} - -/* -==================== -idCurve::ValueForIndex - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve::ValueForIndex( const int index ) const { - int n = values.Num()-1; - - if ( index < 0 ) { - return values[0] + index * ( values[1] - values[0] ); - } else if ( index > n ) { - return values[n] + ( index - n ) * ( values[n] - values[n-1] ); - } - return values[index]; -} - -/* -==================== -idCurve::TimeForIndex - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE float idCurve::TimeForIndex( const int index ) const { - int n = times.Num()-1; - - if ( index < 0 ) { - return times[0] + index * ( times[1] - times[0] ); - } else if ( index > n ) { - return times[n] + ( index - n ) * ( times[n] - times[n-1] ); - } - return times[index]; -} - - -/* -=============================================================================== - - Bezier Curve template. - The degree of the polynomial equals the number of knots minus one. - -=============================================================================== -*/ - -template< class type > -class idCurve_Bezier : public idCurve { -public: - idCurve_Bezier( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const int order, const float t, float *bvals ) const; - void BasisFirstDerivative( const int order, const float t, float *bvals ) const; - void BasisSecondDerivative( const int order, const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_Bezier::idCurve_Bezier -==================== -*/ -template< class type > -ID_INLINE idCurve_Bezier::idCurve_Bezier( void ) { -} - -/* -==================== -idCurve_Bezier::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_Bezier::GetCurrentValue( const float time ) const { - int i; - float *bvals; - type v; - - bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); - - Basis( this->values.Num(), time, bvals ); - v = bvals[0] * this->values[0]; - for ( i = 1; i < this->values.Num(); i++ ) { - v += bvals[i] * this->values[i]; - } - return v; -} - -/* -==================== -idCurve_Bezier::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_Bezier::GetCurrentFirstDerivative( const float time ) const { - int i; - float *bvals, d; - type v; - - bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); - - BasisFirstDerivative( this->values.Num(), time, bvals ); - v = bvals[0] * this->values[0]; - for ( i = 1; i < this->values.Num(); i++ ) { - v += bvals[i] * this->values[i]; - } - d = ( this->times[this->times.Num()-1] - this->times[0] ); - return ( (float) (this->values.Num()-1) / d ) * v; -} - -/* -==================== -idCurve_Bezier::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_Bezier::GetCurrentSecondDerivative( const float time ) const { - int i; - float *bvals, d; - type v; - - bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) ); - - BasisSecondDerivative( this->values.Num(), time, bvals ); - v = bvals[0] * this->values[0]; - for ( i = 1; i < this->values.Num(); i++ ) { - v += bvals[i] * this->values[i]; - } - d = ( this->times[this->times.Num()-1] - this->times[0] ); - return ( (float) (this->values.Num()-2) * (this->values.Num()-1) / ( d * d ) ) * v; -} - -/* -==================== -idCurve_Bezier::Basis - - bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_Bezier::Basis( const int order, const float t, float *bvals ) const { - int i, j, d; - float *c, c1, c2, s, o, ps, po; - - bvals[0] = 1.0f; - d = order - 1; - if ( d <= 0 ) { - return; - } - - c = (float *) _alloca16( (d+1) * sizeof( float ) ); - s = (float) ( t - this->times[0] ) / ( this->times[this->times.Num()-1] - this->times[0] ); - o = 1.0f - s; - ps = s; - po = o; - - for ( i = 1; i < d; i++ ) { - c[i] = 1.0f; - } - for ( i = 1; i < d; i++ ) { - c[i-1] = 0.0f; - c1 = c[i]; - c[i] = 1.0f; - for ( j = i+1; j <= d; j++ ) { - c2 = c[j]; - c[j] = c1 + c[j-1]; - c1 = c2; - } - bvals[i] = c[d] * ps; - ps *= s; - } - for ( i = d-1; i >= 0; i-- ) { - bvals[i] *= po; - po *= o; - } - bvals[d] = ps; -} - -/* -==================== -idCurve_Bezier::BasisFirstDerivative - - first derivative of bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_Bezier::BasisFirstDerivative( const int order, const float t, float *bvals ) const { - int i; - - Basis( order-1, t, bvals+1 ); - bvals[0] = 0.0f; - for ( i = 0; i < order-1; i++ ) { - bvals[i] -= bvals[i+1]; - } -} - -/* -==================== -idCurve_Bezier::BasisSecondDerivative - - second derivative of bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_Bezier::BasisSecondDerivative( const int order, const float t, float *bvals ) const { - int i; - - BasisFirstDerivative( order-1, t, bvals+1 ); - bvals[0] = 0.0f; - for ( i = 0; i < order-1; i++ ) { - bvals[i] -= bvals[i+1]; - } -} - - -/* -=============================================================================== - - Quadratic Bezier Curve template. - Should always have exactly three knots. - -=============================================================================== -*/ - -template< class type > -class idCurve_QuadraticBezier : public idCurve { - -public: - idCurve_QuadraticBezier( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const float t, float *bvals ) const; - void BasisFirstDerivative( const float t, float *bvals ) const; - void BasisSecondDerivative( const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_QuadraticBezier::idCurve_QuadraticBezier -==================== -*/ -template< class type > -ID_INLINE idCurve_QuadraticBezier::idCurve_QuadraticBezier( void ) { -} - - -/* -==================== -idCurve_QuadraticBezier::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_QuadraticBezier::GetCurrentValue( const float time ) const { - float bvals[3]; - assert( this->values.Num() == 3 ); - Basis( time, bvals ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ); -} - -/* -==================== -idCurve_QuadraticBezier::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_QuadraticBezier::GetCurrentFirstDerivative( const float time ) const { - float bvals[3], d; - assert( this->values.Num() == 3 ); - BasisFirstDerivative( time, bvals ); - d = ( this->times[2] - this->times[0] ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / d; -} - -/* -==================== -idCurve_QuadraticBezier::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_QuadraticBezier::GetCurrentSecondDerivative( const float time ) const { - float bvals[3], d; - assert( this->values.Num() == 3 ); - BasisSecondDerivative( time, bvals ); - d = ( this->times[2] - this->times[0] ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / ( d * d ); -} - -/* -==================== -idCurve_QuadraticBezier::Basis - - quadratic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_QuadraticBezier::Basis( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); - float s2 = s1 * s1; - bvals[0] = s2 - 2.0f * s1 + 1.0f; - bvals[1] = -2.0f * s2 + 2.0f * s1; - bvals[2] = s2; -} - -/* -==================== -idCurve_QuadraticBezier::BasisFirstDerivative - - first derivative of quadratic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_QuadraticBezier::BasisFirstDerivative( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); - bvals[0] = 2.0f * s1 - 2.0f; - bvals[1] = -4.0f * s1 + 2.0f; - bvals[2] = 2.0f * s1; -} - -/* -==================== -idCurve_QuadraticBezier::BasisSecondDerivative - - second derivative of quadratic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_QuadraticBezier::BasisSecondDerivative( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] ); - bvals[0] = 2.0f; - bvals[1] = -4.0f; - bvals[2] = 2.0f; -} - - -/* -=============================================================================== - - Cubic Bezier Curve template. - Should always have exactly four knots. - -=============================================================================== -*/ - -template< class type > -class idCurve_CubicBezier : public idCurve { - -public: - idCurve_CubicBezier( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const float t, float *bvals ) const; - void BasisFirstDerivative( const float t, float *bvals ) const; - void BasisSecondDerivative( const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_CubicBezier::idCurve_CubicBezier -==================== -*/ -template< class type > -ID_INLINE idCurve_CubicBezier::idCurve_CubicBezier( void ) { -} - - -/* -==================== -idCurve_CubicBezier::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CubicBezier::GetCurrentValue( const float time ) const { - float bvals[4]; - assert( this->values.Num() == 4 ); - Basis( time, bvals ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ); -} - -/* -==================== -idCurve_CubicBezier::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CubicBezier::GetCurrentFirstDerivative( const float time ) const { - float bvals[4], d; - assert( this->values.Num() == 4 ); - BasisFirstDerivative( time, bvals ); - d = ( this->times[3] - this->times[0] ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / d; -} - -/* -==================== -idCurve_CubicBezier::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CubicBezier::GetCurrentSecondDerivative( const float time ) const { - float bvals[4], d; - assert( this->values.Num() == 4 ); - BasisSecondDerivative( time, bvals ); - d = ( this->times[3] - this->times[0] ); - return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / ( d * d ); -} - -/* -==================== -idCurve_CubicBezier::Basis - - cubic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CubicBezier::Basis( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); - float s2 = s1 * s1; - float s3 = s2 * s1; - bvals[0] = -s3 + 3.0f * s2 - 3.0f * s1 + 1.0f; - bvals[1] = 3.0f * s3 - 6.0f * s2 + 3.0f * s1; - bvals[2] = -3.0f * s3 + 3.0f * s2; - bvals[3] = s3; -} - -/* -==================== -idCurve_CubicBezier::BasisFirstDerivative - - first derivative of cubic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CubicBezier::BasisFirstDerivative( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); - float s2 = s1 * s1; - bvals[0] = -3.0f * s2 + 6.0f * s1 - 3.0f; - bvals[1] = 9.0f * s2 - 12.0f * s1 + 3.0f; - bvals[2] = -9.0f * s2 + 6.0f * s1; - bvals[3] = 3.0f * s2; -} - -/* -==================== -idCurve_CubicBezier::BasisSecondDerivative - - second derivative of cubic bezier basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CubicBezier::BasisSecondDerivative( const float t, float *bvals ) const { - float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] ); - bvals[0] = -6.0f * s1 + 6.0f; - bvals[1] = 18.0f * s1 - 12.0f; - bvals[2] = -18.0f * s1 + 6.0f; - bvals[3] = 6.0f * s1; -} - - -/* -=============================================================================== - - Spline base template. - -=============================================================================== -*/ - -template< class type > -class idCurve_Spline : public idCurve { - -public: - enum boundary_t { BT_FREE, BT_CLAMPED, BT_CLOSED }; - - idCurve_Spline( void ); - - virtual bool IsDone( const float time ) const; - - virtual void SetBoundaryType( const boundary_t bt ) { boundaryType = bt; this->changed = true; } - virtual boundary_t GetBoundaryType( void ) const { return boundaryType; } - - virtual void SetCloseTime( const float t ) { closeTime = t; this->changed = true; } - virtual float GetCloseTime( void ) { return boundaryType == BT_CLOSED ? closeTime : 0.0f; } - -protected: - boundary_t boundaryType; - float closeTime; - - type ValueForIndex( const int index ) const; - float TimeForIndex( const int index ) const; - float ClampedTime( const float t ) const; -}; - -/* -==================== -idCurve_Spline::idCurve_Spline -==================== -*/ -template< class type > -ID_INLINE idCurve_Spline::idCurve_Spline( void ) { - boundaryType = BT_FREE; - closeTime = 0.0f; -} - -/* -==================== -idCurve_Spline::ValueForIndex - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_Spline::ValueForIndex( const int index ) const { - int n = this->values.Num()-1; - - if ( index < 0 ) { - if ( boundaryType == BT_CLOSED ) { - return this->values[ this->values.Num() + index % this->values.Num() ]; - } - else { - return this->values[0] + index * ( this->values[1] - this->values[0] ); - } - } - else if ( index > n ) { - if ( boundaryType == BT_CLOSED ) { - return this->values[ index % this->values.Num() ]; - } - else { - return this->values[n] + ( index - n ) * ( this->values[n] - this->values[n-1] ); - } - } - return this->values[index]; -} - -/* -==================== -idCurve_Spline::TimeForIndex - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE float idCurve_Spline::TimeForIndex( const int index ) const { - int n = this->times.Num()-1; - - if ( index < 0 ) { - if ( boundaryType == BT_CLOSED ) { - return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) - ( this->times[n] + closeTime - this->times[this->times.Num() + index % this->times.Num()] ); - } - else { - return this->times[0] + index * ( this->times[1] - this->times[0] ); - } - } - else if ( index > n ) { - if ( boundaryType == BT_CLOSED ) { - return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) + this->times[index % this->times.Num()]; - } - else { - return this->times[n] + ( index - n ) * ( this->times[n] - this->times[n-1] ); - } - } - return this->times[index]; -} - -/* -==================== -idCurve_Spline::ClampedTime - - return the clamped time based on the boundary type -==================== -*/ -template< class type > -ID_INLINE float idCurve_Spline::ClampedTime( const float t ) const { - if ( boundaryType == BT_CLAMPED ) { - if ( t < this->times[0] ) { - return this->times[0]; - } - else if ( t >= this->times[this->times.Num()-1] ) { - return this->times[this->times.Num()-1]; - } - } - return t; -} - -/* -==================== -idCurve_Spline::IsDone -==================== -*/ -template< class type > -ID_INLINE bool idCurve_Spline::IsDone( const float time ) const { - return ( boundaryType != BT_CLOSED && time >= this->times[ this->times.Num() - 1 ] ); -} - - -/* -=============================================================================== - - Cubic Interpolating Spline template. - The curve goes through all the knots. - -=============================================================================== -*/ - -template< class type > -class idCurve_NaturalCubicSpline : public idCurve_Spline { -public: - idCurve_NaturalCubicSpline( void ); - - virtual void Clear( void ) { idCurve_Spline::Clear(); this->values.Clear(); b.Clear(); c.Clear(); d.Clear(); } - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - mutable idListb; - mutable idListc; - mutable idListd; - - void Setup( void ) const; - void SetupFree( void ) const; - void SetupClamped( void ) const; - void SetupClosed( void ) const; -}; - -/* -==================== -idCurve_NaturalCubicSpline::idCurve_NaturalCubicSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_NaturalCubicSpline::idCurve_NaturalCubicSpline( void ) { -} - -/* -==================== -idCurve_NaturalCubicSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentValue( const float time ) const { - float clampedTime = this->ClampedTime( time ); - int i = this->IndexForTime( clampedTime ); - float s = time - this->TimeForIndex( i ); - Setup(); - return ( this->values[i] + s * ( b[i] + s * ( c[i] + s * d[i] ) ) ); -} - -/* -==================== -idCurve_NaturalCubicSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentFirstDerivative( const float time ) const { - float clampedTime = this->ClampedTime( time ); - int i = this->IndexForTime( clampedTime ); - float s = time - this->TimeForIndex( i ); - Setup(); - return ( b[i] + s * ( 2.0f * c[i] + 3.0f * s * d[i] ) ); -} - -/* -==================== -idCurve_NaturalCubicSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NaturalCubicSpline::GetCurrentSecondDerivative( const float time ) const { - float clampedTime = this->ClampedTime( time ); - int i = this->IndexForTime( clampedTime ); - float s = time - this->TimeForIndex( i ); - Setup(); - return ( 2.0f * c[i] + 6.0f * s * d[i] ); -} - -/* -==================== -idCurve_NaturalCubicSpline::Setup -==================== -*/ -template< class type > -ID_INLINE void idCurve_NaturalCubicSpline::Setup( void ) const { - if ( this->changed ) { - switch( this->boundaryType ) { - case idCurve_Spline::BT_FREE: SetupFree(); break; - case idCurve_Spline::BT_CLAMPED: SetupClamped(); break; - case idCurve_Spline::BT_CLOSED: SetupClosed(); break; - } - this->changed = false; - } -} - -/* -==================== -idCurve_NaturalCubicSpline::SetupFree -==================== -*/ -template< class type > -ID_INLINE void idCurve_NaturalCubicSpline::SetupFree( void ) const { - int i; - float inv; - float *d0, *d1, *beta, *gamma; - type *alpha, *delta; - - d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) ); - beta = (float *) _alloca16( this->values.Num() * sizeof( float ) ); - gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - delta = (type *) _alloca16( this->values.Num() * sizeof( type ) ); - - for ( i = 0; i < this->values.Num() - 1; i++ ) { - d0[i] = this->times[i+1] - this->times[i]; - } - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - d1[i] = this->times[i+1] - this->times[i-1]; - } - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] ); - inv = 1.0f / ( d0[i-1] * d0[i] ); - alpha[i] = inv * sum; - } - - beta[0] = 1.0f; - gamma[0] = 0.0f; - delta[0] = this->values[0] - this->values[0]; - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1]; - inv = 1.0f / beta[i]; - gamma[i] = inv * d0[i]; - delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] ); - } - beta[this->values.Num() - 1] = 1.0f; - delta[this->values.Num() - 1] = this->values[0] - this->values[0]; - - b.AssureSize( this->values.Num() ); - c.AssureSize( this->values.Num() ); - d.AssureSize( this->values.Num() ); - - c[this->values.Num() - 1] = this->values[0] - this->values[0]; - - for ( i = this->values.Num() - 2; i >= 0; i-- ) { - c[i] = delta[i] - gamma[i] * c[i+1]; - inv = 1.0f / d0[i]; - b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i] * ( c[i+1] + 2.0f * c[i] ); - d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] ); - } -} - -/* -==================== -idCurve_NaturalCubicSpline::SetupClamped -==================== -*/ -template< class type > -ID_INLINE void idCurve_NaturalCubicSpline::SetupClamped( void ) const { - int i; - float inv; - float *d0, *d1, *beta, *gamma; - type *alpha, *delta; - - d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) ); - beta = (float *) _alloca16( this->values.Num() * sizeof( float ) ); - gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - delta = (type *) _alloca16( this->values.Num() * sizeof( type ) ); - - for ( i = 0; i < this->values.Num() - 1; i++ ) { - d0[i] = this->times[i+1] - this->times[i]; - } - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - d1[i] = this->times[i+1] - this->times[i-1]; - } - - inv = 1.0f / d0[0]; - alpha[0] = 3.0f * ( inv - 1.0f ) * ( this->values[1] - this->values[0] ); - inv = 1.0f / d0[this->values.Num() - 2]; - alpha[this->values.Num() - 1] = 3.0f * ( 1.0f - inv ) * ( this->values[this->values.Num() - 1] - this->values[this->values.Num() - 2] ); - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] ); - inv = 1.0f / ( d0[i-1] * d0[i] ); - alpha[i] = inv * sum; - } - - beta[0] = 2.0f * d0[0]; - gamma[0] = 0.5f; - inv = 1.0f / beta[0]; - delta[0] = inv * alpha[0]; - - for ( i = 1; i < this->values.Num() - 1; i++ ) { - beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1]; - inv = 1.0f / beta[i]; - gamma[i] = inv * d0[i]; - delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] ); - } - - beta[this->values.Num() - 1] = d0[this->values.Num() - 2] * ( 2.0f - gamma[this->values.Num() - 2] ); - inv = 1.0f / beta[this->values.Num() - 1]; - delta[this->values.Num() - 1] = inv * ( alpha[this->values.Num() - 1] - d0[this->values.Num() - 2] * delta[this->values.Num() - 2] ); - - b.AssureSize( this->values.Num() ); - c.AssureSize( this->values.Num() ); - d.AssureSize( this->values.Num() ); - - c[this->values.Num() - 1] = delta[this->values.Num() - 1]; - - for ( i = this->values.Num() - 2; i >= 0; i-- ) { - c[i] = delta[i] - gamma[i] * c[i+1]; - inv = 1.0f / d0[i]; - b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i]* ( c[i+1] + 2.0f * c[i] ); - d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] ); - } -} - -/* -==================== -idCurve_NaturalCubicSpline::SetupClosed -==================== -*/ -template< class type > -ID_INLINE void idCurve_NaturalCubicSpline::SetupClosed( void ) const { - int i, j; - float c0, c1; - float *d0; - idMatX mat; - idVecX x; - - d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) ); - x.SetData( this->values.Num(), VECX_ALLOCA( this->values.Num() ) ); - mat.SetData( this->values.Num(), this->values.Num(), MATX_ALLOCA( this->values.Num() * this->values.Num() ) ); - - b.AssureSize( this->values.Num() ); - c.AssureSize( this->values.Num() ); - d.AssureSize( this->values.Num() ); - - for ( i = 0; i < this->values.Num() - 1; i++ ) { - d0[i] = this->times[i+1] - this->times[i]; - } - - // matrix of system - mat[0][0] = 1.0f; - mat[0][this->values.Num() - 1] = -1.0f; - for ( i = 1; i <= this->values.Num() - 2; i++ ) { - mat[i][i-1] = d0[i-1]; - mat[i][i ] = 2.0f * ( d0[i-1] + d0[i] ); - mat[i][i+1] = d0[i]; - } - mat[this->values.Num() - 1][this->values.Num() - 2] = d0[this->values.Num() - 2]; - mat[this->values.Num() - 1][0] = 2.0f * ( d0[this->values.Num() - 2] + d0[0] ); - mat[this->values.Num() - 1][1] = d0[0]; - - // right-hand side - c[0].Zero(); - for ( i = 1; i <= this->values.Num() - 2; i++ ) { - c0 = 1.0f / d0[i]; - c1 = 1.0f / d0[i-1]; - c[i] = 3.0f * ( c0 * ( this->values[i + 1] - this->values[i] ) - c1 * ( this->values[i] - this->values[i - 1] ) ); - } - c0 = 1.0f / d0[0]; - c1 = 1.0f / d0[this->values.Num() - 2]; - c[this->values.Num() - 1] = 3.0f * ( c0 * ( this->values[1] - this->values[0] ) - c1 * ( this->values[0] - this->values[this->values.Num() - 2] ) ); - - // solve system for each dimension - mat.LU_Factor( NULL ); - for ( i = 0; i < this->values[0].GetDimension(); i++ ) { - for ( j = 0; j < this->values.Num(); j++ ) { - x[j] = c[j][i]; - } - mat.LU_Solve( x, x, NULL ); - for ( j = 0; j < this->values.Num(); j++ ) { - c[j][i] = x[j]; - } - } - - for ( i = 0; i < this->values.Num() - 1; i++ ) { - c0 = 1.0f / d0[i]; - b[i] = c0 * ( this->values[i + 1] - this->values[i] ) - ( 1.0f / 3.0f ) * ( c[i+1] + 2.0f * c[i] ) * d0[i]; - d[i] = ( 1.0f / 3.0f ) * c0 * ( c[i + 1] - c[i] ); - } -} - - -/* -=============================================================================== - - Uniform Cubic Interpolating Spline template. - The curve goes through all the knots. - -=============================================================================== -*/ - -template< class type > -class idCurve_CatmullRomSpline : public idCurve_Spline { - -public: - idCurve_CatmullRomSpline( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const int index, const float t, float *bvals ) const; - void BasisFirstDerivative( const int index, const float t, float *bvals ) const; - void BasisSecondDerivative( const int index, const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_CatmullRomSpline::idCurve_CatmullRomSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_CatmullRomSpline::idCurve_CatmullRomSpline( void ) { -} - -/* -==================== -idCurve_CatmullRomSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CatmullRomSpline::GetCurrentValue( const float time ) const { - int i, j, k; - float bvals[4], clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - Basis( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_CatmullRomSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CatmullRomSpline::GetCurrentFirstDerivative( const float time ) const { - int i, j, k; - float bvals[4], d, clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisFirstDerivative( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / d; -} - -/* -==================== -idCurve_CatmullRomSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_CatmullRomSpline::GetCurrentSecondDerivative( const float time ) const { - int i, j, k; - float bvals[4], d, clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisSecondDerivative( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / ( d * d ); -} - -/* -==================== -idCurve_CatmullRomSpline::Basis - - spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CatmullRomSpline::Basis( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = ( ( -s + 2.0f ) * s - 1.0f ) * s * 0.5f; // -0.5f s * s * s + s * s - 0.5f * s - bvals[1] = ( ( ( 3.0f * s - 5.0f ) * s ) * s + 2.0f ) * 0.5f; // 1.5f * s * s * s - 2.5f * s * s + 1.0f - bvals[2] = ( ( -3.0f * s + 4.0f ) * s + 1.0f ) * s * 0.5f; // -1.5f * s * s * s - 2.0f * s * s + 0.5f s - bvals[3] = ( ( s - 1.0f ) * s * s ) * 0.5f; // 0.5f * s * s * s - 0.5f * s * s -} - -/* -==================== -idCurve_CatmullRomSpline::BasisFirstDerivative - - first derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CatmullRomSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = ( -1.5f * s + 2.0f ) * s - 0.5f; // -1.5f * s * s + 2.0f * s - 0.5f - bvals[1] = ( 4.5f * s - 5.0f ) * s; // 4.5f * s * s - 5.0f * s - bvals[2] = ( -4.5 * s + 4.0f ) * s + 0.5f; // -4.5 * s * s + 4.0f * s + 0.5f - bvals[3] = 1.5f * s * s - s; // 1.5f * s * s - s -} - -/* -==================== -idCurve_CatmullRomSpline::BasisSecondDerivative - - second derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_CatmullRomSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = -3.0f * s + 2.0f; - bvals[1] = 9.0f * s - 5.0f; - bvals[2] = -9.0f * s + 4.0f; - bvals[3] = 3.0f * s - 1.0f; -} - - -/* -=============================================================================== - - Cubic Interpolating Spline template. - The curve goes through all the knots. - The curve becomes the Catmull-Rom spline if the tension, - continuity and bias are all set to zero. - -=============================================================================== -*/ - -template< class type > -class idCurve_KochanekBartelsSpline : public idCurve_Spline { - -public: - idCurve_KochanekBartelsSpline( void ); - - virtual int AddValue( const float time, const type &value ); - virtual int AddValue( const float time, const type &value, const float tension, const float continuity, const float bias ); - virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); tension.RemoveIndex(index); continuity.RemoveIndex(index); bias.RemoveIndex(index); } - virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); tension.Clear(); continuity.Clear(); bias.Clear(); this->currentIndex = -1; } - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - idList tension; - idList continuity; - idList bias; - - void TangentsForIndex( const int index, type &t0, type &t1 ) const; - - void Basis( const int index, const float t, float *bvals ) const; - void BasisFirstDerivative( const int index, const float t, float *bvals ) const; - void BasisSecondDerivative( const int index, const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_KochanekBartelsSpline::idCurve_KochanekBartelsSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_KochanekBartelsSpline::idCurve_KochanekBartelsSpline( void ) { -} - -/* -==================== -idCurve_KochanekBartelsSpline::AddValue - - add a timed/value pair to the spline - returns the index to the inserted pair -==================== -*/ -template< class type > -ID_INLINE int idCurve_KochanekBartelsSpline::AddValue( const float time, const type &value ) { - int i; - - i = this->IndexForTime( time ); - this->times.Insert( time, i ); - this->values.Insert( value, i ); - tension.Insert( 0.0f, i ); - continuity.Insert( 0.0f, i ); - bias.Insert( 0.0f, i ); - return i; -} - -/* -==================== -idCurve_KochanekBartelsSpline::AddValue - - add a timed/value pair to the spline - returns the index to the inserted pair -==================== -*/ -template< class type > -ID_INLINE int idCurve_KochanekBartelsSpline::AddValue( const float time, const type &value, const float tension, const float continuity, const float bias ) { - int i; - - i = this->IndexForTime( time ); - this->times.Insert( time, i ); - this->values.Insert( value, i ); - this->tension.Insert( tension, i ); - this->continuity.Insert( continuity, i ); - this->bias.Insert( bias, i ); - return i; -} - -/* -==================== -idCurve_KochanekBartelsSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentValue( const float time ) const { - int i; - float bvals[4], clampedTime; - type v, t0, t1; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - TangentsForIndex( i - 1, t0, t1 ); - Basis( i - 1, clampedTime, bvals ); - v = bvals[0] * this->ValueForIndex( i - 1 ); - v += bvals[1] * this->ValueForIndex( i ); - v += bvals[2] * t0; - v += bvals[3] * t1; - return v; -} - -/* -==================== -idCurve_KochanekBartelsSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentFirstDerivative( const float time ) const { - int i; - float bvals[4], d, clampedTime; - type v, t0, t1; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - TangentsForIndex( i - 1, t0, t1 ); - BasisFirstDerivative( i - 1, clampedTime, bvals ); - v = bvals[0] * this->ValueForIndex( i - 1 ); - v += bvals[1] * this->ValueForIndex( i ); - v += bvals[2] * t0; - v += bvals[3] * t1; - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / d; -} - -/* -==================== -idCurve_KochanekBartelsSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_KochanekBartelsSpline::GetCurrentSecondDerivative( const float time ) const { - int i; - float bvals[4], d, clampedTime; - type v, t0, t1; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - TangentsForIndex( i - 1, t0, t1 ); - BasisSecondDerivative( i - 1, clampedTime, bvals ); - v = bvals[0] * this->ValueForIndex( i - 1 ); - v += bvals[1] * this->ValueForIndex( i ); - v += bvals[2] * t0; - v += bvals[3] * t1; - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / ( d * d ); -} - -/* -==================== -idCurve_KochanekBartelsSpline::TangentsForIndex -==================== -*/ -template< class type > -ID_INLINE void idCurve_KochanekBartelsSpline::TangentsForIndex( const int index, type &t0, type &t1 ) const { - float dt, omt, omc, opc, omb, opb, adj, s0, s1; - type delta; - - delta = this->ValueForIndex( index + 1 ) - this->ValueForIndex( index ); - dt = this->TimeForIndex( index + 1 ) - this->TimeForIndex( index ); - - omt = 1.0f - tension[index]; - omc = 1.0f - continuity[index]; - opc = 1.0f + continuity[index]; - omb = 1.0f - bias[index]; - opb = 1.0f + bias[index]; - adj = 2.0f * dt / ( this->TimeForIndex( index + 1 ) - this->TimeForIndex( index - 1 ) ); - s0 = 0.5f * adj * omt * opc * opb; - s1 = 0.5f * adj * omt * omc * omb; - - // outgoing tangent at first point - t0 = s1 * delta + s0 * ( this->ValueForIndex( index ) - this->ValueForIndex( index - 1 ) ); - - omt = 1.0f - tension[index + 1]; - omc = 1.0f - continuity[index + 1]; - opc = 1.0f + continuity[index + 1]; - omb = 1.0f - bias[index + 1]; - opb = 1.0f + bias[index + 1]; - adj = 2.0f * dt / ( this->TimeForIndex( index + 2 ) - this->TimeForIndex( index ) ); - s0 = 0.5f * adj * omt * omc * opb; - s1 = 0.5f * adj * omt * opc * omb; - - // incoming tangent at second point - t1 = s1 * ( this->ValueForIndex( index + 2 ) - this->ValueForIndex( index + 1 ) ) + s0 * delta; -} - -/* -==================== -idCurve_KochanekBartelsSpline::Basis - - spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_KochanekBartelsSpline::Basis( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = ( ( 2.0f * s - 3.0f ) * s ) * s + 1.0f; // 2.0f * s * s * s - 3.0f * s * s + 1.0f - bvals[1] = ( ( -2.0f * s + 3.0f ) * s ) * s; // -2.0f * s * s * s + 3.0f * s * s - bvals[2] = ( ( s - 2.0f ) * s ) * s + s; // s * s * s - 2.0f * s * s + s - bvals[3] = ( ( s - 1.0f ) * s ) * s; // s * s * s - s * s -} - -/* -==================== -idCurve_KochanekBartelsSpline::BasisFirstDerivative - - first derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_KochanekBartelsSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = ( 6.0f * s - 6.0f ) * s; // 6.0f * s * s - 6.0f * s - bvals[1] = ( -6.0f * s + 6.0f ) * s; // -6.0f * s * s + 6.0f * s - bvals[2] = ( 3.0f * s - 4.0f ) * s + 1.0f; // 3.0f * s * s - 4.0f * s + 1.0f - bvals[3] = ( 3.0f * s - 2.0f ) * s; // 3.0f * s * s - 2.0f * s -} - -/* -==================== -idCurve_KochanekBartelsSpline::BasisSecondDerivative - - second derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_KochanekBartelsSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = 12.0f * s - 6.0f; - bvals[1] = -12.0f * s + 6.0f; - bvals[2] = 6.0f * s - 4.0f; - bvals[3] = 6.0f * s - 2.0f; -} - - -/* -=============================================================================== - - B-Spline base template. Uses recursive definition and is slow. - Use idCurve_UniformCubicBSpline or idCurve_NonUniformBSpline instead. - -=============================================================================== -*/ - -template< class type > -class idCurve_BSpline : public idCurve_Spline { - -public: - idCurve_BSpline( void ); - - virtual int GetOrder( void ) const { return order; } - virtual void SetOrder( const int i ) { assert( i > 0 && i < 10 ); order = i; } - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - int order; - - float Basis( const int index, const int order, const float t ) const; - float BasisFirstDerivative( const int index, const int order, const float t ) const; - float BasisSecondDerivative( const int index, const int order, const float t ) const; -}; - -/* -==================== -idCurve_BSpline::idCurve_NaturalCubicSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_BSpline::idCurve_BSpline( void ) { - order = 4; // default to cubic -} - -/* -==================== -idCurve_BSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_BSpline::GetCurrentValue( const float time ) const { - int i, j, k; - float clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < order; j++ ) { - k = i + j - ( order >> 1 ); - v += Basis( k-2, order, clampedTime ) * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_BSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_BSpline::GetCurrentFirstDerivative( const float time ) const { - int i, j, k; - float clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < order; j++ ) { - k = i + j - ( order >> 1 ); - v += BasisFirstDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_BSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_BSpline::GetCurrentSecondDerivative( const float time ) const { - int i, j, k; - float clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < order; j++ ) { - k = i + j - ( order >> 1 ); - v += BasisSecondDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_BSpline::Basis - - spline basis function -==================== -*/ -template< class type > -ID_INLINE float idCurve_BSpline::Basis( const int index, const int order, const float t ) const { - if ( order <= 1 ) { - if ( this->TimeForIndex( index ) < t && t <= this->TimeForIndex( index + 1 ) ) { - return 1.0f; - } else { - return 0.0f; - } - } else { - float sum = 0.0f; - float d1 = this->TimeForIndex( index+order-1 ) - this->TimeForIndex( index ); - if ( d1 != 0.0f ) { - sum += (float) ( t - this->TimeForIndex( index ) ) * Basis( index, order-1, t ) / d1; - } - - float d2 = this->TimeForIndex( index+order ) - this->TimeForIndex( index+1 ); - if ( d2 != 0.0f ) { - sum += (float) ( this->TimeForIndex( index+order ) - t ) * Basis( index+1, order-1, t ) / d2; - } - return sum; - } -} - -/* -==================== -idCurve_BSpline::BasisFirstDerivative - - first derivative of spline basis function -==================== -*/ -template< class type > -ID_INLINE float idCurve_BSpline::BasisFirstDerivative( const int index, const int order, const float t ) const { - return ( Basis( index, order-1, t ) - Basis( index+1, order-1, t ) ) * - (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) ); -} - -/* -==================== -idCurve_BSpline::BasisSecondDerivative - - second derivative of spline basis function -==================== -*/ -template< class type > -ID_INLINE float idCurve_BSpline::BasisSecondDerivative( const int index, const int order, const float t ) const { - return ( BasisFirstDerivative( index, order-1, t ) - BasisFirstDerivative( index+1, order-1, t ) ) * - (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) ); -} - - -/* -=============================================================================== - - Uniform Non-Rational Cubic B-Spline template. - -=============================================================================== -*/ - -template< class type > -class idCurve_UniformCubicBSpline : public idCurve_BSpline { - -public: - idCurve_UniformCubicBSpline( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const int index, const float t, float *bvals ) const; - void BasisFirstDerivative( const int index, const float t, float *bvals ) const; - void BasisSecondDerivative( const int index, const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_UniformCubicBSpline::idCurve_UniformCubicBSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_UniformCubicBSpline::idCurve_UniformCubicBSpline( void ) { - this->order = 4; // always cubic -} - -/* -==================== -idCurve_UniformCubicBSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentValue( const float time ) const { - int i, j, k; - float bvals[4], clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - Basis( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_UniformCubicBSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentFirstDerivative( const float time ) const { - int i, j, k; - float bvals[4], d, clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisFirstDerivative( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / d; -} - -/* -==================== -idCurve_UniformCubicBSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_UniformCubicBSpline::GetCurrentSecondDerivative( const float time ) const { - int i, j, k; - float bvals[4], d, clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisSecondDerivative( i-1, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < 4; j++ ) { - k = i + j - 2; - v += bvals[j] * this->ValueForIndex( k ); - } - d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) ); - return v / ( d * d ); -} - -/* -==================== -idCurve_UniformCubicBSpline::Basis - - spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_UniformCubicBSpline::Basis( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = ( ( ( -s + 3.0f ) * s - 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f ); - bvals[1] = ( ( ( 3.0f * s - 6.0f ) * s ) * s + 4.0f ) * ( 1.0f / 6.0f ); - bvals[2] = ( ( ( -3.0f * s + 3.0f ) * s + 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f ); - bvals[3] = ( s * s * s ) * ( 1.0f / 6.0f ); -} - -/* -==================== -idCurve_UniformCubicBSpline::BasisFirstDerivative - - first derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_UniformCubicBSpline::BasisFirstDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = -0.5f * s * s + s - 0.5f; - bvals[1] = 1.5f * s * s - 2.0f * s; - bvals[2] = -1.5f * s * s + s + 0.5f; - bvals[3] = 0.5f * s * s; -} - -/* -==================== -idCurve_UniformCubicBSpline::BasisSecondDerivative - - second derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_UniformCubicBSpline::BasisSecondDerivative( const int index, const float t, float *bvals ) const { - float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) ); - bvals[0] = -s + 1.0f; - bvals[1] = 3.0f * s - 2.0f; - bvals[2] = -3.0f * s + 1.0f; - bvals[3] = s; -} - - -/* -=============================================================================== - - Non-Uniform Non-Rational B-Spline (NUBS) template. - -=============================================================================== -*/ - -template< class type > -class idCurve_NonUniformBSpline : public idCurve_BSpline { - -public: - idCurve_NonUniformBSpline( void ); - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - void Basis( const int index, const int order, const float t, float *bvals ) const; - void BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const; - void BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const; -}; - -/* -==================== -idCurve_NonUniformBSpline::idCurve_NonUniformBSpline -==================== -*/ -template< class type > -ID_INLINE idCurve_NonUniformBSpline::idCurve_NonUniformBSpline( void ) { -} - -/* -==================== -idCurve_NonUniformBSpline::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NonUniformBSpline::GetCurrentValue( const float time ) const { - int i, j, k; - float clampedTime; - type v; - float *bvals = (float *) _alloca16( this->order * sizeof(float) ); - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - Basis( i-1, this->order, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - v += bvals[j] * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_NonUniformBSpline::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NonUniformBSpline::GetCurrentFirstDerivative( const float time ) const { - int i, j, k; - float clampedTime; - type v; - float *bvals = (float *) _alloca16( this->order * sizeof(float) ); - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisFirstDerivative( i-1, this->order, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - v += bvals[j] * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_NonUniformBSpline::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NonUniformBSpline::GetCurrentSecondDerivative( const float time ) const { - int i, j, k; - float clampedTime; - type v; - float *bvals = (float *) _alloca16( this->order * sizeof(float) ); - - if ( this->times.Num() == 1 ) { - return ( this->values[0] - this->values[0] ); - } - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - BasisSecondDerivative( i-1, this->order, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - v += bvals[j] * this->ValueForIndex( k ); - } - return v; -} - -/* -==================== -idCurve_NonUniformBSpline::Basis - - spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_NonUniformBSpline::Basis( const int index, const int order, const float t, float *bvals ) const { - int r, s, i; - float omega; - - bvals[order-1] = 1.0f; - for ( r = 2; r <= order; r++ ) { - i = index - r + 1; - bvals[order - r] = 0.0f; - for ( s = order - r + 1; s < order; s++ ) { - i++; - omega = (float) ( t - this->TimeForIndex( i ) ) / ( this->TimeForIndex( i + r - 1 ) - this->TimeForIndex( i ) ); - bvals[s - 1] += ( 1.0f - omega ) * bvals[s]; - bvals[s] *= omega; - } - } -} - -/* -==================== -idCurve_NonUniformBSpline::BasisFirstDerivative - - first derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_NonUniformBSpline::BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const { - int i; - - Basis( index, order-1, t, bvals+1 ); - bvals[0] = 0.0f; - for ( i = 0; i < order-1; i++ ) { - bvals[i] -= bvals[i+1]; - bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); - } - bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); -} - -/* -==================== -idCurve_NonUniformBSpline::BasisSecondDerivative - - second derivative of spline basis functions -==================== -*/ -template< class type > -ID_INLINE void idCurve_NonUniformBSpline::BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const { - int i; - - BasisFirstDerivative( index, order-1, t, bvals+1 ); - bvals[0] = 0.0f; - for ( i = 0; i < order-1; i++ ) { - bvals[i] -= bvals[i+1]; - bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); - } - bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) ); -} - - -/* -=============================================================================== - - Non-Uniform Rational B-Spline (NURBS) template. - -=============================================================================== -*/ - -template< class type > -class idCurve_NURBS : public idCurve_NonUniformBSpline { - -public: - idCurve_NURBS( void ); - - virtual int AddValue( const float time, const type &value ); - virtual int AddValue( const float time, const type &value, const float weight ); - virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); weights.RemoveIndex(index); } - virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); weights.Clear(); this->currentIndex = -1; } - - virtual type GetCurrentValue( const float time ) const; - virtual type GetCurrentFirstDerivative( const float time ) const; - virtual type GetCurrentSecondDerivative( const float time ) const; - -protected: - idList weights; - - float WeightForIndex( const int index ) const; -}; - -/* -==================== -idCurve_NURBS::idCurve_NURBS -==================== -*/ -template< class type > -ID_INLINE idCurve_NURBS::idCurve_NURBS( void ) { -} - -/* -==================== -idCurve_NURBS::AddValue - - add a timed/value pair to the spline - returns the index to the inserted pair -==================== -*/ -template< class type > -ID_INLINE int idCurve_NURBS::AddValue( const float time, const type &value ) { - int i; - - i = this->IndexForTime( time ); - this->times.Insert( time, i ); - this->values.Insert( value, i ); - weights.Insert( 1.0f, i ); - return i; -} - -/* -==================== -idCurve_NURBS::AddValue - - add a timed/value pair to the spline - returns the index to the inserted pair -==================== -*/ -template< class type > -ID_INLINE int idCurve_NURBS::AddValue( const float time, const type &value, const float weight ) { - int i; - - i = this->IndexForTime( time ); - this->times.Insert( time, i ); - this->values.Insert( value, i ); - weights.Insert( weight, i ); - return i; -} - -/* -==================== -idCurve_NURBS::GetCurrentValue - - get the value for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NURBS::GetCurrentValue( const float time ) const { - int i, j, k; - float w, b, *bvals, clampedTime; - type v; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - bvals = (float *) _alloca16( this->order * sizeof(float) ); - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - this->Basis( i-1, this->order, clampedTime, bvals ); - v = this->values[0] - this->values[0]; - w = 0.0f; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - b = bvals[j] * WeightForIndex( k ); - w += b; - v += b * this->ValueForIndex( k ); - } - return v / w; -} - -/* -==================== -idCurve_NURBS::GetCurrentFirstDerivative - - get the first derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NURBS::GetCurrentFirstDerivative( const float time ) const { - int i, j, k; - float w, wb, wd1, b, d1, *bvals, *d1vals, clampedTime; - type v, vb, vd1; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - bvals = (float *) _alloca16( this->order * sizeof(float) ); - d1vals = (float *) _alloca16( this->order * sizeof(float) ); - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - this->Basis( i-1, this->order, clampedTime, bvals ); - this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals ); - vb = vd1 = this->values[0] - this->values[0]; - wb = wd1 = 0.0f; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - w = WeightForIndex( k ); - b = bvals[j] * w; - d1 = d1vals[j] * w; - wb += b; - wd1 += d1; - v = this->ValueForIndex( k ); - vb += b * v; - vd1 += d1 * v; - } - return ( wb * vd1 - vb * wd1 ) / ( wb * wb ); -} - -/* -==================== -idCurve_NURBS::GetCurrentSecondDerivative - - get the second derivative for the given time -==================== -*/ -template< class type > -ID_INLINE type idCurve_NURBS::GetCurrentSecondDerivative( const float time ) const { - int i, j, k; - float w, wb, wd1, wd2, b, d1, d2, *bvals, *d1vals, *d2vals, clampedTime; - type v, vb, vd1, vd2; - - if ( this->times.Num() == 1 ) { - return this->values[0]; - } - - bvals = (float *) _alloca16( this->order * sizeof(float) ); - d1vals = (float *) _alloca16( this->order * sizeof(float) ); - d2vals = (float *) _alloca16( this->order * sizeof(float) ); - - clampedTime = this->ClampedTime( time ); - i = this->IndexForTime( clampedTime ); - this->Basis( i-1, this->order, clampedTime, bvals ); - this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals ); - this->BasisSecondDerivative( i-1, this->order, clampedTime, d2vals ); - vb = vd1 = vd2 = this->values[0] - this->values[0]; - wb = wd1 = wd2 = 0.0f; - for ( j = 0; j < this->order; j++ ) { - k = i + j - ( this->order >> 1 ); - w = WeightForIndex( k ); - b = bvals[j] * w; - d1 = d1vals[j] * w; - d2 = d2vals[j] * w; - wb += b; - wd1 += d1; - wd2 += d2; - v = this->ValueForIndex( k ); - vb += b * v; - vd1 += d1 * v; - vd2 += d2 * v; - } - return ( ( wb * wb ) * ( wb * vd2 - vb * wd2 ) - ( wb * vd1 - vb * wd1 ) * 2.0f * wb * wd1 ) / ( wb * wb * wb * wb ); -} - -/* -==================== -idCurve_NURBS::WeightForIndex - - get the weight for the given index -==================== -*/ -template< class type > -ID_INLINE float idCurve_NURBS::WeightForIndex( const int index ) const { - int n = weights.Num()-1; - - if ( index < 0 ) { - if ( this->boundaryType == idCurve_Spline::BT_CLOSED ) { - return weights[ weights.Num() + index % weights.Num() ]; - } else { - return weights[0] + index * ( weights[1] - weights[0] ); - } - } else if ( index > n ) { - if ( this->boundaryType == idCurve_Spline::BT_CLOSED ) { - return weights[ index % weights.Num() ]; - } else { - return weights[n] + ( index - n ) * ( weights[n] - weights[n-1] ); - } - } - return weights[index]; -} - -#endif /* !__MATH_CURVE_H__ */ diff --git a/idlib/math/extrapolate.h b/idlib/math/extrapolate.h deleted file mode 100644 index 05cb672b1..000000000 --- a/idlib/math/extrapolate.h +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_EXTRAPOLATE_H__ -#define __MATH_EXTRAPOLATE_H__ - -/* -============================================================================================== - - Extrapolation - -============================================================================================== -*/ - -typedef enum { - EXTRAPOLATION_NONE = 0x01, // no extrapolation, covered distance = duration * 0.001 * ( baseSpeed ) - EXTRAPOLATION_LINEAR = 0x02, // linear extrapolation, covered distance = duration * 0.001 * ( baseSpeed + speed ) - EXTRAPOLATION_ACCELLINEAR = 0x04, // linear acceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed ) - EXTRAPOLATION_DECELLINEAR = 0x08, // linear deceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed ) - EXTRAPOLATION_ACCELSINE = 0x10, // sinusoidal acceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed ) - EXTRAPOLATION_DECELSINE = 0x20, // sinusoidal deceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed ) - EXTRAPOLATION_NOSTOP = 0x40 // do not stop at startTime + duration -} extrapolation_t; - -template< class type > -class idExtrapolate { -public: - idExtrapolate(); - - void Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType ); - type GetCurrentValue( float time ) const; - type GetCurrentSpeed( float time ) const; - bool IsDone( float time ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && time >= startTime + duration ); } - void SetStartTime( float time ) { startTime = time; currentTime = -1; } - float GetStartTime( void ) const { return startTime; } - float GetEndTime( void ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && duration > 0 ) ? startTime + duration : 0; } - float GetDuration( void ) const { return duration; } - void SetStartValue( const type &value ) { startValue = value; currentTime = -1; } - const type & GetStartValue( void ) const { return startValue; } - const type & GetBaseSpeed( void ) const { return baseSpeed; } - const type & GetSpeed( void ) const { return speed; } - extrapolation_t GetExtrapolationType( void ) const { return extrapolationType; } - -private: - extrapolation_t extrapolationType; - float startTime; - float duration; - type startValue; - type baseSpeed; - type speed; - mutable float currentTime; - mutable type currentValue; -}; - -/* -==================== -idExtrapolate::idExtrapolate -==================== -*/ -template< class type > -ID_INLINE idExtrapolate::idExtrapolate() { - extrapolationType = EXTRAPOLATION_NONE; - startTime = duration = 0.0f; - memset( &startValue, 0, sizeof( startValue ) ); - memset( &baseSpeed, 0, sizeof( baseSpeed ) ); - memset( &speed, 0, sizeof( speed ) ); - currentTime = -1; - currentValue = startValue; -} - -/* -==================== -idExtrapolate::Init -==================== -*/ -template< class type > -ID_INLINE void idExtrapolate::Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType ) { - this->extrapolationType = extrapolationType; - this->startTime = startTime; - this->duration = duration; - this->startValue = startValue; - this->baseSpeed = baseSpeed; - this->speed = speed; - currentTime = -1; - currentValue = startValue; -} - -/* -==================== -idExtrapolate::GetCurrentValue -==================== -*/ -template< class type > -ID_INLINE type idExtrapolate::GetCurrentValue( float time ) const { - float deltaTime, s; - - if ( time == currentTime ) { - return currentValue; - } - - currentTime = time; - - if ( time < startTime ) { - return startValue; - } - - if ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) { - time = startTime + duration; - } - - switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) { - case EXTRAPOLATION_NONE: { - deltaTime = ( time - startTime ) * 0.001f; - currentValue = startValue + deltaTime * baseSpeed; - break; - } - case EXTRAPOLATION_LINEAR: { - deltaTime = ( time - startTime ) * 0.001f; - currentValue = startValue + deltaTime * ( baseSpeed + speed ); - break; - } - case EXTRAPOLATION_ACCELLINEAR: { - if ( !duration ) { - currentValue = startValue; - } else { - deltaTime = ( time - startTime ) / duration; - s = ( 0.5f * deltaTime * deltaTime ) * ( duration * 0.001f ); - currentValue = startValue + deltaTime * baseSpeed + s * speed; - } - break; - } - case EXTRAPOLATION_DECELLINEAR: { - if ( !duration ) { - currentValue = startValue; - } else { - deltaTime = ( time - startTime ) / duration; - s = ( deltaTime - ( 0.5f * deltaTime * deltaTime ) ) * ( duration * 0.001f ); - currentValue = startValue + deltaTime * baseSpeed + s * speed; - } - break; - } - case EXTRAPOLATION_ACCELSINE: { - if ( !duration ) { - currentValue = startValue; - } else { - deltaTime = ( time - startTime ) / duration; - s = ( 1.0f - idMath::Cos( deltaTime * idMath::HALF_PI ) ) * duration * 0.001f * idMath::SQRT_1OVER2; - currentValue = startValue + deltaTime * baseSpeed + s * speed; - } - break; - } - case EXTRAPOLATION_DECELSINE: { - if ( !duration ) { - currentValue = startValue; - } else { - deltaTime = ( time - startTime ) / duration; - s = idMath::Sin( deltaTime * idMath::HALF_PI ) * duration * 0.001f * idMath::SQRT_1OVER2; - currentValue = startValue + deltaTime * baseSpeed + s * speed; - } - break; - } - } - return currentValue; -} - -/* -==================== -idExtrapolate::GetCurrentSpeed -==================== -*/ -template< class type > -ID_INLINE type idExtrapolate::GetCurrentSpeed( float time ) const { - float deltaTime, s; - - if ( time < startTime || !duration ) { - return ( startValue - startValue ); - } - - if ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) { - return ( startValue - startValue ); - } - - switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) { - case EXTRAPOLATION_NONE: { - return baseSpeed; - } - case EXTRAPOLATION_LINEAR: { - return baseSpeed + speed; - } - case EXTRAPOLATION_ACCELLINEAR: { - deltaTime = ( time - startTime ) / duration; - s = deltaTime; - return baseSpeed + s * speed; - } - case EXTRAPOLATION_DECELLINEAR: { - deltaTime = ( time - startTime ) / duration; - s = 1.0f - deltaTime; - return baseSpeed + s * speed; - } - case EXTRAPOLATION_ACCELSINE: { - deltaTime = ( time - startTime ) / duration; - s = idMath::Sin( deltaTime * idMath::HALF_PI ); - return baseSpeed + s * speed; - } - case EXTRAPOLATION_DECELSINE: { - deltaTime = ( time - startTime ) / duration; - s = idMath::Cos( deltaTime * idMath::HALF_PI ); - return baseSpeed + s * speed; - } - default: { - return baseSpeed; - } - } -} - -#endif /* !__MATH_EXTRAPOLATE_H__ */ diff --git a/idlib/math/interpolate.h b/idlib/math/interpolate.h deleted file mode 100644 index af4861224..000000000 --- a/idlib/math/interpolate.h +++ /dev/null @@ -1,409 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_INTERPOLATE_H__ -#define __MATH_INTERPOLATE_H__ - -/* -============================================================================================== - - Linear interpolation. - -============================================================================================== -*/ - -template< class type > -class idInterpolate { -public: - idInterpolate(); - - // Start a transition, this automatically sets the idInterpolate to "enabled" - void Init( const float startTime, const float duration, const type &startValue, const type &endValue ); - void SetStartTime( float time ) { this->startTime = time; } - void SetDuration( float duration ) { this->duration = duration; } - void SetStartValue( const type &startValue ) { this->startValue = startValue; } - void SetEndValue( const type &endValue ) { this->endValue = endValue; } - - type GetCurrentValue( float time ) const; - bool IsDone( float time ) const { return ( time >= startTime + duration ); } - - float GetStartTime( void ) const { return startTime; } - float GetEndTime( void ) const { return startTime + duration; } - float GetDuration( void ) const { return duration; } - const type & GetStartValue( void ) const { return startValue; } - const type & GetEndValue( void ) const { return endValue; } - - // greebo: Returns TRUE if this interpolation is active. - inline bool Enabled() const { return enabled; }; - void SetEnabled(bool isEnabled) { enabled = isEnabled; }; - -private: - bool enabled; - float startTime; - float duration; - type startValue; - type endValue; - mutable float currentTime; - mutable type currentValue; -}; - -/* -==================== -idInterpolate::idInterpolate -==================== -*/ -template< class type > -ID_INLINE idInterpolate::idInterpolate() : - enabled(true) -{ - currentTime = startTime = duration = 0; - memset( ¤tValue, 0, sizeof( currentValue ) ); - startValue = endValue = currentValue; -} - -/* -==================== -idInterpolate::Init -==================== -*/ -template< class type > -ID_INLINE void idInterpolate::Init( const float startTime, const float duration, const type &startValue, const type &endValue ) { - this->startTime = startTime; - this->duration = duration; - this->startValue = startValue; - this->endValue = endValue; - this->currentTime = startTime - 1; - this->currentValue = startValue; - this->enabled = true; -} - -/* -==================== -idInterpolate::GetCurrentValue -==================== -*/ -template< class type > -ID_INLINE type idInterpolate::GetCurrentValue( float time ) const { - float deltaTime; - - deltaTime = time - startTime; - if ( time != currentTime ) { - currentTime = time; - if ( deltaTime <= 0 ) { - currentValue = startValue; - } else if ( deltaTime >= duration ) { - currentValue = endValue; - } else { - currentValue = static_cast(startValue + ( endValue - startValue ) * ( (float) deltaTime / duration )); - } - } - return currentValue; -} - -/* -============================================================================================== - - Continuous interpolation with linear acceleration and deceleration phase. - The velocity is continuous but the acceleration is not. - -============================================================================================== -*/ - -template< class type > -class idInterpolateAccelDecelLinear { -public: - idInterpolateAccelDecelLinear(); - - void Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ); - void SetStartTime( float time ) { startTime = time; Invalidate(); } - void SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); } - void SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); } - - type GetCurrentValue( float time ) const; - type GetCurrentSpeed( float time ) const; - bool IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); } - - float GetStartTime( void ) const { return startTime; } - float GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; } - float GetDuration( void ) const { return accelTime + linearTime + decelTime; } - float GetAcceleration( void ) const { return accelTime; } - float GetDeceleration( void ) const { return decelTime; } - const type & GetStartValue( void ) const { return startValue; } - const type & GetEndValue( void ) const { return endValue; } - -private: - float startTime; - float accelTime; - float linearTime; - float decelTime; - type startValue; - type endValue; - mutable idExtrapolate extrapolate; - - void Invalidate( void ); - void SetPhase( float time ) const; -}; - -/* -==================== -idInterpolateAccelDecelLinear::idInterpolateAccelDecelLinear -==================== -*/ -template< class type > -ID_INLINE idInterpolateAccelDecelLinear::idInterpolateAccelDecelLinear() { - startTime = accelTime = linearTime = decelTime = 0; - memset( &startValue, 0, sizeof( startValue ) ); - endValue = startValue; -} - -/* -==================== -idInterpolateAccelDecelLinear::Init -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelLinear::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) { - type speed; - - this->startTime = startTime; - this->accelTime = accelTime; - this->decelTime = decelTime; - this->startValue = startValue; - this->endValue = endValue; - - if ( duration <= 0.0f ) { - return; - } - - if ( this->accelTime + this->decelTime > duration ) { - this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime ); - this->decelTime = duration - this->accelTime; - } - this->linearTime = duration - this->accelTime - this->decelTime; - speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * 0.5f ) ); - - if ( this->accelTime ) { - extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELLINEAR ); - } else if ( this->linearTime ) { - extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR ); - } else { - extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELLINEAR ); - } -} - -/* -==================== -idInterpolateAccelDecelLinear::Invalidate -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelLinear::Invalidate( void ) { - extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE ); -} - -/* -==================== -idInterpolateAccelDecelLinear::SetPhase -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelLinear::SetPhase( float time ) const { - float deltaTime; - - deltaTime = time - startTime; - if ( deltaTime < accelTime ) { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELLINEAR ) { - extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELLINEAR ); - } - } else if ( deltaTime < accelTime + linearTime ) { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) { - extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * 0.5f ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR ); - } - } else { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELLINEAR ) { - extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * 0.5f ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELLINEAR ); - } - } -} - -/* -==================== -idInterpolateAccelDecelLinear::GetCurrentValue -==================== -*/ -template< class type > -ID_INLINE type idInterpolateAccelDecelLinear::GetCurrentValue( float time ) const { - SetPhase( time ); - return extrapolate.GetCurrentValue( time ); -} - -/* -==================== -idInterpolateAccelDecelLinear::GetCurrentSpeed -==================== -*/ -template< class type > -ID_INLINE type idInterpolateAccelDecelLinear::GetCurrentSpeed( float time ) const { - SetPhase( time ); - return extrapolate.GetCurrentSpeed( time ); -} - - -/* -============================================================================================== - - Continuous interpolation with sinusoidal acceleration and deceleration phase. - Both the velocity and acceleration are continuous. - -============================================================================================== -*/ - -template< class type > -class idInterpolateAccelDecelSine { -public: - idInterpolateAccelDecelSine(); - - void Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ); - void SetStartTime( float time ) { startTime = time; Invalidate(); } - void SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); } - void SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); } - - type GetCurrentValue( float time ) const; - type GetCurrentSpeed( float time ) const; - bool IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); } - - float GetStartTime( void ) const { return startTime; } - float GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; } - float GetDuration( void ) const { return accelTime + linearTime + decelTime; } - float GetAcceleration( void ) const { return accelTime; } - float GetDeceleration( void ) const { return decelTime; } - const type & GetStartValue( void ) const { return startValue; } - const type & GetEndValue( void ) const { return endValue; } - -private: - float startTime; - float accelTime; - float linearTime; - float decelTime; - type startValue; - type endValue; - mutable idExtrapolate extrapolate; - - void Invalidate( void ); - void SetPhase( float time ) const; -}; - -/* -==================== -idInterpolateAccelDecelSine::idInterpolateAccelDecelSine -==================== -*/ -template< class type > -ID_INLINE idInterpolateAccelDecelSine::idInterpolateAccelDecelSine() { - startTime = accelTime = linearTime = decelTime = 0; - memset( &startValue, 0, sizeof( startValue ) ); - endValue = startValue; -} - -/* -==================== -idInterpolateAccelDecelSine::Init -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelSine::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) { - type speed; - - this->startTime = startTime; - this->accelTime = accelTime; - this->decelTime = decelTime; - this->startValue = startValue; - this->endValue = endValue; - - if ( duration <= 0.0f ) { - return; - } - - if ( this->accelTime + this->decelTime > duration ) { - this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime ); - this->decelTime = duration - this->accelTime; - } - this->linearTime = duration - this->accelTime - this->decelTime; - speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * idMath::SQRT_1OVER2 ) ); - - if ( this->accelTime ) { - extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELSINE ); - } else if ( this->linearTime ) { - extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR ); - } else { - extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELSINE ); - } -} - -/* -==================== -idInterpolateAccelDecelSine::Invalidate -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelSine::Invalidate( void ) { - extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE ); -} - -/* -==================== -idInterpolateAccelDecelSine::SetPhase -==================== -*/ -template< class type > -ID_INLINE void idInterpolateAccelDecelSine::SetPhase( float time ) const { - float deltaTime; - - deltaTime = time - startTime; - if ( deltaTime < accelTime ) { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELSINE ) { - extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELSINE ); - } - } else if ( deltaTime < accelTime + linearTime ) { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) { - extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * idMath::SQRT_1OVER2 ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR ); - } - } else { - if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELSINE ) { - extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * idMath::SQRT_1OVER2 ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELSINE ); - } - } -} - -/* -==================== -idInterpolateAccelDecelSine::GetCurrentValue -==================== -*/ -template< class type > -ID_INLINE type idInterpolateAccelDecelSine::GetCurrentValue( float time ) const { - SetPhase( time ); - return extrapolate.GetCurrentValue( time ); -} - -/* -==================== -idInterpolateAccelDecelSine::GetCurrentSpeed -==================== -*/ -template< class type > -ID_INLINE type idInterpolateAccelDecelSine::GetCurrentSpeed( float time ) const { - SetPhase( time ); - return extrapolate.GetCurrentSpeed( time ); -} - -#endif /* !__MATH_INTERPOLATE_H__ */ diff --git a/idlib/math/lcp.cpp b/idlib/math/lcp.cpp deleted file mode 100644 index 6538ae0ff..000000000 --- a/idlib/math/lcp.cpp +++ /dev/null @@ -1,1630 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -static idCVar lcp_showFailures( "lcp_showFailures", "0", CVAR_SYSTEM | CVAR_BOOL, "show LCP solver failures" ); - -const float LCP_BOUND_EPSILON = 1e-5f; -const float LCP_ACCEL_EPSILON = 1e-5f; -const float LCP_DELTA_ACCEL_EPSILON = 1e-9f; -const float LCP_DELTA_FORCE_EPSILON = 1e-9f; - -#define IGNORE_UNSATISFIABLE_VARIABLES - -//=============================================================== -// M -// idLCP_Square MrE -// E -//=============================================================== - -class idLCP_Square : public idLCP { -public: - virtual bool Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ); - -private: - idMatX m; // original matrix - idVecX b; // right hand side - idVecX lo, hi; // low and high bounds - idVecX f, a; // force and acceleration - idVecX delta_f, delta_a; // delta force and delta acceleration - idMatX clamped; // LU factored sub matrix for clamped variables - idVecX diagonal; // reciprocal of diagonal of U of the LU factored sub matrix for clamped variables - int numUnbounded; // number of unbounded variables - int numClamped; // number of clamped variables - float ** rowPtrs; // pointers to the rows of m - int * boxIndex; // box index - int * side; // tells if a variable is at the low boundary = -1, high boundary = 1 or inbetween = 0 - int * permuted; // index to keep track of the permutation - bool padded; // set to true if the rows of the initial matrix are 16 byte padded - -private: - bool FactorClamped( void ); - void SolveClamped( idVecX &x, const float *b ); - void Swap( int i, int j ); - void AddClamped( int r ); - void RemoveClamped( int r ); - void CalcForceDelta( int d, float dir ); - void CalcAccelDelta( int d ); - void ChangeForce( int d, float step ); - void ChangeAccel( int d, float step ); - void GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const; -}; - -/* -============ -idLCP_Square::FactorClamped -============ -*/ -bool idLCP_Square::FactorClamped( void ) { - int i, j, k; - float s, d; - - for ( i = 0; i < numClamped; i++ ) { - memcpy( clamped[i], rowPtrs[i], numClamped * sizeof( float ) ); - } - - for ( i = 0; i < numClamped; i++ ) { - - s = idMath::Fabs( clamped[i][i] ); - - if ( s == 0.0f ) { - return false; - } - - diagonal[i] = d = 1.0f / clamped[i][i]; - for ( j = i + 1; j < numClamped; j++ ) { - clamped[j][i] *= d; - } - - for ( j = i + 1; j < numClamped; j++ ) { - d = clamped[j][i]; - for ( k = i + 1; k < numClamped; k++ ) { - clamped[j][k] -= d * clamped[i][k]; - } - } - } - - return true; -} - -/* -============ -idLCP_Square::SolveClamped -============ -*/ -void idLCP_Square::SolveClamped( idVecX &x, const float *b ) { - int i, j; - float sum; - - // solve L - for ( i = 0; i < numClamped; i++ ) { - sum = b[i]; - for ( j = 0; j < i; j++ ) { - sum -= clamped[i][j] * x[j]; - } - x[i] = sum; - } - - // solve U - for ( i = numClamped - 1; i >= 0; i-- ) { - sum = x[i]; - for ( j = i + 1; j < numClamped; j++ ) { - sum -= clamped[i][j] * x[j]; - } - x[i] = sum * diagonal[i]; - } -} - -/* -============ -idLCP_Square::Swap -============ -*/ -void idLCP_Square::Swap( int i, int j ) { - - if ( i == j ) { - return; - } - - idSwap( rowPtrs[i], rowPtrs[j] ); - m.SwapColumns( i, j ); - b.SwapElements( i, j ); - lo.SwapElements( i, j ); - hi.SwapElements( i, j ); - a.SwapElements( i, j ); - f.SwapElements( i, j ); - if ( boxIndex ) { - idSwap( boxIndex[i], boxIndex[j] ); - } - idSwap( side[i], side[j] ); - idSwap( permuted[i], permuted[j] ); -} - -/* -============ -idLCP_Square::AddClamped -============ -*/ -void idLCP_Square::AddClamped( int r ) { - int i, j; - float sum; - - assert( r >= numClamped ); - - // add a row at the bottom and a column at the right of the factored - // matrix for the clamped variables - - Swap( numClamped, r ); - - // add row to L - for ( i = 0; i < numClamped; i++ ) { - sum = rowPtrs[numClamped][i]; - for ( j = 0; j < i; j++ ) { - sum -= clamped[numClamped][j] * clamped[j][i]; - } - clamped[numClamped][i] = sum * diagonal[i]; - } - - // add column to U - for ( i = 0; i <= numClamped; i++ ) { - sum = rowPtrs[i][numClamped]; - for ( j = 0; j < i; j++ ) { - sum -= clamped[i][j] * clamped[j][numClamped]; - } - clamped[i][numClamped] = sum; - } - - diagonal[numClamped] = 1.0f / clamped[numClamped][numClamped]; - - numClamped++; -} - -/* -============ -idLCP_Square::RemoveClamped -============ -*/ -void idLCP_Square::RemoveClamped( int r ) { - int i, j; - float *y0, *y1, *z0, *z1; - double diag, beta0, beta1, p0, p1, q0, q1, d; - - assert( r < numClamped ); - - numClamped--; - - // no need to swap and update the factored matrix when the last row and column are removed - if ( r == numClamped ) { - return; - } - - y0 = (float *) _alloca16( numClamped * sizeof( float ) ); - z0 = (float *) _alloca16( numClamped * sizeof( float ) ); - y1 = (float *) _alloca16( numClamped * sizeof( float ) ); - z1 = (float *) _alloca16( numClamped * sizeof( float ) ); - - // the row/column need to be subtracted from the factorization - for ( i = 0; i < numClamped; i++ ) { - y0[i] = -rowPtrs[i][r]; - } - - memset( y1, 0, numClamped * sizeof( float ) ); - y1[r] = 1.0f; - - memset( z0, 0, numClamped * sizeof( float ) ); - z0[r] = 1.0f; - - for ( i = 0; i < numClamped; i++ ) { - z1[i] = -rowPtrs[r][i]; - } - - // swap the to be removed row/column with the last row/column - Swap( r, numClamped ); - - // the swapped last row/column need to be added to the factorization - for ( i = 0; i < numClamped; i++ ) { - y0[i] += rowPtrs[i][r]; - } - - for ( i = 0; i < numClamped; i++ ) { - z1[i] += rowPtrs[r][i]; - } - z1[r] = 0.0f; - - // update the beginning of the to be updated row and column - for ( i = 0; i < r; i++ ) { - p0 = y0[i]; - beta1 = z1[i] * diagonal[i]; - - clamped[i][r] += p0; - for ( j = i+1; j < numClamped; j++ ) { - z1[j] -= beta1 * clamped[i][j]; - } - for ( j = i+1; j < numClamped; j++ ) { - y0[j] -= p0 * clamped[j][i]; - } - clamped[r][i] += beta1; - } - - // update the lower right corner starting at r,r - for ( i = r; i < numClamped; i++ ) { - diag = clamped[i][i]; - - p0 = y0[i]; - p1 = z0[i]; - diag += p0 * p1; - - if ( diag == 0.0f ) { - idLib::common->Printf( "idLCP_Square::RemoveClamped: updating factorization failed\n" ); - return; - } - - beta0 = p1 / diag; - - q0 = y1[i]; - q1 = z1[i]; - diag += q0 * q1; - - if ( diag == 0.0f ) { - idLib::common->Printf( "idLCP_Square::RemoveClamped: updating factorization failed\n" ); - return; - } - - d = 1.0f / diag; - beta1 = q1 * d; - - clamped[i][i] = diag; - diagonal[i] = d; - - for ( j = i+1; j < numClamped; j++ ) { - - d = clamped[i][j]; - - d += p0 * z0[j]; - z0[j] -= beta0 * d; - - d += q0 * z1[j]; - z1[j] -= beta1 * d; - - clamped[i][j] = d; - } - - for ( j = i+1; j < numClamped; j++ ) { - - d = clamped[j][i]; - - y0[j] -= p0 * d; - d += beta0 * y0[j]; - - y1[j] -= q0 * d; - d += beta1 * y1[j]; - - clamped[j][i] = d; - } - } - return; -} - -/* -============ -idLCP_Square::CalcForceDelta - - modifies this->delta_f -============ -*/ -inline void idLCP_Square::CalcForceDelta( int d, float dir ) { - int i; - float *ptr; - - delta_f[d] = dir; - - if ( numClamped == 0 ) { - return; - } - - // get column d of matrix - ptr = (float *) _alloca16( numClamped * sizeof( float ) ); - for ( i = 0; i < numClamped; i++ ) { - ptr[i] = rowPtrs[i][d]; - } - - // solve force delta - SolveClamped( delta_f, ptr ); - - // flip force delta based on direction - if ( dir > 0.0f ) { - ptr = delta_f.ToFloatPtr(); - for ( i = 0; i < numClamped; i++ ) { - ptr[i] = - ptr[i]; - } - } -} - -/* -============ -idLCP_Square::CalcAccelDelta - - modifies this->delta_a and uses this->delta_f -============ -*/ -ID_INLINE void idLCP_Square::CalcAccelDelta( int d ) { - int j; - float dot; - - // only the not clamped variables, including the current variable, can have a change in acceleration - for ( j = numClamped; j <= d; j++ ) { - // only the clamped variables and the current variable have a force delta unequal zero - SIMDProcessor->Dot( dot, rowPtrs[j], delta_f.ToFloatPtr(), numClamped ); - delta_a[j] = dot + rowPtrs[j][d] * delta_f[d]; - } -} - -/* -============ -idLCP_Square::ChangeForce - - modifies this->f and uses this->delta_f -============ -*/ -ID_INLINE void idLCP_Square::ChangeForce( int d, float step ) { - // only the clamped variables and current variable have a force delta unequal zero - SIMDProcessor->MulAdd( f.ToFloatPtr(), step, delta_f.ToFloatPtr(), numClamped ); - f[d] += step * delta_f[d]; -} - -/* -============ -idLCP_Square::ChangeAccel - - modifies this->a and uses this->delta_a -============ -*/ -ID_INLINE void idLCP_Square::ChangeAccel( int d, float step ) { - // only the not clamped variables, including the current variable, can have an acceleration unequal zero - SIMDProcessor->MulAdd( a.ToFloatPtr() + numClamped, step, delta_a.ToFloatPtr() + numClamped, d - numClamped + 1 ); -} - -/* -============ -idLCP_Square::GetMaxStep -============ -*/ -void idLCP_Square::GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const { - int i; - float s; - - // default to a full step for the current variable - if ( idMath::Fabs( delta_a[d] ) > LCP_DELTA_ACCEL_EPSILON ) { - maxStep = -a[d] / delta_a[d]; - } else { - maxStep = 0.0f; - } - limit = d; - limitSide = 0; - - // test the current variable - if ( dir < 0.0f ) { - if ( lo[d] != -idMath::INFINITY ) { - s = ( lo[d] - f[d] ) / dir; - if ( s < maxStep ) { - maxStep = s; - limitSide = -1; - } - } - } else { - if ( hi[d] != idMath::INFINITY ) { - s = ( hi[d] - f[d] ) / dir; - if ( s < maxStep ) { - maxStep = s; - limitSide = 1; - } - } - } - - // test the clamped bounded variables - for ( i = numUnbounded; i < numClamped; i++ ) { - if ( delta_f[i] < -LCP_DELTA_FORCE_EPSILON ) { - // if there is a low boundary - if ( lo[i] != -idMath::INFINITY ) { - s = ( lo[i] - f[i] ) / delta_f[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = -1; - } - } - } else if ( delta_f[i] > LCP_DELTA_FORCE_EPSILON ) { - // if there is a high boundary - if ( hi[i] != idMath::INFINITY ) { - s = ( hi[i] - f[i] ) / delta_f[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = 1; - } - } - } - } - - // test the not clamped bounded variables - for ( i = numClamped; i < d; i++ ) { - if ( side[i] == -1 ) { - if ( delta_a[i] >= -LCP_DELTA_ACCEL_EPSILON ) { - continue; - } - } else if ( side[i] == 1 ) { - if ( delta_a[i] <= LCP_DELTA_ACCEL_EPSILON ) { - continue; - } - } else { - continue; - } - // ignore variables for which the force is not allowed to take any substantial value - if ( lo[i] >= -LCP_BOUND_EPSILON && hi[i] <= LCP_BOUND_EPSILON ) { - continue; - } - s = -a[i] / delta_a[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = 0; - } - } -} - -/* -============ -idLCP_Square::Solve -============ -*/ -bool idLCP_Square::Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ) { - int i, j, n, limit, limitSide, boxStartIndex; - float dir, maxStep, dot, s; - char *failed; - - // true when the matrix rows are 16 byte padded - padded = ((o_m.GetNumRows()+3)&~3) == o_m.GetNumColumns(); - - assert( padded || o_m.GetNumRows() == o_m.GetNumColumns() ); - assert( o_x.GetSize() == o_m.GetNumRows() ); - assert( o_b.GetSize() == o_m.GetNumRows() ); - assert( o_lo.GetSize() == o_m.GetNumRows() ); - assert( o_hi.GetSize() == o_m.GetNumRows() ); - - // allocate memory for permuted input - f.SetData( o_m.GetNumRows(), VECX_ALLOCA( o_m.GetNumRows() ) ); - a.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); - b.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); - lo.SetData( o_lo.GetSize(), VECX_ALLOCA( o_lo.GetSize() ) ); - hi.SetData( o_hi.GetSize(), VECX_ALLOCA( o_hi.GetSize() ) ); - if ( o_boxIndex ) { - boxIndex = (int *)_alloca16( o_x.GetSize() * sizeof( int ) ); - memcpy( boxIndex, o_boxIndex, o_x.GetSize() * sizeof( int ) ); - } else { - boxIndex = NULL; - } - - // we override the const on o_m here but on exit the matrix is unchanged - m.SetData( o_m.GetNumRows(), o_m.GetNumColumns(), const_cast(o_m[0]) ); - f.Zero(); - a.Zero(); - b = o_b; - lo = o_lo; - hi = o_hi; - - // pointers to the rows of m - rowPtrs = (float **) _alloca16( m.GetNumRows() * sizeof( float * ) ); - for ( i = 0; i < m.GetNumRows(); i++ ) { - rowPtrs[i] = m[i]; - } - - // tells if a variable is at the low boundary, high boundary or inbetween - side = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); - - // index to keep track of the permutation - permuted = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); - for ( i = 0; i < m.GetNumRows(); i++ ) { - permuted[i] = i; - } - - // permute input so all unbounded variables come first - numUnbounded = 0; - for ( i = 0; i < m.GetNumRows(); i++ ) { - if ( lo[i] == -idMath::INFINITY && hi[i] == idMath::INFINITY ) { - if ( numUnbounded != i ) { - Swap( numUnbounded, i ); - } - numUnbounded++; - } - } - - // permute input so all variables using the boxIndex come last - boxStartIndex = m.GetNumRows(); - if ( boxIndex ) { - for ( i = m.GetNumRows() - 1; i >= numUnbounded; i-- ) { - if ( boxIndex[i] >= 0 && ( lo[i] != -idMath::INFINITY || hi[i] != idMath::INFINITY ) ) { - boxStartIndex--; - if ( boxStartIndex != i ) { - Swap( boxStartIndex, i ); - } - } - } - } - - // sub matrix for factorization - clamped.SetData( m.GetNumRows(), m.GetNumColumns(), MATX_ALLOCA( m.GetNumRows() * m.GetNumColumns() ) ); - diagonal.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - - // all unbounded variables are clamped - numClamped = numUnbounded; - - // if there are unbounded variables - if ( numUnbounded ) { - - // factor and solve for unbounded variables - if ( !FactorClamped() ) { - idLib::common->Printf( "idLCP_Square::Solve: unbounded factorization failed\n" ); - return false; - } - SolveClamped( f, b.ToFloatPtr() ); - - // if there are no bounded variables we are done - if ( numUnbounded == m.GetNumRows() ) { - o_x = f; // the vector is not permuted - return true; - } - } - -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - int numIgnored = 0; -#endif - - // allocate for delta force and delta acceleration - delta_f.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - delta_a.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - - // solve for bounded variables - failed = NULL; - for ( i = numUnbounded; i < m.GetNumRows(); i++ ) { - - // once we hit the box start index we can initialize the low and high boundaries of the variables using the box index - if ( i == boxStartIndex ) { - for ( j = 0; j < boxStartIndex; j++ ) { - o_x[permuted[j]] = f[j]; - } - for ( j = boxStartIndex; j < m.GetNumRows(); j++ ) { - s = o_x[boxIndex[j]]; - if ( lo[j] != -idMath::INFINITY ) { - lo[j] = - idMath::Fabs( lo[j] * s ); - } - if ( hi[j] != idMath::INFINITY ) { - hi[j] = idMath::Fabs( hi[j] * s ); - } - } - } - - // calculate acceleration for current variable - SIMDProcessor->Dot( dot, rowPtrs[i], f.ToFloatPtr(), i ); - a[i] = dot - b[i]; - - // if already at the low boundary - if ( lo[i] >= -LCP_BOUND_EPSILON && a[i] >= -LCP_ACCEL_EPSILON ) { - side[i] = -1; - continue; - } - - // if already at the high boundary - if ( hi[i] <= LCP_BOUND_EPSILON && a[i] <= LCP_ACCEL_EPSILON ) { - side[i] = 1; - continue; - } - - // if inside the clamped region - if ( idMath::Fabs( a[i] ) <= LCP_ACCEL_EPSILON ) { - side[i] = 0; - AddClamped( i ); - continue; - } - - // drive the current variable into a valid region - for ( n = 0; n < maxIterations; n++ ) { - - // direction to move - if ( a[i] <= 0.0f ) { - dir = 1.0f; - } else { - dir = -1.0f; - } - - // calculate force delta - CalcForceDelta( i, dir ); - - // calculate acceleration delta: delta_a = m * delta_f; - CalcAccelDelta( i ); - - // maximum step we can take - GetMaxStep( i, dir, maxStep, limit, limitSide ); - - if ( maxStep <= 0.0f ) { -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - // ignore the current variable completely - lo[i] = hi[i] = 0.0f; - f[i] = 0.0f; - side[i] = -1; - numIgnored++; -#else - failed = va( "invalid step size %.4f", maxStep ); -#endif - break; - } - - // change force - ChangeForce( i, maxStep ); - - // change acceleration - ChangeAccel( i, maxStep ); - - // clamp/unclamp the variable that limited this step - side[limit] = limitSide; - switch( limitSide ) { - case 0: { - a[limit] = 0.0f; - AddClamped( limit ); - break; - } - case -1: { - f[limit] = lo[limit]; - if ( limit != i ) { - RemoveClamped( limit ); - } - break; - } - case 1: { - f[limit] = hi[limit]; - if ( limit != i ) { - RemoveClamped( limit ); - } - break; - } - } - - // if the current variable limited the step we can continue with the next variable - if ( limit == i ) { - break; - } - } - - if ( n >= maxIterations ) { - failed = va( "max iterations %d", maxIterations ); - break; - } - - if ( failed ) { - break; - } - } - -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - if ( numIgnored ) { - if ( lcp_showFailures.GetBool() ) { - idLib::common->Printf( "idLCP_Symmetric::Solve: %d of %d bounded variables ignored\n", numIgnored, m.GetNumRows() - numUnbounded ); - } - } -#endif - - // if failed clear remaining forces - if ( failed ) { - if ( lcp_showFailures.GetBool() ) { - idLib::common->Printf( "idLCP_Square::Solve: %s (%d of %d bounded variables ignored)\n", failed, m.GetNumRows() - i, m.GetNumRows() - numUnbounded ); - } - for ( j = i; j < m.GetNumRows(); j++ ) { - f[j] = 0.0f; - } - } - -#if defined(_DEBUG) && 0 - if ( !failed ) { - // test whether or not the solution satisfies the complementarity conditions - for ( i = 0; i < m.GetNumRows(); i++ ) { - a[i] = -b[i]; - for ( j = 0; j < m.GetNumRows(); j++ ) { - a[i] += rowPtrs[i][j] * f[j]; - } - - if ( f[i] == lo[i] ) { - if ( lo[i] != hi[i] && a[i] < -LCP_ACCEL_EPSILON ) { - int bah1 = 1; - } - } else if ( f[i] == hi[i] ) { - if ( lo[i] != hi[i] && a[i] > LCP_ACCEL_EPSILON ) { - int bah2 = 1; - } - } else if ( f[i] < lo[i] || f[i] > hi[i] || idMath::Fabs( a[i] ) > 1.0f ) { - int bah3 = 1; - } - } - } -#endif - - // unpermute result - for ( i = 0; i < f.GetSize(); i++ ) { - o_x[permuted[i]] = f[i]; - } - - // unpermute original matrix - for ( i = 0; i < m.GetNumRows(); i++ ) { - for ( j = 0; j < m.GetNumRows(); j++ ) { - if ( permuted[j] == i ) { - break; - } - } - if ( i != j ) { - m.SwapColumns( i, j ); - idSwap( permuted[i], permuted[j] ); - } - } - - return true; -} - - -//=============================================================== -// M -// idLCP_Symmetric MrE -// E -//=============================================================== - -class idLCP_Symmetric : public idLCP { -public: - virtual bool Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ); - -private: - idMatX m; // original matrix - idVecX b; // right hand side - idVecX lo, hi; // low and high bounds - idVecX f, a; // force and acceleration - idVecX delta_f, delta_a; // delta force and delta acceleration - idMatX clamped; // LDLt factored sub matrix for clamped variables - idVecX diagonal; // reciprocal of diagonal of LDLt factored sub matrix for clamped variables - idVecX solveCache1; // intermediate result cached in SolveClamped - idVecX solveCache2; // " - int numUnbounded; // number of unbounded variables - int numClamped; // number of clamped variables - int clampedChangeStart; // lowest row/column changed in the clamped matrix during an iteration - float ** rowPtrs; // pointers to the rows of m - int * boxIndex; // box index - int * side; // tells if a variable is at the low boundary = -1, high boundary = 1 or inbetween = 0 - int * permuted; // index to keep track of the permutation - bool padded; // set to true if the rows of the initial matrix are 16 byte padded - -private: - bool FactorClamped( void ); - void SolveClamped( idVecX &x, const float *b ); - void Swap( int i, int j ); - void AddClamped( int r, bool useSolveCache ); - void RemoveClamped( int r ); - void CalcForceDelta( int d, float dir ); - void CalcAccelDelta( int d ); - void ChangeForce( int d, float step ); - void ChangeAccel( int d, float step ); - void GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const; -}; - -/* -============ -idLCP_Symmetric::FactorClamped -============ -*/ -bool idLCP_Symmetric::FactorClamped( void ) { - - clampedChangeStart = 0; - - for ( int i = 0; i < numClamped; i++ ) { - memcpy( clamped[i], rowPtrs[i], numClamped * sizeof( float ) ); - } - return SIMDProcessor->MatX_LDLTFactor( clamped, diagonal, numClamped ); -} - -/* -============ -idLCP_Symmetric::SolveClamped -============ -*/ -void idLCP_Symmetric::SolveClamped( idVecX &x, const float *b ) { - - // solve L - SIMDProcessor->MatX_LowerTriangularSolve( clamped, solveCache1.ToFloatPtr(), b, numClamped, clampedChangeStart ); - - // solve D - SIMDProcessor->Mul( solveCache2.ToFloatPtr(), solveCache1.ToFloatPtr(), diagonal.ToFloatPtr(), numClamped ); - - // solve Lt - SIMDProcessor->MatX_LowerTriangularSolveTranspose( clamped, x.ToFloatPtr(), solveCache2.ToFloatPtr(), numClamped ); - - clampedChangeStart = numClamped; -} - -/* -============ -idLCP_Symmetric::Swap -============ -*/ -void idLCP_Symmetric::Swap( int i, int j ) { - - if ( i == j ) { - return; - } - - idSwap( rowPtrs[i], rowPtrs[j] ); - m.SwapColumns( i, j ); - b.SwapElements( i, j ); - lo.SwapElements( i, j ); - hi.SwapElements( i, j ); - a.SwapElements( i, j ); - f.SwapElements( i, j ); - if ( boxIndex ) { - idSwap( boxIndex[i], boxIndex[j] ); - } - idSwap( side[i], side[j] ); - idSwap( permuted[i], permuted[j] ); -} - -/* -============ -idLCP_Symmetric::AddClamped -============ -*/ -void idLCP_Symmetric::AddClamped( int r, bool useSolveCache ) { - float d, dot; - - assert( r >= numClamped ); - - if ( numClamped < clampedChangeStart ) { - clampedChangeStart = numClamped; - } - - // add a row at the bottom and a column at the right of the factored - // matrix for the clamped variables - - Swap( numClamped, r ); - - // solve for v in L * v = rowPtr[numClamped] - if ( useSolveCache ) { - - // the lower triangular solve was cached in SolveClamped called by CalcForceDelta - memcpy( clamped[numClamped], solveCache2.ToFloatPtr(), numClamped * sizeof( float ) ); - // calculate row dot product - SIMDProcessor->Dot( dot, solveCache2.ToFloatPtr(), solveCache1.ToFloatPtr(), numClamped ); - - } else { - - float *v = (float *) _alloca16( numClamped * sizeof( float ) ); - - SIMDProcessor->MatX_LowerTriangularSolve( clamped, v, rowPtrs[numClamped], numClamped ); - // add bottom row to L - SIMDProcessor->Mul( clamped[numClamped], v, diagonal.ToFloatPtr(), numClamped ); - // calculate row dot product - SIMDProcessor->Dot( dot, clamped[numClamped], v, numClamped ); - } - - // update diagonal[numClamped] - d = rowPtrs[numClamped][numClamped] - dot; - - if ( d == 0.0f ) { - idLib::common->Printf( "idLCP_Symmetric::AddClamped: updating factorization failed\n" ); - numClamped++; - return; - } - - clamped[numClamped][numClamped] = d; - diagonal[numClamped] = 1.0f / d; - - numClamped++; -} - -/* -============ -idLCP_Symmetric::RemoveClamped -============ -*/ -void idLCP_Symmetric::RemoveClamped( int r ) { - int i, j, n; - float *addSub, *original, *v, *ptr, *v1, *v2, dot; - double sum, diag, newDiag, invNewDiag, p1, p2, alpha1, alpha2, beta1, beta2; - - assert( r < numClamped ); - - if ( r < clampedChangeStart ) { - clampedChangeStart = r; - } - - numClamped--; - - // no need to swap and update the factored matrix when the last row and column are removed - if ( r == numClamped ) { - return; - } - - // swap the to be removed row/column with the last row/column - Swap( r, numClamped ); - - // update the factored matrix - addSub = (float *) _alloca16( numClamped * sizeof( float ) ); - - if ( r == 0 ) { - - if ( numClamped == 1 ) { - diag = rowPtrs[0][0]; - if ( diag == 0.0f ) { - idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); - return; - } - clamped[0][0] = diag; - diagonal[0] = 1.0f / diag; - return; - } - - // calculate the row/column to be added to the lower right sub matrix starting at (r, r) - original = rowPtrs[numClamped]; - ptr = rowPtrs[r]; - addSub[0] = ptr[0] - original[numClamped]; - for ( i = 1; i < numClamped; i++ ) { - addSub[i] = ptr[i] - original[i]; - } - - } else { - - v = (float *) _alloca16( numClamped * sizeof( float ) ); - - // solve for v in L * v = rowPtr[r] - SIMDProcessor->MatX_LowerTriangularSolve( clamped, v, rowPtrs[r], r ); - - // update removed row - SIMDProcessor->Mul( clamped[r], v, diagonal.ToFloatPtr(), r ); - - // if the last row/column of the matrix is updated - if ( r == numClamped - 1 ) { - // only calculate new diagonal - SIMDProcessor->Dot( dot, clamped[r], v, r ); - diag = rowPtrs[r][r] - dot; - if ( diag == 0.0f ) { - idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); - return; - } - clamped[r][r] = diag; - diagonal[r] = 1.0f / diag; - return; - } - - // calculate the row/column to be added to the lower right sub matrix starting at (r, r) - for ( i = 0; i < r; i++ ) { - v[i] = clamped[r][i] * clamped[i][i]; - } - for ( i = r; i < numClamped; i++ ) { - if ( i == r ) { - sum = clamped[r][r]; - } else { - sum = clamped[r][r] * clamped[i][r]; - } - ptr = clamped[i]; - for ( j = 0; j < r; j++ ) { - sum += ptr[j] * v[j]; - } - addSub[i] = rowPtrs[r][i] - sum; - } - } - - // add row/column to the lower right sub matrix starting at (r, r) - - v1 = (float *) _alloca16( numClamped * sizeof( float ) ); - v2 = (float *) _alloca16( numClamped * sizeof( float ) ); - - diag = idMath::SQRT_1OVER2; - v1[r] = ( 0.5f * addSub[r] + 1.0f ) * diag; - v2[r] = ( 0.5f * addSub[r] - 1.0f ) * diag; - for ( i = r+1; i < numClamped; i++ ) { - v1[i] = v2[i] = addSub[i] * diag; - } - - alpha1 = 1.0f; - alpha2 = -1.0f; - - // simultaneous update/downdate of the sub matrix starting at (r, r) - n = clamped.GetNumColumns(); - for ( i = r; i < numClamped; i++ ) { - - diag = clamped[i][i]; - p1 = v1[i]; - newDiag = diag + alpha1 * p1 * p1; - - if ( newDiag == 0.0f ) { - idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); - return; - } - - alpha1 /= newDiag; - beta1 = p1 * alpha1; - alpha1 *= diag; - - diag = newDiag; - p2 = v2[i]; - newDiag = diag + alpha2 * p2 * p2; - - if ( newDiag == 0.0f ) { - idLib::common->Printf( "idLCP_Symmetric::RemoveClamped: updating factorization failed\n" ); - return; - } - - clamped[i][i] = newDiag; - diagonal[i] = invNewDiag = 1.0f / newDiag; - - alpha2 *= invNewDiag; - beta2 = p2 * alpha2; - alpha2 *= diag; - - // update column below diagonal (i,i) - ptr = clamped.ToFloatPtr() + i; - - for ( j = i+1; j < numClamped - 1; j += 2 ) { - - float sum0 = ptr[(j+0)*n]; - float sum1 = ptr[(j+1)*n]; - - v1[j+0] -= p1 * sum0; - v1[j+1] -= p1 * sum1; - - sum0 += beta1 * v1[j+0]; - sum1 += beta1 * v1[j+1]; - - v2[j+0] -= p2 * sum0; - v2[j+1] -= p2 * sum1; - - sum0 += beta2 * v2[j+0]; - sum1 += beta2 * v2[j+1]; - - ptr[(j+0)*n] = sum0; - ptr[(j+1)*n] = sum1; - } - - for ( ; j < numClamped; j++ ) { - - sum = ptr[j*n]; - - v1[j] -= p1 * sum; - sum += beta1 * v1[j]; - - v2[j] -= p2 * sum; - sum += beta2 * v2[j]; - - ptr[j*n] = sum; - } - } -} - -/* -============ -idLCP_Symmetric::CalcForceDelta - - modifies this->delta_f -============ -*/ -ID_INLINE void idLCP_Symmetric::CalcForceDelta( int d, float dir ) { - int i; - float *ptr; - - delta_f[d] = dir; - - if ( numClamped == 0 ) { - return; - } - - // solve force delta - SolveClamped( delta_f, rowPtrs[d] ); - - // flip force delta based on direction - if ( dir > 0.0f ) { - ptr = delta_f.ToFloatPtr(); - for ( i = 0; i < numClamped; i++ ) { - ptr[i] = - ptr[i]; - } - } -} - -/* -============ -idLCP_Symmetric::CalcAccelDelta - - modifies this->delta_a and uses this->delta_f -============ -*/ -ID_INLINE void idLCP_Symmetric::CalcAccelDelta( int d ) { - int j; - float dot; - - // only the not clamped variables, including the current variable, can have a change in acceleration - for ( j = numClamped; j <= d; j++ ) { - // only the clamped variables and the current variable have a force delta unequal zero - SIMDProcessor->Dot( dot, rowPtrs[j], delta_f.ToFloatPtr(), numClamped ); - delta_a[j] = dot + rowPtrs[j][d] * delta_f[d]; - } -} - -/* -============ -idLCP_Symmetric::ChangeForce - - modifies this->f and uses this->delta_f -============ -*/ -ID_INLINE void idLCP_Symmetric::ChangeForce( int d, float step ) { - // only the clamped variables and current variable have a force delta unequal zero - SIMDProcessor->MulAdd( f.ToFloatPtr(), step, delta_f.ToFloatPtr(), numClamped ); - f[d] += step * delta_f[d]; -} - -/* -============ -idLCP_Symmetric::ChangeAccel - - modifies this->a and uses this->delta_a -============ -*/ -ID_INLINE void idLCP_Symmetric::ChangeAccel( int d, float step ) { - // only the not clamped variables, including the current variable, can have an acceleration unequal zero - SIMDProcessor->MulAdd( a.ToFloatPtr() + numClamped, step, delta_a.ToFloatPtr() + numClamped, d - numClamped + 1 ); -} - -/* -============ -idLCP_Symmetric::GetMaxStep -============ -*/ -void idLCP_Symmetric::GetMaxStep( int d, float dir, float &maxStep, int &limit, int &limitSide ) const { - int i; - float s; - - // default to a full step for the current variable - if ( idMath::Fabs( delta_a[d] ) > LCP_DELTA_ACCEL_EPSILON ) { - maxStep = -a[d] / delta_a[d]; - } else { - maxStep = 0.0f; - } - limit = d; - limitSide = 0; - - // test the current variable - if ( dir < 0.0f ) { - if ( lo[d] != -idMath::INFINITY ) { - s = ( lo[d] - f[d] ) / dir; - if ( s < maxStep ) { - maxStep = s; - limitSide = -1; - } - } - } else { - if ( hi[d] != idMath::INFINITY ) { - s = ( hi[d] - f[d] ) / dir; - if ( s < maxStep ) { - maxStep = s; - limitSide = 1; - } - } - } - - // test the clamped bounded variables - for ( i = numUnbounded; i < numClamped; i++ ) { - if ( delta_f[i] < -LCP_DELTA_FORCE_EPSILON ) { - // if there is a low boundary - if ( lo[i] != -idMath::INFINITY ) { - s = ( lo[i] - f[i] ) / delta_f[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = -1; - } - } - } else if ( delta_f[i] > LCP_DELTA_FORCE_EPSILON ) { - // if there is a high boundary - if ( hi[i] != idMath::INFINITY ) { - s = ( hi[i] - f[i] ) / delta_f[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = 1; - } - } - } - } - - // test the not clamped bounded variables - for ( i = numClamped; i < d; i++ ) { - if ( side[i] == -1 ) { - if ( delta_a[i] >= -LCP_DELTA_ACCEL_EPSILON ) { - continue; - } - } else if ( side[i] == 1 ) { - if ( delta_a[i] <= LCP_DELTA_ACCEL_EPSILON ) { - continue; - } - } else { - continue; - } - // ignore variables for which the force is not allowed to take any substantial value - if ( lo[i] >= -LCP_BOUND_EPSILON && hi[i] <= LCP_BOUND_EPSILON ) { - continue; - } - s = -a[i] / delta_a[i]; - if ( s < maxStep ) { - maxStep = s; - limit = i; - limitSide = 0; - } - } -} - -/* -============ -idLCP_Symmetric::Solve -============ -*/ -bool idLCP_Symmetric::Solve( const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex ) { - int i, j, n, limit, limitSide, boxStartIndex; - float dir, maxStep, dot, s; - char *failed; - - // true when the matrix rows are 16 byte padded - padded = ((o_m.GetNumRows()+3)&~3) == o_m.GetNumColumns(); - - assert( padded || o_m.GetNumRows() == o_m.GetNumColumns() ); - assert( o_x.GetSize() == o_m.GetNumRows() ); - assert( o_b.GetSize() == o_m.GetNumRows() ); - assert( o_lo.GetSize() == o_m.GetNumRows() ); - assert( o_hi.GetSize() == o_m.GetNumRows() ); - - // allocate memory for permuted input - f.SetData( o_m.GetNumRows(), VECX_ALLOCA( o_m.GetNumRows() ) ); - a.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); - b.SetData( o_b.GetSize(), VECX_ALLOCA( o_b.GetSize() ) ); - lo.SetData( o_lo.GetSize(), VECX_ALLOCA( o_lo.GetSize() ) ); - hi.SetData( o_hi.GetSize(), VECX_ALLOCA( o_hi.GetSize() ) ); - if ( o_boxIndex ) { - boxIndex = (int *)_alloca16( o_x.GetSize() * sizeof( int ) ); - memcpy( boxIndex, o_boxIndex, o_x.GetSize() * sizeof( int ) ); - } else { - boxIndex = NULL; - } - - // we override the const on o_m here but on exit the matrix is unchanged - m.SetData( o_m.GetNumRows(), o_m.GetNumColumns(), const_cast(o_m[0]) ); - f.Zero(); - a.Zero(); - b = o_b; - lo = o_lo; - hi = o_hi; - - // pointers to the rows of m - rowPtrs = (float **) _alloca16( m.GetNumRows() * sizeof( float * ) ); - for ( i = 0; i < m.GetNumRows(); i++ ) { - rowPtrs[i] = m[i]; - } - - // tells if a variable is at the low boundary, high boundary or inbetween - side = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); - - // index to keep track of the permutation - permuted = (int *) _alloca16( m.GetNumRows() * sizeof( int ) ); - for ( i = 0; i < m.GetNumRows(); i++ ) { - permuted[i] = i; - } - - // permute input so all unbounded variables come first - numUnbounded = 0; - for ( i = 0; i < m.GetNumRows(); i++ ) { - if ( lo[i] == -idMath::INFINITY && hi[i] == idMath::INFINITY ) { - if ( numUnbounded != i ) { - Swap( numUnbounded, i ); - } - numUnbounded++; - } - } - - // permute input so all variables using the boxIndex come last - boxStartIndex = m.GetNumRows(); - if ( boxIndex ) { - for ( i = m.GetNumRows() - 1; i >= numUnbounded; i-- ) { - if ( boxIndex[i] >= 0 && ( lo[i] != -idMath::INFINITY || hi[i] != idMath::INFINITY ) ) { - boxStartIndex--; - if ( boxStartIndex != i ) { - Swap( boxStartIndex, i ); - } - } - } - } - - // sub matrix for factorization - clamped.SetData( m.GetNumRows(), m.GetNumColumns(), MATX_ALLOCA( m.GetNumRows() * m.GetNumColumns() ) ); - diagonal.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - solveCache1.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - solveCache2.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - - // all unbounded variables are clamped - numClamped = numUnbounded; - - // if there are unbounded variables - if ( numUnbounded ) { - - // factor and solve for unbounded variables - if ( !FactorClamped() ) { - idLib::common->Printf( "idLCP_Symmetric::Solve: unbounded factorization failed\n" ); - return false; - } - SolveClamped( f, b.ToFloatPtr() ); - - // if there are no bounded variables we are done - if ( numUnbounded == m.GetNumRows() ) { - o_x = f; // the vector is not permuted - return true; - } - } - -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - int numIgnored = 0; -#endif - - // allocate for delta force and delta acceleration - delta_f.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - delta_a.SetData( m.GetNumRows(), VECX_ALLOCA( m.GetNumRows() ) ); - - // solve for bounded variables - failed = NULL; - for ( i = numUnbounded; i < m.GetNumRows(); i++ ) { - - clampedChangeStart = 0; - - // once we hit the box start index we can initialize the low and high boundaries of the variables using the box index - if ( i == boxStartIndex ) { - for ( j = 0; j < boxStartIndex; j++ ) { - o_x[permuted[j]] = f[j]; - } - for ( j = boxStartIndex; j < m.GetNumRows(); j++ ) { - s = o_x[boxIndex[j]]; - if ( lo[j] != -idMath::INFINITY ) { - lo[j] = - idMath::Fabs( lo[j] * s ); - } - if ( hi[j] != idMath::INFINITY ) { - hi[j] = idMath::Fabs( hi[j] * s ); - } - } - } - - // calculate acceleration for current variable - SIMDProcessor->Dot( dot, rowPtrs[i], f.ToFloatPtr(), i ); - a[i] = dot - b[i]; - - // if already at the low boundary - if ( lo[i] >= -LCP_BOUND_EPSILON && a[i] >= -LCP_ACCEL_EPSILON ) { - side[i] = -1; - continue; - } - - // if already at the high boundary - if ( hi[i] <= LCP_BOUND_EPSILON && a[i] <= LCP_ACCEL_EPSILON ) { - side[i] = 1; - continue; - } - - // if inside the clamped region - if ( idMath::Fabs( a[i] ) <= LCP_ACCEL_EPSILON ) { - side[i] = 0; - AddClamped( i, false ); - continue; - } - - // drive the current variable into a valid region - for ( n = 0; n < maxIterations; n++ ) { - - // direction to move - if ( a[i] <= 0.0f ) { - dir = 1.0f; - } else { - dir = -1.0f; - } - - // calculate force delta - CalcForceDelta( i, dir ); - - // calculate acceleration delta: delta_a = m * delta_f; - CalcAccelDelta( i ); - - // maximum step we can take - GetMaxStep( i, dir, maxStep, limit, limitSide ); - - if ( maxStep <= 0.0f ) { -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - // ignore the current variable completely - lo[i] = hi[i] = 0.0f; - f[i] = 0.0f; - side[i] = -1; - numIgnored++; -#else - failed = va( "invalid step size %.4f", maxStep ); -#endif - break; - } - - // change force - ChangeForce( i, maxStep ); - - // change acceleration - ChangeAccel( i, maxStep ); - - // clamp/unclamp the variable that limited this step - side[limit] = limitSide; - switch( limitSide ) { - case 0: { - a[limit] = 0.0f; - AddClamped( limit, ( limit == i ) ); - break; - } - case -1: { - f[limit] = lo[limit]; - if ( limit != i ) { - RemoveClamped( limit ); - } - break; - } - case 1: { - f[limit] = hi[limit]; - if ( limit != i ) { - RemoveClamped( limit ); - } - break; - } - } - - // if the current variable limited the step we can continue with the next variable - if ( limit == i ) { - break; - } - } - - if ( n >= maxIterations ) { - failed = va( "max iterations %d", maxIterations ); - break; - } - - if ( failed ) { - break; - } - } - -#ifdef IGNORE_UNSATISFIABLE_VARIABLES - if ( numIgnored ) { - if ( lcp_showFailures.GetBool() ) { - idLib::common->Printf( "idLCP_Symmetric::Solve: %d of %d bounded variables ignored\n", numIgnored, m.GetNumRows() - numUnbounded ); - } - } -#endif - - // if failed clear remaining forces - if ( failed ) { - if ( lcp_showFailures.GetBool() ) { - idLib::common->Printf( "idLCP_Symmetric::Solve: %s (%d of %d bounded variables ignored)\n", failed, m.GetNumRows() - i, m.GetNumRows() - numUnbounded ); - } - for ( j = i; j < m.GetNumRows(); j++ ) { - f[j] = 0.0f; - } - } - -#if defined(_DEBUG) && 0 - if ( !failed ) { - // test whether or not the solution satisfies the complementarity conditions - for ( i = 0; i < m.GetNumRows(); i++ ) { - a[i] = -b[i]; - for ( j = 0; j < m.GetNumRows(); j++ ) { - a[i] += rowPtrs[i][j] * f[j]; - } - - if ( f[i] == lo[i] ) { - if ( lo[i] != hi[i] && a[i] < -LCP_ACCEL_EPSILON ) { - int bah1 = 1; - } - } else if ( f[i] == hi[i] ) { - if ( lo[i] != hi[i] && a[i] > LCP_ACCEL_EPSILON ) { - int bah2 = 1; - } - } else if ( f[i] < lo[i] || f[i] > hi[i] || idMath::Fabs( a[i] ) > 1.0f ) { - int bah3 = 1; - } - } - } -#endif - - // unpermute result - for ( i = 0; i < f.GetSize(); i++ ) { - o_x[permuted[i]] = f[i]; - } - - // unpermute original matrix - for ( i = 0; i < m.GetNumRows(); i++ ) { - for ( j = 0; j < m.GetNumRows(); j++ ) { - if ( permuted[j] == i ) { - break; - } - } - if ( i != j ) { - m.SwapColumns( i, j ); - idSwap( permuted[i], permuted[j] ); - } - } - - return true; -} - - -//=============================================================== -// -// idLCP -// -//=============================================================== - -/* -============ -idLCP::AllocSquare -============ -*/ -idLCP *idLCP::AllocSquare( void ) { - idLCP *lcp = new idLCP_Square; - lcp->SetMaxIterations( 32 ); - return lcp; -} - -/* -============ -idLCP::AllocSymmetric -============ -*/ -idLCP *idLCP::AllocSymmetric( void ) { - idLCP *lcp = new idLCP_Symmetric; - lcp->SetMaxIterations( 32 ); - return lcp; -} - -/* -============ -idLCP::~idLCP -============ -*/ -idLCP::~idLCP( void ) { -} - -/* -============ -idLCP::SetMaxIterations -============ -*/ -void idLCP::SetMaxIterations( int max ) { - maxIterations = max; -} - -/* -============ -idLCP::GetMaxIterations -============ -*/ -int idLCP::GetMaxIterations( void ) { - return maxIterations; -} diff --git a/idlib/math/lcp.h b/idlib/math/lcp.h deleted file mode 100644 index 01e95433b..000000000 --- a/idlib/math/lcp.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_LCP_H__ -#define __MATH_LCP_H__ - -/* -=============================================================================== - - Box Constrained Mixed Linear Complementarity Problem solver - - A is a matrix of dimension n*n and x, b, lo, hi are vectors of dimension n - - Solve: Ax = b + t, where t is a vector of dimension n, with - complementarity condition: (x[i] - lo[i]) * (x[i] - hi[i]) * t[i] = 0 - such that for each 0 <= i < n one of the following holds: - - 1. lo[i] < x[i] < hi[i], t[i] == 0 - 2. x[i] == lo[i], t[i] >= 0 - 3. x[i] == hi[i], t[i] <= 0 - - Partly bounded or unbounded variables can have lo[i] and/or hi[i] - set to negative/positive idMath::INFITITY respectively. - - If boxIndex != NULL and boxIndex[i] != -1 then - - lo[i] = - fabs( lo[i] * x[boxIndex[i]] ) - hi[i] = fabs( hi[i] * x[boxIndex[i]] ) - boxIndex[boxIndex[i]] must be -1 - - Before calculating any of the bounded x[i] with boxIndex[i] != -1 the - solver calculates all unbounded x[i] and all x[i] with boxIndex[i] == -1. - -=============================================================================== -*/ - -class idLCP { -public: - static idLCP * AllocSquare( void ); // A must be a square matrix - static idLCP * AllocSymmetric( void ); // A must be a symmetric matrix - - virtual ~idLCP( void ); - - virtual bool Solve( const idMatX &A, idVecX &x, const idVecX &b, const idVecX &lo, const idVecX &hi, const int *boxIndex = NULL ) = 0; - virtual void SetMaxIterations( int max ); - virtual int GetMaxIterations( void ); - -protected: - int maxIterations; -}; - -#endif /* !__MATH_LCP_H__ */ diff --git a/idlib/math/math.cpp b/idlib/math/math.cpp deleted file mode 100644 index 818536cfe..000000000 --- a/idlib/math/math.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -const float idMath::PI = 3.14159265358979323846f; -const float idMath::TWO_PI = 2.0f * PI; -const float idMath::HALF_PI = 0.5f * PI; -const float idMath::ONEFOURTH_PI = 0.25f * PI; -const float idMath::E = 2.71828182845904523536f; -const float idMath::SQRT_TWO = 1.41421356237309504880f; -const float idMath::SQRT_THREE = 1.73205080756887729352f; -const float idMath::SQRT_1OVER2 = 0.70710678118654752440f; -const float idMath::SQRT_1OVER3 = 0.57735026918962576450f; -const float idMath::M_DEG2RAD = PI / 180.0f; -const float idMath::M_RAD2DEG = 180.0f / PI; -const float idMath::M_SEC2MS = 1000.0f; -const float idMath::M_MS2SEC = 0.001f; -const float idMath::INFINITY = 1e30f; -const float idMath::FLT_EPSILON = 1.192092896e-07f; - -bool idMath::initialized = false; -dword idMath::iSqrt[SQRT_TABLE_SIZE]; // inverse square root lookup table - -/* -=============== -idMath::Init -=============== -*/ -void idMath::Init( void ) { - union _flint fi, fo; - - for ( int i = 0; i < SQRT_TABLE_SIZE; i++ ) { - fi.i = ((EXP_BIAS-1) << EXP_POS) | (i << LOOKUP_POS); - fo.f = (float)( 1.0 / sqrt( fi.f ) ); - iSqrt[i] = ((dword)(((fo.i + (1<<(SEED_POS-2))) >> SEED_POS) & 0xFF))<= 2 && exponentBits <= 8 ); - assert( mantissaBits >= 2 && mantissaBits <= 23 ); - - int maxBits = ( ( ( 1 << ( exponentBits - 1 ) ) - 1 ) << mantissaBits ) | ( ( 1 << mantissaBits ) - 1 ); - int minBits = ( ( ( 1 << exponentBits ) - 2 ) << mantissaBits ) | 1; - - float max = BitsToFloat( maxBits, exponentBits, mantissaBits ); - float min = BitsToFloat( minBits, exponentBits, mantissaBits ); - - if ( f >= 0.0f ) { - if ( f >= max ) { - return maxBits; - } else if ( f <= min ) { - return minBits; - } - } else { - if ( f <= -max ) { - return ( maxBits | ( 1 << ( exponentBits + mantissaBits ) ) ); - } else if ( f >= -min ) { - return ( minBits | ( 1 << ( exponentBits + mantissaBits ) ) ); - } - } - - exponentBits--; - i = *reinterpret_cast(&f); - sign = ( i >> IEEE_FLT_SIGN_BIT ) & 1; - exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; - mantissa = i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ); - value = sign << ( 1 + exponentBits + mantissaBits ); - value |= ( ( INTSIGNBITSET( exponent ) << exponentBits ) | ( abs( exponent ) & ( ( 1 << exponentBits ) - 1 ) ) ) << mantissaBits; - value |= mantissa >> ( IEEE_FLT_MANTISSA_BITS - mantissaBits ); - return value; -} - -/* -================ -idMath::BitsToFloat -================ -*/ -float idMath::BitsToFloat( int i, int exponentBits, int mantissaBits ) { - static int exponentSign[2] = { 1, -1 }; - int sign, exponent, mantissa, value; - - assert( exponentBits >= 2 && exponentBits <= 8 ); - assert( mantissaBits >= 2 && mantissaBits <= 23 ); - - exponentBits--; - sign = i >> ( 1 + exponentBits + mantissaBits ); - exponent = ( ( i >> mantissaBits ) & ( ( 1 << exponentBits ) - 1 ) ) * exponentSign[( i >> ( exponentBits + mantissaBits ) ) & 1]; - mantissa = ( i & ( ( 1 << mantissaBits ) - 1 ) ) << ( IEEE_FLT_MANTISSA_BITS - mantissaBits ); - value = sign << IEEE_FLT_SIGN_BIT | ( exponent + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS | mantissa; - return *reinterpret_cast(&value); -} diff --git a/idlib/math/math.h b/idlib/math/math.h deleted file mode 100644 index 462ae40ff..000000000 --- a/idlib/math/math.h +++ /dev/null @@ -1,927 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_MATH_H__ -#define __MATH_MATH_H__ - -#include - -#ifdef __linux__ -#include "sys/sys_public.h" -#include -#endif - -#ifdef MACOS_X -// greebo: Include this for ID_INLINE -#include "sys/sys_public.h" - -// for square root estimate instruction -#include -// for FLT_MIN -#include -#endif -/* -=============================================================================== - - Math - -=============================================================================== -*/ - -#ifdef INFINITY -#undef INFINITY -#endif - -#ifdef FLT_EPSILON -#undef FLT_EPSILON -#endif - -#define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD ) -#define RAD2DEG(a) ( (a) * idMath::M_RAD2DEG ) - -#define SEC2MS(t) ( idMath::FtoiFast( (t) * idMath::M_SEC2MS ) ) -#define MS2SEC(t) ( (t) * idMath::M_MS2SEC ) - -#define ANGLE2SHORT(x) ( idMath::FtoiFast( (x) * 65536.0f / 360.0f ) & 65535 ) -#define SHORT2ANGLE(x) ( (x) * ( 360.0f / 65536.0f ) ) - -#define ANGLE2BYTE(x) ( idMath::FtoiFast( (x) * 256.0f / 360.0f ) & 255 ) -#define BYTE2ANGLE(x) ( (x) * ( 360.0f / 256.0f ) ) - -#define FLOATSIGNBITSET(f) ((*(const unsigned long *)&(f)) >> 31) -#define FLOATSIGNBITNOTSET(f) ((~(*(const unsigned long *)&(f))) >> 31) -#define FLOATNOTZERO(f) ((*(const unsigned long *)&(f)) & ~(1<<31) ) -#define INTSIGNBITSET(i) (((const unsigned long)(i)) >> 31) -#define INTSIGNBITNOTSET(i) ((~((const unsigned long)(i))) >> 31) - -#define FLOAT_IS_NAN(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x7f800000) -#define FLOAT_IS_INF(x) (((*(const unsigned long *)&x) & 0x7fffffff) == 0x7f800000) -#define FLOAT_IS_IND(x) ((*(const unsigned long *)&x) == 0xffc00000) -#define FLOAT_IS_DENORMAL(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x00000000 && \ - ((*(const unsigned long *)&x) & 0x007fffff) != 0x00000000 ) - -#define IEEE_FLT_MANTISSA_BITS 23 -#define IEEE_FLT_EXPONENT_BITS 8 -#define IEEE_FLT_EXPONENT_BIAS 127 -#define IEEE_FLT_SIGN_BIT 31 - -#define IEEE_DBL_MANTISSA_BITS 52 -#define IEEE_DBL_EXPONENT_BITS 11 -#define IEEE_DBL_EXPONENT_BIAS 1023 -#define IEEE_DBL_SIGN_BIT 63 - -#define IEEE_DBLE_MANTISSA_BITS 63 -#define IEEE_DBLE_EXPONENT_BITS 15 -#define IEEE_DBLE_EXPONENT_BIAS 0 -#define IEEE_DBLE_SIGN_BIT 79 - -template ID_INLINE T Max( T x, T y ) { return ( x > y ) ? x : y; } -template ID_INLINE T Min( T x, T y ) { return ( x < y ) ? x : y; } -template ID_INLINE int MaxIndex( T x, T y ) { return ( x > y ) ? 0 : 1; } -template ID_INLINE int MinIndex( T x, T y ) { return ( x < y ) ? 0 : 1; } - -template ID_INLINE T Max3( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? x : z ) : ( ( y > z ) ? y : z ); } -template ID_INLINE T Min3( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? x : z ) : ( ( y < z ) ? y : z ); } -template ID_INLINE int Max3Index( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? 0 : 2 ) : ( ( y > z ) ? 1 : 2 ); } -template ID_INLINE int Min3Index( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? 0 : 2 ) : ( ( y < z ) ? 1 : 2 ); } - -template ID_INLINE T Sign( T f ) { return ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ); } -template ID_INLINE T Square( T x ) { return x * x; } -template ID_INLINE T Cube( T x ) { return x * x * x; } - - -class idMath { -public: - - static void Init( void ); - - static float RSqrt( float x ); // reciprocal square root, returns huge number when x == 0.0 - - static float InvSqrt( float x ); // inverse square root with 32 bits precision, returns huge number when x == 0.0 - static float InvSqrt16( float x ); // inverse square root with 16 bits precision, returns huge number when x == 0.0 - static double InvSqrt64( float x ); // inverse square root with 64 bits precision, returns huge number when x == 0.0 - - static float Sqrt( float x ); // square root with 32 bits precision - static float Sqrt16( float x ); // square root with 16 bits precision - static double Sqrt64( float x ); // square root with 64 bits precision - - static float Sin( float a ); // sine with 32 bits precision - static float Sin16( float a ); // sine with 16 bits precision, maximum absolute error is 2.3082e-09 - static double Sin64( float a ); // sine with 64 bits precision - - static float Cos( float a ); // cosine with 32 bits precision - static float Cos16( float a ); // cosine with 16 bits precision, maximum absolute error is 2.3082e-09 - static double Cos64( float a ); // cosine with 64 bits precision - - static void SinCos( float a, float &s, float &c ); // sine and cosine with 32 bits precision - static void SinCos16( float a, float &s, float &c ); // sine and cosine with 16 bits precision - static void SinCos64( float a, double &s, double &c ); // sine and cosine with 64 bits precision - - static float Tan( float a ); // tangent with 32 bits precision - static float Tan16( float a ); // tangent with 16 bits precision, maximum absolute error is 1.8897e-08 - static double Tan64( float a ); // tangent with 64 bits precision - - static float ASin( float a ); // arc sine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN - static float ASin16( float a ); // arc sine with 16 bits precision, maximum absolute error is 6.7626e-05 - static double ASin64( float a ); // arc sine with 64 bits precision - - static float ACos( float a ); // arc cosine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN - static float ACos16( float a ); // arc cosine with 16 bits precision, maximum absolute error is 6.7626e-05 - static double ACos64( float a ); // arc cosine with 64 bits precision - - static float ATan( float a ); // arc tangent with 32 bits precision - static float ATan16( float a ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 - static double ATan64( float a ); // arc tangent with 64 bits precision - - static float ATan( float y, float x ); // arc tangent with 32 bits precision - static float ATan16( float y, float x ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 - static double ATan64( float y, float x ); // arc tangent with 64 bits precision - - static float Pow( float x, float y ); // x raised to the power y with 32 bits precision - static float Pow16( float x, float y ); // x raised to the power y with 16 bits precision - static double Pow64( float x, float y ); // x raised to the power y with 64 bits precision - - static float Exp( float f ); // e raised to the power f with 32 bits precision - static float Exp16( float f ); // e raised to the power f with 16 bits precision - static double Exp64( float f ); // e raised to the power f with 64 bits precision - - static float Log( float f ); // natural logarithm with 32 bits precision - static float Log16( float f ); // natural logarithm with 16 bits precision - static double Log64( float f ); // natural logarithm with 64 bits precision - - static int IPow( int x, int y ); // integral x raised to the power y - static int ILog2( float f ); // integral base-2 logarithm of the floating point value - static int ILog2( int i ); // integral base-2 logarithm of the integer value - - static int BitsForFloat( float f ); // minimum number of bits required to represent ceil( f ) - static int BitsForInteger( int i ); // minimum number of bits required to represent i - static int MaskForFloatSign( float f );// returns 0x00000000 if x >= 0.0f and returns 0xFFFFFFFF if x <= -0.0f - static int MaskForIntegerSign( int i );// returns 0x00000000 if x >= 0 and returns 0xFFFFFFFF if x < 0 - static int FloorPowerOfTwo( int x ); // round x down to the nearest power of 2 - static int CeilPowerOfTwo( int x ); // round x up to the nearest power of 2 - static bool IsPowerOfTwo( int x ); // returns true if x is a power of 2 - static int BitCount( int x ); // returns the number of 1 bits in x - static int BitReverse( int x ); // returns the bit reverse of x - - static int Abs( int x ); // returns the absolute value of the integer value (for reference only) - static float Fabs( float f ); // returns the absolute value of the floating point value - static float Floor( float f ); // returns the largest integer that is less than or equal to the given value - static float Ceil( float f ); // returns the smallest integer that is greater than or equal to the given value - static float Rint( float f ); // returns the nearest integer - static int Ftoi( float f ); // float to int conversion - static int FtoiFast( float f ); // fast float to int conversion but uses current FPU round mode (default round nearest) - static unsigned long Ftol( float f ); // float to long conversion - static unsigned long FtolFast( float ); // fast float to long conversion but uses current FPU round mode (default round nearest) - - static signed char ClampChar( int i ); - static signed short ClampShort( int i ); - static int ClampInt( int min, int max, int value ); - static float ClampFloat( float min, float max, float value ); - - static float AngleNormalize360( float angle ); - static float AngleNormalize180( float angle ); - static float AngleDelta( float angle1, float angle2 ); - - static int FloatToBits( float f, int exponentBits, int mantissaBits ); - static float BitsToFloat( int i, int exponentBits, int mantissaBits ); - - static int FloatHash( const float *array, const int numFloats ); - - static const float PI; // pi - static const float TWO_PI; // pi * 2 - static const float HALF_PI; // pi / 2 - static const float ONEFOURTH_PI; // pi / 4 - static const float E; // e - static const float SQRT_TWO; // sqrt( 2 ) - static const float SQRT_THREE; // sqrt( 3 ) - static const float SQRT_1OVER2; // sqrt( 1 / 2 ) - static const float SQRT_1OVER3; // sqrt( 1 / 3 ) - static const float M_DEG2RAD; // degrees to radians multiplier - static const float M_RAD2DEG; // radians to degrees multiplier - static const float M_SEC2MS; // seconds to milliseconds multiplier - static const float M_MS2SEC; // milliseconds to seconds multiplier - static const float INFINITY; // huge number which should be larger than any valid number used - static const float FLT_EPSILON; // smallest positive number such that 1.0+FLT_EPSILON != 1.0 - -private: - enum { - LOOKUP_BITS = 8, - EXP_POS = 23, - EXP_BIAS = 127, - LOOKUP_POS = (EXP_POS-LOOKUP_BITS), - SEED_POS = (EXP_POS-8), - SQRT_TABLE_SIZE = (2<( &x ); - i = 0x5f3759df - ( i >> 1 ); - r = *reinterpret_cast( &i ); - r = r * ( 1.5f - r * r * y ); - return r; -} - -ID_INLINE float idMath::InvSqrt16( float x ) { - - dword a = ((union _flint*)(&x))->i; - union _flint seed; - - assert( initialized ); - - double y = x * 0.5f; - seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; - double r = seed.f; - r = r * ( 1.5f - r * r * y ); - return (float) r; -} - -ID_INLINE float idMath::InvSqrt( float x ) { - - dword a = ((union _flint*)(&x))->i; - union _flint seed; - - assert( initialized ); - - double y = x * 0.5f; - seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; - double r = seed.f; - r = r * ( 1.5f - r * r * y ); - r = r * ( 1.5f - r * r * y ); - return (float) r; -} - -ID_INLINE double idMath::InvSqrt64( float x ) { - dword a = ((union _flint*)(&x))->i; - union _flint seed; - - assert( initialized ); - - double y = x * 0.5f; - seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK]; - double r = seed.f; - r = r * ( 1.5f - r * r * y ); - r = r * ( 1.5f - r * r * y ); - r = r * ( 1.5f - r * r * y ); - return r; -} - -ID_INLINE float idMath::Sqrt16( float x ) { - return x * InvSqrt16( x ); -} - -ID_INLINE float idMath::Sqrt( float x ) { - return x * InvSqrt( x ); -} - -ID_INLINE double idMath::Sqrt64( float x ) { - return x * InvSqrt64( x ); -} - -ID_INLINE float idMath::Sin( float a ) { - return sinf( a ); -} - -ID_INLINE float idMath::Sin16( float a ) { - float s; - - if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { - a -= floorf( a / TWO_PI ) * TWO_PI; - } -#if 1 - if ( a < PI ) { - if ( a > HALF_PI ) { - a = PI - a; - } - } else { - if ( a > PI + HALF_PI ) { - a = a - TWO_PI; - } else { - a = PI - a; - } - } -#else - a = PI - a; - if ( fabs( a ) >= HALF_PI ) { - a = ( ( a < 0.0f ) ? -PI : PI ) - a; - } -#endif - s = a * a; - return a * ( ( ( ( ( -2.39e-08f * s + 2.7526e-06f ) * s - 1.98409e-04f ) * s + 8.3333315e-03f ) * s - 1.666666664e-01f ) * s + 1.0f ); -} - -ID_INLINE double idMath::Sin64( float a ) { - return sin( a ); -} - -ID_INLINE float idMath::Cos( float a ) { - return cosf( a ); -} - -ID_INLINE float idMath::Cos16( float a ) { - float s, d; - - if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { - a -= floorf( a / TWO_PI ) * TWO_PI; - } -#if 1 - if ( a < PI ) { - if ( a > HALF_PI ) { - a = PI - a; - d = -1.0f; - } else { - d = 1.0f; - } - } else { - if ( a > PI + HALF_PI ) { - a = a - TWO_PI; - d = 1.0f; - } else { - a = PI - a; - d = -1.0f; - } - } -#else - a = PI - a; - if ( fabs( a ) >= HALF_PI ) { - a = ( ( a < 0.0f ) ? -PI : PI ) - a; - d = 1.0f; - } else { - d = -1.0f; - } -#endif - s = a * a; - return d * ( ( ( ( ( -2.605e-07f * s + 2.47609e-05f ) * s - 1.3888397e-03f ) * s + 4.16666418e-02f ) * s - 4.999999963e-01f ) * s + 1.0f ); -} - -ID_INLINE double idMath::Cos64( float a ) { - return cos( a ); -} - -ID_INLINE void idMath::SinCos( float a, float &s, float &c ) { -#ifdef _WIN32 - _asm { - fld a - fsincos - mov ecx, c - mov edx, s - fstp dword ptr [ecx] - fstp dword ptr [edx] - } -#else - s = sinf( a ); - c = cosf( a ); -#endif -} - -ID_INLINE void idMath::SinCos16( float a, float &s, float &c ) { - float t, d; - - if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { - a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; - } -#if 1 - if ( a < PI ) { - if ( a > HALF_PI ) { - a = PI - a; - d = -1.0f; - } else { - d = 1.0f; - } - } else { - if ( a > PI + HALF_PI ) { - a = a - TWO_PI; - d = 1.0f; - } else { - a = PI - a; - d = -1.0f; - } - } -#else - a = PI - a; - if ( fabs( a ) >= HALF_PI ) { - a = ( ( a < 0.0f ) ? -PI : PI ) - a; - d = 1.0f; - } else { - d = -1.0f; - } -#endif - t = a * a; - s = a * ( ( ( ( ( -2.39e-08f * t + 2.7526e-06f ) * t - 1.98409e-04f ) * t + 8.3333315e-03f ) * t - 1.666666664e-01f ) * t + 1.0f ); - c = d * ( ( ( ( ( -2.605e-07f * t + 2.47609e-05f ) * t - 1.3888397e-03f ) * t + 4.16666418e-02f ) * t - 4.999999963e-01f ) * t + 1.0f ); -} - -ID_INLINE void idMath::SinCos64( float a, double &s, double &c ) { -#ifdef _WIN32 - _asm { - fld a - fsincos - mov ecx, c - mov edx, s - fstp qword ptr [ecx] - fstp qword ptr [edx] - } -#else - s = sin( a ); - c = cos( a ); -#endif -} - -ID_INLINE float idMath::Tan( float a ) { - return tanf( a ); -} - -ID_INLINE float idMath::Tan16( float a ) { - float s; - bool reciprocal; - - if ( ( a < 0.0f ) || ( a >= PI ) ) { - a -= floorf( a / PI ) * PI; - } -#if 1 - if ( a < HALF_PI ) { - if ( a > ONEFOURTH_PI ) { - a = HALF_PI - a; - reciprocal = true; - } else { - reciprocal = false; - } - } else { - if ( a > HALF_PI + ONEFOURTH_PI ) { - a = a - PI; - reciprocal = false; - } else { - a = HALF_PI - a; - reciprocal = true; - } - } -#else - a = HALF_PI - a; - if ( fabs( a ) >= ONEFOURTH_PI ) { - a = ( ( a < 0.0f ) ? -HALF_PI : HALF_PI ) - a; - reciprocal = false; - } else { - reciprocal = true; - } -#endif - s = a * a; - s = a * ( ( ( ( ( ( 9.5168091e-03f * s + 2.900525e-03f ) * s + 2.45650893e-02f ) * s + 5.33740603e-02f ) * s + 1.333923995e-01f ) * s + 3.333314036e-01f ) * s + 1.0f ); - if ( reciprocal ) { - return 1.0f / s; - } else { - return s; - } -} - -ID_INLINE double idMath::Tan64( float a ) { - return tan( a ); -} - -ID_INLINE float idMath::ASin( float a ) { - if ( a <= -1.0f ) { - return -HALF_PI; - } - if ( a >= 1.0f ) { - return HALF_PI; - } - return asinf( a ); -} - -ID_INLINE float idMath::ASin16( float a ) { - if ( FLOATSIGNBITSET( a ) ) { - if ( a <= -1.0f ) { - return -HALF_PI; - } - a = fabs( a ); - return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ) - HALF_PI; - } else { - if ( a >= 1.0f ) { - return HALF_PI; - } - return HALF_PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); - } -} - -ID_INLINE double idMath::ASin64( float a ) { - if ( a <= -1.0f ) { - return -HALF_PI; - } - if ( a >= 1.0f ) { - return HALF_PI; - } - return asin( a ); -} - -ID_INLINE float idMath::ACos( float a ) { - if ( a <= -1.0f ) { - return PI; - } - if ( a >= 1.0f ) { - return 0.0f; - } - return acosf( a ); -} - -ID_INLINE float idMath::ACos16( float a ) { - if ( FLOATSIGNBITSET( a ) ) { - if ( a <= -1.0f ) { - return PI; - } - a = fabs( a ); - return PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); - } else { - if ( a >= 1.0f ) { - return 0.0f; - } - return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ); - } -} - -ID_INLINE double idMath::ACos64( float a ) { - if ( a <= -1.0f ) { - return PI; - } - if ( a >= 1.0f ) { - return 0.0f; - } - return acos( a ); -} - -ID_INLINE float idMath::ATan( float a ) { - return atanf( a ); -} - -ID_INLINE float idMath::ATan16( float a ) { - float s; - - if ( fabs( a ) > 1.0f ) { - a = 1.0f / a; - s = a * a; - s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) - * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; - if ( FLOATSIGNBITSET( a ) ) { - return s - HALF_PI; - } else { - return s + HALF_PI; - } - } else { - s = a * a; - return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) - * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; - } -} - -ID_INLINE double idMath::ATan64( float a ) { - return atan( a ); -} - -ID_INLINE float idMath::ATan( float y, float x ) { - return atan2f( y, x ); -} - -ID_INLINE float idMath::ATan16( float y, float x ) { - float a, s; - - if ( fabs( y ) > fabs( x ) ) { - a = x / y; - s = a * a; - s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) - * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; - if ( FLOATSIGNBITSET( a ) ) { - return s - HALF_PI; - } else { - return s + HALF_PI; - } - } else { - a = y / x; - s = a * a; - return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) - * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; - } -} - -ID_INLINE double idMath::ATan64( float y, float x ) { - return atan2( y, x ); -} - -ID_INLINE float idMath::Pow( float x, float y ) { - return powf( x, y ); -} - -ID_INLINE float idMath::Pow16( float x, float y ) { - return Exp16( y * Log16( x ) ); -} - -ID_INLINE double idMath::Pow64( float x, float y ) { - return pow( x, y ); -} - -ID_INLINE float idMath::Exp( float f ) { - return expf( f ); -} - -ID_INLINE float idMath::Exp16( float f ) { - int i, s, e, m, exponent; - float x, x2, y, p, q; - - x = f * 1.44269504088896340f; // multiply with ( 1 / log( 2 ) ) -#if 1 - i = *reinterpret_cast(&x); - s = ( i >> IEEE_FLT_SIGN_BIT ); - e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; - m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); - i = ( ( m >> ( IEEE_FLT_MANTISSA_BITS - e ) ) & ~( e >> 31 ) ) ^ s; -#else - i = (int) x; - if ( x < 0.0f ) { - i--; - } -#endif - exponent = ( i + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS; - y = *reinterpret_cast(&exponent); - x -= (float) i; - if ( x >= 0.5f ) { - x -= 0.5f; - y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) - } - x2 = x * x; - p = x * ( 7.2152891511493f + x2 * 0.0576900723731f ); - q = 20.8189237930062f + x2; - x = y * ( q + p ) / ( q - p ); - return x; -} - -ID_INLINE double idMath::Exp64( float f ) { - return exp( f ); -} - -ID_INLINE float idMath::Log( float f ) { - return logf( f ); -} - -ID_INLINE float idMath::Log16( float f ) { - int i, exponent; - float y, y2; - - i = *reinterpret_cast(&f); - exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; - i -= ( exponent + 1 ) << IEEE_FLT_MANTISSA_BITS; // get value in the range [.5, 1> - y = *reinterpret_cast(&i); - y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) - y = ( y - 1.0f ) / ( y + 1.0f ); - y2 = y * y; - y = y * ( 2.000000000046727f + y2 * ( 0.666666635059382f + y2 * ( 0.4000059794795f + y2 * ( 0.28525381498f + y2 * 0.2376245609f ) ) ) ); - y += 0.693147180559945f * ( (float)exponent + 0.5f ); - return y; -} - -ID_INLINE double idMath::Log64( float f ) { - return log( f ); -} - -ID_INLINE int idMath::IPow( int x, int y ) { - int r; for( r = x; y > 1; y-- ) { r *= x; } return r; -} - -ID_INLINE int idMath::ILog2( float f ) { - return ( ( (*reinterpret_cast(&f)) >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; -} - -ID_INLINE int idMath::ILog2( int i ) { - return ILog2( (float)i ); -} - -ID_INLINE int idMath::BitsForFloat( float f ) { - return ILog2( f ) + 1; -} - -ID_INLINE int idMath::BitsForInteger( int i ) { - return ILog2( (float)i ) + 1; -} - -ID_INLINE int idMath::MaskForFloatSign( float f ) { - return ( (*reinterpret_cast(&f)) >> 31 ); -} - -ID_INLINE int idMath::MaskForIntegerSign( int i ) { - return ( i >> 31 ); -} - -ID_INLINE int idMath::FloorPowerOfTwo( int x ) { - return CeilPowerOfTwo( x ) >> 1; -} - -ID_INLINE int idMath::CeilPowerOfTwo( int x ) { - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x++; - return x; -} - -ID_INLINE bool idMath::IsPowerOfTwo( int x ) { - return ( x & ( x - 1 ) ) == 0 && x > 0; -} - -ID_INLINE int idMath::BitCount( int x ) { - x -= ( ( x >> 1 ) & 0x55555555 ); - x = ( ( ( x >> 2 ) & 0x33333333 ) + ( x & 0x33333333 ) ); - x = ( ( ( x >> 4 ) + x ) & 0x0f0f0f0f ); - x += ( x >> 8 ); - return ( ( x + ( x >> 16 ) ) & 0x0000003f ); -} - -ID_INLINE int idMath::BitReverse( int x ) { - x = ( ( ( x >> 1 ) & 0x55555555 ) | ( ( x & 0x55555555 ) << 1 ) ); - x = ( ( ( x >> 2 ) & 0x33333333 ) | ( ( x & 0x33333333 ) << 2 ) ); - x = ( ( ( x >> 4 ) & 0x0f0f0f0f ) | ( ( x & 0x0f0f0f0f ) << 4 ) ); - x = ( ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x & 0x00ff00ff ) << 8 ) ); - return ( ( x >> 16 ) | ( x << 16 ) ); -} - -ID_INLINE int idMath::Abs( int x ) { - int y = x >> 31; - return ( ( x ^ y ) - y ); -} - -ID_INLINE float idMath::Fabs( float f ) { - int tmp = *reinterpret_cast( &f ); - tmp &= 0x7FFFFFFF; - return *reinterpret_cast( &tmp ); -} - -ID_INLINE float idMath::Floor( float f ) { - return floorf( f ); -} - -ID_INLINE float idMath::Ceil( float f ) { - return ceilf( f ); -} - -ID_INLINE float idMath::Rint( float f ) { - return floorf( f + 0.5f ); -} - -ID_INLINE int idMath::Ftoi( float f ) { - return (int) f; -} - -ID_INLINE int idMath::FtoiFast( float f ) { -#ifdef _WIN32 - int i; - __asm fld f - __asm fistp i // use default rouding mode (round nearest) - return i; -#elif 0 // round chop (C/C++ standard) - int i, s, e, m, shift; - i = *reinterpret_cast(&f); - s = i >> IEEE_FLT_SIGN_BIT; - e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; - m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); - shift = e - IEEE_FLT_MANTISSA_BITS; - return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; -//#elif defined( __i386__ ) -#elif 0 - int i = 0; - __asm__ __volatile__ ( - "fld %1\n" \ - "fistp %0\n" \ - : "=m" (i) \ - : "m" (f) ); - return i; -#else - return (int) f; -#endif -} - -ID_INLINE unsigned long idMath::Ftol( float f ) { - return (unsigned long) f; -} - -ID_INLINE unsigned long idMath::FtolFast( float f ) { -#ifdef _WIN32 - // FIXME: this overflows on 31bits still .. same as FtoiFast - unsigned long i; - __asm fld f - __asm fistp i // use default rouding mode (round nearest) - return i; -#elif 0 // round chop (C/C++ standard) - int i, s, e, m, shift; - i = *reinterpret_cast(&f); - s = i >> IEEE_FLT_SIGN_BIT; - e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; - m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); - shift = e - IEEE_FLT_MANTISSA_BITS; - return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; -//#elif defined( __i386__ ) -#elif 0 - // for some reason, on gcc I need to make sure i == 0 before performing a fistp - int i = 0; - __asm__ __volatile__ ( - "fld %1\n" \ - "fistp %0\n" \ - : "=m" (i) \ - : "m" (f) ); - return i; -#else - return (unsigned long) f; -#endif -} - -ID_INLINE signed char idMath::ClampChar( int i ) { - if ( i < -128 ) { - return -128; - } - if ( i > 127 ) { - return 127; - } - return i; -} - -ID_INLINE signed short idMath::ClampShort( int i ) { - if ( i < -32768 ) { - return -32768; - } - if ( i > 32767 ) { - return 32767; - } - return i; -} - -ID_INLINE int idMath::ClampInt( int min, int max, int value ) { - if ( value < min ) { - return min; - } - if ( value > max ) { - return max; - } - return value; -} - -ID_INLINE float idMath::ClampFloat( float min, float max, float value ) { - if ( value < min ) { - return min; - } - if ( value > max ) { - return max; - } - return value; -} - -ID_INLINE float idMath::AngleNormalize360( float angle ) { - if ( ( angle >= 360.0f ) || ( angle < 0.0f ) ) { - angle -= floor( angle / 360.0f ) * 360.0f; - } - return angle; -} - -ID_INLINE float idMath::AngleNormalize180( float angle ) { - angle = AngleNormalize360( angle ); - if ( angle > 180.0f ) { - angle -= 360.0f; - } - return angle; -} - -ID_INLINE float idMath::AngleDelta( float angle1, float angle2 ) { - return AngleNormalize180( angle1 - angle2 ); -} - -ID_INLINE int idMath::FloatHash( const float *array, const int numFloats ) { - int i, hash = 0; - const int *ptr; - - ptr = reinterpret_cast( array ); - for ( i = 0; i < numFloats; i++ ) { - hash ^= ptr[i]; - } - return hash; -} - -#endif /* !__MATH_MATH_H__ */ diff --git a/idlib/math/matrix.cpp b/idlib/math/matrix.cpp deleted file mode 100644 index 9a9672355..000000000 --- a/idlib/math/matrix.cpp +++ /dev/null @@ -1,8093 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); -#pragma warning( push ) -#pragma warning( disable: 4127 ) -//=============================================================== -// -// idMat2 -// -//=============================================================== - -idMat2 mat2_zero( idVec2( 0, 0 ), idVec2( 0, 0 ) ); -idMat2 mat2_identity( idVec2( 1, 0 ), idVec2( 0, 1 ) ); - -/* -============ -idMat2::InverseSelf -============ -*/ -bool idMat2::InverseSelf( void ) { - // 2+4 = 6 multiplications - // 1 division - double det, invDet, a; - - det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - a = mat[0][0]; - mat[0][0] = mat[1][1] * invDet; - mat[0][1] = - mat[0][1] * invDet; - mat[1][0] = - mat[1][0] * invDet; - mat[1][1] = a * invDet; - - return true; -} - -/* -============ -idMat2::InverseFastSelf -============ -*/ -bool idMat2::InverseFastSelf( void ) { -#if 1 - // 2+4 = 6 multiplications - // 1 division - double det, invDet, a; - - det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - a = mat[0][0]; - mat[0][0] = mat[1][1] * invDet; - mat[0][1] = - mat[0][1] * invDet; - mat[1][0] = - mat[1][0] * invDet; - mat[1][1] = a * invDet; - - return true; -#else - // 2*4 = 8 multiplications - // 2 division - float *mat = reinterpret_cast(this); - double d, di; - float s; - - di = mat[0]; - s = di; - mat[0*2+0] = d = 1.0f / di; - mat[0*2+1] *= d; - d = -d; - mat[1*2+0] *= d; - d = mat[1*2+0] * di; - mat[1*2+1] += mat[0*2+1] * d; - di = mat[1*2+1]; - s *= di; - mat[1*2+1] = d = 1.0f / di; - mat[1*2+0] *= d; - d = -d; - mat[0*2+1] *= d; - d = mat[0*2+1] * di; - mat[0*2+0] += mat[1*2+0] * d; - - return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); -#endif -} - -/* -============= -idMat2::ToString -============= -*/ -const char *idMat2::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idMat3 -// -//=============================================================== - -idMat3 mat3_zero( idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ) ); -idMat3 mat3_identity( idVec3( 1, 0, 0 ), idVec3( 0, 1, 0 ), idVec3( 0, 0, 1 ) ); - -/* -============ -idMat3::ToAngles -============ -*/ -idAngles idMat3::ToAngles( void ) const { - idAngles angles; - double theta; - double cp; - float sp; - - sp = mat[ 0 ][ 2 ]; - - // cap off our sin value so that we don't get any NANs - if ( sp > 1.0f ) { - sp = 1.0f; - } else if ( sp < -1.0f ) { - sp = -1.0f; - } - - theta = -asin( sp ); - cp = cos( theta ); - - if ( cp > 8192.0f * idMath::FLT_EPSILON ) { - angles.pitch = RAD2DEG( theta ); - angles.yaw = RAD2DEG( atan2( mat[ 0 ][ 1 ], mat[ 0 ][ 0 ] ) ); - angles.roll = RAD2DEG( atan2( mat[ 1 ][ 2 ], mat[ 2 ][ 2 ] ) ); - } else { - angles.pitch = RAD2DEG( theta ); - angles.yaw = RAD2DEG( -atan2( mat[ 1 ][ 0 ], mat[ 1 ][ 1 ] ) ); - angles.roll = 0; - } - return angles; -} - -/* -============ -idMat3::ToQuat -============ -*/ -idQuat idMat3::ToQuat( void ) const { - idQuat q; - float trace; - float s; - float t; - int i; - int j; - int k; - - static int next[ 3 ] = { 1, 2, 0 }; - - trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ]; - - if ( trace > 0.0f ) { - - t = trace + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - q[3] = s * t; - q[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s; - q[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s; - q[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s; - - } else { - - i = 0; - if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) { - i = 1; - } - if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) { - i = 2; - } - j = next[ i ]; - k = next[ j ]; - - t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - q[i] = s * t; - q[3] = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s; - q[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s; - q[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s; - } - return q; -} - -/* -============ -idMat3::ToCQuat -============ -*/ -idCQuat idMat3::ToCQuat( void ) const { - idQuat q = ToQuat(); - if ( q.w < 0.0f ) { - return idCQuat( -q.x, -q.y, -q.z ); - } - return idCQuat( q.x, q.y, q.z ); -} - -/* -============ -idMat3::ToRotation -============ -*/ -idRotation idMat3::ToRotation( void ) const { - idRotation r; - float trace; - float s; - float t; - int i; - int j; - int k; - static int next[ 3 ] = { 1, 2, 0 }; - - trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ]; - if ( trace > 0.0f ) { - - t = trace + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - r.angle = s * t; - r.vec[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s; - r.vec[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s; - r.vec[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s; - - } else { - - i = 0; - if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) { - i = 1; - } - if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) { - i = 2; - } - j = next[ i ]; - k = next[ j ]; - - t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f; - s = idMath::InvSqrt( t ) * 0.5f; - - r.vec[i] = s * t; - r.angle = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s; - r.vec[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s; - r.vec[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s; - } - r.angle = idMath::ACos( r.angle ); - if ( idMath::Fabs( r.angle ) < 1e-10f ) { - r.vec.Set( 0.0f, 0.0f, 1.0f ); - r.angle = 0.0f; - } else { - //vec *= (1.0f / sin( angle )); - r.vec.Normalize(); - r.vec.FixDegenerateNormal(); - r.angle *= 2.0f * idMath::M_RAD2DEG; - } - - r.origin.Zero(); - r.axis = *this; - r.axisValid = true; - return r; -} - -/* -================= -idMat3::ToAngularVelocity -================= -*/ -idVec3 idMat3::ToAngularVelocity( void ) const { - idRotation rotation = ToRotation(); - return rotation.GetVec() * DEG2RAD( rotation.GetAngle() ); -} - -/* -============ -idMat3::Determinant -============ -*/ -float idMat3::Determinant( void ) const { - - float det2_12_01 = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; - float det2_12_02 = mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]; - float det2_12_12 = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; - - return mat[0][0] * det2_12_12 - mat[0][1] * det2_12_02 + mat[0][2] * det2_12_01; -} - -/* -============ -idMat3::InverseSelf -============ -*/ -bool idMat3::InverseSelf( void ) { - // 18+3+9 = 30 multiplications - // 1 division - idMat3 inverse; - double det, invDet; - - inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; - inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; - inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; - - det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; - inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; - inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; - inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1]; - inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - - mat[0][0] = inverse[0][0] * invDet; - mat[0][1] = inverse[0][1] * invDet; - mat[0][2] = inverse[0][2] * invDet; - - mat[1][0] = inverse[1][0] * invDet; - mat[1][1] = inverse[1][1] * invDet; - mat[1][2] = inverse[1][2] * invDet; - - mat[2][0] = inverse[2][0] * invDet; - mat[2][1] = inverse[2][1] * invDet; - mat[2][2] = inverse[2][2] * invDet; - - return true; -} - -/* -============ -idMat3::InverseFastSelf -============ -*/ -bool idMat3::InverseFastSelf( void ) { -#if 1 - // 18+3+9 = 30 multiplications - // 1 division - idMat3 inverse; - double det, invDet; - - inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; - inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]; - inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; - - det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2]; - inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]; - inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]; - inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1]; - inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - - mat[0][0] = inverse[0][0] * invDet; - mat[0][1] = inverse[0][1] * invDet; - mat[0][2] = inverse[0][2] * invDet; - - mat[1][0] = inverse[1][0] * invDet; - mat[1][1] = inverse[1][1] * invDet; - mat[1][2] = inverse[1][2] * invDet; - - mat[2][0] = inverse[2][0] * invDet; - mat[2][1] = inverse[2][1] * invDet; - mat[2][2] = inverse[2][2] * invDet; - - return true; -#elif 0 - // 3*10 = 30 multiplications - // 3 divisions - float *mat = reinterpret_cast(this); - float s; - double d, di; - - di = mat[0]; - s = di; - mat[0] = d = 1.0f / di; - mat[1] *= d; - mat[2] *= d; - d = -d; - mat[3] *= d; - mat[6] *= d; - d = mat[3] * di; - mat[4] += mat[1] * d; - mat[5] += mat[2] * d; - d = mat[6] * di; - mat[7] += mat[1] * d; - mat[8] += mat[2] * d; - di = mat[4]; - s *= di; - mat[4] = d = 1.0f / di; - mat[3] *= d; - mat[5] *= d; - d = -d; - mat[1] *= d; - mat[7] *= d; - d = mat[1] * di; - mat[0] += mat[3] * d; - mat[2] += mat[5] * d; - d = mat[7] * di; - mat[6] += mat[3] * d; - mat[8] += mat[5] * d; - di = mat[8]; - s *= di; - mat[8] = d = 1.0f / di; - mat[6] *= d; - mat[7] *= d; - d = -d; - mat[2] *= d; - mat[5] *= d; - d = mat[2] * di; - mat[0] += mat[6] * d; - mat[1] += mat[7] * d; - d = mat[5] * di; - mat[3] += mat[6] * d; - mat[4] += mat[7] * d; - - return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); -#else - // 4*2+4*4 = 24 multiplications - // 2*1 = 2 divisions - idMat2 r0; - float r1[2], r2[2], r3; - float det, invDet; - float *mat = reinterpret_cast(this); - - // r0 = m0.Inverse(); // 2x2 - det = mat[0*3+0] * mat[1*3+1] - mat[0*3+1] * mat[1*3+0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - r0[0][0] = mat[1*3+1] * invDet; - r0[0][1] = - mat[0*3+1] * invDet; - r0[1][0] = - mat[1*3+0] * invDet; - r0[1][1] = mat[0*3+0] * invDet; - - // r1 = r0 * m1; // 2x1 = 2x2 * 2x1 - r1[0] = r0[0][0] * mat[0*3+2] + r0[0][1] * mat[1*3+2]; - r1[1] = r0[1][0] * mat[0*3+2] + r0[1][1] * mat[1*3+2]; - - // r2 = m2 * r1; // 1x1 = 1x2 * 2x1 - r2[0] = mat[2*3+0] * r1[0] + mat[2*3+1] * r1[1]; - - // r3 = r2 - m3; // 1x1 = 1x1 - 1x1 - r3 = r2[0] - mat[2*3+2]; - - // r3.InverseSelf(); - if ( idMath::Fabs( r3 ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - r3 = 1.0f / r3; - - // r2 = m2 * r0; // 1x2 = 1x2 * 2x2 - r2[0] = mat[2*3+0] * r0[0][0] + mat[2*3+1] * r0[1][0]; - r2[1] = mat[2*3+0] * r0[0][1] + mat[2*3+1] * r0[1][1]; - - // m2 = r3 * r2; // 1x2 = 1x1 * 1x2 - mat[2*3+0] = r3 * r2[0]; - mat[2*3+1] = r3 * r2[1]; - - // m0 = r0 - r1 * m2; // 2x2 - 2x1 * 1x2 - mat[0*3+0] = r0[0][0] - r1[0] * mat[2*3+0]; - mat[0*3+1] = r0[0][1] - r1[0] * mat[2*3+1]; - mat[1*3+0] = r0[1][0] - r1[1] * mat[2*3+0]; - mat[1*3+1] = r0[1][1] - r1[1] * mat[2*3+1]; - - // m1 = r1 * r3; // 2x1 = 2x1 * 1x1 - mat[0*3+2] = r1[0] * r3; - mat[1*3+2] = r1[1] * r3; - - // m3 = -r3; - mat[2*3+2] = -r3; - - return true; -#endif -} - -/* -============ -idMat3::InertiaTranslate -============ -*/ -idMat3 idMat3::InertiaTranslate( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) const { - idMat3 m; - idVec3 newCenter; - - newCenter = centerOfMass + translation; - - m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] ) - - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) ); - m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] ) - - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) ); - m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] ) - - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) ); - - m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] ); - m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] ); - m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] ); - - return (*this) + m; -} - -/* -============ -idMat3::InertiaTranslateSelf -============ -*/ -idMat3 &idMat3::InertiaTranslateSelf( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) { - idMat3 m; - idVec3 newCenter; - - newCenter = centerOfMass + translation; - - m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] ) - - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) ); - m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] ) - - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) ); - m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] ) - - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) ); - - m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] ); - m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] ); - m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] ); - - (*this) += m; - - return (*this); -} - -/* -============ -idMat3::InertiaRotate -============ -*/ -idMat3 idMat3::InertiaRotate( const idMat3 &rotation ) const { - // NOTE: the rotation matrix is stored column-major - return rotation.Transpose() * (*this) * rotation; -} - -/* -============ -idMat3::InertiaRotateSelf -============ -*/ -idMat3 &idMat3::InertiaRotateSelf( const idMat3 &rotation ) { - // NOTE: the rotation matrix is stored column-major - *this = rotation.Transpose() * (*this) * rotation; - return *this; -} - -/* -============= -idMat3::ToString -============= -*/ -const char *idMat3::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idMat4 -// -//=============================================================== - -idMat4 mat4_zero( idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ) ); -idMat4 mat4_identity( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ), idVec4( 0, 0, 1, 0 ), idVec4( 0, 0, 0, 1 ) ); - -/* -============ -idMat4::Transpose -============ -*/ -idMat4 idMat4::Transpose( void ) const { - idMat4 transpose; - int i, j; - - for( i = 0; i < 4; i++ ) { - for( j = 0; j < 4; j++ ) { - transpose[ i ][ j ] = mat[ j ][ i ]; - } - } - return transpose; -} - -/* -============ -idMat4::TransposeSelf -============ -*/ -idMat4 &idMat4::TransposeSelf( void ) { - float temp; - int i, j; - - for( i = 0; i < 4; i++ ) { - for( j = i + 1; j < 4; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } - return *this; -} - -/* -============ -idMat4::Determinant -============ -*/ -float idMat4::Determinant( void ) const { - - // 2x2 sub-determinants - float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; - float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; - float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; - float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; - - // 3x3 sub-determinants - float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; - float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; - float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; - float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; - - return ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); -} - -/* -============ -idMat4::InverseSelf -============ -*/ -bool idMat4::InverseSelf( void ) { - // 84+4+16 = 104 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 4x4 determinant - float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; - float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; - float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; - float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; - - // 3x3 sub-determinants required to calculate 4x4 determinant - float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; - float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; - float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; - float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; - - det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0]; - float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0]; - float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0]; - float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1]; - float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1]; - float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2]; - - float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0]; - float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0]; - float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0]; - float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1]; - float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1]; - float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2]; - - // remaining 3x3 sub-determinants - float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01; - float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01; - float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02; - float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12; - - float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01; - float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01; - float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02; - float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12; - - float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01; - float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01; - float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02; - float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12; - - mat[0][0] = - det3_213_123 * invDet; - mat[1][0] = + det3_213_023 * invDet; - mat[2][0] = - det3_213_013 * invDet; - mat[3][0] = + det3_213_012 * invDet; - - mat[0][1] = + det3_203_123 * invDet; - mat[1][1] = - det3_203_023 * invDet; - mat[2][1] = + det3_203_013 * invDet; - mat[3][1] = - det3_203_012 * invDet; - - mat[0][2] = + det3_301_123 * invDet; - mat[1][2] = - det3_301_023 * invDet; - mat[2][2] = + det3_301_013 * invDet; - mat[3][2] = - det3_301_012 * invDet; - - mat[0][3] = - det3_201_123 * invDet; - mat[1][3] = + det3_201_023 * invDet; - mat[2][3] = - det3_201_013 * invDet; - mat[3][3] = + det3_201_012 * invDet; - - return true; -} - -/* -============ -idMat4::InverseFastSelf -============ -*/ -bool idMat4::InverseFastSelf( void ) { -#if 0 - // 84+4+16 = 104 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 4x4 determinant - float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; - float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]; - float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0]; - float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]; - float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1]; - float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2]; - - // 3x3 sub-determinants required to calculate 4x4 determinant - float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01; - float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01; - float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02; - float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12; - - det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] ); - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0]; - float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0]; - float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0]; - float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1]; - float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1]; - float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2]; - - float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0]; - float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0]; - float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0]; - float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1]; - float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1]; - float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2]; - - // remaining 3x3 sub-determinants - float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01; - float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01; - float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02; - float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12; - - float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01; - float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01; - float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02; - float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12; - - float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01; - float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01; - float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02; - float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12; - - mat[0][0] = - det3_213_123 * invDet; - mat[1][0] = + det3_213_023 * invDet; - mat[2][0] = - det3_213_013 * invDet; - mat[3][0] = + det3_213_012 * invDet; - - mat[0][1] = + det3_203_123 * invDet; - mat[1][1] = - det3_203_023 * invDet; - mat[2][1] = + det3_203_013 * invDet; - mat[3][1] = - det3_203_012 * invDet; - - mat[0][2] = + det3_301_123 * invDet; - mat[1][2] = - det3_301_023 * invDet; - mat[2][2] = + det3_301_013 * invDet; - mat[3][2] = - det3_301_012 * invDet; - - mat[0][3] = - det3_201_123 * invDet; - mat[1][3] = + det3_201_023 * invDet; - mat[2][3] = - det3_201_013 * invDet; - mat[3][3] = + det3_201_012 * invDet; - - return true; -#elif 0 - // 4*18 = 72 multiplications - // 4 divisions - float *mat = reinterpret_cast(this); - float s; - double d, di; - - di = mat[0]; - s = di; - mat[0] = d = 1.0f / di; - mat[1] *= d; - mat[2] *= d; - mat[3] *= d; - d = -d; - mat[4] *= d; - mat[8] *= d; - mat[12] *= d; - d = mat[4] * di; - mat[5] += mat[1] * d; - mat[6] += mat[2] * d; - mat[7] += mat[3] * d; - d = mat[8] * di; - mat[9] += mat[1] * d; - mat[10] += mat[2] * d; - mat[11] += mat[3] * d; - d = mat[12] * di; - mat[13] += mat[1] * d; - mat[14] += mat[2] * d; - mat[15] += mat[3] * d; - di = mat[5]; - s *= di; - mat[5] = d = 1.0f / di; - mat[4] *= d; - mat[6] *= d; - mat[7] *= d; - d = -d; - mat[1] *= d; - mat[9] *= d; - mat[13] *= d; - d = mat[1] * di; - mat[0] += mat[4] * d; - mat[2] += mat[6] * d; - mat[3] += mat[7] * d; - d = mat[9] * di; - mat[8] += mat[4] * d; - mat[10] += mat[6] * d; - mat[11] += mat[7] * d; - d = mat[13] * di; - mat[12] += mat[4] * d; - mat[14] += mat[6] * d; - mat[15] += mat[7] * d; - di = mat[10]; - s *= di; - mat[10] = d = 1.0f / di; - mat[8] *= d; - mat[9] *= d; - mat[11] *= d; - d = -d; - mat[2] *= d; - mat[6] *= d; - mat[14] *= d; - d = mat[2] * di; - mat[0] += mat[8] * d; - mat[1] += mat[9] * d; - mat[3] += mat[11] * d; - d = mat[6] * di; - mat[4] += mat[8] * d; - mat[5] += mat[9] * d; - mat[7] += mat[11] * d; - d = mat[14] * di; - mat[12] += mat[8] * d; - mat[13] += mat[9] * d; - mat[15] += mat[11] * d; - di = mat[15]; - s *= di; - mat[15] = d = 1.0f / di; - mat[12] *= d; - mat[13] *= d; - mat[14] *= d; - d = -d; - mat[3] *= d; - mat[7] *= d; - mat[11] *= d; - d = mat[3] * di; - mat[0] += mat[12] * d; - mat[1] += mat[13] * d; - mat[2] += mat[14] * d; - d = mat[7] * di; - mat[4] += mat[12] * d; - mat[5] += mat[13] * d; - mat[6] += mat[14] * d; - d = mat[11] * di; - mat[8] += mat[12] * d; - mat[9] += mat[13] * d; - mat[10] += mat[14] * d; - - return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); -#else - // 6*8+2*6 = 60 multiplications - // 2*1 = 2 divisions - idMat2 r0, r1, r2, r3; - float a, det, invDet; - float *mat = reinterpret_cast(this); - - // r0 = m0.Inverse(); - det = mat[0*4+0] * mat[1*4+1] - mat[0*4+1] * mat[1*4+0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - r0[0][0] = mat[1*4+1] * invDet; - r0[0][1] = - mat[0*4+1] * invDet; - r0[1][0] = - mat[1*4+0] * invDet; - r0[1][1] = mat[0*4+0] * invDet; - - // r1 = r0 * m1; - r1[0][0] = r0[0][0] * mat[0*4+2] + r0[0][1] * mat[1*4+2]; - r1[0][1] = r0[0][0] * mat[0*4+3] + r0[0][1] * mat[1*4+3]; - r1[1][0] = r0[1][0] * mat[0*4+2] + r0[1][1] * mat[1*4+2]; - r1[1][1] = r0[1][0] * mat[0*4+3] + r0[1][1] * mat[1*4+3]; - - // r2 = m2 * r1; - r2[0][0] = mat[2*4+0] * r1[0][0] + mat[2*4+1] * r1[1][0]; - r2[0][1] = mat[2*4+0] * r1[0][1] + mat[2*4+1] * r1[1][1]; - r2[1][0] = mat[3*4+0] * r1[0][0] + mat[3*4+1] * r1[1][0]; - r2[1][1] = mat[3*4+0] * r1[0][1] + mat[3*4+1] * r1[1][1]; - - // r3 = r2 - m3; - r3[0][0] = r2[0][0] - mat[2*4+2]; - r3[0][1] = r2[0][1] - mat[2*4+3]; - r3[1][0] = r2[1][0] - mat[3*4+2]; - r3[1][1] = r2[1][1] - mat[3*4+3]; - - // r3.InverseSelf(); - det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - a = r3[0][0]; - r3[0][0] = r3[1][1] * invDet; - r3[0][1] = - r3[0][1] * invDet; - r3[1][0] = - r3[1][0] * invDet; - r3[1][1] = a * invDet; - - // r2 = m2 * r0; - r2[0][0] = mat[2*4+0] * r0[0][0] + mat[2*4+1] * r0[1][0]; - r2[0][1] = mat[2*4+0] * r0[0][1] + mat[2*4+1] * r0[1][1]; - r2[1][0] = mat[3*4+0] * r0[0][0] + mat[3*4+1] * r0[1][0]; - r2[1][1] = mat[3*4+0] * r0[0][1] + mat[3*4+1] * r0[1][1]; - - // m2 = r3 * r2; - mat[2*4+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0]; - mat[2*4+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1]; - mat[3*4+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0]; - mat[3*4+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1]; - - // m0 = r0 - r1 * m2; - mat[0*4+0] = r0[0][0] - r1[0][0] * mat[2*4+0] - r1[0][1] * mat[3*4+0]; - mat[0*4+1] = r0[0][1] - r1[0][0] * mat[2*4+1] - r1[0][1] * mat[3*4+1]; - mat[1*4+0] = r0[1][0] - r1[1][0] * mat[2*4+0] - r1[1][1] * mat[3*4+0]; - mat[1*4+1] = r0[1][1] - r1[1][0] * mat[2*4+1] - r1[1][1] * mat[3*4+1]; - - // m1 = r1 * r3; - mat[0*4+2] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0]; - mat[0*4+3] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1]; - mat[1*4+2] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0]; - mat[1*4+3] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1]; - - // m3 = -r3; - mat[2*4+2] = -r3[0][0]; - mat[2*4+3] = -r3[0][1]; - mat[3*4+2] = -r3[1][0]; - mat[3*4+3] = -r3[1][1]; - - return true; -#endif -} - -/* -============= -idMat4::ToString -============= -*/ -const char *idMat4::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idMat5 -// -//=============================================================== - -idMat5 mat5_zero( idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ) ); -idMat5 mat5_identity( idVec5( 1, 0, 0, 0, 0 ), idVec5( 0, 1, 0, 0, 0 ), idVec5( 0, 0, 1, 0, 0 ), idVec5( 0, 0, 0, 1, 0 ), idVec5( 0, 0, 0, 0, 1 ) ); - -/* -============ -idMat5::Transpose -============ -*/ -idMat5 idMat5::Transpose( void ) const { - idMat5 transpose; - int i, j; - - for( i = 0; i < 5; i++ ) { - for( j = 0; j < 5; j++ ) { - transpose[ i ][ j ] = mat[ j ][ i ]; - } - } - return transpose; -} - -/* -============ -idMat5::TransposeSelf -============ -*/ -idMat5 &idMat5::TransposeSelf( void ) { - float temp; - int i, j; - - for( i = 0; i < 5; i++ ) { - for( j = i + 1; j < 5; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } - return *this; -} - -/* -============ -idMat5::Determinant -============ -*/ -float idMat5::Determinant( void ) const { - - // 2x2 sub-determinants required to calculate 5x5 determinant - float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; - float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; - float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; - float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; - float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; - float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; - float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; - float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; - float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; - float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; - - // 3x3 sub-determinants required to calculate 5x5 determinant - float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; - float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; - float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; - float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; - float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; - float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; - float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; - float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; - float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; - float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; - - // 4x4 sub-determinants required to calculate 5x5 determinant - float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; - float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; - float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; - float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; - float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; - - // determinant of 5x5 matrix - return mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; -} - -/* -============ -idMat5::InverseSelf -============ -*/ -bool idMat5::InverseSelf( void ) { - // 280+5+25 = 310 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 5x5 determinant - float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; - float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; - float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; - float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; - float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; - float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; - float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; - float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; - float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; - float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; - - // 3x3 sub-determinants required to calculate 5x5 determinant - float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; - float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; - float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; - float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; - float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; - float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; - float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; - float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; - float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; - float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; - - // 4x4 sub-determinants required to calculate 5x5 determinant - float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; - float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; - float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; - float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; - float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; - - // determinant of 5x5 matrix - det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; - - if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0]; - float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0]; - float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0]; - float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0]; - float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1]; - float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1]; - float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1]; - float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2]; - float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2]; - float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3]; - float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0]; - float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0]; - float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0]; - float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0]; - float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1]; - float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1]; - float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1]; - float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2]; - float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2]; - float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3]; - - // remaining 3x3 sub-determinants - float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01; - float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01; - float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01; - float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02; - float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02; - float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03; - float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12; - float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12; - float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13; - float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23; - float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01; - float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01; - float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01; - float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02; - float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02; - float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03; - float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12; - float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12; - float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13; - float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23; - float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01; - float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01; - float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01; - float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02; - float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02; - float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03; - float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12; - float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12; - float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13; - float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23; - - // remaining 4x4 sub-determinants - float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012; - float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012; - float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013; - float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023; - float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123; - float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012; - float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012; - float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013; - float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023; - float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123; - float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012; - float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012; - float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013; - float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023; - float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123; - float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012; - float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012; - float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013; - float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023; - float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123; - - mat[0][0] = det4_1234_1234 * invDet; - mat[0][1] = -det4_0234_1234 * invDet; - mat[0][2] = det4_0134_1234 * invDet; - mat[0][3] = -det4_0124_1234 * invDet; - mat[0][4] = det4_0123_1234 * invDet; - - mat[1][0] = -det4_1234_0234 * invDet; - mat[1][1] = det4_0234_0234 * invDet; - mat[1][2] = -det4_0134_0234 * invDet; - mat[1][3] = det4_0124_0234 * invDet; - mat[1][4] = -det4_0123_0234 * invDet; - - mat[2][0] = det4_1234_0134 * invDet; - mat[2][1] = -det4_0234_0134 * invDet; - mat[2][2] = det4_0134_0134 * invDet; - mat[2][3] = -det4_0124_0134 * invDet; - mat[2][4] = det4_0123_0134 * invDet; - - mat[3][0] = -det4_1234_0124 * invDet; - mat[3][1] = det4_0234_0124 * invDet; - mat[3][2] = -det4_0134_0124 * invDet; - mat[3][3] = det4_0124_0124 * invDet; - mat[3][4] = -det4_0123_0124 * invDet; - - mat[4][0] = det4_1234_0123 * invDet; - mat[4][1] = -det4_0234_0123 * invDet; - mat[4][2] = det4_0134_0123 * invDet; - mat[4][3] = -det4_0124_0123 * invDet; - mat[4][4] = det4_0123_0123 * invDet; - - return true; -} - -/* -============ -idMat5::InverseFastSelf -============ -*/ -bool idMat5::InverseFastSelf( void ) { -#if 0 - // 280+5+25 = 310 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 5x5 determinant - float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; - float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; - float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; - float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; - float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; - float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; - float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; - float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; - float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; - float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; - - // 3x3 sub-determinants required to calculate 5x5 determinant - float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; - float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; - float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; - float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; - float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; - float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; - float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; - float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; - float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; - float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; - - // 4x4 sub-determinants required to calculate 5x5 determinant - float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; - float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; - float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; - float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; - float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; - - // determinant of 5x5 matrix - det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; - - if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0]; - float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0]; - float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0]; - float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0]; - float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1]; - float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1]; - float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1]; - float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2]; - float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2]; - float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3]; - float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0]; - float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0]; - float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0]; - float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0]; - float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1]; - float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1]; - float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1]; - float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2]; - float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2]; - float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3]; - - // remaining 3x3 sub-determinants - float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01; - float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01; - float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01; - float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02; - float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02; - float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03; - float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12; - float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12; - float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13; - float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23; - float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01; - float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01; - float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01; - float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02; - float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02; - float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03; - float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12; - float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12; - float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13; - float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23; - float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01; - float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01; - float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01; - float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02; - float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02; - float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03; - float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12; - float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12; - float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13; - float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23; - - // remaining 4x4 sub-determinants - float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012; - float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012; - float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013; - float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023; - float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123; - float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012; - float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012; - float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013; - float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023; - float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123; - float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012; - float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012; - float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013; - float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023; - float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123; - float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012; - float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012; - float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013; - float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023; - float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123; - - mat[0][0] = det4_1234_1234 * invDet; - mat[0][1] = -det4_0234_1234 * invDet; - mat[0][2] = det4_0134_1234 * invDet; - mat[0][3] = -det4_0124_1234 * invDet; - mat[0][4] = det4_0123_1234 * invDet; - - mat[1][0] = -det4_1234_0234 * invDet; - mat[1][1] = det4_0234_0234 * invDet; - mat[1][2] = -det4_0134_0234 * invDet; - mat[1][3] = det4_0124_0234 * invDet; - mat[1][4] = -det4_0123_0234 * invDet; - - mat[2][0] = det4_1234_0134 * invDet; - mat[2][1] = -det4_0234_0134 * invDet; - mat[2][2] = det4_0134_0134 * invDet; - mat[2][3] = -det4_0124_0134 * invDet; - mat[2][4] = det4_0123_0134 * invDet; - - mat[3][0] = -det4_1234_0124 * invDet; - mat[3][1] = det4_0234_0124 * invDet; - mat[3][2] = -det4_0134_0124 * invDet; - mat[3][3] = det4_0124_0124 * invDet; - mat[3][4] = -det4_0123_0124 * invDet; - - mat[4][0] = det4_1234_0123 * invDet; - mat[4][1] = -det4_0234_0123 * invDet; - mat[4][2] = det4_0134_0123 * invDet; - mat[4][3] = -det4_0124_0123 * invDet; - mat[4][4] = det4_0123_0123 * invDet; - - return true; -#elif 0 - // 5*28 = 140 multiplications - // 5 divisions - float *mat = reinterpret_cast(this); - float s; - double d, di; - - di = mat[0]; - s = di; - mat[0] = d = 1.0f / di; - mat[1] *= d; - mat[2] *= d; - mat[3] *= d; - mat[4] *= d; - d = -d; - mat[5] *= d; - mat[10] *= d; - mat[15] *= d; - mat[20] *= d; - d = mat[5] * di; - mat[6] += mat[1] * d; - mat[7] += mat[2] * d; - mat[8] += mat[3] * d; - mat[9] += mat[4] * d; - d = mat[10] * di; - mat[11] += mat[1] * d; - mat[12] += mat[2] * d; - mat[13] += mat[3] * d; - mat[14] += mat[4] * d; - d = mat[15] * di; - mat[16] += mat[1] * d; - mat[17] += mat[2] * d; - mat[18] += mat[3] * d; - mat[19] += mat[4] * d; - d = mat[20] * di; - mat[21] += mat[1] * d; - mat[22] += mat[2] * d; - mat[23] += mat[3] * d; - mat[24] += mat[4] * d; - di = mat[6]; - s *= di; - mat[6] = d = 1.0f / di; - mat[5] *= d; - mat[7] *= d; - mat[8] *= d; - mat[9] *= d; - d = -d; - mat[1] *= d; - mat[11] *= d; - mat[16] *= d; - mat[21] *= d; - d = mat[1] * di; - mat[0] += mat[5] * d; - mat[2] += mat[7] * d; - mat[3] += mat[8] * d; - mat[4] += mat[9] * d; - d = mat[11] * di; - mat[10] += mat[5] * d; - mat[12] += mat[7] * d; - mat[13] += mat[8] * d; - mat[14] += mat[9] * d; - d = mat[16] * di; - mat[15] += mat[5] * d; - mat[17] += mat[7] * d; - mat[18] += mat[8] * d; - mat[19] += mat[9] * d; - d = mat[21] * di; - mat[20] += mat[5] * d; - mat[22] += mat[7] * d; - mat[23] += mat[8] * d; - mat[24] += mat[9] * d; - di = mat[12]; - s *= di; - mat[12] = d = 1.0f / di; - mat[10] *= d; - mat[11] *= d; - mat[13] *= d; - mat[14] *= d; - d = -d; - mat[2] *= d; - mat[7] *= d; - mat[17] *= d; - mat[22] *= d; - d = mat[2] * di; - mat[0] += mat[10] * d; - mat[1] += mat[11] * d; - mat[3] += mat[13] * d; - mat[4] += mat[14] * d; - d = mat[7] * di; - mat[5] += mat[10] * d; - mat[6] += mat[11] * d; - mat[8] += mat[13] * d; - mat[9] += mat[14] * d; - d = mat[17] * di; - mat[15] += mat[10] * d; - mat[16] += mat[11] * d; - mat[18] += mat[13] * d; - mat[19] += mat[14] * d; - d = mat[22] * di; - mat[20] += mat[10] * d; - mat[21] += mat[11] * d; - mat[23] += mat[13] * d; - mat[24] += mat[14] * d; - di = mat[18]; - s *= di; - mat[18] = d = 1.0f / di; - mat[15] *= d; - mat[16] *= d; - mat[17] *= d; - mat[19] *= d; - d = -d; - mat[3] *= d; - mat[8] *= d; - mat[13] *= d; - mat[23] *= d; - d = mat[3] * di; - mat[0] += mat[15] * d; - mat[1] += mat[16] * d; - mat[2] += mat[17] * d; - mat[4] += mat[19] * d; - d = mat[8] * di; - mat[5] += mat[15] * d; - mat[6] += mat[16] * d; - mat[7] += mat[17] * d; - mat[9] += mat[19] * d; - d = mat[13] * di; - mat[10] += mat[15] * d; - mat[11] += mat[16] * d; - mat[12] += mat[17] * d; - mat[14] += mat[19] * d; - d = mat[23] * di; - mat[20] += mat[15] * d; - mat[21] += mat[16] * d; - mat[22] += mat[17] * d; - mat[24] += mat[19] * d; - di = mat[24]; - s *= di; - mat[24] = d = 1.0f / di; - mat[20] *= d; - mat[21] *= d; - mat[22] *= d; - mat[23] *= d; - d = -d; - mat[4] *= d; - mat[9] *= d; - mat[14] *= d; - mat[19] *= d; - d = mat[4] * di; - mat[0] += mat[20] * d; - mat[1] += mat[21] * d; - mat[2] += mat[22] * d; - mat[3] += mat[23] * d; - d = mat[9] * di; - mat[5] += mat[20] * d; - mat[6] += mat[21] * d; - mat[7] += mat[22] * d; - mat[8] += mat[23] * d; - d = mat[14] * di; - mat[10] += mat[20] * d; - mat[11] += mat[21] * d; - mat[12] += mat[22] * d; - mat[13] += mat[23] * d; - d = mat[19] * di; - mat[15] += mat[20] * d; - mat[16] += mat[21] * d; - mat[17] += mat[22] * d; - mat[18] += mat[23] * d; - - return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); -#else - // 86+30+6 = 122 multiplications - // 2*1 = 2 divisions - idMat3 r0, r1, r2, r3; - float c0, c1, c2, det, invDet; - float *mat = reinterpret_cast(this); - - // r0 = m0.Inverse(); // 3x3 - c0 = mat[1*5+1] * mat[2*5+2] - mat[1*5+2] * mat[2*5+1]; - c1 = mat[1*5+2] * mat[2*5+0] - mat[1*5+0] * mat[2*5+2]; - c2 = mat[1*5+0] * mat[2*5+1] - mat[1*5+1] * mat[2*5+0]; - - det = mat[0*5+0] * c0 + mat[0*5+1] * c1 + mat[0*5+2] * c2; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - r0[0][0] = c0 * invDet; - r0[0][1] = ( mat[0*5+2] * mat[2*5+1] - mat[0*5+1] * mat[2*5+2] ) * invDet; - r0[0][2] = ( mat[0*5+1] * mat[1*5+2] - mat[0*5+2] * mat[1*5+1] ) * invDet; - r0[1][0] = c1 * invDet; - r0[1][1] = ( mat[0*5+0] * mat[2*5+2] - mat[0*5+2] * mat[2*5+0] ) * invDet; - r0[1][2] = ( mat[0*5+2] * mat[1*5+0] - mat[0*5+0] * mat[1*5+2] ) * invDet; - r0[2][0] = c2 * invDet; - r0[2][1] = ( mat[0*5+1] * mat[2*5+0] - mat[0*5+0] * mat[2*5+1] ) * invDet; - r0[2][2] = ( mat[0*5+0] * mat[1*5+1] - mat[0*5+1] * mat[1*5+0] ) * invDet; - - // r1 = r0 * m1; // 3x2 = 3x3 * 3x2 - r1[0][0] = r0[0][0] * mat[0*5+3] + r0[0][1] * mat[1*5+3] + r0[0][2] * mat[2*5+3]; - r1[0][1] = r0[0][0] * mat[0*5+4] + r0[0][1] * mat[1*5+4] + r0[0][2] * mat[2*5+4]; - r1[1][0] = r0[1][0] * mat[0*5+3] + r0[1][1] * mat[1*5+3] + r0[1][2] * mat[2*5+3]; - r1[1][1] = r0[1][0] * mat[0*5+4] + r0[1][1] * mat[1*5+4] + r0[1][2] * mat[2*5+4]; - r1[2][0] = r0[2][0] * mat[0*5+3] + r0[2][1] * mat[1*5+3] + r0[2][2] * mat[2*5+3]; - r1[2][1] = r0[2][0] * mat[0*5+4] + r0[2][1] * mat[1*5+4] + r0[2][2] * mat[2*5+4]; - - // r2 = m2 * r1; // 2x2 = 2x3 * 3x2 - r2[0][0] = mat[3*5+0] * r1[0][0] + mat[3*5+1] * r1[1][0] + mat[3*5+2] * r1[2][0]; - r2[0][1] = mat[3*5+0] * r1[0][1] + mat[3*5+1] * r1[1][1] + mat[3*5+2] * r1[2][1]; - r2[1][0] = mat[4*5+0] * r1[0][0] + mat[4*5+1] * r1[1][0] + mat[4*5+2] * r1[2][0]; - r2[1][1] = mat[4*5+0] * r1[0][1] + mat[4*5+1] * r1[1][1] + mat[4*5+2] * r1[2][1]; - - // r3 = r2 - m3; // 2x2 = 2x2 - 2x2 - r3[0][0] = r2[0][0] - mat[3*5+3]; - r3[0][1] = r2[0][1] - mat[3*5+4]; - r3[1][0] = r2[1][0] - mat[4*5+3]; - r3[1][1] = r2[1][1] - mat[4*5+4]; - - // r3.InverseSelf(); // 2x2 - det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - c0 = r3[0][0]; - r3[0][0] = r3[1][1] * invDet; - r3[0][1] = - r3[0][1] * invDet; - r3[1][0] = - r3[1][0] * invDet; - r3[1][1] = c0 * invDet; - - // r2 = m2 * r0; // 2x3 = 2x3 * 3x3 - r2[0][0] = mat[3*5+0] * r0[0][0] + mat[3*5+1] * r0[1][0] + mat[3*5+2] * r0[2][0]; - r2[0][1] = mat[3*5+0] * r0[0][1] + mat[3*5+1] * r0[1][1] + mat[3*5+2] * r0[2][1]; - r2[0][2] = mat[3*5+0] * r0[0][2] + mat[3*5+1] * r0[1][2] + mat[3*5+2] * r0[2][2]; - r2[1][0] = mat[4*5+0] * r0[0][0] + mat[4*5+1] * r0[1][0] + mat[4*5+2] * r0[2][0]; - r2[1][1] = mat[4*5+0] * r0[0][1] + mat[4*5+1] * r0[1][1] + mat[4*5+2] * r0[2][1]; - r2[1][2] = mat[4*5+0] * r0[0][2] + mat[4*5+1] * r0[1][2] + mat[4*5+2] * r0[2][2]; - - // m2 = r3 * r2; // 2x3 = 2x2 * 2x3 - mat[3*5+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0]; - mat[3*5+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1]; - mat[3*5+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2]; - mat[4*5+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0]; - mat[4*5+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1]; - mat[4*5+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2]; - - // m0 = r0 - r1 * m2; // 3x3 = 3x3 - 3x2 * 2x3 - mat[0*5+0] = r0[0][0] - r1[0][0] * mat[3*5+0] - r1[0][1] * mat[4*5+0]; - mat[0*5+1] = r0[0][1] - r1[0][0] * mat[3*5+1] - r1[0][1] * mat[4*5+1]; - mat[0*5+2] = r0[0][2] - r1[0][0] * mat[3*5+2] - r1[0][1] * mat[4*5+2]; - mat[1*5+0] = r0[1][0] - r1[1][0] * mat[3*5+0] - r1[1][1] * mat[4*5+0]; - mat[1*5+1] = r0[1][1] - r1[1][0] * mat[3*5+1] - r1[1][1] * mat[4*5+1]; - mat[1*5+2] = r0[1][2] - r1[1][0] * mat[3*5+2] - r1[1][1] * mat[4*5+2]; - mat[2*5+0] = r0[2][0] - r1[2][0] * mat[3*5+0] - r1[2][1] * mat[4*5+0]; - mat[2*5+1] = r0[2][1] - r1[2][0] * mat[3*5+1] - r1[2][1] * mat[4*5+1]; - mat[2*5+2] = r0[2][2] - r1[2][0] * mat[3*5+2] - r1[2][1] * mat[4*5+2]; - - // m1 = r1 * r3; // 3x2 = 3x2 * 2x2 - mat[0*5+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0]; - mat[0*5+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1]; - mat[1*5+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0]; - mat[1*5+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1]; - mat[2*5+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0]; - mat[2*5+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1]; - - // m3 = -r3; // 2x2 = - 2x2 - mat[3*5+3] = -r3[0][0]; - mat[3*5+4] = -r3[0][1]; - mat[4*5+3] = -r3[1][0]; - mat[4*5+4] = -r3[1][1]; - - return true; -#endif -} - -/* -============= -idMat5::ToString -============= -*/ -const char *idMat5::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idMat6 -// -//=============================================================== - -idMat6 mat6_zero( idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ) ); -idMat6 mat6_identity( idVec6( 1, 0, 0, 0, 0, 0 ), idVec6( 0, 1, 0, 0, 0, 0 ), idVec6( 0, 0, 1, 0, 0, 0 ), idVec6( 0, 0, 0, 1, 0, 0 ), idVec6( 0, 0, 0, 0, 1, 0 ), idVec6( 0, 0, 0, 0, 0, 1 ) ); - -/* -============ -idMat6::Transpose -============ -*/ -idMat6 idMat6::Transpose( void ) const { - idMat6 transpose; - int i, j; - - for( i = 0; i < 6; i++ ) { - for( j = 0; j < 6; j++ ) { - transpose[ i ][ j ] = mat[ j ][ i ]; - } - } - return transpose; -} - -/* -============ -idMat6::TransposeSelf -============ -*/ -idMat6 &idMat6::TransposeSelf( void ) { - float temp; - int i, j; - - for( i = 0; i < 6; i++ ) { - for( j = i + 1; j < 6; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } - return *this; -} - -/* -============ -idMat6::Determinant -============ -*/ -float idMat6::Determinant( void ) const { - - // 2x2 sub-determinants required to calculate 6x6 determinant - float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; - float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; - float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; - float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; - float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; - float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; - float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; - float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; - float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; - float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; - float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; - float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; - float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; - float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; - float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; - - // 3x3 sub-determinants required to calculate 6x6 determinant - float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; - float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; - float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; - float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; - float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; - float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; - float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; - float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; - float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; - float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; - float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; - float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; - float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; - float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; - float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; - float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; - float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; - float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; - float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; - float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; - - // 4x4 sub-determinants required to calculate 6x6 determinant - float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; - float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; - float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; - float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; - float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; - float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; - float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; - float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; - float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; - float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; - float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; - float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; - float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; - float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; - float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; - - // 5x5 sub-determinants required to calculate 6x6 determinant - float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; - float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; - float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; - float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; - float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; - float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; - - // determinant of 6x6 matrix - return mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - - mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; -} - -/* -============ -idMat6::InverseSelf -============ -*/ -bool idMat6::InverseSelf( void ) { - // 810+6+36 = 852 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 6x6 determinant - float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; - float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; - float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; - float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; - float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; - float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; - float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; - float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; - float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; - float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; - float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; - float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; - float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; - float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; - float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; - - // 3x3 sub-determinants required to calculate 6x6 determinant - float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; - float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; - float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; - float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; - float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; - float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; - float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; - float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; - float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; - float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; - float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; - float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; - float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; - float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; - float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; - float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; - float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; - float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; - float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; - float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; - - // 4x4 sub-determinants required to calculate 6x6 determinant - float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; - float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; - float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; - float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; - float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; - float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; - float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; - float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; - float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; - float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; - float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; - float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; - float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; - float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; - float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; - - // 5x5 sub-determinants required to calculate 6x6 determinant - float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; - float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; - float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; - float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; - float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; - float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; - - // determinant of 6x6 matrix - det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - - mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; - float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; - float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; - float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; - float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0]; - float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; - float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; - float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; - float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1]; - float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; - float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; - float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2]; - float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; - float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3]; - float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4]; - float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0]; - float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0]; - float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0]; - float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0]; - float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0]; - float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1]; - float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1]; - float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1]; - float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1]; - float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2]; - float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2]; - float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2]; - float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3]; - float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3]; - float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4]; - - // remaining 3x3 sub-determinants - float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; - float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; - float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; - float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01; - float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; - float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; - float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02; - float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; - float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03; - float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04; - float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; - float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; - float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12; - float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; - float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13; - float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14; - float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; - float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23; - float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24; - float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34; - float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01; - float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01; - float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01; - float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01; - float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02; - float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02; - float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02; - float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03; - float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03; - float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04; - float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12; - float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12; - float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12; - float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13; - float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13; - float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14; - float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23; - float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23; - float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24; - float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34; - float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01; - float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01; - float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01; - float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01; - float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02; - float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02; - float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02; - float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03; - float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03; - float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04; - float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12; - float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12; - float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12; - float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13; - float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13; - float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14; - float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23; - float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23; - float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24; - float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34; - - // remaining 4x4 sub-determinants - float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; - float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; - float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012; - float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; - float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013; - float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014; - float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; - float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023; - float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024; - float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034; - float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; - float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123; - float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124; - float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134; - float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234; - float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012; - float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012; - float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012; - float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013; - float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013; - float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014; - float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023; - float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023; - float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024; - float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034; - float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123; - float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123; - float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124; - float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134; - float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234; - float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012; - float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012; - float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012; - float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013; - float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013; - float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014; - float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023; - float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023; - float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024; - float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034; - float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123; - float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123; - float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124; - float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134; - float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234; - float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012; - float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012; - float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012; - float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013; - float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013; - float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014; - float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023; - float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023; - float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024; - float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034; - float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123; - float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123; - float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124; - float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134; - float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234; - - // remaining 5x5 sub-determinants - float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; - float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123; - float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124; - float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134; - float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234; - float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234; - float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123; - float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123; - float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124; - float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134; - float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234; - float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234; - float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123; - float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123; - float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124; - float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134; - float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234; - float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234; - float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123; - float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123; - float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124; - float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134; - float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234; - float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234; - float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123; - float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123; - float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124; - float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134; - float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234; - float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234; - - mat[0][0] = det5_12345_12345 * invDet; - mat[0][1] = -det5_02345_12345 * invDet; - mat[0][2] = det5_01345_12345 * invDet; - mat[0][3] = -det5_01245_12345 * invDet; - mat[0][4] = det5_01235_12345 * invDet; - mat[0][5] = -det5_01234_12345 * invDet; - - mat[1][0] = -det5_12345_02345 * invDet; - mat[1][1] = det5_02345_02345 * invDet; - mat[1][2] = -det5_01345_02345 * invDet; - mat[1][3] = det5_01245_02345 * invDet; - mat[1][4] = -det5_01235_02345 * invDet; - mat[1][5] = det5_01234_02345 * invDet; - - mat[2][0] = det5_12345_01345 * invDet; - mat[2][1] = -det5_02345_01345 * invDet; - mat[2][2] = det5_01345_01345 * invDet; - mat[2][3] = -det5_01245_01345 * invDet; - mat[2][4] = det5_01235_01345 * invDet; - mat[2][5] = -det5_01234_01345 * invDet; - - mat[3][0] = -det5_12345_01245 * invDet; - mat[3][1] = det5_02345_01245 * invDet; - mat[3][2] = -det5_01345_01245 * invDet; - mat[3][3] = det5_01245_01245 * invDet; - mat[3][4] = -det5_01235_01245 * invDet; - mat[3][5] = det5_01234_01245 * invDet; - - mat[4][0] = det5_12345_01235 * invDet; - mat[4][1] = -det5_02345_01235 * invDet; - mat[4][2] = det5_01345_01235 * invDet; - mat[4][3] = -det5_01245_01235 * invDet; - mat[4][4] = det5_01235_01235 * invDet; - mat[4][5] = -det5_01234_01235 * invDet; - - mat[5][0] = -det5_12345_01234 * invDet; - mat[5][1] = det5_02345_01234 * invDet; - mat[5][2] = -det5_01345_01234 * invDet; - mat[5][3] = det5_01245_01234 * invDet; - mat[5][4] = -det5_01235_01234 * invDet; - mat[5][5] = det5_01234_01234 * invDet; - - return true; -} - -/* -============ -idMat6::InverseFastSelf -============ -*/ -bool idMat6::InverseFastSelf( void ) { -#if 0 - // 810+6+36 = 852 multiplications - // 1 division - double det, invDet; - - // 2x2 sub-determinants required to calculate 6x6 determinant - float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0]; - float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0]; - float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0]; - float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0]; - float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0]; - float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1]; - float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1]; - float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1]; - float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1]; - float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2]; - float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2]; - float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2]; - float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3]; - float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3]; - float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4]; - - // 3x3 sub-determinants required to calculate 6x6 determinant - float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01; - float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01; - float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01; - float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01; - float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02; - float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02; - float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02; - float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03; - float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03; - float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04; - float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12; - float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12; - float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12; - float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13; - float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13; - float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14; - float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23; - float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23; - float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24; - float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34; - - // 4x4 sub-determinants required to calculate 6x6 determinant - float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012; - float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012; - float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012; - float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013; - float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013; - float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014; - float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023; - float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023; - float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024; - float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034; - float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123; - float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123; - float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124; - float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134; - float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234; - - // 5x5 sub-determinants required to calculate 6x6 determinant - float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123; - float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123; - float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124; - float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134; - float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234; - float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234; - - // determinant of 6x6 matrix - det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 - - mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - // remaining 2x2 sub-determinants - float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0]; - float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0]; - float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0]; - float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0]; - float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0]; - float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1]; - float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1]; - float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1]; - float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1]; - float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2]; - float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2]; - float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2]; - float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3]; - float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3]; - float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4]; - float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0]; - float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0]; - float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0]; - float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0]; - float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0]; - float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1]; - float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1]; - float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1]; - float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1]; - float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2]; - float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2]; - float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2]; - float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3]; - float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3]; - float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4]; - - // remaining 3x3 sub-determinants - float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01; - float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01; - float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01; - float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01; - float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02; - float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02; - float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02; - float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03; - float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03; - float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04; - float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12; - float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12; - float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12; - float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13; - float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13; - float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14; - float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23; - float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23; - float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24; - float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34; - float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01; - float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01; - float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01; - float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01; - float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02; - float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02; - float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02; - float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03; - float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03; - float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04; - float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12; - float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12; - float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12; - float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13; - float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13; - float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14; - float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23; - float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23; - float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24; - float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34; - float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01; - float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01; - float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01; - float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01; - float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02; - float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02; - float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02; - float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03; - float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03; - float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04; - float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12; - float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12; - float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12; - float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13; - float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13; - float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14; - float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23; - float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23; - float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24; - float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34; - - // remaining 4x4 sub-determinants - float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012; - float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012; - float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012; - float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013; - float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013; - float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014; - float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023; - float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023; - float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024; - float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034; - float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123; - float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123; - float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124; - float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134; - float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234; - float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012; - float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012; - float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012; - float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013; - float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013; - float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014; - float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023; - float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023; - float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024; - float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034; - float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123; - float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123; - float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124; - float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134; - float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234; - float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012; - float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012; - float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012; - float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013; - float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013; - float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014; - float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023; - float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023; - float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024; - float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034; - float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123; - float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123; - float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124; - float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134; - float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234; - float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012; - float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012; - float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012; - float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013; - float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013; - float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014; - float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023; - float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023; - float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024; - float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034; - float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123; - float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123; - float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124; - float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134; - float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234; - - // remaining 5x5 sub-determinants - float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123; - float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123; - float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124; - float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134; - float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234; - float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234; - float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123; - float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123; - float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124; - float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134; - float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234; - float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234; - float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123; - float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123; - float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124; - float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134; - float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234; - float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234; - float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123; - float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123; - float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124; - float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134; - float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234; - float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234; - float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123; - float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123; - float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124; - float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134; - float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234; - float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234; - - mat[0][0] = det5_12345_12345 * invDet; - mat[0][1] = -det5_02345_12345 * invDet; - mat[0][2] = det5_01345_12345 * invDet; - mat[0][3] = -det5_01245_12345 * invDet; - mat[0][4] = det5_01235_12345 * invDet; - mat[0][5] = -det5_01234_12345 * invDet; - - mat[1][0] = -det5_12345_02345 * invDet; - mat[1][1] = det5_02345_02345 * invDet; - mat[1][2] = -det5_01345_02345 * invDet; - mat[1][3] = det5_01245_02345 * invDet; - mat[1][4] = -det5_01235_02345 * invDet; - mat[1][5] = det5_01234_02345 * invDet; - - mat[2][0] = det5_12345_01345 * invDet; - mat[2][1] = -det5_02345_01345 * invDet; - mat[2][2] = det5_01345_01345 * invDet; - mat[2][3] = -det5_01245_01345 * invDet; - mat[2][4] = det5_01235_01345 * invDet; - mat[2][5] = -det5_01234_01345 * invDet; - - mat[3][0] = -det5_12345_01245 * invDet; - mat[3][1] = det5_02345_01245 * invDet; - mat[3][2] = -det5_01345_01245 * invDet; - mat[3][3] = det5_01245_01245 * invDet; - mat[3][4] = -det5_01235_01245 * invDet; - mat[3][5] = det5_01234_01245 * invDet; - - mat[4][0] = det5_12345_01235 * invDet; - mat[4][1] = -det5_02345_01235 * invDet; - mat[4][2] = det5_01345_01235 * invDet; - mat[4][3] = -det5_01245_01235 * invDet; - mat[4][4] = det5_01235_01235 * invDet; - mat[4][5] = -det5_01234_01235 * invDet; - - mat[5][0] = -det5_12345_01234 * invDet; - mat[5][1] = det5_02345_01234 * invDet; - mat[5][2] = -det5_01345_01234 * invDet; - mat[5][3] = det5_01245_01234 * invDet; - mat[5][4] = -det5_01235_01234 * invDet; - mat[5][5] = det5_01234_01234 * invDet; - - return true; -#elif 0 - // 6*40 = 240 multiplications - // 6 divisions - float *mat = reinterpret_cast(this); - float s; - double d, di; - - di = mat[0]; - s = di; - mat[0] = d = 1.0f / di; - mat[1] *= d; - mat[2] *= d; - mat[3] *= d; - mat[4] *= d; - mat[5] *= d; - d = -d; - mat[6] *= d; - mat[12] *= d; - mat[18] *= d; - mat[24] *= d; - mat[30] *= d; - d = mat[6] * di; - mat[7] += mat[1] * d; - mat[8] += mat[2] * d; - mat[9] += mat[3] * d; - mat[10] += mat[4] * d; - mat[11] += mat[5] * d; - d = mat[12] * di; - mat[13] += mat[1] * d; - mat[14] += mat[2] * d; - mat[15] += mat[3] * d; - mat[16] += mat[4] * d; - mat[17] += mat[5] * d; - d = mat[18] * di; - mat[19] += mat[1] * d; - mat[20] += mat[2] * d; - mat[21] += mat[3] * d; - mat[22] += mat[4] * d; - mat[23] += mat[5] * d; - d = mat[24] * di; - mat[25] += mat[1] * d; - mat[26] += mat[2] * d; - mat[27] += mat[3] * d; - mat[28] += mat[4] * d; - mat[29] += mat[5] * d; - d = mat[30] * di; - mat[31] += mat[1] * d; - mat[32] += mat[2] * d; - mat[33] += mat[3] * d; - mat[34] += mat[4] * d; - mat[35] += mat[5] * d; - di = mat[7]; - s *= di; - mat[7] = d = 1.0f / di; - mat[6] *= d; - mat[8] *= d; - mat[9] *= d; - mat[10] *= d; - mat[11] *= d; - d = -d; - mat[1] *= d; - mat[13] *= d; - mat[19] *= d; - mat[25] *= d; - mat[31] *= d; - d = mat[1] * di; - mat[0] += mat[6] * d; - mat[2] += mat[8] * d; - mat[3] += mat[9] * d; - mat[4] += mat[10] * d; - mat[5] += mat[11] * d; - d = mat[13] * di; - mat[12] += mat[6] * d; - mat[14] += mat[8] * d; - mat[15] += mat[9] * d; - mat[16] += mat[10] * d; - mat[17] += mat[11] * d; - d = mat[19] * di; - mat[18] += mat[6] * d; - mat[20] += mat[8] * d; - mat[21] += mat[9] * d; - mat[22] += mat[10] * d; - mat[23] += mat[11] * d; - d = mat[25] * di; - mat[24] += mat[6] * d; - mat[26] += mat[8] * d; - mat[27] += mat[9] * d; - mat[28] += mat[10] * d; - mat[29] += mat[11] * d; - d = mat[31] * di; - mat[30] += mat[6] * d; - mat[32] += mat[8] * d; - mat[33] += mat[9] * d; - mat[34] += mat[10] * d; - mat[35] += mat[11] * d; - di = mat[14]; - s *= di; - mat[14] = d = 1.0f / di; - mat[12] *= d; - mat[13] *= d; - mat[15] *= d; - mat[16] *= d; - mat[17] *= d; - d = -d; - mat[2] *= d; - mat[8] *= d; - mat[20] *= d; - mat[26] *= d; - mat[32] *= d; - d = mat[2] * di; - mat[0] += mat[12] * d; - mat[1] += mat[13] * d; - mat[3] += mat[15] * d; - mat[4] += mat[16] * d; - mat[5] += mat[17] * d; - d = mat[8] * di; - mat[6] += mat[12] * d; - mat[7] += mat[13] * d; - mat[9] += mat[15] * d; - mat[10] += mat[16] * d; - mat[11] += mat[17] * d; - d = mat[20] * di; - mat[18] += mat[12] * d; - mat[19] += mat[13] * d; - mat[21] += mat[15] * d; - mat[22] += mat[16] * d; - mat[23] += mat[17] * d; - d = mat[26] * di; - mat[24] += mat[12] * d; - mat[25] += mat[13] * d; - mat[27] += mat[15] * d; - mat[28] += mat[16] * d; - mat[29] += mat[17] * d; - d = mat[32] * di; - mat[30] += mat[12] * d; - mat[31] += mat[13] * d; - mat[33] += mat[15] * d; - mat[34] += mat[16] * d; - mat[35] += mat[17] * d; - di = mat[21]; - s *= di; - mat[21] = d = 1.0f / di; - mat[18] *= d; - mat[19] *= d; - mat[20] *= d; - mat[22] *= d; - mat[23] *= d; - d = -d; - mat[3] *= d; - mat[9] *= d; - mat[15] *= d; - mat[27] *= d; - mat[33] *= d; - d = mat[3] * di; - mat[0] += mat[18] * d; - mat[1] += mat[19] * d; - mat[2] += mat[20] * d; - mat[4] += mat[22] * d; - mat[5] += mat[23] * d; - d = mat[9] * di; - mat[6] += mat[18] * d; - mat[7] += mat[19] * d; - mat[8] += mat[20] * d; - mat[10] += mat[22] * d; - mat[11] += mat[23] * d; - d = mat[15] * di; - mat[12] += mat[18] * d; - mat[13] += mat[19] * d; - mat[14] += mat[20] * d; - mat[16] += mat[22] * d; - mat[17] += mat[23] * d; - d = mat[27] * di; - mat[24] += mat[18] * d; - mat[25] += mat[19] * d; - mat[26] += mat[20] * d; - mat[28] += mat[22] * d; - mat[29] += mat[23] * d; - d = mat[33] * di; - mat[30] += mat[18] * d; - mat[31] += mat[19] * d; - mat[32] += mat[20] * d; - mat[34] += mat[22] * d; - mat[35] += mat[23] * d; - di = mat[28]; - s *= di; - mat[28] = d = 1.0f / di; - mat[24] *= d; - mat[25] *= d; - mat[26] *= d; - mat[27] *= d; - mat[29] *= d; - d = -d; - mat[4] *= d; - mat[10] *= d; - mat[16] *= d; - mat[22] *= d; - mat[34] *= d; - d = mat[4] * di; - mat[0] += mat[24] * d; - mat[1] += mat[25] * d; - mat[2] += mat[26] * d; - mat[3] += mat[27] * d; - mat[5] += mat[29] * d; - d = mat[10] * di; - mat[6] += mat[24] * d; - mat[7] += mat[25] * d; - mat[8] += mat[26] * d; - mat[9] += mat[27] * d; - mat[11] += mat[29] * d; - d = mat[16] * di; - mat[12] += mat[24] * d; - mat[13] += mat[25] * d; - mat[14] += mat[26] * d; - mat[15] += mat[27] * d; - mat[17] += mat[29] * d; - d = mat[22] * di; - mat[18] += mat[24] * d; - mat[19] += mat[25] * d; - mat[20] += mat[26] * d; - mat[21] += mat[27] * d; - mat[23] += mat[29] * d; - d = mat[34] * di; - mat[30] += mat[24] * d; - mat[31] += mat[25] * d; - mat[32] += mat[26] * d; - mat[33] += mat[27] * d; - mat[35] += mat[29] * d; - di = mat[35]; - s *= di; - mat[35] = d = 1.0f / di; - mat[30] *= d; - mat[31] *= d; - mat[32] *= d; - mat[33] *= d; - mat[34] *= d; - d = -d; - mat[5] *= d; - mat[11] *= d; - mat[17] *= d; - mat[23] *= d; - mat[29] *= d; - d = mat[5] * di; - mat[0] += mat[30] * d; - mat[1] += mat[31] * d; - mat[2] += mat[32] * d; - mat[3] += mat[33] * d; - mat[4] += mat[34] * d; - d = mat[11] * di; - mat[6] += mat[30] * d; - mat[7] += mat[31] * d; - mat[8] += mat[32] * d; - mat[9] += mat[33] * d; - mat[10] += mat[34] * d; - d = mat[17] * di; - mat[12] += mat[30] * d; - mat[13] += mat[31] * d; - mat[14] += mat[32] * d; - mat[15] += mat[33] * d; - mat[16] += mat[34] * d; - d = mat[23] * di; - mat[18] += mat[30] * d; - mat[19] += mat[31] * d; - mat[20] += mat[32] * d; - mat[21] += mat[33] * d; - mat[22] += mat[34] * d; - d = mat[29] * di; - mat[24] += mat[30] * d; - mat[25] += mat[31] * d; - mat[26] += mat[32] * d; - mat[27] += mat[33] * d; - mat[28] += mat[34] * d; - - return ( s != 0.0f && !FLOAT_IS_NAN( s ) ); -#else - // 6*27+2*30 = 222 multiplications - // 2*1 = 2 divisions - idMat3 r0, r1, r2, r3; - float c0, c1, c2, det, invDet; - float *mat = reinterpret_cast(this); - - // r0 = m0.Inverse(); - c0 = mat[1*6+1] * mat[2*6+2] - mat[1*6+2] * mat[2*6+1]; - c1 = mat[1*6+2] * mat[2*6+0] - mat[1*6+0] * mat[2*6+2]; - c2 = mat[1*6+0] * mat[2*6+1] - mat[1*6+1] * mat[2*6+0]; - - det = mat[0*6+0] * c0 + mat[0*6+1] * c1 + mat[0*6+2] * c2; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - r0[0][0] = c0 * invDet; - r0[0][1] = ( mat[0*6+2] * mat[2*6+1] - mat[0*6+1] * mat[2*6+2] ) * invDet; - r0[0][2] = ( mat[0*6+1] * mat[1*6+2] - mat[0*6+2] * mat[1*6+1] ) * invDet; - r0[1][0] = c1 * invDet; - r0[1][1] = ( mat[0*6+0] * mat[2*6+2] - mat[0*6+2] * mat[2*6+0] ) * invDet; - r0[1][2] = ( mat[0*6+2] * mat[1*6+0] - mat[0*6+0] * mat[1*6+2] ) * invDet; - r0[2][0] = c2 * invDet; - r0[2][1] = ( mat[0*6+1] * mat[2*6+0] - mat[0*6+0] * mat[2*6+1] ) * invDet; - r0[2][2] = ( mat[0*6+0] * mat[1*6+1] - mat[0*6+1] * mat[1*6+0] ) * invDet; - - // r1 = r0 * m1; - r1[0][0] = r0[0][0] * mat[0*6+3] + r0[0][1] * mat[1*6+3] + r0[0][2] * mat[2*6+3]; - r1[0][1] = r0[0][0] * mat[0*6+4] + r0[0][1] * mat[1*6+4] + r0[0][2] * mat[2*6+4]; - r1[0][2] = r0[0][0] * mat[0*6+5] + r0[0][1] * mat[1*6+5] + r0[0][2] * mat[2*6+5]; - r1[1][0] = r0[1][0] * mat[0*6+3] + r0[1][1] * mat[1*6+3] + r0[1][2] * mat[2*6+3]; - r1[1][1] = r0[1][0] * mat[0*6+4] + r0[1][1] * mat[1*6+4] + r0[1][2] * mat[2*6+4]; - r1[1][2] = r0[1][0] * mat[0*6+5] + r0[1][1] * mat[1*6+5] + r0[1][2] * mat[2*6+5]; - r1[2][0] = r0[2][0] * mat[0*6+3] + r0[2][1] * mat[1*6+3] + r0[2][2] * mat[2*6+3]; - r1[2][1] = r0[2][0] * mat[0*6+4] + r0[2][1] * mat[1*6+4] + r0[2][2] * mat[2*6+4]; - r1[2][2] = r0[2][0] * mat[0*6+5] + r0[2][1] * mat[1*6+5] + r0[2][2] * mat[2*6+5]; - - // r2 = m2 * r1; - r2[0][0] = mat[3*6+0] * r1[0][0] + mat[3*6+1] * r1[1][0] + mat[3*6+2] * r1[2][0]; - r2[0][1] = mat[3*6+0] * r1[0][1] + mat[3*6+1] * r1[1][1] + mat[3*6+2] * r1[2][1]; - r2[0][2] = mat[3*6+0] * r1[0][2] + mat[3*6+1] * r1[1][2] + mat[3*6+2] * r1[2][2]; - r2[1][0] = mat[4*6+0] * r1[0][0] + mat[4*6+1] * r1[1][0] + mat[4*6+2] * r1[2][0]; - r2[1][1] = mat[4*6+0] * r1[0][1] + mat[4*6+1] * r1[1][1] + mat[4*6+2] * r1[2][1]; - r2[1][2] = mat[4*6+0] * r1[0][2] + mat[4*6+1] * r1[1][2] + mat[4*6+2] * r1[2][2]; - r2[2][0] = mat[5*6+0] * r1[0][0] + mat[5*6+1] * r1[1][0] + mat[5*6+2] * r1[2][0]; - r2[2][1] = mat[5*6+0] * r1[0][1] + mat[5*6+1] * r1[1][1] + mat[5*6+2] * r1[2][1]; - r2[2][2] = mat[5*6+0] * r1[0][2] + mat[5*6+1] * r1[1][2] + mat[5*6+2] * r1[2][2]; - - // r3 = r2 - m3; - r3[0][0] = r2[0][0] - mat[3*6+3]; - r3[0][1] = r2[0][1] - mat[3*6+4]; - r3[0][2] = r2[0][2] - mat[3*6+5]; - r3[1][0] = r2[1][0] - mat[4*6+3]; - r3[1][1] = r2[1][1] - mat[4*6+4]; - r3[1][2] = r2[1][2] - mat[4*6+5]; - r3[2][0] = r2[2][0] - mat[5*6+3]; - r3[2][1] = r2[2][1] - mat[5*6+4]; - r3[2][2] = r2[2][2] - mat[5*6+5]; - - // r3.InverseSelf(); - r2[0][0] = r3[1][1] * r3[2][2] - r3[1][2] * r3[2][1]; - r2[1][0] = r3[1][2] * r3[2][0] - r3[1][0] * r3[2][2]; - r2[2][0] = r3[1][0] * r3[2][1] - r3[1][1] * r3[2][0]; - - det = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0]; - - if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - - invDet = 1.0f / det; - - r2[0][1] = r3[0][2] * r3[2][1] - r3[0][1] * r3[2][2]; - r2[0][2] = r3[0][1] * r3[1][2] - r3[0][2] * r3[1][1]; - r2[1][1] = r3[0][0] * r3[2][2] - r3[0][2] * r3[2][0]; - r2[1][2] = r3[0][2] * r3[1][0] - r3[0][0] * r3[1][2]; - r2[2][1] = r3[0][1] * r3[2][0] - r3[0][0] * r3[2][1]; - r2[2][2] = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0]; - - r3[0][0] = r2[0][0] * invDet; - r3[0][1] = r2[0][1] * invDet; - r3[0][2] = r2[0][2] * invDet; - r3[1][0] = r2[1][0] * invDet; - r3[1][1] = r2[1][1] * invDet; - r3[1][2] = r2[1][2] * invDet; - r3[2][0] = r2[2][0] * invDet; - r3[2][1] = r2[2][1] * invDet; - r3[2][2] = r2[2][2] * invDet; - - // r2 = m2 * r0; - r2[0][0] = mat[3*6+0] * r0[0][0] + mat[3*6+1] * r0[1][0] + mat[3*6+2] * r0[2][0]; - r2[0][1] = mat[3*6+0] * r0[0][1] + mat[3*6+1] * r0[1][1] + mat[3*6+2] * r0[2][1]; - r2[0][2] = mat[3*6+0] * r0[0][2] + mat[3*6+1] * r0[1][2] + mat[3*6+2] * r0[2][2]; - r2[1][0] = mat[4*6+0] * r0[0][0] + mat[4*6+1] * r0[1][0] + mat[4*6+2] * r0[2][0]; - r2[1][1] = mat[4*6+0] * r0[0][1] + mat[4*6+1] * r0[1][1] + mat[4*6+2] * r0[2][1]; - r2[1][2] = mat[4*6+0] * r0[0][2] + mat[4*6+1] * r0[1][2] + mat[4*6+2] * r0[2][2]; - r2[2][0] = mat[5*6+0] * r0[0][0] + mat[5*6+1] * r0[1][0] + mat[5*6+2] * r0[2][0]; - r2[2][1] = mat[5*6+0] * r0[0][1] + mat[5*6+1] * r0[1][1] + mat[5*6+2] * r0[2][1]; - r2[2][2] = mat[5*6+0] * r0[0][2] + mat[5*6+1] * r0[1][2] + mat[5*6+2] * r0[2][2]; - - // m2 = r3 * r2; - mat[3*6+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0]; - mat[3*6+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1] + r3[0][2] * r2[2][1]; - mat[3*6+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2] + r3[0][2] * r2[2][2]; - mat[4*6+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0] + r3[1][2] * r2[2][0]; - mat[4*6+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1] + r3[1][2] * r2[2][1]; - mat[4*6+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2] + r3[1][2] * r2[2][2]; - mat[5*6+0] = r3[2][0] * r2[0][0] + r3[2][1] * r2[1][0] + r3[2][2] * r2[2][0]; - mat[5*6+1] = r3[2][0] * r2[0][1] + r3[2][1] * r2[1][1] + r3[2][2] * r2[2][1]; - mat[5*6+2] = r3[2][0] * r2[0][2] + r3[2][1] * r2[1][2] + r3[2][2] * r2[2][2]; - - // m0 = r0 - r1 * m2; - mat[0*6+0] = r0[0][0] - r1[0][0] * mat[3*6+0] - r1[0][1] * mat[4*6+0] - r1[0][2] * mat[5*6+0]; - mat[0*6+1] = r0[0][1] - r1[0][0] * mat[3*6+1] - r1[0][1] * mat[4*6+1] - r1[0][2] * mat[5*6+1]; - mat[0*6+2] = r0[0][2] - r1[0][0] * mat[3*6+2] - r1[0][1] * mat[4*6+2] - r1[0][2] * mat[5*6+2]; - mat[1*6+0] = r0[1][0] - r1[1][0] * mat[3*6+0] - r1[1][1] * mat[4*6+0] - r1[1][2] * mat[5*6+0]; - mat[1*6+1] = r0[1][1] - r1[1][0] * mat[3*6+1] - r1[1][1] * mat[4*6+1] - r1[1][2] * mat[5*6+1]; - mat[1*6+2] = r0[1][2] - r1[1][0] * mat[3*6+2] - r1[1][1] * mat[4*6+2] - r1[1][2] * mat[5*6+2]; - mat[2*6+0] = r0[2][0] - r1[2][0] * mat[3*6+0] - r1[2][1] * mat[4*6+0] - r1[2][2] * mat[5*6+0]; - mat[2*6+1] = r0[2][1] - r1[2][0] * mat[3*6+1] - r1[2][1] * mat[4*6+1] - r1[2][2] * mat[5*6+1]; - mat[2*6+2] = r0[2][2] - r1[2][0] * mat[3*6+2] - r1[2][1] * mat[4*6+2] - r1[2][2] * mat[5*6+2]; - - // m1 = r1 * r3; - mat[0*6+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0] + r1[0][2] * r3[2][0]; - mat[0*6+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1] + r1[0][2] * r3[2][1]; - mat[0*6+5] = r1[0][0] * r3[0][2] + r1[0][1] * r3[1][2] + r1[0][2] * r3[2][2]; - mat[1*6+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0] + r1[1][2] * r3[2][0]; - mat[1*6+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1] + r1[1][2] * r3[2][1]; - mat[1*6+5] = r1[1][0] * r3[0][2] + r1[1][1] * r3[1][2] + r1[1][2] * r3[2][2]; - mat[2*6+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0] + r1[2][2] * r3[2][0]; - mat[2*6+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1] + r1[2][2] * r3[2][1]; - mat[2*6+5] = r1[2][0] * r3[0][2] + r1[2][1] * r3[1][2] + r1[2][2] * r3[2][2]; - - // m3 = -r3; - mat[3*6+3] = -r3[0][0]; - mat[3*6+4] = -r3[0][1]; - mat[3*6+5] = -r3[0][2]; - mat[4*6+3] = -r3[1][0]; - mat[4*6+4] = -r3[1][1]; - mat[4*6+5] = -r3[1][2]; - mat[5*6+3] = -r3[2][0]; - mat[5*6+4] = -r3[2][1]; - mat[5*6+5] = -r3[2][2]; - - return true; -#endif -} - -/* -============= -idMat6::ToString -============= -*/ -const char *idMat6::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idMatX -// -//=============================================================== - -float idMatX::temp[MATX_MAX_TEMP+4]; -float * idMatX::tempPtr = (float *) ( ( (int) idMatX::temp + 15 ) & ~15 ); -int idMatX::tempIndex = 0; - - -/* -============ -idMatX::ChangeSize -============ -*/ -void idMatX::ChangeSize( int rows, int columns, bool makeZero ) { - int alloc = ( rows * columns + 3 ) & ~3; - if ( alloc > alloced && alloced != -1 ) { - float *oldMat = mat; - mat = (float *) Mem_Alloc16( alloc * sizeof( float ) ); - if ( makeZero ) { - memset( mat, 0, alloc * sizeof( float ) ); - } - alloced = alloc; - if ( oldMat ) { - int minRow = Min( numRows, rows ); - int minColumn = Min( numColumns, columns ); - for ( int i = 0; i < minRow; i++ ) { - for ( int j = 0; j < minColumn; j++ ) { - mat[ i * columns + j ] = oldMat[ i * numColumns + j ]; - } - } - Mem_Free16( oldMat ); - } - } else { - if ( columns < numColumns ) { - int minRow = Min( numRows, rows ); - for ( int i = 0; i < minRow; i++ ) { - for ( int j = 0; j < columns; j++ ) { - mat[ i * columns + j ] = mat[ i * numColumns + j ]; - } - } - } else if ( columns > numColumns ) { - for ( int i = Min( numRows, rows ) - 1; i >= 0; i-- ) { - if ( makeZero ) { - for ( int j = columns - 1; j >= numColumns; j-- ) { - mat[ i * columns + j ] = 0.0f; - } - } - for ( int j = numColumns - 1; j >= 0; j-- ) { - mat[ i * columns + j ] = mat[ i * numColumns + j ]; - } - } - } - if ( makeZero && rows > numRows ) { - memset( mat + numRows * columns, 0, ( rows - numRows ) * columns * sizeof( float ) ); - } - } - numRows = rows; - numColumns = columns; - MATX_CLEAREND(); -} - -/* -============ -idMatX::RemoveRow -============ -*/ -idMatX &idMatX::RemoveRow( int r ) { - int i; - - assert( r < numRows ); - - numRows--; - - for ( i = r; i < numRows; i++ ) { - memcpy( &mat[i * numColumns], &mat[( i + 1 ) * numColumns], numColumns * sizeof( float ) ); - } - - return *this; -} - -/* -============ -idMatX::RemoveColumn -============ -*/ -idMatX &idMatX::RemoveColumn( int r ) { - int i; - - assert( r < numColumns ); - - numColumns--; - - for ( i = 0; i < numRows - 1; i++ ) { - memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); - } - memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); - - return *this; -} - -/* -============ -idMatX::RemoveRowColumn -============ -*/ -idMatX &idMatX::RemoveRowColumn( int r ) { - int i; - - assert( r < numRows && r < numColumns ); - - numRows--; - numColumns--; - - if ( r > 0 ) { - for ( i = 0; i < r - 1; i++ ) { - memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); - } - memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); - } - - memcpy( &mat[r * numColumns], &mat[( r + 1 ) * ( numColumns + 1 )], r * sizeof( float ) ); - - for ( i = r; i < numRows - 1; i++ ) { - memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) ); - } - memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) ); - - return *this; -} - -/* -============ -idMatX::IsOrthogonal - - returns true if (*this) * this->Transpose() == Identity -============ -*/ -bool idMatX::IsOrthogonal( const float epsilon ) const { - float *ptr1, *ptr2, sum; - - if ( !IsSquare() ) { - return false; - } - - ptr1 = mat; - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - ptr2 = mat + j; - sum = ptr1[0] * ptr2[0] - (float) ( i == j ); - for ( int n = 1; n < numColumns; n++ ) { - ptr2 += numColumns; - sum += ptr1[n] * ptr2[0]; - } - if ( idMath::Fabs( sum ) > epsilon ) { - return false; - } - } - ptr1 += numColumns; - } - return true; -} - -/* -============ -idMatX::IsOrthonormal - - returns true if (*this) * this->Transpose() == Identity and the length of each column vector is 1 -============ -*/ -bool idMatX::IsOrthonormal( const float epsilon ) const { - float *ptr1, *ptr2, sum; - - if ( !IsSquare() ) { - return false; - } - - ptr1 = mat; - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - ptr2 = mat + j; - sum = ptr1[0] * ptr2[0] - (float) ( i == j ); - for ( int n = 1; n < numColumns; n++ ) { - ptr2 += numColumns; - sum += ptr1[n] * ptr2[0]; - } - if ( idMath::Fabs( sum ) > epsilon ) { - return false; - } - } - ptr1 += numColumns; - - ptr2 = mat + i; - sum = ptr2[0] * ptr2[0] - 1.0f; - for ( i = 1; i < numRows; i++ ) { - ptr2 += numColumns; - sum += ptr2[i] * ptr2[i]; - } - if ( idMath::Fabs( sum ) > epsilon ) { - return false; - } - } - return true; -} - -/* -============ -idMatX::IsPMatrix - - returns true if the matrix is a P-matrix - A square matrix is a P-matrix if all its principal minors are positive. -============ -*/ -bool idMatX::IsPMatrix( const float epsilon ) const { - int i, j; - float d; - idMatX m; - - if ( !IsSquare() ) { - return false; - } - - if ( numRows <= 0 ) { - return true; - } - - if ( (*this)[0][0] <= epsilon ) { - return false; - } - - if ( numRows <= 1 ) { - return true; - } - - m.SetData( numRows - 1, numColumns - 1, MATX_ALLOCA( ( numRows - 1 ) * ( numColumns - 1 ) ) ); - - for ( i = 1; i < numRows; i++ ) { - for ( j = 1; j < numColumns; j++ ) { - m[i-1][j-1] = (*this)[i][j]; - } - } - - if ( !m.IsPMatrix( epsilon ) ) { - return false; - } - - for ( i = 1; i < numRows; i++ ) { - d = (*this)[i][0] / (*this)[0][0]; - for ( j = 1; j < numColumns; j++ ) { - m[i-1][j-1] = (*this)[i][j] - d * (*this)[0][j]; - } - } - - if ( !m.IsPMatrix( epsilon ) ) { - return false; - } - - return true; -} - -/* -============ -idMatX::IsZMatrix - - returns true if the matrix is a Z-matrix - A square matrix M is a Z-matrix if M[i][j] <= 0 for all i != j. -============ -*/ -bool idMatX::IsZMatrix( const float epsilon ) const { - int i, j; - - if ( !IsSquare() ) { - return false; - } - - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - if ( (*this)[i][j] > epsilon && i != j ) { - return false; - } - } - } - return true; -} - -/* -============ -idMatX::IsPositiveDefinite - - returns true if the matrix is Positive Definite (PD) - A square matrix M of order n is said to be PD if y'My > 0 for all vectors y of dimension n, y != 0. -============ -*/ -bool idMatX::IsPositiveDefinite( const float epsilon ) const { - int i, j, k; - float d, s; - idMatX m; - - // the matrix must be square - if ( !IsSquare() ) { - return false; - } - - // copy matrix - m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); - m = *this; - - // add transpose - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - m[i][j] += (*this)[j][i]; - } - } - - // test Positive Definiteness with Gaussian pivot steps - for ( i = 0; i < numRows; i++ ) { - - for ( j = i; j < numColumns; j++ ) { - if ( m[j][j] <= epsilon ) { - return false; - } - } - - d = 1.0f / m[i][i]; - for ( j = i + 1; j < numColumns; j++ ) { - s = d * m[j][i]; - m[j][i] = 0.0f; - for ( k = i + 1; k < numRows; k++ ) { - m[j][k] -= s * m[i][k]; - } - } - } - - return true; -} - -/* -============ -idMatX::IsSymmetricPositiveDefinite - - returns true if the matrix is Symmetric Positive Definite (PD) -============ -*/ -bool idMatX::IsSymmetricPositiveDefinite( const float epsilon ) const { - idMatX m; - - // the matrix must be symmetric - if ( !IsSymmetric( epsilon ) ) { - return false; - } - - // copy matrix - m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); - m = *this; - - // being able to obtain Cholesky factors is both a necessary and sufficient condition for positive definiteness - return m.Cholesky_Factor(); -} - -/* -============ -idMatX::IsPositiveSemiDefinite - - returns true if the matrix is Positive Semi Definite (PSD) - A square matrix M of order n is said to be PSD if y'My >= 0 for all vectors y of dimension n, y != 0. -============ -*/ -bool idMatX::IsPositiveSemiDefinite( const float epsilon ) const { - int i, j, k; - float d, s; - idMatX m; - - // the matrix must be square - if ( !IsSquare() ) { - return false; - } - - // copy original matrix - m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); - m = *this; - - // add transpose - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - m[i][j] += (*this)[j][i]; - } - } - - // test Positive Semi Definiteness with Gaussian pivot steps - for ( i = 0; i < numRows; i++ ) { - - for ( j = i; j < numColumns; j++ ) { - if ( m[j][j] < -epsilon ) { - return false; - } - if ( m[j][j] > epsilon ) { - continue; - } - for ( k = 0; k < numRows; k++ ) { - if ( idMath::Fabs( m[k][j] ) > epsilon ) { - return false; - } - if ( idMath::Fabs( m[j][k] ) > epsilon ) { - return false; - } - } - } - - if ( m[i][i] <= epsilon ) { - continue; - } - - d = 1.0f / m[i][i]; - for ( j = i + 1; j < numColumns; j++ ) { - s = d * m[j][i]; - m[j][i] = 0.0f; - for ( k = i + 1; k < numRows; k++ ) { - m[j][k] -= s * m[i][k]; - } - } - } - - return true; -} - -/* -============ -idMatX::IsSymmetricPositiveSemiDefinite - - returns true if the matrix is Symmetric Positive Semi Definite (PSD) -============ -*/ -bool idMatX::IsSymmetricPositiveSemiDefinite( const float epsilon ) const { - - // the matrix must be symmetric - if ( !IsSymmetric( epsilon ) ) { - return false; - } - - return IsPositiveSemiDefinite( epsilon ); -} - -/* -============ -idMatX::LowerTriangularInverse - - in-place inversion of the lower triangular matrix -============ -*/ -bool idMatX::LowerTriangularInverse( void ) { - int i, j, k; - double d, sum; - - for ( i = 0; i < numRows; i++ ) { - d = (*this)[i][i]; - if ( d == 0.0f ) { - return false; - } - (*this)[i][i] = d = 1.0f / d; - - for ( j = 0; j < i; j++ ) { - sum = 0.0f; - for ( k = j; k < i; k++ ) { - sum -= (*this)[i][k] * (*this)[k][j]; - } - (*this)[i][j] = sum * d; - } - } - return true; -} - -/* -============ -idMatX::UpperTriangularInverse - - in-place inversion of the upper triangular matrix -============ -*/ -bool idMatX::UpperTriangularInverse( void ) { - int i, j, k; - double d, sum; - - for ( i = numRows-1; i >= 0; i-- ) { - d = (*this)[i][i]; - if ( d == 0.0f ) { - return false; - } - (*this)[i][i] = d = 1.0f / d; - - for ( j = numRows-1; j > i; j-- ) { - sum = 0.0f; - for ( k = j; k > i; k-- ) { - sum -= (*this)[i][k] * (*this)[k][j]; - } - (*this)[i][j] = sum * d; - } - } - return true; -} - -/* -============= -idMatX::ToString -============= -*/ -const char *idMatX::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============ -idMatX::Update_RankOne - - Updates the matrix to obtain the matrix: A + alpha * v * w' -============ -*/ -void idMatX::Update_RankOne( const idVecX &v, const idVecX &w, float alpha ) { - int i, j; - float s; - - assert( v.GetSize() >= numRows ); - assert( w.GetSize() >= numColumns ); - - for ( i = 0; i < numRows; i++ ) { - s = alpha * v[i]; - for ( j = 0; j < numColumns; j++ ) { - (*this)[i][j] += s * w[j]; - } - } -} - -/* -============ -idMatX::Update_RankOneSymmetric - - Updates the matrix to obtain the matrix: A + alpha * v * v' -============ -*/ -void idMatX::Update_RankOneSymmetric( const idVecX &v, float alpha ) { - int i, j; - float s; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - - for ( i = 0; i < numRows; i++ ) { - s = alpha * v[i]; - for ( j = 0; j < numColumns; j++ ) { - (*this)[i][j] += s * v[j]; - } - } -} - -/* -============ -idMatX::Update_RowColumn - - Updates the matrix to obtain the matrix: - - [ 0 a 0 ] - A + [ d b e ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] -============ -*/ -void idMatX::Update_RowColumn( const idVecX &v, const idVecX &w, int r ) { - int i; - - assert( w[r] == 0.0f ); - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - - for ( i = 0; i < numRows; i++ ) { - (*this)[i][r] += v[i]; - } - for ( i = 0; i < numColumns; i++ ) { - (*this)[r][i] += w[i]; - } -} - -/* -============ -idMatX::Update_RowColumnSymmetric - - Updates the matrix to obtain the matrix: - - [ 0 a 0 ] - A + [ a b c ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] -============ -*/ -void idMatX::Update_RowColumnSymmetric( const idVecX &v, int r ) { - int i; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - - for ( i = 0; i < r; i++ ) { - (*this)[i][r] += v[i]; - (*this)[r][i] += v[i]; - } - (*this)[r][r] += v[r]; - for ( i = r+1; i < numRows; i++ ) { - (*this)[i][r] += v[i]; - (*this)[r][i] += v[i]; - } -} - -/* -============ -idMatX::Update_Increment - - Updates the matrix to obtain the matrix: - - [ A a ] - [ c b ] - - where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1]], w[numColumns] = 0 -============ -*/ -void idMatX::Update_Increment( const idVecX &v, const idVecX &w ) { - int i; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - assert( w.GetSize() >= numColumns+1 ); - - ChangeSize( numRows+1, numColumns+1, false ); - - for ( i = 0; i < numRows; i++ ) { - (*this)[i][numColumns-1] = v[i]; - } - for ( i = 0; i < numColumns-1; i++ ) { - (*this)[numRows-1][i] = w[i]; - } -} - -/* -============ -idMatX::Update_IncrementSymmetric - - Updates the matrix to obtain the matrix: - - [ A a ] - [ a b ] - - where: a = v[0,numRows-1], b = v[numRows] -============ -*/ -void idMatX::Update_IncrementSymmetric( const idVecX &v ) { - int i; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - - ChangeSize( numRows+1, numColumns+1, false ); - - for ( i = 0; i < numRows-1; i++ ) { - (*this)[i][numColumns-1] = v[i]; - } - for ( i = 0; i < numColumns; i++ ) { - (*this)[numRows-1][i] = v[i]; - } -} - -/* -============ -idMatX::Update_Decrement - - Updates the matrix to obtain a matrix with row r and column r removed. -============ -*/ -void idMatX::Update_Decrement( int r ) { - RemoveRowColumn( r ); -} - -/* -============ -idMatX::Inverse_GaussJordan - - in-place inversion using Gauss-Jordan elimination -============ -*/ -bool idMatX::Inverse_GaussJordan( void ) { - int i, j, k, r, c; - float d, max; - - assert( numRows == numColumns ); - - int *columnIndex = (int *) _alloca16( numRows * sizeof( int ) ); - int *rowIndex = (int *) _alloca16( numRows * sizeof( int ) ); - bool *pivot = (bool *) _alloca16( numRows * sizeof( bool ) ); - - memset( pivot, 0, numRows * sizeof( bool ) ); - - // elimination with full pivoting - for ( i = 0; i < numRows; i++ ) { - - // search the whole matrix except for pivoted rows for the maximum absolute value - max = 0.0f; - r = c = 0; - for ( j = 0; j < numRows; j++ ) { - if ( !pivot[j] ) { - for ( k = 0; k < numRows; k++ ) { - if ( !pivot[k] ) { - d = idMath::Fabs( (*this)[j][k] ); - if ( d > max ) { - max = d; - r = j; - c = k; - } - } - } - } - } - - if ( max == 0.0f ) { - // matrix is not invertible - return false; - } - - pivot[c] = true; - - // swap rows such that entry (c,c) has the pivot entry - if ( r != c ) { - SwapRows( r, c ); - } - - // keep track of the row permutation - rowIndex[i] = r; - columnIndex[i] = c; - - // scale the row to make the pivot entry equal to 1 - d = 1.0f / (*this)[c][c]; - (*this)[c][c] = 1.0f; - for ( k = 0; k < numRows; k++ ) { - (*this)[c][k] *= d; - } - - // zero out the pivot column entries in the other rows - for ( j = 0; j < numRows; j++ ) { - if ( j != c ) { - d = (*this)[j][c]; - (*this)[j][c] = 0.0f; - for ( k = 0; k < numRows; k++ ) { - (*this)[j][k] -= (*this)[c][k] * d; - } - } - } - } - - // reorder rows to store the inverse of the original matrix - for ( j = numRows - 1; j >= 0; j-- ) { - if ( rowIndex[j] != columnIndex[j] ) { - for ( k = 0; k < numRows; k++ ) { - d = (*this)[k][rowIndex[j]]; - (*this)[k][rowIndex[j]] = (*this)[k][columnIndex[j]]; - (*this)[k][columnIndex[j]] = d; - } - } - } - - return true; -} - -/* -============ -idMatX::Inverse_UpdateRankOne - - Updates the in-place inverse using the Sherman-Morrison formula to obtain the inverse for the matrix: A + alpha * v * w' -============ -*/ -bool idMatX::Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha ) { - int i, j; - float beta, s; - idVecX y, z; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - - y.SetData( numRows, VECX_ALLOCA( numRows ) ); - z.SetData( numRows, VECX_ALLOCA( numRows ) ); - - Multiply( y, v ); - TransposeMultiply( z, w ); - beta = 1.0f + ( w * y ); - - if ( beta == 0.0f ) { - return false; - } - - alpha /= beta; - - for ( i = 0; i < numRows; i++ ) { - s = y[i] * alpha; - for ( j = 0; j < numColumns; j++ ) { - (*this)[i][j] -= s * z[j]; - } - } - return true; -} - -/* -============ -idMatX::Inverse_UpdateRowColumn - - Updates the in-place inverse to obtain the inverse for the matrix: - - [ 0 a 0 ] - A + [ d b e ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] -============ -*/ -bool idMatX::Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r ) { - idVecX s; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - assert( r >= 0 && r < numRows && r < numColumns ); - assert( w[r] == 0.0f ); - - s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); - s.Zero(); - s[r] = 1.0f; - - if ( !Inverse_UpdateRankOne( v, s, 1.0f ) ) { - return false; - } - if ( !Inverse_UpdateRankOne( s, w, 1.0f ) ) { - return false; - } - return true; -} - -/* -============ -idMatX::Inverse_UpdateIncrement - - Updates the in-place inverse to obtain the inverse for the matrix: - - [ A a ] - [ c b ] - - where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 -============ -*/ -bool idMatX::Inverse_UpdateIncrement( const idVecX &v, const idVecX &w ) { - idVecX v2; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - assert( w.GetSize() >= numColumns+1 ); - - ChangeSize( numRows+1, numColumns+1, true ); - (*this)[numRows-1][numRows-1] = 1.0f; - - v2.SetData( numRows, VECX_ALLOCA( numRows ) ); - v2 = v; - v2[numRows-1] -= 1.0f; - - return Inverse_UpdateRowColumn( v2, w, numRows-1 ); -} - -/* -============ -idMatX::Inverse_UpdateDecrement - - Updates the in-place inverse to obtain the inverse of the matrix with row r and column r removed. - v and w should store the column and row of the original matrix respectively. -============ -*/ -bool idMatX::Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r ) { - idVecX v1, w1; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( w.GetSize() >= numColumns ); - assert( r >= 0 && r < numRows && r < numColumns ); - - v1.SetData( numRows, VECX_ALLOCA( numRows ) ); - w1.SetData( numRows, VECX_ALLOCA( numRows ) ); - - // update the row and column to identity - v1 = -v; - w1 = -w; - v1[r] += 1.0f; - w1[r] = 0.0f; - - if ( !Inverse_UpdateRowColumn( v1, w1, r ) ) { - return false; - } - - // physically remove the row and column - Update_Decrement( r ); - - return true; -} - -/* -============ -idMatX::Inverse_Solve - - Solve Ax = b with A inverted -============ -*/ -void idMatX::Inverse_Solve( idVecX &x, const idVecX &b ) const { - Multiply( x, b ); -} - -/* -============ -idMatX::LU_Factor - - in-place factorization: LU - L is a triangular matrix stored in the lower triangle. - L has ones on the diagonal that are not stored. - U is a triangular matrix stored in the upper triangle. - If index != NULL partial pivoting is used for numerical stability. - If index != NULL it must point to an array of numRow integers and is used to keep track of the row permutation. - If det != NULL the determinant of the matrix is calculated and stored. -============ -*/ -bool idMatX::LU_Factor( int *index, float *det ) { - int i, j, k, newi, min; - double s, t, d, w; - - // if partial pivoting should be used - if ( index ) { - for ( i = 0; i < numRows; i++ ) { - index[i] = i; - } - } - - w = 1.0f; - min = Min( numRows, numColumns ); - for ( i = 0; i < min; i++ ) { - - newi = i; - s = idMath::Fabs( (*this)[i][i] ); - - if ( index ) { - // find the largest absolute pivot - for ( j = i + 1; j < numRows; j++ ) { - t = idMath::Fabs( (*this)[j][i] ); - if ( t > s ) { - newi = j; - s = t; - } - } - } - - if ( s == 0.0f ) { - return false; - } - - if ( newi != i ) { - - w = -w; - - // swap index elements - k = index[i]; - index[i] = index[newi]; - index[newi] = k; - - // swap rows - for ( j = 0; j < numColumns; j++ ) { - t = (*this)[newi][j]; - (*this)[newi][j] = (*this)[i][j]; - (*this)[i][j] = t; - } - } - - if ( i < numRows ) { - d = 1.0f / (*this)[i][i]; - for ( j = i + 1; j < numRows; j++ ) { - (*this)[j][i] *= d; - } - } - - if ( i < min-1 ) { - for ( j = i + 1; j < numRows; j++ ) { - d = (*this)[j][i]; - for ( k = i + 1; k < numColumns; k++ ) { - (*this)[j][k] -= d * (*this)[i][k]; - } - } - } - } - - if ( det ) { - for ( i = 0; i < numRows; i++ ) { - w *= (*this)[i][i]; - } - *det = w; - } - - return true; -} - -/* -============ -idMatX::LU_UpdateRankOne - - Updates the in-place LU factorization to obtain the factors for the matrix: LU + alpha * v * w' -============ -*/ -bool idMatX::LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index ) { - int i, j, max; - float *y, *z; - double diag, beta, p0, p1, d; - - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - - y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); - z = (float *) _alloca16( w.GetSize() * sizeof( float ) ); - - if ( index != NULL ) { - for ( i = 0; i < numRows; i++ ) { - y[i] = alpha * v[index[i]]; - } - } else { - for ( i = 0; i < numRows; i++ ) { - y[i] = alpha * v[i]; - } - } - - memcpy( z, w.ToFloatPtr(), w.GetSize() * sizeof( float ) ); - - max = Min( numRows, numColumns ); - for ( i = 0; i < max; i++ ) { - diag = (*this)[i][i]; - - p0 = y[i]; - p1 = z[i]; - diag += p0 * p1; - - if ( diag == 0.0f ) { - return false; - } - - beta = p1 / diag; - - (*this)[i][i] = diag; - - for ( j = i+1; j < numColumns; j++ ) { - - d = (*this)[i][j]; - - d += p0 * z[j]; - z[j] -= beta * d; - - (*this)[i][j] = d; - } - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i]; - - y[j] -= p0 * d; - d += beta * y[j]; - - (*this)[j][i] = d; - } - } - return true; -} - -/* -============ -idMatX::LU_UpdateRowColumn - - Updates the in-place LU factorization to obtain the factors for the matrix: - - [ 0 a 0 ] - LU + [ d b e ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] -============ -*/ -bool idMatX::LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index ) { -#if 0 - - idVecX s; - - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - assert( r >= 0 && r < numRows && r < numColumns ); - assert( w[r] == 0.0f ); - - s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); - s.Zero(); - s[r] = 1.0f; - - if ( !LU_UpdateRankOne( v, s, 1.0f, index ) ) { - return false; - } - if ( !LU_UpdateRankOne( s, w, 1.0f, index ) ) { - return false; - } - return true; - -#else - - int i, j, min, max, rp; - float *y0, *y1, *z0, *z1; - double diag, beta0, beta1, p0, p1, q0, q1, d; - - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - assert( r >= 0 && r < numColumns && r < numRows ); - assert( w[r] == 0.0f ); - - y0 = (float *) _alloca16( v.GetSize() * sizeof( float ) ); - z0 = (float *) _alloca16( w.GetSize() * sizeof( float ) ); - y1 = (float *) _alloca16( v.GetSize() * sizeof( float ) ); - z1 = (float *) _alloca16( w.GetSize() * sizeof( float ) ); - - if ( index != NULL ) { - for ( i = 0; i < numRows; i++ ) { - y0[i] = v[index[i]]; - } - rp = r; - for ( i = 0; i < numRows; i++ ) { - if ( index[i] == r ) { - rp = i; - break; - } - } - } else { - memcpy( y0, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); - rp = r; - } - - memset( y1, 0, v.GetSize() * sizeof( float ) ); - y1[rp] = 1.0f; - - memset( z0, 0, w.GetSize() * sizeof( float ) ); - z0[r] = 1.0f; - - memcpy( z1, w.ToFloatPtr(), w.GetSize() * sizeof( float ) ); - - // update the beginning of the to be updated row and column - min = Min( r, rp ); - for ( i = 0; i < min; i++ ) { - p0 = y0[i]; - beta1 = z1[i] / (*this)[i][i]; - - (*this)[i][r] += p0; - for ( j = i+1; j < numColumns; j++ ) { - z1[j] -= beta1 * (*this)[i][j]; - } - for ( j = i+1; j < numRows; j++ ) { - y0[j] -= p0 * (*this)[j][i]; - } - (*this)[rp][i] += beta1; - } - - // update the lower right corner starting at r,r - max = Min( numRows, numColumns ); - for ( i = min; i < max; i++ ) { - diag = (*this)[i][i]; - - p0 = y0[i]; - p1 = z0[i]; - diag += p0 * p1; - - if ( diag == 0.0f ) { - return false; - } - - beta0 = p1 / diag; - - q0 = y1[i]; - q1 = z1[i]; - diag += q0 * q1; - - if ( diag == 0.0f ) { - return false; - } - - beta1 = q1 / diag; - - (*this)[i][i] = diag; - - for ( j = i+1; j < numColumns; j++ ) { - - d = (*this)[i][j]; - - d += p0 * z0[j]; - z0[j] -= beta0 * d; - - d += q0 * z1[j]; - z1[j] -= beta1 * d; - - (*this)[i][j] = d; - } - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i]; - - y0[j] -= p0 * d; - d += beta0 * y0[j]; - - y1[j] -= q0 * d; - d += beta1 * y1[j]; - - (*this)[j][i] = d; - } - } - return true; - -#endif -} - -/* -============ -idMatX::LU_UpdateIncrement - - Updates the in-place LU factorization to obtain the factors for the matrix: - - [ A a ] - [ c b ] - - where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 -============ -*/ -bool idMatX::LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index ) { - int i, j; - float sum; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - assert( w.GetSize() >= numColumns+1 ); - - ChangeSize( numRows+1, numColumns+1, true ); - - // add row to L - for ( i = 0; i < numRows - 1; i++ ) { - sum = w[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[numRows - 1][j] * (*this)[j][i]; - } - (*this)[numRows - 1 ][i] = sum / (*this)[i][i]; - } - - // add row to the permutation index - if ( index != NULL ) { - index[numRows - 1] = numRows - 1; - } - - // add column to U - for ( i = 0; i < numRows; i++ ) { - if ( index != NULL ) { - sum = v[index[i]]; - } else { - sum = v[i]; - } - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * (*this)[j][numRows - 1]; - } - (*this)[i][numRows - 1] = sum; - } - - return true; -} - -/* -============ -idMatX::LU_UpdateDecrement - - Updates the in-place LU factorization to obtain the factors for the matrix with row r and column r removed. - v and w should store the column and row of the original matrix respectively. - If index != NULL then u should store row index[r] of the original matrix. If index == NULL then u = w. -============ -*/ -bool idMatX::LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index ) { - int i, p; - idVecX v1, w1; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - assert( r >= 0 && r < numRows && r < numColumns ); - - v1.SetData( numRows, VECX_ALLOCA( numRows ) ); - w1.SetData( numRows, VECX_ALLOCA( numRows ) ); - - if ( index != NULL ) { - - // find the pivot row - for ( p = i = 0; i < numRows; i++ ) { - if ( index[i] == r ) { - p = i; - break; - } - } - - // update the row and column to identity - v1 = -v; - w1 = -u; - - if ( p != r ) { - idSwap( v1[index[r]], v1[index[p]] ); - idSwap( index[r], index[p] ); - } - - v1[r] += 1.0f; - w1[r] = 0.0f; - - if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) { - return false; - } - - if ( p != r ) { - - if ( idMath::Fabs( u[p] ) < 1e-4f ) { - // NOTE: an additional row interchange is required for numerical stability - } - - // move row index[r] of the original matrix to row index[p] of the original matrix - v1.Zero(); - v1[index[p]] = 1.0f; - w1 = u - w; - - if ( !LU_UpdateRankOne( v1, w1, 1.0f, index ) ) { - return false; - } - } - - // remove the row from the permutation index - for ( i = r; i < numRows - 1; i++ ) { - index[i] = index[i+1]; - } - for ( i = 0; i < numRows - 1; i++ ) { - if ( index[i] > r ) { - index[i]--; - } - } - - } else { - - v1 = -v; - w1 = -w; - v1[r] += 1.0f; - w1[r] = 0.0f; - - if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) { - return false; - } - } - - // physically remove the row and column - Update_Decrement( r ); - - return true; -} - -/* -============ -idMatX::LU_Solve - - Solve Ax = b with A factored in-place as: LU -============ -*/ -void idMatX::LU_Solve( idVecX &x, const idVecX &b, const int *index ) const { - int i, j; - double sum; - - assert( x.GetSize() == numColumns && b.GetSize() == numRows ); - - // solve L - for ( i = 0; i < numRows; i++ ) { - if ( index != NULL ) { - sum = b[index[i]]; - } else { - sum = b[i]; - } - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum; - } - - // solve U - for ( i = numRows - 1; i >= 0; i-- ) { - sum = x[i]; - for ( j = i + 1; j < numRows; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum / (*this)[i][i]; - } -} - -/* -============ -idMatX::LU_Inverse - - Calculates the inverse of the matrix which is factored in-place as LU -============ -*/ -void idMatX::LU_Inverse( idMatX &inv, const int *index ) const { - int i, j; - idVecX x, b; - - assert( numRows == numColumns ); - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - inv.SetSize( numRows, numColumns ); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - LU_Solve( x, b, index ); - for ( j = 0; j < numRows; j++ ) { - inv[j][i] = x[j]; - } - b[i] = 0.0f; - } -} - -/* -============ -idMatX::LU_UnpackFactors - - Unpacks the in-place LU factorization. -============ -*/ -void idMatX::LU_UnpackFactors( idMatX &L, idMatX &U ) const { - int i, j; - - L.Zero( numRows, numColumns ); - U.Zero( numRows, numColumns ); - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < i; j++ ) { - L[i][j] = (*this)[i][j]; - } - L[i][i] = 1.0f; - for ( j = i; j < numColumns; j++ ) { - U[i][j] = (*this)[i][j]; - } - } -} - -/* -============ -idMatX::LU_MultiplyFactors - - Multiplies the factors of the in-place LU factorization to form the original matrix. -============ -*/ -void idMatX::LU_MultiplyFactors( idMatX &m, const int *index ) const { - int r, rp, i, j; - double sum; - - m.SetSize( numRows, numColumns ); - - for ( r = 0; r < numRows; r++ ) { - - if ( index != NULL ) { - rp = index[r]; - } else { - rp = r; - } - - // calculate row of matrix - for ( i = 0; i < numColumns; i++ ) { - if ( i >= r ) { - sum = (*this)[r][i]; - } else { - sum = 0.0f; - } - for ( j = 0; j <= i && j < r; j++ ) { - sum += (*this)[r][j] * (*this)[j][i]; - } - m[rp][i] = sum; - } - } -} - -/* -============ -idMatX::QR_Factor - - in-place factorization: QR - Q is an orthogonal matrix represented as a product of Householder matrices stored in the lower triangle and c. - R is a triangular matrix stored in the upper triangle except for the diagonal elements which are stored in d. - The initial matrix has to be square. -============ -*/ -bool idMatX::QR_Factor( idVecX &c, idVecX &d ) { - int i, j, k; - double scale, s, t, sum; - bool singular = false; - - assert( numRows == numColumns ); - assert( c.GetSize() >= numRows && d.GetSize() >= numRows ); - - for ( k = 0; k < numRows-1; k++ ) { - - scale = 0.0f; - for ( i = k; i < numRows; i++ ) { - s = idMath::Fabs( (*this)[i][k] ); - if ( s > scale ) { - scale = s; - } - } - if ( scale == 0.0f ) { - singular = true; - c[k] = d[k] = 0.0f; - } else { - - s = 1.0f / scale; - for ( i = k; i < numRows; i++ ) { - (*this)[i][k] *= s; - } - - sum = 0.0f; - for ( i = k; i < numRows; i++ ) { - s = (*this)[i][k]; - sum += s * s; - } - - s = idMath::Sqrt( sum ); - if ( (*this)[k][k] < 0.0f ) { - s = -s; - } - (*this)[k][k] += s; - c[k] = s * (*this)[k][k]; - d[k] = -scale * s; - - for ( j = k+1; j < numRows; j++ ) { - - sum = 0.0f; - for ( i = k; i < numRows; i++ ) { - sum += (*this)[i][k] * (*this)[i][j]; - } - t = sum / c[k]; - for ( i = k; i < numRows; i++ ) { - (*this)[i][j] -= t * (*this)[i][k]; - } - } - } - } - d[numRows-1] = (*this)[ (numRows-1) ][ (numRows-1) ]; - if ( d[numRows-1] == 0.0f ) { - singular = true; - } - - return !singular; -} - -/* -============ -idMatX::QR_Rotate - - Performs a Jacobi rotation on the rows i and i+1 of the unpacked QR factors. -============ -*/ -void idMatX::QR_Rotate( idMatX &R, int i, float a, float b ) { - int j; - float f, c, s, w, y; - - if ( a == 0.0f ) { - c = 0.0f; - s = ( b >= 0.0f ) ? 1.0f : -1.0f; - } else if ( idMath::Fabs( a ) > idMath::Fabs( b ) ) { - f = b / a; - c = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) ); - if ( a < 0.0f ) { - c = -c; - } - s = f * c; - } else { - f = a / b; - s = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) ); - if ( b < 0.0f ) { - s = -s; - } - c = f * s; - } - for ( j = i; j < numRows; j++ ) { - y = R[i][j]; - w = R[i+1][j]; - R[i][j] = c * y - s * w; - R[i+1][j] = s * y + c * w; - } - for ( j = 0; j < numRows; j++ ) { - y = (*this)[j][i]; - w = (*this)[j][i+1]; - (*this)[j][i] = c * y - s * w; - (*this)[j][i+1] = s * y + c * w; - } -} - -/* -============ -idMatX::QR_UpdateRankOne - - Updates the unpacked QR factorization to obtain the factors for the matrix: QR + alpha * v * w' -============ -*/ -bool idMatX::QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha ) { - int i, k; - float f; - idVecX u; - - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - - u.SetData( v.GetSize(), VECX_ALLOCA( v.GetSize() ) ); - TransposeMultiply( u, v ); - u *= alpha; - - for ( k = v.GetSize()-1; k > 0; k-- ) { - if ( u[k] != 0.0f ) { - break; - } - } - for ( i = k-1; i >= 0; i-- ) { - QR_Rotate( R, i, u[i], -u[i+1] ); - if ( u[i] == 0.0f ) { - u[i] = idMath::Fabs( u[i+1] ); - } else if ( idMath::Fabs( u[i] ) > idMath::Fabs( u[i+1] ) ) { - f = u[i+1] / u[i]; - u[i] = idMath::Fabs( u[i] ) * idMath::Sqrt( 1.0f + f * f ); - } else { - f = u[i] / u[i+1]; - u[i] = idMath::Fabs( u[i+1] ) * idMath::Sqrt( 1.0f + f * f ); - } - } - for ( i = 0; i < v.GetSize(); i++ ) { - R[0][i] += u[0] * w[i]; - } - for ( i = 0; i < k; i++ ) { - QR_Rotate( R, i, -R[i][i], R[i+1][i] ); - } - return true; -} - -/* -============ -idMatX::QR_UpdateRowColumn - - Updates the unpacked QR factorization to obtain the factors for the matrix: - - [ 0 a 0 ] - QR + [ d b e ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1] -============ -*/ -bool idMatX::QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r ) { - idVecX s; - - assert( v.GetSize() >= numColumns ); - assert( w.GetSize() >= numRows ); - assert( r >= 0 && r < numRows && r < numColumns ); - assert( w[r] == 0.0f ); - - s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) ); - s.Zero(); - s[r] = 1.0f; - - if ( !QR_UpdateRankOne( R, v, s, 1.0f ) ) { - return false; - } - if ( !QR_UpdateRankOne( R, s, w, 1.0f ) ) { - return false; - } - return true; -} - -/* -============ -idMatX::QR_UpdateIncrement - - Updates the unpacked QR factorization to obtain the factors for the matrix: - - [ A a ] - [ c b ] - - where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0 -============ -*/ -bool idMatX::QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w ) { - idVecX v2; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - assert( w.GetSize() >= numColumns+1 ); - - ChangeSize( numRows+1, numColumns+1, true ); - (*this)[numRows-1][numRows-1] = 1.0f; - - R.ChangeSize( R.numRows+1, R.numColumns+1, true ); - R[R.numRows-1][R.numRows-1] = 1.0f; - - v2.SetData( numRows, VECX_ALLOCA( numRows ) ); - v2 = v; - v2[numRows-1] -= 1.0f; - - return QR_UpdateRowColumn( R, v2, w, numRows-1 ); -} - -/* -============ -idMatX::QR_UpdateDecrement - - Updates the unpacked QR factorization to obtain the factors for the matrix with row r and column r removed. - v and w should store the column and row of the original matrix respectively. -============ -*/ -bool idMatX::QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r ) { - idVecX v1, w1; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( w.GetSize() >= numColumns ); - assert( r >= 0 && r < numRows && r < numColumns ); - - v1.SetData( numRows, VECX_ALLOCA( numRows ) ); - w1.SetData( numRows, VECX_ALLOCA( numRows ) ); - - // update the row and column to identity - v1 = -v; - w1 = -w; - v1[r] += 1.0f; - w1[r] = 0.0f; - - if ( !QR_UpdateRowColumn( R, v1, w1, r ) ) { - return false; - } - - // physically remove the row and column - Update_Decrement( r ); - R.Update_Decrement( r ); - - return true; -} - -/* -============ -idMatX::QR_Solve - - Solve Ax = b with A factored in-place as: QR -============ -*/ -void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const { - int i, j; - double sum, t; - - assert( numRows == numColumns ); - assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); - assert( c.GetSize() >= numRows && d.GetSize() >= numRows ); - - for ( i = 0; i < numRows; i++ ) { - x[i] = b[i]; - } - - // multiply b with transpose of Q - for ( i = 0; i < numRows-1; i++ ) { - - sum = 0.0f; - for ( j = i; j < numRows; j++ ) { - sum += (*this)[j][i] * x[j]; - } - t = sum / c[i]; - for ( j = i; j < numRows; j++ ) { - x[j] -= t * (*this)[j][i]; - } - } - - // backsubstitution with R - for ( i = numRows-1; i >= 0; i-- ) { - - sum = x[i]; - for ( j = i + 1; j < numRows; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum / d[i]; - } -} - -/* -============ -idMatX::QR_Solve - - Solve Ax = b with A factored as: QR -============ -*/ -void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const { - int i, j; - double sum; - - assert( numRows == numColumns ); - - // multiply b with transpose of Q - TransposeMultiply( x, b ); - - // backsubstitution with R - for ( i = numRows-1; i >= 0; i-- ) { - - sum = x[i]; - for ( j = i + 1; j < numRows; j++ ) { - sum -= R[i][j] * x[j]; - } - x[i] = sum / R[i][i]; - } -} - -/* -============ -idMatX::QR_Inverse - - Calculates the inverse of the matrix which is factored in-place as: QR -============ -*/ -void idMatX::QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const { - int i, j; - idVecX x, b; - - assert( numRows == numColumns ); - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - inv.SetSize( numRows, numColumns ); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - QR_Solve( x, b, c, d ); - for ( j = 0; j < numRows; j++ ) { - inv[j][i] = x[j]; - } - b[i] = 0.0f; - } -} - -/* -============ -idMatX::QR_UnpackFactors - - Unpacks the in-place QR factorization. -============ -*/ -void idMatX::QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const { - int i, j, k; - double sum; - - Q.Identity( numRows, numColumns ); - for ( i = 0; i < numColumns-1; i++ ) { - if ( c[i] == 0.0f ) { - continue; - } - for ( j = 0; j < numRows; j++ ) { - sum = 0.0f; - for ( k = i; k < numColumns; k++ ) { - sum += (*this)[k][i] * Q[j][k]; - } - sum /= c[i]; - for ( k = i; k < numColumns; k++ ) { - Q[j][k] -= sum * (*this)[k][i]; - } - } - } - - R.Zero( numRows, numColumns ); - for ( i = 0; i < numRows; i++ ) { - R[i][i] = d[i]; - for ( j = i+1; j < numColumns; j++ ) { - R[i][j] = (*this)[i][j]; - } - } -} - -/* -============ -idMatX::QR_MultiplyFactors - - Multiplies the factors of the in-place QR factorization to form the original matrix. -============ -*/ -void idMatX::QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const { - int i, j, k; - double sum; - idMatX Q; - - Q.Identity( numRows, numColumns ); - for ( i = 0; i < numColumns-1; i++ ) { - if ( c[i] == 0.0f ) { - continue; - } - for ( j = 0; j < numRows; j++ ) { - sum = 0.0f; - for ( k = i; k < numColumns; k++ ) { - sum += (*this)[k][i] * Q[j][k]; - } - sum /= c[i]; - for ( k = i; k < numColumns; k++ ) { - Q[j][k] -= sum * (*this)[k][i]; - } - } - } - - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - sum = Q[i][j] * d[i]; - for ( k = 0; k < i; k++ ) { - sum += Q[i][k] * (*this)[j][k]; - } - m[i][j] = sum; - } - } -} - -/* -============ -idMatX::Pythag - - Computes (a^2 + b^2)^1/2 without underflow or overflow. -============ -*/ -float idMatX::Pythag( float a, float b ) const { - double at, bt, ct; - - at = idMath::Fabs( a ); - bt = idMath::Fabs( b ); - if ( at > bt ) { - ct = bt / at; - return at * idMath::Sqrt( 1.0f + ct * ct ); - } else { - if ( bt ) { - ct = at / bt; - return bt * idMath::Sqrt( 1.0f + ct * ct ); - } else { - return 0.0f; - } - } -} - -/* -============ -idMatX::SVD_BiDiag -============ -*/ -void idMatX::SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm ) { - int i, j, k, l; - double f, h, r, g, s, scale; - - anorm = 0.0f; - g = s = scale = 0.0f; - for ( i = 0; i < numColumns; i++ ) { - l = i + 1; - rv1[i] = scale * g; - g = s = scale = 0.0f; - if ( i < numRows ) { - for ( k = i; k < numRows; k++ ) { - scale += idMath::Fabs( (*this)[k][i] ); - } - if ( scale ) { - for ( k = i; k < numRows; k++ ) { - (*this)[k][i] /= scale; - s += (*this)[k][i] * (*this)[k][i]; - } - f = (*this)[i][i]; - g = idMath::Sqrt( s ); - if ( f >= 0.0f ) { - g = -g; - } - h = f * g - s; - (*this)[i][i] = f - g; - if ( i != (numColumns-1) ) { - for ( j = l; j < numColumns; j++ ) { - for ( s = 0.0f, k = i; k < numRows; k++ ) { - s += (*this)[k][i] * (*this)[k][j]; - } - f = s / h; - for ( k = i; k < numRows; k++ ) { - (*this)[k][j] += f * (*this)[k][i]; - } - } - } - for ( k = i; k < numRows; k++ ) { - (*this)[k][i] *= scale; - } - } - } - w[i] = scale * g; - g = s = scale = 0.0f; - if ( i < numRows && i != (numColumns-1) ) { - for ( k = l; k < numColumns; k++ ) { - scale += idMath::Fabs( (*this)[i][k] ); - } - if ( scale ) { - for ( k = l; k < numColumns; k++ ) { - (*this)[i][k] /= scale; - s += (*this)[i][k] * (*this)[i][k]; - } - f = (*this)[i][l]; - g = idMath::Sqrt( s ); - if ( f >= 0.0f ) { - g = -g; - } - h = 1.0f / ( f * g - s ); - (*this)[i][l] = f - g; - for ( k = l; k < numColumns; k++ ) { - rv1[k] = (*this)[i][k] * h; - } - if ( i != (numRows-1) ) { - for ( j = l; j < numRows; j++ ) { - for ( s = 0.0f, k = l; k < numColumns; k++ ) { - s += (*this)[j][k] * (*this)[i][k]; - } - for ( k = l; k < numColumns; k++ ) { - (*this)[j][k] += s * rv1[k]; - } - } - } - for ( k = l; k < numColumns; k++ ) { - (*this)[i][k] *= scale; - } - } - } - r = idMath::Fabs( w[i] ) + idMath::Fabs( rv1[i] ); - if ( r > anorm ) { - anorm = r; - } - } -} - -/* -============ -idMatX::SVD_InitialWV -============ -*/ -void idMatX::SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 ) { - int i, j, k, l; - double f, g, s; - - g = 0.0f; - for ( i = (numColumns-1); i >= 0; i-- ) { - l = i + 1; - if ( i < ( numColumns - 1 ) ) { - if ( g ) { - for ( j = l; j < numColumns; j++ ) { - V[j][i] = ((*this)[i][j] / (*this)[i][l]) / g; - } - // double division to reduce underflow - for ( j = l; j < numColumns; j++ ) { - for ( s = 0.0f, k = l; k < numColumns; k++ ) { - s += (*this)[i][k] * V[k][j]; - } - for ( k = l; k < numColumns; k++ ) { - V[k][j] += s * V[k][i]; - } - } - } - for ( j = l; j < numColumns; j++ ) { - V[i][j] = V[j][i] = 0.0f; - } - } - V[i][i] = 1.0f; - g = rv1[i]; - } - for ( i = numColumns - 1 ; i >= 0; i-- ) { - l = i + 1; - g = w[i]; - if ( i < (numColumns-1) ) { - for ( j = l; j < numColumns; j++ ) { - (*this)[i][j] = 0.0f; - } - } - if ( g ) { - g = 1.0f / g; - if ( i != (numColumns-1) ) { - for ( j = l; j < numColumns; j++ ) { - for ( s = 0.0f, k = l; k < numRows; k++ ) { - s += (*this)[k][i] * (*this)[k][j]; - } - f = (s / (*this)[i][i]) * g; - for ( k = i; k < numRows; k++ ) { - (*this)[k][j] += f * (*this)[k][i]; - } - } - } - for ( j = i; j < numRows; j++ ) { - (*this)[j][i] *= g; - } - } - else { - for ( j = i; j < numRows; j++ ) { - (*this)[j][i] = 0.0f; - } - } - (*this)[i][i] += 1.0f; - } -} - -/* -============ -idMatX::SVD_Factor - - in-place factorization: U * Diag(w) * V.Transpose() - known as the Singular Value Decomposition. - U is a column-orthogonal matrix which overwrites the original matrix. - w is a diagonal matrix with all elements >= 0 which are the singular values. - V is the transpose of an orthogonal matrix. -============ -*/ -bool idMatX::SVD_Factor( idVecX &w, idMatX &V ) { - int flag, i, its, j, jj, k, l, nm; - double c, f, h, s, x, y, z, r, g = 0.0f; - float anorm = 0.0f; - idVecX rv1; - - if ( numRows < numColumns ) { - return false; - } - - rv1.SetData( numColumns, VECX_ALLOCA( numColumns ) ); - rv1.Zero(); - w.Zero( numColumns ); - V.Zero( numColumns, numColumns ); - - SVD_BiDiag( w, rv1, anorm ); - SVD_InitialWV( w, V, rv1 ); - - for ( k = numColumns - 1; k >= 0; k-- ) { - for ( its = 1; its <= 30; its++ ) { - flag = 1; - nm = 0; - for ( l = k; l >= 0; l-- ) { - nm = l - 1; - if ( ( idMath::Fabs( rv1[l] ) + anorm ) == anorm /* idMath::Fabs( rv1[l] ) < idMath::FLT_EPSILON */ ) { - flag = 0; - break; - } - if ( ( idMath::Fabs( w[nm] ) + anorm ) == anorm /* idMath::Fabs( w[nm] ) < idMath::FLT_EPSILON */ ) { - break; - } - } - if ( flag ) { - c = 0.0f; - s = 1.0f; - for ( i = l; i <= k; i++ ) { - f = s * rv1[i]; - - if ( ( idMath::Fabs( f ) + anorm ) != anorm /* idMath::Fabs( f ) > idMath::FLT_EPSILON */ ) { - g = w[i]; - h = Pythag( f, g ); - w[i] = h; - h = 1.0f / h; - c = g * h; - s = -f * h; - for ( j = 0; j < numRows; j++ ) { - y = (*this)[j][nm]; - z = (*this)[j][i]; - (*this)[j][nm] = y * c + z * s; - (*this)[j][i] = z * c - y * s; - } - } - } - } - z = w[k]; - if ( l == k ) { - if ( z < 0.0f ) { - w[k] = -z; - for ( j = 0; j < numColumns; j++ ) { - V[j][k] = -V[j][k]; - } - } - break; - } - if ( its == 30 ) { - return false; // no convergence - } - x = w[l]; - nm = k - 1; - y = w[nm]; - g = rv1[nm]; - h = rv1[k]; - f = ( ( y - z ) * ( y + z ) + ( g - h ) * ( g + h ) ) / ( 2.0f * h * y ); - g = Pythag( f, 1.0f ); - r = ( f >= 0.0f ? g : - g ); - f= ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + r ) ) - h ) ) / x; - c = s = 1.0f; - for ( j = l; j <= nm; j++ ) { - i = j + 1; - g = rv1[i]; - y = w[i]; - h = s * g; - g = c * g; - z = Pythag( f, h ); - rv1[j] = z; - c = f / z; - s = h / z; - f = x * c + g * s; - g = g * c - x * s; - h = y * s; - y = y * c; - for ( jj = 0; jj < numColumns; jj++ ) { - x = V[jj][j]; - z = V[jj][i]; - V[jj][j] = x * c + z * s; - V[jj][i] = z * c - x * s; - } - z = Pythag( f, h ); - w[j] = z; - if ( z ) { - z = 1.0f / z; - c = f * z; - s = h * z; - } - f = ( c * g ) + ( s * y ); - x = ( c * y ) - ( s * g ); - for ( jj = 0; jj < numRows; jj++ ) { - y = (*this)[jj][j]; - z = (*this)[jj][i]; - (*this)[jj][j] = y * c + z * s; - (*this)[jj][i] = z * c - y * s; - } - } - rv1[l] = 0.0f; - rv1[k] = f; - w[k] = x; - } - } - return true; -} - -/* -============ -idMatX::SVD_Solve - - Solve Ax = b with A factored as: U * Diag(w) * V.Transpose() -============ -*/ -void idMatX::SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const { - int i, j; - double sum; - idVecX tmp; - - assert( x.GetSize() >= numColumns ); - assert( b.GetSize() >= numColumns ); - assert( w.GetSize() == numColumns ); - assert( V.GetNumRows() == numColumns && V.GetNumColumns() == numColumns ); - - tmp.SetData( numColumns, VECX_ALLOCA( numColumns ) ); - - for ( i = 0; i < numColumns; i++ ) { - sum = 0.0f; - if ( w[i] >= idMath::FLT_EPSILON ) { - for ( j = 0; j < numRows; j++ ) { - sum += (*this)[j][i] * b[j]; - } - sum /= w[i]; - } - tmp[i] = sum; - } - for ( i = 0; i < numColumns; i++ ) { - sum = 0.0f; - for ( j = 0; j < numColumns; j++ ) { - sum += V[i][j] * tmp[j]; - } - x[i] = sum; - } -} - -/* -============ -idMatX::SVD_Inverse - - Calculates the inverse of the matrix which is factored in-place as: U * Diag(w) * V.Transpose() -============ -*/ -void idMatX::SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const { - int i, j, k; - double wi, sum; - idMatX V2; - - assert( numRows == numColumns ); - - V2 = V; - - // V * [diag(1/w[i])] - for ( i = 0; i < numRows; i++ ) { - wi = w[i]; - wi = ( wi < idMath::FLT_EPSILON ) ? 0.0f : 1.0f / wi; - for ( j = 0; j < numColumns; j++ ) { - V2[j][i] *= wi; - } - } - - // V * [diag(1/w[i])] * Ut - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - sum = V2[i][0] * (*this)[j][0]; - for ( k = 1; k < numColumns; k++ ) { - sum += V2[i][k] * (*this)[j][k]; - } - inv[i][j] = sum; - } - } -} - -/* -============ -idMatX::SVD_MultiplyFactors - - Multiplies the factors of the in-place SVD factorization to form the original matrix. -============ -*/ -void idMatX::SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const { - int r, i, j; - double sum; - - m.SetSize( numRows, V.GetNumRows() ); - - for ( r = 0; r < numRows; r++ ) { - // calculate row of matrix - if ( w[r] >= idMath::FLT_EPSILON ) { - for ( i = 0; i < V.GetNumRows(); i++ ) { - sum = 0.0f; - for ( j = 0; j < numColumns; j++ ) { - sum += (*this)[r][j] * V[i][j]; - } - m[r][i] = sum * w[r]; - } - } else { - for ( i = 0; i < V.GetNumRows(); i++ ) { - m[r][i] = 0.0f; - } - } - } -} - -/* -============ -idMatX::Cholesky_Factor - - in-place Cholesky factorization: LL' - L is a triangular matrix stored in the lower triangle. - The upper triangle is not cleared. - The initial matrix has to be symmetric positive definite. -============ -*/ -bool idMatX::Cholesky_Factor( void ) { - int i, j, k; - float *invSqrt; - double sum; - - assert( numRows == numColumns ); - - invSqrt = (float *) _alloca16( numRows * sizeof( float ) ); - - for ( i = 0; i < numRows; i++ ) { - - for ( j = 0; j < i; j++ ) { - - sum = (*this)[i][j]; - for ( k = 0; k < j; k++ ) { - sum -= (*this)[i][k] * (*this)[j][k]; - } - (*this)[i][j] = sum * invSqrt[j]; - } - - sum = (*this)[i][i]; - for ( k = 0; k < i; k++ ) { - sum -= (*this)[i][k] * (*this)[i][k]; - } - - if ( sum <= 0.0f ) { - return false; - } - - invSqrt[i] = idMath::InvSqrt( sum ); - (*this)[i][i] = invSqrt[i] * sum; - } - return true; -} - -/* -============ -idMatX::Cholesky_UpdateRankOne - - Updates the in-place Cholesky factorization to obtain the factors for the matrix: LL' + alpha * v * v' - If offset > 0 only the lower right corner starting at (offset, offset) is updated. -============ -*/ -bool idMatX::Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset ) { - int i, j; - float *y; - double diag, invDiag, diagSqr, newDiag, newDiagSqr, beta, p, d; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( offset >= 0 && offset < numRows ); - - y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); - memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); - - for ( i = offset; i < numColumns; i++ ) { - p = y[i]; - diag = (*this)[i][i]; - invDiag = 1.0f / diag; - diagSqr = diag * diag; - newDiagSqr = diagSqr + alpha * p * p; - - if ( newDiagSqr <= 0.0f ) { - return false; - } - - (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr ); - - alpha /= newDiagSqr; - beta = p * alpha; - alpha *= diagSqr; - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i] * invDiag; - - y[j] -= p * d; - d += beta * y[j]; - - (*this)[j][i] = d * newDiag; - } - } - return true; -} - -/* -============ -idMatX::Cholesky_UpdateRowColumn - - Updates the in-place Cholesky factorization to obtain the factors for the matrix: - - [ 0 a 0 ] - LL' + [ a b c ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] -============ -*/ -#pragma optimize( "", off ) - -bool idMatX::Cholesky_UpdateRowColumn( const idVecX &v, int r ) { - int i, j; - double sum; - float *original, *y; - idVecX addSub; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( r >= 0 && r < numRows ); - - addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - - if ( r == 0 ) { - - if ( numColumns == 1 ) { - double v0 = v[0]; - sum = (*this)[0][0]; - sum = sum * sum; - sum = sum + v0; - if ( sum <= 0.0f ) { - return false; - } - (*this)[0][0] = idMath::Sqrt( sum ); - return true; - } - for ( i = 0; i < numColumns; i++ ) { - addSub[i] = v[i]; - } - - } else { - - original = (float *) _alloca16( numColumns * sizeof( float ) ); - y = (float *) _alloca16( numColumns * sizeof( float ) ); - - // calculate original row/column of matrix - for ( i = 0; i < numRows; i++ ) { - sum = 0.0f; - for ( j = 0; j <= i; j++ ) { - sum += (*this)[r][j] * (*this)[i][j]; - } - original[i] = sum; - } - - // solve for y in L * y = original + v - for ( i = 0; i < r; i++ ) { - sum = original[i] + v[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[r][j] * (*this)[i][j]; - } - (*this)[r][i] = sum / (*this)[i][i]; - } - - // if the last row/column of the matrix is updated - if ( r == numColumns - 1 ) { - // only calculate new diagonal - sum = original[r] + v[r]; - for ( j = 0; j < r; j++) { - sum -= (*this)[r][j] * (*this)[r][j]; - } - if ( sum <= 0.0f ) { - return false; - } - (*this)[r][r] = idMath::Sqrt( sum ); - return true; - } - - // calculate the row/column to be added to the lower right sub matrix starting at (r, r) - for ( i = r; i < numColumns; i++ ) { - sum = 0.0f; - for ( j = 0; j <= r; j++ ) { - sum += (*this)[r][j] * (*this)[i][j]; - } - addSub[i] = v[i] - ( sum - original[i] ); - } - } - - // add row/column to the lower right sub matrix starting at (r, r) - -#if 0 - - idVecX v1, v2; - double d; - - v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - - d = idMath::SQRT_1OVER2; - v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; - v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; - for ( i = r+1; i < numColumns; i++ ) { - v1[i] = v2[i] = addSub[i] * d; - } - - // update - if ( !Cholesky_UpdateRankOne( v1, 1.0f, r ) ) { - return false; - } - // downdate - if ( !Cholesky_UpdateRankOne( v2, -1.0f, r ) ) { - return false; - } - -#else - - float *v1, *v2; - double diag, invDiag, diagSqr, newDiag, newDiagSqr; - double alpha1, alpha2, beta1, beta2, p1, p2, d; - - v1 = (float *) _alloca16( numColumns * sizeof( float ) ); - v2 = (float *) _alloca16( numColumns * sizeof( float ) ); - - d = idMath::SQRT_1OVER2; - v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; - v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; - for ( i = r+1; i < numColumns; i++ ) { - v1[i] = v2[i] = addSub[i] * d; - } - - alpha1 = 1.0f; - alpha2 = -1.0f; - - // simultaneous update/downdate of the sub matrix starting at (r, r) - for ( i = r; i < numColumns; i++ ) { - p1 = v1[i]; - diag = (*this)[i][i]; - invDiag = 1.0f / diag; - diagSqr = diag * diag; - newDiagSqr = diagSqr + alpha1 * p1 * p1; - - if ( newDiagSqr <= 0.0f ) { - return false; - } - - alpha1 /= newDiagSqr; - beta1 = p1 * alpha1; - alpha1 *= diagSqr; - - p2 = v2[i]; - diagSqr = newDiagSqr; - newDiagSqr = diagSqr + alpha2 * p2 * p2; - - if ( newDiagSqr <= 0.0f ) { - return false; - } - - (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr ); - - alpha2 /= newDiagSqr; - beta2 = p2 * alpha2; - alpha2 *= diagSqr; - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i] * invDiag; - - v1[j] -= p1 * d; - d += beta1 * v1[j]; - - v2[j] -= p2 * d; - d += beta2 * v2[j]; - - (*this)[j][i] = d * newDiag; - } - } - -#endif - - return true; -} - -#pragma optimize( "", off ) - -/* -============ -idMatX::Cholesky_UpdateIncrement - - Updates the in-place Cholesky factorization to obtain the factors for the matrix: - - [ A a ] - [ a b ] - - where: a = v[0,numRows-1], b = v[numRows] -============ -*/ -bool idMatX::Cholesky_UpdateIncrement( const idVecX &v ) { - int i, j; - float *x; - double sum; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - - ChangeSize( numRows+1, numColumns+1, false ); - - x = (float *) _alloca16( numRows * sizeof( float ) ); - - // solve for x in L * x = v - for ( i = 0; i < numRows - 1; i++ ) { - sum = v[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum / (*this)[i][i]; - } - - // calculate new row of L and calculate the square of the diagonal entry - sum = v[numRows - 1]; - for ( i = 0; i < numRows - 1; i++ ) { - (*this)[numRows - 1][i] = x[i]; - sum -= x[i] * x[i]; - } - - if ( sum <= 0.0f ) { - return false; - } - - // store the diagonal entry - (*this)[numRows - 1][numRows - 1] = idMath::Sqrt( sum ); - - return true; -} - -/* -============ -idMatX::Cholesky_UpdateDecrement - - Updates the in-place Cholesky factorization to obtain the factors for the matrix with row r and column r removed. - v should store the row of the original matrix. -============ -*/ -bool idMatX::Cholesky_UpdateDecrement( const idVecX &v, int r ) { - idVecX v1; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( r >= 0 && r < numRows ); - - v1.SetData( numRows, VECX_ALLOCA( numRows ) ); - - // update the row and column to identity - v1 = -v; - v1[r] += 1.0f; - - // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay - // untouched when calling Cholesky_UpdateRowColumn in the if statement -#if 0 - if ( !Cholesky_UpdateRowColumn( v1, r ) ) { -#else - bool ret = Cholesky_UpdateRowColumn( v1, r ); - if ( !ret ) { -#endif - return false; - } - - // physically remove the row and column - Update_Decrement( r ); - - return true; -} - -/* -============ -idMatX::Cholesky_Solve - - Solve Ax = b with A factored in-place as: LL' -============ -*/ -void idMatX::Cholesky_Solve( idVecX &x, const idVecX &b ) const { - int i, j; - double sum; - - assert( numRows == numColumns ); - assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); - - // solve L - for ( i = 0; i < numRows; i++ ) { - sum = b[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum / (*this)[i][i]; - } - - // solve Lt - for ( i = numRows - 1; i >= 0; i-- ) { - sum = x[i]; - for ( j = i + 1; j < numRows; j++ ) { - sum -= (*this)[j][i] * x[j]; - } - x[i] = sum / (*this)[i][i]; - } -} - -/* -============ -idMatX::Cholesky_Inverse - - Calculates the inverse of the matrix which is factored in-place as: LL' -============ -*/ -void idMatX::Cholesky_Inverse( idMatX &inv ) const { - int i, j; - idVecX x, b; - - assert( numRows == numColumns ); - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - inv.SetSize( numRows, numColumns ); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - Cholesky_Solve( x, b ); - for ( j = 0; j < numRows; j++ ) { - inv[j][i] = x[j]; - } - b[i] = 0.0f; - } -} - -/* -============ -idMatX::Cholesky_MultiplyFactors - - Multiplies the factors of the in-place Cholesky factorization to form the original matrix. -============ -*/ -void idMatX::Cholesky_MultiplyFactors( idMatX &m ) const { - int r, i, j; - double sum; - - m.SetSize( numRows, numColumns ); - - for ( r = 0; r < numRows; r++ ) { - - // calculate row of matrix - for ( i = 0; i < numRows; i++ ) { - sum = 0.0f; - for ( j = 0; j <= i && j <= r; j++ ) { - sum += (*this)[r][j] * (*this)[i][j]; - } - m[r][i] = sum; - } - } -} - -/* -============ -idMatX::LDLT_Factor - - in-place factorization: LDL' - L is a triangular matrix stored in the lower triangle. - L has ones on the diagonal that are not stored. - D is a diagonal matrix stored on the diagonal. - The upper triangle is not cleared. - The initial matrix has to be symmetric. -============ -*/ -bool idMatX::LDLT_Factor( void ) { - int i, j, k; - float *v; - double d, sum; - - assert( numRows == numColumns ); - - v = (float *) _alloca16( numRows * sizeof( float ) ); - - for ( i = 0; i < numRows; i++ ) { - - sum = (*this)[i][i]; - for ( j = 0; j < i; j++ ) { - d = (*this)[i][j]; - v[j] = (*this)[j][j] * d; - sum -= v[j] * d; - } - - if ( sum == 0.0f ) { - return false; - } - - (*this)[i][i] = sum; - d = 1.0f / sum; - - for ( j = i + 1; j < numRows; j++ ) { - sum = (*this)[j][i]; - for ( k = 0; k < i; k++ ) { - sum -= (*this)[j][k] * v[k]; - } - (*this)[j][i] = sum * d; - } - } - - return true; -} - -/* -============ -idMatX::LDLT_UpdateRankOne - - Updates the in-place LDL' factorization to obtain the factors for the matrix: LDL' + alpha * v * v' - If offset > 0 only the lower right corner starting at (offset, offset) is updated. -============ -*/ -bool idMatX::LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset ) { - int i, j; - float *y; - double diag, newDiag, beta, p, d; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( offset >= 0 && offset < numRows ); - - y = (float *) _alloca16( v.GetSize() * sizeof( float ) ); - memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) ); - - for ( i = offset; i < numColumns; i++ ) { - p = y[i]; - diag = (*this)[i][i]; - (*this)[i][i] = newDiag = diag + alpha * p * p; - - if ( newDiag == 0.0f ) { - return false; - } - - alpha /= newDiag; - beta = p * alpha; - alpha *= diag; - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i]; - - y[j] -= p * d; - d += beta * y[j]; - - (*this)[j][i] = d; - } - } - - return true; -} - -/* -============ -idMatX::LDLT_UpdateRowColumn - - Updates the in-place LDL' factorization to obtain the factors for the matrix: - - [ 0 a 0 ] - LDL' + [ a b c ] - [ 0 c 0 ] - - where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1] -============ -*/ -bool idMatX::LDLT_UpdateRowColumn( const idVecX &v, int r ) { - int i, j; - double sum; - float *original, *y; - idVecX addSub; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( r >= 0 && r < numRows ); - - addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - - if ( r == 0 ) { - - if ( numColumns == 1 ) { - (*this)[0][0] += v[0]; - return true; - } - for ( i = 0; i < numColumns; i++ ) { - addSub[i] = v[i]; - } - - } else { - - original = (float *) _alloca16( numColumns * sizeof( float ) ); - y = (float *) _alloca16( numColumns * sizeof( float ) ); - - // calculate original row/column of matrix - for ( i = 0; i < r; i++ ) { - y[i] = (*this)[r][i] * (*this)[i][i]; - } - for ( i = 0; i < numColumns; i++ ) { - if ( i < r ) { - sum = (*this)[i][i] * (*this)[r][i]; - } else if ( i == r ) { - sum = (*this)[r][r]; - } else { - sum = (*this)[r][r] * (*this)[i][r]; - } - for ( j = 0; j < i && j < r; j++ ) { - sum += (*this)[i][j] * y[j]; - } - original[i] = sum; - } - - // solve for y in L * y = original + v - for ( i = 0; i < r; i++ ) { - sum = original[i] + v[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * y[j]; - } - y[i] = sum; - } - - // calculate new row of L - for ( i = 0; i < r; i++ ) { - (*this)[r][i] = y[i] / (*this)[i][i]; - } - - // if the last row/column of the matrix is updated - if ( r == numColumns - 1 ) { - // only calculate new diagonal - sum = original[r] + v[r]; - for ( j = 0; j < r; j++ ) { - sum -= (*this)[r][j] * y[j]; - } - if ( sum == 0.0f ) { - return false; - } - (*this)[r][r] = sum; - return true; - } - - // calculate the row/column to be added to the lower right sub matrix starting at (r, r) - for ( i = 0; i < r; i++ ) { - y[i] = (*this)[r][i] * (*this)[i][i]; - } - for ( i = r; i < numColumns; i++ ) { - if ( i == r ) { - sum = (*this)[r][r]; - } else { - sum = (*this)[r][r] * (*this)[i][r]; - } - for ( j = 0; j < r; j++ ) { - sum += (*this)[i][j] * y[j]; - } - addSub[i] = v[i] - ( sum - original[i] ); - } - } - - // add row/column to the lower right sub matrix starting at (r, r) - -#if 0 - - idVecX v1, v2; - double d; - - v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) ); - - d = idMath::SQRT_1OVER2; - v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; - v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; - for ( i = r+1; i < numColumns; i++ ) { - v1[i] = v2[i] = addSub[i] * d; - } - - // update - if ( !LDLT_UpdateRankOne( v1, 1.0f, r ) ) { - return false; - } - // downdate - if ( !LDLT_UpdateRankOne( v2, -1.0f, r ) ) { - return false; - } - -#else - - float *v1, *v2; - double d, diag, newDiag, p1, p2, alpha1, alpha2, beta1, beta2; - - v1 = (float *) _alloca16( numColumns * sizeof( float ) ); - v2 = (float *) _alloca16( numColumns * sizeof( float ) ); - - d = idMath::SQRT_1OVER2; - v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d; - v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d; - for ( i = r+1; i < numColumns; i++ ) { - v1[i] = v2[i] = addSub[i] * d; - } - - alpha1 = 1.0f; - alpha2 = -1.0f; - - // simultaneous update/downdate of the sub matrix starting at (r, r) - for ( i = r; i < numColumns; i++ ) { - - diag = (*this)[i][i]; - p1 = v1[i]; - newDiag = diag + alpha1 * p1 * p1; - - if ( newDiag == 0.0f ) { - return false; - } - - alpha1 /= newDiag; - beta1 = p1 * alpha1; - alpha1 *= diag; - - diag = newDiag; - p2 = v2[i]; - newDiag = diag + alpha2 * p2 * p2; - - if ( newDiag == 0.0f ) { - return false; - } - - alpha2 /= newDiag; - beta2 = p2 * alpha2; - alpha2 *= diag; - - (*this)[i][i] = newDiag; - - for ( j = i+1; j < numRows; j++ ) { - - d = (*this)[j][i]; - - v1[j] -= p1 * d; - d += beta1 * v1[j]; - - v2[j] -= p2 * d; - d += beta2 * v2[j]; - - (*this)[j][i] = d; - } - } - -#endif - - return true; -} - -/* -============ -idMatX::LDLT_UpdateIncrement - - Updates the in-place LDL' factorization to obtain the factors for the matrix: - - [ A a ] - [ a b ] - - where: a = v[0,numRows-1], b = v[numRows] -============ -*/ -bool idMatX::LDLT_UpdateIncrement( const idVecX &v ) { - int i, j; - float *x; - double sum, d; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows+1 ); - - ChangeSize( numRows+1, numColumns+1, false ); - - x = (float *) _alloca16( numRows * sizeof( float ) ); - - // solve for x in L * x = v - for ( i = 0; i < numRows - 1; i++ ) { - sum = v[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum; - } - - // calculate new row of L and calculate the diagonal entry - sum = v[numRows - 1]; - for ( i = 0; i < numRows - 1; i++ ) { - (*this)[numRows - 1][i] = d = x[i] / (*this)[i][i]; - sum -= d * x[i]; - } - - if ( sum == 0.0f ) { - return false; - } - - // store the diagonal entry - (*this)[numRows - 1][numRows - 1] = sum; - - return true; -} - -/* -============ -idMatX::LDLT_UpdateDecrement - - Updates the in-place LDL' factorization to obtain the factors for the matrix with row r and column r removed. - v should store the row of the original matrix. -============ -*/ -bool idMatX::LDLT_UpdateDecrement( const idVecX &v, int r ) { - idVecX v1; - - assert( numRows == numColumns ); - assert( v.GetSize() >= numRows ); - assert( r >= 0 && r < numRows ); - - v1.SetData( numRows, VECX_ALLOCA( numRows ) ); - - // update the row and column to identity - v1 = -v; - v1[r] += 1.0f; - - // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay - // untouched when calling LDLT_UpdateRowColumn in the if statement -#if 0 - if ( !LDLT_UpdateRowColumn( v1, r ) ) { -#else - bool ret = LDLT_UpdateRowColumn( v1, r ); - if ( !ret ) { -#endif - return false; - } - - // physically remove the row and column - Update_Decrement( r ); - - return true; -} - -/* -============ -idMatX::LDLT_Solve - - Solve Ax = b with A factored in-place as: LDL' -============ -*/ -void idMatX::LDLT_Solve( idVecX &x, const idVecX &b ) const { - int i, j; - double sum; - - assert( numRows == numColumns ); - assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); - - // solve L - for ( i = 0; i < numRows; i++ ) { - sum = b[i]; - for ( j = 0; j < i; j++ ) { - sum -= (*this)[i][j] * x[j]; - } - x[i] = sum; - } - - // solve D - for ( i = 0; i < numRows; i++ ) { - x[i] /= (*this)[i][i]; - } - - // solve Lt - for ( i = numRows - 2; i >= 0; i-- ) { - sum = x[i]; - for ( j = i + 1; j < numRows; j++ ) { - sum -= (*this)[j][i] * x[j]; - } - x[i] = sum; - } -} - -/* -============ -idMatX::LDLT_Inverse - - Calculates the inverse of the matrix which is factored in-place as: LDL' -============ -*/ -void idMatX::LDLT_Inverse( idMatX &inv ) const { - int i, j; - idVecX x, b; - - assert( numRows == numColumns ); - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - inv.SetSize( numRows, numColumns ); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - LDLT_Solve( x, b ); - for ( j = 0; j < numRows; j++ ) { - inv[j][i] = x[j]; - } - b[i] = 0.0f; - } -} - -/* -============ -idMatX::LDLT_UnpackFactors - - Unpacks the in-place LDL' factorization. -============ -*/ -void idMatX::LDLT_UnpackFactors( idMatX &L, idMatX &D ) const { - int i, j; - - L.Zero( numRows, numColumns ); - D.Zero( numRows, numColumns ); - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < i; j++ ) { - L[i][j] = (*this)[i][j]; - } - L[i][i] = 1.0f; - D[i][i] = (*this)[i][i]; - } -} - -/* -============ -idMatX::LDLT_MultiplyFactors - - Multiplies the factors of the in-place LDL' factorization to form the original matrix. -============ -*/ -void idMatX::LDLT_MultiplyFactors( idMatX &m ) const { - int r, i, j; - float *v; - double sum; - - v = (float *) _alloca16( numRows * sizeof( float ) ); - m.SetSize( numRows, numColumns ); - - for ( r = 0; r < numRows; r++ ) { - - // calculate row of matrix - for ( i = 0; i < r; i++ ) { - v[i] = (*this)[r][i] * (*this)[i][i]; - } - for ( i = 0; i < numColumns; i++ ) { - if ( i < r ) { - sum = (*this)[i][i] * (*this)[r][i]; - } else if ( i == r ) { - sum = (*this)[r][r]; - } else { - sum = (*this)[r][r] * (*this)[i][r]; - } - for ( j = 0; j < i && j < r; j++ ) { - sum += (*this)[i][j] * v[j]; - } - m[r][i] = sum; - } - } -} - -/* -============ -idMatX::TriDiagonal_ClearTriangles -============ -*/ -void idMatX::TriDiagonal_ClearTriangles( void ) { - int i, j; - - assert( numRows == numColumns ); - for ( i = 0; i < numRows-2; i++ ) { - for ( j = i+2; j < numColumns; j++ ) { - (*this)[i][j] = 0.0f; - (*this)[j][i] = 0.0f; - } - } -} - -/* -============ -idMatX::TriDiagonal_Solve - - Solve Ax = b with A being tridiagonal. -============ -*/ -bool idMatX::TriDiagonal_Solve( idVecX &x, const idVecX &b ) const { - int i; - float d; - idVecX tmp; - - assert( numRows == numColumns ); - assert( x.GetSize() >= numRows && b.GetSize() >= numRows ); - - tmp.SetData( numRows, VECX_ALLOCA( numRows ) ); - - d = (*this)[0][0]; - if ( d == 0.0f ) { - return false; - } - d = 1.0f / d; - x[0] = b[0] * d; - for ( i = 1; i < numRows; i++ ) { - tmp[i] = (*this)[i-1][i] * d; - d = (*this)[i][i] - (*this)[i][i-1] * tmp[i]; - if ( d == 0.0f ) { - return false; - } - d = 1.0f / d; - x[i] = ( b[i] - (*this)[i][i-1] * x[i-1] ) * d; - } - for ( i = numRows - 2; i >= 0; i-- ) { - x[i] -= tmp[i+1] * x[i+1]; - } - return true; -} - -/* -============ -idMatX::TriDiagonal_Inverse - - Calculates the inverse of a tri-diagonal matrix. -============ -*/ -void idMatX::TriDiagonal_Inverse( idMatX &inv ) const { - int i, j; - idVecX x, b; - - assert( numRows == numColumns ); - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - inv.SetSize( numRows, numColumns ); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - TriDiagonal_Solve( x, b ); - for ( j = 0; j < numRows; j++ ) { - inv[j][i] = x[j]; - } - b[i] = 0.0f; - } -} - -/* -============ -idMatX::HouseholderReduction - - Householder reduction to symmetric tri-diagonal form. - The original matrix is replaced by an orthogonal matrix effecting the accumulated householder transformations. - The diagonal elements of the diagonal matrix are stored in diag. - The off-diagonal elements of the diagonal matrix are stored in subd. - The initial matrix has to be symmetric. -============ -*/ -void idMatX::HouseholderReduction( idVecX &diag, idVecX &subd ) { - int i0, i1, i2, i3; - float h, f, g, invH, halfFdivH, scale, invScale, sum; - - assert( numRows == numColumns ); - - diag.SetSize( numRows ); - subd.SetSize( numRows ); - - for ( i0 = numRows-1, i3 = numRows-2; i0 >= 1; i0--, i3-- ) { - h = 0.0f; - scale = 0.0f; - - if ( i3 > 0 ) { - for ( i2 = 0; i2 <= i3; i2++ ) { - scale += idMath::Fabs( (*this)[i0][i2] ); - } - if ( scale == 0 ) { - subd[i0] = (*this)[i0][i3]; - } else { - invScale = 1.0f / scale; - for (i2 = 0; i2 <= i3; i2++) - { - (*this)[i0][i2] *= invScale; - h += (*this)[i0][i2] * (*this)[i0][i2]; - } - f = (*this)[i0][i3]; - g = idMath::Sqrt( h ); - if ( f > 0.0f ) { - g = -g; - } - subd[i0] = scale * g; - h -= f * g; - (*this)[i0][i3] = f - g; - f = 0.0f; - invH = 1.0f / h; - for (i1 = 0; i1 <= i3; i1++) { - (*this)[i1][i0] = (*this)[i0][i1] * invH; - g = 0.0f; - for (i2 = 0; i2 <= i1; i2++) { - g += (*this)[i1][i2] * (*this)[i0][i2]; - } - for (i2 = i1+1; i2 <= i3; i2++) { - g += (*this)[i2][i1] * (*this)[i0][i2]; - } - subd[i1] = g * invH; - f += subd[i1] * (*this)[i0][i1]; - } - halfFdivH = 0.5f * f * invH; - for ( i1 = 0; i1 <= i3; i1++ ) { - f = (*this)[i0][i1]; - g = subd[i1] - halfFdivH * f; - subd[i1] = g; - for ( i2 = 0; i2 <= i1; i2++ ) { - (*this)[i1][i2] -= f * subd[i2] + g * (*this)[i0][i2]; - } - } - } - } else { - subd[i0] = (*this)[i0][i3]; - } - - diag[i0] = h; - } - - diag[0] = 0.0f; - subd[0] = 0.0f; - for ( i0 = 0, i3 = -1; i0 <= numRows-1; i0++, i3++ ) { - if ( diag[i0] ) { - for ( i1 = 0; i1 <= i3; i1++ ) { - sum = 0.0f; - for (i2 = 0; i2 <= i3; i2++) { - sum += (*this)[i0][i2] * (*this)[i2][i1]; - } - for ( i2 = 0; i2 <= i3; i2++ ) { - (*this)[i2][i1] -= sum * (*this)[i2][i0]; - } - } - } - diag[i0] = (*this)[i0][i0]; - (*this)[i0][i0] = 1.0f; - for ( i1 = 0; i1 <= i3; i1++ ) { - (*this)[i1][i0] = 0.0f; - (*this)[i0][i1] = 0.0f; - } - } - - // re-order - for ( i0 = 1, i3 = 0; i0 < numRows; i0++, i3++ ) { - subd[i3] = subd[i0]; - } - subd[numRows-1] = 0.0f; -} - -/* -============ -idMatX::QL - - QL algorithm with implicit shifts to determine the eigenvalues and eigenvectors of a symmetric tri-diagonal matrix. - diag contains the diagonal elements of the symmetric tri-diagonal matrix on input and is overwritten with the eigenvalues. - subd contains the off-diagonal elements of the symmetric tri-diagonal matrix and is destroyed. - This matrix has to be either the identity matrix to determine the eigenvectors for a symmetric tri-diagonal matrix, - or the matrix returned by the Householder reduction to determine the eigenvalues for the original symmetric matrix. -============ -*/ -bool idMatX::QL( idVecX &diag, idVecX &subd ) { - const int maxIter = 32; - int i0, i1, i2, i3; - float a, b, f, g, r, p, s, c; - - assert( numRows == numColumns ); - - for ( i0 = 0; i0 < numRows; i0++ ) { - for ( i1 = 0; i1 < maxIter; i1++ ) { - for ( i2 = i0; i2 <= numRows - 2; i2++ ) { - a = idMath::Fabs( diag[i2] ) + idMath::Fabs( diag[i2+1] ); - if ( idMath::Fabs( subd[i2] ) + a == a ) { - break; - } - } - if ( i2 == i0 ) { - break; - } - - g = ( diag[i0+1] - diag[i0] ) / ( 2.0f * subd[i0] ); - r = idMath::Sqrt( g * g + 1.0f ); - if ( g < 0.0f ) { - g = diag[i2] - diag[i0] + subd[i0] / ( g - r ); - } else { - g = diag[i2] - diag[i0] + subd[i0] / ( g + r ); - } - s = 1.0f; - c = 1.0f; - p = 0.0f; - for ( i3 = i2 - 1; i3 >= i0; i3-- ) { - f = s * subd[i3]; - b = c * subd[i3]; - if ( idMath::Fabs( f ) >= idMath::Fabs( g ) ) { - c = g / f; - r = idMath::Sqrt( c * c + 1.0f ); - subd[i3+1] = f * r; - s = 1.0f / r; - c *= s; - } else { - s = f / g; - r = idMath::Sqrt( s * s + 1.0f ); - subd[i3+1] = g * r; - c = 1.0f / r; - s *= c; - } - g = diag[i3+1] - p; - r = ( diag[i3] - g ) * s + 2.0f * b * c; - p = s * r; - diag[i3+1] = g + p; - g = c * r - b; - - for ( int i4 = 0; i4 < numRows; i4++ ) { - f = (*this)[i4][i3+1]; - (*this)[i4][i3+1] = s * (*this)[i4][i3] + c * f; - (*this)[i4][i3] = c * (*this)[i4][i3] - s * f; - } - } - diag[i0] -= p; - subd[i0] = g; - subd[i2] = 0.0f; - } - if ( i1 == maxIter ) { - return false; - } - } - return true; -} - -/* -============ -idMatX::Eigen_SolveSymmetricTriDiagonal - - Determine eigen values and eigen vectors for a symmetric tri-diagonal matrix. - The eigen values are stored in 'eigenValues'. - Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i]. - The initial matrix has to be symmetric tri-diagonal. -============ -*/ -bool idMatX::Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues ) { - int i; - idVecX subd; - - assert( numRows == numColumns ); - - subd.SetData( numRows, VECX_ALLOCA( numRows ) ); - eigenValues.SetSize( numRows ); - - for ( i = 0; i < numRows-1; i++ ) { - eigenValues[i] = (*this)[i][i]; - subd[i] = (*this)[i+1][i]; - } - eigenValues[numRows-1] = (*this)[numRows-1][numRows-1]; - - Identity(); - - return QL( eigenValues, subd ); -} - -/* -============ -idMatX::Eigen_SolveSymmetric - - Determine eigen values and eigen vectors for a symmetric matrix. - The eigen values are stored in 'eigenValues'. - Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i]. - The initial matrix has to be symmetric. -============ -*/ -bool idMatX::Eigen_SolveSymmetric( idVecX &eigenValues ) { - idVecX subd; - - assert( numRows == numColumns ); - - subd.SetData( numRows, VECX_ALLOCA( numRows ) ); - eigenValues.SetSize( numRows ); - - HouseholderReduction( eigenValues, subd ); - return QL( eigenValues, subd ); -} - -/* -============ -idMatX::HessenbergReduction - - Reduction to Hessenberg form. -============ -*/ -void idMatX::HessenbergReduction( idMatX &H ) { - int i, j, m; - int low = 0; - int high = numRows - 1; - float scale, f, g, h; - idVecX v; - - v.SetData( numRows, VECX_ALLOCA( numRows ) ); - - for ( m = low + 1; m <= high - 1; m++ ) { - - scale = 0.0f; - for ( i = m; i <= high; i++ ) { - scale = scale + idMath::Fabs( H[i][m-1] ); - } - if ( scale != 0.0f ) { - - // compute Householder transformation. - h = 0.0f; - for ( i = high; i >= m; i-- ) { - v[i] = H[i][m-1] / scale; - h += v[i] * v[i]; - } - g = idMath::Sqrt( h ); - if ( v[m] > 0.0f ) { - g = -g; - } - h = h - v[m] * g; - v[m] = v[m] - g; - - // apply Householder similarity transformation - // H = (I-u*u'/h)*H*(I-u*u')/h) - for ( j = m; j < numRows; j++) { - f = 0.0f; - for ( i = high; i >= m; i-- ) { - f += v[i] * H[i][j]; - } - f = f / h; - for ( i = m; i <= high; i++ ) { - H[i][j] -= f * v[i]; - } - } - - for ( i = 0; i <= high; i++ ) { - f = 0.0f; - for ( j = high; j >= m; j-- ) { - f += v[j] * H[i][j]; - } - f = f / h; - for ( j = m; j <= high; j++ ) { - H[i][j] -= f * v[j]; - } - } - v[m] = scale * v[m]; - H[m][m-1] = scale * g; - } - } - - // accumulate transformations - Identity(); - for ( int m = high - 1; m >= low + 1; m-- ) { - if ( H[m][m-1] != 0.0f ) { - for ( i = m + 1; i <= high; i++ ) { - v[i] = H[i][m-1]; - } - for ( j = m; j <= high; j++ ) { - g = 0.0f; - for ( i = m; i <= high; i++ ) { - g += v[i] * (*this)[i][j]; - } - // float division to avoid possible underflow - g = ( g / v[m] ) / H[m][m-1]; - for ( i = m; i <= high; i++ ) { - (*this)[i][j] += g * v[i]; - } - } - } - } -} - -/* -============ -idMatX::ComplexDivision - - Complex scalar division. -============ -*/ -void idMatX::ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi ) { - float r, d; - if ( idMath::Fabs( yr ) > idMath::Fabs( yi ) ) { - r = yi / yr; - d = yr + r * yi; - cdivr = ( xr + r * xi ) / d; - cdivi = ( xi - r * xr ) / d; - } else { - r = yr / yi; - d = yi + r * yr; - cdivr = ( r * xr + xi ) / d; - cdivi = ( r * xi - xr ) / d; - } -} - -/* -============ -idMatX::HessenbergToRealSchur - - Reduction from Hessenberg to real Schur form. -============ -*/ -bool idMatX::HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues ) { - int i, j, k; - int n = numRows - 1; - int low = 0; - int high = numRows - 1; - float eps = 2e-16f, exshift = 0.0f; - float p = 0.0f, q = 0.0f, r = 0.0f, s = 0.0f, z = 0.0f, t, w, x, y; - - // store roots isolated by balanc and compute matrix norm - float norm = 0.0f; - for ( i = 0; i < numRows; i++ ) { - if ( i < low || i > high ) { - realEigenValues[i] = H[i][i]; - imaginaryEigenValues[i] = 0.0f; - } - for ( j = Max( i - 1, 0 ); j < numRows; j++ ) { - norm = norm + idMath::Fabs( H[i][j] ); - } - } - - int iter = 0; - while( n >= low ) { - - // look for single small sub-diagonal element - int l = n; - while ( l > low ) { - s = idMath::Fabs( H[l-1][l-1] ) + idMath::Fabs( H[l][l] ); - if ( s == 0.0f ) { - s = norm; - } - if ( idMath::Fabs( H[l][l-1] ) < eps * s ) { - break; - } - l--; - } - - // check for convergence - if ( l == n ) { // one root found - H[n][n] = H[n][n] + exshift; - realEigenValues[n] = H[n][n]; - imaginaryEigenValues[n] = 0.0f; - n--; - iter = 0; - } else if ( l == n-1 ) { // two roots found - w = H[n][n-1] * H[n-1][n]; - p = ( H[n-1][n-1] - H[n][n] ) / 2.0f; - q = p * p + w; - z = idMath::Sqrt( idMath::Fabs( q ) ); - H[n][n] = H[n][n] + exshift; - H[n-1][n-1] = H[n-1][n-1] + exshift; - x = H[n][n]; - - if ( q >= 0.0f ) { // real pair - if ( p >= 0.0f ) { - z = p + z; - } else { - z = p - z; - } - realEigenValues[n-1] = x + z; - realEigenValues[n] = realEigenValues[n-1]; - if ( z != 0.0f ) { - realEigenValues[n] = x - w / z; - } - imaginaryEigenValues[n-1] = 0.0f; - imaginaryEigenValues[n] = 0.0f; - x = H[n][n-1]; - s = idMath::Fabs( x ) + idMath::Fabs( z ); - p = x / s; - q = z / s; - r = idMath::Sqrt( p * p + q * q ); - p = p / r; - q = q / r; - - // modify row - for ( j = n-1; j < numRows; j++ ) { - z = H[n-1][j]; - H[n-1][j] = q * z + p * H[n][j]; - H[n][j] = q * H[n][j] - p * z; - } - - // modify column - for ( i = 0; i <= n; i++ ) { - z = H[i][n-1]; - H[i][n-1] = q * z + p * H[i][n]; - H[i][n] = q * H[i][n] - p * z; - } - - // accumulate transformations - for ( i = low; i <= high; i++ ) { - z = (*this)[i][n-1]; - (*this)[i][n-1] = q * z + p * (*this)[i][n]; - (*this)[i][n] = q * (*this)[i][n] - p * z; - } - } else { // complex pair - realEigenValues[n-1] = x + p; - realEigenValues[n] = x + p; - imaginaryEigenValues[n-1] = z; - imaginaryEigenValues[n] = -z; - } - n = n - 2; - iter = 0; - - } else { // no convergence yet - - // form shift - x = H[n][n]; - y = 0.0f; - w = 0.0f; - if ( l < n ) { - y = H[n-1][n-1]; - w = H[n][n-1] * H[n-1][n]; - } - - // Wilkinson's original ad hoc shift - if ( iter == 10 ) { - exshift += x; - for ( i = low; i <= n; i++ ) { - H[i][i] -= x; - } - s = idMath::Fabs( H[n][n-1] ) + idMath::Fabs( H[n-1][n-2] ); - x = y = 0.75f * s; - w = -0.4375f * s * s; - } - - // new ad hoc shift - if ( iter == 30 ) { - s = ( y - x ) / 2.0f; - s = s * s + w; - if ( s > 0 ) { - s = idMath::Sqrt( s ); - if ( y < x ) { - s = -s; - } - s = x - w / ( ( y - x ) / 2.0f + s ); - for ( i = low; i <= n; i++ ) { - H[i][i] -= s; - } - exshift += s; - x = y = w = 0.964f; - } - } - - iter = iter + 1; - - // look for two consecutive small sub-diagonal elements - int m; - for( m = n-2; m >= l; m-- ) { - z = H[m][m]; - r = x - z; - s = y - z; - p = ( r * s - w ) / H[m+1][m] + H[m][m+1]; - q = H[m+1][m+1] - z - r - s; - r = H[m+2][m+1]; - s = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r ); - p = p / s; - q = q / s; - r = r / s; - if ( m == l ) { - break; - } - if ( idMath::Fabs( H[m][m-1] ) * ( idMath::Fabs( q ) + idMath::Fabs( r ) ) < - eps * ( idMath::Fabs( p ) * ( idMath::Fabs( H[m-1][m-1] ) + idMath::Fabs( z ) + idMath::Fabs( H[m+1][m+1] ) ) ) ) { - break; - } - } - - for ( i = m+2; i <= n; i++ ) { - H[i][i-2] = 0.0f; - if ( i > m+2 ) { - H[i][i-3] = 0.0f; - } - } - - // double QR step involving rows l:n and columns m:n - for ( k = m; k <= n-1; k++ ) { - bool notlast = ( k != n-1 ); - if ( k != m ) { - p = H[k][k-1]; - q = H[k+1][k-1]; - r = ( notlast ? H[k+2][k-1] : 0.0f ); - x = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r ); - if ( x != 0.0f ) { - p = p / x; - q = q / x; - r = r / x; - } - } - if ( x == 0.0f ) { - break; - } - s = idMath::Sqrt( p * p + q * q + r * r ); - if ( p < 0.0f ) { - s = -s; - } - if ( s != 0.0f ) { - if ( k != m ) { - H[k][k-1] = -s * x; - } else if ( l != m ) { - H[k][k-1] = -H[k][k-1]; - } - p = p + s; - x = p / s; - y = q / s; - z = r / s; - q = q / p; - r = r / p; - - // modify row - for ( j = k; j < numRows; j++ ) { - p = H[k][j] + q * H[k+1][j]; - if ( notlast ) { - p = p + r * H[k+2][j]; - H[k+2][j] = H[k+2][j] - p * z; - } - H[k][j] = H[k][j] - p * x; - H[k+1][j] = H[k+1][j] - p * y; - } - - // modify column - for ( i = 0; i <= Min( n, k + 3 ); i++ ) { - p = x * H[i][k] + y * H[i][k+1]; - if ( notlast ) { - p = p + z * H[i][k+2]; - H[i][k+2] = H[i][k+2] - p * r; - } - H[i][k] = H[i][k] - p; - H[i][k+1] = H[i][k+1] - p * q; - } - - // accumulate transformations - for ( i = low; i <= high; i++ ) { - p = x * (*this)[i][k] + y * (*this)[i][k+1]; - if ( notlast ) { - p = p + z * (*this)[i][k+2]; - (*this)[i][k+2] = (*this)[i][k+2] - p * r; - } - (*this)[i][k] = (*this)[i][k] - p; - (*this)[i][k+1] = (*this)[i][k+1] - p * q; - } - } - } - } - } - - // backsubstitute to find vectors of upper triangular form - if ( norm == 0.0f ) { - return false; - } - - for ( n = numRows-1; n >= 0; n-- ) { - p = realEigenValues[n]; - q = imaginaryEigenValues[n]; - - if ( q == 0.0f ) { // real vector - int l = n; - H[n][n] = 1.0f; - for ( i = n-1; i >= 0; i-- ) { - w = H[i][i] - p; - r = 0.0f; - for ( j = l; j <= n; j++ ) { - r = r + H[i][j] * H[j][n]; - } - if ( imaginaryEigenValues[i] < 0.0f ) { - z = w; - s = r; - } else { - l = i; - if ( imaginaryEigenValues[i] == 0.0f ) { - if ( w != 0.0f ) { - H[i][n] = -r / w; - } else { - H[i][n] = -r / ( eps * norm ); - } - } else { // solve real equations - x = H[i][i+1]; - y = H[i+1][i]; - q = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i]; - t = ( x * s - z * r ) / q; - H[i][n] = t; - if ( idMath::Fabs(x) > idMath::Fabs( z ) ) { - H[i+1][n] = ( -r - w * t ) / x; - } else { - H[i+1][n] = ( -s - y * t ) / z; - } - } - - // overflow control - t = idMath::Fabs(H[i][n]); - if ( ( eps * t ) * t > 1 ) { - for ( j = i; j <= n; j++ ) { - H[j][n] = H[j][n] / t; - } - } - } - } - } else if ( q < 0.0f ) { // complex vector - int l = n-1; - - // last vector component imaginary so matrix is triangular - if ( idMath::Fabs( H[n][n-1] ) > idMath::Fabs( H[n-1][n] ) ) { - H[n-1][n-1] = q / H[n][n-1]; - H[n-1][n] = -( H[n][n] - p ) / H[n][n-1]; - } else { - ComplexDivision( 0.0f, -H[n-1][n], H[n-1][n-1]-p, q, H[n-1][n-1], H[n-1][n] ); - } - H[n][n-1] = 0.0f; - H[n][n] = 1.0f; - for ( i = n-2; i >= 0; i-- ) { - float ra, sa, vr, vi; - ra = 0.0f; - sa = 0.0f; - for ( j = l; j <= n; j++ ) { - ra = ra + H[i][j] * H[j][n-1]; - sa = sa + H[i][j] * H[j][n]; - } - w = H[i][i] - p; - - if ( imaginaryEigenValues[i] < 0.0f ) { - z = w; - r = ra; - s = sa; - } else { - l = i; - if ( imaginaryEigenValues[i] == 0.0f ) { - ComplexDivision( -ra, -sa, w, q, H[i][n-1], H[i][n] ); - } else { - // solve complex equations - x = H[i][i+1]; - y = H[i+1][i]; - vr = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i] - q * q; - vi = ( realEigenValues[i] - p ) * 2.0f * q; - if ( vr == 0.0f && vi == 0.0f ) { - vr = eps * norm * ( idMath::Fabs( w ) + idMath::Fabs( q ) + idMath::Fabs( x ) + idMath::Fabs( y ) + idMath::Fabs( z ) ); - } - ComplexDivision( x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi, H[i][n-1], H[i][n] ); - if ( idMath::Fabs( x ) > ( idMath::Fabs( z ) + idMath::Fabs( q ) ) ) { - H[i+1][n-1] = ( -ra - w * H[i][n-1] + q * H[i][n] ) / x; - H[i+1][n] = ( -sa - w * H[i][n] - q * H[i][n-1] ) / x; - } else { - ComplexDivision( -r - y * H[i][n-1], -s - y * H[i][n], z, q, H[i+1][n-1], H[i+1][n] ); - } - } - - // overflow control - t = Max( idMath::Fabs( H[i][n-1] ), idMath::Fabs( H[i][n] ) ); - if ( ( eps * t ) * t > 1 ) { - for ( j = i; j <= n; j++ ) { - H[j][n-1] = H[j][n-1] / t; - H[j][n] = H[j][n] / t; - } - } - } - } - } - } - - // vectors of isolated roots - for ( i = 0; i < numRows; i++ ) { - if ( i < low || i > high ) { - for ( j = i; j < numRows; j++ ) { - (*this)[i][j] = H[i][j]; - } - } - } - - // back transformation to get eigenvectors of original matrix - for ( j = numRows - 1; j >= low; j-- ) { - for ( i = low; i <= high; i++ ) { - z = 0.0f; - for ( k = low; k <= Min( j, high ); k++ ) { - z = z + (*this)[i][k] * H[k][j]; - } - (*this)[i][j] = z; - } - } - - return true; -} - -/* -============ -idMatX::Eigen_Solve - - Determine eigen values and eigen vectors for a square matrix. - The eigen values are stored in 'realEigenValues' and 'imaginaryEigenValues'. - Column i of the original matrix will store the eigen vector corresponding to the realEigenValues[i] and imaginaryEigenValues[i]. -============ -*/ -bool idMatX::Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues ) { - idMatX H; - - assert( numRows == numColumns ); - - realEigenValues.SetSize( numRows ); - imaginaryEigenValues.SetSize( numRows ); - - H = *this; - - // reduce to Hessenberg form - HessenbergReduction( H ); - - // reduce Hessenberg to real Schur form - return HessenbergToRealSchur( H, realEigenValues, imaginaryEigenValues ); -} - -/* -============ -idMatX::Eigen_SortIncreasing -============ -*/ -void idMatX::Eigen_SortIncreasing( idVecX &eigenValues ) { - int i, j, k; - float min; - - for ( i = 0; i <= numRows - 2; i++ ) { - j = i; - min = eigenValues[j]; - for ( k = i + 1; k < numRows; k++ ) { - if ( eigenValues[k] < min ) { - j = k; - min = eigenValues[j]; - } - } - if ( j != i ) { - eigenValues.SwapElements( i, j ); - SwapColumns( i, j ); - } - } -} - -/* -============ -idMatX::Eigen_SortDecreasing -============ -*/ -void idMatX::Eigen_SortDecreasing( idVecX &eigenValues ) { - int i, j, k; - float max; - - for ( i = 0; i <= numRows - 2; i++ ) { - j = i; - max = eigenValues[j]; - for ( k = i + 1; k < numRows; k++ ) { - if ( eigenValues[k] > max ) { - j = k; - max = eigenValues[j]; - } - } - if ( j != i ) { - eigenValues.SwapElements( i, j ); - SwapColumns( i, j ); - } - } -} - -/* -============ -idMatX::DeterminantGeneric -============ -*/ -float idMatX::DeterminantGeneric( void ) const { - int *index; - float det; - idMatX tmp; - - index = (int *) _alloca16( numRows * sizeof( int ) ); - tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); - tmp = *this; - - if ( !tmp.LU_Factor( index, &det ) ) { - return 0.0f; - } - - return det; -} - -/* -============ -idMatX::InverseSelfGeneric -============ -*/ -bool idMatX::InverseSelfGeneric( void ) { - int i, j, *index; - idMatX tmp; - idVecX x, b; - - index = (int *) _alloca16( numRows * sizeof( int ) ); - tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) ); - tmp = *this; - - if ( !tmp.LU_Factor( index ) ) { - return false; - } - - x.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.SetData( numRows, VECX_ALLOCA( numRows ) ); - b.Zero(); - - for ( i = 0; i < numRows; i++ ) { - - b[i] = 1.0f; - tmp.LU_Solve( x, b, index ); - for ( j = 0; j < numRows; j++ ) { - (*this)[j][i] = x[j]; - } - b[i] = 0.0f; - } - return true; -} - -/* -============ -idMatX::Test -============ -*/ -void idMatX::Test( void ) { - idMatX original, m1, m2, m3, q1, q2, r1, r2; - idVecX v, w, u, c, d; - int offset, size, *index1, *index2; - - size = 6; - original.Random( size, size, 0 ); - original = original * original.Transpose(); - - index1 = (int *) _alloca16( ( size + 1 ) * sizeof( index1[0] ) ); - index2 = (int *) _alloca16( ( size + 1 ) * sizeof( index2[0] ) ); - - /* - idMatX::LowerTriangularInverse - */ - - m1 = original; - m1.ClearUpperTriangle(); - m2 = m1; - - m2.InverseSelf(); - m1.LowerTriangularInverse(); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LowerTriangularInverse failed" ); - } - - /* - idMatX::UpperTriangularInverse - */ - - m1 = original; - m1.ClearLowerTriangle(); - m2 = m1; - - m2.InverseSelf(); - m1.UpperTriangularInverse(); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::UpperTriangularInverse failed" ); - } - - /* - idMatX::Inverse_GaussJordan - */ - - m1 = original; - - m1.Inverse_GaussJordan(); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::Inverse_GaussJordan failed" ); - } - - /* - idMatX::Inverse_UpdateRankOne - */ - - m1 = original; - m2 = original; - - w.Random( size, 1 ); - v.Random( size, 2 ); - - // invert m1 - m1.Inverse_GaussJordan(); - - // modify and invert m2 - m2.Update_RankOne( v, w, 1.0f ); - if ( !m2.Inverse_GaussJordan() ) { - assert( 0 ); - } - - // update inverse of m1 - m1.Inverse_UpdateRankOne( v, w, 1.0f ); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Inverse_UpdateRankOne failed" ); - } - - /* - idMatX::Inverse_UpdateRowColumn - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - v.Random( size, 1 ); - w.Random( size, 2 ); - w[offset] = 0.0f; - - // invert m1 - m1.Inverse_GaussJordan(); - - // modify and invert m2 - m2.Update_RowColumn( v, w, offset ); - if ( !m2.Inverse_GaussJordan() ) { - assert( 0 ); - } - - // update inverse of m1 - m1.Inverse_UpdateRowColumn( v, w, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::Inverse_UpdateRowColumn failed" ); - } - } - - /* - idMatX::Inverse_UpdateIncrement - */ - - m1 = original; - m2 = original; - - v.Random( size + 1, 1 ); - w.Random( size + 1, 2 ); - w[size] = 0.0f; - - // invert m1 - m1.Inverse_GaussJordan(); - - // modify and invert m2 - m2.Update_Increment( v, w ); - if ( !m2.Inverse_GaussJordan() ) { - assert( 0 ); - } - - // update inverse of m1 - m1.Inverse_UpdateIncrement( v, w ); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Inverse_UpdateIncrement failed" ); - } - - /* - idMatX::Inverse_UpdateDecrement - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - v.SetSize( 6 ); - w.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - v[i] = original[i][offset]; - w[i] = original[offset][i]; - } - - // invert m1 - m1.Inverse_GaussJordan(); - - // modify and invert m2 - m2.Update_Decrement( offset ); - if ( !m2.Inverse_GaussJordan() ) { - assert( 0 ); - } - - // update inverse of m1 - m1.Inverse_UpdateDecrement( v, w, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::Inverse_UpdateDecrement failed" ); - } - } - - /* - idMatX::LU_Factor - */ - - m1 = original; - - m1.LU_Factor( NULL ); // no pivoting - m1.LU_UnpackFactors( m2, m3 ); - m1 = m2 * m3; - - if ( !original.Compare( m1, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LU_Factor failed" ); - } - - /* - idMatX::LU_UpdateRankOne - */ - - m1 = original; - m2 = original; - - w.Random( size, 1 ); - v.Random( size, 2 ); - - // factor m1 - m1.LU_Factor( index1 ); - - // modify and factor m2 - m2.Update_RankOne( v, w, 1.0f ); - if ( !m2.LU_Factor( index2 ) ) { - assert( 0 ); - } - m2.LU_MultiplyFactors( m3, index2 ); - m2 = m3; - - // update factored m1 - m1.LU_UpdateRankOne( v, w, 1.0f, index1 ); - m1.LU_MultiplyFactors( m3, index1 ); - m1 = m3; - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LU_UpdateRankOne failed" ); - } - - /* - idMatX::LU_UpdateRowColumn - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - v.Random( size, 1 ); - w.Random( size, 2 ); - w[offset] = 0.0f; - - // factor m1 - m1.LU_Factor( index1 ); - - // modify and factor m2 - m2.Update_RowColumn( v, w, offset ); - if ( !m2.LU_Factor( index2 ) ) { - assert( 0 ); - } - m2.LU_MultiplyFactors( m3, index2 ); - m2 = m3; - - // update m1 - m1.LU_UpdateRowColumn( v, w, offset, index1 ); - m1.LU_MultiplyFactors( m3, index1 ); - m1 = m3; - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::LU_UpdateRowColumn failed" ); - } - } - - /* - idMatX::LU_UpdateIncrement - */ - - m1 = original; - m2 = original; - - v.Random( size + 1, 1 ); - w.Random( size + 1, 2 ); - w[size] = 0.0f; - - // factor m1 - m1.LU_Factor( index1 ); - - // modify and factor m2 - m2.Update_Increment( v, w ); - if ( !m2.LU_Factor( index2 ) ) { - assert( 0 ); - } - m2.LU_MultiplyFactors( m3, index2 ); - m2 = m3; - - // update factored m1 - m1.LU_UpdateIncrement( v, w, index1 ); - m1.LU_MultiplyFactors( m3, index1 ); - m1 = m3; - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LU_UpdateIncrement failed" ); - } - - /* - idMatX::LU_UpdateDecrement - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - v.SetSize( 6 ); - w.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - v[i] = original[i][offset]; - w[i] = original[offset][i]; - } - - // factor m1 - m1.LU_Factor( index1 ); - - // modify and factor m2 - m2.Update_Decrement( offset ); - if ( !m2.LU_Factor( index2 ) ) { - assert( 0 ); - } - m2.LU_MultiplyFactors( m3, index2 ); - m2 = m3; - - u.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - u[i] = original[index1[offset]][i]; - } - - // update factors of m1 - m1.LU_UpdateDecrement( v, w, u, offset, index1 ); - m1.LU_MultiplyFactors( m3, index1 ); - m1 = m3; - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::LU_UpdateDecrement failed" ); - } - } - - /* - idMatX::LU_Inverse - */ - - m2 = original; - - m2.LU_Factor( NULL ); - m2.LU_Inverse( m1, NULL ); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::LU_Inverse failed" ); - } - - /* - idMatX::QR_Factor - */ - - c.SetSize( size ); - d.SetSize( size ); - - m1 = original; - - m1.QR_Factor( c, d ); - m1.QR_UnpackFactors( q1, r1, c, d ); - m1 = q1 * r1; - - if ( !original.Compare( m1, 1e-4f ) ) { - idLib::common->Warning( "idMatX::QR_Factor failed" ); - } - - /* - idMatX::QR_UpdateRankOne - */ - - c.SetSize( size ); - d.SetSize( size ); - - m1 = original; - m2 = original; - - w.Random( size, 0 ); - v = w; - - // factor m1 - m1.QR_Factor( c, d ); - m1.QR_UnpackFactors( q1, r1, c, d ); - - // modify and factor m2 - m2.Update_RankOne( v, w, 1.0f ); - if ( !m2.QR_Factor( c, d ) ) { - assert( 0 ); - } - m2.QR_UnpackFactors( q2, r2, c, d ); - m2 = q2 * r2; - - // update factored m1 - q1.QR_UpdateRankOne( r1, v, w, 1.0f ); - m1 = q1 * r1; - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::QR_UpdateRankOne failed" ); - } - - /* - idMatX::QR_UpdateRowColumn - */ - - for ( offset = 0; offset < size; offset++ ) { - c.SetSize( size ); - d.SetSize( size ); - - m1 = original; - m2 = original; - - v.Random( size, 1 ); - w.Random( size, 2 ); - w[offset] = 0.0f; - - // factor m1 - m1.QR_Factor( c, d ); - m1.QR_UnpackFactors( q1, r1, c, d ); - - // modify and factor m2 - m2.Update_RowColumn( v, w, offset ); - if ( !m2.QR_Factor( c, d ) ) { - assert( 0 ); - } - m2.QR_UnpackFactors( q2, r2, c, d ); - m2 = q2 * r2; - - // update m1 - q1.QR_UpdateRowColumn( r1, v, w, offset ); - m1 = q1 * r1; - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::QR_UpdateRowColumn failed" ); - } - } - - /* - idMatX::QR_UpdateIncrement - */ - - c.SetSize( size+1 ); - d.SetSize( size+1 ); - - m1 = original; - m2 = original; - - v.Random( size + 1, 1 ); - w.Random( size + 1, 2 ); - w[size] = 0.0f; - - // factor m1 - m1.QR_Factor( c, d ); - m1.QR_UnpackFactors( q1, r1, c, d ); - - // modify and factor m2 - m2.Update_Increment( v, w ); - if ( !m2.QR_Factor( c, d ) ) { - assert( 0 ); - } - m2.QR_UnpackFactors( q2, r2, c, d ); - m2 = q2 * r2; - - // update factored m1 - q1.QR_UpdateIncrement( r1, v, w ); - m1 = q1 * r1; - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::QR_UpdateIncrement failed" ); - } - - /* - idMatX::QR_UpdateDecrement - */ - - for ( offset = 0; offset < size; offset++ ) { - c.SetSize( size+1 ); - d.SetSize( size+1 ); - - m1 = original; - m2 = original; - - v.SetSize( 6 ); - w.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - v[i] = original[i][offset]; - w[i] = original[offset][i]; - } - - // factor m1 - m1.QR_Factor( c, d ); - m1.QR_UnpackFactors( q1, r1, c, d ); - - // modify and factor m2 - m2.Update_Decrement( offset ); - if ( !m2.QR_Factor( c, d ) ) { - assert( 0 ); - } - m2.QR_UnpackFactors( q2, r2, c, d ); - m2 = q2 * r2; - - // update factors of m1 - q1.QR_UpdateDecrement( r1, v, w, offset ); - m1 = q1 * r1; - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::QR_UpdateDecrement failed" ); - } - } - - /* - idMatX::QR_Inverse - */ - - m2 = original; - - m2.QR_Factor( c, d ); - m2.QR_Inverse( m1, c, d ); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::QR_Inverse failed" ); - } - - /* - idMatX::SVD_Factor - */ - - m1 = original; - m3.Zero( size, size ); - w.Zero( size ); - - m1.SVD_Factor( w, m3 ); - m2.Diag( w ); - m3.TransposeSelf(); - m1 = m1 * m2 * m3; - - if ( !original.Compare( m1, 1e-4f ) ) { - idLib::common->Warning( "idMatX::SVD_Factor failed" ); - } - - /* - idMatX::SVD_Inverse - */ - - m2 = original; - - m2.SVD_Factor( w, m3 ); - m2.SVD_Inverse( m1, w, m3 ); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::SVD_Inverse failed" ); - } - - /* - idMatX::Cholesky_Factor - */ - - m1 = original; - - m1.Cholesky_Factor(); - m1.Cholesky_MultiplyFactors( m2 ); - - if ( !original.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Cholesky_Factor failed" ); - } - - /* - idMatX::Cholesky_UpdateRankOne - */ - - m1 = original; - m2 = original; - - w.Random( size, 0 ); - - // factor m1 - m1.Cholesky_Factor(); - m1.ClearUpperTriangle(); - - // modify and factor m2 - m2.Update_RankOneSymmetric( w, 1.0f ); - if ( !m2.Cholesky_Factor() ) { - assert( 0 ); - } - m2.ClearUpperTriangle(); - - // update factored m1 - m1.Cholesky_UpdateRankOne( w, 1.0f, 0 ); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Cholesky_UpdateRankOne failed" ); - } - - /* - idMatX::Cholesky_UpdateRowColumn - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - // factor m1 - m1.Cholesky_Factor(); - m1.ClearUpperTriangle(); - - int pdtable[] = { 1, 0, 1, 0, 0, 0 }; - w.Random( size, pdtable[offset] ); - w *= 0.1f; - - // modify and factor m2 - m2.Update_RowColumnSymmetric( w, offset ); - if ( !m2.Cholesky_Factor() ) { - assert( 0 ); - } - m2.ClearUpperTriangle(); - - // update m1 - m1.Cholesky_UpdateRowColumn( w, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::Cholesky_UpdateRowColumn failed" ); - } - } - - /* - idMatX::Cholesky_UpdateIncrement - */ - - m1.Random( size + 1, size + 1, 0 ); - m3 = m1 * m1.Transpose(); - - m1.SquareSubMatrix( m3, size ); - m2 = m1; - - w.SetSize( size + 1 ); - for ( int i = 0; i < size + 1; i++ ) { - w[i] = m3[size][i]; - } - - // factor m1 - m1.Cholesky_Factor(); - - // modify and factor m2 - m2.Update_IncrementSymmetric( w ); - if ( !m2.Cholesky_Factor() ) { - assert( 0 ); - } - - // update factored m1 - m1.Cholesky_UpdateIncrement( w ); - - m1.ClearUpperTriangle(); - m2.ClearUpperTriangle(); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Cholesky_UpdateIncrement failed" ); - } - - /* - idMatX::Cholesky_UpdateDecrement - */ - - for ( offset = 0; offset < size; offset += size - 1 ) { - m1 = original; - m2 = original; - - v.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - v[i] = original[i][offset]; - } - - // factor m1 - m1.Cholesky_Factor(); - - // modify and factor m2 - m2.Update_Decrement( offset ); - if ( !m2.Cholesky_Factor() ) { - assert( 0 ); - } - - // update factors of m1 - m1.Cholesky_UpdateDecrement( v, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::Cholesky_UpdateDecrement failed" ); - } - } - - /* - idMatX::Cholesky_Inverse - */ - - m2 = original; - - m2.Cholesky_Factor(); - m2.Cholesky_Inverse( m1 ); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::Cholesky_Inverse failed" ); - } - - /* - idMatX::LDLT_Factor - */ - - m1 = original; - - m1.LDLT_Factor(); - m1.LDLT_MultiplyFactors( m2 ); - - if ( !original.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LDLT_Factor failed" ); - } - - m1.LDLT_UnpackFactors( m2, m3 ); - m2 = m2 * m3 * m2.Transpose(); - - if ( !original.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LDLT_Factor failed" ); - } - - /* - idMatX::LDLT_UpdateRankOne - */ - - m1 = original; - m2 = original; - - w.Random( size, 0 ); - - // factor m1 - m1.LDLT_Factor(); - m1.ClearUpperTriangle(); - - // modify and factor m2 - m2.Update_RankOneSymmetric( w, 1.0f ); - if ( !m2.LDLT_Factor() ) { - assert( 0 ); - } - m2.ClearUpperTriangle(); - - // update factored m1 - m1.LDLT_UpdateRankOne( w, 1.0f, 0 ); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LDLT_UpdateRankOne failed" ); - } - - /* - idMatX::LDLT_UpdateRowColumn - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - w.Random( size, 0 ); - - // factor m1 - m1.LDLT_Factor(); - m1.ClearUpperTriangle(); - - // modify and factor m2 - m2.Update_RowColumnSymmetric( w, offset ); - if ( !m2.LDLT_Factor() ) { - assert( 0 ); - } - m2.ClearUpperTriangle(); - - // update m1 - m1.LDLT_UpdateRowColumn( w, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::LDLT_UpdateRowColumn failed" ); - } - } - - /* - idMatX::LDLT_UpdateIncrement - */ - - m1.Random( size + 1, size + 1, 0 ); - m3 = m1 * m1.Transpose(); - - m1.SquareSubMatrix( m3, size ); - m2 = m1; - - w.SetSize( size + 1 ); - for ( int i = 0; i < size + 1; i++ ) { - w[i] = m3[size][i]; - } - - // factor m1 - m1.LDLT_Factor(); - - // modify and factor m2 - m2.Update_IncrementSymmetric( w ); - if ( !m2.LDLT_Factor() ) { - assert( 0 ); - } - - // update factored m1 - m1.LDLT_UpdateIncrement( w ); - - m1.ClearUpperTriangle(); - m2.ClearUpperTriangle(); - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::LDLT_UpdateIncrement failed" ); - } - - /* - idMatX::LDLT_UpdateDecrement - */ - - for ( offset = 0; offset < size; offset++ ) { - m1 = original; - m2 = original; - - v.SetSize( 6 ); - for ( int i = 0; i < size; i++ ) { - v[i] = original[i][offset]; - } - - // factor m1 - m1.LDLT_Factor(); - - // modify and factor m2 - m2.Update_Decrement( offset ); - if ( !m2.LDLT_Factor() ) { - assert( 0 ); - } - - // update factors of m1 - m1.LDLT_UpdateDecrement( v, offset ); - - if ( !m1.Compare( m2, 1e-3f ) ) { - idLib::common->Warning( "idMatX::LDLT_UpdateDecrement failed" ); - } - } - - /* - idMatX::LDLT_Inverse - */ - - m2 = original; - - m2.LDLT_Factor(); - m2.LDLT_Inverse( m1 ); - m1 *= original; - - if ( !m1.IsIdentity( 1e-4f ) ) { - idLib::common->Warning( "idMatX::LDLT_Inverse failed" ); - } - - /* - idMatX::Eigen_SolveSymmetricTriDiagonal - */ - - m3 = original; - m3.TriDiagonal_ClearTriangles(); - m1 = m3; - - v.SetSize( size ); - - m1.Eigen_SolveSymmetricTriDiagonal( v ); - - m3.TransposeMultiply( m2, m1 ); - - for ( int i = 0; i < size; i++ ) { - for ( int j = 0; j < size; j++ ) { - m1[i][j] *= v[j]; - } - } - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Eigen_SolveSymmetricTriDiagonal failed" ); - } - - /* - idMatX::Eigen_SolveSymmetric - */ - - m3 = original; - m1 = m3; - - v.SetSize( size ); - - m1.Eigen_SolveSymmetric( v ); - - m3.TransposeMultiply( m2, m1 ); - - for ( int i = 0; i < size; i++ ) { - for ( int j = 0; j < size; j++ ) { - m1[i][j] *= v[j]; - } - } - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Eigen_SolveSymmetric failed" ); - } - - /* - idMatX::Eigen_Solve - */ - - m3 = original; - m1 = m3; - - v.SetSize( size ); - w.SetSize( size ); - - m1.Eigen_Solve( v, w ); - - m3.TransposeMultiply( m2, m1 ); - - for ( int i = 0; i < size; i++ ) { - for ( int j = 0; j < size; j++ ) { - m1[i][j] *= v[j]; - } - } - - if ( !m1.Compare( m2, 1e-4f ) ) { - idLib::common->Warning( "idMatX::Eigen_Solve failed" ); - } -} -#pragma warning( pop ) diff --git a/idlib/math/matrix.h b/idlib/math/matrix.h deleted file mode 100644 index 437775b60..000000000 --- a/idlib/math/matrix.h +++ /dev/null @@ -1,3006 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_MATRIX_H__ -#define __MATH_MATRIX_H__ - -#ifdef __linux__ -#include "sys/sys_public.h" -#include -#endif - -/* -=============================================================================== - - Matrix classes, all matrices are row-major except idMat3 - -=============================================================================== -*/ - -#define MATRIX_INVERSE_EPSILON 1e-14 -#define MATRIX_EPSILON 1e-6 - -class idAngles; -class idQuat; -class idCQuat; -class idRotation; -class idMat4; - -//=============================================================== -// -// idMat2 - 2x2 matrix -// -//=============================================================== - -class idMat2 { -public: - idMat2( void ); - explicit idMat2( const idVec2 &x, const idVec2 &y ); - explicit idMat2( const float xx, const float xy, const float yx, const float yy ); - explicit idMat2( const float src[ 2 ][ 2 ] ); - - const idVec2 & operator[]( int index ) const; - idVec2 & operator[]( int index ); - idMat2 operator-() const; - idMat2 operator*( const float a ) const; - idVec2 operator*( const idVec2 &vec ) const; - idMat2 operator*( const idMat2 &a ) const; - idMat2 operator+( const idMat2 &a ) const; - idMat2 operator-( const idMat2 &a ) const; - idMat2 & operator*=( const float a ); - idMat2 & operator*=( const idMat2 &a ); - idMat2 & operator+=( const idMat2 &a ); - idMat2 & operator-=( const idMat2 &a ); - - friend idMat2 operator*( const float a, const idMat2 &mat ); - friend idVec2 operator*( const idVec2 &vec, const idMat2 &mat ); - friend idVec2 & operator*=( idVec2 &vec, const idMat2 &mat ); - - bool Compare( const idMat2 &a ) const; // exact compare, no epsilon - bool Compare( const idMat2 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMat2 &a ) const; // exact compare, no epsilon - bool operator!=( const idMat2 &a ) const; // exact compare, no epsilon - - void Zero( void ); - void Identity( void ); - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - - float Trace( void ) const; - float Determinant( void ) const; - idMat2 Transpose( void ) const; // returns transpose - idMat2 & TransposeSelf( void ); - idMat2 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMat2 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - idVec2 mat[ 2 ]; -}; - -extern idMat2 mat2_zero; -extern idMat2 mat2_identity; -#define mat2_default mat2_identity - -ID_INLINE idMat2::idMat2( void ) { -} - -ID_INLINE idMat2::idMat2( const idVec2 &x, const idVec2 &y ) { - mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; - mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; -} - -ID_INLINE idMat2::idMat2( const float xx, const float xy, const float yx, const float yy ) { - mat[ 0 ].x = xx; mat[ 0 ].y = xy; - mat[ 1 ].x = yx; mat[ 1 ].y = yy; -} - -ID_INLINE idMat2::idMat2( const float src[ 2 ][ 2 ] ) { - memcpy( mat, src, 2 * 2 * sizeof( float ) ); -} - -ID_INLINE const idVec2 &idMat2::operator[]( int index ) const { - //assert( ( index >= 0 ) && ( index < 2 ) ); - return mat[ index ]; -} - -ID_INLINE idVec2 &idMat2::operator[]( int index ) { - //assert( ( index >= 0 ) && ( index < 2 ) ); - return mat[ index ]; -} - -ID_INLINE idMat2 idMat2::operator-() const { - return idMat2( -mat[0][0], -mat[0][1], - -mat[1][0], -mat[1][1] ); -} - -ID_INLINE idVec2 idMat2::operator*( const idVec2 &vec ) const { - return idVec2( - mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y, - mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y ); -} - -ID_INLINE idMat2 idMat2::operator*( const idMat2 &a ) const { - return idMat2( - mat[0].x * a[0].x + mat[0].y * a[1].x, - mat[0].x * a[0].y + mat[0].y * a[1].y, - mat[1].x * a[0].x + mat[1].y * a[1].x, - mat[1].x * a[0].y + mat[1].y * a[1].y ); -} - -ID_INLINE idMat2 idMat2::operator*( const float a ) const { - return idMat2( - mat[0].x * a, mat[0].y * a, - mat[1].x * a, mat[1].y * a ); -} - -ID_INLINE idMat2 idMat2::operator+( const idMat2 &a ) const { - return idMat2( - mat[0].x + a[0].x, mat[0].y + a[0].y, - mat[1].x + a[1].x, mat[1].y + a[1].y ); -} - -ID_INLINE idMat2 idMat2::operator-( const idMat2 &a ) const { - return idMat2( - mat[0].x - a[0].x, mat[0].y - a[0].y, - mat[1].x - a[1].x, mat[1].y - a[1].y ); -} - -ID_INLINE idMat2 &idMat2::operator*=( const float a ) { - mat[0].x *= a; mat[0].y *= a; - mat[1].x *= a; mat[1].y *= a; - - return *this; -} - -ID_INLINE idMat2 &idMat2::operator*=( const idMat2 &a ) { - float x, y; - x = mat[0].x; y = mat[0].y; - mat[0].x = x * a[0].x + y * a[1].x; - mat[0].y = x * a[0].y + y * a[1].y; - x = mat[1].x; y = mat[1].y; - mat[1].x = x * a[0].x + y * a[1].x; - mat[1].y = x * a[0].y + y * a[1].y; - return *this; -} - -ID_INLINE idMat2 &idMat2::operator+=( const idMat2 &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; - mat[1].x += a[1].x; mat[1].y += a[1].y; - - return *this; -} - -ID_INLINE idMat2 &idMat2::operator-=( const idMat2 &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; - - return *this; -} - -ID_INLINE idVec2 operator*( const idVec2 &vec, const idMat2 &mat ) { - return mat * vec; -} - -ID_INLINE idMat2 operator*( const float a, idMat2 const &mat ) { - return mat * a; -} - -ID_INLINE idVec2 &operator*=( idVec2 &vec, const idMat2 &mat ) { - vec = mat * vec; - return vec; -} - -ID_INLINE bool idMat2::Compare( const idMat2 &a ) const { - if ( mat[0].Compare( a[0] ) && - mat[1].Compare( a[1] ) ) { - return true; - } - return false; -} - -ID_INLINE bool idMat2::Compare( const idMat2 &a, const float epsilon ) const { - if ( mat[0].Compare( a[0], epsilon ) && - mat[1].Compare( a[1], epsilon ) ) { - return true; - } - return false; -} - -ID_INLINE bool idMat2::operator==( const idMat2 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMat2::operator!=( const idMat2 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMat2::Zero( void ) { - mat[0].Zero(); - mat[1].Zero(); -} - -ID_INLINE void idMat2::Identity( void ) { - *this = mat2_identity; -} - -ID_INLINE bool idMat2::IsIdentity( const float epsilon ) const { - return Compare( mat2_identity, epsilon ); -} - -ID_INLINE bool idMat2::IsSymmetric( const float epsilon ) const { - return ( idMath::Fabs( mat[0][1] - mat[1][0] ) < epsilon ); -} - -ID_INLINE bool idMat2::IsDiagonal( const float epsilon ) const { - if ( idMath::Fabs( mat[0][1] ) > epsilon || - idMath::Fabs( mat[1][0] ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE float idMat2::Trace( void ) const { - return ( mat[0][0] + mat[1][1] ); -} - -ID_INLINE float idMat2::Determinant( void ) const { - return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; -} - -ID_INLINE idMat2 idMat2::Transpose( void ) const { - return idMat2( mat[0][0], mat[1][0], - mat[0][1], mat[1][1] ); -} - -ID_INLINE idMat2 &idMat2::TransposeSelf( void ) { - float tmp; - - tmp = mat[0][1]; - mat[0][1] = mat[1][0]; - mat[1][0] = tmp; - - return *this; -} - -ID_INLINE idMat2 idMat2::Inverse( void ) const { - idMat2 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat2 idMat2::InverseFast( void ) const { - idMat2 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE int idMat2::GetDimension( void ) const { - return 4; -} - -ID_INLINE const float *idMat2::ToFloatPtr( void ) const { - return mat[0].ToFloatPtr(); -} - -ID_INLINE float *idMat2::ToFloatPtr( void ) { - return mat[0].ToFloatPtr(); -} - - -//=============================================================== -// -// idMat3 - 3x3 matrix -// -// NOTE: matrix is column-major -// -//=============================================================== - -class idMat3 { -public: - idMat3( void ); - explicit idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z ); - explicit idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ); - explicit idMat3( const float src[ 3 ][ 3 ] ); - - const idVec3 & operator[]( int index ) const; - idVec3 & operator[]( int index ); - idMat3 operator-() const; - idMat3 operator*( const float a ) const; - idVec3 operator*( const idVec3 &vec ) const; - idMat3 operator*( const idMat3 &a ) const; - idMat3 operator+( const idMat3 &a ) const; - idMat3 operator-( const idMat3 &a ) const; - idMat3 & operator*=( const float a ); - idMat3 & operator*=( const idMat3 &a ); - idMat3 & operator+=( const idMat3 &a ); - idMat3 & operator-=( const idMat3 &a ); - - friend idMat3 operator*( const float a, const idMat3 &mat ); - friend idVec3 operator*( const idVec3 &vec, const idMat3 &mat ); - friend idVec3 & operator*=( idVec3 &vec, const idMat3 &mat ); - - bool Compare( const idMat3 &a ) const; // exact compare, no epsilon - bool Compare( const idMat3 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMat3 &a ) const; // exact compare, no epsilon - bool operator!=( const idMat3 &a ) const; // exact compare, no epsilon - - void Zero( void ); - void Identity( void ); - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - bool IsRotated( void ) const; - - void ProjectVector( const idVec3 &src, idVec3 &dst ) const; - void UnprojectVector( const idVec3 &src, idVec3 &dst ) const; - - bool FixDegeneracies( void ); // fix degenerate axial cases - bool FixDenormals( void ); // change tiny numbers to zero - - float Trace( void ) const; - float Determinant( void ) const; - idMat3 OrthoNormalize( void ) const; - idMat3 & OrthoNormalizeSelf( void ); - idMat3 Transpose( void ) const; // returns transpose - idMat3 & TransposeSelf( void ); - idMat3 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMat3 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - idMat3 TransposeMultiply( const idMat3 &b ) const; - - idMat3 InertiaTranslate( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ) const; - idMat3 & InertiaTranslateSelf( const float mass, const idVec3 ¢erOfMass, const idVec3 &translation ); - idMat3 InertiaRotate( const idMat3 &rotation ) const; - idMat3 & InertiaRotateSelf( const idMat3 &rotation ); - - int GetDimension( void ) const; - - idAngles ToAngles( void ) const; - idQuat ToQuat( void ) const; - idCQuat ToCQuat( void ) const; - idRotation ToRotation( void ) const; - idMat4 ToMat4( void ) const; - idVec3 ToAngularVelocity( void ) const; - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - friend void TransposeMultiply( const idMat3 &inv, const idMat3 &b, idMat3 &dst ); - friend idMat3 SkewSymmetric( idVec3 const &src ); - - void GetMat3Params(idVec3 &a, idVec3 &b, idVec3 &c) const { a = mat[0]; b = mat[1], c = mat[2]; }; - -private: - idVec3 mat[ 3 ]; -}; - -extern idMat3 mat3_zero; -extern idMat3 mat3_identity; -#define mat3_default mat3_identity - -ID_INLINE idMat3::idMat3( void ) { -} - -ID_INLINE idMat3::idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z ) { - mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z; - mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z; - mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z; -} - -ID_INLINE idMat3::idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) { - mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz; - mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz; - mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz; -} - -ID_INLINE idMat3::idMat3( const float src[ 3 ][ 3 ] ) { - memcpy( mat, src, 3 * 3 * sizeof( float ) ); -} - -ID_INLINE const idVec3 &idMat3::operator[]( int index ) const { - //assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3 &idMat3::operator[]( int index ) { - //assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idMat3 idMat3::operator-() const { - return idMat3( -mat[0][0], -mat[0][1], -mat[0][2], - -mat[1][0], -mat[1][1], -mat[1][2], - -mat[2][0], -mat[2][1], -mat[2][2] ); -} - -ID_INLINE idVec3 idMat3::operator*( const idVec3 &vec ) const { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE idMat3 idMat3::operator*( const idMat3 &a ) const { - int i, j; - const float *m1Ptr, *m2Ptr; - float *dstPtr; - idMat3 dst; - - m1Ptr = reinterpret_cast(this); - m2Ptr = reinterpret_cast(&a); - dstPtr = reinterpret_cast(&dst); - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 3 + j ]; - dstPtr++; - } - m1Ptr += 3; - } - return dst; -} - -ID_INLINE idMat3 idMat3::operator*( const float a ) const { - return idMat3( - mat[0].x * a, mat[0].y * a, mat[0].z * a, - mat[1].x * a, mat[1].y * a, mat[1].z * a, - mat[2].x * a, mat[2].y * a, mat[2].z * a ); -} - -ID_INLINE idMat3 idMat3::operator+( const idMat3 &a ) const { - return idMat3( - mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, - mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, - mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z ); -} - -ID_INLINE idMat3 idMat3::operator-( const idMat3 &a ) const { - return idMat3( - mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, - mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, - mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z ); -} - -ID_INLINE idMat3 &idMat3::operator*=( const float a ) { - mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; - mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; - mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; - - return *this; -} - -ID_INLINE idMat3 &idMat3::operator*=( const idMat3 &a ) { - int i, j; - const float *m2Ptr; - float *m1Ptr, dst[3]; - - m1Ptr = reinterpret_cast(this); - m2Ptr = reinterpret_cast(&a); - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - dst[j] = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 3 + j ]; - } - m1Ptr[0] = dst[0]; m1Ptr[1] = dst[1]; m1Ptr[2] = dst[2]; - m1Ptr += 3; - } - return *this; -} - -ID_INLINE idMat3 &idMat3::operator+=( const idMat3 &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; - mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; - mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; - - return *this; -} - -ID_INLINE idMat3 &idMat3::operator-=( const idMat3 &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; - mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; - - return *this; -} - -ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat3 &mat ) { - return mat * vec; -} - -ID_INLINE idMat3 operator*( const float a, const idMat3 &mat ) { - return mat * a; -} - -ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat3 &mat ) { - float x = mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z; - float y = mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z; - vec.z = mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z; - vec.x = x; - vec.y = y; - return vec; -} - -ID_INLINE bool idMat3::Compare( const idMat3 &a ) const { - if ( mat[0].Compare( a[0] ) && - mat[1].Compare( a[1] ) && - mat[2].Compare( a[2] ) ) { - return true; - } - return false; -} - -ID_INLINE bool idMat3::Compare( const idMat3 &a, const float epsilon ) const { - if ( mat[0].Compare( a[0], epsilon ) && - mat[1].Compare( a[1], epsilon ) && - mat[2].Compare( a[2], epsilon ) ) { - return true; - } - return false; -} - -ID_INLINE bool idMat3::operator==( const idMat3 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMat3::operator!=( const idMat3 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMat3::Zero( void ) { - memset( mat, 0, sizeof( idMat3 ) ); -} - -ID_INLINE void idMat3::Identity( void ) { - *this = mat3_identity; -} - -ID_INLINE bool idMat3::IsIdentity( const float epsilon ) const { - return Compare( mat3_identity, epsilon ); -} - -ID_INLINE bool idMat3::IsSymmetric( const float epsilon ) const { - if ( idMath::Fabs( mat[0][1] - mat[1][0] ) > epsilon ) { - return false; - } - if ( idMath::Fabs( mat[0][2] - mat[2][0] ) > epsilon ) { - return false; - } - if ( idMath::Fabs( mat[1][2] - mat[2][1] ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE bool idMat3::IsDiagonal( const float epsilon ) const { - if ( idMath::Fabs( mat[0][1] ) > epsilon || - idMath::Fabs( mat[0][2] ) > epsilon || - idMath::Fabs( mat[1][0] ) > epsilon || - idMath::Fabs( mat[1][2] ) > epsilon || - idMath::Fabs( mat[2][0] ) > epsilon || - idMath::Fabs( mat[2][1] ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE bool idMat3::IsRotated( void ) const { - return !Compare( mat3_identity ); -} - -ID_INLINE void idMat3::ProjectVector( const idVec3 &src, idVec3 &dst ) const { - dst.x = src * mat[ 0 ]; - dst.y = src * mat[ 1 ]; - dst.z = src * mat[ 2 ]; -} - -ID_INLINE void idMat3::UnprojectVector( const idVec3 &src, idVec3 &dst ) const { - dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z; -} - -ID_INLINE bool idMat3::FixDegeneracies( void ) { - bool r = mat[0].FixDegenerateNormal(); - r |= mat[1].FixDegenerateNormal(); - r |= mat[2].FixDegenerateNormal(); - return r; -} - -ID_INLINE bool idMat3::FixDenormals( void ) { - bool r = mat[0].FixDenormals(); - r |= mat[1].FixDenormals(); - r |= mat[2].FixDenormals(); - return r; -} - -ID_INLINE float idMat3::Trace( void ) const { - return ( mat[0][0] + mat[1][1] + mat[2][2] ); -} - -ID_INLINE idMat3 idMat3::OrthoNormalize( void ) const { - idMat3 ortho; - - ortho = *this; - ortho[ 0 ].Normalize(); - ortho[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); - ortho[ 2 ].Normalize(); - ortho[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); - ortho[ 1 ].Normalize(); - return ortho; -} - -ID_INLINE idMat3 &idMat3::OrthoNormalizeSelf( void ) { - mat[ 0 ].Normalize(); - mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); - mat[ 2 ].Normalize(); - mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); - mat[ 1 ].Normalize(); - return *this; -} - -ID_INLINE idMat3 idMat3::Transpose( void ) const { - return idMat3( mat[0][0], mat[1][0], mat[2][0], - mat[0][1], mat[1][1], mat[2][1], - mat[0][2], mat[1][2], mat[2][2] ); -} - -ID_INLINE idMat3 &idMat3::TransposeSelf( void ) { - float tmp0, tmp1, tmp2; - - tmp0 = mat[0][1]; - mat[0][1] = mat[1][0]; - mat[1][0] = tmp0; - tmp1 = mat[0][2]; - mat[0][2] = mat[2][0]; - mat[2][0] = tmp1; - tmp2 = mat[1][2]; - mat[1][2] = mat[2][1]; - mat[2][1] = tmp2; - - return *this; -} - -ID_INLINE idMat3 idMat3::Inverse( void ) const { - idMat3 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat3 idMat3::InverseFast( void ) const { - idMat3 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat3 idMat3::TransposeMultiply( const idMat3 &b ) const { - return idMat3( mat[0].x * b[0].x + mat[1].x * b[1].x + mat[2].x * b[2].x, - mat[0].x * b[0].y + mat[1].x * b[1].y + mat[2].x * b[2].y, - mat[0].x * b[0].z + mat[1].x * b[1].z + mat[2].x * b[2].z, - mat[0].y * b[0].x + mat[1].y * b[1].x + mat[2].y * b[2].x, - mat[0].y * b[0].y + mat[1].y * b[1].y + mat[2].y * b[2].y, - mat[0].y * b[0].z + mat[1].y * b[1].z + mat[2].y * b[2].z, - mat[0].z * b[0].x + mat[1].z * b[1].x + mat[2].z * b[2].x, - mat[0].z * b[0].y + mat[1].z * b[1].y + mat[2].z * b[2].y, - mat[0].z * b[0].z + mat[1].z * b[1].z + mat[2].z * b[2].z ); -} - -ID_INLINE void TransposeMultiply( const idMat3 &transpose, const idMat3 &b, idMat3 &dst ) { - dst[0].x = transpose[0].x * b[0].x + transpose[1].x * b[1].x + transpose[2].x * b[2].x; - dst[0].y = transpose[0].x * b[0].y + transpose[1].x * b[1].y + transpose[2].x * b[2].y; - dst[0].z = transpose[0].x * b[0].z + transpose[1].x * b[1].z + transpose[2].x * b[2].z; - dst[1].x = transpose[0].y * b[0].x + transpose[1].y * b[1].x + transpose[2].y * b[2].x; - dst[1].y = transpose[0].y * b[0].y + transpose[1].y * b[1].y + transpose[2].y * b[2].y; - dst[1].z = transpose[0].y * b[0].z + transpose[1].y * b[1].z + transpose[2].y * b[2].z; - dst[2].x = transpose[0].z * b[0].x + transpose[1].z * b[1].x + transpose[2].z * b[2].x; - dst[2].y = transpose[0].z * b[0].y + transpose[1].z * b[1].y + transpose[2].z * b[2].y; - dst[2].z = transpose[0].z * b[0].z + transpose[1].z * b[1].z + transpose[2].z * b[2].z; -} - -ID_INLINE idMat3 SkewSymmetric( idVec3 const &src ) { - return idMat3( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f ); -} - -ID_INLINE int idMat3::GetDimension( void ) const { - return 9; -} - -ID_INLINE const float *idMat3::ToFloatPtr( void ) const { - return mat[0].ToFloatPtr(); -} - -ID_INLINE float *idMat3::ToFloatPtr( void ) { - return mat[0].ToFloatPtr(); -} - - -//=============================================================== -// -// idMat4 - 4x4 matrix -// -//=============================================================== - -class idMat4 { -public: - idMat4( void ); - explicit idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w ); - explicit idMat4(const float xx, const float xy, const float xz, const float xw, - const float yx, const float yy, const float yz, const float yw, - const float zx, const float zy, const float zz, const float zw, - const float wx, const float wy, const float wz, const float ww ); - explicit idMat4( const idMat3 &rotation, const idVec3 &translation ); - explicit idMat4( const float src[ 4 ][ 4 ] ); - - const idVec4 & operator[]( int index ) const; - idVec4 & operator[]( int index ); - idMat4 operator*( const float a ) const; - idVec4 operator*( const idVec4 &vec ) const; - idVec3 operator*( const idVec3 &vec ) const; - idMat4 operator*( const idMat4 &a ) const; - idMat4 operator+( const idMat4 &a ) const; - idMat4 operator-( const idMat4 &a ) const; - idMat4 & operator*=( const float a ); - idMat4 & operator*=( const idMat4 &a ); - idMat4 & operator+=( const idMat4 &a ); - idMat4 & operator-=( const idMat4 &a ); - - friend idMat4 operator*( const float a, const idMat4 &mat ); - friend idVec4 operator*( const idVec4 &vec, const idMat4 &mat ); - friend idVec3 operator*( const idVec3 &vec, const idMat4 &mat ); - friend idVec4 & operator*=( idVec4 &vec, const idMat4 &mat ); - friend idVec3 & operator*=( idVec3 &vec, const idMat4 &mat ); - - bool Compare( const idMat4 &a ) const; // exact compare, no epsilon - bool Compare( const idMat4 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMat4 &a ) const; // exact compare, no epsilon - bool operator!=( const idMat4 &a ) const; // exact compare, no epsilon - - void Zero( void ); - void Identity( void ); - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - bool IsRotated( void ) const; - - void ProjectVector( const idVec4 &src, idVec4 &dst ) const; - void UnprojectVector( const idVec4 &src, idVec4 &dst ) const; - - float Trace( void ) const; - float Determinant( void ) const; - idMat4 Transpose( void ) const; // returns transpose - idMat4 & TransposeSelf( void ); - idMat4 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMat4 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - idMat4 TransposeMultiply( const idMat4 &b ) const; - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - idVec4 mat[ 4 ]; -}; - -extern idMat4 mat4_zero; -extern idMat4 mat4_identity; -#define mat4_default mat4_identity - -ID_INLINE idMat4::idMat4( void ) { -} - -ID_INLINE idMat4::idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w ) { - mat[ 0 ] = x; - mat[ 1 ] = y; - mat[ 2 ] = z; - mat[ 3 ] = w; -} - -ID_INLINE idMat4::idMat4( const float xx, const float xy, const float xz, const float xw, - const float yx, const float yy, const float yz, const float yw, - const float zx, const float zy, const float zz, const float zw, - const float wx, const float wy, const float wz, const float ww ) { - mat[0][0] = xx; mat[0][1] = xy; mat[0][2] = xz; mat[0][3] = xw; - mat[1][0] = yx; mat[1][1] = yy; mat[1][2] = yz; mat[1][3] = yw; - mat[2][0] = zx; mat[2][1] = zy; mat[2][2] = zz; mat[2][3] = zw; - mat[3][0] = wx; mat[3][1] = wy; mat[3][2] = wz; mat[3][3] = ww; -} - -ID_INLINE idMat4::idMat4( const idMat3 &rotation, const idVec3 &translation ) { - // NOTE: idMat3 is transposed because it is column-major - mat[ 0 ][ 0 ] = rotation[0][0]; - mat[ 0 ][ 1 ] = rotation[1][0]; - mat[ 0 ][ 2 ] = rotation[2][0]; - mat[ 0 ][ 3 ] = translation[0]; - mat[ 1 ][ 0 ] = rotation[0][1]; - mat[ 1 ][ 1 ] = rotation[1][1]; - mat[ 1 ][ 2 ] = rotation[2][1]; - mat[ 1 ][ 3 ] = translation[1]; - mat[ 2 ][ 0 ] = rotation[0][2]; - mat[ 2 ][ 1 ] = rotation[1][2]; - mat[ 2 ][ 2 ] = rotation[2][2]; - mat[ 2 ][ 3 ] = translation[2]; - mat[ 3 ][ 0 ] = 0.0f; - mat[ 3 ][ 1 ] = 0.0f; - mat[ 3 ][ 2 ] = 0.0f; - mat[ 3 ][ 3 ] = 1.0f; -} - -ID_INLINE idMat4::idMat4( const float src[ 4 ][ 4 ] ) { - memcpy( mat, src, 4 * 4 * sizeof( float ) ); -} - -ID_INLINE const idVec4 &idMat4::operator[]( int index ) const { - //assert( ( index >= 0 ) && ( index < 4 ) ); - return mat[ index ]; -} - -ID_INLINE idVec4 &idMat4::operator[]( int index ) { - //assert( ( index >= 0 ) && ( index < 4 ) ); - return mat[ index ]; -} - -ID_INLINE idMat4 idMat4::operator*( const float a ) const { - return idMat4( - mat[0].x * a, mat[0].y * a, mat[0].z * a, mat[0].w * a, - mat[1].x * a, mat[1].y * a, mat[1].z * a, mat[1].w * a, - mat[2].x * a, mat[2].y * a, mat[2].z * a, mat[2].w * a, - mat[3].x * a, mat[3].y * a, mat[3].z * a, mat[3].w * a ); -} - -ID_INLINE idVec4 idMat4::operator*( const idVec4 &vec ) const { - return idVec4( - mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w * vec.w, - mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w * vec.w, - mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w * vec.w, - mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w * vec.w ); -} - -ID_INLINE idVec3 idMat4::operator*( const idVec3 &vec ) const { - float s = mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w; - if ( s == 0.0f ) { - return idVec3( 0.0f, 0.0f, 0.0f ); - } - if ( s == 1.0f ) { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w, - mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w, - mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w ); - } - else { - float invS = 1.0f / s; - return idVec3( - (mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w) * invS, - (mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w) * invS, - (mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w) * invS ); - } -} - -ID_INLINE idMat4 idMat4::operator*( const idMat4 &a ) const { - int i, j; - const float *m1Ptr, *m2Ptr; - float *dstPtr; - idMat4 dst; - - m1Ptr = reinterpret_cast(this); - m2Ptr = reinterpret_cast(&a); - dstPtr = reinterpret_cast(&dst); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 4 + j ]; - dstPtr++; - } - m1Ptr += 4; - } - return dst; -} - -ID_INLINE idMat4 idMat4::operator+( const idMat4 &a ) const { - return idMat4( - mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, mat[0].w + a[0].w, - mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, mat[1].w + a[1].w, - mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z, mat[2].w + a[2].w, - mat[3].x + a[3].x, mat[3].y + a[3].y, mat[3].z + a[3].z, mat[3].w + a[3].w ); -} - -ID_INLINE idMat4 idMat4::operator-( const idMat4 &a ) const { - return idMat4( - mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, mat[0].w - a[0].w, - mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, mat[1].w - a[1].w, - mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z, mat[2].w - a[2].w, - mat[3].x - a[3].x, mat[3].y - a[3].y, mat[3].z - a[3].z, mat[3].w - a[3].w ); -} - -ID_INLINE idMat4 &idMat4::operator*=( const float a ) { - mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; mat[0].w *= a; - mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; mat[1].w *= a; - mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; mat[2].w *= a; - mat[3].x *= a; mat[3].y *= a; mat[3].z *= a; mat[3].w *= a; - return *this; -} - -ID_INLINE idMat4 &idMat4::operator*=( const idMat4 &a ) { - *this = (*this) * a; - return *this; -} - -ID_INLINE idMat4 &idMat4::operator+=( const idMat4 &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; mat[0].w += a[0].w; - mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; mat[1].w += a[1].w; - mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; mat[2].w += a[2].w; - mat[3].x += a[3].x; mat[3].y += a[3].y; mat[3].z += a[3].z; mat[3].w += a[3].w; - return *this; -} - -ID_INLINE idMat4 &idMat4::operator-=( const idMat4 &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; mat[0].w -= a[0].w; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; mat[1].w -= a[1].w; - mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; mat[2].w -= a[2].w; - mat[3].x -= a[3].x; mat[3].y -= a[3].y; mat[3].z -= a[3].z; mat[3].w -= a[3].w; - return *this; -} - -ID_INLINE idMat4 operator*( const float a, const idMat4 &mat ) { - return mat * a; -} - -ID_INLINE idVec4 operator*( const idVec4 &vec, const idMat4 &mat ) { - return mat * vec; -} - -ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat4 &mat ) { - return mat * vec; -} - -ID_INLINE idVec4 &operator*=( idVec4 &vec, const idMat4 &mat ) { - vec = mat * vec; - return vec; -} - -ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat4 &mat ) { - vec = mat * vec; - return vec; -} - -ID_INLINE bool idMat4::Compare( const idMat4 &a ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 4*4; i++ ) { - if ( ptr1[i] != ptr2[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat4::Compare( const idMat4 &a, const float epsilon ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 4*4; i++ ) { - if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat4::operator==( const idMat4 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMat4::operator!=( const idMat4 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMat4::Zero( void ) { - memset( mat, 0, sizeof( idMat4 ) ); -} - -ID_INLINE void idMat4::Identity( void ) { - *this = mat4_identity; -} - -ID_INLINE bool idMat4::IsIdentity( const float epsilon ) const { - return Compare( mat4_identity, epsilon ); -} - -ID_INLINE bool idMat4::IsSymmetric( const float epsilon ) const { - for ( int i = 1; i < 4; i++ ) { - for ( int j = 0; j < i; j++ ) { - if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMat4::IsDiagonal( const float epsilon ) const { - for ( int i = 0; i < 4; i++ ) { - for ( int j = 0; j < 4; j++ ) { - if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMat4::IsRotated( void ) const { - if ( !mat[ 0 ][ 1 ] && !mat[ 0 ][ 2 ] && - !mat[ 1 ][ 0 ] && !mat[ 1 ][ 2 ] && - !mat[ 2 ][ 0 ] && !mat[ 2 ][ 1 ] ) { - return false; - } - return true; -} - -ID_INLINE void idMat4::ProjectVector( const idVec4 &src, idVec4 &dst ) const { - dst.x = src * mat[ 0 ]; - dst.y = src * mat[ 1 ]; - dst.z = src * mat[ 2 ]; - dst.w = src * mat[ 3 ]; -} - -ID_INLINE void idMat4::UnprojectVector( const idVec4 &src, idVec4 &dst ) const { - dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z + mat[ 3 ] * src.w; -} - -ID_INLINE float idMat4::Trace( void ) const { - return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] ); -} - -ID_INLINE idMat4 idMat4::Inverse( void ) const { - idMat4 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat4 idMat4::InverseFast( void ) const { - idMat4 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat4 idMat3::ToMat4( void ) const { - // NOTE: idMat3 is transposed because it is column-major - return idMat4( mat[0][0], mat[1][0], mat[2][0], 0.0f, - mat[0][1], mat[1][1], mat[2][1], 0.0f, - mat[0][2], mat[1][2], mat[2][2], 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f ); -} - -ID_INLINE int idMat4::GetDimension( void ) const { - return 16; -} - -ID_INLINE const float *idMat4::ToFloatPtr( void ) const { - return mat[0].ToFloatPtr(); -} - -ID_INLINE float *idMat4::ToFloatPtr( void ) { - return mat[0].ToFloatPtr(); -} - - -//=============================================================== -// -// idMat5 - 5x5 matrix -// -//=============================================================== - -class idMat5 { -public: - idMat5( void ); - explicit idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 ); - explicit idMat5( const float src[ 5 ][ 5 ] ); - - const idVec5 & operator[]( int index ) const; - idVec5 & operator[]( int index ); - idMat5 operator*( const float a ) const; - idVec5 operator*( const idVec5 &vec ) const; - idMat5 operator*( const idMat5 &a ) const; - idMat5 operator+( const idMat5 &a ) const; - idMat5 operator-( const idMat5 &a ) const; - idMat5 & operator*=( const float a ); - idMat5 & operator*=( const idMat5 &a ); - idMat5 & operator+=( const idMat5 &a ); - idMat5 & operator-=( const idMat5 &a ); - - friend idMat5 operator*( const float a, const idMat5 &mat ); - friend idVec5 operator*( const idVec5 &vec, const idMat5 &mat ); - friend idVec5 & operator*=( idVec5 &vec, const idMat5 &mat ); - - bool Compare( const idMat5 &a ) const; // exact compare, no epsilon - bool Compare( const idMat5 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMat5 &a ) const; // exact compare, no epsilon - bool operator!=( const idMat5 &a ) const; // exact compare, no epsilon - - void Zero( void ); - void Identity( void ); - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - - float Trace( void ) const; - float Determinant( void ) const; - idMat5 Transpose( void ) const; // returns transpose - idMat5 & TransposeSelf( void ); - idMat5 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMat5 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - idVec5 mat[ 5 ]; -}; - -extern idMat5 mat5_zero; -extern idMat5 mat5_identity; -#define mat5_default mat5_identity - -ID_INLINE idMat5::idMat5( void ) { -} - -ID_INLINE idMat5::idMat5( const float src[ 5 ][ 5 ] ) { - memcpy( mat, src, 5 * 5 * sizeof( float ) ); -} - -ID_INLINE idMat5::idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 ) { - mat[0] = v0; - mat[1] = v1; - mat[2] = v2; - mat[3] = v3; - mat[4] = v4; -} - -ID_INLINE const idVec5 &idMat5::operator[]( int index ) const { - //assert( ( index >= 0 ) && ( index < 5 ) ); - return mat[ index ]; -} - -ID_INLINE idVec5 &idMat5::operator[]( int index ) { - //assert( ( index >= 0 ) && ( index < 5 ) ); - return mat[ index ]; -} - -ID_INLINE idMat5 idMat5::operator*( const idMat5 &a ) const { - int i, j; - const float *m1Ptr, *m2Ptr; - float *dstPtr; - idMat5 dst; - - m1Ptr = reinterpret_cast(this); - m2Ptr = reinterpret_cast(&a); - dstPtr = reinterpret_cast(&dst); - - for ( i = 0; i < 5; i++ ) { - for ( j = 0; j < 5; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 5 + j ]; - dstPtr++; - } - m1Ptr += 5; - } - return dst; -} - -ID_INLINE idMat5 idMat5::operator*( const float a ) const { - return idMat5( - idVec5( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a ), - idVec5( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a ), - idVec5( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a ), - idVec5( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a ), - idVec5( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a ) ); -} - -ID_INLINE idVec5 idMat5::operator*( const idVec5 &vec ) const { - return idVec5( - mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4], - mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4], - mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4], - mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4], - mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] ); -} - -ID_INLINE idMat5 idMat5::operator+( const idMat5 &a ) const { - return idMat5( - idVec5( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4] ), - idVec5( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4] ), - idVec5( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4] ), - idVec5( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4] ), - idVec5( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4] ) ); -} - -ID_INLINE idMat5 idMat5::operator-( const idMat5 &a ) const { - return idMat5( - idVec5( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4] ), - idVec5( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4] ), - idVec5( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4] ), - idVec5( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4] ), - idVec5( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4] ) ); -} - -ID_INLINE idMat5 &idMat5::operator*=( const float a ) { - mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a; - mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a; - mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a; - mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a; - mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a; - return *this; -} - -ID_INLINE idMat5 &idMat5::operator*=( const idMat5 &a ) { - *this = *this * a; - return *this; -} - -ID_INLINE idMat5 &idMat5::operator+=( const idMat5 &a ) { - mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4]; - mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4]; - mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4]; - mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4]; - mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4]; - return *this; -} - -ID_INLINE idMat5 &idMat5::operator-=( const idMat5 &a ) { - mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4]; - mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4]; - mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4]; - mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4]; - mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4]; - return *this; -} - -ID_INLINE idVec5 operator*( const idVec5 &vec, const idMat5 &mat ) { - return mat * vec; -} - -ID_INLINE idMat5 operator*( const float a, idMat5 const &mat ) { - return mat * a; -} - -ID_INLINE idVec5 &operator*=( idVec5 &vec, const idMat5 &mat ) { - vec = mat * vec; - return vec; -} - -ID_INLINE bool idMat5::Compare( const idMat5 &a ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 5*5; i++ ) { - if ( ptr1[i] != ptr2[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat5::Compare( const idMat5 &a, const float epsilon ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 5*5; i++ ) { - if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat5::operator==( const idMat5 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMat5::operator!=( const idMat5 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMat5::Zero( void ) { - memset( mat, 0, sizeof( idMat5 ) ); -} - -ID_INLINE void idMat5::Identity( void ) { - *this = mat5_identity; -} - -ID_INLINE bool idMat5::IsIdentity( const float epsilon ) const { - return Compare( mat5_identity, epsilon ); -} - -ID_INLINE bool idMat5::IsSymmetric( const float epsilon ) const { - for ( int i = 1; i < 5; i++ ) { - for ( int j = 0; j < i; j++ ) { - if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMat5::IsDiagonal( const float epsilon ) const { - for ( int i = 0; i < 5; i++ ) { - for ( int j = 0; j < 5; j++ ) { - if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE float idMat5::Trace( void ) const { - return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] ); -} - -ID_INLINE idMat5 idMat5::Inverse( void ) const { - idMat5 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat5 idMat5::InverseFast( void ) const { - idMat5 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE int idMat5::GetDimension( void ) const { - return 25; -} - -ID_INLINE const float *idMat5::ToFloatPtr( void ) const { - return mat[0].ToFloatPtr(); -} - -ID_INLINE float *idMat5::ToFloatPtr( void ) { - return mat[0].ToFloatPtr(); -} - - -//=============================================================== -// -// idMat6 - 6x6 matrix -// -//=============================================================== - -class idMat6 { -public: - idMat6( void ); - explicit idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 ); - explicit idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 ); - explicit idMat6( const float src[ 6 ][ 6 ] ); - - const idVec6 & operator[]( int index ) const; - idVec6 & operator[]( int index ); - idMat6 operator*( const float a ) const; - idVec6 operator*( const idVec6 &vec ) const; - idMat6 operator*( const idMat6 &a ) const; - idMat6 operator+( const idMat6 &a ) const; - idMat6 operator-( const idMat6 &a ) const; - idMat6 & operator*=( const float a ); - idMat6 & operator*=( const idMat6 &a ); - idMat6 & operator+=( const idMat6 &a ); - idMat6 & operator-=( const idMat6 &a ); - - friend idMat6 operator*( const float a, const idMat6 &mat ); - friend idVec6 operator*( const idVec6 &vec, const idMat6 &mat ); - friend idVec6 & operator*=( idVec6 &vec, const idMat6 &mat ); - - bool Compare( const idMat6 &a ) const; // exact compare, no epsilon - bool Compare( const idMat6 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMat6 &a ) const; // exact compare, no epsilon - bool operator!=( const idMat6 &a ) const; // exact compare, no epsilon - - void Zero( void ); - void Identity( void ); - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - - idMat3 SubMat3( int n ) const; - float Trace( void ) const; - float Determinant( void ) const; - idMat6 Transpose( void ) const; // returns transpose - idMat6 & TransposeSelf( void ); - idMat6 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMat6 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - idVec6 mat[ 6 ]; -}; - -extern idMat6 mat6_zero; -extern idMat6 mat6_identity; -#define mat6_default mat6_identity - -ID_INLINE idMat6::idMat6( void ) { -} - -ID_INLINE idMat6::idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 ) { - mat[0] = idVec6( m0[0][0], m0[0][1], m0[0][2], m1[0][0], m1[0][1], m1[0][2] ); - mat[1] = idVec6( m0[1][0], m0[1][1], m0[1][2], m1[1][0], m1[1][1], m1[1][2] ); - mat[2] = idVec6( m0[2][0], m0[2][1], m0[2][2], m1[2][0], m1[2][1], m1[2][2] ); - mat[3] = idVec6( m2[0][0], m2[0][1], m2[0][2], m3[0][0], m3[0][1], m3[0][2] ); - mat[4] = idVec6( m2[1][0], m2[1][1], m2[1][2], m3[1][0], m3[1][1], m3[1][2] ); - mat[5] = idVec6( m2[2][0], m2[2][1], m2[2][2], m3[2][0], m3[2][1], m3[2][2] ); -} - -ID_INLINE idMat6::idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 ) { - mat[0] = v0; - mat[1] = v1; - mat[2] = v2; - mat[3] = v3; - mat[4] = v4; - mat[5] = v5; -} - -ID_INLINE idMat6::idMat6( const float src[ 6 ][ 6 ] ) { - memcpy( mat, src, 6 * 6 * sizeof( float ) ); -} - -ID_INLINE const idVec6 &idMat6::operator[]( int index ) const { - //assert( ( index >= 0 ) && ( index < 6 ) ); - return mat[ index ]; -} - -ID_INLINE idVec6 &idMat6::operator[]( int index ) { - //assert( ( index >= 0 ) && ( index < 6 ) ); - return mat[ index ]; -} - -ID_INLINE idMat6 idMat6::operator*( const idMat6 &a ) const { - int i, j; - const float *m1Ptr, *m2Ptr; - float *dstPtr; - idMat6 dst; - - m1Ptr = reinterpret_cast(this); - m2Ptr = reinterpret_cast(&a); - dstPtr = reinterpret_cast(&dst); - - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 6; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 6 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 6 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 6 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 6 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 6 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 6 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return dst; -} - -ID_INLINE idMat6 idMat6::operator*( const float a ) const { - return idMat6( - idVec6( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a, mat[0][5] * a ), - idVec6( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a, mat[1][5] * a ), - idVec6( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a, mat[2][5] * a ), - idVec6( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a, mat[3][5] * a ), - idVec6( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a, mat[4][5] * a ), - idVec6( mat[5][0] * a, mat[5][1] * a, mat[5][2] * a, mat[5][3] * a, mat[5][4] * a, mat[5][5] * a ) ); -} - -ID_INLINE idVec6 idMat6::operator*( const idVec6 &vec ) const { - return idVec6( - mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4] + mat[0][5] * vec[5], - mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4] + mat[1][5] * vec[5], - mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4] + mat[2][5] * vec[5], - mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4] + mat[3][5] * vec[5], - mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] + mat[4][5] * vec[5], - mat[5][0] * vec[0] + mat[5][1] * vec[1] + mat[5][2] * vec[2] + mat[5][3] * vec[3] + mat[5][4] * vec[4] + mat[5][5] * vec[5] ); -} - -ID_INLINE idMat6 idMat6::operator+( const idMat6 &a ) const { - return idMat6( - idVec6( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4], mat[0][5] + a[0][5] ), - idVec6( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4], mat[1][5] + a[1][5] ), - idVec6( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4], mat[2][5] + a[2][5] ), - idVec6( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4], mat[3][5] + a[3][5] ), - idVec6( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4], mat[4][5] + a[4][5] ), - idVec6( mat[5][0] + a[5][0], mat[5][1] + a[5][1], mat[5][2] + a[5][2], mat[5][3] + a[5][3], mat[5][4] + a[5][4], mat[5][5] + a[5][5] ) ); -} - -ID_INLINE idMat6 idMat6::operator-( const idMat6 &a ) const { - return idMat6( - idVec6( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4], mat[0][5] - a[0][5] ), - idVec6( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4], mat[1][5] - a[1][5] ), - idVec6( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4], mat[2][5] - a[2][5] ), - idVec6( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4], mat[3][5] - a[3][5] ), - idVec6( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4], mat[4][5] - a[4][5] ), - idVec6( mat[5][0] - a[5][0], mat[5][1] - a[5][1], mat[5][2] - a[5][2], mat[5][3] - a[5][3], mat[5][4] - a[5][4], mat[5][5] - a[5][5] ) ); -} - -ID_INLINE idMat6 &idMat6::operator*=( const float a ) { - mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a; mat[0][5] *= a; - mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a; mat[1][5] *= a; - mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a; mat[2][5] *= a; - mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a; mat[3][5] *= a; - mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a; mat[4][5] *= a; - mat[5][0] *= a; mat[5][1] *= a; mat[5][2] *= a; mat[5][3] *= a; mat[5][4] *= a; mat[5][5] *= a; - return *this; -} - -ID_INLINE idMat6 &idMat6::operator*=( const idMat6 &a ) { - *this = *this * a; - return *this; -} - -ID_INLINE idMat6 &idMat6::operator+=( const idMat6 &a ) { - mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4]; mat[0][5] += a[0][5]; - mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4]; mat[1][5] += a[1][5]; - mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4]; mat[2][5] += a[2][5]; - mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4]; mat[3][5] += a[3][5]; - mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4]; mat[4][5] += a[4][5]; - mat[5][0] += a[5][0]; mat[5][1] += a[5][1]; mat[5][2] += a[5][2]; mat[5][3] += a[5][3]; mat[5][4] += a[5][4]; mat[5][5] += a[5][5]; - return *this; -} - -ID_INLINE idMat6 &idMat6::operator-=( const idMat6 &a ) { - mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4]; mat[0][5] -= a[0][5]; - mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4]; mat[1][5] -= a[1][5]; - mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4]; mat[2][5] -= a[2][5]; - mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4]; mat[3][5] -= a[3][5]; - mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4]; mat[4][5] -= a[4][5]; - mat[5][0] -= a[5][0]; mat[5][1] -= a[5][1]; mat[5][2] -= a[5][2]; mat[5][3] -= a[5][3]; mat[5][4] -= a[5][4]; mat[5][5] -= a[5][5]; - return *this; -} - -ID_INLINE idVec6 operator*( const idVec6 &vec, const idMat6 &mat ) { - return mat * vec; -} - -ID_INLINE idMat6 operator*( const float a, idMat6 const &mat ) { - return mat * a; -} - -ID_INLINE idVec6 &operator*=( idVec6 &vec, const idMat6 &mat ) { - vec = mat * vec; - return vec; -} - -ID_INLINE bool idMat6::Compare( const idMat6 &a ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 6*6; i++ ) { - if ( ptr1[i] != ptr2[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat6::Compare( const idMat6 &a, const float epsilon ) const { - dword i; - const float *ptr1, *ptr2; - - ptr1 = reinterpret_cast(mat); - ptr2 = reinterpret_cast(a.mat); - for ( i = 0; i < 6*6; i++ ) { - if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMat6::operator==( const idMat6 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMat6::operator!=( const idMat6 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMat6::Zero( void ) { - memset( mat, 0, sizeof( idMat6 ) ); -} - -ID_INLINE void idMat6::Identity( void ) { - *this = mat6_identity; -} - -ID_INLINE bool idMat6::IsIdentity( const float epsilon ) const { - return Compare( mat6_identity, epsilon ); -} - -ID_INLINE bool idMat6::IsSymmetric( const float epsilon ) const { - for ( int i = 1; i < 6; i++ ) { - for ( int j = 0; j < i; j++ ) { - if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMat6::IsDiagonal( const float epsilon ) const { - for ( int i = 0; i < 6; i++ ) { - for ( int j = 0; j < 6; j++ ) { - if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE idMat3 idMat6::SubMat3( int n ) const { - assert( n >= 0 && n < 4 ); - int b0 = ((n & 2) >> 1) * 3; - int b1 = (n & 1) * 3; - return idMat3( - mat[b0 + 0][b1 + 0], mat[b0 + 0][b1 + 1], mat[b0 + 0][b1 + 2], - mat[b0 + 1][b1 + 0], mat[b0 + 1][b1 + 1], mat[b0 + 1][b1 + 2], - mat[b0 + 2][b1 + 0], mat[b0 + 2][b1 + 1], mat[b0 + 2][b1 + 2] ); -} - -ID_INLINE float idMat6::Trace( void ) const { - return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] + mat[5][5] ); -} - -ID_INLINE idMat6 idMat6::Inverse( void ) const { - idMat6 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE idMat6 idMat6::InverseFast( void ) const { - idMat6 invMat; - - invMat = *this; - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE int idMat6::GetDimension( void ) const { - return 36; -} - -ID_INLINE const float *idMat6::ToFloatPtr( void ) const { - return mat[0].ToFloatPtr(); -} - -ID_INLINE float *idMat6::ToFloatPtr( void ) { - return mat[0].ToFloatPtr(); -} - - -//=============================================================== -// -// idMatX - arbitrary sized dense real matrix -// -// The matrix lives on 16 byte aligned and 16 byte padded memory. -// -// NOTE: due to the temporary memory pool idMatX cannot be used by multiple threads. -// -//=============================================================== - -#define MATX_MAX_TEMP 1024 -#define MATX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) ) -#define MATX_CLEAREND() int s = numRows * numColumns; while( s < ( ( s + 3 ) & ~3 ) ) { mat[s++] = 0.0f; } -#define MATX_ALLOCA( n ) ( (float *) _alloca16( MATX_QUAD( n ) ) ) -#define MATX_SIMD - -class idMatX { -public: - idMatX( void ); - explicit idMatX( int rows, int columns ); - explicit idMatX( int rows, int columns, float *src ); - ~idMatX( void ); - - void Set( int rows, int columns, const float *src ); - void Set( const idMat3 &m1, const idMat3 &m2 ); - void Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 ); - - const float * operator[]( int index ) const; - float * operator[]( int index ); - idMatX & operator=( const idMatX &a ); - idMatX operator*( const float a ) const; - idVecX operator*( const idVecX &vec ) const; - idMatX operator*( const idMatX &a ) const; - idMatX operator+( const idMatX &a ) const; - idMatX operator-( const idMatX &a ) const; - idMatX & operator*=( const float a ); - idMatX & operator*=( const idMatX &a ); - idMatX & operator+=( const idMatX &a ); - idMatX & operator-=( const idMatX &a ); - - friend idMatX operator*( const float a, const idMatX &m ); - friend idVecX operator*( const idVecX &vec, const idMatX &m ); - friend idVecX & operator*=( idVecX &vec, const idMatX &m ); - - bool Compare( const idMatX &a ) const; // exact compare, no epsilon - bool Compare( const idMatX &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idMatX &a ) const; // exact compare, no epsilon - bool operator!=( const idMatX &a ) const; // exact compare, no epsilon - - void SetSize( int rows, int columns ); // set the number of rows/columns - void ChangeSize( int rows, int columns, bool makeZero = false ); // change the size keeping data intact where possible - int GetNumRows( void ) const { return numRows; } // get the number of rows - int GetNumColumns( void ) const { return numColumns; } // get the number of columns - void SetData( int rows, int columns, float *data ); // set float array pointer - void Zero( void ); // clear matrix - void Zero( int rows, int columns ); // set size and clear matrix - void Identity( void ); // clear to identity matrix - void Identity( int rows, int columns ); // set size and clear to identity matrix - void Diag( const idVecX &v ); // create diagonal matrix from vector - void Random( int seed, float l = 0.0f, float u = 1.0f ); // fill matrix with random values - void Random( int rows, int columns, int seed, float l = 0.0f, float u = 1.0f ); - void Negate( void ); // (*this) = - (*this) - void Clamp( float min, float max ); // clamp all values - idMatX & SwapRows( int r1, int r2 ); // swap rows - idMatX & SwapColumns( int r1, int r2 ); // swap columns - idMatX & SwapRowsColumns( int r1, int r2 ); // swap rows and columns - idMatX & RemoveRow( int r ); // remove a row - idMatX & RemoveColumn( int r ); // remove a column - idMatX & RemoveRowColumn( int r ); // remove a row and column - void ClearUpperTriangle( void ); // clear the upper triangle - void ClearLowerTriangle( void ); // clear the lower triangle - void SquareSubMatrix( const idMatX &m, int size ); // get square sub-matrix from 0,0 to size,size - float MaxDifference( const idMatX &m ) const; // return maximum element difference between this and m - - bool IsSquare( void ) const { return ( numRows == numColumns ); } - bool IsZero( const float epsilon = MATRIX_EPSILON ) const; - bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const; - bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const; - bool IsTriDiagonal( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const; - bool IsOrthogonal( const float epsilon = MATRIX_EPSILON ) const; - bool IsOrthonormal( const float epsilon = MATRIX_EPSILON ) const; - bool IsPMatrix( const float epsilon = MATRIX_EPSILON ) const; - bool IsZMatrix( const float epsilon = MATRIX_EPSILON ) const; - bool IsPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetricPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const; - bool IsPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const; - bool IsSymmetricPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const; - - float Trace( void ) const; // returns product of diagonal elements - float Determinant( void ) const; // returns determinant of matrix - idMatX Transpose( void ) const; // returns transpose - idMatX & TransposeSelf( void ); // transposes the matrix itself - idMatX Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseSelf( void ); // returns false if determinant is zero - idMatX InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity ) - bool InverseFastSelf( void ); // returns false if determinant is zero - - bool LowerTriangularInverse( void ); // in-place inversion, returns false if determinant is zero - bool UpperTriangularInverse( void ); // in-place inversion, returns false if determinant is zero - - idVecX Multiply( const idVecX &vec ) const; // (*this) * vec - idVecX TransposeMultiply( const idVecX &vec ) const; // this->Transpose() * vec - - idMatX Multiply( const idMatX &a ) const; // (*this) * a - idMatX TransposeMultiply( const idMatX &a ) const; // this->Transpose() * a - - void Multiply( idVecX &dst, const idVecX &vec ) const; // dst = (*this) * vec - void MultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += (*this) * vec - void MultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= (*this) * vec - void TransposeMultiply( idVecX &dst, const idVecX &vec ) const; // dst = this->Transpose() * vec - void TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += this->Transpose() * vec - void TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= this->Transpose() * vec - - void Multiply( idMatX &dst, const idMatX &a ) const; // dst = (*this) * a - void TransposeMultiply( idMatX &dst, const idMatX &a ) const; // dst = this->Transpose() * a - - int GetDimension( void ) const; // returns total number of values in matrix - - const idVec6 & SubVec6( int row ) const; // interpret beginning of row as a const idVec6 - idVec6 & SubVec6( int row ); // interpret beginning of row as an idVec6 - const idVecX SubVecX( int row ) const; // interpret complete row as a const idVecX - idVecX SubVecX( int row ); // interpret complete row as an idVecX - const float * ToFloatPtr( void ) const; // pointer to const matrix float array - float * ToFloatPtr( void ); // pointer to matrix float array - const char * ToString( int precision = 2 ) const; - - void Update_RankOne( const idVecX &v, const idVecX &w, float alpha ); - void Update_RankOneSymmetric( const idVecX &v, float alpha ); - void Update_RowColumn( const idVecX &v, const idVecX &w, int r ); - void Update_RowColumnSymmetric( const idVecX &v, int r ); - void Update_Increment( const idVecX &v, const idVecX &w ); - void Update_IncrementSymmetric( const idVecX &v ); - void Update_Decrement( int r ); - - bool Inverse_GaussJordan( void ); // invert in-place with Gauss-Jordan elimination - bool Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha ); - bool Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r ); - bool Inverse_UpdateIncrement( const idVecX &v, const idVecX &w ); - bool Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r ); - void Inverse_Solve( idVecX &x, const idVecX &b ) const; - - bool LU_Factor( int *index, float *det = NULL ); // factor in-place: L * U - bool LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index ); - bool LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index ); - bool LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index ); - bool LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index ); - void LU_Solve( idVecX &x, const idVecX &b, const int *index ) const; - void LU_Inverse( idMatX &inv, const int *index ) const; - void LU_UnpackFactors( idMatX &L, idMatX &U ) const; - void LU_MultiplyFactors( idMatX &m, const int *index ) const; - - bool QR_Factor( idVecX &c, idVecX &d ); // factor in-place: Q * R - bool QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha ); - bool QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r ); - bool QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w ); - bool QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r ); - void QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const; - void QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const; - void QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const; - void QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const; - void QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const; - - bool SVD_Factor( idVecX &w, idMatX &V ); // factor in-place: U * Diag(w) * V.Transpose() - void SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const; - void SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const; - void SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const; - - bool Cholesky_Factor( void ); // factor in-place: L * L.Transpose() - bool Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 ); - bool Cholesky_UpdateRowColumn( const idVecX &v, int r ); - bool Cholesky_UpdateIncrement( const idVecX &v ); - bool Cholesky_UpdateDecrement( const idVecX &v, int r ); - void Cholesky_Solve( idVecX &x, const idVecX &b ) const; - void Cholesky_Inverse( idMatX &inv ) const; - void Cholesky_MultiplyFactors( idMatX &m ) const; - - bool LDLT_Factor( void ); // factor in-place: L * D * L.Transpose() - bool LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 ); - bool LDLT_UpdateRowColumn( const idVecX &v, int r ); - bool LDLT_UpdateIncrement( const idVecX &v ); - bool LDLT_UpdateDecrement( const idVecX &v, int r ); - void LDLT_Solve( idVecX &x, const idVecX &b ) const; - void LDLT_Inverse( idMatX &inv ) const; - void LDLT_UnpackFactors( idMatX &L, idMatX &D ) const; - void LDLT_MultiplyFactors( idMatX &m ) const; - - void TriDiagonal_ClearTriangles( void ); - bool TriDiagonal_Solve( idVecX &x, const idVecX &b ) const; - void TriDiagonal_Inverse( idMatX &inv ) const; - - bool Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues ); - bool Eigen_SolveSymmetric( idVecX &eigenValues ); - bool Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues ); - void Eigen_SortIncreasing( idVecX &eigenValues ); - void Eigen_SortDecreasing( idVecX &eigenValues ); - - static void Test( void ); - -private: - int numRows; // number of rows - int numColumns; // number of columns - int alloced; // floats allocated, if -1 then mat points to data set with SetData - float * mat; // memory the matrix is stored - - static float temp[MATX_MAX_TEMP+4]; // used to store intermediate results - static float * tempPtr; // pointer to 16 byte aligned temporary memory - static int tempIndex; // index into memory pool, wraps around - -private: - void SetTempSize( int rows, int columns ); - float DeterminantGeneric( void ) const; - bool InverseSelfGeneric( void ); - void QR_Rotate( idMatX &R, int i, float a, float b ); - float Pythag( float a, float b ) const; - void SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm ); - void SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 ); - void HouseholderReduction( idVecX &diag, idVecX &subd ); - bool QL( idVecX &diag, idVecX &subd ); - void HessenbergReduction( idMatX &H ); - void ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi ); - bool HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues ); -}; - -ID_INLINE idMatX::idMatX( void ) { - numRows = numColumns = alloced = 0; - mat = NULL; -} - -ID_INLINE idMatX::~idMatX( void ) { - // if not temp memory - if ( mat != NULL && ( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ) && alloced != -1 ) { - Mem_Free16( mat ); - } -} - -ID_INLINE idMatX::idMatX( int rows, int columns ) { - numRows = numColumns = alloced = 0; - mat = NULL; - SetSize( rows, columns ); -} - -ID_INLINE idMatX::idMatX( int rows, int columns, float *src ) { - numRows = numColumns = alloced = 0; - mat = NULL; - SetData( rows, columns, src ); -} - -ID_INLINE void idMatX::Set( int rows, int columns, const float *src ) { - SetSize( rows, columns ); - memcpy( this->mat, src, rows * columns * sizeof( float ) ); -} - -ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2 ) { - int i, j; - - SetSize( 3, 6 ); - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - mat[(i+0) * numColumns + (j+0)] = m1[i][j]; - mat[(i+0) * numColumns + (j+3)] = m2[i][j]; - } - } -} - -ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 ) { - int i, j; - - SetSize( 6, 6 ); - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - mat[(i+0) * numColumns + (j+0)] = m1[i][j]; - mat[(i+0) * numColumns + (j+3)] = m2[i][j]; - mat[(i+3) * numColumns + (j+0)] = m3[i][j]; - mat[(i+3) * numColumns + (j+3)] = m4[i][j]; - } - } -} - -ID_INLINE const float *idMatX::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < numRows ) ); - return mat + index * numColumns; -} - -ID_INLINE float *idMatX::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < numRows ) ); - return mat + index * numColumns; -} - -ID_INLINE idMatX &idMatX::operator=( const idMatX &a ) { - SetSize( a.numRows, a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->Copy16( mat, a.mat, a.numRows * a.numColumns ); -#else - memcpy( mat, a.mat, a.numRows * a.numColumns * sizeof( float ) ); -#endif - idMatX::tempIndex = 0; - return *this; -} - -ID_INLINE idMatX idMatX::operator*( const float a ) const { - idMatX m; - - m.SetTempSize( numRows, numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->Mul16( m.mat, mat, a, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - m.mat[i] = mat[i] * a; - } -#endif - return m; -} - -ID_INLINE idVecX idMatX::operator*( const idVecX &vec ) const { - idVecX dst; - - assert( numColumns == vec.GetSize() ); - - dst.SetTempSize( numRows ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); -#else - Multiply( dst, vec ); -#endif - return dst; -} - -ID_INLINE idMatX idMatX::operator*( const idMatX &a ) const { - idMatX dst; - - assert( numColumns == a.numRows ); - - dst.SetTempSize( numRows, a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); -#else - Multiply( dst, a ); -#endif - return dst; -} - -ID_INLINE idMatX idMatX::operator+( const idMatX &a ) const { - idMatX m; - - assert( numRows == a.numRows && numColumns == a.numColumns ); - m.SetTempSize( numRows, numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->Add16( m.mat, mat, a.mat, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - m.mat[i] = mat[i] + a.mat[i]; - } -#endif - return m; -} - -ID_INLINE idMatX idMatX::operator-( const idMatX &a ) const { - idMatX m; - - assert( numRows == a.numRows && numColumns == a.numColumns ); - m.SetTempSize( numRows, numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->Sub16( m.mat, mat, a.mat, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - m.mat[i] = mat[i] - a.mat[i]; - } -#endif - return m; -} - -ID_INLINE idMatX &idMatX::operator*=( const float a ) { -#ifdef MATX_SIMD - SIMDProcessor->MulAssign16( mat, a, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] *= a; - } -#endif - idMatX::tempIndex = 0; - return *this; -} - -ID_INLINE idMatX &idMatX::operator*=( const idMatX &a ) { - *this = *this * a; - idMatX::tempIndex = 0; - return *this; -} - -ID_INLINE idMatX &idMatX::operator+=( const idMatX &a ) { - assert( numRows == a.numRows && numColumns == a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->AddAssign16( mat, a.mat, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] += a.mat[i]; - } -#endif - idMatX::tempIndex = 0; - return *this; -} - -ID_INLINE idMatX &idMatX::operator-=( const idMatX &a ) { - assert( numRows == a.numRows && numColumns == a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->SubAssign16( mat, a.mat, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] -= a.mat[i]; - } -#endif - idMatX::tempIndex = 0; - return *this; -} - -ID_INLINE idMatX operator*( const float a, idMatX const &m ) { - return m * a; -} - -ID_INLINE idVecX operator*( const idVecX &vec, const idMatX &m ) { - return m * vec; -} - -ID_INLINE idVecX &operator*=( idVecX &vec, const idMatX &m ) { - vec = m * vec; - return vec; -} - -ID_INLINE bool idMatX::Compare( const idMatX &a ) const { - int i, s; - - assert( numRows == a.numRows && numColumns == a.numColumns ); - - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - if ( mat[i] != a.mat[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMatX::Compare( const idMatX &a, const float epsilon ) const { - int i, s; - - assert( numRows == a.numRows && numColumns == a.numColumns ); - - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idMatX::operator==( const idMatX &a ) const { - return Compare( a ); -} - -ID_INLINE bool idMatX::operator!=( const idMatX &a ) const { - return !Compare( a ); -} - -ID_INLINE void idMatX::SetSize( int rows, int columns ) { - assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ); - int alloc = ( rows * columns + 3 ) & ~3; - if ( alloc > alloced && alloced != -1 ) { - if ( mat != NULL ) { - Mem_Free16( mat ); - } - mat = (float *) Mem_Alloc16( alloc * sizeof( float ) ); - alloced = alloc; - } - numRows = rows; - numColumns = columns; - MATX_CLEAREND(); -} - -ID_INLINE void idMatX::SetTempSize( int rows, int columns ) { - int newSize; - - newSize = ( rows * columns + 3 ) & ~3; - assert( newSize < MATX_MAX_TEMP ); - if ( idMatX::tempIndex + newSize > MATX_MAX_TEMP ) { - idMatX::tempIndex = 0; - } - mat = idMatX::tempPtr + idMatX::tempIndex; - idMatX::tempIndex += newSize; - alloced = newSize; - numRows = rows; - numColumns = columns; - MATX_CLEAREND(); -} - -ID_INLINE void idMatX::SetData( int rows, int columns, float *data ) { - assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ); - if ( mat != NULL && alloced != -1 ) { - Mem_Free16( mat ); - } - assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned - mat = data; - alloced = -1; - numRows = rows; - numColumns = columns; - MATX_CLEAREND(); -} - -ID_INLINE void idMatX::Zero( void ) { -#ifdef MATX_SIMD - SIMDProcessor->Zero16( mat, numRows * numColumns ); -#else - memset( mat, 0, numRows * numColumns * sizeof( float ) ); -#endif -} - -ID_INLINE void idMatX::Zero( int rows, int columns ) { - SetSize( rows, columns ); -#ifdef MATX_SIMD - SIMDProcessor->Zero16( mat, numRows * numColumns ); -#else - memset( mat, 0, rows * columns * sizeof( float ) ); -#endif -} - -ID_INLINE void idMatX::Identity( void ) { - assert( numRows == numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->Zero16( mat, numRows * numColumns ); -#else - memset( mat, 0, numRows * numColumns * sizeof( float ) ); -#endif - for ( int i = 0; i < numRows; i++ ) { - mat[i * numColumns + i] = 1.0f; - } -} - -ID_INLINE void idMatX::Identity( int rows, int columns ) { - assert( rows == columns ); - SetSize( rows, columns ); - idMatX::Identity(); -} - -ID_INLINE void idMatX::Diag( const idVecX &v ) { - Zero( v.GetSize(), v.GetSize() ); - for ( int i = 0; i < v.GetSize(); i++ ) { - mat[i * numColumns + i] = v[i]; - } -} - -ID_INLINE void idMatX::Random( int seed, float l, float u ) { - int i, s; - float c; - idRandom rnd(seed); - - c = u - l; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] = l + rnd.RandomFloat() * c; - } -} - -ID_INLINE void idMatX::Random( int rows, int columns, int seed, float l, float u ) { - int i, s; - float c; - idRandom rnd(seed); - - SetSize( rows, columns ); - c = u - l; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] = l + rnd.RandomFloat() * c; - } -} - -ID_INLINE void idMatX::Negate( void ) { -#ifdef MATX_SIMD - SIMDProcessor->Negate16( mat, numRows * numColumns ); -#else - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - mat[i] = -mat[i]; - } -#endif -} - -ID_INLINE void idMatX::Clamp( float min, float max ) { - int i, s; - s = numRows * numColumns; - for ( i = 0; i < s; i++ ) { - if ( mat[i] < min ) { - mat[i] = min; - } else if ( mat[i] > max ) { - mat[i] = max; - } - } -} - -inline idMatX &idMatX::SwapRows( int r1, int r2 ) { - float *ptr; - - ptr = (float *) _alloca16( numColumns * sizeof( float ) ); - memcpy( ptr, mat + r1 * numColumns, numColumns * sizeof( float ) ); - memcpy( mat + r1 * numColumns, mat + r2 * numColumns, numColumns * sizeof( float ) ); - memcpy( mat + r2 * numColumns, ptr, numColumns * sizeof( float ) ); - - return *this; -} - -ID_INLINE idMatX &idMatX::SwapColumns( int r1, int r2 ) { - int i; - float tmp, *ptr; - - for ( i = 0; i < numRows; i++ ) { - ptr = mat + i * numColumns; - tmp = ptr[r1]; - ptr[r1] = ptr[r2]; - ptr[r2] = tmp; - } - - return *this; -} - -ID_INLINE idMatX &idMatX::SwapRowsColumns( int r1, int r2 ) { - - SwapRows( r1, r2 ); - SwapColumns( r1, r2 ); - return *this; -} - -ID_INLINE void idMatX::ClearUpperTriangle( void ) { - assert( numRows == numColumns ); - for ( int i = numRows-2; i >= 0; i-- ) { - memset( mat + i * numColumns + i + 1, 0, (numColumns - 1 - i) * sizeof(float) ); - } -} - -ID_INLINE void idMatX::ClearLowerTriangle( void ) { - assert( numRows == numColumns ); - for ( int i = 1; i < numRows; i++ ) { - memset( mat + i * numColumns, 0, i * sizeof(float) ); - } -} - -ID_INLINE void idMatX::SquareSubMatrix( const idMatX &m, int size ) { - int i; - assert( size <= m.numRows && size <= m.numColumns ); - SetSize( size, size ); - for ( i = 0; i < size; i++ ) { - memcpy( mat + i * numColumns, m.mat + i * m.numColumns, size * sizeof( float ) ); - } -} - -ID_INLINE float idMatX::MaxDifference( const idMatX &m ) const { - int i, j; - float diff, maxDiff; - - assert( numRows == m.numRows && numColumns == m.numColumns ); - - maxDiff = -1.0f; - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - diff = idMath::Fabs( mat[ i * numColumns + j ] - m[i][j] ); - if ( maxDiff < 0.0f || diff > maxDiff ) { - maxDiff = diff; - } - } - } - return maxDiff; -} - -ID_INLINE bool idMatX::IsZero( const float epsilon ) const { - // returns true if (*this) == Zero - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - if ( idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMatX::IsIdentity( const float epsilon ) const { - // returns true if (*this) == Identity - assert( numRows == numColumns ); - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - if ( idMath::Fabs( mat[i * numColumns + j] - (float)( i == j ) ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMatX::IsDiagonal( const float epsilon ) const { - // returns true if all elements are zero except for the elements on the diagonal - assert( numRows == numColumns ); - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - if ( i != j && idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMatX::IsTriDiagonal( const float epsilon ) const { - // returns true if all elements are zero except for the elements on the diagonal plus or minus one column - - if ( numRows != numColumns ) { - return false; - } - for ( int i = 0; i < numRows-2; i++ ) { - for ( int j = i+2; j < numColumns; j++ ) { - if ( idMath::Fabs( (*this)[i][j] ) > epsilon ) { - return false; - } - if ( idMath::Fabs( (*this)[j][i] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE bool idMatX::IsSymmetric( const float epsilon ) const { - // (*this)[i][j] == (*this)[j][i] - if ( numRows != numColumns ) { - return false; - } - for ( int i = 0; i < numRows; i++ ) { - for ( int j = 0; j < numColumns; j++ ) { - if ( idMath::Fabs( mat[ i * numColumns + j ] - mat[ j * numColumns + i ] ) > epsilon ) { - return false; - } - } - } - return true; -} - -ID_INLINE float idMatX::Trace( void ) const { - float trace = 0.0f; - - assert( numRows == numColumns ); - - // sum of elements on the diagonal - for ( int i = 0; i < numRows; i++ ) { - trace += mat[i * numRows + i]; - } - return trace; -} - -ID_INLINE float idMatX::Determinant( void ) const { - - assert( numRows == numColumns ); - - switch( numRows ) { - case 1: - return mat[0]; - case 2: - return reinterpret_cast(mat)->Determinant(); - case 3: - return reinterpret_cast(mat)->Determinant(); - case 4: - return reinterpret_cast(mat)->Determinant(); - case 5: - return reinterpret_cast(mat)->Determinant(); - case 6: - return reinterpret_cast(mat)->Determinant(); - default: - return DeterminantGeneric(); - } - return 0.0f; -} - -ID_INLINE idMatX idMatX::Transpose( void ) const { - idMatX transpose; - int i, j; - - transpose.SetTempSize( numColumns, numRows ); - - for ( i = 0; i < numRows; i++ ) { - for ( j = 0; j < numColumns; j++ ) { - transpose.mat[j * transpose.numColumns + i] = mat[i * numColumns + j]; - } - } - - return transpose; -} - -ID_INLINE idMatX &idMatX::TransposeSelf( void ) { - *this = Transpose(); - return *this; -} - -ID_INLINE idMatX idMatX::Inverse( void ) const { - idMatX invMat; - - invMat.SetTempSize( numRows, numColumns ); - memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) ); - -#ifdef DEBUG - int r = invMat.InverseSelf(); - assert( r ); -#else - invMat.InverseSelf(); -#endif - - return invMat; -} - -ID_INLINE bool idMatX::InverseSelf( void ) { - - assert( numRows == numColumns ); - - switch( numRows ) { - case 1: - if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - mat[0] = 1.0f / mat[0]; - return true; - case 2: - return reinterpret_cast(mat)->InverseSelf(); - case 3: - return reinterpret_cast(mat)->InverseSelf(); - case 4: - return reinterpret_cast(mat)->InverseSelf(); - case 5: - return reinterpret_cast(mat)->InverseSelf(); - case 6: - return reinterpret_cast(mat)->InverseSelf(); - default: - return InverseSelfGeneric(); - } -} - -ID_INLINE idMatX idMatX::InverseFast( void ) const { - idMatX invMat; - - invMat.SetTempSize( numRows, numColumns ); - memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) ); - -#ifdef DEBUG - int r = invMat.InverseFastSelf(); - assert( r ); -#else - invMat.InverseFastSelf(); -#endif - - return invMat; -} - -ID_INLINE bool idMatX::InverseFastSelf( void ) { - - assert( numRows == numColumns ); - - switch( numRows ) { - case 1: - if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) { - return false; - } - mat[0] = 1.0f / mat[0]; - return true; - case 2: - return reinterpret_cast(mat)->InverseFastSelf(); - case 3: - return reinterpret_cast(mat)->InverseFastSelf(); - case 4: - return reinterpret_cast(mat)->InverseFastSelf(); - case 5: - return reinterpret_cast(mat)->InverseFastSelf(); - case 6: - return reinterpret_cast(mat)->InverseFastSelf(); - default: - return InverseSelfGeneric(); - } -// return false; -} - -ID_INLINE idVecX idMatX::Multiply( const idVecX &vec ) const { - idVecX dst; - - assert( numColumns == vec.GetSize() ); - - dst.SetTempSize( numRows ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); -#else - Multiply( dst, vec ); -#endif - return dst; -} - -ID_INLINE idMatX idMatX::Multiply( const idMatX &a ) const { - idMatX dst; - - assert( numColumns == a.numRows ); - - dst.SetTempSize( numRows, a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); -#else - Multiply( dst, a ); -#endif - return dst; -} - -ID_INLINE idVecX idMatX::TransposeMultiply( const idVecX &vec ) const { - idVecX dst; - - assert( numRows == vec.GetSize() ); - - dst.SetTempSize( numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec ); -#else - TransposeMultiply( dst, vec ); -#endif - return dst; -} - -ID_INLINE idMatX idMatX::TransposeMultiply( const idMatX &a ) const { - idMatX dst; - - assert( numRows == a.numRows ); - - dst.SetTempSize( numColumns, a.numColumns ); -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a ); -#else - TransposeMultiply( dst, a ); -#endif - return dst; -} - -ID_INLINE void idMatX::Multiply( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - mPtr = mat; - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] = sum; - mPtr += numColumns; - } -#endif -} - -ID_INLINE void idMatX::MultiplyAdd( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyAddVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - mPtr = mat; - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] += sum; - mPtr += numColumns; - } -#endif -} - -ID_INLINE void idMatX::MultiplySub( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplySubVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - mPtr = mat; - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] -= sum; - mPtr += numColumns; - } -#endif -} - -ID_INLINE void idMatX::TransposeMultiply( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat + i; - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] = sum; - } -#endif -} - -ID_INLINE void idMatX::TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplyAddVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat + i; - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] += sum; - } -#endif -} - -ID_INLINE void idMatX::TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplySubVecX( dst, *this, vec ); -#else - int i, j; - const float *mPtr, *vPtr; - float *dstPtr; - - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat + i; - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] -= sum; - } -#endif -} - -ID_INLINE void idMatX::Multiply( idMatX &dst, const idMatX &a ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_MultiplyMatX( dst, *this, a ); -#else - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( numColumns == a.numRows ); - - dstPtr = dst.ToFloatPtr(); - m1Ptr = ToFloatPtr(); - m2Ptr = a.ToFloatPtr(); - k = numRows; - l = a.GetNumColumns(); - - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m2Ptr = a.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < numColumns; n++ ) { - m2Ptr += l; - sum += m1Ptr[n] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - m1Ptr += numColumns; - } -#endif -} - -ID_INLINE void idMatX::TransposeMultiply( idMatX &dst, const idMatX &a ) const { -#ifdef MATX_SIMD - SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a ); -#else - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( numRows == a.numRows ); - - dstPtr = dst.ToFloatPtr(); - m1Ptr = ToFloatPtr(); - k = numColumns; - l = a.numColumns; - - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m1Ptr = ToFloatPtr() + i; - m2Ptr = a.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < numRows; n++ ) { - m1Ptr += numColumns; - m2Ptr += a.numColumns; - sum += m1Ptr[0] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - } -#endif -} - -ID_INLINE int idMatX::GetDimension( void ) const { - return numRows * numColumns; -} - -ID_INLINE const idVec6 &idMatX::SubVec6( int row ) const { - assert( numColumns >= 6 && row >= 0 && row < numRows ); - return *reinterpret_cast(mat + row * numColumns); -} - -ID_INLINE idVec6 &idMatX::SubVec6( int row ) { - assert( numColumns >= 6 && row >= 0 && row < numRows ); - return *reinterpret_cast(mat + row * numColumns); -} - -ID_INLINE const idVecX idMatX::SubVecX( int row ) const { - idVecX v; - assert( row >= 0 && row < numRows ); - v.SetData( numColumns, mat + row * numColumns ); - return v; -} - -ID_INLINE idVecX idMatX::SubVecX( int row ) { - idVecX v; - assert( row >= 0 && row < numRows ); - v.SetData( numColumns, mat + row * numColumns ); - return v; -} - -ID_INLINE const float *idMatX::ToFloatPtr( void ) const { - return mat; -} - -ID_INLINE float *idMatX::ToFloatPtr( void ) { - return mat; -} - -#endif /* !__MATH_MATRIX_H__ */ diff --git a/idlib/math/ode.cpp b/idlib/math/ode.cpp deleted file mode 100644 index 55c12d662..000000000 --- a/idlib/math/ode.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -//=============================================================== -// -// idODE_Euler -// -//=============================================================== - -/* -============= -idODE_Euler::idODE_Euler -============= -*/ -idODE_Euler::idODE_Euler( const int dim, deriveFunction_t dr, const void *ud ) { - dimension = dim; - derivatives = new float[dim]; - derive = dr; - userData = ud; -} - -/* -============= -idODE_Euler::~idODE_Euler -============= -*/ -idODE_Euler::~idODE_Euler( void ) { - delete[] derivatives; -} - -/* -============= -idODE_Euler::Evaluate -============= -*/ -float idODE_Euler::Evaluate( const float *state, float *newState, float t0, float t1 ) { - float delta; - int i; - - derive( t0, userData, state, derivatives ); - delta = t1 - t0; - for ( i = 0; i < dimension; i++ ) { - newState[i] = state[i] + delta * derivatives[i]; - } - return delta; -} - -//=============================================================== -// -// idODE_Midpoint -// -//=============================================================== - -/* -============= -idODE_Midpoint::idODE_Midpoint -============= -*/ -idODE_Midpoint::idODE_Midpoint( const int dim, deriveFunction_t dr, const void *ud ) { - dimension = dim; - tmpState = new float[dim]; - derivatives = new float[dim]; - derive = dr; - userData = ud; -} - -/* -============= -idODE_Midpoint::~idODE_Midpoint -============= -*/ -idODE_Midpoint::~idODE_Midpoint( void ) { - delete tmpState; - delete derivatives; -} - -/* -============= -idODE_Midpoint::~Evaluate -============= -*/ -float idODE_Midpoint::Evaluate( const float *state, float *newState, float t0, float t1 ) { - double delta, halfDelta; - int i; - - delta = t1 - t0; - halfDelta = delta * 0.5; - // first step - derive( t0, userData, state, derivatives ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * derivatives[i]; - } - // second step - derive( t0 + halfDelta, userData, tmpState, derivatives ); - - for ( i = 0; i < dimension; i++ ) { - newState[i] = state[i] + delta * derivatives[i]; - } - return delta; -} - -//=============================================================== -// -// idODE_RK4 -// -//=============================================================== - -/* -============= -idODE_RK4::idODE_RK4 -============= -*/ -idODE_RK4::idODE_RK4( const int dim, deriveFunction_t dr, const void *ud ) { - dimension = dim; - derive = dr; - userData = ud; - tmpState = new float[dim]; - d1 = new float[dim]; - d2 = new float[dim]; - d3 = new float[dim]; - d4 = new float[dim]; -} - -/* -============= -idODE_RK4::~idODE_RK4 -============= -*/ -idODE_RK4::~idODE_RK4( void ) { - delete tmpState; - delete d1; - delete d2; - delete d3; - delete d4; -} - -/* -============= -idODE_RK4::Evaluate -============= -*/ -float idODE_RK4::Evaluate( const float *state, float *newState, float t0, float t1 ) { - double delta, halfDelta, sixthDelta; - int i; - - delta = t1 - t0; - halfDelta = delta * 0.5; - // first step - derive( t0, userData, state, d1 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d1[i]; - } - // second step - derive( t0 + halfDelta, userData, tmpState, d2 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d2[i]; - } - // third step - derive( t0 + halfDelta, userData, tmpState, d3 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + delta * d3[i]; - } - // fourth step - derive( t0 + delta, userData, tmpState, d4 ); - - sixthDelta = delta * (1.0/6.0); - for ( i = 0; i < dimension; i++ ) { - newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); - } - return delta; -} - -//=============================================================== -// -// idODE_RK4Adaptive -// -//=============================================================== - -/* -============= -idODE_RK4Adaptive::idODE_RK4Adaptive -============= -*/ -idODE_RK4Adaptive::idODE_RK4Adaptive( const int dim, deriveFunction_t dr, const void *ud ) { - dimension = dim; - derive = dr; - userData = ud; - maxError = 0.01f; - tmpState = new float[dim]; - d1 = new float[dim]; - d1half = new float [dim]; - d2 = new float[dim]; - d3 = new float[dim]; - d4 = new float[dim]; -} - -/* -============= -idODE_RK4Adaptive::~idODE_RK4Adaptive -============= -*/ -idODE_RK4Adaptive::~idODE_RK4Adaptive( void ) { - delete tmpState; - delete d1; - delete d1half; - delete d2; - delete d3; - delete d4; -} - -/* -============= -idODE_RK4Adaptive::SetMaxError -============= -*/ -void idODE_RK4Adaptive::SetMaxError( const float err ) { - if ( err > 0.0f ) { - maxError = err; - } -} - -/* -============= -idODE_RK4Adaptive::Evaluate -============= -*/ -float idODE_RK4Adaptive::Evaluate( const float *state, float *newState, float t0, float t1 ) { - double delta, halfDelta, fourthDelta, sixthDelta; - double error, max; - int i, n; - - delta = t1 - t0; - - for ( n = 0; n < 4; n++ ) { - - halfDelta = delta * 0.5; - fourthDelta = delta * 0.25; - - // first step of first half delta - derive( t0, userData, state, d1 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + fourthDelta * d1[i]; - } - // second step of first half delta - derive( t0 + fourthDelta, userData, tmpState, d2 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + fourthDelta * d2[i]; - } - // third step of first half delta - derive( t0 + fourthDelta, userData, tmpState, d3 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d3[i]; - } - // fourth step of first half delta - derive( t0 + halfDelta, userData, tmpState, d4 ); - - sixthDelta = halfDelta * (1.0/6.0); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); - } - - // first step of second half delta - derive( t0 + halfDelta, userData, tmpState, d1half ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + fourthDelta * d1half[i]; - } - // second step of second half delta - derive( t0 + halfDelta + fourthDelta, userData, tmpState, d2 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + fourthDelta * d2[i]; - } - // third step of second half delta - derive( t0 + halfDelta + fourthDelta, userData, tmpState, d3 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d3[i]; - } - // fourth step of second half delta - derive( t0 + delta, userData, tmpState, d4 ); - - sixthDelta = halfDelta * (1.0/6.0); - for ( i = 0; i < dimension; i++ ) { - newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); - } - - // first step of full delta - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d1[i]; - } - // second step of full delta - derive( t0 + halfDelta, userData, tmpState, d2 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + halfDelta * d2[i]; - } - // third step of full delta - derive( t0 + halfDelta, userData, tmpState, d3 ); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + delta * d3[i]; - } - // fourth step of full delta - derive( t0 + delta, userData, tmpState, d4 ); - - sixthDelta = delta * (1.0/6.0); - for ( i = 0; i < dimension; i++ ) { - tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); - } - - // get max estimated error - max = 0.0; - for ( i = 0; i < dimension; i++ ) { - error = idMath::Fabs( (newState[i] - tmpState[i]) / (delta * d1[i] + 1e-10) ); - if ( error > max ) { - max = error; - } - } - error = max / maxError; - - if ( error <= 1.0f ) { - return delta * 4.0; - } - if ( delta <= 1e-7 ) { - return delta; - } - delta *= 0.25; - } - return delta; -} - diff --git a/idlib/math/ode.h b/idlib/math/ode.h deleted file mode 100644 index 74fc2ab04..000000000 --- a/idlib/math/ode.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_ODE_H__ -#define __MATH_ODE_H__ - -/* -=============================================================================== - - Numerical solvers for ordinary differential equations. - -=============================================================================== -*/ - - -//=============================================================== -// -// idODE -// -//=============================================================== - -typedef void (*deriveFunction_t)( const float t, const void *userData, const float *state, float *derivatives ); - -class idODE { - -public: - virtual ~idODE( void ) {} - - virtual float Evaluate( const float *state, float *newState, float t0, float t1 ) = 0; - -protected: - int dimension; // dimension in floats allocated for - deriveFunction_t derive; // derive function - const void * userData; // client data -}; - -//=============================================================== -// -// idODE_Euler -// -//=============================================================== - -class idODE_Euler : public idODE { - -public: - idODE_Euler( const int dim, const deriveFunction_t dr, const void *ud ); - virtual ~idODE_Euler( void ); - - virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); - -protected: - float * derivatives; // space to store derivatives -}; - -//=============================================================== -// -// idODE_Midpoint -// -//=============================================================== - -class idODE_Midpoint : public idODE { - -public: - idODE_Midpoint( const int dim, const deriveFunction_t dr, const void *ud ); - virtual ~idODE_Midpoint( void ); - - virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); - -protected: - float * tmpState; - float * derivatives; // space to store derivatives -}; - -//=============================================================== -// -// idODE_RK4 -// -//=============================================================== - -class idODE_RK4 : public idODE { - -public: - idODE_RK4( const int dim, const deriveFunction_t dr, const void *ud ); - virtual ~idODE_RK4( void ); - - virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); - -protected: - float * tmpState; - float * d1; // derivatives - float * d2; - float * d3; - float * d4; -}; - -//=============================================================== -// -// idODE_RK4Adaptive -// -//=============================================================== - -class idODE_RK4Adaptive : public idODE { - -public: - idODE_RK4Adaptive( const int dim, const deriveFunction_t dr, const void *ud ); - virtual ~idODE_RK4Adaptive( void ); - - virtual float Evaluate( const float *state, float *newState, float t0, float t1 ); - void SetMaxError( const float err ); - -protected: - float maxError; // maximum allowed error - float * tmpState; - float * d1; // derivatives - float * d1half; - float * d2; - float * d3; - float * d4; -}; - -#endif /* !__MATH_ODE_H__ */ diff --git a/idlib/math/plane.cpp b/idlib/math/plane.cpp deleted file mode 100644 index 3052828f4..000000000 --- a/idlib/math/plane.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idPlane plane_origin( 0.0f, 0.0f, 0.0f, 0.0f ); - -/* -================ -idPlane::Type -================ -*/ -int idPlane::Type( void ) const { - if ( Normal()[0] == 0.0f ) { - if ( Normal()[1] == 0.0f ) { - return Normal()[2] > 0.0f ? PLANETYPE_Z : PLANETYPE_NEGZ; - } - else if ( Normal()[2] == 0.0f ) { - return Normal()[1] > 0.0f ? PLANETYPE_Y : PLANETYPE_NEGY; - } - else { - return PLANETYPE_ZEROX; - } - } - else if ( Normal()[1] == 0.0f ) { - if ( Normal()[2] == 0.0f ) { - return Normal()[0] > 0.0f ? PLANETYPE_X : PLANETYPE_NEGX; - } - else { - return PLANETYPE_ZEROY; - } - } - else if ( Normal()[2] == 0.0f ) { - return PLANETYPE_ZEROZ; - } - else { - return PLANETYPE_NONAXIAL; - } -} - -/* -================ -idPlane::HeightFit -================ -*/ -bool idPlane::HeightFit( const idVec3 *points, const int numPoints ) { - int i; - float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f; - float sumYY = 0.0f, sumYZ = 0.0f; - idVec3 sum, average, dir; - - if ( numPoints == 1 ) { - a = 0.0f; - b = 0.0f; - c = 1.0f; - d = -points[0].z; - return true; - } - if ( numPoints == 2 ) { - dir = points[1] - points[0]; - Normal() = dir.Cross( idVec3( 0, 0, 1 ) ).Cross( dir ); - Normalize(); - d = -( Normal() * points[0] ); - return true; - } - - sum.Zero(); - for ( i = 0; i < numPoints; i++) { - sum += points[i]; - } - average = sum / numPoints; - - for ( i = 0; i < numPoints; i++ ) { - dir = points[i] - average; - sumXX += dir.x * dir.x; - sumXY += dir.x * dir.y; - sumXZ += dir.x * dir.z; - sumYY += dir.y * dir.y; - sumYZ += dir.y * dir.z; - } - - idMat2 m( sumXX, sumXY, sumXY, sumYY ); - if ( !m.InverseSelf() ) { - return false; - } - - a = - sumXZ * m[0][0] - sumYZ * m[0][1]; - b = - sumXZ * m[1][0] - sumYZ * m[1][1]; - c = 1.0f; - Normalize(); - d = -( a * average.x + b * average.y + c * average.z ); - return true; -} - -/* -================ -idPlane::PlaneIntersection -================ -*/ -bool idPlane::PlaneIntersection( const idPlane &plane, idVec3 &start, idVec3 &dir ) const { - double n00, n01, n11, det, invDet, f0, f1; - - n00 = Normal().LengthSqr(); - n01 = Normal() * plane.Normal(); - n11 = plane.Normal().LengthSqr(); - det = n00 * n11 - n01 * n01; - - if ( idMath::Fabs(det) < 1e-6f ) { - return false; - } - - invDet = 1.0f / det; - f0 = ( n01 * plane.d - n11 * d ) * invDet; - f1 = ( n01 * d - n00 * plane.d ) * invDet; - - dir = Normal().Cross( plane.Normal() ); - start = f0 * Normal() + f1 * plane.Normal(); - return true; -} - -/* -============= -idPlane::ToString -============= -*/ -const char *idPlane::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/plane.h b/idlib/math/plane.h deleted file mode 100644 index 15de4cd78..000000000 --- a/idlib/math/plane.h +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_PLANE_H__ -#define __MATH_PLANE_H__ - -/* -=============================================================================== - - 3D plane with equation: a * x + b * y + c * z + d = 0 - -=============================================================================== -*/ - - -class idVec3; -class idMat3; - -#define ON_EPSILON 0.1f -#define DEGENERATE_DIST_EPSILON 1e-4f - -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS 3 - -// plane sides -#define PLANESIDE_FRONT 0 -#define PLANESIDE_BACK 1 -#define PLANESIDE_ON 2 -#define PLANESIDE_CROSS 3 - -// plane types -#define PLANETYPE_X 0 -#define PLANETYPE_Y 1 -#define PLANETYPE_Z 2 -#define PLANETYPE_NEGX 3 -#define PLANETYPE_NEGY 4 -#define PLANETYPE_NEGZ 5 -#define PLANETYPE_TRUEAXIAL 6 // all types < 6 are true axial planes -#define PLANETYPE_ZEROX 6 -#define PLANETYPE_ZEROY 7 -#define PLANETYPE_ZEROZ 8 -#define PLANETYPE_NONAXIAL 9 - -class idPlane { -public: - idPlane( void ); - idPlane( float a, float b, float c, float d ); - idPlane( const idVec3 &normal, const float dist ); - - float operator[]( int index ) const; - float & operator[]( int index ); - idPlane operator-() const; // flips plane - idPlane & operator=( const idVec3 &v ); // sets normal and sets idPlane::d to zero - idPlane operator+( const idPlane &p ) const; // add plane equations - idPlane operator-( const idPlane &p ) const; // subtract plane equations - idPlane & operator*=( const idMat3 &m ); // Normal() *= m - - bool Compare( const idPlane &p ) const; // exact compare, no epsilon - bool Compare( const idPlane &p, const float epsilon ) const; // compare with epsilon - bool Compare( const idPlane &p, const float normalEps, const float distEps ) const; // compare with epsilon - bool operator==( const idPlane &p ) const; // exact compare, no epsilon - bool operator!=( const idPlane &p ) const; // exact compare, no epsilon - - void Zero( void ); // zero plane - void SetNormal( const idVec3 &normal ); // sets the normal - const idVec3 & Normal( void ) const; // reference to const normal - idVec3 & Normal( void ); // reference to normal - float Normalize( bool fixDegenerate = true ); // only normalizes the plane normal, does not adjust d - bool FixDegenerateNormal( void ); // fix degenerate normal - bool FixDegeneracies( float distEpsilon ); // fix degenerate normal and dist - float Dist( void ) const; // returns: -d - void SetDist( const float dist ); // sets: d = -dist - int Type( void ) const; // returns plane type - - bool FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate = true ); - bool FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate = true ); - void FitThroughPoint( const idVec3 &p ); // assumes normal is valid - bool HeightFit( const idVec3 *points, const int numPoints ); - idPlane Translate( const idVec3 &translation ) const; - idPlane & TranslateSelf( const idVec3 &translation ); - idPlane Rotate( const idVec3 &origin, const idMat3 &axis ) const; - idPlane & RotateSelf( const idVec3 &origin, const idMat3 &axis ); - - float Distance( const idVec3 &v ) const; - int Side( const idVec3 &v, const float epsilon = 0.0f ) const; - - bool LineIntersection( const idVec3 &start, const idVec3 &end, float *Fraction = NULL ) const; - // intersection point is start + dir * scale - bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const; - bool PlaneIntersection( const idPlane &plane, idVec3 &start, idVec3 &dir ) const; - - int GetDimension( void ) const; - - const idVec4 & ToVec4( void ) const; - idVec4 & ToVec4( void ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - void GetPlaneParams(float &a, float &b, float &c, float &d) const; -private: - float a; - float b; - float c; - float d; -}; - -extern idPlane plane_origin; -#define plane_zero plane_origin - -ID_INLINE idPlane::idPlane( void ) { -} - -ID_INLINE idPlane::idPlane( float a, float b, float c, float d ) { - this->a = a; - this->b = b; - this->c = c; - this->d = d; -} - -ID_INLINE idPlane::idPlane( const idVec3 &normal, const float dist ) { - this->a = normal.x; - this->b = normal.y; - this->c = normal.z; - this->d = -dist; -} - -ID_INLINE void idPlane::GetPlaneParams(float &fa, float &fb, float &fc, float &fd) const -{ - fa = a; - fb = b; - fc = c; - fd = d; -} - - -ID_INLINE float idPlane::operator[]( int index ) const { - return ( &a )[ index ]; -} - -ID_INLINE float& idPlane::operator[]( int index ) { - return ( &a )[ index ]; -} - -ID_INLINE idPlane idPlane::operator-() const { - return idPlane( -a, -b, -c, -d ); -} - -ID_INLINE idPlane &idPlane::operator=( const idVec3 &v ) { - a = v.x; - b = v.y; - c = v.z; - d = 0; - return *this; -} - -ID_INLINE idPlane idPlane::operator+( const idPlane &p ) const { - return idPlane( a + p.a, b + p.b, c + p.c, d + p.d ); -} - -ID_INLINE idPlane idPlane::operator-( const idPlane &p ) const { - return idPlane( a - p.a, b - p.b, c - p.c, d - p.d ); -} - -ID_INLINE idPlane &idPlane::operator*=( const idMat3 &m ) { - Normal() *= m; - return *this; -} - -ID_INLINE bool idPlane::Compare( const idPlane &p ) const { - return ( a == p.a && b == p.b && c == p.c && d == p.d ); -} - -ID_INLINE bool idPlane::Compare( const idPlane &p, const float epsilon ) const { - if ( idMath::Fabs( a - p.a ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( b - p.b ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( c - p.c ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( d - p.d ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idPlane::Compare( const idPlane &p, const float normalEps, const float distEps ) const { - if ( idMath::Fabs( d - p.d ) > distEps ) { - return false; - } - if ( !Normal().Compare( p.Normal(), normalEps ) ) { - return false; - } - return true; -} - -ID_INLINE bool idPlane::operator==( const idPlane &p ) const { - return Compare( p ); -} - -ID_INLINE bool idPlane::operator!=( const idPlane &p ) const { - return !Compare( p ); -} - -ID_INLINE void idPlane::Zero( void ) { - a = b = c = d = 0.0f; -} - -ID_INLINE void idPlane::SetNormal( const idVec3 &normal ) { - a = normal.x; - b = normal.y; - c = normal.z; -} - -ID_INLINE const idVec3 &idPlane::Normal( void ) const { - return *reinterpret_cast(&a); -} - -ID_INLINE idVec3 &idPlane::Normal( void ) { - return *reinterpret_cast(&a); -} - -ID_INLINE float idPlane::Normalize( bool fixDegenerate ) { - float length = reinterpret_cast(&a)->Normalize(); - - if ( fixDegenerate ) { - FixDegenerateNormal(); - } - return length; -} - -ID_INLINE bool idPlane::FixDegenerateNormal( void ) { - return Normal().FixDegenerateNormal(); -} - -ID_INLINE bool idPlane::FixDegeneracies( float distEpsilon ) { - bool fixedNormal = FixDegenerateNormal(); - // only fix dist if the normal was degenerate - if ( fixedNormal ) { - if ( idMath::Fabs( d - idMath::Rint( d ) ) < distEpsilon ) { - d = idMath::Rint( d ); - } - } - return fixedNormal; -} - -ID_INLINE float idPlane::Dist( void ) const { - return -d; -} - -ID_INLINE void idPlane::SetDist( const float dist ) { - d = -dist; -} - -ID_INLINE bool idPlane::FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate ) { - Normal() = (p1 - p2).Cross( p3 - p2 ); - if ( Normalize( fixDegenerate ) == 0.0f ) { - return false; - } - d = -( Normal() * p2 ); - return true; -} - -ID_INLINE bool idPlane::FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate ) { - Normal() = dir1.Cross( dir2 ); - if ( Normalize( fixDegenerate ) == 0.0f ) { - return false; - } - d = -( Normal() * p ); - return true; -} - -ID_INLINE void idPlane::FitThroughPoint( const idVec3 &p ) { - d = -( Normal() * p ); -} - -ID_INLINE idPlane idPlane::Translate( const idVec3 &translation ) const { - return idPlane( a, b, c, d - translation * Normal() ); -} - -ID_INLINE idPlane &idPlane::TranslateSelf( const idVec3 &translation ) { - d -= translation * Normal(); - return *this; -} - -ID_INLINE idPlane idPlane::Rotate( const idVec3 &origin, const idMat3 &axis ) const { - idPlane p; - p.Normal() = Normal() * axis; - p.d = d + origin * Normal() - origin * p.Normal(); - return p; -} - -ID_INLINE idPlane &idPlane::RotateSelf( const idVec3 &origin, const idMat3 &axis ) { - d += origin * Normal(); - Normal() *= axis; - d -= origin * Normal(); - return *this; -} - -ID_INLINE float idPlane::Distance( const idVec3 &v ) const { - return a * v.x + b * v.y + c * v.z + d; -} - -ID_INLINE int idPlane::Side( const idVec3 &v, const float epsilon ) const { - float dist = Distance( v ); - if ( dist > epsilon ) { - return PLANESIDE_FRONT; - } - else if ( dist < -epsilon ) { - return PLANESIDE_BACK; - } - else { - return PLANESIDE_ON; - } -} - -ID_INLINE bool idPlane::LineIntersection( const idVec3 &start, const idVec3 &end, float *fract ) const{ - float d1, d2, fraction; - - // This code is a copy of the lineintersection code from Id. Because of a bug - // Because of a bug in the calcualtion it doesn't always correctly report the intersection. Until - // it is confirmed that it can be fixed in the plane.h file, without braking any existing code that - // might rely on the current behaviour I keep this code here as a copy. - // Update: According to a mail from Brian (id) he says that the code is correct and is based on - // a slightly different assumption. I don't think so, because the exact same code doesn't work in - // some cases while my fix does, so I keep my version instead. - // d1 = Normal() * start + d; - d1 = -(Normal() * start + d); - d2 = Normal() * end + d; - if ( d1 == d2 ) { - return false; - } - if ( d1 > 0.0f && d2 > 0.0f ) { - return false; - } - if ( d1 < 0.0f && d2 < 0.0f ) { - return false; - } - fraction = ( d1 / ( d1 - d2 ) ); - if(fract != NULL) - *fract = fraction; - - return ( fraction >= 0.0f && fraction <= 1.0f ); -} - -ID_INLINE bool idPlane::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const { - float d1, d2; - - d1 = Normal() * start + d; - d2 = Normal() * dir; - if ( d2 == 0.0f ) { - return false; - } - scale = -( d1 / d2 ); - return true; -} - -ID_INLINE int idPlane::GetDimension( void ) const { - return 4; -} - -ID_INLINE const idVec4 &idPlane::ToVec4( void ) const { - return *reinterpret_cast(&a); -} - -ID_INLINE idVec4 &idPlane::ToVec4( void ) { - return *reinterpret_cast(&a); -} - -ID_INLINE const float *idPlane::ToFloatPtr( void ) const { - return reinterpret_cast(&a); -} - -ID_INLINE float *idPlane::ToFloatPtr( void ) { - return reinterpret_cast(&a); -} - -#endif /* !__MATH_PLANE_H__ */ diff --git a/idlib/math/pluecker.cpp b/idlib/math/pluecker.cpp deleted file mode 100644 index 9cddc47ad..000000000 --- a/idlib/math/pluecker.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idPluecker pluecker_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); - -/* -================ -idPluecker::FromPlanes - - pluecker coordinate for the intersection of two planes -================ -*/ -bool idPluecker::FromPlanes( const idPlane &p1, const idPlane &p2 ) { - - p[0] = -( p1[2] * -p2[3] - p2[2] * -p1[3] ); - p[1] = -( p2[1] * -p1[3] - p1[1] * -p2[3] ); - p[2] = p1[1] * p2[2] - p2[1] * p1[2]; - - p[3] = -( p1[0] * -p2[3] - p2[0] * -p1[3] ); - p[4] = p1[0] * p2[1] - p2[0] * p1[1]; - p[5] = p1[0] * p2[2] - p2[0] * p1[2]; - - return ( p[2] != 0.0f || p[5] != 0.0f || p[4] != 0.0f ); -} - -/* -================ -idPluecker::Distance3DSqr - - calculates square of shortest distance between the two - 3D lines represented by their pluecker coordinates -================ -*/ -float idPluecker::Distance3DSqr( const idPluecker &a ) const { - float d, s; - idVec3 dir; - - dir[0] = -a.p[5] * p[4] - a.p[4] * -p[5]; - dir[1] = a.p[4] * p[2] - a.p[2] * p[4]; - dir[2] = a.p[2] * -p[5] - -a.p[5] * p[2]; - if ( dir[0] == 0.0f && dir[1] == 0.0f && dir[2] == 0.0f ) { - return -1.0f; // FIXME: implement for parallel lines - } - d = a.p[4] * ( p[2]*dir[1] - -p[5]*dir[0]) + - a.p[5] * ( p[2]*dir[2] - p[4]*dir[0]) + - a.p[2] * (-p[5]*dir[2] - p[4]*dir[1]); - s = PermutedInnerProduct( a ) / d; - return ( dir * dir ) * ( s * s ); -} - -/* -============= -idPluecker::ToString -============= -*/ -const char *idPluecker::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/pluecker.h b/idlib/math/pluecker.h deleted file mode 100644 index 0c66f2f58..000000000 --- a/idlib/math/pluecker.h +++ /dev/null @@ -1,352 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_PLUECKER_H__ -#define __MATH_PLUECKER_H__ - -/* -=============================================================================== - - Pluecker coordinate - -=============================================================================== -*/ - -class idPluecker { -public: - idPluecker( void ); - explicit idPluecker( const float *a ); - explicit idPluecker( const idVec3 &start, const idVec3 &end ); - explicit idPluecker( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idPluecker operator-() const; // flips the direction - idPluecker operator*( const float a ) const; - idPluecker operator/( const float a ) const; - float operator*( const idPluecker &a ) const; // permuted inner product - idPluecker operator-( const idPluecker &a ) const; - idPluecker operator+( const idPluecker &a ) const; - idPluecker & operator*=( const float a ); - idPluecker & operator/=( const float a ); - idPluecker & operator+=( const idPluecker &a ); - idPluecker & operator-=( const idPluecker &a ); - - bool Compare( const idPluecker &a ) const; // exact compare, no epsilon - bool Compare( const idPluecker &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idPluecker &a ) const; // exact compare, no epsilon - bool operator!=( const idPluecker &a ) const; // exact compare, no epsilon - - void Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); - void Zero( void ); - - void FromLine( const idVec3 &start, const idVec3 &end ); // pluecker from line - void FromRay( const idVec3 &start, const idVec3 &dir ); // pluecker from ray - bool FromPlanes( const idPlane &p1, const idPlane &p2 ); // pluecker from intersection of planes - bool ToLine( idVec3 &start, idVec3 &end ) const; // pluecker to line - bool ToRay( idVec3 &start, idVec3 &dir ) const; // pluecker to ray - void ToDir( idVec3 &dir ) const; // pluecker to direction - float PermutedInnerProduct( const idPluecker &a ) const; // pluecker permuted inner product - float Distance3DSqr( const idPluecker &a ) const; // pluecker line distance - - float Length( void ) const; // pluecker length - float LengthSqr( void ) const; // pluecker squared length - idPluecker Normalize( void ) const; // pluecker normalize - float NormalizeSelf( void ); // pluecker normalize - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - float p[6]; -}; - -extern idPluecker pluecker_origin; -#define pluecker_zero pluecker_origin - -ID_INLINE idPluecker::idPluecker( void ) { -} - -ID_INLINE idPluecker::idPluecker( const float *a ) { - memcpy( p, a, 6 * sizeof( float ) ); -} - -ID_INLINE idPluecker::idPluecker( const idVec3 &start, const idVec3 &end ) { - FromLine( start, end ); -} - -ID_INLINE idPluecker::idPluecker( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { - p[0] = a1; - p[1] = a2; - p[2] = a3; - p[3] = a4; - p[4] = a5; - p[5] = a6; -} - -ID_INLINE idPluecker idPluecker::operator-() const { - return idPluecker( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] ); -} - -ID_INLINE float idPluecker::operator[]( const int index ) const { - return p[index]; -} - -ID_INLINE float &idPluecker::operator[]( const int index ) { - return p[index]; -} - -ID_INLINE idPluecker idPluecker::operator*( const float a ) const { - return idPluecker( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a ); -} - -ID_INLINE float idPluecker::operator*( const idPluecker &a ) const { - return p[0] * a.p[4] + p[1] * a.p[5] + p[2] * a.p[3] + p[4] * a.p[0] + p[5] * a.p[1] + p[3] * a.p[2]; -} - -ID_INLINE idPluecker idPluecker::operator/( const float a ) const { - float inva; - - assert( a != 0.0f ); - inva = 1.0f / a; - return idPluecker( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva ); -} - -ID_INLINE idPluecker idPluecker::operator+( const idPluecker &a ) const { - return idPluecker( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] ); -} - -ID_INLINE idPluecker idPluecker::operator-( const idPluecker &a ) const { - return idPluecker( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] ); -} - -ID_INLINE idPluecker &idPluecker::operator*=( const float a ) { - p[0] *= a; - p[1] *= a; - p[2] *= a; - p[3] *= a; - p[4] *= a; - p[5] *= a; - return *this; -} - -ID_INLINE idPluecker &idPluecker::operator/=( const float a ) { - float inva; - - assert( a != 0.0f ); - inva = 1.0f / a; - p[0] *= inva; - p[1] *= inva; - p[2] *= inva; - p[3] *= inva; - p[4] *= inva; - p[5] *= inva; - return *this; -} - -ID_INLINE idPluecker &idPluecker::operator+=( const idPluecker &a ) { - p[0] += a[0]; - p[1] += a[1]; - p[2] += a[2]; - p[3] += a[3]; - p[4] += a[4]; - p[5] += a[5]; - return *this; -} - -ID_INLINE idPluecker &idPluecker::operator-=( const idPluecker &a ) { - p[0] -= a[0]; - p[1] -= a[1]; - p[2] -= a[2]; - p[3] -= a[3]; - p[4] -= a[4]; - p[5] -= a[5]; - return *this; -} - -ID_INLINE bool idPluecker::Compare( const idPluecker &a ) const { - return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) && - ( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) ); -} - -ID_INLINE bool idPluecker::Compare( const idPluecker &a, const float epsilon ) const { - if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idPluecker::operator==( const idPluecker &a ) const { - return Compare( a ); -} - -ID_INLINE bool idPluecker::operator!=( const idPluecker &a ) const { - return !Compare( a ); -} - -ID_INLINE void idPluecker::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { - p[0] = a1; - p[1] = a2; - p[2] = a3; - p[3] = a4; - p[4] = a5; - p[5] = a6; -} - -ID_INLINE void idPluecker::Zero( void ) { - p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f; -} - -ID_INLINE void idPluecker::FromLine( const idVec3 &start, const idVec3 &end ) { - p[0] = start[0] * end[1] - end[0] * start[1]; - p[1] = start[0] * end[2] - end[0] * start[2]; - p[2] = start[0] - end[0]; - p[3] = start[1] * end[2] - end[1] * start[2]; - p[4] = start[2] - end[2]; - p[5] = end[1] - start[1]; -} - -ID_INLINE void idPluecker::FromRay( const idVec3 &start, const idVec3 &dir ) { - p[0] = start[0] * dir[1] - dir[0] * start[1]; - p[1] = start[0] * dir[2] - dir[0] * start[2]; - p[2] = -dir[0]; - p[3] = start[1] * dir[2] - dir[1] * start[2]; - p[4] = -dir[2]; - p[5] = dir[1]; -} - -ID_INLINE bool idPluecker::ToLine( idVec3 &start, idVec3 &end ) const { - idVec3 dir1, dir2; - float d; - - dir1[0] = p[3]; - dir1[1] = -p[1]; - dir1[2] = p[0]; - - dir2[0] = -p[2]; - dir2[1] = p[5]; - dir2[2] = -p[4]; - - d = dir2 * dir2; - if ( d == 0.0f ) { - return false; // pluecker coordinate does not represent a line - } - - start = dir2.Cross(dir1) * (1.0f / d); - end = start + dir2; - return true; -} - -ID_INLINE bool idPluecker::ToRay( idVec3 &start, idVec3 &dir ) const { - idVec3 dir1; - float d; - - dir1[0] = p[3]; - dir1[1] = -p[1]; - dir1[2] = p[0]; - - dir[0] = -p[2]; - dir[1] = p[5]; - dir[2] = -p[4]; - - d = dir * dir; - if ( d == 0.0f ) { - return false; // pluecker coordinate does not represent a line - } - - start = dir.Cross(dir1) * (1.0f / d); - return true; -} - -ID_INLINE void idPluecker::ToDir( idVec3 &dir ) const { - dir[0] = -p[2]; - dir[1] = p[5]; - dir[2] = -p[4]; -} - -ID_INLINE float idPluecker::PermutedInnerProduct( const idPluecker &a ) const { - return p[0] * a.p[4] + p[1] * a.p[5] + p[2] * a.p[3] + p[4] * a.p[0] + p[5] * a.p[1] + p[3] * a.p[2]; -} - -ID_INLINE float idPluecker::Length( void ) const { - return ( float )idMath::Sqrt( p[5] * p[5] + p[4] * p[4] + p[2] * p[2] ); -} - -ID_INLINE float idPluecker::LengthSqr( void ) const { - return ( p[5] * p[5] + p[4] * p[4] + p[2] * p[2] ); -} - -ID_INLINE float idPluecker::NormalizeSelf( void ) { - float l, d; - - l = LengthSqr(); - if ( l == 0.0f ) { - return l; // pluecker coordinate does not represent a line - } - d = idMath::InvSqrt( l ); - p[0] *= d; - p[1] *= d; - p[2] *= d; - p[3] *= d; - p[4] *= d; - p[5] *= d; - return d * l; -} - -ID_INLINE idPluecker idPluecker::Normalize( void ) const { - float d; - - d = LengthSqr(); - if ( d == 0.0f ) { - return *this; // pluecker coordinate does not represent a line - } - d = idMath::InvSqrt( d ); - return idPluecker( p[0]*d, p[1]*d, p[2]*d, p[3]*d, p[4]*d, p[5]*d ); -} - -ID_INLINE int idPluecker::GetDimension( void ) const { - return 6; -} - -ID_INLINE const float *idPluecker::ToFloatPtr( void ) const { - return p; -} - -ID_INLINE float *idPluecker::ToFloatPtr( void ) { - return p; -} - -#endif /* !__MATH_PLUECKER_H__ */ diff --git a/idlib/math/polynomial.cpp b/idlib/math/polynomial.cpp deleted file mode 100644 index cd016a799..000000000 --- a/idlib/math/polynomial.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -const float EPSILON = 1e-6f; - -/* -============= -idPolynomial::Laguer -============= -*/ -int idPolynomial::Laguer( const idComplex *coef, const int degree, idComplex &x ) const { - const int MT = 10, MAX_ITERATIONS = MT * 8; - static const float frac[] = { 0.0f, 0.5f, 0.25f, 0.75f, 0.13f, 0.38f, 0.62f, 0.88f, 1.0f }; - int i, j; - float abx, abp, abm, err; - idComplex dx, cx, b, d, f, g, s, gps, gms, g2; - - for ( i = 1; i <= MAX_ITERATIONS; i++ ) { - b = coef[degree]; - err = b.Abs(); - d.Zero(); - f.Zero(); - abx = x.Abs(); - for ( j = degree - 1; j >= 0; j-- ) { - f = x * f + d; - d = x * d + b; - b = x * b + coef[j]; - err = b.Abs() + abx * err; - } - if ( b.Abs() < err * EPSILON ) { - return i; - } - g = d / b; - g2 = g * g; - s = ( ( degree - 1 ) * ( degree * ( g2 - 2.0f * f / b ) - g2 ) ).Sqrt(); - gps = g + s; - gms = g - s; - abp = gps.Abs(); - abm = gms.Abs(); - if ( abp < abm ) { - gps = gms; - } - if ( Max( abp, abm ) > 0.0f ) { - dx = degree / gps; - } else { - dx = idMath::Exp( idMath::Log( 1.0f + abx ) ) * idComplex( idMath::Cos( i ), idMath::Sin( i ) ); - } - cx = x - dx; - if ( x == cx ) { - return i; - } - if ( i % MT == 0 ) { - x = cx; - } else { - x -= frac[i/MT] * dx; - } - } - return i; -} - -/* -============= -idPolynomial::GetRoots -============= -*/ -int idPolynomial::GetRoots( idComplex *roots ) const { - int i, j; - idComplex x, b, c, *coef; - - coef = (idComplex *) _alloca16( ( degree + 1 ) * sizeof( idComplex ) ); - for ( i = 0; i <= degree; i++ ) { - coef[i].Set( coefficient[i], 0.0f ); - } - - for ( i = degree - 1; i >= 0; i-- ) { - x.Zero(); - Laguer( coef, i + 1, x ); - if ( idMath::Fabs( x.i ) < 2.0f * EPSILON * idMath::Fabs( x.r ) ) { - x.i = 0.0f; - } - roots[i] = x; - b = coef[i+1]; - for ( j = i; j >= 0; j-- ) { - c = coef[j]; - coef[j] = b; - b = x * b + c; - } - } - - for ( i = 0; i <= degree; i++ ) { - coef[i].Set( coefficient[i], 0.0f ); - } - for ( i = 0; i < degree; i++ ) { - Laguer( coef, degree, roots[i] ); - } - - for ( i = 1; i < degree; i++ ) { - x = roots[i]; - for ( j = i - 1; j >= 0; j-- ) { - if ( roots[j].r <= x.r ) { - break; - } - roots[j+1] = roots[j]; - } - roots[j+1] = x; - } - - return degree; -} - -/* -============= -idPolynomial::GetRoots -============= -*/ -int idPolynomial::GetRoots( float *roots ) const { - int i, num; - idComplex *complexRoots; - - switch( degree ) { - case 0: return 0; - case 1: return GetRoots1( coefficient[1], coefficient[0], roots ); - case 2: return GetRoots2( coefficient[2], coefficient[1], coefficient[0], roots ); - case 3: return GetRoots3( coefficient[3], coefficient[2], coefficient[1], coefficient[0], roots ); - case 4: return GetRoots4( coefficient[4], coefficient[3], coefficient[2], coefficient[1], coefficient[0], roots ); - } - - // The Abel-Ruffini theorem states that there is no general solution - // in radicals to polynomial equations of degree five or higher. - // A polynomial equation can be solved by radicals if and only if - // its Galois group is a solvable group. - - complexRoots = (idComplex *) _alloca16( degree * sizeof( idComplex ) ); - - GetRoots( complexRoots ); - - for ( num = i = 0; i < degree; i++ ) { - if ( complexRoots[i].i == 0.0f ) { - roots[i] = complexRoots[i].r; - num++; - } - } - return num; -} - -/* -============= -idPolynomial::ToString -============= -*/ -const char *idPolynomial::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============= -idPolynomial::Test -============= -*/ -void idPolynomial::Test( void ) { - int i, num; - float roots[4], value; - idComplex complexRoots[4], complexValue; - idPolynomial p; - - p = idPolynomial( -5.0f, 4.0f ); - num = p.GetRoots( roots ); - for ( i = 0; i < num; i++ ) { - value = p.GetValue( roots[i] ); - assert( idMath::Fabs( value ) < 1e-4f ); - } - - p = idPolynomial( -5.0f, 4.0f, 3.0f ); - num = p.GetRoots( roots ); - for ( i = 0; i < num; i++ ) { - value = p.GetValue( roots[i] ); - assert( idMath::Fabs( value ) < 1e-4f ); - } - - p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); - num = p.GetRoots( roots ); - for ( i = 0; i < num; i++ ) { - value = p.GetValue( roots[i] ); - assert( idMath::Fabs( value ) < 1e-4f ); - } - - p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); - num = p.GetRoots( roots ); - for ( i = 0; i < num; i++ ) { - value = p.GetValue( roots[i] ); - assert( idMath::Fabs( value ) < 1e-4f ); - } - - p = idPolynomial( -5.0f, 4.0f, 3.0f, 2.0f, 1.0f ); - num = p.GetRoots( roots ); - for ( i = 0; i < num; i++ ) { - value = p.GetValue( roots[i] ); - assert( idMath::Fabs( value ) < 1e-4f ); - } - - p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); - num = p.GetRoots( complexRoots ); - for ( i = 0; i < num; i++ ) { - complexValue = p.GetValue( complexRoots[i] ); - assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); - } - - p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); - num = p.GetRoots( complexRoots ); - for ( i = 0; i < num; i++ ) { - complexValue = p.GetValue( complexRoots[i] ); - assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); - } -} diff --git a/idlib/math/polynomial.h b/idlib/math/polynomial.h deleted file mode 100644 index d902f343b..000000000 --- a/idlib/math/polynomial.h +++ /dev/null @@ -1,613 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_POLYNOMIAL_H__ -#define __MATH_POLYNOMIAL_H__ - -/* -=============================================================================== - - Polynomial of arbitrary degree with real coefficients. - -=============================================================================== -*/ - - -class idPolynomial { -public: - idPolynomial( void ); - explicit idPolynomial( int d ); - explicit idPolynomial( float a, float b ); - explicit idPolynomial( float a, float b, float c ); - explicit idPolynomial( float a, float b, float c, float d ); - explicit idPolynomial( float a, float b, float c, float d, float e ); - - float operator[]( int index ) const; - float & operator[]( int index ); - - idPolynomial operator-() const; - idPolynomial & operator=( const idPolynomial &p ); - - idPolynomial operator+( const idPolynomial &p ) const; - idPolynomial operator-( const idPolynomial &p ) const; - idPolynomial operator*( const float s ) const; - idPolynomial operator/( const float s ) const; - - idPolynomial & operator+=( const idPolynomial &p ); - idPolynomial & operator-=( const idPolynomial &p ); - idPolynomial & operator*=( const float s ); - idPolynomial & operator/=( const float s ); - - bool Compare( const idPolynomial &p ) const; // exact compare, no epsilon - bool Compare( const idPolynomial &p, const float epsilon ) const;// compare with epsilon - bool operator==( const idPolynomial &p ) const; // exact compare, no epsilon - bool operator!=( const idPolynomial &p ) const; // exact compare, no epsilon - - void Zero( void ); - void Zero( int d ); - - int GetDimension( void ) const; // get the degree of the polynomial - int GetDegree( void ) const; // get the degree of the polynomial - float GetValue( const float x ) const; // evaluate the polynomial with the given real value - idComplex GetValue( const idComplex &x ) const; // evaluate the polynomial with the given complex value - idPolynomial GetDerivative( void ) const; // get the first derivative of the polynomial - idPolynomial GetAntiDerivative( void ) const; // get the anti derivative of the polynomial - - int GetRoots( idComplex *roots ) const; // get all roots - int GetRoots( float *roots ) const; // get the real roots - - static int GetRoots1( float a, float b, float *roots ); - static int GetRoots2( float a, float b, float c, float *roots ); - static int GetRoots3( float a, float b, float c, float d, float *roots ); - static int GetRoots4( float a, float b, float c, float d, float e, float *roots ); - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - static void Test( void ); - -private: - int degree; - int allocated; - float * coefficient; - - void Resize( int d, bool keep ); - int Laguer( const idComplex *coef, const int degree, idComplex &r ) const; -}; - -ID_INLINE idPolynomial::idPolynomial( void ) { - degree = -1; - allocated = 0; - coefficient = NULL; -} - -ID_INLINE idPolynomial::idPolynomial( int d ) { - degree = -1; - allocated = 0; - coefficient = NULL; - Resize( d, false ); -} - -ID_INLINE idPolynomial::idPolynomial( float a, float b ) { - degree = -1; - allocated = 0; - coefficient = NULL; - Resize( 1, false ); - coefficient[0] = b; - coefficient[1] = a; -} - -ID_INLINE idPolynomial::idPolynomial( float a, float b, float c ) { - degree = -1; - allocated = 0; - coefficient = NULL; - Resize( 2, false ); - coefficient[0] = c; - coefficient[1] = b; - coefficient[2] = a; -} - -ID_INLINE idPolynomial::idPolynomial( float a, float b, float c, float d ) { - degree = -1; - allocated = 0; - coefficient = NULL; - Resize( 3, false ); - coefficient[0] = d; - coefficient[1] = c; - coefficient[2] = b; - coefficient[3] = a; -} - -ID_INLINE idPolynomial::idPolynomial( float a, float b, float c, float d, float e ) { - degree = -1; - allocated = 0; - coefficient = NULL; - Resize( 4, false ); - coefficient[0] = e; - coefficient[1] = d; - coefficient[2] = c; - coefficient[3] = b; - coefficient[4] = a; -} - -ID_INLINE float idPolynomial::operator[]( int index ) const { - assert( index >= 0 && index <= degree ); - return coefficient[ index ]; -} - -ID_INLINE float& idPolynomial::operator[]( int index ) { - assert( index >= 0 && index <= degree ); - return coefficient[ index ]; -} - -ID_INLINE idPolynomial idPolynomial::operator-() const { - int i; - idPolynomial n; - - n = *this; - for ( i = 0; i <= degree; i++ ) { - n[i] = -n[i]; - } - return n; -} - -ID_INLINE idPolynomial &idPolynomial::operator=( const idPolynomial &p ) { - Resize( p.degree, false ); - for ( int i = 0; i <= degree; i++ ) { - coefficient[i] = p.coefficient[i]; - } - return *this; -} - -ID_INLINE idPolynomial idPolynomial::operator+( const idPolynomial &p ) const { - int i; - idPolynomial n; - - if ( degree > p.degree ) { - n.Resize( degree, false ); - for ( i = 0; i <= p.degree; i++ ) { - n.coefficient[i] = coefficient[i] + p.coefficient[i]; - } - for ( ; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i]; - } - n.degree = degree; - } else if ( p.degree > degree ) { - n.Resize( p.degree, false ); - for ( i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] + p.coefficient[i]; - } - for ( ; i <= p.degree; i++ ) { - n.coefficient[i] = p.coefficient[i]; - } - n.degree = p.degree; - } else { - n.Resize( degree, false ); - n.degree = 0; - for ( i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] + p.coefficient[i]; - if ( n.coefficient[i] != 0.0f ) { - n.degree = i; - } - } - } - return n; -} - -ID_INLINE idPolynomial idPolynomial::operator-( const idPolynomial &p ) const { - int i; - idPolynomial n; - - if ( degree > p.degree ) { - n.Resize( degree, false ); - for ( i = 0; i <= p.degree; i++ ) { - n.coefficient[i] = coefficient[i] - p.coefficient[i]; - } - for ( ; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i]; - } - n.degree = degree; - } else if ( p.degree >= degree ) { - n.Resize( p.degree, false ); - for ( i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] - p.coefficient[i]; - } - for ( ; i <= p.degree; i++ ) { - n.coefficient[i] = - p.coefficient[i]; - } - n.degree = p.degree; - } else { - n.Resize( degree, false ); - n.degree = 0; - for ( i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] - p.coefficient[i]; - if ( n.coefficient[i] != 0.0f ) { - n.degree = i; - } - } - } - return n; -} - -ID_INLINE idPolynomial idPolynomial::operator*( const float s ) const { - idPolynomial n; - - if ( s == 0.0f ) { - n.degree = 0; - } else { - n.Resize( degree, false ); - for ( int i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] * s; - } - } - return n; -} - -ID_INLINE idPolynomial idPolynomial::operator/( const float s ) const { - float invs; - idPolynomial n; - - assert( s != 0.0f ); - n.Resize( degree, false ); - invs = 1.0f / s; - for ( int i = 0; i <= degree; i++ ) { - n.coefficient[i] = coefficient[i] * invs; - } - return n; -} - -ID_INLINE idPolynomial &idPolynomial::operator+=( const idPolynomial &p ) { - int i; - - if ( degree > p.degree ) { - for ( i = 0; i <= p.degree; i++ ) { - coefficient[i] += p.coefficient[i]; - } - } else if ( p.degree > degree ) { - Resize( p.degree, true ); - for ( i = 0; i <= degree; i++ ) { - coefficient[i] += p.coefficient[i]; - } - for ( ; i <= p.degree; i++ ) { - coefficient[i] = p.coefficient[i]; - } - } else { - for ( i = 0; i <= degree; i++ ) { - coefficient[i] += p.coefficient[i]; - if ( coefficient[i] != 0.0f ) { - degree = i; - } - } - } - return *this; -} - -ID_INLINE idPolynomial &idPolynomial::operator-=( const idPolynomial &p ) { - int i; - - if ( degree > p.degree ) { - for ( i = 0; i <= p.degree; i++ ) { - coefficient[i] -= p.coefficient[i]; - } - } else if ( p.degree > degree ) { - Resize( p.degree, true ); - for ( i = 0; i <= degree; i++ ) { - coefficient[i] -= p.coefficient[i]; - } - for ( ; i <= p.degree; i++ ) { - coefficient[i] = - p.coefficient[i]; - } - } else { - for ( i = 0; i <= degree; i++ ) { - coefficient[i] -= p.coefficient[i]; - if ( coefficient[i] != 0.0f ) { - degree = i; - } - } - } - return *this; -} - -ID_INLINE idPolynomial &idPolynomial::operator*=( const float s ) { - if ( s == 0.0f ) { - degree = 0; - } else { - for ( int i = 0; i <= degree; i++ ) { - coefficient[i] *= s; - } - } - return *this; -} - -ID_INLINE idPolynomial &idPolynomial::operator/=( const float s ) { - float invs; - - assert( s != 0.0f ); - invs = 1.0f / s; - for ( int i = 0; i <= degree; i++ ) { - coefficient[i] = invs; - } - return *this;; -} - -ID_INLINE bool idPolynomial::Compare( const idPolynomial &p ) const { - if ( degree != p.degree ) { - return false; - } - for ( int i = 0; i <= degree; i++ ) { - if ( coefficient[i] != p.coefficient[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idPolynomial::Compare( const idPolynomial &p, const float epsilon ) const { - if ( degree != p.degree ) { - return false; - } - for ( int i = 0; i <= degree; i++ ) { - if ( idMath::Fabs( coefficient[i] - p.coefficient[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idPolynomial::operator==( const idPolynomial &p ) const { - return Compare( p ); -} - -ID_INLINE bool idPolynomial::operator!=( const idPolynomial &p ) const { - return !Compare( p ); -} - -ID_INLINE void idPolynomial::Zero( void ) { - degree = 0; -} - -ID_INLINE void idPolynomial::Zero( int d ) { - Resize( d, false ); - for ( int i = 0; i <= degree; i++ ) { - coefficient[i] = 0.0f; - } -} - -ID_INLINE int idPolynomial::GetDimension( void ) const { - return degree; -} - -ID_INLINE int idPolynomial::GetDegree( void ) const { - return degree; -} - -ID_INLINE float idPolynomial::GetValue( const float x ) const { - float y, z; - y = coefficient[0]; - z = x; - for ( int i = 1; i <= degree; i++ ) { - y += coefficient[i] * z; - z *= x; - } - return y; -} - -ID_INLINE idComplex idPolynomial::GetValue( const idComplex &x ) const { - idComplex y, z; - y.Set( coefficient[0], 0.0f ); - z = x; - for ( int i = 1; i <= degree; i++ ) { - y += coefficient[i] * z; - z *= x; - } - return y; -} - -ID_INLINE idPolynomial idPolynomial::GetDerivative( void ) const { - idPolynomial n; - - if ( degree == 0 ) { - return n; - } - n.Resize( degree - 1, false ); - for ( int i = 1; i <= degree; i++ ) { - n.coefficient[i-1] = i * coefficient[i]; - } - return n; -} - -ID_INLINE idPolynomial idPolynomial::GetAntiDerivative( void ) const { - idPolynomial n; - - if ( degree == 0 ) { - return n; - } - n.Resize( degree + 1, false ); - n.coefficient[0] = 0.0f; - for ( int i = 0; i <= degree; i++ ) { - n.coefficient[i+1] = coefficient[i] / ( i + 1 ); - } - return n; -} - -ID_INLINE int idPolynomial::GetRoots1( float a, float b, float *roots ) { - assert( a != 0.0f ); - roots[0] = - b / a; - return 1; -} - -ID_INLINE int idPolynomial::GetRoots2( float a, float b, float c, float *roots ) { - float inva, ds; - - if ( a != 1.0f ) { - assert( a != 0.0f ); - inva = 1.0f / a; - c *= inva; - b *= inva; - } - ds = b * b - 4.0f * c; - if ( ds < 0.0f ) { - return 0; - } else if ( ds > 0.0f ) { - ds = idMath::Sqrt( ds ); - roots[0] = 0.5f * ( -b - ds ); - roots[1] = 0.5f * ( -b + ds ); - return 2; - } else { - roots[0] = 0.5f * -b; - return 1; - } -} - -ID_INLINE int idPolynomial::GetRoots3( float a, float b, float c, float d, float *roots ) { - float inva, f, g, halfg, ofs, ds, dist, angle, cs, ss, t; - - if ( a != 1.0f ) { - assert( a != 0.0f ); - inva = 1.0f / a; - d *= inva; - c *= inva; - b *= inva; - } - - f = ( 1.0f / 3.0f ) * ( 3.0f * c - b * b ); - g = ( 1.0f / 27.0f ) * ( 2.0f * b * b * b - 9.0f * c * b + 27.0f * d ); - halfg = 0.5f * g; - ofs = ( 1.0f / 3.0f ) * b; - ds = 0.25f * g * g + ( 1.0f / 27.0f ) * f * f * f; - - if ( ds < 0.0f ) { - dist = idMath::Sqrt( ( -1.0f / 3.0f ) * f ); - angle = ( 1.0f / 3.0f ) * idMath::ATan( idMath::Sqrt( -ds ), -halfg ); - cs = idMath::Cos( angle ); - ss = idMath::Sin( angle ); - roots[0] = 2.0f * dist * cs - ofs; - roots[1] = -dist * ( cs + idMath::SQRT_THREE * ss ) - ofs; - roots[2] = -dist * ( cs - idMath::SQRT_THREE * ss ) - ofs; - return 3; - } else if ( ds > 0.0f ) { - ds = idMath::Sqrt( ds ); - t = -halfg + ds; - if ( t >= 0.0f ) { - roots[0] = idMath::Pow( t, ( 1.0f / 3.0f ) ); - } else { - roots[0] = -idMath::Pow( -t, ( 1.0f / 3.0f ) ); - } - t = -halfg - ds; - if ( t >= 0.0f ) { - roots[0] += idMath::Pow( t, ( 1.0f / 3.0f ) ); - } else { - roots[0] -= idMath::Pow( -t, ( 1.0f / 3.0f ) ); - } - roots[0] -= ofs; - return 1; - } else { - if ( halfg >= 0.0f ) { - t = -idMath::Pow( halfg, ( 1.0f / 3.0f ) ); - } else { - t = idMath::Pow( -halfg, ( 1.0f / 3.0f ) ); - } - roots[0] = 2.0f * t - ofs; - roots[1] = -t - ofs; - roots[2] = roots[1]; - return 3; - } -} - -ID_INLINE int idPolynomial::GetRoots4( float a, float b, float c, float d, float e, float *roots ) { - int count; - float inva, y, ds, r, s1, s2, t1, t2, tp, tm; - float roots3[3]; - - if ( a != 1.0f ) { - assert( a != 0.0f ); - inva = 1.0f / a; - e *= inva; - d *= inva; - c *= inva; - b *= inva; - } - - count = 0; - - GetRoots3( 1.0f, -c, b * d - 4.0f * e, -b * b * e + 4.0f * c * e - d * d, roots3 ); - y = roots3[0]; - ds = 0.25f * b * b - c + y; - - if ( ds < 0.0f ) { - return 0; - } else if ( ds > 0.0f ) { - r = idMath::Sqrt( ds ); - t1 = 0.75f * b * b - r * r - 2.0f * c; - t2 = ( 4.0f * b * c - 8.0f * d - b * b * b ) / ( 4.0f * r ); - tp = t1 + t2; - tm = t1 - t2; - - if ( tp >= 0.0f ) { - s1 = idMath::Sqrt( tp ); - roots[count++] = -0.25f * b + 0.5f * ( r + s1 ); - roots[count++] = -0.25f * b + 0.5f * ( r - s1 ); - } - if ( tm >= 0.0f ) { - s2 = idMath::Sqrt( tm ); - roots[count++] = -0.25f * b + 0.5f * ( s2 - r ); - roots[count++] = -0.25f * b - 0.5f * ( s2 + r ); - } - return count; - } else { - t2 = y * y - 4.0f * e; - if ( t2 >= 0.0f ) { - t2 = 2.0f * idMath::Sqrt( t2 ); - t1 = 0.75f * b * b - 2.0f * c; - if ( t1 + t2 >= 0.0f ) { - s1 = idMath::Sqrt( t1 + t2 ); - roots[count++] = -0.25f * b + 0.5f * s1; - roots[count++] = -0.25f * b - 0.5f * s1; - } - if ( t1 - t2 >= 0.0f ) { - s2 = idMath::Sqrt( t1 - t2 ); - roots[count++] = -0.25f * b + 0.5f * s2; - roots[count++] = -0.25f * b - 0.5f * s2; - } - } - return count; - } -} - -ID_INLINE const float *idPolynomial::ToFloatPtr( void ) const { - return coefficient; -} - -ID_INLINE float *idPolynomial::ToFloatPtr( void ) { - return coefficient; -} - -ID_INLINE void idPolynomial::Resize( int d, bool keep ) { - int alloc = ( d + 1 + 3 ) & ~3; - if ( alloc > allocated ) { - float *ptr = (float *) Mem_Alloc16( alloc * sizeof( float ) ); - if ( coefficient != NULL ) { - if ( keep ) { - for ( int i = 0; i <= degree; i++ ) { - ptr[i] = coefficient[i]; - } - } - Mem_Free16( coefficient ); - } - allocated = alloc; - coefficient = ptr; - } - degree = d; -} - -#endif /* !__MATH_POLYNOMIAL_H__ */ diff --git a/idlib/math/quat.cpp b/idlib/math/quat.cpp deleted file mode 100644 index 8a4105e0b..000000000 --- a/idlib/math/quat.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -===================== -idQuat::ToAngles -===================== -*/ -idAngles idQuat::ToAngles( void ) const { - return ToMat3().ToAngles(); -} - -/* -===================== -idQuat::ToRotation -===================== -*/ -idRotation idQuat::ToRotation( void ) const { - idVec3 vec; - float angle; - - vec.x = x; - vec.y = y; - vec.z = z; - angle = idMath::ACos( w ); - if ( angle == 0.0f ) { - vec.Set( 0.0f, 0.0f, 1.0f ); - } else { - //vec *= (1.0f / sin( angle )); - vec.Normalize(); - vec.FixDegenerateNormal(); - angle *= 2.0f * idMath::M_RAD2DEG; - } - return idRotation( vec3_origin, vec, angle ); -} - -/* -===================== -idQuat::ToMat3 -===================== -*/ -idMat3 idQuat::ToMat3( void ) const { - idMat3 mat; - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - - x2 = x + x; - y2 = y + y; - z2 = z + z; - - xx = x * x2; - xy = x * y2; - xz = x * z2; - - yy = y * y2; - yz = y * z2; - zz = z * z2; - - wx = w * x2; - wy = w * y2; - wz = w * z2; - - mat[ 0 ][ 0 ] = 1.0f - ( yy + zz ); - mat[ 0 ][ 1 ] = xy - wz; - mat[ 0 ][ 2 ] = xz + wy; - - mat[ 1 ][ 0 ] = xy + wz; - mat[ 1 ][ 1 ] = 1.0f - ( xx + zz ); - mat[ 1 ][ 2 ] = yz - wx; - - mat[ 2 ][ 0 ] = xz - wy; - mat[ 2 ][ 1 ] = yz + wx; - mat[ 2 ][ 2 ] = 1.0f - ( xx + yy ); - - return mat; -} - -/* -===================== -idQuat::ToMat4 -===================== -*/ -idMat4 idQuat::ToMat4( void ) const { - return ToMat3().ToMat4(); -} - -/* -===================== -idQuat::ToCQuat -===================== -*/ -idCQuat idQuat::ToCQuat( void ) const { - if ( w < 0.0f ) { - return idCQuat( -x, -y, -z ); - } - return idCQuat( x, y, z ); -} - -/* -============ -idQuat::ToAngularVelocity -============ -*/ -idVec3 idQuat::ToAngularVelocity( void ) const { - idVec3 vec; - - vec.x = x; - vec.y = y; - vec.z = z; - vec.Normalize(); - return vec * idMath::ACos( w ); -} - -/* -============= -idQuat::ToString -============= -*/ -const char *idQuat::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -===================== -idQuat::Slerp - -Spherical linear interpolation between two quaternions. -===================== -*/ -idQuat &idQuat::Slerp( const idQuat &from, const idQuat &to, float t ) { - idQuat temp; - float omega, cosom, sinom, scale0, scale1; - - if ( t <= 0.0f ) { - *this = from; - return *this; - } - - if ( t >= 1.0f ) { - *this = to; - return *this; - } - - if ( from == to ) { - *this = to; - return *this; - } - - cosom = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w; - if ( cosom < 0.0f ) { - temp = -to; - cosom = -cosom; - } else { - temp = to; - } - - if ( ( 1.0f - cosom ) > 1e-6f ) { -#if 0 - omega = acos( cosom ); - sinom = 1.0f / sin( omega ); - scale0 = sin( ( 1.0f - t ) * omega ) * sinom; - scale1 = sin( t * omega ) * sinom; -#else - scale0 = 1.0f - cosom * cosom; - sinom = idMath::InvSqrt( scale0 ); - omega = idMath::ATan16( scale0 * sinom, cosom ); - scale0 = idMath::Sin16( ( 1.0f - t ) * omega ) * sinom; - scale1 = idMath::Sin16( t * omega ) * sinom; -#endif - } else { - scale0 = 1.0f - t; - scale1 = t; - } - - *this = ( scale0 * from ) + ( scale1 * temp ); - return *this; -} - -/* -============= -idCQuat::ToAngles -============= -*/ -idAngles idCQuat::ToAngles( void ) const { - return ToQuat().ToAngles(); -} - -/* -============= -idCQuat::ToRotation -============= -*/ -idRotation idCQuat::ToRotation( void ) const { - return ToQuat().ToRotation(); -} - -/* -============= -idCQuat::ToMat3 -============= -*/ -idMat3 idCQuat::ToMat3( void ) const { - return ToQuat().ToMat3(); -} - -/* -============= -idCQuat::ToMat4 -============= -*/ -idMat4 idCQuat::ToMat4( void ) const { - return ToQuat().ToMat4(); -} - -/* -============= -idCQuat::ToString -============= -*/ -const char *idCQuat::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/quat.h b/idlib/math/quat.h deleted file mode 100644 index 1fa030406..000000000 --- a/idlib/math/quat.h +++ /dev/null @@ -1,388 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_QUAT_H__ -#define __MATH_QUAT_H__ - -/* -=============================================================================== - - Quaternion - -=============================================================================== -*/ - - -class idVec3; -class idAngles; -class idRotation; -class idMat3; -class idMat4; -class idCQuat; - -class idQuat { -public: - float x; - float y; - float z; - float w; - - idQuat( void ); - idQuat( float x, float y, float z, float w ); - - void Set( float x, float y, float z, float w ); - - float operator[]( int index ) const; - float & operator[]( int index ); - idQuat operator-() const; - idQuat & operator=( const idQuat &a ); - idQuat operator+( const idQuat &a ) const; - idQuat & operator+=( const idQuat &a ); - idQuat operator-( const idQuat &a ) const; - idQuat & operator-=( const idQuat &a ); - idQuat operator*( const idQuat &a ) const; - idVec3 operator*( const idVec3 &a ) const; - idQuat operator*( float a ) const; - idQuat & operator*=( const idQuat &a ); - idQuat & operator*=( float a ); - - friend idQuat operator*( const float a, const idQuat &b ); - friend idVec3 operator*( const idVec3 &a, const idQuat &b ); - - bool Compare( const idQuat &a ) const; // exact compare, no epsilon - bool Compare( const idQuat &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idQuat &a ) const; // exact compare, no epsilon - bool operator!=( const idQuat &a ) const; // exact compare, no epsilon - - idQuat Inverse( void ) const; - float Length( void ) const; - idQuat & Normalize( void ); - - float CalcW( void ) const; - int GetDimension( void ) const; - - idAngles ToAngles( void ) const; - idRotation ToRotation( void ) const; - idMat3 ToMat3( void ) const; - idMat4 ToMat4( void ) const; - idCQuat ToCQuat( void ) const; - idVec3 ToAngularVelocity( void ) const; - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - idQuat & Slerp( const idQuat &from, const idQuat &to, float t ); -}; - -ID_INLINE idQuat::idQuat( void ) { -} - -ID_INLINE idQuat::idQuat( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -ID_INLINE float idQuat::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -ID_INLINE float& idQuat::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -ID_INLINE idQuat idQuat::operator-() const { - return idQuat( -x, -y, -z, -w ); -} - -ID_INLINE idQuat &idQuat::operator=( const idQuat &a ) { - x = a.x; - y = a.y; - z = a.z; - w = a.w; - - return *this; -} - -ID_INLINE idQuat idQuat::operator+( const idQuat &a ) const { - return idQuat( x + a.x, y + a.y, z + a.z, w + a.w ); -} - -ID_INLINE idQuat& idQuat::operator+=( const idQuat &a ) { - x += a.x; - y += a.y; - z += a.z; - w += a.w; - - return *this; -} - -ID_INLINE idQuat idQuat::operator-( const idQuat &a ) const { - return idQuat( x - a.x, y - a.y, z - a.z, w - a.w ); -} - -ID_INLINE idQuat& idQuat::operator-=( const idQuat &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - w -= a.w; - - return *this; -} - -ID_INLINE idQuat idQuat::operator*( const idQuat &a ) const { - return idQuat( w*a.x + x*a.w + y*a.z - z*a.y, - w*a.y + y*a.w + z*a.x - x*a.z, - w*a.z + z*a.w + x*a.y - y*a.x, - w*a.w - x*a.x - y*a.y - z*a.z ); -} - -ID_INLINE idVec3 idQuat::operator*( const idVec3 &a ) const { -#if 0 - // it's faster to do the conversion to a 3x3 matrix and multiply the vector by this 3x3 matrix - return ( ToMat3() * a ); -#else - // result = this->Inverse() * idQuat( a.x, a.y, a.z, 0.0f ) * (*this) - float xxzz = x*x - z*z; - float wwyy = w*w - y*y; - - float xw2 = x*w*2.0f; - float xy2 = x*y*2.0f; - float xz2 = x*z*2.0f; - float yw2 = y*w*2.0f; - float yz2 = y*z*2.0f; - float zw2 = z*w*2.0f; - - return idVec3( - (xxzz + wwyy)*a.x + (xy2 + zw2)*a.y + (xz2 - yw2)*a.z, - (xy2 - zw2)*a.x + (y*y+w*w-x*x-z*z)*a.y + (yz2 + xw2)*a.z, - (xz2 + yw2)*a.x + (yz2 - xw2)*a.y + (wwyy - xxzz)*a.z - ); -#endif -} - -ID_INLINE idQuat idQuat::operator*( float a ) const { - return idQuat( x * a, y * a, z * a, w * a ); -} - -ID_INLINE idQuat operator*( const float a, const idQuat &b ) { - return b * a; -} - -ID_INLINE idVec3 operator*( const idVec3 &a, const idQuat &b ) { - return b * a; -} - -ID_INLINE idQuat& idQuat::operator*=( const idQuat &a ) { - *this = *this * a; - - return *this; -} - -ID_INLINE idQuat& idQuat::operator*=( float a ) { - x *= a; - y *= a; - z *= a; - w *= a; - - return *this; -} - -ID_INLINE bool idQuat::Compare( const idQuat &a ) const { - return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && ( w == a.w ) ); -} - -ID_INLINE bool idQuat::Compare( const idQuat &a, const float epsilon ) const { - if ( idMath::Fabs( x - a.x ) > epsilon ) { - return false; - } - if ( idMath::Fabs( y - a.y ) > epsilon ) { - return false; - } - if ( idMath::Fabs( z - a.z ) > epsilon ) { - return false; - } - if ( idMath::Fabs( w - a.w ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE bool idQuat::operator==( const idQuat &a ) const { - return Compare( a ); -} - -ID_INLINE bool idQuat::operator!=( const idQuat &a ) const { - return !Compare( a ); -} - -ID_INLINE void idQuat::Set( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -ID_INLINE idQuat idQuat::Inverse( void ) const { - return idQuat( -x, -y, -z, w ); -} - -ID_INLINE float idQuat::Length( void ) const { - float len; - - len = x * x + y * y + z * z + w * w; - return idMath::Sqrt( len ); -} - -ID_INLINE idQuat& idQuat::Normalize( void ) { - float len; - float ilength; - - len = this->Length(); - if ( len ) { - ilength = 1 / len; - x *= ilength; - y *= ilength; - z *= ilength; - w *= ilength; - } - return *this; -} - -ID_INLINE float idQuat::CalcW( void ) const { - // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1 - return sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ); -} - -ID_INLINE int idQuat::GetDimension( void ) const { - return 4; -} - -ID_INLINE const float *idQuat::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idQuat::ToFloatPtr( void ) { - return &x; -} - - -/* -=============================================================================== - - Compressed quaternion - -=============================================================================== -*/ - -class idCQuat { -public: - float x; - float y; - float z; - - idCQuat( void ); - idCQuat( float x, float y, float z ); - - void Set( float x, float y, float z ); - - float operator[]( int index ) const; - float & operator[]( int index ); - - bool Compare( const idCQuat &a ) const; // exact compare, no epsilon - bool Compare( const idCQuat &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idCQuat &a ) const; // exact compare, no epsilon - bool operator!=( const idCQuat &a ) const; // exact compare, no epsilon - - int GetDimension( void ) const; - - idAngles ToAngles( void ) const; - idRotation ToRotation( void ) const; - idMat3 ToMat3( void ) const; - idMat4 ToMat4( void ) const; - idQuat ToQuat( void ) const; - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; -}; - -ID_INLINE idCQuat::idCQuat( void ) { -} - -ID_INLINE idCQuat::idCQuat( float x, float y, float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE void idCQuat::Set( float x, float y, float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE float idCQuat::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &x )[ index ]; -} - -ID_INLINE float& idCQuat::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &x )[ index ]; -} - -ID_INLINE bool idCQuat::Compare( const idCQuat &a ) const { - return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) ); -} - -ID_INLINE bool idCQuat::Compare( const idCQuat &a, const float epsilon ) const { - if ( idMath::Fabs( x - a.x ) > epsilon ) { - return false; - } - if ( idMath::Fabs( y - a.y ) > epsilon ) { - return false; - } - if ( idMath::Fabs( z - a.z ) > epsilon ) { - return false; - } - return true; -} - -ID_INLINE bool idCQuat::operator==( const idCQuat &a ) const { - return Compare( a ); -} - -ID_INLINE bool idCQuat::operator!=( const idCQuat &a ) const { - return !Compare( a ); -} - -ID_INLINE int idCQuat::GetDimension( void ) const { - return 3; -} - -ID_INLINE idQuat idCQuat::ToQuat( void ) const { - // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1 - return idQuat( x, y, z, sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ) ); -} - -ID_INLINE const float *idCQuat::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idCQuat::ToFloatPtr( void ) { - return &x; -} - -#endif /* !__MATH_QUAT_H__ */ diff --git a/idlib/math/random.h b/idlib/math/random.h deleted file mode 100644 index d213380b5..000000000 --- a/idlib/math/random.h +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_RANDOM_H__ -#define __MATH_RANDOM_H__ - -/* -=============================================================================== - - Random number generator - -=============================================================================== -*/ - -class idRandom { -public: - idRandom( int seed = 0 ); - - void SetSeed( int seed ); - int GetSeed( void ) const; - - int RandomInt( void ); // random integer in the range [0, MAX_RAND] - int RandomInt( int max ); // random integer in the range [0, max[ - float RandomFloat( void ); // random number in the range [0.0f, 1.0f] - float CRandomFloat( void ); // random number in the range [-1.0f, 1.0f] - - static const int MAX_RAND = 0x7fff; - -private: - int seed; -}; - -ID_INLINE idRandom::idRandom( int seed ) { - this->seed = seed; -} - -ID_INLINE void idRandom::SetSeed( int seed ) { - this->seed = seed; -} - -ID_INLINE int idRandom::GetSeed( void ) const { - return seed; -} - -ID_INLINE int idRandom::RandomInt( void ) { - seed = 69069 * seed + 1; - return ( seed & idRandom::MAX_RAND ); -} - -ID_INLINE int idRandom::RandomInt( int max ) { - if ( max == 0 ) { - return 0; // avoid divide by zero error - } - return RandomInt() % max; -} - -ID_INLINE float idRandom::RandomFloat( void ) { - return ( RandomInt() / ( float )( idRandom::MAX_RAND + 1 ) ); -} - -ID_INLINE float idRandom::CRandomFloat( void ) { - return ( 2.0f * ( RandomFloat() - 0.5f ) ); -} - - -/* -=============================================================================== - - Random number generator - -=============================================================================== -*/ - -class idRandom2 { -public: - idRandom2( unsigned long seed = 0 ); - - void SetSeed( unsigned long seed ); - unsigned long GetSeed( void ) const; - - int RandomInt( void ); // random integer in the range [0, MAX_RAND] - int RandomInt( int max ); // random integer in the range [0, max] - float RandomFloat( void ); // random number in the range [0.0f, 1.0f] - float CRandomFloat( void ); // random number in the range [-1.0f, 1.0f] - - static const int MAX_RAND = 0x7fff; - -private: - unsigned long seed; - - static const unsigned long IEEE_ONE = 0x3f800000; - static const unsigned long IEEE_MASK = 0x007fffff; -}; - -ID_INLINE idRandom2::idRandom2( unsigned long seed ) { - this->seed = seed; -} - -ID_INLINE void idRandom2::SetSeed( unsigned long seed ) { - this->seed = seed; -} - -ID_INLINE unsigned long idRandom2::GetSeed( void ) const { - return seed; -} - -ID_INLINE int idRandom2::RandomInt( void ) { - seed = 1664525L * seed + 1013904223L; - return ( (int) seed & idRandom2::MAX_RAND ); -} - -ID_INLINE int idRandom2::RandomInt( int max ) { - if ( max == 0 ) { - return 0; // avoid divide by zero error - } - return ( RandomInt() >> ( 16 - idMath::BitsForInteger( max ) ) ) % max; -} - -ID_INLINE float idRandom2::RandomFloat( void ) { - unsigned long i; - seed = 1664525L * seed + 1013904223L; - i = idRandom2::IEEE_ONE | ( seed & idRandom2::IEEE_MASK ); - return ( ( *(float *)&i ) - 1.0f ); -} - -ID_INLINE float idRandom2::CRandomFloat( void ) { - unsigned long i; - seed = 1664525L * seed + 1013904223L; - i = idRandom2::IEEE_ONE | ( seed & idRandom2::IEEE_MASK ); - return ( 2.0f * ( *(float *)&i ) - 3.0f ); -} - -#endif /* !__MATH_RANDOM_H__ */ diff --git a/idlib/math/rotation.cpp b/idlib/math/rotation.cpp deleted file mode 100644 index f59e38900..000000000 --- a/idlib/math/rotation.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -============ -idRotation::ToAngles -============ -*/ -idAngles idRotation::ToAngles( void ) const { - return ToMat3().ToAngles(); -} - -/* -============ -idRotation::ToQuat -============ -*/ -idQuat idRotation::ToQuat( void ) const { - float a, s, c; - - a = angle * ( idMath::M_DEG2RAD * 0.5f ); - idMath::SinCos( a, s, c ); - return idQuat( vec.x * s, vec.y * s, vec.z * s, c ); -} - -/* -============ -idRotation::toMat3 -============ -*/ -const idMat3 &idRotation::ToMat3( void ) const { - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - float a, c, s, x, y, z; - - if ( axisValid ) { - return axis; - } - - a = angle * ( idMath::M_DEG2RAD * 0.5f ); - idMath::SinCos( a, s, c ); - - x = vec[0] * s; - y = vec[1] * s; - z = vec[2] * s; - - x2 = x + x; - y2 = y + y; - z2 = z + z; - - xx = x * x2; - xy = x * y2; - xz = x * z2; - - yy = y * y2; - yz = y * z2; - zz = z * z2; - - wx = c * x2; - wy = c * y2; - wz = c * z2; - - axis[ 0 ][ 0 ] = 1.0f - ( yy + zz ); - axis[ 0 ][ 1 ] = xy - wz; - axis[ 0 ][ 2 ] = xz + wy; - - axis[ 1 ][ 0 ] = xy + wz; - axis[ 1 ][ 1 ] = 1.0f - ( xx + zz ); - axis[ 1 ][ 2 ] = yz - wx; - - axis[ 2 ][ 0 ] = xz - wy; - axis[ 2 ][ 1 ] = yz + wx; - axis[ 2 ][ 2 ] = 1.0f - ( xx + yy ); - - axisValid = true; - - return axis; -} - -/* -============ -idRotation::ToMat4 -============ -*/ -idMat4 idRotation::ToMat4( void ) const { - return ToMat3().ToMat4(); -} - -/* -============ -idRotation::ToAngularVelocity -============ -*/ -idVec3 idRotation::ToAngularVelocity( void ) const { - return vec * DEG2RAD( angle ); -} - -/* -============ -idRotation::Normalize180 -============ -*/ -void idRotation::Normalize180( void ) { - angle -= floor( angle / 360.0f ) * 360.0f; - if ( angle > 180.0f ) { - angle -= 360.0f; - } - else if ( angle < -180.0f ) { - angle += 360.0f; - } -} - -/* -============ -idRotation::Normalize360 -============ -*/ -void idRotation::Normalize360( void ) { - angle -= floor( angle / 360.0f ) * 360.0f; - if ( angle > 360.0f ) { - angle -= 360.0f; - } - else if ( angle < 0.0f ) { - angle += 360.0f; - } -} diff --git a/idlib/math/rotation.h b/idlib/math/rotation.h deleted file mode 100644 index 863b1e5a2..000000000 --- a/idlib/math/rotation.h +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_ROTATION_H__ -#define __MATH_ROTATION_H__ - -/* -=============================================================================== - - Describes a complete rotation in degrees about an abritray axis. - A local rotation matrix is stored for fast rotation of multiple points. - -=============================================================================== -*/ - - -class idAngles; -class idQuat; -class idMat3; - -class idRotation { - - friend class idAngles; - friend class idQuat; - friend class idMat3; - -public: - idRotation( void ); - idRotation( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ); - - void Set( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ); - void SetOrigin( const idVec3 &rotationOrigin ); - void SetVec( const idVec3 &rotationVec ); // has to be normalized - void SetVec( const float x, const float y, const float z ); // has to be normalized - void SetAngle( const float rotationAngle ); - void Scale( const float s ); - void ReCalculateMatrix( void ); - const idVec3 & GetOrigin( void ) const; - const idVec3 & GetVec( void ) const; - float GetAngle( void ) const; - - idRotation operator-() const; // flips rotation - idRotation operator*( const float s ) const; // scale rotation - idRotation operator/( const float s ) const; // scale rotation - idRotation & operator*=( const float s ); // scale rotation - idRotation & operator/=( const float s ); // scale rotation - idVec3 operator*( const idVec3 &v ) const; // rotate vector - - friend idRotation operator*( const float s, const idRotation &r ); // scale rotation - friend idVec3 operator*( const idVec3 &v, const idRotation &r ); // rotate vector - friend idVec3 & operator*=( idVec3 &v, const idRotation &r ); // rotate vector - - idAngles ToAngles( void ) const; - idQuat ToQuat( void ) const; - const idMat3 & ToMat3( void ) const; - idMat4 ToMat4( void ) const; - idVec3 ToAngularVelocity( void ) const; - - void RotatePoint( idVec3 &point ) const; - - void Normalize180( void ); - void Normalize360( void ); - -private: - idVec3 origin; // origin of rotation - idVec3 vec; // normalized vector to rotate around - float angle; // angle of rotation in degrees - mutable idMat3 axis; // rotation axis - mutable bool axisValid; // true if rotation axis is valid -}; - - -ID_INLINE idRotation::idRotation( void ) { -} - -ID_INLINE idRotation::idRotation( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ) { - origin = rotationOrigin; - vec = rotationVec; - angle = rotationAngle; - axisValid = false; -} - -ID_INLINE void idRotation::Set( const idVec3 &rotationOrigin, const idVec3 &rotationVec, const float rotationAngle ) { - origin = rotationOrigin; - vec = rotationVec; - angle = rotationAngle; - axisValid = false; -} - -ID_INLINE void idRotation::SetOrigin( const idVec3 &rotationOrigin ) { - origin = rotationOrigin; -} - -ID_INLINE void idRotation::SetVec( const idVec3 &rotationVec ) { - vec = rotationVec; - axisValid = false; -} - -ID_INLINE void idRotation::SetVec( float x, float y, float z ) { - vec[0] = x; - vec[1] = y; - vec[2] = z; - axisValid = false; -} - -ID_INLINE void idRotation::SetAngle( const float rotationAngle ) { - angle = rotationAngle; - axisValid = false; -} - -ID_INLINE void idRotation::Scale( const float s ) { - angle *= s; - axisValid = false; -} - -ID_INLINE void idRotation::ReCalculateMatrix( void ) { - axisValid = false; - ToMat3(); -} - -ID_INLINE const idVec3 &idRotation::GetOrigin( void ) const { - return origin; -} - -ID_INLINE const idVec3 &idRotation::GetVec( void ) const { - return vec; -} - -ID_INLINE float idRotation::GetAngle( void ) const { - return angle; -} - -ID_INLINE idRotation idRotation::operator-() const { - return idRotation( origin, vec, -angle ); -} - -ID_INLINE idRotation idRotation::operator*( const float s ) const { - return idRotation( origin, vec, angle * s ); -} - -ID_INLINE idRotation idRotation::operator/( const float s ) const { - assert( s != 0.0f ); - return idRotation( origin, vec, angle / s ); -} - -ID_INLINE idRotation &idRotation::operator*=( const float s ) { - angle *= s; - axisValid = false; - return *this; -} - -ID_INLINE idRotation &idRotation::operator/=( const float s ) { - assert( s != 0.0f ); - angle /= s; - axisValid = false; - return *this; -} - -ID_INLINE idVec3 idRotation::operator*( const idVec3 &v ) const { - if ( !axisValid ) { - ToMat3(); - } - return ((v - origin) * axis + origin); -} - -ID_INLINE idRotation operator*( const float s, const idRotation &r ) { - return r * s; -} - -ID_INLINE idVec3 operator*( const idVec3 &v, const idRotation &r ) { - return r * v; -} - -ID_INLINE idVec3 &operator*=( idVec3 &v, const idRotation &r ) { - v = r * v; - return v; -} - -ID_INLINE void idRotation::RotatePoint( idVec3 &point ) const { - if ( !axisValid ) { - ToMat3(); - } - point = ((point - origin) * axis + origin); -} - -#endif /* !__MATH_ROTATION_H__ */ diff --git a/idlib/math/simd.cpp b/idlib/math/simd.cpp deleted file mode 100644 index 6b3c85ae2..000000000 --- a/idlib/math/simd.cpp +++ /dev/null @@ -1,4318 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// Copyright (C) 2010 The Dark Mod Team - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "simd_generic.h" -#include "simd_mmx.h" -#include "simd_3dnow.h" -#include "simd_sse.h" -#include "simd_sse2.h" -#include "simd_sse3.h" -#include "simd_altivec.h" - -idSIMDProcessor * processor = NULL; // pointer to SIMD processor -idSIMDProcessor * generic = NULL; // pointer to generic SIMD implementation -idSIMDProcessor * SIMDProcessor = NULL; - - -/* -================ -idSIMD::Init -================ -*/ -void idSIMD::Init( void ) { - generic = new idSIMD_Generic; - generic->cpuid = CPUID_GENERIC; - processor = NULL; - SIMDProcessor = generic; -} - -/* -============ -idSIMD::InitProcessor -============ -*/ -void idSIMD::InitProcessor( const char *module, bool forceGeneric ) { - cpuid_t cpuid; - idSIMDProcessor *newProcessor; - - cpuid = idLib::sys->GetProcessorId(); - - /* - * Tels: Bug #2413: Under Linux, cpuid_t is 0, so use inline assembly to get - * the correct flags: - */ -#ifdef __linux__ - int cores = 0; - dword a,c,d, result; - - /* Check for AMD or Intel first */ - __asm__ __volatile__ ( - " pushl %%ebx;" // Save ebx (needed for PIC (position independend code) - " movl $0, %%eax;" // CPUID with EAX = 0 - " cpuid;" // Returns data into eax, ebx, ecx, edx - " movl %%ebx, %%eax;" // EAX => EBX - " popl %%ebx;" // Restore EBX - : "=d" (d), "=c" (c), "=a" (a) // EDX => d, ECX => c, EAX => a - : // no inputs - : ); // clobbers no additional registers (except EAX, ECX and EDX) - - //idLib::common->Printf( "cpuid result is a=%x, c=%x, d=%x\n", a,c,d ); - - result = CPUID_GENERIC; - // "AuthenticAMD" - if (( 0x68747541l == a ) && ( 0x444d4163l == c ) && ( 0x69746e65l == d ) ) - { - result = CPUID_AMD; - } - else - // "GenuineIntel" - if (( 0x756e6547l == a ) && ( 0x6c65746el == c ) && ( 0x49656e69l == d ) ) - { - result = CPUID_INTEL; - } - - __asm__ __volatile__ ( - " pushl %%ebx;" // Save ebx (needed for PIC (position independend code) - " movl $1, %%eax;" // CPUID with EAX = 1 - " cpuid;" // Returns data into eax, ebx, ecx, edx - " movl %%ebx, %%eax;" // Put EBX value into EAX (so we can return it) - " popl %%ebx;" // Restore ebx - : "=d" (d), "=c" (c), "=a" (a) // EDX => d, ECX => c, EAX => a - : // no inputs - : ); // clobbers no extra registers beside the outputs - - // This can only be checked on AMD CPUs - if ( (result & CPUID_AMD) && (d & 0x10000000l) ) // >> 31 does not work here - { - result += CPUID_3DNOW; - } - // The calculation how many physical/logical CPUs the machine has is rather - // convuluted and differes between AMD and Intel, so we don't attempt it, we - // only check bits 16..23 of EBX to see if it is > 1: - cores = (a >> 16) & 0xFF; - // Only on Intel we can have Hyper-Threading - if ( (result & CPUID_INTEL) && ((d >> 28) & 0x1) && cores > 1 ) - { - result += CPUID_HTT; - } - - // These tests are the same for AMD and Intel - if ((d >> 23) & 0x1) - { - result += CPUID_MMX; - } - if ((d >> 25) & 0x1) - { - result += CPUID_SSE; - } - if ((d >> 26) & 0x1) - { - result += CPUID_SSE2; - } - if ((d >> 15) & 0x1) - { - result += CPUID_CMOV; - } - if (c & 0x1) - { - result += CPUID_SSE3; - } - - //idLib::common->Printf( "cpuid result is %i (c = %i d = %i)\n", result, c, d); - cpuid = (cpuid_t)result; -#endif - - // Print what we found to console - idLib::common->Printf( "Found %s CPU%s, features:%s%s%s%s%s%s\n", - // Vendor - cpuid & CPUID_AMD ? "AMD" : - cpuid & CPUID_INTEL ? "Intel" : - cpuid & CPUID_GENERIC ? "Generic" : - "Unsupported", - // Hyper-Threading? - cpuid & CPUID_HTT ? " with Hyper-Threading enabled" : "", - - // the calculation how many physical/logical CPUs the machine has is rather - // convuluted and differes between AMD and Intel, so we don't attempt it: -// cores, -// cores > 1 ? "cores" : "core", - // Flags - cpuid & CPUID_MMX ? " MMX" : "", - cpuid & CPUID_SSE ? " SSE" : "", - cpuid & CPUID_SSE2 ? " SSE2" : "", - cpuid & CPUID_SSE3 ? " SSE3" : "", - cpuid & CPUID_3DNOW ? " 3DNow!" : "", - cpuid & CPUID_CMOV ? " CMOV" : "" ); - - if ( forceGeneric ) { - - newProcessor = generic; - - } else { - - if ( !processor ) { - if ( ( cpuid & CPUID_ALTIVEC ) ) { - processor = new idSIMD_AltiVec; - } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) && ( cpuid & CPUID_SSE2 ) && ( cpuid & CPUID_SSE3 ) ) { - processor = new idSIMD_SSE3; - } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) && ( cpuid & CPUID_SSE2 ) ) { - processor = new idSIMD_SSE2; - } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_SSE ) ) { - processor = new idSIMD_SSE; - } else if ( ( cpuid & CPUID_MMX ) && ( cpuid & CPUID_3DNOW ) ) { - processor = new idSIMD_3DNow; - } else if ( ( cpuid & CPUID_MMX ) ) { - processor = new idSIMD_MMX; - } else { - processor = generic; - } - processor->cpuid = cpuid; - } - - newProcessor = processor; - } - - if ( newProcessor != SIMDProcessor ) { - SIMDProcessor = newProcessor; - } - idLib::common->Printf( "%s using %s for SIMD processing.\n", module, SIMDProcessor->GetName() ); - - if ( cpuid & CPUID_FTZ ) { - idLib::sys->FPU_SetFTZ( true ); - idLib::common->Printf( "enabled Flush-To-Zero mode\n" ); - } - - if ( cpuid & CPUID_DAZ ) { - idLib::sys->FPU_SetDAZ( true ); - idLib::common->Printf( "enabled Denormals-Are-Zero mode\n" ); - } -} - -/* -================ -idSIMD::Shutdown -================ -*/ -void idSIMD::Shutdown( void ) { - if ( processor != generic ) { - delete processor; - } - delete generic; - generic = NULL; - processor = NULL; - SIMDProcessor = NULL; -} - - -//=============================================================== -// -// Test code -// -//=============================================================== - -#define COUNT 1024 // data count -#define NUMTESTS 2048 // number of tests - -#define RANDOM_SEED 1013904223L //((int)idLib::sys->GetClockTicks()) - -idSIMDProcessor *p_simd; -idSIMDProcessor *p_generic; -long baseClocks = 0; - -#ifdef _WIN32 - -#define TIME_TYPE int - -#pragma warning(disable : 4731) // frame pointer register 'ebx' modified by inline assembly code - -long saved_ebx = 0; - -#define StartRecordTime( start ) \ - __asm mov saved_ebx, ebx \ - __asm xor eax, eax \ - __asm cpuid \ - __asm rdtsc \ - __asm mov start, eax \ - __asm xor eax, eax \ - __asm cpuid - -#define StopRecordTime( end ) \ - __asm xor eax, eax \ - __asm cpuid \ - __asm rdtsc \ - __asm mov end, eax \ - __asm mov ebx, saved_ebx \ - __asm xor eax, eax \ - __asm cpuid - -#elif MACOS_X - -#include -#include // this is for sleep() -#include -#include -#include - -double ticksPerNanosecond; - -#define TIME_TYPE uint64_t - -#ifdef __MWERKS__ //time_in_millisec is missing -/* - - .text - .align 2 - .globl _GetTB -_GetTB: - -loop: - mftbu r4 ; load from TBU - mftb r5 ; load from TBL - mftbu r6 ; load from TBU - cmpw r6, r4 ; see if old == new - bne loop ; if not, carry occured, therefore loop - - stw r4, 0(r3) - stw r5, 4(r3) - -done: - blr ; return - -*/ -typedef struct { - unsigned int hi; - unsigned int lo; -} U64; - - -asm void GetTB(U64 *in) -{ - nofralloc // suppress prolog - machine 603 // allows the use of mftb & mftbu functions - -loop: - mftbu r5 // grab the upper time base register (TBU) - mftb r4 // grab the lower time base register (TBL) - mftbu r6 // grab the upper time base register (TBU) again - - cmpw r6,r5 // see if old TBU == new TBU - bne- loop // loop if carry occurred (predict branch not taken) - - stw r4,4(r3) // store TBL in the low 32 bits of the return value - stw r5,0(r3) // store TBU in the high 32 bits of the return value - - blr -} - - - - -double TBToDoubleNano( U64 startTime, U64 stopTime, double ticksPerNanosecond ); - -#if __MWERKS__ -asm void GetTB( U64 * ); -#else -void GetTB( U64 * ); -#endif - -double TBToDoubleNano( U64 startTime, U64 stopTime, double ticksPerNanosecond ) { - #define K_2POWER32 4294967296.0 - #define TICKS_PER_NANOSECOND 0.025 - double nanoTime; - U64 diffTime; - - // calc the difference in TB ticks - diffTime.hi = stopTime.hi - startTime.hi; - diffTime.lo = stopTime.lo - startTime.lo; - - // convert TB ticks into time - nanoTime = (double)(diffTime.hi)*((double)K_2POWER32) + (double)(diffTime.lo); - nanoTime = nanoTime/ticksPerNanosecond; - return (nanoTime); -} - -TIME_TYPE time_in_millisec( void ) { - #define K_2POWER32 4294967296.0 - #define TICKS_PER_NANOSECOND 0.025 - - U64 the_time; - double nanoTime, milliTime; - - GetTB( &the_time ); - - // convert TB ticks into time - nanoTime = (double)(the_time.hi)*((double)K_2POWER32) + (double)(the_time.lo); - nanoTime = nanoTime/ticksPerNanosecond; - - // nanoseconds are 1 billionth of a second. I want milliseconds - milliTime = nanoTime * 1000000.0; - - printf( "ticks per nanosec -- %lf\n", ticksPerNanosecond ); - printf( "nanoTime is %lf -- milliTime is %lf -- as int is %i\n", nanoTime, milliTime, (int)milliTime ); - - return (int)milliTime; -} - -#define StartRecordTime( start ) \ - start = time_in_millisec(); - -#define StopRecordTime( end ) \ - end = time_in_millisec(); - - -#else -#define StartRecordTime( start ) \ - start = mach_absolute_time(); - -#define StopRecordTime( end ) \ - end = mach_absolute_time(); -#endif -#else - -#define TIME_TYPE int - -#define StartRecordTime( start ) \ - start = 0; - -#define StopRecordTime( end ) \ - end = 1; - -#endif - -#define GetBest( start, end, best ) \ - if ( !best || end - start < best ) { \ - best = end - start; \ - } - - -/* -============ -PrintClocks -============ -*/ -void PrintClocks( char *string, int dataCount, int clocks, int otherClocks = 0 ) { - int i; - - idLib::common->Printf( string ); - for ( i = idStr::LengthWithoutColors(string); i < 48; i++ ) { - idLib::common->Printf(" "); - } - clocks -= baseClocks; - if ( otherClocks && clocks ) { - otherClocks -= baseClocks; - int p = (int) ( (float) ( otherClocks - clocks ) * 100.0f / (float) otherClocks ); - idLib::common->Printf( "c = %4d, clcks = %5d, %d%%\n", dataCount, clocks, p ); - } else { - idLib::common->Printf( "c = %4d, clcks = %5d\n", dataCount, clocks ); - } -} - -/* -============ -GetBaseClocks -============ -*/ -void GetBaseClocks( void ) { - int i, start, end, bestClocks; - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - baseClocks = bestClocks; -} - -/* -============ -TestAdd -============ -*/ -void TestAdd( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - fsrc1[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Add( fdst0, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Add( float + float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Add( fdst1, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Add( float + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Add( fdst0, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Add( float[] + float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Add( fdst1, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Add( float[] + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestSub -============ -*/ -void TestSub( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - fsrc1[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Sub( fdst0, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Sub( float + float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Sub( fdst1, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Sub( float + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Sub( fdst0, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Sub( float[] + float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Sub( fdst1, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Sub( float[] + float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestMul -============ -*/ -void TestMul( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - fsrc1[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Mul( fdst0, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Mul( float * float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Mul( fdst1, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Mul( float * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Mul( fdst0, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Mul( float[] * float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Mul( fdst1, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Mul( float[] * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestDiv -============ -*/ -void TestDiv( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - do { - fsrc1[i] = srnd.CRandomFloat() * 10.0f; - } while( idMath::Fabs( fsrc1[i] ) < 0.1f ); - } - - idLib::common->Printf("====================================\n" ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Div( fdst0, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Div( float * float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Div( fdst1, 4.0f, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Div( float * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Div( fdst0, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Div( float[] * float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Div( fdst1, fsrc0, fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-3f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Div( float[] * float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestMulAdd -============ -*/ -void TestMulAdd( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - for ( j = 0; j < 50 && j < COUNT; j++ ) { - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( int k = 0; k < COUNT; k++ ) { - fdst0[k] = k; - } - StartRecordTime( start ); - p_generic->MulAdd( fdst0, 0.123f, fsrc0, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( va( "generic->MulAdd( float * float[%2d] )", j ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( int k = 0; k < COUNT; k++ ) { - fdst1[k] = k; - } - StartRecordTime( start ); - p_simd->MulAdd( fdst1, 0.123f, fsrc0, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MulAdd( float * float[%2d] ) %s", j, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMulSub -============ -*/ -void TestMulSub( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - for ( j = 0; j < 50 && j < COUNT; j++ ) { - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( int k = 0; k < COUNT; k++ ) { - fdst0[k] = k; - } - StartRecordTime( start ); - p_generic->MulSub( fdst0, 0.123f, fsrc0, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( va( "generic->MulSub( float * float[%2d] )", j ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( int k = 0; k < COUNT; k++ ) { - fdst1[k] = k; - } - StartRecordTime( start ); - p_simd->MulSub( fdst1, 0.123f, fsrc0, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MulSub( float * float[%2d] ) %s", j, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestDot -============ -*/ -void TestDot( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - ALIGN16( idVec3 v3src0[COUNT] ); - ALIGN16( idVec3 v3src1[COUNT] ); - ALIGN16( idVec3 v3constant ) ( 1.0f, 2.0f, 3.0f ); - ALIGN16( idPlane v4src0[COUNT] ); - ALIGN16( idPlane v4constant ) (1.0f, 2.0f, 3.0f, 4.0f); - ALIGN16( idDrawVert drawVerts[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - fsrc1[i] = srnd.CRandomFloat() * 10.0f; - v3src0[i][0] = srnd.CRandomFloat() * 10.0f; - v3src0[i][1] = srnd.CRandomFloat() * 10.0f; - v3src0[i][2] = srnd.CRandomFloat() * 10.0f; - v3src1[i][0] = srnd.CRandomFloat() * 10.0f; - v3src1[i][1] = srnd.CRandomFloat() * 10.0f; - v3src1[i][2] = srnd.CRandomFloat() * 10.0f; - v4src0[i] = v3src0[i]; - v4src0[i][3] = srnd.CRandomFloat() * 10.0f; - drawVerts[i].xyz = v3src0[i]; - } - - idLib::common->Printf("====================================\n" ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v3constant, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idVec3 * idVec3[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v3constant, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idVec3 * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v3constant, v4src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idVec3 * idPlane[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v3constant, v4src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idVec3 * idPlane[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v3constant, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idVec3 * idDrawVert[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v3constant, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idVec3 * idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v4constant, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idPlane * idVec3[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v4constant, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idPlane * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v4constant, v4src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idPlane * idPlane[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v4constant, v4src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idPlane * idPlane[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v4constant, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idPlane * idDrawVert[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v4constant, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-5f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idPlane * idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( fdst0, v3src0, v3src1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Dot( idVec3[] * idVec3[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( fdst1, v3src0, v3src1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( idMath::Fabs( fdst0[i] - fdst1[i] ) > 1e-4f ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( idVec3[] * idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - idLib::common->Printf("====================================\n" ); - - float dot1 = 0.0f, dot2 = 0.0f; - for ( j = 0; j < 50 && j < COUNT; j++ ) { - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Dot( dot1, fsrc0, fsrc1, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( va( "generic->Dot( float[%2d] * float[%2d] )", j, j ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Dot( dot2, fsrc0, fsrc1, j ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - result = idMath::Fabs( dot1 - dot2 ) < 1e-4f ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Dot( float[%2d] * float[%2d] ) %s", j, j, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestCompare -============ -*/ -void TestCompare( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( byte bytedst[COUNT] ); - ALIGN16( byte bytedst2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CmpGT( bytedst, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpGT( float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CmpGT( bytedst2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpGT( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst, 0, COUNT ); - StartRecordTime( start ); - p_generic->CmpGT( bytedst, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpGT( 2, float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst2, 0, COUNT ); - StartRecordTime( start ); - p_simd->CmpGT( bytedst2, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpGT( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - // ====================== - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CmpGE( bytedst, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpGE( float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CmpGE( bytedst2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpGE( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst, 0, COUNT ); - StartRecordTime( start ); - p_generic->CmpGE( bytedst, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpGE( 2, float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst2, 0, COUNT ); - StartRecordTime( start ); - p_simd->CmpGE( bytedst2, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpGE( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - // ====================== - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CmpLT( bytedst, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpLT( float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CmpLT( bytedst2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpLT( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst, 0, COUNT ); - StartRecordTime( start ); - p_generic->CmpLT( bytedst, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpLT( 2, float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst2, 0, COUNT ); - StartRecordTime( start ); - p_simd->CmpLT( bytedst2, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpLT( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - // ====================== - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CmpLE( bytedst, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpLE( float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CmpLE( bytedst2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpLE( float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst, 0, COUNT ); - StartRecordTime( start ); - p_generic->CmpLE( bytedst, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CmpLE( 2, float[] >= float )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - memset( bytedst2, 0, COUNT ); - StartRecordTime( start ); - p_simd->CmpLE( bytedst2, 2, fsrc0, 0.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( bytedst[i] != bytedst2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CmpLE( 2, float[] >= float ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestMinMax -============ -*/ -void TestMinMax( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( idVec2 v2src0[COUNT] ); - ALIGN16( idVec3 v3src0[COUNT] ); - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( int indexes[COUNT] ); - float min = 0.0f, max = 0.0f, min2 = 0.0f, max2 = 0.0f; - idVec2 v2min, v2max, v2min2, v2max2; - idVec3 vmin, vmax, vmin2, vmax2; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - v2src0[i][0] = srnd.CRandomFloat() * 10.0f; - v2src0[i][1] = srnd.CRandomFloat() * 10.0f; - v3src0[i][0] = srnd.CRandomFloat() * 10.0f; - v3src0[i][1] = srnd.CRandomFloat() * 10.0f; - v3src0[i][2] = srnd.CRandomFloat() * 10.0f; - drawVerts[i].xyz = v3src0[i]; - indexes[i] = i; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - min = idMath::INFINITY; - max = -idMath::INFINITY; - StartRecordTime( start ); - p_generic->MinMax( min, max, fsrc0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MinMax( float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->MinMax( min2, max2, fsrc0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = ( min == min2 && max == max2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MinMax( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->MinMax( v2min, v2max, v2src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MinMax( idVec2[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->MinMax( v2min2, v2max2, v2src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = ( v2min == v2min2 && v2max == v2max2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MinMax( idVec2[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->MinMax( vmin, vmax, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MinMax( idVec3[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->MinMax( vmin2, vmax2, v3src0, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MinMax( idVec3[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->MinMax( vmin, vmax, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MinMax( idDrawVert[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->MinMax( vmin2, vmax2, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MinMax( idDrawVert[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->MinMax( vmin, vmax, drawVerts, indexes, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MinMax( idDrawVert[], indexes[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->MinMax( vmin2, vmax2, drawVerts, indexes, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = ( vmin == vmin2 && vmax == vmax2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MinMax( idDrawVert[], indexes[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestClamp -============ -*/ -void TestClamp( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fdst0[COUNT] ); - ALIGN16( float fdst1[COUNT] ); - ALIGN16( float fsrc0[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->Clamp( fdst0, fsrc0, -1.0f, 1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Clamp( float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->Clamp( fdst1, fsrc0, -1.0f, 1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( fdst0[i] != fdst1[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Clamp( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->ClampMin( fdst0, fsrc0, -1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->ClampMin( float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->ClampMin( fdst1, fsrc0, -1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( fdst0[i] != fdst1[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->ClampMin( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->ClampMax( fdst0, fsrc0, 1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->ClampMax( float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->ClampMax( fdst1, fsrc0, 1.0f, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( fdst0[i] != fdst1[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->ClampMax( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestMemcpy -============ -*/ -void TestMemcpy( void ) { - int i, j; - byte test0[8192]; - byte test1[8192]; - - idRandom random( RANDOM_SEED ); - - idLib::common->Printf("====================================\n" ); - - for ( i = 5; i < 8192; i += 31 ) { - for ( j = 0; j < i; j++ ) { - test0[j] = random.RandomInt( 255 ); - } - p_simd->Memcpy( test1, test0, 8192 ); - for ( j = 0; j < i; j++ ) { - if ( test1[j] != test0[j] ) { - idLib::common->Printf( " simd->Memcpy() "S_COLOR_RED"X\n" ); - return; - } - } - } - idLib::common->Printf( " simd->Memcpy() ok\n" ); -} - -/* -============ -TestMemset -============ -*/ -void TestMemset( void ) { - int i, j, k; - byte test[8192]; - - for ( i = 0; i < 8192; i++ ) { - test[i] = 0; - } - - for ( i = 5; i < 8192; i += 31 ) { - for ( j = -1; j <= 1; j++ ) { - p_simd->Memset( test, j, i ); - for ( k = 0; k < i; k++ ) { - if ( test[k] != (byte)j ) { - idLib::common->Printf( " simd->Memset() "S_COLOR_RED"X\n" ); - return; - } - } - } - } - idLib::common->Printf( " simd->Memset() ok\n" ); -} - -#define MATX_SIMD_EPSILON 1e-5f - -/* -============ -TestMatXMultiplyVecX -============ -*/ -void TestMatXMultiplyVecX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX mat; - idVecX src(6); - idVecX dst(6); - idVecX tst(6); - - src[0] = 1.0f; - src[1] = 2.0f; - src[2] = 3.0f; - src[3] = 4.0f; - src[4] = 5.0f; - src[5] = 6.0f; - - idLib::common->Printf("================= NxN * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyVecX %dx%d*%dx1", i, i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyVecX %dx%d*%dx1 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= Nx6 * 6x1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyVecX %dx6*6x1", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyVecX %dx6*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyVecX 6x%d*%dx1", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_MultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyVecX 6x%d*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXMultiplyAddVecX -============ -*/ -void TestMatXMultiplyAddVecX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX mat; - idVecX src(6); - idVecX dst(6); - idVecX tst(6); - - src[0] = 1.0f; - src[1] = 2.0f; - src[2] = 3.0f; - src[3] = 4.0f; - src[4] = 5.0f; - src[5] = 6.0f; - - idLib::common->Printf("================= NxN * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyAddVecX %dx%d*%dx1", i, i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyAddVecX %dx%d*%dx1 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= Nx6 * 6x1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyAddVecX %dx6*6x1", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyAddVecX %dx6*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyAddVecX 6x%d*%dx1", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_MultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyAddVecX 6x%d*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXTransposeMultiplyVecX -============ -*/ -void TestMatXTransposeMultiplyVecX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX mat; - idVecX src(6); - idVecX dst(6); - idVecX tst(6); - - src[0] = 1.0f; - src[1] = 2.0f; - src[2] = 3.0f; - src[3] = 4.0f; - src[4] = 5.0f; - src[5] = 6.0f; - - idLib::common->Printf("================= Nx6 * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransposeMulVecX %dx6*%dx1", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransposeMulVecX %dx6*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * 6x1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransposeMulVecX 6x%d*6x1", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransposeMulVecX 6x%d*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXTransposeMultiplyAddVecX -============ -*/ -void TestMatXTransposeMultiplyAddVecX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX mat; - idVecX src(6); - idVecX dst(6); - idVecX tst(6); - - src[0] = 1.0f; - src[1] = 2.0f; - src[2] = 3.0f; - src[3] = 4.0f; - src[4] = 5.0f; - src[5] = 6.0f; - - idLib::common->Printf("================= Nx6 * Nx1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( i, 6, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransposeMulAddVecX %dx6*%dx1", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransposeMulAddVecX %dx6*%dx1 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * 6x1 ===================\n" ); - - for ( i = 1; i <= 6; i++ ) { - mat.Random( 6, i, RANDOM_SEED, -10.0f, 10.0f ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransposeMulAddVecX 6x%d*6x1", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - dst.Zero(); - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyAddVecX( dst, mat, src ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransposeMulAddVecX 6x%d*6x1 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXMultiplyMatX -============ -*/ -#define TEST_VALUE_RANGE 10.0f -#define MATX_MATX_SIMD_EPSILON 1e-4f - -void TestMatXMultiplyMatX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX m1, m2, dst, tst; - - idLib::common->Printf("================= NxN * Nx6 ===================\n" ); - - // NxN * Nx6 - for ( i = 1; i <= 5; i++ ) { - m1.Random( i, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( i, 6 ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyMatX %dx%d*%dx6", i, i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyMatX %dx%d*%dx6 %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * Nx6 ===================\n" ); - - // 6xN * Nx6 - for ( i = 1; i <= 5; i++ ) { - m1.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( 6, 6 ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyMatX 6x%d*%dx6", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyMatX 6x%d*%dx6 %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= Nx6 * 6xN ===================\n" ); - - // Nx6 * 6xN - for ( i = 1; i <= 5; i++ ) { - m1.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( i, i ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyMatX %dx6*6x%d", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyMatX %dx6*6x%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6x6 * 6xN ===================\n" ); - - // 6x6 * 6xN - for ( i = 1; i <= 6; i++ ) { - m1.Random( 6, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( 6, i ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_MultiplyMatX 6x6*6x%d", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_MultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_MultiplyMatX 6x6*6x%d %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXTransposeMultiplyMatX -============ -*/ -void TestMatXTransposeMultiplyMatX( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX m1, m2, dst, tst; - - idLib::common->Printf("================= Nx6 * NxN ===================\n" ); - - // Nx6 * NxN - for ( i = 1; i <= 5; i++ ) { - m1.Random( i, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( i, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( 6, i ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransMultiplyMatX %dx6*%dx%d", i, i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransMultiplyMatX %dx6*%dx%d %s", i, i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } - - idLib::common->Printf("================= 6xN * 6x6 ===================\n" ); - - // 6xN * 6x6 - for ( i = 1; i <= 6; i++ ) { - m1.Random( 6, i, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - m2.Random( 6, 6, RANDOM_SEED, -TEST_VALUE_RANGE, TEST_VALUE_RANGE ); - dst.SetSize( i, 6 ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_TransposeMultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = dst; - - PrintClocks( va( "generic->MatX_TransMultiplyMatX 6x%d*6x6", i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_TransposeMultiplyMatX( dst, m1, m2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = dst.Compare( tst, MATX_MATX_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_TransMultiplyMatX 6x%d*6x6 %s", i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -#define MATX_LTS_SIMD_EPSILON 1.0f -#define MATX_LTS_SOLVE_SIZE 100 - -/* -============ -TestMatXLowerTriangularSolve -============ -*/ -void TestMatXLowerTriangularSolve( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX L; - idVecX x, b, tst; - - idLib::common->Printf("====================================\n" ); - - L.Random( MATX_LTS_SOLVE_SIZE, MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); - x.SetSize( MATX_LTS_SOLVE_SIZE ); - b.Random( MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); - - for ( i = 1; i < MATX_LTS_SOLVE_SIZE; i++ ) { - - x.Zero( i ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_LowerTriangularSolve( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = x; - x.Zero(); - - PrintClocks( va( "generic->MatX_LowerTriangularSolve %dx%d", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_LowerTriangularSolve( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = x.Compare( tst, MATX_LTS_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_LowerTriangularSolve %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestMatXLowerTriangularSolveTranspose -============ -*/ -void TestMatXLowerTriangularSolveTranspose( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX L; - idVecX x, b, tst; - - idLib::common->Printf("====================================\n" ); - - L.Random( MATX_LTS_SOLVE_SIZE, MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); - x.SetSize( MATX_LTS_SOLVE_SIZE ); - b.Random( MATX_LTS_SOLVE_SIZE, 0, -1.0f, 1.0f ); - - for ( i = 1; i < MATX_LTS_SOLVE_SIZE; i++ ) { - - x.Zero( i ); - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_generic->MatX_LowerTriangularSolveTranspose( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - tst = x; - x.Zero(); - - PrintClocks( va( "generic->MatX_LowerTriangularSolveT %dx%d", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - StartRecordTime( start ); - p_simd->MatX_LowerTriangularSolveTranspose( L, x.ToFloatPtr(), b.ToFloatPtr(), i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = x.Compare( tst, MATX_LTS_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_LowerTriangularSolveT %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -#define MATX_LDLT_SIMD_EPSILON 0.1f -#define MATX_LDLT_FACTOR_SOLVE_SIZE 64 - -/* -============ -TestMatXLDLTFactor -============ -*/ -void TestMatXLDLTFactor( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - const char *result; - idMatX src, original, mat1, mat2; - idVecX invDiag1, invDiag2; - - idLib::common->Printf("====================================\n" ); - - original.SetSize( MATX_LDLT_FACTOR_SOLVE_SIZE, MATX_LDLT_FACTOR_SOLVE_SIZE ); - src.Random( MATX_LDLT_FACTOR_SOLVE_SIZE, MATX_LDLT_FACTOR_SOLVE_SIZE, 0, -1.0f, 1.0f ); - src.TransposeMultiply( original, src ); - - for ( i = 1; i < MATX_LDLT_FACTOR_SOLVE_SIZE; i++ ) { - - bestClocksGeneric = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - mat1 = original; - invDiag1.Zero( MATX_LDLT_FACTOR_SOLVE_SIZE ); - StartRecordTime( start ); - p_generic->MatX_LDLTFactor( mat1, invDiag1, i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - - PrintClocks( va( "generic->MatX_LDLTFactor %dx%d", i, i ), 1, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( j = 0; j < NUMTESTS; j++ ) { - mat2 = original; - invDiag2.Zero( MATX_LDLT_FACTOR_SOLVE_SIZE ); - StartRecordTime( start ); - p_simd->MatX_LDLTFactor( mat2, invDiag2, i ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - result = mat1.Compare( mat2, MATX_LDLT_SIMD_EPSILON ) && invDiag1.Compare( invDiag2, MATX_LDLT_SIMD_EPSILON ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MatX_LDLTFactor %dx%d %s", i, i, result ), 1, bestClocksSIMD, bestClocksGeneric ); - } -} - -/* -============ -TestBlendJoints -============ -*/ -void TestBlendJoints( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idJointQuat baseJoints[COUNT] ); - ALIGN16( idJointQuat joints1[COUNT] ); - ALIGN16( idJointQuat joints2[COUNT] ); - ALIGN16( idJointQuat blendJoints[COUNT] ); - ALIGN16( int index[COUNT] ); - float lerp = 0.3f; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - baseJoints[i].q = angles.ToQuat(); - baseJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; - baseJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; - baseJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - blendJoints[i].q = angles.ToQuat(); - blendJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; - blendJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; - blendJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; - index[i] = i; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < COUNT; j++ ) { - joints1[j] = baseJoints[j]; - } - StartRecordTime( start ); - p_generic->BlendJoints( joints1, blendJoints, lerp, index, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->BlendJoints()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < COUNT; j++ ) { - joints2[j] = baseJoints[j]; - } - StartRecordTime( start ); - p_simd->BlendJoints( joints2, blendJoints, lerp, index, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !joints1[i].t.Compare( joints2[i].t, 1e-3f ) ) { - break; - } - if ( !joints1[i].q.Compare( joints2[i].q, 1e-2f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->BlendJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestConvertJointQuatsToJointMats -============ -*/ -void TestConvertJointQuatsToJointMats( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idJointQuat baseJoints[COUNT] ); - ALIGN16( idJointMat joints1[COUNT] ); - ALIGN16( idJointMat joints2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - baseJoints[i].q = angles.ToQuat(); - baseJoints[i].t[0] = srnd.CRandomFloat() * 10.0f; - baseJoints[i].t[1] = srnd.CRandomFloat() * 10.0f; - baseJoints[i].t[2] = srnd.CRandomFloat() * 10.0f; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->ConvertJointQuatsToJointMats( joints1, baseJoints, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->ConvertJointQuatsToJointMats()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->ConvertJointQuatsToJointMats( joints2, baseJoints, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !joints1[i].Compare( joints2[i], 1e-4f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->ConvertJointQuatsToJointMats() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestConvertJointMatsToJointQuats -============ -*/ -void TestConvertJointMatsToJointQuats( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idJointMat baseJoints[COUNT] ); - ALIGN16( idJointQuat joints1[COUNT] ); - ALIGN16( idJointQuat joints2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - baseJoints[i].SetRotation( angles.ToMat3() ); - idVec3 v; - v[0] = srnd.CRandomFloat() * 10.0f; - v[1] = srnd.CRandomFloat() * 10.0f; - v[2] = srnd.CRandomFloat() * 10.0f; - baseJoints[i].SetTranslation( v ); - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->ConvertJointMatsToJointQuats( joints1, baseJoints, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->ConvertJointMatsToJointQuats()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->ConvertJointMatsToJointQuats( joints2, baseJoints, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !joints1[i].q.Compare( joints2[i].q, 1e-4f ) ) { - idLib::common->Printf("ConvertJointMatsToJointQuats: broken q %i\n", i ); - break; - } - if ( !joints1[i].t.Compare( joints2[i].t, 1e-4f ) ) { - idLib::common->Printf("ConvertJointMatsToJointQuats: broken t %i\n", i ); - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->ConvertJointMatsToJointQuats() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestTransformJoints -============ -*/ -void TestTransformJoints( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idJointMat joints[COUNT+1] ); - ALIGN16( idJointMat joints1[COUNT+1] ); - ALIGN16( idJointMat joints2[COUNT+1] ); - ALIGN16( int parents[COUNT+1] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i <= COUNT; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - joints[i].SetRotation( angles.ToMat3() ); - idVec3 v; - v[0] = srnd.CRandomFloat() * 2.0f; - v[1] = srnd.CRandomFloat() * 2.0f; - v[2] = srnd.CRandomFloat() * 2.0f; - joints[i].SetTranslation( v ); - parents[i] = i - 1; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j <= COUNT; j++ ) { - joints1[j] = joints[j]; - } - StartRecordTime( start ); - p_generic->TransformJoints( joints1, parents, 1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->TransformJoints()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j <= COUNT; j++ ) { - joints2[j] = joints[j]; - } - StartRecordTime( start ); - p_simd->TransformJoints( joints2, parents, 1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !joints1[i+1].Compare( joints2[i+1], 1e-4f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->TransformJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestUntransformJoints -============ -*/ -void TestUntransformJoints( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idJointMat joints[COUNT+1] ); - ALIGN16( idJointMat joints1[COUNT+1] ); - ALIGN16( idJointMat joints2[COUNT+1] ); - ALIGN16( int parents[COUNT+1] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i <= COUNT; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - joints[i].SetRotation( angles.ToMat3() ); - idVec3 v; - v[0] = srnd.CRandomFloat() * 2.0f; - v[1] = srnd.CRandomFloat() * 2.0f; - v[2] = srnd.CRandomFloat() * 2.0f; - joints[i].SetTranslation( v ); - parents[i] = i - 1; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j <= COUNT; j++ ) { - joints1[j] = joints[j]; - } - StartRecordTime( start ); - p_generic->UntransformJoints( joints1, parents, 1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->UntransformJoints()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j <= COUNT; j++ ) { - joints2[j] = joints[j]; - } - StartRecordTime( start ); - p_simd->UntransformJoints( joints2, parents, 1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !joints1[i+1].Compare( joints2[i+1], 1e-4f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->UntransformJoints() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestTransformVerts -============ -*/ -#define NUMJOINTS 64 -#define NUMVERTS COUNT/2 -void TestTransformVerts( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts1[NUMVERTS] ); - ALIGN16( idDrawVert drawVerts2[NUMVERTS] ); - ALIGN16( idJointMat joints[NUMJOINTS] ); - ALIGN16( idVec4 weights[COUNT] ); - ALIGN16( int weightIndex[COUNT*2] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < NUMJOINTS; i++ ) { - idAngles angles; - angles[0] = srnd.CRandomFloat() * 180.0f; - angles[1] = srnd.CRandomFloat() * 180.0f; - angles[2] = srnd.CRandomFloat() * 180.0f; - joints[i].SetRotation( angles.ToMat3() ); - idVec3 v; - v[0] = srnd.CRandomFloat() * 2.0f; - v[1] = srnd.CRandomFloat() * 2.0f; - v[2] = srnd.CRandomFloat() * 2.0f; - joints[i].SetTranslation( v ); - } - - for ( i = 0; i < COUNT; i++ ) { - weights[i][0] = srnd.CRandomFloat() * 2.0f; - weights[i][1] = srnd.CRandomFloat() * 2.0f; - weights[i][2] = srnd.CRandomFloat() * 2.0f; - weights[i][3] = srnd.CRandomFloat(); - weightIndex[i*2+0] = ( i * NUMJOINTS / COUNT ) * sizeof( idJointMat ); - weightIndex[i*2+1] = i & 1; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->TransformVerts( drawVerts1, NUMVERTS, joints, weights, weightIndex, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->TransformVerts()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->TransformVerts( drawVerts2, NUMVERTS, joints, weights, weightIndex, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < NUMVERTS; i++ ) { - if ( !drawVerts1[i].xyz.Compare( drawVerts2[i].xyz, 0.5f ) ) { - break; - } - } - result = ( i >= NUMVERTS ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->TransformVerts() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestTracePointCull -============ -*/ -void TestTracePointCull( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idPlane planes[4] ); - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( byte cullBits1[COUNT] ); - ALIGN16( byte cullBits2[COUNT] ); - byte totalOr1 = 0, totalOr2 = 0; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - planes[0].SetNormal( idVec3( 1, 0, 0 ) ); - planes[1].SetNormal( idVec3( -1, 0, 0 ) ); - planes[2].SetNormal( idVec3( 0, 1, 0 ) ); - planes[3].SetNormal( idVec3( 0, -1, 0 ) ); - planes[0][3] = -5.3f; - planes[1][3] = 5.3f; - planes[2][3] = -3.4f; - planes[3][3] = 3.4f; - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->TracePointCull( cullBits1, totalOr1, 0.0f, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->TracePointCull()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->TracePointCull( cullBits2, totalOr2, 0.0f, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( cullBits1[i] != cullBits2[i] ) { - break; - } - } - result = ( i >= COUNT && totalOr1 == totalOr2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->TracePointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestDecalPointCull -============ -*/ -void TestDecalPointCull( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idPlane planes[6] ); - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( byte cullBits1[COUNT] ); - ALIGN16( byte cullBits2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - planes[0].SetNormal( idVec3( 1, 0, 0 ) ); - planes[1].SetNormal( idVec3( -1, 0, 0 ) ); - planes[2].SetNormal( idVec3( 0, 1, 0 ) ); - planes[3].SetNormal( idVec3( 0, -1, 0 ) ); - planes[4].SetNormal( idVec3( 0, 0, 1 ) ); - planes[5].SetNormal( idVec3( 0, 0, -1 ) ); - planes[0][3] = -5.3f; - planes[1][3] = 5.3f; - planes[2][3] = -4.4f; - planes[3][3] = 4.4f; - planes[4][3] = -3.5f; - planes[5][3] = 3.5f; - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->DecalPointCull( cullBits1, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->DecalPointCull()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->DecalPointCull( cullBits2, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( cullBits1[i] != cullBits2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->DecalPointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestOverlayPointCull -============ -*/ -void TestOverlayPointCull( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idPlane planes[2] ); - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( byte cullBits1[COUNT] ); - ALIGN16( byte cullBits2[COUNT] ); - ALIGN16( idVec2 texCoords1[COUNT] ); - ALIGN16( idVec2 texCoords2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - planes[0].SetNormal( idVec3( 0.3f, 0.2f, 0.9f ) ); - planes[1].SetNormal( idVec3( 0.9f, 0.2f, 0.3f ) ); - planes[0][3] = -5.3f; - planes[1][3] = -4.3f; - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->OverlayPointCull( cullBits1, texCoords1, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->OverlayPointCull()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->OverlayPointCull( cullBits2, texCoords2, planes, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( cullBits1[i] != cullBits2[i] ) { - break; - } - if ( !texCoords1[i].Compare( texCoords2[i], 1e-4f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->OverlayPointCull() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestDeriveTriPlanes -============ -*/ -void TestDeriveTriPlanes( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts1[COUNT] ); - ALIGN16( idDrawVert drawVerts2[COUNT] ); - ALIGN16( idPlane planes1[COUNT] ); - ALIGN16( idPlane planes2[COUNT] ); - ALIGN16( int indexes[COUNT*3] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - for ( j = 0; j < 2; j++ ) { - drawVerts1[i].st[j] = srnd.CRandomFloat(); - } - drawVerts2[i] = drawVerts1[i]; - } - - for ( i = 0; i < COUNT; i++ ) { - indexes[i*3+0] = ( i + 0 ) % COUNT; - indexes[i*3+1] = ( i + 1 ) % COUNT; - indexes[i*3+2] = ( i + 2 ) % COUNT; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->DeriveTriPlanes( planes1, drawVerts1, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->DeriveTriPlanes()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->DeriveTriPlanes( planes2, drawVerts2, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !planes1[i].Compare( planes2[i], 1e-1f, 1e-1f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->DeriveTriPlanes() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestDeriveTangents -============ -*/ -void TestDeriveTangents( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts1[COUNT] ); - ALIGN16( idDrawVert drawVerts2[COUNT] ); - ALIGN16( idPlane planes1[COUNT] ); - ALIGN16( idPlane planes2[COUNT] ); - ALIGN16( int indexes[COUNT*3] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - for ( j = 0; j < 2; j++ ) { - drawVerts1[i].st[j] = srnd.CRandomFloat(); - } - drawVerts2[i] = drawVerts1[i]; - } - - for ( i = 0; i < COUNT; i++ ) { - indexes[i*3+0] = ( i + 0 ) % COUNT; - indexes[i*3+1] = ( i + 1 ) % COUNT; - indexes[i*3+2] = ( i + 2 ) % COUNT; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->DeriveTangents( planes1, drawVerts1, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->DeriveTangents()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->DeriveTangents( planes2, drawVerts2, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - idVec3 v1, v2; - - v1 = drawVerts1[i].normal; - v1.Normalize(); - v2 = drawVerts2[i].normal; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - idLib::common->Printf("DeriveTangents: broken at normal %i\n -- expecting %s got %s", i, v1.ToString(), v2.ToString()); - break; - } - v1 = drawVerts1[i].tangents[0]; - v1.Normalize(); - v2 = drawVerts2[i].tangents[0]; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - idLib::common->Printf("DeriveTangents: broken at tangent0 %i -- expecting %s got %s\n", i, v1.ToString(), v2.ToString() ); - break; - } - v1 = drawVerts1[i].tangents[1]; - v1.Normalize(); - v2 = drawVerts2[i].tangents[1]; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - idLib::common->Printf("DeriveTangents: broken at tangent1 %i -- expecting %s got %s\n", i, v1.ToString(), v2.ToString() ); - break; - } - if ( !planes1[i].Compare( planes2[i], 1e-1f, 1e-1f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->DeriveTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestDeriveUnsmoothedTangents -============ -*/ -void TestDeriveUnsmoothedTangents( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts1[COUNT] ); - ALIGN16( idDrawVert drawVerts2[COUNT] ); - ALIGN16( dominantTri_s dominantTris[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts1[i].xyz[j] = srnd.CRandomFloat() * 10.0f; - } - for ( j = 0; j < 2; j++ ) { - drawVerts1[i].st[j] = srnd.CRandomFloat(); - } - drawVerts2[i] = drawVerts1[i]; - - dominantTris[i].v2 = ( i + 1 + srnd.RandomInt( 8 ) ) % COUNT; - dominantTris[i].v3 = ( i + 9 + srnd.RandomInt( 8 ) ) % COUNT; - dominantTris[i].normalizationScale[0] = srnd.CRandomFloat(); - dominantTris[i].normalizationScale[1] = srnd.CRandomFloat(); - dominantTris[i].normalizationScale[2] = srnd.CRandomFloat(); - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->DeriveUnsmoothedTangents( drawVerts1, dominantTris, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->DeriveUnsmoothedTangents()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->DeriveUnsmoothedTangents( drawVerts2, dominantTris, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - idVec3 v1, v2; - - v1 = drawVerts1[i].normal; - v1.Normalize(); - v2 = drawVerts2[i].normal; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - break; - } - v1 = drawVerts1[i].tangents[0]; - v1.Normalize(); - v2 = drawVerts2[i].tangents[0]; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - break; - } - v1 = drawVerts1[i].tangents[1]; - v1.Normalize(); - v2 = drawVerts2[i].tangents[1]; - v2.Normalize(); - if ( !v1.Compare( v2, 1e-1f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->DeriveUnsmoothedTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestNormalizeTangents -============ -*/ -void TestNormalizeTangents( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts1[COUNT] ); - ALIGN16( idDrawVert drawVerts2[COUNT] ); - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts1[i].normal[j] = srnd.CRandomFloat() * 10.0f; - drawVerts1[i].tangents[0][j] = srnd.CRandomFloat() * 10.0f; - drawVerts1[i].tangents[1][j] = srnd.CRandomFloat() * 10.0f; - } - drawVerts2[i] = drawVerts1[i]; - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->NormalizeTangents( drawVerts1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->NormalizeTangents()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->NormalizeTangents( drawVerts2, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !drawVerts1[i].normal.Compare( drawVerts2[i].normal, 1e-2f ) ) { - break; - } - if ( !drawVerts1[i].tangents[0].Compare( drawVerts2[i].tangents[0], 1e-2f ) ) { - break; - } - if ( !drawVerts1[i].tangents[1].Compare( drawVerts2[i].tangents[1], 1e-2f ) ) { - break; - } - - // since we're doing a lot of unaligned work, added this check to - // make sure xyz wasn't getting overwritten - if ( !drawVerts1[i].xyz.Compare( drawVerts2[i].xyz, 1e-2f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->NormalizeTangents() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestGetTextureSpaceLightVectors -============ -*/ -void TestGetTextureSpaceLightVectors( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( idVec4 texCoords1[COUNT] ); - ALIGN16( idVec4 texCoords2[COUNT] ); - ALIGN16( int indexes[COUNT*3] ); - ALIGN16( idVec3 lightVectors1[COUNT] ); - ALIGN16( idVec3 lightVectors2[COUNT] ); - idVec3 lightOrigin; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts[i].xyz[j] = srnd.CRandomFloat() * 100.0f; - drawVerts[i].normal[j] = srnd.CRandomFloat(); - drawVerts[i].tangents[0][j] = srnd.CRandomFloat(); - drawVerts[i].tangents[1][j] = srnd.CRandomFloat(); - } - } - - for ( i = 0; i < COUNT; i++ ) { - indexes[i*3+0] = ( i + 0 ) % COUNT; - indexes[i*3+1] = ( i + 1 ) % COUNT; - indexes[i*3+2] = ( i + 2 ) % COUNT; - } - - lightOrigin[0] = srnd.CRandomFloat() * 100.0f; - lightOrigin[1] = srnd.CRandomFloat() * 100.0f; - lightOrigin[2] = srnd.CRandomFloat() * 100.0f; - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CreateTextureSpaceLightVectors( lightVectors1, lightOrigin, drawVerts, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CreateTextureSpaceLightVectors()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CreateTextureSpaceLightVectors( lightVectors2, lightOrigin, drawVerts, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !lightVectors1[i].Compare( lightVectors2[i], 1e-4f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CreateTextureSpaceLightVectors() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestGetSpecularTextureCoords -============ -*/ -void TestGetSpecularTextureCoords( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( idVec4 texCoords1[COUNT] ); - ALIGN16( idVec4 texCoords2[COUNT] ); - ALIGN16( int indexes[COUNT*3] ); - ALIGN16( idVec3 lightVectors1[COUNT] ); - ALIGN16( idVec3 lightVectors2[COUNT] ); - idVec3 lightOrigin, viewOrigin; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - for ( j = 0; j < 3; j++ ) { - drawVerts[i].xyz[j] = srnd.CRandomFloat() * 100.0f; - drawVerts[i].normal[j] = srnd.CRandomFloat(); - drawVerts[i].tangents[0][j] = srnd.CRandomFloat(); - drawVerts[i].tangents[1][j] = srnd.CRandomFloat(); - } - } - - for ( i = 0; i < COUNT; i++ ) { - indexes[i*3+0] = ( i + 0 ) % COUNT; - indexes[i*3+1] = ( i + 1 ) % COUNT; - indexes[i*3+2] = ( i + 2 ) % COUNT; - } - - lightOrigin[0] = srnd.CRandomFloat() * 100.0f; - lightOrigin[1] = srnd.CRandomFloat() * 100.0f; - lightOrigin[2] = srnd.CRandomFloat() * 100.0f; - viewOrigin[0] = srnd.CRandomFloat() * 100.0f; - viewOrigin[1] = srnd.CRandomFloat() * 100.0f; - viewOrigin[2] = srnd.CRandomFloat() * 100.0f; - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CreateSpecularTextureCoords( texCoords1, lightOrigin, viewOrigin, drawVerts, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CreateSpecularTextureCoords()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CreateSpecularTextureCoords( texCoords2, lightOrigin, viewOrigin, drawVerts, COUNT, indexes, COUNT*3 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !texCoords1[i].Compare( texCoords2[i], 1e-2f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CreateSpecularTextureCoords() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestCreateShadowCache -============ -*/ -void TestCreateShadowCache( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( idDrawVert drawVerts[COUNT] ); - ALIGN16( idVec4 vertexCache1[COUNT*2] ); - ALIGN16( idVec4 vertexCache2[COUNT*2] ); - ALIGN16( int originalVertRemap[COUNT] ); - ALIGN16( int vertRemap1[COUNT] ); - ALIGN16( int vertRemap2[COUNT] ); - ALIGN16( idVec3 lightOrigin ); - int numVerts1 = 0, numVerts2 = 0; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - drawVerts[i].xyz[0] = srnd.CRandomFloat() * 100.0f; - drawVerts[i].xyz[1] = srnd.CRandomFloat() * 100.0f; - drawVerts[i].xyz[2] = srnd.CRandomFloat() * 100.0f; - originalVertRemap[i] = ( srnd.CRandomFloat() > 0.0f ) ? -1 : 0; - } - lightOrigin[0] = srnd.CRandomFloat() * 100.0f; - lightOrigin[1] = srnd.CRandomFloat() * 100.0f; - lightOrigin[2] = srnd.CRandomFloat() * 100.0f; - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < COUNT; j++ ) { - vertRemap1[j] = originalVertRemap[j]; - } - StartRecordTime( start ); - numVerts1 =p_generic->CreateShadowCache( vertexCache1, vertRemap1, lightOrigin, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CreateShadowCache()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < COUNT; j++ ) { - vertRemap2[j] = originalVertRemap[j]; - } - StartRecordTime( start ); - numVerts2 = p_simd->CreateShadowCache( vertexCache2, vertRemap2, lightOrigin, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( i < ( numVerts1 / 2 ) ) { - if ( !vertexCache1[i*2+0].Compare( vertexCache2[i*2+0], 1e-2f ) ) { - break; - } - if ( !vertexCache1[i*2+1].Compare( vertexCache2[i*2+1], 1e-2f ) ) { - break; - } - } - if ( vertRemap1[i] != vertRemap2[i] ) { - break; - } - } - - result = ( i >= COUNT && numVerts1 == numVerts2 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CreateShadowCache() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->CreateVertexProgramShadowCache( vertexCache1, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->CreateVertexProgramShadowCache()", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->CreateVertexProgramShadowCache( vertexCache2, drawVerts, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( !vertexCache1[i*2+0].Compare( vertexCache2[i*2+0], 1e-2f ) ) { - break; - } - if ( !vertexCache1[i*2+1].Compare( vertexCache2[i*2+1], 1e-2f ) ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->CreateVertexProgramShadowCache() %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestSoundUpSampling -============ -*/ -#define SOUND_UPSAMPLE_EPSILON 1.0f - -void TestSoundUpSampling( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( short pcm[MIXBUFFER_SAMPLES*2] ); - ALIGN16( float ogg0[MIXBUFFER_SAMPLES*2] ); - ALIGN16( float ogg1[MIXBUFFER_SAMPLES*2] ); - ALIGN16( float samples1[MIXBUFFER_SAMPLES*2] ); - ALIGN16( float samples2[MIXBUFFER_SAMPLES*2] ); - float *ogg[2]; - int kHz, numSpeakers; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < MIXBUFFER_SAMPLES*2; i++ ) { - pcm[i] = srnd.RandomInt( (1<<16) ) - (1<<15); - ogg0[i] = srnd.RandomFloat(); - ogg1[i] = srnd.RandomFloat(); - } - - ogg[0] = ogg0; - ogg[1] = ogg1; - - for ( numSpeakers = 1; numSpeakers <= 2; numSpeakers++ ) { - - for ( kHz = 11025; kHz <= 44100; kHz *= 2 ) { - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->UpSamplePCMTo44kHz( samples1, pcm, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( va( "generic->UpSamplePCMTo44kHz( %d, %d )", kHz, numSpeakers ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->UpSamplePCMTo44kHz( samples2, pcm, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*numSpeakers; i++ ) { - if ( idMath::Fabs( samples1[i] - samples2[i] ) > SOUND_UPSAMPLE_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*numSpeakers ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->UpSamplePCMTo44kHz( %d, %d ) %s", kHz, numSpeakers, result ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksSIMD, bestClocksGeneric ); - } - } - - for ( numSpeakers = 1; numSpeakers <= 2; numSpeakers++ ) { - - for ( kHz = 11025; kHz <= 44100; kHz *= 2 ) { - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_generic->UpSampleOGGTo44kHz( samples1, ogg, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( va( "generic->UpSampleOGGTo44kHz( %d, %d )", kHz, numSpeakers ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - p_simd->UpSampleOGGTo44kHz( samples2, ogg, MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, kHz, numSpeakers ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*numSpeakers; i++ ) { - if ( idMath::Fabs( samples1[i] - samples2[i] ) > SOUND_UPSAMPLE_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->UpSampleOGGTo44kHz( %d, %d ) %s", kHz, numSpeakers, result ), MIXBUFFER_SAMPLES*numSpeakers*kHz/44100, bestClocksSIMD, bestClocksGeneric ); - } - } -} - -/* -============ -TestSoundMixing -============ -*/ -#define SOUND_MIX_EPSILON 2.0f - -void TestSoundMixing( void ) { - int i, j; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float origMixBuffer[MIXBUFFER_SAMPLES*6] ); - ALIGN16( float mixBuffer1[MIXBUFFER_SAMPLES*6] ); - ALIGN16( float mixBuffer2[MIXBUFFER_SAMPLES*6] ); - ALIGN16( float samples[MIXBUFFER_SAMPLES*6] ); - ALIGN16( short outSamples1[MIXBUFFER_SAMPLES*6] ); - ALIGN16( short outSamples2[MIXBUFFER_SAMPLES*6] ); - float lastV[6]; - float currentV[6]; - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < 6; i++ ) { - lastV[i] = srnd.CRandomFloat(); - currentV[i] = srnd.CRandomFloat(); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - origMixBuffer[i] = srnd.CRandomFloat(); - samples[i] = srnd.RandomInt( (1<<16) ) - (1<<15); - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer1[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_generic->MixSoundTwoSpeakerMono( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MixSoundTwoSpeakerMono()", MIXBUFFER_SAMPLES, bestClocksGeneric ); - - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer2[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_simd->MixSoundTwoSpeakerMono( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MixSoundTwoSpeakerMono() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer1[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_generic->MixSoundTwoSpeakerStereo( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MixSoundTwoSpeakerStereo()", MIXBUFFER_SAMPLES, bestClocksGeneric ); - - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer2[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_simd->MixSoundTwoSpeakerStereo( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MixSoundTwoSpeakerStereo() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); - - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer1[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_generic->MixSoundSixSpeakerMono( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MixSoundSixSpeakerMono()", MIXBUFFER_SAMPLES, bestClocksGeneric ); - - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer2[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_simd->MixSoundSixSpeakerMono( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MixSoundSixSpeakerMono() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer1[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_generic->MixSoundSixSpeakerStereo( mixBuffer1, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MixSoundSixSpeakerStereo()", MIXBUFFER_SAMPLES, bestClocksGeneric ); - - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer2[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_simd->MixSoundSixSpeakerStereo( mixBuffer2, samples, MIXBUFFER_SAMPLES, lastV, currentV ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - if ( idMath::Fabs( mixBuffer1[i] - mixBuffer2[i] ) > SOUND_MIX_EPSILON ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MixSoundSixSpeakerStereo() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); - - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - origMixBuffer[i] = srnd.RandomInt( (1<<17) ) - (1<<16); - } - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer1[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_generic->MixedSoundToSamples( outSamples1, mixBuffer1, MIXBUFFER_SAMPLES*6 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->MixedSoundToSamples()", MIXBUFFER_SAMPLES, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - for ( j = 0; j < MIXBUFFER_SAMPLES*6; j++ ) { - mixBuffer2[j] = origMixBuffer[j]; - } - StartRecordTime( start ); - p_simd->MixedSoundToSamples( outSamples2, mixBuffer2, MIXBUFFER_SAMPLES*6 ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < MIXBUFFER_SAMPLES*6; i++ ) { - if ( outSamples1[i] != outSamples2[i] ) { - break; - } - } - result = ( i >= MIXBUFFER_SAMPLES*6 ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->MixedSoundToSamples() %s", result ), MIXBUFFER_SAMPLES, bestClocksSIMD, bestClocksGeneric ); -} - -/* -============ -TestMath -============ -*/ -void TestMath( void ) { - int i; - TIME_TYPE start, end, bestClocks; - - idLib::common->Printf("====================================\n" ); - - float tst = -1.0f; - float tst2 = 1.0f; - float testvar = 1.0f; - idRandom rnd; - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = fabs( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " fabs( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - int tmp = * ( int * ) &tst; - tmp &= 0x7FFFFFFF; - tst = * ( float * ) &tmp; - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Fabs( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = 10.0f + 100.0f * rnd.RandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = sqrt( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * 0.01f; - tst = 10.0f + 100.0f * rnd.RandomFloat(); - } - PrintClocks( " sqrt( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.RandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Sqrt( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.RandomFloat(); - } - PrintClocks( " idMath::Sqrt( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.RandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Sqrt16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.RandomFloat(); - } - PrintClocks( " idMath::Sqrt16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.RandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Sqrt64( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.RandomFloat(); - } - PrintClocks( " idMath::Sqrt64( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.RandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = tst * idMath::RSqrt( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.RandomFloat(); - } - PrintClocks( " idMath::RSqrt( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Sin( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Sin( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Sin16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Sin16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Cos( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Cos( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Cos16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Cos16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - idMath::SinCos( tst, tst, tst2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::SinCos( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - idMath::SinCos16( tst, tst, tst2 ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( "idMath::SinCos16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Tan( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Tan( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Tan16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Tan16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ASin( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ASin( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ASin16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ASin16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ACos( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ACos( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ACos16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI ); - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ACos16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ATan( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ATan( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::ATan16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::ATan16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Pow( 2.7f, tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * 0.1f; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Pow( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Pow16( 2.7f, tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * 0.1f; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Pow16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Exp( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * 0.1f; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Exp( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - tst = idMath::Exp16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst * 0.1f; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Exp16( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - tst = fabs( tst ) + 1.0f; - StartRecordTime( start ); - tst = idMath::Log( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Log( tst )", 1, bestClocks ); - - bestClocks = 0; - tst = rnd.CRandomFloat(); - for ( i = 0; i < NUMTESTS; i++ ) { - tst = fabs( tst ) + 1.0f; - StartRecordTime( start ); - tst = idMath::Log16( tst ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - testvar = ( testvar + tst ) * tst; - tst = rnd.CRandomFloat(); - } - PrintClocks( " idMath::Log16( tst )", 1, bestClocks ); - - idLib::common->Printf( "testvar = %f\n", testvar ); - - idMat3 resultMat3; - idQuat fromQuat, toQuat, resultQuat; - idCQuat cq; - idAngles ang; - - fromQuat = idAngles( 30, 45, 0 ).ToQuat(); - toQuat = idAngles( 45, 0, 0 ).ToQuat(); - cq = idAngles( 30, 45, 0 ).ToQuat().ToCQuat(); - ang = idAngles( 30, 40, 50 ); - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - resultMat3 = fromQuat.ToMat3(); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - PrintClocks( " idQuat::ToMat3()", 1, bestClocks ); - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - resultQuat.Slerp( fromQuat, toQuat, 0.3f ); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - PrintClocks( " idQuat::Slerp()", 1, bestClocks ); - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - resultQuat = cq.ToQuat(); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - PrintClocks( " idCQuat::ToQuat()", 1, bestClocks ); - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - resultQuat = ang.ToQuat(); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - PrintClocks( " idAngles::ToQuat()", 1, bestClocks ); - - bestClocks = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - StartRecordTime( start ); - resultMat3 = ang.ToMat3(); - StopRecordTime( end ); - GetBest( start, end, bestClocks ); - } - PrintClocks( " idAngles::ToMat3()", 1, bestClocks ); -} - -/* -============ -TestNegate -============ -*/ - -// this wasn't previously in the test -void TestNegate( void ) { - int i; - TIME_TYPE start, end, bestClocksGeneric, bestClocksSIMD; - ALIGN16( float fsrc0[COUNT] ); - ALIGN16( float fsrc1[COUNT] ); - ALIGN16( float fsrc2[COUNT] ); - - const char *result; - - idRandom srnd( RANDOM_SEED ); - - for ( i = 0; i < COUNT; i++ ) { - fsrc0[i] = fsrc1[i] = fsrc2[i] = srnd.CRandomFloat() * 10.0f; - //fsrc1[i] = srnd.CRandomFloat() * 10.0f; - } - - idLib::common->Printf("====================================\n" ); - - bestClocksGeneric = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - - memcpy( &fsrc1[0], &fsrc0[0], COUNT * sizeof(float) ); - - StartRecordTime( start ); - p_generic->Negate16( fsrc1, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksGeneric ); - } - PrintClocks( "generic->Negate16( float[] )", COUNT, bestClocksGeneric ); - - bestClocksSIMD = 0; - for ( i = 0; i < NUMTESTS; i++ ) { - - memcpy( &fsrc2[0], &fsrc0[0], COUNT * sizeof(float) ); - - StartRecordTime( start ); - p_simd->Negate16( fsrc2, COUNT ); - StopRecordTime( end ); - GetBest( start, end, bestClocksSIMD ); - } - - for ( i = 0; i < COUNT; i++ ) { - if ( fsrc1[i] != fsrc2[i] ) { - break; - } - } - result = ( i >= COUNT ) ? "ok" : S_COLOR_RED"X"; - PrintClocks( va( " simd->Negate16( float[] ) %s", result ), COUNT, bestClocksSIMD, bestClocksGeneric ); -} - - -/* -============ -idSIMD::Test_f -============ -*/ -void idSIMD::Test_f( const idCmdArgs &args ) { - -#ifdef _WIN32 - SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); -#endif /* _WIN32 */ - - p_simd = processor; - p_generic = generic; - - if ( idStr::Length( args.Argv( 1 ) ) != 0 ) { - cpuid_t cpuid = idLib::sys->GetProcessorId(); - idStr argString = args.Args(); - - argString.Replace( " ", "" ); - - if ( idStr::Icmp( argString, "MMX" ) == 0 ) { - if ( !( cpuid & CPUID_MMX ) ) { - common->Printf( "CPU does not support MMX\n" ); - return; - } - p_simd = new idSIMD_MMX; - } else if ( idStr::Icmp( argString, "3DNow" ) == 0 ) { - if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_3DNOW ) ) { - common->Printf( "CPU does not support MMX & 3DNow\n" ); - return; - } - p_simd = new idSIMD_3DNow; - } else if ( idStr::Icmp( argString, "SSE" ) == 0 ) { - if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) ) { - common->Printf( "CPU does not support MMX & SSE\n" ); - return; - } - p_simd = new idSIMD_SSE; - } else if ( idStr::Icmp( argString, "SSE2" ) == 0 ) { - if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) || !( cpuid & CPUID_SSE2 ) ) { - common->Printf( "CPU does not support MMX & SSE & SSE2\n" ); - return; - } - p_simd = new idSIMD_SSE2; - } else if ( idStr::Icmp( argString, "SSE3" ) == 0 ) { - if ( !( cpuid & CPUID_MMX ) || !( cpuid & CPUID_SSE ) || !( cpuid & CPUID_SSE2 ) || !( cpuid & CPUID_SSE3 ) ) { - common->Printf( "CPU does not support MMX & SSE & SSE2 & SSE3\n" ); - return; - } - p_simd = new idSIMD_SSE3(); - } else if ( idStr::Icmp( argString, "AltiVec" ) == 0 ) { - if ( !( cpuid & CPUID_ALTIVEC ) ) { - common->Printf( "CPU does not support AltiVec\n" ); - return; - } - p_simd = new idSIMD_AltiVec(); - } else { - common->Printf( "invalid argument, use: MMX, 3DNow, SSE, SSE2, SSE3, AltiVec\n" ); - return; - } - } - - idLib::common->SetRefreshOnPrint( true ); - - idLib::common->Printf( "using %s for SIMD processing\n", p_simd->GetName() ); - - GetBaseClocks(); - - TestMath(); - TestAdd(); - TestSub(); - TestMul(); - TestDiv(); - TestMulAdd(); - TestMulSub(); - TestDot(); - TestCompare(); - TestMinMax(); - TestClamp(); - TestMemcpy(); - TestMemset(); - TestNegate(); - - TestMatXMultiplyVecX(); - TestMatXMultiplyAddVecX(); - TestMatXTransposeMultiplyVecX(); - TestMatXTransposeMultiplyAddVecX(); - TestMatXMultiplyMatX(); - TestMatXTransposeMultiplyMatX(); - TestMatXLowerTriangularSolve(); - TestMatXLowerTriangularSolveTranspose(); - TestMatXLDLTFactor(); - - idLib::common->Printf("====================================\n" ); - - TestBlendJoints(); - TestConvertJointQuatsToJointMats(); - TestConvertJointMatsToJointQuats(); - TestTransformJoints(); - TestUntransformJoints(); - TestTransformVerts(); - TestTracePointCull(); - TestDecalPointCull(); - TestOverlayPointCull(); - TestDeriveTriPlanes(); - TestDeriveTangents(); - TestDeriveUnsmoothedTangents(); - TestNormalizeTangents(); - TestGetTextureSpaceLightVectors(); - TestGetSpecularTextureCoords(); - TestCreateShadowCache(); - - idLib::common->Printf("====================================\n" ); - - TestSoundUpSampling(); - TestSoundMixing(); - - idLib::common->SetRefreshOnPrint( false ); - - if ( p_simd != processor ) { - delete p_simd; - } - p_simd = NULL; - p_generic = NULL; - -#ifdef _WIN32 - SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL ); -#endif /* _WIN32 */ -} diff --git a/idlib/math/simd.h b/idlib/math/simd.h deleted file mode 100644 index 7f6d9dd79..000000000 --- a/idlib/math/simd.h +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_H__ -#define __MATH_SIMD_H__ - -/* -=============================================================================== - - Single Instruction Multiple Data (SIMD) - - For optimal use data should be aligned on a 16 byte boundary. - All idSIMDProcessor routines are thread safe. - -=============================================================================== -*/ - -class idSIMD { -public: - static void Init( void ); - static void InitProcessor( const char *module, bool forceGeneric ); - static void Shutdown( void ); - static void Test_f( const class idCmdArgs &args ); -}; - - -/* -=============================================================================== - - virtual base class for different SIMD processors - -=============================================================================== -*/ - -#ifdef _WIN32 -#define VPCALL __fastcall -#else -#define VPCALL -#endif - -class idVec2; -class idVec3; -class idVec4; -class idVec5; -class idVec6; -class idVecX; -class idMat2; -class idMat3; -class idMat4; -class idMat5; -class idMat6; -class idMatX; -class idPlane; -class idDrawVert; -class idJointQuat; -class idJointMat; -struct dominantTri_s; - -const int MIXBUFFER_SAMPLES = 4096; - -typedef enum { - SPEAKER_LEFT = 0, - SPEAKER_RIGHT, - SPEAKER_CENTER, - SPEAKER_LFE, - SPEAKER_BACKLEFT, - SPEAKER_BACKRIGHT -} speakerLabel; - - -class idSIMDProcessor { -public: - idSIMDProcessor( void ) { cpuid = CPUID_NONE; } - - cpuid_t cpuid; - - virtual const char * VPCALL GetName( void ) const = 0; - - virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ) = 0; - virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ) = 0; - virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ) = 0; - virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ) = 0; - virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ) = 0; - virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ) = 0; - virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ) = 0; - - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ) = 0; - virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) = 0; - virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ) = 0; - - virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ) = 0; - virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) = 0; - - virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ) = 0; - virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) = 0; - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) = 0; - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) = 0; - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) = 0; - - virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ) = 0; - virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ) = 0; - virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ) = 0; - - virtual void VPCALL Memcpy( void *dst, const void *src, const int count ) = 0; - virtual void VPCALL Memset( void *dst, const int val, const int count ) = 0; - - // these assume 16 byte aligned and 16 byte padded memory - virtual void VPCALL Zero16( float *dst, const int count ) = 0; - virtual void VPCALL Negate16( float *dst, const int count ) = 0; - virtual void VPCALL Copy16( float *dst, const float *src, const int count ) = 0; - virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ) = 0; - virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ) = 0; - virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ) = 0; - virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ) = 0; - virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ) = 0; - virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ) = 0; - - // idMatX operations - virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) = 0; - virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) = 0; - virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) = 0; - virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ) = 0; - virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) = 0; - virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) = 0; - - // rendering - virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) = 0; - virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) = 0; - virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) = 0; - virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) = 0; - virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) = 0; - virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) = 0; - virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; - virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; - virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) = 0; - virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; - virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; - virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) = 0; - virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ) = 0; - virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; - virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) = 0; - virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) = 0; - virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) = 0; - - // sound mixing - virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ) = 0; - virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) = 0; - virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) = 0; - virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) = 0; - virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) = 0; - virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) = 0; - virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) = 0; -}; - -// pointer to SIMD processor -extern idSIMDProcessor *SIMDProcessor; - -#endif /* !__MATH_SIMD_H__ */ diff --git a/idlib/math/simd_3dnow.cpp b/idlib/math/simd_3dnow.cpp deleted file mode 100644 index f90781098..000000000 --- a/idlib/math/simd_3dnow.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "Simd_Generic.h" -#include "Simd_MMX.h" -#include "Simd_3DNow.h" - - -//=============================================================== -// -// 3DNow! implementation of idSIMDProcessor -// -//=============================================================== - -#ifdef _WIN32 - -/* -============ -idSIMD_3DNow::GetName -============ -*/ -const char * idSIMD_3DNow::GetName( void ) const { - return "MMX & 3DNow!"; -} - -// Very optimized memcpy() routine for all AMD Athlon and Duron family. -// This code uses any of FOUR different basic copy methods, depending -// on the transfer size. -// NOTE: Since this code uses MOVNTQ (also known as "Non-Temporal MOV" or -// "Streaming Store"), and also uses the software prefetchnta instructions, -// be sure you're running on Athlon/Duron or other recent CPU before calling! - -#define TINY_BLOCK_COPY 64 // upper limit for movsd type copy -// The smallest copy uses the X86 "movsd" instruction, in an optimized -// form which is an "unrolled loop". - -#define IN_CACHE_COPY 64 * 1024 // upper limit for movq/movq copy w/SW prefetch -// Next is a copy that uses the MMX registers to copy 8 bytes at a time, -// also using the "unrolled loop" optimization. This code uses -// the software prefetch instruction to get the data into the cache. - -#define UNCACHED_COPY 197 * 1024 // upper limit for movq/movntq w/SW prefetch -// For larger blocks, which will spill beyond the cache, it's faster to -// use the Streaming Store instruction MOVNTQ. This write instruction -// bypasses the cache and writes straight to main memory. This code also -// uses the software prefetch instruction to pre-read the data. -// USE 64 * 1024 FOR THIS VALUE IF YOU'RE ALWAYS FILLING A "CLEAN CACHE" - -#define BLOCK_PREFETCH_COPY infinity // no limit for movq/movntq w/block prefetch -#define CACHEBLOCK 80h // number of 64-byte blocks (cache lines) for block prefetch -// For the largest size blocks, a special technique called Block Prefetch -// can be used to accelerate the read operations. Block Prefetch reads -// one address per cache line, for a series of cache lines, in a short loop. -// This is faster than using software prefetch. The technique is great for -// getting maximum read bandwidth, especially in DDR memory systems. - -/* -================ -idSIMD_3DNow::Memcpy - - optimized memory copy routine that handles all alignment cases and block sizes efficiently -================ -*/ -void VPCALL idSIMD_3DNow::Memcpy( void *dest, const void *src, const int n ) { - __asm { - - mov ecx, [n] // number of bytes to copy - mov edi, [dest] // destination - mov esi, [src] // source - mov ebx, ecx // keep a copy of count - - cld - cmp ecx, TINY_BLOCK_COPY - jb $memcpy_ic_3 // tiny? skip mmx copy - - cmp ecx, 32*1024 // don't align between 32k-64k because - jbe $memcpy_do_align // it appears to be slower - cmp ecx, 64*1024 - jbe $memcpy_align_done -$memcpy_do_align: - mov ecx, 8 // a trick that's faster than rep movsb... - sub ecx, edi // align destination to qword - and ecx, 111b // get the low bits - sub ebx, ecx // update copy count - neg ecx // set up to jump into the array - add ecx, offset $memcpy_align_done - jmp ecx // jump to array of movsb's - -align 4 - movsb - movsb - movsb - movsb - movsb - movsb - movsb - movsb - -$memcpy_align_done: // destination is dword aligned - mov ecx, ebx // number of bytes left to copy - shr ecx, 6 // get 64-byte block count - jz $memcpy_ic_2 // finish the last few bytes - - cmp ecx, IN_CACHE_COPY/64 // too big 4 cache? use uncached copy - jae $memcpy_uc_test - -// This is small block copy that uses the MMX registers to copy 8 bytes -// at a time. It uses the "unrolled loop" optimization, and also uses -// the software prefetch instruction to get the data into the cache. -align 16 -$memcpy_ic_1: // 64-byte block copies, in-cache copy - - prefetchnta [esi + (200*64/34+192)] // start reading ahead - - movq mm0, [esi+0] // read 64 bits - movq mm1, [esi+8] - movq [edi+0], mm0 // write 64 bits - movq [edi+8], mm1 // note: the normal movq writes the - movq mm2, [esi+16] // data to cache; a cache line will be - movq mm3, [esi+24] // allocated as needed, to store the data - movq [edi+16], mm2 - movq [edi+24], mm3 - movq mm0, [esi+32] - movq mm1, [esi+40] - movq [edi+32], mm0 - movq [edi+40], mm1 - movq mm2, [esi+48] - movq mm3, [esi+56] - movq [edi+48], mm2 - movq [edi+56], mm3 - - add esi, 64 // update source pointer - add edi, 64 // update destination pointer - dec ecx // count down - jnz $memcpy_ic_1 // last 64-byte block? - -$memcpy_ic_2: - mov ecx, ebx // has valid low 6 bits of the byte count -$memcpy_ic_3: - shr ecx, 2 // dword count - and ecx, 1111b // only look at the "remainder" bits - neg ecx // set up to jump into the array - add ecx, offset $memcpy_last_few - jmp ecx // jump to array of movsd's - -$memcpy_uc_test: - cmp ecx, UNCACHED_COPY/64 // big enough? use block prefetch copy - jae $memcpy_bp_1 - -$memcpy_64_test: - or ecx, ecx // tail end of block prefetch will jump here - jz $memcpy_ic_2 // no more 64-byte blocks left - -// For larger blocks, which will spill beyond the cache, it's faster to -// use the Streaming Store instruction MOVNTQ. This write instruction -// bypasses the cache and writes straight to main memory. This code also -// uses the software prefetch instruction to pre-read the data. -align 16 -$memcpy_uc_1: // 64-byte blocks, uncached copy - - prefetchnta [esi + (200*64/34+192)] // start reading ahead - - movq mm0,[esi+0] // read 64 bits - add edi,64 // update destination pointer - movq mm1,[esi+8] - add esi,64 // update source pointer - movq mm2,[esi-48] - movntq [edi-64], mm0 // write 64 bits, bypassing the cache - movq mm0,[esi-40] // note: movntq also prevents the CPU - movntq [edi-56], mm1 // from READING the destination address - movq mm1,[esi-32] // into the cache, only to be over-written - movntq [edi-48], mm2 // so that also helps performance - movq mm2,[esi-24] - movntq [edi-40], mm0 - movq mm0,[esi-16] - movntq [edi-32], mm1 - movq mm1,[esi-8] - movntq [edi-24], mm2 - movntq [edi-16], mm0 - dec ecx - movntq [edi-8], mm1 - jnz $memcpy_uc_1 // last 64-byte block? - - jmp $memcpy_ic_2 // almost done - -// For the largest size blocks, a special technique called Block Prefetch -// can be used to accelerate the read operations. Block Prefetch reads -// one address per cache line, for a series of cache lines, in a short loop. -// This is faster than using software prefetch, in this case. -// The technique is great for getting maximum read bandwidth, -// especially in DDR memory systems. -$memcpy_bp_1: // large blocks, block prefetch copy - - cmp ecx, CACHEBLOCK // big enough to run another prefetch loop? - jl $memcpy_64_test // no, back to regular uncached copy - - mov eax, CACHEBLOCK / 2 // block prefetch loop, unrolled 2X - add esi, CACHEBLOCK * 64 // move to the top of the block -align 16 -$memcpy_bp_2: - mov edx, [esi-64] // grab one address per cache line - mov edx, [esi-128] // grab one address per cache line - sub esi, 128 // go reverse order - dec eax // count down the cache lines - jnz $memcpy_bp_2 // keep grabbing more lines into cache - - mov eax, CACHEBLOCK // now that it's in cache, do the copy -align 16 -$memcpy_bp_3: - movq mm0, [esi ] // read 64 bits - movq mm1, [esi+ 8] - movq mm2, [esi+16] - movq mm3, [esi+24] - movq mm4, [esi+32] - movq mm5, [esi+40] - movq mm6, [esi+48] - movq mm7, [esi+56] - add esi, 64 // update source pointer - movntq [edi ], mm0 // write 64 bits, bypassing cache - movntq [edi+ 8], mm1 // note: movntq also prevents the CPU - movntq [edi+16], mm2 // from READING the destination address - movntq [edi+24], mm3 // into the cache, only to be over-written, - movntq [edi+32], mm4 // so that also helps performance - movntq [edi+40], mm5 - movntq [edi+48], mm6 - movntq [edi+56], mm7 - add edi, 64 // update dest pointer - - dec eax // count down - - jnz $memcpy_bp_3 // keep copying - sub ecx, CACHEBLOCK // update the 64-byte block count - jmp $memcpy_bp_1 // keep processing chunks - -// The smallest copy uses the X86 "movsd" instruction, in an optimized -// form which is an "unrolled loop". Then it handles the last few bytes. -align 4 - movsd - movsd // perform last 1-15 dword copies - movsd - movsd - movsd - movsd - movsd - movsd - movsd - movsd // perform last 1-7 dword copies - movsd - movsd - movsd - movsd - movsd - movsd - -$memcpy_last_few: // dword aligned from before movsd's - mov ecx, ebx // has valid low 2 bits of the byte count - and ecx, 11b // the last few cows must come home - jz $memcpy_final // no more, let's leave - rep movsb // the last 1, 2, or 3 bytes - -$memcpy_final: - emms // clean up the MMX state - sfence // flush the write buffer - mov eax, [dest] // ret value = destination pointer - - } -} - -#endif /* _WIN32 */ diff --git a/idlib/math/simd_3dnow.h b/idlib/math/simd_3dnow.h deleted file mode 100644 index 40839bb62..000000000 --- a/idlib/math/simd_3dnow.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_3DNOW_H__ -#define __MATH_SIMD_3DNOW_H__ - -/* -=============================================================================== - - 3DNow! implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_3DNow : public idSIMD_MMX { -#ifdef _WIN32 -public: - virtual const char * VPCALL GetName( void ) const; - - virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); - -#endif -}; - -#endif /* !__MATH_SIMD_3DNOW_H__ */ diff --git a/idlib/math/simd_altivec.cpp b/idlib/math/simd_altivec.cpp deleted file mode 100644 index 342b7cfd7..000000000 --- a/idlib/math/simd_altivec.cpp +++ /dev/null @@ -1,11224 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "Simd_Generic.h" -#include "Simd_AltiVec.h" -#include -#include - -#ifdef PPC_INTRINSICS - #include -#endif - -// Doom3 SIMD Library version 0.5 -// Patrick Flanagan (pflanagan@apple.com) -// Sanjay Patel (spatel@apple.com) -// Architecture & Performance Group, Apple Computer - - -//=============================================================== -// -// AltiVec implementation of idSIMDProcessor -// -//=============================================================== - -#if defined(MACOS_X) && defined(__ppc__) - -// Data struct sizes - -#ifndef DRAWVERT_PADDED - // 60 bytes, 15 floats at 4 bytes each - #define DRAWVERT_OFFSET 15 -#else - // 64 bytes, 16 floats - #define DRAWVERT_OFFSET 16 -#endif -// 16 bytes each, 4 floats -#define PLANE_OFFSET 4 -// 16 bytes each, 4 floats -#define IDVEC4_OFFSET 4 - -// Alignment tests -#define IS_16BYTE_ALIGNED( x ) ( ( (unsigned long)&x & 0x0F ) == 0 ) -#define NOT_16BYTE_ALIGNED( x ) ( ( (unsigned long)&x & 0x0F) != 0 ) - -// Aligned storing floats -#define ALIGNED_STORE2( ADDR, V0, V1 ) \ - vec_st( V0, 0, ADDR ); \ - vec_st( V1, 16, ADDR ) - -#define ALIGNED_STORE3( ADDR, V0, V1, V2 ) \ - vec_st( V0, 0, ADDR ); \ - vec_st( V1, 16, ADDR ); \ - vec_st( V2, 32, ADDR ) - -#define ALIGNED_STORE4( ADDR, V0, V1, V2, V3 ) \ - vec_st( V0, 0, ADDR ); \ - vec_st( V1, 16, ADDR ); \ - vec_st( V2, 32, ADDR ); \ - vec_st( V3, 48, ADDR ) - -#define ALIGNED_STORE6( ADDR, V0, V1, V2, V3, V4, V5 ) \ - vec_st( V0, 0, ADDR ); \ - vec_st( V1, 16, ADDR ); \ - vec_st( V2, 32, ADDR ); \ - vec_st( V3, 48, ADDR ); \ - vec_st( V4, 64, ADDR ); \ - vec_st( V5, 80, ADDR ) - -#define ALIGNED_STORE8( ADDR, V0, V1, V2, V3, V4, V5, V6, V7 ) \ - vec_st( V0, 0, ADDR ); \ - vec_st( V1, 16, ADDR ); \ - vec_st( V2, 32, ADDR ); \ - vec_st( V3, 48, ADDR ); \ - vec_st( V4, 64, ADDR ); \ - vec_st( V5, 80, ADDR ); \ - vec_st( V6, 96, ADDR ); \ - vec_st( V7, 112, ADDR ) - -// Unaligned storing floats. These assume that we can trash the input -#define UNALIGNED_STORE1( ADDR, V0 ) { \ - /* use store element */ \ - vector unsigned char ULStoreMacroPerm = vec_lvsr( 0, ADDR ); \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - vec_ste( V0, 0, ADDR ); \ - vec_ste( V0, 4, ADDR ); \ - vec_ste( V0, 8, ADDR ); \ - vec_ste( V0, 12, ADDR ); \ - } - -#define UNALIGNED_STORE2( ADDR, V0, V1 ) { \ - /* load up the values that are there now */ \ - vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ - vector float ULStoreMacro2 = vec_ld( 31, ADDR ); \ - /* generate permute vector and mask */ \ - vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ - vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ - /* right rotate input data */ \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ - /* setup the output vectors */ \ - vector float ULStoreVal1, ULStoreVal2, ULStoreVal3; \ - ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ - ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ - ULStoreVal3 = vec_sel( V1, ULStoreMacro2, ULStoreMacroMask ); \ - /* store results */ \ - vec_st( ULStoreVal1, 0, ADDR ); \ - vec_st( ULStoreVal2, 15, ADDR ); \ - vec_st( ULStoreVal3, 31, ADDR ); } - -#define UNALIGNED_STORE3( ADDR, V0, V1, V2 ) { \ - /* load up the values that are there now */ \ - vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ - vector float ULStoreMacro2 = vec_ld( 47, ADDR ); \ - /* generate permute vector and mask */ \ - vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ - vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ - /* right rotate input data */ \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ - V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ - /* setup the output vectors */ \ - vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4; \ - ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ - ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ - ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ - ULStoreVal4 = vec_sel( V2, ULStoreMacro2, ULStoreMacroMask ); \ - /* store results */ \ - vec_st( ULStoreVal1, 0, ADDR ); \ - vec_st( ULStoreVal2, 15, ADDR ); \ - vec_st( ULStoreVal3, 31, ADDR ); \ - vec_st( ULStoreVal4, 47, ADDR ); } - -#define UNALIGNED_STORE4( ADDR, V0, V1, V2, V3 ) { \ - /* load up the values that are there now */ \ - vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ - vector float ULStoreMacro2 = vec_ld( 63, ADDR ); \ - /* generate permute vector and mask */ \ - vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ - vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ - /* right rotate input data */ \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ - V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ - V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ - /* setup the output vectors */ \ - vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5; \ - ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ - ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ - ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ - ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ - ULStoreVal5 = vec_sel( V3, ULStoreMacro2, ULStoreMacroMask ); \ - /* store results */ \ - vec_st( ULStoreVal1, 0, ADDR ); \ - vec_st( ULStoreVal2, 15, ADDR ); \ - vec_st( ULStoreVal3, 31, ADDR ); \ - vec_st( ULStoreVal4, 47, ADDR ); \ - vec_st( ULStoreVal5, 63, ADDR ); } - -#define UNALIGNED_STORE6( ADDR, V0, V1, V2, V3, V4, V5 ) { \ - /* load up the values that are there now */ \ - vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ - vector float ULStoreMacro2 = vec_ld( 95, ADDR ); \ - /* generate permute vector and mask */ \ - vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ - vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ - /* right rotate input data */ \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ - V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ - V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ - V4 = vec_perm( V4, V4, ULStoreMacroPerm ); \ - V5 = vec_perm( V5, V5, ULStoreMacroPerm ); \ - /* setup the output vectors */ \ - vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5, ULStoreVal6, ULStoreVal7; \ - ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ - ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ - ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ - ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ - ULStoreVal5 = vec_sel( V3, V4, ULStoreMacroMask ); \ - ULStoreVal6 = vec_sel( V4, V5, ULStoreMacroMask ); \ - ULStoreVal7 = vec_sel( V5, ULStoreMacro2, ULStoreMacroMask ); \ - /* store results */ \ - vec_st( ULStoreVal1, 0, ADDR ); \ - vec_st( ULStoreVal2, 15, ADDR ); \ - vec_st( ULStoreVal3, 31, ADDR ); \ - vec_st( ULStoreVal4, 47, ADDR ); \ - vec_st( ULStoreVal5, 63, ADDR ); \ - vec_st( ULStoreVal6, 79, ADDR ); \ - vec_st( ULStoreVal7, 95, ADDR ); } - -#define UNALIGNED_STORE9( ADDR, V0, V1, V2, V3, V4, V5, V6, V7, V8 ) { \ - /* load up the values that are there now */ \ - vector float ULStoreMacro1 = vec_ld( 0, ADDR ); \ - vector float ULStoreMacro2 = vec_ld( 143, ADDR ); \ - /* generate permute vector and mask */ \ - vector unsigned char ULStoreMacroPerm = vec_sub( vec_lvsr( 15, ADDR ), (vector unsigned char)(1) ); \ - vector unsigned int ULStoreMacroMask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), ULStoreMacroPerm ); \ - /* right rotate input data */ \ - V0 = vec_perm( V0, V0, ULStoreMacroPerm ); \ - V1 = vec_perm( V1, V1, ULStoreMacroPerm ); \ - V2 = vec_perm( V2, V2, ULStoreMacroPerm ); \ - V3 = vec_perm( V3, V3, ULStoreMacroPerm ); \ - V4 = vec_perm( V4, V4, ULStoreMacroPerm ); \ - V5 = vec_perm( V5, V5, ULStoreMacroPerm ); \ - V6 = vec_perm( V6, V6, ULStoreMacroPerm ); \ - V7 = vec_perm( V7, V7, ULStoreMacroPerm ); \ - V8 = vec_perm( V8, V8, ULStoreMacroPerm ); \ - /* setup the output vectors */ \ - vector float ULStoreVal1, ULStoreVal2, ULStoreVal3, ULStoreVal4, ULStoreVal5, ULStoreVal6, ULStoreVal7; \ - vector float ULStoreVal8, ULStoreVal9, ULStoreVal10; \ - ULStoreVal1 = vec_sel( ULStoreMacro1, V0, ULStoreMacroMask ); \ - ULStoreVal2 = vec_sel( V0, V1, ULStoreMacroMask ); \ - ULStoreVal3 = vec_sel( V1, V2, ULStoreMacroMask ); \ - ULStoreVal4 = vec_sel( V2, V3, ULStoreMacroMask ); \ - ULStoreVal5 = vec_sel( V3, V4, ULStoreMacroMask ); \ - ULStoreVal6 = vec_sel( V4, V5, ULStoreMacroMask ); \ - ULStoreVal7 = vec_sel( V5, V6, ULStoreMacroMask ); \ - ULStoreVal8 = vec_sel( V6, V7, ULStoreMacroMask ); \ - ULStoreVal9 = vec_sel( V7, V8, ULStoreMacroMask ); \ - ULStoreVal10 = vec_sel( V8, ULStoreMacro2, ULStoreMacroMask ); \ - /* store results */ \ - vec_st( ULStoreVal1, 0, ADDR ); \ - vec_st( ULStoreVal2, 15, ADDR ); \ - vec_st( ULStoreVal3, 31, ADDR ); \ - vec_st( ULStoreVal4, 47, ADDR ); \ - vec_st( ULStoreVal5, 63, ADDR ); \ - vec_st( ULStoreVal6, 79, ADDR ); \ - vec_st( ULStoreVal7, 95, ADDR ); \ - vec_st( ULStoreVal8, 111, ADDR ); \ - vec_st( ULStoreVal9, 127, ADDR ); \ - vec_st( ULStoreVal10, 143, ADDR ); } - -/* -============ -idSIMD_AltiVec::GetName -============ -*/ -const char *idSIMD_AltiVec::GetName( void ) const { - return "AltiVec"; -} - -/* - Helper Functions -*/ -#if 0 -// Prints the values of a vector, useful for debugging but -// should never be called in real code -inline void debugPrintVector( vector float v, char *msg ) { - printf("%s -- %vf\n", msg, v ); -} - -inline void debugPrintVector( vector unsigned int v, char *msg ) { - printf("%s -- %vd\n", msg, v ); -} - -inline void debugPrintVector( vector bool int v, char *msg ) { - printf("%s -- %vi\n", msg, v ); -} - -inline void debugPrintVector( vector unsigned char v, char *msg ) { - printf("%s -- %vuc\n", msg, v ); -} - -inline void debugPrintVector( vector unsigned short v, char *msg ) { - printf("%s -- %vs\n", msg, v ); -} -#endif -/* -=============== - Reciprocal - - For each element in vector: - n = 1 / n -=============== -*/ - -// Use Newton-Raphson to calculate reciprocal of a vector -inline vector float Reciprocal( vector float v ) { - //Get the reciprocal estimate - vector float estimate = vec_re( v ); - //One round of Newton-Raphson refinement - return vec_madd( vec_nmsub( estimate, v, (vector float) (1.0) ), estimate, estimate ); -} - -/* -=============== - ReciprocalSquareRoot - - For each element in vector: - n = 1 / sqrt(n) -=============== -*/ -// Reciprocal square root estimate of a vector -inline vector float ReciprocalSquareRoot( vector float v ) { - //Get the square root reciprocal estimate - vector float zero = (vector float)(0); - vector float oneHalf = (vector float)(0.5); - vector float one = (vector float)(1.0); - vector float estimate = vec_rsqrte( vec_max( v, (vector float)(FLT_MIN) ) ); - - //One round of Newton-Raphson refinement - vector float estimateSquared = vec_madd( estimate, estimate, zero ); - vector float halfEstimate = vec_madd( estimate, oneHalf, zero ); - return vec_madd( vec_nmsub( v, estimateSquared, one ), halfEstimate, estimate ); -} - - -/* -=============== - Divide - - For each element in vectors: - n = a / b -=============== -*/ -// Use reciprocal estimate and multiply to divide a vector -inline vector float Divide( vector float a, vector float b ) { - return vec_madd( a, Reciprocal( b ), (vector float)(0) ); -} - -/* -=============== - loadSplatUnalignedScalar - - For each element in vector: - n = s -=============== -*/ -inline vector float loadSplatUnalignedScalar( const float *s ) { - vector unsigned char splatMap = vec_lvsl( 0, s ); - vector float v = vec_ld( 0, s ); - splatMap = (vector unsigned char) vec_splat( (vector float) splatMap, 0 ); - return vec_perm( v, v, splatMap ); -} - -/* -=============== - VectorATan16 - - For each element in vector: - n = idMath::ATan16( x, y ) -=============== -*/ -// calculates arc tangent of a vector with 16 bits of precision, based on atan16 in idMath -inline vector float VectorATan16( vector float x, vector float y ) { - - vector float xDivY = Divide( x, y ); - vector float yDivX = Divide( y, x ); - vector float zeroVector = (vector float)(0); - - vector bool int vecCmp = vec_cmpgt( vec_abs( y ), vec_abs( x ) ); - vector float vecA = vec_sel( yDivX, xDivY, vecCmp ); - vector bool int vecCmp2 = vec_cmplt( vecA, zeroVector ); - vector float vecS = vec_madd( vecA, vecA, (vector float)(0) ); - - // do calculation for S - vector float vecWork1 = vec_madd( (vector float)(0.0028662257f), vecS, (vector float)(-0.0161657367f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.0429096138f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.0752896400f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.1065626393f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.1420889944f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(0.1999355085f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(-0.3333314528f) ); - vecWork1 = vec_madd( vecWork1, vecS, (vector float)(1) ); - - // get the regular S value - vecS = vec_madd( vecWork1, vecA, (vector float)(0) ); - - // calculate what to return if y > x - vector float negSPlusHalfPI = vec_madd( vecS, (vector float)(-1), (vector float)(0.5f * 3.14159265358979323846f) ); - vector float negSMinusHalfPI = vec_madd( vecS, (vector float)(-1), (vector float)(-0.5f * 3.14159265358979323846f) ); - vector float modRet = vec_sel( negSPlusHalfPI, negSMinusHalfPI, vecCmp2 ); - - return vec_sel( modRet, vecS, vecCmp ); -} - -/* -=============== - VectorSin16 - - For each element in vector: - n = idMath::Sin16( v ) -=============== -*/ -inline vector float VectorSin16( vector float v ) { - vector float zero = (vector float)(0); - -#if 0 - // load up half PI and use it to calculate the rest of the values. This is - // sometimes cheaper than loading them from memory - - vector float halfPI = (vector float) ( 0.5f * 3.14159265358979323846f ); - vector float PI = vec_add( halfPI, halfPI ); - vector float oneandhalfPI = vec_add( PI, halfPI ); - vector float twoPI = vec_add( oneandhalfPI, halfPI ); -#else - vector float halfPI = (vector float) ( 0.5f * 3.14159265358979323846f ); - vector float PI = (vector float)(3.14159265358979323846f); - vector float oneandhalfPI = (vector float)(3.14159265358979323846f + ( 0.5f * 3.14159265358979323846f ) ); - vector float twoPI = (vector float)( 2.0f * 3.14159265358979323846f); -#endif - - vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4; - - vector float vecMod; - vector float vecResult; - - // fix the range if needbe - vecMod = vec_floor( Divide( v, twoPI ) ); - vecResult = vec_nmsub( vecMod, twoPI, v ); - - vector float vecPIminusA = vec_sub( PI, vecResult ); - vector float vecAminus2PI = vec_sub( vecResult, twoPI ); - - vecCmp1 = vec_cmplt( vecResult, PI ); - vecCmp2 = vec_cmpgt( vecResult, halfPI ); - - // these are the ones where a > PI + HALF_PI so set a = a - TWO_PI - vecCmp3 = vec_cmpgt( vecResult, oneandhalfPI ); - - // we also want to set a = PI - a everywhere that !(a < PI) and !(a > PI + HALF_PI) - vecCmp4 = vec_and( vec_xor( vecCmp3, (vector bool int)(1) ), vec_xor( vecCmp1, (vector bool int)(1) ) ); // everywhere that both of those are false - - // these are ones where a < PI and a > HALF_PI so we set a = PI - a - vecCmp1 = vec_and( vecCmp1, vecCmp2 ); - vecCmp1 = vec_or( vecCmp1, vecCmp4 ); - - // put the correct values into place - vecResult = vec_sel( vecResult, vecPIminusA, vecCmp1 ); - vecResult = vec_sel( vecResult, vecAminus2PI, vecCmp3 ); - - // calculate answer - vector float vecASquared = vec_madd( vecResult, vecResult, zero ); - vector float vecEst = vec_madd( (vector float)(-2.39e-08f), vecASquared, (vector float)(2.7526e-06f) ); - vecEst = vec_madd( vecEst, vecASquared, (vector float)(-1.98409e-04f) ); - vecEst = vec_madd( vecEst, vecASquared, (vector float)(8.3333315e-03f) ); - vecEst = vec_madd( vecEst, vecASquared, (vector float)(-1.666666664e-01f) ); - vecEst = vec_madd( vecEst, vecASquared, (vector float)(1.0f) ); - return vec_madd( vecResult, vecEst, zero ); -} - -/* -=============== - vecSplatWithRunTime - - For each element in vector: - n = v(i) -=============== -*/ -// splats an element across a vector using a runtime variable -inline vector float vecSplatWithRunTime( vector float v, int i ) { - vector unsigned char rotate = vec_lvsl( i * sizeof( float ), (int*) 0L ); - v = vec_perm( v, v, rotate ); - return vec_splat( v, 0 ); -} - - -/* -=============== - FastScalarInvSqrt - - n = 1 / sqrt( f ) -=============== -*/ -inline float FastScalarInvSqrt( float f ) { -#ifdef PPC_INTRINSICS - float estimate; - const float kSmallestFloat = FLT_MIN; - - //Calculate a 5 bit starting estimate for the reciprocal sqrt - estimate = __frsqrte ( f + kSmallestFloat ); - - //if you require less precision, you may reduce the number of loop iterations. - // This will do 2 rounds of NR - estimate = estimate + 0.5f * estimate * ( 1.0f - f * estimate * estimate ); - estimate = estimate + 0.5f * estimate * ( 1.0f - f * estimate * estimate ); - return estimate; -#else - return idMath::InvSqrt( f ); -#endif -} - -/* -=============== - FastScalarInvSqrt_x3 - - arg1 = 1 / sqrt( arg1 ) - arg2 = 1 / sqrt( arg2 ) - arg3 = 1 / sqrt( arg3 ) -=============== -*/ -inline void FastScalarInvSqrt_x3( float *arg1, float *arg2, float *arg3 ) { -#ifdef PPC_INTRINSICS - register float estimate1, estimate2, estimate3; - const float kSmallestFloat = FLT_MIN; - - //Calculate a 5 bit starting estimate for the reciprocal sqrt of each - estimate1 = __frsqrte ( *arg1 + kSmallestFloat ); - estimate2 = __frsqrte ( *arg2 + kSmallestFloat ); - estimate3 = __frsqrte ( *arg3 + kSmallestFloat ); - - // two rounds newton-raphson - estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); - estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); - estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); - estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); - estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); - estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); - - *arg1 = estimate1; - *arg2 = estimate2; - *arg3 = estimate3; -#else - *arg1 = idMath::InvSqrt( *arg1 ); - *arg2 = idMath::InvSqrt( *arg2 ); - *arg3 = idMath::InvSqrt( *arg3 ); -#endif -} - -/* -=============== - FastScalarInvSqrt_x6 - - arg1 = 1 / sqrt( arg1 ) - arg2 = 1 / sqrt( arg2 ) - arg3 = 1 / sqrt( arg3 ) - arg4 = 1 / sqrt( arg4 ) - arg5 = 1 / sqrt( arg5 ) - arg6 = 1 / sqrt( arg6 ) - - On a G5, you've got 2 pipeline stages to fill. (2 FPU's with 6 stages each) -=============== -*/ -inline void FastScalarInvSqrt_x6( float *arg1, float *arg2, float *arg3, float *arg4, float *arg5, float *arg6 ) { -#ifdef PPC_INTRINSICS - register float estimate1, estimate2, estimate3, estimate4, estimate5, estimate6; - const float kSmallestFloat = FLT_MIN; - - //Calculate a 5 bit starting estimate for the reciprocal sqrt of each - estimate1 = __frsqrte ( *arg1 + kSmallestFloat ); - estimate2 = __frsqrte ( *arg2 + kSmallestFloat ); - estimate3 = __frsqrte ( *arg3 + kSmallestFloat ); - estimate4 = __frsqrte ( *arg4 + kSmallestFloat ); - estimate5 = __frsqrte ( *arg5 + kSmallestFloat ); - estimate6 = __frsqrte ( *arg6 + kSmallestFloat ); - - // two rounds newton-raphson - estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); - estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); - estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); - estimate4 = estimate4 + 0.5f * estimate4 * ( 1.0f - *arg4 * estimate4 * estimate4 ); - estimate5 = estimate5 + 0.5f * estimate5 * ( 1.0f - *arg5 * estimate5 * estimate5 ); - estimate6 = estimate6 + 0.5f * estimate6 * ( 1.0f - *arg6 * estimate6 * estimate6 ); - - estimate1 = estimate1 + 0.5f * estimate1 * ( 1.0f - *arg1 * estimate1 * estimate1 ); - estimate2 = estimate2 + 0.5f * estimate2 * ( 1.0f - *arg2 * estimate2 * estimate2 ); - estimate3 = estimate3 + 0.5f * estimate3 * ( 1.0f - *arg3 * estimate3 * estimate3 ); - estimate4 = estimate4 + 0.5f * estimate4 * ( 1.0f - *arg4 * estimate4 * estimate4 ); - estimate5 = estimate5 + 0.5f * estimate5 * ( 1.0f - *arg5 * estimate5 * estimate5 ); - estimate6 = estimate6 + 0.5f * estimate6 * ( 1.0f - *arg6 * estimate6 * estimate6 ); - - *arg1 = estimate1; - *arg2 = estimate2; - *arg3 = estimate3; - *arg4 = estimate4; - *arg5 = estimate5; - *arg6 = estimate6; -#else - *arg1 = idMath::InvSqrt( *arg1 ); - *arg2 = idMath::InvSqrt( *arg2 ); - *arg3 = idMath::InvSqrt( *arg3 ); - *arg4 = idMath::InvSqrt( *arg4 ); - *arg5 = idMath::InvSqrt( *arg5 ); - *arg6 = idMath::InvSqrt( *arg6 ); -#endif -} - - -// End Helper Functions - -#ifdef ENABLE_SIMPLE_MATH - -/* -============ -idSIMD_AltiVec::Add - - dst[i] = constant + src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Add( float *dst, const float constant, const float *src, const int count ) { - vector float v0, v1, v2, v3; - vector float v0_low, v0_hi, v1_hi; - vector unsigned char permVec; - vector float constVec; - int i; - - // handle unaligned cases at beginning - for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant + src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do first load - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), (vector unsigned char)(1) ); - v1_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v0_hi, v1_hi, permVec ); - - v2 = vec_add( v0, constVec ); - v3 = vec_add( v1, constVec ); - - // store results - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = constant + src[i]; - } -} - -/* -============ -idSIMD_AltiVec::Add - - dst[i] = src0[i] + src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Add( float *dst, const float *src0, const float *src1, const int count ) { - - register vector float v0, v1, v2, v3, v4, v5; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - - int i; - - //unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src0[i] + src1[i]; - } - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - v4 = vec_add( v0, v1 ); - v5 = vec_add( v2, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] + src1[i]; - } -} - -/* -============ -idSIMD_AltiVec::Sub - - dst[i] = constant - src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Sub( float *dst, const float constant, const float *src, const int count ) { - - register vector float v0, v1, v2, v3; - register vector float v0_low, v0_hi, v1_low, v1_hi; - register vector unsigned char permVec; - register vector float constVec; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant - src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute vector and do first load - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); - v1_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - v2 = vec_sub( constVec, v0 ); - v3 = vec_sub( constVec, v1 ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = constant - src[i]; - } -} - -/* -============ -idSIMD_AltiVec::Sub - - dst[i] = src0[i] - src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Sub( float *dst, const float *src0, const float *src1, const int count ) { - register vector float v0, v1, v2, v3, v4, v5; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src0[i] - src1[i]; - } - - //calculate permute and do first loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - v4 = vec_sub( v0, v1 ); - v5 = vec_sub( v2, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] - src1[i]; - } -} - -/* -============ -idSIMD_AltiVec::Mul - - dst[i] = constant * src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Mul( float *dst, const float constant, const float *src, const int count) { - register vector float v0, v0_low, v0_hi, v1_low, v1_hi, v1, v2, v3; - register vector float constVec; - register vector unsigned char permVec; - vector unsigned char oneCharVector = (vector unsigned char)(1); - register vector float zeroVector = (vector float)(0.0); - int i; - - // handle unaligned data at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = constant * src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); - v1_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - v2 = vec_madd( constVec, v0, zeroVector ); - v3 = vec_madd( constVec, v1, zeroVector ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = constant * src[i]; - } -} - -/* -============ -idSIMD_AltiVec::Mul - - dst[i] = src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Mul( float *dst, const float *src0, const float *src1, const int count ) { - register vector float v0, v1, v2, v3, v4, v5; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - register vector float constVec = (vector float)(0.0); - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] * src1[i]; - } - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - //no such thing as regular multiply so we do - //multiply then add zero - v4 = vec_madd( v0, v1, constVec ); - v5 = vec_madd( v2, v3, constVec ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] * src1[i]; - } -} - -/* -============ -idSIMD_AltiVec::Div - - dst[i] = constant / divisor[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Div( float *dst, const float constant, const float *divisor, const int count ) { - register vector float v0, v1, v2, v3; - register vector float v0_low, v0_hi, v1_low, v1_hi; - register vector unsigned char permVec; - register vector float constVec; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = constant / divisor[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do first loads - permVec = vec_add( vec_lvsl( -1, (int*) &divisor[i] ), oneCharVector ); - v1_hi = vec_ld( 0, &divisor[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &divisor[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &divisor[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - v2 = Divide( constVec, v0 ); - v3 = Divide( constVec, v1 ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = constant / divisor[i]; - } -} - -/* -============ -idSIMD_AltiVec::Div - - dst[i] = src0[i] / src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Div( float *dst, const float *src0, const float *src1, const int count ) { - register vector float v0, v1, v2, v3, v4, v5; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] / src1[i]; - } - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - v4 = Divide( v0, v1 ); - v5 = Divide( v2, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] / src1[i]; - } -} - -/* -============ -idSIMD_AltiVec::MulAdd - - dst[i] += constant * src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::MulAdd( float *dst, const float constant, const float *src, const int count ) { - - register vector float v0, v1, v2, v3, v4, v5; - register vector float constVec; - //src - register vector float v0_low, v0_hi, v2_low, v2_hi; - //permute vectors - register vector unsigned char permVec1; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] += constant * src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - - // at this point, dst is known to be aligned - v1 = vec_ld( 0, &dst[i] ); - v3 = vec_ld( 16, &dst[i] ); - - v4 = vec_madd( constVec, v0, v1 ); - v5 = vec_madd( constVec, v2, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] += constant * src[i]; - } -} - -/* -============ -idSIMD_AltiVec::MulAdd - - dst[i] += src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::MulAdd( float *dst, const float *src0, const float *src1, const int count ) { - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - - int i; - - //unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] += src0[i] * src1[i]; - } - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - // load sources - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - //we know dst is aligned because we handled unaligned cases - //up front - v4 = vec_ld( 0, &dst[i] ); - v5 = vec_ld( 16, &dst[i] ); - - v6 = vec_madd( v0, v1, v4 ); - v7 = vec_madd( v2, v3, v5 ); - - ALIGNED_STORE2( &dst[i], v6, v7 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] += src0[i] * src1[i]; - } -} - -/* -============ -idSIMD_AltiVec::MulSub - - dst[i] -= constant * src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::MulSub( float *dst, const float constant, const float *src, const int count ) { - register vector float v0, v1, v2, v3, v4, v5; - register vector float constVec; - //src - register vector float v0_low, v0_hi, v2_low, v2_hi; - //permute vectors - register vector unsigned char permVec1; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] -= constant * src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - - //we know dst will be aligned here because we already handled the preceeding - //unaligned cases - v1 = vec_ld( 0, &dst[i] ); - v3 = vec_ld( 16, &dst[i] ); - - v4 = vec_nmsub( v0, constVec, v1 ); - v5 = vec_nmsub( v2, constVec, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] -= constant * src[i]; - } -} - -/* -============ -idSIMD_AltiVec::MulSub - - dst[i] -= src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::MulSub( float *dst, const float *src0, const float *src1, const int count ) { - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i; - - //unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] -= src0[i] * src1[i]; - } - - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src0[i] ); - v3_hi = vec_ld( 0, &src1[i] ); - - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - // load sources - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src0[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src1[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src1[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - //we know dst is aligned because we handled unaligned cases - //up front - v4 = vec_ld( 0, &dst[i] ); - v5 = vec_ld( 16, &dst[i] ); - - v6 = vec_nmsub( v0, v1, v4 ); - v7 = vec_nmsub( v2, v3, v5 ); - - ALIGNED_STORE2( &dst[i], v6, v7 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] -= src0[i] * src1[i]; - } -} - -#endif /* ENABLE_SIMPLE_MATH */ - -#ifdef ENABLE_DOT -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant * src[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) { - - register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; - register vector float vecX, vecY, vecZ; - vector float vecX2, vecY2, vecZ2; - const float *addr = src[0].ToFloatPtr(); - float tempVal[4]; - float constVal[4]; - register vector float zeroVector = (vector float)(0.0); - register vector float vecConstX, vecConstY, vecConstZ; - - // permute vectors - register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk - register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); - - register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk - register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); - - register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk - register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); - - int i; - - // for scalar cleanup, if necessary - constVal[0] = constant[0]; - constVal[1] = constant[1]; - constVal[2] = constant[2]; - constVal[3] = 0; - - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - vecLd1 = vec_ld( 0, constant.ToFloatPtr() ); - vecLd2 = vec_ld( 11, constant.ToFloatPtr() ); - vecLd1 = vec_perm( vecLd1, vecLd2, constPerm ); - - - // populate const vectors - vecConstX = vec_splat( vecLd1, 0 ); - vecConstY = vec_splat( vecLd1, 1 ); - vecConstZ = vec_splat( vecLd1, 2 ); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, addr ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant * src[i]; - } - - for ( ; i + 7 < count; i += 8 ) { - float *vecPtr = (float*)( addr + (i*3) ); - vector float v0, v1, v2, v3, v4, v5; - - v0 = vecOld; //vec_ld( 0, vecPtr ); - v1 = vec_ld( 15, vecPtr ); - v2 = vec_ld( 31, vecPtr ); - v3 = vec_ld( 47, vecPtr ); - v4 = vec_ld( 63, vecPtr ); - v5 = vec_ld( 79, vecPtr ); - vecOld = vec_ld( 95, vecPtr ); - - vecLd1 = vec_perm( v0, v1, permVec ); - vecLd2 = vec_perm( v1, v2, permVec ); - vecLd3 = vec_perm( v2, v3, permVec ); - - vecLd4 = vec_perm( v3, v4, permVec ); - vecLd5 = vec_perm( v4, v5, permVec ); - vecLd6 = vec_perm( v5, vecOld, permVec ); - - // permute into X Y Z vectors - vecX = vec_perm( vecLd1, vecLd2, permX1 ); - vecY = vec_perm( vecLd1, vecLd2, permY1 ); - vecZ = vec_perm( vecLd1, vecLd2, permZ1 ); - vecX = vec_perm( vecX, vecLd3, permX2 ); - vecY = vec_perm( vecY, vecLd3, permY2 ); - vecZ = vec_perm( vecZ, vecLd3, permZ2 ); - - vecX2 = vec_perm( vecLd4, vecLd5, permX1 ); - vecY2 = vec_perm( vecLd4, vecLd5, permY1 ); - vecZ2 = vec_perm( vecLd4, vecLd5, permZ1 ); - vecX2 = vec_perm( vecX2, vecLd6, permX2 ); - vecY2 = vec_perm( vecY2, vecLd6, permY2 ); - vecZ2 = vec_perm( vecZ2, vecLd6, permZ2 ); - - // do multiply - vecX = vec_madd( vecX, vecConstX, zeroVector ); - vecY = vec_madd( vecY, vecConstY, vecX ); - vecZ = vec_madd( vecZ, vecConstZ, vecY ); - - vecX2 = vec_madd( vecX2, vecConstX, zeroVector ); - vecY2 = vec_madd( vecY2, vecConstY, vecX2 ); - vecZ2 = vec_madd( vecZ2, vecConstZ, vecY2 ); - - // store out results - ALIGNED_STORE2( &dst[i], vecZ, vecZ2 ); - } - - //cleanup - for ( ; i < count; i++ ) { - // look up whats at the address we want, cast it as float pointer, then - // dereference that pointer - tempVal[0] = *( addr + (i*3) + 0 ); - tempVal[1] = *( addr + (i*3) + 1 ); - tempVal[2] = *( addr + (i*3) + 2 ); - dst[i] = constVal[0] * tempVal[0] + constVal[1] * tempVal[1] + constVal[2] * tempVal[2]; - } -} - - -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant * src[i].Normal() + src[i][3]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { -//#define OPER(X) dst[(X)] = constant * src[(X)].Normal() + src[(X)][3]; - - assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); - - int i; - float constVal[4]; - float srcVal[3]; - float srcI3; - float tempVal; - - vector float vecPlaneLd1, vecPlaneLd2, vecPlaneLd3, vecPlaneLd4; - vector float vecPlaneLd5, vecPlaneLd6, vecPlaneLd7, vecPlaneLd8; - vector float vecX, vecY, vecZ, vecI3; - vector float vecX2, vecY2, vecZ2, vecI32; - vector float vecConstX, vecConstY, vecConstZ; - - constVal[0] = constant[0]; - constVal[1] = constant[1]; - constVal[2] = constant[2]; - constVal[3] = 1; - - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - vector float v0 = vec_ld( 0, constant.ToFloatPtr() ); - vector float v1 = vec_ld( 11, constant.ToFloatPtr() ); - vector float vecConst = vec_perm( v0, v1, constPerm ); - - vecConstX = vec_splat( vecConst, 0 ); - vecConstY = vec_splat( vecConst, 1 ); - vecConstZ = vec_splat( vecConst, 2 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant * src[i].Normal() + src[i][3]; - } - - const float *addr = src[i].ToFloatPtr(); - vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, addr ); - - for ( ; i + 7 < count; i += 8 ) { - float *planePtr = (float*)( addr + (i*PLANE_OFFSET) ); - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - v0 = vecOld; //vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - v2 = vec_ld( 31, planePtr ); - v3 = vec_ld( 47, planePtr ); - v4 = vec_ld( 63, planePtr ); - v5 = vec_ld( 79, planePtr ); - v6 = vec_ld( 95, planePtr ); - v7 = vec_ld( 111, planePtr ); - vecOld = vec_ld( 127, planePtr ); - - vecPlaneLd1 = vec_perm( v0, v1, permVec ); - vecPlaneLd2 = vec_perm( v1, v2, permVec ); - vecPlaneLd3 = vec_perm( v2, v3, permVec ); - vecPlaneLd4 = vec_perm( v3, v4, permVec ); - - vecPlaneLd5 = vec_perm( v4, v5, permVec ); - vecPlaneLd6 = vec_perm( v5, v6, permVec ); - vecPlaneLd7 = vec_perm( v6, v7, permVec ); - vecPlaneLd8 = vec_perm( v7, vecOld, permVec ); - - // permute into X Y Z vectors, since this is square its basically - // a matrix transpose - v0 = vec_mergeh( vecPlaneLd1, vecPlaneLd3 ); - v1 = vec_mergeh( vecPlaneLd2, vecPlaneLd4 ); - v2 = vec_mergel( vecPlaneLd1, vecPlaneLd3 ); - v3 = vec_mergel( vecPlaneLd2, vecPlaneLd4 ); - - vecX = vec_mergeh( v0, v1 ); - vecY = vec_mergel( v0, v1 ); - vecZ = vec_mergeh( v2, v3 ); - vecI3 = vec_mergel( v2, v3 ); - - v4 = vec_mergeh( vecPlaneLd5, vecPlaneLd7 ); - v5 = vec_mergeh( vecPlaneLd6, vecPlaneLd8 ); - v6 = vec_mergel( vecPlaneLd5, vecPlaneLd7 ); - v7 = vec_mergel( vecPlaneLd6, vecPlaneLd8 ); - - vecX2 = vec_mergeh( v4, v5 ); - vecY2 = vec_mergel( v4, v5 ); - vecZ2 = vec_mergeh( v6, v7 ); - vecI32 = vec_mergel( v6, v7 ); - - // do calculation - v6 = vec_madd( vecZ, vecConstZ, vecI3 ); - v5 = vec_madd( vecY, vecConstY, v6 ); - v4 = vec_madd( vecX, vecConstX, v5 ); - - v0 = vec_madd( vecZ2, vecConstZ, vecI32 ); - v1 = vec_madd( vecY2, vecConstY, v0 ); - v2 = vec_madd( vecX2, vecConstX, v1 ); - - // store results - ALIGNED_STORE2( &dst[i], v4, v2 ); - } - - // cleanup - for ( ; i < count; i++ ) { - // populate srcVal with src X Y Z - srcVal[0] = *(addr + (i*PLANE_OFFSET) + 0 ); - srcVal[1] = *(addr + (i*PLANE_OFFSET) + 1 ); - srcVal[2] = *(addr + (i*PLANE_OFFSET) + 2 ); - - // put src[i][3] into srcI3 - srcI3 = *(addr + (i*PLANE_OFFSET) + 3 ); - - tempVal = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; - dst[i] = tempVal + srcI3; - } -} - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant * src[i].xyz; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { -//#define OPER(X) dst[(X)] = constant * src[(X)].xyz; - - // idDrawVert size is 60 bytes - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - int i; - register vector float vecConstX, vecConstY, vecConstZ; - register vector float vecSrcX1, vecSrcY1, vecSrcZ1; - register vector float zeroVector = (vector float)(0.0); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - v0 = vec_ld( 0, constant.ToFloatPtr() ); - v1 = vec_ld( 11, constant.ToFloatPtr() ); - v0 = vec_perm( v0, v1, constPerm ); - - // permute into constant vectors - vecConstX = vec_splat( v0, 0 ); - vecConstY = vec_splat( v0, 1 ); - vecConstZ = vec_splat( v0, 2 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant * src[i].xyz; - } - - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < count ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } - - for ( ; i+3 < count; i += 4 ) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 11, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 11, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 11, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 11, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v2 = vec_perm( v2, v3, vertPerm2 ); - v4 = vec_perm( v4, v5, vertPerm3 ); - v6 = vec_perm( v6, v7, vertPerm4 ); - - // transpose into X Y Z vectors - v1 = vec_mergeh( v0, v4 ); - v3 = vec_mergeh( v2, v6 ); - v5 = vec_mergel( v0, v4 ); - v7 = vec_mergel( v2, v6 ); - - vecSrcX1 = vec_mergeh( v1, v3 ); - vecSrcY1 = vec_mergel( v1, v3 ); - vecSrcZ1 = vec_mergeh( v5, v7 ); - - // now calculate dot product - vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); - vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); - vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); - - // store results - vec_st( vecSrcZ1, 0, &dst[i] ); - } - - for ( ; i < count; i++ ) { - dst[i] = constant * src[i].xyz; - } -} -#else -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant * src[i].xyz; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { -//#define OPER(X) dst[(X)] = constant * src[(X)].xyz; - - // idDrawVert size is 64 bytes - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - int i; - register vector float vecConstX, vecConstY, vecConstZ; - register vector float vecSrcX1, vecSrcY1, vecSrcZ1; - register vector float zeroVector = (vector float)(0.0); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - v0 = vec_ld( 0, constant.ToFloatPtr() ); - v1 = vec_ld( 11, constant.ToFloatPtr() ); - v0 = vec_perm( v0, v1, constPerm ); - - // permute into constant vectors - vecConstX = vec_splat( v0, 0 ); - vecConstY = vec_splat( v0, 1 ); - vecConstZ = vec_splat( v0, 2 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant * src[i].xyz; - } - - for ( ; i+3 < count; i += 4 ) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - - // transpose into X Y Z vectors - v1 = vec_mergeh( v0, v4 ); - v3 = vec_mergeh( v2, v6 ); - v5 = vec_mergel( v0, v4 ); - v7 = vec_mergel( v2, v6 ); - - vecSrcX1 = vec_mergeh( v1, v3 ); - vecSrcY1 = vec_mergel( v1, v3 ); - vecSrcZ1 = vec_mergeh( v5, v7 ); - - // now calculate dot product - vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); - vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); - vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); - - // store results - vec_st( vecSrcZ1, 0, &dst[i] ); - } - - for ( ; i < count; i++ ) { - dst[i] = constant * src[i].xyz; - } -} - -#endif /* DRAWVERT_PADDED */ - -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant.Normal() * src[i] + constant[3]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idVec3 *src, const int count ) { -//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)] + constant[3]; - - register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; - register vector float vecX, vecY, vecZ, vecX2, vecY2, vecZ2; - register vector float zeroVector = (vector float)(0.0); - register vector float vecConstX, vecConstY, vecConstZ; - register vector float vecConst3; - - idVec3 constNormal = constant.Normal(); - float const3 = constant[3]; - - // permute vectors - register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk - register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); - - register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk - register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); - - register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk - register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); - - int i; - - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - vecLd1 = vec_ld( 0, constant.ToFloatPtr() ); - vecLd2 = vec_ld( 15, constant.ToFloatPtr() ); - vecLd1 = vec_perm( vecLd1, vecLd2, constPerm ); - - // populate const vec - vecConstX = vec_splat( vecLd1, 0 ); - vecConstY = vec_splat( vecLd1, 1 ); - vecConstZ = vec_splat( vecLd1, 2 ); - - // put constant to add in vector - vecConst3 = loadSplatUnalignedScalar( &const3 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant.Normal() * src[i] + constant[3]; - } - - const float *addr = src[i].ToFloatPtr(); - vector unsigned char permVec = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, addr ); - - for ( ; i+7 < count; i += 8 ) { - float *vecPtr = (float*)( addr + (i*3) ); - vector float v0, v1, v2, v3, v4, v5; - - v0 = vecOld; //vec_ld( 0, vecPtr ); - v1 = vec_ld( 15, vecPtr ); - v2 = vec_ld( 31, vecPtr ); - v3 = vec_ld( 47, vecPtr ); - v4 = vec_ld( 63, vecPtr ); - v5 = vec_ld( 79, vecPtr ); - vecOld = vec_ld( 95, vecPtr ); - - vecLd1 = vec_perm( v0, v1, permVec ); - vecLd2 = vec_perm( v1, v2, permVec ); - vecLd3 = vec_perm( v2, v3, permVec ); - - vecLd4 = vec_perm( v3, v4, permVec ); - vecLd5 = vec_perm( v4, v5, permVec ); - vecLd6 = vec_perm( v5, vecOld, permVec ); - - // permute into X Y Z vectors - vecX = vec_perm( vecLd1, vecLd2, permX1 ); - vecY = vec_perm( vecLd1, vecLd2, permY1 ); - vecZ = vec_perm( vecLd1, vecLd2, permZ1 ); - vecX = vec_perm( vecX, vecLd3, permX2 ); - vecY = vec_perm( vecY, vecLd3, permY2 ); - vecZ = vec_perm( vecZ, vecLd3, permZ2 ); - - vecX2 = vec_perm( vecLd4, vecLd5, permX1 ); - vecY2 = vec_perm( vecLd4, vecLd5, permY1 ); - vecZ2 = vec_perm( vecLd4, vecLd5, permZ1 ); - vecX2 = vec_perm( vecX2, vecLd6, permX2 ); - vecY2 = vec_perm( vecY2, vecLd6, permY2 ); - vecZ2 = vec_perm( vecZ2, vecLd6, permZ2 ); - - // calculate dot product - vecX = vec_madd( vecX, vecConstX, zeroVector ); - vecY = vec_madd( vecY, vecConstY, vecX ); - vecZ = vec_madd( vecZ, vecConstZ, vecY ); - - vecX2 = vec_madd( vecX2, vecConstX, zeroVector ); - vecY2 = vec_madd( vecY2, vecConstY, vecX2 ); - vecZ2 = vec_madd( vecZ2, vecConstZ, vecY2 ); - - // add in constant[3] - vecZ = vec_add( vecZ, vecConst3 ); - vecZ2 = vec_add( vecZ2, vecConst3 ); - - // store out results - ALIGNED_STORE2( &dst[i], vecZ, vecZ2 ); - } - - //cleanup - for ( ; i < count; i++ ) { - dst[i] = constNormal * src[i] + const3; - } -} - -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idPlane *src, const int count ) { -//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].Normal() + constant[3] * src[(X)][3]; - - // check plane size - assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); - - float constVal[4]; - float srcVal[4]; - - int i; - const float *constPtr = constant.ToFloatPtr(); - - register vector float vecX, vecY, vecZ, vecI3; - register vector float vecX2, vecY2, vecZ2, vecI32; - - vector float vecPlaneLd1, vecPlaneLd2, vecPlaneLd3, vecPlaneLd4; - vector float vecPlaneLd5, vecPlaneLd6, vecPlaneLd7, vecPlaneLd8; - register vector float zeroVector = (vector float)(0.0); - register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; - - constVal[0] = *(constPtr); - constVal[1] = *(constPtr+1); - constVal[2] = *(constPtr+2); - constVal[3] = *(constPtr+3); - - // populate const vector - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - vector float v0 = vec_ld( 0, constant.ToFloatPtr() ); - vector float v1 = vec_ld( 15, constant.ToFloatPtr() ); - vector float vecConst = vec_perm( v0, v1, constPerm ); - - vecConstX = vec_splat( vecConst, 0 ); - vecConstY = vec_splat( vecConst, 1 ); - vecConstZ = vec_splat( vecConst, 2 ); - vecConstI3 = vec_splat( vecConst, 3 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; - } - - const float *srcPtr = src[i].ToFloatPtr(); - vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr ), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, srcPtr ); - - for ( ; i+7 < count; i += 8 ) { - float *planePtr = (float*)( srcPtr + (i*PLANE_OFFSET) ); - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - v0 = vecOld; // vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - v2 = vec_ld( 31, planePtr ); - v3 = vec_ld( 47, planePtr ); - v4 = vec_ld( 63, planePtr ); - v5 = vec_ld( 79, planePtr ); - v6 = vec_ld( 95, planePtr ); - v7 = vec_ld( 111, planePtr ); - vecOld = vec_ld( 127, planePtr ); - - vecPlaneLd1 = vec_perm( v0, v1, permVec ); - vecPlaneLd2 = vec_perm( v1, v2, permVec ); - vecPlaneLd3 = vec_perm( v2, v3, permVec ); - vecPlaneLd4 = vec_perm( v3, v4, permVec ); - - vecPlaneLd5 = vec_perm( v4, v5, permVec ); - vecPlaneLd6 = vec_perm( v5, v6, permVec ); - vecPlaneLd7 = vec_perm( v6, v7, permVec ); - vecPlaneLd8 = vec_perm( v7, vecOld, permVec ); - - // permute into X Y Z vectors, since this is square its basically - // a matrix transpose - v0 = vec_mergeh( vecPlaneLd1, vecPlaneLd3 ); - v1 = vec_mergeh( vecPlaneLd2, vecPlaneLd4 ); - v2 = vec_mergel( vecPlaneLd1, vecPlaneLd3 ); - v3 = vec_mergel( vecPlaneLd2, vecPlaneLd4 ); - - vecX = vec_mergeh( v0, v1 ); - vecY = vec_mergel( v0, v1 ); - vecZ = vec_mergeh( v2, v3 ); - vecI3 = vec_mergel( v2, v3 ); - - v4 = vec_mergeh( vecPlaneLd5, vecPlaneLd7 ); - v5 = vec_mergeh( vecPlaneLd6, vecPlaneLd8 ); - v6 = vec_mergel( vecPlaneLd5, vecPlaneLd7 ); - v7 = vec_mergel( vecPlaneLd6, vecPlaneLd8 ); - - vecX2 = vec_mergeh( v4, v5 ); - vecY2 = vec_mergel( v4, v5 ); - vecZ2 = vec_mergeh( v6, v7 ); - vecI32 = vec_mergel( v6, v7 ); - - // do calculation - v4 = vec_madd( vecConstX, vecX, zeroVector ); - v5 = vec_madd( vecConstY, vecY, v4 ); - v6 = vec_madd( vecConstZ, vecZ, v5 ); - v7 = vec_madd( vecConstI3, vecI3, v6 ); - - v0 = vec_madd( vecConstX, vecX2, zeroVector ); - v1 = vec_madd( vecConstY, vecY2, v0 ); - v2 = vec_madd( vecConstZ, vecZ2, v1 ); - v3 = vec_madd( vecConstI3, vecI32, v2 ); - - //store result - ALIGNED_STORE2( &dst[i], v7, v3 ); - } - - // cleanup - for ( ; i < count; i++ ) { - //dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; - srcVal[0] = *(srcPtr + (i*PLANE_OFFSET) + 0 ); - srcVal[1] = *(srcPtr + (i*PLANE_OFFSET) + 1 ); - srcVal[2] = *(srcPtr + (i*PLANE_OFFSET) + 2 ); - srcVal[3] = *(srcPtr + (i*PLANE_OFFSET) + 3 ); - dst[i] = srcVal[0] * constVal[0] + srcVal[1] * constVal[1] + srcVal[2] * constVal[2] + constVal[3] * srcVal[3]; - } -} - - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant.Normal() * src[i].xyz + constant[3]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { -//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].xyz + constant[3]; - - // idDrawVert size is 60 bytes - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); - - int i; - const float *constPtr = constant.ToFloatPtr(); - const float *srcPtr = src[0].xyz.ToFloatPtr(); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; - register vector float vecSrcX1, vecSrcY1, vecSrcZ1; - register vector float vecDest1; - register vector float zeroVector = (vector float)(0.0); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - float constVal[4]; - float srcVal[3]; - - constVal[0] = *(constPtr+0); - constVal[1] = *(constPtr+1); - constVal[2] = *(constPtr+2); - constVal[3] = *(constPtr+3); - - // populate const vec - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - v0 = vec_ld( 0, constant.ToFloatPtr() ); - v1 = vec_ld( 15, constant.ToFloatPtr() ); - v0 = vec_perm( v0, v1, constPerm ); - - vecConstX = vec_splat( v0, 0 ); - vecConstY = vec_splat( v0, 1 ); - vecConstZ = vec_splat( v0, 2 ); - vecConstI3 = vec_splat( v0, 3 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant.Normal() * src[i].xyz + constant[3]; - } - - // every fourth one will have the same alignment, so can store these. Make sure we - // have enough so we don't run off the end of the array - if ( i+3 < count ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } - - for ( ; i+3 < count; i+=4 ) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 11, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 11, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 11, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 11, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v2 = vec_perm( v2, v3, vertPerm2 ); - v4 = vec_perm( v4, v5, vertPerm3 ); - v6 = vec_perm( v6, v7, vertPerm4 ); - - // transpose into X Y Z vectors - v1 = vec_mergeh( v0, v4 ); - v3 = vec_mergeh( v2, v6 ); - v5 = vec_mergel( v0, v4 ); - v7 = vec_mergel( v2, v6 ); - - vecSrcX1 = vec_mergeh( v1, v3 ); - vecSrcY1 = vec_mergel( v1, v3 ); - vecSrcZ1 = vec_mergeh( v5, v7 ); - - // now calculate dot product - vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); - vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); - vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); - vecDest1 = vec_add( vecSrcZ1, vecConstI3 ); - - // store results - vec_st( vecDest1, 0, &dst[i] ); - } - - // cleanup - for ( ; i < count; i++ ) { - srcVal[0] = *(srcPtr + (i*DRAWVERT_OFFSET) + 0 ); - srcVal[1] = *(srcPtr + (i*DRAWVERT_OFFSET) + 1 ); - srcVal[2] = *(srcPtr + (i*DRAWVERT_OFFSET) + 2 ); - // dst[i] = constant.Normal() * src[i].xyz + constant[3]; - - dst[i] = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; - dst[i] += constVal[3]; - } -} -#else -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = constant.Normal() * src[i].xyz + constant[3]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { -//#define OPER(X) dst[(X)] = constant.Normal() * src[(X)].xyz + constant[3]; - - // idDrawVert size is 60 bytes - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof( float ) ); - - int i; - const float *constPtr = constant.ToFloatPtr(); - const float *srcPtr = src[0].xyz.ToFloatPtr(); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecConstX, vecConstY, vecConstZ, vecConstI3; - register vector float vecSrcX1, vecSrcY1, vecSrcZ1; - register vector float vecDest1; - register vector float zeroVector = (vector float)(0.0); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - float constVal[4]; - float srcVal[3]; - - constVal[0] = *(constPtr+0); - constVal[1] = *(constPtr+1); - constVal[2] = *(constPtr+2); - constVal[3] = *(constPtr+3); - - // populate const vec - vector unsigned char constPerm = vec_lvsl( 0, constant.ToFloatPtr() ); - v0 = vec_ld( 0, constant.ToFloatPtr() ); - v1 = vec_ld( 15, constant.ToFloatPtr() ); - v0 = vec_perm( v0, v1, constPerm ); - - vecConstX = vec_splat( v0, 0 ); - vecConstY = vec_splat( v0, 1 ); - vecConstZ = vec_splat( v0, 2 ); - vecConstI3 = vec_splat( v0, 3 ); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = constant.Normal() * src[i].xyz + constant[3]; - } - - for ( ; i+3 < count; i+=4 ) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - - // transpose into X Y Z vectors - v1 = vec_mergeh( v0, v4 ); - v3 = vec_mergeh( v2, v6 ); - v5 = vec_mergel( v0, v4 ); - v7 = vec_mergel( v2, v6 ); - - vecSrcX1 = vec_mergeh( v1, v3 ); - vecSrcY1 = vec_mergel( v1, v3 ); - vecSrcZ1 = vec_mergeh( v5, v7 ); - - // now calculate dot product - vecSrcX1 = vec_madd( vecSrcX1, vecConstX, zeroVector ); - vecSrcY1 = vec_madd( vecSrcY1, vecConstY, vecSrcX1 ); - vecSrcZ1 = vec_madd( vecSrcZ1, vecConstZ, vecSrcY1 ); - vecDest1 = vec_add( vecSrcZ1, vecConstI3 ); - - // store results - vec_st( vecDest1, 0, &dst[i] ); - } - - // cleanup - for ( ; i < count; i++ ) { - srcVal[0] = *(srcPtr + (i*DRAWVERT_OFFSET) + 0 ); - srcVal[1] = *(srcPtr + (i*DRAWVERT_OFFSET) + 1 ); - srcVal[2] = *(srcPtr + (i*DRAWVERT_OFFSET) + 2 ); - // dst[i] = constant.Normal() * src[i].xyz + constant[3]; - - dst[i] = constVal[0] * srcVal[0] + constVal[1] * srcVal[1] + constVal[2] * srcVal[2]; - dst[i] += constVal[3]; - } -} - -#endif /* DRAWVERT_PADDED */ - -/* -============ -idSIMD_AltiVec::Dot - - dst[i] = src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) { -//#define OPER(X) dst[(X)] = src0[(X)] * src1[(X)]; - - int i; - float src0Val[3]; - float src1Val[3]; - - register vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; - vector float vecLd7, vecLd8, vecLd9, vecLd10, vecLd11, vecLd12; - register vector float vecX0, vecY0, vecZ0, vecX1, vecY1, vecZ1; - register vector float vecX02, vecY02, vecZ02, vecX12, vecY12, vecZ12; - register vector float zeroVector = (vector float)(0.0); - // permute vectors - register vector unsigned char permX1 = (vector unsigned char)(0,1,2,3,12,13,14,15,24,25,26,27,28,29,30,31); //last 4 bytes are junk - register vector unsigned char permX2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,20,21,22,23); - register vector unsigned char permY1 = (vector unsigned char)(4,5,6,7,16,17,18,19,28,29,30,31,0,1,2,3); //last 4 bytes are junk - register vector unsigned char permY2 = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,27); - register vector unsigned char permZ1 = (vector unsigned char)(8,9,10,11,20,21,22,23,0,1,2,3,4,5,6,7); //last 8 bytes are junk - register vector unsigned char permZ2 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,28,29,30,31); - - // handle unaligned case at beginning - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src0[i] * src1[i]; - } - - const float *src0Ptr = src0[i].ToFloatPtr(); - const float *src1Ptr = src1[i].ToFloatPtr(); - vector unsigned char permVec1 = vec_add( vec_lvsl( -1, src0Ptr ), (vector unsigned char)(1) ); - vector unsigned char permVec2 = vec_add( vec_lvsl( -1, src1Ptr ), (vector unsigned char)(1) ); - vector float vecOld0 = vec_ld( 0, src0Ptr ); - vector float vecOld1 = vec_ld( 0, src1Ptr ); - - for ( i = 0; i+7 < count; i += 8 ) { - float *s0Ptr = (float*)( src0Ptr + (i*3) ); - float *s1Ptr = (float*)( src1Ptr + (i*3) ); - - vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; - v0 = vecOld0; - v1 = vec_ld( 15, s0Ptr ); - v2 = vec_ld( 31, s0Ptr ); - v3 = vec_ld( 47, s0Ptr ); - v4 = vec_ld( 63, s0Ptr ); - v5 = vec_ld( 79, s0Ptr ); - vecOld0 = vec_ld( 95, s0Ptr ); - - v6 = vecOld1; - v7 = vec_ld( 15, s1Ptr ); - v8 = vec_ld( 31, s1Ptr ); - v9 = vec_ld( 47, s1Ptr ); - v10 = vec_ld( 63, s1Ptr ); - v11 = vec_ld( 79, s1Ptr ); - vecOld1 = vec_ld( 95, s1Ptr ); - - vecLd1 = vec_perm( v0, v1, permVec1 ); - vecLd2 = vec_perm( v1, v2, permVec1 ); - vecLd3 = vec_perm( v2, v3, permVec1 ); - vecLd4 = vec_perm( v3, v4, permVec1 ); - vecLd5 = vec_perm( v4, v5, permVec1 ); - vecLd6 = vec_perm( v5, vecOld0, permVec1 ); - - vecLd7 = vec_perm( v6, v7, permVec2 ); - vecLd8 = vec_perm( v7, v8, permVec2 ); - vecLd9 = vec_perm( v8, v9, permVec2 ); - vecLd10 = vec_perm( v9, v10, permVec2 ); - vecLd11 = vec_perm( v10, v11, permVec2 ); - vecLd12 = vec_perm( v11, vecOld1, permVec2 ); - - // permute into X Y Z vectors - vecX0 = vec_perm( vecLd1, vecLd2, permX1 ); - vecY0 = vec_perm( vecLd1, vecLd2, permY1 ); - vecZ0 = vec_perm( vecLd1, vecLd2, permZ1 ); - vecX0 = vec_perm( vecX0, vecLd3, permX2 ); - vecY0 = vec_perm( vecY0, vecLd3, permY2 ); - vecZ0 = vec_perm( vecZ0, vecLd3, permZ2 ); - - vecX02 = vec_perm( vecLd4, vecLd5, permX1 ); - vecY02 = vec_perm( vecLd4, vecLd5, permY1 ); - vecZ02 = vec_perm( vecLd4, vecLd5, permZ1 ); - vecX02 = vec_perm( vecX02, vecLd6, permX2 ); - vecY02 = vec_perm( vecY02, vecLd6, permY2 ); - vecZ02 = vec_perm( vecZ02, vecLd6, permZ2 ); - - vecX1 = vec_perm( vecLd7, vecLd8, permX1 ); - vecY1 = vec_perm( vecLd7, vecLd8, permY1 ); - vecZ1 = vec_perm( vecLd7, vecLd8, permZ1 ); - vecX1 = vec_perm( vecX1, vecLd9, permX2 ); - vecY1 = vec_perm( vecY1, vecLd9, permY2 ); - vecZ1 = vec_perm( vecZ1, vecLd9, permZ2 ); - - vecX12 = vec_perm( vecLd10, vecLd11, permX1 ); - vecY12 = vec_perm( vecLd10, vecLd11, permY1 ); - vecZ12 = vec_perm( vecLd10, vecLd11, permZ1 ); - vecX12 = vec_perm( vecX12, vecLd12, permX2 ); - vecY12 = vec_perm( vecY12, vecLd12, permY2 ); - vecZ12 = vec_perm( vecZ12, vecLd12, permZ2 ); - - // do multiply - vecX0 = vec_madd( vecX0, vecX1, zeroVector ); - vecY0 = vec_madd( vecY0, vecY1, vecX0 ); - vecZ0 = vec_madd( vecZ0, vecZ1, vecY0 ); - vecX02 = vec_madd( vecX02, vecX12, zeroVector ); - vecY02 = vec_madd( vecY02, vecY12, vecX02 ); - vecZ02 = vec_madd( vecZ02, vecZ12, vecY02 ); - - // store out results - ALIGNED_STORE2( &dst[i], vecZ0, vecZ02 ); - } - - // cleanup - for ( ; i < count; i++ ) { - // dst[i] = src0[i] * src1[i]; - src0Val[0] = *( src0Ptr + (i*3) + 0 ); - src0Val[1] = *( src0Ptr + (i*3) + 1 ); - src0Val[2] = *( src0Ptr + (i*3) + 2 ); - - src1Val[0] = *( src1Ptr + (i*3) + 0 ); - src1Val[1] = *( src1Ptr + (i*3) + 1 ); - src1Val[2] = *( src1Ptr + (i*3) + 2 ); - - dst[i] = src0Val[0] * src1Val[0] + src0Val[1] * src1Val[1] + src0Val[2] * src1Val[2]; - } -} - -/* -============ -idSIMD_AltiVec::Dot - - dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2] + ... -============ -*/ -void VPCALL idSIMD_AltiVec::Dot( float &dot, const float *src1, const float *src2, const int count ) { - dot = 0.0f; - - register vector float v0, v1, v2, v3; - register vector float zeroVector; - register vector float runningTotal1, runningTotal2; - //src0 - register vector float v0_low, v0_hi, v2_low, v2_hi; - //src1 - register vector float v1_low, v1_hi, v3_low, v3_hi; - //permute vectors - register vector unsigned char permVec1, permVec2; - vector unsigned char oneCharVector = (vector unsigned char)(1); - - int i = 0; - - runningTotal1 = (vector float)(0.0); - runningTotal2 = (vector float)(0.0); - zeroVector = (vector float)(0.0); - - if ( count >= 8 ) { - //calculate permute and do loads - permVec1 = vec_add( vec_lvsl( -1, (int*) &src1[i] ), oneCharVector ); - permVec2 = vec_add( vec_lvsl( -1, (int*) &src2[i] ), oneCharVector ); - v2_hi = vec_ld( 0, &src1[i] ); - v3_hi = vec_ld( 0, &src2[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load sources - v0_low = v2_hi; - v0_hi = vec_ld( 15, &src1[i] ); - v2_low = v0_hi; - v2_hi = vec_ld( 31, &src1[i] ); - - v1_low = v3_hi; - v1_hi = vec_ld( 15, &src2[i] ); - v3_low = v1_hi; - v3_hi = vec_ld( 31, &src2[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec1 ); - v1 = vec_perm( v1_low, v1_hi, permVec2 ); - v2 = vec_perm( v2_low, v2_hi, permVec1 ); - v3 = vec_perm( v3_low, v3_hi, permVec2 ); - - //multiply together and keep running sum - runningTotal1 = vec_madd( v0, v1, runningTotal1 ); - runningTotal2 = vec_madd( v2, v3, runningTotal2 ); - } - - runningTotal1 = vec_add( runningTotal1, runningTotal2 ); - - // sum accross vector - v0 = vec_add( runningTotal1, vec_sld( runningTotal1, runningTotal1, 8 ) ); - v1 = vec_add( v0, vec_sld( v0, v0, 4 ) ); - runningTotal1 = vec_splat( v1, 0 ); - vec_ste( runningTotal1, 0, &dot ); - } - - //handle cleanup. when profiling the game, we found that most of the counts to this function were small, so it - // spends a lot of time in this scalar code. It's already really really fast (eg 1 TB tick) for scalar code for - // counts less than 50, so not much point in trying to get vector code in on the action - for ( ; i < count ; i++ ) { - dot += src1[i] * src2[i]; - } - -} -#endif /* ENABLE_DOT */ - -#ifdef ENABLE_COMPARES - -/* -============ -idSIMD_AltiVec::CmpGT - - dst[i] = src0[i] > constant; -============ -*/ - -void VPCALL idSIMD_AltiVec::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] = src0[(X)] > constant; - - register vector float v0, v1, v2, v3; - register vector bool int vr1, vr2, vr3, vr4; - register vector bool short vs1, vs2; - register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; - register vector unsigned char vc1; - register vector bool char vbc1; - register vector float constVec; - register vector unsigned char oneVector = (vector unsigned char)(1); - register vector unsigned char permVec; - int i; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] > constant; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - v3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - // load values - v0_low = v3_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src0[i] ); - v2_low = v1_hi; - v2_hi = vec_ld( 47, &src0[i] ); - v3_low = v2_hi; - v3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - v2 = vec_perm( v2_low, v2_hi, permVec ); - v3 = vec_perm( v3_low, v3_hi, permVec ); - - //do comparison - vr1 = vec_cmpgt( v0, constVec ); - vr2 = vec_cmpgt( v1, constVec ); - vr3 = vec_cmpgt( v2, constVec ); - vr4 = vec_cmpgt( v3, constVec ); - - // pack results into shorts - vs1 = vec_pack(vr1, vr2); - vs2 = vec_pack(vr3, vr4); - - // pack results into byte - vbc1 = vec_pack(vs1, vs2); - - //AND with 1 to get true=1 not true=255 - vc1 = vec_and( vbc1, oneVector ); - - //store results - vec_st( vc1, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] > constant; - } -} - - -/* -============ -idSIMD_AltiVec::CmpGT - - dst[i] |= ( src0[i] > constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] |= ( src0[(X)] > constant ) << bitNum; - - // Temp vector registers - register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; - register vector bool short vtbs0, vtbs1; - register vector bool char vtbc0; - register vector unsigned char vtuc0; - register vector unsigned char permVec, permVec2; - - // dest vectors - register vector unsigned char vd; - // bitNum vectors - register vector unsigned char bitNumVec; - // src0 vectors - register vector float vs0, vs1, vs2, vs3; - register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; - // constant vector - register vector float constVec; - // all one's - register vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] |= ( src0[i] > constant ) << bitNum; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //bitNum is unaligned. - permVec2 = vec_lvsl( 0, &bitNum ); - vtuc0 = vec_ld( 0, &bitNum ); - bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); - bitNumVec = vec_splat( bitNumVec, 0 ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - vs3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - //load sources (floats) - vs0_low = vs3_hi; - vs0_hi = vec_ld( 15, &src0[i] ); - vs1_low = vs0_hi; - vs1_hi = vec_ld( 31, &src0[i] ); - vs2_low = vs1_hi; - vs2_hi = vec_ld( 47, &src0[i] ); - vs3_low = vs2_hi; - vs3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - vs0 = vec_perm( vs0_low, vs0_hi, permVec ); - vs1 = vec_perm( vs1_low, vs1_hi, permVec ); - vs2 = vec_perm( vs2_low, vs2_hi, permVec ); - vs3 = vec_perm( vs3_low, vs3_hi, permVec ); - - //load dest (bytes) as unsigned char - vd = vec_ld( 0, &dst[i] ); - - // do comparison and get bool int result - vtbi0 = vec_cmpgt( vs0, constVec ); - vtbi1 = vec_cmpgt( vs1, constVec ); - vtbi2 = vec_cmpgt( vs2, constVec ); - vtbi3 = vec_cmpgt( vs3, constVec ); - - // pack results into shorts - vtbs0 = vec_pack(vtbi0, vtbi1); - vtbs1 = vec_pack(vtbi2, vtbi3); - - // pack results into byte - vtbc0 = vec_pack(vtbs0, vtbs1); - - //and with 1 to get true=1 instead of true=255 - vtuc0 = vec_and(vtbc0, oneVector); - vtuc0 = vec_sl(vtuc0, bitNumVec ); - - //or with original - vd = vec_or( vd, vtuc0 ); - - vec_st( vd, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] |= ( src0[i] > constant ) << bitNum; - } -} - -/* -============ -idSIMD_AltiVec::CmpGE - - dst[i] = src0[i] >= constant; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { - - register vector float v0, v1, v2, v3; - register vector bool int vr1, vr2, vr3, vr4; - register vector bool short vs1, vs2; - register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; - register vector unsigned char vc1; - register vector bool char vbc1; - register vector float constVec; - register vector unsigned char oneVector = (vector unsigned char)(1); - register vector unsigned char permVec; - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] >= constant; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - v3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - // load values - v0_low = v3_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src0[i] ); - v2_low = v1_hi; - v2_hi = vec_ld( 47, &src0[i] ); - v3_low = v2_hi; - v3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - v2 = vec_perm( v2_low, v2_hi, permVec ); - v3 = vec_perm( v3_low, v3_hi, permVec ); - - //do comparison - vr1 = vec_cmpge( v0, constVec ); - vr2 = vec_cmpge( v1, constVec ); - vr3 = vec_cmpge( v2, constVec ); - vr4 = vec_cmpge( v3, constVec ); - - // pack results into shorts - vs1 = vec_pack(vr1, vr2); - vs2 = vec_pack(vr3, vr4); - - // pack results into byte - vbc1 = vec_pack(vs1, vs2); - - //AND with 1 to get true=1 not true=255 - vc1 = vec_and( vbc1, oneVector ); - - //store results - vec_st( vc1, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] >= constant; - } -} - -/* -============ -idSIMD_AltiVec::CmpGE - - dst[i] |= ( src0[i] >= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; - register vector bool short vtbs0, vtbs1; - register vector bool char vtbc0; - register vector unsigned char vtuc0; - register vector unsigned char permVec, permVec2; - - // dest vectors - register vector unsigned char vd; - // bitNum vectors - register vector unsigned char bitNumVec; - // src0 vectors - register vector float vs0, vs1, vs2, vs3; - register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; - // constant vector - register vector float constVec; - // all one's - register vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] |= ( src0[i] >= constant ) << bitNum; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //bitNum is unaligned. - permVec2 = vec_lvsl( 0, &bitNum ); - vtuc0 = vec_ld( 0, &bitNum ); - bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); - bitNumVec = vec_splat( bitNumVec, 0 ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - vs3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - //load sources (floats) - vs0_low = vs3_hi; - vs0_hi = vec_ld( 15, &src0[i] ); - vs1_low = vs0_hi; - vs1_hi = vec_ld( 31, &src0[i] ); - vs2_low = vs1_hi; - vs2_hi = vec_ld( 47, &src0[i] ); - vs3_low = vs2_hi; - vs3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - vs0 = vec_perm( vs0_low, vs0_hi, permVec ); - vs1 = vec_perm( vs1_low, vs1_hi, permVec ); - vs2 = vec_perm( vs2_low, vs2_hi, permVec ); - vs3 = vec_perm( vs3_low, vs3_hi, permVec ); - - //load dest (bytes) as unsigned char - vd = vec_ld( 0, &dst[i] ); - - // do comparison and get bool int result - vtbi0 = vec_cmpge( vs0, constVec ); - vtbi1 = vec_cmpge( vs1, constVec ); - vtbi2 = vec_cmpge( vs2, constVec ); - vtbi3 = vec_cmpge( vs3, constVec ); - - // pack results into shorts - vtbs0 = vec_pack(vtbi0, vtbi1); - vtbs1 = vec_pack(vtbi2, vtbi3); - - // pack results into byte - vtbc0 = vec_pack(vtbs0, vtbs1); - - //and with 1L to get true=1 instead of true=255 - vtuc0 = vec_and(vtbc0, oneVector); - vtuc0 = vec_sl(vtuc0, bitNumVec ); - - //or with original - vd = vec_or( vd, vtuc0 ); - - vec_st( vd, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] |= ( src0[i] >= constant ) << bitNum; - } -} - - -/* -============ -idSIMD_AltiVec::CmpLT - - dst[i] = src0[i] < constant; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] = src0[(X)] < constant; - register vector float v0, v1, v2, v3; - register vector bool int vr1, vr2, vr3, vr4; - register vector bool short vs1, vs2; - register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; - register vector unsigned char vc1; - register vector bool char vbc1; - register vector float constVec; - register vector unsigned char oneVector = (vector unsigned char)(1); - register vector unsigned char permVec; - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] < constant; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - v3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - // load values - v0_low = v3_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src0[i] ); - v2_low = v1_hi; - v2_hi = vec_ld( 47, &src0[i] ); - v3_low = v2_hi; - v3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - v2 = vec_perm( v2_low, v2_hi, permVec ); - v3 = vec_perm( v3_low, v3_hi, permVec ); - - //do comparison - vr1 = vec_cmplt( v0, constVec ); - vr2 = vec_cmplt( v1, constVec ); - vr3 = vec_cmplt( v2, constVec ); - vr4 = vec_cmplt( v3, constVec ); - - // pack results into shorts - vs1 = vec_pack(vr1, vr2); - vs2 = vec_pack(vr3, vr4); - - // pack results into byte - vbc1 = vec_pack(vs1, vs2); - - //AND with 1 to get true=1 not true=255 - vc1 = vec_and( vbc1, oneVector ); - - //store results - vec_st( vc1, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] < constant; - } -} - -/* -============ -idSIMD_AltiVec::CmpLT - - dst[i] |= ( src0[i] < constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] |= ( src0[(X)] < constant ) << bitNum; - register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; - register vector bool short vtbs0, vtbs1; - register vector bool char vtbc0; - register vector unsigned char vtuc0; - register vector unsigned char permVec, permVec2; - - // dest vectors - register vector unsigned char vd; - // bitNum vectors - register vector unsigned char bitNumVec; - // src0 vectors - register vector float vs0, vs1, vs2, vs3; - register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; - // constant vector - register vector float constVec; - // all one's - register vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( i = 0 ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] |= ( src0[i] < constant ) << bitNum; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //bitNum is unaligned. - permVec2 = vec_lvsl( 0, &bitNum ); - vtuc0 = vec_ld( 0, &bitNum ); - bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); - bitNumVec = vec_splat( bitNumVec, 0 ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - vs3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - //load sources (floats) - vs0_low = vs3_hi; - vs0_hi = vec_ld( 15, &src0[i] ); - vs1_low = vs0_hi; - vs1_hi = vec_ld( 31, &src0[i] ); - vs2_low = vs1_hi; - vs2_hi = vec_ld( 47, &src0[i] ); - vs3_low = vs2_hi; - vs3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - vs0 = vec_perm( vs0_low, vs0_hi, permVec ); - vs1 = vec_perm( vs1_low, vs1_hi, permVec ); - vs2 = vec_perm( vs2_low, vs2_hi, permVec ); - vs3 = vec_perm( vs3_low, vs3_hi, permVec ); - - //load dest (bytes) as unsigned char - vd = vec_ld( 0, &dst[i] ); - - // do comparison and get bool int result - vtbi0 = vec_cmplt( vs0, constVec ); - vtbi1 = vec_cmplt( vs1, constVec ); - vtbi2 = vec_cmplt( vs2, constVec ); - vtbi3 = vec_cmplt( vs3, constVec ); - - // pack results into shorts - vtbs0 = vec_pack(vtbi0, vtbi1); - vtbs1 = vec_pack(vtbi2, vtbi3); - - // pack results into byte - vtbc0 = vec_pack(vtbs0, vtbs1); - - //and with 1L to get true=1 instead of true=255 - vtuc0 = vec_and(vtbc0, oneVector); - vtuc0 = vec_sl(vtuc0, bitNumVec ); - - //or with original - vd = vec_or( vd, vtuc0 ); - - vec_st( vd, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] |= ( src0[i] < constant ) << bitNum; - } - -} -//#endif - -/* -============ -idSIMD_AltiVec::CmpLE - - dst[i] = src0[i] <= constant; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] = src0[(X)] <= constant; - register vector float v0, v1, v2, v3; - register vector bool int vr1, vr2, vr3, vr4; - register vector bool short vs1, vs2; - register vector float v0_low, v0_hi, v1_low, v1_hi, v2_low, v2_hi, v3_low, v3_hi; - register vector unsigned char vc1; - register vector bool char vbc1; - register vector float constVec; - register vector unsigned char oneVector = (vector unsigned char)(1); - register vector unsigned char permVec; - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] = src0[i] <= constant; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - v3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - // load values - v0_low = v3_hi; - v0_hi = vec_ld( 15, &src0[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src0[i] ); - v2_low = v1_hi; - v2_hi = vec_ld( 47, &src0[i] ); - v3_low = v2_hi; - v3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - v2 = vec_perm( v2_low, v2_hi, permVec ); - v3 = vec_perm( v3_low, v3_hi, permVec ); - - //do comparison - vr1 = vec_cmple( v0, constVec ); - vr2 = vec_cmple( v1, constVec ); - vr3 = vec_cmple( v2, constVec ); - vr4 = vec_cmple( v3, constVec ); - - // pack results into shorts - vs1 = vec_pack(vr1, vr2); - vs2 = vec_pack(vr3, vr4); - - // pack results into byte - vbc1 = vec_pack(vs1, vs2); - - //AND with 1 to get true=1 not true=255 - vc1 = vec_and( vbc1, oneVector ); - - //store results - vec_st( vc1, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src0[i] <= constant; - } -} - -/* -============ -idSIMD_AltiVec::CmpLE - - dst[i] |= ( src0[i] <= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_AltiVec::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -//#define OPER(X) dst[(X)] |= ( src0[(X)] <= constant ) << bitNum; - register vector bool int vtbi0, vtbi1, vtbi2, vtbi3; - register vector bool short vtbs0, vtbs1; - register vector bool char vtbc0; - register vector unsigned char vtuc0; - register vector unsigned char permVec, permVec2; - - // dest vectors - register vector unsigned char vd; - // bitNum vectors - register vector unsigned char bitNumVec; - // src0 vectors - register vector float vs0, vs1, vs2, vs3; - register vector float vs0_low, vs0_hi, vs1_low, vs1_hi, vs2_low, vs2_hi, vs3_low, vs3_hi; - // constant vector - register vector float constVec; - // all one's - register vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count );i++ ) { - dst[i] |= ( src0[i] <= constant ) << bitNum; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //bitNum is unaligned. - permVec2 = vec_lvsl( 0, &bitNum ); - vtuc0 = vec_ld( 0, &bitNum ); - bitNumVec = vec_perm( vtuc0, vtuc0, permVec2 ); - bitNumVec = vec_splat( bitNumVec, 0 ); - - //calculate permute and do loads - permVec = vec_add( vec_lvsl( -1, (int*) &src0[i] ), oneVector ); - vs3_hi = vec_ld( 0, &src0[i] ); - - //vectorize! - for ( ; i+15 < count; i += 16 ) { - //load sources (floats) - vs0_low = vs3_hi; - vs0_hi = vec_ld( 15, &src0[i] ); - vs1_low = vs0_hi; - vs1_hi = vec_ld( 31, &src0[i] ); - vs2_low = vs1_hi; - vs2_hi = vec_ld( 47, &src0[i] ); - vs3_low = vs2_hi; - vs3_hi = vec_ld( 63, &src0[i] ); - - //permute into the vectors we want - vs0 = vec_perm( vs0_low, vs0_hi, permVec ); - vs1 = vec_perm( vs1_low, vs1_hi, permVec ); - vs2 = vec_perm( vs2_low, vs2_hi, permVec ); - vs3 = vec_perm( vs3_low, vs3_hi, permVec ); - - //load dest (bytes) as unsigned char - vd = vec_ld( 0, &dst[i] ); - - // do comparison and get bool int result - vtbi0 = vec_cmple( vs0, constVec ); - vtbi1 = vec_cmple( vs1, constVec ); - vtbi2 = vec_cmple( vs2, constVec ); - vtbi3 = vec_cmple( vs3, constVec ); - - // pack results into shorts - vtbs0 = vec_pack(vtbi0, vtbi1); - vtbs1 = vec_pack(vtbi2, vtbi3); - - // pack results into byte - vtbc0 = vec_pack(vtbs0, vtbs1); - - //and with 1L to get true=1 instead of true=255 - vtuc0 = vec_and(vtbc0, oneVector); - vtuc0 = vec_sl(vtuc0, bitNumVec ); - - //or with original - vd = vec_or( vd, vtuc0 ); - - vec_st( vd, 0, &dst[i] ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] |= ( src0[i] <= constant ) << bitNum; - } -} -#endif /* ENABLE_COMPARES */ - -#ifdef ENABLE_MINMAX - -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( float &min, float &max, const float *src, const int count ) { - min = idMath::INFINITY; max = -idMath::INFINITY; -//#define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];} - - register vector float v0, v1, v2, v3; - register vector float maxVec, minVec, tempMin, tempMax; - register vector unsigned char permVec; - register vector float v0_low, v0_hi, v1_low, v1_hi; - vector unsigned char oneCharVector = (vector unsigned char)(1); - int i = 0; - - if ( count >= 4 ) { - - //calculate permute and do first load to - //get a starting point for min and max - permVec = vec_add( vec_lvsl( -1, (int*) &src[0] ), oneCharVector ); - v1_hi = vec_ld( 0, &src[0] ); - - maxVec = loadSplatUnalignedScalar( &max ); - minVec = loadSplatUnalignedScalar( &min ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load sources - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - // minimum - v2 = vec_min( v0, v1 ); - minVec = vec_min( minVec, v2 ); - // maximum - v3 = vec_max( v0, v1 ); - maxVec = vec_max( maxVec, v3 ); - } - - //minVec and maxVec hold the min/max elements from the array, but now - //we need to figure out which particular element it is - - tempMin = minVec; - tempMax = maxVec; - - // rotate vector around and compare to itself to find the real min/max - tempMin = vec_min( tempMin, vec_sld( tempMin, tempMin, 8 ) ); - tempMax = vec_max( tempMax, vec_sld( tempMax, tempMax, 8 ) ); - tempMin = vec_min( tempMin, vec_sld( tempMin, tempMin, 4 ) ); - tempMax = vec_max( tempMax, vec_sld( tempMax, tempMax, 4 ) ); - minVec = vec_splat( tempMin, 0 ); - maxVec = vec_splat( tempMax, 0 ); - vec_ste( minVec, 0, &min ); - vec_ste( maxVec, 0, &max ); - } - - //cleanup - for ( ; i < count; i++ ) { - if ( src[i] < min ) { - min = src[i]; - } - if ( src[i] > max ) { - max = src[i]; - } - } -} - -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { - min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY; -//#define OPER(X) const idVec2 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } - - idVec2 v; - int i = 0; - int j; - - const float *srcPtr = src[0].ToFloatPtr(); - register vector float vecLd1, vecLd2, vecLd3, vecLd4; - register vector float vecMin, vecMax; - - register vector float v0, v1, v2, v3; - - if ( count > 4 ) { - - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr ), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, srcPtr ); - - for ( i = 0, j = 0; i+7 < count; i += 8, j += 4) { - // load data - float *vecPtr = (float*)( srcPtr + (j*4) ); - vector float v0, v1, v2, v3; - - v0 = vecOld; - v1 = vec_ld( 15, vecPtr ); - v2 = vec_ld( 31, vecPtr ); - v3 = vec_ld( 47, vecPtr ); - vecOld = vec_ld( 63, vecPtr ); - - vecLd1 = vec_perm( v0, v1, permVec ); - vecLd2 = vec_perm( v1, v2, permVec ); - vecLd3 = vec_perm( v2, v3, permVec ); - vecLd4 = vec_perm( v3, vecOld, permVec ); - - // each of these vectors contains 2 elements - // looks like | X Y X Y | X Y X Y - v0 = vec_min( vecLd1, vecLd2 ); - v1 = vec_min( vecLd3, vecLd4 ); - v0 = vec_min( v0, v1 ); - - v2 = vec_max( vecLd1, vecLd2 ); - v3 = vec_max( vecLd3, vecLd4 ); - v2 = vec_max( v2, v3 ); - - // since its always X Y X Y we don't have to re-merge each time. we can wait - // until the end - vecMin = vec_min( v0, vecMin ); - vecMax = vec_max( v2, vecMax ); - } - - vecMin = vec_min( vecMin, vec_sld( vecMin, vecMin, 8 ) ); - vecMax = vec_max( vecMax, vec_sld( vecMax, vecMax, 8 ) ); - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMax, 0 ); - v3 = vec_splat( vecMax, 1 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &max[0] ); - vec_ste( v3, 0, &max[1] ); - } - - // cleanup - for ( ; i < count; i++ ) { - v = src[i]; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - } -} - -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; -//#define OPER(X) const idVec3 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } - - int i = 0; - const float *srcPtr = src[0].ToFloatPtr(); - idVec3 v; - - register vector float vecLd1, vecLd2, vecLd3; - register vector float vecMin, vecMax; - register vector float vecSrc1, vecSrc2, vecSrc3, vecSrc4; - register vector float vecMin1, vecMin2, vecMax1, vecMax2; - - if ( count >= 4 ) { - - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, srcPtr), (vector unsigned char)(1) ); - vector float vecOld = vec_ld( 0, srcPtr ); - - // 4 elements at a time - for ( ; i+3 < count; i += 4 ) { - float *vecPtr = (float*)( srcPtr + (i*3) ); - vector float v0, v1, v2; - - v0 = vecOld; - v1 = vec_ld( 15, vecPtr ); - v2 = vec_ld( 31, vecPtr ); - vecOld = vec_ld( 47, vecPtr ); - - vecLd1 = vec_perm( v0, v1, permVec ); - vecLd2 = vec_perm( v1, v2, permVec ); - vecLd3 = vec_perm( v2, vecOld, permVec ); - - // put each idVec3 into its own vector as X Y Z (crap) - vecSrc1 = vecLd1; - vecSrc2 = vec_sld( vecLd1, vecLd2, 12 ); - vecSrc3 = vec_sld( vecLd2, vecLd3, 8 ); - vecSrc4 = vec_sld( vecLd3, vecLd3, 4 ); - - // do min and max - vecMin1 = vec_min( vecSrc1, vecSrc2 ); - vecMin2 = vec_min( vecSrc3, vecSrc4 ); - vecMin1 = vec_min( vecMin1, vecMin2 ); - vecMin = vec_min( vecMin, vecMin1 ); - - vecMax1 = vec_max( vecSrc1, vecSrc2 ); - vecMax2 = vec_max( vecSrc3, vecSrc4 ); - vecMax1 = vec_max( vecMax1, vecMax2 ); - vecMax = vec_max( vecMax1, vecMax ); - } - - // store results - vector float v0, v1, v2, v3, v4, v5; - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMin, 2 ); - v3 = vec_splat( vecMax, 0 ); - v4 = vec_splat( vecMax, 1 ); - v5 = vec_splat( vecMax, 2 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &min[2] ); - vec_ste( v3, 0, &max[0] ); - vec_ste( v4, 0, &max[1] ); - vec_ste( v5, 0, &max[2] ); - } - - // cleanup - for ( ; i < count; i ++ ) { - v = src[i]; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - if ( v[2] < min[2] ) { - min[2] = v[2]; - } - if ( v[2] > max[2] ) { - max[2] = v[2]; - } - } -} - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { - - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; - idVec3 v; - int i = 0; - register vector float vecMin, vecMax; - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecMin1, vecMin2, vecMax1, vecMax2; - - if ( count >= 4 ) { - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - vector unsigned char vertPerm1 = vec_add( vec_lvsl( -1, (float*) src[i].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vector unsigned char vertPerm2 = vec_add( vec_lvsl( -1, (float*) src[i+1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vector unsigned char vertPerm3 = vec_add( vec_lvsl( -1, (float*) src[i+2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vector unsigned char vertPerm4 = vec_add( vec_lvsl( -1, (float*) src[i+3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - - for ( ; i+3 < count; i += 4) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 11, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 11, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 11, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 11, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v2 = vec_perm( v2, v3, vertPerm2 ); - v4 = vec_perm( v4, v5, vertPerm3 ); - v6 = vec_perm( v6, v7, vertPerm4 ); - - vecMin1 = vec_min( v0, v2 ); - vecMin2 = vec_min( v4, v6 ); - vecMin1 = vec_min( vecMin1, vecMin2 ); - vecMin = vec_min( vecMin, vecMin1 ); - - vecMax1 = vec_max( v0, v2 ); - vecMax2 = vec_max( v4, v6 ); - vecMax1 = vec_max( vecMax1, vecMax2 ); - vecMax = vec_max( vecMax, vecMax1 ); - } - - // now we have min/max vectors in X Y Z form, store out - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMin, 2 ); - v3 = vec_splat( vecMax, 0 ); - v4 = vec_splat( vecMax, 1 ); - v5 = vec_splat( vecMax, 2 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &min[2] ); - vec_ste( v3, 0, &max[0] ); - vec_ste( v4, 0, &max[1] ); - vec_ste( v5, 0, &max[2] ); - } - - // cleanup - for ( ; i < count; i++ ) { - v = src[i].xyz; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - - if ( v[2] > max[2] ) { - max[2] = v[2]; - } - - if ( v[2] < min[2] ) { - min[2] = v[2]; - } - } -} -#else -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { - - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; - idVec3 v; - int i = 0; - register vector float vecMin, vecMax; - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecMin1, vecMin2, vecMax1, vecMax2; - - if ( count >= 4 ) { - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - for ( ; i+3 < count; i += 4) { - const float *vertPtr = src[i].xyz.ToFloatPtr(); - const float *vertPtr2 = src[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = src[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = src[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - - vecMin1 = vec_min( v0, v2 ); - vecMin2 = vec_min( v4, v6 ); - vecMin1 = vec_min( vecMin1, vecMin2 ); - vecMin = vec_min( vecMin, vecMin1 ); - - vecMax1 = vec_max( v0, v2 ); - vecMax2 = vec_max( v4, v6 ); - vecMax1 = vec_max( vecMax1, vecMax2 ); - vecMax = vec_max( vecMax, vecMax1 ); - } - - // now we have min/max vectors in X Y Z form, store out - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMin, 2 ); - v3 = vec_splat( vecMax, 0 ); - v4 = vec_splat( vecMax, 1 ); - v5 = vec_splat( vecMax, 2 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &min[2] ); - vec_ste( v3, 0, &max[0] ); - vec_ste( v4, 0, &max[1] ); - vec_ste( v5, 0, &max[2] ); - } - - // cleanup - for ( ; i < count; i++ ) { - v = src[i].xyz; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - - if ( v[2] > max[2] ) { - max[2] = v[2]; - } - - if ( v[2] < min[2] ) { - min[2] = v[2]; - } - } -} - -#endif /* DRAWVERT_PADDED */ - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; - - idVec3 v; - int i = 0; - - register vector float vecMin, vecMax; - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecMin1, vecMin2, vecMax1, vecMax2; - - if ( count >= 4 ) { - - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - vector unsigned char vertPerm1; - vector unsigned char vertPerm2; - vector unsigned char vertPerm3; - vector unsigned char vertPerm4; - - for ( ; i+3 < count; i += 4) { - const float *vertPtr = src[indexes[i]].xyz.ToFloatPtr(); - const float *vertPtr2 = src[indexes[i+1]].xyz.ToFloatPtr(); - const float *vertPtr3 = src[indexes[i+2]].xyz.ToFloatPtr(); - const float *vertPtr4 = src[indexes[i+3]].xyz.ToFloatPtr(); - - vertPerm1 = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, vertPtr2 ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, vertPtr3 ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, vertPtr4 ), (vector unsigned char)(1) ); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v2 = vec_perm( v2, v3, vertPerm2 ); - v4 = vec_perm( v4, v5, vertPerm3 ); - v6 = vec_perm( v6, v7, vertPerm4 ); - - vecMin1 = vec_min( v0, v2 ); - vecMin2 = vec_min( v4, v6 ); - vecMin1 = vec_min( vecMin1, vecMin2 ); - vecMin = vec_min( vecMin, vecMin1 ); - - vecMax1 = vec_max( v0, v2 ); - vecMax2 = vec_max( v4, v6 ); - vecMax1 = vec_max( vecMax1, vecMax2 ); - vecMax = vec_max( vecMax, vecMax1 ); - } - - // now we have min/max vectors in X Y Z form, store out - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMin, 2 ); - v3 = vec_splat( vecMax, 0 ); - v4 = vec_splat( vecMax, 1 ); - v5 = vec_splat( vecMax, 2 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &min[2] ); - vec_ste( v3, 0, &max[0] ); - vec_ste( v4, 0, &max[1] ); - vec_ste( v5, 0, &max[2] ); - } - - // cleanup - for ( ; i < count; i++ ) { - v = src[indexes[i]].xyz; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - - if ( v[2] > max[2] ) { - max[2] = v[2]; - } - - if ( v[2] < min[2] ) { - min[2] = v[2]; - } - } -} -#else -/* -============ -idSIMD_AltiVec::MinMax -============ -*/ -void VPCALL idSIMD_AltiVec::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; - - idVec3 v; - int i = 0; - - register vector float vecMin, vecMax; - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float vecMin1, vecMin2, vecMax1, vecMax2; - - if ( count >= 4 ) { - - vecMin = (vector float)(FLT_MAX); - vecMax = (vector float)(FLT_MIN); - - vector unsigned char vertPerm1; - vector unsigned char vertPerm2; - vector unsigned char vertPerm3; - vector unsigned char vertPerm4; - - for ( ; i+3 < count; i += 4) { - const float *vertPtr = src[indexes[i]].xyz.ToFloatPtr(); - const float *vertPtr2 = src[indexes[i+1]].xyz.ToFloatPtr(); - const float *vertPtr3 = src[indexes[i+2]].xyz.ToFloatPtr(); - const float *vertPtr4 = src[indexes[i+3]].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - - vecMin1 = vec_min( v0, v2 ); - vecMin2 = vec_min( v4, v6 ); - vecMin1 = vec_min( vecMin1, vecMin2 ); - vecMin = vec_min( vecMin, vecMin1 ); - - vecMax1 = vec_max( v0, v2 ); - vecMax2 = vec_max( v4, v6 ); - vecMax1 = vec_max( vecMax1, vecMax2 ); - vecMax = vec_max( vecMax, vecMax1 ); - } - - // now we have min/max vectors in X Y Z form, store out - v0 = vec_splat( vecMin, 0 ); - v1 = vec_splat( vecMin, 1 ); - v2 = vec_splat( vecMin, 2 ); - v3 = vec_splat( vecMax, 0 ); - v4 = vec_splat( vecMax, 1 ); - v5 = vec_splat( vecMax, 2 ); - - vec_ste( v0, 0, &min[0] ); - vec_ste( v1, 0, &min[1] ); - vec_ste( v2, 0, &min[2] ); - vec_ste( v3, 0, &max[0] ); - vec_ste( v4, 0, &max[1] ); - vec_ste( v5, 0, &max[2] ); - } - - // cleanup - for ( ; i < count; i++ ) { - v = src[indexes[i]].xyz; - - if ( v[0] < min[0] ) { - min[0] = v[0]; - } - if ( v[0] > max[0] ) { - max[0] = v[0]; - } - - if ( v[1] < min[1] ) { - min[1] = v[1]; - } - if ( v[1] > max[1] ) { - max[1] = v[1]; - } - - if ( v[2] > max[2] ) { - max[2] = v[2]; - } - - if ( v[2] < min[2] ) { - min[2] = v[2]; - } - } -} - - -#endif /* DRAWVERT_PADDED */ - -#endif /* ENABLE_MINMAX */ - -#ifdef ENABLE_CLAMP - -/* -============ -idSIMD_AltiVec::Clamp -============ -*/ -void VPCALL idSIMD_AltiVec::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { -//#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)] > max ? max : src[(X)]; - register vector float v0, v1, v2, v3, v4, v5; - register vector unsigned char permVec; - register vector float v0_low, v0_hi, v1_low, v1_hi; - vector unsigned char oneVector = (vector unsigned char)(1); - register vector float minVec, maxVec; - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src[i] < min ? min : src[i] > max ? max : src[i]; - } - - //splat min/max into a vector - minVec = loadSplatUnalignedScalar( &min ); - maxVec = loadSplatUnalignedScalar( &max ); - - //calculate permute and do first load - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); - v1_hi = vec_ld( 0, &src[i] ); - - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - //apply minimum - v2 = vec_max( v0, minVec ); - v3 = vec_max( v1, minVec ); - - //apply maximum - v4 = vec_min( v2, maxVec ); - v5 = vec_min( v3, maxVec ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src[i] < min ? min : src[i] > max ? max : src[i]; - } -} - -/* -============ -idSIMD_AltiVec::ClampMin -============ -*/ -void VPCALL idSIMD_AltiVec::ClampMin( float *dst, const float *src, const float min, const int count ) { -//#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)]; - register vector float v0, v1, v2, v3; - register vector unsigned char permVec; - register vector float v0_low, v0_hi, v1_low, v1_hi; - register vector float constVec; - vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src[i] < min ? min : src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &min ); - - //calculate permute and do first load - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); - v1_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - - v2 = vec_max( v0, constVec ); - v3 = vec_max( v1, constVec ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src[i] < min ? min : src[i]; - } - } - -/* -============ -idSIMD_AltiVec::ClampMax -============ -*/ -void VPCALL idSIMD_AltiVec::ClampMax( float *dst, const float *src, const float max, const int count ) { -//#define OPER(X) dst[(X)] = src[(X)] > max ? max : src[(X)]; - register vector float v0, v1, v2, v3; - register vector unsigned char permVec; - register vector float constVec; - register vector float v0_low, v0_hi, v1_low, v1_hi; - vector unsigned char oneVector = (vector unsigned char)(1); - int i = 0; - - //handle unaligned at start - for ( ; NOT_16BYTE_ALIGNED( dst[i] ) && ( i < count ); i++ ) { - dst[i] = src[i] < max ? max : src[i]; - } - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &max ); - - //calculate permute and do first load - permVec = vec_add( vec_lvsl( -1, (int*) &src[i] ), oneVector ); - v1_hi = vec_ld( 0, &src[i] ); - - //vectorize! - for ( ; i+7 < count; i += 8 ) { - //load source - v0_low = v1_hi; - v0_hi = vec_ld( 15, &src[i] ); - v1_low = v0_hi; - v1_hi = vec_ld( 31, &src[i] ); - - v0 = vec_perm( v0_low, v0_hi, permVec ); - v1 = vec_perm( v1_low, v1_hi, permVec ); - v2 = vec_min( v0, constVec ); - v3 = vec_min( v1, constVec ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - //handle cleanup - for ( ; i < count ; i++ ) { - dst[i] = src[i] < max ? max : src[i]; - } -} - -#endif /* ENABLE_CLAMP */ - -#ifdef ENABLE_16ROUTINES - -/* -============ -idSIMD_AltiVec::Zero16 -============ -*/ -void VPCALL idSIMD_AltiVec::Zero16( float *dst, const int count ) { - memset( dst, 0, count * sizeof( float ) ); -} - -/* -============ -idSIMD_AltiVec::Negate16 - - Assumptions: - dst is aligned -============ -*/ -void VPCALL idSIMD_AltiVec::Negate16( float *dst, const int count ) { -//#define OPER(X) ptr[(X)] ^= ( 1 << 31 ) // IEEE 32 bits float sign bit - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - int i = 0; - vector float v0, v1, v2, v3; - - //know its 16-byte aligned - for ( ; i + 7 < count2; i += 8 ) { - v0 = vec_ld( 0, &dst[i] ); - v1 = vec_ld( 16, &dst[i] ); - - v2 = vec_sub( (vector float)(0), v0 ); - v3 = vec_sub( (vector float)(0), v1 ); - - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &dst[i] ); - v1 = vec_sub( (vector float)(0), v0 ); - vec_st( v1, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::Copy16 -============ -*/ -void VPCALL idSIMD_AltiVec::Copy16( float *dst, const float *src, const int count ) { -//#define OPER(X) dst[(X)] = src[(X)] - memcpy( dst, src, sizeof(float) * count ); -} - -/* -============ -idSIMD_AltiVec::Add16 - - Assumptions: - Assumes dst, src1, src2 all start at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::Add16( float *dst, const float *src1, const float *src2, const int count ) { -//#define OPER(X) dst[(X)] = src1[(X)] + src2[(X)] - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // src1 is aligned - assert( IS_16BYTE_ALIGNED( src1[0] ) ); - // src2 is aligned - assert( IS_16BYTE_ALIGNED( src2[0] ) ); - - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - register vector float v0, v1, v2, v3, v4, v5; - int i = 0; - - //know all data is 16-byte aligned, so vectorize! - for ( ; i+7 < count2; i += 8 ) { - //load sources - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_ld( 16, &src1[i] ); - v2 = vec_ld( 0, &src2[i] ); - v3 = vec_ld( 16, &src2[i] ); - v4 = vec_add( v0, v2 ); - v5 = vec_add( v1, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_ld( 0, &src2[i] ); - v2 = vec_add( v0, v1 ); - vec_st( v2, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::Sub16 - - Assumptions: - Assumes that dst, src1, and src2 all start at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::Sub16( float *dst, const float *src1, const float *src2, const int count ) { -//#define OPER(X) dst[(X)] = src1[(X)] - src2[(X)] - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // src1 is aligned - assert( IS_16BYTE_ALIGNED( src1[0] ) ); - // src2 is aligned - assert( IS_16BYTE_ALIGNED( src2[0] ) ); - - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - register vector float v0, v1, v2, v3, v4, v5; - int i = 0; - - //know data is aligned, so vectorize! - for ( ; i+7 < count2; i += 8 ) { - //load sources - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_ld( 16, &src1[i] ); - v2 = vec_ld( 0, &src2[i] ); - v3 = vec_ld( 16, &src2[i] ); - v4 = vec_sub( v0, v2 ); - v5 = vec_sub( v1, v3 ); - - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_ld( 0, &src2[i] ); - v2 = vec_sub( v0, v1 ); - vec_st( v2, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::Mul16 - - Assumptions: - Assumes that dst and src1 start at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::Mul16( float *dst, const float *src1, const float constant, const int count ) { -//#define OPER(X) dst[(X)] = src1[(X)] * constant - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // src1 is aligned - assert( IS_16BYTE_ALIGNED( src1[0] ) ); - - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - register vector float v0, v1, v2, v3; - register vector float constVec; - register vector float zeroVector = (vector float)(0.0); - int i = 0; - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //know data is aligned, so vectorize! - for ( ; i+7 < count2; i += 8 ) { - //load source - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_ld( 16, &src1[i] ); - v2 = vec_madd( constVec, v0, zeroVector ); - v3 = vec_madd( constVec, v1, zeroVector ); - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &src1[i] ); - v1 = vec_madd( constVec, v0, zeroVector ); - vec_st( v1, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::AddAssign16 - - Assumptions: - Assumes that dst and src start at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::AddAssign16( float *dst, const float *src, const int count ) { -//#define OPER(X) dst[(X)] += src[(X)] - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // src is aligned - assert( IS_16BYTE_ALIGNED( src[0] ) ); - - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - register vector float v0, v1, v2, v3, v4, v5; - int i = 0; - - //vectorize! - for ( ; i+7 < count2; i += 8 ) { - v0 = vec_ld( 0, &src[i] ); - v1 = vec_ld( 16, &src[i] ); - v2 = vec_ld( 0, &dst[i] ); - v3 = vec_ld( 16, &dst[i] ); - v4 = vec_add( v0, v2 ); - v5 = vec_add( v1, v3 ); - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &src[i] ); - v1 = vec_ld( 0, &dst[i] ); - v2 = vec_add( v0, v1 ); - vec_st( v2, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::SubAssign16 - - Assumptions: - Assumes that dst and src start at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::SubAssign16( float *dst, const float *src, const int count ) { -//#define OPER(X) dst[(X)] -= src[(X)] - register vector float v0, v1, v2, v3, v4, v5; - int i=0; - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // src is aligned - assert( IS_16BYTE_ALIGNED( src[0] ) ); - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - //vectorize! - for ( ; i+7 < count2; i += 8 ) { - v0 = vec_ld( 0, &src[i] ); - v1 = vec_ld( 16, &src[i] ); - v2 = vec_ld( 0, &dst[i] ); - v3 = vec_ld( 16, &dst[i] ); - v4 = vec_sub( v2, v0 ); - v5 = vec_sub( v3, v1 ); - ALIGNED_STORE2( &dst[i], v4, v5 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &src[i] ); - v1 = vec_ld( 0, &dst[i] ); - v2 = vec_sub( v1, v0 ); - vec_st( v2, 0, &dst[i] ); - } -} - -/* -============ -idSIMD_AltiVec::MulAssign16 - - Assumptions: - Assumes that dst starts at aligned address and count is multiple of 4 -============ -*/ -void VPCALL idSIMD_AltiVec::MulAssign16( float *dst, const float constant, const int count ) { -//#define OPER(X) dst[(X)] *= constant - - // dst is aligned - assert( IS_16BYTE_ALIGNED( dst[0] ) ); - // round count up to next 4 if needbe - int count2 = ( count + 3 ) & ~3; - - register vector float v0, v1, v2, v3; - register vector float constVec; - int i = 0; - register vector float zeroVector = (vector float)(0.0); - - //splat constant into a vector - constVec = loadSplatUnalignedScalar( &constant ); - - //vectorize! - for ( ; i+7 < count2; i += 8 ) { - v0 = vec_ld( 0, &dst[i] ); - v1 = vec_ld( 16, &dst[i] ); - v2 = vec_madd( v0, constVec, zeroVector ); - v3 = vec_madd( v1, constVec, zeroVector ); - ALIGNED_STORE2( &dst[i], v2, v3 ); - } - - for ( ; i < count2; i += 4 ) { - v0 = vec_ld( 0, &dst[i] ); - v1 = vec_madd( v0, constVec, zeroVector ); - vec_st( v1, 0, &dst[i] ); - } -} - -#endif /* ENABLE_16ROUTINES */ - -#ifdef ENABLE_LOWER_TRIANGULAR - -/* -============ -idSIMD_AltiVec::MatX_LowerTriangularSolve - - solves x in L * x = b for the first n rows of L - if skip > 0 the first skip elements of x are assumed to be valid already - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ - -void VPCALL idSIMD_AltiVec::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { - - int i, j; - const float *lptr; - const float *lptr2; - const float *lptr3; - const float *lptr4; - float sum; - float sum2; - float sum3; - float sum4; - float tempSum; - float tempSum2; - float tempSum3; - float tempSum4; - vector float vecSum1 = (vector float)(0.0); - vector float vecSum2 = (vector float)(0.0); - vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; - vector float zeroVector = (vector float)(0.0); - vector float vecSum3, vecSum4, vecSum5, vecSum6, vecSum7, vecSum8; - - vector unsigned char vecPermX = vec_add( vec_lvsl( -1, &x[0] ), (vector unsigned char)(1) ); - - // unrolled this loop a bit - for ( i = skip; i+3 < n; i+=4 ) { - sum = b[i]; - sum2 = b[i+1]; - sum3 = b[i+2]; - sum4 = b[i+3]; - - vecSum1 = zeroVector; - vecSum2 = zeroVector; - vecSum3 = vecSum4 = vecSum5 = vecSum6 = vecSum7 = vecSum8 = zeroVector; - lptr = L[i]; - lptr2 = L[i+1]; - lptr3 = L[i+2]; - lptr4 = L[i+3]; - - vector unsigned char vecPermLptr1 = vec_add( vec_lvsl( -1, lptr ), (vector unsigned char)(1) ); - vector unsigned char vecPermLptr2 = vec_add( vec_lvsl( -1, lptr2 ), (vector unsigned char)(1) ); - vector unsigned char vecPermLptr3 = vec_add( vec_lvsl( -1, lptr3 ), (vector unsigned char)(1) ); - vector unsigned char vecPermLptr4 = vec_add( vec_lvsl( -1, lptr4 ), (vector unsigned char)(1) ); - - for ( j = 0 ; j+7 < i; j+=8 ) { - - v0 = vec_ld( 0, &x[j] ); - v1 = vec_ld( 15, &x[j] ); - vector float vecExtraX = vec_ld( 31, &x[j] ); - v0 = vec_perm( v0, v1, vecPermX ); - v1 = vec_perm( v1, vecExtraX, vecPermX ); - - v2 = vec_ld( 0, lptr + j ); - v3 = vec_ld( 15, lptr + j ); - vector float vecExtra1 = vec_ld( 31, lptr + j ); - v2 = vec_perm( v2, v3, vecPermLptr1 ); - v3 = vec_perm( v3, vecExtra1, vecPermLptr1 ); - - v4 = vec_ld( 0, lptr2 + j ); - v5 = vec_ld( 15, lptr2 + j ); - vector float vecExtra2 = vec_ld( 31, lptr2 + j ); - v4 = vec_perm( v4, v5, vecPermLptr2 ); - v5 = vec_perm( v5, vecExtra2, vecPermLptr2 ); - - v6 = vec_ld( 0, lptr3 + j ); - v7 = vec_ld( 15, lptr3 + j ); - vector float vecExtra3 = vec_ld( 31, lptr3 + j ); - v6 = vec_perm( v6, v7, vecPermLptr3 ); - v7 = vec_perm( v7, vecExtra3, vecPermLptr3 ); - - v8 = vec_ld( 0, lptr4 + j ); - v9 = vec_ld( 15, lptr4 + j ); - vector float vecExtra4 = vec_ld( 31, lptr4 + j ); - v8 = vec_perm( v8, v9, vecPermLptr4 ); - v9 = vec_perm( v9, vecExtra4, vecPermLptr4 ); - - vecSum1 = vec_madd( v2, v0, vecSum1 ); - vecSum2 = vec_madd( v3, v1, vecSum2 ); - - vecSum3 = vec_madd( v4, v0, vecSum3 ); - vecSum4 = vec_madd( v5, v1, vecSum4 ); - - vecSum5 = vec_madd( v6, v0, vecSum5 ); - vecSum6 = vec_madd( v7, v1, vecSum6 ); - - vecSum7 = vec_madd( v8, v0, vecSum7 ); - vecSum8 = vec_madd( v9, v1, vecSum8 ); - } - - // if we ran the unrolled code, we need to sum accross the vectors - // to find out how much to subtract from sum - if ( j > 0 ) { - vecSum1 = vec_add( vecSum1, vecSum2 ); - vecSum3 = vec_add( vecSum3, vecSum4 ); - vecSum5 = vec_add( vecSum5, vecSum6 ); - vecSum7 = vec_add( vecSum7, vecSum8 ); - //sum accross the vectors - vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 8 ) ); - vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 4 ) ); - - vecSum3 = vec_add( vecSum3, vec_sld( vecSum3, vecSum3, 8 ) ); - vecSum3 = vec_add( vecSum3, vec_sld( vecSum3, vecSum3, 4 ) ); - - vecSum5 = vec_add( vecSum5, vec_sld( vecSum5, vecSum5, 8 ) ); - vecSum5 = vec_add( vecSum5, vec_sld( vecSum5, vecSum5, 4 ) ); - - vecSum7 = vec_add( vecSum7, vec_sld( vecSum7, vecSum7, 8 ) ); - vecSum7 = vec_add( vecSum7, vec_sld( vecSum7, vecSum7, 4 ) ); - - //move the result to the FPU - vec_ste( vec_splat( vecSum1, 0 ), 0, &tempSum ); - vec_ste( vec_splat( vecSum3, 0 ), 0, &tempSum2 ); - vec_ste( vec_splat( vecSum5, 0 ), 0, &tempSum3 ); - vec_ste( vec_splat( vecSum7, 0 ), 0, &tempSum4 ); - - sum -= tempSum; - sum2 -= tempSum2; - sum3 -= tempSum3; - sum4 -= tempSum4; - } - - //cleanup - for ( ; j < i; j++ ) { - sum -= lptr[j] * x[j]; - sum2 -= lptr2[j] * x[j]; - sum3 -= lptr3[j] * x[j]; - sum4 -= lptr4[j] * x[j]; - } - - // store the 4 results at a time - sum2 -= ( lptr2[i] * sum ); - sum3 = sum3 - ( lptr3[i+1] * sum2 ) - ( lptr3[i] * sum ); - sum4 = sum4 - ( lptr4[i+2] * sum3 ) - ( lptr4[i+1] * sum2 ) - ( lptr4[i] * sum ); - - x[i] = sum; - x[i+1] = sum2; - x[i+2] = sum3; - x[i+3] = sum4; - } - - // cleanup - for ( ; i < n; i++ ) { - sum = b[i]; - vecSum1 = zeroVector; - vecSum2 = zeroVector; - lptr = L[i]; - vector unsigned char vecPermLptr = vec_add( vec_lvsl( -1, lptr ), (vector unsigned char)(1) ); - - for ( j = 0 ; j+7 < i; j+=8 ) { - - v0 = vec_ld( 0, &x[j] ); - v2 = vec_ld( 15, &x[j] ); - vector float vecExtraX = vec_ld( 31, &x[j] ); - v0 = vec_perm( v0, v2, vecPermX ); - v2 = vec_perm( v2, vecExtraX, vecPermX ); - - v1 = vec_ld( 0, lptr + j ); - v3 = vec_ld( 15, lptr + j ); - vector float vecExtra = vec_ld( 31, lptr + j ); - v1 = vec_perm( v1, v3, vecPermLptr ); - v3 = vec_perm( v3, vecExtra, vecPermLptr ); - - vecSum1 = vec_madd( v1, v0, vecSum1 ); - vecSum2 = vec_madd( v3, v2, vecSum2 ); - } - - // if we ran the unrolled code, we need to sum accross the vectors - // to find out how much to subtract from sum - if ( j > 0 ) { - //sum accross the vectors - vecSum1 = vec_add( vecSum1, vecSum2 ); - vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 8 ) ); - vecSum1 = vec_add( vecSum1, vec_sld( vecSum1, vecSum1, 4 ) ); - - //move the result to the FPU - vec_ste( vec_splat( vecSum1, 0 ), 0, &tempSum ); - sum -= tempSum; - } - - //cleanup - for ( ; j < i; j++ ) { - sum -= lptr[j] * x[j]; - } - x[i] = sum; - } -} - -/* -============ -idSIMD_AltiVec::MatX_LowerTriangularSolveTranspose - - solves x in L.Transpose() * x = b for the first n rows of L - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_AltiVec::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { - - int nc; - const float *lptr; - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - float x0, x1, x2, x3, x4, x5, x6; - // unrolled cases for n < 8 - if ( n < 8 ) { - switch( n ) { - // using local variables to avoid aliasing issues - case 0: - return; - case 1: - x[0] = b[0]; - return; - case 2: - x1 = b[1]; - x0 = b[0] - lptr[1*nc+0] * x1; - - x[1] = x1; - x[0] = x0; - return; - case 3: - x2 = b[2]; - x1 = b[1] - lptr[2*nc+1] * x2; - x0 = b[0] - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; - - x[2] = x2; - x[1] = x1; - x[0] = x0; - return; - case 4: - x3 = b[3]; - x2 = b[2] - lptr[3*nc+2] * x3; - x1 = b[1] - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; - x0 = b[0] - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; - - x[3] = x3; - x[2] = x2; - x[1] = x1; - x[0] = x0; - - return; - case 5: - x4 = b[4]; - x3 = b[3] - lptr[4*nc+3] * x4; - x2 = b[2] - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; - x1 = b[1] - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; - x0 = b[0] - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; - - x[4] = x4; - x[3] = x3; - x[2] = x2; - x[1] = x1; - x[0] = x0; - return; - case 6: - x5 = b[5]; - x4 = b[4] - lptr[5*nc+4] * x5; - x3 = b[3] - lptr[5*nc+3] * x5 - lptr[4*nc+3] * x4; - x2 = b[2] - lptr[5*nc+2] * x5 - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; - x1 = b[1] - lptr[5*nc+1] * x5 - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; - x0 = b[0] - lptr[5*nc+0] * x5 - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; - - x[5] = x5; - x[4] = x4; - x[3] = x3; - x[2] = x2; - x[1] = x1; - x[0] = x0; - - return; - case 7: - x6 = b[6]; - x5 = b[5] - lptr[6*nc+5] * x6; - x4 = b[4] - lptr[6*nc+4] * x6 - lptr[5*nc+4] * x5; - x3 = b[3] - lptr[6*nc+3] * x6 - lptr[5*nc+3] * x5 - lptr[4*nc+3] * x4; - x2 = b[2] - lptr[6*nc+2] * x6 - lptr[5*nc+2] * x5 - lptr[4*nc+2] * x4 - lptr[3*nc+2] * x3; - x1 = b[1] - lptr[6*nc+1] * x6 - lptr[5*nc+1] * x5 - lptr[4*nc+1] * x4 - lptr[3*nc+1] * x3 - lptr[2*nc+1] * x2; - x0 = b[0] - lptr[6*nc+0] * x6 - lptr[5*nc+0] * x5 - lptr[4*nc+0] * x4 - lptr[3*nc+0] * x3 - lptr[2*nc+0] * x2 - lptr[1*nc+0] * x1; - - x[6] = x6; - x[5] = x5; - x[4] = x4; - x[3] = x3; - x[2] = x2; - x[1] = x1; - x[0] = x0; - return; - } - return; - } - - int i, j; - register float s0, s1, s2, s3; - float *xptr; - - lptr = L.ToFloatPtr() + n * nc + n - 4; - xptr = x + n; - - // process 4 rows at a time - for ( i = n; i >= 4; i -= 4 ) { - s0 = b[i-4]; - s1 = b[i-3]; - s2 = b[i-2]; - s3 = b[i-1]; - // process 4x4 blocks - for ( j = 0; j < n-i; j += 4 ) { - s0 -= lptr[(j+0)*nc+0] * xptr[j+0]; - s1 -= lptr[(j+0)*nc+1] * xptr[j+0]; - s2 -= lptr[(j+0)*nc+2] * xptr[j+0]; - s3 -= lptr[(j+0)*nc+3] * xptr[j+0]; - s0 -= lptr[(j+1)*nc+0] * xptr[j+1]; - s1 -= lptr[(j+1)*nc+1] * xptr[j+1]; - s2 -= lptr[(j+1)*nc+2] * xptr[j+1]; - s3 -= lptr[(j+1)*nc+3] * xptr[j+1]; - s0 -= lptr[(j+2)*nc+0] * xptr[j+2]; - s1 -= lptr[(j+2)*nc+1] * xptr[j+2]; - s2 -= lptr[(j+2)*nc+2] * xptr[j+2]; - s3 -= lptr[(j+2)*nc+3] * xptr[j+2]; - s0 -= lptr[(j+3)*nc+0] * xptr[j+3]; - s1 -= lptr[(j+3)*nc+1] * xptr[j+3]; - s2 -= lptr[(j+3)*nc+2] * xptr[j+3]; - s3 -= lptr[(j+3)*nc+3] * xptr[j+3]; - } - // process left over of the 4 rows - s0 -= lptr[0-1*nc] * s3; - s1 -= lptr[1-1*nc] * s3; - s2 -= lptr[2-1*nc] * s3; - s0 -= lptr[0-2*nc] * s2; - s1 -= lptr[1-2*nc] * s2; - s0 -= lptr[0-3*nc] * s1; - // store result - xptr[-4] = s0; - xptr[-3] = s1; - xptr[-2] = s2; - xptr[-1] = s3; - // update pointers for next four rows - lptr -= 4 + 4 * nc; - xptr -= 4; - } - // process left over rows - for ( i--; i >= 0; i-- ) { - s0 = b[i]; - lptr = L[0] + i; - for ( j = i + 1; j < n; j++ ) { - s0 -= lptr[j*nc] * x[j]; - } - x[i] = s0; - } -} - -/* -============ -idSIMD_AltiVec::MatX_LDLTFactor -============ -*/ -bool VPCALL idSIMD_AltiVec::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { - int i, j, k, nc; - float *v, *diag, *mptr; - float s0, s1, s2, s3, sum, d; - float s0_2, s1_2, s2_2, s3_2, sum_2; - float *mptr2; - - v = (float *) _alloca16( n * sizeof( float ) ); - diag = (float *) _alloca16( n * sizeof( float ) ); - - nc = mat.GetNumColumns(); - - if ( n <= 0 ) { - return true; - } - - mptr = mat[0]; - - sum = mptr[0]; - - if ( sum == 0.0f ) { - return false; - } - - diag[0] = sum; - invDiag[0] = d = 1.0f / sum; - - if ( n <= 1 ) { - return true; - } - - mptr = mat[0]; - for ( j = 1; j < n; j++ ) { - mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; - } - - mptr = mat[1]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - sum = mptr[1] - s0; - - if ( sum == 0.0f ) { - return false; - } - - mat[1][1] = sum; - diag[1] = sum; - invDiag[1] = d = 1.0f / sum; - - if ( n <= 2 ) { - return true; - } - - mptr = mat[0]; - for ( j = 2; j < n; j++ ) { - mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; - } - - mptr = mat[2]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - sum = mptr[2] - s0 - s1; - - if ( sum == 0.0f ) { - return false; - } - - mat[2][2] = sum; - diag[2] = sum; - invDiag[2] = d = 1.0f / sum; - - if ( n <= 3 ) { - return true; - } - - mptr = mat[0]; - for ( j = 3; j < n; j++ ) { - mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; - } - - mptr = mat[3]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - sum = mptr[3] - s0 - s1 - s2; - - if ( sum == 0.0f ) { - return false; - } - - mat[3][3] = sum; - diag[3] = sum; - invDiag[3] = d = 1.0f / sum; - - if ( n <= 4 ) { - return true; - } - - mptr = mat[0]; - for ( j = 4; j < n; j++ ) { - mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; - } - - for ( i = 4; i < n; i++ ) { - - mptr = mat[i]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; - for ( k = 4; k < i-3; k += 4 ) { - v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; - v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; - v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; - } - switch( i - k ) { - case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; - case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; - } - sum = s3; - sum += s2; - sum += s1; - sum += s0; - sum = mptr[i] - sum; - - if ( sum == 0.0f ) { - return false; - } - - mat[i][i] = sum; - diag[i] = sum; - invDiag[i] = d = 1.0f / sum; - - if ( i + 1 >= n ) { - return true; - } - - // unrolling madness! - mptr = mat[i+1]; - mptr2 = mat[i+1] + nc; - - for ( j = i+1; j+1 < n; j+=2 ) { - s0 = mptr[0] * v[0]; - s1 = mptr[1] * v[1]; - s2 = mptr[2] * v[2]; - s3 = mptr[3] * v[3]; - - s0_2 = mptr2[0] * v[0]; - s1_2 = mptr2[1] * v[1]; - s2_2 = mptr2[2] * v[2]; - s3_2 = mptr2[3] * v[3]; - - for ( k = 4; k < i-7; k += 8 ) { - s0 += mptr[k+0] * v[k+0]; - s1 += mptr[k+1] * v[k+1]; - s2 += mptr[k+2] * v[k+2]; - s3 += mptr[k+3] * v[k+3]; - s0 += mptr[k+4] * v[k+4]; - s1 += mptr[k+5] * v[k+5]; - s2 += mptr[k+6] * v[k+6]; - s3 += mptr[k+7] * v[k+7]; - - s0_2 += mptr2[k+0] * v[k+0]; - s1_2 += mptr2[k+1] * v[k+1]; - s2_2 += mptr2[k+2] * v[k+2]; - s3_2 += mptr2[k+3] * v[k+3]; - s0_2 += mptr2[k+4] * v[k+4]; - s1_2 += mptr2[k+5] * v[k+5]; - s2_2 += mptr2[k+6] * v[k+6]; - s3_2 += mptr2[k+7] * v[k+7]; - } - - switch( i - k ) { - case 7: s0 += mptr[k+6] * v[k+6]; s0_2 += mptr2[k+6] * v[k+6]; - case 6: s1 += mptr[k+5] * v[k+5]; s1_2 += mptr2[k+5] * v[k+5]; - case 5: s2 += mptr[k+4] * v[k+4]; s2_2 += mptr2[k+4] * v[k+4]; - case 4: s3 += mptr[k+3] * v[k+3]; s3_2 += mptr2[k+3] * v[k+3]; - case 3: s0 += mptr[k+2] * v[k+2]; s0_2 += mptr2[k+2] * v[k+2]; - case 2: s1 += mptr[k+1] * v[k+1]; s1_2 += mptr2[k+1] * v[k+1]; - case 1: s2 += mptr[k+0] * v[k+0]; s2_2 += mptr2[k+0] * v[k+0]; - } - // disassociate these adds - s3 += s2; - s1 += s0; - sum = s1 + s3; - - s3_2 += s2_2; - s1_2 += s0_2; - sum_2 = s1_2 + s3_2; - - mptr[i] = ( mptr[i] - sum ) * d; - mptr2[i] = ( mptr2[i] - sum_2 ) * d; - - mptr += nc*2; - mptr2 += nc*2; - } - - // cleanup - for ( ; j < n; j++ ) { - s0 = mptr[0] * v[0]; - s1 = mptr[1] * v[1]; - s2 = mptr[2] * v[2]; - s3 = mptr[3] * v[3]; - for ( k = 4; k < i-7; k += 8 ) { - s0 += mptr[k+0] * v[k+0]; - s1 += mptr[k+1] * v[k+1]; - s2 += mptr[k+2] * v[k+2]; - s3 += mptr[k+3] * v[k+3]; - s0 += mptr[k+4] * v[k+4]; - s1 += mptr[k+5] * v[k+5]; - s2 += mptr[k+6] * v[k+6]; - s3 += mptr[k+7] * v[k+7]; - } - switch( i - k ) { - case 7: s0 += mptr[k+6] * v[k+6]; - case 6: s1 += mptr[k+5] * v[k+5]; - case 5: s2 += mptr[k+4] * v[k+4]; - case 4: s3 += mptr[k+3] * v[k+3]; - case 3: s0 += mptr[k+2] * v[k+2]; - case 2: s1 += mptr[k+1] * v[k+1]; - case 1: s2 += mptr[k+0] * v[k+0]; - } - // disassociate these adds - s3 += s2; - s1 += s0; - sum = s1 + s3; - mptr[i] = ( mptr[i] - sum ) * d; - mptr += nc; - } - } - return true; -} -#endif /* ENABLE_LOWER_TRIANGULAR */ - - -#ifdef LIVE_VICARIOUSLY -/* -============ -idSIMD_AltiVec::BlendJoints -============ -*/ -void VPCALL idSIMD_AltiVec::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { - int i; - - // since lerp is a constant, we can special case the two cases if they're true - if ( lerp <= 0.0f ) { - // this sets joints back to joints. No sense in doing no work, so just return - return; - } - - if ( lerp >= 1.0f ) { - // this copies each q from blendJoints to joints and copies each t from blendJoints to joints - memcpy( joints[0].q.ToFloatPtr(), blendJoints[0].q.ToFloatPtr(), sizeof(idJointQuat) * numJoints ); - return; - } - - vector float vecLerp = loadSplatUnalignedScalar( &lerp ); - vector float zeroVector = (vector float)(0); - - for ( i = 0; i+3 < numJoints; i+=4 ) { - int j = index[i]; - int j2 = index[i+1]; - int j3 = index[i+2]; - int j4 = index[i+3]; - - // slerp - const float *jointPtr = joints[j].q.ToFloatPtr(); - const float *blendPtr = blendJoints[j].q.ToFloatPtr(); - const float *jointPtr2 = joints[j2].q.ToFloatPtr(); - const float *blendPtr2 = blendJoints[j2].q.ToFloatPtr(); - const float *jointPtr3 = joints[j3].q.ToFloatPtr(); - const float *blendPtr3 = blendJoints[j3].q.ToFloatPtr(); - const float *jointPtr4 = joints[j4].q.ToFloatPtr(); - const float *blendPtr4 = blendJoints[j4].q.ToFloatPtr(); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); - vector unsigned char permVec2 = vec_add( vec_lvsl( -1, jointPtr2 ), (vector unsigned char)(1) ); - vector unsigned char permVec3 = vec_add( vec_lvsl( -1, jointPtr3 ), (vector unsigned char)(1) ); - vector unsigned char permVec4 = vec_add( vec_lvsl( -1, jointPtr4 ), (vector unsigned char)(1) ); - - vector unsigned char permVec5 = vec_add( vec_lvsl( -1, blendPtr ), (vector unsigned char)(1) ); - vector unsigned char permVec6 = vec_add( vec_lvsl( -1, blendPtr2 ), (vector unsigned char)(1) ); - vector unsigned char permVec7 = vec_add( vec_lvsl( -1, blendPtr3 ), (vector unsigned char)(1) ); - vector unsigned char permVec8 = vec_add( vec_lvsl( -1, blendPtr4 ), (vector unsigned char)(1) ); - - vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; - vector float v12, v13, v14, v15, v16; - vector float vecFromX, vecFromY, vecFromZ, vecFromW; - vector float vecToX, vecToY, vecToZ, vecToW; - - // load up the the idJointQuats from joints - v0 = vec_ld( 0, jointPtr ); - v1 = vec_ld( 15, jointPtr ); - v2 = vec_perm( v0, v1, permVec ); - - v3 = vec_ld( 0, jointPtr2 ); - v4 = vec_ld( 15, jointPtr2 ); - v5 = vec_perm( v3, v4, permVec2 ); - - v6 = vec_ld( 0, jointPtr3 ); - v7 = vec_ld( 15, jointPtr3 ); - v8 = vec_perm( v6, v7, permVec3 ); - - v9 = vec_ld( 0, jointPtr4 ); - v10 = vec_ld( 15, jointPtr4 ); - v11 = vec_perm( v9, v10, permVec4 ); - - // planarizing, so put each x y z w into its own vector - v0 = vec_mergeh( v2, v8 ); - v1 = vec_mergeh( v5, v11 ); - v3 = vec_mergel( v2, v8 ); - v4 = vec_mergel( v5, v11 ); - - vecFromX = vec_mergeh( v0, v1 ); - vecFromY = vec_mergel( v0, v1 ); - vecFromZ = vec_mergeh( v3, v4 ); - vecFromW = vec_mergel( v3, v4 ); - - // load up idJointQuats from blendJoints - v5 = vec_ld( 0, blendPtr ); - v6 = vec_ld( 15, blendPtr ); - v7 = vec_perm( v5, v6, permVec5 ); - - v8 = vec_ld( 0, blendPtr2 ); - v9 = vec_ld( 15, blendPtr2 ); - v10 = vec_perm( v8, v9, permVec6 ); - - v11 = vec_ld( 0, blendPtr3 ); - v12 = vec_ld( 15, blendPtr3 ); - v13 = vec_perm( v11, v12, permVec7 ); - - v14 = vec_ld( 0, blendPtr4 ); - v15 = vec_ld( 15, blendPtr4 ); - v16 = vec_perm( v14, v15, permVec8 ); - - // put these into their own vectors too - v5 = vec_mergeh( v7, v13 ); - v6 = vec_mergeh( v10, v16 ); - v8 = vec_mergel( v7, v13 ); - v9 = vec_mergel( v10, v16 ); - - vecToX = vec_mergeh( v5, v6 ); - vecToY = vec_mergel( v5, v6 ); - vecToZ = vec_mergeh( v8, v9 ); - vecToW = vec_mergel( v8, v9 ); - - // calculate cosom - vector float vecCosom = vec_madd( vecFromX, vecToX, (vector float)(0) ); - vecCosom = vec_madd( vecFromY, vecToY, vecCosom ); - vecCosom = vec_madd( vecFromZ, vecToZ, vecCosom ); - vecCosom = vec_madd( vecFromW, vecToW, vecCosom ); - - // if cosom is < 0, negate it and set temp to negated elements in to. otherwise, set temp to - // to - vector bool int vecCmp, vecCmp2; - vecCmp = vec_cmplt( vecCosom, zeroVector ); - - // negate if needed - vecToX = vec_sel( vecToX, vec_madd( vecToX, (vector float)(-1), zeroVector ), vecCmp ); - vecToY = vec_sel( vecToY, vec_madd( vecToY, (vector float)(-1), zeroVector ), vecCmp ); - vecToZ = vec_sel( vecToZ, vec_madd( vecToZ, (vector float)(-1), zeroVector ), vecCmp ); - vecToW = vec_sel( vecToW, vec_madd( vecToW, (vector float)(-1), zeroVector ), vecCmp ); - vecCosom = vec_sel( vecCosom, vec_madd( vecCosom, (vector float)(-1), zeroVector ), vecCmp ); - - // check if we need to calculate scale - vecCmp2 = vec_cmpgt( vec_sub( (vector float)(1), vecCosom ), (vector float)(1e-6f) ); - vector float vecScale0 = vec_sub( (vector float)(1), vecLerp ); - vector float vecScale1 = vec_splat( vecLerp, 0 ); - - vector float vecWork1 = vec_sub( (vector float)(1), vec_madd( vecCosom, vecCosom, zeroVector ) ); - vector float vecWork2 = ReciprocalSquareRoot( vecWork1 ); - vector float vecWork3 = VectorATan16( vec_madd( vecWork1, vecWork2, zeroVector ), vecCosom ); - - vecWork1 = vec_madd( VectorSin16( vec_madd( vecScale0, vecWork3, zeroVector ) ), vecWork2, zeroVector ); - vecWork2 = vec_madd( VectorSin16( vec_madd( vecLerp, vecWork3, zeroVector ) ), vecWork2, zeroVector ); - - // see which ones we have to insert into our scale0 and scale1 vectors - vecScale0 = vec_sel( vecScale0, vecWork1, vecCmp2 ); - vecScale1 = vec_sel( vecScale1, vecWork2, vecCmp2 ); - - // multiply each element by the scale - vecFromX = vec_madd( vecFromX, vecScale0, zeroVector ); - vecFromY = vec_madd( vecFromY, vecScale0, zeroVector ); - vecFromZ = vec_madd( vecFromZ, vecScale0, zeroVector ); - vecFromW = vec_madd( vecFromW, vecScale0, zeroVector ); - - // multiply temp by scale and add to result - vecFromX = vec_madd( vecToX, vecScale1, vecFromX ); - vecFromY = vec_madd( vecToY, vecScale1, vecFromY ); - vecFromZ = vec_madd( vecToZ, vecScale1, vecFromZ ); - vecFromW = vec_madd( vecToW, vecScale1, vecFromW ); - - // do a transform again to get the results back to vectors we can store out - v5 = vec_mergeh( vecFromX, vecFromZ ); - v6 = vec_mergeh( vecFromY, vecFromW ); - v8 = vec_mergel( vecFromX, vecFromZ ); - v9 = vec_mergel( vecFromY, vecFromW ); - - vecToX = vec_mergeh( v5, v6 ); - vecToY = vec_mergel( v5, v6 ); - vecToZ = vec_mergeh( v8, v9 ); - vecToW = vec_mergel( v8, v9 ); - - vector unsigned char storePerm1 = vec_lvsr( 0, jointPtr ); - vector unsigned char storePerm2 = vec_lvsr( 0, jointPtr2 ); - vector unsigned char storePerm3 = vec_lvsr( 0, jointPtr3 ); - vector unsigned char storePerm4 = vec_lvsr( 0, jointPtr4 ); - - // right rotate the input data - vecToX = vec_perm( vecToX, vecToX, storePerm1 ); - vecToY = vec_perm( vecToY, vecToY, storePerm2 ); - vecToZ = vec_perm( vecToZ, vecToZ, storePerm3 ); - vecToW = vec_perm( vecToW, vecToW, storePerm4 ); - - vec_ste( vecToX, 0, (float*) jointPtr ); - vec_ste( vecToX, 4, (float*) jointPtr ); - vec_ste( vecToX, 8, (float*) jointPtr ); - vec_ste( vecToX, 12, (float*) jointPtr ); - - vec_ste( vecToY, 0, (float*) jointPtr2 ); - vec_ste( vecToY, 4, (float*) jointPtr2 ); - vec_ste( vecToY, 8, (float*) jointPtr2 ); - vec_ste( vecToY, 12, (float*) jointPtr2 ); - - vec_ste( vecToZ, 0, (float*) jointPtr3 ); - vec_ste( vecToZ, 4, (float*) jointPtr3 ); - vec_ste( vecToZ, 8, (float*) jointPtr3 ); - vec_ste( vecToZ, 12, (float*) jointPtr3 ); - - vec_ste( vecToW, 0, (float*) jointPtr4 ); - vec_ste( vecToW, 4, (float*) jointPtr4 ); - vec_ste( vecToW, 8, (float*) jointPtr4 ); - vec_ste( vecToW, 12, (float*) jointPtr4 ); - - // lerp is v1 + l * ( v2 - v1 ); - // the idVec3 T is going to be 12 bytes after the Q, so we can do this without calling ToFloatPtr() again. since its - float *jointVecPtr = (float*)( jointPtr + 4 ); - float *jointVecPtr2 = (float*)( jointPtr2 + 4 ); - float *jointVecPtr3 = (float*)( jointPtr3 + 4 ); - float *jointVecPtr4 = (float*)( jointPtr4 + 4 ); - - v0 = vec_ld( 0, jointVecPtr ); - v1 = vec_ld( 11, jointVecPtr ); - vector float vecLd1 = vec_perm( v0, v1, vec_add( vec_lvsl( -1, jointVecPtr ), (vector unsigned char)(1) ) ); - - v2 = vec_ld( 0, jointVecPtr2 ); - v3 = vec_ld( 11, jointVecPtr2 ); - vector float vecLd2 = vec_perm( v2, v3, vec_add( vec_lvsl( -1, jointVecPtr2 ), (vector unsigned char)(1) ) ); - - v4 = vec_ld( 0, jointVecPtr3 ); - v5 = vec_ld( 11, jointVecPtr3 ); - vector float vecLd3 = vec_perm( v4, v5, vec_add( vec_lvsl( -1, jointVecPtr3 ), (vector unsigned char)(1) ) ); - - v6 = vec_ld( 0, jointVecPtr4 ); - v7 = vec_ld( 11, jointVecPtr4 ); - vector float vecLd4 = vec_perm( v6, v7, vec_add( vec_lvsl( -1, jointVecPtr4 ), (vector unsigned char)(1) ) ); - - vector float vecVecX, vecVecY, vecVecZ; - vecVecX = vecVecY = vecVecZ = zeroVector; - - // planarize - v0 = vec_mergeh( vecLd1, vecLd3 ); - v1 = vec_mergeh( vecLd2, vecLd4 ); - v3 = vec_mergel( vecLd1, vecLd3 ); - v4 = vec_mergel( vecLd2, vecLd4 ); - - vecVecX = vec_mergeh( v0, v1 ); - vecVecY = vec_mergel( v0, v1 ); - vecVecZ = vec_mergeh( v3, v4 ); - - // load blend joint idvec3's - float *blendVecPtr = (float*)( blendPtr + 4 ); - float *blendVecPtr2 =(float*)( blendPtr2 + 4 ); - float *blendVecPtr3 = (float*)( blendPtr3 + 4 ); - float *blendVecPtr4 = (float*)( blendPtr4 + 4 ); - - v0 = vec_ld( 0, blendVecPtr ); - v1 = vec_ld( 11, blendVecPtr ); - vector float vecLd5 = vec_perm( v0, v1, vec_add( vec_lvsl( -1, blendVecPtr ), (vector unsigned char)(1) ) ); - - v2 = vec_ld( 0, blendVecPtr2 ); - v3 = vec_ld( 11, blendVecPtr2 ); - vector float vecLd6 = vec_perm( v2, v3, vec_add( vec_lvsl( -1, blendVecPtr2 ), (vector unsigned char)(1) ) ); - - v4 = vec_ld( 0, blendVecPtr3 ); - v5 = vec_ld( 11, blendVecPtr3 ); - vector float vecLd7 = vec_perm( v4, v5, vec_add( vec_lvsl( -1, blendVecPtr3 ), (vector unsigned char)(1) ) ); - - v6 = vec_ld( 0, blendVecPtr4 ); - v7 = vec_ld( 11, blendVecPtr4 ); - vector float vecLd8 = vec_perm( v6, v7, vec_add( vec_lvsl( -1, blendVecPtr4 ), (vector unsigned char)(1) ) ); - - vector float vecBlendX, vecBlendY, vecBlendZ; - vecBlendX = vecBlendY = vecBlendZ = zeroVector; - - // planarize - v0 = vec_mergeh( vecLd5, vecLd7 ); - v1 = vec_mergeh( vecLd6, vecLd8 ); - v3 = vec_mergel( vecLd5, vecLd7 ); - v4 = vec_mergel( vecLd6, vecLd8 ); - - vecBlendX = vec_mergeh( v0, v1 ); - vecBlendY = vec_mergel( v0, v1 ); - vecBlendZ = vec_mergeh( v3, v4 ); - - // do subtraction - vecWork1 = vec_sub( vecBlendX, vecVecX ); - vecWork2 = vec_sub( vecBlendY, vecVecY ); - vecWork3 = vec_sub( vecBlendZ, vecVecZ ); - - // multiply by lerp and add to v1 - vecVecX = vec_madd( vecWork1, vecLerp, vecVecX ); - vecVecY = vec_madd( vecWork2, vecLerp, vecVecY ); - vecVecZ = vec_madd( vecWork3, vecLerp, vecVecZ ); - - // put it back in original form - v0 = vec_mergeh( vecVecX, vecVecZ ); - v1 = vec_mergeh( vecVecY, zeroVector ); - v3 = vec_mergel( vecVecX, vecVecZ ); - v4 = vec_mergel( vecVecY, zeroVector ); - - // generate vectors to store - vecWork1 = vec_mergeh( v0, v1 ); - vecWork2 = vec_mergel( v0, v1 ); - vecWork3 = vec_mergeh( v3, v4 ); - vector float vecWork4 = vec_mergel( v3, v4 ); - - // store the T values - storePerm1 = vec_lvsr( 0, jointVecPtr ); - storePerm2 = vec_lvsr( 0, jointVecPtr2 ); - storePerm3 = vec_lvsr( 0, jointVecPtr3 ); - storePerm4 = vec_lvsr( 0, jointVecPtr4 ); - - // right rotate the input data - vecWork1 = vec_perm( vecWork1, vecWork1, storePerm1 ); - vecWork2 = vec_perm( vecWork2, vecWork2, storePerm2 ); - vecWork3 = vec_perm( vecWork3, vecWork3, storePerm3 ); - vecWork4 = vec_perm( vecWork4, vecWork4, storePerm4 ); - - vec_ste( vecWork1, 0, (float*) jointVecPtr ); - vec_ste( vecWork1, 4, (float*) jointVecPtr ); - vec_ste( vecWork1, 8, (float*) jointVecPtr ); - - vec_ste( vecWork2, 0, (float*) jointVecPtr2 ); - vec_ste( vecWork2, 4, (float*) jointVecPtr2 ); - vec_ste( vecWork2, 8, (float*) jointVecPtr2 ); - - vec_ste( vecWork3, 0, (float*) jointVecPtr3 ); - vec_ste( vecWork3, 4, (float*) jointVecPtr3 ); - vec_ste( vecWork3, 8, (float*) jointVecPtr3 ); - - vec_ste( vecWork4, 0, (float*) jointVecPtr4 ); - vec_ste( vecWork4, 4, (float*) jointVecPtr4 ); - vec_ste( vecWork4, 8, (float*) jointVecPtr4 ); - } - - // cleanup - for ( ; i < numJoints; i++ ) { - int j = index[i]; - joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp ); - joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); - } -} - -/* -============ -idSIMD_AltiVec::ConvertJointQuatsToJointMats -============ -*/ - -// SSE doesn't vectorize this, and I don't think we should either. Its mainly just copying data, there's very little math involved and -// it's not easily parallelizable -void VPCALL idSIMD_AltiVec::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { - - for ( int i = 0; i < numJoints; i++ ) { - - const float *q = jointQuats[i].q.ToFloatPtr(); - float *m = jointMats[i].ToFloatPtr(); - - m[0*4+3] = q[4]; - m[1*4+3] = q[5]; - m[2*4+3] = q[6]; - - float x2 = q[0] + q[0]; - float y2 = q[1] + q[1]; - float z2 = q[2] + q[2]; - - { - float xx = q[0] * x2; - float yy = q[1] * y2; - float zz = q[2] * z2; - - m[0*4+0] = 1.0f - yy - zz; - m[1*4+1] = 1.0f - xx - zz; - m[2*4+2] = 1.0f - xx - yy; - } - - { - float yz = q[1] * z2; - float wx = q[3] * x2; - - m[2*4+1] = yz - wx; - m[1*4+2] = yz + wx; - } - - { - float xy = q[0] * y2; - float wz = q[3] * z2; - - m[1*4+0] = xy - wz; - m[0*4+1] = xy + wz; - } - - { - float xz = q[0] * z2; - float wy = q[3] * y2; - - m[0*4+2] = xz - wy; - m[2*4+0] = xz + wy; - } - } -} - -/* -============ -idSIMD_AltiVec::ConvertJointMatsToJointQuats -============ -*/ -void VPCALL idSIMD_AltiVec::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { - - int index; - - // Since we use very little of the data we have to pull in for the altivec version, we end up with - // a lot of wasted math. Rather than try to force it to use altivec, I wrote an optimized version - // of InvSqrt for the G5, and made it use that instead. With only this change, we get a little - // bigger than 50% speedup, which is not too shabby. Should really replace idMath::InvSqrt with - // my function so everyone can benefit on G5. - - for ( index = 0; index < numJoints; index++ ) { - - idJointQuat jq; - float trace; - float s; - float t; - int i; - int j; - int k; - - static int next[3] = { 1, 2, 0 }; - - float *mat = (float*)( jointMats[index].ToFloatPtr() ); - trace = mat[0 * 4 + 0] + mat[1 * 4 + 1] + mat[2 * 4 + 2]; - - if ( trace > 0.0f ) { - - t = trace + 1.0f; - //s = idMath::InvSqrt( t ) * 0.5f; - s = FastScalarInvSqrt( t ) * 0.5f; - - jq.q[3] = s * t; - jq.q[0] = ( mat[1 * 4 + 2] - mat[2 * 4 + 1] ) * s; - jq.q[1] = ( mat[2 * 4 + 0] - mat[0 * 4 + 2] ) * s; - jq.q[2] = ( mat[0 * 4 + 1] - mat[1 * 4 + 0] ) * s; - - } else { - - i = 0; - if ( mat[1 * 4 + 1] > mat[0 * 4 + 0] ) { - i = 1; - } - if ( mat[2 * 4 + 2] > mat[i * 4 + i] ) { - i = 2; - } - j = next[i]; - k = next[j]; - - t = ( mat[i * 4 + i] - ( mat[j * 4 + j] + mat[k * 4 + k] ) ) + 1.0f; - //s = idMath::InvSqrt( t ) * 0.5f; - s = FastScalarInvSqrt( t ) * 0.5f; - - jq.q[i] = s * t; - jq.q[3] = ( mat[j * 4 + k] - mat[k * 4 + j] ) * s; - jq.q[j] = ( mat[i * 4 + j] + mat[j * 4 + i] ) * s; - jq.q[k] = ( mat[i * 4 + k] + mat[k * 4 + i] ) * s; - } - - jq.t[0] = mat[0 * 4 + 3]; - jq.t[1] = mat[1 * 4 + 3]; - jq.t[2] = mat[2 * 4 + 3]; - jointQuats[index] = jq; - } -} - -/* -============ -idSIMD_AltiVec::TransformJoints -============ -*/ -void VPCALL idSIMD_AltiVec::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { - int i; -#if 0 - for( i = firstJoint; i <= lastJoint; i++ ) { - assert( parents[i] < i ); - jointMats[i] *= jointMats[parents[i]]; - } -#else - - // I don't think you can unroll this since the next iteration of the loop might depending on the previous iteration, depending - // on what the parents array looks like. This is true in the test code. - for ( i = firstJoint; i <= lastJoint; i++ ) { - assert( parents[i] < i ); - float *jointPtr = jointMats[i].ToFloatPtr(); - float *parentPtr = jointMats[parents[i]].ToFloatPtr(); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); - vector unsigned char permVec2 = vec_add( vec_lvsl( -1, parentPtr ), (vector unsigned char)(1) ); - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - // we need to load up 12 float elements that make up the Mat - v0 = vec_ld( 0, jointPtr ); - v1 = vec_ld( 15, jointPtr ); - v2 = vec_ld( 31, jointPtr ); - v3 = vec_ld( 47, jointPtr ); - - // load parents - v4 = vec_ld( 0, parentPtr ); - v5 = vec_ld( 15, parentPtr ); - v6 = vec_ld( 31, parentPtr ); - v7 = vec_ld( 47, parentPtr ); - - // permute into vectors - vector float vecJointMat1 = vec_perm( v0, v1, permVec ); - vector float vecJointMat2 = vec_perm( v1, v2, permVec ); - vector float vecJointMat3 = vec_perm( v2, v3, permVec ); - - vector float vecParentMat1 = vec_perm( v4, v5, permVec2 ); - vector float vecParentMat2 = vec_perm( v5, v6, permVec2 ); - vector float vecParentMat3 = vec_perm( v6, v7, permVec2 ); - - vector float zero = (vector float)(0); - vector float C1, C2, C3; - - // matrix multiply - C1 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 0 ), zero ); // m(0 to 3) * a(0) - C2 = vec_madd( vecJointMat1, vec_splat( vecParentMat2, 0 ), zero ); // m(4 to 7) * a(4) - C3 = vec_madd( vecJointMat1, vec_splat( vecParentMat3, 0 ), zero ); // m(8 to 11) * a(8) - - C1 = vec_madd( vecJointMat2, vec_splat( vecParentMat1, 1 ), C1 ); // add in m(4 to 7) * a(1) - C2 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 1 ), C2 ); // add in m(4 to 7) * a(5) - C3 = vec_madd( vecJointMat2, vec_splat( vecParentMat3, 1 ), C3 ); // add in m(4 to 7) * a(9) - - C1 = vec_madd( vecJointMat3, vec_splat( vecParentMat1, 2 ), C1 ); - C2 = vec_madd( vecJointMat3, vec_splat( vecParentMat2, 2 ), C2 ); - C3 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 2 ), C3 ); - - // do the addition at the end - vector unsigned char permZeroAndLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,28,29,30,31); - C1 = vec_add( C1, vec_perm( zero, vecParentMat1, permZeroAndLast ) ); - C2 = vec_add( C2, vec_perm( zero, vecParentMat2, permZeroAndLast ) ); - C3 = vec_add( C3, vec_perm( zero, vecParentMat3, permZeroAndLast ) ); - - // store results - UNALIGNED_STORE3( (float*) jointPtr, C1, C2, C3 ); - } -#endif -} - -/* -============ -idSIMD_AltiVec::UntransformJoints -============ -*/ -void VPCALL idSIMD_AltiVec::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { - int i; -#if 0 - for( i = lastJoint; i >= firstJoint; i-- ) { - assert( parents[i] < i ); - jointMats[i] /= jointMats[parents[i]]; - } -#else - // I don't think you can unroll this since the next iteration of the loop might depending on the previous iteration, depending - // on what the parents array looks like. This is true in the test code. - for ( i = lastJoint; i >= firstJoint; i-- ) { - assert( parents[i] < i ); - float *jointPtr = jointMats[i].ToFloatPtr(); - float *parentPtr = jointMats[parents[i]].ToFloatPtr(); - - vector unsigned char permVec = vec_add( vec_lvsl( -1, jointPtr ), (vector unsigned char)(1) ); - vector unsigned char permVec2 = vec_add( vec_lvsl( -1, parentPtr ), (vector unsigned char)(1) ); - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - // we need to load up 12 float elements that make up the Mat - v0 = vec_ld( 0, jointPtr ); - v1 = vec_ld( 15, jointPtr ); - v2 = vec_ld( 31, jointPtr ); - v3 = vec_ld( 47, jointPtr ); - - // load parents - v4 = vec_ld( 0, parentPtr ); - v5 = vec_ld( 15, parentPtr ); - v6 = vec_ld( 31, parentPtr ); - v7 = vec_ld( 47, parentPtr ); - - // permute into vectors - vector float vecJointMat1 = vec_perm( v0, v1, permVec ); - vector float vecJointMat2 = vec_perm( v1, v2, permVec ); - vector float vecJointMat3 = vec_perm( v2, v3, permVec ); - - vector float vecParentMat1 = vec_perm( v4, v5, permVec2 ); - vector float vecParentMat2 = vec_perm( v5, v6, permVec2 ); - vector float vecParentMat3 = vec_perm( v6, v7, permVec2 ); - - vector float zero = (vector float)(0); - vector float C1, C2, C3; - - // do subtraction at the beginning - vector unsigned char permZeroAndLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,28,29,30,31); - vecJointMat1 = vec_sub( vecJointMat1, vec_perm( zero, vecParentMat1, permZeroAndLast ) ); - vecJointMat2 = vec_sub( vecJointMat2, vec_perm( zero, vecParentMat2, permZeroAndLast ) ); - vecJointMat3 = vec_sub( vecJointMat3, vec_perm( zero, vecParentMat3, permZeroAndLast ) ); - - // matrix multiply - C1 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 0 ), zero ); - C2 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 1 ), zero ); - C3 = vec_madd( vecJointMat1, vec_splat( vecParentMat1, 2 ), zero ); - - C1 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 0 ), C1 ); - C2 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 1 ), C2 ); - C3 = vec_madd( vecJointMat2, vec_splat( vecParentMat2, 2 ), C3 ); - - C1 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 0 ), C1 ); - C2 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 1 ), C2 ); - C3 = vec_madd( vecJointMat3, vec_splat( vecParentMat3, 2 ), C3 ); - - // store results back - vector unsigned char storePerm = vec_lvsr( 0, jointPtr ); - - // right rotate the input data - C1 = vec_perm( C1, C1, storePerm ); - C2 = vec_perm( C2, C2, storePerm ); - C3 = vec_perm( C3, C3, storePerm ); - - vec_ste( C1, 0, (float*) jointPtr ); - vec_ste( C1, 4, (float*) jointPtr ); - vec_ste( C1, 8, (float*) jointPtr ); - vec_ste( C1, 12, (float*) jointPtr ); - - vec_ste( C2, 16, (float*) jointPtr ); - vec_ste( C2, 20, (float*) jointPtr ); - vec_ste( C2, 24, (float*) jointPtr ); - vec_ste( C2, 28, (float*) jointPtr ); - - vec_ste( C3, 32, (float*) jointPtr ); - vec_ste( C3, 36, (float*) jointPtr ); - vec_ste( C3, 40, (float*) jointPtr ); - vec_ste( C3, 44, (float*) jointPtr ); - } - -#endif -} - -/* -============ -idSIMD_AltiVec::TransformVerts -============ -*/ - -// Here we don't have much for the vector unit to do, and the gain we get from doing the math -// in parallel is eaten by doing unaligned stores. -void VPCALL idSIMD_AltiVec::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, int numWeights ) { - int i, j; - const byte *jointsPtr = (byte *)joints; - - for( j = i = 0; i < numVerts; i++ ) { - idVec3 v; - - float *matPtrOrig = ( *(idJointMat *)( jointsPtr + index[j*2] ) ).ToFloatPtr(); - float *weightPtr = (float*) weights[j].ToFloatPtr(); - - v[0] = matPtrOrig[0] * weightPtr[0]; - v[0] += matPtrOrig[1] * weightPtr[1]; - v[0] += matPtrOrig[2] * weightPtr[2]; - v[0] += matPtrOrig[3] * weightPtr[3]; - - v[1] = matPtrOrig[4] * weightPtr[0]; - v[1] += matPtrOrig[5] * weightPtr[1]; - v[1] += matPtrOrig[6] * weightPtr[2]; - v[1] += matPtrOrig[7] * weightPtr[3]; - - v[2] = matPtrOrig[8] * weightPtr[0]; - v[2] += matPtrOrig[9] * weightPtr[1]; - v[2] += matPtrOrig[10] * weightPtr[2]; - v[2] += matPtrOrig[11] * weightPtr[3]; - - while( index[j*2+1] == 0 ) { - j++; - float *matPtr = ( *(idJointMat *)( jointsPtr + index[j*2] ) ).ToFloatPtr(); - weightPtr = (float*) weights[j].ToFloatPtr(); - - v[0] += matPtr[0] * weightPtr[0]; - v[0] += matPtr[1] * weightPtr[1]; - v[0] += matPtr[2] * weightPtr[2]; - v[0] += matPtr[3] * weightPtr[3]; - - v[1] += matPtr[4] * weightPtr[0]; - v[1] += matPtr[5] * weightPtr[1]; - v[1] += matPtr[6] * weightPtr[2]; - v[1] += matPtr[7] * weightPtr[3]; - - v[2] += matPtr[8] * weightPtr[0]; - v[2] += matPtr[9] * weightPtr[1]; - v[2] += matPtr[10] * weightPtr[2]; - v[2] += matPtr[11] * weightPtr[3]; - } - j++; - - verts[i].xyz = v; - } -} -#endif /* LIVE_VICARIOUSLY */ - -#ifdef ENABLE_CULL - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::TracePointCull -============ -*/ -void VPCALL idSIMD_AltiVec::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - byte tOr; - tOr = 0; - - // pointers - const float *planePtr = planes[0].ToFloatPtr(); - - vector unsigned int vecShift1 = (vector unsigned int)(0,1,2,3); - vector unsigned int vecShift2 = (vector unsigned int)(4,5,6,7); - vector unsigned int vecFlipBits = (vector unsigned int)(0x0F); - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; - vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; - vector unsigned char vecPerm; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - vector float zeroVector = (vector float)(0); - vector float vecRadius; - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector float vec1Sum1, vec1Sum2, vec1Sum3, vec1Sum4; - vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - vector float vecDPlusRadius1, vecDPlusRadius2, vecDPlusRadius3, vecDPlusRadius4; - vector float vecDMinusRadius1, vecDMinusRadius2, vecDMinusRadius3, vecDMinusRadius4; - vector bool int oneIntVector = (vector bool int)(1); - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4, vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; - vector unsigned int vecTotals; - vector unsigned int tempIntSum; - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - - // populate planes - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 4 ); - v3 = vec_ld( 15, planePtr + 4 ); - vecPlane1 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 8 ); - v1 = vec_ld( 15, planePtr + 8 ); - vecPlane2 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 12 ); - v3 = vec_ld( 15, planePtr + 12 ); - vecPlane3 = vec_perm( v2, v3, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane2 ); - v1 = vec_mergeh( vecPlane1, vecPlane3 ); - v2 = vec_mergel( vecPlane0, vecPlane2 ); - v3 = vec_mergel( vecPlane1, vecPlane3 ); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - // load constants - vecRadius = loadSplatUnalignedScalar( &radius ); - - unsigned int cullBitVal[4]; - vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); - int i = 0; - - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < numVerts ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } - - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); - vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); - vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); - vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); - - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); - vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); - - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec1Sum2 ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec1Sum2 ); - vec1Sum2 = vec_add( vec1Sum2, vecPlane3 ); - - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec1Sum3 ); - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec1Sum3 ); - vec1Sum3 = vec_add( vec1Sum3, vecPlane3 ); - - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec1Sum4 ); - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec1Sum4 ); - vec1Sum4 = vec_add( vec1Sum4, vecPlane3 ); - - // vec1Sum1 now holds d0, d1, d2, d3. calculate the - // difference with +radius and -radius - vecDPlusRadius1 = vec_add( vec1Sum1, vecRadius ); - vecDMinusRadius1 = vec_sub( vec1Sum1, vecRadius ); - vecDPlusRadius2 = vec_add( vec1Sum2, vecRadius ); - vecDMinusRadius2 = vec_sub( vec1Sum2, vecRadius ); - vecDPlusRadius3 = vec_add( vec1Sum3, vecRadius ); - vecDMinusRadius3 = vec_sub( vec1Sum3, vecRadius ); - vecDPlusRadius4 = vec_add( vec1Sum4, vecRadius ); - vecDMinusRadius4 = vec_sub( vec1Sum4, vecRadius ); - - // do compare - vecCmp1 = vec_cmplt( vecDPlusRadius1, zeroVector ); - vecCmp2 = vec_cmplt( vecDMinusRadius1, zeroVector ); - vecCmp3 = vec_cmplt( vecDPlusRadius2, zeroVector ); - vecCmp4 = vec_cmplt( vecDMinusRadius2, zeroVector ); - vecCmp5 = vec_cmplt( vecDPlusRadius3, zeroVector ); - vecCmp6 = vec_cmplt( vecDMinusRadius3, zeroVector ); - vecCmp7 = vec_cmplt( vecDPlusRadius4, zeroVector ); - vecCmp8 = vec_cmplt( vecDMinusRadius4, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - vecCmp3 = vec_and( vecCmp3, oneIntVector ); - vecCmp4 = vec_and( vecCmp4, oneIntVector ); - vecCmp5 = vec_and( vecCmp5, oneIntVector ); - vecCmp6 = vec_and( vecCmp6, oneIntVector ); - vecCmp7 = vec_and( vecCmp7, oneIntVector ); - vecCmp8 = vec_and( vecCmp8, oneIntVector ); - - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); - vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); - vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); - vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); - vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); - vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); - vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); - - // OR (add) them all together - vecBitShifted1 = vec_add( vecBitShifted1, vecBitShifted2 ); - vecBitShifted3 = vec_add( vecBitShifted3, vecBitShifted4 ); - vecBitShifted5 = vec_add( vecBitShifted5, vecBitShifted6 ); - vecBitShifted7 = vec_add( vecBitShifted7, vecBitShifted8 ); - - vecTotals = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); - vecTotals = vec_add( vecTotals, vec_sld( vecTotals, vecTotals, 4 ) ); - tempIntSum = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_mergeh( vecTotals, tempIntSum ); - tempIntSum = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_perm( vecTotals, tempIntSum, vecPermHalves ); - tempIntSum = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_perm( vecTotals, tempIntSum, vecPermLast ); - - // store out results - vector unsigned int tempSt = vec_xor( vecTotals, vecFlipBits ); - tempSt = vec_perm( tempSt, tempSt, cullBitPerm ); - vec_ste( tempSt, 0, &cullBitVal[0] ); - vec_ste( tempSt, 4, &cullBitVal[0] ); - vec_ste( tempSt, 8, &cullBitVal[0] ); - vec_ste( tempSt, 12, &cullBitVal[0] ); - - tOr |= cullBitVal[0]; - tOr |= cullBitVal[1]; - tOr |= cullBitVal[2]; - tOr |= cullBitVal[3]; - - cullBits[i] = cullBitVal[0]; - cullBits[i+1] = cullBitVal[1]; - cullBits[i+2] = cullBitVal[2]; - cullBits[i+3] = cullBitVal[3]; - } - - // cleanup - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, t; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - - t = d0 + radius; - bits = FLOATSIGNBITSET( t ) << 0; - t = d1 + radius; - bits |= FLOATSIGNBITSET( t ) << 1; - t = d2 + radius; - bits |= FLOATSIGNBITSET( t ) << 2; - t = d3 + radius; - bits |= FLOATSIGNBITSET( t ) << 3; - - t = d0 - radius; - bits |= FLOATSIGNBITSET( t ) << 4; - t = d1 - radius; - bits |= FLOATSIGNBITSET( t ) << 5; - t = d2 - radius; - bits |= FLOATSIGNBITSET( t ) << 6; - t = d3 - radius; - bits |= FLOATSIGNBITSET( t ) << 7; - - bits ^= 0x0F; // flip lower four bits - - tOr |= bits; - cullBits[i] = bits; - } - - totalOr = tOr; -} -#else - -/* -============ -idSIMD_AltiVec::TracePointCull -============ -*/ -void VPCALL idSIMD_AltiVec::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - byte tOr; - tOr = 0; - - // pointers - const float *planePtr = planes[0].ToFloatPtr(); - - vector unsigned int vecShift1 = (vector unsigned int)(0,1,2,3); - vector unsigned int vecShift2 = (vector unsigned int)(4,5,6,7); - vector unsigned int vecFlipBits = (vector unsigned int)(0x0F); - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; - vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; - vector unsigned char vecPerm; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - vector float zeroVector = (vector float)(0); - vector float vecRadius; - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector float vec1Sum1, vec1Sum2, vec1Sum3, vec1Sum4; - vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - vector float vecDPlusRadius1, vecDPlusRadius2, vecDPlusRadius3, vecDPlusRadius4; - vector float vecDMinusRadius1, vecDMinusRadius2, vecDMinusRadius3, vecDMinusRadius4; - vector bool int oneIntVector = (vector bool int)(1); - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4, vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; - vector unsigned int vecTotals; - vector unsigned int tempIntSum; - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - - // populate planes - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 4 ); - v3 = vec_ld( 15, planePtr + 4 ); - vecPlane1 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 8 ); - v1 = vec_ld( 15, planePtr + 8 ); - vecPlane2 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 12 ); - v3 = vec_ld( 15, planePtr + 12 ); - vecPlane3 = vec_perm( v2, v3, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane2 ); - v1 = vec_mergeh( vecPlane1, vecPlane3 ); - v2 = vec_mergel( vecPlane0, vecPlane2 ); - v3 = vec_mergel( vecPlane1, vecPlane3 ); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - // load constants - vecRadius = loadSplatUnalignedScalar( &radius ); - - unsigned int cullBitVal[4]; - vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); - int i = 0; - - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - vecXYZ1 = vec_ld( 0, vertPtr ); - vecXYZ2 = vec_ld( 0, vertPtr2 ); - vecXYZ3 = vec_ld( 0, vertPtr3 ); - vecXYZ4 = vec_ld( 0, vertPtr4 ); - - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); - vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); - - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec1Sum2 ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec1Sum2 ); - vec1Sum2 = vec_add( vec1Sum2, vecPlane3 ); - - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec1Sum3 ); - vec1Sum3 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec1Sum3 ); - vec1Sum3 = vec_add( vec1Sum3, vecPlane3 ); - - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec1Sum4 ); - vec1Sum4 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec1Sum4 ); - vec1Sum4 = vec_add( vec1Sum4, vecPlane3 ); - - // vec1Sum1 now holds d0, d1, d2, d3. calculate the - // difference with +radius and -radius - vecDPlusRadius1 = vec_add( vec1Sum1, vecRadius ); - vecDMinusRadius1 = vec_sub( vec1Sum1, vecRadius ); - vecDPlusRadius2 = vec_add( vec1Sum2, vecRadius ); - vecDMinusRadius2 = vec_sub( vec1Sum2, vecRadius ); - vecDPlusRadius3 = vec_add( vec1Sum3, vecRadius ); - vecDMinusRadius3 = vec_sub( vec1Sum3, vecRadius ); - vecDPlusRadius4 = vec_add( vec1Sum4, vecRadius ); - vecDMinusRadius4 = vec_sub( vec1Sum4, vecRadius ); - - // do compare - vecCmp1 = vec_cmplt( vecDPlusRadius1, zeroVector ); - vecCmp2 = vec_cmplt( vecDMinusRadius1, zeroVector ); - vecCmp3 = vec_cmplt( vecDPlusRadius2, zeroVector ); - vecCmp4 = vec_cmplt( vecDMinusRadius2, zeroVector ); - vecCmp5 = vec_cmplt( vecDPlusRadius3, zeroVector ); - vecCmp6 = vec_cmplt( vecDMinusRadius3, zeroVector ); - vecCmp7 = vec_cmplt( vecDPlusRadius4, zeroVector ); - vecCmp8 = vec_cmplt( vecDMinusRadius4, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - vecCmp3 = vec_and( vecCmp3, oneIntVector ); - vecCmp4 = vec_and( vecCmp4, oneIntVector ); - vecCmp5 = vec_and( vecCmp5, oneIntVector ); - vecCmp6 = vec_and( vecCmp6, oneIntVector ); - vecCmp7 = vec_and( vecCmp7, oneIntVector ); - vecCmp8 = vec_and( vecCmp8, oneIntVector ); - - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); - vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); - vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); - vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); - vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); - vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); - vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); - - // OR (add) them all together - vecBitShifted1 = vec_add( vecBitShifted1, vecBitShifted2 ); - vecBitShifted3 = vec_add( vecBitShifted3, vecBitShifted4 ); - vecBitShifted5 = vec_add( vecBitShifted5, vecBitShifted6 ); - vecBitShifted7 = vec_add( vecBitShifted7, vecBitShifted8 ); - - vecTotals = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); - vecTotals = vec_add( vecTotals, vec_sld( vecTotals, vecTotals, 4 ) ); - tempIntSum = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_mergeh( vecTotals, tempIntSum ); - tempIntSum = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_perm( vecTotals, tempIntSum, vecPermHalves ); - tempIntSum = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); - tempIntSum = vec_add( tempIntSum, vec_sld( tempIntSum, tempIntSum, 4 ) ); - vecTotals = vec_perm( vecTotals, tempIntSum, vecPermLast ); - - // store out results - vector unsigned int tempSt = vec_xor( vecTotals, vecFlipBits ); - tempSt = vec_perm( tempSt, tempSt, cullBitPerm ); - vec_ste( tempSt, 0, &cullBitVal[0] ); - vec_ste( tempSt, 4, &cullBitVal[0] ); - vec_ste( tempSt, 8, &cullBitVal[0] ); - vec_ste( tempSt, 12, &cullBitVal[0] ); - - tOr |= cullBitVal[0]; - tOr |= cullBitVal[1]; - tOr |= cullBitVal[2]; - tOr |= cullBitVal[3]; - - cullBits[i] = cullBitVal[0]; - cullBits[i+1] = cullBitVal[1]; - cullBits[i+2] = cullBitVal[2]; - cullBits[i+3] = cullBitVal[3]; - } - - // cleanup - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, t; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - - t = d0 + radius; - bits = FLOATSIGNBITSET( t ) << 0; - t = d1 + radius; - bits |= FLOATSIGNBITSET( t ) << 1; - t = d2 + radius; - bits |= FLOATSIGNBITSET( t ) << 2; - t = d3 + radius; - bits |= FLOATSIGNBITSET( t ) << 3; - - t = d0 - radius; - bits |= FLOATSIGNBITSET( t ) << 4; - t = d1 - radius; - bits |= FLOATSIGNBITSET( t ) << 5; - t = d2 - radius; - bits |= FLOATSIGNBITSET( t ) << 6; - t = d3 - radius; - bits |= FLOATSIGNBITSET( t ) << 7; - - bits ^= 0x0F; // flip lower four bits - - tOr |= bits; - cullBits[i] = bits; - } - - totalOr = tOr; -} - -#endif /* DRAWVERT_PADDED */ - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::DecalPointCull -============ -*/ -void VPCALL idSIMD_AltiVec::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - int i; - const float *planePtr = planes[0].ToFloatPtr(); - - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3, vecPlane4, vecPlane5, vecPlane6, vecPlane7; - vector float zeroVector = (vector float)(0.0); - vector unsigned char vecPerm; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - - // populate planes - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 4 ); - v3 = vec_ld( 15, planePtr + 4 ); - vecPlane1 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 8 ); - v1 = vec_ld( 15, planePtr + 8 ); - vecPlane2 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 12 ); - v3 = vec_ld( 15, planePtr + 12 ); - vecPlane3 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 16 ); - v1 = vec_ld( 15, planePtr + 16 ); - vecPlane4 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 20 ); - v3 = vec_ld( 15, planePtr + 20 ); - vecPlane5 = vec_perm( v2, v3, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane2 ); - v1 = vec_mergeh( vecPlane1, vecPlane3 ); - v2 = vec_mergel( vecPlane0, vecPlane2 ); - v3 = vec_mergel( vecPlane1, vecPlane3 ); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - v0 = vec_mergeh( vecPlane4, zeroVector ); - v1 = vec_mergeh( vecPlane5, zeroVector ); - v2 = vec_mergel( vecPlane4, zeroVector ); - v3 = vec_mergel( vecPlane5, zeroVector ); - - vecPlane4 = vec_mergeh( v0, v1 ); - vecPlane5 = vec_mergel( v0, v1 ); - vecPlane6 = vec_mergeh( v2, v3 ); - vecPlane7 = vec_mergel( v2, v3 ); - - - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector bool int oneIntVector = (vector bool int)(1); - vector float vec1Sum1, vec1Sum2, vec2Sum1, vec2Sum2, vec3Sum1, vec3Sum2, vec4Sum1, vec4Sum2; - vector unsigned int vecShift1 = (vector unsigned int)(0, 1, 2, 3 ); - vector unsigned int vecShift2 = (vector unsigned int)(4, 5, 0, 0 ); - - vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4; - vector unsigned int vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; - vector unsigned int vecFlipBits = (vector unsigned int)( 0x3F, 0x3F, 0x3F, 0x3F ); - vector unsigned int vecR1, vecR2, vecR3, vecR4; - vector unsigned char permHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - unsigned int vBits[4]; - vector unsigned char vBitPerm = vec_lvsr( 0, &vBits[4] ); - - i = 0; - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < numVerts ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } - - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); - vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); - vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); - vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); - - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); - vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); - - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane4, zeroVector ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane5, vec1Sum2 ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane6, vec1Sum2 ); - vec1Sum2 = vec_add( vec1Sum2, vecPlane7 ); - - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec2Sum1 ); - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec2Sum1 ); - vec2Sum1 = vec_add( vec2Sum1, vecPlane3 ); - - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane4, zeroVector ); - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane5, vec2Sum2 ); - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane6, vec2Sum2 ); - vec2Sum2 = vec_add( vec2Sum2, vecPlane7 ); - - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec3Sum1 ); - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec3Sum1 ); - vec3Sum1 = vec_add( vec3Sum1, vecPlane3 ); - - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane4, zeroVector ); - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane5, vec3Sum2 ); - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane6, vec3Sum2 ); - vec3Sum2 = vec_add( vec3Sum2, vecPlane7 ); - - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec4Sum1 ); - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec4Sum1 ); - vec4Sum1 = vec_add( vec4Sum1, vecPlane3 ); - - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane4, zeroVector ); - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane5, vec4Sum2 ); - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane6, vec4Sum2 ); - vec4Sum2 = vec_add( vec4Sum2, vecPlane7 ); - - vecCmp1 = vec_cmplt( vec1Sum1, zeroVector ); - vecCmp2 = vec_cmplt( vec1Sum2, zeroVector ); - vecCmp3 = vec_cmplt( vec2Sum1, zeroVector ); - vecCmp4 = vec_cmplt( vec2Sum2, zeroVector ); - vecCmp5 = vec_cmplt( vec3Sum1, zeroVector ); - vecCmp6 = vec_cmplt( vec3Sum2, zeroVector ); - vecCmp7 = vec_cmplt( vec4Sum1, zeroVector ); - vecCmp8 = vec_cmplt( vec4Sum2, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - vecCmp3 = vec_and( vecCmp3, oneIntVector ); - vecCmp4 = vec_and( vecCmp4, oneIntVector ); - vecCmp5 = vec_and( vecCmp5, oneIntVector ); - vecCmp6 = vec_and( vecCmp6, oneIntVector ); - vecCmp7 = vec_and( vecCmp7, oneIntVector ); - vecCmp8 = vec_and( vecCmp8, oneIntVector ); - - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); - vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); - vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); - vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); - vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); - vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); - vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); - - //OR them all together (this is the same as adding them, since they're all only 1 bit set) - vecR1 = (vector unsigned int)(0); //zeroIntVector; - vecR1 = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); - vecR1 = vec_add( vecR1, vec_sld( vecR1, vecR1, 4 ) ); - vecR1 = vec_add(vecR1, vecBitShifted2 ); - vecR1 = vec_or( vecR1, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); - - vecR2 = (vector unsigned int)(0); //zeroIntVector; - vecR2 = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); - vecR2 = vec_add( vecR2, vec_sld( vecR2, vecR2, 4 ) ); - vecR2 = vec_add(vecR2, vecBitShifted4 ); - vecR2 = vec_or( vecR2, vec_sld( vecBitShifted4, vecBitShifted4, 4 ) ); - - vecR3 = (vector unsigned int)(0); //zeroIntVector; - vecR3 = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); - vecR3 = vec_add( vecR3, vec_sld( vecR3, vecR3, 4 ) ); - vecR3 = vec_add(vecR3, vecBitShifted6 ); - vecR3 = vec_or( vecR3, vec_sld( vecBitShifted6, vecBitShifted6, 4 ) ); - - vecR4 = (vector unsigned int)(0); //zeroIntVector; - vecR4 = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); - vecR4 = vec_add( vecR4, vec_sld( vecR4, vecR4, 4 ) ); - vecR4 = vec_add(vecR4, vecBitShifted8 ); - vecR4 = vec_or( vecR4, vec_sld( vecBitShifted8, vecBitShifted8, 4 ) ); - - // take the first element from each vector and put them into vecR1 - vecR1 = vec_mergeh( vecR1, vecR2 ); - vecR3 = vec_mergeh( vecR3, vecR4 ); - vecR1 = vec_perm( vecR1, vecR3, permHalves ); - - // XOR with 0x3F to flip lower 6 bits - vecR1 = vec_xor( vecR1, vecFlipBits ); - - // store out results. don't have 16 at a time so let's just - // do this and avoid alignment concerns - vecR1 = vec_perm( vecR1, vecR1, vBitPerm ); - vec_ste( vecR1, 0, &vBits[0] ); - vec_ste( vecR1, 4, &vBits[0] ); - vec_ste( vecR1, 8, &vBits[0] ); - vec_ste( vecR1, 12, &vBits[0] ); - - cullBits[i] = vBits[0]; - cullBits[i+1] = vBits[1]; - cullBits[i+2] = vBits[2]; - cullBits[i+3] = vBits[3]; - } - - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, d4, d5; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - d4 = planes[4].Distance( v ); - d5 = planes[5].Distance( v ); - - // they check if the sign bit is set by casting as long and shifting right 31 places. - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - bits |= FLOATSIGNBITSET( d2 ) << 2; - bits |= FLOATSIGNBITSET( d3 ) << 3; - bits |= FLOATSIGNBITSET( d4 ) << 4; - bits |= FLOATSIGNBITSET( d5 ) << 5; - - cullBits[i] = bits ^ 0x3F; // flip lower 6 bits - } -} - -#else - -/* -============ -idSIMD_AltiVec::DecalPointCull -============ -*/ -void VPCALL idSIMD_AltiVec::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - int i; - const float *planePtr = planes[0].ToFloatPtr(); - - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3, vecPlane4, vecPlane5, vecPlane6, vecPlane7; - vector float zeroVector = (vector float)(0.0); - vector unsigned char vecPerm; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - - // populate planes - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 4 ); - v3 = vec_ld( 15, planePtr + 4 ); - vecPlane1 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 8 ); - v1 = vec_ld( 15, planePtr + 8 ); - vecPlane2 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 12 ); - v3 = vec_ld( 15, planePtr + 12 ); - vecPlane3 = vec_perm( v2, v3, vecPerm ); - - v0 = vec_ld( 0, planePtr + 16 ); - v1 = vec_ld( 15, planePtr + 16 ); - vecPlane4 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 0, planePtr + 20 ); - v3 = vec_ld( 15, planePtr + 20 ); - vecPlane5 = vec_perm( v2, v3, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane2 ); - v1 = vec_mergeh( vecPlane1, vecPlane3 ); - v2 = vec_mergel( vecPlane0, vecPlane2 ); - v3 = vec_mergel( vecPlane1, vecPlane3 ); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - v0 = vec_mergeh( vecPlane4, zeroVector ); - v1 = vec_mergeh( vecPlane5, zeroVector ); - v2 = vec_mergel( vecPlane4, zeroVector ); - v3 = vec_mergel( vecPlane5, zeroVector ); - - vecPlane4 = vec_mergeh( v0, v1 ); - vecPlane5 = vec_mergel( v0, v1 ); - vecPlane6 = vec_mergeh( v2, v3 ); - vecPlane7 = vec_mergel( v2, v3 ); - - - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector bool int oneIntVector = (vector bool int)(1); - vector float vec1Sum1, vec1Sum2, vec2Sum1, vec2Sum2, vec3Sum1, vec3Sum2, vec4Sum1, vec4Sum2; - vector unsigned int vecShift1 = (vector unsigned int)(0, 1, 2, 3 ); - vector unsigned int vecShift2 = (vector unsigned int)(4, 5, 0, 0 ); - - vector bool int vecCmp1, vecCmp2, vecCmp3, vecCmp4, vecCmp5, vecCmp6, vecCmp7, vecCmp8; - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted3, vecBitShifted4; - vector unsigned int vecBitShifted5, vecBitShifted6, vecBitShifted7, vecBitShifted8; - vector unsigned int vecFlipBits = (vector unsigned int)( 0x3F, 0x3F, 0x3F, 0x3F ); - vector unsigned int vecR1, vecR2, vecR3, vecR4; - vector unsigned char permHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - unsigned int vBits[4]; - vector unsigned char vBitPerm = vec_lvsr( 0, &vBits[4] ); - - i = 0; - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane0, zeroVector ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane1, vec1Sum1 ); - vec1Sum1 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane2, vec1Sum1 ); - vec1Sum1 = vec_add( vec1Sum1, vecPlane3 ); - - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 0 ), vecPlane4, zeroVector ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 1 ), vecPlane5, vec1Sum2 ); - vec1Sum2 = vec_madd( vec_splat( vecXYZ1, 2 ), vecPlane6, vec1Sum2 ); - vec1Sum2 = vec_add( vec1Sum2, vecPlane7 ); - - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane0, zeroVector ); - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane1, vec2Sum1 ); - vec2Sum1 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane2, vec2Sum1 ); - vec2Sum1 = vec_add( vec2Sum1, vecPlane3 ); - - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 0 ), vecPlane4, zeroVector ); - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 1 ), vecPlane5, vec2Sum2 ); - vec2Sum2 = vec_madd( vec_splat( vecXYZ2, 2 ), vecPlane6, vec2Sum2 ); - vec2Sum2 = vec_add( vec2Sum2, vecPlane7 ); - - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane0, zeroVector ); - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane1, vec3Sum1 ); - vec3Sum1 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane2, vec3Sum1 ); - vec3Sum1 = vec_add( vec3Sum1, vecPlane3 ); - - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 0 ), vecPlane4, zeroVector ); - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 1 ), vecPlane5, vec3Sum2 ); - vec3Sum2 = vec_madd( vec_splat( vecXYZ3, 2 ), vecPlane6, vec3Sum2 ); - vec3Sum2 = vec_add( vec3Sum2, vecPlane7 ); - - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane0, zeroVector ); - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane1, vec4Sum1 ); - vec4Sum1 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane2, vec4Sum1 ); - vec4Sum1 = vec_add( vec4Sum1, vecPlane3 ); - - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 0 ), vecPlane4, zeroVector ); - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 1 ), vecPlane5, vec4Sum2 ); - vec4Sum2 = vec_madd( vec_splat( vecXYZ4, 2 ), vecPlane6, vec4Sum2 ); - vec4Sum2 = vec_add( vec4Sum2, vecPlane7 ); - - vecCmp1 = vec_cmplt( vec1Sum1, zeroVector ); - vecCmp2 = vec_cmplt( vec1Sum2, zeroVector ); - vecCmp3 = vec_cmplt( vec2Sum1, zeroVector ); - vecCmp4 = vec_cmplt( vec2Sum2, zeroVector ); - vecCmp5 = vec_cmplt( vec3Sum1, zeroVector ); - vecCmp6 = vec_cmplt( vec3Sum2, zeroVector ); - vecCmp7 = vec_cmplt( vec4Sum1, zeroVector ); - vecCmp8 = vec_cmplt( vec4Sum2, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - vecCmp3 = vec_and( vecCmp3, oneIntVector ); - vecCmp4 = vec_and( vecCmp4, oneIntVector ); - vecCmp5 = vec_and( vecCmp5, oneIntVector ); - vecCmp6 = vec_and( vecCmp6, oneIntVector ); - vecCmp7 = vec_and( vecCmp7, oneIntVector ); - vecCmp8 = vec_and( vecCmp8, oneIntVector ); - - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift1 ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift2 ); - vecBitShifted3 = vec_sl( (vector unsigned int)vecCmp3, vecShift1 ); - vecBitShifted4 = vec_sl( (vector unsigned int)vecCmp4, vecShift2 ); - vecBitShifted5 = vec_sl( (vector unsigned int)vecCmp5, vecShift1 ); - vecBitShifted6 = vec_sl( (vector unsigned int)vecCmp6, vecShift2 ); - vecBitShifted7 = vec_sl( (vector unsigned int)vecCmp7, vecShift1 ); - vecBitShifted8 = vec_sl( (vector unsigned int)vecCmp8, vecShift2 ); - - //OR them all together (this is the same as adding them, since they're all only 1 bit set) - vecR1 = (vector unsigned int)(0); //zeroIntVector; - vecR1 = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 8 ) ); - vecR1 = vec_add( vecR1, vec_sld( vecR1, vecR1, 4 ) ); - vecR1 = vec_add(vecR1, vecBitShifted2 ); - vecR1 = vec_or( vecR1, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); - - vecR2 = (vector unsigned int)(0); //zeroIntVector; - vecR2 = vec_add( vecBitShifted3, vec_sld( vecBitShifted3, vecBitShifted3, 8 ) ); - vecR2 = vec_add( vecR2, vec_sld( vecR2, vecR2, 4 ) ); - vecR2 = vec_add(vecR2, vecBitShifted4 ); - vecR2 = vec_or( vecR2, vec_sld( vecBitShifted4, vecBitShifted4, 4 ) ); - - vecR3 = (vector unsigned int)(0); //zeroIntVector; - vecR3 = vec_add( vecBitShifted5, vec_sld( vecBitShifted5, vecBitShifted5, 8 ) ); - vecR3 = vec_add( vecR3, vec_sld( vecR3, vecR3, 4 ) ); - vecR3 = vec_add(vecR3, vecBitShifted6 ); - vecR3 = vec_or( vecR3, vec_sld( vecBitShifted6, vecBitShifted6, 4 ) ); - - vecR4 = (vector unsigned int)(0); //zeroIntVector; - vecR4 = vec_add( vecBitShifted7, vec_sld( vecBitShifted7, vecBitShifted7, 8 ) ); - vecR4 = vec_add( vecR4, vec_sld( vecR4, vecR4, 4 ) ); - vecR4 = vec_add(vecR4, vecBitShifted8 ); - vecR4 = vec_or( vecR4, vec_sld( vecBitShifted8, vecBitShifted8, 4 ) ); - - // take the first element from each vector and put them into vecR1 - vecR1 = vec_mergeh( vecR1, vecR2 ); - vecR3 = vec_mergeh( vecR3, vecR4 ); - vecR1 = vec_perm( vecR1, vecR3, permHalves ); - - // XOR with 0x3F to flip lower 6 bits - vecR1 = vec_xor( vecR1, vecFlipBits ); - - // store out results. don't have 16 at a time so let's just - // do this and avoid alignment concerns - vecR1 = vec_perm( vecR1, vecR1, vBitPerm ); - vec_ste( vecR1, 0, &vBits[0] ); - vec_ste( vecR1, 4, &vBits[0] ); - vec_ste( vecR1, 8, &vBits[0] ); - vec_ste( vecR1, 12, &vBits[0] ); - - cullBits[i] = vBits[0]; - cullBits[i+1] = vBits[1]; - cullBits[i+2] = vBits[2]; - cullBits[i+3] = vBits[3]; - } - - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, d4, d5; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - d4 = planes[4].Distance( v ); - d5 = planes[5].Distance( v ); - - // they check if the sign bit is set by casting as long and shifting right 31 places. - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - bits |= FLOATSIGNBITSET( d2 ) << 2; - bits |= FLOATSIGNBITSET( d3 ) << 3; - bits |= FLOATSIGNBITSET( d4 ) << 4; - bits |= FLOATSIGNBITSET( d5 ) << 5; - - cullBits[i] = bits ^ 0x3F; // flip lower 6 bits - } -} - - -#endif /*DRAWVERT_PADDED */ - -#ifndef DRAWVERT_PADDED -/* -============ -idSIMD_AltiVec::OverlayPointCull -============ -*/ -void VPCALL idSIMD_AltiVec::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - int i; - - float p0x, p0y, p0z, p0d; - float p1x, p1y, p1z, p1d; - - const float *planePtr = planes[0].ToFloatPtr(); - const float *vertPtr = verts[0].xyz.ToFloatPtr(); - - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - vector unsigned char vecPerm; - vector float zeroVector = (vector float)(0); - - p0x = *(planePtr + 0); - p0y = *(planePtr + 1); - p0z = *(planePtr + 2); - p0d = *(planePtr + 3); - p1x = *(planePtr + 4); - p1y = *(planePtr + 5); - p1z = *(planePtr + 6); - p1d = *(planePtr + 7); - - // populate the planes - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 31, planePtr ); - vecPlane1 = vec_perm( v1, v2, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane0 ); - v1 = vec_mergeh( vecPlane1, vecPlane1 ); - v2 = vec_mergel( vecPlane0, vecPlane0 ); - v3 = vec_mergel( vecPlane1, vecPlane1); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector float oneVector = (vector float)(1); - - vector float vecSum1, vecSum2, vecSum1Inv,vecSum2Inv; - - vector bool int vecCmp1, vecCmp2, vecCmp1Inv, vecCmp2Inv; - vector float negTwoVector = (vector float)(-2); - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted1Inv, vecBitShifted2Inv; - vector unsigned int vecShift = (vector unsigned int)( 0, 1, 0, 1 ); - vector unsigned int vecShiftInv = (vector unsigned int)( 2, 3, 2, 3 ); - vector unsigned char vecPermFirstThird = (vector unsigned char)(0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27); - vector bool int oneIntVector = (vector bool int)(1); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - unsigned int cullBitVal[4]; - vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); - - i = 0; - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < numVerts ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } - - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - vecXYZ1 = vec_perm( v0, v1, vertPerm1 ); - vecXYZ2 = vec_perm( v2, v3, vertPerm2 ); - vecXYZ3 = vec_perm( v4, v5, vertPerm3 ); - vecXYZ4 = vec_perm( v6, v7, vertPerm4 ); - - // like a splat, but only doing halves - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum1 ); - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum1 ); - vecSum1 = vec_add( vecSum1, vecPlane3 ); - - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum2 ); - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum2 ); - vecSum2 = vec_add( vecSum2, vecPlane3 ); - - // store out results - UNALIGNED_STORE2( &texCoords[i][0], vecSum1, vecSum2 ); - - // bit manipulation - vecCmp1 = vec_cmplt( vecSum1, zeroVector ); - vecCmp2 = vec_cmplt( vecSum2, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - - // store out and write to cullBits - // finally, a use for algebra! 1-x = x + 1 - 2x - vecSum1Inv = vec_madd( vecSum1, negTwoVector, vecSum1 ); - vecSum2Inv = vec_madd( vecSum2, negTwoVector, vecSum2 ); - vecSum1Inv = vec_add( vecSum1Inv, oneVector ); - vecSum2Inv = vec_add( vecSum2Inv, oneVector ); - - // do the same comparisons for the inverted d0/d1 - vecCmp1Inv = vec_cmplt( vecSum1Inv, zeroVector ); - vecCmp2Inv = vec_cmplt( vecSum2Inv, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1Inv = vec_and( vecCmp1Inv, oneIntVector ); - vecCmp2Inv = vec_and( vecCmp2Inv, oneIntVector ); - - // shift them as needed - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift ); - vecBitShifted1Inv = vec_sl( (vector unsigned int)vecCmp1Inv, vecShiftInv ); - vecBitShifted2Inv = vec_sl( (vector unsigned int)vecCmp2Inv, vecShiftInv ); - - // OR them all together. since only 1 bit is set for each value, thats - // the same as adding them. add up d0 + d1 + d0Inv + d1Inv - vector unsigned int vecResult; - vector unsigned int vecResult2; - vector unsigned int vecResult3; - vecResult = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 4 ) ); - - vecResult2 = vec_add( vecBitShifted2, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); - - // vecResult now holds the values without the inverses yet, so add those - vecResult = vec_perm( vecResult, vecResult2, vecPermFirstThird ); - vecResult2 = vec_add( vecBitShifted1Inv, vec_sld( vecBitShifted1Inv, vecBitShifted1Inv, 4 ) ); - vecResult3 = vec_add( vecBitShifted2Inv, vec_sld( vecBitShifted2Inv, vecBitShifted2Inv, 4 ) ); - vecResult2 = vec_perm( vecResult2, vecResult3, vecPermFirstThird ); - - vecResult = vec_add( vecResult, vecResult2 ); - - //store out results - vecResult = vec_perm( vecResult, vecResult, cullBitPerm ); - vec_ste( vecResult, 0, &cullBitVal[0] ); - vec_ste( vecResult, 4, &cullBitVal[0] ); - vec_ste( vecResult, 8, &cullBitVal[0] ); - vec_ste( vecResult, 12, &cullBitVal[0] ); - - cullBits[i] = cullBitVal[0]; - cullBits[i+1] = cullBitVal[1]; - cullBits[i+2] = cullBitVal[2]; - cullBits[i+3] = cullBitVal[3]; - } - - // cleanup - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1; - float vx, vy, vz; - - vx = *( vertPtr + (i*DRAWVERT_OFFSET) + 0 ); - vy = *( vertPtr + (i*DRAWVERT_OFFSET) + 1 ); - vz = *( vertPtr + (i*DRAWVERT_OFFSET) + 2 ); - - d0 = p0x * vx + p0y * vy + p0z * vz + p0d; - d1 = p1x * vx + p1y * vy + p1z * vz + p1d; - texCoords[i][0] = d0; - texCoords[i][1] = d1; - - bits = ( d0 >= 0 ) ? 0 : 1; - d0 = 1.0f - d0; - bits |= ( d1 >= 0 ) ? 0 : 1*2; - d1 = 1.0f - d1; - - bits |= ( d0 >= 0 ) ? 0: 1*4; - bits |= ( d1 >= 0 ) ? 0: 1*8; - - cullBits[i] = bits; - } -} -#else - -/* -============ -idSIMD_AltiVec::OverlayPointCull -============ -*/ -void VPCALL idSIMD_AltiVec::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - int i; - - float p0x, p0y, p0z, p0d; - float p1x, p1y, p1z, p1d; - - const float *planePtr = planes[0].ToFloatPtr(); - const float *vertPtr = verts[0].xyz.ToFloatPtr(); - - vector float vecPlane0, vecPlane1, vecPlane2, vecPlane3; - vector float v0, v1, v2, v3, v4, v5, v6, v7; - vector unsigned char vecPerm; - vector float zeroVector = (vector float)(0); - - p0x = *(planePtr + 0); - p0y = *(planePtr + 1); - p0z = *(planePtr + 2); - p0d = *(planePtr + 3); - p1x = *(planePtr + 4); - p1y = *(planePtr + 5); - p1z = *(planePtr + 6); - p1d = *(planePtr + 7); - - // populate the planes - vecPerm = vec_add( vec_lvsl( -1, planePtr ), (vector unsigned char)(1) ); - v0 = vec_ld( 0, planePtr ); - v1 = vec_ld( 15, planePtr ); - vecPlane0 = vec_perm( v0, v1, vecPerm ); - - v2 = vec_ld( 31, planePtr ); - vecPlane1 = vec_perm( v1, v2, vecPerm ); - - // transpose - v0 = vec_mergeh( vecPlane0, vecPlane0 ); - v1 = vec_mergeh( vecPlane1, vecPlane1 ); - v2 = vec_mergel( vecPlane0, vecPlane0 ); - v3 = vec_mergel( vecPlane1, vecPlane1); - - vecPlane0 = vec_mergeh( v0, v1 ); - vecPlane1 = vec_mergel( v0, v1 ); - vecPlane2 = vec_mergeh( v2, v3 ); - vecPlane3 = vec_mergel( v2, v3 ); - - vector float vecXYZ1, vecXYZ2, vecXYZ3, vecXYZ4; - vector float oneVector = (vector float)(1); - - vector float vecSum1, vecSum2, vecSum1Inv,vecSum2Inv; - - vector bool int vecCmp1, vecCmp2, vecCmp1Inv, vecCmp2Inv; - vector float negTwoVector = (vector float)(-2); - vector unsigned int vecBitShifted1, vecBitShifted2, vecBitShifted1Inv, vecBitShifted2Inv; - vector unsigned int vecShift = (vector unsigned int)( 0, 1, 0, 1 ); - vector unsigned int vecShiftInv = (vector unsigned int)( 2, 3, 2, 3 ); - vector unsigned char vecPermFirstThird = (vector unsigned char)(0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27); - vector bool int oneIntVector = (vector bool int)(1); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - unsigned int cullBitVal[4]; - vector unsigned char cullBitPerm = vec_lvsr( 0, &cullBitVal[0] ); - - i = 0; - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - - vecXYZ1 = vec_ld( 0, vertPtr ); - vecXYZ2 = vec_ld( 0, vertPtr2 ); - vecXYZ3 = vec_ld( 0, vertPtr3 ); - vecXYZ4 = vec_ld( 0, vertPtr4 ); - - // like a splat, but only doing halves - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum1 ); - vecSum1 = vec_madd( vec_perm( vecXYZ1, vecXYZ2, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum1 ); - vecSum1 = vec_add( vecSum1, vecPlane3 ); - - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(0,1,2,3,0,1,2,3,16,17,18,19,16,17,18,19) ), vecPlane0, zeroVector ); - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(4,5,6,7,4,5,6,7,20,21,22,23,20,21,22,23) ) , vecPlane1, vecSum2 ); - vecSum2 = vec_madd( vec_perm( vecXYZ3, vecXYZ4, (vector unsigned char)(8,9,10,11,8,9,10,11,24,25,26,27,24,25,26,27) ), vecPlane2, vecSum2 ); - vecSum2 = vec_add( vecSum2, vecPlane3 ); - - // store out results - UNALIGNED_STORE2( &texCoords[i][0], vecSum1, vecSum2 ); - - // bit manipulation - vecCmp1 = vec_cmplt( vecSum1, zeroVector ); - vecCmp2 = vec_cmplt( vecSum2, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1 = vec_and( vecCmp1, oneIntVector ); - vecCmp2 = vec_and( vecCmp2, oneIntVector ); - - // store out and write to cullBits - // finally, a use for algebra! 1-x = x + 1 - 2x - vecSum1Inv = vec_madd( vecSum1, negTwoVector, vecSum1 ); - vecSum2Inv = vec_madd( vecSum2, negTwoVector, vecSum2 ); - vecSum1Inv = vec_add( vecSum1Inv, oneVector ); - vecSum2Inv = vec_add( vecSum2Inv, oneVector ); - - // do the same comparisons for the inverted d0/d1 - vecCmp1Inv = vec_cmplt( vecSum1Inv, zeroVector ); - vecCmp2Inv = vec_cmplt( vecSum2Inv, zeroVector ); - - //and it with 1 so we multiply by 1 not 1111's - vecCmp1Inv = vec_and( vecCmp1Inv, oneIntVector ); - vecCmp2Inv = vec_and( vecCmp2Inv, oneIntVector ); - - // shift them as needed - vecBitShifted1 = vec_sl( (vector unsigned int)vecCmp1, vecShift ); - vecBitShifted2 = vec_sl( (vector unsigned int)vecCmp2, vecShift ); - vecBitShifted1Inv = vec_sl( (vector unsigned int)vecCmp1Inv, vecShiftInv ); - vecBitShifted2Inv = vec_sl( (vector unsigned int)vecCmp2Inv, vecShiftInv ); - - // OR them all together. since only 1 bit is set for each value, thats - // the same as adding them. add up d0 + d1 + d0Inv + d1Inv - vector unsigned int vecResult; - vector unsigned int vecResult2; - vector unsigned int vecResult3; - vecResult = vec_add( vecBitShifted1, vec_sld( vecBitShifted1, vecBitShifted1, 4 ) ); - - vecResult2 = vec_add( vecBitShifted2, vec_sld( vecBitShifted2, vecBitShifted2, 4 ) ); - - // vecResult now holds the values without the inverses yet, so add those - vecResult = vec_perm( vecResult, vecResult2, vecPermFirstThird ); - vecResult2 = vec_add( vecBitShifted1Inv, vec_sld( vecBitShifted1Inv, vecBitShifted1Inv, 4 ) ); - vecResult3 = vec_add( vecBitShifted2Inv, vec_sld( vecBitShifted2Inv, vecBitShifted2Inv, 4 ) ); - vecResult2 = vec_perm( vecResult2, vecResult3, vecPermFirstThird ); - - vecResult = vec_add( vecResult, vecResult2 ); - - //store out results - vecResult = vec_perm( vecResult, vecResult, cullBitPerm ); - vec_ste( vecResult, 0, &cullBitVal[0] ); - vec_ste( vecResult, 4, &cullBitVal[0] ); - vec_ste( vecResult, 8, &cullBitVal[0] ); - vec_ste( vecResult, 12, &cullBitVal[0] ); - - cullBits[i] = cullBitVal[0]; - cullBits[i+1] = cullBitVal[1]; - cullBits[i+2] = cullBitVal[2]; - cullBits[i+3] = cullBitVal[3]; - } - - // cleanup - for ( ; i < numVerts; i++ ) { - byte bits; - float d0, d1; - float vx, vy, vz; - - vx = *( vertPtr + (i*DRAWVERT_OFFSET) + 0 ); - vy = *( vertPtr + (i*DRAWVERT_OFFSET) + 1 ); - vz = *( vertPtr + (i*DRAWVERT_OFFSET) + 2 ); - - d0 = p0x * vx + p0y * vy + p0z * vz + p0d; - d1 = p1x * vx + p1y * vy + p1z * vz + p1d; - texCoords[i][0] = d0; - texCoords[i][1] = d1; - - bits = ( d0 >= 0 ) ? 0 : 1; - d0 = 1.0f - d0; - bits |= ( d1 >= 0 ) ? 0 : 1*2; - d1 = 1.0f - d1; - - bits |= ( d0 >= 0 ) ? 0: 1*4; - bits |= ( d1 >= 0 ) ? 0: 1*8; - - cullBits[i] = bits; - } -} - - -#endif /* DRAWVERT_PADDED */ - -#endif /* ENABLE_CULL */ - -#ifdef ENABLE_DERIVE -/* -============ -idSIMD_AltiVec::DeriveTriPlanes - - Derives a plane equation for each triangle. -============ -*/ -void VPCALL idSIMD_AltiVec::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - // idPlane size - assert( sizeof(idPlane) == PLANE_OFFSET * sizeof(float) ); - int i; - - vector float vecD0, vecD1, vecD2, vecD3, vecD4, vecD5, vecD6, vecD7; - vector float vecVertA, vecVertB, vecVertC; - vector float vecVertA2, vecVertB2, vecVertC2; - vector float vecVertA3, vecVertB3, vecVertC3; - vector float vecVertA4, vecVertB4, vecVertC4; - - vector float vecN, vecN2, vecN3, vecN4; - vector float vecWork1, vecWork2, vecWork3, vecWork4, vecWork5, vecWork6, vecWork7, vecWork8; - vector unsigned char vecPerm1 = (vector unsigned char)(4,5,6,7,8,9,10,11,0,1,2,3,12,13,14,15); - vector unsigned char vecPerm2 = (vector unsigned char)(8,9,10,11,0,1,2,3,4,5,6,7,12,13,14,15); - vector float vecF; - vector float vecF1, vecF2, vecF3, vecF4; - vector float zeroVector = (vector float)(0); - vector float vecNegOne = (vector float)(-1); - vector float vecSecondHalf, vecFirstHalf, vecSecondHalf2, vecFirstHalf2, vecSecondHalf3, vecFirstHalf3, vecFirstHalf4, vecSecondHalf4; - - vector unsigned char vecPermA, vecPermA2, vecPermA3, vecPermA4; - vector unsigned char vecPermB, vecPermB2, vecPermB3, vecPermB4; - vector unsigned char vecPermC, vecPermC2, vecPermC3, vecPermC4; - - vector unsigned char oneVector = (vector unsigned char)(1); - vector float vecLd1, vecLd2, vecLd3, vecLd4, vecLd5, vecLd6; - vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - - const float *xyzPtr = verts[0].xyz.ToFloatPtr(); - float *planePtr = planes[0].ToFloatPtr(); - - int j; - for ( j = 0, i = 0; i+11 < numIndexes; i += 12, j += 4 ) { - -#ifndef DRAWVERT_PADDED - // calculate permute vectors to load as needed. these are all - // triangle indexes and are usaully pretty close together but - // not guaranteed to be in any particular order - vecPermA = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermB = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermC = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermA2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermB2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermC2 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermA3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermB3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermC3 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermA4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermB4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ), oneVector ); - vecPermC4 = vec_add( vec_lvsl( -1, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ), oneVector ); -#endif - -#ifndef DRAWVERT_PADDED - // load first A B C - vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); - vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); - vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); - vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); - vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); - vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); - - vecVertA = vec_perm( vecLd1, vecLd2, vecPermA ); - vecVertB = vec_perm( vecLd3, vecLd4, vecPermB ); - vecVertC = vec_perm( vecLd5, vecLd6, vecPermC ); - - // set the last element to 0 - vecVertA = vec_perm( vecVertA, zeroVector, vecPermZeroLast ); - vecVertB = vec_perm( vecVertB, zeroVector, vecPermZeroLast ); - vecVertC = vec_perm( vecVertC, zeroVector, vecPermZeroLast ); - - // load second A B C - vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); - vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); - vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); - vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); - vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); - vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); - - vecVertA2 = vec_perm( vecLd1, vecLd2, vecPermA2 ); - vecVertB2 = vec_perm( vecLd3, vecLd4, vecPermB2 ); - vecVertC2 = vec_perm( vecLd5, vecLd6, vecPermC2 ); - - // set the last element to 0 - vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); - vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); - vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); - - // load third A B C - vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); - vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); - vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); - vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); - vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); - vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); - - vecVertA3 = vec_perm( vecLd1, vecLd2, vecPermA3 ); - vecVertB3 = vec_perm( vecLd3, vecLd4, vecPermB3 ); - vecVertC3 = vec_perm( vecLd5, vecLd6, vecPermC3 ); - - // set the last element to 0 - vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); - vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); - vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); - - // load the fourth A B C - vecLd1 = vec_ld( 0, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); - vecLd2 = vec_ld( 15, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); - vecLd3 = vec_ld( 0, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); - vecLd4 = vec_ld( 15, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); - vecLd5 = vec_ld( 0, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); - vecLd6 = vec_ld( 15, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); - - vecVertA4 = vec_perm( vecLd1, vecLd2, vecPermA4 ); - vecVertB4 = vec_perm( vecLd3, vecLd4, vecPermB4 ); - vecVertC4 = vec_perm( vecLd5, vecLd6, vecPermC4 ); - - // set the last element to 0 - vecVertA4 = vec_perm( vecVertA4, zeroVector, vecPermZeroLast ); - vecVertB4 = vec_perm( vecVertB4, zeroVector, vecPermZeroLast ); - vecVertC4 = vec_perm( vecVertC4, zeroVector, vecPermZeroLast ); -#else - // load first A B C - vecVertA = vec_ld( 0, xyzPtr + ( indexes[i+0] * DRAWVERT_OFFSET ) ); - vecVertB = vec_ld( 0, xyzPtr + ( indexes[i+1] * DRAWVERT_OFFSET ) ); - vecVertC = vec_ld( 0, xyzPtr + ( indexes[i+2] * DRAWVERT_OFFSET ) ); - - // set the last element to 0 - vecVertA = vec_perm( vecVertA, zeroVector, vecPermZeroLast ); - vecVertB = vec_perm( vecVertB, zeroVector, vecPermZeroLast ); - vecVertC = vec_perm( vecVertC, zeroVector, vecPermZeroLast ); - - // load second A B C - vecVertA2 = vec_ld( 0, xyzPtr + ( indexes[i+3] * DRAWVERT_OFFSET ) ); - vecVertB2 = vec_ld( 0, xyzPtr + ( indexes[i+4] * DRAWVERT_OFFSET ) ); - vecVertC2 = vec_ld( 0, xyzPtr + ( indexes[i+5] * DRAWVERT_OFFSET ) ); - - // set the last element to 0 - vecVertA2 = vec_perm( vecVertA2, zeroVector, vecPermZeroLast ); - vecVertB2 = vec_perm( vecVertB2, zeroVector, vecPermZeroLast ); - vecVertC2 = vec_perm( vecVertC2, zeroVector, vecPermZeroLast ); - - // load third A B C - vecVertA3 = vec_ld( 0, xyzPtr + ( indexes[i+6] * DRAWVERT_OFFSET ) ); - vecVertB3 = vec_ld( 0, xyzPtr + ( indexes[i+7] * DRAWVERT_OFFSET ) ); - vecVertC3 = vec_ld( 0, xyzPtr + ( indexes[i+8] * DRAWVERT_OFFSET ) ); - - // set the last element to 0 - vecVertA3 = vec_perm( vecVertA3, zeroVector, vecPermZeroLast ); - vecVertB3 = vec_perm( vecVertB3, zeroVector, vecPermZeroLast ); - vecVertC3 = vec_perm( vecVertC3, zeroVector, vecPermZeroLast ); - - // load the fourth A B C - vecVertA4 = vec_ld( 0, xyzPtr + ( indexes[i+9] * DRAWVERT_OFFSET ) ); - vecVertB4 = vec_ld( 0, xyzPtr + ( indexes[i+10] * DRAWVERT_OFFSET ) ); - vecVertC4 = vec_ld( 0, xyzPtr + ( indexes[i+11] * DRAWVERT_OFFSET ) ); - - // set the last element to 0 - vecVertA4 = vec_perm( vecVertA4, zeroVector, vecPermZeroLast ); - vecVertB4 = vec_perm( vecVertB4, zeroVector, vecPermZeroLast ); - vecVertC4 = vec_perm( vecVertC4, zeroVector, vecPermZeroLast ); -#endif - // calculate d0 and d1 for each - vecD0 = vec_sub( vecVertB, vecVertA ); - vecD1 = vec_sub( vecVertC, vecVertA ); - - vecD2 = vec_sub( vecVertB2, vecVertA2 ); - vecD3 = vec_sub( vecVertC2, vecVertA2 ); - - vecD4 = vec_sub( vecVertB3, vecVertA3 ); - vecD5 = vec_sub( vecVertC3, vecVertA3 ); - - vecD6 = vec_sub( vecVertB4, vecVertA4 ); - vecD7 = vec_sub( vecVertC4, vecVertA4 ); - - vecWork1 = vec_perm( vecD0, vecD0, vecPerm1 ); - vecWork2 = vec_perm( vecD1, vecD1, vecPerm2 ); - vecWork3 = vec_perm( vecD2, vecD2, vecPerm1 ); - vecWork4 = vec_perm( vecD3, vecD3, vecPerm2 ); - vecWork5 = vec_perm( vecD4, vecD4, vecPerm1 ); - vecWork6 = vec_perm( vecD5, vecD5, vecPerm2 ); - vecWork7 = vec_perm( vecD6, vecD6, vecPerm1 ); - vecWork8 = vec_perm( vecD7, vecD7, vecPerm2 ); - - vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecWork1 = vec_perm( vecD1, vecD1, vecPerm1 ); - vecWork2 = vec_perm( vecD0, vecD0, vecPerm2 ); - vecWork3 = vec_perm( vecD3, vecD3, vecPerm1 ); - vecWork4 = vec_perm( vecD2, vecD2, vecPerm2 ); - vecWork5 = vec_perm( vecD5, vecD5, vecPerm1 ); - vecWork6 = vec_perm( vecD4, vecD4, vecPerm2 ); - vecWork7 = vec_perm( vecD7, vecD7, vecPerm1 ); - vecWork8 = vec_perm( vecD6, vecD6, vecPerm2 ); - - vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecN = vec_madd( vecSecondHalf, vecNegOne, vecFirstHalf ); - vecN2 = vec_madd( vecSecondHalf2, vecNegOne, vecFirstHalf2 ); - vecN3 = vec_madd( vecSecondHalf3, vecNegOne, vecFirstHalf3 ); - vecN4 = vec_madd( vecSecondHalf4, vecNegOne, vecFirstHalf4 ); - - // transpose vecNs - vector float v0, v1, v2, v3; - v0 = vec_mergeh( vecN, vecN3 ); - v1 = vec_mergeh( vecN2, vecN4 ); - v2 = vec_mergel( vecN, vecN3 ); - v3 = vec_mergel( vecN2, vecN4 ); - - vecN = vec_mergeh( v0, v1 ); - vecN2 = vec_mergel( v0, v1 ); - vecN3 = vec_mergeh( v2, v3 ); - vecN4 = vec_mergel( v2, v3 ); - - vecF = vec_madd( vecN, vecN, zeroVector ); - vecF = vec_madd( vecN2, vecN2, vecF ); - vecF = vec_madd( vecN3, vecN3, vecF ); - - vecF = ReciprocalSquareRoot( vecF ); - - vecF1 = vec_madd( vecF, vecN, zeroVector ); - vecF2 = vec_madd( vecF, vecN2, zeroVector ); - vecF3 = vec_madd( vecF, vecN3, zeroVector ); - vecF4 = vec_madd( vecF, vecN4, zeroVector ); - - vector float v8, v9, v10, v11; - v8 = vecF1; - v9 = vecF2; - v10 = vecF3; - v11 = vecF4; - - // transpose vecVerts - v0 = vec_mergeh( vecVertA, vecVertA3 ); - v1 = vec_mergeh( vecVertA2, vecVertA4 ); - v2 = vec_mergel( vecVertA, vecVertA3 ); - v3 = vec_mergel( vecVertA2, vecVertA4 ); - - vecVertA = vec_mergeh( v0, v1 ); - vecVertA2 = vec_mergel( v0, v1 ); - vecVertA3 = vec_mergeh( v2, v3 ); - vecVertA4 = vec_mergel( v2, v3 ); - - vector float vecTotals; - vecTotals = vec_madd( vecVertA, v8, zeroVector ); - vecTotals = vec_madd( vecVertA2, v9, vecTotals ); - vecTotals = vec_madd( vecVertA3, v10, vecTotals ); - vecTotals = vec_madd( vecVertA4, v11, vecTotals ); - vecF = vec_madd( vecTotals, vecNegOne, zeroVector ); - - // transpose vecFs - v0 = vec_mergeh( vecF1, vecF3 ); - v1 = vec_mergeh( vecF2, vecF ); - v2 = vec_mergel( vecF1, vecF3 ); - v3 = vec_mergel( vecF2, vecF ); - - vecF1 = vec_mergeh( v0, v1 ); - vecF2 = vec_mergel( v0, v1 ); - vecF3 = vec_mergeh( v2, v3 ); - vecF4 = vec_mergel( v2, v3 ); - - // store results - UNALIGNED_STORE4( planePtr + ( j * PLANE_OFFSET ), vecF1, vecF2, vecF3, vecF4 ); - } - - // cleanup - for ( ; i < numIndexes; i += 3, j++ ) { - const idDrawVert *a, *b, *c; - float d0[3], d1[3], f; - idVec3 n; - - a = verts + indexes[i + 0]; - b = verts + indexes[i + 1]; - c = verts + indexes[i + 2]; - - d0[0] = b->xyz[0] - a->xyz[0]; - d0[1] = b->xyz[1] - a->xyz[1]; - d0[2] = b->xyz[2] - a->xyz[2]; - - d1[0] = c->xyz[0] - a->xyz[0]; - d1[1] = c->xyz[1] - a->xyz[1]; - d1[2] = c->xyz[2] - a->xyz[2]; - - n[0] = d1[1] * d0[2] - d1[2] * d0[1]; - n[1] = d1[2] * d0[0] - d1[0] * d0[2]; - n[2] = d1[0] * d0[1] - d1[1] * d0[0]; - - f = FastScalarInvSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); - //idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); - - n.x *= f; - n.y *= f; - n.z *= f; - - planes[j].SetNormal( n ); - planes[j].FitThroughPoint( a->xyz ); - } -} - -/* -============ -idSIMD_AltiVec::DeriveTangents - - Derives the normal and orthogonal tangent vectors for the triangle vertices. - For each vertex the normal and tangent vectors are derived from all triangles - using the vertex which results in smooth tangents across the mesh. - In the process the triangle planes are calculated as well. - -============ -*/ -void VPCALL idSIMD_AltiVec::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - int i; - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - idPlane *planesPtr = planes; - for ( i = 0; i < numIndexes; i += 3 ) { - idDrawVert *a, *b, *c; - // unsigned long signBit; - float d0[5], d1[5], area; - idVec3 n, t0, t1; - float f1, f2, f3; - - int v0 = indexes[i + 0]; - int v1 = indexes[i + 1]; - int v2 = indexes[i + 2]; - - a = verts + v0; - b = verts + v1; - c = verts + v2; - - d0[0] = b->xyz[0] - a->xyz[0]; - d0[1] = b->xyz[1] - a->xyz[1]; - d0[2] = b->xyz[2] - a->xyz[2]; - d0[3] = b->st[0] - a->st[0]; - d0[4] = b->st[1] - a->st[1]; - - d1[0] = c->xyz[0] - a->xyz[0]; - d1[1] = c->xyz[1] - a->xyz[1]; - d1[2] = c->xyz[2] - a->xyz[2]; - d1[3] = c->st[0] - a->st[0]; - d1[4] = c->st[1] - a->st[1]; - - // normal - n[0] = d1[1] * d0[2] - d1[2] * d0[1]; - n[1] = d1[2] * d0[0] - d1[0] * d0[2]; - n[2] = d1[0] * d0[1] - d1[1] * d0[0]; - - f1 = n.x * n.x + n.y * n.y + n.z * n.z; - - // area sign bit - area = d0[3] * d1[4] - d0[4] * d1[3]; - - // first tangent - t0[0] = d0[0] * d1[4] - d0[4] * d1[0]; - t0[1] = d0[1] * d1[4] - d0[4] * d1[1]; - t0[2] = d0[2] * d1[4] - d0[4] * d1[2]; - - f2 = t0.x * t0.x + t0.y * t0.y + t0.z * t0.z; - - // second tangent - t1[0] = d0[3] * d1[0] - d0[0] * d1[3]; - t1[1] = d0[3] * d1[1] - d0[1] * d1[3]; - t1[2] = d0[3] * d1[2] - d0[2] * d1[3]; - - f3 = t1.x * t1.x + t1.y * t1.y + t1.z * t1.z; - - // Behold! The power of the pipeline - FastScalarInvSqrt_x3( &f1, &f2, &f3 ); -#ifdef PPC_INTRINSICS - f2 = __fsel( area, f2, -f2 ); - f3 = __fsel( area, f3, -f3 ); -#else - f2 = ( area < 0.0f ) ? -f2 : f2; - f3 = ( area < 0.0f ) ? -f3 : f3; -#endif - t0.x *= f2; - t0.y *= f2; - t0.z *= f2; - - n.x *= f1; - n.y *= f1; - n.z *= f1; - - planesPtr->SetNormal( n ); - planesPtr->FitThroughPoint( a->xyz ); - planesPtr++; - - t1.x *= f3; - t1.y *= f3; - t1.z *= f3; - - if ( used[v0] ) { - a->normal += n; - a->tangents[0] += t0; - a->tangents[1] += t1; - } else { - a->normal = n; - a->tangents[0] = t0; - a->tangents[1] = t1; - used[v0] = true; - } - - if ( used[v1] ) { - b->normal += n; - b->tangents[0] += t0; - b->tangents[1] += t1; - } else { - b->normal = n; - b->tangents[0] = t0; - b->tangents[1] = t1; - used[v1] = true; - } - - if ( used[v2] ) { - c->normal += n; - c->tangents[0] += t0; - c->tangents[1] += t1; - } else { - c->normal = n; - c->tangents[0] = t0; - c->tangents[1] = t1; - used[v2] = true; - } - } -} - - -#ifdef DERIVE_UNSMOOTH_DRAWVERT_ALIGNED - -/* -============ -idSIMD_AltiVec::DeriveUnsmoothedTangents - - Derives the normal and orthogonal tangent vectors for the triangle vertices. - For each vertex the normal and tangent vectors are derived from a single dominant triangle. -============ -*/ -#define DERIVE_UNSMOOTHED_BITANGENT -void VPCALL idSIMD_AltiVec::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { - - int i; - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - // drawverts aligned - assert( IS_16BYTE_ALIGNED( verts[0] ) ); - - vector float vecVertA, vecVertB, vecVertC; - vector float vecVertA2, vecVertB2, vecVertC2; - vector float vecVertA3, vecVertB3, vecVertC3; - vector float vecVertA4, vecVertB4, vecVertC4; - - vector float v0, v1, v2, v3, v4, v5, v6, v7, v8; - vector float vecS0, vecS1, vecS2; - vector float vecS0_2, vecS1_2, vecS2_2; - vector float vecS0_3, vecS1_3, vecS2_3; - vector float vecS0_4, vecS1_4, vecS2_4; - - vector float vecD1, vecD2, vecD3, vecD4, vecD5, vecD6; - vector float vecD7, vecD8, vecD9, vecD10, vecD11, vecD12; - vector float vecT1, vecT1_2, vecT1_3, vecT1_4, vecT2, vecT2_2, vecT2_3, vecT2_4; - vector float vecWork1, vecWork2, vecWork3, vecWork4, vecWork5, vecWork6, vecWork7, vecWork8; - vector float vecN, vecN2, vecN3, vecN4; - - vector unsigned char vecPermN0 = (vector unsigned char)(8,9,10,11,0,1,2,3,4,5,6,7,12,13,14,15); - vector unsigned char vecPermN1 = (vector unsigned char)(4,5,6,7,8,9,10,11,0,1,2,3,12,13,14,15); - vector unsigned char vecPermT0 = (vector unsigned char)(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3); - vector unsigned char vecPermT1 = (vector unsigned char)(8,9,10,11,8,9,10,11,8,9,10,11,8,9,10,11); - vector float zeroVector = (vector float)(0); - - vector float vecNegOne = (vector float)(-1.0); - - vector float vecStore1, vecStore2, vecStore3; - vector unsigned char vecPermFirstThreeLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vecPermStoreSecond = (vector unsigned char)(4,5,6,7,8,9,10,11,16,17,18,19,20,21,22,23); - vector unsigned char vecPermLeadAndThree = (vector unsigned char)(0,1,2,3,16,17,18,19,20,21,22,23,24,25,26,27); - vector unsigned char vecPermStore2 = (vector unsigned char)(4,5,6,7,8,9,10,11,24,25,26,27,28,29,30,31); - vector unsigned char vecPermStore3 = (vector unsigned char)(4,5,6,7,8,9,10,11,16,17,18,19,20,21,22,23); - vector unsigned char vecPermStore4 = (vector unsigned char)(8,9,10,11,16,17,18,19,20,21,22,23,24,25,26,27); - vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - - vector float vecLd1, vecLd2, vecLd3; - vector unsigned char vecPerm0, vecPerm1, vecPerm2, vecPerm3, vecPerm4; - - float *normalPtr = verts[0].normal.ToFloatPtr(); - float *xyzPtr = verts[0].xyz.ToFloatPtr(); - - vector float vecFirstHalf, vecSecondHalf; - vector float vecFirstHalf2, vecSecondHalf2; - vector float vecFirstHalf3, vecSecondHalf3; - vector float vecFirstHalf4, vecSecondHalf4; - - for ( i = 0; i+3 < numVerts; i+=4 ) { - int bOffset1, bOffset2, bOffset3, bOffset4; - int cOffset1, cOffset2, cOffset3, cOffset4; - - bOffset1 = dominantTris[i].v2; - cOffset1 = dominantTris[i].v3; - bOffset2 = dominantTris[i+1].v2; - cOffset2 = dominantTris[i+1].v3; - bOffset3 = dominantTris[i+2].v2; - cOffset3 = dominantTris[i+2].v3; - bOffset4 = dominantTris[i+3].v2; - cOffset4 = dominantTris[i+3].v3; - - vecPerm0 = vec_lvsl( 0, xyzPtr + ( i * DRAWVERT_OFFSET ) ); - v0 = vec_ld( 0, xyzPtr + (i * DRAWVERT_OFFSET ) ); - v1 = vec_ld( 16, xyzPtr + (i * DRAWVERT_OFFSET ) ); - vecVertA = vec_perm( v0, v1, vecPerm0 ); - - vecPerm1 = vec_lvsl( 0, xyzPtr + (bOffset1 * DRAWVERT_OFFSET ) ); - v2 = vec_ld( 0, xyzPtr + ( bOffset1 * DRAWVERT_OFFSET ) ); - v3 = vec_ld( 16, xyzPtr + ( bOffset1 * DRAWVERT_OFFSET ) ); - vecVertB = vec_perm( v2, v3, vecPerm1 ); - - vecPerm2 = vec_lvsl( 0, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); - v4 = vec_ld( 0, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); - v5 = vec_ld( 16, xyzPtr + ( cOffset1 * DRAWVERT_OFFSET ) ); - vecVertC = vec_perm( v4, v5, vecPerm2 ); - - // put remainder into v2 - v1 = vec_perm( v1, v1, vecPerm0 ); - v3 = vec_perm( v3, v3, vecPerm1 ); - v5 = vec_perm( v5, v5, vecPerm2 ); - - v1 = vec_mergeh( v1, v5 ); - v2 = vec_mergeh( v3, zeroVector ); - v2 = vec_mergeh( v1, v2 ); - v2 = vec_perm( v2, v2, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); - - // load second one - vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); - v0 = vec_ld( 0, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); - v1 = vec_ld( 16, xyzPtr + ((i+1) * DRAWVERT_OFFSET ) ); - vecVertA2 = vec_perm( v0, v1, vecPerm0 ); - - vecPerm3 = vec_lvsl( 0, xyzPtr + (bOffset2 * DRAWVERT_OFFSET ) ); - v3 = vec_ld( 0, xyzPtr + ( bOffset2 * DRAWVERT_OFFSET ) ); - v4 = vec_ld( 16, xyzPtr + ( bOffset2 * DRAWVERT_OFFSET ) ); - vecVertB2 = vec_perm( v3, v4, vecPerm3 ); - - vecPerm4 = vec_lvsl( 0, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); - v5 = vec_ld( 0, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); - v6 = vec_ld( 16, xyzPtr + ( cOffset2 * DRAWVERT_OFFSET ) ); - vecVertC2 = vec_perm( v5, v6, vecPerm4 ); - - // put remainder into v3 - v1 = vec_perm( v1, v1, vecPerm0 ); - v4 = vec_perm( v4, v4, vecPerm3 ); - v5 = vec_perm( v6, v6, vecPerm4 ); - - v1 = vec_mergeh( v1, v5 ); - v3 = vec_mergeh( v4, zeroVector ); - v3 = vec_mergeh( v1, v3 ); - v3 = vec_perm( v3, v3, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); - - // load third one - vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); - v0 = vec_ld( 0, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); - v1 = vec_ld( 16, xyzPtr + ((i+2) * DRAWVERT_OFFSET ) ); - vecVertA3 = vec_perm( v0, v1, vecPerm0 ); - - vecPerm1 = vec_lvsl( 0, xyzPtr + (bOffset3 * DRAWVERT_OFFSET ) ); - v4 = vec_ld( 0, xyzPtr + ( bOffset3 * DRAWVERT_OFFSET ) ); - v5 = vec_ld( 16, xyzPtr + ( bOffset3 * DRAWVERT_OFFSET ) ); - vecVertB3 = vec_perm( v4, v5, vecPerm1 ); - - vecPerm2 = vec_lvsl( 0, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); - v6 = vec_ld( 0, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); - v7 = vec_ld( 16, xyzPtr + ( cOffset3 * DRAWVERT_OFFSET ) ); - vecVertC3 = vec_perm( v6, v7, vecPerm2 ); - - // put remainder into v4 - v1 = vec_perm( v1, v1, vecPerm0 ); - v5 = vec_perm( v5, v5, vecPerm1 ); - v7 = vec_perm( v7, v7, vecPerm2 ); - - v1 = vec_mergeh( v1, v7 ); - v4 = vec_mergeh( v5, zeroVector ); - v4 = vec_mergeh( v1, v4 ); - v4 = vec_perm( v4, v4, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); - - // load fourth one - vecPerm0 = vec_lvsl( 0, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); - v0 = vec_ld( 0, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); - v1 = vec_ld( 16, xyzPtr + ((i+3) * DRAWVERT_OFFSET ) ); - vecVertA4 = vec_perm( v0, v1, vecPerm0 ); - - vecPerm3 = vec_lvsl( 0, xyzPtr + (bOffset4 * DRAWVERT_OFFSET ) ); - v5 = vec_ld( 0, xyzPtr + ( bOffset4 * DRAWVERT_OFFSET ) ); - v6 = vec_ld( 16, xyzPtr + ( bOffset4 * DRAWVERT_OFFSET ) ); - vecVertB4 = vec_perm( v5, v6, vecPerm3 ); - - vecPerm4 = vec_lvsl( 0, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); - v7 = vec_ld( 0, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); - v8 = vec_ld( 16, xyzPtr + ( cOffset4 * DRAWVERT_OFFSET ) ); - vecVertC4 = vec_perm( v7, v8, vecPerm4 ); - - // put remainder into v5 - v1 = vec_perm( v1, v1, vecPerm0 ); - v6 = vec_perm( v6, v6, vecPerm3 ); - v8 = vec_perm( v8, v8, vecPerm4 ); - - v1 = vec_mergeh( v1, v8 ); - v5 = vec_mergeh( v6, zeroVector ); - v5 = vec_mergeh( v1, v5 ); - v5 = vec_perm( v5, v5, (vector unsigned char)(4,5,6,7,0,1,2,3,8,9,10,11,0,1,2,3) ); - - // remainder vectors look like b->st[1], a->st[1], c->st[1], a->st[1] - - //vecD1 now holds d0, d1, d2, d3 - vecD1 = vec_sub( vecVertB, vecVertA ); - vecD4 = vec_sub( vecVertB2, vecVertA2 ); - vecD7 = vec_sub( vecVertB3, vecVertA3 ); - vecD10 = vec_sub( vecVertB4, vecVertA4 ); - - // vecD2 how holds d5, d6, d7, d8 - vecD2 = vec_sub( vecVertC, vecVertA ); - vecD5 = vec_sub( vecVertC2, vecVertA2 ); - vecD8 = vec_sub( vecVertC3, vecVertA3 ); - vecD11 = vec_sub( vecVertC4, vecVertA4 ); - - // vecD3 now holds d4, crap, d9, crap - vecD3 = vec_sub( v2, vec_sld( v2, v2, 4 ) ); - vecD6 = vec_sub( v3, vec_sld( v3, v3, 4 ) ); - vecD9 = vec_sub( v4, vec_sld( v4, v4, 4 ) ); - vecD12 = vec_sub( v5, vec_sld( v5, v5, 4 ) ); - - // get permute vectors for loading from dt - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i].normalizationScale[0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+1].normalizationScale[0] ), (vector unsigned char)(1) ); - vecPerm3 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+2].normalizationScale[0] ), (vector unsigned char)(1) ); - vecPerm4 = vec_add( vec_lvsl( -1, (int*) &dominantTris[i+3].normalizationScale[0] ), (vector unsigned char)(1) ); - - // load S values from dominantTris - v0 = vec_ld( 0, &dominantTris[i].normalizationScale[0] ); - v1 = vec_ld( 11, &dominantTris[i].normalizationScale[0] ); - v2 = vec_ld( 0, &dominantTris[i+1].normalizationScale[0] ); - v3 = vec_ld( 11, &dominantTris[i+1].normalizationScale[0] ); - v4 = vec_ld( 0, &dominantTris[i+2].normalizationScale[0] ); - v5 = vec_ld( 11, &dominantTris[i+2].normalizationScale[0] ); - v6 = vec_ld( 0, &dominantTris[i+3].normalizationScale[0] ); - v7 = vec_ld( 11, &dominantTris[i+3].normalizationScale[0] ); - - v0 = vec_perm( v0, v1, vecPerm1 ); - v2 = vec_perm( v2, v3, vecPerm2 ); - v4 = vec_perm( v4, v5, vecPerm3 ); - v6 = vec_perm( v6, v7, vecPerm4 ); - - vecS0 = vec_splat( v0, 0 ); - vecS1 = vec_splat( v0, 1 ); - vecS2 = vec_splat( v0, 2 ); - - vecS0_2 = vec_splat( v2, 0); - vecS1_2 = vec_splat( v2, 1 ); - vecS2_2 = vec_splat( v2, 2 ); - - vecS0_3 = vec_splat( v4, 0 ); - vecS1_3 = vec_splat( v4, 1 ); - vecS2_3 = vec_splat( v4, 2 ); - - vecS0_4 = vec_splat( v6, 0 ); - vecS1_4 = vec_splat( v6, 1 ); - vecS2_4 = vec_splat( v6, 2 ); - - // do calculation - vecWork1 = vec_perm( vecD2, vecD2, vecPermN1 ); - vecWork2 = vec_perm( vecD1, vecD1, vecPermN0 ); - vecWork3 = vec_perm( vecD5, vecD5, vecPermN1 ); - vecWork4 = vec_perm( vecD4, vecD4, vecPermN0 ); - vecWork5 = vec_perm( vecD8, vecD8, vecPermN1 ); - vecWork6 = vec_perm( vecD7, vecD7, vecPermN0 ); - vecWork7 = vec_perm( vecD11, vecD11, vecPermN1 ); - vecWork8 = vec_perm( vecD10, vecD10, vecPermN0 ); - - vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecWork1 = vec_perm( vecD2, vecD2, vecPermN0 ); - vecWork2 = vec_perm( vecD1, vecD1, vecPermN1 ); - vecWork3 = vec_perm( vecD5, vecD5, vecPermN0 ); - vecWork4 = vec_perm( vecD4, vecD4, vecPermN1 ); - vecWork5 = vec_perm( vecD8, vecD8, vecPermN0 ); - vecWork6 = vec_perm( vecD7, vecD7, vecPermN1 ); - vecWork7 = vec_perm( vecD11, vecD11, vecPermN0 ); - vecWork8 = vec_perm( vecD10, vecD10, vecPermN1 ); - - vecSecondHalf = vec_nmsub( vecWork1, vecWork2, vecFirstHalf ); - vecSecondHalf2 = vec_nmsub( vecWork3, vecWork4, vecFirstHalf2 ); - vecSecondHalf3 = vec_nmsub( vecWork5, vecWork6, vecFirstHalf3 ); - vecSecondHalf4 = vec_nmsub( vecWork7, vecWork8, vecFirstHalf4 ); - - - // calculate N values - vecN = vec_madd( vecS2, vecSecondHalf, zeroVector ); - vecN2 = vec_madd( vecS2_2, vecSecondHalf2, zeroVector ); - vecN3 = vec_madd( vecS2_3, vecSecondHalf3, zeroVector ); - vecN4 = vec_madd( vecS2_4, vecSecondHalf4, zeroVector ); - - // calculate both halves of the calculation for t - vecWork1 = vecD1; - vecWork2 = vec_perm( vecD3, vecD3, vecPermT1 ); - vecWork3 = vecD4; - vecWork4 = vec_perm( vecD6, vecD6, vecPermT1 ); - vecWork5 = vecD7; - vecWork6 = vec_perm( vecD9, vecD9, vecPermT1 ); - vecWork7 = vecD10; - vecWork8 = vec_perm( vecD12, vecD12, vecPermT1 ); - - vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecWork1 = vecD2; - vecWork2 = vec_perm( vecD3, vecD3, vecPermT0 ); - vecWork3 = vecD5; - vecWork4 = vec_perm( vecD6, vecD6, vecPermT0 ); - vecWork5 = vecD8; - vecWork6 = vec_perm( vecD9, vecD9, vecPermT0 ); - vecWork7 = vecD11; - vecWork8 = vec_perm( vecD12, vecD12, vecPermT0 ); - - vecSecondHalf = vec_nmsub( vecWork1, vecWork2, vecFirstHalf ); - vecSecondHalf2 = vec_nmsub( vecWork3, vecWork4, vecFirstHalf2 ); - vecSecondHalf3 = vec_nmsub( vecWork5, vecWork6, vecFirstHalf3 ); - vecSecondHalf4 = vec_nmsub( vecWork7, vecWork8, vecFirstHalf4 ); - - // calculate T values - vecT1 = vec_madd( vecS0, vecSecondHalf, zeroVector ); - vecT1_2 = vec_madd( vecS0_2, vecSecondHalf2, zeroVector ); - vecT1_3 = vec_madd( vecS0_3, vecSecondHalf3, zeroVector ); - vecT1_4 = vec_madd( vecS0_4, vecSecondHalf4, zeroVector ); - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - vecWork1 = vecD1; - vecWork2 = vec_perm( vecD2, vecD2, vecPermT2 ); - vecWork3 = vecD4; - vecWork4 = vec_perm( vecD5, vecD5, vecPermT2 ); - vecWork5 = vecD7; - vecWork6 = vec_perm( vecD8, vecD8, vecPermT2 ); - vecWork7 = vecD10; - vecWork8 = vec_perm( vecD11, vecD11, vecPermT2 ); - - vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecWork1 = vec_perm( vecD1, vecD1, vecPermT2 ); - vecWork2 = vecD2; - vecWork3 = vec_perm( vecD4, vecD4, vecPermT2 ); - vecWork4 = vecD5; - vecWork5 = vec_perm( vecD7, vecD7, vecPermT2 ); - vecWork6 = vecD8; - vecWork7 = vec_perm( vecD10, vecD10, vecPermT2 ); - vecWork8 = vecD11; - - vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - -#else - vecWork1 = vec_perm( vecN, vecN, vecPermN1 ); - vecWork2 = vec_perm( vecT1, vecT1, vecPermN0 ); - vecWork3 = vec_perm( vecN2, vecN2, vecPermN1 ); - vecWork4 = vec_perm( vecT1_2, vecT1_2, vecPermN0 ); - vecWork5 = vec_perm( vecN3, vecN3, vecPermN1 ); - vecWork6 = vec_perm( vecT1_3, vecT1_3, vecPermN0 ); - vecWork7 = vec_perm( vecN4, vecN4, vecPermN1 ); - vecWork8 = vec_perm( vecT1_4, vecT1_4, vecPermN0 ); - - vecSecondHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecSecondHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecSecondHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecSecondHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); - - vecWork1 = vec_perm( vecN, vecN, vecPermN0 ); - vecWork2 = vec_perm( vecT1, vecT1, vecPermN1 ); - vecWork3 = vec_perm( vecN2, vecN2, vecPermN0 ); - vecWork4 = vec_perm( vecT1_2, vecT1_2, vecPermN1 ); - vecWork5 = vec_perm( vecN3, vecN3, vecPermN0 ); - vecWork6 = vec_perm( vecT1_3, vecT1_3, vecPermN1 ); - vecWork7 = vec_perm( vecN4, vecN4, vecPermN0 ); - vecWork8 = vec_perm( vecT1_4, vecT1_4, vecPermN1 ); - - vecFirstHalf = vec_madd( vecWork1, vecWork2, zeroVector ); - vecFirstHalf2 = vec_madd( vecWork3, vecWork4, zeroVector ); - vecFirstHalf3 = vec_madd( vecWork5, vecWork6, zeroVector ); - vecFirstHalf4 = vec_madd( vecWork7, vecWork8, zeroVector ); -#endif - // finish the calculation - vecSecondHalf = vec_madd( vecSecondHalf, vecNegOne, vecFirstHalf ); - vecSecondHalf2 = vec_madd( vecSecondHalf2, vecNegOne, vecFirstHalf2 ); - vecSecondHalf3 = vec_madd( vecSecondHalf3, vecNegOne, vecFirstHalf3 ); - vecSecondHalf4 = vec_madd( vecSecondHalf4, vecNegOne, vecFirstHalf4 ); - - vecT2 = vec_madd( vecS1, vecSecondHalf, zeroVector ); - vecT2_2 = vec_madd( vecS1_2, vecSecondHalf2, zeroVector ); - vecT2_3 = vec_madd( vecS1_3, vecSecondHalf3, zeroVector ); - vecT2_4 = vec_madd( vecS1_4, vecSecondHalf4, zeroVector ); - - // Store results - - // read values that we need to preserve - vecLd1 = vec_ld( 0, normalPtr + ( i * DRAWVERT_OFFSET ) ); - vecLd2 = vec_ld( 32, normalPtr + ( i * DRAWVERT_OFFSET ) ); - - //generate vectors to store - vecStore1 = vec_perm( vecLd1, vecN, vecPermLeadAndThree ); - vecStore2 = vec_perm( vecT1, vecT2, vecPermFirstThreeLast ); - vecStore3 = vec_perm( vecT2, vecLd2, vecPermStore2 ); - - // store out results - ALIGNED_STORE3( normalPtr + ( i * DRAWVERT_OFFSET ), vecStore1, vecStore2, vecStore3 ); - - // read values that we need to preserve - vecLd3 = vec_ld( 32, normalPtr + ( (i+1) * DRAWVERT_OFFSET )); - - // generate vectors to store - vecStore1 = vec_perm( vecN2, vecT1_2, vecPermFirstThreeLast ); - vecStore2 = vec_perm( vecT1_2, vecT2_2, vecPermStoreSecond ); - vecStore3 = vec_perm( vecT2_2, vecLd3, (vector unsigned char)(8,9,10,11,20,21,22,23,24,25,26,27,28,29,30,31) ); - - // instead of doing permute, shift it where it needs to be and use vec_ste - // store out vectors - ALIGNED_STORE3( normalPtr + ((i+1) * DRAWVERT_OFFSET), vecStore1, vecStore2, vecStore3 ); - - // read values that we need to preserve - vecLd1 = vec_ld( 0, normalPtr + ( (i+2) * DRAWVERT_OFFSET ) ); - - // generate vectors to store - vecStore1 = vec_perm( vecLd1, vecN3, vecPermFirstThreeLast ); - vecStore2 = vec_perm( vecN3, vecT1_3, vecPermStore3 ); - vecStore3 = vec_perm( vecT1_3, vecT2_3, vecPermStore4 ); - - // store out vectors - ALIGNED_STORE3( normalPtr + ((i+2) * DRAWVERT_OFFSET), vecStore1, vecStore2, vecStore3 ); - - // read values that we need to preserve - vecLd2 = vec_ld( 0, normalPtr + ((i+3) * DRAWVERT_OFFSET ) ); - vecLd3 = vec_ld( 32, normalPtr + ((i+3) * DRAWVERT_OFFSET ) ); - - // generate vectors to store - vecStore1 = vec_perm( vecLd2, vecN4, vecPermHalves ); - vecStore2 = vec_perm( vecN4, vecT1_4, vecPermStore4 ); - vecStore3 = vec_perm( vecT2_4, vecLd3, vecPermFirstThreeLast ); - - // store out vectors - ALIGNED_STORE3( normalPtr + ((i+3) * DRAWVERT_OFFSET ), vecStore1, vecStore2, vecStore3 ); - } - - // cleanup - for ( ; i < numVerts; i++ ) { - idDrawVert *a, *b, *c; - float d0, d1, d2, d3, d4; - float d5, d6, d7, d8, d9; - float s0, s1, s2; - float n0, n1, n2; - float t0, t1, t2; - float t3, t4, t5; - - const dominantTri_s &dt = dominantTris[i]; - - a = verts + i; - b = verts + dt.v2; - c = verts + dt.v3; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - d3 = b->st[0] - a->st[0]; - - d4 = b->st[1] - a->st[1]; - - d5 = c->xyz[0] - a->xyz[0]; - d6 = c->xyz[1] - a->xyz[1]; - d7 = c->xyz[2] - a->xyz[2]; - d8 = c->st[0] - a->st[0]; - - d9 = c->st[1] - a->st[1]; - - s0 = dt.normalizationScale[0]; - s1 = dt.normalizationScale[1]; - s2 = dt.normalizationScale[2]; - - n0 = s2 * ( d6 * d2 - d7 * d1 ); - n1 = s2 * ( d7 * d0 - d5 * d2 ); - n2 = s2 * ( d5 * d1 - d6 * d0 ); - - t0 = s0 * ( d0 * d9 - d4 * d5 ); - t1 = s0 * ( d1 * d9 - d4 * d6 ); - t2 = s0 * ( d2 * d9 - d4 * d7 ); - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - t3 = s1 * ( d3 * d5 - d0 * d8 ); - t4 = s1 * ( d3 * d6 - d1 * d8 ); - t5 = s1 * ( d3 * d7 - d2 * d8 ); -#else - t3 = s1 * ( n2 * t1 - n1 * t2 ); - t4 = s1 * ( n0 * t2 - n2 * t0 ); - t5 = s1 * ( n1 * t0 - n0 * t1 ); -#endif - - a->normal[0] = n0; - a->normal[1] = n1; - a->normal[2] = n2; - - a->tangents[0][0] = t0; - a->tangents[0][1] = t1; - a->tangents[0][2] = t2; - - a->tangents[1][0] = t3; - a->tangents[1][1] = t4; - a->tangents[1][2] = t5; - } -} - -#else -/* -============ -idSIMD_AltiVec::DeriveUnsmoothedTangents - - Derives the normal and orthogonal tangent vectors for the triangle vertices. - For each vertex the normal and tangent vectors are derived from a single dominant triangle. -============ -*/ -#define DERIVE_UNSMOOTHED_BITANGENT - -void VPCALL idSIMD_AltiVec::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { - int i; - - for ( i = 0; i < numVerts; i++ ) { - idDrawVert *a, *b, *c; - float d0, d1, d2, d3, d4; - float d5, d6, d7, d8, d9; - float s0, s1, s2; - float n0, n1, n2; - float t0, t1, t2; - float t3, t4, t5; - - const dominantTri_s &dt = dominantTris[i]; - - a = verts + i; - b = verts + dt.v2; - c = verts + dt.v3; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - d3 = b->st[0] - a->st[0]; - - d4 = b->st[1] - a->st[1]; - - d5 = c->xyz[0] - a->xyz[0]; - d6 = c->xyz[1] - a->xyz[1]; - d7 = c->xyz[2] - a->xyz[2]; - d8 = c->st[0] - a->st[0]; - - d9 = c->st[1] - a->st[1]; - - s0 = dt.normalizationScale[0]; - s1 = dt.normalizationScale[1]; - s2 = dt.normalizationScale[2]; - - n0 = s2 * ( d6 * d2 - d7 * d1 ); - n1 = s2 * ( d7 * d0 - d5 * d2 ); - n2 = s2 * ( d5 * d1 - d6 * d0 ); - - t0 = s0 * ( d0 * d9 - d4 * d5 ); - t1 = s0 * ( d1 * d9 - d4 * d6 ); - t2 = s0 * ( d2 * d9 - d4 * d7 ); - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - t3 = s1 * ( d3 * d5 - d0 * d8 ); - t4 = s1 * ( d3 * d6 - d1 * d8 ); - t5 = s1 * ( d3 * d7 - d2 * d8 ); -#else - t3 = s1 * ( n2 * t1 - n1 * t2 ); - t4 = s1 * ( n0 * t2 - n2 * t0 ); - t5 = s1 * ( n1 * t0 - n0 * t1 ); -#endif - - a->normal[0] = n0; - a->normal[1] = n1; - a->normal[2] = n2; - - a->tangents[0][0] = t0; - a->tangents[0][1] = t1; - a->tangents[0][2] = t2; - - a->tangents[1][0] = t3; - a->tangents[1][1] = t4; - a->tangents[1][2] = t5; - } - -} -#endif /* DERIVE_UNSMOOTH_DRAWVERT_ALIGNED */ - -/* -============ -idSIMD_AltiVec::NormalizeTangents - - Normalizes each vertex normal and projects and normalizes the - tangent vectors onto the plane orthogonal to the vertex normal. -============ -*/ -void VPCALL idSIMD_AltiVec::NormalizeTangents( idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - - float *addr = verts[0].normal.ToFloatPtr(); - float *tAddr = verts[0].tangents[0].ToFloatPtr(); - - // v0 through v3 maintain originally loaded values so we don't take - // as much hit for unaligned stores - vector float v0, v1, v2, v3; - // v5 through v8 are the "working" values of the vectors - vector float v5, v6, v7, v8; - // working values - vector float vec1T0, vec1T1, vec2T0, vec2T1, vec3T0, vec3T1, vec4T0, vec4T1; - vector float vecSum, vecTSum1, vecTSum2, tempSum, tempSum2, tempSum3; - vector float vecF, vecF2; - vector float vecTemp, vecTemp2, vecTemp3, vecTemp4; - - register vector float zeroVector = (vector float)(0.0); - - vector unsigned char vecPermHalves = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23); - vector unsigned char vecPermLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vecPermSplatFirstWithZero = (vector unsigned char)(0,1,2,3,0,1,2,3,0,1,2,3,16,17,18,19); - vector unsigned char vecPerm0, vecPerm1, vecPerm2, vecPerm3; - vector unsigned char storePerm0, storePerm1, storePerm2, storePerm3; - - vector float vecTan11, vecTan12, vecTan13, vecTan21, vecTan22, vecTan23; - vector float vecTan31, vecTan32, vecTan33, vecTan41, vecTan42, vecTan43; - - vector unsigned char vec1T0Perm, vec1T1Perm, vec2T0Perm, vec2T1Perm, vec3T0Perm, vec3T1Perm, vec4T0Perm, vec4T1Perm; - vector unsigned char storeT11, storeT12, storeT21, storeT22, storeT31, storeT32; - vector unsigned char storeT41, storeT42; - - int i = 0; - - if ( i+3 < numVerts ) { - // for loading normal from idDrawVert - vecPerm0 = vec_add( vec_lvsl( -1, addr ), (vector unsigned char)(1) ); - vecPerm1 = vec_add( vec_lvsl( -1, addr + ( 1 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, addr + ( 2 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vecPerm3 = vec_add( vec_lvsl( -1, addr + ( 3 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - - // for loading tangents from idDrawVert - vec1T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 0 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vec1T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 0 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); - vec2T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 1 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vec2T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 1 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); - vec3T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 2 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vec3T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 2 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); - vec4T0Perm = vec_add( vec_lvsl( -1, tAddr + ( 3 * DRAWVERT_OFFSET ) ), (vector unsigned char)(1) ); - vec4T1Perm = vec_add( vec_lvsl( -1, tAddr + ( 3 * DRAWVERT_OFFSET ) + 3 ), (vector unsigned char)(1) ); - - // generate permute vectors to store normals - storePerm0 = vec_lvsr( 0, addr ); - storePerm1 = vec_lvsr( 0, addr + ( 1 * DRAWVERT_OFFSET ) ); - storePerm2 = vec_lvsr( 0, addr + ( 2 * DRAWVERT_OFFSET ) ); - storePerm3 = vec_lvsr( 0, addr + ( 3 * DRAWVERT_OFFSET ) ); - - // generate permute vectors to store tangents - storeT11 = vec_lvsr( 0, tAddr + ( 0 * DRAWVERT_OFFSET ) ); - storeT12 = vec_lvsr( 12, tAddr + ( 0 * DRAWVERT_OFFSET ) ); - - storeT21 = vec_lvsr( 0, tAddr + ( 1 * DRAWVERT_OFFSET ) ); - storeT22 = vec_lvsr( 12, tAddr + ( 1 * DRAWVERT_OFFSET ) ); - - storeT31 = vec_lvsr( 0, tAddr + ( 2 * DRAWVERT_OFFSET ) ); - storeT32 = vec_lvsr( 12, tAddr + ( 2 * DRAWVERT_OFFSET ) ); - - storeT41 = vec_lvsr( 0, tAddr + ( 3 * DRAWVERT_OFFSET ) ); - storeT42 = vec_lvsr( 12, tAddr + ( 3 * DRAWVERT_OFFSET ) ); - } - - for ( ; i+3 < numVerts; i+=4 ) { - - // load normals - vector float vecNormal11 = vec_ld( 0, addr + ( i * DRAWVERT_OFFSET ) ); - vector float vecNormal12 = vec_ld( 15, addr + ( i * DRAWVERT_OFFSET ) ); - v0 = vec_perm( vecNormal11, vecNormal12, vecPerm0 ); - - vector float vecNormal21 = vec_ld( 0, addr + ((i+1) * DRAWVERT_OFFSET ) ); - vector float vecNormal22 = vec_ld( 15, addr + ((i+1) * DRAWVERT_OFFSET ) ); - v1 = vec_perm( vecNormal21, vecNormal22, vecPerm1 ); - - vector float vecNormal31 = vec_ld( 0, addr + ( (i+2) * DRAWVERT_OFFSET ) ); - vector float vecNormal32 = vec_ld( 15, addr + ( (i+2) * DRAWVERT_OFFSET ) ); - v2 = vec_perm( vecNormal31, vecNormal32, vecPerm2 ); - - vector float vecNormal41 = vec_ld( 0, addr + ((i+3) * DRAWVERT_OFFSET ) ); - vector float vecNormal42 = vec_ld( 15, addr + ((i+3) * DRAWVERT_OFFSET ) ); - v3 = vec_perm( vecNormal41, vecNormal42, vecPerm3 ); - - // zero out the last element of each useless vector - v0 = vec_perm( v0, zeroVector, vecPermLast ); - v1 = vec_perm( v1, zeroVector, vecPermLast ); - v2 = vec_perm( v2, zeroVector, vecPermLast ); - v3 = vec_perm( v3, zeroVector, vecPermLast ); - - // got 4 vectors in v0 through v3, sum them each accross - // and put into one vector - vecTemp = vec_madd( v0, v0, zeroVector ); - - vecSum = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - vecSum = vec_add( vecSum, vec_sld( vecSum, vecSum, 4 ) ); - // element 0 of vecSum now has sum of v0 - - vecTemp2 = vec_madd( v1, v1, zeroVector ); - tempSum = vec_add( vecTemp2, vec_sld( vecTemp2, vecTemp2, 8 ) ); - tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); - // put this into vecSum - vecSum = vec_mergeh( vecSum, tempSum ); - - vecTemp3 = vec_madd( v2, v2, zeroVector ); - tempSum = vec_add( vecTemp3, vec_sld( vecTemp3, vecTemp3, 8 ) ); - tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); - // put this into vecSum - vecSum = vec_perm( vecSum, tempSum, vecPermHalves ); - - vecTemp4 = vec_madd( v3, v3, zeroVector ); - tempSum = vec_add( vecTemp4, vec_sld( vecTemp4, vecTemp4, 8 ) ); - tempSum = vec_add( tempSum, vec_sld( tempSum, tempSum, 4 ) ); - // put this into vecSum - vecSum = vec_perm( vecSum, tempSum, vecPermLast ); - - // take reciprocal square roots of these - vecF = ReciprocalSquareRoot( vecSum ); - - // multiply each vector by f - v5 = vec_madd( v0, vec_splat( vecF, 0 ), zeroVector ); - v6 = vec_madd( v1, vec_splat( vecF, 1 ), zeroVector ); - v7 = vec_madd( v2, vec_splat( vecF, 2 ), zeroVector ); - v8 = vec_madd( v3, vec_splat( vecF, 3 ), zeroVector ); - - // load tangents as unaligned - vecTan11 = vec_ld( 0, tAddr + ( i * DRAWVERT_OFFSET ) ); - vecTan12 = vec_ld( 11, tAddr + ( i * DRAWVERT_OFFSET ) ); - vecTan13 = vec_ld( 23, tAddr + ( i * DRAWVERT_OFFSET ) ); - - vecTan21 = vec_ld( 0, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); - vecTan22 = vec_ld( 11, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); - vecTan23 = vec_ld( 23, tAddr + ( (i+1) * DRAWVERT_OFFSET ) ); - - vecTan31 = vec_ld( 0, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); - vecTan32 = vec_ld( 11, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); - vecTan33 = vec_ld( 23, tAddr + ( (i+2) * DRAWVERT_OFFSET ) ); - - vecTan41 = vec_ld( 0, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); - vecTan42 = vec_ld( 11, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); - vecTan43 = vec_ld( 23, tAddr + ( (i+3) * DRAWVERT_OFFSET ) ); - - vec1T0 = vec_perm( vecTan11, vecTan12, vec1T0Perm ); - vec1T1 = vec_perm( vecTan12, vecTan13, vec1T1Perm ); - vec2T0 = vec_perm( vecTan21, vecTan22, vec2T0Perm ); - vec2T1 = vec_perm( vecTan22, vecTan23, vec2T1Perm ); - vec3T0 = vec_perm( vecTan31, vecTan32, vec3T0Perm ); - vec3T1 = vec_perm( vecTan32, vecTan33, vec3T1Perm ); - vec4T0 = vec_perm( vecTan41, vecTan42, vec4T0Perm ); - vec4T1 = vec_perm( vecTan42, vecTan43, vec4T1Perm ); - - //zero out last element of tangents - vec1T0 = vec_perm( vec1T0, zeroVector, vecPermLast ); - vec1T1 = vec_perm( vec1T1, zeroVector, vecPermLast ); - vec2T0 = vec_perm( vec2T0, zeroVector, vecPermLast ); - vec2T1 = vec_perm( vec2T1, zeroVector, vecPermLast ); - vec3T0 = vec_perm( vec3T0, zeroVector, vecPermLast ); - vec3T1 = vec_perm( vec3T1, zeroVector, vecPermLast ); - vec4T0 = vec_perm( vec4T0, zeroVector, vecPermLast ); - vec4T1 = vec_perm( vec4T1, zeroVector, vecPermLast ); - - // all tangents[0] - tempSum = zeroVector; - tempSum = vec_madd( vec1T0, v5, tempSum ); - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - // put tempSum splatted accross vecTSum1 - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v5, zeroVector ); - - //vec1T0 now contains what needs to be rsqrt'd and multiplied by f - vec1T0 = vec_sub( vec1T0, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec2T0, v6, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v6, zeroVector ); - vec2T0 = vec_sub( vec2T0, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec3T0, v7, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v7, zeroVector ); - vec3T0 = vec_sub( vec3T0, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec4T0, v8, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v8, zeroVector ); - vec4T0 = vec_sub( vec4T0, vecTSum1 ); - - // all tangents[1] - tempSum = zeroVector; - tempSum = vec_madd( vec1T1, v5, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v5, zeroVector ); - - //vec1T0 now contains what needs to be rsqrt'd and multiplied by f - vec1T1 = vec_sub( vec1T1, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec2T1, v6, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v6, zeroVector ); - vec2T1 = vec_sub( vec2T1, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec3T1, v7, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v7, zeroVector ); - vec3T1 = vec_sub( vec3T1, vecTSum1 ); - - tempSum = zeroVector; - tempSum = vec_madd( vec4T1, v8, tempSum ); - - //sum accross tempSum - vecTSum1 = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - vecTSum1 = vec_perm( vecTSum1, zeroVector, vecPermSplatFirstWithZero ); - vecTSum1 = vec_madd( vecTSum1, v8, zeroVector ); - vec4T1 = vec_sub( vec4T1, vecTSum1 ); - - - // sum accross vectors and put into one vector - vecTemp = vec_madd( vec1T0, vec1T0, zeroVector ); - vecTSum1 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - vecTSum1 = vec_add( vecTSum1, vec_sld( vecTSum1, vecTSum1, 4 ) ); - - // element 0 of vecSum now has sum of v0 - vecTemp = vec_madd( vec2T0, vec2T0, zeroVector ); - tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); - // put this into vecSum - vecTemp = vec_madd( vec3T0, vec3T0, zeroVector ); - vecTSum1 = vec_mergeh( vecTSum1, tempSum2 ); - tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); - // put this into vecSum - vecTSum1 = vec_perm( vecTSum1, tempSum2, vecPermHalves ); - vecTemp = vec_madd( vec4T0, vec4T0, zeroVector ); - tempSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum2 = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 4 ) ); - // put this into vecSum - vecTSum1 = vec_perm( vecTSum1, tempSum2, vecPermLast ); - - vecTemp = vec_madd( vec1T1, vec1T1, zeroVector ); - vecTSum2 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - vecTSum2 = vec_add( vecTSum2, vec_sld( vecTSum2, vecTSum2, 4 ) ); - // element 0 of vecSum now has sum of v0 - vecTemp = vec_madd( vec2T1, vec2T1, zeroVector ); - tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); - // put this into vecSum - vecTSum2 = vec_mergeh( vecTSum2, tempSum3 ); - vecTemp = vec_madd( vec3T1, vec3T1, zeroVector ); - tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); - // put this into vecSum - vecTSum2 = vec_perm( vecTSum2, tempSum3, vecPermHalves ); - vecTemp = vec_madd( vec4T1, vec4T1, zeroVector ); - tempSum3 = vec_add( vecTemp, vec_sld( vecTemp, vecTemp, 8 ) ); - tempSum3 = vec_add( tempSum3, vec_sld( tempSum3, tempSum3, 4 ) ); - // put this into vecSum - vecTSum2 = vec_perm( vecTSum2, tempSum3, vecPermLast ); - - // tangents[0] - vecF = ReciprocalSquareRoot( vecTSum1 ); - // tangents[1] - vecF2 = ReciprocalSquareRoot( vecTSum2 ); - - // multiply each tangent vector by f - - vec1T0 = vec_madd( vec1T0, vec_splat( vecF, 0 ), zeroVector ); - vec2T0 = vec_madd( vec2T0, vec_splat( vecF, 1 ), zeroVector ); - vec3T0 = vec_madd( vec3T0, vec_splat( vecF, 2 ), zeroVector ); - vec4T0 = vec_madd( vec4T0, vec_splat( vecF, 3 ), zeroVector ); - - vec1T1 = vec_madd( vec1T1, vec_splat( vecF2, 0 ), zeroVector ); - vec2T1 = vec_madd( vec2T1, vec_splat( vecF2, 1 ), zeroVector ); - vec3T1 = vec_madd( vec3T1, vec_splat( vecF2, 2 ), zeroVector ); - vec4T1 = vec_madd( vec4T1, vec_splat( vecF2, 3 ), zeroVector ); - - // rotate input data - v5 = vec_perm( v5, v5, storePerm0 ); - v6 = vec_perm( v6, v6, storePerm1 ); - v7 = vec_perm( v7, v7, storePerm2 ); - v8 = vec_perm( v8, v8, storePerm3 ); - - vec_ste( v5, 0, addr + ( (i+0) * DRAWVERT_OFFSET ) ); - vec_ste( v5, 4, addr + ( (i+0) * DRAWVERT_OFFSET ) ); - vec_ste( v5, 8, addr + ( (i+0) * DRAWVERT_OFFSET ) ); - - vec_ste( v6, 0, addr + ( (i+1) * DRAWVERT_OFFSET ) ); - vec_ste( v6, 4, addr + ( (i+1) * DRAWVERT_OFFSET ) ); - vec_ste( v6, 8, addr + ( (i+1) * DRAWVERT_OFFSET ) ); - - vec_ste( v7, 0, addr + ( (i+2) * DRAWVERT_OFFSET ) ); - vec_ste( v7, 4, addr + ( (i+2) * DRAWVERT_OFFSET ) ); - vec_ste( v7, 8, addr + ( (i+2) * DRAWVERT_OFFSET ) ); - - vec_ste( v8, 0, addr + ( (i+3) * DRAWVERT_OFFSET ) ); - vec_ste( v8, 4, addr + ( (i+3) * DRAWVERT_OFFSET ) ); - vec_ste( v8, 8, addr + ( (i+3) * DRAWVERT_OFFSET ) ); - - // store tangents[0] and tangents[1] - vec1T0 = vec_perm( vec1T0, vec1T0, storeT11 ); - vec1T1 = vec_perm( vec1T1, vec1T1, storeT12 ); - - vec_ste( vec1T0, 0, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - vec_ste( vec1T0, 4, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - vec_ste( vec1T0, 8, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - vec_ste( vec1T1, 12, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - vec_ste( vec1T1, 16, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - vec_ste( vec1T1, 20, tAddr + ((i+0) * DRAWVERT_OFFSET ) ); - - // store second tangents[0] and tangents[1] - vec2T0 = vec_perm( vec2T0, vec2T0, storeT21 ); - vec2T1 = vec_perm( vec2T1, vec2T1, storeT22 ); - - vec_ste( vec2T0, 0, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - vec_ste( vec2T0, 4, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - vec_ste( vec2T0, 8, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - vec_ste( vec2T1, 12, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - vec_ste( vec2T1, 16, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - vec_ste( vec2T1, 20, tAddr + ((i+1) * DRAWVERT_OFFSET ) ); - - // store third tangents[0] and tangents[1] - vec3T0 = vec_perm( vec3T0, vec3T0, storeT31 ); - vec3T1 = vec_perm( vec3T1, vec3T1, storeT32 ); - - vec_ste( vec3T0, 0, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - vec_ste( vec3T0, 4, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - vec_ste( vec3T0, 8, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - vec_ste( vec3T1, 12, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - vec_ste( vec3T1, 16, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - vec_ste( vec3T1, 20, tAddr + ((i+2) * DRAWVERT_OFFSET ) ); - - // store fourth tangents[0] and tangents[1] - vec4T0 = vec_perm( vec4T0, vec4T0, storeT41 ); - vec4T1 = vec_perm( vec4T1, vec4T1, storeT42 ); - - vec_ste( vec4T0, 0, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - vec_ste( vec4T0, 4, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - vec_ste( vec4T0, 8, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - vec_ste( vec4T1, 12, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - vec_ste( vec4T1, 16, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - vec_ste( vec4T1, 20, tAddr + ((i+3) * DRAWVERT_OFFSET ) ); - } - - // cleanup - for ( ; i < numVerts; i++ ) { - idVec3 &v = verts[i].normal; - float f; - - //f = idMath::RSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); - f = FastScalarInvSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); - v.x *= f; v.y *= f; v.z *= f; - - for ( int j = 0; j < 2; j++ ) { - idVec3 &t = verts[i].tangents[j]; - - t -= ( t * v ) * v; - // f = idMath::RSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); - f = FastScalarInvSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); - t.x *= f; t.y *= f; t.z *= f; - } - } -} -#endif /* ENABLE_DERIVE */ - -#ifdef ENABLE_CREATE - -/* -============ -idSIMD_AltiVec::CreateTextureSpaceLightVectors - - Calculates light vectors in texture space for the given triangle vertices. - For each vertex the direction towards the light origin is projected onto texture space. - The light vectors are only calculated for the vertices referenced by the indexes. -============ -*/ - -void VPCALL idSIMD_AltiVec::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - int i; - for ( i = 0; i+7 < numIndexes; i+= 8 ) { - used[indexes[i]] = true; - used[indexes[i+1]] = true; - used[indexes[i+2]] = true; - used[indexes[i+3]] = true; - used[indexes[i+4]] = true; - used[indexes[i+5]] = true; - used[indexes[i+6]] = true; - used[indexes[i+7]] = true; - } - - for ( ; i < numIndexes; i++ ) { - used[indexes[i]] = true; - } - - for ( i = 0; i+1 < numVerts; i+=2 ) { - - const idDrawVert *v = &verts[i]; - const idDrawVert *v2 = &verts[i+1]; - - float x, y, z; - float x2, y2, z2; - idVec3 lightDir, lightDir2; - - lightDir[0] = lightOrigin[0] - v->xyz[0]; - lightDir[1] = lightOrigin[1] - v->xyz[1]; - lightDir[2] = lightOrigin[2] - v->xyz[2]; - - lightDir2[0] = lightOrigin[0] - v2->xyz[0]; - lightDir2[1] = lightOrigin[1] - v2->xyz[1]; - lightDir2[2] = lightOrigin[2] - v2->xyz[2]; - - x = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; - y = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; - z = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; - - x2 = lightDir2[0] * v2->tangents[0][0] + lightDir2[1] * v2->tangents[0][1] + lightDir2[2] * v2->tangents[0][2]; - y2 = lightDir2[0] * v2->tangents[1][0] + lightDir2[1] * v2->tangents[1][1] + lightDir2[2] * v2->tangents[1][2]; - z2 = lightDir2[0] * v2->normal[0] + lightDir2[1] * v2->normal[1] + lightDir2[2] * v2->normal[2]; - - if ( used[i] ) { - lightVectors[i][0] = x; - lightVectors[i][1] = y; - lightVectors[i][2] = z; - } - - if ( used[i+1] ) { - lightVectors[i+1][0] = x2; - lightVectors[i+1][1] = y2; - lightVectors[i+1][2] = z2; - } - } - - // cleanup - for ( ; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - idVec3 lightDir; - - lightDir[0] = lightOrigin[0] - v->xyz[0]; - lightDir[1] = lightOrigin[1] - v->xyz[1]; - lightDir[2] = lightOrigin[2] - v->xyz[2]; - - lightVectors[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; - lightVectors[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; - lightVectors[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; - } -} - -#if 1 -/* -============ -idSIMD_AltiVec::CreateSpecularTextureCoords - - Calculates specular texture coordinates for the given triangle vertices. - For each vertex the normalized direction towards the light origin is added to the - normalized direction towards the view origin and the result is projected onto texture space. - The texture coordinates are only calculated for the vertices referenced by the indexes. -============ -*/ -void VPCALL idSIMD_AltiVec::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - int i; - for ( i = 0; i+7 < numIndexes; i+= 8 ) { - used[indexes[i]] = true; - used[indexes[i+1]] = true; - used[indexes[i+2]] = true; - used[indexes[i+3]] = true; - used[indexes[i+4]] = true; - used[indexes[i+5]] = true; - used[indexes[i+6]] = true; - used[indexes[i+7]] = true; - } - - for ( ; i < numIndexes; i++ ) { - used[indexes[i]] = true; - } - - // load lightOrigin and viewOrigin into vectors - const float *lightOriginPtr = lightOrigin.ToFloatPtr(); - const float *viewOriginPtr = viewOrigin.ToFloatPtr(); - vector unsigned char permVec = vec_lvsl( 0, lightOriginPtr ); - vector unsigned char permVec2 = vec_lvsl( 0, viewOriginPtr ); - vector float v0 = vec_ld( 0, lightOriginPtr ); - vector float v1 = vec_ld( 15, lightOriginPtr ); - vector float v2 = vec_ld( 0, viewOriginPtr ); - vector float v3 = vec_ld( 15, viewOriginPtr ); - vector float vecLightOrigin = vec_perm( v0, v1, permVec ); - vector float vecViewOrigin = vec_perm( v2, v3, permVec2 ); - const vector float zeroVector = (vector float)(0); - int index; - - for ( index = 0; index+1 < numVerts; index+=2 ) { - const float *vertPtr = verts[index].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[index+1].xyz.ToFloatPtr(); - - permVec = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); - permVec2 = vec_add( vec_lvsl( -1, vertPtr2 ), (vector unsigned char)(1) ); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - vector float v2 = vec_ld( 31, vertPtr ); - vector float v3 = vec_ld( 47, vertPtr ); - vector float v4 = vec_ld( 63, vertPtr ); - - vector float v5 = vec_ld( 0, vertPtr2 ); - vector float v6 = vec_ld( 15, vertPtr2 ); - vector float v7 = vec_ld( 31, vertPtr2 ); - vector float v8 = vec_ld( 47, vertPtr2 ); - vector float v9 = vec_ld( 63, vertPtr2 ); - - // figure out what values go where - vector float vecXYZ = vec_perm( v0, v1, permVec ); - vector float vecNormal = vec_perm( v1, v2, permVec ); - vecNormal = vec_sld( vecNormal, vecNormal, 4 ); - const vector float vecTangent0 = vec_perm( v2, v3, permVec ); - permVec = vec_add( permVec, (vector unsigned char)(-4) ); //shift permute right 3 elements - const vector float vecTangent1 = vec_perm( v3, v4, permVec ); - - vector float vecXYZ2 = vec_perm( v5, v6, permVec2 ); - vector float vecNormal2 = vec_perm( v6, v7, permVec2 ); - vecNormal2 = vec_sld( vecNormal2, vecNormal2, 4 ); - const vector float vecTangent02 = vec_perm( v7, v8, permVec2 ); - permVec2 = vec_add( permVec2, (vector unsigned char)(-4) ); - const vector float vecTangent12 = vec_perm( v8, v9, permVec2 ); - - // calculate lightDir - vector float vecLightDir = vec_sub( vecLightOrigin, vecXYZ ); - vector float vecViewDir = vec_sub( vecViewOrigin, vecXYZ ); - - vector float vecLightDir2 = vec_sub( vecLightOrigin, vecXYZ2 ); - vector float vecViewDir2 = vec_sub( vecViewOrigin, vecXYZ2 ); - - // calculate distance - vector float vecTempLight = vec_madd( vecLightDir, vecLightDir, zeroVector ); - vector float vecTempView = vec_madd( vecViewDir, vecViewDir, zeroVector ); - - vector float vecTempLight2 = vec_madd( vecLightDir2, vecLightDir2, zeroVector ); - vector float vecTempView2 = vec_madd( vecViewDir2, vecViewDir2, zeroVector ); - - // sum accross first 3 elements of vector - vector float tempSum = vec_add( vecTempLight, vec_sld( vecTempLight, vecTempLight, 4 ) ); - vecTempLight = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vector float tempSum2 = vec_add( vecTempView, vec_sld( vecTempView, vecTempView, 4 ) ); - vecTempView = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 8 ) ); - - vector float tempSum4 = vec_add( vecTempLight2, vec_sld( vecTempLight2, vecTempLight2, 4 ) ); - vecTempLight2 = vec_add( tempSum4, vec_sld( tempSum4, tempSum4, 8 ) ); - vector float tempSum5 = vec_add( vecTempView2, vec_sld( vecTempView2, vecTempView2, 4 ) ); - vecTempView2 = vec_add( tempSum5, vec_sld( tempSum5, tempSum5, 8 ) ); - - // splat sum accross the whole vector - vecTempLight = vec_splat( vecTempLight, 0 ); - vecTempView = vec_splat( vecTempView, 0 ); - - vecTempLight2 = vec_splat( vecTempLight2, 0 ); - vecTempView2 = vec_splat( vecTempView2, 0 ); - - vecTempLight = ReciprocalSquareRoot( vecTempLight ); - vecTempView = ReciprocalSquareRoot( vecTempView ); - - vecTempLight2 = ReciprocalSquareRoot( vecTempLight2 ); - vecTempView2 = ReciprocalSquareRoot( vecTempView2 ); - - // modify light and view vectors based on ilength - vecViewDir = vec_madd( vecViewDir, vecTempView, zeroVector ); - vecLightDir = vec_madd( vecLightDir, vecTempLight, vecViewDir ); - - vecViewDir2 = vec_madd( vecViewDir2, vecTempView2, zeroVector ); - vecLightDir2 = vec_madd( vecLightDir2, vecTempLight2, vecViewDir2 ); - - // calculate what to store in each texture coord - vector float vecTC0 = vec_madd( vecLightDir, vecTangent0, zeroVector ); - vector float vecTC1 = vec_madd( vecLightDir, vecTangent1, zeroVector ); - vector float vecTC2 = vec_madd( vecLightDir, vecNormal, zeroVector ); - - vector float vecTC3 = vec_madd( vecLightDir2, vecTangent02, zeroVector ); - vector float vecTC4 = vec_madd( vecLightDir2, vecTangent12, zeroVector ); - vector float vecTC5 = vec_madd( vecLightDir2, vecNormal2, zeroVector ); - - // sum accross first 3 elements of vector - vector float tempSum3; - tempSum = vec_add( vecTC0, vec_sld( vecTC0, vecTC0, 4 ) ); - vecTC0 = vec_add( tempSum, vec_sld( vecTC0, vecTC0, 8 ) ); - tempSum2 = vec_add( vecTC1, vec_sld( vecTC1, vecTC1, 4 ) ); - vecTC1 = vec_add( tempSum2, vec_sld( vecTC1, vecTC1, 8 ) ); - tempSum3 = vec_add( vecTC2, vec_sld( vecTC2, vecTC2, 4 ) ); - vecTC2 = vec_add( tempSum3, vec_sld( vecTC2, vecTC2, 8 ) ); - - tempSum4 = vec_add( vecTC3, vec_sld( vecTC3, vecTC3, 4 ) ); - vecTC3 = vec_add( tempSum4, vec_sld( vecTC3, vecTC3, 8 ) ); - tempSum5 = vec_add( vecTC4, vec_sld( vecTC4, vecTC4, 4 ) ); - vecTC4 = vec_add( tempSum5, vec_sld( vecTC4, vecTC4, 8 ) ); - vector float tempSum6 = vec_add( vecTC5, vec_sld( vecTC5, vecTC5, 4 ) ); - vecTC5 = vec_add( tempSum6, vec_sld( vecTC5, vecTC5, 8 ) ); - - vecTC0 = vec_splat( vecTC0, 0 ); - vecTC1 = vec_splat( vecTC1, 0 ); - vecTC2 = vec_splat( vecTC2, 0 ); - - vecTC3 = vec_splat( vecTC3, 0 ); - vecTC4 = vec_splat( vecTC4, 0 ); - vecTC5 = vec_splat( vecTC5, 0 ); - - if ( used[index] ) { - // store out results - vec_ste( vecTC0, 0, &texCoords[index][0] ); - vec_ste( vecTC1, 0, &texCoords[index][1] ); - vec_ste( vecTC2, 0, &texCoords[index][2] ); - vec_ste( (vector float)(1.0), 0, &texCoords[index][3] ); - } - - if ( used[index+1] ) { - vec_ste( vecTC3, 0, &texCoords[index+1][0] ); - vec_ste( vecTC4, 0, &texCoords[index+1][1] ); - vec_ste( vecTC5, 0, &texCoords[index+1][2] ); - vec_ste( (vector float)(1.0), 0, &texCoords[index+1][3] ); - } - } - - // cleanup - for ( ; index < numVerts; index++ ) { - if ( !used[index] ) { - continue; - } - - const float *vertPtr = verts[index].xyz.ToFloatPtr(); - - permVec = vec_add( vec_lvsl( -1, vertPtr ), (vector unsigned char)(1) ); - - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - vector float v2 = vec_ld( 31, vertPtr ); - vector float v3 = vec_ld( 47, vertPtr ); - vector float v4 = vec_ld( 63, vertPtr ); - - // figure out what values go where - vector float vecXYZ = vec_perm( v0, v1, permVec ); - vector float vecNormal = vec_perm( v1, v2, permVec ); - vecNormal = vec_sld( vecNormal, vecNormal, 4 ); - const vector float vecTangent0 = vec_perm( v2, v3, permVec ); - permVec = vec_add( permVec, (vector unsigned char)(-4) ); //shift permute right 3 elements - const vector float vecTangent1 = vec_perm( v3, v4, permVec ); - - // calculate lightDir - vector float vecLightDir = vec_sub( vecLightOrigin, vecXYZ ); - vector float vecViewDir = vec_sub( vecViewOrigin, vecXYZ ); - - // calculate distance - vector float vecTempLight = vec_madd( vecLightDir, vecLightDir, zeroVector ); - vector float vecTempView = vec_madd( vecViewDir, vecViewDir, zeroVector ); - - // sum accross first 3 elements of vector - vector float tempSum = vec_add( vecTempLight, vec_sld( vecTempLight, vecTempLight, 4 ) ); - vecTempLight = vec_add( tempSum, vec_sld( tempSum, tempSum, 8 ) ); - vector float tempSum2 = vec_add( vecTempView, vec_sld( vecTempView, vecTempView, 4 ) ); - vecTempView = vec_add( tempSum2, vec_sld( tempSum2, tempSum2, 8 ) ); - - // splat sum accross the whole vector - vecTempLight = vec_splat( vecTempLight, 0 ); - vecTempView = vec_splat( vecTempView, 0 ); - - vecTempLight = ReciprocalSquareRoot( vecTempLight ); - vecTempView = ReciprocalSquareRoot( vecTempView ); - - // modify light and view vectors based on ilength - vecViewDir = vec_madd( vecViewDir, vecTempView, zeroVector ); - vecLightDir = vec_madd( vecLightDir, vecTempLight, vecViewDir ); - - // calculate what to store in each texture coord - vector float vecTC0 = vec_madd( vecLightDir, vecTangent0, zeroVector ); - vector float vecTC1 = vec_madd( vecLightDir, vecTangent1, zeroVector ); - vector float vecTC2 = vec_madd( vecLightDir, vecNormal, zeroVector ); - - // sum accross first 3 elements of vector - vector float tempSum3; - tempSum = vec_add( vecTC0, vec_sld( vecTC0, vecTC0, 4 ) ); - vecTC0 = vec_add( tempSum, vec_sld( vecTC0, vecTC0, 8 ) ); - tempSum2 = vec_add( vecTC1, vec_sld( vecTC1, vecTC1, 4 ) ); - vecTC1 = vec_add( tempSum2, vec_sld( vecTC1, vecTC1, 8 ) ); - tempSum3 = vec_add( vecTC2, vec_sld( vecTC2, vecTC2, 4 ) ); - vecTC2 = vec_add( tempSum3, vec_sld( vecTC2, vecTC2, 8 ) ); - - vecTC0 = vec_splat( vecTC0, 0 ); - vecTC1 = vec_splat( vecTC1, 0 ); - vecTC2 = vec_splat( vecTC2, 0 ); - - // store out results - vec_ste( vecTC0, 0, &texCoords[index][0] ); - vec_ste( vecTC1, 0, &texCoords[index][1] ); - vec_ste( vecTC2, 0, &texCoords[index][2] ); - vec_ste( (vector float)(1.0), 0, &texCoords[index][3] ); - - } -} -#endif /* 0 for disable spec coord */ - -#if 1 - -#ifdef VERTEXCACHE_ALIGNED -/* -============ -idSIMD_AltiVec::CreateShadowCache -============ -*/ -int VPCALL idSIMD_AltiVec::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { - int outVerts = 0; - int i = 0; - - assert( IS_16BYTE_ALIGNED( vertexCache[0] ) ); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector unsigned char vecPerm, vecPerm2, vecPerm3, vecPerm4, vecPerm5; - register vector float zeroVector = (vector float)(0.0); - register vector float oneVector = (vector float)(1); - register vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - - const float *lPtr = lightOrigin.ToFloatPtr(); - const float *vPtr; - const float *vPtr2; - const float *vPtr3; - const float *vPtr4; - - // put values into a vector - vecPerm = vec_add( vec_lvsl( -1, lPtr ), (vector unsigned char)(1) ); - v0 = vec_ld( 0, lPtr ); - v1 = vec_ld( 15, lPtr ); - v0 = vec_perm( v0, v1, vecPerm ); - v0 = vec_perm( v0, zeroVector, vecPermZeroLast ); - - //v0 now contains lightOrigin[0], lightOrigin[1], lightOrigin[2], 0 - for ( ; i+3 < numVerts; i+= 4 ) { - if ( ! vertRemap[i] ) { - vPtr = verts[i].xyz.ToFloatPtr(); - -#ifndef DRAWVERT_PADDED - vecPerm2 = vec_add( vec_lvsl( -1, vPtr ), (vector unsigned char)(1) ); - v2 = vec_ld( 0, vPtr ); - v3 = vec_ld( 15, vPtr ); - v7 = vec_perm( v2, v3, vecPerm2 ); -#else - v7 = vec_ld( 0, vPtr ); -#endif - v2 = vec_perm( v7, zeroVector, vecPermZeroLast ); - v3 = vec_perm( v7, oneVector, vecPermZeroLast ); - v1 = vec_sub( v2, v0 ); - - vec_st( v3, 0, &vertexCache[outVerts][0] ); - vec_st( v1, 0, &vertexCache[outVerts+1][0] ); - - vertRemap[i] = outVerts; - outVerts += 2; - } - - if ( ! vertRemap[i+1] ) { - vPtr2 = verts[i+1].xyz.ToFloatPtr(); - -#ifndef DRAWVERT_PADDED - vecPerm3 = vec_add( vec_lvsl( -1, vPtr2 ), (vector unsigned char)(1) ); - v4 = vec_ld( 0, vPtr2 ); - v5 = vec_ld( 15, vPtr2 ); - v6 = vec_perm( v4, v5, vecPerm3 ); -#else - v6 = vec_ld( 0, vPtr2 ); -#endif - v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); - v5 = vec_perm( v6, oneVector, vecPermZeroLast ); - v6 = vec_sub( v4, v0 ); - - vec_st( v5, 0, &vertexCache[outVerts][0] ); - vec_st( v6, 0, &vertexCache[outVerts+1][0] ); - - vertRemap[i+1] = outVerts; - outVerts += 2; - } - - if ( ! vertRemap[i+2] ) { - vPtr3 = verts[i+2].xyz.ToFloatPtr(); - -#ifndef DRAWVERT_PADDED - vecPerm4 = vec_add( vec_lvsl( -1, vPtr3 ), (vector unsigned char)(1) ); - v1 = vec_ld( 0, vPtr3 ); - v2 = vec_ld( 15, vPtr3 ); - v3 = vec_perm( v1, v2, vecPerm4 ); -#else - v3 = vec_ld( 0, vPtr3 ); -#endif - v1 = vec_perm( v3, zeroVector, vecPermZeroLast ); - v2 = vec_perm( v3, oneVector, vecPermZeroLast ); - v3 = vec_sub( v1, v0 ); - - vec_st( v2, 0, &vertexCache[outVerts][0] ); - vec_st( v3, 0, &vertexCache[outVerts+1][0] ); - - vertRemap[i+2] = outVerts; - outVerts += 2; - } - - if ( ! vertRemap[i+3] ) { - vPtr4 = verts[i+3].xyz.ToFloatPtr(); -#ifndef DRAWVERT_PADDED - vecPerm5 = vec_add( vec_lvsl( -1, vPtr4 ), (vector unsigned char)(1) ); - v4 = vec_ld( 0, vPtr4 ); - v5 = vec_ld( 16, vPtr4 ); - v6 = vec_perm( v4, v5, vecPerm5 ); -#else - v6 = vec_ld( 0, vPtr4 ); -#endif - v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); - v5 = vec_perm( v6, oneVector, vecPermZeroLast ); - v6 = vec_sub( v4, v0 ); - - vec_st( v5, 0, &vertexCache[outVerts][0] ); - vec_st( v6, 0, &vertexCache[outVerts+1][0] ); - - vertRemap[i+3] = outVerts; - outVerts += 2; - } - } - - // cleanup - for (; i < numVerts; i++ ) { - if ( vertRemap[i] ) { - continue; - } - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[outVerts+0][0] = v[0]; - vertexCache[outVerts+0][1] = v[1]; - vertexCache[outVerts+0][2] = v[2]; - vertexCache[outVerts+0][3] = 1.0f; - - // R_SetupProjection() builds the projection matrix with a slight crunch - // for depth, which keeps this w=0 division from rasterizing right at the - // wrap around point and causing depth fighting with the rear caps - vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; - vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; - vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; - vertexCache[outVerts+1][3] = 0.0f; - vertRemap[i] = outVerts; - outVerts += 2; - } - return outVerts; -} - -#else - -/* -============ -idSIMD_AltiVec::CreateShadowCache -============ -*/ -int VPCALL idSIMD_AltiVec::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { - int outVerts = 0; - int i = 0; - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector unsigned char vecPerm, vecPerm2, vecPerm3, vecPerm4, vecPerm5; - register vector float zeroVector = (vector float)(0.0); - register vector float oneVector = (vector float)(1); - register vector unsigned char vecPermZeroLast = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - - const float *lPtr = lightOrigin.ToFloatPtr(); - const float *vPtr; - const float *vPtr2; - const float *vPtr3; - const float *vPtr4; - - // put values into a vector - vecPerm = vec_add( vec_lvsl( -1, lPtr ), (vector unsigned char)(1) ); - v0 = vec_ld( 0, lPtr ); - v1 = vec_ld( 15, lPtr ); - v0 = vec_perm( v0, v1, vecPerm ); - v0 = vec_perm( v0, zeroVector, vecPermZeroLast ); - - //v0 now contains lightOrigin[0], lightOrigin[1], lightOrigin[2], 0 - for ( ; i+3 < numVerts; i+= 4 ) { - if ( ! vertRemap[i] ) { - vPtr = verts[i].xyz.ToFloatPtr(); -#ifndef DRAWVERT_PADDED - vecPerm2 = vec_add( vec_lvsl( -1, vPtr ), (vector unsigned char)(1) ); - v2 = vec_ld( 0, vPtr ); - v3 = vec_ld( 15, vPtr ); - v7 = vec_perm( v2, v3, vecPerm2 ); -#else - v7 = vec_ld( 0, vPtr ); -#endif - v2 = vec_perm( v7, zeroVector, vecPermZeroLast ); - v3 = vec_perm( v7, oneVector, vecPermZeroLast ); - v1 = vec_sub( v2, v0 ); - - // store results - UNALIGNED_STORE2( &vertexCache[outVerts][0], v3, v1 ); - - vertRemap[i] = outVerts; - outVerts += 2; - } - - if ( ! vertRemap[i+1] ) { - vPtr2 = verts[i+1].xyz.ToFloatPtr(); -#ifndef DRAWVERT_PADDED - vecPerm3 = vec_add( vec_lvsl( -1, vPtr2 ), (vector unsigned char)(1) ); - v4 = vec_ld( 0, vPtr2 ); - v5 = vec_ld( 15, vPtr2 ); - v6 = vec_perm( v4, v5, vecPerm3 ); -#else - v6 = vec_ld( 0, vPtr2 ); -#endif - v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); - v5 = vec_perm( v6, oneVector, vecPermZeroLast ); - v6 = vec_sub( v4, v0 ); - - // store results - UNALIGNED_STORE2( &vertexCache[outVerts][0], v5, v6 ); - - vertRemap[i+1] = outVerts; - outVerts += 2; - } - - if ( ! vertRemap[i+2] ) { - vPtr3 = verts[i+2].xyz.ToFloatPtr(); -#ifndef DRAWVERT_PADDED - vecPerm4 = vec_add( vec_lvsl( -1, vPtr3 ), (vector unsigned char)(1) ); - v1 = vec_ld( 0, vPtr3 ); - v2 = vec_ld( 15, vPtr3 ); - v3 = vec_perm( v1, v2, vecPerm4 ); -#else - v3 = vec_ld( 0, vPtr3 ); -#endif - v1 = vec_perm( v3, zeroVector, vecPermZeroLast ); - v2 = vec_perm( v3, oneVector, vecPermZeroLast ); - v3 = vec_sub( v1, v0 ); - - // store results - UNALIGNED_STORE2( &vertexCache[outVerts][0], v2, v3 ); - - vertRemap[i+2] = outVerts; - outVerts += 2; - } - if ( ! vertRemap[i+3] ) { - vPtr4 = verts[i+3].xyz.ToFloatPtr(); -#ifndef DRAWVERT_PADDED - vecPerm5 = vec_add( vec_lvsl( -1, vPtr4 ), (vector unsigned char)(1) ); - v4 = vec_ld( 0, vPtr4 ); - v5 = vec_ld( 16, vPtr4 ); - v6 = vec_perm( v4, v5, vecPerm5 ); -#else - v6 = vec_ld( 0, vPtr4 ); -#endif - - v4 = vec_perm( v6, zeroVector, vecPermZeroLast ); - v5 = vec_perm( v6, oneVector, vecPermZeroLast ); - v6 = vec_sub( v4, v0 ); - - // store results - UNALIGNED_STORE2( &vertexCache[outVerts][0], v5, v6 ); - - - vertRemap[i+3] = outVerts; - outVerts += 2; - } - } - - // cleanup - for (; i < numVerts; i++ ) { - if ( vertRemap[i] ) { - continue; - } - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[outVerts+0][0] = v[0]; - vertexCache[outVerts+0][1] = v[1]; - vertexCache[outVerts+0][2] = v[2]; - vertexCache[outVerts+0][3] = 1.0f; - - // R_SetupProjection() builds the projection matrix with a slight crunch - // for depth, which keeps this w=0 division from rasterizing right at the - // wrap around point and causing depth fighting with the rear caps - vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; - vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; - vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; - vertexCache[outVerts+1][3] = 0.0f; - vertRemap[i] = outVerts; - outVerts += 2; - } - return outVerts; -} -#endif /* VERTEXCACHE_ALIGNED */ - -#endif /* 0 to disable shadow cache */ - -#if 1 - -#ifdef VERTEXCACHE_ALIGNED -/* -============ -idSIMD_AltiVec::CreateVertexProgramShadowCache -============ -*/ -int VPCALL idSIMD_AltiVec::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { - - // vertexCache aligned - assert( IS_16BYTE_ALIGNED( vertexCache[0] ) ); - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - // idVec4 size - assert( sizeof(idVec4) == IDVEC4_OFFSET * sizeof(float) ); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float zeroVector = (vector float)(0.0); - register vector float oneVector = (vector float)(1); - register vector unsigned char vecPermThreeOne = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - int i = 0; - -#ifndef DRAWVERT_PADDED - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < numVerts ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } -#endif - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - -#ifndef DRAWVERT_PADDED - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v1 = vec_perm( v2, v3, vertPerm2 ); - v2 = vec_perm( v4, v5, vertPerm3 ); - v3 = vec_perm( v6, v7, vertPerm4 ); -#else - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 0, vertPtr2 ); - v2 = vec_ld( 0, vertPtr3 ); - v3 = vec_ld( 0, vertPtr4 ); -#endif - - v0 = vec_perm( v0, oneVector, vecPermThreeOne ); - v4 = vec_perm( v0, zeroVector, vecPermThreeOne ); - - v1 = vec_perm( v1, oneVector, vecPermThreeOne ); - v5 = vec_perm( v1, zeroVector, vecPermThreeOne ); - - v2 = vec_perm( v2, oneVector, vecPermThreeOne ); - v6 = vec_perm( v2, zeroVector, vecPermThreeOne ); - - v3 = vec_perm( v3, oneVector, vecPermThreeOne ); - v7 = vec_perm( v3, zeroVector, vecPermThreeOne ); - - // store results - ALIGNED_STORE4( &vertexCache[i*2][0], v0, v4, v1, v5 ); - ALIGNED_STORE4( &vertexCache[(i+2)*2][0], v2, v6, v3, v7 ); - - } - - // cleanup - for ( ; i < numVerts; i++ ) { - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[i*2+0][0] = v[0]; - vertexCache[i*2+1][0] = v[0]; - vertexCache[i*2+0][1] = v[1]; - vertexCache[i*2+1][1] = v[1]; - vertexCache[i*2+0][2] = v[2]; - vertexCache[i*2+1][2] = v[2]; - vertexCache[i*2+0][3] = 1.0f; - vertexCache[i*2+1][3] = 0.0f; - } - return numVerts * 2; -} - -#else -/* -============ -idSIMD_AltiVec::CreateVertexProgramShadowCache -============ -*/ -int VPCALL idSIMD_AltiVec::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { - - // idDrawVert size - assert( sizeof(idDrawVert) == DRAWVERT_OFFSET * sizeof(float) ); - // idVec4 size - assert( sizeof(idVec4) == IDVEC4_OFFSET * sizeof(float) ); - - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector float zeroVector = (vector float)(0.0); - register vector float oneVector = (vector float)(1); - register vector unsigned char vecPermThreeOne = (vector unsigned char)(0,1,2,3,4,5,6,7,8,9,10,11,16,17,18,19); - vector unsigned char vertPerm1, vertPerm2, vertPerm3, vertPerm4; - int i = 0; - -#ifndef DRAWVERT_PADDED - // every fourth one will have the same alignment. Make sure we've got enough here - if ( i+3 < numVerts ) { - vertPerm1 = vec_add( vec_lvsl( -1, (float*) verts[0].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm2 = vec_add( vec_lvsl( -1, (float*) verts[1].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm3 = vec_add( vec_lvsl( -1, (float*) verts[2].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - vertPerm4 = vec_add( vec_lvsl( -1, (float*) verts[3].xyz.ToFloatPtr() ), (vector unsigned char)(1) ); - } -#endif - - for ( ; i+3 < numVerts; i+=4 ) { - const float *vertPtr = verts[i].xyz.ToFloatPtr(); - const float *vertPtr2 = verts[i+1].xyz.ToFloatPtr(); - const float *vertPtr3 = verts[i+2].xyz.ToFloatPtr(); - const float *vertPtr4 = verts[i+3].xyz.ToFloatPtr(); - -#ifndef DRAWVERT_PADDED - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 15, vertPtr ); - v2 = vec_ld( 0, vertPtr2 ); - v3 = vec_ld( 15, vertPtr2 ); - v4 = vec_ld( 0, vertPtr3 ); - v5 = vec_ld( 15, vertPtr3 ); - v6 = vec_ld( 0, vertPtr4 ); - v7 = vec_ld( 15, vertPtr4 ); - - v0 = vec_perm( v0, v1, vertPerm1 ); - v1 = vec_perm( v2, v3, vertPerm2 ); - v2 = vec_perm( v4, v5, vertPerm3 ); - v3 = vec_perm( v6, v7, vertPerm4 ); -#else - v0 = vec_ld( 0, vertPtr ); - v1 = vec_ld( 0, vertPtr2 ); - v2 = vec_ld( 0, vertPtr3 ); - v3 = vec_ld( 0, vertPtr4 ); -#endif - - v0 = vec_perm( v0, oneVector, vecPermThreeOne ); - v4 = vec_perm( v0, zeroVector, vecPermThreeOne ); - - v1 = vec_perm( v1, oneVector, vecPermThreeOne ); - v5 = vec_perm( v1, zeroVector, vecPermThreeOne ); - - v2 = vec_perm( v2, oneVector, vecPermThreeOne ); - v6 = vec_perm( v2, zeroVector, vecPermThreeOne ); - - v3 = vec_perm( v3, oneVector, vecPermThreeOne ); - v7 = vec_perm( v3, zeroVector, vecPermThreeOne ); - - // store results as unaligned - vector unsigned char storePerm = vec_sub( vec_lvsr( 15, &vertexCache[i*2][0] ), (vector unsigned char)(1) ); - vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); - vector float vc1 = vec_ld( 0, &vertexCache[i*2][0] ); - vector float vc2 = vec_ld( 127, &vertexCache[i*2][0] ); - - // right rotate input data - v0 = vec_perm( v0, v0, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v1 = vec_perm( v1, v1, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - v2 = vec_perm( v2, v2, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v7 = vec_perm( v7, v7, storePerm ); - - vec_st( vec_sel( vc1, v0, mask ), 0 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v0, v4, mask ), 15 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v4, v1, mask ), 31 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v1, v5, mask ), 47 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v5, v2, mask ), 63 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v2, v6, mask ), 79 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v6, v3, mask ), 95 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v3, v7, mask ), 111 , &vertexCache[i*2][0] ); - vec_st( vec_sel( v7, vc2, mask ), 127 , &vertexCache[i*2][0] ); - } - - // cleanup - for ( ; i < numVerts; i++ ) { - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[i*2+0][0] = v[0]; - vertexCache[i*2+1][0] = v[0]; - vertexCache[i*2+0][1] = v[1]; - vertexCache[i*2+1][1] = v[1]; - vertexCache[i*2+0][2] = v[2]; - vertexCache[i*2+1][2] = v[2]; - vertexCache[i*2+0][3] = 1.0f; - vertexCache[i*2+1][3] = 0.0f; - } - return numVerts * 2; -} - -#endif /* VERTEXCACHE_ALIGNED */ - -#endif /* 0 to kill VP shader cache */ - -#endif /* ENABLE_CREATE */ - -#ifdef ENABLE_SOUND_ROUTINES - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::UpSamplePCMTo44kHz - - Duplicate samples for 44kHz output. - - Assumptions: - Assumes that dest starts at aligned address -============ -*/ -void idSIMD_AltiVec::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { - - // dest is aligned - assert( IS_16BYTE_ALIGNED( dest[0] ) ); - - vector signed short vs0, vs1; - register vector signed int vi0, vi1; - register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; - // permute vectors - register vector unsigned char vecFirstHalf = (vector unsigned char)(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7); - register vector unsigned char vecSecondHalf = (vector unsigned char)(8,9,10,11,12,13,14,15,8,9,10,11,12,13,14,15); - - register vector unsigned char vecBottom = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - register vector unsigned char vecTop = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - - // If this can be assumed true, we can eliminate another conditional that checks to see if we can - // load up a vector before the loop - assert( numSamples >= 12 ); - - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - // 8 at a time - int i = 0; - - vector signed short vsOld = vec_ld( 0, &src[i] ); - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[i] ), (vector unsigned char)(1) ); - - for ( ; i+7 < numSamples; i+= 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // permute into vectors in the order to store - - v2 = vec_splat( v0, 0 ); - v3 = vec_splat( v0, 1 ); - v4 = vec_splat( v0, 2 ); - v5 = vec_splat( v0, 3 ); - v6 = vec_splat( v1, 0 ); - v7 = vec_splat( v1, 1 ); - v8 = vec_splat( v1, 2 ); - v9 = vec_splat( v1, 3 ); - - // store results - ALIGNED_STORE8( &dest[i*4], v2, v3, v4, v5, v6, v7, v8, v9 ); - } - // cleanup - for (; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; - } - } else { - int i = 0; - - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( ; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecFirstHalf ); - v3 = v2; - v4 = vec_perm( v0, v0, vecSecondHalf ); - v5 = v4; - v6 = vec_perm( v1, v1, vecFirstHalf ); - v7 = v6; - v8 = vec_perm (v1, v1, vecSecondHalf ); - v9 = v8; - - // store results - ALIGNED_STORE8( &dest[i*4], v2, v3, v4, v5, v6, v7, v8, v9 ); - } - - for ( ; i < numSamples; i += 2 ) { - dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; - dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 0, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecBottom ); - v3 = vec_perm( v0, v0, vecTop ); - v4 = vec_perm( v1, v1, vecBottom ); - v5 = vec_perm (v1, v1, vecTop ); - - // store results - ALIGNED_STORE4( &dest[i*2], v2, v3, v4, v5 ); - } - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; - } - } else { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecFirstHalf ); - v3 = vec_perm( v0, v0, vecSecondHalf ); - v4 = vec_perm( v1, v1, vecFirstHalf ); - v5 = vec_perm (v1, v1, vecSecondHalf ); - - // store results - ALIGNED_STORE4( &dest[i*2], v2, v3, v4, v5 ); - } - // cleanup - for ( ; i < numSamples; i += 2 ) { - dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; - dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; - } - } - } else if ( kHz == 44100 ) { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - - //unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - - //convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - - //store results - ALIGNED_STORE2( &dest[i], v0, v1 ); - } - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i] = (float) src[i]; - } - } else { - assert( 0 ); - } -} - -#else - -/* -============ -idSIMD_AltiVec::UpSamplePCMTo44kHz - - Duplicate samples for 44kHz output. - - Assumptions: - No assumptions -============ -*/ -void idSIMD_AltiVec::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { - - vector signed short vs0, vs1; - register vector signed int vi0, vi1; - register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; - // permute vectors - register vector unsigned char vecFirstHalf = (vector unsigned char)(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7); - register vector unsigned char vecSecondHalf = (vector unsigned char)(8,9,10,11,12,13,14,15,8,9,10,11,12,13,14,15); - - register vector unsigned char vecBottom = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - register vector unsigned char vecTop = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - - // calculate perm vector and masks for stores - vector unsigned char storePerm = vec_sub( vec_lvsr( 15, &dest[0] ), (vector unsigned char)(1) ); - // original values of dest - vector float vecDest = vec_ld( 0, &dest[0] ); - vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); - - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - // 8 at a time - int i = 0; - - vector signed short vsOld = vec_ld( 0, &src[i] ); - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[i] ), (vector unsigned char)(1) ); - - for ( ; i+7 < numSamples; i+= 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // permute into vectors in the order to store - - v2 = vec_splat( v0, 0 ); - v3 = vec_splat( v0, 1 ); - v4 = vec_splat( v0, 2 ); - v5 = vec_splat( v0, 3 ); - v6 = vec_splat( v1, 0 ); - v7 = vec_splat( v1, 1 ); - v8 = vec_splat( v1, 2 ); - v9 = vec_splat( v1, 3 ); - - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v7 = vec_perm( v7, v7, storePerm ); - v8 = vec_perm( v8, v8, storePerm ); - v9 = vec_perm( v9, v9, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); - vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); - vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); - vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); - vec_st( vec_sel( v5, v6, mask ), 63, &dest[i*4] ); - vec_st( vec_sel( v6, v7, mask ), 79, &dest[i*4] ); - vec_st( vec_sel( v7, v8, mask ), 95, &dest[i*4] ); - vec_st( vec_sel( v8, v9, mask ), 111, &dest[i*4] ); - vecDest = vec_sel( v9, vecDestEnd, mask ); - vec_st( vecDest, 127, &dest[i*4] ); - } - // cleanup - for (; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; - } - } else { - int i = 0; - - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( ; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecFirstHalf ); - v3 = v2; - v4 = vec_perm( v0, v0, vecSecondHalf ); - v5 = v4; - v6 = vec_perm( v1, v1, vecFirstHalf ); - v7 = v6; - v8 = vec_perm (v1, v1, vecSecondHalf ); - v9 = v8; - - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v7 = vec_perm( v7, v7, storePerm ); - v8 = vec_perm( v8, v8, storePerm ); - v9 = vec_perm( v9, v9, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); - vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); - vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); - vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); - vec_st( vec_sel( v5, v6, mask ), 63, &dest[i*4] ); - vec_st( vec_sel( v6, v7, mask ), 79, &dest[i*4] ); - vec_st( vec_sel( v7, v8, mask ), 95, &dest[i*4] ); - vec_st( vec_sel( v8, v9, mask ), 111, &dest[i*4] ); - vecDest = vec_sel( v9, vecDestEnd, mask ); - vec_st( vecDest, 127, &dest[i*4] ); - } - - for ( ; i < numSamples; i += 2 ) { - dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; - dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 0, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecBottom ); - v3 = vec_perm( v0, v0, vecTop ); - v4 = vec_perm( v1, v1, vecBottom ); - v5 = vec_perm (v1, v1, vecTop ); - - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*2] ); - vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*2] ); - vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*2] ); - vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*2] ); - vecDest = vec_sel( v5, vecDestEnd, mask ); - vec_st( vecDest, 63, &dest[i*2] ); - - } - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; - } - } else { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load src - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); - - // unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - // convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - // put into vectors in order to store - v2 = vec_perm( v0, v0, vecFirstHalf ); - v3 = vec_perm( v0, v0, vecSecondHalf ); - v4 = vec_perm( v1, v1, vecFirstHalf ); - v5 = vec_perm (v1, v1, vecSecondHalf ); - - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*2] ); - vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*2] ); - vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*2] ); - vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*2] ); - vecDest = vec_sel( v5, vecDestEnd, mask ); - vec_st( vecDest, 63, &dest[i*2] ); - } - // cleanup - for ( ; i < numSamples; i += 2 ) { - dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; - dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; - } - } - } else if ( kHz == 44100 ) { - int i; - vector unsigned char permVec = vec_add( vec_lvsl( -1, &src[0] ), (vector unsigned char)(1) ); - vector signed short vsOld = vec_ld( 0, &src[0] ); - - for ( i = 0; i+7 < numSamples; i += 8 ) { - //vs0 = vec_ld( 0, &src[i] ); - vs1 = vec_ld( 15, &src[i] ); - vs0 = vec_perm( vsOld, vs1, permVec ); - vsOld = vs1; - vector float vecDestEnd = vec_ld( 31, &dest[i] ); - - //unpack shorts to ints - vi0 = vec_unpackh( vs0 ); - vi1 = vec_unpackl( vs0 ); - - //convert ints to floats - v0 = vec_ctf( vi0, 0 ); - v1 = vec_ctf( vi1, 0 ); - - v0 = vec_perm( v0, v0, storePerm ); - v1 = vec_perm( v1, v1, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i] ); - vec_st( vec_sel( v0, v1, mask ), 15, &dest[i] ); - vecDest = vec_sel( v1, vecDestEnd, mask ); - vec_st( vecDest, 31, &dest[i] ); - } - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i] = (float) src[i]; - } - } else { - assert( 0 ); - } -} - -#endif - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::UpSampleOGGTo44kHz - - Duplicate samples for 44kHz output. - - Assumptions: - Assumes that dest starts at aligned address -============ -*/ -void idSIMD_AltiVec::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { - // dest is aligned - assert( IS_16BYTE_ALIGNED( dest[0] ) ); - - register vector float oggVec1, oggVec2, oggVec3, oggVec4, oggVec5, oggVec6, oggVec7, oggVec8; - register vector float constVec, zeroVector; - register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; - vector unsigned char vecPerm1; - vector unsigned char vecPerm2; - - vector unsigned char vecOneTwo = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - vector unsigned char vecThreeFour = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - vector unsigned char vecFirst = (vector unsigned char)(0,1,2,3,16,17,18,19,0,1,2,3,16,17,18,19); - vector unsigned char vecSecond = (vector unsigned char)(4,5,6,7,20,21,22,23,4,5,6,7,20,21,22,23); - vector unsigned char vecThird = (vector unsigned char)(8,9,10,11,24,25,26,27,8,9,10,11,24,25,26,27); - vector unsigned char vecFourth = (vector unsigned char)(12,13,14,15,28,29,30,31,12,13,14,15,28,29,30,31); - - constVec = (vector float)(32768.0f); - zeroVector = (vector float)(0.0); - - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - v10 = vec_ld( 0, &ogg[0][0] ); - - int i; - for ( i = 0; i+7 < numSamples; i += 8 ) { - // as it happens, ogg[0][i] through ogg[0][i+3] are contiguous in memory - v8 = v10; - v9 = vec_ld( 15, &ogg[0][i] ); - v10 = vec_ld( 31, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - v1 = vec_perm( v9, v10, vecPerm1 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec1 = vec_splat( v0, 0 ); - oggVec2 = vec_splat( v0, 1 ); - oggVec3 = vec_splat( v0, 2 ); - oggVec4 = vec_splat( v0, 3 ); - oggVec5 = vec_splat( v1, 0 ); - oggVec6 = vec_splat( v1, 1 ); - oggVec7 = vec_splat( v1, 2 ); - oggVec8 = vec_splat( v1, 3 ); - - v0 = vec_madd( oggVec1, constVec, zeroVector ); - v1 = vec_madd( oggVec2, constVec, zeroVector ); - v2 = vec_madd( oggVec3, constVec, zeroVector ); - v3 = vec_madd( oggVec4, constVec, zeroVector ); - v4 = vec_madd( oggVec5, constVec, zeroVector ); - v5 = vec_madd( oggVec6, constVec, zeroVector ); - v6 = vec_madd( oggVec7, constVec, zeroVector ); - v7 = vec_madd( oggVec8, constVec, zeroVector ); - - //store results - ALIGNED_STORE8( &dest[i*4], v0, v1, v2, v3, v4, v5, v6, v7 ); - - } - - //cleanup - for ( ; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; - } - - } else { - - // calculate perm vec for ogg - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+3 < numSamples >> 1; i+=4 ) { // +1 += 2 - // load and splat from the array ( ogg[0][i] to ogg[0][i+3] ) - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec1 = vec_splat( v0, 0 ); - oggVec2 = vec_splat( v0, 1 ); - oggVec3 = vec_splat( v0, 2 ); - oggVec4 = vec_splat( v0, 3 ); - - // load and splat from the array ( ogg[1][i] to ogg[1][i+3] ) - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec5 = vec_splat( v1, 0 ); - oggVec6 = vec_splat( v1, 1 ); - oggVec7 = vec_splat( v1, 2 ); - oggVec8 = vec_splat( v1, 3 ); - - oggVec1 = vec_madd( oggVec1, constVec, zeroVector ); // ogg[0][i] * 32768 - oggVec2 = vec_madd( oggVec2, constVec, zeroVector ); // ogg[0][i+1] * 32768 - oggVec3 = vec_madd( oggVec3, constVec, zeroVector ); // ogg[0][i+2] * 32768 - oggVec4 = vec_madd( oggVec4, constVec, zeroVector ); // ogg[0][i+3] * 32768 - oggVec5 = vec_madd( oggVec5, constVec, zeroVector ); // ogg[1][i] * 32768 - oggVec6 = vec_madd( oggVec6, constVec, zeroVector ); // ogg[1][i+1] * 32768 - oggVec7 = vec_madd( oggVec7, constVec, zeroVector ); // ogg[1][i+2] * 32768 - oggVec8 = vec_madd( oggVec8, constVec, zeroVector ); // ogg[1][i+3] * 32768 - - //merge generates the interleaved pattern that we want and it - //doesn't require a permute vector, so use that instead - v0 = vec_mergeh( oggVec1, oggVec5 ); - v1 = vec_mergel( oggVec1, oggVec5 ); - v2 = vec_mergeh( oggVec2, oggVec6 ); - v3 = vec_mergel( oggVec2, oggVec6 ); - - v4 = vec_mergeh( oggVec3, oggVec7 ); - v5 = vec_mergel( oggVec3, oggVec7 ); - v6 = vec_mergeh( oggVec4, oggVec8 ); - v10 = vec_mergel( oggVec4, oggVec8 ); - - //store results - ALIGNED_STORE8( &dest[i*8], v0, v1, v2, v3, v4, v5, v6, v10 ); - } - - //cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; - dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - v10 = vec_ld( 0, &ogg[0][0] ); - - int i; - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load values from ogg - v8 = v10; - v9 = vec_ld( 15, &ogg[0][i] ); - v10 = vec_ld( 31, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - v1 = vec_perm( v9, v10, vecPerm1 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // permute into results vectors to store - v5 = vec_perm( v0, v0, vecOneTwo ); - v6 = vec_perm( v0, v0, vecThreeFour); - v7 = vec_perm( v1, v1, vecOneTwo ); - v8 = vec_perm( v1, v1, vecThreeFour ); - - //store results - ALIGNED_STORE4( &dest[i*2], v5, v6, v7, v8 ); - } - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; - } - } else { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - - int i; - for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { - // load ogg[0][i] to ogg[0][i+4] - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // load ogg[1][i] to ogg[1][i+3] - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // generate result vectors to store - v2 = vec_perm( v0, v1, vecFirst ); - v3 = vec_perm( v0, v1, vecSecond ); - v4 = vec_perm( v0, v1, vecThird ); - v5 = vec_perm( v0, v1, vecFourth ); - - // store results - ALIGNED_STORE4( &dest[i*4], v2, v3, v4, v5 ); - } - // cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; - dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 44100 ) { - if ( numChannels == 1 ) { - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load values from ogg - v8 = v9; - v7 = vec_ld( 15, &ogg[0][i] ); - v6 = v7; - v9 = vec_ld( 31, &ogg[0][i] ); - - v0 = vec_perm( v8, v7, vecPerm1 ); - v1 = vec_perm( v6, v9, vecPerm1 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - ALIGNED_STORE2( &dest[i], v0, v1 ); - } - - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*1+0] = ogg[0][i] * 32768.0f; - } - } else { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // load ogg[1][i] to ogg[1][i+3] - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // generate result vectors - v2 = vec_mergeh( v0, v1 ); - v3 = vec_mergel( v0, v1 ); - - // store results - ALIGNED_STORE2( &dest[i*2], v2, v3 ); - } - // cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*2+0] = ogg[0][i] * 32768.0f; - dest[i*2+1] = ogg[1][i] * 32768.0f; - } - } - } else { - assert( 0 ); - } -} - -#else - -/* -============ -idSIMD_AltiVec::UpSampleOGGTo44kHz - - Duplicate samples for 44kHz output. - - Assumptions: - No assumptions -============ -*/ -void idSIMD_AltiVec::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { - - register vector float oggVec1, oggVec2, oggVec3, oggVec4, oggVec5, oggVec6, oggVec7, oggVec8; - register vector float constVec, zeroVector; - register vector float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; - vector unsigned char vecPerm1; - vector unsigned char vecPerm2; - - vector unsigned char vecOneTwo = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - vector unsigned char vecThreeFour = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - vector unsigned char vecFirst = (vector unsigned char)(0,1,2,3,16,17,18,19,0,1,2,3,16,17,18,19); - vector unsigned char vecSecond = (vector unsigned char)(4,5,6,7,20,21,22,23,4,5,6,7,20,21,22,23); - vector unsigned char vecThird = (vector unsigned char)(8,9,10,11,24,25,26,27,8,9,10,11,24,25,26,27); - vector unsigned char vecFourth = (vector unsigned char)(12,13,14,15,28,29,30,31,12,13,14,15,28,29,30,31); - - vector unsigned char storePerm; - - constVec = (vector float)(32768.0f); - zeroVector = (vector float)(0.0); - - // calculate perm vector and masks for stores - storePerm = vec_sub( vec_lvsr( 15, &dest[0] ), (vector unsigned char)(1) ); - // original values of dest - vector float vecDest = vec_ld( 0, &dest[0] ); - vector unsigned int mask = vec_perm( (vector unsigned int)(0), (vector unsigned int)(-1), storePerm ); - - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - v10 = vec_ld( 0, &ogg[0][0] ); - - int i; - for ( i = 0; i+7 < numSamples; i += 8 ) { - // as it happens, ogg[0][i] through ogg[0][i+3] are contiguous in memory - v8 = v10; - v9 = vec_ld( 15, &ogg[0][i] ); - v10 = vec_ld( 31, &ogg[0][i] ); - vector float vecDestEnd = vec_ld( 127, &dest[i*4] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - v1 = vec_perm( v9, v10, vecPerm1 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec1 = vec_splat( v0, 0 ); - oggVec2 = vec_splat( v0, 1 ); - oggVec3 = vec_splat( v0, 2 ); - oggVec4 = vec_splat( v0, 3 ); - oggVec5 = vec_splat( v1, 0 ); - oggVec6 = vec_splat( v1, 1 ); - oggVec7 = vec_splat( v1, 2 ); - oggVec8 = vec_splat( v1, 3 ); - - v0 = vec_madd( oggVec1, constVec, zeroVector ); - v1 = vec_madd( oggVec2, constVec, zeroVector ); - v2 = vec_madd( oggVec3, constVec, zeroVector ); - v3 = vec_madd( oggVec4, constVec, zeroVector ); - v4 = vec_madd( oggVec5, constVec, zeroVector ); - v5 = vec_madd( oggVec6, constVec, zeroVector ); - v6 = vec_madd( oggVec7, constVec, zeroVector ); - v7 = vec_madd( oggVec8, constVec, zeroVector ); - - // rotate input data - v0 = vec_perm( v0, v0, storePerm ); - v1 = vec_perm( v1, v1, storePerm ); - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v7 = vec_perm( v7, v7, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i*4] ); - vec_st( vec_sel( v0, v1, mask ), 15, &dest[i*4] ); - vec_st( vec_sel( v1, v2, mask ), 31, &dest[i*4] ); - vec_st( vec_sel( v2, v3, mask ), 47, &dest[i*4] ); - vec_st( vec_sel( v3, v4, mask ), 63, &dest[i*4] ); - vec_st( vec_sel( v4, v5, mask ), 79, &dest[i*4] ); - vec_st( vec_sel( v5, v6, mask ), 95, &dest[i*4] ); - vec_st( vec_sel( v6, v7, mask ), 111, &dest[i*4] ); - vecDest = vec_sel( v7, vecDestEnd, mask ); - vec_st( vecDest, 127, &dest[i*4] ); - } - - //cleanup - for ( ; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; - } - - } else { - - // calculate perm vec for ogg - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+3 < numSamples >> 1; i+=4 ) { // +1 += 2 - // load and splat from the array ( ogg[0][i] to ogg[0][i+3] ) - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - vector float vecDestEnd = vec_ld( 127, &dest[i*8] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec1 = vec_splat( v0, 0 ); - oggVec2 = vec_splat( v0, 1 ); - oggVec3 = vec_splat( v0, 2 ); - oggVec4 = vec_splat( v0, 3 ); - - // load and splat from the array ( ogg[1][i] to ogg[1][i+3] ) - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // now we have the elements in a vector, we want - // to splat them each accross their own vector - oggVec5 = vec_splat( v1, 0 ); - oggVec6 = vec_splat( v1, 1 ); - oggVec7 = vec_splat( v1, 2 ); - oggVec8 = vec_splat( v1, 3 ); - - oggVec1 = vec_madd( oggVec1, constVec, zeroVector ); // ogg[0][i] * 32768 - oggVec2 = vec_madd( oggVec2, constVec, zeroVector ); // ogg[0][i+1] * 32768 - oggVec3 = vec_madd( oggVec3, constVec, zeroVector ); // ogg[0][i+2] * 32768 - oggVec4 = vec_madd( oggVec4, constVec, zeroVector ); // ogg[0][i+3] * 32768 - oggVec5 = vec_madd( oggVec5, constVec, zeroVector ); // ogg[1][i] * 32768 - oggVec6 = vec_madd( oggVec6, constVec, zeroVector ); // ogg[1][i+1] * 32768 - oggVec7 = vec_madd( oggVec7, constVec, zeroVector ); // ogg[1][i+2] * 32768 - oggVec8 = vec_madd( oggVec8, constVec, zeroVector ); // ogg[1][i+3] * 32768 - - //merge generates the interleaved pattern that we want and it - //doesn't require a permute vector, so use that instead - v0 = vec_mergeh( oggVec1, oggVec5 ); - v1 = vec_mergel( oggVec1, oggVec5 ); - v2 = vec_mergeh( oggVec2, oggVec6 ); - v3 = vec_mergel( oggVec2, oggVec6 ); - - v4 = vec_mergeh( oggVec3, oggVec7 ); - v5 = vec_mergel( oggVec3, oggVec7 ); - v6 = vec_mergeh( oggVec4, oggVec8 ); - v10 = vec_mergel( oggVec4, oggVec8 ); - - // rotate input data - v0 = vec_perm( v0, v0, storePerm ); - v1 = vec_perm( v1, v1, storePerm ); - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v10 = vec_perm( v10, v10, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i*8] ); - vec_st( vec_sel( v0, v1, mask ), 15, &dest[i*8] ); - vec_st( vec_sel( v1, v2, mask ), 31, &dest[i*8] ); - vec_st( vec_sel( v2, v3, mask ), 47, &dest[i*8] ); - vec_st( vec_sel( v3, v4, mask ), 63, &dest[i*8] ); - vec_st( vec_sel( v4, v5, mask ), 79, &dest[i*8] ); - vec_st( vec_sel( v5, v6, mask ), 95, &dest[i*8] ); - vec_st( vec_sel( v6, v10, mask ), 111, &dest[i*8] ); - vecDest = vec_sel( v10, vecDestEnd, mask ); - vec_st( vecDest, 127, &dest[i*8] ); - } - - //cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; - dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - v10 = vec_ld( 0, &ogg[0][0] ); - - int i; - - for ( i = 0; i+7 < numSamples; i += 8 ) { - - // load values from ogg - v8 = v10; - v9 = vec_ld( 15, &ogg[0][i] ); - v10 = vec_ld( 31, &ogg[0][i] ); - vector float vecDestEnd = vec_ld( 63, &dest[i*2] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - v1 = vec_perm( v9, v10, vecPerm1 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // permute into results vectors to store - v5 = vec_perm( v0, v0, vecOneTwo ); - v6 = vec_perm( v0, v0, vecThreeFour); - v7 = vec_perm( v1, v1, vecOneTwo ); - v8 = vec_perm( v1, v1, vecThreeFour ); - - // rotate input data - v5 = vec_perm( v5, v5, storePerm ); - v6 = vec_perm( v6, v6, storePerm ); - v7 = vec_perm( v7, v7, storePerm ); - v8 = vec_perm( v8, v8, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v5, mask ), 0, &dest[i*2] ); - vec_st( vec_sel( v5, v6, mask ), 15, &dest[i*2] ); - vec_st( vec_sel( v6, v7, mask ), 31, &dest[i*2] ); - vec_st( vec_sel( v7, v8, mask ), 47, &dest[i*2] ); - vecDest = vec_sel( v8, vecDestEnd, mask ); - vec_st( vecDest, 63, &dest[i*2] ); - } - - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; - } - } else { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - - int i; - for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { - // load ogg[0][i] to ogg[0][i+4] - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - vector float vecDestEnd = vec_ld( 63, &dest[i*4] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // load ogg[1][i] to ogg[1][i+3] - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // generate result vectors to store - v2 = vec_perm( v0, v1, vecFirst ); - v3 = vec_perm( v0, v1, vecSecond ); - v4 = vec_perm( v0, v1, vecThird ); - v5 = vec_perm( v0, v1, vecFourth ); - - // rotate input data - v2 = vec_perm( v2, v2, storePerm ); - v3 = vec_perm( v3, v3, storePerm ); - v4 = vec_perm( v4, v4, storePerm ); - v5 = vec_perm( v5, v5, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v2, mask ), 0, &dest[i*4] ); - vec_st( vec_sel( v2, v3, mask ), 15, &dest[i*4] ); - vec_st( vec_sel( v3, v4, mask ), 31, &dest[i*4] ); - vec_st( vec_sel( v4, v5, mask ), 47, &dest[i*4] ); - vecDest = vec_sel( v5, vecDestEnd, mask ); - vec_st( vecDest, 63, &dest[i*4] ); - } - - // cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; - dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 44100 ) { - if ( numChannels == 1 ) { - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+7 < numSamples; i += 8 ) { - // load values from ogg - v8 = v9; - v7 = vec_ld( 15, &ogg[0][i] ); - v6 = v7; - v9 = vec_ld( 31, &ogg[0][i] ); - vector float vecDestEnd = vec_ld( 31, &dest[i] ); - - v0 = vec_perm( v8, v7, vecPerm1 ); - v1 = vec_perm( v6, v9, vecPerm1 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // rotate data - v0 = vec_perm( v0, v0, storePerm ); - v1 = vec_perm( v1, v1, storePerm ); - - // store results - vec_st( vec_sel( vecDest, v0, mask ), 0, &dest[i] ); - vec_st( vec_sel( v0, v1, mask ), 15, &dest[i] ); - vecDest = vec_sel( v1, vecDestEnd, mask ); - vec_st( vecDest, 31, &dest[i] ); - } - - // cleanup - for ( ; i < numSamples; i++ ) { - dest[i*1+0] = ogg[0][i] * 32768.0f; - } - } else { - - // calculate perm vector and do first load - vecPerm1 = vec_add( vec_lvsl( -1, (int*) &ogg[0][0] ), (vector unsigned char)(1) ); - vecPerm2 = vec_add( vec_lvsl( -1, (int*) &ogg[1][0] ), (vector unsigned char)(1) ); - v7 = vec_ld( 0, &ogg[1][0] ); - v9 = vec_ld( 0, &ogg[0][0] ); - int i; - - for ( i = 0; i+3 < numSamples >> 1; i += 4 ) { - v8 = v9; - v9 = vec_ld( 15, &ogg[0][i] ); - v0 = vec_perm( v8, v9, vecPerm1 ); - - // load ogg[1][i] to ogg[1][i+3] - v6 = v7; - v7 = vec_ld( 15, &ogg[1][i] ); - v1 = vec_perm( v6, v7, vecPerm2 ); - - // multiply - v0 = vec_madd( v0, constVec, zeroVector ); - v1 = vec_madd( v1, constVec, zeroVector ); - - // generate result vectors - v2 = vec_mergeh( v0, v1 ); - v3 = vec_mergel( v0, v1 ); - - // store results - UNALIGNED_STORE2( &dest[i*2], v2, v3 ); - } - // cleanup - for ( ; i < numSamples >> 1; i++ ) { - dest[i*2+0] = ogg[0][i] * 32768.0f; - dest[i*2+1] = ogg[1][i] * 32768.0f; - } - } - } else { - assert( 0 ); - } -} -#endif /* SOUND_DEST_ALIGNED */ - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::MixSoundTwoSpeakerMono - - Assumptions: - Assumes that mixBuffer starts at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - - // mixBuffer is aligned - assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); - - int i; - float inc[2]; - float spkr[4]; - - register vector float vecInc; - register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; - register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; - register vector float vecSamplesLd1, vecSamplesLd2; - register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; - - register vector unsigned char permVec1 = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); //0,0,1,1 - register vector unsigned char permVec2 = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); //2,2,3,3 - register vector unsigned char permVec3 = (vector unsigned char)(16,17,18,19,16,17,18,19,20,21,22,23,20,21,22,23); //4,4,5,5 - register vector unsigned char permVec4 = (vector unsigned char)(24,25,26,27,24,25,26,27,28,29,30,31,28,29,30,31); //6,6,7,7 - - //constants - vector float fourVec = (vector float)(4.0); - vector float zeroVec = (vector float)(0.0); - - inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - spkr[0] = lastV[0]; - spkr[1] = lastV[1]; - spkr[2] = lastV[0] + inc[0]; - spkr[3] = lastV[1] + inc[1]; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - inc[0] *= 2; - inc[1] *= 2; - - //load data into registers - vector float v0 = loadSplatUnalignedScalar( &inc[0] ); - vector float v1 = loadSplatUnalignedScalar( &inc[1] ); - vecInc = vec_mergeh( v0, v1 ); - - vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); - vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); - vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); - vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); - - // load spkr array - v0 = vec_mergeh( v2, v4 ); - v1 = vec_mergeh( v3, v5 ); - vecSpeaker1 = vec_mergeh( v0, v1 ); - - vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); - vecInc = vec_madd( vecInc, fourVec, zeroVec ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 8, we don't - //need a cleanup loop - for( i=0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { - - //load samples and mix buffers - vecSamplesLd1 = vecSamplesLast; //vec_ld( 0, &samples[i] ); - vecSamplesLd2 = vec_ld( 15, &samples[i] ); - vecSamplesLast = vec_ld( 31, &samples[i] ); - - vecSamplesLd1 = vec_perm( vecSamplesLd1, vecSamplesLd2, samplesPerm ); - vecSamplesLd2 = vec_perm( vecSamplesLd2, vecSamplesLast, samplesPerm ); - - vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*2] ); - vecMixBuffer2 = vec_ld( 0, &mixBuffer[i*2+4] ); - vecMixBuffer3 = vec_ld( 0, &mixBuffer[i*2+8] ); - vecMixBuffer4 = vec_ld( 0, &mixBuffer[i*2+12] ); - - vecSamples1 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec1 ); - vecSamples2 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec2 ); - vecSamples3 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec3 ); - vecSamples4 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec4 ); - - vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); - - // store results - ALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); - - //add for next iteration - vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); - } -} - -#else - -/* -============ -idSIMD_AltiVec::MixSoundTwoSpeakerMono - - Assumptions: - No assumptions -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - - int i; - float inc[2]; - float spkr[4]; - - register vector float vecInc; - register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; - register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; - register vector float vecSamplesLd1, vecSamplesLd2; - register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; - - register vector unsigned char permVec1 = (vector unsigned char)(0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); //0,0,1,1 - register vector unsigned char permVec2 = (vector unsigned char)(8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); //2,2,3,3 - register vector unsigned char permVec3 = (vector unsigned char)(16,17,18,19,16,17,18,19,20,21,22,23,20,21,22,23); //4,4,5,5 - register vector unsigned char permVec4 = (vector unsigned char)(24,25,26,27,24,25,26,27,28,29,30,31,28,29,30,31); //6,6,7,7 - - //constants - vector float fourVec = (vector float)(4.0); - vector float zeroVec = (vector float)(0.0); - - inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - spkr[0] = lastV[0]; - spkr[1] = lastV[1]; - spkr[2] = lastV[0] + inc[0]; - spkr[3] = lastV[1] + inc[1]; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - inc[0] *= 2; - inc[1] *= 2; - - //load data into registers - vector float v0 = loadSplatUnalignedScalar( &inc[0] ); - vector float v1 = loadSplatUnalignedScalar( &inc[1] ); - vecInc = vec_mergeh( v0, v1 ); - - vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); - vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); - vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); - vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); - - // load spkr array - v0 = vec_mergeh( v2, v4 ); - v1 = vec_mergeh( v3, v5 ); - vecSpeaker1 = vec_mergeh( v0, v1 ); - - vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); - vecInc = vec_madd( vecInc, fourVec, zeroVec ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0]), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - vector float vecDest = vec_ld( 0, &mixBuffer[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 8, we don't - //need a cleanup loop - for( i=0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { - - //load samples and mix buffers - vecSamplesLd1 = vecSamplesLast; - vecSamplesLd2 = vec_ld( 15, &samples[i] ); - vecSamplesLast = vec_ld( 31, &samples[i] ); - - vecSamplesLd1 = vec_perm( vecSamplesLd1, vecSamplesLd2, samplesPerm ); - vecSamplesLd2 = vec_perm( vecSamplesLd2, vecSamplesLast, samplesPerm ); - - vecMixBuffer1 = vecDest; - vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*2] ); - vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*2] ); - vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*2] ); - vector float vecDestEnd = vec_ld( 63, &mixBuffer[i*2] ); - - vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); - vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); - vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); - vecMixBuffer4 = vec_perm( vecMixBuffer4, vecDestEnd, mixBufferPerm ); - - vecSamples1 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec1 ); - vecSamples2 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec2 ); - vecSamples3 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec3 ); - vecSamples4 = vec_perm( vecSamplesLd1, vecSamplesLd2, permVec4 ); - - vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); - - // store results - UNALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); - - //add for next iteration - vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); - } -} - -#endif /* SOUND_DEST_ALIGNED */ - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::MixSoundTwoSpeakerStereo - - Assumptions: - Assumes that mixBuffer starts at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - // mixBuffer is aligned - assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); - - int i, k; - float inc[2]; - float spkr[4]; - - // loading buffers - register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; - // loading buffers - register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; - register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; - register vector float vecInc; - vector float fourVec = (vector float)(4.0); - vector float zeroVec = (vector float)(0.0); - - assert( numSamples == MIXBUFFER_SAMPLES ); - - inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - spkr[0] = lastV[0]; - spkr[1] = lastV[1]; - spkr[2] = lastV[0] + inc[0]; - spkr[3] = lastV[1] + inc[1]; - - for ( k = 0; k < 2; k++ ) { - inc[k] *= 2; - } - - // load data in vectors - vector float v0 = loadSplatUnalignedScalar( &inc[0] ); - vector float v1 = loadSplatUnalignedScalar( &inc[1] ); - vecInc = vec_mergeh( v0, v1 ); - - vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); - vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); - vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); - vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); - - // load spkr array - v0 = vec_mergeh( v2, v4 ); - v1 = vec_mergeh( v3, v5 ); - vecSpeaker1 = vec_mergeh( v0, v1 ); - - vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); - vecInc = vec_madd( vecInc, fourVec, zeroVec ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 8, we don't - //need a cleanup loop - for( i = 0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { - // load mix buffers and samples - vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*2] ); - vecMixBuffer2 = vec_ld( 0, &mixBuffer[i*2+4] ); - vecMixBuffer3 = vec_ld( 0, &mixBuffer[i*2+8] ); - vecMixBuffer4 = vec_ld( 0, &mixBuffer[i*2+12] ); - - vecSamples1 = vecSamplesLast; - vecSamples2 = vec_ld( 15, &samples[i*2] ); - vecSamples3 = vec_ld( 31, &samples[i*2] ); - vecSamples4 = vec_ld( 47, &samples[i*2] ); - vecSamplesLast = vec_ld( 63, &samples[i*2] ); - - vecSamples1 = vec_perm( vecSamples1, vecSamples2, samplesPerm ); - vecSamples2 = vec_perm( vecSamples2, vecSamples3, samplesPerm ); - vecSamples3 = vec_perm( vecSamples3, vecSamples4, samplesPerm ); - vecSamples4 = vec_perm( vecSamples4, vecSamplesLast, samplesPerm ); - - vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); - - vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); - - //store results - ALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); - } -} -#else - -/* -============ -idSIMD_AltiVec::MixSoundTwoSpeakerStereo - - Assumptions: - No assumptions -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - - int i, k; - float inc[2]; - float spkr[4]; - // loading buffers - register vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4; - // loading buffers - register vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4; - register vector float vecSpeaker1, vecSpeaker2, vecSpeaker3, vecSpeaker4; - register vector float vecInc; - vector float fourVec = (vector float)(4.0); - vector float zeroVec = (vector float)(0.0); - - assert( numSamples == MIXBUFFER_SAMPLES ); - - inc[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - inc[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - spkr[0] = lastV[0]; - spkr[1] = lastV[1]; - spkr[2] = lastV[0] + inc[0]; - spkr[3] = lastV[1] + inc[1]; - - for ( k = 0; k < 2; k++ ) { - inc[k] *= 2; - } - - // load data in vectors - vector float v0 = loadSplatUnalignedScalar( &inc[0] ); - vector float v1 = loadSplatUnalignedScalar( &inc[1] ); - vecInc = vec_mergeh( v0, v1 ); - - vector float v2 = loadSplatUnalignedScalar( &spkr[0] ); - vector float v3 = loadSplatUnalignedScalar( &spkr[1] ); - vector float v4 = loadSplatUnalignedScalar( &spkr[2] ); - vector float v5 = loadSplatUnalignedScalar( &spkr[3] ); - - // load spkr array - v0 = vec_mergeh( v2, v4 ); - v1 = vec_mergeh( v3, v5 ); - vecSpeaker1 = vec_mergeh( v0, v1 ); - - vecSpeaker2 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker3, vecInc ); - vecInc = vec_madd( vecInc, fourVec, zeroVec ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - vector float vecDest = vec_ld( 0, &mixBuffer[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 8, we don't - //need a cleanup loop - for( i = 0 ; i+7 < MIXBUFFER_SAMPLES; i += 8 ) { - // load mix buffers and samples - vecMixBuffer1 = vecDest; - vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*2] ); - vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*2] ); - vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*2] ); - vector float vecDestEnd = vec_ld( 63, &mixBuffer[i*2] ); - - vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); - vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); - vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); - vecMixBuffer4 = vec_perm( vecMixBuffer4, vecDestEnd, mixBufferPerm ); - - vecSamples1 = vecSamplesLast; - vecSamples2 = vec_ld( 15, &samples[i*2] ); - vecSamples3 = vec_ld( 31, &samples[i*2] ); - vecSamples4 = vec_ld( 47, &samples[i*2] ); - vecSamplesLast = vec_ld( 63, &samples[i*2] ); - - vecSamples1 = vec_perm( vecSamples1, vecSamples2, samplesPerm ); - vecSamples2 = vec_perm( vecSamples2, vecSamples3, samplesPerm ); - vecSamples3 = vec_perm( vecSamples3, vecSamples4, samplesPerm ); - vecSamples4 = vec_perm( vecSamples4, vecSamplesLast, samplesPerm ); - - vecMixBuffer1 = vec_madd( vecSamples1, vecSpeaker1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSpeaker2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSpeaker3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSpeaker4, vecMixBuffer4 ); - - vecSpeaker1 = vec_add( vecSpeaker1, vecInc ); - vecSpeaker2 = vec_add( vecSpeaker2, vecInc ); - vecSpeaker3 = vec_add( vecSpeaker3, vecInc ); - vecSpeaker4 = vec_add( vecSpeaker4, vecInc ); - - // store results - UNALIGNED_STORE4( &mixBuffer[i*2], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4 ); - } -} - -#endif /* SOUND_DEST_ALIGNED */ - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::MixSoundSixSpeakerMono - - Assumptions: - Assumes that mixBuffer starts at aligned address -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - - // mixBuffer is aligned - assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); - - float incL[24]; - float sL[24]; - int i, k; - - vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4, vecIncl5, vecIncl6, vecIncl7; - vector float vecSL1, vecSL2, vecSL3, vecSL4, vecSL5, vecSL6, vecSL7; - vector float vecSamplesLd; - vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4, vecSamples5, vecSamples6; - vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6; - // permute vectors for sample - vector unsigned char samplePerm2 = (vector unsigned char)( 0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - vector unsigned char samplePerm5 = (vector unsigned char)( 8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - // incL array, 6 elements repeated - incL[0] = incL[6] = incL[12] = incL[18] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL[1] = incL[7] = incL[13] = incL[19] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL[2] = incL[8] = incL[14] = incL[20] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL[3] = incL[9] = incL[15] = incL[21] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL[4] = incL[10] = incL[16] = incL[22] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL[5] = incL[11] = incL[17] = incL[23] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - // sL array repeated - for ( k = 0; k < 6; k++ ) { - sL[k] = lastV[k]; - } - for ( k = 6; k < 12; k++ ) { - sL[k] = lastV[k-6] + incL[k]; - } - for ( k = 12; k < 18; k++ ) { - sL[k] = lastV[k-12] + incL[k] + incL[k]; - } - for ( k = 18; k < 24; k++ ) { - sL[k] = lastV[k-18] + incL[k] + incL[k] + incL[k]; - } - - // multiply by 2 since doing 12 at a time - for ( k = 0; k < 24; k++ ) { - incL[k] *= 4; - } - - //load the data - vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); - vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); - - vecIncl1 = vec_ld( 0, &incL[0] ); - vecIncl2 = vec_ld( 15, &incL[0] ); - vecIncl3 = vec_ld( 31, &incL[0] ); - vecIncl4 = vec_ld( 47, &incL[0] ); - vecIncl5 = vec_ld( 63, &incL[0] ); - vecIncl6 = vec_ld( 79, &incL[0] ); - vecIncl7 = vec_ld( 95, &incL[0] ); - - vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); - vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); - vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); - vecIncl4 = vec_perm( vecIncl4, vecIncl5, incPerm ); - vecIncl5 = vec_perm( vecIncl5, vecIncl6, incPerm ); - vecIncl6 = vec_perm( vecIncl6, vecIncl7, incPerm ); - - vecSL1 = vec_ld( 0, &sL[0] ); - vecSL2 = vec_ld( 15, &sL[0] ); - vecSL3 = vec_ld( 31, &sL[0] ); - vecSL4 = vec_ld( 47, &sL[0] ); - vecSL5 = vec_ld( 63, &sL[0] ); - vecSL6 = vec_ld( 79, &sL[0] ); - vecSL7 = vec_ld( 95, &sL[0] ); - - vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); - vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); - vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); - vecSL4 = vec_perm( vecSL4, vecSL5, slPerm ); - vecSL5 = vec_perm( vecSL5, vecSL6, slPerm ); - vecSL6 = vec_perm( vecSL6, vecSL7, slPerm ); - - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 4, we don't - //need a cleanup loop - for( i = 0; i <= MIXBUFFER_SAMPLES - 4; i += 4 ) { - //load mix buffer into vectors, assume aligned - vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*6] ); - vecMixBuffer2 = vec_ld( 0, &mixBuffer[(i*6)+4] ); - vecMixBuffer3 = vec_ld( 0, &mixBuffer[(i*6)+8] ); - vecMixBuffer4 = vec_ld( 0, &mixBuffer[(i*6)+12] ); - vecMixBuffer5 = vec_ld( 0, &mixBuffer[(i*6)+16] ); - vecMixBuffer6 = vec_ld( 0, &mixBuffer[(i*6)+20] ); - - //load samples into vector - vector float vecSamplesLd2 = vec_ld( 15, &samples[i] ); - vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); - vecSamplesLast = vecSamplesLd2; - - //permute to get them ordered how we want - vecSamples1 = vec_splat( vecSamplesLd, 0 ); - vecSamples2 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm2 ); - vecSamples3 = vec_splat( vecSamplesLd, 1 ); - vecSamples4 = vec_splat( vecSamplesLd, 2 ); - vecSamples5 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm5 ); - vecSamples6 = vec_splat( vecSamplesLd, 3 ); - - //do calculation - vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSL4, vecMixBuffer4 ); - vecMixBuffer5 = vec_madd( vecSamples5, vecSL5, vecMixBuffer5 ); - vecMixBuffer6 = vec_madd( vecSamples6, vecSL6, vecMixBuffer6 ); - - //store out results - ALIGNED_STORE6( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6 ); - - // add for next iteration - vecSL1 = vec_add( vecSL1, vecIncl1 ); - vecSL2 = vec_add( vecSL2, vecIncl2 ); - vecSL3 = vec_add( vecSL3, vecIncl3 ); - vecSL4 = vec_add( vecSL4, vecIncl4 ); - vecSL5 = vec_add( vecSL5, vecIncl5 ); - vecSL6 = vec_add( vecSL6, vecIncl6 ); - } -} -#else - -/* -============ -idSIMD_AltiVec::MixSoundSixSpeakerMono - - Assumptions: - No assumptions -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - - float incL[24]; - float sL[24]; - int i, k; - - vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4, vecIncl5, vecIncl6, vecIncl7; - vector float vecSL1, vecSL2, vecSL3, vecSL4, vecSL5, vecSL6, vecSL7; - vector float vecSamplesLd; - vector float vecSamples1, vecSamples2, vecSamples3, vecSamples4, vecSamples5, vecSamples6; - vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6; - // permute vectors for sample - register vector unsigned char samplePerm2 = (vector unsigned char)( 0,1,2,3,0,1,2,3,4,5,6,7,4,5,6,7); - register vector unsigned char samplePerm5 = (vector unsigned char)( 8,9,10,11,8,9,10,11,12,13,14,15,12,13,14,15); - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - // incL array, 6 elements repeated - incL[0] = incL[6] = incL[12] = incL[18] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL[1] = incL[7] = incL[13] = incL[19] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL[2] = incL[8] = incL[14] = incL[20] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL[3] = incL[9] = incL[15] = incL[21] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL[4] = incL[10] = incL[16] = incL[22] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL[5] = incL[11] = incL[17] = incL[23] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - // sL array repeated - for ( k = 0; k < 6; k++ ) { - sL[k] = lastV[k]; - } - for ( k = 6; k < 12; k++ ) { - sL[k] = lastV[k-6] + incL[k]; - } - for ( k = 12; k < 18; k++ ) { - sL[k] = lastV[k-12] + incL[k] + incL[k]; - } - for ( k = 18; k < 24; k++ ) { - sL[k] = lastV[k-18] + incL[k] + incL[k] + incL[k]; - } - - // multiply by 2 since doing 12 at a time - for ( k = 0; k < 24; k++ ) { - incL[k] *= 4; - } - - // load the data - vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); - vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); - - vecIncl1 = vec_ld( 0, &incL[0] ); - vecIncl2 = vec_ld( 15, &incL[0] ); - vecIncl3 = vec_ld( 31, &incL[0] ); - vecIncl4 = vec_ld( 47, &incL[0] ); - vecIncl5 = vec_ld( 63, &incL[0] ); - vecIncl6 = vec_ld( 79, &incL[0] ); - vecIncl7 = vec_ld( 95, &incL[0] ); - - vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); - vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); - vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); - vecIncl4 = vec_perm( vecIncl4, vecIncl5, incPerm ); - vecIncl5 = vec_perm( vecIncl5, vecIncl6, incPerm ); - vecIncl6 = vec_perm( vecIncl6, vecIncl7, incPerm ); - - vecSL1 = vec_ld( 0, &sL[0] ); - vecSL2 = vec_ld( 15, &sL[0] ); - vecSL3 = vec_ld( 31, &sL[0] ); - vecSL4 = vec_ld( 47, &sL[0] ); - vecSL5 = vec_ld( 63, &sL[0] ); - vecSL6 = vec_ld( 79, &sL[0] ); - vecSL7 = vec_ld( 95, &sL[0] ); - - vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); - vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); - vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); - vecSL4 = vec_perm( vecSL4, vecSL5, slPerm ); - vecSL5 = vec_perm( vecSL5, vecSL6, slPerm ); - vecSL6 = vec_perm( vecSL6, vecSL7, slPerm ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - vector float vecDest = vec_ld( 0, &mixBuffer[0] ); - - //since MIXBUFFER_SAMPLES is a multiple of 4, we don't - //need a cleanup loop - for( i = 0; i <= MIXBUFFER_SAMPLES - 4; i += 4 ) { - //load mix buffer into vectors - vecMixBuffer1 = vecDest; - vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*6] ); - vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*6] ); - vecMixBuffer4 = vec_ld( 47, &mixBuffer[i*6] ); - vecMixBuffer5 = vec_ld( 63, &mixBuffer[i*6] ); - vecMixBuffer6 = vec_ld( 79, &mixBuffer[i*6] ); - vector float vecDestEnd = vec_ld( 95, &mixBuffer[i*6] ); - - vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); - vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); - vecMixBuffer3 = vec_perm( vecMixBuffer3, vecMixBuffer4, mixBufferPerm ); - vecMixBuffer4 = vec_perm( vecMixBuffer4, vecMixBuffer5, mixBufferPerm ); - vecMixBuffer5 = vec_perm( vecMixBuffer5, vecMixBuffer6, mixBufferPerm ); - vecMixBuffer6 = vec_perm( vecMixBuffer6, vecDestEnd, mixBufferPerm ); - - //load samples into vector - vector float vecSamplesLd2 = vec_ld( 15, &samples[i] ); - vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); - vecSamplesLast = vecSamplesLd2; - - //permute to get them ordered how we want - vecSamples1 = vec_splat( vecSamplesLd, 0 ); - vecSamples2 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm2 ); - vecSamples3 = vec_splat( vecSamplesLd, 1 ); - vecSamples4 = vec_splat( vecSamplesLd, 2 ); - vecSamples5 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm5 ); - vecSamples6 = vec_splat( vecSamplesLd, 3 ); - - //do calculation - vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); - vecMixBuffer4 = vec_madd( vecSamples4, vecSL4, vecMixBuffer4 ); - vecMixBuffer5 = vec_madd( vecSamples5, vecSL5, vecMixBuffer5 ); - vecMixBuffer6 = vec_madd( vecSamples6, vecSL6, vecMixBuffer6 ); - - // store results - UNALIGNED_STORE6( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3, vecMixBuffer4, vecMixBuffer5, vecMixBuffer6 ); - - // add for next iteration - vecSL1 = vec_add( vecSL1, vecIncl1 ); - vecSL2 = vec_add( vecSL2, vecIncl2 ); - vecSL3 = vec_add( vecSL3, vecIncl3 ); - vecSL4 = vec_add( vecSL4, vecIncl4 ); - vecSL5 = vec_add( vecSL5, vecIncl5 ); - vecSL6 = vec_add( vecSL6, vecIncl6 ); - } -} - -#endif /* SOUND_DEST_ALIGNED */ - -#ifdef SOUND_DEST_ALIGNED -/* -============ -idSIMD_AltiVec::MixSoundSixSpeakerStereo - - Assumptions: - Assumes that mixBuffer starts at aligned address -============ -*/ - -void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - - // mixBuffer is aligned - assert( IS_16BYTE_ALIGNED( mixBuffer[0] ) ); - - float incL[12]; - float sL[12]; - int i; - vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4; - vector float vecSL1, vecSL2, vecSL3, vecSL4; - vector float vecSamplesLd; - vector float vecSamples1, vecSamples2, vecSamples3; - vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3; - // permute vectors for sample - vector unsigned char samplePerm1 = (vector unsigned char)( 0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3); - vector unsigned char samplePerm3 = (vector unsigned char)( 8,9,10,11,8,9,10,11,8,9,10,11,12,13,14,15); - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - // incL array, 6 elements repeated - incL[0] = incL[6] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL[1] = incL[7] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL[2] = incL[8] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL[3] = incL[9] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL[4] = incL[10] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL[5] = incL[11] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - // sL array repeated - sL[0] = lastV[0]; - sL[1] = lastV[1]; - sL[2] = lastV[2]; - sL[3] = lastV[3]; - sL[4] = lastV[4]; - sL[5] = lastV[5]; - sL[6] = lastV[0] + incL[0]; - sL[7] = lastV[1] + incL[1]; - sL[8] = lastV[2] + incL[2]; - sL[9] = lastV[3] + incL[3]; - sL[10] = lastV[4] + incL[4]; - sL[11] = lastV[5] + incL[5]; - - // multiply by 2 since doing 12 at a time - incL[0] *= 2; - incL[1] *= 2; - incL[2] *= 2; - incL[3] *= 2; - incL[4] *= 2; - incL[5] *= 2; - incL[6] *= 2; - incL[7] *= 2; - incL[8] *= 2; - incL[9] *= 2; - incL[10] *= 2; - incL[11] *= 2; - - //we aligned this data, so load it up - vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); - vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); - vecIncl1 = vec_ld( 0, &incL[0] ); - vecIncl2 = vec_ld( 15, &incL[0] ); - vecIncl3 = vec_ld( 31, &incL[0] ); - vecIncl4 = vec_ld( 47, &incL[0] ); - - vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); - vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); - vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); - - vecSL1 = vec_ld( 0, &sL[0] ); - vecSL2 = vec_ld( 15, &sL[0] ); - vecSL3 = vec_ld( 31, &sL[0] ); - vecSL4 = vec_ld( 47, &sL[0] ); - - vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); - vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); - vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - - for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { - - //load mix buffer into vectors, assume aligned - vecMixBuffer1 = vec_ld( 0, &mixBuffer[i*6] ); - vecMixBuffer2 = vec_ld( 0, &mixBuffer[(i*6)+4] ); - vecMixBuffer3 = vec_ld( 0, &mixBuffer[(i*6)+8] ); - - //load samples into vector - vector float vecSamplesLd2 = vec_ld( 15, &samples[i*2] ); - vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); - vecSamplesLast = vecSamplesLd2; - - //permute to get them ordered how we want. For the 2nd vector, - //the order happens to be the same as the order we loaded them - //in, so there's no need to permute that one - vecSamples1 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm1 ); - vecSamples2 = vecSamplesLd; - vecSamples3 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm3 ); - - //do calculation - vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); - - //store out results - ALIGNED_STORE3( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3 ); - - // add for next iteration - vecSL1 = vec_add( vecSL1, vecIncl1 ); - vecSL2 = vec_add( vecSL2, vecIncl2 ); - vecSL3 = vec_add( vecSL3, vecIncl3 ); - } -} -#else - -/* -============ -idSIMD_AltiVec::MixSoundSixSpeakerStereo - - Assumptions: - No assumptions -============ -*/ -void VPCALL idSIMD_AltiVec::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - - float incL[12]; - float sL[12]; - - int i; - vector float vecIncl1, vecIncl2, vecIncl3, vecIncl4; - vector float vecSL1, vecSL2, vecSL3, vecSL4; - vector float vecSamplesLd; - vector float vecSamples1, vecSamples2, vecSamples3; - vector float vecMixBuffer1, vecMixBuffer2, vecMixBuffer3; - // permute vectors for sample - vector unsigned char samplePerm1 = (vector unsigned char)( 0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3); - vector unsigned char samplePerm3 = (vector unsigned char)( 8,9,10,11,8,9,10,11,8,9,10,11,12,13,14,15); - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - // incL array, 6 elements repeated - incL[0] = incL[6] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL[1] = incL[7] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL[2] = incL[8] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL[3] = incL[9] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL[4] = incL[10] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL[5] = incL[11] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - // sL array repeated - sL[0] = lastV[0]; - sL[1] = lastV[1]; - sL[2] = lastV[2]; - sL[3] = lastV[3]; - sL[4] = lastV[4]; - sL[5] = lastV[5]; - sL[6] = lastV[0] + incL[0]; - sL[7] = lastV[1] + incL[1]; - sL[8] = lastV[2] + incL[2]; - sL[9] = lastV[3] + incL[3]; - sL[10] = lastV[4] + incL[4]; - sL[11] = lastV[5] + incL[5]; - - // multiply by 2 since doing 12 at a time - incL[0] *= 2; - incL[1] *= 2; - incL[2] *= 2; - incL[3] *= 2; - incL[4] *= 2; - incL[5] *= 2; - incL[6] *= 2; - incL[7] *= 2; - incL[8] *= 2; - incL[9] *= 2; - incL[10] *= 2; - incL[11] *= 2; - - // load the data - vector unsigned char incPerm = vec_add( vec_lvsl( -1, &incL[0] ), (vector unsigned char)(1) ); - vector unsigned char slPerm = vec_add( vec_lvsl( -1, &sL[0] ), (vector unsigned char)(1) ); - vecIncl1 = vec_ld( 0, &incL[0] ); - vecIncl2 = vec_ld( 15, &incL[0] ); - vecIncl3 = vec_ld( 31, &incL[0] ); - vecIncl4 = vec_ld( 47, &incL[0] ); - - vecIncl1 = vec_perm( vecIncl1, vecIncl2, incPerm ); - vecIncl2 = vec_perm( vecIncl2, vecIncl3, incPerm ); - vecIncl3 = vec_perm( vecIncl3, vecIncl4, incPerm ); - - vecSL1 = vec_ld( 0, &sL[0] ); - vecSL2 = vec_ld( 15, &sL[0] ); - vecSL3 = vec_ld( 31, &sL[0] ); - vecSL4 = vec_ld( 47, &sL[0] ); - - vecSL1 = vec_perm( vecSL1, vecSL2, slPerm ); - vecSL2 = vec_perm( vecSL2, vecSL3, slPerm ); - vecSL3 = vec_perm( vecSL3, vecSL4, slPerm ); - - vector unsigned char samplesPerm = vec_add( vec_lvsl( -1, &samples[0] ), (vector unsigned char)(1) ); - vector unsigned char mixBufferPerm = vec_add( vec_lvsl( -1, &mixBuffer[0] ), (vector unsigned char)(1) ); - vector float vecSamplesLast = vec_ld( 0, &samples[0] ); - vector float vecDest = vec_ld( 0, &mixBuffer[0] ); - - for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { - - //load mix buffer into vectors - vecMixBuffer1 = vecDest; - vecMixBuffer2 = vec_ld( 15, &mixBuffer[i*6] ); - vecMixBuffer3 = vec_ld( 31, &mixBuffer[i*6] ); - vector float vecDestEnd = vec_ld( 47, &mixBuffer[i*6] ); - - vecMixBuffer1 = vec_perm( vecMixBuffer1, vecMixBuffer2, mixBufferPerm ); - vecMixBuffer2 = vec_perm( vecMixBuffer2, vecMixBuffer3, mixBufferPerm ); - vecMixBuffer3 = vec_perm( vecMixBuffer3, vecDestEnd, mixBufferPerm ); - - //load samples into vector - vector float vecSamplesLd2 = vec_ld( 15, &samples[i*2] ); - vecSamplesLd = vec_perm( vecSamplesLast, vecSamplesLd2, samplesPerm ); - vecSamplesLast = vecSamplesLd2; - - //permute to get them ordered how we want. For the 2nd vector, - //the order happens to be the same as the order we loaded them - //in, so there's no need to permute that one - vecSamples1 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm1 ); - vecSamples2 = vecSamplesLd; - vecSamples3 = vec_perm( vecSamplesLd, vecSamplesLd, samplePerm3 ); - - //do calculation - vecMixBuffer1 = vec_madd( vecSamples1, vecSL1, vecMixBuffer1 ); - vecMixBuffer2 = vec_madd( vecSamples2, vecSL2, vecMixBuffer2 ); - vecMixBuffer3 = vec_madd( vecSamples3, vecSL3, vecMixBuffer3 ); - - // store results - UNALIGNED_STORE3( &mixBuffer[i*6], vecMixBuffer1, vecMixBuffer2, vecMixBuffer3 ); - - // add for next iteration - vecSL1 = vec_add( vecSL1, vecIncl1 ); - vecSL2 = vec_add( vecSL2, vecIncl2 ); - vecSL3 = vec_add( vecSL3, vecIncl3 ); - } -} - -#endif - -/* -============ -idSIMD_AltiVec::MixedSoundToSamples -============ -*/ -void VPCALL idSIMD_AltiVec::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { - //this is basically a clamp for sound mixing - register vector float v0, v1, v2, v3, v4, v5, v6, v7; - register vector signed int vi0, vi1, vi2, vi3; - register vector signed short vs0, vs1; - register vector float minVec, maxVec, constVec; - int i = 0; - - //unaligned at start, since samples is not 16-byte aligned - for ( ; NOT_16BYTE_ALIGNED( samples[i] ) && ( i < numSamples ); i++ ) { - samples[i] = mixBuffer[i] <= -32768.0f ? -32768 : mixBuffer[i] >= 32767.0f ? 32767 : (short) mixBuffer[i]; - } - - constVec = (vector float)(65536.0f); - - //splat min/max into a vector - minVec = (vector float)(-32768.0f); - maxVec = (vector float)(32767.0f); - - vector float vecOld = vec_ld( 0, &mixBuffer[i] ); - vector unsigned char permVec = vec_add( vec_lvsl( -1, &mixBuffer[i] ), (vector unsigned char)(1) ); - - //vectorize! - for ( ; i+15 < numSamples; i += 16 ) { - //load source - v0 = vecOld; - v1 = vec_ld( 15, &mixBuffer[i] ); - v2 = vec_ld( 31, &mixBuffer[i] ); - v3 = vec_ld( 31, &mixBuffer[i] ); - vecOld = vec_ld( 47, &mixBuffer[i] ); - - v0 = vec_perm( v0, v1, permVec ); - v1 = vec_perm( v1, v2, permVec ); - v2 = vec_perm( v2, v3, permVec ); - v3 = vec_perm( v3, vecOld, permVec ); - - //apply minimum - v4 = vec_max( v0, minVec ); - v5 = vec_max( v1, minVec ); - v6 = vec_max( v2, minVec ); - v7 = vec_max( v3, minVec ); - - //apply maximum - v4 = vec_min( v4, maxVec ); - v5 = vec_min( v5, maxVec ); - v6 = vec_min( v6, maxVec ); - v7 = vec_min( v7, maxVec ); - - // convert floats to ints - vi0 = vec_cts( v4, 0 ); - vi1 = vec_cts( v5, 0 ); - vi2 = vec_cts( v6, 0 ); - vi3 = vec_cts( v7, 0 ); - - // pack ints into shorts - vs0 = vec_pack( vi0, vi1 ); - vs1 = vec_pack( vi2, vi3 ); - ALIGNED_STORE2( &samples[i], vs0, vs1 ); - } - - //handle cleanup - for ( ; i < numSamples ; i++ ) { - samples[i] = mixBuffer[i] <= -32768.0f ? -32768 : mixBuffer[i] >= 32767.0f ? 32767 : (short) mixBuffer[i]; - } -} -#endif /* ENABLE_SOUND_ROUTINES */ - -#endif /* MACOS_X */ diff --git a/idlib/math/simd_altivec.h b/idlib/math/simd_altivec.h deleted file mode 100644 index 8a1c77473..000000000 --- a/idlib/math/simd_altivec.h +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_ALTIVEC_H__ -#define __MATH_SIMD_ALTIVEC_H__ - -/* -=============================================================================== - - AltiVec implementation of idSIMDProcessor - -=============================================================================== -*/ - -// Defines for enabling parts of the library - -// Turns on/off the simple math routines (add, sub, div, etc) -#define ENABLE_SIMPLE_MATH - -// Turns on/off the dot routines -#define ENABLE_DOT - -// Turns on/off the compare routines -#define ENABLE_COMPARES - -// The MinMax routines introduce a couple of bugs. In the bathroom of the alphalabs2 map, the -// wrong surface appears in the mirror at times. It also introduces a noticable delay when map -// data is loaded such as going through doors. -// Turns on/off MinMax routines -//#define ENABLE_MINMAX - -// Turns on/off Clamp routines -#define ENABLE_CLAMP - -// Turns on/off XXX16 routines -#define ENABLE_16ROUTINES - -// Turns on/off LowerTriangularSolve, LowerTriangularSolveTranspose, and MatX_LDLTFactor -#define ENABLE_LOWER_TRIANGULAR - -// Turns on/off TracePointCull, DecalPointCull, and OverlayPoint -// The Enable_Cull routines breaks the g_decals functionality, DecalPointCull is -// the likely suspect. Bullet holes do not appear on the walls when this optimization -// is enabled. -//#define ENABLE_CULL - -// Turns on/off DeriveTriPlanes, DeriveTangents, DeriveUnsmoothedTangents, NormalizeTangents -#define ENABLE_DERIVE - -// Turns on/off CreateTextureSpaceLightVectors, CreateShadowCache, CreateVertexProgramShadowCache -#define ENABLE_CREATE - -// Turns on/off the sound routines -#define ENABLE_SOUND_ROUTINES - -// Turns on/off the stuff that isn't on elsewhere -// Currently: BlendJoints, TransformJoints, UntransformJoints, ConvertJointQuatsToJointMats, and -// ConvertJointMatsToJointQuats -#define LIVE_VICARIOUSLY - -// This assumes that the dest (and mixBuffer) array to the sound functions is aligned. If this is not true, we take a large -// performance hit from having to do unaligned stores -//#define SOUND_DEST_ALIGNED - -// This assumes that the vertexCache array to CreateShadowCache and CreateVertexProgramShadowCache is aligned. If it's not, -// then we take a big performance hit from unaligned stores. -//#define VERTEXCACHE_ALIGNED - -// This turns on support for PPC intrinsics in the SIMD_AltiVec.cpp file. Right now it's only used for frsqrte. GCC -// supports these intrinsics but XLC does not. -#define PPC_INTRINSICS - -// This assumes that the idDrawVert array that is used in DeriveUnsmoothedTangents is aligned. If its not aligned, -// then we don't get any speedup -//#define DERIVE_UNSMOOTH_DRAWVERT_ALIGNED - -// Disable DRAWVERT_PADDED since we disabled the ENABLE_CULL optimizations and the default -// implementation does not allow for the extra padding. -// This assumes that idDrawVert has been padded by 4 bytes so that xyz always starts at an aligned -// address -//#define DRAWVERT_PADDED - -class idSIMD_AltiVec : public idSIMD_Generic { -#if defined(MACOS_X) && defined(__ppc__) -public: - - virtual const char * VPCALL GetName( void ) const; - -#ifdef ENABLE_SIMPLE_MATH - // Basic math, works for both aligned and unaligned data - virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count); - virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Div( float *dst, const float constant, const float *divisor, const int count ); - virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); -#endif - -#ifdef ENABLE_DOT - // Dot products, expects data structures in contiguous memory - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); - virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); -#endif - -#ifdef ENABLE_COMPARES - // Comparisons, works for both aligned and unaligned data - virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); -#endif - -#ifdef ENABLE_MINMAX - // Min/Max. Expects data structures in contiguous memory - virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); - virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); -#endif - -#ifdef ENABLE_CLAMP - // Clamp operations. Works for both aligned and unaligned data - virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); - virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); - virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); -#endif - - // These are already using memcpy and memset functions. Leaving default implementation -// virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); -// virtual void VPCALL Memset( void *dst, const int val, const int count ); - -#ifdef ENABLE_16ROUTINES - // Operations that expect 16-byte aligned data and 16-byte padded memory (with zeros), generally faster - virtual void VPCALL Zero16( float *dst, const int count ); - virtual void VPCALL Negate16( float *dst, const int count ); - virtual void VPCALL Copy16( float *dst, const float *src, const int count ); - virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); - virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); -#endif - -// Most of these deal with tiny matrices or vectors, generally not worth altivec'ing since -// the scalar code is already really fast - -// virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); -// virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); -// virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); - -#ifdef ENABLE_LOWER_TRIANGULAR - virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); - virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); - virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); -#endif -#ifdef LIVE_VICARIOUSLY - virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); - virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); - virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); -#endif - -#ifdef LIVE_VICARIOUSLY - virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); -#endif - -#ifdef ENABLE_CULL - virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); -#endif - -#ifdef ENABLE_DERIVE - virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); - virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); -#endif - -#ifdef ENABLE_CREATE - virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); - virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); -#endif - -#ifdef ENABLE_SOUND_ROUTINES - // Sound upsampling and mixing routines, works for aligned and unaligned data - virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); -#endif -#endif - -}; - -#endif /* !__MATH_SIMD_ALTIVEC_H__ */ diff --git a/idlib/math/simd_generic.cpp b/idlib/math/simd_generic.cpp deleted file mode 100644 index 9ad85e833..000000000 --- a/idlib/math/simd_generic.cpp +++ /dev/null @@ -1,3049 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); -#pragma warning( push ) -#pragma warning( disable: 4127 ) -#include "simd_generic.h" - - -//=============================================================== -// -// Generic implementation of idSIMDProcessor -// -//=============================================================== - -#define UNROLL1(Y) { int _IX; for (_IX=0;_IX constant; -============ -*/ -void VPCALL idSIMD_Generic::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] = src0[(X)] > constant; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpGT - - dst[i] |= ( src0[i] > constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_Generic::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] |= ( src0[(X)] > constant ) << bitNum; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpGE - - dst[i] = src0[i] >= constant; -============ -*/ -void VPCALL idSIMD_Generic::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] = src0[(X)] >= constant; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpGE - - dst[i] |= ( src0[i] >= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_Generic::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] |= ( src0[(X)] >= constant ) << bitNum; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpLT - - dst[i] = src0[i] < constant; -============ -*/ -void VPCALL idSIMD_Generic::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] = src0[(X)] < constant; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpLT - - dst[i] |= ( src0[i] < constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_Generic::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] |= ( src0[(X)] < constant ) << bitNum; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpLE - - dst[i] = src0[i] <= constant; -============ -*/ -void VPCALL idSIMD_Generic::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] = src0[(X)] <= constant; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::CmpLE - - dst[i] |= ( src0[i] <= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_Generic::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { -#define OPER(X) dst[(X)] |= ( src0[(X)] <= constant ) << bitNum; - UNROLL4(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MinMax -============ -*/ -void VPCALL idSIMD_Generic::MinMax( float &min, float &max, const float *src, const int count ) { - min = idMath::INFINITY; max = -idMath::INFINITY; -#define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];} - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MinMax -============ -*/ -void VPCALL idSIMD_Generic::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { - min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY; -#define OPER(X) const idVec2 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MinMax -============ -*/ -void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; -#define OPER(X) const idVec3 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MinMax -============ -*/ -void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; -#define OPER(X) const idVec3 &v = src[(X)].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MinMax -============ -*/ -void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { - min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; -#define OPER(X) const idVec3 &v = src[indexes[(X)]].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; } - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::Clamp -============ -*/ -void VPCALL idSIMD_Generic::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { -#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)] > max ? max : src[(X)]; - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::ClampMin -============ -*/ -void VPCALL idSIMD_Generic::ClampMin( float *dst, const float *src, const float min, const int count ) { -#define OPER(X) dst[(X)] = src[(X)] < min ? min : src[(X)]; - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::ClampMax -============ -*/ -void VPCALL idSIMD_Generic::ClampMax( float *dst, const float *src, const float max, const int count ) { -#define OPER(X) dst[(X)] = src[(X)] > max ? max : src[(X)]; - UNROLL1(OPER) -#undef OPER -} - -/* -================ -idSIMD_Generic::Memcpy -================ -*/ -void VPCALL idSIMD_Generic::Memcpy( void *dst, const void *src, const int count ) { - memcpy( dst, src, count ); -} - -/* -================ -idSIMD_Generic::Memset -================ -*/ -void VPCALL idSIMD_Generic::Memset( void *dst, const int val, const int count ) { - memset( dst, val, count ); -} - -/* -============ -idSIMD_Generic::Zero16 -============ -*/ -void VPCALL idSIMD_Generic::Zero16( float *dst, const int count ) { - memset( dst, 0, count * sizeof( float ) ); -} - -/* -============ -idSIMD_Generic::Negate16 -============ -*/ -void VPCALL idSIMD_Generic::Negate16( float *dst, const int count ) { - unsigned int *ptr = reinterpret_cast(dst); -#define OPER(X) ptr[(X)] ^= ( 1 << 31 ) // IEEE 32 bits float sign bit - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::Copy16 -============ -*/ -void VPCALL idSIMD_Generic::Copy16( float *dst, const float *src, const int count ) { -#define OPER(X) dst[(X)] = src[(X)] - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::Add16 -============ -*/ -void VPCALL idSIMD_Generic::Add16( float *dst, const float *src1, const float *src2, const int count ) { -#define OPER(X) dst[(X)] = src1[(X)] + src2[(X)] - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::Sub16 -============ -*/ -void VPCALL idSIMD_Generic::Sub16( float *dst, const float *src1, const float *src2, const int count ) { -#define OPER(X) dst[(X)] = src1[(X)] - src2[(X)] - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::Mul16 -============ -*/ -void VPCALL idSIMD_Generic::Mul16( float *dst, const float *src1, const float constant, const int count ) { -#define OPER(X) dst[(X)] = src1[(X)] * constant - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::AddAssign16 -============ -*/ -void VPCALL idSIMD_Generic::AddAssign16( float *dst, const float *src, const int count ) { -#define OPER(X) dst[(X)] += src[(X)] - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::SubAssign16 -============ -*/ -void VPCALL idSIMD_Generic::SubAssign16( float *dst, const float *src, const int count ) { -#define OPER(X) dst[(X)] -= src[(X)] - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MulAssign16 -============ -*/ -void VPCALL idSIMD_Generic::MulAssign16( float *dst, const float constant, const int count ) { -#define OPER(X) dst[(X)] *= constant - UNROLL1(OPER) -#undef OPER -} - -/* -============ -idSIMD_Generic::MatX_MultiplyVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, j, numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - break; - case 3: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - break; - case 4: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3]; - mPtr += 4; - } - break; - case 5: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - break; - case 6: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] = mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - break; - default: - int numColumns = mat.GetNumColumns(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] = sum; - mPtr += numColumns; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_MultiplyAddVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, j, numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - break; - case 3: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - break; - case 4: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3]; - mPtr += 4; - } - break; - case 5: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - break; - case 6: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] += mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - break; - default: - int numColumns = mat.GetNumColumns(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] += sum; - mPtr += numColumns; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_MultiplySubVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, j, numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - break; - case 3: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - break; - case 4: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3]; - mPtr += 4; - } - break; - case 5: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - break; - case 6: - for ( i = 0; i < numRows; i++ ) { - dstPtr[i] -= mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - break; - default: - int numColumns = mat.GetNumColumns(); - for ( i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] -= sum; - mPtr += numColumns; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_TransposeMultiplyVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, j, numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - break; - case 3: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - break; - case 4: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - break; - case 5: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - break; - case 6: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] = *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - break; - default: - int numRows = mat.GetNumRows(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] = sum; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_TransposeMultiplyAddVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, j, numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - break; - case 3: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - break; - case 4: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - break; - case 5: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - break; - case 6: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] += *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - break; - default: - int numRows = mat.GetNumRows(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] += sum; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_TransposeMultiplySubVecX -============ -*/ -void VPCALL idSIMD_Generic::MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { - int i, numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0]; - mPtr++; - } - break; - case 2: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - break; - case 3: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - break; - case 4: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - break; - case 5: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - break; - case 6: - for ( i = 0; i < numColumns; i++ ) { - dstPtr[i] -= *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - break; - default: - int numRows = mat.GetNumRows(); - for ( i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] -= sum; - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_MultiplyMatX - - optimizes the following matrix multiplications: - - NxN * Nx6 - 6xN * Nx6 - Nx6 * 6xN - 6x6 * 6xN - - with N in the range [1-6]. -============ -*/ -void VPCALL idSIMD_Generic::MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( m1.GetNumColumns() == m2.GetNumRows() ); - - dstPtr = dst.ToFloatPtr(); - m1Ptr = m1.ToFloatPtr(); - m2Ptr = m2.ToFloatPtr(); - k = m1.GetNumRows(); - l = m2.GetNumColumns(); - - switch( m1.GetNumColumns() ) { - case 1: { - if ( l == 6 ) { - for ( i = 0; i < k; i++ ) { // Nx1 * 1x6 - *dstPtr++ = m1Ptr[i] * m2Ptr[0]; - *dstPtr++ = m1Ptr[i] * m2Ptr[1]; - *dstPtr++ = m1Ptr[i] * m2Ptr[2]; - *dstPtr++ = m1Ptr[i] * m2Ptr[3]; - *dstPtr++ = m1Ptr[i] * m2Ptr[4]; - *dstPtr++ = m1Ptr[i] * m2Ptr[5]; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0]; - m2Ptr++; - } - m1Ptr++; - } - break; - } - case 2: { - if ( l == 6 ) { - for ( i = 0; i < k; i++ ) { // Nx2 * 2x6 - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6]; - *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7]; - *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8]; - *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9]; - *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10]; - *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11]; - m1Ptr += 2; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l]; - m2Ptr++; - } - m1Ptr += 2; - } - break; - } - case 3: { - if ( l == 6 ) { - for ( i = 0; i < k; i++ ) { // Nx3 * 3x6 - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12]; - *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13]; - *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14]; - *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15]; - *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16]; - *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17]; - m1Ptr += 3; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l]; - m2Ptr++; - } - m1Ptr += 3; - } - break; - } - case 4: { - if ( l == 6 ) { - for ( i = 0; i < k; i++ ) { // Nx4 * 4x6 - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12] + m1Ptr[3] * m2Ptr[18]; - *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13] + m1Ptr[3] * m2Ptr[19]; - *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14] + m1Ptr[3] * m2Ptr[20]; - *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15] + m1Ptr[3] * m2Ptr[21]; - *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16] + m1Ptr[3] * m2Ptr[22]; - *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17] + m1Ptr[3] * m2Ptr[23]; - m1Ptr += 4; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l]; - m2Ptr++; - } - m1Ptr += 4; - } - break; - } - case 5: { - if ( l == 6 ) { - for ( i = 0; i < k; i++ ) { // Nx5 * 5x6 - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[6] + m1Ptr[2] * m2Ptr[12] + m1Ptr[3] * m2Ptr[18] + m1Ptr[4] * m2Ptr[24]; - *dstPtr++ = m1Ptr[0] * m2Ptr[1] + m1Ptr[1] * m2Ptr[7] + m1Ptr[2] * m2Ptr[13] + m1Ptr[3] * m2Ptr[19] + m1Ptr[4] * m2Ptr[25]; - *dstPtr++ = m1Ptr[0] * m2Ptr[2] + m1Ptr[1] * m2Ptr[8] + m1Ptr[2] * m2Ptr[14] + m1Ptr[3] * m2Ptr[20] + m1Ptr[4] * m2Ptr[26]; - *dstPtr++ = m1Ptr[0] * m2Ptr[3] + m1Ptr[1] * m2Ptr[9] + m1Ptr[2] * m2Ptr[15] + m1Ptr[3] * m2Ptr[21] + m1Ptr[4] * m2Ptr[27]; - *dstPtr++ = m1Ptr[0] * m2Ptr[4] + m1Ptr[1] * m2Ptr[10] + m1Ptr[2] * m2Ptr[16] + m1Ptr[3] * m2Ptr[22] + m1Ptr[4] * m2Ptr[28]; - *dstPtr++ = m1Ptr[0] * m2Ptr[5] + m1Ptr[1] * m2Ptr[11] + m1Ptr[2] * m2Ptr[17] + m1Ptr[3] * m2Ptr[23] + m1Ptr[4] * m2Ptr[29]; - m1Ptr += 5; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l]; - m2Ptr++; - } - m1Ptr += 5; - } - break; - } - case 6: { - switch( k ) { - case 1: { - if ( l == 1 ) { // 1x6 * 6x1 - dstPtr[0] = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[1] + m1Ptr[2] * m2Ptr[2] + - m1Ptr[3] * m2Ptr[3] + m1Ptr[4] * m2Ptr[4] + m1Ptr[5] * m2Ptr[5]; - return; - } - break; - } - case 2: { - if ( l == 2 ) { // 2x6 * 6x2 - for ( i = 0; i < 2; i++ ) { - for ( j = 0; j < 2; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 2 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 2 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 2 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 2 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 2 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 2 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - break; - } - case 3: { - if ( l == 3 ) { // 3x6 * 6x3 - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 3 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 3 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 3 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 3 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - break; - } - case 4: { - if ( l == 4 ) { // 4x6 * 6x4 - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 4 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 4 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 4 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - } - case 5: { - if ( l == 5 ) { // 5x6 * 6x5 - for ( i = 0; i < 5; i++ ) { - for ( j = 0; j < 5; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 5 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 5 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - } - case 6: { - switch( l ) { - case 1: { // 6x6 * 6x1 - for ( i = 0; i < 6; i++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 1 ] - + m1Ptr[1] * m2Ptr[ 1 * 1 ] - + m1Ptr[2] * m2Ptr[ 2 * 1 ] - + m1Ptr[3] * m2Ptr[ 3 * 1 ] - + m1Ptr[4] * m2Ptr[ 4 * 1 ] - + m1Ptr[5] * m2Ptr[ 5 * 1 ]; - dstPtr++; - m1Ptr += 6; - } - return; - } - case 2: { // 6x6 * 6x2 - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 2; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 2 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 2 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 2 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 2 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 2 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 2 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - case 3: { // 6x6 * 6x3 - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 3; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 3 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 3 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 3 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 3 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 3 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - case 4: { // 6x6 * 6x4 - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 4; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 4 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 4 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 4 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 4 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 4 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - case 5: { // 6x6 * 6x5 - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 5; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 5 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 5 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 5 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 5 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 5 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - case 6: { // 6x6 * 6x6 - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 6; j++ ) { - *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 6 + j ] - + m1Ptr[1] * m2Ptr[ 1 * 6 + j ] - + m1Ptr[2] * m2Ptr[ 2 * 6 + j ] - + m1Ptr[3] * m2Ptr[ 3 * 6 + j ] - + m1Ptr[4] * m2Ptr[ 4 * 6 + j ] - + m1Ptr[5] * m2Ptr[ 5 * 6 + j ]; - dstPtr++; - } - m1Ptr += 6; - } - return; - } - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l] + m1Ptr[5] * m2Ptr[5*l]; - m2Ptr++; - } - m1Ptr += 6; - } - break; - } - default: { - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m2Ptr = m2.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < m1.GetNumColumns(); n++ ) { - m2Ptr += l; - sum += m1Ptr[n] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - m1Ptr += m1.GetNumColumns(); - } - break; - } - } -} - -/* -============ -idSIMD_Generic::MatX_TransposeMultiplyMatX - - optimizes the following tranpose matrix multiplications: - - Nx6 * NxN - 6xN * 6x6 - - with N in the range [1-6]. -============ -*/ -void VPCALL idSIMD_Generic::MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( m1.GetNumRows() == m2.GetNumRows() ); - - m1Ptr = m1.ToFloatPtr(); - m2Ptr = m2.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - k = m1.GetNumColumns(); - l = m2.GetNumColumns(); - - switch( m1.GetNumRows() ) { - case 1: - if ( k == 6 && l == 1 ) { // 1x6 * 1x1 - for ( i = 0; i < 6; i++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0]; - m1Ptr++; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 2: - if ( k == 6 && l == 2 ) { // 2x6 * 2x2 - for ( i = 0; i < 6; i++ ) { - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*2+0] + m1Ptr[1*6] * m2Ptr[1*2+0]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*2+1] + m1Ptr[1*6] * m2Ptr[1*2+1]; - m1Ptr++; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 3: - if ( k == 6 && l == 3 ) { // 3x6 * 3x3 - for ( i = 0; i < 6; i++ ) { - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+0] + m1Ptr[1*6] * m2Ptr[1*3+0] + m1Ptr[2*6] * m2Ptr[2*3+0]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+1] + m1Ptr[1*6] * m2Ptr[1*3+1] + m1Ptr[2*6] * m2Ptr[2*3+1]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*3+2] + m1Ptr[1*6] * m2Ptr[1*3+2] + m1Ptr[2*6] * m2Ptr[2*3+2]; - m1Ptr++; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 4: - if ( k == 6 && l == 4 ) { // 4x6 * 4x4 - for ( i = 0; i < 6; i++ ) { - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+0] + m1Ptr[1*6] * m2Ptr[1*4+0] + m1Ptr[2*6] * m2Ptr[2*4+0] + m1Ptr[3*6] * m2Ptr[3*4+0]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+1] + m1Ptr[1*6] * m2Ptr[1*4+1] + m1Ptr[2*6] * m2Ptr[2*4+1] + m1Ptr[3*6] * m2Ptr[3*4+1]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+2] + m1Ptr[1*6] * m2Ptr[1*4+2] + m1Ptr[2*6] * m2Ptr[2*4+2] + m1Ptr[3*6] * m2Ptr[3*4+2]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*4+3] + m1Ptr[1*6] * m2Ptr[1*4+3] + m1Ptr[2*6] * m2Ptr[2*4+3] + m1Ptr[3*6] * m2Ptr[3*4+3]; - m1Ptr++; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 5: - if ( k == 6 && l == 5 ) { // 5x6 * 5x5 - for ( i = 0; i < 6; i++ ) { - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+0] + m1Ptr[1*6] * m2Ptr[1*5+0] + m1Ptr[2*6] * m2Ptr[2*5+0] + m1Ptr[3*6] * m2Ptr[3*5+0] + m1Ptr[4*6] * m2Ptr[4*5+0]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+1] + m1Ptr[1*6] * m2Ptr[1*5+1] + m1Ptr[2*6] * m2Ptr[2*5+1] + m1Ptr[3*6] * m2Ptr[3*5+1] + m1Ptr[4*6] * m2Ptr[4*5+1]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+2] + m1Ptr[1*6] * m2Ptr[1*5+2] + m1Ptr[2*6] * m2Ptr[2*5+2] + m1Ptr[3*6] * m2Ptr[3*5+2] + m1Ptr[4*6] * m2Ptr[4*5+2]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+3] + m1Ptr[1*6] * m2Ptr[1*5+3] + m1Ptr[2*6] * m2Ptr[2*5+3] + m1Ptr[3*6] * m2Ptr[3*5+3] + m1Ptr[4*6] * m2Ptr[4*5+3]; - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*5+4] + m1Ptr[1*6] * m2Ptr[1*5+4] + m1Ptr[2*6] * m2Ptr[2*5+4] + m1Ptr[3*6] * m2Ptr[3*5+4] + m1Ptr[4*6] * m2Ptr[4*5+4]; - m1Ptr++; - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 6: - if ( l == 6 ) { - switch( k ) { - case 1: // 6x1 * 6x6 - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*1] * m2Ptr[0*6] + - m1Ptr[1*1] * m2Ptr[1*6] + - m1Ptr[2*1] * m2Ptr[2*6] + - m1Ptr[3*1] * m2Ptr[3*6] + - m1Ptr[4*1] * m2Ptr[4*6] + - m1Ptr[5*1] * m2Ptr[5*6]; - m2Ptr++; - } - return; - case 2: // 6x2 * 6x6 - for ( i = 0; i < 2; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*2] * m2Ptr[0*6] + - m1Ptr[1*2] * m2Ptr[1*6] + - m1Ptr[2*2] * m2Ptr[2*6] + - m1Ptr[3*2] * m2Ptr[3*6] + - m1Ptr[4*2] * m2Ptr[4*6] + - m1Ptr[5*2] * m2Ptr[5*6]; - m2Ptr++; - } - m1Ptr++; - } - return; - case 3: // 6x3 * 6x6 - for ( i = 0; i < 3; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*3] * m2Ptr[0*6] + - m1Ptr[1*3] * m2Ptr[1*6] + - m1Ptr[2*3] * m2Ptr[2*6] + - m1Ptr[3*3] * m2Ptr[3*6] + - m1Ptr[4*3] * m2Ptr[4*6] + - m1Ptr[5*3] * m2Ptr[5*6]; - m2Ptr++; - } - m1Ptr++; - } - return; - case 4: // 6x4 * 6x6 - for ( i = 0; i < 4; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*4] * m2Ptr[0*6] + - m1Ptr[1*4] * m2Ptr[1*6] + - m1Ptr[2*4] * m2Ptr[2*6] + - m1Ptr[3*4] * m2Ptr[3*6] + - m1Ptr[4*4] * m2Ptr[4*6] + - m1Ptr[5*4] * m2Ptr[5*6]; - m2Ptr++; - } - m1Ptr++; - } - return; - case 5: // 6x5 * 6x6 - for ( i = 0; i < 5; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*5] * m2Ptr[0*6] + - m1Ptr[1*5] * m2Ptr[1*6] + - m1Ptr[2*5] * m2Ptr[2*6] + - m1Ptr[3*5] * m2Ptr[3*6] + - m1Ptr[4*5] * m2Ptr[4*6] + - m1Ptr[5*5] * m2Ptr[5*6]; - m2Ptr++; - } - m1Ptr++; - } - return; - case 6: // 6x6 * 6x6 - for ( i = 0; i < 6; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < 6; j++ ) { - *dstPtr++ = m1Ptr[0*6] * m2Ptr[0*6] + - m1Ptr[1*6] * m2Ptr[1*6] + - m1Ptr[2*6] * m2Ptr[2*6] + - m1Ptr[3*6] * m2Ptr[3*6] + - m1Ptr[4*6] * m2Ptr[4*6] + - m1Ptr[5*6] * m2Ptr[5*6]; - m2Ptr++; - } - m1Ptr++; - } - return; - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l] + m1Ptr[5*k] * m2Ptr[5*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - default: - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m1Ptr = m1.ToFloatPtr() + i; - m2Ptr = m2.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < m1.GetNumRows(); n++ ) { - m1Ptr += k; - m2Ptr += l; - sum += m1Ptr[0] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - } - break; - } -} - -/* -============ -idSIMD_Generic::MatX_LowerTriangularSolve - - solves x in Lx = b for the n * n sub-matrix of L - if skip > 0 the first skip elements of x are assumed to be valid already - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_Generic::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { -#if 1 - - int nc; - const float *lptr; - - if ( skip >= n ) { - return; - } - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - #define NSKIP( n, s ) ((n<<3)|(s&7)) - switch( NSKIP( n, skip ) ) { - case NSKIP( 1, 0 ): x[0] = b[0]; - return; - case NSKIP( 2, 0 ): x[0] = b[0]; - case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - return; - case NSKIP( 3, 0 ): x[0] = b[0]; - case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - return; - case NSKIP( 4, 0 ): x[0] = b[0]; - case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - return; - case NSKIP( 5, 0 ): x[0] = b[0]; - case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - return; - case NSKIP( 6, 0 ): x[0] = b[0]; - case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - return; - case NSKIP( 7, 0 ): x[0] = b[0]; - case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; - return; - } - return; - } - - // process first 4 rows - switch( skip ) { - case 0: x[0] = b[0]; - case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; - case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - skip = 4; - } - - lptr = L[skip]; - - int i, j; - register double s0, s1, s2, s3; - - for ( i = skip; i < n; i++ ) { - s0 = lptr[0] * x[0]; - s1 = lptr[1] * x[1]; - s2 = lptr[2] * x[2]; - s3 = lptr[3] * x[3]; - for ( j = 4; j < i-7; j += 8 ) { - s0 += lptr[j+0] * x[j+0]; - s1 += lptr[j+1] * x[j+1]; - s2 += lptr[j+2] * x[j+2]; - s3 += lptr[j+3] * x[j+3]; - s0 += lptr[j+4] * x[j+4]; - s1 += lptr[j+5] * x[j+5]; - s2 += lptr[j+6] * x[j+6]; - s3 += lptr[j+7] * x[j+7]; - } - switch( i - j ) { - NODEFAULT; - case 7: s0 += lptr[j+6] * x[j+6]; - case 6: s1 += lptr[j+5] * x[j+5]; - case 5: s2 += lptr[j+4] * x[j+4]; - case 4: s3 += lptr[j+3] * x[j+3]; - case 3: s0 += lptr[j+2] * x[j+2]; - case 2: s1 += lptr[j+1] * x[j+1]; - case 1: s2 += lptr[j+0] * x[j+0]; - case 0: break; - } - double sum; - sum = s3; - sum += s2; - sum += s1; - sum += s0; - sum -= b[i]; - x[i] = -sum; - lptr += nc; - } - -#else - - int i, j; - const float *lptr; - double sum; - - for ( i = skip; i < n; i++ ) { - sum = b[i]; - lptr = L[i]; - for ( j = 0; j < i; j++ ) { - sum -= lptr[j] * x[j]; - } - x[i] = sum; - } - -#endif -} - -/* -============ -idSIMD_Generic::MatX_LowerTriangularSolveTranspose - - solves x in L'x = b for the n * n sub-matrix of L - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_Generic::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { -#if 1 - - int nc; - const float *lptr; - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - switch( n ) { - case 0: - return; - case 1: - x[0] = b[0]; - return; - case 2: - x[1] = b[1]; - x[0] = b[0] - lptr[1*nc+0] * x[1]; - return; - case 3: - x[2] = b[2]; - x[1] = b[1] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 4: - x[3] = b[3]; - x[2] = b[2] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 5: - x[4] = b[4]; - x[3] = b[3] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 6: - x[5] = b[5]; - x[4] = b[4] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 7: - x[6] = b[6]; - x[5] = b[5] - lptr[6*nc+5] * x[6]; - x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - } - return; - } - - int i, j; - register double s0, s1, s2, s3; - float *xptr; - - lptr = L.ToFloatPtr() + n * nc + n - 4; - xptr = x + n; - - // process 4 rows at a time - for ( i = n; i >= 4; i -= 4 ) { - s0 = b[i-4]; - s1 = b[i-3]; - s2 = b[i-2]; - s3 = b[i-1]; - // process 4x4 blocks - for ( j = 0; j < n-i; j += 4 ) { - s0 -= lptr[(j+0)*nc+0] * xptr[j+0]; - s1 -= lptr[(j+0)*nc+1] * xptr[j+0]; - s2 -= lptr[(j+0)*nc+2] * xptr[j+0]; - s3 -= lptr[(j+0)*nc+3] * xptr[j+0]; - s0 -= lptr[(j+1)*nc+0] * xptr[j+1]; - s1 -= lptr[(j+1)*nc+1] * xptr[j+1]; - s2 -= lptr[(j+1)*nc+2] * xptr[j+1]; - s3 -= lptr[(j+1)*nc+3] * xptr[j+1]; - s0 -= lptr[(j+2)*nc+0] * xptr[j+2]; - s1 -= lptr[(j+2)*nc+1] * xptr[j+2]; - s2 -= lptr[(j+2)*nc+2] * xptr[j+2]; - s3 -= lptr[(j+2)*nc+3] * xptr[j+2]; - s0 -= lptr[(j+3)*nc+0] * xptr[j+3]; - s1 -= lptr[(j+3)*nc+1] * xptr[j+3]; - s2 -= lptr[(j+3)*nc+2] * xptr[j+3]; - s3 -= lptr[(j+3)*nc+3] * xptr[j+3]; - } - // process left over of the 4 rows - s0 -= lptr[0-1*nc] * s3; - s1 -= lptr[1-1*nc] * s3; - s2 -= lptr[2-1*nc] * s3; - s0 -= lptr[0-2*nc] * s2; - s1 -= lptr[1-2*nc] * s2; - s0 -= lptr[0-3*nc] * s1; - // store result - xptr[-4] = s0; - xptr[-3] = s1; - xptr[-2] = s2; - xptr[-1] = s3; - // update pointers for next four rows - lptr -= 4 + 4 * nc; - xptr -= 4; - } - // process left over rows - for ( i--; i >= 0; i-- ) { - s0 = b[i]; - lptr = L[0] + i; - for ( j = i + 1; j < n; j++ ) { - s0 -= lptr[j*nc] * x[j]; - } - x[i] = s0; - } - -#else - - int i, j, nc; - const float *ptr; - double sum; - - nc = L.GetNumColumns(); - for ( i = n - 1; i >= 0; i-- ) { - sum = b[i]; - ptr = L[0] + i; - for ( j = i + 1; j < n; j++ ) { - sum -= ptr[j*nc] * x[j]; - } - x[i] = sum; - } - -#endif -} - -/* -============ -idSIMD_Generic::MatX_LDLTFactor - - in-place factorization LDL' of the n * n sub-matrix of mat - the reciprocal of the diagonal elements are stored in invDiag -============ -*/ -bool VPCALL idSIMD_Generic::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { -#if 1 - - int i, j, k, nc; - float *v, *diag, *mptr; - double s0, s1, s2, s3, sum, d; - - v = (float *) _alloca16( n * sizeof( float ) ); - diag = (float *) _alloca16( n * sizeof( float ) ); - - nc = mat.GetNumColumns(); - - if ( n <= 0 ) { - return true; - } - - mptr = mat[0]; - - sum = mptr[0]; - - if ( sum == 0.0f ) { - return false; - } - - diag[0] = sum; - invDiag[0] = d = 1.0f / sum; - - if ( n <= 1 ) { - return true; - } - - mptr = mat[0]; - for ( j = 1; j < n; j++ ) { - mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; - } - - mptr = mat[1]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - sum = mptr[1] - s0; - - if ( sum == 0.0f ) { - return false; - } - - mat[1][1] = sum; - diag[1] = sum; - invDiag[1] = d = 1.0f / sum; - - if ( n <= 2 ) { - return true; - } - - mptr = mat[0]; - for ( j = 2; j < n; j++ ) { - mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; - } - - mptr = mat[2]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - sum = mptr[2] - s0 - s1; - - if ( sum == 0.0f ) { - return false; - } - - mat[2][2] = sum; - diag[2] = sum; - invDiag[2] = d = 1.0f / sum; - - if ( n <= 3 ) { - return true; - } - - mptr = mat[0]; - for ( j = 3; j < n; j++ ) { - mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; - } - - mptr = mat[3]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - sum = mptr[3] - s0 - s1 - s2; - - if ( sum == 0.0f ) { - return false; - } - - mat[3][3] = sum; - diag[3] = sum; - invDiag[3] = d = 1.0f / sum; - - if ( n <= 4 ) { - return true; - } - - mptr = mat[0]; - for ( j = 4; j < n; j++ ) { - mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; - } - - for ( i = 4; i < n; i++ ) { - - mptr = mat[i]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; - for ( k = 4; k < i-3; k += 4 ) { - v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; - v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; - v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; - } - switch( i - k ) { - NODEFAULT; - case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; - case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; - case 0: break; - } - sum = s3; - sum += s2; - sum += s1; - sum += s0; - sum = mptr[i] - sum; - - if ( sum == 0.0f ) { - return false; - } - - mat[i][i] = sum; - diag[i] = sum; - invDiag[i] = d = 1.0f / sum; - - if ( i + 1 >= n ) { - return true; - } - - mptr = mat[i+1]; - for ( j = i+1; j < n; j++ ) { - s0 = mptr[0] * v[0]; - s1 = mptr[1] * v[1]; - s2 = mptr[2] * v[2]; - s3 = mptr[3] * v[3]; - for ( k = 4; k < i-7; k += 8 ) { - s0 += mptr[k+0] * v[k+0]; - s1 += mptr[k+1] * v[k+1]; - s2 += mptr[k+2] * v[k+2]; - s3 += mptr[k+3] * v[k+3]; - s0 += mptr[k+4] * v[k+4]; - s1 += mptr[k+5] * v[k+5]; - s2 += mptr[k+6] * v[k+6]; - s3 += mptr[k+7] * v[k+7]; - } - switch( i - k ) { - NODEFAULT; - case 7: s0 += mptr[k+6] * v[k+6]; - case 6: s1 += mptr[k+5] * v[k+5]; - case 5: s2 += mptr[k+4] * v[k+4]; - case 4: s3 += mptr[k+3] * v[k+3]; - case 3: s0 += mptr[k+2] * v[k+2]; - case 2: s1 += mptr[k+1] * v[k+1]; - case 1: s2 += mptr[k+0] * v[k+0]; - case 0: break; - } - sum = s3; - sum += s2; - sum += s1; - sum += s0; - mptr[i] = ( mptr[i] - sum ) * d; - mptr += nc; - } - } - - return true; - -#else - - int i, j, k, nc; - float *v, *ptr, *diagPtr; - double d, sum; - - v = (float *) _alloca16( n * sizeof( float ) ); - nc = mat.GetNumColumns(); - - for ( i = 0; i < n; i++ ) { - - ptr = mat[i]; - diagPtr = mat[0]; - sum = ptr[i]; - for ( j = 0; j < i; j++ ) { - d = ptr[j]; - v[j] = diagPtr[0] * d; - sum -= v[j] * d; - diagPtr += nc + 1; - } - - if ( sum == 0.0f ) { - return false; - } - - diagPtr[0] = sum; - invDiag[i] = d = 1.0f / sum; - - if ( i + 1 >= n ) { - continue; - } - - ptr = mat[i+1]; - for ( j = i + 1; j < n; j++ ) { - sum = ptr[i]; - for ( k = 0; k < i; k++ ) { - sum -= ptr[k] * v[k]; - } - ptr[i] = sum * d; - ptr += nc; - } - } - - return true; - -#endif -} - -/* -============ -idSIMD_Generic::BlendJoints -============ -*/ -void VPCALL idSIMD_Generic::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { - int i; - - for ( i = 0; i < numJoints; i++ ) { - int j = index[i]; - joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp ); - joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); - } -} - -/* -============ -idSIMD_Generic::ConvertJointQuatsToJointMats -============ -*/ -void VPCALL idSIMD_Generic::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { - int i; - - for ( i = 0; i < numJoints; i++ ) { - jointMats[i].SetRotation( jointQuats[i].q.ToMat3() ); - jointMats[i].SetTranslation( jointQuats[i].t ); - } -} - -/* -============ -idSIMD_Generic::ConvertJointMatsToJointQuats -============ -*/ -void VPCALL idSIMD_Generic::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { - int i; - - for ( i = 0; i < numJoints; i++ ) { - jointQuats[i] = jointMats[i].ToJointQuat(); - } -} - -/* -============ -idSIMD_Generic::TransformJoints -============ -*/ -void VPCALL idSIMD_Generic::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { - int i; - - for( i = firstJoint; i <= lastJoint; i++ ) { - assert( parents[i] < i ); - jointMats[i] *= jointMats[parents[i]]; - } -} - -/* -============ -idSIMD_Generic::UntransformJoints -============ -*/ -void VPCALL idSIMD_Generic::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { - int i; - - for( i = lastJoint; i >= firstJoint; i-- ) { - assert( parents[i] < i ); - jointMats[i] /= jointMats[parents[i]]; - } -} - -/* -============ -idSIMD_Generic::TransformVerts -============ -*/ -void VPCALL idSIMD_Generic::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, int numWeights ) { - int i, j; - const byte *jointsPtr = (byte *)joints; - - for( j = i = 0; i < numVerts; i++ ) { - idVec3 v; - - v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - while( index[j*2+1] == 0 ) { - j++; - v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - } - j++; - - verts[i].xyz = v; - } -} - -/* -============ -idSIMD_Generic::TracePointCull -============ -*/ -void VPCALL idSIMD_Generic::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - int i; - byte tOr; - - tOr = 0; - - for ( i = 0; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, t; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - - t = d0 + radius; - bits = FLOATSIGNBITSET( t ) << 0; - t = d1 + radius; - bits |= FLOATSIGNBITSET( t ) << 1; - t = d2 + radius; - bits |= FLOATSIGNBITSET( t ) << 2; - t = d3 + radius; - bits |= FLOATSIGNBITSET( t ) << 3; - - t = d0 - radius; - bits |= FLOATSIGNBITSET( t ) << 4; - t = d1 - radius; - bits |= FLOATSIGNBITSET( t ) << 5; - t = d2 - radius; - bits |= FLOATSIGNBITSET( t ) << 6; - t = d3 - radius; - bits |= FLOATSIGNBITSET( t ) << 7; - - bits ^= 0x0F; // flip lower four bits - - tOr |= bits; - cullBits[i] = bits; - } - - totalOr = tOr; -} - -/* -============ -idSIMD_Generic::DecalPointCull -============ -*/ -void VPCALL idSIMD_Generic::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - int i; - - for ( i = 0; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, d4, d5; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0].Distance( v ); - d1 = planes[1].Distance( v ); - d2 = planes[2].Distance( v ); - d3 = planes[3].Distance( v ); - d4 = planes[4].Distance( v ); - d5 = planes[5].Distance( v ); - - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - bits |= FLOATSIGNBITSET( d2 ) << 2; - bits |= FLOATSIGNBITSET( d3 ) << 3; - bits |= FLOATSIGNBITSET( d4 ) << 4; - bits |= FLOATSIGNBITSET( d5 ) << 5; - - cullBits[i] = bits ^ 0x3F; // flip lower 6 bits - } -} - -/* -============ -idSIMD_Generic::OverlayPointCull -============ -*/ -void VPCALL idSIMD_Generic::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { - int i; - - for ( i = 0; i < numVerts; i++ ) { - byte bits; - float d0, d1; - const idVec3 &v = verts[i].xyz; - - texCoords[i][0] = d0 = planes[0].Distance( v ); - texCoords[i][1] = d1 = planes[1].Distance( v ); - - bits = FLOATSIGNBITSET( d0 ) << 0; - d0 = 1.0f - d0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - d1 = 1.0f - d1; - bits |= FLOATSIGNBITSET( d0 ) << 2; - bits |= FLOATSIGNBITSET( d1 ) << 3; - - cullBits[i] = bits; - } -} - -/* -============ -idSIMD_Generic::DeriveTriPlanes - - Derives a plane equation for each triangle. -============ -*/ -void VPCALL idSIMD_Generic::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - int i; - - for ( i = 0; i < numIndexes; i += 3 ) { - const idDrawVert *a, *b, *c; - float d0[3], d1[3], f; - idVec3 n; - - a = verts + indexes[i + 0]; - b = verts + indexes[i + 1]; - c = verts + indexes[i + 2]; - - d0[0] = b->xyz[0] - a->xyz[0]; - d0[1] = b->xyz[1] - a->xyz[1]; - d0[2] = b->xyz[2] - a->xyz[2]; - - d1[0] = c->xyz[0] - a->xyz[0]; - d1[1] = c->xyz[1] - a->xyz[1]; - d1[2] = c->xyz[2] - a->xyz[2]; - - n[0] = d1[1] * d0[2] - d1[2] * d0[1]; - n[1] = d1[2] * d0[0] - d1[0] * d0[2]; - n[2] = d1[0] * d0[1] - d1[1] * d0[0]; - - f = idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); - - n.x *= f; - n.y *= f; - n.z *= f; - - planes->SetNormal( n ); - planes->FitThroughPoint( a->xyz ); - planes++; - } -} - -/* -============ -idSIMD_Generic::DeriveTangents - - Derives the normal and orthogonal tangent vectors for the triangle vertices. - For each vertex the normal and tangent vectors are derived from all triangles - using the vertex which results in smooth tangents across the mesh. - In the process the triangle planes are calculated as well. -============ -*/ -void VPCALL idSIMD_Generic::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - int i; - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - idPlane *planesPtr = planes; - for ( i = 0; i < numIndexes; i += 3 ) { - idDrawVert *a, *b, *c; - unsigned long signBit; - float d0[5], d1[5], f, area; - idVec3 n, t0, t1; - - int v0 = indexes[i + 0]; - int v1 = indexes[i + 1]; - int v2 = indexes[i + 2]; - - a = verts + v0; - b = verts + v1; - c = verts + v2; - - d0[0] = b->xyz[0] - a->xyz[0]; - d0[1] = b->xyz[1] - a->xyz[1]; - d0[2] = b->xyz[2] - a->xyz[2]; - d0[3] = b->st[0] - a->st[0]; - d0[4] = b->st[1] - a->st[1]; - - d1[0] = c->xyz[0] - a->xyz[0]; - d1[1] = c->xyz[1] - a->xyz[1]; - d1[2] = c->xyz[2] - a->xyz[2]; - d1[3] = c->st[0] - a->st[0]; - d1[4] = c->st[1] - a->st[1]; - - // normal - n[0] = d1[1] * d0[2] - d1[2] * d0[1]; - n[1] = d1[2] * d0[0] - d1[0] * d0[2]; - n[2] = d1[0] * d0[1] - d1[1] * d0[0]; - - f = idMath::RSqrt( n.x * n.x + n.y * n.y + n.z * n.z ); - - n.x *= f; - n.y *= f; - n.z *= f; - - planesPtr->SetNormal( n ); - planesPtr->FitThroughPoint( a->xyz ); - planesPtr++; - - // area sign bit - area = d0[3] * d1[4] - d0[4] * d1[3]; - signBit = ( *(unsigned long *)&area ) & ( 1 << 31 ); - - // first tangent - t0[0] = d0[0] * d1[4] - d0[4] * d1[0]; - t0[1] = d0[1] * d1[4] - d0[4] * d1[1]; - t0[2] = d0[2] * d1[4] - d0[4] * d1[2]; - - f = idMath::RSqrt( t0.x * t0.x + t0.y * t0.y + t0.z * t0.z ); - *(unsigned long *)&f ^= signBit; - - t0.x *= f; - t0.y *= f; - t0.z *= f; - - // second tangent - t1[0] = d0[3] * d1[0] - d0[0] * d1[3]; - t1[1] = d0[3] * d1[1] - d0[1] * d1[3]; - t1[2] = d0[3] * d1[2] - d0[2] * d1[3]; - - f = idMath::RSqrt( t1.x * t1.x + t1.y * t1.y + t1.z * t1.z ); - *(unsigned long *)&f ^= signBit; - - t1.x *= f; - t1.y *= f; - t1.z *= f; - - if ( used[v0] ) { - a->normal += n; - a->tangents[0] += t0; - a->tangents[1] += t1; - } else { - a->normal = n; - a->tangents[0] = t0; - a->tangents[1] = t1; - used[v0] = true; - } - - if ( used[v1] ) { - b->normal += n; - b->tangents[0] += t0; - b->tangents[1] += t1; - } else { - b->normal = n; - b->tangents[0] = t0; - b->tangents[1] = t1; - used[v1] = true; - } - - if ( used[v2] ) { - c->normal += n; - c->tangents[0] += t0; - c->tangents[1] += t1; - } else { - c->normal = n; - c->tangents[0] = t0; - c->tangents[1] = t1; - used[v2] = true; - } - } -} - -/* -============ -idSIMD_Generic::DeriveUnsmoothedTangents - - Derives the normal and orthogonal tangent vectors for the triangle vertices. - For each vertex the normal and tangent vectors are derived from a single dominant triangle. -============ -*/ -#define DERIVE_UNSMOOTHED_BITANGENT - -void VPCALL idSIMD_Generic::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { - int i; - - for ( i = 0; i < numVerts; i++ ) { - idDrawVert *a, *b, *c; - float d0, d1, d2, d3, d4; - float d5, d6, d7, d8, d9; - float s0, s1, s2; - float n0, n1, n2; - float t0, t1, t2; - float t3, t4, t5; - - const dominantTri_s &dt = dominantTris[i]; - - a = verts + i; - b = verts + dt.v2; - c = verts + dt.v3; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - d3 = b->st[0] - a->st[0]; - d4 = b->st[1] - a->st[1]; - - d5 = c->xyz[0] - a->xyz[0]; - d6 = c->xyz[1] - a->xyz[1]; - d7 = c->xyz[2] - a->xyz[2]; - d8 = c->st[0] - a->st[0]; - d9 = c->st[1] - a->st[1]; - - s0 = dt.normalizationScale[0]; - s1 = dt.normalizationScale[1]; - s2 = dt.normalizationScale[2]; - - n0 = s2 * ( d6 * d2 - d7 * d1 ); - n1 = s2 * ( d7 * d0 - d5 * d2 ); - n2 = s2 * ( d5 * d1 - d6 * d0 ); - - t0 = s0 * ( d0 * d9 - d4 * d5 ); - t1 = s0 * ( d1 * d9 - d4 * d6 ); - t2 = s0 * ( d2 * d9 - d4 * d7 ); - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - t3 = s1 * ( d3 * d5 - d0 * d8 ); - t4 = s1 * ( d3 * d6 - d1 * d8 ); - t5 = s1 * ( d3 * d7 - d2 * d8 ); -#else - t3 = s1 * ( n2 * t1 - n1 * t2 ); - t4 = s1 * ( n0 * t2 - n2 * t0 ); - t5 = s1 * ( n1 * t0 - n0 * t1 ); -#endif - - a->normal[0] = n0; - a->normal[1] = n1; - a->normal[2] = n2; - - a->tangents[0][0] = t0; - a->tangents[0][1] = t1; - a->tangents[0][2] = t2; - - a->tangents[1][0] = t3; - a->tangents[1][1] = t4; - a->tangents[1][2] = t5; - } -} - -/* -============ -idSIMD_Generic::NormalizeTangents - - Normalizes each vertex normal and projects and normalizes the - tangent vectors onto the plane orthogonal to the vertex normal. -============ -*/ -void VPCALL idSIMD_Generic::NormalizeTangents( idDrawVert *verts, const int numVerts ) { - - for ( int i = 0; i < numVerts; i++ ) { - idVec3 &v = verts[i].normal; - float f; - - f = idMath::RSqrt( v.x * v.x + v.y * v.y + v.z * v.z ); - v.x *= f; v.y *= f; v.z *= f; - - for ( int j = 0; j < 2; j++ ) { - idVec3 &t = verts[i].tangents[j]; - - t -= ( t * v ) * v; - f = idMath::RSqrt( t.x * t.x + t.y * t.y + t.z * t.z ); - t.x *= f; t.y *= f; t.z *= f; - } - } -} - -/* -============ -idSIMD_Generic::CreateTextureSpaceLightVectors - - Calculates light vectors in texture space for the given triangle vertices. - For each vertex the direction towards the light origin is projected onto texture space. - The light vectors are only calculated for the vertices referenced by the indexes. -============ -*/ -void VPCALL idSIMD_Generic::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - for ( int i = numIndexes - 1; i >= 0; i-- ) { - used[indexes[i]] = true; - } - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - - idVec3 lightDir = lightOrigin - v->xyz; - - lightVectors[i][0] = lightDir * v->tangents[0]; - lightVectors[i][1] = lightDir * v->tangents[1]; - lightVectors[i][2] = lightDir * v->normal; - } -} - -/* -============ -idSIMD_Generic::CreateSpecularTextureCoords - - Calculates specular texture coordinates for the given triangle vertices. - For each vertex the normalized direction towards the light origin is added to the - normalized direction towards the view origin and the result is projected onto texture space. - The texture coordinates are only calculated for the vertices referenced by the indexes. -============ -*/ -void VPCALL idSIMD_Generic::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - for ( int i = numIndexes - 1; i >= 0; i-- ) { - used[indexes[i]] = true; - } - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - - idVec3 lightDir = lightOrigin - v->xyz; - idVec3 viewDir = viewOrigin - v->xyz; - - float ilength; - - ilength = idMath::RSqrt( lightDir * lightDir ); - lightDir[0] *= ilength; - lightDir[1] *= ilength; - lightDir[2] *= ilength; - - ilength = idMath::RSqrt( viewDir * viewDir ); - viewDir[0] *= ilength; - viewDir[1] *= ilength; - viewDir[2] *= ilength; - - lightDir += viewDir; - - texCoords[i][0] = lightDir * v->tangents[0]; - texCoords[i][1] = lightDir * v->tangents[1]; - texCoords[i][2] = lightDir * v->normal; - texCoords[i][3] = 1.0f; - } -} - -/* -============ -idSIMD_Generic::CreateShadowCache -============ -*/ -int VPCALL idSIMD_Generic::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { - int outVerts = 0; - - for ( int i = 0; i < numVerts; i++ ) { - if ( vertRemap[i] ) { - continue; - } - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[outVerts+0][0] = v[0]; - vertexCache[outVerts+0][1] = v[1]; - vertexCache[outVerts+0][2] = v[2]; - vertexCache[outVerts+0][3] = 1.0f; - - // R_SetupProjection() builds the projection matrix with a slight crunch - // for depth, which keeps this w=0 division from rasterizing right at the - // wrap around point and causing depth fighting with the rear caps - vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; - vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; - vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; - vertexCache[outVerts+1][3] = 0.0f; - vertRemap[i] = outVerts; - outVerts += 2; - } - return outVerts; -} - -/* -============ -idSIMD_Generic::CreateVertexProgramShadowCache -============ -*/ -int VPCALL idSIMD_Generic::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { - for ( int i = 0; i < numVerts; i++ ) { - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[i*2+0][0] = v[0]; - vertexCache[i*2+1][0] = v[0]; - vertexCache[i*2+0][1] = v[1]; - vertexCache[i*2+1][1] = v[1]; - vertexCache[i*2+0][2] = v[2]; - vertexCache[i*2+1][2] = v[2]; - vertexCache[i*2+0][3] = 1.0f; - vertexCache[i*2+1][3] = 0.0f; - } - return numVerts * 2; -} - -/* -============ -idSIMD_Generic::UpSamplePCMTo44kHz - - Duplicate samples for 44kHz output. -============ -*/ -void idSIMD_Generic::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = (float) src[i+0]; - } - } else { - for ( int i = 0; i < numSamples; i += 2 ) { - dest[i*4+0] = dest[i*4+2] = dest[i*4+4] = dest[i*4+6] = (float) src[i+0]; - dest[i*4+1] = dest[i*4+3] = dest[i*4+5] = dest[i*4+7] = (float) src[i+1]; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = (float) src[i+0]; - } - } else { - for ( int i = 0; i < numSamples; i += 2 ) { - dest[i*2+0] = dest[i*2+2] = (float) src[i+0]; - dest[i*2+1] = dest[i*2+3] = (float) src[i+1]; - } - } - } else if ( kHz == 44100 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i] = (float) src[i]; - } - } else { - assert( 0 ); - } -} - -/* -============ -idSIMD_Generic::UpSampleOGGTo44kHz - - Duplicate samples for 44kHz output. -============ -*/ -void idSIMD_Generic::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i*4+0] = dest[i*4+1] = dest[i*4+2] = dest[i*4+3] = ogg[0][i] * 32768.0f; - } - } else { - for ( int i = 0; i < numSamples >> 1; i++ ) { - dest[i*8+0] = dest[i*8+2] = dest[i*8+4] = dest[i*8+6] = ogg[0][i] * 32768.0f; - dest[i*8+1] = dest[i*8+3] = dest[i*8+5] = dest[i*8+7] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i*2+0] = dest[i*2+1] = ogg[0][i] * 32768.0f; - } - } else { - for ( int i = 0; i < numSamples >> 1; i++ ) { - dest[i*4+0] = dest[i*4+2] = ogg[0][i] * 32768.0f; - dest[i*4+1] = dest[i*4+3] = ogg[1][i] * 32768.0f; - } - } - } else if ( kHz == 44100 ) { - if ( numChannels == 1 ) { - for ( int i = 0; i < numSamples; i++ ) { - dest[i*1+0] = ogg[0][i] * 32768.0f; - } - } else { - for ( int i = 0; i < numSamples >> 1; i++ ) { - dest[i*2+0] = ogg[0][i] * 32768.0f; - dest[i*2+1] = ogg[1][i] * 32768.0f; - } - } - } else { - assert( 0 ); - } -} - -/* -============ -idSIMD_Generic::MixSoundTwoSpeakerMono -============ -*/ -void VPCALL idSIMD_Generic::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - float sL = lastV[0]; - float sR = lastV[1]; - float incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - float incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - for( int j = 0; j < MIXBUFFER_SAMPLES; j++ ) { - mixBuffer[j*2+0] += samples[j] * sL; - mixBuffer[j*2+1] += samples[j] * sR; - sL += incL; - sR += incR; - } -} - -/* -============ -idSIMD_Generic::MixSoundTwoSpeakerStereo -============ -*/ -void VPCALL idSIMD_Generic::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { - float sL = lastV[0]; - float sR = lastV[1]; - float incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - float incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - for( int j = 0; j < MIXBUFFER_SAMPLES; j++ ) { - mixBuffer[j*2+0] += samples[j*2+0] * sL; - mixBuffer[j*2+1] += samples[j*2+1] * sR; - sL += incL; - sR += incR; - } -} - -/* -============ -idSIMD_Generic::MixSoundSixSpeakerMono -============ -*/ -void VPCALL idSIMD_Generic::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - float sL0 = lastV[0]; - float sL1 = lastV[1]; - float sL2 = lastV[2]; - float sL3 = lastV[3]; - float sL4 = lastV[4]; - float sL5 = lastV[5]; - - float incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - float incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - float incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - float incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - float incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - float incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - for( int i = 0; i < MIXBUFFER_SAMPLES; i++ ) { - mixBuffer[i*6+0] += samples[i] * sL0; - mixBuffer[i*6+1] += samples[i] * sL1; - mixBuffer[i*6+2] += samples[i] * sL2; - mixBuffer[i*6+3] += samples[i] * sL3; - mixBuffer[i*6+4] += samples[i] * sL4; - mixBuffer[i*6+5] += samples[i] * sL5; - sL0 += incL0; - sL1 += incL1; - sL2 += incL2; - sL3 += incL3; - sL4 += incL4; - sL5 += incL5; - } -} - -/* -============ -idSIMD_Generic::MixSoundSixSpeakerStereo -============ -*/ -void VPCALL idSIMD_Generic::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { - float sL0 = lastV[0]; - float sL1 = lastV[1]; - float sL2 = lastV[2]; - float sL3 = lastV[3]; - float sL4 = lastV[4]; - float sL5 = lastV[5]; - - float incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - float incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - float incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - float incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - float incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - float incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - for( int i = 0; i < MIXBUFFER_SAMPLES; i++ ) { - mixBuffer[i*6+0] += samples[i*2+0] * sL0; - mixBuffer[i*6+1] += samples[i*2+1] * sL1; - mixBuffer[i*6+2] += samples[i*2+0] * sL2; - mixBuffer[i*6+3] += samples[i*2+0] * sL3; - mixBuffer[i*6+4] += samples[i*2+0] * sL4; - mixBuffer[i*6+5] += samples[i*2+1] * sL5; - sL0 += incL0; - sL1 += incL1; - sL2 += incL2; - sL3 += incL3; - sL4 += incL4; - sL5 += incL5; - } -} - -/* -============ -idSIMD_Generic::MixedSoundToSamples -============ -*/ -void VPCALL idSIMD_Generic::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { - - for ( int i = 0; i < numSamples; i++ ) { - if ( mixBuffer[i] <= -32768.0f ) { - samples[i] = -32768; - } else if ( mixBuffer[i] >= 32767.0f ) { - samples[i] = 32767; - } else { - samples[i] = (short) mixBuffer[i]; - } - } -} - -#pragma warning( pop ) diff --git a/idlib/math/simd_generic.h b/idlib/math/simd_generic.h deleted file mode 100644 index 5e6b52d09..000000000 --- a/idlib/math/simd_generic.h +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_GENERIC_H__ -#define __MATH_SIMD_GENERIC_H__ - -/* -=============================================================================== - - Generic implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_Generic : public idSIMDProcessor { -public: - virtual const char * VPCALL GetName( void ) const; - - virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); - - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); - virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); - - virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - - virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); - virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); - - virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); - virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); - virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); - - virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); - virtual void VPCALL Memset( void *dst, const int val, const int count ); - - virtual void VPCALL Zero16( float *dst, const int count ); - virtual void VPCALL Negate16( float *dst, const int count ); - virtual void VPCALL Copy16( float *dst, const float *src, const int count ); - virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); - virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); - - virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); - virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); - virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); - virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); - virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); - - virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); - virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); - virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); - virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); - virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); - virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); - virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); - virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); - - virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); -}; - -#endif /* !__MATH_SIMD_GENERIC_H__ */ diff --git a/idlib/math/simd_mmx.cpp b/idlib/math/simd_mmx.cpp deleted file mode 100644 index 282aef4cb..000000000 --- a/idlib/math/simd_mmx.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "simd_generic.h" -#include "simd_mmx.h" - - -//=============================================================== -// -// MMX implementation of idSIMDProcessor -// -//=============================================================== - -#if defined(MACOS_X) && defined(__i386__) -/* -============ -idSIMD_MMX::GetName -============ -*/ -const char * idSIMD_MMX::GetName( void ) const { - return "MMX"; -} - -#elif defined(_WIN32) - -#define EMMS_INSTRUCTION __asm emms - -/* -============ -idSIMD_MMX::GetName -============ -*/ -const char * idSIMD_MMX::GetName( void ) const { - return "MMX"; -} - -/* -================ -MMX_Memcpy8B -================ -*/ -void MMX_Memcpy8B( void *dest, const void *src, const int count ) { - _asm { - mov esi, src - mov edi, dest - mov ecx, count - shr ecx, 3 // 8 bytes per iteration - -loop1: - movq mm1, 0[ESI] // Read in source data - movntq 0[EDI], mm1 // Non-temporal stores - - add esi, 8 - add edi, 8 - dec ecx - jnz loop1 - - } - EMMS_INSTRUCTION -} - -/* -================ -MMX_Memcpy64B - - 165MB/sec -================ -*/ -void MMX_Memcpy64B( void *dest, const void *src, const int count ) { - _asm { - mov esi, src - mov edi, dest - mov ecx, count - shr ecx, 6 // 64 bytes per iteration - -loop1: - prefetchnta 64[ESI] // Prefetch next loop, non-temporal - prefetchnta 96[ESI] - - movq mm1, 0[ESI] // Read in source data - movq mm2, 8[ESI] - movq mm3, 16[ESI] - movq mm4, 24[ESI] - movq mm5, 32[ESI] - movq mm6, 40[ESI] - movq mm7, 48[ESI] - movq mm0, 56[ESI] - - movntq 0[EDI], mm1 // Non-temporal stores - movntq 8[EDI], mm2 - movntq 16[EDI], mm3 - movntq 24[EDI], mm4 - movntq 32[EDI], mm5 - movntq 40[EDI], mm6 - movntq 48[EDI], mm7 - movntq 56[EDI], mm0 - - add esi, 64 - add edi, 64 - dec ecx - jnz loop1 - } - EMMS_INSTRUCTION -} - -/* -================ -MMX_Memcpy2kB - - 240MB/sec -================ -*/ -void MMX_Memcpy2kB( void *dest, const void *src, const int count ) { - byte *tbuf = (byte *)_alloca16(2048); - __asm { - push ebx - mov esi, src - mov ebx, count - shr ebx, 11 // 2048 bytes at a time - mov edi, dest - -loop2k: - push edi // copy 2k into temporary buffer - mov edi, tbuf - mov ecx, 32 - -loopMemToL1: - prefetchnta 64[ESI] // Prefetch next loop, non-temporal - prefetchnta 96[ESI] - - movq mm1, 0[ESI] // Read in source data - movq mm2, 8[ESI] - movq mm3, 16[ESI] - movq mm4, 24[ESI] - movq mm5, 32[ESI] - movq mm6, 40[ESI] - movq mm7, 48[ESI] - movq mm0, 56[ESI] - - movq 0[EDI], mm1 // Store into L1 - movq 8[EDI], mm2 - movq 16[EDI], mm3 - movq 24[EDI], mm4 - movq 32[EDI], mm5 - movq 40[EDI], mm6 - movq 48[EDI], mm7 - movq 56[EDI], mm0 - add esi, 64 - add edi, 64 - dec ecx - jnz loopMemToL1 - - pop edi // Now copy from L1 to system memory - push esi - mov esi, tbuf - mov ecx, 32 - -loopL1ToMem: - movq mm1, 0[ESI] // Read in source data from L1 - movq mm2, 8[ESI] - movq mm3, 16[ESI] - movq mm4, 24[ESI] - movq mm5, 32[ESI] - movq mm6, 40[ESI] - movq mm7, 48[ESI] - movq mm0, 56[ESI] - - movntq 0[EDI], mm1 // Non-temporal stores - movntq 8[EDI], mm2 - movntq 16[EDI], mm3 - movntq 24[EDI], mm4 - movntq 32[EDI], mm5 - movntq 40[EDI], mm6 - movntq 48[EDI], mm7 - movntq 56[EDI], mm0 - - add esi, 64 - add edi, 64 - dec ecx - jnz loopL1ToMem - - pop esi // Do next 2k block - dec ebx - jnz loop2k - pop ebx - } - EMMS_INSTRUCTION -} - - -/* -================ -idSIMD_MMX::Memcpy - - optimized memory copy routine that handles all alignment cases and block sizes efficiently -================ -*/ -void VPCALL idSIMD_MMX::Memcpy( void *dest0, const void *src0, const int count0 ) { - // if copying more than 16 bytes and we can copy 8 byte aligned - if ( count0 > 16 && !( ( (int)dest0 ^ (int)src0 ) & 7 ) ) { - byte *dest = (byte *)dest0; - byte *src = (byte *)src0; - - // copy up to the first 8 byte aligned boundary - int count = ((int)dest) & 7; - memcpy( dest, src, count ); - dest += count; - src += count; - count = count0 - count; - - // if there are multiple blocks of 2kB - if ( count & ~4095 ) { - MMX_Memcpy2kB( dest, src, count ); - src += (count & ~2047); - dest += (count & ~2047); - count &= 2047; - } - - // if there are blocks of 64 bytes - if ( count & ~63 ) { - MMX_Memcpy64B( dest, src, count ); - src += (count & ~63); - dest += (count & ~63); - count &= 63; - } - - // if there are blocks of 8 bytes - if ( count & ~7 ) { - MMX_Memcpy8B( dest, src, count ); - src += (count & ~7); - dest += (count & ~7); - count &= 7; - } - - // copy any remaining bytes - memcpy( dest, src, count ); - } else { - // use the regular one if we cannot copy 8 byte aligned - memcpy( dest0, src0, count0 ); - } -} - -/* -================ -idSIMD_MMX::Memset -================ -*/ -void VPCALL idSIMD_MMX::Memset( void* dest0, const int val, const int count0 ) { - union { - byte bytes[8]; - word words[4]; - dword dwords[2]; - } dat; - - byte *dest = (byte *)dest0; - int count = count0; - - while( count > 0 && (((int)dest) & 7) ) { - *dest = val; - dest++; - count--; - } - if ( !count ) { - return; - } - - dat.bytes[0] = val; - dat.bytes[1] = val; - dat.words[1] = dat.words[0]; - dat.dwords[1] = dat.dwords[0]; - - if ( count >= 64 ) { - __asm { - mov edi, dest - mov ecx, count - shr ecx, 6 // 64 bytes per iteration - movq mm1, dat // Read in source data - movq mm2, mm1 - movq mm3, mm1 - movq mm4, mm1 - movq mm5, mm1 - movq mm6, mm1 - movq mm7, mm1 - movq mm0, mm1 -loop1: - movntq 0[EDI], mm1 // Non-temporal stores - movntq 8[EDI], mm2 - movntq 16[EDI], mm3 - movntq 24[EDI], mm4 - movntq 32[EDI], mm5 - movntq 40[EDI], mm6 - movntq 48[EDI], mm7 - movntq 56[EDI], mm0 - - add edi, 64 - dec ecx - jnz loop1 - } - dest += ( count & ~63 ); - count &= 63; - } - - if ( count >= 8 ) { - __asm { - mov edi, dest - mov ecx, count - shr ecx, 3 // 8 bytes per iteration - movq mm1, dat // Read in source data -loop2: - movntq 0[EDI], mm1 // Non-temporal stores - - add edi, 8 - dec ecx - jnz loop2 - } - dest += (count & ~7); - count &= 7; - } - - while( count > 0 ) { - *dest = val; - dest++; - count--; - } - - EMMS_INSTRUCTION -} - -#endif /* _WIN32 */ diff --git a/idlib/math/simd_mmx.h b/idlib/math/simd_mmx.h deleted file mode 100644 index c1cea0844..000000000 --- a/idlib/math/simd_mmx.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_MMX_H__ -#define __MATH_SIMD_MMX_H__ - -/* -=============================================================================== - - MMX implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_MMX : public idSIMD_Generic { -public: -#if defined(MACOS_X) && defined(__i386__) - virtual const char * VPCALL GetName( void ) const; - -#elif defined(_WIN32) - virtual const char * VPCALL GetName( void ) const; - - virtual void VPCALL Memcpy( void *dst, const void *src, const int count ); - virtual void VPCALL Memset( void *dst, const int val, const int count ); - -#endif -}; - -#endif /* !__MATH_SIMD_MMX_H__ */ diff --git a/idlib/math/simd_sse.cpp b/idlib/math/simd_sse.cpp deleted file mode 100644 index 9cfc45a6b..000000000 --- a/idlib/math/simd_sse.cpp +++ /dev/null @@ -1,18076 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "simd_generic.h" -#include "simd_mmx.h" -#include "simd_sse.h" - - -//=============================================================== -// M -// SSE implementation of idSIMDProcessor MrE -// E -//=============================================================== - - -#if defined(MACOS_X) && defined(__i386__) - -#include - -#define DRAWVERT_SIZE 60 -#define DRAWVERT_XYZ_OFFSET (0*4) -#define DRAWVERT_ST_OFFSET (3*4) -#define DRAWVERT_NORMAL_OFFSET (5*4) -#define DRAWVERT_TANGENT0_OFFSET (8*4) -#define DRAWVERT_TANGENT1_OFFSET (11*4) -#define DRAWVERT_COLOR_OFFSET (14*4) - -#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) -#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) - -/* -============ -idSIMD_SSE::GetName -============ -*/ -const char * idSIMD_SSE::GetName( void ) const { - return "MMX & SSE"; -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant.Normal() * src[i].xyz + constant[3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { - // 0, 1, 2 - // 3, 4, 5 - // 6, 7, 8 - // 9, 10, 11 - - /* - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - */ - __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; // Declare 8 xmm registers. - int count_l4 = count; // count_l4 = eax - int count_l1 = count; // count_l1 = edx - char *constant_p = (char *)&constant; // constant_p = edi - char *src_p = (char *) src; // src_p = esi - char *dst_p = (char *) dst; // dst_p = ecx - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - /* - and eax, ~3 - movss xmm4, [edi+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [edi+4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [edi+12] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - */ - count_l4 = count_l4 & ~3; - xmm4 = _mm_load_ss((float *) (constant_p)); - xmm4 = _mm_shuffle_ps(xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm5 = _mm_load_ss((float *) (constant_p + 4)); - xmm5 = _mm_shuffle_ps(xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm6 = _mm_load_ss((float *) (constant_p + 8)); - xmm6 = _mm_shuffle_ps(xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm7 = _mm_load_ss((float *) (constant_p + 12)); - xmm7 = _mm_shuffle_ps(xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 )); - - /* - jz startVert1 - */ - if(count_l4 != 0) { - /* - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - */ - count_l4 = count_l4 * DRAWVERT_SIZE; - src_p = src_p + count_l4; - count_l4 = -count_l4; - /* - loopVert4: - */ - do { - /* - movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X - movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X - movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 - movaps xmm1, xmm0 // 3, X, 0, 1 - */ - xmm0 = _mm_load_ss((float *) (src_p+count_l4+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 3, X, X, X - xmm2 = _mm_load_ss((float *) (src_p+count_l4+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8)); // 2, X, X, X - xmm0 = _mm_loadh_pi(xmm0, (__m64 *) (src_p+count_l4+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 3, X, 0, 1 - xmm1 = xmm0; // 3, X, 0, 1 - - /* - movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 - shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 - */ - xmm1 = _mm_loadl_pi(xmm1, (__m64 *) (src_p+count_l4+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4)); // 4, 5, 0, 1 - xmm2 = _mm_shuffle_ps(xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 )); // 2, X, 4, 5 - - /* - movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 - shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 - */ - xmm3 = _mm_load_ss((float *) (src_p+count_l4+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 9, X, X, X - xmm3 = _mm_loadh_pi(xmm3, (__m64 *) (src_p+count_l4+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0)); // 9, X, 6, 7 - xmm0 = _mm_shuffle_ps(xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 )); // 0, 3, 6, 9 - /* - movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 - shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 - */ - xmm3 = _mm_loadl_pi(xmm3, (__m64 *)(src_p+count_l4+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4)); // 10, 11, 6, 7 - xmm1 = _mm_shuffle_ps(xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 )); // 1, 4, 7, 10 - /* - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 - */ - xmm3 = _mm_loadh_pi(xmm3, (__m64 *)(src_p+count_l4+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8)); // 10, 11, 8, X - xmm2 = _mm_shuffle_ps(xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 )); // 2, 5, 8, 11 - - /* - add ecx, 16 - add eax, 4*DRAWVERT_SIZE - */ - dst_p = dst_p + 16; - count_l4 = count_l4 + 4*DRAWVERT_SIZE; - - /* - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - addps xmm0, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm2 - */ - xmm0 = _mm_mul_ps(xmm0, xmm4); - xmm1 = _mm_mul_ps(xmm1, xmm5); - xmm2 = _mm_mul_ps(xmm2, xmm6); - xmm0 = _mm_add_ps(xmm0, xmm7); - xmm0 = _mm_add_ps(xmm0, xmm1); - xmm0 = _mm_add_ps(xmm0, xmm2); - - /* - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loopVert4 - */ - _mm_storel_pi((__m64 *) (dst_p-16+0), xmm0); - _mm_storeh_pi((__m64 *) (dst_p-16+8), xmm0); - } while(count_l4 < 0); - } - - /* - startVert1: - and edx, 3 - jz done - */ - count_l1 = count_l1 & 3; - if(count_l1 != 0) { - /* - loopVert1: - movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] - mulss xmm0, xmm4 - mulss xmm1, xmm5 - mulss xmm2, xmm6 - addss xmm0, xmm7 - add ecx, 4 - addss xmm0, xmm1 - add eax, DRAWVERT_SIZE - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loopVert1 - */ - do { - xmm0 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+0)); - xmm1 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+4)); - xmm2 = _mm_load_ss((float *) (src_p+count_l4+DRAWVERT_XYZ_OFFSET+8)); - xmm0 = _mm_mul_ss(xmm0, xmm4); - xmm1 = _mm_mul_ss(xmm1, xmm5); - xmm2 = _mm_mul_ss(xmm2, xmm6); - xmm0 = _mm_add_ss(xmm0, xmm7); - dst_p = dst_p + 4; - xmm0 = _mm_add_ss(xmm0, xmm1); - count_l4 = count_l4 + DRAWVERT_SIZE; - xmm0 = _mm_add_ss(xmm0, xmm2); - count_l1 = count_l1 - 1; - _mm_store_ss((float *) (dst_p-4), xmm0); - } while( count_l1 != 0); - } - /* - done: - */ -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; - char *indexes_p; - char *src_p; - int count_l; - int edx; - char *min_p; - char *max_p; - - /* - movss xmm0, idMath::INFINITY - xorps xmm1, xmm1 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - subps xmm1, xmm0 - movaps xmm2, xmm0 - movaps xmm3, xmm1 - */ - xmm0 = _mm_load_ss(&idMath::INFINITY); - // To satisfy the compiler use xmm0 instead. - xmm1 = _mm_xor_ps(xmm0, xmm0); - xmm0 = _mm_shuffle_ps(xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm1 = _mm_sub_ps(xmm1, xmm0); - xmm2 = xmm0; - xmm3 = xmm1; - - /* - mov edi, indexes - mov esi, src - mov eax, count - and eax, ~3 - jz done4 - */ - indexes_p = (char *) indexes; - src_p = (char *) src; - count_l = count; - count_l = count_l & ~3; - if(count_l != 0) { - /* - shl eax, 2 - add edi, eax - neg eax - */ - count_l = count_l << 2; - indexes_p = indexes_p + count_l; - count_l = -count_l; - /* - loop4: -// prefetchnta [edi+128] -// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] - */ - do { - /* - mov edx, [edi+eax+0] - imul edx, DRAWVERT_SIZE - movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - */ - edx = *((int*)(indexes_p+count_l+0)); - edx = edx * DRAWVERT_SIZE; - xmm4 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); - xmm4 = _mm_loadh_pi(xmm4, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); - xmm0 = _mm_min_ps(xmm0, xmm4); - xmm1 = _mm_max_ps(xmm1, xmm4); - - /* - mov edx, [edi+eax+4] - imul edx, DRAWVERT_SIZE - movss xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - movhps xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm5 - maxps xmm3, xmm5 - */ - edx = *((int*)(indexes_p+count_l+4)); - edx = edx * DRAWVERT_SIZE; - xmm5 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0)); - xmm5 = _mm_loadh_pi(xmm5, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+4) ); - xmm2 = _mm_min_ps(xmm2, xmm5); - xmm3 = _mm_max_ps(xmm3, xmm5); - - /* - mov edx, [edi+eax+8] - imul edx, DRAWVERT_SIZE - movss xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm6 - maxps xmm1, xmm6 - */ - edx = *((int*)(indexes_p+count_l+8)); - edx = edx * DRAWVERT_SIZE; - xmm6 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); - xmm6 = _mm_loadh_pi(xmm6, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); - xmm0 = _mm_min_ps(xmm0, xmm6); - xmm1 = _mm_max_ps(xmm1, xmm6); - - /* - mov edx, [edi+eax+12] - imul edx, DRAWVERT_SIZE - movss xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - movhps xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm7 - maxps xmm3, xmm7 - */ - edx = *((int*)(indexes_p+count_l+12)); - edx = edx * DRAWVERT_SIZE; - xmm7 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0)); - xmm7 = _mm_loadh_pi(xmm7, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+4) ); - xmm2 = _mm_min_ps(xmm2, xmm7); - xmm3 = _mm_max_ps(xmm3, xmm7); - - /* - add eax, 4*4 - jl loop4 - */ - count_l = count_l + 4*4; - } while (count_l < 0); - } - /* - done4: - mov eax, count - and eax, 3 - jz done1 - */ - count_l = count; - count_l = count_l & 3; - if(count_l != 0) { - /* - shl eax, 2 - add edi, eax - neg eax - */ - count_l = count_l << 2; - indexes_p = indexes_p + count_l; - count_l = -count_l; - /* - loop1: - */ - do{ - /* - mov edx, [edi+eax+0] - imul edx, DRAWVERT_SIZE; - movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - */ - edx = *((int*)(indexes_p+count_l+0)); - edx = edx * DRAWVERT_SIZE; - xmm4 = _mm_load_ss((float *) (src_p+edx+DRAWVERT_XYZ_OFFSET+8)); - xmm4 = _mm_loadh_pi(xmm4, (__m64 *) (src_p+edx+DRAWVERT_XYZ_OFFSET+0) ); - xmm0 = _mm_min_ps(xmm0, xmm4); - xmm1 = _mm_max_ps(xmm1, xmm4); - - /* - add eax, 4 - jl loop1 - */ - count_l = count_l + 4; - } while (count_l < 0); - - } - - /* - done1: - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) - minps xmm0, xmm2 - maxps xmm1, xmm3 - mov esi, min - movhps [esi], xmm0 - movss [esi+8], xmm0 - mov edi, max - movhps [edi], xmm1 - movss [edi+8], xmm1 - */ - xmm2 = _mm_shuffle_ps(xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 )); - xmm3 = _mm_shuffle_ps(xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 )); - xmm0 = _mm_min_ps(xmm0, xmm2); - xmm1 = _mm_max_ps(xmm1, xmm3); - min_p = (char *) &min; - _mm_storeh_pi((__m64 *)(min_p), xmm0); - _mm_store_ss((float *)(min_p+8), xmm0); - max_p = (char *) &max; - _mm_storeh_pi((__m64 *)(max_p), xmm1); - _mm_store_ss((float *)(max_p+8), xmm1); -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant * src[i].Normal() + src[i][3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { - int count_l4; - int count_l1; - char *constant_p; - char *src_p; - char *dst_p; - __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; - - /* - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - */ - count_l4 = count; - constant_p = (char *) &constant; - count_l1 = count_l4; - src_p = (char *) src; - dst_p = (char *) dst; - count_l4 = count_l4 & ~3; - - /* - movss xmm5, [edi+0] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [edi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - */ - xmm5 = _mm_load_ss((float *) (constant_p+0)); - xmm5 = _mm_shuffle_ps(xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm6 = _mm_load_ss((float *) (constant_p+4)); - xmm6 = _mm_shuffle_ps(xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 )); - xmm7 = _mm_load_ss((float *) (constant_p+8)); - xmm7 = _mm_shuffle_ps(xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 )); - - /* - jz startVert1 - */ - if (count != 0) { - /* - imul eax, 16 - add esi, eax - neg eax - */ - count_l4 = count_l4 * 16; - src_p = src_p + count_l4; - count_l4 = -count_l4; - /* - loopVert4: - */ - do { - /* - movlps xmm1, [esi+eax+ 0] - movlps xmm3, [esi+eax+ 8] - movhps xmm1, [esi+eax+16] - movhps xmm3, [esi+eax+24] - movlps xmm2, [esi+eax+32] - movlps xmm4, [esi+eax+40] - movhps xmm2, [esi+eax+48] - movhps xmm4, [esi+eax+56] - movaps xmm0, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) - movaps xmm2, xmm3 - shufps xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) - */ - xmm1 = _mm_loadl_pi(xmm1, (__m64 *)(src_p+count_l4+ 0)); - xmm3 = _mm_loadl_pi(xmm3, (__m64 *)(src_p+count_l4+ 8)); - xmm1 = _mm_loadh_pi(xmm1, (__m64 *)(src_p+count_l4+16)); - xmm3 = _mm_loadh_pi(xmm3, (__m64 *)(src_p+count_l4+24)); - xmm2 = _mm_loadl_pi(xmm2, (__m64 *)(src_p+count_l4+32)); - xmm4 = _mm_loadl_pi(xmm4, (__m64 *)(src_p+count_l4+40)); - xmm2 = _mm_loadh_pi(xmm2, (__m64 *)(src_p+count_l4+48)); - xmm4 = _mm_loadh_pi(xmm4, (__m64 *)(src_p+count_l4+56)); - - xmm0 = xmm1; - xmm0 = _mm_shuffle_ps(xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 )); - xmm1 = _mm_shuffle_ps(xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 )); - xmm2 = xmm3; - xmm2 = _mm_shuffle_ps(xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 )); - xmm3 = _mm_shuffle_ps(xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 )); - - /* - add ecx, 16 - add eax, 4*16 - */ - dst_p = dst_p + 16; - count_l4 = count_l4 + 4*16; - - /* - mulps xmm0, xmm5 - mulps xmm1, xmm6 - mulps xmm2, xmm7 - addps xmm0, xmm3 - addps xmm0, xmm1 - addps xmm0, xmm2 - */ - xmm0 = _mm_mul_ps(xmm0, xmm5); - xmm1 = _mm_mul_ps(xmm1, xmm6); - xmm2 = _mm_mul_ps(xmm2, xmm7); - xmm0 = _mm_add_ps(xmm0, xmm3); - xmm0 = _mm_add_ps(xmm0, xmm1); - xmm0 = _mm_add_ps(xmm0, xmm2); - - /* - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loopVert4 - */ - _mm_storel_pi((__m64 *) (dst_p-16+0), xmm0); - _mm_storeh_pi((__m64 *) (dst_p-16+8), xmm0); - } while (count_l4 < 0); - } - - /* - startVert1: - and edx, 3 - jz done - */ - count_l1 = count_l1 & 3; - - if(count_l1 != 0) { - /* - loopVert1: - */ - do { - /* - movss xmm0, [esi+eax+0] - movss xmm1, [esi+eax+4] - movss xmm2, [esi+eax+8] - mulss xmm0, xmm5 - mulss xmm1, xmm6 - mulss xmm2, xmm7 - addss xmm0, [esi+eax+12] - add ecx, 4 - addss xmm0, xmm1 - add eax, 16 - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loopVert1 - */ - xmm0 = _mm_load_ss((float *) (src_p+count_l4+ 0)); - xmm1 = _mm_load_ss((float *) (src_p+count_l4+ 4)); - xmm2 = _mm_load_ss((float *) (src_p+count_l4+ 8)); - xmm3 = _mm_load_ss((float *) (src_p+count_l4+12)); - - xmm0 = _mm_mul_ss(xmm0, xmm5); - xmm1 = _mm_mul_ss(xmm1, xmm6); - xmm2 = _mm_mul_ss(xmm2, xmm7); - - xmm0 = _mm_add_ss(xmm0, xmm3); - dst_p = dst_p + 4; - xmm0 = _mm_add_ss(xmm0, xmm1); - count_l4 = count_l4 + 16; - xmm0 = _mm_add_ss(xmm0, xmm2); - count_l1 = count_l1 - 1; - _mm_store_ss((float *) (dst_p-4), xmm0); - } while (count_l1 != 0); - } - /* - done: - */ -} - -#elif defined(_WIN32) - -#include -#pragma warning( push ) -#pragma warning( disable: 4127 4740 ) - -#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) -#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) - -// transpose a 4x4 matrix loaded into 4 xmm registers (reg4 is temporary) -#define TRANSPOSE_4x4( reg0, reg1, reg2, reg3, reg4 ) \ - __asm movaps reg4, reg2 /* reg4 = 8, 9, 10, 11 */ \ - __asm unpcklps reg2, reg3 /* reg2 = 8, 12, 9, 13 */ \ - __asm unpckhps reg4, reg3 /* reg4 = 10, 14, 11, 15 */ \ - __asm movaps reg3, reg0 /* reg3 = 0, 1, 2, 3 */ \ - __asm unpcklps reg0, reg1 /* reg0 = 0, 4, 1, 5 */ \ - __asm unpckhps reg3, reg1 /* reg3 = 2, 6, 3, 7 */ \ - __asm movaps reg1, reg0 /* reg1 = 0, 4, 1, 5 */ \ - __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 1, 0, 1 ) /* reg0 = 0, 4, 8, 12 */ \ - __asm shufps reg1, reg2, R_SHUFFLEPS( 2, 3, 2, 3 ) /* reg1 = 1, 5, 9, 13 */ \ - __asm movaps reg2, reg3 /* reg2 = 2, 6, 3, 7 */ \ - __asm shufps reg2, reg4, R_SHUFFLEPS( 0, 1, 0, 1 ) /* reg2 = 2, 6, 10, 14 */ \ - __asm shufps reg3, reg4, R_SHUFFLEPS( 2, 3, 2, 3 ) /* reg3 = 3, 7, 11, 15 */ - -// transpose a 4x4 matrix from memory into 4 xmm registers (reg4 is temporary) -#define TRANPOSE_4x4_FROM_MEMORY( address, reg0, reg1, reg2, reg3, reg4 ) \ - __asm movlps reg1, [address+ 0] /* reg1 = 0, 1, X, X */ \ - __asm movlps reg3, [address+ 8] /* reg3 = 2, 3, X, X */ \ - __asm movhps reg1, [address+16] /* reg1 = 0, 1, 4, 5 */ \ - __asm movhps reg3, [address+24] /* reg3 = 2, 3, 6, 7 */ \ - __asm movlps reg2, [address+32] /* reg2 = 8, 9, X, X */ \ - __asm movlps reg4, [address+40] /* reg4 = 10, 11, X, X */ \ - __asm movhps reg2, [address+48] /* reg2 = 8, 9, 12, 13 */ \ - __asm movhps reg4, [address+56] /* reg4 = 10, 11, 14, 15 */ \ - __asm movaps reg0, reg1 /* reg0 = 0, 1, 4, 5 */ \ - __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 2, 0, 2 ) /* reg0 = 0, 4, 8, 12 */ \ - __asm shufps reg1, reg2, R_SHUFFLEPS( 1, 3, 1, 3 ) /* reg1 = 1, 5, 9, 13 */ \ - __asm movaps reg2, reg3 /* reg2 = 2, 3, 6, 7 */ \ - __asm shufps reg2, reg4, R_SHUFFLEPS( 0, 2, 0, 2 ) /* reg2 = 2, 6, 10, 14 */ \ - __asm shufps reg3, reg4, R_SHUFFLEPS( 1, 3, 1, 3 ) /* reg3 = 3, 7, 11, 15 */ - -// transpose a 4x4 matrix to memory from 4 xmm registers (reg4 is temporary) -#define TRANPOSE_4x4_TO_MEMORY( address, reg0, reg1, reg2, reg3, reg4 ) \ - __asm movaps reg4, reg0 /* reg4 = 0, 4, 8, 12 */ \ - __asm unpcklps reg0, reg1 /* reg0 = 0, 1, 4, 5 */ \ - __asm unpckhps reg4, reg1 /* reg4 = 8, 9, 12, 13 */ \ - __asm movaps reg1, reg2 /* reg1 = 2, 6, 10, 14 */ \ - __asm unpcklps reg2, reg3 /* reg2 = 2, 3, 6, 7 */ \ - __asm unpckhps reg1, reg3 /* reg1 = 10, 11, 14, 15 */ \ - __asm movlps [address+ 0], reg0 /* mem0 = 0, 1, X, X */ \ - __asm movlps [address+ 8], reg2 /* mem0 = 0, 1, 2, 3 */ \ - __asm movhps [address+16], reg0 /* mem1 = 4, 5, X, X */ \ - __asm movhps [address+24], reg2 /* mem1 = 4, 5, 6, 7 */ \ - __asm movlps [address+32], reg4 /* mem2 = 8, 9, X, X */ \ - __asm movlps [address+40], reg1 /* mem2 = 8, 9, 10, 11 */ \ - __asm movhps [address+48], reg4 /* mem3 = 12, 13, X, X */ \ - __asm movhps [address+56], reg1 /* mem3 = 12, 13, 14, 15 */ - -// transpose a 4x3 matrix loaded into 3 xmm registers (reg3 is temporary) -#define TRANSPOSE_4x3( reg0, reg1, reg2, reg3 ) \ - __asm movaps reg3, reg2 /* reg3 = 8, 9, 10, 11 */ \ - __asm shufps reg3, reg1, R_SHUFFLEPS( 2, 3, 0, 1 ) /* reg3 = 10, 11, 4, 5 */ \ - __asm shufps reg2, reg0, R_SHUFFLEPS( 0, 1, 2, 3 ) /* reg2 = 8, 9, 2, 3 */ \ - __asm shufps reg1, reg0, R_SHUFFLEPS( 2, 3, 0, 1 ) /* reg1 = 6, 7, 0, 1 */ \ - __asm movaps reg0, reg1 /* reg0 = 6, 7, 0, 1 */ \ - __asm shufps reg0, reg2, R_SHUFFLEPS( 2, 0, 3, 1 ) /* reg0 = 0, 6, 3, 9 */ \ - __asm shufps reg1, reg3, R_SHUFFLEPS( 3, 1, 2, 0 ) /* reg1 = 1, 7, 4, 10 */ \ - __asm shufps reg2, reg3, R_SHUFFLEPS( 2, 0, 3, 1 ) /* reg2 = 2, 8, 5, 11 */ - -// transpose a 4x3 matrix from memory into 3 xmm registers (reg3 is temporary) -#define TRANSPOSE_4x3_FROM_MEMORY( address, reg0, reg1, reg2, reg3 ) \ - __asm movlps reg1, [address+ 0] /* reg1 = 0, 1, X, X */ \ - __asm movlps reg2, [address+ 8] /* reg2 = 2, 3, X, X */ \ - __asm movlps reg3, [address+16] /* reg3 = 4, 5, X, X */ \ - __asm movhps reg1, [address+24] /* reg1 = 0, 1, 6, 7 */ \ - __asm movhps reg2, [address+32] /* reg2 = 2, 3, 8, 9 */ \ - __asm movhps reg3, [address+40] /* reg3 = 4, 5, 10, 11 */ \ - __asm movaps reg0, reg1 /* reg0 = 0, 1, 6, 7 */ \ - __asm shufps reg0, reg2, R_SHUFFLEPS( 0, 2, 1, 3 ) /* reg0 = 0, 6, 3, 9 */ \ - __asm shufps reg1, reg3, R_SHUFFLEPS( 1, 3, 0, 2 ) /* reg1 = 1, 7, 4, 10 */ \ - __asm shufps reg2, reg3, R_SHUFFLEPS( 0, 2, 1, 3 ) /* reg2 = 2, 8, 5, 11 */ - -// transpose a 4x3 matrix to memory from 3 xmm registers (reg3 is temporary) -#define TRANSPOSE_4x3_TO_MEMORY( address, reg0, reg1, reg2, reg3 ) \ - __asm movhlps reg3, reg0 /* reg3 = 3, 9, X, X */ \ - __asm unpcklps reg0, reg1 /* reg0 = 0, 1, 6, 7 */ \ - __asm unpckhps reg1, reg2 /* reg1 = 4, 5, 10, 11 */ \ - __asm unpcklps reg2, reg3 /* reg2 = 2, 3, 8, 9 */ \ - __asm movlps [address+ 0], reg0 /* mem0 = 0, 1, X, X */ \ - __asm movlps [address+ 8], reg2 /* mem0 = 0, 1, 2, 3 */ \ - __asm movlps [address+16], reg1 /* mem1 = 4, 5, X, X */ \ - __asm movhps [address+24], reg0 /* mem1 = 4, 5, 6, 7 */ \ - __asm movhps [address+32], reg2 /* mem2 = 8, 9, X, X */ \ - __asm movhps [address+40], reg1 /* mem2 = 8, 9, 10, 11 */ - - -// with alignment -#define KFLOATINITS( SRC0, COUNT, PRE, POST ) KFLOATINITDSS( SRC0,SRC0,SRC0,COUNT,PRE,POST ) -#define KFLOATINITD( DST, COUNT, PRE, POST ) KFLOATINITDSS( DST,DST,DST,COUNT,PRE,POST ) -#define KFLOATINITDS( DST, SRC0, COUNT, PRE, POST ) KFLOATINITDSS( DST,SRC0,SRC0,COUNT,PRE,POST ) - -#define KFLOATINITDSS( DST, SRC0, SRC1, COUNT, PRE, POST )\ - __asm mov ecx,DST \ - __asm shr ecx,2 \ - __asm mov ebx,COUNT \ - __asm neg ecx \ - __asm mov edx,SRC0 \ - __asm and ecx,3 \ - __asm mov esi,SRC1 \ - __asm sub ebx,ecx \ - __asm jge noUnderFlow \ - __asm xor ebx,ebx \ - __asm mov ecx,COUNT \ - __asm noUnderFlow: \ - __asm mov PRE,ecx \ - __asm mov eax,ebx \ - __asm mov edi,DST \ - __asm and eax,8-1 \ - __asm mov POST,eax \ - __asm and ebx,0xfffffff8 \ - __asm jle done \ - __asm shl ebx,2 \ - __asm lea ecx,[ecx*4+ebx] \ - __asm neg ebx \ - __asm add edx,ecx \ - __asm add esi,ecx \ - __asm add edi,ecx \ - __asm mov eax,edx \ - __asm or eax,esi - -// without alignment (pre==0) -#define KFLOATINITS_NA( SRC0, COUNT, PRE, POST ) KFLOATINITDSS_NA( SRC0,SRC0,SRC0,COUNT,PRE,POST ) -#define KFLOATINITD_NA( DST, COUNT, PRE, POST ) KFLOATINITDSS_NA( DST,DST,DST,COUNT,PRE,POST ) -#define KFLOATINITDS_NA( DST, SRC0, COUNT, PRE, POST ) KFLOATINITDSS_NA( DST,SRC0,SRC0,COUNT,PRE,POST ) -#define KFLOATINITDSS_NA( DST, SRC0, SRC1, COUNT, PRE, POST )\ - __asm mov eax,COUNT \ - __asm mov PRE,0 \ - __asm and eax,8-1 \ - __asm mov ebx,COUNT \ - __asm mov POST,eax \ - __asm and ebx,0xfffffff8 \ - __asm je done \ - __asm shl ebx,2 \ - __asm mov edx,SRC0 \ - __asm mov esi,SRC1 \ - __asm mov edi,DST \ - __asm add edx,ebx \ - __asm add esi,ebx \ - __asm add edi,ebx \ - __asm mov eax,edx \ - __asm or eax,esi \ - __asm or eax,edi \ - __asm neg ebx \ - -/* - when OPER is called: - edx = s0 - esi = s1 - edi = d - ebx = index*4 - - xmm0 & xmm1 must not be trashed -*/ -#define KMOVDS1( DST, SRC0 ) \ - __asm movss xmm2,SRC0 \ - __asm movss DST,xmm2 -#define KMOVDS4( DST, SRC0 ) \ - __asm movups xmm2,SRC0 \ - __asm movups DST,xmm2 -#define KMINDS1( DST, SRC0 ) \ - __asm movss xmm2,SRC0 \ - __asm minss DST,xmm2 -#define KMAXDS1( DST, SRC0 ) \ - __asm movss xmm2,SRC0 \ - __asm maxss DST,xmm2 - -// general ALU operation -#define KALUDSS1( OP, DST, SRC0, SRC1 ) \ - __asm movss xmm2,SRC0 \ - __asm OP##ss xmm2,SRC1 \ - __asm movss DST,xmm2 -#define KALUDSS4( OP, DST, SRC0, SRC1 ) \ - __asm movups xmm2,SRC0 \ - __asm movups xmm3,SRC1 \ - __asm OP##ps xmm2,xmm3 \ - __asm movups DST,xmm2 - -#define KADDDSS1( DST, SRC0, SRC1 ) KALUDSS1( add, DST,SRC0,SRC1 ) -#define KADDDSS4( DST, SRC0, SRC1 ) KALUDSS4( add, DST,SRC0,SRC1 ) -#define KSUBDSS1( DST, SRC0, SRC1 ) KALUDSS1( sub, DST,SRC0,SRC1 ) -#define KSUBDSS4( DST, SRC0, SRC1 ) KALUDSS4( sub, DST,SRC0,SRC1 ) -#define KMULDSS1( DST, SRC0, SRC1 ) KALUDSS1( mul, DST,SRC0,SRC1 ) -#define KMULDSS4( DST, SRC0, SRC1 ) KALUDSS4( mul, DST,SRC0,SRC1 ) - -#define KDIVDSS1( DST, SRC0, SRC1 ) \ - __asm movss xmm2,SRC1 \ - __asm rcpss xmm3,xmm2 \ - __asm mulss xmm2,xmm3 \ - __asm mulss xmm2,xmm3 \ - __asm addss xmm3,xmm3 \ - __asm subss xmm3,xmm2 \ - __asm mulss xmm3,SRC0 \ - __asm movss DST,xmm3 -#define KDIVDSS4( DST, SRC0, SRC1 ) \ - __asm movups xmm2,SRC1 \ - __asm rcpps xmm3,xmm2 \ - __asm mulps xmm2,xmm3 \ - __asm mulps xmm2,xmm3 \ - __asm addps xmm3,xmm3 \ - __asm subps xmm3,xmm2 \ - __asm movups xmm2,SRC0 \ - __asm mulps xmm3,xmm2 \ - __asm movups DST,xmm3 -#define KF2IDS1( SRC0 ) \ - __asm movss xmm2,SRC0 \ - __asm cvttps2pi mm2,xmm2 \ - __asm movd [edi+ebx],mm2 -#define KF2IDS4( SRC0 ) \ - __asm movups xmm2,SRC0 \ - __asm cvttps2pi mm2,xmm2 \ - __asm movq [edi+ebx+0],mm2 \ - __asm shufps xmm2,xmm2,SHUFFLEPS(1,0,3,2) \ - __asm cvttps2pi mm2,xmm2 \ - __asm movq [edi+ebx+8],mm2 -#define KISQRTDS1( DST,SRC0 ) \ - __asm movss xmm2,SRC0 \ - __asm rsqrtss xmm3,xmm2 \ - __asm mulss xmm2,xmm3 \ - __asm mulss xmm2,xmm3 \ - __asm subss xmm2,xmm1 \ - __asm mulss xmm3,xmm0 \ - __asm mulss xmm3,xmm2 \ - __asm movss DST,xmm3 -#define KISQRTDS4( DST,SRC0 ) \ - __asm movups xmm2,SRC0 \ - __asm rsqrtps xmm3,xmm2 \ - __asm mulps xmm2,xmm3 \ - __asm mulps xmm2,xmm3 \ - __asm subps xmm2,xmm1 \ - __asm mulps xmm3,xmm0 \ - __asm mulps xmm3,xmm2 \ - __asm movups DST,xmm3 - -// this is used in vector4 implementation to shift constant V4 -#define KANDREGDSV( DST, SRC0, VALUE ) \ - __asm mov DST,SRC0 \ - __asm and DST,VALUE - -// this is used in vector4 code to operate with float arrays as sources -#define KEXPANDFLOAT( DST, SRC ) \ - __asm movss DST,SRC \ - __asm shufps DST,DST,0 - -#define KADDDS1( DST,SRC ) KADDDSS1( DST,DST,SRC ) -#define KADDDS4( DST,SRC ) KADDDSS4( DST,DST,SRC ) -#define KSUBDS1( DST,SRC ) KSUBDSS1( DST,DST,SRC ) -#define KSUBDS4( DST,SRC ) KSUBDSS4( DST,DST,SRC ) -#define KMULDS1( DST,SRC ) KMULDSS1( DST,DST,SRC ) -#define KMULDS4( DST,SRC ) KMULDSS4( DST,DST,SRC ) -#define KDIVDS1( DST,SRC ) KDIVDSS1( DST,DST,SRC ) -#define KDIVDS4( DST,SRC ) KDIVDSS4( DST,DST,SRC ) - -// handles pre & post leftovers -#define KFLOATOPER( OPER, OPER4, COUNT ) \ - __asm mov ecx,pre \ - __asm mov ebx,COUNT \ - __asm cmp ebx,ecx \ - __asm cmovl ecx,COUNT \ - __asm test ecx,ecx \ - __asm je preDone \ - __asm xor ebx,ebx \ - __asm lpPre: \ - OPER \ - __asm add ebx,4 \ - __asm dec ecx \ - __asm jg lpPre \ - __asm preDone: \ - __asm mov ecx,post \ - __asm mov ebx,COUNT \ - __asm sub ebx,ecx \ - __asm shl ebx,2 \ - __asm cmp ecx,4 \ - __asm jl post4Done \ - OPER4 \ - __asm sub ecx,4 \ - __asm add ebx,4*4 \ - __asm post4Done: \ - __asm test ecx,ecx \ - __asm je postDone \ - __asm lpPost: \ - OPER \ - __asm add ebx,4 \ - __asm dec ecx \ - __asm jg lpPost \ - __asm postDone: - -// operate on a constant and a float array -#define KFLOAT_CA( ALUOP, DST, SRC, CONSTANT, COUNT ) \ - int pre,post; \ - __asm movss xmm0,CONSTANT \ - __asm shufps xmm0,xmm0,0 \ - KFLOATINITDS( DST, SRC, COUNT, pre, post ) \ - __asm and eax,15 \ - __asm jne lpNA \ - __asm jmp lpA \ - __asm align 16 \ - __asm lpA: \ - __asm prefetchnta [edx+ebx+64] \ - __asm movaps xmm1,xmm0 \ - __asm movaps xmm2,xmm0 \ - __asm ALUOP##ps xmm1,[edx+ebx] \ - __asm ALUOP##ps xmm2,[edx+ebx+16] \ - __asm movaps [edi+ebx],xmm1 \ - __asm movaps [edi+ebx+16],xmm2 \ - __asm add ebx,16*2 \ - __asm jl lpA \ - __asm jmp done \ - __asm align 16 \ - __asm lpNA: \ - __asm prefetchnta [edx+ebx+64] \ - __asm movaps xmm1,xmm0 \ - __asm movaps xmm2,xmm0 \ - __asm movups xmm3,[edx+ebx] \ - __asm movups xmm4,[edx+ebx+16] \ - __asm ALUOP##ps xmm1,xmm3 \ - __asm ALUOP##ps xmm2,xmm4 \ - __asm movaps [edi+ebx],xmm1 \ - __asm movaps [edi+ebx+16],xmm2 \ - __asm add ebx,16*2 \ - __asm jl lpNA \ - __asm done: \ - __asm mov edx,SRC \ - __asm mov edi,DST \ - __asm KFLOATOPER( KALUDSS1( ALUOP, [edi+ebx],xmm0,[edx+ebx] ), \ - __asm KALUDSS4( ALUOP, [edi+ebx],xmm0,[edx+ebx] ), COUNT ) - -// operate on two float arrays -#define KFLOAT_AA( ALUOP, DST, SRC0, SRC1, COUNT ) \ - int pre,post; \ - KFLOATINITDSS( DST, SRC0, SRC1, COUNT, pre, post ) \ - __asm and eax,15 \ - __asm jne lpNA \ - __asm jmp lpA \ - __asm align 16 \ - __asm lpA: \ - __asm movaps xmm1,[edx+ebx] \ - __asm movaps xmm2,[edx+ebx+16] \ - __asm ALUOP##ps xmm1,[esi+ebx] \ - __asm ALUOP##ps xmm2,[esi+ebx+16] \ - __asm prefetchnta [edx+ebx+64] \ - __asm prefetchnta [esi+ebx+64] \ - __asm movaps [edi+ebx],xmm1 \ - __asm movaps [edi+ebx+16],xmm2 \ - __asm add ebx,16*2 \ - __asm jl lpA \ - __asm jmp done \ - __asm align 16 \ - __asm lpNA: \ - __asm movups xmm1,[edx+ebx] \ - __asm movups xmm2,[edx+ebx+16] \ - __asm movups xmm3,[esi+ebx] \ - __asm movups xmm4,[esi+ebx+16] \ - __asm prefetchnta [edx+ebx+64] \ - __asm prefetchnta [esi+ebx+64] \ - __asm ALUOP##ps xmm1,xmm3 \ - __asm ALUOP##ps xmm2,xmm4 \ - __asm movaps [edi+ebx],xmm1 \ - __asm movaps [edi+ebx+16],xmm2 \ - __asm add ebx,16*2 \ - __asm jl lpNA \ - __asm done: \ - __asm mov edx,SRC0 \ - __asm mov esi,SRC1 \ - __asm mov edi,DST \ - KFLOATOPER( KALUDSS1( ALUOP, [edi+ebx],[edx+ebx],[esi+ebx] ), \ - KALUDSS4( ALUOP, [edi+ebx],[edx+ebx],[esi+ebx] ), COUNT ) - - -#define DRAWVERT_SIZE 60 -#define DRAWVERT_XYZ_OFFSET (0*4) -#define DRAWVERT_ST_OFFSET (3*4) -#define DRAWVERT_NORMAL_OFFSET (5*4) -#define DRAWVERT_TANGENT0_OFFSET (8*4) -#define DRAWVERT_TANGENT1_OFFSET (11*4) -#define DRAWVERT_COLOR_OFFSET (14*4) - -#define JOINTQUAT_SIZE (7*4) -#define JOINTMAT_SIZE (4*3*4) -#define JOINTWEIGHT_SIZE (4*4) - - -#define ALIGN4_INIT1( X, INIT ) ALIGN16( static X[4] ) = { INIT, INIT, INIT, INIT } -#define ALIGN4_INIT4( X, I0, I1, I2, I3 ) ALIGN16( static X[4] ) = { I0, I1, I2, I3 } -#define ALIGN8_INIT1( X, INIT ) ALIGN16( static X[8] ) = { INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT } - -ALIGN8_INIT1( unsigned short SIMD_W_zero, 0 ); -ALIGN8_INIT1( unsigned short SIMD_W_maxShort, 1<<15 ); - -ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle0, (3<<0)|(2<<8)|(1<<16)|(0<<24) ); -ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle1, (0<<0)|(1<<8)|(2<<16)|(3<<24) ); -ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle2, (1<<0)|(0<<8)|(3<<16)|(2<<24) ); -ALIGN4_INIT1( unsigned long SIMD_DW_mat2quatShuffle3, (2<<0)|(3<<8)|(0<<16)|(1<<24) ); - -ALIGN4_INIT4( unsigned long SIMD_SP_singleSignBitMask, (unsigned long) ( 1 << 31 ), 0, 0, 0 ); -ALIGN4_INIT1( unsigned long SIMD_SP_signBitMask, (unsigned long) ( 1 << 31 ) ); -ALIGN4_INIT1( unsigned long SIMD_SP_absMask, (unsigned long) ~( 1 << 31 ) ); -ALIGN4_INIT1( unsigned long SIMD_SP_infinityMask, (unsigned long) ~( 1 << 23 ) ); -ALIGN4_INIT1( unsigned long SIMD_SP_not, 0xFFFFFFFF ); - -ALIGN4_INIT1( float SIMD_SP_zero, 0.0f ); -ALIGN4_INIT1( float SIMD_SP_half, 0.5f ); -ALIGN4_INIT1( float SIMD_SP_one, 1.0f ); -ALIGN4_INIT1( float SIMD_SP_two, 2.0f ); -ALIGN4_INIT1( float SIMD_SP_three, 3.0f ); -ALIGN4_INIT1( float SIMD_SP_four, 4.0f ); -ALIGN4_INIT1( float SIMD_SP_maxShort, (1<<15) ); -ALIGN4_INIT1( float SIMD_SP_tiny, 1e-10f ); -ALIGN4_INIT1( float SIMD_SP_PI, idMath::PI ); -ALIGN4_INIT1( float SIMD_SP_halfPI, idMath::HALF_PI ); -ALIGN4_INIT1( float SIMD_SP_twoPI, idMath::TWO_PI ); -ALIGN4_INIT1( float SIMD_SP_oneOverTwoPI, 1.0f / idMath::TWO_PI ); -ALIGN4_INIT1( float SIMD_SP_infinity, idMath::INFINITY ); -ALIGN4_INIT4( float SIMD_SP_lastOne, 0.0f, 0.0f, 0.0f, 1.0f ); - -ALIGN4_INIT1( float SIMD_SP_rsqrt_c0, 3.0f ); -ALIGN4_INIT1( float SIMD_SP_rsqrt_c1, -0.5f ); -ALIGN4_INIT1( float SIMD_SP_mat2quat_rsqrt_c1, -0.5f*0.5f ); - -ALIGN4_INIT1( float SIMD_SP_sin_c0, -2.39e-08f ); -ALIGN4_INIT1( float SIMD_SP_sin_c1, 2.7526e-06f ); -ALIGN4_INIT1( float SIMD_SP_sin_c2, -1.98409e-04f ); -ALIGN4_INIT1( float SIMD_SP_sin_c3, 8.3333315e-03f ); -ALIGN4_INIT1( float SIMD_SP_sin_c4, -1.666666664e-01f ); - -ALIGN4_INIT1( float SIMD_SP_cos_c0, -2.605e-07f ); -ALIGN4_INIT1( float SIMD_SP_cos_c1, 2.47609e-05f ); -ALIGN4_INIT1( float SIMD_SP_cos_c2, -1.3888397e-03f ); -ALIGN4_INIT1( float SIMD_SP_cos_c3, 4.16666418e-02f ); -ALIGN4_INIT1( float SIMD_SP_cos_c4, -4.999999963e-01f ); - -ALIGN4_INIT1( float SIMD_SP_atan_c0, 0.0028662257f ); -ALIGN4_INIT1( float SIMD_SP_atan_c1, -0.0161657367f ); -ALIGN4_INIT1( float SIMD_SP_atan_c2, 0.0429096138f ); -ALIGN4_INIT1( float SIMD_SP_atan_c3, -0.0752896400f ); -ALIGN4_INIT1( float SIMD_SP_atan_c4, 0.1065626393f ); -ALIGN4_INIT1( float SIMD_SP_atan_c5, -0.1420889944f ); -ALIGN4_INIT1( float SIMD_SP_atan_c6, 0.1999355085f ); -ALIGN4_INIT1( float SIMD_SP_atan_c7, -0.3333314528f ); - -/* -============ -SSE_InvSqrt -============ -*/ -float SSE_InvSqrt( float x ) { - float y; - - __asm { - movss xmm0, x - rsqrtss xmm1, xmm0 - mulss xmm0, xmm1 - mulss xmm0, xmm1 - subss xmm0, SIMD_SP_rsqrt_c0 - mulss xmm1, SIMD_SP_rsqrt_c1 - mulss xmm0, xmm1 - movss y, xmm0 - } - return y; -} - -/* -============ -SSE_InvSqrt4 -============ -*/ -void SSE_InvSqrt4( float x[4] ) { - __asm { - mov edi, x - movaps xmm0, [edi] - rsqrtps xmm1, xmm0 - mulps xmm0, xmm1 - mulps xmm0, xmm1 - subps xmm0, SIMD_SP_rsqrt_c0 - mulps xmm1, SIMD_SP_rsqrt_c1 - mulps xmm0, xmm1 - movaps [edi], xmm0 - } -} - -/* -============ -SSE_SinZeroHalfPI - - The angle must be between zero and half PI. -============ -*/ -float SSE_SinZeroHalfPI( float a ) { -#if 1 - - float t; - - assert( a >= 0.0f && a <= idMath::HALF_PI ); - - __asm { - movss xmm0, a - movss xmm1, xmm0 - mulss xmm1, xmm1 - movss xmm2, SIMD_SP_sin_c0 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c1 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c2 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c3 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c4 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_one - mulss xmm2, xmm0 - movss t, xmm2 - } - - return t; - -#else - - float s, t; - - assert( a >= 0.0f && a <= idMath::HALF_PI ); - - s = a * a; - t = -2.39e-08f; - t *= s; - t += 2.7526e-06f; - t *= s; - t += -1.98409e-04f; - t *= s; - t += 8.3333315e-03f; - t *= s; - t += -1.666666664e-01f; - t *= s; - t += 1.0f; - t *= a; - - return t; - -#endif -} - -/* -============ -SSE_Sin4ZeroHalfPI - - The angle must be between zero and half PI. -============ -*/ -void SSE_Sin4ZeroHalfPI( float a[4], float s[4] ) { - __asm { - mov edi, a - mov esi, s - movaps xmm0, [edi] - movaps xmm1, xmm0 - mulps xmm1, xmm1 - movaps xmm2, SIMD_SP_sin_c0 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c1 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c2 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c3 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c4 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_one - mulps xmm2, xmm0 - movaps [esi], xmm2 - } -} - -/* -============ -SSE_Sin -============ -*/ -float SSE_Sin( float a ) { -#if 1 - - float t; - - __asm { - movss xmm1, a - movss xmm2, xmm1 - movss xmm3, xmm1 - mulss xmm2, SIMD_SP_oneOverTwoPI - cvttss2si ecx, xmm2 - cmpltss xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - cvtsi2ss xmm2, ecx - subss xmm2, xmm3 - mulss xmm2, SIMD_SP_twoPI - subss xmm1, xmm2 - - movss xmm0, SIMD_SP_PI // xmm0 = PI - subss xmm0, xmm1 // xmm0 = PI - a - movss xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movss xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movss xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - movss xmm1, xmm0 - mulss xmm1, xmm1 - movss xmm2, SIMD_SP_sin_c0 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c1 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c2 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c3 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_sin_c4 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_one - mulss xmm2, xmm0 - movss t, xmm2 - } - - return t; - -#else - - float s, t; - - if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { - a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; - } - - a = idMath::PI - a; - if ( fabs( a ) >= idMath::HALF_PI ) { - a = ( ( a < 0.0f ) ? -idMath::PI : idMath::PI ) - a; - } - - s = a * a; - t = -2.39e-08f; - t *= s; - t += 2.7526e-06f; - t *= s; - t += -1.98409e-04f; - t *= s; - t += 8.3333315e-03f; - t *= s; - t += -1.666666664e-01f; - t *= s; - t += 1.0f; - t *= a; - - return t; - -#endif -} - -/* -============ -SSE_Sin4 -============ -*/ -void SSE_Sin4( float a[4], float s[4] ) { - __asm { - mov edi, a - mov esi, s - movaps xmm1, [edi] - movaps xmm2, xmm1 - mulps xmm2, SIMD_SP_oneOverTwoPI - movhlps xmm3, xmm2 - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) - movaps xmm3, xmm1 - cmpltps xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - subps xmm2, xmm3 - mulps xmm2, SIMD_SP_twoPI - subps xmm1, xmm2 - - movaps xmm0, SIMD_SP_PI // xmm0 = PI - subps xmm0, xmm1 // xmm0 = PI - a - movaps xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movaps xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movaps xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - movaps xmm1, xmm0 - mulps xmm1, xmm1 - movaps xmm2, SIMD_SP_sin_c0 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c1 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c2 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c3 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_sin_c4 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_one - mulps xmm2, xmm0 - movaps [esi], xmm2 - } -} - -/* -============ -SSE_CosZeroHalfPI - - The angle must be between zero and half PI. -============ -*/ -float SSE_CosZeroHalfPI( float a ) { -#if 1 - - float t; - - assert( a >= 0.0f && a <= idMath::HALF_PI ); - - __asm { - movss xmm0, a - mulss xmm0, xmm0 - movss xmm1, SIMD_SP_cos_c0 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c1 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c2 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c3 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c4 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_one - movss t, xmm1 - } - - return t; - -#else - - float s, t; - - assert( a >= 0.0f && a <= idMath::HALF_PI ); - - s = a * a; - t = -2.605e-07f; - t *= s; - t += 2.47609e-05f; - t *= s; - t += -1.3888397e-03f; - t *= s; - t += 4.16666418e-02f; - t *= s; - t += -4.999999963e-01f; - t *= s; - t += 1.0f; - - return t; - -#endif -} - -/* -============ -SSE_Cos4ZeroHalfPI - - The angle must be between zero and half PI. -============ -*/ -void SSE_Cos4ZeroHalfPI( float a[4], float c[4] ) { - __asm { - mov edi, a - mov esi, c - movaps xmm0, [edi] - mulps xmm0, xmm0 - movaps xmm1, SIMD_SP_cos_c0 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c1 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c2 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c3 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c4 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_one - movaps [esi], xmm2 - } -} - -/* -============ -SSE_Cos -============ -*/ -float SSE_Cos( float a ) { -#if 1 - - float t; - - __asm { - movss xmm1, a - movss xmm2, xmm1 - movss xmm3, xmm1 - mulss xmm2, SIMD_SP_oneOverTwoPI - cvttss2si ecx, xmm2 - cmpltss xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - cvtsi2ss xmm2, ecx - subss xmm2, xmm3 - mulss xmm2, SIMD_SP_twoPI - subss xmm1, xmm2 - - movss xmm0, SIMD_SP_PI // xmm0 = PI - subss xmm0, xmm1 // xmm0 = PI - a - movss xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movss xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movss xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - mulss xmm0, xmm0 - movss xmm1, SIMD_SP_cos_c0 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c1 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c2 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c3 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_cos_c4 - mulss xmm1, xmm0 - addss xmm1, SIMD_SP_one - xorps xmm2, SIMD_SP_signBitMask - xorps xmm1, xmm2 - movss t, xmm1 - } - - return t; - -#else - - float s, t; - - if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) { - a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI; - } - - a = idMath::PI - a; - if ( fabs( a ) >= idMath::HALF_PI ) { - a = ( ( a < 0.0f ) ? -idMath::PI : idMath::PI ) - a; - d = 1.0f; - } else { - d = -1.0f; - } - - s = a * a; - t = -2.605e-07f; - t *= s; - t += 2.47609e-05f; - t *= s; - t += -1.3888397e-03f; - t *= s; - t += 4.16666418e-02f; - t *= s; - t += -4.999999963e-01f; - t *= s; - t += 1.0f; - t *= d; - - return t; - -#endif -} - -/* -============ -SSE_Cos4 -============ -*/ -void SSE_Cos4( float a[4], float c[4] ) { - __asm { - mov edi, a - mov esi, c - movaps xmm1, [edi] - movaps xmm2, xmm1 - mulps xmm2, SIMD_SP_oneOverTwoPI - movhlps xmm3, xmm2 - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) - movaps xmm3, xmm1 - cmpltps xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - subps xmm2, xmm3 - mulps xmm2, SIMD_SP_twoPI - subps xmm1, xmm2 - - movaps xmm0, SIMD_SP_PI // xmm0 = PI - subps xmm0, xmm1 // xmm0 = PI - a - movaps xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movaps xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movaps xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - mulps xmm0, xmm0 - movaps xmm1, SIMD_SP_cos_c0 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c1 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c2 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c3 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_cos_c4 - mulps xmm1, xmm0 - addps xmm1, SIMD_SP_one - xorps xmm2, SIMD_SP_signBitMask - xorps xmm1, xmm2 - movaps [esi], xmm1 - } -} - -/* -============ -SSE_SinCos -============ -*/ -void SSE_SinCos( float a, float &s, float &c ) { - __asm { - mov edi, s - mov esi, c - movss xmm1, a - movss xmm2, xmm1 - movss xmm3, xmm1 - mulss xmm2, SIMD_SP_oneOverTwoPI - cvttss2si ecx, xmm2 - cmpltss xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - cvtsi2ss xmm2, ecx - subss xmm2, xmm3 - mulss xmm2, SIMD_SP_twoPI - subss xmm1, xmm2 - - movss xmm0, SIMD_SP_PI // xmm0 = PI - subss xmm0, xmm1 // xmm0 = PI - a - movss xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movss xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltss xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movss xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - movss xmm1, xmm0 - mulss xmm1, xmm1 - movss xmm3, SIMD_SP_sin_c0 - movss xmm4, SIMD_SP_cos_c0 - mulss xmm3, xmm1 - mulss xmm4, xmm1 - addss xmm3, SIMD_SP_sin_c1 - addss xmm4, SIMD_SP_cos_c1 - mulss xmm3, xmm1 - mulss xmm4, xmm1 - addss xmm3, SIMD_SP_sin_c2 - addss xmm4, SIMD_SP_cos_c2 - mulss xmm3, xmm1 - mulss xmm4, xmm1 - addss xmm3, SIMD_SP_sin_c3 - addss xmm4, SIMD_SP_cos_c3 - mulss xmm3, xmm1 - mulss xmm4, xmm1 - addss xmm3, SIMD_SP_sin_c4 - addss xmm4, SIMD_SP_cos_c4 - mulss xmm3, xmm1 - mulss xmm4, xmm1 - addss xmm3, SIMD_SP_one - addss xmm4, SIMD_SP_one - mulss xmm3, xmm0 - xorps xmm2, SIMD_SP_signBitMask - xorps xmm4, xmm2 - movss [edi], xmm2 - movss [esi], xmm3 - } -} - -/* -============ -SSE_SinCos4 -============ -*/ -void SSE_SinCos4( float a[4], float s[4], float c[4] ) { - __asm { - mov eax, a - mov edi, s - mov esi, c - movaps xmm1, [eax] - movaps xmm2, xmm1 - mulps xmm2, SIMD_SP_oneOverTwoPI - movhlps xmm3, xmm2 - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 0, 0, 0 ) - cvttss2si ecx, xmm2 - cvtsi2ss xmm2, ecx - cvttss2si edx, xmm3 - cvtsi2ss xmm3, edx - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 0, 1, 0 ) - movaps xmm3, xmm1 - cmpltps xmm3, SIMD_SP_zero - andps xmm3, SIMD_SP_one - subps xmm2, xmm3 - mulps xmm2, SIMD_SP_twoPI - subps xmm1, xmm2 - - movaps xmm0, SIMD_SP_PI // xmm0 = PI - subps xmm0, xmm1 // xmm0 = PI - a - movaps xmm1, xmm0 // xmm1 = PI - a - andps xmm1, SIMD_SP_signBitMask // xmm1 = signbit( PI - a ) - movaps xmm2, xmm0 // xmm2 = PI - a - xorps xmm2, xmm1 // xmm2 = fabs( PI - a ) - cmpnltps xmm2, SIMD_SP_halfPI // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? 0xFFFFFFFF : 0x00000000 - movaps xmm3, SIMD_SP_PI // xmm3 = PI - xorps xmm3, xmm1 // xmm3 = PI ^ signbit( PI - a ) - andps xmm3, xmm2 // xmm3 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? ( PI ^ signbit( PI - a ) ) : 0.0f - andps xmm2, SIMD_SP_signBitMask // xmm2 = ( fabs( PI - a ) >= idMath::HALF_PI ) ? SIMD_SP_signBitMask : 0.0f - xorps xmm0, xmm2 - addps xmm0, xmm3 - - movaps xmm0, [eax] - movaps xmm1, xmm0 - mulps xmm1, xmm1 - movaps xmm3, SIMD_SP_sin_c0 - movaps xmm4, SIMD_SP_cos_c0 - mulps xmm3, xmm1 - mulps xmm4, xmm1 - addps xmm3, SIMD_SP_sin_c1 - addps xmm4, SIMD_SP_cos_c1 - mulps xmm3, xmm1 - mulps xmm4, xmm1 - addps xmm3, SIMD_SP_sin_c2 - addps xmm4, SIMD_SP_cos_c2 - mulps xmm3, xmm1 - mulps xmm4, xmm1 - addps xmm3, SIMD_SP_sin_c3 - addps xmm4, SIMD_SP_cos_c3 - mulps xmm3, xmm1 - mulps xmm4, xmm1 - addps xmm3, SIMD_SP_sin_c4 - addps xmm4, SIMD_SP_cos_c4 - mulps xmm3, xmm1 - mulps xmm4, xmm1 - addps xmm3, SIMD_SP_one - addps xmm4, SIMD_SP_one - mulps xmm3, xmm0 - xorps xmm2, SIMD_SP_signBitMask - xorps xmm4, xmm2 - movaps [edi], xmm3 - movaps [esi], xmm4 - } -} - -/* -============ -SSE_ATanPositive - - Both 'x' and 'y' must be positive. -============ -*/ -float SSE_ATanPositive( float y, float x ) { -#if 1 - - float t; - - assert( y >= 0.0f && x >= 0.0f ); - - __asm { - movss xmm0, x - movss xmm3, xmm0 - movss xmm1, y - minss xmm0, xmm1 - maxss xmm1, xmm3 - cmpeqss xmm3, xmm0 - rcpss xmm2, xmm1 - mulss xmm1, xmm2 - mulss xmm1, xmm2 - addss xmm2, xmm2 - subss xmm2, xmm1 // xmm2 = 1 / y or 1 / x - mulss xmm0, xmm2 // xmm0 = x / y or y / x - movss xmm1, xmm3 - andps xmm1, SIMD_SP_signBitMask - xorps xmm0, xmm1 // xmm0 = -x / y or y / x - andps xmm3, SIMD_SP_halfPI // xmm3 = HALF_PI or 0.0f - movss xmm1, xmm0 - mulss xmm1, xmm1 // xmm1 = s - movss xmm2, SIMD_SP_atan_c0 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c1 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c2 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c3 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c4 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c5 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c6 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c7 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_one - mulss xmm2, xmm0 - addss xmm2, xmm3 - movss t, xmm2 - } - - return t; - -#else - - float a, d, s, t; - - assert( y >= 0.0f && x >= 0.0f ); - - if ( y > x ) { - a = -x / y; - d = idMath::HALF_PI; - } else { - a = y / x; - d = 0.0f; - } - s = a * a; - t = 0.0028662257f; - t *= s; - t += -0.0161657367f; - t *= s; - t += 0.0429096138f; - t *= s; - t += -0.0752896400f; - t *= s; - t += 0.1065626393f; - t *= s; - t += -0.1420889944f; - t *= s; - t += 0.1999355085f; - t *= s; - t += -0.3333314528f; - t *= s; - t += 1.0f; - t *= a; - t += d; - - return t; - -#endif -} - -/* -============ -SSE_ATan4Positive - - Both 'x' and 'y' must be positive. -============ -*/ -void SSE_ATan4Positive( float y[4], float x[4], float at[4] ) { - __asm { - mov esi, x - mov edi, y - mov edx, at - movaps xmm0, [esi] - movaps xmm3, xmm0 - movaps xmm1, [edi] - minps xmm0, xmm1 - maxps xmm1, xmm3 - cmpeqps xmm3, xmm0 - rcpps xmm2, xmm1 - mulps xmm1, xmm2 - mulps xmm1, xmm2 - addps xmm2, xmm2 - subps xmm2, xmm1 // xmm2 = 1 / y or 1 / x - mulps xmm0, xmm2 // xmm0 = x / y or y / x - movaps xmm1, xmm3 - andps xmm1, SIMD_SP_signBitMask - xorps xmm0, xmm1 // xmm0 = -x / y or y / x - andps xmm3, SIMD_SP_halfPI // xmm3 = HALF_PI or 0.0f - movaps xmm1, xmm0 - mulps xmm1, xmm1 // xmm1 = s - movaps xmm2, SIMD_SP_atan_c0 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c1 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c2 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c3 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c4 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c5 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c6 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c7 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_one - mulps xmm2, xmm0 - addps xmm2, xmm3 - movaps [edx], xmm2 - } -} - -/* -============ -SSE_ATan -============ -*/ -float SSE_ATan( float y, float x ) { -#if 1 - - float t; - - __asm { - movss xmm0, x - movss xmm3, xmm0 - movss xmm4, xmm0 - andps xmm0, SIMD_SP_absMask - movss xmm1, y - xorps xmm4, xmm1 - andps xmm1, SIMD_SP_absMask - andps xmm4, SIMD_SP_signBitMask - minss xmm0, xmm1 - maxss xmm1, xmm3 - cmpeqss xmm3, xmm0 - rcpss xmm2, xmm1 - mulss xmm1, xmm2 - mulss xmm1, xmm2 - addss xmm2, xmm2 - subss xmm2, xmm1 // xmm2 = 1 / y or 1 / x - mulss xmm0, xmm2 // xmm0 = x / y or y / x - xorps xmm0, xmm4 - movss xmm1, xmm3 - andps xmm1, SIMD_SP_signBitMask - xorps xmm0, xmm1 // xmm0 = -x / y or y / x - orps xmm4, SIMD_SP_halfPI // xmm4 = +/- HALF_PI - andps xmm3, xmm4 // xmm3 = +/- HALF_PI or 0.0f - movss xmm1, xmm0 - mulss xmm1, xmm1 // xmm1 = s - movss xmm2, SIMD_SP_atan_c0 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c1 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c2 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c3 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c4 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c5 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c6 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_atan_c7 - mulss xmm2, xmm1 - addss xmm2, SIMD_SP_one - mulss xmm2, xmm0 - addss xmm2, xmm3 - movss t, xmm2 - } - - return t; - -#else - - float a, d, s, t; - - if ( fabs( y ) > fabs( x ) ) { - a = -x / y; - d = idMath::HALF_PI; - *((unsigned long *)&d) ^= ( *((unsigned long *)&x) ^ *((unsigned long *)&y) ) & (1<<31); - } else { - a = y / x; - d = 0.0f; - } - - s = a * a; - t = 0.0028662257f; - t *= s; - t += -0.0161657367f; - t *= s; - t += 0.0429096138f; - t *= s; - t += -0.0752896400f; - t *= s; - t += 0.1065626393f; - t *= s; - t += -0.1420889944f; - t *= s; - t += 0.1999355085f; - t *= s; - t += -0.3333314528f; - t *= s; - t += 1.0f; - t *= a; - t += d; - - return t; - -#endif -} - -/* -============ -SSE_ATan4 -============ -*/ -void SSE_ATan4( float y[4], float x[4], float at[4] ) { - __asm { - mov esi, x - mov edi, y - mov edx, at - movaps xmm0, [esi] - movaps xmm3, xmm0 - movaps xmm4, xmm0 - andps xmm0, SIMD_SP_absMask - movaps xmm1, [edi] - xorps xmm4, xmm1 - andps xmm1, SIMD_SP_absMask - andps xmm4, SIMD_SP_signBitMask - minps xmm0, xmm1 - maxps xmm1, xmm3 - cmpeqps xmm3, xmm0 - rcpps xmm2, xmm1 - mulps xmm1, xmm2 - mulps xmm1, xmm2 - addps xmm2, xmm2 - subps xmm2, xmm1 // xmm2 = 1 / y or 1 / x - mulps xmm0, xmm2 // xmm0 = x / y or y / x - xorps xmm0, xmm4 - movaps xmm1, xmm3 - andps xmm1, SIMD_SP_signBitMask - xorps xmm0, xmm1 // xmm0 = -x / y or y / x - orps xmm4, SIMD_SP_halfPI // xmm4 = +/- HALF_PI - andps xmm3, xmm4 // xmm3 = +/- HALF_PI or 0.0f - movaps xmm1, xmm0 - mulps xmm1, xmm1 // xmm1 = s - movaps xmm2, SIMD_SP_atan_c0 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c1 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c2 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c3 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c4 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c5 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c6 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_atan_c7 - mulps xmm2, xmm1 - addps xmm2, SIMD_SP_one - mulps xmm2, xmm0 - addps xmm2, xmm3 - movaps [edx], xmm2 - } -} - -/* -============ -SSE_TestTrigonometry -============ -*/ -void SSE_TestTrigonometry( void ) { - int i; - float a, s1, s2, c1, c2; - - for ( i = 0; i < 100; i++ ) { - a = i * idMath::HALF_PI / 100.0f; - - s1 = sin( a ); - s2 = SSE_SinZeroHalfPI( a ); - - if ( fabs( s1 - s2 ) > 1e-7f ) { - assert( 0 ); - } - - c1 = cos( a ); - c2 = SSE_CosZeroHalfPI( a ); - - if ( fabs( c1 - c2 ) > 1e-7f ) { - assert( 0 ); - } - } - - for ( i = -200; i < 200; i++ ) { - a = i * idMath::TWO_PI / 100.0f; - - s1 = sin( a ); - s2 = SSE_Sin( a ); - - if ( fabs( s1 - s2 ) > 1e-6f ) { - assert( 0 ); - } - - c1 = cos( a ); - c2 = SSE_Cos( a ); - - if ( fabs( c1 - c2 ) > 1e-6f ) { - assert( 0 ); - } - - SSE_SinCos( a, s2, c2 ); - if ( fabs( s1 - s2 ) > 1e-6f || fabs( c1 - c2 ) > 1e-6f ) { - assert( 0 ); - } - } -} - -/* -============ -idSIMD_SSE::GetName -============ -*/ -const char * idSIMD_SSE::GetName( void ) const { - return "MMX & SSE"; -} - -/* -============ -idSIMD_SSE::Add - - dst[i] = constant + src[i]; -============ -*/ -void VPCALL idSIMD_SSE::Add( float *dst, const float constant, const float *src, const int count ) { - KFLOAT_CA( add, dst, src, constant, count ) -} - -/* -============ -idSIMD_SSE::Add - - dst[i] = src0[i] + src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::Add( float *dst, const float *src0, const float *src1, const int count ) { - KFLOAT_AA( add, dst, src0, src1, count ) -} - -/* -============ -idSIMD_SSE::Sub - - dst[i] = constant - src[i]; -============ -*/ -void VPCALL idSIMD_SSE::Sub( float *dst, const float constant, const float *src, const int count ) { - KFLOAT_CA( sub, dst, src, constant, count ) -} - -/* -============ -idSIMD_SSE::Sub - - dst[i] = src0[i] - src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::Sub( float *dst, const float *src0, const float *src1, const int count ) { - KFLOAT_AA( sub, dst, src0, src1, count ) -} - -/* -============ -idSIMD_SSE::Mul - - dst[i] = constant * src[i]; -============ -*/ -void VPCALL idSIMD_SSE::Mul( float *dst, const float constant, const float *src, const int count ) { - KFLOAT_CA( mul, dst, src, constant, count ) -} - -/* -============ -idSIMD_SSE::Mul - - dst[i] = src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::Mul( float *dst, const float *src0, const float *src1, const int count ) { - KFLOAT_AA( mul, dst, src0, src1, count ) -} - -/* -============ -idSIMD_SSE::Div - - dst[i] = constant / src[i]; -============ -*/ -void VPCALL idSIMD_SSE::Div( float *dst, const float constant, const float *src, const int count ) { - int pre, post; - - // 1 / x = 2 * rcpps(x) - (x * rcpps(x) * rcpps(x)); - __asm - { - movss xmm1,constant - shufps xmm1,xmm1,0 - - KFLOATINITDS( dst, src, count, pre, post ) - and eax,15 - jne lpNA - jmp lpA - align 16 -lpA: - movaps xmm2,[edx+ebx] - movaps xmm3,[edx+ebx+16] - rcpps xmm4,xmm2 - rcpps xmm5,xmm3 - prefetchnta [edx+ebx+64] - mulps xmm2,xmm4 - mulps xmm2,xmm4 - mulps xmm3,xmm5 - mulps xmm3,xmm5 - addps xmm4,xmm4 - addps xmm5,xmm5 - subps xmm4,xmm2 - subps xmm5,xmm3 - mulps xmm4,xmm1 - mulps xmm5,xmm1 - movaps [edi+ebx],xmm4 - movaps [edi+ebx+16],xmm5 - add ebx,16*2 - jl lpA - jmp done - align 16 -lpNA: - movups xmm2,[edx+ebx] - movups xmm3,[edx+ebx+16] - rcpps xmm4,xmm2 - rcpps xmm5,xmm3 - prefetchnta [edx+ebx+64] - mulps xmm2,xmm4 - mulps xmm2,xmm4 - mulps xmm3,xmm5 - mulps xmm3,xmm5 - addps xmm4,xmm4 - addps xmm5,xmm5 - subps xmm4,xmm2 - subps xmm5,xmm3 - mulps xmm4,xmm1 - mulps xmm5,xmm1 - movaps [edi+ebx],xmm4 - movaps [edi+ebx+16],xmm5 - add ebx,16*2 - jl lpNA -done: - mov edx,src - mov edi,dst - KFLOATOPER( KDIVDSS1( [edi+ebx],xmm1,[edx+ebx] ), - KDIVDSS4( [edi+ebx],xmm1,[edx+ebx] ), count ) - } -} - -/* -============ -idSIMD_SSE::Div - - dst[i] = src0[i] / src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::Div( float *dst, const float *src0, const float *src1, const int count ) { - int pre,post; - - // 1 / x = 2 * rcpps(x) - (x * rcpps(x) * rcpps(x)); - __asm - { - KFLOATINITDSS( dst, src0, src1, count, pre, post ) - and eax,15 - jne lpNA - jmp lpA - align 16 -lpA: - movaps xmm2,[esi+ebx] - movaps xmm3,[esi+ebx+16] - rcpps xmm4,xmm2 - rcpps xmm5,xmm3 - prefetchnta [esi+ebx+64] - mulps xmm2,xmm4 - mulps xmm2,xmm4 - mulps xmm3,xmm5 - mulps xmm3,xmm5 - addps xmm4,xmm4 - addps xmm5,xmm5 - subps xmm4,xmm2 - subps xmm5,xmm3 - mulps xmm4,[edx+ebx] - mulps xmm5,[edx+ebx+16] - movaps [edi+ebx],xmm4 - movaps [edi+ebx+16],xmm5 - add ebx,16*2 - jl lpA - jmp done - align 16 -lpNA: - movups xmm2,[esi+ebx] - movups xmm3,[esi+ebx+16] - rcpps xmm4,xmm2 - rcpps xmm5,xmm3 - prefetchnta [esi+ebx+64] - mulps xmm2,xmm4 - mulps xmm2,xmm4 - mulps xmm3,xmm5 - mulps xmm3,xmm5 - addps xmm4,xmm4 - addps xmm5,xmm5 - subps xmm4,xmm2 - subps xmm5,xmm3 - movups xmm2,[edx+ebx] - movups xmm3,[edx+ebx+16] - mulps xmm4,xmm2 - mulps xmm5,xmm3 - movaps [edi+ebx],xmm4 - movaps [edi+ebx+16],xmm5 - add ebx,16*2 - jl lpNA -done: - mov edx,src0 - mov esi,src1 - mov edi,dst - KFLOATOPER( KDIVDSS1( [edi+ebx],[edx+ebx],[esi+ebx] ), - KDIVDSS4( [edi+ebx],[edx+ebx],[esi+ebx] ), count ) - } -} -/* -============ -Simd_MulAdd - - assumes count >= 7 -============ -*/ -static void Simd_MulAdd( float *dst, const float constant, const float *src, const int count ) { - __asm mov esi, dst - __asm mov edi, src - __asm mov eax, count - __asm shl eax, 2 - __asm mov ecx, esi - __asm mov edx, eax - __asm or ecx, edi - __asm fld constant - __asm and ecx, 15 - __asm jz SimdMulAdd16 - __asm and ecx, 3 - __asm jnz SimdMulAdd8 - __asm mov ecx, esi - __asm xor ecx, edi - __asm and ecx, 15 - __asm jnz MulAdd8 - __asm mov ecx, esi - __asm and ecx, 15 - __asm neg ecx - __asm add ecx, 16 - __asm sub eax, ecx - __asm add edi, ecx - __asm add esi, ecx - __asm neg ecx - __asm mov edx, eax - __asm loopPreMulAdd16: - __asm fld st - __asm fmul dword ptr [edi+ecx] - __asm fadd dword ptr [esi+ecx] - __asm fstp dword ptr [esi+ecx] - __asm add ecx, 4 - __asm jl loopPreMulAdd16 - __asm SimdMulAdd16: - __asm and eax, ~15 - __asm movss xmm1, constant - __asm shufps xmm1, xmm1, 0x00 - __asm add esi, eax - __asm add edi, eax - __asm neg eax - __asm align 16 - __asm loopMulAdd16: - __asm movaps xmm0, [edi+eax] - __asm mulps xmm0, xmm1 - __asm addps xmm0, [esi+eax] - __asm movaps [esi+eax], xmm0 - __asm add eax, 16 - __asm jl loopMulAdd16 - __asm jmp postMulAdd - __asm MulAdd8: - __asm mov ecx, esi - __asm and ecx, 7 - __asm jz SimdMulAdd8 - __asm sub eax, ecx - __asm add esi, ecx - __asm add edi, ecx - __asm neg ecx - __asm mov edx, eax - __asm loopPreMulAdd8: - __asm fld st - __asm fmul dword ptr [edi+ecx] - __asm fadd dword ptr [esi+ecx] - __asm fstp dword ptr [esi+ecx] - __asm add ecx, 4 - __asm jl loopPreMulAdd8 - __asm SimdMulAdd8: - __asm and eax, ~15 - __asm movss xmm1, constant - __asm shufps xmm1, xmm1, 0x00 - __asm add esi, eax - __asm add edi, eax - __asm neg eax - __asm align 16 - __asm loopMulAdd8: - __asm movlps xmm0, [edi+eax] - __asm movhps xmm0, [edi+eax+8] - __asm mulps xmm0, xmm1 - __asm movlps xmm2, [esi+eax] - __asm movhps xmm2, [esi+eax+8] - __asm addps xmm0, xmm2 - __asm movlps [esi+eax], xmm0 - __asm movhps [esi+eax+8], xmm0 - __asm add eax, 16 - __asm jl loopMulAdd8 - __asm jmp postMulAdd - __asm postMulAdd: - __asm and edx, 15 - __asm jz MulAddDone - __asm add esi, edx - __asm add edi, edx - __asm neg edx - __asm loopPostMulAdd: - __asm fld st - __asm fmul dword ptr [edi+edx] - __asm fadd dword ptr [esi+edx] - __asm fstp dword ptr [esi+edx] - __asm add edx, 4 - __asm jl loopPostMulAdd - __asm MulAddDone: - __asm fstp st -} - -#define MULADD_FEW( OPER ) \ -switch( count ) { \ - case 0: \ - return; \ - case 1: \ - dst[0] OPER c * src[0]; \ - return; \ - case 2: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; \ - return; \ - case 3: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; \ - return; \ - case 4: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - return; \ - case 5: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; \ - return; \ - case 6: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; \ - return; \ - case 7: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; \ - return; \ - case 8: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ - return; \ - case 9: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ - dst[8] OPER c * src[8]; \ - return; \ - case 10: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ - dst[8] OPER c * src[8]; dst[9] OPER c * src[9]; \ - return; \ - case 11: \ - dst[0] OPER c * src[0]; dst[1] OPER c * src[1]; dst[2] OPER c * src[2]; dst[3] OPER c * src[3]; \ - dst[4] OPER c * src[4]; dst[5] OPER c * src[5]; dst[6] OPER c * src[6]; dst[7] OPER c * src[7]; \ - dst[8] OPER c * src[8]; dst[9] OPER c * src[9]; dst[10] OPER c * src[10]; \ - return; \ -} - -/* -============ -idSIMD_SSE::MulAdd - - dst[i] += constant * src[i]; -============ -*/ -void VPCALL idSIMD_SSE::MulAdd( float *dst, const float constant, const float *src, const int count ) { - float c = constant; - MULADD_FEW( += ) - Simd_MulAdd( dst, constant, src, count ); -} - -/* -============ -idSIMD_SSE::MulAdd - - dst[i] += src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::MulAdd( float *dst, const float *src0, const float *src1, const int count ) { - for ( int i = 0; i < count; i++ ) { - dst[i] += src0[i] + src1[i]; - } -} - -/* -============ -idSIMD_SSE::MulSub - - dst[i] -= constant * src[i]; -============ -*/ -void VPCALL idSIMD_SSE::MulSub( float *dst, const float constant, const float *src, const int count ) { - float c = constant; - MULADD_FEW( -= ) - Simd_MulAdd( dst, -constant, src, count ); -} - -/* -============ -idSIMD_SSE::MulSub - - dst[i] -= src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::MulSub( float *dst, const float *src0, const float *src1, const int count ) { - for ( int i = 0; i < count; i++ ) { - dst[i] -= src0[i] + src1[i]; - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant * src[i]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ) { - __asm - { - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - - movss xmm4, [edi+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [edi+4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - - jz done4 - imul eax, 12 - add esi, eax - neg eax - - loop4: - movlps xmm1, [esi+eax+ 0] - movlps xmm2, [esi+eax+ 8] - movlps xmm3, [esi+eax+16] - movhps xmm1, [esi+eax+24] - movhps xmm2, [esi+eax+32] - movhps xmm3, [esi+eax+40] - movaps xmm0, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) - shufps xmm1, xmm3, R_SHUFFLEPS( 1, 3, 0, 2 ) - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) - add ecx, 16 - add eax, 4*12 - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - addps xmm0, xmm1 - addps xmm0, xmm2 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 1, 3 ) - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loop4 - - done4: - and edx, 3 - jz done1 - - loop1: - movss xmm0, [esi+eax+0] - movss xmm1, [esi+eax+4] - movss xmm2, [esi+eax+8] - mulss xmm0, xmm4 - mulss xmm1, xmm5 - mulss xmm2, xmm6 - add ecx, 4 - addss xmm0, xmm1 - add eax, 12 - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loop1 - - done1: - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant * src[i].Normal() + src[i][3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ) { - __asm { - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - - movss xmm5, [edi+0] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [edi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - jz startVert1 - imul eax, 16 - add esi, eax - neg eax - - loopVert4: - - movlps xmm1, [esi+eax+ 0] - movlps xmm3, [esi+eax+ 8] - movhps xmm1, [esi+eax+16] - movhps xmm3, [esi+eax+24] - movlps xmm2, [esi+eax+32] - movlps xmm4, [esi+eax+40] - movhps xmm2, [esi+eax+48] - movhps xmm4, [esi+eax+56] - movaps xmm0, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm1, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) - movaps xmm2, xmm3 - shufps xmm2, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm3, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) - - add ecx, 16 - add eax, 4*16 - - mulps xmm0, xmm5 - mulps xmm1, xmm6 - mulps xmm2, xmm7 - addps xmm0, xmm3 - addps xmm0, xmm1 - addps xmm0, xmm2 - - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loopVert4 - - startVert1: - and edx, 3 - jz done - - loopVert1: - movss xmm0, [esi+eax+0] - movss xmm1, [esi+eax+4] - movss xmm2, [esi+eax+8] - mulss xmm0, xmm5 - mulss xmm1, xmm6 - mulss xmm2, xmm7 - addss xmm0, [esi+eax+12] - add ecx, 4 - addss xmm0, xmm1 - add eax, 16 - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loopVert1 - - done: - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant * src[i].xyz; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - // 0, 1, 2 - // 3, 4, 5 - // 6, 7, 8 - // 9, 10, 11 - - __asm { - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - - movss xmm4, [edi+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [edi+4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - - jz startVert1 - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loopVert4: - movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X - movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X - movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 - movaps xmm1, xmm0 // 3, X, 0, 1 - - movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 - shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 - - movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 - shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 - - movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 - shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 - - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 - - add ecx, 16 - add eax, 4*DRAWVERT_SIZE - - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - addps xmm0, xmm1 - addps xmm0, xmm2 - - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loopVert4 - - startVert1: - and edx, 3 - jz done - - loopVert1: - movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] - mulss xmm0, xmm4 - mulss xmm1, xmm5 - mulss xmm2, xmm6 - add ecx, 4 - addss xmm0, xmm1 - add eax, DRAWVERT_SIZE - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loopVert1 - - done: - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant.Normal() * src[i] + constant[3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idVec3 *src, const int count ) { - __asm - { - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - - movss xmm4, [edi+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [edi+4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [edi+12] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - jz done4 - imul eax, 12 - add esi, eax - neg eax - - loop4: - movlps xmm1, [esi+eax+ 0] - movlps xmm2, [esi+eax+ 8] - movlps xmm3, [esi+eax+16] - movhps xmm1, [esi+eax+24] - movhps xmm2, [esi+eax+32] - movhps xmm3, [esi+eax+40] - movaps xmm0, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) - shufps xmm1, xmm3, R_SHUFFLEPS( 1, 3, 0, 2 ) - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) - - add ecx, 16 - add eax, 4*12 - - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - addps xmm0, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm2 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 1, 3 ) - - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loop4 - - done4: - and edx, 3 - jz done1 - - loop1: - movss xmm0, [esi+eax+0] - movss xmm1, [esi+eax+4] - movss xmm2, [esi+eax+8] - mulss xmm0, xmm4 - mulss xmm1, xmm5 - mulss xmm2, xmm6 - addss xmm0, xmm7 - add ecx, 4 - addss xmm0, xmm1 - add eax, 12 - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loop1 - - done1: - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant.Normal() * src[i].Normal() + constant[3] * src[i][3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idPlane *src, const int count ) { - -#define SINGLE_OP(SRC, DEST) \ - __asm movlps xmm0,[SRC] \ - __asm movlps xmm1,[SRC+8] \ - __asm mulps xmm0,xmm4 \ - __asm mulps xmm1,xmm5 \ - __asm addps xmm0,xmm1 \ - __asm movaps xmm1,xmm0 \ - __asm shufps xmm1,xmm1,SHUFFLEPS(1,1,1,1) \ - __asm addss xmm0,xmm1 \ - __asm movss [DEST],xmm0 \ - __asm add SRC,16 \ - __asm add DEST,4 - -#define DUAL_OP(SRC, DEST) \ - __asm movlps xmm0,[SRC] \ - __asm movlps xmm1,[SRC+8] \ - __asm movhps xmm0,[SRC+16] \ - __asm movhps xmm1,[SRC+24] \ - __asm mulps xmm0,xmm4 \ - __asm mulps xmm1,xmm5 \ - __asm addps xmm0,xmm1 \ - __asm shufps xmm1,xmm0,SHUFFLEPS(2,0,1,0) \ - __asm shufps xmm0,xmm0,SHUFFLEPS(3,1,2,0) \ - __asm addps xmm0,xmm1 \ - __asm movhps [DEST],xmm0 \ - __asm add SRC,32 \ - __asm add DEST,8 - - __asm { - mov edx, dst - mov eax, src - mov ebx, constant - mov ecx, count - - movlps xmm4, [ebx] - shufps xmm4, xmm4, SHUFFLEPS(1,0,1,0) - movlps xmm5, [ebx+8] - shufps xmm5, xmm5, SHUFFLEPS(1,0,1,0) - - xorps xmm0, xmm0 - xorps xmm1, xmm1 - - _lpAlignDest: - test edx, 0x0f - jz _destAligned - SINGLE_OP(eax,edx) - dec ecx - jnz _lpAlignDest - jmp _vpExit - - _destAligned: - push ecx - - cmp ecx, 4 - jl _post - - and ecx, ~3 - shl ecx, 2 - lea eax, [eax+ecx*4] - add edx, ecx - neg ecx - - movlps xmm0, [eax+ecx*4] - movhps xmm0, [eax+ecx*4+16] - movlps xmm2, [eax+ecx*4+32] - movhps xmm2, [eax+ecx*4+48] - jmp _lpStart - - align 16 - _lp: - prefetchnta [eax+ecx*4+128] - addps xmm1, xmm0 - movlps xmm0, [eax+ecx*4] - movhps xmm0, [eax+ecx*4+16] - movlps xmm2, [eax+ecx*4+32] - movhps xmm2, [eax+ecx*4+48] - movaps [edx+ecx-16],xmm1 - _lpStart: - movlps xmm1, [eax+ecx*4+8] - movhps xmm1, [eax+ecx*4+24] - movlps xmm3, [eax+ecx*4+40] - movhps xmm3, [eax+ecx*4+56] - add ecx, 16 - mulps xmm1, xmm5 - mulps xmm2, xmm4 - mulps xmm3, xmm5 - addps xmm2, xmm3 // y3+w3 x3+z3 y2+w2 x2+z2 - mulps xmm0, xmm4 - addps xmm0, xmm1 // y1+w1 x1+z1 y0+w0 x0+z0 - movaps xmm1, xmm0 - shufps xmm0, xmm2, SHUFFLEPS(2,0,2,0) // x3+z3 x2+z2 x1+z1 x0+z0 - shufps xmm1, xmm2, SHUFFLEPS(3,1,3,1) // y3+w3 y2+w2 y1+w1 y0+w0 - js _lp - addps xmm1, xmm0 - movaps [edx+ecx-16], xmm1 - _post: - pop ecx - and ecx, 0x3 - cmp ecx, 2 - jl _post1 - DUAL_OP(eax,edx) - sub ecx, 2 - _post1: - cmp ecx, 1 - jne _vpExit - SINGLE_OP(eax,edx) - _vpExit: - } - -#undef DUAL_OP -#undef SINGLE_OP - -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = constant.Normal() * src[i].xyz + constant[3]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idPlane &constant, const idDrawVert *src, const int count ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - // 0, 1, 2 - // 3, 4, 5 - // 6, 7, 8 - // 9, 10, 11 - - __asm { - mov eax, count - mov edi, constant - mov edx, eax - mov esi, src - mov ecx, dst - and eax, ~3 - - movss xmm4, [edi+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [edi+4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [edi+8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [edi+12] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - jz startVert1 - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loopVert4: - movss xmm0, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, X, X - movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 2, X, X, X - movhps xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 3, X, 0, 1 - movaps xmm1, xmm0 // 3, X, 0, 1 - - movlps xmm1, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 4, 5, 0, 1 - shufps xmm2, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) // 2, X, 4, 5 - - movss xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, X, X - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] // 9, X, 6, 7 - shufps xmm0, xmm3, R_SHUFFLEPS( 2, 0, 2, 0 ) // 0, 3, 6, 9 - - movlps xmm3, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] // 10, 11, 6, 7 - shufps xmm1, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 1, 4, 7, 10 - - movhps xmm3, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] // 10, 11, 8, X - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 3, 2, 1 ) // 2, 5, 8, 11 - - add ecx, 16 - add eax, 4*DRAWVERT_SIZE - - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - addps xmm0, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm2 - - movlps [ecx-16+0], xmm0 - movhps [ecx-16+8], xmm0 - jl loopVert4 - - startVert1: - and edx, 3 - jz done - - loopVert1: - movss xmm0, [esi+eax+DRAWVERT_XYZ_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_XYZ_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_XYZ_OFFSET+8] - mulss xmm0, xmm4 - mulss xmm1, xmm5 - mulss xmm2, xmm6 - addss xmm0, xmm7 - add ecx, 4 - addss xmm0, xmm1 - add eax, DRAWVERT_SIZE - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loopVert1 - - done: - } -} - -/* -============ -idSIMD_SSE::Dot - - dst[i] = src0[i] * src1[i]; -============ -*/ -void VPCALL idSIMD_SSE::Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ) { - __asm - { - mov eax, count - mov edi, src0 - mov edx, eax - mov esi, src1 - mov ecx, dst - and eax, ~3 - - jz done4 - imul eax, 12 - add edi, eax - add esi, eax - neg eax - - loop4: - movlps xmm0, [esi+eax] // 0, 1, X, X - movlps xmm3, [edi+eax] // 0, 1, X, X - movlps xmm1, [esi+eax+8] // 2, 3, X, X - movlps xmm4, [edi+eax+8] // 2, 3, X, X - movhps xmm0, [esi+eax+24] // 0, 1, 6, 7 - movhps xmm3, [edi+eax+24] // 0, 1, 6, 7 - movhps xmm1, [esi+eax+32] // 2, 3, 8, 9 - movhps xmm4, [edi+eax+32] // 2, 3, 8, 9 - movlps xmm2, [esi+eax+16] // 4, 5, X, X - movlps xmm5, [edi+eax+16] // 4, 5, X, X - movhps xmm2, [esi+eax+40] // 4, 5, 10, 11 - movhps xmm5, [edi+eax+40] // 4, 5, 10, 11 - - add ecx, 16 - add eax, 48 - - mulps xmm0, xmm3 - mulps xmm1, xmm4 - mulps xmm2, xmm5 - movaps xmm7, xmm0 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) // 0, 6, 3, 9 - shufps xmm0, xmm2, R_SHUFFLEPS( 1, 3, 0, 2 ) // 1, 7, 4, 10 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 2, 1, 3 ) // 2, 8, 5, 11 - addps xmm7, xmm0 - addps xmm7, xmm1 - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 2, 1, 3 ) - - movlps [ecx-16+0], xmm7 - movhps [ecx-16+8], xmm7 - jl loop4 - - done4: - and edx, 3 - jz done1 - - loop1: - movss xmm0, [esi+eax+0] - movss xmm3, [edi+eax+0] - movss xmm1, [esi+eax+4] - movss xmm4, [edi+eax+4] - movss xmm2, [esi+eax+8] - movss xmm5, [edi+eax+8] - mulss xmm0, xmm3 - mulss xmm1, xmm4 - mulss xmm2, xmm5 - add ecx, 4 - addss xmm0, xmm1 - add eax, 12 - addss xmm0, xmm2 - dec edx - movss [ecx-4], xmm0 - jnz loop1 - - done1: - } -} - -/* -============ -idSIMD_SSE::Dot - - dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2] + ... -============ -*/ -void VPCALL idSIMD_SSE::Dot( float &dot, const float *src1, const float *src2, const int count ) { - switch( count ) { - case 0: - dot = 0.0f; - return; - case 1: - dot = src1[0] * src2[0]; - return; - case 2: - dot = src1[0] * src2[0] + src1[1] * src2[1]; - return; - case 3: - dot = src1[0] * src2[0] + src1[1] * src2[1] + src1[2] * src2[2]; - return; - default: - __asm { - mov ecx, src1 - mov edx, src2 - mov eax, ecx - or eax, edx - and eax, 15 - jz alignedDot - // unaligned - mov eax, count - shr eax, 2 - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - movups xmm0, [ecx+eax] - movups xmm1, [edx+eax] - mulps xmm0, xmm1 - add eax, 16 - jz doneDot - loopUnalignedDot: - movups xmm1, [ecx+eax] - movups xmm2, [edx+eax] - mulps xmm1, xmm2 - addps xmm0, xmm1 - add eax, 16 - jl loopUnalignedDot - jmp doneDot - // aligned - alignedDot: - mov eax, count - shr eax, 2 - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - movaps xmm0, [ecx+eax] - movaps xmm1, [edx+eax] - mulps xmm0, xmm1 - add eax, 16 - jz doneDot - loopAlignedDot: - movaps xmm1, [ecx+eax] - movaps xmm2, [edx+eax] - mulps xmm1, xmm2 - addps xmm0, xmm1 - add eax, 16 - jl loopAlignedDot - doneDot: - } - switch( count & 3 ) { - case 1: - __asm { - movss xmm1, [ecx] - movss xmm2, [edx] - mulss xmm1, xmm2 - addss xmm0, xmm1 - } - break; - case 2: - __asm { - xorps xmm2, xmm2 - movlps xmm1, [ecx] - movlps xmm2, [edx] - mulps xmm1, xmm2 - addps xmm0, xmm1 - } - break; - case 3: - __asm { - movss xmm1, [ecx] - movhps xmm1, [ecx+4] - movss xmm2, [edx] - movhps xmm2, [edx+4] - mulps xmm1, xmm2 - addps xmm0, xmm1 - } - break; - } - __asm { - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - mov eax, dot - movss [eax], xmm0 - } - return; - } -} - -// -// cmpeqps == Equal -// cmpneqps != Not Equal -// cmpltps < Less Than -// cmpnltps >= Not Less Than -// cmpnleps > Not Less Or Equal -// -#define FLIP not al -#define NOFLIP - -#define COMPARECONSTANT( DST, SRC0, CONSTANT, COUNT, CMP, CMPSIMD, DOFLIP ) \ - int i, cnt, pre, post; \ - float *aligned; \ - \ - /* if the float array is not aligned on a 4 byte boundary */ \ - if ( ((int) SRC0) & 3 ) { \ - /* unaligned memory access */ \ - pre = 0; \ - cnt = COUNT >> 2; \ - post = COUNT - (cnt<<2); \ - __asm mov edx, cnt \ - __asm test edx, edx \ - __asm je doneCmp \ - __asm push ebx \ - __asm neg edx \ - __asm mov esi, SRC0 \ - __asm prefetchnta [esi+64] \ - __asm movss xmm1, CONSTANT \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mov edi, DST \ - __asm mov ecx, 0x01010101 \ - __asm loopNA: \ - __asm movups xmm0, [esi] \ - __asm prefetchnta [esi+128] \ - __asm CMPSIMD xmm0, xmm1 \ - __asm movmskps eax, xmm0 \ - __asm DOFLIP \ - __asm mov ah, al \ - __asm shr ah, 1 \ - __asm mov bx, ax \ - __asm shl ebx, 14 \ - __asm mov bx, ax \ - __asm and ebx, ecx \ - __asm mov dword ptr [edi], ebx \ - __asm add esi, 16 \ - __asm add edi, 4 \ - __asm inc edx \ - __asm jl loopNA \ - __asm pop ebx \ - } \ - else { \ - /* aligned memory access */ \ - aligned = (float *) ((((int) SRC0) + 15) & ~15); \ - if ( (int)aligned > ((int)src0) + COUNT ) { \ - pre = COUNT; \ - post = 0; \ - } \ - else { \ - pre = aligned - SRC0; \ - cnt = (COUNT - pre) >> 2; \ - post = COUNT - pre - (cnt<<2); \ - __asm mov edx, cnt \ - __asm test edx, edx \ - __asm je doneCmp \ - __asm push ebx \ - __asm neg edx \ - __asm mov esi, aligned \ - __asm prefetchnta [esi+64] \ - __asm movss xmm1, CONSTANT \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mov edi, DST \ - __asm add edi, pre \ - __asm mov ecx, 0x01010101 \ - __asm loopA: \ - __asm movaps xmm0, [esi] \ - __asm prefetchnta [esi+128] \ - __asm CMPSIMD xmm0, xmm1 \ - __asm movmskps eax, xmm0 \ - __asm DOFLIP \ - __asm mov ah, al \ - __asm shr ah, 1 \ - __asm mov bx, ax \ - __asm shl ebx, 14 \ - __asm mov bx, ax \ - __asm and ebx, ecx \ - __asm mov dword ptr [edi], ebx \ - __asm add esi, 16 \ - __asm add edi, 4 \ - __asm inc edx \ - __asm jl loopA \ - __asm pop ebx \ - } \ - } \ - doneCmp: \ - double c = constant; \ - for ( i = 0; i < pre; i++ ) { \ - dst[i] = src0[i] CMP c; \ - } \ - for ( i = count - post; i < count; i++ ) { \ - dst[i] = src0[i] CMP c; \ - } - -#define COMPAREBITCONSTANT( DST, BITNUM, SRC0, CONSTANT, COUNT, CMP, CMPSIMD, DOFLIP ) \ - int i, cnt, pre, post; \ - float *aligned; \ - \ - /* if the float array is not aligned on a 4 byte boundary */ \ - if ( ((int) SRC0) & 3 ) { \ - /* unaligned memory access */ \ - pre = 0; \ - cnt = COUNT >> 2; \ - post = COUNT - (cnt<<2); \ - __asm mov edx, cnt \ - __asm test edx, edx \ - __asm je doneCmp \ - __asm push ebx \ - __asm neg edx \ - __asm mov esi, SRC0 \ - __asm prefetchnta [esi+64] \ - __asm movss xmm1, CONSTANT \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mov edi, DST \ - __asm mov cl, bitNum \ - __asm loopNA: \ - __asm movups xmm0, [esi] \ - __asm prefetchnta [esi+128] \ - __asm CMPSIMD xmm0, xmm1 \ - __asm movmskps eax, xmm0 \ - __asm DOFLIP \ - __asm mov ah, al \ - __asm shr ah, 1 \ - __asm mov bx, ax \ - __asm shl ebx, 14 \ - __asm mov bx, ax \ - __asm and ebx, 0x01010101 \ - __asm shl ebx, cl \ - __asm or ebx, dword ptr [edi] \ - __asm mov dword ptr [edi], ebx \ - __asm add esi, 16 \ - __asm add edi, 4 \ - __asm inc edx \ - __asm jl loopNA \ - __asm pop ebx \ - } \ - else { \ - /* aligned memory access */ \ - aligned = (float *) ((((int) SRC0) + 15) & ~15); \ - if ( (int)aligned > ((int)src0) + COUNT ) { \ - pre = COUNT; \ - post = 0; \ - } \ - else { \ - pre = aligned - SRC0; \ - cnt = (COUNT - pre) >> 2; \ - post = COUNT - pre - (cnt<<2); \ - __asm mov edx, cnt \ - __asm test edx, edx \ - __asm je doneCmp \ - __asm push ebx \ - __asm neg edx \ - __asm mov esi, aligned \ - __asm prefetchnta [esi+64] \ - __asm movss xmm1, CONSTANT \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mov edi, DST \ - __asm add edi, pre \ - __asm mov cl, bitNum \ - __asm loopA: \ - __asm movaps xmm0, [esi] \ - __asm prefetchnta [esi+128] \ - __asm CMPSIMD xmm0, xmm1 \ - __asm movmskps eax, xmm0 \ - __asm DOFLIP \ - __asm mov ah, al \ - __asm shr ah, 1 \ - __asm mov bx, ax \ - __asm shl ebx, 14 \ - __asm mov bx, ax \ - __asm and ebx, 0x01010101 \ - __asm shl ebx, cl \ - __asm or ebx, dword ptr [edi] \ - __asm mov dword ptr [edi], ebx \ - __asm add esi, 16 \ - __asm add edi, 4 \ - __asm inc edx \ - __asm jl loopA \ - __asm pop ebx \ - } \ - } \ - doneCmp: \ - float c = constant; \ - for ( i = 0; i < pre; i++ ) { \ - dst[i] |= ( src0[i] CMP c ) << BITNUM; \ - } \ - for ( i = count - post; i < count; i++ ) { \ - dst[i] |= ( src0[i] CMP c ) << BITNUM; \ - } - -/* -============ -idSIMD_SSE::CmpGT - - dst[i] = src0[i] > constant; -============ -*/ -void VPCALL idSIMD_SSE::CmpGT( byte *dst, const float *src0, const float constant, const int count ) { - COMPARECONSTANT( dst, src0, constant, count, >, cmpnleps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpGT - - dst[i] |= ( src0[i] > constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_SSE::CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, >, cmpnleps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpGE - - dst[i] = src0[i] >= constant; -============ -*/ -void VPCALL idSIMD_SSE::CmpGE( byte *dst, const float *src0, const float constant, const int count ) { - COMPARECONSTANT( dst, src0, constant, count, >=, cmpnltps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpGE - - dst[i] |= ( src0[i] >= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_SSE::CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, >=, cmpnltps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpLT - - dst[i] = src0[i] < constant; -============ -*/ -void VPCALL idSIMD_SSE::CmpLT( byte *dst, const float *src0, const float constant, const int count ) { - COMPARECONSTANT( dst, src0, constant, count, <, cmpltps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpLT - - dst[i] |= ( src0[i] < constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_SSE::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, <, cmpltps, NOFLIP ) -} - -/* -============ -idSIMD_SSE::CmpLE - - dst[i] = src0[i] <= constant; -============ -*/ -void VPCALL idSIMD_SSE::CmpLE( byte *dst, const float *src0, const float constant, const int count ) { - COMPARECONSTANT( dst, src0, constant, count, <=, cmpnleps, FLIP ) -} - -/* -============ -idSIMD_SSE::CmpLE - - dst[i] |= ( src0[i] <= constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_SSE::CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - COMPAREBITCONSTANT( dst, bitNum, src0, constant, count, <=, cmpnleps, FLIP ) -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( float &min, float &max, const float *src, const int count ) { - int i, pre, post; - - min = idMath::INFINITY; max = -idMath::INFINITY; - - __asm - { - push ebx - mov eax, min - mov ebx, max - movss xmm0, [eax] - movss xmm1, [ebx] - shufps xmm0, xmm0, 0 - shufps xmm1, xmm1, 0 - - KFLOATINITS( src, count, pre, post ) - and eax, 15 - jz lpA - jmp lpNA - align 16 -lpNA: - movups xmm2, [edx+ebx] - movups xmm3, [edx+ebx+16] - minps xmm0, xmm2 - maxps xmm1, xmm2 - prefetchnta [edx+ebx+64] - minps xmm0, xmm3 - maxps xmm1, xmm3 - add ebx, 16*2 - jl lpNA - jmp done2 -lpA: - movaps xmm2, [edx+ebx] - movaps xmm3, [edx+ebx+16] - minps xmm0, xmm2 - maxps xmm1, xmm2 - prefetchnta [edx+ebx+64] - minps xmm0, xmm3 - maxps xmm1, xmm3 - add ebx, 16*2 - jl lpA - jmp done2 - align 16 -done2: - movaps xmm2, xmm0 - movaps xmm3, xmm1 - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) - minss xmm0, xmm2 - maxss xmm1, xmm3 - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) - minss xmm0, xmm2 - maxss xmm1, xmm3 - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) - minss xmm0, xmm2 - maxss xmm1, xmm3 - mov eax, min - mov ebx, max - movss [eax], xmm0 - movss [ebx], xmm1 -done: - pop ebx - } - - for ( i = 0; i < pre; i++ ) { - float tmp = src[i]; - if ( tmp > max ) { - max = tmp; - } - if ( tmp < min ) { - min = tmp; - } - } - for ( i = count - post; i < count; i++ ) { - float tmp = src[i]; - if ( tmp > max ) { - max = tmp; - } - if ( tmp < min ) { - min = tmp; - } - } -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { - __asm { - mov eax, count - test eax, eax - movss xmm0, idMath::INFINITY - xorps xmm1, xmm1 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - subps xmm1, xmm0 - jz done - mov ecx, eax - and ecx, 1 - mov esi, src - jz startLoop - movlps xmm2, [esi] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - dec eax - add esi, 2*4 - minps xmm0, xmm2 - maxps xmm1, xmm2 - startLoop: - imul eax, 2*4 - add esi, eax - neg eax - loopVert: - movlps xmm2, [esi+eax] - movhps xmm2, [esi+eax+8] - add eax, 4*4 - minps xmm0, xmm2 - maxps xmm1, xmm2 - jl loopVert - done: - movaps xmm2, xmm0 - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ) - minps xmm0, xmm2 - mov esi, min - movlps [esi], xmm0 - movaps xmm3, xmm1 - shufps xmm3, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) - maxps xmm1, xmm3 - mov edi, max - movlps [edi], xmm1 - } -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { - __asm { - - movss xmm0, idMath::INFINITY - xorps xmm1, xmm1 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - subps xmm1, xmm0 - movaps xmm2, xmm0 - movaps xmm3, xmm1 - - mov esi, src - mov eax, count - and eax, ~3 - jz done4 - imul eax, 12 - add esi, eax - neg eax - - loop4: -// prefetchnta [esi+4*12] - - movss xmm4, [esi+eax+0*12+8] - movhps xmm4, [esi+eax+0*12+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - movss xmm5, [esi+eax+1*12+0] - movhps xmm5, [esi+eax+1*12+4] - minps xmm2, xmm5 - maxps xmm3, xmm5 - - movss xmm6, [esi+eax+2*12+8] - movhps xmm6, [esi+eax+2*12+0] - minps xmm0, xmm6 - maxps xmm1, xmm6 - - movss xmm7, [esi+eax+3*12+0] - movhps xmm7, [esi+eax+3*12+4] - minps xmm2, xmm7 - maxps xmm3, xmm7 - - add eax, 4*12 - jl loop4 - - done4: - mov eax, count - and eax, 3 - jz done1 - imul eax, 12 - add esi, eax - neg eax - - loop1: - movss xmm4, [esi+eax+0*12+8] - movhps xmm4, [esi+eax+0*12+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - add eax, 12 - jl loop1 - - done1: - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) - minps xmm0, xmm2 - maxps xmm1, xmm3 - mov esi, min - movhps [esi], xmm0 - movss [esi+8], xmm0 - mov edi, max - movhps [edi], xmm1 - movss [edi+8], xmm1 - } -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - - movss xmm0, idMath::INFINITY - xorps xmm1, xmm1 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - subps xmm1, xmm0 - movaps xmm2, xmm0 - movaps xmm3, xmm1 - - mov esi, src - mov eax, count - and eax, ~3 - jz done4 - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loop4: -// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] - - movss xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - movss xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm5 - maxps xmm3, xmm5 - - movss xmm6, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm6, [esi+eax+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm6 - maxps xmm1, xmm6 - - movss xmm7, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm7, [esi+eax+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm7 - maxps xmm3, xmm7 - - add eax, 4*DRAWVERT_SIZE - jl loop4 - - done4: - mov eax, count - and eax, 3 - jz done1 - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loop1: - movss xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - add eax, DRAWVERT_SIZE - jl loop1 - - done1: - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) - minps xmm0, xmm2 - maxps xmm1, xmm3 - mov esi, min - movhps [esi], xmm0 - movss [esi+8], xmm0 - mov edi, max - movhps [edi], xmm1 - movss [edi+8], xmm1 - } -} - -/* -============ -idSIMD_SSE::MinMax -============ -*/ -void VPCALL idSIMD_SSE::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - - movss xmm0, idMath::INFINITY - xorps xmm1, xmm1 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - subps xmm1, xmm0 - movaps xmm2, xmm0 - movaps xmm3, xmm1 - - mov edi, indexes - mov esi, src - mov eax, count - and eax, ~3 - jz done4 - shl eax, 2 - add edi, eax - neg eax - - loop4: -// prefetchnta [edi+128] -// prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] - - mov edx, [edi+eax+0] - imul edx, DRAWVERT_SIZE - movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - mov edx, [edi+eax+4] - imul edx, DRAWVERT_SIZE - movss xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - movhps xmm5, [esi+edx+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm5 - maxps xmm3, xmm5 - - mov edx, [edi+eax+8] - imul edx, DRAWVERT_SIZE - movss xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm6, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm6 - maxps xmm1, xmm6 - - mov edx, [edi+eax+12] - imul edx, DRAWVERT_SIZE - movss xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - movhps xmm7, [esi+edx+DRAWVERT_XYZ_OFFSET+4] - minps xmm2, xmm7 - maxps xmm3, xmm7 - - add eax, 4*4 - jl loop4 - - done4: - mov eax, count - and eax, 3 - jz done1 - shl eax, 2 - add edi, eax - neg eax - - loop1: - mov edx, [edi+eax+0] - imul edx, DRAWVERT_SIZE; - movss xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+8] - movhps xmm4, [esi+edx+DRAWVERT_XYZ_OFFSET+0] - minps xmm0, xmm4 - maxps xmm1, xmm4 - - add eax, 4 - jl loop1 - - done1: - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 1, 0, 2 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 1, 0, 2 ) - minps xmm0, xmm2 - maxps xmm1, xmm3 - mov esi, min - movhps [esi], xmm0 - movss [esi+8], xmm0 - mov edi, max - movhps [edi], xmm1 - movss [edi+8], xmm1 - } -} - -/* -============ -idSIMD_SSE::Clamp -============ -*/ -void VPCALL idSIMD_SSE::Clamp( float *dst, const float *src, const float min, const float max, const int count ) { - int i, pre, post; - - __asm - { - movss xmm0,min - movss xmm1,max - shufps xmm0,xmm0,0 - shufps xmm1,xmm1,0 - - KFLOATINITDS( dst, src, count, pre, post ) - and eax,15 - jne lpNA - jmp lpA - align 16 -lpA: - movaps xmm2,[edx+ebx] - movaps xmm3,[edx+ebx+16] - maxps xmm2,xmm0 - maxps xmm3,xmm0 - prefetchnta [edx+ebx+64] - minps xmm2,xmm1 - minps xmm3,xmm1 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpA - jmp done - - align 16 -lpNA: - movups xmm2,[edx+ebx] - movups xmm3,[edx+ebx+16] - maxps xmm2,xmm0 - maxps xmm3,xmm0 - prefetchnta [edx+ebx+64] - minps xmm2,xmm1 - minps xmm3,xmm1 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpNA -done: - } - - for ( i = 0; i < pre; i++ ) { - if ( src[i] < min ) - dst[i] = min; - else if ( src[i] > max ) - dst[i] = max; - else - dst[i] = src[i]; - } - - for( i = count - post; i < count; i++ ) { - if ( src[i] < min ) - dst[i] = min; - else if ( src[i] > max ) - dst[i] = max; - else - dst[i] = src[i]; - } -} - -/* -============ -idSIMD_SSE::ClampMin -============ -*/ -void VPCALL idSIMD_SSE::ClampMin( float *dst, const float *src, const float min, const int count ) { - int i, pre, post; - - __asm - { - movss xmm0,min - shufps xmm0,xmm0,0 - - KFLOATINITDS( dst, src, count, pre, post ) - and eax,15 - jne lpNA - jmp lpA - align 16 -lpA: - movaps xmm2,[edx+ebx] - movaps xmm3,[edx+ebx+16] - maxps xmm2,xmm0 - prefetchnta [edx+ebx+64] - maxps xmm3,xmm0 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpA - jmp done - - align 16 -lpNA: - movups xmm2,[edx+ebx] - movups xmm3,[edx+ebx+16] - maxps xmm2,xmm0 - prefetchnta [edx+ebx+64] - maxps xmm3,xmm0 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpNA -done: - } - - for( i = 0; i < pre; i++ ) { - if ( src[i] < min ) - dst[i] = min; - else - dst[i] = src[i]; - } - for( i = count - post; i < count; i++ ) { - if ( src[i] < min ) - dst[i] = min; - else - dst[i] = src[i]; - } -} - -/* -============ -idSIMD_SSE::ClampMax -============ -*/ -void VPCALL idSIMD_SSE::ClampMax( float *dst, const float *src, const float max, const int count ) { - int i, pre, post; - - __asm - { - movss xmm1,max - shufps xmm1,xmm1,0 - - KFLOATINITDS( dst, src, count, pre, post ) - and eax,15 - jne lpNA - jmp lpA - align 16 -lpA: - movaps xmm2,[edx+ebx] - movaps xmm3,[edx+ebx+16] - minps xmm2,xmm1 - prefetchnta [edx+ebx+64] - minps xmm3,xmm1 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpA - jmp done - - align 16 -lpNA: - movups xmm2,[edx+ebx] - movups xmm3,[edx+ebx+16] - minps xmm2,xmm1 - prefetchnta [edx+ebx+64] - minps xmm3,xmm1 - movaps [edi+ebx],xmm2 - movaps [edi+ebx+16],xmm3 - add ebx,16*2 - jl lpNA -done: - } - - for( i = 0; i < pre; i++ ) { - if ( src[i] > max ) - dst[i] = max; - else - dst[i] = src[i]; - } - - for( i = count - post; i < count; i++ ) { - if ( src[i] > max ) - dst[i] = max; - else - dst[i] = src[i]; - } -} - -/* -============ -idSIMD_SSE::Zero16 -============ -*/ -void VPCALL idSIMD_SSE::Zero16( float *dst, const int count ) { - __asm { - mov edx, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneZero16 - shl eax, 4 - add edx, eax - neg eax - xorps xmm0, xmm0 - loopZero16: - movaps [edx+eax], xmm0 - add eax, 16 - jl loopZero16 - doneZero16: - } -} - -/* -============ -idSIMD_SSE::Negate16 -============ -*/ -void VPCALL idSIMD_SSE::Negate16( float *dst, const int count ) { - __asm { - mov edx, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneNegate16 - shl eax, 4 - add edx, eax - neg eax - movss xmm0, SIMD_SP_signBitMask - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - loopNegate16: - movaps xmm1, [edx+eax] - xorps xmm1, xmm0 - movaps [edx+eax], xmm1 - add eax, 16 - jl loopNegate16 - doneNegate16: - } -} - -/* -============ -idSIMD_SSE::Copy16 -============ -*/ -void VPCALL idSIMD_SSE::Copy16( float *dst, const float *src, const int count ) { - __asm { - mov ecx, src - mov edx, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneCopy16 - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - loopCopy16: - movaps xmm0, [ecx+eax] - movaps [edx+eax], xmm0 - add eax, 16 - jl loopCopy16 - doneCopy16: - } -} - -/* -============ -idSIMD_SSE::Add16 -============ -*/ -void VPCALL idSIMD_SSE::Add16( float *dst, const float *src1, const float *src2, const int count ) { - __asm { - mov ecx, src1 - mov edx, src2 - mov esi, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneAdd16 - shl eax, 4 - add esi, eax - add ecx, eax - add edx, eax - neg eax - loopAdd16: - movaps xmm0, [ecx+eax] - addps xmm0, [edx+eax] - movaps [esi+eax], xmm0 - add eax, 16 - jl loopAdd16 - doneAdd16: - } -} - -/* -============ -idSIMD_SSE::Sub16 -============ -*/ -void VPCALL idSIMD_SSE::Sub16( float *dst, const float *src1, const float *src2, const int count ) { - __asm { - mov ecx, src1 - mov edx, src2 - mov esi, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneSub16 - shl eax, 4 - add esi, eax - add ecx, eax - add edx, eax - neg eax - loopSub16: - movaps xmm0, [ecx+eax] - subps xmm0, [edx+eax] - movaps [esi+eax], xmm0 - add eax, 16 - jl loopSub16 - doneSub16: - } -} - -/* -============ -idSIMD_SSE::Mul16 -============ -*/ -void VPCALL idSIMD_SSE::Mul16( float *dst, const float *src1, const float constant, const int count ) { - __asm { - mov ecx, dst - mov edx, src1 - mov eax, count - add eax, 3 - shr eax, 2 - jz doneMulScalar16 - movss xmm1, constant - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - shufps xmm1, xmm1, 0x00 - loopMulScalar16: - movaps xmm0, [edx+eax] - mulps xmm0, xmm1 - movaps [ecx+eax], xmm0 - add eax, 16 - jl loopMulScalar16 - doneMulScalar16: - } -} - -/* -============ -idSIMD_SSE::AddAssign16 -============ -*/ -void VPCALL idSIMD_SSE::AddAssign16( float *dst, const float *src, const int count ) { - __asm { - mov ecx, dst - mov edx, src - mov eax, count - add eax, 3 - shr eax, 2 - jz doneAddAssign16 - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - loopAddAssign16: - movaps xmm0, [ecx+eax] - addps xmm0, [edx+eax] - movaps [ecx+eax], xmm0 - add eax, 16 - jl loopAddAssign16 - doneAddAssign16: - } -} - -/* -============ -idSIMD_SSE::SubAssign16 -============ -*/ -void VPCALL idSIMD_SSE::SubAssign16( float *dst, const float *src, const int count ) { - __asm { - mov ecx, dst - mov edx, src - mov eax, count - add eax, 3 - shr eax, 2 - jz doneSubAssign16 - shl eax, 4 - add ecx, eax - add edx, eax - neg eax - loopSubAssign16: - movaps xmm0, [ecx+eax] - subps xmm0, [edx+eax] - movaps [ecx+eax], xmm0 - add eax, 16 - jl loopSubAssign16 - doneSubAssign16: - } -} - -/* -============ -idSIMD_SSE::MulAssign16 -============ -*/ -void VPCALL idSIMD_SSE::MulAssign16( float *dst, const float constant, const int count ) { - __asm { - mov ecx, dst - mov eax, count - add eax, 3 - shr eax, 2 - jz doneMulAssign16 - movss xmm1, constant - shl eax, 4 - add ecx, eax - neg eax - shufps xmm1, xmm1, 0x00 - loopMulAssign16: - movaps xmm0, [ecx+eax] - mulps xmm0, xmm1 - movaps [ecx+eax], xmm0 - add eax, 16 - jl loopMulAssign16 - doneMulAssign16: - } -} - -/* -============ -idSIMD_SSE::MatX_MultiplyVecX - - optimizes the following matrix multiplications: - - NxN * Nx1 - Nx6 * 6x1 - 6xN * Nx1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss [eax+offset], reg1 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps [eax+offset], reg1 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps [eax+offset], reg1 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps [eax+offset], reg1 \ - __asm movhps [eax+offset+8], reg1 -#define STOREC = - - int numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: { - switch( numRows ) { - case 1: { // 1x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - STORE1( 0, xmm0, xmm1 ) - } - return; - } - case 6: { // 6x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0]; - mPtr++; - } - return; - } - } - break; - } - case 2: { - switch( numRows ) { - case 2: { // 2x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm1, [esi+4] - movss xmm2, [edi] - mulss xmm2, xmm0 - movss xmm3, [edi+4] - mulss xmm3, xmm1 - addss xmm2, xmm3 - STORE1( 0, xmm2, xmm4 ) - mulss xmm0, [edi+8] - mulss xmm1, [edi+8+4] - addss xmm0, xmm1 - STORE1( 4, xmm0, xmm4 ) - } - return; - } - case 6: { // 6x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, [esi] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movaps xmm0, [edi] - mulps xmm0, xmm7 - movaps xmm1, [edi+16] - mulps xmm1, xmm7 - movaps xmm2, xmm0 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - movaps xmm3, [edi+32] - addps xmm0, xmm2 - mulps xmm3, xmm7 - STORE4( 0, xmm0, xmm4 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm1, xmm3 - addps xmm3, xmm1 - STORE2LO( 16, xmm3, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - return; - } - } - break; - } - case 3: { - switch( numRows ) { - case 3: { // 3x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm4, [edi] - mulss xmm4, xmm0 - movss xmm1, [esi+4] - movss xmm5, [edi+4] - mulss xmm5, xmm1 - addss xmm4, xmm5 - movss xmm2, [esi+8] - movss xmm6, [edi+8] - mulss xmm6, xmm2 - addss xmm4, xmm6 - movss xmm3, [edi+12] - mulss xmm3, xmm0 - STORE1( 0, xmm4, xmm7 ); - movss xmm5, [edi+12+4] - mulss xmm5, xmm1 - addss xmm3, xmm5 - movss xmm6, [edi+12+8] - mulss xmm6, xmm2 - addss xmm3, xmm6 - mulss xmm0, [edi+24] - mulss xmm1, [edi+24+4] - STORE1( 4, xmm3, xmm7 ); - addss xmm0, xmm1 - mulss xmm2, [edi+24+8] - addss xmm0, xmm2 - STORE1( 8, xmm0, xmm7 ); - } - return; - } - case 6: { // 6x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm5, [esi] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [esi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 - movlps xmm1, [edi+4*4] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 - movlps xmm2, [edi+6*4] - movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 - mulps xmm0, xmm5 - movlps xmm3, [edi+10*4] - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 - movaps xmm3, xmm1 - shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 - mulps xmm1, xmm6 - shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 - mulps xmm3, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm3 - STORE4( 0, xmm0, xmm4 ) - movss xmm1, [edi+12*4] - mulss xmm1, xmm5 - movss xmm2, [edi+13*4] - mulss xmm2, xmm6 - movss xmm3, [edi+14*4] - mulss xmm3, xmm7 - addss xmm1, xmm2 - addss xmm1, xmm3 - STORE1( 16, xmm1, xmm4 ) - mulss xmm5, [edi+15*4] - mulss xmm6, [edi+16*4] - mulss xmm7, [edi+17*4] - addss xmm5, xmm6 - addss xmm5, xmm7 - STORE1( 20, xmm5, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - return; - } - } - break; - } - case 4: { - switch( numRows ) { - case 4: { // 4x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi ] - movlps xmm0, qword ptr [edi ] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - STORE4( 0, xmm0, xmm2 ) - } - return; - } - case 6: { // 6x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi+ 0] - movlps xmm0, qword ptr [edi+ 0] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - movlps xmm1, qword ptr [edi+64] - movhps xmm1, qword ptr [edi+80] - STORE4( 0, xmm0, xmm4 ) - mulps xmm1, xmm6 - movlps xmm2, qword ptr [edi+72] - movhps xmm2, qword ptr [edi+88] - mulps xmm2, xmm7 - addps xmm1, xmm2 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm3, xmm1 - addps xmm1, xmm3 - STORE2LO( 16, xmm1, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; - mPtr += 4; - } - return; - } - } - break; - } - case 5: { - switch( numRows ) { - case 5: { // 5x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X - movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 - movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X - movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 - movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 - shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 - movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 - movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 - movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 - movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 - movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 - movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 - shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 - movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 - movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 - movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X - movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 - shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 - movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 - shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 - movss xmm7, [esi+0*4] - shufps xmm7, xmm7, 0 - mulps xmm0, xmm7 - movss xmm5, [esi+1*4] - shufps xmm5, xmm5, 0 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, 0 - mulps xmm2, xmm6 - addps xmm0, xmm2 - movss xmm1, [esi+3*4] - shufps xmm1, xmm1, 0 - mulps xmm3, xmm1 - addps xmm0, xmm3 - movss xmm2, [esi+4*4] - shufps xmm2, xmm2, 0 - mulps xmm4, xmm2 - addps xmm0, xmm4 - mulss xmm7, [edi+20*4] - mulss xmm5, [edi+21*4] - addps xmm7, xmm5 - mulss xmm6, [edi+22*4] - addps xmm7, xmm6 - mulss xmm1, [edi+23*4] - addps xmm7, xmm1 - mulss xmm2, [edi+24*4] - addps xmm7, xmm2 - STORE4( 0, xmm0, xmm3 ) - STORE1( 16, xmm7, xmm4 ) - } - return; - } - case 6: { // 6x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [esi] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm0, [edi] - movhps xmm3, [edi+8] - movaps xmm1, [edi+16] - movlps xmm2, [edi+32] - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 - mulps xmm0, xmm6 - mulps xmm3, xmm7 - movlps xmm2, [edi+40] - addps xmm0, xmm3 // xmm0 + xmm1 - movhps xmm5, [edi+40+8] - movlps xmm3, [edi+40+16] - movhps xmm3, [edi+40+24] - movlps xmm4, [edi+40+32] - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 - shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 - shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 - mulps xmm2, xmm6 - mulps xmm5, xmm7 - addps xmm2, xmm5 // xmm2 + xmm3 - movss xmm5, [esi+16] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm0 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) - shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) - addps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - STORE4( 0, xmm0, xmm2 ) - movlps xmm4, [edi+80] - movhps xmm3, [edi+80+8] - movaps xmm1, [edi+80+16] - movlps xmm2, [edi+80+32] - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 - mulps xmm4, xmm6 - mulps xmm3, xmm7 - mulps xmm1, xmm5 - addps xmm4, xmm3 // xmm4 + xmm1 - shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) - addps xmm4, xmm1 - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) - addps xmm4, xmm1 - STORE2LO( 16, xmm4, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - return; - } - } - break; - } - case 6: { - switch( numRows ) { - case 1: { // 1x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - movss xmm1, [esi+4] - mulss xmm1, [edi+4] - movss xmm2, [esi+8] - addss xmm0, xmm1 - mulss xmm2, [edi+8] - movss xmm3, [esi+12] - addss xmm0, xmm2 - mulss xmm3, [edi+12] - movss xmm4, [esi+16] - addss xmm0, xmm3 - mulss xmm4, [edi+16] - movss xmm5, [esi+20] - addss xmm0, xmm4 - mulss xmm5, [edi+20] - movss xmm6, [esi+24] - addss xmm0, xmm5 - mulss xmm6, [edi+24] - addss xmm0, xmm6 - STORE1( 0, xmm0, xmm7 ) - } - return; - } - case 2: { // 2x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - } - return; - } - case 3: { // 3x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - // row 2 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - STORE1( 8, xmm0, xmm3 ) - } - return; - } - case 4: { // 4x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm4 ) - } - return; - } - case 5: { // 5x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm3 ) - // row 5 - movaps xmm0, [edi+96] - movaps xmm1, [edi+96+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 0x01 - addss xmm0, xmm1 - STORE1( 16, xmm0, xmm3 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, qword ptr [esi] - movlps xmm6, qword ptr [esi+8] - shufps xmm7, xmm7, 0x44 - shufps xmm6, xmm6, 0x44 - movlps xmm0, qword ptr [edi ] - movhps xmm0, qword ptr [edi+ 24] - mulps xmm0, xmm7 - movlps xmm3, qword ptr [edi+ 8] - movhps xmm3, qword ptr [edi+ 32] - mulps xmm3, xmm6 - movlps xmm1, qword ptr [edi+ 48] - movhps xmm1, qword ptr [edi+ 72] - mulps xmm1, xmm7 - movlps xmm2, qword ptr [edi+ 96] - movhps xmm2, qword ptr [edi+120] - mulps xmm2, xmm7 - movlps xmm4, qword ptr [edi+ 56] - movhps xmm4, qword ptr [edi+ 80] - movlps xmm5, qword ptr [edi+104] - movhps xmm5, qword ptr [edi+128] - mulps xmm4, xmm6 - movlps xmm7, qword ptr [esi+16] - addps xmm0, xmm3 - shufps xmm7, xmm7, 0x44 - mulps xmm5, xmm6 - addps xmm1, xmm4 - movlps xmm3, qword ptr [edi+ 16] - movhps xmm3, qword ptr [edi+ 40] - addps xmm2, xmm5 - movlps xmm4, qword ptr [edi+ 64] - movhps xmm4, qword ptr [edi+ 88] - mulps xmm3, xmm7 - movlps xmm5, qword ptr [edi+112] - movhps xmm5, qword ptr [edi+136] - addps xmm0, xmm3 - mulps xmm4, xmm7 - mulps xmm5, xmm7 - addps xmm1, xmm4 - addps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm0, xmm1, 0x88 - shufps xmm6, xmm1, 0xDD - movaps xmm7, xmm2 - shufps xmm7, xmm2, 0x88 - shufps xmm2, xmm2, 0xDD - addps xmm0, xmm6 - addps xmm2, xmm7 - STORE4( 0, xmm0, xmm3 ) - STORE2LO( 16, xmm2, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - return; - } - } - break; - } - default: { - int numColumns = mat.GetNumColumns(); - for ( int i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] STOREC sum; - mPtr += numColumns; - } - break; - } - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -idSIMD_SSE::MatX_MultiplyAddVecX - - optimizes the following matrix multiplications: - - NxN * Nx1 - Nx6 * 6x1 - 6xN * Nx1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss reg2, [eax+offset] \ - __asm addss reg2, reg1 \ - __asm movss [eax+offset], reg2 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm addps reg2, reg1 \ - __asm movlps [eax+offset], reg2 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps reg2, [eax+offset] \ - __asm addps reg2, reg1 \ - __asm movhps [eax+offset], reg2 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm movhps reg2, [eax+offset+8] \ - __asm addps reg2, reg1 \ - __asm movlps [eax+offset], reg2 \ - __asm movhps [eax+offset+8], reg2 -#define STOREC += - - int numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: { - switch( numRows ) { - case 1: { // 1x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - STORE1( 0, xmm0, xmm1 ) - } - return; - } - case 6: { // 6x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0]; - mPtr++; - } - return; - } - } - break; - } - case 2: { - switch( numRows ) { - case 2: { // 2x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm1, [esi+4] - movss xmm2, [edi] - mulss xmm2, xmm0 - movss xmm3, [edi+4] - mulss xmm3, xmm1 - addss xmm2, xmm3 - STORE1( 0, xmm2, xmm4 ) - mulss xmm0, [edi+8] - mulss xmm1, [edi+8+4] - addss xmm0, xmm1 - STORE1( 4, xmm0, xmm4 ) - } - return; - } - case 6: { // 6x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, [esi] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movaps xmm0, [edi] - mulps xmm0, xmm7 - movaps xmm1, [edi+16] - mulps xmm1, xmm7 - movaps xmm2, xmm0 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - movaps xmm3, [edi+32] - addps xmm0, xmm2 - mulps xmm3, xmm7 - STORE4( 0, xmm0, xmm4 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm1, xmm3 - addps xmm3, xmm1 - STORE2LO( 16, xmm3, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - return; - } - } - break; - } - case 3: { - switch( numRows ) { - case 3: { // 3x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm4, [edi] - mulss xmm4, xmm0 - movss xmm1, [esi+4] - movss xmm5, [edi+4] - mulss xmm5, xmm1 - addss xmm4, xmm5 - movss xmm2, [esi+8] - movss xmm6, [edi+8] - mulss xmm6, xmm2 - addss xmm4, xmm6 - movss xmm3, [edi+12] - mulss xmm3, xmm0 - STORE1( 0, xmm4, xmm7 ); - movss xmm5, [edi+12+4] - mulss xmm5, xmm1 - addss xmm3, xmm5 - movss xmm6, [edi+12+8] - mulss xmm6, xmm2 - addss xmm3, xmm6 - mulss xmm0, [edi+24] - mulss xmm1, [edi+24+4] - STORE1( 4, xmm3, xmm7 ); - addss xmm0, xmm1 - mulss xmm2, [edi+24+8] - addss xmm0, xmm2 - STORE1( 8, xmm0, xmm7 ); - } - return; - } - case 6: { // 6x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm5, [esi] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [esi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 - movlps xmm1, [edi+4*4] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 - movlps xmm2, [edi+6*4] - movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 - mulps xmm0, xmm5 - movlps xmm3, [edi+10*4] - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 - movaps xmm3, xmm1 - shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 - mulps xmm1, xmm6 - shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 - mulps xmm3, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm3 - STORE4( 0, xmm0, xmm4 ) - movss xmm1, [edi+12*4] - mulss xmm1, xmm5 - movss xmm2, [edi+13*4] - mulss xmm2, xmm6 - movss xmm3, [edi+14*4] - mulss xmm3, xmm7 - addss xmm1, xmm2 - addss xmm1, xmm3 - STORE1( 16, xmm1, xmm4 ) - mulss xmm5, [edi+15*4] - mulss xmm6, [edi+16*4] - mulss xmm7, [edi+17*4] - addss xmm5, xmm6 - addss xmm5, xmm7 - STORE1( 20, xmm5, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - return; - } - } - break; - } - case 4: { - switch( numRows ) { - case 4: { // 4x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi ] - movlps xmm0, qword ptr [edi ] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - STORE4( 0, xmm0, xmm2 ) - } - return; - } - case 6: { // 6x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi+ 0] - movlps xmm0, qword ptr [edi+ 0] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - movlps xmm1, qword ptr [edi+64] - movhps xmm1, qword ptr [edi+80] - STORE4( 0, xmm0, xmm4 ) - mulps xmm1, xmm6 - movlps xmm2, qword ptr [edi+72] - movhps xmm2, qword ptr [edi+88] - mulps xmm2, xmm7 - addps xmm1, xmm2 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm3, xmm1 - addps xmm1, xmm3 - STORE2LO( 16, xmm1, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; - mPtr += 4; - } - return; - } - } - break; - } - case 5: { - switch( numRows ) { - case 5: { // 5x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X - movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 - movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X - movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 - movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 - shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 - movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 - movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 - movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 - movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 - movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 - movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 - shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 - movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 - movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 - movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X - movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 - shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 - movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 - shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 - movss xmm7, [esi+0*4] - shufps xmm7, xmm7, 0 - mulps xmm0, xmm7 - movss xmm5, [esi+1*4] - shufps xmm5, xmm5, 0 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, 0 - mulps xmm2, xmm6 - addps xmm0, xmm2 - movss xmm1, [esi+3*4] - shufps xmm1, xmm1, 0 - mulps xmm3, xmm1 - addps xmm0, xmm3 - movss xmm2, [esi+4*4] - shufps xmm2, xmm2, 0 - mulps xmm4, xmm2 - addps xmm0, xmm4 - mulss xmm7, [edi+20*4] - mulss xmm5, [edi+21*4] - addps xmm7, xmm5 - mulss xmm6, [edi+22*4] - addps xmm7, xmm6 - mulss xmm1, [edi+23*4] - addps xmm7, xmm1 - mulss xmm2, [edi+24*4] - addps xmm7, xmm2 - STORE4( 0, xmm0, xmm3 ) - STORE1( 16, xmm7, xmm4 ) - } - return; - } - case 6: { // 6x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [esi] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm0, [edi] - movhps xmm3, [edi+8] - movaps xmm1, [edi+16] - movlps xmm2, [edi+32] - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 - mulps xmm0, xmm6 - mulps xmm3, xmm7 - movlps xmm2, [edi+40] - addps xmm0, xmm3 // xmm0 + xmm1 - movhps xmm5, [edi+40+8] - movlps xmm3, [edi+40+16] - movhps xmm3, [edi+40+24] - movlps xmm4, [edi+40+32] - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 - shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 - shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 - mulps xmm2, xmm6 - mulps xmm5, xmm7 - addps xmm2, xmm5 // xmm2 + xmm3 - movss xmm5, [esi+16] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm0 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) - shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) - addps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - STORE4( 0, xmm0, xmm2 ) - movlps xmm4, [edi+80] - movhps xmm3, [edi+80+8] - movaps xmm1, [edi+80+16] - movlps xmm2, [edi+80+32] - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 - mulps xmm4, xmm6 - mulps xmm3, xmm7 - mulps xmm1, xmm5 - addps xmm4, xmm3 // xmm4 + xmm1 - shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) - addps xmm4, xmm1 - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) - addps xmm4, xmm1 - STORE2LO( 16, xmm4, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - return; - } - } - break; - } - case 6: { - switch( numRows ) { - case 1: { // 1x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - movss xmm1, [esi+4] - mulss xmm1, [edi+4] - movss xmm2, [esi+8] - addss xmm0, xmm1 - mulss xmm2, [edi+8] - movss xmm3, [esi+12] - addss xmm0, xmm2 - mulss xmm3, [edi+12] - movss xmm4, [esi+16] - addss xmm0, xmm3 - mulss xmm4, [edi+16] - movss xmm5, [esi+20] - addss xmm0, xmm4 - mulss xmm5, [edi+20] - movss xmm6, [esi+24] - addss xmm0, xmm5 - mulss xmm6, [edi+24] - addss xmm0, xmm6 - STORE1( 0, xmm0, xmm7 ) - } - return; - } - case 2: { // 2x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - } - return; - } - case 3: { // 3x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - // row 2 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - STORE1( 8, xmm0, xmm3 ) - } - return; - } - case 4: { // 4x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm4 ) - } - return; - } - case 5: { // 5x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm3 ) - // row 5 - movaps xmm0, [edi+96] - movaps xmm1, [edi+96+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 0x01 - addss xmm0, xmm1 - STORE1( 16, xmm0, xmm3 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, qword ptr [esi] - movlps xmm6, qword ptr [esi+8] - shufps xmm7, xmm7, 0x44 - shufps xmm6, xmm6, 0x44 - movlps xmm0, qword ptr [edi ] - movhps xmm0, qword ptr [edi+ 24] - mulps xmm0, xmm7 - movlps xmm3, qword ptr [edi+ 8] - movhps xmm3, qword ptr [edi+ 32] - mulps xmm3, xmm6 - movlps xmm1, qword ptr [edi+ 48] - movhps xmm1, qword ptr [edi+ 72] - mulps xmm1, xmm7 - movlps xmm2, qword ptr [edi+ 96] - movhps xmm2, qword ptr [edi+120] - mulps xmm2, xmm7 - movlps xmm4, qword ptr [edi+ 56] - movhps xmm4, qword ptr [edi+ 80] - movlps xmm5, qword ptr [edi+104] - movhps xmm5, qword ptr [edi+128] - mulps xmm4, xmm6 - movlps xmm7, qword ptr [esi+16] - addps xmm0, xmm3 - shufps xmm7, xmm7, 0x44 - mulps xmm5, xmm6 - addps xmm1, xmm4 - movlps xmm3, qword ptr [edi+ 16] - movhps xmm3, qword ptr [edi+ 40] - addps xmm2, xmm5 - movlps xmm4, qword ptr [edi+ 64] - movhps xmm4, qword ptr [edi+ 88] - mulps xmm3, xmm7 - movlps xmm5, qword ptr [edi+112] - movhps xmm5, qword ptr [edi+136] - addps xmm0, xmm3 - mulps xmm4, xmm7 - mulps xmm5, xmm7 - addps xmm1, xmm4 - addps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm0, xmm1, 0x88 - shufps xmm6, xmm1, 0xDD - movaps xmm7, xmm2 - shufps xmm7, xmm2, 0x88 - shufps xmm2, xmm2, 0xDD - addps xmm0, xmm6 - addps xmm2, xmm7 - STORE4( 0, xmm0, xmm3 ) - STORE2LO( 16, xmm2, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - return; - } - } - break; - } - default: { - int numColumns = mat.GetNumColumns(); - for ( int i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] STOREC sum; - mPtr += numColumns; - } - break; - } - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -idSIMD_SSE::MatX_MultiplySubVecX - - optimizes the following matrix multiplications: - - NxN * Nx1 - Nx6 * 6x1 - 6xN * Nx1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss reg2, [eax+offset] \ - __asm subss reg2, reg1 \ - __asm movss [eax+offset], reg2 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm subps reg2, reg1 \ - __asm movlps [eax+offset], reg2 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps reg2, [eax+offset] \ - __asm subps reg2, reg1 \ - __asm movhps [eax+offset], reg2 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm movhps reg2, [eax+offset+8] \ - __asm subps reg2, reg1 \ - __asm movlps [eax+offset], reg2 \ - __asm movhps [eax+offset+8], reg2 -#define STOREC -= - - int numRows; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumColumns() ); - assert( dst.GetSize() >= mat.GetNumRows() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numRows = mat.GetNumRows(); - switch( mat.GetNumColumns() ) { - case 1: { - switch( numRows ) { - case 1: { // 1x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - STORE1( 0, xmm0, xmm1 ) - } - return; - } - case 6: { // 6x1 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0]; - mPtr++; - } - return; - } - } - break; - } - case 2: { - switch( numRows ) { - case 2: { // 2x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm1, [esi+4] - movss xmm2, [edi] - mulss xmm2, xmm0 - movss xmm3, [edi+4] - mulss xmm3, xmm1 - addss xmm2, xmm3 - STORE1( 0, xmm2, xmm4 ) - mulss xmm0, [edi+8] - mulss xmm1, [edi+8+4] - addss xmm0, xmm1 - STORE1( 4, xmm0, xmm4 ) - } - return; - } - case 6: { // 6x2 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, [esi] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movaps xmm0, [edi] - mulps xmm0, xmm7 - movaps xmm1, [edi+16] - mulps xmm1, xmm7 - movaps xmm2, xmm0 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm2, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - movaps xmm3, [edi+32] - addps xmm0, xmm2 - mulps xmm3, xmm7 - STORE4( 0, xmm0, xmm4 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm1, xmm3 - addps xmm3, xmm1 - STORE2LO( 16, xmm3, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1]; - mPtr += 2; - } - return; - } - } - break; - } - case 3: { - switch( numRows ) { - case 3: { // 3x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - movss xmm4, [edi] - mulss xmm4, xmm0 - movss xmm1, [esi+4] - movss xmm5, [edi+4] - mulss xmm5, xmm1 - addss xmm4, xmm5 - movss xmm2, [esi+8] - movss xmm6, [edi+8] - mulss xmm6, xmm2 - addss xmm4, xmm6 - movss xmm3, [edi+12] - mulss xmm3, xmm0 - STORE1( 0, xmm4, xmm7 ); - movss xmm5, [edi+12+4] - mulss xmm5, xmm1 - addss xmm3, xmm5 - movss xmm6, [edi+12+8] - mulss xmm6, xmm2 - addss xmm3, xmm6 - mulss xmm0, [edi+24] - mulss xmm1, [edi+24+4] - STORE1( 4, xmm3, xmm7 ); - addss xmm0, xmm1 - mulss xmm2, [edi+24+8] - addss xmm0, xmm2 - STORE1( 8, xmm0, xmm7 ); - } - return; - } - case 6: { // 6x3 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm5, [esi] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [esi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm0, [edi] // xmm0 = 0, 1, 2, 3 - movlps xmm1, [edi+4*4] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm1 = 4, 5, 1, 2 - movlps xmm2, [edi+6*4] - movhps xmm2, [edi+8*4] // xmm2 = 6, 7, 8, 9 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 3, 0, 3 ) // xmm0 = 0, 3, 6, 9 - mulps xmm0, xmm5 - movlps xmm3, [edi+10*4] - shufps xmm2, xmm3, R_SHUFFLEPS( 1, 2, 0, 1 ) // xmm2 = 7, 8, 10, 11 - movaps xmm3, xmm1 - shufps xmm1, xmm2, R_SHUFFLEPS( 2, 0, 0, 2 ) // xmm1 = 1, 4, 7, 10 - mulps xmm1, xmm6 - shufps xmm3, xmm2, R_SHUFFLEPS( 3, 1, 1, 3 ) // xmm3 = 2, 5, 8, 11 - mulps xmm3, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm3 - STORE4( 0, xmm0, xmm4 ) - movss xmm1, [edi+12*4] - mulss xmm1, xmm5 - movss xmm2, [edi+13*4] - mulss xmm2, xmm6 - movss xmm3, [edi+14*4] - mulss xmm3, xmm7 - addss xmm1, xmm2 - addss xmm1, xmm3 - STORE1( 16, xmm1, xmm4 ) - mulss xmm5, [edi+15*4] - mulss xmm6, [edi+16*4] - mulss xmm7, [edi+17*4] - addss xmm5, xmm6 - addss xmm5, xmm7 - STORE1( 20, xmm5, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2]; - mPtr += 3; - } - return; - } - } - break; - } - case 4: { - switch( numRows ) { - case 4: { // 4x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi ] - movlps xmm0, qword ptr [edi ] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - STORE4( 0, xmm0, xmm2 ) - } - return; - } - case 6: { // 6x4 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, qword ptr [esi+ 0] - movlps xmm0, qword ptr [edi+ 0] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm0, qword ptr [edi+16] - mulps xmm0, xmm6 - movlps xmm7, qword ptr [esi+ 8] - movlps xmm2, qword ptr [edi+ 8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movhps xmm2, qword ptr [edi+24] - mulps xmm2, xmm7 - movlps xmm1, qword ptr [edi+32] - movhps xmm1, qword ptr [edi+48] - mulps xmm1, xmm6 - movlps xmm3, qword ptr [edi+40] - addps xmm0, xmm2 - movhps xmm3, qword ptr [edi+56] - mulps xmm3, xmm7 - movaps xmm4, xmm0 - addps xmm1, xmm3 - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm4 - movlps xmm1, qword ptr [edi+64] - movhps xmm1, qword ptr [edi+80] - STORE4( 0, xmm0, xmm4 ) - mulps xmm1, xmm6 - movlps xmm2, qword ptr [edi+72] - movhps xmm2, qword ptr [edi+88] - mulps xmm2, xmm7 - addps xmm1, xmm2 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm3, xmm1 - addps xmm1, xmm3 - STORE2LO( 16, xmm1, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3]; - mPtr += 4; - } - return; - } - } - break; - } - case 5: { - switch( numRows ) { - case 5: { // 5x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+5*4] // xmm0 = 5, X, X, X - movhps xmm0, [edi+0*4] // xmm0 = 5, X, 0, 1 - movss xmm5, [edi+15*4] // xmm4 = 15, X, X, X - movhps xmm5, [edi+10*4] // xmm5 = 15, X, 10, 11 - movaps xmm1, xmm0 // xmm1 = 5, X, 0, 1 - shufps xmm0, xmm5, R_SHUFFLEPS( 2, 0, 2, 0 ) // xmm0 = 0, 5, 10, 15 - movlps xmm1, [edi+6*4] // xmm1 = 6, 7, 0, 1 - movlps xmm5, [edi+16*4] // xmm5 = 16, 17, 10, 11 - movaps xmm2, xmm1 // xmm2 = 6, 7, 0, 1 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm1 = 1, 6, 11, 16 - movhps xmm2, [edi+2*4] // xmm2 = 6, 7, 2, 3 - movhps xmm5, [edi+12*4] // xmm5 = 16, 17, 12, 13 - movaps xmm3, xmm2 // xmm3 = 6, 7, 2, 3 - shufps xmm2, xmm5, R_SHUFFLEPS( 2, 1, 2, 1 ) // xmm2 = 2, 7, 12, 17 - movlps xmm3, [edi+8*4] // xmm3 = 8, 9, 2, 3 - movlps xmm5, [edi+18*4] // xmm5 = 18, 19, 12, 13 - movss xmm4, [edi+4*4] // xmm4 = 4, X, X, X - movlhps xmm4, xmm3 // xmm4 = 4, X, 8, 9 - shufps xmm3, xmm5, R_SHUFFLEPS( 3, 0, 3, 0 ) // xmm3 = 3, 8, 13, 18 - movhps xmm5, [edi+14*4] // xmm6 = 18, 19, 14, 15 - shufps xmm4, xmm5, R_SHUFFLEPS( 0, 3, 2, 1 ) // xmm4 = 4, 9, 14, 19 - movss xmm7, [esi+0*4] - shufps xmm7, xmm7, 0 - mulps xmm0, xmm7 - movss xmm5, [esi+1*4] - shufps xmm5, xmm5, 0 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, 0 - mulps xmm2, xmm6 - addps xmm0, xmm2 - movss xmm1, [esi+3*4] - shufps xmm1, xmm1, 0 - mulps xmm3, xmm1 - addps xmm0, xmm3 - movss xmm2, [esi+4*4] - shufps xmm2, xmm2, 0 - mulps xmm4, xmm2 - addps xmm0, xmm4 - mulss xmm7, [edi+20*4] - mulss xmm5, [edi+21*4] - addps xmm7, xmm5 - mulss xmm6, [edi+22*4] - addps xmm7, xmm6 - mulss xmm1, [edi+23*4] - addps xmm7, xmm1 - mulss xmm2, [edi+24*4] - addps xmm7, xmm2 - STORE4( 0, xmm0, xmm3 ) - STORE1( 16, xmm7, xmm4 ) - } - return; - } - case 6: { // 6x5 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [esi] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm7, [esi+8] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 1, 0, 1 ) - movlps xmm0, [edi] - movhps xmm3, [edi+8] - movaps xmm1, [edi+16] - movlps xmm2, [edi+32] - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm0 = 0, 1, 5, 6 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 4, 7, 8, 9 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 2, 3, 7, 8 - mulps xmm0, xmm6 - mulps xmm3, xmm7 - movlps xmm2, [edi+40] - addps xmm0, xmm3 // xmm0 + xmm1 - movhps xmm5, [edi+40+8] - movlps xmm3, [edi+40+16] - movhps xmm3, [edi+40+24] - movlps xmm4, [edi+40+32] - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm2 = 10, 11, 15, 16 - shufps xmm3, xmm4, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm3 = 14, 17, 18, 19 - shufps xmm5, xmm3, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm5 = 12, 13, 17, 18 - mulps xmm2, xmm6 - mulps xmm5, xmm7 - addps xmm2, xmm5 // xmm2 + xmm3 - movss xmm5, [esi+16] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm0 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm4, xmm2, R_SHUFFLEPS( 1, 3, 1, 3 ) - shufps xmm1, xmm3, R_SHUFFLEPS( 0, 3, 0, 3 ) - addps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - STORE4( 0, xmm0, xmm2 ) - movlps xmm4, [edi+80] - movhps xmm3, [edi+80+8] - movaps xmm1, [edi+80+16] - movlps xmm2, [edi+80+32] - shufps xmm4, xmm1, R_SHUFFLEPS( 0, 1, 1, 2 ) // xmm4 = 20, 21, 25, 26 - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 3, 0, 1 ) // xmm1 = 24, 27, 28, 29 - shufps xmm3, xmm1, R_SHUFFLEPS( 2, 3, 1, 2 ) // xmm3 = 22, 23, 27, 28 - mulps xmm4, xmm6 - mulps xmm3, xmm7 - mulps xmm1, xmm5 - addps xmm4, xmm3 // xmm4 + xmm1 - shufps xmm1, xmm4, R_SHUFFLEPS( 0, 3, 0, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 1, 3, 0, 0 ) - addps xmm4, xmm1 - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 3, 0, 1 ) - addps xmm4, xmm1 - STORE2LO( 16, xmm4, xmm2 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4]; - mPtr += 5; - } - return; - } - } - break; - } - case 6: { - switch( numRows ) { - case 1: { // 1x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - mulss xmm0, [edi] - movss xmm1, [esi+4] - mulss xmm1, [edi+4] - movss xmm2, [esi+8] - addss xmm0, xmm1 - mulss xmm2, [edi+8] - movss xmm3, [esi+12] - addss xmm0, xmm2 - mulss xmm3, [edi+12] - movss xmm4, [esi+16] - addss xmm0, xmm3 - mulss xmm4, [edi+16] - movss xmm5, [esi+20] - addss xmm0, xmm4 - mulss xmm5, [edi+20] - movss xmm6, [esi+24] - addss xmm0, xmm5 - mulss xmm6, [edi+24] - addss xmm0, xmm6 - STORE1( 0, xmm0, xmm7 ) - } - return; - } - case 2: { // 2x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - } - return; - } - case 3: { // 3x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 1, 3 ) - movhlps xmm0, xmm1 - addps xmm0, xmm1 - STORE2LO( 0, xmm0, xmm3 ) - // row 2 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - STORE1( 8, xmm0, xmm3 ) - } - return; - } - case 4: { // 4x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm4 ) - } - return; - } - case 5: { // 5x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - // load idVecX - movlps xmm4, [esi] - movhps xmm4, [esi+8] - movlps xmm5, [esi+16] - movlhps xmm5, xmm4 - movhlps xmm6, xmm4 - movlhps xmm6, xmm5 - // row 0 and 1 - movaps xmm0, [edi] - movaps xmm1, [edi+16] - movaps xmm2, [edi+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm7, xmm0 - movlhps xmm7, xmm2 - addps xmm7, xmm1 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm7, xmm0 - // row 2 and 3 - movaps xmm0, [edi+48] - movaps xmm1, [edi+48+16] - movaps xmm2, [edi+48+32] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - mulps xmm2, xmm6 - movhlps xmm3, xmm0 - movlhps xmm3, xmm2 - addps xmm1, xmm3 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 2, 3 ) - addps xmm1, xmm0 - // last 4 additions for the first 4 rows and store result - movaps xmm0, xmm7 - shufps xmm7, xmm1, R_SHUFFLEPS( 0, 2, 0, 2 ) - shufps xmm0, xmm1, R_SHUFFLEPS( 1, 3, 1, 3 ) - addps xmm0, xmm7 - STORE4( 0, xmm0, xmm3 ) - // row 5 - movaps xmm0, [edi+96] - movaps xmm1, [edi+96+16] - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 0x01 - addss xmm0, xmm1 - STORE1( 16, xmm0, xmm3 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm7, qword ptr [esi] - movlps xmm6, qword ptr [esi+8] - shufps xmm7, xmm7, 0x44 - shufps xmm6, xmm6, 0x44 - movlps xmm0, qword ptr [edi ] - movhps xmm0, qword ptr [edi+ 24] - mulps xmm0, xmm7 - movlps xmm3, qword ptr [edi+ 8] - movhps xmm3, qword ptr [edi+ 32] - mulps xmm3, xmm6 - movlps xmm1, qword ptr [edi+ 48] - movhps xmm1, qword ptr [edi+ 72] - mulps xmm1, xmm7 - movlps xmm2, qword ptr [edi+ 96] - movhps xmm2, qword ptr [edi+120] - mulps xmm2, xmm7 - movlps xmm4, qword ptr [edi+ 56] - movhps xmm4, qword ptr [edi+ 80] - movlps xmm5, qword ptr [edi+104] - movhps xmm5, qword ptr [edi+128] - mulps xmm4, xmm6 - movlps xmm7, qword ptr [esi+16] - addps xmm0, xmm3 - shufps xmm7, xmm7, 0x44 - mulps xmm5, xmm6 - addps xmm1, xmm4 - movlps xmm3, qword ptr [edi+ 16] - movhps xmm3, qword ptr [edi+ 40] - addps xmm2, xmm5 - movlps xmm4, qword ptr [edi+ 64] - movhps xmm4, qword ptr [edi+ 88] - mulps xmm3, xmm7 - movlps xmm5, qword ptr [edi+112] - movhps xmm5, qword ptr [edi+136] - addps xmm0, xmm3 - mulps xmm4, xmm7 - mulps xmm5, xmm7 - addps xmm1, xmm4 - addps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm0, xmm1, 0x88 - shufps xmm6, xmm1, 0xDD - movaps xmm7, xmm2 - shufps xmm7, xmm2, 0x88 - shufps xmm2, xmm2, 0xDD - addps xmm0, xmm6 - addps xmm2, xmm7 - STORE4( 0, xmm0, xmm3 ) - STORE2LO( 16, xmm2, xmm4 ) - } - return; - } - default: { - for ( int i = 0; i < numRows; i++ ) { - dstPtr[i] STOREC mPtr[0] * vPtr[0] + mPtr[1] * vPtr[1] + mPtr[2] * vPtr[2] + - mPtr[3] * vPtr[3] + mPtr[4] * vPtr[4] + mPtr[5] * vPtr[5]; - mPtr += 6; - } - return; - } - } - break; - } - default: { - int numColumns = mat.GetNumColumns(); - for ( int i = 0; i < numRows; i++ ) { - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numColumns; j++ ) { - sum += mPtr[j] * vPtr[j]; - } - dstPtr[i] STOREC sum; - mPtr += numColumns; - } - break; - } - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -idSIMD_SSE::MatX_TransposeMultiplyVecX - - optimizes the following matrix multiplications: - - Nx6 * Nx1 - 6xN * 6x1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss [eax+offset], reg1 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps [eax+offset], reg1 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps [eax+offset], reg1 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps [eax+offset], reg1 \ - __asm movhps [eax+offset+8], reg1 -#define STOREC = - - int numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - switch( numColumns ) { - case 6: { // 1x6 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm3 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0]; - mPtr++; - } - return; - } - } - break; - case 2: - switch( numColumns ) { - case 6: { // 2x6 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movaps xmm1, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - movaps xmm2, [edi] - mulps xmm2, xmm0 - movlps xmm3, [edi+24] - movhps xmm3, [edi+32] - mulps xmm3, xmm1 - addps xmm2, xmm3 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm4, [edi+16] - movhps xmm4, [edi+40] - mulps xmm4, xmm0 - movhlps xmm3, xmm4 - addps xmm3, xmm4 - STORE4( 0, xmm2, xmm5 ) - STORE2LO( 16, xmm3, xmm6 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - return; - } - } - break; - case 3: - switch( numColumns ) { - case 6: { // 3x6 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movss xmm1, [esi+2*4] - movlps xmm3, [edi+(0*6+0)*4] - movhps xmm3, [edi+(0*6+2)*4] - movaps xmm4, xmm0 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm1 - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(2*6+4)*4] - mulps xmm5, xmm1 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - return; - } - } - break; - case 4: - switch( numColumns ) { - case 6: { // 4x6 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - return; - } - } - break; - case 5: - switch( numColumns ) { - case 6: { // 5x6 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movss xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm2 - mulps xmm4, [edi+(4*6+0)*4] - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - return; - } - } - break; - case 6: - switch( numColumns ) { - case 1: { // 6x1 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movhps xmm0, [esi+8] - movlps xmm1, [esi+16] - mulps xmm0, [edi] - mulps xmm1, [edi+16] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) - addps xmm0, xmm1 - movhlps xmm2, xmm0 - addss xmm2, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm2, xmm0 - STORE1( 0, xmm2, xmm3 ) - } - return; - } - case 2: { // 6x2 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm6, [edi+0*4] - mulps xmm6, xmm0 - movlps xmm1, [esi+2*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+4*4] - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm2, [esi+4*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+8*4] - mulps xmm7, xmm2 - addps xmm6, xmm7 - movhlps xmm3, xmm6 - addps xmm3, xmm6 - STORE2LO( 0, xmm3, xmm7 ) - } - return; - } - case 3: { // 6x3 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+(0*3+2)*4] - movhps xmm0, [edi+(0*3+0)*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm6, [esi+0*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movss xmm1, [edi+(1*3+0)*4] - movhps xmm1, [edi+(1*3+1)*4] - movss xmm7, [esi+1*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movss xmm2, [edi+(2*3+2)*4] - movhps xmm2, [edi+(2*3+0)*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+2*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movss xmm3, [edi+(3*3+0)*4] - movhps xmm3, [edi+(3*3+1)*4] - movss xmm7, [esi+3*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movss xmm4, [edi+(4*3+2)*4] - movhps xmm4, [edi+(4*3+0)*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+4*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movss xmm5, [edi+(5*3+0)*4] - movhps xmm5, [edi+(5*3+1)*4] - movss xmm7, [esi+5*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE1( 0, xmm6, xmm7 ) - STORE2HI( 4, xmm6, xmm7 ) - } - return; - } - case 4: { // 6x4 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm3, [edi+(0*4+0)*4] - movhps xmm3, [edi+(0*4+2)*4] - movss xmm4, [esi+0*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*4+0)*4] - movhps xmm5, [edi+(1*4+2)*4] - movss xmm6, [esi+1*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*4+0)*4] - movhps xmm4, [edi+(2*4+2)*4] - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*4+0)*4] - movhps xmm5, [edi+(3*4+2)*4] - movss xmm6, [esi+3*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(4*4+0)*4] - movhps xmm4, [edi+(4*4+2)*4] - movss xmm6, [esi+4*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(5*4+0)*4] - movhps xmm5, [edi+(5*4+2)*4] - movss xmm6, [esi+5*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - } - return; - } - case 5: { // 6x5 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [edi+(0*5+0)*4] - movhps xmm6, [edi+(0*5+2)*4] - movss xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movlps xmm7, [edi+(1*5+0)*4] - movhps xmm7, [edi+(1*5+2)*4] - movss xmm1, [esi+1*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm7, [edi+(2*5+0)*4] - movhps xmm7, [edi+(2*5+2)*4] - movss xmm2, [esi+2*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movlps xmm7, [edi+(3*5+0)*4] - movhps xmm7, [edi+(3*5+2)*4] - movss xmm3, [esi+3*4] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movlps xmm7, [edi+(4*5+0)*4] - movhps xmm7, [edi+(4*5+2)*4] - movss xmm4, [esi+4*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movlps xmm7, [edi+(5*5+0)*4] - movhps xmm7, [edi+(5*5+2)*4] - movss xmm5, [esi+5*4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE4( 0, xmm6, xmm7 ) - movss xmm6, [edi+(0*5+4)*4] - mulss xmm6, xmm0 - movss xmm7, [edi+(1*5+4)*4] - mulss xmm7, xmm1 - addss xmm6, xmm7 - movss xmm7, [edi+(2*5+4)*4] - mulss xmm7, xmm2 - addss xmm6, xmm7 - movss xmm7, [edi+(3*5+4)*4] - mulss xmm7, xmm3 - addss xmm6, xmm7 - movss xmm7, [edi+(4*5+4)*4] - mulss xmm7, xmm4 - addss xmm6, xmm7 - movss xmm7, [edi+(5*5+4)*4] - mulss xmm7, xmm5 - addss xmm6, xmm7 - STORE1( 16, xmm6, xmm7 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movlps xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(4*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(5*6+0)*4] - movhps xmm5, [edi+(5*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - movhps xmm5, [edi+(5*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - return; - } - } - break; - default: - int numRows = mat.GetNumRows(); - for ( int i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] STOREC sum; - } - break; - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -idSIMD_SSE::MatX_TransposeMultiplyAddVecX - - optimizes the following matrix multiplications: - - Nx6 * Nx1 - 6xN * 6x1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss reg2, [eax+offset] \ - __asm addss reg2, reg1 \ - __asm movss [eax+offset], reg2 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm addps reg2, reg1 \ - __asm movlps [eax+offset], reg2 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps reg2, [eax+offset] \ - __asm addps reg2, reg1 \ - __asm movhps [eax+offset], reg2 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm movhps reg2, [eax+offset+8] \ - __asm addps reg2, reg1 \ - __asm movlps [eax+offset], reg2 \ - __asm movhps [eax+offset+8], reg2 -#define STOREC += - - int numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - switch( numColumns ) { - case 6: { // 1x6 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm3 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0]; - mPtr++; - } - return; - } - } - break; - case 2: - switch( numColumns ) { - case 6: { // 2x6 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movaps xmm1, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - movaps xmm2, [edi] - mulps xmm2, xmm0 - movlps xmm3, [edi+24] - movhps xmm3, [edi+32] - mulps xmm3, xmm1 - addps xmm2, xmm3 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm4, [edi+16] - movhps xmm4, [edi+40] - mulps xmm4, xmm0 - movhlps xmm3, xmm4 - addps xmm3, xmm4 - STORE4( 0, xmm2, xmm5 ) - STORE2LO( 16, xmm3, xmm6 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - return; - } - } - break; - case 3: - switch( numColumns ) { - case 6: { // 3x6 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movss xmm1, [esi+2*4] - movlps xmm3, [edi+(0*6+0)*4] - movhps xmm3, [edi+(0*6+2)*4] - movaps xmm4, xmm0 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm1 - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(2*6+4)*4] - mulps xmm5, xmm1 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - return; - } - } - break; - case 4: - switch( numColumns ) { - case 6: { // 4x6 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - return; - } - } - break; - case 5: - switch( numColumns ) { - case 6: { // 5x6 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movss xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm2 - mulps xmm4, [edi+(4*6+0)*4] - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - return; - } - } - break; - case 6: - switch( numColumns ) { - case 1: { // 6x1 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movhps xmm0, [esi+8] - movlps xmm1, [esi+16] - mulps xmm0, [edi] - mulps xmm1, [edi+16] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) - addps xmm0, xmm1 - movhlps xmm2, xmm0 - addss xmm2, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm2, xmm0 - STORE1( 0, xmm2, xmm3 ) - } - return; - } - case 2: { // 6x2 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm6, [edi+0*4] - mulps xmm6, xmm0 - movlps xmm1, [esi+2*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+4*4] - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm2, [esi+4*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+8*4] - mulps xmm7, xmm2 - addps xmm6, xmm7 - movhlps xmm3, xmm6 - addps xmm3, xmm6 - STORE2LO( 0, xmm3, xmm7 ) - } - return; - } - case 3: { // 6x3 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+(0*3+2)*4] - movhps xmm0, [edi+(0*3+0)*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm6, [esi+0*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movss xmm1, [edi+(1*3+0)*4] - movhps xmm1, [edi+(1*3+1)*4] - movss xmm7, [esi+1*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movss xmm2, [edi+(2*3+2)*4] - movhps xmm2, [edi+(2*3+0)*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+2*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movss xmm3, [edi+(3*3+0)*4] - movhps xmm3, [edi+(3*3+1)*4] - movss xmm7, [esi+3*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movss xmm4, [edi+(4*3+2)*4] - movhps xmm4, [edi+(4*3+0)*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+4*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movss xmm5, [edi+(5*3+0)*4] - movhps xmm5, [edi+(5*3+1)*4] - movss xmm7, [esi+5*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE1( 0, xmm6, xmm7 ) - STORE2HI( 4, xmm6, xmm7 ) - } - return; - } - case 4: { // 6x4 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm3, [edi+(0*4+0)*4] - movhps xmm3, [edi+(0*4+2)*4] - movss xmm4, [esi+0*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*4+0)*4] - movhps xmm5, [edi+(1*4+2)*4] - movss xmm6, [esi+1*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*4+0)*4] - movhps xmm4, [edi+(2*4+2)*4] - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*4+0)*4] - movhps xmm5, [edi+(3*4+2)*4] - movss xmm6, [esi+3*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(4*4+0)*4] - movhps xmm4, [edi+(4*4+2)*4] - movss xmm6, [esi+4*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(5*4+0)*4] - movhps xmm5, [edi+(5*4+2)*4] - movss xmm6, [esi+5*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - } - return; - } - case 5: { // 6x5 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [edi+(0*5+0)*4] - movhps xmm6, [edi+(0*5+2)*4] - movss xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movlps xmm7, [edi+(1*5+0)*4] - movhps xmm7, [edi+(1*5+2)*4] - movss xmm1, [esi+1*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm7, [edi+(2*5+0)*4] - movhps xmm7, [edi+(2*5+2)*4] - movss xmm2, [esi+2*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movlps xmm7, [edi+(3*5+0)*4] - movhps xmm7, [edi+(3*5+2)*4] - movss xmm3, [esi+3*4] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movlps xmm7, [edi+(4*5+0)*4] - movhps xmm7, [edi+(4*5+2)*4] - movss xmm4, [esi+4*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movlps xmm7, [edi+(5*5+0)*4] - movhps xmm7, [edi+(5*5+2)*4] - movss xmm5, [esi+5*4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE4( 0, xmm6, xmm7 ) - movss xmm6, [edi+(0*5+4)*4] - mulss xmm6, xmm0 - movss xmm7, [edi+(1*5+4)*4] - mulss xmm7, xmm1 - addss xmm6, xmm7 - movss xmm7, [edi+(2*5+4)*4] - mulss xmm7, xmm2 - addss xmm6, xmm7 - movss xmm7, [edi+(3*5+4)*4] - mulss xmm7, xmm3 - addss xmm6, xmm7 - movss xmm7, [edi+(4*5+4)*4] - mulss xmm7, xmm4 - addss xmm6, xmm7 - movss xmm7, [edi+(5*5+4)*4] - mulss xmm7, xmm5 - addss xmm6, xmm7 - STORE1( 16, xmm6, xmm7 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movlps xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(4*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(5*6+0)*4] - movhps xmm5, [edi+(5*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - movhps xmm5, [edi+(5*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - return; - } - } - break; - default: - int numRows = mat.GetNumRows(); - for ( int i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] STOREC sum; - } - break; - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -void idSIMD_SSE::MatX_TransposeMultiplySubVecX - - optimizes the following matrix multiplications: - - Nx6 * Nx1 - 6xN * 6x1 - - with N in the range [1-6] -============ -*/ -void VPCALL idSIMD_SSE::MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ) { -#define STORE1( offset, reg1, reg2 ) \ - __asm movss reg2, [eax+offset] \ - __asm subss reg2, reg1 \ - __asm movss [eax+offset], reg2 -#define STORE2LO( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm subps reg2, reg1 \ - __asm movlps [eax+offset], reg2 -#define STORE2HI( offset, reg1, reg2 ) \ - __asm movhps reg2, [eax+offset] \ - __asm subps reg2, reg1 \ - __asm movhps [eax+offset], reg2 -#define STORE4( offset, reg1, reg2 ) \ - __asm movlps reg2, [eax+offset] \ - __asm movhps reg2, [eax+offset+8] \ - __asm subps reg2, reg1 \ - __asm movlps [eax+offset], reg2 \ - __asm movhps [eax+offset+8], reg2 -#define STOREC -= - - int numColumns; - const float *mPtr, *vPtr; - float *dstPtr; - - assert( vec.GetSize() >= mat.GetNumRows() ); - assert( dst.GetSize() >= mat.GetNumColumns() ); - - mPtr = mat.ToFloatPtr(); - vPtr = vec.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - numColumns = mat.GetNumColumns(); - switch( mat.GetNumRows() ) { - case 1: - switch( numColumns ) { - case 6: { // 1x6 * 1x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - STORE4( 0, xmm0, xmm2 ) - STORE2LO( 16, xmm1, xmm3 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0]; - mPtr++; - } - return; - } - } - break; - case 2: - switch( numColumns ) { - case 6: { // 2x6 * 2x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movaps xmm1, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - movaps xmm2, [edi] - mulps xmm2, xmm0 - movlps xmm3, [edi+24] - movhps xmm3, [edi+32] - mulps xmm3, xmm1 - addps xmm2, xmm3 - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm4, [edi+16] - movhps xmm4, [edi+40] - mulps xmm4, xmm0 - movhlps xmm3, xmm4 - addps xmm3, xmm4 - STORE4( 0, xmm2, xmm5 ) - STORE2LO( 16, xmm3, xmm6 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1]; - mPtr++; - } - return; - } - } - break; - case 3: - switch( numColumns ) { - case 6: { // 3x6 * 3x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movss xmm1, [esi+2*4] - movlps xmm3, [edi+(0*6+0)*4] - movhps xmm3, [edi+(0*6+2)*4] - movaps xmm4, xmm0 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm1 - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(2*6+4)*4] - mulps xmm5, xmm1 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2]; - mPtr++; - } - return; - } - } - break; - case 4: - switch( numColumns ) { - case 6: { // 4x6 * 4x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*6+0)*4] - movhps xmm4, [edi+(2*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3]; - mPtr++; - } - return; - } - } - break; - case 5: - switch( numColumns ) { - case 6: { // 5x6 * 5x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movss xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm4, xmm2 - mulps xmm4, [edi+(4*6+0)*4] - addps xmm3, xmm4 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4]; - mPtr++; - } - return; - } - } - break; - case 6: - switch( numColumns ) { - case 1: { // 6x1 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi] - movhps xmm0, [esi+8] - movlps xmm1, [esi+16] - mulps xmm0, [edi] - mulps xmm1, [edi+16] - shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 3, 2 ) - addps xmm0, xmm1 - movhlps xmm2, xmm0 - addss xmm2, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm2, xmm0 - STORE1( 0, xmm2, xmm3 ) - } - return; - } - case 2: { // 6x2 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm6, [edi+0*4] - mulps xmm6, xmm0 - movlps xmm1, [esi+2*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+4*4] - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm2, [esi+4*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm7, [edi+8*4] - mulps xmm7, xmm2 - addps xmm6, xmm7 - movhlps xmm3, xmm6 - addps xmm3, xmm6 - STORE2LO( 0, xmm3, xmm7 ) - } - return; - } - case 3: { // 6x3 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movss xmm0, [edi+(0*3+2)*4] - movhps xmm0, [edi+(0*3+0)*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm6, [esi+0*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movss xmm1, [edi+(1*3+0)*4] - movhps xmm1, [edi+(1*3+1)*4] - movss xmm7, [esi+1*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movss xmm2, [edi+(2*3+2)*4] - movhps xmm2, [edi+(2*3+0)*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+2*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movss xmm3, [edi+(3*3+0)*4] - movhps xmm3, [edi+(3*3+1)*4] - movss xmm7, [esi+3*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movss xmm4, [edi+(4*3+2)*4] - movhps xmm4, [edi+(4*3+0)*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 2, 1, 3, 0 ) - movss xmm7, [esi+4*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movss xmm5, [edi+(5*3+0)*4] - movhps xmm5, [edi+(5*3+1)*4] - movss xmm7, [esi+5*4] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE1( 0, xmm6, xmm7 ) - STORE2HI( 4, xmm6, xmm7 ) - } - return; - } - case 4: { // 6x4 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm3, [edi+(0*4+0)*4] - movhps xmm3, [edi+(0*4+2)*4] - movss xmm4, [esi+0*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm4 - movlps xmm5, [edi+(1*4+0)*4] - movhps xmm5, [edi+(1*4+2)*4] - movss xmm6, [esi+1*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(2*4+0)*4] - movhps xmm4, [edi+(2*4+2)*4] - movss xmm6, [esi+2*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(3*4+0)*4] - movhps xmm5, [edi+(3*4+2)*4] - movss xmm6, [esi+3*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movlps xmm4, [edi+(4*4+0)*4] - movhps xmm4, [edi+(4*4+2)*4] - movss xmm6, [esi+4*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm6 - addps xmm3, xmm4 - movlps xmm5, [edi+(5*4+0)*4] - movhps xmm5, [edi+(5*4+2)*4] - movss xmm6, [esi+5*4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - } - return; - } - case 5: { // 6x5 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm6, [edi+(0*5+0)*4] - movhps xmm6, [edi+(0*5+2)*4] - movss xmm0, [esi+0*4] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movlps xmm7, [edi+(1*5+0)*4] - movhps xmm7, [edi+(1*5+2)*4] - movss xmm1, [esi+1*4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movlps xmm7, [edi+(2*5+0)*4] - movhps xmm7, [edi+(2*5+2)*4] - movss xmm2, [esi+2*4] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - movlps xmm7, [edi+(3*5+0)*4] - movhps xmm7, [edi+(3*5+2)*4] - movss xmm3, [esi+3*4] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm3 - addps xmm6, xmm7 - movlps xmm7, [edi+(4*5+0)*4] - movhps xmm7, [edi+(4*5+2)*4] - movss xmm4, [esi+4*4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movlps xmm7, [edi+(5*5+0)*4] - movhps xmm7, [edi+(5*5+2)*4] - movss xmm5, [esi+5*4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - STORE4( 0, xmm6, xmm7 ) - movss xmm6, [edi+(0*5+4)*4] - mulss xmm6, xmm0 - movss xmm7, [edi+(1*5+4)*4] - mulss xmm7, xmm1 - addss xmm6, xmm7 - movss xmm7, [edi+(2*5+4)*4] - mulss xmm7, xmm2 - addss xmm6, xmm7 - movss xmm7, [edi+(3*5+4)*4] - mulss xmm7, xmm3 - addss xmm6, xmm7 - movss xmm7, [edi+(4*5+4)*4] - mulss xmm7, xmm4 - addss xmm6, xmm7 - movss xmm7, [edi+(5*5+4)*4] - mulss xmm7, xmm5 - addss xmm6, xmm7 - STORE1( 16, xmm6, xmm7 ) - } - return; - } - case 6: { // 6x6 * 6x1 - __asm { - mov esi, vPtr - mov edi, mPtr - mov eax, dstPtr - movlps xmm0, [esi+0*4] - movlps xmm1, [esi+2*4] - movlps xmm2, [esi+4*4] - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, [edi+(0*6+0)*4] - movlps xmm5, [edi+(1*6+0)*4] - movhps xmm5, [edi+(1*6+2)*4] - movaps xmm6, xmm0 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(2*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(3*6+0)*4] - movhps xmm5, [edi+(3*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, [edi+(4*6+0)*4] - addps xmm3, xmm6 - movaps xmm6, xmm2 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - movlps xmm5, [edi+(5*6+0)*4] - movhps xmm5, [edi+(5*6+2)*4] - mulps xmm5, xmm6 - addps xmm3, xmm5 - STORE4( 0, xmm3, xmm7 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - movlps xmm3, [edi+(0*6+4)*4] - movhps xmm3, [edi+(1*6+4)*4] - mulps xmm3, xmm0 - movlps xmm4, [edi+(2*6+4)*4] - movhps xmm4, [edi+(3*6+4)*4] - mulps xmm4, xmm1 - addps xmm3, xmm4 - movlps xmm5, [edi+(4*6+4)*4] - movhps xmm5, [edi+(5*6+4)*4] - mulps xmm5, xmm2 - addps xmm3, xmm5 - movhlps xmm4, xmm3 - addps xmm3, xmm4 - STORE2LO( 16, xmm3, xmm7 ) - } - return; - } - default: { - for ( int i = 0; i < numColumns; i++ ) { - dstPtr[i] STOREC *(mPtr) * vPtr[0] + *(mPtr+numColumns) * vPtr[1] + *(mPtr+2*numColumns) * vPtr[2] + - *(mPtr+3*numColumns) * vPtr[3] + *(mPtr+4*numColumns) * vPtr[4] + *(mPtr+5*numColumns) * vPtr[5]; - mPtr++; - } - return; - } - } - break; - default: - int numRows = mat.GetNumRows(); - for ( int i = 0; i < numColumns; i++ ) { - mPtr = mat.ToFloatPtr() + i; - float sum = mPtr[0] * vPtr[0]; - for ( int j = 1; j < numRows; j++ ) { - mPtr += numColumns; - sum += mPtr[0] * vPtr[j]; - } - dstPtr[i] STOREC sum; - } - break; - } - -#undef STOREC -#undef STORE4 -#undef STORE2HI -#undef STORE2LO -#undef STORE1 -} - -/* -============ -idSIMD_SSE::MatX_MultiplyMatX - - optimizes the following matrix multiplications: - - NxN * Nx6 - 6xN * Nx6 - Nx6 * 6xN - 6x6 * 6xN - - with N in the range [1-6]. - - The hot cache clock cycle counts are generally better for the SIMD version than the - FPU version. At times up to 40% less clock cycles on a P3. In practise however, - the results are poor probably due to memory access. -============ -*/ -void VPCALL idSIMD_SSE::MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( m1.GetNumColumns() == m2.GetNumRows() ); - - dstPtr = dst.ToFloatPtr(); - m1Ptr = m1.ToFloatPtr(); - m2Ptr = m2.ToFloatPtr(); - k = m1.GetNumRows(); - l = m2.GetNumColumns(); - n = m1.GetNumColumns(); - - switch( n ) { - case 1: { - if ( !(l^6) ) { - switch( k ) { - case 1: { // 1x1 * 1x6, no precision loss compared to FPU version - __asm { - mov esi, m2Ptr - mov edi, m1Ptr - mov eax, dstPtr - movss xmm0, [edi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, [esi] - mulps xmm1, xmm0 - movaps [eax], xmm1 - movlps xmm2, [esi+16] - mulps xmm2, xmm0 - movlps [eax+16], xmm2 - } - return; - } - case 6: { // 6x1 * 1x6, no precision loss compared to FPU version - __asm { - mov esi, m2Ptr - mov edi, m1Ptr - mov eax, dstPtr - xorps xmm1, xmm1 - movaps xmm0, [edi] - movlps xmm1, [edi+16] - movlhps xmm1, xmm0 - movhlps xmm2, xmm0 - movlhps xmm2, xmm1 - // row 0 and 1 - movaps xmm3, [esi] - movaps xmm4, xmm3 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm5, xmm3 - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) - movaps xmm6, xmm3 - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - movaps [eax], xmm4 - movaps [eax+16], xmm5 - movaps [eax+32], xmm6 - // row 2 and 3 - movaps xmm4, xmm3 - shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 2, 2 ) - movaps xmm5, xmm3 - shufps xmm5, xmm5, R_SHUFFLEPS( 2, 2, 3, 3 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm3, xmm2 - movaps [eax+48], xmm4 - movaps [eax+64], xmm5 - movaps [eax+80], xmm3 - // row 4 and 5 - movlps xmm3, [esi+16] - movaps xmm4, xmm3 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm5, xmm3 - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm3, xmm2 - movaps [eax+96], xmm4 - movaps [eax+112], xmm5 - movaps [eax+128], xmm3 - } - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0]; - m2Ptr++; - } - m1Ptr++; - } - break; - } - case 2: { - if ( !(l^6) ) { - switch( k ) { - case 2: { // 2x2 * 2x6 - - #define MUL_Nx2_2x6_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movaps xmm0, [esi] \ - __asm movlps xmm1, [esi+16] \ - __asm movhps xmm1, [esi+40] \ - __asm movlps xmm2, [esi+24] \ - __asm movhps xmm2, [esi+32] - - #define MUL_Nx2_2x6_ROW2( row ) \ - __asm movaps xmm3, [edi+row*16] \ - __asm movaps xmm5, xmm0 \ - __asm movaps xmm4, xmm3 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm4 \ - __asm movaps xmm4, xmm3 \ - __asm movaps xmm6, xmm2 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 1, 1, 1, 1 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm5, xmm6 \ - __asm movaps [eax+row*48], xmm5 \ - __asm movaps xmm4, xmm3 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm movaps xmm7, xmm1 \ - __asm mulps xmm7, xmm4 \ - __asm movaps xmm4, xmm3 \ - __asm movaps xmm5, xmm0 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 2, 2 ) \ - __asm mulps xmm5, xmm4 \ - __asm movaps xmm4, xmm3 \ - __asm movaps xmm6, xmm2 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 3, 3, 3, 3 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm5, xmm6 \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 2, 2, 3, 3 ) \ - __asm movaps xmm6, xmm1 \ - __asm mulps xmm6, xmm3 \ - __asm movaps xmm4, xmm7 \ - __asm movlhps xmm7, xmm6 \ - __asm movhlps xmm6, xmm4 \ - __asm addps xmm6, xmm7 \ - __asm movlps [eax+row*48+16], xmm6 \ - __asm movlps [eax+row*48+24], xmm5 \ - __asm movhps [eax+row*48+32], xmm5 \ - __asm movhps [eax+row*48+40], xmm6 - - MUL_Nx2_2x6_INIT - MUL_Nx2_2x6_ROW2( 0 ) - - return; - } - case 6: { // 6x2 * 2x6 - - MUL_Nx2_2x6_INIT - MUL_Nx2_2x6_ROW2( 0 ) - MUL_Nx2_2x6_ROW2( 1 ) - MUL_Nx2_2x6_ROW2( 2 ) - - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l]; - m2Ptr++; - } - m1Ptr += 2; - } - break; - } - case 3: { - if ( !(l^6) ) { - switch( k ) { - case 3: { // 3x3 * 3x6 - __asm { - mov esi, m2Ptr - mov edi, m1Ptr - mov eax, dstPtr - movaps xmm5, xmmword ptr [esi] - movlps xmm6, qword ptr [esi+24] - movhps xmm6, qword ptr [esi+32] - movaps xmm7, xmmword ptr [esi+48] - movss xmm0, dword ptr [edi] - shufps xmm0, xmm0, 0 - mulps xmm0, xmm5 - movss xmm1, dword ptr [edi+4] - shufps xmm1, xmm1, 0 - mulps xmm1, xmm6 - movss xmm2, dword ptr [edi+8] - shufps xmm2, xmm2, 0 - mulps xmm2, xmm7 - addps xmm0, xmm1 - addps xmm0, xmm2 - movaps xmmword ptr [eax], xmm0 - movss xmm3, dword ptr [edi+12] - shufps xmm3, xmm3, 0 - mulps xmm3, xmm5 - movss xmm4, dword ptr [edi+16] - shufps xmm4, xmm4, 0 - mulps xmm4, xmm6 - movss xmm0, dword ptr [edi+20] - shufps xmm0, xmm0, 0 - mulps xmm0, xmm7 - addps xmm3, xmm4 - addps xmm0, xmm3 - movlps qword ptr [eax+24], xmm0 - movhps qword ptr [eax+32], xmm0 - movss xmm1, dword ptr [edi+24] - shufps xmm1, xmm1, 0 - mulps xmm1, xmm5 - movss xmm2, dword ptr [edi+28] - shufps xmm2, xmm2, 0 - mulps xmm2, xmm6 - movss xmm3, dword ptr [edi+32] - shufps xmm3, xmm3, 0 - mulps xmm3, xmm7 - addps xmm1, xmm2 - addps xmm1, xmm3 - movaps xmmword ptr [eax+48], xmm1 - movlps xmm5, qword ptr [esi+16] - movlps xmm6, qword ptr [esi+40] - movlps xmm7, qword ptr [esi+64] - shufps xmm5, xmm5, 0x44 - shufps xmm6, xmm6, 0x44 - shufps xmm7, xmm7, 0x44 - movaps xmm3, xmmword ptr [edi] - movlps xmm4, qword ptr [edi+16] - movaps xmm0, xmm3 - shufps xmm0, xmm0, 0xF0 - mulps xmm0, xmm5 - movaps xmm1, xmm3 - shufps xmm1, xmm4, 0x05 - mulps xmm1, xmm6 - shufps xmm3, xmm4, 0x5A - mulps xmm3, xmm7 - addps xmm1, xmm0 - addps xmm1, xmm3 - movlps qword ptr [eax+16], xmm1 - movhps qword ptr [eax+40], xmm1 - movss xmm0, dword ptr [edi+24] - shufps xmm0, xmm0, 0 - mulps xmm0, xmm5 - movss xmm2, dword ptr [edi+28] - shufps xmm2, xmm2, 0 - mulps xmm2, xmm6 - movss xmm4, dword ptr [edi+32] - shufps xmm4, xmm4, 0 - mulps xmm4, xmm7 - addps xmm0, xmm2 - addps xmm0, xmm4 - movlps qword ptr [eax+64], xmm0 - } - return; - } - case 6: { // 6x3 * 3x6 - #define MUL_Nx3_3x6_FIRST4COLUMNS_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 2*4] \ - __asm movlps xmm1, [esi+ 6*4] \ - __asm movhps xmm1, [esi+ 8*4] \ - __asm movlps xmm2, [esi+12*4] \ - __asm movhps xmm2, [esi+14*4] - - #define MUL_Nx3_3x6_FIRST4COLUMNS_ROW( row ) \ - __asm movss xmm3, [edi+(row*3+0)*4] \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm3, xmm0 \ - __asm movss xmm4, [edi+(row*3+1)*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm4, xmm1 \ - __asm addps xmm3, xmm4 \ - __asm movss xmm5, [edi+(row*3+2)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm5 \ - __asm movlps [eax+(row*6+0)*4], xmm3 \ - __asm movhps [eax+(row*6+2)*4], xmm3 - - #define MUL_Nx3_3x6_LAST2COLUMNS_ROW6 \ - __asm movlps xmm0, [esi+ 4*4] \ - __asm movlps xmm1, [esi+10*4] \ - __asm movlps xmm2, [esi+16*4] \ - __asm shufps xmm0, xmm0, 0x44 \ - __asm shufps xmm1, xmm1, 0x44 \ - __asm shufps xmm2, xmm2, 0x44 \ - __asm movlps xmm3, [edi+0*4] \ - __asm movhps xmm3, [edi+2*4] \ - __asm movaps xmm4, xmm3 \ - __asm movaps xmm5, xmm3 \ - __asm shufps xmm3, xmm3, 0xF0 \ - __asm mulps xmm3, xmm0 \ - __asm movlps xmm6, [edi+4*4] \ - __asm movhps xmm6, [edi+6*4] \ - __asm shufps xmm4, xmm6, 0x05 \ - __asm mulps xmm4, xmm1 \ - __asm addps xmm3, xmm4 \ - __asm shufps xmm5, xmm6, 0x5A \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm5 \ - __asm movlps [eax+4*4], xmm3 \ - __asm movhps [eax+10*4], xmm3 \ - __asm movaps xmm5, xmm6 \ - __asm movlps xmm3, [edi+8*4] \ - __asm movhps xmm3, [edi+10*4] \ - __asm movaps xmm4, xmm3 \ - __asm shufps xmm5, xmm3, 0x5A \ - __asm mulps xmm5, xmm0 \ - __asm shufps xmm6, xmm3, 0xAF \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm5, xmm6 \ - __asm shufps xmm4, xmm4, 0xF0 \ - __asm mulps xmm4, xmm2 \ - __asm addps xmm4, xmm5 \ - __asm movlps [eax+16*4], xmm4 \ - __asm movhps [eax+22*4], xmm4 \ - __asm movlps xmm6, [edi+12*4] \ - __asm movhps xmm6, [edi+14*4] \ - __asm movaps xmm5, xmm6 \ - __asm movaps xmm4, xmm6 \ - __asm shufps xmm6, xmm6, 0xF0 \ - __asm mulps xmm6, xmm0 \ - __asm movlps xmm3, [edi+16*4] \ - __asm shufps xmm5, xmm3, 0x05 \ - __asm mulps xmm5, xmm1 \ - __asm addps xmm5, xmm6 \ - __asm shufps xmm4, xmm3, 0x5A \ - __asm mulps xmm4, xmm2 \ - __asm addps xmm4, xmm5 \ - __asm movlps [eax+28*4], xmm4 \ - __asm movhps [eax+34*4], xmm4 - - MUL_Nx3_3x6_FIRST4COLUMNS_INIT - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 0 ) - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 1 ) - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 2 ) - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 3 ) - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 4 ) - MUL_Nx3_3x6_FIRST4COLUMNS_ROW( 5 ) - MUL_Nx3_3x6_LAST2COLUMNS_ROW6 - - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l]; - m2Ptr++; - } - m1Ptr += 3; - } - break; - } - case 4: { - if ( !(l^6) ) { - switch( k ) { - case 4: { // 4x4 * 4x6 - - #define MUL_Nx4_4x6_FIRST4COLUMNS_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 2*4] \ - __asm movlps xmm1, [esi+ 6*4] \ - __asm movhps xmm1, [esi+ 8*4] \ - __asm movlps xmm2, [esi+12*4] \ - __asm movhps xmm2, [esi+14*4] \ - __asm movlps xmm3, [esi+18*4] \ - __asm movhps xmm3, [esi+20*4] - - #define MUL_Nx4_4x6_FIRST4COLUMNS_ROW( row ) \ - __asm movss xmm4, [edi+row*16+0*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm4, xmm0 \ - __asm movss xmm5, [edi+row*16+1*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm1 \ - __asm addps xmm4, xmm5 \ - __asm movss xmm6, [edi+row*16+2*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm4, xmm6 \ - __asm movss xmm7, [edi+row*16+3*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm3 \ - __asm addps xmm4, xmm7 \ - __asm movlps [eax+row*24+0], xmm4 \ - __asm movhps [eax+row*24+8], xmm4 - - #define MUL_Nx4_4x6_LAST2COLUMNS_INIT \ - __asm movlps xmm0, [esi+ 4*4] \ - __asm movlps xmm1, [esi+10*4] \ - __asm movlps xmm2, [esi+16*4] \ - __asm movlps xmm3, [esi+22*4] \ - __asm shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm1, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - - #define MUL_Nx4_4x6_LAST2COLUMNS_ROW2( row ) \ - __asm movlps xmm7, [edi+row*32+ 0*4] \ - __asm movhps xmm7, [edi+row*32+ 4*4] \ - __asm movaps xmm6, xmm7 \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 3, 3 ) \ - __asm mulps xmm6, xmm0 \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 1, 1, 2, 2 ) \ - __asm mulps xmm7, xmm1 \ - __asm addps xmm6, xmm7 \ - __asm movlps xmm4, [edi+row*32+ 2*4] \ - __asm movhps xmm4, [edi+row*32+ 6*4] \ - __asm movaps xmm5, xmm4 \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 3, 3 ) \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm6, xmm5 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 1, 1, 2, 2 ) \ - __asm mulps xmm4, xmm3 \ - __asm addps xmm6, xmm4 \ - __asm movlps [eax+row*48+ 4*4], xmm6 \ - __asm movhps [eax+row*48+10*4], xmm6 - - MUL_Nx4_4x6_FIRST4COLUMNS_INIT - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 0 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 1 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 2 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 3 ) - MUL_Nx4_4x6_LAST2COLUMNS_INIT - MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 0 ) - MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 1 ) - - return; - } - case 6: { // 6x4 * 4x6 - - MUL_Nx4_4x6_FIRST4COLUMNS_INIT - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 0 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 1 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 2 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 3 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 4 ) - MUL_Nx4_4x6_FIRST4COLUMNS_ROW( 5 ) - MUL_Nx4_4x6_LAST2COLUMNS_INIT - MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 0 ) - MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 1 ) - MUL_Nx4_4x6_LAST2COLUMNS_ROW2( 2 ) - - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l]; - m2Ptr++; - } - m1Ptr += 4; - } - break; - } - case 5: { - if ( !(l^6) ) { - switch( k ) { - case 5: { // 5x5 * 5x6 - - #define MUL_Nx5_5x6_FIRST4COLUMNS_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 2*4] \ - __asm movlps xmm1, [esi+ 6*4] \ - __asm movhps xmm1, [esi+ 8*4] \ - __asm movlps xmm2, [esi+12*4] \ - __asm movhps xmm2, [esi+14*4] \ - __asm movlps xmm3, [esi+18*4] \ - __asm movhps xmm3, [esi+20*4] \ - __asm movlps xmm4, [esi+24*4] \ - __asm movhps xmm4, [esi+26*4] - - #define MUL_Nx5_5x6_FIRST4COLUMNS_ROW( row ) \ - __asm movss xmm6, [edi+row*20+0*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm0 \ - __asm movss xmm5, [edi+row*20+1*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm1 \ - __asm addps xmm6, xmm5 \ - __asm movss xmm5, [edi+row*20+2*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm6, xmm5 \ - __asm movss xmm5, [edi+row*20+3*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm3 \ - __asm addps xmm6, xmm5 \ - __asm movss xmm5, [edi+row*20+4*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm4 \ - __asm addps xmm6, xmm5 \ - __asm movlps [eax+row*24+0], xmm6 \ - __asm movhps [eax+row*24+8], xmm6 - - #define MUL_Nx5_5x6_LAST2COLUMNS_INIT \ - __asm movlps xmm0, [esi+ 4*4] \ - __asm movlps xmm1, [esi+10*4] \ - __asm movlps xmm2, [esi+16*4] \ - __asm movlps xmm3, [esi+22*4] \ - __asm movlps xmm4, [esi+28*4] \ - __asm shufps xmm0, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm1, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm2, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm3, xmm4, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm4, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) - - #define MUL_Nx5_5x6_LAST2COLUMNS_ROW2( row ) \ - __asm movlps xmm7, [edi+row*40+ 0*4] \ - __asm movhps xmm7, [edi+row*40+ 6*4] \ - __asm movaps xmm6, xmm7 \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 2, 2 ) \ - __asm mulps xmm6, xmm0 \ - __asm movaps xmm5, xmm7 \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 3, 3 ) \ - __asm mulps xmm5, xmm1 \ - __asm addps xmm6, xmm5 \ - __asm movlps xmm7, [edi+row*40+ 2*4] \ - __asm movhps xmm7, [edi+row*40+ 8*4] \ - __asm movaps xmm5, xmm7 \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 2, 2 ) \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm6, xmm5 \ - __asm movaps xmm5, xmm7 \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 3, 3 ) \ - __asm mulps xmm5, xmm3 \ - __asm addps xmm6, xmm5 \ - __asm movlps xmm5, [edi+row*40+ 4*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm5, xmm4 \ - __asm addps xmm6, xmm5 \ - __asm movlps [eax+row*48+ 4*4], xmm6 \ - __asm movhps [eax+row*48+10*4], xmm6 - - #define MUL_Nx5_5x6_LAST2COLUMNS_ROW( row ) \ - __asm movlps xmm6, [edi+20*4+0*4] \ - __asm unpcklps xmm6, xmm6 \ - __asm mulps xmm6, xmm0 \ - __asm movlps xmm5, [edi+20*4+2*4] \ - __asm unpcklps xmm5, xmm5 \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm6, xmm5 \ - __asm movss xmm5, [edi+20*4+4*4] \ - __asm unpcklps xmm5, xmm5 \ - __asm mulps xmm5, xmm4 \ - __asm addps xmm6, xmm5 \ - __asm movhlps xmm7, xmm6 \ - __asm addps xmm6, xmm7 \ - __asm movlps [eax+row*24+4*4], xmm6 - - MUL_Nx5_5x6_FIRST4COLUMNS_INIT - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 0 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 1 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 2 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 3 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 4 ) - MUL_Nx5_5x6_LAST2COLUMNS_INIT - MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 0 ) - MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 1 ) - MUL_Nx5_5x6_LAST2COLUMNS_ROW( 4 ) - - return; - } - case 6: { // 6x5 * 5x6 - - MUL_Nx5_5x6_FIRST4COLUMNS_INIT - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 0 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 1 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 2 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 3 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 4 ) - MUL_Nx5_5x6_FIRST4COLUMNS_ROW( 5 ) - MUL_Nx5_5x6_LAST2COLUMNS_INIT - MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 0 ) - MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 1 ) - MUL_Nx5_5x6_LAST2COLUMNS_ROW2( 2 ) - - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l]; - m2Ptr++; - } - m1Ptr += 5; - } - break; - } - case 6: { - switch( k ) { - case 1: { - if ( !(l^1) ) { // 1x6 * 6x1 - dstPtr[0] = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[1] + m1Ptr[2] * m2Ptr[2] + - m1Ptr[3] * m2Ptr[3] + m1Ptr[4] * m2Ptr[4] + m1Ptr[5] * m2Ptr[5]; - return; - } - break; - } - case 2: { - if ( !(l^2) ) { // 2x6 * 6x2 - - #define MUL_Nx6_6x2_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movaps xmm0, [esi] \ - __asm movaps xmm1, [esi+16] \ - __asm movaps xmm2, [esi+32] - - #define MUL_Nx6_6x2_ROW2( row ) \ - __asm movaps xmm7, [edi+row*48+0*4] \ - __asm movaps xmm6, xmm7 \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm7, xmm0 \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 2, 2, 3, 3 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movaps xmm6, [edi+row*48+4*4] \ - __asm movaps xmm5, xmm6 \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 2, 2, 3, 3 ) \ - __asm mulps xmm5, xmm0 \ - __asm movaps xmm6, [edi+row*48+24+2*4] \ - __asm movaps xmm4, xmm6 \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm5, xmm6 \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 2, 2, 3, 3 ) \ - __asm mulps xmm4, xmm2 \ - __asm addps xmm5, xmm4 \ - __asm movaps xmm4, xmm5 \ - __asm movhlps xmm5, xmm7 \ - __asm movlhps xmm7, xmm4 \ - __asm addps xmm7, xmm5 \ - __asm movaps [eax+row*16], xmm7 - - MUL_Nx6_6x2_INIT - MUL_Nx6_6x2_ROW2( 0 ) - - return; - } - break; - } - case 3: { - if ( !(l^3) ) { // 3x6 * 6x3 - - #define MUL_Nx6_6x3_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movss xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 1*4] \ - __asm movss xmm1, [esi+ 3*4] \ - __asm movhps xmm1, [esi+ 4*4] \ - __asm movss xmm2, [esi+ 6*4] \ - __asm movhps xmm2, [esi+ 7*4] \ - __asm movss xmm3, [esi+ 9*4] \ - __asm movhps xmm3, [esi+10*4] \ - __asm movss xmm4, [esi+12*4] \ - __asm movhps xmm4, [esi+13*4] \ - __asm movss xmm5, [esi+15*4] \ - __asm movhps xmm5, [esi+16*4] - - #define MUL_Nx6_6x3_ROW( row ) \ - __asm movss xmm7, [edi+row*24+0] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm movss xmm6, [edi+row*24+4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+8] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+12] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+16] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+20] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm movss [eax+row*12+0], xmm7 \ - __asm movhps [eax+row*12+4], xmm7 - - MUL_Nx6_6x3_INIT - MUL_Nx6_6x3_ROW( 0 ) - MUL_Nx6_6x3_ROW( 1 ) - MUL_Nx6_6x3_ROW( 2 ) - - return; - } - break; - } - case 4: { - if ( !(l^4) ) { // 4x6 * 6x4 - - #define MUL_Nx6_6x4_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movaps xmm0, [esi] \ - __asm movaps xmm1, [esi+16] \ - __asm movaps xmm2, [esi+32] \ - __asm movaps xmm3, [esi+48] \ - __asm movaps xmm4, [esi+64] \ - __asm movaps xmm5, [esi+80] - - #define MUL_Nx6_6x4_ROW( row ) \ - __asm movss xmm7, [edi+row*24+0] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm movss xmm6, [edi+row*24+4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+8] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+12] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+16] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+row*24+20] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm movaps [eax+row*16], xmm7 - - MUL_Nx6_6x4_INIT - MUL_Nx6_6x4_ROW( 0 ) - MUL_Nx6_6x4_ROW( 1 ) - MUL_Nx6_6x4_ROW( 2 ) - MUL_Nx6_6x4_ROW( 3 ) - - return; - } - break; - } - case 5: { - if ( !(l^5) ) { // 5x6 * 6x5 - - #define MUL_Nx6_6x5_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movaps xmm0, [esi] \ - __asm movlps xmm1, [esi+20] \ - __asm movhps xmm1, [esi+28] \ - __asm movlps xmm2, [esi+40] \ - __asm movhps xmm2, [esi+48] \ - __asm movlps xmm3, [esi+60] \ - __asm movhps xmm3, [esi+68] \ - __asm movaps xmm4, [esi+80] \ - __asm movlps xmm5, [esi+100] \ - __asm movhps xmm5, [esi+108] - - #define MUL_Nx6_6x5_ROW( row ) \ - __asm movss xmm7, [edi+row*24+0] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm fld dword ptr [edi+(row*6+0)*4] \ - __asm fmul dword ptr [esi+(4+0*5)*4] \ - __asm movss xmm6, [edi+row*24+4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm fld dword ptr [edi+(row*6+1)*4] \ - __asm fmul dword ptr [esi+(4+1*5)*4] \ - __asm faddp st(1),st \ - __asm movss xmm6, [edi+row*24+8] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm fld dword ptr [edi+(row*6+2)*4] \ - __asm fmul dword ptr [esi+(4+2*5)*4] \ - __asm faddp st(1),st \ - __asm movss xmm6, [edi+row*24+12] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm fld dword ptr [edi+(row*6+3)*4] \ - __asm fmul dword ptr [esi+(4+3*5)*4] \ - __asm faddp st(1),st \ - __asm movss xmm6, [edi+row*24+16] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm fld dword ptr [edi+(row*6+4)*4] \ - __asm fmul dword ptr [esi+(4+4*5)*4] \ - __asm faddp st(1),st \ - __asm movss xmm6, [edi+row*24+20] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm fld dword ptr [edi+(row*6+5)*4] \ - __asm fmul dword ptr [esi+(4+5*5)*4] \ - __asm faddp st(1),st \ - __asm fstp dword ptr [eax+(row*5+4)*4] \ - __asm movlps [eax+row*20], xmm7 \ - __asm movhps [eax+row*20+8], xmm7 - - MUL_Nx6_6x5_INIT - MUL_Nx6_6x5_ROW( 0 ) - MUL_Nx6_6x5_ROW( 1 ) - MUL_Nx6_6x5_ROW( 2 ) - MUL_Nx6_6x5_ROW( 3 ) - MUL_Nx6_6x5_ROW( 4 ) - - return; - } - break; - } - case 6: { - switch( l ) { - case 1: { // 6x6 * 6x1 - __asm { - mov esi, m2Ptr - mov edi, m1Ptr - mov eax, dstPtr - movlps xmm7, qword ptr [esi] - movlps xmm6, qword ptr [esi+8] - shufps xmm7, xmm7, 0x44 - shufps xmm6, xmm6, 0x44 - movlps xmm0, qword ptr [edi ] - movhps xmm0, qword ptr [edi+ 24] - mulps xmm0, xmm7 - movlps xmm3, qword ptr [edi+ 8] - movhps xmm3, qword ptr [edi+ 32] - mulps xmm3, xmm6 - movlps xmm1, qword ptr [edi+ 48] - movhps xmm1, qword ptr [edi+ 72] - mulps xmm1, xmm7 - movlps xmm2, qword ptr [edi+ 96] - movhps xmm2, qword ptr [edi+120] - mulps xmm2, xmm7 - movlps xmm4, qword ptr [edi+ 56] - movhps xmm4, qword ptr [edi+ 80] - movlps xmm5, qword ptr [edi+104] - movhps xmm5, qword ptr [edi+128] - mulps xmm4, xmm6 - movlps xmm7, qword ptr [esi+16] - addps xmm0, xmm3 - shufps xmm7, xmm7, 0x44 - mulps xmm5, xmm6 - addps xmm1, xmm4 - movlps xmm3, qword ptr [edi+ 16] - movhps xmm3, qword ptr [edi+ 40] - addps xmm2, xmm5 - movlps xmm4, qword ptr [edi+ 64] - movhps xmm4, qword ptr [edi+ 88] - mulps xmm3, xmm7 - movlps xmm5, qword ptr [edi+112] - movhps xmm5, qword ptr [edi+136] - addps xmm0, xmm3 - mulps xmm4, xmm7 - mulps xmm5, xmm7 - addps xmm1, xmm4 - addps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm0, xmm1, 0x88 - shufps xmm6, xmm1, 0xDD - movaps xmm7, xmm2 - shufps xmm7, xmm2, 0x88 - shufps xmm2, xmm2, 0xDD - addps xmm0, xmm6 - addps xmm2, xmm7 - movlps [eax], xmm0 - movhps [eax+8], xmm0 - movlps [eax+16], xmm2 - } - return; - } - case 2: { // 6x6 * 6x2 - - MUL_Nx6_6x2_INIT - MUL_Nx6_6x2_ROW2( 0 ) - MUL_Nx6_6x2_ROW2( 1 ) - MUL_Nx6_6x2_ROW2( 2 ) - - return; - } - case 3: { // 6x6 * 6x3 - - MUL_Nx6_6x3_INIT - MUL_Nx6_6x3_ROW( 0 ) - MUL_Nx6_6x3_ROW( 1 ) - MUL_Nx6_6x3_ROW( 2 ) - MUL_Nx6_6x3_ROW( 3 ) - MUL_Nx6_6x3_ROW( 4 ) - MUL_Nx6_6x3_ROW( 5 ) - - return; - } - case 4: { // 6x6 * 6x4 - - MUL_Nx6_6x4_INIT - MUL_Nx6_6x4_ROW( 0 ) - MUL_Nx6_6x4_ROW( 1 ) - MUL_Nx6_6x4_ROW( 2 ) - MUL_Nx6_6x4_ROW( 3 ) - MUL_Nx6_6x4_ROW( 4 ) - MUL_Nx6_6x4_ROW( 5 ) - - return; - } - case 5: { // 6x6 * 6x5 - - MUL_Nx6_6x5_INIT - MUL_Nx6_6x5_ROW( 0 ) - MUL_Nx6_6x5_ROW( 1 ) - MUL_Nx6_6x5_ROW( 2 ) - MUL_Nx6_6x5_ROW( 3 ) - MUL_Nx6_6x5_ROW( 4 ) - MUL_Nx6_6x5_ROW( 5 ) - - return; - } - case 6: { // 6x6 * 6x6 - __asm { - mov ecx, dword ptr m2Ptr - movlps xmm3, qword ptr [ecx+72] - mov edx, dword ptr m1Ptr - // Loading first 4 columns (upper 4 rows) of m2Ptr. - movaps xmm0, xmmword ptr [ecx] - movlps xmm1, qword ptr [ecx+24] - movhps xmm1, qword ptr [ecx+32] - movaps xmm2, xmmword ptr [ecx+48] - movhps xmm3, qword ptr [ecx+80] - // Calculating first 4 elements in the first row of the destination matrix. - movss xmm4, dword ptr [edx] - movss xmm5, dword ptr [edx+4] - mov eax, dword ptr dstPtr - shufps xmm4, xmm4, 0 - movss xmm6, dword ptr [edx+8] - shufps xmm5, xmm5, 0 - movss xmm7, dword ptr [edx+12] - mulps xmm4, xmm0 - shufps xmm6, xmm6, 0 - shufps xmm7, xmm7, 0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - addps xmm5, xmm4 - mulps xmm7, xmm3 - addps xmm6, xmm5 - addps xmm7, xmm6 - movaps xmmword ptr [eax], xmm7 - // Calculating first 4 elements in the second row of the destination matrix. - movss xmm4, dword ptr [edx+24] - shufps xmm4, xmm4, 0 - mulps xmm4, xmm0 - movss xmm5, dword ptr [edx+28] - shufps xmm5, xmm5, 0 - mulps xmm5, xmm1 - movss xmm6, dword ptr [edx+32] - shufps xmm6, xmm6, 0 - movss xmm7, dword ptr [edx+36] - shufps xmm7, xmm7, 0 - mulps xmm6, xmm2 - mulps xmm7, xmm3 - addps xmm7, xmm6 - addps xmm5, xmm4 - addps xmm7, xmm5 - // Calculating first 4 elements in the third row of the destination matrix. - movss xmm4, dword ptr [edx+48] - movss xmm5, dword ptr [edx+52] - movlps qword ptr [eax+24], xmm7 ; save 2nd - movhps qword ptr [eax+32], xmm7 ; row - movss xmm6, dword ptr [edx+56] - movss xmm7, dword ptr [edx+60] - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - shufps xmm6, xmm6, 0 - shufps xmm7, xmm7, 0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - mulps xmm7, xmm3 - addps xmm5, xmm4 - addps xmm7, xmm6 - addps xmm7, xmm5 - movaps xmmword ptr [eax+48], xmm7 - // Calculating first 4 elements in the fourth row of the destination matrix. - movss xmm4, dword ptr [edx+72] - movss xmm5, dword ptr [edx+76] - movss xmm6, dword ptr [edx+80] - movss xmm7, dword ptr [edx+84] - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - shufps xmm6, xmm6, 0 - shufps xmm7, xmm7, 0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - mulps xmm7, xmm3 - addps xmm4, xmm5 - addps xmm6, xmm4 - addps xmm7, xmm6 - movlps qword ptr [eax+72], xmm7 - movhps qword ptr [eax+80], xmm7 - // Calculating first 4 elements in the fifth row of the destination matrix. - movss xmm4, dword ptr [edx+96] - movss xmm5, dword ptr [edx+100] - movss xmm6, dword ptr [edx+104] - movss xmm7, dword ptr [edx+108] - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - shufps xmm6, xmm6, 0 - shufps xmm7, xmm7, 0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - mulps xmm7, xmm3 - addps xmm5, xmm4 - addps xmm7, xmm6 - addps xmm7, xmm5 - movaps xmmword ptr [eax+96], xmm7 - // Calculating first 4 elements in the sixth row of the destination matrix. - movss xmm4, dword ptr [edx+120] - movss xmm5, dword ptr [edx+124] - movss xmm6, dword ptr [edx+128] - movss xmm7, dword ptr [edx+132] - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - shufps xmm6, xmm6, 0 - shufps xmm7, xmm7, 0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm6, xmm2 - mulps xmm7, xmm3 - addps xmm4, xmm5 - addps xmm6, xmm4 - addps xmm7, xmm6 - movhps qword ptr [eax+128], xmm7 - movlps qword ptr [eax+120], xmm7 - // Loading first 4 columns (lower 2 rows) of m2Ptr. - movlps xmm0, qword ptr [ecx+96] - movhps xmm0, qword ptr [ecx+104] - movlps xmm1, qword ptr [ecx+120] - movhps xmm1, qword ptr [ecx+128] - // Calculating first 4 elements in the first row of the destination matrix. - movss xmm2, dword ptr [edx+16] - shufps xmm2, xmm2, 0 - movss xmm4, dword ptr [edx+40] - movss xmm3, dword ptr [edx+20] - movss xmm5, dword ptr [edx+44] - movaps xmm6, xmmword ptr [eax] - movlps xmm7, qword ptr [eax+24] - shufps xmm3, xmm3, 0 - shufps xmm5, xmm5, 0 - movhps xmm7, qword ptr [eax+32] - shufps xmm4, xmm4, 0 - mulps xmm5, xmm1 - mulps xmm2, xmm0 - mulps xmm3, xmm1 - mulps xmm4, xmm0 - addps xmm6, xmm2 - addps xmm7, xmm4 - addps xmm7, xmm5 - addps xmm6, xmm3 - movlps qword ptr [eax+24], xmm7 - movaps xmmword ptr [eax], xmm6 - movhps qword ptr [eax+32], xmm7 - // Calculating first 4 elements in the third row of the destination matrix. - movss xmm2, dword ptr [edx+64] - movss xmm4, dword ptr [edx+88] - movss xmm5, dword ptr [edx+92] - movss xmm3, dword ptr [edx+68] - movaps xmm6, xmmword ptr [eax+48] - movlps xmm7, qword ptr [eax+72] - movhps xmm7, qword ptr [eax+80] - shufps xmm2, xmm2, 0 - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - shufps xmm3, xmm3, 0 - mulps xmm2, xmm0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - mulps xmm3, xmm1 - addps xmm6, xmm2 - addps xmm6, xmm3 - addps xmm7, xmm4 - addps xmm7, xmm5 - movlps qword ptr [eax+72], xmm7 - movaps xmmword ptr [eax+48], xmm6 - movhps qword ptr [eax+80], xmm7 - // Calculating first 4 elements in the fifth row of the destination matrix. - movss xmm2, dword ptr [edx+112] - movss xmm3, dword ptr [edx+116] - movaps xmm6, xmmword ptr [eax+96] - shufps xmm2, xmm2, 0 - shufps xmm3, xmm3, 0 - mulps xmm2, xmm0 - mulps xmm3, xmm1 - addps xmm6, xmm2 - addps xmm6, xmm3 - movaps xmmword ptr [eax+96], xmm6 - // Calculating first 4 elements in the sixth row of the destination matrix. - movss xmm4, dword ptr [edx+136] - movss xmm5, dword ptr [edx+140] - movhps xmm7, qword ptr [eax+128] - movlps xmm7, qword ptr [eax+120] - shufps xmm4, xmm4, 0 - shufps xmm5, xmm5, 0 - mulps xmm4, xmm0 - mulps xmm5, xmm1 - addps xmm7, xmm4 - addps xmm7, xmm5 - // Calculating last 2 columns of the destination matrix. - movlps xmm0, qword ptr [ecx+16] - movhps xmm0, qword ptr [ecx+40] - movhps qword ptr [eax+128], xmm7 - movlps qword ptr [eax+120], xmm7 - movlps xmm2, qword ptr [ecx+64] - movhps xmm2, qword ptr [ecx+88] - movaps xmm3, xmm2 - shufps xmm3, xmm3, 4Eh - movlps xmm4, qword ptr [ecx+112] - movhps xmm4, qword ptr [ecx+136] - movaps xmm5, xmm4 - shufps xmm5, xmm5, 4Eh - movlps xmm6, qword ptr [edx] - movhps xmm6, qword ptr [edx+24] - movaps xmm7, xmm6 - shufps xmm7, xmm7, 0F0h - mulps xmm7, xmm0 - shufps xmm6, xmm6, 0A5h - movaps xmm1, xmm0 - shufps xmm1, xmm1, 4Eh - mulps xmm1, xmm6 - addps xmm7, xmm1 - movlps xmm6, qword ptr [edx+8] - movhps xmm6, qword ptr [edx+32] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm2 - mulps xmm6, xmm3 - addps xmm7, xmm1 - addps xmm7, xmm6 - movhps xmm6, qword ptr [edx+40] - movlps xmm6, qword ptr [edx+16] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm4 - mulps xmm6, xmm5 - addps xmm7, xmm1 - addps xmm7, xmm6 - movlps qword ptr [eax+16], xmm7 - movhps qword ptr [eax+40], xmm7 - movlps xmm6, qword ptr [edx+48] - movhps xmm6, qword ptr [edx+72] - movaps xmm7, xmm6 - shufps xmm7, xmm7, 0F0h - mulps xmm7, xmm0 - shufps xmm6, xmm6, 0A5h - movaps xmm1, xmm0 - shufps xmm1, xmm1, 4Eh - mulps xmm1, xmm6 - addps xmm7, xmm1 - movhps xmm6, qword ptr [edx+80] - movlps xmm6, qword ptr [edx+56] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm2 - mulps xmm6, xmm3 - addps xmm7, xmm1 - addps xmm7, xmm6 - movlps xmm6, qword ptr [edx+64] - movhps xmm6, qword ptr [edx+88] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm4 - mulps xmm6, xmm5 - addps xmm7, xmm1 - addps xmm7, xmm6 - movlps qword ptr [eax+64], xmm7 - movhps qword ptr [eax+88], xmm7 - movlps xmm6, qword ptr [edx+96] - movhps xmm6, qword ptr [edx+120] - movaps xmm7, xmm6 - shufps xmm7, xmm7, 0F0h - mulps xmm7, xmm0 - shufps xmm6, xmm6, 0A5h - movaps xmm1, xmm0 - shufps xmm1, xmm1, 4Eh - mulps xmm1, xmm6 - addps xmm7, xmm1 - movlps xmm6, qword ptr [edx+104] - movhps xmm6, qword ptr [edx+128] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm2 - mulps xmm6, xmm3 - addps xmm7, xmm1 - addps xmm7, xmm6 - movlps xmm6, qword ptr [edx+112] - movhps xmm6, qword ptr [edx+136] - movaps xmm1, xmm6 - shufps xmm1, xmm1, 0F0h - shufps xmm6, xmm6, 0A5h - mulps xmm1, xmm4 - mulps xmm6, xmm5 - addps xmm7, xmm1 - addps xmm7, xmm6 - movlps qword ptr [eax+112], xmm7 - movhps qword ptr [eax+136], xmm7 - } - return; - } - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[1] * m2Ptr[l] + m1Ptr[2] * m2Ptr[2*l] + - m1Ptr[3] * m2Ptr[3*l] + m1Ptr[4] * m2Ptr[4*l] + m1Ptr[5] * m2Ptr[5*l]; - m2Ptr++; - } - m1Ptr += 6; - } - break; - } - default: { - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m2Ptr = m2.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < m1.GetNumColumns(); n++ ) { - m2Ptr += l; - sum += m1Ptr[n] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - m1Ptr += m1.GetNumColumns(); - } - break; - } - } -} - -/* -============ -idSIMD_SSE::MatX_TransposeMultiplyMatX - - optimizes the following transpose matrix multiplications: - - Nx6 * NxN - 6xN * 6x6 - - with N in the range [1-6]. -============ -*/ -void VPCALL idSIMD_SSE::MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ) { - int i, j, k, l, n; - float *dstPtr; - const float *m1Ptr, *m2Ptr; - double sum; - - assert( m1.GetNumRows() == m2.GetNumRows() ); - - m1Ptr = m1.ToFloatPtr(); - m2Ptr = m2.ToFloatPtr(); - dstPtr = dst.ToFloatPtr(); - k = m1.GetNumColumns(); - l = m2.GetNumColumns(); - - switch( m1.GetNumRows() ) { - case 1: - if ( !((k^6)|(l^1)) ) { // 1x6 * 1x1 - __asm { - mov esi, m2Ptr - mov edi, m1Ptr - mov eax, dstPtr - movss xmm0, [esi] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm1, xmm0 - mulps xmm0, [edi] - mulps xmm1, [edi+16] - movaps [eax], xmm0 - movlps [eax+16], xmm1 - } - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 2: - if ( !((k^6)|(l^2)) ) { // 2x6 * 2x2 - #define MUL_2xN_2x2_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi] \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm movlps xmm1, [esi+8] \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) - - #define MUL_2xN_2x2_ROW2( N, row ) \ - __asm movlps xmm6, [edi+(row+0*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm movlps xmm7, [edi+(row+1*N)*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm0 \ - __asm mulps xmm7, xmm1 \ - __asm addps xmm6, xmm7 \ - __asm movaps [eax+(row*2)*4], xmm6 - - MUL_2xN_2x2_INIT - MUL_2xN_2x2_ROW2( 6, 0 ) - MUL_2xN_2x2_ROW2( 6, 2 ) - MUL_2xN_2x2_ROW2( 6, 4 ) - - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 3: - if ( !((k^6)|(l^3)) ) { // 3x6 * 3x3 - - #define MUL_3xN_3x3_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movss xmm0, [esi+(0*3+0)*4] \ - __asm movhps xmm0, [esi+(0*3+1)*4] \ - __asm movss xmm1, [esi+(1*3+0)*4] \ - __asm movhps xmm1, [esi+(1*3+1)*4] \ - __asm movss xmm2, [esi+(2*3+0)*4] \ - __asm movhps xmm2, [esi+(2*3+1)*4] - - #define MUL_3xN_3x3_INIT_ROW4 \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 2, 3, 0 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 0 ) \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 0, 2, 3, 0 ) - - #define MUL_3xN_3x3_ROW4( N, row ) \ - __asm movlps xmm3, [edi+(row+0*N+0)*4] \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 1 ) \ - __asm movlps xmm4, [edi+(row+1*N+0)*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 1 ) \ - __asm movlps xmm5, [edi+(row+2*N+0)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 1 ) \ - __asm mulps xmm3, xmm0 \ - __asm mulps xmm4, xmm1 \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm4 \ - __asm addps xmm3, xmm5 \ - __asm movaps [eax+(row*3+0)*4], xmm3 \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm movlps xmm3, [edi+(row+0*N+1)*4] \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm movlps xmm4, [edi+(row+1*N+1)*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm movlps xmm5, [edi+(row+2*N+1)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm3, xmm0 \ - __asm mulps xmm4, xmm1 \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm4 \ - __asm addps xmm3, xmm5 \ - __asm movaps [eax+(row*3+4)*4], xmm3 \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 1 ) \ - __asm movlps xmm3, [edi+(row+0*N+2)*4] \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 1, 1, 1 ) \ - __asm movlps xmm4, [edi+(row+1*N+2)*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 1, 1, 1 ) \ - __asm movlps xmm5, [edi+(row+2*N+2)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 1, 1 ) \ - __asm mulps xmm3, xmm0 \ - __asm mulps xmm4, xmm1 \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm4 \ - __asm addps xmm3, xmm5 \ - __asm movaps [eax+(row*3+8)*4], xmm3 - - #define MUL_3xN_3x3_INIT_ROW4_ROW4 \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - #define MUL_3xN_3x3_INIT_ROW4_ROW \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 1, 1, 2, 3 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 2, 3 ) \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 1, 1, 2, 3 ) - - #define MUL_3xN_3x3_ROW( N, row ) \ - __asm movss xmm3, [edi+(row+0*N)*4] \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm movss xmm4, [edi+(row+1*N)*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm movss xmm5, [edi+(row+2*N)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm3, xmm0 \ - __asm mulps xmm4, xmm1 \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm3, xmm4 \ - __asm addps xmm3, xmm5 \ - __asm movss [eax+(row*3+0)*4], xmm3 \ - __asm movhps [eax+(row*3+1)*4], xmm3 - - MUL_3xN_3x3_INIT - MUL_3xN_3x3_INIT_ROW4 - MUL_3xN_3x3_ROW4( 6, 0 ) - MUL_3xN_3x3_INIT_ROW4_ROW - MUL_3xN_3x3_ROW( 6, 4 ) - MUL_3xN_3x3_ROW( 6, 5 ) - - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 4: - if ( !((k^6)|(l^4)) ) { // 4x6 * 4x4 - - #define MUL_4xN_4x4_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movaps xmm0, [esi] \ - __asm movaps xmm1, [esi+16] \ - __asm movaps xmm2, [esi+32] \ - __asm movaps xmm3, [esi+48] - - #define MUL_4xN_4x4_ROW( N, row ) \ - __asm movss xmm7, [edi+(row+0*N)*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm movss xmm6, [edi+(row+1*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+2*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+3*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movaps [eax+row*16], xmm7 - - MUL_4xN_4x4_INIT - MUL_4xN_4x4_ROW( 6, 0 ) - MUL_4xN_4x4_ROW( 6, 1 ) - MUL_4xN_4x4_ROW( 6, 2 ) - MUL_4xN_4x4_ROW( 6, 3 ) - MUL_4xN_4x4_ROW( 6, 4 ) - MUL_4xN_4x4_ROW( 6, 5 ) - - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 5: - if ( !((k^6)|(l^5)) ) { // 5x6 * 5x5 - - #define MUL_5xN_5x5_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 2*4] \ - __asm movlps xmm1, [esi+ 5*4] \ - __asm movhps xmm1, [esi+ 7*4] \ - __asm movlps xmm2, [esi+10*4] \ - __asm movhps xmm2, [esi+12*4] \ - __asm movlps xmm3, [esi+15*4] \ - __asm movhps xmm3, [esi+17*4] \ - __asm movlps xmm4, [esi+20*4] \ - __asm movhps xmm4, [esi+22*4] - - #define MUL_5xN_5x5_ROW( N, row ) \ - __asm movss xmm6, [edi+(row+0*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm0 \ - __asm fld dword ptr [edi+(row+0*N)*4] \ - __asm fmul dword ptr [esi+ 4*4] \ - __asm movss xmm5, [edi+(row+1*N)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm1 \ - __asm addps xmm6, xmm5 \ - __asm fld dword ptr [edi+(row+1*N)*4] \ - __asm fmul dword ptr [esi+ 9*4] \ - __asm faddp st(1),st \ - __asm movss xmm5, [edi+(row+2*N)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm2 \ - __asm addps xmm6, xmm5 \ - __asm fld dword ptr [edi+(row+2*N)*4] \ - __asm fmul dword ptr [esi+14*4] \ - __asm faddp st(1),st \ - __asm movss xmm5, [edi+(row+3*N)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm3 \ - __asm addps xmm6, xmm5 \ - __asm fld dword ptr [edi+(row+3*N)*4] \ - __asm fmul dword ptr [esi+19*4] \ - __asm faddp st(1),st \ - __asm movss xmm5, [edi+(row+4*N)*4] \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm5, xmm4 \ - __asm addps xmm6, xmm5 \ - __asm fld dword ptr [edi+(row+4*N)*4] \ - __asm fmul dword ptr [esi+24*4] \ - __asm faddp st(1),st \ - __asm fstp dword ptr [eax+(row*5+4)*4] \ - __asm movlps [eax+(row*5+0)*4], xmm6 \ - __asm movhps [eax+(row*5+2)*4], xmm6 - - MUL_5xN_5x5_INIT - MUL_5xN_5x5_ROW( 6, 0 ) - MUL_5xN_5x5_ROW( 6, 1 ) - MUL_5xN_5x5_ROW( 6, 2 ) - MUL_5xN_5x5_ROW( 6, 3 ) - MUL_5xN_5x5_ROW( 6, 4 ) - MUL_5xN_5x5_ROW( 6, 5 ) - - return; - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - case 6: - if ( !(l^6) ) { - switch( k ) { - case 1: { // 6x1 * 6x6 - #define MUL_6xN_6x6_FIRST4COLUMNS_INIT \ - __asm mov esi, m2Ptr \ - __asm mov edi, m1Ptr \ - __asm mov eax, dstPtr \ - __asm movlps xmm0, [esi+ 0*4] \ - __asm movhps xmm0, [esi+ 2*4] \ - __asm movlps xmm1, [esi+ 6*4] \ - __asm movhps xmm1, [esi+ 8*4] \ - __asm movlps xmm2, [esi+12*4] \ - __asm movhps xmm2, [esi+14*4] \ - __asm movlps xmm3, [esi+18*4] \ - __asm movhps xmm3, [esi+20*4] \ - __asm movlps xmm4, [esi+24*4] \ - __asm movhps xmm4, [esi+26*4] \ - __asm movlps xmm5, [esi+30*4] \ - __asm movhps xmm5, [esi+32*4] - - #define MUL_6xN_6x6_FIRST4COLUMNS_ROW( N, row ) \ - __asm movss xmm7, [edi+(row+0*N)*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm movss xmm6, [edi+(row+1*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+2*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+3*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+4*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(row+5*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm movlps [eax+(row*6+0)*4], xmm7 \ - __asm movhps [eax+(row*6+2)*4], xmm7 - - #define MUL_6xN_6x6_LAST2COLUMNS_INIT \ - __asm movlps xmm0, [esi+ 4*4] \ - __asm movlps xmm1, [esi+10*4] \ - __asm shufps xmm0, xmm0, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm movlps xmm2, [esi+16*4] \ - __asm movlps xmm3, [esi+22*4] \ - __asm shufps xmm2, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm3, xmm3, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm movlps xmm4, [esi+28*4] \ - __asm movlps xmm5, [esi+34*4] \ - __asm shufps xmm4, xmm4, R_SHUFFLEPS( 0, 1, 0, 1 ) \ - __asm shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 0, 1 ) - - #define MUL_6xN_6x6_LAST2COLUMNS_ROW2( N, row ) \ - __asm movlps xmm7, [edi+(row*2+0*N)*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm7, xmm0 \ - __asm movlps xmm6, [edi+(row*2+1*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movlps xmm6, [edi+(row*2+2*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movlps xmm6, [edi+(row*2+3*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movlps xmm6, [edi+(row*2+4*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm movlps xmm6, [edi+(row*2+5*N)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 1, 1 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm movlps [eax+(row*12+ 4)*4], xmm7 \ - __asm movhps [eax+(row*12+10)*4], xmm7 - - #define MUL_6xN_6x6_LAST2COLUMNS_ROW( N, row ) \ - __asm movss xmm7, [edi+(1*N-1)*4] \ - __asm shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm7, xmm0 \ - __asm movss xmm6, [edi+(2*N-1)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm1 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(3*N-1)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm2 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(4*N-1)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm3 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(5*N-1)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm4 \ - __asm addps xmm7, xmm6 \ - __asm movss xmm6, [edi+(6*N-1)*4] \ - __asm shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) \ - __asm mulps xmm6, xmm5 \ - __asm addps xmm7, xmm6 \ - __asm movlps [eax+(row*6+4)*4], xmm7 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 1, 0 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW( 1, 0 ) - - return; - } - case 2: { // 6x2 * 6x6 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 2, 0 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 2, 1 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 2, 0 ) - - return; - } - case 3: { // 6x3 * 6x6 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 0 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 1 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 3, 2 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 3, 0 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW( 3, 2 ) - - return; - } - case 4: { // 6x4 * 6x6 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 0 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 1 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 2 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 4, 3 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 4, 0 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 4, 1 ) - - return; - } - case 5: { // 6x5 * 6x6 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 0 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 1 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 2 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 3 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 5, 4 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 5, 0 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 5, 1 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW( 5, 4 ) - - return; - } - case 6: { // 6x6 * 6x6 - - MUL_6xN_6x6_FIRST4COLUMNS_INIT - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 0 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 1 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 2 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 3 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 4 ) - MUL_6xN_6x6_FIRST4COLUMNS_ROW( 6, 5 ) - MUL_6xN_6x6_LAST2COLUMNS_INIT - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 0 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 1 ) - MUL_6xN_6x6_LAST2COLUMNS_ROW2( 6, 2 ) - - return; - } - } - } - for ( i = 0; i < k; i++ ) { - m2Ptr = m2.ToFloatPtr(); - for ( j = 0; j < l; j++ ) { - *dstPtr++ = m1Ptr[0] * m2Ptr[0] + m1Ptr[k] * m2Ptr[l] + m1Ptr[2*k] * m2Ptr[2*l] + - m1Ptr[3*k] * m2Ptr[3*l] + m1Ptr[4*k] * m2Ptr[4*l] + m1Ptr[5*k] * m2Ptr[5*l]; - m2Ptr++; - } - m1Ptr++; - } - break; - default: - for ( i = 0; i < k; i++ ) { - for ( j = 0; j < l; j++ ) { - m1Ptr = m1.ToFloatPtr() + i; - m2Ptr = m2.ToFloatPtr() + j; - sum = m1Ptr[0] * m2Ptr[0]; - for ( n = 1; n < m1.GetNumRows(); n++ ) { - m1Ptr += k; - m2Ptr += l; - sum += m1Ptr[0] * m2Ptr[0]; - } - *dstPtr++ = sum; - } - } - break; - } -} - -/* -============ -idSIMD_SSE::MatX_LowerTriangularSolve - - solves x in Lx = b for the n * n sub-matrix of L - if skip > 0 the first skip elements of x are assumed to be valid already - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_SSE::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { - int nc; - const float *lptr; - - if ( skip >= n ) { - return; - } - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - #define NSKIP( n, s ) ((n<<3)|(s&7)) - switch( NSKIP( n, skip ) ) { - case NSKIP( 1, 0 ): x[0] = b[0]; - return; - case NSKIP( 2, 0 ): x[0] = b[0]; - case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - return; - case NSKIP( 3, 0 ): x[0] = b[0]; - case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - return; - case NSKIP( 4, 0 ): x[0] = b[0]; - case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - return; - case NSKIP( 5, 0 ): x[0] = b[0]; - case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - return; - case NSKIP( 6, 0 ): x[0] = b[0]; - case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - return; - case NSKIP( 7, 0 ): x[0] = b[0]; - case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; - return; - } - return; - } - - // process first 4 rows - switch( skip ) { - case 0: x[0] = b[0]; - case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; - case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - skip = 4; - } - - lptr = L[skip]; - - // this code assumes n > 4 - __asm { - push ebx - mov eax, skip // eax = i - shl eax, 2 // eax = i*4 - mov edx, n // edx = n - shl edx, 2 // edx = n*4 - mov esi, x // esi = x - mov edi, lptr // edi = lptr - add esi, eax - add edi, eax - mov ebx, b // ebx = b - - // check for aligned memory - mov ecx, nc - shl ecx, 2 - or ecx, esi - or ecx, edi - and ecx, 15 - jnz loopurow - - // aligned - looprow: - mov ecx, eax - neg ecx - movaps xmm0, [esi+ecx] - mulps xmm0, [edi+ecx] - add ecx, 12*4 - jg donedot8 - dot8: - movaps xmm1, [esi+ecx-(8*4)] - mulps xmm1, [edi+ecx-(8*4)] - addps xmm0, xmm1 - movaps xmm3, [esi+ecx-(4*4)] - mulps xmm3, [edi+ecx-(4*4)] - addps xmm0, xmm3 - add ecx, 8*4 - jle dot8 - donedot8: - sub ecx, 4*4 - jg donedot4 - //dot4: - movaps xmm1, [esi+ecx-(4*4)] - mulps xmm1, [edi+ecx-(4*4)] - addps xmm0, xmm1 - add ecx, 4*4 - donedot4: - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - sub ecx, 4*4 - jz dot0 - add ecx, 4 - jz dot1 - add ecx, 4 - jz dot2 - //dot3: - movss xmm1, [esi-(3*4)] - mulss xmm1, [edi-(3*4)] - addss xmm0, xmm1 - dot2: - movss xmm3, [esi-(2*4)] - mulss xmm3, [edi-(2*4)] - addss xmm0, xmm3 - dot1: - movss xmm5, [esi-(1*4)] - mulss xmm5, [edi-(1*4)] - addss xmm0, xmm5 - dot0: - movss xmm1, [ebx+eax] - subss xmm1, xmm0 - movss [esi], xmm1 - add eax, 4 - cmp eax, edx - jge done - add esi, 4 - mov ecx, nc - shl ecx, 2 - add edi, ecx - add edi, 4 - jmp looprow - - // unaligned - loopurow: - mov ecx, eax - neg ecx - movups xmm0, [esi+ecx] - movups xmm1, [edi+ecx] - mulps xmm0, xmm1 - add ecx, 12*4 - jg doneudot8 - udot8: - movups xmm1, [esi+ecx-(8*4)] - movups xmm2, [edi+ecx-(8*4)] - mulps xmm1, xmm2 - addps xmm0, xmm1 - movups xmm3, [esi+ecx-(4*4)] - movups xmm4, [edi+ecx-(4*4)] - mulps xmm3, xmm4 - addps xmm0, xmm3 - add ecx, 8*4 - jle udot8 - doneudot8: - sub ecx, 4*4 - jg doneudot4 - //udot4: - movups xmm1, [esi+ecx-(4*4)] - movups xmm2, [edi+ecx-(4*4)] - mulps xmm1, xmm2 - addps xmm0, xmm1 - add ecx, 4*4 - doneudot4: - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm1 - sub ecx, 4*4 - jz udot0 - add ecx, 4 - jz udot1 - add ecx, 4 - jz udot2 - //udot3: - movss xmm1, [esi-(3*4)] - movss xmm2, [edi-(3*4)] - mulss xmm1, xmm2 - addss xmm0, xmm1 - udot2: - movss xmm3, [esi-(2*4)] - movss xmm4, [edi-(2*4)] - mulss xmm3, xmm4 - addss xmm0, xmm3 - udot1: - movss xmm5, [esi-(1*4)] - movss xmm6, [edi-(1*4)] - mulss xmm5, xmm6 - addss xmm0, xmm5 - udot0: - movss xmm1, [ebx+eax] - subss xmm1, xmm0 - movss [esi], xmm1 - add eax, 4 - cmp eax, edx - jge done - add esi, 4 - mov ecx, nc - shl ecx, 2 - add edi, ecx - add edi, 4 - jmp loopurow - done: - pop ebx - } -} - -/* -============ -idSIMD_SSE::MatX_LowerTriangularSolveTranspose - - solves x in L'x = b for the n * n sub-matrix of L - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_SSE::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { - int nc; - const float *lptr; - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - switch( n ) { - case 0: - return; - case 1: - x[0] = b[0]; - return; - case 2: - x[1] = b[1]; - x[0] = b[0] - lptr[1*nc+0] * x[1]; - return; - case 3: - x[2] = b[2]; - x[1] = b[1] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 4: - x[3] = b[3]; - x[2] = b[2] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 5: - x[4] = b[4]; - x[3] = b[3] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 6: - x[5] = b[5]; - x[4] = b[4] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 7: - x[6] = b[6]; - x[5] = b[5] - lptr[6*nc+5] * x[6]; - x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - } - return; - } - -#if 1 - - int i, j, m; - float *xptr; - double s0; - - // if the number of columns is not a multiple of 2 we're screwed for alignment. - // however, if the number of columns is a multiple of 2 but the number of to be - // processed rows is not a multiple of 2 we can still run 8 byte aligned - m = n; - if ( m & 1 ) { - - m--; - x[m] = b[m]; - - lptr = L.ToFloatPtr() + m * nc + m - 4; - xptr = x + m; - __asm { - push ebx - mov eax, m // eax = i - mov esi, xptr // esi = xptr - mov edi, lptr // edi = lptr - mov ebx, b // ebx = b - mov edx, nc // edx = nc*sizeof(float) - shl edx, 2 - process4rows_1: - movlps xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] - movhps xmm0, [ebx+eax*4-8] // load b[i-4], b[i-3] - xor ecx, ecx - sub eax, m - neg eax - jz done4x4_1 - process4x4_1: // process 4x4 blocks - movlps xmm2, [edi+0] - movhps xmm2, [edi+8] - add edi, edx - movss xmm1, [esi+4*ecx+0] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm3, [edi+0] - movhps xmm3, [edi+8] - add edi, edx - mulps xmm1, xmm2 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm4, [edi+0] - movhps xmm4, [edi+8] - add edi, edx - mulps xmm1, xmm3 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+8] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm5, [edi+0] - movhps xmm5, [edi+8] - add edi, edx - mulps xmm1, xmm4 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+12] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - add ecx, 4 - cmp ecx, eax - mulps xmm1, xmm5 - subps xmm0, xmm1 - jl process4x4_1 - done4x4_1: // process left over of the 4 rows - movlps xmm2, [edi+0] - movhps xmm2, [edi+8] - movss xmm1, [esi+4*ecx] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm1, xmm2 - subps xmm0, xmm1 - imul ecx, edx - sub edi, ecx - neg eax - - add eax, m - sub eax, 4 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - movaps xmm2, xmm0 - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 2, 2, 2 ) - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) - sub edi, edx - movss [esi-4], xmm3 // xptr[-1] = s3 - movss xmm4, xmm3 - movss xmm5, xmm3 - mulss xmm3, [edi+8] // lptr[-1*nc+2] * s3 - mulss xmm4, [edi+4] // lptr[-1*nc+1] * s3 - mulss xmm5, [edi+0] // lptr[-1*nc+0] * s3 - subss xmm2, xmm3 - movss [esi-8], xmm2 // xptr[-2] = s2 - movss xmm6, xmm2 - sub edi, edx - subss xmm0, xmm5 - subss xmm1, xmm4 - mulss xmm2, [edi+4] // lptr[-2*nc+1] * s2 - mulss xmm6, [edi+0] // lptr[-2*nc+0] * s2 - subss xmm1, xmm2 - movss [esi-12], xmm1 // xptr[-3] = s1 - subss xmm0, xmm6 - sub edi, edx - cmp eax, 4 - mulss xmm1, [edi+0] // lptr[-3*nc+0] * s1 - subss xmm0, xmm1 - movss [esi-16], xmm0 // xptr[-4] = s0 - jl done4rows_1 - sub edi, edx - sub edi, 16 - sub esi, 16 - jmp process4rows_1 - done4rows_1: - pop ebx - } - - } else { - - lptr = L.ToFloatPtr() + m * nc + m - 4; - xptr = x + m; - __asm { - push ebx - mov eax, m // eax = i - mov esi, xptr // esi = xptr - mov edi, lptr // edi = lptr - mov ebx, b // ebx = b - mov edx, nc // edx = nc*sizeof(float) - shl edx, 2 - process4rows: - movlps xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] - movhps xmm0, [ebx+eax*4-8] // load b[i-4], b[i-3] - sub eax, m - jz done4x4 - neg eax - xor ecx, ecx - process4x4: // process 4x4 blocks - movlps xmm2, [edi+0] - movhps xmm2, [edi+8] - add edi, edx - movss xmm1, [esi+4*ecx+0] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm3, [edi+0] - movhps xmm3, [edi+8] - add edi, edx - mulps xmm1, xmm2 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm4, [edi+0] - movhps xmm4, [edi+8] - add edi, edx - mulps xmm1, xmm3 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+8] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps xmm5, [edi+0] - movhps xmm5, [edi+8] - add edi, edx - mulps xmm1, xmm4 - subps xmm0, xmm1 - movss xmm1, [esi+4*ecx+12] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - add ecx, 4 - cmp ecx, eax - mulps xmm1, xmm5 - subps xmm0, xmm1 - jl process4x4 - imul ecx, edx - sub edi, ecx - neg eax - done4x4: // process left over of the 4 rows - add eax, m - sub eax, 4 - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - movaps xmm2, xmm0 - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 2, 2, 2 ) - movaps xmm3, xmm0 - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 3, 3, 3 ) - sub edi, edx - movss [esi-4], xmm3 // xptr[-1] = s3 - movss xmm4, xmm3 - movss xmm5, xmm3 - mulss xmm3, [edi+8] // lptr[-1*nc+2] * s3 - mulss xmm4, [edi+4] // lptr[-1*nc+1] * s3 - mulss xmm5, [edi+0] // lptr[-1*nc+0] * s3 - subss xmm2, xmm3 - movss [esi-8], xmm2 // xptr[-2] = s2 - movss xmm6, xmm2 - sub edi, edx - subss xmm0, xmm5 - subss xmm1, xmm4 - mulss xmm2, [edi+4] // lptr[-2*nc+1] * s2 - mulss xmm6, [edi+0] // lptr[-2*nc+0] * s2 - subss xmm1, xmm2 - movss [esi-12], xmm1 // xptr[-3] = s1 - subss xmm0, xmm6 - sub edi, edx - cmp eax, 4 - mulss xmm1, [edi+0] // lptr[-3*nc+0] * s1 - subss xmm0, xmm1 - movss [esi-16], xmm0 // xptr[-4] = s0 - jl done4rows - sub edi, edx - sub edi, 16 - sub esi, 16 - jmp process4rows - done4rows: - pop ebx - } - } - - // process left over rows - for ( i = (m&3)-1; i >= 0; i-- ) { - s0 = b[i]; - lptr = L[0] + i; - for ( j = i + 1; j < n; j++ ) { - s0 -= lptr[j*nc] * x[j]; - } - x[i] = s0; - } - -#else - - int i, j, m; - double s0, s1, s2, s3, t; - const float *lptr2; - float *xptr, *xptr2; - - m = n; - if ( m & 1 ) { - - m--; - x[m] = b[m]; - - lptr = L.ToFloatPtr() + m * nc + m - 4; - xptr = x + m; - // process 4 rows at a time - for ( i = m; i >= 4; i -= 4 ) { - s0 = b[i-4]; - s1 = b[i-3]; - s2 = b[i-2]; - s3 = b[i-1]; - // process 4x4 blocks - xptr2 = xptr; // x + i; - lptr2 = lptr; // ptr = L[i] + i - 4; - for ( j = 0; j < m-i; j += 4 ) { - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - } - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - // process left over of the 4 rows - lptr -= nc; - s0 -= lptr[0] * s3; - s1 -= lptr[1] * s3; - s2 -= lptr[2] * s3; - lptr -= nc; - s0 -= lptr[0] * s2; - s1 -= lptr[1] * s2; - lptr -= nc; - s0 -= lptr[0] * s1; - lptr -= nc; - // store result - xptr[-4] = s0; - xptr[-3] = s1; - xptr[-2] = s2; - xptr[-1] = s3; - // update pointers for next four rows - lptr -= 4; - xptr -= 4; - } - - } else { - - lptr = L.ToFloatPtr() + m * nc + m - 4; - xptr = x + m; - // process 4 rows at a time - for ( i = m; i >= 4; i -= 4 ) { - s0 = b[i-4]; - s1 = b[i-3]; - s2 = b[i-2]; - s3 = b[i-1]; - // process 4x4 blocks - xptr2 = xptr; // x + i; - lptr2 = lptr; // ptr = L[i] + i - 4; - for ( j = 0; j < m-i; j += 4 ) { - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - t = xptr2[0]; - s0 -= lptr2[0] * t; - s1 -= lptr2[1] * t; - s2 -= lptr2[2] * t; - s3 -= lptr2[3] * t; - lptr2 += nc; - xptr2++; - } - // process left over of the 4 rows - lptr -= nc; - s0 -= lptr[0] * s3; - s1 -= lptr[1] * s3; - s2 -= lptr[2] * s3; - lptr -= nc; - s0 -= lptr[0] * s2; - s1 -= lptr[1] * s2; - lptr -= nc; - s0 -= lptr[0] * s1; - lptr -= nc; - // store result - xptr[-4] = s0; - xptr[-3] = s1; - xptr[-2] = s2; - xptr[-1] = s3; - // update pointers for next four rows - lptr -= 4; - xptr -= 4; - } - } - // process left over rows - for ( i--; i >= 0; i-- ) { - s0 = b[i]; - lptr = L[0] + i; - for ( j = i + 1; j < m; j++ ) { - s0 -= lptr[j*nc] * x[j]; - } - x[i] = s0; - } - -#endif -} - -/* -============ -idSIMD_SSE::MatX_LDLTFactor - - in-place factorization LDL' of the n * n sub-matrix of mat - the reciprocal of the diagonal elements are stored in invDiag - currently assumes the number of columns of mat is a multiple of 4 -============ -*/ -bool VPCALL idSIMD_SSE::MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ) { -#if 1 - - int j, nc; - float *v, *diag, *invDiagPtr, *mptr; - double s0, s1, s2, sum, d; - - v = (float *) _alloca16( n * sizeof( float ) ); - diag = (float *) _alloca16( n * sizeof( float ) ); - invDiagPtr = invDiag.ToFloatPtr(); - - nc = mat.GetNumColumns(); - - assert( ( nc & 3 ) == 0 ); - - if ( n <= 0 ) { - return true; - } - - mptr = mat[0]; - - sum = mptr[0]; - - if ( sum == 0.0f ) { - return false; - } - - diag[0] = sum; - invDiagPtr[0] = d = 1.0f / sum; - - if ( n <= 1 ) { - return true; - } - - mptr = mat[0]; - for ( j = 1; j < n; j++ ) { - mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; - } - - mptr = mat[1]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - sum = mptr[1] - s0; - - if ( sum == 0.0f ) { - return false; - } - - mat[1][1] = sum; - diag[1] = sum; - invDiagPtr[1] = d = 1.0f / sum; - - if ( n <= 2 ) { - return true; - } - - mptr = mat[0]; - for ( j = 2; j < n; j++ ) { - mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; - } - - mptr = mat[2]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - sum = mptr[2] - s0 - s1; - - if ( sum == 0.0f ) { - return false; - } - - mat[2][2] = sum; - diag[2] = sum; - invDiagPtr[2] = d = 1.0f / sum; - - if ( n <= 3 ) { - return true; - } - - mptr = mat[0]; - for ( j = 3; j < n; j++ ) { - mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; - } - - mptr = mat[3]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - sum = mptr[3] - s0 - s1 - s2; - - if ( sum == 0.0f ) { - return false; - } - - mat[3][3] = sum; - diag[3] = sum; - invDiagPtr[3] = d = 1.0f / sum; - - if ( n <= 4 ) { - return true; - } - - mptr = mat[0]; - for ( j = 4; j < n; j++ ) { - mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; - } - - int ncf = nc * sizeof( float ); - mptr = mat[0]; - - __asm { - xorps xmm2, xmm2 - xorps xmm3, xmm3 - xorps xmm4, xmm4 - - push ebx - mov ebx, 4 - - loopRow: - cmp ebx, n - jge done - - mov ecx, ebx // esi = i - shl ecx, 2 // esi = i * 4 - mov edx, diag // edx = diag - add edx, ecx // edx = &diag[i] - mov edi, ebx // edi = i - imul edi, ncf // edi = i * nc * sizeof( float ) - add edi, mptr // edi = mat[i] - add edi, ecx // edi = &mat[i][i] - mov esi, v // ecx = v - add esi, ecx // ecx = &v[i] - mov eax, invDiagPtr // eax = invDiagPtr - add eax, ecx // eax = &invDiagPtr[i] - neg ecx - - movaps xmm0, [edx+ecx] - mulps xmm0, [edi+ecx] - movaps [esi+ecx], xmm0 - mulps xmm0, [edi+ecx] - add ecx, 12*4 - jg doneDot8 - dot8: - movaps xmm1, [edx+ecx-(8*4)] - mulps xmm1, [edi+ecx-(8*4)] - movaps [esi+ecx-(8*4)], xmm1 - mulps xmm1, [edi+ecx-(8*4)] - addps xmm0, xmm1 - movaps xmm2, [edx+ecx-(4*4)] - mulps xmm2, [edi+ecx-(4*4)] - movaps [esi+ecx-(4*4)], xmm2 - mulps xmm2, [edi+ecx-(4*4)] - addps xmm0, xmm2 - add ecx, 8*4 - jle dot8 - doneDot8: - sub ecx, 4*4 - jg doneDot4 - movaps xmm1, [edx+ecx-(4*4)] - mulps xmm1, [edi+ecx-(4*4)] - movaps [esi+ecx-(4*4)], xmm1 - mulps xmm1, [edi+ecx-(4*4)] - addps xmm0, xmm1 - add ecx, 4*4 - doneDot4: - sub ecx, 2*4 - jg doneDot2 - movlps xmm3, [edx+ecx-(2*4)] - movlps xmm4, [edi+ecx-(2*4)] - mulps xmm3, xmm4 - movlps [esi+ecx-(2*4)], xmm3 - mulps xmm3, xmm4 - addps xmm0, xmm3 - add ecx, 2*4 - doneDot2: - sub ecx, 1*4 - jg doneDot1 - movss xmm3, [edx+ecx-(1*4)] - movss xmm4, [edi+ecx-(1*4)] - mulss xmm3, xmm4 - movss [esi+ecx-(1*4)], xmm3 - mulss xmm3, xmm4 - addss xmm0, xmm3 - doneDot1: - movhlps xmm2, xmm0 - addps xmm0, xmm2 - movaps xmm2, xmm0 - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm2 - movss xmm1, [edi] - subss xmm1, xmm0 - movss [edi], xmm1 // mptr[i] = sum; - movss [edx], xmm1 // diag[i] = sum; - - // if ( sum == 0.0f ) return false; - movaps xmm2, xmm1 - cmpeqss xmm2, SIMD_SP_zero - andps xmm2, SIMD_SP_tiny - orps xmm1, xmm2 - - rcpss xmm7, xmm1 - mulss xmm1, xmm7 - mulss xmm1, xmm7 - addss xmm7, xmm7 - subss xmm7, xmm1 - movss [eax], xmm7 // invDiagPtr[i] = 1.0f / sum; - - mov edx, n // edx = n - sub edx, ebx // edx = n - i - dec edx // edx = n - i - 1 - jle doneSubRow // if ( i + 1 >= n ) return true; - - mov eax, ebx // eax = i - shl eax, 2 // eax = i * 4 - neg eax - - loopSubRow: - add edi, ncf - mov ecx, eax - movaps xmm0, [esi+ecx] - mulps xmm0, [edi+ecx] - add ecx, 12*4 - jg doneSubDot8 - subDot8: - movaps xmm1, [esi+ecx-(8*4)] - mulps xmm1, [edi+ecx-(8*4)] - addps xmm0, xmm1 - movaps xmm2, [esi+ecx-(4*4)] - mulps xmm2, [edi+ecx-(4*4)] - addps xmm0, xmm2 - add ecx, 8*4 - jle subDot8 - doneSubDot8: - sub ecx, 4*4 - jg doneSubDot4 - movaps xmm1, [esi+ecx-(4*4)] - mulps xmm1, [edi+ecx-(4*4)] - addps xmm0, xmm1 - add ecx, 4*4 - doneSubDot4: - sub ecx, 2*4 - jg doneSubDot2 - movlps xmm3, [esi+ecx-(2*4)] - movlps xmm4, [edi+ecx-(2*4)] - mulps xmm3, xmm4 - addps xmm0, xmm3 - add ecx, 2*4 - doneSubDot2: - sub ecx, 1*4 - jg doneSubDot1 - movss xmm3, [esi+ecx-(1*4)] - movss xmm4, [edi+ecx-(1*4)] - mulss xmm3, xmm4 - addss xmm0, xmm3 - doneSubDot1: - movhlps xmm2, xmm0 - addps xmm0, xmm2 - movaps xmm2, xmm0 - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 0, 0, 0 ) - addss xmm0, xmm2 - movss xmm1, [edi] - subss xmm1, xmm0 - mulss xmm1, xmm7 - movss [edi], xmm1 - dec edx - jg loopSubRow - doneSubRow: - inc ebx - jmp loopRow - done: - pop ebx - } - - return true; - -#else - - int i, j, k, nc; - float *v, *diag, *mptr; - double s0, s1, s2, s3, sum, d; - - v = (float *) _alloca16( n * sizeof( float ) ); - diag = (float *) _alloca16( n * sizeof( float ) ); - - nc = mat.GetNumColumns(); - - if ( n <= 0 ) { - return true; - } - - mptr = mat[0]; - - sum = mptr[0]; - - if ( sum == 0.0f ) { - return false; - } - - diag[0] = sum; - invDiag[0] = d = 1.0f / sum; - - if ( n <= 1 ) { - return true; - } - - mptr = mat[0]; - for ( j = 1; j < n; j++ ) { - mptr[j*nc+0] = ( mptr[j*nc+0] ) * d; - } - - mptr = mat[1]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - sum = mptr[1] - s0; - - if ( sum == 0.0f ) { - return false; - } - - mat[1][1] = sum; - diag[1] = sum; - invDiag[1] = d = 1.0f / sum; - - if ( n <= 2 ) { - return true; - } - - mptr = mat[0]; - for ( j = 2; j < n; j++ ) { - mptr[j*nc+1] = ( mptr[j*nc+1] - v[0] * mptr[j*nc+0] ) * d; - } - - mptr = mat[2]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - sum = mptr[2] - s0 - s1; - - if ( sum == 0.0f ) { - return false; - } - - mat[2][2] = sum; - diag[2] = sum; - invDiag[2] = d = 1.0f / sum; - - if ( n <= 3 ) { - return true; - } - - mptr = mat[0]; - for ( j = 3; j < n; j++ ) { - mptr[j*nc+2] = ( mptr[j*nc+2] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] ) * d; - } - - mptr = mat[3]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - sum = mptr[3] - s0 - s1 - s2; - - if ( sum == 0.0f ) { - return false; - } - - mat[3][3] = sum; - diag[3] = sum; - invDiag[3] = d = 1.0f / sum; - - if ( n <= 4 ) { - return true; - } - - mptr = mat[0]; - for ( j = 4; j < n; j++ ) { - mptr[j*nc+3] = ( mptr[j*nc+3] - v[0] * mptr[j*nc+0] - v[1] * mptr[j*nc+1] - v[2] * mptr[j*nc+2] ) * d; - } - - for ( i = 4; i < n; i++ ) { - - mptr = mat[i]; - - v[0] = diag[0] * mptr[0]; s0 = v[0] * mptr[0]; - v[1] = diag[1] * mptr[1]; s1 = v[1] * mptr[1]; - v[2] = diag[2] * mptr[2]; s2 = v[2] * mptr[2]; - v[3] = diag[3] * mptr[3]; s3 = v[3] * mptr[3]; - for ( k = 4; k < i-3; k += 4 ) { - v[k+0] = diag[k+0] * mptr[k+0]; s0 += v[k+0] * mptr[k+0]; - v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - v[k+2] = diag[k+2] * mptr[k+2]; s2 += v[k+2] * mptr[k+2]; - v[k+3] = diag[k+3] * mptr[k+3]; s3 += v[k+3] * mptr[k+3]; - } - switch( i - k ) { - case 3: v[k+2] = diag[k+2] * mptr[k+2]; s0 += v[k+2] * mptr[k+2]; - case 2: v[k+1] = diag[k+1] * mptr[k+1]; s1 += v[k+1] * mptr[k+1]; - case 1: v[k+0] = diag[k+0] * mptr[k+0]; s2 += v[k+0] * mptr[k+0]; - } - sum = s3; - sum += s2; - sum += s1; - sum += s0; - sum = mptr[i] - sum; - - if ( sum == 0.0f ) { - return false; - } - - mat[i][i] = sum; - diag[i] = sum; - invDiag[i] = d = 1.0f / sum; - - if ( i + 1 >= n ) { - return true; - } - - mptr = mat[i+1]; - for ( j = i+1; j < n; j++ ) { - s0 = mptr[0] * v[0]; - s1 = mptr[1] * v[1]; - s2 = mptr[2] * v[2]; - s3 = mptr[3] * v[3]; - for ( k = 4; k < i-7; k += 8 ) { - s0 += mptr[k+0] * v[k+0]; - s1 += mptr[k+1] * v[k+1]; - s2 += mptr[k+2] * v[k+2]; - s3 += mptr[k+3] * v[k+3]; - s0 += mptr[k+4] * v[k+4]; - s1 += mptr[k+5] * v[k+5]; - s2 += mptr[k+6] * v[k+6]; - s3 += mptr[k+7] * v[k+7]; - } - switch( i - k ) { - case 7: s0 += mptr[k+6] * v[k+6]; - case 6: s1 += mptr[k+5] * v[k+5]; - case 5: s2 += mptr[k+4] * v[k+4]; - case 4: s3 += mptr[k+3] * v[k+3]; - case 3: s0 += mptr[k+2] * v[k+2]; - case 2: s1 += mptr[k+1] * v[k+1]; - case 1: s2 += mptr[k+0] * v[k+0]; - } - sum = s3; - sum += s2; - sum += s1; - sum += s0; - mptr[i] = ( mptr[i] - sum ) * d; - mptr += nc; - } - } - - return true; - -#endif -} - -/* -============ -idSIMD_SSE::BlendJoints -============ -*/ -#define REFINE_BLENDJOINTS_RECIPROCAL - -void VPCALL idSIMD_SSE::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { - int i; - - if ( lerp <= 0.0f ) { - return; - } else if ( lerp >= 1.0f ) { - for ( i = 0; i < numJoints; i++ ) { - int j = index[i]; - joints[j] = blendJoints[j]; - } - return; - } - - for ( i = 0; i <= numJoints - 4; i += 4 ) { - ALIGN16( float jointVert0[4] ); - ALIGN16( float jointVert1[4] ); - ALIGN16( float jointVert2[4] ); - ALIGN16( float blendVert0[4] ); - ALIGN16( float blendVert1[4] ); - ALIGN16( float blendVert2[4] ); - ALIGN16( float jointQuat0[4] ); - ALIGN16( float jointQuat1[4] ); - ALIGN16( float jointQuat2[4] ); - ALIGN16( float jointQuat3[4] ); - ALIGN16( float blendQuat0[4] ); - ALIGN16( float blendQuat1[4] ); - ALIGN16( float blendQuat2[4] ); - ALIGN16( float blendQuat3[4] ); - - for ( int j = 0; j < 4; j++ ) { - int n = index[i+j]; - - jointVert0[j] = joints[n].t[0]; - jointVert1[j] = joints[n].t[1]; - jointVert2[j] = joints[n].t[2]; - - blendVert0[j] = blendJoints[n].t[0]; - blendVert1[j] = blendJoints[n].t[1]; - blendVert2[j] = blendJoints[n].t[2]; - - jointQuat0[j] = joints[n].q[0]; - jointQuat1[j] = joints[n].q[1]; - jointQuat2[j] = joints[n].q[2]; - jointQuat3[j] = joints[n].q[3]; - - blendQuat0[j] = blendJoints[n].q[0]; - blendQuat1[j] = blendJoints[n].q[1]; - blendQuat2[j] = blendJoints[n].q[2]; - blendQuat3[j] = blendJoints[n].q[3]; - } - -#if 1 - __asm { - // lerp translation - movss xmm7, lerp - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - movaps xmm0, blendVert0 - subps xmm0, jointVert0 - mulps xmm0, xmm7 - addps xmm0, jointVert0 - movaps jointVert0, xmm0 - movaps xmm1, blendVert1 - subps xmm1, jointVert1 - mulps xmm1, xmm7 - addps xmm1, jointVert1 - movaps jointVert1, xmm1 - movaps xmm2, blendVert2 - subps xmm2, jointVert2 - mulps xmm2, xmm7 - addps xmm2, jointVert2 - movaps jointVert2, xmm2 - - // lerp quaternions - movaps xmm0, jointQuat0 - mulps xmm0, blendQuat0 - movaps xmm1, jointQuat1 - mulps xmm1, blendQuat1 - addps xmm0, xmm1 - movaps xmm2, jointQuat2 - mulps xmm2, blendQuat2 - addps xmm0, xmm2 - movaps xmm3, jointQuat3 - mulps xmm3, blendQuat3 - addps xmm0, xmm3 // xmm0 = cosom - - movaps xmm1, xmm0 - movaps xmm2, xmm0 - andps xmm1, SIMD_SP_signBitMask // xmm1 = signBit - xorps xmm0, xmm1 - mulps xmm2, xmm2 - - xorps xmm4, xmm4 - movaps xmm3, SIMD_SP_one - subps xmm3, xmm2 // xmm3 = scale0 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 - -#ifdef REFINE_BLENDJOINTS_RECIPROCAL - movaps xmm2, xmm3 - rsqrtps xmm4, xmm2 - mulps xmm2, xmm4 - mulps xmm2, xmm4 - subps xmm2, SIMD_SP_rsqrt_c0 - mulps xmm4, SIMD_SP_rsqrt_c1 - mulps xmm2, xmm4 -#else - rsqrtps xmm2, xmm3 // xmm2 = sinom -#endif - mulps xmm3, xmm2 // xmm3 = sqrt( scale0 ) - - // omega0 = atan2( xmm3, xmm0 ) - movaps xmm4, xmm0 - minps xmm0, xmm3 - maxps xmm3, xmm4 - cmpeqps xmm4, xmm0 - -#ifdef REFINE_BLENDJOINTS_RECIPROCAL - rcpps xmm5, xmm3 - mulps xmm3, xmm5 - mulps xmm3, xmm5 - addps xmm5, xmm5 - subps xmm5, xmm3 // xmm5 = 1 / y or 1 / x - mulps xmm0, xmm5 // xmm0 = x / y or y / x -#else - rcpps xmm3, xmm3 // xmm3 = 1 / y or 1 / x - mulps xmm0, xmm3 // xmm0 = x / y or y / x -#endif - movaps xmm3, xmm4 - andps xmm3, SIMD_SP_signBitMask - xorps xmm0, xmm3 // xmm0 = -x / y or y / x - andps xmm4, SIMD_SP_halfPI // xmm4 = HALF_PI or 0.0f - movaps xmm3, xmm0 - mulps xmm3, xmm3 // xmm3 = s - movaps xmm5, SIMD_SP_atan_c0 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c1 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c2 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c3 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c4 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c5 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c6 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_atan_c7 - mulps xmm5, xmm3 - addps xmm5, SIMD_SP_one - mulps xmm5, xmm0 - addps xmm5, xmm4 // xmm5 = omega0 - - movaps xmm6, xmm7 // xmm6 = lerp - mulps xmm6, xmm5 // xmm6 = omega1 - subps xmm5, xmm6 // xmm5 = omega0 - - // scale0 = sin( xmm5 ) * xmm2 - // scale1 = sin( xmm6 ) * xmm2 - movaps xmm3, xmm5 - movaps xmm7, xmm6 - mulps xmm3, xmm3 - mulps xmm7, xmm7 - movaps xmm4, SIMD_SP_sin_c0 - movaps xmm0, SIMD_SP_sin_c0 - mulps xmm4, xmm3 - mulps xmm0, xmm7 - addps xmm4, SIMD_SP_sin_c1 - addps xmm0, SIMD_SP_sin_c1 - mulps xmm4, xmm3 - mulps xmm0, xmm7 - addps xmm4, SIMD_SP_sin_c2 - addps xmm0, SIMD_SP_sin_c2 - mulps xmm4, xmm3 - mulps xmm0, xmm7 - addps xmm4, SIMD_SP_sin_c3 - addps xmm0, SIMD_SP_sin_c3 - mulps xmm4, xmm3 - mulps xmm0, xmm7 - addps xmm4, SIMD_SP_sin_c4 - addps xmm0, SIMD_SP_sin_c4 - mulps xmm4, xmm3 - mulps xmm0, xmm7 - addps xmm4, SIMD_SP_one - addps xmm0, SIMD_SP_one - mulps xmm5, xmm4 - mulps xmm6, xmm0 - mulps xmm5, xmm2 // xmm5 = scale0 - mulps xmm6, xmm2 // xmm6 = scale1 - - xorps xmm6, xmm1 - - movaps xmm0, jointQuat0 - mulps xmm0, xmm5 - movaps xmm1, blendQuat0 - mulps xmm1, xmm6 - addps xmm0, xmm1 - movaps jointQuat0, xmm0 - - movaps xmm1, jointQuat1 - mulps xmm1, xmm5 - movaps xmm2, blendQuat1 - mulps xmm2, xmm6 - addps xmm1, xmm2 - movaps jointQuat1, xmm1 - - movaps xmm2, jointQuat2 - mulps xmm2, xmm5 - movaps xmm3, blendQuat2 - mulps xmm3, xmm6 - addps xmm2, xmm3 - movaps jointQuat2, xmm2 - - movaps xmm3, jointQuat3 - mulps xmm3, xmm5 - movaps xmm4, blendQuat3 - mulps xmm4, xmm6 - addps xmm3, xmm4 - movaps jointQuat3, xmm3 - } - -#else - - jointVert0[0] += lerp * ( blendVert0[0] - jointVert0[0] ); - jointVert0[1] += lerp * ( blendVert0[1] - jointVert0[1] ); - jointVert0[2] += lerp * ( blendVert0[2] - jointVert0[2] ); - jointVert0[3] += lerp * ( blendVert0[3] - jointVert0[3] ); - - jointVert1[0] += lerp * ( blendVert1[0] - jointVert1[0] ); - jointVert1[1] += lerp * ( blendVert1[1] - jointVert1[1] ); - jointVert1[2] += lerp * ( blendVert1[2] - jointVert1[2] ); - jointVert1[3] += lerp * ( blendVert1[3] - jointVert1[3] ); - - jointVert2[0] += lerp * ( blendVert2[0] - jointVert2[0] ); - jointVert2[1] += lerp * ( blendVert2[1] - jointVert2[1] ); - jointVert2[2] += lerp * ( blendVert2[2] - jointVert2[2] ); - jointVert2[3] += lerp * ( blendVert2[3] - jointVert2[3] ); - - ALIGN16( float cosom[4] ); - ALIGN16( float sinom[4] ); - ALIGN16( float omega0[4] ); - ALIGN16( float omega1[4] ); - ALIGN16( float scale0[4] ); - ALIGN16( float scale1[4] ); - ALIGN16( unsigned long signBit[4] ); - - cosom[0] = jointQuat0[0] * blendQuat0[0]; - cosom[1] = jointQuat0[1] * blendQuat0[1]; - cosom[2] = jointQuat0[2] * blendQuat0[2]; - cosom[3] = jointQuat0[3] * blendQuat0[3]; - - cosom[0] += jointQuat1[0] * blendQuat1[0]; - cosom[1] += jointQuat1[1] * blendQuat1[1]; - cosom[2] += jointQuat1[2] * blendQuat1[2]; - cosom[3] += jointQuat1[3] * blendQuat1[3]; - - cosom[0] += jointQuat2[0] * blendQuat2[0]; - cosom[1] += jointQuat2[1] * blendQuat2[1]; - cosom[2] += jointQuat2[2] * blendQuat2[2]; - cosom[3] += jointQuat2[3] * blendQuat2[3]; - - cosom[0] += jointQuat3[0] * blendQuat3[0]; - cosom[1] += jointQuat3[1] * blendQuat3[1]; - cosom[2] += jointQuat3[2] * blendQuat3[2]; - cosom[3] += jointQuat3[3] * blendQuat3[3]; - - signBit[0] = (*(unsigned long *)&cosom[0]) & ( 1 << 31 ); - signBit[1] = (*(unsigned long *)&cosom[1]) & ( 1 << 31 ); - signBit[2] = (*(unsigned long *)&cosom[2]) & ( 1 << 31 ); - signBit[3] = (*(unsigned long *)&cosom[3]) & ( 1 << 31 ); - - (*(unsigned long *)&cosom[0]) ^= signBit[0]; - (*(unsigned long *)&cosom[1]) ^= signBit[1]; - (*(unsigned long *)&cosom[2]) ^= signBit[2]; - (*(unsigned long *)&cosom[3]) ^= signBit[3]; - - scale0[0] = 1.0f - cosom[0] * cosom[0]; - scale0[1] = 1.0f - cosom[1] * cosom[1]; - scale0[2] = 1.0f - cosom[2] * cosom[2]; - scale0[3] = 1.0f - cosom[3] * cosom[3]; - - scale0[0] = ( scale0[0] <= 0.0f ) ? SIMD_SP_tiny[0] : scale0[0]; - scale0[1] = ( scale0[1] <= 0.0f ) ? SIMD_SP_tiny[1] : scale0[1]; - scale0[2] = ( scale0[2] <= 0.0f ) ? SIMD_SP_tiny[2] : scale0[2]; - scale0[3] = ( scale0[3] <= 0.0f ) ? SIMD_SP_tiny[3] : scale0[3]; - - sinom[0] = idMath::RSqrt( scale0[0] ); - sinom[1] = idMath::RSqrt( scale0[1] ); - sinom[2] = idMath::RSqrt( scale0[2] ); - sinom[3] = idMath::RSqrt( scale0[3] ); - - scale0[0] *= sinom[0]; - scale0[1] *= sinom[1]; - scale0[2] *= sinom[2]; - scale0[3] *= sinom[3]; - - omega0[0] = SSE_ATanPositive( scale0[0], cosom[0] ); - omega0[1] = SSE_ATanPositive( scale0[1], cosom[1] ); - omega0[2] = SSE_ATanPositive( scale0[2], cosom[2] ); - omega0[3] = SSE_ATanPositive( scale0[3], cosom[3] ); - - omega1[0] = lerp * omega0[0]; - omega1[1] = lerp * omega0[1]; - omega1[2] = lerp * omega0[2]; - omega1[3] = lerp * omega0[3]; - - omega0[0] -= omega1[0]; - omega0[1] -= omega1[1]; - omega0[2] -= omega1[2]; - omega0[3] -= omega1[3]; - - scale0[0] = SSE_SinZeroHalfPI( omega0[0] ) * sinom[0]; - scale0[1] = SSE_SinZeroHalfPI( omega0[1] ) * sinom[1]; - scale0[2] = SSE_SinZeroHalfPI( omega0[2] ) * sinom[2]; - scale0[3] = SSE_SinZeroHalfPI( omega0[3] ) * sinom[3]; - - scale1[0] = SSE_SinZeroHalfPI( omega1[0] ) * sinom[0]; - scale1[1] = SSE_SinZeroHalfPI( omega1[1] ) * sinom[1]; - scale1[2] = SSE_SinZeroHalfPI( omega1[2] ) * sinom[2]; - scale1[3] = SSE_SinZeroHalfPI( omega1[3] ) * sinom[3]; - - (*(unsigned long *)&scale1[0]) ^= signBit[0]; - (*(unsigned long *)&scale1[1]) ^= signBit[1]; - (*(unsigned long *)&scale1[2]) ^= signBit[2]; - (*(unsigned long *)&scale1[3]) ^= signBit[3]; - - jointQuat0[0] = scale0[0] * jointQuat0[0] + scale1[0] * blendQuat0[0]; - jointQuat0[1] = scale0[1] * jointQuat0[1] + scale1[1] * blendQuat0[1]; - jointQuat0[2] = scale0[2] * jointQuat0[2] + scale1[2] * blendQuat0[2]; - jointQuat0[3] = scale0[3] * jointQuat0[3] + scale1[3] * blendQuat0[3]; - - jointQuat1[0] = scale0[0] * jointQuat1[0] + scale1[0] * blendQuat1[0]; - jointQuat1[1] = scale0[1] * jointQuat1[1] + scale1[1] * blendQuat1[1]; - jointQuat1[2] = scale0[2] * jointQuat1[2] + scale1[2] * blendQuat1[2]; - jointQuat1[3] = scale0[3] * jointQuat1[3] + scale1[3] * blendQuat1[3]; - - jointQuat2[0] = scale0[0] * jointQuat2[0] + scale1[0] * blendQuat2[0]; - jointQuat2[1] = scale0[1] * jointQuat2[1] + scale1[1] * blendQuat2[1]; - jointQuat2[2] = scale0[2] * jointQuat2[2] + scale1[2] * blendQuat2[2]; - jointQuat2[3] = scale0[3] * jointQuat2[3] + scale1[3] * blendQuat2[3]; - - jointQuat3[0] = scale0[0] * jointQuat3[0] + scale1[0] * blendQuat3[0]; - jointQuat3[1] = scale0[1] * jointQuat3[1] + scale1[1] * blendQuat3[1]; - jointQuat3[2] = scale0[2] * jointQuat3[2] + scale1[2] * blendQuat3[2]; - jointQuat3[3] = scale0[3] * jointQuat3[3] + scale1[3] * blendQuat3[3]; - -#endif - - for ( int j = 0; j < 4; j++ ) { - int n = index[i+j]; - - joints[n].t[0] = jointVert0[j]; - joints[n].t[1] = jointVert1[j]; - joints[n].t[2] = jointVert2[j]; - - joints[n].q[0] = jointQuat0[j]; - joints[n].q[1] = jointQuat1[j]; - joints[n].q[2] = jointQuat2[j]; - joints[n].q[3] = jointQuat3[j]; - } - } - - for ( ; i < numJoints; i++ ) { - int n = index[i]; - - idVec3 &jointVert = joints[n].t; - const idVec3 &blendVert = blendJoints[n].t; - - jointVert[0] += lerp * ( blendVert[0] - jointVert[0] ); - jointVert[1] += lerp * ( blendVert[1] - jointVert[1] ); - jointVert[2] += lerp * ( blendVert[2] - jointVert[2] ); - - idQuat &jointQuat = joints[n].q; - const idQuat &blendQuat = blendJoints[n].q; - - float cosom; - float sinom; - float omega; - float scale0; - float scale1; - unsigned long signBit; - - cosom = jointQuat.x * blendQuat.x + jointQuat.y * blendQuat.y + jointQuat.z * blendQuat.z + jointQuat.w * blendQuat.w; - - signBit = (*(unsigned long *)&cosom) & ( 1 << 31 ); - - (*(unsigned long *)&cosom) ^= signBit; - - scale0 = 1.0f - cosom * cosom; - scale0 = ( scale0 <= 0.0f ) ? SIMD_SP_tiny[0] : scale0; - sinom = idMath::InvSqrt( scale0 ); - omega = idMath::ATan16( scale0 * sinom, cosom ); - scale0 = idMath::Sin16( ( 1.0f - lerp ) * omega ) * sinom; - scale1 = idMath::Sin16( lerp * omega ) * sinom; - - (*(unsigned long *)&scale1) ^= signBit; - - jointQuat.x = scale0 * jointQuat.x + scale1 * blendQuat.x; - jointQuat.y = scale0 * jointQuat.y + scale1 * blendQuat.y; - jointQuat.z = scale0 * jointQuat.z + scale1 * blendQuat.z; - jointQuat.w = scale0 * jointQuat.w + scale1 * blendQuat.w; - } -} - -/* -============ -idSIMD_SSE::ConvertJointQuatsToJointMats -============ -*/ -void VPCALL idSIMD_SSE::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { - - assert( sizeof( idJointQuat ) == JOINTQUAT_SIZE ); - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - assert( (int)(&((idJointQuat *)0)->t) == (int)(&((idJointQuat *)0)->q) + (int)sizeof( ((idJointQuat *)0)->q ) ); - - for ( int i = 0; i < numJoints; i++ ) { - - const float *q = jointQuats[i].q.ToFloatPtr(); - float *m = jointMats[i].ToFloatPtr(); - - m[0*4+3] = q[4]; - m[1*4+3] = q[5]; - m[2*4+3] = q[6]; - - float x2 = q[0] + q[0]; - float y2 = q[1] + q[1]; - float z2 = q[2] + q[2]; - - { - float xx = q[0] * x2; - float yy = q[1] * y2; - float zz = q[2] * z2; - - m[0*4+0] = 1.0f - yy - zz; - m[1*4+1] = 1.0f - xx - zz; - m[2*4+2] = 1.0f - xx - yy; - } - - { - float yz = q[1] * z2; - float wx = q[3] * x2; - - m[2*4+1] = yz - wx; - m[1*4+2] = yz + wx; - } - - { - float xy = q[0] * y2; - float wz = q[3] * z2; - - m[1*4+0] = xy - wz; - m[0*4+1] = xy + wz; - } - - { - float xz = q[0] * z2; - float wy = q[3] * y2; - - m[0*4+2] = xz - wy; - m[2*4+0] = xz + wy; - } - } -} - -/* -============ -idSIMD_SSE::ConvertJointMatsToJointQuats -============ -*/ -void VPCALL idSIMD_SSE::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { - - assert( sizeof( idJointQuat ) == JOINTQUAT_SIZE ); - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - assert( (int)(&((idJointQuat *)0)->t) == (int)(&((idJointQuat *)0)->q) + (int)sizeof( ((idJointQuat *)0)->q ) ); - -#if 1 - - ALIGN16( byte shuffle[16] ); - - __asm { - mov eax, numJoints - mov esi, jointMats - mov edi, jointQuats - and eax, ~3 - jz done4 - imul eax, JOINTMAT_SIZE - add esi, eax - neg eax - - loopMat4: - movss xmm5, [esi+eax+3*JOINTMAT_SIZE+0*16+0*4] - movss xmm6, [esi+eax+3*JOINTMAT_SIZE+1*16+1*4] - movss xmm7, [esi+eax+3*JOINTMAT_SIZE+2*16+2*4] - - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm0, [esi+eax+2*JOINTMAT_SIZE+0*16+0*4] - movss xmm1, [esi+eax+2*JOINTMAT_SIZE+1*16+1*4] - movss xmm2, [esi+eax+2*JOINTMAT_SIZE+2*16+2*4] - - movss xmm5, xmm0 - movss xmm6, xmm1 - movss xmm7, xmm2 - - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm0, [esi+eax+1*JOINTMAT_SIZE+0*16+0*4] - movss xmm1, [esi+eax+1*JOINTMAT_SIZE+1*16+1*4] - movss xmm2, [esi+eax+1*JOINTMAT_SIZE+2*16+2*4] - - movss xmm5, xmm0 - movss xmm6, xmm1 - movss xmm7, xmm2 - - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm6, xmm6, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm0, [esi+eax+0*JOINTMAT_SIZE+0*16+0*4] - movss xmm1, [esi+eax+0*JOINTMAT_SIZE+1*16+1*4] - movss xmm2, [esi+eax+0*JOINTMAT_SIZE+2*16+2*4] - - movss xmm5, xmm0 - movss xmm6, xmm1 - movss xmm7, xmm2 - - // ------------------- - - movaps xmm0, xmm5 - addps xmm0, xmm6 - addps xmm0, xmm7 - cmpnltps xmm0, SIMD_SP_zero // xmm0 = m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f - - movaps xmm1, xmm5 - movaps xmm2, xmm5 - cmpnltps xmm1, xmm6 - cmpnltps xmm2, xmm7 - andps xmm2, xmm1 // xmm2 = m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] - - movaps xmm4, xmm6 - cmpnltps xmm4, xmm7 // xmm3 = m[1 * 4 + 1] > m[2 * 4 + 2] - - movaps xmm1, xmm0 - andnps xmm1, xmm2 - orps xmm2, xmm0 - movaps xmm3, xmm2 - andnps xmm2, xmm4 - orps xmm3, xmm2 - xorps xmm3, SIMD_SP_not - - andps xmm0, SIMD_DW_mat2quatShuffle0 - movaps xmm4, xmm1 - andps xmm4, SIMD_DW_mat2quatShuffle1 - orps xmm0, xmm4 - movaps xmm4, xmm2 - andps xmm4, SIMD_DW_mat2quatShuffle2 - orps xmm0, xmm4 - movaps xmm4, xmm3 - andps xmm4, SIMD_DW_mat2quatShuffle3 - orps xmm4, xmm0 - - movaps shuffle, xmm4 - - movaps xmm0, xmm2 - orps xmm0, xmm3 // xmm0 = xmm2 | xmm3 = s0 - orps xmm2, xmm1 // xmm2 = xmm1 | xmm2 = s2 - orps xmm1, xmm3 // xmm1 = xmm1 | xmm3 = s1 - - andps xmm0, SIMD_SP_signBitMask - andps xmm1, SIMD_SP_signBitMask - andps xmm2, SIMD_SP_signBitMask - - xorps xmm5, xmm0 - xorps xmm6, xmm1 - xorps xmm7, xmm2 - addps xmm5, xmm6 - addps xmm7, SIMD_SP_one - addps xmm5, xmm7 // xmm5 = t - - movaps xmm7, xmm5 // xmm7 = t - rsqrtps xmm6, xmm5 - mulps xmm5, xmm6 - mulps xmm5, xmm6 - subps xmm5, SIMD_SP_rsqrt_c0 - mulps xmm6, SIMD_SP_mat2quat_rsqrt_c1 - mulps xmm6, xmm5 // xmm5 = s - - mulps xmm7, xmm6 // xmm7 = s * t - xorps xmm6, SIMD_SP_signBitMask // xmm6 = -s - - // ------------------- - - add edi, 4*JOINTQUAT_SIZE - - movzx ecx, byte ptr shuffle[0*4+0] // ecx = k0 - movss [edi+ecx*4-4*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; - - movzx edx, byte ptr shuffle[0*4+1] // edx = k1 - movss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+0*4] - xorps xmm4, xmm2 - subss xmm4, [esi+eax+0*JOINTMAT_SIZE+0*16+1*4] - mulss xmm4, xmm6 - movss [edi+edx*4-4*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - - movzx ecx, byte ptr shuffle[0*4+2] // ecx = k2 - movss xmm3, [esi+eax+0*JOINTMAT_SIZE+0*16+2*4] - xorps xmm3, xmm1 - subss xmm3, [esi+eax+0*JOINTMAT_SIZE+2*16+0*4] - mulss xmm3, xmm6 - movss [edi+ecx*4-4*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - - movzx edx, byte ptr shuffle[0*4+3] // edx = k3 - movss xmm4, [esi+eax+0*JOINTMAT_SIZE+2*16+1*4] - xorps xmm4, xmm0 - subss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+2*4] - mulss xmm4, xmm6 - movss [edi+edx*4-4*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - mov ecx, [esi+eax+0*JOINTMAT_SIZE+0*16+3*4] - mov [edi-4*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; - mov edx, [esi+eax+0*JOINTMAT_SIZE+1*16+3*4] - mov [edi-4*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; - mov ecx, [esi+eax+0*JOINTMAT_SIZE+2*16+3*4] - mov [edi-4*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; - - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movzx ecx, byte ptr shuffle[1*4+0] // ecx = k0 - movss [edi+ecx*4-3*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; - - movzx edx, byte ptr shuffle[1*4+1] // edx = k1 - movss xmm4, [esi+eax+1*JOINTMAT_SIZE+1*16+0*4] - xorps xmm4, xmm2 - subss xmm4, [esi+eax+1*JOINTMAT_SIZE+0*16+1*4] - mulss xmm4, xmm6 - movss [edi+edx*4-3*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - - movzx ecx, byte ptr shuffle[1*4+2] // ecx = k2 - movss xmm3, [esi+eax+1*JOINTMAT_SIZE+0*16+2*4] - xorps xmm3, xmm1 - subss xmm3, [esi+eax+1*JOINTMAT_SIZE+2*16+0*4] - mulss xmm3, xmm6 - movss [edi+ecx*4-3*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - - movzx edx, byte ptr shuffle[1*4+3] // edx = k3 - movss xmm4, [esi+eax+1*JOINTMAT_SIZE+2*16+1*4] - xorps xmm4, xmm0 - subss xmm4, [esi+eax+1*JOINTMAT_SIZE+1*16+2*4] - mulss xmm4, xmm6 - movss [edi+edx*4-3*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - mov ecx, [esi+eax+1*JOINTMAT_SIZE+0*16+3*4] - mov [edi-3*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; - mov edx, [esi+eax+1*JOINTMAT_SIZE+1*16+3*4] - mov [edi-3*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; - mov ecx, [esi+eax+1*JOINTMAT_SIZE+2*16+3*4] - mov [edi-3*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; - - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movzx ecx, byte ptr shuffle[2*4+0] // ecx = k0 - movss [edi+ecx*4-2*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; - - movzx edx, byte ptr shuffle[2*4+1] // edx = k1 - movss xmm4, [esi+eax+2*JOINTMAT_SIZE+1*16+0*4] - xorps xmm4, xmm2 - subss xmm4, [esi+eax+2*JOINTMAT_SIZE+0*16+1*4] - mulss xmm4, xmm6 - movss [edi+edx*4-2*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - - movzx ecx, byte ptr shuffle[2*4+2] // ecx = k2 - movss xmm3, [esi+eax+2*JOINTMAT_SIZE+0*16+2*4] - xorps xmm3, xmm1 - subss xmm3, [esi+eax+2*JOINTMAT_SIZE+2*16+0*4] - mulss xmm3, xmm6 - movss [edi+ecx*4-2*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - - movzx edx, byte ptr shuffle[2*4+3] // edx = k3 - movss xmm4, [esi+eax+2*JOINTMAT_SIZE+2*16+1*4] - xorps xmm4, xmm0 - subss xmm4, [esi+eax+2*JOINTMAT_SIZE+1*16+2*4] - mulss xmm4, xmm6 - movss [edi+edx*4-2*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - mov ecx, [esi+eax+2*JOINTMAT_SIZE+0*16+3*4] - mov [edi-2*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; - mov edx, [esi+eax+2*JOINTMAT_SIZE+1*16+3*4] - mov [edi-2*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; - mov ecx, [esi+eax+2*JOINTMAT_SIZE+2*16+3*4] - mov [edi-2*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; - - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movzx ecx, byte ptr shuffle[3*4+0] // ecx = k0 - movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; - - movzx edx, byte ptr shuffle[3*4+1] // edx = k1 - movss xmm4, [esi+eax+3*JOINTMAT_SIZE+1*16+0*4] - xorps xmm4, xmm2 - subss xmm4, [esi+eax+3*JOINTMAT_SIZE+0*16+1*4] - mulss xmm4, xmm6 - movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - - movzx ecx, byte ptr shuffle[3*4+2] // ecx = k2 - movss xmm3, [esi+eax+3*JOINTMAT_SIZE+0*16+2*4] - xorps xmm3, xmm1 - subss xmm3, [esi+eax+3*JOINTMAT_SIZE+2*16+0*4] - mulss xmm3, xmm6 - movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - - movzx edx, byte ptr shuffle[3*4+3] // edx = k3 - movss xmm4, [esi+eax+3*JOINTMAT_SIZE+2*16+1*4] - xorps xmm4, xmm0 - subss xmm4, [esi+eax+3*JOINTMAT_SIZE+1*16+2*4] - mulss xmm4, xmm6 - movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - mov ecx, [esi+eax+3*JOINTMAT_SIZE+0*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; - mov edx, [esi+eax+3*JOINTMAT_SIZE+1*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; - mov ecx, [esi+eax+3*JOINTMAT_SIZE+2*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; - - add eax, 4*JOINTMAT_SIZE - jl loopMat4 - - done4: - mov eax, numJoints - and eax, 3 - jz done1 - imul eax, JOINTMAT_SIZE - add esi, eax - neg eax - - loopMat1: - movss xmm5, [esi+eax+0*JOINTMAT_SIZE+0*16+0*4] - movss xmm6, [esi+eax+0*JOINTMAT_SIZE+1*16+1*4] - movss xmm7, [esi+eax+0*JOINTMAT_SIZE+2*16+2*4] - - // ------------------- - - movaps xmm0, xmm5 - addss xmm0, xmm6 - addss xmm0, xmm7 - cmpnltss xmm0, SIMD_SP_zero // xmm0 = m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f - - movaps xmm1, xmm5 - movaps xmm2, xmm5 - cmpnltss xmm1, xmm6 - cmpnltss xmm2, xmm7 - andps xmm2, xmm1 // xmm2 = m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] - - movaps xmm4, xmm6 - cmpnltss xmm4, xmm7 // xmm3 = m[1 * 4 + 1] > m[2 * 4 + 2] - - movaps xmm1, xmm0 - andnps xmm1, xmm2 - orps xmm2, xmm0 - movaps xmm3, xmm2 - andnps xmm2, xmm4 - orps xmm3, xmm2 - xorps xmm3, SIMD_SP_not - - andps xmm0, SIMD_DW_mat2quatShuffle0 - movaps xmm4, xmm1 - andps xmm4, SIMD_DW_mat2quatShuffle1 - orps xmm0, xmm4 - movaps xmm4, xmm2 - andps xmm4, SIMD_DW_mat2quatShuffle2 - orps xmm0, xmm4 - movaps xmm4, xmm3 - andps xmm4, SIMD_DW_mat2quatShuffle3 - orps xmm4, xmm0 - - movss shuffle, xmm4 - - movaps xmm0, xmm2 - orps xmm0, xmm3 // xmm0 = xmm2 | xmm3 = s0 - orps xmm2, xmm1 // xmm2 = xmm1 | xmm2 = s2 - orps xmm1, xmm3 // xmm1 = xmm1 | xmm3 = s1 - - andps xmm0, SIMD_SP_signBitMask - andps xmm1, SIMD_SP_signBitMask - andps xmm2, SIMD_SP_signBitMask - - xorps xmm5, xmm0 - xorps xmm6, xmm1 - xorps xmm7, xmm2 - addss xmm5, xmm6 - addss xmm7, SIMD_SP_one - addss xmm5, xmm7 // xmm5 = t - - movss xmm7, xmm5 // xmm7 = t - rsqrtss xmm6, xmm5 - mulss xmm5, xmm6 - mulss xmm5, xmm6 - subss xmm5, SIMD_SP_rsqrt_c0 - mulss xmm6, SIMD_SP_mat2quat_rsqrt_c1 - mulss xmm6, xmm5 // xmm5 = s - - mulss xmm7, xmm6 // xmm7 = s * t - xorps xmm6, SIMD_SP_signBitMask // xmm6 = -s - - // ------------------- - - movzx ecx, byte ptr shuffle[0] // ecx = k0 - add edi, JOINTQUAT_SIZE - movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm7 // q[k0] = s * t; - - movzx edx, byte ptr shuffle[1] // edx = k1 - movss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+0*4] - xorps xmm4, xmm2 - subss xmm4, [esi+eax+0*JOINTMAT_SIZE+0*16+1*4] - mulss xmm4, xmm6 - movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - - movzx ecx, byte ptr shuffle[2] // ecx = k2 - movss xmm3, [esi+eax+0*JOINTMAT_SIZE+0*16+2*4] - xorps xmm3, xmm1 - subss xmm3, [esi+eax+0*JOINTMAT_SIZE+2*16+0*4] - mulss xmm3, xmm6 - movss [edi+ecx*4-1*JOINTQUAT_SIZE], xmm3 // q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - - movzx edx, byte ptr shuffle[3] // edx = k3 - movss xmm4, [esi+eax+0*JOINTMAT_SIZE+2*16+1*4] - xorps xmm4, xmm0 - subss xmm4, [esi+eax+0*JOINTMAT_SIZE+1*16+2*4] - mulss xmm4, xmm6 - movss [edi+edx*4-1*JOINTQUAT_SIZE], xmm4 // q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - mov ecx, [esi+eax+0*JOINTMAT_SIZE+0*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+16], ecx // q[4] = m[0 * 4 + 3]; - mov edx, [esi+eax+0*JOINTMAT_SIZE+1*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+20], edx // q[5] = m[1 * 4 + 3]; - mov ecx, [esi+eax+0*JOINTMAT_SIZE+2*16+3*4] - mov [edi-1*JOINTQUAT_SIZE+24], ecx // q[6] = m[2 * 4 + 3]; - - add eax, JOINTMAT_SIZE - jl loopMat1 - - done1: - } - -#elif 0 - - for ( int i = 0; i < numJoints; i++ ) { - float s0, s1, s2; - int k0, k1, k2, k3; - - float *q = jointQuats[i].q.ToFloatPtr(); - const float *m = jointMats[i].ToFloatPtr(); - - if ( m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f ) { - - k0 = 3; - k1 = 2; - k2 = 1; - k3 = 0; - s0 = 1.0f; - s1 = 1.0f; - s2 = 1.0f; - - } else if ( m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] ) { - - k0 = 0; - k1 = 1; - k2 = 2; - k3 = 3; - s0 = 1.0f; - s1 = -1.0f; - s2 = -1.0f; - - } else if ( m[1 * 4 + 1] > m[2 * 4 + 2] ) { - - k0 = 1; - k1 = 0; - k2 = 3; - k3 = 2; - s0 = -1.0f; - s1 = 1.0f; - s2 = -1.0f; - - } else { - - k0 = 2; - k1 = 3; - k2 = 0; - k3 = 1; - s0 = -1.0f; - s1 = -1.0f; - s2 = 1.0f; - - } - - float t = s0 * m[0 * 4 + 0] + s1 * m[1 * 4 + 1] + s2 * m[2 * 4 + 2] + 1.0f; - float s = idMath::InvSqrt( t ) * 0.5f; - - q[k0] = s * t; - q[k1] = ( m[0 * 4 + 1] - s2 * m[1 * 4 + 0] ) * s; - q[k2] = ( m[2 * 4 + 0] - s1 * m[0 * 4 + 2] ) * s; - q[k3] = ( m[1 * 4 + 2] - s0 * m[2 * 4 + 1] ) * s; - - q[4] = m[0 * 4 + 3]; - q[5] = m[1 * 4 + 3]; - q[6] = m[2 * 4 + 3]; - } - -#elif 1 - - for ( int i = 0; i < numJoints; i++ ) { - - float *q = jointQuats[i].q.ToFloatPtr(); - const float *m = jointMats[i].ToFloatPtr(); - - if ( m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f ) { - - float t = + m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f; - float s = idMath::InvSqrt( t ) * 0.5f; - - q[3] = s * t; - q[2] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s; - q[1] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s; - q[0] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s; - - } else if ( m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] ) { - - float t = + m[0 * 4 + 0] - m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f; - float s = idMath::InvSqrt( t ) * 0.5f; - - q[0] = s * t; - q[1] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s; - q[2] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s; - q[3] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s; - - } else if ( m[1 * 4 + 1] > m[2 * 4 + 2] ) { - - float t = - m[0 * 4 + 0] + m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f; - float s = idMath::InvSqrt( t ) * 0.5f; - - q[1] = s * t; - q[0] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s; - q[3] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s; - q[2] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s; - - } else { - - float t = - m[0 * 4 + 0] - m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f; - float s = idMath::InvSqrt( t ) * 0.5f; - - q[2] = s * t; - q[3] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s; - q[0] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s; - q[1] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s; - - } - - q[4] = m[0 * 4 + 3]; - q[5] = m[1 * 4 + 3]; - q[6] = m[2 * 4 + 3]; - } - -#endif -} - -/* -============ -idSIMD_SSE::TransformJoints -============ -*/ -void VPCALL idSIMD_SSE::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { -#if 1 - - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - - __asm { - - mov ecx, firstJoint - mov eax, lastJoint - sub eax, ecx - jl done - imul ecx, 4 - mov edi, parents - add edi, ecx - imul ecx, 12 - mov esi, jointMats - imul eax, 4 - add edi, eax - neg eax - - loopJoint: - - movaps xmm0, [esi+ecx+ 0] // xmm0 = m0, m1, m2, t0 - mov edx, [edi+eax] - movaps xmm1, [esi+ecx+16] // xmm1 = m2, m3, m4, t1 - imul edx, JOINTMAT_SIZE - movaps xmm2, [esi+ecx+32] // xmm2 = m5, m6, m7, t2 - - movss xmm4, [esi+edx+ 0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm0 - - movss xmm5, [esi+edx+ 4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm1 - addps xmm4, xmm5 - movss xmm6, [esi+edx+ 8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm2 - addps xmm4, xmm6 - - movss xmm5, [esi+edx+16] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm0 - - movss xmm7, [esi+edx+12] - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - addps xmm4, xmm7 - - movaps [esi+ecx+ 0], xmm4 - - movss xmm6, [esi+edx+20] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm1 - addps xmm5, xmm6 - movss xmm7, [esi+edx+24] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm5, xmm7 - - movss xmm6, [esi+edx+32] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - - movss xmm3, [esi+edx+28] - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) - addps xmm5, xmm3 - - movaps [esi+ecx+16], xmm5 - - movss xmm7, [esi+edx+36] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movss xmm3, [esi+edx+40] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm2 - addps xmm6, xmm3 - - movss xmm7, [esi+edx+44] - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - addps xmm6, xmm7 - - movaps [esi+ecx+32], xmm6 - - add ecx, JOINTMAT_SIZE - add eax, 4 - jle loopJoint - done: - } - -#else - - int i; - - for( i = firstJoint; i <= lastJoint; i++ ) { - assert( parents[i] < i ); - jointMats[i] *= jointMats[parents[i]]; - } - -#endif -} - -/* -============ -idSIMD_SSE::UntransformJoints -============ -*/ -void VPCALL idSIMD_SSE::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { -#if 1 - - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - - __asm { - - mov edx, firstJoint - mov eax, lastJoint - mov ecx, eax - sub eax, edx - jl done - mov esi, jointMats - imul ecx, JOINTMAT_SIZE - imul edx, 4 - mov edi, parents - add edi, edx - imul eax, 4 - - loopJoint: - - movaps xmm0, [esi+ecx+ 0] // xmm0 = m0, m1, m2, t0 - mov edx, [edi+eax] - movaps xmm1, [esi+ecx+16] // xmm1 = m2, m3, m4, t1 - imul edx, JOINTMAT_SIZE - movaps xmm2, [esi+ecx+32] // xmm2 = m5, m6, m7, t2 - - movss xmm6, [esi+edx+12] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - subps xmm0, xmm6 - movss xmm7, [esi+edx+28] - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 2, 3, 0 ) - subps xmm1, xmm7 - movss xmm3, [esi+edx+44] - shufps xmm3, xmm3, R_SHUFFLEPS( 1, 2, 3, 0 ) - subps xmm2, xmm3 - - movss xmm4, [esi+edx+ 0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm4, xmm0 - movss xmm5, [esi+edx+16] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm1 - addps xmm4, xmm5 - movss xmm6, [esi+edx+32] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm2 - addps xmm4, xmm6 - - movaps [esi+ecx+ 0], xmm4 - - movss xmm5, [esi+edx+ 4] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm5, xmm0 - movss xmm6, [esi+edx+20] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm1 - addps xmm5, xmm6 - movss xmm7, [esi+edx+36] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm5, xmm7 - - movaps [esi+ecx+16], xmm5 - - movss xmm6, [esi+edx+ 8] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movss xmm7, [esi+edx+24] - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movss xmm3, [esi+edx+40] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm3, xmm2 - addps xmm6, xmm3 - - movaps [esi+ecx+32], xmm6 - - sub ecx, JOINTMAT_SIZE - sub eax, 4 - jge loopJoint - done: - } - -#else - - int i; - - for( i = lastJoint; i >= firstJoint; i-- ) { - assert( parents[i] < i ); - jointMats[i] /= jointMats[parents[i]]; - } - -#endif -} - -/* -============ -idSIMD_SSE::TransformVerts -============ -*/ -void VPCALL idSIMD_SSE::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) { -#if 1 - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - assert( sizeof( idVec4 ) == JOINTWEIGHT_SIZE ); - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - - __asm - { - mov eax, numVerts - test eax, eax - jz done - imul eax, DRAWVERT_SIZE - - mov ecx, verts - mov edx, index - mov esi, weights - mov edi, joints - - add ecx, eax - neg eax - - loopVert: - mov ebx, [edx] - movaps xmm2, [esi] - add edx, 8 - movaps xmm0, xmm2 - add esi, JOINTWEIGHT_SIZE - movaps xmm1, xmm2 - - mulps xmm0, [edi+ebx+ 0] // xmm0 = m0, m1, m2, t0 - mulps xmm1, [edi+ebx+16] // xmm1 = m3, m4, m5, t1 - mulps xmm2, [edi+ebx+32] // xmm2 = m6, m7, m8, t2 - - cmp dword ptr [edx-4], 0 - - jne doneWeight - - loopWeight: - mov ebx, [edx] - movaps xmm5, [esi] - add edx, 8 - movaps xmm3, xmm5 - add esi, JOINTWEIGHT_SIZE - movaps xmm4, xmm5 - - mulps xmm3, [edi+ebx+ 0] // xmm3 = m0, m1, m2, t0 - mulps xmm4, [edi+ebx+16] // xmm4 = m3, m4, m5, t1 - mulps xmm5, [edi+ebx+32] // xmm5 = m6, m7, m8, t2 - - cmp dword ptr [edx-4], 0 - - addps xmm0, xmm3 - addps xmm1, xmm4 - addps xmm2, xmm5 - - je loopWeight - - doneWeight: - add eax, DRAWVERT_SIZE - - movaps xmm6, xmm0 // xmm6 = m0, m1, m2, t0 - unpcklps xmm6, xmm1 // xmm6 = m0, m3, m1, m4 - unpckhps xmm0, xmm1 // xmm1 = m2, m5, t0, t1 - addps xmm6, xmm0 // xmm6 = m0+m2, m3+m5, m1+t0, m4+t1 - - movaps xmm7, xmm2 // xmm7 = m6, m7, m8, t2 - movlhps xmm2, xmm6 // xmm2 = m6, m7, m0+m2, m3+m5 - movhlps xmm6, xmm7 // xmm6 = m8, t2, m1+t0, m4+t1 - addps xmm6, xmm2 // xmm6 = m6+m8, m7+t2, m0+m1+m2+t0, m3+m4+m5+t1 - - movhps [ecx+eax-DRAWVERT_SIZE+0], xmm6 - - movaps xmm5, xmm6 // xmm5 = m6+m8, m7+t2 - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 0, 2, 3 ) // xmm5 = m7+t2, m6+m8 - addss xmm5, xmm6 // xmm5 = m6+m8+m7+t2 - - movss [ecx+eax-DRAWVERT_SIZE+8], xmm5 - - jl loopVert - done: - } - -#else - - int i, j; - const byte *jointsPtr = (byte *)joints; - - for( j = i = 0; i < numVerts; i++ ) { - idVec3 v; - - v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - while( index[j*2+1] == 0 ) { - j++; - v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - } - j++; - - verts[i].xyz = v; - } - -#endif -} - -/* -============ -idSIMD_SSE::TracePointCull -============ -*/ -void VPCALL idSIMD_SSE::TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { -#if 1 - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - push ebx - mov eax, numVerts - test eax, eax - jz done - - mov edi, planes - movlps xmm1, [edi] // xmm1 = 0, 1, X, X - movhps xmm1, [edi+16] // xmm1 = 0, 1, 4, 5 - movlps xmm3, [edi+8] // xmm3 = 2, 3, X, X - movhps xmm3, [edi+24] // xmm3 = 2, 3, 6, 7 - movlps xmm4, [edi+32] // xmm4 = 8, 9, X, X - movhps xmm4, [edi+48] // xmm4 = 8, 9, 12, 13 - movlps xmm5, [edi+40] // xmm5 = 10, 11, X, X - movhps xmm5, [edi+56] // xmm5 = 10, 11, 14, 15 - movaps xmm0, xmm1 // xmm0 = 0, 1, 4, 5 - shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm0 = 0, 4, 8, 12 - shufps xmm1, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm1 = 1, 5, 9, 13 - movaps xmm2, xmm3 // xmm2 = 2, 3, 6, 7 - shufps xmm2, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm2 = 2, 6, 10, 14 - shufps xmm3, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm3 = 3, 7, 11, 15 - movss xmm7, radius - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - xor edx, edx - mov esi, verts - mov edi, cullBits - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loopVert: - movss xmm4, [esi+eax+DRAWVERT_XYZ_OFFSET+0] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm5, [esi+eax+DRAWVERT_XYZ_OFFSET+4] - mulps xmm4, xmm0 - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - movss xmm6, [esi+eax+DRAWVERT_XYZ_OFFSET+8] - mulps xmm5, xmm1 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - addps xmm4, xmm5 - mulps xmm6, xmm2 - addps xmm4, xmm3 - addps xmm4, xmm6 - movaps xmm5, xmm4 - xorps xmm5, SIMD_SP_signBitMask - cmpltps xmm4, xmm7 - movmskps ecx, xmm4 - cmpltps xmm5, xmm7 - movmskps ebx, xmm5 - shl cx, 4 - or cl, bl - inc edi - or dl, cl - add eax, DRAWVERT_SIZE - mov byte ptr [edi-1], cl - jl loopVert - - done: - mov esi, totalOr - mov byte ptr [esi], dl - pop ebx - } - -#else - - int i; - byte tOr; - - tOr = 0; - - for ( i = 0; i < numVerts; i++ ) { - byte bits; - float d0, d1, d2, d3, t; - const idVec3 &v = verts[i].xyz; - - d0 = planes[0][0] * v[0] + planes[0][1] * v[1] + planes[0][2] * v[2] + planes[0][3]; - d1 = planes[1][0] * v[0] + planes[1][1] * v[1] + planes[1][2] * v[2] + planes[1][3]; - d2 = planes[2][0] * v[0] + planes[2][1] * v[1] + planes[2][2] * v[2] + planes[2][3]; - d3 = planes[3][0] * v[0] + planes[3][1] * v[1] + planes[3][2] * v[2] + planes[3][3]; - - t = d0 + radius; - bits = FLOATSIGNBITSET( t ) << 0; - t = d1 + radius; - bits |= FLOATSIGNBITSET( t ) << 1; - t = d2 + radius; - bits |= FLOATSIGNBITSET( t ) << 2; - t = d3 + radius; - bits |= FLOATSIGNBITSET( t ) << 3; - - t = d0 - radius; - bits |= FLOATSIGNBITSET( t ) << 4; - t = d1 - radius; - bits |= FLOATSIGNBITSET( t ) << 5; - t = d2 - radius; - bits |= FLOATSIGNBITSET( t ) << 6; - t = d3 - radius; - bits |= FLOATSIGNBITSET( t ) << 7; - - bits ^= 0x0F; // flip lower four bits - - tOr |= bits; - cullBits[i] = bits; - } - - totalOr = tOr; - -#endif -} - -/* -============ -idSIMD_SSE::DecalPointCull -============ -*/ -void VPCALL idSIMD_SSE::DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { -#if 1 - - ALIGN16( float p0[4] ); - ALIGN16( float p1[4] ); - ALIGN16( float p2[4] ); - ALIGN16( float p3[4] ); - ALIGN16( float p4[4] ); - ALIGN16( float p5[4] ); - ALIGN16( float p6[4] ); - ALIGN16( float p7[4] ); - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - mov ecx, planes - movlps xmm1, [ecx] // xmm1 = 0, 1, X, X - movhps xmm1, [ecx+16] // xmm1 = 0, 1, 4, 5 - movlps xmm3, [ecx+8] // xmm3 = 2, 3, X, X - movhps xmm3, [ecx+24] // xmm3 = 2, 3, 6, 7 - movlps xmm4, [ecx+32] // xmm4 = 8, 9, X, X - movhps xmm4, [ecx+48] // xmm4 = 8, 9, 12, 13 - movlps xmm5, [ecx+40] // xmm5 = 10, 11, X, X - movhps xmm5, [ecx+56] // xmm5 = 10, 11, 14, 15 - movaps xmm0, xmm1 // xmm0 = 0, 1, 4, 5 - shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm0 = 0, 4, 8, 12 - shufps xmm1, xmm4, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm1 = 1, 5, 9, 13 - movaps xmm2, xmm3 // xmm2 = 2, 3, 6, 7 - shufps xmm2, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm2 = 2, 6, 10, 14 - shufps xmm3, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm3 = 3, 7, 11, 15 - - movaps p0, xmm0 - movaps p1, xmm1 - movaps p2, xmm2 - movaps p3, xmm3 - - movlps xmm4, [ecx+64] // xmm4 = p40, p41, X, X - movhps xmm4, [ecx+80] // xmm4 = p40, p41, p50, p51 - movaps xmm5, xmm4 // xmm5 = p40, p41, p50, p51 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm4 = p40, p50, p40, p50 - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm5 = p41, p51, p41, p51 - movlps xmm6, [ecx+72] // xmm6 = p42, p43, X, X - movhps xmm6, [ecx+88] // xmm6 = p42, p43, p52, p53 - movaps xmm7, xmm6 // xmm7 = p42, p43, p52, p53 - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 0, 2 ) // xmm6 = p42, p52, p42, p52 - shufps xmm7, xmm7, R_SHUFFLEPS( 1, 3, 1, 3 ) // xmm7 = p43, p53, p43, p53 - - movaps p4, xmm4 - movaps p5, xmm5 - movaps p6, xmm6 - movaps p7, xmm7 - - mov esi, verts - mov edi, cullBits - mov eax, numVerts - and eax, ~1 - jz done2 - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - - loopVert2: - movaps xmm6, p0 - movss xmm0, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movaps xmm7, p1 - movss xmm1, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movaps xmm7, p2 - movss xmm2, [esi+eax+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - addps xmm6, p3 - - cmpnltps xmm6, SIMD_SP_zero - movmskps ecx, xmm6 - - movaps xmm6, p0 - movss xmm3, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm3 - movaps xmm7, p1 - movss xmm4, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm4 - addps xmm6, xmm7 - movaps xmm7, p2 - movss xmm5, [esi+eax+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm5 - addps xmm6, xmm7 - addps xmm6, p3 - - cmpnltps xmm6, SIMD_SP_zero - movmskps edx, xmm6 - mov ch, dl - - shufps xmm0, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm0, p4 - shufps xmm1, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm1, p5 - addps xmm0, xmm1 - shufps xmm2, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm2, p6 - addps xmm0, xmm2 - addps xmm0, p7 - - cmpnltps xmm0, SIMD_SP_zero - movmskps edx, xmm0 - - add edi, 2 - - mov dh, dl - shl dl, 4 - shl dh, 2 - and edx, (3<<4)|(3<<12) - or ecx, edx - - add eax, 2*DRAWVERT_SIZE - mov word ptr [edi-2], cx - jl loopVert2 - - done2: - - mov eax, numVerts - and eax, 1 - jz done - - movaps xmm6, p0 - movss xmm0, [esi+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm6, xmm0 - movaps xmm7, p1 - movss xmm1, [esi+DRAWVERT_XYZ_OFFSET+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm1 - addps xmm6, xmm7 - movaps xmm7, p2 - movss xmm2, [esi+DRAWVERT_XYZ_OFFSET+8] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm7, xmm2 - addps xmm6, xmm7 - addps xmm6, p3 - - cmpnltps xmm6, SIMD_SP_zero - movmskps ecx, xmm6 - - mulps xmm0, p4 - mulps xmm1, p5 - addps xmm0, xmm1 - mulps xmm2, p6 - addps xmm0, xmm2 - addps xmm0, p7 - - cmpnltps xmm0, SIMD_SP_zero - movmskps edx, xmm0 - - and edx, 3 - shl edx, 4 - or ecx, edx - - mov byte ptr [edi], cl - - done: - } - - -#else - - int i; - - for ( i = 0; i < numVerts; i += 2 ) { - unsigned short bits0, bits1; - float d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11; - const idVec3 &v0 = verts[i+0].xyz; - const idVec3 &v1 = verts[i+1].xyz; - - d0 = planes[0][0] * v0[0] + planes[0][1] * v0[1] + planes[0][2] * v0[2] + planes[0][3]; - d1 = planes[1][0] * v0[0] + planes[1][1] * v0[1] + planes[1][2] * v0[2] + planes[1][3]; - d2 = planes[2][0] * v0[0] + planes[2][1] * v0[1] + planes[2][2] * v0[2] + planes[2][3]; - d3 = planes[3][0] * v0[0] + planes[3][1] * v0[1] + planes[3][2] * v0[2] + planes[3][3]; - - d4 = planes[4][0] * v0[0] + planes[4][1] * v0[1] + planes[4][2] * v0[2] + planes[4][3]; - d5 = planes[5][0] * v0[0] + planes[5][1] * v0[1] + planes[5][2] * v0[2] + planes[5][3]; - d10 = planes[4][0] * v1[0] + planes[4][1] * v1[1] + planes[4][2] * v1[2] + planes[4][3]; - d11 = planes[5][0] * v1[0] + planes[5][1] * v1[1] + planes[5][2] * v1[2] + planes[5][3]; - - d6 = planes[0][0] * v1[0] + planes[0][1] * v1[1] + planes[0][2] * v1[2] + planes[0][3]; - d7 = planes[1][0] * v1[0] + planes[1][1] * v1[1] + planes[1][2] * v1[2] + planes[1][3]; - d8 = planes[2][0] * v1[0] + planes[2][1] * v1[1] + planes[2][2] * v1[2] + planes[2][3]; - d9 = planes[3][0] * v1[0] + planes[3][1] * v1[1] + planes[3][2] * v1[2] + planes[3][3]; - - bits0 = FLOATSIGNBITSET( d0 ) << (0+0); - bits0 |= FLOATSIGNBITSET( d1 ) << (0+1); - bits0 |= FLOATSIGNBITSET( d2 ) << (0+2); - bits0 |= FLOATSIGNBITSET( d3 ) << (0+3); - bits0 |= FLOATSIGNBITSET( d4 ) << (0+4); - bits0 |= FLOATSIGNBITSET( d5 ) << (0+5); - - bits1 = FLOATSIGNBITSET( d6 ) << (8+0); - bits1 |= FLOATSIGNBITSET( d7 ) << (8+1); - bits1 |= FLOATSIGNBITSET( d8 ) << (8+2); - bits1 |= FLOATSIGNBITSET( d9 ) << (8+3); - bits1 |= FLOATSIGNBITSET( d10 ) << (8+4); - bits1 |= FLOATSIGNBITSET( d11 ) << (8+5); - - *(unsigned short *)(cullBits + i) = ( bits0 | bits1 ) ^ 0x3F3F; - } - - if ( numVerts & 1 ) { - byte bits; - float d0, d1, d2, d3, d4, d5; - const idVec3 &v = verts[numVerts - 1].xyz; - - d0 = planes[0][0] * v[0] + planes[0][1] * v[1] + planes[0][2] * v[2] + planes[0][3]; - d1 = planes[1][0] * v[0] + planes[1][1] * v[1] + planes[1][2] * v[2] + planes[1][3]; - d2 = planes[2][0] * v[0] + planes[2][1] * v[1] + planes[2][2] * v[2] + planes[2][3]; - d3 = planes[3][0] * v[0] + planes[3][1] * v[1] + planes[3][2] * v[2] + planes[3][3]; - - d4 = planes[4][0] * v[0] + planes[4][1] * v[1] + planes[4][2] * v[2] + planes[4][3]; - d5 = planes[5][0] * v[0] + planes[5][1] * v[1] + planes[5][2] * v[2] + planes[5][3]; - - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - bits |= FLOATSIGNBITSET( d2 ) << 2; - bits |= FLOATSIGNBITSET( d3 ) << 3; - - bits |= FLOATSIGNBITSET( d4 ) << 4; - bits |= FLOATSIGNBITSET( d5 ) << 5; - - cullBits[numVerts - 1] = bits ^ 0x3F; // flip lower 6 bits - } - -#endif -} - -/* -============ -idSIMD_SSE::OverlayPointCull -============ -*/ -void VPCALL idSIMD_SSE::OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ) { -#if 1 - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - mov eax, numVerts - mov edx, verts - mov esi, texCoords - mov edi, cullBits - - mov ecx, planes - movss xmm4, [ecx+ 0] - movss xmm5, [ecx+16] - shufps xmm4, xmm5, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) - movss xmm5, [ecx+ 4] - movss xmm6, [ecx+20] - shufps xmm5, xmm6, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 2, 0, 2 ) - movss xmm6, [ecx+ 8] - movss xmm7, [ecx+24] - shufps xmm6, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 0, 2 ) - movss xmm7, [ecx+12] - movss xmm0, [ecx+28] - shufps xmm7, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 2, 0, 2 ) - - and eax, ~1 - jz done2 - add edi, eax - neg eax - - loopVert2: - movss xmm0, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movss xmm1, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm0, xmm4 - movss xmm1, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - movss xmm2, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm1, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm1, xmm5 - movss xmm2, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movss xmm3, [edx+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - shufps xmm2, xmm3, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm2, xmm6 - addps xmm0, xmm1 - addps xmm0, xmm2 - addps xmm0, xmm7 - movaps [esi], xmm0 - movaps xmm1, xmm0 - movaps xmm2, SIMD_SP_one - subps xmm2, xmm0 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - shufps xmm1, xmm2, R_SHUFFLEPS( 2, 3, 2, 3 ) - add edx, 2*DRAWVERT_SIZE - movmskps ecx, xmm0 - mov byte ptr [edi+eax+0], cl - add esi, 4*4 - movmskps ecx, xmm1 - mov byte ptr [edi+eax+1], cl - add eax, 2 - jl loopVert2 - - done2: - mov eax, numVerts - and eax, 1 - jz done - - movss xmm0, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm0, xmm4 - movss xmm1, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm1, xmm5 - movss xmm2, [edx+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm2, xmm6 - addps xmm0, xmm1 - addps xmm0, xmm2 - addps xmm0, xmm7 - movlps [esi], xmm0 - movaps xmm1, xmm0 - movaps xmm2, SIMD_SP_one - subps xmm2, xmm0 - shufps xmm0, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - movmskps ecx, xmm0 - mov byte ptr [edi], cl - - done: - } - -#else - - const idPlane &p0 = planes[0]; - const idPlane &p1 = planes[1]; - - for ( int i = 0; i < numVerts - 1; i += 2 ) { - unsigned short bits; - float d0, d1, d2, d3; - - const idVec3 &v0 = verts[i+0].xyz; - const idVec3 &v1 = verts[i+1].xyz; - - d0 = p0[0] * v0[0] + p0[1] * v0[1] + p0[2] * v0[2] + p0[3]; - d1 = p1[0] * v0[0] + p1[1] * v0[1] + p1[2] * v0[2] + p1[3]; - d2 = p0[0] * v1[0] + p0[1] * v1[1] + p0[2] * v1[2] + p0[3]; - d3 = p1[0] * v1[0] + p1[1] * v1[1] + p1[2] * v1[2] + p1[3]; - - texCoords[i+0][0] = d0; - texCoords[i+0][1] = d1; - texCoords[i+1][0] = d2; - texCoords[i+1][1] = d3; - - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - bits |= FLOATSIGNBITSET( d2 ) << 8; - bits |= FLOATSIGNBITSET( d3 ) << 9; - - d0 = 1.0f - d0; - d1 = 1.0f - d1; - d2 = 1.0f - d2; - d3 = 1.0f - d3; - - bits |= FLOATSIGNBITSET( d0 ) << 2; - bits |= FLOATSIGNBITSET( d1 ) << 3; - bits |= FLOATSIGNBITSET( d2 ) << 10; - bits |= FLOATSIGNBITSET( d3 ) << 11; - - *(unsigned short *)(cullBits + i) = bits; - } - - if ( numVerts & 1 ) { - byte bits; - float d0, d1; - - const idPlane &p0 = planes[0]; - const idPlane &p1 = planes[1]; - const idVec3 &v0 = verts[numVerts - 1].xyz; - - d0 = p0[0] * v0[0] + p0[1] * v0[1] + p0[2] * v0[2] + p0[3]; - d1 = p1[0] * v0[0] + p1[1] * v0[1] + p1[2] * v0[2] + p1[3]; - - texCoords[i][0] = d0; - texCoords[i][1] = d1; - - bits = FLOATSIGNBITSET( d0 ) << 0; - bits |= FLOATSIGNBITSET( d1 ) << 1; - - d0 = 1.0f - d0; - d1 = 1.0f - d1; - - bits |= FLOATSIGNBITSET( d0 ) << 2; - bits |= FLOATSIGNBITSET( d1 ) << 3; - - cullBits[numVerts - 1] = bits; - } - -#endif -} - -/* -============ -idSIMD_SSE::DeriveTriPlanes -============ -*/ -void VPCALL idSIMD_SSE::DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { -#if 1 - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - - __asm { - mov eax, numIndexes - shl eax, 2 - mov esi, verts - mov edi, indexes - mov edx, planes - - add edi, eax - neg eax - - add eax, 4*12 - jge done4 - - loopPlane4: - mov ebx, [edi+eax-4*12+4] - imul ebx, DRAWVERT_SIZE - mov ecx, [edi+eax-4*12+0] - imul ecx, DRAWVERT_SIZE - - movss xmm0, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - - movss xmm1, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - - movss xmm2, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - mov ebx, [edi+eax-4*12+8] - imul ebx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm3, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm3, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - - movss xmm4, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm4, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - - movss xmm5, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm5, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - mov ebx, [edi+eax-3*12+4] - imul ebx, DRAWVERT_SIZE - mov ecx, [edi+eax-3*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm0, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm1, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm2, xmm6 - - mov ebx, [edi+eax-3*12+8] - imul ebx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm3, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm4, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm5, xmm7 - - mov ebx, [edi+eax-2*12+4] - imul ebx, DRAWVERT_SIZE - mov ecx, [edi+eax-2*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm0, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm1, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm2, xmm6 - - mov ebx, [edi+eax-2*12+8] - imul ebx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm3, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm4, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm5, xmm7 - - mov ebx, [edi+eax-1*12+4] - imul ebx, DRAWVERT_SIZE - mov ecx, [edi+eax-1*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm3, xmm3, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm4, xmm4, R_SHUFFLEPS( 3, 0, 1, 2 ) - shufps xmm5, xmm5, R_SHUFFLEPS( 3, 0, 1, 2 ) - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm0, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm1, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm2, xmm6 - - mov ebx, [edi+eax-1*12+8] - imul ebx, DRAWVERT_SIZE - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - movss xmm3, xmm7 - - movss xmm6, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm6, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - movss xmm4, xmm6 - - movss xmm7, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm7, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - movss xmm5, xmm7 - - movaps xmm6, xmm4 - mulps xmm6, xmm2 - movaps xmm7, xmm5 - mulps xmm7, xmm1 - subps xmm6, xmm7 - - mulps xmm5, xmm0 - mulps xmm2, xmm3 - subps xmm5, xmm2 - - mulps xmm3, xmm1 - mulps xmm4, xmm0 - subps xmm3, xmm4 - - movaps xmm0, xmm6 - mulps xmm6, xmm6 - movaps xmm1, xmm5 - mulps xmm5, xmm5 - movaps xmm2, xmm3 - mulps xmm3, xmm3 - - addps xmm3, xmm5 - addps xmm3, xmm6 - rsqrtps xmm3, xmm3 - - add edx, 4*16 - mov ecx, [edi+eax-1*12+0] - imul ecx, DRAWVERT_SIZE - - mulps xmm0, xmm3 - mulps xmm1, xmm3 - mulps xmm2, xmm3 - - movss [edx-1*16+0], xmm0 - movss [edx-1*16+4], xmm1 - movss [edx-1*16+8], xmm2 - - mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - xorps xmm0, SIMD_SP_singleSignBitMask - subss xmm0, xmm1 - subss xmm0, xmm2 - movss [edx-1*16+12], xmm0 - - mov ecx, [edi+eax-2*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [edx-2*16+0], xmm0 - movss [edx-2*16+4], xmm1 - movss [edx-2*16+8], xmm2 - - mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - xorps xmm0, SIMD_SP_singleSignBitMask - subss xmm0, xmm1 - subss xmm0, xmm2 - movss [edx-2*16+12], xmm0 - - mov ecx, [edi+eax-3*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [edx-3*16+0], xmm0 - movss [edx-3*16+4], xmm1 - movss [edx-3*16+8], xmm2 - - mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - xorps xmm0, SIMD_SP_singleSignBitMask - subss xmm0, xmm1 - subss xmm0, xmm2 - movss [edx-3*16+12], xmm0 - - mov ecx, [edi+eax-4*12+0] - imul ecx, DRAWVERT_SIZE - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [edx-4*16+0], xmm0 - movss [edx-4*16+4], xmm1 - movss [edx-4*16+8], xmm2 - - mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - xorps xmm0, SIMD_SP_singleSignBitMask - subss xmm0, xmm1 - subss xmm0, xmm2 - movss [edx-4*16+12], xmm0 - - add eax, 4*12 - jle loopPlane4 - - done4: - - sub eax, 4*12 - jge done - - loopPlane1: - mov ebx, [edi+eax+4] - imul ebx, DRAWVERT_SIZE - mov ecx, [edi+eax+0] - imul ecx, DRAWVERT_SIZE - - movss xmm0, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - - movss xmm1, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - - movss xmm2, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - mov ebx, [edi+eax+8] - imul ebx, DRAWVERT_SIZE - - movss xmm3, [esi+ebx+DRAWVERT_XYZ_OFFSET+0] - subss xmm3, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - - movss xmm4, [esi+ebx+DRAWVERT_XYZ_OFFSET+4] - subss xmm4, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - - movss xmm5, [esi+ebx+DRAWVERT_XYZ_OFFSET+8] - subss xmm5, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - movss xmm6, xmm4 - mulss xmm6, xmm2 - movss xmm7, xmm5 - mulss xmm7, xmm1 - subss xmm6, xmm7 - - mulss xmm5, xmm0 - mulss xmm2, xmm3 - subss xmm5, xmm2 - - mulss xmm3, xmm1 - mulss xmm4, xmm0 - subss xmm3, xmm4 - - movss xmm0, xmm6 - mulss xmm6, xmm6 - movss xmm1, xmm5 - mulss xmm5, xmm5 - movss xmm2, xmm3 - mulss xmm3, xmm3 - - addss xmm3, xmm5 - addss xmm3, xmm6 - rsqrtss xmm3, xmm3 - - add edx, 1*16 - - mulss xmm0, xmm3 - mulss xmm1, xmm3 - mulss xmm2, xmm3 - - movss [edx-1*16+0], xmm0 - movss [edx-1*16+4], xmm1 - movss [edx-1*16+8], xmm2 - - mulss xmm0, [esi+ecx+DRAWVERT_XYZ_OFFSET+0] - mulss xmm1, [esi+ecx+DRAWVERT_XYZ_OFFSET+4] - mulss xmm2, [esi+ecx+DRAWVERT_XYZ_OFFSET+8] - - xorps xmm0, SIMD_SP_singleSignBitMask - subss xmm0, xmm1 - subss xmm0, xmm2 - movss [edx-1*16+12], xmm0 - - add eax, 1*12 - jl loopPlane1 - - done: - } - -#else - - int i, j; - - for ( i = 0; i <= numIndexes - 12; i += 12 ) { - ALIGN16( float d0[4] ); - ALIGN16( float d1[4] ); - ALIGN16( float d2[4] ); - ALIGN16( float d3[4] ); - ALIGN16( float d4[4] ); - ALIGN16( float d5[4] ); - ALIGN16( float n0[4] ); - ALIGN16( float n1[4] ); - ALIGN16( float n2[4] ); - - for ( j = 0; j < 4; j++ ) { - const idDrawVert *a, *b, *c; - - a = verts + indexes[i + j * 3 + 0]; - b = verts + indexes[i + j * 3 + 1]; - c = verts + indexes[i + j * 3 + 2]; - - d0[j] = b->xyz[0] - a->xyz[0]; - d1[j] = b->xyz[1] - a->xyz[1]; - d2[j] = b->xyz[2] - a->xyz[2]; - - d3[j] = c->xyz[0] - a->xyz[0]; - d4[j] = c->xyz[1] - a->xyz[1]; - d5[j] = c->xyz[2] - a->xyz[2]; - } - - ALIGN16( float tmp[4] ); - - n0[0] = d4[0] * d2[0]; - n0[1] = d4[1] * d2[1]; - n0[2] = d4[2] * d2[2]; - n0[3] = d4[3] * d2[3]; - - n0[0] -= d5[0] * d1[0]; - n0[1] -= d5[1] * d1[1]; - n0[2] -= d5[2] * d1[2]; - n0[3] -= d5[3] * d1[3]; - - n1[0] = d5[0] * d0[0]; - n1[1] = d5[1] * d0[1]; - n1[2] = d5[2] * d0[2]; - n1[3] = d5[3] * d0[3]; - - n1[0] -= d3[0] * d2[0]; - n1[1] -= d3[1] * d2[1]; - n1[2] -= d3[2] * d2[2]; - n1[3] -= d3[3] * d2[3]; - - n2[0] = d3[0] * d1[0]; - n2[1] = d3[1] * d1[1]; - n2[2] = d3[2] * d1[2]; - n2[3] = d3[3] * d1[3]; - - n2[0] -= d4[0] * d0[0]; - n2[1] -= d4[1] * d0[1]; - n2[2] -= d4[2] * d0[2]; - n2[3] -= d4[3] * d0[3]; - - tmp[0] = n0[0] * n0[0]; - tmp[1] = n0[1] * n0[1]; - tmp[2] = n0[2] * n0[2]; - tmp[3] = n0[3] * n0[3]; - - tmp[0] += n1[0] * n1[0]; - tmp[1] += n1[1] * n1[1]; - tmp[2] += n1[2] * n1[2]; - tmp[3] += n1[3] * n1[3]; - - tmp[0] += n2[0] * n2[0]; - tmp[1] += n2[1] * n2[1]; - tmp[2] += n2[2] * n2[2]; - tmp[3] += n2[3] * n2[3]; - - tmp[0] = idMath::RSqrt( tmp[0] ); - tmp[1] = idMath::RSqrt( tmp[1] ); - tmp[2] = idMath::RSqrt( tmp[2] ); - tmp[3] = idMath::RSqrt( tmp[3] ); - - n0[0] *= tmp[0]; - n0[1] *= tmp[1]; - n0[2] *= tmp[2]; - n0[3] *= tmp[3]; - - n1[0] *= tmp[0]; - n1[1] *= tmp[1]; - n1[2] *= tmp[2]; - n1[3] *= tmp[3]; - - n2[0] *= tmp[0]; - n2[1] *= tmp[1]; - n2[2] *= tmp[2]; - n2[3] *= tmp[3]; - - - for ( j = 0; j < 4; j++ ) { - const idDrawVert *a; - - a = verts + indexes[i + j * 3]; - - planes->Normal()[0] = n0[j]; - planes->Normal()[1] = n1[j]; - planes->Normal()[2] = n2[j]; - planes->FitThroughPoint( a->xyz ); - planes++; - } - } - - for ( ; i < numIndexes; i += 3 ) { - const idDrawVert *a, *b, *c; - float d0, d1, d2, d3, d4, d5; - float n0, n1, n2; - - a = verts + indexes[i + 0]; - b = verts + indexes[i + 1]; - c = verts + indexes[i + 2]; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - - d3 = c->xyz[0] - a->xyz[0]; - d4 = c->xyz[1] - a->xyz[1]; - d5 = c->xyz[2] - a->xyz[2]; - - float tmp; - - n0 = d4 * d2 - d5 * d1; - n1 = d5 * d0 - d3 * d2; - n2 = d3 * d1 - d4 * d0; - - tmp = idMath::RSqrt( n0 * n0 + n1 * n1 + n2 * n2 ); - - n0 *= tmp; - n1 *= tmp; - n2 *= tmp; - - planes->Normal()[0] = n0; - planes->Normal()[1] = n1; - planes->Normal()[2] = n2; - planes->FitThroughPoint( a->xyz ); - planes++; - } - -#endif -} - -/* -============ -idSIMD_SSE::DeriveTangents -============ -*/ -//#define REFINE_TANGENT_SQUAREROOT -#define FIX_DEGENERATE_TANGENT - -void VPCALL idSIMD_SSE::DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - int i; - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); - - assert( planes != NULL ); - assert( verts != NULL ); - assert( numVerts >= 0 ); - -#ifdef REFINE_TANGENT_SQUAREROOT - __asm { - movaps xmm6, SIMD_SP_rsqrt_c0 - movaps xmm7, SIMD_SP_rsqrt_c1 - } -#endif - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - for ( i = 0; i <= numIndexes - 12; i += 12 ) { - idDrawVert *a, *b, *c; - ALIGN16( unsigned long signBit[4] ); - ALIGN16( float d0[4] ); - ALIGN16( float d1[4] ); - ALIGN16( float d2[4] ); - ALIGN16( float d3[4] ); - ALIGN16( float d4[4] ); - ALIGN16( float d5[4] ); - ALIGN16( float d6[4] ); - ALIGN16( float d7[4] ); - ALIGN16( float d8[4] ); - ALIGN16( float d9[4] ); - ALIGN16( float n0[4] ); - ALIGN16( float n1[4] ); - ALIGN16( float n2[4] ); - ALIGN16( float t0[4] ); - ALIGN16( float t1[4] ); - ALIGN16( float t2[4] ); - ALIGN16( float t3[4] ); - ALIGN16( float t4[4] ); - ALIGN16( float t5[4] ); - - for ( int j = 0; j < 4; j++ ) { - - a = verts + indexes[i + j * 3 + 0]; - b = verts + indexes[i + j * 3 + 1]; - c = verts + indexes[i + j * 3 + 2]; - - d0[j] = b->xyz[0] - a->xyz[0]; - d1[j] = b->xyz[1] - a->xyz[1]; - d2[j] = b->xyz[2] - a->xyz[2]; - d3[j] = b->st[0] - a->st[0]; - d4[j] = b->st[1] - a->st[1]; - - d5[j] = c->xyz[0] - a->xyz[0]; - d6[j] = c->xyz[1] - a->xyz[1]; - d7[j] = c->xyz[2] - a->xyz[2]; - d8[j] = c->st[0] - a->st[0]; - d9[j] = c->st[1] - a->st[1]; - } - -#if 1 - - __asm { - // normal - movaps xmm0, d6 - mulps xmm0, d2 - movaps xmm1, d7 - mulps xmm1, d1 - subps xmm0, xmm1 - - movaps xmm1, d7 - mulps xmm1, d0 - movaps xmm2, d5 - mulps xmm2, d2 - subps xmm1, xmm2 - - movaps xmm2, d5 - mulps xmm2, d1 - movaps xmm3, d6 - mulps xmm3, d0 - subps xmm2, xmm3 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - mulps xmm0, xmm3 - movaps n0, xmm0 - mulps xmm1, xmm3 - movaps n1, xmm1 - mulps xmm2, xmm3 - movaps n2, xmm2 - - // area sign bit - movaps xmm0, d3 - mulps xmm0, d9 - movaps xmm1, d4 - mulps xmm1, d8 - subps xmm0, xmm1 - andps xmm0, SIMD_SP_signBitMask - movaps signBit, xmm0 - - // first tangent - movaps xmm0, d0 - mulps xmm0, d9 - movaps xmm1, d4 - mulps xmm1, d5 - subps xmm0, xmm1 - - movaps xmm1, d1 - mulps xmm1, d9 - movaps xmm2, d4 - mulps xmm2, d6 - subps xmm1, xmm2 - - movaps xmm2, d2 - mulps xmm2, d9 - movaps xmm3, d4 - mulps xmm3, d7 - subps xmm2, xmm3 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - xorps xmm3, signBit - - mulps xmm0, xmm3 - movaps t0, xmm0 - mulps xmm1, xmm3 - movaps t1, xmm1 - mulps xmm2, xmm3 - movaps t2, xmm2 - - // second tangent - movaps xmm0, d3 - mulps xmm0, d5 - movaps xmm1, d0 - mulps xmm1, d8 - subps xmm0, xmm1 - - movaps xmm1, d3 - mulps xmm1, d6 - movaps xmm2, d1 - mulps xmm2, d8 - subps xmm1, xmm2 - - movaps xmm2, d3 - mulps xmm2, d7 - movaps xmm3, d2 - mulps xmm3, d8 - subps xmm2, xmm3 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - xorps xmm3, signBit - - mulps xmm0, xmm3 - movaps t3, xmm0 - mulps xmm1, xmm3 - movaps t4, xmm1 - mulps xmm2, xmm3 - movaps t5, xmm2 - } - -#else - - ALIGN16( float tmp[4] ); - - // normal - n0[0] = d6[0] * d2[0]; - n0[1] = d6[1] * d2[1]; - n0[2] = d6[2] * d2[2]; - n0[3] = d6[3] * d2[3]; - - n0[0] -= d7[0] * d1[0]; - n0[1] -= d7[1] * d1[1]; - n0[2] -= d7[2] * d1[2]; - n0[3] -= d7[3] * d1[3]; - - n1[0] = d7[0] * d0[0]; - n1[1] = d7[1] * d0[1]; - n1[2] = d7[2] * d0[2]; - n1[3] = d7[3] * d0[3]; - - n1[0] -= d5[0] * d2[0]; - n1[1] -= d5[1] * d2[1]; - n1[2] -= d5[2] * d2[2]; - n1[3] -= d5[3] * d2[3]; - - n2[0] = d5[0] * d1[0]; - n2[1] = d5[1] * d1[1]; - n2[2] = d5[2] * d1[2]; - n2[3] = d5[3] * d1[3]; - - n2[0] -= d6[0] * d0[0]; - n2[1] -= d6[1] * d0[1]; - n2[2] -= d6[2] * d0[2]; - n2[3] -= d6[3] * d0[3]; - - tmp[0] = n0[0] * n0[0]; - tmp[1] = n0[1] * n0[1]; - tmp[2] = n0[2] * n0[2]; - tmp[3] = n0[3] * n0[3]; - - tmp[0] += n1[0] * n1[0]; - tmp[1] += n1[1] * n1[1]; - tmp[2] += n1[2] * n1[2]; - tmp[3] += n1[3] * n1[3]; - - tmp[0] += n2[0] * n2[0]; - tmp[1] += n2[1] * n2[1]; - tmp[2] += n2[2] * n2[2]; - tmp[3] += n2[3] * n2[3]; - - tmp[0] = idMath::RSqrt( tmp[0] ); - tmp[1] = idMath::RSqrt( tmp[1] ); - tmp[2] = idMath::RSqrt( tmp[2] ); - tmp[3] = idMath::RSqrt( tmp[3] ); - - n0[0] *= tmp[0]; - n0[1] *= tmp[1]; - n0[2] *= tmp[2]; - n0[3] *= tmp[3]; - - n1[0] *= tmp[0]; - n1[1] *= tmp[1]; - n1[2] *= tmp[2]; - n1[3] *= tmp[3]; - - n2[0] *= tmp[0]; - n2[1] *= tmp[1]; - n2[2] *= tmp[2]; - n2[3] *= tmp[3]; - - // area sign bit - tmp[0] = d3[0] * d9[0]; - tmp[1] = d3[1] * d9[1]; - tmp[2] = d3[2] * d9[2]; - tmp[3] = d3[3] * d9[3]; - - tmp[0] -= d4[0] * d8[0]; - tmp[1] -= d4[1] * d8[1]; - tmp[2] -= d4[2] * d8[2]; - tmp[3] -= d4[3] * d8[3]; - - signBit[0] = ( *(unsigned long *)&tmp[0] ) & ( 1 << 31 ); - signBit[1] = ( *(unsigned long *)&tmp[1] ) & ( 1 << 31 ); - signBit[2] = ( *(unsigned long *)&tmp[2] ) & ( 1 << 31 ); - signBit[3] = ( *(unsigned long *)&tmp[3] ) & ( 1 << 31 ); - - // first tangent - t0[0] = d0[0] * d9[0]; - t0[1] = d0[1] * d9[1]; - t0[2] = d0[2] * d9[2]; - t0[3] = d0[3] * d9[3]; - - t0[0] -= d4[0] * d5[0]; - t0[1] -= d4[1] * d5[1]; - t0[2] -= d4[2] * d5[2]; - t0[3] -= d4[3] * d5[3]; - - t1[0] = d1[0] * d9[0]; - t1[1] = d1[1] * d9[1]; - t1[2] = d1[2] * d9[2]; - t1[3] = d1[3] * d9[3]; - - t1[0] -= d4[0] * d6[0]; - t1[1] -= d4[1] * d6[1]; - t1[2] -= d4[2] * d6[2]; - t1[3] -= d4[3] * d6[3]; - - t2[0] = d2[0] * d9[0]; - t2[1] = d2[1] * d9[1]; - t2[2] = d2[2] * d9[2]; - t2[3] = d2[3] * d9[3]; - - t2[0] -= d4[0] * d7[0]; - t2[1] -= d4[1] * d7[1]; - t2[2] -= d4[2] * d7[2]; - t2[3] -= d4[3] * d7[3]; - - tmp[0] = t0[0] * t0[0]; - tmp[1] = t0[1] * t0[1]; - tmp[2] = t0[2] * t0[2]; - tmp[3] = t0[3] * t0[3]; - - tmp[0] += t1[0] * t1[0]; - tmp[1] += t1[1] * t1[1]; - tmp[2] += t1[2] * t1[2]; - tmp[3] += t1[3] * t1[3]; - - tmp[0] += t2[0] * t2[0]; - tmp[1] += t2[1] * t2[1]; - tmp[2] += t2[2] * t2[2]; - tmp[3] += t2[3] * t2[3]; - - tmp[0] = idMath::RSqrt( tmp[0] ); - tmp[1] = idMath::RSqrt( tmp[1] ); - tmp[2] = idMath::RSqrt( tmp[2] ); - tmp[3] = idMath::RSqrt( tmp[3] ); - - *(unsigned long *)&tmp[0] ^= signBit[0]; - *(unsigned long *)&tmp[1] ^= signBit[1]; - *(unsigned long *)&tmp[2] ^= signBit[2]; - *(unsigned long *)&tmp[3] ^= signBit[3]; - - t0[0] *= tmp[0]; - t0[1] *= tmp[1]; - t0[2] *= tmp[2]; - t0[3] *= tmp[3]; - - t1[0] *= tmp[0]; - t1[1] *= tmp[1]; - t1[2] *= tmp[2]; - t1[3] *= tmp[3]; - - t2[0] *= tmp[0]; - t2[1] *= tmp[1]; - t2[2] *= tmp[2]; - t2[3] *= tmp[3]; - - // second tangent - t3[0] = d3[0] * d5[0]; - t3[1] = d3[1] * d5[1]; - t3[2] = d3[2] * d5[2]; - t3[3] = d3[3] * d5[3]; - - t3[0] -= d0[0] * d8[0]; - t3[1] -= d0[1] * d8[1]; - t3[2] -= d0[2] * d8[2]; - t3[3] -= d0[3] * d8[3]; - - t4[0] = d3[0] * d6[0]; - t4[1] = d3[1] * d6[1]; - t4[2] = d3[2] * d6[2]; - t4[3] = d3[3] * d6[3]; - - t4[0] -= d1[0] * d8[0]; - t4[1] -= d1[1] * d8[1]; - t4[2] -= d1[2] * d8[2]; - t4[3] -= d1[3] * d8[3]; - - t5[0] = d3[0] * d7[0]; - t5[1] = d3[1] * d7[1]; - t5[2] = d3[2] * d7[2]; - t5[3] = d3[3] * d7[3]; - - t5[0] -= d2[0] * d8[0]; - t5[1] -= d2[1] * d8[1]; - t5[2] -= d2[2] * d8[2]; - t5[3] -= d2[3] * d8[3]; - - tmp[0] = t3[0] * t3[0]; - tmp[1] = t3[1] * t3[1]; - tmp[2] = t3[2] * t3[2]; - tmp[3] = t3[3] * t3[3]; - - tmp[0] += t4[0] * t4[0]; - tmp[1] += t4[1] * t4[1]; - tmp[2] += t4[2] * t4[2]; - tmp[3] += t4[3] * t4[3]; - - tmp[0] += t5[0] * t5[0]; - tmp[1] += t5[1] * t5[1]; - tmp[2] += t5[2] * t5[2]; - tmp[3] += t5[3] * t5[3]; - - tmp[0] = idMath::RSqrt( tmp[0] ); - tmp[1] = idMath::RSqrt( tmp[1] ); - tmp[2] = idMath::RSqrt( tmp[2] ); - tmp[3] = idMath::RSqrt( tmp[3] ); - - *(unsigned long *)&tmp[0] ^= signBit[0]; - *(unsigned long *)&tmp[1] ^= signBit[1]; - *(unsigned long *)&tmp[2] ^= signBit[2]; - *(unsigned long *)&tmp[3] ^= signBit[3]; - - t3[0] *= tmp[0]; - t3[1] *= tmp[1]; - t3[2] *= tmp[2]; - t3[3] *= tmp[3]; - - t4[0] *= tmp[0]; - t4[1] *= tmp[1]; - t4[2] *= tmp[2]; - t4[3] *= tmp[3]; - - t5[0] *= tmp[0]; - t5[1] *= tmp[1]; - t5[2] *= tmp[2]; - t5[3] *= tmp[3]; - -#endif - - for ( int j = 0; j < 4; j++ ) { - - const int v0 = indexes[i + j * 3 + 0]; - const int v1 = indexes[i + j * 3 + 1]; - const int v2 = indexes[i + j * 3 + 2]; - - a = verts + v0; - b = verts + v1; - c = verts + v2; - - planes->Normal()[0] = n0[j]; - planes->Normal()[1] = n1[j]; - planes->Normal()[2] = n2[j]; - planes->FitThroughPoint( a->xyz ); - planes++; - - if ( used[v0] ) { - a->normal[0] += n0[j]; - a->normal[1] += n1[j]; - a->normal[2] += n2[j]; - - a->tangents[0][0] += t0[j]; - a->tangents[0][1] += t1[j]; - a->tangents[0][2] += t2[j]; - - a->tangents[1][0] += t3[j]; - a->tangents[1][1] += t4[j]; - a->tangents[1][2] += t5[j]; - } else { - a->normal[0] = n0[j]; - a->normal[1] = n1[j]; - a->normal[2] = n2[j]; - - a->tangents[0][0] = t0[j]; - a->tangents[0][1] = t1[j]; - a->tangents[0][2] = t2[j]; - - a->tangents[1][0] = t3[j]; - a->tangents[1][1] = t4[j]; - a->tangents[1][2] = t5[j]; - - used[v0] = true; - } - - if ( used[v1] ) { - b->normal[0] += n0[j]; - b->normal[1] += n1[j]; - b->normal[2] += n2[j]; - - b->tangents[0][0] += t0[j]; - b->tangents[0][1] += t1[j]; - b->tangents[0][2] += t2[j]; - - b->tangents[1][0] += t3[j]; - b->tangents[1][1] += t4[j]; - b->tangents[1][2] += t5[j]; - } else { - b->normal[0] = n0[j]; - b->normal[1] = n1[j]; - b->normal[2] = n2[j]; - - b->tangents[0][0] = t0[j]; - b->tangents[0][1] = t1[j]; - b->tangents[0][2] = t2[j]; - - b->tangents[1][0] = t3[j]; - b->tangents[1][1] = t4[j]; - b->tangents[1][2] = t5[j]; - - used[v1] = true; - } - - if ( used[v2] ) { - c->normal[0] += n0[j]; - c->normal[1] += n1[j]; - c->normal[2] += n2[j]; - - c->tangents[0][0] += t0[j]; - c->tangents[0][1] += t1[j]; - c->tangents[0][2] += t2[j]; - - c->tangents[1][0] += t3[j]; - c->tangents[1][1] += t4[j]; - c->tangents[1][2] += t5[j]; - } else { - c->normal[0] = n0[j]; - c->normal[1] = n1[j]; - c->normal[2] = n2[j]; - - c->tangents[0][0] = t0[j]; - c->tangents[0][1] = t1[j]; - c->tangents[0][2] = t2[j]; - - c->tangents[1][0] = t3[j]; - c->tangents[1][1] = t4[j]; - c->tangents[1][2] = t5[j]; - - used[v2] = true; - } - } - } - - for ( ; i < numIndexes; i += 3 ) { - idDrawVert *a, *b, *c; - ALIGN16( unsigned long signBit[4] ); - float d0, d1, d2, d3, d4; - float d5, d6, d7, d8, d9; - float n0, n1, n2; - float t0, t1, t2; - float t3, t4, t5; - - const int v0 = indexes[i + 0]; - const int v1 = indexes[i + 1]; - const int v2 = indexes[i + 2]; - - a = verts + v0; - b = verts + v1; - c = verts + v2; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - d3 = b->st[0] - a->st[0]; - d4 = b->st[1] - a->st[1]; - - d5 = c->xyz[0] - a->xyz[0]; - d6 = c->xyz[1] - a->xyz[1]; - d7 = c->xyz[2] - a->xyz[2]; - d8 = c->st[0] - a->st[0]; - d9 = c->st[1] - a->st[1]; - -#if 1 - - __asm { - // normal - movss xmm0, d6 - mulss xmm0, d2 - movss xmm1, d7 - mulss xmm1, d1 - subss xmm0, xmm1 - - movss xmm1, d7 - mulss xmm1, d0 - movss xmm2, d5 - mulss xmm2, d2 - subss xmm1, xmm2 - - movss xmm2, d5 - mulss xmm2, d1 - movss xmm3, d6 - mulss xmm3, d0 - subss xmm2, xmm3 - - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - mulss xmm0, xmm3 - movss n0, xmm0 - mulss xmm1, xmm3 - movss n1, xmm1 - mulss xmm2, xmm3 - movss n2, xmm2 - - // area sign bit - movss xmm0, d3 - mulss xmm0, d9 - movss xmm1, d4 - mulss xmm1, d8 - subss xmm0, xmm1 - andps xmm0, SIMD_SP_signBitMask - movaps signBit, xmm0 - - // first tangent - movss xmm0, d0 - mulss xmm0, d9 - movss xmm1, d4 - mulss xmm1, d5 - subss xmm0, xmm1 - - movss xmm1, d1 - mulss xmm1, d9 - movss xmm2, d4 - mulss xmm2, d6 - subss xmm1, xmm2 - - movss xmm2, d2 - mulss xmm2, d9 - movss xmm3, d4 - mulss xmm3, d7 - subss xmm2, xmm3 - - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - xorps xmm3, signBit - - mulss xmm0, xmm3 - movss t0, xmm0 - mulss xmm1, xmm3 - movss t1, xmm1 - mulss xmm2, xmm3 - movss t2, xmm2 - - // second tangent - movss xmm0, d3 - mulss xmm0, d5 - movss xmm1, d0 - mulss xmm1, d8 - subss xmm0, xmm1 - - movss xmm1, d3 - mulss xmm1, d6 - movss xmm2, d1 - mulss xmm2, d8 - subss xmm1, xmm2 - - movss xmm2, d3 - mulss xmm2, d7 - movss xmm3, d2 - mulss xmm3, d8 - subss xmm2, xmm3 - - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef FIX_DEGENERATE_TANGENT - xorps xmm4, xmm4 - cmpeqps xmm4, xmm3 - andps xmm4, SIMD_SP_tiny // if values are zero replace them with a tiny number - andps xmm3, SIMD_SP_absMask // make sure the values are positive - orps xmm3, xmm4 -#endif - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - xorps xmm3, signBit - - mulss xmm0, xmm3 - movss t3, xmm0 - mulss xmm1, xmm3 - movss t4, xmm1 - mulss xmm2, xmm3 - movss t5, xmm2 - } - -#else - - float tmp; - - // normal - n0 = d6 * d2 - d7 * d1; - n1 = d7 * d0 - d5 * d2; - n2 = d5 * d1 - d6 * d0; - - tmp = idMath::RSqrt( n0 * n0 + n1 * n1 + n2 * n2 ); - - n0 *= tmp; - n1 *= tmp; - n2 *= tmp; - - // area sign bit - tmp = d3 * d9 - d4 * d8; - signBit[0] = ( *(unsigned long *)&tmp ) & ( 1 << 31 ); - - // first tangent - t0 = d0 * d9 - d4 * d5; - t1 = d1 * d9 - d4 * d6; - t2 = d2 * d9 - d4 * d7; - - tmp = idMath::RSqrt( t0 * t0 + t1 * t1 + t2 * t2 ); - *(unsigned long *)&tmp ^= signBit[0]; - - t0 *= tmp; - t1 *= tmp; - t2 *= tmp; - - // second tangent - t3 = d3 * d5 - d0 * d8; - t4 = d3 * d6 - d1 * d8; - t5 = d3 * d7 - d2 * d8; - - tmp = idMath::RSqrt( t3 * t3 + t4 * t4 + t5 * t5 ); - *(unsigned long *)&tmp ^= signBit[0]; - - t3 *= tmp; - t4 *= tmp; - t5 *= tmp; - -#endif - - planes->Normal()[0] = n0; - planes->Normal()[1] = n1; - planes->Normal()[2] = n2; - planes->FitThroughPoint( a->xyz ); - planes++; - - if ( used[v0] ) { - a->normal[0] += n0; - a->normal[1] += n1; - a->normal[2] += n2; - - a->tangents[0][0] += t0; - a->tangents[0][1] += t1; - a->tangents[0][2] += t2; - - a->tangents[1][0] += t3; - a->tangents[1][1] += t4; - a->tangents[1][2] += t5; - } else { - a->normal[0] = n0; - a->normal[1] = n1; - a->normal[2] = n2; - - a->tangents[0][0] = t0; - a->tangents[0][1] = t1; - a->tangents[0][2] = t2; - - a->tangents[1][0] = t3; - a->tangents[1][1] = t4; - a->tangents[1][2] = t5; - - used[v0] = true; - } - - if ( used[v1] ) { - b->normal[0] += n0; - b->normal[1] += n1; - b->normal[2] += n2; - - b->tangents[0][0] += t0; - b->tangents[0][1] += t1; - b->tangents[0][2] += t2; - - b->tangents[1][0] += t3; - b->tangents[1][1] += t4; - b->tangents[1][2] += t5; - } else { - b->normal[0] = n0; - b->normal[1] = n1; - b->normal[2] = n2; - - b->tangents[0][0] = t0; - b->tangents[0][1] = t1; - b->tangents[0][2] = t2; - - b->tangents[1][0] = t3; - b->tangents[1][1] = t4; - b->tangents[1][2] = t5; - - used[v1] = true; - } - - if ( used[v2] ) { - c->normal[0] += n0; - c->normal[1] += n1; - c->normal[2] += n2; - - c->tangents[0][0] += t0; - c->tangents[0][1] += t1; - c->tangents[0][2] += t2; - - c->tangents[1][0] += t3; - c->tangents[1][1] += t4; - c->tangents[1][2] += t5; - } else { - c->normal[0] = n0; - c->normal[1] = n1; - c->normal[2] = n2; - - c->tangents[0][0] = t0; - c->tangents[0][1] = t1; - c->tangents[0][2] = t2; - - c->tangents[1][0] = t3; - c->tangents[1][1] = t4; - c->tangents[1][2] = t5; - - used[v2] = true; - } - } -} - -/* -============ -idSIMD_SSE::DeriveUnsmoothedTangents -============ -*/ -#define DERIVE_UNSMOOTHED_BITANGENT - -void VPCALL idSIMD_SSE::DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ) { - int i, j; - - for ( i = 0; i <= numVerts - 4; i += 4 ) { - ALIGN16( float s0[4] ); - ALIGN16( float s1[4] ); - ALIGN16( float s2[4] ); - ALIGN16( float d0[4] ); - ALIGN16( float d1[4] ); - ALIGN16( float d2[4] ); - ALIGN16( float d3[4] ); - ALIGN16( float d4[4] ); - ALIGN16( float d5[4] ); - ALIGN16( float d6[4] ); - ALIGN16( float d7[4] ); - ALIGN16( float d8[4] ); - ALIGN16( float d9[4] ); - ALIGN16( float n0[4] ); - ALIGN16( float n1[4] ); - ALIGN16( float n2[4] ); - ALIGN16( float t0[4] ); - ALIGN16( float t1[4] ); - ALIGN16( float t2[4] ); - ALIGN16( float t3[4] ); - ALIGN16( float t4[4] ); - ALIGN16( float t5[4] ); - - for ( j = 0; j < 4; j++ ) { - const idDrawVert *a, *b, *c; - - const dominantTri_s &dt = dominantTris[i+j]; - - s0[j] = dt.normalizationScale[0]; - s1[j] = dt.normalizationScale[1]; - s2[j] = dt.normalizationScale[2]; - - a = verts + i + j; - b = verts + dt.v2; - c = verts + dt.v3; - - d0[j] = b->xyz[0] - a->xyz[0]; - d1[j] = b->xyz[1] - a->xyz[1]; - d2[j] = b->xyz[2] - a->xyz[2]; - d3[j] = b->st[0] - a->st[0]; - d4[j] = b->st[1] - a->st[1]; - - d5[j] = c->xyz[0] - a->xyz[0]; - d6[j] = c->xyz[1] - a->xyz[1]; - d7[j] = c->xyz[2] - a->xyz[2]; - d8[j] = c->st[0] - a->st[0]; - d9[j] = c->st[1] - a->st[1]; - } - -#if 1 - - __asm { - - movaps xmm0, d6 - mulps xmm0, d2 - movaps xmm1, d7 - mulps xmm1, d1 - - movaps xmm2, d7 - mulps xmm2, d0 - movaps xmm3, d5 - mulps xmm3, d2 - - movaps xmm4, d5 - mulps xmm4, d1 - movaps xmm5, d6 - mulps xmm5, d0 - - subps xmm0, xmm1 - subps xmm2, xmm3 - movaps xmm7, s2 - subps xmm4, xmm5 - - mulps xmm0, xmm7 - movaps n0, xmm0 - mulps xmm2, xmm7 - movaps n1, xmm2 - mulps xmm4, xmm7 - movaps n2, xmm4 - - movaps xmm0, d0 - mulps xmm0, d9 - movaps xmm1, d4 - mulps xmm1, d5 - - movaps xmm2, d1 - mulps xmm2, d9 - movaps xmm3, d4 - mulps xmm3, d6 - - movaps xmm4, d2 - mulps xmm4, d9 - movaps xmm5, d4 - mulps xmm5, d7 - - subps xmm0, xmm1 - subps xmm2, xmm3 - movaps xmm7, s0 - subps xmm4, xmm5 - - mulps xmm0, xmm7 - movaps t0, xmm0 - mulps xmm2, xmm7 - movaps t1, xmm2 - mulps xmm4, xmm7 - movaps t2, xmm4 - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - movaps xmm0, d3 - mulps xmm0, d5 - movaps xmm1, d0 - mulps xmm1, d8 - - movaps xmm2, d3 - mulps xmm2, d6 - movaps xmm3, d1 - mulps xmm3, d8 - - movaps xmm4, d3 - mulps xmm4, d7 - movaps xmm5, d2 - mulps xmm5, d8 -#else - movaps xmm0, n2 - mulps xmm0, t1 - movaps xmm1, n1 - mulps xmm1, t2 - - movaps xmm2, n0 - mulps xmm2, t2 - movaps xmm3, n2 - mulps xmm3, t0 - - movaps xmm4, n1 - mulps xmm4, t0 - movaps xmm5, n0 - mulps xmm5, t1 -#endif - subps xmm0, xmm1 - subps xmm2, xmm3 - movaps xmm7, s1 - subps xmm4, xmm5 - - mulps xmm0, xmm7 - movaps t3, xmm0 - mulps xmm2, xmm7 - movaps t4, xmm2 - mulps xmm4, xmm7 - movaps t5, xmm4 - } - -#else - - n0[0] = d6[0] * d2[0]; - n0[1] = d6[1] * d2[1]; - n0[2] = d6[2] * d2[2]; - n0[3] = d6[3] * d2[3]; - - n1[0] = d7[0] * d0[0]; - n1[1] = d7[1] * d0[1]; - n1[2] = d7[2] * d0[2]; - n1[3] = d7[3] * d0[3]; - - n2[0] = d5[0] * d1[0]; - n2[1] = d5[1] * d1[1]; - n2[2] = d5[2] * d1[2]; - n2[3] = d5[3] * d1[3]; - - n0[0] -= d7[0] * d1[0]; - n0[1] -= d7[1] * d1[1]; - n0[2] -= d7[2] * d1[2]; - n0[3] -= d7[3] * d1[3]; - - n1[0] -= d5[0] * d2[0]; - n1[1] -= d5[1] * d2[1]; - n1[2] -= d5[2] * d2[2]; - n1[3] -= d5[3] * d2[3]; - - n2[0] -= d6[0] * d0[0]; - n2[1] -= d6[1] * d0[1]; - n2[2] -= d6[2] * d0[2]; - n2[3] -= d6[3] * d0[3]; - - n0[0] *= s2[0]; - n0[1] *= s2[1]; - n0[2] *= s2[2]; - n0[3] *= s2[3]; - - n1[0] *= s2[0]; - n1[1] *= s2[1]; - n1[2] *= s2[2]; - n1[3] *= s2[3]; - - n2[0] *= s2[0]; - n2[1] *= s2[1]; - n2[2] *= s2[2]; - n2[3] *= s2[3]; - - t0[0] = d0[0] * d9[0]; - t0[1] = d0[1] * d9[1]; - t0[2] = d0[2] * d9[2]; - t0[3] = d0[3] * d9[3]; - - t1[0] = d1[0] * d9[0]; - t1[1] = d1[1] * d9[1]; - t1[2] = d1[2] * d9[2]; - t1[3] = d1[3] * d9[3]; - - t2[0] = d2[0] * d9[0]; - t2[1] = d2[1] * d9[1]; - t2[2] = d2[2] * d9[2]; - t2[3] = d2[3] * d9[3]; - - t0[0] -= d4[0] * d5[0]; - t0[1] -= d4[1] * d5[1]; - t0[2] -= d4[2] * d5[2]; - t0[3] -= d4[3] * d5[3]; - - t1[0] -= d4[0] * d6[0]; - t1[1] -= d4[1] * d6[1]; - t1[2] -= d4[2] * d6[2]; - t1[3] -= d4[3] * d6[3]; - - t2[0] -= d4[0] * d7[0]; - t2[1] -= d4[1] * d7[1]; - t2[2] -= d4[2] * d7[2]; - t2[3] -= d4[3] * d7[3]; - - t0[0] *= s0[0]; - t0[1] *= s0[1]; - t0[2] *= s0[2]; - t0[3] *= s0[3]; - - t1[0] *= s0[0]; - t1[1] *= s0[1]; - t1[2] *= s0[2]; - t1[3] *= s0[3]; - - t2[0] *= s0[0]; - t2[1] *= s0[1]; - t2[2] *= s0[2]; - t2[3] *= s0[3]; - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - t3[0] = d3[0] * d5[0]; - t3[1] = d3[1] * d5[1]; - t3[2] = d3[2] * d5[2]; - t3[3] = d3[3] * d5[3]; - - t4[0] = d3[0] * d6[0]; - t4[1] = d3[1] * d6[1]; - t4[2] = d3[2] * d6[2]; - t4[3] = d3[3] * d6[3]; - - t5[0] = d3[0] * d7[0]; - t5[1] = d3[1] * d7[1]; - t5[2] = d3[2] * d7[2]; - t5[3] = d3[3] * d7[3]; - - t3[0] -= d0[0] * d8[0]; - t3[1] -= d0[1] * d8[1]; - t3[2] -= d0[2] * d8[2]; - t3[3] -= d0[3] * d8[3]; - - t4[0] -= d1[0] * d8[0]; - t4[1] -= d1[1] * d8[1]; - t4[2] -= d1[2] * d8[2]; - t4[3] -= d1[3] * d8[3]; - - t5[0] -= d2[0] * d8[0]; - t5[1] -= d2[1] * d8[1]; - t5[2] -= d2[2] * d8[2]; - t5[3] -= d2[3] * d8[3]; -#else - t3[0] = n2[0] * t1[0]; - t3[1] = n2[1] * t1[1]; - t3[2] = n2[2] * t1[2]; - t3[3] = n2[3] * t1[3]; - - t4[0] = n0[0] * t2[0]; - t4[1] = n0[1] * t2[1]; - t4[2] = n0[2] * t2[2]; - t4[3] = n0[3] * t2[3]; - - t5[0] = n1[0] * t0[0]; - t5[1] = n1[1] * t0[1]; - t5[2] = n1[2] * t0[2]; - t5[3] = n1[3] * t0[3]; - - t3[0] -= n1[0] * t2[0]; - t3[1] -= n1[1] * t2[1]; - t3[2] -= n1[2] * t2[2]; - t3[3] -= n1[3] * t2[3]; - - t4[0] -= n2[0] * t0[0]; - t4[1] -= n2[1] * t0[1]; - t4[2] -= n2[2] * t0[2]; - t4[3] -= n2[3] * t0[3]; - - t5[0] -= n0[0] * t1[0]; - t5[1] -= n0[1] * t1[1]; - t5[2] -= n0[2] * t1[2]; - t5[3] -= n0[3] * t1[3]; -#endif - t3[0] *= s1[0]; - t3[1] *= s1[1]; - t3[2] *= s1[2]; - t3[3] *= s1[3]; - - t4[0] *= s1[0]; - t4[1] *= s1[1]; - t4[2] *= s1[2]; - t4[3] *= s1[3]; - - t5[0] *= s1[0]; - t5[1] *= s1[1]; - t5[2] *= s1[2]; - t5[3] *= s1[3]; - -#endif - - for ( j = 0; j < 4; j++ ) { - idDrawVert *a; - - a = verts + i + j; - - a->normal[0] = n0[j]; - a->normal[1] = n1[j]; - a->normal[2] = n2[j]; - - a->tangents[0][0] = t0[j]; - a->tangents[0][1] = t1[j]; - a->tangents[0][2] = t2[j]; - - a->tangents[1][0] = t3[j]; - a->tangents[1][1] = t4[j]; - a->tangents[1][2] = t5[j]; - } - } - - for ( ; i < numVerts; i++ ) { - idDrawVert *a, *b, *c; - float d0, d1, d2, d3, d4; - float d5, d6, d7, d8, d9; - float s0, s1, s2; - float n0, n1, n2; - float t0, t1, t2; - float t3, t4, t5; - - const dominantTri_s &dt = dominantTris[i]; - - s0 = dt.normalizationScale[0]; - s1 = dt.normalizationScale[1]; - s2 = dt.normalizationScale[2]; - - a = verts + i; - b = verts + dt.v2; - c = verts + dt.v3; - - d0 = b->xyz[0] - a->xyz[0]; - d1 = b->xyz[1] - a->xyz[1]; - d2 = b->xyz[2] - a->xyz[2]; - d3 = b->st[0] - a->st[0]; - d4 = b->st[1] - a->st[1]; - - d5 = c->xyz[0] - a->xyz[0]; - d6 = c->xyz[1] - a->xyz[1]; - d7 = c->xyz[2] - a->xyz[2]; - d8 = c->st[0] - a->st[0]; - d9 = c->st[1] - a->st[1]; - -#if 1 - - __asm { - - movss xmm0, d6 - mulss xmm0, d2 - movss xmm1, d7 - mulss xmm1, d1 - - movss xmm2, d7 - mulss xmm2, d0 - movss xmm3, d5 - mulss xmm3, d2 - - movss xmm4, d5 - mulss xmm4, d1 - movss xmm5, d6 - mulss xmm5, d0 - - subss xmm0, xmm1 - subss xmm2, xmm3 - movss xmm7, s2 - subss xmm4, xmm5 - - mulss xmm0, xmm7 - movss n0, xmm0 - mulss xmm2, xmm7 - movss n1, xmm2 - mulss xmm4, xmm7 - movss n2, xmm4 - - movss xmm0, d0 - mulss xmm0, d9 - movss xmm1, d4 - mulss xmm1, d5 - - movss xmm2, d1 - mulss xmm2, d9 - movss xmm3, d4 - mulss xmm3, d6 - - movss xmm4, d2 - mulss xmm4, d9 - movss xmm5, d4 - mulss xmm5, d7 - - subss xmm0, xmm1 - subss xmm2, xmm3 - movss xmm7, s0 - subss xmm4, xmm5 - - mulss xmm0, xmm7 - movss t0, xmm0 - mulss xmm2, xmm7 - movss t1, xmm2 - mulss xmm4, xmm7 - movss t2, xmm4 - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - movss xmm0, d3 - mulss xmm0, d5 - movss xmm1, d0 - mulss xmm1, d8 - - movss xmm2, d3 - mulss xmm2, d6 - movss xmm3, d1 - mulss xmm3, d8 - - movss xmm4, d3 - mulss xmm4, d7 - movss xmm5, d2 - mulss xmm5, d8 -#else - movss xmm0, n2 - mulss xmm0, t1 - movss xmm1, n1 - mulss xmm1, t2 - - movss xmm2, n0 - mulss xmm2, t2 - movss xmm3, n2 - mulss xmm3, t0 - - movss xmm4, n1 - mulss xmm4, t0 - movss xmm5, n0 - mulss xmm5, t1 -#endif - subss xmm0, xmm1 - subss xmm2, xmm3 - movss xmm7, s1 - subss xmm4, xmm5 - - mulss xmm0, xmm7 - movss t3, xmm0 - mulss xmm2, xmm7 - movss t4, xmm2 - mulss xmm4, xmm7 - movss t5, xmm4 - } - -#else - - n0 = s2 * ( d6 * d2 - d7 * d1 ); - n1 = s2 * ( d7 * d0 - d5 * d2 ); - n2 = s2 * ( d5 * d1 - d6 * d0 ); - - t0 = s0 * ( d0 * d9 - d4 * d5 ); - t1 = s0 * ( d1 * d9 - d4 * d6 ); - t2 = s0 * ( d2 * d9 - d4 * d7 ); - -#ifndef DERIVE_UNSMOOTHED_BITANGENT - t3 = s1 * ( d3 * d5 - d0 * d8 ); - t4 = s1 * ( d3 * d6 - d1 * d8 ); - t5 = s1 * ( d3 * d7 - d2 * d8 ); -#else - t3 = s1 * ( n2 * t1 - n1 * t2 ); - t4 = s1 * ( n0 * t2 - n2 * t0 ); - t5 = s1 * ( n1 * t0 - n0 * t1 ); -#endif - -#endif - - a->normal[0] = n0; - a->normal[1] = n1; - a->normal[2] = n2; - - a->tangents[0][0] = t0; - a->tangents[0][1] = t1; - a->tangents[0][2] = t2; - - a->tangents[1][0] = t3; - a->tangents[1][1] = t4; - a->tangents[1][2] = t5; - } -} - -/* -============ -idSIMD_SSE::NormalizeTangents -============ -*/ -void VPCALL idSIMD_SSE::NormalizeTangents( idDrawVert *verts, const int numVerts ) { - ALIGN16( float normal[12] ); - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); - - assert( verts != NULL ); - assert( numVerts >= 0 ); - - __asm { - mov eax, numVerts - test eax, eax - jz done -#ifdef REFINE_TANGENT_SQUAREROOT - movaps xmm6, SIMD_SP_rsqrt_c0 - movaps xmm7, SIMD_SP_rsqrt_c1 -#endif - mov esi, verts - imul eax, DRAWVERT_SIZE - add esi, eax - neg eax - add eax, DRAWVERT_SIZE*4 - jle loopVert4 - - sub eax, DRAWVERT_SIZE*4 - jl loopVert1 - - loopVert4: - - sub eax, DRAWVERT_SIZE*4 - - // normalize 4 idDrawVert::normal - - movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+0] // 0, X, X, X - movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+0] // 0, X, 3, 4 - movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+8] // 5, X, X, X - movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+4] // 5, X, 1, 2 - movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+0] // 6, X, X, X - movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+0] // 6, X, 9, 10 - movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+8] // 11, X, X, X - movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+4] // 11, X, 7, 8 - - movaps xmm1, xmm0 - movaps xmm5, xmm2 - shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 - shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 - shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 - shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - - mulps xmm0, xmm3 - mulps xmm1, xmm3 - mulps xmm2, xmm3 - - // save the 4 idDrawVert::normal to project the tangents - - movaps [normal+ 0], xmm0 - movaps [normal+16], xmm1 - movaps [normal+32], xmm2 - - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_NORMAL_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_NORMAL_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_NORMAL_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_NORMAL_OFFSET+8], xmm2 - - // project and normalize 4 idDrawVert::tangent[0] - - movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+0] // 0, X, X, X - movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+0] // 0, X, 3, 4 - movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+8] // 5, X, X, X - movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+4] // 5, X, 1, 2 - movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+0] // 6, X, X, X - movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+0] // 6, X, 9, 10 - movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+8] // 11, X, X, X - movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+4] // 11, X, 7, 8 - - movaps xmm1, xmm0 - movaps xmm5, xmm2 - shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 - shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 - shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 - shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, [normal+ 0] - mulps xmm4, [normal+16] - mulps xmm5, [normal+32] - addps xmm3, xmm4 - addps xmm3, xmm5 - - movaps xmm4, xmm3 - movaps xmm5, xmm3 - mulps xmm3, [normal+ 0] - mulps xmm4, [normal+16] - mulps xmm5, [normal+32] - subps xmm0, xmm3 - subps xmm1, xmm4 - subps xmm2, xmm5 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - - mulps xmm0, xmm3 - mulps xmm1, xmm3 - mulps xmm2, xmm3 - - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT0_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT0_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT0_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT0_OFFSET+8], xmm2 - - // project and normalize 4 idDrawVert::tangent[1] - - movss xmm0, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+0] // 0, X, X, X - movhps xmm0, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+0] // 0, X, 3, 4 - movss xmm2, [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+8] // 5, X, X, X - movhps xmm2, [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+4] // 5, X, 1, 2 - movss xmm4, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+0] // 6, X, X, X - movhps xmm4, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+0] // 6, X, 9, 10 - movss xmm3, [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+8] // 11, X, X, X - movhps xmm3, [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+4] // 11, X, 7, 8 - - movaps xmm1, xmm0 - movaps xmm5, xmm2 - shufps xmm0, xmm4, R_SHUFFLEPS( 0, 2, 0, 2 ) // 0, 3, 6, 9 - shufps xmm2, xmm3, R_SHUFFLEPS( 3, 0, 3, 0 ) // 2, 5, 8, 11 - shufps xmm1, xmm5, R_SHUFFLEPS( 3, 3, 2, 2 ) // 4, 4, 1, 1 - shufps xmm4, xmm3, R_SHUFFLEPS( 3, 3, 2, 2 ) // 10, 10, 7, 7 - shufps xmm1, xmm4, R_SHUFFLEPS( 2, 0, 2, 0 ) // 1, 4, 7, 10 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, [normal+ 0] - mulps xmm4, [normal+16] - mulps xmm5, [normal+32] - addps xmm3, xmm4 - addps xmm3, xmm5 - - movaps xmm4, xmm3 - movaps xmm5, xmm3 - mulps xmm3, [normal+ 0] - mulps xmm4, [normal+16] - mulps xmm5, [normal+32] - subps xmm0, xmm3 - subps xmm1, xmm4 - subps xmm2, xmm5 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - movaps xmm5, xmm2 - - mulps xmm3, xmm3 - mulps xmm4, xmm4 - mulps xmm5, xmm5 - addps xmm3, xmm4 - addps xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtps xmm4, xmm3 - mulps xmm3, xmm4 - mulps xmm3, xmm4 - subps xmm3, xmm6 - mulps xmm4, xmm7 - mulps xmm3, xmm4 -#else - rsqrtps xmm3, xmm3 -#endif - - mulps xmm0, xmm3 - mulps xmm1, xmm3 - mulps xmm2, xmm3 - - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*0+DRAWVERT_TANGENT1_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*1+DRAWVERT_TANGENT1_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*2+DRAWVERT_TANGENT1_OFFSET+8], xmm2 - - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 2, 3, 0 ) - shufps xmm2, xmm2, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_SIZE*3+DRAWVERT_TANGENT1_OFFSET+8], xmm2 - - add eax, DRAWVERT_SIZE*8 - - jle loopVert4 - - sub eax, DRAWVERT_SIZE*4 - jge done - - loopVert1: - - // normalize one idDrawVert::normal - - movss xmm0, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - - mulss xmm0, xmm3 - mulss xmm1, xmm3 - mulss xmm2, xmm3 - - movss [esi+eax+DRAWVERT_NORMAL_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_NORMAL_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_NORMAL_OFFSET+8], xmm2 - - // project and normalize one idDrawVert::tangent[0] - - movss xmm0, [esi+eax+DRAWVERT_TANGENT0_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_TANGENT0_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_TANGENT0_OFFSET+8] - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] - mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] - mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] - addss xmm3, xmm4 - addss xmm3, xmm5 - - movss xmm4, xmm3 - movss xmm5, xmm3 - mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] - mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] - mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] - subss xmm0, xmm3 - subss xmm1, xmm4 - subss xmm2, xmm5 - - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - - mulss xmm0, xmm3 - mulss xmm1, xmm3 - mulss xmm2, xmm3 - - movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_TANGENT0_OFFSET+8], xmm2 - - // project and normalize one idDrawVert::tangent[1] - - movss xmm0, [esi+eax+DRAWVERT_TANGENT1_OFFSET+0] - movss xmm1, [esi+eax+DRAWVERT_TANGENT1_OFFSET+4] - movss xmm2, [esi+eax+DRAWVERT_TANGENT1_OFFSET+8] - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] - mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] - mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] - addss xmm3, xmm4 - addss xmm3, xmm5 - - movss xmm4, xmm3 - movss xmm5, xmm3 - mulss xmm3, [esi+eax+DRAWVERT_NORMAL_OFFSET+0] - mulss xmm4, [esi+eax+DRAWVERT_NORMAL_OFFSET+4] - mulss xmm5, [esi+eax+DRAWVERT_NORMAL_OFFSET+8] - subss xmm0, xmm3 - subss xmm1, xmm4 - subss xmm2, xmm5 - - movss xmm3, xmm0 - movss xmm4, xmm1 - movss xmm5, xmm2 - - mulss xmm3, xmm3 - mulss xmm4, xmm4 - mulss xmm5, xmm5 - addss xmm3, xmm4 - addss xmm3, xmm5 - -#ifdef REFINE_TANGENT_SQUAREROOT - rsqrtss xmm4, xmm3 - mulss xmm3, xmm4 - mulss xmm3, xmm4 - subss xmm3, xmm6 - mulss xmm4, xmm7 - mulss xmm3, xmm4 -#else - rsqrtss xmm3, xmm3 -#endif - - mulss xmm0, xmm3 - mulss xmm1, xmm3 - mulss xmm2, xmm3 - - movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+0], xmm0 - movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+4], xmm1 - movss [esi+eax+DRAWVERT_TANGENT1_OFFSET+8], xmm2 - - add eax, DRAWVERT_SIZE - - jl loopVert1 - done: - } -} - -/* -============ -idSIMD_SSE::CreateTextureSpaceLightVectors -============ -*/ -void VPCALL idSIMD_SSE::CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - for ( int i = numIndexes - 1; i >= 0; i-- ) { - used[indexes[i]] = true; - } - -#if 0 - - __asm { - - mov eax, numVerts - - mov esi, used - add esi, eax - - mov edi, verts - sub edi, DRAWVERT_SIZE - - neg eax - dec eax - - mov ecx, lightOrigin - movss xmm7, [ecx+0] - movhps xmm7, [ecx+4] - - mov ecx, lightVectors - sub ecx, 3*4 - - loopVert: - inc eax - jge done - - add edi, DRAWVERT_SIZE - add ecx, 3*4 - - cmp byte ptr [esi+eax], 0 - je loopVert - - movaps xmm0, xmm7 - movss xmm1, [edi+DRAWVERT_XYZ_OFFSET+0] - movhps xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] - subps xmm0, xmm1 - - // 0, X, 1, 2 - // 3, X, 4, 5 - // 6, X, 7, 8 - - movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+0] - movhps xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+4] - mulps xmm2, xmm0 - - movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] - movhps xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+4] - mulps xmm3, xmm0 - - movaps xmm5, xmm2 // xmm5 = 0, X, 1, 2 - unpcklps xmm5, xmm3 // xmm5 = 0, 3, X, X - unpckhps xmm2, xmm3 // xmm2 = 1, 4, 2, 5 - - movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+0] - movhps xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] - mulps xmm4, xmm0 - - movlhps xmm5, xmm4 // xmm5 = 0, 3, 6, X - movhlps xmm4, xmm2 // xmm4 = 2, 5, 7, 8 - shufps xmm2, xmm4, R_SHUFFLEPS( 0, 1, 3, 2 ) // xmm2 = 2, 5, 8, 7 - - addps xmm5, xmm4 - addps xmm5, xmm2 - movlps [ecx+0], xmm5 - shufps xmm5, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) - movss [ecx+8], xmm5 - - jmp loopVert - - done: - } - -#elif 1 - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - idVec3 lightDir; - - lightDir[0] = lightOrigin[0] - v->xyz[0]; - lightDir[1] = lightOrigin[1] - v->xyz[1]; - lightDir[2] = lightOrigin[2] - v->xyz[2]; - - lightVectors[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; - lightVectors[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; - lightVectors[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; - } - -#elif 1 - - ALIGN16( int usedVertNums[4] ); - ALIGN16( float lightDir0[4] ); - ALIGN16( float lightDir1[4] ); - ALIGN16( float lightDir2[4] ); - ALIGN16( float normal0[4] ); - ALIGN16( float normal1[4] ); - ALIGN16( float normal2[4] ); - ALIGN16( float tangent0[4] ); - ALIGN16( float tangent1[4] ); - ALIGN16( float tangent2[4] ); - ALIGN16( float tangent3[4] ); - ALIGN16( float tangent4[4] ); - ALIGN16( float tangent5[4] ); - idVec3 localLightOrigin = lightOrigin; - - __asm { - - xor ecx, ecx - mov eax, numVerts - - mov esi, used - add esi, eax - - mov edi, verts - sub edi, DRAWVERT_SIZE - - neg eax - dec eax - - loopVert4: - inc eax - jge done4 - - add edi, DRAWVERT_SIZE - - cmp byte ptr [esi+eax], 0 - je loopVert4 - - mov usedVertNums[ecx*4], eax - - inc ecx - cmp ecx, 4 - - movss xmm0, localLightOrigin[0] - movss xmm1, localLightOrigin[4] - movss xmm2, localLightOrigin[8] - - subss xmm0, [edi+DRAWVERT_XYZ_OFFSET+0] - subss xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] - subss xmm2, [edi+DRAWVERT_XYZ_OFFSET+8] - - movss lightDir0[ecx*4-4], xmm0 - movss lightDir1[ecx*4-4], xmm1 - movss lightDir2[ecx*4-4], xmm2 - - movss xmm3, [edi+DRAWVERT_NORMAL_OFFSET+0] - movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] - movss xmm5, [edi+DRAWVERT_NORMAL_OFFSET+8] - - movss normal0[ecx*4-4], xmm3 - movss normal1[ecx*4-4], xmm4 - movss normal2[ecx*4-4], xmm5 - - movss xmm0, [edi+DRAWVERT_TANGENT0_OFFSET+0] - movss xmm1, [edi+DRAWVERT_TANGENT0_OFFSET+4] - movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+8] - - movss tangent0[ecx*4-4], xmm0 - movss tangent1[ecx*4-4], xmm1 - movss tangent2[ecx*4-4], xmm2 - - movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] - movss xmm4, [edi+DRAWVERT_TANGENT1_OFFSET+4] - movss xmm5, [edi+DRAWVERT_TANGENT1_OFFSET+8] - - movss tangent3[ecx*4-4], xmm3 - movss tangent4[ecx*4-4], xmm4 - movss tangent5[ecx*4-4], xmm5 - - jl loopVert4 - - movaps xmm0, lightDir0 - movaps xmm1, lightDir1 - movaps xmm2, lightDir2 - - movaps xmm3, tangent0 - mulps xmm3, xmm0 - movaps xmm4, tangent1 - mulps xmm4, xmm1 - movaps xmm5, tangent2 - mulps xmm5, xmm2 - - addps xmm3, xmm4 - addps xmm5, xmm3 - - movaps xmm3, tangent3 - mulps xmm3, xmm0 - movaps xmm4, tangent4 - mulps xmm4, xmm1 - movaps xmm6, tangent5 - mulps xmm6, xmm2 - - addps xmm3, xmm4 - addps xmm6, xmm3 - - mulps xmm0, normal0 - mulps xmm1, normal1 - mulps xmm2, normal2 - - addps xmm0, xmm1 - addps xmm0, xmm2 - - mov ecx, numVerts - imul ecx, 12 - mov edx, usedVertNums[0] - add ecx, lightVectors - imul edx, 12 - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[4] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - imul edx, 12 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[8] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - imul edx, 12 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[12] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - imul edx, 12 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - - xor ecx, ecx - jmp loopVert4 - - done4: - test ecx, ecx - jz done - xor eax, eax - mov edi, numVerts - imul edi, 12 - add edi, lightVectors - - loopVert1: - movss xmm0, lightDir0[eax*4] - movss xmm1, lightDir1[eax*4] - movss xmm2, lightDir2[eax*4] - - mov edx, usedVertNums[eax*4] - imul edx, 12 - - movss xmm3, tangent0[eax*4] - mulss xmm3, xmm0 - movss xmm4, tangent1[eax*4] - mulss xmm4, xmm1 - movss xmm5, tangent2[eax*4] - mulss xmm5, xmm2 - - addss xmm3, xmm4 - addss xmm5, xmm3 - movss [edi+edx+0], xmm5 - - movss xmm3, tangent3[eax*4] - mulss xmm3, xmm0 - movss xmm4, tangent4[eax*4] - mulss xmm4, xmm1 - movss xmm6, tangent5[eax*4] - mulss xmm6, xmm2 - - addss xmm3, xmm4 - addss xmm6, xmm3 - movss [edi+edx+4], xmm6 - - mulss xmm0, normal0[eax*4] - mulss xmm1, normal1[eax*4] - mulss xmm2, normal2[eax*4] - - addss xmm0, xmm1 - addss xmm0, xmm2 - movss [edi+edx+8], xmm0 - - inc eax - dec ecx - jg loopVert1 - - done: - } - -#else - - ALIGN16( float lightVectors0[4] ); - ALIGN16( float lightVectors1[4] ); - ALIGN16( float lightVectors2[4] ); - int numUsedVerts = 0; - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - - lightDir0[numUsedVerts] = lightOrigin[0] - v->xyz[0]; - lightDir1[numUsedVerts] = lightOrigin[1] - v->xyz[1]; - lightDir2[numUsedVerts] = lightOrigin[2] - v->xyz[2]; - - normal0[numUsedVerts] = v->normal[0]; - normal1[numUsedVerts] = v->normal[1]; - normal2[numUsedVerts] = v->normal[2]; - - tangent0[numUsedVerts] = v->tangents[0][0]; - tangent1[numUsedVerts] = v->tangents[0][1]; - tangent2[numUsedVerts] = v->tangents[0][2]; - - tangent3[numUsedVerts] = v->tangents[1][0]; - tangent4[numUsedVerts] = v->tangents[1][1]; - tangent5[numUsedVerts] = v->tangents[1][2]; - - usedVertNums[numUsedVerts++] = i; - if ( numUsedVerts < 4 ) { - continue; - } - - lightVectors0[0] = lightDir0[0] * tangent0[0]; - lightVectors0[1] = lightDir0[1] * tangent0[1]; - lightVectors0[2] = lightDir0[2] * tangent0[2]; - lightVectors0[3] = lightDir0[3] * tangent0[3]; - - lightVectors0[0] += lightDir1[0] * tangent1[0]; - lightVectors0[1] += lightDir1[1] * tangent1[1]; - lightVectors0[2] += lightDir1[2] * tangent1[2]; - lightVectors0[3] += lightDir1[3] * tangent1[3]; - - lightVectors0[0] += lightDir2[0] * tangent2[0]; - lightVectors0[1] += lightDir2[1] * tangent2[1]; - lightVectors0[2] += lightDir2[2] * tangent2[2]; - lightVectors0[3] += lightDir2[3] * tangent2[3]; - - lightVectors1[0] = lightDir0[0] * tangent3[0]; - lightVectors1[1] = lightDir0[1] * tangent3[1]; - lightVectors1[2] = lightDir0[2] * tangent3[2]; - lightVectors1[3] = lightDir0[3] * tangent3[3]; - - lightVectors1[0] += lightDir1[0] * tangent4[0]; - lightVectors1[1] += lightDir1[1] * tangent4[1]; - lightVectors1[2] += lightDir1[2] * tangent4[2]; - lightVectors1[3] += lightDir1[3] * tangent4[3]; - - lightVectors1[0] += lightDir2[0] * tangent5[0]; - lightVectors1[1] += lightDir2[1] * tangent5[1]; - lightVectors1[2] += lightDir2[2] * tangent5[2]; - lightVectors1[3] += lightDir2[3] * tangent5[3]; - - lightVectors2[0] = lightDir0[0] * normal0[0]; - lightVectors2[1] = lightDir0[1] * normal0[1]; - lightVectors2[2] = lightDir0[2] * normal0[2]; - lightVectors2[3] = lightDir0[3] * normal0[3]; - - lightVectors2[0] += lightDir1[0] * normal1[0]; - lightVectors2[1] += lightDir1[1] * normal1[1]; - lightVectors2[2] += lightDir1[2] * normal1[2]; - lightVectors2[3] += lightDir1[3] * normal1[3]; - - lightVectors2[0] += lightDir2[0] * normal2[0]; - lightVectors2[1] += lightDir2[1] * normal2[1]; - lightVectors2[2] += lightDir2[2] * normal2[2]; - lightVectors2[3] += lightDir2[3] * normal2[3]; - - - for ( int j = 0; j < 4; j++ ) { - int n = usedVertNums[j]; - - lightVectors[n][0] = lightVectors0[j]; - lightVectors[n][1] = lightVectors1[j]; - lightVectors[n][2] = lightVectors2[j]; - } - - numUsedVerts = 0; - } - - for ( int i = 0; i < numUsedVerts; i++ ) { - - lightVectors0[i] = lightDir0[i] * tangent0[i] + lightDir1[i] * tangent1[i] + lightDir2[i] * tangent2[i]; - lightVectors1[i] = lightDir0[i] * tangent3[i] + lightDir1[i] * tangent4[i] + lightDir2[i] * tangent5[i]; - lightVectors2[i] = lightDir0[i] * normal0[i] + lightDir1[i] * normal1[i] + lightDir2[i] * normal2[i]; - - int n = usedVertNums[i]; - lightVectors[n][0] = lightVectors0[i]; - lightVectors[n][1] = lightVectors1[i]; - lightVectors[n][2] = lightVectors2[i]; - } - -#endif -} - -/* -============ -idSIMD_SSE::CreateSpecularTextureCoords -============ -*/ -void VPCALL idSIMD_SSE::CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ) { - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - assert( (int)&((idDrawVert *)0)->normal == DRAWVERT_NORMAL_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[0] == DRAWVERT_TANGENT0_OFFSET ); - assert( (int)&((idDrawVert *)0)->tangents[1] == DRAWVERT_TANGENT1_OFFSET ); - - bool *used = (bool *)_alloca16( numVerts * sizeof( used[0] ) ); - memset( used, 0, numVerts * sizeof( used[0] ) ); - - for ( int i = numIndexes - 1; i >= 0; i-- ) { - used[indexes[i]] = true; - } - -#if 0 - - __asm { - - mov eax, numVerts - - mov esi, used - add esi, eax - - mov edi, verts - sub edi, DRAWVERT_SIZE - - neg eax - dec eax - - mov ecx, viewOrigin - movss xmm6, [ecx+0] - movhps xmm6, [ecx+4] - - mov ecx, lightOrigin - movss xmm7, [ecx+0] - movhps xmm7, [ecx+4] - - mov ecx, texCoords - sub ecx, 4*4 - - loopVert: - inc eax - jge done - - add edi, DRAWVERT_SIZE - add ecx, 4*4 - - cmp byte ptr [esi+eax], 0 - je loopVert - - movaps xmm0, xmm7 - movaps xmm1, xmm6 - movss xmm2, [edi+DRAWVERT_XYZ_OFFSET+0] - movhps xmm2, [edi+DRAWVERT_XYZ_OFFSET+4] - subps xmm0, xmm2 - subps xmm1, xmm2 - - movaps xmm3, xmm0 - movaps xmm4, xmm1 - mulps xmm3, xmm3 - mulps xmm4, xmm4 - - // 0, X, 1, 2 - // 3, X, 4, 5 - - movaps xmm5, xmm3 // xmm5 = 0, X, 1, 2 - unpcklps xmm5, xmm4 // xmm5 = 0, 3, X, X - unpckhps xmm3, xmm4 // xmm3 = 1, 4, 2, 5 - movhlps xmm4, xmm3 // xmm4 = 2, 5, 4, 5 - - addps xmm5, xmm3 - addps xmm5, xmm4 - shufps xmm5, xmm5, R_SHUFFLEPS( 0, 1, 0, 1 ) - rsqrtps xmm5, xmm5 - - movaps xmm4, xmm5 - shufps xmm4, xmm4, R_SHUFFLEPS( 0, 0, 0, 0 ) - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 1, 1, 1 ) - - mulps xmm0, xmm4 - mulps xmm1, xmm5 - addps xmm0, xmm1 - - movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+0] - movhps xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+4] - mulps xmm2, xmm0 - - movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] - movhps xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+4] - mulps xmm3, xmm0 - - movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+0] - movhps xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] - mulps xmm4, xmm0 - - movaps xmm5, xmm2 // xmm5 = 0, X, 1, 2 - unpcklps xmm5, xmm3 // xmm5 = 0, 3, X, X - unpckhps xmm2, xmm3 // xmm2 = 1, 4, 2, 5 - - movlhps xmm5, xmm4 // xmm5 = 0, 3, 6, X - movhlps xmm4, xmm2 // xmm4 = 2, 5, 7, 8 - shufps xmm2, xmm4, R_SHUFFLEPS( 0, 1, 3, 2 ) // xmm2 = 2, 5, 8, 7 - - movaps xmm3, SIMD_SP_one - - addps xmm5, xmm4 - addps xmm5, xmm2 - movaps [ecx+0], xmm5 - movss [ecx+12], xmm3 - - jmp loopVert - - done: - } - -#elif 0 - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - - idVec3 lightDir = lightOrigin - v->xyz; - idVec3 viewDir = viewOrigin - v->xyz; - - float ilength; - - ilength = idMath::RSqrt( lightDir[0] * lightDir[0] + lightDir[1] * lightDir[1] + lightDir[2] * lightDir[2] ); - lightDir[0] *= ilength; - lightDir[1] *= ilength; - lightDir[2] *= ilength; - - ilength = idMath::RSqrt( viewDir[0] * viewDir[0] + viewDir[1] * viewDir[1] + viewDir[2] * viewDir[2] ); - viewDir[0] *= ilength; - viewDir[1] *= ilength; - viewDir[2] *= ilength; - - lightDir += viewDir; - - texCoords[i][0] = lightDir[0] * v->tangents[0][0] + lightDir[1] * v->tangents[0][1] + lightDir[2] * v->tangents[0][2]; - texCoords[i][1] = lightDir[0] * v->tangents[1][0] + lightDir[1] * v->tangents[1][1] + lightDir[2] * v->tangents[1][2]; - texCoords[i][2] = lightDir[0] * v->normal[0] + lightDir[1] * v->normal[1] + lightDir[2] * v->normal[2]; - texCoords[i][3] = 1.0f; - } - - -#elif 1 - - ALIGN16( int usedVertNums[4] ); - ALIGN16( float lightDir0[4] ); - ALIGN16( float lightDir1[4] ); - ALIGN16( float lightDir2[4] ); - ALIGN16( float viewDir0[4] ); - ALIGN16( float viewDir1[4] ); - ALIGN16( float viewDir2[4] ); - ALIGN16( float normal0[4] ); - ALIGN16( float normal1[4] ); - ALIGN16( float normal2[4] ); - ALIGN16( float tangent0[4] ); - ALIGN16( float tangent1[4] ); - ALIGN16( float tangent2[4] ); - ALIGN16( float tangent3[4] ); - ALIGN16( float tangent4[4] ); - ALIGN16( float tangent5[4] ); - idVec3 localLightOrigin = lightOrigin; - idVec3 localViewOrigin = viewOrigin; - - __asm { - - xor ecx, ecx - mov eax, numVerts - - mov esi, used - add esi, eax - - mov edi, verts - sub edi, DRAWVERT_SIZE - - neg eax - dec eax - - loopVert4: - inc eax - jge done4 - - add edi, DRAWVERT_SIZE - - cmp byte ptr [esi+eax], 0 - je loopVert4 - - mov usedVertNums[ecx*4], eax - - inc ecx - cmp ecx, 4 - - movss xmm3, localLightOrigin[0] - movss xmm4, localLightOrigin[4] - movss xmm5, localLightOrigin[8] - - subss xmm3, [edi+DRAWVERT_XYZ_OFFSET+0] - subss xmm4, [edi+DRAWVERT_XYZ_OFFSET+4] - subss xmm5, [edi+DRAWVERT_XYZ_OFFSET+8] - - movss lightDir0[ecx*4-4], xmm3 - movss lightDir1[ecx*4-4], xmm4 - movss lightDir2[ecx*4-4], xmm5 - - movss xmm0, localViewOrigin[0] - movss xmm1, localViewOrigin[4] - movss xmm2, localViewOrigin[8] - - subss xmm0, [edi+DRAWVERT_XYZ_OFFSET+0] - subss xmm1, [edi+DRAWVERT_XYZ_OFFSET+4] - subss xmm2, [edi+DRAWVERT_XYZ_OFFSET+8] - - movss viewDir0[ecx*4-4], xmm0 - movss viewDir1[ecx*4-4], xmm1 - movss viewDir2[ecx*4-4], xmm2 - - movss xmm3, [edi+DRAWVERT_NORMAL_OFFSET+0] - movss xmm4, [edi+DRAWVERT_NORMAL_OFFSET+4] - movss xmm5, [edi+DRAWVERT_NORMAL_OFFSET+8] - - movss normal0[ecx*4-4], xmm3 - movss normal1[ecx*4-4], xmm4 - movss normal2[ecx*4-4], xmm5 - - movss xmm0, [edi+DRAWVERT_TANGENT0_OFFSET+0] - movss xmm1, [edi+DRAWVERT_TANGENT0_OFFSET+4] - movss xmm2, [edi+DRAWVERT_TANGENT0_OFFSET+8] - - movss tangent0[ecx*4-4], xmm0 - movss tangent1[ecx*4-4], xmm1 - movss tangent2[ecx*4-4], xmm2 - - movss xmm3, [edi+DRAWVERT_TANGENT1_OFFSET+0] - movss xmm4, [edi+DRAWVERT_TANGENT1_OFFSET+4] - movss xmm5, [edi+DRAWVERT_TANGENT1_OFFSET+8] - - movss tangent3[ecx*4-4], xmm3 - movss tangent4[ecx*4-4], xmm4 - movss tangent5[ecx*4-4], xmm5 - - jl loopVert4 - - movaps xmm6, lightDir0 - movaps xmm0, xmm6 - mulps xmm6, xmm6 - movaps xmm7, lightDir1 - movaps xmm1, xmm7 - mulps xmm7, xmm7 - addps xmm6, xmm7 - movaps xmm5, lightDir2 - movaps xmm2, xmm5 - mulps xmm5, xmm5 - addps xmm6, xmm5 - rsqrtps xmm6, xmm6 - - mulps xmm0, xmm6 - mulps xmm1, xmm6 - mulps xmm2, xmm6 - - movaps xmm3, viewDir0 - movaps xmm7, xmm3 - mulps xmm7, xmm7 - movaps xmm4, viewDir1 - movaps xmm6, xmm4 - mulps xmm6, xmm6 - addps xmm7, xmm6 - movaps xmm5, viewDir2 - movaps xmm6, xmm5 - mulps xmm6, xmm6 - addps xmm7, xmm6 - rsqrtps xmm7, xmm7 - - mulps xmm3, xmm7 - addps xmm0, xmm3 - mulps xmm4, xmm7 - addps xmm1, xmm4 - mulps xmm5, xmm7 - addps xmm2, xmm5 - - movaps xmm3, tangent0 - mulps xmm3, xmm0 - movaps xmm4, tangent1 - mulps xmm4, xmm1 - addps xmm3, xmm4 - movaps xmm5, tangent2 - mulps xmm5, xmm2 - addps xmm5, xmm3 - - movaps xmm3, tangent3 - mulps xmm3, xmm0 - movaps xmm4, tangent4 - mulps xmm4, xmm1 - addps xmm3, xmm4 - movaps xmm6, tangent5 - mulps xmm6, xmm2 - addps xmm6, xmm3 - - mulps xmm0, normal0 - mulps xmm1, normal1 - addps xmm0, xmm1 - mulps xmm2, normal2 - addps xmm0, xmm2 - - mov ecx, numVerts - shl ecx, 4 - mov edx, usedVertNums[0] - add ecx, texCoords - shl edx, 4 - movss xmm3, SIMD_SP_one - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - movss [ecx+edx+12], xmm3 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[4] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shl edx, 4 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - movss [ecx+edx+12], xmm3 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[8] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shl edx, 4 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - movss [ecx+edx+12], xmm3 - - shufps xmm5, xmm5, R_SHUFFLEPS( 1, 2, 3, 0 ) - mov edx, usedVertNums[12] - shufps xmm6, xmm6, R_SHUFFLEPS( 1, 2, 3, 0 ) - shl edx, 4 - shufps xmm0, xmm0, R_SHUFFLEPS( 1, 2, 3, 0 ) - - movss [ecx+edx+0], xmm5 - movss [ecx+edx+4], xmm6 - movss [ecx+edx+8], xmm0 - movss [ecx+edx+12], xmm3 - - xor ecx, ecx - jmp loopVert4 - - done4: - test ecx, ecx - jz done - xor eax, eax - mov edi, numVerts - shl edi, 4 - add edi, texCoords - - loopVert1: - movss xmm6, lightDir0[eax*4] - movss xmm0, xmm6 - mulss xmm6, xmm6 - movss xmm7, lightDir1[eax*4] - movss xmm1, xmm7 - mulss xmm7, xmm7 - addss xmm6, xmm7 - movss xmm5, lightDir2[eax*4] - movss xmm2, xmm5 - mulss xmm5, xmm5 - addss xmm6, xmm5 - rsqrtss xmm6, xmm6 - - mulss xmm0, xmm6 - mulss xmm1, xmm6 - mulss xmm2, xmm6 - - movss xmm3, viewDir0[eax*4] - movss xmm7, xmm3 - mulss xmm7, xmm7 - movss xmm4, viewDir1[eax*4] - movss xmm6, xmm4 - mulss xmm6, xmm6 - addss xmm7, xmm6 - movss xmm5, viewDir2[eax*4] - movss xmm6, xmm5 - mulss xmm6, xmm6 - addss xmm7, xmm6 - rsqrtss xmm7, xmm7 - - mulss xmm3, xmm7 - addss xmm0, xmm3 - mulss xmm4, xmm7 - addss xmm1, xmm4 - mulss xmm5, xmm7 - addss xmm2, xmm5 - - mov edx, usedVertNums[eax*4] - shl edx, 4 - - movss xmm3, tangent0[eax*4] - mulss xmm3, xmm0 - movss xmm4, tangent1[eax*4] - mulss xmm4, xmm1 - addss xmm3, xmm4 - movss xmm5, tangent2[eax*4] - mulss xmm5, xmm2 - addss xmm5, xmm3 - movss [edi+edx+0], xmm5 - - movss xmm3, tangent3[eax*4] - mulss xmm3, xmm0 - movss xmm4, tangent4[eax*4] - mulss xmm4, xmm1 - addss xmm3, xmm4 - movss xmm6, tangent5[eax*4] - mulss xmm6, xmm2 - addss xmm6, xmm3 - movss [edi+edx+4], xmm6 - - mulss xmm0, normal0[eax*4] - mulss xmm1, normal1[eax*4] - addss xmm0, xmm1 - mulss xmm2, normal2[eax*4] - addss xmm0, xmm2 - movss [edi+edx+8], xmm0 - - movss xmm3, SIMD_SP_one - movss [edi+edx+12], xmm3 - - inc eax - dec ecx - jg loopVert1 - - done: - } - -#else - - ALIGN16( int usedVertNums[4] ); - ALIGN16( float lightDir0[4] ); - ALIGN16( float lightDir1[4] ); - ALIGN16( float lightDir2[4] ); - ALIGN16( float viewDir0[4] ); - ALIGN16( float viewDir1[4] ); - ALIGN16( float viewDir2[4] ); - ALIGN16( float normal0[4] ); - ALIGN16( float normal1[4] ); - ALIGN16( float normal2[4] ); - ALIGN16( float tangent0[4] ); - ALIGN16( float tangent1[4] ); - ALIGN16( float tangent2[4] ); - ALIGN16( float tangent3[4] ); - ALIGN16( float tangent4[4] ); - ALIGN16( float tangent5[4] ); - ALIGN16( float texCoords0[4] ); - ALIGN16( float texCoords1[4] ); - ALIGN16( float texCoords2[4] ); - idVec3 localLightOrigin = lightOrigin; - idVec3 localViewOrigin = viewOrigin; - int numUsedVerts = 0; - - for ( int i = 0; i < numVerts; i++ ) { - if ( !used[i] ) { - continue; - } - - const idDrawVert *v = &verts[i]; - - lightDir0[numUsedVerts] = localLightOrigin[0] - v->xyz[0]; - lightDir1[numUsedVerts] = localLightOrigin[1] - v->xyz[1]; - lightDir2[numUsedVerts] = localLightOrigin[2] - v->xyz[2]; - - viewDir0[numUsedVerts] = localViewOrigin[0] - v->xyz[0]; - viewDir1[numUsedVerts] = localViewOrigin[1] - v->xyz[1]; - viewDir2[numUsedVerts] = localViewOrigin[2] - v->xyz[2]; - - normal0[numUsedVerts] = v->normal[0]; - normal1[numUsedVerts] = v->normal[1]; - normal2[numUsedVerts] = v->normal[2]; - - tangent0[numUsedVerts] = v->tangents[0][0]; - tangent1[numUsedVerts] = v->tangents[0][1]; - tangent2[numUsedVerts] = v->tangents[0][2]; - - tangent3[numUsedVerts] = v->tangents[1][0]; - tangent4[numUsedVerts] = v->tangents[1][1]; - tangent5[numUsedVerts] = v->tangents[1][2]; - - usedVertNums[numUsedVerts++] = i; - if ( numUsedVerts < 4 ) { - continue; - } - - ALIGN16( float temp[4] ); - - temp[0] = lightDir0[0] * lightDir0[0]; - temp[1] = lightDir0[1] * lightDir0[1]; - temp[2] = lightDir0[2] * lightDir0[2]; - temp[3] = lightDir0[3] * lightDir0[3]; - - temp[0] += lightDir1[0] * lightDir1[0]; - temp[1] += lightDir1[1] * lightDir1[1]; - temp[2] += lightDir1[2] * lightDir1[2]; - temp[3] += lightDir1[3] * lightDir1[3]; - - temp[0] += lightDir2[0] * lightDir2[0]; - temp[1] += lightDir2[1] * lightDir2[1]; - temp[2] += lightDir2[2] * lightDir2[2]; - temp[3] += lightDir2[3] * lightDir2[3]; - - temp[0] = idMath::RSqrt( temp[0] ); - temp[1] = idMath::RSqrt( temp[1] ); - temp[2] = idMath::RSqrt( temp[2] ); - temp[3] = idMath::RSqrt( temp[3] ); - - lightDir0[0] *= temp[0]; - lightDir0[1] *= temp[1]; - lightDir0[2] *= temp[2]; - lightDir0[3] *= temp[3]; - - lightDir1[0] *= temp[0]; - lightDir1[1] *= temp[1]; - lightDir1[2] *= temp[2]; - lightDir1[3] *= temp[3]; - - lightDir2[0] *= temp[0]; - lightDir2[1] *= temp[1]; - lightDir2[2] *= temp[2]; - lightDir2[3] *= temp[3]; - - temp[0] = viewDir0[0] * viewDir0[0]; - temp[1] = viewDir0[1] * viewDir0[1]; - temp[2] = viewDir0[2] * viewDir0[2]; - temp[3] = viewDir0[3] * viewDir0[3]; - - temp[0] += viewDir1[0] * viewDir1[0]; - temp[1] += viewDir1[1] * viewDir1[1]; - temp[2] += viewDir1[2] * viewDir1[2]; - temp[3] += viewDir1[3] * viewDir1[3]; - - temp[0] += viewDir2[0] * viewDir2[0]; - temp[1] += viewDir2[1] * viewDir2[1]; - temp[2] += viewDir2[2] * viewDir2[2]; - temp[3] += viewDir2[3] * viewDir2[3]; - - temp[0] = idMath::RSqrt( temp[0] ); - temp[1] = idMath::RSqrt( temp[1] ); - temp[2] = idMath::RSqrt( temp[2] ); - temp[3] = idMath::RSqrt( temp[3] ); - - viewDir0[0] *= temp[0]; - viewDir0[1] *= temp[1]; - viewDir0[2] *= temp[2]; - viewDir0[3] *= temp[3]; - - viewDir1[0] *= temp[0]; - viewDir1[1] *= temp[1]; - viewDir1[2] *= temp[2]; - viewDir1[3] *= temp[3]; - - viewDir2[0] *= temp[0]; - viewDir2[1] *= temp[1]; - viewDir2[2] *= temp[2]; - viewDir2[3] *= temp[3]; - - lightDir0[0] += viewDir0[0]; - lightDir0[1] += viewDir0[1]; - lightDir0[2] += viewDir0[2]; - lightDir0[3] += viewDir0[3]; - - lightDir1[0] += viewDir1[0]; - lightDir1[1] += viewDir1[1]; - lightDir1[2] += viewDir1[2]; - lightDir1[3] += viewDir1[3]; - - lightDir2[0] += viewDir2[0]; - lightDir2[1] += viewDir2[1]; - lightDir2[2] += viewDir2[2]; - lightDir2[3] += viewDir2[3]; - - texCoords0[0] = lightDir0[0] * tangent0[0]; - texCoords0[1] = lightDir0[1] * tangent0[1]; - texCoords0[2] = lightDir0[2] * tangent0[2]; - texCoords0[3] = lightDir0[3] * tangent0[3]; - - texCoords0[0] += lightDir1[0] * tangent1[0]; - texCoords0[1] += lightDir1[1] * tangent1[1]; - texCoords0[2] += lightDir1[2] * tangent1[2]; - texCoords0[3] += lightDir1[3] * tangent1[3]; - - texCoords0[0] += lightDir2[0] * tangent2[0]; - texCoords0[1] += lightDir2[1] * tangent2[1]; - texCoords0[2] += lightDir2[2] * tangent2[2]; - texCoords0[3] += lightDir2[3] * tangent2[3]; - - texCoords1[0] = lightDir0[0] * tangent3[0]; - texCoords1[1] = lightDir0[1] * tangent3[1]; - texCoords1[2] = lightDir0[2] * tangent3[2]; - texCoords1[3] = lightDir0[3] * tangent3[3]; - - texCoords1[0] += lightDir1[0] * tangent4[0]; - texCoords1[1] += lightDir1[1] * tangent4[1]; - texCoords1[2] += lightDir1[2] * tangent4[2]; - texCoords1[3] += lightDir1[3] * tangent4[3]; - - texCoords1[0] += lightDir2[0] * tangent5[0]; - texCoords1[1] += lightDir2[1] * tangent5[1]; - texCoords1[2] += lightDir2[2] * tangent5[2]; - texCoords1[3] += lightDir2[3] * tangent5[3]; - - texCoords2[0] = lightDir0[0] * normal0[0]; - texCoords2[1] = lightDir0[1] * normal0[1]; - texCoords2[2] = lightDir0[2] * normal0[2]; - texCoords2[3] = lightDir0[3] * normal0[3]; - - texCoords2[0] += lightDir1[0] * normal1[0]; - texCoords2[1] += lightDir1[1] * normal1[1]; - texCoords2[2] += lightDir1[2] * normal1[2]; - texCoords2[3] += lightDir1[3] * normal1[3]; - - texCoords2[0] += lightDir2[0] * normal2[0]; - texCoords2[1] += lightDir2[1] * normal2[1]; - texCoords2[2] += lightDir2[2] * normal2[2]; - texCoords2[3] += lightDir2[3] * normal2[3]; - - for ( int j = 0; j < 4; j++ ) { - int n = usedVertNums[j]; - - texCoords[n][0] = texCoords0[j]; - texCoords[n][1] = texCoords1[j]; - texCoords[n][2] = texCoords2[j]; - texCoords[n][3] = 1.0f; - } - - numUsedVerts = 0; - } - - for ( int i = 0; i < numUsedVerts; i++ ) { - float temp; - - temp = lightDir0[i] * lightDir0[i] + lightDir1[i] * lightDir1[i] + lightDir2[i] * lightDir2[i]; - temp = idMath::RSqrt( temp ); - - lightDir0[i] *= temp; - lightDir1[i] *= temp; - lightDir2[i] *= temp; - - temp = viewDir0[i] * viewDir0[i] + viewDir1[i] * viewDir1[i] + viewDir2[i] * viewDir2[i]; - temp = idMath::RSqrt( temp ); - - viewDir0[i] *= temp; - viewDir1[i] *= temp; - viewDir2[i] *= temp; - - lightDir0[i] += viewDir0[i]; - lightDir1[i] += viewDir1[i]; - lightDir2[i] += viewDir2[i]; - - texCoords0[i] = lightDir0[i] * tangent0[i] + lightDir1[i] * tangent1[i] + lightDir2[i] * tangent2[i]; - texCoords1[i] = lightDir0[i] * tangent3[i] + lightDir1[i] * tangent4[i] + lightDir2[i] * tangent5[i]; - texCoords2[i] = lightDir0[i] * normal0[i] + lightDir1[i] * normal1[i] + lightDir2[i] * normal2[i]; - - int n = usedVertNums[i]; - texCoords[n][0] = texCoords0; - texCoords[n][1] = texCoords1; - texCoords[n][2] = texCoords2; - texCoords[n][3] = 1.0f; - } - -#endif -} - -/* -============ -idSIMD_SSE::CreateShadowCache -============ -*/ -int VPCALL idSIMD_SSE::CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ) { -#if 1 - int outVerts; - - __asm { - push ebx - - mov esi, lightOrigin - movaps xmm5, SIMD_SP_lastOne - movss xmm6, [esi+0] - movhps xmm6, [esi+4] - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 2, 3, 1 ) - orps xmm6, SIMD_SP_lastOne - movaps xmm7, xmm6 - - xor ebx, ebx - xor ecx, ecx - - mov edx, vertRemap - mov esi, verts - mov edi, vertexCache - mov eax, numVerts - and eax, ~3 - jz done4 - shl eax, 2 - add edx, eax - neg eax - - loop4: - prefetchnta [edx+128] - prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] - - cmp dword ptr [edx+eax+0], ebx - jne skip1 - - mov dword ptr [edx+eax+0], ecx - movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - add ecx, 2 - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); - orps xmm0, xmm5 - movaps [edi+0*16], xmm0 - subps xmm0, xmm6 - movaps [edi+1*16], xmm0 - add edi, 2*16 - - skip1: - cmp dword ptr [edx+eax+4], ebx - jne skip2 - - mov dword ptr [edx+eax+4], ecx - movss xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - add ecx, 2 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 1 ) - orps xmm1, xmm5 - movaps [edi+0*16], xmm1 - subps xmm1, xmm7 - movaps [edi+1*16], xmm1 - add edi, 2*16 - - skip2: - cmp dword ptr [edx+eax+8], ebx - jne skip3 - - mov dword ptr [edx+eax+8], ecx - movss xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - add ecx, 2 - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ); - orps xmm2, xmm5 - movaps [edi+0*16], xmm2 - subps xmm2, xmm6 - movaps [edi+1*16], xmm2 - add edi, 2*16 - - skip3: - cmp dword ptr [edx+eax+12], ebx - jne skip4 - - mov dword ptr [edx+eax+12], ecx - movss xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - add ecx, 2 - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 3, 1 ) - orps xmm3, xmm5 - movaps [edi+0*16], xmm3 - subps xmm3, xmm7 - movaps [edi+1*16], xmm3 - add edi, 2*16 - - skip4: - add esi, 4*DRAWVERT_SIZE - add eax, 4*4 - jl loop4 - - done4: - mov eax, numVerts - and eax, 3 - jz done1 - shl eax, 2 - add edx, eax - neg eax - - loop1: - cmp dword ptr [edx+eax+0], ebx - jne skip0 - - mov dword ptr [edx+eax+0], ecx - movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - add ecx, 2 - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ) - orps xmm0, xmm5 - movaps [edi+0*16], xmm0 - subps xmm0, xmm6 - movaps [edi+1*16], xmm0 - add edi, 2*16 - - skip0: - - add esi, DRAWVERT_SIZE - add eax, 4 - jl loop1 - - done1: - pop ebx - mov outVerts, ecx - } - return outVerts; - -#else - - int outVerts = 0; - for ( int i = 0; i < numVerts; i++ ) { - if ( vertRemap[i] ) { - continue; - } - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[outVerts+0][0] = v[0]; - vertexCache[outVerts+0][1] = v[1]; - vertexCache[outVerts+0][2] = v[2]; - vertexCache[outVerts+0][3] = 1.0f; - - // R_SetupProjection() builds the projection matrix with a slight crunch - // for depth, which keeps this w=0 division from rasterizing right at the - // wrap around point and causing depth fighting with the rear caps - vertexCache[outVerts+1][0] = v[0] - lightOrigin[0]; - vertexCache[outVerts+1][1] = v[1] - lightOrigin[1]; - vertexCache[outVerts+1][2] = v[2] - lightOrigin[2]; - vertexCache[outVerts+1][3] = 0.0f; - vertRemap[i] = outVerts; - outVerts += 2; - } - return outVerts; - -#endif -} - -/* -============ -idSIMD_SSE::CreateVertexProgramShadowCache -============ -*/ -int VPCALL idSIMD_SSE::CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ) { -#if 1 - - __asm { - movaps xmm4, SIMD_SP_lastOne - movaps xmm5, xmm4 - movaps xmm6, xmm4 - movaps xmm7, xmm4 - - mov esi, verts - mov edi, vertexCache - mov eax, numVerts - and eax, ~3 - jz done4 - shl eax, 5 - add edi, eax - neg eax - - loop4: - prefetchnta [esi+4*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET] - - movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); - movaps [edi+eax+1*16], xmm0 - orps xmm0, xmm4 - movaps [edi+eax+0*16], xmm0 - - movss xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm1, [esi+1*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 2, 3, 1 ) - movaps [edi+eax+3*16], xmm1 - orps xmm1, xmm5 - movaps [edi+eax+2*16], xmm1 - - movss xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm2, [esi+2*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm2, xmm2, R_SHUFFLEPS( 2, 3, 0, 1 ); - movaps [edi+eax+5*16], xmm2 - orps xmm2, xmm6 - movaps [edi+eax+4*16], xmm2 - - movss xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - movhps xmm3, [esi+3*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+4] - shufps xmm3, xmm3, R_SHUFFLEPS( 0, 2, 3, 1 ) - movaps [edi+eax+7*16], xmm3 - orps xmm3, xmm7 - movaps [edi+eax+6*16], xmm3 - - add esi, 4*DRAWVERT_SIZE - add eax, 4*8*4 - jl loop4 - - done4: - mov eax, numVerts - and eax, 3 - jz done1 - shl eax, 5 - add edi, eax - neg eax - - loop1: - movss xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+8] - movhps xmm0, [esi+0*DRAWVERT_SIZE+DRAWVERT_XYZ_OFFSET+0] - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 3, 0, 1 ); - movaps [edi+eax+1*16], xmm0 - orps xmm0, xmm4 - movaps [edi+eax+0*16], xmm0 - - add esi, DRAWVERT_SIZE - add eax, 8*4 - jl loop1 - - done1: - } - return numVerts * 2; - -#else - - for ( int i = 0; i < numVerts; i++ ) { - const float *v = verts[i].xyz.ToFloatPtr(); - vertexCache[i*2+0][0] = v[0]; - vertexCache[i*2+0][1] = v[1]; - vertexCache[i*2+0][2] = v[2]; - vertexCache[i*2+0][3] = 1.0f; - - vertexCache[i*2+1][0] = v[0]; - vertexCache[i*2+1][1] = v[1]; - vertexCache[i*2+1][2] = v[2]; - vertexCache[i*2+1][3] = 0.0f; - } - return numVerts * 2; - -#endif -} - -/* -============ -SSE_UpSample11kHzMonoPCMTo44kHz -============ -*/ -static void SSE_UpSample11kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { - __asm { - mov esi, src - mov edi, dest - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 2*4*4 - - movsx ecx, word ptr [esi+eax+0] - cvtsi2ss xmm0, ecx - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi-2*4*4+0], xmm0 - movhps [edi-2*4*4+8], xmm0 - - movsx edx, word ptr [esi+eax+2] - cvtsi2ss xmm1, edx - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi-1*4*4+0], xmm1 - movhps [edi-1*4*4+8], xmm1 - - add eax, 2*2 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movsx ecx, word ptr [esi] - cvtsi2ss xmm0, ecx - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi+0], xmm0 - movhps [edi+8], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample11kHzStereoPCMTo44kHz -============ -*/ -static void SSE_UpSample11kHzStereoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { - __asm { - mov esi, src - mov edi, dest - - mov eax, numSamples - test eax, ~1 - jz done2 - shl eax, 1 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 8*4 - - movsx ecx, word ptr [esi+eax+0] - cvtsi2ss xmm0, ecx - - movsx edx, word ptr [esi+eax+2] - cvtsi2ss xmm1, edx - - unpcklps xmm0, xmm1 - - movlps [edi-8*4+0], xmm0 - movlps [edi-8*4+8], xmm0 - movlps [edi-4*4+0], xmm0 - movlps [edi-4*4+8], xmm0 - - add eax, 2*2 - jl loop2 - - done2: - } -} - -/* -============ -SSE_UpSample22kHzMonoPCMTo44kHz -============ -*/ -static void SSE_UpSample22kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { - __asm { - mov esi, src - mov edi, dest - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 4*4 - - movsx ecx, word ptr [esi+eax+0] - cvtsi2ss xmm0, ecx - - movsx edx, word ptr [esi+eax+2] - cvtsi2ss xmm1, edx - - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi-4*4+0], xmm0 - movhps [edi-4*4+8], xmm0 - - add eax, 2*2 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movsx ecx, word ptr [esi] - cvtsi2ss xmm0, ecx - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample22kHzStereoPCMTo44kHz -============ -*/ -static void SSE_UpSample22kHzStereoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { - __asm { - mov esi, src - mov edi, dest - - mov eax, numSamples - test eax, ~1 - jz done2 - shl eax, 1 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 4*4 - - movsx ecx, word ptr [esi+eax+0] - cvtsi2ss xmm0, ecx - movss [edi-4*4], xmm0 - movss [edi-2*4], xmm0 - - movsx edx, word ptr [esi+eax+2] - cvtsi2ss xmm1, edx - movss [edi-3*4], xmm1 - movss [edi-1*4], xmm1 - - add eax, 2*2 - jl loop2 - - done2: - } -} - -/* -============ -SSE_UpSample44kHzMonoPCMTo44kHz -============ -*/ -static void SSE_UpSample44kHzMonoPCMTo44kHz( float *dest, const short *src, const int numSamples ) { - __asm { - mov esi, src - mov edi, dest - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 2*4 - - movsx ecx, word ptr [esi+eax+0] - cvtsi2ss xmm0, ecx - movss [edi-2*4], xmm0 - - movsx edx, word ptr [esi+eax+2] - cvtsi2ss xmm1, edx - movss [edi-1*4], xmm1 - - add eax, 2*2 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movsx ecx, word ptr [esi] - cvtsi2ss xmm0, ecx - movss [edi], xmm0 - - done: - } -} - -/* -============ -idSIMD_SSE::UpSamplePCMTo44kHz - - Duplicate samples for 44kHz output. -============ -*/ -void idSIMD_SSE::UpSamplePCMTo44kHz( float *dest, const short *src, const int numSamples, const int kHz, const int numChannels ) { - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - SSE_UpSample11kHzMonoPCMTo44kHz( dest, src, numSamples ); - } else { - SSE_UpSample11kHzStereoPCMTo44kHz( dest, src, numSamples ); - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - SSE_UpSample22kHzMonoPCMTo44kHz( dest, src, numSamples ); - } else { - SSE_UpSample22kHzStereoPCMTo44kHz( dest, src, numSamples ); - } - } else if ( kHz == 44100 ) { - SSE_UpSample44kHzMonoPCMTo44kHz( dest, src, numSamples ); - } else { - assert( 0 ); - } -} - -/* -============ -SSE_UpSample11kHzMonoOGGTo44kHz -============ -*/ -static void SSE_UpSample11kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { - float constant = 32768.0f; - __asm { - mov esi, src - mov edi, dest - movss xmm7, constant - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 2 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 2*16 - - movss xmm0, [esi+eax+0] - mulss xmm0, xmm7 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi-32], xmm0 - movlps [edi-24], xmm0 - - movss xmm1, [esi+eax+4] - mulss xmm1, xmm7 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi-16], xmm1 - movlps [edi- 8], xmm1 - - add eax, 2*4 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movss xmm0, [esi] - mulss xmm0, xmm7 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi+0], xmm0 - movlps [edi+8], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample11kHzStereoOGGTo44kHz -============ -*/ -static void SSE_UpSample11kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { - float constant = 32768.0f; - __asm { - mov esi, src - mov ecx, [esi+0] - mov edx, [esi+4] - mov edi, dest - movss xmm7, constant - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add ecx, eax - add edx, eax - neg eax - - align 16 - loop2: - add edi, 4*16 - - movlps xmm0, [ecx+eax] - movlps xmm1, [edx+eax] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi-8*8], xmm0 - movlps [edi-7*8], xmm0 - movlps [edi-6*8], xmm0 - movlps [edi-5*8], xmm0 - movhps [edi-4*8], xmm0 - movhps [edi-3*8], xmm0 - movhps [edi-2*8], xmm0 - movhps [edi-1*8], xmm0 - - add eax, 2*4 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movss xmm0, [ecx] - movss xmm1, [edx] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi+0*8], xmm0 - movlps [edi+1*8], xmm0 - movlps [edi+2*8], xmm0 - movlps [edi+3*8], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample22kHzMonoOGGTo44kHz -============ -*/ -static void SSE_UpSample22kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { - float constant = 32768.0f; - __asm { - mov esi, src - mov edi, dest - movss xmm7, constant - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 2 - add esi, eax - neg eax - - align 16 - loop2: - add edi, 2*8 - - movss xmm0, [esi+eax+0] - movss xmm1, [esi+eax+4] - shufps xmm0, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm0, xmm7 - movlps [edi-16], xmm0 - movhps [edi- 8], xmm0 - - add eax, 2*4 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movss xmm0, [esi] - mulss xmm0, xmm7 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 0, 0 ) - movlps [edi+0], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample22kHzStereoOGGTo44kHz -============ -*/ -static void SSE_UpSample22kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { - float constant = 32768.0f; - __asm { - mov esi, src - mov ecx, [esi+0] - mov edx, [esi+4] - mov edi, dest - movss xmm7, constant - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add ecx, eax - add edx, eax - neg eax - - align 16 - loop2: - add edi, 2*16 - - movlps xmm0, [ecx+eax] - movlps xmm1, [edx+eax] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi-4*8], xmm0 - movlps [edi-3*8], xmm0 - movhps [edi-2*8], xmm0 - movhps [edi-1*8], xmm0 - - add eax, 2*4 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movss xmm0, [ecx] - movss xmm1, [edx] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi+0*8], xmm0 - movlps [edi+1*8], xmm0 - - done: - } -} - -/* -============ -SSE_UpSample44kHzMonoOGGTo44kHz -============ -*/ -static void SSE_UpSample44kHzMonoOGGTo44kHz( float *dest, const float *src, const int numSamples ) { - float constant = 32768.0f; - KFLOAT_CA( mul, dest, src, constant, numSamples ) -} - -/* -============ -SSE_UpSample44kHzStereoOGGTo44kHz -============ -*/ -static void SSE_UpSample44kHzStereoOGGTo44kHz( float *dest, const float * const *src, const int numSamples ) { - float constant = 32768.0f; - __asm { - mov esi, src - mov ecx, [esi+0] - mov edx, [esi+4] - mov edi, dest - movss xmm7, constant - shufps xmm7, xmm7, R_SHUFFLEPS( 0, 0, 0, 0 ) - - mov eax, numSamples - and eax, ~1 - jz done2 - shl eax, 1 - add ecx, eax - add edx, eax - neg eax - - align 16 - loop2: - add edi, 16 - - movlps xmm0, [ecx+eax] - movlps xmm1, [edx+eax] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi-2*8], xmm0 - movhps [edi-1*8], xmm0 - - add eax, 2*4 - jl loop2 - - done2: - mov eax, numSamples - and eax, 1 - jz done - - movss xmm0, [ecx] - movss xmm1, [edx] - unpcklps xmm0, xmm1 - mulps xmm0, xmm7 - movlps [edi+0*8], xmm0 - - done: - } -} - -/* -============ -idSIMD_SSE::UpSampleOGGTo44kHz - - Duplicate samples for 44kHz output. -============ -*/ -void idSIMD_SSE::UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ) { - if ( kHz == 11025 ) { - if ( numChannels == 1 ) { - SSE_UpSample11kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); - } else { - SSE_UpSample11kHzStereoOGGTo44kHz( dest, ogg, numSamples ); - } - } else if ( kHz == 22050 ) { - if ( numChannels == 1 ) { - SSE_UpSample22kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); - } else { - SSE_UpSample22kHzStereoOGGTo44kHz( dest, ogg, numSamples ); - } - } else if ( kHz == 44100 ) { - if ( numChannels == 1 ) { - SSE_UpSample44kHzMonoOGGTo44kHz( dest, ogg[0], numSamples ); - } else { - SSE_UpSample44kHzStereoOGGTo44kHz( dest, ogg, numSamples ); - } - } else { - assert( 0 ); - } -} - -/* -============ -idSIMD_SSE::MixSoundTwoSpeakerMono -============ -*/ -void VPCALL idSIMD_SSE::MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { -#if 1 - - ALIGN16( float incs[2] ); - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - __asm { - mov eax, MIXBUFFER_SAMPLES - mov edi, mixBuffer - mov esi, samples - shl eax, 2 - add esi, eax - neg eax - - mov ecx, lastV - movlps xmm6, [ecx] - xorps xmm7, xmm7 - movhps xmm7, incs - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - addps xmm6, xmm7 - shufps xmm7, xmm7, R_SHUFFLEPS( 2, 3, 2, 3 ) - addps xmm7, xmm7 - - loop16: - add edi, 4*4*4 - - movaps xmm0, [esi+eax+0*4*4] - movaps xmm1, xmm0 - shufps xmm0, xmm0, R_SHUFFLEPS( 0, 0, 1, 1 ) - mulps xmm0, xmm6 - addps xmm0, [edi-4*4*4] - addps xmm6, xmm7 - movaps [edi-4*4*4], xmm0 - - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 3, 3 ) - mulps xmm1, xmm6 - addps xmm1, [edi-3*4*4] - addps xmm6, xmm7 - movaps [edi-3*4*4], xmm1 - - movaps xmm2, [esi+eax+1*4*4] - movaps xmm3, xmm2 - shufps xmm2, xmm2, R_SHUFFLEPS( 0, 0, 1, 1 ) - mulps xmm2, xmm6 - addps xmm2, [edi-2*4*4] - addps xmm6, xmm7 - movaps [edi-2*4*4], xmm2 - - shufps xmm3, xmm3, R_SHUFFLEPS( 2, 2, 3, 3 ) - mulps xmm3, xmm6 - addps xmm3, [edi-1*4*4] - addps xmm6, xmm7 - movaps [edi-1*4*4], xmm3 - - add eax, 2*4*4 - - jl loop16 - } - -#else - - int i; - float incL; - float incR; - float sL0, sL1; - float sR0, sR1; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - sL0 = lastV[0]; - sR0 = lastV[1]; - sL1 = lastV[0] + incL; - sR1 = lastV[1] + incR; - - incL *= 2; - incR *= 2; - - for( i = 0; i < MIXBUFFER_SAMPLES; i += 2 ) { - mixBuffer[i*2+0] += samples[i+0] * sL0; - mixBuffer[i*2+1] += samples[i+0] * sR0; - mixBuffer[i*2+2] += samples[i+1] * sL1; - mixBuffer[i*2+3] += samples[i+1] * sR1; - sL0 += incL; - sR0 += incR; - sL1 += incL; - sR1 += incR; - } - -#endif -} - -/* -============ -idSIMD_SSE::MixSoundTwoSpeakerStereo -============ -*/ -void VPCALL idSIMD_SSE::MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ) { -#if 1 - - ALIGN16( float incs[2] ); - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - __asm { - mov eax, MIXBUFFER_SAMPLES - mov edi, mixBuffer - mov esi, samples - shl eax, 3 - add esi, eax - neg eax - - mov ecx, lastV - movlps xmm6, [ecx] - xorps xmm7, xmm7 - movhps xmm7, incs - shufps xmm6, xmm6, R_SHUFFLEPS( 0, 1, 0, 1 ) - addps xmm6, xmm7 - shufps xmm7, xmm7, R_SHUFFLEPS( 2, 3, 2, 3 ) - addps xmm7, xmm7 - - loop16: - add edi, 4*4*4 - - movaps xmm0, [esi+eax+0*4*4] - mulps xmm0, xmm6 - addps xmm0, [edi-4*4*4] - addps xmm6, xmm7 - movaps [edi-4*4*4], xmm0 - - movaps xmm2, [esi+eax+1*4*4] - mulps xmm2, xmm6 - addps xmm2, [edi-3*4*4] - addps xmm6, xmm7 - movaps [edi-3*4*4], xmm2 - - movaps xmm3, [esi+eax+2*4*4] - mulps xmm3, xmm6 - addps xmm3, [edi-2*4*4] - addps xmm6, xmm7 - movaps [edi-2*4*4], xmm3 - - movaps xmm4, [esi+eax+3*4*4] - mulps xmm4, xmm6 - addps xmm4, [edi-1*4*4] - addps xmm6, xmm7 - movaps [edi-1*4*4], xmm4 - - add eax, 4*4*4 - - jl loop16 - } - -#else - - int i; - float incL; - float incR; - float sL0, sL1; - float sR0, sR1; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incL = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incR = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - - sL0 = lastV[0]; - sR0 = lastV[1]; - sL1 = lastV[0] + incL; - sR1 = lastV[1] + incR; - - incL *= 2; - incR *= 2; - - for( i = 0; i < MIXBUFFER_SAMPLES; i += 2 ) { - mixBuffer[i*2+0] += samples[i*2+0] * sL0; - mixBuffer[i*2+1] += samples[i*2+1] * sR0; - mixBuffer[i*2+2] += samples[i*2+2] * sL1; - mixBuffer[i*2+3] += samples[i*2+3] * sR1; - sL0 += incL; - sR0 += incR; - sL1 += incL; - sR1 += incR; - } - -#endif -} - -/* -============ -idSIMD_SSE::MixSoundSixSpeakerMono -============ -*/ -void VPCALL idSIMD_SSE::MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { -#if 1 - - ALIGN16( float incs[6] ); - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incs[2] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incs[3] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incs[4] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incs[5] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - __asm { - mov eax, MIXBUFFER_SAMPLES - mov edi, mixBuffer - mov esi, samples - shl eax, 2 - add esi, eax - neg eax - - mov ecx, lastV - movlps xmm2, [ecx+ 0] - movhps xmm2, [ecx+ 8] - movlps xmm3, [ecx+16] - movaps xmm4, xmm2 - shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - shufps xmm4, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) - - xorps xmm5, xmm5 - movhps xmm5, incs - movlps xmm7, incs+8 - movhps xmm7, incs+16 - addps xmm3, xmm5 - addps xmm4, xmm7 - shufps xmm5, xmm7, R_SHUFFLEPS( 2, 3, 0, 1 ) - movaps xmm6, xmm7 - shufps xmm6, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) - addps xmm5, xmm5 - addps xmm6, xmm6 - addps xmm7, xmm7 - - loop24: - add edi, 6*16 - - movaps xmm0, [esi+eax] - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - mulps xmm1, xmm2 - addps xmm1, [edi-6*16] - addps xmm2, xmm5 - movaps [edi-6*16], xmm1 - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 1, 1 ) - mulps xmm1, xmm3 - addps xmm1, [edi-5*16] - addps xmm3, xmm6 - movaps [edi-5*16], xmm1 - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 1, 1, 1, 1 ) - mulps xmm1, xmm4 - addps xmm1, [edi-4*16] - addps xmm4, xmm7 - movaps [edi-4*16], xmm1 - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 2, 2 ) - mulps xmm1, xmm2 - addps xmm1, [edi-3*16] - addps xmm2, xmm5 - movaps [edi-3*16], xmm1 - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 2, 2, 3, 3 ) - mulps xmm1, xmm3 - addps xmm1, [edi-2*16] - addps xmm3, xmm6 - movaps [edi-2*16], xmm1 - - shufps xmm0, xmm0, R_SHUFFLEPS( 3, 3, 3, 3 ) - mulps xmm0, xmm4 - addps xmm0, [edi-1*16] - addps xmm4, xmm7 - movaps [edi-1*16], xmm0 - - add eax, 4*4 - - jl loop24 - } - -#else - - int i; - float sL0, sL1, sL2, sL3, sL4, sL5, sL6, sL7, sL8, sL9, sL10, sL11; - float incL0, incL1, incL2, incL3, incL4, incL5; - - assert( numSamples == MIXBUFFER_SAMPLES ); - - incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - sL0 = lastV[0]; - sL1 = lastV[1]; - sL2 = lastV[2]; - sL3 = lastV[3]; - sL4 = lastV[4]; - sL5 = lastV[5]; - - sL6 = lastV[0] + incL0; - sL7 = lastV[1] + incL1; - sL8 = lastV[2] + incL2; - sL9 = lastV[3] + incL3; - sL10 = lastV[4] + incL4; - sL11 = lastV[5] + incL5; - - incL0 *= 2; - incL1 *= 2; - incL2 *= 2; - incL3 *= 2; - incL4 *= 2; - incL5 *= 2; - - for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { - mixBuffer[i*6+ 0] += samples[i+0] * sL0; - mixBuffer[i*6+ 1] += samples[i+0] * sL1; - mixBuffer[i*6+ 2] += samples[i+0] * sL2; - mixBuffer[i*6+ 3] += samples[i+0] * sL3; - - mixBuffer[i*6+ 4] += samples[i+0] * sL4; - mixBuffer[i*6+ 5] += samples[i+0] * sL5; - mixBuffer[i*6+ 6] += samples[i+1] * sL6; - mixBuffer[i*6+ 7] += samples[i+1] * sL7; - - mixBuffer[i*6+ 8] += samples[i+1] * sL8; - mixBuffer[i*6+ 9] += samples[i+1] * sL9; - mixBuffer[i*6+10] += samples[i+1] * sL10; - mixBuffer[i*6+11] += samples[i+1] * sL11; - - sL0 += incL0; - sL1 += incL1; - sL2 += incL2; - sL3 += incL3; - - sL4 += incL4; - sL5 += incL5; - sL6 += incL0; - sL7 += incL1; - - sL8 += incL2; - sL9 += incL3; - sL10 += incL4; - sL11 += incL5; - } - -#endif -} - -/* -============ -idSIMD_SSE::MixSoundSixSpeakerStereo -============ -*/ -void VPCALL idSIMD_SSE::MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ) { -#if 1 - - ALIGN16( float incs[6] ); - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - incs[0] = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incs[1] = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incs[2] = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incs[3] = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incs[4] = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incs[5] = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - __asm { - mov eax, MIXBUFFER_SAMPLES - mov edi, mixBuffer - mov esi, samples - shl eax, 3 - add esi, eax - neg eax - - mov ecx, lastV - movlps xmm2, [ecx+ 0] - movhps xmm2, [ecx+ 8] - movlps xmm3, [ecx+16] - movaps xmm4, xmm2 - shufps xmm3, xmm2, R_SHUFFLEPS( 0, 1, 0, 1 ) - shufps xmm4, xmm3, R_SHUFFLEPS( 2, 3, 0, 1 ) - - xorps xmm5, xmm5 - movhps xmm5, incs - movlps xmm7, incs+ 8 - movhps xmm7, incs+16 - addps xmm3, xmm5 - addps xmm4, xmm7 - shufps xmm5, xmm7, R_SHUFFLEPS( 2, 3, 0, 1 ) - movaps xmm6, xmm7 - shufps xmm6, xmm5, R_SHUFFLEPS( 2, 3, 0, 1 ) - addps xmm5, xmm5 - addps xmm6, xmm6 - addps xmm7, xmm7 - - loop12: - add edi, 3*16 - - movaps xmm0, [esi+eax+0] - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 0, 0 ) - mulps xmm1, xmm2 - addps xmm1, [edi-3*16] - addps xmm2, xmm5 - movaps [edi-3*16], xmm1 - - movaps xmm1, xmm0 - shufps xmm1, xmm1, R_SHUFFLEPS( 0, 1, 2, 3 ) - mulps xmm1, xmm3 - addps xmm1, [edi-2*16] - addps xmm3, xmm6 - movaps [edi-2*16], xmm1 - - add eax, 4*4 - - shufps xmm0, xmm0, R_SHUFFLEPS( 2, 2, 2, 3 ) - mulps xmm0, xmm4 - addps xmm0, [edi-1*16] - addps xmm4, xmm7 - movaps [edi-1*16], xmm0 - - jl loop12 - - emms - } - -#else - - int i; - float sL0, sL1, sL2, sL3, sL4, sL5, sL6, sL7, sL8, sL9, sL10, sL11; - float incL0, incL1, incL2, incL3, incL4, incL5; - - assert( numSamples == MIXBUFFER_SAMPLES ); - assert( SPEAKER_RIGHT == 1 ); - assert( SPEAKER_BACKRIGHT == 5 ); - - incL0 = ( currentV[0] - lastV[0] ) / MIXBUFFER_SAMPLES; - incL1 = ( currentV[1] - lastV[1] ) / MIXBUFFER_SAMPLES; - incL2 = ( currentV[2] - lastV[2] ) / MIXBUFFER_SAMPLES; - incL3 = ( currentV[3] - lastV[3] ) / MIXBUFFER_SAMPLES; - incL4 = ( currentV[4] - lastV[4] ) / MIXBUFFER_SAMPLES; - incL5 = ( currentV[5] - lastV[5] ) / MIXBUFFER_SAMPLES; - - sL0 = lastV[0]; - sL1 = lastV[1]; - sL2 = lastV[2]; - sL3 = lastV[3]; - sL4 = lastV[4]; - sL5 = lastV[5]; - - sL6 = lastV[0] + incL0; - sL7 = lastV[1] + incL1; - sL8 = lastV[2] + incL2; - sL9 = lastV[3] + incL3; - sL10 = lastV[4] + incL4; - sL11 = lastV[5] + incL5; - - incL0 *= 2; - incL1 *= 2; - incL2 *= 2; - incL3 *= 2; - incL4 *= 2; - incL5 *= 2; - - for( i = 0; i <= MIXBUFFER_SAMPLES - 2; i += 2 ) { - mixBuffer[i*6+ 0] += samples[i*2+0+0] * sL0; - mixBuffer[i*6+ 1] += samples[i*2+0+1] * sL1; - mixBuffer[i*6+ 2] += samples[i*2+0+0] * sL2; - mixBuffer[i*6+ 3] += samples[i*2+0+0] * sL3; - - mixBuffer[i*6+ 4] += samples[i*2+0+0] * sL4; - mixBuffer[i*6+ 5] += samples[i*2+0+1] * sL5; - mixBuffer[i*6+ 6] += samples[i*2+2+0] * sL6; - mixBuffer[i*6+ 7] += samples[i*2+2+1] * sL7; - - mixBuffer[i*6+ 8] += samples[i*2+2+0] * sL8; - mixBuffer[i*6+ 9] += samples[i*2+2+0] * sL9; - mixBuffer[i*6+10] += samples[i*2+2+0] * sL10; - mixBuffer[i*6+11] += samples[i*2+2+1] * sL11; - - sL0 += incL0; - sL1 += incL1; - sL2 += incL2; - sL3 += incL3; - - sL4 += incL4; - sL5 += incL5; - sL6 += incL0; - sL7 += incL1; - - sL8 += incL2; - sL9 += incL3; - sL10 += incL4; - sL11 += incL5; - } - -#endif -} - -/* -============ -idSIMD_SSE::MixedSoundToSamples -============ -*/ -void VPCALL idSIMD_SSE::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { -#if 1 - - assert( ( numSamples % MIXBUFFER_SAMPLES ) == 0 ); - - __asm { - - mov eax, numSamples - mov edi, mixBuffer - mov esi, samples - shl eax, 2 - add edi, eax - neg eax - - loop16: - - movaps xmm0, [edi+eax+0*16] - movaps xmm2, [edi+eax+1*16] - movaps xmm4, [edi+eax+2*16] - movaps xmm6, [edi+eax+3*16] - - add esi, 4*4*2 - - movhlps xmm1, xmm0 - movhlps xmm3, xmm2 - movhlps xmm5, xmm4 - movhlps xmm7, xmm6 - - prefetchnta [edi+eax+64] - - cvtps2pi mm0, xmm0 - cvtps2pi mm2, xmm2 - cvtps2pi mm4, xmm4 - cvtps2pi mm6, xmm6 - - prefetchnta [edi+eax+128] - - cvtps2pi mm1, xmm1 - cvtps2pi mm3, xmm3 - cvtps2pi mm5, xmm5 - cvtps2pi mm7, xmm7 - - add eax, 4*16 - - packssdw mm0, mm1 - packssdw mm2, mm3 - packssdw mm4, mm5 - packssdw mm6, mm7 - - movq [esi-4*4*2], mm0 - movq [esi-3*4*2], mm2 - movq [esi-2*4*2], mm4 - movq [esi-1*4*2], mm6 - - jl loop16 - - emms - } - -#else - - for ( int i = 0; i < numSamples; i++ ) { - if ( mixBuffer[i] <= -32768.0f ) { - samples[i] = -32768; - } else if ( mixBuffer[i] >= 32767.0f ) { - samples[i] = 32767; - } else { - samples[i] = (short) mixBuffer[i]; - } - } - -#endif -} -#pragma warning( pop ) - -#endif /* _WIN32 */ diff --git a/idlib/math/simd_sse.h b/idlib/math/simd_sse.h deleted file mode 100644 index 4bf4a1127..000000000 --- a/idlib/math/simd_sse.h +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_SSE_H__ -#define __MATH_SIMD_SSE_H__ - -/* -=============================================================================== - - SSE implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_SSE : public idSIMD_MMX { -public: -#if defined(MACOS_X) && defined(__i386__) - virtual const char * VPCALL GetName( void ) const; - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); - -#elif defined(_WIN32) - virtual const char * VPCALL GetName( void ) const; - - virtual void VPCALL Add( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Add( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Sub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Sub( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Mul( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Mul( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL Div( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL Div( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulAdd( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulAdd( float *dst, const float *src0, const float *src1, const int count ); - virtual void VPCALL MulSub( float *dst, const float constant, const float *src, const int count ); - virtual void VPCALL MulSub( float *dst, const float *src0, const float *src1, const int count ); - - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 &constant, const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idVec3 *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idPlane *src, const int count ); - virtual void VPCALL Dot( float *dst, const idPlane &constant,const idDrawVert *src, const int count ); - virtual void VPCALL Dot( float *dst, const idVec3 *src0, const idVec3 *src1, const int count ); - virtual void VPCALL Dot( float &dot, const float *src1, const float *src2, const int count ); - - virtual void VPCALL CmpGT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpGE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const float *src0, const float constant, const int count ); - virtual void VPCALL CmpLE( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - - virtual void VPCALL MinMax( float &min, float &max, const float *src, const int count ); - virtual void VPCALL MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ); - virtual void VPCALL MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int *indexes, const int count ); - - virtual void VPCALL Clamp( float *dst, const float *src, const float min, const float max, const int count ); - virtual void VPCALL ClampMin( float *dst, const float *src, const float min, const int count ); - virtual void VPCALL ClampMax( float *dst, const float *src, const float max, const int count ); - - virtual void VPCALL Zero16( float *dst, const int count ); - virtual void VPCALL Negate16( float *dst, const int count ); - virtual void VPCALL Copy16( float *dst, const float *src, const int count ); - virtual void VPCALL Add16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Sub16( float *dst, const float *src1, const float *src2, const int count ); - virtual void VPCALL Mul16( float *dst, const float *src1, const float constant, const int count ); - virtual void VPCALL AddAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL SubAssign16( float *dst, const float *src, const int count ); - virtual void VPCALL MulAssign16( float *dst, const float constant, const int count ); - - virtual void VPCALL MatX_MultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplyVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplyAddVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_TransposeMultiplySubVecX( idVecX &dst, const idMatX &mat, const idVecX &vec ); - virtual void VPCALL MatX_MultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); - virtual void VPCALL MatX_TransposeMultiplyMatX( idMatX &dst, const idMatX &m1, const idMatX &m2 ); - virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); - virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); - virtual bool VPCALL MatX_LDLTFactor( idMatX &mat, idVecX &invDiag, const int n ); - - virtual void VPCALL BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ); - virtual void VPCALL ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ); - virtual void VPCALL ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ); - virtual void VPCALL TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ); - virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); - virtual void VPCALL TracePointCull( byte *cullBits, byte &totalOr, const float radius, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL DecalPointCull( byte *cullBits, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL OverlayPointCull( byte *cullBits, idVec2 *texCoords, const idPlane *planes, const idDrawVert *verts, const int numVerts ); - virtual void VPCALL DeriveTriPlanes( idPlane *planes, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveTangents( idPlane *planes, idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL DeriveUnsmoothedTangents( idDrawVert *verts, const dominantTri_s *dominantTris, const int numVerts ); - virtual void VPCALL NormalizeTangents( idDrawVert *verts, const int numVerts ); - virtual void VPCALL CreateTextureSpaceLightVectors( idVec3 *lightVectors, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual void VPCALL CreateSpecularTextureCoords( idVec4 *texCoords, const idVec3 &lightOrigin, const idVec3 &viewOrigin, const idDrawVert *verts, const int numVerts, const int *indexes, const int numIndexes ); - virtual int VPCALL CreateShadowCache( idVec4 *vertexCache, int *vertRemap, const idVec3 &lightOrigin, const idDrawVert *verts, const int numVerts ); - virtual int VPCALL CreateVertexProgramShadowCache( idVec4 *vertexCache, const idDrawVert *verts, const int numVerts ); - - virtual void VPCALL UpSamplePCMTo44kHz( float *dest, const short *pcm, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL UpSampleOGGTo44kHz( float *dest, const float * const *ogg, const int numSamples, const int kHz, const int numChannels ); - virtual void VPCALL MixSoundTwoSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundTwoSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[2], const float currentV[2] ); - virtual void VPCALL MixSoundSixSpeakerMono( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixSoundSixSpeakerStereo( float *mixBuffer, const float *samples, const int numSamples, const float lastV[6], const float currentV[6] ); - virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); - -#endif -}; - -#endif /* !__MATH_SIMD_SSE_H__ */ diff --git a/idlib/math/simd_sse2.cpp b/idlib/math/simd_sse2.cpp deleted file mode 100644 index 137804516..000000000 --- a/idlib/math/simd_sse2.cpp +++ /dev/null @@ -1,863 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "simd_generic.h" -#include "simd_mmx.h" -#include "simd_sse.h" -#include "simd_sse2.h" - - -//=============================================================== -// -// SSE2 implementation of idSIMDProcessor -// -//=============================================================== -#if defined(MACOS_X) && defined(__i386__) - -#include - -#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) -#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) - -/* -============ -idSIMD_SSE2::GetName -============ -*/ -const char * idSIMD_SSE2::GetName( void ) const { - return "MMX & SSE & SSE2"; -} - -/* -============ -idSIMD_SSE::CmpLT - - dst[i] |= ( src0[i] < constant ) << bitNum; -============ -*/ -void VPCALL idSIMD_SSE2::CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ) { - int i, cnt, pre, post; - float *aligned; - __m128 xmm0, xmm1; - __m128i xmm0i; - int cnt_l; - char *src0_p; - char *constant_p; - char *dst_p; - int mask_l; - int dst_l; - - /* if the float array is not aligned on a 4 byte boundary */ - if ( ((int) src0) & 3 ) { - /* unaligned memory access */ - pre = 0; - cnt = count >> 2; - post = count - (cnt<<2); - - /* - __asm mov edx, cnt - __asm test edx, edx - __asm je doneCmp - */ - cnt_l = cnt; - if(cnt_l != 0) { - /* - __asm push ebx - __asm neg edx - __asm mov esi, src0 - __asm prefetchnta [esi+64] - __asm movss xmm1, constant - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - __asm mov edi, dst - __asm mov cl, bitNum - */ - cnt_l = -cnt_l; - src0_p = (char *) src0; - _mm_prefetch(src0_p+64, _MM_HINT_NTA); - constant_p = (char *) &constant; - xmm1 = _mm_load_ss((float *)constant_p); - xmm1 = _mm_shuffle_ps(xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 )); - dst_p = (char *)dst; - /* - __asm loopNA: - */ - do { - /* - __asm movups xmm0, [esi] - __asm prefetchnta [esi+128] - __asm cmpltps xmm0, xmm1 - __asm movmskps eax, xmm0 \ - __asm mov ah, al - __asm shr ah, 1 - __asm mov bx, ax - __asm shl ebx, 14 - __asm mov bx, ax - __asm and ebx, 0x01010101 - __asm shl ebx, cl - __asm or ebx, dword ptr [edi] - __asm mov dword ptr [edi], ebx - __asm add esi, 16 - __asm add edi, 4 - __asm inc edx - __asm jl loopNA - __asm pop ebx - */ - xmm0 = _mm_loadu_ps((float *) src0_p); - _mm_prefetch(src0_p+128, _MM_HINT_NTA); - xmm0 = _mm_cmplt_ps(xmm0, xmm1); - // Simplify using SSE2 - xmm0i = (__m128i) xmm0; - xmm0i = _mm_packs_epi32(xmm0i, xmm0i); - xmm0i = _mm_packs_epi16(xmm0i, xmm0i); - mask_l = _mm_cvtsi128_si32(xmm0i); - // End - mask_l = mask_l & 0x01010101; - mask_l = mask_l << bitNum; - dst_l = *((int *) dst_p); - mask_l = mask_l | dst_l; - *((int *) dst_p) = mask_l; - src0_p = src0_p + 16; - dst_p = dst_p + 4; - cnt_l = cnt_l + 1; - } while (cnt_l < 0); - } - } - else { - /* aligned memory access */ - aligned = (float *) ((((int) src0) + 15) & ~15); - if ( (int)aligned > ((int)src0) + count ) { - pre = count; - post = 0; - } - else { - pre = aligned - src0; - cnt = (count - pre) >> 2; - post = count - pre - (cnt<<2); - /* - __asm mov edx, cnt - __asm test edx, edx - __asm je doneCmp - */ - cnt_l = cnt; - if(cnt_l != 0) { - /* - __asm push ebx - __asm neg edx - __asm mov esi, aligned - __asm prefetchnta [esi+64] - __asm movss xmm1, constant - __asm shufps xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 ) - __asm mov edi, dst - __asm add edi, pre - __asm mov cl, bitNum - */ - cnt_l = -cnt_l; - src0_p = (char *) src0; - _mm_prefetch(src0_p+64, _MM_HINT_NTA); - constant_p = (char *) &constant; - xmm1 = _mm_load_ss((float *)constant_p); - xmm1 = _mm_shuffle_ps(xmm1, xmm1, R_SHUFFLEPS( 0, 0, 0, 0 )); - dst_p = (char *)dst; - dst_p = dst_p + pre; - /* - __asm loopA: - */ - do { - /* - __asm movaps xmm0, [esi] - __asm prefetchnta [esi+128] - __asm cmpltps xmm0, xmm1 - __asm movmskps eax, xmm0 \ - __asm mov ah, al - __asm shr ah, 1 - __asm mov bx, ax - __asm shl ebx, 14 - __asm mov bx, ax - __asm and ebx, 0x01010101 - __asm shl ebx, cl - __asm or ebx, dword ptr [edi] - __asm mov dword ptr [edi], ebx - __asm add esi, 16 - __asm add edi, 4 - __asm inc edx - __asm jl loopA - __asm pop ebx - */ - xmm0 = _mm_load_ps((float *) src0_p); - _mm_prefetch(src0_p+128, _MM_HINT_NTA); - xmm0 = _mm_cmplt_ps(xmm0, xmm1); - // Simplify using SSE2 - xmm0i = (__m128i) xmm0; - xmm0i = _mm_packs_epi32(xmm0i, xmm0i); - xmm0i = _mm_packs_epi16(xmm0i, xmm0i); - mask_l = _mm_cvtsi128_si32(xmm0i); - // End - mask_l = mask_l & 0x01010101; - mask_l = mask_l << bitNum; - dst_l = *((int *) dst_p); - mask_l = mask_l | dst_l; - *((int *) dst_p) = mask_l; - src0_p = src0_p + 16; - dst_p = dst_p + 4; - cnt_l = cnt_l + 1; - } while (cnt_l < 0); - } - } - } - /* - doneCmp: - */ - float c = constant; - for ( i = 0; i < pre; i++ ) { - dst[i] |= ( src0[i] < c ) << bitNum; - } - for ( i = count - post; i < count; i++ ) { - dst[i] |= ( src0[i] < c ) << bitNum; - } -} - -#elif defined(_WIN32) - -#include - -#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) -#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) -#define SHUFFLEPD( x, y ) (( (x) & 1 ) << 1 | ( (y) & 1 )) -#define R_SHUFFLEPD( x, y ) (( (y) & 1 ) << 1 | ( (x) & 1 )) - - -#define ALIGN4_INIT1( X, INIT ) ALIGN16( static X[4] ) = { INIT, INIT, INIT, INIT } -#define ALIGN4_INIT4( X, I0, I1, I2, I3 ) ALIGN16( static X[4] ) = { I0, I1, I2, I3 } -#define ALIGN8_INIT1( X, INIT ) ALIGN16( static X[8] ) = { INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT } - -ALIGN8_INIT1( unsigned short SIMD_W_zero, 0 ); -ALIGN8_INIT1( unsigned short SIMD_W_maxShort, 1<<15 ); - -ALIGN4_INIT4( unsigned long SIMD_SP_singleSignBitMask, (unsigned long) ( 1 << 31 ), 0, 0, 0 ); -ALIGN4_INIT1( unsigned long SIMD_SP_signBitMask, (unsigned long) ( 1 << 31 ) ); -ALIGN4_INIT1( unsigned long SIMD_SP_absMask, (unsigned long) ~( 1 << 31 ) ); -ALIGN4_INIT1( unsigned long SIMD_SP_infinityMask, (unsigned long) ~( 1 << 23 ) ); - -ALIGN4_INIT1( float SIMD_SP_zero, 0.0f ); -ALIGN4_INIT1( float SIMD_SP_one, 1.0f ); -ALIGN4_INIT1( float SIMD_SP_two, 2.0f ); -ALIGN4_INIT1( float SIMD_SP_three, 3.0f ); -ALIGN4_INIT1( float SIMD_SP_four, 4.0f ); -ALIGN4_INIT1( float SIMD_SP_maxShort, (1<<15) ); -ALIGN4_INIT1( float SIMD_SP_tiny, 1e-10f ); -ALIGN4_INIT1( float SIMD_SP_PI, idMath::PI ); -ALIGN4_INIT1( float SIMD_SP_halfPI, idMath::HALF_PI ); -ALIGN4_INIT1( float SIMD_SP_twoPI, idMath::TWO_PI ); -ALIGN4_INIT1( float SIMD_SP_oneOverTwoPI, 1.0f / idMath::TWO_PI ); -ALIGN4_INIT1( float SIMD_SP_infinity, idMath::INFINITY ); - - -/* -============ -idSIMD_SSE2::GetName -============ -*/ -const char * idSIMD_SSE2::GetName( void ) const { - return "MMX & SSE & SSE2"; -} - -#if 0 // the SSE2 code is ungodly slow - -/* -============ -idSIMD_SSE2::MatX_LowerTriangularSolve - - solves x in Lx = b for the n * n sub-matrix of L - if skip > 0 the first skip elements of x are assumed to be valid already - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_SSE2::MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip ) { - int nc; - const float *lptr; - - if ( skip >= n ) { - return; - } - - lptr = L[skip]; - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - #define NSKIP( n, s ) ((n<<3)|(s&7)) - switch( NSKIP( n, skip ) ) { - case NSKIP( 1, 0 ): x[0] = b[0]; - return; - case NSKIP( 2, 0 ): x[0] = b[0]; - case NSKIP( 2, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - return; - case NSKIP( 3, 0 ): x[0] = b[0]; - case NSKIP( 3, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 3, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - return; - case NSKIP( 4, 0 ): x[0] = b[0]; - case NSKIP( 4, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 4, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 4, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - return; - case NSKIP( 5, 0 ): x[0] = b[0]; - case NSKIP( 5, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 5, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 5, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 5, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - return; - case NSKIP( 6, 0 ): x[0] = b[0]; - case NSKIP( 6, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 6, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 6, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 6, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 6, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - return; - case NSKIP( 7, 0 ): x[0] = b[0]; - case NSKIP( 7, 1 ): x[1] = b[1] - lptr[1*nc+0] * x[0]; - case NSKIP( 7, 2 ): x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case NSKIP( 7, 3 ): x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - case NSKIP( 7, 4 ): x[4] = b[4] - lptr[4*nc+0] * x[0] - lptr[4*nc+1] * x[1] - lptr[4*nc+2] * x[2] - lptr[4*nc+3] * x[3]; - case NSKIP( 7, 5 ): x[5] = b[5] - lptr[5*nc+0] * x[0] - lptr[5*nc+1] * x[1] - lptr[5*nc+2] * x[2] - lptr[5*nc+3] * x[3] - lptr[5*nc+4] * x[4]; - case NSKIP( 7, 6 ): x[6] = b[6] - lptr[6*nc+0] * x[0] - lptr[6*nc+1] * x[1] - lptr[6*nc+2] * x[2] - lptr[6*nc+3] * x[3] - lptr[6*nc+4] * x[4] - lptr[6*nc+5] * x[5]; - return; - } - return; - } - - // process first 4 rows - switch( skip ) { - case 0: x[0] = b[0]; - case 1: x[1] = b[1] - lptr[1*nc+0] * x[0]; - case 2: x[2] = b[2] - lptr[2*nc+0] * x[0] - lptr[2*nc+1] * x[1]; - case 3: x[3] = b[3] - lptr[3*nc+0] * x[0] - lptr[3*nc+1] * x[1] - lptr[3*nc+2] * x[2]; - skip = 4; - } - - lptr = L[skip]; - - __asm { - push ebx - mov eax, skip // eax = i - shl eax, 2 // eax = i*4 - mov edx, n // edx = n - shl edx, 2 // edx = n*4 - mov esi, x // esi = x - mov edi, lptr // edi = lptr - add esi, eax - add edi, eax - mov ebx, b // ebx = b - // aligned - looprow: - mov ecx, eax - neg ecx - cvtps2pd xmm0, [esi+ecx] - cvtps2pd xmm2, [edi+ecx] - mulpd xmm0, xmm2 - cvtps2pd xmm1, [esi+ecx+8] - cvtps2pd xmm3, [edi+ecx+8] - mulpd xmm1, xmm3 - add ecx, 20*4 - jg donedot16 - dot16: - cvtps2pd xmm2, [esi+ecx-(16*4)] - cvtps2pd xmm3, [edi+ecx-(16*4)] - cvtps2pd xmm4, [esi+ecx-(14*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(14*4)] - addpd xmm0, xmm2 - cvtps2pd xmm2, [esi+ecx-(12*4)] - mulpd xmm4, xmm5 - cvtps2pd xmm3, [edi+ecx-(12*4)] - addpd xmm1, xmm4 - cvtps2pd xmm4, [esi+ecx-(10*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(10*4)] - addpd xmm0, xmm2 - cvtps2pd xmm2, [esi+ecx-(8*4)] - mulpd xmm4, xmm5 - cvtps2pd xmm3, [edi+ecx-(8*4)] - addpd xmm1, xmm4 - cvtps2pd xmm4, [esi+ecx-(6*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(6*4)] - addpd xmm0, xmm2 - cvtps2pd xmm2, [esi+ecx-(4*4)] - mulpd xmm4, xmm5 - cvtps2pd xmm3, [edi+ecx-(4*4)] - addpd xmm1, xmm4 - cvtps2pd xmm4, [esi+ecx-(2*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(2*4)] - addpd xmm0, xmm2 - add ecx, 16*4 - mulpd xmm4, xmm5 - addpd xmm1, xmm4 - jle dot16 - donedot16: - sub ecx, 8*4 - jg donedot8 - dot8: - cvtps2pd xmm2, [esi+ecx-(8*4)] - cvtps2pd xmm3, [edi+ecx-(8*4)] - cvtps2pd xmm7, [esi+ecx-(6*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(6*4)] - addpd xmm0, xmm2 - cvtps2pd xmm6, [esi+ecx-(4*4)] - mulpd xmm7, xmm5 - cvtps2pd xmm3, [edi+ecx-(4*4)] - addpd xmm1, xmm7 - cvtps2pd xmm4, [esi+ecx-(2*4)] - mulpd xmm6, xmm3 - cvtps2pd xmm7, [edi+ecx-(2*4)] - addpd xmm0, xmm6 - add ecx, 8*4 - mulpd xmm4, xmm7 - addpd xmm1, xmm4 - donedot8: - sub ecx, 4*4 - jg donedot4 - dot4: - cvtps2pd xmm2, [esi+ecx-(4*4)] - cvtps2pd xmm3, [edi+ecx-(4*4)] - cvtps2pd xmm4, [esi+ecx-(2*4)] - mulpd xmm2, xmm3 - cvtps2pd xmm5, [edi+ecx-(2*4)] - addpd xmm0, xmm2 - add ecx, 4*4 - mulpd xmm4, xmm5 - addpd xmm1, xmm4 - donedot4: - addpd xmm0, xmm1 - movaps xmm1, xmm0 - shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 0 ) - addsd xmm0, xmm1 - sub ecx, 4*4 - jz dot0 - add ecx, 4 - jz dot1 - add ecx, 4 - jz dot2 - //dot3: - cvtss2sd xmm1, [esi-(3*4)] - cvtss2sd xmm2, [edi-(3*4)] - mulsd xmm1, xmm2 - addsd xmm0, xmm1 - dot2: - cvtss2sd xmm3, [esi-(2*4)] - cvtss2sd xmm4, [edi-(2*4)] - mulsd xmm3, xmm4 - addsd xmm0, xmm3 - dot1: - cvtss2sd xmm5, [esi-(1*4)] - cvtss2sd xmm6, [edi-(1*4)] - mulsd xmm5, xmm6 - addsd xmm0, xmm5 - dot0: - cvtss2sd xmm1, [ebx+eax] - subsd xmm1, xmm0 - cvtsd2ss xmm0, xmm1 - movss [esi], xmm0 - add eax, 4 - cmp eax, edx - jge done - add esi, 4 - mov ecx, nc - shl ecx, 2 - add edi, ecx - add edi, 4 - jmp looprow - // done - done: - pop ebx - } -} - -/* -============ -idSIMD_SSE2::MatX_LowerTriangularSolveTranspose - - solves x in L'x = b for the n * n sub-matrix of L - L has to be a lower triangular matrix with (implicit) ones on the diagonal - x == b is allowed -============ -*/ -void VPCALL idSIMD_SSE2::MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ) { - int nc; - const float *lptr; - - lptr = L.ToFloatPtr(); - nc = L.GetNumColumns(); - - // unrolled cases for n < 8 - if ( n < 8 ) { - switch( n ) { - case 0: - return; - case 1: - x[0] = b[0]; - return; - case 2: - x[1] = b[1]; - x[0] = b[0] - lptr[1*nc+0] * x[1]; - return; - case 3: - x[2] = b[2]; - x[1] = b[1] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 4: - x[3] = b[3]; - x[2] = b[2] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 5: - x[4] = b[4]; - x[3] = b[3] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 6: - x[5] = b[5]; - x[4] = b[4] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - case 7: - x[6] = b[6]; - x[5] = b[5] - lptr[6*nc+5] * x[6]; - x[4] = b[4] - lptr[6*nc+4] * x[6] - lptr[5*nc+4] * x[5]; - x[3] = b[3] - lptr[6*nc+3] * x[6] - lptr[5*nc+3] * x[5] - lptr[4*nc+3] * x[4]; - x[2] = b[2] - lptr[6*nc+2] * x[6] - lptr[5*nc+2] * x[5] - lptr[4*nc+2] * x[4] - lptr[3*nc+2] * x[3]; - x[1] = b[1] - lptr[6*nc+1] * x[6] - lptr[5*nc+1] * x[5] - lptr[4*nc+1] * x[4] - lptr[3*nc+1] * x[3] - lptr[2*nc+1] * x[2]; - x[0] = b[0] - lptr[6*nc+0] * x[6] - lptr[5*nc+0] * x[5] - lptr[4*nc+0] * x[4] - lptr[3*nc+0] * x[3] - lptr[2*nc+0] * x[2] - lptr[1*nc+0] * x[1]; - return; - } - return; - } - - int i, j, m; - float *xptr; - double s0; - - // if the number of columns is not a multiple of 2 we're screwed for alignment. - // however, if the number of columns is a multiple of 2 but the number of to be - // processed rows is not a multiple of 2 we can still run 8 byte aligned - m = n; - if ( m & 1 ) { - m--; - x[m] = b[m]; - - lptr = L[m] + m - 4; - xptr = x + m; - __asm { - push ebx - mov eax, m // eax = i - mov esi, xptr // esi = xptr - mov edi, lptr // edi = lptr - mov ebx, b // ebx = b - mov edx, nc // edx = nc*sizeof(float) - shl edx, 2 - process4rows_1: - cvtps2pd xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] - cvtps2pd xmm2, [ebx+eax*4-8] // load b[i-4], b[i-3] - xor ecx, ecx - sub eax, m - neg eax - jz done4x4_1 - process4x4_1: // process 4x4 blocks - cvtps2pd xmm3, [edi] - cvtps2pd xmm4, [edi+8] - add edi, edx - cvtss2sd xmm5, [esi+4*ecx+0] - shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) - mulpd xmm3, xmm5 - cvtps2pd xmm1, [edi] - mulpd xmm4, xmm5 - cvtps2pd xmm6, [edi+8] - subpd xmm0, xmm3 - subpd xmm2, xmm4 - add edi, edx - cvtss2sd xmm7, [esi+4*ecx+4] - shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) - mulpd xmm1, xmm7 - cvtps2pd xmm3, [edi] - mulpd xmm6, xmm7 - cvtps2pd xmm4, [edi+8] - subpd xmm0, xmm1 - subpd xmm2, xmm6 - add edi, edx - cvtss2sd xmm5, [esi+4*ecx+8] - shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) - mulpd xmm3, xmm5 - cvtps2pd xmm1, [edi] - mulpd xmm4, xmm5 - cvtps2pd xmm6, [edi+8] - subpd xmm0, xmm3 - subpd xmm2, xmm4 - add edi, edx - cvtss2sd xmm7, [esi+4*ecx+12] - shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) - mulpd xmm1, xmm7 - add ecx, 4 - mulpd xmm6, xmm7 - cmp ecx, eax - subpd xmm0, xmm1 - subpd xmm2, xmm6 - jl process4x4_1 - done4x4_1: // process left over of the 4 rows - cvtps2pd xmm3, [edi] - cvtps2pd xmm4, [edi+8] - cvtss2sd xmm5, [esi+4*ecx] - shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) - mulpd xmm3, xmm5 - mulpd xmm4, xmm5 - subpd xmm0, xmm3 - subpd xmm2, xmm4 - imul ecx, edx - sub edi, ecx - neg eax - - add eax, m - sub eax, 4 - movapd xmm1, xmm0 - shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 1 ) - movapd xmm3, xmm2 - shufpd xmm3, xmm3, R_SHUFFLEPD( 1, 1 ) - sub edi, edx - cvtsd2ss xmm7, xmm3 - movss [esi-4], xmm7 // xptr[-1] = s3 - movsd xmm4, xmm3 - movsd xmm5, xmm3 - cvtss2sd xmm7, [edi+8] - mulsd xmm3, xmm7 // lptr[-1*nc+2] * s3 - cvtss2sd xmm7, [edi+4] - mulsd xmm4, xmm7 // lptr[-1*nc+1] * s3 - cvtss2sd xmm7, [edi] - mulsd xmm5, xmm7 // lptr[-1*nc+0] * s3 - subsd xmm2, xmm3 - cvtsd2ss xmm7, xmm2 - movss [esi-8], xmm7 // xptr[-2] = s2 - movsd xmm6, xmm2 - sub edi, edx - subsd xmm0, xmm5 - subsd xmm1, xmm4 - cvtss2sd xmm7, [edi+4] - mulsd xmm2, xmm7 // lptr[-2*nc+1] * s2 - cvtss2sd xmm7, [edi] - mulsd xmm6, xmm7 // lptr[-2*nc+0] * s2 - subsd xmm1, xmm2 - cvtsd2ss xmm7, xmm1 - movss [esi-12], xmm7 // xptr[-3] = s1 - subsd xmm0, xmm6 - sub edi, edx - cmp eax, 4 - cvtss2sd xmm7, [edi] - mulsd xmm1, xmm7 // lptr[-3*nc+0] * s1 - subsd xmm0, xmm1 - cvtsd2ss xmm7, xmm0 - movss [esi-16], xmm7 // xptr[-4] = s0 - jl done4rows_1 - sub edi, edx - sub edi, 16 - sub esi, 16 - jmp process4rows_1 - done4rows_1: - pop ebx - } - } - else { - lptr = L.ToFloatPtr() + m * L.GetNumColumns() + m - 4; - xptr = x + m; - __asm { - push ebx - mov eax, m // eax = i - mov esi, xptr // esi = xptr - mov edi, lptr // edi = lptr - mov ebx, b // ebx = b - mov edx, nc // edx = nc*sizeof(float) - shl edx, 2 - process4rows: - cvtps2pd xmm0, [ebx+eax*4-16] // load b[i-2], b[i-1] - cvtps2pd xmm2, [ebx+eax*4-8] // load b[i-4], b[i-3] - sub eax, m - jz done4x4 - neg eax - xor ecx, ecx - process4x4: // process 4x4 blocks - cvtps2pd xmm3, [edi] - cvtps2pd xmm4, [edi+8] - add edi, edx - cvtss2sd xmm5, [esi+4*ecx+0] - shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) - mulpd xmm3, xmm5 - cvtps2pd xmm1, [edi] - mulpd xmm4, xmm5 - cvtps2pd xmm6, [edi+8] - subpd xmm0, xmm3 - subpd xmm2, xmm4 - add edi, edx - cvtss2sd xmm7, [esi+4*ecx+4] - shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) - mulpd xmm1, xmm7 - cvtps2pd xmm3, [edi] - mulpd xmm6, xmm7 - cvtps2pd xmm4, [edi+8] - subpd xmm0, xmm1 - subpd xmm2, xmm6 - add edi, edx - cvtss2sd xmm5, [esi+4*ecx+8] - shufpd xmm5, xmm5, R_SHUFFLEPD( 0, 0 ) - mulpd xmm3, xmm5 - cvtps2pd xmm1, [edi] - mulpd xmm4, xmm5 - cvtps2pd xmm6, [edi+8] - subpd xmm0, xmm3 - subpd xmm2, xmm4 - add edi, edx - cvtss2sd xmm7, [esi+4*ecx+12] - shufpd xmm7, xmm7, R_SHUFFLEPD( 0, 0 ) - mulpd xmm1, xmm7 - add ecx, 4 - mulpd xmm6, xmm7 - cmp ecx, eax - subpd xmm0, xmm1 - subpd xmm2, xmm6 - jl process4x4 - imul ecx, edx - sub edi, ecx - neg eax - done4x4: // process left over of the 4 rows - add eax, m - sub eax, 4 - movapd xmm1, xmm0 - shufpd xmm1, xmm1, R_SHUFFLEPD( 1, 1 ) - movapd xmm3, xmm2 - shufpd xmm3, xmm3, R_SHUFFLEPD( 1, 1 ) - sub edi, edx - cvtsd2ss xmm7, xmm3 - movss [esi-4], xmm7 // xptr[-1] = s3 - movsd xmm4, xmm3 - movsd xmm5, xmm3 - cvtss2sd xmm7, [edi+8] - mulsd xmm3, xmm7 // lptr[-1*nc+2] * s3 - cvtss2sd xmm7, [edi+4] - mulsd xmm4, xmm7 // lptr[-1*nc+1] * s3 - cvtss2sd xmm7, [edi] - mulsd xmm5, xmm7 // lptr[-1*nc+0] * s3 - subsd xmm2, xmm3 - cvtsd2ss xmm7, xmm2 - movss [esi-8], xmm7 // xptr[-2] = s2 - movsd xmm6, xmm2 - sub edi, edx - subsd xmm0, xmm5 - subsd xmm1, xmm4 - cvtss2sd xmm7, [edi+4] - mulsd xmm2, xmm7 // lptr[-2*nc+1] * s2 - cvtss2sd xmm7, [edi] - mulsd xmm6, xmm7 // lptr[-2*nc+0] * s2 - subsd xmm1, xmm2 - cvtsd2ss xmm7, xmm1 - movss [esi-12], xmm7 // xptr[-3] = s1 - subsd xmm0, xmm6 - sub edi, edx - cmp eax, 4 - cvtss2sd xmm7, [edi] - mulsd xmm1, xmm7 // lptr[-3*nc+0] * s1 - subsd xmm0, xmm1 - cvtsd2ss xmm7, xmm0 - movss [esi-16], xmm7 // xptr[-4] = s0 - jl done4rows - sub edi, edx - sub edi, 16 - sub esi, 16 - jmp process4rows - done4rows: - pop ebx - } - } - - // process left over rows - for ( i = (m&3)-1; i >= 0; i-- ) { - s0 = b[i]; - lptr = L[i+1] + i; - for ( j = i + 1; j < m; j++ ) { - s0 -= lptr[0] * x[j]; - lptr += nc; - } - x[i] = s0; - } -} - -#endif - -/* -============ -idSIMD_SSE2::MixedSoundToSamples -============ -*/ -void VPCALL idSIMD_SSE2::MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ) { - - assert( ( numSamples % MIXBUFFER_SAMPLES ) == 0 ); - - __asm { - - mov eax, numSamples - mov edi, mixBuffer - mov esi, samples - shl eax, 2 - add edi, eax - neg eax - - loop16: - - movaps xmm0, [edi+eax+0*16] - movaps xmm1, [edi+eax+1*16] - movaps xmm2, [edi+eax+2*16] - movaps xmm3, [edi+eax+3*16] - - add esi, 4*4*2 - - cvtps2dq xmm4, xmm0 - cvtps2dq xmm5, xmm1 - cvtps2dq xmm6, xmm2 - cvtps2dq xmm7, xmm3 - - prefetchnta [edi+eax+128] - - packssdw xmm4, xmm5 - packssdw xmm6, xmm7 - - add eax, 4*16 - - movlps [esi-4*4*2], xmm4 // FIXME: should not use movlps/movhps to move integer data - movhps [esi-3*4*2], xmm4 - movlps [esi-2*4*2], xmm6 - movhps [esi-1*4*2], xmm6 - - jl loop16 - } -} - -#endif /* _WIN32 */ diff --git a/idlib/math/simd_sse2.h b/idlib/math/simd_sse2.h deleted file mode 100644 index 1984be19b..000000000 --- a/idlib/math/simd_sse2.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_SSE2_H__ -#define __MATH_SIMD_SSE2_H__ - -/* -=============================================================================== - - SSE2 implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_SSE2 : public idSIMD_SSE { -public: -#if defined(MACOS_X) && defined(__i386__) - virtual const char * VPCALL GetName( void ) const; - virtual void VPCALL CmpLT( byte *dst, const byte bitNum, const float *src0, const float constant, const int count ); - -#elif defined(_WIN32) - virtual const char * VPCALL GetName( void ) const; - - //virtual void VPCALL MatX_LowerTriangularSolve( const idMatX &L, float *x, const float *b, const int n, int skip = 0 ); - //virtual void VPCALL MatX_LowerTriangularSolveTranspose( const idMatX &L, float *x, const float *b, const int n ); - - virtual void VPCALL MixedSoundToSamples( short *samples, const float *mixBuffer, const int numSamples ); - -#endif -}; - -#endif /* !__MATH_SIMD_SSE2_H__ */ diff --git a/idlib/math/simd_sse3.cpp b/idlib/math/simd_sse3.cpp deleted file mode 100644 index 75b89d93c..000000000 --- a/idlib/math/simd_sse3.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#include "simd_generic.h" -#include "simd_mmx.h" -#include "simd_sse.h" -#include "simd_sse2.h" -#include "simd_sse3.h" - - -//=============================================================== -// -// SSE3 implementation of idSIMDProcessor -// -//=============================================================== - -#if defined(MACOS_X) && defined(__i386__) - -/* -============ -idSIMD_SSE3::GetName -============ -*/ -const char * idSIMD_SSE3::GetName( void ) const { - return "MMX & SSE & SSE2 & SSE3"; -} - -#elif defined(_WIN32) - -#include - -#define SHUFFLEPS( x, y, z, w ) (( (x) & 3 ) << 6 | ( (y) & 3 ) << 4 | ( (z) & 3 ) << 2 | ( (w) & 3 )) -#define R_SHUFFLEPS( x, y, z, w ) (( (w) & 3 ) << 6 | ( (z) & 3 ) << 4 | ( (y) & 3 ) << 2 | ( (x) & 3 )) -#define SHUFFLEPD( x, y ) (( (x) & 1 ) << 1 | ( (y) & 1 )) -#define R_SHUFFLEPD( x, y ) (( (y) & 1 ) << 1 | ( (x) & 1 )) - -/* - - The first argument of an instruction macro is the destination - and the second argument is the source operand. The destination - operand can be _xmm0 to _xmm7 only. The source operand can be - any one of the registers _xmm0 to _xmm7 or _eax, _ecx, _edx, _esp, - _ebp, _ebx, _esi, or _edi that contains the effective address. - - For instance: haddps xmm0, xmm1 - becomes: haddps( _xmm0, _xmm1 ) - and: haddps xmm0, [esi] - becomes: haddps( _xmm0, _esi ) - - The ADDRESS_ADDC macro can be used when the effective source address - is formed by adding a constant to a general purpose register. - For instance: haddps xmm0, [esi+48] - becomes: haddps( _xmm0, ADDRESS_ADDC( _esi, 48 ) ) - - The ADDRESS_ADDR macro can be used when the effective source address - is formed by adding two general purpose registers. - For instance: haddps xmm0, [esi+eax] - becomes: haddps( _xmm0, ADDRESS_ADDR( _esi, _eax ) ) - - The ADDRESS_ADDRC macro can be used when the effective source address - is formed by adding two general purpose registers and a constant. - The constant must be in the range [-128, 127]. - For instance: haddps xmm0, [esi+eax+48] - becomes: haddps( _xmm0, ADDRESS_ADDRC( _esi, _eax, 48 ) ) - - The ADDRESS_SCALEADDR macro can be used when the effective source address is formed - by adding a scaled general purpose register to another general purpose register. - The scale must be either 1, 2, 4 or 8. - For instance: haddps xmm0, [esi+eax*4] - becomes: haddps( _xmm0, ADDRESS_SCALEADDR( _esi, _eax, 4 ) ) - - The ADDRESS_SCALEADDRC macro can be used when the effective source address is formed - by adding a scaled general purpose register to another general purpose register and - also adding a constant. The scale must be either 1, 2, 4 or 8. The constant must - be in the range [-128, 127]. - For instance: haddps xmm0, [esi+eax*4+64] - becomes: haddps( _xmm0, ADDRESS_SCALEADDRC( _esi, _eax, 4, 64 ) ) - -*/ - -#define _eax 0x00 -#define _ecx 0x01 -#define _edx 0x02 -#define _ebx 0x03 -#define _esp 0x04 -#define _ebp 0x05 -#define _esi 0x06 -#define _edi 0x07 - -#define _xmm0 0xC0 -#define _xmm1 0xC1 -#define _xmm2 0xC2 -#define _xmm3 0xC3 -#define _xmm4 0xC4 -#define _xmm5 0xC5 -#define _xmm6 0xC6 -#define _xmm7 0xC7 - -#define RSCALE( s ) ( (s&2)<<5 ) | ( (s&4)<<5 ) | ( (s&8)<<3 ) | ( (s&8)<<4 ) - -#define ADDRESS_ADDC( reg0, constant ) 0x40 | ( reg0 & 7 ) \ - _asm _emit constant - -#define ADDRESS_ADDR( reg0, reg1 ) 0x04 \ - _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) - -#define ADDRESS_ADDRC( reg0, reg1, constant ) 0x44 \ - _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) \ - _asm _emit constant - -#define ADDRESS_SCALEADDR( reg0, reg1, scale ) 0x04 \ - _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) | RSCALE( scale ) - -#define ADDRESS_SCALEADDRC( reg0, reg1, scale, constant ) 0x44 \ - _asm _emit ( ( reg1 & 7 ) << 3 ) | ( reg0 & 7 ) | RSCALE( scale ) \ - _asm _emit constant - - -// Packed Single-FP Add/Subtract ( dst[0]=dst[0]+src[0], dst[1]=dst[1]-src[1], dst[2]=dst[2]+src[2], dst[3]=dst[3]-src[3] ) -#define addsubps( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0xD0 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Packed Double-FP Add/Subtract ( dst[0]=dst[0]+src[0], dst[1]=dst[1]-src[1] ) -#define addsubpd( dst, src ) \ - _asm _emit 0x66 \ - _asm _emit 0x0F \ - _asm _emit 0xD0 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Packed Single-FP Horizontal Add ( dst[0]=dst[0]+dst[1], dst[1]=dst[2]+dst[3], dst[2]=src[0]+src[1], dst[3]=src[2]+src[3] ) -#define haddps( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0x7C \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Packed Double-FP Horizontal Add ( dst[0]=dst[0]+dst[1], dst[1]=src[0]+src[1] ) -#define haddpd( dst, src ) \ - _asm _emit 0x66 \ - _asm _emit 0x0F \ - _asm _emit 0x7C \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Packed Single-FP Horizontal Subtract ( dst[0]=dst[0]-dst[1], dst[1]=dst[2]-dst[3], dst[2]=src[0]-src[1], dst[3]=src[2]-src[3] ) -#define hsubps( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0x7D \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Packed Double-FP Horizontal Subtract ( dst[0]=dst[0]-dst[1], dst[1]=src[0]-src[1] ) -#define hsubpd( dst, src ) \ - _asm _emit 0x66 \ - _asm _emit 0x0F \ - _asm _emit 0x7D \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Move Packed Single-FP Low and Duplicate ( dst[0]=src[0], dst[1]=src[0], dst[2]=src[2], dst[3]=src[2] ) -#define movsldup( dst, src ) \ - _asm _emit 0xF3 \ - _asm _emit 0x0F \ - _asm _emit 0x12 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Move One Double-FP Low and Duplicate ( dst[0]=src[0], dst[1]=src[0] ) -#define movdldup( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0x12 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Move Packed Single-FP High and Duplicate ( dst[0]=src[1], dst[1]=src[1], dst[2]=src[3], dst[3]=src[3] ) -#define movshdup( dst, src ) \ - _asm _emit 0xF3 \ - _asm _emit 0x0F \ - _asm _emit 0x16 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Move One Double-FP High and Duplicate ( dst[0]=src[1], dst[1]=src[1] ) -#define movdhdup( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0x16 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - -// Load Unaligned Integer 128 bits -#define lddqu( dst, src ) \ - _asm _emit 0xF2 \ - _asm _emit 0x0F \ - _asm _emit 0xF0 \ - _asm _emit ( ( dst & 7 ) << 3 ) | src - - -#define DRAWVERT_SIZE 60 -#define DRAWVERT_XYZ_OFFSET (0*4) -#define DRAWVERT_ST_OFFSET (3*4) -#define DRAWVERT_NORMAL_OFFSET (5*4) -#define DRAWVERT_TANGENT0_OFFSET (8*4) -#define DRAWVERT_TANGENT1_OFFSET (11*4) -#define DRAWVERT_COLOR_OFFSET (14*4) - -#define JOINTQUAT_SIZE (7*4) -#define JOINTMAT_SIZE (4*3*4) -#define JOINTWEIGHT_SIZE (4*4) - - -/* -============ -SSE3_Dot -============ -*/ -float SSE3_Dot( const idVec4 &v1, const idVec4 &v2 ) { - float d; - __asm { - mov esi, v1 - mov edi, v2 - movaps xmm0, [esi] - mulps xmm0, [edi] - haddps( _xmm0, _xmm0 ) - haddps( _xmm0, _xmm0 ) - movss d, xmm0 - } - return d; -} - -/* -============ -idSIMD_SSE3::GetName -============ -*/ -const char * idSIMD_SSE3::GetName( void ) const { - return "MMX & SSE & SSE2 & SSE3"; -} - -/* -============ -idSIMD_SSE3::TransformVerts -============ -*/ -void VPCALL idSIMD_SSE3::TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ) { -#if 1 - - assert( sizeof( idDrawVert ) == DRAWVERT_SIZE ); - assert( (int)&((idDrawVert *)0)->xyz == DRAWVERT_XYZ_OFFSET ); - assert( sizeof( idVec4 ) == JOINTWEIGHT_SIZE ); - assert( sizeof( idJointMat ) == JOINTMAT_SIZE ); - - __asm - { - mov eax, numVerts - test eax, eax - jz done - imul eax, DRAWVERT_SIZE - - mov ecx, verts - mov edx, index - mov esi, weights - mov edi, joints - - add ecx, eax - neg eax - - loopVert: - mov ebx, [edx] - movaps xmm2, [esi] - add edx, 8 - movaps xmm0, xmm2 - add esi, JOINTWEIGHT_SIZE - movaps xmm1, xmm2 - - mulps xmm0, [edi+ebx+ 0] // xmm0 = m0, m1, m2, t0 - mulps xmm1, [edi+ebx+16] // xmm1 = m3, m4, m5, t1 - mulps xmm2, [edi+ebx+32] // xmm2 = m6, m7, m8, t2 - - cmp dword ptr [edx-4], 0 - - jne doneWeight - - loopWeight: - mov ebx, [edx] - movaps xmm5, [esi] - add edx, 8 - movaps xmm3, xmm5 - add esi, JOINTWEIGHT_SIZE - movaps xmm4, xmm5 - - mulps xmm3, [edi+ebx+ 0] // xmm3 = m0, m1, m2, t0 - mulps xmm4, [edi+ebx+16] // xmm4 = m3, m4, m5, t1 - mulps xmm5, [edi+ebx+32] // xmm5 = m6, m7, m8, t2 - - cmp dword ptr [edx-4], 0 - - addps xmm0, xmm3 - addps xmm1, xmm4 - addps xmm2, xmm5 - - je loopWeight - - doneWeight: - add eax, DRAWVERT_SIZE - - haddps( _xmm0, _xmm1 ) - haddps( _xmm2, _xmm0 ) - - movhps [ecx+eax-DRAWVERT_SIZE+0], xmm2 - - haddps( _xmm2, _xmm2 ) - - movss [ecx+eax-DRAWVERT_SIZE+8], xmm2 - - jl loopVert - done: - } - -#else - - int i, j; - const byte *jointsPtr = (byte *)joints; - - for( j = i = 0; i < numVerts; i++ ) { - idVec3 v; - - v = ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - while( index[j*2+1] == 0 ) { - j++; - v += ( *(idJointMat *) ( jointsPtr + index[j*2+0] ) ) * weights[j]; - } - j++; - - verts[i].xyz = v; - } - -#endif -} - -#endif /* _WIN32 */ diff --git a/idlib/math/simd_sse3.h b/idlib/math/simd_sse3.h deleted file mode 100644 index bf0b8e8f8..000000000 --- a/idlib/math/simd_sse3.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_SIMD_SSE3_H__ -#define __MATH_SIMD_SSE3_H__ - -/* -=============================================================================== - - SSE3 implementation of idSIMDProcessor - -=============================================================================== -*/ - -class idSIMD_SSE3 : public idSIMD_SSE2 { -public: -#if defined(MACOS_X) && defined(__i386__) - virtual const char * VPCALL GetName( void ) const; - -#elif defined(_WIN32) - virtual const char * VPCALL GetName( void ) const; - - virtual void VPCALL TransformVerts( idDrawVert *verts, const int numVerts, const idJointMat *joints, const idVec4 *weights, const int *index, const int numWeights ); - -#endif -}; - -#endif /* !__MATH_SIMD_SSE3_H__ */ diff --git a/idlib/math/vector.cpp b/idlib/math/vector.cpp deleted file mode 100644 index 9e2c5d775..000000000 --- a/idlib/math/vector.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "../precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -idVec2 vec2_origin( 0.0f, 0.0f ); -idVec3 vec3_origin( 0.0f, 0.0f, 0.0f ); -idVec4 vec4_origin( 0.0f, 0.0f, 0.0f, 0.0f ); -idVec5 vec5_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); -idVec6 vec6_origin( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ); -idVec6 vec6_infinity( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY, idMath::INFINITY ); - - -//=============================================================== -// -// idVec2 -// -//=============================================================== - -/* -============= -idVec2::ToString -============= -*/ -const char *idVec2::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============= -Lerp - -Linearly inperpolates one vector to another. -============= -*/ -void idVec2::Lerp( const idVec2 &v1, const idVec2 &v2, const float l ) { - if ( l <= 0.0f ) { - (*this) = v1; - } else if ( l >= 1.0f ) { - (*this) = v2; - } else { - (*this) = v1 + l * ( v2 - v1 ); - } -} - - -//=============================================================== -// -// idVec3 -// -//=============================================================== - -/* -============= -idVec3::ToYaw -============= -*/ -float idVec3::ToYaw( void ) const { - float yaw; - - if ( ( y == 0.0f ) && ( x == 0.0f ) ) { - yaw = 0.0f; - } else { - yaw = RAD2DEG( atan2( y, x ) ); - if ( yaw < 0.0f ) { - yaw += 360.0f; - } - } - - return yaw; -} - -/* -============= -idVec3::ToPitch -============= -*/ -float idVec3::ToPitch( void ) const { - float forward; - float pitch; - - if ( ( x == 0.0f ) && ( y == 0.0f ) ) { - if ( z > 0.0f ) { - pitch = 90.0f; - } else { - pitch = 270.0f; - } - } else { - forward = ( float )idMath::Sqrt( x * x + y * y ); - pitch = RAD2DEG( atan2( z, forward ) ); - if ( pitch < 0.0f ) { - pitch += 360.0f; - } - } - - return pitch; -} - -/* -============= -idVec3::ToAngles -============= -*/ -idAngles idVec3::ToAngles( void ) const { - float forward; - float yaw; - float pitch; - - if ( ( x == 0.0f ) && ( y == 0.0f ) ) { - yaw = 0.0f; - if ( z > 0.0f ) { - pitch = 90.0f; - } else { - pitch = 270.0f; - } - } else { - yaw = RAD2DEG( atan2( y, x ) ); - if ( yaw < 0.0f ) { - yaw += 360.0f; - } - - forward = ( float )idMath::Sqrt( x * x + y * y ); - pitch = RAD2DEG( atan2( z, forward ) ); - if ( pitch < 0.0f ) { - pitch += 360.0f; - } - } - - return idAngles( -pitch, yaw, 0.0f ); -} - -/* -============= -idVec3::ToPolar -============= -*/ -idPolar3 idVec3::ToPolar( void ) const { - float forward; - float yaw; - float pitch; - - if ( ( x == 0.0f ) && ( y == 0.0f ) ) { - yaw = 0.0f; - if ( z > 0.0f ) { - pitch = 90.0f; - } else { - pitch = 270.0f; - } - } else { - yaw = RAD2DEG( atan2( y, x ) ); - if ( yaw < 0.0f ) { - yaw += 360.0f; - } - - forward = ( float )idMath::Sqrt( x * x + y * y ); - pitch = RAD2DEG( atan2( z, forward ) ); - if ( pitch < 0.0f ) { - pitch += 360.0f; - } - } - return idPolar3( idMath::Sqrt( x * x + y * y + z * z ), yaw, -pitch ); -} - -/* -============= -idVec3::ToMat3 -============= -*/ -idMat3 idVec3::ToMat3( void ) const { - idMat3 mat; - float d; - - mat[0] = *this; - d = x * x + y * y; - if ( !d ) { - mat[1][0] = 1.0f; - mat[1][1] = 0.0f; - mat[1][2] = 0.0f; - } else { - d = idMath::InvSqrt( d ); - mat[1][0] = -y * d; - mat[1][1] = x * d; - mat[1][2] = 0.0f; - } - mat[2] = Cross( mat[1] ); - - return mat; -} - -/* -============= -idVec3::ToString -============= -*/ -const char *idVec3::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============= -Lerp - -Linearly inperpolates one vector to another. -============= -*/ -void idVec3::Lerp( const idVec3 &v1, const idVec3 &v2, const float l ) { - if ( l <= 0.0f ) { - (*this) = v1; - } else if ( l >= 1.0f ) { - (*this) = v2; - } else { - (*this) = v1 + l * ( v2 - v1 ); - } -} - -/* -============= -SLerp - -Spherical linear interpolation from v1 to v2. -Vectors are expected to be normalized. -============= -*/ -#define LERP_DELTA 1e-6 - -void idVec3::SLerp( const idVec3 &v1, const idVec3 &v2, const float t ) { - float omega, cosom, sinom, scale0, scale1; - - if ( t <= 0.0f ) { - (*this) = v1; - return; - } else if ( t >= 1.0f ) { - (*this) = v2; - return; - } - - cosom = v1 * v2; - if ( ( 1.0f - cosom ) > LERP_DELTA ) { - omega = acos( cosom ); - sinom = sin( omega ); - scale0 = sin( ( 1.0f - t ) * omega ) / sinom; - scale1 = sin( t * omega ) / sinom; - } else { - scale0 = 1.0f - t; - scale1 = t; - } - - (*this) = ( v1 * scale0 + v2 * scale1 ); -} - -/* -============= -ProjectSelfOntoSphere - -Projects the z component onto a sphere. -============= -*/ -void idVec3::ProjectSelfOntoSphere( const float radius ) { - float rsqr = radius * radius; - float len = Length(); - if ( len < rsqr * 0.5f ) { - z = sqrt( rsqr - len ); - } else { - z = rsqr / ( 2.0f * sqrt( len ) ); - } -} - - - -//=============================================================== -// -// idVec4 -// -//=============================================================== - -/* -============= -idVec4::ToString -============= -*/ -const char *idVec4::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============= -Lerp - -Linearly inperpolates one vector to another. -============= -*/ -void idVec4::Lerp( const idVec4 &v1, const idVec4 &v2, const float l ) { - if ( l <= 0.0f ) { - (*this) = v1; - } else if ( l >= 1.0f ) { - (*this) = v2; - } else { - (*this) = v1 + l * ( v2 - v1 ); - } -} - - -//=============================================================== -// -// idVec5 -// -//=============================================================== - -/* -============= -idVec5::ToString -============= -*/ -const char *idVec5::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - -/* -============= -idVec5::Lerp -============= -*/ -void idVec5::Lerp( const idVec5 &v1, const idVec5 &v2, const float l ) { - if ( l <= 0.0f ) { - (*this) = v1; - } else if ( l >= 1.0f ) { - (*this) = v2; - } else { - x = v1.x + l * ( v2.x - v1.x ); - y = v1.y + l * ( v2.y - v1.y ); - z = v1.z + l * ( v2.z - v1.z ); - s = v1.s + l * ( v2.s - v1.s ); - t = v1.t + l * ( v2.t - v1.t ); - } -} - - -//=============================================================== -// -// idVec6 -// -//=============================================================== - -/* -============= -idVec6::ToString -============= -*/ -const char *idVec6::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} - - -//=============================================================== -// -// idVecX -// -//=============================================================== - -float idVecX::temp[VECX_MAX_TEMP+4]; -float * idVecX::tempPtr = (float *) ( ( (int) idVecX::temp + 15 ) & ~15 ); -int idVecX::tempIndex = 0; - -/* -============= -idVecX::ToString -============= -*/ -const char *idVecX::ToString( int precision ) const { - return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision ); -} diff --git a/idlib/math/vector.h b/idlib/math/vector.h deleted file mode 100644 index e332aed8d..000000000 --- a/idlib/math/vector.h +++ /dev/null @@ -1,2017 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATH_VECTOR_H__ -#define __MATH_VECTOR_H__ - -/* -=============================================================================== - - Vector classes - -=============================================================================== -*/ - -#define VECTOR_EPSILON 0.001f - -class idAngles; -class idPolar3; -class idMat3; - -//=============================================================== -// -// idVec2 - 2D vector -// -//=============================================================== - -class idVec2 { -public: - float x; - float y; - - idVec2( void ); - explicit idVec2( const float x, const float y ); - - void Set( const float x, const float y ); - void Zero( void ); - - float operator[]( int index ) const; - float & operator[]( int index ); - idVec2 operator-() const; - float operator*( const idVec2 &a ) const; - idVec2 operator*( const float a ) const; - idVec2 operator/( const float a ) const; - idVec2 operator+( const idVec2 &a ) const; - idVec2 operator-( const idVec2 &a ) const; - idVec2 & operator+=( const idVec2 &a ); - idVec2 & operator-=( const idVec2 &a ); - idVec2 & operator/=( const idVec2 &a ); - idVec2 & operator/=( const float a ); - idVec2 & operator*=( const float a ); - - friend idVec2 operator*( const float a, const idVec2 b ); - - bool Compare( const idVec2 &a ) const; // exact compare, no epsilon - bool Compare( const idVec2 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idVec2 &a ) const; // exact compare, no epsilon - bool operator!=( const idVec2 &a ) const; // exact compare, no epsilon - - float Length( void ) const; - float LengthFast( void ) const; - float LengthSqr( void ) const; - float Normalize( void ); // returns length - float NormalizeFast( void ); // returns length - idVec2 & Truncate( float length ); // cap length - void Clamp( const idVec2 &min, const idVec2 &max ); - void Snap( void ); // snap to closest integer value - void SnapInt( void ); // snap towards integer (floor) - - int GetDimension( void ) const; - - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - void Lerp( const idVec2 &v1, const idVec2 &v2, const float l ); -}; - -extern idVec2 vec2_origin; -#define vec2_zero vec2_origin - -ID_INLINE idVec2::idVec2( void ) { -} - -ID_INLINE idVec2::idVec2( const float x, const float y ) { - this->x = x; - this->y = y; -} - -ID_INLINE void idVec2::Set( const float x, const float y ) { - this->x = x; - this->y = y; -} - -ID_INLINE void idVec2::Zero( void ) { - x = y = 0.0f; -} - -ID_INLINE bool idVec2::Compare( const idVec2 &a ) const { - return ( ( x == a.x ) && ( y == a.y ) ); -} - -ID_INLINE bool idVec2::Compare( const idVec2 &a, const float epsilon ) const { - if ( idMath::Fabs( x - a.x ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( y - a.y ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idVec2::operator==( const idVec2 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idVec2::operator!=( const idVec2 &a ) const { - return !Compare( a ); -} - -ID_INLINE float idVec2::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec2::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE float idVec2::Length( void ) const { - return ( float )idMath::Sqrt( x * x + y * y ); -} - -ID_INLINE float idVec2::LengthFast( void ) const { - float sqrLength; - - sqrLength = x * x + y * y; - return sqrLength * idMath::RSqrt( sqrLength ); -} - -ID_INLINE float idVec2::LengthSqr( void ) const { - return ( x * x + y * y ); -} - -ID_INLINE float idVec2::Normalize( void ) { - float sqrLength, invLength; - - sqrLength = x * x + y * y; - invLength = idMath::InvSqrt( sqrLength ); - x *= invLength; - y *= invLength; - return invLength * sqrLength; -} - -ID_INLINE float idVec2::NormalizeFast( void ) { - float lengthSqr, invLength; - - lengthSqr = x * x + y * y; - invLength = idMath::RSqrt( lengthSqr ); - x *= invLength; - y *= invLength; - return invLength * lengthSqr; -} - -ID_INLINE idVec2 &idVec2::Truncate( float length ) { - float length2; - float ilength; - - if ( !length ) { - Zero(); - } - else { - length2 = LengthSqr(); - if ( length2 > length * length ) { - ilength = length * idMath::InvSqrt( length2 ); - x *= ilength; - y *= ilength; - } - } - - return *this; -} - -ID_INLINE void idVec2::Clamp( const idVec2 &min, const idVec2 &max ) { - if ( x < min.x ) { - x = min.x; - } else if ( x > max.x ) { - x = max.x; - } - if ( y < min.y ) { - y = min.y; - } else if ( y > max.y ) { - y = max.y; - } -} - -ID_INLINE void idVec2::Snap( void ) { - x = floor( x + 0.5f ); - y = floor( y + 0.5f ); -} - -ID_INLINE void idVec2::SnapInt( void ) { - x = float( int( x ) ); - y = float( int( y ) ); -} - -ID_INLINE idVec2 idVec2::operator-() const { - return idVec2( -x, -y ); -} - -ID_INLINE idVec2 idVec2::operator-( const idVec2 &a ) const { - return idVec2( x - a.x, y - a.y ); -} - -ID_INLINE float idVec2::operator*( const idVec2 &a ) const { - return x * a.x + y * a.y; -} - -ID_INLINE idVec2 idVec2::operator*( const float a ) const { - return idVec2( x * a, y * a ); -} - -ID_INLINE idVec2 idVec2::operator/( const float a ) const { - float inva = 1.0f / a; - return idVec2( x * inva, y * inva ); -} - -ID_INLINE idVec2 operator*( const float a, const idVec2 b ) { - return idVec2( b.x * a, b.y * a ); -} - -ID_INLINE idVec2 idVec2::operator+( const idVec2 &a ) const { - return idVec2( x + a.x, y + a.y ); -} - -ID_INLINE idVec2 &idVec2::operator+=( const idVec2 &a ) { - x += a.x; - y += a.y; - - return *this; -} - -ID_INLINE idVec2 &idVec2::operator/=( const idVec2 &a ) { - x /= a.x; - y /= a.y; - - return *this; -} - -ID_INLINE idVec2 &idVec2::operator/=( const float a ) { - float inva = 1.0f / a; - x *= inva; - y *= inva; - - return *this; -} - -ID_INLINE idVec2 &idVec2::operator-=( const idVec2 &a ) { - x -= a.x; - y -= a.y; - - return *this; -} - -ID_INLINE idVec2 &idVec2::operator*=( const float a ) { - x *= a; - y *= a; - - return *this; -} - -ID_INLINE int idVec2::GetDimension( void ) const { - return 2; -} - -ID_INLINE const float *idVec2::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idVec2::ToFloatPtr( void ) { - return &x; -} - - -//=============================================================== -// -// idVec3 - 3D vector -// -//=============================================================== - -class idVec3 { -public: - float x; - float y; - float z; - - idVec3( void ); - explicit idVec3( const float x, const float y, const float z ); - - void Set( const float x, const float y, const float z ); - void Zero( void ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idVec3 operator-() const; - idVec3 & operator=( const idVec3 &a ); // required because of a msvc 6 & 7 bug - float operator*( const idVec3 &a ) const; - idVec3 operator*( const float a ) const; - idVec3 operator/( const float a ) const; - idVec3 operator+( const idVec3 &a ) const; - idVec3 operator-( const idVec3 &a ) const; - idVec3 & operator+=( const idVec3 &a ); - idVec3 & operator-=( const idVec3 &a ); - idVec3 & operator/=( const idVec3 &a ); - idVec3 & operator/=( const float a ); - idVec3 & operator*=( const float a ); - idVec3 & MulCW( const idVec3 &a ); // multiply on vector component-wise - idVec3 & DivCW( const idVec3 &a ); // divide on vector component-wise - - friend idVec3 operator*( const float a, const idVec3 b ); - - bool Compare( const idVec3 &a ) const; // exact compare, no epsilon - bool Compare( const idVec3 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idVec3 &a ) const; // exact compare, no epsilon - bool operator!=( const idVec3 &a ) const; // exact compare, no epsilon - - bool FixDegenerateNormal( void ); // fix degenerate axial cases - bool FixDenormals( void ); // change tiny numbers to zero - - idVec3 Cross( const idVec3 &a ) const; - idVec3 & Cross( const idVec3 &a, const idVec3 &b ); - float Length( void ) const; - float LengthSqr( void ) const; - float LengthFast( void ) const; - float Normalize( void ); // returns length - float NormalizeFast( void ); // returns length - idVec3 & Truncate( float length ); // cap length - void Clamp( const idVec3 &min, const idVec3 &max ); - void Snap( void ); // snap to closest integer value - void SnapInt( void ); // snap towards integer (floor) - - int GetDimension( void ) const; - - float ToYaw( void ) const; - float ToPitch( void ) const; - idAngles ToAngles( void ) const; - idPolar3 ToPolar( void ) const; - idMat3 ToMat3( void ) const; // vector should be normalized - const idVec2 & ToVec2( void ) const; - idVec2 & ToVec2( void ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - void NormalVectors( idVec3 &left, idVec3 &down ) const; // vector should be normalized - void OrthogonalBasis( idVec3 &left, idVec3 &up ) const; - - void ProjectOntoPlane( const idVec3 &normal, const float overBounce = 1.0f ); - bool ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce = 1.0f ); - void ProjectSelfOntoSphere( const float radius ); - - void Lerp( const idVec3 &v1, const idVec3 &v2, const float l ); - void SLerp( const idVec3 &v1, const idVec3 &v2, const float l ); -}; - -extern idVec3 vec3_origin; -#define vec3_zero vec3_origin - -// Default constructor -ID_INLINE idVec3::idVec3( void ): - x(0.0f), // OrbWeaver: let's not leave stuff uninitialised - y(0.0f), - z(0.0f) -{ -} - -ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE float idVec3::operator[]( const int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float &idVec3::operator[]( const int index ) { - return ( &x )[ index ]; -} - -ID_INLINE void idVec3::Set( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE void idVec3::Zero( void ) { - x = y = z = 0.0f; -} - -ID_INLINE idVec3 idVec3::operator-() const { - return idVec3( -x, -y, -z ); -} - -ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) { - x = a.x; - y = a.y; - z = a.z; - return *this; -} - -ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const { - return idVec3( x - a.x, y - a.y, z - a.z ); -} - -ID_INLINE float idVec3::operator*( const idVec3 &a ) const { - return x * a.x + y * a.y + z * a.z; -} - -ID_INLINE idVec3 idVec3::operator*( const float a ) const { - return idVec3( x * a, y * a, z * a ); -} - -ID_INLINE idVec3 idVec3::operator/( const float a ) const { - float inva = 1.0f / a; - return idVec3( x * inva, y * inva, z * inva ); -} - -ID_INLINE idVec3 operator*( const float a, const idVec3 b ) { - return idVec3( b.x * a, b.y * a, b.z * a ); -} - -ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const { - return idVec3( x + a.x, y + a.y, z + a.z ); -} - -ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) { - x += a.x; - y += a.y; - z += a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator/=( const idVec3 &a ) { - x /= a.x; - y /= a.y; - z /= a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator/=( const float a ) { - float inva = 1.0f / a; - x *= inva; - y *= inva; - z *= inva; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator*=( const float a ) { - x *= a; - y *= a; - z *= a; - - return *this; -} - -ID_INLINE idVec3 &idVec3::MulCW( const idVec3 &a ) { - x *= a.x; - y *= a.y; - z *= a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::DivCW( const idVec3 &a ) { - x /= a.x; - y /= a.y; - z /= a.z; - - return *this; -} - -ID_INLINE bool idVec3::Compare( const idVec3 &a ) const { - return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) ); -} - -ID_INLINE bool idVec3::Compare( const idVec3 &a, const float epsilon ) const { - if ( idMath::Fabs( x - a.x ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( y - a.y ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( z - a.z ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idVec3::operator==( const idVec3 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idVec3::operator!=( const idVec3 &a ) const { - return !Compare( a ); -} - -ID_INLINE float idVec3::NormalizeFast( void ) { - float sqrLength, invLength; - - sqrLength = x * x + y * y + z * z; - invLength = idMath::RSqrt( sqrLength ); - x *= invLength; - y *= invLength; - z *= invLength; - return invLength * sqrLength; -} - -ID_INLINE bool idVec3::FixDegenerateNormal( void ) { - if ( x == 0.0f ) { - if ( y == 0.0f ) { - if ( z > 0.0f ) { - if ( z != 1.0f ) { - z = 1.0f; - return true; - } - } else { - if ( z != -1.0f ) { - z = -1.0f; - return true; - } - } - return false; - } else if ( z == 0.0f ) { - if ( y > 0.0f ) { - if ( y != 1.0f ) { - y = 1.0f; - return true; - } - } else { - if ( y != -1.0f ) { - y = -1.0f; - return true; - } - } - return false; - } - } else if ( y == 0.0f ) { - if ( z == 0.0f ) { - if ( x > 0.0f ) { - if ( x != 1.0f ) { - x = 1.0f; - return true; - } - } else { - if ( x != -1.0f ) { - x = -1.0f; - return true; - } - } - return false; - } - } - if ( idMath::Fabs( x ) == 1.0f ) { - if ( y != 0.0f || z != 0.0f ) { - y = z = 0.0f; - return true; - } - return false; - } else if ( idMath::Fabs( y ) == 1.0f ) { - if ( x != 0.0f || z != 0.0f ) { - x = z = 0.0f; - return true; - } - return false; - } else if ( idMath::Fabs( z ) == 1.0f ) { - if ( x != 0.0f || y != 0.0f ) { - x = y = 0.0f; - return true; - } - return false; - } - return false; -} - -ID_INLINE bool idVec3::FixDenormals( void ) { - bool denormal = false; - if ( fabs( x ) < 1e-30f ) { - x = 0.0f; - denormal = true; - } - if ( fabs( y ) < 1e-30f ) { - y = 0.0f; - denormal = true; - } - if ( fabs( z ) < 1e-30f ) { - z = 0.0f; - denormal = true; - } - return denormal; -} - -ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const { - return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x ); -} - -ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) { - x = a.y * b.z - a.z * b.y; - y = a.z * b.x - a.x * b.z; - z = a.x * b.y - a.y * b.x; - - return *this; -} - -ID_INLINE float idVec3::Length( void ) const { - return ( float )idMath::Sqrt( x * x + y * y + z * z ); -} - -ID_INLINE float idVec3::LengthSqr( void ) const { - return ( x * x + y * y + z * z ); -} - -ID_INLINE float idVec3::LengthFast( void ) const { - float sqrLength; - - sqrLength = x * x + y * y + z * z; - return sqrLength * idMath::RSqrt( sqrLength ); -} - -ID_INLINE float idVec3::Normalize( void ) { - float sqrLength, invLength; - - sqrLength = x * x + y * y + z * z; - invLength = idMath::InvSqrt( sqrLength ); - x *= invLength; - y *= invLength; - z *= invLength; - return invLength * sqrLength; -} - -ID_INLINE idVec3 &idVec3::Truncate( float length ) { - float length2; - float ilength; - - if ( !length ) { - Zero(); - } - else { - length2 = LengthSqr(); - if ( length2 > length * length ) { - ilength = length * idMath::InvSqrt( length2 ); - x *= ilength; - y *= ilength; - z *= ilength; - } - } - - return *this; -} - -ID_INLINE void idVec3::Clamp( const idVec3 &min, const idVec3 &max ) { - if ( x < min.x ) { - x = min.x; - } else if ( x > max.x ) { - x = max.x; - } - if ( y < min.y ) { - y = min.y; - } else if ( y > max.y ) { - y = max.y; - } - if ( z < min.z ) { - z = min.z; - } else if ( z > max.z ) { - z = max.z; - } -} - -ID_INLINE void idVec3::Snap( void ) { - x = floor( x + 0.5f ); - y = floor( y + 0.5f ); - z = floor( z + 0.5f ); -} - -ID_INLINE void idVec3::SnapInt( void ) { - x = float( int( x ) ); - y = float( int( y ) ); - z = float( int( z ) ); -} - -ID_INLINE int idVec3::GetDimension( void ) const { - return 3; -} - -ID_INLINE const idVec2 &idVec3::ToVec2( void ) const { - return *reinterpret_cast(this); -} - -ID_INLINE idVec2 &idVec3::ToVec2( void ) { - return *reinterpret_cast(this); -} - -ID_INLINE const float *idVec3::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idVec3::ToFloatPtr( void ) { - return &x; -} - -ID_INLINE void idVec3::NormalVectors( idVec3 &left, idVec3 &down ) const { - float d; - - d = x * x + y * y; - if ( !d ) { - left[0] = 1; - left[1] = 0; - left[2] = 0; - } else { - d = idMath::InvSqrt( d ); - left[0] = -y * d; - left[1] = x * d; - left[2] = 0; - } - down = left.Cross( *this ); -} - -ID_INLINE void idVec3::OrthogonalBasis( idVec3 &left, idVec3 &up ) const { - float l, s; - - if ( idMath::Fabs( z ) > 0.7f ) { - l = y * y + z * z; - s = idMath::InvSqrt( l ); - up[0] = 0; - up[1] = z * s; - up[2] = -y * s; - left[0] = l * s; - left[1] = -x * up[2]; - left[2] = x * up[1]; - } - else { - l = x * x + y * y; - s = idMath::InvSqrt( l ); - left[0] = -y * s; - left[1] = x * s; - left[2] = 0; - up[0] = -z * left[1]; - up[1] = z * left[0]; - up[2] = l * s; - } -} - -ID_INLINE void idVec3::ProjectOntoPlane( const idVec3 &normal, const float overBounce ) { - float backoff; - - backoff = *this * normal; - - if ( overBounce != 1.0 ) { - if ( backoff < 0 ) { - backoff *= overBounce; - } else { - backoff /= overBounce; - } - } - - *this -= backoff * normal; -} - -ID_INLINE bool idVec3::ProjectAlongPlane( const idVec3 &normal, const float epsilon, const float overBounce ) { - idVec3 cross; - float len; - - cross = this->Cross( normal ).Cross( (*this) ); - // normalize so a fixed epsilon can be used - cross.Normalize(); - len = normal * cross; - if ( idMath::Fabs( len ) < epsilon ) { - return false; - } - cross *= overBounce * ( normal * (*this) ) / len; - (*this) -= cross; - return true; -} - - -//=============================================================== -// -// idVec4 - 4D vector -// -//=============================================================== - -class idVec4 { -public: - float x; - float y; - float z; - float w; - - idVec4( void ); - explicit idVec4( const float x, const float y, const float z, const float w ); - - void Set( const float x, const float y, const float z, const float w ); - void Zero( void ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idVec4 operator-() const; - float operator*( const idVec4 &a ) const; - idVec4 operator*( const float a ) const; - idVec4 operator/( const float a ) const; - idVec4 operator+( const idVec4 &a ) const; - idVec4 operator-( const idVec4 &a ) const; - idVec4 & operator+=( const idVec4 &a ); - idVec4 & operator-=( const idVec4 &a ); - idVec4 & operator/=( const idVec4 &a ); - idVec4 & operator/=( const float a ); - idVec4 & operator*=( const float a ); - - friend idVec4 operator*( const float a, const idVec4 b ); - - bool Compare( const idVec4 &a ) const; // exact compare, no epsilon - bool Compare( const idVec4 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idVec4 &a ) const; // exact compare, no epsilon - bool operator!=( const idVec4 &a ) const; // exact compare, no epsilon - - float Length( void ) const; - float LengthSqr( void ) const; - float Normalize( void ); // returns length - float NormalizeFast( void ); // returns length - - int GetDimension( void ) const; - - const idVec2 & ToVec2( void ) const; - idVec2 & ToVec2( void ); - const idVec3 & ToVec3( void ) const; - idVec3 & ToVec3( void ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - void Lerp( const idVec4 &v1, const idVec4 &v2, const float l ); -}; - -extern idVec4 vec4_origin; -#define vec4_zero vec4_origin - -ID_INLINE idVec4::idVec4( void ) { -} - -ID_INLINE idVec4::idVec4( const float x, const float y, const float z, const float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -ID_INLINE void idVec4::Set( const float x, const float y, const float z, const float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -ID_INLINE void idVec4::Zero( void ) { - x = y = z = w = 0.0f; -} - -ID_INLINE float idVec4::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec4::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec4 idVec4::operator-() const { - return idVec4( -x, -y, -z, -w ); -} - -ID_INLINE idVec4 idVec4::operator-( const idVec4 &a ) const { - return idVec4( x - a.x, y - a.y, z - a.z, w - a.w ); -} - -ID_INLINE float idVec4::operator*( const idVec4 &a ) const { - return x * a.x + y * a.y + z * a.z + w * a.w; -} - -ID_INLINE idVec4 idVec4::operator*( const float a ) const { - return idVec4( x * a, y * a, z * a, w * a ); -} - -ID_INLINE idVec4 idVec4::operator/( const float a ) const { - float inva = 1.0f / a; - return idVec4( x * inva, y * inva, z * inva, w * inva ); -} - -ID_INLINE idVec4 operator*( const float a, const idVec4 b ) { - return idVec4( b.x * a, b.y * a, b.z * a, b.w * a ); -} - -ID_INLINE idVec4 idVec4::operator+( const idVec4 &a ) const { - return idVec4( x + a.x, y + a.y, z + a.z, w + a.w ); -} - -ID_INLINE idVec4 &idVec4::operator+=( const idVec4 &a ) { - x += a.x; - y += a.y; - z += a.z; - w += a.w; - - return *this; -} - -ID_INLINE idVec4 &idVec4::operator/=( const idVec4 &a ) { - x /= a.x; - y /= a.y; - z /= a.z; - w /= a.w; - - return *this; -} - -ID_INLINE idVec4 &idVec4::operator/=( const float a ) { - float inva = 1.0f / a; - x *= inva; - y *= inva; - z *= inva; - w *= inva; - - return *this; -} - -ID_INLINE idVec4 &idVec4::operator-=( const idVec4 &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - w -= a.w; - - return *this; -} - -ID_INLINE idVec4 &idVec4::operator*=( const float a ) { - x *= a; - y *= a; - z *= a; - w *= a; - - return *this; -} - -ID_INLINE bool idVec4::Compare( const idVec4 &a ) const { - return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && w == a.w ); -} - -ID_INLINE bool idVec4::Compare( const idVec4 &a, const float epsilon ) const { - if ( idMath::Fabs( x - a.x ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( y - a.y ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( z - a.z ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( w - a.w ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idVec4::operator==( const idVec4 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idVec4::operator!=( const idVec4 &a ) const { - return !Compare( a ); -} - -ID_INLINE float idVec4::Length( void ) const { - return ( float )idMath::Sqrt( x * x + y * y + z * z + w * w ); -} - -ID_INLINE float idVec4::LengthSqr( void ) const { - return ( x * x + y * y + z * z + w * w ); -} - -ID_INLINE float idVec4::Normalize( void ) { - float sqrLength, invLength; - - sqrLength = x * x + y * y + z * z + w * w; - invLength = idMath::InvSqrt( sqrLength ); - x *= invLength; - y *= invLength; - z *= invLength; - w *= invLength; - return invLength * sqrLength; -} - -ID_INLINE float idVec4::NormalizeFast( void ) { - float sqrLength, invLength; - - sqrLength = x * x + y * y + z * z + w * w; - invLength = idMath::RSqrt( sqrLength ); - x *= invLength; - y *= invLength; - z *= invLength; - w *= invLength; - return invLength * sqrLength; -} - -ID_INLINE int idVec4::GetDimension( void ) const { - return 4; -} - -ID_INLINE const idVec2 &idVec4::ToVec2( void ) const { - return *reinterpret_cast(this); -} - -ID_INLINE idVec2 &idVec4::ToVec2( void ) { - return *reinterpret_cast(this); -} - -ID_INLINE const idVec3 &idVec4::ToVec3( void ) const { - return *reinterpret_cast(this); -} - -ID_INLINE idVec3 &idVec4::ToVec3( void ) { - return *reinterpret_cast(this); -} - -ID_INLINE const float *idVec4::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idVec4::ToFloatPtr( void ) { - return &x; -} - - -//=============================================================== -// -// idVec5 - 5D vector -// -//=============================================================== - -class idVec5 { -public: - float x; - float y; - float z; - float s; - float t; - - idVec5( void ); - explicit idVec5( const idVec3 &xyz, const idVec2 &st ); - explicit idVec5( const float x, const float y, const float z, const float s, const float t ); - - float operator[]( int index ) const; - float & operator[]( int index ); - idVec5 & operator=( const idVec3 &a ); - - int GetDimension( void ) const; - - const idVec3 & ToVec3( void ) const; - idVec3 & ToVec3( void ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - - void Lerp( const idVec5 &v1, const idVec5 &v2, const float l ); -}; - -extern idVec5 vec5_origin; -#define vec5_zero vec5_origin - -ID_INLINE idVec5::idVec5( void ) { -} - -ID_INLINE idVec5::idVec5( const idVec3 &xyz, const idVec2 &st ) { - x = xyz.x; - y = xyz.y; - z = xyz.z; - s = st[0]; - t = st[1]; -} - -ID_INLINE idVec5::idVec5( const float x, const float y, const float z, const float s, const float t ) { - this->x = x; - this->y = y; - this->z = z; - this->s = s; - this->t = t; -} - -ID_INLINE float idVec5::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec5::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec5 &idVec5::operator=( const idVec3 &a ) { - x = a.x; - y = a.y; - z = a.z; - s = t = 0; - return *this; -} - -ID_INLINE int idVec5::GetDimension( void ) const { - return 5; -} - -ID_INLINE const idVec3 &idVec5::ToVec3( void ) const { - return *reinterpret_cast(this); -} - -ID_INLINE idVec3 &idVec5::ToVec3( void ) { - return *reinterpret_cast(this); -} - -ID_INLINE const float *idVec5::ToFloatPtr( void ) const { - return &x; -} - -ID_INLINE float *idVec5::ToFloatPtr( void ) { - return &x; -} - - -//=============================================================== -// -// idVec6 - 6D vector -// -//=============================================================== - -class idVec6 { -public: - idVec6( void ); - explicit idVec6( const float *a ); - explicit idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); - - void Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ); - void Zero( void ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idVec6 operator-() const; - idVec6 operator*( const float a ) const; - idVec6 operator/( const float a ) const; - float operator*( const idVec6 &a ) const; - idVec6 operator-( const idVec6 &a ) const; - idVec6 operator+( const idVec6 &a ) const; - idVec6 & operator*=( const float a ); - idVec6 & operator/=( const float a ); - idVec6 & operator+=( const idVec6 &a ); - idVec6 & operator-=( const idVec6 &a ); - - friend idVec6 operator*( const float a, const idVec6 b ); - - bool Compare( const idVec6 &a ) const; // exact compare, no epsilon - bool Compare( const idVec6 &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idVec6 &a ) const; // exact compare, no epsilon - bool operator!=( const idVec6 &a ) const; // exact compare, no epsilon - - float Length( void ) const; - float LengthSqr( void ) const; - float Normalize( void ); // returns length - float NormalizeFast( void ); // returns length - - int GetDimension( void ) const; - - const idVec3 & SubVec3( int index ) const; - idVec3 & SubVec3( int index ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - float p[6]; -}; - -extern idVec6 vec6_origin; -#define vec6_zero vec6_origin -extern idVec6 vec6_infinity; - -ID_INLINE idVec6::idVec6( void ) { -} - -ID_INLINE idVec6::idVec6( const float *a ) { - memcpy( p, a, 6 * sizeof( float ) ); -} - -ID_INLINE idVec6::idVec6( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { - p[0] = a1; - p[1] = a2; - p[2] = a3; - p[3] = a4; - p[4] = a5; - p[5] = a6; -} - -ID_INLINE idVec6 idVec6::operator-() const { - return idVec6( -p[0], -p[1], -p[2], -p[3], -p[4], -p[5] ); -} - -ID_INLINE float idVec6::operator[]( const int index ) const { - return p[index]; -} - -ID_INLINE float &idVec6::operator[]( const int index ) { - return p[index]; -} - -ID_INLINE idVec6 idVec6::operator*( const float a ) const { - return idVec6( p[0]*a, p[1]*a, p[2]*a, p[3]*a, p[4]*a, p[5]*a ); -} - -ID_INLINE float idVec6::operator*( const idVec6 &a ) const { - return p[0] * a[0] + p[1] * a[1] + p[2] * a[2] + p[3] * a[3] + p[4] * a[4] + p[5] * a[5]; -} - -ID_INLINE idVec6 idVec6::operator/( const float a ) const { - float inva; - - assert( a != 0.0f ); - inva = 1.0f / a; - return idVec6( p[0]*inva, p[1]*inva, p[2]*inva, p[3]*inva, p[4]*inva, p[5]*inva ); -} - -ID_INLINE idVec6 idVec6::operator+( const idVec6 &a ) const { - return idVec6( p[0] + a[0], p[1] + a[1], p[2] + a[2], p[3] + a[3], p[4] + a[4], p[5] + a[5] ); -} - -ID_INLINE idVec6 idVec6::operator-( const idVec6 &a ) const { - return idVec6( p[0] - a[0], p[1] - a[1], p[2] - a[2], p[3] - a[3], p[4] - a[4], p[5] - a[5] ); -} - -ID_INLINE idVec6 &idVec6::operator*=( const float a ) { - p[0] *= a; - p[1] *= a; - p[2] *= a; - p[3] *= a; - p[4] *= a; - p[5] *= a; - return *this; -} - -ID_INLINE idVec6 &idVec6::operator/=( const float a ) { - float inva; - - assert( a != 0.0f ); - inva = 1.0f / a; - p[0] *= inva; - p[1] *= inva; - p[2] *= inva; - p[3] *= inva; - p[4] *= inva; - p[5] *= inva; - return *this; -} - -ID_INLINE idVec6 &idVec6::operator+=( const idVec6 &a ) { - p[0] += a[0]; - p[1] += a[1]; - p[2] += a[2]; - p[3] += a[3]; - p[4] += a[4]; - p[5] += a[5]; - return *this; -} - -ID_INLINE idVec6 &idVec6::operator-=( const idVec6 &a ) { - p[0] -= a[0]; - p[1] -= a[1]; - p[2] -= a[2]; - p[3] -= a[3]; - p[4] -= a[4]; - p[5] -= a[5]; - return *this; -} - -ID_INLINE idVec6 operator*( const float a, const idVec6 b ) { - return b * a; -} - -ID_INLINE bool idVec6::Compare( const idVec6 &a ) const { - return ( ( p[0] == a[0] ) && ( p[1] == a[1] ) && ( p[2] == a[2] ) && - ( p[3] == a[3] ) && ( p[4] == a[4] ) && ( p[5] == a[5] ) ); -} - -ID_INLINE bool idVec6::Compare( const idVec6 &a, const float epsilon ) const { - if ( idMath::Fabs( p[0] - a[0] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[1] - a[1] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[2] - a[2] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[3] - a[3] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[4] - a[4] ) > epsilon ) { - return false; - } - - if ( idMath::Fabs( p[5] - a[5] ) > epsilon ) { - return false; - } - - return true; -} - -ID_INLINE bool idVec6::operator==( const idVec6 &a ) const { - return Compare( a ); -} - -ID_INLINE bool idVec6::operator!=( const idVec6 &a ) const { - return !Compare( a ); -} - -ID_INLINE void idVec6::Set( const float a1, const float a2, const float a3, const float a4, const float a5, const float a6 ) { - p[0] = a1; - p[1] = a2; - p[2] = a3; - p[3] = a4; - p[4] = a5; - p[5] = a6; -} - -ID_INLINE void idVec6::Zero( void ) { - p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0.0f; -} - -ID_INLINE float idVec6::Length( void ) const { - return ( float )idMath::Sqrt( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] ); -} - -ID_INLINE float idVec6::LengthSqr( void ) const { - return ( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5] ); -} - -ID_INLINE float idVec6::Normalize( void ) { - float sqrLength, invLength; - - sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5]; - invLength = idMath::InvSqrt( sqrLength ); - p[0] *= invLength; - p[1] *= invLength; - p[2] *= invLength; - p[3] *= invLength; - p[4] *= invLength; - p[5] *= invLength; - return invLength * sqrLength; -} - -ID_INLINE float idVec6::NormalizeFast( void ) { - float sqrLength, invLength; - - sqrLength = p[0] * p[0] + p[1] * p[1] + p[2] * p[2] + p[3] * p[3] + p[4] * p[4] + p[5] * p[5]; - invLength = idMath::RSqrt( sqrLength ); - p[0] *= invLength; - p[1] *= invLength; - p[2] *= invLength; - p[3] *= invLength; - p[4] *= invLength; - p[5] *= invLength; - return invLength * sqrLength; -} - -ID_INLINE int idVec6::GetDimension( void ) const { - return 6; -} - -ID_INLINE const idVec3 &idVec6::SubVec3( int index ) const { - return *reinterpret_cast(p + index * 3); -} - -ID_INLINE idVec3 &idVec6::SubVec3( int index ) { - return *reinterpret_cast(p + index * 3); -} - -ID_INLINE const float *idVec6::ToFloatPtr( void ) const { - return p; -} - -ID_INLINE float *idVec6::ToFloatPtr( void ) { - return p; -} - - -//=============================================================== -// -// idVecX - arbitrary sized vector -// -// The vector lives on 16 byte aligned and 16 byte padded memory. -// -// NOTE: due to the temporary memory pool idVecX cannot be used by multiple threads -// -//=============================================================== - -#define VECX_MAX_TEMP 1024 -#define VECX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) ) -#define VECX_CLEAREND() int s = size; while( s < ( ( s + 3) & ~3 ) ) { p[s++] = 0.0f; } -#define VECX_ALLOCA( n ) ( (float *) _alloca16( VECX_QUAD( n ) ) ) -#define VECX_SIMD - -class idVecX { - friend class idMatX; - -public: - idVecX( void ); - explicit idVecX( int length ); - explicit idVecX( int length, float *data ); - ~idVecX( void ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idVecX operator-() const; - idVecX & operator=( const idVecX &a ); - idVecX operator*( const float a ) const; - idVecX operator/( const float a ) const; - float operator*( const idVecX &a ) const; - idVecX operator-( const idVecX &a ) const; - idVecX operator+( const idVecX &a ) const; - idVecX & operator*=( const float a ); - idVecX & operator/=( const float a ); - idVecX & operator+=( const idVecX &a ); - idVecX & operator-=( const idVecX &a ); - - friend idVecX operator*( const float a, const idVecX b ); - - bool Compare( const idVecX &a ) const; // exact compare, no epsilon - bool Compare( const idVecX &a, const float epsilon ) const; // compare with epsilon - bool operator==( const idVecX &a ) const; // exact compare, no epsilon - bool operator!=( const idVecX &a ) const; // exact compare, no epsilon - - void SetSize( int size ); - void ChangeSize( int size, bool makeZero = false ); - int GetSize( void ) const { return size; } - void SetData( int length, float *data ); - void Zero( void ); - void Zero( int length ); - void Random( int seed, float l = 0.0f, float u = 1.0f ); - void Random( int length, int seed, float l = 0.0f, float u = 1.0f ); - void Negate( void ); - void Clamp( float min, float max ); - idVecX & SwapElements( int e1, int e2 ); - - float Length( void ) const; - float LengthSqr( void ) const; - idVecX Normalize( void ) const; - float NormalizeSelf( void ); - - int GetDimension( void ) const; - - const idVec3 & SubVec3( int index ) const; - idVec3 & SubVec3( int index ); - const idVec6 & SubVec6( int index ) const; - idVec6 & SubVec6( int index ); - const float * ToFloatPtr( void ) const; - float * ToFloatPtr( void ); - const char * ToString( int precision = 2 ) const; - -private: - int size; // size of the vector - int alloced; // if -1 p points to data set with SetData - float * p; // memory the vector is stored - - static float temp[VECX_MAX_TEMP+4]; // used to store intermediate results - static float * tempPtr; // pointer to 16 byte aligned temporary memory - static int tempIndex; // index into memory pool, wraps around - -private: - void SetTempSize( int size ); -}; - - -ID_INLINE idVecX::idVecX( void ) { - size = alloced = 0; - p = NULL; -} - -ID_INLINE idVecX::idVecX( int length ) { - size = alloced = 0; - p = NULL; - SetSize( length ); -} - -ID_INLINE idVecX::idVecX( int length, float *data ) { - size = alloced = 0; - p = NULL; - SetData( length, data ); -} - -ID_INLINE idVecX::~idVecX( void ) { - // if not temp memory - if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) { - Mem_Free16( p ); - } -} - -ID_INLINE float idVecX::operator[]( const int index ) const { - assert( index >= 0 && index < size ); - return p[index]; -} - -ID_INLINE float &idVecX::operator[]( const int index ) { - assert( index >= 0 && index < size ); - return p[index]; -} - -ID_INLINE idVecX idVecX::operator-() const { - int i; - idVecX m; - - m.SetTempSize( size ); - for ( i = 0; i < size; i++ ) { - m.p[i] = -p[i]; - } - return m; -} - -ID_INLINE idVecX &idVecX::operator=( const idVecX &a ) { - SetSize( a.size ); -#ifdef VECX_SIMD - SIMDProcessor->Copy16( p, a.p, a.size ); -#else - memcpy( p, a.p, a.size * sizeof( float ) ); -#endif - idVecX::tempIndex = 0; - return *this; -} - -ID_INLINE idVecX idVecX::operator+( const idVecX &a ) const { - idVecX m; - - assert( size == a.size ); - m.SetTempSize( size ); -#ifdef VECX_SIMD - SIMDProcessor->Add16( m.p, p, a.p, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - m.p[i] = p[i] + a.p[i]; - } -#endif - return m; -} - -ID_INLINE idVecX idVecX::operator-( const idVecX &a ) const { - idVecX m; - - assert( size == a.size ); - m.SetTempSize( size ); -#ifdef VECX_SIMD - SIMDProcessor->Sub16( m.p, p, a.p, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - m.p[i] = p[i] - a.p[i]; - } -#endif - return m; -} - -ID_INLINE idVecX &idVecX::operator+=( const idVecX &a ) { - assert( size == a.size ); -#ifdef VECX_SIMD - SIMDProcessor->AddAssign16( p, a.p, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - p[i] += a.p[i]; - } -#endif - idVecX::tempIndex = 0; - return *this; -} - -ID_INLINE idVecX &idVecX::operator-=( const idVecX &a ) { - assert( size == a.size ); -#ifdef VECX_SIMD - SIMDProcessor->SubAssign16( p, a.p, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - p[i] -= a.p[i]; - } -#endif - idVecX::tempIndex = 0; - return *this; -} - -ID_INLINE idVecX idVecX::operator*( const float a ) const { - idVecX m; - - m.SetTempSize( size ); -#ifdef VECX_SIMD - SIMDProcessor->Mul16( m.p, p, a, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - m.p[i] = p[i] * a; - } -#endif - return m; -} - -ID_INLINE idVecX &idVecX::operator*=( const float a ) { -#ifdef VECX_SIMD - SIMDProcessor->MulAssign16( p, a, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - p[i] *= a; - } -#endif - return *this; -} - -ID_INLINE idVecX idVecX::operator/( const float a ) const { - assert( a != 0.0f ); - return (*this) * ( 1.0f / a ); -} - -ID_INLINE idVecX &idVecX::operator/=( const float a ) { - assert( a != 0.0f ); - (*this) *= ( 1.0f / a ); - return *this; -} - -ID_INLINE idVecX operator*( const float a, const idVecX b ) { - return b * a; -} - -ID_INLINE float idVecX::operator*( const idVecX &a ) const { - int i; - float sum = 0.0f; - - assert( size == a.size ); - for ( i = 0; i < size; i++ ) { - sum += p[i] * a.p[i]; - } - return sum; -} - -ID_INLINE bool idVecX::Compare( const idVecX &a ) const { - int i; - - assert( size == a.size ); - for ( i = 0; i < size; i++ ) { - if ( p[i] != a.p[i] ) { - return false; - } - } - return true; -} - -ID_INLINE bool idVecX::Compare( const idVecX &a, const float epsilon ) const { - int i; - - assert( size == a.size ); - for ( i = 0; i < size; i++ ) { - if ( idMath::Fabs( p[i] - a.p[i] ) > epsilon ) { - return false; - } - } - return true; -} - -ID_INLINE bool idVecX::operator==( const idVecX &a ) const { - return Compare( a ); -} - -ID_INLINE bool idVecX::operator!=( const idVecX &a ) const { - return !Compare( a ); -} - -ID_INLINE void idVecX::SetSize( int newSize ) { - int alloc = ( newSize + 3 ) & ~3; - if ( alloc > alloced && alloced != -1 ) { - if ( p ) { - Mem_Free16( p ); - } - p = (float *) Mem_Alloc16( alloc * sizeof( float ) ); - alloced = alloc; - } - size = newSize; - VECX_CLEAREND(); -} - -ID_INLINE void idVecX::ChangeSize( int newSize, bool makeZero ) { - int alloc = ( newSize + 3 ) & ~3; - if ( alloc > alloced && alloced != -1 ) { - float *oldVec = p; - p = (float *) Mem_Alloc16( alloc * sizeof( float ) ); - alloced = alloc; - if ( oldVec ) { - for ( int i = 0; i < size; i++ ) { - p[i] = oldVec[i]; - } - Mem_Free16( oldVec ); - } - if ( makeZero ) { - // zero any new elements - for ( int i = size; i < newSize; i++ ) { - p[i] = 0.0f; - } - } - } - size = newSize; - VECX_CLEAREND(); -} - -ID_INLINE void idVecX::SetTempSize( int newSize ) { - - size = newSize; - alloced = ( newSize + 3 ) & ~3; - assert( alloced < VECX_MAX_TEMP ); - if ( idVecX::tempIndex + alloced > VECX_MAX_TEMP ) { - idVecX::tempIndex = 0; - } - p = idVecX::tempPtr + idVecX::tempIndex; - idVecX::tempIndex += alloced; - VECX_CLEAREND(); -} - -ID_INLINE void idVecX::SetData( int length, float *data ) { - if ( p && ( p < idVecX::tempPtr || p >= idVecX::tempPtr + VECX_MAX_TEMP ) && alloced != -1 ) { - Mem_Free16( p ); - } - assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned - p = data; - size = length; - alloced = -1; - VECX_CLEAREND(); -} - -ID_INLINE void idVecX::Zero( void ) { -#ifdef VECX_SIMD - SIMDProcessor->Zero16( p, size ); -#else - memset( p, 0, size * sizeof( float ) ); -#endif -} - -ID_INLINE void idVecX::Zero( int length ) { - SetSize( length ); -#ifdef VECX_SIMD - SIMDProcessor->Zero16( p, length ); -#else - memset( p, 0, size * sizeof( float ) ); -#endif -} - -ID_INLINE void idVecX::Random( int seed, float l, float u ) { - int i; - float c; - idRandom rnd( seed ); - - c = u - l; - for ( i = 0; i < size; i++ ) { - p[i] = l + rnd.RandomFloat() * c; - } -} - -ID_INLINE void idVecX::Random( int length, int seed, float l, float u ) { - int i; - float c; - idRandom rnd( seed ); - - SetSize( length ); - c = u - l; - for ( i = 0; i < size; i++ ) { - p[i] = l + rnd.RandomFloat() * c; - } -} - -ID_INLINE void idVecX::Negate( void ) { -#ifdef VECX_SIMD - SIMDProcessor->Negate16( p, size ); -#else - int i; - for ( i = 0; i < size; i++ ) { - p[i] = -p[i]; - } -#endif -} - -ID_INLINE void idVecX::Clamp( float min, float max ) { - int i; - for ( i = 0; i < size; i++ ) { - if ( p[i] < min ) { - p[i] = min; - } else if ( p[i] > max ) { - p[i] = max; - } - } -} - -ID_INLINE idVecX &idVecX::SwapElements( int e1, int e2 ) { - float tmp; - tmp = p[e1]; - p[e1] = p[e2]; - p[e2] = tmp; - return *this; -} - -ID_INLINE float idVecX::Length( void ) const { - int i; - float sum = 0.0f; - - for ( i = 0; i < size; i++ ) { - sum += p[i] * p[i]; - } - return idMath::Sqrt( sum ); -} - -ID_INLINE float idVecX::LengthSqr( void ) const { - int i; - float sum = 0.0f; - - for ( i = 0; i < size; i++ ) { - sum += p[i] * p[i]; - } - return sum; -} - -ID_INLINE idVecX idVecX::Normalize( void ) const { - int i; - idVecX m; - float invSqrt, sum = 0.0f; - - m.SetTempSize( size ); - for ( i = 0; i < size; i++ ) { - sum += p[i] * p[i]; - } - invSqrt = idMath::InvSqrt( sum ); - for ( i = 0; i < size; i++ ) { - m.p[i] = p[i] * invSqrt; - } - return m; -} - -ID_INLINE float idVecX::NormalizeSelf( void ) { - float invSqrt, sum = 0.0f; - int i; - for ( i = 0; i < size; i++ ) { - sum += p[i] * p[i]; - } - invSqrt = idMath::InvSqrt( sum ); - for ( i = 0; i < size; i++ ) { - p[i] *= invSqrt; - } - return invSqrt * sum; -} - -ID_INLINE int idVecX::GetDimension( void ) const { - return size; -} - -ID_INLINE idVec3 &idVecX::SubVec3( int index ) { - assert( index >= 0 && index * 3 + 3 <= size ); - return *reinterpret_cast(p + index * 3); -} - -ID_INLINE const idVec3 &idVecX::SubVec3( int index ) const { - assert( index >= 0 && index * 3 + 3 <= size ); - return *reinterpret_cast(p + index * 3); -} - -ID_INLINE idVec6 &idVecX::SubVec6( int index ) { - assert( index >= 0 && index * 6 + 6 <= size ); - return *reinterpret_cast(p + index * 6); -} - -ID_INLINE const idVec6 &idVecX::SubVec6( int index ) const { - assert( index >= 0 && index * 6 + 6 <= size ); - return *reinterpret_cast(p + index * 6); -} - -ID_INLINE const float *idVecX::ToFloatPtr( void ) const { - return p; -} - -ID_INLINE float *idVecX::ToFloatPtr( void ) { - return p; -} - - -//=============================================================== -// -// idPolar3 -// -//=============================================================== - -class idPolar3 { -public: - float radius, theta, phi; - - idPolar3( void ); - explicit idPolar3( const float radius, const float theta, const float phi ); - explicit idPolar3( const idVec3 vec3 ); - - void Set( const float radius, const float theta, const float phi ); - - float operator[]( const int index ) const; - float & operator[]( const int index ); - idPolar3 operator-() const; - idPolar3 & operator=( const idPolar3 &a ); - - idVec3 ToVec3( void ) const; -}; - -ID_INLINE idPolar3::idPolar3( void ) { -} - -ID_INLINE idPolar3::idPolar3( const float radius, const float theta, const float phi ) { - assert( radius > 0 ); - this->radius = radius; - this->theta = theta; - this->phi = phi; -} - -ID_INLINE idPolar3::idPolar3( const idVec3 vec3 ) { - assert( vec3.x > 0 ); - this->radius = vec3.x; - this->theta = vec3.y; - this->phi = vec3.z; -} - -ID_INLINE void idPolar3::Set( const float radius, const float theta, const float phi ) { - assert( radius > 0 ); - this->radius = radius; - this->theta = theta; - this->phi = phi; -} - -ID_INLINE float idPolar3::operator[]( const int index ) const { - return ( &radius )[ index ]; -} - -ID_INLINE float &idPolar3::operator[]( const int index ) { - return ( &radius )[ index ]; -} - -ID_INLINE idPolar3 idPolar3::operator-() const { - return idPolar3( radius, -theta, -phi ); -} - -ID_INLINE idPolar3 &idPolar3::operator=( const idPolar3 &a ) { - radius = a.radius; - theta = a.theta; - phi = a.phi; - return *this; -} - -ID_INLINE idVec3 idPolar3::ToVec3( void ) const { - float sp, cp, st, ct; - idMath::SinCos( phi, sp, cp ); - idMath::SinCos( theta, st, ct ); - return idVec3( cp * radius * ct, cp * radius * st, radius * sp ); -} - - -/* -=============================================================================== - - Old 3D vector macros, should no longer be used. - -=============================================================================== -*/ - -#define DotProduct( a, b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) -#define VectorSubtract( a, b, c ) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2]) -#define VectorAdd( a, b, c ) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2]) -#define VectorScale( v, s, o ) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#define VectorMA( v, s, b, o ) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s)) -#define VectorCopy( a, b ) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) - - -#endif /* !__MATH_VECTOR_H__ */ diff --git a/idlib/parser.cpp b/idlib/parser.cpp deleted file mode 100644 index 35634284c..000000000 --- a/idlib/parser.cpp +++ /dev/null @@ -1,3243 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#pragma warning( push ) -#pragma warning( disable : 4127 ) - -//#define DEBUG_EVAL -#define MAX_DEFINEPARMS 128 -#define DEFINEHASHSIZE 2048 - -#define TOKEN_FL_RECURSIVE_DEFINE 1 - -define_t * idParser::globaldefines; - -/* -================ -idParser::SetBaseFolder -================ -*/ -void idParser::SetBaseFolder( const char *path) { - idLexer::SetBaseFolder(path); -} - -/* -================ -idParser::AddGlobalDefine -================ -*/ -int idParser::AddGlobalDefine( const char *string ) { - define_t *define; - - define = idParser::DefineFromString(string); - if (!define) { - return false; - } - define->next = globaldefines; - globaldefines = define; - return true; -} - -/* -================ -idParser::RemoveGlobalDefine -================ -*/ -int idParser::RemoveGlobalDefine( const char *name ) { - define_t *d, *prev; - - for ( prev = NULL, d = idParser::globaldefines; d; prev = d, d = d->next ) { - if ( !strcmp( d->name, name ) ) { - break; - } - } - if ( d ) { - if ( prev ) { - prev->next = d->next; - } - else { - idParser::globaldefines = d->next; - } - idParser::FreeDefine( d ); - return true; - } - return false; -} - -/* -================ -idParser::RemoveAllGlobalDefines -================ -*/ -void idParser::RemoveAllGlobalDefines( void ) { - define_t *define; - - for ( define = globaldefines; define; define = globaldefines ) { - globaldefines = globaldefines->next; - idParser::FreeDefine(define); - } -} - - -/* -=============================================================================== - -idParser - -=============================================================================== -*/ - -/* -================ -idParser::PrintDefine -================ -*/ -void idParser::PrintDefine( define_t *define ) { - idLib::common->Printf("define->name = %s\n", define->name); - idLib::common->Printf("define->flags = %d\n", define->flags); - idLib::common->Printf("define->builtin = %d\n", define->builtin); - idLib::common->Printf("define->numparms = %d\n", define->numparms); -} - -/* -================ -PC_PrintDefineHashTable -================ -* / -static void PC_PrintDefineHashTable(define_t **definehash) { - int i; - define_t *d; - - for (i = 0; i < DEFINEHASHSIZE; i++) { - Log_Write("%4d:", i); - for (d = definehash[i]; d; d = d->hashnext) { - Log_Write(" %s", d->name); - } - Log_Write("\n"); - } -} -*/ - -/* -================ -PC_NameHash -================ -*/ -ID_INLINE int PC_NameHash( const char *name ) { - int hash, i; - - hash = 0; - for ( i = 0; name[i] != '\0'; i++ ) { - hash += name[i] * (119 + i); - } - hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (DEFINEHASHSIZE-1); - return hash; -} - -/* -================ -idParser::AddDefineToHash -================ -*/ -void idParser::AddDefineToHash( define_t *define, define_t **definehash ) { - int hash; - - hash = PC_NameHash(define->name); - define->hashnext = definehash[hash]; - definehash[hash] = define; -} - -/* -================ -FindHashedDefine -================ -*/ -define_t *idParser::FindHashedDefine( define_t **definehash, const char *name ) { - define_t *d; - int hash; - - hash = PC_NameHash(name); - for ( d = definehash[hash]; d; d = d->hashnext ) { - if ( !strcmp(d->name, name) ) { - return d; - } - } - return NULL; -} - -/* -================ -idParser::FindDefine -================ -*/ -define_t *idParser::FindDefine( define_t *defines, const char *name ) { - define_t *d; - - for ( d = defines; d; d = d->next ) { - if ( !strcmp(d->name, name) ) { - return d; - } - } - return NULL; -} - -/* -================ -idParser::FindDefineParm -================ -*/ -int idParser::FindDefineParm( define_t *define, const char *name ) { - idToken *p; - int i; - - i = 0; - for ( p = define->parms; p; p = p->next ) { - if ( (*p) == name ) { - return i; - } - i++; - } - return -1; -} - -/* -================ -idParser::CopyDefine -================ -*/ -define_t *idParser::CopyDefine( define_t *define ) { - define_t *newdefine; - idToken *token, *newtoken, *lasttoken; - - newdefine = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(define->name) + 1); - //copy the define name - newdefine->name = (char *) newdefine + sizeof(define_t); - strcpy(newdefine->name, define->name); - newdefine->flags = define->flags; - newdefine->builtin = define->builtin; - newdefine->numparms = define->numparms; - //the define is not linked - newdefine->next = NULL; - newdefine->hashnext = NULL; - //copy the define tokens - newdefine->tokens = NULL; - for (lasttoken = NULL, token = define->tokens; token; token = token->next) { - newtoken = new idToken(token); - newtoken->next = NULL; - if (lasttoken) lasttoken->next = newtoken; - else newdefine->tokens = newtoken; - lasttoken = newtoken; - } - //copy the define parameters - newdefine->parms = NULL; - for (lasttoken = NULL, token = define->parms; token; token = token->next) { - newtoken = new idToken(token); - newtoken->next = NULL; - if (lasttoken) lasttoken->next = newtoken; - else newdefine->parms = newtoken; - lasttoken = newtoken; - } - return newdefine; -} - -/* -================ -idParser::FreeDefine -================ -*/ -void idParser::FreeDefine( define_t *define ) { - idToken *t, *next; - - //free the define parameters - for (t = define->parms; t; t = next) { - next = t->next; - delete t; - } - //free the define tokens - for (t = define->tokens; t; t = next) { - next = t->next; - delete t; - } - //free the define - Mem_Free( define ); -} - -/* -================ -idParser::DefineFromString -================ -*/ -define_t *idParser::DefineFromString( const char *string ) { - idParser src; - define_t *def; - - if ( !src.LoadMemory(string, strlen(string), "*defineString") ) { - return NULL; - } - // create a define from the source - if ( !src.Directive_define() ) { - src.FreeSource(); - return NULL; - } - def = src.CopyFirstDefine(); - src.FreeSource(); - //if the define was created succesfully - return def; -} - -/* -================ -idParser::Error -================ -*/ -void idParser::Error( const char *str, ... ) const { - char text[MAX_STRING_CHARS]; - va_list ap; - - va_start(ap, str); - vsprintf(text, str, ap); - va_end(ap); - if ( idParser::scriptstack ) { - idParser::scriptstack->Error( text ); - } -} - -/* -================ -idParser::Warning -================ -*/ -void idParser::Warning( const char *str, ... ) const { - char text[MAX_STRING_CHARS]; - va_list ap; - - va_start(ap, str); - vsprintf(text, str, ap); - va_end(ap); - if ( idParser::scriptstack ) { - idParser::scriptstack->Warning( text ); - } -} - -/* -================ -idParser::PushIndent -================ -*/ -void idParser::PushIndent( int type, int skip ) { - indent_t *indent; - - indent = (indent_t *) Mem_Alloc(sizeof(indent_t)); - indent->type = type; - indent->script = idParser::scriptstack; - indent->skip = (skip != 0); - idParser::skip += indent->skip; - indent->next = idParser::indentstack; - idParser::indentstack = indent; -} - -/* -================ -idParser::PopIndent -================ -*/ -void idParser::PopIndent( int *type, int *skip ) { - indent_t *indent; - - *type = 0; - *skip = 0; - - indent = idParser::indentstack; - if (!indent) return; - - // must be an indent from the current script - if (idParser::indentstack->script != idParser::scriptstack) { - return; - } - - *type = indent->type; - *skip = indent->skip; - idParser::indentstack = idParser::indentstack->next; - idParser::skip -= indent->skip; - Mem_Free( indent ); -} - -/* -================ -idParser::PushScript -================ -*/ -void idParser::PushScript( idLexer *script ) { - idLexer *s; - - for ( s = idParser::scriptstack; s; s = s->next ) { - if ( !idStr::Icmp(s->GetFileName(), script->GetFileName()) ) { - idParser::Warning( "'%s' recursively included", script->GetFileName() ); - return; - } - } - //push the script on the script stack - script->next = idParser::scriptstack; - idParser::scriptstack = script; -} - -/* -================ -idParser::ReadSourceToken -================ -*/ -int idParser::ReadSourceToken( idToken *token ) { - idToken *t; - idLexer *script; - int type, skip, changedScript; - - if ( !idParser::scriptstack ) { - idLib::common->FatalError( "idParser::ReadSourceToken: not loaded" ); - return false; - } - changedScript = 0; - // if there's no token already available - while( !idParser::tokens ) { - // if there's a token to read from the script - if ( idParser::scriptstack->ReadToken( token ) ) { - token->linesCrossed += changedScript; - - // set the marker based on the start of the token read in - if ( !marker_p ) { - marker_p = token->whiteSpaceEnd_p; - } - return true; - } - // if at the end of the script - if ( idParser::scriptstack->EndOfFile() ) { - // remove all indents of the script - while( idParser::indentstack && idParser::indentstack->script == idParser::scriptstack ) { - idParser::Warning( "missing #endif" ); - idParser::PopIndent( &type, &skip ); - } - changedScript = 1; - } - // if this was the initial script - if ( !idParser::scriptstack->next ) { - return false; - } - // remove the script and return to the previous one - script = idParser::scriptstack; - idParser::scriptstack = idParser::scriptstack->next; - delete script; - } - // copy the already available token - *token = idParser::tokens; - // remove the token from the source - t = idParser::tokens; - idParser::tokens = idParser::tokens->next; - delete t; - return true; -} - -/* -================ -idParser::UnreadSourceToken -================ -*/ -int idParser::UnreadSourceToken( idToken *token ) { - idToken *t; - - t = new idToken(token); - t->next = idParser::tokens; - idParser::tokens = t; - return true; -} - -/* -================ -idParser::ReadDefineParms -================ -*/ -int idParser::ReadDefineParms( define_t *define, idToken **parms, int maxparms ) { - define_t *newdefine; - idToken token, *t, *last; - int i, done, lastcomma, numparms, indent; - - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "define '%s' missing parameters", define->name ); - return false; - } - - if ( define->numparms > maxparms ) { - idParser::Error( "define with more than %d parameters", maxparms ); - return false; - } - - for ( i = 0; i < define->numparms; i++ ) { - parms[i] = NULL; - } - // if no leading "(" - if ( token != "(" ) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "define '%s' missing parameters", define->name ); - return false; - } - // read the define parameters - for ( done = 0, numparms = 0, indent = 1; !done; ) { - if ( numparms >= maxparms ) { - idParser::Error( "define '%s' with too many parameters", define->name ); - return false; - } - parms[numparms] = NULL; - lastcomma = 1; - last = NULL; - while( !done ) { - - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "define '%s' incomplete", define->name ); - return false; - } - - if ( token == "," ) { - if ( indent <= 1 ) { - if ( lastcomma ) { - idParser::Warning( "too many comma's" ); - } - if ( numparms >= define->numparms ) { - idParser::Warning( "too many define parameters" ); - } - lastcomma = 1; - break; - } - } - else if ( token == "(" ) { - indent++; - } - else if ( token == ")" ) { - indent--; - if ( indent <= 0 ) { - if ( !parms[define->numparms-1] ) { - idParser::Warning( "too few define parameters" ); - } - done = 1; - break; - } - } - else if ( token.type == TT_NAME ) { - newdefine = FindHashedDefine( idParser::definehash, token.c_str() ); - if ( newdefine ) { - if ( !idParser::ExpandDefineIntoSource( &token, newdefine ) ) { - return false; - } - continue; - } - } - - lastcomma = 0; - - if ( numparms < define->numparms ) { - - t = new idToken( token ); - t->next = NULL; - if (last) last->next = t; - else parms[numparms] = t; - last = t; - } - } - numparms++; - } - return true; -} - -/* -================ -idParser::StringizeTokens -================ -*/ -int idParser::StringizeTokens( idToken *tokens, idToken *token ) { - idToken *t; - - token->type = TT_STRING; - token->whiteSpaceStart_p = NULL; - token->whiteSpaceEnd_p = NULL; - (*token) = ""; - for ( t = tokens; t; t = t->next ) { - token->Append( t->c_str() ); - } - return true; -} - -/* -================ -idParser::MergeTokens -================ -*/ -int idParser::MergeTokens( idToken *t1, idToken *t2 ) { - // merging of a name with a name or number - if ( t1->type == TT_NAME && (t2->type == TT_NAME || (t2->type == TT_NUMBER && !(t2->subtype & TT_FLOAT))) ) { - t1->Append( t2->c_str() ); - return true; - } - // merging of two strings - if (t1->type == TT_STRING && t2->type == TT_STRING) { - t1->Append( t2->c_str() ); - return true; - } - // merging of two numbers - if ( t1->type == TT_NUMBER && t2->type == TT_NUMBER && - !(t1->subtype & (TT_HEX|TT_BINARY)) && !(t2->subtype & (TT_HEX|TT_BINARY)) && - (!(t1->subtype & TT_FLOAT) || !(t2->subtype & TT_FLOAT)) ) { - t1->Append( t2->c_str() ); - return true; - } - - return false; -} - -/* -================ -idParser::AddBuiltinDefines -================ -*/ -void idParser::AddBuiltinDefines( void ) { - int i; - define_t *define; - struct builtin - { - const char *string; - int id; - } builtin[] = { - { "__LINE__", BUILTIN_LINE }, - { "__FILE__", BUILTIN_FILE }, - { "__DATE__", BUILTIN_DATE }, - { "__TIME__", BUILTIN_TIME }, - { "__STDC__", BUILTIN_STDC }, - { NULL, 0 } - }; - - for (i = 0; builtin[i].string; i++) { - define = (define_t *) Mem_Alloc(sizeof(define_t) + strlen(builtin[i].string) + 1); - define->name = (char *) define + sizeof(define_t); - strcpy(define->name, builtin[i].string); - define->flags = DEFINE_FIXED; - define->builtin = builtin[i].id; - define->numparms = 0; - define->parms = NULL; - define->tokens = NULL; - // add the define to the source - AddDefineToHash(define, idParser::definehash); - } -} - -/* -================ -idParser::CopyFirstDefine -================ -*/ -define_t *idParser::CopyFirstDefine( void ) { - int i; - - for ( i = 0; i < DEFINEHASHSIZE; i++ ) { - if ( idParser::definehash[i] ) { - return CopyDefine(idParser::definehash[i]); - } - } - return NULL; -} - -/* -================ -idParser::ExpandBuiltinDefine -================ -*/ -int idParser::ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) { - idToken *token; - time_t t; - char *curtime; - char buf[MAX_STRING_CHARS]; - - token = new idToken(deftoken); - switch( define->builtin ) { - case BUILTIN_LINE: { - sprintf( buf, "%d", deftoken->line ); - (*token) = buf; - token->intvalue = deftoken->line; - token->floatvalue = deftoken->line; - token->type = TT_NUMBER; - token->subtype = TT_DECIMAL | TT_INTEGER | TT_VALUESVALID; - token->line = deftoken->line; - token->linesCrossed = deftoken->linesCrossed; - token->flags = 0; - *firsttoken = token; - *lasttoken = token; - break; - } - case BUILTIN_FILE: { - (*token) = idParser::scriptstack->GetFileName(); - token->type = TT_NAME; - token->subtype = token->Length(); - token->line = deftoken->line; - token->linesCrossed = deftoken->linesCrossed; - token->flags = 0; - *firsttoken = token; - *lasttoken = token; - break; - } - case BUILTIN_DATE: { - t = time(NULL); - curtime = ctime(&t); - (*token) = "\""; - token->Append( curtime+4 ); - token[7] = '\0'; - token->Append( curtime+20 ); - token[10] = '\0'; - token->Append( "\"" ); - free(curtime); - token->type = TT_STRING; - token->subtype = token->Length(); - token->line = deftoken->line; - token->linesCrossed = deftoken->linesCrossed; - token->flags = 0; - *firsttoken = token; - *lasttoken = token; - break; - } - case BUILTIN_TIME: { - t = time(NULL); - curtime = ctime(&t); - (*token) = "\""; - token->Append( curtime+11 ); - token[8] = '\0'; - token->Append( "\"" ); - free(curtime); - token->type = TT_STRING; - token->subtype = token->Length(); - token->line = deftoken->line; - token->linesCrossed = deftoken->linesCrossed; - token->flags = 0; - *firsttoken = token; - *lasttoken = token; - break; - } - case BUILTIN_STDC: { - idParser::Warning( "__STDC__ not supported\n" ); - *firsttoken = NULL; - *lasttoken = NULL; - break; - } - default: { - *firsttoken = NULL; - *lasttoken = NULL; - break; - } - } - return true; -} - -/* -================ -idParser::ExpandDefine -================ -*/ -int idParser::ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ) { - idToken *parms[MAX_DEFINEPARMS], *dt, *pt, *t; - idToken *t1, *t2, *first, *last, *nextpt, token; - int parmnum, i; - - // if it is a builtin define - if ( define->builtin ) { - return idParser::ExpandBuiltinDefine( deftoken, define, firsttoken, lasttoken ); - } - // if the define has parameters - if ( define->numparms ) { - if ( !idParser::ReadDefineParms( define, parms, MAX_DEFINEPARMS ) ) { - return false; - } -#ifdef DEBUG_EVAL - for ( i = 0; i < define->numparms; i++ ) { - Log_Write("define parms %d:", i); - for ( pt = parms[i]; pt; pt = pt->next ) { - Log_Write( "%s", pt->c_str() ); - } - } -#endif //DEBUG_EVAL - } - // empty list at first - first = NULL; - last = NULL; - // create a list with tokens of the expanded define - for ( dt = define->tokens; dt; dt = dt->next ) { - parmnum = -1; - // if the token is a name, it could be a define parameter - if ( dt->type == TT_NAME ) { - parmnum = FindDefineParm( define, dt->c_str() ); - } - // if it is a define parameter - if ( parmnum >= 0 ) { - for ( pt = parms[parmnum]; pt; pt = pt->next ) { - t = new idToken(pt); - //add the token to the list - t->next = NULL; - if (last) last->next = t; - else first = t; - last = t; - } - } - else { - // if stringizing operator - if ( (*dt) == "#" ) { - // the stringizing operator must be followed by a define parameter - if ( dt->next ) { - parmnum = FindDefineParm( define, dt->next->c_str() ); - } - else { - parmnum = -1; - } - - if ( parmnum >= 0 ) { - // step over the stringizing operator - dt = dt->next; - // stringize the define parameter tokens - if ( !idParser::StringizeTokens( parms[parmnum], &token ) ) { - idParser::Error( "can't stringize tokens" ); - return false; - } - t = new idToken(token); - t->line = deftoken->line; - } - else { - idParser::Warning( "stringizing operator without define parameter" ); - continue; - } - } - else { - t = new idToken(dt); - t->line = deftoken->line; - } - // add the token to the list - t->next = NULL; -// the token being read from the define list should use the line number of -// the original file, not the header file - t->line = deftoken->line; - - if ( last ) last->next = t; - else first = t; - last = t; - } - } - // check for the merging operator - for ( t = first; t; ) { - if ( t->next ) { - // if the merging operator - if ( (*t->next) == "##" ) { - t1 = t; - t2 = t->next->next; - if ( t2 ) { - if ( !idParser::MergeTokens( t1, t2 ) ) { - idParser::Error( "can't merge '%s' with '%s'", t1->c_str(), t2->c_str() ); - return false; - } - delete t1->next; - t1->next = t2->next; - if ( t2 == last ) last = t1; - delete t2; - continue; - } - } - } - t = t->next; - } - // store the first and last token of the list - *firsttoken = first; - *lasttoken = last; - // free all the parameter tokens - for ( i = 0; i < define->numparms; i++ ) { - for ( pt = parms[i]; pt; pt = nextpt ) { - nextpt = pt->next; - delete pt; - } - } - - return true; -} - -/* -================ -idParser::ExpandDefineIntoSource -================ -*/ -int idParser::ExpandDefineIntoSource( idToken *deftoken, define_t *define ) { - idToken *firsttoken, *lasttoken; - - if ( !idParser::ExpandDefine( deftoken, define, &firsttoken, &lasttoken ) ) { - return false; - } - // if the define is not empty - if ( firsttoken && lasttoken ) { - firsttoken->linesCrossed += deftoken->linesCrossed; - lasttoken->next = idParser::tokens; - idParser::tokens = firsttoken; - } - return true; -} - -/* -================ -idParser::ReadLine - -reads a token from the current line, continues reading on the next -line only if a backslash '\' is found -================ -*/ -int idParser::ReadLine( idToken *token ) { - int crossline; - - crossline = 0; - do { - if (!idParser::ReadSourceToken( token )) { - return false; - } - - if (token->linesCrossed > crossline) { - idParser::UnreadSourceToken( token ); - return false; - } - crossline = 1; - } while( (*token) == "\\" ); - return true; -} - -/* -================ -idParser::Directive_include -================ -*/ -int idParser::Directive_include( void ) { - idLexer *script; - idToken token; - idStr path; - - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "#include without file name" ); - return false; - } - if ( token.linesCrossed > 0 ) { - idParser::Error( "#include without file name" ); - return false; - } - if ( token.type == TT_STRING ) { - script = new idLexer; - // try relative to the current file - path = scriptstack->GetFileName(); - path.StripFilename(); - path += "/"; - path += token; - if ( !script->LoadFile( path, OSPath ) ) { - // try absolute path - path = token; - if ( !script->LoadFile( path, OSPath ) ) { - // try from the include path - path = includepath + token; - if ( !script->LoadFile( path, OSPath ) ) { - delete script; - script = NULL; - } - } - } - } - else if ( token.type == TT_PUNCTUATION && token == "<" ) { - path = idParser::includepath; - while( idParser::ReadSourceToken( &token ) ) { - if ( token.linesCrossed > 0 ) { - idParser::UnreadSourceToken( &token ); - break; - } - if ( token.type == TT_PUNCTUATION && token == ">" ) { - break; - } - path += token; - } - if ( token != ">" ) { - idParser::Warning( "#include missing trailing >" ); - } - if ( !path.Length() ) { - idParser::Error( "#include without file name between < >" ); - return false; - } - if ( idParser::flags & LEXFL_NOBASEINCLUDES ) { - return true; - } - script = new idLexer; - if ( !script->LoadFile( includepath + path, OSPath ) ) { - delete script; - script = NULL; - } - } - else { - idParser::Error( "#include without file name" ); - return false; - } - if (!script) { - idParser::Error( "file '%s' not found", path.c_str() ); - return false; - } - script->SetFlags( idParser::flags ); - script->SetPunctuations( idParser::punctuations ); - idParser::PushScript( script ); - return true; -} - -/* -================ -idParser::Directive_undef -================ -*/ -int idParser::Directive_undef( void ) { - idToken token; - define_t *define, *lastdefine; - int hash; - - // - if (!idParser::ReadLine( &token )) { - idParser::Error( "undef without name" ); - return false; - } - if (token.type != TT_NAME) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "expected name but found '%s'", token.c_str() ); - return false; - } - - hash = PC_NameHash( token.c_str() ); - for (lastdefine = NULL, define = idParser::definehash[hash]; define; define = define->hashnext) { - if (!strcmp(define->name, token.c_str())) - { - if (define->flags & DEFINE_FIXED) { - idParser::Warning( "can't undef '%s'", token.c_str() ); - } - else { - if (lastdefine) { - lastdefine->hashnext = define->hashnext; - } - else { - idParser::definehash[hash] = define->hashnext; - } - FreeDefine(define); - } - break; - } - lastdefine = define; - } - return true; -} - -/* -================ -idParser::Directive_define -================ -*/ -int idParser::Directive_define( void ) { - idToken token, *t, *last; - define_t *define; - - if (!idParser::ReadLine( &token )) { - idParser::Error( "#define without name" ); - return false; - } - if (token.type != TT_NAME) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "expected name after #define, found '%s'", token.c_str() ); - return false; - } - // check if the define already exists - define = FindHashedDefine(idParser::definehash, token.c_str()); - if (define) { - if (define->flags & DEFINE_FIXED) { - idParser::Error( "can't redefine '%s'", token.c_str() ); - return false; - } - idParser::Warning( "redefinition of '%s'", token.c_str() ); - // unread the define name before executing the #undef directive - idParser::UnreadSourceToken( &token ); - if (!idParser::Directive_undef()) - return false; - // if the define was not removed (define->flags & DEFINE_FIXED) - define = FindHashedDefine(idParser::definehash, token.c_str()); - } - // allocate define - define = (define_t *) Mem_ClearedAlloc(sizeof(define_t) + token.Length() + 1); - define->name = (char *) define + sizeof(define_t); - strcpy(define->name, token.c_str()); - // add the define to the source - AddDefineToHash(define, idParser::definehash); - // if nothing is defined, just return - if ( !idParser::ReadLine( &token ) ) { - return true; - } - // if it is a define with parameters - if ( token.WhiteSpaceBeforeToken() == 0 && token == "(" ) { - // read the define parameters - last = NULL; - if ( !idParser::CheckTokenString(")") ) { - while(1) { - if ( !idParser::ReadLine( &token ) ) { - idParser::Error( "expected define parameter" ); - return false; - } - // if it isn't a name - if (token.type != TT_NAME) { - idParser::Error( "invalid define parameter" ); - return false; - } - - if (FindDefineParm(define, token.c_str()) >= 0) { - idParser::Error( "two the same define parameters" ); - return false; - } - // add the define parm - t = new idToken(token); - t->ClearTokenWhiteSpace(); - t->next = NULL; - if (last) last->next = t; - else define->parms = t; - last = t; - define->numparms++; - // read next token - if (!idParser::ReadLine( &token )) { - idParser::Error( "define parameters not terminated" ); - return false; - } - - if ( token == ")" ) { - break; - } - // then it must be a comma - if ( token != "," ) { - idParser::Error( "define not terminated" ); - return false; - } - } - } - if ( !idParser::ReadLine( &token ) ) { - return true; - } - } - // read the defined stuff - last = NULL; - do - { - t = new idToken(token); - if ( t->type == TT_NAME && !strcmp( t->c_str(), define->name ) ) { - t->flags |= TOKEN_FL_RECURSIVE_DEFINE; - idParser::Warning( "recursive define (removed recursion)" ); - } - t->ClearTokenWhiteSpace(); - t->next = NULL; - if ( last ) last->next = t; - else define->tokens = t; - last = t; - } while( idParser::ReadLine( &token ) ); - - if ( last ) { - // check for merge operators at the beginning or end - if ( (*define->tokens) == "##" || (*last) == "##" ) { - idParser::Error( "define with misplaced ##" ); - return false; - } - } - return true; -} - -/* -================ -idParser::AddDefine -================ -*/ -int idParser::AddDefine( const char *string ) { - define_t *define; - - define = DefineFromString( string ); - if (!define) { - return false; - } - AddDefineToHash(define, idParser::definehash); - return true; -} - -/* -================ -idParser::AddGlobalDefinesToSource -================ -*/ -void idParser::AddGlobalDefinesToSource( void ) { - define_t *define, *newdefine; - - for (define = globaldefines; define; define = define->next) { - newdefine = CopyDefine( define ); - AddDefineToHash(newdefine, idParser::definehash); - } -} - -/* -================ -idParser::Directive_if_def -================ -*/ -int idParser::Directive_if_def( int type ) { - idToken token; - define_t *d; - int skip; - - if ( !idParser::ReadLine( &token ) ) { - idParser::Error( "#ifdef without name" ); - return false; - } - if (token.type != TT_NAME) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "expected name after #ifdef, found '%s'", token.c_str() ); - return false; - } - d = FindHashedDefine(idParser::definehash, token.c_str()); - skip = (type == INDENT_IFDEF) == (d == NULL); - idParser::PushIndent( type, skip ); - return true; -} - -/* -================ -idParser::Directive_ifdef -================ -*/ -int idParser::Directive_ifdef( void ) { - return idParser::Directive_if_def( INDENT_IFDEF ); -} - -/* -================ -idParser::Directive_ifndef -================ -*/ -int idParser::Directive_ifndef( void ) { - return idParser::Directive_if_def( INDENT_IFNDEF ); -} - -/* -================ -idParser::Directive_else -================ -*/ -int idParser::Directive_else( void ) { - int type, skip; - - idParser::PopIndent( &type, &skip ); - if (!type) { - idParser::Error( "misplaced #else" ); - return false; - } - if (type == INDENT_ELSE) { - idParser::Error( "#else after #else" ); - return false; - } - idParser::PushIndent( INDENT_ELSE, !skip ); - return true; -} - -/* -================ -idParser::Directive_endif -================ -*/ -int idParser::Directive_endif( void ) { - int type, skip; - - idParser::PopIndent( &type, &skip ); - if (!type) { - idParser::Error( "misplaced #endif" ); - return false; - } - return true; -} - -/* -================ -idParser::EvaluateTokens -================ -*/ -typedef struct operator_s -{ - int op; - int priority; - int parentheses; - struct operator_s *prev, *next; -} operator_t; - -typedef struct value_s -{ - signed long int intvalue; - double floatvalue; - int parentheses; - struct value_s *prev, *next; -} value_t; - -int PC_OperatorPriority(int op) { - switch(op) { - case P_MUL: return 15; - case P_DIV: return 15; - case P_MOD: return 15; - case P_ADD: return 14; - case P_SUB: return 14; - - case P_LOGIC_AND: return 7; - case P_LOGIC_OR: return 6; - case P_LOGIC_GEQ: return 12; - case P_LOGIC_LEQ: return 12; - case P_LOGIC_EQ: return 11; - case P_LOGIC_UNEQ: return 11; - - case P_LOGIC_NOT: return 16; - case P_LOGIC_GREATER: return 12; - case P_LOGIC_LESS: return 12; - - case P_RSHIFT: return 13; - case P_LSHIFT: return 13; - - case P_BIN_AND: return 10; - case P_BIN_OR: return 8; - case P_BIN_XOR: return 9; - case P_BIN_NOT: return 16; - - case P_COLON: return 5; - case P_QUESTIONMARK: return 5; - } - return false; -} - -//#define AllocValue() GetClearedMemory(sizeof(value_t)); -//#define FreeValue(val) FreeMemory(val) -//#define AllocOperator(op) op = (operator_t *) GetClearedMemory(sizeof(operator_t)); -//#define FreeOperator(op) FreeMemory(op); - -#define MAX_VALUES 64 -#define MAX_OPERATORS 64 - -#define AllocValue(val) \ - if ( numvalues >= MAX_VALUES ) { \ - idParser::Error( "out of value space\n" ); \ - error = 1; \ - break; \ - } \ - else { \ - val = &value_heap[numvalues++]; \ - } - -#define FreeValue(val) - -#define AllocOperator(op) \ - if ( numoperators >= MAX_OPERATORS ) { \ - idParser::Error( "out of operator space\n" ); \ - error = 1; \ - break; \ - } \ - else { \ - op = &operator_heap[numoperators++]; \ - } - -#define FreeOperator(op) - -int idParser::EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ) { - operator_t *o, *firstoperator, *lastoperator; - value_t *v, *firstvalue, *lastvalue, *v1, *v2; - idToken *t; - int brace = 0; - int parentheses = 0; - int error = 0; - int lastwasvalue = 0; - int negativevalue = 0; - int questmarkintvalue = 0; - double questmarkfloatvalue = 0; - int gotquestmarkvalue = false; - int lastoperatortype = 0; - // - operator_t operator_heap[MAX_OPERATORS]; - int numoperators = 0; - value_t value_heap[MAX_VALUES]; - int numvalues = 0; - - firstoperator = lastoperator = NULL; - firstvalue = lastvalue = NULL; - if (intvalue) *intvalue = 0; - if (floatvalue) *floatvalue = 0; - for ( t = tokens; t; t = t->next ) { - switch( t->type ) { - case TT_NAME: - { - if ( lastwasvalue || negativevalue ) { - idParser::Error( "syntax error in #if/#elif" ); - error = 1; - break; - } - if ( (*t) != "defined" ) { - idParser::Error( "undefined name '%s' in #if/#elif", t->c_str() ); - error = 1; - break; - } - t = t->next; - if ( (*t) == "(" ) { - brace = true; - t = t->next; - } - if (!t || t->type != TT_NAME) { - idParser::Error( "defined() without name in #if/#elif" ); - error = 1; - break; - } - //v = (value_t *) GetClearedMemory(sizeof(value_t)); - AllocValue(v); - if (FindHashedDefine(idParser::definehash, t->c_str())) { - v->intvalue = 1; - v->floatvalue = 1; - } - else { - v->intvalue = 0; - v->floatvalue = 0; - } - v->parentheses = parentheses; - v->next = NULL; - v->prev = lastvalue; - if (lastvalue) lastvalue->next = v; - else firstvalue = v; - lastvalue = v; - if (brace) { - t = t->next; - if (!t || (*t) != ")" ) { - idParser::Error( "defined missing ) in #if/#elif" ); - error = 1; - break; - } - } - brace = false; - // defined() creates a value - lastwasvalue = 1; - break; - } - case TT_NUMBER: - { - if (lastwasvalue) { - idParser::Error( "syntax error in #if/#elif" ); - error = 1; - break; - } - //v = (value_t *) GetClearedMemory(sizeof(value_t)); - AllocValue(v); - if (negativevalue) { - v->intvalue = - t->GetIntValue(); - v->floatvalue = - t->GetFloatValue(); - } - else { - v->intvalue = t->GetIntValue(); - v->floatvalue = t->GetFloatValue(); - } - v->parentheses = parentheses; - v->next = NULL; - v->prev = lastvalue; - if (lastvalue) lastvalue->next = v; - else firstvalue = v; - lastvalue = v; - //last token was a value - lastwasvalue = 1; - // - negativevalue = 0; - break; - } - case TT_PUNCTUATION: - { - if (negativevalue) { - idParser::Error( "misplaced minus sign in #if/#elif" ); - error = 1; - break; - } - if (t->subtype == P_PARENTHESESOPEN) { - parentheses++; - break; - } - else if (t->subtype == P_PARENTHESESCLOSE) { - parentheses--; - if (parentheses < 0) { - idParser::Error( "too many ) in #if/#elsif" ); - error = 1; - } - break; - } - //check for invalid operators on floating point values - if ( !integer ) { - if (t->subtype == P_BIN_NOT || t->subtype == P_MOD || - t->subtype == P_RSHIFT || t->subtype == P_LSHIFT || - t->subtype == P_BIN_AND || t->subtype == P_BIN_OR || - t->subtype == P_BIN_XOR) { - idParser::Error( "illigal operator '%s' on floating point operands\n", t->c_str() ); - error = 1; - break; - } - } - switch( t->subtype ) { - case P_LOGIC_NOT: - case P_BIN_NOT: - { - if (lastwasvalue) { - idParser::Error( "! or ~ after value in #if/#elif" ); - error = 1; - break; - } - break; - } - case P_INC: - case P_DEC: - { - idParser::Error( "++ or -- used in #if/#elif" ); - break; - } - case P_SUB: - { - if (!lastwasvalue) { - negativevalue = 1; - break; - } - } - - case P_MUL: - case P_DIV: - case P_MOD: - case P_ADD: - - case P_LOGIC_AND: - case P_LOGIC_OR: - case P_LOGIC_GEQ: - case P_LOGIC_LEQ: - case P_LOGIC_EQ: - case P_LOGIC_UNEQ: - - case P_LOGIC_GREATER: - case P_LOGIC_LESS: - - case P_RSHIFT: - case P_LSHIFT: - - case P_BIN_AND: - case P_BIN_OR: - case P_BIN_XOR: - - case P_COLON: - case P_QUESTIONMARK: - { - if (!lastwasvalue) { - idParser::Error( "operator '%s' after operator in #if/#elif", t->c_str() ); - error = 1; - break; - } - break; - } - default: - { - idParser::Error( "invalid operator '%s' in #if/#elif", t->c_str() ); - error = 1; - break; - } - } - if (!error && !negativevalue) { - //o = (operator_t *) GetClearedMemory(sizeof(operator_t)); - AllocOperator(o); - o->op = t->subtype; - o->priority = PC_OperatorPriority(t->subtype); - o->parentheses = parentheses; - o->next = NULL; - o->prev = lastoperator; - if (lastoperator) lastoperator->next = o; - else firstoperator = o; - lastoperator = o; - lastwasvalue = 0; - } - break; - } - default: - { - idParser::Error( "unknown '%s' in #if/#elif", t->c_str() ); - error = 1; - break; - } - } - if (error) { - break; - } - } - if (!error) { - if (!lastwasvalue) { - idParser::Error( "trailing operator in #if/#elif" ); - error = 1; - } - else if (parentheses) { - idParser::Error( "too many ( in #if/#elif" ); - error = 1; - } - } - // - gotquestmarkvalue = false; - questmarkintvalue = 0; - questmarkfloatvalue = 0; - //while there are operators - while( !error && firstoperator ) { - v = firstvalue; - for (o = firstoperator; o->next; o = o->next) { - //if the current operator is nested deeper in parentheses - //than the next operator - if (o->parentheses > o->next->parentheses) { - break; - } - //if the current and next operator are nested equally deep in parentheses - if (o->parentheses == o->next->parentheses) { - //if the priority of the current operator is equal or higher - //than the priority of the next operator - if (o->priority >= o->next->priority) { - break; - } - } - //if the arity of the operator isn't equal to 1 - if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) { - v = v->next; - } - //if there's no value or no next value - if (!v) { - idParser::Error( "mising values in #if/#elif" ); - error = 1; - break; - } - } - if (error) { - break; - } - v1 = v; - v2 = v->next; -#ifdef DEBUG_EVAL - if (integer) { - Log_Write("operator %s, value1 = %d", idParser::scriptstack->getPunctuationFromId(o->op), v1->intvalue); - if (v2) Log_Write("value2 = %d", v2->intvalue); - } - else { - Log_Write("operator %s, value1 = %f", idParser::scriptstack->getPunctuationFromId(o->op), v1->floatvalue); - if (v2) Log_Write("value2 = %f", v2->floatvalue); - } -#endif //DEBUG_EVAL - switch(o->op) { - case P_LOGIC_NOT: v1->intvalue = !v1->intvalue; - v1->floatvalue = !v1->floatvalue; break; - case P_BIN_NOT: v1->intvalue = ~v1->intvalue; - break; - case P_MUL: v1->intvalue *= v2->intvalue; - v1->floatvalue *= v2->floatvalue; break; - case P_DIV: if (!v2->intvalue || !v2->floatvalue) - { - idParser::Error( "divide by zero in #if/#elif\n" ); - error = 1; - break; - } - v1->intvalue /= v2->intvalue; - v1->floatvalue /= v2->floatvalue; break; - case P_MOD: if (!v2->intvalue) - { - idParser::Error( "divide by zero in #if/#elif\n" ); - error = 1; - break; - } - v1->intvalue %= v2->intvalue; break; - case P_ADD: v1->intvalue += v2->intvalue; - v1->floatvalue += v2->floatvalue; break; - case P_SUB: v1->intvalue -= v2->intvalue; - v1->floatvalue -= v2->floatvalue; break; - case P_LOGIC_AND: v1->intvalue = v1->intvalue && v2->intvalue; - v1->floatvalue = v1->floatvalue && v2->floatvalue; break; - case P_LOGIC_OR: v1->intvalue = v1->intvalue || v2->intvalue; - v1->floatvalue = v1->floatvalue || v2->floatvalue; break; - case P_LOGIC_GEQ: v1->intvalue = v1->intvalue >= v2->intvalue; - v1->floatvalue = v1->floatvalue >= v2->floatvalue; break; - case P_LOGIC_LEQ: v1->intvalue = v1->intvalue <= v2->intvalue; - v1->floatvalue = v1->floatvalue <= v2->floatvalue; break; - case P_LOGIC_EQ: v1->intvalue = v1->intvalue == v2->intvalue; - v1->floatvalue = v1->floatvalue == v2->floatvalue; break; - case P_LOGIC_UNEQ: v1->intvalue = v1->intvalue != v2->intvalue; - v1->floatvalue = v1->floatvalue != v2->floatvalue; break; - case P_LOGIC_GREATER: v1->intvalue = v1->intvalue > v2->intvalue; - v1->floatvalue = v1->floatvalue > v2->floatvalue; break; - case P_LOGIC_LESS: v1->intvalue = v1->intvalue < v2->intvalue; - v1->floatvalue = v1->floatvalue < v2->floatvalue; break; - case P_RSHIFT: v1->intvalue >>= v2->intvalue; - break; - case P_LSHIFT: v1->intvalue <<= v2->intvalue; - break; - case P_BIN_AND: v1->intvalue &= v2->intvalue; - break; - case P_BIN_OR: v1->intvalue |= v2->intvalue; - break; - case P_BIN_XOR: v1->intvalue ^= v2->intvalue; - break; - case P_COLON: - { - if (!gotquestmarkvalue) { - idParser::Error( ": without ? in #if/#elif" ); - error = 1; - break; - } - if (integer) { - if (!questmarkintvalue) - v1->intvalue = v2->intvalue; - } - else { - if (!questmarkfloatvalue) - v1->floatvalue = v2->floatvalue; - } - gotquestmarkvalue = false; - break; - } - case P_QUESTIONMARK: - { - if (gotquestmarkvalue) { - idParser::Error( "? after ? in #if/#elif" ); - error = 1; - break; - } - questmarkintvalue = v1->intvalue; - questmarkfloatvalue = v1->floatvalue; - gotquestmarkvalue = true; - break; - } - } -#ifdef DEBUG_EVAL - if (integer) Log_Write("result value = %d", v1->intvalue); - else Log_Write("result value = %f", v1->floatvalue); -#endif //DEBUG_EVAL - if (error) - break; - lastoperatortype = o->op; - //if not an operator with arity 1 - if (o->op != P_LOGIC_NOT && o->op != P_BIN_NOT) { - //remove the second value if not question mark operator - if (o->op != P_QUESTIONMARK) { - v = v->next; - } - // - if (v->prev) v->prev->next = v->next; - else firstvalue = v->next; - if (v->next) v->next->prev = v->prev; - else lastvalue = v->prev; - //FreeMemory(v); - FreeValue(v); - } - //remove the operator - if (o->prev) o->prev->next = o->next; - else firstoperator = o->next; - if (o->next) o->next->prev = o->prev; - else lastoperator = o->prev; - //FreeMemory(o); - FreeOperator(o); - } - if (firstvalue) { - if (intvalue) *intvalue = firstvalue->intvalue; - if (floatvalue) *floatvalue = firstvalue->floatvalue; - } - for (o = firstoperator; o; o = lastoperator) { - lastoperator = o->next; - //FreeMemory(o); - FreeOperator(o); - } - for (v = firstvalue; v; v = lastvalue) { - lastvalue = v->next; - //FreeMemory(v); - FreeValue(v); - } - if (!error) { - return true; - } - if (intvalue) { - *intvalue = 0; - } - if (floatvalue) { - *floatvalue = 0; - } - return false; -} - -/* -================ -idParser::Evaluate -================ -*/ -int idParser::Evaluate( signed long int *intvalue, double *floatvalue, int integer ) { - idToken token, *firsttoken, *lasttoken; - idToken *t, *nexttoken; - define_t *define; - int defined = false; - - if (intvalue) { - *intvalue = 0; - } - if (floatvalue) { - *floatvalue = 0; - } - // - if ( !idParser::ReadLine( &token ) ) { - idParser::Error( "no value after #if/#elif" ); - return false; - } - firsttoken = NULL; - lasttoken = NULL; - do { - //if the token is a name - if (token.type == TT_NAME) { - if (defined) { - defined = false; - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else if ( token == "defined" ) { - defined = true; - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else { - //then it must be a define - define = FindHashedDefine(idParser::definehash, token.c_str()); - if (!define) { - idParser::Error( "can't Evaluate '%s', not defined", token.c_str() ); - return false; - } - if ( !idParser::ExpandDefineIntoSource( &token, define ) ) { - return false; - } - } - } - //if the token is a number or a punctuation - else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) { - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else { - idParser::Error( "can't Evaluate '%s'", token.c_str() ); - return false; - } - } while(idParser::ReadLine( &token )); - // - if ( !idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer ) ) { - return false; - } - // -#ifdef DEBUG_EVAL - Log_Write("eval:"); -#endif //DEBUG_EVAL - for (t = firsttoken; t; t = nexttoken) { -#ifdef DEBUG_EVAL - Log_Write(" %s", t->c_str()); -#endif //DEBUG_EVAL - nexttoken = t->next; - delete t; - } //end for -#ifdef DEBUG_EVAL - if (integer) Log_Write("eval result: %d", *intvalue); - else Log_Write("eval result: %f", *floatvalue); -#endif //DEBUG_EVAL - // - return true; -} - -/* -================ -idParser::DollarEvaluate -================ -*/ -int idParser::DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer) { - int indent, defined = false; - idToken token, *firsttoken, *lasttoken; - idToken *t, *nexttoken; - define_t *define; - - if (intvalue) { - *intvalue = 0; - } - if (floatvalue) { - *floatvalue = 0; - } - // - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "no leading ( after $evalint/$evalfloat" ); - return false; - } - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "nothing to Evaluate" ); - return false; - } - indent = 1; - firsttoken = NULL; - lasttoken = NULL; - do { - //if the token is a name - if (token.type == TT_NAME) { - if (defined) { - defined = false; - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else if ( token == "defined" ) { - defined = true; - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else { - //then it must be a define - define = FindHashedDefine(idParser::definehash, token.c_str()); - if (!define) { - idParser::Warning( "can't Evaluate '%s', not defined", token.c_str() ); - return false; - } - if ( !idParser::ExpandDefineIntoSource( &token, define ) ) { - return false; - } - } - } - //if the token is a number or a punctuation - else if (token.type == TT_NUMBER || token.type == TT_PUNCTUATION) { - if ( token[0] == '(' ) indent++; - else if ( token[0] == ')' ) indent--; - if (indent <= 0) { - break; - } - t = new idToken(token); - t->next = NULL; - if (lasttoken) lasttoken->next = t; - else firsttoken = t; - lasttoken = t; - } - else { - idParser::Error( "can't Evaluate '%s'", token.c_str() ); - return false; - } - } while(idParser::ReadSourceToken( &token )); - // - if (!idParser::EvaluateTokens( firsttoken, intvalue, floatvalue, integer)) { - return false; - } - // -#ifdef DEBUG_EVAL - Log_Write("$eval:"); -#endif //DEBUG_EVAL - for (t = firsttoken; t; t = nexttoken) { -#ifdef DEBUG_EVAL - Log_Write(" %s", t->c_str()); -#endif //DEBUG_EVAL - nexttoken = t->next; - delete t; - } //end for -#ifdef DEBUG_EVAL - if (integer) Log_Write("$eval result: %d", *intvalue); - else Log_Write("$eval result: %f", *floatvalue); -#endif //DEBUG_EVAL - // - return true; -} - -/* -================ -idParser::Directive_elif -================ -*/ -int idParser::Directive_elif( void ) { - signed long int value; - int type, skip; - - idParser::PopIndent( &type, &skip ); - if (!type || type == INDENT_ELSE) { - idParser::Error( "misplaced #elif" ); - return false; - } - if ( !idParser::Evaluate( &value, NULL, true ) ) { - return false; - } - skip = (value == 0); - idParser::PushIndent( INDENT_ELIF, skip ); - return true; -} - -/* -================ -idParser::Directive_if -================ -*/ -int idParser::Directive_if( void ) { - signed long int value; - int skip; - - if ( !idParser::Evaluate( &value, NULL, true ) ) { - return false; - } - skip = (value == 0); - idParser::PushIndent( INDENT_IF, skip ); - return true; -} - -/* -================ -idParser::Directive_line -================ -*/ -int idParser::Directive_line( void ) { - idToken token; - - idParser::Error( "#line directive not supported" ); - while( idParser::ReadLine( &token ) ) { - } - return true; -} - -/* -================ -idParser::Directive_error -================ -*/ -int idParser::Directive_error( void ) { - idToken token; - - if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) { - idParser::Error( "#error without string" ); - return false; - } - idParser::Error( "#error: %s", token.c_str() ); - return true; -} - -/* -================ -idParser::Directive_warning -================ -*/ -int idParser::Directive_warning( void ) { - idToken token; - - if ( !idParser::ReadLine( &token) || token.type != TT_STRING ) { - idParser::Warning( "#warning without string" ); - return false; - } - idParser::Warning( "#warning: %s", token.c_str() ); - return true; -} - -/* -================ -idParser::Directive_pragma -================ -*/ -int idParser::Directive_pragma( void ) { - idToken token; - - idParser::Warning( "#pragma directive not supported" ); - while( idParser::ReadLine( &token ) ) { - } - return true; -} - -/* -================ -idParser::UnreadSignToken -================ -*/ -void idParser::UnreadSignToken( void ) { - idToken token; - - token.line = idParser::scriptstack->GetLineNum(); - token.whiteSpaceStart_p = NULL; - token.whiteSpaceEnd_p = NULL; - token.linesCrossed = 0; - token.flags = 0; - token = "-"; - token.type = TT_PUNCTUATION; - token.subtype = P_SUB; - idParser::UnreadSourceToken( &token ); -} - -/* -================ -idParser::Directive_eval -================ -*/ -int idParser::Directive_eval( void ) { - signed long int value; - idToken token; - char buf[128]; - - if ( !idParser::Evaluate( &value, NULL, true ) ) { - return false; - } - - token.line = idParser::scriptstack->GetLineNum(); - token.whiteSpaceStart_p = NULL; - token.whiteSpaceEnd_p = NULL; - token.linesCrossed = 0; - token.flags = 0; - sprintf(buf, "%d", abs(value)); - token = buf; - token.type = TT_NUMBER; - token.subtype = TT_INTEGER|TT_LONG|TT_DECIMAL; - idParser::UnreadSourceToken( &token ); - if ( value < 0 ) { - idParser::UnreadSignToken(); - } - return true; -} - -/* -================ -idParser::Directive_evalfloat -================ -*/ -int idParser::Directive_evalfloat( void ) { - double value; - idToken token; - char buf[128]; - - if ( !idParser::Evaluate( NULL, &value, false ) ) { - return false; - } - - token.line = idParser::scriptstack->GetLineNum(); - token.whiteSpaceStart_p = NULL; - token.whiteSpaceEnd_p = NULL; - token.linesCrossed = 0; - token.flags = 0; - sprintf(buf, "%1.2f", idMath::Fabs(value)); - token = buf; - token.type = TT_NUMBER; - token.subtype = TT_FLOAT|TT_LONG|TT_DECIMAL; - idParser::UnreadSourceToken( &token ); - if (value < 0) { - idParser::UnreadSignToken(); - } - return true; -} - -/* -================ -idParser::ReadDirective -================ -*/ -int idParser::ReadDirective( void ) { - idToken token; - - //read the directive name - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "found '#' without name" ); - return false; - } - //directive name must be on the same line - if (token.linesCrossed > 0) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "found '#' at end of line" ); - return false; - } - //if if is a name - if (token.type == TT_NAME) { - if ( token == "if" ) { - return idParser::Directive_if(); - } - else if ( token == "ifdef" ) { - return idParser::Directive_ifdef(); - } - else if ( token == "ifndef" ) { - return idParser::Directive_ifndef(); - } - else if ( token == "elif" ) { - return idParser::Directive_elif(); - } - else if ( token == "else" ) { - return idParser::Directive_else(); - } - else if ( token == "endif" ) { - return idParser::Directive_endif(); - } - else if (idParser::skip > 0) { - // skip the rest of the line - while( idParser::ReadLine( &token ) ) { - } - return true; - } - else { - if ( token == "include" ) { - return idParser::Directive_include(); - } - else if ( token == "define" ) { - return idParser::Directive_define(); - } - else if ( token == "undef" ) { - return idParser::Directive_undef(); - } - else if ( token == "line" ) { - return idParser::Directive_line(); - } - else if ( token == "error" ) { - return idParser::Directive_error(); - } - else if ( token == "warning" ) { - return idParser::Directive_warning(); - } - else if ( token == "pragma" ) { - return idParser::Directive_pragma(); - } - else if ( token == "eval" ) { - return idParser::Directive_eval(); - } - else if ( token == "evalfloat" ) { - return idParser::Directive_evalfloat(); - } - } - } - idParser::Error( "unknown precompiler directive '%s'", token.c_str() ); - return false; -} - -/* -================ -idParser::DollarDirective_evalint -================ -*/ -int idParser::DollarDirective_evalint( void ) { - signed long int value; - idToken token; - char buf[128]; - - if ( !idParser::DollarEvaluate( &value, NULL, true ) ) { - return false; - } - - token.line = idParser::scriptstack->GetLineNum(); - token.whiteSpaceStart_p = NULL; - token.whiteSpaceEnd_p = NULL; - token.linesCrossed = 0; - token.flags = 0; - sprintf( buf, "%d", abs( value ) ); - token = buf; - token.type = TT_NUMBER; - token.subtype = TT_INTEGER | TT_LONG | TT_DECIMAL | TT_VALUESVALID; - token.intvalue = abs( value ); - token.floatvalue = abs( value ); - idParser::UnreadSourceToken( &token ); - if ( value < 0 ) { - idParser::UnreadSignToken(); - } - return true; -} - -/* -================ -idParser::DollarDirective_evalfloat -================ -*/ -int idParser::DollarDirective_evalfloat( void ) { - double value; - idToken token; - char buf[128]; - - if ( !idParser::DollarEvaluate( NULL, &value, false ) ) { - return false; - } - - token.line = idParser::scriptstack->GetLineNum(); - token.whiteSpaceStart_p = NULL; - token.whiteSpaceEnd_p = NULL; - token.linesCrossed = 0; - token.flags = 0; - sprintf( buf, "%1.2f", fabs( value ) ); - token = buf; - token.type = TT_NUMBER; - token.subtype = TT_FLOAT | TT_LONG | TT_DECIMAL | TT_VALUESVALID; - token.intvalue = (unsigned long) fabs( value ); - token.floatvalue = fabs( value ); - idParser::UnreadSourceToken( &token ); - if ( value < 0 ) { - idParser::UnreadSignToken(); - } - return true; -} - -/* -================ -idParser::ReadDollarDirective -================ -*/ -int idParser::ReadDollarDirective( void ) { - idToken token; - - // read the directive name - if ( !idParser::ReadSourceToken( &token ) ) { - idParser::Error( "found '$' without name" ); - return false; - } - // directive name must be on the same line - if ( token.linesCrossed > 0 ) { - idParser::UnreadSourceToken( &token ); - idParser::Error( "found '$' at end of line" ); - return false; - } - // if if is a name - if (token.type == TT_NAME) { - if ( token == "evalint" ) { - return idParser::DollarDirective_evalint(); - } - else if ( token == "evalfloat" ) { - return idParser::DollarDirective_evalfloat(); - } - } - idParser::UnreadSourceToken( &token ); - return false; -} - -/* -================ -idParser::ReadToken -================ -*/ -int idParser::ReadToken( idToken *token ) { - define_t *define; - - while(1) { - if ( !idParser::ReadSourceToken( token ) ) { - return false; - } - // check for precompiler directives - if ( token->type == TT_PUNCTUATION && (*token)[0] == '#' && (*token)[1] == '\0' ) { - // read the precompiler directive - if ( !idParser::ReadDirective() ) { - return false; - } - continue; - } - // if skipping source because of conditional compilation - if ( idParser::skip ) { - continue; - } - // recursively concatenate strings that are behind each other still resolving defines - if ( token->type == TT_STRING && !(idParser::scriptstack->GetFlags() & LEXFL_NOSTRINGCONCAT) ) { - idToken newtoken; - if ( idParser::ReadToken( &newtoken ) ) { - if ( newtoken.type == TT_STRING ) { - token->Append( newtoken.c_str() ); - } - else { - idParser::UnreadSourceToken( &newtoken ); - } - } - } - // - if ( !(idParser::scriptstack->GetFlags() & LEXFL_NODOLLARPRECOMPILE) ) { - // check for special precompiler directives - if ( token->type == TT_PUNCTUATION && (*token)[0] == '$' && (*token)[1] == '\0' ) { - // read the precompiler directive - if ( idParser::ReadDollarDirective() ) { - continue; - } - } - } - // if the token is a name - if ( token->type == TT_NAME && !( token->flags & TOKEN_FL_RECURSIVE_DEFINE ) ) { - // check if the name is a define macro - define = FindHashedDefine( idParser::definehash, token->c_str() ); - // if it is a define macro - if ( define ) { - // expand the defined macro - if ( !idParser::ExpandDefineIntoSource( token, define ) ) { - return false; - } - continue; - } - } - // found a token - return true; - } -} - -/* -================ -idParser::ExpectTokenString -================ -*/ -int idParser::ExpectTokenString( const char *string ) { - idToken token; - - if ( !idParser::ReadToken( &token ) ) { - idParser::Error( "couldn't find expected '%s'", string ); - return false; - } - - if ( token != string ) { - idParser::Error( "expected '%s' but found '%s'", string, token.c_str() ); - return false; - } - return true; -} - -/* -================ -idParser::ExpectTokenType -================ -*/ -int idParser::ExpectTokenType( int type, int subtype, idToken *token ) { - idStr str; - - if ( !idParser::ReadToken( token ) ) { - idParser::Error( "couldn't read expected token" ); - return 0; - } - - if ( token->type != type ) { - switch( type ) { - case TT_STRING: str = "string"; break; - case TT_LITERAL: str = "literal"; break; - case TT_NUMBER: str = "number"; break; - case TT_NAME: str = "name"; break; - case TT_PUNCTUATION: str = "punctuation"; break; - default: str = "unknown type"; break; - } - idParser::Error( "expected a %s but found '%s'", str.c_str(), token->c_str() ); - return 0; - } - if ( token->type == TT_NUMBER ) { - if ( (token->subtype & subtype) != subtype ) { - str.Clear(); - if ( subtype & TT_DECIMAL ) str = "decimal "; - if ( subtype & TT_HEX ) str = "hex "; - if ( subtype & TT_OCTAL ) str = "octal "; - if ( subtype & TT_BINARY ) str = "binary "; - if ( subtype & TT_UNSIGNED ) str += "unsigned "; - if ( subtype & TT_LONG ) str += "long "; - if ( subtype & TT_FLOAT ) str += "float "; - if ( subtype & TT_INTEGER ) str += "integer "; - str.StripTrailing( ' ' ); - idParser::Error( "expected %s but found '%s'", str.c_str(), token->c_str() ); - return 0; - } - } - else if ( token->type == TT_PUNCTUATION ) { - if ( subtype < 0 ) { - idParser::Error( "BUG: wrong punctuation subtype" ); - return 0; - } - if ( token->subtype != subtype ) { - idParser::Error( "expected '%s' but found '%s'", scriptstack->GetPunctuationFromId( subtype ), token->c_str() ); - return 0; - } - } - return 1; -} - -/* -================ -idParser::ExpectAnyToken -================ -*/ -int idParser::ExpectAnyToken( idToken *token ) { - if (!idParser::ReadToken( token )) { - idParser::Error( "couldn't read expected token" ); - return false; - } - else { - return true; - } -} - -/* -================ -idParser::CheckTokenString -================ -*/ -int idParser::CheckTokenString( const char *string ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return false; - } - //if the token is available - if ( tok == string ) { - return true; - } - - UnreadSourceToken( &tok ); - return false; -} - -/* -================ -idParser::CheckTokenType -================ -*/ -int idParser::CheckTokenType( int type, int subtype, idToken *token ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return false; - } - //if the type matches - if (tok.type == type && (tok.subtype & subtype) == subtype) { - *token = tok; - return true; - } - - UnreadSourceToken( &tok ); - return false; -} - -/* -================ -idParser::PeekTokenString -================ -*/ -int idParser::PeekTokenString( const char *string ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return false; - } - - UnreadSourceToken( &tok ); - - // if the token is available - if ( tok == string ) { - return true; - } - return false; -} - -/* -================ -idParser::PeekTokenType -================ -*/ -int idParser::PeekTokenType( int type, int subtype, idToken *token ) { - idToken tok; - - if ( !ReadToken( &tok ) ) { - return false; - } - - UnreadSourceToken( &tok ); - - // if the type matches - if ( tok.type == type && ( tok.subtype & subtype ) == subtype ) { - *token = tok; - return true; - } - return false; -} - -/* -================ -idParser::SkipUntilString -================ -*/ -int idParser::SkipUntilString( const char *string ) { - idToken token; - - while(idParser::ReadToken( &token )) { - if ( token == string ) { - return true; - } - } - return false; -} - -/* -================ -idParser::SkipRestOfLine -================ -*/ -int idParser::SkipRestOfLine( void ) { - idToken token; - - while(idParser::ReadToken( &token )) { - if ( token.linesCrossed ) { - idParser::UnreadSourceToken( &token ); - return true; - } - } - return false; -} - -/* -================= -idParser::SkipBracedSection - -Skips until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -int idParser::SkipBracedSection( bool parseFirstBrace ) { - idToken token; - int depth; - - depth = parseFirstBrace ? 0 : 1; - do { - if ( !ReadToken( &token ) ) { - return false; - } - if( token.type == TT_PUNCTUATION ) { - if( token == "{" ) { - depth++; - } else if ( token == "}" ) { - depth--; - } - } - } while( depth ); - return true; -} - -/* -================= -idParser::ParseBracedSectionExact - -The next token should be an open brace. -Parses until a matching close brace is found. -Maintains the exact formating of the braced section - - FIXME: what about precompilation ? -================= -*/ -const char *idParser::ParseBracedSectionExact( idStr &out, int tabs ) { - return scriptstack->ParseBracedSectionExact( out, tabs ); -} - -/* -================= -idParser::ParseBracedSection - -The next token should be an open brace. -Parses until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -const char *idParser::ParseBracedSection( idStr &out, int tabs ) { - idToken token; - int i, depth; - bool doTabs = false; - if (tabs >= 0) { - doTabs = true; - } - - out.Empty(); - if ( !idParser::ExpectTokenString( "{" ) ) { - return out.c_str(); - } - out = "{"; - depth = 1; - do { - if ( !idParser::ReadToken( &token ) ) { - Error( "missing closing brace" ); - return out.c_str(); - } - - // if the token is on a new line - for ( i = 0; i < token.linesCrossed; i++ ) { - out += "\r\n"; - } - - if (doTabs && token.linesCrossed) { - i = tabs; - if (token[0] == '}' && i > 0) { - i--; - } - while (i-- > 0) { - out += "\t"; - } - } - if ( token.type == TT_PUNCTUATION ) { - if ( token[0] == '{' ) { - depth++; - if (doTabs) { - tabs++; - } - } - else if ( token[0] == '}' ) { - depth--; - if (doTabs) { - tabs--; - } - } - } - - if ( token.type == TT_STRING ) { - out += "\"" + token + "\""; - } - else { - out += token; - } - out += " "; - } while( depth ); - - return out.c_str(); -} - -/* -================= -idParser::ParseRestOfLine - - parse the rest of the line -================= -*/ -const char *idParser::ParseRestOfLine( idStr &out ) { - idToken token; - - out.Empty(); - while(idParser::ReadToken( &token )) { - if ( token.linesCrossed ) { - idParser::UnreadSourceToken( &token ); - break; - } - if ( out.Length() ) { - out += " "; - } - out += token; - } - return out.c_str(); -} - -/* -================ -idParser::UnreadToken -================ -*/ -void idParser::UnreadToken( idToken *token ) { - idParser::UnreadSourceToken( token ); -} - -/* -================ -idParser::ReadTokenOnLine -================ -*/ -int idParser::ReadTokenOnLine( idToken *token ) { - idToken tok; - - if (!idParser::ReadToken( &tok )) { - return false; - } - // if no lines were crossed before this token - if ( !tok.linesCrossed ) { - *token = tok; - return true; - } - // - idParser::UnreadSourceToken( &tok ); - return false; -} - -/* -================ -idParser::ParseInt -================ -*/ -int idParser::ParseInt( void ) { - idToken token; - - if ( !idParser::ReadToken( &token ) ) { - idParser::Error( "couldn't read expected integer" ); - return 0; - } - if ( token.type == TT_PUNCTUATION && token == "-" ) { - idParser::ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); - return -((signed int) token.GetIntValue()); - } - else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) { - idParser::Error( "expected integer value, found '%s'", token.c_str() ); - } - return token.GetIntValue(); -} - -/* -================ -idParser::ParseBool -================ -*/ -bool idParser::ParseBool( void ) { - idToken token; - - if ( !idParser::ExpectTokenType( TT_NUMBER, 0, &token ) ) { - idParser::Error( "couldn't read expected boolean" ); - return false; - } - return ( token.GetIntValue() != 0 ); -} - -/* -================ -idParser::ParseFloat -================ -*/ -float idParser::ParseFloat( void ) { - idToken token; - - if ( !idParser::ReadToken( &token ) ) { - idParser::Error( "couldn't read expected floating point number" ); - return 0.0f; - } - if ( token.type == TT_PUNCTUATION && token == "-" ) { - idParser::ExpectTokenType( TT_NUMBER, 0, &token ); - return -token.GetFloatValue(); - } - else if ( token.type != TT_NUMBER ) { - idParser::Error( "expected float value, found '%s'", token.c_str() ); - } - return token.GetFloatValue(); -} - -/* -================ -idParser::Parse1DMatrix -================ -*/ -int idParser::Parse1DMatrix( int x, float *m ) { - int i; - - if ( !idParser::ExpectTokenString( "(" ) ) { - return false; - } - - for ( i = 0; i < x; i++ ) { - m[i] = idParser::ParseFloat(); - } - - if ( !idParser::ExpectTokenString( ")" ) ) { - return false; - } - return true; -} - -/* -================ -idParser::Parse2DMatrix -================ -*/ -int idParser::Parse2DMatrix( int y, int x, float *m ) { - int i; - - if ( !idParser::ExpectTokenString( "(" ) ) { - return false; - } - - for ( i = 0; i < y; i++ ) { - if ( !idParser::Parse1DMatrix( x, m + i * x ) ) { - return false; - } - } - - if ( !idParser::ExpectTokenString( ")" ) ) { - return false; - } - return true; -} - -/* -================ -idParser::Parse3DMatrix -================ -*/ -int idParser::Parse3DMatrix( int z, int y, int x, float *m ) { - int i; - - if ( !idParser::ExpectTokenString( "(" ) ) { - return false; - } - - for ( i = 0 ; i < z; i++ ) { - if ( !idParser::Parse2DMatrix( y, x, m + i * x*y ) ) { - return false; - } - } - - if ( !idParser::ExpectTokenString( ")" ) ) { - return false; - } - return true; -} - -/* -================ -idParser::GetLastWhiteSpace -================ -*/ -int idParser::GetLastWhiteSpace( idStr &whiteSpace ) const { - if ( scriptstack ) { - scriptstack->GetLastWhiteSpace( whiteSpace ); - } else { - whiteSpace.Clear(); - } - return whiteSpace.Length(); -} - -/* -================ -idParser::SetMarker -================ -*/ -void idParser::SetMarker( void ) { - marker_p = NULL; -} - -/* -================ -idParser::GetStringFromMarker - - FIXME: this is very bad code, the script isn't even garrenteed to still be around -================ -*/ -void idParser::GetStringFromMarker( idStr& out, bool clean ) { - char* p; - char save; - - if ( marker_p == NULL ) { - marker_p = scriptstack->buffer; - } - - if ( tokens ) { - p = (char*)tokens->whiteSpaceStart_p; - } else { - p = (char*)scriptstack->script_p; - } - - // Set the end character to NULL to give us a complete string - save = *p; - *p = 0; - - // If cleaning then reparse - if ( clean ) { - idParser temp( marker_p, strlen( marker_p ), "temp", flags ); - idToken token; - while ( temp.ReadToken ( &token ) ) { - out += token; - } - } else { - out = marker_p; - } - - // restore the character we set to NULL - *p = save; -} - -/* -================ -idParser::SetIncludePath -================ -*/ -void idParser::SetIncludePath( const char *path ) { - idParser::includepath = path; - // add trailing path seperator - if (idParser::includepath[idParser::includepath.Length()-1] != '\\' && - idParser::includepath[idParser::includepath.Length()-1] != '/') { - idParser::includepath += PATHSEPERATOR_STR; - } -} - -/* -================ -idParser::SetPunctuations -================ -*/ -void idParser::SetPunctuations( const punctuation_t *p ) { - idParser::punctuations = p; -} - -/* -================ -idParser::SetFlags -================ -*/ -void idParser::SetFlags( int flags ) { - idLexer *s; - - idParser::flags = flags; - for ( s = idParser::scriptstack; s; s = s->next ) { - s->SetFlags( flags ); - } -} - -/* -================ -idParser::GetFlags -================ -*/ -int idParser::GetFlags( void ) const { - return idParser::flags; -} - -/* -================ -idParser::LoadFile -================ -*/ -int idParser::LoadFile( const char *filename, bool OSPath ) { - idLexer *script; - - if ( idParser::loaded ) { - idLib::common->FatalError("idParser::loadFile: another source already loaded"); - return false; - } - script = new idLexer( filename, 0, OSPath ); - if ( !script->IsLoaded() ) { - delete script; - return false; - } - script->SetFlags( idParser::flags ); - script->SetPunctuations( idParser::punctuations ); - script->next = NULL; - idParser::OSPath = OSPath; - idParser::filename = filename; - idParser::scriptstack = script; - idParser::tokens = NULL; - idParser::indentstack = NULL; - idParser::skip = 0; - idParser::loaded = true; - - if ( !idParser::definehash ) { - idParser::defines = NULL; - idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) ); - idParser::AddGlobalDefinesToSource(); - } - return true; -} - -/* -================ -idParser::LoadMemory -================ -*/ -int idParser::LoadMemory(const char *ptr, int length, const char *name ) { - idLexer *script; - - if ( idParser::loaded ) { - idLib::common->FatalError("idParser::loadMemory: another source already loaded"); - return false; - } - script = new idLexer( ptr, length, name ); - if ( !script->IsLoaded() ) { - delete script; - return false; - } - script->SetFlags( idParser::flags ); - script->SetPunctuations( idParser::punctuations ); - script->next = NULL; - idParser::filename = name; - idParser::scriptstack = script; - idParser::tokens = NULL; - idParser::indentstack = NULL; - idParser::skip = 0; - idParser::loaded = true; - - if ( !idParser::definehash ) { - idParser::defines = NULL; - idParser::definehash = (define_t **) Mem_ClearedAlloc( DEFINEHASHSIZE * sizeof(define_t *) ); - idParser::AddGlobalDefinesToSource(); - } - return true; -} - -/* -================ -idParser::FreeSource -================ -*/ -void idParser::FreeSource( bool keepDefines ) { - idLexer *script; - idToken *token; - define_t *define; - indent_t *indent; - int i; - - // free all the scripts - while( scriptstack ) { - script = scriptstack; - scriptstack = scriptstack->next; - delete script; - } - // free all the tokens - while( tokens ) { - token = tokens; - tokens = tokens->next; - delete token; - } - // free all indents - while( indentstack ) { - indent = indentstack; - indentstack = indentstack->next; - Mem_Free( indent ); - } - if ( !keepDefines ) { - // free hash table - if ( definehash ) { - // free defines - for ( i = 0; i < DEFINEHASHSIZE; i++ ) { - while( definehash[i] ) { - define = definehash[i]; - definehash[i] = definehash[i]->hashnext; - FreeDefine(define); - } - } - defines = NULL; - Mem_Free( idParser::definehash ); - definehash = NULL; - } - } - loaded = false; -} - -/* -================ -idParser::GetPunctuationFromId -================ -*/ -const char *idParser::GetPunctuationFromId( int id ) { - int i; - - if ( !idParser::punctuations ) { - idLexer lex; - return lex.GetPunctuationFromId( id ); - } - - for (i = 0; idParser::punctuations[i].p; i++) { - if ( idParser::punctuations[i].n == id ) { - return idParser::punctuations[i].p; - } - } - return "unkown punctuation"; -} - -/* -================ -idParser::GetPunctuationId -================ -*/ -int idParser::GetPunctuationId( const char *p ) { - int i; - - if ( !idParser::punctuations ) { - idLexer lex; - return lex.GetPunctuationId( p ); - } - - for (i = 0; idParser::punctuations[i].p; i++) { - if ( !strcmp(idParser::punctuations[i].p, p) ) { - return idParser::punctuations[i].n; - } - } - return 0; -} - -/* -================ -idParser::idParser -================ -*/ -idParser::idParser() { - this->loaded = false; - this->OSPath = false; - this->punctuations = 0; - this->flags = 0; - this->scriptstack = NULL; - this->indentstack = NULL; - this->definehash = NULL; - this->defines = NULL; - this->tokens = NULL; - this->marker_p = NULL; -} - -/* -================ -idParser::idParser -================ -*/ -idParser::idParser( int flags ) { - this->loaded = false; - this->OSPath = false; - this->punctuations = 0; - this->flags = flags; - this->scriptstack = NULL; - this->indentstack = NULL; - this->definehash = NULL; - this->defines = NULL; - this->tokens = NULL; - this->marker_p = NULL; -} - -/* -================ -idParser::idParser -================ -*/ -idParser::idParser( const char *filename, int flags, bool OSPath ) { - this->loaded = false; - this->OSPath = true; - this->punctuations = 0; - this->flags = flags; - this->scriptstack = NULL; - this->indentstack = NULL; - this->definehash = NULL; - this->defines = NULL; - this->tokens = NULL; - this->marker_p = NULL; - LoadFile( filename, OSPath ); -} - -/* -================ -idParser::idParser -================ -*/ -idParser::idParser( const char *ptr, int length, const char *name, int flags ) { - this->loaded = false; - this->OSPath = false; - this->punctuations = 0; - this->flags = flags; - this->scriptstack = NULL; - this->indentstack = NULL; - this->definehash = NULL; - this->defines = NULL; - this->tokens = NULL; - this->marker_p = NULL; - LoadMemory( ptr, length, name ); -} - -/* -================ -idParser::~idParser -================ -*/ -idParser::~idParser( void ) { - idParser::FreeSource( false ); -} - -#pragma warning( pop ) - diff --git a/idlib/parser.h b/idlib/parser.h deleted file mode 100644 index 27064cd84..000000000 --- a/idlib/parser.h +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __PARSER_H__ -#define __PARSER_H__ - -/* -=============================================================================== - - C/C++ compatible pre-compiler - -=============================================================================== -*/ - -#define DEFINE_FIXED 0x0001 - -#define BUILTIN_LINE 1 -#define BUILTIN_FILE 2 -#define BUILTIN_DATE 3 -#define BUILTIN_TIME 4 -#define BUILTIN_STDC 5 - -#define INDENT_IF 0x0001 -#define INDENT_ELSE 0x0002 -#define INDENT_ELIF 0x0004 -#define INDENT_IFDEF 0x0008 -#define INDENT_IFNDEF 0x0010 - -// macro definitions -typedef struct define_s { - char * name; // define name - int flags; // define flags - int builtin; // > 0 if builtin define - int numparms; // number of define parameters - idToken * parms; // define parameters - idToken * tokens; // macro tokens (possibly containing parm tokens) - struct define_s *next; // next defined macro in a list - struct define_s *hashnext; // next define in the hash chain -} define_t; - -// indents used for conditional compilation directives: -// #if, #else, #elif, #ifdef, #ifndef -typedef struct indent_s { - int type; // indent type - int skip; // true if skipping current indent - idLexer * script; // script the indent was in - struct indent_s *next; // next indent on the indent stack -} indent_t; - - -class idParser { - -public: - // constructor - idParser(); - idParser( int flags ); - idParser( const char *filename, int flags = 0, bool OSPath = false ); - idParser( const char *ptr, int length, const char *name, int flags = 0 ); - // destructor - ~idParser(); - // load a source file - int LoadFile( const char *filename, bool OSPath = false ); - // load a source from the given memory with the given length - // NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0' - int LoadMemory( const char *ptr, int length, const char *name ); - // free the current source - void FreeSource( bool keepDefines = false ); - // returns true if a source is loaded - int IsLoaded( void ) const { return idParser::loaded; } - // read a token from the source - int ReadToken( idToken *token ); - // expect a certain token, reads the token when available - int ExpectTokenString( const char *string ); - // expect a certain token type - int ExpectTokenType( int type, int subtype, idToken *token ); - // expect a token - int ExpectAnyToken( idToken *token ); - // returns true if the next token equals the given string and removes the token from the source - int CheckTokenString( const char *string ); - // returns true if the next token equals the given type and removes the token from the source - int CheckTokenType( int type, int subtype, idToken *token ); - // returns true if the next token equals the given string but does not remove the token from the source - int PeekTokenString( const char *string ); - // returns true if the next token equals the given type but does not remove the token from the source - int PeekTokenType( int type, int subtype, idToken *token ); - // skip tokens until the given token string is read - int SkipUntilString( const char *string ); - // skip the rest of the current line - int SkipRestOfLine( void ); - // skip the braced section - int SkipBracedSection( bool parseFirstBrace = true ); - // parse a braced section into a string - const char * ParseBracedSection( idStr &out, int tabs = -1 ); - // parse a braced section into a string, maintaining indents and newlines - const char * ParseBracedSectionExact( idStr &out, int tabs = -1 ); - // parse the rest of the line - const char * ParseRestOfLine( idStr &out ); - // unread the given token - void UnreadToken( idToken *token ); - // read a token only if on the current line - int ReadTokenOnLine( idToken *token ); - // read a signed integer - int ParseInt( void ); - // read a boolean - bool ParseBool( void ); - // read a floating point number - float ParseFloat( void ); - // parse matrices with floats - int Parse1DMatrix( int x, float *m ); - int Parse2DMatrix( int y, int x, float *m ); - int Parse3DMatrix( int z, int y, int x, float *m ); - // get the white space before the last read token - int GetLastWhiteSpace( idStr &whiteSpace ) const; - // Set a marker in the source file (there is only one marker) - void SetMarker( void ); - // Get the string from the marker to the current position - void GetStringFromMarker( idStr& out, bool clean = false ); - // add a define to the source - int AddDefine( const char *string ); - // add builtin defines - void AddBuiltinDefines( void ); - // set the source include path - void SetIncludePath( const char *path ); - // set the punctuation set - void SetPunctuations( const punctuation_t *p ); - // returns a pointer to the punctuation with the given id - const char * GetPunctuationFromId( int id ); - // get the id for the given punctuation - int GetPunctuationId( const char *p ); - // set lexer flags - void SetFlags( int flags ); - // get lexer flags - int GetFlags( void ) const; - // returns the current filename - const char * GetFileName( void ) const; - // get current offset in current script - const int GetFileOffset( void ) const; - // get file time for current script - const unsigned int GetFileTime( void ) const; - // returns the current line number - const int GetLineNum( void ) const; - // print an error message - void Error( const char *str, ... ) const id_attribute((format(printf,2,3))); - // print a warning message - void Warning( const char *str, ... ) const id_attribute((format(printf,2,3))); - - // add a global define that will be added to all opened sources - static int AddGlobalDefine( const char *string ); - // remove the given global define - static int RemoveGlobalDefine( const char *name ); - // remove all global defines - static void RemoveAllGlobalDefines( void ); - // set the base folder to load files from - static void SetBaseFolder( const char *path ); - -private: - int loaded; // set when a source file is loaded from file or memory - idStr filename; // file name of the script - idStr includepath; // path to include files - bool OSPath; // true if the file was loaded from an OS path - const punctuation_t *punctuations; // punctuations to use - int flags; // flags used for script parsing - idLexer * scriptstack; // stack with scripts of the source - idToken * tokens; // tokens to read first - define_t * defines; // list with macro definitions - define_t ** definehash; // hash chain with defines - indent_t * indentstack; // stack with indents - int skip; // > 0 if skipping conditional code - const char* marker_p; - - static define_t *globaldefines; // list with global defines added to every source loaded - -private: - void PushIndent( int type, int skip ); - void PopIndent( int *type, int *skip ); - void PushScript( idLexer *script ); - int ReadSourceToken( idToken *token ); - int ReadLine( idToken *token ); - int UnreadSourceToken( idToken *token ); - int ReadDefineParms( define_t *define, idToken **parms, int maxparms ); - int StringizeTokens( idToken *tokens, idToken *token ); - int MergeTokens( idToken *t1, idToken *t2 ); - int ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); - int ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); - int ExpandDefineIntoSource( idToken *deftoken, define_t *define ); - void AddGlobalDefinesToSource( void ); - define_t * CopyDefine( define_t *define ); - define_t * FindHashedDefine(define_t **definehash, const char *name); - int FindDefineParm( define_t *define, const char *name ); - void AddDefineToHash(define_t *define, define_t **definehash); - static void PrintDefine( define_t *define ); - static void FreeDefine( define_t *define ); - static define_t *FindDefine( define_t *defines, const char *name ); - static define_t *DefineFromString( const char *string); - define_t * CopyFirstDefine( void ); - int Directive_include( void ); - int Directive_undef( void ); - int Directive_if_def( int type ); - int Directive_ifdef( void ); - int Directive_ifndef( void ); - int Directive_else( void ); - int Directive_endif( void ); - int EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ); - int Evaluate( signed long int *intvalue, double *floatvalue, int integer ); - int DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer); - int Directive_define( void ); - int Directive_elif( void ); - int Directive_if( void ); - int Directive_line( void ); - int Directive_error( void ); - int Directive_warning( void ); - int Directive_pragma( void ); - void UnreadSignToken( void ); - int Directive_eval( void ); - int Directive_evalfloat( void ); - int ReadDirective( void ); - int DollarDirective_evalint( void ); - int DollarDirective_evalfloat( void ); - int ReadDollarDirective( void ); -}; - -ID_INLINE const char *idParser::GetFileName( void ) const { - if ( idParser::scriptstack ) { - return idParser::scriptstack->GetFileName(); - } - else { - return ""; - } -} - -ID_INLINE const int idParser::GetFileOffset( void ) const { - if ( idParser::scriptstack ) { - return idParser::scriptstack->GetFileOffset(); - } - else { - return 0; - } -} - -ID_INLINE const unsigned int idParser::GetFileTime( void ) const { - if ( idParser::scriptstack ) { - return idParser::scriptstack->GetFileTime(); - } - else { - return 0; - } -} - -ID_INLINE const int idParser::GetLineNum( void ) const { - if ( idParser::scriptstack ) { - return idParser::scriptstack->GetLineNum(); - } - else { - return 0; - } -} - -#endif /* !__PARSER_H__ */ diff --git a/idlib/precompiled.cpp b/idlib/precompiled.cpp new file mode 100644 index 000000000..c4e75e7c3 --- /dev/null +++ b/idlib/precompiled.cpp @@ -0,0 +1,19 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "precompiled.h" diff --git a/idlib/precompiled.h b/idlib/precompiled.h index 83d2b75ea..94743b55a 100644 --- a/idlib/precompiled.h +++ b/idlib/precompiled.h @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __PRECOMPILED_H__ #define __PRECOMPILED_H__ @@ -17,34 +24,44 @@ //----------------------------------------------------- +#define ID_TIME_T time_t + #ifdef _WIN32 #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // prevent auto literal to string conversion -#define _WIN32_WINNT 0x0501 + #ifndef _D3SDK #ifndef GAME_DLL #define WINVER 0x501 +#if 0 +// Dedicated server hits unresolved when trying to link this way now. Likely because of the 2010/Win7 transition? - TTimo + #ifdef ID_DEDICATED // dedicated sets windows version here #define _WIN32_WINNT WINVER #define WIN32_LEAN_AND_MEAN #else -// non-dedicated includes MFC and sets windows verion here +// non-dedicated includes MFC and sets windows version here #include "../tools/comafx/StdAfx.h" // this will go away when MFC goes away #endif +#else + +#include "../tools/comafx/StdAfx.h" + +#endif + #include #include #include -#define DIRECTINPUT_VERSION 0x0700 +#define DIRECTINPUT_VERSION 0x0800 // was 0x0700 with the old mssdk #define DIRECTSOUND_VERSION 0x0800 -#include "../mssdk/include/dsound.h" -#include "../mssdk/include/dinput.h" -#include "../mssdk/include/dxerr8.h" +#include +#include #endif /* !GAME_DLL */ #endif /* !_D3SDK */ @@ -52,11 +69,10 @@ #pragma warning(disable : 4100) // unreferenced formal parameter #pragma warning(disable : 4244) // conversion to smaller type, possible loss of data #pragma warning(disable : 4714) // function marked as __forceinline not inlined +#pragma warning(disable : 4996) // unsafe string operations #include // no malloc.h on mac or unix - -#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ -#define NOMINMAX +#include // greebo: Include this before windows.h #include // for qgl.h #undef FindText // stupid namespace poluting Microsoft monkeys @@ -86,31 +102,28 @@ #include "../sys/sys_public.h" // id lib -#include "../idlib/lib.h" - -#if !defined( _D3SDK ) && defined( __WITH_PB__ ) - #include "../punkbuster/pbcommon.h" -#endif +#include "../idlib/Lib.h" // framework -#include "../framework/buildversion.h" -#include "../framework/builddefines.h" -#include "../framework/licensee.h" -#include "../framework/cmdsystem.h" -#include "../framework/cvarsystem.h" -#include "../framework/common.h" -#include "../framework/file.h" -#include "../framework/filesystem.h" -#include "../framework/usercmdgen.h" +#include "../framework/BuildVersion.h" +#include "../framework/BuildDefines.h" +#include "../framework/Licensee.h" +#include "../framework/CmdSystem.h" +#include "../framework/CVarSystem.h" +#include "../framework/Common.h" +#include "../framework/File.h" +#include "../framework/FileSystem.h" +#include "../framework/UsercmdGen.h" // decls -#include "../framework/declmanager.h" -#include "../framework/decltable.h" -#include "../framework/declskin.h" -#include "../framework/declentitydef.h" -#include "../framework/declfx.h" -#include "../framework/declparticle.h" -#include "../framework/declaf.h" +#include "../framework/DeclManager.h" +#include "../framework/DeclTable.h" +#include "../framework/DeclSkin.h" +#include "../framework/DeclEntityDef.h" +#include "../framework/DeclFX.h" +#include "../framework/DeclParticle.h" +#include "../framework/DeclAF.h" +#include "../framework/DeclPDA.h" // We have expression parsing and evaluation code in multiple places: // materials, sound shaders, and guis. We should unify them. @@ -119,52 +132,73 @@ const int MAX_EXPRESSION_REGISTERS = 4096; // renderer #include "../renderer/qgl.h" -#include "../renderer/cinematic.h" -#include "../renderer/material.h" -#include "../renderer/model.h" -#include "../renderer/modelmanager.h" -#include "../renderer/rendersystem.h" -#include "../renderer/renderworld.h" +#include "../renderer/Cinematic.h" +#include "../renderer/Material.h" +#include "../renderer/Model.h" +#include "../renderer/ModelManager.h" +#include "../renderer/RenderSystem.h" +#include "../renderer/RenderWorld.h" // sound engine #include "../sound/sound.h" // asynchronous networking -#include "../framework/async/networksystem.h" +#include "../framework/async/NetworkSystem.h" // user interfaces -#include "../ui/listgui.h" -#include "../ui/userinterface.h" +#include "../ui/ListGUI.h" +#include "../ui/UserInterface.h" // collision detection system -#include "../cm/collisionmodel.h" +#include "../cm/CollisionModel.h" // AAS files and manager -#include "../tools/compilers/aas/aasfile.h" -#include "../tools/compilers/aas/aasfilemanager.h" +#include "../tools/compilers/aas/AASFile.h" +#include "../tools/compilers/aas/AASFileManager.h" // game -#include "../game/game.h" +#include "../game/Game.h" //----------------------------------------------------- #ifndef _D3SDK -#include "../game/game_local.h" +#ifdef GAME_DLL -#endif /* !_D3SDK */ +#if defined(_D3XP) +#include "../d3xp/Game_local.h" +#else +#include "../game/Game_local.h" +#endif -//----------------------------------------------------- +#else -#ifdef _WIN32 +#include "../framework/DemoChecksum.h" -// greebo: The idMath::FLT_EPSILON variable conflicts with the one defined in VC++'s float.h header -// undefine it to avoid this conflict -#ifdef FLT_EPSILON -#undef FLT_EPSILON -#endif +// framework +#include "../framework/Compressor.h" +#include "../framework/EventLoop.h" +#include "../framework/KeyInput.h" +#include "../framework/EditField.h" +#include "../framework/Console.h" +#include "../framework/DemoFile.h" +#include "../framework/Session.h" -#endif +// asynchronous networking +#include "../framework/async/AsyncNetwork.h" + +// The editor entry points are always declared, but may just be +// stubbed out on non-windows platforms. +#include "../tools/edit_public.h" + +// Compilers for map, model, video etc. processing. +#include "../tools/compilers/compiler_public.h" + +#endif /* !GAME_DLL */ + +#endif /* !_D3SDK */ + +//----------------------------------------------------- #endif /* __cplusplus */ diff --git a/idlib/str.cpp b/idlib/str.cpp deleted file mode 100644 index deec2d8c0..000000000 --- a/idlib/str.cpp +++ /dev/null @@ -1,1856 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -#if !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X ) - #define USE_STRING_DATA_ALLOCATOR -#endif - -#ifdef USE_STRING_DATA_ALLOCATOR -static idDynamicBlockAlloc stringDataAllocator; -#endif - -idVec4 g_color_table[16] = -{ - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(1.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_RED - idVec4(0.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_GREEN - idVec4(1.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_YELLOW - idVec4(0.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_BLUE - idVec4(0.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_CYAN - idVec4(1.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_MAGENTA - idVec4(1.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_WHITE - idVec4(0.5f, 0.5f, 0.5f, 1.0f), // S_COLOR_GRAY - idVec4(0.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_BLACK - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(0.0f, 0.0f, 0.0f, 1.0f), - idVec4(0.0f, 0.0f, 0.0f, 1.0f), -}; - -const char *units[2][4] = -{ - { "B", "KB", "MB", "GB" }, - { "B/s", "KB/s", "MB/s", "GB/s" } -}; - -/* -============ -idStr::ColorForIndex -============ -*/ -idVec4 & idStr::ColorForIndex( int i ) { - return g_color_table[ i & 15 ]; -} - -/* -============ -idStr::ReAllocate -============ -*/ -void idStr::ReAllocate( int amount, bool keepold ) { - char *newbuffer; - int newsize; - int mod; - - //assert( data ); - assert( amount > 0 ); - - mod = amount % STR_ALLOC_GRAN; - if ( !mod ) { - newsize = amount; - } - else { - newsize = amount + STR_ALLOC_GRAN - mod; - } - alloced = newsize; - -#ifdef USE_STRING_DATA_ALLOCATOR - newbuffer = stringDataAllocator.Alloc( alloced ); -#else - newbuffer = new char[ alloced ]; -#endif - if ( keepold && data ) { - data[ len ] = '\0'; - strcpy( newbuffer, data ); - } - - if ( data && data != baseBuffer ) { -#ifdef USE_STRING_DATA_ALLOCATOR - stringDataAllocator.Free( data ); -#else - delete [] data; -#endif - } - - data = newbuffer; -} - -/* -============ -idStr::FreeData -============ -*/ -void idStr::FreeData( void ) { - if ( data && data != baseBuffer ) { -#ifdef USE_STRING_DATA_ALLOCATOR - stringDataAllocator.Free( data ); -#else - delete[] data; -#endif - data = baseBuffer; - } -} - -/* -============ -idStr::operator= -============ -*/ -void idStr::operator=( const char *text ) { - int l; - int diff; - int i; - - if ( !text ) { - // safe behaviour if NULL - EnsureAlloced( 1, false ); - data[ 0 ] = '\0'; - len = 0; - return; - } - - if ( text == data ) { - return; // copying same thing - } - - // check if we're aliasing - if ( text >= data && text <= data + len ) { - diff = text - data; - - assert( strlen( text ) < (unsigned)len ); - - for ( i = 0; text[ i ]; i++ ) { - data[ i ] = text[ i ]; - } - - data[ i ] = '\0'; - - len -= diff; - - return; - } - - l = strlen( text ); - EnsureAlloced( l + 1, false ); - strcpy( data, text ); - len = l; -} - -idStr idStr::RandomPart( const char c, const float rand ) const { - idStr part; - - // check for list and if found, use random part - int seps = Count(c); - if (seps > 0) { - // if we have X commata, we have X+1 pieces, so select one at random - seps ++; - //gameLocal.Printf("Found random list with %i parts.\n", seps); - float r = rand; - if (r < 0.0f || r > 1.0f) - { - r = gameLocal.random.RandomFloat(); - } - int idx = (int) (r * (float)seps); - //gameLocal.Printf("random part #%i\n", idx); - // split string into pieces, and select idx - int i = 0; int d = 0; - int start = 0; int end = len; - while (d < len) { - if (data[d] == c) { - i++; - } - if (i == idx) { - // found start, find end - start = d; - if (i > 0) - { - // on first part, start at 0, other parts skip "c" - start ++; - } - end = start; - while (end < len && data[end] != c) - { - end++; - } - break; - } - d++; - } - //gameLocal.Printf("Cutting %s between %i and %i.\n", data, start, end); - part = Mid(start, end - start); - // left-over separator - part.Strip(c); - // and spaces - part.Strip(' '); - if (part == "''") { - // default - part = ""; - } - //gameLocal.Printf("Result: '%s'.\n", part.c_str() ); - // end for random - } - else { - // copy - part.Append( data ); - } - - return part; -} - -/* -============ -idStr::CountChar - -returns count of c between start and end -============ -*/ -int idStr::CountChar( const char *str, const char c, int start, int end ) { - int i; - int count = 0; - - if ( end == -1 ) { - end = strlen( str ) - 1; - } - - for ( i = start; i <= end; i++ ) { - if ( str[i] == c ) { - count++; - } - } - return count; -} - -/* -============ -idStr::FindChar - -returns -1 if not found otherwise the index of the char -============ -*/ -int idStr::FindChar( const char *str, const char c, int start, int end ) { - int i; - - if ( end == -1 ) { - end = strlen( str ) - 1; - } - for ( i = start; i <= end; i++ ) { - if ( str[i] == c ) { - return i; - } - } - return -1; -} - -/* -============ -idStr::FindText - -returns -1 if not found otherwise the index of the text -============ -*/ -int idStr::FindText( const char *str, const char *text, bool casesensitive, int start, int end ) { - int l, i, j; - - if ( end == -1 ) { - end = strlen( str ); - } - l = end - strlen( text ); - for ( i = start; i <= l; i++ ) { - if ( casesensitive ) { - for ( j = 0; text[j]; j++ ) { - if ( str[i+j] != text[j] ) { - break; - } - } - } else { - for ( j = 0; text[j]; j++ ) { - if ( ::toupper( str[i+j] ) != ::toupper( text[j] ) ) { - break; - } - } - } - if ( !text[j] ) { - return i; - } - } - return -1; -} - -/* -============ -idStr::Filter - -Returns true if the string conforms the given filter. -Several metacharacter may be used in the filter. - -* match any string of zero or more characters -? match any single character -[abc...] match any of the enclosed characters; a hyphen can - be used to specify a range (e.g. a-z, A-Z, 0-9) - -============ -*/ -bool idStr::Filter( const char *filter, const char *name, bool casesensitive ) { - idStr buf; - int i, found, index; - - while(*filter) { - if (*filter == '*') { - filter++; - buf.Empty(); - for (i = 0; *filter; i++) { - if ( *filter == '*' || *filter == '?' || (*filter == '[' && *(filter+1) != '[') ) { - break; - } - buf += *filter; - if ( *filter == '[' ) { - filter++; - } - filter++; - } - if ( buf.Length() ) { - index = idStr(name).Find( buf.c_str(), casesensitive ); - if ( index == -1 ) { - return false; - } - name += index + strlen(buf); - } - } - else if (*filter == '?') { - filter++; - name++; - } - else if (*filter == '[') { - if ( *(filter+1) == '[' ) { - if ( *name != '[' ) { - return false; - } - filter += 2; - name++; - } - else { - filter++; - found = false; - while(*filter && !found) { - if (*filter == ']' && *(filter+1) != ']') { - break; - } - if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']')) { - if (casesensitive) { - if (*name >= *filter && *name <= *(filter+2)) { - found = true; - } - } - else { - if ( ::toupper(*name) >= ::toupper(*filter) && ::toupper(*name) <= ::toupper(*(filter+2)) ) { - found = true; - } - } - filter += 3; - } - else { - if (casesensitive) { - if (*filter == *name) { - found = true; - } - } - else { - if ( ::toupper(*filter) == ::toupper(*name) ) { - found = true; - } - } - filter++; - } - } - if (!found) { - return false; - } - while(*filter) { - if ( *filter == ']' && *(filter+1) != ']' ) { - break; - } - filter++; - } - filter++; - name++; - } - } - else { - if (casesensitive) { - if (*filter != *name) { - return false; - } - } - else { - if ( ::toupper(*filter) != ::toupper(*name) ) { - return false; - } - } - filter++; - name++; - } - } - return true; -} - -/* -============= -idStr::StripMediaName - - makes the string lower case, replaces backslashes with forward slashes, and removes extension -============= -*/ -void idStr::StripMediaName( const char *name, idStr &mediaName ) { - char c; - - mediaName.Empty(); - - for ( c = *name; c; c = *(++name) ) { - // truncate at an extension - if ( c == '.' ) { - break; - } - // convert backslashes to forward slashes - if ( c == '\\' ) { - mediaName.Append( '/' ); - } else { - mediaName.Append( idStr::ToLower( c ) ); - } - } -} - -/* -============= -idStr::CheckExtension -============= -*/ -bool idStr::CheckExtension( const char *name, const char *ext ) { - const char *s1 = name + Length( name ) - 1; - const char *s2 = ext + Length( ext ) - 1; - int c1, c2, d; - - do { - c1 = *s1--; - c2 = *s2--; - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - return false; - } - } while( s1 > name && s2 > ext ); - - return ( s1 >= name ); -} - -/* -============= -idStr::FloatArrayToString -============= -*/ -const char *idStr::FloatArrayToString( const float *array, const int length, const int precision ) { - static int index = 0; - static char str[4][16384]; // in case called by nested functions - int i, n; - char format[16], *s; - - // use an array of string so that multiple calls won't collide - s = str[ index ]; - index = (index + 1) & 3; - - idStr::snPrintf( format, sizeof( format ), "%%.%df", precision ); - n = idStr::snPrintf( s, sizeof( str[0] ), format, array[0] ); - if ( precision > 0 ) { - while( n > 0 && s[n-1] == '0' ) s[--n] = '\0'; - while( n > 0 && s[n-1] == '.' ) s[--n] = '\0'; - } - idStr::snPrintf( format, sizeof( format ), " %%.%df", precision ); - for ( i = 1; i < length; i++ ) { - n += idStr::snPrintf( s + n, sizeof( str[0] ) - n, format, array[i] ); - if ( precision > 0 ) { - while( n > 0 && s[n-1] == '0' ) s[--n] = '\0'; - while( n > 0 && s[n-1] == '.' ) s[--n] = '\0'; - } - } - return s; -} - -/* -============ -idStr::Last - -returns -1 if not found otherwise the index of the char -============ -*/ -int idStr::Last( const char c ) const { - int i; - - for( i = Length(); i > 0; i-- ) { - if ( data[ i - 1 ] == c ) { - return i - 1; - } - } - - return -1; -} - -/* -============ -idStr::StripLeading -============ -*/ -void idStr::StripLeading( const char c ) { - // Tels: The string is zero-terminated, so exit if trying to remove zeros - if (c == 0x00) { - return; - } - // Tels: first count how many chars to remove, then move only once - int remove = 0; - while( data[ remove ] == c ) { - remove ++; - } - len -= remove; - // +1 to copy the 0x00 at the end - memmove( &data[ 0 ], &data[ remove ], len + 1 ); -} - -/* -============ -idStr::StripLeadingWhitespace -============ -*/ -void idStr::StripLeadingWhitespace( void ) { - // Tels: first count how many chars to remove, then move the data only once - int remove = 0; - // cast to unsigned char to prevent stripping off high-ASCII characters - while( (unsigned char)data[ remove ] <= ' ' ) { - remove ++; - } - len -= remove; - // +1 to copy the 0x00 at the end - memmove( &data[ 0 ], &data[ remove ], len + 1 ); -} -/* -============ -idStr::StripLeading -============ -*/ -void idStr::StripLeading( const char *string ) { - int l; - - l = strlen( string ); - if ( l > 0 ) { - while ( !Cmpn( string, l ) ) { - memmove( data, data + l, len - l + 1 ); - len -= l; - } - } -} - -/* -============ -idStr::StripLeadingOnce -============ -*/ -bool idStr::StripLeadingOnce( const char *string ) { - int l; - - l = strlen( string ); - if ( ( l > 0 ) && !Cmpn( string, l ) ) { - memmove( data, data + l, len - l + 1 ); - len -= l; - return true; - } - return false; -} - -/* -============ -idStr::StripTrailing -============ -*/ -void idStr::StripTrailing( const char c ) { - int i; - - for( i = Length(); i > 0 && data[ i - 1 ] == c; i-- ) { - data[ i - 1 ] = '\0'; - len--; - } -} - -/* -============ -idStr::StripLeading -============ -*/ -void idStr::StripTrailing( const char *string ) { - int l; - - l = strlen( string ); - if ( l > 0 ) { - while ( ( len >= l ) && !Cmpn( string, data + len - l, l ) ) { - len -= l; - data[len] = '\0'; - } - } -} - -/* -============ -idStr::StripTrailingOnce -============ -*/ -bool idStr::StripTrailingOnce( const char *string ) { - int l; - - l = strlen( string ); - if ( ( l > 0 ) && ( len >= l ) && !Cmpn( string, data + len - l, l ) ) { - len -= l; - data[len] = '\0'; - return true; - } - return false; -} - -/* -============ -idStr::Replace -============ -*/ -void idStr::Replace( const char *old, const char *nw ) { - int oldLen, newLen, i, j, count; - idStr oldString( data ); - - assert(old); - assert(nw); - - oldLen = strlen( old ); - newLen = strlen( nw ); - - // Work out how big the new string will be - count = 0; - for( i = 0; i < oldString.Length(); i++ ) { - if( !idStr::Cmpn( &oldString[i], old, oldLen ) ) { - count++; - i += oldLen - 1; - } - } - - if( count ) { - EnsureAlloced( len + ( ( newLen - oldLen ) * count ) + 2, false ); - - // Replace the old data with the new data - for( i = 0, j = 0; i < oldString.Length(); i++ ) { - if( !idStr::Cmpn( &oldString[i], old, oldLen ) ) { - memcpy( data + j, nw, newLen ); - i += oldLen - 1; - j += newLen; - } else { - data[j] = oldString[i]; - j++; - } - } - data[j] = 0; - len = strlen( data ); - } -} - -/* -============ -idStr::Replace -============ -*/ -void idStr::Replace( const char old, const char nw ) { - // cannot replace 0x00 or swap 0xXX to 0x00 - assert(old); - assert(nw); - - for( int i = 0; i < len; i++ ) { - if (data[i] == old) { data[i] = nw; } - } -} - -/* -============ -idStr::Mid -============ -*/ -const char *idStr::Mid( int start, int len, idStr &result ) const { - int i; - - result.Empty(); - - i = Length(); - if ( i == 0 || len <= 0 || start >= i ) { - return NULL; - } - - if ( start + len >= i ) { - len = i - start; - } - - result.Append( &data[ start ], len ); - return result; -} - -/* -============ -idStr::Mid -============ -*/ -idStr idStr::Mid( int start, int len ) const { - int i; - idStr result; - - i = Length(); - if ( i == 0 || len <= 0 || start >= i ) { - return result; - } - - if ( start + len >= i ) { - len = i - start; - } - - result.Append( &data[ start ], len ); - return result; -} - -/* -============ -idStr::StripTrailingWhitespace -============ -*/ -void idStr::StripTrailingWhitespace( void ) { - int i; - - // cast to unsigned char to prevent stripping off high-ASCII characters - for( i = Length(); i > 0 && (unsigned char)(data[ i - 1 ]) <= ' '; i-- ) { - data[ i - 1 ] = '\0'; - len--; - } -} - -/* -============ -idStr::StripQuotes - -Removes the quotes from the beginning and end of the string -============ -*/ -idStr& idStr::StripQuotes ( void ) -{ - if ( data[0] != '\"' ) - { - return *this; - } - - // Remove the trailing quote first - if ( data[len-1] == '\"' ) - { - data[len-1] = '\0'; - len--; - } - - // Strip the leading quote now - len--; - memmove( &data[ 0 ], &data[ 1 ], len ); - data[len] = '\0'; - - return *this; -} - -/* -===================================================================== - - filename methods - -===================================================================== -*/ - -/* -============ -idStr::FileNameHash -============ -*/ -int idStr::FileNameHash( void ) const { - int i; - long hash; - char letter; - - hash = 0; - i = 0; - while( data[i] != '\0' ) { - letter = idStr::ToLower( data[i] ); - if ( letter == '.' ) { - break; // don't include extension - } - if ( letter =='\\' ) { - letter = '/'; - } - hash += (long)(letter)*(i+119); - i++; - } - hash &= (FILE_HASH_SIZE-1); - return hash; -} - -/* -============ -idStr::BackSlashesToSlashes -============ -*/ -idStr &idStr::BackSlashesToSlashes( void ) { - int i; - - for ( i = 0; i < len; i++ ) { - if ( data[ i ] == '\\' ) { - data[ i ] = '/'; - } - } - return *this; -} - -/* -============ -idStr::SetFileExtension -============ -*/ -idStr &idStr::SetFileExtension( const char *extension ) { - StripFileExtension(); - if ( *extension != '.' ) { - Append( '.' ); - } - Append( extension ); - return *this; -} - -/* -============ -idStr::StripFileExtension -============ -*/ -idStr &idStr::StripFileExtension( void ) { - int i; - - for ( i = len-1; i >= 0; i-- ) { - if ( data[i] == '.' ) { - data[i] = '\0'; - len = i; - break; - } - } - return *this; -} - -/* -============ -idStr::StripAbsoluteFileExtension -============ -*/ -idStr &idStr::StripAbsoluteFileExtension( void ) { - int i; - - for ( i = 0; i < len; i++ ) { - if ( data[i] == '.' ) { - data[i] = '\0'; - len = i; - break; - } - } - - return *this; -} - -/* -================== -idStr::DefaultFileExtension -================== -*/ -idStr &idStr::DefaultFileExtension( const char *extension ) { - int i; - - // do nothing if the string already has an extension - for ( i = len-1; i >= 0; i-- ) { - if ( data[i] == '.' ) { - return *this; - } - } - if ( *extension != '.' ) { - Append( '.' ); - } - Append( extension ); - return *this; -} - -/* -================== -idStr::DefaultPath -================== -*/ -idStr &idStr::DefaultPath( const char *basepath ) { - if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) { - // absolute path location - return *this; - } - - *this = basepath + *this; - return *this; -} - -/* -==================== -idStr::AppendPath -==================== -*/ -void idStr::AppendPath( const char *text ) { - int pos; - int i = 0; - - if ( text && text[i] ) { - pos = len; - EnsureAlloced( len + strlen( text ) + 2 ); - - if ( pos ) { - if ( data[ pos-1 ] != '/' ) { - data[ pos++ ] = '/'; - } - } - if ( text[i] == '/' ) { - i++; - } - - for ( ; text[ i ]; i++ ) { - if ( text[ i ] == '\\' ) { - data[ pos++ ] = '/'; - } else { - data[ pos++ ] = text[ i ]; - } - } - len = pos; - data[ pos ] = '\0'; - } -} - -/* -================== -idStr::StripFilename -================== -*/ -idStr &idStr::StripFilename( void ) { - int pos; - - pos = Length() - 1; - while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) { - pos--; - } - - if ( pos < 0 ) { - pos = 0; - } - - CapLength( pos ); - return *this; -} - -/* -================== -idStr::StripPath -================== -*/ -idStr &idStr::StripPath( void ) { - int pos; - - pos = Length(); - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { - pos--; - } - - *this = Right( Length() - pos ); - return *this; -} - -/* -==================== -idStr::ExtractFilePath -==================== -*/ -void idStr::ExtractFilePath( idStr &dest ) const { - int pos; - - // - // back up until a \ or the start - // - pos = Length(); - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { - pos--; - } - - Left( pos, dest ); -} - -/* -==================== -idStr::ExtractFileName -==================== -*/ -void idStr::ExtractFileName( idStr &dest ) const { - int pos; - - // - // back up until a \ or the start - // - pos = Length() - 1; - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { - pos--; - } - - Right( Length() - pos, dest ); -} - -/* -==================== -idStr::ExtractFileBase -==================== -*/ -void idStr::ExtractFileBase( idStr &dest ) const { - int pos; - int start; - - // - // back up until a \ or the start - // - pos = Length() - 1; - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { - pos--; - } - - start = pos; - while( ( pos < Length() ) && ( ( *this )[ pos ] != '.' ) ) { - pos++; - } - - Mid( start, pos - start, dest ); -} - -/* -==================== -idStr::ExtractFileExtension -==================== -*/ -void idStr::ExtractFileExtension( idStr &dest ) const { - int pos; - - // - // back up until a . or the start - // - pos = Length() - 1; - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '.' ) ) { - pos--; - } - - if ( !pos ) { - // no extension - dest.Empty(); - } else { - Right( Length() - pos, dest ); - } -} - - -/* -===================================================================== - - char * methods to replace library functions - -===================================================================== -*/ - -/* -============ -idStr::IsNumeric - -Checks a string to see if it contains only numerical values. -============ -*/ -bool idStr::IsNumeric( const char *s ) { - int i; - bool dot; - - if ( *s == '-' ) { - s++; - } - - dot = false; - for ( i = 0; s[i]; i++ ) { - if ( !isdigit( s[i] ) ) { - if ( ( s[ i ] == '.' ) && !dot ) { - dot = true; - continue; - } - return false; - } - } - - return true; -} - -/* -============ -idStr::HasLower - -Checks if a string has any lowercase chars -============ -*/ -bool idStr::HasLower( const char *s ) { - if ( !s ) { - return false; - } - - while ( *s ) { - if ( CharIsLower( *s ) ) { - return true; - } - s++; - } - - return false; -} - -/* -============ -idStr::HasUpper - -Checks if a string has any uppercase chars -============ -*/ -bool idStr::HasUpper( const char *s ) { - if ( !s ) { - return false; - } - - while ( *s ) { - if ( CharIsUpper( *s ) ) { - return true; - } - s++; - } - - return false; -} - -/* -================ -idStr::Cmp -================ -*/ -int idStr::Cmp( const char *s1, const char *s2 ) { - int c1, c2, d; - - do { - c1 = *s1++; - c2 = *s2++; - - d = c1 - c2; - if ( d ) { - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; // strings are equal -} - -/* -================ -idStr::Cmpn -================ -*/ -int idStr::Cmpn( const char *s1, const char *s2, int n ) { - int c1, c2, d; - - assert( n >= 0 ); - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - d = c1 - c2; - if ( d ) { - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; // strings are equal -} - -/* -================ -idStr::Icmp -================ -*/ -int idStr::Icmp( const char *s1, const char *s2 ) { - int c1, c2, d; - - do { - c1 = *s1++; - c2 = *s2++; - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; // strings are equal -} - -/* -================ -idStr::Icmpn -================ -*/ -int idStr::Icmpn( const char *s1, const char *s2, int n ) { - int c1, c2, d; - - assert( n >= 0 ); - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; // strings are equal -} - -/* -================ -idStr::Icmp -================ -*/ -int idStr::IcmpNoColor( const char *s1, const char *s2 ) { - int c1, c2, d; - - do { - while ( idStr::IsColor( s1 ) ) { - s1 += 2; - } - while ( idStr::IsColor( s2 ) ) { - s2 += 2; - } - c1 = *s1++; - c2 = *s2++; - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; // strings are equal -} - -/* -================ -idStr::IcmpPath -================ -*/ -int idStr::IcmpPath( const char *s1, const char *s2 ) { - int c1, c2, d; - -#if 0 -//#if !defined( _WIN32 ) - idLib::common->Printf( "WARNING: IcmpPath used on a case-sensitive filesystem?\n" ); -#endif - - do { - c1 = *s1++; - c2 = *s2++; - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c1 == '\\' ) { - d += ('/' - '\\'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 == '\\' ) { - d -= ('/' - '\\'); - if ( !d ) { - break; - } - } - // make sure folders come first - while( c1 ) { - if ( c1 == '/' || c1 == '\\' ) { - break; - } - c1 = *s1++; - } - while( c2 ) { - if ( c2 == '/' || c2 == '\\' ) { - break; - } - c2 = *s2++; - } - if ( c1 && !c2 ) { - return -1; - } else if ( !c1 && c2 ) { - return 1; - } - // same folder depth so use the regular compare - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; -} - -/* -================ -idStr::IcmpnPath -================ -*/ -int idStr::IcmpnPath( const char *s1, const char *s2, int n ) { - int c1, c2, d; - -#if 0 -//#if !defined( _WIN32 ) - idLib::common->Printf( "WARNING: IcmpPath used on a case-sensitive filesystem?\n" ); -#endif - - assert( n >= 0 ); - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - d = c1 - c2; - while( d ) { - if ( c1 <= 'Z' && c1 >= 'A' ) { - d += ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c1 == '\\' ) { - d += ('/' - '\\'); - if ( !d ) { - break; - } - } - if ( c2 <= 'Z' && c2 >= 'A' ) { - d -= ('a' - 'A'); - if ( !d ) { - break; - } - } - if ( c2 == '\\' ) { - d -= ('/' - '\\'); - if ( !d ) { - break; - } - } - // make sure folders come first - while( c1 ) { - if ( c1 == '/' || c1 == '\\' ) { - break; - } - c1 = *s1++; - } - while( c2 ) { - if ( c2 == '/' || c2 == '\\' ) { - break; - } - c2 = *s2++; - } - if ( c1 && !c2 ) { - return -1; - } else if ( !c1 && c2 ) { - return 1; - } - // same folder depth so use the regular compare - return ( INTSIGNBITNOTSET( d ) << 1 ) - 1; - } - } while( c1 ); - - return 0; -} - -/* -============= -idStr::Copynz - -Safe strncpy that ensures a trailing zero -============= -*/ -void idStr::Copynz( char *dest, const char *src, int destsize ) { - if ( !src ) { - idLib::common->Warning( "idStr::Copynz: NULL src" ); - return; - } - if ( destsize < 1 ) { - idLib::common->Warning( "idStr::Copynz: destsize < 1" ); - return; - } - - strncpy( dest, src, destsize-1 ); - dest[destsize-1] = 0; -} - -/* -================ -idStr::Append - - never goes past bounds or leaves without a terminating 0 -================ -*/ -void idStr::Append( char *dest, int size, const char *src ) { - int l1; - - l1 = strlen( dest ); - if ( l1 >= size ) { - idLib::common->Error( "idStr::Append: already overflowed" ); - } - idStr::Copynz( dest + l1, src, size - l1 ); -} - -/* -================ -idStr::LengthWithoutColors -================ -*/ -int idStr::LengthWithoutColors( const char *s ) { - int len; - const char *p; - - if ( !s ) { - return 0; - } - - len = 0; - p = s; - while( *p ) { - if ( idStr::IsColor( p ) ) { - p += 2; - continue; - } - p++; - len++; - } - - return len; -} - -/* -================ -idStr::RemoveColors -================ -*/ -char *idStr::RemoveColors( char *string ) { - char *d; - char *s; - int c; - - s = string; - d = string; - while( (c = *s) != 0 ) { - if ( idStr::IsColor( s ) ) { - s++; - } - else { - *d++ = c; - } - s++; - } - *d = '\0'; - - return string; -} - -/* -================ -idStr::snPrintf -================ -*/ -int idStr::snPrintf( char *dest, int size, const char *fmt, ...) { - int len; - va_list argptr; - char buffer[32000]; // big, but small enough to fit in PPC stack - - va_start( argptr, fmt ); - len = vsprintf( buffer, fmt, argptr ); - va_end( argptr ); - if ( len >= sizeof( buffer ) ) { - idLib::common->Error( "idStr::snPrintf: overflowed buffer" ); - } - if ( len >= size ) { - idLib::common->Warning( "idStr::snPrintf: overflow of %i in %i\n", len, size ); - len = size; - } - idStr::Copynz( dest, buffer, size ); - return len; -} - -/* -============ -idStr::vsnPrintf - -vsnprintf portability: - -C99 standard: vsnprintf returns the number of characters (excluding the trailing -'\0') which would have been written to the final string if enough space had been available -snprintf and vsnprintf do not write more than size bytes (including the trailing '\0') - -win32: _vsnprintf returns the number of characters written, not including the terminating null character, -or a negative value if an output error occurs. If the number of characters to write exceeds count, then count -characters are written and -1 is returned and no trailing '\0' is added. - -idStr::vsnPrintf: always appends a trailing '\0', returns number of characters written (not including terminal \0) -or returns -1 on failure or if the buffer would be overflowed. -============ -*/ -int idStr::vsnPrintf( char *dest, int size, const char *fmt, va_list argptr ) { - int ret; - -#ifdef _WIN32 -#undef _vsnprintf - ret = _vsnprintf( dest, size-1, fmt, argptr ); -#define _vsnprintf use_idStr_vsnPrintf -#else -#undef vsnprintf - ret = vsnprintf( dest, size, fmt, argptr ); -#define vsnprintf use_idStr_vsnPrintf -#endif - dest[size-1] = '\0'; - if ( ret < 0 || ret >= size ) { - return -1; - } - return ret; -} - -/* -============ -sprintf - -Sets the value of the string using a printf interface. -============ -*/ -int sprintf( idStr &string, const char *fmt, ... ) { - int l; - va_list argptr; - char buffer[32000]; - - va_start( argptr, fmt ); - l = idStr::vsnPrintf( buffer, sizeof(buffer)-1, fmt, argptr ); - va_end( argptr ); - buffer[sizeof(buffer)-1] = '\0'; - - string = buffer; - return l; -} - -/* -============ -vsprintf - -Sets the value of the string using a vprintf interface. -============ -*/ -int vsprintf( idStr &string, const char *fmt, va_list argptr ) { - int l; - char buffer[32000]; - - l = idStr::vsnPrintf( buffer, sizeof(buffer)-1, fmt, argptr ); - buffer[sizeof(buffer)-1] = '\0'; - - string = buffer; - return l; -} - -/* -============ -va - -does a varargs printf into a temp buffer -NOTE: not thread safe -============ -*/ -char *va( const char *fmt, ... ) { - va_list argptr; - static int index = 0; - static char string[4][16384]; // in case called by nested functions - char *buf; - - buf = string[index]; - index = (index + 1) & 3; - - va_start( argptr, fmt ); - vsprintf( buf, fmt, argptr ); - va_end( argptr ); - - return buf; -} - - - -/* -============ -idStr::BestUnit -============ -*/ -int idStr::BestUnit( const char *format, float value, Measure_t measure ) { - int unit = 1; - while ( unit <= 3 && ( 1 << ( unit * 10 ) < value ) ) { - unit++; - } - unit--; - value /= 1 << ( unit * 10 ); - sprintf( *this, format, value ); - *this += " "; - *this += units[ measure ][ unit ]; - return unit; -} - -/* -============ -idStr::SetUnit -============ -*/ -void idStr::SetUnit( const char *format, float value, int unit, Measure_t measure ) { - value /= 1 << ( unit * 10 ); - sprintf( *this, format, value ); - *this += " "; - *this += units[ measure ][ unit ]; -} - -/* -================ -idStr::InitMemory -================ -*/ -void idStr::InitMemory( void ) { -#ifdef USE_STRING_DATA_ALLOCATOR - stringDataAllocator.Init(); -#endif -} - -/* -================ -idStr::ShutdownMemory -================ -*/ -void idStr::ShutdownMemory( void ) { -#ifdef USE_STRING_DATA_ALLOCATOR - stringDataAllocator.Shutdown(); -#endif -} - -/* -================ -idStr::PurgeMemory -================ -*/ -void idStr::PurgeMemory( void ) { -#ifdef USE_STRING_DATA_ALLOCATOR - stringDataAllocator.FreeEmptyBaseBlocks(); -#endif -} - -/* -================ -idStr::ShowMemoryUsage_f -================ -*/ -void idStr::ShowMemoryUsage_f( const idCmdArgs &args ) { -#ifdef USE_STRING_DATA_ALLOCATOR - idLib::common->Printf( "%6d KB string memory (%d KB free in %d blocks, %d empty base blocks)\n", - stringDataAllocator.GetBaseBlockMemory() >> 10, stringDataAllocator.GetFreeBlockMemory() >> 10, - stringDataAllocator.GetNumFreeBlocks(), stringDataAllocator.GetNumEmptyBaseBlocks() ); -#endif -} - -/* -================ -idStr::FormatNumber -================ -*/ -struct formatList_t { - int gran; - int count; -}; - -// elements of list need to decend in size -formatList_t formatList[] = { - { 1000000000, 0 }, - { 1000000, 0 }, - { 1000, 0 } -}; - -int numFormatList = sizeof(formatList) / sizeof( formatList[0] ); - - -idStr idStr::FormatNumber( int number ) { - idStr string; - bool hit; - - // reset - for ( int i = 0; i < numFormatList; i++ ) { - formatList_t *li = formatList + i; - li->count = 0; - } - - // main loop - do { - hit = false; - - for ( int i = 0; i < numFormatList; i++ ) { - formatList_t *li = formatList + i; - - if ( number >= li->gran ) { - li->count++; - number -= li->gran; - hit = true; - break; - } - } - } while ( hit ); - - // print out - bool found = false; - - for ( int i = 0; i < numFormatList; i++ ) { - formatList_t *li = formatList + i; - - if ( li->count ) { - if ( !found ) { - string += va( "%i,", li->count ); - } else { - string += va( "%3.3i,", li->count ); - } - found = true; - } - else if ( found ) { - string += va( "%3.3i,", li->count ); - } - } - - if ( found ) { - string += va( "%3.3i", number ); - } - else { - string += va( "%i", number ); - } - - // pad to proper size - int count = 11 - string.Length(); - - for ( int i = 0; i < count; i++ ) { - string.Insert( " ", 0 ); - } - - return string; -} - diff --git a/idlib/str.h b/idlib/str.h deleted file mode 100644 index 1b8f04016..000000000 --- a/idlib/str.h +++ /dev/null @@ -1,1015 +0,0 @@ -// vim:ts=4:sw=4:cindent -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __STR_H__ -#define __STR_H__ - -#ifdef __linux__ -#include -#endif - -/* -=============================================================================== - - Character string - -=============================================================================== -*/ - -class idVec4; - -#ifndef FILE_HASH_SIZE -#define FILE_HASH_SIZE 1024 -#endif - -// color escape character -const int C_COLOR_ESCAPE = '^'; -const int C_COLOR_DEFAULT = '0'; -const int C_COLOR_RED = '1'; -const int C_COLOR_GREEN = '2'; -const int C_COLOR_YELLOW = '3'; -const int C_COLOR_BLUE = '4'; -const int C_COLOR_CYAN = '5'; -const int C_COLOR_MAGENTA = '6'; -const int C_COLOR_WHITE = '7'; -const int C_COLOR_GRAY = '8'; -const int C_COLOR_BLACK = '9'; - -// color escape string -#define S_COLOR_DEFAULT "^0" -#define S_COLOR_RED "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW "^3" -#define S_COLOR_BLUE "^4" -#define S_COLOR_CYAN "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" -#define S_COLOR_GRAY "^8" -#define S_COLOR_BLACK "^9" - -// make idStr a multiple of 32 bytes long -// don't make too large to keep memory requirements to a minimum -const int STR_ALLOC_BASE = 20; -const int STR_ALLOC_GRAN = 32; - -typedef enum { - MEASURE_SIZE = 0, - MEASURE_BANDWIDTH -} Measure_t; - -class idStr { - -public: - idStr( void ); - idStr( const idStr &text ); - idStr( const idStr &text, int start, int end ); - idStr( const char *text ); - idStr( const char *text, int start, int end ); - explicit idStr( const bool b ); - explicit idStr( const char c ); - explicit idStr( const int i ); - explicit idStr( const unsigned u ); - explicit idStr( const float f ); - ~idStr( void ); - - size_t Size( void ) const; - const char * c_str( void ) const; - operator const char *( void ) const; - operator const char *( void ); - - char operator[]( int index ) const; - char & operator[]( int index ); - - void operator=( const idStr &text ); - void operator=( const char *text ); - - friend idStr operator+( const idStr &a, const idStr &b ); - friend idStr operator+( const idStr &a, const char *b ); - friend idStr operator+( const char *a, const idStr &b ); - - friend idStr operator+( const idStr &a, const float b ); - friend idStr operator+( const idStr &a, const int b ); - friend idStr operator+( const idStr &a, const unsigned b ); - friend idStr operator+( const idStr &a, const bool b ); - friend idStr operator+( const idStr &a, const char b ); - - idStr & operator+=( const idStr &a ); - idStr & operator+=( const char *a ); - idStr & operator+=( const float a ); - idStr & operator+=( const char a ); - idStr & operator+=( const int a ); - idStr & operator+=( const unsigned a ); - idStr & operator+=( const bool a ); - - // case sensitive compare - friend bool operator==( const idStr &a, const idStr &b ); - friend bool operator==( const idStr &a, const char *b ); - friend bool operator==( const char *a, const idStr &b ); - - // case sensitive compare - friend bool operator!=( const idStr &a, const idStr &b ); - friend bool operator!=( const idStr &a, const char *b ); - friend bool operator!=( const char *a, const idStr &b ); - - // case sensitive compare - int Cmp( const char *text ) const; - int Cmpn( const char *text, int n ) const; - int CmpPrefix( const char *text ) const; - - // case insensitive compare - int Icmp( const char *text ) const; - int Icmpn( const char *text, int n ) const; - int IcmpPrefix( const char *text ) const; - - // case insensitive compare ignoring color - int IcmpNoColor( const char *text ) const; - - // compares paths and makes sure folders come first - int IcmpPath( const char *text ) const; - int IcmpnPath( const char *text, int n ) const; - int IcmpPrefixPath( const char *text ) const; - - int Length( void ) const; - int Allocated( void ) const; - void Empty( void ); - bool IsEmpty( void ) const; - void Clear( void ); - void Append( const char a ); - void Append( const idStr &text ); - void Append( const char *text ); - void Append( const char *text, int len ); - void Insert( const char a, int index ); - void Insert( const char *text, int index ); - void ToLower( void ); - void ToUpper( void ); - bool IsNumeric( void ) const; - bool IsColor( void ) const; - bool HasLower( void ) const; - bool HasUpper( void ) const; - int LengthWithoutColors( void ) const; - idStr & RemoveColors( void ); - void CapLength( int ); - void Fill( const char ch, int newlen ); - - // returns -1 if not found otherwise the index of the char - int Find( const char c, int start = 0, int end = -1 ) const; - int Find( const char *text, bool casesensitive = true, int start = 0, int end = -1 ) const; - // Tels: Count how often c occurs between start and end - int Count( const char c, int start = 0, int end = -1 ) const; - // Tels: Given a list like "abcXdef" (where X = ',' but can be changed), returns one part of it randomly. - // If given an optional random value between 0.0 < x <= 1.0, then this will be used instead of gameLocal.random.RandomFloat() - idStr RandomPart( const char c = ',', const float rand = -1.0f) const; - bool Filter( const char *filter, bool casesensitive ) const; - int Last( const char c ) const; // return the index to the last occurance of 'c', returns -1 if not found - const char * Left( int len, idStr &result ) const; // store the leftmost 'len' characters in the result - const char * Right( int len, idStr &result ) const; // store the rightmost 'len' characters in the result - const char * Mid( int start, int len, idStr &result ) const; // store 'len' characters starting at 'start' in result - idStr Left( int len ) const; // return the leftmost 'len' characters - idStr Right( int len ) const; // return the rightmost 'len' characters - idStr Mid( int start, int len ) const; // return 'len' characters starting at 'start' - void StripLeading( const char c ); // strip char from front as many times as the char occurs - void StripLeading( const char *string ); // strip string from front as many times as the string occurs - bool StripLeadingOnce( const char *string ); // strip string from front just once if it occurs - void StripLeadingWhitespace( void ); // tels: strip leading white space characters (c <= 0x20) - void StripTrailing( const char c ); // strip char from end as many times as the char occurs - void StripTrailing( const char *string ); // strip string from end as many times as the string occurs - bool StripTrailingOnce( const char *string ); // strip string from end just once if it occurs - void Strip( const char c ); // strip char from front and end as many times as the char occurs - void Strip( const char *string ); // strip string from front and end as many times as the string occurs - void StripTrailingWhitespace( void ); // strip trailing white space characters (c <= 0x20) - idStr & StripQuotes( void ); // strip quotes around string - void Replace( const char *old, const char *nw ); - void Replace( const char old, const char nw ); // faster version of Repace() if you want to swap only one char - - // file name methods - int FileNameHash( void ) const; // hash key for the filename (skips extension) - idStr & BackSlashesToSlashes( void ); // convert slashes - idStr & SetFileExtension( const char *extension ); // set the given file extension - idStr & StripFileExtension( void ); // remove any file extension - idStr & StripAbsoluteFileExtension( void ); // remove any file extension looking from front (useful if there are multiple .'s) - idStr & DefaultFileExtension( const char *extension ); // if there's no file extension use the default - idStr & DefaultPath( const char *basepath ); // if there's no path use the default - void AppendPath( const char *text ); // append a partial path - idStr & StripFilename( void ); // remove the filename from a path - idStr & StripPath( void ); // remove the path from the filename - void ExtractFilePath( idStr &dest ) const; // copy the file path to another string - void ExtractFileName( idStr &dest ) const; // copy the filename to another string - void ExtractFileBase( idStr &dest ) const; // copy the filename minus the extension to another string - void ExtractFileExtension( idStr &dest ) const; // copy the file extension to another string - bool CheckExtension( const char *ext ); - - // char * methods to replace library functions - static int Length( const char *s ); - static char * ToLower( char *s ); - static char * ToUpper( char *s ); - static bool IsNumeric( const char *s ); - static bool IsColor( const char *s ); - static bool HasLower( const char *s ); - static bool HasUpper( const char *s ); - static int LengthWithoutColors( const char *s ); - static char * RemoveColors( char *s ); - static int Cmp( const char *s1, const char *s2 ); - static int Cmpn( const char *s1, const char *s2, int n ); - static int Icmp( const char *s1, const char *s2 ); - static int Icmpn( const char *s1, const char *s2, int n ); - static int IcmpNoColor( const char *s1, const char *s2 ); - static int IcmpPath( const char *s1, const char *s2 ); // compares paths and makes sure folders come first - static int IcmpnPath( const char *s1, const char *s2, int n ); // compares paths and makes sure folders come first - static void Append( char *dest, int size, const char *src ); - static void Copynz( char *dest, const char *src, int destsize ); - static int snPrintf( char *dest, int size, const char *fmt, ... ) id_attribute((format(printf,3,4))); - static int vsnPrintf( char *dest, int size, const char *fmt, va_list argptr ); - // returns -1 if not found otherwise the index of the char - static int FindChar( const char *str, const char c, int start = 0, int end = -1 ); - static int CountChar( const char *str, const char c, int start = 0, int end = -1 ); - static int FindText( const char *str, const char *text, bool casesensitive = true, int start = 0, int end = -1 ); - static bool Filter( const char *filter, const char *name, bool casesensitive ); - static void StripMediaName( const char *name, idStr &mediaName ); - static bool CheckExtension( const char *name, const char *ext ); - static const char * FloatArrayToString( const float *array, const int length, const int precision ); - - // hash keys - static int Hash( const char *string ); - static int Hash( const char *string, int length ); - static int IHash( const char *string ); // case insensitive - static int IHash( const char *string, int length ); // case insensitive - - // character methods - static char ToLower( char c ); - static char ToUpper( char c ); - static bool CharIsPrintable( int c ); - static bool CharIsLower( int c ); - static bool CharIsUpper( int c ); - static bool CharIsAlpha( int c ); - static bool CharIsNumeric( int c ); - static bool CharIsNewLine( char c ); - static bool CharIsTab( char c ); - static int ColorIndex( int c ); - static idVec4 & ColorForIndex( int i ); - - friend int sprintf( idStr &dest, const char *fmt, ... ); - friend int vsprintf( idStr &dest, const char *fmt, va_list ap ); - - void ReAllocate( int amount, bool keepold ); // reallocate string data buffer - void FreeData( void ); // free allocated string memory - - // format value in the given measurement with the best unit, returns the best unit - int BestUnit( const char *format, float value, Measure_t measure ); - // format value in the requested unit and measurement - void SetUnit( const char *format, float value, int unit, Measure_t measure ); - - static void InitMemory( void ); - static void ShutdownMemory( void ); - static void PurgeMemory( void ); - static void ShowMemoryUsage_f( const idCmdArgs &args ); - - int DynamicMemoryUsed() const; - static idStr FormatNumber( int number ); - -protected: - int len; - char * data; - int alloced; - char baseBuffer[ STR_ALLOC_BASE ]; - - void Init( void ); // initialize string using base buffer - void EnsureAlloced( int amount, bool keepold = true ); // ensure string data buffer is large anough -}; - -char * va( const char *fmt, ... ) id_attribute((format(printf,1,2))); - - -ID_INLINE void idStr::EnsureAlloced( int amount, bool keepold ) { - if ( amount > alloced ) { - ReAllocate( amount, keepold ); - } -} - -ID_INLINE void idStr::Init( void ) { - len = 0; - alloced = STR_ALLOC_BASE; - data = baseBuffer; - data[ 0 ] = '\0'; -#ifdef ID_DEBUG_UNINITIALIZED_MEMORY - memset( baseBuffer, 0, sizeof( baseBuffer ) ); -#endif -} - -ID_INLINE idStr::idStr( void ) { - Init(); -} - -ID_INLINE idStr::idStr( const idStr &text ) { - int l; - - Init(); - l = text.Length(); - EnsureAlloced( l + 1 ); - strcpy( data, text.data ); - len = l; -} - -ID_INLINE idStr::idStr( const idStr &text, int start, int end ) { - int i; - int l; - - Init(); - if ( end > text.Length() ) { - end = text.Length(); - } - if ( start > text.Length() ) { - start = text.Length(); - } else if ( start < 0 ) { - start = 0; - } - - l = end - start; - if ( l < 0 ) { - l = 0; - } - - EnsureAlloced( l + 1 ); - - for ( i = 0; i < l; i++ ) { - data[ i ] = text[ start + i ]; - } - - data[ l ] = '\0'; - len = l; -} - -ID_INLINE idStr::idStr( const char *text ) { - int l; - - Init(); - if ( text ) { - l = strlen( text ); - EnsureAlloced( l + 1 ); - strcpy( data, text ); - len = l; - } -} - -ID_INLINE idStr::idStr( const char *text, int start, int end ) { - int i; - int l = strlen( text ); - - Init(); - if ( end > l ) { - end = l; - } - if ( start > l ) { - start = l; - } else if ( start < 0 ) { - start = 0; - } - - l = end - start; - if ( l < 0 ) { - l = 0; - } - - EnsureAlloced( l + 1 ); - - for ( i = 0; i < l; i++ ) { - data[ i ] = text[ start + i ]; - } - - data[ l ] = '\0'; - len = l; -} - -ID_INLINE idStr::idStr( const bool b ) { - Init(); - EnsureAlloced( 2 ); - data[ 0 ] = b ? '1' : '0'; - data[ 1 ] = '\0'; - len = 1; -} - -ID_INLINE idStr::idStr( const char c ) { - Init(); - EnsureAlloced( 2 ); - data[ 0 ] = c; - data[ 1 ] = '\0'; - len = 1; -} - -ID_INLINE idStr::idStr( const int i ) { - char text[ 64 ]; - int l; - - Init(); - l = sprintf( text, "%d", i ); - EnsureAlloced( l + 1 ); - strcpy( data, text ); - len = l; -} - -ID_INLINE idStr::idStr( const unsigned u ) { - char text[ 64 ]; - int l; - - Init(); - l = sprintf( text, "%u", u ); - EnsureAlloced( l + 1 ); - strcpy( data, text ); - len = l; -} - -ID_INLINE idStr::idStr( const float f ) { - char text[ 64 ]; - int l; - - Init(); - l = idStr::snPrintf( text, sizeof( text ), "%f", f ); - while( l > 0 && text[l-1] == '0' ) text[--l] = '\0'; - while( l > 0 && text[l-1] == '.' ) text[--l] = '\0'; - EnsureAlloced( l + 1 ); - strcpy( data, text ); - len = l; -} - -ID_INLINE idStr::~idStr( void ) { - FreeData(); -} - -ID_INLINE size_t idStr::Size( void ) const { - return sizeof( *this ) + Allocated(); -} - -ID_INLINE const char *idStr::c_str( void ) const { - return data; -} - -ID_INLINE idStr::operator const char *( void ) { - return c_str(); -} - -ID_INLINE idStr::operator const char *( void ) const { - return c_str(); -} - -ID_INLINE char idStr::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index <= len ) ); - return data[ index ]; -} - -ID_INLINE char &idStr::operator[]( int index ) { - assert( ( index >= 0 ) && ( index <= len ) ); - return data[ index ]; -} - -ID_INLINE void idStr::operator=( const idStr &text ) { - int l; - - l = text.Length(); - EnsureAlloced( l + 1, false ); - memcpy( data, text.data, l ); - data[l] = '\0'; - len = l; -} - -ID_INLINE idStr operator+( const idStr &a, const idStr &b ) { - idStr result( a ); - result.Append( b ); - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const char *b ) { - idStr result( a ); - result.Append( b ); - return result; -} - -ID_INLINE idStr operator+( const char *a, const idStr &b ) { - idStr result( a ); - result.Append( b ); - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const bool b ) { - idStr result( a ); - result.Append( b ? "true" : "false" ); - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const char b ) { - idStr result( a ); - result.Append( b ); - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const float b ) { - char text[ 64 ]; - idStr result( a ); - - sprintf( text, "%f", b ); - result.Append( text ); - - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const int b ) { - char text[ 64 ]; - idStr result( a ); - - sprintf( text, "%d", b ); - result.Append( text ); - - return result; -} - -ID_INLINE idStr operator+( const idStr &a, const unsigned b ) { - char text[ 64 ]; - idStr result( a ); - - sprintf( text, "%u", b ); - result.Append( text ); - - return result; -} - -ID_INLINE idStr &idStr::operator+=( const float a ) { - char text[ 64 ]; - - sprintf( text, "%f", a ); - Append( text ); - - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const int a ) { - char text[ 64 ]; - - sprintf( text, "%d", a ); - Append( text ); - - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const unsigned a ) { - char text[ 64 ]; - - sprintf( text, "%u", a ); - Append( text ); - - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const idStr &a ) { - Append( a ); - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const char *a ) { - Append( a ); - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const char a ) { - Append( a ); - return *this; -} - -ID_INLINE idStr &idStr::operator+=( const bool a ) { - Append( a ? "true" : "false" ); - return *this; -} - -ID_INLINE bool operator==( const idStr &a, const idStr &b ) { - return ( !idStr::Cmp( a.data, b.data ) ); -} - -ID_INLINE bool operator==( const idStr &a, const char *b ) { - assert( b ); - return ( !idStr::Cmp( a.data, b ) ); -} - -ID_INLINE bool operator==( const char *a, const idStr &b ) { - assert( a ); - return ( !idStr::Cmp( a, b.data ) ); -} - -ID_INLINE bool operator!=( const idStr &a, const idStr &b ) { - return !( a == b ); -} - -ID_INLINE bool operator!=( const idStr &a, const char *b ) { - return !( a == b ); -} - -ID_INLINE bool operator!=( const char *a, const idStr &b ) { - return !( a == b ); -} - -ID_INLINE int idStr::Cmp( const char *text ) const { - assert( text ); - return idStr::Cmp( data, text ); -} - -ID_INLINE int idStr::Cmpn( const char *text, int n ) const { - assert( text ); - return idStr::Cmpn( data, text, n ); -} - -ID_INLINE int idStr::CmpPrefix( const char *text ) const { - assert( text ); - return idStr::Cmpn( data, text, strlen( text ) ); -} - -ID_INLINE int idStr::Icmp( const char *text ) const { - assert( text ); - return idStr::Icmp( data, text ); -} - -ID_INLINE int idStr::Icmpn( const char *text, int n ) const { - assert( text ); - return idStr::Icmpn( data, text, n ); -} - -ID_INLINE int idStr::IcmpPrefix( const char *text ) const { - assert( text ); - return idStr::Icmpn( data, text, strlen( text ) ); -} - -ID_INLINE int idStr::IcmpNoColor( const char *text ) const { - assert( text ); - return idStr::IcmpNoColor( data, text ); -} - -ID_INLINE int idStr::IcmpPath( const char *text ) const { - assert( text ); - return idStr::IcmpPath( data, text ); -} - -ID_INLINE int idStr::IcmpnPath( const char *text, int n ) const { - assert( text ); - return idStr::IcmpnPath( data, text, n ); -} - -ID_INLINE int idStr::IcmpPrefixPath( const char *text ) const { - assert( text ); - return idStr::IcmpnPath( data, text, strlen( text ) ); -} - -ID_INLINE int idStr::Length( void ) const { - return len; -} - -ID_INLINE int idStr::Allocated( void ) const { - if ( data != baseBuffer ) { - return alloced; - } else { - return 0; - } -} - -ID_INLINE void idStr::Empty( void ) { - EnsureAlloced( 1 ); - data[ 0 ] = '\0'; - len = 0; -} - -ID_INLINE bool idStr::IsEmpty( void ) const { - return ( idStr::Cmp( data, "" ) == 0 ); -} - -ID_INLINE void idStr::Clear( void ) { - FreeData(); - Init(); -} - -ID_INLINE void idStr::Append( const char a ) { - EnsureAlloced( len + 2 ); - data[ len ] = a; - len++; - data[ len ] = '\0'; -} - -ID_INLINE void idStr::Append( const idStr &text ) { - int newLen; - int i; - - newLen = len + text.Length(); - EnsureAlloced( newLen + 1 ); - for ( i = 0; i < text.len; i++ ) { - data[ len + i ] = text[ i ]; - } - len = newLen; - data[ len ] = '\0'; -} - -ID_INLINE void idStr::Append( const char *text ) { - int newLen; - int i; - - if ( text ) { - newLen = len + strlen( text ); - EnsureAlloced( newLen + 1 ); - for ( i = 0; text[ i ]; i++ ) { - data[ len + i ] = text[ i ]; - } - len = newLen; - data[ len ] = '\0'; - } -} - -ID_INLINE void idStr::Append( const char *text, int l ) { - int newLen; - int i; - - if ( text && l ) { - newLen = len + l; - EnsureAlloced( newLen + 1 ); - for ( i = 0; text[ i ] && i < l; i++ ) { - data[ len + i ] = text[ i ]; - } - len = newLen; - data[ len ] = '\0'; - } -} - -ID_INLINE void idStr::Insert( const char a, int index ) { - int i, l; - - if ( index < 0 ) { - index = 0; - } else if ( index > len ) { - index = len; - } - - l = 1; - EnsureAlloced( len + l + 1 ); - for ( i = len; i >= index; i-- ) { - data[i+l] = data[i]; - } - data[index] = a; - len++; -} - -ID_INLINE void idStr::Insert( const char *text, int index ) { - int i, l; - - if ( index < 0 ) { - index = 0; - } else if ( index > len ) { - index = len; - } - - l = strlen( text ); - EnsureAlloced( len + l + 1 ); - for ( i = len; i >= index; i-- ) { - data[i+l] = data[i]; - } - for ( i = 0; i < l; i++ ) { - data[index+i] = text[i]; - } - len += l; -} - -ID_INLINE void idStr::ToLower( void ) { - for (int i = 0; data[i]; i++ ) { - if ( CharIsUpper( data[i] ) ) { - data[i] += ( 'a' - 'A' ); - } - } -} - -ID_INLINE void idStr::ToUpper( void ) { - for (int i = 0; data[i]; i++ ) { - if ( CharIsLower( data[i] ) ) { - data[i] -= ( 'a' - 'A' ); - } - } -} - -ID_INLINE bool idStr::IsNumeric( void ) const { - return idStr::IsNumeric( data ); -} - -ID_INLINE bool idStr::IsColor( void ) const { - return idStr::IsColor( data ); -} - -ID_INLINE bool idStr::HasLower( void ) const { - return idStr::HasLower( data ); -} - -ID_INLINE bool idStr::HasUpper( void ) const { - return idStr::HasUpper( data ); -} - -ID_INLINE idStr &idStr::RemoveColors( void ) { - idStr::RemoveColors( data ); - len = Length( data ); - return *this; -} - -ID_INLINE int idStr::LengthWithoutColors( void ) const { - return idStr::LengthWithoutColors( data ); -} - -ID_INLINE void idStr::CapLength( int newlen ) { - if ( len <= newlen ) { - return; - } - data[ newlen ] = 0; - len = newlen; -} - -ID_INLINE void idStr::Fill( const char ch, int newlen ) { - EnsureAlloced( newlen + 1 ); - len = newlen; - memset( data, ch, len ); - data[ len ] = 0; -} - -ID_INLINE int idStr::Count( const char c, int start, int end ) const { - if ( end == -1 ) { - end = len; - } - return idStr::CountChar( data, c, start, end ); -} - -ID_INLINE int idStr::Find( const char c, int start, int end ) const { - if ( end == -1 ) { - end = len; - } - return idStr::FindChar( data, c, start, end ); -} - -ID_INLINE int idStr::Find( const char *text, bool casesensitive, int start, int end ) const { - if ( end == -1 ) { - end = len; - } - return idStr::FindText( data, text, casesensitive, start, end ); -} - -ID_INLINE bool idStr::Filter( const char *filter, bool casesensitive ) const { - return idStr::Filter( filter, data, casesensitive ); -} - -ID_INLINE const char *idStr::Left( int len, idStr &result ) const { - return Mid( 0, len, result ); -} - -ID_INLINE const char *idStr::Right( int len, idStr &result ) const { - if ( len >= Length() ) { - result = *this; - return result; - } - return Mid( Length() - len, len, result ); -} - -ID_INLINE idStr idStr::Left( int len ) const { - return Mid( 0, len ); -} - -ID_INLINE idStr idStr::Right( int len ) const { - if ( len >= Length() ) { - return *this; - } - return Mid( Length() - len, len ); -} - -ID_INLINE void idStr::Strip( const char c ) { - StripLeading( c ); - StripTrailing( c ); -} - -ID_INLINE void idStr::Strip( const char *string ) { - StripLeading( string ); - StripTrailing( string ); -} - -ID_INLINE bool idStr::CheckExtension( const char *ext ) { - return idStr::CheckExtension( data, ext ); -} - -ID_INLINE int idStr::Length( const char *s ) { - int i; - for ( i = 0; s[i]; i++ ) {} - return i; -} - -ID_INLINE char *idStr::ToLower( char *s ) { - for ( int i = 0; s[i]; i++ ) { - if ( CharIsUpper( s[i] ) ) { - s[i] += ( 'a' - 'A' ); - } - } - return s; -} - -ID_INLINE char *idStr::ToUpper( char *s ) { - for ( int i = 0; s[i]; i++ ) { - if ( CharIsLower( s[i] ) ) { - s[i] -= ( 'a' - 'A' ); - } - } - return s; -} - -ID_INLINE int idStr::Hash( const char *string ) { - int i, hash = 0; - for ( i = 0; *string != '\0'; i++ ) { - hash += ( *string++ ) * ( i + 119 ); - } - return hash; -} - -ID_INLINE int idStr::Hash( const char *string, int length ) { - int i, hash = 0; - for ( i = 0; i < length; i++ ) { - hash += ( *string++ ) * ( i + 119 ); - } - return hash; -} - -ID_INLINE int idStr::IHash( const char *string ) { - int i, hash = 0; - for( i = 0; *string != '\0'; i++ ) { - hash += ToLower( *string++ ) * ( i + 119 ); - } - return hash; -} - -ID_INLINE int idStr::IHash( const char *string, int length ) { - int i, hash = 0; - for ( i = 0; i < length; i++ ) { - hash += ToLower( *string++ ) * ( i + 119 ); - } - return hash; -} - -ID_INLINE bool idStr::IsColor( const char *s ) { - return ( s[0] == C_COLOR_ESCAPE && s[1] != '\0' && s[1] != ' ' ); -} - -ID_INLINE char idStr::ToLower( char c ) { - if ( c <= 'Z' && c >= 'A' ) { - return ( c + ( 'a' - 'A' ) ); - } - return c; -} - -ID_INLINE char idStr::ToUpper( char c ) { - if ( c >= 'a' && c <= 'z' ) { - return ( c - ( 'a' - 'A' ) ); - } - return c; -} - -ID_INLINE bool idStr::CharIsPrintable( int c ) { - // test for regular ascii and western European high-ascii chars - return ( c >= 0x20 && c <= 0x7E ) || ( c >= 0xA1 && c <= 0xFF ); -} - -ID_INLINE bool idStr::CharIsLower( int c ) { - // test for regular ascii and western European high-ascii chars - return ( c >= 'a' && c <= 'z' ) || ( c >= 0xE0 && c <= 0xFF ); -} - -ID_INLINE bool idStr::CharIsUpper( int c ) { - // test for regular ascii and western European high-ascii chars - return ( c <= 'Z' && c >= 'A' ) || ( c >= 0xC0 && c <= 0xDF ); -} - -ID_INLINE bool idStr::CharIsAlpha( int c ) { - // test for regular ascii and western European high-ascii chars - return ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || - ( c >= 0xC0 && c <= 0xFF ) ); -} - -ID_INLINE bool idStr::CharIsNumeric( int c ) { - return ( c <= '9' && c >= '0' ); -} - -ID_INLINE bool idStr::CharIsNewLine( char c ) { - return ( c == '\n' || c == '\r' || c == '\v' ); -} - -ID_INLINE bool idStr::CharIsTab( char c ) { - return ( c == '\t' ); -} - -ID_INLINE int idStr::ColorIndex( int c ) { - return ( c & 15 ); -} - -ID_INLINE int idStr::DynamicMemoryUsed() const { - return ( data == baseBuffer ) ? 0 : alloced; -} - -#endif /* !__STR_H__ */ diff --git a/idlib/timer.cpp b/idlib/timer.cpp deleted file mode 100644 index 546b98f64..000000000 --- a/idlib/timer.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -double idTimer::base = -1.0; - -/* -================= -idTimer::InitBaseClockTicks -================= -*/ -void idTimer::InitBaseClockTicks( void ) const { - idTimer timer; - double ct, b; - int i; - - base = 0.0; - b = -1.0; - for ( i = 0; i < 1000; i++ ) { - timer.Clear(); - timer.Start(); - timer.Stop(); - ct = timer.ClockTicks(); - if ( b < 0.0 || ct < b ) { - b = ct; - } - } - base = b; -} - - -/* -================= -idTimerReport::idTimerReport -================= -*/ -idTimerReport::idTimerReport() { -} - -/* -================= -idTimerReport::SetReportName -================= -*/ -void idTimerReport::SetReportName( const char *name ) { - reportName = ( name ) ? name : "Timer Report"; -} - -/* -================= -idTimerReport::~idTimerReport -================= -*/ -idTimerReport::~idTimerReport() { - Clear(); -} - -/* -================= -idTimerReport::AddReport -================= -*/ -int idTimerReport::AddReport( const char *name ) { - if ( name && *name ) { - names.Append( name ); - return timers.Append( new idTimer() ); - } - return -1; -} - -/* -================= -idTimerReport::Clear -================= -*/ -void idTimerReport::Clear() { - timers.DeleteContents( true ); - names.Clear(); - reportName.Clear(); -} - -/* -================= -idTimerReport::Reset -================= -*/ -void idTimerReport::Reset() { - assert ( timers.Num() == names.Num() ); - for ( int i = 0; i < timers.Num(); i++ ) { - timers[i]->Clear(); - } -} - -/* -================= -idTimerReport::AddTime -================= -*/ -void idTimerReport::AddTime( const char *name, idTimer *time ) { - assert ( timers.Num() == names.Num() ); - int i; - for ( i = 0; i < names.Num(); i++ ) { - if ( names[i].Icmp( name ) == 0 ) { - *timers[i] += *time; - break; - } - } - if ( i == names.Num() ) { - int index = AddReport( name ); - if ( index >= 0 ) { - timers[index]->Clear(); - *timers[index] += *time; - } - } -} - -/* -================= -idTimerReport::PrintReport -================= -*/ -void idTimerReport::PrintReport() { - assert( timers.Num() == names.Num() ); - idLib::common->Printf( "Timing Report for %s\n", reportName.c_str() ); - idLib::common->Printf( "-------------------------------\n" ); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Timing Report for %s\n", reportName.c_str()); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("-------------------------------\n"); - float total = 0.0f; - for ( int i = 0; i < names.Num(); i++ ) { - idLib::common->Printf( "%s consumed %5.2f seconds\n", names[i].c_str(), timers[i]->Milliseconds() * 0.001f ); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("%s consumed %5.2f seconds\n", names[i].c_str(), timers[i]->Milliseconds() * 0.001f); - total += timers[i]->Milliseconds(); - } - idLib::common->Printf( "Total time for report %s was %5.2f\n\n", reportName.c_str(), total * 0.001f ); - DM_LOG(LC_AI, LT_INFO)LOGSTRING("Total time for report %s was %5.2f\n\n", reportName.c_str(), total * 0.001f); -} diff --git a/idlib/timer.h b/idlib/timer.h deleted file mode 100644 index 9a97962d1..000000000 --- a/idlib/timer.h +++ /dev/null @@ -1,220 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __TIMER_H__ -#define __TIMER_H__ - -/* -=============================================================================== - - Clock tick counter. Should only be used for profiling. - -=============================================================================== -*/ - -class idTimer { -public: - idTimer( void ); - idTimer( double clockTicks ); - ~idTimer( void ); - - idTimer operator+( const idTimer &t ) const; - idTimer operator-( const idTimer &t ) const; - idTimer & operator+=( const idTimer &t ); - idTimer & operator-=( const idTimer &t ); - - void Start( void ); - void Stop( void ); - void Clear( void ); - - bool Running() const; - - double ClockTicks( void ) const; - double Milliseconds( void ) const; - -private: - static double base; - enum { - TS_STARTED, - TS_STOPPED - } state; - double start; - double clockTicks; - - void InitBaseClockTicks( void ) const; -}; - -/* -================= -idTimer::idTimer -================= -*/ -ID_INLINE idTimer::idTimer( void ) { - state = TS_STOPPED; - clockTicks = 0.0; -} - -/* -================= -idTimer::idTimer -================= -*/ -ID_INLINE idTimer::idTimer( double _clockTicks ) { - state = TS_STOPPED; - clockTicks = _clockTicks; -} - -/* -================= -idTimer::~idTimer -================= -*/ -ID_INLINE idTimer::~idTimer( void ) { -} - -/* -================= -idTimer::operator+ -================= -*/ -ID_INLINE idTimer idTimer::operator+( const idTimer &t ) const { - assert( state == TS_STOPPED && t.state == TS_STOPPED ); - return idTimer( clockTicks + t.clockTicks ); -} - -/* -================= -idTimer::operator- -================= -*/ -ID_INLINE idTimer idTimer::operator-( const idTimer &t ) const { - assert( state == TS_STOPPED && t.state == TS_STOPPED ); - return idTimer( clockTicks - t.clockTicks ); -} - -/* -================= -idTimer::operator+= -================= -*/ -ID_INLINE idTimer &idTimer::operator+=( const idTimer &t ) { - assert( state == TS_STOPPED && t.state == TS_STOPPED ); - clockTicks += t.clockTicks; - return *this; -} - -/* -================= -idTimer::operator-= -================= -*/ -ID_INLINE idTimer &idTimer::operator-=( const idTimer &t ) { - assert( state == TS_STOPPED && t.state == TS_STOPPED ); - clockTicks -= t.clockTicks; - return *this; -} - -/* -================= -idTimer::Start -================= -*/ -ID_INLINE void idTimer::Start( void ) { - assert( state == TS_STOPPED ); - state = TS_STARTED; - start = idLib::sys->GetClockTicks(); -} - -/* -================= -idTimer::Stop -================= -*/ -ID_INLINE void idTimer::Stop( void ) { - assert( state == TS_STARTED ); - clockTicks += idLib::sys->GetClockTicks() - start; - if ( base < 0.0 ) { - InitBaseClockTicks(); - } - if ( clockTicks > base ) { - clockTicks -= base; - } - state = TS_STOPPED; -} - -/* -================= -TDM: idTimer::Clear -================= -*/ -ID_INLINE bool idTimer::Running() const -{ - return state == TS_STARTED; -} - -/* -================= -idTimer::Clear -================= -*/ -ID_INLINE void idTimer::Clear( void ) { - clockTicks = 0.0; -} - -/* -================= -idTimer::ClockTicks -================= -*/ -ID_INLINE double idTimer::ClockTicks( void ) const { - assert( state == TS_STOPPED ); - return clockTicks; -} - -/* -================= -idTimer::Milliseconds -================= -*/ -ID_INLINE double idTimer::Milliseconds( void ) const { - assert( state == TS_STOPPED ); - return clockTicks / ( idLib::sys->ClockTicksPerSecond() * 0.001 ); -} - - -/* -=============================================================================== - - Report of multiple named timers. - -=============================================================================== -*/ - -class idTimerReport { -public: - idTimerReport( void ); - ~idTimerReport( void ); - - void SetReportName( const char *name ); - int AddReport( const char *name ); - void Clear( void ); - void Reset( void ); - void PrintReport( void ); - void AddTime( const char *name, idTimer *time ); - -private: - idListtimers; - idStrList names; - idStr reportName; -}; - -#endif /* !__TIMER_H__ */ diff --git a/idlib/token.cpp b/idlib/token.cpp deleted file mode 100644 index ed3268740..000000000 --- a/idlib/token.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#include "precompiled.h" -#pragma hdrstop - -static bool init_version = FileVersionList("$Id$", init_version); - -/* -================ -idToken::NumberValue -================ -*/ -void idToken::NumberValue( void ) { - int i, pow, div, c; - const char *p; - double m; - - assert( type == TT_NUMBER ); - p = c_str(); - floatvalue = 0; - intvalue = 0; - // floating point number - if ( subtype & TT_FLOAT ) { - if ( subtype & ( TT_INFINITE | TT_INDEFINITE | TT_NAN ) ) { - if ( subtype & TT_INFINITE ) { // 1.#INF - unsigned int inf = 0x7f800000; - floatvalue = (double) *(float*)&inf; - } - else if ( subtype & TT_INDEFINITE ) { // 1.#IND - unsigned int ind = 0xffc00000; - floatvalue = (double) *(float*)&ind; - } - else if ( subtype & TT_NAN ) { // 1.#QNAN - unsigned int nan = 0x7fc00000; - floatvalue = (double) *(float*)&nan; - } - } - else { - while( *p && *p != '.' && *p != 'e' ) { - floatvalue = floatvalue * 10.0 + (double) (*p - '0'); - p++; - } - if ( *p == '.' ) { - p++; - for( m = 0.1; *p && *p != 'e'; p++ ) { - floatvalue = floatvalue + (double) (*p - '0') * m; - m *= 0.1; - } - } - if ( *p == 'e' ) { - p++; - if ( *p == '-' ) { - div = true; - p++; - } - else if ( *p == '+' ) { - div = false; - p++; - } - else { - div = false; - } - pow = 0; - for ( pow = 0; *p; p++ ) { - pow = pow * 10 + (int) (*p - '0'); - } - for ( m = 1.0, i = 0; i < pow; i++ ) { - m *= 10.0; - } - if ( div ) { - floatvalue /= m; - } - else { - floatvalue *= m; - } - } - } - intvalue = idMath::Ftol( floatvalue ); - } - else if ( subtype & TT_DECIMAL ) { - while( *p ) { - intvalue = intvalue * 10 + (*p - '0'); - p++; - } - floatvalue = intvalue; - } - else if ( subtype & TT_IPADDRESS ) { - c = 0; - while( *p && *p != ':' ) { - if ( *p == '.' ) { - while( c != 3 ) { - intvalue = intvalue * 10; - c++; - } - c = 0; - } - else { - intvalue = intvalue * 10 + (*p - '0'); - c++; - } - p++; - } - while( c != 3 ) { - intvalue = intvalue * 10; - c++; - } - floatvalue = intvalue; - } - else if ( subtype & TT_OCTAL ) { - // step over the first zero - p += 1; - while( *p ) { - intvalue = (intvalue << 3) + (*p - '0'); - p++; - } - floatvalue = intvalue; - } - else if ( subtype & TT_HEX ) { - // step over the leading 0x or 0X - p += 2; - while( *p ) { - intvalue <<= 4; - if (*p >= 'a' && *p <= 'f') - intvalue += *p - 'a' + 10; - else if (*p >= 'A' && *p <= 'F') - intvalue += *p - 'A' + 10; - else - intvalue += *p - '0'; - p++; - } - floatvalue = intvalue; - } - else if ( subtype & TT_BINARY ) { - // step over the leading 0b or 0B - p += 2; - while( *p ) { - intvalue = (intvalue << 1) + (*p - '0'); - p++; - } - floatvalue = intvalue; - } - subtype |= TT_VALUESVALID; -} - -/* -================ -idToken::ClearTokenWhiteSpace -================ -*/ -void idToken::ClearTokenWhiteSpace( void ) { - whiteSpaceStart_p = NULL; - whiteSpaceEnd_p = NULL; - linesCrossed = 0; -} diff --git a/idlib/token.h b/idlib/token.h deleted file mode 100644 index 3ba72a907..000000000 --- a/idlib/token.h +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __TOKEN_H__ -#define __TOKEN_H__ - -/* -=============================================================================== - - idToken is a token read from a file or memory with idLexer or idParser - -=============================================================================== -*/ - -// token types -#define TT_STRING 1 // string -#define TT_LITERAL 2 // literal -#define TT_NUMBER 3 // number -#define TT_NAME 4 // name -#define TT_PUNCTUATION 5 // punctuation - -// number sub types -#define TT_INTEGER 0x00001 // integer -#define TT_DECIMAL 0x00002 // decimal number -#define TT_HEX 0x00004 // hexadecimal number -#define TT_OCTAL 0x00008 // octal number -#define TT_BINARY 0x00010 // binary number -#define TT_LONG 0x00020 // long int -#define TT_UNSIGNED 0x00040 // unsigned int -#define TT_FLOAT 0x00080 // floating point number -#define TT_SINGLE_PRECISION 0x00100 // float -#define TT_DOUBLE_PRECISION 0x00200 // double -#define TT_EXTENDED_PRECISION 0x00400 // long double -#define TT_INFINITE 0x00800 // infinite 1.#INF -#define TT_INDEFINITE 0x01000 // indefinite 1.#IND -#define TT_NAN 0x02000 // NaN -#define TT_IPADDRESS 0x04000 // ip address -#define TT_IPPORT 0x08000 // ip port -#define TT_VALUESVALID 0x10000 // set if intvalue and floatvalue are valid - -// string sub type is the length of the string -// literal sub type is the ASCII code -// punctuation sub type is the punctuation id -// name sub type is the length of the name - -class idToken : public idStr { - - friend class idParser; - friend class idLexer; - -public: - int type; // token type - int subtype; // token sub type - int line; // line in script the token was on - int linesCrossed; // number of lines crossed in white space before token - int flags; // token flags, used for recursive defines - -public: - idToken( void ); - idToken( const idToken *token ); - ~idToken( void ); - - void operator=( const idStr& text ); - void operator=( const char *text ); - - double GetDoubleValue( void ); // double value of TT_NUMBER - float GetFloatValue( void ); // float value of TT_NUMBER - unsigned long GetUnsignedLongValue( void ); // unsigned long value of TT_NUMBER - int GetIntValue( void ); // int value of TT_NUMBER - int WhiteSpaceBeforeToken( void ) const;// returns length of whitespace before token - void ClearTokenWhiteSpace( void ); // forget whitespace before token - - void NumberValue( void ); // calculate values for a TT_NUMBER - -private: - unsigned long intvalue; // integer value - double floatvalue; // floating point value - const char * whiteSpaceStart_p; // start of white space before token, only used by idLexer - const char * whiteSpaceEnd_p; // end of white space before token, only used by idLexer - idToken * next; // next token in chain, only used by idParser - - void AppendDirty( const char a ); // append character without adding trailing zero -}; - -ID_INLINE idToken::idToken( void ) { -} - -ID_INLINE idToken::idToken( const idToken *token ) { - *this = *token; -} - -ID_INLINE idToken::~idToken( void ) { -} - -ID_INLINE void idToken::operator=( const char *text) { - *static_cast(this) = text; -} - -ID_INLINE void idToken::operator=( const idStr& text ) { - *static_cast(this) = text; -} - -ID_INLINE double idToken::GetDoubleValue( void ) { - if ( type != TT_NUMBER ) { - return 0.0; - } - if ( !(subtype & TT_VALUESVALID) ) { - NumberValue(); - } - return floatvalue; -} - -ID_INLINE float idToken::GetFloatValue( void ) { - return (float) GetDoubleValue(); -} - -ID_INLINE unsigned long idToken::GetUnsignedLongValue( void ) { - if ( type != TT_NUMBER ) { - return 0; - } - if ( !(subtype & TT_VALUESVALID) ) { - NumberValue(); - } - return intvalue; -} - -ID_INLINE int idToken::GetIntValue( void ) { - return (int) GetUnsignedLongValue(); -} - -ID_INLINE int idToken::WhiteSpaceBeforeToken( void ) const { - return ( whiteSpaceEnd_p > whiteSpaceStart_p ); -} - -ID_INLINE void idToken::AppendDirty( const char a ) { - EnsureAlloced( len + 2, true ); - data[len++] = a; -} - -#endif /* !__TOKEN_H__ */ diff --git a/win32/libjpeg/include/cderror.h b/include/libjpeg/cderror.h similarity index 100% rename from win32/libjpeg/include/cderror.h rename to include/libjpeg/cderror.h diff --git a/win32/libjpeg/include/cdjpeg.h b/include/libjpeg/cdjpeg.h similarity index 100% rename from win32/libjpeg/include/cdjpeg.h rename to include/libjpeg/cdjpeg.h diff --git a/win32/libjpeg/include/jconfig.h b/include/libjpeg/jconfig.h similarity index 100% rename from win32/libjpeg/include/jconfig.h rename to include/libjpeg/jconfig.h diff --git a/win32/libjpeg/include/jdct.h b/include/libjpeg/jdct.h similarity index 100% rename from win32/libjpeg/include/jdct.h rename to include/libjpeg/jdct.h diff --git a/win32/libjpeg/include/jerror.h b/include/libjpeg/jerror.h similarity index 100% rename from win32/libjpeg/include/jerror.h rename to include/libjpeg/jerror.h diff --git a/win32/libjpeg/include/jinclude.h b/include/libjpeg/jinclude.h similarity index 100% rename from win32/libjpeg/include/jinclude.h rename to include/libjpeg/jinclude.h diff --git a/win32/libjpeg/include/jmemsys.h b/include/libjpeg/jmemsys.h similarity index 100% rename from win32/libjpeg/include/jmemsys.h rename to include/libjpeg/jmemsys.h diff --git a/win32/libjpeg/include/jmorecfg.h b/include/libjpeg/jmorecfg.h similarity index 100% rename from win32/libjpeg/include/jmorecfg.h rename to include/libjpeg/jmorecfg.h diff --git a/win32/libjpeg/include/jpegint.h b/include/libjpeg/jpegint.h similarity index 100% rename from win32/libjpeg/include/jpegint.h rename to include/libjpeg/jpegint.h diff --git a/win32/libjpeg/include/jpeglib.h b/include/libjpeg/jpeglib.h similarity index 100% rename from win32/libjpeg/include/jpeglib.h rename to include/libjpeg/jpeglib.h diff --git a/win32/libjpeg/include/jversion.h b/include/libjpeg/jversion.h similarity index 100% rename from win32/libjpeg/include/jversion.h rename to include/libjpeg/jversion.h diff --git a/win32/libjpeg/include/transupp.h b/include/libjpeg/transupp.h similarity index 100% rename from win32/libjpeg/include/transupp.h rename to include/libjpeg/transupp.h diff --git a/win32/libpng/include/png.h b/include/libpng/png.h similarity index 100% rename from win32/libpng/include/png.h rename to include/libpng/png.h diff --git a/win32/libpng/include/pngconf.h b/include/libpng/pngconf.h similarity index 100% rename from win32/libpng/include/pngconf.h rename to include/libpng/pngconf.h diff --git a/win32/libpng/include/pngpriv.h b/include/libpng/pngpriv.h similarity index 100% rename from win32/libpng/include/pngpriv.h rename to include/libpng/pngpriv.h diff --git a/lib/curl/polarssl.h b/lib/curl/polarssl.h index 964af1728..9228cdd83 100644 --- a/lib/curl/polarssl.h +++ b/lib/curl/polarssl.h @@ -20,7 +20,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id: polarssl.h,v 1.10 2009-02-12 20:48:43 danf Exp $ + * $Id$ ***************************************************************************/ #ifdef USE_POLARSSL diff --git a/lib/devil/il_png.c b/lib/devil/il_png.c index 508bb328f..9071c9eae 100644 --- a/lib/devil/il_png.c +++ b/lib/devil/il_png.c @@ -277,8 +277,14 @@ ILboolean readpng_get_image(ILdouble display_exponent) &bit_depth, &color_type, NULL, NULL, NULL); // Expand low-bit-depth grayscale images to 8 bits - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + { +// greebo: We have libpng 1.4.x, hack this for proper linking +#if PNG_LIBPNG_VER < 10400 png_set_gray_1_2_4_to_8(png_ptr); +#else + png_set_expand_gray_1_2_4_to_8(png_ptr); +#endif } // Expand RGB images with transparency to full alpha channels diff --git a/win32/libjpeg/src/ansi2knr.c b/lib/libjpeg/ansi2knr.c similarity index 100% rename from win32/libjpeg/src/ansi2knr.c rename to lib/libjpeg/ansi2knr.c diff --git a/win32/libjpeg/src/cdjpeg.c b/lib/libjpeg/cdjpeg.c similarity index 100% rename from win32/libjpeg/src/cdjpeg.c rename to lib/libjpeg/cdjpeg.c diff --git a/win32/libjpeg/src/cjpeg.c b/lib/libjpeg/cjpeg.c similarity index 100% rename from win32/libjpeg/src/cjpeg.c rename to lib/libjpeg/cjpeg.c diff --git a/win32/libjpeg/src/ckconfig.c b/lib/libjpeg/ckconfig.c similarity index 100% rename from win32/libjpeg/src/ckconfig.c rename to lib/libjpeg/ckconfig.c diff --git a/win32/libjpeg/src/djpeg.c b/lib/libjpeg/djpeg.c similarity index 100% rename from win32/libjpeg/src/djpeg.c rename to lib/libjpeg/djpeg.c diff --git a/win32/libjpeg/src/example.c b/lib/libjpeg/example.c similarity index 100% rename from win32/libjpeg/src/example.c rename to lib/libjpeg/example.c diff --git a/win32/libjpeg/src/jaricom.c b/lib/libjpeg/jaricom.c similarity index 100% rename from win32/libjpeg/src/jaricom.c rename to lib/libjpeg/jaricom.c diff --git a/win32/libjpeg/src/jcapimin.c b/lib/libjpeg/jcapimin.c similarity index 100% rename from win32/libjpeg/src/jcapimin.c rename to lib/libjpeg/jcapimin.c diff --git a/win32/libjpeg/src/jcapistd.c b/lib/libjpeg/jcapistd.c similarity index 100% rename from win32/libjpeg/src/jcapistd.c rename to lib/libjpeg/jcapistd.c diff --git a/win32/libjpeg/src/jcarith.c b/lib/libjpeg/jcarith.c similarity index 100% rename from win32/libjpeg/src/jcarith.c rename to lib/libjpeg/jcarith.c diff --git a/win32/libjpeg/src/jccoefct.c b/lib/libjpeg/jccoefct.c similarity index 100% rename from win32/libjpeg/src/jccoefct.c rename to lib/libjpeg/jccoefct.c diff --git a/win32/libjpeg/src/jccolor.c b/lib/libjpeg/jccolor.c similarity index 100% rename from win32/libjpeg/src/jccolor.c rename to lib/libjpeg/jccolor.c diff --git a/win32/libjpeg/src/jcdctmgr.c b/lib/libjpeg/jcdctmgr.c similarity index 100% rename from win32/libjpeg/src/jcdctmgr.c rename to lib/libjpeg/jcdctmgr.c diff --git a/win32/libjpeg/src/jchuff.c b/lib/libjpeg/jchuff.c similarity index 100% rename from win32/libjpeg/src/jchuff.c rename to lib/libjpeg/jchuff.c diff --git a/win32/libjpeg/src/jcinit.c b/lib/libjpeg/jcinit.c similarity index 100% rename from win32/libjpeg/src/jcinit.c rename to lib/libjpeg/jcinit.c diff --git a/win32/libjpeg/src/jcmainct.c b/lib/libjpeg/jcmainct.c similarity index 100% rename from win32/libjpeg/src/jcmainct.c rename to lib/libjpeg/jcmainct.c diff --git a/win32/libjpeg/src/jcmarker.c b/lib/libjpeg/jcmarker.c similarity index 100% rename from win32/libjpeg/src/jcmarker.c rename to lib/libjpeg/jcmarker.c diff --git a/win32/libjpeg/src/jcmaster.c b/lib/libjpeg/jcmaster.c similarity index 100% rename from win32/libjpeg/src/jcmaster.c rename to lib/libjpeg/jcmaster.c diff --git a/win32/libjpeg/src/jcomapi.c b/lib/libjpeg/jcomapi.c similarity index 100% rename from win32/libjpeg/src/jcomapi.c rename to lib/libjpeg/jcomapi.c diff --git a/win32/libjpeg/src/jcparam.c b/lib/libjpeg/jcparam.c similarity index 100% rename from win32/libjpeg/src/jcparam.c rename to lib/libjpeg/jcparam.c diff --git a/win32/libjpeg/src/jcprepct.c b/lib/libjpeg/jcprepct.c similarity index 100% rename from win32/libjpeg/src/jcprepct.c rename to lib/libjpeg/jcprepct.c diff --git a/win32/libjpeg/src/jcsample.c b/lib/libjpeg/jcsample.c similarity index 100% rename from win32/libjpeg/src/jcsample.c rename to lib/libjpeg/jcsample.c diff --git a/win32/libjpeg/src/jctrans.c b/lib/libjpeg/jctrans.c similarity index 100% rename from win32/libjpeg/src/jctrans.c rename to lib/libjpeg/jctrans.c diff --git a/win32/libjpeg/src/jdapimin.c b/lib/libjpeg/jdapimin.c similarity index 100% rename from win32/libjpeg/src/jdapimin.c rename to lib/libjpeg/jdapimin.c diff --git a/win32/libjpeg/src/jdapistd.c b/lib/libjpeg/jdapistd.c similarity index 100% rename from win32/libjpeg/src/jdapistd.c rename to lib/libjpeg/jdapistd.c diff --git a/win32/libjpeg/src/jdarith.c b/lib/libjpeg/jdarith.c similarity index 100% rename from win32/libjpeg/src/jdarith.c rename to lib/libjpeg/jdarith.c diff --git a/win32/libjpeg/src/jdatadst.c b/lib/libjpeg/jdatadst.c similarity index 100% rename from win32/libjpeg/src/jdatadst.c rename to lib/libjpeg/jdatadst.c diff --git a/win32/libjpeg/src/jdatasrc.c b/lib/libjpeg/jdatasrc.c similarity index 100% rename from win32/libjpeg/src/jdatasrc.c rename to lib/libjpeg/jdatasrc.c diff --git a/win32/libjpeg/src/jdcoefct.c b/lib/libjpeg/jdcoefct.c similarity index 100% rename from win32/libjpeg/src/jdcoefct.c rename to lib/libjpeg/jdcoefct.c diff --git a/win32/libjpeg/src/jdcolor.c b/lib/libjpeg/jdcolor.c similarity index 100% rename from win32/libjpeg/src/jdcolor.c rename to lib/libjpeg/jdcolor.c diff --git a/win32/libjpeg/src/jddctmgr.c b/lib/libjpeg/jddctmgr.c similarity index 100% rename from win32/libjpeg/src/jddctmgr.c rename to lib/libjpeg/jddctmgr.c diff --git a/win32/libjpeg/src/jdhuff.c b/lib/libjpeg/jdhuff.c similarity index 100% rename from win32/libjpeg/src/jdhuff.c rename to lib/libjpeg/jdhuff.c diff --git a/win32/libjpeg/src/jdinput.c b/lib/libjpeg/jdinput.c similarity index 100% rename from win32/libjpeg/src/jdinput.c rename to lib/libjpeg/jdinput.c diff --git a/win32/libjpeg/src/jdmainct.c b/lib/libjpeg/jdmainct.c similarity index 100% rename from win32/libjpeg/src/jdmainct.c rename to lib/libjpeg/jdmainct.c diff --git a/win32/libjpeg/src/jdmarker.c b/lib/libjpeg/jdmarker.c similarity index 100% rename from win32/libjpeg/src/jdmarker.c rename to lib/libjpeg/jdmarker.c diff --git a/win32/libjpeg/src/jdmaster.c b/lib/libjpeg/jdmaster.c similarity index 100% rename from win32/libjpeg/src/jdmaster.c rename to lib/libjpeg/jdmaster.c diff --git a/win32/libjpeg/src/jdmerge.c b/lib/libjpeg/jdmerge.c similarity index 100% rename from win32/libjpeg/src/jdmerge.c rename to lib/libjpeg/jdmerge.c diff --git a/win32/libjpeg/src/jdpostct.c b/lib/libjpeg/jdpostct.c similarity index 100% rename from win32/libjpeg/src/jdpostct.c rename to lib/libjpeg/jdpostct.c diff --git a/win32/libjpeg/src/jdsample.c b/lib/libjpeg/jdsample.c similarity index 100% rename from win32/libjpeg/src/jdsample.c rename to lib/libjpeg/jdsample.c diff --git a/win32/libjpeg/src/jdtrans.c b/lib/libjpeg/jdtrans.c similarity index 100% rename from win32/libjpeg/src/jdtrans.c rename to lib/libjpeg/jdtrans.c diff --git a/win32/libjpeg/src/jerror.c b/lib/libjpeg/jerror.c similarity index 100% rename from win32/libjpeg/src/jerror.c rename to lib/libjpeg/jerror.c diff --git a/win32/libjpeg/src/jfdctflt.c b/lib/libjpeg/jfdctflt.c similarity index 100% rename from win32/libjpeg/src/jfdctflt.c rename to lib/libjpeg/jfdctflt.c diff --git a/win32/libjpeg/src/jfdctfst.c b/lib/libjpeg/jfdctfst.c similarity index 100% rename from win32/libjpeg/src/jfdctfst.c rename to lib/libjpeg/jfdctfst.c diff --git a/win32/libjpeg/src/jfdctint.c b/lib/libjpeg/jfdctint.c similarity index 100% rename from win32/libjpeg/src/jfdctint.c rename to lib/libjpeg/jfdctint.c diff --git a/win32/libjpeg/src/jidctflt.c b/lib/libjpeg/jidctflt.c similarity index 100% rename from win32/libjpeg/src/jidctflt.c rename to lib/libjpeg/jidctflt.c diff --git a/win32/libjpeg/src/jidctfst.c b/lib/libjpeg/jidctfst.c similarity index 100% rename from win32/libjpeg/src/jidctfst.c rename to lib/libjpeg/jidctfst.c diff --git a/win32/libjpeg/src/jidctint.c b/lib/libjpeg/jidctint.c similarity index 100% rename from win32/libjpeg/src/jidctint.c rename to lib/libjpeg/jidctint.c diff --git a/win32/libjpeg/src/jmemansi.c b/lib/libjpeg/jmemansi.c similarity index 100% rename from win32/libjpeg/src/jmemansi.c rename to lib/libjpeg/jmemansi.c diff --git a/win32/libjpeg/src/jmemmgr.c b/lib/libjpeg/jmemmgr.c similarity index 100% rename from win32/libjpeg/src/jmemmgr.c rename to lib/libjpeg/jmemmgr.c diff --git a/win32/libjpeg/src/jmemname.c b/lib/libjpeg/jmemname.c similarity index 100% rename from win32/libjpeg/src/jmemname.c rename to lib/libjpeg/jmemname.c diff --git a/win32/libjpeg/src/jmemnobs.c b/lib/libjpeg/jmemnobs.c similarity index 100% rename from win32/libjpeg/src/jmemnobs.c rename to lib/libjpeg/jmemnobs.c diff --git a/win32/libjpeg/src/jpegtran.c b/lib/libjpeg/jpegtran.c similarity index 100% rename from win32/libjpeg/src/jpegtran.c rename to lib/libjpeg/jpegtran.c diff --git a/win32/libjpeg/src/jquant1.c b/lib/libjpeg/jquant1.c similarity index 100% rename from win32/libjpeg/src/jquant1.c rename to lib/libjpeg/jquant1.c diff --git a/win32/libjpeg/src/jquant2.c b/lib/libjpeg/jquant2.c similarity index 100% rename from win32/libjpeg/src/jquant2.c rename to lib/libjpeg/jquant2.c diff --git a/win32/libjpeg/src/jutils.c b/lib/libjpeg/jutils.c similarity index 100% rename from win32/libjpeg/src/jutils.c rename to lib/libjpeg/jutils.c diff --git a/win32/libjpeg/src/transupp.c b/lib/libjpeg/transupp.c similarity index 100% rename from win32/libjpeg/src/transupp.c rename to lib/libjpeg/transupp.c diff --git a/win32/libpng/src/png.c b/lib/libpng/png.c similarity index 100% rename from win32/libpng/src/png.c rename to lib/libpng/png.c diff --git a/win32/libpng/src/pngerror.c b/lib/libpng/pngerror.c similarity index 100% rename from win32/libpng/src/pngerror.c rename to lib/libpng/pngerror.c diff --git a/win32/libpng/src/pngget.c b/lib/libpng/pngget.c similarity index 100% rename from win32/libpng/src/pngget.c rename to lib/libpng/pngget.c diff --git a/win32/libpng/src/pngmem.c b/lib/libpng/pngmem.c similarity index 100% rename from win32/libpng/src/pngmem.c rename to lib/libpng/pngmem.c diff --git a/win32/libpng/src/pngpread.c b/lib/libpng/pngpread.c similarity index 100% rename from win32/libpng/src/pngpread.c rename to lib/libpng/pngpread.c diff --git a/win32/libpng/src/pngread.c b/lib/libpng/pngread.c similarity index 100% rename from win32/libpng/src/pngread.c rename to lib/libpng/pngread.c diff --git a/win32/libpng/src/pngrio.c b/lib/libpng/pngrio.c similarity index 100% rename from win32/libpng/src/pngrio.c rename to lib/libpng/pngrio.c diff --git a/win32/libpng/src/pngrtran.c b/lib/libpng/pngrtran.c similarity index 100% rename from win32/libpng/src/pngrtran.c rename to lib/libpng/pngrtran.c diff --git a/win32/libpng/src/pngrutil.c b/lib/libpng/pngrutil.c similarity index 100% rename from win32/libpng/src/pngrutil.c rename to lib/libpng/pngrutil.c diff --git a/win32/libpng/src/pngset.c b/lib/libpng/pngset.c similarity index 100% rename from win32/libpng/src/pngset.c rename to lib/libpng/pngset.c diff --git a/win32/libpng/src/pngtest.c b/lib/libpng/pngtest.c similarity index 100% rename from win32/libpng/src/pngtest.c rename to lib/libpng/pngtest.c diff --git a/win32/libpng/src/pngtrans.c b/lib/libpng/pngtrans.c similarity index 100% rename from win32/libpng/src/pngtrans.c rename to lib/libpng/pngtrans.c diff --git a/win32/libpng/src/pngwio.c b/lib/libpng/pngwio.c similarity index 100% rename from win32/libpng/src/pngwio.c rename to lib/libpng/pngwio.c diff --git a/win32/libpng/src/pngwrite.c b/lib/libpng/pngwrite.c similarity index 100% rename from win32/libpng/src/pngwrite.c rename to lib/libpng/pngwrite.c diff --git a/win32/libpng/src/pngwtran.c b/lib/libpng/pngwtran.c similarity index 100% rename from win32/libpng/src/pngwtran.c rename to lib/libpng/pngwtran.c diff --git a/win32/libpng/src/pngwutil.c b/lib/libpng/pngwutil.c similarity index 100% rename from win32/libpng/src/pngwutil.c rename to lib/libpng/pngwutil.c diff --git a/linuxBuild.sh b/linuxBuild.sh deleted file mode 100755 index 9a4fbbd1b..000000000 --- a/linuxBuild.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -mkdir -p ~/.doom3/darkmod - -# $@ = pass along the flags like "BUILD=profile" or "BUILD=debug" -time scons -j2 BUILD_GAMEPAK=1 "$@" && cp tdm_game02.pk4 ~/.doom3/darkmod/ -mv gamex86-base.so gamex86.so -strip gamex86.so diff --git a/macosx/libjpeg/libjpeg.a b/macosx/libjpeg/libjpeg.a deleted file mode 100644 index 026765413..000000000 Binary files a/macosx/libjpeg/libjpeg.a and /dev/null differ diff --git a/macosx/libpng/libpng12.a b/macosx/libpng/libpng12.a deleted file mode 100644 index 6fecb0596..000000000 Binary files a/macosx/libpng/libpng12.a and /dev/null differ diff --git a/openal/docs/ChangeLog b/openal/docs/ChangeLog new file mode 100644 index 000000000..b4eb754d2 --- /dev/null +++ b/openal/docs/ChangeLog @@ -0,0 +1,378 @@ +2001-02-06 Bernd Kreimeier + + * chp-rendering.sgml: added annotation about CONE calculation. + * chp-state.sgml: added more annotation on log vs. linear GAIN. + +2001-01-09 Bernd Kreimeier + + * chp-state.sgml: ungrep of scratched DISTANCE_SCALE. + +2001-01-08 Bernd Kreimeier + + * chp-rendering.sgml: amended MAX_DISTANCE. + * chp-state.sgml: culling clarification. + Note: MAX_DISTANCE (and consequently the current + Inverse Clamped Distance Model) do not fit the API. + The clamping of the distance (instead of clamping + to the effective gain at the max. distance) will + potentially break other distance-dependend calculations + further down in the processing chain. + TODO: revisit Inverse Clamped Distance Model. _DS3D extension? + +2001-01-05 Bernd Kreimeier + + * chp-rendering.sgml: SOURCE_RELATIVE specification. + + * chp-state.sgml: clarified distance attentuation calculation + a bit, and added back in the linear version as an annotation. + Note: watch this, it's tied into the GAIN_LINEAR issue. + TODO: added dist calculation requirements. + +2001-01-04 Bernd Kreimeier + + * chp-operation.sgml: INVALID_ENUM for getters and enable, + not INVALID_OPERATION. Later: Delete{Object}s accepts zero. + +2000-12-04 Bernd Kreimeier + + * Makefile: added HTML ZIP targets ("update" for website). + +2000-11-10 Bernd Kreimeier + + * WWW: reworked the OpenAL web site as in CVS. This + includes emptying HTML files with obsolete whitepaper + and specification content not even linked from the + official pages, and reworking the official pages to + remove redundancy, and generally point to the snapshots. + Also created snapshots page (along with cronjob and + automated update installed by Rafael). + + * Makefile: added ZIP file generation to update target. + + * index.html: edited for snapshots/ page on www.openal.org. + As it is next to impossible to reproduce the Official OpenAL + Look w/o lots of tap dancing, I use the style from the + DocBook HTML rendering instead. + +2000-11-06 Bernd Kreimeier + + * Makefile (full): full rendering target added. + * ent-marks-full.sgml: created. + +2000-10-27 Bernd Kreimeier + + * Makefile: rendering targets for cronjob driven update. + +2000-10-26 Bernd Kreimeier + + * alc-context.sgml: annotation on release of hardware resources. + Removed version query enry point, added size-safe GetIntegerv + and GetString, removed GetErrorString, added integer and string + query tokens, added device enumeration query. Added more annotation. + + * chp-rendering.sgml: remark on release of hardware resources. + + * alc-context.sgml: had INVALID_DEVICE also marked by RFC. + Removed the "device parameter should be NULL" leftovers. + Added Query functions. Removed redundant device parameters + to avoid GLX-style redundancy and resulting BadMatch errors. + + +2000-10-25 Bernd Kreimeier + + * oalspecs.sgml: include extension list entity (below). + * ent-extensions.sgml: created. + Note: during several unsuccessful attempts to convince + DocBook and the DocBook toolchain to handle CDATA external + entities properly for and , + I also had to recover accidentally deleted files. + +2000-10-24 Bernd Kreimeier + + * alc-context.sgml: shared object section. Mike Kelly request + as RFC. ALC Error section placeholder. ALC attribute section + as placeholder. Process/Suspend added plus annotation, Update + removed. More typo fixes. Added extension query. Removed old + RFC's. No UNDERFLOW error. No CHANNELS attribute, MIXAHEAD + redundant. Removed alcUpdate( PROCESS | SUSPEND ) RFC. + + +2000-10-23 Bernd Kreimeier + + * alc-context.sgml: entities for ALCdevice and ALCcontext. + Fixed typos reported by CarloV on non-pointer handles. + + * chp-rendering.sgml: infinite LOOPING attribute. + +2000-10-20 Bernd Kreimeier + + * ent-examples.sgml: experimenting with external sample.c + files as CDATA entities, to no avail. + * oalspecs.sgml: example entities. + +2000-10-16 Bernd Kreimeier + + * chp-rendering.sgml: moved in buffer queueing. + Scratched PLAY_COUNT. Fixed SourceStart{v} residue. + + * chp-queueing.sgml: proof-reading, contents then moved out. + +2000-10-13 Bernd Kreimeier + + * chp-queueing.sgml: changed according to discussion. + Removed some, but not all redundant annotation, and removed + remainders of old attribute based approach. Added annotation + on repetition by multiple calls. Changed signatures. + +2000-10-11 Bernd Kreimeier + + * chp-state.sgml: removed GAIN_LINAR based equations. + * chp-rendering.sgml: removed GAIN_LINAR. + * ext-gainlinear.sgml: collected GAIN_LINEAR related sections. + Note: choosing to use GAIN_LINEAR_LOKI for now. The duplication + of tokens complicates specification and implementation, and + requires further discussion. + + * ent-marks.sgml: added Revision mark. + + * oalspecs.sgml: added per-file revision history (appendix). + Note: we might wind up never rendering these, I can't see + a consistent way to do this. + + * ChangeLog: moved in revision history from oalspecs.sgml. + Note: see the very first entry in this document for the + revision history that predates this ChangeLog. + TODO: include ChangeLog in RFC/Revision rendering. + + * chp-introduction.sgml: removed CVS based revision history. + Added a %Revision marked section (we now have these per-file). + +2000-10-10 Bernd Kreimeier + + * oalspecs.sgml: reworked for new distributed document. + + * app-annotations.sgml: created from original doc. + * app-extensionprocess.sgml: created from original doc. + * app-extensions.sgml: created from original doc. + * app-constants.sgml: created from original doc. + + * alc-context.sgml: created from original doc. + Note: this breaks the scheme a bit, as this is technically + a chapter, but if ALC turns into a multi-chapter + documentation at some point down the road it will have + to be a separate document anyway. + + * chp-multichannel.sgml: created from original doc. + * chp-queueing.sgml: created from original doc. + * chp-buffers.sgml: created from original doc. + * chp-rendering.sgml: created from original doc. + * chp-state.sgml: created from original doc. + * chp-operation.sgml: created from original doc. + * chp-introduction.sgml: created from original doc. + * sec-bookinfo.sgml: created from original doc. + + * ent-names.sgml: created from original doc. + * ent-marks.sgml: got it working. + Note: this will be a temporary file (created from the Makefile), + not sure whether it should be in CVS at all. + + * ChangeLog: created. + +2000--1999 Bernd Kreimeier + + * oalspecs.sgml: moved out CVS Revision History (below). + + The AL Specification was originally maintained as an HTML + document, and subsequently as a single SGML file. With the + split into several files, it is no longer possible or + desirable to maintain a single revision history. As we + have a manually maintained revhistory within the DocBook + source, I decided to move the old revision history into + the ChangeLog. + + Revision 1.11 2000/10/11 18:44:46 bk + More JMJ typo corrections. IA-SID I3DL2 section rephrased. Moved + marked section toggles in ent-marks.sgml file so that these can + be generated or modified from the Makefile. Split document up into + several separate files using external entities. Created external + ChangeLog. From now on, revision history and changes will be + maintained in the ChangeLog as it is scattered over files. + + Revision 1.10 2000/09/27 22:57:02 bk + Commit w/o subdoc (doesn't work). + + Revision 1.9 2000/09/27 22:54:36 bk + Typos from MKV and JMJ. Fixed Inverse Square Law. Scratched + ProgagationSpeed. Described distance models in full. Changed + to INVERSE_DISTANCE (both models use ROF). Added GH text (parts) + as annotation to "View" sections, added Basic AL Operation text + he sent (some changes, removed redundant section), marked source + as Example sections. Changed Terminology annotation. Added TBA + on Fundamentals. RFC'ed distributed error section from GL and + annotation. Added TBA on Floating Point Computation. Added AL + State TBA. Added AL entity as opposed to OAL. Added Command Syntax + TBA (minimal) plus annotation. More fixes from JMJ. No NaN + check comment. Rephrased invalid commmands. Disclaimer on + Enable/Disable being unused. Query with NULL destination + clarified. Example values for simple query. TBA on data + conversions. Cleaned out Time query/scaling, added RFC, + marked DURATION/REMAINDER as Scratch. Euclidean. No Transforms + now annotation. Promoted RFC on Source( BUFER, NONE ) to spec + text. Scratch'ed Streaming Buffer remarks. Removed IMPLIED. + Scratch'ed Buffer Traversal and a whole shebang of queueing + annotation to go with it. ALC cleanup, RFC on multiple + current contexts. Skipped Buffer Queueing section for now. + SUBDOC NO in DocBook declaration. Validation pass for CVS. + + Revision 1.8 2000/09/20 01:21:33 bk + Fixes from Ian Ollman: fixed wrong title on Buffer Attributes + section. Annotation on No application selected Names. Fixes + from JMJ: typos and mistakes on I3DL2. Renamed LOOP_COUNT to + PLAY_COUNT and clarified counting as requested. DOPPLER_FACTOR, + DOPPLER_VELOCITY, Doppler Effect section rewritten according to + announced changes. Removed DistanceFactor, added scale invariance. + Scratch-marked Multichannel sketch. Added BufferWriteData as Loki + extension. Removed obsolete RFC on depercating BUFFER. Rewrote + Buffer queueing state section and renamed BUFFERS_USED to + BUFFERS_PROCESSED following discussion with John Kraft, to remove + ambiguity. Rewrote BUFFERS_PROCESSED description. Added + MAX_DISTANCE plus MUTE annotation. Added No Culling section. + Edited DISTANCE_MODEL section. Distance Model Source Attributes + added. Rolloff quantization annotation added. Evaluation order + on attenuation/gain. Marked Scratch the current IASIG section + per JMJ's request, added Source Environment Attribute section + as TBA. Removed and moved RFC's (AppendData, GenStreaming). + Clarified directional attenuation. Clarified CONE_OUTER_GAIN + as scaling factor. Added a Programmers and Implementors View. + + Revision 1.7 2000/08/15 02:47:03 bk + Fixed RFC markup error needed for Full version. + + Revision 1.6 2000/08/15 02:20:49 bk + Clarified BUFFER_USED vs. buffer state. Started section on + handling multichannel output. Moved out GenStreamingBuffer + in annotation on BufferAppendData extension. Added BufferWriteData + with internalFormat parameter and discussion on mono vs. + multichannel buffers. Added Multichannel objects (kept short in + case we demote to extension or replace). Some annotation. + Tried GGI docbook2texi in attempt to end those rogue linux/doc + activities, to no avail. Removed messy scratchpad section. + Removed outdated example listing. Turned remaining scratch + annotation into appendix. Created minimal Makefile (cleanup). + + Revision 1.5 2000/08/08 02:56:05 bk + alcGetCurrentContext. Attempt to formulate Design Objectives as + a guideline. RFC's on INITIAL state, ACTIVE misnomer. RFC on + INVALID_POINTER. Lots of scratch stuff (fallout from buffer + queueing discussions). Annotations on various buffer queue + rejects and related issues. Added Scaling and Timing sections + and related calls. Added CONE_OUTER_GAIN. Added Doppler sections. + Rewrote and shuffle globale state, simple query, string query. + Moved Extensions sections in Appendix. Added annotation and + RFC's regarding distance/gain model. No more ILLGEAL - finally + checked the specs and Mesa 3.3 to be sure. Picked OPERATION at + the same time, also specs conformat (no comment...). Removed + JMJ as responsible author (all blame shall be mine). Fixed + Play(), INITIAL vs. STOPPED. Edited related RFC's, stripped + obsolete commentary. Rewrote State/State Transition section. + Fixes on SGML. CHANNELS and BITS moved in RFC's. Moved and + rewrote RFC on Duration/Remainder queries into Time section. + Stripped BYTE_LOKI of all but the essentials. Added placeholders + for Callback and AppendData in same (backwards compatibility) + section. Lots of Buffer Queueing. + + Revision 1.4 2000/07/25 17:19:17 bk + Changed ILLEGAL_OPERATION to ILLEGAL_COMMAND consistently. Added + excerpts from mailinglist to scratch section. Added Appendix on + Extension Process. Typos. RFC on EXTENSIONS changed to Annotation. + SGML validation and error fixes (not done on cvs1.3, sorry). + + Revision 1.3 2000/07/24 21:18:53 bk + Reordered manual revision history to be CVS compliant. Diff against + Rev. 1.4/bk000626 as it was not checked in CVS. Created scratch + section for removed RFC 's. Checked edits on Extension section and + removal of related RFC/bk000506. Converted removed RFC/bk000504 + on IsExtensionPresent in Annotation. Rewrote Mike's annotations + on source types and distance attentuation clamping as RFC's and + added some removed RFC sections back. Rewrote annotation added by + MikeV on compressed buffers, split of RFC on AL_SIZE query. + Re-added RFC's an buffer attribute defaults, edited annotation + on GetEnumValue return. RFC's on factory methods for streaming + buffers, memory budgeting, initial object state. Re-inserted and + extended RFC on format enum issue. Re-inserted the global + setter/getter in scratch section. Implementation requirement + section. Resurrected CONE_OUTSIDE_GAIN as RFC. BITS bitching, + annotation to explain why not enumerating frequencies. Got a grip + and recognized BITS and CHANNELS as query-only. More on frequency + in BufferData. Into CVS before current discussions are added. + + Revision 1.2 2000/07/19 15:16:58 briareos + Enable/Disable return void, not enum. + + Revision 1.1 2000/06/29 00:27:24 briareos + Initial draft of OpenAL specs. + + + 1.4/briareos : not in CVS + Finished editing related to my comments, with Joe's + feedback, in preparation for use by Creative and eventual + public dissemination later this week. + + 1.4/bk000626 : not in CVS + Started using id attribute on RFC note elements, to ensure unique + identifiers. Added Annote level. Added oal15-jm/overview.html + changes. Added oal15-jm/object-state.html (mostly). Removed + Filtering/Spatialization distinction and merged attribute table. + Moved Filter chapter to annotation. Moved Geometry to annotation, + rewrote annotation with my latest conclusions on A3D/EAGLE like + approach. Stripped out ALU and ALUT, added annotation on reasons. + Added some text to introduction chapter. Moved ALC chapter to end + of specification. Followed John Hall advice to enable section + numbers in print stylesheet. Rewrote section on GetError. Created + I3DL2 extension appendix. Reworked all tables for better + formatting with separated descriptions. Took out a bunch of + outdated RFC's. Rewrote Query and String Query section. Added + Scratch sections. Added ARB/Ack section. Didn't get RFC comments + from MikeV. Fixed permission to copy. + + 1.4/bk000508 : not in CVS. + Added RFC to Device section. Made nested RFC around entire + device section to make sure. Added trailing blanks to data type + entities as a cheap workaround to the HTML backend problem in + FuncSynopsis. Added RFC from BYTE_LOKI discussion on mailinglist. + + 1.4/bk000507 : not in CVS. + Added altypes.h info on scalar types, copied Linux OpenGL Base + ABI layout. Also added some missing enums. Checked alc.h header, + added UpdateContext and RFC's. Changed alc*Context signatures to + include ALCdevice handle. Checked al.h header, fixed outdated + BufferData/BufferAppendData signatures, added RFC's. Added comments + on differing return types. This pretty much concludes the inventory. + + 1.4/bk000506 : not in CVS. + The HTML in CVS was completely mangled between the 1.2 and 1.3 + revisions. Also, redundant al and AL_ prefixes were added, and + the document was restructured. I tried SaveAs ASCII and + whitespace insensitive compare, and finally did the compare + manually (no guarantees). The text sections that looked + relevant have been added in RFC's with the bk000506 tag. + Also added a revision history and CVS tags for future CVS based + revision control (post-E3). + + 1.4/bk000505 : not in CVS. + SGML version. Merges AL specification and API reference as + of GDC (v1.2) with each other. Adds ALC placeholder. + Addition of several RFCs based on recent discussions. + + 1.3/cvogelsa : only in CVS. + api-reference.html CVS v1.14 + specification.html CVS v1.3 + + 1.2/briareos : 8 March 2000, released at GDC. + api-reference.html CVS v1.13 + specification.html CVS v1.2 + + x.xx/nn : early specifications. + Neither the early working papers by Terry Sikes, Sean L. Palmer + and others nor the first versions of the &OAL; specification + as compiled at Loki were archived and versioned in a coherent way. \ No newline at end of file diff --git a/openal/docs/Makefile b/openal/docs/Makefile new file mode 100644 index 000000000..ce5932b95 --- /dev/null +++ b/openal/docs/Makefile @@ -0,0 +1,148 @@ +## ------------------------------------------------ +## Makefile for openal/docs/ + + +## DocBook stuff +DB2PS = db2ps +DB2PDF = db2pdf +DB2HTML = db2html + +## TexInfo stuff +MAKEINFO = makeinfo + + + +## Targets +OALSPEC = oalspecs +DB_OBJS = $(OALSPEC).ps $(OALSPEC)/index.html + +TEXI_OBJS = openal.info + +.SUFFIXES: .texi .info + +## Rules +%.ps : %.sgml + $(DB2PS) $< + +%/index.html : %.sgml + $(DB2HTML) $< + + +## Fixme - config.h +%.info : %.texi ../config.h + $(MAKEINFO) $< + + + +## ---------------- +## Standard targets +default: all + +all: render + +render: $(DB_OBJS) + +texi: $(TEXI_OBJS) + + +## -------------- +## Cronjob target +update: specs annotated full + + +## ---------------------------------------------------------- +## Specification - prototypes, tokens, explanation +## +specs-ps: + -rm -f $(OALSPEC)-specs.ps + cp ent-marks-specification.sgml ent-marks.sgml + $(DB2PS) $(OALSPEC).sgml + mv $(OALSPEC).ps $(OALSPEC)-specs.ps + zip -9 $(OALSPEC)-specs.ps.zip $(OALSPEC)-specs.ps + +specs-html: + -rm -rf $(OALSPEC)-specs/ + cp ent-marks-specification.sgml ent-marks.sgml + $(DB2HTML) $(OALSPEC).sgml + mv $(OALSPEC) $(OALSPEC)-specs + -rm $(OALSPEC)-specs.html.zip + zip -r9 $(OALSPEC)-specs.html.zip $(OALSPEC)-specs/ + +specs: specs-ps specs-html + + +## ----------------------------------------------------------- +## Annotated Version - including annotation seections +## (not Programmer's Guide, no examples) +annotated-ps: + -rm -f $(OALSPEC)-annote.ps + cp ent-marks-annotated.sgml ent-marks.sgml + $(DB2PS) $(OALSPEC).sgml + mv $(OALSPEC).ps $(OALSPEC)-annote.ps + zip -9 $(OALSPEC)-annote.ps.zip $(OALSPEC)-annote.ps + +annotated-html: + -rm -rf $(OALSPEC)-annote/ + cp ent-marks-annotated.sgml ent-marks.sgml + $(DB2HTML) $(OALSPEC).sgml + mv $(OALSPEC) $(OALSPEC)-annote + -rm $(OALSPEC)-annote.html.zip + zip -r9 $(OALSPEC)-annote.html.zip $(OALSPEC)-annote/ + +annotated: annotated-ps annotated-html + +## ---------------------------------------------------------- +## FULL Version - include's the RFC's and everything else +## +full-ps: + -rm -f $(OALSPEC)-full.ps + cp ent-marks-full.sgml ent-marks.sgml + $(DB2PS) $(OALSPEC).sgml + mv $(OALSPEC).ps $(OALSPEC)-full.ps + zip -9 $(OALSPEC)-full.ps.zip $(OALSPEC)-full.ps + +full-html: + -rm -rf $(OALSPEC)-full/ + cp ent-marks-full.sgml ent-marks.sgml + $(DB2HTML) $(OALSPEC).sgml + mv $(OALSPEC) $(OALSPEC)-full + -rm $(OALSPEC)-full.html.zip + zip -r9 $(OALSPEC)-full.html.zip $(OALSPEC)-full/ + +full: full-ps full-html + + +## ---------------------------------------------------------- +## ZIP - create archive +## + + + +clean: db_clean texi_clean + +db_clean: + -rm -f $(OALSPEC).dvi + -rm -f $(OALSPEC).aux + -rm -f $(OALSPEC).log + -rm -f $(OALSPEC).tex + -rm -rf $(OALSPEC).junk + -rm -f \#*\# + -rm -f *~ + +texi_clean: + @echo "Not done." + +install: + @echo "Not done." + +distclean: clean + -rm -rf \ + $(OALSPEC)-full/ \ + $(OALSPEC)-full.ps \ + $(OALSPEC)-annote/ \ + $(OALSPEC)-annote.ps \ + $(OALSPEC)-specs/ \ + $(OALSPEC)-specs.ps \ + *.zip + + diff --git a/openal/docs/alc-context.sgml b/openal/docs/alc-context.sgml new file mode 100644 index 000000000..3b0ae0f48 --- /dev/null +++ b/openal/docs/alc-context.sgml @@ -0,0 +1,846 @@ + + + + AL Contexts and the ALC API + + This section of the AL specification describes ALC, the AL Context API. + ALC is a portable API for managing &AL; contexts, including + resource sharing, locking, and unlocking. Within the core AL API the + existence of a Context is implied, but the Context is not exposed. The + Context encapsulates the state of a given intance of the AL state machine. + + + To avoid confusion with the AL related prefixes implied throughout + this document, the "alc" and "ALC_" prefixes have been made explicit + in the ALC related sections. + + + ALC defines the following objects: Contexts. + + + + Annotation (ALC entry points) + While the actual ALC implemention might be supplied + as a separate library, or as part of a server or + daemon, the specification requires that the AL library + provides the actual ALC entry points. + + ]]> + + Annotation (ALC OS independend) + ALC is meant to be OS-independent. OS specifics are + expected to be adressed by defining proper device + specifiers strings, and configuration attributes. + In this, ALC differs from GLX/WGL, which (due to the + tighter coupling with the window manager and + operating system) attempt to abstract OS specifics + to a much lesser degree. + + ]]> + + + RFC/ Issues + Hardware init/deinit, mapping many processes with + multiple contexts to many devices, sharing resources + among processes. + + ]]> + + + + Managing Devices + + ALC introduces the notion of a Device. A Device can be, + depending on the implementation, a hardware device, or + a daemon/OS service/actual server. This mechanism also + permits different drivers (and hardware) to coexist + within the same system, as well as allowing several + applications to share system resources for audio, including + a single hardware output device. The details are left + to the implementation, which has to map the available + backends to uniq7ue device specifiers (represented as + strings). + + + + Annotation (Network transparency) + &AL; is meant for interoperability with &OGL;. Some + implementations of &OGL; bindings (e.g. GLX) are network + transparent. The Device API theoretically allows for + a network transparent AL implementation. No wire protocol + is specified, no specification or implementation is planned. + + ]]> + + Annotation (Device Enumeration) + At this time, ALC does not provide mechanism to query + for available devices, and request device enumerations. + This might be added at a later time, depending on demand + and the ability to abstract OS and configuration specifics. + + ]]> + + Annotation (X11 Audio) + The ALC API intentionally mimicks XOpenDisplay + and XCloseDisplay. There is no X Audio standard, + although proposals have been made in the past. + The ALC API design accounts for this possibility + in a minimal way. + + ]]> + + + Connecting to a Device + + The alcOpenDevice function allows the application (i.e. the + client program) to connect to a device (i.e. the server). + + &device; * alcOpenDevice + const &ubyte;* deviceSpecifier + + If the function returns NULL, then no sound driver/device has + been found. The argument is a null terminated string that requests + a certain device or device configuration. If NULL is specified, + the implementation will provide an implementation specific default. + + Annotation (Operating system dependencies) + At this point, system specific configuration, and operating system + specific details, are handled by leaving the details of the + string specifier to the implementation. The application coder + has to determine how he wants to obtain this information from the + OS or the user. If, at a later point, device enumeration and + configuration requests are supported through ALC, the resulting + string might still be operating system and implementation specific. + + ]]> + + + + Disconnecting from a Device + + The alcCloseDevice function allows the application (i.e. the + client program) to disconnect from a device (i.e. the server). + + &void; alcCloseDevice + &device; * deviceHandle + + If deviceHandle is NULL or invalid, an ALC_INVALID_DEVICE error + will be generated. Once closed, a deviceHandle is invalid. + + + + + + + + + Managing Rendering Contexts + + All operations of the AL core API affect a current AL context. + Within the scope of AL, the ALC is implied - it is not visible as + a handle or function parameter. Only one AL Context per INprocess + can be current at a time. Applications maintaining multiple + AL Contexts, whether threaded or not, have to set the current + context accordingly. Applications can have multiple threads + that share one more or contexts. In other words, AL and ALC are + threadsafe. + + + The default AL Context interoperates with a hardware device driver. + The application manages hardware and driver resources by + communicating through the ALC API, and configures and uses + such Contexts by issuing AL API calls. A default AL Context + processes AL calls and sound data to generate sound output. + Such a Context is called a Rendering Context. There might + be non-rendering contexts in the future. + + + The word "rendering" was chosen intentionally to emphasize the + primary objective of the AL API - spatialized sound - and the + underlying concept of AL as a sound synthesis pipeline that + simulates sound propagation by specifying spatial arrangements + of listeners, filters, and sources. If used in describing an + application that uses both &OGL; and &AL;, "sound rendering + context" and "graphics rendering context" should be used for + clarity. Throughout this document, "rendering" is used + to describe spatialized audio synthesis (avoiding ambiguous + words like "processing", as well as proprietary and restrictive + terms like "wavetracing"). + + + + + Context Attributes + + The application can choose to specify certain attributes for + a context. Attributes not specified explicitely are set to + implementation dependend defaults. + + + + Context Attributes + + + + + + Name + Description + + + + + ALC_FREQUENCY + Frequency for mixing output buffer, in units of Hz. + + + ALC_REFRESH + Refresh intervalls, in units of Hz. + + + ALC_SYNC + Flag, indicating a synchronous context. + + + +
+
+ + Annotation (Refresh Control) + Applications might have a fixed, or bounded, schedule for + state changes (e.g. synchronously with the GL framerate). + In this case it is desirable to specify the mixahead + interval (milliseconds), or refresh rate (Hz), for the + mixing thread. This is especially important for a synchronous + context, where the application has to specify the refresh + interval it intends to keep. + + ]]> + + + RFC / Mixing Buffer Configuration + ALC_RESOLUTION was originally used to specify the accuracy of the + mixing output buffer. For the time being this is not supported, but + could be added if mixing path and result accuracy control is desirable + to scale resource requirements. + A full ALC_FORMAT (including channel and other attributes) does not + make sense for rendering contexts, but will be necessary for PBuffers + (mix to memory). + + ]]> + + RFC / LOKI extensions + + + ALC_SOURCES_HINT_LOKI, /* # of sources to pre-allocate */ + ALC_BUFFERS_HINT_LOKI, /* # of buffers to pre-allocate */ + + ALC_CD_LOKI, /* demand CD/DVD control */ + + + + ]]> +
+ + + + Creating a Context + + A context is created using alcCreateContext. The device parameter + has to be a valid device. The attribute list can be NULL, + or a zero terminated list of integer pairs composed of valid + ALC attribute tokens and requested values. + + &context; * alcCreateContext + const &device; * deviceHandle + ∫ * attrList + + Context creation will fail + if the application requests attributes that, by themselves, + can not be provided. Context creation will fail if the + combination of specified attributes can not be provided. + Context creation will fail if a specified attribute, or + the combination of attributes, does not match the default + values for unspecified attributes. + + + + + Selecting a Context for Operation + + To make a Context current with respect to AL Operation (state + changes by issueing commands), alcMakeContextCurrent is used. + The context parameter can be NULL or a valid context pointer. + The operation will apply to the device that the context was + created for. + + &bool; alcMakeContextCurrent + &context; * context + + For each OS process (usually this means for each application), only + one context can be current at any given time. All AL commands apply + to the current context. Commands that affect objects shared among + contexts (e.g. buffers) have side effects on other contexts. + + Annotation (No Explicit Device) + An ALC context is bound to the device it was created for. + The context carries this information, thus removing the + need to specify the device explicitely. Contexts can not + be made current for any other device aside from the one + they were created for. + + ]]> + + Annotation (No Multiple Current) + There is only one current context per process, even + in multithreaded applications, even if multiple + devices are used. + + ]]> + + + Annotation (Current NULL) + The implementation is encouraged to exploit optimizations + possible if the application sets the current context + to NULL, indicating that no state changes are intended + for the time being. The application should not set the + current context to NULL if more state changes are + pending on the most recent, or another context created + for the same device. + + ]]> + + Annotation (Shared Objects) + Buffers are shared among contexts. As mutiple contexts + can exist at the same time, the state of shared objects + is also shared among contexts. + + ]]> + + RFC / Buffer Deletion + Buffers that have not yet been processed in another context + can not be deleted from any other context. + + ]]> + + + + Initiate Context Processing + + The current context is the only context accessible to state + changes by AL commands (aside from state changes affecting + shared objects). However, multiple contexts can be processed + at the same time. To indicate that a context should be + processed (i.e. that internal execution state like offset + increments are supposed to be performed), the application + has to use alcProcessContext. + + &void; alcProcessContext + &context; * context + + Repeated calls to alcProcessContext are legal, and do not + affect a context that is already marked as processing. The + default state of a context created by alcCreateContext is + that it is not marked as processing. + + + Annotation (Sync and async implementations) + Unfortunately, the exact semantics of alcProcessContext is + not independend of the implementation. Ideally it should be completely + transparent to the application whether the sound driver is threaded or + synced. Unfortunately a synced context has to have its execution + initiated by the application, which requires calls of + alcProcessContext timed in accordance to the drivers mixahead, + or the rendering buffer will underflow. For a threaded driver, + the implementation is free to consider alcProcessContext + a NOP once the context has been marked as processing. + + One consequence is that an application that was developed + using a threaded implementation of AL might not work + properly with a synchronous implementation of AL (on + the other hand, an AL application that works using a + synchronous implementation is guaranteed to work with + a threaded implementation. + + Enforcing alcProcessContext calls would defeat the purpose + of a threaded implementation. Permitting the AL implementation + to e.g. schedule optimizations based on alcProcessContext + calls would similarly obfuscate the exact semantincs. + Consequently, the application coder has to accept this + implementation dependency, and has to rely on the ALC_SYNC + attribute to explicitely request a synchronous implementation. + The implementation can expect the application to be aware + of the additonal constraints imposed on alcProcessContext in + this case. + + ]]> + + Annotation (Multiple Contexts and SYNC refresh) + The application can request SYNC contexts or threaded contexts, + however, the implementation is not obliged to provide both, or provide + a mixture of both on the same device. + + ]]> + + + RFC/ Implications for Networking + What does alcProcessContext imply for networking? + For AL, will we add alFlush/alFinish? + + ]]> + + + + Suspend Context Processing + + The application can suspend any context from processing + (including the current one). To indicate that a context should be + suspended from processing (i.e. that internal execution state like + offset increments is not supposed to be changed), the application + has to use alcSuspendContext. + + &void; alcSuspendContext + &context; * context + + Repeated calls to alcSuspendContext are legal, and do not + affect a context that is already marked as suspended. The + default state of a context created by alcCreateContext is + that it is marked as suspended. + + + Annotation (Sync and async implementations) + Unfortunately, the exact semantics of alcSuspendContext is + also not independend of the implementation. For a threaded + implementation, alcSuspendContext is necessary to ensure a context + is not processed. For a synchronous implementation, omitting + alcProcessContext calls will ultimately have the same effect, + but will also generate rendering buffer underflow errors. + Again, the application coder that requests a synchronous + context using ALC_SYNC has to make sure that alcSuspendContext + is used accordingly. + + ]]> + + Annotation (Suspending vs. Muting a context) + By setting Listener GAIN to zero, an application can mute a + context, and expect the implementation to bypass all rendering. + However, the context is still processing, and the internal + execution state is still updated accordingly. Suspending a + context, whether muted or not, will incidentally suspend rendering + as well. However, it is the application's responsibility to + prevent artifacts (e.g. by proper GAIN control to fade in and + out). It is recommended to mute a context before suspending. + + ]]> + + Annotation (Current Context Suspended) + It is possible to make a suspended context current, or + suspend the current context. In this case, the implementation + is still obliged to immediately verify AL commands as they + are issued, and generate errors accordingly. The implementation + is permitted to postpone propagating the actual state changes + until the context is marked for processing again, with the + exception of dereferencing data (e.g. buffer contents). + For efficiency reasons (memory usage), most if not all + AL commands applied to a suspended context will usually + be applied immediately. State changes will have to be applied + in the sequence they were requested. It is possible to + use suspension of a current context as an explicit locking + (to enforce apparent synchronicity), but execution is still + guaranteed to be in sequence, and the implementation is not + expected to optimize this operation. A typical use would + be setting up the initial configuration while loading a + scene. + + ]]> + + Annotation (Release of Hardware Resources) + The specification does not guarantee that the implementation + will release hardware resources used by a suspended context. + This might well depend on the details of the hardware and driver. + Neither a muted context nor a suspended context can be expected + to free device resources. If all contexts for a given device + are suspended, and no context of this device is current, the + implementation is expected to release all hardware resources if possible. + + ]]> + + + + + + + Destroying a Context + + + &void; alcDestroyContext + &context; * context + + The correct way to destroy a context is to first release it using + alcMakeCurrent and NULL. Applications should not attempt to destroy + a current context. + + +
+ + + + + ALC Queries + + + Query for Current Context + + The application can query for, and obtain an handle to, the current + context for the application. If there is no current context, NULL is + returned. + + &context; * alcGetCurrentContext + + + + + + + Query for a Context's Device + + The application can query for, and obtain an handle to, the device + of a given context. + + &device; * alcGetContextsDevice + &context; * context + + + + + + + Query For Extensions + + To verify that a given extension is available for the current + context and the device it is associated with, use + + + &bool;IsExtensionPresent + const &device; * deviceHandle + const &ubyte; * extName + + + A NULL name argument returns FALSE, as do invalid and unsupported string + tokens. A NULL deviceHandle will result in an INVALID_DEVICE error. + Annotation (Exlicit Device Parameter) + Certain ALC Extensions might be relevant to context creation + (like additional attributes, or support for unusual multi-context + combinations), thus the application might have to query these + before a context is created. On the other hand, ALC Extensions + are specific to the device. + + ]]> + + + + + Query for Function Entry Addresses + + The application is expected to verify the applicability of + an extension or core function entry point before requesting + it by name, by use of alcIsExtensionPresent. + + &void; * alcGetProcAddress + const &device; * deviceHandle + const &ubyte; * funcName + + Entry points can be device specific, but are not context specific. + Using a NULL device handle does not guarantee that the entry + point is returned, even if available for one of the available + devices. Specifying a NULL name parameter will cause an + ALC_INVALID_VALUE error. + + + + + Retrieving Enumeration Values + + Enumeration/token values are device independend, but tokens + defined for extensions might not be present for a given device. + Using a NULL handle is legal, but only the tokens defined by + the AL core are guaranteed. Availability of extension tokens + dependends on the ALC extension. + + &uint; alcGetEnumValue + const &device; * deviceHandle + const &ubyte; enumName + + Specifying a NULL name parameter will cause an + ALC_INVALID_VALUE error. + + + + + Query for Error Conditions + + ALC uses the same conventions and mechanisms as AL for error + handling. In particular, ALC does not use conventions + derived from X11 (GLX) or Windows (WGL). + The alcGetError function can be used to query ALC errors. + + &enum;alcGetError + &device; * deviceHandle + + Error conditions are specific to the device. + + + + + Error Conditions + + + + + + Name + Description + + + + + ALC_NO_ERROR + The device handle or specifier does name an accessible driver/server. + + + ALC_INVALID_DEVICE + The Context argument does not name a valid context. + + + ALC_INVALID_CONTEXT + The Context argument does not name a valid context. + + + ALC_INVALID_ENUM + A token used is not valid, or not applicable. + + + ALC_INVALID_VALUE + An value (e.g. attribute) is not valid, or not applicable. + + + +
+
+ + + Annotation (No UNDERFLOW error) + Applications using synchronous (and, depending on CPU + load, even an asynchronous implementation itself) might + fail to prevent underflow of the rendering output + buffer. No ALC error is generated in these cases, + as it this error condition can not be applied to a + specific command. + + ]]> +
+ + + String Query + + The application can obtain certain strings from ALC. + + const &ubyte; * alcGetString + &device; * deviceHandle + &enum; token + + For some tokens, NULL is is a legal value for the deviceHandle. + In other cases, specifying a NULL device will generate an + ALC_INVALID_DEVICE error. + + + + String Query Tokens + + + + + + Name + Description + + + + + ALC_DEFAULT_DEVICE_SPECIFIER + The specifier string for the default device (NULL handle is legal). + + + ALC_DEVICE_SPECIFIER + The specifier string for the device (NULL handle is not legal). + + + ALC_EXTENSIONS + The extensions string for diagnostics and printing. + + + +
+
+ + + In addition, printable error message strings are provided for + all valid error tokens, including ALC_NO_ERROR, ALC_INVALID_DEVICE, + ALC_INVALID_CONTEXT, ALC_INVALID_ENUM, ALC_INVALID_VALUE. + +
+ + + Integer Query + + The application can query ALC for information using an integer + query function. + + &void; alcGetIntegerv + &device; * deviceHandle + &enum; token + &sizei; size + dest + + For some tokens, NULL is a legal deviceHandle. In other + cases, specifying a NULL device will generate an ALC_INVALID_DEVICE + error. The application + has to specify the size of the destination buffer provided. + A NULL destination or a zero size parameter will cause ALC to ignore + the query. + + + + + Integer Query Tokens + + + + + + Name + Description + + + + + ALC_MAJOR_VERSION + Major version query. + + + ALC_MINOR_VERSION + Minor version query. + + + ALC_ATTRIBUTES_SIZE + The size required for the zero-terminated attributes + list, for the current context. NULL is an invalid + device. NULL (no current context for the + specified device) is legal. + + + ALC_ALL_ATTRIBUTES + Expects a destination of ALC_CURRENT_ATTRIBUTES_SIZE, + and provides the attribute list for the current + context of the specified device. NULL is an invalid + device. NULL (no current context for the + specified device) will return the default attributes + defined by the specified device. + + + +
+
+ + Annotation (Backward Compatibility) + Backward compatibility is guaranteed only for minor revisions. + Breaking ABI backwards compatibility will require a issuing + major revision. + + ]]> + + RFC / Version Matching + The ALC version can be different from the AL version. + The ALC major version has to be identical between + application and driver (client and server). + The ALC minor version can differ between client and server, + and the minimum of the two minor version numbers is returned. + + ]]> + + RFC / Device Enumeration + ALC_NUM_DEVICE_SPECIFIERS could be provided as an extension, + but it requires the number of device configurations to be + finite and small, as they are to be represented by strings. + + ]]> + +
+
+ + + + + Shared Objects + + For efficiency reasons, certain AL objects are shared across + ALC contexts. At this time, AL buffers are the only shared + objects. + + + RFC/ Sharing Sources? + Mike Kelly from Dynamix describes an application scenario with + multiple camera views of the same scene (implemented using + several viewports on a single, "split screen", context) + in which he needs multiple listeners (one per view) to + preceive the same sources, with the rendering results of + each listener to mixed for a single output device. As an + alternative to permitting multiple listeners within a context, + it might be preferable to introduce a mechanism to explicitely + share certain AL objects among contexts, at a later time. + It is not desirable to share Sources by default, especially + as the more common multi-listener application is expected to + maintain listeners with disjunct sets of sources. + + ]]> + + Shared Buffers + + Buffers are shared among contexts. The processing state of a buffer + is determined by the dependencies imposed by all contexts, not just + the current context. This includes suspended contexts as well as + contexts that are processing. + + + + + +
diff --git a/openal/docs/api-reference.html b/openal/docs/api-reference.html new file mode 100644 index 000000000..37607702c --- /dev/null +++ b/openal/docs/api-reference.html @@ -0,0 +1,15 @@ + + + + +OpenAL API Reference + + + +

OpenAL API Reference

+

+ This document has been removed. +

+ + + diff --git a/openal/docs/app-annotations.sgml b/openal/docs/app-annotations.sgml new file mode 100644 index 000000000..6eabf4b5e --- /dev/null +++ b/openal/docs/app-annotations.sgml @@ -0,0 +1,297 @@ + + + Miscellaneous Annotations + +
+ Reverberation Objects? + + In a generalization of the I3DL2 Extension for + listener specific reverberation effects, it might + be best to implement Reverb Objects. A Reverb Object + is one example of a parametrized filter. Each + such object encapsulates a set of attributes (the + filter parameters). Sources and Listener alike + have an attribute that allows the application coder + to choose a reverb object for application either + at the origin of the sound, or at the position of + the listener. Initial implementation would only + support one Reverb Object per Context, applied at + the listener position. + + + The I3DL2 Environment is a filter that alters the + way the user experiences the virtual world. As + filters require DSP operations it is limited by hardware + processing capabilities. + + + The I3DL2 Environment models the surroundings of the + listener by simplifying the presumed acoustic properties + of those surroundings into a small set of parameters. + It allows to reproduce the effects of sound reflections + and reverberation caused by walls and obstacles, and + the muffling effects of obstacles inside environments + or partitions between environments. + + + Environment properties: + Early reflections level and delay. + Late reverberation level and delay, low- and high-frequency decay time. + Reverberation diffusion, density and spectrum. + + + Source properties: + Direct path intensity and spectrum. + Reverberation intensity and spectrum. + +
+ +
+ On Filters + + RFC/bk000502: Filters as the general concept of modifiers? + Environment as a special case filter? + Can we break down EAX environments into ReverbFilters where we + parametrize late reflections, and ReflectFilters, which fake + early reflections? Do we need this separation if we have + calculated or distinct echo effect reflections instead of + stocastic ones? Does it make sense to superimpose a general + reverb kicking in after a delay t, with reflections (random + or not) or should reverb only kick in after reflections are + discarded? + + + RFC/bk000502: old text. + (Environment) Properties: + Geometry - geometry is specified using an immediate mode API which is + similar to OpenGL. Support for scene lists are also provided on a basis + similar to OpenGL's display lists. + Materials - specify the absorptive and reflective qualities of a piece + of geometry. &AL; should provide a facility for accessing preset + materials, and storing and retrieving new materials at runtime. + + + RFC/nn: Atmospheric/ambient properties? + REF/nn: A3D 2.0 IA3dMaterial + + +
+ Atmospheric Filter + + The atmospheric filter the effects of media with constant density, + on propagating sound waves. The effect of the atmospheric filter + is distance dependent. Atmospheric effects can be parameterized + by specifying attenuation per unit distance, the scale for the + unit distance, for one of a minimum of two frequency ranges + (low frequency and high frequency roll-off). + + + RFC/bk000502: do we specify the atmospheric filter per-source? + The effect is clearly dominated by the most dense medium, but + we have little chance simulating crossings between different + media this way. Distance attenuation in media clearly depends + on source and listener being embedded in the same medium, + without any obstruction along the LOS. + +
+ +
+ Listener Reverb + + Listener Reverb is a parameterized filter that modifies the sound at + listener position to emulate effects of the surroundings, namely + effects of late reflections. Without simulating sound propagation + this reverb accounts for the averaged outcome of different arrangements + of reflecting/absorbing surfaces around the listener. + +
+ +
+ Source Reverb + + There is currently no support for reverb at the source position. + +
+ +
+ Reflection Filter + + First order reflection (and, if support, O(n) reflection for small n) + can choose to simulate the effects of different materials by + parametrizing reflection filters. + There is currently no support for reflections. + +
+ +
+ Transmission Filter + + Sound propagation along the LOS can pass through obstructions + specified as convex polygons. The effects of lossy transmission + can be approximated by applying a once-off filtering. Like + atmospheric filters, this can be a frequency-dependent roll-off, + unlike atmospheric filters this does not take distance into + account. Transmission filters can be used to emulate losses + on crossing separating surfaces between different media (water/air + borders). + There is currently no support for transmissions. + +
+
+ +
+ Parameterization over Time + + Fading and cross-fading. There are three ways to handle any kind + of gain control as a function of time: + + + + manipulate gain per frame/sufficiently often + + + + + parameterize, i.e. specify a target gain, + a duration over which to interpolate, and an interpolation function + + + + + provide an buffer that indicates amplitude, stretched over + a duration/by a frequency + + + The last mechanism also works for early reflections and echos, + and any other temporal filtering. The first and second approach + also work for attributes like Pitch. + +
+ + +
+ On Geometry + + Both the A3D API and implementation as well as EAX related utilities + like EAGLE seem to indicate that any effort to handle scene geoemtry + at API level will inevitably duplicate modules found in common game + engines for purposes of collision detection, path planning, AI + support, visibility and sound propagation culling. + + + In other words, any such effort will inevitably lead to competing + subsystems and multiple use of processing and memory resources to + implement the same functionality. While it makes sense to provide + templates, examples, and even utilities like EAGLE and SDK's to + developers, it makes no sense to integrate any such functionality + with the API. + + + The geometry based processing inevitably leads to a scene graph + API, with all the resulting problems. On closer examination it + seems that the specification and storage of source and listener + positions is a red herring. + + + Second and higher order reflections seem to be irrelevant. + + + Reflection can be faked by stochastic means, but an actual + presence/immersion effect will require smooth transitions + depending on the continuous change of distance between + sources, listener, and dominant reflectors. + + + Dominant reflectors are presumed to be 1st order, + with material properties that incur little or no loss + (or even provide amplification), and significant + surface area. + + + Transmission loss through dense media is equivalent to + the distance attenuation model. + + + Refraction/reflection loss at border surfaces separating + media.... + + + No explicit geometry to check whether there is any indirect + (1st order reflection, multiple reflections) path between + source and listener - the application is usually better + equipped to handle this (portal states, PHS). The benefit + of forcing the AL implementation to check for obstruction + (object inersecting LOS) is questionable at best - LOS + checking is also better done by the main application. + In essence, the application might even handle the 1st + order reflections IFF we provide the means to generate + early reflection instead of rolling dice, and if we + make it cheap to enable a path between a source and + the listener complete with a material. Come to think of + it: the implementation guarantees n paths with m filters + one of which is transmission or reflection, one is + distance attenuation, one is source reverb, one is + listener reverb.... + +
+ +
+ No ALU + RFC + ALU, like GLU, is a problem: linkage dependencies, multiple drivers + sharing one ALU etc. It would be best to not clutter the specification + with ALU/ALUT. Any support code/template repository/SDK can be + maintained as a separate open source project. + + + ALU provides operations that do not affect driver or hardware state. + These can be resampling/conversion methods or other sample data + processing, or utilities for (optimized) filter generation. ALU + does not provide I/O operations. At this time, + ALU is not specified and not implemented. + + + RFC/bk000502: GLU is becoming a bit of a problem right now, with + most applications avoiding it as they load GL DLL's explicitely, + but do not trust the ABI specification enough to link against GLU, + and not bothering to load it. A vendor-neutral open source ALU + works for me, but we can not accept link time dependencies to AL. + ALU (like GLU) is meant for minimal convenience, in small + building blocks, it is not meant as an SDK. + + + RFC/bk000502: old text. + ALU is the AL Utility library, and provide functions for performing audio + conversion, preset material properties, and a compatability layer for + legacy stereo format audio. This includes support for panning and per + channel volume control. + + + RFC/nn: Er, what else does the world of 2D sound usually need? + +
+ + +
+ No ALUT + + Application coders frequently request additional support for sound + handling to the extent of sophisticated SDKs. It is expected that + SDK vendors will provide such products on top of AL. ALUT (in analogy + to GLUT) would constitute an "official" SDK if desired. At this time, + ALUT is not specified and not implemented, and not intended to be part + of &AL; proper. + + + ALUT is a utility toolkit for &AL;. It sits on top of ALC. + It provides convenience functions for accessing files, for playing sounds, + and an API for accessing CDROM functionality. + +
+ + + +
\ No newline at end of file diff --git a/openal/docs/app-constants.sgml b/openal/docs/app-constants.sgml new file mode 100644 index 000000000..8c852e207 --- /dev/null +++ b/openal/docs/app-constants.sgml @@ -0,0 +1,43 @@ + + + Global Constants + + + Misc. &AL; Global Constants + + + + + + Name + &OAL; datatype + Description + Literal value + + + + + ALenum + FALSE + boolean false + 0 + + + ALenum + TRUE + boolean true + 1 + + + +
+
+ + + RFC + NONE, ONE, ZERO needed? + + ]]> +
+ diff --git a/openal/docs/app-extensionprocess.sgml b/openal/docs/app-extensionprocess.sgml new file mode 100644 index 000000000..778c09122 --- /dev/null +++ b/openal/docs/app-extensionprocess.sgml @@ -0,0 +1,36 @@ + + + Extension Process + + There are two ways to suggest an Extension to AL or ALC. + The simplest way is to write an ASCII text that matches + the following template: + + + + RFC: rfc-iiyymmdd-nn + Name: (indicating the purpose/feature) + Maintainer: (name and spam-secured e-mail) + Date: (last revision) + Revision: (last revision) + + new enums + new functions + + description of operation + + + + Such an RFC can be submitted on the &AL; discussion + list (please use RFC in the Subject line), or send to the + maintainer of the &AL; specification. If you are shipping + an actual implementation as a patch or as part of the + &AL; CVS a formal writeup is recommend. In this case, + the Extension has to be described as part of the + specification, which is maintained in DocBook SGML + (available for UNIX, Linux and Win32). The SGML source of + the specification is available by CVS, and the Appendix + on Extensions can be used as a template. Contact the + maintainer for details. + + diff --git a/openal/docs/app-extensions.sgml b/openal/docs/app-extensions.sgml new file mode 100644 index 000000000..1f4b3b926 --- /dev/null +++ b/openal/docs/app-extensions.sgml @@ -0,0 +1,754 @@ + + + Extensions + + Extensions are a way to provide for future expansion of the &AL; API. + Typically, extensions are specified and proposed by a vendor, and + can be treated as vendor neutral if no intellectual property + restrictions apply. Extensions can also be specified as, or + promoted to be, ARB extensions, which is usually the final step + before adding a tried and true extension to the core API. ARB + extensions, once specified, have mandatory presence for + backwards compatibility. The handling of vendors-specific or + multi-vendor extensions is left to the implementation. The IA-SIG + I3DL2 Extension is an example of multi-vender extensions to + the current &AL; core API. + + + + Extension Query + + To use an extension, the application will have to obtain function addresses + and enumeration values. Before an extension can be used, the application will + have to verify + the presence of an extension using IsExtensionPresent(). The application + can then retrieve the address (function pointer) of an extension entry + point using GetProcAddress. Extensions and entry points can be + Context-specific, and the application can not count on an Extension being available + based on the mere return of an entry point. The application also + has to maintain pointers on a per-Context basis. + + + + &bool; IsExtensionPresent + const &ubyte; * extName + + + + Returns TRUE if the given extension is supported for the current + context, FALSE otherwise. + + + Annotation (IsExtensionPresent) + This function is inspired by the GLU addition, but placed in + the core API as we intend to avoid a separate ALU. This function + avoids potential string overflow and string parsing issues (strstr) + raised by GetString( EXTENSIONS ). + + ]]> + + + Annotation/ EXTENSIONS + GetString( EXTENSIONS ) is supported as well, as it allows for + easy archiving and priting of the list of supported extensions. + + ]]> + + + + Retrieving Function Entry Addresses + + + &void;* GetProcAddress + const &ubyte; * funcName + + Returns NULL if no entry point with the name funcName can be found. + Implementations are free to return NULL if an entry point is present, + but not applicable for the current context. However the specification + does not guarantee this behavior. + + + Applications can use GetProcAddress to obtain core API entry points, + not just extensions. This is the recommended way to dynamically load + and unload &AL; DLL's as sound drivers. + + + RFC/bk000504: + Original spec required all addresses are Context independent. + This matches the Linux &OGL; ABI specification, but imposes + additional implementation constraints. For now, the specification + does not guarantee this. + + ]]> + + + + + Retrieving Enumeration Values + + To obtain enumeration values for extensions, the application has + to use GetEnumValue of an extension token. Enumeration values are + defined within the &AL; namespace and allocated according to + specification of the core API and the extensions, thus they are + context-independent. + + &uint; GetEnumValue + const &ubyte; enumName + + Returns 0 if the enumeration can not be found. The presence of an + enum value does not guarantee the applicability of an extension + to the current context. A non-zero return indicates merely that + the implementation is aware of the existence of this extension. + Implementations should not attempt to return 0 to indicate that + the extensions is not supported for the current context. + + + Annotation/ enums with value zero + The literal value 0 is guaranteed for a number of AL + enums, such as FALSE, NONE, ZERO. As with GL applications + might employ sloppy use of this identity. It also means + that enums with zero value can not be queried through + GetEnumValue, a minor flaw given the constraints of + ABI backward compatibility. The recommended value to + compare GetEnumValue results with is NONE. + + ]]> + + + + Naming Conventions + + Extensions are required to use a postfix that separates the + extension namespace from the core API's namespace. + For example, an ARB-approved extension would use + "_ARB" with tokens (ALenum), and "ARB" with commands (function + names). A vendor specific extension uses a vendor-chosen + postfix, e.g. Loki Extensions use "_LOKI" and "LOKI", + respectively. + + + + + ARB Extensions + + There are no ARB Extensions defined yet, as the ARB has + yet to be installed. + + + + + + Other Extension + + For the time being this section + will list externally proposed extensions, namely + the extension based on the IASIG Level 2 guideline. + + + + + + + IA-SIG I3DL2 Extension + + + The IA-SIG I3DL2 guideline defines a set of parameters to control + the reverberation characteristics of the environment the listener + is located in, as well as filtering or muffling effects applied to + individual Sources (useful for simulating the effects of obstacles + and partitions). These features are supported by a vendor neutral + extension to &AL; (TBA). + The + IA-SIG 3D Level 2 rendering guideline + provides related information. + + + RFC: Global Attributes + Do we need global setters for these: + DIRECT_IASIG/DIRECT_HIGH_FREQUENCY_IASIG? + ROOM_IASIG/ROOM_HIGH_FREQUENCY_IASIG? + + ]]> + + + + Listener Environment Attributes + + + + + + ENV_ROOM Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_ROOM_EXT + f + [0.0, 1.0] + 1.0f + + + +
+ Description: ??? +
+ + + + + ENV_ROOM_HIGH_FREQUENCY Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_ROOM_HIGH_FREQUENCY_EXT + f + [0.0, 1.0] + 0.1f ??? + + + +
+ Description: ??? +
+ + + + + ENV_DECAY_TIME Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_DECAY_TIME_EXT + f + [0.1, 20.0] + 1.0f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + NV_DECAY_HIGH_FREQUENCY_RATIO Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_DECAY_HIGH_FREQUENCY_RATIO_EXT + f + [0.1, 2.0] + 0.5f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_REFLECTIONS Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_REFLECTIONS_EXT + f + [0.1, 3.0] + 1.0f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_REFLECTIONS_DELAY Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_REFLECTIONS_DELAY_EXT + f + [0.0, 0.3] + 0.02f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_REVERB Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_REVERB_EXT + f + [0.0, 10.0] + 1.0f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_REVERB_DELAY Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_REVERB_DELAY_EXT + f + [0.0, 0.1] + 0.04f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_DIFFUSION Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_DIFFUSION_EXT + f + [0.0, 100.0] + 100.0f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_DENSITY Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_DENSITY_EXT + f + [0.0, 100.0] + 100.0f + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+ + + + + ENV_HIGH_FREQUENCY_REFERENCE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ENV_HIGH_FREQUENCY_REFERENCE_EXT + f + [20.0, 20000.0] + 5000.0 + + + +
+ Description: ??? + What's up with the defaults? Not a normalized range + and a global Scale to set? +
+
+ + Source Environment Attributes + + TBA. + + + ]]> +
+ + ]]> + + + + + Compatibility Extensions + + The extensions described have at one point been in use for + experimental purposes, proof of concept, or short term needs. + They are preserved for backwards compatibility. Use is not + recommended, avialability not guaranteed. Most of these will + be officially dropped by the time API revision 2.0 is released. + + + + + Loki Buffer InternalFormat Extension + + &AL; currently does not provide a separate processing + chain for multichannel data. To handle stereo samples, + the following alternative entry point to BufferData + has been defined. + + &void; BufferWriteData + &uint; bufferName + &enum; format + &void;* data + &sizei; size + &uint; frequency + &enum; internalFormat + + Valid formats for internalFormat are FORMAT_MONO8, FORMAT_MONO16, + FORMAT_STEREO8, and FORMAT_STEREO16. + + + + + Loki BufferAppendData Extension + + Experimental implementation to append data to an existing + buffer. Obsoleted by Buffer Queueing. TBA. + + Annotation (GenStreamingBuffers): + It is possible that a consistent implementation of this + extension will require distinguishing streaming from + regular buffers at creation time, instead of making + this distinction implied by the use of BufferData vs. + BufferAppendData. + + ]]> + + RFC: alBufferAppendData + Specify data to be filled into a streaming buffer. + This takes the current position at the time of the + call, and returns the number of samples written. + ALsizei ALAPIENTRY alBufferAppendData( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALuint freq ); + + + + + ]]> + + RFC: GenStreamingBuffers + Currently there is a function call on the Linux side, + alGenStreamingBuffers(), which generates a Buffer intended + for streaming. The intent of this function was the provide + a clear creation point for streaming buffers, rather than + the previous behaviour of a Buffer "magically" becoming + streaming Buffer the first time BufferAppendData() was + called on it. However, it's hard to believe this anomaly + in the API can be any better. What about + DelStreamingBuffers()? IsStreamingBuffer()? + + The design problem here is that we handle qualitatively different + objects using the same API. Streaming and non-streaming buffers + are fundamentally different. If we create an API that makes it + easy to mistake one for the other, or worse, if we decide to + quietly convert one type of object into another in some cases, + we create a plethora of error cases for the implementation and + the app coder to catch. Separating the Factory methods for the + objects allows us to omit an specialization API that will + accidentally be called more than once, and saves us handling + different stages of "initialization state". AL should not have + any notion of "partially initialized" or "incomplete" objects: + misery and despair lie down that road. If necessary the entire + API should be duplicated (after all, nobody handles 1D, 2D, and + 3D textures using the same GL API hooks), but as the AL + implementation has the ability to distinguish streaming and + non-streamin buffers internally there might not be a need. + Unless a concrete alternative is proposed to resolve the "anomaly" + it will be the preferred method to avoid an API that is + leaner at the expense of being more error-prone. + + ]]> + + + + + + + Loki Decoding Callback Extension + + Experimental implementation to allow the application to + specify a decoding callback for compression formats + and codecs not supported by &AL;. This is supposed to + be used if full uncompression by the application is prohibited + by memory footprint, but streaming (by queueing) is not + desired as the compressed data can be kept in memory + in its entirety. + + + If mixing can be done from the compressed data directly, + several sources can use the sample without having to + be synchronized. For compression formats not supported + by AL, however, partial decompression has to be done by + the application. This extension allows for the implementation + to "pull" data, using apllication provided decompression + code. + + + The use of this callback by the &AL; + implementation makes sense only if late decompression + (incremerntal, on demand, as needed for mixing) is done, + as full early compression (ahead-of-time) inside the + implementation would exact a similar memory footprint. + + + TBA. + + + This extension forces execution of third party code + during (possibly threaded) driver operation, and + might also require state management with global + variables for decoder state, which raises issues + of thread safety and use for multiple buffers. This + extension should be obsolete as soon as &AL; + supports a reasonable set of state of the art + compression and encoding schemes. + + + + + + + + Loki Infinite Loop Extension + + To support infinite looping, a boolean LOOP was introduced. + With the introduction of buffer queueing and the request for + support for a limited number of repetitions, this mechanism + was redundant. This extension is not supported for + buffer queue operations, attempts to use it will cause + an ILLEGAL_OPERATION error. For backwards compatibility + it is supported as the equivalent to + + Source( sName, PLAY_COUNT, MAX_INTEGER ) + + For the query LOOP==TRUE, the comparison + PLAY_COUNT!=MAX_INTEGER has to be executed on + the queue, not the current value which is decremented + for a PLAYING Source. + + Source LOOP_LOKI Attribute + + + + + + + + + &Par; + &Sig; + &Val + &Def; + + + + + LOOP_LOKI + b + &TRUE; &FALSE; + &FALSE; + + + +
+ Description: + &TRUE; indicates that the Source will perform an inifinite + loop over the content of the current Buffer it refers to. +
+
+ + + + + Loki Byte Offset Extension + + The following has been obsoleted by explicit Source State query. + hack. + + + + + Buffer BYTE Offset attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + BYTE_LOKI + ui + n/a + n/a + + + +
+ Current byte for the buffer bound to the source interpreted + as an offset from the beginning of the buffer. +
+ +
+ + ]]> + + + + Loop Point Extension + + + In external file now. + + + + ]]> + +
+ diff --git a/openal/docs/architecture.html b/openal/docs/architecture.html new file mode 100644 index 000000000..78d985bbf --- /dev/null +++ b/openal/docs/architecture.html @@ -0,0 +1,16 @@ + + + + OpenAL Architecture + + + +

OpenAL Architecture

+

+ This document has been removed. + See Index + for the specification. +

+ + + diff --git a/openal/docs/chp-buffers.sgml b/openal/docs/chp-buffers.sgml new file mode 100644 index 000000000..5a7cdff8f --- /dev/null +++ b/openal/docs/chp-buffers.sgml @@ -0,0 +1,691 @@ + + + + Buffers + + A Buffer encapsulates &AL; state related to storing sample data. The + application can request and + release Buffer objects, and fill them with data. Data can be supplied + compressed and encoded as long as the format is supported. + Buffers can, internally, contain waveform data as uncompressed or + compressed samples. + + + Unlike Sources and Listener, Buffer Objects can be shared among AL contexts. + Buffers are referenced by Sources. + A single Buffer can be referred to by multiple Sources. This separation allows + drivers and hardware to optimize storage and processing where applicable. + + + The simplest supported format for buffer data is PCM. + + + + + Annotation/ Compressed Buffers + Compressed formats are in no way guaranteed by the implementation + to remain compressed. The driver might have to uncompres in memory + at once, if no hardware-assisted or incremental decoding is possible. + In many cases an implementation has to decompress the buffer, + converting the uncompressed data to a canonical internal format, + and resample it into the format native to the current context. + + ]]> + + RFC: Compressed Buffers + MikeV suggests: an application can query the amount of memory buffer + is consuming. He suggests using GetBufferi(AL_SIZE, ... ). This seems + a bad idea as (a) the application is not meant to micromanage + driver-internal memory, (b) the memory requirements known to the + application might differ from the actual, (c) there are OS + mechanisms to query free memory, (d) AL_SIZE is now ambiguous as + it announces app-side memory as allocated vs. driver side memory + as used by the driver. For clarity AL_INTERNAL_SIZE (analog to + internal format enums) might be a better choice. + + ]]> + + + Buffers can be non-streaming (default) or streaming. Non-streaming + buffers are used to store looping and non-looping (single-shot) sound + data. Streaming buffers have to be used to cache streaming + media that the application can not keep in memory for technical + reasons: e.g. data delivered in real time over network. Streaming buffers + can also be used to partially store sound samples that the application + coder consider too large to keep in memory at once. + + ]]> + + + + + + Buffer States + + At this time, Buffer states are defined for purposes of discussion. + The states described in this section are not exposed through the API + (can not be queried, or be set directly), and the state description + used in the implementation might differ from this. + + + A Buffer is considered to be in one of the following States, with respect + to all Sources: + + + + UNUSED: the Buffer is not included in any queue + for any Source. In particular, the + Buffer is neither pending nor current + for any Source. The Buffer name can be + deleted at this time. + + + + + + PROCESSED: the Buffer is listed in the queue of + at least one Source, but is neither pending + nor current for any Source. The Buffer can + be deleted as soon as it has been unqueued + for all Sources it is queued with. + + + + + PENDING: there is at least one Source for which the + Buffer has been queued, for which the Buffer + data has not yet been dereferenced. The Buffer + can only be unqueued for those Sources that + have dereferenced the data in the Buffer + in its entirety, and cannot be deleted or + changed. + + + + The Buffer state is dependent on the state of all Sources + that is has been queued for. + A single queue occurrence of a Buffer propagates the + Buffer state (over all Sources) from UNUSED to PROCESSED + or higher. Sources that are STOPPED or INITIAL still have + queue entries that cause Buffers to be PROCESSED. + + + A single queue entry + with a single Source for which the Buffer is not yet + PROCESSED propagates the buffer's queueing state to + PENDING. + + + Buffers that are PROCESSED for a given Source can be + unqueued from that Source's queue. Buffers that have + been unqueued from all Sources are UNUSED. + Buffers that are UNUSED can be deleted, or changed by + BufferData commands. + + + Annotation (No CURRENT State) + For buffer queueing, it is not relevant whether + the Buffer data is currently dereferenced by any + Source or not. It is therefore not necessary to + distinguish a CURRENT state (being referenced as + current buffer by a single PLAYING or PAUSED Source). + + ]]> + + Annotation (State Query and Shared Buffers) + A buffer that is unused by one Source might be used + by another. The Unqueue operation is determined by + the number of queue entries already processed by the + given Source. + However, the application has to check whether the + Buffer is still in use by other Sources. For now, + applications have to maintain their own lists of + buffer consumer (source) lists. If necessary, an + explicit call to determine current buffer state + with respect to all Sources might be added in + future revisions. + + ]]> + RFC: IsBufferProcessed? + Instead of exposing the internal state, a simple boolean query + whether a buffer can be deleted or refilled can be used. + + ]]> + + RFC: BufferData on QUEUED + The error on using BufferData in QUEUED buffers is introduced + because the implementation might not be able to guarantee when + the Buffer is dereferenced. Applications have to account for the + possibility that the Buffer is dereferenced at the latest possible + moment, e.g. when it becomes CURRENT. As it is easier to relax + this restricition at a later time (no effect on backwards + compatibility) than doing the reverse, we are conserative here. + + ]]> + + RFC: Buffer State Query + Buffer State could be queried using alBuffer(), but it can't be + set. Prohibiting deferred deletion of buffers would make such a + state query desirable. + + ]]> + + + + + Managing Buffer Names + + &AL; provides calls to obtain Buffer names, to request + deletion of a Buffer object associated with a valid Buffer name, + and to validate a Buffer name. Calls to control Buffer attributes + are also provided. + + + + Requesting Buffers Names + + The application requests a number of Buffers using GenBuffers. + + void GenBuffers + &sizei; n + &uint;* bufferNames + + + + RFC: Buffer Name 0 + NONE or 0 is a reserved buffer name. What properties does + this buffer have? Does it have content? If there is no content, + what is its duration? 0? 1 microsecond? Should we use this buffer + to schedule a limited duration "silence"? + + ]]> + + + + Releasing Buffer Names + + The application requests deletion of a number of Buffers + by calling DeleteBuffers. + + + Once deleted, Names are no longer valid for use with AL + function calls. Any such use will cause an INVALID_NAME + error. The implementation is free to defer actual + release of resources. + + &void; DeleteBuffers + &sizei; n + &uint;* bufferNames + + IsBuffer(bname) can be used to verify deletion of a buffer. + Deleting bufferName 0 is a legal NOP in both scalar and + vector forms of the command. The same is true for unused + buffer names, e.g. such as not allocated yet, or as + released already. + + + RFC: Force Deletion + If a buffer name is deleted, we could replace all occurences + in queues with bname 0. This is the GL behavior for deleting + the texture currently bound. + + ]]> + RFC: Relasing used Buffers + If a Buffer is USED or QUEUED, it cannot be deleted, and the operation + should fail. We have three possible responses: throw an error, deferr + deletion, or force deletion by replacing every use + of the buffer in question with bname zero. + Throwing an error requires that we lock, verify that all specified + buffers can be deleted, then perform deletion, then unlock. If there + is one buffer that can not be deleted we have to throw an error and + make the entire operation a NOP. + Deferred deletion has its own set of problems (see other RFC). + Forcing deletion makes the mistake obvious to the application + for current buffers (sound artifacts) but still doesn't expose + errors for queued buffers. It also requires complete consumer + book-keeping for each buffer. GL uses this approach for textures + at little expense because it only has one current texture. + + ]]> + + RFC: Deferred Buffer Release + Buffer deletion could be performed as a deferred operation. + In this case actual deletion would be deferred until a Buffer is + unused, i.e. not QUEUED or CURRENT anymore. The specification + would not guarantee that they are deleted as soon as possible. + + However, such a deferred execution would be muddying the borders + between immediate and deferred execution in general (as we + might want to add scheduling and deferred commands at a later time). + Introduced as the default it makes impossible for the application + to force deletion or errors. Errors caused by improper use of + &AL; will be triggered at some distance from the original mistaken + command. Debugging such conditions is usually expensive. This approach + also does not take into account sharing of buffers among contexts. + + It might be possible to introduce this behavior as a Hint() + in case that it is not desirable to explicitely introduce + deferred commands. + + ]]> + + RFC: sourceName 0 + Is there a useful application for this? Do we mark that this + is reserved? + + ]]> + + + + Validating a Buffer Name + + The application can verify whether a buffer Name is valid + using the IsBuffer query. + + &bool; IsBuffer + &uint; bufferName + + + + + + + + Manipulating Buffer Attributes + + + Buffer Attributes + + This section lists the attributes that can be set, or + queried, per Buffer. Note that some of these attributes + can not be set using the Buffer commands, but are set + using commands like BufferData. + + + Querying the attributes of a Buffer with a buffer name that + is not valid throws an INVALID_OPERATION. Passing in an + attribute name that is invalid throws an INVALID_VALUE error. + + + + + Buffer FREQUENCY Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + FREQUENCY + float + none + (0, any] + + + +
+ Description: Frequency, specified in samples per second, + i.e. units of Hertz [Hz]. + Query by GetBuffer. The frequency state of a buffer is set by + BufferData calls. +
+ + Annotation (No Frequency enumeration) + As the implementation has to support conversion from + one frequency to another to implement pitch, it is + feasible to offer support for arbitrary sample + frequencies, instead of restricting the application + to an enumeration of supported sample frequencies. + Another reason not to limit frequency to an enumerated + set is that future hardware might support variable + frequencies as well (it might be preferable to choose + the sampling frequency according to the PSD of the + signal then). + + However, it is desirable to avoid conversions due + to differences between the sample frequency used in + the original data, the frequency supported during the + mixing, and the frequency expected by the output device. + + ]]> + + + Annotation (Implied Frequency) + To account for the possibility of future AL implementations + supporting encoding formats for the application might + not want, or be able, to retrieve the actual frequency + from the encoded sample, the specification will be + amended to guarantee the following behavior: If a nonzero + frequency is specified, it will force a conversion from + the actual to the requested frequency. If the application + specifies a 0 frequency, AL will use the actual frequency. + If there is no frequency information implied by the format + or contained in the encoded data, specifying a 0 frequency + will yield INVALID_VALUE. It is recommended that applications + use NONE instead of the literal value. + + ]]> + + RFC: BITS not needed + This is not a setter. As a state query it doesn't provide useful + information about the internal canonical format (which could be + queried independent of the buffer). + + + + Buffer BITS Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + BITS + ui + 8,16 + 0 + + + +
+ Description: + Bits per sample. This is a query-only attribute. The + default value for an (empty) buffer is zero. +
+ ]]> + + + Annotation (No Format query) + As of this time there is no query for FORMAT, or format + related state information. Query of the channels or + bits of a given buffer make little sense if the query + the internal (canonical, not buffer specific) format. + Query of the original sample data format makes little + sense unless the implementation is obliged to preserve + the original data. + + ]]> + + RFC: CHANNELS needed? + No setter. Does this indicate the channels in the original data, + or those in the (canonical) format internally used? Redundant to + querying the buffer type. Should be enums as speaker configurations + might have to be destribed by two integers: 5.1. + + + + Buffer CHANNELS Attribute + + + + &Par; + &Sig; + &Val; + &Def; + + + + + CHANNELS + ui + RFC: enums or N/A? + 0 + + + +
+ Description: Channels that buffer stores. Query only + attribute. This is almost + always 1, as applications using spatialized sound always + downsample to mono. This depends on the purpose of the + buffer: buffers used for spatialization have to provide + single-channel data. The default value for an (empty) + buffer is zero. +
+ ]]> + + + + Buffer SIZE Attribute + + + + &Par; + &Sig; + &Val; + &Def; + + + + + SIZE + &sizei; + [0, MAX_UINT] + 0 + + + +
+ Description: Size in bytes of the buffer data. Query through + GetBuffer, can be set only using BufferData calls. + Setting a SIZE of 0 is a legal NOP. The number of bytes does + not necessarily equal the number of samples (e.g. for compressed data). +
+ + + RFC: buffer overflow/underflow + If a SIZE is specified for a buffer and an attempt is made to + write less or more data to the buffer, is this an error? Do we + have SubData updates? Is trying to write data to a zero size buffer + an error? Which error? + + ]]> + + RFC: query for samples/duration? + Do we need a query for samples (which does not equal memory size)? + Do we prefer a duration query? As integral, for precision? Which, + combined with frequency, has to guarantee accurate sample number? + + ]]> + + + RFC: memory budgeting + SIZE comment said: Useful for memory budgeting with compressed data. + Sounds bogus: the application can only announce how many bytes + of data it intends to provide, it might not be able to estimate + the uncompressed, decoded size in the internal format chosen by + the implementation w/o decompressing, decoding, and querying for + the internal format. Micromanaging memory is usually a bad idea. + Using SIZE to configure a buffer might ge a mistake. Using the + same enum to query the actual size internally (which might + consists of two or more buffer areas and cached decoding state) + will be confusing. + + ]]> + + RFC: buffer initial state + MikeV added: + "The default attribute values for a Buffer are nonsensical insofar + as a Buffer is incomplete without data having been + specified." + This seems wrong. An AL object will always be complete and valid, + albeit useless. A Buffer in its default state might not produce + any useful outout, but it can be specified and used. + + ]]> +
+ + + + Querying Buffer Attributes + + Buffer state is maintained inside the &AL; implementation and can be + queried in full. The valid values for paramName are identical to the + ones for Buffer*. + + void GetBuffer{n}{sifd}{v} + &uint; bufferName + &enum; paramName + &type;* values + + + + + + Specifying Buffer Content + + A special case of Buffer state is the actual sound sample data stored + in asociation with the Buffer. Applications can specify sample data using + BufferData. + + &void; BufferData + &uint; bufferName + &enum; format + &void;* data + &sizei; size + &sizei; frequency + + The data specified is copied to an internal software, or if possible, + hardware buffer. The implementation is free to apply decompression, + conversion, resampling, and filtering as needed. The internal format + of the Buffer is not exposed to the application, and not + accessible. Valid formats are FORMAT_MONO8, FORMAT_MONO16, + FORMAT_STEREO8, and FORMAT_STEREO16. An implementation may + expose other formats, see the chapter on Extensions for + information on determining if additional formats are supported. + + + + Applications should always check for an error condition after attempting + to specify buffer data in case an implementation has to generate an + OUT_OF_MEMORY or conversion related INVALID_VALUE error. The application + is free to reuse the memory specified by the data pointer once the + call to BufferData returns. The implementation has to dereference, + e.g. copy, the data during BufferData execution. + + + RFC: format enums + With the possible exception of sample frequency, all + details of a sample (mono/stero, bit resolution, channels, + encoding,compression) should be specified in a format parameter. + In other words, I opt for an enumeration of formats. GL has a + quite large number of those w/o suffering damage. Allowing + parameters the way we do increases error cases and/or + conversion load. The space is combinatorial to begin with, + but an enumeration of valid formats seems better to impose + restrictions. Using enums helps dealing with formats + opaque to the application (compressed data with compressed + header) where sample size and sampling frequency might not + be available. + + There is the related issue of internal formats. A buffer used + for spatialization will have to convert to mono. A buffer used + to pass through to the output hardware will have to + remap an n-channel format to an m-channel format (or let the + hardware do it) including crosstalk handling depending on + the output device (headphones vs. speaker). To prevent that + every buffer has to do both AL needs to know the purpose of a + buffer when dereferencing the data. + + ]]> + + RFC: Frequency woes + Frequency as a uint rises precision issues. + Frequency might not be known for compressed data, we might need + a (yuck) wildcard frequency specifier? + We have a redundancy: frequency per context (mixing quality + desired), frequency internally used by the implementation when + storing the buffers, frequency provided in the data. We need + to specify the latter in some cases and can't in others. Format + enum or frequency enum again. + + ]]> + + + + RFC: data mover mess + API to copy data from output buffer to a buffer? + BufferWriteData to supersede BufferData, BufferReadData + as later extensions for buffer readback for those who want it? + Reading the output stream reverses the problems we have + with appendData: the application provides a memory buffer + into which AL copies as much data as available/as fits. + + ]]> + + + + RFC: expose internal format + Implementations are free to use whatever internal data format is best + suited for their hardware/software implementation, leaving the actual + sample format and structure opaque to the application. Should applications + be able to influence this? Through context creation? Per Buffer? + Do we use Lowest Common Denominator or highest possible quality as a + default? + + ]]> + + RFC: memory management with compressed data + If we allow for mixing from compressed data (perfectly reasonable + for hardware) then it seems even more unlikely the application could + estimate memory usage. + If a compressed format is supported by AL, do we require support for mixing from + compressed data? I daresay not - some formats might not allow for + cheap incremental decompression. + + ]]> + + RFC: conversion and sample retrieval + To retrieve a sample, the size has to be queried first for allocating a + properly sized memory segment as destination. This is dependent on the + format. Conversion can be implemented as creating a buffer, and then + requesting the data in a different format. Is this desirable? Even if + we restrict reading from buffers to the same format they were written + to, conversion from the internal format might be inevitable. Querying + and setting the internal format however might be desirable for certain + purposes. + + ]]> + + +
+
+ diff --git a/openal/docs/chp-introduction.sgml b/openal/docs/chp-introduction.sgml new file mode 100644 index 000000000..c94855303 --- /dev/null +++ b/openal/docs/chp-introduction.sgml @@ -0,0 +1,304 @@ + + + Introduction + + + CVS Document: $Id: chp-introduction.sgml,v 1.3 2000/11/10 21:23:52 bk Exp $ + CVS Revision: $Revision: 1.3 $ + + $Log: chp-introduction.sgml,v $ + Revision 1.3 2000/11/10 21:23:52 bk + Use ../CREDITS for list of contributors. + + Revision 1.2 2000/10/26 02:58:55 bk + Cleanup (typos). + + Revision 1.1 2000/10/11 18:44:46 bk + Document split into separate files. Minor fixes. + + ]]> + +
+ Formatting and Conventions + + This API Specification and Reference uses a style that is a blend of the + OpenGL v1.2 specification and the OpenGL Programming Guide, 2nd ed. + Conventions: 'T' is used to designate a type for those functions which + exist in multiple signatures for different types. 'Object' is used + to designate a target Object for those functions which exist in multiple + versions for different Object categories. The 'al' and 'AL_' prefix + is omitted throughout the document. + + + Annotation (Terminology) + "State" refers to state within the context of the &OAL; + state machine description of the &OAL; implementation. + "Objects" refer to &OAL; primitives. + "Attribute" refers to attributes of &OAL; Objects. + Attributes of a &OAL; Objects are one part of the + &OAL; state. Some attributes are not specific to + single objects, but apply to the entire context. + "Parameter" is used for function arguments that might + or might not be attributes, in particular for + command arguments that are not stored as state. + The use of "Property" is to be avoided. + + ]]> + + + + + + 1.8/1.7./1.6/1.5 + September-August 2000 + bk + Final Draft for Public Review + + + + 1.4 + June 2000 + bk + First Draft for Public Review + + + + 1.2 + March 2000 + mkv + Draft released for GDC + + + + TODO + + - work thru past changes + - add GH section + - add rewrite of GH section + + - add section on rfc/ann id's + - add section on procedure + - add proper id's to rfc/ann/sections etc. + + + + ]]> + +
+ +
+ What is the &OAL; Audio System? + + &OAL; (for "Open Audio Library") is a software interface to audio hardware. + The interface consists of a number of functions that allow a programmer + to specify the objects and operations in producing high-quality audio + output, specifically multichannel output of 3D arrangements of sound + sources around a listener. + + + The &OAL; API is designed to be cross-platform and easy to use. + It resembles the &OGL; API in coding style and conventions. &OAL; uses a + syntax resembling that of &OGL; where applicable. + + + &OAL; is foremost a means to generate audio in a simulated three-dimensional + space. Consequently, legacy audio concepts such as panning and left/right + channels are not directly supported. &OAL; does include extensions compatible + with the IA-SIG 3D Level 1 and Level 2 rendering guidelines to handle + sound-source directivity and distance-related attenuation and Doppler effects, + as well as environmental effects such as reflection, obstruction, transmission, + reverberation. + + + + Like &OGL;, the &OAL; core API has no notion of an explicit rendering context, + and operates on an implied current &OAL; Context. Unlike the &OGL; + specification the &OAL; specification includes both the core API (the + actual &OAL; API) and the operating system bindings + of the ALC API (the "Audio Library Context"). Unlike &OGL;'s GLX, WGL + and other OS-specific bindings, the ALC API is portable across platforms + as well. + +
+ +
+ Programmer's View of &OAL; + + To the programmer, &OAL; is a set of commands that allow the + specification of sound sources and a listener in three + dimensions, combined with commands that control how these + sound sources are rendered into the output buffer. The + effect of &OAL; commands is not guaranteed to be immediate, + as there are latencies depending on the implementation, + but ideally such latency should not be noticeable to the + user. + + + A typical program that uses &OAL; begins with calls to + open a sound device which is used to process output and + play it on attached hardware (e.g. speakers or headphones). + Then, calls are made to allocate an AL context and + associate it with the device. Once an AL context is + allocated, the programmer is free to issue AL commands. + Some calls are used to render Sources (point and directional + Sources, looping or not), while others affect the rendering + of these Sources including how they are attenuated by + distance and relative orientation. + + + Annotation (&OAL; and &OGL; use) + Often, &OAL; will be used to render a 3D audio environment + matched by a 3D visual scenery. For this purpose, &OAL; is + meant to be a seamlessly integrating complement to &OGL;. + &OAL; state can be updated in sync with the &OGL; or video + updates (synchronized), or in timesteps independent of the + graphics framerate. Audio rendering loops usually update + the current locations of the sources and the listener, updates + global settings, and manages buffers. + + ]]> +
+ + +
+ Implementor's View of &OAL; + + To the implementor, &OAL; is a set of commands that affect + the operation of CPU and sound hardware. If the hardware + consists only of an addressable output buffer, then &OAL; must + be implemented almost entirely on the host CPU. In some cases + audio hardware provides DSP-based and other acceleration in + various degress. The &OAL; implementors task is to provide + the CPU software interface while dividing the work for each + AL command between the CPU and the audio hardware. This + division should be tailored to the available audio hardware + to obtain optimum performance in carrying out AL calls. + + + &OAL; maintains a considerable amount of state information. + This state controls how the Sources are rendered into the + output buffer. Some of this state is directly available to + the user: he or she can make calls to obtain its value. + Some of it, however, is visible only by the effect it has + on what is rendered. One of the main goals of this + specification is to make &OAL; state information explicit, + to eludicate how it changes, and to indicate what its + effects are. + + + Annotation (Native audio APIs) + Implementors can choose to implement &OAL; on top + of an existing native audio API. + + ]]> + +
+ + +
+ Our View + + We view &OAL; as a state machine that controls a multichannel + processing system to synthesize a digital stream, passing sample + data through a chain of parametrized digital audio signal + processing operations. This model should engender a specification + that satisfies the needs of both programmers and implementors. + It does not, however, necessarily + provide a model for implementation. Any conformant implementation + must produce results conforming to those produced by the specified + methods, but there may be ways to carry out a particular computation + that are more efficient than the one specified. + + +
+ + +
+ Requirements, Conformance and Extensions + + The specification has to guarantee a minimum number of resources. + However, implementations are encouraged to compete on performance, + available resources, and output quality. + + + RFC: suggested requirements + These have been taken from earlier specs drafts, suggested by + Creative: + A minimum of sixteen (16) Sources per Context should always be available. + The number and size of Buffers available is limited only by the amount + of memory available and/or accessible by the implementation. + The specification could also list requirements by the implementation: + A minimum storage space of half a megabyte (512kB) should always be available. + + ]]> + + RFC: no requirements + I3DL1-like requirements might be so arbitrary that they are useless. + The dangers here are cap bits, and a subtle aliasing of source and + hardware buffers. AL implementations should implement as much quality + and performance as possible for any given number of sources/ + Application request resources when creating a context and can use Hints + to indicate desired trade-offs. + + ]]> + + + + There will be an &OAL; set of conformance tests available along + with the open source sample implementation. Vendors and individuals + are encouraged to specify and implement extensions to &OAL; in + the same way &OGL; is extensible. Successful extensions will + become part of the core specification as necessary and desirable. + &OAL; implementations have to guarantee backwards compatibility + and ABI compatibility for minor revisions. + + + The current sample implementation and documentation for &OAL; can be + obtained from + openal.org. + &OAL; is also available from the the + + &OAL; CVS repository. For more information on how to get + &OAL; from CVS also see + &coLoki; CVS. + +
+ + + +
+ Architecture Review and Acknowledgements + + Like &OGL;, &OAL; is meant to evolve through a joined effort of + implementators and application programmers meeting in regular + sessions of an Architecture Review Board (ARB). As of this time + the ARB has not yet been set up. Currently, the two companies + committed to implementing &OAL; drivers have appointed two + contacts responsible for preparing the specification draft. + + + Consequently &OAL; is a cooperative effort, one in a sequence of + earlier attempts to create a cross-platform audio API. The current + authors/editors have assembled this draft of the specification, + but many have, directly and indirectly, contributed to the content + of the actual document. The following list (in all likelihood + incomplete) gives in alphabetical order participants in the discussion + and contributors to the specification processs and related efforts: + + &CREDITS; + + + +
+
+ + \ No newline at end of file diff --git a/openal/docs/chp-multichannel.sgml b/openal/docs/chp-multichannel.sgml new file mode 100644 index 000000000..425ec067a --- /dev/null +++ b/openal/docs/chp-multichannel.sgml @@ -0,0 +1,261 @@ + + + Handling Multichannel Data + + &AL; is foremost an API to control processing of spatialized sound. For that + reason, the internal, canonical format of data stored in buffers is mono. + The specification does not require the implementation to preserve the + original data, thus multichannel (e.g. stereo) data is usually downsampled + using an algorithm of the implementor's choosing. Implementations are free + to defer decompression, decoding, and conversion until the latest possible + moment, but they are not required to do so by the specification. + + + However, &AL; is an audio API, and consequently has to provide means to + pass through preprocessed multichannel data to the sound driver and + hardware, which in turn will map it to the actual output channels. This + processing might involve mapping from n channels in the data to m channels + in the output, as well as filtering to account for varying requirements + for a given setup. For example, headphone and speaker setups differ with + respect to handling of crosstalk and noise. + + + For this reason, mono buffers can not be used to store data meant for + direct multichannel output. The API has to provide means by which the + application can signal its intention to use a given buffer in this way, + causing the implementation to either preserve the original data, or + convert it as needed for the direct output to the given speaker or + headphone configuration. In many cases, multichannel buffers could be + used with Sources, but the specification does not endorse this at this + time as this might not be guaranteed for all multichannel data formats + &AL; will support. + + + While spatialized sound is often played once, or looping a limited number + of times, multichannel data is usually streaming: typically stereo or MP3 + music, soundtracks, maybe voice data accompanying animation and cinematic + sequences. The queueing mechanism defined for mono buffers and spatialized + Sources is thus also applied to multichannel buffers and passthrough + output. + + + Applications can expect &AL; implementations to support more than one + multichannel output at once (e.g. mixing two stereo streams, or fading + from one to the other for transition). For that reason we can not restrict + multichannel output to just one stream or buffer at a time. + + + Annotation (per-case Buffer use) + The specification will likely be amended at a later time to + allow for the use of mono buffers with multichannel output, + and multichannel buffers with spatialized Sources. + The decision to use the same buffer API for mono + and multichannel buffers was taken in anticipation of this. + In cases where the specification can not guarantee + use of a given multichannel data encoding with a + spatialized source, an error can be generated at the + attempted use, validating the buffer's internal format + against the output chosen. In cases were the specification + can not guarantee the implementation will defer the + conversion of multichannel buffer content as needed (e.g. + PCM stereo data), the application can either specify the + internal format, or the internal format enumeration + can be extended to explicitely request storage of both + multichannel and mono data within the same buffer, at memory + expense. + + ]]> + + +
+ Specifying Buffer Content and Internal Format + + The existing BufferData command does not permit the application + to specify an internal format. The implementation is free to + apply conversions, downsampling, upsampling, including + interpolation and filtering, in accordance with the specification. + + + However, applications might want to use different trade-offs + between quality and resource expenditure. More imortantly, + applications might choose to use preprocessed, multichannel + data instead of doing runtime spatialization, e.g. for + recorded music, voice, and realtime streams. In this case + the application expects efficient passthrough of the data + to the hardware. + + + To account for this requirement, an extended command to specify + sample data to be stored in a given buffer is introduced. + + &void; BufferWriteData + &uint; bufferName + &enum; format + &void;* data + &sizei; size + &uint; frequency + &enum; internalFormat + + The internal format of the Buffer can be requested by the + application. The implementation is not required to match + the request excatly. The specification does guarantee that + use of a multichannel internalFormat parameter will cause + the implementation to treat the data as multichannel data. + The implementation is free to perform any remapping from + the number of channels used in the data to the number of + channels available at the output, and apply other prcessing + as needed. + + + Valid formats for internalFormat are FORMAT_MONO8, FORMAT_MONO16, + FORMAT_STEREO8, and FORMAT_STEREO16. An implementation may + expose other formats, see the chapter on Extensions for + information on determining if additional formats are supported. + In general, the set of valid internalFormat parameters will be + a subset of those available as format parameters. + + + Annotation (atomic WriteData) + The internal format for a buffer can not be specified + by using Bufferi. The modular way to set state + is preferable for operations that are always, or + nearly legal and orthogonal, but specifying the + internal format affect allocation and use of a buffer, + and would cause too many error cases. + + ]]> + + Annotation (change buffer format on write) + The API allows for changing a buffer on every write operation, + turning a multichannel buffer into a mono buffer and vice versa. + The specification does not require the implementation to handle + these operations efficiently, as they might require reallocation + of memory. The same is true for resize operations at write. + Applications might prefer to release buffer names that do not + match current requirements, and request new buffer names instead, + an operation which implementations are encouraged to optimize. + + ]]> + + Annotation (BufferReadData) + The specification might be amended at a later time + with a command to retrieve the data from a buffer, + following use of alGetBuffer to retrieve size and + internalFormat. Reading has to be queued for + continuous reads from the actual mixing buffer. + + ]]> + RFC: frequency for write/read? + Do we (ever) want to provide the application control over the internal frequency? + + ]]> +
+ + +
+ Rendering Multichannel Buffers + + For a variety of reasons, Sources are not used to feed buffer + data into multichannel processing. Instead, a different class + of &AL; object is introduced to encapsulate state management + and resource management for multichannel output: Multichannel + objects. + + + Multichannel objects are referred to by name, and they + are managed by an API partly duplicating the Source API: + GenMultichannels, IsMultichannel, DeleteMultichannels, + Multichanneli and GetMultichanneli. However, the + SourcePlay/Stop commands as well as the Queue/Unqueue + commands can be applied to both: these commands accept + mcName parameters as well as sName parameters. It is + left to the implementation how a Name is mapped to an + object, and how the implementation dinstiguishes sNames + from mcNames. Within a 32bit namespace, and given the + small number of multichannel sources to expect (more than + one is quite possible, but not common), the implementation + can exploit the fact that Names are opaque to the + application. + + + Annotation (Source NONE) + The literal value "0", i.e. NONE, is legal. All + operations on Source/Multichannel NONE are legal NOPs + and quietly ignored. Because of the ambiguity + (is NONE a Source or Multichannel) NONE will never + be available as an actual object, nor will operations + on it ever have effects. + + ]]> + + Annotation (implicit ambient) + One way to feed multichannel data into the rendering is + using the Listener as a Source (sname==0 implies + Listener). This was rejected, as it + does not allow for multiple streams. Using multiple + Sources with appropriate type SOURCE_AMBIENT or + SOURCE_MULTICHHANEL was rejected, as Sources + are by definition spatialized, and support operations + which are meaningless or even illegal for an output + that is not spatialized at all. Modifying the semantics + of Source spatialization by a provision that a relative + position of (0,0,0) would mark a Source as ambient was + rejected for clarity and cleanness. Updates of Source + position can not be expected to convert Sources from + spatialized to ambient and vice versa at any time, + a Source State dependent semantics of position updates + is outright confusing, handling of sources that are + SOURCE_ABSOLUTE but incidentally at listener position + can not be different from that of SOURCE_RELATIVE with + a zero offset. Furthermore, multichannel data is not + necessarily ambient (surround can rotate, while ambient + attempts to prevent any perception of direction). + Finally, multichannel processing might require per-channel + gain adjustment at user request, which is a meaningless + concept for Sources. + + ]]> + + + Annotation (no direct mixing) + Direct mixing into the rendering buffer, allowing the + application to superimpose its multichannel data + (or custom software mixing results) on the audio stream + generated by spatialization was rejected, as it suffers + from similar problems as BufferAppendData and loop points, + namely the need to operate at sample level on buffers of + unknown format that might not even be directly accessible. + The same rationale that led to the adoption of maintaining + a processing queue for Sources applies to multichannel data. + + ]]> + + Annotation (no combined Buffer/Passthrough) + Multichannel buffers cannot serve as multichannel output + objects for two reasons: it would complicate the buffer + API with operations only applicable to a subset of buffers, + and it does not allow for queueing. + + ]]> + + RFC: Per-Channel access + At a later time we might want to amend the specification to + gain access to a single channel within a multichannel buffer. + I suggest that any such operation should be restricted to the + ability of reading samples from just one channel into application + memory, which allows for writing it into a mono buffer subsequently. + + ]]> + +
+
\ No newline at end of file diff --git a/openal/docs/chp-operation.sgml b/openal/docs/chp-operation.sgml new file mode 100644 index 000000000..78fa87b6d --- /dev/null +++ b/openal/docs/chp-operation.sgml @@ -0,0 +1,977 @@ + + + &OAL; Operation + + + &OAL; Fundamentals + + &OAL; (henceforth, the "&AL;") is concerned only with rendering audio + into an output buffer, + and primarily meant for spatialized audio. + There is no support for reading audio input from buffers at this + time, and no support for MIDI and other components usually + associated with audio hardware. Programmers must relay on other + mechanisms to obtain audio (e.g. voice) input or generate music. + + + The &AL; has three fundamental primitives or objects -- Buffers, Sources, + and a single Listener. Each object can be changed independently, + the setting of one object does not affect the setting of others. + The application can also set modes that affect processing. Modes + are set, objects specified, and other &AL; operations performed + by sending commands in the form of function or procedure calls. + + Sources store locations, directions, and other attributes of an object in 3D + space and have a buffer associated with them for playback. There are + normally far more sources defined than buffers. When the program wants to play + a sound, it controls execution through a source object. Sources are + processed independently from each other. + + Buffers store compressed or un-compressed audio data. It is common to + initialize a large set of buffers when the program first starts (or at + non-critical times during execution -- between levels in a game, for instance). + Buffers are referred to by Sources. Data (audio sample data) is associated + with buffers. + + There is only one listener (per audio context). The listener attributes are + similar to source attributes, but are used to represent where the user is + hearing the audio from. The influence of all the sources from the + perspective of the listener is mixed and played for the user. + + + RFC: Data Binding + Have to specifiy when pointer arguments are dereferenced. + + ]]> + + Primitive Types + + As &AL; is meant to allow for seamless integration with &OGL; code + if needed, the &AL; primitive (scalar) data types mimic the + &OGL; data types. Guaranteed minimum sizes are stated for &OGL; + data types (see table 2.2 of the &OGL; 1.2 Specification), but + the actual choice of C datatype is left to the implementation. + All implementations on a given binary architecture, however, must + use a common definition of these datatypes. + + + RFC/000507: + ALlong/ALulong are omitted from the Linux OpenGL Base ABI, + and the GL specification. Do we want to go ahead on this, + or trail GL? Do we include non-i386 architectures to list + sizes explicitely. I.e. do we make the ABI part of our + mandate? + + ]]> + + + Note that this table uses explicit AL prefixes for clarity, + while they might be omitted from the rest of the document + for brevity. GCC equivalents are given for IA32, i.e. a + portable and widely available compiler on the most common + target architecture. + + &AL; Primitive Data Types + + + + + + AL Type + Description + GL Type + GCC IA32 + + + + + ALboolean + 8-bit boolean + GLboolean + unsigned char + + + ALbyte + signed 8-bit 2's-complement integer + GLbyte + signed char + + + ALubyte + unsigned 8-bit integer + GLubyte + unsigned char + + + ALshort + signed 16-bit 2's-complement integer + GLshort + short + + ALushort + unsigned 16-bit integer + GLushort + unsigned short + + + ALint + signed 32-bit 2's-complement integer + GLint + int + + + ALuint + unsigned 32-bit integer + GLuint + unsigned int + + + ALlong + signed 64-bit 2's-complement integer + n/a + long long + + + ALulong + unsigned 64-bit integer + n/a + unsigned long long + + ]]> + + ALsizei + non-negative 32-bit binary integer size + GLsizei + int + + + ALenum + enumerated 32-bit value + GLenum + unsigned int + + + ALbitfield + 32 bit bitfield + GLbitfield + unsigned int + + + ALfloat + 32-bit IEEE754 floating-point + GLfloat + float + + + ALclampf + Same as ALfloat, but in range [0, 1] + GLclampf + float + + + ALdouble + 64-bit IEEE754 floating-point + GLdouble + double + + + ALclampd + Same as ALdouble, but in range [0, 1] + GLclampd + double + + + +
+
+ + + + Annotation on Type Sizes + It would be desirable to guarantee the bit size of &AL; data + types, but this might affect the mapping to &OGL; types + for which the &OGL; specification only guarantees a minimum + size. + + Annotation on 64bit integral + It would be desirable to define ulong and long, but again + we defer to &OGL; in this decision. + + Annotation on Enumeration + &enum; is not a C or C++ enumeration, but implemented as + C preprocesor defines. This makes it easier to handle + extensions to the &AL; namespace, in particular in + dealing with delays in distributing updated reference + headers. + + ]]> +
+ + Floating-Point Computation + + Any representable floating-point value is legal as input + to a &AL; command that requires floating point data. + The result of providing a value that is not a floating + point number to such a command is unspecified, but must not + lead to &AL; interruption or termination. In IEEE arithmetic, + for example, providing a negative zero or a denormalized + number to a GL command yields predictable results, while + providing an NaN or infinity yields unspecified results. + + Some calculations require division. In such cases (including + implied divisions required by vector normalizations), a + division by zero produces an unspecified result but must + not lead to GL interruption or termination. + + +
+ + + AL State + + The &AL; maintains considerable state. This documents enumerates + each state variable and describes how each variable can be + changed. For purposes of discussion, state variables are + categorized somewhat arbitrarily by their function. For example, + although we describe operations that the &AL; performs on the + implied output buffer, the outbut buffer is not part of the + &AL; state. Certain states of &AL; objects (e.g. buffer states + with respect to queueing) are introduced for discussion purposes, + but not exposed through the API. + + + + + AL Command Syntax + + &AL; commands are functions or procedures. Various groups of + commands perform the same operation but differ in how + arguments are supplied to them. To conveniently accomodate + this variation, we adopt the &OGL; nnotation for describing + commands and their arguments. + + + Annotation (Not all types supported yet) + At this time &AL; does not support the full flexibility that + &OGL; offers. Certain entry points are supported only for + some data types. In general, &AL; tends to use less entry + points, using setter commands that use the same tokens + as the matching query commands. + + ]]> + + + + + Basic AL Operation + + &AL; can be used for a variety of audio playback tasks, and is an + excellent complement to &OGL; for real-time rendering. A programmer who is + familiar with &OGL; will immediately notice the similarities between the + two APIs in that they describe their 3D environments using similar methods. + + + For an &OGL;/&AL; program, most of the audio programming will be in two + places in the code: initialization of the program, and the rendering loop. + An &OGL;/&AL; program will typically contain a section where the graphics and + audio systems are initialized, although it may be spread into multiple functions. + For OpenAL, initialization normally consists of creating a context, creating + the initial set of buffers, loading the buffers with sample data, creating + sources, attaching buffers to sources, setting locations and directions for + the listener and sources, and setting the initial values for state global + to &AL;. + + + + Initialization Example + + &sample.c; + + + + + + + Initialization Example + + &ExInitAL.c; + + + ]]> + + + The audio update within + the rendering loop normally consists of telling &AL; the current locations + of the sources and listener, updating the environment settings, and managing + buffers. + + + + Processing Loop + +// PlaceCamera -- places OpenGL camera and updates OpenAL listener position and source state +void 3DEnvironemnt:PlaceCamera() +{ + // update OpenGL camera position + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-0.1333, 0.1333, -0.1, 0.1, 0.2, 50.0); + + gluLookAt(listenerPos[0], listenerPos[1], listenerPos[2], + (listenerPos[0] + sin(listenerAngle)), listenerPos[1], (listenerPos[2] - cos(listenerAngle)), + 0.0, 1.0, 0.0); + + // OpenAL stuff... + // place listener at camera + alListener3f(AL_POSITION, listenerPos[0], listenerPos[1], listenerPos[2]); + float directionvect[6]; + directionvect[0] = (float) sin(listenerAngle); + directionvect[1] = 0; + directionvect[2] = (float) cos(listenerAngle); + directionvect[3] = 0; + directionvect[4] = 1; + directionvect[5] = 0; + alListenerfv(AL_ORIENTATION, directionvect); + + // play phasor if in range, else stop playback + if (range() < 9) + { + alSourcePlay(source[1]); + } else + { + alSourceStop(source[1]); + } +} + + + ]]> + + + + + AL Errors + + The AL detects only a subset of those conditions that could be + considered errors. This is because in many cases error checking + would adversely impact the performance of an error-free program. + The command + + &enum; GetError + + + is used to obtain error information. Each detectable error is + assigned a numeric code. When an error is detected by AL, + a flag is set and the error code is recorded. Further errors, + if they occur, do not affect this recorded code. When GetError + is called, the code is returned and the flag is cleared, so that + a further error will again record its code. If a call to GetError + returns NO_ERROR then there has been no detectable error since + the last call to GetError (or since the AL was initialized). + + + RFC: GL distributed error + To allow for distributed implementations there may be several + flag/code pairs. In this case, after a call to GetError returns a + value other than NO_ERROR each subsequent call returns the + non-NO_ERROR code of another distinct flag-code pair (in + unspecified order), until all NO_ERROR codes have been returned. + When there are no more non-NO_ERROR codes, all flags be reset. + The initial state of all flags is cleared and the initial value + of all codes is NO_ERROR. + + Annotation (Looping GetError) + &AL; applications are advised to loop calls of GetError to + make sure that all flags are reset. Only the first error + occurence for each flag/code pair is recorded, subsequent + errors are ignored. The result of a repeated GetError call + is not a stack trace or LIFO sequence. All error handling + is context specific. + + + ]]> + + + Annotation (Only First Error) + Like &OGL; &AL; will ignore subsequent errors once an + error conditation has been encountered. + + ]]> + + + Error codes can be mapped to strings. The GetString function + returns a pointer to a constant (literal) string that is + identical to the identifier used for the enumeration value, + as defined in the specification. + + + Annotation/ Verbose Error String + There is no need to maintain a separate GetErrorString + function (inspired by the proposed gluGetErrorStrings) + as the existing GetString entry point can be used. + + ]]> + + + + + Error Conditions + + + + + + Name + Description + + + + + NO_ERROR + "No Error" token. + + + INVALID_NAME + Invalid Name parameter. + + + INVALID_ENUM + Invalid parameter. + + + INVALID_VALUE + Invalid enum parameter value. + + + INVALID_OPERATION + Illegal call. + + + OUT_OF_MEMORY + Unable to allocate memory. + + + +
+ The table summarizes the AL errors. Currently, when an error flag + is set, results of AL operations are undefined only if OUT_OF_MEMORY + has occured. In other cases, the command generating the error is + ignored so that it has no effect on AL state or output buffer + contents. If the error generating command returns a value, + it returns zero. If the generating command modifies values + through a pointer argument, no change is made to these values. + These error semantics apply only to AL errors, not to system errors + such as memory access errors. +
+ + Several error generation conditions are implicit in the description + of the various AL commands. First, if a command that requires + an enumerated value is passed a value that is not one of those + specified as allowable for that command, the error INVALID_ENUM + results. This is the case even if the argument is a pointer to + a symbolic constant if that value is not allowable for the given + command. + This will occur whether the value is allowable for other functions, + or an invalid integer value. + + + Integer parameters that are used as names for &AL; objects + such as Buffers and Sources are checked for validity. If an invalid + name parameter is specified in an &AL; command, an + INVALID_NAME error will be generated, and the command is ignored. + + + If a negative integer is provided where an argument of type + &sizei; is specified, the error INVALID_VALUE results. The same + error will result from attempts to set integral and floating + point values for attributes exceeding the legal range for + these. The specification does not guarantee that the implementation + emits INVALID_VALUE if a &NaN; or &Infty; value is + passed in for a &float; or &double; argument (as the specification + does not enforce possibly expensive testing of floating point + values). + + + + Commands can be invalid. For example, certain commands might not be + applicable to a given object. There are also illegal combinations + of tokens and values as arguments to a command. &AL; responds to any + such illegal command with an INVALID_OPERATION error. + + + + No longer true except for extensions. To be avoided + in general: &AL; has + mutually exclusive commands operating on similar objects. + One example is treating a streaming buffer as a + non-streaming buffer, another is appending data to a + non-streaming buffer. + + ]]> + + + If memory is exhausted as a side effect of the execution of an + AL command, either on system level or by exhausting the allocated + resources at AL's internal disposal, the error OUT_OF_MEMORY + may be generated. This can also happen independent of recent + commands if &AL; has to request memory for an internal task + and fails to allocate the required memory from the operating + system. + + + Otherwise errors are generated only for conditions that are + explicitely described in this specification. + + + + RFC: INVALID_SIZE? + Specific error case in which the size argument is + negative, or mismatches internal conditions for a getter? + + ]]> + + + RFC: INVALID_POINTER? + GL seemingly does not specify a response to NULL pointer + destinations, and does not assign an error case. INVALID_VALUE + could be used, also we could introduce a separate INVALID_POINTER. + Is there a good reason not to catch these cases? + + ]]> + + +
+ + + + + Controlling AL Execution + + The application can temporarily disable certain AL capabilities + on a per Context basis. This allows the driver implementation + to optimize for certain subsets of operations. + Enabling and disabling capabilities is handled using a function + pair. + + &void; Enable + &enum; target + + + &void; Disable + &enum; target + + The application can also query whether a given capability is + currently enabled or not. + + &bool; IsEnabled + &enum; target + + If the token used to specify target is not legal, + an INVALID_ENUM error will be generated. + + + At this time, this mechanism is not used. There are no valid + targets. + + Annotation (Enable/Disable) + Currently, &AL; is controlled exploiting existing + commands. For example, to disable sound output but + not processing, the Listener can be muted setting + GAIN to zero. Selecting NONE as the distance model + disables distance attenuation. Setting DOPPLER_FACTOR + to zero disables the Doppler Effect. A redundant + mechanism to accomplish the same is not needed. + + ]]> + + + + + Object Paradigm + + &AL; is an object-oriented API, but it does not expose classes, structs, + or other explicit data structures to the application. + + + + + Object Categories + + &AL; has three primary categories of Objects: + + + + one unique Listener per Context + + + + + multiple Buffers shared among Contexts + + + + + multiple Sources, each local to a Context + + + + In the following, "{Object}" will stand for either Source, + Listener, or Buffer. + + + + + Static vs. Dynamic Objects + + The vast majority of &AL; objects are dynamic, and will be created + on application demand. There are also &AL; objects that do not have + to be created, and can not be created, on application demand. + Currently, the Listener is the only such static object in &AL;. + + + + + + Object Names + + Dynamic Objects are manipulated using an integer, which in + analogy to &OGL; is referred to as the object's "name". These + are of type unsigned integer (uint). Names can be valid + beyond the lifetime of the context they were requested + if the objects in question can be shared among contexts. + No guarantees or assumptions are + made in the specification about the precise values or their distribution + over the lifetime of the application. As objects might be shared, + Names are guaranteed to be + unique within a class of &AL; objects, but no guarantees are made + across different classes of objects. Objects that are unique + (singletons), like the Listener, do not require and do not have + an integer "name". + + + + + + Requesting Object Names + + &AL; provides calls to obtain Object Names. The application requests + a number of Objects of a given category using Gen{Object}s. + If the number n of Objects requested is negative, + an INVALID_VALUE error will caused. The actual values of the + Names returned are implementation dependent. No guarantees on + range or value are made. Unlike &OGL; &OAL does not offer alternative + means to define (bind) a Name. + + + Allocation of Object Names does not imply immediate allocation of + resources or creation of Objects: the implementation is free to + defer this until a given Object is actually used in mutator calls. + The Names are written at the memory location specified by the caller. + + void Gen{Object}s + &sizei; n + &uint;* objectNames + + + + Requesting zero names is a legal NOP. Requesting a negative + number of names causes an INVALID_VALUE error. + &AL; will respond with an OUT_OF_MEMORY if the application + requests too many objects. The specification does not guarantee + that the &AL; implementation will allocate all resources + needed for the actual objects at the time the names are + reserved. In many cases (Buffers) this could only be + implemented by worst case estimation. Allocation of names + does not guarantee that all the named objects can actually + be used. + + + + + We do not re-use Names under any circumstance. Do we require + implementations throwing OUT_OF_MERMORY errors on allocation of + Names? No - we don't even specify buffer sizes. Ambiguity - could + an implementation throw OOM because of no names, or OOM because + of a (worst case) estimate of object sizes? Do we need OUT_OF_NAMES? + + ]]> + + + + The current headers include a sizei return parameter: + "Returns the number of ids actually allocated." + This violates the "failed commands are NOPs" design + and introduces ambiguity in error handling, and has + thus been changed breaking backwards compatibility. + + ]]> + + Annotation (No application selected Names) + Unlike GL, applications are not free to choose Names; all + Names have to be requested. Aside from possible benefits for + the implementation, and avoidance of errors in projects + that have many modules using the AL implementation (a problem + encountered in GL, when the two generation mechanisms are + mixed), this also leaves open the door to feed different + kinds of objects by Name through the same API entry points. + + ]]> + + Annotate (Negative/zero sizei) + The specification does not guarantee that sizei is an + unsigned integer, but legal values have to be non-negative. + However, requesting zero names is a legal NOP. + + ]]> + + RFC: Resource Release Hint + Do we need a hint that resource release has to be done on DeleteXXX, + instead of leaving this housekeeping to &AL;? + + RFC: Zero Name + Do we reserve the name "0"? &OGL; provides an alternative mechanism + which lets the application pick texture names, which we discarded + because it is prone to create error conditions when mixing both + approaches. As all our names are generated using GenXXXX, there + is no real need to treat "0" special. + + ]]> + + + + + + Releasing Object Names + + &AL; provides calls to the application to release Object Names + using Delete{Object}s, implicitly requesting deletion of the + Objects associated with the Names released. If the number n of Objects named + is negative, an INVALID_VALUE error will be caused. + If one or more of the specified Names is not valid, an INVALID_NAME + error will be caused. Implementation behavior following any error + is undefined. + + + Once deleted (even if an error occured on deletion), the Names are + no longer valid for use with any &AL; function calls including + calls to Delete{Objects}s. Any such use will cause an INVALID_NAME + error. + + + The &AL; implementation is free to defer actual release of + resources. Ideally, resources should be released as soon as + possible, but no guarantees are made. + + &void;Delete{Object}s + &sizei;n + &uint;*objectNames + + + + Annotation + GenXXX and DeleteXXX can not reasonably be expected to be used + for controlling driver-side resource management from the + application. A driver might never release a Source once allocated + during the lifetime of the application. + + ]]> + + RFC: Deletion Errors + chasan@acm.org: + What happens if an active source (or its associated buffer) is deleted? + The source should be stopped? Or the delete operation is invalid? + + ]]> + + + + + + Validating an Object Name + + &AL; provides calls to validate the Name of an Object. + The application can verify whether an Object Name is valid + using the Is{Object} query. There is no vector (array) + version of this function as it defeats the purpose of + unambiguous (in)valdiation. Returns &TRUE; if id is a + valid Object Name, and &FALSE; otherwise. Object Names are + valid between request (Gen{Object}s) and release (Delete{Object}s). + Is{Object} does not distinguish between invalid and deleted Names. + + &bool;Is{Object} + &uint;objectName + + + RFC/bk000504: + If zero is a valid name, this function will have to accept + it without an actyual object (or only an internal dummy) + being associated with it. I recommend that implementations + never return "0" as an object name. + + ]]> + + + + + Setting Object Attributes + + For &AL; Objects, calls to control their attributes are provided. + These depend on the actual properties of a given Object + Category. The precise API is discussed for each category, + below. Each &AL; command affecting the state of + a named Object is usually of the form + + void {Object}{n}{sifd}{v} + &uint; objectName + &enum; paramName + &type; values + + In the case of unnamed (unique) Objects, the (integer) objectName + is omitted, as it is implied by the {Object} part of function name: + + void {Object}{n}{sifd}{v} + &enum; paramName + &type; values + + For example, the Listener3d command would not require an (integer) + objectName argument. + + + The objectName specifies the &AL; object affected by this call. + Use of an invalid Name will cause an INVALID_NAME error. + + + The Object's Attribute to be affected has to be named + as paramName. &AL; parameters applicable to one category + of Objects are not necessarily legal for another catetgory + of &AL; Objects. Specification of a parameter illegal for + a given object will cause an INVALID_OPERATION error. + + + Not all possible values for a type will be legal for a + given objectName and parameterName. Use of an illegal value + or a NULL value pointer will cause an INVALID_VALUE error. + + + Any command that causes an error is a NOP. + + + + + Querying Object Attributes + + For named and for unique &AL; Objects, calls to query their + current attributes are provided. + These depend on the actual properties of a given Object + Category. The performance of such queries is implementation + dependent, no performance guarantees are made. The valid values for the + parameter paramName are identical to the ones legal for the complementing + attribute setting function. + + void Get{Object}{n}{sifd}{v} + &uint; objectName + &enum; paramName + &type;* destination + + For unnamed unique Objects, the objectName is omitted as it is + implied by the function name: + + void Get{Object}{n}{sifd}{v} + &enum; paramName + &type;* destination + + + + The precise API is discussed for each category separately, below. + Unlike their matching mutators, Query functions for non-scalar + properties (vectors etc.) are only available in array form. + + + Use of an invalid Name will cause an INVALID_NAME error. + Specification of an illegal parameter type (token) will cause + an INVALID_ENUM error. A call with a destination + NULL pointer will be quietly ignored. The &AL; state will not + be affected by errors. In case of errors, destination memory + will not be changed. + + + + + + Object Attributes + + + Attributes affecting the processing of sounds can be set for various + &AL; Object categories, or might change as an effect of &AL; calls. + The vast majority of these Object properties are specific to the + &AL; Object category, in question, but some are applicable to two + or more categories, and are listed separately. + + + The general form in which this document describes parameters is + + {Object} Parameters + + + + + + + + &Par; + &Sig; + &Val + &Def; + + + + + paramName + T + range or set + scalar or n-tuple + + + +
+ Description: + The description specifies additional restrictions and details. + paramName is given as the &AL; enum defined as its name. + T can be a list of legal signatures, usually the array form + as well as the flat (unfolded) form. +
+ + + RFC: Initial (Default) State + The default state of objects will have to be specified here. + There will be no commands that allow the application to set + other defaults. + + ]]> +
+
+
+ diff --git a/openal/docs/chp-queueing.sgml b/openal/docs/chp-queueing.sgml new file mode 100644 index 000000000..8bce727b5 --- /dev/null +++ b/openal/docs/chp-queueing.sgml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/openal/docs/chp-rendering.sgml b/openal/docs/chp-rendering.sgml new file mode 100644 index 000000000..1237e88df --- /dev/null +++ b/openal/docs/chp-rendering.sgml @@ -0,0 +1,2076 @@ + + + + Listener and Sources + + + Basic Listener and Source Attributes + + This section introduces basic attributes that can be set both for + the Listener object and for Source objects. + + + RFC: attribute grouping + JM: "These attributes are of + two types: non-positional and positional. + Non-positional properties include gain control and Environment Name." + + I said: (low pass) Filters are applied to the sound during processing + at various stages. The exact sequence in which Filters are applied is + determined based on the location of the Objects they are + set for - spatial arrangement of Objects determines the + sequence unless invariance is guaranteed, or invariance + violation is permitted by the specification and current &AL; + configuration state. + + Is there a required order of application, i.e. a pipeline? + + Filter Parameters vs. Non-positional properties. + Spatialization vs. Positional properties. + Spatial attributes? + Let's postpone grouping of attributes. + + ]]> + + + + The &AL; Listener and Sources have attributes to describe + their position, velocity and orientation in three dimensional space. + &AL; like &OGL;, uses a right-handed Cartesian coordinate system (RHS), + where in a frontal default view X (thumb) points right, + Y (index finger) points up, and Z (middle finger) points towards + the viewer/camera. To switch from a left handed coordinate system (LHS) + to a right handed coordinate systems, flip the sign on the Z coordinate. + + + + + Listener/Source Position + + + + &Par; + &Sig; + &Val + &Def; + + + + + POSITION + 3fv, 3f + any except NaN + { 0.0f, 0.0f, 0.0f } + + + +
+ Description: + POSITION specifies the current location of the Object in the + world coordinate system. Any 3-tuple of valid float/double values + is allowed. Implementation behavior on encountering &NaN; and &Infty; + is not defined. The Object position is always defined in the + world coordinate system. +
+ + Annotation (No Transformation) + &AL; does not support transformation operations on Objects. + Support for transformation matrices is not planned. + + ]]> + + + + + Listener/Source Velocity + + + + &Par; + &Sig; + &Val + &Def; + + + + + VELOCITY + 3fv, 3f + any except NaN + { 0.0f, 0.0f, 0.0f } + + + +
+ Description: + VELOCITY specifies the current velocity (speed and direction) of + the Object, in the world coordinate system. Any 3-tuple of valid + float/double values is allowed. The Object VELOCITY does not affect + its position. + &AL; does not calculate the velocity from subsequent position + updates, nor does it adjust the position over time based on + the specified velocity. Any such calculation is left to the + application. For the purposes of sound processing, position and + velocity are independent parameters affecting different aspects + of the sounds. +
+ VELOCITY is taken into account by the driver to synthesize the + Doppler effect perceived by the Listener for each source, based + on the velocity of both Source and Listener, and the Doppler + related parameters. + + + + + + + + Listener/Source Gain (logarithmic) + + + + &Par; + &Sig; + &Val + &Def; + + + + + GAIN + f + 0.0f, (0.0f, any + 1.0f + + + +
+ Description: + GAIN defines a scalar amplitude multiplier. As a Source attribute, it applies + to that particular source only. As a Listener attribute, it effectively + applies to all Sources in the current Context. The default 1.0 means + that the sound is un-attenuated. A GAIN value of 0.5 is equivalent to + an attenuation of 6 dB. The value zero equals silence (no output). Driver + implementations are free to optimize this case and skip mixing and + processing stages where applicable. The implementation is in charge of + ensuring artifact-free (click-free) changes of gain values and is free + to defer actual modification of the sound samples, within the limits of + acceptable latencies. +
+ + GAIN larger than 1 (amplification) is permitted for Source and + Listener. However, the implementation is free to clamp the + total gain (effective gain per source times listener gain) + to 1 to prevent overflow. + + + + Annotation/ Effective Minimal Distance + Presuming that the sample uses the entire dynamic range of + the encoding format, an effective gain of 1 represents the + maximum volume at which a source can reasonably be played. + During processing, the implementation combines the Source + GAIN (or MIN_GAIN, if set and larger) with distance based + attenuation. The distance at which the effective gain is 1 + is equivalent to the DirectSound3D MIN_DISTANCE parameter. + Once the effective gain has reached the maximum possible + value, it will not increase with decreasing distance anymore. + + ]]> + + + Annotation (Muting a Context) + To mute the current context, simply set Listener GAIN to zero. + The implementation is expected to optimize for this case, + calculating necessary (offset) updates but bypassing the + mixing and releasing hardware resources. + The specification does not guarantee that the implementation + will release hardware resources used by a muted context. + + ]]> + + Annotation (Muting a Source) + To mute a Source, set Source GAIN to zero. The &AL; implementation + is encouraged to optimize for this case. + + ]]> + + + RFC: GAIN > 1? + GAIN could exceed 1 (to compensate attenuation elsewhere, or to account + for grater dynamic range of the hardware? No guarantees are made with + respect to range overflows? Precision loss? Culling by effective gain? + Does &AL; clip values during processing, and when/at what stages? + + + RFC: Doppler + JM wrote: "VELOCITY is used by the driver + to synthesize the Doppler effect perceived by the listener for each + source, based on the relative velocity of this source with respect + to the listener." + Doppler is calculated using Source and Listener velocities measured + with respect to the medium. Do we have to account for the medium + to move (offsetting listener/source) in later revisions (air/water currents)? + + + RFC: + JM removed: "For the purposes of sound processing, position and + velocity are independent parameters affecting different paths + in the sound synthesis." I think the "different aspects of sounds" + is ambiguous. Is there a problem with describing &AL; as a + multichannel processing machine? + + + ]]> + +
+ + + + Listener Object + + + The Listener Object defines various properties that affect processing of + the sound for the actual output. The Listener is unique for an &AL; Context, + and has no Name. By controlling the listener, the application controls + the way the user experiences the virtual world, as the listener defines + the sampling/pickup point and orientation, and other parameters that + affect the output stream. + + + It is entirely up to the driver and hardware configuration, i.e. + the installation of &AL; as part of the operating system and + hardware setup, whether the output stream is generated for + headphones or 2 speakers, 4.1 speakers, or other arrangements, + whether (and which) HRTF's are applied, etc.. + + + Annotation (Listener Anatomy) + The API is ignorant with respect to the real world + listener, it does not need to make assumptions on the + listening capabilities of the user, its species or its + number of ears. It only describes a scene and the position + of the listener in this scene. It is the &AL; implementation + that is designed for humans with ears on either side of the + head. + + ]]> + + + Annotation (Listener State Evaluation) + Some Listener state (GAIN) affects only the very last + stage of sound synthesis, and is thus applied to the sound stream + as sampled at the Listener position. Other Listener state is + applied earlier. One example is Listener velocity as used to + compute the amount of Doppler pitch-shifting applied to each source: + In a typical implementation, pitch-shifting (sample-rate conversion) + might be the first stage of the audio processing for each source. + + ]]> + + + + Listener Attributes + + + Several Source attributes also apply to Listener: e.g. POSITION, VELOCITY, + GAIN. In addition, some attributes are listener specific. + + Listener Orientation + + + + &Par; + &Sig; + &Val + &Def; + + + + + ORIENTATION + fv + any except NaN + { { 0.0f, 0.0f, -1.0f }, { 0.0f, 1.0f, 0.0f } } + + + +
+ Description: + ORIENTATION is a pair of 3-tuples representing the 'at' direction vector + and 'up' direction of the Object in Cartesian space. &AL; expects two + vectors that are orthogonal to each other. These + vectors are not expected to be normalized. If one or more vectors + have zero length, implementation behavior is undefined. If the two + vectors are linearly dependent, behavior is undefined. +
+ RFC: Orientation Paranoia + Watch LHS vs. RHS (sign on 'at'). + Confirm sequence is (up, at) not vice versa. + Do we want to allow for different representations down the road? + + ]]> +
+ + + Changing Listener Attributes + + Listener attributes are changed using the Listener group of commands. + + void Listener{n}{sifd}{v} + &enum; paramName + &type; values + + + + + + Querying Listener Attributes + + Listener state is maintained inside the &AL; implementation and can be + queried in full. See Querying Object Attributes. The valid values for + paramName are identical to the ones for the Listener* command. + + void GetListener{sifd}v + &enum; paramName + &type;* values + + + +
+ + + + + Source Objects + + Sources specify attributes like position, velocity, and a buffer with + sample data. By controlling a Source's attributes the + application can modify and parameterize the static sample data provided + by the Buffer referenced by the Source. + Sources define a localized sound, and encapsulate + a set of attributes applied to a sound at its origin, i.e. in the + very first stage of the processing on the way to the listener. + Source related effects have to be applied + before Listener related effects unless the output is invariant + to any collapse or reversal of order. + + + &AL; also provides additional functions to manipulate and query the + execution state of Sources: the current playing status of a + source (started, stopped, paused), including access to the current + sampling position within the associated Buffer. + + + RFC: Mike on Source Types + AL_SOURCE_ABSOLUTE and AL_SOURCE_AMBIENT have been + deprecated. AL_SOURCE_ABSOLUTE was simply the converse of the + AL_SOURCE_RELATIVE pname, and as such was unnecessary. The + effect of AL_SOURCE_AMBIENT is trivially emulated by either + querying the Listener position and setting the Source position + accordingly, or setting the Source position to (0,0,0) and the + type to AL_SOURCE_RELATIVE, and is therefore also unnecessary. + + ]]> + + + RFC: Bernd on Source Types + Mike seems to miss a few problems here. W/o a converse we can't + reset source attributes to ABSOLUTE. Ambient sounds are not + necessarily trivial. A3D manual suggested some magic number + to fake the effect of ambient (i.e. sound that ideally + can't be localized by listener). If we can get away with such magic + numbers in a tutorial in a driver-independent way, fine. If there is any + risk that the impression of ambient sound requires driver specific + hacks, then we need AMBIENT. As soon as we have a third localization + type, ABSOLUTE and RELATIVE are needed as there is no unambiguous + converse. + + From the A3D 2.0 Optimize.doc: + "Adding some ambient background noise is a great way to fill in the gaps + when the audio content is reduced. A great way to make an ambient sound + seem like it is coming from everywhere is to load up two buffers with the + same sound, and position them about 2 meters behind the listener at + about 4 and 8 o\rquote clock. The waves have to be looping (make sure + there is no beating when you play them back). Starting the sounds 180 + degrees out of phase can help, as will playing them with slightly different + pitch-shift values." + + ]]> + + RFC: Bernd on Source Types (2) + There is a point to be made in using POSITION_RELATIVE and + VELOCITY_RELATIVE iff we do not have AMBIENT to consider. + This makes it a call-by-call choice when setting Source3f{v} + vectors, as it is applied when dereferencing. + + ]]> + + RFC: Bernd on Source Types (3) + Semantically, AMBIENT has nothing to do with coordinate systems, + it is a qualifier just like multichannel direct passthru. + + ]]> + + RFC: Source Attenuation Clamping + Using AL_SOURCE_ATTENUATION_MIN and AL_SOURCE_ATTENUATION_MAX + to specify the clamping values for the normalized attenuation + factor (which is a function of distance) is in contradiction + to the distance based model that Creative is pushing for + (DirectSound). As driver-interall culling of source and other + processing might be based on the effective (overall, ultimate) + gain composed of amplifications and attenuations accumulated + over the entire processing, I raise the question whether a sound + designer might not want to control the effective GAIN ranges + instead of the distance attenuation itself. Samples commonly + use the entire dynamic range provided by the format, which is + mapped to the entire dynamic range of the output device. An + effective gain exceeding 1 does not make sense, an amplification + during processing might. + + ]]> + + + + + + + Managing Source Names + + &AL; provides calls to request and release Source Names handles. + Calls to control Source Execution State are also provided. + + + + Requesting a Source Name + + The application requests a number of Sources using GenSources. + + &void; GenSources + &sizei; n + &uint;* sources + + + + + + + Releasing Source Names + + The application requests deletion of a number of Sources + by DeleteSources. + + &void; DeleteSources + &sizei; n + &uint;* sources + + + + + + Validating a Source Name + + The application can verify whether a source name is valid + using the IsSource query. + + &bool; IsSource + &uint; sourceName + + + + + + + + Source Attributes + + This section lists the attributes that are set per Source, + affecting the processing of the current buffer. Some of + these attributes can also be set for buffer queue entries. + + Annotation (No Priorities) + There are no per Source priorities, and no explicit priority + handling, defined at this point. A mechanism that lets the + application express preferences in case that the implementation + provides culling and prioritization mechanisms might be added + at some later time. This topic is under discussion for GL as + well, which already has one exlicit priority API along with + internally used MRU heuristics (for resident texture memory). + + ]]> + + + + + + Source Positioning + + + SOURCE_RELATIVE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + SOURCE_RELATIVE + &bool; + FALSE, TRUE + FALSE + + + +
+ SOURCE_RELATIVE set to TRUE indicates that the values + specified by POSITION are to be interpreted relative + to the listener position. +
+ + + Annotation (Position only) + SOURCE_RELATIVE does not affect velocity or orientation + calculation. + + ]]> + +
+ + + Buffer Looping + + + Source LOOPING Attribute + + + + + + + + + &Par; + &Sig; + &Val + &Def; + + + + + LOOPING + &uint; + TURE, FALSE + FALSE + + + +
+ Description: + LOOPING is a flag that indicates that the Source will not + be in STOPPED state once it reaches the end of last buffer + in the buffer queue. Instead, the Source will immediately + promote to INITIAL and PLAYING. The default value is FALSE. + LOOPING can be changed on a Source in any execution state. + In particular, it can be changed on a PLAYING Source. +
+ + Annotation (Finite Repetition) + Finite reptition is implemented by buffer queueing. + + ]]> + + Annotation (Loop Control) + To implement a 3 stage "loop point" solution, the + application has to queue the FadeIn buffer first, + then queue the buffer it wants to loop, and set + LOOPING to TRUE once the FadeIn buffer has been + processed and unqueued. To fade from looping, the + application can queue a FadeOut buffer, then + set LOOPING to false on the PLAYING source. Alternatively, + the application can decide to not use the LOOPING + attribute at all, and just continue to queue the buffer + it wants repeated. + + ]]> + + Annotation (Rejected alternatives) + A finite loop counter was rejected because it is + ambiguous with respect to persistent (initial counter) + vs. transient (current counter). For similar reasons, + a Play-equivalent command with a (transient) loop counter + was rejected. + + ]]> +
+ + + Current Buffer + + + Source BUFFER Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + BUFFER + &uint; + any valid bufferName + &NONE; + + + +
+ Description: + Specifies the current Buffer object, making it the + head entry in the Source's queue. Using BUFFER on a + STOPPED or INITIAL Source empties the entire queue, + then appends the one Buffer specified. +
+ + For a PLAYING or PAUSED Source, using the Source command + with BUFFER is an INVALID_OPERATION. + It can be applied to INITIAL and STOPPED Sources only. + Specifying an invalid bufferName will + result in an INVALID_VALUE error while specifying an + invalid sourceName results in an INVALID_NAME error. + + + NONE, i.e. 0, is a valid buffer Name. + Source( sName, BUFFER, 0 ) is a legal way to release the + current buffer queue on an INITIAL or STOPPED Source, + whether it has just one entry (current buffer) or more. + The Source( sName, BUFFER, NONE) call still causes an + INVALID_OPERATION for any source PLAYING or PAUSED, + consequently it cannot be abused to mute or stop a source. + + + Annotation (repeated Source+BUFFER does not queue) + Using repeated Source(BUFFER) calls to queue a buffer on + an active source would imply that there is no way to + release the current buffer e.g. by setting it to 0. + On the other hand read-only queues do not allow for + releasing a buffer without releasing the entire queue. + + We can not require BUFFER state to be transient and lost + as soon as a Source is implicitely or explicitely stopped. + This contradicts queue state being part of the Source's + configuration state that is preserved through Stop() + operations and available for Play(). + + ]]> + + +
+ + + + Queue State Queries + + + BUFFERS_QUEUED Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + BUFFERS_QUEUED + &uint; + [0, any] + none + + + +
+ Query only. Query the number of buffers in the queue + of a given Source. This includes those not yet played, + the one currently playing, and the ones that have been + played already. This will return 0 if the current and + only bufferName is 0. +
+ + + + + BUFFERS_PROCESSED Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + BUFFERS_PROCESSED + &uint; + [0, any] + none + + + +
+ Query only. Query the number of buffers that have + been played by a given Source. + Indirectly, this gives the index of the buffer + currently playing. Used to determine how much + slots are needed for unqueueing them. + On an STOPPED Source, all buffers are processed. + On an INITIAL Source, no buffers are processed, + all buffers are pending. + This will return 0 if the current and + only bufferName is 0. +
+ + Annotation (per-Source vs. Buffer State) + BUFFERS_PROCESSED is only defined within the scope of a given + Source's queue. It indicates that the given number of buffer names + can be unqueued for this Source. It does not guarantee that the + buffers can safely be deleted or refilled, as they might still be + queued with other Sources. One way to keep track of this is to + store, per buffer, the Source for which a given buffer was most + recently scheduled (this will not work if Sources sharing buffers + might be paused by the application). If necessary an explicit + query for a given buffer name can be added in later revisions. + + ]]> + + Annotation (No Looping Queues) + Unqueueing requires nonzero BUFFERS_PROCESSED, + which necessitates no looping on entire queues, + unless we accept that no unqueueing is possible + from Source looping over the entire queue. + Currently not supported, as queueing is + primarily meant for streaming, which implies + unqueue-refill-requeue operations. + + ]]> + + +
+ + + Bounds on Gain + + + Source Minimal Gain + + + + &Par; + &Sig; + &Val + &Def; + + + + + MIN_GAIN + f + 0.0f, (0.0f, 1.0f] + 0.0f + + + +
+ Description: + MIN_GAIN is a scalar amplitude threshold. It indicates the minimal GAIN + that is always guaranteed for this Source. At the end of the processing + of various attenuation factors such as distance based attenuation and + Source GAIN, the effective gain calculated is compared to this value. + If the effective gain is lower than MIN_GAIN, MIN_GAIN is applied. + This happens before the Listener GAIN is applied. If a zero MIN_GAIN + is set, then the effective gain will not be corrected. +
+ + + Annotation (Effective Maximal Distance) + By setting MIN_GAIN, the application implicitely defines a + maximum distance for a given distance attenuation model and + Source GAIN. The distance at which the effective gain is MIN_GAIN + can be used as a replacement to the DirectSound3D MAX_DISTANCE parameter. + Once the effective gain has reached the MIN_GAIN value, it will + no longer decrease with increasing distance. + + ]]> + + + + + Source Maximal Gain (logarithmic) + + + + &Par; + &Sig; + &Val + &Def; + + + + + MAX_GAIN + f + 0.0f, (0.0f, 1.0f] + 1.0f + + + +
+ Description: + MAX_GAIN defines a scalar amplitude threshold. It indicates the maximal + GAIN permitted for this Source. At the end of the processing + of various attenuation factors such as distance based attenuation and + Source GAIN, the effective gain calculated is compared to this value. + If the effective gain is higher than MAX_GAIN, MAX_GAIN is applied. + This happens before the Listener GAIN is applied. If the Listener gain + times MAX_GAIN still exceeds the maximum gain the implementation can + handle, the implementation is free to clamp. If a zero MAX_GAIN + is set, then the Source is effectively muted. The implementation is free + to optimize for this situation, but no optimization is required or + recommended as setting GAIN to zero is the proper way to mute a Source. +
+ + Annotation (Un-attenuated Source) + Setting MIN_GAIN and MAX_GAIN to the GAIN value will effectively + make the Source amplitude independent of distance. The + implementation is free to optimize for this situation. However, the + recommended way to accomplish this effect is using a ROLLOFF_FACTOR + of zero. + + ]]> + + + + Annotation (Internal GAIN threshold) + The &AL; implementation is free to use an internally chosen + threshold level below which a Source is ignored for mixing. + Reasonable choices would set this threshold low enough so + that the user will not perceive a difference. Setting MIN_GAIN + for a source will override any implementation defined test. + + ]]> +
+ + + + + Distance Model Attributes + + + REFERENCE_DISTANCE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + REFERENCE_DISTANCE + &float; + [0, any] + 1.0f + + + +
+ This is used for distance attenuation calculations + based on inverse distance with rolloff. Depending + on the distance model it will also act as a distance + threshold below which gain is clamped. See the + section on distance models for details. +
+ + + + + ROLLOFF_FACTOR Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + ROLLOFF_FACTOR + &float; + [0, any] + 1.0f + + + +
+ This is used for distance attenuation calculations + based on inverse distance with rolloff. For + distances smaller than MAX_DISTANCE (and, depending + on the distance model, larger than REFERENCE_DISTANCE), + this will scale the distance attenuation over the + applicable range. See section on distance models for + details how the attenuation is computed as a function + of the distance. +
+ + In particular, ROLLOFF_FACTOR can be set to zero for + those Sources that are supposed to be exempt from + distance attenuation. The implementation is encouraged + to optimize this case, bypassing distance attenuation + calculation entirely on a per-Source basis. + + + + + MAX_DISTANCE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + MAX_DISTANCE + &float; + [0, any] + MAX_FLOAT + + + +
+ This is used for distance attenuation calculations + based on inverse distance with rolloff, if the + Inverse Clamped Distance Model is used. In this case, + distances greater than MAX_DISTANCE will + be clamped to MAX_DISTANCE. + MAX_DISTANCE based clamping is applied before MIN_GAIN clamping, + so if the effective gain at MAX_DISTANCE is larger than MIN_GAIN, + MIN_GAIN will have no effect. No culling is supported. +
+ + Annotation (No Culling) + This is a per-Source attribute supported for DS3D compatibility + only. Other API features might suffer from side effects due to + the clamping of distance (instead of e.g. clamping to an effective + gain at MAX_DISTANCE). + + ]]> + +
+ + + + + + Frequency Shift by Pitch + + + Source PITCH Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + PITCH + f + (0.0f, 2.0f] + 1.0f + + + +
+ Description: + Desired pitch shift, where 1.0 equals identity. Each reduction by 50 percent + equals a pitch shift of -12 semitones (one octave reduction). Zero is not + a legal value. +
+
+ + + + Direction and Cone + + Each Source can be directional, depending on the settings for + CONE_INNER_ANGLE and CONE_OUTER_ANGLE. There are three zones + defined: the inner cone, the outside zone, and the transitional + zone in between. + The angle-dependent gain for a directional source is constant + inside the inner cone, and changes over the transitional zone + to the value specified outside the outer cone. + Source GAIN is applied for the inner cone, + with an application selectable CONE_OUTER_GAIN factor to + define the gain in the outer zone. In the transitional + zone implementation-dependent interpolation between + GAIN and GAIN times CONE_OUTER_GAIN is applied. + + + + Annotation (Interpolation Restrictions) + The specification does not specify the exact interpolation + applied in the transitional zone, to calculate gain as a + function of angle. The implementation is free to use + linear or other interpolation, as long as the values + are monotonically decreasing from GAIN to GAIN times CONE_OUTER_GAIN. + + ]]> + + + + + Source DIRECTION Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + DIRECTION + 3fv, 3f + any except NaN + { 0.0f, 0.0f, 0.0f } + + + +
+ Description: + If DIRECTION does not equal the zero vector, the Source is directional. + The sound emission is presumed to be symmetric + around the direction vector (cylinder symmetry). Sources are not + oriented in full 3 degrees of freedom, only two angles are effectively + needed. +
+ The zero vector is default, indicating that a Source is not directional. + Specifying a non-zero vector will make the Source directional. + Specifying a zero vector for a directional Source will effectively + mark it as nondirectional. + + + RFC: Oriented Sources + Do we want an alternative AZIMUTH/ALTITUDE parametrization? + Do we need ORIENTATION later? Is this superimposable? Can we mix both? + + ]]> + + Annotation (All Sources Directional) + From the point of view of the &AL; implementation, all + Sources are directional. Certain choices for cone angles + as well as a direction vector with zero length are treated + equivalent to an omnidirectional source. The &AL; + implementation is free to flag and optimize these cases. + + ]]> + + RFC: Separate GenDirectionSource? + Is there any risk that directional sources require different + resources that have to be allocated from the beginning, and + that we can not change an omnidirectional source to a + bidirectional source at runtime? + + ]]> + + + + + Source CONE_INNER_ANGLE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + CONE_INNER_ANGLE + i,f + any except NaN + 360.0f + + + +
+ Description: + Inside angle of the sound cone, in degrees. The default of 360 means that the + inner angle covers the entire world, which is equivalent to an omnidirectional + source. +
+ RFC: inconsistent cone angles? + Is (inner <= outer) required? Do we generate an error? + Shouldn't this be a CONE_ANGLES 2f call specifying both angles at once? + + ]]> + + + + + + + Source CONE_OUTER_ANGLE Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + CONE_OUTER_ANGLE + i,f + any except NaN + 360.0f + + + +
+ Description: Outer angle of the sound cone, in degrees. The default of 360 means that the + outer angle covers the entire world. If the inner angle is also 360, then + the zone for angle-dependent attenuation is zero. +
+ + RFC: addition? + More generally, we could specify: + "If the sum of inner and outer angles is larger than 360, + CONE_OUTER_ANGLE is clamped to (360-CONE_INNER_ANGLE) and + there is no transition zone." + + ]]> + + + + Source CONE_OUTER_GAIN Attribute + + + + &Par; + &Sig; + &Val + &Def; + + + + + CONE_OUTER_GAIN + i,f + [0.0f, 1.0f] + 0.0f + + + +
+ Description: the factor with which GAIN is multiplied to + determine the effective gain outside the cone defined by + the outer angle. The effective gain applied outside the + outer cone is GAIN times CONE_OUTER_GAIN. Changing + GAIN affects all directions, i.e. the source is attenuated + in all directions, for any position of the listener. + The application has to change CONE_OUTER_GAIN as well if + a different behavior is desired. +
+ + + Annotation (GAIN calculation) + The angle-dependend gain DGAIN is multiplied with the + gain determined by the source's GAIN and any distance + attenuation as applicable. Let theta be the angle + between the source's direction vector, and the vector + connection the source and the listener. This multiplier + DGAIN is calculated as: + + OUTER = CONE_OUTER_ANGLE/2; + INNER = CONE_INNER_ANGLE/2; + if ( theta less/equal INNER ) + DGAIN = 1 + else if ( theta greater/equal OUTER ) + DGAIN = CONE_OUTER_GAIN + else + DGAIN = 1 - (1-CONE_OUTER_GAIN)*((theta-INNER)/(OUTER-INNER)) + GAIN *= DGAIN + + in the case of linear interpolation. The implementation + is free to use a different interplation across the (INNER,OUTER) + range as long as it is monotone. + + ]]> + + Annotation (CONE_OUTER_GAIN always less than GAIN) + CONE_OUTER_GAIN is not an absolute value, but (like all GAIN + parameters) a scaling factor. This avoids a possible error + case (implementations can count on effective gain outside the + outer cone being smaller than GAIN), and ensures the common + case in which changing GAIN should affect inner, transitional, + and outer zone simultaneously. + + In case that the application desires to have an outer zone + volume exceeding that of the inner cone, the mapping to + &AL; will require to rotate the Source direction to the + opposite direction (negate vector), and swapping + inner and outer angle. + + ]]> +
+
+ + + + Changing Source Attributes + + The Source specifies the position and other properties as + taken into account during sound processing. + + void Source{n}{sifd} + &uint; sourceName + &enum; paramName + &type; value + + + void Source{n}{sifd}v + &uint; sourceName + &enum; paramName + &type;* values + + + + + + Querying Source Attributes + + Source state is maintained inside the &AL; implementation, and the + current attributes can be queried. The performance of such queries is + implementation dependent, no performance guarantees are made. The + valid values for the paramName parameter are identical to the ones + for Source*. + + void GetSource{n}{sifd}{v} + &uint; sourceName + &enum; paramName + &type;* values + + + + + Old signature: T GetSource{sifd}{v}( uint id, enum param ); + + ]]> + + + + + + + Queueing Buffers with a Source + + &AL; does not specify a built-in streaming mechanism. There + is no mechanism to stream data e.g. into a Buffer object. + Instead, the API introduces a more flexible and versatile + mechanism to queue Buffers for Sources. + + + There are many ways to use this feature, with + streaming being only one of them. + + + + Streaming is replaced by queuing static + buffers. This effectively moves any multi-buffer + caching into the application and allows the + application to select how many buffers it wants + to use, whether these are re-used in cycle, + pooled, or thrown away. + + + + + Looping (over a finite number of repititions) can be + implemented by explicitely repeating buffers + in the queue. Infinite loops can (theoretically) + be accomplished by sufficiently large repetition counters. + If only a single buffer is supposed to be repeated + infinitely, using the respective Source attribute is + recommended. + + + + + Loop Points for restricted looping inside a buffer + can in many cases be replaced by splitting the + sample into several buffers, queueing the sample + fragments (including repetitions) accordingly. + + + + Buffers can be queued, unqueued after they have been + used, and either be deleted, or refilled and queued again. + Splitting large samples over several buffers maintained + in a queue has a distinct advantages over approaches that + require explicit management of samples and sample indices. + + + RFC: Unified Handling + Jonathan Blow has proposed removing the distinction between + streaming and non-streaming buffers. An existing example is + the unified for directional and omnidirectional sources, where + all sources are treated as directional. + + ]]> + + + + Queueing command + + The application can queue up one or multiple buffer names + using SourceQueueBuffers. The buffers will be queued in the sequence + in which they appear in the array. + + &void; alSourceQueueBuffers + &uint; sourceName + &sizei; numBuffers + &uint; * bufferNames + + This command is legal on a Source in any state (to allow for + streaming, queueing has to be possible on a PLAYING Source). + Queues are read-only with exception of the unqueue operation. + The Buffer Name NONE (i.e. 0) can be queued. + + + Annotation (BUFFER vs. SourceQueueBuffers) + A Sourcei( sname, BUFFER, bname ) command is an immediate + command, and executed immediately. It effectively unqueues + all buffers, and then adds the specified buffer to the + then empty queue as its single entry. Consequently, this + call is only legal if SourceUnqueueBuffers is legal. + In particular, the Source has to be STOPPED or INITIAL. + The application is still obliged to delete all + buffers as were contained in the queue. + Sourcei( sname, BUFFER, NONE ) is a legal command, + effectively wiping the queue without specifying an + actually playable buffer. + + ]]> + + + Annotation (Buffer Repetition) + To accomplish a finite number of repetitions of a buffer name multiple times, + the buffer has to be queued multiple times. If the need occurs, the + API could be extended by SourceQueueBuffer( sname, bname, repetitions ) + call for brevity. + + ]]> + + RFC: Duration of bName==0? + The buffer is considered empty, it should have zero length, + thus zero duration for consistency. If an application wants to + schedule a pause, specifying duration for a gain==0 queue entry + might be a cleaner solution. + + ]]> + + + Annotation (Backwards Compatiblity) + Sourcei( sname, BUFFER, bname ) has been rejected as + a queueing command, as it would make semantics dependent on + source state (queueing if PLAYING, immediate else). + The command is not legal on a PLAYING or PAUSED Source. + + ]]> + + Annotation (No BUFFER_QUEUE) + Duplication of one entry point is preferable to + duplicating token enums, and tokens do not express + commands, but specify the attribute/state affected. + From the same reason, there is no BUFFER_UNQUEUE + token-as-command. + + ]]> + + + + + Unqueueing command + + Once a queue entry for a buffer has been appended to a queue + and is pending processing, it should not be changed. + Removal of a given queue entry is not possible unless + either the Source is STOPPED (in which case then entire queue + is considered processed), or if the queue entry has already + been processed (PLAYING or PAUSED Source). + + + The Unqueue command removes a number of buffers entries that + have finished processing, in the order of appearance, from + the queue. The operation will fail if more buffers are + requested than available, leaving the destination arguments + unchanged. An INVALID_VALUE error will be thrown. + If no error, the destination argument will have been updated + accordingly. + + void SourceUnqueueBuffers + &uint; sourceName + &sizei; numEntries + &uint;* bufferNames + + + + Annotation (Unqueueing shared buffers) + If a buffer is queued with more than one source, it might have + been processed for some not all of them. With the current + interface, the application is forced to maintain its own list + of consumers (Sources) for a buffer it wishes to unqueue. + For groups of Sources that are never individually PAUSED + nor STOPPED, the application can save the MRU Source for + which the buffer was scheduled last. + + ]]> + + Annotation (Looping a Queue vs. Unqueue): + If a Source is playing repeatedly, it will traverse + the entire Queue repeatedly. Consequently, no buffer + in the queue can be considered processed until + there is no further repetition scheduled. + + ]]> + + Annotation (No Name based access) + No interface is provided to access a queue entry by name, + due to ambiguity (same buffer name scheduled several times + in a sequence). + + ]]> + + Annotation (No Index based access) + No interface is provided for random access to a queue entry + by index. + + ]]> + + + + + + More Annotation on Queueing + + Annotation (No Queue Copying) + The current queue of a source could be copied to another source, + as repetition and traversal parameters are stored unless the + queue entry is unqueued, or the queue is replaced using + AL_BUFFER. Copying a queue is a special case of + copying Source state in one sense, and a special case of + a synching problem in another. Due to these unresolved issues + no such command is included in the current specification. + To share queues, the application can keep buffer names + and the selected attributes that define the queue entries + in an array or other lookup table. + + ]]> + + Annotation (No Explicit QueueClear) + Sourcei( sname, BUFFER, NONE ) serves the + same purpose. The operation is also redundant + with respect to Unqueue for a STOPPED Source. + + ]]> + + Annotation (Queueing vs. AppendData): + Buffer queueing does not solve the synchronization and timing + issues raised by possible underflow, as these are inherent + to application-driven (pushed) streaming. However, it turns + an internal AL error condition (offset exceeds valid data) + into an audible artifact (Source stops). + Its main advantage is that it allows the application coder + to operate at a scale of her own choice, selecting the + number and size of buffers used for caching the stream, + and to schedule buffer refill and queueing according to + preferences and constraints. Queueing effectively moves + all problems related to replacing or appending Buffer data + to the scale of entire arrays istead of single samples and + indices. + + ]]> + + Annotation (Multiple Sources on a stream) + Queueing allows for the application to determine how much of + a backlog of the data stream is preserved. The application can + keep buffers, and queue them with other Sources after they have + been used already by the original Source. Unlike the mechanism + for appending data to a buffer, the backlog is visible to the + application and under its control, and no synchronization of + Sources using the stream is required. + + ]]> + + + + Annotation (Loop Points and Compressed Data) + For compressed data, uncompression by the application might be + impossible or undesireable. In consequence, splitting the sample + into several buffers is not possible without explicit support + by the API. Buffer-Buffer operations will be added as needed, + for the time being applications should not try to use compressed + samples if more than full looping is required. + + ]]> + + + + Annotation (No Explicit Queue Objects) + Explicit Queue objects have been considered and rejected, + as they introduce another producer-consumer dependency with + another level of indirection. Further, e.g. QUEUE would + also require deprecating BUFFER (breaking backwards + compatibility) as an alSource argument, or would introduce + a confusing set of precedence and overide rules if both + are used in sequence. However, in the absence of explicit + queue objects the application will be forced to keep track + where buffers have been queued in case it intends to + unqueue them for refill or deletion. If several sources + use the same buffers (e.g. for synchronous or + asynchronous streaming) the buffer will have to be + unqueued from each single one. + + ]]> + + + Annotation (Queue no Display List) + An interface resembling &OGL; display-lists has been + considered and rejected. The problem with this approach + is that not only commands would have to be prohibited + (similarly, not all GL calls are legal within a display + list), but also parameters (enumerations). + + In particular, only a small set of operations is meant + to be legal for a queue at this point, and appending + to a queue has to be possible at any time. + Within a hypothetical AL display list, only relative + timing/conditionals are allowed as arguments. This + might necessitate to have multiple forms for deferred + commands, or to not allow for absolute timing. + + Example: + + // lock this queue for overwriting/appending + alBeginQueue( qname, APPEND | REPLACE ); + + // queue a buffer in sequence, with parameters + // boolean: never skip? never bail? + alQueue( AL_BUFFER, bid, loopdir, repetitions ); + ... + + // end lock. + // Existing queue content will be replaced + // or appended at this point. + alEndQueue(); + + + ]]> + + + + Queue Then Delete + + + create source + queue buffer1 + queue buffer2 + queue buffer3 + play + request deletion of buffer1,2,3 + + + + ]]> + + + Queue and Refill with Dual Buffering + + + create source + fill buffer1 + queue buffer1 + play + fill buffer2 + queue buffer2 + check for unused buffers + unqueue buffer1 + fill buffer1 + queue buffer1 + ... + + + + ]]> + + + Queue for Loop Points + + + create source + read sample data + split sample data into pre/main/post + queue pre + queue main with repetitions + queue post + play + set repetitions to 0 on main when needed + wait till post has been played + + + + ]]> + + +]]> + + + Attributes Specific to Queueing + +
+ Buffer Traversal + + The Buffer traversal attribute specifies the direction + in which the sample in the buffer is supposed to be + processed. To account for the 3 basic modes of traversal that + can be implemented in software and hardware, the following + tokens are defined: + + LOOP_DIRECTION /* traversal direction */ + + FORWARD /* linear forward (increment) */ + BACKWARD /* linear backward (decrement) */ + FORWARD_AND_BACK /* RESERVED: ping-pong-looping */ + + + The first and the next two tokens are legal with a buffer queue command. + They are not legal for a Source command, in any possible + Source state. The last token is reserved, but not yet legal to use. + + + + Annotation (Ping-Pong postponed) + Definition and implementation of ping-pong looping + has been postponed. Applications can fake it at doubling + memory expense by reverse copying the buffer (2nd buffer queued + or in a double size single buffer). If there is hardware support + for this feature, AL will have to support it eventually. A boolean + flag is not acceptable because of this possibility. + + ]]> + +]]> + + + + + + + + + + + Managing Source Execution + + The execution state of a source can be queried. &AL; provides + a set of functions that initiate state transitions causing + Sources to start and stop execution. + + + TBA: State Transition Diagram. + + + Annotation/ Source Config/Exec State + Sources have configuration state and execution state. + Configuration state is directly set by the application using + AL commands, starting with the INITIAL configuration. Execution + state (e.g. the offset to the current sample) is not under direct + application control and not exposed. + + ]]> + + + Source State Query + + The application can query the current state of any Source + using GetSource with the parameter Name SOURCE_STATE. + Each Source can be in one of four possible execution states: + INITIAL, PLAYING, PAUSED, STOPPED. Sources that are either + PLAYING or PAUSED are considered active. Sources that are + STOPPED or INITIAL are considered inactive. Only PLAYING + Sources are included in the processing. The implementation + is free to skip those processing stages for Sources that + have no effect on the output (e.g. mixing for a Source + muted by zero GAIN, but not sample offset increments). + Depending on the current state of a Source certain (e.g. repeated) + state transition commands are legal NOPs: they will be ignored, + no error is generated. + + + + + State Transition Commands + + The default state of any Source is INITIAL. From this state + it can be propagated to any other state by appropriate use + of the commands below. There are no irreversible state + transitions. + + void SourcePlay + &uint; sName + + + void SourcePause + &uint; sName + + + void SourceStop + &uint; sName + + + void SourceRewind + &uint; sName + + + + + + The functions are also available as a vector variant, + which guarantees synchronized operation on a set of + Sources. + + void SourcePlayv + &sizei; n + &uint;* sNames + + + void SourcePausev + &sizei; n + &uint;* sNames + + + void SourceStopv + &sizei; n + &uint;* sNames + + + + void SourceRewindv + &sizei; n + &uint;* sNames + + + + + The following state/command/state transitions are defined: + + + + Play() applied to an INITIAL Source will promote the Source + to PLAYING, thus the data found in the Buffer will be fed + into the processing, starting at the beginning. + Play() applied to a PLAYING Source will restart the Source + from the beginning. It will not affect the configuration, + and will leave the Source in PLAYING state, but reset the + sampling offset to the beginning. + Play() applied to a PAUSED Source will + resume processing using the Source state + as preserved at the Pause() operation. + Play() applied to a STOPPED Source will propagate it + to INITIAL then to PLAYING immediately. + + + + + Pause() applied to an INITIAL Source is a legal NOP. + Pause() applied to a PLAYING Source will change its state to + PAUSED. The Source is exempt from processing, its current + state is preserved. + Pause() applied to a PAUSED Source is a legal NOP. + Pause() applied to a STOPPED Source is a legal NOP. + + + + + Stop() applied to an INITIAL Source is a legal NOP. + Stop() applied to a PLAYING Source will change its state to + STOPPED. The Source is exempt from processing, its current + state is preserved. + Stop() applied to a PAUSED Source will change its state + to STOPPED, with the same consequences as on a PLAYING + Source. + Stop() applied to a STOPPED Source is a legal NOP. + + + + + Rewind() applied to an INITIAL Source is a legal NOP. + Rewind() applied to a PLAYING Source will change its state to + STOPPED then INITIAL. The Source is exempt from processing: + its current state is preserved, with the exception of the + sampling offset, which is reset to the beginning. + Rewind() applied to a PAUSED Source will change its state + to INITIAL, with the same consequences as on a PLAYING + Source. + Rewind() applied to a STOPPED Source promotes the Source + to INITIAL, resetting the sampling offset to the beginning. + + + + + + Annotation (SourceNext) + The specification does not provide any means to + immediately skip from the current Buffer to the + next in the queue. A conditional stop (following + the next complete traversal) is available. + If necessary an additonal entry point could be + provided in future revisions. + + ]]> + + Annotation (Rewind() optional) + The INITIAL state is not identical to the STOPPED state. + Applications that want to verify whether a Source + has indeed been PLAYING before becoming STOPPED can + use Rewind() to reset the Source state to INITIAL. + This is an optional operation that can safely be + omitted by application without this constraint. + Applications that want to guard against Play() on + a Source that is INITIAL can query the Source state + first. + + ]]> + + Annotation (Play() on a PLAYING Source) + Repeated Play() commands applied a PLAYING Source are + interpreted as an (atomic) sequence to stop and restart a + Source. This can be used by applications that want to restart + a sound but do not care whether the Source has finished or not, + and do not want an audible pause. One example is the DOOM + chaingun repeatedly abbreviating the pistol sound. To guard + against redundant Play() commands, an application can query + the current state before executing Play(). If the application + coder wants to be sure that the Source will play the buffer + again, she can either increment PLAY_COUNT, or queue the buffer. + + ]]> + + Annotation (redundant commands) + The simple variant (e.g. SourcePlay) is redundant to + the vector variant (e.g. SourcePlayv). However, these + calls will be used frequently, and the simple variant + is provided for convenience. However, &AL; does not + enable applications to use literals as source names. + + ]]> + + + + + Resetting Configuration + + The INITIAL state is not necessarily identical to the + default state in which Source is created. INITIAL merely + indicates that the Source can be executed using the + SourcePlay command. A STOPPED or INITIAL Source can + be reset into the default configuration by using a + sequence Source commands as necessary. As the application + has to specify all relevant state anyway to create a + useful Source configuration, no reset command is provided. + + + + RFC: remove INITIAL + INITIAL is identical to STOPPED. The only additional information + conveyed is that INITIAL indicates a source has never been played. + Once a Source is STOPPED, it is not possible by state query alone + to decide whether it has played again. If Sources are used only + once, an application can use INITIAL to verify a Source has been + played. + The problem that I have with this is that if we acknowledge that + the application might need to verify a Source has played once, + why force the application to throw away Sources to accomplish + this? An explicit state PLAYABLE replacing INITIAL and its + inauspicious connotations (default state) and a state transition + function Rewind() that makes a STOPPED Source PLAYABLE again would + be one possibility to address this need. The obvious drawback is + that it breaks backwards compatibility. + + ]]> + + + RFC: state issues + A Source is active if it is PAUSED or PLAYING. + + A Source that is STOPPED preserves configuration state, + including buffer/queue information. + + Only a Source that is Reset() to INITIAL looses all + buffer and queue information. In this case, the INITIAL + + Sources will be stopped implicitely when reaching the + end of a non-repeating (non-looping) buffer traversal. + Sources can be stopped explicitely by the application + with either Stop() or Reset(). + + Stop() propagates + the source to STOPPED preserving its configuration state, + setting its execution state to the same as if it reached + the end of execution. + + + ]]> + + + Annotation (illegal NOPs) + In the current specification there are no illegal NOPs. + In other words, no sequence of commands affecting the + execution state will generate an INVALID_OPERATION error. + + ]]> + + + RFC/bk000504: + No UNDEFINED state. Always valid state. I.e. we have a default Buffer + that is used for sources where the application doesn't specify, + and what's in it? Default gain is zero? We need to specify + INITIAL. + + + RFC/bk000504: + Potential ambiguity: how to we distinguish STOPPED as + requested by the application from INACTIVE for + non-looping sounds once the buffer has been iterated? + Related: handling of Sources using an underflowing + streaming buffer? IMO not recommended, make this + undefined on error. + + + + RFC/bk000504: + Possible redundancy: the only reason for STOP seems to + be resetting the play positions. Redundant if we + ever manipulate offsets directly (rewind/set). + + + RFC/bk000504: + Possible redundancy: + If we ever want to support explicit setting of the start + position/offset into Buffer, START is equivalent to Set(0). + Also see LOOP (implies has to be STOPPED). Fade-Out and + Fade-In control - always manually? + + + ]]> + + + + + + diff --git a/openal/docs/chp-state.sgml b/openal/docs/chp-state.sgml new file mode 100644 index 000000000..8175a3631 --- /dev/null +++ b/openal/docs/chp-state.sgml @@ -0,0 +1,730 @@ + + + State and State Requests + + The majority of &AL; state is associated with individual &AL; objects, + and has to be set and queried referencing the objects. However, some + state - e.g. processing errors - is + defined context specific. &AL; has global state that affects all + objects and processing equally. This state is set using a variety + of functions, and + can be queried using query functions. The majority of queries + has to use the interface described in "Simple Queries". + + + + + Querying &AL; State + + + + Simple Queries + + Like &OGL;, &AL; uses a simplified interface for querying global + state. The following functions accept a set of enumerations. + + void GetBooleanv + &enum; paramName + &bool;* dest + + + + void GetIntegerv + &enum; paramName + ∫* dest + + + + void GetFloatv + &enum; paramName + &float;* dest + + + + void GetDoublev + &enum; paramName + &double;* dest + + Legal values are e.g. DOPPLER_FACTOR, DOPPLER_VELOCITY, DISTANCE_MODEL. + + + NULL destinations are quietly ignored. INVALID_ENUM is the + response to errors in specifying paramName. The amount of memory + required in the destination depends on the actual state requested. + Usually, state variables are returned in only one or some of the + formats above. + + + To query state controlled by Enable/Disable there is an additional + IsEnabled function defined (see "Controlling &AL; Execution"). + + + + + + Data Conversions + + If a Get command is issued that returns value types different from + the type of the value being obtained, a type converswion is + performed. If GetBooleanv is called, a floating-point or integer + value converts to FALSE if and only if it is zero (otherwise + it converts to TRUE). If GetIntegerv is called, a boolean value + is interpreted as either 1 or 0, and a floating-point value is + rounded to the nearest integer. If GetFloatv is called, a boolean + value is interpreted as either 1.0 or 0.0, an integer is + coerced to floating point, and a double-presicion foating-point + value is converted to single precision. Analogous conversions are + carried out in the case of GetDoublev. If a value is so large + in magnitude that it cannot be represented with the requested + type, then the nearest value is representable using the requested + type is returned. + + Annotation (Query of Modes) + Modes (e.g. the current distance model) can be queried + using the respective tokens. The recommended query + command is GetIntegerv. + + ]]> + + + + + String Queries + + The application can retrieve state information global to the current + &AL; Context. GetString will return a pointer to a constant string. + Valid values for param are VERSION, RENDERER, VENDOR, and EXTENSIONS, + as well as the error codes defined by &AL;. The application can + use GetString to retrieve a string for an error code. + + const &ubyte;* GetString + &enum; paramName + + + + + + + + Time and Frequency + + By default, &AL; uses seconds and Hertz as units for + time and frequency, respectively. + A float or integral value of one + for a variable that specifies quantities like duration, + latency, delay, or any other parameter measured as time, + specifies 1 second. + For frequency, the basic unit is 1/second, or Hertz. + In other words, sample frequencies and frequency + cut-offs or filter parameters specifying frequencies + are expressed in units of Hertz. + + + RFC: Query and Factor? + Will time be an &AL; state that can be queried and scaled? + &AL; usually (always) implements a real-time + process with the constraint that it has to be + synchronized with the time as experienced by the user. + Do the units used with respect to time and frequency have + a fixed meaning? + + ]]> + + RFC: Setting Time/Long + Given a frequency range from a few Hz to 50kHz or more, + we need a temporal resolution of 20 microseconds or less. + For simplicity that means we either resolve Milliseconds + and loose precision, or we resolve microseconds. + Applications might run hours or days, which is 10E5 seconds + or more. If we cover 12 orders of magnitude (10E6 to 10E-6) + 32bit unsigned integer will not suffice. Do we introduce + a 64 signed integer for the purpose of specifying time + over a duration of several days at microseconds resolution, + or do we use two 32bit integers, and how do we split them? + + ]]> + + RFC: Duration Query + + The application might want to cull Sources based on + how many milliseconds are left for their current buffer + or queue (either to stop those that will stop soon + anyway, or to stop those that will take too long, + depending). + + + We need to divorce sample (memory) count from duration, + because of compression and differences between + internal and external sample format. + + + Duration can be queried in microsecond resolution in + case we want to account for O(10Khz) sampling + frequencies properly, or milliseconds if we + do not anticipate the need to go beyond typical + operating system time resolution. + + + We need query as double, float, and possibly + long (as of now an undefined data type). + We might need an INVALID_RANGE error on the getter, + especially if large reptition counters can be set. + For paused source, the remainder will be the same + as for playing sources. The application can query + the Source State to find out the additional + information. INFINITE is not needed, + no is UNKNOWN as we operate on known + queues. + + ]]> + + Annotation (Buffer vs. Queue Duration) + Sourcel( sName , REMAINDER, &rem ) queries the remainder + for the current buffer (zero if the Source is STOPPED, + duration of the first buffer if the source is INITIAL). + Sourcel( sName, REMAINDER_QUEUE, &rem ) queries the remainder + of the entire queue. + A STOPPED Source has remainder==0. + An INITIAL Source has full remainder. + + ]]> + + + Annotation (DURATION vs. REMAINDER) + DURATION is a buffer attribute independent of + execution state. REMAINDER is a Source attribute + that encapsulates part of the execution state. + Sources and Buffers should not share these attributes: + there is no Buffer REMAINDER and no Source DURATION. + + ]]> + ]]> + + + + + + + Space and Distance + + &AL; does not define the units of measurement for distances. + The application is free to use meters, inches, or parsecs. + &AL; provides means for simulating the natural attenuation + of sound according to distance, and to exagerate or reduce + this effect. However, the resulting effects do not depend on + the distance unit used by the application to express source + and listener coordinates. &AL; calculations are scale + invariant. + + + The specification assumes Euclidean calculation of + distances, and mandates that if two Sources are + sorted with respect to the Euclidean metric, the + distance calculation used by the implementation has + to preserve that order. + + + Annotation (No DistanceFactor) + &AL; does not provide a global, per Context DISTANCE_FACTOR, + as all calculations are scale invariant. + + ]]> + + Annotation (Distance Calculations) + The specification does not enforce that distances + are calculated using the euclidean norm, to permit + using computationally cheaper approximations. + Implementations that opt to use approximations + might cause audible artifacts. The specification does + not enforce any upper limits on distance calculation + errors yet. + + ]]> + + RFC: Limiting Errors + Do we limit permissible errors on distance or gain + calculations? How much quality + and accuracy do we expect from conformant implementations? + + ]]> + + + Annotation (DS3D DistanceFactor) + The DS3D documentation explicitely states that the default + unit is 1 meter. &AL; does not specify any units. + &AL; calculations are scale invariant. The main purpose + of the DS3D DistanceFactor (modifying Doppler Shift + by scaling velocity but not reference velocity) is + accomplished using DOPPLER_VELOCITY in &AL;. &AL; + does not have an equivalent to A3D's SetUnitsPerMeter + either. + + + ]]> + + + + + + + Attenuation By Distance + + Samples usually use the entire dynamic range of the + chosen format/encoding, independent of their real world + intensity. In other words, a jet engine and a clockwork + both will have samples with full amplitude. The application + will then have to adjust Source GAIN accordingly to account + for relative differences. + + + Source GAIN is then attenuated by distance. + The effective attenuation of a Source depends on many + factors, among which distance attenuation and source + and Listener GAIN are only some of the contributing + factors. Even if the source and Listener GAIN exceed 1.0 + (amplification beyond the guaranteed dynamic range), + distance and other attenuation might ultimately limit + the overall GAIN to a value below 1.0. + + + &AL; currently supports three modes of operation + with respect to distance attenuation. It supports + two distance-dependent attenuation models, including one + that is similar to the IASIG I3DL2 (and DS3D) model. + The application chooses one of these two models (or + chooses to disable distance-dependent attenuation) + on a per-context basis. + + void DistanceModel + &enum; modelName + + Legal arguments are NONE, INVERSE_DISTANCE, and + INVERSE_DISTANCE_CLAMPED. NONE bypasses all distance + attenuation calculation for all Sources. The implementation + is expected to optimize this situation. INVERSE_DISTANCE_CLAMPED + is the DS3D model, with REFERENCE_DISTANCE indicating both the + reference distance and the distance below which gain will + be clamped. INVERSE_DISTANCE is equivalent to the DS3D model + with the exception that REFERENCE_DISTANCE does not imply any + clamping. The &AL; implementation is still free to apply + any range clamping as necessary. The current distance model + chosen can be queried using GetIntegerv and DISTANCE_MODEL. + + + Annotation (Inverse Square Law) + The "inverse square law" used in physics applies to sound + intensity (energy), which is proportional to the square + of linear gain (amplitude). Thus the inverse distance model + describes a physically correct inverse square behavior + if ROLLOFF_FACTOR is set to 1.0. + + ]]> + + Annotation (Enable/Disable Attenuation) + As ROLLOFF_FACTOR is a per-Source attribute, setting it to zero + can not be used to globally enable or disable distance + attenuation, which (e.g. when using tables) can be resource + intensive. Using Enable/Disable/IsEnabled with a DISTANCE_ATTENUATION + token is redundant with respect to the possibility that support + for different distance models might be desired at a later time. + + ]]> + + + + Inverse Distance Rolloff Model + + The following formula describes the distance attenutation + defined by the Rolloff Attenutation Model, as logarithmic + calculation. + + + G_dB = GAIN - 20*log10(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE ); + G_dB = min(G_dB,MAX_GAIN); + G_dB = max(G_dB,MIN_GAIN); + + + The REFERENCE_DISTANCE parameter used here is a per-Source attribute + that can be set and queried using the REFERENCE_DISTANCE token. + REFERENCE_DISTANCE is the distance at which the Listener will + experience GAIN (unless the implementation had to clamp effective + GAIN to the available dynamic range). + ROLLOFF_FACTOR is per-Source parameter the application can use + to increase or decrease the range of a source by decreasing + or increasing the attenuation, respectively. The default value + is 1. The implementation is free to optimize for a + ROLLOFF_FACTOR value of 0, which indicates that the application + does not wish any distance attenuation on the respective Source. + + + Annotation (Linear Calculation) + The logarithmic formula above is equivalent to + + G = gain_linear / ( 1 + ROLLOFF_FACTOR*((dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE) ); + G = min(G,max_gain_linear); + G = max(G,min_gain_linear); + + with linear gains calculated from the logarithmic GAIN, + MIN_GAIN, MAX_GAIN accordingly. + By means of explanation: linear GAIN is applied to the sample, which describes + an amplitude ultimately (DAC) converted into voltage. The actual power of the + signal is proportional to the square of the amplitude (voltage). Logarithmic + measurement is done by comparing the actual power with a reference value, + i.e. the power (e.g in Watt) at the reference distance. The original Bel unit + of measure (named after Alexander Graham Bell) was defined to account for the + logarithmic response of the human ear: our subjective impression of "loudness" + is not linear in the power of the acoustic signal. For practical purposes (range + of volumes the human ear can handle) the deciBel (dB) is a better unit: + + dB = 10 * log( P/P0 ) = 10 * log( sqr(A/A0 ) = 20 * log( A/A0 ) + + Common power/amplitude ratios and attenuations per distance are: + + Logarithmic Scale and Gain + + + + Distance + Attenuation + Power Ratio + Amplitude Ratio + + + + + REF + 0dB + 1:1 + 1:1 + + + 2*REF + -6dB + 1:4 + 1:2 + + + 4*REF + -12dB + 1:16 + 1:4 + + + 8*REF + -18dB + 1:64 + 1:8 + + + 0.5*REF + 6dB + 2:1 + 4:1 + + + 0.25*REF + 12dB + 4:1 + 16:1 + + + + +
+ The logarithmic gain will drop from zero (linear gain 1) to negative infinity + (approaching linear gain 0). A linear gain of zero can not be represented + logarithmically. Any doubling of the reference distance will add another + -6dB (i.e. 6dB of attenuation). This approximates an inverse square law falloff + of signal power with distance, as long as the distance exceeds the reference + distance. +
+ ]]> + + Annotation (Rolloff quantization) + Implementations that use lookup tables to speed up + distance attenuation calculation may opt to map + ROLLOFF_FACTOR to a limited set of internally used + values, to minimize expense of per-Source calculations + and setup/memory costs. + + ]]> + + Annotation (Gain Clamping) + In the absence of user MIN_GAIN and MAX_GAIN selections, + clamping is implied by implementation constraints, and + clamping behavior might change. + The &AL; implementation should not clamp intermediate + values of effective gain to unit range. + Any clamping, if necessary, should be applied at the latest + possible stage. In other words, GAIN>1 is perfectly + valid as the implementation is free to clamp the value as + needed for maximum mixing accuracy and to account for the + actual dynamic range of the output device. + + ]]> + + + Annotation (Extended Dynamic Range) + For applications that + change GAIN but do not want to adjust ROLLOFF_FACTOR + and REFERENCE_DISTANCE to account for different ranges, + the separation in this distance model might allow for + more intuitive adjustments: + If we put a damper on the jet engine by lowering GAIN, + we still want the listener to perceive the full volume, + but now at a closer distance, without changing the + reference distance. + + ]]> +
+ + + Inverse Distance Clamped Model + + This is essentially the Inverse Distance model, + extended to guarantee that for distances below + REFERENCE_DISTANCE, gain is clamped. This mode + is equivalent to the IASIG I3DL2 (and DS3D) distance + model. + + dist = max(dist,REFERENCE_DISTANCE); + dist = min(dist,MAX_DISTANCE); + G_dB = GAIN - 20*log10(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE ) + G_dB = min(G_dB,MAX_GAIN); + G_dB = max(G_dB,MIN_GAIN); + + + + + Annotation (DS3D MIN_DISTANCE) + The DS3D attenuation model is extended by an explicit + clamping mechanism. REFERENCE_DISTANCE is equivalent + to DS3D MIN_DISTANCE if the INVERSE_DISTANCE_CLAMPED + mode is used. + + ]]> + + Annotation (High Frequency Rolloff) + To simulate different atmospheric conditions, a frequency + dependent attenuation is used in A3D and EAX. + At this time &AL; does not have a mechanism to specify + lowpass filtering parameterized by distance. + + ]]> + +
+ + + + Evaluation of Gain/Attenuation Related State + + While amplification/attenuation commute (mulplication of + scaling factors), clamping operations do not. The order + in which various gain related operations are applied is: + Distance attenuation is calculated first, including + minimum (REFERENCE_DISTANCE) and maximum (MAX_DISTANCE) + thresholds. If the Source is directional (CONE_INNER_ANGLE + less than CONE_OUTER_ANGLE), an angle-dependent attenuation + is calculated depending on CONE_OUTER_GAIN, and multiplied + with the distance dependent attenuation. + The resulting attenuation factor for the given angle and + distance between Listener and Source is multiplied + with Source GAIN. The effective GAIN computed this way + is compared against MIN_GAIN and MAX_GAIN thresholds. + The result is guaranteed to be clamped to [MIN_GAIN, MAX_GAIN], + and subsequently multiplied by Listener GAIN which serves + as an overall volume control. The implementation is free + to clamp Listener GAIN if necessary due to hardware or + implementation constraints. + + + + + + + No Culling By Distance + + With the DS3D compatible Inverse Clamped Distance Model, + &AL; provides a per-Source MAX_DISTANCE attribute + that can be used to define a distance beyond which the Source will + not be further attenuated by distance. + The DS3D distance attenuation model and its clamping of volume + is also extended by a mechanism to cull (mute) sources from proccessing, + based on distance. However, &AL; does not + support culling a Source from processing based on a distance + threshold. + + + At this time &AL; is not meant to support culling at all. Culling + based on distance, or bounding volumes, or other criteria, is best + left to the application. For example, the application might + employ sophisticated techniques to determine whether sources + are audible that are beyond the scope of &AL;. In particular, + rule based culling inevitably introduces acoustic artifacts. + E.g. if the Listener-Source distance is nearly equal to the + culling threshold distance, but varies above and below, there + will be popping artifacts in the absence of hysteresis. + + + Annotation (No MAX_DISTANCE plus MUTE) + &AL; does support the AUDIBLE mode with MAX_DISTANCE (clamping), + but does not support culling. Applications that employ this + DS3D feature will have to perform their own distance calculation + and mute the source (Source GAIN equals zero) as desired. + + ]]> + + RFC: DS3D-like Extension + For ease of portability, should we define an Extension that + provides MAX_DISTANCE for MUTE mode? + + ]]> + + + + + + NO Sound Propagation Speed + + &AL; implementations can choose to model sound propagation with + limited speed for certain effects, e.g. early reflections. + In addition, the Doppler Effect is defined with respect to the + speed of sound in the predominant medium. The application can + set the speed of sound as a scalar value. The speed is defined + with respect to the scaled unit. If D I S T A N C E _ S C A L E is changed, + this will affect both the distance and the propagation speed, + leaving the propagation time unaffected. + + void PropagationSpeed + &float; propSpeed + + + + A negative scale will result in an INVALID_VALUE error, the + command is then ignored. The default value is 1. The current + setting can be queried using GetFloatv and PROPAGATION_SPEED. + + + ]]> + + + Velocity Dependent Doppler Effect + + The Doppler Effect depends on the velocities of Source and + Listener relative to the medium, and the propagation speed + of sound in that medium. The application might want to + emphasize or de-emphasize the Doppler Effect as physically + accurate calculation might not give the desired results. The + amount of frequency shift (pitch change) is proportional + to the speed of listener and source along their line of + sight. The application can increase or decrease that + frequency shift by specifying the scaling factor &AL; + should apply to the result of the calculation. + + + The Doppler Effect as implemented by &AL; is described + by the formula below. Effects of the medium (air, water) + moving with respect to listener and source are ignored. + DOPPLER_VELOCITY is the propagation speed relative to + which the Source velocities are interpreted. + + VD: DOPPLER_VELOCITY + DF: DOPPLER_FACTOR + vl: Listener velocity (scalar, projected on source-listener vector) + vs: Source velocity (scalar, projected on source-listener vector) + f: Frequency of sample + f': effective Doppler shifted frequency + + f' = DF * f * (VD-vl)/(VD+vs) + + vl<0, vs>0 : source and listener approaching each other + vl>0, vs<0 : source and listener moving away from each other + + The implementation has to clamp the projected Listener + velocity vl, if abs(vl) is greater or equal to VD. It similarly has to + clamp the projected Source velocity vs if abs(vs) is greater or equal + to VD. + + + There are two API calls global to the current context that provide + control of the two related parameters. DOPPLER_FACTOR is a simple + scaling to exaggerate or deemphasize the Doppler (pitch) shift + resulting from the calculation. + + void DopplerFactor + &float; dopplerFactor + + A negative value will result in an INVALID_VALUE error, the + command is then ignored. The default value is 1. The current + setting can be queried using GetFloatv and DOPPLER_FACTOR. + The implementation is free to optimize the case of DOPPLER_FACTOR + being set to zero, as this effectively disables the effect. + + + Annotation (No Enable) + There is currently no mechanism to switch on/off Doppler + calculation using e.g. a DOPPLER_SHIFT token and Enable/Disable. + For the time being, DopplerFactor(0) may be used to signal + to the implementation that no Doppler Effect calculation is + required. + + ]]> + + + DOPPLER_VELOCITY allows the application to change the + reference (propagation) velocity used in the Doppler Effect + calculation. This permits the application to use a velocity + scale appropriate to its purposes. + + void DopplerVelocity + &float; dopplerVelocity + + A negative or zero value will result in an INVALID_VALUE error, and the + command is ignored. The default value is 1. + The current setting can be queried using GetFloatv and DOPPLER_VELOCITY. + + + Annotation (No Sideeffects on Delay) + To permit independent control of Doppler Effect as opposed + to other, sound wave propagation related effects (delays, + echos, reverberation), DOPPLER_VELOCITY is not taken into + account for any other calculation than Doppler Shift. + + ]]> + + Annotation (SetUnitsPerMeter) + DOPPLER_VELOCITY accomplishes the purposes of DS3D + scaling parameters in a straightforward way, without + introducing the undesirable connotations of real world + units. + + ]]> + + +
+ diff --git a/openal/docs/ent-examples.sgml b/openal/docs/ent-examples.sgml new file mode 100644 index 000000000..24957738c --- /dev/null +++ b/openal/docs/ent-examples.sgml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/openal/docs/ent-extensions.sgml b/openal/docs/ent-extensions.sgml new file mode 100644 index 000000000..c4acd939a --- /dev/null +++ b/openal/docs/ent-extensions.sgml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/openal/docs/ent-marks-annotated.sgml b/openal/docs/ent-marks-annotated.sgml new file mode 100644 index 000000000..2cbe4d358 --- /dev/null +++ b/openal/docs/ent-marks-annotated.sgml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openal/docs/ent-marks-full.sgml b/openal/docs/ent-marks-full.sgml new file mode 100644 index 000000000..eb5515ac9 --- /dev/null +++ b/openal/docs/ent-marks-full.sgml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openal/docs/ent-marks-reference.sgml b/openal/docs/ent-marks-reference.sgml new file mode 100644 index 000000000..bb34d5e5d --- /dev/null +++ b/openal/docs/ent-marks-reference.sgml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openal/docs/ent-marks-specification.sgml b/openal/docs/ent-marks-specification.sgml new file mode 100644 index 000000000..f68660ae9 --- /dev/null +++ b/openal/docs/ent-marks-specification.sgml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openal/docs/ent-names.sgml b/openal/docs/ent-names.sgml new file mode 100644 index 000000000..9da1b979c --- /dev/null +++ b/openal/docs/ent-names.sgml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openal/docs/index.html b/openal/docs/index.html new file mode 100644 index 000000000..d4060d1c7 --- /dev/null +++ b/openal/docs/index.html @@ -0,0 +1,21 @@ + + + + + Index + + + + +

Index

+

+ This document has been removed. + See www.openal.org + for information. +

+ + + + + + diff --git a/openal/docs/oalspecs.sgml b/openal/docs/oalspecs.sgml new file mode 100644 index 000000000..fb8d3b3f4 --- /dev/null +++ b/openal/docs/oalspecs.sgml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + %Marks; + %Entities; + %Examples; + %Extensions; + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + + + + + &secBookInfo; + + + &chpIntroduction; + + + &chpOperation; + &chpState; + &chpRendering; + &chpBuffers; + &chpQueueing; + + + + &alcContext; + + + + &appConstants; + &appExtensions; + &appExtensionProcess; + + + + + + Main Document CVS Revision History + + CVS Document: $Id: oalspecs.sgml,v 1.15 2000/11/10 23:10:44 bk Exp $ + CVS Revision: $Revision: 1.15 $ + + $Log: oalspecs.sgml,v $ + Revision 1.15 2000/11/10 23:10:44 bk + Cleanup. + + Revision 1.14 2000/11/04 00:11:40 bk + Maintenance update + + Revision 1.13 2000/10/26 03:01:55 bk + Fixed typo for ALC entity. + + Revision 1.12 2000/10/26 02:59:46 bk + External entities. + + + +]]> + + + + + diff --git a/openal/docs/sec-bookinfo.sgml b/openal/docs/sec-bookinfo.sgml new file mode 100644 index 000000000..26b3b7a68 --- /dev/null +++ b/openal/docs/sec-bookinfo.sgml @@ -0,0 +1,53 @@ + + + + &OAL; Specification and Reference + + + + Version 1.0 Draft + + June 2000 + + 1999-2000 + Loki Software + + + + + Permission is granted to make and distribute verbatim copies of this + manual provided the copyright notice and this permission notice are + preserved on all copies. + + + + + Permission is granted to copy and distribute translations of this + manual into another language, under the above conditions for modified + versions, except that this permission notice may be stated in a + translation approved by the copyright owners. + + + + UNIX is a trademark of X/Open Group. + X Window System is a trademark of X Consortium, Inc. + Linux is a trademark of Linus Torvalds. + Windows is a trademark of Microsoft Corp. + Macintosh and Apple are trademarks of Apple Computer, Inc. + Loki and &OAL; are trademarks of Loki Software, Inc. + All other trademarks are property of their respective owners. + + + + Draft document of &OAL; Specification. + + + + + + \ No newline at end of file diff --git a/openal/docs/specification.html b/openal/docs/specification.html new file mode 100644 index 000000000..0d51804b5 --- /dev/null +++ b/openal/docs/specification.html @@ -0,0 +1,18 @@ + + + + +OpenAL Specification + + + + +

OpenAL Specification

+

+ This document has been removed. + See Index + for the specification. +

+ + + diff --git a/openal/docs/white-paper.html b/openal/docs/white-paper.html new file mode 100644 index 000000000..3c763541c --- /dev/null +++ b/openal/docs/white-paper.html @@ -0,0 +1,16 @@ + + + + OpenAL Whitepaper + + + +

OpenAL Whitepaper

+

+ This document has been removed. + See Index + for the specification. +

+ + + diff --git a/openal/idal.cpp b/openal/idal.cpp new file mode 100644 index 000000000..1a2ff2304 --- /dev/null +++ b/openal/idal.cpp @@ -0,0 +1,158 @@ +// generated header. do not edit +// C:\Python23\Lib\idlelib\idle.pyw +// Mon Mar 28 12:31:26 2005 + +ALenum ( ALAPIENTRY * idalGetError )( ALvoid ) = NULL; +ALvoid ( ALAPIENTRY * idalGenBuffers )( ALsizei, ALuint * ) = NULL; +ALboolean ( ALAPIENTRY * idalIsSource )( ALuint ) = NULL; +ALvoid ( ALAPIENTRY * idalSourceStop )( ALuint ) = NULL; +ALvoid ( ALAPIENTRY * idalGetSourcei )( ALuint, ALenum, ALint * ) = NULL; +ALint ( ALAPIENTRY * idalGetInteger )( ALenum ) = NULL; +ALCvoid ( ALAPIENTRY * idalcSuspendContext )( ALCcontext * ) = NULL; +ALCboolean ( ALAPIENTRY * idalcMakeContextCurrent )( ALCcontext * ) = NULL; +ALCvoid ( ALAPIENTRY * idalcProcessContext )( ALCcontext * ) = NULL; +ALCvoid ( ALAPIENTRY * idalcDestroyContext )( ALCcontext * ) = NULL; +ALCubyte * ( ALAPIENTRY * idalcGetString )( ALCdevice *, ALCenum ) = NULL; +ALvoid ( ALAPIENTRY * idalBufferData )( ALuint, ALenum, ALvoid *, ALsizei, ALsizei ) = NULL; +ALvoid ( ALAPIENTRY * idalDeleteBuffers )( ALsizei, ALuint * ) = NULL; +ALboolean ( ALAPIENTRY * idalIsExtensionPresent )( ALubyte * ) = NULL; +ALvoid ( ALAPIENTRY * idalDeleteSources )( ALsizei, ALuint * ) = NULL; +ALenum ( ALAPIENTRY * idalGetEnumValue )( ALubyte * ) = NULL; +ALvoid * ( ALAPIENTRY * idalGetProcAddress )( ALubyte * ) = NULL; +ALCcontext * ( ALAPIENTRY * idalcCreateContext )( ALCdevice *, ALCint * ) = NULL; +ALCdevice * ( ALAPIENTRY * idalcOpenDevice )( ALubyte * ) = NULL; +ALvoid ( ALAPIENTRY * idalListenerfv )( ALenum, ALfloat* ) = NULL; +ALvoid ( ALAPIENTRY * idalSourceQueueBuffers )( ALuint, ALsizei, ALuint * ) = NULL; +ALvoid ( ALAPIENTRY * idalSourcei )( ALuint, ALenum, ALint ) = NULL; +ALvoid ( ALAPIENTRY * idalListenerf )( ALenum, ALfloat ) = NULL; +ALCvoid ( ALAPIENTRY * idalcCloseDevice )( ALCdevice * ) = NULL; +ALboolean ( ALAPIENTRY * idalIsBuffer )( ALuint ) = NULL; +ALvoid ( ALAPIENTRY * idalSource3f )( ALuint, ALenum, ALfloat, ALfloat, ALfloat ) = NULL; +ALvoid ( ALAPIENTRY * idalGenSources )( ALsizei, ALuint * ) = NULL; +ALvoid ( ALAPIENTRY * idalSourcef )( ALuint, ALenum, ALfloat ) = NULL; +ALvoid ( ALAPIENTRY * idalSourceUnqueueBuffers )( ALuint, ALsizei, ALuint * ) = NULL; +ALvoid ( ALAPIENTRY * idalSourcePlay )( ALuint ) = NULL; + +const char* InitializeIDAL( HMODULE h ) { +idalGetError = ( ALenum ( ALAPIENTRY * ) ( ALvoid ) )GetProcAddress( h, "alGetError" ); +if ( !idalGetError) { + return "alGetError"; +} +idalGenBuffers = ( ALvoid ( ALAPIENTRY * ) ( ALsizei, ALuint * ) )GetProcAddress( h, "alGenBuffers" ); +if ( !idalGenBuffers) { + return "alGenBuffers"; +} +idalIsSource = ( ALboolean ( ALAPIENTRY * ) ( ALuint ) )GetProcAddress( h, "alIsSource" ); +if ( !idalIsSource) { + return "alIsSource"; +} +idalSourceStop = ( ALvoid ( ALAPIENTRY * ) ( ALuint ) )GetProcAddress( h, "alSourceStop" ); +if ( !idalSourceStop) { + return "alSourceStop"; +} +idalGetSourcei = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALenum, ALint * ) )GetProcAddress( h, "alGetSourcei" ); +if ( !idalGetSourcei) { + return "alGetSourcei"; +} +idalGetInteger = ( ALint ( ALAPIENTRY * ) ( ALenum ) )GetProcAddress( h, "alGetInteger" ); +if ( !idalGetInteger) { + return "alGetInteger"; +} +idalcSuspendContext = ( ALCvoid ( ALAPIENTRY * ) ( ALCcontext * ) )GetProcAddress( h, "alcSuspendContext" ); +if ( !idalcSuspendContext) { + return "alcSuspendContext"; +} +idalcMakeContextCurrent = ( ALCboolean ( ALAPIENTRY * ) ( ALCcontext * ) )GetProcAddress( h, "alcMakeContextCurrent" ); +if ( !idalcMakeContextCurrent) { + return "alcMakeContextCurrent"; +} +idalcProcessContext = ( ALCvoid ( ALAPIENTRY * ) ( ALCcontext * ) )GetProcAddress( h, "alcProcessContext" ); +if ( !idalcProcessContext) { + return "alcProcessContext"; +} +idalcDestroyContext = ( ALCvoid ( ALAPIENTRY * ) ( ALCcontext * ) )GetProcAddress( h, "alcDestroyContext" ); +if ( !idalcDestroyContext) { + return "alcDestroyContext"; +} +idalcGetString = ( ALCubyte * ( ALAPIENTRY * ) ( ALCdevice *, ALCenum ) )GetProcAddress( h, "alcGetString" ); +if ( !idalcGetString) { + return "alcGetString"; +} +idalBufferData = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALenum, ALvoid *, ALsizei, ALsizei ) )GetProcAddress( h, "alBufferData" ); +if ( !idalBufferData) { + return "alBufferData"; +} +idalDeleteBuffers = ( ALvoid ( ALAPIENTRY * ) ( ALsizei, ALuint * ) )GetProcAddress( h, "alDeleteBuffers" ); +if ( !idalDeleteBuffers) { + return "alDeleteBuffers"; +} +idalIsExtensionPresent = ( ALboolean ( ALAPIENTRY * ) ( ALubyte * ) )GetProcAddress( h, "alIsExtensionPresent" ); +if ( !idalIsExtensionPresent) { + return "alIsExtensionPresent"; +} +idalDeleteSources = ( ALvoid ( ALAPIENTRY * ) ( ALsizei, ALuint * ) )GetProcAddress( h, "alDeleteSources" ); +if ( !idalDeleteSources) { + return "alDeleteSources"; +} +idalGetEnumValue = ( ALenum ( ALAPIENTRY * ) ( ALubyte * ) )GetProcAddress( h, "alGetEnumValue" ); +if ( !idalGetEnumValue) { + return "alGetEnumValue"; +} +idalGetProcAddress = ( ALvoid * ( ALAPIENTRY * ) ( ALubyte * ) )GetProcAddress( h, "alGetProcAddress" ); +if ( !idalGetProcAddress) { + return "alGetProcAddress"; +} +idalcCreateContext = ( ALCcontext * ( ALAPIENTRY * ) ( ALCdevice *, ALCint * ) )GetProcAddress( h, "alcCreateContext" ); +if ( !idalcCreateContext) { + return "alcCreateContext"; +} +idalcOpenDevice = ( ALCdevice * ( ALAPIENTRY * ) ( ALubyte * ) )GetProcAddress( h, "alcOpenDevice" ); +if ( !idalcOpenDevice) { + return "alcOpenDevice"; +} +idalListenerfv = ( ALvoid ( ALAPIENTRY * ) ( ALenum, ALfloat* ) )GetProcAddress( h, "alListenerfv" ); +if ( !idalListenerfv) { + return "alListenerfv"; +} +idalSourceQueueBuffers = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALsizei, ALuint * ) )GetProcAddress( h, "alSourceQueueBuffers" ); +if ( !idalSourceQueueBuffers) { + return "alSourceQueueBuffers"; +} +idalSourcei = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALenum, ALint ) )GetProcAddress( h, "alSourcei" ); +if ( !idalSourcei) { + return "alSourcei"; +} +idalListenerf = ( ALvoid ( ALAPIENTRY * ) ( ALenum, ALfloat ) )GetProcAddress( h, "alListenerf" ); +if ( !idalListenerf) { + return "alListenerf"; +} +idalcCloseDevice = ( ALCvoid ( ALAPIENTRY * ) ( ALCdevice * ) )GetProcAddress( h, "alcCloseDevice" ); +if ( !idalcCloseDevice) { + return "alcCloseDevice"; +} +idalIsBuffer = ( ALboolean ( ALAPIENTRY * ) ( ALuint ) )GetProcAddress( h, "alIsBuffer" ); +if ( !idalIsBuffer) { + return "alIsBuffer"; +} +idalSource3f = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALenum, ALfloat, ALfloat, ALfloat ) )GetProcAddress( h, "alSource3f" ); +if ( !idalSource3f) { + return "alSource3f"; +} +idalGenSources = ( ALvoid ( ALAPIENTRY * ) ( ALsizei, ALuint * ) )GetProcAddress( h, "alGenSources" ); +if ( !idalGenSources) { + return "alGenSources"; +} +idalSourcef = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALenum, ALfloat ) )GetProcAddress( h, "alSourcef" ); +if ( !idalSourcef) { + return "alSourcef"; +} +idalSourceUnqueueBuffers = ( ALvoid ( ALAPIENTRY * ) ( ALuint, ALsizei, ALuint * ) )GetProcAddress( h, "alSourceUnqueueBuffers" ); +if ( !idalSourceUnqueueBuffers) { + return "alSourceUnqueueBuffers"; +} +idalSourcePlay = ( ALvoid ( ALAPIENTRY * ) ( ALuint ) )GetProcAddress( h, "alSourcePlay" ); +if ( !idalSourcePlay) { + return "alSourcePlay"; +} +return NULL; +}; diff --git a/openal/idal.h b/openal/idal.h new file mode 100644 index 000000000..d6e28652e --- /dev/null +++ b/openal/idal.h @@ -0,0 +1,65 @@ +// generated header. do not edit +// C:\Python23\Lib\idlelib\idle.pyw +// Mon Mar 28 12:31:26 2005 + +extern ALenum ( ALAPIENTRY * idalGetError )( ALvoid ); +extern ALvoid ( ALAPIENTRY * idalGenBuffers )( ALsizei, ALuint * ); +extern ALboolean ( ALAPIENTRY * idalIsSource )( ALuint ); +extern ALvoid ( ALAPIENTRY * idalSourceStop )( ALuint ); +extern ALvoid ( ALAPIENTRY * idalGetSourcei )( ALuint, ALenum, ALint * ); +extern ALint ( ALAPIENTRY * idalGetInteger )( ALenum ); +extern ALCvoid ( ALAPIENTRY * idalcSuspendContext )( ALCcontext * ); +extern ALCboolean ( ALAPIENTRY * idalcMakeContextCurrent )( ALCcontext * ); +extern ALCvoid ( ALAPIENTRY * idalcProcessContext )( ALCcontext * ); +extern ALCvoid ( ALAPIENTRY * idalcDestroyContext )( ALCcontext * ); +extern ALCubyte * ( ALAPIENTRY * idalcGetString )( ALCdevice *, ALCenum ); +extern ALvoid ( ALAPIENTRY * idalBufferData )( ALuint, ALenum, ALvoid *, ALsizei, ALsizei ); +extern ALvoid ( ALAPIENTRY * idalDeleteBuffers )( ALsizei, ALuint * ); +extern ALboolean ( ALAPIENTRY * idalIsExtensionPresent )( ALubyte * ); +extern ALvoid ( ALAPIENTRY * idalDeleteSources )( ALsizei, ALuint * ); +extern ALenum ( ALAPIENTRY * idalGetEnumValue )( ALubyte * ); +extern ALvoid * ( ALAPIENTRY * idalGetProcAddress )( ALubyte * ); +extern ALCcontext * ( ALAPIENTRY * idalcCreateContext )( ALCdevice *, ALCint * ); +extern ALCdevice * ( ALAPIENTRY * idalcOpenDevice )( ALubyte * ); +extern ALvoid ( ALAPIENTRY * idalListenerfv )( ALenum, ALfloat* ); +extern ALvoid ( ALAPIENTRY * idalSourceQueueBuffers )( ALuint, ALsizei, ALuint * ); +extern ALvoid ( ALAPIENTRY * idalSourcei )( ALuint, ALenum, ALint ); +extern ALvoid ( ALAPIENTRY * idalListenerf )( ALenum, ALfloat ); +extern ALCvoid ( ALAPIENTRY * idalcCloseDevice )( ALCdevice * ); +extern ALboolean ( ALAPIENTRY * idalIsBuffer )( ALuint ); +extern ALvoid ( ALAPIENTRY * idalSource3f )( ALuint, ALenum, ALfloat, ALfloat, ALfloat ); +extern ALvoid ( ALAPIENTRY * idalGenSources )( ALsizei, ALuint * ); +extern ALvoid ( ALAPIENTRY * idalSourcef )( ALuint, ALenum, ALfloat ); +extern ALvoid ( ALAPIENTRY * idalSourceUnqueueBuffers )( ALuint, ALsizei, ALuint * ); +extern ALvoid ( ALAPIENTRY * idalSourcePlay )( ALuint ); + +#define alGetError idalGetError +#define alGenBuffers idalGenBuffers +#define alIsSource idalIsSource +#define alSourceStop idalSourceStop +#define alGetSourcei idalGetSourcei +#define alGetInteger idalGetInteger +#define alcSuspendContext idalcSuspendContext +#define alcMakeContextCurrent idalcMakeContextCurrent +#define alcProcessContext idalcProcessContext +#define alcDestroyContext idalcDestroyContext +#define alcGetString idalcGetString +#define alBufferData idalBufferData +#define alDeleteBuffers idalDeleteBuffers +#define alIsExtensionPresent idalIsExtensionPresent +#define alDeleteSources idalDeleteSources +#define alGetEnumValue idalGetEnumValue +#define alGetProcAddress idalGetProcAddress +#define alcCreateContext idalcCreateContext +#define alcOpenDevice idalcOpenDevice +#define alListenerfv idalListenerfv +#define alSourceQueueBuffers idalSourceQueueBuffers +#define alSourcei idalSourcei +#define alListenerf idalListenerf +#define alcCloseDevice idalcCloseDevice +#define alIsBuffer idalIsBuffer +#define alSource3f idalSource3f +#define alGenSources idalGenSources +#define alSourcef idalSourcef +#define alSourceUnqueueBuffers idalSourceUnqueueBuffers +#define alSourcePlay idalSourcePlay diff --git a/openal/idal.py b/openal/idal.py new file mode 100644 index 000000000..3a8151b0e --- /dev/null +++ b/openal/idal.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# create win32 source for OpenAL on-demand loading from AL API definitions +# a set of defines al* -> idal* +# typedefs and code pointer functions definition + +# 1: get linking with no OpenAL DLL link in anymore +# i.e. have the defines and the code pointer working +# 2: do the load code + +import time + +funcs = [ + [ 'ALenum', 'alGetError', 'ALvoid' ], + [ 'ALvoid', 'alGenBuffers', 'ALsizei', 'ALuint *' ], + [ 'ALboolean', 'alIsSource', 'ALuint' ], + [ 'ALvoid', 'alSourceStop', 'ALuint' ], + [ 'ALvoid', 'alGetSourcei', 'ALuint', 'ALenum', 'ALint *' ], + [ 'ALint', 'alGetInteger', 'ALenum' ], + [ 'ALCvoid', 'alcSuspendContext', 'ALCcontext *' ], + [ 'ALCboolean', 'alcMakeContextCurrent', 'ALCcontext *' ], + [ 'ALCvoid', 'alcProcessContext', 'ALCcontext *' ], + [ 'ALCvoid', 'alcDestroyContext', 'ALCcontext *' ], + [ 'ALCubyte *', 'alcGetString', 'ALCdevice *', 'ALCenum' ], + [ 'ALvoid', 'alBufferData', 'ALuint', 'ALenum', 'ALvoid *', 'ALsizei', 'ALsizei' ], + [ 'ALvoid', 'alDeleteBuffers', 'ALsizei', 'ALuint *' ], + [ 'ALboolean', 'alIsExtensionPresent', 'ALubyte *' ], + [ 'ALvoid', 'alDeleteSources', 'ALsizei', 'ALuint *' ], + [ 'ALenum', 'alGetEnumValue', 'ALubyte *' ], + [ 'ALvoid *', 'alGetProcAddress', 'ALubyte *' ], + [ 'ALCcontext *', 'alcCreateContext', 'ALCdevice *', 'ALCint *' ], + [ 'ALCdevice *', 'alcOpenDevice', 'ALubyte *' ], + [ 'ALvoid', 'alListenerfv', 'ALenum', 'ALfloat*' ], + [ 'ALvoid', 'alSourceQueueBuffers', 'ALuint', 'ALsizei', 'ALuint *' ], + [ 'ALvoid', 'alSourcei', 'ALuint', 'ALenum', 'ALint' ], + [ 'ALvoid', 'alListenerf', 'ALenum', 'ALfloat' ], + [ 'ALCvoid', 'alcCloseDevice', 'ALCdevice *' ], + [ 'ALboolean', 'alIsBuffer', 'ALuint' ], + [ 'ALvoid', 'alSource3f', 'ALuint', 'ALenum', 'ALfloat', 'ALfloat', 'ALfloat' ], + [ 'ALvoid', 'alGenSources', 'ALsizei', 'ALuint *' ], + [ 'ALvoid', 'alSourcef', 'ALuint', 'ALenum', 'ALfloat' ], + [ 'ALvoid', 'alSourceUnqueueBuffers', 'ALuint', 'ALsizei', 'ALuint *' ], + [ 'ALvoid', 'alSourcePlay', 'ALuint' ], + ] + +def warningHeader( f ): + f.write( '// generated header. do not edit\n' ) + f.write( '// ' + __file__ + '\n' ) + f.write( '// ' + time.asctime() + '\n\n' ) + +def genIDALFunc( f, declare ): + if ( declare ): + extern = 'extern ' + else: + extern = '' + for func in funcs: + f.write( extern + func[0] + ' ( ALAPIENTRY * id' + func[1] + ' )( ' ) + i = 2 + while ( i < len( func ) ): + if ( i != 2 ): + f.write( ', ' ) + f.write( func[i] ) + i += 1 + if ( declare ): + f.write( ' );\n' ) + else: + f.write( ' ) = NULL;\n' ) + +def genDefineMapping( f ): + for func in funcs: + fname = func[1] + f.write( '#define %s id%s\n' % ( fname, fname ) ) + +def genIDALInit( f ): + for func in funcs: + # annoying casting + cast = func[0] + ' ( ALAPIENTRY * ) ( ' + i = 2 + while ( i < len( func ) ): + if ( i != 2 ): + cast += ', ' + cast += func[i] + i += 1 + cast += ' )' + # function + f.write( 'id' + func[1] + ' = ( ' + cast + ' )GetProcAddress( h, "' + func[1] + '" );\n' ) + f.write( 'if ( !id' + func[1] + ') {\n return "' + func[1] + '";\n}\n' ) + +if __name__ == '__main__': + f = open( 'idal.h', 'w' ) + warningHeader( f ) + genIDALFunc( f, True ) + f.write( '\n' ) + genDefineMapping( f ) + f.close() + f = open( 'idal.cpp', 'w' ) + warningHeader( f ) + genIDALFunc( f, False ) + f.write( '\n' ); + f.write( 'const char* InitializeIDAL( HMODULE h ) {\n' ) + genIDALInit( f ) + f.write( 'return NULL;\n' ); + f.write( '};\n' ) + f.close() diff --git a/openal/include/al.h b/openal/include/al.h new file mode 100644 index 000000000..8c4f1202c --- /dev/null +++ b/openal/include/al.h @@ -0,0 +1,491 @@ +#ifndef _AL_H_ +#define _AL_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ +#include "altypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _OPENAL32LIB + #define ALAPI __declspec(dllexport) + #else + #define ALAPI __declspec(dllimport) + #endif + #define ALAPIENTRY __cdecl + #define AL_CALLBACK +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALAPI + #define ALAPIENTRY __cdecl + #define AL_CALLBACK +#endif + +#define OPENAL + +#ifndef AL_NO_PROTOTYPES + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY alEnable( ALenum capability ); +ALAPI ALvoid ALAPIENTRY alDisable( ALenum capability ); +ALAPI ALboolean ALAPIENTRY alIsEnabled( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY alHint( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY alGetBoolean( ALenum param ); +ALAPI ALint ALAPIENTRY alGetInteger( ALenum param ); +ALAPI ALfloat ALAPIENTRY alGetFloat( ALenum param ); +ALAPI ALdouble ALAPIENTRY alGetDouble( ALenum param ); +ALAPI ALvoid ALAPIENTRY alGetBooleanv( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY alGetIntegerv( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY alGetFloatv( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY alGetDoublev( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY alGetString( ALenum param ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY alGetError( ALvoid ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY alIsExtensionPresent( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY alGetProcAddress( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY alGetEnumValue( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY alListeneri( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY alListenerf( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY alListener3f( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY alListenerfv( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alGetListeneri( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetListenerf( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetListener3f( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetListenerfv( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY alGenSources( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY alDeleteSources( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY alIsSource( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alSourcei( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY alSourcef( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY alSource3f( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY alSourcefv( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alGetSourcei( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetSourcef( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetSource3f( ALuint source, ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetSourcefv( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alSourcePlayv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourcePausev( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceStopv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceRewindv(ALsizei n,ALuint *sources); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY alSourcePlay( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY alSourcePause( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceStop( ALuint source ); + +/** + * Rewinds a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceRewind( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY alGenBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alDeleteBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY alIsBuffer( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY alBufferData( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + + +ALAPI ALvoid ALAPIENTRY alGetBufferi( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetBufferf( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ + +ALAPI ALvoid ALAPIENTRY alSourceQueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alSourceUnqueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY alDistanceModel( ALenum value ); +ALAPI ALvoid ALAPIENTRY alDopplerFactor( ALfloat value ); +ALAPI ALvoid ALAPIENTRY alDopplerVelocity( ALfloat value ); + +#else /* AL_NO_PROTOTYPES */ + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY (*alEnable)( ALenum capability ); +ALAPI ALvoid ALAPIENTRY (*alDisable)( ALenum capability ); +ALAPI ALboolean ALAPIENTRY (*alIsEnabled)( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY (*alHint)( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY (*alGetBoolean)( ALenum param ); +ALAPI ALint ALAPIENTRY (*alGetInteger)( ALenum param ); +ALAPI ALfloat ALAPIENTRY (*alGetFloat)( ALenum param ); +ALAPI ALdouble ALAPIENTRY (*alGetDouble)( ALenum param ); +ALAPI ALvoid ALAPIENTRY (*alGetBooleanv)( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY (*alGetIntegerv)( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY (*alGetFloatv)( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY (*alGetDoublev)( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY (*alGetString)( ALenum param ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY (*alGetError)( ALvoid ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY (*alIsExtensionPresent)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY (*alGetProcAddress)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY (*alGetEnumValue)( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY (*alListeneri)( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY (*alListenerf)( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY (*alListener3f)( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY (*alListenerfv)( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alGetListeneri)( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerf)( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListener3f)( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerfv)( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alGenSources)( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alDeleteSources)( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY (*alIsSource)( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alSourcei)( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY (*alSourcef)( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alSource3f)( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY (*alSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alGetSourcei)( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcef)( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alSourcePlayv)( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY (*alSourceStopv)( ALsizei n, ALuint *sources ); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY (*alSourcePlay)( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY (*alSourcePause)( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY (*alSourceStop)( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY (*alGenBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alDeleteBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY (*alIsBuffer)( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY (*alBufferData)( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + +ALAPI ALvoid ALAPIENTRY (*alGetBufferi)( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetBufferf)( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ +ALAPI ALvoid ALAPIENTRY (*alSourceQueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alSourceUnqueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY (*alDistanceModel)( ALenum value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerFactor)( ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerVelocity)( ALfloat value ); + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/include/alc.h b/openal/include/alc.h new file mode 100644 index 000000000..b7252c4fb --- /dev/null +++ b/openal/include/alc.h @@ -0,0 +1,91 @@ +#ifndef _ALC_H_ +#define _ALC_H_ + +#include "altypes.h" +#include "alctypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _OPENAL32LIB + #define ALCAPI __declspec(dllexport) + #else + #define ALCAPI __declspec(dllimport) + #endif + + typedef struct ALCdevice_struct ALCdevice; + typedef struct ALCcontext_struct ALCcontext; + + #define ALCAPIENTRY __cdecl +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALCAPI + #define ALCAPIENTRY __cdecl +#endif + + + +#ifndef ALC_NO_PROTOTYPES + +ALCAPI ALCubyte* ALCAPIENTRY alcGetString(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(ALCubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY alcCloseDevice(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY alcCreateContext(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcProcessContext(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY alcGetCurrentContext(ALCvoid); +ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcSuspendContext(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY alcGetError(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY alcGetProcAddress(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY alcGetEnumValue(ALCdevice *device,ALCubyte *enumName); + +#else /* ALC_NO_PROTOTYPES */ + +ALCAPI ALCubyte* ALCAPIENTRY (*alcGetString)(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY (*alcGetIntegerv)(ALCdevice * device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY (*alcOpenDevice)(ALubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY (*alcCloseDevice)(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY (*alcCreateContext)(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY (*alcMakeContextCurrent)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcProcessContext)(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY (*alcGetCurrentContext)(ALCvoid); +ALCAPI ALCdevice* ALCAPIENTRY (*alcGetContextsDevice)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcSuspendContext)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcDestroyContext)(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY (*alcGetError)(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY (*alcIsExtensionPresent)(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY (*alcGetProcAddress)(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY (*alcGetEnumValue)(ALCdevice *device,ALCubyte *enumName); + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/include/alctypes.h b/openal/include/alctypes.h new file mode 100644 index 000000000..436fcfacc --- /dev/null +++ b/openal/include/alctypes.h @@ -0,0 +1,125 @@ +#ifndef _ALCTYPES_H_ +#define _ALCTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** ALC boolean type. */ +typedef char ALCboolean; + +/** ALC 8bit signed byte. */ +typedef char ALCbyte; + +/** ALC 8bit unsigned byte. */ +typedef unsigned char ALCubyte; + +/** ALC 16bit signed short integer type. */ +typedef short ALCshort; + +/** ALC 16bit unsigned short integer type. */ +typedef unsigned short ALCushort; + +/** ALC 32bit unsigned integer type. */ +typedef unsigned ALCuint; + +/** ALC 32bit signed integer type. */ +typedef int ALCint; + +/** ALC 32bit floating point type. */ +typedef float ALCfloat; + +/** ALC 64bit double point type. */ +typedef double ALCdouble; + +/** ALC 32bit type. */ +typedef unsigned int ALCsizei; + +/** ALC void type */ +typedef void ALCvoid; + +/** ALC enumerations. */ +typedef int ALCenum; + +/* Bad value. */ +#define ALC_INVALID (-1) + +/* Boolean False. */ +#define ALC_FALSE 0 + +/* Boolean True. */ +#define ALC_TRUE 1 + +/** Errors: No Error. */ +#define ALC_NO_ERROR ALC_FALSE + +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 + +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +#define ALC_DEVICE_SPECIFIER 0x1005 +#define ALC_EXTENSIONS 0x1006 + +#define ALC_FREQUENCY 0x1007 +#define ALC_REFRESH 0x1008 +#define ALC_SYNC 0x1009 + +/** + * The device argument does not name a valid dvice. + */ +#define ALC_INVALID_DEVICE 0xA001 + +/** + * The context argument does not name a valid context. + */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define ALC_INVALID_ENUM 0xA003 + +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define ALC_INVALID_VALUE 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define ALC_OUT_OF_MEMORY 0xA005 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/include/altypes.h b/openal/include/altypes.h new file mode 100644 index 000000000..9dc4ead19 --- /dev/null +++ b/openal/include/altypes.h @@ -0,0 +1,333 @@ +#ifndef _ALTYPES_H_ +#define _ALTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** OpenAL boolean type. */ +typedef char ALboolean; + +/** OpenAL 8bit signed byte. */ +typedef char ALbyte; + +/** OpenAL 8bit unsigned byte. */ +typedef unsigned char ALubyte; + +/** OpenAL 16bit signed short integer type. */ +typedef short ALshort; + +/** OpenAL 16bit unsigned short integer type. */ +typedef unsigned short ALushort; + +/** OpenAL 32bit unsigned integer type. */ +typedef unsigned ALuint; + +/** OpenAL 32bit signed integer type. */ +typedef int ALint; + +/** OpenAL 32bit floating point type. */ +typedef float ALfloat; + +/** OpenAL 64bit double point type. */ +typedef double ALdouble; + +/** OpenAL 32bit type. */ +typedef unsigned int ALsizei; + +/** OpenAL void type */ +typedef void ALvoid; + +/** OpenAL enumerations. */ +typedef int ALenum; + +/* Bad value. */ +#define AL_INVALID (-1) + +/* Disable value. */ +#define AL_NONE 0 + +/* Boolean False. */ +#define AL_FALSE 0 + +/* Boolean True. */ +#define AL_TRUE 1 + +/** + * Indicate the type of AL_SOURCE. + * Sources can be spatialized + */ +#define AL_SOURCE_TYPE 0x200 + +/** Indicate source has absolute coordinates. */ +#define AL_SOURCE_ABSOLUTE 0x201 + +/** Indicate Source has listener relative coordinates. */ +#define AL_SOURCE_RELATIVE 0x202 + +/** + * Directional source, inner cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_INNER_ANGLE 0x1001 + +/** + * Directional source, outer cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_OUTER_ANGLE 0x1002 + +/** + * Specify the pitch to be applied, either at source, + * or on mixer results, at listener. + * Range: [0.5-2.0] + * Default: 1.0 + */ +#define AL_PITCH 0x1003 + +/** + * Specify the current location in three dimensional space. + * OpenAL, like OpenGL, uses a right handed coordinate system, + * where in a frontal default view X (thumb) points right, + * Y points up (index finger), and Z points towards the + * viewer/camera (middle finger). + * To switch from a left handed coordinate system, flip the + * sign on the Z coordinate. + * Listener position is always in the world coordinate system. + */ +#define AL_POSITION 0x1004 + +/** Specify the current direction as forward vector. */ +#define AL_DIRECTION 0x1005 + +/** Specify the current velocity in three dimensional space. */ +#define AL_VELOCITY 0x1006 + +/** + * Indicate whether source has to loop infinite. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + */ +#define AL_LOOPING 0x1007 + +/** + * Indicate the buffer to provide sound samples. + * Type: ALuint. + * Range: any valid Buffer id. + */ +#define AL_BUFFER 0x1009 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_GAIN 0x100A + +/** + * Indicate minimum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MIN_GAIN 0x100D + +/** + * Indicate maximum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MAX_GAIN 0x100E + +/** + * Specify the current orientation. + * Type: ALfv6 (at/up) + * Range: N/A + */ +#define AL_ORIENTATION 0x100F + +/* byte offset into source (in canon format). -1 if source + * is not playing. Don't set this, get this. + * + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_REFERENCE_DISTANCE 0x1020 + + /** + * Indicate the rolloff factor for the source. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Specify the maximum distance. + * Type: ALfloat + * Range: [0.0 - ] + */ +#define AL_MAX_DISTANCE 0x1023 + +/** + * Specify the channel mask. (Creative) + * Type: ALuint + * Range: [0 - 255] + */ +#define AL_CHANNEL_MASK 0x3000 + +/** + * Source state information + */ +#define AL_SOURCE_STATE 0x1010 +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Buffer Queue params + */ +#define AL_BUFFERS_QUEUED 0x1015 +#define AL_BUFFERS_PROCESSED 0x1016 + +/** Sound buffers: format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** + * Sound buffers: frequency, in units of Hertz [Hz]. + * This is the number of samples per second. Half of the + * sample frequency marks the maximum significant + * frequency component. + */ +#define AL_FREQUENCY 0x2001 +#define AL_BITS 0x2002 +#define AL_CHANNELS 0x2003 +#define AL_SIZE 0x2004 +#define AL_DATA 0x2005 + +/** + * Buffer state. + * + * Not supported for public use (yet). + */ +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 + +/** Errors: No Error. */ +#define AL_NO_ERROR AL_FALSE + +/** + * Illegal name passed as an argument to an AL call. + */ +#define AL_INVALID_NAME 0xA001 + +/** + * Illegal enum passed as an argument to an AL call. + */ +#define AL_INVALID_ENUM 0xA002 +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define AL_INVALID_VALUE 0xA003 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define AL_INVALID_OPERATION 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define AL_OUT_OF_MEMORY 0xA005 + +/** Context strings: Vendor Name. */ +#define AL_VENDOR 0xB001 +#define AL_VERSION 0xB002 +#define AL_RENDERER 0xB003 +#define AL_EXTENSIONS 0xB004 + +/** Global tweakage. */ + +/** + * Doppler scale. Default 1.0 + */ +#define AL_DOPPLER_FACTOR 0xC000 + +/** + * Doppler velocity. Default 1.0 + */ +#define AL_DOPPLER_VELOCITY 0xC001 + +/** + * Distance model. Default AL_INVERSE_DISTANCE_CLAMPED + */ +#define AL_DISTANCE_MODEL 0xD000 + +/** Distance models. */ + +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 + + /** + * enables + */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/include/alu.h b/openal/include/alu.h new file mode 100644 index 000000000..c6adff62c --- /dev/null +++ b/openal/include/alu.h @@ -0,0 +1,34 @@ +#ifndef _ALU_H_ +#define _ALU_H_ + +#define ALUAPI +#define ALUAPIENTRY __cdecl + +#define BUFFERSIZE 48000 +#define FRACTIONBITS 14 +#define FRACTIONMASK ((1L< + + /* + * EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5} + */ + DEFINE_GUID(CLSID_EAXDirectSound, + 0x4ff53b81, + 0x1ce0, + 0x11d3, + 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5); + + /* + * EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C} + */ + DEFINE_GUID(CLSID_EAXDirectSound8, + 0xca503b60, + 0xb176, + 0x11d4, + 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc); + + + +#ifdef DIRECTSOUND_VERSION +#if DIRECTSOUND_VERSION == 0x0800 + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*); +#endif +#endif + + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); + +#else // OPENAL + //#include + + #ifndef GUID_DEFINED + #define GUID_DEFINED + typedef struct _GUID + { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + } GUID; + #endif // !GUID_DEFINED + + #ifndef DEFINE_GUID + #ifndef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID /*FAR*/ name + #else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + #endif // INITGUID + #endif // DEFINE_GUID + + + /* + * EAX OpenAL Extension + */ + typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALboolean (*EAXSetBufferMode)(ALsizei,ALuint*,ALint); + typedef ALenum (*EAXGetBufferMode)(ALuint,ALint*); +#endif + +#pragma pack(push, 4) + +/* + * EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87} + */ +DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties, + 0xa8fa6882, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties + +typedef enum +{ + DSPROPERTY_EAXLISTENER_NONE, + DSPROPERTY_EAXLISTENER_ALLPARAMETERS, + DSPROPERTY_EAXLISTENER_ENVIRONMENT, + DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, + DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION, + DSPROPERTY_EAXLISTENER_ROOM, + DSPROPERTY_EAXLISTENER_ROOMHF, + DSPROPERTY_EAXLISTENER_ROOMLF, + DSPROPERTY_EAXLISTENER_DECAYTIME, + DSPROPERTY_EAXLISTENER_DECAYHFRATIO, + DSPROPERTY_EAXLISTENER_DECAYLFRATIO, + DSPROPERTY_EAXLISTENER_REFLECTIONS, + DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY, + DSPROPERTY_EAXLISTENER_REFLECTIONSPAN, + DSPROPERTY_EAXLISTENER_REVERB, + DSPROPERTY_EAXLISTENER_REVERBDELAY, + DSPROPERTY_EAXLISTENER_REVERBPAN, + DSPROPERTY_EAXLISTENER_ECHOTIME, + DSPROPERTY_EAXLISTENER_ECHODEPTH, + DSPROPERTY_EAXLISTENER_MODULATIONTIME, + DSPROPERTY_EAXLISTENER_MODULATIONDEPTH, + DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF, + DSPROPERTY_EAXLISTENER_HFREFERENCE, + DSPROPERTY_EAXLISTENER_LFREFERENCE, + DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXLISTENER_FLAGS +} DSPROPERTY_EAX_LISTENERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \ + DSPROPERTY_EAXLISTENER_IMMEDIATE) +#ifndef EAXVECTOR_DEFINED +#define EAXVECTOR_DEFINED +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; +#endif + +// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all times and delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myListener.lRoom = -1000; +// myListener.lRoomHF = -100; +// ... +// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ; +// instead of: +// myListener = { -1000, -100, ... , 0x00000009 }; +// If you want to save and load presets in binary form, you +// should define your own structure to insure future compatibility. +// +typedef struct _EAXLISTENERPROPERTIES +{ + unsigned long ulEnvironment; // sets all listener properties + float flEnvironmentSize; // environment size in meters + float flEnvironmentDiffusion; // environment diffusion + long lRoom; // room effect level (at mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lRoomLF; // relative room effect level at low frequencies + float flDecayTime; // reverberation decay time at mid frequencies + float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio + float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio + long lReflections; // early reflections level relative to room effect + float flReflectionsDelay; // initial reflection delay time + EAXVECTOR vReflectionsPan; // early reflections panning vector + long lReverb; // late reverberation level relative to room effect + float flReverbDelay; // late reverberation delay time relative to initial reflection + EAXVECTOR vReverbPan; // late reverberation panning vector + float flEchoTime; // echo time + float flEchoDepth; // echo depth + float flModulationTime; // modulation time + float flModulationDepth; // modulation depth + float flAirAbsorptionHF; // change in level per meter at high frequencies + float flHFReference; // reference high frequency + float flLFReference; // reference low frequency + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + unsigned long ulFlags; // modifies the behavior of properties +} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES; + +// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT +#ifndef EAX_ENVIRONMENTS_DEFINED +#define EAX_ENVIRONMENTS_DEFINED +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_UNDEFINED, + + EAX_ENVIRONMENT_COUNT +}; +#endif + +// Used by DSPROPERTY_EAXLISTENER_FLAGS +// +// Note: The number and order of flags may change in future EAX versions. +// It is recommended to use the flag defines as follows: +// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE; +// instead of: +// myFlags = 0x00000009; +// +// These flags determine what properties are affected by environment size. +#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time +#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level +#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time +#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level +#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time +#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time +#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time + +// This flag limits high-frequency decay time according to air absorption. +#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020 + +#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use + +// Property ranges and defaults: + +#define EAXLISTENER_MINENVIRONMENT 0 +#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1) +#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC + +#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f +#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f +#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f + +#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f +#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f +#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f + +#define EAXLISTENER_MINROOM (-10000) +#define EAXLISTENER_MAXROOM 0 +#define EAXLISTENER_DEFAULTROOM (-1000) + +#define EAXLISTENER_MINROOMHF (-10000) +#define EAXLISTENER_MAXROOMHF 0 +#define EAXLISTENER_DEFAULTROOMHF (-100) + +#define EAXLISTENER_MINROOMLF (-10000) +#define EAXLISTENER_MAXROOMLF 0 +#define EAXLISTENER_DEFAULTROOMLF 0 + +#define EAXLISTENER_MINDECAYTIME 0.1f +#define EAXLISTENER_MAXDECAYTIME 20.0f +#define EAXLISTENER_DEFAULTDECAYTIME 1.49f + +#define EAXLISTENER_MINDECAYHFRATIO 0.1f +#define EAXLISTENER_MAXDECAYHFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f + +#define EAXLISTENER_MINDECAYLFRATIO 0.1f +#define EAXLISTENER_MAXDECAYLFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f + +#define EAXLISTENER_MINREFLECTIONS (-10000) +#define EAXLISTENER_MAXREFLECTIONS 1000 +#define EAXLISTENER_DEFAULTREFLECTIONS (-2602) + +#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f +#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f +#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f + +#define EAXLISTENER_MINREVERB (-10000) +#define EAXLISTENER_MAXREVERB 2000 +#define EAXLISTENER_DEFAULTREVERB 200 + +#define EAXLISTENER_MINREVERBDELAY 0.0f +#define EAXLISTENER_MAXREVERBDELAY 0.1f +#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f + +#define EAXLISTENER_MINECHOTIME 0.075f +#define EAXLISTENER_MAXECHOTIME 0.25f +#define EAXLISTENER_DEFAULTECHOTIME 0.25f + +#define EAXLISTENER_MINECHODEPTH 0.0f +#define EAXLISTENER_MAXECHODEPTH 1.0f +#define EAXLISTENER_DEFAULTECHODEPTH 0.0f + +#define EAXLISTENER_MINMODULATIONTIME 0.04f +#define EAXLISTENER_MAXMODULATIONTIME 4.0f +#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f + +#define EAXLISTENER_MINMODULATIONDEPTH 0.0f +#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f +#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f + +#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f) +#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f +#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXLISTENER_MINHFREFERENCE 1000.0f +#define EAXLISTENER_MAXHFREFERENCE 20000.0f +#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f + +#define EAXLISTENER_MINLFREFERENCE 20.0f +#define EAXLISTENER_MAXLFREFERENCE 1000.0f +#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f + +#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f +#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f +#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \ + EAXLISTENERFLAGS_REFLECTIONSSCALE | \ + EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \ + EAXLISTENERFLAGS_REVERBSCALE | \ + EAXLISTENERFLAGS_REVERBDELAYSCALE | \ + EAXLISTENERFLAGS_DECAYHFLIMIT) + + + +/* +* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87} +*/ +DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties, + 0xa8fa6881, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties +#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties + +typedef enum +{ + DSPROPERTY_EAXBUFFER_NONE, + DSPROPERTY_EAXBUFFER_ALLPARAMETERS, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS, + DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_DIRECT, + DSPROPERTY_EAXBUFFER_DIRECTHF, + DSPROPERTY_EAXBUFFER_ROOM, + DSPROPERTY_EAXBUFFER_ROOMHF, + DSPROPERTY_EAXBUFFER_OBSTRUCTION, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSION, + DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO, + DSPROPERTY_EAXBUFFER_EXCLUSION, + DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF, + DSPROPERTY_EAXBUFFER_DOPPLERFACTOR, + DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR, + DSPROPERTY_EAXBUFFER_FLAGS +} DSPROPERTY_EAX_BUFFERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \ + DSPROPERTY_EAXBUFFER_IMMEDIATE) + +// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +typedef struct _EAXBUFFERPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lObstruction; // main obstruction control (attenuation at high frequencies) + float flObstructionLFRatio; // obstruction low-frequency level re. main control + long lOcclusion; // main occlusion control (attenuation at high frequencies) + float flOcclusionLFRatio; // occlusion low-frequency level re. main control + float flOcclusionRoomRatio; // relative occlusion control for room effect + float flOcclusionDirectRatio; // relative occlusion control for direct path + long lExclusion; // main exlusion control (attenuation at high frequencies) + float flExclusionLFRatio; // exclusion low-frequency level re. main control + long lOutsideVolumeHF; // outside sound cone level at high frequencies + float flDopplerFactor; // like DS3D flDopplerFactor but per source + float flRolloffFactor; // like DS3D flRolloffFactor but per source + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF + unsigned long ulFlags; // modifies the behavior of properties +} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION, +#ifndef EAX_OBSTRUCTIONPROPERTIES_DEFINED +#define EAX_OBSTRUCTIONPROPERTIES_DEFINED +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; +#endif + +// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION +#ifndef EAX_OCCLUSIONPROPERTIES_DEFINED +#define EAX_OCCLUSIONPROPERTIES_DEFINED +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; +#endif + +// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION +#ifndef EAX_EXCLUSIONPROPERTIES_DEFINED +#define EAX_EXCLUSIONPROPERTIES_DEFINED +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; +#endif + +// Used by DSPROPERTY_EAXBUFFER_FLAGS +// TRUE: value is computed automatically - property is an offset +// FALSE: value is used directly +// +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO; +// instead of: +// myFlags = 0x00000003; +// +#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF +#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM +#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF + +#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use + +// Property ranges and defaults: + +#define EAXBUFFER_MINDIRECT (-10000) +#define EAXBUFFER_MAXDIRECT 1000 +#define EAXBUFFER_DEFAULTDIRECT 0 + +#define EAXBUFFER_MINDIRECTHF (-10000) +#define EAXBUFFER_MAXDIRECTHF 0 +#define EAXBUFFER_DEFAULTDIRECTHF 0 + +#define EAXBUFFER_MINROOM (-10000) +#define EAXBUFFER_MAXROOM 1000 +#define EAXBUFFER_DEFAULTROOM 0 + +#define EAXBUFFER_MINROOMHF (-10000) +#define EAXBUFFER_MAXROOMHF 0 +#define EAXBUFFER_DEFAULTROOMHF 0 + +#define EAXBUFFER_MINOBSTRUCTION (-10000) +#define EAXBUFFER_MAXOBSTRUCTION 0 +#define EAXBUFFER_DEFAULTOBSTRUCTION 0 + +#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f +#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f + +#define EAXBUFFER_MINOCCLUSION (-10000) +#define EAXBUFFER_MAXOCCLUSION 0 +#define EAXBUFFER_DEFAULTOCCLUSION 0 + +#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f + +#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f + +#define EAXBUFFER_MINEXCLUSION (-10000) +#define EAXBUFFER_MAXEXCLUSION 0 +#define EAXBUFFER_DEFAULTEXCLUSION 0 + +#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f + +#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000) +#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0 +#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0 + +#define EAXBUFFER_MINDOPPLERFACTOR 0.0f +#define EAXBUFFER_MAXDOPPLERFACTOR 10.f +#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f + +#define EAXBUFFER_MINROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f +#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f +#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f + +#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \ + EAXBUFFERFLAGS_ROOMAUTO | \ + EAXBUFFERFLAGS_ROOMHFAUTO ) + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif diff --git a/openal/include/eax4.h b/openal/include/eax4.h new file mode 100644 index 000000000..6bf131378 --- /dev/null +++ b/openal/include/eax4.h @@ -0,0 +1,1575 @@ +/*******************************************************************\ +* * +* EAX.H - Environmental Audio Extensions version 4.0 * +* for OpenAL and DirectSound3D * +* * +* File revision 1.0.0 (GDC Beta SDK Release) * +* * +\*******************************************************************/ + +#ifndef EAX_H_INCLUDED +#define EAX_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef OPENAL + #include + + /* + * EAX Unified Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5} + */ + DEFINE_GUID(CLSID_EAXDirectSound, + 0x4ff53b81, + 0x1ce0, + 0x11d3, + 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5); + + /* + * EAX Unified Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C} + */ + DEFINE_GUID(CLSID_EAXDirectSound8, + 0xca503b60, + 0xb176, + 0x11d4, + 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc); + + + +#ifdef DIRECTSOUND_VERSION +#if DIRECTSOUND_VERSION >= 0x0800 + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*); +#endif +#endif + + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); + +#else // OPENAL +// #include + + #ifndef GUID_DEFINED + #define GUID_DEFINED + typedef struct _GUID + { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + } GUID; + #endif // GUID_DEFINED + + #ifndef DEFINE_GUID + #ifndef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID /*FAR*/ name + #else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + #endif // INITGUID + #endif // DEFINE_GUID + + /* + * EAX OpenAL Extensions + */ + typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALboolean (*EAXSetBufferMode)(ALsizei, ALuint*, ALint); + typedef ALenum (*EAXGetBufferMode)(ALuint, ALint*); +#endif + +#pragma pack(push, 4) + + + + +//////////////////////////////////////////////////////////////////////////// +// Constants + +#define EAX_MAX_FXSLOTS 4 +#define EAX_MAX_ACTIVE_FXSLOTS 2 + +// The EAX_NULL_GUID is used by EAXFXSLOT_LOADEFFECT, EAXCONTEXT_PRIMARYFXSLOTID +// and EAXSOURCE_ACTIVEFXSLOTID + +// {00000000-0000-0000-0000-000000000000} +DEFINE_GUID(EAX_NULL_GUID, + 0x00000000, + 0x0000, + 0x0000, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +// The EAX_PrimaryFXSlotID GUID is used by EAXSOURCE_ACTIVEFXSLOTID + +// {F317866D-924C-450C-861B-E6DAA25E7C20} +DEFINE_GUID(EAX_PrimaryFXSlotID, + 0xf317866d, + 0x924c, + 0x450c, + 0x86, 0x1b, 0xe6, 0xda, 0xa2, 0x5e, 0x7c, 0x20); + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Structures + +// Use this structure for EAXCONTEXT_ALL property. +typedef struct _EAXCONTEXTPROPERTIES +{ + GUID guidPrimaryFXSlotID; + float flDistanceFactor; + float flAirAbsorptionHF; + float flHFReference; +} EAXCONTEXTPROPERTIES, *LPEAXCONTEXTPROPERTIES; + +// Use this structure for EAXSOURCE_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXSOURCEFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +typedef struct _EAXSOURCEPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lObstruction; // main obstruction control (attenuation at high frequencies) + float flObstructionLFRatio; // obstruction low-frequency level re. main control + long lOcclusion; // main occlusion control (attenuation at high frequencies) + float flOcclusionLFRatio; // occlusion low-frequency level re. main control + float flOcclusionRoomRatio; // relative occlusion control for room effect + float flOcclusionDirectRatio; // relative occlusion control for direct path + long lExclusion; // main exlusion control (attenuation at high frequencies) + float flExclusionLFRatio; // exclusion low-frequency level re. main control + long lOutsideVolumeHF; // outside sound cone level at high frequencies + float flDopplerFactor; // like DS3D flDopplerFactor but per source + float flRolloffFactor; // like DS3D flRolloffFactor but per source + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + float flAirAbsorptionFactor; // multiplies EAXREVERB_AIRABSORPTIONHF + unsigned long ulFlags; // modifies the behavior of properties +} EAXSOURCEPROPERTIES, *LPEAXSOURCEPROPERTIES; + +// Use this structure for EAXSOURCE_ALLSENDPARAMETERS +// - all levels are hundredths of decibels +// +typedef struct _EAXSOURCEALLSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lSend; // send level (at low and mid frequencies) + long lSendHF; // relative send level at high frequencies + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; + long lExclusion; + float flExclusionLFRatio; +} EAXSOURCEALLSENDPROPERTIES, *LPEAXSOURCEALLSENDPROPERTIES; + +// Use this structure for EAXSOURCE_ACTIVEFXSLOTID +typedef struct _EAXACTIVEFXSLOTS +{ + GUID guidActiveFXSlots[EAX_MAX_ACTIVE_FXSLOTS]; +} EAXACTIVEFXSLOTS, *LPEAXACTIVEFXSLOTS; + +// Use this structure for EAXSOURCE_OBSTRUCTIONPARAMETERS property. +#ifndef EAX_OBSTRUCTIONPROPERTIES_DEFINED +#define EAX_OBSTRUCTIONPROPERTIES_DEFINED +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_OCCLUSIONPARAMETERS property. +#ifndef EAX_OCCLUSIONPROPERTIES_DEFINED +#define EAX_OCCLUSIONPROPERTIES_DEFINED +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_EXCLUSIONPARAMETERS property. +#ifndef EAX_EXCLUSIONPROPERTIES_DEFINED +#define EAX_EXCLUSIONPROPERTIES_DEFINED +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_SENDPARAMETERS properties. +typedef struct _EAXSOURCESENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lSend; + long lSendHF; +} EAXSOURCESENDPROPERTIES, *LPEAXSOURCESENDPROPERTIES; + +// Use this structure for EAXSOURCE_OCCLUSIONSENDPARAMETERS +typedef struct _EAXSOURCEOCCLUSIONSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXSOURCEOCCLUSIONSENDPROPERTIES, *LPEAXSOURCEOCCLUSIONSENDPROPERTIES; + +// Use this structure for EAXSOURCE_EXCLUSIONSENDPARAMETERS +typedef struct _EAXSOURCEEXCLUSIONSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lExclusion; + float flExclusionLFRatio; +} EAXSOURCEEXCLUSIONSENDPROPERTIES, *LPEAXSOURCEEXCLUSIONSENDPROPERTIES; + +// Use this structure for EAXFXSLOT_ALLPARAMETERS +// - all levels are hundredths of decibels +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myFXSlot.guidLoadEffect = EAX_REVERB_EFFECT; +// myFXSlot.lVolume = 0; +// myFXSlot.lLock = 1; +// myFXSlot.ulFlags = myFlags /* see EAXFXSLOTFLAGS below */ ; +// instead of: +// myFXSlot = { EAX_REVERB_EFFECT, 0, 1, 0x00000001 }; +// +typedef struct _EAXFXSLOTPROPERTIES +{ + GUID guidLoadEffect; + long lVolume; + long lLock; + unsigned long ulFlags; +} EAXFXSLOTPROPERTIES, *LPEAXFXSLOTPROPERTIES; + +// Use this structure for EAXREVERB_REFLECTIONSPAN and EAXREVERB_REVERBPAN properties. +#ifndef EAXVECTOR_DEFINED +#define EAXVECTOR_DEFINED +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; +#endif + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Error Codes + +#define EAX_OK 0 +#define EAXERR_INVALID_OPERATION (-1) +#define EAXERR_INVALID_VALUE (-2) +#define EAXERR_NO_EFFECT_LOADED (-3) +#define EAXERR_UNKNOWN_EFFECT (-4) +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Context Object + +// {1D4870AD-0DEF-43c0-A40C-523632296342} +DEFINE_GUID(EAXPROPERTYID_EAX40_Context, + 0x1d4870ad, + 0xdef, + 0x43c0, + 0xa4, 0xc, 0x52, 0x36, 0x32, 0x29, 0x63, 0x42); + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_Context EAXPROPERTYID_EAX40_Context + +typedef enum +{ + EAXCONTEXT_NONE = 0, + EAXCONTEXT_ALLPARAMETERS, + EAXCONTEXT_PRIMARYFXSLOTID, + EAXCONTEXT_DISTANCEFACTOR, + EAXCONTEXT_AIRABSORPTIONHF, + EAXCONTEXT_HFREFERENCE, + EAXCONTEXT_LASTERROR +} EAXCONTEXT_PROPERTY; + +// OR these flags with property id +#define EAXCONTEXT_PARAMETER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXCONTEXT_PARAMETER_DEFER 0x80000000 // changes take effect later +#define EAXCONTEXT_PARAMETER_COMMITDEFERREDSETTINGS (EAXCONTEXT_NONE | \ + EAXCONTEXT_PARAMETER_IMMEDIATE) + +// EAX Context property ranges and defaults: +#define EAXCONTEXT_DEFAULTPRIMARYFXSLOTID EAXPROPERTYID_EAX40_FXSlot0 + +#define EAXCONTEXT_MINDISTANCEFACTOR FLT_MIN //minimum positive value +#define EAXCONTEXT_MAXDISTANCEFACTOR FLT_MAX +#define EAXCONTEXT_DEFAULTDISTANCEFACTOR 1.0f + +#define EAXCONTEXT_MINAIRABSORPTIONHF (-100.0f) +#define EAXCONTEXT_MAXAIRABSORPTIONHF 0.0f +#define EAXCONTEXT_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXCONTEXT_MINHFREFERENCE 1000.0f +#define EAXCONTEXT_MAXHFREFERENCE 20000.0f +#define EAXCONTEXT_DEFAULTHFREFERENCE 5000.0f + +#define EAXCONTEXT_DEFAULTLASTERROR EAX_OK + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Effect Slot Objects + +// {C4D79F1E-F1AC-436b-A81D-A738E7045469} +DEFINE_GUID(EAXPROPERTYID_EAX40_FXSlot0, + 0xc4d79f1e, + 0xf1ac, + 0x436b, + 0xa8, 0x1d, 0xa7, 0x38, 0xe7, 0x4, 0x54, 0x69); + +// {08C00E96-74BE-4491-93AA-E8AD35A49117} +DEFINE_GUID(EAXPROPERTYID_EAX40_FXSlot1, + 0x8c00e96, + 0x74be, + 0x4491, + 0x93, 0xaa, 0xe8, 0xad, 0x35, 0xa4, 0x91, 0x17); + +// {1D433B88-F0F6-4637-919F-60E7E06B5EDD} +DEFINE_GUID(EAXPROPERTYID_EAX40_FXSlot2, + 0x1d433b88, + 0xf0f6, + 0x4637, + 0x91, 0x9f, 0x60, 0xe7, 0xe0, 0x6b, 0x5e, 0xdd); + +// {EFFF08EA-C7D8-44ab-93AD-6DBD5F910064} +DEFINE_GUID(EAXPROPERTYID_EAX40_FXSlot3, + 0xefff08ea, + 0xc7d8, + 0x44ab, + 0x93, 0xad, 0x6d, 0xbd, 0x5f, 0x91, 0x0, 0x64); + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_FXSlot0 EAXPROPERTYID_EAX40_FXSlot0 +#define EAXPROPERTYID_EAX_FXSlot1 EAXPROPERTYID_EAX40_FXSlot1 +#define EAXPROPERTYID_EAX_FXSlot2 EAXPROPERTYID_EAX40_FXSlot2 +#define EAXPROPERTYID_EAX_FXSlot3 EAXPROPERTYID_EAX40_FXSlot3 + +// FXSlot object properties +typedef enum +{ + EAXFXSLOT_PARAMETER = 0, // range 0-0x40 reserved for loaded effect parameters + EAXFXSLOT_NONE = 0x10000, + EAXFXSLOT_ALLPARAMETERS, + EAXFXSLOT_LOADEFFECT, + EAXFXSLOT_VOLUME, + EAXFXSLOT_LOCK, + EAXFXSLOT_FLAGS +} EAXFXSLOT_PROPERTY; + +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXFXSLOTFLAGS_ENVIRONMENT; +// instead of: +// myFlags = 0x00000001; +// +#define EAXFXSLOTFLAGS_ENVIRONMENT 0x00000001 +#define EAXFXSLOTFLAGS_RESERVED 0xFFFFFFFE // reserved future use + +// EAX Effect Slot property ranges and defaults: +#define EAXFXSLOT_MINVOLUME (-10000) +#define EAXFXSLOT_MAXVOLUME 0 +#define EAXFXSLOT_DEFAULTVOLUME 0 + +#define EAXFXSLOT_MINLOCK 0 +#define EAXFXSLOT_MAXLOCK 1 + +enum +{ + EAXFXSLOT_UNLOCKED = 0, + EAXFXSLOT_LOCKED = 1 +}; + +#define EAXFXSLOT_DEFAULTFLAGS (EAXFXSLOTFLAGS_ENVIRONMENT) +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Source Object + +// {1B86B823-22DF-4eae-8B3C-1278CE544227} +DEFINE_GUID(EAXPROPERTYID_EAX40_Source, + 0x1b86b823, + 0x22df, + 0x4eae, + 0x8b, 0x3c, 0x12, 0x78, 0xce, 0x54, 0x42, 0x27); + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_Source EAXPROPERTYID_EAX40_Source + +// Source object properties +typedef enum +{ + EAXSOURCE_NONE, + EAXSOURCE_ALLPARAMETERS, + EAXSOURCE_OBSTRUCTIONPARAMETERS, + EAXSOURCE_OCCLUSIONPARAMETERS, + EAXSOURCE_EXCLUSIONPARAMETERS, + EAXSOURCE_DIRECT, + EAXSOURCE_DIRECTHF, + EAXSOURCE_ROOM, + EAXSOURCE_ROOMHF, + EAXSOURCE_OBSTRUCTION, + EAXSOURCE_OBSTRUCTIONLFRATIO, + EAXSOURCE_OCCLUSION, + EAXSOURCE_OCCLUSIONLFRATIO, + EAXSOURCE_OCCLUSIONROOMRATIO, + EAXSOURCE_OCCLUSIONDIRECTRATIO, + EAXSOURCE_EXCLUSION, + EAXSOURCE_EXCLUSIONLFRATIO, + EAXSOURCE_OUTSIDEVOLUMEHF, + EAXSOURCE_DOPPLERFACTOR, + EAXSOURCE_ROLLOFFFACTOR, + EAXSOURCE_ROOMROLLOFFFACTOR, + EAXSOURCE_AIRABSORPTIONFACTOR, + EAXSOURCE_FLAGS, + EAXSOURCE_SENDPARAMETERS, + EAXSOURCE_ALLSENDPARAMETERS, + EAXSOURCE_OCCLUSIONSENDPARAMETERS, + EAXSOURCE_EXCLUSIONSENDPARAMETERS, + EAXSOURCE_ACTIVEFXSLOTID, +} EAXSOURCE_PROPERTY; + +// OR these flags with property id +#define EAXSOURCE_PARAMETER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXSOURCE_PARAMETER_DEFERRED 0x80000000 // changes take effect later +#define EAXSOURCE_PARAMETER_COMMITDEFERREDSETTINGS (EAXSOURCE_NONE | \ + EAXSOURCE_PARAMETER_IMMEDIATE) +// Used by EAXSOURCE_FLAGS for EAXSOURCEFLAGS_xxxAUTO +// TRUE: value is computed automatically - property is an offset +// FALSE: value is used directly +// +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXSOURCE_DIRECTHFAUTO | EAXSOURCE_ROOMAUTO; +// instead of: +// myFlags = 0x00000003; +// +#define EAXSOURCEFLAGS_DIRECTHFAUTO 0x00000001 // relates to EAXSOURCE_DIRECTHF +#define EAXSOURCEFLAGS_ROOMAUTO 0x00000002 // relates to EAXSOURCE_ROOM +#define EAXSOURCEFLAGS_ROOMHFAUTO 0x00000004 // relates to EAXSOURCE_ROOMHF +#define EAXSOURCEFLAGS_RESERVED 0xFFFFFFF8 // reserved future use + +// EAX Source property ranges and defaults: +#define EAXSOURCE_MINSEND (-10000) +#define EAXSOURCE_MAXSEND 0 +#define EAXSOURCE_DEFAULTSEND 0 + +#define EAXSOURCE_MINSENDHF (-10000) +#define EAXSOURCE_MAXSENDHF 0 +#define EAXSOURCE_DEFAULTSENDHF 0 + +#define EAXSOURCE_MINDIRECT (-10000) +#define EAXSOURCE_MAXDIRECT 1000 +#define EAXSOURCE_DEFAULTDIRECT 0 + +#define EAXSOURCE_MINDIRECTHF (-10000) +#define EAXSOURCE_MAXDIRECTHF 0 +#define EAXSOURCE_DEFAULTDIRECTHF 0 + +#define EAXSOURCE_MINROOM (-10000) +#define EAXSOURCE_MAXROOM 1000 +#define EAXSOURCE_DEFAULTROOM 0 + +#define EAXSOURCE_MINROOMHF (-10000) +#define EAXSOURCE_MAXROOMHF 0 +#define EAXSOURCE_DEFAULTROOMHF 0 + +#define EAXSOURCE_MINOBSTRUCTION (-10000) +#define EAXSOURCE_MAXOBSTRUCTION 0 +#define EAXSOURCE_DEFAULTOBSTRUCTION 0 + +#define EAXSOURCE_MINOBSTRUCTIONLFRATIO 0.0f +#define EAXSOURCE_MAXOBSTRUCTIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTOBSTRUCTIONLFRATIO 0.0f + +#define EAXSOURCE_MINOCCLUSION (-10000) +#define EAXSOURCE_MAXOCCLUSION 0 +#define EAXSOURCE_DEFAULTOCCLUSION 0 + +#define EAXSOURCE_MINOCCLUSIONLFRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXSOURCE_MINOCCLUSIONROOMRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONROOMRATIO 10.0f +#define EAXSOURCE_DEFAULTOCCLUSIONROOMRATIO 1.5f + +#define EAXSOURCE_MINOCCLUSIONDIRECTRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONDIRECTRATIO 10.0f +#define EAXSOURCE_DEFAULTOCCLUSIONDIRECTRATIO 1.0f + +#define EAXSOURCE_MINEXCLUSION (-10000) +#define EAXSOURCE_MAXEXCLUSION 0 +#define EAXSOURCE_DEFAULTEXCLUSION 0 + +#define EAXSOURCE_MINEXCLUSIONLFRATIO 0.0f +#define EAXSOURCE_MAXEXCLUSIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTEXCLUSIONLFRATIO 1.0f + +#define EAXSOURCE_MINOUTSIDEVOLUMEHF (-10000) +#define EAXSOURCE_MAXOUTSIDEVOLUMEHF 0 +#define EAXSOURCE_DEFAULTOUTSIDEVOLUMEHF 0 + +#define EAXSOURCE_MINDOPPLERFACTOR 0.0f +#define EAXSOURCE_MAXDOPPLERFACTOR 10.f +#define EAXSOURCE_DEFAULTDOPPLERFACTOR 1.0f + +#define EAXSOURCE_MINROLLOFFFACTOR 0.0f +#define EAXSOURCE_MAXROLLOFFFACTOR 10.f +#define EAXSOURCE_DEFAULTROLLOFFFACTOR 0.0f + +#define EAXSOURCE_MINROOMROLLOFFFACTOR 0.0f +#define EAXSOURCE_MAXROOMROLLOFFFACTOR 10.f +#define EAXSOURCE_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXSOURCE_MINAIRABSORPTIONFACTOR 0.0f +#define EAXSOURCE_MAXAIRABSORPTIONFACTOR 10.0f +#define EAXSOURCE_DEFAULTAIRABSORPTIONFACTOR 0.0f + +#define EAXSOURCE_DEFAULTFLAGS (EAXSOURCEFLAGS_DIRECTHFAUTO | \ + EAXSOURCEFLAGS_ROOMAUTO | \ + EAXSOURCEFLAGS_ROOMHFAUTO ) + +#define EAXSOURCE_DEFAULTACTIVEFXSLOTID {{ EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_PrimaryFXSlotID.Data1, EAX_PrimaryFXSlotID.Data2, \ + EAX_PrimaryFXSlotID.Data3, EAX_PrimaryFXSlotID.Data4[0],\ + EAX_PrimaryFXSlotID.Data4[1],EAX_PrimaryFXSlotID.Data4[2],\ + EAX_PrimaryFXSlotID.Data4[3],EAX_PrimaryFXSlotID.Data4[4],\ + EAX_PrimaryFXSlotID.Data4[5],EAX_PrimaryFXSlotID.Data4[6],\ + EAX_PrimaryFXSlotID.Data4[7] }} + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Reverb Effect + +// EAX REVERB {0CF95C8F-A3CC-4849-B0B6-832ECC1822DF} +DEFINE_GUID(EAX_REVERB_EFFECT, + 0xcf95c8f, + 0xa3cc, + 0x4849, + 0xb0, 0xb6, 0x83, 0x2e, 0xcc, 0x18, 0x22, 0xdf); + +// Reverb effect properties +typedef enum +{ + EAXREVERB_NONE, + EAXREVERB_ALLPARAMETERS, + EAXREVERB_ENVIRONMENT, + EAXREVERB_ENVIRONMENTSIZE, + EAXREVERB_ENVIRONMENTDIFFUSION, + EAXREVERB_ROOM, + EAXREVERB_ROOMHF, + EAXREVERB_ROOMLF, + EAXREVERB_DECAYTIME, + EAXREVERB_DECAYHFRATIO, + EAXREVERB_DECAYLFRATIO, + EAXREVERB_REFLECTIONS, + EAXREVERB_REFLECTIONSDELAY, + EAXREVERB_REFLECTIONSPAN, + EAXREVERB_REVERB, + EAXREVERB_REVERBDELAY, + EAXREVERB_REVERBPAN, + EAXREVERB_ECHOTIME, + EAXREVERB_ECHODEPTH, + EAXREVERB_MODULATIONTIME, + EAXREVERB_MODULATIONDEPTH, + EAXREVERB_AIRABSORPTIONHF, + EAXREVERB_HFREFERENCE, + EAXREVERB_LFREFERENCE, + EAXREVERB_ROOMROLLOFFFACTOR, + EAXREVERB_FLAGS, +} EAXREVERB_PROPERTY; + +// OR these flags with property id +#define EAXREVERB_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXREVERB_DEFERRED 0x80000000 // changes take effect later +#define EAXREVERB_COMMITDEFERREDSETTINGS (EAXREVERB_NONE | \ + EAXREVERB_IMMEDIATE) + +// used by EAXREVERB_ENVIRONMENT +#ifndef EAX_ENVIRONMENTS_DEFINED +#define EAX_ENVIRONMENTS_DEFINED +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_UNDEFINED, + + EAX_ENVIRONMENT_COUNT +}; +#endif + +// Used by EAXREVERB_FLAGS +// +// Note: The number and order of flags may change in future EAX versions. +// It is recommended to use the flag defines as follows: +// myFlags = EAXREVERBFLAGS_DECAYTIMESCALE | EAXREVERBFLAGS_REVERBSCALE; +// instead of: +// myFlags = 0x00000009; +// +// These flags determine what properties are affected by environment size. +#define EAXREVERBFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time +#define EAXREVERBFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level +#define EAXREVERBFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time +#define EAXREVERBFLAGS_REVERBSCALE 0x00000008 // reflections level +#define EAXREVERBFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time +#define EAXREVERBFLAGS_ECHOTIMESCALE 0x00000040 // echo time +#define EAXREVERBFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time +// This flag limits high-frequency decay time according to air absorption. +#define EAXREVERBFLAGS_DECAYHFLIMIT 0x00000020 +#define EAXREVERBFLAGS_RESERVED 0xFFFFFF00 // reserved future use + +// Use this structure for EAXREVERB_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all times and delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myReverb.lRoom = -1000; +// myReverb.lRoomHF = -100; +// ... +// myReverb.dwFlags = myFlags /* see EAXREVERBFLAGS below */ ; +// instead of: +// myReverb = { -1000, -100, ... , 0x00000009 }; +// If you want to save and load presets in binary form, you +// should define your own structure to insure future compatibility. +// +typedef struct _EAXREVERBPROPERTIES +{ + unsigned long ulEnvironment; // sets all reverb properties + float flEnvironmentSize; // environment size in meters + float flEnvironmentDiffusion; // environment diffusion + long lRoom; // room effect level (at mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lRoomLF; // relative room effect level at low frequencies + float flDecayTime; // reverberation decay time at mid frequencies + float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio + float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio + long lReflections; // early reflections level relative to room effect + float flReflectionsDelay; // initial reflection delay time + EAXVECTOR vReflectionsPan; // early reflections panning vector + long lReverb; // late reverberation level relative to room effect + float flReverbDelay; // late reverberation delay time relative to initial reflection + EAXVECTOR vReverbPan; // late reverberation panning vector + float flEchoTime; // echo time + float flEchoDepth; // echo depth + float flModulationTime; // modulation time + float flModulationDepth; // modulation depth + float flAirAbsorptionHF; // change in level per meter at high frequencies + float flHFReference; // reference high frequency + float flLFReference; // reference low frequency + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + unsigned long ulFlags; // modifies the behavior of properties +} EAXREVERBPROPERTIES, *LPEAXREVERBPROPERTIES; + +// Property ranges and defaults: +#define EAXREVERB_MINENVIRONMENT 0 +#define EAXREVERB_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1) +#define EAXREVERB_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC + +#define EAXREVERB_MINENVIRONMENTSIZE 1.0f +#define EAXREVERB_MAXENVIRONMENTSIZE 100.0f +#define EAXREVERB_DEFAULTENVIRONMENTSIZE 7.5f + +#define EAXREVERB_MINENVIRONMENTDIFFUSION 0.0f +#define EAXREVERB_MAXENVIRONMENTDIFFUSION 1.0f +#define EAXREVERB_DEFAULTENVIRONMENTDIFFUSION 1.0f + +#define EAXREVERB_MINROOM (-10000) +#define EAXREVERB_MAXROOM 0 +#define EAXREVERB_DEFAULTROOM (-1000) + +#define EAXREVERB_MINROOMHF (-10000) +#define EAXREVERB_MAXROOMHF 0 +#define EAXREVERB_DEFAULTROOMHF (-100) + +#define EAXREVERB_MINROOMLF (-10000) +#define EAXREVERB_MAXROOMLF 0 +#define EAXREVERB_DEFAULTROOMLF 0 + +#define EAXREVERB_MINDECAYTIME 0.1f +#define EAXREVERB_MAXDECAYTIME 20.0f +#define EAXREVERB_DEFAULTDECAYTIME 1.49f + +#define EAXREVERB_MINDECAYHFRATIO 0.1f +#define EAXREVERB_MAXDECAYHFRATIO 2.0f +#define EAXREVERB_DEFAULTDECAYHFRATIO 0.83f + +#define EAXREVERB_MINDECAYLFRATIO 0.1f +#define EAXREVERB_MAXDECAYLFRATIO 2.0f +#define EAXREVERB_DEFAULTDECAYLFRATIO 1.00f + +#define EAXREVERB_MINREFLECTIONS (-10000) +#define EAXREVERB_MAXREFLECTIONS 1000 +#define EAXREVERB_DEFAULTREFLECTIONS (-2602) + +#define EAXREVERB_MINREFLECTIONSDELAY 0.0f +#define EAXREVERB_MAXREFLECTIONSDELAY 0.3f +#define EAXREVERB_DEFAULTREFLECTIONSDELAY 0.007f + +#define EAXREVERB_DEFAULTREFLECTIONSPAN {0.0f, 0.0f, 0.0f} + +#define EAXREVERB_MINREVERB (-10000) +#define EAXREVERB_MAXREVERB 2000 +#define EAXREVERB_DEFAULTREVERB 200 + +#define EAXREVERB_MINREVERBDELAY 0.0f +#define EAXREVERB_MAXREVERBDELAY 0.1f +#define EAXREVERB_DEFAULTREVERBDELAY 0.011f + +#define EAXREVERB_DEFAULTREVERBPAN {0.0f, 0.0f, 0.0f} + +#define EAXREVERB_MINECHOTIME 0.075f +#define EAXREVERB_MAXECHOTIME 0.25f +#define EAXREVERB_DEFAULTECHOTIME 0.25f + +#define EAXREVERB_MINECHODEPTH 0.0f +#define EAXREVERB_MAXECHODEPTH 1.0f +#define EAXREVERB_DEFAULTECHODEPTH 0.0f + +#define EAXREVERB_MINMODULATIONTIME 0.04f +#define EAXREVERB_MAXMODULATIONTIME 4.0f +#define EAXREVERB_DEFAULTMODULATIONTIME 0.25f + +#define EAXREVERB_MINMODULATIONDEPTH 0.0f +#define EAXREVERB_MAXMODULATIONDEPTH 1.0f +#define EAXREVERB_DEFAULTMODULATIONDEPTH 0.0f + +#define EAXREVERB_MINAIRABSORPTIONHF (-100.0f) +#define EAXREVERB_MAXAIRABSORPTIONHF 0.0f +#define EAXREVERB_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXREVERB_MINHFREFERENCE 1000.0f +#define EAXREVERB_MAXHFREFERENCE 20000.0f +#define EAXREVERB_DEFAULTHFREFERENCE 5000.0f + +#define EAXREVERB_MINLFREFERENCE 20.0f +#define EAXREVERB_MAXLFREFERENCE 1000.0f +#define EAXREVERB_DEFAULTLFREFERENCE 250.0f + +#define EAXREVERB_MINROOMROLLOFFFACTOR 0.0f +#define EAXREVERB_MAXROOMROLLOFFFACTOR 10.0f +#define EAXREVERB_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXREVERB_DEFAULTFLAGS (EAXREVERBFLAGS_DECAYTIMESCALE | \ + EAXREVERBFLAGS_REFLECTIONSSCALE | \ + EAXREVERBFLAGS_REFLECTIONSDELAYSCALE | \ + EAXREVERBFLAGS_REVERBSCALE | \ + EAXREVERBFLAGS_REVERBDELAYSCALE | \ + EAXREVERBFLAGS_DECAYHFLIMIT) +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// + +// New Effect Types + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// AGC Compressor Effect + +// EAX AGC COMPRESSOR {BFB7A01E-7825-4039-927F-3AABDA0C560} + +DEFINE_GUID(EAX_AGCCOMPRESSOR_EFFECT, + 0xbfb7a01e, + 0x7825, + 0x4039, + 0x92, 0x7f, 0x3, 0xaa, 0xbd, 0xa0, 0xc5, 0x60); + +// AGC Compressor properties +typedef enum +{ + EAXAGCCOMPRESSOR_NONE, + EAXAGCCOMPRESSOR_ALLPARAMETERS, + EAXAGCCOMPRESSOR_ONOFF +} EAXAGCCOMPRESSOR_PROPERTY; + +// OR these flags with property id +#define EAXAGCCOMPRESSOR_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXAGCCOMPRESSOR_DEFERRED 0x80000000 // changes take effect later +#define EAXAGCCOMPRESSOR_COMMITDEFERREDSETTINGS (EAXAGCCOMPRESSOR_NONE | \ + EAXAGCCOMPRESSOR_IMMEDIATE) + +// Use this structure for EAXAGCCOMPRESSOR_ALLPARAMETERS +typedef struct _EAXAGCCOMPRESSORPROPERTIES +{ + unsigned long ulOnOff; // Switch Compressor on or off +} EAXAGCCOMPRESSORPROPERTIES, *LPEAXAGCCOMPRESSORPROPERTIES; + +// Property ranges and defaults: + +#define EAXAGCCOMPRESSOR_MINONOFF 0 +#define EAXAGCCOMPRESSOR_MAXONOFF 1 +#define EAXAGCCOMPRESSOR_DEFAULTONOFF 1 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Autowah Effect + +// EAX AUTOWAH {EC3130C0-AC7A-11D2-88DD-A024D13CE1} +DEFINE_GUID(EAX_AUTOWAH_EFFECT, + 0xec3130c0, + 0xac7a, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Autowah properties +typedef enum +{ + EAXAUTOWAH_NONE, + EAXAUTOWAH_ALLPARAMETERS, + EAXAUTOWAH_ATTACKTIME, + EAXAUTOWAH_RELEASETIME, + EAXAUTOWAH_RESONANCE, + EAXAUTOWAH_PEAKLEVEL +} EAXAUTOWAH_PROPERTY; + +// OR these flags with property id +#define EAXAUTOWAH_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXAUTOWAH_DEFERRED 0x80000000 // changes take effect later +#define EAXAUTOWAH_COMMITDEFERREDSETTINGS (EAXAUTOWAH_NONE | \ + EAXAUTOWAH_IMMEDIATE) + +// Use this structure for EAXAUTOWAH_ALLPARAMETERS +typedef struct _EAXAUTOWAHPROPERTIES +{ + float flAttackTime; // Attack time (seconds) + float flReleaseTime; // Release time (seconds) + long lResonance; // Resonance (mB) + long lPeakLevel; // Peak level (mB) +} EAXAUTOWAHPROPERTIES, *LPEAXAUTOWAHPROPERTIES; + +// Property ranges and defaults: + +#define EAXAUTOWAH_MINATTACKTIME 0.0001f +#define EAXAUTOWAH_MAXATTACKTIME 1.0f +#define EAXAUTOWAH_DEFAULTATTACKTIME 0.06f + +#define EAXAUTOWAH_MINRELEASETIME 0.0001f +#define EAXAUTOWAH_MAXRELEASETIME 1.0f +#define EAXAUTOWAH_DEFAULTRELEASETIME 0.06f + +#define EAXAUTOWAH_MINRESONANCE 600 +#define EAXAUTOWAH_MAXRESONANCE 6000 +#define EAXAUTOWAH_DEFAULTRESONANCE 6000 + +#define EAXAUTOWAH_MINPEAKLEVEL (-9000) +#define EAXAUTOWAH_MAXPEAKLEVEL 9000 +#define EAXAUTOWAH_DEFAULTPEAKLEVEL 2100 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Chorus Effect + +// EAX CHORUS {DE6D6FE0-AC79-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_CHORUS_EFFECT, + 0xde6d6fe0, + 0xac79, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + + +// Chorus properties +typedef enum +{ + EAXCHORUS_NONE, + EAXCHORUS_ALLPARAMETERS, + EAXCHORUS_WAVEFORM, + EAXCHORUS_PHASE, + EAXCHORUS_RATE, + EAXCHORUS_DEPTH, + EAXCHORUS_FEEDBACK, + EAXCHORUS_DELAY +} EAXCHORUS_PROPERTY; + +// OR these flags with property id +#define EAXCHORUS_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXCHORUS_DEFERRED 0x80000000 // changes take effect later +#define EAXCHORUS_COMMITDEFERREDSETTINGS (EAXCHORUS_NONE | \ + EAXCHORUS_IMMEDIATE) + +// used by EAXCHORUS_WAVEFORM +enum +{ + EAX_CHORUS_SINUSOID, + EAX_CHORUS_TRIANGLE +}; + +// Use this structure for EAXCHORUS_ALLPARAMETERS +typedef struct _EAXCHORUSPROPERTIES +{ + unsigned long ulWaveform; // Waveform selector - see enum above + long lPhase; // Phase (Degrees) + float flRate; // Rate (Hz) + float flDepth; // Depth (0 to 1) + float flFeedback; // Feedback (-1 to 1) + float flDelay; // Delay (seconds) +} EAXCHORUSPROPERTIES, *LPEAXCHORUSPROPERTIES; + +// Property ranges and defaults: + +#define EAXCHORUS_MINWAVEFORM 0 +#define EAXCHORUS_MAXWAVEFORM 1 +#define EAXCHORUS_DEFAULTWAVEFORM 1 + +#define EAXCHORUS_MINPHASE (-180) +#define EAXCHORUS_MAXPHASE 180 +#define EAXCHORUS_DEFAULTPHASE 90 + +#define EAXCHORUS_MINRATE 0.0f +#define EAXCHORUS_MAXRATE 10.0f +#define EAXCHORUS_DEFAULTRATE 1.1f + +#define EAXCHORUS_MINDEPTH 0.0f +#define EAXCHORUS_MAXDEPTH 1.0f +#define EAXCHORUS_DEFAULTDEPTH 0.1f + +#define EAXCHORUS_MINFEEDBACK (-1.0f) +#define EAXCHORUS_MAXFEEDBACK 1.0f +#define EAXCHORUS_DEFAULTFEEDBACK 0.25f + +#define EAXCHORUS_MINDELAY 0.0f +#define EAXCHORUS_MAXDELAY 0.016f +#define EAXCHORUS_DEFAULTDELAY 0.016f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Distortion Effect + +// EAX DISTORTION {975A4CE0-AC7E-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_DISTORTION_EFFECT, + 0x975a4ce0, + 0xac7e, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Distortion properties +typedef enum +{ + EAXDISTORTION_NONE, + EAXDISTORTION_ALLPARAMETERS, + EAXDISTORTION_EDGE, + EAXDISTORTION_GAIN, + EAXDISTORTION_LOWPASSCUTOFF, + EAXDISTORTION_EQCENTER, + EAXDISTORTION_EQBANDWIDTH +} EAXDISTORTION_PROPERTY; + +// OR these flags with property id +#define EAXDISTORTION_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXDISTORTION_DEFERRED 0x80000000 // changes take effect later +#define EAXDISTORTION_COMMITDEFERREDSETTINGS (EAXDISTORTION_NONE | \ + EAXDISTORTION_IMMEDIATE) + +// Use this structure for EAXDISTORTION_ALLPARAMETERS +typedef struct _EAXDISTORTIONPROPERTIES +{ + float flEdge; // Controls the shape of the distortion (0 to 1) + long lGain; // Controls the post distortion gain (mB) + float flLowPassCutOff; // Controls the cut-off of the filter pre-distortion (Hz) + float flEQCenter; // Controls the center frequency of the EQ post-distortion (Hz) + float flEQBandwidth; // Controls the bandwidth of the EQ post-distortion (Hz) +} EAXDISTORTIONPROPERTIES, *LPEAXDISTORTIONPROPERTIES; + +// Property ranges and defaults: + +#define EAXDISTORTION_MINEDGE 0.0f +#define EAXDISTORTION_MAXEDGE 1.0f +#define EAXDISTORTION_DEFAULTEDGE 0.2f + +#define EAXDISTORTION_MINGAIN (-6000) +#define EAXDISTORTION_MAXGAIN 0 +#define EAXDISTORTION_DEFAULTGAIN (-2600) + +#define EAXDISTORTION_MINLOWPASSCUTOFF 80.0f +#define EAXDISTORTION_MAXLOWPASSCUTOFF 24000.0f +#define EAXDISTORTION_DEFAULTLOWPASSCUTOFF 8000.0f + +#define EAXDISTORTION_MINEQCENTER 80.0f +#define EAXDISTORTION_MAXEQCENTER 24000.0f +#define EAXDISTORTION_DEFAULTEQCENTER 3600.0f + +#define EAXDISTORTION_MINEQBANDWIDTH 80.0f +#define EAXDISTORTION_MAXEQBANDWIDTH 24000.0f +#define EAXDISTORTION_DEFAULTEQBANDWIDTH 3600.0f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Echo Effect + +// EAX ECHO {E9F1BC0-AC82-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_ECHO_EFFECT, + 0xe9f1bc0, + 0xac82, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Echo properties +typedef enum +{ + EAXECHO_NONE, + EAXECHO_ALLPARAMETERS, + EAXECHO_DELAY, + EAXECHO_LRDELAY, + EAXECHO_DAMPING, + EAXECHO_FEEDBACK, + EAXECHO_SPREAD +} EAXECHO_PROPERTY; + +// OR these flags with property id +#define EAXECHO_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXECHO_DEFERRED 0x80000000 // changes take effect later +#define EAXECHO_COMMITDEFERREDSETTINGS (EAXECHO_NONE | \ + EAXECHO_IMMEDIATE) + +// Use this structure for EAXECHO_ALLPARAMETERS +typedef struct _EAXECHOPROPERTIES +{ + float flDelay; // Controls the initial delay time (seconds) + float flLRDelay; // Controls the delay time between the first and second taps (seconds) + float flDamping; // Controls a low-pass filter that dampens the echoes (0 to 1) + float flFeedback; // Controls the duration of echo repetition (0 to 1) + float flSpread; // Controls the left-right spread of the echoes +} EAXECHOPROPERTIES, *LPEAXECHOPROPERTIES; + +// Property ranges and defaults: + +#define EAXECHO_MINDAMPING 0.0f +#define EAXECHO_MAXDAMPING 0.99f +#define EAXECHO_DEFAULTDAMPING 0.5f + +#define EAXECHO_MINDELAY 0.0f +#define EAXECHO_MAXDELAY 0.207f +#define EAXECHO_DEFAULTDELAY 0.1f + +#define EAXECHO_MINLRDELAY 0.0f +#define EAXECHO_MAXLRDELAY 0.404f +#define EAXECHO_DEFAULTLRDELAY 0.1f + +#define EAXECHO_MINFEEDBACK 0.0f +#define EAXECHO_MAXFEEDBACK 1.0f +#define EAXECHO_DEFAULTFEEDBACK 0.5f + +#define EAXECHO_MINSPREAD (-1.0f) +#define EAXECHO_MAXSPREAD 1.0f +#define EAXECHO_DEFAULTSPREAD (-1.0f) + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Equalizer Effect + +// EAX EQUALIZER {65F94CE0-9793-11D3-939D-C0F02DD6F0} + +DEFINE_GUID(EAX_EQUALIZER_EFFECT, + 0x65f94ce0, + 0x9793, + 0x11d3, + 0x93, 0x9d, 0x0, 0xc0, 0xf0, 0x2d, 0xd6, 0xf0); + + +// Equalizer properties +typedef enum +{ + EAXEQUALIZER_NONE, + EAXEQUALIZER_ALLPARAMETERS, + EAXEQUALIZER_LOWGAIN, + EAXEQUALIZER_LOWCUTOFF, + EAXEQUALIZER_MID1GAIN, + EAXEQUALIZER_MID1CENTER, + EAXEQUALIZER_MID1WIDTH, + EAXEQUALIZER_MID2GAIN, + EAXEQUALIZER_MID2CENTER, + EAXEQUALIZER_MID2WIDTH, + EAXEQUALIZER_HIGHGAIN, + EAXEQUALIZER_HIGHCUTOFF +} EAXEQUALIZER_PROPERTY; + +// OR these flags with property id +#define EAXEQUALIZER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXEQUALIZER_DEFERRED 0x80000000 // changes take effect later +#define EAXEQUALIZER_COMMITDEFERREDSETTINGS (EAXEQUALIZER_NONE | \ + EAXEQUALIZER_IMMEDIATE) + +// Use this structure for EAXEQUALIZER_ALLPARAMETERS +typedef struct _EAXEQUALIZERPROPERTIES +{ + long lLowGain; // (mB) + float flLowCutOff; // (Hz) + long lMid1Gain; // (mB) + float flMid1Center; // (Hz) + float flMid1Width; // (octaves) + long lMid2Gain; // (mB) + float flMid2Center; // (Hz) + float flMid2Width; // (octaves) + long lHighGain; // (mB) + float flHighCutOff; // (Hz) +} EAXEQUALIZERPROPERTIES, *LPEAXEQUALIZERPROPERTIES; + +// Property ranges and defaults: + +#define EAXEQUALIZER_MINLOWGAIN (-1800) +#define EAXEQUALIZER_MAXLOWGAIN 1800 +#define EAXEQUALIZER_DEFAULTLOWGAIN 0 + +#define EAXEQUALIZER_MINLOWCUTOFF 50.0f +#define EAXEQUALIZER_MAXLOWCUTOFF 800.0f +#define EAXEQUALIZER_DEFAULTLOWCUTOFF 200.0f + +#define EAXEQUALIZER_MINMID1GAIN (-1800) +#define EAXEQUALIZER_MAXMID1GAIN 1800 +#define EAXEQUALIZER_DEFAULTMID1GAIN 0 + +#define EAXEQUALIZER_MINMID1CENTER 200.0f +#define EAXEQUALIZER_MAXMID1CENTER 3000.0f +#define EAXEQUALIZER_DEFAULTMID1CENTER 500.0f + +#define EAXEQUALIZER_MINMID1WIDTH 0.01f +#define EAXEQUALIZER_MAXMID1WIDTH 1.0f +#define EAXEQUALIZER_DEFAULTMID1WIDTH 1.0f + +#define EAXEQUALIZER_MINMID2GAIN (-1800) +#define EAXEQUALIZER_MAXMID2GAIN 1800 +#define EAXEQUALIZER_DEFAULTMID2GAIN 0 + +#define EAXEQUALIZER_MINMID2CENTER 1000.0f +#define EAXEQUALIZER_MAXMID2CENTER 8000.0f +#define EAXEQUALIZER_DEFAULTMID2CENTER 3000.0f + +#define EAXEQUALIZER_MINMID2WIDTH 0.01f +#define EAXEQUALIZER_MAXMID2WIDTH 1.0f +#define EAXEQUALIZER_DEFAULTMID2WIDTH 1.0f + +#define EAXEQUALIZER_MINHIGHGAIN (-1800) +#define EAXEQUALIZER_MAXHIGHGAIN 1800 +#define EAXEQUALIZER_DEFAULTHIGHGAIN 0 + +#define EAXEQUALIZER_MINHIGHCUTOFF 4000.0f +#define EAXEQUALIZER_MAXHIGHCUTOFF 16000.0f +#define EAXEQUALIZER_DEFAULTHIGHCUTOFF 6000.0f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Flanger Effect + +// EAX FLANGER {A70007C0-7D2-11D3-9B1E-A024D13CE1} + +DEFINE_GUID(EAX_FLANGER_EFFECT, + 0xa70007c0, + 0x7d2, + 0x11d3, + 0x9b, 0x1e, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Flanger properties +typedef enum +{ + EAXFLANGER_NONE, + EAXFLANGER_ALLPARAMETERS, + EAXFLANGER_WAVEFORM, + EAXFLANGER_PHASE, + EAXFLANGER_RATE, + EAXFLANGER_DEPTH, + EAXFLANGER_FEEDBACK, + EAXFLANGER_DELAY +} EAXFLANGER_PROPERTY; + +// OR these flags with property id +#define EAXFLANGER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXFLANGER_DEFERRED 0x80000000 // changes take effect later +#define EAXFLANGER_COMMITDEFERREDSETTINGS (EAXFLANGER_NONE | \ + EAXFLANGER_IMMEDIATE) + +// used by EAXFLANGER_WAVEFORM +enum +{ + EAX_FLANGER_SINUSOID, + EAX_FLANGER_TRIANGLE +}; + +// Use this structure for EAXFLANGER_ALLPARAMETERS +typedef struct _EAXFLANGERPROPERTIES +{ + unsigned long ulWaveform; // Waveform selector - see enum above + long lPhase; // Phase (Degrees) + float flRate; // Rate (Hz) + float flDepth; // Depth (0 to 1) + float flFeedback; // Feedback (0 to 1) + float flDelay; // Delay (seconds) +} EAXFLANGERPROPERTIES, *LPEAXFLANGERPROPERTIES; + +// Property ranges and defaults: + +#define EAXFLANGER_MINWAVEFORM 0 +#define EAXFLANGER_MAXWAVEFORM 1 +#define EAXFLANGER_DEFAULTWAVEFORM 1 + +#define EAXFLANGER_MINPHASE (-180) +#define EAXFLANGER_MAXPHASE 180 +#define EAXFLANGER_DEFAULTPHASE 0 + +#define EAXFLANGER_MINRATE 0.0f +#define EAXFLANGER_MAXRATE 10.0f +#define EAXFLANGER_DEFAULTRATE 0.27f + +#define EAXFLANGER_MINDEPTH 0.0f +#define EAXFLANGER_MAXDEPTH 1.0f +#define EAXFLANGER_DEFAULTDEPTH 1.0f + +#define EAXFLANGER_MINFEEDBACK (-1.0f) +#define EAXFLANGER_MAXFEEDBACK 1.0f +#define EAXFLANGER_DEFAULTFEEDBACK (-0.5f) + +#define EAXFLANGER_MINDELAY 0.0f +#define EAXFLANGER_MAXDELAY 0.004f +#define EAXFLANGER_DEFAULTDELAY 0.002f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Frequency Shifter Effect + +// EAX FREQUENCY SHIFTER {DC3E1880-9212-11D3-939D-C0F02DD6F0} + +DEFINE_GUID(EAX_FREQUENCYSHIFTER_EFFECT, + 0xdc3e1880, + 0x9212, + 0x11d3, + 0x93, 0x9d, 0x0, 0xc0, 0xf0, 0x2d, 0xd6, 0xf0); + +// Frequency Shifter properties +typedef enum +{ + EAXFREQUENCYSHIFTER_NONE, + EAXFREQUENCYSHIFTER_ALLPARAMETERS, + EAXFREQUENCYSHIFTER_FREQUENCY, + EAXFREQUENCYSHIFTER_LEFTDIRECTION, + EAXFREQUENCYSHIFTER_RIGHTDIRECTION +} EAXFREQUENCYSHIFTER_PROPERTY; + +// OR these flags with property id +#define EAXFREQUENCYSHIFTER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXFREQUENCYSHIFTER_DEFERRED 0x80000000 // changes take effect later +#define EAXFREQUENCYSHIFTER_COMMITDEFERREDSETTINGS (EAXFREQUENCYSHIFTER_NONE | \ + EAXFREQUENCYSHIFTER_IMMEDIATE) + +// used by EAXFREQUENCYSHIFTER_LEFTDIRECTION and EAXFREQUENCYSHIFTER_RIGHTDIRECTION +enum +{ + EAX_FREQUENCYSHIFTER_DOWN, + EAX_FREQUENCYSHIFTER_UP, + EAX_FREQUENCYSHIFTER_OFF +}; + +// Use this structure for EAXFREQUENCYSHIFTER_ALLPARAMETERS +typedef struct _EAXFREQUENCYSHIFTERPROPERTIES +{ + float flFrequency; // (Hz) + unsigned long ulLeftDirection; // see enum above + unsigned long ulRightDirection; // see enum above +} EAXFREQUENCYSHIFTERPROPERTIES, *LPEAXFREQUENCYSHIFTERPROPERTIES; + +// Property ranges and defaults: + +#define EAXFREQUENCYSHIFTER_MINFREQUENCY 0.0f +#define EAXFREQUENCYSHIFTER_MAXFREQUENCY 24000.0f +#define EAXFREQUENCYSHIFTER_DEFAULTFREQUENCY 0.0f + +#define EAXFREQUENCYSHIFTER_MINLEFTDIRECTION 0 +#define EAXFREQUENCYSHIFTER_MAXLEFTDIRECTION 2 +#define EAXFREQUENCYSHIFTER_DEFAULTLEFTDIRECTION 0 + +#define EAXFREQUENCYSHIFTER_MINRIGHTDIRECTION 0 +#define EAXFREQUENCYSHIFTER_MAXRIGHTDIRECTION 2 +#define EAXFREQUENCYSHIFTER_DEFAULTRIGHTDIRECTION 0 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Vocal Morpher Effect + +// EAX VOCAL MORPHER {E41CF10C-3383-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_VOCALMORPHER_EFFECT, + 0xe41cf10c, + 0x3383, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Vocal Morpher properties +typedef enum +{ + EAXVOCALMORPHER_NONE, + EAXVOCALMORPHER_ALLPARAMETERS, + EAXVOCALMORPHER_PHONEMEA, + EAXVOCALMORPHER_PHONEMEACOARSETUNING, + EAXVOCALMORPHER_PHONEMEB, + EAXVOCALMORPHER_PHONEMEBCOARSETUNING, + EAXVOCALMORPHER_WAVEFORM, + EAXVOCALMORPHER_RATE +} EAXVOCALMORPHER_PROPERTY; + +// OR these flags with property id +#define EAXVOCALMORPHER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXVOCALMORPHER_DEFERRED 0x80000000 // changes take effect later +#define EAXVOCALMORPHER_COMMITDEFERREDSETTINGS (EAXVOCALMORPHER_NONE | \ + EAXVOCALMORPHER_IMMEDIATE) + +// used by EAXVOCALMORPHER_PHONEMEA and EAXVOCALMORPHER_PHONEMEB +enum +{ + A, E, I, O, U, AA, AE, AH, AO, EH, ER, IH, IY, UH, UW, B, D, F, G, + J, K, L, M, N, P, R, S, T, V, Z +}; + +// used by EAXVOCALMORPHER_WAVEFORM +enum +{ + EAX_VOCALMORPHER_SINUSOID, + EAX_VOCALMORPHER_TRIANGLE, + EAX_VOCALMORPHER_SAWTOOTH +}; + +// Use this structure for EAXVOCALMORPHER_ALLPARAMETERS +typedef struct _EAXVOCALMORPHERPROPERTIES +{ + unsigned long ulPhonemeA; // see enum above + long lPhonemeACoarseTuning; // (semitones) + unsigned long ulPhonemeB; // see enum above + long lPhonemeBCoarseTuning; // (semitones) + unsigned long ulWaveform; // Waveform selector - see enum above + float flRate; // (Hz) +} EAXVOCALMORPHERPROPERTIES, *LPEAXVOCALMORPHERPROPERTIES; + +// Property ranges and defaults: + +#define EAXVOCALMORPHER_MINPHONEMEA 0 +#define EAXVOCALMORPHER_MAXPHONEMEA 29 +#define EAXVOCALMORPHER_DEFAULTPHONEMEA 0 + +#define EAXVOCALMORPHER_MINPHONEMEACOARSETUNING (-24) +#define EAXVOCALMORPHER_MAXPHONEMEACOARSETUNING 24 +#define EAXVOCALMORPHER_DEFAULTPHONEMEACOARSETUNING 0 + +#define EAXVOCALMORPHER_MINPHONEMEB 0 +#define EAXVOCALMORPHER_MAXPHONEMEB 29 +#define EAXVOCALMORPHER_DEFAULTPHONEMEB 10 + +#define EAXVOCALMORPHER_MINPHONEMEBCOARSETUNING (-24) +#define EAXVOCALMORPHER_MAXPHONEMEBCOARSETUNING 24 +#define EAXVOCALMORPHER_DEFAULTPHONEMEBCOARSETUNING 0 + +#define EAXVOCALMORPHER_MINWAVEFORM 0 +#define EAXVOCALMORPHER_MAXWAVEFORM 2 +#define EAXVOCALMORPHER_DEFAULTWAVEFORM 0 + +#define EAXVOCALMORPHER_MINRATE 0.0f +#define EAXVOCALMORPHER_MAXRATE 10.0f +#define EAXVOCALMORPHER_DEFAULTRATE 1.41f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Pitch Shifter Effect + +// EAX PITCH SHIFTER {E7905100-AFB2-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_PITCHSHIFTER_EFFECT, + 0xe7905100, + 0xafb2, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Pitch Shifter properties +typedef enum +{ + EAXPITCHSHIFTER_NONE, + EAXPITCHSHIFTER_ALLPARAMETERS, + EAXPITCHSHIFTER_COARSETUNE, + EAXPITCHSHIFTER_FINETUNE +} EAXPITCHSHIFTER_PROPERTY; + +// OR these flags with property id +#define EAXPITCHSHIFTER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXPITCHSHIFTER_DEFERRED 0x80000000 // changes take effect later +#define EAXPITCHSHIFTER_COMMITDEFERREDSETTINGS (EAXPITCHSHIFTER_NONE | \ + EAXPITCHSHIFTER_IMMEDIATE) + +// Use this structure for EAXPITCHSHIFTER_ALLPARAMETERS +typedef struct _EAXPITCHSHIFTERPROPERTIES +{ + long lCoarseTune; // Amount of pitch shift (semitones) + long lFineTune; // Amount of pitch shift (cents) +} EAXPITCHSHIFTERPROPERTIES, *LPEAXPITCHSHIFTERPROPERTIES; + +// Property ranges and defaults: + +#define EAXPITCHSHIFTER_MINCOARSETUNE (-12) +#define EAXPITCHSHIFTER_MAXCOARSETUNE 12 +#define EAXPITCHSHIFTER_DEFAULTCOARSETUNE 12 + +#define EAXPITCHSHIFTER_MINFINETUNE (-50) +#define EAXPITCHSHIFTER_MAXFINETUNE 50 +#define EAXPITCHSHIFTER_DEFAULTFINETUNE 0 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Ring Modulator Effect + +// EAX RING MODULATOR {B89FE60-AFB5-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_RINGMODULATOR_EFFECT, + 0xb89fe60, + 0xafb5, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Ring Modulator properties +typedef enum +{ + EAXRINGMODULATOR_NONE, + EAXRINGMODULATOR_ALLPARAMETERS, + EAXRINGMODULATOR_FREQUENCY, + EAXRINGMODULATOR_HIGHPASSCUTOFF, + EAXRINGMODULATOR_WAVEFORM +} EAXRINGMODULATOR_PROPERTY; + +// OR these flags with property id +#define EAXRINGMODULATOR_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXRINGMODULATOR_DEFERRED 0x80000000 // changes take effect later +#define EAXRINGMODULATOR_COMMITDEFERREDSETTINGS (EAXRINGMODULATOR_NONE | \ + EAXRINGMODULATOR_IMMEDIATE) + +// used by EAXRINGMODULATOR_WAVEFORM +enum +{ + EAX_RINGMODULATOR_SINUSOID, + EAX_RINGMODULATOR_SAWTOOTH, + EAX_RINGMODULATOR_SQUARE +}; + +// Use this structure for EAXRINGMODULATOR_ALLPARAMETERS +typedef struct _EAXRINGMODULATORPROPERTIES +{ + float flFrequency; // Frequency of modulation (Hz) + float flHighPassCutOff; // Cut-off frequency of high-pass filter (Hz) + unsigned long ulWaveform; // Waveform selector - see enum above +} EAXRINGMODULATORPROPERTIES, *LPEAXRINGMODULATORPROPERTIES; + +// Property ranges and defaults: + +#define EAXRINGMODULATOR_MINFREQUENCY 0.0f +#define EAXRINGMODULATOR_MAXFREQUENCY 8000.0f +#define EAXRINGMODULATOR_DEFAULTFREQUENCY 440.0f + +#define EAXRINGMODULATOR_MINHIGHPASSCUTOFF 0.0f +#define EAXRINGMODULATOR_MAXHIGHPASSCUTOFF 24000.0f +#define EAXRINGMODULATOR_DEFAULTHIGHPASSCUTOFF 800.0f + +#define EAXRINGMODULATOR_MINWAVEFORM 0 +#define EAXRINGMODULATOR_MAXWAVEFORM 2 +#define EAXRINGMODULATOR_DEFAULTWAVEFORM 0 + +//////////////////////////////////////////////////////////////////////////// + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif diff --git a/openal/include/eax5.h b/openal/include/eax5.h new file mode 100644 index 000000000..e4cba6d93 --- /dev/null +++ b/openal/include/eax5.h @@ -0,0 +1,1792 @@ +/*******************************************************************\ +* * +* EAX.H - Environmental Audio Extensions version 5.0 * +* for OpenAL and DirectSound3D * +* * +* File revision 0.9.6 version a (July 14th 2004) * +* EAX 5.0 API Spec version 1.5 * +* * +\*******************************************************************/ + +#ifndef EAX_H_INCLUDED +#define EAX_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef OPENAL + #include + + /* + * EAX Unified Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5} + */ + DEFINE_GUID(CLSID_EAXDirectSound, + 0x4ff53b81, + 0x1ce0, + 0x11d3, + 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5); + + /* + * EAX Unified Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C} + */ + DEFINE_GUID(CLSID_EAXDirectSound8, + 0xca503b60, + 0xb176, + 0x11d4, + 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc); + + + +#ifdef DIRECTSOUND_VERSION +#if DIRECTSOUND_VERSION >= 0x0800 + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*); +#endif +#endif + + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); + +#else // OPENAL + #include + + #ifndef GUID_DEFINED + #define GUID_DEFINED + typedef struct _GUID + { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + } GUID; + #endif // GUID_DEFINED + + #ifndef DEFINE_GUID + #ifndef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID /*FAR*/ name + #else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + #endif // INITGUID + #endif // DEFINE_GUID + + /* + * EAX OpenAL Extensions + */ + typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALboolean (*EAXSetBufferMode)(ALsizei, ALuint*, ALint); + typedef ALenum (*EAXGetBufferMode)(ALuint, ALint*); +#endif + +#pragma pack(push, 4) + + + + +//////////////////////////////////////////////////////////////////////////// +// Constants + +#define EAX_MAX_FXSLOTS 4 +#define EAX_MAX_ACTIVE_FXSLOTS 4 + +// The EAX_NULL_GUID is used by EAXFXSLOT_LOADEFFECT, EAXCONTEXT_PRIMARYFXSLOTID +// and EAXSOURCE_ACTIVEFXSLOTID + +// {00000000-0000-0000-0000-000000000000} +DEFINE_GUID(EAX_NULL_GUID, + 0x00000000, + 0x0000, + 0x0000, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +// The EAX_PrimaryFXSlotID GUID is used by EAXSOURCE_ACTIVEFXSLOTID +// {F317866D-924C-450C-861B-E6DAA25E7C20} +DEFINE_GUID(EAX_PrimaryFXSlotID, + 0xf317866d, + 0x924c, + 0x450c, + 0x86, 0x1b, 0xe6, 0xda, 0xa2, 0x5e, 0x7c, 0x20); + + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Structures + +// Use this structure for EAXCONTEXT_EAXSESSION property +#ifndef EAXSESSIONPROPERTIES_DEFINED +#define EAXSESSIONPROPERTIES_DEFINED +typedef struct _EAXSESSIONPROPERTIES +{ + unsigned long ulEAXVersion; + unsigned long ulMaxActiveSends; +} EAXSESSIONPROPERTIES, *LPEAXSESSIONPROPERTIES; +#endif + +// Use this structure for EAXCONTEXT_ALL property. +#ifndef EAXCONTEXTPROPERTIES_DEFINED +#define EAXCONTEXTPROPERTIES_DEFINED +typedef struct _EAXCONTEXTPROPERTIES +{ + GUID guidPrimaryFXSlotID; + float flDistanceFactor; + float flAirAbsorptionHF; + float flHFReference; + float flMacroFXFactor; +} EAXCONTEXTPROPERTIES, *LPEAXCONTEXTPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXSOURCEFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +#ifndef EAXSOURCEPROPERTIES_DEFINED +#define EAXSOURCEPROPERTIES_DEFINED +typedef struct _EAXSOURCEPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lObstruction; // main obstruction control (attenuation at high frequencies) + float flObstructionLFRatio; // obstruction low-frequency level re. main control + long lOcclusion; // main occlusion control (attenuation at high frequencies) + float flOcclusionLFRatio; // occlusion low-frequency level re. main control + float flOcclusionRoomRatio; // relative occlusion control for room effect + float flOcclusionDirectRatio; // relative occlusion control for direct path + long lExclusion; // main exlusion control (attenuation at high frequencies) + float flExclusionLFRatio; // exclusion low-frequency level re. main control + long lOutsideVolumeHF; // outside sound cone level at high frequencies + float flDopplerFactor; // like DS3D flDopplerFactor but per source + float flRolloffFactor; // like DS3D flRolloffFactor but per source + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + float flAirAbsorptionFactor; // multiplies EAXREVERB_AIRABSORPTIONHF + unsigned long ulFlags; // modifies the behavior of properties + float flMacroFXFactor; //###TODO### add comment here +} EAXSOURCEPROPERTIES, *LPEAXSOURCEPROPERTIES; +#endif + + +// Use this structure for EAXSOURCE_ALL2DPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXSOURCEFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +#ifndef EAXSOURCE2DPROPERTIES_DEFINED +#define EAXSOURCE2DPROPERTIES_DEFINED +typedef struct _EAXSOURCE2DPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + unsigned long ulFlags; // modifies the behavior of properties +} EAXSOURCE2DPROPERTIES, *LPEAXSOURCE2DPROPERTIES; +#endif + + +// Use this structure for EAXSOURCE_ALLSENDPARAMETERS +// - all levels are hundredths of decibels +// +#ifndef EAXSOURCEALLSENDPROPERTIES_DEFINED +#define EAXSOURCEALLSENDPROPERTIES_DEFINED +typedef struct _EAXSOURCEALLSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lSend; // send level (at low and mid frequencies) + long lSendHF; // relative send level at high frequencies + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; + long lExclusion; + float flExclusionLFRatio; +} EAXSOURCEALLSENDPROPERTIES, *LPEAXSOURCEALLSENDPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_SPEAKERLEVELS +// - level is in hundredths of decibels +// +#ifndef EAXSPEAKERLEVELPROPERTIES_DEFINED +#define EAXSPEAKERLEVELPROPERTIES_DEFINED +typedef struct _EAXSPEAKERLEVELPROPERTIES +{ + long lSpeakerID; + long lLevel; +} EAXSPEAKERLEVELPROPERTIES, *LPEAXSPEAKERLEVELPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_ACTIVEFXSLOTID +#ifndef EAXACTIVEFXSLOTS_DEFINED +#define EAXACTIVEFXSLOTS_DEFINED +typedef struct _EAXACTIVEFXSLOTS +{ + GUID guidActiveFXSlots[EAX_MAX_ACTIVE_FXSLOTS]; +} EAXACTIVEFXSLOTS, *LPEAXACTIVEFXSLOTS; +#endif + +// Use this structure for EAXSOURCE_OBSTRUCTIONPARAMETERS property. +#ifndef EAXOBSTRUCTIONPROPERTIES_DEFINED +#define EAXOBSTRUCTIONPROPERTIES_DEFINED +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_OCCLUSIONPARAMETERS property. +#ifndef EAXOCCLUSIONPROPERTIES_DEFINED +#define EAXOCCLUSIONPROPERTIES_DEFINED +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_EXCLUSIONPARAMETERS property. +#ifndef EAXEXCLUSIONPROPERTIES_DEFINED +#define EAXEXCLUSIONPROPERTIES_DEFINED +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_SENDPARAMETERS properties. +#ifndef EAXSOURCESENDPROPERTIES_DEFINED +#define EAXSOURCESENDPROPERTIES_DEFINED +typedef struct _EAXSOURCESENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lSend; + long lSendHF; +} EAXSOURCESENDPROPERTIES, *LPEAXSOURCESENDPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_OCCLUSIONSENDPARAMETERS +#ifndef EAXSOURCEOCCLUSIONSENDPROPERTIES_DEFINED +#define EAXSOURCEOCCLUSIONSENDPROPERTIES_DEFINED +typedef struct _EAXSOURCEOCCLUSIONSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXSOURCEOCCLUSIONSENDPROPERTIES, *LPEAXSOURCEOCCLUSIONSENDPROPERTIES; +#endif + +// Use this structure for EAXSOURCE_EXCLUSIONSENDPARAMETERS +#ifndef EAXSOURCEEXCLUSIONSENDPROPERTIES_DEFINED +#define EAXSOURCEEXCLUSIONSENDPROPERTIES_DEFINED +typedef struct _EAXSOURCEEXCLUSIONSENDPROPERTIES +{ + GUID guidReceivingFXSlotID; + long lExclusion; + float flExclusionLFRatio; +} EAXSOURCEEXCLUSIONSENDPROPERTIES, *LPEAXSOURCEEXCLUSIONSENDPROPERTIES; +#endif + +// Use this structure for EAXFXSLOT_ALLPARAMETERS +// - all levels are hundredths of decibels +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myFXSlot.guidLoadEffect = EAX_REVERB_EFFECT; +// myFXSlot.lVolume = 0; +// myFXSlot.lLock = 1; +// myFXSlot.ulFlags = myFlags /* see EAXFXSLOTFLAGS below */ ; +// instead of: +// myFXSlot = { EAX_REVERB_EFFECT, 0, 1, 0x00000001 }; +// +#ifndef EAXFXSLOTPROPERTIES_DEFINED +#define EAXFXSLOTPROPERTIES_DEFINED +typedef struct _EAXFXSLOTPROPERTIES +{ + GUID guidLoadEffect; + long lVolume; + long lLock; + unsigned long ulFlags; + long lOcclusion; + float flOcclusionLFRatio; +} EAXFXSLOTPROPERTIES, *LPEAXFXSLOTPROPERTIES; +#endif + + +// Use this structure for EAXREVERB_REFLECTIONSPAN and EAXREVERB_REVERBPAN properties. +#ifndef EAXVECTOR_DEFINED +#define EAXVECTOR_DEFINED +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; +#endif + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Error Codes + +#define EAX_OK 0 +#define EAXERR_INVALID_OPERATION (-1) +#define EAXERR_INVALID_VALUE (-2) +#define EAXERR_NO_EFFECT_LOADED (-3) +#define EAXERR_UNKNOWN_EFFECT (-4) +#define EAXERR_INCOMPATIBLE_SOURCE_TYPE (-5) +#define EAXERR_INCOMPATIBLE_EAX_VERSION (-6) +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Context Object + +// {57E13437-B932-4ab2-B8BD-5266C1A887EE} +DEFINE_GUID(EAXPROPERTYID_EAX50_Context, + 0x57e13437, + 0xb932, + 0x4ab2, + 0xb8, 0xbd, 0x52, 0x66, 0xc1, 0xa8, 0x87, 0xee); + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_Context EAXPROPERTYID_EAX50_Context + +typedef enum +{ + EAXCONTEXT_NONE = 0, + EAXCONTEXT_ALLPARAMETERS, + EAXCONTEXT_PRIMARYFXSLOTID, + EAXCONTEXT_DISTANCEFACTOR, + EAXCONTEXT_AIRABSORPTIONHF, + EAXCONTEXT_HFREFERENCE, + EAXCONTEXT_LASTERROR, + EAXCONTEXT_SPEAKERCONFIG, + EAXCONTEXT_EAXSESSION, + EAXCONTEXT_MACROFXFACTOR +} EAXCONTEXT_PROPERTY; + +// OR these flags with property id +#define EAXCONTEXT_PARAMETER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXCONTEXT_PARAMETER_DEFER 0x80000000 // changes take effect later +#define EAXCONTEXT_PARAMETER_COMMITDEFERREDSETTINGS (EAXCONTEXT_NONE | \ + EAXCONTEXT_PARAMETER_IMMEDIATE) + +// EAX Context property ranges and defaults: +#define EAXCONTEXT_DEFAULTPRIMARYFXSLOTID EAXPROPERTYID_EAX50_FXSlot0 + +#define EAXCONTEXT_MINDISTANCEFACTOR FLT_MIN //minimum positive value +#define EAXCONTEXT_MAXDISTANCEFACTOR FLT_MAX +#define EAXCONTEXT_DEFAULTDISTANCEFACTOR 1.0f + +#define EAXCONTEXT_MINAIRABSORPTIONHF (-100.0f) +#define EAXCONTEXT_MAXAIRABSORPTIONHF 0.0f +#define EAXCONTEXT_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXCONTEXT_MINHFREFERENCE 1000.0f +#define EAXCONTEXT_MAXHFREFERENCE 20000.0f +#define EAXCONTEXT_DEFAULTHFREFERENCE 5000.0f + +#define EAXCONTEXT_DEFAULTLASTERROR EAX_OK + +enum { + HEADPHONES = 0, + SPEAKERS_2, + SPEAKERS_4, + SPEAKERS_5, // 5.1 speakers + SPEAKERS_6, // 6.1 speakers + SPEAKERS_7, // 7.1 speakers +}; + +enum { + EAX_40 = 5, // EAX 4.0 + EAX_50 = 6, // EAX 5.0 +}; + +// min,max, default values for ulEAXVersion in struct EAXSESSIONPROPERTIES +#define EAXCONTEXT_MINEAXSESSION EAX_40 +#define EAXCONTEXT_MAXEAXSESSION EAX_50 +#define EAXCONTEXT_DEFAULTEAXSESSION EAX_40 + +// min,max, default values for ulMaxActiveSends in struct EAXSESSIONPROPERTIES +#define EAXCONTEXT_MINMAXACTIVESENDS 2 +#define EAXCONTEXT_MAXMAXACTIVESENDS 4 +#define EAXCONTEXT_DEFAULTMAXACTIVESENDS 2 + +#define EAXCONTEXT_MINMACROFXFACTOR 0.0f +#define EAXCONTEXT_MAXMACROFXFACTOR 1.0f +#define EAXCONTEXT_DEFAULTMACROFXFACTOR 0.0f + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Effect Slot Objects + +// {91F9590F-C388-407a-84B0-1BAE0EF71ABC} +DEFINE_GUID(EAXPROPERTYID_EAX50_FXSlot0, + 0x91f9590f, + 0xc388, + 0x407a, + 0x84, 0xb0, 0x1b, 0xae, 0xe, 0xf7, 0x1a, 0xbc); + +// {8F5F7ACA-9608-4965-8137-8213C7B9D9DE} +DEFINE_GUID(EAXPROPERTYID_EAX50_FXSlot1, + 0x8f5f7aca, + 0x9608, + 0x4965, + 0x81, 0x37, 0x82, 0x13, 0xc7, 0xb9, 0xd9, 0xde); + +// {3C0F5252-9834-46f0-A1D8-5B95C4A00A30} +DEFINE_GUID(EAXPROPERTYID_EAX50_FXSlot2, + 0x3c0f5252, + 0x9834, + 0x46f0, + 0xa1, 0xd8, 0x5b, 0x95, 0xc4, 0xa0, 0xa, 0x30); + +// {E2EB0EAA-E806-45e7-9F86-06C1571A6FA3} +DEFINE_GUID(EAXPROPERTYID_EAX50_FXSlot3, + 0xe2eb0eaa, + 0xe806, + 0x45e7, + 0x9f, 0x86, 0x6, 0xc1, 0x57, 0x1a, 0x6f, 0xa3); + + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_FXSlot0 EAXPROPERTYID_EAX50_FXSlot0 +#define EAXPROPERTYID_EAX_FXSlot1 EAXPROPERTYID_EAX50_FXSlot1 +#define EAXPROPERTYID_EAX_FXSlot2 EAXPROPERTYID_EAX50_FXSlot2 +#define EAXPROPERTYID_EAX_FXSlot3 EAXPROPERTYID_EAX50_FXSlot3 + +// FXSlot object properties +typedef enum +{ + EAXFXSLOT_PARAMETER = 0, // range 0-0x40 reserved for loaded effect parameters + EAXFXSLOT_NONE = 0x10000, + EAXFXSLOT_ALLPARAMETERS, + EAXFXSLOT_LOADEFFECT, + EAXFXSLOT_VOLUME, + EAXFXSLOT_LOCK, + EAXFXSLOT_FLAGS, + EAXFXSLOT_OCCLUSION, + EAXFXSLOT_OCCLUSIONLFRATIO +} EAXFXSLOT_PROPERTY; + +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXFXSLOTFLAGS_ENVIRONMENT; +// instead of: +// myFlags = 0x00000001; +// +#define EAXFXSLOTFLAGS_ENVIRONMENT 0x00000001 +#define EAXFXSLOTFLAGS_UPMIX 0x00000002 +#define EAXFXSLOTFLAGS_RESERVED 0xFFFFFFFC // reserved future use + +// EAX Effect Slot property ranges and defaults: +#define EAXFXSLOT_MINVOLUME (-10000) +#define EAXFXSLOT_MAXVOLUME 0 +#define EAXFXSLOT_DEFAULTVOLUME 0 + +enum +{ + EAXFXSLOT_UNLOCKED = 0, + EAXFXSLOT_LOCKED = 1 +}; + +#define EAXFXSLOT_MINLOCK 0 +#define EAXFXSLOT_MAXLOCK 1 + +#define EAXFXSLOT_MINOCCLUSION (-10000) +#define EAXFXSLOT_MAXOCCLUSION 0 +#define EAXFXSLOT_DEFAULTOCCLUSION 0 + +#define EAXFXSLOT_MINOCCLUSIONLFRATIO 0.0f +#define EAXFXSLOT_MAXOCCLUSIONLFRATIO 1.0f +#define EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXFXSLOT_DEFAULTFLAGS (EAXFXSLOTFLAGS_ENVIRONMENT | \ + EAXFXSLOTFLAGS_UPMIX ) // ignored for reverb +//////////////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////////////// +// Source Object + +// {5EDF82F0-24A7-4f38-8E64-2F09CA05DEE1} +DEFINE_GUID(EAXPROPERTYID_EAX50_Source, + 0x5edf82f0, + 0x24a7, + 0x4f38, + 0x8e, 0x64, 0x2f, 0x9, 0xca, 0x5, 0xde, 0xe1); + + +// For compatibility with future EAX versions: +#define EAXPROPERTYID_EAX_Source EAXPROPERTYID_EAX50_Source + +// Source object properties +typedef enum +{ + EAXSOURCE_NONE, + EAXSOURCE_ALLPARAMETERS, + EAXSOURCE_OBSTRUCTIONPARAMETERS, + EAXSOURCE_OCCLUSIONPARAMETERS, + EAXSOURCE_EXCLUSIONPARAMETERS, + EAXSOURCE_DIRECT, + EAXSOURCE_DIRECTHF, + EAXSOURCE_ROOM, + EAXSOURCE_ROOMHF, + EAXSOURCE_OBSTRUCTION, + EAXSOURCE_OBSTRUCTIONLFRATIO, + EAXSOURCE_OCCLUSION, + EAXSOURCE_OCCLUSIONLFRATIO, + EAXSOURCE_OCCLUSIONROOMRATIO, + EAXSOURCE_OCCLUSIONDIRECTRATIO, + EAXSOURCE_EXCLUSION, + EAXSOURCE_EXCLUSIONLFRATIO, + EAXSOURCE_OUTSIDEVOLUMEHF, + EAXSOURCE_DOPPLERFACTOR, + EAXSOURCE_ROLLOFFFACTOR, + EAXSOURCE_ROOMROLLOFFFACTOR, + EAXSOURCE_AIRABSORPTIONFACTOR, + EAXSOURCE_FLAGS, + EAXSOURCE_SENDPARAMETERS, + EAXSOURCE_ALLSENDPARAMETERS, + EAXSOURCE_OCCLUSIONSENDPARAMETERS, + EAXSOURCE_EXCLUSIONSENDPARAMETERS, + EAXSOURCE_ACTIVEFXSLOTID, + EAXSOURCE_MACROFXFACTOR, + EAXSOURCE_SPEAKERLEVELS, + EAXSOURCE_ALL2DPARAMETERS, +} EAXSOURCE_PROPERTY; + +// OR these flags with property id +#define EAXSOURCE_PARAMETER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXSOURCE_PARAMETER_DEFERRED 0x80000000 // changes take effect later +#define EAXSOURCE_PARAMETER_COMMITDEFERREDSETTINGS (EAXSOURCE_NONE | \ + EAXSOURCE_PARAMETER_IMMEDIATE) +// Used by EAXSOURCE_FLAGS for EAXSOURCEFLAGS_xxxAUTO +// TRUE: value is computed automatically - property is an offset +// FALSE: value is used directly +// +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXSOURCE_DIRECTHFAUTO | EAXSOURCE_ROOMAUTO; +// instead of: +// myFlags = 0x00000003; +// +#define EAXSOURCEFLAGS_DIRECTHFAUTO 0x00000001 // relates to EAXSOURCE_DIRECTHF +#define EAXSOURCEFLAGS_ROOMAUTO 0x00000002 // relates to EAXSOURCE_ROOM +#define EAXSOURCEFLAGS_ROOMHFAUTO 0x00000004 // relates to EAXSOURCE_ROOMHF +#define EAXSOURCEFLAGS_3DELEVATIONFILTER 0x00000008 +#define EAXSOURCEFLAGS_UPMIX 0x00000010 +#define EAXSOURCEFLAGS_APPLYSPEAKERLEVELS 0x00000020 +#define EAXSOURCEFLAGS_RESERVED 0xFFFFFFC0 // reserved future use + +// EAX Source property ranges and defaults: +#define EAXSOURCE_MINSEND (-10000) +#define EAXSOURCE_MAXSEND 0 +#define EAXSOURCE_DEFAULTSEND 0 + +#define EAXSOURCE_MINSENDHF (-10000) +#define EAXSOURCE_MAXSENDHF 0 +#define EAXSOURCE_DEFAULTSENDHF 0 + +#define EAXSOURCE_MINDIRECT (-10000) +#define EAXSOURCE_MAXDIRECT 1000 +#define EAXSOURCE_DEFAULTDIRECT 0 + +#define EAXSOURCE_MINDIRECTHF (-10000) +#define EAXSOURCE_MAXDIRECTHF 0 +#define EAXSOURCE_DEFAULTDIRECTHF 0 + +#define EAXSOURCE_MINROOM (-10000) +#define EAXSOURCE_MAXROOM 1000 +#define EAXSOURCE_DEFAULTROOM 0 + +#define EAXSOURCE_MINROOMHF (-10000) +#define EAXSOURCE_MAXROOMHF 0 +#define EAXSOURCE_DEFAULTROOMHF 0 + +#define EAXSOURCE_MINOBSTRUCTION (-10000) +#define EAXSOURCE_MAXOBSTRUCTION 0 +#define EAXSOURCE_DEFAULTOBSTRUCTION 0 + +#define EAXSOURCE_MINOBSTRUCTIONLFRATIO 0.0f +#define EAXSOURCE_MAXOBSTRUCTIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTOBSTRUCTIONLFRATIO 0.0f + +#define EAXSOURCE_MINOCCLUSION (-10000) +#define EAXSOURCE_MAXOCCLUSION 0 +#define EAXSOURCE_DEFAULTOCCLUSION 0 + +#define EAXSOURCE_MINOCCLUSIONLFRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXSOURCE_MINOCCLUSIONROOMRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONROOMRATIO 10.0f +#define EAXSOURCE_DEFAULTOCCLUSIONROOMRATIO 1.5f + +#define EAXSOURCE_MINOCCLUSIONDIRECTRATIO 0.0f +#define EAXSOURCE_MAXOCCLUSIONDIRECTRATIO 10.0f +#define EAXSOURCE_DEFAULTOCCLUSIONDIRECTRATIO 1.0f + +#define EAXSOURCE_MINEXCLUSION (-10000) +#define EAXSOURCE_MAXEXCLUSION 0 +#define EAXSOURCE_DEFAULTEXCLUSION 0 + +#define EAXSOURCE_MINEXCLUSIONLFRATIO 0.0f +#define EAXSOURCE_MAXEXCLUSIONLFRATIO 1.0f +#define EAXSOURCE_DEFAULTEXCLUSIONLFRATIO 1.0f + +#define EAXSOURCE_MINOUTSIDEVOLUMEHF (-10000) +#define EAXSOURCE_MAXOUTSIDEVOLUMEHF 0 +#define EAXSOURCE_DEFAULTOUTSIDEVOLUMEHF 0 + +#define EAXSOURCE_MINDOPPLERFACTOR 0.0f +#define EAXSOURCE_MAXDOPPLERFACTOR 10.f +#define EAXSOURCE_DEFAULTDOPPLERFACTOR 1.0f + +#define EAXSOURCE_MINROLLOFFFACTOR 0.0f +#define EAXSOURCE_MAXROLLOFFFACTOR 10.f +#define EAXSOURCE_DEFAULTROLLOFFFACTOR 0.0f + +#define EAXSOURCE_MINROOMROLLOFFFACTOR 0.0f +#define EAXSOURCE_MAXROOMROLLOFFFACTOR 10.f +#define EAXSOURCE_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXSOURCE_MINAIRABSORPTIONFACTOR 0.0f +#define EAXSOURCE_MAXAIRABSORPTIONFACTOR 10.0f +#define EAXSOURCE_DEFAULTAIRABSORPTIONFACTOR 0.0f + +#define EAXSOURCE_MINMACROFXFACTOR 0.0f +#define EAXSOURCE_MAXMACROFXFACTOR 1.0f +#define EAXSOURCE_DEFAULTMACROFXFACTOR 1.0f + +#define EAXSOURCE_MINSPEAKERLEVEL (-10000) +#define EAXSOURCE_MAXSPEAKERLEVEL 0 +#define EAXSOURCE_DEFAULTSPEAKERLEVEL (-10000) + +enum +{ + EAXSPEAKER_FRONT_LEFT = 1, + EAXSPEAKER_FRONT_CENTER = 2, + EAXSPEAKER_FRONT_RIGHT = 3, + EAXSPEAKER_SIDE_RIGHT = 4, + EAXSPEAKER_REAR_RIGHT = 5, + EAXSPEAKER_REAR_CENTER = 6, + EAXSPEAKER_REAR_LEFT = 7, + EAXSPEAKER_SIDE_LEFT = 8, + EAXSPEAKER_LOW_FREQUENCY = 9 +}; + + +// EAXSOURCEFLAGS_DIRECTHFAUTO, EAXSOURCEFLAGS_ROOMAUTO and EAXSOURCEFLAGS_ROOMHFAUTO are ignored for 2D sources +// EAXSOURCEFLAGS_UPMIX is ignored for 3D sources +#define EAXSOURCE_DEFAULTFLAGS (EAXSOURCEFLAGS_DIRECTHFAUTO | \ + EAXSOURCEFLAGS_ROOMAUTO | \ + EAXSOURCEFLAGS_ROOMHFAUTO | \ + EAXSOURCEFLAGS_UPMIX ) + + +// A 3D Source's default ACTIVEFXSLOTID is { EAX_NULL_GUID, EAX_PrimaryFXSlotID, EAX_NULL_GUID, EAX_NULL_GUID } +#define EAXSOURCE_3DDEFAULTACTIVEFXSLOTID {{ EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_PrimaryFXSlotID.Data1, EAX_PrimaryFXSlotID.Data2, \ + EAX_PrimaryFXSlotID.Data3, EAX_PrimaryFXSlotID.Data4[0], \ + EAX_PrimaryFXSlotID.Data4[1],EAX_PrimaryFXSlotID.Data4[2], \ + EAX_PrimaryFXSlotID.Data4[3],EAX_PrimaryFXSlotID.Data4[4], \ + EAX_PrimaryFXSlotID.Data4[5],EAX_PrimaryFXSlotID.Data4[6], \ + EAX_PrimaryFXSlotID.Data4[7] }, \ + { EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] } } + +// A 2D Source's default ACTIVEFXSLOTID is { EAX_NULL_GUID, EAX_NULL_GUID, EAX_NULL_GUID, EAX_NULL_GUID } +#define EAXSOURCE_2DDEFAULTACTIVEFXSLOTID {{ EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] }, \ + { EAX_NULL_GUID.Data1, EAX_NULL_GUID.Data2, EAX_NULL_GUID.Data3, \ + EAX_NULL_GUID.Data4[0],EAX_NULL_GUID.Data4[1],EAX_NULL_GUID.Data4[2],\ + EAX_NULL_GUID.Data4[3],EAX_NULL_GUID.Data4[4],EAX_NULL_GUID.Data4[5],\ + EAX_NULL_GUID.Data4[6],EAX_NULL_GUID.Data4[7] } } + + +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// +// Reverb Effect + +// EAX REVERB {0CF95C8F-A3CC-4849-B0B6-832ECC1822DF} +DEFINE_GUID(EAX_REVERB_EFFECT, + 0xcf95c8f, + 0xa3cc, + 0x4849, + 0xb0, 0xb6, 0x83, 0x2e, 0xcc, 0x18, 0x22, 0xdf); + +// Reverb effect properties +typedef enum +{ + EAXREVERB_NONE, + EAXREVERB_ALLPARAMETERS, + EAXREVERB_ENVIRONMENT, + EAXREVERB_ENVIRONMENTSIZE, + EAXREVERB_ENVIRONMENTDIFFUSION, + EAXREVERB_ROOM, + EAXREVERB_ROOMHF, + EAXREVERB_ROOMLF, + EAXREVERB_DECAYTIME, + EAXREVERB_DECAYHFRATIO, + EAXREVERB_DECAYLFRATIO, + EAXREVERB_REFLECTIONS, + EAXREVERB_REFLECTIONSDELAY, + EAXREVERB_REFLECTIONSPAN, + EAXREVERB_REVERB, + EAXREVERB_REVERBDELAY, + EAXREVERB_REVERBPAN, + EAXREVERB_ECHOTIME, + EAXREVERB_ECHODEPTH, + EAXREVERB_MODULATIONTIME, + EAXREVERB_MODULATIONDEPTH, + EAXREVERB_AIRABSORPTIONHF, + EAXREVERB_HFREFERENCE, + EAXREVERB_LFREFERENCE, + EAXREVERB_ROOMROLLOFFFACTOR, + EAXREVERB_FLAGS, +} EAXREVERB_PROPERTY; + +// OR these flags with property id +#define EAXREVERB_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXREVERB_DEFERRED 0x80000000 // changes take effect later +#define EAXREVERB_COMMITDEFERREDSETTINGS (EAXREVERB_NONE | \ + EAXREVERB_IMMEDIATE) + +// used by EAXREVERB_ENVIRONMENT +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_UNDEFINED, + + EAX_ENVIRONMENT_COUNT +}; + +// Used by EAXREVERB_FLAGS +// +// Note: The number and order of flags may change in future EAX versions. +// It is recommended to use the flag defines as follows: +// myFlags = EAXREVERBFLAGS_DECAYTIMESCALE | EAXREVERBFLAGS_REVERBSCALE; +// instead of: +// myFlags = 0x00000009; +// +// These flags determine what properties are affected by environment size. +#define EAXREVERBFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time +#define EAXREVERBFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level +#define EAXREVERBFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time +#define EAXREVERBFLAGS_REVERBSCALE 0x00000008 // reflections level +#define EAXREVERBFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time +#define EAXREVERBFLAGS_ECHOTIMESCALE 0x00000040 // echo time +#define EAXREVERBFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time +// This flag limits high-frequency decay time according to air absorption. +#define EAXREVERBFLAGS_DECAYHFLIMIT 0x00000020 +#define EAXREVERBFLAGS_RESERVED 0xFFFFFF00 // reserved future use + +// Use this structure for EAXREVERB_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all times and delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myReverb.lRoom = -1000; +// myReverb.lRoomHF = -100; +// ... +// myReverb.dwFlags = myFlags /* see EAXREVERBFLAGS below */ ; +// instead of: +// myReverb = { -1000, -100, ... , 0x00000009 }; +// If you want to save and load presets in binary form, you +// should define your own structure to insure future compatibility. +// +#ifndef EAXREVERBPROPERTIES_DEFINED +#define EAXREVERBPROPERTIES_DEFINED +typedef struct _EAXREVERBPROPERTIES +{ + unsigned long ulEnvironment; // sets all reverb properties + float flEnvironmentSize; // environment size in meters + float flEnvironmentDiffusion; // environment diffusion + long lRoom; // room effect level (at mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lRoomLF; // relative room effect level at low frequencies + float flDecayTime; // reverberation decay time at mid frequencies + float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio + float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio + long lReflections; // early reflections level relative to room effect + float flReflectionsDelay; // initial reflection delay time + EAXVECTOR vReflectionsPan; // early reflections panning vector + long lReverb; // late reverberation level relative to room effect + float flReverbDelay; // late reverberation delay time relative to initial reflection + EAXVECTOR vReverbPan; // late reverberation panning vector + float flEchoTime; // echo time + float flEchoDepth; // echo depth + float flModulationTime; // modulation time + float flModulationDepth; // modulation depth + float flAirAbsorptionHF; // change in level per meter at high frequencies + float flHFReference; // reference high frequency + float flLFReference; // reference low frequency + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + unsigned long ulFlags; // modifies the behavior of properties +} EAXREVERBPROPERTIES, *LPEAXREVERBPROPERTIES; +#endif + +// Property ranges and defaults: +#define EAXREVERB_MINENVIRONMENT 0 +#define EAXREVERB_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1) +#define EAXREVERB_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC + +#define EAXREVERB_MINENVIRONMENTSIZE 1.0f +#define EAXREVERB_MAXENVIRONMENTSIZE 100.0f +#define EAXREVERB_DEFAULTENVIRONMENTSIZE 7.5f + +#define EAXREVERB_MINENVIRONMENTDIFFUSION 0.0f +#define EAXREVERB_MAXENVIRONMENTDIFFUSION 1.0f +#define EAXREVERB_DEFAULTENVIRONMENTDIFFUSION 1.0f + +#define EAXREVERB_MINROOM (-10000) +#define EAXREVERB_MAXROOM 0 +#define EAXREVERB_DEFAULTROOM (-1000) + +#define EAXREVERB_MINROOMHF (-10000) +#define EAXREVERB_MAXROOMHF 0 +#define EAXREVERB_DEFAULTROOMHF (-100) + +#define EAXREVERB_MINROOMLF (-10000) +#define EAXREVERB_MAXROOMLF 0 +#define EAXREVERB_DEFAULTROOMLF 0 + +#define EAXREVERB_MINDECAYTIME 0.1f +#define EAXREVERB_MAXDECAYTIME 20.0f +#define EAXREVERB_DEFAULTDECAYTIME 1.49f + +#define EAXREVERB_MINDECAYHFRATIO 0.1f +#define EAXREVERB_MAXDECAYHFRATIO 2.0f +#define EAXREVERB_DEFAULTDECAYHFRATIO 0.83f + +#define EAXREVERB_MINDECAYLFRATIO 0.1f +#define EAXREVERB_MAXDECAYLFRATIO 2.0f +#define EAXREVERB_DEFAULTDECAYLFRATIO 1.00f + +#define EAXREVERB_MINREFLECTIONS (-10000) +#define EAXREVERB_MAXREFLECTIONS 1000 +#define EAXREVERB_DEFAULTREFLECTIONS (-2602) + +#define EAXREVERB_MINREFLECTIONSDELAY 0.0f +#define EAXREVERB_MAXREFLECTIONSDELAY 0.3f +#define EAXREVERB_DEFAULTREFLECTIONSDELAY 0.007f + +#define EAXREVERB_DEFAULTREFLECTIONSPAN {0.0f, 0.0f, 0.0f} + +#define EAXREVERB_MINREVERB (-10000) +#define EAXREVERB_MAXREVERB 2000 +#define EAXREVERB_DEFAULTREVERB 200 + +#define EAXREVERB_MINREVERBDELAY 0.0f +#define EAXREVERB_MAXREVERBDELAY 0.1f +#define EAXREVERB_DEFAULTREVERBDELAY 0.011f + +#define EAXREVERB_DEFAULTREVERBPAN {0.0f, 0.0f, 0.0f} + +#define EAXREVERB_MINECHOTIME 0.075f +#define EAXREVERB_MAXECHOTIME 0.25f +#define EAXREVERB_DEFAULTECHOTIME 0.25f + +#define EAXREVERB_MINECHODEPTH 0.0f +#define EAXREVERB_MAXECHODEPTH 1.0f +#define EAXREVERB_DEFAULTECHODEPTH 0.0f + +#define EAXREVERB_MINMODULATIONTIME 0.04f +#define EAXREVERB_MAXMODULATIONTIME 4.0f +#define EAXREVERB_DEFAULTMODULATIONTIME 0.25f + +#define EAXREVERB_MINMODULATIONDEPTH 0.0f +#define EAXREVERB_MAXMODULATIONDEPTH 1.0f +#define EAXREVERB_DEFAULTMODULATIONDEPTH 0.0f + +#define EAXREVERB_MINAIRABSORPTIONHF (-100.0f) +#define EAXREVERB_MAXAIRABSORPTIONHF 0.0f +#define EAXREVERB_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXREVERB_MINHFREFERENCE 1000.0f +#define EAXREVERB_MAXHFREFERENCE 20000.0f +#define EAXREVERB_DEFAULTHFREFERENCE 5000.0f + +#define EAXREVERB_MINLFREFERENCE 20.0f +#define EAXREVERB_MAXLFREFERENCE 1000.0f +#define EAXREVERB_DEFAULTLFREFERENCE 250.0f + +#define EAXREVERB_MINROOMROLLOFFFACTOR 0.0f +#define EAXREVERB_MAXROOMROLLOFFFACTOR 10.0f +#define EAXREVERB_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXREVERB_DEFAULTFLAGS (EAXREVERBFLAGS_DECAYTIMESCALE | \ + EAXREVERBFLAGS_REFLECTIONSSCALE | \ + EAXREVERBFLAGS_REFLECTIONSDELAYSCALE | \ + EAXREVERBFLAGS_REVERBSCALE | \ + EAXREVERBFLAGS_REVERBDELAYSCALE | \ + EAXREVERBFLAGS_DECAYHFLIMIT) +//////////////////////////////////////////////////////////////////////////// + + + + +//////////////////////////////////////////////////////////////////////////// + +// New Effect Types + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// AGC Compressor Effect + +// EAX AGC COMPRESSOR {BFB7A01E-7825-4039-927F-3AABDA0C560} + +DEFINE_GUID(EAX_AGCCOMPRESSOR_EFFECT, + 0xbfb7a01e, + 0x7825, + 0x4039, + 0x92, 0x7f, 0x3, 0xaa, 0xbd, 0xa0, 0xc5, 0x60); + +// AGC Compressor properties +typedef enum +{ + EAXAGCCOMPRESSOR_NONE, + EAXAGCCOMPRESSOR_ALLPARAMETERS, + EAXAGCCOMPRESSOR_ONOFF +} EAXAGCCOMPRESSOR_PROPERTY; + +// OR these flags with property id +#define EAXAGCCOMPRESSOR_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXAGCCOMPRESSOR_DEFERRED 0x80000000 // changes take effect later +#define EAXAGCCOMPRESSOR_COMMITDEFERREDSETTINGS (EAXAGCCOMPRESSOR_NONE | \ + EAXAGCCOMPRESSOR_IMMEDIATE) + +// Use this structure for EAXAGCCOMPRESSOR_ALLPARAMETERS +#ifndef EAXAGCCOMPRESSORPROPERTIES_DEFINED +#define EAXAGCCOMPRESSORPROPERTIES_DEFINED +typedef struct _EAXAGCCOMPRESSORPROPERTIES +{ + unsigned long ulOnOff; // Switch Compressor on or off +} EAXAGCCOMPRESSORPROPERTIES, *LPEAXAGCCOMPRESSORPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXAGCCOMPRESSOR_MINONOFF 0 +#define EAXAGCCOMPRESSOR_MAXONOFF 1 +#define EAXAGCCOMPRESSOR_DEFAULTONOFF 1 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Autowah Effect + +// EAX AUTOWAH {EC3130C0-AC7A-11D2-88DD-A024D13CE1} +DEFINE_GUID(EAX_AUTOWAH_EFFECT, + 0xec3130c0, + 0xac7a, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Autowah properties +typedef enum +{ + EAXAUTOWAH_NONE, + EAXAUTOWAH_ALLPARAMETERS, + EAXAUTOWAH_ATTACKTIME, + EAXAUTOWAH_RELEASETIME, + EAXAUTOWAH_RESONANCE, + EAXAUTOWAH_PEAKLEVEL +} EAXAUTOWAH_PROPERTY; + +// OR these flags with property id +#define EAXAUTOWAH_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXAUTOWAH_DEFERRED 0x80000000 // changes take effect later +#define EAXAUTOWAH_COMMITDEFERREDSETTINGS (EAXAUTOWAH_NONE | \ + EAXAUTOWAH_IMMEDIATE) + +// Use this structure for EAXAUTOWAH_ALLPARAMETERS +#ifndef EAXAUTOWAHPROPERTIES_DEFINED +#define EAXAUTOWAHPROPERTIES_DEFINED +typedef struct _EAXAUTOWAHPROPERTIES +{ + float flAttackTime; // Attack time (seconds) + float flReleaseTime; // Release time (seconds) + long lResonance; // Resonance (mB) + long lPeakLevel; // Peak level (mB) +} EAXAUTOWAHPROPERTIES, *LPEAXAUTOWAHPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXAUTOWAH_MINATTACKTIME 0.0001f +#define EAXAUTOWAH_MAXATTACKTIME 1.0f +#define EAXAUTOWAH_DEFAULTATTACKTIME 0.06f + +#define EAXAUTOWAH_MINRELEASETIME 0.0001f +#define EAXAUTOWAH_MAXRELEASETIME 1.0f +#define EAXAUTOWAH_DEFAULTRELEASETIME 0.06f + +#define EAXAUTOWAH_MINRESONANCE 600 +#define EAXAUTOWAH_MAXRESONANCE 6000 +#define EAXAUTOWAH_DEFAULTRESONANCE 6000 + +#define EAXAUTOWAH_MINPEAKLEVEL (-9000) +#define EAXAUTOWAH_MAXPEAKLEVEL 9000 +#define EAXAUTOWAH_DEFAULTPEAKLEVEL 2100 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Chorus Effect + +// EAX CHORUS {DE6D6FE0-AC79-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_CHORUS_EFFECT, + 0xde6d6fe0, + 0xac79, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + + +// Chorus properties +typedef enum +{ + EAXCHORUS_NONE, + EAXCHORUS_ALLPARAMETERS, + EAXCHORUS_WAVEFORM, + EAXCHORUS_PHASE, + EAXCHORUS_RATE, + EAXCHORUS_DEPTH, + EAXCHORUS_FEEDBACK, + EAXCHORUS_DELAY +} EAXCHORUS_PROPERTY; + +// OR these flags with property id +#define EAXCHORUS_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXCHORUS_DEFERRED 0x80000000 // changes take effect later +#define EAXCHORUS_COMMITDEFERREDSETTINGS (EAXCHORUS_NONE | \ + EAXCHORUS_IMMEDIATE) + +// used by EAXCHORUS_WAVEFORM +enum +{ + EAX_CHORUS_SINUSOID, + EAX_CHORUS_TRIANGLE +}; + +// Use this structure for EAXCHORUS_ALLPARAMETERS +#ifndef EAXCHORUSPROPERTIES_DEFINED +#define EAXCHORUSPROPERTIES_DEFINED +typedef struct _EAXCHORUSPROPERTIES +{ + unsigned long ulWaveform; // Waveform selector - see enum above + long lPhase; // Phase (Degrees) + float flRate; // Rate (Hz) + float flDepth; // Depth (0 to 1) + float flFeedback; // Feedback (-1 to 1) + float flDelay; // Delay (seconds) +} EAXCHORUSPROPERTIES, *LPEAXCHORUSPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXCHORUS_MINWAVEFORM 0 +#define EAXCHORUS_MAXWAVEFORM 1 +#define EAXCHORUS_DEFAULTWAVEFORM 1 + +#define EAXCHORUS_MINPHASE (-180) +#define EAXCHORUS_MAXPHASE 180 +#define EAXCHORUS_DEFAULTPHASE 90 + +#define EAXCHORUS_MINRATE 0.0f +#define EAXCHORUS_MAXRATE 10.0f +#define EAXCHORUS_DEFAULTRATE 1.1f + +#define EAXCHORUS_MINDEPTH 0.0f +#define EAXCHORUS_MAXDEPTH 1.0f +#define EAXCHORUS_DEFAULTDEPTH 0.1f + +#define EAXCHORUS_MINFEEDBACK (-1.0f) +#define EAXCHORUS_MAXFEEDBACK 1.0f +#define EAXCHORUS_DEFAULTFEEDBACK 0.25f + +#define EAXCHORUS_MINDELAY 0.0002f +#define EAXCHORUS_MAXDELAY 0.016f +#define EAXCHORUS_DEFAULTDELAY 0.016f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Distortion Effect + +// EAX DISTORTION {975A4CE0-AC7E-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_DISTORTION_EFFECT, + 0x975a4ce0, + 0xac7e, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Distortion properties +typedef enum +{ + EAXDISTORTION_NONE, + EAXDISTORTION_ALLPARAMETERS, + EAXDISTORTION_EDGE, + EAXDISTORTION_GAIN, + EAXDISTORTION_LOWPASSCUTOFF, + EAXDISTORTION_EQCENTER, + EAXDISTORTION_EQBANDWIDTH +} EAXDISTORTION_PROPERTY; + +// OR these flags with property id +#define EAXDISTORTION_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXDISTORTION_DEFERRED 0x80000000 // changes take effect later +#define EAXDISTORTION_COMMITDEFERREDSETTINGS (EAXDISTORTION_NONE | \ + EAXDISTORTION_IMMEDIATE) + +// Use this structure for EAXDISTORTION_ALLPARAMETERS +#ifndef EAXDISTORTIONPROPERTIES_DEFINED +#define EAXDISTORTIONPROPERTIES_DEFINED +typedef struct _EAXDISTORTIONPROPERTIES +{ + float flEdge; // Controls the shape of the distortion (0 to 1) + long lGain; // Controls the post distortion gain (mB) + float flLowPassCutOff; // Controls the cut-off of the filter pre-distortion (Hz) + float flEQCenter; // Controls the center frequency of the EQ post-distortion (Hz) + float flEQBandwidth; // Controls the bandwidth of the EQ post-distortion (Hz) +} EAXDISTORTIONPROPERTIES, *LPEAXDISTORTIONPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXDISTORTION_MINEDGE 0.0f +#define EAXDISTORTION_MAXEDGE 1.0f +#define EAXDISTORTION_DEFAULTEDGE 0.2f + +#define EAXDISTORTION_MINGAIN (-6000) +#define EAXDISTORTION_MAXGAIN 0 +#define EAXDISTORTION_DEFAULTGAIN (-2600) + +#define EAXDISTORTION_MINLOWPASSCUTOFF 80.0f +#define EAXDISTORTION_MAXLOWPASSCUTOFF 24000.0f +#define EAXDISTORTION_DEFAULTLOWPASSCUTOFF 8000.0f + +#define EAXDISTORTION_MINEQCENTER 80.0f +#define EAXDISTORTION_MAXEQCENTER 24000.0f +#define EAXDISTORTION_DEFAULTEQCENTER 3600.0f + +#define EAXDISTORTION_MINEQBANDWIDTH 80.0f +#define EAXDISTORTION_MAXEQBANDWIDTH 24000.0f +#define EAXDISTORTION_DEFAULTEQBANDWIDTH 3600.0f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Echo Effect + +// EAX ECHO {E9F1BC0-AC82-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_ECHO_EFFECT, + 0xe9f1bc0, + 0xac82, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Echo properties +typedef enum +{ + EAXECHO_NONE, + EAXECHO_ALLPARAMETERS, + EAXECHO_DELAY, + EAXECHO_LRDELAY, + EAXECHO_DAMPING, + EAXECHO_FEEDBACK, + EAXECHO_SPREAD +} EAXECHO_PROPERTY; + +// OR these flags with property id +#define EAXECHO_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXECHO_DEFERRED 0x80000000 // changes take effect later +#define EAXECHO_COMMITDEFERREDSETTINGS (EAXECHO_NONE | \ + EAXECHO_IMMEDIATE) + +// Use this structure for EAXECHO_ALLPARAMETERS +#ifndef EAXECHOPROPERTIES_DEFINED +#define EAXECHOPROPERTIES_DEFINED +typedef struct _EAXECHOPROPERTIES +{ + float flDelay; // Controls the initial delay time (seconds) + float flLRDelay; // Controls the delay time between the first and second taps (seconds) + float flDamping; // Controls a low-pass filter that dampens the echoes (0 to 1) + float flFeedback; // Controls the duration of echo repetition (0 to 1) + float flSpread; // Controls the left-right spread of the echoes +} EAXECHOPROPERTIES, *LPEAXECHOPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXECHO_MINDAMPING 0.0f +#define EAXECHO_MAXDAMPING 0.99f +#define EAXECHO_DEFAULTDAMPING 0.5f + +#define EAXECHO_MINDELAY 0.002f +#define EAXECHO_MAXDELAY 0.207f +#define EAXECHO_DEFAULTDELAY 0.1f + +#define EAXECHO_MINLRDELAY 0.0f +#define EAXECHO_MAXLRDELAY 0.404f +#define EAXECHO_DEFAULTLRDELAY 0.1f + +#define EAXECHO_MINFEEDBACK 0.0f +#define EAXECHO_MAXFEEDBACK 1.0f +#define EAXECHO_DEFAULTFEEDBACK 0.5f + +#define EAXECHO_MINSPREAD (-1.0f) +#define EAXECHO_MAXSPREAD 1.0f +#define EAXECHO_DEFAULTSPREAD (-1.0f) + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Equalizer Effect + +// EAX EQUALIZER {65F94CE0-9793-11D3-939D-C0F02DD6F0} + +DEFINE_GUID(EAX_EQUALIZER_EFFECT, + 0x65f94ce0, + 0x9793, + 0x11d3, + 0x93, 0x9d, 0x0, 0xc0, 0xf0, 0x2d, 0xd6, 0xf0); + + +// Equalizer properties +typedef enum +{ + EAXEQUALIZER_NONE, + EAXEQUALIZER_ALLPARAMETERS, + EAXEQUALIZER_LOWGAIN, + EAXEQUALIZER_LOWCUTOFF, + EAXEQUALIZER_MID1GAIN, + EAXEQUALIZER_MID1CENTER, + EAXEQUALIZER_MID1WIDTH, + EAXEQUALIZER_MID2GAIN, + EAXEQUALIZER_MID2CENTER, + EAXEQUALIZER_MID2WIDTH, + EAXEQUALIZER_HIGHGAIN, + EAXEQUALIZER_HIGHCUTOFF +} EAXEQUALIZER_PROPERTY; + +// OR these flags with property id +#define EAXEQUALIZER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXEQUALIZER_DEFERRED 0x80000000 // changes take effect later +#define EAXEQUALIZER_COMMITDEFERREDSETTINGS (EAXEQUALIZER_NONE | \ + EAXEQUALIZER_IMMEDIATE) + +// Use this structure for EAXEQUALIZER_ALLPARAMETERS +#ifndef EAXEQUALIZERPROPERTIES_DEFINED +#define EAXEQUALIZERPROPERTIES_DEFINED +typedef struct _EAXEQUALIZERPROPERTIES +{ + long lLowGain; // (mB) + float flLowCutOff; // (Hz) + long lMid1Gain; // (mB) + float flMid1Center; // (Hz) + float flMid1Width; // (octaves) + long lMid2Gain; // (mB) + float flMid2Center; // (Hz) + float flMid2Width; // (octaves) + long lHighGain; // (mB) + float flHighCutOff; // (Hz) +} EAXEQUALIZERPROPERTIES, *LPEAXEQUALIZERPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXEQUALIZER_MINLOWGAIN (-1800) +#define EAXEQUALIZER_MAXLOWGAIN 1800 +#define EAXEQUALIZER_DEFAULTLOWGAIN 0 + +#define EAXEQUALIZER_MINLOWCUTOFF 50.0f +#define EAXEQUALIZER_MAXLOWCUTOFF 800.0f +#define EAXEQUALIZER_DEFAULTLOWCUTOFF 200.0f + +#define EAXEQUALIZER_MINMID1GAIN (-1800) +#define EAXEQUALIZER_MAXMID1GAIN 1800 +#define EAXEQUALIZER_DEFAULTMID1GAIN 0 + +#define EAXEQUALIZER_MINMID1CENTER 200.0f +#define EAXEQUALIZER_MAXMID1CENTER 3000.0f +#define EAXEQUALIZER_DEFAULTMID1CENTER 500.0f + +#define EAXEQUALIZER_MINMID1WIDTH 0.01f +#define EAXEQUALIZER_MAXMID1WIDTH 1.0f +#define EAXEQUALIZER_DEFAULTMID1WIDTH 1.0f + +#define EAXEQUALIZER_MINMID2GAIN (-1800) +#define EAXEQUALIZER_MAXMID2GAIN 1800 +#define EAXEQUALIZER_DEFAULTMID2GAIN 0 + +#define EAXEQUALIZER_MINMID2CENTER 1000.0f +#define EAXEQUALIZER_MAXMID2CENTER 8000.0f +#define EAXEQUALIZER_DEFAULTMID2CENTER 3000.0f + +#define EAXEQUALIZER_MINMID2WIDTH 0.01f +#define EAXEQUALIZER_MAXMID2WIDTH 1.0f +#define EAXEQUALIZER_DEFAULTMID2WIDTH 1.0f + +#define EAXEQUALIZER_MINHIGHGAIN (-1800) +#define EAXEQUALIZER_MAXHIGHGAIN 1800 +#define EAXEQUALIZER_DEFAULTHIGHGAIN 0 + +#define EAXEQUALIZER_MINHIGHCUTOFF 4000.0f +#define EAXEQUALIZER_MAXHIGHCUTOFF 16000.0f +#define EAXEQUALIZER_DEFAULTHIGHCUTOFF 6000.0f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Flanger Effect + +// EAX FLANGER {A70007C0-7D2-11D3-9B1E-A024D13CE1} + +DEFINE_GUID(EAX_FLANGER_EFFECT, + 0xa70007c0, + 0x7d2, + 0x11d3, + 0x9b, 0x1e, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Flanger properties +typedef enum +{ + EAXFLANGER_NONE, + EAXFLANGER_ALLPARAMETERS, + EAXFLANGER_WAVEFORM, + EAXFLANGER_PHASE, + EAXFLANGER_RATE, + EAXFLANGER_DEPTH, + EAXFLANGER_FEEDBACK, + EAXFLANGER_DELAY +} EAXFLANGER_PROPERTY; + +// OR these flags with property id +#define EAXFLANGER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXFLANGER_DEFERRED 0x80000000 // changes take effect later +#define EAXFLANGER_COMMITDEFERREDSETTINGS (EAXFLANGER_NONE | \ + EAXFLANGER_IMMEDIATE) + +// used by EAXFLANGER_WAVEFORM +enum +{ + EAX_FLANGER_SINUSOID, + EAX_FLANGER_TRIANGLE +}; + +// Use this structure for EAXFLANGER_ALLPARAMETERS +#ifndef EAXFLANGERPROPERTIES_DEFINED +#define EAXFLANGERPROPERTIES_DEFINED +typedef struct _EAXFLANGERPROPERTIES +{ + unsigned long ulWaveform; // Waveform selector - see enum above + long lPhase; // Phase (Degrees) + float flRate; // Rate (Hz) + float flDepth; // Depth (0 to 1) + float flFeedback; // Feedback (0 to 1) + float flDelay; // Delay (seconds) +} EAXFLANGERPROPERTIES, *LPEAXFLANGERPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXFLANGER_MINWAVEFORM 0 +#define EAXFLANGER_MAXWAVEFORM 1 +#define EAXFLANGER_DEFAULTWAVEFORM 1 + +#define EAXFLANGER_MINPHASE (-180) +#define EAXFLANGER_MAXPHASE 180 +#define EAXFLANGER_DEFAULTPHASE 0 + +#define EAXFLANGER_MINRATE 0.0f +#define EAXFLANGER_MAXRATE 10.0f +#define EAXFLANGER_DEFAULTRATE 0.27f + +#define EAXFLANGER_MINDEPTH 0.0f +#define EAXFLANGER_MAXDEPTH 1.0f +#define EAXFLANGER_DEFAULTDEPTH 1.0f + +#define EAXFLANGER_MINFEEDBACK (-1.0f) +#define EAXFLANGER_MAXFEEDBACK 1.0f +#define EAXFLANGER_DEFAULTFEEDBACK (-0.5f) + +#define EAXFLANGER_MINDELAY 0.0002f +#define EAXFLANGER_MAXDELAY 0.004f +#define EAXFLANGER_DEFAULTDELAY 0.002f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Frequency Shifter Effect + +// EAX FREQUENCY SHIFTER {DC3E1880-9212-11D3-939D-C0F02DD6F0} + +DEFINE_GUID(EAX_FREQUENCYSHIFTER_EFFECT, + 0xdc3e1880, + 0x9212, + 0x11d3, + 0x93, 0x9d, 0x0, 0xc0, 0xf0, 0x2d, 0xd6, 0xf0); + +// Frequency Shifter properties +typedef enum +{ + EAXFREQUENCYSHIFTER_NONE, + EAXFREQUENCYSHIFTER_ALLPARAMETERS, + EAXFREQUENCYSHIFTER_FREQUENCY, + EAXFREQUENCYSHIFTER_LEFTDIRECTION, + EAXFREQUENCYSHIFTER_RIGHTDIRECTION +} EAXFREQUENCYSHIFTER_PROPERTY; + +// OR these flags with property id +#define EAXFREQUENCYSHIFTER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXFREQUENCYSHIFTER_DEFERRED 0x80000000 // changes take effect later +#define EAXFREQUENCYSHIFTER_COMMITDEFERREDSETTINGS (EAXFREQUENCYSHIFTER_NONE | \ + EAXFREQUENCYSHIFTER_IMMEDIATE) + +// used by EAXFREQUENCYSHIFTER_LEFTDIRECTION and EAXFREQUENCYSHIFTER_RIGHTDIRECTION +enum +{ + EAX_FREQUENCYSHIFTER_DOWN, + EAX_FREQUENCYSHIFTER_UP, + EAX_FREQUENCYSHIFTER_OFF +}; + +// Use this structure for EAXFREQUENCYSHIFTER_ALLPARAMETERS +#ifndef EAXFREQUENCYSHIFTERPROPERTIES_DEFINED +#define EAXFREQUENCYSHIFTERPROPERTIES_DEFINED +typedef struct _EAXFREQUENCYSHIFTERPROPERTIES +{ + float flFrequency; // (Hz) + unsigned long ulLeftDirection; // see enum above + unsigned long ulRightDirection; // see enum above +} EAXFREQUENCYSHIFTERPROPERTIES, *LPEAXFREQUENCYSHIFTERPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXFREQUENCYSHIFTER_MINFREQUENCY 0.0f +#define EAXFREQUENCYSHIFTER_MAXFREQUENCY 24000.0f +#define EAXFREQUENCYSHIFTER_DEFAULTFREQUENCY 0.0f + +#define EAXFREQUENCYSHIFTER_MINLEFTDIRECTION 0 +#define EAXFREQUENCYSHIFTER_MAXLEFTDIRECTION 2 +#define EAXFREQUENCYSHIFTER_DEFAULTLEFTDIRECTION 0 + +#define EAXFREQUENCYSHIFTER_MINRIGHTDIRECTION 0 +#define EAXFREQUENCYSHIFTER_MAXRIGHTDIRECTION 2 +#define EAXFREQUENCYSHIFTER_DEFAULTRIGHTDIRECTION 0 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Vocal Morpher Effect + +// EAX VOCAL MORPHER {E41CF10C-3383-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_VOCALMORPHER_EFFECT, + 0xe41cf10c, + 0x3383, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Vocal Morpher properties +typedef enum +{ + EAXVOCALMORPHER_NONE, + EAXVOCALMORPHER_ALLPARAMETERS, + EAXVOCALMORPHER_PHONEMEA, + EAXVOCALMORPHER_PHONEMEACOARSETUNING, + EAXVOCALMORPHER_PHONEMEB, + EAXVOCALMORPHER_PHONEMEBCOARSETUNING, + EAXVOCALMORPHER_WAVEFORM, + EAXVOCALMORPHER_RATE +} EAXVOCALMORPHER_PROPERTY; + +// OR these flags with property id +#define EAXVOCALMORPHER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXVOCALMORPHER_DEFERRED 0x80000000 // changes take effect later +#define EAXVOCALMORPHER_COMMITDEFERREDSETTINGS (EAXVOCALMORPHER_NONE | \ + EAXVOCALMORPHER_IMMEDIATE) + +// used by EAXVOCALMORPHER_PHONEMEA and EAXVOCALMORPHER_PHONEMEB +enum +{ + A, E, I, O, U, AA, AE, AH, AO, EH, ER, IH, IY, UH, UW, B, D, F, G, + J, K, L, M, N, P, R, S, T, V, Z +}; + +// used by EAXVOCALMORPHER_WAVEFORM +enum +{ + EAX_VOCALMORPHER_SINUSOID, + EAX_VOCALMORPHER_TRIANGLE, + EAX_VOCALMORPHER_SAWTOOTH +}; + +// Use this structure for EAXVOCALMORPHER_ALLPARAMETERS +#ifndef EAXVOCALMORPHERPROPERTIES_DEFINED +#define EAXVOCALMORPHERPROPERTIES_DEFINED +typedef struct _EAXVOCALMORPHERPROPERTIES +{ + unsigned long ulPhonemeA; // see enum above + long lPhonemeACoarseTuning; // (semitones) + unsigned long ulPhonemeB; // see enum above + long lPhonemeBCoarseTuning; // (semitones) + unsigned long ulWaveform; // Waveform selector - see enum above + float flRate; // (Hz) +} EAXVOCALMORPHERPROPERTIES, *LPEAXVOCALMORPHERPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXVOCALMORPHER_MINPHONEMEA 0 +#define EAXVOCALMORPHER_MAXPHONEMEA 29 +#define EAXVOCALMORPHER_DEFAULTPHONEMEA 0 + +#define EAXVOCALMORPHER_MINPHONEMEACOARSETUNING (-24) +#define EAXVOCALMORPHER_MAXPHONEMEACOARSETUNING 24 +#define EAXVOCALMORPHER_DEFAULTPHONEMEACOARSETUNING 0 + +#define EAXVOCALMORPHER_MINPHONEMEB 0 +#define EAXVOCALMORPHER_MAXPHONEMEB 29 +#define EAXVOCALMORPHER_DEFAULTPHONEMEB 10 + +#define EAXVOCALMORPHER_MINPHONEMEBCOARSETUNING (-24) +#define EAXVOCALMORPHER_MAXPHONEMEBCOARSETUNING 24 +#define EAXVOCALMORPHER_DEFAULTPHONEMEBCOARSETUNING 0 + +#define EAXVOCALMORPHER_MINWAVEFORM 0 +#define EAXVOCALMORPHER_MAXWAVEFORM 2 +#define EAXVOCALMORPHER_DEFAULTWAVEFORM 0 + +#define EAXVOCALMORPHER_MINRATE 0.0f +#define EAXVOCALMORPHER_MAXRATE 10.0f +#define EAXVOCALMORPHER_DEFAULTRATE 1.41f + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Pitch Shifter Effect + +// EAX PITCH SHIFTER {E7905100-AFB2-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_PITCHSHIFTER_EFFECT, + 0xe7905100, + 0xafb2, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Pitch Shifter properties +typedef enum +{ + EAXPITCHSHIFTER_NONE, + EAXPITCHSHIFTER_ALLPARAMETERS, + EAXPITCHSHIFTER_COARSETUNE, + EAXPITCHSHIFTER_FINETUNE +} EAXPITCHSHIFTER_PROPERTY; + +// OR these flags with property id +#define EAXPITCHSHIFTER_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXPITCHSHIFTER_DEFERRED 0x80000000 // changes take effect later +#define EAXPITCHSHIFTER_COMMITDEFERREDSETTINGS (EAXPITCHSHIFTER_NONE | \ + EAXPITCHSHIFTER_IMMEDIATE) + +// Use this structure for EAXPITCHSHIFTER_ALLPARAMETERS +#ifndef EAXPITCHSHIFTERPROPERTIES_DEFINED +#define EAXPITCHSHIFTERPROPERTIES_DEFINED +typedef struct _EAXPITCHSHIFTERPROPERTIES +{ + long lCoarseTune; // Amount of pitch shift (semitones) + long lFineTune; // Amount of pitch shift (cents) +} EAXPITCHSHIFTERPROPERTIES, *LPEAXPITCHSHIFTERPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXPITCHSHIFTER_MINCOARSETUNE (-12) +#define EAXPITCHSHIFTER_MAXCOARSETUNE 12 +#define EAXPITCHSHIFTER_DEFAULTCOARSETUNE 12 + +#define EAXPITCHSHIFTER_MINFINETUNE (-50) +#define EAXPITCHSHIFTER_MAXFINETUNE 50 +#define EAXPITCHSHIFTER_DEFAULTFINETUNE 0 + +//////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// +// Ring Modulator Effect + +// EAX RING MODULATOR {B89FE60-AFB5-11D2-88DD-A024D13CE1} + +DEFINE_GUID(EAX_RINGMODULATOR_EFFECT, + 0xb89fe60, + 0xafb5, + 0x11d2, + 0x88, 0xdd, 0x0, 0xa0, 0x24, 0xd1, 0x3c, 0xe1); + +// Ring Modulator properties +typedef enum +{ + EAXRINGMODULATOR_NONE, + EAXRINGMODULATOR_ALLPARAMETERS, + EAXRINGMODULATOR_FREQUENCY, + EAXRINGMODULATOR_HIGHPASSCUTOFF, + EAXRINGMODULATOR_WAVEFORM +} EAXRINGMODULATOR_PROPERTY; + +// OR these flags with property id +#define EAXRINGMODULATOR_IMMEDIATE 0x00000000 // changes take effect immediately +#define EAXRINGMODULATOR_DEFERRED 0x80000000 // changes take effect later +#define EAXRINGMODULATOR_COMMITDEFERREDSETTINGS (EAXRINGMODULATOR_NONE | \ + EAXRINGMODULATOR_IMMEDIATE) + +// used by EAXRINGMODULATOR_WAVEFORM +enum +{ + EAX_RINGMODULATOR_SINUSOID, + EAX_RINGMODULATOR_SAWTOOTH, + EAX_RINGMODULATOR_SQUARE +}; + +// Use this structure for EAXRINGMODULATOR_ALLPARAMETERS +#ifndef EAXRINGMODULATORPROPERTIES_DEFINED +#define EAXRINGMODULATORPROPERTIES_DEFINED +typedef struct _EAXRINGMODULATORPROPERTIES +{ + float flFrequency; // Frequency of modulation (Hz) + float flHighPassCutOff; // Cut-off frequency of high-pass filter (Hz) + unsigned long ulWaveform; // Waveform selector - see enum above +} EAXRINGMODULATORPROPERTIES, *LPEAXRINGMODULATORPROPERTIES; +#endif + +// Property ranges and defaults: + +#define EAXRINGMODULATOR_MINFREQUENCY 0.0f +#define EAXRINGMODULATOR_MAXFREQUENCY 8000.0f +#define EAXRINGMODULATOR_DEFAULTFREQUENCY 440.0f + +#define EAXRINGMODULATOR_MINHIGHPASSCUTOFF 0.0f +#define EAXRINGMODULATOR_MAXHIGHPASSCUTOFF 24000.0f +#define EAXRINGMODULATOR_DEFAULTHIGHPASSCUTOFF 800.0f + +#define EAXRINGMODULATOR_MINWAVEFORM 0 +#define EAXRINGMODULATOR_MAXWAVEFORM 2 +#define EAXRINGMODULATOR_DEFAULTWAVEFORM 0 + +//////////////////////////////////////////////////////////////////////////// + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif diff --git a/openal/include/eaxac3.h b/openal/include/eaxac3.h new file mode 100644 index 000000000..450224e7a --- /dev/null +++ b/openal/include/eaxac3.h @@ -0,0 +1,232 @@ +/************************************************************************************************ +/ +/ EAX-AC3 Open AL Extension Header file +/ +/ Description : The EAX-AC3 extension to Open AL provides a way to playback Dolby Digital AC3 +/ files on systems equipped with a SB Live! card. The packaged AC3 data is output +/ via the MMSYSTEM Wave device. +/ If a SB Live! 5.1 card is installed then the AC3 data will be decoded by the +/ audio card. +/ If a legacy SB Live! card is installed then the AC3 data will be sent directly +/ to the S/PDIF Out. +/ The API supports multiple EAX-AC3 devices, and multiple AC3 streams. However +/ the current implementation provides one EAX-AC3 device capable of playing +/ one AC3 Stream at a time. +/ +/ Programmer : Daniel Peacock Creative Labs, Inc February 2001 +/ +/************************************************************************************************/ + +#ifndef _EAXAC3_H_ +#define _EAXAC3_H_ + +// Do not define the symbol EAXAC3_EXPORTS in any projects that use the EAX-AC3 Open AL Extension +#ifdef EAXAC3_EXPORTS +#define EAXAC3_API __declspec(dllexport) +#else +#define EAXAC3_API __declspec(dllimport) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _HRESULT_DEFINED +#define _HRESULT_DEFINED +typedef signed long HRESULT; +#endif + +enum POSFORMAT { MILLISECONDS, BYTES, AC3FRAMES }; + +enum SOURCE { AC3FILE, MEMORY }; + +// Success Codes +#define EAXAC3_OK 0 +#define EAXAC3_ALREADYPLAYING 1 +#define EAXAC3_EOF 2 + +// Error Codes +#define EAXAC3ERR_UNABLETOOPENEAXAC3DEVICE -1 +#define EAXAC3ERR_WAVEOUTPREPAREHEADERFAILURE -2 +#define EAXAC3ERR_OUTOFMEMORY -3 +#define EAXAC3ERR_FILENOTFOUND -4 +#define EAXAC3ERR_AC3FILETOBIG -5 +#define EAXAC3ERR_AC3FRAMENOTFOUND -6 +#define EAXAC3ERR_AC3NOTAT48KHZ -7 +#define EAXAC3ERR_INVALIDAC3FRAME -8 +#define EAXAC3ERR_AC3FILENOTOPEN -9 +#define EAXAC3ERR_BUFFERNOTMULTIPLEOFAC3FRAMESIZE -10 +#define EAXAC3ERR_WAVEOUTERROR -11 +#define EAXAC3ERR_FAILEDTOCREATEEVENT -12 +#define EAXAC3ERR_EAXAC3DEVICENOTOPEN -13 +#define EAXAC3ERR_AC3STREAMALREADYOPEN -14 +#define EAXAC3ERR_POSITIONOUTOFRANGE -15 +#define EAXAC3ERR_NOTATSTARTOFAC3FRAME -16 +#define EAXAC3ERR_AC3STREAMNOTOPEN -17 +#define EAXAC3ERR_SETPOSITIONONLYWORKSONAC3FILES -18 +#define EAXAC3ERR_WRITEDATAONLYWORKSWITHMEMORYSTREAMS -19 +#define EAXAC3ERR_INVALIDPARAMETER -20 +#define EAXAC3ERR_NOTENOUGHAC3DATAINAC3DATABUFFER -21 +#define EAXAC3ERR_NOTENOUGHDATA -22 +#define EAXAC3ERR_EAXAC3DEVICEALREADYOPEN -23 +#define EAXAC3ERR_EAXAC3DEVICENOTFOUND -24 +#define EAXAC3ERR_UNSUPPORTED -25 +#define EAXAC3ERR_FAILEDTOCREATEFNTABLE -26 + +#define DEFAULTEAXAC3DEVICE 0 + +#define ENTIREBUFFER 0 +#define FROMWRITECURSOR 1 + +#define LOOPING 1 + +#define ENDOFDATA 1 + +typedef unsigned int EAXAC3HANDLE; + +typedef unsigned int AC3STREAM; + +// Callback function +typedef void (__stdcall *LPAC3CALLBACK)(AC3STREAM AC3Stream, int msg); + +// Callback messages +#define EAXAC3NEEDMOREDATA 0 +#define EAXAC3REACHEDEND 1 + +typedef struct +{ + unsigned int nNumOfAC3Frames; + unsigned int nAC3FrameSize; + unsigned int nSizeOfFile; + unsigned int nDuration; + unsigned int nFrequency; +} AC3FILEINFO, *LPAC3FILEINFO; + +#define UNKNOWN 1 +#define SPDIFPASSTHRU 2 +#define FULLDECODE 4 + +typedef struct +{ + char szDeviceName[256]; + unsigned int uFlags; + unsigned int uStreams; + unsigned int uReserved; +} EAXAC3DEVICEINFO, *LPEAXAC3DEVICEINFO; + +// Function typedefs + +typedef int (*LPEAXAC3QUERYNUMBEROFDEVICES) (void); +typedef HRESULT (*LPEAXAC3QUERYFILE) (char *, LPAC3FILEINFO, int); +typedef HRESULT (*LPEAXAC3QUERYMEMORY) (char *, int, LPAC3FILEINFO, int); +typedef int (*LPEAXAC3QUERYNOOFFRAMESREQFORPLAYBACK) (AC3STREAM); +typedef HRESULT (*LPEAXAC3OPENPLAYBACKDEVICE) (EAXAC3HANDLE); +typedef HRESULT (*LPEAXAC3CLOSEPLAYBACKDEVICE) (EAXAC3HANDLE); +typedef HRESULT (*LPEAXAC3QUERYDEVICECAPS) (EAXAC3HANDLE, LPEAXAC3DEVICEINFO, int); +typedef HRESULT (*LPEAXAC3GETPOSITION) (AC3STREAM, enum POSFORMAT, int *); +typedef HRESULT (*LPEAXAC3SETFILEPOSITION) (AC3STREAM, enum POSFORMAT, int); +typedef HRESULT (*LPEAXAC3OPENSTREAM) (EAXAC3HANDLE, AC3STREAM *, LPAC3CALLBACK, char *, enum SOURCE); +typedef HRESULT (*LPEAXAC3CLOSESTREAM) (AC3STREAM); +typedef HRESULT (*LPEAXAC3PREPLAYSTREAM) (AC3STREAM); +typedef HRESULT (*LPEAXAC3PLAYSTREAM) (AC3STREAM, int); +typedef HRESULT (*LPEAXAC3STOPSTREAM) (AC3STREAM); +typedef HRESULT (*LPEAXAC3PAUSESTREAM) (AC3STREAM); +typedef HRESULT (*LPEAXAC3RESUMESTREAM) (AC3STREAM); +typedef HRESULT (*LPEAXAC3LOCKBUFFER) (AC3STREAM, unsigned long, void **, unsigned long *, void **, + unsigned long *, unsigned long); +typedef HRESULT (*LPEAXAC3UNLOCKBUFFER) (AC3STREAM, void *, unsigned long, void *, unsigned long, int); +typedef HRESULT (*LPEAXAC3SETPLAYBACKMODE) (EAXAC3HANDLE, unsigned int); +typedef char * (*LPEAXAC3GETERRORSTRING) (HRESULT, char *, int); +typedef HRESULT (*LPEAXAC3GETLASTERROR) (HRESULT *); + +// Function table declaration +typedef struct +{ + LPEAXAC3QUERYNUMBEROFDEVICES EAXAC3QueryNumberOfDevices; + LPEAXAC3QUERYFILE EAXAC3QueryFile; + LPEAXAC3QUERYMEMORY EAXAC3QueryMemory; + LPEAXAC3QUERYNOOFFRAMESREQFORPLAYBACK EAXAC3QueryNoOfFramesReqForPlayback; + LPEAXAC3OPENPLAYBACKDEVICE EAXAC3OpenPlaybackDevice; + LPEAXAC3CLOSEPLAYBACKDEVICE EAXAC3ClosePlaybackDevice; + LPEAXAC3QUERYDEVICECAPS EAXAC3QueryDeviceCaps; + LPEAXAC3GETPOSITION EAXAC3GetPosition; + LPEAXAC3SETFILEPOSITION EAXAC3SetFilePosition; + LPEAXAC3OPENSTREAM EAXAC3OpenStream; + LPEAXAC3CLOSESTREAM EAXAC3CloseStream; + LPEAXAC3PREPLAYSTREAM EAXAC3PrePlayStream; + LPEAXAC3PLAYSTREAM EAXAC3PlayStream; + LPEAXAC3STOPSTREAM EAXAC3StopStream; + LPEAXAC3PAUSESTREAM EAXAC3PauseStream; + LPEAXAC3RESUMESTREAM EAXAC3ResumeStream; + LPEAXAC3LOCKBUFFER EAXAC3LockBuffer; + LPEAXAC3UNLOCKBUFFER EAXAC3UnLockBuffer; + LPEAXAC3SETPLAYBACKMODE EAXAC3SetPlaybackMode; + LPEAXAC3GETERRORSTRING EAXAC3GetErrorString; + LPEAXAC3GETLASTERROR EAXAC3GetLastError; +} EAXAC3FNTABLE, *LPEAXAC3FNTABLE; + + +#ifndef OPENAL +typedef EAXAC3_API HRESULT (*LPEAXAC3GETFUNCTIONTABLE) (LPEAXAC3FNTABLE); +#else +typedef ALboolean (*LPALEAXAC3GETFUNCTIONTABLE) (LPEAXAC3FNTABLE); +#endif + +// Functions exposed in the DLL + +EAXAC3_API HRESULT EAXAC3GetFunctionTable(LPEAXAC3FNTABLE lpEAXAC3FnTable); + +EAXAC3_API int EAXAC3QueryNumberOfDevices(); + +EAXAC3_API HRESULT EAXAC3QueryFile(char *szAC3Filename, LPAC3FILEINFO lpAC3Caps, int nSizeOfAC3FileInfoStruct); + +EAXAC3_API HRESULT EAXAC3QueryMemory(char *lpBuffer, int nSizeOfBuffer, LPAC3FILEINFO lpAC3FileInfo, + int nSizeOfAC3FileInfoStruct); + +EAXAC3_API int EAXAC3QueryNoOfFramesReqForPlayback(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3OpenPlaybackDevice(EAXAC3HANDLE EAXAC3Handle); + +EAXAC3_API HRESULT EAXAC3ClosePlaybackDevice(EAXAC3HANDLE EAXAC3Handle); + +EAXAC3_API HRESULT EAXAC3QueryDeviceCaps(EAXAC3HANDLE EAXAC3Handle, LPEAXAC3DEVICEINFO lpEAXAC3DeviceInfo, + int nSizeOfAC3DeviceInfoStruct); + +EAXAC3_API HRESULT EAXAC3GetPosition(AC3STREAM AC3Stream, enum POSFORMAT posFormat, int *lpAmount); + +EAXAC3_API HRESULT EAXAC3SetFilePosition(AC3STREAM AC3Stream, enum POSFORMAT posFormat, int nAmount); + +EAXAC3_API HRESULT EAXAC3OpenStream(EAXAC3HANDLE EAXAC3Handle, AC3STREAM *lpAC3Stream, + LPAC3CALLBACK pAC3CallbackFn, char *szAC3Filename, enum SOURCE src); + +EAXAC3_API HRESULT EAXAC3CloseStream(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3PrePlayStream(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3PlayStream(AC3STREAM AC3Stream, int nLooping); + +EAXAC3_API HRESULT EAXAC3StopStream(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3PauseStream(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3ResumeStream(AC3STREAM AC3Stream); + +EAXAC3_API HRESULT EAXAC3LockBuffer(AC3STREAM AC3Stream, unsigned long ulBytes, void **ppvPointer1, + unsigned long *pdwBytes1, void **ppvPointer2, unsigned long *pdwBytes2, + unsigned long ulFlags); + +EAXAC3_API HRESULT EAXAC3UnLockBuffer(AC3STREAM AC3Stream, void *pvPointer1, unsigned long ulSize1, + void *pvPointer2, unsigned long ulSize2, int nFinished); + +EAXAC3_API HRESULT EAXAC3SetPlaybackMode(EAXAC3HANDLE EAXAC3Handle, unsigned int ulPlayMode); + +EAXAC3_API char * EAXAC3GetErrorString(HRESULT hr, char *szErrorString, int nSizeOfErrorString); + +EAXAC3_API HRESULT EAXAC3GetLastError(HRESULT *hr); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/include/eaxman.h b/openal/include/eaxman.h new file mode 100644 index 000000000..b54ea1d80 --- /dev/null +++ b/openal/include/eaxman.h @@ -0,0 +1,171 @@ +/* +*/ +#ifndef __EAXMANH +#define __EAXMANH + +#define COM_NO_WINDOWS_H +#include +#include "eax3.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +//#define CLSID_EAXMANAGER CLSID_EAX20_Manager +//#define IID_IEaxManager IID_EAX20_Manager +#define EM_MAX_NAME 32 + +#define EMFLAG_IDDEFAULT (-1) +#define EMFLAG_IDNONE (-2) +#define EMFLAG_LOCKPOSITION 1 +#define EMFLAG_LOADFROMMEMORY 2 +#define EMFLAG_NODIFFRACTION 4 + +typedef struct _EMPOINT { + float fX; + float fY; + float fZ; +} EMPOINT; +typedef EMPOINT FAR *LPEMPOINT; + +typedef struct _LISTENERATTRIBUTES { + float fDistanceFactor; + float fRolloffFactor; + float fDopplerFactor; +} LISTENERATTRIBUTES; +typedef LISTENERATTRIBUTES FAR *LPLISTENERATTRIBUTES; + +typedef struct _SOURCEATTRIBUTES { + EAXBUFFERPROPERTIES eaxAttributes; + unsigned long ulInsideConeAngle; + unsigned long ulOutsideConeAngle; + long lConeOutsideVolume; + float fConeXdir; + float fConeYdir; + float fConeZdir; + float fMinDistance; + float fMaxDistance; + long lDupCount; + long lPriority; +} SOURCEATTRIBUTES; +typedef SOURCEATTRIBUTES FAR *LPSOURCEATTRIBUTES; + +typedef struct _MATERIALATTRIBUTES { + long lLevel; + float fLFRatio; + float fRoomRatio; + DWORD dwFlags; +} MATERIALATTRIBUTES; +typedef MATERIALATTRIBUTES FAR *LPMATERIALATTRIBUTES; + +#define EMMATERIAL_OBSTRUCTS 1 +#define EMMATERIAL_OCCLUDES 3 + +typedef struct _DIFFRACTIONBOX { + long lSubspaceID; + EMPOINT empMin; + EMPOINT empMax; +} DIFFRACTIONBOX; +typedef DIFFRACTIONBOX FAR *LPDIFFRACTIONBOX; + +// {7CE4D6E6-562F-11d3-8812-005004062F83} +DEFINE_GUID(CLSID_EAXMANAGER, 0x60b721a1, 0xf7c8, 0x11d2, 0xa0, 0x2e, 0x0, 0x50, 0x4, 0x6, 0x18, 0xb8); + +#ifdef __cplusplus +struct IEaxManager; +#endif // __cplusplus + +typedef struct IEaxManager *LPEAXMANAGER; + +// {7CE4D6E8-562F-11d3-8812-005004062F83} +DEFINE_GUID(IID_IEaxManager, 0x60b721a2, 0xf7c8, 0x11d2, 0xa0, 0x2e, 0x0, 0x50, 0x4, 0x6, 0x18, 0xb8); + +#undef INTERFACE +#define INTERFACE IEaxManager + +extern HRESULT __stdcall EaxManagerCreate(LPEAXMANAGER*); +typedef HRESULT (__stdcall *LPEAXMANAGERCREATE)(LPEAXMANAGER*); + +DECLARE_INTERFACE_(IEaxManager, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + STDMETHOD(GetDataSetSize) (THIS_ unsigned long*, DWORD) PURE; + STDMETHOD(LoadDataSet) (THIS_ char*, DWORD) PURE; + STDMETHOD(FreeDataSet) (THIS_ DWORD) PURE; + STDMETHOD(GetListenerAttributes) (THIS_ LPLISTENERATTRIBUTES) PURE; + STDMETHOD(GetSourceID) (THIS_ char*, long*) PURE; + STDMETHOD(GetSourceAttributes) (THIS_ long, LPSOURCEATTRIBUTES) PURE; + STDMETHOD(GetSourceNumInstances) (THIS_ long, long*) PURE; + STDMETHOD(GetSourceInstancePos) (THIS_ long, long, LPEMPOINT) PURE; + STDMETHOD(GetEnvironmentID) (THIS_ char*, long*) PURE; + STDMETHOD(GetEnvironmentAttributes) (THIS_ long, LPEAXLISTENERPROPERTIES) PURE; + STDMETHOD(GetMaterialID) (THIS_ char*, long*) PURE; + STDMETHOD(GetMaterialAttributes) (THIS_ long, LPMATERIALATTRIBUTES) PURE; + STDMETHOD(GetGeometrySetID) (THIS_ char*, long*) PURE; + STDMETHOD(GetListenerDynamicAttributes) (THIS_ long, LPEMPOINT, long*, DWORD) PURE; + STDMETHOD(GetSourceDynamicAttributes) (THIS_ long, LPEMPOINT, long*, float*, long*, float*, float*, LPEMPOINT, DWORD) PURE; +// STDMETHOD(GetSubSpaceID) (THIS_ long, LPEMPOINT, long *) PURE; + STDMETHOD(GetEnvironmentName) (THIS_ long, char *szString, long lStrlen) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IEaxManager_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IEaxManager_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IEaxManager_Release(p) (p)->lpVtbl->Release(p) +#define IEaxManager_GetDataSetSize(p,a,b) (p)->lpVtbl->GetDataSetSize(p,a,b) +#define IEaxManager_LoadDataSet(p,a,b) (p)->lpVtbl->LoadDataSet(p,a,b) +#define IEaxManager_FreeDataSet(p,a) (p)->lpVtbl->FreeDataSet(p,a) +#define IEaxManager_GetListenerAttributes(p,a) (p)->lpVtbl->GetListenerAttributes(p,a) +#define IEaxManager_GetSourceID(p,a,b) (p)->lpVtbl->GetSourceID(p,a,b) +#define IEaxManager_GetSourceAttributes(p,a,b) (p)->lpVtbl->GetSourceAttributes(p,a,b) +#define IEaxManager_GetSourceNumInstances(p,a,b) (p)->lpVtbl->GetSourceNumInstances(p,a,b) +#define IEaxManager_GetSourceInstancePos(p,a,b,c) (p)->lpVtbl->GetSourceInstancePos(p,a,b,c) +#define IEaxManager_GetEnvironmentID(p,a,b) (p)->lpVtbl->GetEnvironmentID(p,a,b) +#define IEaxManager_GetEnvironmentAttributes(p,a,b) (p)->lpVtbl->GetEnvironmentAttributes(p,a,b) +#define IEaxManager_GetMaterialID(p,a,b) (p)->lpVtbl->GetMaterialID(p,a,b) +#define IEaxManager_GetMaterialAttributes(p,a,b) (p)->lpVtbl->GetMaterialAttributes(p,a,b) +#define IEaxManager_GetGeometrySetID(p,a,b) (p)->lpVtbl->GetGeometrySetID(p,a,b) +#define IEaxManager_GetListenerDynamicAttributes(p,a,b,c,d) (p)->lpVtbl->GetListenerDynamicAttributes(p,a,b,c,d) +#define IEaxManager_GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i) +//#define IEaxManager_GetSubSpaceID(p,a,b,c) (p)->lpVtbl->GetSubSpaceID(p,a,b,c) +#define IEaxManager_GetEnvironmentName(p,a,b,c) (p)->lpVtbl->GetEnvironmentName(p,a,b,c) +#else +#define IEaxManager_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IEaxManager_AddRef(p) (p)->AddRef() +#define IEaxManager_Release(p) (p)->Release() +#define IEaxManager_GetDataSetSize(p,a,b) (p)->GetDataSetSize(a,b) +#define IEaxManager_LoadDataSet(p,a,b) (p)->LoadDataSet(a,b) +#define IEaxManager_FreeDataSet(p,a) (p)->FreeDataSet(a) +#define IEaxManager_GetListenerAttributes(p,a) (p)->GetListenerAttributes(a) +#define IEaxManager_GetSourceID(p,a,b) (p)->GetSourceID(a,b) +#define IEaxManager_GetSourceAttributes(p,a,b) (p)->GetSourceAttributes(a,b) +#define IEaxManager_GetSourceNumInstances(p,a,b) (p)->GetSourceNumInstances(a,b) +#define IEaxManager_GetSourceInstancePos(p,a,b,c) (p)->GetSourceInstancePos(a,b,c) +#define IEaxManager_GetEnvironmentID(p,a,b) (p)->GetEnvironmentID(a,b) +#define IEaxManager_GetEnvironmentAttributes(p,a,b) (p)->GetEnvironmentAttributes(a,b) +#define IEaxManager_GetMaterialID(p,a,b) (p)->GetMaterialID(a,b) +#define IEaxManager_GetMaterialAttributes(p,a,b) (p)->GetMaterialAttributes(a,b) +#define IEaxManager_GetGeometrySetID(p,a,b) (p)->GetGeometrySetID(a,b) +#define IEaxManager_GetListenerDynamicAttributes(p,a,b,c,d) (p)->GetListenerDynamicAttributes(a,b,c,d) +#define IEaxManager_GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i) (p)->GetSourceDynamicAttributes(a,b,c,d,e,f,g,h,i) +//#define IEaxManager_GetSubSpaceID(p,a,b,c) (p)->GetSubSpaceID(a,b,c) +#define IEaxManager_GetEnvironmentName(p,a,b,c) (p)->GetEnvironmentName(a,b,c) +#endif + +#define EM_OK 0 +#define EM_INVALIDID MAKE_HRESULT(1, FACILITY_ITF, 1) +#define EM_IDNOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 2) +#define EM_FILENOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 3) +#define EM_FILEINVALID MAKE_HRESULT(1, FACILITY_ITF, 4) +#define EM_VERSIONINVALID MAKE_HRESULT(1, FACILITY_ITF, 5) +#define EM_INSTANCENOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 6) + +#ifdef __cplusplus +}; +#endif // __cplusplus + +#endif diff --git a/openal/include/efxlib.h b/openal/include/efxlib.h new file mode 100644 index 000000000..176c3394d --- /dev/null +++ b/openal/include/efxlib.h @@ -0,0 +1,61 @@ +/* +*/ + +#ifndef __EFXLIBH +#define __EFXLIBH + +#include "eax4.h" + + + + +/////////////////////////////////////////////////////////// +// Class definitions. +class idSoundEffect +{ +public: + idSoundEffect() { + }; + ~idSoundEffect() { + if ( data && datasize ) { + Mem_Free( data ); + data = NULL; + } + } + + idStr name; + int datasize; + void *data; +}; + +class idEFXFile +{ +private: + +protected: + // Protected data members. + +public: + // Public data members. + +private: + +public: + idEFXFile(); + ~idEFXFile(); + + bool FindEffect( idStr &name, idSoundEffect **effect, int *index ); + bool ReadEffect( idLexer &lexer, idSoundEffect *effect ); + bool LoadFile( const char *filename, bool OSPath = false ); + void UnloadFile( void ); + void Clear( void ); + + idListeffects; +}; +/////////////////////////////////////////////////////////// + + + + +#endif // __EFXLIBH + diff --git a/openal/lib/eaxguid.lib b/openal/lib/eaxguid.lib new file mode 100644 index 000000000..83618ae59 Binary files /dev/null and b/openal/lib/eaxguid.lib differ diff --git a/openal/lib/openal32.lib b/openal/lib/openal32.lib new file mode 100644 index 000000000..0ec190dbc Binary files /dev/null and b/openal/lib/openal32.lib differ diff --git a/openal/osx/OpenAL.framework/Headers b/openal/osx/OpenAL.framework/Headers new file mode 100644 index 000000000..a177d2a6b --- /dev/null +++ b/openal/osx/OpenAL.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/openal/osx/OpenAL.framework/OpenAL b/openal/osx/OpenAL.framework/OpenAL new file mode 100644 index 000000000..7a4d340e4 --- /dev/null +++ b/openal/osx/OpenAL.framework/OpenAL @@ -0,0 +1 @@ +Versions/Current/OpenAL \ No newline at end of file diff --git a/openal/osx/OpenAL.framework/Resources b/openal/osx/OpenAL.framework/Resources new file mode 100644 index 000000000..953ee36f3 --- /dev/null +++ b/openal/osx/OpenAL.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/openal/osx/OpenAL.framework/Versions/A/Headers/al.h b/openal/osx/OpenAL.framework/Versions/A/Headers/al.h new file mode 100644 index 000000000..8759876a2 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Headers/al.h @@ -0,0 +1,498 @@ +#ifndef _AL_H_ +#define _AL_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "altypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _LIB + #define ALAPI __declspec(dllexport) + #else + #define ALAPI __declspec(dllimport) + #endif + #define ALAPIENTRY __cdecl + #define AL_CALLBACK +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALAPI + #define ALAPIENTRY + #define AL_CALLBACK +#endif + +#define OPENAL + +#ifndef AL_NO_PROTOTYPES + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY alEnable( ALenum capability ); +ALAPI ALvoid ALAPIENTRY alDisable( ALenum capability ); +ALAPI ALboolean ALAPIENTRY alIsEnabled( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY alHint( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY alGetBoolean( ALenum param ); +ALAPI ALint ALAPIENTRY alGetInteger( ALenum param ); +ALAPI ALfloat ALAPIENTRY alGetFloat( ALenum param ); +ALAPI ALdouble ALAPIENTRY alGetDouble( ALenum param ); +ALAPI ALvoid ALAPIENTRY alGetBooleanv( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY alGetIntegerv( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY alGetFloatv( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY alGetDoublev( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY alGetString( ALenum param ); + +ALAPI ALvoid ALAPIENTRY alSetInteger( ALenum pname, ALint value ); +ALAPI ALvoid ALAPIENTRY alSetDouble( ALenum pname, ALdouble value ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY alGetError(); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY alIsExtensionPresent( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY alGetProcAddress( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY alGetEnumValue( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY alListeneri( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY alListenerf( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY alListener3f( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY alListenerfv( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alGetListeneri( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetListenerf( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetListener3f( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetListenerfv( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY alGenSources( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY alDeleteSources( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY alIsSource( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alSourcei( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY alSourcef( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY alSource3f( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY alSourcefv( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alGetSourcei( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetSourcef( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetSource3f( ALuint source, ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetSourcefv( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alSourcePlayv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourcePausev( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceStopv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceRewindv(ALsizei n,ALuint *sources); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY alSourcePlay( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY alSourcePause( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceStop( ALuint source ); + +/** + * Rewinds a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceRewind( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY alGenBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alDeleteBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY alIsBuffer( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY alBufferData( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + + +ALAPI ALvoid ALAPIENTRY alGetBufferi( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetBufferf( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ + +ALAPI ALvoid ALAPIENTRY alSourceQueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alSourceUnqueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY alDistanceModel( ALenum value ); +ALAPI ALvoid ALAPIENTRY alDopplerFactor( ALfloat value ); +ALAPI ALvoid ALAPIENTRY alDopplerVelocity( ALfloat value ); + +#else /* AL_NO_PROTOTYPES */ + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY (*alEnable)( ALenum capability ); +ALAPI ALvoid ALAPIENTRY (*alDisable)( ALenum capability ); +ALAPI ALboolean ALAPIENTRY (*alIsEnabled)( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY (*alHint)( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY (*alGetBoolean)( ALenum param ); +ALAPI ALint ALAPIENTRY (*alGetInteger)( ALenum param ); +ALAPI ALfloat ALAPIENTRY (*alGetFloat)( ALenum param ); +ALAPI ALdouble ALAPIENTRY (*alGetDouble)( ALenum param ); +ALAPI ALvoid ALAPIENTRY (*alGetBooleanv)( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY (*alGetIntegerv)( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY (*alGetFloatv)( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY (*alGetDoublev)( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY (*alGetString)( ALenum param ); + +ALAPI ALvoid ALAPIENTRY (*alSetInteger)( ALenum pname, ALint value ); +ALAPI ALvoid ALAPIENTRY (*alSetDouble)( ALenum pname, ALdouble value ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY (*alGetError)( ALvoid ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY (*alIsExtensionPresent)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY (*alGetProcAddress)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY (*alGetEnumValue)( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY (*alListeneri)( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY (*alListenerf)( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY (*alListener3f)( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY (*alListenerfv)( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alGetListeneri)( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerf)( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListener3f)( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerfv)( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alGenSources)( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alDeleteSources)( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY (*alIsSource)( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alSourcei)( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY (*alSourcef)( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alSource3f)( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY (*alSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alGetSourcei)( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcef)( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alSourcePlayv)( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY (*alSourceStopv)( ALsizei n, ALuint *sources ); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY (*alSourcePlay)( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY (*alSourcePause)( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY (*alSourceStop)( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY (*alGenBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alDeleteBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY (*alIsBuffer)( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY (*alBufferData)( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + +ALAPI ALvoid ALAPIENTRY (*alGetBufferi)( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetBufferf)( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ +ALAPI ALvoid ALAPIENTRY (*alSourceQueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alSourceUnqueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY (*alDistanceModel)( ALenum value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerFactor)( ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerVelocity)( ALfloat value ); + + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openal/osx/OpenAL.framework/Versions/A/Headers/alc.h b/openal/osx/OpenAL.framework/Versions/A/Headers/alc.h new file mode 100644 index 000000000..641e2fd85 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Headers/alc.h @@ -0,0 +1,88 @@ +#ifndef _ALC_H_ +#define _ALC_H_ + +#include "altypes.h" +#include "alctypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _LIB + #define ALCAPI __declspec(dllexport) + #else + #define ALCAPI __declspec(dllimport) + typedef ALCvoid ALCdevice; + typedef ALCvoid ALCcontext; + #endif + #define ALCAPIENTRY __cdecl +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALCAPI + #define ALCAPIENTRY + typedef ALCvoid ALCdevice; + typedef ALCvoid ALCcontext; +#endif + +#ifndef ALC_NO_PROTOTYPES + +ALCAPI ALCubyte* ALCAPIENTRY alcGetString(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(ALCubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY alcCloseDevice(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY alcCreateContext(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcProcessContext(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY alcGetCurrentContext(); +ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcSuspendContext(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY alcGetError(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY alcGetProcAddress(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY alcGetEnumValue(ALCdevice *device,ALCubyte *enumName); + +#else /* AL_NO_PROTOTYPES */ + +ALCAPI ALCubyte* ALCAPIENTRY (*alcGetString)(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY (*alcGetIntegerv)(ALCdevice * device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY (*alcOpenDevice)(ALubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY (*alcCloseDevice)(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY (*alcCreateContext)(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY (*alcMakeContextCurrent)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcProcessContext)(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY (*alcGetCurrentContext)(ALCvoid); +ALCAPI ALCdevice* ALCAPIENTRY (*alcGetContextsDevice)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcSuspendContext)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcDestroyContext)(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY (*alcGetError)(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY (*alcIsExtensionPresent)(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY (*alcGetProcAddress)(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY (*alcGetEnumValue)(ALCdevice *device,ALCubyte *enumName); + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openal/osx/OpenAL.framework/Versions/A/Headers/alctypes.h b/openal/osx/OpenAL.framework/Versions/A/Headers/alctypes.h new file mode 100644 index 000000000..90364609d --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Headers/alctypes.h @@ -0,0 +1,165 @@ +#ifndef _ALCTYPES_H_ +#define _ALCTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * Portions Copyright (C) 2004 by Apple Computer Inc. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** ALC boolean type. */ +typedef char ALCboolean; + +/** ALC 8bit signed byte. */ +typedef char ALCbyte; + +/** ALC 8bit unsigned byte. */ +typedef unsigned char ALCubyte; + +/** ALC 16bit signed short integer type. */ +typedef short ALCshort; + +/** ALC 16bit unsigned short integer type. */ +typedef unsigned short ALCushort; + +/** ALC 32bit unsigned integer type. */ +typedef unsigned ALCuint; + +/** ALC 32bit signed integer type. */ +typedef int ALCint; + +/** ALC 32bit floating point type. */ +typedef float ALCfloat; + +/** ALC 64bit double point type. */ +typedef double ALCdouble; + +/** ALC 32bit type. */ +typedef unsigned int ALCsizei; + +/** ALC void type */ +typedef void ALCvoid; + +/** ALC enumerations. */ +typedef int ALCenum; + +/* Bad value. */ +#define ALC_INVALID (-1) + +/* Boolean False. */ +#define ALC_FALSE 0 + +/* Boolean True. */ +#define ALC_TRUE 1 + +/** Errors: No Error. */ +#define ALC_NO_ERROR ALC_FALSE + +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 + +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +#define ALC_DEVICE_SPECIFIER 0x1005 +#define ALC_EXTENSIONS 0x1006 + +#define ALC_FREQUENCY 0x1007 +#define ALC_REFRESH 0x1008 +#define ALC_SYNC 0x1009 + +/** + * The device argument does not name a valid dvice. + */ +#define ALC_INVALID_DEVICE 0xA001 + +/** + * The context argument does not name a valid context. + */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define ALC_INVALID_ENUM 0xA003 + +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define ALC_INVALID_VALUE 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define ALC_OUT_OF_MEMORY 0xA005 + + +//********************************************************************************* +// OSX Specific Properties +//********************************************************************************* + +/** + * Convert Data When Loading. Default false, currently applies only to monophonic sounds + */ +#define ALC_CONVERT_DATA_UPON_LOADING 0xF001 + +/** + * Render Quality. + */ +#define ALC_SPATIAL_RENDERING_QUALITY 0xF002 + #define ALC_SPATIAL_RENDERING_QUALITY_HIGH 'rqhi' + #define ALC_SPATIAL_RENDERING_QUALITY_LOW 'rdlo' + +/** + * Mixer Output Rate. + */ +#define ALC_MIXER_OUTPUT_RATE 0xF003 + +/** + * Maximum Mixer Busses. + * Set this before opening a new OAL device to indicate how many busses on the mixer + * are desired. Get returns either the current devices bus count value, or the value + * that will be used to open a device + */ +#define ALC_MIXER_MAXIMUM_BUSSES 0xF004 + +/** + * Render Channels. + * Allows a user to force OpenAL to render to stereo, regardless of the audio hardware being used + */ +#define ALC_RENDER_CHANNEL_COUNT 0xF005 + #define ALC_RENDER_CHANNEL_COUNT_STEREO 'rcst' + #define ALC_RENDER_CHANNEL_COUNT_MULTICHANNEL 'rcmc' + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/osx/OpenAL.framework/Versions/A/Headers/altypes.h b/openal/osx/OpenAL.framework/Versions/A/Headers/altypes.h new file mode 100644 index 000000000..6e96d334e --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Headers/altypes.h @@ -0,0 +1,326 @@ +#ifndef _ALTYPES_H_ +#define _ALTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** OpenAL boolean type. */ +typedef char ALboolean; + +/** OpenAL 8bit signed byte. */ +typedef char ALbyte; + +/** OpenAL 8bit unsigned byte. */ +typedef unsigned char ALubyte; + +/** OpenAL 16bit signed short integer type. */ +typedef short ALshort; + +/** OpenAL 16bit unsigned short integer type. */ +typedef unsigned short ALushort; + +/** OpenAL 32bit unsigned integer type. */ +typedef unsigned ALuint; + +/** OpenAL 32bit signed integer type. */ +typedef int ALint; + +/** OpenAL 32bit floating point type. */ +typedef float ALfloat; + +/** OpenAL 64bit double point type. */ +typedef double ALdouble; + +/** OpenAL 32bit type. */ +typedef unsigned int ALsizei; + +/** OpenAL void type */ +typedef void ALvoid; + +/** OpenAL enumerations. */ +typedef int ALenum; + +/* Bad value. */ +#define AL_INVALID (-1) + +/* Disable value. */ +#define AL_NONE 0 + +/* Boolean False. */ +#define AL_FALSE 0 + +/* Boolean True. */ +#define AL_TRUE 1 + +/** + * Indicate the type of AL_SOURCE. + * Sources can be spatialized + */ +#define AL_SOURCE_TYPE 0x200 + +/** Indicate source has absolute coordinates. */ +#define AL_SOURCE_ABSOLUTE 0x201 + +/** Indicate Source has listener relative coordinates. */ +#define AL_SOURCE_RELATIVE 0x202 + +/** + * Directional source, inner cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_INNER_ANGLE 0x1001 + +/** + * Directional source, outer cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_OUTER_ANGLE 0x1002 + +/** + * Specify the pitch to be applied, either at source, + * or on mixer results, at listener. + * Range: [0.5-2.0] + * Default: 1.0 + */ +#define AL_PITCH 0x1003 + +/** + * Specify the current location in three dimensional space. + * OpenAL, like OpenGL, uses a right handed coordinate system, + * where in a frontal default view X (thumb) points right, + * Y points up (index finger), and Z points towards the + * viewer/camera (middle finger). + * To switch from a left handed coordinate system, flip the + * sign on the Z coordinate. + * Listener position is always in the world coordinate system. + */ +#define AL_POSITION 0x1004 + +/** Specify the current direction as forward vector. */ +#define AL_DIRECTION 0x1005 + +/** Specify the current velocity in three dimensional space. */ +#define AL_VELOCITY 0x1006 + +/** + * Indicate whether source has to loop infinite. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + */ +#define AL_LOOPING 0x1007 + +/** + * Indicate the buffer to provide sound samples. + * Type: ALuint. + * Range: any valid Buffer id. + */ +#define AL_BUFFER 0x1009 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_GAIN 0x100A + +/** + * Indicate minimum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MIN_GAIN 0x100D + +/** + * Indicate maximum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MAX_GAIN 0x100E + +/** + * Specify the current orientation. + * Type: ALfv6 (at/up) + * Range: N/A + */ +#define AL_ORIENTATION 0x100F + +/* byte offset into source (in canon format). -1 if source + * is not playing. Don't set this, get this. + * + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_REFERENCE_DISTANCE 0x1020 + + /** + * Indicate the rolloff factor for the source. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Specify the maximum distance. + * Type: ALfloat + * Range: [0.0 - ] + */ +#define AL_MAX_DISTANCE 0x1023 + +/** + * Source state information + */ +#define AL_SOURCE_STATE 0x1010 +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Buffer Queue params + */ +#define AL_BUFFERS_QUEUED 0x1015 +#define AL_BUFFERS_PROCESSED 0x1016 + +/** Sound buffers: format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** + * Sound buffers: frequency, in units of Hertz [Hz]. + * This is the number of samples per second. Half of the + * sample frequency marks the maximum significant + * frequency component. + */ +#define AL_FREQUENCY 0x2001 +#define AL_BITS 0x2002 +#define AL_CHANNELS 0x2003 +#define AL_SIZE 0x2004 +#define AL_DATA 0x2005 + +/** + * Buffer state. + * + * Not supported for public use (yet). + */ +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 + +/** Errors: No Error. */ +#define AL_NO_ERROR AL_FALSE + +/** + * Illegal name passed as an argument to an AL call. + */ +#define AL_INVALID_NAME 0xA001 + +/** + * Illegal enum passed as an argument to an AL call. + */ +#define AL_INVALID_ENUM 0xA002 +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define AL_INVALID_VALUE 0xA003 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define AL_INVALID_OPERATION 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define AL_OUT_OF_MEMORY 0xA005 + +/** Context strings: Vendor Name. */ +#define AL_VENDOR 0xB001 +#define AL_VERSION 0xB002 +#define AL_RENDERER 0xB003 +#define AL_EXTENSIONS 0xB004 + +/** Global tweakage. */ + +/** + * Doppler scale. Default 1.0 + */ +#define AL_DOPPLER_FACTOR 0xC000 + +/** + * Doppler velocity. Default 1.0 + */ +#define AL_DOPPLER_VELOCITY 0xC001 + +/** + * Distance model. Default AL_INVERSE_DISTANCE_CLAMPED + */ +#define AL_DISTANCE_MODEL 0xD000 + +/** Distance models. */ + +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 + + /** + * enables + */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openal/osx/OpenAL.framework/Versions/A/Headers/alut.h b/openal/osx/OpenAL.framework/Versions/A/Headers/alut.h new file mode 100644 index 000000000..0b1baea41 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Headers/alut.h @@ -0,0 +1,55 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef _ALUT_H_ +#define _ALUT_H_ + +#define ALUTAPI +#define ALUTAPIENTRY + +#include "al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif +#endif + +ALUTAPI ALvoid ALUTAPIENTRY alutInit(ALint *argc,ALbyte **argv); +ALUTAPI ALvoid ALUTAPIENTRY alutExit(ALvoid); +ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq); +ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq); +ALUTAPI ALvoid ALUTAPIENTRY alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq); + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openal/osx/OpenAL.framework/Versions/A/OpenAL b/openal/osx/OpenAL.framework/Versions/A/OpenAL new file mode 100644 index 000000000..b03b04f17 Binary files /dev/null and b/openal/osx/OpenAL.framework/Versions/A/OpenAL differ diff --git a/openal/osx/OpenAL.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/openal/osx/OpenAL.framework/Versions/A/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..fa858023e Binary files /dev/null and b/openal/osx/OpenAL.framework/Versions/A/Resources/English.lproj/InfoPlist.strings differ diff --git a/openal/osx/OpenAL.framework/Versions/A/Resources/Info.plist b/openal/osx/OpenAL.framework/Versions/A/Resources/Info.plist new file mode 100644 index 000000000..a811c8bf9 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + OpenAL + CFBundleGetInfoString + OpenAL + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + OpenAL + CFBundlePackageType + FMWK + CFBundleShortVersionString + OpenAL + CFBundleSignature + ???? + CFBundleVersion + 1.0.1d1 + CSResourcesFileMapped + + + diff --git a/openal/osx/OpenAL.framework/Versions/A/Resources/READ_ME b/openal/osx/OpenAL.framework/Versions/A/Resources/READ_ME new file mode 100644 index 000000000..378b78178 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Resources/READ_ME @@ -0,0 +1,86 @@ + +February 13th, 2004 - Apple Computer Inc. +updated: March 15th, 2004 - Apple Computer Inc. + +---------------------------------------------------------------------------------------------------------------------- +READ ME: OPEN AL - OSX IMPLEMENTATION USING THE 3DMIXER AUDIOUNIT +---------------------------------------------------------------------------------------------------------------------- + +This Read Me should accompany the 3DMixer implementation of OpenAL (Open Audio Library). + +CoreAUdio SDK Requirements +----------------------- +Building this implementation of OpenAL for Mac OSX requires the latest CoreAudio SDK (version 1.3.1), due to it use +of new CoreAudio Public Utility classes. + +CoreAudio Version requirements +----------------------- +There are Recommended and Minimum CoreAudio framework and component pieces for running this implementation +of OpenAL for Mac OSX: + + Recommended: + ------------ + OSX: version 10.2.6 AND + QuickTime: version 6.5.1 + AudioToolbox.framework (version 1.3.2) + AudioUnit.framework (version 1.3.2) + CoreAudio.component (version 1.3.2 - this version contains the 2.0 version of the 3DMixer AudioUnit) + + Minimum: + ------------ + OSX: version 10.2 (Jaguar) AND + QuickTime: version 6.4 + AudioToolbox.framework (version 1.2xxxxx) + AudioUnit.framework (version 1.2xxxxx) + CoreAudio.component (version 1.2xxxxxx - this version contains the 1.3 version of the 3DMixer AudioUnit) + +---------------------------------------------------------------------------------------------------------------------- +OpenAL Extensions: +---------------------------------------------------------------------------------------------------------------------- + +This implementation has the following OpenAL extensions. These constants can be found in the included "alctypes.h" header. + +***** ALC_CONVERT_DATA_UPON_LOADING +This extension allows the caller to tell OpenAL to preconvert to the native CoreAudio format, the audio data passed to the +library with the alBufferData() call. Preconverting the audio data, reduces CPU usage by removing an audio data conversion +(per source) at render timem at the expense of a larger memory footprint. + +This feature is toggled on/off by using the alDisable() & alEnable() APIs. This setting will be applied to all subsequent +calls to alBufferData(). + +***** ALC_SPATIAL_RENDERING_QUALITY +This extension allows the application to specify the quality of spatial rendering to better suit the resources of the CPU. +At this time, the quality settings are only applied when rendering to stereo hw. All multichannel rendering uses the same +spatilaization setting on the 3DMixer. Use the alSetInteger() & alGetInteger() APIs to specify and retrieve this setting. +This implmentation provides 2 setting constants: ALC_SPATIAL_RENDERING_QUALITY_HIGH (HRTF) + ALC_SPATIAL_RENDERING_QUALITY_LOW (EqualPowerPanning) + +note: This implementation applies the setting to all the OAL Sources of an OAL Context. However, spatial settings can be applied to +each input bus of the 3DMixer, so it is possible to have this setting on a per OAL Source basis, allowing the developer to give +quality priorities to the various sounds used in an application. + +note: Currently, all stereo sounds are 'passed thru' with no spatial rendering applied. This has the best output quality for rendering +what are typically background sound tracks. However, the 3DMixer has the ability to render a stereo source to a spatial coordinate +if this was desired and support to do so would be trivial. + +***** ALC_MIXER_OUTPUT_RATE +This extension allows the developer to let the AudioGraph be efficient about sample rate conversion. If for example, all sounds +being played have a sample rate of 44k, but the output hardware is set to 48k, then it is best for the 3DMixer to leave the +the audio data (Mixer Outputut Rate) at 44k, letting the output AU rate convert the streams after they have been mixed. By default, +this is set to 44k which is very common sample rate for sound hw. + +***** ALC_MIXER_MAXIMUM_BUSSES +This extension allows the developer to optimize the 3DMixer by setting it available input bus count. This allows the 3DMixer to be as +efficient as possible in resource allocations. By default, the 3DMixer currently defaults to 64 busses (note: the 1.3 version of the +3DMixer does not respect this setting, so always confirm the bus count with a get call, after setting the bus count and creating a new device). +Use: set the bus count before making a call to alOpenDevice(). This will cause the library to set the mixer to you desired bus count. +as it creates the AUGraph. Use the alSetInteger() & alGetInteger() APIs to specify and retrieve this setting. + +***** ALC_RENDER_CHANNEL_COUNT +Because the audio system has no way to know if a user has actually connected a speaker to an output of the audio hardware, it may be desired +to allow the user to clamp all rendering to stereo. Use the alSetInteger() & alGetInteger() APIs to specify and retrieve this setting. +This implmentation provides 2 setting constants: ALC_RENDER_CHANNEL_COUNT_STEREO (clamp the 3DMixer output rendering to stereo, regardless of the hw capabilities) + ALC_RENDER_CHANNEL_COUNT_MULTICHANNEL (try and render to the maximum speakers possible by interrogating the device) + +---------------------------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------------------------- diff --git a/openal/osx/OpenAL.framework/Versions/A/Resources/pbdevelopment.plist b/openal/osx/OpenAL.framework/Versions/A/Resources/pbdevelopment.plist new file mode 100644 index 000000000..151e2d617 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/A/Resources/pbdevelopment.plist @@ -0,0 +1,8 @@ + + + + + PBXProjectSourcePath + /Users/mmarks/Development/OpenAL/openal/macosx/al_osx.xcode + + diff --git a/openal/osx/OpenAL.framework/Versions/Current b/openal/osx/OpenAL.framework/Versions/Current new file mode 100644 index 000000000..8c7e5a667 --- /dev/null +++ b/openal/osx/OpenAL.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/openal/stubs.cpp b/openal/stubs.cpp new file mode 100644 index 000000000..b5143eb36 --- /dev/null +++ b/openal/stubs.cpp @@ -0,0 +1,126 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#include "../sound/snd_local.h" + +AL_API ALenum AL_APIENTRY alGetError() { + return AL_NO_ERROR; +} + +AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid ) { + return AL_FALSE; +} + +AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers ) { } + +AL_API void AL_APIENTRY alSourceStop( ALuint sid ) { } + +AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum pname, ALint* value ) { } + +AL_API ALint AL_APIENTRY alGetInteger( ALenum param ) { return 0; } + +ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *alcHandle ) { } + +ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALchar *tokstr ) { + return NULL; +} + +AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers ) { } + +AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* fname ) { + return AL_FALSE; +} + +AL_API void AL_APIENTRY alBufferData( ALuint buffer, + ALenum format, + const ALvoid* data, + ALsizei size, + ALsizei freq ) { } + +ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *alcHandle ) { + return 0; +} + +ALC_API ALCvoid ALC_APIENTRY alcProcessContext( ALCcontext *alcHandle ) { + return; +} + +ALC_API ALCvoid ALC_APIENTRY alcDestroyContext( ALCcontext *alcHandle ) { + return; +} + +ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *deviceHandle, ALCenum token ) { + return NULL; +} + +AL_API void AL_APIENTRY alBufferData( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ) { } + +AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, ALuint* buffers ) { } + +AL_API ALboolean AL_APIENTRY alIsExtensionPresent( ALubyte* fname ) { + return AL_FALSE; +} + +AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources ) { } + +AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename ) { + return 0; +} + +AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname ) { + return NULL; +} + +ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *dev, + const ALCint* attrlist ) { + return NULL; +} + +ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( ALubyte *tokstr ) { + return NULL; +} + +AL_API void AL_APIENTRY alListenerfv( ALenum pname, const ALfloat* param ) { } + +AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ) { } + +AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value ) { } + +AL_API void AL_APIENTRY alListenerf( ALenum pname, ALfloat param ) { } + +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *dev ) { return false; } + +AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint buffer ) { + return AL_FALSE; +} + +AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, + ALfloat f1, ALfloat f2, ALfloat f3 ) { } + +AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources ) { } + +AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value ) { } + +AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ) { } + +AL_API void AL_APIENTRY alSourcePlay( ALuint sid ) { } diff --git a/renderer/Cinematic.cpp b/renderer/Cinematic.cpp new file mode 100644 index 000000000..4591d9c3d --- /dev/null +++ b/renderer/Cinematic.cpp @@ -0,0 +1,1765 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#define JPEG_INTERNALS +extern "C" { +#include "jpeg-6/jpeglib.h" +} + +#include "tr_local.h" + +#define CIN_system 1 +#define CIN_loop 2 +#define CIN_hold 4 +#define CIN_silent 8 +#define CIN_shader 16 + +class idCinematicLocal : public idCinematic { +public: + idCinematicLocal(); + virtual ~idCinematicLocal(); + + virtual bool InitFromFile( const char *qpath, bool looping ); + virtual cinData_t ImageForTime( int milliseconds ); + virtual int AnimationLength(); + virtual void Close(); + virtual void ResetTime(int time); + +private: + unsigned int mcomp[256]; + byte ** qStatus[2]; + idStr fileName; + int CIN_WIDTH, CIN_HEIGHT; + idFile * iFile; + cinStatus_t status; + long tfps; + long RoQPlayed; + long ROQSize; + unsigned int RoQFrameSize; + long onQuad; + long numQuads; + long samplesPerLine; + unsigned int roq_id; + long screenDelta; + byte * buf; + long samplesPerPixel; // defaults to 2 + unsigned int xsize, ysize, maxsize, minsize; + long normalBuffer0; + long roq_flags; + long roqF0; + long roqF1; + long t[2]; + long roqFPS; + long drawX, drawY; + + int animationLength; + int startTime; + float frameRate; + + byte * image; + + bool looping; + bool dirty; + bool half; + bool smootheddouble; + bool inMemory; + + void RoQ_init( void ); + void blitVQQuad32fs( byte **status, unsigned char *data ); + void RoQShutdown( void ); + void RoQInterrupt(void); + + void move8_32( byte *src, byte *dst, int spl ); + void move4_32( byte *src, byte *dst, int spl ); + void blit8_32( byte *src, byte *dst, int spl ); + void blit4_32( byte *src, byte *dst, int spl ); + void blit2_32( byte *src, byte *dst, int spl ); + + unsigned short yuv_to_rgb( long y, long u, long v ); + unsigned int yuv_to_rgb24( long y, long u, long v ); + + void decodeCodeBook( byte *input, unsigned short roq_flags ); + void recurseQuad( long startX, long startY, long quadSize, long xOff, long yOff ); + void setupQuad( long xOff, long yOff ); + void readQuadInfo( byte *qData ); + void RoQPrepMcomp( long xoff, long yoff ); + void RoQReset(); +}; + +const int DEFAULT_CIN_WIDTH = 512; +const int DEFAULT_CIN_HEIGHT = 512; +const int MAXSIZE = 8; +const int MINSIZE = 4; + +const int ROQ_FILE = 0x1084; +const int ROQ_QUAD = 0x1000; +const int ROQ_QUAD_INFO = 0x1001; +const int ROQ_CODEBOOK = 0x1002; +const int ROQ_QUAD_VQ = 0x1011; +const int ROQ_QUAD_JPEG = 0x1012; +const int ROQ_QUAD_HANG = 0x1013; +const int ROQ_PACKET = 0x1030; +const int ZA_SOUND_MONO = 0x1020; +const int ZA_SOUND_STEREO = 0x1021; + +// temporary buffers used by all cinematics +static long ROQ_YY_tab[256]; +static long ROQ_UB_tab[256]; +static long ROQ_UG_tab[256]; +static long ROQ_VG_tab[256]; +static long ROQ_VR_tab[256]; +static byte * file = NULL; +static unsigned short * vq2 = NULL; +static unsigned short * vq4 = NULL; +static unsigned short * vq8 = NULL; + + + +//=========================================== + +/* +============== +idCinematicLocal::InitCinematic +============== +*/ +void idCinematic::InitCinematic( void ) { + float t_ub,t_vr,t_ug,t_vg; + long i; + + // generate YUV tables + t_ub = (1.77200f/2.0f) * (float)(1<<6) + 0.5f; + t_vr = (1.40200f/2.0f) * (float)(1<<6) + 0.5f; + t_ug = (0.34414f/2.0f) * (float)(1<<6) + 0.5f; + t_vg = (0.71414f/2.0f) * (float)(1<<6) + 0.5f; + for( i = 0; i < 256; i++ ) { + float x = (float)(2 * i - 255); + + ROQ_UB_tab[i] = (long)( ( t_ub * x) + (1<<5)); + ROQ_VR_tab[i] = (long)( ( t_vr * x) + (1<<5)); + ROQ_UG_tab[i] = (long)( (-t_ug * x) ); + ROQ_VG_tab[i] = (long)( (-t_vg * x) + (1<<5)); + ROQ_YY_tab[i] = (long)( (i << 6) | (i >> 2) ); + } + + file = (byte *)Mem_Alloc( 65536 ); + vq2 = (word *)Mem_Alloc( 256*16*4 * sizeof( word ) ); + vq4 = (word *)Mem_Alloc( 256*64*4 * sizeof( word ) ); + vq8 = (word *)Mem_Alloc( 256*256*4 * sizeof( word ) ); +} + +/* +============== +idCinematicLocal::ShutdownCinematic +============== +*/ +void idCinematic::ShutdownCinematic( void ) { + Mem_Free( file ); + file = NULL; + Mem_Free( vq2 ); + vq2 = NULL; + Mem_Free( vq4 ); + vq4 = NULL; + Mem_Free( vq8 ); + vq8 = NULL; +} + +/* +============== +idCinematicLocal::Alloc +============== +*/ +idCinematic *idCinematic::Alloc() { + return new idCinematicLocal; +} + +/* +============== +idCinematicLocal::~idCinematic +============== +*/ +idCinematic::~idCinematic( ) { + Close(); +} + +/* +============== +idCinematicLocal::InitFromFile +============== +*/ +bool idCinematic::InitFromFile( const char *qpath, bool looping ) { + return false; +} + +/* +============== +idCinematicLocal::AnimationLength +============== +*/ +int idCinematic::AnimationLength() { + return 0; +} + +/* +============== +idCinematicLocal::ResetTime +============== +*/ +void idCinematic::ResetTime(int milliseconds) { +} + +/* +============== +idCinematicLocal::ImageForTime +============== +*/ +cinData_t idCinematic::ImageForTime( int milliseconds ) { + cinData_t c; + memset( &c, 0, sizeof( c ) ); + return c; +} + +/* +============== +idCinematicLocal::Close +============== +*/ +void idCinematic::Close() { +} + +//=========================================== + +/* +============== +idCinematicLocal::idCinematicLocal +============== +*/ +idCinematicLocal::idCinematicLocal() { + image = NULL; + status = FMV_EOF; + buf = NULL; + iFile = NULL; + + qStatus[0] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) ); + qStatus[1] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) ); +} + +/* +============== +idCinematicLocal::~idCinematicLocal +============== +*/ +idCinematicLocal::~idCinematicLocal() { + Close(); + + Mem_Free( qStatus[0] ); + qStatus[0] = NULL; + Mem_Free( qStatus[1] ); + qStatus[1] = NULL; +} + +/* +============== +idCinematicLocal::InitFromFile +============== +*/ +bool idCinematicLocal::InitFromFile( const char *qpath, bool amilooping ) { + unsigned short RoQID; + + Close(); + + inMemory = 0; + animationLength = 100000; + + if ( strstr( qpath, "/" ) == NULL && strstr( qpath, "\\" ) == NULL ) { + sprintf( fileName, "video/%s", qpath ); + } else { + sprintf( fileName, "%s", qpath ); + } + + iFile = fileSystem->OpenFileRead( fileName ); + + if ( !iFile ) { + return false; + } + + ROQSize = iFile->Length(); + + looping = amilooping; + + CIN_HEIGHT = DEFAULT_CIN_HEIGHT; + CIN_WIDTH = DEFAULT_CIN_WIDTH; + samplesPerPixel = 4; + startTime = 0; //Sys_Milliseconds(); + buf = NULL; + + iFile->Read( file, 16 ); + + RoQID = (unsigned short)(file[0]) + (unsigned short)(file[1])*256; + + frameRate = file[6]; + if ( frameRate == 32.0f ) { + frameRate = 1000.0f / 32.0f; + } + + if ( RoQID == ROQ_FILE ) { + RoQ_init(); + status = FMV_PLAY; + ImageForTime( 0 ); + status = ( looping ) ? FMV_PLAY : FMV_IDLE; + return true; + } + + RoQShutdown(); + return false; +} + +/* +============== +idCinematicLocal::Close +============== +*/ +void idCinematicLocal::Close() { + if ( image ) { + Mem_Free( (void *)image ); + image = NULL; + buf = NULL; + status = FMV_EOF; + } + RoQShutdown(); +} + +/* +============== +idCinematicLocal::AnimationLength +============== +*/ +int idCinematicLocal::AnimationLength() { + return animationLength; +} + +/* +============== +idCinematicLocal::ResetTime +============== +*/ +void idCinematicLocal::ResetTime(int time) { + startTime = ( backEnd.viewDef ) ? 1000 * backEnd.viewDef->floatTime : -1; + status = FMV_PLAY; +} + +/* +============== +idCinematicLocal::ImageForTime +============== +*/ +cinData_t idCinematicLocal::ImageForTime( int thisTime ) { + cinData_t cinData; + + if ( thisTime < 0 ) { + thisTime = 0; + } + + memset( &cinData, 0, sizeof(cinData) ); + + if ( r_skipROQ.GetBool() ) { + return cinData; + } + + if ( status == FMV_EOF || status == FMV_IDLE ) { + return cinData; + } + + if ( buf == NULL || startTime == -1 ) { + if ( startTime == -1 ) { + RoQReset(); + } + startTime = thisTime; + } + + tfps = ( ( thisTime - startTime ) * frameRate ) / 1000; + + if ( tfps < 0 ) { + tfps = 0; + } + + if ( tfps < numQuads ) { + RoQReset(); + buf = NULL; + status = FMV_PLAY; + } + + if ( buf == NULL ) { + while( buf == NULL ) { + RoQInterrupt(); + } + } else { + while( (tfps != numQuads && status == FMV_PLAY) ) { + RoQInterrupt(); + } + } + + if ( status == FMV_LOOPED ) { + status = FMV_PLAY; + while( buf == NULL && status == FMV_PLAY ) { + RoQInterrupt(); + } + startTime = thisTime; + } + + if ( status == FMV_EOF ) { + if ( looping ) { + RoQReset(); + buf = NULL; + if ( status == FMV_LOOPED ) { + status = FMV_PLAY; + } + while ( buf == NULL && status == FMV_PLAY ) { + RoQInterrupt(); + } + startTime = thisTime; + } else { + status = FMV_IDLE; + RoQShutdown(); + } + } + + cinData.imageWidth = CIN_WIDTH; + cinData.imageHeight = CIN_HEIGHT; + cinData.status = status; + cinData.image = buf; + + return cinData; +} + +/* +============== +idCinematicLocal::move8_32 +============== +*/ +void idCinematicLocal::move8_32( byte *src, byte *dst, int spl ) { +#if 1 + int *dsrc, *ddst; + int dspl; + + dsrc = (int *)src; + ddst = (int *)dst; + dspl = spl>>2; + + ddst[0*dspl+0] = dsrc[0*dspl+0]; + ddst[0*dspl+1] = dsrc[0*dspl+1]; + ddst[0*dspl+2] = dsrc[0*dspl+2]; + ddst[0*dspl+3] = dsrc[0*dspl+3]; + ddst[0*dspl+4] = dsrc[0*dspl+4]; + ddst[0*dspl+5] = dsrc[0*dspl+5]; + ddst[0*dspl+6] = dsrc[0*dspl+6]; + ddst[0*dspl+7] = dsrc[0*dspl+7]; + + ddst[1*dspl+0] = dsrc[1*dspl+0]; + ddst[1*dspl+1] = dsrc[1*dspl+1]; + ddst[1*dspl+2] = dsrc[1*dspl+2]; + ddst[1*dspl+3] = dsrc[1*dspl+3]; + ddst[1*dspl+4] = dsrc[1*dspl+4]; + ddst[1*dspl+5] = dsrc[1*dspl+5]; + ddst[1*dspl+6] = dsrc[1*dspl+6]; + ddst[1*dspl+7] = dsrc[1*dspl+7]; + + ddst[2*dspl+0] = dsrc[2*dspl+0]; + ddst[2*dspl+1] = dsrc[2*dspl+1]; + ddst[2*dspl+2] = dsrc[2*dspl+2]; + ddst[2*dspl+3] = dsrc[2*dspl+3]; + ddst[2*dspl+4] = dsrc[2*dspl+4]; + ddst[2*dspl+5] = dsrc[2*dspl+5]; + ddst[2*dspl+6] = dsrc[2*dspl+6]; + ddst[2*dspl+7] = dsrc[2*dspl+7]; + + ddst[3*dspl+0] = dsrc[3*dspl+0]; + ddst[3*dspl+1] = dsrc[3*dspl+1]; + ddst[3*dspl+2] = dsrc[3*dspl+2]; + ddst[3*dspl+3] = dsrc[3*dspl+3]; + ddst[3*dspl+4] = dsrc[3*dspl+4]; + ddst[3*dspl+5] = dsrc[3*dspl+5]; + ddst[3*dspl+6] = dsrc[3*dspl+6]; + ddst[3*dspl+7] = dsrc[3*dspl+7]; + + ddst[4*dspl+0] = dsrc[4*dspl+0]; + ddst[4*dspl+1] = dsrc[4*dspl+1]; + ddst[4*dspl+2] = dsrc[4*dspl+2]; + ddst[4*dspl+3] = dsrc[4*dspl+3]; + ddst[4*dspl+4] = dsrc[4*dspl+4]; + ddst[4*dspl+5] = dsrc[4*dspl+5]; + ddst[4*dspl+6] = dsrc[4*dspl+6]; + ddst[4*dspl+7] = dsrc[4*dspl+7]; + + ddst[5*dspl+0] = dsrc[5*dspl+0]; + ddst[5*dspl+1] = dsrc[5*dspl+1]; + ddst[5*dspl+2] = dsrc[5*dspl+2]; + ddst[5*dspl+3] = dsrc[5*dspl+3]; + ddst[5*dspl+4] = dsrc[5*dspl+4]; + ddst[5*dspl+5] = dsrc[5*dspl+5]; + ddst[5*dspl+6] = dsrc[5*dspl+6]; + ddst[5*dspl+7] = dsrc[5*dspl+7]; + + ddst[6*dspl+0] = dsrc[6*dspl+0]; + ddst[6*dspl+1] = dsrc[6*dspl+1]; + ddst[6*dspl+2] = dsrc[6*dspl+2]; + ddst[6*dspl+3] = dsrc[6*dspl+3]; + ddst[6*dspl+4] = dsrc[6*dspl+4]; + ddst[6*dspl+5] = dsrc[6*dspl+5]; + ddst[6*dspl+6] = dsrc[6*dspl+6]; + ddst[6*dspl+7] = dsrc[6*dspl+7]; + + ddst[7*dspl+0] = dsrc[7*dspl+0]; + ddst[7*dspl+1] = dsrc[7*dspl+1]; + ddst[7*dspl+2] = dsrc[7*dspl+2]; + ddst[7*dspl+3] = dsrc[7*dspl+3]; + ddst[7*dspl+4] = dsrc[7*dspl+4]; + ddst[7*dspl+5] = dsrc[7*dspl+5]; + ddst[7*dspl+6] = dsrc[7*dspl+6]; + ddst[7*dspl+7] = dsrc[7*dspl+7]; +#else + double *dsrc, *ddst; + int dspl; + + dsrc = (double *)src; + ddst = (double *)dst; + dspl = spl>>3; + + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; +#endif +} + +/* +============== +idCinematicLocal::move4_32 +============== +*/ +void idCinematicLocal::move4_32( byte *src, byte *dst, int spl ) { +#if 1 + int *dsrc, *ddst; + int dspl; + + dsrc = (int *)src; + ddst = (int *)dst; + dspl = spl>>2; + + ddst[0*dspl+0] = dsrc[0*dspl+0]; + ddst[0*dspl+1] = dsrc[0*dspl+1]; + ddst[0*dspl+2] = dsrc[0*dspl+2]; + ddst[0*dspl+3] = dsrc[0*dspl+3]; + + ddst[1*dspl+0] = dsrc[1*dspl+0]; + ddst[1*dspl+1] = dsrc[1*dspl+1]; + ddst[1*dspl+2] = dsrc[1*dspl+2]; + ddst[1*dspl+3] = dsrc[1*dspl+3]; + + ddst[2*dspl+0] = dsrc[2*dspl+0]; + ddst[2*dspl+1] = dsrc[2*dspl+1]; + ddst[2*dspl+2] = dsrc[2*dspl+2]; + ddst[2*dspl+3] = dsrc[2*dspl+3]; + + ddst[3*dspl+0] = dsrc[3*dspl+0]; + ddst[3*dspl+1] = dsrc[3*dspl+1]; + ddst[3*dspl+2] = dsrc[3*dspl+2]; + ddst[3*dspl+3] = dsrc[3*dspl+3]; +#else + double *dsrc, *ddst; + int dspl; + + dsrc = (double *)src; + ddst = (double *)dst; + dspl = spl>>3; + + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += dspl; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; +#endif +} + +/* +============== +idCinematicLocal::blit8_32 +============== +*/ +void idCinematicLocal::blit8_32( byte *src, byte *dst, int spl ) { +#if 1 + int *dsrc, *ddst; + int dspl; + + dsrc = (int *)src; + ddst = (int *)dst; + dspl = spl>>2; + + ddst[0*dspl+0] = dsrc[ 0]; + ddst[0*dspl+1] = dsrc[ 1]; + ddst[0*dspl+2] = dsrc[ 2]; + ddst[0*dspl+3] = dsrc[ 3]; + ddst[0*dspl+4] = dsrc[ 4]; + ddst[0*dspl+5] = dsrc[ 5]; + ddst[0*dspl+6] = dsrc[ 6]; + ddst[0*dspl+7] = dsrc[ 7]; + + ddst[1*dspl+0] = dsrc[ 8]; + ddst[1*dspl+1] = dsrc[ 9]; + ddst[1*dspl+2] = dsrc[10]; + ddst[1*dspl+3] = dsrc[11]; + ddst[1*dspl+4] = dsrc[12]; + ddst[1*dspl+5] = dsrc[13]; + ddst[1*dspl+6] = dsrc[14]; + ddst[1*dspl+7] = dsrc[15]; + + ddst[2*dspl+0] = dsrc[16]; + ddst[2*dspl+1] = dsrc[17]; + ddst[2*dspl+2] = dsrc[18]; + ddst[2*dspl+3] = dsrc[19]; + ddst[2*dspl+4] = dsrc[20]; + ddst[2*dspl+5] = dsrc[21]; + ddst[2*dspl+6] = dsrc[22]; + ddst[2*dspl+7] = dsrc[23]; + + ddst[3*dspl+0] = dsrc[24]; + ddst[3*dspl+1] = dsrc[25]; + ddst[3*dspl+2] = dsrc[26]; + ddst[3*dspl+3] = dsrc[27]; + ddst[3*dspl+4] = dsrc[28]; + ddst[3*dspl+5] = dsrc[29]; + ddst[3*dspl+6] = dsrc[30]; + ddst[3*dspl+7] = dsrc[31]; + + ddst[4*dspl+0] = dsrc[32]; + ddst[4*dspl+1] = dsrc[33]; + ddst[4*dspl+2] = dsrc[34]; + ddst[4*dspl+3] = dsrc[35]; + ddst[4*dspl+4] = dsrc[36]; + ddst[4*dspl+5] = dsrc[37]; + ddst[4*dspl+6] = dsrc[38]; + ddst[4*dspl+7] = dsrc[39]; + + ddst[5*dspl+0] = dsrc[40]; + ddst[5*dspl+1] = dsrc[41]; + ddst[5*dspl+2] = dsrc[42]; + ddst[5*dspl+3] = dsrc[43]; + ddst[5*dspl+4] = dsrc[44]; + ddst[5*dspl+5] = dsrc[45]; + ddst[5*dspl+6] = dsrc[46]; + ddst[5*dspl+7] = dsrc[47]; + + ddst[6*dspl+0] = dsrc[48]; + ddst[6*dspl+1] = dsrc[49]; + ddst[6*dspl+2] = dsrc[50]; + ddst[6*dspl+3] = dsrc[51]; + ddst[6*dspl+4] = dsrc[52]; + ddst[6*dspl+5] = dsrc[53]; + ddst[6*dspl+6] = dsrc[54]; + ddst[6*dspl+7] = dsrc[55]; + + ddst[7*dspl+0] = dsrc[56]; + ddst[7*dspl+1] = dsrc[57]; + ddst[7*dspl+2] = dsrc[58]; + ddst[7*dspl+3] = dsrc[59]; + ddst[7*dspl+4] = dsrc[60]; + ddst[7*dspl+5] = dsrc[61]; + ddst[7*dspl+6] = dsrc[62]; + ddst[7*dspl+7] = dsrc[63]; +#else + double *dsrc, *ddst; + int dspl; + + dsrc = (double *)src; + ddst = (double *)dst; + dspl = spl>>3; + + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; + dsrc += 4; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3]; +#endif +} + +/* +============== +idCinematicLocal::blit4_32 +============== +*/ +void idCinematicLocal::blit4_32( byte *src, byte *dst, int spl ) { +#if 1 + int *dsrc, *ddst; + int dspl; + + dsrc = (int *)src; + ddst = (int *)dst; + dspl = spl>>2; + + ddst[0*dspl+0] = dsrc[ 0]; + ddst[0*dspl+1] = dsrc[ 1]; + ddst[0*dspl+2] = dsrc[ 2]; + ddst[0*dspl+3] = dsrc[ 3]; + ddst[1*dspl+0] = dsrc[ 4]; + ddst[1*dspl+1] = dsrc[ 5]; + ddst[1*dspl+2] = dsrc[ 6]; + ddst[1*dspl+3] = dsrc[ 7]; + ddst[2*dspl+0] = dsrc[ 8]; + ddst[2*dspl+1] = dsrc[ 9]; + ddst[2*dspl+2] = dsrc[10]; + ddst[2*dspl+3] = dsrc[11]; + ddst[3*dspl+0] = dsrc[12]; + ddst[3*dspl+1] = dsrc[13]; + ddst[3*dspl+2] = dsrc[14]; + ddst[3*dspl+3] = dsrc[15]; +#else + double *dsrc, *ddst; + int dspl; + + dsrc = (double *)src; + ddst = (double *)dst; + dspl = spl>>3; + + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += 2; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += 2; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; + dsrc += 2; ddst += dspl; + ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; +#endif +} + +/* +============== +idCinematicLocal::blit2_32 +============== +*/ +void idCinematicLocal::blit2_32( byte *src, byte *dst, int spl ) { +#if 1 + int *dsrc, *ddst; + int dspl; + + dsrc = (int *)src; + ddst = (int *)dst; + dspl = spl>>2; + + ddst[0*dspl+0] = dsrc[0]; + ddst[0*dspl+1] = dsrc[1]; + ddst[1*dspl+0] = dsrc[2]; + ddst[1*dspl+1] = dsrc[3]; +#else + double *dsrc, *ddst; + int dspl; + + dsrc = (double *)src; + ddst = (double *)dst; + dspl = spl>>3; + + ddst[0] = dsrc[0]; + ddst[dspl] = dsrc[1]; +#endif +} + +/* +============== +idCinematicLocal::blitVQQuad32fs +============== +*/ +void idCinematicLocal::blitVQQuad32fs( byte **status, unsigned char *data ) { + unsigned short newd, celdata, code; + unsigned int index, i; + + newd = 0; + celdata = 0; + index = 0; + + do { + if (!newd) { + newd = 7; + celdata = data[0] + data[1]*256; + data += 2; + } else { + newd--; + } + + code = (unsigned short)(celdata&0xc000); + celdata <<= 2; + + switch (code) { + case 0x8000: // vq code + blit8_32( (byte *)&vq8[(*data)*128], status[index], samplesPerLine ); + data++; + index += 5; + break; + case 0xc000: // drop + index++; // skip 8x8 + for(i=0;i<4;i++) { + if (!newd) { + newd = 7; + celdata = data[0] + data[1]*256; + data += 2; + } else { + newd--; + } + + code = (unsigned short)(celdata&0xc000); celdata <<= 2; + + switch (code) { // code in top two bits of code + case 0x8000: // 4x4 vq code + blit4_32( (byte *)&vq4[(*data)*32], status[index], samplesPerLine ); + data++; + break; + case 0xc000: // 2x2 vq code + blit2_32( (byte *)&vq2[(*data)*8], status[index], samplesPerLine ); + data++; + blit2_32( (byte *)&vq2[(*data)*8], status[index]+8, samplesPerLine ); + data++; + blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2, samplesPerLine ); + data++; + blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2+8, samplesPerLine ); + data++; + break; + case 0x4000: // motion compensation + move4_32( status[index] + mcomp[(*data)], status[index], samplesPerLine ); + data++; + break; + } + index++; + } + break; + case 0x4000: // motion compensation + move8_32( status[index] + mcomp[(*data)], status[index], samplesPerLine ); + data++; + index += 5; + break; + case 0x0000: + index += 5; + break; + } + } while ( status[index] != NULL ); +} + +#define VQ2TO4(a,b,c,d) { \ + *c++ = a[0]; \ + *d++ = a[0]; \ + *d++ = a[0]; \ + *c++ = a[1]; \ + *d++ = a[1]; \ + *d++ = a[1]; \ + *c++ = b[0]; \ + *d++ = b[0]; \ + *d++ = b[0]; \ + *c++ = b[1]; \ + *d++ = b[1]; \ + *d++ = b[1]; \ + *d++ = a[0]; \ + *d++ = a[0]; \ + *d++ = a[1]; \ + *d++ = a[1]; \ + *d++ = b[0]; \ + *d++ = b[0]; \ + *d++ = b[1]; \ + *d++ = b[1]; \ + a += 2; b += 2; } + +#define VQ2TO2(a,b,c,d) { \ + *c++ = *a; \ + *d++ = *a; \ + *d++ = *a; \ + *c++ = *b; \ + *d++ = *b; \ + *d++ = *b; \ + *d++ = *a; \ + *d++ = *a; \ + *d++ = *b; \ + *d++ = *b; \ + a++; b++; } + +/* +============== +idCinematicLocal::yuv_to_rgb +============== +*/ +unsigned short idCinematicLocal::yuv_to_rgb( long y, long u, long v ) { + long r,g,b,YY = (long)(ROQ_YY_tab[(y)]); + + r = (YY + ROQ_VR_tab[v]) >> 9; + g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 8; + b = (YY + ROQ_UB_tab[u]) >> 9; + + if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0; + if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31; + + return (unsigned short)((r<<11)+(g<<5)+(b)); +} + +/* +============== +idCinematicLocal::yuv_to_rgb24 +============== +*/ +unsigned int idCinematicLocal::yuv_to_rgb24( long y, long u, long v ) { + long r,g,b,YY = (long)(ROQ_YY_tab[(y)]); + + r = (YY + ROQ_VR_tab[v]) >> 6; + g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 6; + b = (YY + ROQ_UB_tab[u]) >> 6; + + if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0; + if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; + + return LittleLong((r)+(g<<8)+(b<<16)); +} + +/* +============== +idCinematicLocal::decodeCodeBook +============== +*/ +void idCinematicLocal::decodeCodeBook( byte *input, unsigned short roq_flags ) { + long i, j, two, four; + unsigned short *aptr, *bptr, *cptr, *dptr; + long y0,y1,y2,y3,cr,cb; + unsigned int *iaptr, *ibptr, *icptr, *idptr; + + if (!roq_flags) { + two = four = 256; + } else { + two = roq_flags>>8; + if (!two) two = 256; + four = roq_flags&0xff; + } + + four *= 2; + + bptr = (unsigned short *)vq2; + + if (!half) { + if (!smootheddouble) { +// +// normal height +// + if (samplesPerPixel==2) { + for(i=0;i CIN_WIDTH) bigx = CIN_WIDTH; + if (bigy > CIN_HEIGHT) bigy = CIN_HEIGHT; + + if ( (startX >= lowx) && (startX+quadSize) <= (bigx) && (startY+quadSize) <= (bigy) && (startY >= lowy) && quadSize <= MAXSIZE) { + useY = startY; + scroff = image + (useY+((CIN_HEIGHT-bigy)>>1)+yOff)*(samplesPerLine) + (((startX+xOff))*samplesPerPixel); + + qStatus[0][onQuad ] = scroff; + qStatus[1][onQuad++] = scroff+offset; + } + + if ( quadSize != MINSIZE ) { + quadSize >>= 1; + recurseQuad( startX, startY , quadSize, xOff, yOff ); + recurseQuad( startX+quadSize, startY , quadSize, xOff, yOff ); + recurseQuad( startX, startY+quadSize , quadSize, xOff, yOff ); + recurseQuad( startX+quadSize, startY+quadSize , quadSize, xOff, yOff ); + } +} + +/* +============== +idCinematicLocal::setupQuad +============== +*/ +void idCinematicLocal::setupQuad( long xOff, long yOff ) { + long numQuadCels, i,x,y; + byte *temp; + + numQuadCels = (CIN_WIDTH*CIN_HEIGHT) / (16); + numQuadCels += numQuadCels/4 + numQuadCels/16; + numQuadCels += 64; // for overflow + + numQuadCels = (xsize*ysize) / (16); + numQuadCels += numQuadCels/4; + numQuadCels += 64; // for overflow + + onQuad = 0; + + for(y=0;y<(long)ysize;y+=16) + for(x=0;x<(long)xsize;x+=16) + recurseQuad( x, y, 16, xOff, yOff ); + + temp = NULL; + + for(i=(numQuadCels-64);iSeek( 0, FS_SEEK_SET ); + iFile->Read( file, 16 ); + RoQ_init(); + status = FMV_LOOPED; +} + + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + byte *infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ + int memsize; +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 32768 /* choose an efficiently fread'able size */ + +/* jpeg error handling */ +struct jpeg_error_mgr jerr; + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + + +METHODDEF boolean fill_input_buffer( j_decompress_ptr cinfo ) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + int nbytes; + + nbytes = INPUT_BUF_SIZE; + if (nbytes > src->memsize) nbytes = src->memsize; + if (nbytes == 0) { + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } else { + memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); + src->infile = src->infile + nbytes; + src->memsize = src->memsize - INPUT_BUF_SIZE; + } + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + + +METHODDEF void init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF void +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + src->infile = src->infile + num_bytes; + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF void +term_source (j_decompress_ptr cinfo) +{ + cinfo = cinfo; + /* no work necessary here */ +} + +GLOBAL void +jpeg_memory_src (j_decompress_ptr cinfo, byte *infile, int size) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * sizeof(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->memsize = size; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +int JPEGBlit( byte *wStatus, byte *data, int datasize ) +{ + /* This struct contains the JPEG decompression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct cinfo; + /* We use our private extension JPEG error handler. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + /* More stuff */ + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We set up the normal JPEG error routines, then override error_exit. */ + cinfo.err = jpeg_std_error(&jerr); + + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_memory_src(&cinfo, data, datasize); + + /* Step 3: read file parameters with jpeg_read_header() */ + + (void) jpeg_read_header(&cinfo, TRUE); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + + /* In this example, we don't need to change any of the defaults set by + * jpeg_read_header(), so we do nothing here. + */ + + /* Step 5: Start decompressor */ + + cinfo.dct_method = JDCT_IFAST; + cinfo.dct_method = JDCT_FASTEST; + cinfo.dither_mode = JDITHER_NONE; + cinfo.do_fancy_upsampling = FALSE; +// cinfo.out_color_space = JCS_GRAYSCALE; + + (void) jpeg_start_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = cinfo.output_width * cinfo.output_components; + + /* Make a one-row-high sample array that will go away when done with image */ + buffer = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + + wStatus += (cinfo.output_height-1)*row_stride; + while (cinfo.output_scanline < cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + (void) jpeg_read_scanlines(&cinfo, &buffer[0], 1); + + /* Assume put_scanline_someplace wants a pointer and sample count. */ + memcpy( wStatus, &buffer[0][0], row_stride ); + /* + int x; + unsigned int *buf = (unsigned int *)&buffer[0][0]; + unsigned int *out = (unsigned int *)wStatus; + for(x=0;xRead( file, RoQFrameSize+8 ); + if ( RoQPlayed >= ROQSize ) { + if (looping) { + RoQReset(); + } else { + status = FMV_EOF; + } + return; + } + + framedata = file; +// +// new frame is ready +// +redump: + switch(roq_id) + { + case ROQ_QUAD_VQ: + if ((numQuads&1)) { + normalBuffer0 = t[1]; + RoQPrepMcomp( roqF0, roqF1 ); + blitVQQuad32fs( qStatus[1], framedata); + buf = image + screenDelta; + } else { + normalBuffer0 = t[0]; + RoQPrepMcomp( roqF0, roqF1 ); + blitVQQuad32fs( qStatus[0], framedata ); + buf = image; + } + if (numQuads == 0) { // first frame + memcpy(image+screenDelta, image, samplesPerLine*ysize); + } + numQuads++; + dirty = true; + break; + case ROQ_CODEBOOK: + decodeCodeBook( framedata, (unsigned short)roq_flags ); + break; + case ZA_SOUND_MONO: + break; + case ZA_SOUND_STEREO: + break; + case ROQ_QUAD_INFO: + if (numQuads == -1) { + readQuadInfo( framedata ); + setupQuad( 0, 0 ); + } + if (numQuads != 1) numQuads = 0; + break; + case ROQ_PACKET: + inMemory = ( roq_flags != 0 ); + RoQFrameSize = 0; // for header + break; + case ROQ_QUAD_HANG: + RoQFrameSize = 0; + break; + case ROQ_QUAD_JPEG: + if (!numQuads) { + normalBuffer0 = t[0]; + JPEGBlit( image, framedata, RoQFrameSize ); + memcpy(image+screenDelta, image, samplesPerLine*ysize); + numQuads++; + } + break; + default: + status = FMV_EOF; + break; + } +// +// read in next frame data +// + if ( RoQPlayed >= ROQSize ) { + if (looping) { + RoQReset(); + } else { + status = FMV_EOF; + } + return; + } + + framedata += RoQFrameSize; + roq_id = framedata[0] + framedata[1]*256; + RoQFrameSize = framedata[2] + framedata[3]*256 + framedata[4]*65536; + roq_flags = framedata[6] + framedata[7]*256; + roqF0 = (char)framedata[7]; + roqF1 = (char)framedata[6]; + + if (RoQFrameSize>65536||roq_id==0x1084) { + common->DPrintf("roq_size>65536||roq_id==0x1084\n"); + status = FMV_EOF; + if (looping) { + RoQReset(); + } + return; + } + if (inMemory && (status != FMV_EOF)) { + inMemory = false; framedata += 8; goto redump; + } +// +// one more frame hits the dust +// +// assert(RoQFrameSize <= 65536); +// r = Sys_StreamedRead( file, RoQFrameSize+8, 1, iFile ); + RoQPlayed += RoQFrameSize+8; +} + +/* +============== +idCinematicLocal::RoQ_init +============== +*/ +void idCinematicLocal::RoQ_init( void ) { + + RoQPlayed = 24; + + /* get frame rate */ + roqFPS = file[ 6] + file[ 7]*256; + + if (!roqFPS) roqFPS = 30; + + numQuads = -1; + + roq_id = file[ 8] + file[ 9]*256; + RoQFrameSize= file[10] + file[11]*256 + file[12]*65536; + roq_flags = file[14] + file[15]*256; +} + +/* +============== +idCinematicLocal::RoQShutdown +============== +*/ +void idCinematicLocal::RoQShutdown( void ) { + if ( status == FMV_IDLE ) { + return; + } + status = FMV_IDLE; + + if ( iFile ) { + fileSystem->CloseFile( iFile ); + iFile = NULL; + } + + fileName = ""; +} + +//=========================================== + +/* +============== +idSndWindow::InitFromFile +============== +*/ +bool idSndWindow::InitFromFile( const char *qpath, bool looping ) { + idStr fname = qpath; + + fname.ToLower(); + if ( !fname.Icmp( "waveform" ) ) { + showWaveform = true; + } else { + showWaveform = false; + } + return true; +} + +/* +============== +idSndWindow::ImageForTime +============== +*/ +cinData_t idSndWindow::ImageForTime( int milliseconds ) { + return soundSystem->ImageForTime( milliseconds, showWaveform ); +} + +/* +============== +idSndWindow::AnimationLength +============== +*/ +int idSndWindow::AnimationLength() { + return -1; +} diff --git a/renderer/Cinematic.h b/renderer/Cinematic.h new file mode 100644 index 000000000..ec81ca0b9 --- /dev/null +++ b/renderer/Cinematic.h @@ -0,0 +1,105 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CINEMATIC_H__ +#define __CINEMATIC_H__ + +/* +=============================================================================== + + RoQ cinematic + + Multiple idCinematics can run simultaniously. + A single idCinematic can be reused for multiple files if desired. + +=============================================================================== +*/ + +// cinematic states +typedef enum { + FMV_IDLE, + FMV_PLAY, // play + FMV_EOF, // all other conditions, i.e. stop/EOF/abort + FMV_ID_BLT, + FMV_ID_IDLE, + FMV_LOOPED, + FMV_ID_WAIT +} cinStatus_t; + +// a cinematic stream generates an image buffer, which the caller will upload to a texture +typedef struct { + int imageWidth, imageHeight; // will be a power of 2 + const byte * image; // RGBA format, alpha will be 255 + int status; +} cinData_t; + +class idCinematic { +public: + // initialize cinematic play back data + static void InitCinematic( void ); + + // shutdown cinematic play back data + static void ShutdownCinematic( void ); + + // allocates and returns a private subclass that implements the methods + // This should be used instead of new + static idCinematic *Alloc(); + + // frees all allocated memory + virtual ~idCinematic(); + + // returns false if it failed to load + virtual bool InitFromFile( const char *qpath, bool looping ); + + // returns the length of the animation in milliseconds + virtual int AnimationLength(); + + // the pointers in cinData_t will remain valid until the next UpdateForTime() call + virtual cinData_t ImageForTime( int milliseconds ); + + // closes the file and frees all allocated memory + virtual void Close(); + + // closes the file and frees all allocated memory + virtual void ResetTime(int time); +}; + +/* +=============================================== + + Sound meter. + +=============================================== +*/ + +class idSndWindow : public idCinematic { +public: + + idSndWindow() { showWaveform = false; } + ~idSndWindow() {} + + bool InitFromFile( const char *qpath, bool looping ); + cinData_t ImageForTime( int milliseconds ); + int AnimationLength(); + +private: + bool showWaveform; +}; + +#endif /* !__CINEMATIC_H__ */ diff --git a/renderer/GuiModel.cpp b/renderer/GuiModel.cpp new file mode 100644 index 000000000..09086e92f --- /dev/null +++ b/renderer/GuiModel.cpp @@ -0,0 +1,643 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +/* +================ +idGuiModel::idGuiModel +================ +*/ +idGuiModel::idGuiModel() { + indexes.SetGranularity( 1000 ); + verts.SetGranularity( 1000 ); +} + +/* +================ +idGuiModel::Clear + +Begins collecting draw commands into surfaces +================ +*/ +void idGuiModel::Clear() { + surfaces.SetNum( 0, false ); + indexes.SetNum( 0, false ); + verts.SetNum( 0, false ); + AdvanceSurf(); +} + +/* +================ +idGuiModel::WriteToDemo +================ +*/ +void idGuiModel::WriteToDemo( idDemoFile *demo ) { + int i, j; + + i = verts.Num(); + demo->WriteInt( i ); + for ( j = 0; j < i; j++ ) + { + demo->WriteVec3( verts[j].xyz ); + demo->WriteVec2( verts[j].st ); + demo->WriteVec3( verts[j].normal ); + demo->WriteVec3( verts[j].tangents[0] ); + demo->WriteVec3( verts[j].tangents[1] ); + demo->WriteUnsignedChar( verts[j].color[0] ); + demo->WriteUnsignedChar( verts[j].color[1] ); + demo->WriteUnsignedChar( verts[j].color[2] ); + demo->WriteUnsignedChar( verts[j].color[3] ); + } + + i = indexes.Num(); + demo->WriteInt( i ); + for ( j = 0; j < i; j++ ) { + demo->WriteInt(indexes[j] ); + } + + i = surfaces.Num(); + demo->WriteInt( i ); + for ( j = 0 ; j < i ; j++ ) { + guiModelSurface_t *surf = &surfaces[j]; + + demo->WriteInt( (int&)surf->material ); + demo->WriteFloat( surf->color[0] ); + demo->WriteFloat( surf->color[1] ); + demo->WriteFloat( surf->color[2] ); + demo->WriteFloat( surf->color[3] ); + demo->WriteInt( surf->firstVert ); + demo->WriteInt( surf->numVerts ); + demo->WriteInt( surf->firstIndex ); + demo->WriteInt( surf->numIndexes ); + demo->WriteHashString( surf->material->GetName() ); + } +} + +/* +================ +idGuiModel::ReadFromDemo +================ +*/ +void idGuiModel::ReadFromDemo( idDemoFile *demo ) { + int i, j; + + i = verts.Num(); + demo->ReadInt( i ); + verts.SetNum( i, false ); + for ( j = 0; j < i; j++ ) + { + demo->ReadVec3( verts[j].xyz ); + demo->ReadVec2( verts[j].st ); + demo->ReadVec3( verts[j].normal ); + demo->ReadVec3( verts[j].tangents[0] ); + demo->ReadVec3( verts[j].tangents[1] ); + demo->ReadUnsignedChar( verts[j].color[0] ); + demo->ReadUnsignedChar( verts[j].color[1] ); + demo->ReadUnsignedChar( verts[j].color[2] ); + demo->ReadUnsignedChar( verts[j].color[3] ); + } + + i = indexes.Num(); + demo->ReadInt( i ); + indexes.SetNum( i, false ); + for ( j = 0; j < i; j++ ) { + demo->ReadInt(indexes[j] ); + } + + i = surfaces.Num(); + demo->ReadInt( i ); + surfaces.SetNum( i, false ); + for ( j = 0 ; j < i ; j++ ) { + guiModelSurface_t *surf = &surfaces[j]; + + demo->ReadInt( (int&)surf->material ); + demo->ReadFloat( surf->color[0] ); + demo->ReadFloat( surf->color[1] ); + demo->ReadFloat( surf->color[2] ); + demo->ReadFloat( surf->color[3] ); + demo->ReadInt( surf->firstVert ); + demo->ReadInt( surf->numVerts ); + demo->ReadInt( surf->firstIndex ); + demo->ReadInt( surf->numIndexes ); + surf->material = declManager->FindMaterial( demo->ReadHashString() ); + } +} + +/* +================ +EmitSurface +================ +*/ +void idGuiModel::EmitSurface( guiModelSurface_t *surf, float modelMatrix[16], float modelViewMatrix[16], bool depthHack ) { + srfTriangles_t *tri; + + if ( surf->numVerts == 0 ) { + return; // nothing in the surface + } + + // copy verts and indexes + tri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *tri ) ); + + tri->numIndexes = surf->numIndexes; + tri->numVerts = surf->numVerts; + tri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( tri->indexes[0] ) ); + memcpy( tri->indexes, &indexes[surf->firstIndex], tri->numIndexes * sizeof( tri->indexes[0] ) ); + + // we might be able to avoid copying these and just let them reference the list vars + // but some things, like deforms and recursive + // guis, need to access the verts in cpu space, not just through the vertex range + tri->verts = (idDrawVert *)R_FrameAlloc( tri->numVerts * sizeof( tri->verts[0] ) ); + memcpy( tri->verts, &verts[surf->firstVert], tri->numVerts * sizeof( tri->verts[0] ) ); + + // move the verts to the vertex cache + tri->ambientCache = vertexCache.AllocFrameTemp( tri->verts, tri->numVerts * sizeof( tri->verts[0] ) ); + + // if we are out of vertex cache, don't create the surface + if ( !tri->ambientCache ) { + return; + } + + renderEntity_t renderEntity; + memset( &renderEntity, 0, sizeof( renderEntity ) ); + memcpy( renderEntity.shaderParms, surf->color, sizeof( surf->color ) ); + + viewEntity_t *guiSpace = (viewEntity_t *)R_ClearedFrameAlloc( sizeof( *guiSpace ) ); + memcpy( guiSpace->modelMatrix, modelMatrix, sizeof( guiSpace->modelMatrix ) ); + memcpy( guiSpace->modelViewMatrix, modelViewMatrix, sizeof( guiSpace->modelViewMatrix ) ); + guiSpace->weaponDepthHack = depthHack; + + // add the surface, which might recursively create another gui + R_AddDrawSurf( tri, guiSpace, &renderEntity, surf->material, tr.viewDef->scissor ); +} + +/* +==================== +EmitToCurrentView +==================== +*/ +void idGuiModel::EmitToCurrentView( float modelMatrix[16], bool depthHack ) { + float modelViewMatrix[16]; + + myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.modelViewMatrix, + modelViewMatrix ); + + for ( int i = 0 ; i < surfaces.Num() ; i++ ) { + EmitSurface( &surfaces[i], modelMatrix, modelViewMatrix, depthHack ); + } +} + +/* +================ +idGuiModel::EmitFullScreen + +Creates a view that covers the screen and emit the surfaces +================ +*/ +void idGuiModel::EmitFullScreen( void ) { + viewDef_t *viewDef; + + if ( surfaces[0].numVerts == 0 ) { + return; + } + + viewDef = (viewDef_t *)R_ClearedFrameAlloc( sizeof( *viewDef ) ); + + // for gui editor + if ( !tr.viewDef || !tr.viewDef->isEditor ) { + viewDef->renderView.x = 0; + viewDef->renderView.y = 0; + viewDef->renderView.width = SCREEN_WIDTH; + viewDef->renderView.height = SCREEN_HEIGHT; + + tr.RenderViewToViewport( &viewDef->renderView, &viewDef->viewport ); + + viewDef->scissor.x1 = 0; + viewDef->scissor.y1 = 0; + viewDef->scissor.x2 = viewDef->viewport.x2 - viewDef->viewport.x1; + viewDef->scissor.y2 = viewDef->viewport.y2 - viewDef->viewport.y1; + } else { + viewDef->renderView.x = tr.viewDef->renderView.x; + viewDef->renderView.y = tr.viewDef->renderView.y; + viewDef->renderView.width = tr.viewDef->renderView.width; + viewDef->renderView.height = tr.viewDef->renderView.height; + + viewDef->viewport.x1 = tr.viewDef->renderView.x; + viewDef->viewport.x2 = tr.viewDef->renderView.x + tr.viewDef->renderView.width; + viewDef->viewport.y1 = tr.viewDef->renderView.y; + viewDef->viewport.y2 = tr.viewDef->renderView.y + tr.viewDef->renderView.height; + + viewDef->scissor.x1 = tr.viewDef->scissor.x1; + viewDef->scissor.y1 = tr.viewDef->scissor.y1; + viewDef->scissor.x2 = tr.viewDef->scissor.x2; + viewDef->scissor.y2 = tr.viewDef->scissor.y2; + } + + viewDef->floatTime = tr.frameShaderTime; + + // qglOrtho( 0, 640, 480, 0, 0, 1 ); // always assume 640x480 virtual coordinates + viewDef->projectionMatrix[0] = 2.0f / 640.0f; + viewDef->projectionMatrix[5] = -2.0f / 480.0f; + viewDef->projectionMatrix[10] = -2.0f / 1.0f; + viewDef->projectionMatrix[12] = -1.0f; + viewDef->projectionMatrix[13] = 1.0f; + viewDef->projectionMatrix[14] = -1.0f; + viewDef->projectionMatrix[15] = 1.0f; + + viewDef->worldSpace.modelViewMatrix[0] = 1.0f; + viewDef->worldSpace.modelViewMatrix[5] = 1.0f; + viewDef->worldSpace.modelViewMatrix[10] = 1.0f; + viewDef->worldSpace.modelViewMatrix[15] = 1.0f; + + viewDef->maxDrawSurfs = surfaces.Num(); + viewDef->drawSurfs = (drawSurf_t **)R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ) ); + viewDef->numDrawSurfs = 0; + + viewDef_t *oldViewDef = tr.viewDef; + tr.viewDef = viewDef; + + // add the surfaces to this view + for ( int i = 0 ; i < surfaces.Num() ; i++ ) { + EmitSurface( &surfaces[i], viewDef->worldSpace.modelMatrix, viewDef->worldSpace.modelViewMatrix, false ); + } + + tr.viewDef = oldViewDef; + + // add the command to draw this view + R_AddDrawViewCmd( viewDef ); +} + +/* +============= +AdvanceSurf +============= +*/ +void idGuiModel::AdvanceSurf() { + guiModelSurface_t s; + + if ( surfaces.Num() ) { + s.color[0] = surf->color[0]; + s.color[1] = surf->color[1]; + s.color[2] = surf->color[2]; + s.color[3] = surf->color[3]; + s.material = surf->material; + } else { + s.color[0] = 1; + s.color[1] = 1; + s.color[2] = 1; + s.color[3] = 1; + s.material = tr.defaultMaterial; + } + s.numIndexes = 0; + s.firstIndex = indexes.Num(); + s.numVerts = 0; + s.firstVert = verts.Num(); + + surfaces.Append( s ); + surf = &surfaces[ surfaces.Num() - 1 ]; +} + +/* +============= +SetColor +============= +*/ +void idGuiModel::SetColor( float r, float g, float b, float a ) { + if ( !glConfig.isInitialized ) { + return; + } + if ( r == surf->color[0] && g == surf->color[1] + && b == surf->color[2] && a == surf->color[3] ) { + return; // no change + } + + if ( surf->numVerts ) { + AdvanceSurf(); + } + + // change the parms + surf->color[0] = r; + surf->color[1] = g; + surf->color[2] = b; + surf->color[3] = a; +} + +/* +============= +DrawStretchPic +============= +*/ +void idGuiModel::DrawStretchPic( const idDrawVert *dverts, const glIndex_t *dindexes, int vertCount, int indexCount, const idMaterial *hShader, + bool clip, float min_x, float min_y, float max_x, float max_y ) { + if ( !glConfig.isInitialized ) { + return; + } + if ( !( dverts && dindexes && vertCount && indexCount && hShader ) ) { + return; + } + + // break the current surface if we are changing to a new material + if ( hShader != surf->material ) { + if ( surf->numVerts ) { + AdvanceSurf(); + } + const_cast(hShader)->EnsureNotPurged(); // in case it was a gui item started before a level change + surf->material = hShader; + } + + // add the verts and indexes to the current surface + + if ( clip ) { + int i, j; + + // FIXME: this is grim stuff, and should be rewritten if we have any significant + // number of guis asking for clipping + idFixedWinding w; + for ( i = 0; i < indexCount; i += 3 ) { + w.Clear(); + w.AddPoint(idVec5(dverts[dindexes[i]].xyz.x, dverts[dindexes[i]].xyz.y, dverts[dindexes[i]].xyz.z, dverts[dindexes[i]].st.x, dverts[dindexes[i]].st.y)); + w.AddPoint(idVec5(dverts[dindexes[i+1]].xyz.x, dverts[dindexes[i+1]].xyz.y, dverts[dindexes[i+1]].xyz.z, dverts[dindexes[i+1]].st.x, dverts[dindexes[i+1]].st.y)); + w.AddPoint(idVec5(dverts[dindexes[i+2]].xyz.x, dverts[dindexes[i+2]].xyz.y, dverts[dindexes[i+2]].xyz.z, dverts[dindexes[i+2]].st.x, dverts[dindexes[i+2]].st.y)); + + for ( j = 0; j < 3; j++ ) { + if ( w[j].x < min_x || w[j].x > max_x || + w[j].y < min_y || w[j].y > max_y ) { + break; + } + } + if ( j < 3 ) { + idPlane p; + p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = 1.0f; p.SetDist( min_x ); + w.ClipInPlace( p ); + p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = -1.0f; p.SetDist( -max_x ); + w.ClipInPlace( p ); + p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = 1.0f; p.SetDist( min_y ); + w.ClipInPlace( p ); + p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = -1.0f; p.SetDist( -max_y ); + w.ClipInPlace( p ); + } + + int numVerts = verts.Num(); + verts.SetNum( numVerts + w.GetNumPoints(), false ); + for ( j = 0 ; j < w.GetNumPoints() ; j++ ) { + idDrawVert *dv = &verts[numVerts+j]; + + dv->xyz.x = w[j].x; + dv->xyz.y = w[j].y; + dv->xyz.z = w[j].z; + dv->st.x = w[j].s; + dv->st.y = w[j].t; + dv->normal.Set(0, 0, 1); + dv->tangents[0].Set(1, 0, 0); + dv->tangents[1].Set(0, 1, 0); + } + surf->numVerts += w.GetNumPoints(); + + for ( j = 2; j < w.GetNumPoints(); j++ ) { + indexes.Append( numVerts - surf->firstVert ); + indexes.Append( numVerts + j - 1 - surf->firstVert ); + indexes.Append( numVerts + j - surf->firstVert ); + surf->numIndexes += 3; + } + } + + } else { + + int numVerts = verts.Num(); + int numIndexes = indexes.Num(); + + verts.AssureSize( numVerts + vertCount ); + indexes.AssureSize( numIndexes + indexCount ); + + surf->numVerts += vertCount; + surf->numIndexes += indexCount; + + for ( int i = 0; i < indexCount; i++ ) { + indexes[numIndexes + i] = numVerts + dindexes[i] - surf->firstVert; + } + + memcpy( &verts[numVerts], dverts, vertCount * sizeof( verts[0] ) ); + } +} + +/* +============= +DrawStretchPic + +x/y/w/h are in the 0,0 to 640,480 range +============= +*/ +void idGuiModel::DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *hShader ) { + idDrawVert verts[4]; + glIndex_t indexes[6]; + + if ( !glConfig.isInitialized ) { + return; + } + if ( !hShader ) { + return; + } + + // clip to edges, because the pic may be going into a guiShader + // instead of full screen + if ( x < 0 ) { + s1 += ( s2 - s1 ) * -x / w; + w += x; + x = 0; + } + if ( y < 0 ) { + t1 += ( t2 - t1 ) * -y / h; + h += y; + y = 0; + } + if ( x + w > 640 ) { + s2 -= ( s2 - s1 ) * ( x + w - 640 ) / w; + w = 640 - x; + } + if ( y + h > 480 ) { + t2 -= ( t2 - t1 ) * ( y + h - 480 ) / h; + h = 480 - y; + } + + if ( w <= 0 || h <= 0 ) { + return; // completely clipped away + } + + indexes[0] = 3; + indexes[1] = 0; + indexes[2] = 2; + indexes[3] = 2; + indexes[4] = 0; + indexes[5] = 1; + verts[0].xyz[0] = x; + verts[0].xyz[1] = y; + verts[0].xyz[2] = 0; + verts[0].st[0] = s1; + verts[0].st[1] = t1; + verts[0].normal[0] = 0; + verts[0].normal[1] = 0; + verts[0].normal[2] = 1; + verts[0].tangents[0][0] = 1; + verts[0].tangents[0][1] = 0; + verts[0].tangents[0][2] = 0; + verts[0].tangents[1][0] = 0; + verts[0].tangents[1][1] = 1; + verts[0].tangents[1][2] = 0; + verts[1].xyz[0] = x + w; + verts[1].xyz[1] = y; + verts[1].xyz[2] = 0; + verts[1].st[0] = s2; + verts[1].st[1] = t1; + verts[1].normal[0] = 0; + verts[1].normal[1] = 0; + verts[1].normal[2] = 1; + verts[1].tangents[0][0] = 1; + verts[1].tangents[0][1] = 0; + verts[1].tangents[0][2] = 0; + verts[1].tangents[1][0] = 0; + verts[1].tangents[1][1] = 1; + verts[1].tangents[1][2] = 0; + verts[2].xyz[0] = x + w; + verts[2].xyz[1] = y + h; + verts[2].xyz[2] = 0; + verts[2].st[0] = s2; + verts[2].st[1] = t2; + verts[2].normal[0] = 0; + verts[2].normal[1] = 0; + verts[2].normal[2] = 1; + verts[2].tangents[0][0] = 1; + verts[2].tangents[0][1] = 0; + verts[2].tangents[0][2] = 0; + verts[2].tangents[1][0] = 0; + verts[2].tangents[1][1] = 1; + verts[2].tangents[1][2] = 0; + verts[3].xyz[0] = x; + verts[3].xyz[1] = y + h; + verts[3].xyz[2] = 0; + verts[3].st[0] = s1; + verts[3].st[1] = t2; + verts[3].normal[0] = 0; + verts[3].normal[1] = 0; + verts[3].normal[2] = 1; + verts[3].tangents[0][0] = 1; + verts[3].tangents[0][1] = 0; + verts[3].tangents[0][2] = 0; + verts[3].tangents[1][0] = 0; + verts[3].tangents[1][1] = 1; + verts[3].tangents[1][2] = 0; + + DrawStretchPic( &verts[0], &indexes[0], 4, 6, hShader, false, 0.0f, 0.0f, 640.0f, 480.0f ); +} + +/* +============= +DrawStretchTri + +x/y/w/h are in the 0,0 to 640,480 range +============= +*/ +void idGuiModel::DrawStretchTri( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) { + idDrawVert tempVerts[3]; + glIndex_t tempIndexes[3]; + int vertCount = 3; + int indexCount = 3; + + if ( !glConfig.isInitialized ) { + return; + } + if ( !material ) { + return; + } + + tempIndexes[0] = 1; + tempIndexes[1] = 0; + tempIndexes[2] = 2; + tempVerts[0].xyz[0] = p1.x; + tempVerts[0].xyz[1] = p1.y; + tempVerts[0].xyz[2] = 0; + tempVerts[0].st[0] = t1.x; + tempVerts[0].st[1] = t1.y; + tempVerts[0].normal[0] = 0; + tempVerts[0].normal[1] = 0; + tempVerts[0].normal[2] = 1; + tempVerts[0].tangents[0][0] = 1; + tempVerts[0].tangents[0][1] = 0; + tempVerts[0].tangents[0][2] = 0; + tempVerts[0].tangents[1][0] = 0; + tempVerts[0].tangents[1][1] = 1; + tempVerts[0].tangents[1][2] = 0; + tempVerts[1].xyz[0] = p2.x; + tempVerts[1].xyz[1] = p2.y; + tempVerts[1].xyz[2] = 0; + tempVerts[1].st[0] = t2.x; + tempVerts[1].st[1] = t2.y; + tempVerts[1].normal[0] = 0; + tempVerts[1].normal[1] = 0; + tempVerts[1].normal[2] = 1; + tempVerts[1].tangents[0][0] = 1; + tempVerts[1].tangents[0][1] = 0; + tempVerts[1].tangents[0][2] = 0; + tempVerts[1].tangents[1][0] = 0; + tempVerts[1].tangents[1][1] = 1; + tempVerts[1].tangents[1][2] = 0; + tempVerts[2].xyz[0] = p3.x; + tempVerts[2].xyz[1] = p3.y; + tempVerts[2].xyz[2] = 0; + tempVerts[2].st[0] = t3.x; + tempVerts[2].st[1] = t3.y; + tempVerts[2].normal[0] = 0; + tempVerts[2].normal[1] = 0; + tempVerts[2].normal[2] = 1; + tempVerts[2].tangents[0][0] = 1; + tempVerts[2].tangents[0][1] = 0; + tempVerts[2].tangents[0][2] = 0; + tempVerts[2].tangents[1][0] = 0; + tempVerts[2].tangents[1][1] = 1; + tempVerts[2].tangents[1][2] = 0; + + // break the current surface if we are changing to a new material + if ( material != surf->material ) { + if ( surf->numVerts ) { + AdvanceSurf(); + } + const_cast(material)->EnsureNotPurged(); // in case it was a gui item started before a level change + surf->material = material; + } + + + int numVerts = verts.Num(); + int numIndexes = indexes.Num(); + + verts.AssureSize( numVerts + vertCount ); + indexes.AssureSize( numIndexes + indexCount ); + + surf->numVerts += vertCount; + surf->numIndexes += indexCount; + + for ( int i = 0; i < indexCount; i++ ) { + indexes[numIndexes + i] = numVerts + tempIndexes[i] - surf->firstVert; + } + + memcpy( &verts[numVerts], tempVerts, vertCount * sizeof( verts[0] ) ); +} + diff --git a/renderer/GuiModel.h b/renderer/GuiModel.h new file mode 100644 index 000000000..59de616cc --- /dev/null +++ b/renderer/GuiModel.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +typedef struct { + const idMaterial *material; + float color[4]; + int firstVert; + int numVerts; + int firstIndex; + int numIndexes; +} guiModelSurface_t; + +class idGuiModel { +public: + idGuiModel(); + + void Clear(); + + void WriteToDemo( idDemoFile *demo ); + void ReadFromDemo( idDemoFile *demo ); + + void EmitToCurrentView( float modelMatrix[16], bool depthHack ); + void EmitFullScreen(); + + // these calls are forwarded from the renderer + void SetColor( float r, float g, float b, float a ); + void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *hShader, + bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f ); + void DrawStretchPic( float x, float y, float w, float h, + float s1, float t1, float s2, float t2, const idMaterial *hShader); + void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ); + + //--------------------------- +private: + void AdvanceSurf(); + void EmitSurface( guiModelSurface_t *surf, float modelMatrix[16], float modelViewMatrix[16], bool depthHack ); + + guiModelSurface_t *surf; + + idList surfaces; + idList indexes; + idList verts; +}; + diff --git a/renderer/Image.h b/renderer/Image.h new file mode 100644 index 000000000..73ce8d8d1 --- /dev/null +++ b/renderer/Image.h @@ -0,0 +1,487 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* +==================================================================== + +IMAGE + +idImage have a one to one correspondance with OpenGL textures. + +No texture is ever used that does not have a corresponding idImage. + +no code outside this unit should call any of these OpenGL functions: + +qglGenTextures +qglDeleteTextures +qglBindTexture + +qglTexParameter + +qglTexImage +qglTexSubImage + +qglCopyTexImage +qglCopyTexSubImage + +qglEnable( GL_TEXTURE_* ) +qglDisable( GL_TEXTURE_* ) + +==================================================================== +*/ + +typedef enum { + IS_UNLOADED, // no gl texture number + IS_PARTIAL, // has a texture number and the low mip levels loaded + IS_LOADED // has a texture number and the full mip hierarchy +} imageState_t; + +static const int MAX_TEXTURE_LEVELS = 14; + +// surface description flags +const unsigned long DDSF_CAPS = 0x00000001l; +const unsigned long DDSF_HEIGHT = 0x00000002l; +const unsigned long DDSF_WIDTH = 0x00000004l; +const unsigned long DDSF_PITCH = 0x00000008l; +const unsigned long DDSF_PIXELFORMAT = 0x00001000l; +const unsigned long DDSF_MIPMAPCOUNT = 0x00020000l; +const unsigned long DDSF_LINEARSIZE = 0x00080000l; +const unsigned long DDSF_DEPTH = 0x00800000l; + +// pixel format flags +const unsigned long DDSF_ALPHAPIXELS = 0x00000001l; +const unsigned long DDSF_FOURCC = 0x00000004l; +const unsigned long DDSF_RGB = 0x00000040l; +const unsigned long DDSF_RGBA = 0x00000041l; + +// our extended flags +const unsigned long DDSF_ID_INDEXCOLOR = 0x10000000l; +const unsigned long DDSF_ID_MONOCHROME = 0x20000000l; + +// dwCaps1 flags +const unsigned long DDSF_COMPLEX = 0x00000008l; +const unsigned long DDSF_TEXTURE = 0x00001000l; +const unsigned long DDSF_MIPMAP = 0x00400000l; + +#define DDS_MAKEFOURCC(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) + +typedef struct { + unsigned long dwSize; + unsigned long dwFlags; + unsigned long dwFourCC; + unsigned long dwRGBBitCount; + unsigned long dwRBitMask; + unsigned long dwGBitMask; + unsigned long dwBBitMask; + unsigned long dwABitMask; +} ddsFilePixelFormat_t; + +typedef struct +{ + unsigned long dwSize; + unsigned long dwFlags; + unsigned long dwHeight; + unsigned long dwWidth; + unsigned long dwPitchOrLinearSize; + unsigned long dwDepth; + unsigned long dwMipMapCount; + unsigned long dwReserved1[11]; + ddsFilePixelFormat_t ddspf; + unsigned long dwCaps1; + unsigned long dwCaps2; + unsigned long dwReserved2[3]; +} ddsFileHeader_t; + + +// increasing numeric values imply more information is stored +typedef enum { + TD_SPECULAR, // may be compressed, and always zeros the alpha channel + TD_DIFFUSE, // may be compressed + TD_DEFAULT, // will use compressed formats when possible + TD_BUMP, // may be compressed with 8 bit lookup + TD_HIGH_QUALITY // either 32 bit or a component format, no loss at all +} textureDepth_t; + +typedef enum { + TT_DISABLED, + TT_2D, + TT_3D, + TT_CUBIC, + TT_RECT +} textureType_t; + +typedef enum { + CF_2D, // not a cube map + CF_NATIVE, // _px, _nx, _py, etc, directly sent to GL + CF_CAMERA // _forward, _back, etc, rotated and flipped as needed before sending to GL +} cubeFiles_t; + +#define MAX_IMAGE_NAME 256 + +class idImage { +public: + idImage(); + + // Makes this image active on the current GL texture unit. + // automatically enables or disables cube mapping or texture3D + // May perform file loading if the image was not preloaded. + // May start a background image read. + void Bind(); + + // for use with fragment programs, doesn't change any enable2D/3D/cube states + void BindFragment(); + + // deletes the texture object, but leaves the structure so it can be reloaded + void PurgeImage(); + + // used by callback functions to specify the actual data + // data goes from the bottom to the top line of the image, as OpenGL expects it + // These perform an implicit Bind() on the current texture unit + // FIXME: should we implement cinematics this way, instead of with explicit calls? + void GenerateImage( const byte *pic, int width, int height, + textureFilter_t filter, bool allowDownSize, + textureRepeat_t repeat, textureDepth_t depth ); + void Generate3DImage( const byte *pic, int width, int height, int depth, + textureFilter_t filter, bool allowDownSize, + textureRepeat_t repeat, textureDepth_t minDepth ); + void GenerateCubeImage( const byte *pic[6], int size, + textureFilter_t filter, bool allowDownSize, + textureDepth_t depth ); + + void CopyFramebuffer( int x, int y, int width, int height, bool useOversizedBuffer ); + + void CopyDepthbuffer( int x, int y, int width, int height ); + + void UploadScratch( const byte *pic, int width, int height ); + + // just for resource tracking + void SetClassification( int tag ); + + // estimates size of the GL image based on dimensions and storage type + int StorageSize() const; + + // print a one line summary of the image + void Print() const; + + // check for changed timestamp on disk and reload if necessary + void Reload( bool checkPrecompressed, bool force ); + + void AddReference() { refCount++; }; + +//========================================================== + + void GetDownsize( int &scaled_width, int &scaled_height ) const; + void MakeDefault(); // fill with a grid pattern + void SetImageFilterAndRepeat() const; + bool ShouldImageBePartialCached(); + void WritePrecompressedImage(); + bool CheckPrecompressedImage( bool fullLoad ); + void UploadPrecompressedImage( byte *data, int len ); + void ActuallyLoadImage( bool checkForPrecompressed, bool fromBackEnd ); + void StartBackgroundImageLoad(); + int BitsForInternalFormat( int internalFormat ) const; + void UploadCompressedNormalMap( int width, int height, const byte *rgba, int mipLevel ); + GLenum SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, int width, int height, + textureDepth_t minimumDepth, bool *monochromeResult ) const; + void ImageProgramStringToCompressedFileName( const char *imageProg, char *fileName ) const; + int NumLevelsForImageSize( int width, int height ) const; + + // data commonly accessed is grouped here + static const int TEXTURE_NOT_LOADED = -1; + GLuint texnum; // gl texture binding, will be TEXTURE_NOT_LOADED if not loaded + textureType_t type; + int frameUsed; // for texture usage in frame statistics + int bindCount; // incremented each bind + + // background loading information + idImage *partialImage; // shrunken, space-saving version + bool isPartialImage; // true if this is pointed to by another image + bool backgroundLoadInProgress; // true if another thread is reading the complete d3t file + backgroundDownload_t bgl; + idImage * bglNext; // linked from tr.backgroundImageLoads + + // parameters that define this image + idStr imgName; // game path, including extension (except for cube maps), may be an image program + void (*generatorFunction)( idImage *image ); // NULL for files + bool allowDownSize; // this also doubles as a don't-partially-load flag + textureFilter_t filter; + textureRepeat_t repeat; + textureDepth_t depth; + cubeFiles_t cubeFiles; // determines the naming and flipping conventions for the six images + + bool referencedOutsideLevelLoad; + bool levelLoadReferenced; // for determining if it needs to be purged + bool precompressedFile; // true when it was loaded from a .d3t file + bool defaulted; // true if the default image was generated because a file couldn't be loaded + bool isMonochrome; // so the NV20 path can use a reduced pass count + ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command + + int imageHash; // for identical-image checking + + int classification; // just for resource profiling + + // data for listImages + int uploadWidth, uploadHeight, uploadDepth; // after power of two, downsample, and MAX_TEXTURE_SIZE + int internalFormat; + + idImage *cacheUsagePrev, *cacheUsageNext; // for dynamic cache purging of old images + + idImage * hashNext; // for hash chains to speed lookup + + int refCount; // overall ref count +}; + +ID_INLINE idImage::idImage() { + texnum = TEXTURE_NOT_LOADED; + partialImage = NULL; + type = TT_DISABLED; + isPartialImage = false; + frameUsed = 0; + classification = 0; + backgroundLoadInProgress = false; + bgl.opcode = DLTYPE_FILE; + bgl.f = NULL; + bglNext = NULL; + imgName[0] = '\0'; + generatorFunction = NULL; + allowDownSize = false; + filter = TF_DEFAULT; + repeat = TR_REPEAT; + depth = TD_DEFAULT; + cubeFiles = CF_2D; + referencedOutsideLevelLoad = false; + levelLoadReferenced = false; + precompressedFile = false; + defaulted = false; + timestamp = 0; + bindCount = 0; + uploadWidth = uploadHeight = uploadDepth = 0; + internalFormat = 0; + cacheUsagePrev = cacheUsageNext = NULL; + hashNext = NULL; + isMonochrome = false; + refCount = 0; +} + + +// data is RGBA +void R_WriteTGA( const char *filename, const byte *data, int width, int height, bool flipVertical = false ); +// data is an 8 bit index into palette, which is RGB (no A) +void R_WritePalTGA( const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical = false ); +// data is in top-to-bottom raster order unless flipVertical is set + + +class idImageManager { +public: + void Init(); + void Shutdown(); + + // If the exact combination of parameters has been asked for already, an existing + // image will be returned, otherwise a new image will be created. + // Be careful not to use the same image file with different filter / repeat / etc parameters + // if possible, because it will cause a second copy to be loaded. + // If the load fails for any reason, the image will be filled in with the default + // grid pattern. + // Will automatically resample non-power-of-two images and execute image programs if needed. + idImage * ImageFromFile( const char *name, + textureFilter_t filter, bool allowDownSize, + textureRepeat_t repeat, textureDepth_t depth, cubeFiles_t cubeMap = CF_2D ); + + // look for a loaded image, whatever the parameters + idImage * GetImage( const char *name ) const; + + // The callback will be issued immediately, and later if images are reloaded or vid_restart + // The callback function should call one of the idImage::Generate* functions to fill in the data + idImage * ImageFromFunction( const char *name, void (*generatorFunction)( idImage *image )); + + // called once a frame to allow any background loads that have been completed + // to turn into textures. + void CompleteBackgroundImageLoads(); + + // returns the number of bytes of image data bound in the previous frame + int SumOfUsedImages(); + + // called each frame to allow some cvars to automatically force changes + void CheckCvars(); + + // purges all the images before a vid_restart + void PurgeAllImages(); + + // reloads all apropriate images after a vid_restart + void ReloadAllImages(); + + // disable the active texture unit + void BindNull(); + + // Mark all file based images as currently unused, + // but don't free anything. Calls to ImageFromFile() will + // either mark the image as used, or create a new image without + // loading the actual data. + // Called only by renderSystem::BeginLevelLoad + void BeginLevelLoad(); + + // Free all images marked as unused, and load all images that are necessary. + // This architecture prevents us from having the union of two level's + // worth of data present at one time. + // Called only by renderSystem::EndLevelLoad + void EndLevelLoad(); + + // used to clear and then write the dds conversion batch file + void StartBuild(); + void FinishBuild( bool removeDups = false ); + void AddDDSCommand( const char *cmd ); + + void PrintMemInfo( MemInfo_t *mi ); + + // cvars + static idCVar image_roundDown; // round bad sizes down to nearest power of two + static idCVar image_colorMipLevels; // development aid to see texture mip usage + static idCVar image_downSize; // controls texture downsampling + static idCVar image_useCompression; // 0 = force everything to high quality + static idCVar image_filter; // changes texture filtering on mipmapped images + static idCVar image_anisotropy; // set the maximum texture anisotropy if available + static idCVar image_lodbias; // change lod bias on mipmapped images + static idCVar image_useAllFormats; // allow alpha/intensity/luminance/luminance+alpha + static idCVar image_usePrecompressedTextures; // use .dds files if present + static idCVar image_writePrecompressedTextures; // write .dds files if necessary + static idCVar image_writeNormalTGA; // debug tool to write out .tgas of the final normal maps + static idCVar image_writeNormalTGAPalletized; // debug tool to write out palletized versions of the final normal maps + static idCVar image_writeTGA; // debug tool to write out .tgas of the non normal maps + static idCVar image_useNormalCompression; // 1 = use 256 color compression for normal maps if available, 2 = use rxgb compression + static idCVar image_useOffLineCompression; // will write a batch file with commands for the offline compression + static idCVar image_preload; // if 0, dynamically load all images + static idCVar image_cacheMinK; // maximum K of precompressed files to read at specification time, + // the remainder will be dynamically cached + static idCVar image_cacheMegs; // maximum bytes set aside for temporary loading of full-sized precompressed images + static idCVar image_useCache; // 1 = do background load image caching + static idCVar image_showBackgroundLoads; // 1 = print number of outstanding background loads + static idCVar image_forceDownSize; // allows the ability to force a downsize + static idCVar image_downSizeSpecular; // downsize specular + static idCVar image_downSizeSpecularLimit;// downsize specular limit + static idCVar image_downSizeBump; // downsize bump maps + static idCVar image_downSizeBumpLimit; // downsize bump limit + static idCVar image_ignoreHighQuality; // ignore high quality on materials + static idCVar image_downSizeLimit; // downsize diffuse limit + + // built-in images + idImage * defaultImage; + idImage * flatNormalMap; // 128 128 255 in all pixels + idImage * ambientNormalMap; // tr.ambientLightVector encoded in all pixels + idImage * rampImage; // 0-255 in RGBA in S + idImage * alphaRampImage; // 0-255 in alpha, 255 in RGB + idImage * alphaNotchImage; // 2x1 texture with just 1110 and 1111 with point sampling + idImage * whiteImage; // full of 0xff + idImage * blackImage; // full of 0x00 + idImage * normalCubeMapImage; // cube map to normalize STR into RGB + idImage * noFalloffImage; // all 255, but zero clamped + idImage * fogImage; // increasing alpha is denser fog + idImage * fogEnterImage; // adjust fogImage alpha based on terminator plane + idImage * cinematicImage; + idImage * scratchImage; + idImage * scratchImage2; + idImage * accumImage; + idImage * currentRenderImage; // for SS_POST_PROCESS shaders + idImage * scratchCubeMapImage; + idImage * specularTableImage; // 1D intensity texture with our specular function + idImage * specular2DTableImage; // 2D intensity texture with our specular function with variable specularity + idImage * borderClampImage; // white inside, black outside + + //-------------------------------------------------------- + + idImage * AllocImage( const char *name ); + void SetNormalPalette(); + void ChangeTextureFilter(); + + idList images; + idStrList ddsList; + idHashIndex ddsHash; + + bool insideLevelLoad; // don't actually load images now + + byte originalToCompressed[256]; // maps normal maps to 8 bit textures + byte compressedPalette[768]; // the palette that normal maps use + + // default filter modes for images + GLenum textureMinFilter; + GLenum textureMaxFilter; + float textureAnisotropy; + float textureLODBias; + + idImage * imageHashTable[FILE_HASH_SIZE]; + + idImage * backgroundImageLoads; // chain of images that have background file loads active + idImage cacheLRU; // head/tail of doubly linked list + int totalCachedImageSize; // for determining when something should be purged + + int numActiveBackgroundImageLoads; + const static int MAX_BACKGROUND_IMAGE_LOADS = 8; +}; + +extern idImageManager *globalImages; // pointer to global list for the rest of the system + +int MakePowerOfTwo( int num ); + +/* +==================================================================== + +IMAGEPROCESS + +FIXME: make an "imageBlock" type to hold byte*,width,height? +==================================================================== +*/ + +byte *R_Dropsample( const byte *in, int inwidth, int inheight, + int outwidth, int outheight ); +byte *R_ResampleTexture( const byte *in, int inwidth, int inheight, + int outwidth, int outheight ); +byte *R_MipMapWithAlphaSpecularity( const byte *in, int width, int height ); +byte *R_MipMap( const byte *in, int width, int height, bool preserveBorder ); +byte *R_MipMap3D( const byte *in, int width, int height, int depth, bool preserveBorder ); + +// these operate in-place on the provided pixels +void R_SetBorderTexels( byte *inBase, int width, int height, const byte border[4] ); +void R_SetBorderTexels3D( byte *inBase, int width, int height, int depth, const byte border[4] ); +void R_BlendOverTexture( byte *data, int pixelCount, const byte blend[4] ); +void R_HorizontalFlip( byte *data, int width, int height ); +void R_VerticalFlip( byte *data, int width, int height ); +void R_RotatePic( byte *data, int width ); + +/* +==================================================================== + +IMAGEFILES + +==================================================================== +*/ + +void R_LoadImage( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 ); +// pic is in top to bottom raster format +bool R_LoadCubeImages( const char *cname, cubeFiles_t extensions, byte *pic[6], int *size, ID_TIME_T *timestamp ); + +/* +==================================================================== + +IMAGEPROGRAM + +==================================================================== +*/ + +void R_LoadImageProgram( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, textureDepth_t *depth = NULL ); +const char *R_ParsePastImageProgram( idLexer &src ); + diff --git a/renderer/Image_files.cpp b/renderer/Image_files.cpp new file mode 100644 index 000000000..3c5e2fc33 --- /dev/null +++ b/renderer/Image_files.cpp @@ -0,0 +1,1172 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + +This file only has a single entry point: + +void R_LoadImage( const char *name, byte **pic, int *width, int *height, bool makePowerOf2 ); + +*/ + +/* + * Include file for users of JPEG library. + * You will need to have included system headers that define at least + * the typedefs FILE and size_t before you can include jpeglib.h. + * (stdio.h is sufficient on ANSI-conforming systems.) + * You may also wish to include "jerror.h". + */ + +extern "C" { +#include "jpeg-6/jpeglib.h" + + // hooks from jpeg lib to our system + + void jpg_Error( const char *fmt, ... ) { + va_list argptr; + char msg[2048]; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + common->FatalError( "%s", msg ); + } + + void jpg_Printf( const char *fmt, ... ) { + va_list argptr; + char msg[2048]; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + common->Printf( "%s", msg ); + } + +} + + +/* +================ +R_WriteTGA +================ +*/ +void R_WriteTGA( const char *filename, const byte *data, int width, int height, bool flipVertical ) { + byte *buffer; + int i; + int bufferSize = width*height*4 + 18; + int imgStart = 18; + + buffer = (byte *)Mem_Alloc( bufferSize ); + memset( buffer, 0, 18 ); + buffer[2] = 2; // uncompressed type + buffer[12] = width&255; + buffer[13] = width>>8; + buffer[14] = height&255; + buffer[15] = height>>8; + buffer[16] = 32; // pixel size + if ( !flipVertical ) { + buffer[17] = (1<<5); // flip bit, for normal top to bottom raster order + } + + // swap rgb to bgr + for ( i=imgStart ; iWriteFile( filename, buffer, bufferSize ); + + Mem_Free (buffer); +} + + +/* +================ +R_WritePalTGA +================ +*/ +void R_WritePalTGA( const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical ) { + byte *buffer; + int i; + int bufferSize = (width * height) + (256 * 3) + 18; + int palStart = 18; + int imgStart = 18 + (256 * 3); + + buffer = (byte *)Mem_Alloc( bufferSize ); + memset( buffer, 0, 18 ); + buffer[1] = 1; // color map type + buffer[2] = 1; // uncompressed color mapped image + buffer[5] = 0; // number of palette entries (lo) + buffer[6] = 1; // number of palette entries (hi) + buffer[7] = 24; // color map bpp + buffer[12] = width&255; + buffer[13] = width>>8; + buffer[14] = height&255; + buffer[15] = height>>8; + buffer[16] = 8; // pixel size + if ( !flipVertical ) { + buffer[17] = (1<<5); // flip bit, for normal top to bottom raster order + } + + // store palette, swapping rgb to bgr + for ( i=palStart ; iWriteFile( filename, buffer, bufferSize ); + + Mem_Free (buffer); +} + + +static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ); +static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ); +static void LoadJPG( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ); + + +/* +======================================================================== + +PCX files are used for 8 bit images + +======================================================================== +*/ + +typedef struct { + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned char data; // unbounded +} pcx_t; + + +/* +======================================================================== + +TGA files are used for 24/32 bit images + +======================================================================== +*/ + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + + +/* +========================================================= + +BMP LOADING + +========================================================= +*/ +typedef struct +{ + char id[2]; + unsigned long fileSize; + unsigned long reserved0; + unsigned long bitmapDataOffset; + unsigned long bitmapHeaderSize; + unsigned long width; + unsigned long height; + unsigned short planes; + unsigned short bitsPerPixel; + unsigned long compression; + unsigned long bitmapDataSize; + unsigned long hRes; + unsigned long vRes; + unsigned long colors; + unsigned long importantColors; + unsigned char palette[256][4]; +} BMPHeader_t; + +/* +============== +LoadBMP +============== +*/ +static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ) +{ + int columns, rows, numPixels; + byte *pixbuf; + int row, column; + byte *buf_p; + byte *buffer; + int length; + BMPHeader_t bmpHeader; + byte *bmpRGBA; + + if ( !pic ) { + fileSystem->ReadFile ( name, NULL, timestamp ); + return; // just getting timestamp + } + + *pic = NULL; + + // + // load the file + // + length = fileSystem->ReadFile( name, (void **)&buffer, timestamp ); + if ( !buffer ) { + return; + } + + buf_p = buffer; + + bmpHeader.id[0] = *buf_p++; + bmpHeader.id[1] = *buf_p++; + bmpHeader.fileSize = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.width = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.height = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.planes = LittleShort( * ( short * ) buf_p ); + buf_p += 2; + bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p ); + buf_p += 2; + bmpHeader.compression = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.hRes = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.vRes = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.colors = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + bmpHeader.importantColors = LittleLong( * ( long * ) buf_p ); + buf_p += 4; + + memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) ); + + if ( bmpHeader.bitsPerPixel == 8 ) + buf_p += 1024; + + if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' ) + { + common->Error( "LoadBMP: only Windows-style BMP files supported (%s)\n", name ); + } + if ( bmpHeader.fileSize != length ) + { + common->Error( "LoadBMP: header size does not match file size (%lu vs. %d) (%s)\n", bmpHeader.fileSize, length, name ); + } + if ( bmpHeader.compression != 0 ) + { + common->Error( "LoadBMP: only uncompressed BMP files supported (%s)\n", name ); + } + if ( bmpHeader.bitsPerPixel < 8 ) + { + common->Error( "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name ); + } + + columns = bmpHeader.width; + rows = bmpHeader.height; + if ( rows < 0 ) + rows = -rows; + numPixels = columns * rows; + + if ( width ) + *width = columns; + if ( height ) + *height = rows; + + bmpRGBA = (byte *)R_StaticAlloc( numPixels * 4 ); + *pic = bmpRGBA; + + + for ( row = rows-1; row >= 0; row-- ) + { + pixbuf = bmpRGBA + row*columns*4; + + for ( column = 0; column < columns; column++ ) + { + unsigned char red, green, blue, alpha; + int palIndex; + unsigned short shortPixel; + + switch ( bmpHeader.bitsPerPixel ) + { + case 8: + palIndex = *buf_p++; + *pixbuf++ = bmpHeader.palette[palIndex][2]; + *pixbuf++ = bmpHeader.palette[palIndex][1]; + *pixbuf++ = bmpHeader.palette[palIndex][0]; + *pixbuf++ = 0xff; + break; + case 16: + shortPixel = * ( unsigned short * ) pixbuf; + pixbuf += 2; + *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7; + *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2; + *pixbuf++ = ( shortPixel & ( 31 ) ) << 3; + *pixbuf++ = 0xff; + break; + + case 24: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + alpha = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alpha; + break; + default: + common->Error( "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name ); + break; + } + } + } + + fileSystem->FreeFile( buffer ); + +} + + +/* +================================================================= + +PCX LOADING + +================================================================= +*/ + + +/* +============== +LoadPCX +============== +*/ +static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height, + ID_TIME_T *timestamp ) { + byte *raw; + pcx_t *pcx; + int x, y; + int len; + int dataByte, runLength; + byte *out, *pix; + int xmax, ymax; + + if ( !pic ) { + fileSystem->ReadFile( filename, NULL, timestamp ); + return; // just getting timestamp + } + + *pic = NULL; + *palette = NULL; + + // + // load the file + // + len = fileSystem->ReadFile( filename, (void **)&raw, timestamp ); + if (!raw) { + return; + } + + // + // parse the PCX file + // + pcx = (pcx_t *)raw; + raw = &pcx->data; + + xmax = LittleShort(pcx->xmax); + ymax = LittleShort(pcx->ymax); + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || xmax >= 1024 + || ymax >= 1024) + { + common->Printf( "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax); + return; + } + + out = (byte *)R_StaticAlloc( (ymax+1) * (xmax+1) ); + + *pic = out; + + pix = out; + + if (palette) + { + *palette = (byte *)R_StaticAlloc(768); + memcpy (*palette, (byte *)pcx + len - 768, 768); + } + + if (width) + *width = xmax+1; + if (height) + *height = ymax+1; +// FIXME: use bytes_per_line here? + + for (y=0 ; y<=ymax ; y++, pix += xmax+1) + { + for (x=0 ; x<=xmax ; ) + { + dataByte = *raw++; + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = *raw++; + } + else + runLength = 1; + + while(runLength-- > 0) + pix[x++] = dataByte; + } + + } + + if ( raw - (byte *)pcx > len) + { + common->Printf( "PCX file %s was malformed", filename ); + R_StaticFree (*pic); + *pic = NULL; + } + + fileSystem->FreeFile( pcx ); +} + + +/* +============== +LoadPCX32 +============== +*/ +static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height, ID_TIME_T *timestamp) { + byte *palette; + byte *pic8; + int i, c, p; + byte *pic32; + + if ( !pic ) { + fileSystem->ReadFile( filename, NULL, timestamp ); + return; // just getting timestamp + } + LoadPCX (filename, &pic8, &palette, width, height, timestamp); + if (!pic8) { + *pic = NULL; + return; + } + + c = (*width) * (*height); + pic32 = *pic = (byte *)R_StaticAlloc(4 * c ); + for (i = 0 ; i < c ; i++) { + p = pic8[i]; + pic32[0] = palette[p*3]; + pic32[1] = palette[p*3 + 1]; + pic32[2] = palette[p*3 + 2]; + pic32[3] = 255; + pic32 += 4; + } + + R_StaticFree( pic8 ); + R_StaticFree( palette ); +} + +/* +========================================================= + +TARGA LOADING + +========================================================= +*/ + +/* +============= +LoadTGA +============= +*/ +static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ) { + int columns, rows, numPixels, fileSize, numBytes; + byte *pixbuf; + int row, column; + byte *buf_p; + byte *buffer; + TargaHeader targa_header; + byte *targa_rgba; + + if ( !pic ) { + fileSystem->ReadFile( name, NULL, timestamp ); + return; // just getting timestamp + } + + *pic = NULL; + + // + // load the file + // + fileSize = fileSystem->ReadFile( name, (void **)&buffer, timestamp ); + if ( !buffer ) { + return; + } + + buf_p = buffer; + + targa_header.id_length = *buf_p++; + targa_header.colormap_type = *buf_p++; + targa_header.image_type = *buf_p++; + + targa_header.colormap_index = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.colormap_length = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.colormap_size = *buf_p++; + targa_header.x_origin = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.y_origin = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.width = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.height = LittleShort ( *(short *)buf_p ); + buf_p += 2; + targa_header.pixel_size = *buf_p++; + targa_header.attributes = *buf_p++; + + if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) { + common->Error( "LoadTGA( %s ): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name ); + } + + if ( targa_header.colormap_type != 0 ) { + common->Error( "LoadTGA( %s ): colormaps not supported\n", name ); + } + + if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) { + common->Error( "LoadTGA( %s ): Only 32 or 24 bit images supported (no colormaps)\n", name ); + } + + if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) { + numBytes = targa_header.width * targa_header.height * ( targa_header.pixel_size >> 3 ); + if ( numBytes > fileSize - 18 - targa_header.id_length ) { + common->Error( "LoadTGA( %s ): incomplete file\n", name ); + } + } + + columns = targa_header.width; + rows = targa_header.height; + numPixels = columns * rows; + + if ( width ) { + *width = columns; + } + if ( height ) { + *height = rows; + } + + targa_rgba = (byte *)R_StaticAlloc(numPixels*4); + *pic = targa_rgba; + + if ( targa_header.id_length != 0 ) { + buf_p += targa_header.id_length; // skip TARGA image comment + } + + if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) + { + // Uncompressed RGB or gray scale image + for( row = rows - 1; row >= 0; row-- ) + { + pixbuf = targa_rgba + row*columns*4; + for( column = 0; column < columns; column++) + { + unsigned char red,green,blue,alphabyte; + switch( targa_header.pixel_size ) + { + + case 8: + blue = *buf_p++; + green = blue; + red = blue; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + + case 24: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + alphabyte = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + } + } + } + else if ( targa_header.image_type == 10 ) { // Runlength encoded RGB images + unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; + + red = 0; + green = 0; + blue = 0; + alphabyte = 0xff; + + for( row = rows - 1; row >= 0; row-- ) { + pixbuf = targa_rgba + row*columns*4; + for( column = 0; column < columns; ) { + packetHeader= *buf_p++; + packetSize = 1 + (packetHeader & 0x7f); + if ( packetHeader & 0x80 ) { // run-length packet + switch( targa_header.pixel_size ) { + case 24: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + alphabyte = 255; + break; + case 32: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + alphabyte = *buf_p++; + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + + for( j = 0; j < packetSize; j++ ) { + *pixbuf++=red; + *pixbuf++=green; + *pixbuf++=blue; + *pixbuf++=alphabyte; + column++; + if ( column == columns ) { // run spans across rows + column = 0; + if ( row > 0) { + row--; + } + else { + goto breakOut; + } + pixbuf = targa_rgba + row*columns*4; + } + } + } + else { // non run-length packet + for( j = 0; j < packetSize; j++ ) { + switch( targa_header.pixel_size ) { + case 24: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = *buf_p++; + green = *buf_p++; + red = *buf_p++; + alphabyte = *buf_p++; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + column++; + if ( column == columns ) { // pixel packet run spans across rows + column = 0; + if ( row > 0 ) { + row--; + } + else { + goto breakOut; + } + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut: ; + } + } + + if ( (targa_header.attributes & (1<<5)) ) { // image flp bit + R_VerticalFlip( *pic, *width, *height ); + } + + fileSystem->FreeFile( buffer ); +} + +/* +========================================================= + +JPG LOADING + +Interfaces with the huge libjpeg +========================================================= +*/ + +/* +============= +LoadJPG +============= +*/ +static void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height, ID_TIME_T *timestamp ) { + /* This struct contains the JPEG decompression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct cinfo; + /* We use our private extension JPEG error handler. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + unsigned char *out; + byte *fbuffer; + byte *bbuf; + + /* In this example we want to open the input file before doing anything else, + * so that the setjmp() error recovery below can assume the file is open. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to read binary files. + */ + + // JDC: because fill_input_buffer() blindly copies INPUT_BUF_SIZE bytes, + // we need to make sure the file buffer is padded or it may crash + if ( pic ) { + *pic = NULL; // until proven otherwise + } + { + int len; + idFile *f; + + f = fileSystem->OpenFileRead( filename ); + if ( !f ) { + return; + } + len = f->Length(); + if ( timestamp ) { + *timestamp = f->Timestamp(); + } + if ( !pic ) { + fileSystem->CloseFile( f ); + return; // just getting timestamp + } + fbuffer = (byte *)Mem_ClearedAlloc( len + 4096 ); + f->Read( fbuffer, len ); + fileSystem->CloseFile( f ); + } + + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_stdio_src(&cinfo, fbuffer); + + /* Step 3: read file parameters with jpeg_read_header() */ + + (void) jpeg_read_header(&cinfo, true ); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + + /* In this example, we don't need to change any of the defaults set by + * jpeg_read_header(), so we do nothing here. + */ + + /* Step 5: Start decompressor */ + + (void) jpeg_start_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = cinfo.output_width * cinfo.output_components; + + if (cinfo.output_components!=4) { + common->DWarning( "JPG %s is unsupported color depth (%d)", + filename, cinfo.output_components); + } + out = (byte *)R_StaticAlloc(cinfo.output_width*cinfo.output_height*4); + + *pic = out; + *width = cinfo.output_width; + *height = cinfo.output_height; + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo.output_scanline < cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + bbuf = ((out+(row_stride*cinfo.output_scanline))); + buffer = &bbuf; + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + } + + // clear all the alphas to 255 + { + int i, j; + byte *buf; + + buf = *pic; + + j = cinfo.output_width * cinfo.output_height * 4; + for ( i = 3 ; i < j ; i+=4 ) { + buf[i] = 255; + } + } + + /* Step 7: Finish decompression */ + + (void) jpeg_finish_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* Step 8: Release JPEG decompression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_decompress(&cinfo); + + /* After finish_decompress, we can close the input file. + * Here we postpone it until after no more JPEG errors are possible, + * so as to simplify the setjmp error logic above. (Actually, I don't + * think that jpeg_destroy can do an error exit, but why assume anything...) + */ + Mem_Free( fbuffer ); + + /* At this point you may want to check to see whether any corrupt-data + * warnings occurred (test whether jerr.pub.num_warnings is nonzero). + */ + + /* And we're done! */ +} + +//=================================================================== + +/* +================= +R_LoadImage + +Loads any of the supported image types into a cannonical +32 bit format. + +Automatically attempts to load .jpg files if .tga files fail to load. + +*pic will be NULL if the load failed. + +Anything that is going to make this into a texture would use +makePowerOf2 = true, but something loading an image as a lookup +table of some sort would leave it in identity form. + +It is important to do this at image load time instead of texture load +time for bump maps. + +Timestamp may be NULL if the value is going to be ignored + +If pic is NULL, the image won't actually be loaded, it will just find the +timestamp. +================= +*/ +void R_LoadImage( const char *cname, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 ) { + idStr name = cname; + + if ( pic ) { + *pic = NULL; + } + if ( timestamp ) { + *timestamp = 0xFFFFFFFF; + } + if ( width ) { + *width = 0; + } + if ( height ) { + *height = 0; + } + + name.DefaultFileExtension( ".tga" ); + + if (name.Length()<5) { + return; + } + + name.ToLower(); + idStr ext; + name.ExtractFileExtension( ext ); + + if ( ext == "tga" ) { + LoadTGA( name.c_str(), pic, width, height, timestamp ); // try tga first + if ( ( pic && *pic == 0 ) || ( timestamp && *timestamp == -1 ) ) { + name.StripFileExtension(); + name.DefaultFileExtension( ".jpg" ); + LoadJPG( name.c_str(), pic, width, height, timestamp ); + } + } else if ( ext == "pcx" ) { + LoadPCX32( name.c_str(), pic, width, height, timestamp ); + } else if ( ext == "bmp" ) { + LoadBMP( name.c_str(), pic, width, height, timestamp ); + } else if ( ext == "jpg" ) { + LoadJPG( name.c_str(), pic, width, height, timestamp ); + } + + if ( ( width && *width < 1 ) || ( height && *height < 1 ) ) { + if ( pic && *pic ) { + R_StaticFree( *pic ); + *pic = 0; + } + } + + // + // convert to exact power of 2 sizes + // + if ( pic && *pic && makePowerOf2 ) { + int w, h; + int scaled_width, scaled_height; + byte *resampledBuffer; + + w = *width; + h = *height; + + for (scaled_width = 1 ; scaled_width < w ; scaled_width<<=1) + ; + for (scaled_height = 1 ; scaled_height < h ; scaled_height<<=1) + ; + + if ( scaled_width != w || scaled_height != h ) { + if ( globalImages->image_roundDown.GetBool() && scaled_width > w ) { + scaled_width >>= 1; + } + if ( globalImages->image_roundDown.GetBool() && scaled_height > h ) { + scaled_height >>= 1; + } + + resampledBuffer = R_ResampleTexture( *pic, w, h, scaled_width, scaled_height ); + R_StaticFree( *pic ); + *pic = resampledBuffer; + *width = scaled_width; + *height = scaled_height; + } + } +} + + +/* +======================= +R_LoadCubeImages + +Loads six files with proper extensions +======================= +*/ +bool R_LoadCubeImages( const char *imgName, cubeFiles_t extensions, byte *pics[6], int *outSize, ID_TIME_T *timestamp ) { + int i, j; + char *cameraSides[6] = { "_forward.tga", "_back.tga", "_left.tga", "_right.tga", + "_up.tga", "_down.tga" }; + char *axisSides[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga", + "_pz.tga", "_nz.tga" }; + char **sides; + char fullName[MAX_IMAGE_NAME]; + int width, height, size = 0; + + if ( extensions == CF_CAMERA ) { + sides = cameraSides; + } else { + sides = axisSides; + } + + // FIXME: precompressed cube map files + if ( pics ) { + memset( pics, 0, 6*sizeof(pics[0]) ); + } + if ( timestamp ) { + *timestamp = 0; + } + + for ( i = 0 ; i < 6 ; i++ ) { + idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] ); + + ID_TIME_T thisTime; + if ( !pics ) { + // just checking timestamps + R_LoadImageProgram( fullName, NULL, &width, &height, &thisTime ); + } else { + R_LoadImageProgram( fullName, &pics[i], &width, &height, &thisTime ); + } + if ( thisTime == FILE_NOT_FOUND_TIMESTAMP ) { + break; + } + if ( i == 0 ) { + size = width; + } + if ( width != size || height != size ) { + common->Warning( "Mismatched sizes on cube map '%s'", imgName ); + break; + } + if ( timestamp ) { + if ( thisTime > *timestamp ) { + *timestamp = thisTime; + } + } + if ( pics && extensions == CF_CAMERA ) { + // convert from "camera" images to native cube map images + switch( i ) { + case 0: // forward + R_RotatePic( pics[i], width); + break; + case 1: // back + R_RotatePic( pics[i], width); + R_HorizontalFlip( pics[i], width, height ); + R_VerticalFlip( pics[i], width, height ); + break; + case 2: // left + R_VerticalFlip( pics[i], width, height ); + break; + case 3: // right + R_HorizontalFlip( pics[i], width, height ); + break; + case 4: // up + R_RotatePic( pics[i], width); + break; + case 5: // down + R_RotatePic( pics[i], width); + break; + } + } + } + + if ( i != 6 ) { + // we had an error, so free everything + if ( pics ) { + for ( j = 0 ; j < i ; j++ ) { + R_StaticFree( pics[j] ); + } + } + + if ( timestamp ) { + *timestamp = 0; + } + return false; + } + + if ( outSize ) { + *outSize = size; + } + return true; +} diff --git a/renderer/Image_init.cpp b/renderer/Image_init.cpp new file mode 100644 index 000000000..97ebb38e7 --- /dev/null +++ b/renderer/Image_init.cpp @@ -0,0 +1,2210 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +const char *imageFilter[] = { + "GL_LINEAR_MIPMAP_NEAREST", + "GL_LINEAR_MIPMAP_LINEAR", + "GL_NEAREST", + "GL_LINEAR", + "GL_NEAREST_MIPMAP_NEAREST", + "GL_NEAREST_MIPMAP_LINEAR", + NULL +}; + +idCVar idImageManager::image_filter( "image_filter", imageFilter[1], CVAR_RENDERER | CVAR_ARCHIVE, "changes texture filtering on mipmapped images", imageFilter, idCmdSystem::ArgCompletion_String ); +idCVar idImageManager::image_anisotropy( "image_anisotropy", "1", CVAR_RENDERER | CVAR_ARCHIVE, "set the maximum texture anisotropy if available" ); +idCVar idImageManager::image_lodbias( "image_lodbias", "0", CVAR_RENDERER | CVAR_ARCHIVE, "change lod bias on mipmapped images" ); +idCVar idImageManager::image_downSize( "image_downSize", "0", CVAR_RENDERER | CVAR_ARCHIVE, "controls texture downsampling" ); +idCVar idImageManager::image_forceDownSize( "image_forceDownSize", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "" ); +idCVar idImageManager::image_roundDown( "image_roundDown", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "round bad sizes down to nearest power of two" ); +idCVar idImageManager::image_colorMipLevels( "image_colorMipLevels", "0", CVAR_RENDERER | CVAR_BOOL, "development aid to see texture mip usage" ); +idCVar idImageManager::image_preload( "image_preload", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "if 0, dynamically load all images" ); +idCVar idImageManager::image_useCompression( "image_useCompression", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "0 = force everything to high quality" ); +idCVar idImageManager::image_useAllFormats( "image_useAllFormats", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "allow alpha/intensity/luminance/luminance+alpha" ); +idCVar idImageManager::image_useNormalCompression( "image_useNormalCompression", "2", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "2 = use rxgb compression for normal maps, 1 = use 256 color compression for normal maps if available" ); +idCVar idImageManager::image_usePrecompressedTextures( "image_usePrecompressedTextures", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use .dds files if present" ); +idCVar idImageManager::image_writePrecompressedTextures( "image_writePrecompressedTextures", "0", CVAR_RENDERER | CVAR_BOOL, "write .dds files if necessary" ); +idCVar idImageManager::image_writeNormalTGA( "image_writeNormalTGA", "0", CVAR_RENDERER | CVAR_BOOL, "write .tgas of the final normal maps for debugging" ); +idCVar idImageManager::image_writeNormalTGAPalletized( "image_writeNormalTGAPalletized", "0", CVAR_RENDERER | CVAR_BOOL, "write .tgas of the final palletized normal maps for debugging" ); +idCVar idImageManager::image_writeTGA( "image_writeTGA", "0", CVAR_RENDERER | CVAR_BOOL, "write .tgas of the non normal maps for debugging" ); +idCVar idImageManager::image_useOffLineCompression( "image_useOfflineCompression", "0", CVAR_RENDERER | CVAR_BOOL, "write a batch file for offline compression of DDS files" ); +idCVar idImageManager::image_cacheMinK( "image_cacheMinK", "200", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "maximum KB of precompressed files to read at specification time" ); +idCVar idImageManager::image_cacheMegs( "image_cacheMegs", "20", CVAR_RENDERER | CVAR_ARCHIVE, "maximum MB set aside for temporary loading of full-sized precompressed images" ); +idCVar idImageManager::image_useCache( "image_useCache", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "1 = do background load image caching" ); +idCVar idImageManager::image_showBackgroundLoads( "image_showBackgroundLoads", "0", CVAR_RENDERER | CVAR_BOOL, "1 = print number of outstanding background loads" ); +idCVar idImageManager::image_downSizeSpecular( "image_downSizeSpecular", "0", CVAR_RENDERER | CVAR_ARCHIVE, "controls specular downsampling" ); +idCVar idImageManager::image_downSizeBump( "image_downSizeBump", "0", CVAR_RENDERER | CVAR_ARCHIVE, "controls normal map downsampling" ); +idCVar idImageManager::image_downSizeSpecularLimit( "image_downSizeSpecularLimit", "64", CVAR_RENDERER | CVAR_ARCHIVE, "controls specular downsampled limit" ); +idCVar idImageManager::image_downSizeBumpLimit( "image_downSizeBumpLimit", "128", CVAR_RENDERER | CVAR_ARCHIVE, "controls normal map downsample limit" ); +idCVar idImageManager::image_ignoreHighQuality( "image_ignoreHighQuality", "0", CVAR_RENDERER | CVAR_ARCHIVE, "ignore high quality setting on materials" ); +idCVar idImageManager::image_downSizeLimit( "image_downSizeLimit", "256", CVAR_RENDERER | CVAR_ARCHIVE, "controls diffuse map downsample limit" ); +// do this with a pointer, in case we want to make the actual manager +// a private virtual subclass +idImageManager imageManager; +idImageManager *globalImages = &imageManager; + + +enum IMAGE_CLASSIFICATION { + IC_NPC, + IC_WEAPON, + IC_MONSTER, + IC_MODELGEOMETRY, + IC_ITEMS, + IC_MODELSOTHER, + IC_GUIS, + IC_WORLDGEOMETRY, + IC_OTHER, + IC_COUNT +}; + +struct imageClassificate_t { + const char *rootPath; + const char *desc; + int type; + int maxWidth; + int maxHeight; +}; + +typedef idList< int > intList; + +const imageClassificate_t IC_Info[] = { + { "models/characters", "Characters", IC_NPC, 512, 512 }, + { "models/weapons", "Weapons", IC_WEAPON, 512, 512 }, + { "models/monsters", "Monsters", IC_MONSTER, 512, 512 }, + { "models/mapobjects", "Model Geometry", IC_MODELGEOMETRY, 512, 512 }, + { "models/items", "Items", IC_ITEMS, 512, 512 }, + { "models", "Other model textures", IC_MODELSOTHER, 512, 512 }, + { "guis/assets", "Guis", IC_GUIS, 256, 256 }, + { "textures", "World Geometry", IC_WORLDGEOMETRY, 256, 256 }, + { "", "Other", IC_OTHER, 256, 256 } +}; + + + +static int ClassifyImage( const char *name ) { + idStr str; + str = name; + for ( int i = 0; i < IC_COUNT; i++ ) { + if ( str.Find( IC_Info[i].rootPath, false ) == 0 ) { + return IC_Info[i].type; + } + } + return IC_OTHER; +} + +/* +================ +R_RampImage + +Creates a 0-255 ramp image +================ +*/ +static void R_RampImage( idImage *image ) { + int x; + byte data[256][4]; + + for (x=0 ; x<256 ; x++) { + data[x][0] = + data[x][1] = + data[x][2] = + data[x][3] = x; + } + + image->GenerateImage( (byte *)data, 256, 1, + TF_NEAREST, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + +/* +================ +R_SpecularTableImage + +Creates a ramp that matches our fudged specular calculation +================ +*/ +static void R_SpecularTableImage( idImage *image ) { + int x; + byte data[256][4]; + + for (x=0 ; x<256 ; x++) { + float f = x/255.f; +#if 0 + f = pow(f, 16); +#else + // this is the behavior of the hacked up fragment programs that + // can't really do a power function + f = (f-0.75)*4; + if ( f < 0 ) { + f = 0; + } + f = f * f; +#endif + int b = (int)(f * 255); + + data[x][0] = + data[x][1] = + data[x][2] = + data[x][3] = b; + } + + image->GenerateImage( (byte *)data, 256, 1, + TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + + +/* +================ +R_Specular2DTableImage + +Create a 2D table that calculates ( reflection dot , specularity ) +================ +*/ +static void R_Specular2DTableImage( idImage *image ) { + int x, y; + byte data[256][256][4]; + + memset( data, 0, sizeof( data ) ); + for ( x = 0 ; x < 256 ; x++ ) { + float f = x / 255.0f; + for ( y = 0; y < 256; y++ ) { + + int b = (int)( pow( f, y ) * 255.0f ); + if ( b == 0 ) { + // as soon as b equals zero all remaining values in this column are going to be zero + // we early out to avoid pow() underflows + break; + } + + data[y][x][0] = + data[y][x][1] = + data[y][x][2] = + data[y][x][3] = b; + } + } + + image->GenerateImage( (byte *)data, 256, 256, TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + + + +/* +================ +R_AlphaRampImage + +Creates a 0-255 ramp image +================ +*/ +static void R_AlphaRampImage( idImage *image ) { + int x; + byte data[256][4]; + + for (x=0 ; x<256 ; x++) { + data[x][0] = + data[x][1] = + data[x][2] = 255; + data[x][3] = x; + } + + image->GenerateImage( (byte *)data, 256, 1, + TF_NEAREST, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + + + +/* +================== +R_CreateDefaultImage + +the default image will be grey with a white box outline +to allow you to see the mapping coordinates on a surface +================== +*/ +#define DEFAULT_SIZE 16 +void idImage::MakeDefault() { + int x, y; + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + + if ( com_developer.GetBool() ) { + // grey center + for ( y = 0 ; y < DEFAULT_SIZE ; y++ ) { + for ( x = 0 ; x < DEFAULT_SIZE ; x++ ) { + data[y][x][0] = 32; + data[y][x][1] = 32; + data[y][x][2] = 32; + data[y][x][3] = 255; + } + } + + // white border + for ( x = 0 ; x < DEFAULT_SIZE ; x++ ) { + data[0][x][0] = + data[0][x][1] = + data[0][x][2] = + data[0][x][3] = 255; + + data[x][0][0] = + data[x][0][1] = + data[x][0][2] = + data[x][0][3] = 255; + + data[DEFAULT_SIZE-1][x][0] = + data[DEFAULT_SIZE-1][x][1] = + data[DEFAULT_SIZE-1][x][2] = + data[DEFAULT_SIZE-1][x][3] = 255; + + data[x][DEFAULT_SIZE-1][0] = + data[x][DEFAULT_SIZE-1][1] = + data[x][DEFAULT_SIZE-1][2] = + data[x][DEFAULT_SIZE-1][3] = 255; + } + } else { + for ( y = 0 ; y < DEFAULT_SIZE ; y++ ) { + for ( x = 0 ; x < DEFAULT_SIZE ; x++ ) { + data[y][x][0] = 0; + data[y][x][1] = 0; + data[y][x][2] = 0; + data[y][x][3] = 0; + } + } + } + + GenerateImage( (byte *)data, + DEFAULT_SIZE, DEFAULT_SIZE, + TF_DEFAULT, true, TR_REPEAT, TD_DEFAULT ); + + defaulted = true; +} + +static void R_DefaultImage( idImage *image ) { + image->MakeDefault(); +} + +static void R_WhiteImage( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + + // solid white texture + memset( data, 255, sizeof( data ) ); + image->GenerateImage( (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, + TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT ); +} + +static void R_BlackImage( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + + // solid black texture + memset( data, 0, sizeof( data ) ); + image->GenerateImage( (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, + TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT ); +} + + +// the size determines how far away from the edge the blocks start fading +static const int BORDER_CLAMP_SIZE = 32; +static void R_BorderClampImage( idImage *image ) { + byte data[BORDER_CLAMP_SIZE][BORDER_CLAMP_SIZE][4]; + + // solid white texture with a single pixel black border + memset( data, 255, sizeof( data ) ); + for ( int i = 0 ; i < BORDER_CLAMP_SIZE ; i++ ) { + data[i][0][0] = + data[i][0][1] = + data[i][0][2] = + data[i][0][3] = + + data[i][BORDER_CLAMP_SIZE-1][0] = + data[i][BORDER_CLAMP_SIZE-1][1] = + data[i][BORDER_CLAMP_SIZE-1][2] = + data[i][BORDER_CLAMP_SIZE-1][3] = + + data[0][i][0] = + data[0][i][1] = + data[0][i][2] = + data[0][i][3] = + + data[BORDER_CLAMP_SIZE-1][i][0] = + data[BORDER_CLAMP_SIZE-1][i][1] = + data[BORDER_CLAMP_SIZE-1][i][2] = + data[BORDER_CLAMP_SIZE-1][i][3] = 0; + } + + image->GenerateImage( (byte *)data, BORDER_CLAMP_SIZE, BORDER_CLAMP_SIZE, + TF_LINEAR /* TF_NEAREST */, false, TR_CLAMP_TO_BORDER, TD_DEFAULT ); + + if ( !glConfig.isInitialized ) { + // can't call qglTexParameterfv yet + return; + } + // explicit zero border + float color[4]; + color[0] = color[1] = color[2] = color[3] = 0; + qglTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color ); +} + +static void R_RGBA8Image( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + + memset( data, 0, sizeof( data ) ); + data[0][0][0] = 16; + data[0][0][1] = 32; + data[0][0][2] = 48; + data[0][0][3] = 96; + + image->GenerateImage( (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, + TF_DEFAULT, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_RGB8Image( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + + memset( data, 0, sizeof( data ) ); + data[0][0][0] = 16; + data[0][0][1] = 32; + data[0][0][2] = 48; + data[0][0][3] = 255; + + image->GenerateImage( (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, + TF_DEFAULT, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_AlphaNotchImage( idImage *image ) { + byte data[2][4]; + + // this is used for alpha test clip planes + + data[0][0] = data[0][1] = data[0][2] = 255; + data[0][3] = 0; + data[1][0] = data[1][1] = data[1][2] = 255; + data[1][3] = 255; + + image->GenerateImage( (byte *)data, 2, 1, + TF_NEAREST, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + +static void R_FlatNormalImage( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + int i; + + int red = ( globalImages->image_useNormalCompression.GetInteger() == 1 ) ? 0 : 3; + int alpha = ( red == 0 ) ? 3 : 0; + // flat normal map for default bunp mapping + for ( i = 0 ; i < 4 ; i++ ) { + data[0][i][red] = 128; + data[0][i][1] = 128; + data[0][i][2] = 255; + data[0][i][alpha] = 255; + } + image->GenerateImage( (byte *)data, 2, 2, + TF_DEFAULT, true, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_AmbientNormalImage( idImage *image ) { + byte data[DEFAULT_SIZE][DEFAULT_SIZE][4]; + int i; + + int red = ( globalImages->image_useNormalCompression.GetInteger() == 1 ) ? 0 : 3; + int alpha = ( red == 0 ) ? 3 : 0; + // flat normal map for default bunp mapping + for ( i = 0 ; i < 4 ; i++ ) { + data[0][i][red] = (byte)(255 * tr.ambientLightVector[0]); + data[0][i][1] = (byte)(255 * tr.ambientLightVector[1]); + data[0][i][2] = (byte)(255 * tr.ambientLightVector[2]); + data[0][i][alpha] = 255; + } + const byte *pics[6]; + for ( i = 0 ; i < 6 ; i++ ) { + pics[i] = data[0][0]; + } + // this must be a cube map for fragment programs to simply substitute for the normalization cube map + image->GenerateCubeImage( pics, 2, TF_DEFAULT, true, TD_HIGH_QUALITY ); +} + + +static void CreateSquareLight( void ) { + byte *buffer; + int x, y; + int dx, dy; + int d; + int width, height; + + width = height = 128; + + buffer = (byte *)R_StaticAlloc( 128 * 128 * 4 ); + + for ( x = 0 ; x < 128 ; x++ ) { + if ( x < 32 ) { + dx = 32 - x; + } else if ( x > 96 ) { + dx = x - 96; + } else { + dx = 0; + } + for ( y = 0 ; y < 128 ; y++ ) { + if ( y < 32 ) { + dy = 32 - y; + } else if ( y > 96 ) { + dy = y - 96; + } else { + dy = 0; + } + d = (byte)idMath::Sqrt( dx * dx + dy * dy ); + if ( d > 32 ) { + d = 32; + } + d = 255 - d * 8; + if ( d < 0 ) { + d = 0; + } + buffer[(y*128+x)*4+0] = + buffer[(y*128+x)*4+1] = + buffer[(y*128+x)*4+2] = d; + buffer[(y*128+x)*4+3] = 255; + } + } + + R_WriteTGA( "lights/squarelight.tga", buffer, width, height ); + + R_StaticFree( buffer ); +} + +static void CreateFlashOff( void ) { + byte *buffer; + int x, y; + int d; + int width, height; + + width = 256; + height = 4; + + buffer = (byte *)R_StaticAlloc( width * height * 4 ); + + for ( x = 0 ; x < width ; x++ ) { + for ( y = 0 ; y < height ; y++ ) { + d = 255 - ( x * 256 / width ); + buffer[(y*width+x)*4+0] = + buffer[(y*width+x)*4+1] = + buffer[(y*width+x)*4+2] = d; + buffer[(y*width+x)*4+3] = 255; + } + } + + R_WriteTGA( "lights/flashoff.tga", buffer, width, height ); + + R_StaticFree( buffer ); +} + + +/* +=============== +CreatePitFogImage +=============== +*/ +void CreatePitFogImage( void ) { + byte data[16][16][4]; + int i, j; + + memset( data, 0, sizeof( data ) ); + for ( i = 0 ; i < 16 ; i++ ) { + int a; + +#if 0 + if ( i > 14 ) { + a = 0; + } else +#endif + { + a = i * 255 / 15; + if ( a > 255 ) { + a = 255; + } + } + + for ( j = 0 ; j < 16 ; j++ ) { + data[j][i][0] = + data[j][i][1] = + data[j][i][2] = 255; + data[j][i][3] = a; + } + } + + R_WriteTGA( "shapes/pitFalloff.tga", data[0][0], 16, 16 ); +} + +/* +=============== +CreatealphaSquareImage +=============== +*/ +void CreatealphaSquareImage( void ) { + byte data[16][16][4]; + int i, j; + + for ( i = 0 ; i < 16 ; i++ ) { + int a; + + for ( j = 0 ; j < 16 ; j++ ) { + if ( i == 0 || i == 15 || j == 0 || j == 15 ) { + a = 0; + } else { + a = 255; + } + data[j][i][0] = + data[j][i][1] = + data[j][i][2] = 255; + data[j][i][3] = a; + } + } + + R_WriteTGA( "shapes/alphaSquare.tga", data[0][0], 16, 16 ); +} + +#define NORMAL_MAP_SIZE 32 + +/*** NORMALIZATION CUBE MAP CONSTRUCTION ***/ + +/* Given a cube map face index, cube map size, and integer 2D face position, + * return the cooresponding normalized vector. + */ +static void getCubeVector(int i, int cubesize, int x, int y, float *vector) { + float s, t, sc, tc, mag; + + s = ((float)x + 0.5) / (float)cubesize; + t = ((float)y + 0.5) / (float)cubesize; + sc = s*2.0 - 1.0; + tc = t*2.0 - 1.0; + + switch (i) { + case 0: + vector[0] = 1.0; + vector[1] = -tc; + vector[2] = -sc; + break; + case 1: + vector[0] = -1.0; + vector[1] = -tc; + vector[2] = sc; + break; + case 2: + vector[0] = sc; + vector[1] = 1.0; + vector[2] = tc; + break; + case 3: + vector[0] = sc; + vector[1] = -1.0; + vector[2] = -tc; + break; + case 4: + vector[0] = sc; + vector[1] = -tc; + vector[2] = 1.0; + break; + case 5: + vector[0] = -sc; + vector[1] = -tc; + vector[2] = -1.0; + break; + } + + mag = idMath::InvSqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]); + vector[0] *= mag; + vector[1] *= mag; + vector[2] *= mag; +} + +/* Initialize a cube map texture object that generates RGB values + * that when expanded to a [-1,1] range in the register combiners + * form a normalized vector matching the per-pixel vector used to + * access the cube map. + */ +static void makeNormalizeVectorCubeMap( idImage *image ) { + float vector[3]; + int i, x, y; + byte *pixels[6]; + int size; + + size = NORMAL_MAP_SIZE; + + pixels[0] = (GLubyte*) Mem_Alloc(size*size*4*6); + + for (i = 0; i < 6; i++) { + pixels[i] = pixels[0] + i*size*size*4; + for (y = 0; y < size; y++) { + for (x = 0; x < size; x++) { + getCubeVector(i, size, x, y, vector); + pixels[i][4*(y*size+x) + 0] = (byte)(128 + 127*vector[0]); + pixels[i][4*(y*size+x) + 1] = (byte)(128 + 127*vector[1]); + pixels[i][4*(y*size+x) + 2] = (byte)(128 + 127*vector[2]); + pixels[i][4*(y*size+x) + 3] = 255; + } + } + } + + image->GenerateCubeImage( (const byte **)pixels, size, + TF_LINEAR, false, TD_HIGH_QUALITY ); + + Mem_Free(pixels[0]); +} + + + + +/* +================ +R_CreateNoFalloffImage + +This is a solid white texture that is zero clamped. +================ +*/ +static void R_CreateNoFalloffImage( idImage *image ) { + int x,y; + byte data[16][FALLOFF_TEXTURE_SIZE][4]; + + memset( data, 0, sizeof( data ) ); + for (x=1 ; xGenerateImage( (byte *)data, FALLOFF_TEXTURE_SIZE, 16, + TF_DEFAULT, false, TR_CLAMP_TO_ZERO, TD_HIGH_QUALITY ); +} + + +/* +================ +R_FogImage + +We calculate distance correctly in two planes, but the +third will still be projection based +================ +*/ +const int FOG_SIZE = 128; + +void R_FogImage( idImage *image ) { + int x,y; + byte data[FOG_SIZE][FOG_SIZE][4]; + int b; + +float step[256]; +int i; +float remaining = 1.0; +for ( i = 0 ; i < 256 ; i++ ) { + step[i] = remaining; + remaining *= 0.982f; +} + + for (x=0 ; x 255 ) { + b = 255; + } +b = (byte)(255 * ( 1.0 - step[b] )); + if ( x == 0 || x == FOG_SIZE-1 || y == 0 || y == FOG_SIZE-1 ) { + b = 255; // avoid clamping issues + } + data[y][x][0] = + data[y][x][1] = + data[y][x][2] = 255; + data[y][x][3] = b; + } + } + + image->GenerateImage( (byte *)data, FOG_SIZE, FOG_SIZE, + TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + + +/* +================ +FogFraction + +Height values below zero are inside the fog volume +================ +*/ +static const float RAMP_RANGE = 8; +static const float DEEP_RANGE = -30; +static float FogFraction( float viewHeight, float targetHeight ) { + float total = idMath::Fabs( targetHeight - viewHeight ); + +// return targetHeight >= 0 ? 0 : 1.0; + + // only ranges that cross the ramp range are special + if ( targetHeight > 0 && viewHeight > 0 ) { + return 0.0; + } + if ( targetHeight < -RAMP_RANGE && viewHeight < -RAMP_RANGE ) { + return 1.0; + } + + float above; + if ( targetHeight > 0 ) { + above = targetHeight; + } else if ( viewHeight > 0 ) { + above = viewHeight; + } else { + above = 0; + } + + float rampTop, rampBottom; + + if ( viewHeight > targetHeight ) { + rampTop = viewHeight; + rampBottom = targetHeight; + } else { + rampTop = targetHeight; + rampBottom = viewHeight; + } + if ( rampTop > 0 ) { + rampTop = 0; + } + if ( rampBottom < -RAMP_RANGE ) { + rampBottom = -RAMP_RANGE; + } + + float rampSlope = 1.0 / RAMP_RANGE; + + if ( !total ) { + return -viewHeight * rampSlope; + } + + float ramp = ( 1.0 - ( rampTop * rampSlope + rampBottom * rampSlope ) * -0.5 ) * ( rampTop - rampBottom ); + + float frac = ( total - above - ramp ) / total; + + // after it gets moderately deep, always use full value + float deepest = viewHeight < targetHeight ? viewHeight : targetHeight; + + float deepFrac = deepest / DEEP_RANGE; + if ( deepFrac >= 1.0 ) { + return 1.0; + } + + frac = frac * ( 1.0 - deepFrac ) + deepFrac; + + return frac; +} + +/* +================ +R_FogEnterImage + +Modulate the fog alpha density based on the distance of the +start and end points to the terminator plane +================ +*/ +void R_FogEnterImage( idImage *image ) { + int x,y; + byte data[FOG_ENTER_SIZE][FOG_ENTER_SIZE][4]; + int b; + + for (x=0 ; x 255 ) { + b = 255; + } + data[y][x][0] = + data[y][x][1] = + data[y][x][2] = 255; + data[y][x][3] = b; + } + } + + // if mipmapped, acutely viewed surfaces fade wrong + image->GenerateImage( (byte *)data, FOG_ENTER_SIZE, FOG_ENTER_SIZE, + TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + + +/* +================ +R_QuadraticImage + +================ +*/ +static const int QUADRATIC_WIDTH = 32; +static const int QUADRATIC_HEIGHT = 4; + +void R_QuadraticImage( idImage *image ) { + int x,y; + byte data[QUADRATIC_HEIGHT][QUADRATIC_WIDTH][4]; + int b; + + + for (x=0 ; x 255 ) { + b = 255; + } + data[y][x][0] = + data[y][x][1] = + data[y][x][2] = b; + data[y][x][3] = 255; + } + } + + image->GenerateImage( (byte *)data, QUADRATIC_WIDTH, QUADRATIC_HEIGHT, + TF_DEFAULT, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + +//===================================================================== + + +typedef struct { + char *name; + int minimize, maximize; +} filterName_t; + + + +/* +=============== +ChangeTextureFilter + +This resets filtering on all loaded images +New images will automatically pick up the current values. +=============== +*/ +void idImageManager::ChangeTextureFilter( void ) { + int i; + idImage *glt; + const char *string; +static filterName_t textureFilters[] = { + {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR}, + {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}, + {"GL_NEAREST", GL_NEAREST, GL_NEAREST}, + {"GL_LINEAR", GL_LINEAR, GL_LINEAR}, + {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST}, + {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST} +}; + + // if these are changed dynamically, it will force another ChangeTextureFilter + image_filter.ClearModified(); + image_anisotropy.ClearModified(); + image_lodbias.ClearModified(); + + string = image_filter.GetString(); + for ( i = 0; i < 6; i++ ) { + if ( !idStr::Icmp( textureFilters[i].name, string ) ) { + break; + } + } + + if ( i == 6 ) { + common->Warning( "bad r_textureFilter: '%s'", string); + // default to LINEAR_MIPMAP_NEAREST + i = 0; + } + + // set the values for future images + textureMinFilter = textureFilters[i].minimize; + textureMaxFilter = textureFilters[i].maximize; + textureAnisotropy = image_anisotropy.GetFloat(); + if ( textureAnisotropy < 1 ) { + textureAnisotropy = 1; + } else if ( textureAnisotropy > glConfig.maxTextureAnisotropy ) { + textureAnisotropy = glConfig.maxTextureAnisotropy; + } + textureLODBias = image_lodbias.GetFloat(); + + // change all the existing mipmap texture objects with default filtering + + for ( i = 0 ; i < images.Num() ; i++ ) { + unsigned int texEnum = GL_TEXTURE_2D; + + glt = images[ i ]; + + switch( glt->type ) { + case TT_2D: + texEnum = GL_TEXTURE_2D; + break; + case TT_3D: + texEnum = GL_TEXTURE_3D; + break; + case TT_CUBIC: + texEnum = GL_TEXTURE_CUBE_MAP_EXT; + break; + } + + // make sure we don't start a background load + if ( glt->texnum == idImage::TEXTURE_NOT_LOADED ) { + continue; + } + glt->Bind(); + if ( glt->filter == TF_DEFAULT ) { + qglTexParameterf(texEnum, GL_TEXTURE_MIN_FILTER, globalImages->textureMinFilter ); + qglTexParameterf(texEnum, GL_TEXTURE_MAG_FILTER, globalImages->textureMaxFilter ); + } + if ( glConfig.anisotropicAvailable ) { + qglTexParameterf(texEnum, GL_TEXTURE_MAX_ANISOTROPY_EXT, globalImages->textureAnisotropy ); + } + if ( glConfig.textureLODBiasAvailable ) { + qglTexParameterf(texEnum, GL_TEXTURE_LOD_BIAS_EXT, globalImages->textureLODBias ); + } + } +} + +/* +=============== +idImage::Reload +=============== +*/ +void idImage::Reload( bool checkPrecompressed, bool force ) { + // always regenerate functional images + if ( generatorFunction ) { + common->DPrintf( "regenerating %s.\n", imgName.c_str() ); + generatorFunction( this ); + return; + } + + // check file times + if ( !force ) { + ID_TIME_T current; + + if ( cubeFiles != CF_2D ) { + R_LoadCubeImages( imgName, cubeFiles, NULL, NULL, ¤t ); + } else { + // get the current values + R_LoadImageProgram( imgName, NULL, NULL, NULL, ¤t ); + } + if ( current <= timestamp ) { + return; + } + } + + common->DPrintf( "reloading %s.\n", imgName.c_str() ); + + PurgeImage(); + + // force no precompressed image check, which will cause it to be reloaded + // from source, and another precompressed file generated. + // Load is from the front end, so the back end must be synced + ActuallyLoadImage( checkPrecompressed, false ); +} + +/* +=============== +R_ReloadImages_f + +Regenerate all images that came directly from files that have changed, so +any saved changes will show up in place. + +New r_texturesize/r_texturedepth variables will take effect on reload + +reloadImages +=============== +*/ +void R_ReloadImages_f( const idCmdArgs &args ) { + int i; + idImage *image; + bool all; + bool checkPrecompressed; + + // this probably isn't necessary... + globalImages->ChangeTextureFilter(); + + all = false; + checkPrecompressed = false; // if we are doing this as a vid_restart, look for precompressed like normal + + if ( args.Argc() == 2 ) { + if ( !idStr::Icmp( args.Argv(1), "all" ) ) { + all = true; + } else if ( !idStr::Icmp( args.Argv(1), "reload" ) ) { + all = true; + checkPrecompressed = true; + } else { + common->Printf( "USAGE: reloadImages \n" ); + return; + } + } + + for ( i = 0 ; i < globalImages->images.Num() ; i++ ) { + image = globalImages->images[ i ]; + image->Reload( checkPrecompressed, all ); + } +} + +typedef struct { + idImage *image; + int size; +} sortedImage_t; + +/* +======================= +R_QsortImageSizes + +======================= +*/ +static int R_QsortImageSizes( const void *a, const void *b ) { + const sortedImage_t *ea, *eb; + + ea = (sortedImage_t *)a; + eb = (sortedImage_t *)b; + + if ( ea->size > eb->size ) { + return -1; + } + if ( ea->size < eb->size ) { + return 1; + } + return idStr::Icmp( ea->image->imgName, eb->image->imgName ); +} + +/* +=============== +R_ListImages_f +=============== +*/ +void R_ListImages_f( const idCmdArgs &args ) { + int i, j, partialSize; + idImage *image; + int totalSize; + int count = 0; + int matchTag = 0; + bool uncompressedOnly = false; + bool unloaded = false; + bool partial = false; + bool cached = false; + bool uncached = false; + bool failed = false; + bool touched = false; + bool sorted = false; + bool duplicated = false; + bool byClassification = false; + bool overSized = false; + + if ( args.Argc() == 1 ) { + + } else if ( args.Argc() == 2 ) { + if ( idStr::Icmp( args.Argv( 1 ), "uncompressed" ) == 0 ) { + uncompressedOnly = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "sorted" ) == 0 ) { + sorted = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "partial" ) == 0 ) { + partial = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "unloaded" ) == 0 ) { + unloaded = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "cached" ) == 0 ) { + cached = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "uncached" ) == 0 ) { + uncached = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "tagged" ) == 0 ) { + matchTag = 1; + } else if ( idStr::Icmp( args.Argv( 1 ), "duplicated" ) == 0 ) { + duplicated = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "touched" ) == 0 ) { + touched = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "classify" ) == 0 ) { + byClassification = true; + sorted = true; + } else if ( idStr::Icmp( args.Argv( 1 ), "oversized" ) == 0 ) { + byClassification = true; + sorted = true; + overSized = true; + } else { + failed = true; + } + } else { + failed = true; + } + + if ( failed ) { + common->Printf( "usage: listImages [ sorted | partial | unloaded | cached | uncached | tagged | duplicated | touched | classify | showOverSized ]\n" ); + return; + } + + const char *header = " -w-- -h-- filt -fmt-- wrap size --name-------\n"; + common->Printf( "\n%s", header ); + + totalSize = 0; + + sortedImage_t *sortedArray = (sortedImage_t *)alloca( sizeof( sortedImage_t ) * globalImages->images.Num() ); + + for ( i = 0 ; i < globalImages->images.Num() ; i++ ) { + image = globalImages->images[ i ]; + + if ( uncompressedOnly ) { + if ( ( image->internalFormat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT && image->internalFormat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) + || image->internalFormat == GL_COLOR_INDEX8_EXT ) { + continue; + } + } + + if ( matchTag && image->classification != matchTag ) { + continue; + } + if ( unloaded && image->texnum != idImage::TEXTURE_NOT_LOADED ) { + continue; + } + if ( partial && !image->isPartialImage ) { + continue; + } + if ( cached && ( !image->partialImage || image->texnum == idImage::TEXTURE_NOT_LOADED ) ) { + continue; + } + if ( uncached && ( !image->partialImage || image->texnum != idImage::TEXTURE_NOT_LOADED ) ) { + continue; + } + + // only print duplicates (from mismatched wrap / clamp, etc) + if ( duplicated ) { + int j; + for ( j = i+1 ; j < globalImages->images.Num() ; j++ ) { + if ( idStr::Icmp( image->imgName, globalImages->images[ j ]->imgName ) == 0 ) { + break; + } + } + if ( j == globalImages->images.Num() ) { + continue; + } + } + + // "listimages touched" will list only images bound since the last "listimages touched" call + if ( touched ) { + if ( image->bindCount == 0 ) { + continue; + } + image->bindCount = 0; + } + + if ( sorted ) { + sortedArray[count].image = image; + sortedArray[count].size = image->StorageSize(); + } else { + common->Printf( "%4i:", i ); + image->Print(); + } + totalSize += image->StorageSize(); + count++; + } + + if ( sorted ) { + qsort( sortedArray, count, sizeof( sortedImage_t ), R_QsortImageSizes ); + partialSize = 0; + for ( i = 0 ; i < count ; i++ ) { + common->Printf( "%4i:", i ); + sortedArray[i].image->Print(); + partialSize += sortedArray[i].image->StorageSize(); + if ( ( (i+1) % 10 ) == 0 ) { + common->Printf( "-------- %5.1f of %5.1f megs --------\n", + partialSize / (1024*1024.0), totalSize / (1024*1024.0) ); + } + } + } + + common->Printf( "%s", header ); + common->Printf( " %i images (%i total)\n", count, globalImages->images.Num() ); + common->Printf( " %5.1f total megabytes of images\n\n\n", totalSize / (1024*1024.0) ); + + if ( byClassification ) { + + idList< int > classifications[IC_COUNT]; + + for ( i = 0 ; i < count ; i++ ) { + int cl = ClassifyImage( sortedArray[i].image->imgName ); + classifications[ cl ].Append( i ); + } + + for ( i = 0; i < IC_COUNT; i++ ) { + partialSize = 0; + idList< int > overSizedList; + for ( j = 0; j < classifications[ i ].Num(); j++ ) { + partialSize += sortedArray[ classifications[ i ][ j ] ].image->StorageSize(); + if ( overSized ) { + if ( sortedArray[ classifications[ i ][ j ] ].image->uploadWidth > IC_Info[i].maxWidth && sortedArray[ classifications[ i ][ j ] ].image->uploadHeight > IC_Info[i].maxHeight ) { + overSizedList.Append( classifications[ i ][ j ] ); + } + } + } + common->Printf ( " Classification %s contains %i images using %5.1f megabytes\n", IC_Info[i].desc, classifications[i].Num(), partialSize / ( 1024*1024.0 ) ); + if ( overSized && overSizedList.Num() ) { + common->Printf( " The following images may be oversized\n" ); + for ( j = 0; j < overSizedList.Num(); j++ ) { + common->Printf( " " ); + sortedArray[ overSizedList[ j ] ].image->Print(); + common->Printf( "\n" ); + } + } + } + } + +} + +/* +================== +SetNormalPalette + +Create a 256 color palette to be used by compressed normal maps +================== +*/ +void idImageManager::SetNormalPalette( void ) { + int i, j; + idVec3 v; + float t; + //byte temptable[768]; + byte *temptable = compressedPalette; + int compressedToOriginal[16]; + + // make an ad-hoc separable compression mapping scheme + for ( i = 0 ; i < 8 ; i++ ) { + float f, y; + + f = ( i + 1 ) / 8.5; + y = idMath::Sqrt( 1.0 - f * f ); + y = 1.0 - y; + + compressedToOriginal[7-i] = 127 - (int)( y * 127 + 0.5 ); + compressedToOriginal[8+i] = 128 + (int)( y * 127 + 0.5 ); + } + + for ( i = 0 ; i < 256 ; i++ ) { + if ( i <= compressedToOriginal[0] ) { + originalToCompressed[i] = 0; + } else if ( i >= compressedToOriginal[15] ) { + originalToCompressed[i] = 15; + } else { + for ( j = 0 ; j < 14 ; j++ ) { + if ( i <= compressedToOriginal[j+1] ) { + break; + } + } + if ( i - compressedToOriginal[j] < compressedToOriginal[j+1] - i ) { + originalToCompressed[i] = j; + } else { + originalToCompressed[i] = j + 1; + } + } + } + +#if 0 + for ( i = 0; i < 16; i++ ) { + for ( j = 0 ; j < 16 ; j++ ) { + + v[0] = ( i - 7.5 ) / 8; + v[1] = ( j - 7.5 ) / 8; + + t = 1.0 - ( v[0]*v[0] + v[1]*v[1] ); + if ( t < 0 ) { + t = 0; + } + v[2] = idMath::Sqrt( t ); + + temptable[(i*16+j)*3+0] = 128 + floor( 127 * v[0] + 0.5 ); + temptable[(i*16+j)*3+1] = 128 + floor( 127 * v[1] ); + temptable[(i*16+j)*3+2] = 128 + floor( 127 * v[2] ); + } + } +#else + for ( i = 0; i < 16; i++ ) { + for ( j = 0 ; j < 16 ; j++ ) { + + v[0] = ( compressedToOriginal[i] - 127.5 ) / 128; + v[1] = ( compressedToOriginal[j] - 127.5 ) / 128; + + t = 1.0 - ( v[0]*v[0] + v[1]*v[1] ); + if ( t < 0 ) { + t = 0; + } + v[2] = idMath::Sqrt( t ); + + temptable[(i*16+j)*3+0] = (byte)(128 + floor( 127 * v[0] + 0.5 )); + temptable[(i*16+j)*3+1] = (byte)(128 + floor( 127 * v[1] )); + temptable[(i*16+j)*3+2] = (byte)(128 + floor( 127 * v[2] )); + } + } +#endif + + // color 255 will be the "nullnormal" color for no reflection + temptable[255*3+0] = + temptable[255*3+1] = + temptable[255*3+2] = 128; + + if ( !glConfig.sharedTexturePaletteAvailable ) { + return; + } + + qglColorTableEXT( GL_SHARED_TEXTURE_PALETTE_EXT, + GL_RGB, + 256, + GL_RGB, + GL_UNSIGNED_BYTE, + temptable ); + + qglEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); +} + +/* +============== +AllocImage + +Allocates an idImage, adds it to the list, +copies the name, and adds it to the hash chain. +============== +*/ +idImage *idImageManager::AllocImage( const char *name ) { + idImage *image; + int hash; + + if (strlen(name) >= MAX_IMAGE_NAME ) { + common->Error ("idImageManager::AllocImage: \"%s\" is too long\n", name); + } + + hash = idStr( name ).FileNameHash(); + + image = new idImage; + images.Append( image ); + + image->hashNext = imageHashTable[hash]; + imageHashTable[hash] = image; + + image->imgName = name; + + return image; +} + +/* +================== +ImageFromFunction + +Images that are procedurally generated are allways specified +with a callback which must work at any time, allowing the OpenGL +system to be completely regenerated if needed. +================== +*/ +idImage *idImageManager::ImageFromFunction( const char *_name, void (*generatorFunction)( idImage *image ) ) { + idStr name; + idImage *image; + int hash; + + if ( !name ) { + common->FatalError( "idImageManager::ImageFromFunction: NULL name" ); + } + + // strip any .tga file extensions from anywhere in the _name + name = _name; + name.Replace( ".tga", "" ); + name.BackSlashesToSlashes(); + + // see if the image already exists + hash = name.FileNameHash(); + for ( image = imageHashTable[hash] ; image; image = image->hashNext ) { + if ( name.Icmp( image->imgName ) == 0 ) { + if ( image->generatorFunction != generatorFunction ) { + common->DPrintf( "WARNING: reused image %s with mixed generators\n", name.c_str() ); + } + return image; + } + } + + // create the image and issue the callback + image = AllocImage( name ); + + image->generatorFunction = generatorFunction; + + if ( image_preload.GetBool() ) { + // check for precompressed, load is from the front end + image->referencedOutsideLevelLoad = true; + image->ActuallyLoadImage( true, false ); + } + + return image; +} + +/* +=============== +ImageFromFile + +Finds or loads the given image, always returning a valid image pointer. +Loading of the image may be deferred for dynamic loading. +============== +*/ +idImage *idImageManager::ImageFromFile( const char *_name, textureFilter_t filter, bool allowDownSize, + textureRepeat_t repeat, textureDepth_t depth, cubeFiles_t cubeMap ) { + idStr name; + idImage *image; + int hash; + + if ( !_name || !_name[0] || idStr::Icmp( _name, "default" ) == 0 || idStr::Icmp( _name, "_default" ) == 0 ) { + declManager->MediaPrint( "DEFAULTED\n" ); + return globalImages->defaultImage; + } + + // strip any .tga file extensions from anywhere in the _name, including image program parameters + name = _name; + name.Replace( ".tga", "" ); + name.BackSlashesToSlashes(); + + // + // see if the image is already loaded, unless we + // are in a reloadImages call + // + hash = name.FileNameHash(); + for ( image = imageHashTable[hash]; image; image = image->hashNext ) { + if ( name.Icmp( image->imgName ) == 0 ) { + // the built in's, like _white and _flat always match the other options + if ( name[0] == '_' ) { + return image; + } + if ( image->cubeFiles != cubeMap ) { + common->Error( "Image '%s' has been referenced with conflicting cube map states", _name ); + } + + if ( image->filter != filter || image->repeat != repeat ) { + // we might want to have the system reset these parameters on every bind and + // share the image data + continue; + } + + if ( image->allowDownSize == allowDownSize && image->depth == depth ) { + // note that it is used this level load + image->levelLoadReferenced = true; + if ( image->partialImage != NULL ) { + image->partialImage->levelLoadReferenced = true; + } + return image; + } + + // the same image is being requested, but with a different allowDownSize or depth + // so pick the highest of the two and reload the old image with those parameters + if ( !image->allowDownSize ) { + allowDownSize = false; + } + if ( image->depth > depth ) { + depth = image->depth; + } + if ( image->allowDownSize == allowDownSize && image->depth == depth ) { + // the already created one is already the highest quality + image->levelLoadReferenced = true; + if ( image->partialImage != NULL ) { + image->partialImage->levelLoadReferenced = true; + } + return image; + } + + image->allowDownSize = allowDownSize; + image->depth = depth; + image->levelLoadReferenced = true; + if ( image->partialImage != NULL ) { + image->partialImage->levelLoadReferenced = true; + } + if ( image_preload.GetBool() && !insideLevelLoad ) { + image->referencedOutsideLevelLoad = true; + image->ActuallyLoadImage( true, false ); // check for precompressed, load is from front end + declManager->MediaPrint( "%ix%i %s (reload for mixed referneces)\n", image->uploadWidth, image->uploadHeight, image->imgName.c_str() ); + } + return image; + } + } + + // + // create a new image + // + image = AllocImage( name ); + + // HACK: to allow keep fonts from being mip'd, as new ones will be introduced with localization + // this keeps us from having to make a material for each font tga + if ( name.Find( "fontImage_") >= 0 ) { + allowDownSize = false; + } + + image->allowDownSize = allowDownSize; + image->repeat = repeat; + image->depth = depth; + image->type = TT_2D; + image->cubeFiles = cubeMap; + image->filter = filter; + + image->levelLoadReferenced = true; + + // also create a shrunken version if we are going to dynamically cache the full size image + if ( image->ShouldImageBePartialCached() ) { + // if we only loaded part of the file, create a new idImage for the shrunken version + image->partialImage = new idImage; + + image->partialImage->allowDownSize = allowDownSize; + image->partialImage->repeat = repeat; + image->partialImage->depth = depth; + image->partialImage->type = TT_2D; + image->partialImage->cubeFiles = cubeMap; + image->partialImage->filter = filter; + + image->partialImage->levelLoadReferenced = true; + + // we don't bother hooking this into the hash table for lookup, but we do add it to the manager + // list for listImages + globalImages->images.Append( image->partialImage ); + image->partialImage->imgName = image->imgName; + image->partialImage->isPartialImage = true; + + // let the background file loader know that we can load + image->precompressedFile = true; + + if ( image_preload.GetBool() && !insideLevelLoad ) { + image->partialImage->ActuallyLoadImage( true, false ); // check for precompressed, load is from front end + declManager->MediaPrint( "%ix%i %s\n", image->partialImage->uploadWidth, image->partialImage->uploadHeight, image->imgName.c_str() ); + } else { + declManager->MediaPrint( "%s\n", image->imgName.c_str() ); + } + return image; + } + + // load it if we aren't in a level preload + if ( image_preload.GetBool() && !insideLevelLoad ) { + image->referencedOutsideLevelLoad = true; + image->ActuallyLoadImage( true, false ); // check for precompressed, load is from front end + declManager->MediaPrint( "%ix%i %s\n", image->uploadWidth, image->uploadHeight, image->imgName.c_str() ); + } else { + declManager->MediaPrint( "%s\n", image->imgName.c_str() ); + } + + return image; +} + +/* +=============== +idImageManager::GetImage +=============== +*/ +idImage *idImageManager::GetImage( const char *_name ) const { + idStr name; + idImage *image; + int hash; + + if ( !_name || !_name[0] || idStr::Icmp( _name, "default" ) == 0 || idStr::Icmp( _name, "_default" ) == 0 ) { + declManager->MediaPrint( "DEFAULTED\n" ); + return globalImages->defaultImage; + } + + // strip any .tga file extensions from anywhere in the _name, including image program parameters + name = _name; + name.Replace( ".tga", "" ); + name.BackSlashesToSlashes(); + + // + // look in loaded images + // + hash = name.FileNameHash(); + for ( image = imageHashTable[hash]; image; image = image->hashNext ) { + if ( name.Icmp( image->imgName ) == 0 ) { + return image; + } + } + + return NULL; +} + +/* +=============== +PurgeAllImages +=============== +*/ +void idImageManager::PurgeAllImages() { + int i; + idImage *image; + + for ( i = 0; i < images.Num() ; i++ ) { + image = images[i]; + image->PurgeImage(); + } +} + +/* +=============== +ReloadAllImages +=============== +*/ +void idImageManager::ReloadAllImages() { + idCmdArgs args; + + // build the compressed normal map palette + SetNormalPalette(); + + args.TokenizeString( "reloadImages reload", false ); + R_ReloadImages_f( args ); +} + +/* +=============== +R_CombineCubeImages_f + +Used to combine animations of six separate tga files into +a serials of 6x taller tga files, for preparation to roq compress +=============== +*/ +void R_CombineCubeImages_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Printf( "usage: combineCubeImages \n" ); + common->Printf( " combines basename[1-6][0001-9999].tga to basenameCM[0001-9999].tga\n" ); + common->Printf( " 1: forward 2:right 3:back 4:left 5:up 6:down\n" ); + return; + } + + idStr baseName = args.Argv( 1 ); + common->SetRefreshOnPrint( true ); + + for ( int frameNum = 1 ; frameNum < 10000 ; frameNum++ ) { + char filename[MAX_IMAGE_NAME]; + byte *pics[6]; + int width, height; + int side; + int orderRemap[6] = { 1,3,4,2,5,6 }; + for ( side = 0 ; side < 6 ; side++ ) { + sprintf( filename, "%s%i%04i.tga", baseName.c_str(), orderRemap[side], frameNum ); + + common->Printf( "reading %s\n", filename ); + R_LoadImage( filename, &pics[side], &width, &height, NULL, true ); + + if ( !pics[side] ) { + common->Printf( "not found.\n" ); + break; + } + + // convert from "camera" images to native cube map images + switch( side ) { + case 0: // forward + R_RotatePic( pics[side], width); + break; + case 1: // back + R_RotatePic( pics[side], width); + R_HorizontalFlip( pics[side], width, height ); + R_VerticalFlip( pics[side], width, height ); + break; + case 2: // left + R_VerticalFlip( pics[side], width, height ); + break; + case 3: // right + R_HorizontalFlip( pics[side], width, height ); + break; + case 4: // up + R_RotatePic( pics[side], width); + break; + case 5: // down + R_RotatePic( pics[side], width); + break; + } + } + + if ( side != 6 ) { + for ( int i = 0 ; i < side ; side++ ) { + Mem_Free( pics[side] ); + } + break; + } + + byte *combined = (byte *)Mem_Alloc( width*height*6*4 ); + for ( side = 0 ; side < 6 ; side++ ) { + memcpy( combined+width*height*4*side, pics[side], width*height*4 ); + Mem_Free( pics[side] ); + } + sprintf( filename, "%sCM%04i.tga", baseName.c_str(), frameNum ); + + common->Printf( "writing %s\n", filename ); + R_WriteTGA( filename, combined, width, height*6 ); + + Mem_Free( combined ); + } + common->SetRefreshOnPrint( false ); +} + + +/* +================== +idImage::StartBackgroundImageLoad +================== +*/ +void idImage::StartBackgroundImageLoad() { + if ( imageManager.numActiveBackgroundImageLoads >= idImageManager::MAX_BACKGROUND_IMAGE_LOADS ) { + return; + } + if ( globalImages->image_showBackgroundLoads.GetBool() ) { + common->Printf( "idImage::StartBackgroundImageLoad: %s\n", imgName.c_str() ); + } + backgroundLoadInProgress = true; + + if ( !precompressedFile ) { + common->Warning( "idImageManager::StartBackgroundImageLoad: %s wasn't a precompressed file", imgName.c_str() ); + return; + } + + bglNext = globalImages->backgroundImageLoads; + globalImages->backgroundImageLoads = this; + + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + + bgl.completed = false; + bgl.f = fileSystem->OpenFileRead( filename ); + if ( !bgl.f ) { + common->Warning( "idImageManager::StartBackgroundImageLoad: Couldn't load %s", imgName.c_str() ); + return; + } + bgl.file.position = 0; + bgl.file.length = bgl.f->Length(); + if ( bgl.file.length < sizeof( ddsFileHeader_t ) ) { + common->Warning( "idImageManager::StartBackgroundImageLoad: %s had a bad file length", imgName.c_str() ); + return; + } + + bgl.file.buffer = R_StaticAlloc( bgl.file.length ); + + fileSystem->BackgroundDownload( &bgl ); + + imageManager.numActiveBackgroundImageLoads++; + + // purge some images if necessary + int totalSize = 0; + for ( idImage *check = globalImages->cacheLRU.cacheUsageNext ; check != &globalImages->cacheLRU ; check = check->cacheUsageNext ) { + totalSize += check->StorageSize(); + } + int needed = this->StorageSize(); + + while ( ( totalSize + needed ) > globalImages->image_cacheMegs.GetFloat() * 1024 * 1024 ) { + // purge the least recently used + idImage *check = globalImages->cacheLRU.cacheUsagePrev; + if ( check->texnum != TEXTURE_NOT_LOADED ) { + totalSize -= check->StorageSize(); + if ( globalImages->image_showBackgroundLoads.GetBool() ) { + common->Printf( "purging %s\n", check->imgName.c_str() ); + } + check->PurgeImage(); + } + // remove it from the cached list + check->cacheUsageNext->cacheUsagePrev = check->cacheUsagePrev; + check->cacheUsagePrev->cacheUsageNext = check->cacheUsageNext; + check->cacheUsageNext = NULL; + check->cacheUsagePrev = NULL; + } +} + +/* +================== +R_CompleteBackgroundImageLoads + +Do we need to worry about vid_restarts here? +================== +*/ +void idImageManager::CompleteBackgroundImageLoads() { + idImage *remainingList = NULL; + idImage *next; + + for ( idImage *image = backgroundImageLoads ; image ; image = next ) { + next = image->bglNext; + if ( image->bgl.completed ) { + numActiveBackgroundImageLoads--; + fileSystem->CloseFile( image->bgl.f ); + // upload the image + image->UploadPrecompressedImage( (byte *)image->bgl.file.buffer, image->bgl.file.length ); + R_StaticFree( image->bgl.file.buffer ); + if ( image_showBackgroundLoads.GetBool() ) { + common->Printf( "R_CompleteBackgroundImageLoad: %s\n", image->imgName.c_str() ); + } + } else { + image->bglNext = remainingList; + remainingList = image; + } + } + if ( image_showBackgroundLoads.GetBool() ) { + static int prev; + if ( numActiveBackgroundImageLoads != prev ) { + prev = numActiveBackgroundImageLoads; + common->Printf( "background Loads: %i\n", numActiveBackgroundImageLoads ); + } + } + + backgroundImageLoads = remainingList; +} + +/* +=============== +CheckCvars +=============== +*/ +void idImageManager::CheckCvars() { + // textureFilter stuff + if ( image_filter.IsModified() || image_anisotropy.IsModified() || image_lodbias.IsModified() ) { + ChangeTextureFilter(); + image_filter.ClearModified(); + image_anisotropy.ClearModified(); + image_lodbias.ClearModified(); + } +} + +/* +=============== +SumOfUsedImages +=============== +*/ +int idImageManager::SumOfUsedImages() { + int total; + int i; + idImage *image; + + total = 0; + for ( i = 0; i < images.Num(); i++ ) { + image = images[i]; + if ( image->frameUsed == backEnd.frameCount ) { + total += image->StorageSize(); + } + } + + return total; +} + +/* +=============== +BindNull +=============== +*/ +void idImageManager::BindNull() { + tmu_t *tmu; + + tmu = &backEnd.glState.tmu[backEnd.glState.currenttmu]; + + RB_LogComment( "BindNull()\n" ); + if ( tmu->textureType == TT_CUBIC ) { + qglDisable( GL_TEXTURE_CUBE_MAP_EXT ); + } else if ( tmu->textureType == TT_3D ) { + qglDisable( GL_TEXTURE_3D ); + } else if ( tmu->textureType == TT_2D ) { + qglDisable( GL_TEXTURE_2D ); + } + tmu->textureType = TT_DISABLED; +} + +/* +=============== +Init +=============== +*/ +void idImageManager::Init() { + + memset(imageHashTable, 0, sizeof(imageHashTable)); + + images.Resize( 1024, 1024 ); + + // clear the cached LRU + cacheLRU.cacheUsageNext = &cacheLRU; + cacheLRU.cacheUsagePrev = &cacheLRU; + + // set default texture filter modes + ChangeTextureFilter(); + + // create built in images + defaultImage = ImageFromFunction( "_default", R_DefaultImage ); + whiteImage = ImageFromFunction( "_white", R_WhiteImage ); + blackImage = ImageFromFunction( "_black", R_BlackImage ); + borderClampImage = ImageFromFunction( "_borderClamp", R_BorderClampImage ); + flatNormalMap = ImageFromFunction( "_flat", R_FlatNormalImage ); + ambientNormalMap = ImageFromFunction( "_ambient", R_AmbientNormalImage ); + specularTableImage = ImageFromFunction( "_specularTable", R_SpecularTableImage ); + specular2DTableImage = ImageFromFunction( "_specular2DTable", R_Specular2DTableImage ); + rampImage = ImageFromFunction( "_ramp", R_RampImage ); + alphaRampImage = ImageFromFunction( "_alphaRamp", R_RampImage ); + alphaNotchImage = ImageFromFunction( "_alphaNotch", R_AlphaNotchImage ); + fogImage = ImageFromFunction( "_fog", R_FogImage ); + fogEnterImage = ImageFromFunction( "_fogEnter", R_FogEnterImage ); + normalCubeMapImage = ImageFromFunction( "_normalCubeMap", makeNormalizeVectorCubeMap ); + noFalloffImage = ImageFromFunction( "_noFalloff", R_CreateNoFalloffImage ); + ImageFromFunction( "_quadratic", R_QuadraticImage ); + + // cinematicImage is used for cinematic drawing + // scratchImage is used for screen wipes/doublevision etc.. + cinematicImage = ImageFromFunction("_cinematic", R_RGBA8Image ); + scratchImage = ImageFromFunction("_scratch", R_RGBA8Image ); + scratchImage2 = ImageFromFunction("_scratch2", R_RGBA8Image ); + accumImage = ImageFromFunction("_accum", R_RGBA8Image ); + scratchCubeMapImage = ImageFromFunction("_scratchCubeMap", makeNormalizeVectorCubeMap ); + currentRenderImage = ImageFromFunction("_currentRender", R_RGBA8Image ); + + cmdSystem->AddCommand( "reloadImages", R_ReloadImages_f, CMD_FL_RENDERER, "reloads images" ); + cmdSystem->AddCommand( "listImages", R_ListImages_f, CMD_FL_RENDERER, "lists images" ); + cmdSystem->AddCommand( "combineCubeImages", R_CombineCubeImages_f, CMD_FL_RENDERER, "combines six images for roq compression" ); + + // should forceLoadImages be here? +} + +/* +=============== +Shutdown +=============== +*/ +void idImageManager::Shutdown() { + images.DeleteContents( true ); +} + +/* +==================== +BeginLevelLoad + +Mark all file based images as currently unused, +but don't free anything. Calls to ImageFromFile() will +either mark the image as used, or create a new image without +loading the actual data. +==================== +*/ +void idImageManager::BeginLevelLoad() { + insideLevelLoad = true; + + for ( int i = 0 ; i < images.Num() ; i++ ) { + idImage *image = images[ i ]; + + // generator function images are always kept around + if ( image->generatorFunction ) { + continue; + } + + if ( com_purgeAll.GetBool() ) { + image->PurgeImage(); + } + + image->levelLoadReferenced = false; + } +} + +/* +==================== +EndLevelLoad + +Free all images marked as unused, and load all images that are necessary. +This architecture prevents us from having the union of two level's +worth of data present at one time. + +preload everything, never free +preload everything, free unused after level load +blocking load on demand +preload low mip levels, background load remainder on demand +==================== +*/ +void idImageManager::EndLevelLoad() { + int start = Sys_Milliseconds(); + + insideLevelLoad = false; + if ( idAsyncNetwork::serverDedicated.GetInteger() ) { + return; + } + + common->Printf( "----- idImageManager::EndLevelLoad -----\n" ); + + int purgeCount = 0; + int keepCount = 0; + int loadCount = 0; + + // purge the ones we don't need + for ( int i = 0 ; i < images.Num() ; i++ ) { + idImage *image = images[ i ]; + if ( image->generatorFunction ) { + continue; + } + + if ( !image->levelLoadReferenced && !image->referencedOutsideLevelLoad ) { +// common->Printf( "Purging %s\n", image->imgName.c_str() ); + purgeCount++; + image->PurgeImage(); + } else if ( image->texnum != idImage::TEXTURE_NOT_LOADED ) { +// common->Printf( "Keeping %s\n", image->imgName.c_str() ); + keepCount++; + } + } + + // load the ones we do need, if we are preloading + for ( int i = 0 ; i < images.Num() ; i++ ) { + idImage *image = images[ i ]; + if ( image->generatorFunction ) { + continue; + } + + if ( image->levelLoadReferenced && image->texnum == idImage::TEXTURE_NOT_LOADED && !image->partialImage ) { +// common->Printf( "Loading %s\n", image->imgName.c_str() ); + loadCount++; + image->ActuallyLoadImage( true, false ); + + if ( ( loadCount & 15 ) == 0 ) { + session->PacifierUpdate(); + } + } + } + + int end = Sys_Milliseconds(); + common->Printf( "%5i purged from previous\n", purgeCount ); + common->Printf( "%5i kept from previous\n", keepCount ); + common->Printf( "%5i new loaded\n", loadCount ); + common->Printf( "all images loaded in %5.1f seconds\n", (end-start) * 0.001 ); + common->Printf( "----------------------------------------\n" ); +} + +/* +=============== +idImageManager::StartBuild +=============== +*/ +void idImageManager::StartBuild() { + ddsList.Clear(); + ddsHash.Free(); +} + +/* +=============== +idImageManager::FinishBuild +=============== +*/ +void idImageManager::FinishBuild( bool removeDups ) { + idFile *batchFile; + if ( removeDups ) { + ddsList.Clear(); + char *buffer = NULL; + fileSystem->ReadFile( "makedds.bat", (void**)&buffer ); + if ( buffer ) { + idStr str = buffer; + while ( str.Length() ) { + int n = str.Find( '\n' ); + if ( n > 0 ) { + idStr line = str.Left( n + 1 ); + idStr right; + str.Right( str.Length() - n - 1, right ); + str = right; + ddsList.AddUnique( line ); + } else { + break; + } + } + } + } + batchFile = fileSystem->OpenFileWrite( ( removeDups ) ? "makedds2.bat" : "makedds.bat" ); + if ( batchFile ) { + int i; + int ddsNum = ddsList.Num(); + + for ( i = 0; i < ddsNum; i++ ) { + batchFile->WriteFloatString( "%s", ddsList[ i ].c_str() ); + batchFile->Printf( "@echo Finished compressing %d of %d. %.1f percent done.\n", i+1, ddsNum, ((float)(i+1)/(float)ddsNum)*100.f ); + } + fileSystem->CloseFile( batchFile ); + } + ddsList.Clear(); + ddsHash.Free(); +} + +/* +=============== +idImageManager::AddDDSCommand +=============== +*/ +void idImageManager::AddDDSCommand( const char *cmd ) { + int i, key; + + if ( !( cmd && *cmd ) ) { + return; + } + + key = ddsHash.GenerateKey( cmd, false ); + for ( i = ddsHash.First( key ); i != -1; i = ddsHash.Next( i ) ) { + if ( ddsList[i].Icmp( cmd ) == 0 ) { + break; + } + } + + if ( i == -1 ) { + ddsList.Append( cmd ); + } +} + +/* +=============== +idImageManager::PrintMemInfo +=============== +*/ +void idImageManager::PrintMemInfo( MemInfo_t *mi ) { + int i, j, total = 0; + int *sortIndex; + idFile *f; + + f = fileSystem->OpenFileWrite( mi->filebase + "_images.txt" ); + if ( !f ) { + return; + } + + // sort first + sortIndex = new int[images.Num()]; + + for ( i = 0; i < images.Num(); i++ ) { + sortIndex[i] = i; + } + + for ( i = 0; i < images.Num() - 1; i++ ) { + for ( j = i + 1; j < images.Num(); j++ ) { + if ( images[sortIndex[i]]->StorageSize() < images[sortIndex[j]]->StorageSize() ) { + int temp = sortIndex[i]; + sortIndex[i] = sortIndex[j]; + sortIndex[j] = temp; + } + } + } + + // print next + for ( i = 0; i < images.Num(); i++ ) { + idImage *im = images[sortIndex[i]]; + int size; + + size = im->StorageSize(); + total += size; + + f->Printf( "%s %3i %s\n", idStr::FormatNumber( size ).c_str(), im->refCount, im->imgName.c_str() ); + } + + delete sortIndex; + mi->imageAssetsTotal = total; + + f->Printf( "\nTotal image bytes allocated: %s\n", idStr::FormatNumber( total ).c_str() ); + fileSystem->CloseFile( f ); +} diff --git a/renderer/Image_load.cpp b/renderer/Image_load.cpp new file mode 100644 index 000000000..9c94439aa --- /dev/null +++ b/renderer/Image_load.cpp @@ -0,0 +1,2203 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +PROBLEM: compressed textures may break the zero clamp rule! +*/ + +static bool FormatIsDXT( int internalFormat ) { + if ( internalFormat < GL_COMPRESSED_RGB_S3TC_DXT1_EXT + || internalFormat > GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) { + return false; + } + return true; +} + +int MakePowerOfTwo( int num ) { + int pot; + for (pot = 1 ; pot < num ; pot<<=1) { + } + return pot; +} + +/* +================ +BitsForInternalFormat + +Used for determining memory utilization +================ +*/ +int idImage::BitsForInternalFormat( int internalFormat ) const { + switch ( internalFormat ) { + case GL_INTENSITY8: + case 1: + return 8; + case 2: + case GL_LUMINANCE8_ALPHA8: + return 16; + case 3: + return 32; // on some future hardware, this may actually be 24, but be conservative + case 4: + return 32; + case GL_LUMINANCE8: + return 8; + case GL_ALPHA8: + return 8; + case GL_RGBA8: + return 32; + case GL_RGB8: + return 32; // on some future hardware, this may actually be 24, but be conservative + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return 4; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return 4; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return 8; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return 8; + case GL_RGBA4: + return 16; + case GL_RGB5: + return 16; + case GL_COLOR_INDEX8_EXT: + return 8; + case GL_COLOR_INDEX: + return 8; + case GL_COMPRESSED_RGB_ARB: + return 4; // not sure + case GL_COMPRESSED_RGBA_ARB: + return 8; // not sure + default: + common->Error( "R_BitsForInternalFormat: BAD FORMAT:%i", internalFormat ); + } + return 0; +} + +/* +================== +UploadCompressedNormalMap + +Create a 256 color palette to be used by compressed normal maps +================== +*/ +void idImage::UploadCompressedNormalMap( int width, int height, const byte *rgba, int mipLevel ) { + byte *normals; + const byte *in; + byte *out; + int i, j; + int x, y, z; + int row; + + // OpenGL's pixel packing rule + row = width < 4 ? 4 : width; + + normals = (byte *)_alloca( row * height ); + if ( !normals ) { + common->Error( "R_UploadCompressedNormalMap: _alloca failed" ); + } + + in = rgba; + out = normals; + for ( i = 0 ; i < height ; i++, out += row, in += width * 4 ) { + for ( j = 0 ; j < width ; j++ ) { + x = in[ j * 4 + 0 ]; + y = in[ j * 4 + 1 ]; + z = in[ j * 4 + 2 ]; + + int c; + if ( x == 128 && y == 128 && z == 128 ) { + // the "nullnormal" color + c = 255; + } else { + c = ( globalImages->originalToCompressed[x] << 4 ) | globalImages->originalToCompressed[y]; + if ( c == 255 ) { + c = 254; // don't use the nullnormal color + } + } + out[j] = c; + } + } + + if ( mipLevel == 0 ) { + // Optionally write out the paletized normal map to a .tga + if ( globalImages->image_writeNormalTGAPalletized.GetBool() ) { + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + char *ext = strrchr(filename, '.'); + if ( ext ) { + strcpy(ext, "_pal.tga"); + R_WritePalTGA( filename, normals, globalImages->compressedPalette, width, height); + } + } + } + + if ( glConfig.sharedTexturePaletteAvailable ) { + qglTexImage2D( GL_TEXTURE_2D, + mipLevel, + GL_COLOR_INDEX8_EXT, + width, + height, + 0, + GL_COLOR_INDEX, + GL_UNSIGNED_BYTE, + normals ); + } +} + + +//======================================================================= + + +static byte mipBlendColors[16][4] = { + {0,0,0,0}, + {255,0,0,128}, + {0,255,0,128}, + {0,0,255,128}, + {255,0,0,128}, + {0,255,0,128}, + {0,0,255,128}, + {255,0,0,128}, + {0,255,0,128}, + {0,0,255,128}, + {255,0,0,128}, + {0,255,0,128}, + {0,0,255,128}, + {255,0,0,128}, + {0,255,0,128}, + {0,0,255,128}, +}; + +/* +=============== +SelectInternalFormat + +This may need to scan six cube map images +=============== +*/ +GLenum idImage::SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, int width, int height, + textureDepth_t minimumDepth, bool *monochromeResult ) const { + int i, c; + const byte *scan; + int rgbOr, rgbAnd, aOr, aAnd; + int rgbDiffer, rgbaDiffer; + + // determine if the rgb channels are all the same + // and if either all rgb or all alpha are 255 + c = width*height; + rgbDiffer = 0; + rgbaDiffer = 0; + rgbOr = 0; + rgbAnd = -1; + aOr = 0; + aAnd = -1; + + *monochromeResult = true; // until shown otherwise + + for ( int side = 0 ; side < numDataPtrs ; side++ ) { + scan = dataPtrs[side]; + for ( i = 0; i < c; i++, scan += 4 ) { + int cor, cand; + + aOr |= scan[3]; + aAnd &= scan[3]; + + cor = scan[0] | scan[1] | scan[2]; + cand = scan[0] & scan[1] & scan[2]; + + // if rgb are all the same, the or and and will match + rgbDiffer |= ( cor ^ cand ); + + // our "isMonochrome" test is more lax than rgbDiffer, + // allowing the values to be off by several units and + // still use the NV20 mono path + if ( *monochromeResult ) { + if ( abs( scan[0] - scan[1] ) > 16 + || abs( scan[0] - scan[2] ) > 16 ) { + *monochromeResult = false; + } + } + + rgbOr |= cor; + rgbAnd &= cand; + + cor |= scan[3]; + cand &= scan[3]; + + rgbaDiffer |= ( cor ^ cand ); + } + } + + // we assume that all 0 implies that the alpha channel isn't needed, + // because some tools will spit out 32 bit images with a 0 alpha instead + // of 255 alpha, but if the alpha actually is referenced, there will be + // different behavior in the compressed vs uncompressed states. + bool needAlpha; + if ( aAnd == 255 || aOr == 0 ) { + needAlpha = false; + } else { + needAlpha = true; + } + + // catch normal maps first + if ( minimumDepth == TD_BUMP ) { + if ( globalImages->image_useCompression.GetBool() && globalImages->image_useNormalCompression.GetInteger() == 1 && glConfig.sharedTexturePaletteAvailable ) { + // image_useNormalCompression should only be set to 1 on nv_10 and nv_20 paths + return GL_COLOR_INDEX8_EXT; + } else if ( globalImages->image_useCompression.GetBool() && globalImages->image_useNormalCompression.GetInteger() && glConfig.textureCompressionAvailable ) { + // image_useNormalCompression == 2 uses rxgb format which produces really good quality for medium settings + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } else { + // we always need the alpha channel for bump maps for swizzling + return GL_RGBA8; + } + } + + // allow a complete override of image compression with a cvar + if ( !globalImages->image_useCompression.GetBool() ) { + minimumDepth = TD_HIGH_QUALITY; + } + + if ( minimumDepth == TD_SPECULAR ) { + // we are assuming that any alpha channel is unintentional + if ( glConfig.textureCompressionAvailable ) { + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } else { + return GL_RGB5; + } + } + if ( minimumDepth == TD_DIFFUSE ) { + // we might intentionally have an alpha channel for alpha tested textures + if ( glConfig.textureCompressionAvailable ) { + if ( !needAlpha ) { + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } else { + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + } + } else if ( ( aAnd == 255 || aOr == 0 ) ) { + return GL_RGB5; + } else { + return GL_RGBA4; + } + } + + // there will probably be some drivers that don't + // correctly handle the intensity/alpha/luminance/luminance+alpha + // formats, so provide a fallback that only uses the rgb/rgba formats + if ( !globalImages->image_useAllFormats.GetBool() ) { + // pretend rgb is varying and inconsistant, which + // prevents any of the more compact forms + rgbDiffer = 1; + rgbaDiffer = 1; + rgbAnd = 0; + } + + // cases without alpha + if ( !needAlpha ) { + if ( minimumDepth == TD_HIGH_QUALITY ) { + return GL_RGB8; // four bytes + } + if ( glConfig.textureCompressionAvailable ) { + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // half byte + } + return GL_RGB5; // two bytes + } + + // cases with alpha + if ( !rgbaDiffer ) { + if ( minimumDepth != TD_HIGH_QUALITY && glConfig.textureCompressionAvailable ) { + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte + } + return GL_INTENSITY8; // single byte for all channels + } + +#if 0 + // we don't support alpha textures any more, because there + // is a discrepancy in the definition of TEX_ENV_COMBINE that + // causes them to be treated as 0 0 0 A, instead of 1 1 1 A as + // normal texture modulation treats them + if ( rgbAnd == 255 ) { + return GL_ALPHA8; // single byte, only alpha + } +#endif + + if ( minimumDepth == TD_HIGH_QUALITY ) { + return GL_RGBA8; // four bytes + } + if ( glConfig.textureCompressionAvailable ) { + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; // one byte + } + if ( !rgbDiffer ) { + return GL_LUMINANCE8_ALPHA8; // two bytes, max quality + } + return GL_RGBA4; // two bytes +} + +/* +================== +SetImageFilterAndRepeat +================== +*/ +void idImage::SetImageFilterAndRepeat() const { + // set the minimize / maximize filtering + switch( filter ) { + case TF_DEFAULT: + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, globalImages->textureMinFilter ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, globalImages->textureMaxFilter ); + break; + case TF_LINEAR: + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + break; + case TF_NEAREST: + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + break; + default: + common->FatalError( "R_CreateImage: bad texture filter" ); + } + + if ( glConfig.anisotropicAvailable ) { + // only do aniso filtering on mip mapped images + if ( filter == TF_DEFAULT ) { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, globalImages->textureAnisotropy ); + } else { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + } + } + if ( glConfig.textureLODBiasAvailable ) { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS_EXT, globalImages->textureLODBias ); + } + + // set the wrap/clamp modes + switch( repeat ) { + case TR_REPEAT: + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + break; + case TR_CLAMP_TO_BORDER: + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); + break; + case TR_CLAMP_TO_ZERO: + case TR_CLAMP_TO_ZERO_ALPHA: + case TR_CLAMP: + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + break; + default: + common->FatalError( "R_CreateImage: bad texture repeat" ); + } +} + +/* +================ +idImage::Downsize +helper function that takes the current width/height and might make them smaller +================ +*/ +void idImage::GetDownsize( int &scaled_width, int &scaled_height ) const { + int size = 0; + + // perform optional picmip operation to save texture memory + if ( depth == TD_SPECULAR && globalImages->image_downSizeSpecular.GetInteger() ) { + size = globalImages->image_downSizeSpecularLimit.GetInteger(); + if ( size == 0 ) { + size = 64; + } + } else if ( depth == TD_BUMP && globalImages->image_downSizeBump.GetInteger() ) { + size = globalImages->image_downSizeBumpLimit.GetInteger(); + if ( size == 0 ) { + size = 64; + } + } else if ( ( allowDownSize || globalImages->image_forceDownSize.GetBool() ) && globalImages->image_downSize.GetInteger() ) { + size = globalImages->image_downSizeLimit.GetInteger(); + if ( size == 0 ) { + size = 256; + } + } + + if ( size > 0 ) { + while ( scaled_width > size || scaled_height > size ) { + if ( scaled_width > 1 ) { + scaled_width >>= 1; + } + if ( scaled_height > 1 ) { + scaled_height >>= 1; + } + } + } + + // clamp to minimum size + if ( scaled_width < 1 ) { + scaled_width = 1; + } + if ( scaled_height < 1 ) { + scaled_height = 1; + } + + // clamp size to the hardware specific upper limit + // scale both axis down equally so we don't have to + // deal with a half mip resampling + // This causes a 512*256 texture to sample down to + // 256*128 on a voodoo3, even though it could be 256*256 + while ( scaled_width > glConfig.maxTextureSize + || scaled_height > glConfig.maxTextureSize ) { + scaled_width >>= 1; + scaled_height >>= 1; + } +} + +/* +================ +GenerateImage + +The alpha channel bytes should be 255 if you don't +want the channel. + +We need a material characteristic to ask for specific texture modes. + +Designed limitations of flexibility: + +No support for texture borders. + +No support for texture border color. + +No support for texture environment colors or GL_BLEND or GL_DECAL +texture environments, because the automatic optimization to single +or dual component textures makes those modes potentially undefined. + +No non-power-of-two images. + +No palettized textures. + +There is no way to specify separate wrap/clamp values for S and T + +There is no way to specify explicit mip map levels + +================ +*/ +void idImage::GenerateImage( const byte *pic, int width, int height, + textureFilter_t filterParm, bool allowDownSizeParm, + textureRepeat_t repeatParm, textureDepth_t depthParm ) { + bool preserveBorder; + byte *scaledBuffer; + int scaled_width, scaled_height; + byte *shrunk; + + PurgeImage(); + + filter = filterParm; + allowDownSize = allowDownSizeParm; + repeat = repeatParm; + depth = depthParm; + + // if we don't have a rendering context, just return after we + // have filled in the parms. We must have the values set, or + // an image match from a shader before OpenGL starts would miss + // the generated texture + if ( !glConfig.isInitialized ) { + return; + } + + // don't let mip mapping smear the texture into the clamped border + if ( repeat == TR_CLAMP_TO_ZERO ) { + preserveBorder = true; + } else { + preserveBorder = false; + } + + // make sure it is a power of 2 + scaled_width = MakePowerOfTwo( width ); + scaled_height = MakePowerOfTwo( height ); + + if ( scaled_width != width || scaled_height != height ) { + common->Error( "R_CreateImage: not a power of 2 image" ); + } + + // Optionally modify our width/height based on options/hardware + GetDownsize( scaled_width, scaled_height ); + + scaledBuffer = NULL; + + // generate the texture number + qglGenTextures( 1, &texnum ); + + // select proper internal format before we resample + internalFormat = SelectInternalFormat( &pic, 1, width, height, depth, &isMonochrome ); + + // copy or resample data as appropriate for first MIP level + if ( ( scaled_width == width ) && ( scaled_height == height ) ) { + // we must copy even if unchanged, because the border zeroing + // would otherwise modify const data + scaledBuffer = (byte *)R_StaticAlloc( sizeof( unsigned ) * scaled_width * scaled_height ); + memcpy (scaledBuffer, pic, width*height*4); + } else { + // resample down as needed (FIXME: this doesn't seem like it resamples anymore!) + // scaledBuffer = R_ResampleTexture( pic, width, height, width >>= 1, height >>= 1 ); + scaledBuffer = R_MipMap( pic, width, height, preserveBorder ); + width >>= 1; + height >>= 1; + if ( width < 1 ) { + width = 1; + } + if ( height < 1 ) { + height = 1; + } + + while ( width > scaled_width || height > scaled_height ) { + shrunk = R_MipMap( scaledBuffer, width, height, preserveBorder ); + R_StaticFree( scaledBuffer ); + scaledBuffer = shrunk; + + width >>= 1; + height >>= 1; + if ( width < 1 ) { + width = 1; + } + if ( height < 1 ) { + height = 1; + } + } + + // one might have shrunk down below the target size + scaled_width = width; + scaled_height = height; + } + + uploadHeight = scaled_height; + uploadWidth = scaled_width; + type = TT_2D; + + // zero the border if desired, allowing clamped projection textures + // even after picmip resampling or careless artists. + if ( repeat == TR_CLAMP_TO_ZERO ) { + byte rgba[4]; + + rgba[0] = rgba[1] = rgba[2] = 0; + rgba[3] = 255; + R_SetBorderTexels( (byte *)scaledBuffer, width, height, rgba ); + } + if ( repeat == TR_CLAMP_TO_ZERO_ALPHA ) { + byte rgba[4]; + + rgba[0] = rgba[1] = rgba[2] = 255; + rgba[3] = 0; + R_SetBorderTexels( (byte *)scaledBuffer, width, height, rgba ); + } + + if ( generatorFunction == NULL && ( depth == TD_BUMP && globalImages->image_writeNormalTGA.GetBool() || depth != TD_BUMP && globalImages->image_writeTGA.GetBool() ) ) { + // Optionally write out the texture to a .tga + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + char *ext = strrchr(filename, '.'); + if ( ext ) { + strcpy( ext, ".tga" ); + // swap the red/alpha for the write + /* + if ( depth == TD_BUMP ) { + for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) { + scaledBuffer[ i ] = scaledBuffer[ i + 3 ]; + scaledBuffer[ i + 3 ] = 0; + } + } + */ + R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height, false ); + + // put it back + /* + if ( depth == TD_BUMP ) { + for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) { + scaledBuffer[ i + 3 ] = scaledBuffer[ i ]; + scaledBuffer[ i ] = 0; + } + } + */ + } + } + + // swap the red and alpha for rxgb support + // do this even on tga normal maps so we only have to use + // one fragment program + // if the image is precompressed ( either in palletized mode or true rxgb mode ) + // then it is loaded above and the swap never happens here + if ( depth == TD_BUMP && globalImages->image_useNormalCompression.GetInteger() != 1 ) { + for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) { + scaledBuffer[ i + 3 ] = scaledBuffer[ i ]; + scaledBuffer[ i ] = 0; + } + } + // upload the main image level + Bind(); + + + if ( internalFormat == GL_COLOR_INDEX8_EXT ) { + /* + if ( depth == TD_BUMP ) { + for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) { + scaledBuffer[ i ] = scaledBuffer[ i + 3 ]; + scaledBuffer[ i + 3 ] = 0; + } + } + */ + UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, 0 ); + } else { + qglTexImage2D( GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer ); + } + + // create and upload the mip map levels, which we do in all cases, even if we don't think they are needed + int miplevel; + + miplevel = 0; + while ( scaled_width > 1 || scaled_height > 1 ) { + // preserve the border after mip map unless repeating + shrunk = R_MipMap( scaledBuffer, scaled_width, scaled_height, preserveBorder ); + R_StaticFree( scaledBuffer ); + scaledBuffer = shrunk; + + scaled_width >>= 1; + scaled_height >>= 1; + if ( scaled_width < 1 ) { + scaled_width = 1; + } + if ( scaled_height < 1 ) { + scaled_height = 1; + } + miplevel++; + + // this is a visualization tool that shades each mip map + // level with a different color so you can see the + // rasterizer's texture level selection algorithm + // Changing the color doesn't help with lumminance/alpha/intensity formats... + if ( depth == TD_DIFFUSE && globalImages->image_colorMipLevels.GetBool() ) { + R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] ); + } + + // upload the mip map + if ( internalFormat == GL_COLOR_INDEX8_EXT ) { + UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, miplevel ); + } else { + qglTexImage2D( GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer ); + } + } + + if ( scaledBuffer != 0 ) { + R_StaticFree( scaledBuffer ); + } + + SetImageFilterAndRepeat(); + + // see if we messed anything up + GL_CheckErrors(); +} + + +/* +================== +Generate3DImage +================== +*/ +void idImage::Generate3DImage( const byte *pic, int width, int height, int picDepth, + textureFilter_t filterParm, bool allowDownSizeParm, + textureRepeat_t repeatParm, textureDepth_t minDepthParm ) { + int scaled_width, scaled_height, scaled_depth; + + PurgeImage(); + + filter = filterParm; + allowDownSize = allowDownSizeParm; + repeat = repeatParm; + depth = minDepthParm; + + // if we don't have a rendering context, just return after we + // have filled in the parms. We must have the values set, or + // an image match from a shader before OpenGL starts would miss + // the generated texture + if ( !glConfig.isInitialized ) { + return; + } + + // make sure it is a power of 2 + scaled_width = MakePowerOfTwo( width ); + scaled_height = MakePowerOfTwo( height ); + scaled_depth = MakePowerOfTwo( picDepth ); + if ( scaled_width != width || scaled_height != height || scaled_depth != picDepth ) { + common->Error( "R_Create3DImage: not a power of 2 image" ); + } + + // FIXME: allow picmip here + + // generate the texture number + qglGenTextures( 1, &texnum ); + + // select proper internal format before we resample + // this function doesn't need to know it is 3D, so just make it very "tall" + internalFormat = SelectInternalFormat( &pic, 1, width, height * picDepth, minDepthParm, &isMonochrome ); + + uploadHeight = scaled_height; + uploadWidth = scaled_width; + uploadDepth = scaled_depth; + + + type = TT_3D; + + // upload the main image level + Bind(); + + qglTexImage3D(GL_TEXTURE_3D, 0, internalFormat, scaled_width, scaled_height, scaled_depth, + 0, GL_RGBA, GL_UNSIGNED_BYTE, pic ); + + // create and upload the mip map levels + int miplevel; + byte *scaledBuffer, *shrunk; + + scaledBuffer = (byte *)R_StaticAlloc( scaled_width * scaled_height * scaled_depth * 4 ); + memcpy( scaledBuffer, pic, scaled_width * scaled_height * scaled_depth * 4 ); + miplevel = 0; + while ( scaled_width > 1 || scaled_height > 1 || scaled_depth > 1 ) { + // preserve the border after mip map unless repeating + shrunk = R_MipMap3D( scaledBuffer, scaled_width, scaled_height, scaled_depth, + (bool)(repeat != TR_REPEAT) ); + R_StaticFree( scaledBuffer ); + scaledBuffer = shrunk; + + scaled_width >>= 1; + scaled_height >>= 1; + scaled_depth >>= 1; + if ( scaled_width < 1 ) { + scaled_width = 1; + } + if ( scaled_height < 1 ) { + scaled_height = 1; + } + if ( scaled_depth < 1 ) { + scaled_depth = 1; + } + miplevel++; + + // upload the mip map + qglTexImage3D(GL_TEXTURE_3D, miplevel, internalFormat, scaled_width, scaled_height, scaled_depth, + 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer ); + } + R_StaticFree( scaledBuffer ); + + // set the minimize / maximize filtering + switch( filter ) { + case TF_DEFAULT: + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, globalImages->textureMinFilter ); + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, globalImages->textureMaxFilter ); + break; + case TF_LINEAR: + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + break; + case TF_NEAREST: + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + break; + default: + common->FatalError( "R_CreateImage: bad texture filter" ); + } + + // set the wrap/clamp modes + switch( repeat ) { + case TR_REPEAT: + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT ); + break; + case TR_CLAMP_TO_BORDER: + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); + break; + case TR_CLAMP_TO_ZERO: + case TR_CLAMP_TO_ZERO_ALPHA: + case TR_CLAMP: + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + break; + default: + common->FatalError( "R_CreateImage: bad texture repeat" ); + } + + // see if we messed anything up + GL_CheckErrors(); +} + + +/* +==================== +GenerateCubeImage + +Non-square cube sides are not allowed +==================== +*/ +void idImage::GenerateCubeImage( const byte *pic[6], int size, + textureFilter_t filterParm, bool allowDownSizeParm, + textureDepth_t depthParm ) { + int scaled_width, scaled_height; + int width, height; + int i; + + PurgeImage(); + + filter = filterParm; + allowDownSize = allowDownSizeParm; + depth = depthParm; + + type = TT_CUBIC; + + // if we don't have a rendering context, just return after we + // have filled in the parms. We must have the values set, or + // an image match from a shader before OpenGL starts would miss + // the generated texture + if ( !glConfig.isInitialized ) { + return; + } + + if ( ! glConfig.cubeMapAvailable ) { + return; + } + + width = height = size; + + // generate the texture number + qglGenTextures( 1, &texnum ); + + // select proper internal format before we resample + internalFormat = SelectInternalFormat( pic, 6, width, height, depth, &isMonochrome ); + + // don't bother with downsample for now + scaled_width = width; + scaled_height = height; + + uploadHeight = scaled_height; + uploadWidth = scaled_width; + + Bind(); + + // no other clamp mode makes sense + qglTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // set the minimize / maximize filtering + switch( filter ) { + case TF_DEFAULT: + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, globalImages->textureMinFilter ); + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, globalImages->textureMaxFilter ); + break; + case TF_LINEAR: + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + break; + case TF_NEAREST: + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + break; + default: + common->FatalError( "R_CreateImage: bad texture filter" ); + } + + // upload the base level + // FIXME: support GL_COLOR_INDEX8_EXT? + for ( i = 0 ; i < 6 ; i++ ) { + qglTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT+i, 0, internalFormat, scaled_width, scaled_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pic[i] ); + } + + + // create and upload the mip map levels + int miplevel; + byte *shrunk[6]; + + for ( i = 0 ; i < 6 ; i++ ) { + shrunk[i] = R_MipMap( pic[i], scaled_width, scaled_height, false ); + } + + miplevel = 1; + while ( scaled_width > 1 ) { + for ( i = 0 ; i < 6 ; i++ ) { + byte *shrunken; + + qglTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT+i, miplevel, internalFormat, + scaled_width / 2, scaled_height / 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, shrunk[i] ); + + if ( scaled_width > 2 ) { + shrunken = R_MipMap( shrunk[i], scaled_width/2, scaled_height/2, false ); + } else { + shrunken = NULL; + } + + R_StaticFree( shrunk[i] ); + shrunk[i] = shrunken; + } + + scaled_width >>= 1; + scaled_height >>= 1; + miplevel++; + } + + // see if we messed anything up + GL_CheckErrors(); +} + + +/* +================ +ImageProgramStringToFileCompressedFileName +================ +*/ +void idImage::ImageProgramStringToCompressedFileName( const char *imageProg, char *fileName ) const { + const char *s; + char *f; + + strcpy( fileName, "dds/" ); + f = fileName + strlen( fileName ); + + int depth = 0; + + // convert all illegal characters to underscores + // this could conceivably produce a duplicated mapping, but we aren't going to worry about it + for ( s = imageProg ; *s ; s++ ) { + if ( *s == '/' || *s == '\\' || *s == '(') { + if ( depth < 4 ) { + *f = '/'; + depth ++; + } else { + *f = ' '; + } + f++; + } else if ( *s == '<' || *s == '>' || *s == ':' || *s == '|' || *s == '"' || *s == '.' ) { + *f = '_'; + f++; + } else if ( *s == ' ' && *(f-1) == '/' ) { // ignore a space right after a slash + } else if ( *s == ')' || *s == ',' ) { // always ignore these + } else { + *f = *s; + f++; + } + } + *f++ = 0; + strcat( fileName, ".dds" ); +} + +/* +================== +NumLevelsForImageSize +================== +*/ +int idImage::NumLevelsForImageSize( int width, int height ) const { + int numLevels = 1; + + while ( width > 1 || height > 1 ) { + numLevels++; + width >>= 1; + height >>= 1; + } + + return numLevels; +} + +/* +================ +WritePrecompressedImage + +When we are happy with our source data, we can write out precompressed +versions of everything to speed future load times. +================ +*/ +void idImage::WritePrecompressedImage() { + + // Always write the precompressed image if we're making a build + if ( !com_makingBuild.GetBool() ) { + if ( !globalImages->image_writePrecompressedTextures.GetBool() || !globalImages->image_usePrecompressedTextures.GetBool() ) { + return; + } + } + + if ( !glConfig.isInitialized ) { + return; + } + + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + + + + int numLevels = NumLevelsForImageSize( uploadWidth, uploadHeight ); + if ( numLevels > MAX_TEXTURE_LEVELS ) { + common->Warning( "R_WritePrecompressedImage: level > MAX_TEXTURE_LEVELS for image %s", filename ); + return; + } + + // glGetTexImage only supports a small subset of all the available internal formats + // We have to use BGRA because DDS is a windows based format + int altInternalFormat = 0; + int bitSize = 0; + switch ( internalFormat ) { + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX: + // this will not work with dds viewers but we need it in this format to save disk + // load speed ( i.e. size ) + altInternalFormat = GL_COLOR_INDEX; + bitSize = 24; + break; + case 1: + case GL_INTENSITY8: + case GL_LUMINANCE8: + case 3: + case GL_RGB8: + altInternalFormat = GL_BGR_EXT; + bitSize = 24; + break; + case GL_LUMINANCE8_ALPHA8: + case 4: + case GL_RGBA8: + altInternalFormat = GL_BGRA_EXT; + bitSize = 32; + break; + case GL_ALPHA8: + altInternalFormat = GL_ALPHA; + bitSize = 8; + break; + default: + if ( FormatIsDXT( internalFormat ) ) { + altInternalFormat = internalFormat; + } else { + common->Warning("Unknown or unsupported format for %s", filename); + return; + } + } + + if ( globalImages->image_useOffLineCompression.GetBool() && FormatIsDXT( altInternalFormat ) ) { + idStr outFile = fileSystem->RelativePathToOSPath( filename, "fs_basepath" ); + idStr inFile = outFile; + inFile.StripFileExtension(); + inFile.SetFileExtension( "tga" ); + idStr format; + if ( depth == TD_BUMP ) { + format = "RXGB +red 0.0 +green 0.5 +blue 0.5"; + } else { + switch ( altInternalFormat ) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + format = "DXT1"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + format = "DXT1 -alpha_threshold"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + format = "DXT3"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + format = "DXT5"; + break; + } + } + globalImages->AddDDSCommand( va( "z:/d3xp/compressonator/thecompressonator -convert \"%s\" \"%s\" %s -mipmaps\n", inFile.c_str(), outFile.c_str(), format.c_str() ) ); + return; + } + + + ddsFileHeader_t header; + memset( &header, 0, sizeof(header) ); + header.dwSize = sizeof(header); + header.dwFlags = DDSF_CAPS | DDSF_PIXELFORMAT | DDSF_WIDTH | DDSF_HEIGHT; + header.dwHeight = uploadHeight; + header.dwWidth = uploadWidth; + + // hack in our monochrome flag for the NV20 optimization + if ( isMonochrome ) { + header.dwFlags |= DDSF_ID_MONOCHROME; + } + + if ( FormatIsDXT( altInternalFormat ) ) { + // size (in bytes) of the compressed base image + header.dwFlags |= DDSF_LINEARSIZE; + header.dwPitchOrLinearSize = ( ( uploadWidth + 3 ) / 4 ) * ( ( uploadHeight + 3 ) / 4 )* + (altInternalFormat <= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16); + } + else { + // 4 Byte aligned line width (from nv_dds) + header.dwFlags |= DDSF_PITCH; + header.dwPitchOrLinearSize = ( ( uploadWidth * bitSize + 31 ) & -32 ) >> 3; + } + + header.dwCaps1 = DDSF_TEXTURE; + + if ( numLevels > 1 ) { + header.dwMipMapCount = numLevels; + header.dwFlags |= DDSF_MIPMAPCOUNT; + header.dwCaps1 |= DDSF_MIPMAP | DDSF_COMPLEX; + } + + header.ddspf.dwSize = sizeof(header.ddspf); + if ( FormatIsDXT( altInternalFormat ) ) { + header.ddspf.dwFlags = DDSF_FOURCC; + switch ( altInternalFormat ) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + header.ddspf.dwFourCC = DDS_MAKEFOURCC('D','X','T','1'); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + header.ddspf.dwFlags |= DDSF_ALPHAPIXELS; + header.ddspf.dwFourCC = DDS_MAKEFOURCC('D','X','T','1'); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + header.ddspf.dwFourCC = DDS_MAKEFOURCC('D','X','T','3'); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + header.ddspf.dwFourCC = DDS_MAKEFOURCC('D','X','T','5'); + break; + } + } else { + header.ddspf.dwFlags = ( internalFormat == GL_COLOR_INDEX8_EXT ) ? DDSF_RGB | DDSF_ID_INDEXCOLOR : DDSF_RGB; + header.ddspf.dwRGBBitCount = bitSize; + switch ( altInternalFormat ) { + case GL_BGRA_EXT: + case GL_LUMINANCE_ALPHA: + header.ddspf.dwFlags |= DDSF_ALPHAPIXELS; + header.ddspf.dwABitMask = 0xFF000000; + // Fall through + case GL_BGR_EXT: + case GL_LUMINANCE: + case GL_COLOR_INDEX: + header.ddspf.dwRBitMask = 0x00FF0000; + header.ddspf.dwGBitMask = 0x0000FF00; + header.ddspf.dwBBitMask = 0x000000FF; + break; + case GL_ALPHA: + header.ddspf.dwFlags = DDSF_ALPHAPIXELS; + header.ddspf.dwABitMask = 0xFF000000; + break; + default: + common->Warning( "Unknown or unsupported format for %s", filename ); + return; + } + } + + idFile *f = fileSystem->OpenFileWrite( filename ); + if ( f == NULL ) { + common->Warning( "Could not open %s trying to write precompressed image", filename ); + return; + } + common->Printf( "Writing precompressed image: %s\n", filename ); + + f->Write( "DDS ", 4 ); + f->Write( &header, sizeof(header) ); + + // bind to the image so we can read back the contents + Bind(); + + qglPixelStorei( GL_PACK_ALIGNMENT, 1 ); // otherwise small rows get padded to 32 bits + + int uw = uploadWidth; + int uh = uploadHeight; + + // Will be allocated first time through the loop + byte *data = NULL; + + for ( int level = 0 ; level < numLevels ; level++ ) { + + int size = 0; + if ( FormatIsDXT( altInternalFormat ) ) { + size = ( ( uw + 3 ) / 4 ) * ( ( uh + 3 ) / 4 ) * + (altInternalFormat <= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16); + } else { + size = uw * uh * (bitSize / 8); + } + + if (data == NULL) { + data = (byte *)R_StaticAlloc( size ); + } + + if ( FormatIsDXT( altInternalFormat ) ) { + qglGetCompressedTexImageARB( GL_TEXTURE_2D, level, data ); + } else { + qglGetTexImage( GL_TEXTURE_2D, level, altInternalFormat, GL_UNSIGNED_BYTE, data ); + } + + f->Write( data, size ); + + uw /= 2; + uh /= 2; + if (uw < 1) { + uw = 1; + } + if (uh < 1) { + uh = 1; + } + } + + if (data != NULL) { + R_StaticFree( data ); + } + + fileSystem->CloseFile( f ); +} + +/* +================ +ShouldImageBePartialCached + +Returns true if there is a precompressed image, and it is large enough +to be worth caching +================ +*/ +bool idImage::ShouldImageBePartialCached() { + if ( !glConfig.textureCompressionAvailable ) { + return false; + } + + if ( !globalImages->image_useCache.GetBool() ) { + return false; + } + + // the allowDownSize flag does double-duty as don't-partial-load + if ( !allowDownSize ) { + return false; + } + + if ( globalImages->image_cacheMinK.GetInteger() <= 0 ) { + return false; + } + + // if we are doing a copyFiles, make sure the original images are referenced + if ( fileSystem->PerformingCopyFiles() ) { + return false; + } + + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + + // get the file timestamp + fileSystem->ReadFile( filename, NULL, ×tamp ); + + if ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) { + return false; + } + + // open it and get the file size + idFile *f; + + f = fileSystem->OpenFileRead( filename ); + if ( !f ) { + return false; + } + + int len = f->Length(); + fileSystem->CloseFile( f ); + + if ( len <= globalImages->image_cacheMinK.GetInteger() * 1024 ) { + return false; + } + + // we do want to do a partial load + return true; +} + +/* +================ +CheckPrecompressedImage + +If fullLoad is false, only the small mip levels of the image will be loaded +================ +*/ +bool idImage::CheckPrecompressedImage( bool fullLoad ) { + if ( !glConfig.isInitialized || !glConfig.textureCompressionAvailable ) { + return false; + } + +#if 1 // ( _D3XP had disabled ) - Allow grabbing of DDS's from original Doom pak files + // if we are doing a copyFiles, make sure the original images are referenced + if ( fileSystem->PerformingCopyFiles() ) { + return false; + } +#endif + + if ( depth == TD_BUMP && globalImages->image_useNormalCompression.GetInteger() != 2 ) { + return false; + } + + // god i love last minute hacks :-) + if ( com_machineSpec.GetInteger() >= 1 && com_videoRam.GetInteger() >= 128 && imgName.Icmpn( "lights/", 7 ) == 0 ) { + return false; + } + + char filename[MAX_IMAGE_NAME]; + ImageProgramStringToCompressedFileName( imgName, filename ); + + // get the file timestamp + ID_TIME_T precompTimestamp; + fileSystem->ReadFile( filename, NULL, &precompTimestamp ); + + + if ( precompTimestamp == FILE_NOT_FOUND_TIMESTAMP ) { + return false; + } + + if ( !generatorFunction && timestamp != FILE_NOT_FOUND_TIMESTAMP ) { + if ( precompTimestamp < timestamp ) { + // The image has changed after being precompressed + return false; + } + } + + timestamp = precompTimestamp; + + // open it and just read the header + idFile *f; + + f = fileSystem->OpenFileRead( filename ); + if ( !f ) { + return false; + } + + int len = f->Length(); + if ( len < sizeof( ddsFileHeader_t ) ) { + fileSystem->CloseFile( f ); + return false; + } + + if ( !fullLoad && len > globalImages->image_cacheMinK.GetInteger() * 1024 ) { + len = globalImages->image_cacheMinK.GetInteger() * 1024; + } + + byte *data = (byte *)R_StaticAlloc( len ); + + f->Read( data, len ); + + fileSystem->CloseFile( f ); + + unsigned long magic = LittleLong( *(unsigned long *)data ); + ddsFileHeader_t *_header = (ddsFileHeader_t *)(data + 4); + int ddspf_dwFlags = LittleLong( _header->ddspf.dwFlags ); + + if ( magic != DDS_MAKEFOURCC('D', 'D', 'S', ' ')) { + common->Printf( "CheckPrecompressedImage( %s ): magic != 'DDS '\n", imgName.c_str() ); + R_StaticFree( data ); + return false; + } + + // if we don't support color index textures, we must load the full image + // should we just expand the 256 color image to 32 bit for upload? + if ( ddspf_dwFlags & DDSF_ID_INDEXCOLOR && !glConfig.sharedTexturePaletteAvailable ) { + R_StaticFree( data ); + return false; + } + + // upload all the levels + UploadPrecompressedImage( data, len ); + + R_StaticFree( data ); + + return true; +} + +/* +=================== +UploadPrecompressedImage + +This can be called by the front end during nromal loading, +or by the backend after a background read of the file +has completed +=================== +*/ +void idImage::UploadPrecompressedImage( byte *data, int len ) { + ddsFileHeader_t *header = (ddsFileHeader_t *)(data + 4); + + // ( not byte swapping dwReserved1 dwReserved2 ) + header->dwSize = LittleLong( header->dwSize ); + header->dwFlags = LittleLong( header->dwFlags ); + header->dwHeight = LittleLong( header->dwHeight ); + header->dwWidth = LittleLong( header->dwWidth ); + header->dwPitchOrLinearSize = LittleLong( header->dwPitchOrLinearSize ); + header->dwDepth = LittleLong( header->dwDepth ); + header->dwMipMapCount = LittleLong( header->dwMipMapCount ); + header->dwCaps1 = LittleLong( header->dwCaps1 ); + header->dwCaps2 = LittleLong( header->dwCaps2 ); + + header->ddspf.dwSize = LittleLong( header->ddspf.dwSize ); + header->ddspf.dwFlags = LittleLong( header->ddspf.dwFlags ); + header->ddspf.dwFourCC = LittleLong( header->ddspf.dwFourCC ); + header->ddspf.dwRGBBitCount = LittleLong( header->ddspf.dwRGBBitCount ); + header->ddspf.dwRBitMask = LittleLong( header->ddspf.dwRBitMask ); + header->ddspf.dwGBitMask = LittleLong( header->ddspf.dwGBitMask ); + header->ddspf.dwBBitMask = LittleLong( header->ddspf.dwBBitMask ); + header->ddspf.dwABitMask = LittleLong( header->ddspf.dwABitMask ); + + // generate the texture number + qglGenTextures( 1, &texnum ); + + int externalFormat = 0; + + precompressedFile = true; + + uploadWidth = header->dwWidth; + uploadHeight = header->dwHeight; + if ( header->ddspf.dwFlags & DDSF_FOURCC ) { + switch ( header->ddspf.dwFourCC ) { + case DDS_MAKEFOURCC( 'D', 'X', 'T', '1' ): + if ( header->ddspf.dwFlags & DDSF_ALPHAPIXELS ) { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + } else { + internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } + break; + case DDS_MAKEFOURCC( 'D', 'X', 'T', '3' ): + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case DDS_MAKEFOURCC( 'D', 'X', 'T', '5' ): + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case DDS_MAKEFOURCC( 'R', 'X', 'G', 'B' ): + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + default: + common->Warning( "Invalid compressed internal format\n" ); + return; + } + } else if ( ( header->ddspf.dwFlags & DDSF_RGBA ) && header->ddspf.dwRGBBitCount == 32 ) { + externalFormat = GL_BGRA_EXT; + internalFormat = GL_RGBA8; + } else if ( ( header->ddspf.dwFlags & DDSF_RGB ) && header->ddspf.dwRGBBitCount == 32 ) { + externalFormat = GL_BGRA_EXT; + internalFormat = GL_RGBA8; + } else if ( ( header->ddspf.dwFlags & DDSF_RGB ) && header->ddspf.dwRGBBitCount == 24 ) { + if ( header->ddspf.dwFlags & DDSF_ID_INDEXCOLOR ) { + externalFormat = GL_COLOR_INDEX; + internalFormat = GL_COLOR_INDEX8_EXT; + } else { + externalFormat = GL_BGR_EXT; + internalFormat = GL_RGB8; + } + } else if ( header->ddspf.dwRGBBitCount == 8 ) { + externalFormat = GL_ALPHA; + internalFormat = GL_ALPHA8; + } else { + common->Warning( "Invalid uncompressed internal format\n" ); + return; + } + + // we need the monochrome flag for the NV20 optimized path + if ( header->dwFlags & DDSF_ID_MONOCHROME ) { + isMonochrome = true; + } + + type = TT_2D; // FIXME: we may want to support pre-compressed cube maps in the future + + Bind(); + + int numMipmaps = 1; + if ( header->dwFlags & DDSF_MIPMAPCOUNT ) { + numMipmaps = header->dwMipMapCount; + } + + int uw = uploadWidth; + int uh = uploadHeight; + + // We may skip some mip maps if we are downsizing + int skipMip = 0; + GetDownsize( uploadWidth, uploadHeight ); + + byte *imagedata = data + sizeof(ddsFileHeader_t) + 4; + + for ( int i = 0 ; i < numMipmaps; i++ ) { + int size = 0; + if ( FormatIsDXT( internalFormat ) ) { + size = ( ( uw + 3 ) / 4 ) * ( ( uh + 3 ) / 4 ) * + (internalFormat <= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16); + } else { + size = uw * uh * (header->ddspf.dwRGBBitCount / 8); + } + + if ( uw > uploadWidth || uh > uploadHeight ) { + skipMip++; + } else { + if ( FormatIsDXT( internalFormat ) ) { + qglCompressedTexImage2DARB( GL_TEXTURE_2D, i - skipMip, internalFormat, uw, uh, 0, size, imagedata ); + } else { + qglTexImage2D( GL_TEXTURE_2D, i - skipMip, internalFormat, uw, uh, 0, externalFormat, GL_UNSIGNED_BYTE, imagedata ); + } + } + + imagedata += size; + uw /= 2; + uh /= 2; + if (uw < 1) { + uw = 1; + } + if (uh < 1) { + uh = 1; + } + } + + SetImageFilterAndRepeat(); +} + +/* +=============== +ActuallyLoadImage + +Absolutely every image goes through this path +On exit, the idImage will have a valid OpenGL texture number that can be bound +=============== +*/ +void idImage::ActuallyLoadImage( bool checkForPrecompressed, bool fromBackEnd ) { + int width, height; + byte *pic; + + // this is the ONLY place generatorFunction will ever be called + if ( generatorFunction ) { + generatorFunction( this ); + return; + } + + // if we are a partial image, we are only going to load from a compressed file + if ( isPartialImage ) { + if ( CheckPrecompressedImage( false ) ) { + return; + } + // this is an error -- the partial image failed to load + MakeDefault(); + return; + } + + // + // load the image from disk + // + if ( cubeFiles != CF_2D ) { + byte *pics[6]; + + // we don't check for pre-compressed cube images currently + R_LoadCubeImages( imgName, cubeFiles, pics, &width, ×tamp ); + + if ( pics[0] == NULL ) { + common->Warning( "Couldn't load cube image: %s", imgName.c_str() ); + MakeDefault(); + return; + } + + GenerateCubeImage( (const byte **)pics, width, filter, allowDownSize, depth ); + precompressedFile = false; + + for ( int i = 0 ; i < 6 ; i++ ) { + if ( pics[i] ) { + R_StaticFree( pics[i] ); + } + } + } else { + // see if we have a pre-generated image file that is + // already image processed and compressed + if ( checkForPrecompressed && globalImages->image_usePrecompressedTextures.GetBool() ) { + if ( CheckPrecompressedImage( true ) ) { + // we got the precompressed image + return; + } + // fall through to load the normal image + } + + R_LoadImageProgram( imgName, &pic, &width, &height, ×tamp, &depth ); + + if ( pic == NULL ) { + common->Warning( "Couldn't load image: %s", imgName.c_str() ); + MakeDefault(); + return; + } +/* + // swap the red and alpha for rxgb support + // do this even on tga normal maps so we only have to use + // one fragment program + // if the image is precompressed ( either in palletized mode or true rxgb mode ) + // then it is loaded above and the swap never happens here + if ( depth == TD_BUMP && globalImages->image_useNormalCompression.GetInteger() != 1 ) { + for ( int i = 0; i < width * height * 4; i += 4 ) { + pic[ i + 3 ] = pic[ i ]; + pic[ i ] = 0; + } + } +*/ + // build a hash for checking duplicate image files + // NOTE: takes about 10% of image load times (SD) + // may not be strictly necessary, but some code uses it, so let's leave it in + imageHash = MD4_BlockChecksum( pic, width * height * 4 ); + + GenerateImage( pic, width, height, filter, allowDownSize, repeat, depth ); + timestamp = timestamp; + precompressedFile = false; + + R_StaticFree( pic ); + + // write out the precompressed version of this file if needed + WritePrecompressedImage(); + } +} + +//========================================================================================================= + +/* +=============== +PurgeImage +=============== +*/ +void idImage::PurgeImage() { + if ( texnum != TEXTURE_NOT_LOADED ) { + // sometimes is NULL when exiting with an error + if ( qglDeleteTextures ) { + qglDeleteTextures( 1, &texnum ); // this should be the ONLY place it is ever called! + } + texnum = TEXTURE_NOT_LOADED; + } + + // clear all the current binding caches, so the next bind will do a real one + for ( int i = 0 ; i < MAX_MULTITEXTURE_UNITS ; i++ ) { + backEnd.glState.tmu[i].current2DMap = -1; + backEnd.glState.tmu[i].current3DMap = -1; + backEnd.glState.tmu[i].currentCubeMap = -1; + } +} + +/* +============== +Bind + +Automatically enables 2D mapping, cube mapping, or 3D texturing if needed +============== +*/ +void idImage::Bind() { + if ( tr.logFile ) { + RB_LogComment( "idImage::Bind( %s )\n", imgName.c_str() ); + } + + // if this is an image that we are caching, move it to the front of the LRU chain + if ( partialImage ) { + if ( cacheUsageNext ) { + // unlink from old position + cacheUsageNext->cacheUsagePrev = cacheUsagePrev; + cacheUsagePrev->cacheUsageNext = cacheUsageNext; + } + // link in at the head of the list + cacheUsageNext = globalImages->cacheLRU.cacheUsageNext; + cacheUsagePrev = &globalImages->cacheLRU; + + cacheUsageNext->cacheUsagePrev = this; + cacheUsagePrev->cacheUsageNext = this; + } + + // load the image if necessary (FIXME: not SMP safe!) + if ( texnum == TEXTURE_NOT_LOADED ) { + if ( partialImage ) { + // if we have a partial image, go ahead and use that + this->partialImage->Bind(); + + // start a background load of the full thing if it isn't already in the queue + if ( !backgroundLoadInProgress ) { + StartBackgroundImageLoad(); + } + return; + } + + // load the image on demand here, which isn't our normal game operating mode + ActuallyLoadImage( true, true ); // check for precompressed, load is from back end + } + + + // bump our statistic counters + frameUsed = backEnd.frameCount; + bindCount++; + + tmu_t *tmu = &backEnd.glState.tmu[backEnd.glState.currenttmu]; + + // enable or disable apropriate texture modes + if ( tmu->textureType != type && ( backEnd.glState.currenttmu < glConfig.maxTextureUnits ) ) { + if ( tmu->textureType == TT_CUBIC ) { + qglDisable( GL_TEXTURE_CUBE_MAP_EXT ); + } else if ( tmu->textureType == TT_3D ) { + qglDisable( GL_TEXTURE_3D ); + } else if ( tmu->textureType == TT_2D ) { + qglDisable( GL_TEXTURE_2D ); + } + + if ( type == TT_CUBIC ) { + qglEnable( GL_TEXTURE_CUBE_MAP_EXT ); + } else if ( type == TT_3D ) { + qglEnable( GL_TEXTURE_3D ); + } else if ( type == TT_2D ) { + qglEnable( GL_TEXTURE_2D ); + } + tmu->textureType = type; + } + + // bind the texture + if ( type == TT_2D ) { + if ( tmu->current2DMap != texnum ) { + tmu->current2DMap = texnum; + qglBindTexture( GL_TEXTURE_2D, texnum ); + } + } else if ( type == TT_CUBIC ) { + if ( tmu->currentCubeMap != texnum ) { + tmu->currentCubeMap = texnum; + qglBindTexture( GL_TEXTURE_CUBE_MAP_EXT, texnum ); + } + } else if ( type == TT_3D ) { + if ( tmu->current3DMap != texnum ) { + tmu->current3DMap = texnum; + qglBindTexture( GL_TEXTURE_3D, texnum ); + } + } + + if ( com_purgeAll.GetBool() ) { + GLclampf priority = 1.0f; + qglPrioritizeTextures( 1, &texnum, &priority ); + } +} + +/* +============== +BindFragment + +Fragment programs explicitly say which type of map they want, so we don't need to +do any enable / disable changes +============== +*/ +void idImage::BindFragment() { + if ( tr.logFile ) { + RB_LogComment( "idImage::BindFragment %s )\n", imgName.c_str() ); + } + + // if this is an image that we are caching, move it to the front of the LRU chain + if ( partialImage ) { + if ( cacheUsageNext ) { + // unlink from old position + cacheUsageNext->cacheUsagePrev = cacheUsagePrev; + cacheUsagePrev->cacheUsageNext = cacheUsageNext; + } + // link in at the head of the list + cacheUsageNext = globalImages->cacheLRU.cacheUsageNext; + cacheUsagePrev = &globalImages->cacheLRU; + + cacheUsageNext->cacheUsagePrev = this; + cacheUsagePrev->cacheUsageNext = this; + } + + // load the image if necessary (FIXME: not SMP safe!) + if ( texnum == TEXTURE_NOT_LOADED ) { + if ( partialImage ) { + // if we have a partial image, go ahead and use that + this->partialImage->BindFragment(); + + // start a background load of the full thing if it isn't already in the queue + if ( !backgroundLoadInProgress ) { + StartBackgroundImageLoad(); + } + return; + } + + // load the image on demand here, which isn't our normal game operating mode + ActuallyLoadImage( true, true ); // check for precompressed, load is from back end + } + + + // bump our statistic counters + frameUsed = backEnd.frameCount; + bindCount++; + + // bind the texture + if ( type == TT_2D ) { + qglBindTexture( GL_TEXTURE_2D, texnum ); + } else if ( type == TT_RECT ) { + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, texnum ); + } else if ( type == TT_CUBIC ) { + qglBindTexture( GL_TEXTURE_CUBE_MAP_EXT, texnum ); + } else if ( type == TT_3D ) { + qglBindTexture( GL_TEXTURE_3D, texnum ); + } +} + + +/* +==================== +CopyFramebuffer +==================== +*/ +void idImage::CopyFramebuffer( int x, int y, int imageWidth, int imageHeight, bool useOversizedBuffer ) { + Bind(); + + if ( cvarSystem->GetCVarBool( "g_lowresFullscreenFX" ) ) { + imageWidth = 512; + imageHeight = 512; + } + + // if the size isn't a power of 2, the image must be increased in size + int potWidth, potHeight; + + potWidth = MakePowerOfTwo( imageWidth ); + potHeight = MakePowerOfTwo( imageHeight ); + + GetDownsize( imageWidth, imageHeight ); + GetDownsize( potWidth, potHeight ); + + qglReadBuffer( GL_BACK ); + + // only resize if the current dimensions can't hold it at all, + // otherwise subview renderings could thrash this + if ( ( useOversizedBuffer && ( uploadWidth < potWidth || uploadHeight < potHeight ) ) + || ( !useOversizedBuffer && ( uploadWidth != potWidth || uploadHeight != potHeight ) ) ) { + uploadWidth = potWidth; + uploadHeight = potHeight; + if ( potWidth == imageWidth && potHeight == imageHeight ) { + qglCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, x, y, imageWidth, imageHeight, 0 ); + } else { + byte *junk; + // we need to create a dummy image with power of two dimensions, + // then do a qglCopyTexSubImage2D of the data we want + // this might be a 16+ meg allocation, which could fail on _alloca + junk = (byte *)Mem_Alloc( potWidth * potHeight * 4 ); + memset( junk, 0, potWidth * potHeight * 4 ); //!@# +#if 0 // Disabling because it's unnecessary and introduces a green strip on edge of _currentRender + for ( int i = 0 ; i < potWidth * potHeight * 4 ; i+=4 ) { + junk[i+1] = 255; + } +#endif + qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, junk ); + Mem_Free( junk ); + + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, x, y, imageWidth, imageHeight ); + } + } else { + // otherwise, just subimage upload it so that drivers can tell we are going to be changing + // it and don't try and do a texture compression or some other silliness + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, x, y, imageWidth, imageHeight ); + } + + // if the image isn't a full power of two, duplicate an extra row and/or column to fix bilerps + if ( imageWidth != potWidth ) { + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, imageWidth, 0, x+imageWidth-1, y, 1, imageHeight ); + } + if ( imageHeight != potHeight ) { + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, imageHeight, x, y+imageHeight-1, imageWidth, 1 ); + } + + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + backEnd.c_copyFrameBuffer++; +} + +/* +==================== +CopyDepthbuffer + +This should just be part of copyFramebuffer once we have a proper image type field +==================== +*/ +void idImage::CopyDepthbuffer( int x, int y, int imageWidth, int imageHeight ) { + Bind(); + + // if the size isn't a power of 2, the image must be increased in size + int potWidth, potHeight; + + potWidth = MakePowerOfTwo( imageWidth ); + potHeight = MakePowerOfTwo( imageHeight ); + + if ( uploadWidth != potWidth || uploadHeight != potHeight ) { + uploadWidth = potWidth; + uploadHeight = potHeight; + if ( potWidth == imageWidth && potHeight == imageHeight ) { + qglCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, x, y, imageWidth, imageHeight, 0 ); + } else { + // we need to create a dummy image with power of two dimensions, + // then do a qglCopyTexSubImage2D of the data we want + qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, potWidth, potHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL ); + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, x, y, imageWidth, imageHeight ); + } + } else { + // otherwise, just subimage upload it so that drivers can tell we are going to be changing + // it and don't try and do a texture compression or some other silliness + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, x, y, imageWidth, imageHeight ); + } + +// qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); +// qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); +} + +/* +============= +RB_UploadScratchImage + +if rows = cols * 6, assume it is a cube map animation +============= +*/ +void idImage::UploadScratch( const byte *data, int cols, int rows ) { + int i; + + // if rows = cols * 6, assume it is a cube map animation + if ( rows == cols * 6 ) { + if ( type != TT_CUBIC ) { + type = TT_CUBIC; + uploadWidth = -1; // for a non-sub upload + } + + Bind(); + + rows /= 6; + // if the scratchImage isn't in the format we want, specify it as a new texture + if ( cols != uploadWidth || rows != uploadHeight ) { + uploadWidth = cols; + uploadHeight = rows; + + // upload the base level + for ( i = 0 ; i < 6 ; i++ ) { + qglTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT+i, 0, GL_RGB8, cols, rows, 0, + GL_RGBA, GL_UNSIGNED_BYTE, data + cols*rows*4*i ); + } + } else { + // otherwise, just subimage upload it so that drivers can tell we are going to be changing + // it and don't try and do a texture compression + for ( i = 0 ; i < 6 ; i++ ) { + qglTexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT+i, 0, 0, 0, cols, rows, + GL_RGBA, GL_UNSIGNED_BYTE, data + cols*rows*4*i ); + } + } + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + // no other clamp mode makes sense + qglTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } else { + // otherwise, it is a 2D image + if ( type != TT_2D ) { + type = TT_2D; + uploadWidth = -1; // for a non-sub upload + } + + Bind(); + + // if the scratchImage isn't in the format we want, specify it as a new texture + if ( cols != uploadWidth || rows != uploadHeight ) { + uploadWidth = cols; + uploadHeight = rows; + qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); + } else { + // otherwise, just subimage upload it so that drivers can tell we are going to be changing + // it and don't try and do a texture compression + qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data ); + } + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + // these probably should be clamp, but we have a lot of issues with editor + // geometry coming out with texcoords slightly off one side, resulting in + // a smear across the entire polygon +#if 1 + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); +#else + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); +#endif + } +} + + +void idImage::SetClassification( int tag ) { + classification = tag; +} + +/* +================== +StorageSize +================== +*/ +int idImage::StorageSize() const { + int baseSize; + + if ( texnum == TEXTURE_NOT_LOADED ) { + return 0; + } + + switch ( type ) { + default: + case TT_2D: + baseSize = uploadWidth*uploadHeight; + break; + case TT_3D: + baseSize = uploadWidth*uploadHeight*uploadDepth; + break; + case TT_CUBIC: + baseSize = 6 * uploadWidth*uploadHeight; + break; + } + + baseSize *= BitsForInternalFormat( internalFormat ); + + baseSize /= 8; + + // account for mip mapping + baseSize = baseSize * 4 / 3; + + return baseSize; +} + +/* +================== +Print +================== +*/ +void idImage::Print() const { + if ( precompressedFile ) { + common->Printf( "P" ); + } else if ( generatorFunction ) { + common->Printf( "F" ); + } else { + common->Printf( " " ); + } + + switch ( type ) { + case TT_2D: + common->Printf( " " ); + break; + case TT_3D: + common->Printf( "3" ); + break; + case TT_CUBIC: + common->Printf( "C" ); + break; + case TT_RECT: + common->Printf( "R" ); + break; + default: + common->Printf( "", type ); + break; + } + + common->Printf( "%4i %4i ", uploadWidth, uploadHeight ); + + switch( filter ) { + case TF_DEFAULT: + common->Printf( "dflt " ); + break; + case TF_LINEAR: + common->Printf( "linr " ); + break; + case TF_NEAREST: + common->Printf( "nrst " ); + break; + default: + common->Printf( "", filter ); + break; + } + + switch ( internalFormat ) { + case GL_INTENSITY8: + case 1: + common->Printf( "I " ); + break; + case 2: + case GL_LUMINANCE8_ALPHA8: + common->Printf( "LA " ); + break; + case 3: + common->Printf( "RGB " ); + break; + case 4: + common->Printf( "RGBA " ); + break; + case GL_LUMINANCE8: + common->Printf( "L " ); + break; + case GL_ALPHA8: + common->Printf( "A " ); + break; + case GL_RGBA8: + common->Printf( "RGBA8 " ); + break; + case GL_RGB8: + common->Printf( "RGB8 " ); + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + common->Printf( "DXT1 " ); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + common->Printf( "DXT1A " ); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + common->Printf( "DXT3 " ); + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + common->Printf( "DXT5 " ); + break; + case GL_RGBA4: + common->Printf( "RGBA4 " ); + break; + case GL_RGB5: + common->Printf( "RGB5 " ); + break; + case GL_COLOR_INDEX8_EXT: + common->Printf( "CI8 " ); + break; + case GL_COLOR_INDEX: + common->Printf( "CI " ); + break; + case GL_COMPRESSED_RGB_ARB: + common->Printf( "RGBC " ); + break; + case GL_COMPRESSED_RGBA_ARB: + common->Printf( "RGBAC " ); + break; + case 0: + common->Printf( " " ); + break; + default: + common->Printf( "", internalFormat ); + break; + } + + switch ( repeat ) { + case TR_REPEAT: + common->Printf( "rept " ); + break; + case TR_CLAMP_TO_ZERO: + common->Printf( "zero " ); + break; + case TR_CLAMP_TO_ZERO_ALPHA: + common->Printf( "azro " ); + break; + case TR_CLAMP: + common->Printf( "clmp " ); + break; + default: + common->Printf( "", repeat ); + break; + } + + common->Printf( "%4ik ", StorageSize() / 1024 ); + + common->Printf( " %s\n", imgName.c_str() ); +} diff --git a/renderer/Image_process.cpp b/renderer/Image_process.cpp new file mode 100644 index 000000000..1893359fc --- /dev/null +++ b/renderer/Image_process.cpp @@ -0,0 +1,612 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +================ +R_ResampleTexture + +Used to resample images in a more general than quartering fashion. + +This will only have filter coverage if the resampled size +is greater than half the original size. + +If a larger shrinking is needed, use the mipmap function +after resampling to the next lower power of two. +================ +*/ +#define MAX_DIMENSION 4096 +byte *R_ResampleTexture( const byte *in, int inwidth, int inheight, + int outwidth, int outheight ) { + int i, j; + const byte *inrow, *inrow2; + unsigned int frac, fracstep; + unsigned int p1[MAX_DIMENSION], p2[MAX_DIMENSION]; + const byte *pix1, *pix2, *pix3, *pix4; + byte *out, *out_p; + + if ( outwidth > MAX_DIMENSION ) { + outwidth = MAX_DIMENSION; + } + if ( outheight > MAX_DIMENSION ) { + outheight = MAX_DIMENSION; + } + + out = (byte *)R_StaticAlloc( outwidth * outheight * 4 ); + out_p = out; + + fracstep = inwidth*0x10000/outwidth; + + frac = fracstep>>2; + for ( i=0 ; i>16); + frac += fracstep; + } + frac = 3*(fracstep>>2); + for ( i=0 ; i>16); + frac += fracstep; + } + + for (i=0 ; i> 1; + for (j=0 ; j>2; + out_p[j*4+1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2; + out_p[j*4+2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2; + out_p[j*4+3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2; + } + } + + return out; +} + +/* +================ +R_Dropsample + +Used to resample images in a more general than quartering fashion. +Normal maps and such should not be bilerped. +================ +*/ +byte *R_Dropsample( const byte *in, int inwidth, int inheight, + int outwidth, int outheight ) { + int i, j, k; + const byte *inrow; + const byte *pix1; + byte *out, *out_p; + + out = (byte *)R_StaticAlloc( outwidth * outheight * 4 ); + out_p = out; + + for (i=0 ; iFatalError( "R_MipMapWithAlphaMin called with size %i,%i", width, height ); + } + + // convert the incoming texture to centered floating point + c = width * height; + fbuf = (float *)_alloca( c * 4 * sizeof( *fbuf ) ); + in_p = in; + fbuf_p = fbuf; + for ( i = 0 ; i < c ; i++, in_p+=4, fbuf_p += 4 ) { + fbuf_p[0] = ( in_p[0] / 255.0 ) * 2.0 - 1.0; // convert to a normal + fbuf_p[1] = ( in_p[1] / 255.0 ) * 2.0 - 1.0; + fbuf_p[2] = ( in_p[2] / 255.0 ) * 2.0 - 1.0; + fbuf_p[3] = ( in_p[3] / 255.0 ); // filtered divegence / specularity + } + + row = width * 4; + + newWidth = width >> 1; + newHeight = height >> 1; + if ( !newWidth ) { + newWidth = 1; + } + if ( !newHeight ) { + newHeight = 1; + } + out = (byte *)R_StaticAlloc( newWidth * newHeight * 4 ); + out_p = out; + + in_p = in; + + for ( i=0 ; iFatalError( "R_MipMap called with size %i,%i", width, height ); + } + + border[0] = in[0]; + border[1] = in[1]; + border[2] = in[2]; + border[3] = in[3]; + + row = width * 4; + + newWidth = width >> 1; + newHeight = height >> 1; + if ( !newWidth ) { + newWidth = 1; + } + if ( !newHeight ) { + newHeight = 1; + } + out = (byte *)R_StaticAlloc( newWidth * newHeight * 4 ); + out_p = out; + + in_p = in; + + width >>= 1; + height >>= 1; + + if ( width == 0 || height == 0 ) { + width += height; // get largest + if ( preserveBorder ) { + for (i=0 ; i>1; + out_p[1] = ( in_p[1] + in_p[5] )>>1; + out_p[2] = ( in_p[2] + in_p[6] )>>1; + out_p[3] = ( in_p[3] + in_p[7] )>>1; + } + } + return out; + } + + for (i=0 ; i>2; + out_p[1] = (in_p[1] + in_p[5] + in_p[row+1] + in_p[row+5])>>2; + out_p[2] = (in_p[2] + in_p[6] + in_p[row+2] + in_p[row+6])>>2; + out_p[3] = (in_p[3] + in_p[7] + in_p[row+3] + in_p[row+7])>>2; + } + } + + // copy the old border texel back around if desired + if ( preserveBorder ) { + R_SetBorderTexels( out, width, height, border ); + } + + return out; +} + +/* +================ +R_MipMap3D + +Returns a new copy of the texture, eigthed in size and filtered. + +If a texture is intended to be used in GL_CLAMP or GL_CLAMP_TO_EDGE mode with +a completely transparent border, we must prevent any blurring into the outer +ring of texels by filling it with the border from the previous level. This +will result in a slight shrinking of the texture as it mips, but better than +smeared clamps... +================ +*/ +byte *R_MipMap3D( const byte *in, int width, int height, int depth, bool preserveBorder ) { + int i, j, k; + const byte *in_p; + byte *out, *out_p; + int row, plane; + byte border[4]; + int newWidth, newHeight, newDepth; + + if ( depth == 1 ) { + return R_MipMap( in, width, height, preserveBorder ); + } + + // assume symetric for now + if ( width < 2 || height < 2 || depth < 2 ) { + common->FatalError( "R_MipMap3D called with size %i,%i,%i", width, height, depth ); + } + + border[0] = in[0]; + border[1] = in[1]; + border[2] = in[2]; + border[3] = in[3]; + + row = width * 4; + plane = row * height; + + newWidth = width >> 1; + newHeight = height >> 1; + newDepth = depth >> 1; + + out = (byte *)R_StaticAlloc( newWidth * newHeight * newDepth * 4 ); + out_p = out; + + in_p = in; + + width >>= 1; + height >>= 1; + depth >>= 1; + + for (k=0 ; k>3; + out_p[1] = (in_p[1] + in_p[5] + in_p[row+1] + in_p[row+5] + + in_p[plane+1] + in_p[plane+5] + in_p[plane+row+1] + in_p[plane+row+5] + )>>3; + out_p[2] = (in_p[2] + in_p[6] + in_p[row+2] + in_p[row+6] + + in_p[plane+2] + in_p[plane+6] + in_p[plane+row+2] + in_p[plane+row+6] + )>>3; + out_p[3] = (in_p[3] + in_p[7] + in_p[row+3] + in_p[row+7] + + in_p[plane+3] + in_p[plane+6] + in_p[plane+row+3] + in_p[plane+row+6] + )>>3; + } + } + } + + // copy the old border texel back around if desired + if ( preserveBorder ) { + R_SetBorderTexels3D( out, width, height, depth, border ); + } + + return out; +} + + +/* +================== +R_BlendOverTexture + +Apply a color blend over a set of pixels +================== +*/ +void R_BlendOverTexture( byte *data, int pixelCount, const byte blend[4] ) { + int i; + int inverseAlpha; + int premult[3]; + + inverseAlpha = 255 - blend[3]; + premult[0] = blend[0] * blend[3]; + premult[1] = blend[1] * blend[3]; + premult[2] = blend[2] * blend[3]; + + for ( i = 0 ; i < pixelCount ; i++, data+=4 ) { + data[0] = ( data[0] * inverseAlpha + premult[0] ) >> 9; + data[1] = ( data[1] * inverseAlpha + premult[1] ) >> 9; + data[2] = ( data[2] * inverseAlpha + premult[2] ) >> 9; + } +} + + +/* +================== +R_HorizontalFlip + +Flip the image in place +================== +*/ +void R_HorizontalFlip( byte *data, int width, int height ) { + int i, j; + int temp; + + for ( i = 0 ; i < height ; i++ ) { + for ( j = 0 ; j < width / 2 ; j++ ) { + temp = *( (int *)data + i * width + j ); + *( (int *)data + i * width + j ) = *( (int *)data + i * width + width - 1 - j ); + *( (int *)data + i * width + width - 1 - j ) = temp; + } + } +} + +void R_VerticalFlip( byte *data, int width, int height ) { + int i, j; + int temp; + + for ( i = 0 ; i < width ; i++ ) { + for ( j = 0 ; j < height / 2 ; j++ ) { + temp = *( (int *)data + j * width + i ); + *( (int *)data + j * width + i ) = *( (int *)data + ( height - 1 - j ) * width + i ); + *( (int *)data + ( height - 1 - j ) * width + i ) = temp; + } + } +} + +void R_RotatePic( byte *data, int width ) { + int i, j; + int *temp; + + temp = (int *)R_StaticAlloc( width * width * 4 ); + + for ( i = 0 ; i < width ; i++ ) { + for ( j = 0 ; j < width ; j++ ) { + *( temp + i * width + j ) = *( (int *)data + j * width + i ); + } + } + + memcpy( data, temp, width * width * 4 ); + + R_StaticFree( temp ); +} + diff --git a/renderer/Image_program.cpp b/renderer/Image_program.cpp new file mode 100644 index 000000000..3f9d29439 --- /dev/null +++ b/renderer/Image_program.cpp @@ -0,0 +1,635 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +/* + +all uncompressed +uncompressed normal maps + +downsample images + +16 meg Dynamic cache + +Anisotropic texturing + +Trilinear on all +Trilinear on normal maps, bilinear on others +Bilinear on all + + +Manager + +->List +->Print +->Reload( bool force ) + +*/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +// tr_imageprogram.c + +#include "tr_local.h" + +/* + +Anywhere that an image name is used (diffusemaps, bumpmaps, specularmaps, lights, etc), +an imageProgram can be specified. + +This allows load time operations, like heightmap-to-normalmap conversion and image +composition, to be automatically handled in a way that supports timestamped reloads. + +*/ + +/* +================= +R_HeightmapToNormalMap + +it is not possible to convert a heightmap into a normal map +properly without knowing the texture coordinate stretching. +We can assume constant and equal ST vectors for walls, but not for characters. +================= +*/ +static void R_HeightmapToNormalMap( byte *data, int width, int height, float scale ) { + int i, j; + byte *depth; + + scale = scale / 256; + + // copy and convert to grey scale + j = width * height; + depth = (byte *)R_StaticAlloc( j ); + for ( i = 0 ; i < j ; i++ ) { + depth[i] = ( data[i*4] + data[i*4+1] + data[i*4+2] ) / 3; + } + + idVec3 dir, dir2; + for ( i = 0 ; i < height ; i++ ) { + for ( j = 0 ; j < width ; j++ ) { + int d1, d2, d3, d4; + int a1, a2, a3, a4; + + // FIXME: look at five points? + + // look at three points to estimate the gradient + a1 = d1 = depth[ ( i * width + j ) ]; + a2 = d2 = depth[ ( i * width + ( ( j + 1 ) & ( width - 1 ) ) ) ]; + a3 = d3 = depth[ ( ( ( i + 1 ) & ( height - 1 ) ) * width + j ) ]; + a4 = d4 = depth[ ( ( ( i + 1 ) & ( height - 1 ) ) * width + ( ( j + 1 ) & ( width - 1 ) ) ) ]; + + d2 -= d1; + d3 -= d1; + + dir[0] = -d2 * scale; + dir[1] = -d3 * scale; + dir[2] = 1; + dir.NormalizeFast(); + + a1 -= a3; + a4 -= a3; + + dir2[0] = -a4 * scale; + dir2[1] = a1 * scale; + dir2[2] = 1; + dir2.NormalizeFast(); + + dir += dir2; + dir.NormalizeFast(); + + a1 = ( i * width + j ) * 4; + data[ a1 + 0 ] = (byte)(dir[0] * 127 + 128); + data[ a1 + 1 ] = (byte)(dir[1] * 127 + 128); + data[ a1 + 2 ] = (byte)(dir[2] * 127 + 128); + data[ a1 + 3 ] = 255; + } + } + + + R_StaticFree( depth ); +} + + +/* +================= +R_ImageScale +================= +*/ +static void R_ImageScale( byte *data, int width, int height, float scale[4] ) { + int i, j; + int c; + + c = width * height * 4; + + for ( i = 0 ; i < c ; i++ ) { + j = (byte)(data[i] * scale[i&3]); + if ( j < 0 ) { + j = 0; + } else if ( j > 255 ) { + j = 255; + } + data[i] = j; + } +} + +/* +================= +R_InvertAlpha +================= +*/ +static void R_InvertAlpha( byte *data, int width, int height ) { + int i; + int c; + + c = width * height* 4; + + for ( i = 0 ; i < c ; i+=4 ) { + data[i+3] = 255 - data[i+3]; + } +} + +/* +================= +R_InvertColor +================= +*/ +static void R_InvertColor( byte *data, int width, int height ) { + int i; + int c; + + c = width * height* 4; + + for ( i = 0 ; i < c ; i+=4 ) { + data[i+0] = 255 - data[i+0]; + data[i+1] = 255 - data[i+1]; + data[i+2] = 255 - data[i+2]; + } +} + + +/* +=================== +R_AddNormalMaps + +=================== +*/ +static void R_AddNormalMaps( byte *data1, int width1, int height1, byte *data2, int width2, int height2 ) { + int i, j; + byte *newMap; + + // resample pic2 to the same size as pic1 + if ( width2 != width1 || height2 != height1 ) { + newMap = R_Dropsample( data2, width2, height2, width1, height1 ); + data2 = newMap; + } else { + newMap = NULL; + } + + // add the normal change from the second and renormalize + for ( i = 0 ; i < height1 ; i++ ) { + for ( j = 0 ; j < width1 ; j++ ) { + byte *d1, *d2; + idVec3 n; + float len; + + d1 = data1 + ( i * width1 + j ) * 4; + d2 = data2 + ( i * width1 + j ) * 4; + + n[0] = ( d1[0] - 128 ) / 127.0; + n[1] = ( d1[1] - 128 ) / 127.0; + n[2] = ( d1[2] - 128 ) / 127.0; + + // There are some normal maps that blend to 0,0,0 at the edges + // this screws up compression, so we try to correct that here by instead fading it to 0,0,1 + len = n.LengthFast(); + if ( len < 1.0f ) { + n[2] = idMath::Sqrt(1.0 - (n[0]*n[0]) - (n[1]*n[1])); + } + + n[0] += ( d2[0] - 128 ) / 127.0; + n[1] += ( d2[1] - 128 ) / 127.0; + n.Normalize(); + + d1[0] = (byte)(n[0] * 127 + 128); + d1[1] = (byte)(n[1] * 127 + 128); + d1[2] = (byte)(n[2] * 127 + 128); + d1[3] = 255; + } + } + + if ( newMap ) { + R_StaticFree( newMap ); + } +} + +/* +================ +R_SmoothNormalMap +================ +*/ +static void R_SmoothNormalMap( byte *data, int width, int height ) { + byte *orig; + int i, j, k, l; + idVec3 normal; + byte *out; + static float factors[3][3] = { + { 1, 1, 1 }, + { 1, 1, 1 }, + { 1, 1, 1 } + }; + + orig = (byte *)R_StaticAlloc( width * height * 4 ); + memcpy( orig, data, width * height * 4 ); + + for ( i = 0 ; i < width ; i++ ) { + for ( j = 0 ; j < height ; j++ ) { + normal = vec3_origin; + for ( k = -1 ; k < 2 ; k++ ) { + for ( l = -1 ; l < 2 ; l++ ) { + byte *in; + + in = orig + ( ((j+l)&(height-1))*width + ((i+k)&(width-1)) ) * 4; + + // ignore 000 and -1 -1 -1 + if ( in[0] == 0 && in[1] == 0 && in[2] == 0 ) { + continue; + } + if ( in[0] == 128 && in[1] == 128 && in[2] == 128 ) { + continue; + } + + normal[0] += factors[k+1][l+1] * ( in[0] - 128 ); + normal[1] += factors[k+1][l+1] * ( in[1] - 128 ); + normal[2] += factors[k+1][l+1] * ( in[2] - 128 ); + } + } + normal.Normalize(); + out = data + ( j * width + i ) * 4; + out[0] = (byte)(128 + 127 * normal[0]); + out[1] = (byte)(128 + 127 * normal[1]); + out[2] = (byte)(128 + 127 * normal[2]); + } + } + + R_StaticFree( orig ); +} + + +/* +=================== +R_ImageAdd + +=================== +*/ +static void R_ImageAdd( byte *data1, int width1, int height1, byte *data2, int width2, int height2 ) { + int i, j; + int c; + byte *newMap; + + // resample pic2 to the same size as pic1 + if ( width2 != width1 || height2 != height1 ) { + newMap = R_Dropsample( data2, width2, height2, width1, height1 ); + data2 = newMap; + } else { + newMap = NULL; + } + + + c = width1 * height1 * 4; + + for ( i = 0 ; i < c ; i++ ) { + j = data1[i] + data2[i]; + if ( j > 255 ) { + j = 255; + } + data1[i] = j; + } + + if ( newMap ) { + R_StaticFree( newMap ); + } +} + + +// we build a canonical token form of the image program here +static char parseBuffer[MAX_IMAGE_NAME]; + +/* +=================== +AppendToken +=================== +*/ +static void AppendToken( idToken &token ) { + // add a leading space if not at the beginning + if ( parseBuffer[0] ) { + idStr::Append( parseBuffer, MAX_IMAGE_NAME, " " ); + } + idStr::Append( parseBuffer, MAX_IMAGE_NAME, token.c_str() ); +} + +/* +=================== +MatchAndAppendToken +=================== +*/ +static void MatchAndAppendToken( idLexer &src, const char *match ) { + if ( !src.ExpectTokenString( match ) ) { + return; + } + // a matched token won't need a leading space + idStr::Append( parseBuffer, MAX_IMAGE_NAME, match ); +} + +/* +=================== +R_ParseImageProgram_r + +If pic is NULL, the timestamps will be filled in, but no image will be generated +If both pic and timestamps are NULL, it will just advance past it, which can be +used to parse an image program from a text stream. +=================== +*/ +static bool R_ParseImageProgram_r( idLexer &src, byte **pic, int *width, int *height, + ID_TIME_T *timestamps, textureDepth_t *depth ) { + idToken token; + float scale; + ID_TIME_T timestamp; + + src.ReadToken( &token ); + AppendToken( token ); + + if ( !token.Icmp( "heightmap" ) ) { + MatchAndAppendToken( src, "(" ); + + if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) { + return false; + } + + MatchAndAppendToken( src, "," ); + + src.ReadToken( &token ); + AppendToken( token ); + scale = token.GetFloatValue(); + + // process it + if ( pic ) { + R_HeightmapToNormalMap( *pic, *width, *height, scale ); + if ( depth ) { + *depth = TD_BUMP; + } + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "addnormals" ) ) { + byte *pic2; + int width2, height2; + + MatchAndAppendToken( src, "(" ); + + if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) { + return false; + } + + MatchAndAppendToken( src, "," ); + + if ( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, depth ) ) { + if ( pic ) { + R_StaticFree( *pic ); + *pic = NULL; + } + return false; + } + + // process it + if ( pic ) { + R_AddNormalMaps( *pic, *width, *height, pic2, width2, height2 ); + R_StaticFree( pic2 ); + if ( depth ) { + *depth = TD_BUMP; + } + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "smoothnormals" ) ) { + MatchAndAppendToken( src, "(" ); + + if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) { + return false; + } + + if ( pic ) { + R_SmoothNormalMap( *pic, *width, *height ); + if ( depth ) { + *depth = TD_BUMP; + } + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "add" ) ) { + byte *pic2; + int width2, height2; + + MatchAndAppendToken( src, "(" ); + + if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) { + return false; + } + + MatchAndAppendToken( src, "," ); + + if ( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, depth ) ) { + if ( pic ) { + R_StaticFree( *pic ); + *pic = NULL; + } + return false; + } + + // process it + if ( pic ) { + R_ImageAdd( *pic, *width, *height, pic2, width2, height2 ); + R_StaticFree( pic2 ); + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "scale" ) ) { + float scale[4]; + int i; + + MatchAndAppendToken( src, "(" ); + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + for ( i = 0 ; i < 4 ; i++ ) { + MatchAndAppendToken( src, "," ); + src.ReadToken( &token ); + AppendToken( token ); + scale[i] = token.GetFloatValue(); + } + + // process it + if ( pic ) { + R_ImageScale( *pic, *width, *height, scale ); + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "invertAlpha" ) ) { + MatchAndAppendToken( src, "(" ); + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + // process it + if ( pic ) { + R_InvertAlpha( *pic, *width, *height ); + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "invertColor" ) ) { + MatchAndAppendToken( src, "(" ); + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + // process it + if ( pic ) { + R_InvertColor( *pic, *width, *height ); + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "makeIntensity" ) ) { + int i; + + MatchAndAppendToken( src, "(" ); + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + // copy red to green, blue, and alpha + if ( pic ) { + int c; + c = *width * *height * 4; + for ( i = 0 ; i < c ; i+=4 ) { + (*pic)[i+1] = + (*pic)[i+2] = + (*pic)[i+3] = (*pic)[i]; + } + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + if ( !token.Icmp( "makeAlpha" ) ) { + int i; + + MatchAndAppendToken( src, "(" ); + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + // average RGB into alpha, then set RGB to white + if ( pic ) { + int c; + c = *width * *height * 4; + for ( i = 0 ; i < c ; i+=4 ) { + (*pic)[i+3] = ( (*pic)[i+0] + (*pic)[i+1] + (*pic)[i+2] ) / 3; + (*pic)[i+0] = + (*pic)[i+1] = + (*pic)[i+2] = 255; + } + } + + MatchAndAppendToken( src, ")" ); + return true; + } + + // if we are just parsing instead of loading or checking, + // don't do the R_LoadImage + if ( !timestamps && !pic ) { + return true; + } + + // load it as an image + R_LoadImage( token.c_str(), pic, width, height, ×tamp, true ); + + if ( timestamp == -1 ) { + return false; + } + + // add this to the timestamp + if ( timestamps ) { + if ( timestamp > *timestamps ) { + *timestamps = timestamp; + } + } + + return true; +} + + +/* +=================== +R_LoadImageProgram +=================== +*/ +void R_LoadImageProgram( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamps, textureDepth_t *depth ) { + idLexer src; + + src.LoadMemory( name, strlen(name), name ); + src.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + + parseBuffer[0] = 0; + if ( timestamps ) { + *timestamps = 0; + } + + R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ); + + src.FreeSource(); +} + +/* +=================== +R_ParsePastImageProgram +=================== +*/ +const char *R_ParsePastImageProgram( idLexer &src ) { + parseBuffer[0] = 0; + R_ParseImageProgram_r( src, NULL, NULL, NULL, NULL, NULL ); + return parseBuffer; +} + diff --git a/renderer/Interaction.cpp b/renderer/Interaction.cpp new file mode 100644 index 000000000..cececa191 --- /dev/null +++ b/renderer/Interaction.cpp @@ -0,0 +1,1299 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +=========================================================================== + +idInteraction implementation + +=========================================================================== +*/ + +// FIXME: use private allocator for srfCullInfo_t + +/* +================ +R_CalcInteractionFacing + +Determines which triangles of the surface are facing towards the light origin. + +The facing array should be allocated with one extra index than +the number of surface triangles, which will be used to handle dangling +edge silhouettes. +================ +*/ +void R_CalcInteractionFacing( const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo ) { + idVec3 localLightOrigin; + + if ( cullInfo.facing != NULL ) { + return; + } + + R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, localLightOrigin ); + + int numFaces = tri->numIndexes / 3; + + if ( !tri->facePlanes || !tri->facePlanesCalculated ) { + R_DeriveFacePlanes( const_cast(tri) ); + } + + cullInfo.facing = (byte *) R_StaticAlloc( ( numFaces + 1 ) * sizeof( cullInfo.facing[0] ) ); + + // calculate back face culling + float *planeSide = (float *) _alloca16( numFaces * sizeof( float ) ); + + // exact geometric cull against face + SIMDProcessor->Dot( planeSide, localLightOrigin, tri->facePlanes, numFaces ); + SIMDProcessor->CmpGE( cullInfo.facing, planeSide, 0.0f, numFaces ); + + cullInfo.facing[ numFaces ] = 1; // for dangling edges to reference +} + +/* +===================== +R_CalcInteractionCullBits + +We want to cull a little on the sloppy side, because the pre-clipping +of geometry to the lights in dmap will give many cases that are right +at the border we throw things out on the border, because if any one +vertex is clearly inside, the entire triangle will be accepted. +===================== +*/ +void R_CalcInteractionCullBits( const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo ) { + int i, frontBits; + + if ( cullInfo.cullBits != NULL ) { + return; + } + + frontBits = 0; + + // cull the triangle surface bounding box + for ( i = 0; i < 6; i++ ) { + + R_GlobalPlaneToLocal( ent->modelMatrix, -light->frustum[i], cullInfo.localClipPlanes[i] ); + + // get front bits for the whole surface + if ( tri->bounds.PlaneDistance( cullInfo.localClipPlanes[i] ) >= LIGHT_CLIP_EPSILON ) { + frontBits |= 1<numVerts * sizeof( cullInfo.cullBits[0] ) ); + SIMDProcessor->Memset( cullInfo.cullBits, 0, tri->numVerts * sizeof( cullInfo.cullBits[0] ) ); + + float *planeSide = (float *) _alloca16( tri->numVerts * sizeof( float ) ); + + for ( i = 0; i < 6; i++ ) { + // if completely infront of this clipping plane + if ( frontBits & ( 1 << i ) ) { + continue; + } + SIMDProcessor->Dot( planeSide, cullInfo.localClipPlanes[i], tri->verts, tri->numVerts ); + SIMDProcessor->CmpLT( cullInfo.cullBits, i, planeSide, LIGHT_CLIP_EPSILON, tri->numVerts ); + } +} + +/* +================ +R_FreeInteractionCullInfo +================ +*/ +void R_FreeInteractionCullInfo( srfCullInfo_t &cullInfo ) { + if ( cullInfo.facing != NULL ) { + R_StaticFree( cullInfo.facing ); + cullInfo.facing = NULL; + } + if ( cullInfo.cullBits != NULL ) { + if ( cullInfo.cullBits != LIGHT_CULL_ALL_FRONT ) { + R_StaticFree( cullInfo.cullBits ); + } + cullInfo.cullBits = NULL; + } +} + +#define MAX_CLIPPED_POINTS 20 +typedef struct { + int numVerts; + idVec3 verts[MAX_CLIPPED_POINTS]; +} clipTri_t; + +/* +============= +R_ChopWinding + +Clips a triangle from one buffer to another, setting edge flags +The returned buffer may be the same as inNum if no clipping is done +If entirely clipped away, clipTris[returned].numVerts == 0 + +I have some worries about edge flag cases when polygons are clipped +multiple times near the epsilon. +============= +*/ +static int R_ChopWinding( clipTri_t clipTris[2], int inNum, const idPlane plane ) { + clipTri_t *in, *out; + float dists[MAX_CLIPPED_POINTS]; + int sides[MAX_CLIPPED_POINTS]; + int counts[3]; + float dot; + int i, j; + idVec3 mid; + bool front; + + in = &clipTris[inNum]; + out = &clipTris[inNum^1]; + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + front = false; + for ( i = 0; i < in->numVerts; i++ ) { + dot = in->verts[i] * plane.Normal() + plane[3]; + dists[i] = dot; + if ( dot < LIGHT_CLIP_EPSILON ) { // slop onto the back + sides[i] = SIDE_BACK; + } else { + sides[i] = SIDE_FRONT; + if ( dot > LIGHT_CLIP_EPSILON ) { + front = true; + } + } + counts[sides[i]]++; + } + + // if none in front, it is completely clipped away + if ( !front ) { + in->numVerts = 0; + return inNum; + } + if ( !counts[SIDE_BACK] ) { + return inNum; // inout stays the same + } + + // avoid wrapping checks by duplicating first value to end + sides[i] = sides[0]; + dists[i] = dists[0]; + in->verts[in->numVerts] = in->verts[0]; + + out->numVerts = 0; + for ( i = 0 ; i < in->numVerts ; i++ ) { + idVec3 &p1 = in->verts[i]; + + if ( sides[i] == SIDE_FRONT ) { + out->verts[out->numVerts] = p1; + out->numVerts++; + } + + if ( sides[i+1] == sides[i] ) { + continue; + } + + // generate a split point + idVec3 &p2 = in->verts[i+1]; + + dot = dists[i] / ( dists[i] - dists[i+1] ); + for ( j = 0; j < 3; j++ ) { + mid[j] = p1[j] + dot * ( p2[j] - p1[j] ); + } + + out->verts[out->numVerts] = mid; + + out->numVerts++; + } + + return inNum ^ 1; +} + +/* +=================== +R_ClipTriangleToLight + +Returns false if nothing is left after clipping +=================== +*/ +static bool R_ClipTriangleToLight( const idVec3 &a, const idVec3 &b, const idVec3 &c, int planeBits, const idPlane frustum[6] ) { + int i; + clipTri_t pingPong[2]; + int p; + + pingPong[0].numVerts = 3; + pingPong[0].verts[0] = a; + pingPong[0].verts[1] = b; + pingPong[0].verts[2] = c; + + p = 0; + for ( i = 0 ; i < 6 ; i++ ) { + if ( planeBits & ( 1 << i ) ) { + p = R_ChopWinding( pingPong, p, frustum[i] ); + if ( pingPong[p].numVerts < 1 ) { + return false; + } + } + } + + return true; +} + +/* +==================== +R_CreateLightTris + +The resulting surface will be a subset of the original triangles, +it will never clip triangles, but it may cull on a per-triangle basis. +==================== +*/ +static srfTriangles_t *R_CreateLightTris( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + const idMaterial *shader, srfCullInfo_t &cullInfo ) { + int i; + int numIndexes; + glIndex_t *indexes; + srfTriangles_t *newTri; + int c_backfaced; + int c_distance; + idBounds bounds; + bool includeBackFaces; + int faceNum; + + tr.pc.c_createLightTris++; + c_backfaced = 0; + c_distance = 0; + + numIndexes = 0; + indexes = NULL; + + // it is debatable if non-shadowing lights should light back faces. we aren't at the moment + if ( r_lightAllBackFaces.GetBool() || light->lightShader->LightEffectsBackSides() + || shader->ReceivesLightingOnBackSides() + || ent->parms.noSelfShadow || ent->parms.noShadow ) { + includeBackFaces = true; + } else { + includeBackFaces = false; + } + + // allocate a new surface for the lit triangles + newTri = R_AllocStaticTriSurf(); + + // save a reference to the original surface + newTri->ambientSurface = const_cast(tri); + + // the light surface references the verts of the ambient surface + newTri->numVerts = tri->numVerts; + R_ReferenceStaticTriSurfVerts( newTri, tri ); + + // calculate cull information + if ( !includeBackFaces ) { + R_CalcInteractionFacing( ent, tri, light, cullInfo ); + } + R_CalcInteractionCullBits( ent, tri, light, cullInfo ); + + // if the surface is completely inside the light frustum + if ( cullInfo.cullBits == LIGHT_CULL_ALL_FRONT ) { + + // if we aren't self shadowing, let back facing triangles get + // through so the smooth shaded bump maps light all the way around + if ( includeBackFaces ) { + + // the whole surface is lit so the light surface just references the indexes of the ambient surface + R_ReferenceStaticTriSurfIndexes( newTri, tri ); + numIndexes = tri->numIndexes; + bounds = tri->bounds; + + } else { + + // the light tris indexes are going to be a subset of the original indexes so we generally + // allocate too much memory here but we decrease the memory block when the number of indexes is known + R_AllocStaticTriSurfIndexes( newTri, tri->numIndexes ); + + // back face cull the individual triangles + indexes = newTri->indexes; + const byte *facing = cullInfo.facing; + for ( faceNum = i = 0; i < tri->numIndexes; i += 3, faceNum++ ) { + if ( !facing[ faceNum ] ) { + c_backfaced++; + continue; + } + indexes[numIndexes+0] = tri->indexes[i+0]; + indexes[numIndexes+1] = tri->indexes[i+1]; + indexes[numIndexes+2] = tri->indexes[i+2]; + numIndexes += 3; + } + + // get bounds for the surface + SIMDProcessor->MinMax( bounds[0], bounds[1], tri->verts, indexes, numIndexes ); + + // decrease the size of the memory block to the size of the number of used indexes + R_ResizeStaticTriSurfIndexes( newTri, numIndexes ); + } + + } else { + + // the light tris indexes are going to be a subset of the original indexes so we generally + // allocate too much memory here but we decrease the memory block when the number of indexes is known + R_AllocStaticTriSurfIndexes( newTri, tri->numIndexes ); + + // cull individual triangles + indexes = newTri->indexes; + const byte *facing = cullInfo.facing; + const byte *cullBits = cullInfo.cullBits; + for ( faceNum = i = 0; i < tri->numIndexes; i += 3, faceNum++ ) { + int i1, i2, i3; + + // if we aren't self shadowing, let back facing triangles get + // through so the smooth shaded bump maps light all the way around + if ( !includeBackFaces ) { + // back face cull + if ( !facing[ faceNum ] ) { + c_backfaced++; + continue; + } + } + + i1 = tri->indexes[i+0]; + i2 = tri->indexes[i+1]; + i3 = tri->indexes[i+2]; + + // fast cull outside the frustum + // if all three points are off one plane side, it definately isn't visible + if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) { + c_distance++; + continue; + } + + if ( r_usePreciseTriangleInteractions.GetBool() ) { + // do a precise clipped cull if none of the points is completely inside the frustum + // note that we do not actually use the clipped triangle, which would have Z fighting issues. + if ( cullBits[i1] && cullBits[i2] && cullBits[i3] ) { + int cull = cullBits[i1] | cullBits[i2] | cullBits[i3]; + if ( !R_ClipTriangleToLight( tri->verts[i1].xyz, tri->verts[i2].xyz, tri->verts[i3].xyz, cull, cullInfo.localClipPlanes ) ) { + continue; + } + } + } + + // add to the list + indexes[numIndexes+0] = i1; + indexes[numIndexes+1] = i2; + indexes[numIndexes+2] = i3; + numIndexes += 3; + } + + // get bounds for the surface + SIMDProcessor->MinMax( bounds[0], bounds[1], tri->verts, indexes, numIndexes ); + + // decrease the size of the memory block to the size of the number of used indexes + R_ResizeStaticTriSurfIndexes( newTri, numIndexes ); + } + + if ( !numIndexes ) { + R_ReallyFreeStaticTriSurf( newTri ); + return NULL; + } + + newTri->numIndexes = numIndexes; + + newTri->bounds = bounds; + + return newTri; +} + +/* +=============== +idInteraction::idInteraction +=============== +*/ +idInteraction::idInteraction( void ) { + numSurfaces = 0; + surfaces = NULL; + entityDef = NULL; + lightDef = NULL; + lightNext = NULL; + lightPrev = NULL; + entityNext = NULL; + entityPrev = NULL; + dynamicModelFrameCount = 0; + frustumState = FRUSTUM_UNINITIALIZED; + frustumAreas = NULL; +} + +/* +=============== +idInteraction::AllocAndLink +=============== +*/ +idInteraction *idInteraction::AllocAndLink( idRenderEntityLocal *edef, idRenderLightLocal *ldef ) { + if ( !edef || !ldef ) { + common->Error( "idInteraction::AllocAndLink: NULL parm" ); + } + + idRenderWorldLocal *renderWorld = edef->world; + + idInteraction *interaction = renderWorld->interactionAllocator.Alloc(); + + // link and initialize + interaction->dynamicModelFrameCount = 0; + + interaction->lightDef = ldef; + interaction->entityDef = edef; + + interaction->numSurfaces = -1; // not checked yet + interaction->surfaces = NULL; + + interaction->frustumState = idInteraction::FRUSTUM_UNINITIALIZED; + interaction->frustumAreas = NULL; + + // link at the start of the entity's list + interaction->lightNext = ldef->firstInteraction; + interaction->lightPrev = NULL; + ldef->firstInteraction = interaction; + if ( interaction->lightNext != NULL ) { + interaction->lightNext->lightPrev = interaction; + } else { + ldef->lastInteraction = interaction; + } + + // link at the start of the light's list + interaction->entityNext = edef->firstInteraction; + interaction->entityPrev = NULL; + edef->firstInteraction = interaction; + if ( interaction->entityNext != NULL ) { + interaction->entityNext->entityPrev = interaction; + } else { + edef->lastInteraction = interaction; + } + + // update the interaction table + if ( renderWorld->interactionTable ) { + int index = ldef->index * renderWorld->interactionTableWidth + edef->index; + if ( renderWorld->interactionTable[index] != NULL ) { + common->Error( "idInteraction::AllocAndLink: non NULL table entry" ); + } + renderWorld->interactionTable[ index ] = interaction; + } + + return interaction; +} + +/* +=============== +idInteraction::FreeSurfaces + +Frees the surfaces, but leaves the interaction linked in, so it +will be regenerated automatically +=============== +*/ +void idInteraction::FreeSurfaces( void ) { + if ( this->surfaces ) { + for ( int i = 0 ; i < this->numSurfaces ; i++ ) { + surfaceInteraction_t *sint = &this->surfaces[i]; + + if ( sint->lightTris ) { + if ( sint->lightTris != LIGHT_TRIS_DEFERRED ) { + R_FreeStaticTriSurf( sint->lightTris ); + } + sint->lightTris = NULL; + } + if ( sint->shadowTris ) { + // if it doesn't have an entityDef, it is part of a prelight + // model, not a generated interaction + if ( this->entityDef ) { + R_FreeStaticTriSurf( sint->shadowTris ); + sint->shadowTris = NULL; + } + } + R_FreeInteractionCullInfo( sint->cullInfo ); + } + + R_StaticFree( this->surfaces ); + this->surfaces = NULL; + } + this->numSurfaces = -1; +} + +/* +=============== +idInteraction::Unlink +=============== +*/ +void idInteraction::Unlink( void ) { + + // unlink from the entity's list + if ( this->entityPrev ) { + this->entityPrev->entityNext = this->entityNext; + } else { + this->entityDef->firstInteraction = this->entityNext; + } + if ( this->entityNext ) { + this->entityNext->entityPrev = this->entityPrev; + } else { + this->entityDef->lastInteraction = this->entityPrev; + } + this->entityNext = this->entityPrev = NULL; + + // unlink from the light's list + if ( this->lightPrev ) { + this->lightPrev->lightNext = this->lightNext; + } else { + this->lightDef->firstInteraction = this->lightNext; + } + if ( this->lightNext ) { + this->lightNext->lightPrev = this->lightPrev; + } else { + this->lightDef->lastInteraction = this->lightPrev; + } + this->lightNext = this->lightPrev = NULL; +} + +/* +=============== +idInteraction::UnlinkAndFree + +Removes links and puts it back on the free list. +=============== +*/ +void idInteraction::UnlinkAndFree( void ) { + + // clear the table pointer + idRenderWorldLocal *renderWorld = this->lightDef->world; + if ( renderWorld->interactionTable ) { + int index = this->lightDef->index * renderWorld->interactionTableWidth + this->entityDef->index; + if ( renderWorld->interactionTable[index] != this ) { + common->Error( "idInteraction::UnlinkAndFree: interactionTable wasn't set" ); + } + renderWorld->interactionTable[index] = NULL; + } + + Unlink(); + + FreeSurfaces(); + + // free the interaction area references + areaNumRef_t *area, *nextArea; + for ( area = frustumAreas; area; area = nextArea ) { + nextArea = area->next; + renderWorld->areaNumRefAllocator.Free( area ); + } + + // put it back on the free list + renderWorld->interactionAllocator.Free( this ); +} + +/* +=============== +idInteraction::MakeEmpty + +Makes the interaction empty and links it at the end of the entity's and light's interaction lists. +=============== +*/ +void idInteraction::MakeEmpty( void ) { + + // an empty interaction has no surfaces + numSurfaces = 0; + + Unlink(); + + // relink at the end of the entity's list + this->entityNext = NULL; + this->entityPrev = this->entityDef->lastInteraction; + this->entityDef->lastInteraction = this; + if ( this->entityPrev ) { + this->entityPrev->entityNext = this; + } else { + this->entityDef->firstInteraction = this; + } + + // relink at the end of the light's list + this->lightNext = NULL; + this->lightPrev = this->lightDef->lastInteraction; + this->lightDef->lastInteraction = this; + if ( this->lightPrev ) { + this->lightPrev->lightNext = this; + } else { + this->lightDef->firstInteraction = this; + } +} + +/* +=============== +idInteraction::HasShadows +=============== +*/ +ID_INLINE bool idInteraction::HasShadows( void ) const { + return ( !lightDef->parms.noShadows && !entityDef->parms.noShadow && lightDef->lightShader->LightCastsShadows() ); +} + +/* +=============== +idInteraction::MemoryUsed + +Counts up the memory used by all the surfaceInteractions, which +will be used to determine when we need to start purging old interactions. +=============== +*/ +int idInteraction::MemoryUsed( void ) { + int total = 0; + + for ( int i = 0 ; i < numSurfaces ; i++ ) { + surfaceInteraction_t *inter = &surfaces[i]; + + total += R_TriSurfMemory( inter->lightTris ); + total += R_TriSurfMemory( inter->shadowTris ); + } + + return total; +} + +/* +================== +idInteraction::CalcInteractionScissorRectangle +================== +*/ +idScreenRect idInteraction::CalcInteractionScissorRectangle( const idFrustum &viewFrustum ) { + idBounds projectionBounds; + idScreenRect portalRect; + idScreenRect scissorRect; + + if ( r_useInteractionScissors.GetInteger() == 0 ) { + return lightDef->viewLight->scissorRect; + } + + if ( r_useInteractionScissors.GetInteger() < 0 ) { + // this is the code from Cass at nvidia, it is more precise, but slower + return R_CalcIntersectionScissor( lightDef, entityDef, tr.viewDef ); + } + + // the following is Mr.E's code + + // frustum must be initialized and valid + if ( frustumState == idInteraction::FRUSTUM_UNINITIALIZED || frustumState == idInteraction::FRUSTUM_INVALID ) { + return lightDef->viewLight->scissorRect; + } + + // calculate scissors for the portals through which the interaction is visible + if ( r_useInteractionScissors.GetInteger() > 1 ) { + areaNumRef_t *area; + + if ( frustumState == idInteraction::FRUSTUM_VALID ) { + // retrieve all the areas the interaction frustum touches + for ( areaReference_t *ref = entityDef->entityRefs; ref; ref = ref->ownerNext ) { + area = entityDef->world->areaNumRefAllocator.Alloc(); + area->areaNum = ref->area->areaNum; + area->next = frustumAreas; + frustumAreas = area; + } + frustumAreas = tr.viewDef->renderWorld->FloodFrustumAreas( frustum, frustumAreas ); + frustumState = idInteraction::FRUSTUM_VALIDAREAS; + } + + portalRect.Clear(); + for ( area = frustumAreas; area; area = area->next ) { + portalRect.Union( entityDef->world->GetAreaScreenRect( area->areaNum ) ); + } + portalRect.Intersect( lightDef->viewLight->scissorRect ); + } else { + portalRect = lightDef->viewLight->scissorRect; + } + + // early out if the interaction is not visible through any portals + if ( portalRect.IsEmpty() ) { + return portalRect; + } + + // calculate bounds of the interaction frustum projected into the view frustum + if ( lightDef->parms.pointLight ) { + viewFrustum.ClippedProjectionBounds( frustum, idBox( lightDef->parms.origin, lightDef->parms.lightRadius, lightDef->parms.axis ), projectionBounds ); + } else { + viewFrustum.ClippedProjectionBounds( frustum, idBox( lightDef->frustumTris->bounds ), projectionBounds ); + } + + if ( projectionBounds.IsCleared() ) { + return portalRect; + } + + // derive a scissor rectangle from the projection bounds + scissorRect = R_ScreenRectFromViewFrustumBounds( projectionBounds ); + + // intersect with the portal crossing scissor rectangle + scissorRect.Intersect( portalRect ); + + if ( r_showInteractionScissors.GetInteger() > 0 ) { + R_ShowColoredScreenRect( scissorRect, lightDef->index ); + } + + return scissorRect; +} + +/* +=================== +idInteraction::CullInteractionByViewFrustum +=================== +*/ +bool idInteraction::CullInteractionByViewFrustum( const idFrustum &viewFrustum ) { + + if ( !r_useInteractionCulling.GetBool() ) { + return false; + } + + if ( frustumState == idInteraction::FRUSTUM_INVALID ) { + return false; + } + + if ( frustumState == idInteraction::FRUSTUM_UNINITIALIZED ) { + + frustum.FromProjection( idBox( entityDef->referenceBounds, entityDef->parms.origin, entityDef->parms.axis ), lightDef->globalLightOrigin, MAX_WORLD_SIZE ); + + if ( !frustum.IsValid() ) { + frustumState = idInteraction::FRUSTUM_INVALID; + return false; + } + + if ( lightDef->parms.pointLight ) { + frustum.ConstrainToBox( idBox( lightDef->parms.origin, lightDef->parms.lightRadius, lightDef->parms.axis ) ); + } else { + frustum.ConstrainToBox( idBox( lightDef->frustumTris->bounds ) ); + } + + frustumState = idInteraction::FRUSTUM_VALID; + } + + if ( !viewFrustum.IntersectsFrustum( frustum ) ) { + return true; + } + + if ( r_showInteractionFrustums.GetInteger() ) { + static idVec4 colors[] = { colorRed, colorGreen, colorBlue, colorYellow, colorMagenta, colorCyan, colorWhite, colorPurple }; + tr.viewDef->renderWorld->DebugFrustum( colors[lightDef->index & 7], frustum, ( r_showInteractionFrustums.GetInteger() > 1 ) ); + if ( r_showInteractionFrustums.GetInteger() > 2 ) { + tr.viewDef->renderWorld->DebugBox( colorWhite, idBox( entityDef->referenceBounds, entityDef->parms.origin, entityDef->parms.axis ) ); + } + } + + return false; +} + +/* +==================== +idInteraction::CreateInteraction + +Called when a entityDef and a lightDef are both present in a +portalArea, and might be visible. Performs cull checking before doing the expensive +computations. + +References tr.viewCount so lighting surfaces will only be created if the ambient surface is visible, +otherwise it will be marked as deferred. + +The results of this are cached and valid until the light or entity change. +==================== +*/ +void idInteraction::CreateInteraction( const idRenderModel *model ) { + const idMaterial * lightShader = lightDef->lightShader; + const idMaterial* shader; + bool interactionGenerated; + idBounds bounds; + + tr.pc.c_createInteractions++; + + bounds = model->Bounds( &entityDef->parms ); + + // if it doesn't contact the light frustum, none of the surfaces will + if ( R_CullLocalBox( bounds, entityDef->modelMatrix, 6, lightDef->frustum ) ) { + MakeEmpty(); + return; + } + + // use the turbo shadow path + shadowGen_t shadowGen = SG_DYNAMIC; + + // really large models, like outside terrain meshes, should use + // the more exactly culled static shadow path instead of the turbo shadow path. + // FIXME: this is a HACK, we should probably have a material flag. + if ( bounds[1][0] - bounds[0][0] > 3000 ) { + shadowGen = SG_STATIC; + } + + // + // create slots for each of the model's surfaces + // + numSurfaces = model->NumSurfaces(); + surfaces = (surfaceInteraction_t *)R_ClearedStaticAlloc( sizeof( *surfaces ) * numSurfaces ); + + interactionGenerated = false; + + // check each surface in the model + for ( int c = 0 ; c < model->NumSurfaces() ; c++ ) { + const modelSurface_t *surf; + srfTriangles_t *tri; + + surf = model->Surface( c ); + + tri = surf->geometry; + if ( !tri ) { + continue; + } + + // determine the shader for this surface, possibly by skinning + shader = surf->shader; + shader = R_RemapShaderBySkin( shader, entityDef->parms.customSkin, entityDef->parms.customShader ); + + if ( !shader ) { + continue; + } + + // try to cull each surface + if ( R_CullLocalBox( tri->bounds, entityDef->modelMatrix, 6, lightDef->frustum ) ) { + continue; + } + + surfaceInteraction_t *sint = &surfaces[c]; + + sint->shader = shader; + + // save the ambient tri pointer so we can reject lightTri interactions + // when the ambient surface isn't in view, and we can get shared vertex + // and shadow data from the source surface + sint->ambientTris = tri; + + // "invisible ink" lights and shaders + if ( shader->Spectrum() != lightShader->Spectrum() ) { + continue; + } + + // generate a lighted surface and add it + if ( shader->ReceivesLighting() ) { + if ( tri->ambientViewCount == tr.viewCount ) { + sint->lightTris = R_CreateLightTris( entityDef, tri, lightDef, shader, sint->cullInfo ); + } else { + // this will be calculated when sint->ambientTris is actually in view + sint->lightTris = LIGHT_TRIS_DEFERRED; + } + interactionGenerated = true; + } + + // if the interaction has shadows and this surface casts a shadow + if ( HasShadows() && shader->SurfaceCastsShadow() && tri->silEdges != NULL ) { + + // if the light has an optimized shadow volume, don't create shadows for any models that are part of the base areas + if ( lightDef->parms.prelightModel == NULL || !model->IsStaticWorldModel() || !r_useOptimizedShadows.GetBool() ) { + + // this is the only place during gameplay (outside the utilities) that R_CreateShadowVolume() is called + sint->shadowTris = R_CreateShadowVolume( entityDef, tri, lightDef, shadowGen, sint->cullInfo ); + if ( sint->shadowTris ) { + if ( shader->Coverage() != MC_OPAQUE || ( !r_skipSuppress.GetBool() && entityDef->parms.suppressSurfaceInViewID ) ) { + // if any surface is a shadow-casting perforated or translucent surface, or the + // base surface is suppressed in the view (world weapon shadows) we can't use + // the external shadow optimizations because we can see through some of the faces + sint->shadowTris->numShadowIndexesNoCaps = sint->shadowTris->numIndexes; + sint->shadowTris->numShadowIndexesNoFrontCaps = sint->shadowTris->numIndexes; + } + } + interactionGenerated = true; + } + } + + // free the cull information when it's no longer needed + if ( sint->lightTris != LIGHT_TRIS_DEFERRED ) { + R_FreeInteractionCullInfo( sint->cullInfo ); + } + } + + // if none of the surfaces generated anything, don't even bother checking? + if ( !interactionGenerated ) { + MakeEmpty(); + } +} + +/* +====================== +R_PotentiallyInsideInfiniteShadow + +If we know that we are "off to the side" of an infinite shadow volume, +we can draw it without caps in zpass mode +====================== +*/ +static bool R_PotentiallyInsideInfiniteShadow( const srfTriangles_t *occluder, + const idVec3 &localView, const idVec3 &localLight ) { + idBounds exp; + + // expand the bounds to account for the near clip plane, because the + // view could be mathematically outside, but if the near clip plane + // chops a volume edge, the zpass rendering would fail. + float znear = r_znear.GetFloat(); + if ( tr.viewDef->renderView.cramZNear ) { + znear *= 0.25f; + } + float stretch = znear * 2; // in theory, should vary with FOV + exp[0][0] = occluder->bounds[0][0] - stretch; + exp[0][1] = occluder->bounds[0][1] - stretch; + exp[0][2] = occluder->bounds[0][2] - stretch; + exp[1][0] = occluder->bounds[1][0] + stretch; + exp[1][1] = occluder->bounds[1][1] + stretch; + exp[1][2] = occluder->bounds[1][2] + stretch; + + if ( exp.ContainsPoint( localView ) ) { + return true; + } + if ( exp.ContainsPoint( localLight ) ) { + return true; + } + + // if the ray from localLight to localView intersects a face of the + // expanded bounds, we will be inside the projection + + idVec3 ray = localView - localLight; + + // intersect the ray from the view to the light with the near side of the bounds + for ( int axis = 0; axis < 3; axis++ ) { + float d, frac; + idVec3 hit; + + if ( localLight[axis] < exp[0][axis] ) { + if ( localView[axis] < exp[0][axis] ) { + continue; + } + d = exp[0][axis] - localLight[axis]; + frac = d / ray[axis]; + hit = localLight + frac * ray; + hit[axis] = exp[0][axis]; + } else if ( localLight[axis] > exp[1][axis] ) { + if ( localView[axis] > exp[1][axis] ) { + continue; + } + d = exp[1][axis] - localLight[axis]; + frac = d / ray[axis]; + hit = localLight + frac * ray; + hit[axis] = exp[1][axis]; + } else { + continue; + } + + if ( exp.ContainsPoint( hit ) ) { + return true; + } + } + + // the view is definitely not inside the projected shadow + return false; +} + +/* +================== +idInteraction::AddActiveInteraction + +Create and add any necessary light and shadow triangles + +If the model doesn't have any surfaces that need interactions +with this type of light, it can be skipped, but we might need to +instantiate the dynamic model to find out +================== +*/ +void idInteraction::AddActiveInteraction( void ) { + viewLight_t * vLight; + viewEntity_t * vEntity; + idScreenRect shadowScissor; + idScreenRect lightScissor; + idVec3 localLightOrigin; + idVec3 localViewOrigin; + + vLight = lightDef->viewLight; + vEntity = entityDef->viewEntity; + + // do not waste time culling the interaction frustum if there will be no shadows + if ( !HasShadows() ) { + + // use the entity scissor rectangle + shadowScissor = vEntity->scissorRect; + + // culling does not seem to be worth it for static world models + } else if ( entityDef->parms.hModel->IsStaticWorldModel() ) { + + // use the light scissor rectangle + shadowScissor = vLight->scissorRect; + + } else { + + // try to cull the interaction + // this will also cull the case where the light origin is inside the + // view frustum and the entity bounds are outside the view frustum + if ( CullInteractionByViewFrustum( tr.viewDef->viewFrustum ) ) { + return; + } + + // calculate the shadow scissor rectangle + shadowScissor = CalcInteractionScissorRectangle( tr.viewDef->viewFrustum ); + } + + // get out before making the dynamic model if the shadow scissor rectangle is empty + if ( shadowScissor.IsEmpty() ) { + return; + } + + // We will need the dynamic surface created to make interactions, even if the + // model itself wasn't visible. This just returns a cached value after it + // has been generated once in the view. + idRenderModel *model = R_EntityDefDynamicModel( entityDef ); + if ( model == NULL || model->NumSurfaces() <= 0 ) { + return; + } + + // the dynamic model may have changed since we built the surface list + if ( !IsDeferred() && entityDef->dynamicModelFrameCount != dynamicModelFrameCount ) { + FreeSurfaces(); + } + dynamicModelFrameCount = entityDef->dynamicModelFrameCount; + + // actually create the interaction if needed, building light and shadow surfaces as needed + if ( IsDeferred() ) { + CreateInteraction( model ); + } + + R_GlobalPointToLocal( vEntity->modelMatrix, lightDef->globalLightOrigin, localLightOrigin ); + R_GlobalPointToLocal( vEntity->modelMatrix, tr.viewDef->renderView.vieworg, localViewOrigin ); + + // calculate the scissor as the intersection of the light and model rects + // this is used for light triangles, but not for shadow triangles + lightScissor = vLight->scissorRect; + lightScissor.Intersect( vEntity->scissorRect ); + + bool lightScissorsEmpty = lightScissor.IsEmpty(); + + // for each surface of this entity / light interaction + for ( int i = 0; i < numSurfaces; i++ ) { + surfaceInteraction_t *sint = &surfaces[i]; + + // see if the base surface is visible, we may still need to add shadows even if empty + if ( !lightScissorsEmpty && sint->ambientTris && sint->ambientTris->ambientViewCount == tr.viewCount ) { + + // make sure we have created this interaction, which may have been deferred + // on a previous use that only needed the shadow + if ( sint->lightTris == LIGHT_TRIS_DEFERRED ) { + sint->lightTris = R_CreateLightTris( vEntity->entityDef, sint->ambientTris, vLight->lightDef, sint->shader, sint->cullInfo ); + R_FreeInteractionCullInfo( sint->cullInfo ); + } + + srfTriangles_t *lightTris = sint->lightTris; + + if ( lightTris ) { + + // try to cull before adding + // FIXME: this may not be worthwhile. We have already done culling on the ambient, + // but individual surfaces may still be cropped somewhat more + if ( !R_CullLocalBox( lightTris->bounds, vEntity->modelMatrix, 5, tr.viewDef->frustum ) ) { + + // make sure the original surface has its ambient cache created + srfTriangles_t *tri = sint->ambientTris; + if ( !tri->ambientCache ) { + if ( !R_CreateAmbientCache( tri, sint->shader->ReceivesLighting() ) ) { + // skip if we were out of vertex memory + continue; + } + } + + // reference the original surface's ambient cache + lightTris->ambientCache = tri->ambientCache; + + // touch the ambient surface so it won't get purged + vertexCache.Touch( lightTris->ambientCache ); + + // regenerate the lighting cache (for non-vertex program cards) if it has been purged + if ( !lightTris->lightingCache ) { + if ( !R_CreateLightingCache( entityDef, lightDef, lightTris ) ) { + // skip if we are out of vertex memory + continue; + } + } + // touch the light surface so it won't get purged + // (vertex program cards won't have a light cache at all) + if ( lightTris->lightingCache ) { + vertexCache.Touch( lightTris->lightingCache ); + } + + if ( !lightTris->indexCache && r_useIndexBuffers.GetBool() ) { + vertexCache.Alloc( lightTris->indexes, lightTris->numIndexes * sizeof( lightTris->indexes[0] ), &lightTris->indexCache, true ); + } + if ( lightTris->indexCache ) { + vertexCache.Touch( lightTris->indexCache ); + } + + // add the surface to the light list + + const idMaterial *shader = sint->shader; + R_GlobalShaderOverride( &shader ); + + // there will only be localSurfaces if the light casts shadows and + // there are surfaces with NOSELFSHADOW + if ( sint->shader->Coverage() == MC_TRANSLUCENT ) { + R_LinkLightSurf( &vLight->translucentInteractions, lightTris, + vEntity, lightDef, shader, lightScissor, false ); + } else if ( !lightDef->parms.noShadows && sint->shader->TestMaterialFlag(MF_NOSELFSHADOW) ) { + R_LinkLightSurf( &vLight->localInteractions, lightTris, + vEntity, lightDef, shader, lightScissor, false ); + } else { + R_LinkLightSurf( &vLight->globalInteractions, lightTris, + vEntity, lightDef, shader, lightScissor, false ); + } + } + } + } + + srfTriangles_t *shadowTris = sint->shadowTris; + + // the shadows will always have to be added, unless we can tell they + // are from a surface in an unconnected area + if ( shadowTris ) { + + // check for view specific shadow suppression (player shadows, etc) + if ( !r_skipSuppress.GetBool() ) { + if ( entityDef->parms.suppressShadowInViewID && + entityDef->parms.suppressShadowInViewID == tr.viewDef->renderView.viewID ) { + continue; + } + if ( entityDef->parms.suppressShadowInLightID && + entityDef->parms.suppressShadowInLightID == lightDef->parms.lightId ) { + continue; + } + } + + // cull static shadows that have a non-empty bounds + // dynamic shadows that use the turboshadow code will not have valid + // bounds, because the perspective projection extends them to infinity + if ( r_useShadowCulling.GetBool() && !shadowTris->bounds.IsCleared() ) { + if ( R_CullLocalBox( shadowTris->bounds, vEntity->modelMatrix, 5, tr.viewDef->frustum ) ) { + continue; + } + } + + // copy the shadow vertexes to the vertex cache if they have been purged + + // if we are using shared shadowVertexes and letting a vertex program fix them up, + // get the shadowCache from the parent ambient surface + if ( !shadowTris->shadowVertexes ) { + // the data may have been purged, so get the latest from the "home position" + shadowTris->shadowCache = sint->ambientTris->shadowCache; + } + + // if we have been purged, re-upload the shadowVertexes + if ( !shadowTris->shadowCache ) { + if ( shadowTris->shadowVertexes ) { + // each interaction has unique vertexes + R_CreatePrivateShadowCache( shadowTris ); + } else { + R_CreateVertexProgramShadowCache( sint->ambientTris ); + shadowTris->shadowCache = sint->ambientTris->shadowCache; + } + // if we are out of vertex cache space, skip the interaction + if ( !shadowTris->shadowCache ) { + continue; + } + } + + // touch the shadow surface so it won't get purged + vertexCache.Touch( shadowTris->shadowCache ); + + if ( !shadowTris->indexCache && r_useIndexBuffers.GetBool() ) { + vertexCache.Alloc( shadowTris->indexes, shadowTris->numIndexes * sizeof( shadowTris->indexes[0] ), &shadowTris->indexCache, true ); + vertexCache.Touch( shadowTris->indexCache ); + } + + // see if we can avoid using the shadow volume caps + bool inside = R_PotentiallyInsideInfiniteShadow( sint->ambientTris, localViewOrigin, localLightOrigin ); + + if ( sint->shader->TestMaterialFlag( MF_NOSELFSHADOW ) ) { + R_LinkLightSurf( &vLight->localShadows, + shadowTris, vEntity, lightDef, NULL, shadowScissor, inside ); + } else { + R_LinkLightSurf( &vLight->globalShadows, + shadowTris, vEntity, lightDef, NULL, shadowScissor, inside ); + } + } + } +} + +/* +=================== +R_ShowInteractionMemory_f +=================== +*/ +void R_ShowInteractionMemory_f( const idCmdArgs &args ) { + int total = 0; + int entities = 0; + int interactions = 0; + int deferredInteractions = 0; + int emptyInteractions = 0; + int lightTris = 0; + int lightTriVerts = 0; + int lightTriIndexes = 0; + int shadowTris = 0; + int shadowTriVerts = 0; + int shadowTriIndexes = 0; + + for ( int i = 0; i < tr.primaryWorld->entityDefs.Num(); i++ ) { + idRenderEntityLocal *def = tr.primaryWorld->entityDefs[i]; + if ( !def ) { + continue; + } + if ( def->firstInteraction == NULL ) { + continue; + } + entities++; + + for ( idInteraction *inter = def->firstInteraction; inter != NULL; inter = inter->entityNext ) { + interactions++; + total += inter->MemoryUsed(); + + if ( inter->IsDeferred() ) { + deferredInteractions++; + continue; + } + if ( inter->IsEmpty() ) { + emptyInteractions++; + continue; + } + + for ( int j = 0; j < inter->numSurfaces; j++ ) { + surfaceInteraction_t *srf = &inter->surfaces[j]; + + if ( srf->lightTris && srf->lightTris != LIGHT_TRIS_DEFERRED ) { + lightTris++; + lightTriVerts += srf->lightTris->numVerts; + lightTriIndexes += srf->lightTris->numIndexes; + } + if ( srf->shadowTris ) { + shadowTris++; + shadowTriVerts += srf->shadowTris->numVerts; + shadowTriIndexes += srf->shadowTris->numIndexes; + } + } + } + } + + common->Printf( "%i entities with %i total interactions totalling %ik\n", entities, interactions, total / 1024 ); + common->Printf( "%i deferred interactions, %i empty interactions\n", deferredInteractions, emptyInteractions ); + common->Printf( "%5i indexes %5i verts in %5i light tris\n", lightTriIndexes, lightTriVerts, lightTris ); + common->Printf( "%5i indexes %5i verts in %5i shadow tris\n", shadowTriIndexes, shadowTriVerts, shadowTris ); +} diff --git a/renderer/Interaction.h b/renderer/Interaction.h new file mode 100644 index 000000000..f827c4e58 --- /dev/null +++ b/renderer/Interaction.h @@ -0,0 +1,175 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __INTERACTION_H__ +#define __INTERACTION_H__ + +/* +=============================================================================== + + Interaction between entityDef surfaces and a lightDef. + + Interactions with no lightTris and no shadowTris are still + valid, because they show that a given entityDef / lightDef + do not interact, even though they share one or more areas. + +=============================================================================== +*/ + +#define LIGHT_TRIS_DEFERRED ((srfTriangles_t *)-1) +#define LIGHT_CULL_ALL_FRONT ((byte *)-1) +#define LIGHT_CLIP_EPSILON 0.1f + + +typedef struct { + // For each triangle a byte set to 1 if facing the light origin. + byte * facing; + + // For each vertex a byte with the bits [0-5] set if the + // vertex is at the back side of the corresponding clip plane. + // If the 'cullBits' pointer equals LIGHT_CULL_ALL_FRONT all + // vertices are at the front of all the clip planes. + byte * cullBits; + + // Clip planes in surface space used to calculate the cull bits. + idPlane localClipPlanes[6]; +} srfCullInfo_t; + + +typedef struct { + // if lightTris == LIGHT_TRIS_DEFERRED, then the calculation of the + // lightTris has been deferred, and must be done if ambientTris is visible + srfTriangles_t * lightTris; + + // shadow volume triangle surface + srfTriangles_t * shadowTris; + + // so we can check ambientViewCount before adding lightTris, and get + // at the shared vertex and possibly shadowVertex caches + srfTriangles_t * ambientTris; + + const idMaterial * shader; + + int expCulled; // only for the experimental shadow buffer renderer + + srfCullInfo_t cullInfo; +} surfaceInteraction_t; + + +typedef struct areaNumRef_s { + struct areaNumRef_s * next; + int areaNum; +} areaNumRef_t; + + +class idRenderEntityLocal; +class idRenderLightLocal; + +class idInteraction { +public: + // this may be 0 if the light and entity do not actually intersect + // -1 = an untested interaction + int numSurfaces; + + // if there is a whole-entity optimized shadow hull, it will + // be present as a surfaceInteraction_t with a NULL ambientTris, but + // possibly having a shader to specify the shadow sorting order + surfaceInteraction_t * surfaces; + + // get space from here, if NULL, it is a pre-generated shadow volume from dmap + idRenderEntityLocal * entityDef; + idRenderLightLocal * lightDef; + + idInteraction * lightNext; // for lightDef chains + idInteraction * lightPrev; + idInteraction * entityNext; // for entityDef chains + idInteraction * entityPrev; + +public: + idInteraction( void ); + + // because these are generated and freed each game tic for active elements all + // over the world, we use a custom pool allocater to avoid memory allocation overhead + // and fragmentation + static idInteraction * AllocAndLink( idRenderEntityLocal *edef, idRenderLightLocal *ldef ); + + // unlinks from the entity and light, frees all surfaceInteractions, + // and puts it back on the free list + void UnlinkAndFree( void ); + + // free the interaction surfaces + void FreeSurfaces( void ); + + // makes the interaction empty for when the light and entity do not actually intersect + // all empty interactions are linked at the end of the light's and entity's interaction list + void MakeEmpty( void ); + + // returns true if the interaction is empty + bool IsEmpty( void ) const { return ( numSurfaces == 0 ); } + + // returns true if the interaction is not yet completely created + bool IsDeferred( void ) const { return ( numSurfaces == -1 ); } + + // returns true if the interaction has shadows + bool HasShadows( void ) const; + + // counts up the memory used by all the surfaceInteractions, which + // will be used to determine when we need to start purging old interactions + int MemoryUsed( void ); + + // makes sure all necessary light surfaces and shadow surfaces are created, and + // calls R_LinkLightSurf() for each one + void AddActiveInteraction( void ); + +private: + enum { + FRUSTUM_UNINITIALIZED, + FRUSTUM_INVALID, + FRUSTUM_VALID, + FRUSTUM_VALIDAREAS, + } frustumState; + idFrustum frustum; // frustum which contains the interaction + areaNumRef_t * frustumAreas; // numbers of the areas the frustum touches + + int dynamicModelFrameCount; // so we can tell if a callback model animated + +private: + // actually create the interaction + void CreateInteraction( const idRenderModel *model ); + + // unlink from entity and light lists + void Unlink( void ); + + // try to determine if the entire interaction, including shadows, is guaranteed + // to be outside the view frustum + bool CullInteractionByViewFrustum( const idFrustum &viewFrustum ); + + // determine the minimum scissor rect that will include the interaction shadows + // projected to the bounds of the light + idScreenRect CalcInteractionScissorRectangle( const idFrustum &viewFrustum ); +}; + + +void R_CalcInteractionFacing( const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo ); +void R_CalcInteractionCullBits( const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo ); +void R_FreeInteractionCullInfo( srfCullInfo_t &cullInfo ); + +void R_ShowInteractionMemory_f( const idCmdArgs &args ); + +#endif /* !__INTERACTION_H__ */ diff --git a/renderer/Material.cpp b/renderer/Material.cpp new file mode 100644 index 000000000..03c562b9b --- /dev/null +++ b/renderer/Material.cpp @@ -0,0 +1,2727 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + +Any errors during parsing just set MF_DEFAULTED and return, rather than throwing +a hard error. This will cause the material to fall back to default material, +but otherwise let things continue. + +Each material may have a set of calculations that must be evaluated before +drawing with it. + +Every expression that a material uses can be evaluated at one time, which +will allow for perfect common subexpression removal when I get around to +writing it. + +Without this, scrolling an entire surface could result in evaluating the +same texture matrix calculations a half dozen times. + + Open question: should I allow arbitrary per-vertex color, texCoord, and vertex + calculations to be specified in the material code? + + Every stage will definately have a valid image pointer. + + We might want the ability to change the sort value based on conditionals, + but it could be a hassle to implement, + +*/ + +// keep all of these on the stack, when they are static it makes material parsing non-reentrant +typedef struct mtrParsingData_s { + bool registerIsTemporary[MAX_EXPRESSION_REGISTERS]; + float shaderRegisters[MAX_EXPRESSION_REGISTERS]; + expOp_t shaderOps[MAX_EXPRESSION_OPS]; + shaderStage_t parseStages[MAX_SHADER_STAGES]; + + bool registersAreConstant; + bool forceOverlays; +} mtrParsingData_t; + + +/* +============= +idMaterial::CommonInit +============= +*/ +void idMaterial::CommonInit() { + desc = ""; + renderBump = ""; + contentFlags = CONTENTS_SOLID; + surfaceFlags = SURFTYPE_NONE; + materialFlags = 0; + sort = SS_BAD; + coverage = MC_BAD; + cullType = CT_FRONT_SIDED; + deform = DFRM_NONE; + numOps = 0; + ops = NULL; + numRegisters = 0; + expressionRegisters = NULL; + constantRegisters = NULL; + numStages = 0; + numAmbientStages = 0; + stages = NULL; + editorImage = NULL; + lightFalloffImage = NULL; + shouldCreateBackSides = false; + entityGui = 0; + fogLight = false; + blendLight = false; + ambientLight = false; + noFog = false; + hasSubview = false; + allowOverlays = true; + unsmoothedTangents = false; + gui = NULL; + memset( deformRegisters, 0, sizeof( deformRegisters ) ); + editorAlpha = 1.0; + spectrum = 0; + polygonOffset = 0; + suppressInSubview = false; + refCount = 0; + portalSky = false; + + decalInfo.stayTime = 10000; + decalInfo.fadeTime = 4000; + decalInfo.start[0] = 1; + decalInfo.start[1] = 1; + decalInfo.start[2] = 1; + decalInfo.start[3] = 1; + decalInfo.end[0] = 0; + decalInfo.end[1] = 0; + decalInfo.end[2] = 0; + decalInfo.end[3] = 0; +} + +/* +============= +idMaterial::idMaterial +============= +*/ +idMaterial::idMaterial() { + CommonInit(); + + // we put this here instead of in CommonInit, because + // we don't want it cleared when a material is purged + surfaceArea = 0; +} + +/* +============= +idMaterial::~idMaterial +============= +*/ +idMaterial::~idMaterial() { +} + +/* +=============== +idMaterial::FreeData +=============== +*/ +void idMaterial::FreeData() { + int i; + + if ( stages ) { + // delete any idCinematic textures + for ( i = 0; i < numStages; i++ ) { + if ( stages[i].texture.cinematic != NULL ) { + delete stages[i].texture.cinematic; + stages[i].texture.cinematic = NULL; + } + if ( stages[i].newStage != NULL ) { + Mem_Free( stages[i].newStage ); + stages[i].newStage = NULL; + } + } + R_StaticFree( stages ); + stages = NULL; + } + if ( expressionRegisters != NULL ) { + R_StaticFree( expressionRegisters ); + expressionRegisters = NULL; + } + if ( constantRegisters != NULL ) { + R_StaticFree( constantRegisters ); + constantRegisters = NULL; + } + if ( ops != NULL ) { + R_StaticFree( ops ); + ops = NULL; + } +} + +/* +============== +idMaterial::GetEditorImage +============== +*/ +idImage *idMaterial::GetEditorImage( void ) const { + if ( editorImage ) { + return editorImage; + } + + // if we don't have an editorImageName, use the first stage image + if ( !editorImageName.Length()) { + // _D3XP :: First check for a diffuse image, then use the first + if ( numStages && stages ) { + int i; + for( i = 0; i < numStages; i++ ) { + if ( stages[i].lighting == SL_DIFFUSE ) { + editorImage = stages[i].texture.image; + break; + } + } + if ( !editorImage ) { + editorImage = stages[0].texture.image; + } + } else { + editorImage = globalImages->defaultImage; + } + } else { + // look for an explicit one + editorImage = globalImages->ImageFromFile( editorImageName, TF_DEFAULT, true, TR_REPEAT, TD_DEFAULT ); + } + + if ( !editorImage ) { + editorImage = globalImages->defaultImage; + } + + return editorImage; +} + + +// info parms +typedef struct { + char *name; + int clearSolid, surfaceFlags, contents; +} infoParm_t; + +static infoParm_t infoParms[] = { + // game relevant attributes + {"solid", 0, 0, CONTENTS_SOLID }, // may need to override a clearSolid + {"water", 1, 0, CONTENTS_WATER }, // used for water + {"playerclip", 0, 0, CONTENTS_PLAYERCLIP }, // solid to players + {"monsterclip", 0, 0, CONTENTS_MONSTERCLIP }, // solid to monsters + {"moveableclip",0, 0, CONTENTS_MOVEABLECLIP },// solid to moveable entities + {"ikclip", 0, 0, CONTENTS_IKCLIP }, // solid to IK + {"blood", 0, 0, CONTENTS_BLOOD }, // used to detect blood decals + {"trigger", 0, 0, CONTENTS_TRIGGER }, // used for triggers + {"aassolid", 0, 0, CONTENTS_AAS_SOLID }, // solid for AAS + {"aasobstacle", 0, 0, CONTENTS_AAS_OBSTACLE },// used to compile an obstacle into AAS that can be enabled/disabled + {"flashlight_trigger", 0, 0, CONTENTS_FLASHLIGHT_TRIGGER }, // used for triggers that are activated by the flashlight + {"nonsolid", 1, 0, 0 }, // clears the solid flag + {"nullNormal", 0, SURF_NULLNORMAL,0 }, // renderbump will draw as 0x80 0x80 0x80 + + // utility relevant attributes + {"areaportal", 1, 0, CONTENTS_AREAPORTAL }, // divides areas + {"qer_nocarve", 1, 0, CONTENTS_NOCSG}, // don't cut brushes in editor + + {"discrete", 1, SURF_DISCRETE, 0 }, // surfaces should not be automatically merged together or + // clipped to the world, + // because they represent discrete objects like gui shaders + // mirrors, or autosprites + {"noFragment", 0, SURF_NOFRAGMENT, 0 }, + + {"slick", 0, SURF_SLICK, 0 }, + {"collision", 0, SURF_COLLISION, 0 }, + {"noimpact", 0, SURF_NOIMPACT, 0 }, // don't make impact explosions or marks + {"nodamage", 0, SURF_NODAMAGE, 0 }, // no falling damage when hitting + {"ladder", 0, SURF_LADDER, 0 }, // climbable + {"nosteps", 0, SURF_NOSTEPS, 0 }, // no footsteps + + // material types for particle, sound, footstep feedback + {"metal", 0, SURFTYPE_METAL, 0 }, // metal + {"stone", 0, SURFTYPE_STONE, 0 }, // stone + {"flesh", 0, SURFTYPE_FLESH, 0 }, // flesh + {"wood", 0, SURFTYPE_WOOD, 0 }, // wood + {"cardboard", 0, SURFTYPE_CARDBOARD, 0 }, // cardboard + {"liquid", 0, SURFTYPE_LIQUID, 0 }, // liquid + {"glass", 0, SURFTYPE_GLASS, 0 }, // glass + {"plastic", 0, SURFTYPE_PLASTIC, 0 }, // plastic + {"ricochet", 0, SURFTYPE_RICOCHET, 0 }, // behaves like metal but causes a ricochet sound + + // unassigned surface types + {"surftype10", 0, SURFTYPE_10, 0 }, + {"surftype11", 0, SURFTYPE_11, 0 }, + {"surftype12", 0, SURFTYPE_12, 0 }, + {"surftype13", 0, SURFTYPE_13, 0 }, + {"surftype14", 0, SURFTYPE_14, 0 }, + {"surftype15", 0, SURFTYPE_15, 0 }, +}; + +static const int numInfoParms = sizeof(infoParms) / sizeof (infoParms[0]); + + +/* +=============== +idMaterial::CheckSurfaceParm + +See if the current token matches one of the surface parm bit flags +=============== +*/ +bool idMaterial::CheckSurfaceParm( idToken *token ) { + + for ( int i = 0 ; i < numInfoParms ; i++ ) { + if ( !token->Icmp( infoParms[i].name ) ) { + if ( infoParms[i].surfaceFlags & SURF_TYPE_MASK ) { + // ensure we only have one surface type set + surfaceFlags &= ~SURF_TYPE_MASK; + } + surfaceFlags |= infoParms[i].surfaceFlags; + contentFlags |= infoParms[i].contents; + if ( infoParms[i].clearSolid ) { + contentFlags &= ~CONTENTS_SOLID; + } + return true; + } + } + return false; +} + +/* +=============== +idMaterial::MatchToken + +Sets defaultShader and returns false if the next token doesn't match +=============== +*/ +bool idMaterial::MatchToken( idLexer &src, const char *match ) { + if ( !src.ExpectTokenString( match ) ) { + SetMaterialFlag( MF_DEFAULTED ); + return false; + } + return true; +} + +/* +================= +idMaterial::ParseSort +================= +*/ +void idMaterial::ParseSort( idLexer &src ) { + idToken token; + + if ( !src.ReadTokenOnLine( &token ) ) { + src.Warning( "missing sort parameter" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + + if ( !token.Icmp( "subview" ) ) { + sort = SS_SUBVIEW; + } else if ( !token.Icmp( "opaque" ) ) { + sort = SS_OPAQUE; + }else if ( !token.Icmp( "decal" ) ) { + sort = SS_DECAL; + } else if ( !token.Icmp( "far" ) ) { + sort = SS_FAR; + } else if ( !token.Icmp( "medium" ) ) { + sort = SS_MEDIUM; + } else if ( !token.Icmp( "close" ) ) { + sort = SS_CLOSE; + } else if ( !token.Icmp( "almostNearest" ) ) { + sort = SS_ALMOST_NEAREST; + } else if ( !token.Icmp( "nearest" ) ) { + sort = SS_NEAREST; + } else if ( !token.Icmp( "postProcess" ) ) { + sort = SS_POST_PROCESS; + } else if ( !token.Icmp( "portalSky" ) ) { + sort = SS_PORTAL_SKY; + } else { + sort = atof( token ); + } +} + +/* +================= +idMaterial::ParseDecalInfo +================= +*/ +void idMaterial::ParseDecalInfo( idLexer &src ) { + idToken token; + + decalInfo.stayTime = src.ParseFloat() * 1000; + decalInfo.fadeTime = src.ParseFloat() * 1000; + float start[4], end[4]; + src.Parse1DMatrix( 4, start ); + src.Parse1DMatrix( 4, end ); + for ( int i = 0 ; i < 4 ; i++ ) { + decalInfo.start[i] = start[i]; + decalInfo.end[i] = end[i]; + } +} + +/* +============= +idMaterial::GetExpressionConstant +============= +*/ +int idMaterial::GetExpressionConstant( float f ) { + int i; + + for ( i = EXP_REG_NUM_PREDEFINED ; i < numRegisters ; i++ ) { + if ( !pd->registerIsTemporary[i] && pd->shaderRegisters[i] == f ) { + return i; + } + } + if ( numRegisters == MAX_EXPRESSION_REGISTERS ) { + common->Warning( "GetExpressionConstant: material '%s' hit MAX_EXPRESSION_REGISTERS", GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + return 0; + } + pd->registerIsTemporary[i] = false; + pd->shaderRegisters[i] = f; + numRegisters++; + + return i; +} + +/* +============= +idMaterial::GetExpressionTemporary +============= +*/ +int idMaterial::GetExpressionTemporary( void ) { + if ( numRegisters == MAX_EXPRESSION_REGISTERS ) { + common->Warning( "GetExpressionTemporary: material '%s' hit MAX_EXPRESSION_REGISTERS", GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + return 0; + } + pd->registerIsTemporary[numRegisters] = true; + numRegisters++; + return numRegisters - 1; +} + +/* +============= +idMaterial::GetExpressionOp +============= +*/ +expOp_t *idMaterial::GetExpressionOp( void ) { + if ( numOps == MAX_EXPRESSION_OPS ) { + common->Warning( "GetExpressionOp: material '%s' hit MAX_EXPRESSION_OPS", GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + return &pd->shaderOps[0]; + } + + return &pd->shaderOps[numOps++]; +} + +/* +================= +idMaterial::EmitOp +================= +*/ +int idMaterial::EmitOp( int a, int b, expOpType_t opType ) { + expOp_t *op; + + // optimize away identity operations + if ( opType == OP_TYPE_ADD ) { + if ( !pd->registerIsTemporary[a] && pd->shaderRegisters[a] == 0 ) { + return b; + } + if ( !pd->registerIsTemporary[b] && pd->shaderRegisters[b] == 0 ) { + return a; + } + if ( !pd->registerIsTemporary[a] && !pd->registerIsTemporary[b] ) { + return GetExpressionConstant( pd->shaderRegisters[a] + pd->shaderRegisters[b] ); + } + } + if ( opType == OP_TYPE_MULTIPLY ) { + if ( !pd->registerIsTemporary[a] && pd->shaderRegisters[a] == 1 ) { + return b; + } + if ( !pd->registerIsTemporary[a] && pd->shaderRegisters[a] == 0 ) { + return a; + } + if ( !pd->registerIsTemporary[b] && pd->shaderRegisters[b] == 1 ) { + return a; + } + if ( !pd->registerIsTemporary[b] && pd->shaderRegisters[b] == 0 ) { + return b; + } + if ( !pd->registerIsTemporary[a] && !pd->registerIsTemporary[b] ) { + return GetExpressionConstant( pd->shaderRegisters[a] * pd->shaderRegisters[b] ); + } + } + + op = GetExpressionOp(); + op->opType = opType; + op->a = a; + op->b = b; + op->c = GetExpressionTemporary(); + + return op->c; +} + +/* +================= +idMaterial::ParseEmitOp +================= +*/ +int idMaterial::ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority ) { + int b; + + b = ParseExpressionPriority( src, priority ); + return EmitOp( a, b, opType ); +} + +/* +================= +idMaterial::ParseTerm + +Returns a register index +================= +*/ +int idMaterial::ParseTerm( idLexer &src ) { + idToken token; + int a, b; + + src.ReadToken( &token ); + + if ( token == "(" ) { + a = ParseExpression( src ); + MatchToken( src, ")" ); + return a; + } + + if ( !token.Icmp( "time" ) ) { + pd->registersAreConstant = false; + return EXP_REG_TIME; + } + if ( !token.Icmp( "parm0" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM0; + } + if ( !token.Icmp( "parm1" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM1; + } + if ( !token.Icmp( "parm2" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM2; + } + if ( !token.Icmp( "parm3" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM3; + } + if ( !token.Icmp( "parm4" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM4; + } + if ( !token.Icmp( "parm5" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM5; + } + if ( !token.Icmp( "parm6" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM6; + } + if ( !token.Icmp( "parm7" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM7; + } + if ( !token.Icmp( "parm8" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM8; + } + if ( !token.Icmp( "parm9" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM9; + } + if ( !token.Icmp( "parm10" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM10; + } + if ( !token.Icmp( "parm11" ) ) { + pd->registersAreConstant = false; + return EXP_REG_PARM11; + } + if ( !token.Icmp( "global0" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL0; + } + if ( !token.Icmp( "global1" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL1; + } + if ( !token.Icmp( "global2" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL2; + } + if ( !token.Icmp( "global3" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL3; + } + if ( !token.Icmp( "global4" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL4; + } + if ( !token.Icmp( "global5" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL5; + } + if ( !token.Icmp( "global6" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL6; + } + if ( !token.Icmp( "global7" ) ) { + pd->registersAreConstant = false; + return EXP_REG_GLOBAL7; + } + if ( !token.Icmp( "fragmentPrograms" ) ) { + return GetExpressionConstant( (float) glConfig.ARBFragmentProgramAvailable ); + } + + if ( !token.Icmp( "sound" ) ) { + pd->registersAreConstant = false; + return EmitOp( 0, 0, OP_TYPE_SOUND ); + } + + // parse negative numbers + if ( token == "-" ) { + src.ReadToken( &token ); + if ( token.type == TT_NUMBER || token == "." ) { + return GetExpressionConstant( -(float) token.GetFloatValue() ); + } + src.Warning( "Bad negative number '%s'", token.c_str() ); + SetMaterialFlag( MF_DEFAULTED ); + return 0; + } + + if ( token.type == TT_NUMBER || token == "." || token == "-" ) { + return GetExpressionConstant( (float) token.GetFloatValue() ); + } + + // see if it is a table name + const idDeclTable *table = static_cast( declManager->FindType( DECL_TABLE, token.c_str(), false ) ); + if ( !table ) { + src.Warning( "Bad term '%s'", token.c_str() ); + SetMaterialFlag( MF_DEFAULTED ); + return 0; + } + + // parse a table expression + MatchToken( src, "[" ); + + b = ParseExpression( src ); + + MatchToken( src, "]" ); + + return EmitOp( table->Index(), b, OP_TYPE_TABLE ); +} + +/* +================= +idMaterial::ParseExpressionPriority + +Returns a register index +================= +*/ +#define TOP_PRIORITY 4 +int idMaterial::ParseExpressionPriority( idLexer &src, int priority ) { + idToken token; + int a; + + if ( priority == 0 ) { + return ParseTerm( src ); + } + + a = ParseExpressionPriority( src, priority - 1 ); + + if ( TestMaterialFlag( MF_DEFAULTED ) ) { // we have a parse error + return 0; + } + + if ( !src.ReadToken( &token ) ) { + // we won't get EOF in a real file, but we can + // when parsing from generated strings + return a; + } + + if ( priority == 1 && token == "*" ) { + return ParseEmitOp( src, a, OP_TYPE_MULTIPLY, priority ); + } + if ( priority == 1 && token == "/" ) { + return ParseEmitOp( src, a, OP_TYPE_DIVIDE, priority ); + } + if ( priority == 1 && token == "%" ) { // implied truncate both to integer + return ParseEmitOp( src, a, OP_TYPE_MOD, priority ); + } + if ( priority == 2 && token == "+" ) { + return ParseEmitOp( src, a, OP_TYPE_ADD, priority ); + } + if ( priority == 2 && token == "-" ) { + return ParseEmitOp( src, a, OP_TYPE_SUBTRACT, priority ); + } + if ( priority == 3 && token == ">" ) { + return ParseEmitOp( src, a, OP_TYPE_GT, priority ); + } + if ( priority == 3 && token == ">=" ) { + return ParseEmitOp( src, a, OP_TYPE_GE, priority ); + } + if ( priority == 3 && token == "<" ) { + return ParseEmitOp( src, a, OP_TYPE_LT, priority ); + } + if ( priority == 3 && token == "<=" ) { + return ParseEmitOp( src, a, OP_TYPE_LE, priority ); + } + if ( priority == 3 && token == "==" ) { + return ParseEmitOp( src, a, OP_TYPE_EQ, priority ); + } + if ( priority == 3 && token == "!=" ) { + return ParseEmitOp( src, a, OP_TYPE_NE, priority ); + } + if ( priority == 4 && token == "&&" ) { + return ParseEmitOp( src, a, OP_TYPE_AND, priority ); + } + if ( priority == 4 && token == "||" ) { + return ParseEmitOp( src, a, OP_TYPE_OR, priority ); + } + + // assume that anything else terminates the expression + // not too robust error checking... + + src.UnreadToken( &token ); + + return a; +} + +/* +================= +idMaterial::ParseExpression + +Returns a register index +================= +*/ +int idMaterial::ParseExpression( idLexer &src ) { + return ParseExpressionPriority( src, TOP_PRIORITY ); +} + + +/* +=============== +idMaterial::ClearStage +=============== +*/ +void idMaterial::ClearStage( shaderStage_t *ss ) { + ss->drawStateBits = 0; + ss->conditionRegister = GetExpressionConstant( 1 ); + ss->color.registers[0] = + ss->color.registers[1] = + ss->color.registers[2] = + ss->color.registers[3] = GetExpressionConstant( 1 ); +} + +/* +=============== +idMaterial::NameToSrcBlendMode +=============== +*/ +int idMaterial::NameToSrcBlendMode( const idStr &name ) { + if ( !name.Icmp( "GL_ONE" ) ) { + return GLS_SRCBLEND_ONE; + } else if ( !name.Icmp( "GL_ZERO" ) ) { + return GLS_SRCBLEND_ZERO; + } else if ( !name.Icmp( "GL_DST_COLOR" ) ) { + return GLS_SRCBLEND_DST_COLOR; + } else if ( !name.Icmp( "GL_ONE_MINUS_DST_COLOR" ) ) { + return GLS_SRCBLEND_ONE_MINUS_DST_COLOR; + } else if ( !name.Icmp( "GL_SRC_ALPHA" ) ) { + return GLS_SRCBLEND_SRC_ALPHA; + } else if ( !name.Icmp( "GL_ONE_MINUS_SRC_ALPHA" ) ) { + return GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA; + } else if ( !name.Icmp( "GL_DST_ALPHA" ) ) { + return GLS_SRCBLEND_DST_ALPHA; + } else if ( !name.Icmp( "GL_ONE_MINUS_DST_ALPHA" ) ) { + return GLS_SRCBLEND_ONE_MINUS_DST_ALPHA; + } else if ( !name.Icmp( "GL_SRC_ALPHA_SATURATE" ) ) { + return GLS_SRCBLEND_ALPHA_SATURATE; + } + + common->Warning( "unknown blend mode '%s' in material '%s'", name.c_str(), GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + + return GLS_SRCBLEND_ONE; +} + +/* +=============== +idMaterial::NameToDstBlendMode +=============== +*/ +int idMaterial::NameToDstBlendMode( const idStr &name ) { + if ( !name.Icmp( "GL_ONE" ) ) { + return GLS_DSTBLEND_ONE; + } else if ( !name.Icmp( "GL_ZERO" ) ) { + return GLS_DSTBLEND_ZERO; + } else if ( !name.Icmp( "GL_SRC_ALPHA" ) ) { + return GLS_DSTBLEND_SRC_ALPHA; + } else if ( !name.Icmp( "GL_ONE_MINUS_SRC_ALPHA" ) ) { + return GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA; + } else if ( !name.Icmp( "GL_DST_ALPHA" ) ) { + return GLS_DSTBLEND_DST_ALPHA; + } else if ( !name.Icmp( "GL_ONE_MINUS_DST_ALPHA" ) ) { + return GLS_DSTBLEND_ONE_MINUS_DST_ALPHA; + } else if ( !name.Icmp( "GL_SRC_COLOR" ) ) { + return GLS_DSTBLEND_SRC_COLOR; + } else if ( !name.Icmp( "GL_ONE_MINUS_SRC_COLOR" ) ) { + return GLS_DSTBLEND_ONE_MINUS_SRC_COLOR; + } + + common->Warning( "unknown blend mode '%s' in material '%s'", name.c_str(), GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + + return GLS_DSTBLEND_ONE; +} + +/* +================ +idMaterial::ParseBlend +================ +*/ +void idMaterial::ParseBlend( idLexer &src, shaderStage_t *stage ) { + idToken token; + int srcBlend, dstBlend; + + if ( !src.ReadToken( &token ) ) { + return; + } + + // blending combinations + if ( !token.Icmp( "blend" ) ) { + stage->drawStateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA; + return; + } + if ( !token.Icmp( "add" ) ) { + stage->drawStateBits = GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE; + return; + } + if ( !token.Icmp( "filter" ) || !token.Icmp( "modulate" ) ) { + stage->drawStateBits = GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO; + return; + } + if ( !token.Icmp( "none" ) ) { + // none is used when defining an alpha mask that doesn't draw + stage->drawStateBits = GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE; + return; + } + if ( !token.Icmp( "bumpmap" ) ) { + stage->lighting = SL_BUMP; + return; + } + if ( !token.Icmp( "diffusemap" ) ) { + stage->lighting = SL_DIFFUSE; + return; + } + if ( !token.Icmp( "specularmap" ) ) { + stage->lighting = SL_SPECULAR; + return; + } + + srcBlend = NameToSrcBlendMode( token ); + + MatchToken( src, "," ); + if ( !src.ReadToken( &token ) ) { + return; + } + dstBlend = NameToDstBlendMode( token ); + + stage->drawStateBits = srcBlend | dstBlend; +} + +/* +================ +idMaterial::ParseVertexParm + +If there is a single value, it will be repeated across all elements +If there are two values, 3 = 0.0, 4 = 1.0 +if there are three values, 4 = 1.0 +================ +*/ +void idMaterial::ParseVertexParm( idLexer &src, newShaderStage_t *newStage ) { + idToken token; + + src.ReadTokenOnLine( &token ); + int parm = token.GetIntValue(); + if ( !token.IsNumeric() || parm < 0 || parm >= MAX_VERTEX_PARMS ) { + common->Warning( "bad vertexParm number\n" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + if ( parm >= newStage->numVertexParms ) { + newStage->numVertexParms = parm+1; + } + + newStage->vertexParms[parm][0] = ParseExpression( src ); + + src.ReadTokenOnLine( &token ); + if ( !token[0] || token.Icmp( "," ) ) { + newStage->vertexParms[parm][1] = + newStage->vertexParms[parm][2] = + newStage->vertexParms[parm][3] = newStage->vertexParms[parm][0]; + return; + } + + newStage->vertexParms[parm][1] = ParseExpression( src ); + + src.ReadTokenOnLine( &token ); + if ( !token[0] || token.Icmp( "," ) ) { + newStage->vertexParms[parm][2] = GetExpressionConstant( 0 ); + newStage->vertexParms[parm][3] = GetExpressionConstant( 1 ); + return; + } + + newStage->vertexParms[parm][2] = ParseExpression( src ); + + src.ReadTokenOnLine( &token ); + if ( !token[0] || token.Icmp( "," ) ) { + newStage->vertexParms[parm][3] = GetExpressionConstant( 1 ); + return; + } + + newStage->vertexParms[parm][3] = ParseExpression( src ); +} + + +/* +================ +idMaterial::ParseFragmentMap +================ +*/ +void idMaterial::ParseFragmentMap( idLexer &src, newShaderStage_t *newStage ) { + const char *str; + textureFilter_t tf; + textureRepeat_t trp; + textureDepth_t td; + cubeFiles_t cubeMap; + bool allowPicmip; + idToken token; + + tf = TF_DEFAULT; + trp = TR_REPEAT; + td = TD_DEFAULT; + allowPicmip = true; + cubeMap = CF_2D; + + src.ReadTokenOnLine( &token ); + int unit = token.GetIntValue(); + if ( !token.IsNumeric() || unit < 0 || unit >= MAX_FRAGMENT_IMAGES ) { + common->Warning( "bad fragmentMap number\n" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + + // unit 1 is the normal map.. make sure it gets flagged as the proper depth + if ( unit == 1 ) { + td = TD_BUMP; + } + + if ( unit >= newStage->numFragmentProgramImages ) { + newStage->numFragmentProgramImages = unit+1; + } + + while( 1 ) { + src.ReadTokenOnLine( &token ); + + if ( !token.Icmp( "cubeMap" ) ) { + cubeMap = CF_NATIVE; + continue; + } + if ( !token.Icmp( "cameraCubeMap" ) ) { + cubeMap = CF_CAMERA; + continue; + } + if ( !token.Icmp( "nearest" ) ) { + tf = TF_NEAREST; + continue; + } + if ( !token.Icmp( "linear" ) ) { + tf = TF_LINEAR; + continue; + } + if ( !token.Icmp( "clamp" ) ) { + trp = TR_CLAMP; + continue; + } + if ( !token.Icmp( "noclamp" ) ) { + trp = TR_REPEAT; + continue; + } + if ( !token.Icmp( "zeroclamp" ) ) { + trp = TR_CLAMP_TO_ZERO; + continue; + } + if ( !token.Icmp( "alphazeroclamp" ) ) { + trp = TR_CLAMP_TO_ZERO_ALPHA; + continue; + } + if ( !token.Icmp( "forceHighQuality" ) ) { + td = TD_HIGH_QUALITY; + continue; + } + + if ( !token.Icmp( "uncompressed" ) || !token.Icmp( "highquality" ) ) { + if ( !globalImages->image_ignoreHighQuality.GetInteger() ) { + td = TD_HIGH_QUALITY; + } + continue; + } + if ( !token.Icmp( "nopicmip" ) ) { + allowPicmip = false; + continue; + } + + // assume anything else is the image name + src.UnreadToken( &token ); + break; + } + str = R_ParsePastImageProgram( src ); + + newStage->fragmentProgramImages[unit] = + globalImages->ImageFromFile( str, tf, allowPicmip, trp, td, cubeMap ); + if ( !newStage->fragmentProgramImages[unit] ) { + newStage->fragmentProgramImages[unit] = globalImages->defaultImage; + } +} + +/* +=============== +idMaterial::MultiplyTextureMatrix +=============== +*/ +void idMaterial::MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] ) { + int old[2][3]; + + if ( !ts->hasMatrix ) { + ts->hasMatrix = true; + memcpy( ts->matrix, registers, sizeof( ts->matrix ) ); + return; + } + + memcpy( old, ts->matrix, sizeof( old ) ); + + // multiply the two maticies + ts->matrix[0][0] = EmitOp( + EmitOp( old[0][0], registers[0][0], OP_TYPE_MULTIPLY ), + EmitOp( old[0][1], registers[1][0], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ); + ts->matrix[0][1] = EmitOp( + EmitOp( old[0][0], registers[0][1], OP_TYPE_MULTIPLY ), + EmitOp( old[0][1], registers[1][1], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ); + ts->matrix[0][2] = EmitOp( + EmitOp( + EmitOp( old[0][0], registers[0][2], OP_TYPE_MULTIPLY ), + EmitOp( old[0][1], registers[1][2], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ), + old[0][2], OP_TYPE_ADD ); + + ts->matrix[1][0] = EmitOp( + EmitOp( old[1][0], registers[0][0], OP_TYPE_MULTIPLY ), + EmitOp( old[1][1], registers[1][0], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ); + ts->matrix[1][1] = EmitOp( + EmitOp( old[1][0], registers[0][1], OP_TYPE_MULTIPLY ), + EmitOp( old[1][1], registers[1][1], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ); + ts->matrix[1][2] = EmitOp( + EmitOp( + EmitOp( old[1][0], registers[0][2], OP_TYPE_MULTIPLY ), + EmitOp( old[1][1], registers[1][2], OP_TYPE_MULTIPLY ), OP_TYPE_ADD ), + old[1][2], OP_TYPE_ADD ); + +} + +/* +================= +idMaterial::ParseStage + +An open brace has been parsed + + +{ + if + map + "nearest" "linear" "clamp" "zeroclamp" "uncompressed" "highquality" "nopicmip" + scroll, scale, rotate +} + +================= +*/ +void idMaterial::ParseStage( idLexer &src, const textureRepeat_t trpDefault ) { + idToken token; + const char *str; + shaderStage_t *ss; + textureStage_t *ts; + textureFilter_t tf; + textureRepeat_t trp; + textureDepth_t td; + cubeFiles_t cubeMap; + bool allowPicmip; + char imageName[MAX_IMAGE_NAME]; + int a, b; + int matrix[2][3]; + newShaderStage_t newStage; + + if ( numStages >= MAX_SHADER_STAGES ) { + SetMaterialFlag( MF_DEFAULTED ); + common->Warning( "material '%s' exceeded %i stages", GetName(), MAX_SHADER_STAGES ); + } + + tf = TF_DEFAULT; + trp = trpDefault; + td = TD_DEFAULT; + allowPicmip = true; + cubeMap = CF_2D; + + imageName[0] = 0; + + memset( &newStage, 0, sizeof( newStage ) ); + + ss = &pd->parseStages[numStages]; + ts = &ss->texture; + + ClearStage( ss ); + + while ( 1 ) { + if ( TestMaterialFlag( MF_DEFAULTED ) ) { // we have a parse error + return; + } + if ( !src.ExpectAnyToken( &token ) ) { + SetMaterialFlag( MF_DEFAULTED ); + return; + } + + // the close brace for the entire material ends the draw block + if ( token == "}" ) { + break; + } + + //BSM Nerve: Added for stage naming in the material editor + if( !token.Icmp( "name") ) { + src.SkipRestOfLine(); + continue; + } + + // image options + if ( !token.Icmp( "blend" ) ) { + ParseBlend( src, ss ); + continue; + } + + if ( !token.Icmp( "map" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::Copynz( imageName, str, sizeof( imageName ) ); + continue; + } + + if ( !token.Icmp( "remoteRenderMap" ) ) { + ts->dynamic = DI_REMOTE_RENDER; + ts->width = src.ParseInt(); + ts->height = src.ParseInt(); + continue; + } + + if ( !token.Icmp( "mirrorRenderMap" ) ) { + ts->dynamic = DI_MIRROR_RENDER; + ts->width = src.ParseInt(); + ts->height = src.ParseInt(); + ts->texgen = TG_SCREEN; + continue; + } + + if ( !token.Icmp( "xrayRenderMap" ) ) { + ts->dynamic = DI_XRAY_RENDER; + ts->width = src.ParseInt(); + ts->height = src.ParseInt(); + ts->texgen = TG_SCREEN; + continue; + } + if ( !token.Icmp( "screen" ) ) { + ts->texgen = TG_SCREEN; + continue; + } + if ( !token.Icmp( "screen2" ) ) { + ts->texgen = TG_SCREEN2; + continue; + } + if ( !token.Icmp( "glassWarp" ) ) { + ts->texgen = TG_GLASSWARP; + continue; + } + + if ( !token.Icmp( "videomap" ) ) { + // note that videomaps will always be in clamp mode, so texture + // coordinates had better be in the 0 to 1 range + if ( !src.ReadToken( &token ) ) { + common->Warning( "missing parameter for 'videoMap' keyword in material '%s'", GetName() ); + continue; + } + bool loop = false; + if ( !token.Icmp( "loop" ) ) { + loop = true; + if ( !src.ReadToken( &token ) ) { + common->Warning( "missing parameter for 'videoMap' keyword in material '%s'", GetName() ); + continue; + } + } + ts->cinematic = idCinematic::Alloc(); + ts->cinematic->InitFromFile( token.c_str(), loop ); + continue; + } + + if ( !token.Icmp( "soundmap" ) ) { + if ( !src.ReadToken( &token ) ) { + common->Warning( "missing parameter for 'soundmap' keyword in material '%s'", GetName() ); + continue; + } + ts->cinematic = new idSndWindow(); + ts->cinematic->InitFromFile( token.c_str(), true ); + continue; + } + + if ( !token.Icmp( "cubeMap" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::Copynz( imageName, str, sizeof( imageName ) ); + cubeMap = CF_NATIVE; + continue; + } + + if ( !token.Icmp( "cameraCubeMap" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::Copynz( imageName, str, sizeof( imageName ) ); + cubeMap = CF_CAMERA; + continue; + } + + if ( !token.Icmp( "ignoreAlphaTest" ) ) { + ss->ignoreAlphaTest = true; + continue; + } + if ( !token.Icmp( "nearest" ) ) { + tf = TF_NEAREST; + continue; + } + if ( !token.Icmp( "linear" ) ) { + tf = TF_LINEAR; + continue; + } + if ( !token.Icmp( "clamp" ) ) { + trp = TR_CLAMP; + continue; + } + if ( !token.Icmp( "noclamp" ) ) { + trp = TR_REPEAT; + continue; + } + if ( !token.Icmp( "zeroclamp" ) ) { + trp = TR_CLAMP_TO_ZERO; + continue; + } + if ( !token.Icmp( "alphazeroclamp" ) ) { + trp = TR_CLAMP_TO_ZERO_ALPHA; + continue; + } + if ( !token.Icmp( "uncompressed" ) || !token.Icmp( "highquality" ) ) { + if ( !globalImages->image_ignoreHighQuality.GetInteger() ) { + td = TD_HIGH_QUALITY; + } + continue; + } + if ( !token.Icmp( "forceHighQuality" ) ) { + td = TD_HIGH_QUALITY; + continue; + } + if ( !token.Icmp( "nopicmip" ) ) { + allowPicmip = false; + continue; + } + if ( !token.Icmp( "vertexColor" ) ) { + ss->vertexColor = SVC_MODULATE; + continue; + } + if ( !token.Icmp( "inverseVertexColor" ) ) { + ss->vertexColor = SVC_INVERSE_MODULATE; + continue; + } + + // privatePolygonOffset + else if ( !token.Icmp( "privatePolygonOffset" ) ) { + if ( !src.ReadTokenOnLine( &token ) ) { + ss->privatePolygonOffset = 1; + continue; + } + // explict larger (or negative) offset + src.UnreadToken( &token ); + ss->privatePolygonOffset = src.ParseFloat(); + continue; + } + + // texture coordinate generation + if ( !token.Icmp( "texGen" ) ) { + src.ExpectAnyToken( &token ); + if ( !token.Icmp( "normal" ) ) { + ts->texgen = TG_DIFFUSE_CUBE; + } else if ( !token.Icmp( "reflect" ) ) { + ts->texgen = TG_REFLECT_CUBE; + } else if ( !token.Icmp( "skybox" ) ) { + ts->texgen = TG_SKYBOX_CUBE; + } else if ( !token.Icmp( "wobbleSky" ) ) { + ts->texgen = TG_WOBBLESKY_CUBE; + texGenRegisters[0] = ParseExpression( src ); + texGenRegisters[1] = ParseExpression( src ); + texGenRegisters[2] = ParseExpression( src ); + } else { + common->Warning( "bad texGen '%s' in material %s", token.c_str(), GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + } + continue; + } + if ( !token.Icmp( "scroll" ) || !token.Icmp( "translate" ) ) { + a = ParseExpression( src ); + MatchToken( src, "," ); + b = ParseExpression( src ); + matrix[0][0] = GetExpressionConstant( 1 ); + matrix[0][1] = GetExpressionConstant( 0 ); + matrix[0][2] = a; + matrix[1][0] = GetExpressionConstant( 0 ); + matrix[1][1] = GetExpressionConstant( 1 ); + matrix[1][2] = b; + + MultiplyTextureMatrix( ts, matrix ); + continue; + } + if ( !token.Icmp( "scale" ) ) { + a = ParseExpression( src ); + MatchToken( src, "," ); + b = ParseExpression( src ); + // this just scales without a centering + matrix[0][0] = a; + matrix[0][1] = GetExpressionConstant( 0 ); + matrix[0][2] = GetExpressionConstant( 0 ); + matrix[1][0] = GetExpressionConstant( 0 ); + matrix[1][1] = b; + matrix[1][2] = GetExpressionConstant( 0 ); + + MultiplyTextureMatrix( ts, matrix ); + continue; + } + if ( !token.Icmp( "centerScale" ) ) { + a = ParseExpression( src ); + MatchToken( src, "," ); + b = ParseExpression( src ); + // this subtracts 0.5, then scales, then adds 0.5 + matrix[0][0] = a; + matrix[0][1] = GetExpressionConstant( 0 ); + matrix[0][2] = EmitOp( GetExpressionConstant( 0.5 ), EmitOp( GetExpressionConstant( 0.5 ), a, OP_TYPE_MULTIPLY ), OP_TYPE_SUBTRACT ); + matrix[1][0] = GetExpressionConstant( 0 ); + matrix[1][1] = b; + matrix[1][2] = EmitOp( GetExpressionConstant( 0.5 ), EmitOp( GetExpressionConstant( 0.5 ), b, OP_TYPE_MULTIPLY ), OP_TYPE_SUBTRACT ); + + MultiplyTextureMatrix( ts, matrix ); + continue; + } + if ( !token.Icmp( "shear" ) ) { + a = ParseExpression( src ); + MatchToken( src, "," ); + b = ParseExpression( src ); + // this subtracts 0.5, then shears, then adds 0.5 + matrix[0][0] = GetExpressionConstant( 1 ); + matrix[0][1] = a; + matrix[0][2] = EmitOp( GetExpressionConstant( -0.5 ), a, OP_TYPE_MULTIPLY ); + matrix[1][0] = b; + matrix[1][1] = GetExpressionConstant( 1 ); + matrix[1][2] = EmitOp( GetExpressionConstant( -0.5 ), b, OP_TYPE_MULTIPLY ); + + MultiplyTextureMatrix( ts, matrix ); + continue; + } + if ( !token.Icmp( "rotate" ) ) { + const idDeclTable *table; + int sinReg, cosReg; + + // in cycles + a = ParseExpression( src ); + + table = static_cast( declManager->FindType( DECL_TABLE, "sinTable", false ) ); + if ( !table ) { + common->Warning( "no sinTable for rotate defined" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + sinReg = EmitOp( table->Index(), a, OP_TYPE_TABLE ); + + table = static_cast( declManager->FindType( DECL_TABLE, "cosTable", false ) ); + if ( !table ) { + common->Warning( "no cosTable for rotate defined" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + cosReg = EmitOp( table->Index(), a, OP_TYPE_TABLE ); + + // this subtracts 0.5, then rotates, then adds 0.5 + matrix[0][0] = cosReg; + matrix[0][1] = EmitOp( GetExpressionConstant( 0 ), sinReg, OP_TYPE_SUBTRACT ); + matrix[0][2] = EmitOp( EmitOp( EmitOp( GetExpressionConstant( -0.5 ), cosReg, OP_TYPE_MULTIPLY ), + EmitOp( GetExpressionConstant( 0.5 ), sinReg, OP_TYPE_MULTIPLY ), OP_TYPE_ADD ), + GetExpressionConstant( 0.5 ), OP_TYPE_ADD ); + + matrix[1][0] = sinReg; + matrix[1][1] = cosReg; + matrix[1][2] = EmitOp( EmitOp( EmitOp( GetExpressionConstant( -0.5 ), sinReg, OP_TYPE_MULTIPLY ), + EmitOp( GetExpressionConstant( -0.5 ), cosReg, OP_TYPE_MULTIPLY ), OP_TYPE_ADD ), + GetExpressionConstant( 0.5 ), OP_TYPE_ADD ); + + MultiplyTextureMatrix( ts, matrix ); + continue; + } + + // color mask options + if ( !token.Icmp( "maskRed" ) ) { + ss->drawStateBits |= GLS_REDMASK; + continue; + } + if ( !token.Icmp( "maskGreen" ) ) { + ss->drawStateBits |= GLS_GREENMASK; + continue; + } + if ( !token.Icmp( "maskBlue" ) ) { + ss->drawStateBits |= GLS_BLUEMASK; + continue; + } + if ( !token.Icmp( "maskAlpha" ) ) { + ss->drawStateBits |= GLS_ALPHAMASK; + continue; + } + if ( !token.Icmp( "maskColor" ) ) { + ss->drawStateBits |= GLS_COLORMASK; + continue; + } + if ( !token.Icmp( "maskDepth" ) ) { + ss->drawStateBits |= GLS_DEPTHMASK; + continue; + } + if ( !token.Icmp( "alphaTest" ) ) { + ss->hasAlphaTest = true; + ss->alphaTestRegister = ParseExpression( src ); + coverage = MC_PERFORATED; + continue; + } + + // shorthand for 2D modulated + if ( !token.Icmp( "colored" ) ) { + ss->color.registers[0] = EXP_REG_PARM0; + ss->color.registers[1] = EXP_REG_PARM1; + ss->color.registers[2] = EXP_REG_PARM2; + ss->color.registers[3] = EXP_REG_PARM3; + pd->registersAreConstant = false; + continue; + } + + if ( !token.Icmp( "color" ) ) { + ss->color.registers[0] = ParseExpression( src ); + MatchToken( src, "," ); + ss->color.registers[1] = ParseExpression( src ); + MatchToken( src, "," ); + ss->color.registers[2] = ParseExpression( src ); + MatchToken( src, "," ); + ss->color.registers[3] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "red" ) ) { + ss->color.registers[0] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "green" ) ) { + ss->color.registers[1] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "blue" ) ) { + ss->color.registers[2] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "alpha" ) ) { + ss->color.registers[3] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "rgb" ) ) { + ss->color.registers[0] = ss->color.registers[1] = + ss->color.registers[2] = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "rgba" ) ) { + ss->color.registers[0] = ss->color.registers[1] = + ss->color.registers[2] = ss->color.registers[3] = ParseExpression( src ); + continue; + } + + if ( !token.Icmp( "if" ) ) { + ss->conditionRegister = ParseExpression( src ); + continue; + } + if ( !token.Icmp( "program" ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() ); + newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() ); + } + continue; + } + if ( !token.Icmp( "fragmentProgram" ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() ); + } + continue; + } + if ( !token.Icmp( "vertexProgram" ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() ); + } + continue; + } + if ( !token.Icmp( "megaTexture" ) ) { + if ( src.ReadTokenOnLine( &token ) ) { + newStage.megaTexture = new idMegaTexture; + if ( !newStage.megaTexture->InitFromMegaFile( token.c_str() ) ) { + delete newStage.megaTexture; + SetMaterialFlag( MF_DEFAULTED ); + continue; + } + newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "megaTexture.vfp" ); + newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "megaTexture.vfp" ); + continue; + } + } + + + if ( !token.Icmp( "vertexParm" ) ) { + ParseVertexParm( src, &newStage ); + continue; + } + + if ( !token.Icmp( "fragmentMap" ) ) { + ParseFragmentMap( src, &newStage ); + continue; + } + + + common->Warning( "unknown token '%s' in material '%s'", token.c_str(), GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + + + // if we are using newStage, allocate a copy of it + if ( newStage.fragmentProgram || newStage.vertexProgram ) { + ss->newStage = (newShaderStage_t *)Mem_Alloc( sizeof( newStage ) ); + *(ss->newStage) = newStage; + } + + // successfully parsed a stage + numStages++; + + // select a compressed depth based on what the stage is + if ( td == TD_DEFAULT ) { + switch( ss->lighting ) { + case SL_BUMP: + td = TD_BUMP; + break; + case SL_DIFFUSE: + td = TD_DIFFUSE; + break; + case SL_SPECULAR: + td = TD_SPECULAR; + break; + default: + break; + } + } + + // now load the image with all the parms we parsed + if ( imageName[0] ) { + ts->image = globalImages->ImageFromFile( imageName, tf, allowPicmip, trp, td, cubeMap ); + if ( !ts->image ) { + ts->image = globalImages->defaultImage; + } + } else if ( !ts->cinematic && !ts->dynamic && !ss->newStage ) { + common->Warning( "material '%s' had stage with no image", GetName() ); + ts->image = globalImages->defaultImage; + } +} + +/* +=============== +idMaterial::ParseDeform +=============== +*/ +void idMaterial::ParseDeform( idLexer &src ) { + idToken token; + + if ( !src.ExpectAnyToken( &token ) ) { + return; + } + + if ( !token.Icmp( "sprite" ) ) { + deform = DFRM_SPRITE; + cullType = CT_TWO_SIDED; + SetMaterialFlag( MF_NOSHADOWS ); + return; + } + if ( !token.Icmp( "tube" ) ) { + deform = DFRM_TUBE; + cullType = CT_TWO_SIDED; + SetMaterialFlag( MF_NOSHADOWS ); + return; + } + if ( !token.Icmp( "flare" ) ) { + deform = DFRM_FLARE; + cullType = CT_TWO_SIDED; + deformRegisters[0] = ParseExpression( src ); + SetMaterialFlag( MF_NOSHADOWS ); + return; + } + if ( !token.Icmp( "expand" ) ) { + deform = DFRM_EXPAND; + deformRegisters[0] = ParseExpression( src ); + return; + } + if ( !token.Icmp( "move" ) ) { + deform = DFRM_MOVE; + deformRegisters[0] = ParseExpression( src ); + return; + } + if ( !token.Icmp( "turbulent" ) ) { + deform = DFRM_TURB; + + if ( !src.ExpectAnyToken( &token ) ) { + src.Warning( "deform particle missing particle name" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + deformDecl = declManager->FindType( DECL_TABLE, token.c_str(), true ); + + deformRegisters[0] = ParseExpression( src ); + deformRegisters[1] = ParseExpression( src ); + deformRegisters[2] = ParseExpression( src ); + return; + } + if ( !token.Icmp( "eyeBall" ) ) { + deform = DFRM_EYEBALL; + return; + } + if ( !token.Icmp( "particle" ) ) { + deform = DFRM_PARTICLE; + if ( !src.ExpectAnyToken( &token ) ) { + src.Warning( "deform particle missing particle name" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + deformDecl = declManager->FindType( DECL_PARTICLE, token.c_str(), true ); + return; + } + if ( !token.Icmp( "particle2" ) ) { + deform = DFRM_PARTICLE2; + if ( !src.ExpectAnyToken( &token ) ) { + src.Warning( "deform particle missing particle name" ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + deformDecl = declManager->FindType( DECL_PARTICLE, token.c_str(), true ); + return; + } + src.Warning( "Bad deform type '%s'", token.c_str() ); + SetMaterialFlag( MF_DEFAULTED ); +} + + +/* +============== +idMaterial::AddImplicitStages + +If a material has diffuse or specular stages without any +bump stage, add an implicit _flat bumpmap stage. + +If a material has a bump stage but no diffuse or specular +stage, add a _white diffuse stage. + +It is valid to have either a diffuse or specular without the other. + +It is valid to have a reflection map and a bump map for bumpy reflection +============== +*/ +void idMaterial::AddImplicitStages( const textureRepeat_t trpDefault /* = TR_REPEAT */ ) { + char buffer[1024]; + idLexer newSrc; + bool hasDiffuse = false; + bool hasSpecular = false; + bool hasBump = false; + bool hasReflection = false; + + for ( int i = 0 ; i < numStages ; i++ ) { + if ( pd->parseStages[i].lighting == SL_BUMP ) { + hasBump = true; + } + if ( pd->parseStages[i].lighting == SL_DIFFUSE ) { + hasDiffuse = true; + } + if ( pd->parseStages[i].lighting == SL_SPECULAR ) { + hasSpecular = true; + } + if ( pd->parseStages[i].texture.texgen == TG_REFLECT_CUBE ) { + hasReflection = true; + } + } + + // if it doesn't have an interaction at all, don't add anything + if ( !hasBump && !hasDiffuse && !hasSpecular ) { + return; + } + + if ( numStages == MAX_SHADER_STAGES ) { + return; + } + + if ( !hasBump ) { + idStr::snPrintf( buffer, sizeof( buffer ), "blend bumpmap\nmap _flat\n}\n" ); + newSrc.LoadMemory( buffer, strlen(buffer), "bumpmap" ); + newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + ParseStage( newSrc, trpDefault ); + newSrc.FreeSource(); + } + + if ( !hasDiffuse && !hasSpecular && !hasReflection ) { + idStr::snPrintf( buffer, sizeof( buffer ), "blend diffusemap\nmap _white\n}\n" ); + newSrc.LoadMemory( buffer, strlen(buffer), "diffusemap" ); + newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + ParseStage( newSrc, trpDefault ); + newSrc.FreeSource(); + } + +} + +/* +=============== +idMaterial::SortInteractionStages + +The renderer expects bump, then diffuse, then specular +There can be multiple bump maps, followed by additional +diffuse and specular stages, which allows cross-faded bump mapping. + +Ambient stages can be interspersed anywhere, but they are +ignored during interactions, and all the interaction +stages are ignored during ambient drawing. +=============== +*/ +void idMaterial::SortInteractionStages() { + int j; + + for ( int i = 0 ; i < numStages ; i = j ) { + // find the next bump map + for ( j = i + 1 ; j < numStages ; j++ ) { + if ( pd->parseStages[j].lighting == SL_BUMP ) { + // if the very first stage wasn't a bumpmap, + // this bumpmap is part of the first group + if ( pd->parseStages[i].lighting != SL_BUMP ) { + continue; + } + break; + } + } + + // bubble sort everything bump / diffuse / specular + for ( int l = 1 ; l < j-i ; l++ ) { + for ( int k = i ; k < j-l ; k++ ) { + if ( pd->parseStages[k].lighting > pd->parseStages[k+1].lighting ) { + shaderStage_t temp; + + temp = pd->parseStages[k]; + pd->parseStages[k] = pd->parseStages[k+1]; + pd->parseStages[k+1] = temp; + } + } + } + } +} + +/* +================= +idMaterial::ParseMaterial + +The current text pointer is at the explicit text definition of the +Parse it into the global material variable. Later functions will optimize it. + +If there is any error during parsing, defaultShader will be set. +================= +*/ +void idMaterial::ParseMaterial( idLexer &src ) { + idToken token; + int s; + char buffer[1024]; + const char *str; + idLexer newSrc; + int i; + + s = 0; + + numOps = 0; + numRegisters = EXP_REG_NUM_PREDEFINED; // leave space for the parms to be copied in + for ( i = 0 ; i < numRegisters ; i++ ) { + pd->registerIsTemporary[i] = true; // they aren't constants that can be folded + } + + numStages = 0; + + textureRepeat_t trpDefault = TR_REPEAT; // allow a global setting for repeat + + while ( 1 ) { + if ( TestMaterialFlag( MF_DEFAULTED ) ) { // we have a parse error + return; + } + if ( !src.ExpectAnyToken( &token ) ) { + SetMaterialFlag( MF_DEFAULTED ); + return; + } + + // end of material definition + if ( token == "}" ) { + break; + } + else if ( !token.Icmp( "qer_editorimage") ) { + src.ReadTokenOnLine( &token ); + editorImageName = token.c_str(); + src.SkipRestOfLine(); + continue; + } + // description + else if ( !token.Icmp( "description") ) { + src.ReadTokenOnLine( &token ); + desc = token.c_str(); + continue; + } + // check for the surface / content bit flags + else if ( CheckSurfaceParm( &token ) ) { + continue; + } + + + // polygonOffset + else if ( !token.Icmp( "polygonOffset" ) ) { + SetMaterialFlag( MF_POLYGONOFFSET ); + if ( !src.ReadTokenOnLine( &token ) ) { + polygonOffset = 1; + continue; + } + // explict larger (or negative) offset + polygonOffset = token.GetFloatValue(); + continue; + } + // noshadow + else if ( !token.Icmp( "noShadows" ) ) { + SetMaterialFlag( MF_NOSHADOWS ); + continue; + } + else if ( !token.Icmp( "suppressInSubview" ) ) { + suppressInSubview = true; + continue; + } + else if ( !token.Icmp( "portalSky" ) ) { + portalSky = true; + continue; + } + // noSelfShadow + else if ( !token.Icmp( "noSelfShadow" ) ) { + SetMaterialFlag( MF_NOSELFSHADOW ); + continue; + } + // noPortalFog + else if ( !token.Icmp( "noPortalFog" ) ) { + SetMaterialFlag( MF_NOPORTALFOG ); + continue; + } + // forceShadows allows nodraw surfaces to cast shadows + else if ( !token.Icmp( "forceShadows" ) ) { + SetMaterialFlag( MF_FORCESHADOWS ); + continue; + } + // overlay / decal suppression + else if ( !token.Icmp( "noOverlays" ) ) { + allowOverlays = false; + continue; + } + // moster blood overlay forcing for alpha tested or translucent surfaces + else if ( !token.Icmp( "forceOverlays" ) ) { + pd->forceOverlays = true; + continue; + } + // translucent + else if ( !token.Icmp( "translucent" ) ) { + coverage = MC_TRANSLUCENT; + continue; + } + // global zero clamp + else if ( !token.Icmp( "zeroclamp" ) ) { + trpDefault = TR_CLAMP_TO_ZERO; + continue; + } + // global clamp + else if ( !token.Icmp( "clamp" ) ) { + trpDefault = TR_CLAMP; + continue; + } + // global clamp + else if ( !token.Icmp( "alphazeroclamp" ) ) { + trpDefault = TR_CLAMP_TO_ZERO; + continue; + } + // forceOpaque is used for skies-behind-windows + else if ( !token.Icmp( "forceOpaque" ) ) { + coverage = MC_OPAQUE; + continue; + } + // twoSided + else if ( !token.Icmp( "twoSided" ) ) { + cullType = CT_TWO_SIDED; + // twoSided implies no-shadows, because the shadow + // volume would be coplanar with the surface, giving depth fighting + // we could make this no-self-shadows, but it may be more important + // to receive shadows from no-self-shadow monsters + SetMaterialFlag( MF_NOSHADOWS ); + } + // backSided + else if ( !token.Icmp( "backSided" ) ) { + cullType = CT_BACK_SIDED; + // the shadow code doesn't handle this, so just disable shadows. + // We could fix this in the future if there was a need. + SetMaterialFlag( MF_NOSHADOWS ); + } + // foglight + else if ( !token.Icmp( "fogLight" ) ) { + fogLight = true; + continue; + } + // blendlight + else if ( !token.Icmp( "blendLight" ) ) { + blendLight = true; + continue; + } + // ambientLight + else if ( !token.Icmp( "ambientLight" ) ) { + ambientLight = true; + continue; + } + // mirror + else if ( !token.Icmp( "mirror" ) ) { + sort = SS_SUBVIEW; + coverage = MC_OPAQUE; + continue; + } + // noFog + else if ( !token.Icmp( "noFog" ) ) { + noFog = true; + continue; + } + // unsmoothedTangents + else if ( !token.Icmp( "unsmoothedTangents" ) ) { + unsmoothedTangents = true; + continue; + } + // lightFallofImage + // specifies the image to use for the third axis of projected + // light volumes + else if ( !token.Icmp( "lightFalloffImage" ) ) { + str = R_ParsePastImageProgram( src ); + idStr copy; + + copy = str; // so other things don't step on it + lightFalloffImage = globalImages->ImageFromFile( copy, TF_DEFAULT, false, TR_CLAMP /* TR_CLAMP_TO_ZERO */, TD_DEFAULT ); + continue; + } + // guisurf | guisurf entity + // an entity guisurf must have an idUserInterface + // specified in the renderEntity + else if ( !token.Icmp( "guisurf" ) ) { + src.ReadTokenOnLine( &token ); + if ( !token.Icmp( "entity" ) ) { + entityGui = 1; + } else if ( !token.Icmp( "entity2" ) ) { + entityGui = 2; + } else if ( !token.Icmp( "entity3" ) ) { + entityGui = 3; + } else { + gui = uiManager->FindGui( token.c_str(), true ); + } + continue; + } + // sort + else if ( !token.Icmp( "sort" ) ) { + ParseSort( src ); + continue; + } + // spectrum + else if ( !token.Icmp( "spectrum" ) ) { + src.ReadTokenOnLine( &token ); + spectrum = atoi( token.c_str() ); + continue; + } + // deform < sprite | tube | flare > + else if ( !token.Icmp( "deform" ) ) { + ParseDeform( src ); + continue; + } + // decalInfo ( ) ( ) + else if ( !token.Icmp( "decalInfo" ) ) { + ParseDecalInfo( src ); + continue; + } + // renderbump + else if ( !token.Icmp( "renderbump") ) { + src.ParseRestOfLine( renderBump ); + continue; + } + // diffusemap for stage shortcut + else if ( !token.Icmp( "diffusemap" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::snPrintf( buffer, sizeof( buffer ), "blend diffusemap\nmap %s\n}\n", str ); + newSrc.LoadMemory( buffer, strlen(buffer), "diffusemap" ); + newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + ParseStage( newSrc, trpDefault ); + newSrc.FreeSource(); + continue; + } + // specularmap for stage shortcut + else if ( !token.Icmp( "specularmap" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::snPrintf( buffer, sizeof( buffer ), "blend specularmap\nmap %s\n}\n", str ); + newSrc.LoadMemory( buffer, strlen(buffer), "specularmap" ); + newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + ParseStage( newSrc, trpDefault ); + newSrc.FreeSource(); + continue; + } + // normalmap for stage shortcut + else if ( !token.Icmp( "bumpmap" ) ) { + str = R_ParsePastImageProgram( src ); + idStr::snPrintf( buffer, sizeof( buffer ), "blend bumpmap\nmap %s\n}\n", str ); + newSrc.LoadMemory( buffer, strlen(buffer), "bumpmap" ); + newSrc.SetFlags( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + ParseStage( newSrc, trpDefault ); + newSrc.FreeSource(); + continue; + } + // DECAL_MACRO for backwards compatibility with the preprocessor macros + else if ( !token.Icmp( "DECAL_MACRO" ) ) { + // polygonOffset + SetMaterialFlag( MF_POLYGONOFFSET ); + polygonOffset = 1; + + // discrete + surfaceFlags |= SURF_DISCRETE; + contentFlags &= ~CONTENTS_SOLID; + + // sort decal + sort = SS_DECAL; + + // noShadows + SetMaterialFlag( MF_NOSHADOWS ); + continue; + } + else if ( token == "{" ) { + // create the new stage + ParseStage( src, trpDefault ); + continue; + } + else { + common->Warning( "unknown general material parameter '%s' in '%s'", token.c_str(), GetName() ); + SetMaterialFlag( MF_DEFAULTED ); + return; + } + } + + // add _flat or _white stages if needed + AddImplicitStages(); + + // order the diffuse / bump / specular stages properly + SortInteractionStages(); + + // if we need to do anything with normals (lighting or environment mapping) + // and two sided lighting was asked for, flag + // shouldCreateBackSides() and change culling back to single sided, + // so we get proper tangent vectors on both sides + + // we can't just call ReceivesLighting(), because the stages are still + // in temporary form + if ( cullType == CT_TWO_SIDED ) { + for ( i = 0 ; i < numStages ; i++ ) { + if ( pd->parseStages[i].lighting != SL_AMBIENT || pd->parseStages[i].texture.texgen != TG_EXPLICIT ) { + if ( cullType == CT_TWO_SIDED ) { + cullType = CT_FRONT_SIDED; + shouldCreateBackSides = true; + } + break; + } + } + } + + // currently a surface can only have one unique texgen for all the stages on old hardware + texgen_t firstGen = TG_EXPLICIT; + for ( i = 0; i < numStages; i++ ) { + if ( pd->parseStages[i].texture.texgen != TG_EXPLICIT ) { + if ( firstGen == TG_EXPLICIT ) { + firstGen = pd->parseStages[i].texture.texgen; + } else if ( firstGen != pd->parseStages[i].texture.texgen ) { + common->Warning( "material '%s' has multiple stages with a texgen", GetName() ); + break; + } + } + } +} + +/* +========================= +idMaterial::SetGui +========================= +*/ +void idMaterial::SetGui( const char *_gui ) const { + gui = uiManager->FindGui( _gui, true, false, true ); +} + +/* +========================= +idMaterial::Parse + +Parses the current material definition and finds all necessary images. +========================= +*/ +bool idMaterial::Parse( const char *text, const int textLength ) { + idLexer src; + idToken token; + mtrParsingData_t parsingData; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + // reset to the unparsed state + CommonInit(); + + memset( &parsingData, 0, sizeof( parsingData ) ); + + pd = &parsingData; // this is only valid during parse + + // parse it + ParseMaterial( src ); + + // if we are doing an fs_copyfiles, also reference the editorImage + if ( cvarSystem->GetCVarInteger( "fs_copyFiles" ) ) { + GetEditorImage(); + } + + // + // count non-lit stages + numAmbientStages = 0; + int i; + for ( i = 0 ; i < numStages ; i++ ) { + if ( pd->parseStages[i].lighting == SL_AMBIENT ) { + numAmbientStages++; + } + } + + // see if there is a subview stage + if ( sort == SS_SUBVIEW ) { + hasSubview = true; + } else { + hasSubview = false; + for ( i = 0 ; i < numStages ; i++ ) { + if ( pd->parseStages[i].texture.dynamic ) { + hasSubview = true; + } + } + } + + // automatically determine coverage if not explicitly set + if ( coverage == MC_BAD ) { + // automatically set MC_TRANSLUCENT if we don't have any interaction stages and + // the first stage is blended and not an alpha test mask or a subview + if ( !numStages ) { + // non-visible + coverage = MC_TRANSLUCENT; + } else if ( numStages != numAmbientStages ) { + // we have an interaction draw + coverage = MC_OPAQUE; + } else if ( + ( pd->parseStages[0].drawStateBits & GLS_DSTBLEND_BITS ) != GLS_DSTBLEND_ZERO || + ( pd->parseStages[0].drawStateBits & GLS_SRCBLEND_BITS ) == GLS_SRCBLEND_DST_COLOR || + ( pd->parseStages[0].drawStateBits & GLS_SRCBLEND_BITS ) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR || + ( pd->parseStages[0].drawStateBits & GLS_SRCBLEND_BITS ) == GLS_SRCBLEND_DST_ALPHA || + ( pd->parseStages[0].drawStateBits & GLS_SRCBLEND_BITS ) == GLS_SRCBLEND_ONE_MINUS_DST_ALPHA + ) { + // blended with the destination + coverage = MC_TRANSLUCENT; + } else { + coverage = MC_OPAQUE; + } + } + + // translucent automatically implies noshadows + if ( coverage == MC_TRANSLUCENT ) { + SetMaterialFlag( MF_NOSHADOWS ); + } else { + // mark the contents as opaque + contentFlags |= CONTENTS_OPAQUE; + } + + // if we are translucent, draw with an alpha in the editor + if ( coverage == MC_TRANSLUCENT ) { + editorAlpha = 0.5; + } else { + editorAlpha = 1.0; + } + + // the sorts can make reasonable defaults + if ( sort == SS_BAD ) { + if ( TestMaterialFlag(MF_POLYGONOFFSET) ) { + sort = SS_DECAL; + } else if ( coverage == MC_TRANSLUCENT ) { + sort = SS_MEDIUM; + } else { + sort = SS_OPAQUE; + } + } + + // anything that references _currentRender will automatically get sort = SS_POST_PROCESS + // and coverage = MC_TRANSLUCENT + + for ( i = 0 ; i < numStages ; i++ ) { + shaderStage_t *pStage = &pd->parseStages[i]; + if ( pStage->texture.image == globalImages->currentRenderImage ) { + if ( sort != SS_PORTAL_SKY ) { + sort = SS_POST_PROCESS; + coverage = MC_TRANSLUCENT; + } + break; + } + if ( pStage->newStage ) { + for ( int j = 0 ; j < pStage->newStage->numFragmentProgramImages ; j++ ) { + if ( pStage->newStage->fragmentProgramImages[j] == globalImages->currentRenderImage ) { + if ( sort != SS_PORTAL_SKY ) { + sort = SS_POST_PROCESS; + coverage = MC_TRANSLUCENT; + } + i = numStages; + break; + } + } + } + } + + // set the drawStateBits depth flags + for ( i = 0 ; i < numStages ; i++ ) { + shaderStage_t *pStage = &pd->parseStages[i]; + if ( sort == SS_POST_PROCESS ) { + // post-process effects fill the depth buffer as they draw, so only the + // topmost post-process effect is rendered + pStage->drawStateBits |= GLS_DEPTHFUNC_LESS; + } else if ( coverage == MC_TRANSLUCENT || pStage->ignoreAlphaTest ) { + // translucent surfaces can extend past the exactly marked depth buffer + pStage->drawStateBits |= GLS_DEPTHFUNC_LESS | GLS_DEPTHMASK; + } else { + // opaque and perforated surfaces must exactly match the depth buffer, + // which gets alpha test correct + pStage->drawStateBits |= GLS_DEPTHFUNC_EQUAL | GLS_DEPTHMASK; + } + } + + // determine if this surface will accept overlays / decals + + if ( pd->forceOverlays ) { + // explicitly flaged in material definition + allowOverlays = true; + } else { + if ( !IsDrawn() ) { + allowOverlays = false; + } + if ( Coverage() != MC_OPAQUE ) { + allowOverlays = false; + } + if ( GetSurfaceFlags() & SURF_NOIMPACT ) { + allowOverlays = false; + } + } + + // add a tiny offset to the sort orders, so that different materials + // that have the same sort value will at least sort consistantly, instead + // of flickering back and forth +/* this messed up in-game guis + if ( sort != SS_SUBVIEW ) { + int hash, l; + + l = name.Length(); + hash = 0; + for ( int i = 0 ; i < l ; i++ ) { + hash ^= name[i]; + } + sort += hash * 0.01; + } +*/ + + if (numStages) { + stages = (shaderStage_t *)R_StaticAlloc( numStages * sizeof( stages[0] ) ); + memcpy( stages, pd->parseStages, numStages * sizeof( stages[0] ) ); + } + + if ( numOps ) { + ops = (expOp_t *)R_StaticAlloc( numOps * sizeof( ops[0] ) ); + memcpy( ops, pd->shaderOps, numOps * sizeof( ops[0] ) ); + } + + if ( numRegisters ) { + expressionRegisters = (float *)R_StaticAlloc( numRegisters * sizeof( expressionRegisters[0] ) ); + memcpy( expressionRegisters, pd->shaderRegisters, numRegisters * sizeof( expressionRegisters[0] ) ); + } + + // see if the registers are completely constant, and don't need to be evaluated + // per-surface + CheckForConstantRegisters(); + + pd = NULL; // the pointer will be invalid after exiting this function + + // finish things up + if ( TestMaterialFlag( MF_DEFAULTED ) ) { + MakeDefault(); + return false; + } + return true; +} + +/* +=================== +idMaterial::Print +=================== +*/ +char *opNames[] = { + "OP_TYPE_ADD", + "OP_TYPE_SUBTRACT", + "OP_TYPE_MULTIPLY", + "OP_TYPE_DIVIDE", + "OP_TYPE_MOD", + "OP_TYPE_TABLE", + "OP_TYPE_GT", + "OP_TYPE_GE", + "OP_TYPE_LT", + "OP_TYPE_LE", + "OP_TYPE_EQ", + "OP_TYPE_NE", + "OP_TYPE_AND", + "OP_TYPE_OR" +}; + +void idMaterial::Print() const { + int i; + + for ( i = EXP_REG_NUM_PREDEFINED ; i < GetNumRegisters() ; i++ ) { + common->Printf( "register %i: %f\n", i, expressionRegisters[i] ); + } + common->Printf( "\n" ); + for ( i = 0 ; i < numOps ; i++ ) { + const expOp_t *op = &ops[i]; + if ( op->opType == OP_TYPE_TABLE ) { + common->Printf( "%i = %s[ %i ]\n", op->c, declManager->DeclByIndex( DECL_TABLE, op->a )->GetName(), op->b ); + } else { + common->Printf( "%i = %i %s %i\n", op->c, op->a, opNames[ op->opType ], op->b ); + } + } +} + +/* +=============== +idMaterial::Save +=============== +*/ +bool idMaterial::Save( const char *fileName ) { + return ReplaceSourceFileText(); +} + +/* +=============== +idMaterial::AddReference +=============== +*/ +void idMaterial::AddReference() { + refCount++; + + for ( int i = 0; i < numStages; i++ ) { + shaderStage_t *s = &stages[i]; + + if ( s->texture.image ) { + s->texture.image->AddReference(); + } + } +} + +/* +=============== +idMaterial::EvaluateRegisters + +Parameters are taken from the localSpace and the renderView, +then all expressions are evaluated, leaving the material registers +set to their apropriate values. +=============== +*/ +void idMaterial::EvaluateRegisters( float *registers, const float shaderParms[MAX_ENTITY_SHADER_PARMS], + const viewDef_t *view, idSoundEmitter *soundEmitter ) const { + int i, b; + expOp_t *op; + + // copy the material constants + for ( i = EXP_REG_NUM_PREDEFINED ; i < numRegisters ; i++ ) { + registers[i] = expressionRegisters[i]; + } + + // copy the local and global parameters + registers[EXP_REG_TIME] = view->floatTime; + registers[EXP_REG_PARM0] = shaderParms[0]; + registers[EXP_REG_PARM1] = shaderParms[1]; + registers[EXP_REG_PARM2] = shaderParms[2]; + registers[EXP_REG_PARM3] = shaderParms[3]; + registers[EXP_REG_PARM4] = shaderParms[4]; + registers[EXP_REG_PARM5] = shaderParms[5]; + registers[EXP_REG_PARM6] = shaderParms[6]; + registers[EXP_REG_PARM7] = shaderParms[7]; + registers[EXP_REG_PARM8] = shaderParms[8]; + registers[EXP_REG_PARM9] = shaderParms[9]; + registers[EXP_REG_PARM10] = shaderParms[10]; + registers[EXP_REG_PARM11] = shaderParms[11]; + registers[EXP_REG_GLOBAL0] = view->renderView.shaderParms[0]; + registers[EXP_REG_GLOBAL1] = view->renderView.shaderParms[1]; + registers[EXP_REG_GLOBAL2] = view->renderView.shaderParms[2]; + registers[EXP_REG_GLOBAL3] = view->renderView.shaderParms[3]; + registers[EXP_REG_GLOBAL4] = view->renderView.shaderParms[4]; + registers[EXP_REG_GLOBAL5] = view->renderView.shaderParms[5]; + registers[EXP_REG_GLOBAL6] = view->renderView.shaderParms[6]; + registers[EXP_REG_GLOBAL7] = view->renderView.shaderParms[7]; + + op = ops; + for ( i = 0 ; i < numOps ; i++, op++ ) { + switch( op->opType ) { + case OP_TYPE_ADD: + registers[op->c] = registers[op->a] + registers[op->b]; + break; + case OP_TYPE_SUBTRACT: + registers[op->c] = registers[op->a] - registers[op->b]; + break; + case OP_TYPE_MULTIPLY: + registers[op->c] = registers[op->a] * registers[op->b]; + break; + case OP_TYPE_DIVIDE: + registers[op->c] = registers[op->a] / registers[op->b]; + break; + case OP_TYPE_MOD: + b = (int)registers[op->b]; + b = b != 0 ? b : 1; + registers[op->c] = (int)registers[op->a] % b; + break; + case OP_TYPE_TABLE: + { + const idDeclTable *table = static_cast( declManager->DeclByIndex( DECL_TABLE, op->a ) ); + registers[op->c] = table->TableLookup( registers[op->b] ); + } + break; + case OP_TYPE_SOUND: + if ( soundEmitter ) { + registers[op->c] = soundEmitter->CurrentAmplitude(); + } else { + registers[op->c] = 0; + } + break; + case OP_TYPE_GT: + registers[op->c] = registers[ op->a ] > registers[op->b]; + break; + case OP_TYPE_GE: + registers[op->c] = registers[ op->a ] >= registers[op->b]; + break; + case OP_TYPE_LT: + registers[op->c] = registers[ op->a ] < registers[op->b]; + break; + case OP_TYPE_LE: + registers[op->c] = registers[ op->a ] <= registers[op->b]; + break; + case OP_TYPE_EQ: + registers[op->c] = registers[ op->a ] == registers[op->b]; + break; + case OP_TYPE_NE: + registers[op->c] = registers[ op->a ] != registers[op->b]; + break; + case OP_TYPE_AND: + registers[op->c] = registers[ op->a ] && registers[op->b]; + break; + case OP_TYPE_OR: + registers[op->c] = registers[ op->a ] || registers[op->b]; + break; + default: + common->FatalError( "R_EvaluateExpression: bad opcode" ); + } + } + +} + +/* +============= +idMaterial::Texgen +============= +*/ +texgen_t idMaterial::Texgen() const { + if ( stages ) { + for ( int i = 0; i < numStages; i++ ) { + if ( stages[ i ].texture.texgen != TG_EXPLICIT ) { + return stages[ i ].texture.texgen; + } + } + } + + return TG_EXPLICIT; +} + +/* +============= +idMaterial::GetImageWidth +============= +*/ +int idMaterial::GetImageWidth( void ) const { + assert( GetStage(0) && GetStage(0)->texture.image ); + return GetStage(0)->texture.image->uploadWidth; +} + +/* +============= +idMaterial::GetImageHeight +============= +*/ +int idMaterial::GetImageHeight( void ) const { + assert( GetStage(0) && GetStage(0)->texture.image ); + return GetStage(0)->texture.image->uploadHeight; +} + +/* +============= +idMaterial::CinematicLength +============= +*/ +int idMaterial::CinematicLength() const { + if ( !stages || !stages[0].texture.cinematic ) { + return 0; + } + return stages[0].texture.cinematic->AnimationLength(); +} + +/* +============= +idMaterial::UpdateCinematic +============= +*/ +void idMaterial::UpdateCinematic( int time ) const { + if ( !stages || !stages[0].texture.cinematic || !backEnd.viewDef ) { + return; + } + stages[0].texture.cinematic->ImageForTime( tr.primaryRenderView.time ); +} + +/* +============= +idMaterial::CloseCinematic +============= +*/ +void idMaterial::CloseCinematic( void ) const { + for( int i = 0; i < numStages; i++ ) { + if ( stages[i].texture.cinematic ) { + stages[i].texture.cinematic->Close(); + delete stages[i].texture.cinematic; + stages[i].texture.cinematic = NULL; + } + } +} + +/* +============= +idMaterial::ResetCinematicTime +============= +*/ +void idMaterial::ResetCinematicTime( int time ) const { + for( int i = 0; i < numStages; i++ ) { + if ( stages[i].texture.cinematic ) { + stages[i].texture.cinematic->ResetTime( time ); + } + } +} + +/* +============= +idMaterial::ConstantRegisters +============= +*/ +const float *idMaterial::ConstantRegisters() const { + if ( !r_useConstantMaterials.GetBool() ) { + return NULL; + } + return constantRegisters; +} + +/* +================== +idMaterial::CheckForConstantRegisters + +As of 5/2/03, about half of the unique materials loaded on typical +maps are constant, but 2/3 of the surface references are. +This is probably an optimization of dubious value. +================== +*/ +static int c_constant, c_variable; +void idMaterial::CheckForConstantRegisters() { + if ( !pd->registersAreConstant ) { + return; + } + + // evaluate the registers once, and save them + constantRegisters = (float *)R_ClearedStaticAlloc( GetNumRegisters() * sizeof( float ) ); + + float shaderParms[MAX_ENTITY_SHADER_PARMS]; + memset( shaderParms, 0, sizeof( shaderParms ) ); + viewDef_t viewDef; + memset( &viewDef, 0, sizeof( viewDef ) ); + + EvaluateRegisters( constantRegisters, shaderParms, &viewDef, 0 ); +} + +/* +=================== +idMaterial::ImageName +=================== +*/ +const char *idMaterial::ImageName( void ) const { + if ( numStages == 0 ) { + return "_scratch"; + } + idImage *image = stages[0].texture.image; + if ( image ) { + return image->imgName; + } + return "_scratch"; +} + +/* +=================== +idMaterial::SetImageClassifications + +Just for image resource tracking. +=================== +*/ +void idMaterial::SetImageClassifications( int tag ) const { + for ( int i = 0 ; i < numStages ; i++ ) { + idImage *image = stages[i].texture.image; + if ( image ) { + image->SetClassification( tag ); + } + } +} + +/* +================= +idMaterial::Size +================= +*/ +size_t idMaterial::Size( void ) const { + return sizeof( idMaterial ); +} + +/* +=================== +idMaterial::SetDefaultText +=================== +*/ +bool idMaterial::SetDefaultText( void ) { + // if there exists an image with the same name + if ( 1 ) { //fileSystem->ReadFile( GetName(), NULL ) != -1 ) { + char generated[2048]; + idStr::snPrintf( generated, sizeof( generated ), + "material %s // IMPLICITLY GENERATED\n" + "{\n" + "{\n" + "blend blend\n" + "colored\n" + "map \"%s\"\n" + "clamp\n" + "}\n" + "}\n", GetName(), GetName() ); + SetText( generated ); + return true; + } else { + return false; + } +} + +/* +=================== +idMaterial::DefaultDefinition +=================== +*/ +const char *idMaterial::DefaultDefinition() const { + return + "{\n" + "\t" "{\n" + "\t\t" "blend\tblend\n" + "\t\t" "map\t\t_default\n" + "\t" "}\n" + "}"; +} + + +/* +=================== +idMaterial::GetBumpStage +=================== +*/ +const shaderStage_t *idMaterial::GetBumpStage( void ) const { + for ( int i = 0 ; i < numStages ; i++ ) { + if ( stages[i].lighting == SL_BUMP ) { + return &stages[i]; + } + } + return NULL; +} + +/* +=================== +idMaterial::ReloadImages +=================== +*/ +void idMaterial::ReloadImages( bool force ) const +{ + for ( int i = 0 ; i < numStages ; i++ ) { + if ( stages[i].newStage ) { + for ( int j = 0 ; j < stages[i].newStage->numFragmentProgramImages ; j++ ) { + if ( stages[i].newStage->fragmentProgramImages[j] ) { + stages[i].newStage->fragmentProgramImages[j]->Reload( false, force ); + } + } + } else if ( stages[i].texture.image ) { + stages[i].texture.image->Reload( false, force ); + } + } +} diff --git a/renderer/Material.h b/renderer/Material.h new file mode 100644 index 000000000..dbbaccdc2 --- /dev/null +++ b/renderer/Material.h @@ -0,0 +1,689 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MATERIAL_H__ +#define __MATERIAL_H__ + +/* +=============================================================================== + + Material + +=============================================================================== +*/ + +class idImage; +class idCinematic; +class idUserInterface; +class idMegaTexture; + +// moved from image.h for default parm +typedef enum { + TF_LINEAR, + TF_NEAREST, + TF_DEFAULT // use the user-specified r_textureFilter +} textureFilter_t; + +typedef enum { + TR_REPEAT, + TR_CLAMP, + TR_CLAMP_TO_BORDER, // this should replace TR_CLAMP_TO_ZERO and TR_CLAMP_TO_ZERO_ALPHA, + // but I don't want to risk changing it right now + TR_CLAMP_TO_ZERO, // guarantee 0,0,0,255 edge for projected textures, + // set AFTER image format selection + TR_CLAMP_TO_ZERO_ALPHA // guarantee 0 alpha edge for projected textures, + // set AFTER image format selection +} textureRepeat_t; + +typedef struct { + int stayTime; // msec for no change + int fadeTime; // msec to fade vertex colors over + float start[4]; // vertex color at spawn (possibly out of 0.0 - 1.0 range, will clamp after calc) + float end[4]; // vertex color at fade-out (possibly out of 0.0 - 1.0 range, will clamp after calc) +} decalInfo_t; + +typedef enum { + DFRM_NONE, + DFRM_SPRITE, + DFRM_TUBE, + DFRM_FLARE, + DFRM_EXPAND, + DFRM_MOVE, + DFRM_EYEBALL, + DFRM_PARTICLE, + DFRM_PARTICLE2, + DFRM_TURB +} deform_t; + +typedef enum { + DI_STATIC, + DI_SCRATCH, // video, screen wipe, etc + DI_CUBE_RENDER, + DI_MIRROR_RENDER, + DI_XRAY_RENDER, + DI_REMOTE_RENDER +} dynamicidImage_t; + +// note: keep opNames[] in sync with changes +typedef enum { + OP_TYPE_ADD, + OP_TYPE_SUBTRACT, + OP_TYPE_MULTIPLY, + OP_TYPE_DIVIDE, + OP_TYPE_MOD, + OP_TYPE_TABLE, + OP_TYPE_GT, + OP_TYPE_GE, + OP_TYPE_LT, + OP_TYPE_LE, + OP_TYPE_EQ, + OP_TYPE_NE, + OP_TYPE_AND, + OP_TYPE_OR, + OP_TYPE_SOUND +} expOpType_t; + +typedef enum { + EXP_REG_TIME, + + EXP_REG_PARM0, + EXP_REG_PARM1, + EXP_REG_PARM2, + EXP_REG_PARM3, + EXP_REG_PARM4, + EXP_REG_PARM5, + EXP_REG_PARM6, + EXP_REG_PARM7, + EXP_REG_PARM8, + EXP_REG_PARM9, + EXP_REG_PARM10, + EXP_REG_PARM11, + + EXP_REG_GLOBAL0, + EXP_REG_GLOBAL1, + EXP_REG_GLOBAL2, + EXP_REG_GLOBAL3, + EXP_REG_GLOBAL4, + EXP_REG_GLOBAL5, + EXP_REG_GLOBAL6, + EXP_REG_GLOBAL7, + + EXP_REG_NUM_PREDEFINED +} expRegister_t; + +typedef struct { + expOpType_t opType; + int a, b, c; +} expOp_t; + +typedef struct { + int registers[4]; +} colorStage_t; + +typedef enum { + TG_EXPLICIT, + TG_DIFFUSE_CUBE, + TG_REFLECT_CUBE, + TG_SKYBOX_CUBE, + TG_WOBBLESKY_CUBE, + TG_SCREEN, // screen aligned, for mirrorRenders and screen space temporaries + TG_SCREEN2, + TG_GLASSWARP +} texgen_t; + +typedef struct { + idCinematic * cinematic; + idImage * image; + texgen_t texgen; + bool hasMatrix; + int matrix[2][3]; // we only allow a subset of the full projection matrix + + // dynamic image variables + dynamicidImage_t dynamic; + int width, height; + int dynamicFrameCount; +} textureStage_t; + +// the order BUMP / DIFFUSE / SPECULAR is necessary for interactions to draw correctly on low end cards +typedef enum { + SL_AMBIENT, // execute after lighting + SL_BUMP, + SL_DIFFUSE, + SL_SPECULAR +} stageLighting_t; + +// cross-blended terrain textures need to modulate the color by +// the vertex color to smoothly blend between two textures +typedef enum { + SVC_IGNORE, + SVC_MODULATE, + SVC_INVERSE_MODULATE +} stageVertexColor_t; + +static const int MAX_FRAGMENT_IMAGES = 8; +static const int MAX_VERTEX_PARMS = 4; + +typedef struct { + int vertexProgram; + int numVertexParms; + int vertexParms[MAX_VERTEX_PARMS][4]; // evaluated register indexes + + int fragmentProgram; + int numFragmentProgramImages; + idImage * fragmentProgramImages[MAX_FRAGMENT_IMAGES]; + + idMegaTexture *megaTexture; // handles all the binding and parameter setting +} newShaderStage_t; + +typedef struct { + int conditionRegister; // if registers[conditionRegister] == 0, skip stage + stageLighting_t lighting; // determines which passes interact with lights + int drawStateBits; + colorStage_t color; + bool hasAlphaTest; + int alphaTestRegister; + textureStage_t texture; + stageVertexColor_t vertexColor; + bool ignoreAlphaTest; // this stage should act as translucent, even + // if the surface is alpha tested + float privatePolygonOffset; // a per-stage polygon offset + + newShaderStage_t *newStage; // vertex / fragment program based stage +} shaderStage_t; + +typedef enum { + MC_BAD, + MC_OPAQUE, // completely fills the triangle, will have black drawn on fillDepthBuffer + MC_PERFORATED, // may have alpha tested holes + MC_TRANSLUCENT // blended with background +} materialCoverage_t; + +typedef enum { + SS_SUBVIEW = -3, // mirrors, viewscreens, etc + SS_GUI = -2, // guis + SS_BAD = -1, + SS_OPAQUE, // opaque + + SS_PORTAL_SKY, + + SS_DECAL, // scorch marks, etc. + + SS_FAR, + SS_MEDIUM, // normal translucent + SS_CLOSE, + + SS_ALMOST_NEAREST, // gun smoke puffs + + SS_NEAREST, // screen blood blobs + + SS_POST_PROCESS = 100 // after a screen copy to texture +} materialSort_t; + +typedef enum { + CT_FRONT_SIDED, + CT_BACK_SIDED, + CT_TWO_SIDED +} cullType_t; + +// these don't effect per-material storage, so they can be very large +const int MAX_SHADER_STAGES = 256; + +const int MAX_TEXGEN_REGISTERS = 4; + +const int MAX_ENTITY_SHADER_PARMS = 12; + +// material flags +typedef enum { + MF_DEFAULTED = BIT(0), + MF_POLYGONOFFSET = BIT(1), + MF_NOSHADOWS = BIT(2), + MF_FORCESHADOWS = BIT(3), + MF_NOSELFSHADOW = BIT(4), + MF_NOPORTALFOG = BIT(5), // this fog volume won't ever consider a portal fogged out + MF_EDITOR_VISIBLE = BIT(6) // in use (visible) per editor +} materialFlags_t; + +// contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these! +typedef enum { + CONTENTS_SOLID = BIT(0), // an eye is never valid in a solid + CONTENTS_OPAQUE = BIT(1), // blocks visibility (for ai) + CONTENTS_WATER = BIT(2), // used for water + CONTENTS_PLAYERCLIP = BIT(3), // solid to players + CONTENTS_MONSTERCLIP = BIT(4), // solid to monsters + CONTENTS_MOVEABLECLIP = BIT(5), // solid to moveable entities + CONTENTS_IKCLIP = BIT(6), // solid to IK + CONTENTS_BLOOD = BIT(7), // used to detect blood decals + CONTENTS_BODY = BIT(8), // used for actors + CONTENTS_PROJECTILE = BIT(9), // used for projectiles + CONTENTS_CORPSE = BIT(10), // used for dead bodies + CONTENTS_RENDERMODEL = BIT(11), // used for render models for collision detection + CONTENTS_TRIGGER = BIT(12), // used for triggers + CONTENTS_AAS_SOLID = BIT(13), // solid for AAS + CONTENTS_AAS_OBSTACLE = BIT(14), // used to compile an obstacle into AAS that can be enabled/disabled + CONTENTS_FLASHLIGHT_TRIGGER = BIT(15), // used for triggers that are activated by the flashlight + CONTENTS_FROBABLE = BIT(16), // TDM: Used for CMs that are only for frobbing + CONTENTS_RESPONSE = BIT(17), // TDM: Used for stim/response optimization. + CONTENTS_MELEEWEAP = BIT(18), // TDM: Used for melee weapons and shields + + // contents used by utils + CONTENTS_AREAPORTAL = BIT(20), // portal separating renderer areas + CONTENTS_NOCSG = BIT(21), // don't cut this brush with CSG operations in the editor + + CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG) +} contentsFlags_t; + +// surface types +const int NUM_SURFACE_BITS = 4; +const int MAX_SURFACE_TYPES = 1 << NUM_SURFACE_BITS; + +typedef enum { + SURFTYPE_NONE, // default type + SURFTYPE_METAL, + SURFTYPE_STONE, + SURFTYPE_FLESH, + SURFTYPE_WOOD, + SURFTYPE_CARDBOARD, + SURFTYPE_LIQUID, + SURFTYPE_GLASS, + SURFTYPE_PLASTIC, + SURFTYPE_RICOCHET, + SURFTYPE_10, + SURFTYPE_11, + SURFTYPE_12, + SURFTYPE_13, + SURFTYPE_14, + SURFTYPE_15 +} surfTypes_t; + +// surface flags +typedef enum { + SURF_TYPE_BIT0 = BIT(0), // encodes the material type (metal, flesh, concrete, etc.) + SURF_TYPE_BIT1 = BIT(1), // " + SURF_TYPE_BIT2 = BIT(2), // " + SURF_TYPE_BIT3 = BIT(3), // " + SURF_TYPE_MASK = ( 1 << NUM_SURFACE_BITS ) - 1, + + SURF_NODAMAGE = BIT(4), // never give falling damage + SURF_SLICK = BIT(5), // effects game physics + SURF_COLLISION = BIT(6), // collision surface + SURF_LADDER = BIT(7), // player can climb up this surface + SURF_NOIMPACT = BIT(8), // don't make missile explosions + SURF_NOSTEPS = BIT(9), // no footstep sounds + SURF_DISCRETE = BIT(10), // not clipped or merged by utilities + SURF_NOFRAGMENT = BIT(11), // dmap won't cut surface at each bsp boundary + SURF_NULLNORMAL = BIT(12) // renderbump will draw this surface as 0x80 0x80 0x80, which + // won't collect light from any angle +} surfaceFlags_t; + +class idSoundEmitter; + +class idMaterial : public idDecl { +public: + idMaterial(); + virtual ~idMaterial(); + + virtual size_t Size( void ) const; + virtual bool SetDefaultText( void ); + virtual const char *DefaultDefinition( void ) const; + virtual bool Parse( const char *text, const int textLength ); + virtual void FreeData( void ); + virtual void Print( void ) const; + + //BSM Nerve: Added for material editor + bool Save( const char *fileName = NULL ); + + // returns the internal image name for stage 0, which can be used + // for the renderer CaptureRenderToImage() call + // I'm not really sure why this needs to be virtual... + virtual const char *ImageName( void ) const; + + void ReloadImages( bool force ) const; + + // returns number of stages this material contains + const int GetNumStages( void ) const { return numStages; } + + // get a specific stage + const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; } + + // get the first bump map stage, or NULL if not present. + // used for bumpy-specular + const shaderStage_t *GetBumpStage( void ) const; + + // returns true if the material will draw anything at all. Triggers, portals, + // etc, will not have anything to draw. A not drawn surface can still castShadow, + // which can be used to make a simplified shadow hull for a complex object set + // as noShadow + bool IsDrawn( void ) const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); } + + // Tels: Added for TDM v1.03 + bool IsSlick( void ) const { return ((surfaceFlags & SURF_SLICK) != 0); }; + bool IsLadder( void ) const { return ((surfaceFlags & SURF_LADDER) != 0); }; + + // returns true if the material will draw any non light interaction stages + bool HasAmbient( void ) const { return ( numAmbientStages > 0 ); } + + // returns true if material has a gui + bool HasGui( void ) const { return ( entityGui != 0 || gui != NULL ); } + + // returns true if the material will generate another view, either as + // a mirror or dynamic rendered image + bool HasSubview( void ) const { return hasSubview; } + + // returns true if the material will generate shadows, not making a + // distinction between global and no-self shadows + bool SurfaceCastsShadow( void ) const { return TestMaterialFlag( MF_FORCESHADOWS ) || !TestMaterialFlag( MF_NOSHADOWS ); } + + // returns true if the material will generate interactions with fog/blend lights + // All non-translucent surfaces receive fog unless they are explicitly noFog + bool ReceivesFog( void ) const { return ( IsDrawn() && !noFog && coverage != MC_TRANSLUCENT ); } + + // returns true if the material will generate interactions with normal lights + // Many special effect surfaces don't have any bump/diffuse/specular + // stages, and don't interact with lights at all + bool ReceivesLighting( void ) const { return numAmbientStages != numStages; } + + // returns true if the material should generate interactions on sides facing away + // from light centers, as with noshadow and noselfshadow options + bool ReceivesLightingOnBackSides( void ) const { return ( materialFlags & (MF_NOSELFSHADOW|MF_NOSHADOWS) ) != 0; } + + // Standard two-sided triangle rendering won't work with bump map lighting, because + // the normal and tangent vectors won't be correct for the back sides. When two + // sided lighting is desired. typically for alpha tested surfaces, this is + // addressed by having CleanupModelSurfaces() create duplicates of all the triangles + // with apropriate order reversal. + bool ShouldCreateBackSides( void ) const { return shouldCreateBackSides; } + + // characters and models that are created by a complete renderbump can use a faster + // method of tangent and normal vector generation than surfaces which have a flat + // renderbump wrapped over them. + bool UseUnsmoothedTangents( void ) const { return unsmoothedTangents; } + + // by default, monsters can have blood overlays placed on them, but this can + // be overrided on a per-material basis with the "noOverlays" material command. + // This will always return false for translucent surfaces + bool AllowOverlays( void ) const { return allowOverlays; } + + // MC_OPAQUE, MC_PERFORATED, or MC_TRANSLUCENT, for interaction list linking and + // dmap flood filling + // The depth buffer will not be filled for MC_TRANSLUCENT surfaces + // FIXME: what do nodraw surfaces return? + materialCoverage_t Coverage( void ) const { return coverage; } + + // returns true if this material takes precedence over other in coplanar cases + bool HasHigherDmapPriority( const idMaterial &other ) const { return ( IsDrawn() && !other.IsDrawn() ) || + ( Coverage() < other.Coverage() ); } + + // returns a idUserInterface if it has a global gui, or NULL if no gui + idUserInterface * GlobalGui( void ) const { return gui; } + + // a discrete surface will never be merged with other surfaces by dmap, which is + // necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other + // special effects from being combined into a single surface + // guis, merging sprites or other effects, mirrors and remote views are always discrete + bool IsDiscrete( void ) const { return ( entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW || + ( surfaceFlags & SURF_DISCRETE ) != 0 ); } + + // Normally, dmap chops each surface by every BSP boundary, then reoptimizes. + // For gigantic polygons like sky boxes, this can cause a huge number of planar + // triangles that make the optimizer take forever to turn back into a single + // triangle. The "noFragment" option causes dmap to only break the polygons at + // area boundaries, instead of every BSP boundary. This has the negative effect + // of not automatically fixing up interpenetrations, so when this is used, you + // should manually make the edges of your sky box exactly meet, instead of poking + // into each other. + bool NoFragment( void ) const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; } + + //------------------------------------------------------------------ + // light shader specific functions, only called for light entities + + // lightshader option to fill with fog from viewer instead of light from center + bool IsFogLight() const { return fogLight; } + + // perform simple blending of the projection, instead of interacting with bumps and textures + bool IsBlendLight() const { return blendLight; } + + // an ambient light has non-directional bump mapping and no specular + bool IsAmbientLight() const { return ambientLight; } + + // implicitly no-shadows lights (ambients, fogs, etc) will never cast shadows + // but individual light entities can also override this value + bool LightCastsShadows() const { return TestMaterialFlag( MF_FORCESHADOWS ) || + ( !fogLight && !ambientLight && !blendLight && !TestMaterialFlag( MF_NOSHADOWS ) ); } + + // fog lights, blend lights, ambient lights, etc will all have to have interaction + // triangles generated for sides facing away from the light as well as those + // facing towards the light. It is debatable if noshadow lights should effect back + // sides, making everything "noSelfShadow", but that would make noshadow lights + // potentially slower than normal lights, which detracts from their optimization + // ability, so they currently do not. + bool LightEffectsBackSides() const { return fogLight || ambientLight || blendLight; } + + // NULL unless an image is explicitly specified in the shader with "lightFalloffShader " + idImage * LightFalloffImage() const { return lightFalloffImage; } + + //------------------------------------------------------------------ + + // returns the renderbump command line for this shader, or an empty string if not present + const char * GetRenderBump() const { return renderBump; }; + + // set specific material flag(s) + void SetMaterialFlag( const int flag ) const { materialFlags |= flag; } + + // clear specific material flag(s) + void ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; } + + // test for existance of specific material flag(s) + bool TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; } + + // get content flags + const int GetContentFlags( void ) const { return contentFlags; } + + // get surface flags + const int GetSurfaceFlags( void ) const { return surfaceFlags; } + + // gets name for surface type (stone, metal, flesh, etc.) + const surfTypes_t GetSurfaceType( void ) const { return static_cast( surfaceFlags & SURF_TYPE_MASK ); } + + // get material description + const char * GetDescription( void ) const { return desc; } + + // get sort order + const float GetSort( void ) const { return sort; } + // this is only used by the gui system to force sorting order + // on images referenced from tga's instead of materials. + // this is done this way as there are 2000 tgas the guis use + void SetSort( float s ) const { sort = s; }; + + // DFRM_NONE, DFRM_SPRITE, etc + deform_t Deform( void ) const { return deform; } + + // flare size, expansion size, etc + const int GetDeformRegister( int index ) const { return deformRegisters[index]; } + + // particle system to emit from surface and table for turbulent + const idDecl *GetDeformDecl( void ) const { return deformDecl; } + + // currently a surface can only have one unique texgen for all the stages + texgen_t Texgen() const; + + // wobble sky parms + const int * GetTexGenRegisters( void ) const { return texGenRegisters; } + + // get cull type + const cullType_t GetCullType( void ) const { return cullType; } + + float GetEditorAlpha( void ) const { return editorAlpha; } + + int GetEntityGui( void ) const { return entityGui; } + + decalInfo_t GetDecalInfo( void ) const { return decalInfo; } + + // spectrums are used for "invisible writing" that can only be + // illuminated by a light of matching spectrum + int Spectrum( void ) const { return spectrum; } + + float GetPolygonOffset( void ) const { return polygonOffset; } + + float GetSurfaceArea( void ) const { return surfaceArea; } + void AddToSurfaceArea( float area ) { surfaceArea += area; } + + //------------------------------------------------------------------ + + // returns the length, in milliseconds, of the videoMap on this material, + // or zero if it doesn't have one + int CinematicLength( void ) const; + + void CloseCinematic( void ) const; + + void ResetCinematicTime( int time ) const; + + void UpdateCinematic( int time ) const; + + //------------------------------------------------------------------ + + // gets an image for the editor to use + idImage * GetEditorImage( void ) const; + int GetImageWidth( void ) const; + int GetImageHeight( void ) const; + + void SetGui( const char *_gui ) const; + + // just for resource tracking + void SetImageClassifications( int tag ) const; + + //------------------------------------------------------------------ + + // returns number of registers this material contains + const int GetNumRegisters() const { return numRegisters; } + + // regs should point to a float array large enough to hold GetNumRegisters() floats + void EvaluateRegisters( float *regs, const float entityParms[MAX_ENTITY_SHADER_PARMS], + const struct viewDef_s *view, idSoundEmitter *soundEmitter = NULL ) const; + + // if a material only uses constants (no entityParm or globalparm references), this + // will return a pointer to an internal table, and EvaluateRegisters will not need + // to be called. If NULL is returned, EvaluateRegisters must be used. + const float * ConstantRegisters() const; + + bool SuppressInSubview() const { return suppressInSubview; }; + bool IsPortalSky() const { return portalSky; }; + void AddReference(); + +private: + // parse the entire material + void CommonInit(); + void ParseMaterial( idLexer &src ); + bool MatchToken( idLexer &src, const char *match ); + void ParseSort( idLexer &src ); + void ParseBlend( idLexer &src, shaderStage_t *stage ); + void ParseVertexParm( idLexer &src, newShaderStage_t *newStage ); + void ParseFragmentMap( idLexer &src, newShaderStage_t *newStage ); + void ParseStage( idLexer &src, const textureRepeat_t trpDefault = TR_REPEAT ); + void ParseDeform( idLexer &src ); + void ParseDecalInfo( idLexer &src ); + bool CheckSurfaceParm( idToken *token ); + int GetExpressionConstant( float f ); + int GetExpressionTemporary( void ); + expOp_t * GetExpressionOp( void ); + int EmitOp( int a, int b, expOpType_t opType ); + int ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority ); + int ParseTerm( idLexer &src ); + int ParseExpressionPriority( idLexer &src, int priority ); + int ParseExpression( idLexer &src ); + void ClearStage( shaderStage_t *ss ); + int NameToSrcBlendMode( const idStr &name ); + int NameToDstBlendMode( const idStr &name ); + void MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] ); // FIXME: for some reason the const is bad for gcc and Mac + void SortInteractionStages(); + void AddImplicitStages( const textureRepeat_t trpDefault = TR_REPEAT ); + void CheckForConstantRegisters(); + +private: + idStr desc; // description + idStr renderBump; // renderbump command options, without the "renderbump" at the start + + idImage * lightFalloffImage; + + int entityGui; // draw a gui with the idUserInterface from the renderEntity_t + // non zero will draw gui, gui2, or gui3 from renderEnitty_t + mutable idUserInterface *gui; // non-custom guis are shared by all users of a material + + bool noFog; // surface does not create fog interactions + + int spectrum; // for invisible writing, used for both lights and surfaces + + float polygonOffset; + + int contentFlags; // content flags + int surfaceFlags; // surface flags + mutable int materialFlags; // material flags + + decalInfo_t decalInfo; + + + mutable float sort; // lower numbered shaders draw before higher numbered + deform_t deform; + int deformRegisters[4]; // numeric parameter for deforms + const idDecl *deformDecl; // for surface emitted particle deforms and tables + + int texGenRegisters[MAX_TEXGEN_REGISTERS]; // for wobbleSky + + materialCoverage_t coverage; + cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED + bool shouldCreateBackSides; + + bool fogLight; + bool blendLight; + bool ambientLight; + bool unsmoothedTangents; + bool hasSubview; // mirror, remote render, etc + bool allowOverlays; + + int numOps; + expOp_t * ops; // evaluate to make expressionRegisters + + int numRegisters; // + float * expressionRegisters; + + float * constantRegisters; // NULL if ops ever reference globalParms or entityParms + + int numStages; + int numAmbientStages; + + shaderStage_t * stages; + + struct mtrParsingData_s *pd; // only used during parsing + + float surfaceArea; // only for listSurfaceAreas + + // we defer loading of the editor image until it is asked for, so the game doesn't load up + // all the invisible and uncompressed images. + // If editorImage is NULL, it will atempt to load editorImageName, and set editorImage to that or defaultImage + idStr editorImageName; + mutable idImage * editorImage; // image used for non-shaded preview + float editorAlpha; + + bool suppressInSubview; + bool portalSky; + int refCount; +}; + +typedef idList idMatList; + +#endif /* !__MATERIAL_H__ */ diff --git a/renderer/MegaTexture.cpp b/renderer/MegaTexture.cpp new file mode 100644 index 000000000..6383bc603 --- /dev/null +++ b/renderer/MegaTexture.cpp @@ -0,0 +1,904 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +idCVar idMegaTexture::r_megaTextureLevel( "r_megaTextureLevel", "0", CVAR_RENDERER | CVAR_INTEGER, "draw only a specific level" ); +idCVar idMegaTexture::r_showMegaTexture( "r_showMegaTexture", "0", CVAR_RENDERER | CVAR_BOOL, "display all the level images" ); +idCVar idMegaTexture::r_showMegaTextureLabels( "r_showMegaTextureLabels", "0", CVAR_RENDERER | CVAR_BOOL, "draw colored blocks in each tile" ); +idCVar idMegaTexture::r_skipMegaTexture( "r_skipMegaTexture", "0", CVAR_RENDERER | CVAR_INTEGER, "only use the lowest level image" ); +idCVar idMegaTexture::r_terrainScale( "r_terrainScale", "3", CVAR_RENDERER | CVAR_INTEGER, "vertically scale USGS data" ); + +/* + +allow sparse population of the upper detail tiles + +*/ + +int RoundDownToPowerOfTwo( int num ) { + int pot; + for (pot = 1 ; (pot*2) <= num ; pot<<=1) { + } + return pot; +} + +static union { + int intVal; + byte color[4]; +} fillColor; + +static byte colors[8][4] = { + { 0, 0, 0, 255 }, + { 255, 0, 0, 255 }, + { 0, 255, 0, 255 }, + { 255, 255, 0, 255 }, + { 0, 0, 255, 255 }, + { 255, 0, 255, 255 }, + { 0, 255, 255, 255 }, + { 255, 255, 255, 255 } +}; + +static void R_EmptyLevelImage( idImage *image ) { + int c = MAX_LEVEL_WIDTH * MAX_LEVEL_WIDTH; + byte *data = (byte *)_alloca( c*4 ); + + for ( int i = 0 ; i < c ; i++ ) { + ((int *)data)[i] = fillColor.intVal; + } + + // FIXME: this won't live past vid mode changes + image->GenerateImage( data, MAX_LEVEL_WIDTH, MAX_LEVEL_WIDTH, + TF_DEFAULT, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + + +/* +==================== +InitFromMegaFile +==================== +*/ +bool idMegaTexture::InitFromMegaFile( const char *fileBase ) { + idStr name = "megaTextures/"; + name += fileBase; + name.StripFileExtension(); + name += ".mega"; + + int width, height; + + fileHandle = fileSystem->OpenFileRead( name.c_str() ); + if ( !fileHandle ) { + common->Printf( "idMegaTexture: failed to open %s\n", name.c_str() ); + return false; + } + + fileHandle->Read( &header, sizeof( header ) ); + if ( header.tileSize < 64 || header.tilesWide < 1 || header.tilesHigh < 1 ) { + common->Printf( "idMegaTexture: bad header on %s\n", name.c_str() ); + return false; + } + + currentTriMapping = NULL; + + numLevels = 0; + width = header.tilesWide; + height = header.tilesHigh; + + int tileOffset = 1; // just past the header + + memset( levels, 0, sizeof( levels ) ); + while( 1 ) { + idTextureLevel *level = &levels[numLevels]; + + level->mega = this; + level->tileOffset = tileOffset; + level->tilesWide = width; + level->tilesHigh = height; + level->parms[0] = -1; // initially mask everything + level->parms[1] = 0; + level->parms[2] = 0; + level->parms[3] = (float)width / TILE_PER_LEVEL; + level->Invalidate(); + + tileOffset += level->tilesWide * level->tilesHigh; + + char str[1024]; + sprintf( str, "MEGA_%s_%i", fileBase, numLevels ); + + // give each level a default fill color + for (int i = 0 ; i < 4 ; i++ ) { + fillColor.color[i] = colors[numLevels+1][i]; + } + + levels[numLevels].image = globalImages->ImageFromFunction( str, R_EmptyLevelImage ); + numLevels++; + + if ( width <= TILE_PER_LEVEL && height <= TILE_PER_LEVEL ) { + break; + } + width = ( width + 1 ) >> 1; + height = ( height + 1 ) >> 1; + } + + // force first bind to load everything + currentViewOrigin[0] = -99999999.0f; + currentViewOrigin[1] = -99999999.0f; + currentViewOrigin[2] = -99999999.0f; + + return true; +} + +/* +==================== +SetMappingForSurface + +analyzes xyz and st to create a mapping +This is not very robust, but works for rectangular grids +==================== +*/ +void idMegaTexture::SetMappingForSurface( const srfTriangles_t *tri ) { + if ( tri == currentTriMapping ) { + return; + } + currentTriMapping = tri; + + if ( !tri->verts ) { + return; + } + + idDrawVert origin, axis[2]; + + origin.st[0] = 1.0; + origin.st[1] = 1.0; + + axis[0].st[0] = 0; + axis[0].st[1] = 1; + + axis[1].st[0] = 1; + axis[1].st[1] = 0; + + for ( int i = 0 ; i < tri->numVerts ; i++ ) { + idDrawVert *v = &tri->verts[i]; + + if ( v->st[0] <= origin.st[0] && v->st[1] <= origin.st[1] ) { + origin = *v; + } + if ( v->st[0] >= axis[0].st[0] && v->st[1] <= axis[0].st[1] ) { + axis[0] = *v; + } + if ( v->st[0] <= axis[1].st[0] && v->st[1] >= axis[1].st[1] ) { + axis[1] = *v; + } + } + + for ( int i = 0 ; i < 2 ; i++ ) { + idVec3 dir = axis[i].xyz - origin.xyz; + float texLen = axis[i].st[i] - origin.st[i]; + float spaceLen = (axis[i].xyz - origin.xyz).Length(); + + float scale = texLen / (spaceLen*spaceLen); + dir *= scale; + + float c = origin.xyz * dir - origin.st[i]; + + localViewToTextureCenter[i][0] = dir[0]; + localViewToTextureCenter[i][1] = dir[1]; + localViewToTextureCenter[i][2] = dir[2]; + localViewToTextureCenter[i][3] = -c; + } +} + +/* +==================== +BindForViewOrigin +==================== +*/ +void idMegaTexture::BindForViewOrigin( const idVec3 viewOrigin ) { + + SetViewOrigin( viewOrigin ); + + // borderClamp image goes in texture 0 + GL_SelectTexture( 0 ); + globalImages->borderClampImage->Bind(); + + // level images in higher textures, blurriest first + for ( int i = 0 ; i < 7 ; i++ ) { + GL_SelectTexture( 1+i ); + + if ( i >= numLevels ) { + globalImages->whiteImage->Bind(); + + static float parms[4] = { -2, -2, 0, 1 }; // no contribution + qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, parms ); + } else { + idTextureLevel *level = &levels[ numLevels-1-i ]; + + if ( r_showMegaTexture.GetBool() ) { + if ( i & 1 ) { + globalImages->blackImage->Bind(); + } else { + globalImages->whiteImage->Bind(); + } + } else { + level->image->Bind(); + } + qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, level->parms ); + } + } + + float parms[4]; + parms[0] = 0; + parms[1] = 0; + parms[2] = 0; + parms[3] = 1; + qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 7, parms ); + + parms[0] = 1; + parms[1] = 1; + parms[2] = r_terrainScale.GetFloat(); + parms[3] = 1; + qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 8, parms ); +} + +/* +==================== +Unbind + +This can go away once everything uses fragment programs so the enable states don't +need tracking +==================== +*/ +void idMegaTexture::Unbind( void ) { + for ( int i = 0 ; i < numLevels ; i++ ) { + GL_SelectTexture( 1+i ); + globalImages->BindNull(); + } +} + + +/* +==================== +SetViewOrigin +==================== +*/ +void idMegaTexture::SetViewOrigin( const idVec3 viewOrigin ) { + if ( r_showMegaTextureLabels.IsModified() ) { + r_showMegaTextureLabels.ClearModified(); + currentViewOrigin[0] = viewOrigin[0] + 0.1; // force a change + for ( int i = 0 ; i < numLevels ; i++ ) { + levels[i].Invalidate(); + } + } + + if ( viewOrigin == currentViewOrigin ) { + return; + } + if ( r_skipMegaTexture.GetBool() ) { + return; + } + + currentViewOrigin = viewOrigin; + + float texCenter[2]; + + // convert the viewOrigin to a texture center, which will + // be a different conversion for each megaTexture + for ( int i = 0 ; i < 2 ; i++ ) { + texCenter[i] = + viewOrigin[0] * localViewToTextureCenter[i][0] + + viewOrigin[1] * localViewToTextureCenter[i][1] + + viewOrigin[2] * localViewToTextureCenter[i][2] + + localViewToTextureCenter[i][3]; + } + + for ( int i = 0 ; i < numLevels ; i++ ) { + levels[i].UpdateForCenter( texCenter ); + } +} + + +/* +==================== +UpdateTile + +A local tile will only be mapped to globalTile[ localTile + X * TILE_PER_LEVEL ] for some x +==================== +*/ +void idTextureLevel::UpdateTile( int localX, int localY, int globalX, int globalY ) { + idTextureTile *tile = &tileMap[localX][localY]; + + if ( tile->x == globalX && tile->y == globalY ) { + return; + } + if ( (globalX & (TILE_PER_LEVEL-1)) != localX || (globalY & (TILE_PER_LEVEL-1)) != localY ) { + common->Error( "idTextureLevel::UpdateTile: bad coordinate mod" ); + } + + tile->x = globalX; + tile->y = globalY; + + byte data[ TILE_SIZE * TILE_SIZE * 4 ]; + + if ( globalX >= tilesWide || globalX < 0 || globalY >= tilesHigh || globalY < 0 ) { + // off the map + memset( data, 0, sizeof( data ) ); + } else { + // extract the data from the full image (FIXME: background load from disk) + int tileNum = tileOffset + tile->y * tilesWide + tile->x; + + int tileSize = TILE_SIZE * TILE_SIZE * 4; + + mega->fileHandle->Seek( tileNum * tileSize, FS_SEEK_SET ); + memset( data, 128, sizeof( data ) ); + mega->fileHandle->Read( data, tileSize ); + } + + if ( idMegaTexture::r_showMegaTextureLabels.GetBool() ) { + // put a color marker in it + byte color[4] = { 255 * localX / TILE_PER_LEVEL, 255 * localY / TILE_PER_LEVEL, 0, 0 }; + for ( int x = 0 ; x < 8 ; x++ ) { + for ( int y = 0 ; y < 8 ; y++ ) { + *(int *)&data[ ( ( y + TILE_SIZE/2 - 4 ) * TILE_SIZE + x + TILE_SIZE/2 - 4 ) * 4 ] = *(int *)color; + } + } + } + + // upload all the mip-map levels + int level = 0; + int size = TILE_SIZE; + while ( 1 ) { + qglTexSubImage2D( GL_TEXTURE_2D, level, localX * size, localY * size, size, size, GL_RGBA, GL_UNSIGNED_BYTE, data ); + size >>= 1; + level++; + + if ( size == 0 ) { + break; + } + + int byteSize = size * 4; + // mip-map in place + for ( int y = 0 ; y < size ; y++ ) { + byte *in, *in2, *out; + in = data + y * size * 16; + in2 = in + size * 8; + out = data + y * size * 4; + for ( int x = 0 ; x < size ; x++ ) { + out[x*4+0] = ( in[x*8+0] + in[x*8+4+0] + in2[x*8+0] + in2[x*8+4+0] ) >> 2; + out[x*4+1] = ( in[x*8+1] + in[x*8+4+1] + in2[x*8+1] + in2[x*8+4+1] ) >> 2; + out[x*4+2] = ( in[x*8+2] + in[x*8+4+2] + in2[x*8+2] + in2[x*8+4+2] ) >> 2; + out[x*4+3] = ( in[x*8+3] + in[x*8+4+3] + in2[x*8+3] + in2[x*8+4+3] ) >> 2; + } + } + } +} + +/* +==================== +UpdateForCenter + +Center is in the 0.0 to 1.0 range +==================== +*/ +void idTextureLevel::UpdateForCenter( float center[2] ) { + int globalTileCorner[2]; + int localTileOffset[2]; + + if ( tilesWide <= TILE_PER_LEVEL && tilesHigh <= TILE_PER_LEVEL ) { + globalTileCorner[0] = 0; + globalTileCorner[1] = 0; + localTileOffset[0] = 0; + localTileOffset[1] = 0; + // orient the mask so that it doesn't mask anything at all + parms[0] = 0.25; + parms[1] = 0.25; + parms[3] = 0.25; + } else { + for ( int i = 0 ; i < 2 ; i++ ) { + float global[2]; + + // this value will be outside the 0.0 to 1.0 range unless + // we are in the corner of the megaTexture + global[i] = ( center[i] * parms[3] - 0.5 ) * TILE_PER_LEVEL; + + globalTileCorner[i] = (int)( global[i] + 0.5 ); + + localTileOffset[i] = globalTileCorner[i] & (TILE_PER_LEVEL-1); + + // scaling for the mask texture to only allow the proper window + // of tiles to show through + parms[i] = -globalTileCorner[i] / (float)TILE_PER_LEVEL; + } + } + + image->Bind(); + + for ( int x = 0 ; x < TILE_PER_LEVEL ; x++ ) { + for ( int y = 0 ; y < TILE_PER_LEVEL ; y++ ) { + int globalTile[2]; + + globalTile[0] = globalTileCorner[0] + ( ( x - localTileOffset[0] ) & (TILE_PER_LEVEL-1) ); + globalTile[1] = globalTileCorner[1] + ( ( y - localTileOffset[1] ) & (TILE_PER_LEVEL-1) ); + + UpdateTile( x, y, globalTile[0], globalTile[1] ); + } + } +} + +/* +===================== +Invalidate + +Forces all tiles to be regenerated +===================== +*/ +void idTextureLevel::Invalidate() { + for ( int x = 0 ; x < TILE_PER_LEVEL ; x++ ) { + for ( int y = 0 ; y < TILE_PER_LEVEL ; y++ ) { + tileMap[x][y].x = + tileMap[x][y].y = -99999; + } + } +} + +//=================================================================================================== + + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + +static byte ReadByte( idFile *f ) { + byte b; + + f->Read( &b, 1 ); + return b; +} + +static short ReadShort( idFile *f ) { + byte b[2]; + + f->Read( &b, 2 ); + + return b[0] + ( b[1] << 8 ); +} + + +/* +==================== +GenerateMegaMipMaps +==================== +*/ +void idMegaTexture::GenerateMegaMipMaps( megaTextureHeader_t *header, idFile *outFile ) { + outFile->Flush(); + + // out fileSystem doesn't allow read / write access... + idFile *inFile = fileSystem->OpenFileRead( outFile->GetName() ); + + int tileOffset = 1; + int width = header->tilesWide; + int height = header->tilesHigh; + + int tileSize = header->tileSize * header->tileSize * 4; + byte *oldBlock = (byte *)_alloca( tileSize ); + byte *newBlock = (byte *)_alloca( tileSize ); + + while ( width > 1 || height > 1 ) { + int newHeight = (height+1) >> 1; + if ( newHeight < 1 ) { + newHeight = 1; + } + int newWidth = (width+1) >> 1; + if ( width < 1 ) { + width = 1; + } + common->Printf( "generating %i x %i block mip level\n", newWidth, newHeight ); + + int tileNum; + + for ( int y = 0 ; y < newHeight ; y++ ) { + common->Printf( "row %i\n", y ); + session->UpdateScreen(); + + for ( int x = 0 ; x < newWidth ; x++ ) { + // mip map four original blocks down into a single new block + for ( int yy = 0 ; yy < 2 ; yy++ ) { + for ( int xx = 0 ; xx< 2 ; xx++ ) { + int tx = x*2 + xx; + int ty = y*2 + yy; + + if ( tx > width || ty > height ) { + // off edge, zero fill + memset( newBlock, 0, sizeof( newBlock ) ); + } else { + tileNum = tileOffset + ty * width + tx; + inFile->Seek( tileNum * tileSize, FS_SEEK_SET ); + inFile->Read( oldBlock, tileSize ); + } + // mip map the new pixels + for ( int yyy = 0 ; yyy < TILE_SIZE / 2 ; yyy++ ) { + for ( int xxx = 0 ; xxx < TILE_SIZE / 2 ; xxx++ ) { + byte *in = &oldBlock[ ( yyy * 2 * TILE_SIZE + xxx * 2 ) * 4 ]; + byte *out = &newBlock[ ( ( ( TILE_SIZE/2 * yy ) + yyy ) * TILE_SIZE + ( TILE_SIZE/2 * xx ) + xxx ) * 4 ]; + out[0] = ( in[0] + in[4] + in[0+TILE_SIZE*4] + in[4+TILE_SIZE*4] ) >> 2; + out[1] = ( in[1] + in[5] + in[1+TILE_SIZE*4] + in[5+TILE_SIZE*4] ) >> 2; + out[2] = ( in[2] + in[6] + in[2+TILE_SIZE*4] + in[6+TILE_SIZE*4] ) >> 2; + out[3] = ( in[3] + in[7] + in[3+TILE_SIZE*4] + in[7+TILE_SIZE*4] ) >> 2; + } + } + + // write the block out + tileNum = tileOffset + width * height + y * newWidth + x; + outFile->Seek( tileNum * tileSize, FS_SEEK_SET ); + outFile->Write( newBlock, tileSize ); + + } + } + } + } + tileOffset += width * height; + width = newWidth; + height = newHeight; + } + + delete inFile; +} + +/* +==================== +GenerateMegaPreview + +Make a 2k x 2k preview image for a mega texture that can be used in modeling programs +==================== +*/ +void idMegaTexture::GenerateMegaPreview( const char *fileName ) { + idFile *fileHandle = fileSystem->OpenFileRead( fileName ); + if ( !fileHandle ) { + common->Printf( "idMegaTexture: failed to open %s\n", fileName ); + return; + } + + idStr outName = fileName; + outName.StripFileExtension(); + outName += "_preview.tga"; + + common->Printf( "Creating %s.\n", outName.c_str() ); + + megaTextureHeader_t header; + + fileHandle->Read( &header, sizeof( header ) ); + if ( header.tileSize < 64 || header.tilesWide < 1 || header.tilesHigh < 1 ) { + common->Printf( "idMegaTexture: bad header on %s\n", fileName ); + return; + } + + int tileSize = header.tileSize; + int width = header.tilesWide; + int height = header.tilesHigh; + int tileOffset = 1; + int tileBytes = tileSize * tileSize * 4; + // find the level that fits + while ( width * tileSize > 2048 || height * tileSize > 2048 ) { + tileOffset += width * height; + width >>= 1; + if ( width < 1 ) { + width = 1; + } + height >>= 1; + if ( height < 1 ) { + height = 1; + } + } + + byte *pic = (byte *)R_StaticAlloc( width * height * tileBytes ); + byte *oldBlock = (byte *)_alloca( tileBytes ); + for ( int y = 0 ; y < height ; y++ ) { + for ( int x = 0 ; x < width ; x++ ) { + int tileNum = tileOffset + y * width + x; + fileHandle->Seek( tileNum * tileBytes, FS_SEEK_SET ); + fileHandle->Read( oldBlock, tileBytes ); + + for ( int yy = 0 ; yy < tileSize ; yy++ ) { + memcpy( pic + ( ( y * tileSize + yy ) * width * tileSize + x * tileSize ) * 4, + oldBlock + yy * tileSize * 4, tileSize * 4 ); + } + } + } + + R_WriteTGA( outName.c_str(), pic, width * tileSize, height * tileSize, false ); + + R_StaticFree( pic ); + + delete fileHandle; +} + + +/* +==================== +MakeMegaTexture_f + +Incrementally load a giant tga file and process into the mega texture block format +==================== +*/ +void idMegaTexture::MakeMegaTexture_f( const idCmdArgs &args ) { + int columns, rows, fileSize, numBytes; + byte *pixbuf; + int row, column; + TargaHeader targa_header; + + if ( args.Argc() != 2 ) { + common->Printf( "USAGE: makeMegaTexture \n" ); + return; + } + + idStr name_s = "megaTextures/"; + name_s += args.Argv(1); + name_s.StripFileExtension(); + name_s += ".tga"; + + const char *name = name_s.c_str(); + + // + // open the file + // + common->Printf( "Opening %s.\n", name ); + fileSize = fileSystem->ReadFile( name, NULL, NULL ); + idFile *file = fileSystem->OpenFileRead( name ); + + if ( !file ) { + common->Printf( "Couldn't open %s\n", name ); + return; + } + + targa_header.id_length = ReadByte( file ); + targa_header.colormap_type = ReadByte( file ); + targa_header.image_type = ReadByte( file ); + + targa_header.colormap_index = ReadShort( file ); + targa_header.colormap_length = ReadShort( file ); + targa_header.colormap_size = ReadByte( file ); + targa_header.x_origin = ReadShort( file ); + targa_header.y_origin = ReadShort( file ); + targa_header.width = ReadShort( file ); + targa_header.height = ReadShort( file ); + targa_header.pixel_size = ReadByte( file ); + targa_header.attributes = ReadByte( file ); + + if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) { + common->Error( "LoadTGA( %s ): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name ); + } + + if ( targa_header.colormap_type != 0 ) { + common->Error( "LoadTGA( %s ): colormaps not supported\n", name ); + } + + if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) { + common->Error( "LoadTGA( %s ): Only 32 or 24 bit images supported (no colormaps)\n", name ); + } + + if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) { + numBytes = targa_header.width * targa_header.height * ( targa_header.pixel_size >> 3 ); + if ( numBytes > fileSize - 18 - targa_header.id_length ) { + common->Error( "LoadTGA( %s ): incomplete file\n", name ); + } + } + + columns = targa_header.width; + rows = targa_header.height; + + // skip TARGA image comment + if ( targa_header.id_length != 0 ) { + file->Seek( targa_header.id_length, FS_SEEK_CUR ); + } + + megaTextureHeader_t mtHeader; + + mtHeader.tileSize = TILE_SIZE; + mtHeader.tilesWide = RoundDownToPowerOfTwo( targa_header.width ) / TILE_SIZE; + mtHeader.tilesHigh = RoundDownToPowerOfTwo( targa_header.height ) / TILE_SIZE; + + idStr outName = name; + outName.StripFileExtension(); + outName += ".mega"; + + common->Printf( "Writing %i x %i size %i tiles to %s.\n", + mtHeader.tilesWide, mtHeader.tilesHigh, mtHeader.tileSize, outName.c_str() ); + + // open the output megatexture file + idFile *out = fileSystem->OpenFileWrite( outName.c_str() ); + + out->Write( &mtHeader, sizeof( mtHeader ) ); + out->Seek( TILE_SIZE * TILE_SIZE * 4, FS_SEEK_SET ); + + // we will process this one row of tiles at a time, since the entire thing + // won't fit in memory + byte *targa_rgba = (byte *)R_StaticAlloc( TILE_SIZE * targa_header.width * 4 ); + + int blockRowsRemaining = mtHeader.tilesHigh; + while ( blockRowsRemaining-- ) { + common->Printf( "%i blockRowsRemaining\n", blockRowsRemaining ); + session->UpdateScreen(); + + if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) { + // Uncompressed RGB or gray scale image + for( row = 0 ; row < TILE_SIZE ; row++ ) { + pixbuf = targa_rgba + row*columns*4; + for( column = 0; column < columns; column++) { + unsigned char red,green,blue,alphabyte; + switch( targa_header.pixel_size ) { + case 8: + blue = ReadByte( file ); + green = blue; + red = blue; + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + + case 24: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + alphabyte = ReadByte( file ); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + } + } + } else if ( targa_header.image_type == 10 ) { // Runlength encoded RGB images + unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; + + red = 0; + green = 0; + blue = 0; + alphabyte = 0xff; + + for( row = 0 ; row < TILE_SIZE ; row++ ) { + pixbuf = targa_rgba + row*columns*4; + for( column = 0; column < columns; ) { + packetHeader= ReadByte( file ); + packetSize = 1 + (packetHeader & 0x7f); + if ( packetHeader & 0x80 ) { // run-length packet + switch( targa_header.pixel_size ) { + case 24: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + alphabyte = 255; + break; + case 32: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + alphabyte = ReadByte( file ); + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + + for( j = 0; j < packetSize; j++ ) { + *pixbuf++=red; + *pixbuf++=green; + *pixbuf++=blue; + *pixbuf++=alphabyte; + column++; + if ( column == columns ) { // run spans across rows + common->Error( "TGA had RLE across columns, probably breaks block" ); + column = 0; + if ( row > 0) { + row--; + } + else { + goto breakOut; + } + pixbuf = targa_rgba + row*columns*4; + } + } + } else { // non run-length packet + for( j = 0; j < packetSize; j++ ) { + switch( targa_header.pixel_size ) { + case 24: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = ReadByte( file ); + green = ReadByte( file ); + red = ReadByte( file ); + alphabyte = ReadByte( file ); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + default: + common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size ); + break; + } + column++; + if ( column == columns ) { // pixel packet run spans across rows + column = 0; + if ( row > 0 ) { + row--; + } + else { + goto breakOut; + } + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut: ; + } + } + + // + // write out individual blocks from the full row block buffer + // + for ( int rowBlock = 0 ; rowBlock < mtHeader.tilesWide ; rowBlock++ ) { + for ( int y = 0 ; y < TILE_SIZE ; y++ ) { + out->Write( targa_rgba + ( y * targa_header.width + rowBlock * TILE_SIZE ) * 4, TILE_SIZE * 4 ); + } + } + } + + R_StaticFree( targa_rgba ); + + GenerateMegaMipMaps( &mtHeader, out ); + + delete out; + delete file; + + GenerateMegaPreview( outName.c_str() ); +#if 0 + if ( (targa_header.attributes & (1<<5)) ) { // image flp bit + R_VerticalFlip( *pic, *width, *height ); + } +#endif +} + + diff --git a/renderer/MegaTexture.h b/renderer/MegaTexture.h new file mode 100644 index 000000000..3b149a03c --- /dev/null +++ b/renderer/MegaTexture.h @@ -0,0 +1,90 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +class idTextureTile { +public: + int x, y; +}; + +static const int TILE_PER_LEVEL = 4; +static const int MAX_MEGA_CHANNELS = 3; // normal, diffuse, specular +static const int MAX_LEVELS = 12; +static const int MAX_LEVEL_WIDTH = 512; +static const int TILE_SIZE = MAX_LEVEL_WIDTH / TILE_PER_LEVEL; + +class idMegaTexture; + +class idTextureLevel { +public: + idMegaTexture *mega; + + int tileOffset; + int tilesWide; + int tilesHigh; + + idImage *image; + idTextureTile tileMap[TILE_PER_LEVEL][TILE_PER_LEVEL]; + + float parms[4]; + + void UpdateForCenter( float center[2] ); + void UpdateTile( int localX, int localY, int globalX, int globalY ); + void Invalidate(); +}; + +typedef struct { + int tileSize; + int tilesWide; + int tilesHigh; +} megaTextureHeader_t; + + +class idMegaTexture { +public: + bool InitFromMegaFile( const char *fileBase ); + void SetMappingForSurface( const srfTriangles_t *tri ); // analyzes xyz and st to create a mapping + void BindForViewOrigin( const idVec3 origin ); // binds images and sets program parameters + void Unbind(); // removes texture bindings + + static void MakeMegaTexture_f( const idCmdArgs &args ); +private: +friend class idTextureLevel; + void SetViewOrigin( const idVec3 origin ); + static void GenerateMegaMipMaps( megaTextureHeader_t *header, idFile *file ); + static void GenerateMegaPreview( const char *fileName ); + + idFile *fileHandle; + + const srfTriangles_t *currentTriMapping; + + idVec3 currentViewOrigin; + + float localViewToTextureCenter[2][4]; + + int numLevels; + idTextureLevel levels[MAX_LEVELS]; // 0 is the highest resolution + megaTextureHeader_t header; + + static idCVar r_megaTextureLevel; + static idCVar r_showMegaTexture; + static idCVar r_showMegaTextureLabels; + static idCVar r_skipMegaTexture; + static idCVar r_terrainScale; +}; + diff --git a/renderer/Model.cpp b/renderer/Model.cpp new file mode 100644 index 000000000..699236eb7 --- /dev/null +++ b/renderer/Model.cpp @@ -0,0 +1,2319 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" +#include "Model_ase.h" +#include "Model_lwo.h" +#include "Model_ma.h" + +idCVar idRenderModelStatic::r_mergeModelSurfaces( "r_mergeModelSurfaces", "1", CVAR_BOOL|CVAR_RENDERER, "combine model surfaces with the same material" ); +idCVar idRenderModelStatic::r_slopVertex( "r_slopVertex", "0.01", CVAR_RENDERER, "merge xyz coordinates this far apart" ); +idCVar idRenderModelStatic::r_slopTexCoord( "r_slopTexCoord", "0.001", CVAR_RENDERER, "merge texture coordinates this far apart" ); +idCVar idRenderModelStatic::r_slopNormal( "r_slopNormal", "0.02", CVAR_RENDERER, "merge normals that dot less than this" ); + +/* +================ +idRenderModelStatic::idRenderModelStatic +================ +*/ +idRenderModelStatic::idRenderModelStatic() { + name = ""; + bounds.Clear(); + lastModifiedFrame = 0; + lastArchivedFrame = 0; + overlaysAdded = 0; + shadowHull = NULL; + isStaticWorldModel = false; + defaulted = false; + purged = false; + fastLoad = false; + reloadable = true; + levelLoadReferenced = false; + timeStamp = 0; +} + +/* +================ +idRenderModelStatic::~idRenderModelStatic +================ +*/ +idRenderModelStatic::~idRenderModelStatic() { + PurgeModel(); +} + +/* +============== +idRenderModelStatic::Print +============== +*/ +void idRenderModelStatic::Print() const { + common->Printf( "%s\n", name.c_str() ); + common->Printf( "Static model.\n" ); + common->Printf( "bounds: (%f %f %f) to (%f %f %f)\n", + bounds[0][0], bounds[0][1], bounds[0][2], + bounds[1][0], bounds[1][1], bounds[1][2] ); + + common->Printf( " verts tris material\n" ); + for ( int i = 0 ; i < NumSurfaces() ; i++ ) { + const modelSurface_t *surf = Surface( i ); + + srfTriangles_t *tri = surf->geometry; + const idMaterial *material = surf->shader; + + if ( !tri ) { + common->Printf( "%2i: %s, NULL surface geometry\n", i, material->GetName() ); + continue; + } + + common->Printf( "%2i: %5i %5i %s", i, tri->numVerts, tri->numIndexes / 3, material->GetName() ); + if ( tri->generateNormals ) { + common->Printf( " (smoothed)\n" ); + } else { + common->Printf( "\n" ); + } + } +} + +/* +============== +idRenderModelStatic::Memory +============== +*/ +int idRenderModelStatic::Memory() const { + int totalBytes = 0; + + totalBytes += sizeof( *this ); + totalBytes += name.DynamicMemoryUsed(); + totalBytes += surfaces.MemoryUsed(); + + if ( shadowHull ) { + totalBytes += R_TriSurfMemory( shadowHull ); + } + + for ( int j = 0 ; j < NumSurfaces() ; j++ ) { + const modelSurface_t *surf = Surface( j ); + if ( !surf->geometry ) { + continue; + } + totalBytes += R_TriSurfMemory( surf->geometry ); + } + + return totalBytes; +} + +/* +============== +idRenderModelStatic::List +============== +*/ +void idRenderModelStatic::List() const { + int totalTris = 0; + int totalVerts = 0; + int totalBytes = 0; + + totalBytes = Memory(); + + char closed = 'C'; + for ( int j = 0 ; j < NumSurfaces() ; j++ ) { + const modelSurface_t *surf = Surface( j ); + if ( !surf->geometry ) { + continue; + } + if ( !surf->geometry->perfectHull ) { + closed = ' '; + } + totalTris += surf->geometry->numIndexes / 3; + totalVerts += surf->geometry->numVerts; + } + common->Printf( "%c%4ik %3i %4i %4i %s", closed, totalBytes/1024, NumSurfaces(), totalVerts, totalTris, Name() ); + + if ( IsDynamicModel() == DM_CACHED ) { + common->Printf( " (DM_CACHED)" ); + } + if ( IsDynamicModel() == DM_CONTINUOUS ) { + common->Printf( " (DM_CONTINUOUS)" ); + } + if ( defaulted ) { + common->Printf( " (DEFAULTED)" ); + } + if ( bounds[0][0] >= bounds[1][0] ) { + common->Printf( " (EMPTY BOUNDS)" ); + } + if ( bounds[1][0] - bounds[0][0] > 100000 ) { + common->Printf( " (HUGE BOUNDS)" ); + } + + common->Printf( "\n" ); +} + +/* +================ +idRenderModelStatic::IsDefaultModel +================ +*/ +bool idRenderModelStatic::IsDefaultModel() const { + return defaulted; +} + +/* +================ +AddCubeFace +================ +*/ +static void AddCubeFace( srfTriangles_t *tri, idVec3 v1, idVec3 v2, idVec3 v3, idVec3 v4 ) { + tri->verts[tri->numVerts+0].Clear(); + tri->verts[tri->numVerts+0].xyz = v1 * 8; + tri->verts[tri->numVerts+0].st[0] = 0; + tri->verts[tri->numVerts+0].st[1] = 0; + + tri->verts[tri->numVerts+1].Clear(); + tri->verts[tri->numVerts+1].xyz = v2 * 8; + tri->verts[tri->numVerts+1].st[0] = 1; + tri->verts[tri->numVerts+1].st[1] = 0; + + tri->verts[tri->numVerts+2].Clear(); + tri->verts[tri->numVerts+2].xyz = v3 * 8; + tri->verts[tri->numVerts+2].st[0] = 1; + tri->verts[tri->numVerts+2].st[1] = 1; + + tri->verts[tri->numVerts+3].Clear(); + tri->verts[tri->numVerts+3].xyz = v4 * 8; + tri->verts[tri->numVerts+3].st[0] = 0; + tri->verts[tri->numVerts+3].st[1] = 1; + + tri->indexes[tri->numIndexes+0] = tri->numVerts + 0; + tri->indexes[tri->numIndexes+1] = tri->numVerts + 1; + tri->indexes[tri->numIndexes+2] = tri->numVerts + 2; + tri->indexes[tri->numIndexes+3] = tri->numVerts + 0; + tri->indexes[tri->numIndexes+4] = tri->numVerts + 2; + tri->indexes[tri->numIndexes+5] = tri->numVerts + 3; + + tri->numVerts += 4; + tri->numIndexes += 6; +} + +/* +================ +idRenderModelStatic::MakeDefaultModel +================ +*/ +void idRenderModelStatic::MakeDefaultModel() { + + defaulted = true; + + // throw out any surfaces we already have + PurgeModel(); + + // create one new surface + modelSurface_t surf; + + srfTriangles_t *tri = R_AllocStaticTriSurf(); + + surf.shader = tr.defaultMaterial; + surf.geometry = tri; + + R_AllocStaticTriSurfVerts( tri, 24 ); + R_AllocStaticTriSurfIndexes( tri, 36 ); + + AddCubeFace( tri, idVec3(-1, 1, 1), idVec3(1, 1, 1), idVec3(1, -1, 1), idVec3(-1, -1, 1) ); + AddCubeFace( tri, idVec3(-1, 1, -1), idVec3(-1, -1, -1), idVec3(1, -1, -1), idVec3(1, 1, -1) ); + + AddCubeFace( tri, idVec3(1, -1, 1), idVec3(1, 1, 1), idVec3(1, 1, -1), idVec3(1, -1, -1) ); + AddCubeFace( tri, idVec3(-1, -1, 1), idVec3(-1, -1, -1), idVec3(-1, 1, -1), idVec3(-1, 1, 1) ); + + AddCubeFace( tri, idVec3(-1, -1, 1), idVec3(1, -1, 1), idVec3(1, -1, -1), idVec3(-1, -1, -1) ); + AddCubeFace( tri, idVec3(-1, 1, 1), idVec3(-1, 1, -1), idVec3(1, 1, -1), idVec3(1, 1, 1) ); + + tri->generateNormals = true; + + AddSurface( surf ); + FinishSurfaces(); +} + +/* +================ +idRenderModelStatic::PartialInitFromFile +================ +*/ +void idRenderModelStatic::PartialInitFromFile( const char *fileName ) { + fastLoad = true; + InitFromFile( fileName ); +} + +/* +================ +idRenderModelStatic::InitFromFile +================ +*/ +void idRenderModelStatic::InitFromFile( const char *fileName ) { + bool loaded; + idStr extension; + + InitEmpty( fileName ); + + // FIXME: load new .proc map format + + name.ExtractFileExtension( extension ); + + if ( extension.Icmp( "ase" ) == 0 ) { + loaded = LoadASE( name ); + reloadable = true; + } else if ( extension.Icmp( "lwo" ) == 0 ) { + loaded = LoadLWO( name ); + reloadable = true; + } else if ( extension.Icmp( "flt" ) == 0 ) { + loaded = LoadFLT( name ); + reloadable = true; + } else if ( extension.Icmp( "ma" ) == 0 ) { + loaded = LoadMA( name ); + reloadable = true; + } else { + common->Warning( "idRenderModelStatic::InitFromFile: unknown type for model: \'%s\'", name.c_str() ); + loaded = false; + } + + if ( !loaded ) { + common->Warning( "Couldn't load model: '%s'", name.c_str() ); + MakeDefaultModel(); + return; + } + + // it is now available for use + purged = false; + + // create the bounds for culling and dynamic surface creation + FinishSurfaces(); +} + +/* +================ +idRenderModelStatic::LoadModel +================ +*/ +void idRenderModelStatic::LoadModel() { + PurgeModel(); + InitFromFile( name ); +} + +/* +================ +idRenderModelStatic::InitEmpty +================ +*/ +void idRenderModelStatic::InitEmpty( const char *fileName ) { + // model names of the form _area* are static parts of the + // world, and have already been considered for optimized shadows + // other model names are inline entity models, and need to be + // shadowed normally + if ( !idStr::Cmpn( fileName, "_area", 5 ) ) { + isStaticWorldModel = true; + } else { + isStaticWorldModel = false; + } + + name = fileName; + reloadable = false; // if it didn't come from a file, we can't reload it + PurgeModel(); + purged = false; + bounds.Zero(); +} + +/* +================ +idRenderModelStatic::AddSurface +================ +*/ +void idRenderModelStatic::AddSurface( modelSurface_t surface ) { + surfaces.Append( surface ); + if ( surface.geometry ) { + bounds += surface.geometry->bounds; + } +} + +/* +================ +idRenderModelStatic::Name +================ +*/ +const char *idRenderModelStatic::Name() const { + return name; +} + +/* +================ +idRenderModelStatic::Timestamp +================ +*/ +ID_TIME_T idRenderModelStatic::Timestamp() const { + return timeStamp; +} + +/* +================ +idRenderModelStatic::NumSurfaces +================ +*/ +int idRenderModelStatic::NumSurfaces() const { + return surfaces.Num(); +} + +/* +================ +idRenderModelStatic::NumBaseSurfaces +================ +*/ +int idRenderModelStatic::NumBaseSurfaces() const { + return surfaces.Num() - overlaysAdded; +} + +/* +================ +idRenderModelStatic::Surface +================ +*/ +const modelSurface_t *idRenderModelStatic::Surface( int surfaceNum ) const { + return &surfaces[surfaceNum]; +} + +/* +================ +idRenderModelStatic::AllocSurfaceTriangles +================ +*/ +srfTriangles_t *idRenderModelStatic::AllocSurfaceTriangles( int numVerts, int numIndexes ) const { + srfTriangles_t *tri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( tri, numVerts ); + R_AllocStaticTriSurfIndexes( tri, numIndexes ); + return tri; +} + +/* +================ +idRenderModelStatic::FreeSurfaceTriangles +================ +*/ +void idRenderModelStatic::FreeSurfaceTriangles( srfTriangles_t *tris ) const { + R_FreeStaticTriSurf( tris ); +} + +/* +================ +idRenderModelStatic::ShadowHull +================ +*/ +srfTriangles_t *idRenderModelStatic::ShadowHull() const { + return shadowHull; +} + +/* +================ +idRenderModelStatic::IsStaticWorldModel +================ +*/ +bool idRenderModelStatic::IsStaticWorldModel() const { + return isStaticWorldModel; +} + +/* +================ +idRenderModelStatic::IsDynamicModel +================ +*/ +dynamicModel_t idRenderModelStatic::IsDynamicModel() const { + // dynamic subclasses will override this + return DM_STATIC; +} + +/* +================ +idRenderModelStatic::IsReloadable +================ +*/ +bool idRenderModelStatic::IsReloadable() const { + return reloadable; +} + +/* +================ +idRenderModelStatic::Bounds +================ +*/ +idBounds idRenderModelStatic::Bounds( const struct renderEntity_s *mdef ) const { + return bounds; +} + +/* +================ +idRenderModelStatic::DepthHack +================ +*/ +float idRenderModelStatic::DepthHack() const { + return 0.0f; +} + +/* +================ +idRenderModelStatic::InstantiateDynamicModel +================ +*/ +idRenderModel *idRenderModelStatic::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) { + if ( cachedModel ) { + delete cachedModel; + cachedModel = NULL; + } + common->Error( "InstantiateDynamicModel called on static model '%s'", name.c_str() ); + return NULL; +} + +/* +================ +idRenderModelStatic::NumJoints +================ +*/ +int idRenderModelStatic::NumJoints( void ) const { + return 0; +} + +/* +================ +idRenderModelStatic::GetJoints +================ +*/ +const idMD5Joint *idRenderModelStatic::GetJoints( void ) const { + return NULL; +} + +/* +================ +idRenderModelStatic::GetJointHandle +================ +*/ +jointHandle_t idRenderModelStatic::GetJointHandle( const char *name ) const { + return INVALID_JOINT; +} + +/* +================ +idRenderModelStatic::GetJointName +================ +*/ +const char * idRenderModelStatic::GetJointName( jointHandle_t handle ) const { + return ""; +} + +/* +================ +idRenderModelStatic::GetDefaultPose +================ +*/ +const idJointQuat *idRenderModelStatic::GetDefaultPose( void ) const { + return NULL; +} + +/* +================ +idRenderModelStatic::NearestJoint +================ +*/ +int idRenderModelStatic::NearestJoint( int surfaceNum, int a, int b, int c ) const { + return INVALID_JOINT; +} + + +//===================================================================== + + +/* +================ +idRenderModelStatic::FinishSurfaces + +The mergeShadows option allows surfaces with different textures to share +silhouette edges for shadow calculation, instead of leaving shared edges +hanging. + +If any of the original shaders have the noSelfShadow flag set, the surfaces +can't be merged, because they will need to be drawn in different order. + +If there is only one surface, a separate merged surface won't be generated. + +A model with multiple surfaces can't later have a skinned shader change the +state of the noSelfShadow flag. + +----------------- + +Creates mirrored copies of two sided surfaces with normal maps, which would +otherwise light funny. + +Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges. + +================ +*/ +void idRenderModelStatic::FinishSurfaces() { + int i; + int totalVerts, totalIndexes; + + purged = false; + + // make sure we don't have a huge bounds even if we don't finish everything + bounds.Zero(); + + if ( surfaces.Num() == 0 ) { + return; + } + + // renderBump doesn't care about most of this + if ( fastLoad ) { + bounds.Zero(); + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + R_BoundTriSurf( surf->geometry ); + bounds.AddBounds( surf->geometry->bounds ); + } + + return; + } + + // cleanup all the final surfaces, but don't create sil edges + totalVerts = 0; + totalIndexes = 0; + + // decide if we are going to merge all the surfaces into one shadower + int numOriginalSurfaces = surfaces.Num(); + + // make sure there aren't any NULL shaders or geometry + for ( i = 0 ; i < numOriginalSurfaces ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + if ( surf->geometry == NULL || surf->shader == NULL ) { + MakeDefaultModel(); + common->Error( "Model %s, surface %i had NULL geometry", name.c_str(), i ); + } + if ( surf->shader == NULL ) { + MakeDefaultModel(); + common->Error( "Model %s, surface %i had NULL shader", name.c_str(), i ); + } + } + + // duplicate and reverse triangles for two sided bump mapped surfaces + // note that this won't catch surfaces that have their shaders dynamically + // changed, and won't work with animated models. + // It is better to create completely separate surfaces, rather than + // add vertexes and indexes to the existing surface, because the + // tangent generation wouldn't like the acute shared edges + for ( i = 0 ; i < numOriginalSurfaces ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + if ( surf->shader->ShouldCreateBackSides() ) { + srfTriangles_t *newTri; + + newTri = R_CopyStaticTriSurf( surf->geometry ); + R_ReverseTriangles( newTri ); + + modelSurface_t newSurf; + + newSurf.shader = surf->shader; + newSurf.geometry = newTri; + + AddSurface( newSurf ); + } + } + + // clean the surfaces + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() ); + if ( surf->shader->SurfaceCastsShadow() ) { + totalVerts += surf->geometry->numVerts; + totalIndexes += surf->geometry->numIndexes; + } + } + + // add up the total surface area for development information + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + srfTriangles_t *tri = surf->geometry; + + for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) { + float area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz, + tri->verts[tri->indexes[j+1]].xyz, tri->verts[tri->indexes[j+2]].xyz ); + const_cast(surf->shader)->AddToSurfaceArea( area ); + } + } + + // calculate the bounds + if ( surfaces.Num() == 0 ) { + bounds.Zero(); + } else { + bounds.Clear(); + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + modelSurface_t *surf = &surfaces[i]; + + // if the surface has a deformation, increase the bounds + // the amount here is somewhat arbitrary, designed to handle + // autosprites and flares, but could be done better with exact + // deformation information. + // Note that this doesn't handle deformations that are skinned in + // at run time... + if ( surf->shader->Deform() != DFRM_NONE ) { + srfTriangles_t *tri = surf->geometry; + idVec3 mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f; + float radius = ( tri->bounds[0] - mid ).Length(); + radius += 20.0f; + + tri->bounds[0][0] = mid[0] - radius; + tri->bounds[0][1] = mid[1] - radius; + tri->bounds[0][2] = mid[2] - radius; + + tri->bounds[1][0] = mid[0] + radius; + tri->bounds[1][1] = mid[1] + radius; + tri->bounds[1][2] = mid[2] + radius; + } + + // add to the model bounds + bounds.AddBounds( surf->geometry->bounds ); + + } + } +} + +/* +================= +idRenderModelStatic::ConvertASEToModelSurfaces +================= +*/ +typedef struct matchVert_s { + struct matchVert_s *next; + int v, tv; + byte color[4]; + idVec3 normal; +} matchVert_t; + +bool idRenderModelStatic::ConvertASEToModelSurfaces( const struct aseModel_s *ase ) { + aseObject_t * object; + aseMesh_t * mesh; + aseMaterial_t * material; + const idMaterial *im1, *im2; + srfTriangles_t *tri; + int objectNum; + int i, j, k; + int v, tv; + int * vRemap; + int * tvRemap; + matchVert_t * mvTable; // all of the match verts + matchVert_t ** mvHash; // points inside mvTable for each xyz index + matchVert_t * lastmv; + matchVert_t * mv; + idVec3 normal; + float uOffset, vOffset, textureSin, textureCos; + float uTiling, vTiling; + int * mergeTo; + byte * color; + static byte identityColor[4] = { 255, 255, 255, 255 }; + modelSurface_t surf, *modelSurf; + + if ( !ase ) { + return false; + } + if ( ase->objects.Num() < 1 ) { + return false; + } + + timeStamp = ase->timeStamp; + + // the modeling programs can save out multiple surfaces with a common + // material, but we would like to mege them together where possible + // meaning that this->NumSurfaces() <= ase->objects.currentElements + mergeTo = (int *)_alloca( ase->objects.Num() * sizeof( *mergeTo ) ); + surf.geometry = NULL; + if ( ase->materials.Num() == 0 ) { + // if we don't have any materials, dump everything into a single surface + surf.shader = tr.defaultMaterial; + surf.id = 0; + this->AddSurface( surf ); + for ( i = 0 ; i < ase->objects.Num() ; i++ ) { + mergeTo[i] = 0; + } + } else if ( !r_mergeModelSurfaces.GetBool() ) { + // don't merge any + for ( i = 0 ; i < ase->objects.Num() ; i++ ) { + mergeTo[i] = i; + object = ase->objects[i]; + material = ase->materials[object->materialRef]; + surf.shader = declManager->FindMaterial( material->name ); + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } else { + // search for material matches + for ( i = 0 ; i < ase->objects.Num() ; i++ ) { + object = ase->objects[i]; + material = ase->materials[object->materialRef]; + im1 = declManager->FindMaterial( material->name ); + if ( im1->IsDiscrete() ) { + // flares, autosprites, etc + j = this->NumSurfaces(); + } else { + for ( j = 0 ; j < this->NumSurfaces() ; j++ ) { + modelSurf = &this->surfaces[j]; + im2 = modelSurf->shader; + if ( im1 == im2 ) { + // merge this + mergeTo[i] = j; + break; + } + } + } + if ( j == this->NumSurfaces() ) { + // didn't merge + mergeTo[i] = j; + surf.shader = im1; + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } + } + + idVectorSubset vertexSubset; + idVectorSubset texCoordSubset; + + // build the surfaces + for ( objectNum = 0 ; objectNum < ase->objects.Num() ; objectNum++ ) { + object = ase->objects[objectNum]; + mesh = &object->mesh; + material = ase->materials[object->materialRef]; + im1 = declManager->FindMaterial( material->name ); + + bool normalsParsed = mesh->normalsParsed; + + // completely ignore any explict normals on surfaces with a renderbump command + // which will guarantee the best contours and least vertexes. + const char *rb = im1->GetRenderBump(); + if ( rb && rb[0] ) { + normalsParsed = false; + } + + // It seems like the tools our artists are using often generate + // verts and texcoords slightly separated that should be merged + // note that we really should combine the surfaces with common materials + // before doing this operation, because we can miss a slop combination + // if they are in different surfaces + + vRemap = (int *)R_StaticAlloc( mesh->numVertexes * sizeof( vRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < mesh->numVertexes; j++ ) { + vRemap[j] = j; + } + } else { + float vertexEpsilon = r_slopVertex.GetFloat(); + float expand = 2 * 32 * vertexEpsilon; + idVec3 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, mesh->vertexes, mesh->numVertexes ); + mins -= idVec3( expand, expand, expand ); + maxs += idVec3( expand, expand, expand ); + vertexSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < mesh->numVertexes; j++ ) { + vRemap[j] = vertexSubset.FindVector( mesh->vertexes, j, vertexEpsilon ); + } + } + + tvRemap = (int *)R_StaticAlloc( mesh->numTVertexes * sizeof( tvRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < mesh->numTVertexes; j++ ) { + tvRemap[j] = j; + } + } else { + float texCoordEpsilon = r_slopTexCoord.GetFloat(); + float expand = 2 * 32 * texCoordEpsilon; + idVec2 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, mesh->tvertexes, mesh->numTVertexes ); + mins -= idVec2( expand, expand ); + maxs += idVec2( expand, expand ); + texCoordSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < mesh->numTVertexes; j++ ) { + tvRemap[j] = texCoordSubset.FindVector( mesh->tvertexes, j, texCoordEpsilon ); + } + } + + // we need to find out how many unique vertex / texcoord combinations + // there are, because ASE tracks them separately but we need them unified + + // the maximum possible number of combined vertexes is the number of indexes + mvTable = (matchVert_t *)R_ClearedStaticAlloc( mesh->numFaces * 3 * sizeof( mvTable[0] ) ); + + // we will have a hash chain based on the xyz values + mvHash = (matchVert_t **)R_ClearedStaticAlloc( mesh->numVertexes * sizeof( mvHash[0] ) ); + + // allocate triangle surface + tri = R_AllocStaticTriSurf(); + tri->numVerts = 0; + tri->numIndexes = 0; + R_AllocStaticTriSurfIndexes( tri, mesh->numFaces * 3 ); + tri->generateNormals = !normalsParsed; + + // init default normal, color and tex coord index + normal.Zero(); + color = identityColor; + tv = 0; + + // find all the unique combinations + float normalEpsilon = 1.0f - r_slopNormal.GetFloat(); + for ( j = 0; j < mesh->numFaces; j++ ) { + for ( k = 0; k < 3; k++ ) { + v = mesh->faces[j].vertexNum[k]; + + if ( v < 0 || v >= mesh->numVertexes ) { + common->Error( "ConvertASEToModelSurfaces: bad vertex index in ASE file %s", name.c_str() ); + } + + // collapse the position if it was slightly offset + v = vRemap[v]; + + // we may or may not have texcoords to compare + if ( mesh->numTVFaces == mesh->numFaces && mesh->numTVertexes != 0 ) { + tv = mesh->faces[j].tVertexNum[k]; + if ( tv < 0 || tv >= mesh->numTVertexes ) { + common->Error( "ConvertASEToModelSurfaces: bad tex coord index in ASE file %s", name.c_str() ); + } + // collapse the tex coord if it was slightly offset + tv = tvRemap[tv]; + } + + // we may or may not have normals to compare + if ( normalsParsed ) { + normal = mesh->faces[j].vertexNormals[k]; + } + + // we may or may not have colors to compare + if ( mesh->colorsParsed ) { + color = mesh->faces[j].vertexColors[k]; + } + + // find a matching vert + for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) { + if ( mv->tv != tv ) { + continue; + } + if ( *(unsigned *)mv->color != *(unsigned *)color ) { + continue; + } + if ( !normalsParsed ) { + // if we are going to create the normals, just + // matching texcoords is enough + break; + } + if ( mv->normal * normal > normalEpsilon ) { + break; // we already have this one + } + } + if ( !mv ) { + // allocate a new match vert and link to hash chain + mv = &mvTable[ tri->numVerts ]; + mv->v = v; + mv->tv = tv; + mv->normal = normal; + *(unsigned *)mv->color = *(unsigned *)color; + mv->next = NULL; + if ( lastmv ) { + lastmv->next = mv; + } else { + mvHash[v] = mv; + } + tri->numVerts++; + } + + tri->indexes[tri->numIndexes] = mv - mvTable; + tri->numIndexes++; + } + } + + // allocate space for the indexes and copy them + if ( tri->numIndexes > mesh->numFaces * 3 ) { + common->FatalError( "ConvertASEToModelSurfaces: index miscount in ASE file %s", name.c_str() ); + } + if ( tri->numVerts > mesh->numFaces * 3 ) { + common->FatalError( "ConvertASEToModelSurfaces: vertex miscount in ASE file %s", name.c_str() ); + } + + // an ASE allows the texture coordinates to be scaled, translated, and rotated + if ( ase->materials.Num() == 0 ) { + uOffset = vOffset = 0.0f; + uTiling = vTiling = 1.0f; + textureSin = 0.0f; + textureCos = 1.0f; + } else { + material = ase->materials[object->materialRef]; + uOffset = -material->uOffset; + vOffset = material->vOffset; + uTiling = material->uTiling; + vTiling = material->vTiling; + textureSin = idMath::Sin( material->angle ); + textureCos = idMath::Cos( material->angle ); + } + + // now allocate and generate the combined vertexes + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( j = 0; j < tri->numVerts; j++ ) { + mv = &mvTable[j]; + tri->verts[ j ].Clear(); + tri->verts[ j ].xyz = mesh->vertexes[ mv->v ]; + tri->verts[ j ].normal = mv->normal; + *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color; + if ( mesh->numTVFaces == mesh->numFaces && mesh->numTVertexes != 0 ) { + const idVec2 &tv = mesh->tvertexes[ mv->tv ]; + float u = tv.x * uTiling + uOffset; + float v = tv.y * vTiling + vOffset; + tri->verts[ j ].st[0] = u * textureCos + v * textureSin; + tri->verts[ j ].st[1] = u * -textureSin + v * textureCos; + } + } + + R_StaticFree( mvTable ); + R_StaticFree( mvHash ); + R_StaticFree( tvRemap ); + R_StaticFree( vRemap ); + + // see if we need to merge with a previous surface of the same material + modelSurf = &this->surfaces[mergeTo[ objectNum ]]; + srfTriangles_t *mergeTri = modelSurf->geometry; + if ( !mergeTri ) { + modelSurf->geometry = tri; + } else { + modelSurf->geometry = R_MergeTriangles( mergeTri, tri ); + R_FreeStaticTriSurf( tri ); + R_FreeStaticTriSurf( mergeTri ); + } + } + + return true; +} + +/* +================= +idRenderModelStatic::ConvertLWOToModelSurfaces +================= +*/ +bool idRenderModelStatic::ConvertLWOToModelSurfaces( const struct st_lwObject *lwo ) { + const idMaterial *im1, *im2; + srfTriangles_t *tri; + lwSurface * lwoSurf; + int numTVertexes; + int i, j, k; + int v, tv; + idVec3 * vList; + int * vRemap; + idVec2 * tvList; + int * tvRemap; + matchVert_t * mvTable; // all of the match verts + matchVert_t ** mvHash; // points inside mvTable for each xyz index + matchVert_t * lastmv; + matchVert_t * mv; + idVec3 normal; + int * mergeTo; + byte color[4]; + modelSurface_t surf, *modelSurf; + + if ( !lwo ) { + return false; + } + if ( lwo->surf == NULL ) { + return false; + } + + timeStamp = lwo->timeStamp; + + // count the number of surfaces + i = 0; + for ( lwoSurf = lwo->surf; lwoSurf; lwoSurf = lwoSurf->next ) { + i++; + } + + // the modeling programs can save out multiple surfaces with a common + // material, but we would like to merge them together where possible + mergeTo = (int *)_alloca( i * sizeof( mergeTo[0] ) ); + memset( &surf, 0, sizeof( surf ) ); + + if ( !r_mergeModelSurfaces.GetBool() ) { + // don't merge any + for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) { + mergeTo[i] = i; + surf.shader = declManager->FindMaterial( lwoSurf->name ); + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } else { + // search for material matches + for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) { + im1 = declManager->FindMaterial( lwoSurf->name ); + if ( im1->IsDiscrete() ) { + // flares, autosprites, etc + j = this->NumSurfaces(); + } else { + for ( j = 0 ; j < this->NumSurfaces() ; j++ ) { + modelSurf = &this->surfaces[j]; + im2 = modelSurf->shader; + if ( im1 == im2 ) { + // merge this + mergeTo[i] = j; + break; + } + } + } + if ( j == this->NumSurfaces() ) { + // didn't merge + mergeTo[i] = j; + surf.shader = im1; + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } + } + + idVectorSubset vertexSubset; + idVectorSubset texCoordSubset; + + // we only ever use the first layer + lwLayer *layer = lwo->layer; + + // vertex positions + if ( layer->point.count <= 0 ) { + common->Warning( "ConvertLWOToModelSurfaces: model \'%s\' has bad or missing vertex data", name.c_str() ); + return false; + } + + vList = (idVec3 *)R_StaticAlloc( layer->point.count * sizeof( vList[0] ) ); + for ( j = 0; j < layer->point.count; j++ ) { + vList[j].x = layer->point.pt[j].pos[0]; + vList[j].y = layer->point.pt[j].pos[2]; + vList[j].z = layer->point.pt[j].pos[1]; + } + + // vertex texture coords + numTVertexes = 0; + + if ( layer->nvmaps ) { + for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) { + if ( vm->type == LWID_('T','X','U','V') ) { + numTVertexes += vm->nverts; + } + } + } + + if ( numTVertexes ) { + tvList = (idVec2 *)Mem_Alloc( numTVertexes * sizeof( tvList[0] ) ); + int offset = 0; + for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) { + if ( vm->type == LWID_('T','X','U','V') ) { + vm->offset = offset; + for ( k = 0; k < vm->nverts; k++ ) { + tvList[k + offset].x = vm->val[k][0]; + tvList[k + offset].y = 1.0f - vm->val[k][1]; // invert the t + } + offset += vm->nverts; + } + } + } else { + common->Warning( "ConvertLWOToModelSurfaces: model \'%s\' has bad or missing uv data", name.c_str() ); + numTVertexes = 1; + tvList = (idVec2 *)Mem_ClearedAlloc( numTVertexes * sizeof( tvList[0] ) ); + } + + // It seems like the tools our artists are using often generate + // verts and texcoords slightly separated that should be merged + // note that we really should combine the surfaces with common materials + // before doing this operation, because we can miss a slop combination + // if they are in different surfaces + + vRemap = (int *)R_StaticAlloc( layer->point.count * sizeof( vRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < layer->point.count; j++ ) { + vRemap[j] = j; + } + } else { + float vertexEpsilon = r_slopVertex.GetFloat(); + float expand = 2 * 32 * vertexEpsilon; + idVec3 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, vList, layer->point.count ); + mins -= idVec3( expand, expand, expand ); + maxs += idVec3( expand, expand, expand ); + vertexSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < layer->point.count; j++ ) { + vRemap[j] = vertexSubset.FindVector( vList, j, vertexEpsilon ); + } + } + + tvRemap = (int *)R_StaticAlloc( numTVertexes * sizeof( tvRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < numTVertexes; j++ ) { + tvRemap[j] = j; + } + } else { + float texCoordEpsilon = r_slopTexCoord.GetFloat(); + float expand = 2 * 32 * texCoordEpsilon; + idVec2 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, tvList, numTVertexes ); + mins -= idVec2( expand, expand ); + maxs += idVec2( expand, expand ); + texCoordSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < numTVertexes; j++ ) { + tvRemap[j] = texCoordSubset.FindVector( tvList, j, texCoordEpsilon ); + } + } + + // build the surfaces + for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) { + im1 = declManager->FindMaterial( lwoSurf->name ); + + bool normalsParsed = true; + + // completely ignore any explict normals on surfaces with a renderbump command + // which will guarantee the best contours and least vertexes. + const char *rb = im1->GetRenderBump(); + if ( rb && rb[0] ) { + normalsParsed = false; + } + + // we need to find out how many unique vertex / texcoord combinations there are + + // the maximum possible number of combined vertexes is the number of indexes + mvTable = (matchVert_t *)R_ClearedStaticAlloc( layer->polygon.count * 3 * sizeof( mvTable[0] ) ); + + // we will have a hash chain based on the xyz values + mvHash = (matchVert_t **)R_ClearedStaticAlloc( layer->point.count * sizeof( mvHash[0] ) ); + + // allocate triangle surface + tri = R_AllocStaticTriSurf(); + tri->numVerts = 0; + tri->numIndexes = 0; + R_AllocStaticTriSurfIndexes( tri, layer->polygon.count * 3 ); + tri->generateNormals = !normalsParsed; + + // find all the unique combinations + float normalEpsilon; + if ( fastLoad ) { + normalEpsilon = 1.0f; // don't merge unless completely exact + } else { + normalEpsilon = 1.0f - r_slopNormal.GetFloat(); + } + for ( j = 0; j < layer->polygon.count; j++ ) { + lwPolygon *poly = &layer->polygon.pol[j]; + + if ( poly->surf != lwoSurf ) { + continue; + } + + if ( poly->nverts != 3 ) { + common->Warning( "ConvertLWOToModelSurfaces: model %s has too many verts for a poly! Make sure you triplet it down", name.c_str() ); + continue; + } + + for ( k = 0; k < 3; k++ ) { + + v = vRemap[poly->v[k].index]; + + normal.x = poly->v[k].norm[0]; + normal.y = poly->v[k].norm[2]; + normal.z = poly->v[k].norm[1]; + + // LWO models aren't all that pretty when it comes down to the floating point values they store + normal.FixDegenerateNormal(); + + tv = 0; + + color[0] = lwoSurf->color.rgb[0] * 255; + color[1] = lwoSurf->color.rgb[1] * 255; + color[2] = lwoSurf->color.rgb[2] * 255; + color[3] = 255; + + // first set attributes from the vertex + lwPoint *pt = &layer->point.pt[poly->v[k].index]; + int nvm; + for ( nvm = 0; nvm < pt->nvmaps; nvm++ ) { + lwVMapPt *vm = &pt->vm[nvm]; + + if ( vm->vmap->type == LWID_('T','X','U','V') ) { + tv = tvRemap[vm->index + vm->vmap->offset]; + } + if ( vm->vmap->type == LWID_('R','G','B','A') ) { + for ( int chan = 0; chan < 4; chan++ ) { + color[chan] = 255 * vm->vmap->val[vm->index][chan]; + } + } + } + + // then override with polygon attributes + for ( nvm = 0; nvm < poly->v[k].nvmaps; nvm++ ) { + lwVMapPt *vm = &poly->v[k].vm[nvm]; + + if ( vm->vmap->type == LWID_('T','X','U','V') ) { + tv = tvRemap[vm->index + vm->vmap->offset]; + } + if ( vm->vmap->type == LWID_('R','G','B','A') ) { + for ( int chan = 0; chan < 4; chan++ ) { + color[chan] = 255 * vm->vmap->val[vm->index][chan]; + } + } + } + + // find a matching vert + for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) { + if ( mv->tv != tv ) { + continue; + } + if ( *(unsigned *)mv->color != *(unsigned *)color ) { + continue; + } + if ( !normalsParsed ) { + // if we are going to create the normals, just + // matching texcoords is enough + break; + } + if ( mv->normal * normal > normalEpsilon ) { + break; // we already have this one + } + } + if ( !mv ) { + // allocate a new match vert and link to hash chain + mv = &mvTable[ tri->numVerts ]; + mv->v = v; + mv->tv = tv; + mv->normal = normal; + *(unsigned *)mv->color = *(unsigned *)color; + mv->next = NULL; + if ( lastmv ) { + lastmv->next = mv; + } else { + mvHash[v] = mv; + } + tri->numVerts++; + } + + tri->indexes[tri->numIndexes] = mv - mvTable; + tri->numIndexes++; + } + } + + // allocate space for the indexes and copy them + if ( tri->numIndexes > layer->polygon.count * 3 ) { + common->FatalError( "ConvertLWOToModelSurfaces: index miscount in LWO file %s", name.c_str() ); + } + if ( tri->numVerts > layer->polygon.count * 3 ) { + common->FatalError( "ConvertLWOToModelSurfaces: vertex miscount in LWO file %s", name.c_str() ); + } + + // now allocate and generate the combined vertexes + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( j = 0; j < tri->numVerts; j++ ) { + mv = &mvTable[j]; + tri->verts[ j ].Clear(); + tri->verts[ j ].xyz = vList[ mv->v ]; + tri->verts[ j ].st = tvList[ mv->tv ]; + tri->verts[ j ].normal = mv->normal; + *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color; + } + + R_StaticFree( mvTable ); + R_StaticFree( mvHash ); + + // see if we need to merge with a previous surface of the same material + modelSurf = &this->surfaces[mergeTo[ i ]]; + srfTriangles_t *mergeTri = modelSurf->geometry; + if ( !mergeTri ) { + modelSurf->geometry = tri; + } else { + modelSurf->geometry = R_MergeTriangles( mergeTri, tri ); + R_FreeStaticTriSurf( tri ); + R_FreeStaticTriSurf( mergeTri ); + } + } + + R_StaticFree( tvRemap ); + R_StaticFree( vRemap ); + R_StaticFree( tvList ); + R_StaticFree( vList ); + + return true; +} + +/* +================= +idRenderModelStatic::ConvertLWOToASE +================= +*/ +struct aseModel_s *idRenderModelStatic::ConvertLWOToASE( const struct st_lwObject *obj, const char *fileName ) { + int j, k; + aseModel_t *ase; + + if ( !obj ) { + return NULL; + } + + // NOTE: using new operator because aseModel_t contains idList class objects + ase = new aseModel_t; + ase->timeStamp = obj->timeStamp; + ase->objects.Resize( obj->nlayers, obj->nlayers ); + + int materialRef = 0; + + for ( lwSurface *surf = obj->surf; surf; surf = surf->next ) { + + aseMaterial_t *mat = (aseMaterial_t *)Mem_ClearedAlloc( sizeof( *mat ) ); + strcpy( mat->name, surf->name ); + mat->uTiling = mat->vTiling = 1; + mat->angle = mat->uOffset = mat->vOffset = 0; + ase->materials.Append( mat ); + + lwLayer *layer = obj->layer; + + aseObject_t *object = (aseObject_t *)Mem_ClearedAlloc( sizeof( *object ) ); + object->materialRef = materialRef++; + + aseMesh_t *mesh = &object->mesh; + ase->objects.Append( object ); + + mesh->numFaces = layer->polygon.count; + mesh->numTVFaces = mesh->numFaces; + mesh->faces = (aseFace_t *)Mem_Alloc( mesh->numFaces * sizeof( mesh->faces[0] ) ); + + mesh->numVertexes = layer->point.count; + mesh->vertexes = (idVec3 *)Mem_Alloc( mesh->numVertexes * sizeof( mesh->vertexes[0] ) ); + + // vertex positions + if ( layer->point.count <= 0 ) { + common->Warning( "ConvertLWOToASE: model \'%s\' has bad or missing vertex data", name.c_str() ); + } + + for ( j = 0; j < layer->point.count; j++ ) { + mesh->vertexes[j].x = layer->point.pt[j].pos[0]; + mesh->vertexes[j].y = layer->point.pt[j].pos[2]; + mesh->vertexes[j].z = layer->point.pt[j].pos[1]; + } + + // vertex texture coords + mesh->numTVertexes = 0; + + if ( layer->nvmaps ) { + for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) { + if ( vm->type == LWID_('T','X','U','V') ) { + mesh->numTVertexes += vm->nverts; + } + } + } + + if ( mesh->numTVertexes ) { + mesh->tvertexes = (idVec2 *)Mem_Alloc( mesh->numTVertexes * sizeof( mesh->tvertexes[0] ) ); + int offset = 0; + for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) { + if ( vm->type == LWID_('T','X','U','V') ) { + vm->offset = offset; + for ( k = 0; k < vm->nverts; k++ ) { + mesh->tvertexes[k + offset].x = vm->val[k][0]; + mesh->tvertexes[k + offset].y = 1.0f - vm->val[k][1]; // invert the t + } + offset += vm->nverts; + } + } + } else { + common->Warning( "ConvertLWOToASE: model \'%s\' has bad or missing uv data", fileName ); + mesh->numTVertexes = 1; + mesh->tvertexes = (idVec2 *)Mem_ClearedAlloc( mesh->numTVertexes * sizeof( mesh->tvertexes[0] ) ); + } + + mesh->normalsParsed = true; + mesh->colorsParsed = true; // because we are falling back to the surface color + + // triangles + int faceIndex = 0; + for ( j = 0; j < layer->polygon.count; j++ ) { + lwPolygon *poly = &layer->polygon.pol[j]; + + if ( poly->surf != surf ) { + continue; + } + + if ( poly->nverts != 3 ) { + common->Warning( "ConvertLWOToASE: model %s has too many verts for a poly! Make sure you triplet it down", fileName ); + continue; + } + + mesh->faces[faceIndex].faceNormal.x = poly->norm[0]; + mesh->faces[faceIndex].faceNormal.y = poly->norm[2]; + mesh->faces[faceIndex].faceNormal.z = poly->norm[1]; + + for ( k = 0; k < 3; k++ ) { + + mesh->faces[faceIndex].vertexNum[k] = poly->v[k].index; + + mesh->faces[faceIndex].vertexNormals[k].x = poly->v[k].norm[0]; + mesh->faces[faceIndex].vertexNormals[k].y = poly->v[k].norm[2]; + mesh->faces[faceIndex].vertexNormals[k].z = poly->v[k].norm[1]; + + // complete fallbacks + mesh->faces[faceIndex].tVertexNum[k] = 0; + + mesh->faces[faceIndex].vertexColors[k][0] = surf->color.rgb[0] * 255; + mesh->faces[faceIndex].vertexColors[k][1] = surf->color.rgb[1] * 255; + mesh->faces[faceIndex].vertexColors[k][2] = surf->color.rgb[2] * 255; + mesh->faces[faceIndex].vertexColors[k][3] = 255; + + // first set attributes from the vertex + lwPoint *pt = &layer->point.pt[poly->v[k].index]; + int nvm; + for ( nvm = 0; nvm < pt->nvmaps; nvm++ ) { + lwVMapPt *vm = &pt->vm[nvm]; + + if ( vm->vmap->type == LWID_('T','X','U','V') ) { + mesh->faces[faceIndex].tVertexNum[k] = vm->index + vm->vmap->offset; + } + if ( vm->vmap->type == LWID_('R','G','B','A') ) { + for ( int chan = 0; chan < 4; chan++ ) { + mesh->faces[faceIndex].vertexColors[k][chan] = 255 * vm->vmap->val[vm->index][chan]; + } + } + } + + // then override with polygon attributes + for ( nvm = 0; nvm < poly->v[k].nvmaps; nvm++ ) { + lwVMapPt *vm = &poly->v[k].vm[nvm]; + + if ( vm->vmap->type == LWID_('T','X','U','V') ) { + mesh->faces[faceIndex].tVertexNum[k] = vm->index + vm->vmap->offset; + } + if ( vm->vmap->type == LWID_('R','G','B','A') ) { + for ( int chan = 0; chan < 4; chan++ ) { + mesh->faces[faceIndex].vertexColors[k][chan] = 255 * vm->vmap->val[vm->index][chan]; + } + } + } + } + + faceIndex++; + } + + mesh->numFaces = faceIndex; + mesh->numTVFaces = faceIndex; + + aseFace_t *newFaces = ( aseFace_t* )Mem_Alloc( mesh->numFaces * sizeof ( mesh->faces[0] ) ); + memcpy( newFaces, mesh->faces, sizeof( mesh->faces[0] ) * mesh->numFaces ); + Mem_Free( mesh->faces ); + mesh->faces = newFaces; + } + + return ase; +} + +/* +================= +idRenderModelStatic::ConvertMAToModelSurfaces +================= +*/ +bool idRenderModelStatic::ConvertMAToModelSurfaces (const struct maModel_s *ma ) { + + maObject_t * object; + maMesh_t * mesh; + maMaterial_t * material; + + const idMaterial *im1, *im2; + srfTriangles_t *tri; + int objectNum; + int i, j, k; + int v, tv; + int * vRemap; + int * tvRemap; + matchVert_t * mvTable; // all of the match verts + matchVert_t ** mvHash; // points inside mvTable for each xyz index + matchVert_t * lastmv; + matchVert_t * mv; + idVec3 normal; + float uOffset, vOffset, textureSin, textureCos; + float uTiling, vTiling; + int * mergeTo; + byte * color; + static byte identityColor[4] = { 255, 255, 255, 255 }; + modelSurface_t surf, *modelSurf; + + if ( !ma ) { + return false; + } + if ( ma->objects.Num() < 1 ) { + return false; + } + + timeStamp = ma->timeStamp; + + // the modeling programs can save out multiple surfaces with a common + // material, but we would like to mege them together where possible + // meaning that this->NumSurfaces() <= ma->objects.currentElements + mergeTo = (int *)_alloca( ma->objects.Num() * sizeof( *mergeTo ) ); + + surf.geometry = NULL; + if ( ma->materials.Num() == 0 ) { + // if we don't have any materials, dump everything into a single surface + surf.shader = tr.defaultMaterial; + surf.id = 0; + this->AddSurface( surf ); + for ( i = 0 ; i < ma->objects.Num() ; i++ ) { + mergeTo[i] = 0; + } + } else if ( !r_mergeModelSurfaces.GetBool() ) { + // don't merge any + for ( i = 0 ; i < ma->objects.Num() ; i++ ) { + mergeTo[i] = i; + object = ma->objects[i]; + if(object->materialRef >= 0) { + material = ma->materials[object->materialRef]; + surf.shader = declManager->FindMaterial( material->name ); + } else { + surf.shader = tr.defaultMaterial; + } + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } else { + // search for material matches + for ( i = 0 ; i < ma->objects.Num() ; i++ ) { + object = ma->objects[i]; + if(object->materialRef >= 0) { + material = ma->materials[object->materialRef]; + im1 = declManager->FindMaterial( material->name ); + } else { + im1 = tr.defaultMaterial; + } + if ( im1->IsDiscrete() ) { + // flares, autosprites, etc + j = this->NumSurfaces(); + } else { + for ( j = 0 ; j < this->NumSurfaces() ; j++ ) { + modelSurf = &this->surfaces[j]; + im2 = modelSurf->shader; + if ( im1 == im2 ) { + // merge this + mergeTo[i] = j; + break; + } + } + } + if ( j == this->NumSurfaces() ) { + // didn't merge + mergeTo[i] = j; + surf.shader = im1; + surf.id = this->NumSurfaces(); + this->AddSurface( surf ); + } + } + } + + idVectorSubset vertexSubset; + idVectorSubset texCoordSubset; + + // build the surfaces + for ( objectNum = 0 ; objectNum < ma->objects.Num() ; objectNum++ ) { + object = ma->objects[objectNum]; + mesh = &object->mesh; + if(object->materialRef >= 0) { + material = ma->materials[object->materialRef]; + im1 = declManager->FindMaterial( material->name ); + } else { + im1 = tr.defaultMaterial; + } + + bool normalsParsed = mesh->normalsParsed; + + // completely ignore any explict normals on surfaces with a renderbump command + // which will guarantee the best contours and least vertexes. + const char *rb = im1->GetRenderBump(); + if ( rb && rb[0] ) { + normalsParsed = false; + } + + // It seems like the tools our artists are using often generate + // verts and texcoords slightly separated that should be merged + // note that we really should combine the surfaces with common materials + // before doing this operation, because we can miss a slop combination + // if they are in different surfaces + + vRemap = (int *)R_StaticAlloc( mesh->numVertexes * sizeof( vRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < mesh->numVertexes; j++ ) { + vRemap[j] = j; + } + } else { + float vertexEpsilon = r_slopVertex.GetFloat(); + float expand = 2 * 32 * vertexEpsilon; + idVec3 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, mesh->vertexes, mesh->numVertexes ); + mins -= idVec3( expand, expand, expand ); + maxs += idVec3( expand, expand, expand ); + vertexSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < mesh->numVertexes; j++ ) { + vRemap[j] = vertexSubset.FindVector( mesh->vertexes, j, vertexEpsilon ); + } + } + + tvRemap = (int *)R_StaticAlloc( mesh->numTVertexes * sizeof( tvRemap[0] ) ); + + if ( fastLoad ) { + // renderbump doesn't care about vertex count + for ( j = 0; j < mesh->numTVertexes; j++ ) { + tvRemap[j] = j; + } + } else { + float texCoordEpsilon = r_slopTexCoord.GetFloat(); + float expand = 2 * 32 * texCoordEpsilon; + idVec2 mins, maxs; + + SIMDProcessor->MinMax( mins, maxs, mesh->tvertexes, mesh->numTVertexes ); + mins -= idVec2( expand, expand ); + maxs += idVec2( expand, expand ); + texCoordSubset.Init( mins, maxs, 32, 1024 ); + for ( j = 0; j < mesh->numTVertexes; j++ ) { + tvRemap[j] = texCoordSubset.FindVector( mesh->tvertexes, j, texCoordEpsilon ); + } + } + + // we need to find out how many unique vertex / texcoord / color combinations + // there are, because MA tracks them separately but we need them unified + + // the maximum possible number of combined vertexes is the number of indexes + mvTable = (matchVert_t *)R_ClearedStaticAlloc( mesh->numFaces * 3 * sizeof( mvTable[0] ) ); + + // we will have a hash chain based on the xyz values + mvHash = (matchVert_t **)R_ClearedStaticAlloc( mesh->numVertexes * sizeof( mvHash[0] ) ); + + // allocate triangle surface + tri = R_AllocStaticTriSurf(); + tri->numVerts = 0; + tri->numIndexes = 0; + R_AllocStaticTriSurfIndexes( tri, mesh->numFaces * 3 ); + tri->generateNormals = !normalsParsed; + + // init default normal, color and tex coord index + normal.Zero(); + color = identityColor; + tv = 0; + + // find all the unique combinations + float normalEpsilon = 1.0f - r_slopNormal.GetFloat(); + for ( j = 0; j < mesh->numFaces; j++ ) { + for ( k = 0; k < 3; k++ ) { + v = mesh->faces[j].vertexNum[k]; + + if ( v < 0 || v >= mesh->numVertexes ) { + common->Error( "ConvertMAToModelSurfaces: bad vertex index in MA file %s", name.c_str() ); + } + + // collapse the position if it was slightly offset + v = vRemap[v]; + + // we may or may not have texcoords to compare + if ( mesh->numTVertexes != 0 ) { + tv = mesh->faces[j].tVertexNum[k]; + if ( tv < 0 || tv >= mesh->numTVertexes ) { + common->Error( "ConvertMAToModelSurfaces: bad tex coord index in MA file %s", name.c_str() ); + } + // collapse the tex coord if it was slightly offset + tv = tvRemap[tv]; + } + + // we may or may not have normals to compare + if ( normalsParsed ) { + normal = mesh->faces[j].vertexNormals[k]; + } + + //BSM: Todo: Fix the vertex colors + // we may or may not have colors to compare + if ( mesh->faces[j].vertexColors[k] != -1 && mesh->faces[j].vertexColors[k] != -999 ) { + + color = &mesh->colors[mesh->faces[j].vertexColors[k]*4]; + } + + // find a matching vert + for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) { + if ( mv->tv != tv ) { + continue; + } + if ( *(unsigned *)mv->color != *(unsigned *)color ) { + continue; + } + if ( !normalsParsed ) { + // if we are going to create the normals, just + // matching texcoords is enough + break; + } + if ( mv->normal * normal > normalEpsilon ) { + break; // we already have this one + } + } + if ( !mv ) { + // allocate a new match vert and link to hash chain + mv = &mvTable[ tri->numVerts ]; + mv->v = v; + mv->tv = tv; + mv->normal = normal; + *(unsigned *)mv->color = *(unsigned *)color; + mv->next = NULL; + if ( lastmv ) { + lastmv->next = mv; + } else { + mvHash[v] = mv; + } + tri->numVerts++; + } + + tri->indexes[tri->numIndexes] = mv - mvTable; + tri->numIndexes++; + } + } + + // allocate space for the indexes and copy them + if ( tri->numIndexes > mesh->numFaces * 3 ) { + common->FatalError( "ConvertMAToModelSurfaces: index miscount in MA file %s", name.c_str() ); + } + if ( tri->numVerts > mesh->numFaces * 3 ) { + common->FatalError( "ConvertMAToModelSurfaces: vertex miscount in MA file %s", name.c_str() ); + } + + // an MA allows the texture coordinates to be scaled, translated, and rotated + //BSM: Todo: Does Maya support this and if so how + //if ( ase->materials.Num() == 0 ) { + uOffset = vOffset = 0.0f; + uTiling = vTiling = 1.0f; + textureSin = 0.0f; + textureCos = 1.0f; + //} else { + // material = ase->materials[object->materialRef]; + // uOffset = -material->uOffset; + // vOffset = material->vOffset; + // uTiling = material->uTiling; + // vTiling = material->vTiling; + // textureSin = idMath::Sin( material->angle ); + // textureCos = idMath::Cos( material->angle ); + //} + + // now allocate and generate the combined vertexes + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( j = 0; j < tri->numVerts; j++ ) { + mv = &mvTable[j]; + tri->verts[ j ].Clear(); + tri->verts[ j ].xyz = mesh->vertexes[ mv->v ]; + tri->verts[ j ].normal = mv->normal; + *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color; + if ( mesh->numTVertexes != 0 ) { + const idVec2 &tv = mesh->tvertexes[ mv->tv ]; + float u = tv.x * uTiling + uOffset; + float v = tv.y * vTiling + vOffset; + tri->verts[ j ].st[0] = u * textureCos + v * textureSin; + tri->verts[ j ].st[1] = u * -textureSin + v * textureCos; + } + } + + R_StaticFree( mvTable ); + R_StaticFree( mvHash ); + R_StaticFree( tvRemap ); + R_StaticFree( vRemap ); + + // see if we need to merge with a previous surface of the same material + modelSurf = &this->surfaces[mergeTo[ objectNum ]]; + srfTriangles_t *mergeTri = modelSurf->geometry; + if ( !mergeTri ) { + modelSurf->geometry = tri; + } else { + modelSurf->geometry = R_MergeTriangles( mergeTri, tri ); + R_FreeStaticTriSurf( tri ); + R_FreeStaticTriSurf( mergeTri ); + } + } + + return true; +} + +/* +================= +idRenderModelStatic::LoadASE +================= +*/ +bool idRenderModelStatic::LoadASE( const char *fileName ) { + aseModel_t *ase; + + ase = ASE_Load( fileName ); + if ( ase == NULL ) { + return false; + } + + ConvertASEToModelSurfaces( ase ); + + ASE_Free( ase ); + + return true; +} + +/* +================= +idRenderModelStatic::LoadLWO +================= +*/ +bool idRenderModelStatic::LoadLWO( const char *fileName ) { + unsigned int failID; + int failPos; + lwObject *lwo; + + lwo = lwGetObject( fileName, &failID, &failPos ); + if ( lwo == NULL ) { + return false; + } + + ConvertLWOToModelSurfaces( lwo ); + + lwFreeObject( lwo ); + + return true; +} + +/* +================= +idRenderModelStatic::LoadMA +================= +*/ +bool idRenderModelStatic::LoadMA( const char *fileName ) { + maModel_t *ma; + + ma = MA_Load( fileName ); + if ( ma == NULL ) { + return false; + } + + ConvertMAToModelSurfaces( ma ); + + MA_Free( ma ); + + return true; +} + +/* +================= +idRenderModelStatic::LoadFLT + +USGS height map data for megaTexture experiments +================= +*/ +bool idRenderModelStatic::LoadFLT( const char *fileName ) { + float *data; + int len; + + len = fileSystem->ReadFile( fileName, (void **)&data ); + if ( len <= 0 ) { + return false; + } + int size = sqrt( len / 4.0f ); + + // bound the altitudes + float min = 9999999; + float max = -9999999; + for ( int i = 0 ; i < len/4 ; i++ ) { + data[i] = BigFloat( data[i] ); + if ( data[i] == -9999 ) { + data[i] = 0; // unscanned areas + } + + if ( data[i] < min ) { + min = data[i]; + } + if ( data[i] > max ) { + max = data[i]; + } + } +#if 1 + // write out a gray scale height map + byte *image = (byte *)R_StaticAlloc( len ); + byte *image_p = image; + for ( int i = 0 ; i < len/4 ; i++ ) { + float v = ( data[i] - min ) / ( max - min ); + image_p[0] = + image_p[1] = + image_p[2] = v * 255; + image_p[3] = 255; + image_p += 4; + } + idStr tgaName = fileName; + tgaName.StripFileExtension(); + tgaName += ".tga"; + R_WriteTGA( tgaName.c_str(), image, size, size, false ); + R_StaticFree( image ); +//return false; +#endif + + // find the island above sea level + int minX, maxX, minY, maxY; + { + int i; + for ( minX = 0 ; minX < size ; minX++ ) { + for ( i = 0 ; i < size ; i++ ) { + if ( data[i*size + minX] > 1.0 ) { + break; + } + } + if ( i != size ) { + break; + } + } + + for ( maxX = size-1 ; maxX > 0 ; maxX-- ) { + for ( i = 0 ; i < size ; i++ ) { + if ( data[i*size + maxX] > 1.0 ) { + break; + } + } + if ( i != size ) { + break; + } + } + + for ( minY = 0 ; minY < size ; minY++ ) { + for ( i = 0 ; i < size ; i++ ) { + if ( data[minY*size + i] > 1.0 ) { + break; + } + } + if ( i != size ) { + break; + } + } + + for ( maxY = size-1 ; maxY < size ; maxY-- ) { + for ( i = 0 ; i < size ; i++ ) { + if ( data[maxY*size + i] > 1.0 ) { + break; + } + } + if ( i != size ) { + break; + } + } + } + + int width = maxX - minX + 1; + int height = maxY - minY + 1; + +//width /= 2; + // allocate triangle surface + srfTriangles_t *tri = R_AllocStaticTriSurf(); + tri->numVerts = width * height; + tri->numIndexes = (width-1) * (height-1) * 6; + + fastLoad = true; // don't do all the sil processing + + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + + for ( int i = 0 ; i < height ; i++ ) { + for ( int j = 0; j < width ; j++ ) { + int v = i * width + j; + tri->verts[ v ].Clear(); + tri->verts[ v ].xyz[0] = j * 10; // each sample is 10 meters + tri->verts[ v ].xyz[1] = -i * 10; + tri->verts[ v ].xyz[2] = data[(minY+i)*size+minX+j]; // height is in meters + tri->verts[ v ].st[0] = (float) j / (width-1); + tri->verts[ v ].st[1] = 1.0 - ( (float) i / (height-1) ); + } + } + + for ( int i = 0 ; i < height-1 ; i++ ) { + for ( int j = 0; j < width-1 ; j++ ) { + int v = ( i * (width-1) + j ) * 6; +#if 0 + tri->indexes[ v + 0 ] = i * width + j; + tri->indexes[ v + 1 ] = (i+1) * width + j; + tri->indexes[ v + 2 ] = (i+1) * width + j + 1; + tri->indexes[ v + 3 ] = i * width + j; + tri->indexes[ v + 4 ] = (i+1) * width + j + 1; + tri->indexes[ v + 5 ] = i * width + j + 1; +#else + tri->indexes[ v + 0 ] = i * width + j; + tri->indexes[ v + 1 ] = i * width + j + 1; + tri->indexes[ v + 2 ] = (i+1) * width + j + 1; + tri->indexes[ v + 3 ] = i * width + j; + tri->indexes[ v + 4 ] = (i+1) * width + j + 1; + tri->indexes[ v + 5 ] = (i+1) * width + j; +#endif + } + } + + fileSystem->FreeFile( data ); + + modelSurface_t surface; + + surface.geometry = tri; + surface.id = 0; + surface.shader = tr.defaultMaterial; // declManager->FindMaterial( "shaderDemos/megaTexture" ); + + this->AddSurface( surface ); + + return true; +} + + +//============================================================================= + +/* +================ +idRenderModelStatic::PurgeModel +================ +*/ +void idRenderModelStatic::PurgeModel() { + int i; + modelSurface_t *surf; + + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + surf = &surfaces[i]; + + if ( surf->geometry ) { + R_FreeStaticTriSurf( surf->geometry ); + } + } + surfaces.Clear(); + + purged = true; +} + +/* +============== +idRenderModelStatic::FreeVertexCache + +We are about to restart the vertex cache, so dump everything +============== +*/ +void idRenderModelStatic::FreeVertexCache( void ) { + for ( int j = 0 ; j < surfaces.Num() ; j++ ) { + srfTriangles_t *tri = surfaces[j].geometry; + if ( !tri ) { + continue; + } + if ( tri->ambientCache ) { + vertexCache.Free( tri->ambientCache ); + tri->ambientCache = NULL; + } + // static shadows may be present + if ( tri->shadowCache ) { + vertexCache.Free( tri->shadowCache ); + tri->shadowCache = NULL; + } + } +} + +/* +================ +idRenderModelStatic::ReadFromDemoFile +================ +*/ +void idRenderModelStatic::ReadFromDemoFile( class idDemoFile *f ) { + PurgeModel(); + + InitEmpty( f->ReadHashString() ); + + int i, j, numSurfaces; + f->ReadInt( numSurfaces ); + + for ( i = 0 ; i < numSurfaces ; i++ ) { + modelSurface_t surf; + + surf.shader = declManager->FindMaterial( f->ReadHashString() ); + + srfTriangles_t *tri = R_AllocStaticTriSurf(); + + f->ReadInt( tri->numIndexes ); + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + for ( j = 0; j < tri->numIndexes; ++j ) + f->ReadInt( (int&)tri->indexes[j] ); + + f->ReadInt( tri->numVerts ); + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( j = 0; j < tri->numVerts; ++j ) { + f->ReadVec3( tri->verts[j].xyz ); + f->ReadVec2( tri->verts[j].st ); + f->ReadVec3( tri->verts[j].normal ); + f->ReadVec3( tri->verts[j].tangents[0] ); + f->ReadVec3( tri->verts[j].tangents[1] ); + f->ReadUnsignedChar( tri->verts[j].color[0] ); + f->ReadUnsignedChar( tri->verts[j].color[1] ); + f->ReadUnsignedChar( tri->verts[j].color[2] ); + f->ReadUnsignedChar( tri->verts[j].color[3] ); + } + + surf.geometry = tri; + + this->AddSurface( surf ); + } + this->FinishSurfaces(); +} + +/* +================ +idRenderModelStatic::WriteToDemoFile +================ +*/ +void idRenderModelStatic::WriteToDemoFile( class idDemoFile *f ) { + int data[1]; + + // note that it has been updated + lastArchivedFrame = tr.frameCount; + + data[0] = DC_DEFINE_MODEL; + f->WriteInt( data[0] ); + f->WriteHashString( this->Name() ); + + int i, j, iData = surfaces.Num(); + f->WriteInt( iData ); + + for ( i = 0 ; i < surfaces.Num() ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + f->WriteHashString( surf->shader->GetName() ); + + srfTriangles_t *tri = surf->geometry; + f->WriteInt( tri->numIndexes ); + for ( j = 0; j < tri->numIndexes; ++j ) + f->WriteInt( (int&)tri->indexes[j] ); + f->WriteInt( tri->numVerts ); + for ( j = 0; j < tri->numVerts; ++j ) { + f->WriteVec3( tri->verts[j].xyz ); + f->WriteVec2( tri->verts[j].st ); + f->WriteVec3( tri->verts[j].normal ); + f->WriteVec3( tri->verts[j].tangents[0] ); + f->WriteVec3( tri->verts[j].tangents[1] ); + f->WriteUnsignedChar( tri->verts[j].color[0] ); + f->WriteUnsignedChar( tri->verts[j].color[1] ); + f->WriteUnsignedChar( tri->verts[j].color[2] ); + f->WriteUnsignedChar( tri->verts[j].color[3] ); + } + } +} + +/* +================ +idRenderModelStatic::IsLoaded +================ +*/ +bool idRenderModelStatic::IsLoaded( void ) { + return !purged; +} + +/* +================ +idRenderModelStatic::SetLevelLoadReferenced +================ +*/ +void idRenderModelStatic::SetLevelLoadReferenced( bool referenced ) { + levelLoadReferenced = referenced; +} + +/* +================ +idRenderModelStatic::IsLevelLoadReferenced +================ +*/ +bool idRenderModelStatic::IsLevelLoadReferenced( void ) { + return levelLoadReferenced; +} + +/* +================= +idRenderModelStatic::TouchData +================= +*/ +void idRenderModelStatic::TouchData( void ) { + for ( int i = 0 ; i < surfaces.Num() ; i++ ) { + const modelSurface_t *surf = &surfaces[i]; + + // re-find the material to make sure it gets added to the + // level keep list + declManager->FindMaterial( surf->shader->GetName() ); + } +} + +/* +================= +idRenderModelStatic::DeleteSurfaceWithId +================= +*/ +bool idRenderModelStatic::DeleteSurfaceWithId( int id ) { + int i; + + for ( i = 0; i < surfaces.Num(); i++ ) { + if ( surfaces[i].id == id ) { + R_FreeStaticTriSurf( surfaces[i].geometry ); + surfaces.RemoveIndex( i ); + return true; + } + } + return false; +} + +/* +================= +idRenderModelStatic::DeleteSurfacesWithNegativeId +================= +*/ +void idRenderModelStatic::DeleteSurfacesWithNegativeId( void ) { + int i; + + for ( i = 0; i < surfaces.Num(); i++ ) { + if ( surfaces[i].id < 0 ) { + R_FreeStaticTriSurf( surfaces[i].geometry ); + surfaces.RemoveIndex( i ); + i--; + } + } +} + +/* +================= +idRenderModelStatic::FindSurfaceWithId +================= +*/ +bool idRenderModelStatic::FindSurfaceWithId( int id, int &surfaceNum ) { + int i; + + for ( i = 0; i < surfaces.Num(); i++ ) { + if ( surfaces[i].id == id ) { + surfaceNum = i; + return true; + } + } + return false; +} diff --git a/renderer/Model.h b/renderer/Model.h new file mode 100644 index 000000000..d07683d74 --- /dev/null +++ b/renderer/Model.h @@ -0,0 +1,305 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODEL_H__ +#define __MODEL_H__ + +/* +=============================================================================== + + Render Model + +=============================================================================== +*/ + +// shared between the renderer, game, and Maya export DLL +#define MD5_VERSION_STRING "MD5Version" +#define MD5_MESH_EXT "md5mesh" +#define MD5_ANIM_EXT "md5anim" +#define MD5_CAMERA_EXT "md5camera" +#define MD5_VERSION 10 + +// using shorts for triangle indexes can save a significant amount of traffic, but +// to support the large models that renderBump loads, they need to be 32 bits +#if 1 + +#define GL_INDEX_TYPE GL_UNSIGNED_INT +typedef int glIndex_t; + +#else + +#define GL_INDEX_TYPE GL_UNSIGNED_SHORT +typedef short glIndex_t; + +#endif + + +typedef struct { + // NOTE: making this a glIndex is dubious, as there can be 2x the faces as verts + glIndex_t p1, p2; // planes defining the edge + glIndex_t v1, v2; // verts defining the edge +} silEdge_t; + +// this is used for calculating unsmoothed normals and tangents for deformed models +typedef struct dominantTri_s { + glIndex_t v2, v3; + float normalizationScale[3]; +} dominantTri_t; + +typedef struct lightingCache_s { + idVec3 localLightVector; // this is the statically computed vector to the light + // in texture space for cards without vertex programs +} lightingCache_t; + +typedef struct shadowCache_s { + idVec4 xyz; // we use homogenous coordinate tricks +} shadowCache_t; + +const int SHADOW_CAP_INFINITE = 64; + +// our only drawing geometry type +typedef struct srfTriangles_s { + idBounds bounds; // for culling + + int ambientViewCount; // if == tr.viewCount, it is visible this view + + bool generateNormals; // create normals from geometry, instead of using explicit ones + bool tangentsCalculated; // set when the vertex tangents have been calculated + bool facePlanesCalculated; // set when the face planes have been calculated + bool perfectHull; // true if there aren't any dangling edges + bool deformedSurface; // if true, indexes, silIndexes, mirrorVerts, and silEdges are + // pointers into the original surface, and should not be freed + + int numVerts; // number of vertices + idDrawVert * verts; // vertices, allocated with special allocator + + int numIndexes; // for shadows, this has both front and rear end caps and silhouette planes + glIndex_t * indexes; // indexes, allocated with special allocator + + glIndex_t * silIndexes; // indexes changed to be the first vertex with same XYZ, ignoring normal and texcoords + + int numMirroredVerts; // this many verts at the end of the vert list are tangent mirrors + int * mirroredVerts; // tri->mirroredVerts[0] is the mirror of tri->numVerts - tri->numMirroredVerts + 0 + + int numDupVerts; // number of duplicate vertexes + int * dupVerts; // pairs of the number of the first vertex and the number of the duplicate vertex + + int numSilEdges; // number of silhouette edges + silEdge_t * silEdges; // silhouette edges + + idPlane * facePlanes; // [numIndexes/3] plane equations + + dominantTri_t * dominantTris; // [numVerts] for deformed surface fast tangent calculation + + int numShadowIndexesNoFrontCaps; // shadow volumes with front caps omitted + int numShadowIndexesNoCaps; // shadow volumes with the front and rear caps omitted + + int shadowCapPlaneBits; // bits 0-5 are set when that plane of the interacting light has triangles + // projected on it, which means that if the view is on the outside of that + // plane, we need to draw the rear caps of the shadow volume + // turboShadows will have SHADOW_CAP_INFINITE + + shadowCache_t * shadowVertexes; // these will be copied to shadowCache when it is going to be drawn. + // these are NULL when vertex programs are available + + struct srfTriangles_s * ambientSurface; // for light interactions, point back at the original surface that generated + // the interaction, which we will get the ambientCache from + + struct srfTriangles_s * nextDeferredFree; // chain of tris to free next frame + + // data in vertex object space, not directly readable by the CPU + struct vertCache_s * indexCache; // int + struct vertCache_s * ambientCache; // idDrawVert + struct vertCache_s * lightingCache; // lightingCache_t + struct vertCache_s * shadowCache; // shadowCache_t +} srfTriangles_t; + +typedef idList idTriList; + +typedef struct modelSurface_s { + int id; + const idMaterial * shader; + srfTriangles_t * geometry; +} modelSurface_t; + +typedef enum { + DM_STATIC, // never creates a dynamic model + DM_CACHED, // once created, stays constant until the entity is updated (animating characters) + DM_CONTINUOUS // must be recreated for every single view (time dependent things like particles) +} dynamicModel_t; + +typedef enum { + INVALID_JOINT = -1 +} jointHandle_t; + +class idMD5Joint { +public: + idMD5Joint() { parent = NULL; } + idStr name; + const idMD5Joint * parent; +}; + + +// the init methods may be called again on an already created model when +// a reloadModels is issued + +class idRenderModel { +public: + virtual ~idRenderModel() {}; + + // Loads static models only, dynamic models must be loaded by the modelManager + virtual void InitFromFile( const char *fileName ) = 0; + + // renderBump uses this to load the very high poly count models, skipping the + // shadow and tangent generation, along with some surface cleanup to make it load faster + virtual void PartialInitFromFile( const char *fileName ) = 0; + + // this is used for dynamically created surfaces, which are assumed to not be reloadable. + // It can be called again to clear out the surfaces of a dynamic model for regeneration. + virtual void InitEmpty( const char *name ) = 0; + + // dynamic model instantiations will be created with this + // the geometry data will be owned by the model, and freed when it is freed + // the geoemtry should be raw triangles, with no extra processing + virtual void AddSurface( modelSurface_t surface ) = 0; + + // cleans all the geometry and performs cross-surface processing + // like shadow hulls + // Creates the duplicated back side geometry for two sided, alpha tested, lit materials + // This does not need to be called if none of the surfaces added with AddSurface require + // light interaction, and all the triangles are already well formed. + virtual void FinishSurfaces() = 0; + + // frees all the data, but leaves the class around for dangling references, + // which can regenerate the data with LoadModel() + virtual void PurgeModel() = 0; + + // resets any model information that needs to be reset on a same level load etc.. + // currently only implemented for liquids + virtual void Reset() = 0; + + // used for initial loads, reloadModel, and reloading the data of purged models + // Upon exit, the model will absolutely be valid, but possibly as a default model + virtual void LoadModel() = 0; + + // internal use + virtual bool IsLoaded() = 0; + virtual void SetLevelLoadReferenced( bool referenced ) = 0; + virtual bool IsLevelLoadReferenced() = 0; + + // models that are already loaded at level start time + // will still touch their data to make sure they + // are kept loaded + virtual void TouchData() = 0; + + // dump any ambient caches on the model surfaces + virtual void FreeVertexCache() = 0; + + // returns the name of the model + virtual const char * Name() const = 0; + + // prints a detailed report on the model for printModel + virtual void Print() const = 0; + + // prints a single line report for listModels + virtual void List() const = 0; + + // reports the amount of memory (roughly) consumed by the model + virtual int Memory() const = 0; + + // for reloadModels + virtual ID_TIME_T Timestamp() const = 0; + + // returns the number of surfaces + virtual int NumSurfaces() const = 0; + + // NumBaseSurfaces will not count any overlays added to dynamic models + virtual int NumBaseSurfaces() const = 0; + + // get a pointer to a surface + virtual const modelSurface_t *Surface( int surfaceNum ) const = 0; + + // Allocates surface triangles. + // Allocates memory for srfTriangles_t::verts and srfTriangles_t::indexes + // The allocated memory is not initialized. + // srfTriangles_t::numVerts and srfTriangles_t::numIndexes are set to zero. + virtual srfTriangles_t * AllocSurfaceTriangles( int numVerts, int numIndexes ) const = 0; + + // Frees surfaces triangles. + virtual void FreeSurfaceTriangles( srfTriangles_t *tris ) const = 0; + + // created at load time by stitching together all surfaces and sharing + // the maximum number of edges. This may be incorrect if a skin file + // remaps surfaces between shadow casting and non-shadow casting, or + // if some surfaces are noSelfShadow and others aren't + virtual srfTriangles_t * ShadowHull() const = 0; + + // models of the form "_area*" may have a prelight shadow model associated with it + virtual bool IsStaticWorldModel() const = 0; + + // models parsed from inside map files or dynamically created cannot be reloaded by + // reloadmodels + virtual bool IsReloadable() const = 0; + + // md3, md5, particles, etc + virtual dynamicModel_t IsDynamicModel() const = 0; + + // if the load failed for any reason, this will return true + virtual bool IsDefaultModel() const = 0; + + // dynamic models should return a fast, conservative approximation + // static models should usually return the exact value + virtual idBounds Bounds( const struct renderEntity_s *ent = NULL ) const = 0; + + // returns value != 0.0f if the model requires the depth hack + virtual float DepthHack() const = 0; + + // returns a static model based on the definition and view + // currently, this will be regenerated for every view, even though + // some models, like character meshes, could be used for multiple (mirror) + // views in a frame, or may stay static for multiple frames (corpses) + // The renderer will delete the returned dynamic model the next view + // This isn't const, because it may need to reload a purged model if it + // wasn't precached correctly. + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) = 0; + + // Returns the number of joints or 0 if the model is not an MD5 + virtual int NumJoints( void ) const = 0; + + // Returns the MD5 joints or NULL if the model is not an MD5 + virtual const idMD5Joint * GetJoints( void ) const = 0; + + // Returns the handle for the joint with the given name. + virtual jointHandle_t GetJointHandle( const char *name ) const = 0; + + // Returns the name for the joint with the given handle. + virtual const char * GetJointName( jointHandle_t handle ) const = 0; + + // Returns the default animation pose or NULL if the model is not an MD5. + virtual const idJointQuat * GetDefaultPose( void ) const = 0; + + // Returns number of the joint nearest to the given triangle. + virtual int NearestJoint( int surfaceNum, int a, int c, int b ) const = 0; + + // Writing to and reading from a demo file. + virtual void ReadFromDemoFile( class idDemoFile *f ) = 0; + virtual void WriteToDemoFile( class idDemoFile *f ) = 0; +}; + +#endif /* !__MODEL_H__ */ diff --git a/renderer/ModelDecal.cpp b/renderer/ModelDecal.cpp new file mode 100644 index 000000000..e6bf3c519 --- /dev/null +++ b/renderer/ModelDecal.cpp @@ -0,0 +1,528 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + +// decalFade filter 5 0.1 +// polygonOffset +// { +// map invertColor( textures/splat ) +// blend GL_ZERO GL_ONE_MINUS_SRC +// vertexColor +// clamp +// } + +/* +================== +idRenderModelDecal::idRenderModelDecal +================== +*/ +idRenderModelDecal::idRenderModelDecal( void ) { + memset( &tri, 0, sizeof( tri ) ); + tri.verts = verts; + tri.indexes = indexes; + material = NULL; + nextDecal = NULL; +} + +/* +================== +idRenderModelDecal::~idRenderModelDecal +================== +*/ +idRenderModelDecal::~idRenderModelDecal( void ) { +} + +/* +================== +idRenderModelDecal::idRenderModelDecal +================== +*/ +idRenderModelDecal *idRenderModelDecal::Alloc( void ) { + return new idRenderModelDecal; +} + +/* +================== +idRenderModelDecal::idRenderModelDecal +================== +*/ +void idRenderModelDecal::Free( idRenderModelDecal *decal ) { + delete decal; +} + +/* +================= +idRenderModelDecal::CreateProjectionInfo +================= +*/ +bool idRenderModelDecal::CreateProjectionInfo( decalProjectionInfo_t &info, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) { + + if ( winding.GetNumPoints() != NUM_DECAL_BOUNDING_PLANES - 2 ) { + common->Printf( "idRenderModelDecal::CreateProjectionInfo: winding must have %d points\n", NUM_DECAL_BOUNDING_PLANES - 2 ); + return false; + } + + assert( material != NULL ); + + info.projectionOrigin = projectionOrigin; + info.material = material; + info.parallel = parallel; + info.fadeDepth = fadeDepth; + info.startTime = startTime; + info.force = false; + + // get the winding plane and the depth of the projection volume + idPlane windingPlane; + winding.GetPlane( windingPlane ); + float depth = windingPlane.Distance( projectionOrigin ); + + // find the bounds for the projection + winding.GetBounds( info.projectionBounds ); + if ( parallel ) { + info.projectionBounds.ExpandSelf( depth ); + } else { + info.projectionBounds.AddPoint( projectionOrigin ); + } + + // calculate the world space projection volume bounding planes, positive sides face outside the decal + if ( parallel ) { + for ( int i = 0; i < winding.GetNumPoints(); i++ ) { + idVec3 edge = winding[(i+1)%winding.GetNumPoints()].ToVec3() - winding[i].ToVec3(); + info.boundingPlanes[i].Normal().Cross( windingPlane.Normal(), edge ); + info.boundingPlanes[i].Normalize(); + info.boundingPlanes[i].FitThroughPoint( winding[i].ToVec3() ); + } + } else { + for ( int i = 0; i < winding.GetNumPoints(); i++ ) { + info.boundingPlanes[i].FromPoints( projectionOrigin, winding[i].ToVec3(), winding[(i+1)%winding.GetNumPoints()].ToVec3() ); + } + } + info.boundingPlanes[NUM_DECAL_BOUNDING_PLANES - 2] = windingPlane; + info.boundingPlanes[NUM_DECAL_BOUNDING_PLANES - 2][3] -= depth; + info.boundingPlanes[NUM_DECAL_BOUNDING_PLANES - 1] = -windingPlane; + + // fades will be from these plane + info.fadePlanes[0] = windingPlane; + info.fadePlanes[0][3] -= fadeDepth; + info.fadePlanes[1] = -windingPlane; + info.fadePlanes[1][3] += depth - fadeDepth; + + // calculate the texture vectors for the winding + float len, texArea, inva; + idVec3 temp; + idVec5 d0, d1; + + const idVec5 &a = winding[0]; + const idVec5 &b = winding[1]; + const idVec5 &c = winding[2]; + + d0 = b.ToVec3() - a.ToVec3(); + d0.s = b.s - a.s; + d0.t = b.t - a.t; + d1 = c.ToVec3() - a.ToVec3(); + d1.s = c.s - a.s; + d1.t = c.t - a.t; + + texArea = ( d0[3] * d1[4] ) - ( d0[4] * d1[3] ); + inva = 1.0f / texArea; + + temp[0] = ( d0[0] * d1[4] - d0[4] * d1[0] ) * inva; + temp[1] = ( d0[1] * d1[4] - d0[4] * d1[1] ) * inva; + temp[2] = ( d0[2] * d1[4] - d0[4] * d1[2] ) * inva; + len = temp.Normalize(); + info.textureAxis[0].Normal() = temp * ( 1.0f / len ); + info.textureAxis[0][3] = winding[0].s - ( winding[0].ToVec3() * info.textureAxis[0].Normal() ); + + temp[0] = ( d0[3] * d1[0] - d0[0] * d1[3] ) * inva; + temp[1] = ( d0[3] * d1[1] - d0[1] * d1[3] ) * inva; + temp[2] = ( d0[3] * d1[2] - d0[2] * d1[3] ) * inva; + len = temp.Normalize(); + info.textureAxis[1].Normal() = temp * ( 1.0f / len ); + info.textureAxis[1][3] = winding[0].t - ( winding[0].ToVec3() * info.textureAxis[1].Normal() ); + + return true; +} + +/* +================= +idRenderModelDecal::CreateProjectionInfo +================= +*/ +void idRenderModelDecal::GlobalProjectionInfoToLocal( decalProjectionInfo_t &localInfo, const decalProjectionInfo_t &info, const idVec3 &origin, const idMat3 &axis ) { + float modelMatrix[16]; + + R_AxisToModelMatrix( axis, origin, modelMatrix ); + + for ( int j = 0; j < NUM_DECAL_BOUNDING_PLANES; j++ ) { + R_GlobalPlaneToLocal( modelMatrix, info.boundingPlanes[j], localInfo.boundingPlanes[j] ); + } + R_GlobalPlaneToLocal( modelMatrix, info.fadePlanes[0], localInfo.fadePlanes[0] ); + R_GlobalPlaneToLocal( modelMatrix, info.fadePlanes[1], localInfo.fadePlanes[1] ); + R_GlobalPlaneToLocal( modelMatrix, info.textureAxis[0], localInfo.textureAxis[0] ); + R_GlobalPlaneToLocal( modelMatrix, info.textureAxis[1], localInfo.textureAxis[1] ); + R_GlobalPointToLocal( modelMatrix, info.projectionOrigin, localInfo.projectionOrigin ); + localInfo.projectionBounds = info.projectionBounds; + localInfo.projectionBounds.TranslateSelf( -origin ); + localInfo.projectionBounds.RotateSelf( axis.Transpose() ); + localInfo.material = info.material; + localInfo.parallel = info.parallel; + localInfo.fadeDepth = info.fadeDepth; + localInfo.startTime = info.startTime; + localInfo.force = info.force; +} + +/* +================= +idRenderModelDecal::AddWinding +================= +*/ +void idRenderModelDecal::AddWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ) { + int i; + float invFadeDepth, fade; + decalInfo_t decalInfo; + + if ( ( material == NULL || material == decalMaterial ) && + tri.numVerts + w.GetNumPoints() < MAX_DECAL_VERTS && + tri.numIndexes + ( w.GetNumPoints() - 2 ) * 3 < MAX_DECAL_INDEXES ) { + + material = decalMaterial; + + // add to this decal + decalInfo = material->GetDecalInfo(); + invFadeDepth = -1.0f / fadeDepth; + + for ( i = 0; i < w.GetNumPoints(); i++ ) { + fade = fadePlanes[0].Distance( w[i].ToVec3() ) * invFadeDepth; + if ( fade < 0.0f ) { + fade = fadePlanes[1].Distance( w[i].ToVec3() ) * invFadeDepth; + } + if ( fade < 0.0f ) { + fade = 0.0f; + } else if ( fade > 0.99f ) { + fade = 1.0f; + } + fade = 1.0f - fade; + vertDepthFade[tri.numVerts + i] = fade; + tri.verts[tri.numVerts + i].xyz = w[i].ToVec3(); + tri.verts[tri.numVerts + i].st[0] = w[i].s; + tri.verts[tri.numVerts + i].st[1] = w[i].t; + for ( int k = 0 ; k < 4 ; k++ ) { + int icolor = idMath::FtoiFast( decalInfo.start[k] * fade * 255.0f ); + if ( icolor < 0 ) { + icolor = 0; + } else if ( icolor > 255 ) { + icolor = 255; + } + tri.verts[tri.numVerts + i].color[k] = icolor; + } + } + for ( i = 2; i < w.GetNumPoints(); i++ ) { + tri.indexes[tri.numIndexes + 0] = tri.numVerts; + tri.indexes[tri.numIndexes + 1] = tri.numVerts + i - 1; + tri.indexes[tri.numIndexes + 2] = tri.numVerts + i; + indexStartTime[tri.numIndexes] = + indexStartTime[tri.numIndexes + 1] = + indexStartTime[tri.numIndexes + 2] = startTime; + tri.numIndexes += 3; + } + tri.numVerts += w.GetNumPoints(); + return; + } + + // if we are at the end of the list, create a new decal + if ( !nextDecal ) { + nextDecal = idRenderModelDecal::Alloc(); + } + // let the next decal on the chain take a look + nextDecal->AddWinding( w, decalMaterial, fadePlanes, fadeDepth, startTime ); +} + +/* +================= +idRenderModelDecal::AddDepthFadedWinding +================= +*/ +void idRenderModelDecal::AddDepthFadedWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ) { + idFixedWinding front, back; + + front = w; + if ( front.Split( &back, fadePlanes[0], 0.1f ) == SIDE_CROSS ) { + AddWinding( back, decalMaterial, fadePlanes, fadeDepth, startTime ); + } + + if ( front.Split( &back, fadePlanes[1], 0.1f ) == SIDE_CROSS ) { + AddWinding( back, decalMaterial, fadePlanes, fadeDepth, startTime ); + } + + AddWinding( front, decalMaterial, fadePlanes, fadeDepth, startTime ); +} + +/* +================= +idRenderModelDecal::CreateDecal +================= +*/ +void idRenderModelDecal::CreateDecal( const idRenderModel *model, const decalProjectionInfo_t &localInfo ) { + + // check all model surfaces + for ( int surfNum = 0; surfNum < model->NumSurfaces(); surfNum++ ) { + const modelSurface_t *surf = model->Surface( surfNum ); + + // if no geometry or no shader + if ( !surf->geometry || !surf->shader ) { + continue; + } + + // decals and overlays use the same rules + if ( !localInfo.force && !surf->shader->AllowOverlays() ) { + continue; + } + + srfTriangles_t *stri = surf->geometry; + + // if the triangle bounds do not overlap with projection bounds + if ( !localInfo.projectionBounds.IntersectsBounds( stri->bounds ) ) { + continue; + } + + // allocate memory for the cull bits + byte *cullBits = (byte *)_alloca16( stri->numVerts * sizeof( cullBits[0] ) ); + + // catagorize all points by the planes + SIMDProcessor->DecalPointCull( cullBits, localInfo.boundingPlanes, stri->verts, stri->numVerts ); + + // find triangles inside the projection volume + for ( int triNum = 0, index = 0; index < stri->numIndexes; index += 3, triNum++ ) { + int v1 = stri->indexes[index+0]; + int v2 = stri->indexes[index+1]; + int v3 = stri->indexes[index+2]; + + // skip triangles completely off one side + if ( cullBits[v1] & cullBits[v2] & cullBits[v3] ) { + continue; + } + + // skip back facing triangles + if ( stri->facePlanes && stri->facePlanesCalculated && + stri->facePlanes[triNum].Normal() * localInfo.boundingPlanes[NUM_DECAL_BOUNDING_PLANES - 2].Normal() < -0.1f ) { + continue; + } + + // create a winding with texture coordinates for the triangle + idFixedWinding fw; + fw.SetNumPoints( 3 ); + if ( localInfo.parallel ) { + for ( int j = 0; j < 3; j++ ) { + fw[j] = stri->verts[stri->indexes[index+j]].xyz; + fw[j].s = localInfo.textureAxis[0].Distance( fw[j].ToVec3() ); + fw[j].t = localInfo.textureAxis[1].Distance( fw[j].ToVec3() ); + } + } else { + for ( int j = 0; j < 3; j++ ) { + idVec3 dir; + float scale; + + fw[j] = stri->verts[stri->indexes[index+j]].xyz; + dir = fw[j].ToVec3() - localInfo.projectionOrigin; + localInfo.boundingPlanes[NUM_DECAL_BOUNDING_PLANES - 1].RayIntersection( fw[j].ToVec3(), dir, scale ); + dir = fw[j].ToVec3() + scale * dir; + fw[j].s = localInfo.textureAxis[0].Distance( dir ); + fw[j].t = localInfo.textureAxis[1].Distance( dir ); + } + } + + int orBits = cullBits[v1] | cullBits[v2] | cullBits[v3]; + + // clip the exact surface triangle to the projection volume + for ( int j = 0; j < NUM_DECAL_BOUNDING_PLANES; j++ ) { + if ( orBits & ( 1 << j ) ) { + if ( !fw.ClipInPlace( -localInfo.boundingPlanes[j] ) ) { + break; + } + } + } + + if ( fw.GetNumPoints() == 0 ) { + continue; + } + + AddDepthFadedWinding( fw, localInfo.material, localInfo.fadePlanes, localInfo.fadeDepth, localInfo.startTime ); + } + } +} + +/* +===================== +idRenderModelDecal::RemoveFadedDecals +===================== +*/ +idRenderModelDecal *idRenderModelDecal::RemoveFadedDecals( idRenderModelDecal *decals, int time ) { + int i, j, minTime, newNumIndexes, newNumVerts; + int inUse[MAX_DECAL_VERTS]; + decalInfo_t decalInfo; + idRenderModelDecal *nextDecal; + + if ( decals == NULL ) { + return NULL; + } + + // recursively free any next decals + decals->nextDecal = RemoveFadedDecals( decals->nextDecal, time ); + + // free the decals if no material set + if ( decals->material == NULL ) { + nextDecal = decals->nextDecal; + Free( decals ); + return nextDecal; + } + + decalInfo = decals->material->GetDecalInfo(); + minTime = time - ( decalInfo.stayTime + decalInfo.fadeTime ); + + newNumIndexes = 0; + for ( i = 0; i < decals->tri.numIndexes; i += 3 ) { + if ( decals->indexStartTime[i] > minTime ) { + // keep this triangle + if ( newNumIndexes != i ) { + for ( j = 0; j < 3; j++ ) { + decals->tri.indexes[newNumIndexes+j] = decals->tri.indexes[i+j]; + decals->indexStartTime[newNumIndexes+j] = decals->indexStartTime[i+j]; + } + } + newNumIndexes += 3; + } + } + + // free the decals if all trianges faded away + if ( newNumIndexes == 0 ) { + nextDecal = decals->nextDecal; + Free( decals ); + return nextDecal; + } + + decals->tri.numIndexes = newNumIndexes; + + memset( inUse, 0, sizeof( inUse ) ); + for ( i = 0; i < decals->tri.numIndexes; i++ ) { + inUse[decals->tri.indexes[i]] = 1; + } + + newNumVerts = 0; + for ( i = 0; i < decals->tri.numVerts; i++ ) { + if ( !inUse[i] ) { + continue; + } + decals->tri.verts[newNumVerts] = decals->tri.verts[i]; + decals->vertDepthFade[newNumVerts] = decals->vertDepthFade[i]; + inUse[i] = newNumVerts; + newNumVerts++; + } + decals->tri.numVerts = newNumVerts; + + for ( i = 0; i < decals->tri.numIndexes; i++ ) { + decals->tri.indexes[i] = inUse[decals->tri.indexes[i]]; + } + + return decals; +} + +/* +===================== +idRenderModelDecal::AddDecalDrawSurf +===================== +*/ +void idRenderModelDecal::AddDecalDrawSurf( viewEntity_t *space ) { + int i, j, maxTime; + float f; + decalInfo_t decalInfo; + + if ( tri.numIndexes == 0 ) { + return; + } + + // fade down all the verts with time + decalInfo = material->GetDecalInfo(); + maxTime = decalInfo.stayTime + decalInfo.fadeTime; + + // set vertex colors and remove faded triangles + for ( i = 0 ; i < tri.numIndexes ; i += 3 ) { + int deltaTime = tr.viewDef->renderView.time - indexStartTime[i]; + + if ( deltaTime > maxTime ) { + continue; + } + + if ( deltaTime <= decalInfo.stayTime ) { + continue; + } + + deltaTime -= decalInfo.stayTime; + f = (float)deltaTime / decalInfo.fadeTime; + + for ( j = 0; j < 3; j++ ) { + int ind = tri.indexes[i+j]; + + for ( int k = 0; k < 4; k++ ) { + float fcolor = decalInfo.start[k] + ( decalInfo.end[k] - decalInfo.start[k] ) * f; + int icolor = idMath::FtoiFast( fcolor * vertDepthFade[ind] * 255.0f ); + if ( icolor < 0 ) { + icolor = 0; + } else if ( icolor > 255 ) { + icolor = 255; + } + tri.verts[ind].color[k] = icolor; + } + } + } + + // copy the tri and indexes to temp heap memory, + // because if we are running multi-threaded, we wouldn't + // be able to reorganize the index list + srfTriangles_t *newTri = (srfTriangles_t *)R_FrameAlloc( sizeof( *newTri ) ); + *newTri = tri; + + // copy the current vertexes to temp vertex cache + newTri->ambientCache = vertexCache.AllocFrameTemp( tri.verts, tri.numVerts * sizeof( idDrawVert ) ); + + // create the drawsurf + R_AddDrawSurf( newTri, space, &space->entityDef->parms, material, space->scissorRect ); +} + +/* +==================== +idRenderModelDecal::ReadFromDemoFile +==================== +*/ +void idRenderModelDecal::ReadFromDemoFile( idDemoFile *f ) { + // FIXME: implement +} + +/* +==================== +idRenderModelDecal::WriteToDemoFile +==================== +*/ +void idRenderModelDecal::WriteToDemoFile( idDemoFile *f ) const { + // FIXME: implement +} diff --git a/renderer/ModelDecal.h b/renderer/ModelDecal.h new file mode 100644 index 000000000..3ce37bb17 --- /dev/null +++ b/renderer/ModelDecal.h @@ -0,0 +1,107 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODELDECAL_H__ +#define __MODELDECAL_H__ + +/* +=============================================================================== + + Decals are lightweight primitives for bullet / blood marks. + Decals with common materials will be merged together, but additional + decals will be allocated as needed. The material should not be + one that receives lighting, because no interactions are generated + for these lightweight surfaces. + + FIXME: Decals on models in portalled off areas do not get freed + until the area becomes visible again. + +=============================================================================== +*/ + +const int NUM_DECAL_BOUNDING_PLANES = 6; + +typedef struct decalProjectionInfo_s { + idVec3 projectionOrigin; + idBounds projectionBounds; + idPlane boundingPlanes[6]; + idPlane fadePlanes[2]; + idPlane textureAxis[2]; + const idMaterial * material; + bool parallel; + float fadeDepth; + int startTime; + bool force; +} decalProjectionInfo_t; + + +class idRenderModelDecal { +public: + idRenderModelDecal( void ); + ~idRenderModelDecal( void ); + + static idRenderModelDecal * Alloc( void ); + static void Free( idRenderModelDecal *decal ); + + // Creates decal projection info. + static bool CreateProjectionInfo( decalProjectionInfo_t &info, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ); + + // Transform the projection info from global space to local. + static void GlobalProjectionInfoToLocal( decalProjectionInfo_t &localInfo, const decalProjectionInfo_t &info, const idVec3 &origin, const idMat3 &axis ); + + // Creates a deal on the given model. + void CreateDecal( const idRenderModel *model, const decalProjectionInfo_t &localInfo ); + + // Remove decals that are completely faded away. + static idRenderModelDecal * RemoveFadedDecals( idRenderModelDecal *decals, int time ); + + // Updates the vertex colors, removing any faded indexes, + // then copy the verts to temporary vertex cache and adds a drawSurf. + void AddDecalDrawSurf( struct viewEntity_s *space ); + + // Returns the next decal in the chain. + idRenderModelDecal * Next( void ) const { return nextDecal; } + + void ReadFromDemoFile( class idDemoFile *f ); + void WriteToDemoFile( class idDemoFile *f ) const; + +private: + static const int MAX_DECAL_VERTS = 40; + static const int MAX_DECAL_INDEXES = 60; + + const idMaterial * material; + srfTriangles_t tri; + idDrawVert verts[MAX_DECAL_VERTS]; + float vertDepthFade[MAX_DECAL_VERTS]; + glIndex_t indexes[MAX_DECAL_INDEXES]; + int indexStartTime[MAX_DECAL_INDEXES]; + idRenderModelDecal * nextDecal; + + // Adds the winding triangles to the appropriate decal in the + // chain, creating a new one if necessary. + void AddWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ); + + // Adds depth faded triangles for the winding to the appropriate + // decal in the chain, creating a new one if necessary. + // The part of the winding at the front side of both fade planes is not faded. + // The parts at the back sides of the fade planes are faded with the given depth. + void AddDepthFadedWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ); +}; + +#endif /* !__MODELDECAL_H__ */ diff --git a/renderer/ModelManager.cpp b/renderer/ModelManager.cpp new file mode 100644 index 000000000..511f81b18 --- /dev/null +++ b/renderer/ModelManager.cpp @@ -0,0 +1,613 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Model_local.h" +#include "tr_local.h" // just for R_FreeWorldInteractions and R_CreateWorldInteractions + + +class idRenderModelManagerLocal : public idRenderModelManager { +public: + idRenderModelManagerLocal(); + virtual ~idRenderModelManagerLocal() {} + + virtual void Init(); + virtual void Shutdown(); + virtual idRenderModel * AllocModel(); + virtual void FreeModel( idRenderModel *model ); + virtual idRenderModel * FindModel( const char *modelName ); + virtual idRenderModel * CheckModel( const char *modelName ); + virtual idRenderModel * DefaultModel(); + virtual void AddModel( idRenderModel *model ); + virtual void RemoveModel( idRenderModel *model ); + virtual void ReloadModels( bool forceAll = false ); + virtual void FreeModelVertexCaches(); + virtual void WritePrecacheCommands( idFile *file ); + virtual void BeginLevelLoad(); + virtual void EndLevelLoad(); + + virtual void PrintMemInfo( MemInfo_t *mi ); + +private: + idList models; + idHashIndex hash; + idRenderModel * defaultModel; + idRenderModel * beamModel; + idRenderModel * spriteModel; + idRenderModel * trailModel; + bool insideLevelLoad; // don't actually load now + + idRenderModel * GetModel( const char *modelName, bool createIfNotFound ); + + static void PrintModel_f( const idCmdArgs &args ); + static void ListModels_f( const idCmdArgs &args ); + static void ReloadModels_f( const idCmdArgs &args ); + static void TouchModel_f( const idCmdArgs &args ); +}; + + +idRenderModelManagerLocal localModelManager; +idRenderModelManager * renderModelManager = &localModelManager; + +/* +============== +idRenderModelManagerLocal::idRenderModelManagerLocal +============== +*/ +idRenderModelManagerLocal::idRenderModelManagerLocal() { + defaultModel = NULL; + beamModel = NULL; + spriteModel = NULL; + insideLevelLoad = false; + trailModel = NULL; +} + +/* +============== +idRenderModelManagerLocal::PrintModel_f +============== +*/ +void idRenderModelManagerLocal::PrintModel_f( const idCmdArgs &args ) { + idRenderModel *model; + + if ( args.Argc() != 2 ) { + common->Printf( "usage: printModel \n" ); + return; + } + + model = renderModelManager->CheckModel( args.Argv( 1 ) ); + if ( !model ) { + common->Printf( "model \"%s\" not found\n", args.Argv( 1 ) ); + return; + } + + model->Print(); +} + +/* +============== +idRenderModelManagerLocal::ListModels_f +============== +*/ +void idRenderModelManagerLocal::ListModels_f( const idCmdArgs &args ) { + int totalMem = 0; + int inUse = 0; + + common->Printf( " mem srf verts tris\n" ); + common->Printf( " --- --- ----- ----\n" ); + + for ( int i = 0 ; i < localModelManager.models.Num() ; i++ ) { + idRenderModel *model = localModelManager.models[i]; + + if ( !model->IsLoaded() ) { + continue; + } + model->List(); + totalMem += model->Memory(); + inUse++; + } + + common->Printf( " --- --- ----- ----\n" ); + common->Printf( " mem srf verts tris\n" ); + + common->Printf( "%i loaded models\n", inUse ); + common->Printf( "total memory: %4.1fM\n", (float)totalMem / (1024*1024) ); +} + +/* +============== +idRenderModelManagerLocal::ReloadModels_f +============== +*/ +void idRenderModelManagerLocal::ReloadModels_f( const idCmdArgs &args ) { + if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) { + localModelManager.ReloadModels( true ); + } else { + localModelManager.ReloadModels( false ); + } +} + +/* +============== +idRenderModelManagerLocal::TouchModel_f + +Precache a specific model +============== +*/ +void idRenderModelManagerLocal::TouchModel_f( const idCmdArgs &args ) { + const char *model = args.Argv( 1 ); + + if ( !model[0] ) { + common->Printf( "usage: touchModel \n" ); + return; + } + + common->Printf( "touchModel %s\n", model ); + session->UpdateScreen(); + idRenderModel *m = renderModelManager->CheckModel( model ); + if ( !m ) { + common->Printf( "...not found\n" ); + } +} + +/* +================= +idRenderModelManagerLocal::WritePrecacheCommands +================= +*/ +void idRenderModelManagerLocal::WritePrecacheCommands( idFile *f ) { + for ( int i = 0 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + + if ( !model ) { + continue; + } + if ( !model->IsReloadable() ) { + continue; + } + + char str[1024]; + sprintf( str, "touchModel %s\n", model->Name() ); + common->Printf( "%s", str ); + f->Printf( "%s", str ); + } +} + +/* +================= +idRenderModelManagerLocal::Init +================= +*/ +void idRenderModelManagerLocal::Init() { + cmdSystem->AddCommand( "listModels", ListModels_f, CMD_FL_RENDERER, "lists all models" ); + cmdSystem->AddCommand( "printModel", PrintModel_f, CMD_FL_RENDERER, "prints model info", idCmdSystem::ArgCompletion_ModelName ); + cmdSystem->AddCommand( "reloadModels", ReloadModels_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "reloads models" ); + cmdSystem->AddCommand( "touchModel", TouchModel_f, CMD_FL_RENDERER, "touches a model", idCmdSystem::ArgCompletion_ModelName ); + + insideLevelLoad = false; + + // create a default model + idRenderModelStatic *model = new idRenderModelStatic; + model->InitEmpty( "_DEFAULT" ); + model->MakeDefaultModel(); + model->SetLevelLoadReferenced( true ); + defaultModel = model; + AddModel( model ); + + // create the beam model + idRenderModelStatic *beam = new idRenderModelBeam; + beam->InitEmpty( "_BEAM" ); + beam->SetLevelLoadReferenced( true ); + beamModel = beam; + AddModel( beam ); + + idRenderModelStatic *sprite = new idRenderModelSprite; + sprite->InitEmpty( "_SPRITE" ); + sprite->SetLevelLoadReferenced( true ); + spriteModel = sprite; + AddModel( sprite ); +} + +/* +================= +idRenderModelManagerLocal::Shutdown +================= +*/ +void idRenderModelManagerLocal::Shutdown() { + models.DeleteContents( true ); + hash.Free(); +} + +/* +================= +idRenderModelManagerLocal::GetModel +================= +*/ +idRenderModel *idRenderModelManagerLocal::GetModel( const char *modelName, bool createIfNotFound ) { + idStr canonical; + idStr extension; + + if ( !modelName || !modelName[0] ) { + return NULL; + } + + canonical = modelName; + canonical.ToLower(); + + // see if it is already present + int key = hash.GenerateKey( modelName, false ); + for ( int i = hash.First( key ); i != -1; i = hash.Next( i ) ) { + idRenderModel *model = models[i]; + + if ( canonical.Icmp( model->Name() ) == 0 ) { + if ( !model->IsLoaded() ) { + // reload it if it was purged + model->LoadModel(); + } else if ( insideLevelLoad && !model->IsLevelLoadReferenced() ) { + // we are reusing a model already in memory, but + // touch all the materials to make sure they stay + // in memory as well + model->TouchData(); + } + model->SetLevelLoadReferenced( true ); + return model; + } + } + + // see if we can load it + + // determine which subclass of idRenderModel to initialize + + idRenderModel *model; + + canonical.ExtractFileExtension( extension ); + + if ( ( extension.Icmp( "ase" ) == 0 ) || ( extension.Icmp( "lwo" ) == 0 ) || ( extension.Icmp( "flt" ) == 0 ) ) { + model = new idRenderModelStatic; + model->InitFromFile( modelName ); + } else if ( extension.Icmp( "ma" ) == 0 ) { + model = new idRenderModelStatic; + model->InitFromFile( modelName ); + } else if ( extension.Icmp( MD5_MESH_EXT ) == 0 ) { + model = new idRenderModelMD5; + model->InitFromFile( modelName ); + } else if ( extension.Icmp( "md3" ) == 0 ) { + model = new idRenderModelMD3; + model->InitFromFile( modelName ); + } else if ( extension.Icmp( "prt" ) == 0 ) { + model = new idRenderModelPrt; + model->InitFromFile( modelName ); + } else if ( extension.Icmp( "liquid" ) == 0 ) { + model = new idRenderModelLiquid; + model->InitFromFile( modelName ); + } else { + + if ( extension.Length() ) { + common->Warning( "unknown model type '%s'", canonical.c_str() ); + } + + if ( !createIfNotFound ) { + return NULL; + } + + idRenderModelStatic *smodel = new idRenderModelStatic; + smodel->InitEmpty( modelName ); + smodel->MakeDefaultModel(); + + model = smodel; + } + + model->SetLevelLoadReferenced( true ); + + if ( !createIfNotFound && model->IsDefaultModel() ) { + delete model; + model = NULL; + + return NULL; + } + + AddModel( model ); + + return model; +} + +/* +================= +idRenderModelManagerLocal::AllocModel +================= +*/ +idRenderModel *idRenderModelManagerLocal::AllocModel() { + return new idRenderModelStatic(); +} + +/* +================= +idRenderModelManagerLocal::FreeModel +================= +*/ +void idRenderModelManagerLocal::FreeModel( idRenderModel *model ) { + if ( !model ) { + return; + } + if ( !dynamic_cast( model ) ) { + common->Error( "idRenderModelManager::FreeModel: model '%s' is not a static model", model->Name() ); + return; + } + if ( model == defaultModel ) { + common->Error( "idRenderModelManager::FreeModel: can't free the default model" ); + return; + } + if ( model == beamModel ) { + common->Error( "idRenderModelManager::FreeModel: can't free the beam model" ); + return; + } + if ( model == spriteModel ) { + common->Error( "idRenderModelManager::FreeModel: can't free the sprite model" ); + return; + } + + R_CheckForEntityDefsUsingModel( model ); + + delete model; +} + +/* +================= +idRenderModelManagerLocal::FindModel +================= +*/ +idRenderModel *idRenderModelManagerLocal::FindModel( const char *modelName ) { + return GetModel( modelName, true ); +} + +/* +================= +idRenderModelManagerLocal::CheckModel +================= +*/ +idRenderModel *idRenderModelManagerLocal::CheckModel( const char *modelName ) { + return GetModel( modelName, false ); +} + +/* +================= +idRenderModelManagerLocal::DefaultModel +================= +*/ +idRenderModel *idRenderModelManagerLocal::DefaultModel() { + return defaultModel; +} + +/* +================= +idRenderModelManagerLocal::AddModel +================= +*/ +void idRenderModelManagerLocal::AddModel( idRenderModel *model ) { + hash.Add( hash.GenerateKey( model->Name(), false ), models.Append( model ) ); +} + +/* +================= +idRenderModelManagerLocal::RemoveModel +================= +*/ +void idRenderModelManagerLocal::RemoveModel( idRenderModel *model ) { + int index = models.FindIndex( model ); + hash.RemoveIndex( hash.GenerateKey( model->Name(), false ), index ); + models.RemoveIndex( index ); +} + +/* +================= +idRenderModelManagerLocal::ReloadModels +================= +*/ +void idRenderModelManagerLocal::ReloadModels( bool forceAll ) { + if ( forceAll ) { + common->Printf( "Reloading all model files...\n" ); + } else { + common->Printf( "Checking for changed model files...\n" ); + } + + R_FreeDerivedData(); + + // skip the default model at index 0 + for ( int i = 1 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + + // we may want to allow world model reloading in the future, but we don't now + if ( !model->IsReloadable() ) { + continue; + } + + if ( !forceAll ) { + // check timestamp + ID_TIME_T current; + + fileSystem->ReadFile( model->Name(), NULL, ¤t ); + if ( current <= model->Timestamp() ) { + continue; + } + } + + common->DPrintf( "reloading %s.\n", model->Name() ); + + model->LoadModel(); + } + + // we must force the world to regenerate, because models may + // have changed size, making their references invalid + R_ReCreateWorldReferences(); +} + +/* +================= +idRenderModelManagerLocal::FreeModelVertexCaches +================= +*/ +void idRenderModelManagerLocal::FreeModelVertexCaches() { + for ( int i = 0 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + model->FreeVertexCache(); + } +} + +/* +================= +idRenderModelManagerLocal::BeginLevelLoad +================= +*/ +void idRenderModelManagerLocal::BeginLevelLoad() { + insideLevelLoad = true; + + for ( int i = 0 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + + if ( com_purgeAll.GetBool() && model->IsReloadable() ) { + R_CheckForEntityDefsUsingModel( model ); + model->PurgeModel(); + } + + model->SetLevelLoadReferenced( false ); + } + + // purge unused triangle surface memory + R_PurgeTriSurfData( frameData ); +} + +/* +================= +idRenderModelManagerLocal::EndLevelLoad +================= +*/ +void idRenderModelManagerLocal::EndLevelLoad() { + common->Printf( "----- idRenderModelManagerLocal::EndLevelLoad -----\n" ); + + int start = Sys_Milliseconds(); + + insideLevelLoad = false; + int purgeCount = 0; + int keepCount = 0; + int loadCount = 0; + + // purge any models not touched + for ( int i = 0 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + + if ( !model->IsLevelLoadReferenced() && model->IsLoaded() && model->IsReloadable() ) { + +// common->Printf( "purging %s\n", model->Name() ); + + purgeCount++; + + R_CheckForEntityDefsUsingModel( model ); + + model->PurgeModel(); + + } else { + +// common->Printf( "keeping %s\n", model->Name() ); + + keepCount++; + } + } + + // purge unused triangle surface memory + R_PurgeTriSurfData( frameData ); + + // load any new ones + for ( int i = 0 ; i < models.Num() ; i++ ) { + idRenderModel *model = models[i]; + + if ( model->IsLevelLoadReferenced() && !model->IsLoaded() && model->IsReloadable() ) { + + loadCount++; + model->LoadModel(); + + if ( ( loadCount & 15 ) == 0 ) { + session->PacifierUpdate(); + } + } + } + + // _D3XP added this + int end = Sys_Milliseconds(); + common->Printf( "%5i models purged from previous level, ", purgeCount ); + common->Printf( "%5i models kept.\n", keepCount ); + if ( loadCount ) { + common->Printf( "%5i new models loaded in %5.1f seconds\n", loadCount, (end-start) * 0.001 ); + } + common->Printf( "---------------------------------------------------\n" ); +} + +/* +================= +idRenderModelManagerLocal::PrintMemInfo +================= +*/ +void idRenderModelManagerLocal::PrintMemInfo( MemInfo_t *mi ) { + int i, j, totalMem = 0; + int *sortIndex; + idFile *f; + + f = fileSystem->OpenFileWrite( mi->filebase + "_models.txt" ); + if ( !f ) { + return; + } + + // sort first + sortIndex = new int[ localModelManager.models.Num()]; + + for ( i = 0; i < localModelManager.models.Num(); i++ ) { + sortIndex[i] = i; + } + + for ( i = 0; i < localModelManager.models.Num() - 1; i++ ) { + for ( j = i + 1; j < localModelManager.models.Num(); j++ ) { + if ( localModelManager.models[sortIndex[i]]->Memory() < localModelManager.models[sortIndex[j]]->Memory() ) { + int temp = sortIndex[i]; + sortIndex[i] = sortIndex[j]; + sortIndex[j] = temp; + } + } + } + + // print next + for ( int i = 0 ; i < localModelManager.models.Num() ; i++ ) { + idRenderModel *model = localModelManager.models[sortIndex[i]]; + int mem; + + if ( !model->IsLoaded() ) { + continue; + } + + mem = model->Memory(); + totalMem += mem; + f->Printf( "%s %s\n", idStr::FormatNumber( mem ).c_str(), model->Name() ); + } + + delete sortIndex; + mi->modelAssetsTotal = totalMem; + + f->Printf( "\nTotal model bytes allocated: %s\n", idStr::FormatNumber( totalMem ).c_str() ); + fileSystem->CloseFile( f ); +} diff --git a/renderer/ModelManager.h b/renderer/ModelManager.h new file mode 100644 index 000000000..e0dc32108 --- /dev/null +++ b/renderer/ModelManager.h @@ -0,0 +1,90 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODELMANAGER_H__ +#define __MODELMANAGER_H__ + +/* +=============================================================================== + + Model Manager + + Temporarily created models do not need to be added to the model manager. + +=============================================================================== +*/ + +class idRenderModelManager { +public: + virtual ~idRenderModelManager() {} + + // registers console commands and clears the list + virtual void Init() = 0; + + // frees all the models + virtual void Shutdown() = 0; + + // called only by renderer::BeginLevelLoad + virtual void BeginLevelLoad() = 0; + + // called only by renderer::EndLevelLoad + virtual void EndLevelLoad() = 0; + + // allocates a new empty render model. + virtual idRenderModel * AllocModel() = 0; + + // frees a render model + virtual void FreeModel( idRenderModel *model ) = 0; + + // returns NULL if modelName is NULL or an empty string, otherwise + // it will create a default model if not loadable + virtual idRenderModel * FindModel( const char *modelName ) = 0; + + // returns NULL if not loadable + virtual idRenderModel * CheckModel( const char *modelName ) = 0; + + // returns the default cube model + virtual idRenderModel * DefaultModel() = 0; + + // world map parsing will add all the inline models with this call + virtual void AddModel( idRenderModel *model ) = 0; + + // when a world map unloads, it removes its internal models from the list + // before freeing them. + // There may be an issue with multiple renderWorlds that share data... + virtual void RemoveModel( idRenderModel *model ) = 0; + + // the reloadModels console command calls this, but it can + // also be explicitly invoked + virtual void ReloadModels( bool forceAll = false ) = 0; + + // write "touchModel " commands for each non-world-map model + virtual void WritePrecacheCommands( idFile *f ) = 0; + + // called during vid_restart + virtual void FreeModelVertexCaches() = 0; + + // print memory info + virtual void PrintMemInfo( MemInfo_t *mi ) = 0; +}; + +// this will be statically pointed at a private implementation +extern idRenderModelManager *renderModelManager; + +#endif /* !__MODELMANAGER_H__ */ diff --git a/renderer/ModelOverlay.cpp b/renderer/ModelOverlay.cpp new file mode 100644 index 000000000..3c35568fe --- /dev/null +++ b/renderer/ModelOverlay.cpp @@ -0,0 +1,377 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Model_local.h" +#include "tr_local.h" + + +/* +==================== +idRenderModelOverlay::idRenderModelOverlay +==================== +*/ +idRenderModelOverlay::idRenderModelOverlay() { +} + +/* +==================== +idRenderModelOverlay::~idRenderModelOverlay +==================== +*/ +idRenderModelOverlay::~idRenderModelOverlay() { + int i, k; + + for ( k = 0; k < materials.Num(); k++ ) { + for ( i = 0; i < materials[k]->surfaces.Num(); i++ ) { + FreeSurface( materials[k]->surfaces[i] ); + } + materials[k]->surfaces.Clear(); + delete materials[k]; + } + materials.Clear(); +} + +/* +==================== +idRenderModelOverlay::Alloc +==================== +*/ +idRenderModelOverlay *idRenderModelOverlay::Alloc( void ) { + return new idRenderModelOverlay; +} + +/* +==================== +idRenderModelOverlay::Free +==================== +*/ +void idRenderModelOverlay::Free( idRenderModelOverlay *overlay ) { + delete overlay; +} + +/* +==================== +idRenderModelOverlay::FreeSurface +==================== +*/ +void idRenderModelOverlay::FreeSurface( overlaySurface_t *surface ) { + if ( surface->verts ) { + Mem_Free( surface->verts ); + } + if ( surface->indexes ) { + Mem_Free( surface->indexes ); + } + Mem_Free( surface ); +} + +/* +===================== +idRenderModelOverlay::CreateOverlay + +This projects on both front and back sides to avoid seams +The material should be clamped, because entire triangles are added, some of which +may extend well past the 0.0 to 1.0 texture range +===================== +*/ +void idRenderModelOverlay::CreateOverlay( const idRenderModel *model, const idPlane localTextureAxis[2], const idMaterial *mtr ) { + int i, maxVerts, maxIndexes, surfNum; + idRenderModelOverlay *overlay = NULL; + + // count up the maximum possible vertices and indexes per surface + maxVerts = 0; + maxIndexes = 0; + for ( surfNum = 0; surfNum < model->NumSurfaces(); surfNum++ ) { + const modelSurface_t *surf = model->Surface( surfNum ); + if ( surf->geometry->numVerts > maxVerts ) { + maxVerts = surf->geometry->numVerts; + } + if ( surf->geometry->numIndexes > maxIndexes ) { + maxIndexes = surf->geometry->numIndexes; + } + } + + // make temporary buffers for the building process + overlayVertex_t *overlayVerts = (overlayVertex_t *)_alloca( maxVerts * sizeof( *overlayVerts ) ); + glIndex_t *overlayIndexes = (glIndex_t *)_alloca16( maxIndexes * sizeof( *overlayIndexes ) ); + + // pull out the triangles we need from the base surfaces + for ( surfNum = 0; surfNum < model->NumBaseSurfaces(); surfNum++ ) { + const modelSurface_t *surf = model->Surface( surfNum ); + float d; + + if ( !surf->geometry || !surf->shader ) { + continue; + } + + // some surfaces can explicitly disallow overlays + if ( !surf->shader->AllowOverlays() ) { + continue; + } + + const srfTriangles_t *stri = surf->geometry; + + // try to cull the whole surface along the first texture axis + d = stri->bounds.PlaneDistance( localTextureAxis[0] ); + if ( d < 0.0f || d > 1.0f ) { + continue; + } + + // try to cull the whole surface along the second texture axis + d = stri->bounds.PlaneDistance( localTextureAxis[1] ); + if ( d < 0.0f || d > 1.0f ) { + continue; + } + + byte *cullBits = (byte *)_alloca16( stri->numVerts * sizeof( cullBits[0] ) ); + idVec2 *texCoords = (idVec2 *)_alloca16( stri->numVerts * sizeof( texCoords[0] ) ); + + SIMDProcessor->OverlayPointCull( cullBits, texCoords, localTextureAxis, stri->verts, stri->numVerts ); + + glIndex_t *vertexRemap = (glIndex_t *)_alloca16( sizeof( vertexRemap[0] ) * stri->numVerts ); + SIMDProcessor->Memset( vertexRemap, -1, sizeof( vertexRemap[0] ) * stri->numVerts ); + + // find triangles that need the overlay + int numVerts = 0; + int numIndexes = 0; + int triNum = 0; + for ( int index = 0; index < stri->numIndexes; index += 3, triNum++ ) { + int v1 = stri->indexes[index+0]; + int v2 = stri->indexes[index+1]; + int v3 = stri->indexes[index+2]; + + // skip triangles completely off one side + if ( cullBits[v1] & cullBits[v2] & cullBits[v3] ) { + continue; + } + + // we could do more precise triangle culling, like the light interaction does, if desired + + // keep this triangle + for ( int vnum = 0; vnum < 3; vnum++ ) { + int ind = stri->indexes[index+vnum]; + if ( vertexRemap[ind] == (glIndex_t)-1 ) { + vertexRemap[ind] = numVerts; + + overlayVerts[numVerts].vertexNum = ind; + overlayVerts[numVerts].st[0] = texCoords[ind][0]; + overlayVerts[numVerts].st[1] = texCoords[ind][1]; + + numVerts++; + } + overlayIndexes[numIndexes++] = vertexRemap[ind]; + } + } + + if ( !numIndexes ) { + continue; + } + + overlaySurface_t *s = (overlaySurface_t *) Mem_Alloc( sizeof( overlaySurface_t ) ); + s->surfaceNum = surfNum; + s->surfaceId = surf->id; + s->verts = (overlayVertex_t *)Mem_Alloc( numVerts * sizeof( s->verts[0] ) ); + memcpy( s->verts, overlayVerts, numVerts * sizeof( s->verts[0] ) ); + s->numVerts = numVerts; + s->indexes = (glIndex_t *)Mem_Alloc( numIndexes * sizeof( s->indexes[0] ) ); + memcpy( s->indexes, overlayIndexes, numIndexes * sizeof( s->indexes[0] ) ); + s->numIndexes = numIndexes; + + for ( i = 0; i < materials.Num(); i++ ) { + if ( materials[i]->material == mtr ) { + break; + } + } + if ( i < materials.Num() ) { + materials[i]->surfaces.Append( s ); + } else { + overlayMaterial_t *mat = new overlayMaterial_t; + mat->material = mtr; + mat->surfaces.Append( s ); + materials.Append( mat ); + } + } + + // remove the oldest overlay surfaces if there are too many per material + for ( i = 0; i < materials.Num(); i++ ) { + while( materials[i]->surfaces.Num() > MAX_OVERLAY_SURFACES ) { + FreeSurface( materials[i]->surfaces[0] ); + materials[i]->surfaces.RemoveIndex( 0 ); + } + } +} + +/* +==================== +idRenderModelOverlay::AddOverlaySurfacesToModel +==================== +*/ +void idRenderModelOverlay::AddOverlaySurfacesToModel( idRenderModel *baseModel ) { + int i, j, k, numVerts, numIndexes, surfaceNum; + const modelSurface_t *baseSurf; + idRenderModelStatic *staticModel; + overlaySurface_t *surf; + srfTriangles_t *newTri; + modelSurface_t *newSurf; + + if ( baseModel == NULL || baseModel->IsDefaultModel() ) { + return; + } + + // md5 models won't have any surfaces when r_showSkel is set + if ( !baseModel->NumSurfaces() ) { + return; + } + + if ( baseModel->IsDynamicModel() != DM_STATIC ) { + common->Error( "idRenderModelOverlay::AddOverlaySurfacesToModel: baseModel is not a static model" ); + } + + assert( dynamic_cast(baseModel) != NULL ); + staticModel = static_cast(baseModel); + + staticModel->overlaysAdded = 0; + + if ( !materials.Num() ) { + staticModel->DeleteSurfacesWithNegativeId(); + return; + } + + for ( k = 0; k < materials.Num(); k++ ) { + + numVerts = numIndexes = 0; + for ( i = 0; i < materials[k]->surfaces.Num(); i++ ) { + numVerts += materials[k]->surfaces[i]->numVerts; + numIndexes += materials[k]->surfaces[i]->numIndexes; + } + + if ( staticModel->FindSurfaceWithId( -1 - k, surfaceNum ) ) { + newSurf = &staticModel->surfaces[surfaceNum]; + } else { + newSurf = &staticModel->surfaces.Alloc(); + newSurf->geometry = NULL; + newSurf->shader = materials[k]->material; + newSurf->id = -1 - k; + } + + if ( newSurf->geometry == NULL || newSurf->geometry->numVerts < numVerts || newSurf->geometry->numIndexes < numIndexes ) { + R_FreeStaticTriSurf( newSurf->geometry ); + newSurf->geometry = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( newSurf->geometry, numVerts ); + R_AllocStaticTriSurfIndexes( newSurf->geometry, numIndexes ); + SIMDProcessor->Memset( newSurf->geometry->verts, 0, numVerts * sizeof( newTri->verts[0] ) ); + } else { + R_FreeStaticTriSurfVertexCaches( newSurf->geometry ); + } + + newTri = newSurf->geometry; + numVerts = numIndexes = 0; + + for ( i = 0; i < materials[k]->surfaces.Num(); i++ ) { + surf = materials[k]->surfaces[i]; + + // get the model surface for this overlay surface + if ( surf->surfaceNum < staticModel->NumSurfaces() ) { + baseSurf = staticModel->Surface( surf->surfaceNum ); + } else { + baseSurf = NULL; + } + + // if the surface ids no longer match + if ( !baseSurf || baseSurf->id != surf->surfaceId ) { + // find the surface with the correct id + if ( staticModel->FindSurfaceWithId( surf->surfaceId, surf->surfaceNum ) ) { + baseSurf = staticModel->Surface( surf->surfaceNum ); + } else { + // the surface with this id no longer exists + FreeSurface( surf ); + materials[k]->surfaces.RemoveIndex( i ); + i--; + continue; + } + } + + // copy indexes; + for ( j = 0; j < surf->numIndexes; j++ ) { + newTri->indexes[numIndexes + j] = numVerts + surf->indexes[j]; + } + numIndexes += surf->numIndexes; + + // copy vertices + for ( j = 0; j < surf->numVerts; j++ ) { + overlayVertex_t *overlayVert = &surf->verts[j]; + + newTri->verts[numVerts].st[0] = overlayVert->st[0]; + newTri->verts[numVerts].st[1] = overlayVert->st[1]; + + if ( overlayVert->vertexNum >= baseSurf->geometry->numVerts ) { + // This can happen when playing a demofile and a model has been changed since it was recorded, so just issue a warning and go on. + common->Warning( "idRenderModelOverlay::AddOverlaySurfacesToModel: overlay vertex out of range. Model has probably changed since generating the overlay." ); + FreeSurface( surf ); + materials[k]->surfaces.RemoveIndex( i ); + staticModel->DeleteSurfaceWithId( newSurf->id ); + return; + } + newTri->verts[numVerts].xyz = baseSurf->geometry->verts[overlayVert->vertexNum].xyz; + numVerts++; + } + } + + newTri->numVerts = numVerts; + newTri->numIndexes = numIndexes; + R_BoundTriSurf( newTri ); + + staticModel->overlaysAdded++; // so we don't create an overlay on an overlay surface + } +} + +/* +==================== +idRenderModelOverlay::RemoveOverlaySurfacesFromModel +==================== +*/ +void idRenderModelOverlay::RemoveOverlaySurfacesFromModel( idRenderModel *baseModel ) { + idRenderModelStatic *staticModel; + + assert( dynamic_cast(baseModel) != NULL ); + staticModel = static_cast(baseModel); + + staticModel->DeleteSurfacesWithNegativeId(); + staticModel->overlaysAdded = 0; +} + +/* +==================== +idRenderModelOverlay::ReadFromDemoFile +==================== +*/ +void idRenderModelOverlay::ReadFromDemoFile( idDemoFile *f ) { + // FIXME: implement +} + +/* +==================== +idRenderModelOverlay::WriteToDemoFile +==================== +*/ +void idRenderModelOverlay::WriteToDemoFile( idDemoFile *f ) const { + // FIXME: implement +} diff --git a/renderer/ModelOverlay.h b/renderer/ModelOverlay.h new file mode 100644 index 000000000..b5f25f13a --- /dev/null +++ b/renderer/ModelOverlay.h @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODELOVERLAY_H__ +#define __MODELOVERLAY_H__ + +/* +=============================================================================== + + Render model overlay for adding decals on top of dynamic models. + +=============================================================================== +*/ + +const int MAX_OVERLAY_SURFACES = 16; + +typedef struct overlayVertex_s { + int vertexNum; + float st[2]; +} overlayVertex_t; + +typedef struct overlaySurface_s { + int surfaceNum; + int surfaceId; + int numIndexes; + glIndex_t * indexes; + int numVerts; + overlayVertex_t * verts; +} overlaySurface_t; + +typedef struct overlayMaterial_s { + const idMaterial * material; + idList surfaces; +} overlayMaterial_t; + + +class idRenderModelOverlay { +public: + idRenderModelOverlay(); + ~idRenderModelOverlay(); + + static idRenderModelOverlay *Alloc( void ); + static void Free( idRenderModelOverlay *overlay ); + + // Projects an overlay onto deformable geometry and can be added to + // a render entity to allow decals on top of dynamic models. + // This does not generate tangent vectors, so it can't be used with + // light interaction shaders. Materials for overlays should always + // be clamped, because the projected texcoords can run well off the + // texture since no new clip vertexes are generated. + void CreateOverlay( const idRenderModel *model, const idPlane localTextureAxis[2], const idMaterial *material ); + + // Creates new model surfaces for baseModel, which should be a static instantiation of a dynamic model. + void AddOverlaySurfacesToModel( idRenderModel *baseModel ); + + // Removes overlay surfaces from the model. + static void RemoveOverlaySurfacesFromModel( idRenderModel *baseModel ); + + void ReadFromDemoFile( class idDemoFile *f ); + void WriteToDemoFile( class idDemoFile *f ) const; + +private: + idList materials; + + void FreeSurface( overlaySurface_t *surface ); +}; + +#endif /* !__MODELOVERLAY_H__ */ diff --git a/renderer/Model_ase.cpp b/renderer/Model_ase.cpp new file mode 100644 index 000000000..d433f83b3 --- /dev/null +++ b/renderer/Model_ase.cpp @@ -0,0 +1,903 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Model_ase.h" + +/* +====================================================================== + + Parses 3D Studio Max ASCII export files. + The goal is to parse the information into memory exactly as it is + represented in the file. Users of the data will then move it + into a form that is more convenient for them. + +====================================================================== +*/ + + +#define VERBOSE( x ) { if ( ase.verbose ) { common->Printf x ; } } + +// working variables used during parsing +typedef struct { + const char *buffer; + const char *curpos; + int len; + char token[1024]; + + bool verbose; + + aseModel_t *model; + aseObject_t *currentObject; + aseMesh_t *currentMesh; + aseMaterial_t *currentMaterial; + int currentFace; + int currentVertex; +} ase_t; + +static ase_t ase; + + +static aseMesh_t *ASE_GetCurrentMesh( void ) +{ + return ase.currentMesh; +} + +static int CharIsTokenDelimiter( int ch ) +{ + if ( ch <= 32 ) + return 1; + return 0; +} + +static int ASE_GetToken( bool restOfLine ) +{ + int i = 0; + + if ( ase.buffer == 0 ) + return 0; + + if ( ( ase.curpos - ase.buffer ) == ase.len ) + return 0; + + // skip over crap + while ( ( ( ase.curpos - ase.buffer ) < ase.len ) && + ( *ase.curpos <= 32 ) ) + { + ase.curpos++; + } + + while ( ( ase.curpos - ase.buffer ) < ase.len ) + { + ase.token[i] = *ase.curpos; + + ase.curpos++; + i++; + + if ( ( CharIsTokenDelimiter( ase.token[i-1] ) && !restOfLine ) || + ( ( ase.token[i-1] == '\n' ) || ( ase.token[i-1] == '\r' ) ) ) + { + ase.token[i-1] = 0; + break; + } + } + + ase.token[i] = 0; + + return 1; +} + +static void ASE_ParseBracedBlock( void (*parser)( const char *token ) ) +{ + int indent = 0; + + while ( ASE_GetToken( false ) ) + { + if ( !strcmp( ase.token, "{" ) ) + { + indent++; + } + else if ( !strcmp( ase.token, "}" ) ) + { + --indent; + if ( indent == 0 ) + break; + else if ( indent < 0 ) + common->Error( "Unexpected '}'" ); + } + else + { + if ( parser ) + parser( ase.token ); + } + } +} + +static void ASE_SkipEnclosingBraces( void ) +{ + int indent = 0; + + while ( ASE_GetToken( false ) ) + { + if ( !strcmp( ase.token, "{" ) ) + { + indent++; + } + else if ( !strcmp( ase.token, "}" ) ) + { + indent--; + if ( indent == 0 ) + break; + else if ( indent < 0 ) + common->Error( "Unexpected '}'" ); + } + } +} + +static void ASE_SkipRestOfLine( void ) +{ + ASE_GetToken( true ); +} + +static void ASE_KeyMAP_DIFFUSE( const char *token ) +{ + aseMaterial_t *material; + + if ( !strcmp( token, "*BITMAP" ) ) + { + idStr qpath; + idStr matname; + + ASE_GetToken( false ); + + // remove the quotes + char *s = strstr( ase.token + 1, "\"" ); + if ( s ) { + *s = 0; + } + matname = ase.token + 1; + + // convert the 3DSMax material pathname to a qpath + matname.BackSlashesToSlashes(); + qpath = fileSystem->OSPathToRelativePath( matname ); + idStr::Copynz( ase.currentMaterial->name, qpath, sizeof( ase.currentMaterial->name ) ); + } + else if ( !strcmp( token, "*UVW_U_OFFSET" ) ) + { + material = ase.model->materials[ase.model->materials.Num() - 1]; + ASE_GetToken( false ); + material->uOffset = atof( ase.token ); + } + else if ( !strcmp( token, "*UVW_V_OFFSET" ) ) + { + material = ase.model->materials[ase.model->materials.Num() - 1]; + ASE_GetToken( false ); + material->vOffset = atof( ase.token ); + } + else if ( !strcmp( token, "*UVW_U_TILING" ) ) + { + material = ase.model->materials[ase.model->materials.Num() - 1]; + ASE_GetToken( false ); + material->uTiling = atof( ase.token ); + } + else if ( !strcmp( token, "*UVW_V_TILING" ) ) + { + material = ase.model->materials[ase.model->materials.Num() - 1]; + ASE_GetToken( false ); + material->vTiling = atof( ase.token ); + } + else if ( !strcmp( token, "*UVW_ANGLE" ) ) + { + material = ase.model->materials[ase.model->materials.Num() - 1]; + ASE_GetToken( false ); + material->angle = atof( ase.token ); + } + else + { + } +} + +static void ASE_KeyMATERIAL( const char *token ) +{ + if ( !strcmp( token, "*MAP_DIFFUSE" ) ) + { + ASE_ParseBracedBlock( ASE_KeyMAP_DIFFUSE ); + } + else + { + } +} + +static void ASE_KeyMATERIAL_LIST( const char *token ) +{ + if ( !strcmp( token, "*MATERIAL_COUNT" ) ) + { + ASE_GetToken( false ); + VERBOSE( ( "..num materials: %s\n", ase.token ) ); + } + else if ( !strcmp( token, "*MATERIAL" ) ) + { + VERBOSE( ( "..material %d\n", ase.model->materials.Num() ) ); + + ase.currentMaterial = (aseMaterial_t *)Mem_Alloc( sizeof( aseMaterial_t ) ); + memset( ase.currentMaterial, 0, sizeof( aseMaterial_t ) ); + ase.currentMaterial->uTiling = 1; + ase.currentMaterial->vTiling = 1; + ase.model->materials.Append(ase.currentMaterial); + + ASE_ParseBracedBlock( ASE_KeyMATERIAL ); + } +} + +static void ASE_KeyNODE_TM( const char *token ) +{ + int i; + + if ( !strcmp( token, "*TM_ROW0" ) ) { + for ( i = 0 ; i < 3 ; i++ ) { + ASE_GetToken( false ); + ase.currentObject->mesh.transform[0][i] = atof( ase.token ); + } + } else if ( !strcmp( token, "*TM_ROW1" ) ) { + for ( i = 0 ; i < 3 ; i++ ) { + ASE_GetToken( false ); + ase.currentObject->mesh.transform[1][i] = atof( ase.token ); + } + } else if ( !strcmp( token, "*TM_ROW2" ) ) { + for ( i = 0 ; i < 3 ; i++ ) { + ASE_GetToken( false ); + ase.currentObject->mesh.transform[2][i] = atof( ase.token ); + } + } else if ( !strcmp( token, "*TM_ROW3" ) ) { + for ( i = 0 ; i < 3 ; i++ ) { + ASE_GetToken( false ); + ase.currentObject->mesh.transform[3][i] = atof( ase.token ); + } + } +} + +static void ASE_KeyMESH_VERTEX_LIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*MESH_VERTEX" ) ) + { + ASE_GetToken( false ); // skip number + + ASE_GetToken( false ); + pMesh->vertexes[ase.currentVertex].x = atof( ase.token ); + + ASE_GetToken( false ); + pMesh->vertexes[ase.currentVertex].y = atof( ase.token ); + + ASE_GetToken( false ); + pMesh->vertexes[ase.currentVertex].z = atof( ase.token ); + + ase.currentVertex++; + + if ( ase.currentVertex > pMesh->numVertexes ) + { + common->Error( "ase.currentVertex >= pMesh->numVertexes" ); + } + } + else + { + common->Error( "Unknown token '%s' while parsing MESH_VERTEX_LIST", token ); + } +} + +static void ASE_KeyMESH_FACE_LIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*MESH_FACE" ) ) + { + ASE_GetToken( false ); // skip face number + + // we are flipping the order here to change the front/back facing + // from 3DS to our standard (clockwise facing out) + ASE_GetToken( false ); // skip label + ASE_GetToken( false ); // first vertex + pMesh->faces[ase.currentFace].vertexNum[0] = atoi( ase.token ); + + ASE_GetToken( false ); // skip label + ASE_GetToken( false ); // second vertex + pMesh->faces[ase.currentFace].vertexNum[2] = atoi( ase.token ); + + ASE_GetToken( false ); // skip label + ASE_GetToken( false ); // third vertex + pMesh->faces[ase.currentFace].vertexNum[1] = atoi( ase.token ); + + ASE_GetToken( true ); + + // we could parse material id and smoothing groups here +/* + if ( ( p = strstr( ase.token, "*MESH_MTLID" ) ) != 0 ) + { + p += strlen( "*MESH_MTLID" ) + 1; + mtlID = atoi( p ); + } + else + { + common->Error( "No *MESH_MTLID found for face!" ); + } +*/ + + ase.currentFace++; + } + else + { + common->Error( "Unknown token '%s' while parsing MESH_FACE_LIST", token ); + } +} + +static void ASE_KeyTFACE_LIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*MESH_TFACE" ) ) + { + int a, b, c; + + ASE_GetToken( false ); + + ASE_GetToken( false ); + a = atoi( ase.token ); + ASE_GetToken( false ); + c = atoi( ase.token ); + ASE_GetToken( false ); + b = atoi( ase.token ); + + pMesh->faces[ase.currentFace].tVertexNum[0] = a; + pMesh->faces[ase.currentFace].tVertexNum[1] = b; + pMesh->faces[ase.currentFace].tVertexNum[2] = c; + + ase.currentFace++; + } + else + { + common->Error( "Unknown token '%s' in MESH_TFACE", token ); + } +} + +static void ASE_KeyCFACE_LIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*MESH_CFACE" ) ) + { + ASE_GetToken( false ); + + for ( int i = 0 ; i < 3 ; i++ ) { + ASE_GetToken( false ); + int a = atoi( ase.token ); + + // we flip the vertex order to change the face direction to our style + static int remap[3] = { 0, 2, 1 }; + pMesh->faces[ase.currentFace].vertexColors[remap[i]][0] = pMesh->cvertexes[a][0] * 255; + pMesh->faces[ase.currentFace].vertexColors[remap[i]][1] = pMesh->cvertexes[a][1] * 255; + pMesh->faces[ase.currentFace].vertexColors[remap[i]][2] = pMesh->cvertexes[a][2] * 255; + } + + ase.currentFace++; + } + else + { + common->Error( "Unknown token '%s' in MESH_CFACE", token ); + } +} + +static void ASE_KeyMESH_TVERTLIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*MESH_TVERT" ) ) + { + char u[80], v[80], w[80]; + + ASE_GetToken( false ); + + ASE_GetToken( false ); + strcpy( u, ase.token ); + + ASE_GetToken( false ); + strcpy( v, ase.token ); + + ASE_GetToken( false ); + strcpy( w, ase.token ); + + pMesh->tvertexes[ase.currentVertex].x = atof( u ); + // our OpenGL second texture axis is inverted from MAX's sense + pMesh->tvertexes[ase.currentVertex].y = 1.0f - atof( v ); + + ase.currentVertex++; + + if ( ase.currentVertex > pMesh->numTVertexes ) + { + common->Error( "ase.currentVertex > pMesh->numTVertexes" ); + } + } + else + { + common->Error( "Unknown token '%s' while parsing MESH_TVERTLIST", token ); + } +} + +static void ASE_KeyMESH_CVERTLIST( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + pMesh->colorsParsed = true; + + if ( !strcmp( token, "*MESH_VERTCOL" ) ) + { + ASE_GetToken( false ); + + ASE_GetToken( false ); + pMesh->cvertexes[ase.currentVertex][0] = atof( token ); + + ASE_GetToken( false ); + pMesh->cvertexes[ase.currentVertex][1] = atof( token ); + + ASE_GetToken( false ); + pMesh->cvertexes[ase.currentVertex][2] = atof( token ); + + ase.currentVertex++; + + if ( ase.currentVertex > pMesh->numCVertexes ) + { + common->Error( "ase.currentVertex > pMesh->numCVertexes" ); + } + } + else { + common->Error( "Unknown token '%s' while parsing MESH_CVERTLIST", token ); + } +} + +static void ASE_KeyMESH_NORMALS( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + aseFace_t *f; + idVec3 n; + + pMesh->normalsParsed = true; + f = &pMesh->faces[ase.currentFace]; + + if ( !strcmp( token, "*MESH_FACENORMAL" ) ) + { + int num; + + ASE_GetToken( false ); + num = atoi( ase.token ); + + if ( num >= pMesh->numFaces || num < 0 ) { + common->Error( "MESH_NORMALS face index out of range: %i", num ); + } + + if ( num != ase.currentFace ) { + common->Error( "MESH_NORMALS face index != currentFace" ); + } + + ASE_GetToken( false ); + n[0] = atof( ase.token ); + ASE_GetToken( false ); + n[1] = atof( ase.token ); + ASE_GetToken( false ); + n[2]= atof( ase.token ); + + f->faceNormal[0] = n[0] * pMesh->transform[0][0] + n[1] * pMesh->transform[1][0] + n[2] * pMesh->transform[2][0]; + f->faceNormal[1] = n[0] * pMesh->transform[0][1] + n[1] * pMesh->transform[1][1] + n[2] * pMesh->transform[2][1]; + f->faceNormal[2] = n[0] * pMesh->transform[0][2] + n[1] * pMesh->transform[1][2] + n[2] * pMesh->transform[2][2]; + + f->faceNormal.Normalize(); + + ase.currentFace++; + } + else if ( !strcmp( token, "*MESH_VERTEXNORMAL" ) ) + { + int num; + int v; + + ASE_GetToken( false ); + num = atoi( ase.token ); + + if ( num >= pMesh->numVertexes || num < 0 ) { + common->Error( "MESH_NORMALS vertex index out of range: %i", num ); + } + + f = &pMesh->faces[ ase.currentFace - 1 ]; + + for ( v = 0 ; v < 3 ; v++ ) { + if ( num == f->vertexNum[ v ] ) { + break; + } + } + + if ( v == 3 ) { + common->Error( "MESH_NORMALS vertex index doesn't match face" ); + } + + ASE_GetToken( false ); + n[0] = atof( ase.token ); + ASE_GetToken( false ); + n[1] = atof( ase.token ); + ASE_GetToken( false ); + n[2]= atof( ase.token ); + + f->vertexNormals[ v ][0] = n[0] * pMesh->transform[0][0] + n[1] * pMesh->transform[1][0] + n[2] * pMesh->transform[2][0]; + f->vertexNormals[ v ][1] = n[0] * pMesh->transform[0][1] + n[1] * pMesh->transform[1][1] + n[2] * pMesh->transform[2][1]; + f->vertexNormals[ v ][2] = n[0] * pMesh->transform[0][2] + n[1] * pMesh->transform[1][2] + n[2] * pMesh->transform[2][2]; + + f->vertexNormals[v].Normalize(); + } +} + +static void ASE_KeyMESH( const char *token ) +{ + aseMesh_t *pMesh = ASE_GetCurrentMesh(); + + if ( !strcmp( token, "*TIMEVALUE" ) ) + { + ASE_GetToken( false ); + + pMesh->timeValue = atoi( ase.token ); + VERBOSE( ( ".....timevalue: %d\n", pMesh->timeValue ) ); + } + else if ( !strcmp( token, "*MESH_NUMVERTEX" ) ) + { + ASE_GetToken( false ); + + pMesh->numVertexes = atoi( ase.token ); + VERBOSE( ( ".....num vertexes: %d\n", pMesh->numVertexes ) ); + } + else if ( !strcmp( token, "*MESH_NUMTVERTEX" ) ) + { + ASE_GetToken( false ); + + pMesh->numTVertexes = atoi( ase.token ); + VERBOSE( ( ".....num tvertexes: %d\n", pMesh->numTVertexes ) ); + } + else if ( !strcmp( token, "*MESH_NUMCVERTEX" ) ) + { + ASE_GetToken( false ); + + pMesh->numCVertexes = atoi( ase.token ); + VERBOSE( ( ".....num cvertexes: %d\n", pMesh->numCVertexes ) ); + } + else if ( !strcmp( token, "*MESH_NUMFACES" ) ) + { + ASE_GetToken( false ); + + pMesh->numFaces = atoi( ase.token ); + VERBOSE( ( ".....num faces: %d\n", pMesh->numFaces ) ); + } + else if ( !strcmp( token, "*MESH_NUMTVFACES" ) ) + { + ASE_GetToken( false ); + + pMesh->numTVFaces = atoi( ase.token ); + VERBOSE( ( ".....num tvfaces: %d\n", pMesh->numTVFaces ) ); + + if ( pMesh->numTVFaces != pMesh->numFaces ) + { + common->Error( "MESH_NUMTVFACES != MESH_NUMFACES" ); + } + } + else if ( !strcmp( token, "*MESH_NUMCVFACES" ) ) + { + ASE_GetToken( false ); + + pMesh->numCVFaces = atoi( ase.token ); + VERBOSE( ( ".....num cvfaces: %d\n", pMesh->numCVFaces ) ); + + if ( pMesh->numTVFaces != pMesh->numFaces ) + { + common->Error( "MESH_NUMCVFACES != MESH_NUMFACES" ); + } + } + else if ( !strcmp( token, "*MESH_VERTEX_LIST" ) ) + { + pMesh->vertexes = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numVertexes ); + ase.currentVertex = 0; + VERBOSE( ( ".....parsing MESH_VERTEX_LIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyMESH_VERTEX_LIST ); + } + else if ( !strcmp( token, "*MESH_TVERTLIST" ) ) + { + ase.currentVertex = 0; + pMesh->tvertexes = (idVec2 *)Mem_Alloc( sizeof( idVec2 ) * pMesh->numTVertexes ); + VERBOSE( ( ".....parsing MESH_TVERTLIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyMESH_TVERTLIST ); + } + else if ( !strcmp( token, "*MESH_CVERTLIST" ) ) + { + ase.currentVertex = 0; + pMesh->cvertexes = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numCVertexes ); + VERBOSE( ( ".....parsing MESH_CVERTLIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyMESH_CVERTLIST ); + } + else if ( !strcmp( token, "*MESH_FACE_LIST" ) ) + { + pMesh->faces = (aseFace_t *)Mem_Alloc( sizeof( aseFace_t ) * pMesh->numFaces ); + ase.currentFace = 0; + VERBOSE( ( ".....parsing MESH_FACE_LIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyMESH_FACE_LIST ); + } + else if ( !strcmp( token, "*MESH_TFACELIST" ) ) + { + if ( !pMesh->faces ) { + common->Error( "*MESH_TFACELIST before *MESH_FACE_LIST" ); + } + ase.currentFace = 0; + VERBOSE( ( ".....parsing MESH_TFACE_LIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyTFACE_LIST ); + } + else if ( !strcmp( token, "*MESH_CFACELIST" ) ) + { + if ( !pMesh->faces ) { + common->Error( "*MESH_CFACELIST before *MESH_FACE_LIST" ); + } + ase.currentFace = 0; + VERBOSE( ( ".....parsing MESH_CFACE_LIST\n" ) ); + ASE_ParseBracedBlock( ASE_KeyCFACE_LIST ); + } + else if ( !strcmp( token, "*MESH_NORMALS" ) ) + { + if ( !pMesh->faces ) { + common->Warning( "*MESH_NORMALS before *MESH_FACE_LIST" ); + } + ase.currentFace = 0; + VERBOSE( ( ".....parsing MESH_NORMALS\n" ) ); + ASE_ParseBracedBlock( ASE_KeyMESH_NORMALS ); + } +} + +static void ASE_KeyMESH_ANIMATION( const char *token ) +{ + aseMesh_t *mesh; + + // loads a single animation frame + if ( !strcmp( token, "*MESH" ) ) + { + VERBOSE( ( "...found MESH\n" ) ); + + mesh = (aseMesh_t *)Mem_Alloc( sizeof( aseMesh_t ) ); + memset( mesh, 0, sizeof( aseMesh_t ) ); + ase.currentMesh = mesh; + + ase.currentObject->frames.Append( mesh ); + + ASE_ParseBracedBlock( ASE_KeyMESH ); + } + else + { + common->Error( "Unknown token '%s' while parsing MESH_ANIMATION", token ); + } +} + +static void ASE_KeyGEOMOBJECT( const char *token ) +{ + aseObject_t *object; + + object = ase.currentObject; + + if ( !strcmp( token, "*NODE_NAME" ) ) + { + ASE_GetToken( true ); + VERBOSE( ( " %s\n", ase.token ) ); + idStr::Copynz( object->name, ase.token, sizeof( object->name ) ); + } + else if ( !strcmp( token, "*NODE_PARENT" ) ) + { + ASE_SkipRestOfLine(); + } + // ignore unused data blocks + else if ( !strcmp( token, "*NODE_TM" ) || + !strcmp( token, "*TM_ANIMATION" ) ) + { + ASE_ParseBracedBlock( ASE_KeyNODE_TM ); + } + // ignore regular meshes that aren't part of animation + else if ( !strcmp( token, "*MESH" ) ) + { + ase.currentMesh = &ase.currentObject->mesh; + memset( ase.currentMesh, 0, sizeof( ase.currentMesh ) ); + + ASE_ParseBracedBlock( ASE_KeyMESH ); + } + // according to spec these are obsolete + else if ( !strcmp( token, "*MATERIAL_REF" ) ) + { + ASE_GetToken( false ); + + object->materialRef = atoi( ase.token ); + } + // loads a sequence of animation frames + else if ( !strcmp( token, "*MESH_ANIMATION" ) ) + { + VERBOSE( ( "..found MESH_ANIMATION\n" ) ); + + ASE_ParseBracedBlock( ASE_KeyMESH_ANIMATION ); + } + // skip unused info + else if ( !strcmp( token, "*PROP_MOTIONBLUR" ) || + !strcmp( token, "*PROP_CASTSHADOW" ) || + !strcmp( token, "*PROP_RECVSHADOW" ) ) + { + ASE_SkipRestOfLine(); + } + +} + +void ASE_ParseGeomObject( void ) { + aseObject_t *object; + + VERBOSE( ("GEOMOBJECT" ) ); + + object = (aseObject_t *)Mem_Alloc( sizeof( aseObject_t ) ); + memset( object, 0, sizeof( aseObject_t ) ); + ase.model->objects.Append( object ); + ase.currentObject = object; + + object->frames.Resize(32, 32); + + ASE_ParseBracedBlock( ASE_KeyGEOMOBJECT ); +} + +static void ASE_KeyGROUP( const char *token ) +{ + if ( !strcmp( token, "*GEOMOBJECT" ) ) { + ASE_ParseGeomObject(); + } +} + +/* +================= +ASE_Parse +================= +*/ +aseModel_t *ASE_Parse( const char *buffer, bool verbose ) { + memset( &ase, 0, sizeof( ase ) ); + + ase.verbose = verbose; + + ase.buffer = buffer; + ase.len = strlen( buffer ); + ase.curpos = ase.buffer; + ase.currentObject = NULL; + + // NOTE: using new operator because aseModel_t contains idList class objects + ase.model = new aseModel_t; + memset( ase.model, 0, sizeof( aseModel_t ) ); + ase.model->objects.Resize( 32, 32 ); + ase.model->materials.Resize( 32, 32 ); + + while ( ASE_GetToken( false ) ) { + if ( !strcmp( ase.token, "*3DSMAX_ASCIIEXPORT" ) || + !strcmp( ase.token, "*COMMENT" ) ) { + ASE_SkipRestOfLine(); + } else if ( !strcmp( ase.token, "*SCENE" ) ) { + ASE_SkipEnclosingBraces(); + } else if ( !strcmp( ase.token, "*GROUP" ) ) { + ASE_GetToken( false ); // group name + ASE_ParseBracedBlock( ASE_KeyGROUP ); + } else if ( !strcmp( ase.token, "*SHAPEOBJECT" ) ) { + ASE_SkipEnclosingBraces(); + } else if ( !strcmp( ase.token, "*CAMERAOBJECT" ) ) { + ASE_SkipEnclosingBraces(); + } else if ( !strcmp( ase.token, "*MATERIAL_LIST" ) ) { + VERBOSE( ("MATERIAL_LIST\n") ); + + ASE_ParseBracedBlock( ASE_KeyMATERIAL_LIST ); + } else if ( !strcmp( ase.token, "*GEOMOBJECT" ) ) { + ASE_ParseGeomObject(); + } else if ( ase.token[0] ) { + common->Printf( "Unknown token '%s'\n", ase.token ); + } + } + + return ase.model; +} + +/* +================= +ASE_Load +================= +*/ +aseModel_t *ASE_Load( const char *fileName ) { + char *buf; + ID_TIME_T timeStamp; + aseModel_t *ase; + + fileSystem->ReadFile( fileName, (void **)&buf, &timeStamp ); + if ( !buf ) { + return NULL; + } + + ase = ASE_Parse( buf, false ); + ase->timeStamp = timeStamp; + + fileSystem->FreeFile( buf ); + + return ase; +} + +/* +================= +ASE_Free +================= +*/ +void ASE_Free( aseModel_t *ase ) { + int i, j; + aseObject_t *obj; + aseMesh_t *mesh; + aseMaterial_t *material; + + if ( !ase ) { + return; + } + for ( i = 0; i < ase->objects.Num(); i++ ) { + obj = ase->objects[i]; + for ( j = 0; j < obj->frames.Num(); j++ ) { + mesh = obj->frames[j]; + if ( mesh->vertexes ) { + Mem_Free( mesh->vertexes ); + } + if ( mesh->tvertexes ) { + Mem_Free( mesh->tvertexes ); + } + if ( mesh->cvertexes ) { + Mem_Free( mesh->cvertexes ); + } + if ( mesh->faces ) { + Mem_Free( mesh->faces ); + } + Mem_Free( mesh ); + } + + obj->frames.Clear(); + + // free the base nesh + mesh = &obj->mesh; + if ( mesh->vertexes ) { + Mem_Free( mesh->vertexes ); + } + if ( mesh->tvertexes ) { + Mem_Free( mesh->tvertexes ); + } + if ( mesh->cvertexes ) { + Mem_Free( mesh->cvertexes ); + } + if ( mesh->faces ) { + Mem_Free( mesh->faces ); + } + Mem_Free( obj ); + } + ase->objects.Clear(); + + for ( i = 0; i < ase->materials.Num(); i++ ) { + material = ase->materials[i]; + Mem_Free( material ); + } + ase->materials.Clear(); + + delete ase; +} diff --git a/renderer/Model_ase.h b/renderer/Model_ase.h new file mode 100644 index 000000000..f4cefc237 --- /dev/null +++ b/renderer/Model_ase.h @@ -0,0 +1,86 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODEL_ASE_H__ +#define __MODEL_ASE_H__ + +/* +=============================================================================== + + ASE loader. (3D Studio Max ASCII Export) + +=============================================================================== +*/ + +typedef struct { + int vertexNum[3]; + int tVertexNum[3]; + idVec3 faceNormal; + idVec3 vertexNormals[3]; + byte vertexColors[3][4]; +} aseFace_t; + +typedef struct { + int timeValue; + + int numVertexes; + int numTVertexes; + int numCVertexes; + int numFaces; + int numTVFaces; + int numCVFaces; + + idVec3 transform[4]; // applied to normals + + bool colorsParsed; + bool normalsParsed; + idVec3 * vertexes; + idVec2 * tvertexes; + idVec3 * cvertexes; + aseFace_t * faces; +} aseMesh_t; + +typedef struct { + char name[128]; + float uOffset, vOffset; // max lets you offset by material without changing texCoords + float uTiling, vTiling; // multiply tex coords by this + float angle; // in clockwise radians +} aseMaterial_t; + +typedef struct { + char name[128]; + int materialRef; + + aseMesh_t mesh; + + // frames are only present with animations + idList frames; // aseMesh_t +} aseObject_t; + +typedef struct aseModel_s { + ID_TIME_T timeStamp; + idList materials; + idList objects; +} aseModel_t; + + +aseModel_t *ASE_Load( const char *fileName ); +void ASE_Free( aseModel_t *ase ); + +#endif /* !__MODEL_ASE_H__ */ diff --git a/renderer/Model_beam.cpp b/renderer/Model_beam.cpp new file mode 100644 index 000000000..43e5423aa --- /dev/null +++ b/renderer/Model_beam.cpp @@ -0,0 +1,204 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + +/* + +This is a simple dynamic model that just creates a stretched quad between +two points that faces the view, like a dynamic deform tube. + +*/ + +static const char *beam_SnapshotName = "_beam_Snapshot_"; + +/* +=============== +idRenderModelBeam::IsDynamicModel +=============== +*/ +dynamicModel_t idRenderModelBeam::IsDynamicModel() const { + return DM_CONTINUOUS; // regenerate for every view +} + +/* +=============== +idRenderModelBeam::IsLoaded +=============== +*/ +bool idRenderModelBeam::IsLoaded() const { + return true; // don't ever need to load +} + +/* +=============== +idRenderModelBeam::InstantiateDynamicModel +=============== +*/ +idRenderModel *idRenderModelBeam::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) { + idRenderModelStatic *staticModel; + srfTriangles_t *tri; + modelSurface_t surf; + + if ( cachedModel ) { + delete cachedModel; + cachedModel = NULL; + } + + if ( renderEntity == NULL || viewDef == NULL ) { + delete cachedModel; + return NULL; + } + + if ( cachedModel != NULL ) { + + assert( dynamic_cast( cachedModel ) != NULL ); + assert( idStr::Icmp( cachedModel->Name(), beam_SnapshotName ) == 0 ); + + staticModel = static_cast( cachedModel ); + surf = *staticModel->Surface( 0 ); + tri = surf.geometry; + + } else { + + staticModel = new idRenderModelStatic; + staticModel->InitEmpty( beam_SnapshotName ); + + tri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( tri, 4 ); + R_AllocStaticTriSurfIndexes( tri, 6 ); + + tri->verts[0].Clear(); + tri->verts[0].st[0] = 0; + tri->verts[0].st[1] = 0; + + tri->verts[1].Clear(); + tri->verts[1].st[0] = 0; + tri->verts[1].st[1] = 1; + + tri->verts[2].Clear(); + tri->verts[2].st[0] = 1; + tri->verts[2].st[1] = 0; + + tri->verts[3].Clear(); + tri->verts[3].st[0] = 1; + tri->verts[3].st[1] = 1; + + tri->indexes[0] = 0; + tri->indexes[1] = 2; + tri->indexes[2] = 1; + tri->indexes[3] = 2; + tri->indexes[4] = 3; + tri->indexes[5] = 1; + + tri->numVerts = 4; + tri->numIndexes = 6; + + surf.geometry = tri; + surf.id = 0; + surf.shader = tr.defaultMaterial; + staticModel->AddSurface( surf ); + } + + idVec3 target = *reinterpret_cast( &renderEntity->shaderParms[SHADERPARM_BEAM_END_X] ); + + // we need the view direction to project the minor axis of the tube + // as the view changes + idVec3 localView, localTarget; + float modelMatrix[16]; + R_AxisToModelMatrix( renderEntity->axis, renderEntity->origin, modelMatrix ); + R_GlobalPointToLocal( modelMatrix, viewDef->renderView.vieworg, localView ); + R_GlobalPointToLocal( modelMatrix, target, localTarget ); + + idVec3 major = localTarget; + idVec3 minor; + + idVec3 mid = 0.5f * localTarget; + idVec3 dir = mid - localView; + minor.Cross( major, dir ); + minor.Normalize(); + if ( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] != 0.0f ) { + minor *= renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] * 0.5f; + } + + int red = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_RED] * 255.0f ); + int green = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_GREEN] * 255.0f ); + int blue = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_BLUE] * 255.0f ); + int alpha = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_ALPHA] * 255.0f ); + + tri->verts[0].xyz = minor; + tri->verts[0].color[0] = red; + tri->verts[0].color[1] = green; + tri->verts[0].color[2] = blue; + tri->verts[0].color[3] = alpha; + + tri->verts[1].xyz = -minor; + tri->verts[1].color[0] = red; + tri->verts[1].color[1] = green; + tri->verts[1].color[2] = blue; + tri->verts[1].color[3] = alpha; + + tri->verts[2].xyz = localTarget + minor; + tri->verts[2].color[0] = red; + tri->verts[2].color[1] = green; + tri->verts[2].color[2] = blue; + tri->verts[2].color[3] = alpha; + + tri->verts[3].xyz = localTarget - minor; + tri->verts[3].color[0] = red; + tri->verts[3].color[1] = green; + tri->verts[3].color[2] = blue; + tri->verts[3].color[3] = alpha; + + R_BoundTriSurf( tri ); + + staticModel->bounds = tri->bounds; + + return staticModel; +} + +/* +=============== +idRenderModelBeam::Bounds +=============== +*/ +idBounds idRenderModelBeam::Bounds( const struct renderEntity_s *renderEntity ) const { + idBounds b; + + b.Zero(); + if ( !renderEntity ) { + b.ExpandSelf( 8.0f ); + } else { + idVec3 target = *reinterpret_cast( &renderEntity->shaderParms[SHADERPARM_BEAM_END_X] ); + idVec3 localTarget; + float modelMatrix[16]; + R_AxisToModelMatrix( renderEntity->axis, renderEntity->origin, modelMatrix ); + R_GlobalPointToLocal( modelMatrix, target, localTarget ); + + b.AddPoint( localTarget ); + if ( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] != 0.0f ) { + b.ExpandSelf( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] * 0.5f ); + } + } + return b; +} diff --git a/renderer/Model_liquid.cpp b/renderer/Model_liquid.cpp new file mode 100644 index 000000000..e3444f66f --- /dev/null +++ b/renderer/Model_liquid.cpp @@ -0,0 +1,523 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + +#define LIQUID_MAX_SKIP_FRAMES 5 +#define LIQUID_MAX_TYPES 3 + +/* +==================== +idRenderModelLiquid::idRenderModelLiquid +==================== +*/ +idRenderModelLiquid::idRenderModelLiquid() { + verts_x = 32; + verts_y = 32; + scale_x = 256.0f; + scale_y = 256.0f; + liquid_type = 0; + density = 0.97f; + drop_height = 4; + drop_radius = 4; + drop_delay = 1000; + shader = declManager->FindMaterial( NULL ); + update_tics = 33; // ~30 hz + time = 0; + seed = 0; + + random.SetSeed( 0 ); +} + +/* +==================== +idRenderModelLiquid::GenerateSurface +==================== +*/ +modelSurface_t idRenderModelLiquid::GenerateSurface( float lerp ) { + srfTriangles_t *tri; + int i, base; + idDrawVert *vert; + modelSurface_t surf; + float inv_lerp; + + inv_lerp = 1.0f - lerp; + vert = verts.Ptr(); + for( i = 0; i < verts.Num(); i++, vert++ ) { + vert->xyz.z = page1[ i ] * lerp + page2[ i ] * inv_lerp; + } + + tr.pc.c_deformedSurfaces++; + tr.pc.c_deformedVerts += deformInfo->numOutputVerts; + tr.pc.c_deformedIndexes += deformInfo->numIndexes; + + tri = R_AllocStaticTriSurf(); + + // note that some of the data is references, and should not be freed + tri->deformedSurface = true; + + tri->numIndexes = deformInfo->numIndexes; + tri->indexes = deformInfo->indexes; + tri->silIndexes = deformInfo->silIndexes; + tri->numMirroredVerts = deformInfo->numMirroredVerts; + tri->mirroredVerts = deformInfo->mirroredVerts; + tri->numDupVerts = deformInfo->numDupVerts; + tri->dupVerts = deformInfo->dupVerts; + tri->numSilEdges = deformInfo->numSilEdges; + tri->silEdges = deformInfo->silEdges; + tri->dominantTris = deformInfo->dominantTris; + + tri->numVerts = deformInfo->numOutputVerts; + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + SIMDProcessor->Memcpy( tri->verts, verts.Ptr(), deformInfo->numSourceVerts * sizeof(tri->verts[0]) ); + + // replicate the mirror seam vertexes + base = deformInfo->numOutputVerts - deformInfo->numMirroredVerts; + for ( i = 0 ; i < deformInfo->numMirroredVerts ; i++ ) { + tri->verts[base + i] = tri->verts[deformInfo->mirroredVerts[i]]; + } + + R_BoundTriSurf( tri ); + + // If a surface is going to be have a lighting interaction generated, it will also have to call + // R_DeriveTangents() to get normals, tangents, and face planes. If it only + // needs shadows generated, it will only have to generate face planes. If it only + // has ambient drawing, or is culled, no additional work will be necessary + if ( !r_useDeferredTangents.GetBool() ) { + // set face planes, vertex normals, tangents + R_DeriveTangents( tri ); + } + + surf.geometry = tri; + surf.shader = shader; + + return surf; +} + +/* +==================== +idRenderModelLiquid::WaterDrop +==================== +*/ +void idRenderModelLiquid::WaterDrop( int x, int y, float *page ) { + int cx, cy; + int left,top,right,bottom; + int square; + int radsquare = drop_radius * drop_radius; + float invlength = 1.0f / ( float )radsquare; + float dist; + + if ( x < 0 ) { + x = 1 + drop_radius + random.RandomInt( verts_x - 2 * drop_radius - 1 ); + } + if ( y < 0 ) { + y = 1 + drop_radius + random.RandomInt( verts_y - 2 * drop_radius - 1 ); + } + + left=-drop_radius; right = drop_radius; + top=-drop_radius; bottom = drop_radius; + + // Perform edge clipping... + if ( x - drop_radius < 1 ) { + left -= (x-drop_radius-1); + } + if ( y - drop_radius < 1 ) { + top -= (y-drop_radius-1); + } + if ( x + drop_radius > verts_x - 1 ) { + right -= (x+drop_radius-verts_x+1); + } + if ( y + drop_radius > verts_y - 1 ) { + bottom-= (y+drop_radius-verts_y+1); + } + + for ( cy = top; cy < bottom; cy++ ) { + for ( cx = left; cx < right; cx++ ) { + square = cy*cy + cx*cx; + if ( square < radsquare ) { + dist = idMath::Sqrt( (float)square * invlength ); + page[verts_x*(cy+y) + cx+x] += idMath::Cos16( dist * idMath::PI * 0.5f ) * drop_height; + } + } + } +} + +/* +==================== +idRenderModelLiquid::IntersectBounds +==================== +*/ +void idRenderModelLiquid::IntersectBounds( const idBounds &bounds, float displacement ) { + int cx, cy; + int left,top,right,bottom; + float up, down; + float *pos; + + left = ( int )( bounds[ 0 ].x / scale_x ); + right = ( int )( bounds[ 1 ].x / scale_x ); + top = ( int )( bounds[ 0 ].y / scale_y ); + bottom = ( int )( bounds[ 1 ].y / scale_y ); + down = bounds[ 0 ].z; + up = bounds[ 1 ].z; + + if ( ( right < 1 ) || ( left >= verts_x ) || ( bottom < 1 ) || ( top >= verts_x ) ) { + return; + } + + // Perform edge clipping... + if ( left < 1 ) { + left = 1; + } + if ( right >= verts_x ) { + right = verts_x - 1; + } + if ( top < 1 ) { + top = 1; + } + if ( bottom >= verts_y ) { + bottom = verts_y - 1; + } + + for ( cy = top; cy < bottom; cy++ ) { + for ( cx = left; cx < right; cx++ ) { + pos = &page1[ verts_x * cy + cx ]; + if ( *pos > down ) {//&& ( *pos < up ) ) { + *pos = down; + } + } + } +} + +/* +==================== +idRenderModelLiquid::Update +==================== +*/ +void idRenderModelLiquid::Update( void ) { + int x, y; + float *p2; + float *p1; + float value; + + time += update_tics; + + idSwap( page1, page2 ); + + if ( time > nextDropTime ) { + WaterDrop( -1, -1, page2 ); + nextDropTime = time + drop_delay; + } else if ( time < nextDropTime - drop_delay ) { + nextDropTime = time + drop_delay; + } + + p1 = page1; + p2 = page2; + + switch( liquid_type ) { + case 0 : + for ( y = 1; y < verts_y - 1; y++ ) { + p2 += verts_x; + p1 += verts_x; + for ( x = 1; x < verts_x - 1; x++ ) { + value = + ( p2[ x + verts_x ] + + p2[ x - verts_x ] + + p2[ x + 1 ] + + p2[ x - 1 ] + + p2[ x - verts_x - 1 ] + + p2[ x - verts_x + 1 ] + + p2[ x + verts_x - 1 ] + + p2[ x + verts_x + 1 ] + + p2[ x ] ) * ( 2.0f / 9.0f ) - + p1[ x ]; + + p1[ x ] = value * density; + } + } + break; + + case 1 : + for ( y = 1; y < verts_y - 1; y++ ) { + p2 += verts_x; + p1 += verts_x; + for ( x = 1; x < verts_x - 1; x++ ) { + value = + ( p2[ x + verts_x ] + + p2[ x - verts_x ] + + p2[ x + 1 ] + + p2[ x - 1 ] + + p2[ x - verts_x - 1 ] + + p2[ x - verts_x + 1 ] + + p2[ x + verts_x - 1 ] + + p2[ x + verts_x + 1 ] ) * 0.25f - + p1[ x ]; + + p1[ x ] = value * density; + } + } + break; + + case 2 : + for ( y = 1; y < verts_y - 1; y++ ) { + p2 += verts_x; + p1 += verts_x; + for ( x = 1; x < verts_x - 1; x++ ) { + value = + ( p2[ x + verts_x ] + + p2[ x - verts_x ] + + p2[ x + 1 ] + + p2[ x - 1 ] + + p2[ x - verts_x - 1 ] + + p2[ x - verts_x + 1 ] + + p2[ x + verts_x - 1 ] + + p2[ x + verts_x + 1 ] + + p2[ x ] ) * ( 1.0f / 9.0f ); + + p1[ x ] = value * density; + } + } + break; + } +} + +/* +==================== +idRenderModelLiquid::Reset +==================== +*/ +void idRenderModelLiquid::Reset() { + int i, x, y; + + if ( pages.Num() < 2 * verts_x * verts_y ) { + return; + } + + nextDropTime = 0; + time = 0; + random.SetSeed( seed ); + + page1 = pages.Ptr(); + page2 = page1 + verts_x * verts_y; + + for ( i = 0, y = 0; y < verts_y; y++ ) { + for ( x = 0; x < verts_x; x++, i++ ) { + page1[ i ] = 0.0f; + page2[ i ] = 0.0f; + verts[ i ].xyz.z = 0.0f; + } + } +} + +/* +==================== +idRenderModelLiquid::InitFromFile +==================== +*/ +void idRenderModelLiquid::InitFromFile( const char *fileName ) { + int i, x, y; + idToken token; + idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); + idList tris; + float size_x, size_y; + float rate; + + name = fileName; + + if ( !parser.LoadFile( fileName ) ) { + MakeDefaultModel(); + return; + } + + size_x = scale_x * verts_x; + size_y = scale_y * verts_y; + + while( parser.ReadToken( &token ) ) { + if ( !token.Icmp( "seed" ) ) { + seed = parser.ParseInt(); + } else if ( !token.Icmp( "size_x" ) ) { + size_x = parser.ParseFloat(); + } else if ( !token.Icmp( "size_y" ) ) { + size_y = parser.ParseFloat(); + } else if ( !token.Icmp( "verts_x" ) ) { + verts_x = parser.ParseFloat(); + if ( verts_x < 2 ) { + parser.Warning( "Invalid # of verts. Using default model." ); + MakeDefaultModel(); + return; + } + } else if ( !token.Icmp( "verts_y" ) ) { + verts_y = parser.ParseFloat(); + if ( verts_y < 2 ) { + parser.Warning( "Invalid # of verts. Using default model." ); + MakeDefaultModel(); + return; + } + } else if ( !token.Icmp( "liquid_type" ) ) { + liquid_type = parser.ParseInt() - 1; + if ( ( liquid_type < 0 ) || ( liquid_type >= LIQUID_MAX_TYPES ) ) { + parser.Warning( "Invalid liquid_type. Using default model." ); + MakeDefaultModel(); + return; + } + } else if ( !token.Icmp( "density" ) ) { + density = parser.ParseFloat(); + } else if ( !token.Icmp( "drop_height" ) ) { + drop_height = parser.ParseFloat(); + } else if ( !token.Icmp( "drop_radius" ) ) { + drop_radius = parser.ParseInt(); + } else if ( !token.Icmp( "drop_delay" ) ) { + drop_delay = SEC2MS( parser.ParseFloat() ); + } else if ( !token.Icmp( "shader" ) ) { + parser.ReadToken( &token ); + shader = declManager->FindMaterial( token ); + } else if ( !token.Icmp( "seed" ) ) { + seed = parser.ParseInt(); + } else if ( !token.Icmp( "update_rate" ) ) { + rate = parser.ParseFloat(); + if ( ( rate <= 0.0f ) || ( rate > 60.0f ) ) { + parser.Warning( "Invalid update_rate. Must be between 0 and 60. Using default model." ); + MakeDefaultModel(); + return; + } + update_tics = 1000 / rate; + } else { + parser.Warning( "Unknown parameter '%s'. Using default model.", token.c_str() ); + MakeDefaultModel(); + return; + } + } + + scale_x = size_x / ( verts_x - 1 ); + scale_y = size_y / ( verts_y - 1 ); + + pages.SetNum( 2 * verts_x * verts_y ); + page1 = pages.Ptr(); + page2 = page1 + verts_x * verts_y; + + verts.SetNum( verts_x * verts_y ); + for ( i = 0, y = 0; y < verts_y; y++ ) { + for ( x = 0; x < verts_x; x++, i++ ) { + page1[ i ] = 0.0f; + page2[ i ] = 0.0f; + verts[ i ].Clear(); + verts[ i ].xyz.Set( x * scale_x, y * scale_y, 0.0f ); + verts[ i ].st.Set( (float) x / (float)( verts_x - 1 ), (float) -y / (float)( verts_y - 1 ) ); + } + } + + tris.SetNum( ( verts_x - 1 ) * ( verts_y - 1 ) * 6 ); + for( i = 0, y = 0; y < verts_y - 1; y++ ) { + for( x = 1; x < verts_x; x++, i += 6 ) { + tris[ i + 0 ] = y * verts_x + x; + tris[ i + 1 ] = y * verts_x + x - 1; + tris[ i + 2 ] = ( y + 1 ) * verts_x + x - 1; + + tris[ i + 3 ] = ( y + 1 ) * verts_x + x - 1; + tris[ i + 4 ] = ( y + 1 ) * verts_x + x; + tris[ i + 5 ] = y * verts_x + x; + } + } + + // build the information that will be common to all animations of this mesh: + // sil edge connectivity and normal / tangent generation information + deformInfo = R_BuildDeformInfo( verts.Num(), verts.Ptr(), tris.Num(), tris.Ptr(), true ); + + bounds.Clear(); + bounds.AddPoint( idVec3( 0.0f, 0.0f, drop_height * -10.0f ) ); + bounds.AddPoint( idVec3( ( verts_x - 1 ) * scale_x, ( verts_y - 1 ) * scale_y, drop_height * 10.0f ) ); + + // set the timestamp for reloadmodels + fileSystem->ReadFile( name, NULL, &timeStamp ); + + Reset(); +} + +/* +==================== +idRenderModelLiquid::InstantiateDynamicModel +==================== +*/ +idRenderModel *idRenderModelLiquid::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) { + idRenderModelStatic *staticModel; + int frames; + int t; + float lerp; + + if ( cachedModel ) { + delete cachedModel; + cachedModel = NULL; + } + + if ( !deformInfo ) { + return NULL; + } + + if ( !view ) { + t = 0; + } else { + t = view->renderView.time; + } + + // update the liquid model + frames = ( t - time ) / update_tics; + if ( frames > LIQUID_MAX_SKIP_FRAMES ) { + // don't let time accumalate when skipping frames + time += update_tics * ( frames - LIQUID_MAX_SKIP_FRAMES ); + + frames = LIQUID_MAX_SKIP_FRAMES; + } + + while( frames > 0 ) { + Update(); + frames--; + } + + // create the surface + lerp = ( float )( t - time ) / ( float )update_tics; + modelSurface_t surf = GenerateSurface( lerp ); + + staticModel = new idRenderModelStatic; + staticModel->AddSurface( surf ); + staticModel->bounds = surf.geometry->bounds; + + return staticModel; +} + +/* +==================== +idRenderModelLiquid::IsDynamicModel +==================== +*/ +dynamicModel_t idRenderModelLiquid::IsDynamicModel() const { + return DM_CONTINUOUS; +} + +/* +==================== +idRenderModelLiquid::Bounds +==================== +*/ +idBounds idRenderModelLiquid::Bounds(const struct renderEntity_s *ent) const { + // FIXME: need to do this better + return bounds; +} diff --git a/renderer/Model_local.h b/renderer/Model_local.h new file mode 100644 index 000000000..8f16fe79f --- /dev/null +++ b/renderer/Model_local.h @@ -0,0 +1,376 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODEL_LOCAL_H__ +#define __MODEL_LOCAL_H__ + +/* +=============================================================================== + + Static model + +=============================================================================== +*/ + +class idRenderModelStatic : public idRenderModel { +public: + // the inherited public interface + static idRenderModel * Alloc(); + + idRenderModelStatic(); + virtual ~idRenderModelStatic(); + + virtual void InitFromFile( const char *fileName ); + virtual void PartialInitFromFile( const char *fileName ); + virtual void PurgeModel(); + virtual void Reset() {}; + virtual void LoadModel(); + virtual bool IsLoaded(); + virtual void SetLevelLoadReferenced( bool referenced ); + virtual bool IsLevelLoadReferenced(); + virtual void TouchData(); + virtual void InitEmpty( const char *name ); + virtual void AddSurface( modelSurface_t surface ); + virtual void FinishSurfaces(); + virtual void FreeVertexCache(); + virtual const char * Name() const; + virtual void Print() const; + virtual void List() const; + virtual int Memory() const; + virtual ID_TIME_T Timestamp() const; + virtual int NumSurfaces() const; + virtual int NumBaseSurfaces() const; + virtual const modelSurface_t *Surface( int surfaceNum ) const; + virtual srfTriangles_t * AllocSurfaceTriangles( int numVerts, int numIndexes ) const; + virtual void FreeSurfaceTriangles( srfTriangles_t *tris ) const; + virtual srfTriangles_t * ShadowHull() const; + virtual bool IsStaticWorldModel() const; + virtual dynamicModel_t IsDynamicModel() const; + virtual bool IsDefaultModel() const; + virtual bool IsReloadable() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual int NumJoints( void ) const; + virtual const idMD5Joint * GetJoints( void ) const; + virtual jointHandle_t GetJointHandle( const char *name ) const; + virtual const char * GetJointName( jointHandle_t handle ) const; + virtual const idJointQuat * GetDefaultPose( void ) const; + virtual int NearestJoint( int surfaceNum, int a, int b, int c ) const; + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + virtual void ReadFromDemoFile( class idDemoFile *f ); + virtual void WriteToDemoFile( class idDemoFile *f ); + virtual float DepthHack() const; + + void MakeDefaultModel(); + + bool LoadASE( const char *fileName ); + bool LoadLWO( const char *fileName ); + bool LoadFLT( const char *fileName ); + bool LoadMA( const char *filename ); + + bool ConvertASEToModelSurfaces( const struct aseModel_s *ase ); + bool ConvertLWOToModelSurfaces( const struct st_lwObject *lwo ); + bool ConvertMAToModelSurfaces (const struct maModel_s *ma ); + + struct aseModel_s * ConvertLWOToASE( const struct st_lwObject *obj, const char *fileName ); + + bool DeleteSurfaceWithId( int id ); + void DeleteSurfacesWithNegativeId( void ); + bool FindSurfaceWithId( int id, int &surfaceNum ); + +public: + idList surfaces; + idBounds bounds; + int overlaysAdded; + +protected: + int lastModifiedFrame; + int lastArchivedFrame; + + idStr name; + srfTriangles_t * shadowHull; + bool isStaticWorldModel; + bool defaulted; + bool purged; // eventually we will have dynamic reloading + bool fastLoad; // don't generate tangents and shadow data + bool reloadable; // if not, reloadModels won't check timestamp + bool levelLoadReferenced; // for determining if it needs to be freed + ID_TIME_T timeStamp; + + static idCVar r_mergeModelSurfaces; // combine model surfaces with the same material + static idCVar r_slopVertex; // merge xyz coordinates this far apart + static idCVar r_slopTexCoord; // merge texture coordinates this far apart + static idCVar r_slopNormal; // merge normals that dot less than this +}; + +/* +=============================================================================== + + MD5 animated model + +=============================================================================== +*/ + +class idMD5Mesh { + friend class idRenderModelMD5; + +public: + idMD5Mesh(); + ~idMD5Mesh(); + + void ParseMesh( idLexer &parser, int numJoints, const idJointMat *joints ); + void UpdateSurface( const struct renderEntity_s *ent, const idJointMat *joints, modelSurface_t *surf ); + idBounds CalcBounds( const idJointMat *joints ); + int NearestJoint( int a, int b, int c ) const; + int NumVerts( void ) const; + int NumTris( void ) const; + int NumWeights( void ) const; + +private: + idList texCoords; // texture coordinates + int numWeights; // number of weights + idVec4 * scaledWeights; // joint weights + int * weightIndex; // pairs of: joint offset + bool true if next weight is for next vertex + const idMaterial * shader; // material applied to mesh + int numTris; // number of triangles + struct deformInfo_s * deformInfo; // used to create srfTriangles_t from base frames and new vertexes + int surfaceNum; // number of the static surface created for this mesh + + void TransformVerts( idDrawVert *verts, const idJointMat *joints ); + void TransformScaledVerts( idDrawVert *verts, const idJointMat *joints, float scale ); +}; + +class idRenderModelMD5 : public idRenderModelStatic { +public: + virtual void InitFromFile( const char *fileName ); + virtual dynamicModel_t IsDynamicModel() const; + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + virtual void Print() const; + virtual void List() const; + virtual void TouchData(); + virtual void PurgeModel(); + virtual void LoadModel(); + virtual int Memory() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual int NumJoints( void ) const; + virtual const idMD5Joint * GetJoints( void ) const; + virtual jointHandle_t GetJointHandle( const char *name ) const; + virtual const char * GetJointName( jointHandle_t handle ) const; + virtual const idJointQuat * GetDefaultPose( void ) const; + virtual int NearestJoint( int surfaceNum, int a, int b, int c ) const; + +private: + idList joints; + idList defaultPose; + idList meshes; + + void CalculateBounds( const idJointMat *joints ); + void GetFrameBounds( const renderEntity_t *ent, idBounds &bounds ) const; + void DrawJoints( const renderEntity_t *ent, const struct viewDef_s *view ) const; + void ParseJoint( idLexer &parser, idMD5Joint *joint, idJointQuat *defaultPose ); +}; + +/* +=============================================================================== + + MD3 animated model + +=============================================================================== +*/ + +struct md3Header_s; +struct md3Surface_s; + +class idRenderModelMD3 : public idRenderModelStatic { +public: + virtual void InitFromFile( const char *fileName ); + virtual dynamicModel_t IsDynamicModel() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + +private: + int index; // model = tr.models[model->index] + int dataSize; // just for listing purposes + struct md3Header_s * md3; // only if type == MOD_MESH + int numLods; + + void LerpMeshVertexes( srfTriangles_t *tri, const struct md3Surface_s *surf, const float backlerp, const int frame, const int oldframe ) const; +}; + +/* +=============================================================================== + + Liquid model + +=============================================================================== +*/ + +class idRenderModelLiquid : public idRenderModelStatic { +public: + idRenderModelLiquid(); + + virtual void InitFromFile( const char *fileName ); + virtual dynamicModel_t IsDynamicModel() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + + virtual void Reset(); + void IntersectBounds( const idBounds &bounds, float displacement ); + +private: + modelSurface_t GenerateSurface( float lerp ); + void WaterDrop( int x, int y, float *page ); + void Update( void ); + + int verts_x; + int verts_y; + float scale_x; + float scale_y; + int time; + int liquid_type; + int update_tics; + int seed; + + idRandom random; + + const idMaterial * shader; + struct deformInfo_s * deformInfo; // used to create srfTriangles_t from base frames + // and new vertexes + + float density; + float drop_height; + int drop_radius; + float drop_delay; + + idList pages; + float * page1; + float * page2; + + idList verts; + + int nextDropTime; + +}; + +/* +=============================================================================== + + PRT model + +=============================================================================== +*/ + +class idRenderModelPrt : public idRenderModelStatic { +public: + idRenderModelPrt(); + + virtual void InitFromFile( const char *fileName ); + virtual void TouchData(); + virtual dynamicModel_t IsDynamicModel() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + virtual float DepthHack() const; + virtual int Memory() const; + +private: + const idDeclParticle * particleSystem; +}; + +/* +=============================================================================== + + Beam model + +=============================================================================== +*/ + +class idRenderModelBeam : public idRenderModelStatic { +public: + virtual dynamicModel_t IsDynamicModel() const; + virtual bool IsLoaded() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; +}; + +/* +=============================================================================== + + Beam model + +=============================================================================== +*/ +#define MAX_TRAIL_PTS 20 + +struct Trail_t { + int lastUpdateTime; + int duration; + + idVec3 pts[MAX_TRAIL_PTS]; + int numPoints; +}; + +class idRenderModelTrail : public idRenderModelStatic { + idList trails; + int numActive; + idBounds trailBounds; + +public: + idRenderModelTrail(); + + virtual dynamicModel_t IsDynamicModel() const; + virtual bool IsLoaded() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; + + int NewTrail( idVec3 pt, int duration ); + void UpdateTrail( int index, idVec3 pt ); + void DrawTrail( int index, const struct renderEntity_s *ent, srfTriangles_t *tri, float globalAlpha ); +}; + +/* +=============================================================================== + + Lightning model + +=============================================================================== +*/ + +class idRenderModelLightning : public idRenderModelStatic { +public: + virtual dynamicModel_t IsDynamicModel() const; + virtual bool IsLoaded() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; +}; + +/* +================================================================================ + + idRenderModelSprite + +================================================================================ +*/ +class idRenderModelSprite : public idRenderModelStatic { +public: + virtual dynamicModel_t IsDynamicModel() const; + virtual bool IsLoaded() const; + virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ); + virtual idBounds Bounds( const struct renderEntity_s *ent ) const; +}; + +#endif /* !__MODEL_LOCAL_H__ */ diff --git a/renderer/Model_lwo.cpp b/renderer/Model_lwo.cpp new file mode 100644 index 000000000..803e65f16 --- /dev/null +++ b/renderer/Model_lwo.cpp @@ -0,0 +1,4129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Model_lwo.h" + +/* +====================================================================== + + Converted from lwobject sample prog from LW 6.5 SDK. + +====================================================================== +*/ + +/* +====================================================================== +lwFreeClip() + +Free memory used by an lwClip. +====================================================================== */ + +void lwFreeClip( lwClip *clip ) +{ + if ( clip ) { + lwListFree( clip->ifilter, (void (__cdecl *)(void *))lwFreePlugin ); + lwListFree( clip->pfilter, (void (__cdecl *)(void *))lwFreePlugin ); + switch( clip->type ) { + case ID_STIL: { + if ( clip->source.still.name ) Mem_Free( clip->source.still.name ); + break; + } + case ID_ISEQ: { + if ( clip->source.seq.suffix ) Mem_Free( clip->source.seq.suffix ); + if ( clip->source.seq.prefix ) Mem_Free( clip->source.seq.prefix ); + break; + } + case ID_ANIM: { + if ( clip->source.anim.server ) Mem_Free( clip->source.anim.server ); + if ( clip->source.anim.name ) Mem_Free( clip->source.anim.name ); + break; + } + case ID_XREF: { + if ( clip->source.xref.string ) Mem_Free( clip->source.xref.string ); + break; + } + case ID_STCC: { + if ( clip->source.cycle.name ) Mem_Free( clip->source.cycle.name ); + break; + } + } + Mem_Free( clip ); + } +} + + +/* +====================================================================== +lwGetClip() + +Read image references from a CLIP chunk in an LWO2 file. +====================================================================== */ + +lwClip *lwGetClip( idFile *fp, int cksize ) +{ + lwClip *clip; + lwPlugin *filt; + unsigned int id; + unsigned short sz; + int pos, rlen; + + + /* allocate the Clip structure */ + + clip = (lwClip*)Mem_ClearedAlloc( sizeof( lwClip ) ); + if ( !clip ) goto Fail; + + clip->contrast.val = 1.0f; + clip->brightness.val = 1.0f; + clip->saturation.val = 1.0f; + clip->gamma.val = 1.0f; + + /* remember where we started */ + + set_flen( 0 ); + pos = fp->Tell(); + + /* index */ + + clip->index = getI4( fp ); + + /* first subchunk header */ + + clip->type = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + sz += sz & 1; + set_flen( 0 ); + + switch ( clip->type ) { + case ID_STIL: + clip->source.still.name = getS0( fp ); + break; + + case ID_ISEQ: + clip->source.seq.digits = getU1( fp ); + clip->source.seq.flags = getU1( fp ); + clip->source.seq.offset = getI2( fp ); + clip->source.seq.start = getI2( fp ); + clip->source.seq.end = getI2( fp ); + clip->source.seq.prefix = getS0( fp ); + clip->source.seq.suffix = getS0( fp ); + break; + + case ID_ANIM: + clip->source.anim.name = getS0( fp ); + clip->source.anim.server = getS0( fp ); + rlen = get_flen(); + clip->source.anim.data = getbytes( fp, sz - rlen ); + break; + + case ID_XREF: + clip->source.xref.index = getI4( fp ); + clip->source.xref.string = getS0( fp ); + break; + + case ID_STCC: + clip->source.cycle.lo = getI2( fp ); + clip->source.cycle.hi = getI2( fp ); + clip->source.cycle.name = getS0( fp ); + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the CLIP chunk? */ + + rlen = fp->Tell() - pos; + if ( cksize < rlen ) goto Fail; + if ( cksize == rlen ) + return clip; + + /* process subchunks as they're encountered */ + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_TIME: + clip->start_time = getF4( fp ); + clip->duration = getF4( fp ); + clip->frame_rate = getF4( fp ); + break; + + case ID_CONT: + clip->contrast.val = getF4( fp ); + clip->contrast.eindex = getVX( fp ); + break; + + case ID_BRIT: + clip->brightness.val = getF4( fp ); + clip->brightness.eindex = getVX( fp ); + break; + + case ID_SATR: + clip->saturation.val = getF4( fp ); + clip->saturation.eindex = getVX( fp ); + break; + + case ID_HUE: + clip->hue.val = getF4( fp ); + clip->hue.eindex = getVX( fp ); + break; + + case ID_GAMM: + clip->gamma.val = getF4( fp ); + clip->gamma.eindex = getVX( fp ); + break; + + case ID_NEGA: + clip->negative = getU2( fp ); + break; + + case ID_IFLT: + case ID_PFLT: + filt = (lwPlugin*)Mem_ClearedAlloc( sizeof( lwPlugin ) ); + if ( !filt ) goto Fail; + + filt->name = getS0( fp ); + filt->flags = getU2( fp ); + rlen = get_flen(); + filt->data = getbytes( fp, sz - rlen ); + + if ( id == ID_IFLT ) { + lwListAdd( (void**)&clip->ifilter, filt ); + clip->nifilters++; + } + else { + lwListAdd( (void**)&clip->pfilter, filt ); + clip->npfilters++; + } + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the CLIP chunk? */ + + rlen = fp->Tell() - pos; + if ( cksize < rlen ) goto Fail; + if ( cksize == rlen ) break; + + /* get the next chunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) goto Fail; + } + + return clip; + +Fail: + lwFreeClip( clip ); + return NULL; +} + + +/* +====================================================================== +lwFindClip() + +Returns an lwClip pointer, given a clip index. +====================================================================== */ + +lwClip *lwFindClip( lwClip *list, int index ) +{ + lwClip *clip; + + clip = list; + while ( clip ) { + if ( clip->index == index ) break; + clip = clip->next; + } + return clip; +} + + +/* +====================================================================== +lwFreeEnvelope() + +Free the memory used by an lwEnvelope. +====================================================================== */ + +void lwFree( void *ptr ) { + Mem_Free( ptr ); +} + +void lwFreeEnvelope( lwEnvelope *env ) +{ + if ( env ) { + if ( env->name ) Mem_Free( env->name ); + lwListFree( env->key, lwFree ); + lwListFree( env->cfilter, (void (__cdecl *)(void *))lwFreePlugin ); + Mem_Free( env ); + } +} + + +static int compare_keys( lwKey *k1, lwKey *k2 ) +{ + return k1->time > k2->time ? 1 : k1->time < k2->time ? -1 : 0; +} + + +/* +====================================================================== +lwGetEnvelope() + +Read an ENVL chunk from an LWO2 file. +====================================================================== */ + +lwEnvelope *lwGetEnvelope( idFile *fp, int cksize ) +{ + lwEnvelope *env; + lwKey *key; + lwPlugin *plug; + unsigned int id; + unsigned short sz; + float f[ 4 ]; + int i, nparams, pos, rlen; + + + /* allocate the Envelope structure */ + + env = (lwEnvelope*)Mem_ClearedAlloc( sizeof( lwEnvelope ) ); + if ( !env ) goto Fail; + + /* remember where we started */ + + set_flen( 0 ); + pos = fp->Tell(); + + /* index */ + + env->index = getVX( fp ); + + /* first subchunk header */ + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + /* process subchunks as they're encountered */ + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_TYPE: + env->type = getU2( fp ); + break; + + case ID_NAME: + env->name = getS0( fp ); + break; + + case ID_PRE: + env->behavior[ 0 ] = getU2( fp ); + break; + + case ID_POST: + env->behavior[ 1 ] = getU2( fp ); + break; + + case ID_KEY: + key = (lwKey*)Mem_ClearedAlloc( sizeof( lwKey ) ); + if ( !key ) goto Fail; + key->time = getF4( fp ); + key->value = getF4( fp ); + lwListInsert( (void**)&env->key, key, (int (__cdecl *)(void *,void *))compare_keys ); + env->nkeys++; + break; + + case ID_SPAN: + if ( !key ) goto Fail; + key->shape = getU4( fp ); + + nparams = ( sz - 4 ) / 4; + if ( nparams > 4 ) nparams = 4; + for ( i = 0; i < nparams; i++ ) + f[ i ] = getF4( fp ); + + switch ( key->shape ) { + case ID_TCB: + key->tension = f[ 0 ]; + key->continuity = f[ 1 ]; + key->bias = f[ 2 ]; + break; + + case ID_BEZI: + case ID_HERM: + case ID_BEZ2: + for ( i = 0; i < nparams; i++ ) + key->param[ i ] = f[ i ]; + break; + } + break; + + case ID_CHAN: + plug = (lwPlugin*)Mem_ClearedAlloc( sizeof( lwPlugin ) ); + if ( !plug ) goto Fail; + + plug->name = getS0( fp ); + plug->flags = getU2( fp ); + plug->data = getbytes( fp, sz - get_flen() ); + + lwListAdd( (void**)&env->cfilter, plug ); + env->ncfilters++; + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the ENVL chunk? */ + + rlen = fp->Tell() - pos; + if ( cksize < rlen ) goto Fail; + if ( cksize == rlen ) break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) goto Fail; + } + + return env; + +Fail: + lwFreeEnvelope( env ); + return NULL; +} + + +/* +====================================================================== +lwFindEnvelope() + +Returns an lwEnvelope pointer, given an envelope index. +====================================================================== */ + +lwEnvelope *lwFindEnvelope( lwEnvelope *list, int index ) +{ + lwEnvelope *env; + + env = list; + while ( env ) { + if ( env->index == index ) break; + env = env->next; + } + return env; +} + + +/* +====================================================================== +range() + +Given the value v of a periodic function, returns the equivalent value +v2 in the principal interval [lo, hi]. If i isn't NULL, it receives +the number of wavelengths between v and v2. + + v2 = v - i * (hi - lo) + +For example, range( 3 pi, 0, 2 pi, i ) returns pi, with i = 1. +====================================================================== */ + +static float range( float v, float lo, float hi, int *i ) +{ + float v2, r = hi - lo; + + if ( r == 0.0 ) { + if ( i ) *i = 0; + return lo; + } + + v2 = lo + v - r * ( float ) floor(( double ) v / r ); + if ( i ) *i = -( int )(( v2 - v ) / r + ( v2 > v ? 0.5 : -0.5 )); + + return v2; +} + + +/* +====================================================================== +hermite() + +Calculate the Hermite coefficients. +====================================================================== */ + +static void hermite( float t, float *h1, float *h2, float *h3, float *h4 ) +{ + float t2, t3; + + t2 = t * t; + t3 = t * t2; + + *h2 = 3.0f * t2 - t3 - t3; + *h1 = 1.0f - *h2; + *h4 = t3 - t2; + *h3 = *h4 - t2 + t; +} + + +/* +====================================================================== +bezier() + +Interpolate the value of a 1D Bezier curve. +====================================================================== */ + +static float bezier( float x0, float x1, float x2, float x3, float t ) +{ + float a, b, c, t2, t3; + + t2 = t * t; + t3 = t2 * t; + + c = 3.0f * ( x1 - x0 ); + b = 3.0f * ( x2 - x1 ) - c; + a = x3 - x0 - c - b; + + return a * t3 + b * t2 + c * t + x0; +} + + +/* +====================================================================== +bez2_time() + +Find the t for which bezier() returns the input time. The handle +endpoints of a BEZ2 curve represent the control points, and these have +(time, value) coordinates, so time is used as both a coordinate and a +parameter for this curve type. +====================================================================== */ + +static float bez2_time( float x0, float x1, float x2, float x3, float time, + float *t0, float *t1 ) +{ + float v, t; + + t = *t0 + ( *t1 - *t0 ) * 0.5f; + v = bezier( x0, x1, x2, x3, t ); + if ( idMath::Fabs( time - v ) > .0001f ) { + if ( v > time ) + *t1 = t; + else + *t0 = t; + return bez2_time( x0, x1, x2, x3, time, t0, t1 ); + } + else + return t; +} + + +/* +====================================================================== +bez2() + +Interpolate the value of a BEZ2 curve. +====================================================================== */ + +static float bez2( lwKey *key0, lwKey *key1, float time ) +{ + float x, y, t, t0 = 0.0f, t1 = 1.0f; + + if ( key0->shape == ID_BEZ2 ) + x = key0->time + key0->param[ 2 ]; + else + x = key0->time + ( key1->time - key0->time ) / 3.0f; + + t = bez2_time( key0->time, x, key1->time + key1->param[ 0 ], key1->time, + time, &t0, &t1 ); + + if ( key0->shape == ID_BEZ2 ) + y = key0->value + key0->param[ 3 ]; + else + y = key0->value + key0->param[ 1 ] / 3.0f; + + return bezier( key0->value, y, key1->param[ 1 ] + key1->value, key1->value, t ); +} + + +/* +====================================================================== +outgoing() + +Return the outgoing tangent to the curve at key0. The value returned +for the BEZ2 case is used when extrapolating a linear pre behavior and +when interpolating a non-BEZ2 span. +====================================================================== */ + +static float outgoing( lwKey *key0, lwKey *key1 ) +{ + float a, b, d, t, out; + + switch ( key0->shape ) + { + case ID_TCB: + a = ( 1.0f - key0->tension ) + * ( 1.0f + key0->continuity ) + * ( 1.0f + key0->bias ); + b = ( 1.0f - key0->tension ) + * ( 1.0f - key0->continuity ) + * ( 1.0f - key0->bias ); + d = key1->value - key0->value; + + if ( key0->prev ) { + t = ( key1->time - key0->time ) / ( key1->time - key0->prev->time ); + out = t * ( a * ( key0->value - key0->prev->value ) + b * d ); + } + else + out = b * d; + break; + + case ID_LINE: + d = key1->value - key0->value; + if ( key0->prev ) { + t = ( key1->time - key0->time ) / ( key1->time - key0->prev->time ); + out = t * ( key0->value - key0->prev->value + d ); + } + else + out = d; + break; + + case ID_BEZI: + case ID_HERM: + out = key0->param[ 1 ]; + if ( key0->prev ) + out *= ( key1->time - key0->time ) / ( key1->time - key0->prev->time ); + break; + + case ID_BEZ2: + out = key0->param[ 3 ] * ( key1->time - key0->time ); + if ( idMath::Fabs( key0->param[ 2 ] ) > 1e-5f ) + out /= key0->param[ 2 ]; + else + out *= 1e5f; + break; + + case ID_STEP: + default: + out = 0.0f; + break; + } + + return out; +} + + +/* +====================================================================== +incoming() + +Return the incoming tangent to the curve at key1. The value returned +for the BEZ2 case is used when extrapolating a linear post behavior. +====================================================================== */ + +static float incoming( lwKey *key0, lwKey *key1 ) +{ + float a, b, d, t, in; + + switch ( key1->shape ) + { + case ID_LINE: + d = key1->value - key0->value; + if ( key1->next ) { + t = ( key1->time - key0->time ) / ( key1->next->time - key0->time ); + in = t * ( key1->next->value - key1->value + d ); + } + else + in = d; + break; + + case ID_TCB: + a = ( 1.0f - key1->tension ) + * ( 1.0f - key1->continuity ) + * ( 1.0f + key1->bias ); + b = ( 1.0f - key1->tension ) + * ( 1.0f + key1->continuity ) + * ( 1.0f - key1->bias ); + d = key1->value - key0->value; + + if ( key1->next ) { + t = ( key1->time - key0->time ) / ( key1->next->time - key0->time ); + in = t * ( b * ( key1->next->value - key1->value ) + a * d ); + } + else + in = a * d; + break; + + case ID_BEZI: + case ID_HERM: + in = key1->param[ 0 ]; + if ( key1->next ) + in *= ( key1->time - key0->time ) / ( key1->next->time - key0->time ); + break; + return in; + + case ID_BEZ2: + in = key1->param[ 1 ] * ( key1->time - key0->time ); + if ( idMath::Fabs( key1->param[ 0 ] ) > 1e-5f ) + in /= key1->param[ 0 ]; + else + in *= 1e5f; + break; + + case ID_STEP: + default: + in = 0.0f; + break; + } + + return in; +} + + +/* +====================================================================== +evalEnvelope() + +Given a list of keys and a time, returns the interpolated value of the +envelope at that time. +====================================================================== */ + +float evalEnvelope( lwEnvelope *env, float time ) +{ + lwKey *key0, *key1, *skey, *ekey; + float t, h1, h2, h3, h4, in, out, offset = 0.0f; + int noff; + + + /* if there's no key, the value is 0 */ + + if ( env->nkeys == 0 ) return 0.0f; + + /* if there's only one key, the value is constant */ + + if ( env->nkeys == 1 ) + return env->key->value; + + /* find the first and last keys */ + + skey = ekey = env->key; + while ( ekey->next ) ekey = ekey->next; + + /* use pre-behavior if time is before first key time */ + + if ( time < skey->time ) { + switch ( env->behavior[ 0 ] ) + { + case BEH_RESET: + return 0.0f; + + case BEH_CONSTANT: + return skey->value; + + case BEH_REPEAT: + time = range( time, skey->time, ekey->time, NULL ); + break; + + case BEH_OSCILLATE: + time = range( time, skey->time, ekey->time, &noff ); + if ( noff % 2 ) + time = ekey->time - skey->time - time; + break; + + case BEH_OFFSET: + time = range( time, skey->time, ekey->time, &noff ); + offset = noff * ( ekey->value - skey->value ); + break; + + case BEH_LINEAR: + out = outgoing( skey, skey->next ) + / ( skey->next->time - skey->time ); + return out * ( time - skey->time ) + skey->value; + } + } + + /* use post-behavior if time is after last key time */ + + else if ( time > ekey->time ) { + switch ( env->behavior[ 1 ] ) + { + case BEH_RESET: + return 0.0f; + + case BEH_CONSTANT: + return ekey->value; + + case BEH_REPEAT: + time = range( time, skey->time, ekey->time, NULL ); + break; + + case BEH_OSCILLATE: + time = range( time, skey->time, ekey->time, &noff ); + if ( noff % 2 ) + time = ekey->time - skey->time - time; + break; + + case BEH_OFFSET: + time = range( time, skey->time, ekey->time, &noff ); + offset = noff * ( ekey->value - skey->value ); + break; + + case BEH_LINEAR: + in = incoming( ekey->prev, ekey ) + / ( ekey->time - ekey->prev->time ); + return in * ( time - ekey->time ) + ekey->value; + } + } + + /* get the endpoints of the interval being evaluated */ + + key0 = env->key; + while ( time > key0->next->time ) + key0 = key0->next; + key1 = key0->next; + + /* check for singularities first */ + + if ( time == key0->time ) + return key0->value + offset; + else if ( time == key1->time ) + return key1->value + offset; + + /* get interval length, time in [0, 1] */ + + t = ( time - key0->time ) / ( key1->time - key0->time ); + + /* interpolate */ + + switch ( key1->shape ) + { + case ID_TCB: + case ID_BEZI: + case ID_HERM: + out = outgoing( key0, key1 ); + in = incoming( key0, key1 ); + hermite( t, &h1, &h2, &h3, &h4 ); + return h1 * key0->value + h2 * key1->value + h3 * out + h4 * in + offset; + + case ID_BEZ2: + return bez2( key0, key1, time ) + offset; + + case ID_LINE: + return key0->value + t * ( key1->value - key0->value ) + offset; + + case ID_STEP: + return key0->value + offset; + + default: + return offset; + } +} + + + +/* +====================================================================== +lwListFree() + +Free the items in a list. +====================================================================== */ + +void lwListFree( void *list, void ( *freeNode )( void * )) +{ + lwNode *node, *next; + + node = ( lwNode * ) list; + while ( node ) { + next = node->next; + freeNode( node ); + node = next; + } +} + + +/* +====================================================================== +lwListAdd() + +Append a node to a list. +====================================================================== */ + +void lwListAdd( void **list, void *node ) +{ + lwNode *head, *tail; + + head = *(( lwNode ** ) list ); + if ( !head ) { + *list = node; + return; + } + while ( head ) { + tail = head; + head = head->next; + } + tail->next = ( lwNode * ) node; + (( lwNode * ) node )->prev = tail; +} + + +/* +====================================================================== +lwListInsert() + +Insert a node into a list in sorted order. +====================================================================== */ + +void lwListInsert( void **vlist, void *vitem, int ( *compare )( void *, void * )) +{ + lwNode **list, *item, *node, *prev; + + if ( !*vlist ) { + *vlist = vitem; + return; + } + + list = ( lwNode ** ) vlist; + item = ( lwNode * ) vitem; + node = *list; + prev = NULL; + + while ( node ) { + if ( 0 < compare( node, item )) break; + prev = node; + node = node->next; + } + + if ( !prev ) { + *list = item; + node->prev = item; + item->next = node; + } + else if ( !node ) { + prev->next = item; + item->prev = prev; + } + else { + item->next = node; + item->prev = prev; + prev->next = item; + node->prev = item; + } +} + +/* +====================================================================== +flen + +This accumulates a count of the number of bytes read. Callers can set +it at the beginning of a sequence of reads and then retrieve it to get +the number of bytes actually read. If one of the I/O functions fails, +flen is set to an error code, after which the I/O functions ignore +read requests until flen is reset. +====================================================================== */ + +#define FLEN_ERROR -9999 + +static int flen; + +void set_flen( int i ) { flen = i; } + +int get_flen( void ) { return flen; } + +void *getbytes( idFile *fp, int size ) +{ + void *data; + + if ( flen == FLEN_ERROR ) return NULL; + if ( size < 0 ) { + flen = FLEN_ERROR; + return NULL; + } + data = Mem_ClearedAlloc( size ); + if ( !data ) { + flen = FLEN_ERROR; + return NULL; + } + if ( size != fp->Read( data, size ) ) { + flen = FLEN_ERROR; + Mem_Free( data ); + return NULL; + } + + flen += size; + return data; +} + + +void skipbytes( idFile *fp, int n ) +{ + if ( flen == FLEN_ERROR ) return; + if ( fp->Seek( n, FS_SEEK_CUR )) + flen = FLEN_ERROR; + else + flen += n; +} + + +int getI1( idFile *fp ) +{ + int i, c; + + if ( flen == FLEN_ERROR ) return 0; + c = 0; + i = fp->Read(&c, 1); + if ( i < 0 ) { + flen = FLEN_ERROR; + return 0; + } + if ( c > 127 ) c -= 256; + flen += 1; + return c; +} + + +short getI2( idFile *fp ) +{ + short i; + + if ( flen == FLEN_ERROR ) return 0; + if ( 2 != fp->Read( &i, 2 )) { + flen = FLEN_ERROR; + return 0; + } + BigRevBytes( &i, 2, 1 ); + flen += 2; + return i; +} + + +int getI4( idFile *fp ) +{ + int i; + + if ( flen == FLEN_ERROR ) return 0; + if ( 4 != fp->Read( &i, 4 )) { + flen = FLEN_ERROR; + return 0; + } + BigRevBytes( &i, 4, 1 ); + flen += 4; + return i; +} + + +unsigned char getU1( idFile *fp ) +{ + int i, c; + + if ( flen == FLEN_ERROR ) return 0; + c = 0; + i = fp->Read(&c, 1); + if ( i < 0 ) { + flen = FLEN_ERROR; + return 0; + } + flen += 1; + return c; +} + + +unsigned short getU2( idFile *fp ) +{ + unsigned short i; + + if ( flen == FLEN_ERROR ) return 0; + if ( 2 != fp->Read( &i, 2 )) { + flen = FLEN_ERROR; + return 0; + } + BigRevBytes( &i, 2, 1 ); + flen += 2; + return i; +} + + +unsigned int getU4( idFile *fp ) +{ + unsigned int i; + + if ( flen == FLEN_ERROR ) return 0; + if ( 4 != fp->Read( &i, 4 )) { + flen = FLEN_ERROR; + return 0; + } + BigRevBytes( &i, 4, 1 ); + flen += 4; + return i; +} + + +int getVX( idFile *fp ) +{ + byte c; + int i; + + if ( flen == FLEN_ERROR ) return 0; + + c = 0; + if (fp->Read(&c, 1) == -1) { + return 0; + } + + if ( c != 0xFF ) { + i = c << 8; + c = 0; + if (fp->Read(&c, 1) == -1) { + return 0; + } + i |= c; + flen += 2; + } + else { + c = 0; + if (fp->Read(&c, 1) == -1) { + return 0; + } + i = c << 16; + c = 0; + if (fp->Read(&c, 1) == -1) { + return 0; + } + i |= c << 8; + c = 0; + if (fp->Read(&c, 1) == -1) { + return 0; + } + i |= c; + flen += 4; + } + + return i; +} + + +float getF4( idFile *fp ) +{ + float f; + + if ( flen == FLEN_ERROR ) return 0.0f; + if ( 4 != fp->Read( &f, 4 ) ) { + flen = FLEN_ERROR; + return 0.0f; + } + BigRevBytes( &f, 4, 1 ); + flen += 4; + + if ( FLOAT_IS_DENORMAL( f ) ) { + f = 0.0f; + } + return f; +} + + +char *getS0( idFile *fp ) +{ + char *s; + int i, c, len, pos; + + if ( flen == FLEN_ERROR ) return NULL; + + pos = fp->Tell(); + for ( i = 1; ; i++ ) { + c = 0; + if (fp->Read(&c, 1) == -1) { + flen = FLEN_ERROR; + return NULL; + } + if ( c == 0 ) break; + } + + if ( i == 1 ) { + if ( fp->Seek( pos + 2, FS_SEEK_SET )) + flen = FLEN_ERROR; + else + flen += 2; + return NULL; + } + + len = i + ( i & 1 ); + s = (char*)Mem_ClearedAlloc( len ); + if ( !s ) { + flen = FLEN_ERROR; + return NULL; + } + + if ( fp->Seek( pos, FS_SEEK_SET )) { + flen = FLEN_ERROR; + return NULL; + } + if ( len != fp->Read( s, len )) { + flen = FLEN_ERROR; + return NULL; + } + + flen += len; + return s; +} + + +int sgetI1( unsigned char **bp ) +{ + int i; + + if ( flen == FLEN_ERROR ) return 0; + i = **bp; + if ( i > 127 ) i -= 256; + flen += 1; + *bp++; + return i; +} + + +short sgetI2( unsigned char **bp ) +{ + short i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 2 ); + BigRevBytes( &i, 2, 1 ); + flen += 2; + *bp += 2; + return i; +} + + +int sgetI4( unsigned char **bp ) +{ + int i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 4 ); + BigRevBytes( &i, 4, 1 ); + flen += 4; + *bp += 4; + return i; +} + + +unsigned char sgetU1( unsigned char **bp ) +{ + unsigned char c; + + if ( flen == FLEN_ERROR ) return 0; + c = **bp; + flen += 1; + *bp++; + return c; +} + + +unsigned short sgetU2( unsigned char **bp ) +{ + unsigned char *buf = *bp; + unsigned short i; + + if ( flen == FLEN_ERROR ) return 0; + i = ( buf[ 0 ] << 8 ) | buf[ 1 ]; + flen += 2; + *bp += 2; + return i; +} + + +unsigned int sgetU4( unsigned char **bp ) +{ + unsigned int i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 4 ); + BigRevBytes( &i, 4, 1 ); + flen += 4; + *bp += 4; + return i; +} + + +int sgetVX( unsigned char **bp ) +{ + unsigned char *buf = *bp; + int i; + + if ( flen == FLEN_ERROR ) return 0; + + if ( buf[ 0 ] != 0xFF ) { + i = buf[ 0 ] << 8 | buf[ 1 ]; + flen += 2; + *bp += 2; + } + else { + i = ( buf[ 1 ] << 16 ) | ( buf[ 2 ] << 8 ) | buf[ 3 ]; + flen += 4; + *bp += 4; + } + return i; +} + + +float sgetF4( unsigned char **bp ) +{ + float f; + + if ( flen == FLEN_ERROR ) return 0.0f; + memcpy( &f, *bp, 4 ); + BigRevBytes( &f, 4, 1 ); + flen += 4; + *bp += 4; + + if ( FLOAT_IS_DENORMAL( f ) ) { + f = 0.0f; + } + return f; +} + + +char *sgetS0( unsigned char **bp ) +{ + char *s; + unsigned char *buf = *bp; + int len; + + if ( flen == FLEN_ERROR ) return NULL; + + len = strlen( (const char*)buf ) + 1; + if ( len == 1 ) { + flen += 2; + *bp += 2; + return NULL; + } + len += len & 1; + s = (char*)Mem_ClearedAlloc( len ); + if ( !s ) { + flen = FLEN_ERROR; + return NULL; + } + + memcpy( s, buf, len ); + flen += len; + *bp += len; + return s; +} + +/* +====================================================================== +lwFreeLayer() + +Free memory used by an lwLayer. +====================================================================== */ + +void lwFreeLayer( lwLayer *layer ) +{ + if ( layer ) { + if ( layer->name ) Mem_Free( layer->name ); + lwFreePoints( &layer->point ); + lwFreePolygons( &layer->polygon ); + lwListFree( layer->vmap, (void (__cdecl *)(void *))lwFreeVMap ); + Mem_Free( layer ); + } +} + + +/* +====================================================================== +lwFreeObject() + +Free memory used by an lwObject. +====================================================================== */ + +void lwFreeObject( lwObject *object ) +{ + if ( object ) { + lwListFree( object->layer, (void (__cdecl *)(void *))lwFreeLayer ); + lwListFree( object->env, (void (__cdecl *)(void *))lwFreeEnvelope ); + lwListFree( object->clip, (void (__cdecl *)(void *))lwFreeClip ); + lwListFree( object->surf, (void (__cdecl *)(void *))lwFreeSurface ); + lwFreeTags( &object->taglist ); + Mem_Free( object ); + } +} + + +/* +====================================================================== +lwGetObject() + +Returns the contents of a LightWave object, given its filename, or +NULL if the file couldn't be loaded. On failure, failID and failpos +can be used to diagnose the cause. + +1. If the file isn't an LWO2 or an LWOB, failpos will contain 12 and + failID will be unchanged. + +2. If an error occurs while reading, failID will contain the most + recently read IFF chunk ID, and failpos will contain the value + returned by fp->Tell() at the time of the failure. + +3. If the file couldn't be opened, or an error occurs while reading + the first 12 bytes, both failID and failpos will be unchanged. + +If you don't need this information, failID and failpos can be NULL. +====================================================================== */ + +lwObject *lwGetObject( const char *filename, unsigned int *failID, int *failpos ) +{ + idFile *fp = NULL; + lwObject *object; + lwLayer *layer; + lwNode *node; + int id, formsize, type, cksize; + int i, rlen; + + fp = fileSystem->OpenFileRead( filename ); + if ( !fp ) { + return NULL; + } + + /* read the first 12 bytes */ + + set_flen( 0 ); + id = getU4( fp ); + formsize = getU4( fp ); + type = getU4( fp ); + if ( 12 != get_flen() ) { + fileSystem->CloseFile( fp ); + return NULL; + } + + /* is this a LW object? */ + + if ( id != ID_FORM ) { + fileSystem->CloseFile( fp ); + if ( failpos ) *failpos = 12; + return NULL; + } + + if ( type != ID_LWO2 ) { + fileSystem->CloseFile( fp ); + if ( type == ID_LWOB ) + return lwGetObject5( filename, failID, failpos ); + else { + if ( failpos ) *failpos = 12; + return NULL; + } + } + + /* allocate an object and a default layer */ + + object = (lwObject*)Mem_ClearedAlloc( sizeof( lwObject ) ); + if ( !object ) goto Fail; + + layer = (lwLayer*)Mem_ClearedAlloc( sizeof( lwLayer ) ); + if ( !layer ) goto Fail; + object->layer = layer; + + object->timeStamp = fp->Timestamp(); + + /* get the first chunk header */ + + id = getU4( fp ); + cksize = getU4( fp ); + if ( 0 > get_flen() ) goto Fail; + + /* process chunks as they're encountered */ + + while ( 1 ) { + cksize += cksize & 1; + + switch ( id ) + { + case ID_LAYR: + if ( object->nlayers > 0 ) { + layer = (lwLayer*)Mem_ClearedAlloc( sizeof( lwLayer ) ); + if ( !layer ) goto Fail; + lwListAdd( (void**)&object->layer, layer ); + } + object->nlayers++; + + set_flen( 0 ); + layer->index = getU2( fp ); + layer->flags = getU2( fp ); + layer->pivot[ 0 ] = getF4( fp ); + layer->pivot[ 1 ] = getF4( fp ); + layer->pivot[ 2 ] = getF4( fp ); + layer->name = getS0( fp ); + + rlen = get_flen(); + if ( rlen < 0 || rlen > cksize ) goto Fail; + if ( rlen <= cksize - 2 ) + layer->parent = getU2( fp ); + rlen = get_flen(); + if ( rlen < cksize ) + fp->Seek( cksize - rlen, FS_SEEK_CUR ); + break; + + case ID_PNTS: + if ( !lwGetPoints( fp, cksize, &layer->point )) + goto Fail; + break; + + case ID_POLS: + if ( !lwGetPolygons( fp, cksize, &layer->polygon, + layer->point.offset )) + goto Fail; + break; + + case ID_VMAP: + case ID_VMAD: + node = ( lwNode * ) lwGetVMap( fp, cksize, layer->point.offset, + layer->polygon.offset, id == ID_VMAD ); + if ( !node ) goto Fail; + lwListAdd( (void**)&layer->vmap, node ); + layer->nvmaps++; + break; + + case ID_PTAG: + if ( !lwGetPolygonTags( fp, cksize, &object->taglist, + &layer->polygon )) + goto Fail; + break; + + case ID_BBOX: + set_flen( 0 ); + for ( i = 0; i < 6; i++ ) + layer->bbox[ i ] = getF4( fp ); + rlen = get_flen(); + if ( rlen < 0 || rlen > cksize ) goto Fail; + if ( rlen < cksize ) + fp->Seek( cksize - rlen, FS_SEEK_CUR ); + break; + + case ID_TAGS: + if ( !lwGetTags( fp, cksize, &object->taglist )) + goto Fail; + break; + + case ID_ENVL: + node = ( lwNode * ) lwGetEnvelope( fp, cksize ); + if ( !node ) goto Fail; + lwListAdd( (void**)&object->env, node ); + object->nenvs++; + break; + + case ID_CLIP: + node = ( lwNode * ) lwGetClip( fp, cksize ); + if ( !node ) goto Fail; + lwListAdd( (void**)&object->clip, node ); + object->nclips++; + break; + + case ID_SURF: + node = ( lwNode * ) lwGetSurface( fp, cksize ); + if ( !node ) goto Fail; + lwListAdd( (void**)&object->surf, node ); + object->nsurfs++; + break; + + case ID_DESC: + case ID_TEXT: + case ID_ICON: + default: + fp->Seek( cksize, FS_SEEK_CUR ); + break; + } + + /* end of the file? */ + + if ( formsize <= fp->Tell() - 8 ) break; + + /* get the next chunk header */ + + set_flen( 0 ); + id = getU4( fp ); + cksize = getU4( fp ); + if ( 8 != get_flen() ) goto Fail; + } + + fileSystem->CloseFile( fp ); + fp = NULL; + + if ( object->nlayers == 0 ) + object->nlayers = 1; + + layer = object->layer; + while ( layer ) { + lwGetBoundingBox( &layer->point, layer->bbox ); + lwGetPolyNormals( &layer->point, &layer->polygon ); + if ( !lwGetPointPolygons( &layer->point, &layer->polygon )) goto Fail; + if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist, + &object->surf, &object->nsurfs )) goto Fail; + lwGetVertNormals( &layer->point, &layer->polygon ); + if ( !lwGetPointVMaps( &layer->point, layer->vmap )) goto Fail; + if ( !lwGetPolyVMaps( &layer->polygon, layer->vmap )) goto Fail; + layer = layer->next; + } + + return object; + +Fail: + if ( failID ) *failID = id; + if ( fp ) { + if ( failpos ) *failpos = fp->Tell(); + fileSystem->CloseFile( fp ); + } + lwFreeObject( object ); + return NULL; +} + + + + +/* IDs specific to LWOB */ + +#define ID_SRFS LWID_('S','R','F','S') +#define ID_FLAG LWID_('F','L','A','G') +#define ID_VLUM LWID_('V','L','U','M') +#define ID_VDIF LWID_('V','D','I','F') +#define ID_VSPC LWID_('V','S','P','C') +#define ID_RFLT LWID_('R','F','L','T') +#define ID_BTEX LWID_('B','T','E','X') +#define ID_CTEX LWID_('C','T','E','X') +#define ID_DTEX LWID_('D','T','E','X') +#define ID_LTEX LWID_('L','T','E','X') +#define ID_RTEX LWID_('R','T','E','X') +#define ID_STEX LWID_('S','T','E','X') +#define ID_TTEX LWID_('T','T','E','X') +#define ID_TFLG LWID_('T','F','L','G') +#define ID_TSIZ LWID_('T','S','I','Z') +#define ID_TCTR LWID_('T','C','T','R') +#define ID_TFAL LWID_('T','F','A','L') +#define ID_TVEL LWID_('T','V','E','L') +#define ID_TCLR LWID_('T','C','L','R') +#define ID_TVAL LWID_('T','V','A','L') +#define ID_TAMP LWID_('T','A','M','P') +#define ID_TIMG LWID_('T','I','M','G') +#define ID_TAAS LWID_('T','A','A','S') +#define ID_TREF LWID_('T','R','E','F') +#define ID_TOPC LWID_('T','O','P','C') +#define ID_SDAT LWID_('S','D','A','T') +#define ID_TFP0 LWID_('T','F','P','0') +#define ID_TFP1 LWID_('T','F','P','1') + + +/* +====================================================================== +add_clip() + +Add a clip to the clip list. Used to store the contents of an RIMG or +TIMG surface subchunk. +====================================================================== */ + +static int add_clip( char *s, lwClip **clist, int *nclips ) +{ + lwClip *clip; + char *p; + + clip = (lwClip*)Mem_ClearedAlloc( sizeof( lwClip ) ); + if ( !clip ) return 0; + + clip->contrast.val = 1.0f; + clip->brightness.val = 1.0f; + clip->saturation.val = 1.0f; + clip->gamma.val = 1.0f; + + if ( p = strstr( s, "(sequence)" )) { + p[ -1 ] = 0; + clip->type = ID_ISEQ; + clip->source.seq.prefix = s; + clip->source.seq.digits = 3; + } + else { + clip->type = ID_STIL; + clip->source.still.name = s; + } + + *nclips++; + clip->index = *nclips; + + lwListAdd( (void**)clist, clip ); + + return clip->index; +} + + +/* +====================================================================== +add_tvel() + +Add a triple of envelopes to simulate the old texture velocity +parameters. +====================================================================== */ + +static int add_tvel( float pos[], float vel[], lwEnvelope **elist, int *nenvs ) +{ + lwEnvelope *env; + lwKey *key0, *key1; + int i; + + for ( i = 0; i < 3; i++ ) { + env = (lwEnvelope*)Mem_ClearedAlloc( sizeof( lwEnvelope ) ); + key0 = (lwKey*)Mem_ClearedAlloc( sizeof( lwKey ) ); + key1 = (lwKey*)Mem_ClearedAlloc( sizeof( lwKey ) ); + if ( !env || !key0 || !key1 ) return 0; + + key0->next = key1; + key0->value = pos[ i ]; + key0->time = 0.0f; + key1->prev = key0; + key1->value = pos[ i ] + vel[ i ] * 30.0f; + key1->time = 1.0f; + key0->shape = key1->shape = ID_LINE; + + env->index = *nenvs + i + 1; + env->type = 0x0301 + i; + env->name = (char*)Mem_ClearedAlloc( 11 ); + if ( env->name ) { + strcpy( env->name, "Position.X" ); + env->name[ 9 ] += i; + } + env->key = key0; + env->nkeys = 2; + env->behavior[ 0 ] = BEH_LINEAR; + env->behavior[ 1 ] = BEH_LINEAR; + + lwListAdd( (void**)elist, env ); + } + + *nenvs += 3; + return env->index - 2; +} + + +/* +====================================================================== +get_texture() + +Create a new texture for BTEX, CTEX, etc. subchunks. +====================================================================== */ + +static lwTexture *get_texture( char *s ) +{ + lwTexture *tex; + + tex = (lwTexture*)Mem_ClearedAlloc( sizeof( lwTexture ) ); + if ( !tex ) return NULL; + + tex->tmap.size.val[ 0 ] = + tex->tmap.size.val[ 1 ] = + tex->tmap.size.val[ 2 ] = 1.0f; + tex->opacity.val = 1.0f; + tex->enabled = 1; + + if ( strstr( s, "Image Map" )) { + tex->type = ID_IMAP; + if ( strstr( s, "Planar" )) tex->param.imap.projection = 0; + else if ( strstr( s, "Cylindrical" )) tex->param.imap.projection = 1; + else if ( strstr( s, "Spherical" )) tex->param.imap.projection = 2; + else if ( strstr( s, "Cubic" )) tex->param.imap.projection = 3; + else if ( strstr( s, "Front" )) tex->param.imap.projection = 4; + tex->param.imap.aa_strength = 1.0f; + tex->param.imap.amplitude.val = 1.0f; + Mem_Free( s ); + } + else { + tex->type = ID_PROC; + tex->param.proc.name = s; + } + + return tex; +} + + +/* +====================================================================== +lwGetSurface5() + +Read an lwSurface from an LWOB file. +====================================================================== */ + +lwSurface *lwGetSurface5( idFile *fp, int cksize, lwObject *obj ) +{ + lwSurface *surf; + lwTexture *tex; + lwPlugin *shdr; + char *s; + float v[ 3 ]; + unsigned int id, flags; + unsigned short sz; + int pos, rlen, i; + + + /* allocate the Surface structure */ + + surf = (lwSurface*)Mem_ClearedAlloc( sizeof( lwSurface ) ); + if ( !surf ) goto Fail; + + /* non-zero defaults */ + + surf->color.rgb[ 0 ] = 0.78431f; + surf->color.rgb[ 1 ] = 0.78431f; + surf->color.rgb[ 2 ] = 0.78431f; + surf->diffuse.val = 1.0f; + surf->glossiness.val = 0.4f; + surf->bump.val = 1.0f; + surf->eta.val = 1.0f; + surf->sideflags = 1; + + /* remember where we started */ + + set_flen( 0 ); + pos = fp->Tell(); + + /* name */ + + surf->name = getS0( fp ); + + /* first subchunk header */ + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + /* process subchunks as they're encountered */ + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_COLR: + surf->color.rgb[ 0 ] = getU1( fp ) / 255.0f; + surf->color.rgb[ 1 ] = getU1( fp ) / 255.0f; + surf->color.rgb[ 2 ] = getU1( fp ) / 255.0f; + break; + + case ID_FLAG: + flags = getU2( fp ); + if ( flags & 4 ) surf->smooth = 1.56207f; + if ( flags & 8 ) surf->color_hilite.val = 1.0f; + if ( flags & 16 ) surf->color_filter.val = 1.0f; + if ( flags & 128 ) surf->dif_sharp.val = 0.5f; + if ( flags & 256 ) surf->sideflags = 3; + if ( flags & 512 ) surf->add_trans.val = 1.0f; + break; + + case ID_LUMI: + surf->luminosity.val = getI2( fp ) / 256.0f; + break; + + case ID_VLUM: + surf->luminosity.val = getF4( fp ); + break; + + case ID_DIFF: + surf->diffuse.val = getI2( fp ) / 256.0f; + break; + + case ID_VDIF: + surf->diffuse.val = getF4( fp ); + break; + + case ID_SPEC: + surf->specularity.val = getI2( fp ) / 256.0f; + break; + + case ID_VSPC: + surf->specularity.val = getF4( fp ); + break; + + case ID_GLOS: + surf->glossiness.val = ( float ) logf( ( float) getU2( fp )) / 20.7944f; + break; + + case ID_SMAN: + surf->smooth = getF4( fp ); + break; + + case ID_REFL: + surf->reflection.val.val = getI2( fp ) / 256.0f; + break; + + case ID_RFLT: + surf->reflection.options = getU2( fp ); + break; + + case ID_RIMG: + s = getS0( fp ); + surf->reflection.cindex = add_clip( s, &obj->clip, &obj->nclips ); + surf->reflection.options = 3; + break; + + case ID_RSAN: + surf->reflection.seam_angle = getF4( fp ); + break; + + case ID_TRAN: + surf->transparency.val.val = getI2( fp ) / 256.0f; + break; + + case ID_RIND: + surf->eta.val = getF4( fp ); + break; + + case ID_BTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->bump.tex, tex ); + break; + + case ID_CTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->color.tex, tex ); + break; + + case ID_DTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->diffuse.tex, tex ); + break; + + case ID_LTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->luminosity.tex, tex ); + break; + + case ID_RTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->reflection.val.tex, tex ); + break; + + case ID_STEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->specularity.tex, tex ); + break; + + case ID_TTEX: + s = (char*)getbytes( fp, sz ); + tex = get_texture( s ); + lwListAdd( (void**)&surf->transparency.val.tex, tex ); + break; + + case ID_TFLG: + flags = getU2( fp ); + + if ( flags & 1 ) i = 0; + if ( flags & 2 ) i = 1; + if ( flags & 4 ) i = 2; + tex->axis = i; + if ( tex->type == ID_IMAP ) + tex->param.imap.axis = i; + else + tex->param.proc.axis = i; + + if ( flags & 8 ) tex->tmap.coord_sys = 1; + if ( flags & 16 ) tex->negative = 1; + if ( flags & 32 ) tex->param.imap.pblend = 1; + if ( flags & 64 ) { + tex->param.imap.aa_strength = 1.0f; + tex->param.imap.aas_flags = 1; + } + break; + + case ID_TSIZ: + for ( i = 0; i < 3; i++ ) + tex->tmap.size.val[ i ] = getF4( fp ); + break; + + case ID_TCTR: + for ( i = 0; i < 3; i++ ) + tex->tmap.center.val[ i ] = getF4( fp ); + break; + + case ID_TFAL: + for ( i = 0; i < 3; i++ ) + tex->tmap.falloff.val[ i ] = getF4( fp ); + break; + + case ID_TVEL: + for ( i = 0; i < 3; i++ ) + v[ i ] = getF4( fp ); + tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v, + &obj->env, &obj->nenvs ); + break; + + case ID_TCLR: + if ( tex->type == ID_PROC ) + for ( i = 0; i < 3; i++ ) + tex->param.proc.value[ i ] = getU1( fp ) / 255.0f; + break; + + case ID_TVAL: + tex->param.proc.value[ 0 ] = getI2( fp ) / 256.0f; + break; + + case ID_TAMP: + if ( tex->type == ID_IMAP ) + tex->param.imap.amplitude.val = getF4( fp ); + break; + + case ID_TIMG: + s = getS0( fp ); + tex->param.imap.cindex = add_clip( s, &obj->clip, &obj->nclips ); + break; + + case ID_TAAS: + tex->param.imap.aa_strength = getF4( fp ); + tex->param.imap.aas_flags = 1; + break; + + case ID_TREF: + tex->tmap.ref_object = (char*)getbytes( fp, sz ); + break; + + case ID_TOPC: + tex->opacity.val = getF4( fp ); + break; + + case ID_TFP0: + if ( tex->type == ID_IMAP ) + tex->param.imap.wrapw.val = getF4( fp ); + break; + + case ID_TFP1: + if ( tex->type == ID_IMAP ) + tex->param.imap.wraph.val = getF4( fp ); + break; + + case ID_SHDR: + shdr = (lwPlugin*)Mem_ClearedAlloc( sizeof( lwPlugin ) ); + if ( !shdr ) goto Fail; + shdr->name = (char*)getbytes( fp, sz ); + lwListAdd( (void**)&surf->shader, shdr ); + surf->nshaders++; + break; + + case ID_SDAT: + shdr->data = getbytes( fp, sz ); + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the SURF chunk? */ + + if ( cksize <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) goto Fail; + } + + return surf; + +Fail: + if ( surf ) lwFreeSurface( surf ); + return NULL; +} + + +/* +====================================================================== +lwGetPolygons5() + +Read polygon records from a POLS chunk in an LWOB file. The polygons +are added to the array in the lwPolygonList. +====================================================================== */ + +int lwGetPolygons5( idFile *fp, int cksize, lwPolygonList *plist, int ptoffset ) +{ + lwPolygon *pp; + lwPolVert *pv; + unsigned char *buf, *bp; + int i, j, nv, nverts, npols; + + + if ( cksize == 0 ) return 1; + + /* read the whole chunk */ + + set_flen( 0 ); + buf = (unsigned char*)getbytes( fp, cksize ); + if ( !buf ) goto Fail; + + /* count the polygons and vertices */ + + nverts = 0; + npols = 0; + bp = buf; + + while ( bp < buf + cksize ) { + nv = sgetU2( &bp ); + nverts += nv; + npols++; + bp += 2 * nv; + i = sgetI2( &bp ); + if ( i < 0 ) bp += 2; /* detail polygons */ + } + + if ( !lwAllocPolygons( plist, npols, nverts )) + goto Fail; + + /* fill in the new polygons */ + + bp = buf; + pp = plist->pol + plist->offset; + pv = plist->pol[ 0 ].v + plist->voffset; + + for ( i = 0; i < npols; i++ ) { + nv = sgetU2( &bp ); + + pp->nverts = nv; + pp->type = ID_FACE; + if ( !pp->v ) pp->v = pv; + for ( j = 0; j < nv; j++ ) + pv[ j ].index = sgetU2( &bp ) + ptoffset; + j = sgetI2( &bp ); + if ( j < 0 ) { + j = -j; + bp += 2; + } + j -= 1; + pp->surf = ( lwSurface * ) j; + + pp++; + pv += nv; + } + + Mem_Free( buf ); + return 1; + +Fail: + if ( buf ) Mem_Free( buf ); + lwFreePolygons( plist ); + return 0; +} + + +/* +====================================================================== +getLWObject5() + +Returns the contents of an LWOB, given its filename, or NULL if the +file couldn't be loaded. On failure, failID and failpos can be used +to diagnose the cause. + +1. If the file isn't an LWOB, failpos will contain 12 and failID will + be unchanged. + +2. If an error occurs while reading an LWOB, failID will contain the + most recently read IFF chunk ID, and failpos will contain the + value returned by fp->Tell() at the time of the failure. + +3. If the file couldn't be opened, or an error occurs while reading + the first 12 bytes, both failID and failpos will be unchanged. + +If you don't need this information, failID and failpos can be NULL. +====================================================================== */ + +lwObject *lwGetObject5( const char *filename, unsigned int *failID, int *failpos ) +{ + idFile *fp = NULL; + lwObject *object; + lwLayer *layer; + lwNode *node; + int id, formsize, type, cksize; + + + /* open the file */ + + //fp = fopen( filename, "rb" ); + //if ( !fp ) return NULL; + + /* read the first 12 bytes */ + fp = fileSystem->OpenFileRead( filename ); + if ( !fp ) { + return NULL; + } + + set_flen( 0 ); + id = getU4( fp ); + formsize = getU4( fp ); + type = getU4( fp ); + if ( 12 != get_flen() ) { + fileSystem->CloseFile( fp ); + return NULL; + } + + /* LWOB? */ + + if ( id != ID_FORM || type != ID_LWOB ) { + fileSystem->CloseFile( fp ); + if ( failpos ) *failpos = 12; + return NULL; + } + + /* allocate an object and a default layer */ + + object = (lwObject*)Mem_ClearedAlloc( sizeof( lwObject ) ); + if ( !object ) goto Fail2; + + layer = (lwLayer*)Mem_ClearedAlloc( sizeof( lwLayer ) ); + if ( !layer ) goto Fail2; + object->layer = layer; + object->nlayers = 1; + + /* get the first chunk header */ + + id = getU4( fp ); + cksize = getU4( fp ); + if ( 0 > get_flen() ) goto Fail2; + + /* process chunks as they're encountered */ + + while ( 1 ) { + cksize += cksize & 1; + + switch ( id ) + { + case ID_PNTS: + if ( !lwGetPoints( fp, cksize, &layer->point )) + goto Fail2; + break; + + case ID_POLS: + if ( !lwGetPolygons5( fp, cksize, &layer->polygon, + layer->point.offset )) + goto Fail2; + break; + + case ID_SRFS: + if ( !lwGetTags( fp, cksize, &object->taglist )) + goto Fail2; + break; + + case ID_SURF: + node = ( lwNode * ) lwGetSurface5( fp, cksize, object ); + if ( !node ) goto Fail2; + lwListAdd( (void**)&object->surf, node ); + object->nsurfs++; + break; + + default: + fp->Seek( cksize, FS_SEEK_CUR ); + break; + } + + /* end of the file? */ + + if ( formsize <= fp->Tell() - 8 ) break; + + /* get the next chunk header */ + + set_flen( 0 ); + id = getU4( fp ); + cksize = getU4( fp ); + if ( 8 != get_flen() ) goto Fail2; + } + + fileSystem->CloseFile( fp ); + fp = NULL; + + lwGetBoundingBox( &layer->point, layer->bbox ); + lwGetPolyNormals( &layer->point, &layer->polygon ); + if ( !lwGetPointPolygons( &layer->point, &layer->polygon )) goto Fail2; + if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist, + &object->surf, &object->nsurfs )) goto Fail2; + lwGetVertNormals( &layer->point, &layer->polygon ); + + return object; + +Fail2: + if ( failID ) *failID = id; + if ( fp ) { + if ( failpos ) *failpos = fp->Tell(); + fileSystem->CloseFile( fp ); + } + lwFreeObject( object ); + return NULL; +} + +/* +====================================================================== +lwFreePoints() + +Free the memory used by an lwPointList. +====================================================================== */ + +void lwFreePoints( lwPointList *point ) +{ + int i; + + if ( point ) { + if ( point->pt ) { + for ( i = 0; i < point->count; i++ ) { + if ( point->pt[ i ].pol ) Mem_Free( point->pt[ i ].pol ); + if ( point->pt[ i ].vm ) Mem_Free( point->pt[ i ].vm ); + } + Mem_Free( point->pt ); + } + memset( point, 0, sizeof( lwPointList )); + } +} + + +/* +====================================================================== +lwFreePolygons() + +Free the memory used by an lwPolygonList. +====================================================================== */ + +void lwFreePolygons( lwPolygonList *plist ) +{ + int i, j; + + if ( plist ) { + if ( plist->pol ) { + for ( i = 0; i < plist->count; i++ ) { + if ( plist->pol[ i ].v ) { + for ( j = 0; j < plist->pol[ i ].nverts; j++ ) + if ( plist->pol[ i ].v[ j ].vm ) + Mem_Free( plist->pol[ i ].v[ j ].vm ); + } + } + if ( plist->pol[ 0 ].v ) + Mem_Free( plist->pol[ 0 ].v ); + Mem_Free( plist->pol ); + } + memset( plist, 0, sizeof( lwPolygonList )); + } +} + + +/* +====================================================================== +lwGetPoints() + +Read point records from a PNTS chunk in an LWO2 file. The points are +added to the array in the lwPointList. +====================================================================== */ + +int lwGetPoints( idFile *fp, int cksize, lwPointList *point ) +{ + float *f; + int np, i, j; + + if ( cksize == 1 ) return 1; + + /* extend the point array to hold the new points */ + + np = cksize / 12; + point->offset = point->count; + point->count += np; + lwPoint *oldpt = point->pt; + point->pt = (lwPoint*)Mem_Alloc( point->count * sizeof( lwPoint ) ); + if ( !point->pt ) return 0; + if ( oldpt ) { + memcpy( point->pt, oldpt, point->offset * sizeof( lwPoint ) ); + Mem_Free( oldpt ); + } + memset( &point->pt[ point->offset ], 0, np * sizeof( lwPoint ) ); + + /* read the whole chunk */ + + f = ( float * ) getbytes( fp, cksize ); + if ( !f ) return 0; + BigRevBytes( f, 4, np * 3 ); + + /* assign position values */ + + for ( i = 0, j = 0; i < np; i++, j += 3 ) { + point->pt[ i ].pos[ 0 ] = f[ j ]; + point->pt[ i ].pos[ 1 ] = f[ j + 1 ]; + point->pt[ i ].pos[ 2 ] = f[ j + 2 ]; + } + + Mem_Free( f ); + return 1; +} + + +/* +====================================================================== +lwGetBoundingBox() + +Calculate the bounding box for a point list, but only if the bounding +box hasn't already been initialized. +====================================================================== */ + +void lwGetBoundingBox( lwPointList *point, float bbox[] ) +{ + int i, j; + + if ( point->count == 0 ) return; + + for ( i = 0; i < 6; i++ ) + if ( bbox[ i ] != 0.0f ) return; + + bbox[ 0 ] = bbox[ 1 ] = bbox[ 2 ] = 1e20f; + bbox[ 3 ] = bbox[ 4 ] = bbox[ 5 ] = -1e20f; + for ( i = 0; i < point->count; i++ ) { + for ( j = 0; j < 3; j++ ) { + if ( bbox[ j ] > point->pt[ i ].pos[ j ] ) + bbox[ j ] = point->pt[ i ].pos[ j ]; + if ( bbox[ j + 3 ] < point->pt[ i ].pos[ j ] ) + bbox[ j + 3 ] = point->pt[ i ].pos[ j ]; + } + } +} + + +/* +====================================================================== +lwAllocPolygons() + +Allocate or extend the polygon arrays to hold new records. +====================================================================== */ + +int lwAllocPolygons( lwPolygonList *plist, int npols, int nverts ) +{ + int i; + + plist->offset = plist->count; + plist->count += npols; + lwPolygon *oldpol = plist->pol; + plist->pol = (lwPolygon*)Mem_Alloc( plist->count * sizeof( lwPolygon ) ); + if ( !plist->pol ) return 0; + if ( oldpol ) { + memcpy( plist->pol, oldpol, plist->offset * sizeof( lwPolygon ) ); + Mem_Free( oldpol ); + } + memset( plist->pol + plist->offset, 0, npols * sizeof( lwPolygon ) ); + + plist->voffset = plist->vcount; + plist->vcount += nverts; + lwPolVert *oldpolv = plist->pol[0].v; + plist->pol[0].v = (lwPolVert*)Mem_Alloc( plist->vcount * sizeof( lwPolVert ) ); + if ( !plist->pol[ 0 ].v ) return 0; + if ( oldpolv ) { + memcpy( plist->pol[0].v, oldpolv, plist->voffset * sizeof( lwPolVert ) ); + Mem_Free( oldpolv ); + } + memset( plist->pol[ 0 ].v + plist->voffset, 0, nverts * sizeof( lwPolVert ) ); + + /* fix up the old vertex pointers */ + + for ( i = 1; i < plist->offset; i++ ) + plist->pol[ i ].v = plist->pol[ i - 1 ].v + plist->pol[ i - 1 ].nverts; + + return 1; +} + + +/* +====================================================================== +lwGetPolygons() + +Read polygon records from a POLS chunk in an LWO2 file. The polygons +are added to the array in the lwPolygonList. +====================================================================== */ + +int lwGetPolygons( idFile *fp, int cksize, lwPolygonList *plist, int ptoffset ) +{ + lwPolygon *pp; + lwPolVert *pv; + unsigned char *buf, *bp; + int i, j, flags, nv, nverts, npols; + unsigned int type; + + + if ( cksize == 0 ) return 1; + + /* read the whole chunk */ + + set_flen( 0 ); + type = getU4( fp ); + buf = (unsigned char*)getbytes( fp, cksize - 4 ); + if ( cksize != get_flen() ) goto Fail; + + /* count the polygons and vertices */ + + nverts = 0; + npols = 0; + bp = buf; + + while ( bp < buf + cksize - 4 ) { + nv = sgetU2( &bp ); + nv &= 0x03FF; + nverts += nv; + npols++; + for ( i = 0; i < nv; i++ ) + j = sgetVX( &bp ); + } + + if ( !lwAllocPolygons( plist, npols, nverts )) + goto Fail; + + /* fill in the new polygons */ + + bp = buf; + pp = plist->pol + plist->offset; + pv = plist->pol[ 0 ].v + plist->voffset; + + for ( i = 0; i < npols; i++ ) { + nv = sgetU2( &bp ); + flags = nv & 0xFC00; + nv &= 0x03FF; + + pp->nverts = nv; + pp->flags = flags; + pp->type = type; + if ( !pp->v ) pp->v = pv; + for ( j = 0; j < nv; j++ ) + pp->v[ j ].index = sgetVX( &bp ) + ptoffset; + + pp++; + pv += nv; + } + + Mem_Free( buf ); + return 1; + +Fail: + if ( buf ) Mem_Free( buf ); + lwFreePolygons( plist ); + return 0; +} + + +/* +====================================================================== +lwGetPolyNormals() + +Calculate the polygon normals. By convention, LW's polygon normals +are found as the cross product of the first and last edges. It's +undefined for one- and two-point polygons. +====================================================================== */ + +void lwGetPolyNormals( lwPointList *point, lwPolygonList *polygon ) +{ + int i, j; + float p1[ 3 ], p2[ 3 ], pn[ 3 ], v1[ 3 ], v2[ 3 ]; + + for ( i = 0; i < polygon->count; i++ ) { + if ( polygon->pol[ i ].nverts < 3 ) continue; + for ( j = 0; j < 3; j++ ) { + + // FIXME: track down why indexes are way out of range + p1[ j ] = point->pt[ polygon->pol[ i ].v[ 0 ].index ].pos[ j ]; + p2[ j ] = point->pt[ polygon->pol[ i ].v[ 1 ].index ].pos[ j ]; + pn[ j ] = point->pt[ polygon->pol[ i ].v[ polygon->pol[ i ].nverts - 1 ].index ].pos[ j ]; + } + + for ( j = 0; j < 3; j++ ) { + v1[ j ] = p2[ j ] - p1[ j ]; + v2[ j ] = pn[ j ] - p1[ j ]; + } + + cross( v1, v2, polygon->pol[ i ].norm ); + normalize( polygon->pol[ i ].norm ); + } +} + + +/* +====================================================================== +lwGetPointPolygons() + +For each point, fill in the indexes of the polygons that share the +point. Returns 0 if any of the memory allocations fail, otherwise +returns 1. +====================================================================== */ + +int lwGetPointPolygons( lwPointList *point, lwPolygonList *polygon ) +{ + int i, j, k; + + /* count the number of polygons per point */ + + for ( i = 0; i < polygon->count; i++ ) + for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) + ++point->pt[ polygon->pol[ i ].v[ j ].index ].npols; + + /* alloc per-point polygon arrays */ + + for ( i = 0; i < point->count; i++ ) { + if ( point->pt[ i ].npols == 0 ) continue; + point->pt[ i ].pol = (int*)Mem_ClearedAlloc( point->pt[ i ].npols * sizeof( int ) ); + if ( !point->pt[ i ].pol ) return 0; + point->pt[ i ].npols = 0; + } + + /* fill in polygon array for each point */ + + for ( i = 0; i < polygon->count; i++ ) { + for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) { + k = polygon->pol[ i ].v[ j ].index; + point->pt[ k ].pol[ point->pt[ k ].npols ] = i; + ++point->pt[ k ].npols; + } + } + + return 1; +} + + +/* +====================================================================== +lwResolvePolySurfaces() + +Convert tag indexes into actual lwSurface pointers. If any polygons +point to tags for which no corresponding surface can be found, a +default surface is created. +====================================================================== */ + +int lwResolvePolySurfaces( lwPolygonList *polygon, lwTagList *tlist, + lwSurface **surf, int *nsurfs ) +{ + lwSurface **s, *st; + int i, index; + + if ( tlist->count == 0 ) return 1; + + s = (lwSurface**)Mem_ClearedAlloc( tlist->count * sizeof( lwSurface * ) ); + if ( !s ) return 0; + + for ( i = 0; i < tlist->count; i++ ) { + st = *surf; + while ( st ) { + if ( !strcmp( st->name, tlist->tag[ i ] )) { + s[ i ] = st; + break; + } + st = st->next; + } + } + + for ( i = 0; i < polygon->count; i++ ) { + index = ( int ) polygon->pol[ i ].surf; + if ( index < 0 || index > tlist->count ) return 0; + if ( !s[ index ] ) { + s[ index ] = lwDefaultSurface(); + if ( !s[ index ] ) return 0; + s[ index ]->name = (char*)Mem_ClearedAlloc( strlen( tlist->tag[ index ] ) + 1 ); + if ( !s[ index ]->name ) return 0; + strcpy( s[ index ]->name, tlist->tag[ index ] ); + lwListAdd( (void**)surf, s[ index ] ); + *nsurfs = *nsurfs + 1; + } + polygon->pol[ i ].surf = s[ index ]; + } + + Mem_Free( s ); + return 1; +} + + +/* +====================================================================== +lwGetVertNormals() + +Calculate the vertex normals. For each polygon vertex, sum the +normals of the polygons that share the point. If the normals of the +current and adjacent polygons form an angle greater than the max +smoothing angle for the current polygon's surface, the normal of the +adjacent polygon is excluded from the sum. It's also excluded if the +polygons aren't in the same smoothing group. + +Assumes that lwGetPointPolygons(), lwGetPolyNormals() and +lwResolvePolySurfaces() have already been called. +====================================================================== */ + +void lwGetVertNormals( lwPointList *point, lwPolygonList *polygon ) +{ + int j, k, n, g, h, p; + float a; + + for ( j = 0; j < polygon->count; j++ ) { + for ( n = 0; n < polygon->pol[ j ].nverts; n++ ) { + for ( k = 0; k < 3; k++ ) + polygon->pol[ j ].v[ n ].norm[ k ] = polygon->pol[ j ].norm[ k ]; + + if ( polygon->pol[ j ].surf->smooth <= 0 ) continue; + + p = polygon->pol[ j ].v[ n ].index; + + for ( g = 0; g < point->pt[ p ].npols; g++ ) { + h = point->pt[ p ].pol[ g ]; + if ( h == j ) continue; + + if ( polygon->pol[ j ].smoothgrp != polygon->pol[ h ].smoothgrp ) + continue; + a = vecangle( polygon->pol[ j ].norm, polygon->pol[ h ].norm ); + if ( a > polygon->pol[ j ].surf->smooth ) continue; + + for ( k = 0; k < 3; k++ ) + polygon->pol[ j ].v[ n ].norm[ k ] += polygon->pol[ h ].norm[ k ]; + } + + normalize( polygon->pol[ j ].v[ n ].norm ); + } + } +} + + +/* +====================================================================== +lwFreeTags() + +Free memory used by an lwTagList. +====================================================================== */ + +void lwFreeTags( lwTagList *tlist ) +{ + int i; + + if ( tlist ) { + if ( tlist->tag ) { + for ( i = 0; i < tlist->count; i++ ) + if ( tlist->tag[ i ] ) { + Mem_Free( tlist->tag[ i ] ); + } + Mem_Free( tlist->tag ); + } + memset( tlist, 0, sizeof( lwTagList )); + } +} + + +/* +====================================================================== +lwGetTags() + +Read tag strings from a TAGS chunk in an LWO2 file. The tags are +added to the lwTagList array. +====================================================================== */ + +int lwGetTags( idFile *fp, int cksize, lwTagList *tlist ) +{ + char *buf, *bp; + int i, len, ntags; + + if ( cksize == 0 ) return 1; + + /* read the whole chunk */ + + set_flen( 0 ); + buf = (char*)getbytes( fp, cksize ); + if ( !buf ) return 0; + + /* count the strings */ + + ntags = 0; + bp = buf; + while ( bp < buf + cksize ) { + len = strlen( bp ) + 1; + len += len & 1; + bp += len; + ++ntags; + } + + /* expand the string array to hold the new tags */ + + tlist->offset = tlist->count; + tlist->count += ntags; + char **oldtag = tlist->tag; + tlist->tag = (char**)Mem_Alloc( tlist->count * sizeof( char * ) ); + if ( !tlist->tag ) goto Fail; + if ( oldtag ) { + memcpy( tlist->tag, oldtag, tlist->offset * sizeof( char * ) ); + Mem_Free( oldtag ); + } + memset( &tlist->tag[ tlist->offset ], 0, ntags * sizeof( char * ) ); + + /* copy the new tags to the tag array */ + + bp = buf; + for ( i = 0; i < ntags; i++ ) + tlist->tag[ i + tlist->offset ] = sgetS0( (unsigned char**)&bp ); + + Mem_Free( buf ); + return 1; + +Fail: + if ( buf ) Mem_Free( buf ); + return 0; +} + + +/* +====================================================================== +lwGetPolygonTags() + +Read polygon tags from a PTAG chunk in an LWO2 file. +====================================================================== */ + +int lwGetPolygonTags( idFile *fp, int cksize, lwTagList *tlist, lwPolygonList *plist ) +{ + unsigned int type; + int rlen = 0, i, j; + + set_flen( 0 ); + type = getU4( fp ); + rlen = get_flen(); + if ( rlen < 0 ) return 0; + + if ( type != ID_SURF && type != ID_PART && type != ID_SMGP ) { + fp->Seek( cksize - 4, FS_SEEK_CUR ); + return 1; + } + + while ( rlen < cksize ) { + i = getVX( fp ) + plist->offset; + j = getVX( fp ) + tlist->offset; + rlen = get_flen(); + if ( rlen < 0 || rlen > cksize ) return 0; + + switch ( type ) { + case ID_SURF: plist->pol[ i ].surf = ( lwSurface * ) j; break; + case ID_PART: plist->pol[ i ].part = j; break; + case ID_SMGP: plist->pol[ i ].smoothgrp = j; break; + } + } + + return 1; +} + + +/* +====================================================================== +lwFreePlugin() + +Free the memory used by an lwPlugin. +====================================================================== */ + +void lwFreePlugin( lwPlugin *p ) +{ + if ( p ) { + if ( p->ord ) Mem_Free( p->ord ); + if ( p->name ) Mem_Free( p->name ); + if ( p->data ) Mem_Free( p->data ); + Mem_Free( p ); + } +} + + +/* +====================================================================== +lwFreeTexture() + +Free the memory used by an lwTexture. +====================================================================== */ + +void lwFreeTexture( lwTexture *t ) +{ + if ( t ) { + if ( t->ord ) Mem_Free( t->ord ); + switch ( t->type ) { + case ID_IMAP: + if ( t->param.imap.vmap_name ) Mem_Free( t->param.imap.vmap_name ); + break; + case ID_PROC: + if ( t->param.proc.name ) Mem_Free( t->param.proc.name ); + if ( t->param.proc.data ) Mem_Free( t->param.proc.data ); + break; + case ID_GRAD: + if ( t->param.grad.key ) Mem_Free( t->param.grad.key ); + if ( t->param.grad.ikey ) Mem_Free( t->param.grad.ikey ); + break; + } + if ( t->tmap.ref_object ) Mem_Free( t->tmap.ref_object ); + Mem_Free( t ); + } +} + + +/* +====================================================================== +lwFreeSurface() + +Free the memory used by an lwSurface. +====================================================================== */ + +void lwFreeSurface( lwSurface *surf ) +{ + if ( surf ) { + if ( surf->name ) Mem_Free( surf->name ); + if ( surf->srcname ) Mem_Free( surf->srcname ); + + lwListFree( surf->shader, (void (__cdecl *)(void *))lwFreePlugin ); + + lwListFree( surf->color.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->luminosity.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->diffuse.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->specularity.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->glossiness.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->reflection.val.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->transparency.val.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->eta.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->translucency.tex, (void (__cdecl *)(void *))lwFreeTexture ); + lwListFree( surf->bump.tex, (void (__cdecl *)(void *))lwFreeTexture ); + + Mem_Free( surf ); + } +} + + +/* +====================================================================== +lwGetTHeader() + +Read a texture map header from a SURF.BLOK in an LWO2 file. This is +the first subchunk in a BLOK, and its contents are common to all three +texture types. +====================================================================== */ + +int lwGetTHeader( idFile *fp, int hsz, lwTexture *tex ) +{ + unsigned int id; + unsigned short sz; + int pos, rlen; + + + /* remember where we started */ + + set_flen( 0 ); + pos = fp->Tell(); + + /* ordinal string */ + + tex->ord = getS0( fp ); + + /* first subchunk header */ + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) return 0; + + /* process subchunks as they're encountered */ + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_CHAN: + tex->chan = getU4( fp ); + break; + + case ID_OPAC: + tex->opac_type = getU2( fp ); + tex->opacity.val = getF4( fp ); + tex->opacity.eindex = getVX( fp ); + break; + + case ID_ENAB: + tex->enabled = getU2( fp ); + break; + + case ID_NEGA: + tex->negative = getU2( fp ); + break; + + case ID_AXIS: + tex->axis = getU2( fp ); + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the texture header subchunk? */ + + if ( hsz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) return 0; + } + + set_flen( fp->Tell() - pos ); + return 1; +} + + +/* +====================================================================== +lwGetTMap() + +Read a texture map from a SURF.BLOK in an LWO2 file. The TMAP +defines the mapping from texture to world or object coordinates. +====================================================================== */ + +int lwGetTMap( idFile *fp, int tmapsz, lwTMap *tmap ) +{ + unsigned int id; + unsigned short sz; + int rlen, pos, i; + + pos = fp->Tell(); + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) return 0; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_SIZE: + for ( i = 0; i < 3; i++ ) + tmap->size.val[ i ] = getF4( fp ); + tmap->size.eindex = getVX( fp ); + break; + + case ID_CNTR: + for ( i = 0; i < 3; i++ ) + tmap->center.val[ i ] = getF4( fp ); + tmap->center.eindex = getVX( fp ); + break; + + case ID_ROTA: + for ( i = 0; i < 3; i++ ) + tmap->rotate.val[ i ] = getF4( fp ); + tmap->rotate.eindex = getVX( fp ); + break; + + case ID_FALL: + tmap->fall_type = getU2( fp ); + for ( i = 0; i < 3; i++ ) + tmap->falloff.val[ i ] = getF4( fp ); + tmap->falloff.eindex = getVX( fp ); + break; + + case ID_OREF: + tmap->ref_object = getS0( fp ); + break; + + case ID_CSYS: + tmap->coord_sys = getU2( fp ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the TMAP subchunk? */ + + if ( tmapsz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) return 0; + } + + set_flen( fp->Tell() - pos ); + return 1; +} + + +/* +====================================================================== +lwGetImageMap() + +Read an lwImageMap from a SURF.BLOK in an LWO2 file. +====================================================================== */ + +int lwGetImageMap( idFile *fp, int rsz, lwTexture *tex ) +{ + unsigned int id; + unsigned short sz; + int rlen, pos; + + pos = fp->Tell(); + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) return 0; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( fp, sz, &tex->tmap )) return 0; + break; + + case ID_PROJ: + tex->param.imap.projection = getU2( fp ); + break; + + case ID_VMAP: + tex->param.imap.vmap_name = getS0( fp ); + break; + + case ID_AXIS: + tex->param.imap.axis = getU2( fp ); + break; + + case ID_IMAG: + tex->param.imap.cindex = getVX( fp ); + break; + + case ID_WRAP: + tex->param.imap.wrapw_type = getU2( fp ); + tex->param.imap.wraph_type = getU2( fp ); + break; + + case ID_WRPW: + tex->param.imap.wrapw.val = getF4( fp ); + tex->param.imap.wrapw.eindex = getVX( fp ); + break; + + case ID_WRPH: + tex->param.imap.wraph.val = getF4( fp ); + tex->param.imap.wraph.eindex = getVX( fp ); + break; + + case ID_AAST: + tex->param.imap.aas_flags = getU2( fp ); + tex->param.imap.aa_strength = getF4( fp ); + break; + + case ID_PIXB: + tex->param.imap.pblend = getU2( fp ); + break; + + case ID_STCK: + tex->param.imap.stck.val = getF4( fp ); + tex->param.imap.stck.eindex = getVX( fp ); + break; + + case ID_TAMP: + tex->param.imap.amplitude.val = getF4( fp ); + tex->param.imap.amplitude.eindex = getVX( fp ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the image map? */ + + if ( rsz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) return 0; + } + + set_flen( fp->Tell() - pos ); + return 1; +} + + +/* +====================================================================== +lwGetProcedural() + +Read an lwProcedural from a SURF.BLOK in an LWO2 file. +====================================================================== */ + +int lwGetProcedural( idFile *fp, int rsz, lwTexture *tex ) +{ + unsigned int id; + unsigned short sz; + int rlen, pos; + + pos = fp->Tell(); + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) return 0; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( fp, sz, &tex->tmap )) return 0; + break; + + case ID_AXIS: + tex->param.proc.axis = getU2( fp ); + break; + + case ID_VALU: + tex->param.proc.value[ 0 ] = getF4( fp ); + if ( sz >= 8 ) tex->param.proc.value[ 1 ] = getF4( fp ); + if ( sz >= 12 ) tex->param.proc.value[ 2 ] = getF4( fp ); + break; + + case ID_FUNC: + tex->param.proc.name = getS0( fp ); + rlen = get_flen(); + tex->param.proc.data = getbytes( fp, sz - rlen ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the procedural block? */ + + if ( rsz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) return 0; + } + + set_flen( fp->Tell() - pos ); + return 1; +} + + +/* +====================================================================== +lwGetGradient() + +Read an lwGradient from a SURF.BLOK in an LWO2 file. +====================================================================== */ + +int lwGetGradient( idFile *fp, int rsz, lwTexture *tex ) +{ + unsigned int id; + unsigned short sz; + int rlen, pos, i, j, nkeys; + + pos = fp->Tell(); + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) return 0; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( fp, sz, &tex->tmap )) return 0; + break; + + case ID_PNAM: + tex->param.grad.paramname = getS0( fp ); + break; + + case ID_INAM: + tex->param.grad.itemname = getS0( fp ); + break; + + case ID_GRST: + tex->param.grad.start = getF4( fp ); + break; + + case ID_GREN: + tex->param.grad.end = getF4( fp ); + break; + + case ID_GRPT: + tex->param.grad.repeat = getU2( fp ); + break; + + case ID_FKEY: + nkeys = sz / sizeof( lwGradKey ); + tex->param.grad.key = (lwGradKey*)Mem_ClearedAlloc( nkeys * sizeof( lwGradKey ) ); + if ( !tex->param.grad.key ) return 0; + for ( i = 0; i < nkeys; i++ ) { + tex->param.grad.key[ i ].value = getF4( fp ); + for ( j = 0; j < 4; j++ ) + tex->param.grad.key[ i ].rgba[ j ] = getF4( fp ); + } + break; + + case ID_IKEY: + nkeys = sz / 2; + tex->param.grad.ikey = (short*)Mem_ClearedAlloc( nkeys * sizeof( short ) ); + if ( !tex->param.grad.ikey ) return 0; + for ( i = 0; i < nkeys; i++ ) + tex->param.grad.ikey[ i ] = getU2( fp ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the gradient? */ + + if ( rsz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) return 0; + } + + set_flen( fp->Tell() - pos ); + return 1; +} + + +/* +====================================================================== +lwGetTexture() + +Read an lwTexture from a SURF.BLOK in an LWO2 file. +====================================================================== */ + +lwTexture *lwGetTexture( idFile *fp, int bloksz, unsigned int type ) +{ + lwTexture *tex; + unsigned short sz; + int ok; + + tex = (lwTexture*)Mem_ClearedAlloc( sizeof( lwTexture ) ); + if ( !tex ) return NULL; + + tex->type = type; + tex->tmap.size.val[ 0 ] = + tex->tmap.size.val[ 1 ] = + tex->tmap.size.val[ 2 ] = 1.0f; + tex->opacity.val = 1.0f; + tex->enabled = 1; + + sz = getU2( fp ); + if ( !lwGetTHeader( fp, sz, tex )) { + Mem_Free( tex ); + return NULL; + } + + sz = bloksz - sz - 6; + switch ( type ) { + case ID_IMAP: ok = lwGetImageMap( fp, sz, tex ); break; + case ID_PROC: ok = lwGetProcedural( fp, sz, tex ); break; + case ID_GRAD: ok = lwGetGradient( fp, sz, tex ); break; + default: + ok = !fp->Seek( sz, FS_SEEK_CUR ); + } + + if ( !ok ) { + lwFreeTexture( tex ); + return NULL; + } + + set_flen( bloksz ); + return tex; +} + + +/* +====================================================================== +lwGetShader() + +Read a shader record from a SURF.BLOK in an LWO2 file. +====================================================================== */ + +lwPlugin *lwGetShader( idFile *fp, int bloksz ) +{ + lwPlugin *shdr; + unsigned int id; + unsigned short sz; + int hsz, rlen, pos; + + shdr = (lwPlugin*)Mem_ClearedAlloc( sizeof( lwPlugin ) ); + if ( !shdr ) return NULL; + + pos = fp->Tell(); + set_flen( 0 ); + hsz = getU2( fp ); + shdr->ord = getS0( fp ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + while ( hsz > 0 ) { + sz += sz & 1; + hsz -= sz; + if ( id == ID_ENAB ) { + shdr->flags = getU2( fp ); + break; + } + else { + fp->Seek( sz, FS_SEEK_CUR ); + id = getU4( fp ); + sz = getU2( fp ); + } + } + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_FUNC: + shdr->name = getS0( fp ); + rlen = get_flen(); + shdr->data = getbytes( fp, sz - rlen ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the shader block? */ + + if ( bloksz <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) goto Fail; + } + + set_flen( fp->Tell() - pos ); + return shdr; + +Fail: + lwFreePlugin( shdr ); + return NULL; +} + + +/* +====================================================================== +compare_textures() +compare_shaders() + +Callbacks for the lwListInsert() function, which is called to add +textures to surface channels and shaders to surfaces. +====================================================================== */ + +static int compare_textures( lwTexture *a, lwTexture *b ) +{ + return strcmp( a->ord, b->ord ); +} + + +static int compare_shaders( lwPlugin *a, lwPlugin *b ) +{ + return strcmp( a->ord, b->ord ); +} + + +/* +====================================================================== +add_texture() + +Finds the surface channel (lwTParam or lwCParam) to which a texture is +applied, then calls lwListInsert(). +====================================================================== */ + +static int add_texture( lwSurface *surf, lwTexture *tex ) +{ + lwTexture **list; + + switch ( tex->chan ) { + case ID_COLR: list = &surf->color.tex; break; + case ID_LUMI: list = &surf->luminosity.tex; break; + case ID_DIFF: list = &surf->diffuse.tex; break; + case ID_SPEC: list = &surf->specularity.tex; break; + case ID_GLOS: list = &surf->glossiness.tex; break; + case ID_REFL: list = &surf->reflection.val.tex; break; + case ID_TRAN: list = &surf->transparency.val.tex; break; + case ID_RIND: list = &surf->eta.tex; break; + case ID_TRNL: list = &surf->translucency.tex; break; + case ID_BUMP: list = &surf->bump.tex; break; + default: return 0; + } + + lwListInsert( (void**)list, tex, (int (__cdecl *)(void *,void *))compare_textures ); + return 1; +} + + +/* +====================================================================== +lwDefaultSurface() + +Allocate and initialize a surface. +====================================================================== */ + +lwSurface *lwDefaultSurface( void ) +{ + lwSurface *surf; + + surf = (lwSurface*)Mem_ClearedAlloc( sizeof( lwSurface ) ); + if ( !surf ) return NULL; + + surf->color.rgb[ 0 ] = 0.78431f; + surf->color.rgb[ 1 ] = 0.78431f; + surf->color.rgb[ 2 ] = 0.78431f; + surf->diffuse.val = 1.0f; + surf->glossiness.val = 0.4f; + surf->bump.val = 1.0f; + surf->eta.val = 1.0f; + surf->sideflags = 1; + + return surf; +} + + +/* +====================================================================== +lwGetSurface() + +Read an lwSurface from an LWO2 file. +====================================================================== */ + +lwSurface *lwGetSurface( idFile *fp, int cksize ) +{ + lwSurface *surf; + lwTexture *tex; + lwPlugin *shdr; + unsigned int id, type; + unsigned short sz; + int pos, rlen; + + + /* allocate the Surface structure */ + + surf = (lwSurface*)Mem_ClearedAlloc( sizeof( lwSurface ) ); + if ( !surf ) goto Fail; + + /* non-zero defaults */ + + surf->color.rgb[ 0 ] = 0.78431f; + surf->color.rgb[ 1 ] = 0.78431f; + surf->color.rgb[ 2 ] = 0.78431f; + surf->diffuse.val = 1.0f; + surf->glossiness.val = 0.4f; + surf->bump.val = 1.0f; + surf->eta.val = 1.0f; + surf->sideflags = 1; + + /* remember where we started */ + + set_flen( 0 ); + pos = fp->Tell(); + + /* names */ + + surf->name = getS0( fp ); + surf->srcname = getS0( fp ); + + /* first subchunk header */ + + id = getU4( fp ); + sz = getU2( fp ); + if ( 0 > get_flen() ) goto Fail; + + /* process subchunks as they're encountered */ + + while ( 1 ) { + sz += sz & 1; + set_flen( 0 ); + + switch ( id ) { + case ID_COLR: + surf->color.rgb[ 0 ] = getF4( fp ); + surf->color.rgb[ 1 ] = getF4( fp ); + surf->color.rgb[ 2 ] = getF4( fp ); + surf->color.eindex = getVX( fp ); + break; + + case ID_LUMI: + surf->luminosity.val = getF4( fp ); + surf->luminosity.eindex = getVX( fp ); + break; + + case ID_DIFF: + surf->diffuse.val = getF4( fp ); + surf->diffuse.eindex = getVX( fp ); + break; + + case ID_SPEC: + surf->specularity.val = getF4( fp ); + surf->specularity.eindex = getVX( fp ); + break; + + case ID_GLOS: + surf->glossiness.val = getF4( fp ); + surf->glossiness.eindex = getVX( fp ); + break; + + case ID_REFL: + surf->reflection.val.val = getF4( fp ); + surf->reflection.val.eindex = getVX( fp ); + break; + + case ID_RFOP: + surf->reflection.options = getU2( fp ); + break; + + case ID_RIMG: + surf->reflection.cindex = getVX( fp ); + break; + + case ID_RSAN: + surf->reflection.seam_angle = getF4( fp ); + break; + + case ID_TRAN: + surf->transparency.val.val = getF4( fp ); + surf->transparency.val.eindex = getVX( fp ); + break; + + case ID_TROP: + surf->transparency.options = getU2( fp ); + break; + + case ID_TIMG: + surf->transparency.cindex = getVX( fp ); + break; + + case ID_RIND: + surf->eta.val = getF4( fp ); + surf->eta.eindex = getVX( fp ); + break; + + case ID_TRNL: + surf->translucency.val = getF4( fp ); + surf->translucency.eindex = getVX( fp ); + break; + + case ID_BUMP: + surf->bump.val = getF4( fp ); + surf->bump.eindex = getVX( fp ); + break; + + case ID_SMAN: + surf->smooth = getF4( fp ); + break; + + case ID_SIDE: + surf->sideflags = getU2( fp ); + break; + + case ID_CLRH: + surf->color_hilite.val = getF4( fp ); + surf->color_hilite.eindex = getVX( fp ); + break; + + case ID_CLRF: + surf->color_filter.val = getF4( fp ); + surf->color_filter.eindex = getVX( fp ); + break; + + case ID_ADTR: + surf->add_trans.val = getF4( fp ); + surf->add_trans.eindex = getVX( fp ); + break; + + case ID_SHRP: + surf->dif_sharp.val = getF4( fp ); + surf->dif_sharp.eindex = getVX( fp ); + break; + + case ID_GVAL: + surf->glow.val = getF4( fp ); + surf->glow.eindex = getVX( fp ); + break; + + case ID_LINE: + surf->line.enabled = 1; + if ( sz >= 2 ) surf->line.flags = getU2( fp ); + if ( sz >= 6 ) surf->line.size.val = getF4( fp ); + if ( sz >= 8 ) surf->line.size.eindex = getVX( fp ); + break; + + case ID_ALPH: + surf->alpha_mode = getU2( fp ); + surf->alpha = getF4( fp ); + break; + + case ID_AVAL: + surf->alpha = getF4( fp ); + break; + + case ID_BLOK: + type = getU4( fp ); + + switch ( type ) { + case ID_IMAP: + case ID_PROC: + case ID_GRAD: + tex = lwGetTexture( fp, sz - 4, type ); + if ( !tex ) goto Fail; + if ( !add_texture( surf, tex )) + lwFreeTexture( tex ); + set_flen( 4 + get_flen() ); + break; + case ID_SHDR: + shdr = lwGetShader( fp, sz - 4 ); + if ( !shdr ) goto Fail; + lwListInsert( (void**)&surf->shader, shdr, (int (__cdecl *)(void *,void *))compare_shaders ); + ++surf->nshaders; + set_flen( 4 + get_flen() ); + break; + } + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = get_flen(); + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + fp->Seek( sz - rlen, FS_SEEK_CUR ); + + /* end of the SURF chunk? */ + + if ( cksize <= fp->Tell() - pos ) + break; + + /* get the next subchunk header */ + + set_flen( 0 ); + id = getU4( fp ); + sz = getU2( fp ); + if ( 6 != get_flen() ) goto Fail; + } + + return surf; + +Fail: + if ( surf ) lwFreeSurface( surf ); + return NULL; +} + + +float dot( float a[], float b[] ) +{ + return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ]; +} + + +void cross( float a[], float b[], float c[] ) +{ + c[ 0 ] = a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ]; + c[ 1 ] = a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ]; + c[ 2 ] = a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ]; +} + + +void normalize( float v[] ) +{ + float r; + + r = ( float ) idMath::Sqrt( dot( v, v )); + if ( r > 0 ) { + v[ 0 ] /= r; + v[ 1 ] /= r; + v[ 2 ] /= r; + } +} + +/* +====================================================================== +lwFreeVMap() + +Free memory used by an lwVMap. +====================================================================== */ + +void lwFreeVMap( lwVMap *vmap ) +{ + if ( vmap ) { + if ( vmap->name ) Mem_Free( vmap->name ); + if ( vmap->vindex ) Mem_Free( vmap->vindex ); + if ( vmap->pindex ) Mem_Free( vmap->pindex ); + if ( vmap->val ) { + if ( vmap->val[ 0 ] ) Mem_Free( vmap->val[ 0 ] ); + Mem_Free( vmap->val ); + } + Mem_Free( vmap ); + } +} + + +/* +====================================================================== +lwGetVMap() + +Read an lwVMap from a VMAP or VMAD chunk in an LWO2. +====================================================================== */ + +lwVMap *lwGetVMap( idFile *fp, int cksize, int ptoffset, int poloffset, + int perpoly ) +{ + unsigned char *buf, *bp; + lwVMap *vmap; + float *f; + int i, j, npts, rlen; + + + /* read the whole chunk */ + + set_flen( 0 ); + buf = (unsigned char*)getbytes( fp, cksize ); + if ( !buf ) return NULL; + + vmap = (lwVMap*)Mem_ClearedAlloc( sizeof( lwVMap ) ); + if ( !vmap ) { + Mem_Free( buf ); + return NULL; + } + + /* initialize the vmap */ + + vmap->perpoly = perpoly; + + bp = buf; + set_flen( 0 ); + vmap->type = sgetU4( &bp ); + vmap->dim = sgetU2( &bp ); + vmap->name = sgetS0( &bp ); + rlen = get_flen(); + + /* count the vmap records */ + + npts = 0; + while ( bp < buf + cksize ) { + i = sgetVX( &bp ); + if ( perpoly ) + i = sgetVX( &bp ); + bp += vmap->dim * sizeof( float ); + ++npts; + } + + /* allocate the vmap */ + + vmap->nverts = npts; + vmap->vindex = (int*)Mem_ClearedAlloc( npts * sizeof( int ) ); + if ( !vmap->vindex ) goto Fail; + if ( perpoly ) { + vmap->pindex = (int*)Mem_ClearedAlloc( npts * sizeof( int ) ); + if ( !vmap->pindex ) goto Fail; + } + + if ( vmap->dim > 0 ) { + vmap->val = (float**)Mem_ClearedAlloc( npts * sizeof( float * ) ); + if ( !vmap->val ) goto Fail; + f = (float*)Mem_ClearedAlloc( npts * vmap->dim * sizeof( float ) ); + if ( !f ) goto Fail; + for ( i = 0; i < npts; i++ ) + vmap->val[ i ] = f + i * vmap->dim; + } + + /* fill in the vmap values */ + + bp = buf + rlen; + for ( i = 0; i < npts; i++ ) { + vmap->vindex[ i ] = sgetVX( &bp ); + if ( perpoly ) + vmap->pindex[ i ] = sgetVX( &bp ); + for ( j = 0; j < vmap->dim; j++ ) + vmap->val[ i ][ j ] = sgetF4( &bp ); + } + + Mem_Free( buf ); + return vmap; + +Fail: + if ( buf ) Mem_Free( buf ); + lwFreeVMap( vmap ); + return NULL; +} + + +/* +====================================================================== +lwGetPointVMaps() + +Fill in the lwVMapPt structure for each point. +====================================================================== */ + +int lwGetPointVMaps( lwPointList *point, lwVMap *vmap ) +{ + lwVMap *vm; + int i, j, n; + + /* count the number of vmap values for each point */ + + vm = vmap; + while ( vm ) { + if ( !vm->perpoly ) + for ( i = 0; i < vm->nverts; i++ ) + ++point->pt[ vm->vindex[ i ]].nvmaps; + vm = vm->next; + } + + /* allocate vmap references for each mapped point */ + + for ( i = 0; i < point->count; i++ ) { + if ( point->pt[ i ].nvmaps ) { + point->pt[ i ].vm = (lwVMapPt*)Mem_ClearedAlloc( point->pt[ i ].nvmaps * sizeof( lwVMapPt ) ); + if ( !point->pt[ i ].vm ) return 0; + point->pt[ i ].nvmaps = 0; + } + } + + /* fill in vmap references for each mapped point */ + + vm = vmap; + while ( vm ) { + if ( !vm->perpoly ) { + for ( i = 0; i < vm->nverts; i++ ) { + j = vm->vindex[ i ]; + n = point->pt[ j ].nvmaps; + point->pt[ j ].vm[ n ].vmap = vm; + point->pt[ j ].vm[ n ].index = i; + ++point->pt[ j ].nvmaps; + } + } + vm = vm->next; + } + + return 1; +} + + +/* +====================================================================== +lwGetPolyVMaps() + +Fill in the lwVMapPt structure for each polygon vertex. +====================================================================== */ + +int lwGetPolyVMaps( lwPolygonList *polygon, lwVMap *vmap ) +{ + lwVMap *vm; + lwPolVert *pv; + int i, j; + + /* count the number of vmap values for each polygon vertex */ + + vm = vmap; + while ( vm ) { + if ( vm->perpoly ) { + for ( i = 0; i < vm->nverts; i++ ) { + for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) { + pv = &polygon->pol[ vm->pindex[ i ]].v[ j ]; + if ( vm->vindex[ i ] == pv->index ) { + ++pv->nvmaps; + break; + } + } + } + } + vm = vm->next; + } + + /* allocate vmap references for each mapped vertex */ + + for ( i = 0; i < polygon->count; i++ ) { + for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) { + pv = &polygon->pol[ i ].v[ j ]; + if ( pv->nvmaps ) { + pv->vm = (lwVMapPt*)Mem_ClearedAlloc( pv->nvmaps * sizeof( lwVMapPt ) ); + if ( !pv->vm ) return 0; + pv->nvmaps = 0; + } + } + } + + /* fill in vmap references for each mapped point */ + + vm = vmap; + while ( vm ) { + if ( vm->perpoly ) { + for ( i = 0; i < vm->nverts; i++ ) { + for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) { + pv = &polygon->pol[ vm->pindex[ i ]].v[ j ]; + if ( vm->vindex[ i ] == pv->index ) { + pv->vm[ pv->nvmaps ].vmap = vm; + pv->vm[ pv->nvmaps ].index = i; + ++pv->nvmaps; + break; + } + } + } + } + vm = vm->next; + } + + return 1; +} diff --git a/renderer/Model_lwo.h b/renderer/Model_lwo.h new file mode 100644 index 000000000..9e6204a86 --- /dev/null +++ b/renderer/Model_lwo.h @@ -0,0 +1,667 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LWO2_H__ +#define __LWO2_H__ + +/* +====================================================================== + + LWO2 loader. (LightWave Object) + + Ernie Wright 17 Sep 00 + +====================================================================== +*/ + +/* chunk and subchunk IDs */ + +#define LWID_(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) + +#define ID_FORM LWID_('F','O','R','M') +#define ID_LWO2 LWID_('L','W','O','2') +#define ID_LWOB LWID_('L','W','O','B') + +/* top-level chunks */ +#define ID_LAYR LWID_('L','A','Y','R') +#define ID_TAGS LWID_('T','A','G','S') +#define ID_PNTS LWID_('P','N','T','S') +#define ID_BBOX LWID_('B','B','O','X') +#define ID_VMAP LWID_('V','M','A','P') +#define ID_VMAD LWID_('V','M','A','D') +#define ID_POLS LWID_('P','O','L','S') +#define ID_PTAG LWID_('P','T','A','G') +#define ID_ENVL LWID_('E','N','V','L') +#define ID_CLIP LWID_('C','L','I','P') +#define ID_SURF LWID_('S','U','R','F') +#define ID_DESC LWID_('D','E','S','C') +#define ID_TEXT LWID_('T','E','X','T') +#define ID_ICON LWID_('I','C','O','N') + +/* polygon types */ +#define ID_FACE LWID_('F','A','C','E') +#define ID_CURV LWID_('C','U','R','V') +#define ID_PTCH LWID_('P','T','C','H') +#define ID_MBAL LWID_('M','B','A','L') +#define ID_BONE LWID_('B','O','N','E') + +/* polygon tags */ +#define ID_SURF LWID_('S','U','R','F') +#define ID_PART LWID_('P','A','R','T') +#define ID_SMGP LWID_('S','M','G','P') + +/* envelopes */ +#define ID_PRE LWID_('P','R','E',' ') +#define ID_POST LWID_('P','O','S','T') +#define ID_KEY LWID_('K','E','Y',' ') +#define ID_SPAN LWID_('S','P','A','N') +#define ID_TCB LWID_('T','C','B',' ') +#define ID_HERM LWID_('H','E','R','M') +#define ID_BEZI LWID_('B','E','Z','I') +#define ID_BEZ2 LWID_('B','E','Z','2') +#define ID_LINE LWID_('L','I','N','E') +#define ID_STEP LWID_('S','T','E','P') + +/* clips */ +#define ID_STIL LWID_('S','T','I','L') +#define ID_ISEQ LWID_('I','S','E','Q') +#define ID_ANIM LWID_('A','N','I','M') +#define ID_XREF LWID_('X','R','E','F') +#define ID_STCC LWID_('S','T','C','C') +#define ID_TIME LWID_('T','I','M','E') +#define ID_CONT LWID_('C','O','N','T') +#define ID_BRIT LWID_('B','R','I','T') +#define ID_SATR LWID_('S','A','T','R') +#define ID_HUE LWID_('H','U','E',' ') +#define ID_GAMM LWID_('G','A','M','M') +#define ID_NEGA LWID_('N','E','G','A') +#define ID_IFLT LWID_('I','F','L','T') +#define ID_PFLT LWID_('P','F','L','T') + +/* surfaces */ +#define ID_COLR LWID_('C','O','L','R') +#define ID_LUMI LWID_('L','U','M','I') +#define ID_DIFF LWID_('D','I','F','F') +#define ID_SPEC LWID_('S','P','E','C') +#define ID_GLOS LWID_('G','L','O','S') +#define ID_REFL LWID_('R','E','F','L') +#define ID_RFOP LWID_('R','F','O','P') +#define ID_RIMG LWID_('R','I','M','G') +#define ID_RSAN LWID_('R','S','A','N') +#define ID_TRAN LWID_('T','R','A','N') +#define ID_TROP LWID_('T','R','O','P') +#define ID_TIMG LWID_('T','I','M','G') +#define ID_RIND LWID_('R','I','N','D') +#define ID_TRNL LWID_('T','R','N','L') +#define ID_BUMP LWID_('B','U','M','P') +#define ID_SMAN LWID_('S','M','A','N') +#define ID_SIDE LWID_('S','I','D','E') +#define ID_CLRH LWID_('C','L','R','H') +#define ID_CLRF LWID_('C','L','R','F') +#define ID_ADTR LWID_('A','D','T','R') +#define ID_SHRP LWID_('S','H','R','P') +#define ID_LINE LWID_('L','I','N','E') +#define ID_LSIZ LWID_('L','S','I','Z') +#define ID_ALPH LWID_('A','L','P','H') +#define ID_AVAL LWID_('A','V','A','L') +#define ID_GVAL LWID_('G','V','A','L') +#define ID_BLOK LWID_('B','L','O','K') + +/* texture layer */ +#define ID_TYPE LWID_('T','Y','P','E') +#define ID_CHAN LWID_('C','H','A','N') +#define ID_NAME LWID_('N','A','M','E') +#define ID_ENAB LWID_('E','N','A','B') +#define ID_OPAC LWID_('O','P','A','C') +#define ID_FLAG LWID_('F','L','A','G') +#define ID_PROJ LWID_('P','R','O','J') +#define ID_STCK LWID_('S','T','C','K') +#define ID_TAMP LWID_('T','A','M','P') + +/* texture coordinates */ +#define ID_TMAP LWID_('T','M','A','P') +#define ID_AXIS LWID_('A','X','I','S') +#define ID_CNTR LWID_('C','N','T','R') +#define ID_SIZE LWID_('S','I','Z','E') +#define ID_ROTA LWID_('R','O','T','A') +#define ID_OREF LWID_('O','R','E','F') +#define ID_FALL LWID_('F','A','L','L') +#define ID_CSYS LWID_('C','S','Y','S') + +/* image map */ +#define ID_IMAP LWID_('I','M','A','P') +#define ID_IMAG LWID_('I','M','A','G') +#define ID_WRAP LWID_('W','R','A','P') +#define ID_WRPW LWID_('W','R','P','W') +#define ID_WRPH LWID_('W','R','P','H') +#define ID_VMAP LWID_('V','M','A','P') +#define ID_AAST LWID_('A','A','S','T') +#define ID_PIXB LWID_('P','I','X','B') + +/* procedural */ +#define ID_PROC LWID_('P','R','O','C') +#define ID_COLR LWID_('C','O','L','R') +#define ID_VALU LWID_('V','A','L','U') +#define ID_FUNC LWID_('F','U','N','C') +#define ID_FTPS LWID_('F','T','P','S') +#define ID_ITPS LWID_('I','T','P','S') +#define ID_ETPS LWID_('E','T','P','S') + +/* gradient */ +#define ID_GRAD LWID_('G','R','A','D') +#define ID_GRST LWID_('G','R','S','T') +#define ID_GREN LWID_('G','R','E','N') +#define ID_PNAM LWID_('P','N','A','M') +#define ID_INAM LWID_('I','N','A','M') +#define ID_GRPT LWID_('G','R','P','T') +#define ID_FKEY LWID_('F','K','E','Y') +#define ID_IKEY LWID_('I','K','E','Y') + +/* shader */ +#define ID_SHDR LWID_('S','H','D','R') +#define ID_DATA LWID_('D','A','T','A') + + +/* generic linked list */ + +typedef struct st_lwNode { + struct st_lwNode *next, *prev; + void *data; +} lwNode; + + +/* plug-in reference */ + +typedef struct st_lwPlugin { + struct st_lwPlugin *next, *prev; + char *ord; + char *name; + int flags; + void *data; +} lwPlugin; + + +/* envelopes */ + +typedef struct st_lwKey { + struct st_lwKey *next, *prev; + float value; + float time; + unsigned int shape; /* ID_TCB, ID_BEZ2, etc. */ + float tension; + float continuity; + float bias; + float param[ 4 ]; +} lwKey; + +typedef struct st_lwEnvelope { + struct st_lwEnvelope *next, *prev; + int index; + int type; + char *name; + lwKey *key; /* linked list of keys */ + int nkeys; + int behavior[ 2 ]; /* pre and post (extrapolation) */ + lwPlugin *cfilter; /* linked list of channel filters */ + int ncfilters; +} lwEnvelope; + +#define BEH_RESET 0 +#define BEH_CONSTANT 1 +#define BEH_REPEAT 2 +#define BEH_OSCILLATE 3 +#define BEH_OFFSET 4 +#define BEH_LINEAR 5 + + +/* values that can be enveloped */ + +typedef struct st_lwEParam { + float val; + int eindex; +} lwEParam; + +typedef struct st_lwVParam { + float val[ 3 ]; + int eindex; +} lwVParam; + + +/* clips */ + +typedef struct st_lwClipStill { + char *name; +} lwClipStill; + +typedef struct st_lwClipSeq { + char *prefix; /* filename before sequence digits */ + char *suffix; /* after digits, e.g. extensions */ + int digits; + int flags; + int offset; + int start; + int end; +} lwClipSeq; + +typedef struct st_lwClipAnim { + char *name; + char *server; /* anim loader plug-in */ + void *data; +} lwClipAnim; + +typedef struct st_lwClipXRef { + char *string; + int index; + struct st_lwClip *clip; +} lwClipXRef; + +typedef struct st_lwClipCycle { + char *name; + int lo; + int hi; +} lwClipCycle; + +typedef struct st_lwClip { + struct st_lwClip *next, *prev; + int index; + unsigned int type; /* ID_STIL, ID_ISEQ, etc. */ + union { + lwClipStill still; + lwClipSeq seq; + lwClipAnim anim; + lwClipXRef xref; + lwClipCycle cycle; + } source; + float start_time; + float duration; + float frame_rate; + lwEParam contrast; + lwEParam brightness; + lwEParam saturation; + lwEParam hue; + lwEParam gamma; + int negative; + lwPlugin *ifilter; /* linked list of image filters */ + int nifilters; + lwPlugin *pfilter; /* linked list of pixel filters */ + int npfilters; +} lwClip; + + +/* textures */ + +typedef struct st_lwTMap { + lwVParam size; + lwVParam center; + lwVParam rotate; + lwVParam falloff; + int fall_type; + char *ref_object; + int coord_sys; +} lwTMap; + +typedef struct st_lwImageMap { + int cindex; + int projection; + char *vmap_name; + int axis; + int wrapw_type; + int wraph_type; + lwEParam wrapw; + lwEParam wraph; + float aa_strength; + int aas_flags; + int pblend; + lwEParam stck; + lwEParam amplitude; +} lwImageMap; + +#define PROJ_PLANAR 0 +#define PROJ_CYLINDRICAL 1 +#define PROJ_SPHERICAL 2 +#define PROJ_CUBIC 3 +#define PROJ_FRONT 4 + +#define WRAP_NONE 0 +#define WRAP_EDGE 1 +#define WRAP_REPEAT 2 +#define WRAP_MIRROR 3 + +typedef struct st_lwProcedural { + int axis; + float value[ 3 ]; + char *name; + void *data; +} lwProcedural; + +typedef struct st_lwGradKey { + struct st_lwGradKey *next, *prev; + float value; + float rgba[ 4 ]; +} lwGradKey; + +typedef struct st_lwGradient { + char *paramname; + char *itemname; + float start; + float end; + int repeat; + lwGradKey *key; /* array of gradient keys */ + short *ikey; /* array of interpolation codes */ +} lwGradient; + +typedef struct st_lwTexture { + struct st_lwTexture *next, *prev; + char *ord; + unsigned int type; + unsigned int chan; + lwEParam opacity; + short opac_type; + short enabled; + short negative; + short axis; + union { + lwImageMap imap; + lwProcedural proc; + lwGradient grad; + } param; + lwTMap tmap; +} lwTexture; + + +/* values that can be textured */ + +typedef struct st_lwTParam { + float val; + int eindex; + lwTexture *tex; /* linked list of texture layers */ +} lwTParam; + +typedef struct st_lwCParam { + float rgb[ 3 ]; + int eindex; + lwTexture *tex; /* linked list of texture layers */ +} lwCParam; + + +/* surfaces */ + +typedef struct st_lwGlow { + short enabled; + short type; + lwEParam intensity; + lwEParam size; +} Glow; + +typedef struct st_lwRMap { + lwTParam val; + int options; + int cindex; + float seam_angle; +} lwRMap; + +typedef struct st_lwLine { + short enabled; + unsigned short flags; + lwEParam size; +} lwLine; + +typedef struct st_lwSurface { + struct st_lwSurface *next, *prev; + char *name; + char *srcname; + lwCParam color; + lwTParam luminosity; + lwTParam diffuse; + lwTParam specularity; + lwTParam glossiness; + lwRMap reflection; + lwRMap transparency; + lwTParam eta; + lwTParam translucency; + lwTParam bump; + float smooth; + int sideflags; + float alpha; + int alpha_mode; + lwEParam color_hilite; + lwEParam color_filter; + lwEParam add_trans; + lwEParam dif_sharp; + lwEParam glow; + lwLine line; + lwPlugin *shader; /* linked list of shaders */ + int nshaders; +} lwSurface; + + +/* vertex maps */ + +typedef struct st_lwVMap { + struct st_lwVMap *next, *prev; + char *name; + unsigned int type; + int dim; + int nverts; + int perpoly; + int *vindex; /* array of point indexes */ + int *pindex; /* array of polygon indexes */ + float **val; + + // added by duffy + int offset; +} lwVMap; + +typedef struct st_lwVMapPt { + lwVMap *vmap; + int index; /* vindex or pindex element */ +} lwVMapPt; + + +/* points and polygons */ + +typedef struct st_lwPoint { + float pos[ 3 ]; + int npols; /* number of polygons sharing the point */ + int *pol; /* array of polygon indexes */ + int nvmaps; + lwVMapPt *vm; /* array of vmap references */ +} lwPoint; + +typedef struct st_lwPolVert { + int index; /* index into the point array */ + float norm[ 3 ]; + int nvmaps; + lwVMapPt *vm; /* array of vmap references */ +} lwPolVert; + +typedef struct st_lwPolygon { + lwSurface *surf; + int part; /* part index */ + int smoothgrp; /* smoothing group */ + int flags; + unsigned int type; + float norm[ 3 ]; + int nverts; + lwPolVert *v; /* array of vertex records */ +} lwPolygon; + +typedef struct st_lwPointList { + int count; + int offset; /* only used during reading */ + lwPoint *pt; /* array of points */ +} lwPointList; + +typedef struct st_lwPolygonList { + int count; + int offset; /* only used during reading */ + int vcount; /* total number of vertices */ + int voffset; /* only used during reading */ + lwPolygon *pol; /* array of polygons */ +} lwPolygonList; + + +/* geometry layers */ + +typedef struct st_lwLayer { + struct st_lwLayer *next, *prev; + char *name; + int index; + int parent; + int flags; + float pivot[ 3 ]; + float bbox[ 6 ]; + lwPointList point; + lwPolygonList polygon; + int nvmaps; + lwVMap *vmap; /* linked list of vmaps */ +} lwLayer; + + +/* tag strings */ + +typedef struct st_lwTagList { + int count; + int offset; /* only used during reading */ + char **tag; /* array of strings */ +} lwTagList; + + +/* an object */ + +typedef struct st_lwObject { + ID_TIME_T timeStamp; + lwLayer * layer; /* linked list of layers */ + lwEnvelope * env; /* linked list of envelopes */ + lwClip * clip; /* linked list of clips */ + lwSurface * surf; /* linked list of surfaces */ + lwTagList taglist; + int nlayers; + int nenvs; + int nclips; + int nsurfs; +} lwObject; + + +/* lwo2.c */ + +lwObject *lwGetObject( const char *filename, unsigned int *failID, int *failpos ); +void lwFreeObject( lwObject *object ); +void lwFreeLayer( lwLayer *layer ); + +/* pntspols.c */ + +void lwFreePoints( lwPointList *point ); +void lwFreePolygons( lwPolygonList *plist ); +int lwGetPoints( idFile *fp, int cksize, lwPointList *point ); +void lwGetBoundingBox( lwPointList *point, float bbox[] ); +int lwAllocPolygons( lwPolygonList *plist, int npols, int nverts ); +int lwGetPolygons( idFile *fp, int cksize, lwPolygonList *plist, int ptoffset ); +void lwGetPolyNormals( lwPointList *point, lwPolygonList *polygon ); +int lwGetPointPolygons( lwPointList *point, lwPolygonList *polygon ); +int lwResolvePolySurfaces( lwPolygonList *polygon, lwTagList *tlist, + lwSurface **surf, int *nsurfs ); +void lwGetVertNormals( lwPointList *point, lwPolygonList *polygon ); +void lwFreeTags( lwTagList *tlist ); +int lwGetTags( idFile *fp, int cksize, lwTagList *tlist ); +int lwGetPolygonTags( idFile *fp, int cksize, lwTagList *tlist, + lwPolygonList *plist ); + +/* vmap.c */ + +void lwFreeVMap( lwVMap *vmap ); +lwVMap *lwGetVMap( idFile *fp, int cksize, int ptoffset, int poloffset, + int perpoly ); +int lwGetPointVMaps( lwPointList *point, lwVMap *vmap ); +int lwGetPolyVMaps( lwPolygonList *polygon, lwVMap *vmap ); + +/* clip.c */ + +void lwFreeClip( lwClip *clip ); +lwClip *lwGetClip( idFile *fp, int cksize ); +lwClip *lwFindClip( lwClip *list, int index ); + +/* envelope.c */ + +void lwFreeEnvelope( lwEnvelope *env ); +lwEnvelope *lwGetEnvelope( idFile *fp, int cksize ); +lwEnvelope *lwFindEnvelope( lwEnvelope *list, int index ); +float lwEvalEnvelope( lwEnvelope *env, float time ); + +/* surface.c */ + +void lwFreePlugin( lwPlugin *p ); +void lwFreeTexture( lwTexture *t ); +void lwFreeSurface( lwSurface *surf ); +int lwGetTHeader( idFile *fp, int hsz, lwTexture *tex ); +int lwGetTMap( idFile *fp, int tmapsz, lwTMap *tmap ); +int lwGetImageMap( idFile *fp, int rsz, lwTexture *tex ); +int lwGetProcedural( idFile *fp, int rsz, lwTexture *tex ); +int lwGetGradient( idFile *fp, int rsz, lwTexture *tex ); +lwTexture *lwGetTexture( idFile *fp, int bloksz, unsigned int type ); +lwPlugin *lwGetShader( idFile *fp, int bloksz ); +lwSurface *lwGetSurface( idFile *fp, int cksize ); +lwSurface *lwDefaultSurface( void ); + +/* lwob.c */ + +lwSurface *lwGetSurface5( idFile *fp, int cksize, lwObject *obj ); +int lwGetPolygons5( idFile *fp, int cksize, lwPolygonList *plist, int ptoffset ); +lwObject *lwGetObject5( const char *filename, unsigned int *failID, int *failpos ); + +/* list.c */ + +void lwListFree( void *list, void ( *freeNode )( void * )); +void lwListAdd( void **list, void *node ); +void lwListInsert( void **vlist, void *vitem, + int ( *compare )( void *, void * )); + +/* vecmath.c */ + +float dot( float a[], float b[] ); +void cross( float a[], float b[], float c[] ); +void normalize( float v[] ); +#define vecangle( a, b ) ( float ) idMath::ACos( dot( a, b ) ) + +/* lwio.c */ + +void set_flen( int i ); +int get_flen( void ); +void *getbytes( idFile *fp, int size ); +void skipbytes( idFile *fp, int n ); +int getI1( idFile *fp ); +short getI2( idFile *fp ); +int getI4( idFile *fp ); +unsigned char getU1( idFile *fp ); +unsigned short getU2( idFile *fp ); +unsigned int getU4( idFile *fp ); +int getVX( idFile *fp ); +float getF4( idFile *fp ); +char *getS0( idFile *fp ); +int sgetI1( unsigned char **bp ); +short sgetI2( unsigned char **bp ); +int sgetI4( unsigned char **bp ); +unsigned char sgetU1( unsigned char **bp ); +unsigned short sgetU2( unsigned char **bp ); +unsigned int sgetU4( unsigned char **bp ); +int sgetVX( unsigned char **bp ); +float sgetF4( unsigned char **bp ); +char *sgetS0( unsigned char **bp ); + +#endif /* !__LWO2_H__ */ diff --git a/renderer/Model_ma.cpp b/renderer/Model_ma.cpp new file mode 100644 index 000000000..f8dd9b2ad --- /dev/null +++ b/renderer/Model_ma.cpp @@ -0,0 +1,1098 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Model_ma.h" + +/* +====================================================================== + + Parses Maya ASCII files. + +====================================================================== +*/ + + +#define MA_VERBOSE( x ) { if ( maGlobal.verbose ) { common->Printf x ; } } + +// working variables used during parsing +typedef struct { + bool verbose; + maModel_t *model; + maObject_t *currentObject; +} ma_t; + +static ma_t maGlobal; + + +void MA_ParseNodeHeader(idParser& parser, maNodeHeader_t* header) { + + memset(header, 0, sizeof(maNodeHeader_t)); + + idToken token; + while(parser.ReadToken(&token)) { + if(!token.Icmp("-")) { + parser.ReadToken(&token); + if (!token.Icmp("n")) { + parser.ReadToken(&token); + strcpy(header->name, token.c_str()); + } else if (!token.Icmp("p")) { + parser.ReadToken(&token); + strcpy(header->parent, token.c_str()); + } + } else if (!token.Icmp(";")) { + break; + } + } +} + +bool MA_ParseHeaderIndex(maAttribHeader_t* header, int& minIndex, int& maxIndex, const char* headerType, const char* skipString) { + + idParser miniParse; + idToken token; + + miniParse.LoadMemory(header->name, strlen(header->name), headerType); + if(skipString) { + miniParse.SkipUntilString(skipString); + } + + if(!miniParse.SkipUntilString("[")) { + //This was just a header + return false; + } + minIndex = miniParse.ParseInt(); + miniParse.ReadToken(&token); + if(!token.Icmp("]")) { + maxIndex = minIndex; + } else { + maxIndex = miniParse.ParseInt(); + } + return true; +} + +bool MA_ParseAttribHeader(idParser &parser, maAttribHeader_t* header) { + + idToken token; + + memset(header, 0, sizeof(maAttribHeader_t)); + + parser.ReadToken(&token); + if(!token.Icmp("-")) { + parser.ReadToken(&token); + if (!token.Icmp("s")) { + header->size = parser.ParseInt(); + parser.ReadToken(&token); + } + } + strcpy(header->name, token.c_str()); + return true; +} + +bool MA_ReadVec3(idParser& parser, idVec3& vec) { + idToken token; + if(!parser.SkipUntilString("double3")) { + throw idException( va("Maya Loader '%s': Invalid Vec3", parser.GetFileName()) ); + return false; + } + + + //We need to flip y and z because of the maya coordinate system + vec.x = parser.ParseFloat(); + vec.z = parser.ParseFloat(); + vec.y = parser.ParseFloat(); + + return true; +} + +bool IsNodeComplete(idToken& token) { + if(!token.Icmp("createNode") || !token.Icmp("connectAttr") || !token.Icmp("select")) { + return true; + } + return false; +} + +bool MA_ParseTransform(idParser& parser) { + + maNodeHeader_t header; + maTransform_t* transform; + memset(&header, 0, sizeof(header)); + + //Allocate room for the transform + transform = (maTransform_t *)Mem_Alloc( sizeof( maTransform_t ) ); + memset(transform, 0, sizeof(maTransform_t)); + transform->scale.x = transform->scale.y = transform->scale.z = 1; + + //Get the header info from the transform + MA_ParseNodeHeader(parser, &header); + + //Read the transform attributes + idToken token; + while(parser.ReadToken(&token)) { + if(IsNodeComplete(token)) { + parser.UnreadToken(&token); + break; + } + if(!token.Icmp("setAttr")) { + parser.ReadToken(&token); + if(!token.Icmp(".t")) { + if(!MA_ReadVec3(parser, transform->translate)) { + return false; + } + transform->translate.y *= -1; + } else if (!token.Icmp(".r")) { + if(!MA_ReadVec3(parser, transform->rotate)) { + return false; + } + } else if (!token.Icmp(".s")) { + if(!MA_ReadVec3(parser, transform->scale)) { + return false; + } + } else { + parser.SkipRestOfLine(); + } + } + } + + if(header.parent[0] != 0) { + //Find the parent + maTransform_t** parent; + maGlobal.model->transforms.Get(header.parent, &parent); + if(parent) { + transform->parent = *parent; + } + } + + //Add this transform to the list + maGlobal.model->transforms.Set(header.name, transform); + return true; +} + +bool MA_ParseVertex(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->vertexes) { + pMesh->numVertexes = header->size; + pMesh->vertexes = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numVertexes ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "VertexHeader", NULL)) { + //This was just a header + return true; + } + + //Read each vert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->vertexes[i].x = parser.ParseFloat(); + pMesh->vertexes[i].z = parser.ParseFloat(); + pMesh->vertexes[i].y = -parser.ParseFloat(); + } + + return true; +} + +bool MA_ParseVertexTransforms(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->vertTransforms) { + if(header->size == 0) { + header->size = 1; + } + + pMesh->numVertTransforms = header->size; + pMesh->vertTransforms = (idVec4 *)Mem_Alloc( sizeof( idVec4 ) * pMesh->numVertTransforms ); + pMesh->nextVertTransformIndex = 0; + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "VertexTransformHeader", NULL)) { + //This was just a header + return true; + } + + parser.ReadToken(&token); + if(!token.Icmp("-")) { + idToken tk2; + parser.ReadToken(&tk2); + if(!tk2.Icmp("type")) { + parser.SkipUntilString("float3"); + } else { + parser.UnreadToken(&tk2); + parser.UnreadToken(&token); + } + } else { + parser.UnreadToken(&token); + } + + //Read each vert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->vertTransforms[pMesh->nextVertTransformIndex].x = parser.ParseFloat(); + pMesh->vertTransforms[pMesh->nextVertTransformIndex].z = parser.ParseFloat(); + pMesh->vertTransforms[pMesh->nextVertTransformIndex].y = -parser.ParseFloat(); + + //w hold the vert index + pMesh->vertTransforms[pMesh->nextVertTransformIndex].w = i; + + pMesh->nextVertTransformIndex++; + } + + return true; +} + +bool MA_ParseEdge(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->edges) { + pMesh->numEdges = header->size; + pMesh->edges = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numEdges ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "EdgeHeader", NULL)) { + //This was just a header + return true; + } + + //Read each vert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->edges[i].x = parser.ParseFloat(); + pMesh->edges[i].y = parser.ParseFloat(); + pMesh->edges[i].z = parser.ParseFloat(); + } + + return true; +} + +bool MA_ParseNormal(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->normals) { + pMesh->numNormals = header->size; + pMesh->normals = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numNormals ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "NormalHeader", NULL)) { + //This was just a header + return true; + } + + + parser.ReadToken(&token); + if(!token.Icmp("-")) { + idToken tk2; + parser.ReadToken(&tk2); + if(!tk2.Icmp("type")) { + parser.SkipUntilString("float3"); + } else { + parser.UnreadToken(&tk2); + parser.UnreadToken(&token); + } + } else { + parser.UnreadToken(&token); + } + + + //Read each vert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->normals[i].x = parser.ParseFloat(); + + //Adjust the normals for the change in coordinate systems + pMesh->normals[i].z = parser.ParseFloat(); + pMesh->normals[i].y = -parser.ParseFloat(); + + pMesh->normals[i].Normalize(); + + } + + pMesh->normalsParsed = true; + pMesh->nextNormal = 0; + + return true; +} + + + +bool MA_ParseFace(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->faces) { + pMesh->numFaces = header->size; + pMesh->faces = (maFace_t *)Mem_Alloc( sizeof( maFace_t ) * pMesh->numFaces ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "FaceHeader", NULL)) { + //This was just a header + return true; + } + + //Read the face data + int currentFace = minIndex-1; + while(parser.ReadToken(&token)) { + if(IsNodeComplete(token)) { + parser.UnreadToken(&token); + break; + } + + if(!token.Icmp("f")) { + int count = parser.ParseInt(); + if(count != 3) { + throw idException(va("Maya Loader '%s': Face is not a triangle.", parser.GetFileName())); + return false; + } + //Increment the face number because a new face always starts with an "f" token + currentFace++; + + //We cannot reorder edges until later because the normal processing + //assumes the edges are in the original order + pMesh->faces[currentFace].edge[0] = parser.ParseInt(); + pMesh->faces[currentFace].edge[1] = parser.ParseInt(); + pMesh->faces[currentFace].edge[2] = parser.ParseInt(); + + //Some more init stuff + pMesh->faces[currentFace].vertexColors[0] = pMesh->faces[currentFace].vertexColors[1] = pMesh->faces[currentFace].vertexColors[2] = -1; + + } else if(!token.Icmp("mu")) { + int uvstIndex = parser.ParseInt(); + int count = parser.ParseInt(); + if(count != 3) { + throw idException(va("Maya Loader '%s': Invalid texture coordinates.", parser.GetFileName())); + return false; + } + pMesh->faces[currentFace].tVertexNum[0] = parser.ParseInt(); + pMesh->faces[currentFace].tVertexNum[1] = parser.ParseInt(); + pMesh->faces[currentFace].tVertexNum[2] = parser.ParseInt(); + + } else if(!token.Icmp("mf")) { + int count = parser.ParseInt(); + if(count != 3) { + throw idException(va("Maya Loader '%s': Invalid texture coordinates.", parser.GetFileName())); + return false; + } + pMesh->faces[currentFace].tVertexNum[0] = parser.ParseInt(); + pMesh->faces[currentFace].tVertexNum[1] = parser.ParseInt(); + pMesh->faces[currentFace].tVertexNum[2] = parser.ParseInt(); + + } else if(!token.Icmp("fc")) { + + int count = parser.ParseInt(); + if(count != 3) { + throw idException(va("Maya Loader '%s': Invalid vertex color.", parser.GetFileName())); + return false; + } + pMesh->faces[currentFace].vertexColors[0] = parser.ParseInt(); + pMesh->faces[currentFace].vertexColors[1] = parser.ParseInt(); + pMesh->faces[currentFace].vertexColors[2] = parser.ParseInt(); + + } + } + + return true; +} + +bool MA_ParseColor(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //Allocate enough space for all the verts if this is the first attribute for verticies + if(!pMesh->colors) { + pMesh->numColors = header->size; + pMesh->colors = (byte *)Mem_Alloc( sizeof( byte ) * pMesh->numColors * 4 ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "ColorHeader", NULL)) { + //This was just a header + return true; + } + + //Read each vert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->colors[i*4] = parser.ParseFloat() * 255; + pMesh->colors[i*4+1] = parser.ParseFloat() * 255; + pMesh->colors[i*4+2] = parser.ParseFloat() * 255; + pMesh->colors[i*4+3] = parser.ParseFloat() * 255; + } + + return true; +} + +bool MA_ParseTVert(idParser& parser, maAttribHeader_t* header) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + idToken token; + + //This is not the texture coordinates. It is just the name so ignore it + if(strstr(header->name, "uvsn")) { + return true; + } + + //Allocate enough space for all the data + if(!pMesh->tvertexes) { + pMesh->numTVertexes = header->size; + pMesh->tvertexes = (idVec2 *)Mem_Alloc( sizeof( idVec2 ) * pMesh->numTVertexes ); + } + + //Get the start and end index for this attribute + int minIndex, maxIndex; + if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "TextureCoordHeader", "uvsp")) { + //This was just a header + return true; + } + + parser.ReadToken(&token); + if(!token.Icmp("-")) { + idToken tk2; + parser.ReadToken(&tk2); + if(!tk2.Icmp("type")) { + parser.SkipUntilString("float2"); + } else { + parser.UnreadToken(&tk2); + parser.UnreadToken(&token); + } + } else { + parser.UnreadToken(&token); + } + + //Read each tvert + for(int i = minIndex; i <= maxIndex; i++) { + pMesh->tvertexes[i].x = parser.ParseFloat(); + pMesh->tvertexes[i].y = 1.0f - parser.ParseFloat(); + } + + return true; +} + + + +/* +* Quick check to see if the vert participates in a shared normal +*/ +bool MA_QuickIsVertShared(int faceIndex, int vertIndex) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + int vertNum = pMesh->faces[faceIndex].vertexNum[vertIndex]; + + for( int i = 0; i < 3; i++) { + int edge = pMesh->faces[faceIndex].edge[i]; + if(edge < 0) { + edge = idMath::Fabs(edge)-1; + } + if(pMesh->edges[edge].z == 1 && (pMesh->edges[edge].x == vertNum || pMesh->edges[edge].y == vertNum)) { + return true; + } + } + return false; +} + +void MA_GetSharedFace(int faceIndex, int vertIndex, int& sharedFace, int& sharedVert) { + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + int vertNum = pMesh->faces[faceIndex].vertexNum[vertIndex]; + + sharedFace = -1; + sharedVert = -1; + + //Find a shared edge on this face that contains the specified vert + for(int edgeIndex = 0; edgeIndex < 3; edgeIndex++) { + + int edge = pMesh->faces[faceIndex].edge[edgeIndex]; + if(edge < 0) { + edge = idMath::Fabs(edge)-1; + } + + if(pMesh->edges[edge].z == 1 && (pMesh->edges[edge].x == vertNum || pMesh->edges[edge].y == vertNum)) { + + for(int i = 0; i < faceIndex; i++) { + + for(int j = 0; j < 3; j++) { + if(pMesh->faces[i].vertexNum[j] == vertNum) { + sharedFace = i; + sharedVert = j; + break; + } + } + } + } + if(sharedFace != -1) + break; + + } +} + +void MA_ParseMesh(idParser& parser) { + + maObject_t *object; + object = (maObject_t *)Mem_Alloc( sizeof( maObject_t ) ); + memset( object, 0, sizeof( maObject_t ) ); + maGlobal.model->objects.Append( object ); + maGlobal.currentObject = object; + object->materialRef = -1; + + + //Get the header info from the mesh + maNodeHeader_t header; + MA_ParseNodeHeader(parser, &header); + + //Find my parent + if(header.parent[0] != 0) { + //Find the parent + maTransform_t** parent; + maGlobal.model->transforms.Get(header.parent, &parent); + if(parent) { + maGlobal.currentObject->mesh.transform = *parent; + } + } + + strcpy(object->name, header.name); + + //Read the transform attributes + idToken token; + while(parser.ReadToken(&token)) { + if(IsNodeComplete(token)) { + parser.UnreadToken(&token); + break; + } + if(!token.Icmp("setAttr")) { + maAttribHeader_t header; + MA_ParseAttribHeader(parser, &header); + + if(strstr(header.name, ".vt")) { + MA_ParseVertex(parser, &header); + } else if (strstr(header.name, ".ed")) { + MA_ParseEdge(parser, &header); + } else if (strstr(header.name, ".pt")) { + MA_ParseVertexTransforms(parser, &header); + } else if (strstr(header.name, ".n")) { + MA_ParseNormal(parser, &header); + } else if (strstr(header.name, ".fc")) { + MA_ParseFace(parser, &header); + } else if (strstr(header.name, ".clr")) { + MA_ParseColor(parser, &header); + } else if (strstr(header.name, ".uvst")) { + MA_ParseTVert(parser, &header); + } else { + parser.SkipRestOfLine(); + } + } + } + + + maMesh_t* pMesh = &maGlobal.currentObject->mesh; + + //Get the verts from the edge + for(int i = 0; i < pMesh->numFaces; i++) { + for(int j = 0; j < 3; j++) { + int edge = pMesh->faces[i].edge[j]; + if(edge < 0) { + edge = idMath::Fabs(edge)-1; + pMesh->faces[i].vertexNum[j] = pMesh->edges[edge].y; + } else { + pMesh->faces[i].vertexNum[j] = pMesh->edges[edge].x; + } + } + } + + //Get the normals + if(pMesh->normalsParsed) { + for(int i = 0; i < pMesh->numFaces; i++) { + for(int j = 0; j < 3; j++) { + + //Is this vertex shared + int sharedFace = -1; + int sharedVert = -1; + + if(MA_QuickIsVertShared(i, j)) { + MA_GetSharedFace(i, j, sharedFace, sharedVert); + } + + if(sharedFace != -1) { + //Get the normal from the share + pMesh->faces[i].vertexNormals[j] = pMesh->faces[sharedFace].vertexNormals[sharedVert]; + + } else { + //The vertex is not shared so get the next normal + if(pMesh->nextNormal >= pMesh->numNormals) { + //We are using more normals than exist + throw idException(va("Maya Loader '%s': Invalid Normals Index.", parser.GetFileName())); + } + pMesh->faces[i].vertexNormals[j] = pMesh->normals[pMesh->nextNormal]; + pMesh->nextNormal++; + } + } + } + } + + //Now that the normals are good...lets reorder the verts to make the tris face the right way + for(int i = 0; i < pMesh->numFaces; i++) { + int tmp = pMesh->faces[i].vertexNum[1]; + pMesh->faces[i].vertexNum[1] = pMesh->faces[i].vertexNum[2]; + pMesh->faces[i].vertexNum[2] = tmp; + + idVec3 tmpVec = pMesh->faces[i].vertexNormals[1]; + pMesh->faces[i].vertexNormals[1] = pMesh->faces[i].vertexNormals[2]; + pMesh->faces[i].vertexNormals[2] = tmpVec; + + tmp = pMesh->faces[i].tVertexNum[1]; + pMesh->faces[i].tVertexNum[1] = pMesh->faces[i].tVertexNum[2]; + pMesh->faces[i].tVertexNum[2] = tmp; + + tmp = pMesh->faces[i].vertexColors[1]; + pMesh->faces[i].vertexColors[1] = pMesh->faces[i].vertexColors[2]; + pMesh->faces[i].vertexColors[2] = tmp; + } + + //Now apply the pt transformations + for(int i = 0; i < pMesh->numVertTransforms; i++) { + pMesh->vertexes[(int)pMesh->vertTransforms[i].w] += pMesh->vertTransforms[i].ToVec3(); + } + + MA_VERBOSE((va("MESH %s - parent %s\n", header.name, header.parent))); + MA_VERBOSE((va("\tverts:%d\n",maGlobal.currentObject->mesh.numVertexes))); + MA_VERBOSE((va("\tfaces:%d\n",maGlobal.currentObject->mesh.numFaces))); +} + +void MA_ParseFileNode(idParser& parser) { + + //Get the header info from the node + maNodeHeader_t header; + MA_ParseNodeHeader(parser, &header); + + //Read the transform attributes + idToken token; + while(parser.ReadToken(&token)) { + if(IsNodeComplete(token)) { + parser.UnreadToken(&token); + break; + } + if(!token.Icmp("setAttr")) { + maAttribHeader_t attribHeader; + MA_ParseAttribHeader(parser, &attribHeader); + + if(strstr(attribHeader.name, ".ftn")) { + parser.SkipUntilString("string"); + parser.ReadToken(&token); + if(!token.Icmp("(")) { + parser.ReadToken(&token); + } + + maFileNode_t* fileNode; + fileNode = (maFileNode_t*)Mem_Alloc( sizeof( maFileNode_t ) ); + strcpy(fileNode->name, header.name); + strcpy(fileNode->path, token.c_str()); + + maGlobal.model->fileNodes.Set(fileNode->name, fileNode); + } else { + parser.SkipRestOfLine(); + } + } + } +} + +void MA_ParseMaterialNode(idParser& parser) { + + //Get the header info from the node + maNodeHeader_t header; + MA_ParseNodeHeader(parser, &header); + + maMaterialNode_t* matNode; + matNode = (maMaterialNode_t*)Mem_Alloc( sizeof( maMaterialNode_t ) ); + memset(matNode, 0, sizeof(maMaterialNode_t)); + + strcpy(matNode->name, header.name); + + maGlobal.model->materialNodes.Set(matNode->name, matNode); +} + +void MA_ParseCreateNode(idParser& parser) { + + idToken token; + parser.ReadToken(&token); + + if(!token.Icmp("transform")) { + MA_ParseTransform(parser); + } else if(!token.Icmp("mesh")) { + MA_ParseMesh(parser); + } else if(!token.Icmp("file")) { + MA_ParseFileNode(parser); + } else if(!token.Icmp("shadingEngine") || !token.Icmp("lambert") || !token.Icmp("phong") || !token.Icmp("blinn") ) { + MA_ParseMaterialNode(parser); + } +} + + +int MA_AddMaterial(const char* materialName) { + + + maMaterialNode_t** destNode; + maGlobal.model->materialNodes.Get(materialName, &destNode); + if(destNode) { + maMaterialNode_t* matNode = *destNode; + + //Iterate down the tree until we get a file + while(matNode && !matNode->file) { + matNode = matNode->child; + } + if(matNode && matNode->file) { + + //Got the file + maMaterial_t *material; + material = (maMaterial_t *)Mem_Alloc( sizeof( maMaterial_t ) ); + memset( material, 0, sizeof( maMaterial_t ) ); + + //Remove the OS stuff + idStr qPath; + qPath = fileSystem->OSPathToRelativePath( matNode->file->path ); + + strcpy(material->name, qPath.c_str()); + + maGlobal.model->materials.Append( material ); + return maGlobal.model->materials.Num()-1; + } + } + return -1; +} + +bool MA_ParseConnectAttr(idParser& parser) { + + idStr temp; + idStr srcName; + idStr srcType; + idStr destName; + idStr destType; + + idToken token; + parser.ReadToken(&token); + temp = token; + int dot = temp.Find("."); + if(dot == -1) { + throw idException(va("Maya Loader '%s': Invalid Connect Attribute.", parser.GetFileName())); + return false; + } + srcName = temp.Left(dot); + srcType = temp.Right(temp.Length()-dot-1); + + parser.ReadToken(&token); + temp = token; + dot = temp.Find("."); + if(dot == -1) { + throw idException(va("Maya Loader '%s': Invalid Connect Attribute.", parser.GetFileName())); + return false; + } + destName = temp.Left(dot); + destType = temp.Right(temp.Length()-dot-1); + + if(srcType.Find("oc") != -1) { + + //Is this attribute a material node attribute + maMaterialNode_t** matNode; + maGlobal.model->materialNodes.Get(srcName, &matNode); + if(matNode) { + maMaterialNode_t** destNode; + maGlobal.model->materialNodes.Get(destName, &destNode); + if(destNode) { + (*destNode)->child = *matNode; + } + } + + //Is this attribute a file node + maFileNode_t** fileNode; + maGlobal.model->fileNodes.Get(srcName, &fileNode); + if(fileNode) { + maMaterialNode_t** destNode; + maGlobal.model->materialNodes.Get(destName, &destNode); + if(destNode) { + (*destNode)->file = *fileNode; + } + } + } + + if(srcType.Find("iog") != -1) { + //Is this an attribute for one of our meshes + for(int i = 0; i < maGlobal.model->objects.Num(); i++) { + if(!strcmp(maGlobal.model->objects[i]->name, srcName)) { + //maGlobal.model->objects[i]->materialRef = MA_AddMaterial(destName); + strcpy(maGlobal.model->objects[i]->materialName, destName); + break; + } + } + } + + return true; +} + + +void MA_BuildScale(idMat4& mat, float x, float y, float z) { + mat.Identity(); + mat[0][0] = x; + mat[1][1] = y; + mat[2][2] = z; +} + +void MA_BuildAxisRotation(idMat4& mat, float ang, int axis) { + + float sinAng = idMath::Sin(ang); + float cosAng = idMath::Cos(ang); + + mat.Identity(); + switch(axis) { + case 0: //x + mat[1][1] = cosAng; + mat[1][2] = sinAng; + mat[2][1] = -sinAng; + mat[2][2] = cosAng; + break; + case 1: //y + mat[0][0] = cosAng; + mat[0][2] = -sinAng; + mat[2][0] = sinAng; + mat[2][2] = cosAng; + break; + case 2://z + mat[0][0] = cosAng; + mat[0][1] = sinAng; + mat[1][0] = -sinAng; + mat[1][1] = cosAng; + break; + } +} + +void MA_ApplyTransformation(maModel_t *model) { + + for(int i = 0; i < model->objects.Num(); i++) { + maMesh_t* mesh = &model->objects[i]->mesh; + maTransform_t* transform = mesh->transform; + + + + while(transform) { + + idMat4 rotx, roty, rotz; + idMat4 scale; + + rotx.Identity(); + roty.Identity(); + rotz.Identity(); + + if(fabs(transform->rotate.x) > 0.0f) { + MA_BuildAxisRotation(rotx, DEG2RAD(-transform->rotate.x), 0); + } + if(fabs(transform->rotate.y) > 0.0f) { + MA_BuildAxisRotation(roty, DEG2RAD(transform->rotate.y), 1); + } + if(fabs(transform->rotate.z) > 0.0f) { + MA_BuildAxisRotation(rotz, DEG2RAD(-transform->rotate.z), 2); + } + + MA_BuildScale(scale, transform->scale.x, transform->scale.y, transform->scale.z); + + //Apply the transformation to each vert + for(int j = 0; j < mesh->numVertexes; j++) { + mesh->vertexes[j] = scale * mesh->vertexes[j]; + + mesh->vertexes[j] = rotx * mesh->vertexes[j]; + mesh->vertexes[j] = rotz * mesh->vertexes[j]; + mesh->vertexes[j] = roty * mesh->vertexes[j]; + + mesh->vertexes[j] = mesh->vertexes[j] + transform->translate; + } + + transform = transform->parent; + } + } +} + +/* +================= +MA_Parse +================= +*/ +maModel_t *MA_Parse( const char *buffer, const char* filename, bool verbose ) { + memset( &maGlobal, 0, sizeof( maGlobal ) ); + + maGlobal.verbose = verbose; + + + + + maGlobal.currentObject = NULL; + + // NOTE: using new operator because aseModel_t contains idList class objects + maGlobal.model = new maModel_t; + maGlobal.model->objects.Resize( 32, 32 ); + maGlobal.model->materials.Resize( 32, 32 ); + + + idParser parser; + parser.SetFlags(LEXFL_NOSTRINGCONCAT); + parser.LoadMemory(buffer, strlen(buffer), filename); + + idToken token; + while(parser.ReadToken(&token)) { + + if(!token.Icmp("createNode")) { + MA_ParseCreateNode(parser); + } else if(!token.Icmp("connectAttr")) { + MA_ParseConnectAttr(parser); + } + } + + //Resolve The Materials + for(int i = 0; i < maGlobal.model->objects.Num(); i++) { + maGlobal.model->objects[i]->materialRef = MA_AddMaterial(maGlobal.model->objects[i]->materialName); + } + + + + //Apply Transformation + MA_ApplyTransformation(maGlobal.model); + + return maGlobal.model; +} + +/* +================= +MA_Load +================= +*/ +maModel_t *MA_Load( const char *fileName ) { + char *buf; + ID_TIME_T timeStamp; + maModel_t *ma; + + fileSystem->ReadFile( fileName, (void **)&buf, &timeStamp ); + if ( !buf ) { + return NULL; + } + + try { + ma = MA_Parse( buf, fileName, false ); + ma->timeStamp = timeStamp; + } catch( idException &e ) { + common->Warning("%s", e.error); + if(maGlobal.model) { + MA_Free(maGlobal.model); + } + ma = NULL; + } + + fileSystem->FreeFile( buf ); + + return ma; +} + +/* +================= +MA_Free +================= +*/ +void MA_Free( maModel_t *ma ) { + int i; + maObject_t *obj; + maMesh_t *mesh; + maMaterial_t *material; + + if ( !ma ) { + return; + } + for ( i = 0; i < ma->objects.Num(); i++ ) { + obj = ma->objects[i]; + + // free the base nesh + mesh = &obj->mesh; + + if ( mesh->vertexes ) { + Mem_Free( mesh->vertexes ); + } + if ( mesh->vertTransforms ) { + Mem_Free( mesh->vertTransforms ); + } + if ( mesh->normals ) { + Mem_Free( mesh->normals ); + } + if ( mesh->tvertexes ) { + Mem_Free( mesh->tvertexes ); + } + if ( mesh->edges ) { + Mem_Free( mesh->edges ); + } + if ( mesh->colors ) { + Mem_Free( mesh->colors ); + } + if ( mesh->faces ) { + Mem_Free( mesh->faces ); + } + Mem_Free( obj ); + } + ma->objects.Clear(); + + for ( i = 0; i < ma->materials.Num(); i++ ) { + material = ma->materials[i]; + Mem_Free( material ); + } + ma->materials.Clear(); + + maTransform_t** trans; + for ( i = 0; i < ma->transforms.Num(); i++ ) { + trans = ma->transforms.GetIndex(i); + Mem_Free( *trans ); + } + ma->transforms.Clear(); + + + maFileNode_t** fileNode; + for ( i = 0; i < ma->fileNodes.Num(); i++ ) { + fileNode = ma->fileNodes.GetIndex(i); + Mem_Free( *fileNode ); + } + ma->fileNodes.Clear(); + + maMaterialNode_t** matNode; + for ( i = 0; i < ma->materialNodes.Num(); i++ ) { + matNode = ma->materialNodes.GetIndex(i); + Mem_Free( *matNode ); + } + ma->materialNodes.Clear(); + delete ma; +} diff --git a/renderer/Model_ma.h b/renderer/Model_ma.h new file mode 100644 index 000000000..0a1b6f472 --- /dev/null +++ b/renderer/Model_ma.h @@ -0,0 +1,136 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODEL_MA_H__ +#define __MODEL_MA_H__ + +/* +=============================================================================== + + MA loader. (Maya Ascii Format) + +=============================================================================== +*/ + +typedef struct { + char name[128]; + char parent[128]; +} maNodeHeader_t; + +typedef struct { + char name[128]; + int size; +} maAttribHeader_t; + +typedef struct maTransform_s { + idVec3 translate; + idVec3 rotate; + idVec3 scale; + maTransform_s* parent; +} maTransform_t; + +typedef struct { + int edge[3]; + int vertexNum[3]; + int tVertexNum[3]; + int vertexColors[3]; + idVec3 vertexNormals[3]; +} maFace_t; + +typedef struct { + + //Transform to be applied + maTransform_t* transform; + + //Verts + int numVertexes; + idVec3 * vertexes; + int numVertTransforms; + idVec4 * vertTransforms; + int nextVertTransformIndex; + + //Texture Coordinates + int numTVertexes; + idVec2 * tvertexes; + + //Edges + int numEdges; + idVec3 * edges; + + //Colors + int numColors; + byte* colors; + + //Faces + int numFaces; + maFace_t * faces; + + //Normals + int numNormals; + idVec3 * normals; + bool normalsParsed; + int nextNormal; + +} maMesh_t; + +typedef struct { + char name[128]; + float uOffset, vOffset; // max lets you offset by material without changing texCoords + float uTiling, vTiling; // multiply tex coords by this + float angle; // in clockwise radians +} maMaterial_t; + +typedef struct { + char name[128]; + int materialRef; + char materialName[128]; + + maMesh_t mesh; +} maObject_t; + + +typedef struct { + char name[128]; + char path[1024]; +} maFileNode_t; + +typedef struct maMaterialNode_s { + char name[128]; + + maMaterialNode_s* child; + maFileNode_t* file; + +} maMaterialNode_t; + +typedef struct maModel_s { + ID_TIME_T timeStamp; + idList materials; + idList objects; + idHashTable transforms; + + //Material Resolution + idHashTable fileNodes; + idHashTable materialNodes; + +} maModel_t; + +maModel_t *MA_Load( const char *fileName ); +void MA_Free( maModel_t *ma ); + +#endif /* !__MODEL_MA_H__ */ diff --git a/renderer/Model_md3.cpp b/renderer/Model_md3.cpp new file mode 100644 index 000000000..9924432b9 --- /dev/null +++ b/renderer/Model_md3.cpp @@ -0,0 +1,362 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" +#include "Model_md3.h" + +/*********************************************************************** + + idMD3Mesh + +***********************************************************************/ + +#define LL(x) x=LittleLong(x) + +/* +================= +idRenderModelMD3::InitFromFile +================= +*/ +void idRenderModelMD3::InitFromFile( const char *fileName ) { + int i, j; + md3Header_t *pinmodel; + md3Frame_t *frame; + md3Surface_t *surf; + md3Shader_t *shader; + md3Triangle_t *tri; + md3St_t *st; + md3XyzNormal_t *xyz; + md3Tag_t *tag; + void *buffer; + int version; + int size; + + + name = fileName; + + size = fileSystem->ReadFile( fileName, &buffer, NULL ); + if (!size || size<0 ) { + return; + } + + pinmodel = (md3Header_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != MD3_VERSION) { + fileSystem->FreeFile( buffer ); + common->Warning( "InitFromFile: %s has wrong version (%i should be %i)", + fileName, version, MD3_VERSION); + return; + } + + size = LittleLong(pinmodel->ofsEnd); + dataSize += size; + md3 = (md3Header_t *)Mem_Alloc( size ); + + memcpy (md3, buffer, LittleLong(pinmodel->ofsEnd) ); + + LL(md3->ident); + LL(md3->version); + LL(md3->numFrames); + LL(md3->numTags); + LL(md3->numSurfaces); + LL(md3->ofsFrames); + LL(md3->ofsTags); + LL(md3->ofsSurfaces); + LL(md3->ofsEnd); + + if ( md3->numFrames < 1 ) { + common->Warning( "InitFromFile: %s has no frames", fileName ); + fileSystem->FreeFile( buffer ); + return; + } + + // swap all the frames + frame = (md3Frame_t *) ( (byte *)md3 + md3->ofsFrames ); + for ( i = 0 ; i < md3->numFrames ; i++, frame++) { + frame->radius = LittleFloat( frame->radius ); + for ( j = 0 ; j < 3 ; j++ ) { + frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] ); + frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] ); + frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] ); + } + } + + // swap all the tags + tag = (md3Tag_t *) ( (byte *)md3 + md3->ofsTags ); + for ( i = 0 ; i < md3->numTags * md3->numFrames ; i++, tag++) { + for ( j = 0 ; j < 3 ; j++ ) { + tag->origin[j] = LittleFloat( tag->origin[j] ); + tag->axis[0][j] = LittleFloat( tag->axis[0][j] ); + tag->axis[1][j] = LittleFloat( tag->axis[1][j] ); + tag->axis[2][j] = LittleFloat( tag->axis[2][j] ); + } + } + + // swap all the surfaces + surf = (md3Surface_t *) ( (byte *)md3 + md3->ofsSurfaces ); + for ( i = 0 ; i < md3->numSurfaces ; i++) { + + LL(surf->ident); + LL(surf->flags); + LL(surf->numFrames); + LL(surf->numShaders); + LL(surf->numTriangles); + LL(surf->ofsTriangles); + LL(surf->numVerts); + LL(surf->ofsShaders); + LL(surf->ofsSt); + LL(surf->ofsXyzNormals); + LL(surf->ofsEnd); + + if ( surf->numVerts > SHADER_MAX_VERTEXES ) { + common->Error( "InitFromFile: %s has more than %i verts on a surface (%i)", + fileName, SHADER_MAX_VERTEXES, surf->numVerts ); + } + if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) { + common->Error( "InitFromFile: %s has more than %i triangles on a surface (%i)", + fileName, SHADER_MAX_INDEXES / 3, surf->numTriangles ); + } + + // change to surface identifier + surf->ident = 0; //SF_MD3; + + // lowercase the surface name so skin compares are faster + int slen = (int)strlen( surf->name ); + for( j = 0; j < slen; j++ ) { + surf->name[j] = tolower( surf->name[j] ); + } + + // strip off a trailing _1 or _2 + // this is a crutch for q3data being a mess + j = strlen( surf->name ); + if ( j > 2 && surf->name[j-2] == '_' ) { + surf->name[j-2] = 0; + } + + // register the shaders + shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders ); + for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) { + const idMaterial *sh; + + sh = declManager->FindMaterial( shader->name ); + shader->shader = sh; + } + + // swap all the triangles + tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles ); + for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) { + LL(tri->indexes[0]); + LL(tri->indexes[1]); + LL(tri->indexes[2]); + } + + // swap all the ST + st = (md3St_t *) ( (byte *)surf + surf->ofsSt ); + for ( j = 0 ; j < surf->numVerts ; j++, st++ ) { + st->st[0] = LittleFloat( st->st[0] ); + st->st[1] = LittleFloat( st->st[1] ); + } + + // swap all the XyzNormals + xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals ); + for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ ) + { + xyz->xyz[0] = LittleShort( xyz->xyz[0] ); + xyz->xyz[1] = LittleShort( xyz->xyz[1] ); + xyz->xyz[2] = LittleShort( xyz->xyz[2] ); + + xyz->normal = LittleShort( xyz->normal ); + } + + + // find the next surface + surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd ); + } + + fileSystem->FreeFile( buffer ); +} + +/* +================= +idRenderModelMD3::IsDynamicModel +================= +*/ +dynamicModel_t idRenderModelMD3::IsDynamicModel() const { + return DM_CACHED; +} + +/* +================= +idRenderModelMD3::LerpMeshVertexes +================= +*/ +void idRenderModelMD3::LerpMeshVertexes ( srfTriangles_t *tri, const struct md3Surface_s *surf, const float backlerp, const int frame, const int oldframe ) const { + short *oldXyz, *newXyz; + float oldXyzScale, newXyzScale; + int vertNum; + int numVerts; + + newXyz = (short *)((byte *)surf + surf->ofsXyzNormals) + (frame * surf->numVerts * 4); + + newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp); + + numVerts = surf->numVerts; + + if ( backlerp == 0 ) { + // + // just copy the vertexes + // + for (vertNum=0 ; vertNum < numVerts ; vertNum++, newXyz += 4 ) { + + idDrawVert *outvert = &tri->verts[tri->numVerts]; + + outvert->xyz.x = newXyz[0] * newXyzScale; + outvert->xyz.y = newXyz[1] * newXyzScale; + outvert->xyz.z = newXyz[2] * newXyzScale; + + tri->numVerts++; + } + } else { + // + // interpolate and copy the vertexes + // + oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals) + (oldframe * surf->numVerts * 4); + + oldXyzScale = MD3_XYZ_SCALE * backlerp; + + for (vertNum=0 ; vertNum < numVerts ; vertNum++, oldXyz += 4, newXyz += 4 ) { + + idDrawVert *outvert = &tri->verts[tri->numVerts]; + + // interpolate the xyz + outvert->xyz.x = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale; + outvert->xyz.y = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale; + outvert->xyz.z = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale; + + tri->numVerts++; + } + } +} + +/* +============= +idRenderModelMD3::InstantiateDynamicModel +============= +*/ +idRenderModel *idRenderModelMD3::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) { + int i, j; + float backlerp; + int * triangles; + float * texCoords; + int indexes; + int numVerts; + md3Surface_t * surface; + int frame, oldframe; + idRenderModelStatic *staticModel; + + if ( cachedModel ) { + delete cachedModel; + cachedModel = NULL; + } + + staticModel = new idRenderModelStatic; + staticModel->bounds.Clear(); + + surface = (md3Surface_t *) ((byte *)md3 + md3->ofsSurfaces); + + // TODO: these need set by an entity + frame = ent->shaderParms[SHADERPARM_MD3_FRAME]; // probably want to keep frames < 1000 or so + oldframe = ent->shaderParms[SHADERPARM_MD3_LASTFRAME]; + backlerp = ent->shaderParms[SHADERPARM_MD3_BACKLERP]; + + for( i = 0; i < md3->numSurfaces; i++ ) { + + srfTriangles_t *tri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( tri, surface->numVerts ); + R_AllocStaticTriSurfIndexes( tri, surface->numTriangles * 3 ); + tri->bounds.Clear(); + + modelSurface_t surf; + + surf.geometry = tri; + + md3Shader_t* shaders = (md3Shader_t *) ((byte *)surface + surface->ofsShaders); + surf.shader = shaders->shader; + + LerpMeshVertexes( tri, surface, backlerp, frame, oldframe ); + + triangles = (int *) ((byte *)surface + surface->ofsTriangles); + indexes = surface->numTriangles * 3; + for (j = 0 ; j < indexes ; j++) { + tri->indexes[j] = triangles[j]; + } + tri->numIndexes += indexes; + + texCoords = (float *) ((byte *)surface + surface->ofsSt); + + numVerts = surface->numVerts; + for ( j = 0; j < numVerts; j++ ) { + idDrawVert *stri = &tri->verts[j]; + stri->st[0] = texCoords[j*2+0]; + stri->st[1] = texCoords[j*2+1]; + } + + R_BoundTriSurf( tri ); + + staticModel->AddSurface( surf ); + staticModel->bounds.AddPoint( surf.geometry->bounds[0] ); + staticModel->bounds.AddPoint( surf.geometry->bounds[1] ); + + // find the next surface + surface = (md3Surface_t *)( (byte *)surface + surface->ofsEnd ); + } + + return staticModel; +} + +/* +===================== +idRenderModelMD3::Bounds +===================== +*/ + +idBounds idRenderModelMD3::Bounds(const struct renderEntity_s *ent) const { + idBounds ret; + + ret.Clear(); + + if (!ent || !md3) { + // just give it the editor bounds + ret.AddPoint(idVec3(-10,-10,-10)); + ret.AddPoint(idVec3( 10, 10, 10)); + return ret; + } + + md3Frame_t *frame = (md3Frame_t *)( (byte *)md3 + md3->ofsFrames ); + + ret.AddPoint( frame->bounds[0] ); + ret.AddPoint( frame->bounds[1] ); + + return ret; +} + diff --git a/renderer/Model_md3.h b/renderer/Model_md3.h new file mode 100644 index 000000000..bc7abd009 --- /dev/null +++ b/renderer/Model_md3.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MODEL_MD3_H__ +#define __MODEL_MD3_H__ + +/* +======================================================================== + +.MD3 triangle model file format + +Private structures used by the MD3 loader. + +======================================================================== +*/ + +#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') +#define MD3_VERSION 15 + +// surface geometry should not exceed these limits +#define SHADER_MAX_VERTEXES 1000 +#define SHADER_MAX_INDEXES (6*SHADER_MAX_VERTEXES) + +// limits +#define MD3_MAX_LODS 4 +#define MD3_MAX_TRIANGLES 8192 // per surface +#define MD3_MAX_VERTS 4096 // per surface +#define MD3_MAX_SHADERS 256 // per surface +#define MD3_MAX_FRAMES 1024 // per model +#define MD3_MAX_SURFACES 32 // per model +#define MD3_MAX_TAGS 16 // per frame +#define MAX_MD3PATH 64 // from quake3 + +// vertex scales +#define MD3_XYZ_SCALE (1.0/64) + +typedef struct md3Frame_s { + idVec3 bounds[2]; + idVec3 localOrigin; + float radius; + char name[16]; +} md3Frame_t; + +typedef struct md3Tag_s { + char name[MAX_MD3PATH]; // tag name + idVec3 origin; + idVec3 axis[3]; +} md3Tag_t; + +/* +** md3Surface_t +** +** CHUNK SIZE +** header sizeof( md3Surface_t ) +** shaders sizeof( md3Shader_t ) * numShaders +** triangles[0] sizeof( md3Triangle_t ) * numTriangles +** st sizeof( md3St_t ) * numVerts +** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames +*/ + +typedef struct md3Surface_s { + int ident; // + + char name[MAX_MD3PATH]; // polyset name + + int flags; + int numFrames; // all surfaces in a model should have the same + + int numShaders; // all surfaces in a model should have the same + int numVerts; + + int numTriangles; + int ofsTriangles; + + int ofsShaders; // offset from start of md3Surface_t + int ofsSt; // texture coords are common for all frames + int ofsXyzNormals; // numVerts * numFrames + + int ofsEnd; // next surface follows +} md3Surface_t; + +typedef struct { + char name[MAX_MD3PATH]; + const idMaterial * shader; // for in-game use +} md3Shader_t; + +typedef struct { + int indexes[3]; +} md3Triangle_t; + +typedef struct { + float st[2]; +} md3St_t; + +typedef struct { + short xyz[3]; + short normal; +} md3XyzNormal_t; + +typedef struct md3Header_s { + int ident; + int version; + + char name[MAX_MD3PATH]; // model name + + int flags; + + int numFrames; + int numTags; + int numSurfaces; + + int numSkins; + + int ofsFrames; // offset for first frame + int ofsTags; // numFrames * numTags + int ofsSurfaces; // first surface, others follow + + int ofsEnd; // end of file +} md3Header_t; + +#endif /* !__MODEL_MD3_H__ */ diff --git a/renderer/Model_md5.cpp b/renderer/Model_md5.cpp new file mode 100644 index 000000000..0c5828453 --- /dev/null +++ b/renderer/Model_md5.cpp @@ -0,0 +1,953 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + +static const char *MD5_SnapshotName = "_MD5_Snapshot_"; + + +/*********************************************************************** + + idMD5Mesh + +***********************************************************************/ + +static int c_numVerts = 0; +static int c_numWeights = 0; +static int c_numWeightJoints = 0; + +typedef struct vertexWeight_s { + int vert; + int joint; + idVec3 offset; + float jointWeight; +} vertexWeight_t; + +/* +==================== +idMD5Mesh::idMD5Mesh +==================== +*/ +idMD5Mesh::idMD5Mesh() { + scaledWeights = NULL; + weightIndex = NULL; + shader = NULL; + numTris = 0; + deformInfo = NULL; + surfaceNum = 0; +} + +/* +==================== +idMD5Mesh::~idMD5Mesh +==================== +*/ +idMD5Mesh::~idMD5Mesh() { + Mem_Free16( scaledWeights ); + Mem_Free16( weightIndex ); + if ( deformInfo ) { + R_FreeDeformInfo( deformInfo ); + deformInfo = NULL; + } +} + +/* +==================== +idMD5Mesh::ParseMesh +==================== +*/ +void idMD5Mesh::ParseMesh( idLexer &parser, int numJoints, const idJointMat *joints ) { + idToken token; + idToken name; + int num; + int count; + int jointnum; + idStr shaderName; + int i, j; + idList tris; + idList firstWeightForVertex; + idList numWeightsForVertex; + int maxweight; + idList tempWeights; + + parser.ExpectTokenString( "{" ); + + // + // parse name + // + if ( parser.CheckTokenString( "name" ) ) { + parser.ReadToken( &name ); + } + + // + // parse shader + // + parser.ExpectTokenString( "shader" ); + + parser.ReadToken( &token ); + shaderName = token; + + shader = declManager->FindMaterial( shaderName ); + + // + // parse texture coordinates + // + parser.ExpectTokenString( "numverts" ); + count = parser.ParseInt(); + if ( count < 0 ) { + parser.Error( "Invalid size: %s", token.c_str() ); + } + + texCoords.SetNum( count ); + firstWeightForVertex.SetNum( count ); + numWeightsForVertex.SetNum( count ); + + numWeights = 0; + maxweight = 0; + for( i = 0; i < texCoords.Num(); i++ ) { + parser.ExpectTokenString( "vert" ); + parser.ParseInt(); + + parser.Parse1DMatrix( 2, texCoords[ i ].ToFloatPtr() ); + + firstWeightForVertex[ i ] = parser.ParseInt(); + numWeightsForVertex[ i ] = parser.ParseInt(); + + if ( !numWeightsForVertex[ i ] ) { + parser.Error( "Vertex without any joint weights." ); + } + + numWeights += numWeightsForVertex[ i ]; + if ( numWeightsForVertex[ i ] + firstWeightForVertex[ i ] > maxweight ) { + maxweight = numWeightsForVertex[ i ] + firstWeightForVertex[ i ]; + } + } + + // + // parse tris + // + parser.ExpectTokenString( "numtris" ); + count = parser.ParseInt(); + if ( count < 0 ) { + parser.Error( "Invalid size: %d", count ); + } + + tris.SetNum( count * 3 ); + numTris = count; + for( i = 0; i < count; i++ ) { + parser.ExpectTokenString( "tri" ); + parser.ParseInt(); + + tris[ i * 3 + 0 ] = parser.ParseInt(); + tris[ i * 3 + 1 ] = parser.ParseInt(); + tris[ i * 3 + 2 ] = parser.ParseInt(); + } + + // + // parse weights + // + parser.ExpectTokenString( "numweights" ); + count = parser.ParseInt(); + if ( count < 0 ) { + parser.Error( "Invalid size: %d", count ); + } + + if ( maxweight > count ) { + parser.Warning( "Vertices reference out of range weights in model (%d of %d weights).", maxweight, count ); + } + + tempWeights.SetNum( count ); + + for( i = 0; i < count; i++ ) { + parser.ExpectTokenString( "weight" ); + parser.ParseInt(); + + jointnum = parser.ParseInt(); + if ( ( jointnum < 0 ) || ( jointnum >= numJoints ) ) { + parser.Error( "Joint Index out of range(%d): %d", numJoints, jointnum ); + } + + tempWeights[ i ].joint = jointnum; + tempWeights[ i ].jointWeight = parser.ParseFloat(); + + parser.Parse1DMatrix( 3, tempWeights[ i ].offset.ToFloatPtr() ); + } + + // create pre-scaled weights and an index for the vertex/joint lookup + scaledWeights = (idVec4 *) Mem_Alloc16( numWeights * sizeof( scaledWeights[0] ) ); + weightIndex = (int *) Mem_Alloc16( numWeights * 2 * sizeof( weightIndex[0] ) ); + memset( weightIndex, 0, numWeights * 2 * sizeof( weightIndex[0] ) ); + + count = 0; + for( i = 0; i < texCoords.Num(); i++ ) { + num = firstWeightForVertex[i]; + for( j = 0; j < numWeightsForVertex[i]; j++, num++, count++ ) { + scaledWeights[count].ToVec3() = tempWeights[num].offset * tempWeights[num].jointWeight; + scaledWeights[count].w = tempWeights[num].jointWeight; + weightIndex[count * 2 + 0] = tempWeights[num].joint * sizeof( idJointMat ); + } + weightIndex[count * 2 - 1] = 1; + } + + tempWeights.Clear(); + numWeightsForVertex.Clear(); + firstWeightForVertex.Clear(); + + parser.ExpectTokenString( "}" ); + + // update counters + c_numVerts += texCoords.Num(); + c_numWeights += numWeights; + c_numWeightJoints++; + for ( i = 0; i < numWeights; i++ ) { + c_numWeightJoints += weightIndex[i*2+1]; + } + + // + // build the information that will be common to all animations of this mesh: + // silhouette edge connectivity and normal / tangent generation information + // + idDrawVert *verts = (idDrawVert *) _alloca16( texCoords.Num() * sizeof( idDrawVert ) ); + for ( i = 0; i < texCoords.Num(); i++ ) { + verts[i].Clear(); + verts[i].st = texCoords[i]; + } + TransformVerts( verts, joints ); + deformInfo = R_BuildDeformInfo( texCoords.Num(), verts, tris.Num(), tris.Ptr(), shader->UseUnsmoothedTangents() ); +} + +/* +==================== +idMD5Mesh::TransformVerts +==================== +*/ +void idMD5Mesh::TransformVerts( idDrawVert *verts, const idJointMat *entJoints ) { + SIMDProcessor->TransformVerts( verts, texCoords.Num(), entJoints, scaledWeights, weightIndex, numWeights ); +} + +/* +==================== +idMD5Mesh::TransformScaledVerts + +Special transform to make the mesh seem fat or skinny. May be used for zombie deaths +==================== +*/ +void idMD5Mesh::TransformScaledVerts( idDrawVert *verts, const idJointMat *entJoints, float scale ) { + idVec4 *scaledWeights = (idVec4 *) _alloca16( numWeights * sizeof( scaledWeights[0] ) ); + SIMDProcessor->Mul( scaledWeights[0].ToFloatPtr(), scale, scaledWeights[0].ToFloatPtr(), numWeights * 4 ); + SIMDProcessor->TransformVerts( verts, texCoords.Num(), entJoints, scaledWeights, weightIndex, numWeights ); +} + +/* +==================== +idMD5Mesh::UpdateSurface +==================== +*/ +void idMD5Mesh::UpdateSurface( const struct renderEntity_s *ent, const idJointMat *entJoints, modelSurface_t *surf ) { + int i, base; + srfTriangles_t *tri; + + tr.pc.c_deformedSurfaces++; + tr.pc.c_deformedVerts += deformInfo->numOutputVerts; + tr.pc.c_deformedIndexes += deformInfo->numIndexes; + + surf->shader = shader; + + if ( surf->geometry ) { + // if the number of verts and indexes are the same we can re-use the triangle surface + // the number of indexes must be the same to assure the correct amount of memory is allocated for the facePlanes + if ( surf->geometry->numVerts == deformInfo->numOutputVerts && surf->geometry->numIndexes == deformInfo->numIndexes ) { + R_FreeStaticTriSurfVertexCaches( surf->geometry ); + } else { + R_FreeStaticTriSurf( surf->geometry ); + surf->geometry = R_AllocStaticTriSurf(); + } + } else { + surf->geometry = R_AllocStaticTriSurf(); + } + + tri = surf->geometry; + + // note that some of the data is references, and should not be freed + tri->deformedSurface = true; + tri->tangentsCalculated = false; + tri->facePlanesCalculated = false; + + tri->numIndexes = deformInfo->numIndexes; + tri->indexes = deformInfo->indexes; + tri->silIndexes = deformInfo->silIndexes; + tri->numMirroredVerts = deformInfo->numMirroredVerts; + tri->mirroredVerts = deformInfo->mirroredVerts; + tri->numDupVerts = deformInfo->numDupVerts; + tri->dupVerts = deformInfo->dupVerts; + tri->numSilEdges = deformInfo->numSilEdges; + tri->silEdges = deformInfo->silEdges; + tri->dominantTris = deformInfo->dominantTris; + tri->numVerts = deformInfo->numOutputVerts; + + if ( tri->verts == NULL ) { + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( i = 0; i < deformInfo->numSourceVerts; i++ ) { + tri->verts[i].Clear(); + tri->verts[i].st = texCoords[i]; + } + } + + if ( ent->shaderParms[ SHADERPARM_MD5_SKINSCALE ] != 0.0f ) { + TransformScaledVerts( tri->verts, entJoints, ent->shaderParms[ SHADERPARM_MD5_SKINSCALE ] ); + } else { + TransformVerts( tri->verts, entJoints ); + } + + // replicate the mirror seam vertexes + base = deformInfo->numOutputVerts - deformInfo->numMirroredVerts; + for ( i = 0; i < deformInfo->numMirroredVerts; i++ ) { + tri->verts[base + i] = tri->verts[deformInfo->mirroredVerts[i]]; + } + + R_BoundTriSurf( tri ); + + // If a surface is going to be have a lighting interaction generated, it will also have to call + // R_DeriveTangents() to get normals, tangents, and face planes. If it only + // needs shadows generated, it will only have to generate face planes. If it only + // has ambient drawing, or is culled, no additional work will be necessary + if ( !r_useDeferredTangents.GetBool() ) { + // set face planes, vertex normals, tangents + R_DeriveTangents( tri ); + } +} + +/* +==================== +idMD5Mesh::CalcBounds +==================== +*/ +idBounds idMD5Mesh::CalcBounds( const idJointMat *entJoints ) { + idBounds bounds; + idDrawVert *verts = (idDrawVert *) _alloca16( texCoords.Num() * sizeof( idDrawVert ) ); + + TransformVerts( verts, entJoints ); + + SIMDProcessor->MinMax( bounds[0], bounds[1], verts, texCoords.Num() ); + + return bounds; +} + +/* +==================== +idMD5Mesh::NearestJoint +==================== +*/ +int idMD5Mesh::NearestJoint( int a, int b, int c ) const { + int i, bestJoint, vertNum, weightVertNum; + float bestWeight; + + // duplicated vertices might not have weights + if ( a >= 0 && a < texCoords.Num() ) { + vertNum = a; + } else if ( b >= 0 && b < texCoords.Num() ) { + vertNum = b; + } else if ( c >= 0 && c < texCoords.Num() ) { + vertNum = c; + } else { + // all vertices are duplicates which shouldn't happen + return 0; + } + + // find the first weight for this vertex + weightVertNum = 0; + for( i = 0; weightVertNum < vertNum; i++ ) { + weightVertNum += weightIndex[i*2+1]; + } + + // get the joint for the largest weight + bestWeight = scaledWeights[i].w; + bestJoint = weightIndex[i*2+0] / sizeof( idJointMat ); + for( ; weightIndex[i*2+1] == 0; i++ ) { + if ( scaledWeights[i].w > bestWeight ) { + bestWeight = scaledWeights[i].w; + bestJoint = weightIndex[i*2+0] / sizeof( idJointMat ); + } + } + return bestJoint; +} + +/* +==================== +idMD5Mesh::NumVerts +==================== +*/ +int idMD5Mesh::NumVerts( void ) const { + return texCoords.Num(); +} + +/* +==================== +idMD5Mesh::NumTris +==================== +*/ +int idMD5Mesh::NumTris( void ) const { + return numTris; +} + +/* +==================== +idMD5Mesh::NumWeights +==================== +*/ +int idMD5Mesh::NumWeights( void ) const { + return numWeights; +} + +/*********************************************************************** + + idRenderModelMD5 + +***********************************************************************/ + +/* +==================== +idRenderModelMD5::ParseJoint +==================== +*/ +void idRenderModelMD5::ParseJoint( idLexer &parser, idMD5Joint *joint, idJointQuat *defaultPose ) { + idToken token; + int num; + + // + // parse name + // + parser.ReadToken( &token ); + joint->name = token; + + // + // parse parent + // + num = parser.ParseInt(); + if ( num < 0 ) { + joint->parent = NULL; + } else { + if ( num >= joints.Num() - 1 ) { + parser.Error( "Invalid parent for joint '%s'", joint->name.c_str() ); + } + joint->parent = &joints[ num ]; + } + + // + // parse default pose + // + parser.Parse1DMatrix( 3, defaultPose->t.ToFloatPtr() ); + parser.Parse1DMatrix( 3, defaultPose->q.ToFloatPtr() ); + defaultPose->q.w = defaultPose->q.CalcW(); +} + +/* +==================== +idRenderModelMD5::InitFromFile +==================== +*/ +void idRenderModelMD5::InitFromFile( const char *fileName ) { + name = fileName; + LoadModel(); +} + +/* +==================== +idRenderModelMD5::LoadModel + +used for initial loads, reloadModel, and reloading the data of purged models +Upon exit, the model will absolutely be valid, but possibly as a default model +==================== +*/ +void idRenderModelMD5::LoadModel() { + int version; + int i; + int num; + int parentNum; + idToken token; + idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); + idJointQuat *pose; + idMD5Joint *joint; + idJointMat *poseMat3; + + if ( !purged ) { + PurgeModel(); + } + purged = false; + + if ( !parser.LoadFile( name ) ) { + MakeDefaultModel(); + return; + } + + parser.ExpectTokenString( MD5_VERSION_STRING ); + version = parser.ParseInt(); + + if ( version != MD5_VERSION ) { + parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); + } + + // + // skip commandline + // + parser.ExpectTokenString( "commandline" ); + parser.ReadToken( &token ); + + // parse num joints + parser.ExpectTokenString( "numJoints" ); + num = parser.ParseInt(); + joints.SetGranularity( 1 ); + joints.SetNum( num ); + defaultPose.SetGranularity( 1 ); + defaultPose.SetNum( num ); + poseMat3 = ( idJointMat * )_alloca16( num * sizeof( *poseMat3 ) ); + + // parse num meshes + parser.ExpectTokenString( "numMeshes" ); + num = parser.ParseInt(); + if ( num < 0 ) { + parser.Error( "Invalid size: %d", num ); + } + meshes.SetGranularity( 1 ); + meshes.SetNum( num ); + + // + // parse joints + // + parser.ExpectTokenString( "joints" ); + parser.ExpectTokenString( "{" ); + pose = defaultPose.Ptr(); + joint = joints.Ptr(); + for( i = 0; i < joints.Num(); i++, joint++, pose++ ) { + ParseJoint( parser, joint, pose ); + poseMat3[ i ].SetRotation( pose->q.ToMat3() ); + poseMat3[ i ].SetTranslation( pose->t ); + if ( joint->parent ) { + parentNum = joint->parent - joints.Ptr(); + pose->q = ( poseMat3[ i ].ToMat3() * poseMat3[ parentNum ].ToMat3().Transpose() ).ToQuat(); + pose->t = ( poseMat3[ i ].ToVec3() - poseMat3[ parentNum ].ToVec3() ) * poseMat3[ parentNum ].ToMat3().Transpose(); + } + } + parser.ExpectTokenString( "}" ); + + for( i = 0; i < meshes.Num(); i++ ) { + parser.ExpectTokenString( "mesh" ); + meshes[ i ].ParseMesh( parser, defaultPose.Num(), poseMat3 ); + } + + // + // calculate the bounds of the model + // + CalculateBounds( poseMat3 ); + + // set the timestamp for reloadmodels + fileSystem->ReadFile( name, NULL, &timeStamp ); +} + +/* +============== +idRenderModelMD5::Print +============== +*/ +void idRenderModelMD5::Print() const { + const idMD5Mesh *mesh; + int i; + + common->Printf( "%s\n", name.c_str() ); + common->Printf( "Dynamic model.\n" ); + common->Printf( "Generated smooth normals.\n" ); + common->Printf( " verts tris weights material\n" ); + int totalVerts = 0; + int totalTris = 0; + int totalWeights = 0; + for( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + totalVerts += mesh->NumVerts(); + totalTris += mesh->NumTris(); + totalWeights += mesh->NumWeights(); + common->Printf( "%2i: %5i %5i %7i %s\n", i, mesh->NumVerts(), mesh->NumTris(), mesh->NumWeights(), mesh->shader->GetName() ); + } + common->Printf( "-----\n" ); + common->Printf( "%4i verts.\n", totalVerts ); + common->Printf( "%4i tris.\n", totalTris ); + common->Printf( "%4i weights.\n", totalWeights ); + common->Printf( "%4i joints.\n", joints.Num() ); +} + +/* +============== +idRenderModelMD5::List +============== +*/ +void idRenderModelMD5::List() const { + int i; + const idMD5Mesh *mesh; + int totalTris = 0; + int totalVerts = 0; + + for( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + totalTris += mesh->numTris; + totalVerts += mesh->NumVerts(); + } + common->Printf( " %4ik %3i %4i %4i %s(MD5)", Memory()/1024, meshes.Num(), totalVerts, totalTris, Name() ); + + if ( defaulted ) { + common->Printf( " (DEFAULTED)" ); + } + + common->Printf( "\n" ); +} + +/* +==================== +idRenderModelMD5::CalculateBounds +==================== +*/ +void idRenderModelMD5::CalculateBounds( const idJointMat *entJoints ) { + int i; + idMD5Mesh *mesh; + + bounds.Clear(); + for( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + bounds.AddBounds( mesh->CalcBounds( entJoints ) ); + } +} + +/* +==================== +idRenderModelMD5::Bounds + +This calculates a rough bounds by using the joint radii without +transforming all the points +==================== +*/ +idBounds idRenderModelMD5::Bounds( const renderEntity_t *ent ) const { +#if 0 + // we can't calculate a rational bounds without an entity, + // because joints could be positioned to deform it into an + // arbitrarily large shape + if ( !ent ) { + common->Error( "idRenderModelMD5::Bounds: called without entity" ); + } +#endif + + if ( !ent ) { + // this is the bounds for the reference pose + return bounds; + } + + return ent->bounds; +} + +/* +==================== +idRenderModelMD5::DrawJoints +==================== +*/ +void idRenderModelMD5::DrawJoints( const renderEntity_t *ent, const struct viewDef_s *view ) const { + int i; + int num; + idVec3 pos; + const idJointMat *joint; + const idMD5Joint *md5Joint; + int parentNum; + + num = ent->numJoints; + joint = ent->joints; + md5Joint = joints.Ptr(); + for( i = 0; i < num; i++, joint++, md5Joint++ ) { + pos = ent->origin + joint->ToVec3() * ent->axis; + if ( md5Joint->parent ) { + parentNum = md5Joint->parent - joints.Ptr(); + session->rw->DebugLine( colorWhite, ent->origin + ent->joints[ parentNum ].ToVec3() * ent->axis, pos ); + } + + session->rw->DebugLine( colorRed, pos, pos + joint->ToMat3()[ 0 ] * 2.0f * ent->axis ); + session->rw->DebugLine( colorGreen, pos, pos + joint->ToMat3()[ 1 ] * 2.0f * ent->axis ); + session->rw->DebugLine( colorBlue, pos, pos + joint->ToMat3()[ 2 ] * 2.0f * ent->axis ); + } + + idBounds bounds; + + bounds.FromTransformedBounds( ent->bounds, vec3_zero, ent->axis ); + session->rw->DebugBounds( colorMagenta, bounds, ent->origin ); + + if ( ( r_jointNameScale.GetFloat() != 0.0f ) && ( bounds.Expand( 128.0f ).ContainsPoint( view->renderView.vieworg - ent->origin ) ) ) { + idVec3 offset( 0, 0, r_jointNameOffset.GetFloat() ); + float scale; + + scale = r_jointNameScale.GetFloat(); + joint = ent->joints; + num = ent->numJoints; + for( i = 0; i < num; i++, joint++ ) { + pos = ent->origin + joint->ToVec3() * ent->axis; + session->rw->DrawText( joints[ i ].name, pos + offset, scale, colorWhite, view->renderView.viewaxis, 1 ); + } + } +} + +/* +==================== +idRenderModelMD5::InstantiateDynamicModel +==================== +*/ +idRenderModel *idRenderModelMD5::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) { + int i, surfaceNum; + idMD5Mesh *mesh; + idRenderModelStatic *staticModel; + + if ( cachedModel && !r_useCachedDynamicModels.GetBool() ) { + delete cachedModel; + cachedModel = NULL; + } + + if ( purged ) { + common->DWarning( "model %s instantiated while purged", Name() ); + LoadModel(); + } + + if ( !ent->joints ) { + common->Printf( "idRenderModelMD5::InstantiateDynamicModel: NULL joints on renderEntity for '%s'\n", Name() ); + delete cachedModel; + return NULL; + } else if ( ent->numJoints != joints.Num() ) { + common->Printf( "idRenderModelMD5::InstantiateDynamicModel: renderEntity has different number of joints than model for '%s'\n", Name() ); + delete cachedModel; + return NULL; + } + + tr.pc.c_generateMd5++; + + if ( cachedModel ) { + assert( dynamic_cast(cachedModel) != NULL ); + assert( idStr::Icmp( cachedModel->Name(), MD5_SnapshotName ) == 0 ); + staticModel = static_cast(cachedModel); + } else { + staticModel = new idRenderModelStatic; + staticModel->InitEmpty( MD5_SnapshotName ); + } + + staticModel->bounds.Clear(); + + if ( r_showSkel.GetInteger() ) { + if ( ( view != NULL ) && ( !r_skipSuppress.GetBool() || !ent->suppressSurfaceInViewID || ( ent->suppressSurfaceInViewID != view->renderView.viewID ) ) ) { + // only draw the skeleton + DrawJoints( ent, view ); + } + + if ( r_showSkel.GetInteger() > 1 ) { + // turn off the model when showing the skeleton + staticModel->InitEmpty( MD5_SnapshotName ); + return staticModel; + } + } + + // create all the surfaces + for( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + // avoid deforming the surface if it will be a nodraw due to a skin remapping + // FIXME: may have to still deform clipping hulls + const idMaterial *shader = mesh->shader; + + shader = R_RemapShaderBySkin( shader, ent->customSkin, ent->customShader ); + + if ( !shader || ( !shader->IsDrawn() && !shader->SurfaceCastsShadow() ) ) { + staticModel->DeleteSurfaceWithId( i ); + mesh->surfaceNum = -1; + continue; + } + + modelSurface_t *surf; + + if ( staticModel->FindSurfaceWithId( i, surfaceNum ) ) { + mesh->surfaceNum = surfaceNum; + surf = &staticModel->surfaces[surfaceNum]; + } else { + + // Remove Overlays before adding new surfaces + idRenderModelOverlay::RemoveOverlaySurfacesFromModel( staticModel ); + + mesh->surfaceNum = staticModel->NumSurfaces(); + surf = &staticModel->surfaces.Alloc(); + surf->geometry = NULL; + surf->shader = NULL; + surf->id = i; + } + + mesh->UpdateSurface( ent, ent->joints, surf ); + + staticModel->bounds.AddPoint( surf->geometry->bounds[0] ); + staticModel->bounds.AddPoint( surf->geometry->bounds[1] ); + } + + return staticModel; +} + +/* +==================== +idRenderModelMD5::IsDynamicModel +==================== +*/ +dynamicModel_t idRenderModelMD5::IsDynamicModel() const { + return DM_CACHED; +} + +/* +==================== +idRenderModelMD5::NumJoints +==================== +*/ +int idRenderModelMD5::NumJoints( void ) const { + return joints.Num(); +} + +/* +==================== +idRenderModelMD5::GetJoints +==================== +*/ +const idMD5Joint *idRenderModelMD5::GetJoints( void ) const { + return joints.Ptr(); +} + +/* +==================== +idRenderModelMD5::GetDefaultPose +==================== +*/ +const idJointQuat *idRenderModelMD5::GetDefaultPose( void ) const { + return defaultPose.Ptr(); +} + +/* +==================== +idRenderModelMD5::GetJointHandle +==================== +*/ +jointHandle_t idRenderModelMD5::GetJointHandle( const char *name ) const { + const idMD5Joint *joint; + int i; + + joint = joints.Ptr(); + for( i = 0; i < joints.Num(); i++, joint++ ) { + if ( idStr::Icmp( joint->name.c_str(), name ) == 0 ) { + return ( jointHandle_t )i; + } + } + + return INVALID_JOINT; +} + +/* +===================== +idRenderModelMD5::GetJointName +===================== +*/ +const char *idRenderModelMD5::GetJointName( jointHandle_t handle ) const { + if ( ( handle < 0 ) || ( handle >= joints.Num() ) ) { + return ""; + } + + return joints[ handle ].name; +} + +/* +==================== +idRenderModelMD5::NearestJoint +==================== +*/ +int idRenderModelMD5::NearestJoint( int surfaceNum, int a, int b, int c ) const { + int i; + const idMD5Mesh *mesh; + + if ( surfaceNum > meshes.Num() ) { + common->Error( "idRenderModelMD5::NearestJoint: surfaceNum > meshes.Num()" ); + } + + for ( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + if ( mesh->surfaceNum == surfaceNum ) { + return mesh->NearestJoint( a, b, c ); + } + } + return 0; +} + +/* +==================== +idRenderModelMD5::TouchData + +models that are already loaded at level start time +will still touch their materials to make sure they +are kept loaded +==================== +*/ +void idRenderModelMD5::TouchData() { + idMD5Mesh *mesh; + int i; + + for( mesh = meshes.Ptr(), i = 0; i < meshes.Num(); i++, mesh++ ) { + declManager->FindMaterial( mesh->shader->GetName() ); + } +} + +/* +=================== +idRenderModelMD5::PurgeModel + +frees all the data, but leaves the class around for dangling references, +which can regenerate the data with LoadModel() +=================== +*/ +void idRenderModelMD5::PurgeModel() { + purged = true; + joints.Clear(); + defaultPose.Clear(); + meshes.Clear(); +} + +/* +=================== +idRenderModelMD5::Memory +=================== +*/ +int idRenderModelMD5::Memory() const { + int total, i; + + total = sizeof( *this ); + total += joints.MemoryUsed() + defaultPose.MemoryUsed() + meshes.MemoryUsed(); + + // count up strings + for ( i = 0; i < joints.Num(); i++ ) { + total += joints[i].name.DynamicMemoryUsed(); + } + + // count up meshes + for ( i = 0 ; i < meshes.Num() ; i++ ) { + const idMD5Mesh *mesh = &meshes[i]; + + total += mesh->texCoords.MemoryUsed() + mesh->numWeights * ( sizeof( mesh->scaledWeights[0] ) + sizeof( mesh->weightIndex[0] ) * 2 ); + + // sum up deform info + total += sizeof( mesh->deformInfo ); + total += R_DeformInfoMemoryUsed( mesh->deformInfo ); + } + return total; +} diff --git a/renderer/Model_prt.cpp b/renderer/Model_prt.cpp new file mode 100644 index 000000000..8f910d5a9 --- /dev/null +++ b/renderer/Model_prt.cpp @@ -0,0 +1,281 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + +static const char *parametricParticle_SnapshotName = "_ParametricParticle_Snapshot_"; + +/* +==================== +idRenderModelPrt::idRenderModelPrt +==================== +*/ +idRenderModelPrt::idRenderModelPrt() { + particleSystem = NULL; +} + +/* +==================== +idRenderModelPrt::InitFromFile +==================== +*/ +void idRenderModelPrt::InitFromFile( const char *fileName ) { + name = fileName; + particleSystem = static_cast( declManager->FindType( DECL_PARTICLE, fileName ) ); +} + +/* +================= +idRenderModelPrt::TouchData +================= +*/ +void idRenderModelPrt::TouchData( void ) { + // Ensure our particle system is added to the list of referenced decls + particleSystem = static_cast( declManager->FindType( DECL_PARTICLE, name ) ); +} + +/* +==================== +idRenderModelPrt::InstantiateDynamicModel +==================== +*/ +idRenderModel *idRenderModelPrt::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) { + idRenderModelStatic *staticModel; + + if ( cachedModel && !r_useCachedDynamicModels.GetBool() ) { + delete cachedModel; + cachedModel = NULL; + } + + // this may be triggered by a model trace or other non-view related source, to which we should look like an empty model + if ( renderEntity == NULL || viewDef == NULL ) { + delete cachedModel; + return NULL; + } + + if ( r_skipParticles.GetBool() ) { + delete cachedModel; + return NULL; + } + + /* + // if the entire system has faded out + if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && viewDef->renderView.time * 0.001f >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) { + delete cachedModel; + return NULL; + } + */ + + if ( cachedModel != NULL ) { + + assert( dynamic_cast(cachedModel) != NULL ); + assert( idStr::Icmp( cachedModel->Name(), parametricParticle_SnapshotName ) == 0 ); + + staticModel = static_cast(cachedModel); + + } else { + + staticModel = new idRenderModelStatic; + staticModel->InitEmpty( parametricParticle_SnapshotName ); + } + + particleGen_t g; + + g.renderEnt = renderEntity; + g.renderView = &viewDef->renderView; + g.origin.Zero(); + g.axis.Identity(); + + for ( int stageNum = 0; stageNum < particleSystem->stages.Num(); stageNum++ ) { + idParticleStage *stage = particleSystem->stages[stageNum]; + + if ( !stage->material ) { + continue; + } + if ( !stage->cycleMsec ) { + continue; + } + if ( stage->hidden ) { // just for gui particle editor use + staticModel->DeleteSurfaceWithId( stageNum ); + continue; + } + + idRandom steppingRandom, steppingRandom2; + + int stageAge = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000; + int stageCycle = stageAge / stage->cycleMsec; + int inCycleTime = stageAge - stageCycle * stage->cycleMsec; + + // some particles will be in this cycle, some will be in the previous cycle + steppingRandom.SetSeed( (( stageCycle << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) ); + steppingRandom2.SetSeed( (( (stageCycle-1) << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) ); + + int count = stage->totalParticles * stage->NumQuadsPerParticle(); + + int surfaceNum; + modelSurface_t *surf; + + if ( staticModel->FindSurfaceWithId( stageNum, surfaceNum ) ) { + surf = &staticModel->surfaces[surfaceNum]; + R_FreeStaticTriSurfVertexCaches( surf->geometry ); + } else { + surf = &staticModel->surfaces.Alloc(); + surf->id = stageNum; + surf->shader = stage->material; + surf->geometry = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( surf->geometry, 4 * count ); + R_AllocStaticTriSurfIndexes( surf->geometry, 6 * count ); + R_AllocStaticTriSurfPlanes( surf->geometry, 6 * count ); + } + + int numVerts = 0; + idDrawVert *verts = surf->geometry->verts; + + for ( int index = 0; index < stage->totalParticles; index++ ) { + g.index = index; + + // bump the random + steppingRandom.RandomInt(); + steppingRandom2.RandomInt(); + + // calculate local age for this index + int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / stage->totalParticles; + + int particleAge = stageAge - bunchOffset; + int particleCycle = particleAge / stage->cycleMsec; + if ( particleCycle < 0 ) { + // before the particleSystem spawned + continue; + } + if ( stage->cycles && particleCycle >= stage->cycles ) { + // cycled systems will only run cycle times + continue; + } + + if ( particleCycle == stageCycle ) { + g.random = steppingRandom; + } else { + g.random = steppingRandom2; + } + + int inCycleTime = particleAge - particleCycle * stage->cycleMsec; + + if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && + g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME]*1000 ) { + // don't fire any more particles + continue; + } + + // supress particles before or after the age clamp + g.frac = (float)inCycleTime / ( stage->particleLife * 1000 ); + if ( g.frac < 0.0f ) { + // yet to be spawned + continue; + } + if ( g.frac > 1.0f ) { + // this particle is in the deadTime band + continue; + } + + // this is needed so aimed particles can calculate origins at different times + g.originalRandom = g.random; + + g.age = g.frac * stage->particleLife; + + // if the particle doesn't get drawn because it is faded out or beyond a kill region, don't increment the verts + numVerts += stage->CreateParticle( &g, verts + numVerts ); + } + + // numVerts must be a multiple of 4 + assert( ( numVerts & 3 ) == 0 && numVerts <= 4 * count ); + + // build the indexes + int numIndexes = 0; + glIndex_t *indexes = surf->geometry->indexes; + for ( int i = 0; i < numVerts; i += 4 ) { + indexes[numIndexes+0] = i; + indexes[numIndexes+1] = i+2; + indexes[numIndexes+2] = i+3; + indexes[numIndexes+3] = i; + indexes[numIndexes+4] = i+3; + indexes[numIndexes+5] = i+1; + numIndexes += 6; + } + + surf->geometry->tangentsCalculated = false; + surf->geometry->facePlanesCalculated = false; + surf->geometry->numVerts = numVerts; + surf->geometry->numIndexes = numIndexes; + surf->geometry->bounds = stage->bounds; // just always draw the particles + } + + return staticModel; +} + +/* +==================== +idRenderModelPrt::IsDynamicModel +==================== +*/ +dynamicModel_t idRenderModelPrt::IsDynamicModel() const { + return DM_CONTINUOUS; +} + +/* +==================== +idRenderModelPrt::Bounds +==================== +*/ +idBounds idRenderModelPrt::Bounds( const struct renderEntity_s *ent ) const { + return particleSystem->bounds; +} + +/* +==================== +idRenderModelPrt::DepthHack +==================== +*/ +float idRenderModelPrt::DepthHack() const { + return particleSystem->depthHack; +} + +/* +==================== +idRenderModelPrt::Memory +==================== +*/ +int idRenderModelPrt::Memory() const { + int total = 0; + + total += idRenderModelStatic::Memory(); + + if ( particleSystem ) { + total += sizeof( *particleSystem ); + + for ( int i = 0; i < particleSystem->stages.Num(); i++ ) { + total += sizeof( particleSystem->stages[i] ); + } + } + + return total; +} diff --git a/renderer/Model_sprite.cpp b/renderer/Model_sprite.cpp new file mode 100644 index 000000000..d48f253ad --- /dev/null +++ b/renderer/Model_sprite.cpp @@ -0,0 +1,189 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "Model_local.h" + + +/* + +A simple sprite model that always faces the view axis. + +*/ + +static const char *sprite_SnapshotName = "_sprite_Snapshot_"; + +/* +=============== +idRenderModelBeam::IsDynamicModel +=============== +*/ +dynamicModel_t idRenderModelSprite::IsDynamicModel() const { + return DM_CONTINUOUS; +} + +/* +=============== +idRenderModelBeam::IsLoaded +=============== +*/ +bool idRenderModelSprite::IsLoaded() const { + return true; +} + +/* +=============== +idRenderModelSprite::InstantiateDynamicModel +=============== +*/ +idRenderModel * idRenderModelSprite::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) { + idRenderModelStatic *staticModel; + srfTriangles_t *tri; + modelSurface_t surf; + + if ( cachedModel && !r_useCachedDynamicModels.GetBool() ) { + delete cachedModel; + cachedModel = NULL; + } + + if ( renderEntity == NULL || viewDef == NULL ) { + delete cachedModel; + return NULL; + } + + if ( cachedModel != NULL ) { + + assert( dynamic_cast( cachedModel ) != NULL ); + assert( idStr::Icmp( cachedModel->Name(), sprite_SnapshotName ) == 0 ); + + staticModel = static_cast( cachedModel ); + surf = *staticModel->Surface( 0 ); + tri = surf.geometry; + + } else { + + staticModel = new idRenderModelStatic; + staticModel->InitEmpty( sprite_SnapshotName ); + + tri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( tri, 4 ); + R_AllocStaticTriSurfIndexes( tri, 6 ); + + tri->verts[ 0 ].Clear(); + tri->verts[ 0 ].normal.Set( 1.0f, 0.0f, 0.0f ); + tri->verts[ 0 ].tangents[0].Set( 0.0f, 1.0f, 0.0f ); + tri->verts[ 0 ].tangents[1].Set( 0.0f, 0.0f, 1.0f ); + tri->verts[ 0 ].st[ 0 ] = 0.0f; + tri->verts[ 0 ].st[ 1 ] = 0.0f; + + tri->verts[ 1 ].Clear(); + tri->verts[ 1 ].normal.Set( 1.0f, 0.0f, 0.0f ); + tri->verts[ 1 ].tangents[0].Set( 0.0f, 1.0f, 0.0f ); + tri->verts[ 1 ].tangents[1].Set( 0.0f, 0.0f, 1.0f ); + tri->verts[ 1 ].st[ 0 ] = 1.0f; + tri->verts[ 1 ].st[ 1 ] = 0.0f; + + tri->verts[ 2 ].Clear(); + tri->verts[ 2 ].normal.Set( 1.0f, 0.0f, 0.0f ); + tri->verts[ 2 ].tangents[0].Set( 0.0f, 1.0f, 0.0f ); + tri->verts[ 2 ].tangents[1].Set( 0.0f, 0.0f, 1.0f ); + tri->verts[ 2 ].st[ 0 ] = 1.0f; + tri->verts[ 2 ].st[ 1 ] = 1.0f; + + tri->verts[ 3 ].Clear(); + tri->verts[ 3 ].normal.Set( 1.0f, 0.0f, 0.0f ); + tri->verts[ 3 ].tangents[0].Set( 0.0f, 1.0f, 0.0f ); + tri->verts[ 3 ].tangents[1].Set( 0.0f, 0.0f, 1.0f ); + tri->verts[ 3 ].st[ 0 ] = 0.0f; + tri->verts[ 3 ].st[ 1 ] = 1.0f; + + tri->indexes[ 0 ] = 0; + tri->indexes[ 1 ] = 1; + tri->indexes[ 2 ] = 3; + tri->indexes[ 3 ] = 1; + tri->indexes[ 4 ] = 2; + tri->indexes[ 5 ] = 3; + + tri->numVerts = 4; + tri->numIndexes = 6; + + surf.geometry = tri; + surf.id = 0; + surf.shader = tr.defaultMaterial; + staticModel->AddSurface( surf ); + } + + int red = idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_RED ] * 255.0f ); + int green = idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_GREEN ] * 255.0f ); + int blue = idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_BLUE ] * 255.0f ); + int alpha = idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_ALPHA ] * 255.0f ); + + idVec3 right = idVec3( 0.0f, renderEntity->shaderParms[ SHADERPARM_SPRITE_WIDTH ] * 0.5f, 0.0f ); + idVec3 up = idVec3( 0.0f, 0.0f, renderEntity->shaderParms[ SHADERPARM_SPRITE_HEIGHT ] * 0.5f ); + + tri->verts[ 0 ].xyz = up + right; + tri->verts[ 0 ].color[ 0 ] = red; + tri->verts[ 0 ].color[ 1 ] = green; + tri->verts[ 0 ].color[ 2 ] = blue; + tri->verts[ 0 ].color[ 3 ] = alpha; + + tri->verts[ 1 ].xyz = up - right; + tri->verts[ 1 ].color[ 0 ] = red; + tri->verts[ 1 ].color[ 1 ] = green; + tri->verts[ 1 ].color[ 2 ] = blue; + tri->verts[ 1 ].color[ 3 ] = alpha; + + tri->verts[ 2 ].xyz = - right - up; + tri->verts[ 2 ].color[ 0 ] = red; + tri->verts[ 2 ].color[ 1 ] = green; + tri->verts[ 2 ].color[ 2 ] = blue; + tri->verts[ 2 ].color[ 3 ] = alpha; + + tri->verts[ 3 ].xyz = right - up; + tri->verts[ 3 ].color[ 0 ] = red; + tri->verts[ 3 ].color[ 1 ] = green; + tri->verts[ 3 ].color[ 2 ] = blue; + tri->verts[ 3 ].color[ 3 ] = alpha; + + R_BoundTriSurf( tri ); + + staticModel->bounds = tri->bounds; + + return staticModel; +} + +/* +=============== +idRenderModelSprite::Bounds +=============== +*/ +idBounds idRenderModelSprite::Bounds( const struct renderEntity_s *renderEntity ) const { + idBounds b; + + b.Zero(); + if ( renderEntity == NULL ) { + b.ExpandSelf( 8.0f ); + } else { + b.ExpandSelf( Max( renderEntity->shaderParms[ SHADERPARM_SPRITE_WIDTH ], renderEntity->shaderParms[ SHADERPARM_SPRITE_HEIGHT ] ) * 0.5f ); + } + return b; +} diff --git a/renderer/RenderEntity.cpp b/renderer/RenderEntity.cpp new file mode 100644 index 000000000..5ce75c7b0 --- /dev/null +++ b/renderer/RenderEntity.cpp @@ -0,0 +1,108 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +idRenderEntityLocal::idRenderEntityLocal() { + memset( &parms, 0, sizeof( parms ) ); + memset( modelMatrix, 0, sizeof( modelMatrix ) ); + + world = NULL; + index = 0; + lastModifiedFrameNum = 0; + archived = false; + dynamicModel = NULL; + dynamicModelFrameCount = 0; + cachedDynamicModel = NULL; + referenceBounds = bounds_zero; + viewCount = 0; + viewEntity = NULL; + visibleCount = 0; + decals = NULL; + overlay = NULL; + entityRefs = NULL; + firstInteraction = NULL; + lastInteraction = NULL; + needsPortalSky = false; +} + +void idRenderEntityLocal::FreeRenderEntity() { +} + +void idRenderEntityLocal::UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate ) { +} + +void idRenderEntityLocal::GetRenderEntity( renderEntity_t *re ) { +} + +void idRenderEntityLocal::ForceUpdate() { +} + +int idRenderEntityLocal::GetIndex() { + return index; +} + +void idRenderEntityLocal::ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ) { +} +void idRenderEntityLocal::RemoveDecals() { +} + +//====================================================================== + +idRenderLightLocal::idRenderLightLocal() { + memset( &parms, 0, sizeof( parms ) ); + memset( modelMatrix, 0, sizeof( modelMatrix ) ); + memset( shadowFrustums, 0, sizeof( shadowFrustums ) ); + memset( lightProject, 0, sizeof( lightProject ) ); + memset( frustum, 0, sizeof( frustum ) ); + memset( frustumWindings, 0, sizeof( frustumWindings ) ); + + lightHasMoved = false; + world = NULL; + index = 0; + areaNum = 0; + lastModifiedFrameNum = 0; + archived = false; + lightShader = NULL; + falloffImage = NULL; + globalLightOrigin = vec3_zero; + frustumTris = NULL; + numShadowFrustums = 0; + viewCount = 0; + viewLight = NULL; + references = NULL; + foggedPortals = NULL; + firstInteraction = NULL; + lastInteraction = NULL; +} + +void idRenderLightLocal::FreeRenderLight() { +} +void idRenderLightLocal::UpdateRenderLight( const renderLight_t *re, bool forceUpdate ) { +} +void idRenderLightLocal::GetRenderLight( renderLight_t *re ) { +} +void idRenderLightLocal::ForceUpdate() { +} +int idRenderLightLocal::GetIndex() { + return index; +} diff --git a/renderer/RenderSystem.cpp b/renderer/RenderSystem.cpp new file mode 100644 index 000000000..4ebd81a3d --- /dev/null +++ b/renderer/RenderSystem.cpp @@ -0,0 +1,1032 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +idRenderSystemLocal tr; +idRenderSystem *renderSystem = &tr; + + +/* +===================== +R_PerformanceCounters + +This prints both front and back end counters, so it should +only be called when the back end thread is idle. +===================== +*/ +static void R_PerformanceCounters( void ) { + if ( r_showPrimitives.GetInteger() != 0 ) { + + float megaBytes = globalImages->SumOfUsedImages() / ( 1024*1024.0 ); + + if ( r_showPrimitives.GetInteger() > 1 ) { + common->Printf( "v:%i ds:%i t:%i/%i v:%i/%i st:%i sv:%i image:%5.1f MB\n", + tr.pc.c_numViews, + backEnd.pc.c_drawElements + backEnd.pc.c_shadowElements, + backEnd.pc.c_drawIndexes / 3, + ( backEnd.pc.c_drawIndexes - backEnd.pc.c_drawRefIndexes ) / 3, + backEnd.pc.c_drawVertexes, + ( backEnd.pc.c_drawVertexes - backEnd.pc.c_drawRefVertexes ), + backEnd.pc.c_shadowIndexes / 3, + backEnd.pc.c_shadowVertexes, + megaBytes + ); + } else { + common->Printf( "views:%i draws:%i tris:%i (shdw:%i) (vbo:%i) image:%5.1f MB\n", + tr.pc.c_numViews, + backEnd.pc.c_drawElements + backEnd.pc.c_shadowElements, + ( backEnd.pc.c_drawIndexes + backEnd.pc.c_shadowIndexes ) / 3, + backEnd.pc.c_shadowIndexes / 3, + backEnd.pc.c_vboIndexes / 3, + megaBytes + ); + } + } + + if ( r_showDynamic.GetBool() ) { + common->Printf( "callback:%i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i\n", + tr.pc.c_entityDefCallbacks, + tr.pc.c_generateMd5, + tr.pc.c_deformedVerts, + tr.pc.c_deformedIndexes/3, + tr.pc.c_tangentIndexes/3, + tr.pc.c_guiSurfs + ); + } + + if ( r_showCull.GetBool() ) { + common->Printf( "%i sin %i sclip %i sout %i bin %i bout\n", + tr.pc.c_sphere_cull_in, tr.pc.c_sphere_cull_clip, tr.pc.c_sphere_cull_out, + tr.pc.c_box_cull_in, tr.pc.c_box_cull_out ); + } + + if ( r_showAlloc.GetBool() ) { + common->Printf( "alloc:%i free:%i\n", tr.pc.c_alloc, tr.pc.c_free ); + } + + if ( r_showInteractions.GetBool() ) { + common->Printf( "createInteractions:%i createLightTris:%i createShadowVolumes:%i\n", + tr.pc.c_createInteractions, tr.pc.c_createLightTris, tr.pc.c_createShadowVolumes ); + } + if ( r_showDefs.GetBool() ) { + common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", tr.pc.c_visibleViewEntities, + tr.pc.c_shadowViewEntities, tr.pc.c_viewLights ); + } + if ( r_showUpdates.GetBool() ) { + common->Printf( "entityUpdates:%i entityRefs:%i lightUpdates:%i lightRefs:%i\n", + tr.pc.c_entityUpdates, tr.pc.c_entityReferences, + tr.pc.c_lightUpdates, tr.pc.c_lightReferences ); + } + if ( r_showMemory.GetBool() ) { + int m1 = frameData ? frameData->memoryHighwater : 0; + common->Printf( "frameData: %i (%i)\n", R_CountFrameData(), m1 ); + } + if ( r_showLightScale.GetBool() ) { + common->Printf( "lightScale: %f\n", backEnd.pc.maxLightValue ); + } + + memset( &tr.pc, 0, sizeof( tr.pc ) ); + memset( &backEnd.pc, 0, sizeof( backEnd.pc ) ); +} + + + +/* +==================== +R_IssueRenderCommands + +Called by R_EndFrame each frame +==================== +*/ +static void R_IssueRenderCommands( void ) { + if ( frameData->cmdHead->commandId == RC_NOP + && !frameData->cmdHead->next ) { + // nothing to issue + return; + } + + // r_skipBackEnd allows the entire time of the back end + // to be removed from performance measurements, although + // nothing will be drawn to the screen. If the prints + // are going to a file, or r_skipBackEnd is later disabled, + // usefull data can be received. + + // r_skipRender is usually more usefull, because it will still + // draw 2D graphics + if ( !r_skipBackEnd.GetBool() ) { + RB_ExecuteBackEndCommands( frameData->cmdHead ); + } + + R_ClearCommandChain(); +} + +/* +============ +R_GetCommandBuffer + +Returns memory for a command buffer (stretchPicCommand_t, +drawSurfsCommand_t, etc) and links it to the end of the +current command chain. +============ +*/ +void *R_GetCommandBuffer( int bytes ) { + emptyCommand_t *cmd; + + cmd = (emptyCommand_t *)R_FrameAlloc( bytes ); + cmd->next = NULL; + frameData->cmdTail->next = &cmd->commandId; + frameData->cmdTail = cmd; + + return (void *)cmd; +} + + +/* +==================== +R_ClearCommandChain + +Called after every buffer submission +and by R_ToggleSmpFrame +==================== +*/ +void R_ClearCommandChain( void ) { + // clear the command chain + frameData->cmdHead = frameData->cmdTail = (emptyCommand_t *)R_FrameAlloc( sizeof( *frameData->cmdHead ) ); + frameData->cmdHead->commandId = RC_NOP; + frameData->cmdHead->next = NULL; +} + +/* +================= +R_ViewStatistics +================= +*/ +static void R_ViewStatistics( viewDef_t *parms ) { + // report statistics about this view + if ( !r_showSurfaces.GetBool() ) { + return; + } + common->Printf( "view:%p surfs:%i\n", parms, parms->numDrawSurfs ); +} + +/* +============= +R_AddDrawViewCmd + +This is the main 3D rendering command. A single scene may +have multiple views if a mirror, portal, or dynamic texture is present. +============= +*/ +void R_AddDrawViewCmd( viewDef_t *parms ) { + drawSurfsCommand_t *cmd; + + cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); + cmd->commandId = RC_DRAW_VIEW; + + cmd->viewDef = parms; + + if ( parms->viewEntitys ) { + // save the command for r_lockSurfaces debugging + tr.lockSurfacesCmd = *cmd; + } + + tr.pc.c_numViews++; + + R_ViewStatistics( parms ); +} + + +//================================================================================= + + +/* +====================== +R_LockSurfaceScene + +r_lockSurfaces allows a developer to move around +without changing the composition of the scene, including +culling. The only thing that is modified is the +view position and axis, no front end work is done at all + + +Add the stored off command again, so the new rendering will use EXACTLY +the same surfaces, including all the culling, even though the transformation +matricies have been changed. This allow the culling tightness to be +evaluated interactively. +====================== +*/ +void R_LockSurfaceScene( viewDef_t *parms ) { + drawSurfsCommand_t *cmd; + viewEntity_t *vModel; + + // set the matrix for world space to eye space + R_SetViewMatrix( parms ); + tr.lockSurfacesCmd.viewDef->worldSpace = parms->worldSpace; + + // update the view origin and axis, and all + // the entity matricies + for( vModel = tr.lockSurfacesCmd.viewDef->viewEntitys ; vModel ; vModel = vModel->next ) { + myGlMultMatrix( vModel->modelMatrix, + tr.lockSurfacesCmd.viewDef->worldSpace.modelViewMatrix, + vModel->modelViewMatrix ); + } + + // add the stored off surface commands again + cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); + *cmd = tr.lockSurfacesCmd; +} + +/* +============= +R_CheckCvars + +See if some cvars that we watch have changed +============= +*/ +static void R_CheckCvars( void ) { + globalImages->CheckCvars(); + + // gamma stuff + if ( r_gamma.IsModified() || r_brightness.IsModified() ) { + r_gamma.ClearModified(); + r_brightness.ClearModified(); + R_SetColorMappings(); + } + + // check for changes to logging state + GLimp_EnableLogging( r_logFile.GetInteger() != 0 ); +} + +/* +============= +idRenderSystemLocal::idRenderSystemLocal +============= +*/ +idRenderSystemLocal::idRenderSystemLocal( void ) { + Clear(); +} + +/* +============= +idRenderSystemLocal::~idRenderSystemLocal +============= +*/ +idRenderSystemLocal::~idRenderSystemLocal( void ) { +} + +/* +============= +SetColor + +This can be used to pass general information to the current material, not +just colors +============= +*/ +void idRenderSystemLocal::SetColor( const idVec4 &rgba ) { + guiModel->SetColor( rgba[0], rgba[1], rgba[2], rgba[3] ); +} + + +/* +============= +SetColor4 +============= +*/ +void idRenderSystemLocal::SetColor4( float r, float g, float b, float a ) { + guiModel->SetColor( r, g, b, a ); +} + +/* +============= +DrawStretchPic +============= +*/ +void idRenderSystemLocal::DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, + bool clip, float min_x, float min_y, float max_x, float max_y ) { + guiModel->DrawStretchPic( verts, indexes, vertCount, indexCount, material, + clip, min_x, min_y, max_x, max_y ); +} + +/* +============= +DrawStretchPic + +x/y/w/h are in the 0,0 to 640,480 range +============= +*/ +void idRenderSystemLocal::DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) { + guiModel->DrawStretchPic( x, y, w, h, s1, t1, s2, t2, material ); +} + +/* +============= +DrawStretchTri + +x/y/w/h are in the 0,0 to 640,480 range +============= +*/ +void idRenderSystemLocal::DrawStretchTri( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) { + tr.guiModel->DrawStretchTri( p1, p2, p3, t1, t2, t3, material ); +} + +/* +============= +GlobalToNormalizedDeviceCoordinates +============= +*/ +void idRenderSystemLocal::GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ) { + R_GlobalToNormalizedDeviceCoordinates( global, ndc ); +} + +/* +============= +GlobalToNormalizedDeviceCoordinates +============= +*/ +void idRenderSystemLocal::GetGLSettings( int& width, int& height ) { + width = glConfig.vidWidth; + height = glConfig.vidHeight; +} + +/* +===================== +idRenderSystemLocal::DrawSmallChar + +small chars are drawn at native screen resolution +===================== +*/ +void idRenderSystemLocal::DrawSmallChar( int x, int y, int ch, const idMaterial *material ) { + int row, col; + float frow, fcol; + float size; + + ch &= 255; + + if ( ch == ' ' ) { + return; + } + + if ( y < -SMALLCHAR_HEIGHT ) { + return; + } + + row = ch >> 4; + col = ch & 15; + + frow = row * 0.0625f; + fcol = col * 0.0625f; + size = 0.0625f; + + DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, + fcol, frow, + fcol + size, frow + size, + material ); +} + +/* +================== +idRenderSystemLocal::DrawSmallString[Color] + +Draws a multi-colored string with a drop shadow, optionally forcing +to a fixed color. + +Coordinates are at 640 by 480 virtual resolution +================== +*/ +void idRenderSystemLocal::DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) { + idVec4 color; + const unsigned char *s; + int xx; + + // draw the colored text + s = (const unsigned char*)string; + xx = x; + SetColor( setColor ); + while ( *s ) { + if ( idStr::IsColor( (const char*)s ) ) { + if ( !forceColor ) { + if ( *(s+1) == C_COLOR_DEFAULT ) { + SetColor( setColor ); + } else { + color = idStr::ColorForIndex( *(s+1) ); + color[3] = setColor[3]; + SetColor( color ); + } + } + s += 2; + continue; + } + DrawSmallChar( xx, y, *s, material ); + xx += SMALLCHAR_WIDTH; + s++; + } + SetColor( colorWhite ); +} + +/* +===================== +idRenderSystemLocal::DrawBigChar +===================== +*/ +void idRenderSystemLocal::DrawBigChar( int x, int y, int ch, const idMaterial *material ) { + int row, col; + float frow, fcol; + float size; + + ch &= 255; + + if ( ch == ' ' ) { + return; + } + + if ( y < -BIGCHAR_HEIGHT ) { + return; + } + + row = ch >> 4; + col = ch & 15; + + frow = row * 0.0625f; + fcol = col * 0.0625f; + size = 0.0625f; + + DrawStretchPic( x, y, BIGCHAR_WIDTH, BIGCHAR_HEIGHT, + fcol, frow, + fcol + size, frow + size, + material ); +} + +/* +================== +idRenderSystemLocal::DrawBigString[Color] + +Draws a multi-colored string with a drop shadow, optionally forcing +to a fixed color. + +Coordinates are at 640 by 480 virtual resolution +================== +*/ +void idRenderSystemLocal::DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) { + idVec4 color; + const char *s; + int xx; + + // draw the colored text + s = string; + xx = x; + SetColor( setColor ); + while ( *s ) { + if ( idStr::IsColor( s ) ) { + if ( !forceColor ) { + if ( *(s+1) == C_COLOR_DEFAULT ) { + SetColor( setColor ); + } else { + color = idStr::ColorForIndex( *(s+1) ); + color[3] = setColor[3]; + SetColor( color ); + } + } + s += 2; + continue; + } + DrawBigChar( xx, y, *s, material ); + xx += BIGCHAR_WIDTH; + s++; + } + SetColor( colorWhite ); +} + +//====================================================================================== + +/* +================== +SetBackEndRenderer + +Check for changes in the back end renderSystem, possibly invalidating cached data +================== +*/ +void idRenderSystemLocal::SetBackEndRenderer() { + if ( !r_renderer.IsModified() ) { + return; + } + + bool oldVPstate = backEndRendererHasVertexPrograms; + + backEndRenderer = BE_BAD; + + if ( idStr::Icmp( r_renderer.GetString(), "arb" ) == 0 ) { + backEndRenderer = BE_ARB; + } else if ( idStr::Icmp( r_renderer.GetString(), "arb2" ) == 0 ) { + if ( glConfig.allowARB2Path ) { + backEndRenderer = BE_ARB2; + } + } else if ( idStr::Icmp( r_renderer.GetString(), "nv10" ) == 0 ) { + if ( glConfig.allowNV10Path ) { + backEndRenderer = BE_NV10; + } + } else if ( idStr::Icmp( r_renderer.GetString(), "nv20" ) == 0 ) { + if ( glConfig.allowNV20Path ) { + backEndRenderer = BE_NV20; + } + } else if ( idStr::Icmp( r_renderer.GetString(), "r200" ) == 0 ) { + if ( glConfig.allowR200Path ) { + backEndRenderer = BE_R200; + } + } + + // fallback + if ( backEndRenderer == BE_BAD ) { + // choose the best + if ( glConfig.allowARB2Path ) { + backEndRenderer = BE_ARB2; + } else if ( glConfig.allowR200Path ) { + backEndRenderer = BE_R200; + } else if ( glConfig.allowNV20Path ) { + backEndRenderer = BE_NV20; + } else if ( glConfig.allowNV10Path ) { + backEndRenderer = BE_NV10; + } else { + // the others are considered experimental + backEndRenderer = BE_ARB; + } + } + + backEndRendererHasVertexPrograms = false; + backEndRendererMaxLight = 1.0; + + switch( backEndRenderer ) { + case BE_ARB: + common->Printf( "using ARB renderSystem\n" ); + break; + case BE_NV10: + common->Printf( "using NV10 renderSystem\n" ); + break; + case BE_NV20: + common->Printf( "using NV20 renderSystem\n" ); + backEndRendererHasVertexPrograms = true; + break; + case BE_R200: + common->Printf( "using R200 renderSystem\n" ); + backEndRendererHasVertexPrograms = true; + break; + case BE_ARB2: + common->Printf( "using ARB2 renderSystem\n" ); + backEndRendererHasVertexPrograms = true; + backEndRendererMaxLight = 999; + break; + default: + common->FatalError( "SetbackEndRenderer: bad back end" ); + } + + // clear the vertex cache if we are changing between + // using vertex programs and not, because specular and + // shadows will be different data + if ( oldVPstate != backEndRendererHasVertexPrograms ) { + vertexCache.PurgeAll(); + if ( primaryWorld ) { + primaryWorld->FreeInteractions(); + } + } + + r_renderer.ClearModified(); +} + +/* +==================== +BeginFrame +==================== +*/ +void idRenderSystemLocal::BeginFrame( int windowWidth, int windowHeight ) { + setBufferCommand_t *cmd; + + if ( !glConfig.isInitialized ) { + return; + } + + // determine which back end we will use + SetBackEndRenderer(); + + guiModel->Clear(); + + // for the larger-than-window tiled rendering screenshots + if ( tiledViewport[0] ) { + windowWidth = tiledViewport[0]; + windowHeight = tiledViewport[1]; + } + + glConfig.vidWidth = windowWidth; + glConfig.vidHeight = windowHeight; + + renderCrops[0].x = 0; + renderCrops[0].y = 0; + renderCrops[0].width = windowWidth; + renderCrops[0].height = windowHeight; + currentRenderCrop = 0; + + // screenFraction is just for quickly testing fill rate limitations + if ( r_screenFraction.GetInteger() != 100 ) { + int w = SCREEN_WIDTH * r_screenFraction.GetInteger() / 100.0f; + int h = SCREEN_HEIGHT * r_screenFraction.GetInteger() / 100.0f; + CropRenderSize( w, h ); + } + + + // this is the ONLY place this is modified + frameCount++; + + // just in case we did a common->Error while this + // was set + guiRecursionLevel = 0; + + // the first rendering will be used for commands like + // screenshot, rather than a possible subsequent remote + // or mirror render +// primaryWorld = NULL; + + // set the time for shader effects in 2D rendering + frameShaderTime = eventLoop->Milliseconds() * 0.001; + + // + // draw buffer stuff + // + cmd = (setBufferCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); + cmd->commandId = RC_SET_BUFFER; + cmd->frameCount = frameCount; + + if ( r_frontBuffer.GetBool() ) { + cmd->buffer = (int)GL_FRONT; + } else { + cmd->buffer = (int)GL_BACK; + } +} + +void idRenderSystemLocal::WriteDemoPics() { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_GUI_MODEL ); + guiModel->WriteToDemo( session->writeDemo ); +} + +void idRenderSystemLocal::DrawDemoPics() { + demoGuiModel->EmitFullScreen(); +} + +/* +============= +EndFrame + +Returns the number of msec spent in the back end +============= +*/ +void idRenderSystemLocal::EndFrame( int *frontEndMsec, int *backEndMsec ) { + emptyCommand_t *cmd; + + if ( !glConfig.isInitialized ) { + return; + } + + // close any gui drawing + guiModel->EmitFullScreen(); + guiModel->Clear(); + + // save out timing information + if ( frontEndMsec ) { + *frontEndMsec = pc.frontEndMsec; + } + if ( backEndMsec ) { + *backEndMsec = backEnd.pc.msec; + } + + // print any other statistics and clear all of them + R_PerformanceCounters(); + + // check for dynamic changes that require some initialization + R_CheckCvars(); + + // check for errors + GL_CheckErrors(); + + // add the swapbuffers command + cmd = (emptyCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); + cmd->commandId = RC_SWAP_BUFFERS; + + // start the back end up again with the new command list + R_IssueRenderCommands(); + + // use the other buffers next frame, because another CPU + // may still be rendering into the current buffers + R_ToggleSmpFrame(); + + // we can now release the vertexes used this frame + vertexCache.EndFrame(); + + if ( session->writeDemo ) { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_END_FRAME ); + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_END_FRAME\n" ); + } + } + +} + +/* +===================== +RenderViewToViewport + +Converts from SCREEN_WIDTH / SCREEN_HEIGHT coordinates to current cropped pixel coordinates +===================== +*/ +void idRenderSystemLocal::RenderViewToViewport( const renderView_t *renderView, idScreenRect *viewport ) { + renderCrop_t *rc = &renderCrops[currentRenderCrop]; + + float wRatio = (float)rc->width / SCREEN_WIDTH; + float hRatio = (float)rc->height / SCREEN_HEIGHT; + + viewport->x1 = idMath::Ftoi( rc->x + renderView->x * wRatio ); + viewport->x2 = idMath::Ftoi( rc->x + floor( ( renderView->x + renderView->width ) * wRatio + 0.5f ) - 1 ); + viewport->y1 = idMath::Ftoi( ( rc->y + rc->height ) - floor( ( renderView->y + renderView->height ) * hRatio + 0.5f ) ); + viewport->y2 = idMath::Ftoi( ( rc->y + rc->height ) - floor( renderView->y * hRatio + 0.5f ) - 1 ); +} + +static int RoundDownToPowerOfTwo( int v ) { + int i; + + for ( i = 0 ; i < 20 ; i++ ) { + if ( ( 1 << i ) == v ) { + return v; + } + if ( ( 1 << i ) > v ) { + return 1 << ( i-1 ); + } + } + return 1<EmitFullScreen(); + guiModel->Clear(); + + if ( width < 1 || height < 1 ) { + common->Error( "CropRenderSize: bad sizes" ); + } + + if ( session->writeDemo ) { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_CROP_RENDER ); + session->writeDemo->WriteInt( width ); + session->writeDemo->WriteInt( height ); + session->writeDemo->WriteInt( makePowerOfTwo ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_CROP_RENDER\n" ); + } + } + + // convert from virtual SCREEN_WIDTH/SCREEN_HEIGHT coordinates to physical OpenGL pixels + renderView_t renderView; + renderView.x = 0; + renderView.y = 0; + renderView.width = width; + renderView.height = height; + + idScreenRect r; + RenderViewToViewport( &renderView, &r ); + + width = r.x2 - r.x1 + 1; + height = r.y2 - r.y1 + 1; + + if ( forceDimensions ) { + // just give exactly what we ask for + width = renderView.width; + height = renderView.height; + } + + // if makePowerOfTwo, drop to next lower power of two after scaling to physical pixels + if ( makePowerOfTwo ) { + width = RoundDownToPowerOfTwo( width ); + height = RoundDownToPowerOfTwo( height ); + // FIXME: megascreenshots with offset viewports don't work right with this yet + } + + renderCrop_t *rc = &renderCrops[currentRenderCrop]; + + // we might want to clip these to the crop window instead + while ( width > glConfig.vidWidth ) { + width >>= 1; + } + while ( height > glConfig.vidHeight ) { + height >>= 1; + } + + if ( currentRenderCrop == MAX_RENDER_CROPS ) { + common->Error( "idRenderSystemLocal::CropRenderSize: currentRenderCrop == MAX_RENDER_CROPS" ); + } + + currentRenderCrop++; + + rc = &renderCrops[currentRenderCrop]; + + rc->x = 0; + rc->y = 0; + rc->width = width; + rc->height = height; +} + +/* +================ +UnCrop +================ +*/ +void idRenderSystemLocal::UnCrop() { + if ( !glConfig.isInitialized ) { + return; + } + + if ( currentRenderCrop < 1 ) { + common->Error( "idRenderSystemLocal::UnCrop: currentRenderCrop < 1" ); + } + + // close any gui drawing + guiModel->EmitFullScreen(); + guiModel->Clear(); + + currentRenderCrop--; + + if ( session->writeDemo ) { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_UNCROP_RENDER ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_UNCROP\n" ); + } + } +} + +/* +================ +CaptureRenderToImage +================ +*/ +void idRenderSystemLocal::CaptureRenderToImage( const char *imageName ) { + if ( !glConfig.isInitialized ) { + return; + } + guiModel->EmitFullScreen(); + guiModel->Clear(); + + if ( session->writeDemo ) { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_CAPTURE_RENDER ); + session->writeDemo->WriteHashString( imageName ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_CAPTURE_RENDER: %s\n", imageName ); + } + } + + // look up the image before we create the render command, because it + // may need to sync to create the image + idImage *image = globalImages->ImageFromFile(imageName, TF_DEFAULT, true, TR_REPEAT, TD_DEFAULT); + + renderCrop_t *rc = &renderCrops[currentRenderCrop]; + + copyRenderCommand_t *cmd = (copyRenderCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); + cmd->commandId = RC_COPY_RENDER; + cmd->x = rc->x; + cmd->y = rc->y; + cmd->imageWidth = rc->width; + cmd->imageHeight = rc->height; + cmd->image = image; + + guiModel->Clear(); +} + +/* +============== +CaptureRenderToFile + +============== +*/ +void idRenderSystemLocal::CaptureRenderToFile( const char *fileName, bool fixAlpha ) { + if ( !glConfig.isInitialized ) { + return; + } + + renderCrop_t *rc = &renderCrops[currentRenderCrop]; + + guiModel->EmitFullScreen(); + guiModel->Clear(); + R_IssueRenderCommands(); + + qglReadBuffer( GL_BACK ); + + // include extra space for OpenGL padding to word boundaries + int c = ( rc->width + 3 ) * rc->height; + byte *data = (byte *)R_StaticAlloc( c * 3 ); + + qglReadPixels( rc->x, rc->y, rc->width, rc->height, GL_RGB, GL_UNSIGNED_BYTE, data ); + + byte *data2 = (byte *)R_StaticAlloc( c * 4 ); + + for ( int i = 0 ; i < c ; i++ ) { + data2[ i * 4 ] = data[ i * 3 ]; + data2[ i * 4 + 1 ] = data[ i * 3 + 1 ]; + data2[ i * 4 + 2 ] = data[ i * 3 + 2 ]; + data2[ i * 4 + 3 ] = 0xff; + } + + R_WriteTGA( fileName, data2, rc->width, rc->height, true ); + + R_StaticFree( data ); + R_StaticFree( data2 ); +} + + +/* +============== +AllocRenderWorld +============== +*/ +idRenderWorld *idRenderSystemLocal::AllocRenderWorld() { + idRenderWorldLocal *rw; + rw = new idRenderWorldLocal; + worlds.Append( rw ); + return rw; +} + +/* +============== +FreeRenderWorld +============== +*/ +void idRenderSystemLocal::FreeRenderWorld( idRenderWorld *rw ) { + if ( primaryWorld == rw ) { + primaryWorld = NULL; + } + worlds.Remove( static_cast(rw) ); + delete rw; +} + +/* +============== +PrintMemInfo +============== +*/ +void idRenderSystemLocal::PrintMemInfo( MemInfo_t *mi ) { + // sum up image totals + globalImages->PrintMemInfo( mi ); + + // sum up model totals + renderModelManager->PrintMemInfo( mi ); + + // compute render totals + +} + +/* +=============== +idRenderSystemLocal::UploadImage +=============== +*/ +bool idRenderSystemLocal::UploadImage( const char *imageName, const byte *data, int width, int height ) { + idImage *image = globalImages->GetImage( imageName ); + if ( !image ) { + return false; + } + image->UploadScratch( data, width, height ); + image->SetImageFilterAndRepeat(); + return true; +} diff --git a/renderer/RenderSystem.h b/renderer/RenderSystem.h new file mode 100644 index 000000000..5e555f676 --- /dev/null +++ b/renderer/RenderSystem.h @@ -0,0 +1,267 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __RENDERER_H__ +#define __RENDERER_H__ + +/* +=============================================================================== + + idRenderSystem is responsible for managing the screen, which can have + multiple idRenderWorld and 2D drawing done on it. + +=============================================================================== +*/ + + +// Contains variables specific to the OpenGL configuration being run right now. +// These are constant once the OpenGL subsystem is initialized. +typedef struct glconfig_s { + const char *renderer_string; + const char *vendor_string; + const char *version_string; + const char *extensions_string; + const char *wgl_extensions_string; + + float glVersion; // atof( version_string ) + + + int maxTextureSize; // queried from GL + int maxTextureUnits; + int maxTextureCoords; + int maxTextureImageUnits; + float maxTextureAnisotropy; + + int colorBits, depthBits, stencilBits; + + bool multitextureAvailable; + bool textureCompressionAvailable; + bool anisotropicAvailable; + bool textureLODBiasAvailable; + bool textureEnvAddAvailable; + bool textureEnvCombineAvailable; + bool registerCombinersAvailable; + bool cubeMapAvailable; + bool envDot3Available; + bool texture3DAvailable; + bool sharedTexturePaletteAvailable; + bool ARBVertexBufferObjectAvailable; + bool ARBVertexProgramAvailable; + bool ARBFragmentProgramAvailable; + bool twoSidedStencilAvailable; + bool textureNonPowerOfTwoAvailable; + bool depthBoundsTestAvailable; + + // ati r200 extensions + bool atiFragmentShaderAvailable; + + // ati r300 + bool atiTwoSidedStencilAvailable; + + int vidWidth, vidHeight; // passed to R_BeginFrame + + int displayFrequency; + + bool isFullscreen; + + bool allowNV30Path; + bool allowNV20Path; + bool allowNV10Path; + bool allowR200Path; + bool allowARB2Path; + + bool isInitialized; +} glconfig_t; + + +// font support +const int GLYPH_START = 0; +const int GLYPH_END = 255; +const int GLYPH_CHARSTART = 32; +const int GLYPH_CHAREND = 127; +const int GLYPHS_PER_FONT = GLYPH_END - GLYPH_START + 1; + +typedef struct { + int height; // number of scan lines + int top; // top of glyph in buffer + int bottom; // bottom of glyph in buffer + int pitch; // width for copying + int xSkip; // x adjustment + int imageWidth; // width of actual image + int imageHeight; // height of actual image + float s; // x offset in image where glyph starts + float t; // y offset in image where glyph starts + float s2; + float t2; + const idMaterial * glyph; // shader with the glyph + char shaderName[32]; +} glyphInfo_t; + +typedef struct { + glyphInfo_t glyphs [GLYPHS_PER_FONT]; + float glyphScale; + char name[64]; +} fontInfo_t; + +typedef struct { + fontInfo_t fontInfoSmall; + fontInfo_t fontInfoMedium; + fontInfo_t fontInfoLarge; + int maxHeight; + int maxWidth; + int maxHeightSmall; + int maxWidthSmall; + int maxHeightMedium; + int maxWidthMedium; + int maxHeightLarge; + int maxWidthLarge; + char name[64]; +} fontInfoEx_t; + +const int SMALLCHAR_WIDTH = 8; +const int SMALLCHAR_HEIGHT = 16; +const int BIGCHAR_WIDTH = 16; +const int BIGCHAR_HEIGHT = 16; + +// all drawing is done to a 640 x 480 virtual screen size +// and will be automatically scaled to the real resolution +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; + +class idRenderWorld; + + +class idRenderSystem { +public: + + virtual ~idRenderSystem() {} + + // set up cvars and basic data structures, but don't + // init OpenGL, so it can also be used for dedicated servers + virtual void Init( void ) = 0; + + // only called before quitting + virtual void Shutdown( void ) = 0; + + virtual void InitOpenGL( void ) = 0; + + virtual void ShutdownOpenGL( void ) = 0; + + virtual bool IsOpenGLRunning( void ) const = 0; + + virtual bool IsFullScreen( void ) const = 0; + virtual int GetScreenWidth( void ) const = 0; + virtual int GetScreenHeight( void ) const = 0; + + // allocate a renderWorld to be used for drawing + virtual idRenderWorld * AllocRenderWorld( void ) = 0; + virtual void FreeRenderWorld( idRenderWorld * rw ) = 0; + + // All data that will be used in a level should be + // registered before rendering any frames to prevent disk hits, + // but they can still be registered at a later time + // if necessary. + virtual void BeginLevelLoad( void ) = 0; + virtual void EndLevelLoad( void ) = 0; + + // font support + virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ) = 0; + + // GUI drawing just involves shader parameter setting and axial image subsections + virtual void SetColor( const idVec4 &rgba ) = 0; + virtual void SetColor4( float r, float g, float b, float a ) = 0; + + virtual void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, + bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f ) = 0; + virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) = 0; + + virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) = 0; + virtual void GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ) = 0; + virtual void GetGLSettings( int& width, int& height ) = 0; + virtual void PrintMemInfo( MemInfo_t *mi ) = 0; + + virtual void DrawSmallChar( int x, int y, int ch, const idMaterial *material ) = 0; + virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0; + virtual void DrawBigChar( int x, int y, int ch, const idMaterial *material ) = 0; + virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0; + + // dump all 2D drawing so far this frame to the demo file + virtual void WriteDemoPics() = 0; + + // draw the 2D pics that were saved out with the current demo frame + virtual void DrawDemoPics() = 0; + + // FIXME: add an interface for arbitrary point/texcoord drawing + + + // a frame cam consist of 2D drawing and potentially multiple 3D scenes + // window sizes are needed to convert SCREEN_WIDTH / SCREEN_HEIGHT values + virtual void BeginFrame( int windowWidth, int windowHeight ) = 0; + + // if the pointers are not NULL, timing info will be returned + virtual void EndFrame( int *frontEndMsec, int *backEndMsec ) = 0; + + // aviDemo uses this. + // Will automatically tile render large screen shots if necessary + // Samples is the number of jittered frames for anti-aliasing + // If ref == NULL, session->updateScreen will be used + // This will perform swapbuffers, so it is NOT an approppriate way to + // generate image files that happen during gameplay, as for savegame + // markers. Use WriteRender() instead. + virtual void TakeScreenshot( int width, int height, const char *fileName, int samples, struct renderView_s *ref ) = 0; + + // the render output can be cropped down to a subset of the real screen, as + // for save-game reviews and split-screen multiplayer. Users of the renderer + // will not know the actual pixel size of the area they are rendering to + + // the x,y,width,height values are in virtual SCREEN_WIDTH / SCREEN_HEIGHT coordinates + + // to render to a texture, first set the crop size with makePowerOfTwo = true, + // then perform all desired rendering, then capture to an image + // if the specified physical dimensions are larger than the current cropped region, they will be cut down to fit + virtual void CropRenderSize( int width, int height, bool makePowerOfTwo = false, bool forceDimensions = false ) = 0; + virtual void CaptureRenderToImage( const char *imageName ) = 0; + // fixAlpha will set all the alpha channel values to 0xff, which allows screen captures + // to use the default tga loading code without having dimmed down areas in many places + virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha = false ) = 0; + virtual void UnCrop() = 0; + virtual void GetCardCaps( bool &oldCard, bool &nv10or20 ) = 0; + + // the image has to be already loaded ( most straightforward way would be through a FindMaterial ) + // texture filter / mipmapping / repeat won't be modified by the upload + // returns false if the image wasn't found + virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ) = 0; +}; + +extern idRenderSystem * renderSystem; + +// +// functions mainly intended for editor and dmap integration +// + +// returns the frustum planes in world space +void R_RenderLightFrustum( const struct renderLight_s &renderLight, idPlane lightFrustum[6] ); + +// for use by dmap to do the carving-on-light-boundaries and for the editor for display +void R_LightProjectionMatrix( const idVec3 &origin, const idPlane &rearPlane, idVec4 mat[4] ); + +// used by the view shot taker +void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ); + +#endif /* !__RENDERER_H__ */ diff --git a/renderer/RenderSystem_init.cpp b/renderer/RenderSystem_init.cpp new file mode 100644 index 000000000..4e235352d --- /dev/null +++ b/renderer/RenderSystem_init.cpp @@ -0,0 +1,2315 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +// Vista OpenGL wrapper check +#ifdef _WIN32 +#include "../sys/win32/win_local.h" +#endif + +// functions that are not called every frame + +glconfig_t glConfig; + +static void GfxInfo_f( void ); + +const char *r_rendererArgs[] = { "best", "arb", "arb2", "Cg", "exp", "nv10", "nv20", "r200", NULL }; + +idCVar r_inhibitFragmentProgram( "r_inhibitFragmentProgram", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the fragment program extension" ); +idCVar r_glDriver( "r_glDriver", "", CVAR_RENDERER, "\"opengl32\", etc." ); +idCVar r_useLightPortalFlow( "r_useLightPortalFlow", "1", CVAR_RENDERER | CVAR_BOOL, "use a more precise area reference determination" ); +idCVar r_multiSamples( "r_multiSamples", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "number of antialiasing samples" ); +idCVar r_mode( "r_mode", "3", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_INTEGER, "video mode number" ); +idCVar r_displayRefresh( "r_displayRefresh", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_NOCHEAT, "optional display refresh rate option for vid mode", 0.0f, 200.0f ); +idCVar r_fullscreen( "r_fullscreen", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "0 = windowed, 1 = full screen" ); +idCVar r_customWidth( "r_customWidth", "720", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen width. set r_mode to -1 to activate" ); +idCVar r_customHeight( "r_customHeight", "486", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen height. set r_mode to -1 to activate" ); +idCVar r_singleTriangle( "r_singleTriangle", "0", CVAR_RENDERER | CVAR_BOOL, "only draw a single triangle per primitive" ); +idCVar r_checkBounds( "r_checkBounds", "0", CVAR_RENDERER | CVAR_BOOL, "compare all surface bounds with precalculated ones" ); + +idCVar r_useNV20MonoLights( "r_useNV20MonoLights", "1", CVAR_RENDERER | CVAR_INTEGER, "use pass optimization for mono lights" ); +idCVar r_useConstantMaterials( "r_useConstantMaterials", "1", CVAR_RENDERER | CVAR_BOOL, "use pre-calculated material registers if possible" ); +idCVar r_useTripleTextureARB( "r_useTripleTextureARB", "1", CVAR_RENDERER | CVAR_BOOL, "cards with 3+ texture units do a two pass instead of three pass" ); +idCVar r_useSilRemap( "r_useSilRemap", "1", CVAR_RENDERER | CVAR_BOOL, "consider verts with the same XYZ, but different ST the same for shadows" ); +idCVar r_useNodeCommonChildren( "r_useNodeCommonChildren", "1", CVAR_RENDERER | CVAR_BOOL, "stop pushing reference bounds early when possible" ); +idCVar r_useShadowProjectedCull( "r_useShadowProjectedCull", "1", CVAR_RENDERER | CVAR_BOOL, "discard triangles outside light volume before shadowing" ); +idCVar r_useShadowVertexProgram( "r_useShadowVertexProgram", "1", CVAR_RENDERER | CVAR_BOOL, "do the shadow projection in the vertex program on capable cards" ); +idCVar r_useShadowSurfaceScissor( "r_useShadowSurfaceScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor shadows by the scissor rect of the interaction surfaces" ); +idCVar r_useInteractionTable( "r_useInteractionTable", "1", CVAR_RENDERER | CVAR_BOOL, "create a full entityDefs * lightDefs table to make finding interactions faster" ); +idCVar r_useTurboShadow( "r_useTurboShadow", "1", CVAR_RENDERER | CVAR_BOOL, "use the infinite projection with W technique for dynamic shadows" ); +idCVar r_useTwoSidedStencil( "r_useTwoSidedStencil", "1", CVAR_RENDERER | CVAR_BOOL, "do stencil shadows in one pass with different ops on each side" ); +idCVar r_useDeferredTangents( "r_useDeferredTangents", "1", CVAR_RENDERER | CVAR_BOOL, "defer tangents calculations after deform" ); +idCVar r_useCachedDynamicModels( "r_useCachedDynamicModels", "1", CVAR_RENDERER | CVAR_BOOL, "cache snapshots of dynamic models" ); + +idCVar r_useVertexBuffers( "r_useVertexBuffers", "1", CVAR_RENDERER | CVAR_INTEGER, "use ARB_vertex_buffer_object for vertexes", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> ); +idCVar r_useIndexBuffers( "r_useIndexBuffers", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "use ARB_vertex_buffer_object for indexes", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> ); + +idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" ); +idCVar r_useInfiniteFarZ( "r_useInfiniteFarZ", "1", CVAR_RENDERER | CVAR_BOOL, "use the no-far-clip-plane trick" ); + +idCVar r_znear( "r_znear", "3", CVAR_RENDERER | CVAR_FLOAT, "near Z clip plane distance", 0.001f, 200.0f ); + +idCVar r_ignoreGLErrors( "r_ignoreGLErrors", "1", CVAR_RENDERER | CVAR_BOOL, "ignore GL errors" ); +idCVar r_finish( "r_finish", "0", CVAR_RENDERER | CVAR_BOOL, "force a call to glFinish() every frame" ); +idCVar r_swapInterval( "r_swapInterval", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "changes wglSwapIntarval" ); + +idCVar r_gamma( "r_gamma", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 3.0f ); +idCVar r_brightness( "r_brightness", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 2.0f ); + +idCVar r_renderer( "r_renderer", "best", CVAR_RENDERER | CVAR_ARCHIVE, "hardware specific renderer path to use", r_rendererArgs, idCmdSystem::ArgCompletion_String ); + +idCVar r_jitter( "r_jitter", "0", CVAR_RENDERER | CVAR_BOOL, "randomly subpixel jitter the projection matrix" ); + +idCVar r_skipSuppress( "r_skipSuppress", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the per-view suppressions" ); +idCVar r_skipPostProcess( "r_skipPostProcess", "0", CVAR_RENDERER | CVAR_BOOL, "skip all post-process renderings" ); +idCVar r_skipLightScale( "r_skipLightScale", "0", CVAR_RENDERER | CVAR_BOOL, "don't do any post-interaction light scaling, makes things dim on low-dynamic range cards" ); +idCVar r_skipInteractions( "r_skipInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "skip all light/surface interaction drawing" ); +idCVar r_skipDynamicTextures( "r_skipDynamicTextures", "0", CVAR_RENDERER | CVAR_BOOL, "don't dynamically create textures" ); +idCVar r_skipCopyTexture( "r_skipCopyTexture", "0", CVAR_RENDERER | CVAR_BOOL, "do all rendering, but don't actually copyTexSubImage2D" ); +idCVar r_skipBackEnd( "r_skipBackEnd", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw anything" ); +idCVar r_skipRender( "r_skipRender", "0", CVAR_RENDERER | CVAR_BOOL, "skip 3D rendering, but pass 2D" ); +idCVar r_skipRenderContext( "r_skipRenderContext", "0", CVAR_RENDERER | CVAR_BOOL, "NULL the rendering context during backend 3D rendering" ); +idCVar r_skipTranslucent( "r_skipTranslucent", "0", CVAR_RENDERER | CVAR_BOOL, "skip the translucent interaction rendering" ); +idCVar r_skipAmbient( "r_skipAmbient", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all non-interaction drawing" ); +idCVar r_skipNewAmbient( "r_skipNewAmbient", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "bypasses all vertex/fragment program ambient drawing" ); +idCVar r_skipBlendLights( "r_skipBlendLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all blend lights" ); +idCVar r_skipFogLights( "r_skipFogLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all fog lights" ); +idCVar r_skipDeforms( "r_skipDeforms", "0", CVAR_RENDERER | CVAR_BOOL, "leave all deform materials in their original state" ); +idCVar r_skipFrontEnd( "r_skipFrontEnd", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all front end work, but 2D gui rendering still draws" ); +idCVar r_skipUpdates( "r_skipUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't accept any entity or light updates, making everything static" ); +idCVar r_skipOverlays( "r_skipOverlays", "0", CVAR_RENDERER | CVAR_BOOL, "skip overlay surfaces" ); +idCVar r_skipSpecular( "r_skipSpecular", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_CHEAT | CVAR_ARCHIVE, "use black for specular1" ); +idCVar r_skipBump( "r_skipBump", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "uses a flat surface instead of the bump map" ); +idCVar r_skipDiffuse( "r_skipDiffuse", "0", CVAR_RENDERER | CVAR_BOOL, "use black for diffuse" ); +idCVar r_skipROQ( "r_skipROQ", "0", CVAR_RENDERER | CVAR_BOOL, "skip ROQ decoding" ); + +idCVar r_ignore( "r_ignore", "0", CVAR_RENDERER, "used for random debugging without defining new vars" ); +idCVar r_ignore2( "r_ignore2", "0", CVAR_RENDERER, "used for random debugging without defining new vars" ); +idCVar r_usePreciseTriangleInteractions( "r_usePreciseTriangleInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "1 = do winding clipping to determine if each ambiguous tri should be lit" ); +idCVar r_useCulling( "r_useCulling", "2", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = sphere, 2 = sphere + box", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_useLightCulling( "r_useLightCulling", "3", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = box, 2 = exact clip of polyhedron faces, 3 = also areas", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_useLightScissors( "r_useLightScissors", "1", CVAR_RENDERER | CVAR_BOOL, "1 = use custom scissor rectangle for each light" ); +idCVar r_useClippedLightScissors( "r_useClippedLightScissors", "1", CVAR_RENDERER | CVAR_INTEGER, "0 = full screen when near clipped, 1 = exact when near clipped, 2 = exact always", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_useEntityCulling( "r_useEntityCulling", "1", CVAR_RENDERER | CVAR_BOOL, "0 = none, 1 = box" ); +idCVar r_useEntityScissors( "r_useEntityScissors", "0", CVAR_RENDERER | CVAR_BOOL, "1 = use custom scissor rectangle for each entity" ); +idCVar r_useInteractionCulling( "r_useInteractionCulling", "1", CVAR_RENDERER | CVAR_BOOL, "1 = cull interactions" ); +idCVar r_useInteractionScissors( "r_useInteractionScissors", "2", CVAR_RENDERER | CVAR_INTEGER, "1 = use a custom scissor rectangle for each shadow interaction, 2 = also crop using portal scissors", -2, 2, idCmdSystem::ArgCompletion_Integer<-2,2> ); +idCVar r_useShadowCulling( "r_useShadowCulling", "1", CVAR_RENDERER | CVAR_BOOL, "try to cull shadows from partially visible lights" ); +idCVar r_useFrustumFarDistance( "r_useFrustumFarDistance", "0", CVAR_RENDERER | CVAR_FLOAT, "if != 0 force the view frustum far distance to this distance" ); +idCVar r_logFile( "r_logFile", "0", CVAR_RENDERER | CVAR_INTEGER, "number of frames to emit GL logs" ); +idCVar r_clear( "r_clear", "2", CVAR_RENDERER, "force screen clear every frame, 1 = purple, 2 = black, 'r g b' = custom" ); +idCVar r_offsetFactor( "r_offsetfactor", "0", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" ); +idCVar r_offsetUnits( "r_offsetunits", "-600", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" ); +idCVar r_shadowPolygonOffset( "r_shadowPolygonOffset", "-1", CVAR_RENDERER | CVAR_FLOAT, "bias value added to depth test for stencil shadow drawing" ); +idCVar r_shadowPolygonFactor( "r_shadowPolygonFactor", "0", CVAR_RENDERER | CVAR_FLOAT, "scale value for stencil shadow drawing" ); +idCVar r_frontBuffer( "r_frontBuffer", "0", CVAR_RENDERER | CVAR_BOOL, "draw to front buffer for debugging" ); +idCVar r_skipSubviews( "r_skipSubviews", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = don't render any gui elements on surfaces" ); +idCVar r_skipGuiShaders( "r_skipGuiShaders", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all gui elements on surfaces, 2 = skip drawing but still handle events, 3 = draw but skip events", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_skipParticles( "r_skipParticles", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> ); +idCVar r_subviewOnly( "r_subviewOnly", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't render main view, allowing subviews to be debugged" ); +idCVar r_shadows( "r_shadows", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "enable shadows" ); +idCVar r_testARBProgram( "r_testARBProgram", "0", CVAR_RENDERER | CVAR_BOOL, "experiment with vertex/fragment programs" ); +idCVar r_testGamma( "r_testGamma", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels", 0, 195 ); +idCVar r_testGammaBias( "r_testGammaBias", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels" ); +idCVar r_testStepGamma( "r_testStepGamma", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels" ); +idCVar r_lightScale( "r_lightScale", "2", CVAR_RENDERER | CVAR_FLOAT, "all light intensities are multiplied by this" ); +idCVar r_lightSourceRadius( "r_lightSourceRadius", "0", CVAR_RENDERER | CVAR_FLOAT, "for soft-shadow sampling" ); +idCVar r_flareSize( "r_flareSize", "1", CVAR_RENDERER | CVAR_FLOAT, "scale the flare deforms from the material def" ); + +idCVar r_useExternalShadows( "r_useExternalShadows", "1", CVAR_RENDERER | CVAR_INTEGER, "1 = skip drawing caps when outside the light volume, 2 = force to no caps for testing", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_useOptimizedShadows( "r_useOptimizedShadows", "1", CVAR_RENDERER | CVAR_BOOL, "use the dmap generated static shadow volumes" ); +idCVar r_useScissor( "r_useScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor clip as portals and lights are processed" ); +idCVar r_useCombinerDisplayLists( "r_useCombinerDisplayLists", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NOCHEAT, "put all nvidia register combiner programming in display lists" ); +idCVar r_useDepthBoundsTest( "r_useDepthBoundsTest", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test to reduce shadow fill" ); + +idCVar r_screenFraction( "r_screenFraction", "100", CVAR_RENDERER | CVAR_INTEGER, "for testing fill rate, the resolution of the entire screen can be changed" ); +idCVar r_demonstrateBug( "r_demonstrateBug", "0", CVAR_RENDERER | CVAR_BOOL, "used during development to show IHV's their problems" ); +idCVar r_usePortals( "r_usePortals", "1", CVAR_RENDERER | CVAR_BOOL, " 1 = use portals to perform area culling, otherwise draw everything" ); +idCVar r_singleLight( "r_singleLight", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one light" ); +idCVar r_singleEntity( "r_singleEntity", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one entity" ); +idCVar r_singleSurface( "r_singleSurface", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one surface on each entity" ); +idCVar r_singleArea( "r_singleArea", "0", CVAR_RENDERER | CVAR_BOOL, "only draw the portal area the view is actually in" ); +idCVar r_forceLoadImages( "r_forceLoadImages", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "draw all images to screen after registration" ); +idCVar r_orderIndexes( "r_orderIndexes", "1", CVAR_RENDERER | CVAR_BOOL, "perform index reorganization to optimize vertex use" ); +idCVar r_lightAllBackFaces( "r_lightAllBackFaces", "0", CVAR_RENDERER | CVAR_BOOL, "light all the back faces, even when they would be shadowed" ); + +// visual debugging info +idCVar r_showPortals( "r_showPortals", "0", CVAR_RENDERER | CVAR_BOOL, "draw portal outlines in color based on passed / not passed" ); +idCVar r_showUnsmoothedTangents( "r_showUnsmoothedTangents", "0", CVAR_RENDERER | CVAR_BOOL, "if 1, put all nvidia register combiner programming in display lists" ); +idCVar r_showSilhouette( "r_showSilhouette", "0", CVAR_RENDERER | CVAR_BOOL, "highlight edges that are casting shadow planes" ); +idCVar r_showVertexColor( "r_showVertexColor", "0", CVAR_RENDERER | CVAR_BOOL, "draws all triangles with the solid vertex color" ); +idCVar r_showUpdates( "r_showUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "report entity and light updates and ref counts" ); +idCVar r_showDemo( "r_showDemo", "0", CVAR_RENDERER | CVAR_BOOL, "report reads and writes to the demo file" ); +idCVar r_showDynamic( "r_showDynamic", "0", CVAR_RENDERER | CVAR_BOOL, "report stats on dynamic surface generation" ); +idCVar r_showLightScale( "r_showLightScale", "0", CVAR_RENDERER | CVAR_BOOL, "report the scale factor applied to drawing for overbrights" ); +idCVar r_showDefs( "r_showDefs", "0", CVAR_RENDERER | CVAR_BOOL, "report the number of modeDefs and lightDefs in view" ); +idCVar r_showTrace( "r_showTrace", "0", CVAR_RENDERER | CVAR_INTEGER, "show the intersection of an eye trace with the world", idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_showIntensity( "r_showIntensity", "0", CVAR_RENDERER | CVAR_BOOL, "draw the screen colors based on intensity, red = 0, green = 128, blue = 255" ); +idCVar r_showImages( "r_showImages", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show all images instead of rendering, 2 = show in proportional size", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_showSmp( "r_showSmp", "0", CVAR_RENDERER | CVAR_BOOL, "show which end (front or back) is blocking" ); +idCVar r_showLights( "r_showLights", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = just print volumes numbers, highlighting ones covering the view, 2 = also draw planes of each volume, 3 = also draw edges of each volume", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showShadows( "r_showShadows", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = visualize the stencil shadow volumes, 2 = draw filled in", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showShadowCount( "r_showShadowCount", "0", CVAR_RENDERER | CVAR_INTEGER, "colors screen based on shadow volume depth complexity, >= 2 = print overdraw count based on stencil index values, 3 = only show turboshadows, 4 = only show static shadows", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> ); +idCVar r_showLightScissors( "r_showLightScissors", "0", CVAR_RENDERER | CVAR_BOOL, "show light scissor rectangles" ); +idCVar r_showEntityScissors( "r_showEntityScissors", "0", CVAR_RENDERER | CVAR_BOOL, "show entity scissor rectangles" ); +idCVar r_showInteractionFrustums( "r_showInteractionFrustums", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show a frustum for each interaction, 2 = also draw lines to light origin, 3 = also draw entity bbox", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show screen rectangle which contains the interaction frustum, 2 = also draw construction lines", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_showLightCount( "r_showLightCount", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = colors surfaces based on light count, 2 = also count everything through walls, 3 = also print overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showViewEntitys( "r_showViewEntitys", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = displays the bounding boxes of all view models, 2 = print index numbers" ); +idCVar r_showTris( "r_showTris", "0", CVAR_RENDERER | CVAR_INTEGER, "enables wireframe rendering of the world, 1 = only draw visible ones, 2 = draw all front facing, 3 = draw all", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showSurfaceInfo( "r_showSurfaceInfo", "0", CVAR_RENDERER | CVAR_BOOL, "show surface material name under crosshair" ); +idCVar r_showNormals( "r_showNormals", "0", CVAR_RENDERER | CVAR_FLOAT, "draws wireframe normals" ); +idCVar r_showMemory( "r_showMemory", "0", CVAR_RENDERER | CVAR_BOOL, "print frame memory utilization" ); +idCVar r_showCull( "r_showCull", "0", CVAR_RENDERER | CVAR_BOOL, "report sphere and box culling stats" ); +idCVar r_showInteractions( "r_showInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "report interaction generation activity" ); +idCVar r_showDepth( "r_showDepth", "0", CVAR_RENDERER | CVAR_BOOL, "display the contents of the depth buffer and the depth range" ); +idCVar r_showSurfaces( "r_showSurfaces", "0", CVAR_RENDERER | CVAR_BOOL, "report surface/light/shadow counts" ); +idCVar r_showPrimitives( "r_showPrimitives", "0", CVAR_RENDERER | CVAR_INTEGER, "report drawsurf/index/vertex counts" ); +idCVar r_showEdges( "r_showEdges", "0", CVAR_RENDERER | CVAR_BOOL, "draw the sil edges" ); +idCVar r_showTexturePolarity( "r_showTexturePolarity", "0", CVAR_RENDERER | CVAR_BOOL, "shade triangles by texture area polarity" ); +idCVar r_showTangentSpace( "r_showTangentSpace", "0", CVAR_RENDERER | CVAR_INTEGER, "shade triangles by tangent space, 1 = use 1st tangent vector, 2 = use 2nd tangent vector, 3 = use normal vector", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); +idCVar r_showDominantTri( "r_showDominantTri", "0", CVAR_RENDERER | CVAR_BOOL, "draw lines from vertexes to center of dominant triangles" ); +idCVar r_showAlloc( "r_showAlloc", "0", CVAR_RENDERER | CVAR_BOOL, "report alloc/free counts" ); +idCVar r_showTextureVectors( "r_showTextureVectors", "0", CVAR_RENDERER | CVAR_FLOAT, " if > 0 draw each triangles texture (tangent) vectors" ); +idCVar r_showOverDraw( "r_showOverDraw", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> ); + +idCVar r_lockSurfaces( "r_lockSurfaces", "0", CVAR_RENDERER | CVAR_BOOL, "allow moving the view point without changing the composition of the scene, including culling" ); +idCVar r_useEntityCallbacks( "r_useEntityCallbacks", "1", CVAR_RENDERER | CVAR_BOOL, "if 0, issue the callback immediately at update time, rather than defering" ); + +idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "draw the skeleton when model animates, 1 = draw model with skeleton, 2 = draw skeleton only", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar r_jointNameScale( "r_jointNameScale", "0.02", CVAR_RENDERER | CVAR_FLOAT, "size of joint names when r_showskel is set to 1" ); +idCVar r_jointNameOffset( "r_jointNameOffset", "0.5", CVAR_RENDERER | CVAR_FLOAT, "offset of joint names when r_showskel is set to 1" ); + +idCVar r_cgVertexProfile( "r_cgVertexProfile", "best", CVAR_RENDERER | CVAR_ARCHIVE, "arbvp1, vp20, vp30" ); +idCVar r_cgFragmentProfile( "r_cgFragmentProfile", "best", CVAR_RENDERER | CVAR_ARCHIVE, "arbfp1, fp30" ); + +idCVar r_debugLineDepthTest( "r_debugLineDepthTest", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "perform depth test on debug lines" ); +idCVar r_debugLineWidth( "r_debugLineWidth", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "width of debug lines" ); +idCVar r_debugArrowStep( "r_debugArrowStep", "120", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "step size of arrow cone line rotation in degrees", 0, 120 ); +idCVar r_debugPolygonFilled( "r_debugPolygonFilled", "1", CVAR_RENDERER | CVAR_BOOL, "draw a filled polygon" ); + +idCVar r_materialOverride( "r_materialOverride", "", CVAR_RENDERER, "overrides all materials", idCmdSystem::ArgCompletion_Decl ); + +idCVar r_debugRenderToTexture( "r_debugRenderToTexture", "0", CVAR_RENDERER | CVAR_INTEGER, "" ); + +void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t ); +void ( APIENTRY * qglMultiTexCoord2fvARB )( GLenum texture, GLfloat *st ); +void ( APIENTRY * qglActiveTextureARB )( GLenum texture ); +void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture ); + +void ( APIENTRY *qglCombinerParameterfvNV )( GLenum pname, const GLfloat *params ); +void ( APIENTRY *qglCombinerParameterivNV )( GLenum pname, const GLint *params ); +void ( APIENTRY *qglCombinerParameterfNV )( GLenum pname, const GLfloat param ); +void ( APIENTRY *qglCombinerParameteriNV )( GLenum pname, const GLint param ); +void ( APIENTRY *qglCombinerInputNV )( GLenum stage, GLenum portion, GLenum variable, GLenum input, + GLenum mapping, GLenum componentUsage ); +void ( APIENTRY *qglCombinerOutputNV )( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, + GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, + GLboolean cdDotProduct, GLboolean muxSum ); +void ( APIENTRY *qglFinalCombinerInputNV )( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage ); + + +void (APIENTRY *qglVertexArrayRangeNV)( GLsizei length, void *pointer ); +// TTimo: wgl vs glX +// http://oss.sgi.com/projects/ogl-sample/registry/NV/vertex_array_range.txt +// since APIs are the same anyway, let's be wgl/glX agnostic +void *(APIENTRY *qAllocateMemoryNV)( GLsizei size, float readFrequency, float writeFrequency, float priority); +void (APIENTRY *qFreeMemoryNV)( void *pointer ); +#ifdef GLX_VERSION_1_1 +#define Q_ALLOCATE_MEMORY_NV "glXAllocateMemoryNV" +#define Q_FREE_MEMORY_NV "glXFreeMemoryNV" +#else +#define Q_ALLOCATE_MEMORY_NV "wglAllocateMemoryNV" +#define Q_FREE_MEMORY_NV "wglFreeMemoryNV" +#endif + +void (APIENTRY *qglTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); + +void (APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * ); + + +// ATI_fragment_shader +PFNGLGENFRAGMENTSHADERSATIPROC qglGenFragmentShadersATI; +PFNGLBINDFRAGMENTSHADERATIPROC qglBindFragmentShaderATI; +PFNGLDELETEFRAGMENTSHADERATIPROC qglDeleteFragmentShaderATI; +PFNGLBEGINFRAGMENTSHADERATIPROC qglBeginFragmentShaderATI; +PFNGLENDFRAGMENTSHADERATIPROC qglEndFragmentShaderATI; +PFNGLPASSTEXCOORDATIPROC qglPassTexCoordATI; +PFNGLSAMPLEMAPATIPROC qglSampleMapATI; +PFNGLCOLORFRAGMENTOP1ATIPROC qglColorFragmentOp1ATI; +PFNGLCOLORFRAGMENTOP2ATIPROC qglColorFragmentOp2ATI; +PFNGLCOLORFRAGMENTOP3ATIPROC qglColorFragmentOp3ATI; +PFNGLALPHAFRAGMENTOP1ATIPROC qglAlphaFragmentOp1ATI; +PFNGLALPHAFRAGMENTOP2ATIPROC qglAlphaFragmentOp2ATI; +PFNGLALPHAFRAGMENTOP3ATIPROC qglAlphaFragmentOp3ATI; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC qglSetFragmentShaderConstantATI; + +// EXT_stencil_two_side +PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT; + +// ATI_separate_stencil +PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparateATI; +PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparateATI; + +// ARB_texture_compression +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; + +// ARB_vertex_buffer_object +PFNGLBINDBUFFERARBPROC qglBindBufferARB; +PFNGLDELETEBUFFERSARBPROC qglDeleteBuffersARB; +PFNGLGENBUFFERSARBPROC qglGenBuffersARB; +PFNGLISBUFFERARBPROC qglIsBufferARB; +PFNGLBUFFERDATAARBPROC qglBufferDataARB; +PFNGLBUFFERSUBDATAARBPROC qglBufferSubDataARB; +PFNGLGETBUFFERSUBDATAARBPROC qglGetBufferSubDataARB; +PFNGLMAPBUFFERARBPROC qglMapBufferARB; +PFNGLUNMAPBUFFERARBPROC qglUnmapBufferARB; +PFNGLGETBUFFERPARAMETERIVARBPROC qglGetBufferParameterivARB; +PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB; + +// ARB_vertex_program / ARB_fragment_program +PFNGLVERTEXATTRIBPOINTERARBPROC qglVertexAttribPointerARB; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC qglEnableVertexAttribArrayARB; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC qglDisableVertexAttribArrayARB; +PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; +PFNGLBINDPROGRAMARBPROC qglBindProgramARB; +PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; +PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB; + +// GL_EXT_depth_bounds_test +PFNGLDEPTHBOUNDSEXTPROC qglDepthBoundsEXT; + +/* +================= +R_CheckExtension +================= +*/ +bool R_CheckExtension( char *name ) { + if ( !strstr( glConfig.extensions_string, name ) ) { + common->Printf( "X..%s not found\n", name ); + return false; + } + + common->Printf( "...using %s\n", name ); + return true; +} + +/* +================== +R_CheckPortableExtensions + +================== +*/ +static void R_CheckPortableExtensions( void ) { + glConfig.glVersion = atof( glConfig.version_string ); + + // GL_ARB_multitexture + glConfig.multitextureAvailable = R_CheckExtension( "GL_ARB_multitexture" ); + if ( glConfig.multitextureAvailable ) { + qglMultiTexCoord2fARB = (void(APIENTRY *)(GLenum, GLfloat, GLfloat))GLimp_ExtensionPointer( "glMultiTexCoord2fARB" ); + qglMultiTexCoord2fvARB = (void(APIENTRY *)(GLenum, GLfloat *))GLimp_ExtensionPointer( "glMultiTexCoord2fvARB" ); + qglActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glActiveTextureARB" ); + qglClientActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glClientActiveTextureARB" ); + qglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, (GLint *)&glConfig.maxTextureUnits ); + if ( glConfig.maxTextureUnits > MAX_MULTITEXTURE_UNITS ) { + glConfig.maxTextureUnits = MAX_MULTITEXTURE_UNITS; + } + if ( glConfig.maxTextureUnits < 2 ) { + glConfig.multitextureAvailable = false; // shouldn't ever happen + } + qglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, (GLint *)&glConfig.maxTextureCoords ); + qglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (GLint *)&glConfig.maxTextureImageUnits ); + } + + // GL_ARB_texture_env_combine + glConfig.textureEnvCombineAvailable = R_CheckExtension( "GL_ARB_texture_env_combine" ); + + // GL_ARB_texture_cube_map + glConfig.cubeMapAvailable = R_CheckExtension( "GL_ARB_texture_cube_map" ); + + // GL_ARB_texture_env_dot3 + glConfig.envDot3Available = R_CheckExtension( "GL_ARB_texture_env_dot3" ); + + // GL_ARB_texture_env_add + glConfig.textureEnvAddAvailable = R_CheckExtension( "GL_ARB_texture_env_add" ); + + // GL_ARB_texture_non_power_of_two + glConfig.textureNonPowerOfTwoAvailable = R_CheckExtension( "GL_ARB_texture_non_power_of_two" ); + + // GL_ARB_texture_compression + GL_S3_s3tc + // DRI drivers may have GL_ARB_texture_compression but no GL_EXT_texture_compression_s3tc + if ( R_CheckExtension( "GL_ARB_texture_compression" ) && R_CheckExtension( "GL_EXT_texture_compression_s3tc" ) ) { + glConfig.textureCompressionAvailable = true; + qglCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)GLimp_ExtensionPointer( "glCompressedTexImage2DARB" ); + qglGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)GLimp_ExtensionPointer( "glGetCompressedTexImageARB" ); + } else { + glConfig.textureCompressionAvailable = false; + } + + // GL_EXT_texture_filter_anisotropic + glConfig.anisotropicAvailable = R_CheckExtension( "GL_EXT_texture_filter_anisotropic" ); + if ( glConfig.anisotropicAvailable ) { + qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureAnisotropy ); + common->Printf( " maxTextureAnisotropy: %f\n", glConfig.maxTextureAnisotropy ); + } else { + glConfig.maxTextureAnisotropy = 1; + } + + // GL_EXT_texture_lod_bias + // The actual extension is broken as specificed, storing the state in the texture unit instead + // of the texture object. The behavior in GL 1.4 is the behavior we use. + if ( glConfig.glVersion >= 1.4 || R_CheckExtension( "GL_EXT_texture_lod" ) ) { + common->Printf( "...using %s\n", "GL_1.4_texture_lod_bias" ); + glConfig.textureLODBiasAvailable = true; + } else { + common->Printf( "X..%s not found\n", "GL_1.4_texture_lod_bias" ); + glConfig.textureLODBiasAvailable = false; + } + + // GL_EXT_shared_texture_palette + glConfig.sharedTexturePaletteAvailable = R_CheckExtension( "GL_EXT_shared_texture_palette" ); + if ( glConfig.sharedTexturePaletteAvailable ) { + qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) GLimp_ExtensionPointer( "glColorTableEXT" ); + } + + // GL_EXT_texture3D (not currently used for anything) + glConfig.texture3DAvailable = R_CheckExtension( "GL_EXT_texture3D" ); + if ( glConfig.texture3DAvailable ) { + qglTexImage3D = + (void (APIENTRY *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) ) + GLimp_ExtensionPointer( "glTexImage3D" ); + } + + // EXT_stencil_wrap + // This isn't very important, but some pathological case might cause a clamp error and give a shadow bug. + // Nvidia also believes that future hardware may be able to run faster with this enabled to avoid the + // serialization of clamping. + if ( R_CheckExtension( "GL_EXT_stencil_wrap" ) ) { + tr.stencilIncr = GL_INCR_WRAP_EXT; + tr.stencilDecr = GL_DECR_WRAP_EXT; + } else { + tr.stencilIncr = GL_INCR; + tr.stencilDecr = GL_DECR; + } + + // GL_NV_register_combiners + glConfig.registerCombinersAvailable = R_CheckExtension( "GL_NV_register_combiners" ); + if ( glConfig.registerCombinersAvailable ) { + qglCombinerParameterfvNV = (void (APIENTRY *)( GLenum pname, const GLfloat *params )) + GLimp_ExtensionPointer( "glCombinerParameterfvNV" ); + qglCombinerParameterivNV = (void (APIENTRY *)( GLenum pname, const GLint *params )) + GLimp_ExtensionPointer( "glCombinerParameterivNV" ); + qglCombinerParameterfNV = (void (APIENTRY *)( GLenum pname, const GLfloat param )) + GLimp_ExtensionPointer( "glCombinerParameterfNV" ); + qglCombinerParameteriNV = (void (APIENTRY *)( GLenum pname, const GLint param )) + GLimp_ExtensionPointer( "glCombinerParameteriNV" ); + qglCombinerInputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum variable, GLenum input, + GLenum mapping, GLenum componentUsage )) + GLimp_ExtensionPointer( "glCombinerInputNV" ); + qglCombinerOutputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, + GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, + GLboolean cdDotProduct, GLboolean muxSum )) + GLimp_ExtensionPointer( "glCombinerOutputNV" ); + qglFinalCombinerInputNV = (void (APIENTRY *)( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage )) + GLimp_ExtensionPointer( "glFinalCombinerInputNV" ); + } + + // GL_EXT_stencil_two_side + glConfig.twoSidedStencilAvailable = R_CheckExtension( "GL_EXT_stencil_two_side" ); + if ( glConfig.twoSidedStencilAvailable ) { + qglActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)GLimp_ExtensionPointer( "glActiveStencilFaceEXT" ); + } else { + glConfig.atiTwoSidedStencilAvailable = R_CheckExtension( "GL_ATI_separate_stencil" ); + if ( glConfig.atiTwoSidedStencilAvailable ) { + qglStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilFuncSeparateATI" ); + qglStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilOpSeparateATI" ); + } + } + + // GL_ATI_fragment_shader + glConfig.atiFragmentShaderAvailable = R_CheckExtension( "GL_ATI_fragment_shader" ); + if (! glConfig.atiFragmentShaderAvailable ) { + // only on OSX: ATI_fragment_shader is faked through ATI_text_fragment_shader (macosx_glimp.cpp) + glConfig.atiFragmentShaderAvailable = R_CheckExtension( "GL_ATI_text_fragment_shader" ); + } + if ( glConfig.atiFragmentShaderAvailable ) { + qglGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)GLimp_ExtensionPointer( "glGenFragmentShadersATI" ); + qglBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glBindFragmentShaderATI" ); + qglDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glDeleteFragmentShaderATI" ); + qglBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glBeginFragmentShaderATI" ); + qglEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glEndFragmentShaderATI" ); + qglPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)GLimp_ExtensionPointer( "glPassTexCoordATI" ); + qglSampleMapATI = (PFNGLSAMPLEMAPATIPROC)GLimp_ExtensionPointer( "glSampleMapATI" ); + qglColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp1ATI" ); + qglColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp2ATI" ); + qglColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp3ATI" ); + qglAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp1ATI" ); + qglAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp2ATI" ); + qglAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp3ATI" ); + qglSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)GLimp_ExtensionPointer( "glSetFragmentShaderConstantATI" ); + } + + // ARB_vertex_buffer_object + glConfig.ARBVertexBufferObjectAvailable = R_CheckExtension( "GL_ARB_vertex_buffer_object" ); + if(glConfig.ARBVertexBufferObjectAvailable) { + qglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLimp_ExtensionPointer( "glBindBufferARB"); + qglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLimp_ExtensionPointer( "glDeleteBuffersARB"); + qglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLimp_ExtensionPointer( "glGenBuffersARB"); + qglIsBufferARB = (PFNGLISBUFFERARBPROC)GLimp_ExtensionPointer( "glIsBufferARB"); + qglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLimp_ExtensionPointer( "glBufferDataARB"); + qglBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glBufferSubDataARB"); + qglGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glGetBufferSubDataARB"); + qglMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glMapBufferARB"); + qglUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glUnmapBufferARB"); + qglGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLimp_ExtensionPointer( "glGetBufferParameterivARB"); + qglGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLimp_ExtensionPointer( "glGetBufferPointervARB"); + } + + // ARB_vertex_program + glConfig.ARBVertexProgramAvailable = R_CheckExtension( "GL_ARB_vertex_program" ); + if (glConfig.ARBVertexProgramAvailable) { + qglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GLimp_ExtensionPointer( "glVertexAttribPointerARB" ); + qglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glEnableVertexAttribArrayARB" ); + qglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glDisableVertexAttribArrayARB" ); + qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)GLimp_ExtensionPointer( "glProgramStringARB" ); + qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)GLimp_ExtensionPointer( "glBindProgramARB" ); + qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)GLimp_ExtensionPointer( "glGenProgramsARB" ); + qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramEnvParameter4fvARB" ); + qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramLocalParameter4fvARB" ); + } + + // ARB_fragment_program + if ( r_inhibitFragmentProgram.GetBool() ) { + glConfig.ARBFragmentProgramAvailable = false; + } else { + glConfig.ARBFragmentProgramAvailable = R_CheckExtension( "GL_ARB_fragment_program" ); + if (glConfig.ARBFragmentProgramAvailable) { + // these are the same as ARB_vertex_program + qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)GLimp_ExtensionPointer( "glProgramStringARB" ); + qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)GLimp_ExtensionPointer( "glBindProgramARB" ); + qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramEnvParameter4fvARB" ); + qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramLocalParameter4fvARB" ); + } + } + + // check for minimum set + if ( !glConfig.multitextureAvailable || !glConfig.textureEnvCombineAvailable || !glConfig.cubeMapAvailable + || !glConfig.envDot3Available ) { + common->Error( common->GetLanguageDict()->GetString( "#str_06780" ) ); + } + + // GL_EXT_depth_bounds_test + glConfig.depthBoundsTestAvailable = R_CheckExtension( "EXT_depth_bounds_test" ); + if ( glConfig.depthBoundsTestAvailable ) { + qglDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)GLimp_ExtensionPointer( "glDepthBoundsEXT" ); + } + +} + + +/* +==================== +R_GetModeInfo + +r_mode is normally a small non-negative integer that +looks resolutions up in a table, but if it is set to -1, +the values from r_customWidth, amd r_customHeight +will be used instead. +==================== +*/ +typedef struct vidmode_s { + const char *description; + int width, height; +} vidmode_t; + +vidmode_t r_vidModes[] = { + { "Mode 0: 320x240", 320, 240 }, + { "Mode 1: 400x300", 400, 300 }, + { "Mode 2: 512x384", 512, 384 }, + { "Mode 3: 640x480", 640, 480 }, + { "Mode 4: 800x600", 800, 600 }, + { "Mode 5: 1024x768", 1024, 768 }, + { "Mode 6: 1152x864", 1152, 864 }, + { "Mode 7: 1280x1024", 1280, 1024 }, + { "Mode 8: 1600x1200", 1600, 1200 }, +}; +static int s_numVidModes = ( sizeof( r_vidModes ) / sizeof( r_vidModes[0] ) ); + +#if MACOS_X +bool R_GetModeInfo( int *width, int *height, int mode ) { +#else +static bool R_GetModeInfo( int *width, int *height, int mode ) { +#endif + vidmode_t *vm; + + if ( mode < -1 ) { + return false; + } + if ( mode >= s_numVidModes ) { + return false; + } + + if ( mode == -1 ) { + *width = r_customWidth.GetInteger(); + *height = r_customHeight.GetInteger(); + return true; + } + + vm = &r_vidModes[mode]; + + if ( width ) { + *width = vm->width; + } + if ( height ) { + *height = vm->height; + } + + return true; +} + + +/* +================== +R_InitOpenGL + +This function is responsible for initializing a valid OpenGL subsystem +for rendering. This is done by calling the system specific GLimp_Init, +which gives us a working OGL subsystem, then setting all necessary openGL +state, including images, vertex programs, and display lists. + +Changes to the vertex cache size or smp state require a vid_restart. + +If glConfig.isInitialized is false, no rendering can take place, but +all renderSystem functions will still operate properly, notably the material +and model information functions. +================== +*/ +void R_InitOpenGL( void ) { + GLint temp; + glimpParms_t parms; + int i; + + common->Printf( "----- R_InitOpenGL -----\n" ); + + if ( glConfig.isInitialized ) { + common->FatalError( "R_InitOpenGL called while active" ); + } + + // in case we had an error while doing a tiled rendering + tr.viewportOffset[0] = 0; + tr.viewportOffset[1] = 0; + + // + // initialize OS specific portions of the renderSystem + // + for ( i = 0 ; i < 2 ; i++ ) { + // set the parameters we are trying + R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, r_mode.GetInteger() ); + + parms.width = glConfig.vidWidth; + parms.height = glConfig.vidHeight; + parms.fullScreen = r_fullscreen.GetBool(); + parms.displayHz = r_displayRefresh.GetInteger(); + parms.multiSamples = r_multiSamples.GetInteger(); + parms.stereo = false; + + if ( GLimp_Init( parms ) ) { + // it worked + break; + } + + if ( i == 1 ) { + common->FatalError( "Unable to initialize OpenGL" ); + } + + // if we failed, set everything back to "safe mode" + // and try again + r_mode.SetInteger( 3 ); + r_fullscreen.SetInteger( 1 ); + r_displayRefresh.SetInteger( 0 ); + r_multiSamples.SetInteger( 0 ); + } + + // input and sound systems need to be tied to the new window + Sys_InitInput(); + soundSystem->InitHW(); + + // get our config strings + glConfig.vendor_string = (const char *)qglGetString(GL_VENDOR); + glConfig.renderer_string = (const char *)qglGetString(GL_RENDERER); + glConfig.version_string = (const char *)qglGetString(GL_VERSION); + glConfig.extensions_string = (const char *)qglGetString(GL_EXTENSIONS); + + // OpenGL driver constants + qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp ); + glConfig.maxTextureSize = temp; + + // stubbed or broken drivers may have reported 0... + if ( glConfig.maxTextureSize <= 0 ) { + glConfig.maxTextureSize = 256; + } + + glConfig.isInitialized = true; + + // recheck all the extensions (FIXME: this might be dangerous) + R_CheckPortableExtensions(); + + // parse our vertex and fragment programs, possibly disably support for + // one of the paths if there was an error + R_NV10_Init(); + R_NV20_Init(); + R_R200_Init(); + R_ARB2_Init(); + + cmdSystem->AddCommand( "reloadARBprograms", R_ReloadARBPrograms_f, CMD_FL_RENDERER, "reloads ARB programs" ); + R_ReloadARBPrograms_f( idCmdArgs() ); + + // allocate the vertex array range or vertex objects + vertexCache.Init(); + + // select which renderSystem we are going to use + r_renderer.SetModified(); + tr.SetBackEndRenderer(); + + // allocate the frame data, which may be more if smp is enabled + R_InitFrameData(); + + // Reset our gamma + R_SetColorMappings(); + +#ifdef _WIN32 + static bool glCheck = false; + if ( !glCheck && win32.osversion.dwMajorVersion == 6 ) { + glCheck = true; + if ( !idStr::Icmp( glConfig.vendor_string, "Microsoft" ) && idStr::FindText( glConfig.renderer_string, "OpenGL-D3D" ) != -1 ) { + if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" ); + Sys_GrabMouseCursor( false ); + } + int ret = MessageBox( NULL, "Please install OpenGL drivers from your graphics hardware vendor to run " GAME_NAME ".\nYour OpenGL functionality is limited.", + "Insufficient OpenGL capabilities", MB_OKCANCEL | MB_ICONWARNING | MB_TASKMODAL ); + if ( ret == IDCANCEL ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + cmdSystem->ExecuteCommandBuffer(); + } + if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" ); + } + } + } +#endif +} + +/* +================== +GL_CheckErrors +================== +*/ +void GL_CheckErrors( void ) { + int err; + char s[64]; + int i; + + // check for up to 10 errors pending + for ( i = 0 ; i < 10 ; i++ ) { + err = qglGetError(); + if ( err == GL_NO_ERROR ) { + return; + } + switch( err ) { + case GL_INVALID_ENUM: + strcpy( s, "GL_INVALID_ENUM" ); + break; + case GL_INVALID_VALUE: + strcpy( s, "GL_INVALID_VALUE" ); + break; + case GL_INVALID_OPERATION: + strcpy( s, "GL_INVALID_OPERATION" ); + break; + case GL_STACK_OVERFLOW: + strcpy( s, "GL_STACK_OVERFLOW" ); + break; + case GL_STACK_UNDERFLOW: + strcpy( s, "GL_STACK_UNDERFLOW" ); + break; + case GL_OUT_OF_MEMORY: + strcpy( s, "GL_OUT_OF_MEMORY" ); + break; + default: + idStr::snPrintf( s, sizeof(s), "%i", err); + break; + } + + if ( !r_ignoreGLErrors.GetBool() ) { + common->Printf( "GL_CheckErrors: %s\n", s ); + } + } +} + +/* +===================== +R_ReloadSurface_f + +Reload the material displayed by r_showSurfaceInfo +===================== +*/ +static void R_ReloadSurface_f( const idCmdArgs &args ) { + modelTrace_t mt; + idVec3 start, end; + + // start far enough away that we don't hit the player model + start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16; + end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f; + if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) { + return; + } + + common->Printf( "Reloading %s\n", mt.material->GetName() ); + + // reload the decl + mt.material->base->Reload(); + + // reload any images used by the decl + mt.material->ReloadImages( false ); +} + + + +/* +============== +R_ListModes_f +============== +*/ +static void R_ListModes_f( const idCmdArgs &args ) { + int i; + + common->Printf( "\n" ); + for ( i = 0; i < s_numVidModes; i++ ) { + common->Printf( "%s\n", r_vidModes[i].description ); + } + common->Printf( "\n" ); +} + + + +/* +============= +R_TestImage_f + +Display the given image centered on the screen. +testimage +testimage +============= +*/ +void R_TestImage_f( const idCmdArgs &args ) { + int imageNum; + + if ( tr.testVideo ) { + delete tr.testVideo; + tr.testVideo = NULL; + } + tr.testImage = NULL; + + if ( args.Argc() != 2 ) { + return; + } + + if ( idStr::IsNumeric( args.Argv(1) ) ) { + imageNum = atoi( args.Argv(1) ); + if ( imageNum >= 0 && imageNum < globalImages->images.Num() ) { + tr.testImage = globalImages->images[imageNum]; + } + } else { + tr.testImage = globalImages->ImageFromFile( args.Argv( 1 ), TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT ); + } +} + +/* +============= +R_TestVideo_f + +Plays the cinematic file in a testImage +============= +*/ +void R_TestVideo_f( const idCmdArgs &args ) { + if ( tr.testVideo ) { + delete tr.testVideo; + tr.testVideo = NULL; + } + tr.testImage = NULL; + + if ( args.Argc() < 2 ) { + return; + } + + tr.testImage = globalImages->ImageFromFile( "_scratch", TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT ); + tr.testVideo = idCinematic::Alloc(); + tr.testVideo->InitFromFile( args.Argv( 1 ), true ); + + cinData_t cin; + cin = tr.testVideo->ImageForTime( 0 ); + if ( !cin.image ) { + delete tr.testVideo; + tr.testVideo = NULL; + tr.testImage = NULL; + return; + } + + common->Printf( "%i x %i images\n", cin.imageWidth, cin.imageHeight ); + + int len = tr.testVideo->AnimationLength(); + common->Printf( "%5.1f seconds of video\n", len * 0.001 ); + + tr.testVideoStartTime = tr.primaryRenderView.time * 0.001; + + // try to play the matching wav file + idStr wavString = args.Argv( ( args.Argc() == 2 ) ? 1 : 2 ); + wavString.StripFileExtension(); + wavString = wavString + ".wav"; + session->sw->PlayShaderDirectly( wavString.c_str() ); +} + +static int R_QsortSurfaceAreas( const void *a, const void *b ) { + const idMaterial *ea, *eb; + int ac, bc; + + ea = *(idMaterial **)a; + if ( !ea->EverReferenced() ) { + ac = 0; + } else { + ac = ea->GetSurfaceArea(); + } + eb = *(idMaterial **)b; + if ( !eb->EverReferenced() ) { + bc = 0; + } else { + bc = eb->GetSurfaceArea(); + } + + if ( ac < bc ) { + return -1; + } + if ( ac > bc ) { + return 1; + } + + return idStr::Icmp( ea->GetName(), eb->GetName() ); +} + + +/* +=================== +R_ReportSurfaceAreas_f + +Prints a list of the materials sorted by surface area +=================== +*/ +void R_ReportSurfaceAreas_f( const idCmdArgs &args ) { + int i, count; + idMaterial **list; + + count = declManager->GetNumDecls( DECL_MATERIAL ); + list = (idMaterial **)_alloca( count * sizeof( *list ) ); + + for ( i = 0 ; i < count ; i++ ) { + list[i] = (idMaterial *)declManager->DeclByIndex( DECL_MATERIAL, i, false ); + } + + qsort( list, count, sizeof( list[0] ), R_QsortSurfaceAreas ); + + // skip over ones with 0 area + for ( i = 0 ; i < count ; i++ ) { + if ( list[i]->GetSurfaceArea() > 0 ) { + break; + } + } + + for ( ; i < count ; i++ ) { + // report size in "editor blocks" + int blocks = list[i]->GetSurfaceArea() / 4096.0; + common->Printf( "%7i %s\n", blocks, list[i]->GetName() ); + } +} + +/* +=================== +R_ReportImageDuplication_f + +Checks for images with the same hash value and does a better comparison +=================== +*/ +void R_ReportImageDuplication_f( const idCmdArgs &args ) { + int i, j; + + common->Printf( "Images with duplicated contents:\n" ); + + int count = 0; + + for ( i = 0 ; i < globalImages->images.Num() ; i++ ) { + idImage *image1 = globalImages->images[i]; + + if ( image1->isPartialImage ) { + // ignore background loading stubs + continue; + } + if ( image1->generatorFunction ) { + // ignore procedural images + continue; + } + if ( image1->cubeFiles != CF_2D ) { + // ignore cube maps + continue; + } + if ( image1->defaulted ) { + continue; + } + byte *data1; + int w1, h1; + + R_LoadImageProgram( image1->imgName, &data1, &w1, &h1, NULL ); + + for ( j = 0 ; j < i ; j++ ) { + idImage *image2 = globalImages->images[j]; + + if ( image2->isPartialImage ) { + continue; + } + if ( image2->generatorFunction ) { + continue; + } + if ( image2->cubeFiles != CF_2D ) { + continue; + } + if ( image2->defaulted ) { + continue; + } + if ( image1->imageHash != image2->imageHash ) { + continue; + } + if ( image2->uploadWidth != image1->uploadWidth + || image2->uploadHeight != image1->uploadHeight ) { + continue; + } + if ( !idStr::Icmp( image1->imgName, image2->imgName ) ) { + // ignore same image-with-different-parms + continue; + } + + byte *data2; + int w2, h2; + + R_LoadImageProgram( image2->imgName, &data2, &w2, &h2, NULL ); + + if ( w2 != w1 || h2 != h1 ) { + R_StaticFree( data2 ); + continue; + } + + if ( memcmp( data1, data2, w1*h1*4 ) ) { + R_StaticFree( data2 ); + continue; + } + + R_StaticFree( data2 ); + + common->Printf( "%s == %s\n", image1->imgName.c_str(), image2->imgName.c_str() ); + session->UpdateScreen( true ); + count++; + break; + } + + R_StaticFree( data1 ); + } + common->Printf( "%i / %i collisions\n", count, globalImages->images.Num() ); +} + +/* +============================================================================== + + THROUGHPUT BENCHMARKING + +============================================================================== +*/ + +/* +================ +R_RenderingFPS +================ +*/ +static float R_RenderingFPS( const renderView_t *renderView ) { + qglFinish(); + + int start = Sys_Milliseconds(); + static const int SAMPLE_MSEC = 1000; + int end; + int count = 0; + + while( 1 ) { + // render + renderSystem->BeginFrame( glConfig.vidWidth, glConfig.vidHeight ); + tr.primaryWorld->RenderScene( renderView ); + renderSystem->EndFrame( NULL, NULL ); + qglFinish(); + count++; + end = Sys_Milliseconds(); + if ( end - start > SAMPLE_MSEC ) { + break; + } + } + + float fps = count * 1000.0 / ( end - start ); + + return fps; +} + +/* +================ +R_Benchmark_f +================ +*/ +void R_Benchmark_f( const idCmdArgs &args ) { + float fps, msec; + renderView_t view; + + if ( !tr.primaryView ) { + common->Printf( "No primaryView for benchmarking\n" ); + return; + } + view = tr.primaryRenderView; + + for ( int size = 100 ; size >= 10 ; size -= 10 ) { + r_screenFraction.SetInteger( size ); + fps = R_RenderingFPS( &view ); + int kpix = glConfig.vidWidth * glConfig.vidHeight * ( size * 0.01 ) * ( size * 0.01 ) * 0.001; + msec = 1000.0 / fps; + common->Printf( "kpix: %4i msec:%5.1f fps:%5.1f\n", kpix, msec, fps ); + } + + // enable r_singleTriangle 1 while r_screenFraction is still at 10 + r_singleTriangle.SetBool( 1 ); + fps = R_RenderingFPS( &view ); + msec = 1000.0 / fps; + common->Printf( "single tri msec:%5.1f fps:%5.1f\n", msec, fps ); + r_singleTriangle.SetBool( 0 ); + r_screenFraction.SetInteger( 100 ); + + // enable r_skipRenderContext 1 + r_skipRenderContext.SetBool( true ); + fps = R_RenderingFPS( &view ); + msec = 1000.0 / fps; + common->Printf( "no context msec:%5.1f fps:%5.1f\n", msec, fps ); + r_skipRenderContext.SetBool( false ); +} + + +/* +============================================================================== + + SCREEN SHOTS + +============================================================================== +*/ + +/* +==================== +R_ReadTiledPixels + +Allows the rendering of an image larger than the actual window by +tiling it into window-sized chunks and rendering each chunk separately + +If ref isn't specified, the full session UpdateScreen will be done. +==================== +*/ +void R_ReadTiledPixels( int width, int height, byte *buffer, renderView_t *ref = NULL ) { + // include extra space for OpenGL padding to word boundaries + byte *temp = (byte *)R_StaticAlloc( (glConfig.vidWidth+3) * glConfig.vidHeight * 3 ); + + int oldWidth = glConfig.vidWidth; + int oldHeight = glConfig.vidHeight; + + tr.tiledViewport[0] = width; + tr.tiledViewport[1] = height; + + // disable scissor, so we don't need to adjust all those rects + r_useScissor.SetBool( false ); + + for ( int xo = 0 ; xo < width ; xo += oldWidth ) { + for ( int yo = 0 ; yo < height ; yo += oldHeight ) { + tr.viewportOffset[0] = -xo; + tr.viewportOffset[1] = -yo; + + if ( ref ) { + tr.BeginFrame( oldWidth, oldHeight ); + tr.primaryWorld->RenderScene( ref ); + tr.EndFrame( NULL, NULL ); + } else { + session->UpdateScreen(); + } + + int w = oldWidth; + if ( xo + w > width ) { + w = width - xo; + } + int h = oldHeight; + if ( yo + h > height ) { + h = height - yo; + } + + qglReadBuffer( GL_FRONT ); + qglReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, temp ); + + int row = ( w * 3 + 3 ) & ~3; // OpenGL pads to dword boundaries + + for ( int y = 0 ; y < h ; y++ ) { + memcpy( buffer + ( ( yo + y )* width + xo ) * 3, + temp + y * row, w * 3 ); + } + } + } + + r_useScissor.SetBool( true ); + + tr.viewportOffset[0] = 0; + tr.viewportOffset[1] = 0; + tr.tiledViewport[0] = 0; + tr.tiledViewport[1] = 0; + + R_StaticFree( temp ); + + glConfig.vidWidth = oldWidth; + glConfig.vidHeight = oldHeight; +} + + +/* +================== +TakeScreenshot + +Move to tr_imagefiles.c... + +Will automatically tile render large screen shots if necessary +Downsample is the number of steps to mipmap the image before saving it +If ref == NULL, session->updateScreen will be used +================== +*/ +void idRenderSystemLocal::TakeScreenshot( int width, int height, const char *fileName, int blends, renderView_t *ref ) { + byte *buffer; + int i, j, c, temp; + + takingScreenshot = true; + + int pix = width * height; + + buffer = (byte *)R_StaticAlloc(pix*3 + 18); + memset (buffer, 0, 18); + + if ( blends <= 1 ) { + R_ReadTiledPixels( width, height, buffer + 18, ref ); + } else { + unsigned short *shortBuffer = (unsigned short *)R_StaticAlloc(pix*2*3); + memset (shortBuffer, 0, pix*2*3); + + // enable anti-aliasing jitter + r_jitter.SetBool( true ); + + for ( i = 0 ; i < blends ; i++ ) { + R_ReadTiledPixels( width, height, buffer + 18, ref ); + + for ( j = 0 ; j < pix*3 ; j++ ) { + shortBuffer[j] += buffer[18+j]; + } + } + + // divide back to bytes + for ( i = 0 ; i < pix*3 ; i++ ) { + buffer[18+i] = shortBuffer[i] / blends; + } + + R_StaticFree( shortBuffer ); + r_jitter.SetBool( false ); + } + + // fill in the header (this is vertically flipped, which qglReadPixels emits) + buffer[2] = 2; // uncompressed type + buffer[12] = width & 255; + buffer[13] = width >> 8; + buffer[14] = height & 255; + buffer[15] = height >> 8; + buffer[16] = 24; // pixel size + + // swap rgb to bgr + c = 18 + width * height * 3; + for (i=18 ; iWriteFile( fileName, buffer, c, "fs_cdpath" ); + } else { + fileSystem->WriteFile( fileName, buffer, c ); + } + + R_StaticFree( buffer ); + + takingScreenshot = false; + +} + + +/* +================== +R_ScreenshotFilename + +Returns a filename with digits appended +if we have saved a previous screenshot, don't scan +from the beginning, because recording demo avis can involve +thousands of shots +================== +*/ +void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ) { + int a,b,c,d, e; + + bool restrict = cvarSystem->GetCVarBool( "fs_restrict" ); + cvarSystem->SetCVarBool( "fs_restrict", false ); + + lastNumber++; + if ( lastNumber > 99999 ) { + lastNumber = 99999; + } + for ( ; lastNumber < 99999 ; lastNumber++ ) { + int frac = lastNumber; + + a = frac / 10000; + frac -= a*10000; + b = frac / 1000; + frac -= b*1000; + c = frac / 100; + frac -= c*100; + d = frac / 10; + frac -= d*10; + e = frac; + + sprintf( fileName, "%s%i%i%i%i%i.tga", base, a, b, c, d, e ); + if ( lastNumber == 99999 ) { + break; + } + int len = fileSystem->ReadFile( fileName, NULL, NULL ); + if ( len <= 0 ) { + break; + } + // check again... + } + cvarSystem->SetCVarBool( "fs_restrict", restrict ); +} + +/* +================== +R_BlendedScreenShot + +screenshot +screenshot [filename] +screenshot [width] [height] +screenshot [width] [height] [samples] +================== +*/ +#define MAX_BLENDS 256 // to keep the accumulation in shorts +void R_ScreenShot_f( const idCmdArgs &args ) { + static int lastNumber = 0; + idStr checkname; + + int width = glConfig.vidWidth; + int height = glConfig.vidHeight; + int x = 0; + int y = 0; + int blends = 0; + + switch ( args.Argc() ) { + case 1: + width = glConfig.vidWidth; + height = glConfig.vidHeight; + blends = 1; + R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname ); + break; + case 2: + width = glConfig.vidWidth; + height = glConfig.vidHeight; + blends = 1; + checkname = args.Argv( 1 ); + break; + case 3: + width = atoi( args.Argv( 1 ) ); + height = atoi( args.Argv( 2 ) ); + blends = 1; + R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname ); + break; + case 4: + width = atoi( args.Argv( 1 ) ); + height = atoi( args.Argv( 2 ) ); + blends = atoi( args.Argv( 3 ) ); + if ( blends < 1 ) { + blends = 1; + } + if ( blends > MAX_BLENDS ) { + blends = MAX_BLENDS; + } + R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname ); + break; + default: + common->Printf( "usage: screenshot\n screenshot \n screenshot \n screenshot \n" ); + return; + } + + // put the console away + console->Close(); + + tr.TakeScreenshot( width, height, checkname, blends, NULL ); + + common->Printf( "Wrote %s\n", checkname.c_str() ); +} + +/* +=============== +R_StencilShot +Save out a screenshot showing the stencil buffer expanded by 16x range +=============== +*/ +void R_StencilShot( void ) { + byte *buffer; + int i, c; + + int width = tr.GetScreenWidth(); + int height = tr.GetScreenHeight(); + + int pix = width * height; + + c = pix * 3 + 18; + buffer = (byte *)Mem_Alloc(c); + memset (buffer, 0, 18); + + byte *byteBuffer = (byte *)Mem_Alloc(pix); + + qglReadPixels( 0, 0, width, height, GL_STENCIL_INDEX , GL_UNSIGNED_BYTE, byteBuffer ); + + for ( i = 0 ; i < pix ; i++ ) { + buffer[18+i*3] = + buffer[18+i*3+1] = + // buffer[18+i*3+2] = ( byteBuffer[i] & 15 ) * 16; + buffer[18+i*3+2] = byteBuffer[i]; + } + + // fill in the header (this is vertically flipped, which qglReadPixels emits) + buffer[2] = 2; // uncompressed type + buffer[12] = width & 255; + buffer[13] = width >> 8; + buffer[14] = height & 255; + buffer[15] = height >> 8; + buffer[16] = 24; // pixel size + + fileSystem->WriteFile( "screenshots/stencilShot.tga", buffer, c, "fs_savepath" ); + + Mem_Free( buffer ); + Mem_Free( byteBuffer ); +} + +/* +================== +R_EnvShot_f + +envshot + +Saves out env/_ft.tga, etc +================== +*/ +void R_EnvShot_f( const idCmdArgs &args ) { + idStr fullname; + const char *baseName; + int i; + idMat3 axis[6]; + renderView_t ref; + viewDef_t primary; + int blends; + char *extensions[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga", + "_pz.tga", "_nz.tga" }; + int size; + + if ( args.Argc() != 2 && args.Argc() != 3 && args.Argc() != 4 ) { + common->Printf( "USAGE: envshot [size] [blends]\n" ); + return; + } + baseName = args.Argv( 1 ); + + blends = 1; + if ( args.Argc() == 4 ) { + size = atoi( args.Argv( 2 ) ); + blends = atoi( args.Argv( 3 ) ); + } else if ( args.Argc() == 3 ) { + size = atoi( args.Argv( 2 ) ); + blends = 1; + } else { + size = 256; + blends = 1; + } + + if ( !tr.primaryView ) { + common->Printf( "No primary view.\n" ); + return; + } + + primary = *tr.primaryView; + + memset( &axis, 0, sizeof( axis ) ); + axis[0][0][0] = 1; + axis[0][1][2] = 1; + axis[0][2][1] = 1; + + axis[1][0][0] = -1; + axis[1][1][2] = -1; + axis[1][2][1] = 1; + + axis[2][0][1] = 1; + axis[2][1][0] = -1; + axis[2][2][2] = -1; + + axis[3][0][1] = -1; + axis[3][1][0] = -1; + axis[3][2][2] = 1; + + axis[4][0][2] = 1; + axis[4][1][0] = -1; + axis[4][2][1] = 1; + + axis[5][0][2] = -1; + axis[5][1][0] = 1; + axis[5][2][1] = 1; + + for ( i = 0 ; i < 6 ; i++ ) { + ref = primary.renderView; + ref.x = ref.y = 0; + ref.fov_x = ref.fov_y = 90; + ref.width = glConfig.vidWidth; + ref.height = glConfig.vidHeight; + ref.viewaxis = axis[i]; + sprintf( fullname, "env/%s%s", baseName, extensions[i] ); + tr.TakeScreenshot( size, size, fullname, blends, &ref ); + } + + common->Printf( "Wrote %s, etc\n", fullname.c_str() ); +} + +//============================================================================ + +static idMat3 cubeAxis[6]; + + +/* +================== +R_SampleCubeMap +================== +*/ +void R_SampleCubeMap( const idVec3 &dir, int size, byte *buffers[6], byte result[4] ) { + float adir[3]; + int axis, x, y; + + adir[0] = fabs(dir[0]); + adir[1] = fabs(dir[1]); + adir[2] = fabs(dir[2]); + + if ( dir[0] >= adir[1] && dir[0] >= adir[2] ) { + axis = 0; + } else if ( -dir[0] >= adir[1] && -dir[0] >= adir[2] ) { + axis = 1; + } else if ( dir[1] >= adir[0] && dir[1] >= adir[2] ) { + axis = 2; + } else if ( -dir[1] >= adir[0] && -dir[1] >= adir[2] ) { + axis = 3; + } else if ( dir[2] >= adir[1] && dir[2] >= adir[2] ) { + axis = 4; + } else { + axis = 5; + } + + float fx = (dir * cubeAxis[axis][1]) / (dir * cubeAxis[axis][0]); + float fy = (dir * cubeAxis[axis][2]) / (dir * cubeAxis[axis][0]); + + fx = -fx; + fy = -fy; + x = size * 0.5 * (fx + 1); + y = size * 0.5 * (fy + 1); + if ( x < 0 ) { + x = 0; + } else if ( x >= size ) { + x = size-1; + } + if ( y < 0 ) { + y = 0; + } else if ( y >= size ) { + y = size-1; + } + + result[0] = buffers[axis][(y*size+x)*4+0]; + result[1] = buffers[axis][(y*size+x)*4+1]; + result[2] = buffers[axis][(y*size+x)*4+2]; + result[3] = buffers[axis][(y*size+x)*4+3]; +} + +/* +================== +R_MakeAmbientMap_f + +R_MakeAmbientMap_f [size] + +Saves out env/_amb_ft.tga, etc +================== +*/ +void R_MakeAmbientMap_f( const idCmdArgs &args ) { + idStr fullname; + const char *baseName; + int i; + renderView_t ref; + viewDef_t primary; + int downSample; + char *extensions[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga", + "_pz.tga", "_nz.tga" }; + int outSize; + byte *buffers[6]; + int width, height; + + if ( args.Argc() != 2 && args.Argc() != 3 ) { + common->Printf( "USAGE: ambientshot [size]\n" ); + return; + } + baseName = args.Argv( 1 ); + + downSample = 0; + if ( args.Argc() == 3 ) { + outSize = atoi( args.Argv( 2 ) ); + } else { + outSize = 32; + } + + memset( &cubeAxis, 0, sizeof( cubeAxis ) ); + cubeAxis[0][0][0] = 1; + cubeAxis[0][1][2] = 1; + cubeAxis[0][2][1] = 1; + + cubeAxis[1][0][0] = -1; + cubeAxis[1][1][2] = -1; + cubeAxis[1][2][1] = 1; + + cubeAxis[2][0][1] = 1; + cubeAxis[2][1][0] = -1; + cubeAxis[2][2][2] = -1; + + cubeAxis[3][0][1] = -1; + cubeAxis[3][1][0] = -1; + cubeAxis[3][2][2] = 1; + + cubeAxis[4][0][2] = 1; + cubeAxis[4][1][0] = -1; + cubeAxis[4][2][1] = 1; + + cubeAxis[5][0][2] = -1; + cubeAxis[5][1][0] = 1; + cubeAxis[5][2][1] = 1; + + // read all of the images + for ( i = 0 ; i < 6 ; i++ ) { + sprintf( fullname, "env/%s%s", baseName, extensions[i] ); + common->Printf( "loading %s\n", fullname.c_str() ); + session->UpdateScreen(); + R_LoadImage( fullname, &buffers[i], &width, &height, NULL, true ); + if ( !buffers[i] ) { + common->Printf( "failed.\n" ); + for ( i-- ; i >= 0 ; i-- ) { + Mem_Free( buffers[i] ); + } + return; + } + } + + // resample with hemispherical blending + int samples = 1000; + + byte *outBuffer = (byte *)_alloca( outSize * outSize * 4 ); + + for ( int map = 0 ; map < 2 ; map++ ) { + for ( i = 0 ; i < 6 ; i++ ) { + for ( int x = 0 ; x < outSize ; x++ ) { + for ( int y = 0 ; y < outSize ; y++ ) { + idVec3 dir; + float total[3]; + + dir = cubeAxis[i][0] + -( -1 + 2.0*x/(outSize-1) ) * cubeAxis[i][1] + -( -1 + 2.0*y/(outSize-1) ) * cubeAxis[i][2]; + dir.Normalize(); + total[0] = total[1] = total[2] = 0; + //samples = 1; + float limit = map ? 0.95 : 0.25; // small for specular, almost hemisphere for ambient + + for ( int s = 0 ; s < samples ; s++ ) { + // pick a random direction vector that is inside the unit sphere but not behind dir, + // which is a robust way to evenly sample a hemisphere + idVec3 test; + while( 1 ) { + for ( int j = 0 ; j < 3 ; j++ ) { + test[j] = -1 + 2 * (rand()&0x7fff)/(float)0x7fff; + } + if ( test.Length() > 1.0 ) { + continue; + } + test.Normalize(); + if ( test * dir > limit ) { // don't do a complete hemisphere + break; + } + } + byte result[4]; + //test = dir; + R_SampleCubeMap( test, width, buffers, result ); + total[0] += result[0]; + total[1] += result[1]; + total[2] += result[2]; + } + outBuffer[(y*outSize+x)*4+0] = total[0] / samples; + outBuffer[(y*outSize+x)*4+1] = total[1] / samples; + outBuffer[(y*outSize+x)*4+2] = total[2] / samples; + outBuffer[(y*outSize+x)*4+3] = 255; + } + } + + if ( map == 0 ) { + sprintf( fullname, "env/%s_amb%s", baseName, extensions[i] ); + } else { + sprintf( fullname, "env/%s_spec%s", baseName, extensions[i] ); + } + common->Printf( "writing %s\n", fullname.c_str() ); + session->UpdateScreen(); + R_WriteTGA( fullname, outBuffer, outSize, outSize ); + } + } + + for ( i = 0 ; i < 6 ; i++ ) { + if ( buffers[i] ) { + Mem_Free( buffers[i] ); + } + } +} + +//============================================================================ + + +/* +=============== +R_SetColorMappings +=============== +*/ +void R_SetColorMappings( void ) { + int i, j; + float g, b; + int inf; + + b = r_brightness.GetFloat(); + g = r_gamma.GetFloat(); + + for ( i = 0; i < 256; i++ ) { + j = i * b; + if (j > 255) { + j = 255; + } + + if ( g == 1 ) { + inf = (j<<8) | j; + } else { + inf = 0xffff * pow ( j/255.0f, 1.0f / g ) + 0.5f; + } + if (inf < 0) { + inf = 0; + } + if (inf > 0xffff) { + inf = 0xffff; + } + + tr.gammaTable[i] = inf; + } + + GLimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable ); +} + + +/* +================ +GfxInfo_f +================ +*/ +void GfxInfo_f( const idCmdArgs &args ) { + const char *fsstrings[] = + { + "windowed", + "fullscreen" + }; + + common->Printf( "\nGL_VENDOR: %s\n", glConfig.vendor_string ); + common->Printf( "GL_RENDERER: %s\n", glConfig.renderer_string ); + common->Printf( "GL_VERSION: %s\n", glConfig.version_string ); + common->Printf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string ); + if ( glConfig.wgl_extensions_string ) { + common->Printf( "WGL_EXTENSIONS: %s\n", glConfig.wgl_extensions_string ); + } + common->Printf( "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize ); + common->Printf( "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.maxTextureUnits ); + common->Printf( "GL_MAX_TEXTURE_COORDS_ARB: %d\n", glConfig.maxTextureCoords ); + common->Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %d\n", glConfig.maxTextureImageUnits ); + common->Printf( "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits ); + common->Printf( "MODE: %d, %d x %d %s hz:", r_mode.GetInteger(), glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen.GetBool()] ); + + if ( glConfig.displayFrequency ) { + common->Printf( "%d\n", glConfig.displayFrequency ); + } else { + common->Printf( "N/A\n" ); + } + common->Printf( "CPU: %s\n", Sys_GetProcessorString() ); + + const char *active[2] = { "", " (ACTIVE)" }; + common->Printf( "ARB path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB] ); + + if ( glConfig.allowNV10Path ) { + common->Printf( "NV10 path ENABLED%s\n", active[tr.backEndRenderer == BE_NV10] ); + } else { + common->Printf( "NV10 path disabled\n" ); + } + + if ( glConfig.allowNV20Path ) { + common->Printf( "NV20 path ENABLED%s\n", active[tr.backEndRenderer == BE_NV20] ); + } else { + common->Printf( "NV20 path disabled\n" ); + } + + if ( glConfig.allowR200Path ) { + common->Printf( "R200 path ENABLED%s\n", active[tr.backEndRenderer == BE_R200] ); + } else { + common->Printf( "R200 path disabled\n" ); + } + + if ( glConfig.allowARB2Path ) { + common->Printf( "ARB2 path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB2] ); + } else { + common->Printf( "ARB2 path disabled\n" ); + } + + //============================= + + common->Printf( "-------\n" ); + + if ( r_finish.GetBool() ) { + common->Printf( "Forcing glFinish\n" ); + } else { + common->Printf( "glFinish not forced\n" ); + } + +#ifdef _WIN32 +// WGL_EXT_swap_interval +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + + if ( r_swapInterval.GetInteger() && wglSwapIntervalEXT ) { + common->Printf( "Forcing swapInterval %i\n", r_swapInterval.GetInteger() ); + } else { + common->Printf( "swapInterval not forced\n" ); + } +#endif + + bool tss = glConfig.twoSidedStencilAvailable || glConfig.atiTwoSidedStencilAvailable; + + if ( !r_useTwoSidedStencil.GetBool() && tss ) { + common->Printf( "Two sided stencil available but disabled\n" ); + } else if ( !tss ) { + common->Printf( "Two sided stencil not available\n" ); + } else if ( tss ) { + common->Printf( "Using two sided stencil\n" ); + } + + if ( vertexCache.IsFast() ) { + common->Printf( "Vertex cache is fast\n" ); + } else { + common->Printf( "Vertex cache is SLOW\n" ); + } +} + +/* +================= +R_VidRestart_f +================= +*/ +void R_VidRestart_f( const idCmdArgs &args ) { + int err; + + // if OpenGL isn't started, do nothing + if ( !glConfig.isInitialized ) { + return; + } + + bool full = true; + bool forceWindow = false; + for ( int i = 1 ; i < args.Argc() ; i++ ) { + if ( idStr::Icmp( args.Argv( i ), "partial" ) == 0 ) { + full = false; + continue; + } + if ( idStr::Icmp( args.Argv( i ), "windowed" ) == 0 ) { + forceWindow = true; + continue; + } + } + + // this could take a while, so give them the cursor back ASAP + Sys_GrabMouseCursor( false ); + + // dump ambient caches + renderModelManager->FreeModelVertexCaches(); + + // free any current world interaction surfaces and vertex caches + R_FreeDerivedData(); + + // make sure the defered frees are actually freed + R_ToggleSmpFrame(); + R_ToggleSmpFrame(); + + // free the vertex caches so they will be regenerated again + vertexCache.PurgeAll(); + + // sound and input are tied to the window we are about to destroy + + if ( full ) { + // free all of our texture numbers + soundSystem->ShutdownHW(); + Sys_ShutdownInput(); + globalImages->PurgeAllImages(); + // free the context and close the window + GLimp_Shutdown(); + glConfig.isInitialized = false; + + // create the new context and vertex cache + bool latch = cvarSystem->GetCVarBool( "r_fullscreen" ); + if ( forceWindow ) { + cvarSystem->SetCVarBool( "r_fullscreen", false ); + } + R_InitOpenGL(); + cvarSystem->SetCVarBool( "r_fullscreen", latch ); + + // regenerate all images + globalImages->ReloadAllImages(); + } else { + glimpParms_t parms; + parms.width = glConfig.vidWidth; + parms.height = glConfig.vidHeight; + parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetBool(); + parms.displayHz = r_displayRefresh.GetInteger(); + parms.multiSamples = r_multiSamples.GetInteger(); + parms.stereo = false; + GLimp_SetScreenParms( parms ); + } + + + + // make sure the regeneration doesn't use anything no longer valid + tr.viewCount++; + tr.viewDef = NULL; + + // regenerate all necessary interactions + R_RegenerateWorld_f( idCmdArgs() ); + + // check for problems + err = qglGetError(); + if ( err != GL_NO_ERROR ) { + common->Printf( "glGetError() = 0x%x\n", err ); + } + + // start sound playing again + soundSystem->SetMute( false ); +} + + +/* +================= +R_InitMaterials +================= +*/ +void R_InitMaterials( void ) { + tr.defaultMaterial = declManager->FindMaterial( "_default", false ); + if ( !tr.defaultMaterial ) { + common->FatalError( "_default material not found" ); + } + declManager->FindMaterial( "_default", false ); + + // needed by R_DeriveLightData + declManager->FindMaterial( "lights/defaultPointLight" ); + declManager->FindMaterial( "lights/defaultProjectedLight" ); +} + + +/* +================= +R_SizeUp_f + +Keybinding command +================= +*/ +static void R_SizeUp_f( const idCmdArgs &args ) { + if ( r_screenFraction.GetInteger() + 10 > 100 ) { + r_screenFraction.SetInteger( 100 ); + } else { + r_screenFraction.SetInteger( r_screenFraction.GetInteger() + 10 ); + } +} + + +/* +================= +R_SizeDown_f + +Keybinding command +================= +*/ +static void R_SizeDown_f( const idCmdArgs &args ) { + if ( r_screenFraction.GetInteger() - 10 < 10 ) { + r_screenFraction.SetInteger( 10 ); + } else { + r_screenFraction.SetInteger( r_screenFraction.GetInteger() - 10 ); + } +} + + +/* +=============== +TouchGui_f + + this is called from the main thread +=============== +*/ +void R_TouchGui_f( const idCmdArgs &args ) { + const char *gui = args.Argv( 1 ); + + if ( !gui[0] ) { + common->Printf( "USAGE: touchGui \n" ); + return; + } + + common->Printf( "touchGui %s\n", gui ); + session->UpdateScreen(); + uiManager->Touch( gui ); +} + +/* +================= +R_InitCvars +================= +*/ +void R_InitCvars( void ) { + // update latched cvars here +} + +/* +================= +R_InitCommands +================= +*/ +void R_InitCommands( void ) { + cmdSystem->AddCommand( "MakeMegaTexture", idMegaTexture::MakeMegaTexture_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "processes giant images" ); + cmdSystem->AddCommand( "sizeUp", R_SizeUp_f, CMD_FL_RENDERER, "makes the rendered view larger" ); + cmdSystem->AddCommand( "sizeDown", R_SizeDown_f, CMD_FL_RENDERER, "makes the rendered view smaller" ); + cmdSystem->AddCommand( "reloadGuis", R_ReloadGuis_f, CMD_FL_RENDERER, "reloads guis" ); + cmdSystem->AddCommand( "listGuis", R_ListGuis_f, CMD_FL_RENDERER, "lists guis" ); + cmdSystem->AddCommand( "touchGui", R_TouchGui_f, CMD_FL_RENDERER, "touches a gui" ); + cmdSystem->AddCommand( "screenshot", R_ScreenShot_f, CMD_FL_RENDERER, "takes a screenshot" ); + cmdSystem->AddCommand( "envshot", R_EnvShot_f, CMD_FL_RENDERER, "takes an environment shot" ); + cmdSystem->AddCommand( "makeAmbientMap", R_MakeAmbientMap_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "makes an ambient map" ); + cmdSystem->AddCommand( "benchmark", R_Benchmark_f, CMD_FL_RENDERER, "benchmark" ); + cmdSystem->AddCommand( "gfxInfo", GfxInfo_f, CMD_FL_RENDERER, "show graphics info" ); + cmdSystem->AddCommand( "modulateLights", R_ModulateLights_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "modifies shader parms on all lights" ); + cmdSystem->AddCommand( "testImage", R_TestImage_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given image centered on screen", idCmdSystem::ArgCompletion_ImageName ); + cmdSystem->AddCommand( "testVideo", R_TestVideo_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given cinematic", idCmdSystem::ArgCompletion_VideoName ); + cmdSystem->AddCommand( "reportSurfaceAreas", R_ReportSurfaceAreas_f, CMD_FL_RENDERER, "lists all used materials sorted by surface area" ); + cmdSystem->AddCommand( "reportImageDuplication", R_ReportImageDuplication_f, CMD_FL_RENDERER, "checks all referenced images for duplications" ); + cmdSystem->AddCommand( "regenerateWorld", R_RegenerateWorld_f, CMD_FL_RENDERER, "regenerates all interactions" ); + cmdSystem->AddCommand( "showInteractionMemory", R_ShowInteractionMemory_f, CMD_FL_RENDERER, "shows memory used by interactions" ); + cmdSystem->AddCommand( "showTriSurfMemory", R_ShowTriSurfMemory_f, CMD_FL_RENDERER, "shows memory used by triangle surfaces" ); + cmdSystem->AddCommand( "vid_restart", R_VidRestart_f, CMD_FL_RENDERER, "restarts renderSystem" ); + cmdSystem->AddCommand( "listRenderEntityDefs", R_ListRenderEntityDefs_f, CMD_FL_RENDERER, "lists the entity defs" ); + cmdSystem->AddCommand( "listRenderLightDefs", R_ListRenderLightDefs_f, CMD_FL_RENDERER, "lists the light defs" ); + cmdSystem->AddCommand( "listModes", R_ListModes_f, CMD_FL_RENDERER, "lists all video modes" ); + cmdSystem->AddCommand( "reloadSurface", R_ReloadSurface_f, CMD_FL_RENDERER, "reloads the decl and images for selected surface" ); +} + +/* +=============== +idRenderSystemLocal::Clear +=============== +*/ +void idRenderSystemLocal::Clear( void ) { + registered = false; + frameCount = 0; + viewCount = 0; + staticAllocCount = 0; + frameShaderTime = 0.0f; + viewportOffset[0] = 0; + viewportOffset[1] = 0; + tiledViewport[0] = 0; + tiledViewport[1] = 0; + backEndRenderer = BE_BAD; + backEndRendererHasVertexPrograms = false; + backEndRendererMaxLight = 1.0f; + ambientLightVector.Zero(); + sortOffset = 0; + worlds.Clear(); + primaryWorld = NULL; + memset( &primaryRenderView, 0, sizeof( primaryRenderView ) ); + primaryView = NULL; + defaultMaterial = NULL; + testImage = NULL; + ambientCubeImage = NULL; + viewDef = NULL; + memset( &pc, 0, sizeof( pc ) ); + memset( &lockSurfacesCmd, 0, sizeof( lockSurfacesCmd ) ); + memset( &identitySpace, 0, sizeof( identitySpace ) ); + logFile = NULL; + stencilIncr = 0; + stencilDecr = 0; + memset( renderCrops, 0, sizeof( renderCrops ) ); + currentRenderCrop = 0; + guiRecursionLevel = 0; + guiModel = NULL; + demoGuiModel = NULL; + memset( gammaTable, 0, sizeof( gammaTable ) ); + takingScreenshot = false; +} + +/* +=============== +idRenderSystemLocal::Init +=============== +*/ +void idRenderSystemLocal::Init( void ) { + + common->Printf( "------- Initializing renderSystem --------\n" ); + + // clear all our internal state + viewCount = 1; // so cleared structures never match viewCount + // we used to memset tr, but now that it is a class, we can't, so + // there may be other state we need to reset + + ambientLightVector[0] = 0.5f; + ambientLightVector[1] = 0.5f - 0.385f; + ambientLightVector[2] = 0.8925f; + ambientLightVector[3] = 1.0f; + + memset( &backEnd, 0, sizeof( backEnd ) ); + + R_InitCvars(); + + R_InitCommands(); + + guiModel = new idGuiModel; + guiModel->Clear(); + + demoGuiModel = new idGuiModel; + demoGuiModel->Clear(); + + R_InitTriSurfData(); + + globalImages->Init(); + + idCinematic::InitCinematic( ); + + // build brightness translation tables + R_SetColorMappings(); + + R_InitMaterials(); + + renderModelManager->Init(); + + // set the identity space + identitySpace.modelMatrix[0*4+0] = 1.0f; + identitySpace.modelMatrix[1*4+1] = 1.0f; + identitySpace.modelMatrix[2*4+2] = 1.0f; + + // determine which back end we will use + // ??? this is invalid here as there is not enough information to set it up correctly + SetBackEndRenderer(); + + common->Printf( "renderSystem initialized.\n" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +=============== +idRenderSystemLocal::Shutdown +=============== +*/ +void idRenderSystemLocal::Shutdown( void ) { + common->Printf( "idRenderSystem::Shutdown()\n" ); + + R_DoneFreeType( ); + + if ( glConfig.isInitialized ) { + globalImages->PurgeAllImages(); + } + + renderModelManager->Shutdown(); + + idCinematic::ShutdownCinematic( ); + + globalImages->Shutdown(); + + // close the r_logFile + if ( logFile ) { + fprintf( logFile, "*** CLOSING LOG ***\n" ); + fclose( logFile ); + logFile = 0; + } + + // free frame memory + R_ShutdownFrameData(); + + // free the vertex cache, which should have nothing allocated now + vertexCache.Shutdown(); + + R_ShutdownTriSurfData(); + + RB_ShutdownDebugTools(); + + delete guiModel; + delete demoGuiModel; + + Clear(); + + ShutdownOpenGL(); +} + +/* +======================== +idRenderSystemLocal::BeginLevelLoad +======================== +*/ +void idRenderSystemLocal::BeginLevelLoad( void ) { + renderModelManager->BeginLevelLoad(); + globalImages->BeginLevelLoad(); +} + +/* +======================== +idRenderSystemLocal::EndLevelLoad +======================== +*/ +void idRenderSystemLocal::EndLevelLoad( void ) { + renderModelManager->EndLevelLoad(); + globalImages->EndLevelLoad(); + if ( r_forceLoadImages.GetBool() ) { + RB_ShowImages(); + } +} + +/* +======================== +idRenderSystemLocal::InitOpenGL +======================== +*/ +void idRenderSystemLocal::InitOpenGL( void ) { + // if OpenGL isn't started, start it now + if ( !glConfig.isInitialized ) { + int err; + + R_InitOpenGL(); + + globalImages->ReloadAllImages(); + + err = qglGetError(); + if ( err != GL_NO_ERROR ) { + common->Printf( "glGetError() = 0x%x\n", err ); + } + } +} + +/* +======================== +idRenderSystemLocal::ShutdownOpenGL +======================== +*/ +void idRenderSystemLocal::ShutdownOpenGL( void ) { + // free the context and close the window + R_ShutdownFrameData(); + GLimp_Shutdown(); + glConfig.isInitialized = false; +} + +/* +======================== +idRenderSystemLocal::IsOpenGLRunning +======================== +*/ +bool idRenderSystemLocal::IsOpenGLRunning( void ) const { + if ( !glConfig.isInitialized ) { + return false; + } + return true; +} + +/* +======================== +idRenderSystemLocal::IsFullScreen +======================== +*/ +bool idRenderSystemLocal::IsFullScreen( void ) const { + return glConfig.isFullscreen; +} + +/* +======================== +idRenderSystemLocal::GetScreenWidth +======================== +*/ +int idRenderSystemLocal::GetScreenWidth( void ) const { + return glConfig.vidWidth; +} + +/* +======================== +idRenderSystemLocal::GetScreenHeight +======================== +*/ +int idRenderSystemLocal::GetScreenHeight( void ) const { + return glConfig.vidHeight; +} + +/* +======================== +idRenderSystemLocal::GetCardCaps +======================== +*/ +void idRenderSystemLocal::GetCardCaps( bool &oldCard, bool &nv10or20 ) { + nv10or20 = ( tr.backEndRenderer == BE_NV10 || tr.backEndRenderer == BE_NV20 ); + oldCard = ( tr.backEndRenderer == BE_ARB || tr.backEndRenderer == BE_R200 || tr.backEndRenderer == BE_NV10 || tr.backEndRenderer == BE_NV20 ); +} + diff --git a/renderer/RenderWorld.cpp b/renderer/RenderWorld.cpp new file mode 100644 index 000000000..28a0cde6b --- /dev/null +++ b/renderer/RenderWorld.cpp @@ -0,0 +1,2133 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +=================== +R_ListRenderLightDefs_f +=================== +*/ +void R_ListRenderLightDefs_f( const idCmdArgs &args ) { + int i; + idRenderLightLocal *ldef; + + if ( !tr.primaryWorld ) { + return; + } + int active = 0; + int totalRef = 0; + int totalIntr = 0; + + for ( i = 0 ; i < tr.primaryWorld->lightDefs.Num() ; i++ ) { + ldef = tr.primaryWorld->lightDefs[i]; + if ( !ldef ) { + common->Printf( "%4i: FREED\n", i ); + continue; + } + + // count up the interactions + int iCount = 0; + for ( idInteraction *inter = ldef->firstInteraction; inter != NULL; inter = inter->lightNext ) { + iCount++; + } + totalIntr += iCount; + + // count up the references + int rCount = 0; + for ( areaReference_t *ref = ldef->references ; ref ; ref = ref->ownerNext ) { + rCount++; + } + totalRef += rCount; + + common->Printf( "%4i: %3i intr %2i refs %s\n", i, iCount, rCount, ldef->lightShader->GetName()); + active++; + } + + common->Printf( "%i lightDefs, %i interactions, %i areaRefs\n", active, totalIntr, totalRef ); +} + +/* +=================== +R_ListRenderEntityDefs_f +=================== +*/ +void R_ListRenderEntityDefs_f( const idCmdArgs &args ) { + int i; + idRenderEntityLocal *mdef; + + if ( !tr.primaryWorld ) { + return; + } + int active = 0; + int totalRef = 0; + int totalIntr = 0; + + for ( i = 0 ; i < tr.primaryWorld->entityDefs.Num() ; i++ ) { + mdef = tr.primaryWorld->entityDefs[i]; + if ( !mdef ) { + common->Printf( "%4i: FREED\n", i ); + continue; + } + + // count up the interactions + int iCount = 0; + for ( idInteraction *inter = mdef->firstInteraction; inter != NULL; inter = inter->entityNext ) { + iCount++; + } + totalIntr += iCount; + + // count up the references + int rCount = 0; + for ( areaReference_t *ref = mdef->entityRefs ; ref ; ref = ref->ownerNext ) { + rCount++; + } + totalRef += rCount; + + common->Printf( "%4i: %3i intr %2i refs %s\n", i, iCount, rCount, mdef->parms.hModel->Name()); + active++; + } + + common->Printf( "total active: %i\n", active ); +} + +/* +=================== +idRenderWorldLocal::idRenderWorldLocal +=================== +*/ +idRenderWorldLocal::idRenderWorldLocal() { + mapName.Clear(); + mapTimeStamp = FILE_NOT_FOUND_TIMESTAMP; + + generateAllInteractionsCalled = false; + + areaNodes = NULL; + numAreaNodes = 0; + + portalAreas = NULL; + numPortalAreas = 0; + + doublePortals = NULL; + numInterAreaPortals = 0; + + interactionTable = 0; + interactionTableWidth = 0; + interactionTableHeight = 0; +} + +/* +=================== +idRenderWorldLocal::~idRenderWorldLocal +=================== +*/ +idRenderWorldLocal::~idRenderWorldLocal() { + // free all the entityDefs, lightDefs, portals, etc + FreeWorld(); + + // free up the debug lines, polys, and text + RB_ClearDebugPolygons( 0 ); + RB_ClearDebugLines( 0 ); + RB_ClearDebugText( 0 ); +} + +/* +=================== +ResizeInteractionTable +=================== +*/ +void idRenderWorldLocal::ResizeInteractionTable() { + // we overflowed the interaction table, so dump it + // we may want to resize this in the future if it turns out to be common + common->Printf( "idRenderWorldLocal::ResizeInteractionTable: overflowed interactionTableWidth, dumping\n" ); + R_StaticFree( interactionTable ); + interactionTable = NULL; +} + +/* +=================== +AddEntityDef +=================== +*/ +qhandle_t idRenderWorldLocal::AddEntityDef( const renderEntity_t *re ){ + // try and reuse a free spot + int entityHandle = entityDefs.FindNull(); + if ( entityHandle == -1 ) { + entityHandle = entityDefs.Append( NULL ); + if ( interactionTable && entityDefs.Num() > interactionTableWidth ) { + ResizeInteractionTable(); + } + } + + UpdateEntityDef( entityHandle, re ); + + return entityHandle; +} + +/* +============== +UpdateEntityDef + +Does not write to the demo file, which will only be updated for +visible entities +============== +*/ +int c_callbackUpdate; + +void idRenderWorldLocal::UpdateEntityDef( qhandle_t entityHandle, const renderEntity_t *re ) { + if ( r_skipUpdates.GetBool() ) { + return; + } + + tr.pc.c_entityUpdates++; + + if ( !re->hModel && !re->callback ) { + common->Error( "idRenderWorld::UpdateEntityDef: NULL hModel" ); + } + + // create new slots if needed + if ( entityHandle < 0 || entityHandle > LUDICROUS_INDEX ) { + common->Error( "idRenderWorld::UpdateEntityDef: index = %i", entityHandle ); + } + while ( entityHandle >= entityDefs.Num() ) { + entityDefs.Append( NULL ); + } + + idRenderEntityLocal *def = entityDefs[entityHandle]; + if ( def ) { + + if ( !re->forceUpdate ) { + + // check for exact match (OPTIMIZE: check through pointers more) + if ( !re->joints && !re->callbackData && !def->dynamicModel && !memcmp( re, &def->parms, sizeof( *re ) ) ) { + return; + } + + // if the only thing that changed was shaderparms, we can just leave things as they are + // after updating parms + + // if we have a callback function and the bounds, origin, axis and model match, + // then we can leave the references as they are + if ( re->callback ) { + + bool axisMatch = ( re->axis == def->parms.axis ); + bool originMatch = ( re->origin == def->parms.origin ); + bool boundsMatch = ( re->bounds == def->referenceBounds ); + bool modelMatch = ( re->hModel == def->parms.hModel ); + + if ( boundsMatch && originMatch && axisMatch && modelMatch ) { + // only clear the dynamic model and interaction surfaces if they exist + c_callbackUpdate++; + R_ClearEntityDefDynamicModel( def ); + def->parms = *re; + return; + } + } + } + + // save any decals if the model is the same, allowing marks to move with entities + if ( def->parms.hModel == re->hModel ) { + R_FreeEntityDefDerivedData( def, true, true ); + } else { + R_FreeEntityDefDerivedData( def, false, false ); + } + } else { + // creating a new one + def = new idRenderEntityLocal; + entityDefs[entityHandle] = def; + + def->world = this; + def->index = entityHandle; + } + + def->parms = *re; + + R_AxisToModelMatrix( def->parms.axis, def->parms.origin, def->modelMatrix ); + + def->lastModifiedFrameNum = tr.frameCount; + if ( session->writeDemo && def->archived ) { + WriteFreeEntity( entityHandle ); + def->archived = false; + } + + // optionally immediately issue any callbacks + if ( !r_useEntityCallbacks.GetBool() && def->parms.callback ) { + R_IssueEntityDefCallback( def ); + } + + // based on the model bounds, add references in each area + // that may contain the updated surface + R_CreateEntityRefs( def ); +} + +/* +=================== +FreeEntityDef + +Frees all references and lit surfaces from the model, and +NULL's out it's entry in the world list +=================== +*/ +void idRenderWorldLocal::FreeEntityDef( qhandle_t entityHandle ) { + idRenderEntityLocal *def; + + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { + common->Printf( "idRenderWorld::FreeEntityDef: handle %i > %i\n", entityHandle, entityDefs.Num() ); + return; + } + + def = entityDefs[entityHandle]; + if ( !def ) { + common->Printf( "idRenderWorld::FreeEntityDef: handle %i is NULL\n", entityHandle ); + return; + } + + R_FreeEntityDefDerivedData( def, false, false ); + + if ( session->writeDemo && def->archived ) { + WriteFreeEntity( entityHandle ); + } + + // if we are playing a demo, these will have been freed + // in R_FreeEntityDefDerivedData(), otherwise the gui + // object still exists in the game + + def->parms.gui[ 0 ] = NULL; + def->parms.gui[ 1 ] = NULL; + def->parms.gui[ 2 ] = NULL; + + delete def; + entityDefs[ entityHandle ] = NULL; +} + +/* +================== +GetRenderEntity +================== +*/ +const renderEntity_t *idRenderWorldLocal::GetRenderEntity( qhandle_t entityHandle ) const { + idRenderEntityLocal *def; + + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { + common->Printf( "idRenderWorld::GetRenderEntity: invalid handle %i [0, %i]\n", entityHandle, entityDefs.Num() ); + return NULL; + } + + def = entityDefs[entityHandle]; + if ( !def ) { + common->Printf( "idRenderWorld::GetRenderEntity: handle %i is NULL\n", entityHandle ); + return NULL; + } + + return &def->parms; +} + +/* +================== +AddLightDef +================== +*/ +qhandle_t idRenderWorldLocal::AddLightDef( const renderLight_t *rlight ) { + // try and reuse a free spot + int lightHandle = lightDefs.FindNull(); + + if ( lightHandle == -1 ) { + lightHandle = lightDefs.Append( NULL ); + if ( interactionTable && lightDefs.Num() > interactionTableHeight ) { + ResizeInteractionTable(); + } + } + UpdateLightDef( lightHandle, rlight ); + + return lightHandle; +} + +/* +================= +UpdateLightDef + +The generation of all the derived interaction data will +usually be deferred until it is visible in a scene + +Does not write to the demo file, which will only be done for visible lights +================= +*/ +void idRenderWorldLocal::UpdateLightDef( qhandle_t lightHandle, const renderLight_t *rlight ) { + if ( r_skipUpdates.GetBool() ) { + return; + } + + tr.pc.c_lightUpdates++; + + // create new slots if needed + if ( lightHandle < 0 || lightHandle > LUDICROUS_INDEX ) { + common->Error( "idRenderWorld::UpdateLightDef: index = %i", lightHandle ); + } + while ( lightHandle >= lightDefs.Num() ) { + lightDefs.Append( NULL ); + } + + bool justUpdate = false; + idRenderLightLocal *light = lightDefs[lightHandle]; + if ( light ) { + // if the shape of the light stays the same, we don't need to dump + // any of our derived data, because shader parms are calculated every frame + if ( rlight->axis == light->parms.axis && rlight->end == light->parms.end && + rlight->lightCenter == light->parms.lightCenter && rlight->lightRadius == light->parms.lightRadius && + rlight->noShadows == light->parms.noShadows && rlight->origin == light->parms.origin && + rlight->parallel == light->parms.parallel && rlight->pointLight == light->parms.pointLight && + rlight->right == light->parms.right && rlight->start == light->parms.start && + rlight->target == light->parms.target && rlight->up == light->parms.up && + rlight->shader == light->lightShader && rlight->prelightModel == light->parms.prelightModel ) { + justUpdate = true; + } else { + // if we are updating shadows, the prelight model is no longer valid + light->lightHasMoved = true; + R_FreeLightDefDerivedData( light ); + } + } else { + // create a new one + light = new idRenderLightLocal; + lightDefs[lightHandle] = light; + + light->world = this; + light->index = lightHandle; + } + + light->parms = *rlight; + light->lastModifiedFrameNum = tr.frameCount; + if ( session->writeDemo && light->archived ) { + WriteFreeLight( lightHandle ); + light->archived = false; + } + + if ( light->lightHasMoved ) { + light->parms.prelightModel = NULL; + } + + if (!justUpdate) { + R_DeriveLightData( light ); + R_CreateLightRefs( light ); + R_CreateLightDefFogPortals( light ); + } +} + +/* +==================== +FreeLightDef + +Frees all references and lit surfaces from the light, and +NULL's out it's entry in the world list +==================== +*/ +void idRenderWorldLocal::FreeLightDef( qhandle_t lightHandle ) { + idRenderLightLocal *light; + + if ( lightHandle < 0 || lightHandle >= lightDefs.Num() ) { + common->Printf( "idRenderWorld::FreeLightDef: invalid handle %i [0, %i]\n", lightHandle, lightDefs.Num() ); + return; + } + + light = lightDefs[lightHandle]; + if ( !light ) { + common->Printf( "idRenderWorld::FreeLightDef: handle %i is NULL\n", lightHandle ); + return; + } + + R_FreeLightDefDerivedData( light ); + + if ( session->writeDemo && light->archived ) { + WriteFreeLight( lightHandle ); + } + + delete light; + lightDefs[lightHandle] = NULL; +} + +/* +================== +GetRenderLight +================== +*/ +const renderLight_t *idRenderWorldLocal::GetRenderLight( qhandle_t lightHandle ) const { + idRenderLightLocal *def; + + if ( lightHandle < 0 || lightHandle >= lightDefs.Num() ) { + common->Printf( "idRenderWorld::GetRenderLight: handle %i > %i\n", lightHandle, lightDefs.Num() ); + return NULL; + } + + def = lightDefs[lightHandle]; + if ( !def ) { + common->Printf( "idRenderWorld::GetRenderLight: handle %i is NULL\n", lightHandle ); + return NULL; + } + + return &def->parms; +} + +/* +================ +idRenderWorldLocal::ProjectDecalOntoWorld +================ +*/ +void idRenderWorldLocal::ProjectDecalOntoWorld( const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) { + int i, areas[10], numAreas; + const areaReference_t *ref; + const portalArea_t *area; + const idRenderModel *model; + idRenderEntityLocal *def; + decalProjectionInfo_t info, localInfo; + + if ( !idRenderModelDecal::CreateProjectionInfo( info, winding, projectionOrigin, parallel, fadeDepth, material, startTime ) ) { + return; + } + + // get the world areas touched by the projection volume + numAreas = BoundsInAreas( info.projectionBounds, areas, 10 ); + + // check all areas for models + for ( i = 0; i < numAreas; i++ ) { + + area = &portalAreas[ areas[i] ]; + + // check all models in this area + for ( ref = area->entityRefs.areaNext; ref != &area->entityRefs; ref = ref->areaNext ) { + def = ref->entity; + + // completely ignore any dynamic or callback models + model = def->parms.hModel; + if ( model == NULL || model->IsDynamicModel() != DM_STATIC || def->parms.callback ) { + continue; + } + + if ( def->parms.customShader != NULL && !def->parms.customShader->AllowOverlays() ) { + continue; + } + + idBounds bounds; + bounds.FromTransformedBounds( model->Bounds( &def->parms ), def->parms.origin, def->parms.axis ); + + // if the model bounds do not overlap with the projection bounds + if ( !info.projectionBounds.IntersectsBounds( bounds ) ) { + continue; + } + + // transform the bounding planes, fade planes and texture axis into local space + idRenderModelDecal::GlobalProjectionInfoToLocal( localInfo, info, def->parms.origin, def->parms.axis ); + localInfo.force = ( def->parms.customShader != NULL ); + + if ( !def->decals ) { + def->decals = idRenderModelDecal::Alloc(); + } + def->decals->CreateDecal( model, localInfo ); + } + } +} + +/* +==================== +idRenderWorldLocal::ProjectDecal +==================== +*/ +void idRenderWorldLocal::ProjectDecal( qhandle_t entityHandle, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) { + decalProjectionInfo_t info, localInfo; + + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { + common->Error( "idRenderWorld::ProjectOverlay: index = %i", entityHandle ); + return; + } + + idRenderEntityLocal *def = entityDefs[ entityHandle ]; + if ( !def ) { + return; + } + + const idRenderModel *model = def->parms.hModel; + + if ( model == NULL || model->IsDynamicModel() != DM_STATIC || def->parms.callback ) { + return; + } + + if ( !idRenderModelDecal::CreateProjectionInfo( info, winding, projectionOrigin, parallel, fadeDepth, material, startTime ) ) { + return; + } + + idBounds bounds; + bounds.FromTransformedBounds( model->Bounds( &def->parms ), def->parms.origin, def->parms.axis ); + + // if the model bounds do not overlap with the projection bounds + if ( !info.projectionBounds.IntersectsBounds( bounds ) ) { + return; + } + + // transform the bounding planes, fade planes and texture axis into local space + idRenderModelDecal::GlobalProjectionInfoToLocal( localInfo, info, def->parms.origin, def->parms.axis ); + localInfo.force = ( def->parms.customShader != NULL ); + + if ( def->decals == NULL ) { + def->decals = idRenderModelDecal::Alloc(); + } + def->decals->CreateDecal( model, localInfo ); +} + +/* +==================== +idRenderWorldLocal::ProjectOverlay +==================== +*/ +void idRenderWorldLocal::ProjectOverlay( qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material ) { + + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { + common->Error( "idRenderWorld::ProjectOverlay: index = %i", entityHandle ); + return; + } + + idRenderEntityLocal *def = entityDefs[ entityHandle ]; + if ( !def ) { + return; + } + + const renderEntity_t *refEnt = &def->parms; + + idRenderModel *model = refEnt->hModel; + if ( model->IsDynamicModel() != DM_CACHED ) { // FIXME: probably should be MD5 only + return; + } + model = R_EntityDefDynamicModel( def ); + + if ( def->overlay == NULL ) { + def->overlay = idRenderModelOverlay::Alloc(); + } + def->overlay->CreateOverlay( model, localTextureAxis, material ); +} + +/* +==================== +idRenderWorldLocal::RemoveDecals +==================== +*/ +void idRenderWorldLocal::RemoveDecals( qhandle_t entityHandle ) { + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { + common->Error( "idRenderWorld::ProjectOverlay: index = %i", entityHandle ); + return; + } + + idRenderEntityLocal *def = entityDefs[ entityHandle ]; + if ( !def ) { + return; + } + + R_FreeEntityDefDecals( def ); + R_FreeEntityDefOverlay( def ); +} + +/* +==================== +SetRenderView + +Sets the current view so any calls to the render world will use the correct parms. +==================== +*/ +void idRenderWorldLocal::SetRenderView( const renderView_t *renderView ) { + tr.primaryRenderView = *renderView; +} + +/* +==================== +RenderScene + +Draw a 3D view into a part of the window, then return +to 2D drawing. + +Rendering a scene may require multiple views to be rendered +to handle mirrors, +==================== +*/ +void idRenderWorldLocal::RenderScene( const renderView_t *renderView ) { +#ifndef ID_DEDICATED + renderView_t copy; + + if ( !glConfig.isInitialized ) { + return; + } + + copy = *renderView; + + // skip front end rendering work, which will result + // in only gui drawing + if ( r_skipFrontEnd.GetBool() ) { + return; + } + + if ( renderView->fov_x <= 0 || renderView->fov_y <= 0 ) { + common->Error( "idRenderWorld::RenderScene: bad FOVs: %f, %f", renderView->fov_x, renderView->fov_y ); + } + + // close any gui drawing + tr.guiModel->EmitFullScreen(); + tr.guiModel->Clear(); + + int startTime = Sys_Milliseconds(); + + // setup view parms for the initial view + // + viewDef_t *parms = (viewDef_t *)R_ClearedFrameAlloc( sizeof( *parms ) ); + parms->renderView = *renderView; + + if ( tr.takingScreenshot ) { + parms->renderView.forceUpdate = true; + } + + // set up viewport, adjusted for resolution and OpenGL style 0 at the bottom + tr.RenderViewToViewport( &parms->renderView, &parms->viewport ); + + // the scissor bounds may be shrunk in subviews even if + // the viewport stays the same + // this scissor range is local inside the viewport + parms->scissor.x1 = 0; + parms->scissor.y1 = 0; + parms->scissor.x2 = parms->viewport.x2 - parms->viewport.x1; + parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1; + + + parms->isSubview = false; + parms->initialViewAreaOrigin = renderView->vieworg; + parms->floatTime = parms->renderView.time * 0.001f; + parms->renderWorld = this; + + // use this time for any subsequent 2D rendering, so damage blobs/etc + // can use level time + tr.frameShaderTime = parms->floatTime; + + // see if the view needs to reverse the culling sense in mirrors + // or environment cube sides + idVec3 cross; + cross = parms->renderView.viewaxis[1].Cross( parms->renderView.viewaxis[2] ); + if ( cross * parms->renderView.viewaxis[0] > 0 ) { + parms->isMirror = false; + } else { + parms->isMirror = true; + } + + if ( r_lockSurfaces.GetBool() ) { + R_LockSurfaceScene( parms ); + return; + } + + // save this world for use by some console commands + tr.primaryWorld = this; + tr.primaryRenderView = *renderView; + tr.primaryView = parms; + + // rendering this view may cause other views to be rendered + // for mirrors / portals / shadows / environment maps + // this will also cause any necessary entities and lights to be + // updated to the demo file + R_RenderView( parms ); + + // now write delete commands for any modified-but-not-visible entities, and + // add the renderView command to the demo + if ( session->writeDemo ) { + WriteRenderView( renderView ); + } + +#if 0 + for ( int i = 0 ; i < entityDefs.Num() ; i++ ) { + idRenderEntityLocal *def = entityDefs[i]; + if ( !def ) { + continue; + } + if ( def->parms.callback ) { + continue; + } + if ( def->parms.hModel->IsDynamicModel() == DM_CONTINUOUS ) { + } + } +#endif + + int endTime = Sys_Milliseconds(); + + tr.pc.frontEndMsec += endTime - startTime; + + // prepare for any 2D drawing after this + tr.guiModel->Clear(); +#endif +} + +/* +=================== +NumAreas +=================== +*/ +int idRenderWorldLocal::NumAreas( void ) const { + return numPortalAreas; +} + +/* +=================== +NumPortalsInArea +=================== +*/ +int idRenderWorldLocal::NumPortalsInArea( int areaNum ) { + portalArea_t *area; + int count; + portal_t *portal; + + if ( areaNum >= numPortalAreas || areaNum < 0 ) { + common->Error( "idRenderWorld::NumPortalsInArea: bad areanum %i", areaNum ); + } + area = &portalAreas[areaNum]; + + count = 0; + for ( portal = area->portals ; portal ; portal = portal->next ) { + count++; + } + return count; +} + +/* +=================== +GetPortal +=================== +*/ +exitPortal_t idRenderWorldLocal::GetPortal( int areaNum, int portalNum ) { + portalArea_t *area; + int count; + portal_t *portal; + exitPortal_t ret; + + if ( areaNum > numPortalAreas ) { + common->Error( "idRenderWorld::GetPortal: areaNum > numAreas" ); + } + area = &portalAreas[areaNum]; + + count = 0; + for ( portal = area->portals ; portal ; portal = portal->next ) { + if ( count == portalNum ) { + ret.areas[0] = areaNum; + ret.areas[1] = portal->intoArea; + ret.w = portal->w; + ret.blockingBits = portal->doublePortal->blockingBits; + ret.portalHandle = portal->doublePortal - doublePortals + 1; + return ret; + } + count++; + } + + common->Error( "idRenderWorld::GetPortal: portalNum > numPortals" ); + + memset( &ret, 0, sizeof( ret ) ); + return ret; +} + +/* +=============== +PointInAreaNum + +Will return -1 if the point is not in an area, otherwise +it will return 0 <= value < tr.world->numPortalAreas +=============== +*/ +int idRenderWorldLocal::PointInArea( const idVec3 &point ) const { + areaNode_t *node; + int nodeNum; + float d; + + node = areaNodes; + if ( !node ) { + return -1; + } + while( 1 ) { + d = point * node->plane.Normal() + node->plane[3]; + if (d > 0) { + nodeNum = node->children[0]; + } else { + nodeNum = node->children[1]; + } + if ( nodeNum == 0 ) { + return -1; // in solid + } + if ( nodeNum < 0 ) { + nodeNum = -1 - nodeNum; + if ( nodeNum >= numPortalAreas ) { + common->Error( "idRenderWorld::PointInArea: area out of range" ); + } + return nodeNum; + } + node = areaNodes + nodeNum; + } + + return -1; +} + +/* +=================== +BoundsInAreas_r +=================== +*/ +void idRenderWorldLocal::BoundsInAreas_r( int nodeNum, const idBounds &bounds, int *areas, int *numAreas, int maxAreas ) const { + int side, i; + areaNode_t *node; + + do { + if ( nodeNum < 0 ) { + nodeNum = -1 - nodeNum; + + for ( i = 0; i < (*numAreas); i++ ) { + if ( areas[i] == nodeNum ) { + break; + } + } + if ( i >= (*numAreas) && (*numAreas) < maxAreas ) { + areas[(*numAreas)++] = nodeNum; + } + return; + } + + node = areaNodes + nodeNum; + + side = bounds.PlaneSide( node->plane ); + if ( side == PLANESIDE_FRONT ) { + nodeNum = node->children[0]; + } + else if ( side == PLANESIDE_BACK ) { + nodeNum = node->children[1]; + } + else { + if ( node->children[1] != 0 ) { + BoundsInAreas_r( node->children[1], bounds, areas, numAreas, maxAreas ); + if ( (*numAreas) >= maxAreas ) { + return; + } + } + nodeNum = node->children[0]; + } + } while( nodeNum != 0 ); + + return; +} + +/* +=================== +BoundsInAreas + + fills the *areas array with the number of the areas the bounds are in + returns the total number of areas the bounds are in +=================== +*/ +int idRenderWorldLocal::BoundsInAreas( const idBounds &bounds, int *areas, int maxAreas ) const { + int numAreas = 0; + + assert( areas ); + assert( bounds[0][0] <= bounds[1][0] && bounds[0][1] <= bounds[1][1] && bounds[0][2] <= bounds[1][2] ); + assert( bounds[1][0] - bounds[0][0] < 1e4f && bounds[1][1] - bounds[0][1] < 1e4f && bounds[1][2] - bounds[0][2] < 1e4f ); + + if ( !areaNodes ) { + return numAreas; + } + BoundsInAreas_r( 0, bounds, areas, &numAreas, maxAreas ); + return numAreas; +} + +/* +================ +GuiTrace + +checks a ray trace against any gui surfaces in an entity, returning the +fraction location of the trace on the gui surface, or -1,-1 if no hit. +this doesn't do any occlusion testing, simply ignoring non-gui surfaces. +start / end are in global world coordinates. +================ +*/ +guiPoint_t idRenderWorldLocal::GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const { + localTrace_t local; + idVec3 localStart, localEnd, bestPoint; + int j; + idRenderModel *model; + srfTriangles_t *tri; + const idMaterial *shader; + guiPoint_t pt; + + pt.x = pt.y = -1; + pt.guiId = 0; + + if ( ( entityHandle < 0 ) || ( entityHandle >= entityDefs.Num() ) ) { + common->Printf( "idRenderWorld::GuiTrace: invalid handle %i\n", entityHandle ); + return pt; + } + + idRenderEntityLocal *def = entityDefs[entityHandle]; + if ( !def ) { + common->Printf( "idRenderWorld::GuiTrace: handle %i is NULL\n", entityHandle ); + return pt; + } + + model = def->parms.hModel; + if ( def->parms.callback || !def->parms.hModel || def->parms.hModel->IsDynamicModel() != DM_STATIC ) { + return pt; + } + + // transform the points into local space + R_GlobalPointToLocal( def->modelMatrix, start, localStart ); + R_GlobalPointToLocal( def->modelMatrix, end, localEnd ); + + + float best = 99999.0; + const modelSurface_t *bestSurf = NULL; + + for ( j = 0 ; j < model->NumSurfaces() ; j++ ) { + const modelSurface_t *surf = model->Surface( j ); + + tri = surf->geometry; + if ( !tri ) { + continue; + } + + shader = R_RemapShaderBySkin( surf->shader, def->parms.customSkin, def->parms.customShader ); + if ( !shader ) { + continue; + } + // only trace against gui surfaces + if (!shader->HasGui()) { + continue; + } + + local = R_LocalTrace( localStart, localEnd, 0.0f, tri ); + if ( local.fraction < 1.0 ) { + idVec3 origin, axis[3]; + idVec3 cursor; + float axisLen[2]; + + R_SurfaceToTextureAxis( tri, origin, axis ); + cursor = local.point - origin; + + axisLen[0] = axis[0].Length(); + axisLen[1] = axis[1].Length(); + + pt.x = ( cursor * axis[0] ) / ( axisLen[0] * axisLen[0] ); + pt.y = ( cursor * axis[1] ) / ( axisLen[1] * axisLen[1] ); + pt.guiId = shader->GetEntityGui(); + + return pt; + } + } + + return pt; +} + +/* +=================== +idRenderWorldLocal::ModelTrace +=================== +*/ +bool idRenderWorldLocal::ModelTrace( modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius ) const { + int i; + bool collisionSurface; + const modelSurface_t *surf; + localTrace_t localTrace; + idRenderModel *model; + float modelMatrix[16]; + idVec3 localStart, localEnd; + const idMaterial *shader; + + trace.fraction = 1.0f; + + if ( entityHandle < 0 || entityHandle >= entityDefs.Num() ) { +// common->Error( "idRenderWorld::ModelTrace: index = %i", entityHandle ); + return false; + } + + idRenderEntityLocal *def = entityDefs[entityHandle]; + if ( !def ) { + return false; + } + + renderEntity_t *refEnt = &def->parms; + + model = R_EntityDefDynamicModel( def ); + if ( !model ) { + return false; + } + + // transform the points into local space + R_AxisToModelMatrix( refEnt->axis, refEnt->origin, modelMatrix ); + R_GlobalPointToLocal( modelMatrix, start, localStart ); + R_GlobalPointToLocal( modelMatrix, end, localEnd ); + + // if we have explicit collision surfaces, only collide against them + // (FIXME, should probably have a parm to control this) + collisionSurface = false; + for ( i = 0; i < model->NumBaseSurfaces(); i++ ) { + surf = model->Surface( i ); + + shader = R_RemapShaderBySkin( surf->shader, def->parms.customSkin, def->parms.customShader ); + + if ( shader->GetSurfaceFlags() & SURF_COLLISION ) { + collisionSurface = true; + break; + } + } + + // only use baseSurfaces, not any overlays + for ( i = 0; i < model->NumBaseSurfaces(); i++ ) { + surf = model->Surface( i ); + + shader = R_RemapShaderBySkin( surf->shader, def->parms.customSkin, def->parms.customShader ); + + if ( !surf->geometry || !shader ) { + continue; + } + + if ( collisionSurface ) { + // only trace vs collision surfaces + if ( !( shader->GetSurfaceFlags() & SURF_COLLISION ) ) { + continue; + } + } else { + // skip if not drawn or translucent + if ( !shader->IsDrawn() || ( shader->Coverage() != MC_OPAQUE && shader->Coverage() != MC_PERFORATED ) ) { + continue; + } + } + + localTrace = R_LocalTrace( localStart, localEnd, radius, surf->geometry ); + + if ( localTrace.fraction < trace.fraction ) { + trace.fraction = localTrace.fraction; + R_LocalPointToGlobal( modelMatrix, localTrace.point, trace.point ); + trace.normal = localTrace.normal * refEnt->axis; + trace.material = shader; + trace.entity = &def->parms; + trace.jointNumber = refEnt->hModel->NearestJoint( i, localTrace.indexes[0], localTrace.indexes[1], localTrace.indexes[2] ); + } + } + + return ( trace.fraction < 1.0f ); +} + +/* +=================== +idRenderWorldLocal::Trace +=================== +*/ +// FIXME: _D3XP added those. +const char* playerModelExcludeList[] = { + "models/md5/characters/player/d3xp_spplayer.md5mesh", + "models/md5/characters/player/head/d3xp_head.md5mesh", + "models/md5/weapons/pistol_world/worldpistol.md5mesh", + NULL +}; + +const char* playerMaterialExcludeList[] = { + "muzzlesmokepuff", + NULL +}; + +bool idRenderWorldLocal::Trace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic, bool skipPlayer /*_D3XP*/ ) const { + areaReference_t * ref; + idRenderEntityLocal *def; + portalArea_t * area; + idRenderModel * model; + srfTriangles_t * tri; + localTrace_t localTrace; + int areas[128], numAreas, i, j, numSurfaces; + idBounds traceBounds, bounds; + float modelMatrix[16]; + idVec3 localStart, localEnd; + const idMaterial *shader; + + trace.fraction = 1.0f; + trace.point = end; + + // bounds for the whole trace + traceBounds.Clear(); + traceBounds.AddPoint( start ); + traceBounds.AddPoint( end ); + + // get the world areas the trace is in + numAreas = BoundsInAreas( traceBounds, areas, 128 ); + + numSurfaces = 0; + + // check all areas for models + for ( i = 0; i < numAreas; i++ ) { + + area = &portalAreas[ areas[i] ]; + + // check all models in this area + for ( ref = area->entityRefs.areaNext; ref != &area->entityRefs; ref = ref->areaNext ) { + def = ref->entity; + + model = def->parms.hModel; + if ( !model ) { + continue; + } + + if ( model->IsDynamicModel() != DM_STATIC ) { + if ( skipDynamic ) { + continue; + } + +#if 1 /* _D3XP addition. could use a cleaner approach */ + if ( skipPlayer ) { + idStr name = model->Name(); + const char *exclude; + int k; + + for ( k = 0; playerModelExcludeList[k]; k++ ) { + exclude = playerModelExcludeList[k]; + if ( name == exclude ) { + break; + } + } + + if ( playerModelExcludeList[k] ) { + continue; + } + } +#endif + + model = R_EntityDefDynamicModel( def ); + if ( !model ) { + continue; // can happen with particle systems, which don't instantiate without a valid view + } + } + + bounds.FromTransformedBounds( model->Bounds( &def->parms ), def->parms.origin, def->parms.axis ); + + // if the model bounds do not overlap with the trace bounds + if ( !traceBounds.IntersectsBounds( bounds ) || !bounds.LineIntersection( start, trace.point ) ) { + continue; + } + + // check all model surfaces + for ( j = 0; j < model->NumSurfaces(); j++ ) { + const modelSurface_t *surf = model->Surface( j ); + + shader = R_RemapShaderBySkin( surf->shader, def->parms.customSkin, def->parms.customShader ); + + // if no geometry or no shader + if ( !surf->geometry || !shader ) { + continue; + } + +#if 1 /* _D3XP addition. could use a cleaner approach */ + if ( skipPlayer ) { + idStr name = shader->GetName(); + const char *exclude; + int k; + + for ( k = 0; playerMaterialExcludeList[k]; k++ ) { + exclude = playerMaterialExcludeList[k]; + if ( name == exclude ) { + break; + } + } + + if ( playerMaterialExcludeList[k] ) { + continue; + } + } +#endif + + tri = surf->geometry; + + bounds.FromTransformedBounds( tri->bounds, def->parms.origin, def->parms.axis ); + + // if triangle bounds do not overlap with the trace bounds + if ( !traceBounds.IntersectsBounds( bounds ) || !bounds.LineIntersection( start, trace.point ) ) { + continue; + } + + numSurfaces++; + + // transform the points into local space + R_AxisToModelMatrix( def->parms.axis, def->parms.origin, modelMatrix ); + R_GlobalPointToLocal( modelMatrix, start, localStart ); + R_GlobalPointToLocal( modelMatrix, end, localEnd ); + + localTrace = R_LocalTrace( localStart, localEnd, radius, surf->geometry ); + + if ( localTrace.fraction < trace.fraction ) { + trace.fraction = localTrace.fraction; + R_LocalPointToGlobal( modelMatrix, localTrace.point, trace.point ); + trace.normal = localTrace.normal * def->parms.axis; + trace.material = shader; + trace.entity = &def->parms; + trace.jointNumber = model->NearestJoint( j, localTrace.indexes[0], localTrace.indexes[1], localTrace.indexes[2] ); + + traceBounds.Clear(); + traceBounds.AddPoint( start ); + traceBounds.AddPoint( start + trace.fraction * (end - start) ); + } + } + } + } + return ( trace.fraction < 1.0f ); +} + +/* +================== +idRenderWorldLocal::RecurseProcBSP +================== +*/ +void idRenderWorldLocal::RecurseProcBSP_r( modelTrace_t *results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3 &p1, const idVec3 &p2 ) const { + float t1, t2; + float frac; + idVec3 mid; + int side; + float midf; + areaNode_t *node; + + if ( results->fraction <= p1f) { + return; // already hit something nearer + } + // empty leaf + if ( nodeNum < 0 ) { + return; + } + // if solid leaf node + if ( nodeNum == 0 ) { + if ( parentNodeNum != -1 ) { + + results->fraction = p1f; + results->point = p1; + node = &areaNodes[parentNodeNum]; + results->normal = node->plane.Normal(); + return; + } + } + node = &areaNodes[nodeNum]; + + // distance from plane for trace start and end + t1 = node->plane.Normal() * p1 + node->plane[3]; + t2 = node->plane.Normal() * p2 + node->plane[3]; + + if ( t1 >= 0.0f && t2 >= 0.0f ) { + RecurseProcBSP_r( results, nodeNum, node->children[0], p1f, p2f, p1, p2 ); + return; + } + if ( t1 < 0.0f && t2 < 0.0f ) { + RecurseProcBSP_r( results, nodeNum, node->children[1], p1f, p2f, p1, p2 ); + return; + } + side = t1 < t2; + frac = t1 / (t1 - t2); + midf = p1f + frac*(p2f - p1f); + mid[0] = p1[0] + frac*(p2[0] - p1[0]); + mid[1] = p1[1] + frac*(p2[1] - p1[1]); + mid[2] = p1[2] + frac*(p2[2] - p1[2]); + RecurseProcBSP_r( results, nodeNum, node->children[side], p1f, midf, p1, mid ); + RecurseProcBSP_r( results, nodeNum, node->children[side^1], midf, p2f, mid, p2 ); +} + +/* +================== +idRenderWorldLocal::FastWorldTrace +================== +*/ +bool idRenderWorldLocal::FastWorldTrace( modelTrace_t &results, const idVec3 &start, const idVec3 &end ) const { + memset( &results, 0, sizeof( modelTrace_t ) ); + results.fraction = 1.0f; + if ( areaNodes != NULL ) { + RecurseProcBSP_r( &results, -1, 0, 0.0f, 1.0f, start, end ); + return ( results.fraction < 1.0f ); + } + return false; +} + +/* +================================================================================= + +CREATE MODEL REFS + +================================================================================= +*/ + +/* +================= +AddEntityRefToArea + +This is called by R_PushVolumeIntoTree and also directly +for the world model references that are precalculated. +================= +*/ +void idRenderWorldLocal::AddEntityRefToArea( idRenderEntityLocal *def, portalArea_t *area ) { + areaReference_t *ref; + + if ( !def ) { + common->Error( "idRenderWorldLocal::AddEntityRefToArea: NULL def" ); + } + + ref = areaReferenceAllocator.Alloc(); + + tr.pc.c_entityReferences++; + + ref->entity = def; + + // link to entityDef + ref->ownerNext = def->entityRefs; + def->entityRefs = ref; + + // link to end of area list + ref->area = area; + ref->areaNext = &area->entityRefs; + ref->areaPrev = area->entityRefs.areaPrev; + ref->areaNext->areaPrev = ref; + ref->areaPrev->areaNext = ref; +} + +/* +=================== +AddLightRefToArea + +=================== +*/ +void idRenderWorldLocal::AddLightRefToArea( idRenderLightLocal *light, portalArea_t *area ) { + areaReference_t *lref; + + // add a lightref to this area + lref = areaReferenceAllocator.Alloc(); + lref->light = light; + lref->area = area; + lref->ownerNext = light->references; + light->references = lref; + tr.pc.c_lightReferences++; + + // doubly linked list so we can free them easily later + area->lightRefs.areaNext->areaPrev = lref; + lref->areaNext = area->lightRefs.areaNext; + lref->areaPrev = &area->lightRefs; + area->lightRefs.areaNext = lref; +} + +/* +=================== +GenerateAllInteractions + +Force the generation of all light / surface interactions at the start of a level +If this isn't called, they will all be dynamically generated + +This really isn't all that helpful anymore, because the calculation of shadows +and light interactions is deferred from idRenderWorldLocal::CreateLightDefInteractions(), but we +use it as an oportunity to size the interactionTable +=================== +*/ +void idRenderWorldLocal::GenerateAllInteractions() { + if ( !glConfig.isInitialized ) { + return; + } + + int start = Sys_Milliseconds(); + + generateAllInteractionsCalled = false; + + // watch how much memory we allocate + tr.staticAllocCount = 0; + + // let idRenderWorldLocal::CreateLightDefInteractions() know that it shouldn't + // try and do any view specific optimizations + tr.viewDef = NULL; + + for ( int i = 0 ; i < this->lightDefs.Num() ; i++ ) { + idRenderLightLocal *ldef = this->lightDefs[i]; + if ( !ldef ) { + continue; + } + this->CreateLightDefInteractions( ldef ); + } + + int end = Sys_Milliseconds(); + int msec = end - start; + + common->Printf( "idRenderWorld::GenerateAllInteractions, msec = %i, staticAllocCount = %i.\n", msec, tr.staticAllocCount ); + + + // build the interaction table + if ( r_useInteractionTable.GetBool() ) { + interactionTableWidth = entityDefs.Num() + 100; + interactionTableHeight = lightDefs.Num() + 100; + int size = interactionTableWidth * interactionTableHeight * sizeof( *interactionTable ); + interactionTable = (idInteraction **)R_ClearedStaticAlloc( size ); + + int count = 0; + for ( int i = 0 ; i < this->lightDefs.Num() ; i++ ) { + idRenderLightLocal *ldef = this->lightDefs[i]; + if ( !ldef ) { + continue; + } + idInteraction *inter; + for ( inter = ldef->firstInteraction; inter != NULL; inter = inter->lightNext ) { + idRenderEntityLocal *edef = inter->entityDef; + int index = ldef->index * interactionTableWidth + edef->index; + + interactionTable[ index ] = inter; + count++; + } + } + + common->Printf( "interactionTable size: %i bytes\n", size ); + common->Printf( "%i interaction take %i bytes\n", count, count * sizeof( idInteraction ) ); + } + + // entities flagged as noDynamicInteractions will no longer make any + generateAllInteractionsCalled = true; +} + +/* +=================== +idRenderWorldLocal::FreeInteractions +=================== +*/ +void idRenderWorldLocal::FreeInteractions() { + int i; + idRenderEntityLocal *def; + + for ( i = 0 ; i < entityDefs.Num(); i++ ) { + def = entityDefs[i]; + if ( !def ) { + continue; + } + // free all the interactions + while ( def->firstInteraction != NULL ) { + def->firstInteraction->UnlinkAndFree(); + } + } +} + +/* +================== +PushVolumeIntoTree + +Used for both light volumes and model volumes. + +This does not clip the points by the planes, so some slop +occurs. + +tr.viewCount should be bumped before calling, allowing it +to prevent double checking areas. + +We might alternatively choose to do this with an area flow. +================== +*/ +void idRenderWorldLocal::PushVolumeIntoTree_r( idRenderEntityLocal *def, idRenderLightLocal *light, const idSphere *sphere, int numPoints, const idVec3 (*points), + int nodeNum ) { + int i; + areaNode_t *node; + bool front, back; + + if ( nodeNum < 0 ) { + portalArea_t *area; + int areaNum = -1 - nodeNum; + + area = &portalAreas[ areaNum ]; + if ( area->viewCount == tr.viewCount ) { + return; // already added a reference here + } + area->viewCount = tr.viewCount; + + if ( def ) { + AddEntityRefToArea( def, area ); + } + if ( light ) { + AddLightRefToArea( light, area ); + } + + return; + } + + node = areaNodes + nodeNum; + + // if we know that all possible children nodes only touch an area + // we have already marked, we can early out + if ( r_useNodeCommonChildren.GetBool() && + node->commonChildrenArea != CHILDREN_HAVE_MULTIPLE_AREAS ) { + // note that we do NOT try to set a reference in this area + // yet, because the test volume may yet wind up being in the + // solid part, which would cause bounds slightly poked into + // a wall to show up in the next room + if ( portalAreas[ node->commonChildrenArea ].viewCount == tr.viewCount ) { + return; + } + } + + // if the bounding sphere is completely on one side, don't + // bother checking the individual points + float sd = node->plane.Distance( sphere->GetOrigin() ); + if ( sd >= sphere->GetRadius() ) { + nodeNum = node->children[0]; + if ( nodeNum ) { // 0 = solid + PushVolumeIntoTree_r( def, light, sphere, numPoints, points, nodeNum ); + } + return; + } + if ( sd <= -sphere->GetRadius() ) { + nodeNum = node->children[1]; + if ( nodeNum ) { // 0 = solid + PushVolumeIntoTree_r( def, light, sphere, numPoints, points, nodeNum ); + } + return; + } + + // exact check all the points against the node plane + front = back = false; +#ifdef MACOS_X //loop unrolling & pre-fetching for performance + const idVec3 norm = node->plane.Normal(); + const float plane3 = node->plane[3]; + float D0, D1, D2, D3; + + for ( i = 0 ; i < numPoints - 4; i+=4 ) { + D0 = points[i+0] * norm + plane3; + D1 = points[i+1] * norm + plane3; + if ( !front && D0 >= 0.0f ) { + front = true; + } else if ( !back && D0 <= 0.0f ) { + back = true; + } + D2 = points[i+1] * norm + plane3; + if ( !front && D1 >= 0.0f ) { + front = true; + } else if ( !back && D1 <= 0.0f ) { + back = true; + } + D3 = points[i+1] * norm + plane3; + if ( !front && D2 >= 0.0f ) { + front = true; + } else if ( !back && D2 <= 0.0f ) { + back = true; + } + + if ( !front && D3 >= 0.0f ) { + front = true; + } else if ( !back && D3 <= 0.0f ) { + back = true; + } + if ( back && front ) { + break; + } + } + if(!(back && front)) { + for (; i < numPoints ; i++ ) { + float d; + d = points[i] * node->plane.Normal() + node->plane[3]; + if ( d >= 0.0f ) { + front = true; + } else if ( d <= 0.0f ) { + back = true; + } + if ( back && front ) { + break; + } + } + } +#else + for ( i = 0 ; i < numPoints ; i++ ) { + float d; + + d = points[i] * node->plane.Normal() + node->plane[3]; + if ( d >= 0.0f ) { + front = true; + } else if ( d <= 0.0f ) { + back = true; + } + if ( back && front ) { + break; + } + } +#endif + if ( front ) { + nodeNum = node->children[0]; + if ( nodeNum ) { // 0 = solid + PushVolumeIntoTree_r( def, light, sphere, numPoints, points, nodeNum ); + } + } + if ( back ) { + nodeNum = node->children[1]; + if ( nodeNum ) { // 0 = solid + PushVolumeIntoTree_r( def, light, sphere, numPoints, points, nodeNum ); + } + } +} + +/* +============== +PushVolumeIntoTree +============== +*/ +void idRenderWorldLocal::PushVolumeIntoTree( idRenderEntityLocal *def, idRenderLightLocal *light, int numPoints, const idVec3 (*points) ) { + int i; + float radSquared, lr; + idVec3 mid, dir; + + if ( areaNodes == NULL ) { + return; + } + + // calculate a bounding sphere for the points + mid.Zero(); + for ( i = 0; i < numPoints; i++ ) { + mid += points[i]; + } + mid *= ( 1.0f / numPoints ); + + radSquared = 0; + + for ( i = 0; i < numPoints; i++ ) { + dir = points[i] - mid; + lr = dir * dir; + if ( lr > radSquared ) { + radSquared = lr; + } + } + + idSphere sphere( mid, sqrt( radSquared ) ); + + PushVolumeIntoTree_r( def, light, &sphere, numPoints, points, 0 ); +} + +//=================================================================== + +/* +==================== +idRenderWorldLocal::DebugClearLines +==================== +*/ +void idRenderWorldLocal::DebugClearLines( int time ) { + RB_ClearDebugLines( time ); + RB_ClearDebugText( time ); +} + +/* +==================== +idRenderWorldLocal::DebugLine +==================== +*/ +void idRenderWorldLocal::DebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime, const bool depthTest ) { + RB_AddDebugLine( color, start, end, lifetime, depthTest ); +} + +/* +================ +idRenderWorldLocal::DebugArrow +================ +*/ +void idRenderWorldLocal::DebugArrow( const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime ) { + idVec3 forward, right, up, v1, v2; + float a, s; + int i; + static float arrowCos[40]; + static float arrowSin[40]; + static int arrowStep; + + DebugLine( color, start, end, lifetime ); + + if ( r_debugArrowStep.GetInteger() <= 10 ) { + return; + } + // calculate sine and cosine when step size changes + if ( arrowStep != r_debugArrowStep.GetInteger() ) { + arrowStep = r_debugArrowStep.GetInteger(); + for (i = 0, a = 0; a < 360.0f; a += arrowStep, i++) { + arrowCos[i] = idMath::Cos16( DEG2RAD( a ) ); + arrowSin[i] = idMath::Sin16( DEG2RAD( a ) ); + } + arrowCos[i] = arrowCos[0]; + arrowSin[i] = arrowSin[0]; + } + // draw a nice arrow + forward = end - start; + forward.Normalize(); + forward.NormalVectors( right, up); + for (i = 0, a = 0; a < 360.0f; a += arrowStep, i++) { + s = 0.5f * size * arrowCos[i]; + v1 = end - size * forward; + v1 = v1 + s * right; + s = 0.5f * size * arrowSin[i]; + v1 = v1 + s * up; + + s = 0.5f * size * arrowCos[i+1]; + v2 = end - size * forward; + v2 = v2 + s * right; + s = 0.5f * size * arrowSin[i+1]; + v2 = v2 + s * up; + + DebugLine( color, v1, end, lifetime ); + DebugLine( color, v1, v2, lifetime ); + } +} + +/* +==================== +idRenderWorldLocal::DebugWinding +==================== +*/ +void idRenderWorldLocal::DebugWinding( const idVec4 &color, const idWinding &w, const idVec3 &origin, const idMat3 &axis, const int lifetime, const bool depthTest ) { + int i; + idVec3 point, lastPoint; + + if ( w.GetNumPoints() < 2 ) { + return; + } + + lastPoint = origin + w[w.GetNumPoints()-1].ToVec3() * axis; + for ( i = 0; i < w.GetNumPoints(); i++ ) { + point = origin + w[i].ToVec3() * axis; + DebugLine( color, lastPoint, point, lifetime, depthTest ); + lastPoint = point; + } +} + +/* +==================== +idRenderWorldLocal::DebugCircle +==================== +*/ +void idRenderWorldLocal::DebugCircle( const idVec4 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const int lifetime, const bool depthTest ) { + int i; + float a; + idVec3 left, up, point, lastPoint; + + dir.OrthogonalBasis( left, up ); + left *= radius; + up *= radius; + lastPoint = origin + up; + for ( i = 1; i <= numSteps; i++ ) { + a = idMath::TWO_PI * i / numSteps; + point = origin + idMath::Sin16( a ) * left + idMath::Cos16( a ) * up; + DebugLine( color, lastPoint, point, lifetime, depthTest ); + lastPoint = point; + } +} + +/* +============ +idRenderWorldLocal::DebugSphere +============ +*/ +void idRenderWorldLocal::DebugSphere( const idVec4 &color, const idSphere &sphere, const int lifetime, const bool depthTest /*_D3XP*/ ) { + int i, j, n, num; + float s, c; + idVec3 p, lastp, *lastArray; + + num = 360 / 15; + lastArray = (idVec3 *) _alloca16( num * sizeof( idVec3 ) ); + lastArray[0] = sphere.GetOrigin() + idVec3( 0, 0, sphere.GetRadius() ); + for ( n = 1; n < num; n++ ) { + lastArray[n] = lastArray[0]; + } + + for ( i = 15; i <= 360; i += 15 ) { + s = idMath::Sin16( DEG2RAD(i) ); + c = idMath::Cos16( DEG2RAD(i) ); + lastp[0] = sphere.GetOrigin()[0]; + lastp[1] = sphere.GetOrigin()[1] + sphere.GetRadius() * s; + lastp[2] = sphere.GetOrigin()[2] + sphere.GetRadius() * c; + for ( n = 0, j = 15; j <= 360; j += 15, n++ ) { + p[0] = sphere.GetOrigin()[0] + idMath::Sin16( DEG2RAD(j) ) * sphere.GetRadius() * s; + p[1] = sphere.GetOrigin()[1] + idMath::Cos16( DEG2RAD(j) ) * sphere.GetRadius() * s; + p[2] = lastp[2]; + + DebugLine( color, lastp, p, lifetime,depthTest ); + DebugLine( color, lastp, lastArray[n], lifetime, depthTest ); + + lastArray[n] = lastp; + lastp = p; + } + } +} + +/* +==================== +idRenderWorldLocal::DebugBounds +==================== +*/ +void idRenderWorldLocal::DebugBounds( const idVec4 &color, const idBounds &bounds, const idVec3 &org, const int lifetime ) { + int i; + idVec3 v[8]; + + if ( bounds.IsCleared() ) { + return; + } + + for ( i = 0; i < 8; i++ ) { + v[i][0] = org[0] + bounds[(i^(i>>1))&1][0]; + v[i][1] = org[1] + bounds[(i>>1)&1][1]; + v[i][2] = org[2] + bounds[(i>>2)&1][2]; + } + for ( i = 0; i < 4; i++ ) { + DebugLine( color, v[i], v[(i+1)&3], lifetime ); + DebugLine( color, v[4+i], v[4+((i+1)&3)], lifetime ); + DebugLine( color, v[i], v[4+i], lifetime ); + } +} + +/* +==================== +idRenderWorldLocal::DebugBox +==================== +*/ +void idRenderWorldLocal::DebugBox( const idVec4 &color, const idBox &box, const int lifetime ) { + int i; + idVec3 v[8]; + + box.ToPoints( v ); + for ( i = 0; i < 4; i++ ) { + DebugLine( color, v[i], v[(i+1)&3], lifetime ); + DebugLine( color, v[4+i], v[4+((i+1)&3)], lifetime ); + DebugLine( color, v[i], v[4+i], lifetime ); + } +} + +/* +================ +idRenderWorldLocal::DebugFrustum +================ +*/ +void idRenderWorldLocal::DebugFrustum( const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin, const int lifetime ) { + int i; + idVec3 v[8]; + + frustum.ToPoints( v ); + + if ( frustum.GetNearDistance() > 0.0f ) { + for ( i = 0; i < 4; i++ ) { + DebugLine( color, v[i], v[(i+1)&3], lifetime ); + } + if ( showFromOrigin ) { + for ( i = 0; i < 4; i++ ) { + DebugLine( color, frustum.GetOrigin(), v[i], lifetime ); + } + } + } + for ( i = 0; i < 4; i++ ) { + DebugLine( color, v[4+i], v[4+((i+1)&3)], lifetime ); + DebugLine( color, v[i], v[4+i], lifetime ); + } +} + +/* +============ +idRenderWorldLocal::DebugCone + + dir is the cone axis + radius1 is the radius at the apex + radius2 is the radius at apex+dir +============ +*/ +void idRenderWorldLocal::DebugCone( const idVec4 &color, const idVec3 &apex, const idVec3 &dir, float radius1, float radius2, const int lifetime ) { + int i; + idMat3 axis; + idVec3 top, p1, p2, lastp1, lastp2, d; + + axis[2] = dir; + axis[2].Normalize(); + axis[2].NormalVectors( axis[0], axis[1] ); + axis[1] = -axis[1]; + + top = apex + dir; + lastp2 = top + radius2 * axis[1]; + + if ( radius1 == 0.0f ) { + for ( i = 20; i <= 360; i += 20 ) { + d = idMath::Sin16( DEG2RAD(i) ) * axis[0] + idMath::Cos16( DEG2RAD(i) ) * axis[1]; + p2 = top + d * radius2; + DebugLine( color, lastp2, p2, lifetime ); + DebugLine( color, p2, apex, lifetime ); + lastp2 = p2; + } + } else { + lastp1 = apex + radius1 * axis[1]; + for ( i = 20; i <= 360; i += 20 ) { + d = idMath::Sin16( DEG2RAD(i) ) * axis[0] + idMath::Cos16( DEG2RAD(i) ) * axis[1]; + p1 = apex + d * radius1; + p2 = top + d * radius2; + DebugLine( color, lastp1, p1, lifetime ); + DebugLine( color, lastp2, p2, lifetime ); + DebugLine( color, p1, p2, lifetime ); + lastp1 = p1; + lastp2 = p2; + } + } +} + +/* +================ +idRenderWorldLocal::DebugAxis +================ +*/ +void idRenderWorldLocal::DebugAxis( const idVec3 &origin, const idMat3 &axis ) { + idVec3 start = origin; + idVec3 end = start + axis[0] * 20.0f; + DebugArrow( colorWhite, start, end, 2 ); + end = start + axis[0] * -20.0f; + DebugArrow( colorWhite, start, end, 2 ); + end = start + axis[1] * +20.0f; + DebugArrow( colorGreen, start, end, 2 ); + end = start + axis[1] * -20.0f; + DebugArrow( colorGreen, start, end, 2 ); + end = start + axis[2] * +20.0f; + DebugArrow( colorBlue, start, end, 2 ); + end = start + axis[2] * -20.0f; + DebugArrow( colorBlue, start, end, 2 ); +} + +/* +==================== +idRenderWorldLocal::DebugClearPolygons +==================== +*/ +void idRenderWorldLocal::DebugClearPolygons( int time ) { + RB_ClearDebugPolygons( time ); +} + +/* +==================== +idRenderWorldLocal::DebugPolygon +==================== +*/ +void idRenderWorldLocal::DebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ) { + RB_AddDebugPolygon( color, winding, lifeTime, depthTest ); +} + +/* +================ +idRenderWorldLocal::DebugScreenRect +================ +*/ +void idRenderWorldLocal::DebugScreenRect( const idVec4 &color, const idScreenRect &rect, const viewDef_t *viewDef, const int lifetime ) { + int i; + float centerx, centery, dScale, hScale, vScale; + idBounds bounds; + idVec3 p[4]; + + centerx = ( viewDef->viewport.x2 - viewDef->viewport.x1 ) * 0.5f; + centery = ( viewDef->viewport.y2 - viewDef->viewport.y1 ) * 0.5f; + + dScale = r_znear.GetFloat() + 1.0f; + hScale = dScale * idMath::Tan16( DEG2RAD( viewDef->renderView.fov_x * 0.5f ) ); + vScale = dScale * idMath::Tan16( DEG2RAD( viewDef->renderView.fov_y * 0.5f ) ); + + bounds[0][0] = bounds[1][0] = dScale; + bounds[0][1] = -( rect.x1 - centerx ) / centerx * hScale; + bounds[1][1] = -( rect.x2 - centerx ) / centerx * hScale; + bounds[0][2] = ( rect.y1 - centery ) / centery * vScale; + bounds[1][2] = ( rect.y2 - centery ) / centery * vScale; + + for ( i = 0; i < 4; i++ ) { + p[i].x = bounds[0][0]; + p[i].y = bounds[(i^(i>>1))&1].y; + p[i].z = bounds[(i>>1)&1].z; + p[i] = viewDef->renderView.vieworg + p[i] * viewDef->renderView.viewaxis; + } + for ( i = 0; i < 4; i++ ) { + DebugLine( color, p[i], p[(i+1)&3], false ); + } +} + +/* +================ +idRenderWorldLocal::DrawTextLength + + returns the length of the given text +================ +*/ +float idRenderWorldLocal::DrawTextLength( const char *text, float scale, int len ) { + return RB_DrawTextLength( text, scale, len ); +} + +/* +================ +idRenderWorldLocal::DrawText + + oriented on the viewaxis + align can be 0-left, 1-center (default), 2-right +================ +*/ +void idRenderWorldLocal::DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ) { + RB_AddDebugText( text, origin, scale, color, viewAxis, align, lifetime, depthTest ); +} + +/* +=============== +idRenderWorldLocal::RegenerateWorld +=============== +*/ +void idRenderWorldLocal::RegenerateWorld() { + R_RegenerateWorld_f( idCmdArgs() ); +} + +/* +=============== +R_GlobalShaderOverride +=============== +*/ +bool R_GlobalShaderOverride( const idMaterial **shader ) { + + if ( !(*shader)->IsDrawn() ) { + return false; + } + + if ( tr.primaryRenderView.globalMaterial ) { + *shader = tr.primaryRenderView.globalMaterial; + return true; + } + + if ( r_materialOverride.GetString()[0] != '\0' ) { + *shader = declManager->FindMaterial( r_materialOverride.GetString() ); + return true; + } + + return false; +} + +/* +=============== +R_RemapShaderBySkin +=============== +*/ +const idMaterial *R_RemapShaderBySkin( const idMaterial *shader, const idDeclSkin *skin, const idMaterial *customShader ) { + + if ( !shader ) { + return NULL; + } + + // never remap surfaces that were originally nodraw, like collision hulls + if ( !shader->IsDrawn() ) { + return shader; + } + + if ( customShader ) { + // this is sort of a hack, but cause deformed surfaces to map to empty surfaces, + // so the item highlight overlay doesn't highlight the autosprite surface + if ( shader->Deform() ) { + return NULL; + } + return const_cast(customShader); + } + + if ( !skin || !shader ) { + return const_cast(shader); + } + + return skin->RemapShaderBySkin( shader ); +} diff --git a/renderer/RenderWorld.h b/renderer/RenderWorld.h new file mode 100644 index 000000000..a7ee30373 --- /dev/null +++ b/renderer/RenderWorld.h @@ -0,0 +1,415 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __RENDERWORLD_H__ +#define __RENDERWORLD_H__ + +/* +=============================================================================== + + Render World + +=============================================================================== +*/ + +#define PROC_FILE_EXT "proc" +#define PROC_FILE_ID "mapProcFile003" + +// shader parms +const int MAX_GLOBAL_SHADER_PARMS = 12; + +const int SHADERPARM_RED = 0; +const int SHADERPARM_GREEN = 1; +const int SHADERPARM_BLUE = 2; +const int SHADERPARM_ALPHA = 3; +const int SHADERPARM_TIMESCALE = 3; +const int SHADERPARM_TIMEOFFSET = 4; +const int SHADERPARM_DIVERSITY = 5; // random between 0.0 and 1.0 for some effects (muzzle flashes, etc) +const int SHADERPARM_MODE = 7; // for selecting which shader passes to enable +const int SHADERPARM_TIME_OF_DEATH = 7; // for the monster skin-burn-away effect enable and time offset + +// model parms +const int SHADERPARM_MD5_SKINSCALE = 8; // for scaling vertex offsets on md5 models (jack skellington effect) + +const int SHADERPARM_MD3_FRAME = 8; +const int SHADERPARM_MD3_LASTFRAME = 9; +const int SHADERPARM_MD3_BACKLERP = 10; + +const int SHADERPARM_BEAM_END_X = 8; // for _beam models +const int SHADERPARM_BEAM_END_Y = 9; +const int SHADERPARM_BEAM_END_Z = 10; +const int SHADERPARM_BEAM_WIDTH = 11; + +const int SHADERPARM_SPRITE_WIDTH = 8; +const int SHADERPARM_SPRITE_HEIGHT = 9; + +const int SHADERPARM_PARTICLE_STOPTIME = 8; // don't spawn any more particles after this time + +// guis +const int MAX_RENDERENTITY_GUI = 3; + + +typedef bool(*deferredEntityCallback_t)( renderEntity_s *, const renderView_s * ); + + +typedef struct renderEntity_s { + idRenderModel * hModel; // this can only be null if callback is set + + int entityNum; + int bodyId; + + // Entities that are expensive to generate, like skeletal models, can be + // deferred until their bounds are found to be in view, in the frustum + // of a shadowing light that is in view, or contacted by a trace / overlay test. + // This is also used to do visual cueing on items in the view + // The renderView may be NULL if the callback is being issued for a non-view related + // source. + // The callback function should clear renderEntity->callback if it doesn't + // want to be called again next time the entity is referenced (ie, if the + // callback has now made the entity valid until the next updateEntity) + idBounds bounds; // only needs to be set for deferred models and md5s + deferredEntityCallback_t callback; + + void * callbackData; // used for whatever the callback wants + + // player bodies and possibly player shadows should be suppressed in views from + // that player's eyes, but will show up in mirrors and other subviews + // security cameras could suppress their model in their subviews if we add a way + // of specifying a view number for a remoteRenderMap view + int suppressSurfaceInViewID; + int suppressShadowInViewID; + + // world models for the player and weapons will not cast shadows from view weapon + // muzzle flashes + int suppressShadowInLightID; + + // if non-zero, the surface and shadow (if it casts one) + // will only show up in the specific view, ie: player weapons + int allowSurfaceInViewID; + + // positioning + // axis rotation vectors must be unit length for many + // R_LocalToGlobal functions to work, so don't scale models! + // axis vectors are [0] = forward, [1] = left, [2] = up + idVec3 origin; + idMat3 axis; + + // texturing + const idMaterial * customShader; // if non-0, all surfaces will use this + const idMaterial * referenceShader; // used so flares can reference the proper light shader + const idDeclSkin * customSkin; // 0 for no remappings + class idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds + float shaderParms[ MAX_ENTITY_SHADER_PARMS ]; // can be used in any way by shader or model generation + + // networking: see WriteGUIToSnapshot / ReadGUIFromSnapshot + class idUserInterface * gui[ MAX_RENDERENTITY_GUI ]; + + struct renderView_s * remoteRenderView; // any remote camera surfaces will use this + + int numJoints; + idJointMat * joints; // array of joints that will modify vertices. + // NULL if non-deformable model. NOT freed by renderer + + float modelDepthHack; // squash depth range so particle effects don't clip into walls + + // options to override surface shader flags (replace with material parameters?) + bool noSelfShadow; // cast shadows onto other objects,but not self + bool noShadow; // no shadow at all + + bool noDynamicInteractions; // don't create any light / shadow interactions after + // the level load is completed. This is a performance hack + // for the gigantic outdoor meshes in the monorail map, so + // all the lights in the moving monorail don't touch the meshes + + bool weaponDepthHack; // squash depth range so view weapons don't poke into walls + // this automatically implies noShadow + int forceUpdate; // force an update (NOTE: not a bool to keep this struct a multiple of 4 bytes) + int timeGroup; + int xrayIndex; +} renderEntity_t; + + +typedef struct renderLight_s { + idMat3 axis; // rotation vectors, must be unit length + idVec3 origin; + + // if non-zero, the light will not show up in the specific view, + // which may be used if we want to have slightly different muzzle + // flash lights for the player and other views + int suppressLightInViewID; + + // if non-zero, the light will only show up in the specific view + // which can allow player gun gui lights and such to not effect everyone + int allowLightInViewID; + + // I am sticking the four bools together so there are no unused gaps in + // the padded structure, which could confuse the memcmp that checks for redundant + // updates + bool noShadows; // (should we replace this with material parameters on the shader?) + bool noSpecular; // (should we replace this with material parameters on the shader?) + + bool pointLight; // otherwise a projection light (should probably invert the sense of this, because points are way more common) + bool parallel; // lightCenter gives the direction to the light at infinity + idVec3 lightRadius; // xyz radius for point lights + idVec3 lightCenter; // offset the lighting direction for shading and + // shadows, relative to origin + + // frustum definition for projected lights, all reletive to origin + // FIXME: we should probably have real plane equations here, and offer + // a helper function for conversion from this format + idVec3 target; + idVec3 right; + idVec3 up; + idVec3 start; + idVec3 end; + + // Dmap will generate an optimized shadow volume named _prelight_ + // for the light against all the _area* models in the map. The renderer will + // ignore this value if the light has been moved after initial creation + idRenderModel * prelightModel; + + // muzzle flash lights will not cast shadows from player and weapon world models + int lightId; + + + const idMaterial * shader; // NULL = either lights/defaultPointLight or lights/defaultProjectedLight + float shaderParms[MAX_ENTITY_SHADER_PARMS]; // can be used in any way by shader + idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds +} renderLight_t; + + +typedef struct renderView_s { + // player views will set this to a non-zero integer for model suppress / allow + // subviews (mirrors, cameras, etc) will always clear it to zero + int viewID; + + // sized from 0 to SCREEN_WIDTH / SCREEN_HEIGHT (640/480), not actual resolution + int x, y, width, height; + + float fov_x, fov_y; + idVec3 vieworg; + idMat3 viewaxis; // transformation matrix, view looks down the positive X axis + + bool cramZNear; // for cinematics, we want to set ZNear much lower + bool forceUpdate; // for an update + + // time in milliseconds for shader effects and other time dependent rendering issues + int time; + float shaderParms[MAX_GLOBAL_SHADER_PARMS]; // can be used in any way by shader + const idMaterial *globalMaterial; // used to override everything draw +} renderView_t; + + +// exitPortal_t is returned by idRenderWorld::GetPortal() +typedef struct { + int areas[2]; // areas connected by this portal + const idWinding * w; // winding points have counter clockwise ordering seen from areas[0] + int blockingBits; // PS_BLOCK_VIEW, PS_BLOCK_AIR, etc + qhandle_t portalHandle; +} exitPortal_t; + + +// guiPoint_t is returned by idRenderWorld::GuiTrace() +typedef struct { + float x, y; // 0.0 to 1.0 range if trace hit a gui, otherwise -1 + int guiId; // id of gui ( 0, 1, or 2 ) that the trace happened against +} guiPoint_t; + + +// modelTrace_t is for tracing vs. visual geometry +typedef struct modelTrace_s { + float fraction; // fraction of trace completed + idVec3 point; // end point of trace in global space + idVec3 normal; // hit triangle normal vector in global space + const idMaterial * material; // material of hit surface + const renderEntity_t * entity; // render entity that was hit + int jointNumber; // md5 joint nearest to the hit triangle +} modelTrace_t; + + +static const int NUM_PORTAL_ATTRIBUTES = 3; + +typedef enum { + PS_BLOCK_NONE = 0, + + PS_BLOCK_VIEW = 1, + PS_BLOCK_LOCATION = 2, // game map location strings often stop in hallways + PS_BLOCK_AIR = 4, // windows between pressurized and unpresurized areas + + PS_BLOCK_ALL = (1<archived = false; + } + } + for ( i = 0 ; i < entityDefs.Num() ; i++ ) { + if ( entityDefs[i] ) { + entityDefs[i]->archived = false; + } + } +} + +void idRenderWorldLocal::StopWritingDemo() { +// writeDemo = NULL; +} + +/* +============== +ProcessDemoCommand +============== +*/ +bool idRenderWorldLocal::ProcessDemoCommand( idDemoFile *readDemo, renderView_t *renderView, int *demoTimeOffset ) { + bool newMap = false; + + if ( !readDemo ) { + return false; + } + + demoCommand_t dc; + qhandle_t h; + + if ( !readDemo->ReadInt( (int&)dc ) ) { + // a demoShot may not have an endFrame, but it is still valid + return false; + } + + switch( dc ) { + case DC_LOADMAP: + // read the initial data + demoHeader_t header; + + readDemo->ReadInt( header.version ); + readDemo->ReadInt( header.sizeofRenderEntity ); + readDemo->ReadInt( header.sizeofRenderLight ); + for ( int i = 0; i < 256; i++ ) + readDemo->ReadChar( header.mapname[i] ); + // the internal version value got replaced by DS_VERSION at toplevel + if ( header.version != 4 ) { + common->Error( "Demo version mismatch.\n" ); + } + + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_LOADMAP: %s\n", header.mapname ); + } + InitFromMap( header.mapname ); + + newMap = true; // we will need to set demoTimeOffset + + break; + + case DC_RENDERVIEW: + readDemo->ReadInt( renderView->viewID ); + readDemo->ReadInt( renderView->x ); + readDemo->ReadInt( renderView->y ); + readDemo->ReadInt( renderView->width ); + readDemo->ReadInt( renderView->height ); + readDemo->ReadFloat( renderView->fov_x ); + readDemo->ReadFloat( renderView->fov_y ); + readDemo->ReadVec3( renderView->vieworg ); + readDemo->ReadMat3( renderView->viewaxis ); + readDemo->ReadBool( renderView->cramZNear ); + readDemo->ReadBool( renderView->forceUpdate ); + // binary compatibility with win32 padded structures + char tmp; + readDemo->ReadChar( tmp ); + readDemo->ReadChar( tmp ); + readDemo->ReadInt( renderView->time ); + for ( int i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) + readDemo->ReadFloat( renderView->shaderParms[i] ); + + if ( !readDemo->ReadInt( (int&)renderView->globalMaterial ) ) { + return false; + } + + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_RENDERVIEW: %i\n", renderView->time ); + } + + // possibly change the time offset if this is from a new map + if ( newMap && demoTimeOffset ) { + *demoTimeOffset = renderView->time - eventLoop->Milliseconds(); + } + return false; + + case DC_UPDATE_ENTITYDEF: + ReadRenderEntity(); + break; + case DC_DELETE_ENTITYDEF: + if ( !readDemo->ReadInt( h ) ) { + return false; + } + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_DELETE_ENTITYDEF: %i\n", h ); + } + FreeEntityDef( h ); + break; + case DC_UPDATE_LIGHTDEF: + ReadRenderLight(); + break; + case DC_DELETE_LIGHTDEF: + if ( !readDemo->ReadInt( h ) ) { + return false; + } + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_DELETE_LIGHTDEF: %i\n", h ); + } + FreeLightDef( h ); + break; + + case DC_CAPTURE_RENDER: + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_CAPTURE_RENDER\n" ); + } + renderSystem->CaptureRenderToImage( readDemo->ReadHashString() ); + break; + + case DC_CROP_RENDER: + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_CROP_RENDER\n" ); + } + int size[3]; + readDemo->ReadInt( size[0] ); + readDemo->ReadInt( size[1] ); + readDemo->ReadInt( size[2] ); + renderSystem->CropRenderSize( size[0], size[1], size[2] != 0 ); + break; + + case DC_UNCROP_RENDER: + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_UNCROP\n" ); + } + renderSystem->UnCrop(); + break; + + case DC_GUI_MODEL: + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_GUI_MODEL\n" ); + } + tr.demoGuiModel->ReadFromDemo( readDemo ); + break; + + case DC_DEFINE_MODEL: + { + idRenderModel *model = renderModelManager->AllocModel(); + model->ReadFromDemoFile( session->readDemo ); + // add to model manager, so we can find it + renderModelManager->AddModel( model ); + + // save it in the list to free when clearing this map + localModels.Append( model ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_DEFINE_MODEL\n" ); + } + break; + } + case DC_SET_PORTAL_STATE: + { + int data[2]; + readDemo->ReadInt( data[0] ); + readDemo->ReadInt( data[1] ); + SetPortalState( data[0], data[1] ); + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_SET_PORTAL_STATE: %i %i\n", data[0], data[1] ); + } + } + + break; + case DC_END_FRAME: + return true; + + default: + common->Error( "Bad token in demo stream" ); + } + + return false; +} + +/* +================ +WriteLoadMap +================ +*/ +void idRenderWorldLocal::WriteLoadMap() { + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_LOADMAP ); + + demoHeader_t header; + strncpy( header.mapname, mapName.c_str(), sizeof( header.mapname ) - 1 ); + header.version = 4; + header.sizeofRenderEntity = sizeof( renderEntity_t ); + header.sizeofRenderLight = sizeof( renderLight_t ); + session->writeDemo->WriteInt( header.version ); + session->writeDemo->WriteInt( header.sizeofRenderEntity ); + session->writeDemo->WriteInt( header.sizeofRenderLight ); + for ( int i = 0; i < 256; i++ ) + session->writeDemo->WriteChar( header.mapname[i] ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_DELETE_LIGHTDEF: %s\n", mapName.c_str() ); + } +} + +/* +================ +WriteVisibleDefs + +================ +*/ +void idRenderWorldLocal::WriteVisibleDefs( const viewDef_t *viewDef ) { + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + // make sure all necessary entities and lights are updated + for ( viewEntity_t *viewEnt = viewDef->viewEntitys ; viewEnt ; viewEnt = viewEnt->next ) { + idRenderEntityLocal *ent = viewEnt->entityDef; + + if ( ent->archived ) { + // still up to date + continue; + } + + // write it out + WriteRenderEntity( ent->index, &ent->parms ); + ent->archived = true; + } + + for ( viewLight_t *viewLight = viewDef->viewLights ; viewLight ; viewLight = viewLight->next ) { + idRenderLightLocal *light = viewLight->lightDef; + + if ( light->archived ) { + // still up to date + continue; + } + // write it out + WriteRenderLight( light->index, &light->parms ); + light->archived = true; + } +} + + +/* +================ +WriteRenderView +================ +*/ +void idRenderWorldLocal::WriteRenderView( const renderView_t *renderView ) { + int i; + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + // write the actual view command + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_RENDERVIEW ); + session->writeDemo->WriteInt( renderView->viewID ); + session->writeDemo->WriteInt( renderView->x ); + session->writeDemo->WriteInt( renderView->y ); + session->writeDemo->WriteInt( renderView->width ); + session->writeDemo->WriteInt( renderView->height ); + session->writeDemo->WriteFloat( renderView->fov_x ); + session->writeDemo->WriteFloat( renderView->fov_y ); + session->writeDemo->WriteVec3( renderView->vieworg ); + session->writeDemo->WriteMat3( renderView->viewaxis ); + session->writeDemo->WriteBool( renderView->cramZNear ); + session->writeDemo->WriteBool( renderView->forceUpdate ); + // binary compatibility with old win32 version writing padded structures directly to disk + session->writeDemo->WriteUnsignedChar( 0 ); + session->writeDemo->WriteUnsignedChar( 0 ); + session->writeDemo->WriteInt( renderView->time ); + for ( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) + session->writeDemo->WriteFloat( renderView->shaderParms[i] ); + session->writeDemo->WriteInt( (int&)renderView->globalMaterial ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_RENDERVIEW: %i\n", renderView->time ); + } +} + +/* +================ +WriteFreeEntity +================ +*/ +void idRenderWorldLocal::WriteFreeEntity( qhandle_t handle ) { + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_DELETE_ENTITYDEF ); + session->writeDemo->WriteInt( handle ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_DELETE_ENTITYDEF: %i\n", handle ); + } +} + +/* +================ +WriteFreeLightEntity +================ +*/ +void idRenderWorldLocal::WriteFreeLight( qhandle_t handle ) { + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_DELETE_LIGHTDEF ); + session->writeDemo->WriteInt( handle ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_DELETE_LIGHTDEF: %i\n", handle ); + } +} + +/* +================ +WriteRenderLight +================ +*/ +void idRenderWorldLocal::WriteRenderLight( qhandle_t handle, const renderLight_t *light ) { + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_UPDATE_LIGHTDEF ); + session->writeDemo->WriteInt( handle ); + + session->writeDemo->WriteMat3( light->axis ); + session->writeDemo->WriteVec3( light->origin ); + session->writeDemo->WriteInt( light->suppressLightInViewID ); + session->writeDemo->WriteInt( light->allowLightInViewID ); + session->writeDemo->WriteBool( light->noShadows ); + session->writeDemo->WriteBool( light->noSpecular ); + session->writeDemo->WriteBool( light->pointLight ); + session->writeDemo->WriteBool( light->parallel ); + session->writeDemo->WriteVec3( light->lightRadius ); + session->writeDemo->WriteVec3( light->lightCenter ); + session->writeDemo->WriteVec3( light->target ); + session->writeDemo->WriteVec3( light->right ); + session->writeDemo->WriteVec3( light->up ); + session->writeDemo->WriteVec3( light->start ); + session->writeDemo->WriteVec3( light->end ); + session->writeDemo->WriteInt( (int&)light->prelightModel ); + session->writeDemo->WriteInt( light->lightId ); + session->writeDemo->WriteInt( (int&)light->shader ); + for ( int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++) + session->writeDemo->WriteFloat( light->shaderParms[i] ); + session->writeDemo->WriteInt( (int&)light->referenceSound ); + + if ( light->prelightModel ) { + session->writeDemo->WriteHashString( light->prelightModel->Name() ); + } + if ( light->shader ) { + session->writeDemo->WriteHashString( light->shader->GetName() ); + } + if ( light->referenceSound ) { + int index = light->referenceSound->Index(); + session->writeDemo->WriteInt( index ); + } + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_UPDATE_LIGHTDEF: %i\n", handle ); + } +} + +/* +================ +ReadRenderLight +================ +*/ +void idRenderWorldLocal::ReadRenderLight( ) { + renderLight_t light; + int index; + + session->readDemo->ReadInt( index ); + if ( index < 0 ) { + common->Error( "ReadRenderLight: index < 0 " ); + } + + session->readDemo->ReadMat3( light.axis ); + session->readDemo->ReadVec3( light.origin ); + session->readDemo->ReadInt( light.suppressLightInViewID ); + session->readDemo->ReadInt( light.allowLightInViewID ); + session->readDemo->ReadBool( light.noShadows ); + session->readDemo->ReadBool( light.noSpecular ); + session->readDemo->ReadBool( light.pointLight ); + session->readDemo->ReadBool( light.parallel ); + session->readDemo->ReadVec3( light.lightRadius ); + session->readDemo->ReadVec3( light.lightCenter ); + session->readDemo->ReadVec3( light.target ); + session->readDemo->ReadVec3( light.right ); + session->readDemo->ReadVec3( light.up ); + session->readDemo->ReadVec3( light.start ); + session->readDemo->ReadVec3( light.end ); + session->readDemo->ReadInt( (int&)light.prelightModel ); + session->readDemo->ReadInt( light.lightId ); + session->readDemo->ReadInt( (int&)light.shader ); + for ( int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++) + session->readDemo->ReadFloat( light.shaderParms[i] ); + session->readDemo->ReadInt( (int&)light.referenceSound ); + if ( light.prelightModel ) { + light.prelightModel = renderModelManager->FindModel( session->readDemo->ReadHashString() ); + } + if ( light.shader ) { + light.shader = declManager->FindMaterial( session->readDemo->ReadHashString() ); + } + if ( light.referenceSound ) { + int index; + session->readDemo->ReadInt( index ); + light.referenceSound = session->sw->EmitterForIndex( index ); + } + + UpdateLightDef( index, &light ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_UPDATE_LIGHTDEF: %i\n", index ); + } +} + +/* +================ +WriteRenderEntity +================ +*/ +void idRenderWorldLocal::WriteRenderEntity( qhandle_t handle, const renderEntity_t *ent ) { + + // only the main renderWorld writes stuff to demos, not the wipes or + // menu renders + if ( this != session->rw ) { + return; + } + + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_UPDATE_ENTITYDEF ); + session->writeDemo->WriteInt( handle ); + + session->writeDemo->WriteInt( (int&)ent->hModel ); + session->writeDemo->WriteInt( ent->entityNum ); + session->writeDemo->WriteInt( ent->bodyId ); + session->writeDemo->WriteVec3( ent->bounds[0] ); + session->writeDemo->WriteVec3( ent->bounds[1] ); + session->writeDemo->WriteInt( (int&)ent->callback ); + session->writeDemo->WriteInt( (int&)ent->callbackData ); + session->writeDemo->WriteInt( ent->suppressSurfaceInViewID ); + session->writeDemo->WriteInt( ent->suppressShadowInViewID ); + session->writeDemo->WriteInt( ent->suppressShadowInLightID ); + session->writeDemo->WriteInt( ent->allowSurfaceInViewID ); + session->writeDemo->WriteVec3( ent->origin ); + session->writeDemo->WriteMat3( ent->axis ); + session->writeDemo->WriteInt( (int&)ent->customShader ); + session->writeDemo->WriteInt( (int&)ent->referenceShader ); + session->writeDemo->WriteInt( (int&)ent->customSkin ); + session->writeDemo->WriteInt( (int&)ent->referenceSound ); + for ( int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) + session->writeDemo->WriteFloat( ent->shaderParms[i] ); + for ( int i = 0; i < MAX_RENDERENTITY_GUI; i++ ) + session->writeDemo->WriteInt( (int&)ent->gui[i] ); + session->writeDemo->WriteInt( (int&)ent->remoteRenderView ); + session->writeDemo->WriteInt( ent->numJoints ); + session->writeDemo->WriteInt( (int&)ent->joints ); + session->writeDemo->WriteFloat( ent->modelDepthHack ); + session->writeDemo->WriteBool( ent->noSelfShadow ); + session->writeDemo->WriteBool( ent->noShadow ); + session->writeDemo->WriteBool( ent->noDynamicInteractions ); + session->writeDemo->WriteBool( ent->weaponDepthHack ); + session->writeDemo->WriteInt( ent->forceUpdate ); + + if ( ent->customShader ) { + session->writeDemo->WriteHashString( ent->customShader->GetName() ); + } + if ( ent->customSkin ) { + session->writeDemo->WriteHashString( ent->customSkin->GetName() ); + } + if ( ent->hModel ) { + session->writeDemo->WriteHashString( ent->hModel->Name() ); + } + if ( ent->referenceShader ) { + session->writeDemo->WriteHashString( ent->referenceShader->GetName() ); + } + if ( ent->referenceSound ) { + int index = ent->referenceSound->Index(); + session->writeDemo->WriteInt( index ); + } + if ( ent->numJoints ) { + for ( int i = 0; i < ent->numJoints; i++) { + float *data = ent->joints[i].ToFloatPtr(); + for ( int j = 0; j < 12; ++j) + session->writeDemo->WriteFloat( data[j] ); + } + } + + /* + if ( ent->decals ) { + ent->decals->WriteToDemoFile( session->readDemo ); + } + if ( ent->overlay ) { + ent->overlay->WriteToDemoFile( session->writeDemo ); + } + */ + +#ifdef WRITE_GUIS + if ( ent->gui ) { + ent->gui->WriteToDemoFile( session->writeDemo ); + } + if ( ent->gui2 ) { + ent->gui2->WriteToDemoFile( session->writeDemo ); + } + if ( ent->gui3 ) { + ent->gui3->WriteToDemoFile( session->writeDemo ); + } +#endif + + // RENDERDEMO_VERSION >= 2 ( Doom3 1.2 ) + session->writeDemo->WriteInt( ent->timeGroup ); + session->writeDemo->WriteInt( ent->xrayIndex ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "write DC_UPDATE_ENTITYDEF: %i = %s\n", handle, ent->hModel ? ent->hModel->Name() : "NULL" ); + } +} + +/* +================ +ReadRenderEntity +================ +*/ +void idRenderWorldLocal::ReadRenderEntity() { + renderEntity_t ent; + int index, i; + + session->readDemo->ReadInt( index ); + if ( index < 0 ) { + common->Error( "ReadRenderEntity: index < 0" ); + } + + session->readDemo->ReadInt( (int&)ent.hModel ); + session->readDemo->ReadInt( ent.entityNum ); + session->readDemo->ReadInt( ent.bodyId ); + session->readDemo->ReadVec3( ent.bounds[0] ); + session->readDemo->ReadVec3( ent.bounds[1] ); + session->readDemo->ReadInt( (int&)ent.callback ); + session->readDemo->ReadInt( (int&)ent.callbackData ); + session->readDemo->ReadInt( ent.suppressSurfaceInViewID ); + session->readDemo->ReadInt( ent.suppressShadowInViewID ); + session->readDemo->ReadInt( ent.suppressShadowInLightID ); + session->readDemo->ReadInt( ent.allowSurfaceInViewID ); + session->readDemo->ReadVec3( ent.origin ); + session->readDemo->ReadMat3( ent.axis ); + session->readDemo->ReadInt( (int&)ent.customShader ); + session->readDemo->ReadInt( (int&)ent.referenceShader ); + session->readDemo->ReadInt( (int&)ent.customSkin ); + session->readDemo->ReadInt( (int&)ent.referenceSound ); + for ( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + session->readDemo->ReadFloat( ent.shaderParms[i] ); + } + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + session->readDemo->ReadInt( (int&)ent.gui[i] ); + } + session->readDemo->ReadInt( (int&)ent.remoteRenderView ); + session->readDemo->ReadInt( ent.numJoints ); + session->readDemo->ReadInt( (int&)ent.joints ); + session->readDemo->ReadFloat( ent.modelDepthHack ); + session->readDemo->ReadBool( ent.noSelfShadow ); + session->readDemo->ReadBool( ent.noShadow ); + session->readDemo->ReadBool( ent.noDynamicInteractions ); + session->readDemo->ReadBool( ent.weaponDepthHack ); + session->readDemo->ReadInt( ent.forceUpdate ); + ent.callback = NULL; + if ( ent.customShader ) { + ent.customShader = declManager->FindMaterial( session->readDemo->ReadHashString() ); + } + if ( ent.customSkin ) { + ent.customSkin = declManager->FindSkin( session->readDemo->ReadHashString() ); + } + if ( ent.hModel ) { + ent.hModel = renderModelManager->FindModel( session->readDemo->ReadHashString() ); + } + if ( ent.referenceShader ) { + ent.referenceShader = declManager->FindMaterial( session->readDemo->ReadHashString() ); + } + if ( ent.referenceSound ) { + int index; + session->readDemo->ReadInt( index ); + ent.referenceSound = session->sw->EmitterForIndex( index ); + } + if ( ent.numJoints ) { + ent.joints = (idJointMat *)Mem_Alloc16( ent.numJoints * sizeof( ent.joints[0] ) ); + for ( int i = 0; i < ent.numJoints; i++) { + float *data = ent.joints[i].ToFloatPtr(); + for ( int j = 0; j < 12; ++j) + session->readDemo->ReadFloat( data[j] ); + } + } + + ent.callbackData = NULL; + + /* + if ( ent.decals ) { + ent.decals = idRenderModelDecal::Alloc(); + ent.decals->ReadFromDemoFile( session->readDemo ); + } + if ( ent.overlay ) { + ent.overlay = idRenderModelOverlay::Alloc(); + ent.overlay->ReadFromDemoFile( session->readDemo ); + } + */ + + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + if ( ent.gui[ i ] ) { + ent.gui[ i ] = uiManager->Alloc(); +#ifdef WRITE_GUIS + ent.gui[ i ]->ReadFromDemoFile( session->readDemo ); +#endif + } + } + + // >= Doom3 v1.2 only + if ( session->renderdemoVersion >= 2 ) { + session->readDemo->ReadInt( ent.timeGroup ); + session->readDemo->ReadInt( ent.xrayIndex ); + } else { + ent.timeGroup = 0; + ent.xrayIndex = 0; + } + + UpdateEntityDef( index, &ent ); + + if ( r_showDemo.GetBool() ) { + common->Printf( "DC_UPDATE_ENTITYDEF: %i = %s\n", index, ent.hModel ? ent.hModel->Name() : "NULL" ); + } +} diff --git a/renderer/RenderWorld_load.cpp b/renderer/RenderWorld_load.cpp new file mode 100644 index 000000000..2855da7ce --- /dev/null +++ b/renderer/RenderWorld_load.cpp @@ -0,0 +1,691 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +/* +================ +idRenderWorldLocal::FreeWorld +================ +*/ +void idRenderWorldLocal::FreeWorld() { + int i; + + // this will free all the lightDefs and entityDefs + FreeDefs(); + + // free all the portals and check light/model references + for ( i = 0 ; i < numPortalAreas ; i++ ) { + portalArea_t *area; + portal_t *portal, *nextPortal; + + area = &portalAreas[i]; + for ( portal = area->portals ; portal ; portal = nextPortal ) { + nextPortal = portal->next; + delete portal->w; + R_StaticFree( portal ); + } + + // there shouldn't be any remaining lightRefs or entityRefs + if ( area->lightRefs.areaNext != &area->lightRefs ) { + common->Error( "FreeWorld: unexpected remaining lightRefs" ); + } + if ( area->entityRefs.areaNext != &area->entityRefs ) { + common->Error( "FreeWorld: unexpected remaining entityRefs" ); + } + } + + if ( portalAreas ) { + R_StaticFree( portalAreas ); + portalAreas = NULL; + numPortalAreas = 0; + R_StaticFree( areaScreenRect ); + areaScreenRect = NULL; + } + + if ( doublePortals ) { + R_StaticFree( doublePortals ); + doublePortals = NULL; + numInterAreaPortals = 0; + } + + if ( areaNodes ) { + R_StaticFree( areaNodes ); + areaNodes = NULL; + } + + // free all the inline idRenderModels + for ( i = 0 ; i < localModels.Num() ; i++ ) { + renderModelManager->RemoveModel( localModels[i] ); + delete localModels[i]; + } + localModels.Clear(); + + areaReferenceAllocator.Shutdown(); + interactionAllocator.Shutdown(); + areaNumRefAllocator.Shutdown(); + + mapName = ""; +} + +/* +================ +idRenderWorldLocal::TouchWorldModels +================ +*/ +void idRenderWorldLocal::TouchWorldModels( void ) { + int i; + + for ( i = 0 ; i < localModels.Num() ; i++ ) { + renderModelManager->CheckModel( localModels[i]->Name() ); + } +} + +/* +================ +idRenderWorldLocal::ParseModel +================ +*/ +idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) { + idRenderModel *model; + idToken token; + int i, j; + srfTriangles_t *tri; + modelSurface_t surf; + + src->ExpectTokenString( "{" ); + + // parse the name + src->ExpectAnyToken( &token ); + + model = renderModelManager->AllocModel(); + model->InitEmpty( token ); + + int numSurfaces = src->ParseInt(); + if ( numSurfaces < 0 ) { + src->Error( "R_ParseModel: bad numSurfaces" ); + } + + for ( i = 0 ; i < numSurfaces ; i++ ) { + src->ExpectTokenString( "{" ); + + src->ExpectAnyToken( &token ); + + surf.shader = declManager->FindMaterial( token ); + + ((idMaterial*)surf.shader)->AddReference(); + + tri = R_AllocStaticTriSurf(); + surf.geometry = tri; + + tri->numVerts = src->ParseInt(); + tri->numIndexes = src->ParseInt(); + + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + for ( j = 0 ; j < tri->numVerts ; j++ ) { + float vec[8]; + + src->Parse1DMatrix( 8, vec ); + + tri->verts[j].xyz[0] = vec[0]; + tri->verts[j].xyz[1] = vec[1]; + tri->verts[j].xyz[2] = vec[2]; + tri->verts[j].st[0] = vec[3]; + tri->verts[j].st[1] = vec[4]; + tri->verts[j].normal[0] = vec[5]; + tri->verts[j].normal[1] = vec[6]; + tri->verts[j].normal[2] = vec[7]; + } + + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + tri->indexes[j] = src->ParseInt(); + } + src->ExpectTokenString( "}" ); + + // add the completed surface to the model + model->AddSurface( surf ); + } + + src->ExpectTokenString( "}" ); + + model->FinishSurfaces(); + + return model; +} + +/* +================ +idRenderWorldLocal::ParseShadowModel +================ +*/ +idRenderModel *idRenderWorldLocal::ParseShadowModel( idLexer *src ) { + idRenderModel *model; + idToken token; + int j; + srfTriangles_t *tri; + modelSurface_t surf; + + src->ExpectTokenString( "{" ); + + // parse the name + src->ExpectAnyToken( &token ); + + model = renderModelManager->AllocModel(); + model->InitEmpty( token ); + + surf.shader = tr.defaultMaterial; + + tri = R_AllocStaticTriSurf(); + surf.geometry = tri; + + tri->numVerts = src->ParseInt(); + tri->numShadowIndexesNoCaps = src->ParseInt(); + tri->numShadowIndexesNoFrontCaps = src->ParseInt(); + tri->numIndexes = src->ParseInt(); + tri->shadowCapPlaneBits = src->ParseInt(); + + R_AllocStaticTriSurfShadowVerts( tri, tri->numVerts ); + tri->bounds.Clear(); + for ( j = 0 ; j < tri->numVerts ; j++ ) { + float vec[8]; + + src->Parse1DMatrix( 3, vec ); + tri->shadowVertexes[j].xyz[0] = vec[0]; + tri->shadowVertexes[j].xyz[1] = vec[1]; + tri->shadowVertexes[j].xyz[2] = vec[2]; + tri->shadowVertexes[j].xyz[3] = 1; // no homogenous value + + tri->bounds.AddPoint( tri->shadowVertexes[j].xyz.ToVec3() ); + } + + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + tri->indexes[j] = src->ParseInt(); + } + + // add the completed surface to the model + model->AddSurface( surf ); + + src->ExpectTokenString( "}" ); + + // we do NOT do a model->FinishSurfaceces, because we don't need sil edges, planes, tangents, etc. +// model->FinishSurfaces(); + + return model; +} + +/* +================ +idRenderWorldLocal::SetupAreaRefs +================ +*/ +void idRenderWorldLocal::SetupAreaRefs() { + int i; + + connectedAreaNum = 0; + for ( i = 0 ; i < numPortalAreas ; i++ ) { + portalAreas[i].areaNum = i; + portalAreas[i].lightRefs.areaNext = + portalAreas[i].lightRefs.areaPrev = + &portalAreas[i].lightRefs; + portalAreas[i].entityRefs.areaNext = + portalAreas[i].entityRefs.areaPrev = + &portalAreas[i].entityRefs; + } +} + +/* +================ +idRenderWorldLocal::ParseInterAreaPortals +================ +*/ +void idRenderWorldLocal::ParseInterAreaPortals( idLexer *src ) { + int i, j; + + src->ExpectTokenString( "{" ); + + numPortalAreas = src->ParseInt(); + if ( numPortalAreas < 0 ) { + src->Error( "R_ParseInterAreaPortals: bad numPortalAreas" ); + return; + } + portalAreas = (portalArea_t *)R_ClearedStaticAlloc( numPortalAreas * sizeof( portalAreas[0] ) ); + areaScreenRect = (idScreenRect *) R_ClearedStaticAlloc( numPortalAreas * sizeof( idScreenRect ) ); + + // set the doubly linked lists + SetupAreaRefs(); + + numInterAreaPortals = src->ParseInt(); + if ( numInterAreaPortals < 0 ) { + src->Error( "R_ParseInterAreaPortals: bad numInterAreaPortals" ); + return; + } + + doublePortals = (doublePortal_t *)R_ClearedStaticAlloc( numInterAreaPortals * + sizeof( doublePortals [0] ) ); + + for ( i = 0 ; i < numInterAreaPortals ; i++ ) { + int numPoints, a1, a2; + idWinding *w; + portal_t *p; + + numPoints = src->ParseInt(); + a1 = src->ParseInt(); + a2 = src->ParseInt(); + + w = new idWinding( numPoints ); + w->SetNumPoints( numPoints ); + for ( j = 0 ; j < numPoints ; j++ ) { + src->Parse1DMatrix( 3, (*w)[j].ToFloatPtr() ); + // no texture coordinates + (*w)[j][3] = 0; + (*w)[j][4] = 0; + } + + // add the portal to a1 + p = (portal_t *)R_ClearedStaticAlloc( sizeof( *p ) ); + p->intoArea = a2; + p->doublePortal = &doublePortals[i]; + p->w = w; + p->w->GetPlane( p->plane ); + + p->next = portalAreas[a1].portals; + portalAreas[a1].portals = p; + + doublePortals[i].portals[0] = p; + + // reverse it for a2 + p = (portal_t *)R_ClearedStaticAlloc( sizeof( *p ) ); + p->intoArea = a1; + p->doublePortal = &doublePortals[i]; + p->w = w->Reverse(); + p->w->GetPlane( p->plane ); + + p->next = portalAreas[a2].portals; + portalAreas[a2].portals = p; + + doublePortals[i].portals[1] = p; + } + + src->ExpectTokenString( "}" ); +} + +/* +================ +idRenderWorldLocal::ParseNodes +================ +*/ +void idRenderWorldLocal::ParseNodes( idLexer *src ) { + int i; + + src->ExpectTokenString( "{" ); + + numAreaNodes = src->ParseInt(); + if ( numAreaNodes < 0 ) { + src->Error( "R_ParseNodes: bad numAreaNodes" ); + } + areaNodes = (areaNode_t *)R_ClearedStaticAlloc( numAreaNodes * sizeof( areaNodes[0] ) ); + + for ( i = 0 ; i < numAreaNodes ; i++ ) { + areaNode_t *node; + + node = &areaNodes[i]; + + src->Parse1DMatrix( 4, node->plane.ToFloatPtr() ); + node->children[0] = src->ParseInt(); + node->children[1] = src->ParseInt(); + } + + src->ExpectTokenString( "}" ); +} + +/* +================ +idRenderWorldLocal::CommonChildrenArea_r +================ +*/ +int idRenderWorldLocal::CommonChildrenArea_r( areaNode_t *node ) { + int nums[2]; + + for ( int i = 0 ; i < 2 ; i++ ) { + if ( node->children[i] <= 0 ) { + nums[i] = -1 - node->children[i]; + } else { + nums[i] = CommonChildrenArea_r( &areaNodes[ node->children[i] ] ); + } + } + + // solid nodes will match any area + if ( nums[0] == AREANUM_SOLID ) { + nums[0] = nums[1]; + } + if ( nums[1] == AREANUM_SOLID ) { + nums[1] = nums[0]; + } + + int common; + if ( nums[0] == nums[1] ) { + common = nums[0]; + } else { + common = CHILDREN_HAVE_MULTIPLE_AREAS; + } + + node->commonChildrenArea = common; + + return common; +} + +/* +================= +idRenderWorldLocal::ClearWorld + +Sets up for a single area world +================= +*/ +void idRenderWorldLocal::ClearWorld() { + numPortalAreas = 1; + portalAreas = (portalArea_t *)R_ClearedStaticAlloc( sizeof( portalAreas[0] ) ); + areaScreenRect = (idScreenRect *) R_ClearedStaticAlloc( sizeof( idScreenRect ) ); + + SetupAreaRefs(); + + // even though we only have a single area, create a node + // that has both children pointing at it so we don't need to + // + areaNodes = (areaNode_t *)R_ClearedStaticAlloc( sizeof( areaNodes[0] ) ); + areaNodes[0].plane[3] = 1; + areaNodes[0].children[0] = -1; + areaNodes[0].children[1] = -1; +} + +/* +================= +idRenderWorldLocal::FreeDefs + +dump all the interactions +================= +*/ +void idRenderWorldLocal::FreeDefs() { + int i; + + generateAllInteractionsCalled = false; + + if ( interactionTable ) { + R_StaticFree( interactionTable ); + interactionTable = NULL; + } + + // free all lightDefs + for ( i = 0 ; i < lightDefs.Num() ; i++ ) { + idRenderLightLocal *light; + + light = lightDefs[i]; + if ( light && light->world == this ) { + FreeLightDef( i ); + lightDefs[i] = NULL; + } + } + + // free all entityDefs + for ( i = 0 ; i < entityDefs.Num() ; i++ ) { + idRenderEntityLocal *mod; + + mod = entityDefs[i]; + if ( mod && mod->world == this ) { + FreeEntityDef( i ); + entityDefs[i] = NULL; + } + } +} + +/* +================= +idRenderWorldLocal::InitFromMap + +A NULL or empty name will make a world without a map model, which +is still useful for displaying a bare model +================= +*/ +bool idRenderWorldLocal::InitFromMap( const char *name ) { + idLexer * src; + idToken token; + idStr filename; + idRenderModel * lastModel; + + // if this is an empty world, initialize manually + if ( !name || !name[0] ) { + FreeWorld(); + mapName.Clear(); + ClearWorld(); + return true; + } + + + // load it + filename = name; + filename.SetFileExtension( PROC_FILE_EXT ); + + // if we are reloading the same map, check the timestamp + // and try to skip all the work + ID_TIME_T currentTimeStamp; + fileSystem->ReadFile( filename, NULL, ¤tTimeStamp ); + + if ( name == mapName ) { + if ( currentTimeStamp != FILE_NOT_FOUND_TIMESTAMP && currentTimeStamp == mapTimeStamp ) { + common->Printf( "idRenderWorldLocal::InitFromMap: retaining existing map\n" ); + FreeDefs(); + TouchWorldModels(); + AddWorldModelEntities(); + ClearPortalStates(); + return true; + } + common->Printf( "idRenderWorldLocal::InitFromMap: timestamp has changed, reloading.\n" ); + } + + FreeWorld(); + + src = new idLexer( filename, LEXFL_NOSTRINGCONCAT | LEXFL_NODOLLARPRECOMPILE ); + if ( !src->IsLoaded() ) { + common->Printf( "idRenderWorldLocal::InitFromMap: %s not found\n", filename.c_str() ); + ClearWorld(); + return false; + } + + + mapName = name; + mapTimeStamp = currentTimeStamp; + + // if we are writing a demo, archive the load command + if ( session->writeDemo ) { + WriteLoadMap(); + } + + if ( !src->ReadToken( &token ) || token.Icmp( PROC_FILE_ID ) ) { + common->Printf( "idRenderWorldLocal::InitFromMap: bad id '%s' instead of '%s'\n", token.c_str(), PROC_FILE_ID ); + delete src; + return false; + } + + // parse the file + while ( 1 ) { + if ( !src->ReadToken( &token ) ) { + break; + } + + if ( token == "model" ) { + lastModel = ParseModel( src ); + + // add it to the model manager list + renderModelManager->AddModel( lastModel ); + + // save it in the list to free when clearing this map + localModels.Append( lastModel ); + continue; + } + + if ( token == "shadowModel" ) { + lastModel = ParseShadowModel( src ); + + // add it to the model manager list + renderModelManager->AddModel( lastModel ); + + // save it in the list to free when clearing this map + localModels.Append( lastModel ); + continue; + } + + if ( token == "interAreaPortals" ) { + ParseInterAreaPortals( src ); + continue; + } + + if ( token == "nodes" ) { + ParseNodes( src ); + continue; + } + + src->Error( "idRenderWorldLocal::InitFromMap: bad token \"%s\"", token.c_str() ); + } + + delete src; + + // if it was a trivial map without any areas, create a single area + if ( !numPortalAreas ) { + ClearWorld(); + } + + // find the points where we can early-our of reference pushing into the BSP tree + CommonChildrenArea_r( &areaNodes[0] ); + + AddWorldModelEntities(); + ClearPortalStates(); + + // done! + return true; +} + +/* +===================== +idRenderWorldLocal::ClearPortalStates +===================== +*/ +void idRenderWorldLocal::ClearPortalStates() { + int i, j; + + // all portals start off open + for ( i = 0 ; i < numInterAreaPortals ; i++ ) { + doublePortals[i].blockingBits = PS_BLOCK_NONE; + } + + // flood fill all area connections + for ( i = 0 ; i < numPortalAreas ; i++ ) { + for ( j = 0 ; j < NUM_PORTAL_ATTRIBUTES ; j++ ) { + connectedAreaNum++; + FloodConnectedAreas( &portalAreas[i], j ); + } + } +} + +/* +===================== +idRenderWorldLocal::AddWorldModelEntities +===================== +*/ +void idRenderWorldLocal::AddWorldModelEntities() { + int i; + + // add the world model for each portal area + // we can't just call AddEntityDef, because that would place the references + // based on the bounding box, rather than explicitly into the correct area + for ( i = 0 ; i < numPortalAreas ; i++ ) { + idRenderEntityLocal *def; + int index; + + def = new idRenderEntityLocal; + + // try and reuse a free spot + index = entityDefs.FindNull(); + if ( index == -1 ) { + index = entityDefs.Append(def); + } else { + entityDefs[index] = def; + } + + def->index = index; + def->world = this; + + def->parms.hModel = renderModelManager->FindModel( va("_area%i", i ) ); + if ( def->parms.hModel->IsDefaultModel() || !def->parms.hModel->IsStaticWorldModel() ) { + common->Error( "idRenderWorldLocal::InitFromMap: bad area model lookup" ); + } + + idRenderModel *hModel = def->parms.hModel; + + for ( int j = 0; j < hModel->NumSurfaces(); j++ ) { + const modelSurface_t *surf = hModel->Surface( j ); + + if ( surf->shader->GetName() == idStr( "textures/smf/portal_sky" ) ) { + def->needsPortalSky = true; + } + } + + def->referenceBounds = def->parms.hModel->Bounds(); + + def->parms.axis[0][0] = 1; + def->parms.axis[1][1] = 1; + def->parms.axis[2][2] = 1; + + R_AxisToModelMatrix( def->parms.axis, def->parms.origin, def->modelMatrix ); + + // in case an explicit shader is used on the world, we don't + // want it to have a 0 alpha or color + def->parms.shaderParms[0] = + def->parms.shaderParms[1] = + def->parms.shaderParms[2] = + def->parms.shaderParms[3] = 1; + + AddEntityRefToArea( def, &portalAreas[i] ); + } +} + +/* +===================== +CheckAreaForPortalSky +===================== +*/ +bool idRenderWorldLocal::CheckAreaForPortalSky( int areaNum ) { + areaReference_t *ref; + + assert( areaNum >= 0 && areaNum < numPortalAreas ); + + for ( ref = portalAreas[areaNum].entityRefs.areaNext; ref->entity; ref = ref->areaNext ) { + assert( ref->area == &portalAreas[areaNum] ); + + if ( ref->entity && ref->entity->needsPortalSky ) { + return true; + } + } + + return false; +} diff --git a/renderer/RenderWorld_local.h b/renderer/RenderWorld_local.h new file mode 100644 index 000000000..850c6fdd9 --- /dev/null +++ b/renderer/RenderWorld_local.h @@ -0,0 +1,253 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __RENDERWORLDLOCAL_H__ +#define __RENDERWORLDLOCAL_H__ + +// assume any lightDef or entityDef index above this is an internal error +const int LUDICROUS_INDEX = 10000; + + +typedef struct portal_s { + int intoArea; // area this portal leads to + idWinding * w; // winding points have counter clockwise ordering seen this area + idPlane plane; // view must be on the positive side of the plane to cross + struct portal_s * next; // next portal of the area + struct doublePortal_s * doublePortal; +} portal_t; + + +typedef struct doublePortal_s { + struct portal_s * portals[2]; + int blockingBits; // PS_BLOCK_VIEW, PS_BLOCK_AIR, etc, set by doors that shut them off + + // A portal will be considered closed if it is past the + // fog-out point in a fog volume. We only support a single + // fog volume over each portal. + idRenderLightLocal * fogLight; + struct doublePortal_s * nextFoggedPortal; +} doublePortal_t; + + +typedef struct portalArea_s { + int areaNum; + int connectedAreaNum[NUM_PORTAL_ATTRIBUTES]; // if two areas have matching connectedAreaNum, they are + // not separated by a portal with the apropriate PS_BLOCK_* blockingBits + int viewCount; // set by R_FindViewLightsAndEntities + portal_t * portals; // never changes after load + areaReference_t entityRefs; // head/tail of doubly linked list, may change + areaReference_t lightRefs; // head/tail of doubly linked list, may change +} portalArea_t; + + +static const int CHILDREN_HAVE_MULTIPLE_AREAS = -2; +static const int AREANUM_SOLID = -1; +typedef struct { + idPlane plane; + int children[2]; // negative numbers are (-1 - areaNumber), 0 = solid + int commonChildrenArea; // if all children are either solid or a single area, + // this is the area number, else CHILDREN_HAVE_MULTIPLE_AREAS +} areaNode_t; + + +class idRenderWorldLocal : public idRenderWorld { +public: + idRenderWorldLocal(); + virtual ~idRenderWorldLocal(); + + virtual qhandle_t AddEntityDef( const renderEntity_t *re ); + virtual void UpdateEntityDef( qhandle_t entityHandle, const renderEntity_t *re ); + virtual void FreeEntityDef( qhandle_t entityHandle ); + virtual const renderEntity_t *GetRenderEntity( qhandle_t entityHandle ) const; + + virtual qhandle_t AddLightDef( const renderLight_t *rlight ); + virtual void UpdateLightDef( qhandle_t lightHandle, const renderLight_t *rlight ); + virtual void FreeLightDef( qhandle_t lightHandle ); + virtual const renderLight_t *GetRenderLight( qhandle_t lightHandle ) const; + + virtual bool CheckAreaForPortalSky( int areaNum ); + + virtual void GenerateAllInteractions(); + virtual void RegenerateWorld(); + + virtual void ProjectDecalOntoWorld( const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ); + virtual void ProjectDecal( qhandle_t entityHandle, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ); + virtual void ProjectOverlay( qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material ); + virtual void RemoveDecals( qhandle_t entityHandle ); + + virtual void SetRenderView( const renderView_t *renderView ); + virtual void RenderScene( const renderView_t *renderView ); + + virtual int NumAreas( void ) const; + virtual int PointInArea( const idVec3 &point ) const; + virtual int BoundsInAreas( const idBounds &bounds, int *areas, int maxAreas ) const; + virtual int NumPortalsInArea( int areaNum ); + virtual exitPortal_t GetPortal( int areaNum, int portalNum ); + + virtual guiPoint_t GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const; + virtual bool ModelTrace( modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius ) const; + virtual bool Trace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic = true, bool skipPlayer = false ) const; + virtual bool FastWorldTrace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end ) const; + + virtual void DebugClearLines( int time ); + virtual void DebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime = 0, const bool depthTest = false ); + virtual void DebugArrow( const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime = 0 ); + virtual void DebugWinding( const idVec4 &color, const idWinding &w, const idVec3 &origin, const idMat3 &axis, const int lifetime = 0, const bool depthTest = false ); + virtual void DebugCircle( const idVec4 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const int lifetime = 0, const bool depthTest = false ); + virtual void DebugSphere( const idVec4 &color, const idSphere &sphere, const int lifetime = 0, bool depthTest = false ); + virtual void DebugBounds( const idVec4 &color, const idBounds &bounds, const idVec3 &org = vec3_origin, const int lifetime = 0 ); + virtual void DebugBox( const idVec4 &color, const idBox &box, const int lifetime = 0 ); + virtual void DebugFrustum( const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin = false, const int lifetime = 0 ); + virtual void DebugCone( const idVec4 &color, const idVec3 &apex, const idVec3 &dir, float radius1, float radius2, const int lifetime = 0 ); + virtual void DebugScreenRect( const idVec4 &color, const idScreenRect &rect, const viewDef_t *viewDef, const int lifetime = 0 ); + virtual void DebugAxis( const idVec3 &origin, const idMat3 &axis ); + + virtual void DebugClearPolygons( int time ); + virtual void DebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime = 0, const bool depthTest = false ); + + virtual void DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align = 1, const int lifetime = 0, bool depthTest = false ); + + //----------------------- + + idStr mapName; // ie: maps/tim_dm2.proc, written to demoFile + ID_TIME_T mapTimeStamp; // for fast reloads of the same level + + areaNode_t * areaNodes; + int numAreaNodes; + + portalArea_t * portalAreas; + int numPortalAreas; + int connectedAreaNum; // incremented every time a door portal state changes + + idScreenRect * areaScreenRect; + + doublePortal_t * doublePortals; + int numInterAreaPortals; + + idList localModels; + + idList entityDefs; + idList lightDefs; + + idBlockAlloc areaReferenceAllocator; + idBlockAlloc interactionAllocator; + idBlockAlloc areaNumRefAllocator; + + // all light / entity interactions are referenced here for fast lookup without + // having to crawl the doubly linked lists. EnntityDefs are sequential for better + // cache access, because the table is accessed by light in idRenderWorldLocal::CreateLightDefInteractions() + // Growing this table is time consuming, so we add a pad value to the number + // of entityDefs and lightDefs + idInteraction ** interactionTable; + int interactionTableWidth; // entityDefs + int interactionTableHeight; // lightDefs + + + bool generateAllInteractionsCalled; + + //----------------------- + // RenderWorld_load.cpp + + idRenderModel * ParseModel( idLexer *src ); + idRenderModel * ParseShadowModel( idLexer *src ); + void SetupAreaRefs(); + void ParseInterAreaPortals( idLexer *src ); + void ParseNodes( idLexer *src ); + int CommonChildrenArea_r( areaNode_t *node ); + void FreeWorld(); + void ClearWorld(); + void FreeDefs(); + void TouchWorldModels( void ); + void AddWorldModelEntities(); + void ClearPortalStates(); + virtual bool InitFromMap( const char *mapName ); + + //-------------------------- + // RenderWorld_portals.cpp + + idScreenRect ScreenRectFromWinding( const idWinding *w, viewEntity_t *space ); + bool PortalIsFoggedOut( const portal_t *p ); + void FloodViewThroughArea_r( const idVec3 origin, int areaNum, const struct portalStack_s *ps ); + void FlowViewThroughPortals( const idVec3 origin, int numPlanes, const idPlane *planes ); + void FloodLightThroughArea_r( idRenderLightLocal *light, int areaNum, const struct portalStack_s *ps ); + void FlowLightThroughPortals( idRenderLightLocal *light ); + areaNumRef_t * FloodFrustumAreas_r( const idFrustum &frustum, const int areaNum, const idBounds &bounds, areaNumRef_t *areas ); + areaNumRef_t * FloodFrustumAreas( const idFrustum &frustum, areaNumRef_t *areas ); + bool CullEntityByPortals( const idRenderEntityLocal *entity, const struct portalStack_s *ps ); + void AddAreaEntityRefs( int areaNum, const struct portalStack_s *ps ); + bool CullLightByPortals( const idRenderLightLocal *light, const struct portalStack_s *ps ); + void AddAreaLightRefs( int areaNum, const struct portalStack_s *ps ); + void AddAreaRefs( int areaNum, const struct portalStack_s *ps ); + void BuildConnectedAreas_r( int areaNum ); + void BuildConnectedAreas( void ); + void FindViewLightsAndEntities( void ); + + int NumPortals( void ) const; + qhandle_t FindPortal( const idBounds &b ) const; + void SetPortalState( qhandle_t portal, int blockingBits ); + int GetPortalState( qhandle_t portal ); + bool AreasAreConnected( int areaNum1, int areaNum2, portalConnection_t connection ); + void FloodConnectedAreas( portalArea_t *area, int portalAttributeIndex ); + idScreenRect & GetAreaScreenRect( int areaNum ) const { return areaScreenRect[areaNum]; } + void ShowPortals(); + + //-------------------------- + // RenderWorld_demo.cpp + + void StartWritingDemo( idDemoFile *demo ); + void StopWritingDemo(); + bool ProcessDemoCommand( idDemoFile *readDemo, renderView_t *demoRenderView, int *demoTimeOffset ); + + void WriteLoadMap(); + void WriteRenderView( const renderView_t *renderView ); + void WriteVisibleDefs( const viewDef_t *viewDef ); + void WriteFreeLight( qhandle_t handle ); + void WriteFreeEntity( qhandle_t handle ); + void WriteRenderLight( qhandle_t handle, const renderLight_t *light ); + void WriteRenderEntity( qhandle_t handle, const renderEntity_t *ent ); + void ReadRenderEntity(); + void ReadRenderLight(); + + + //-------------------------- + // RenderWorld.cpp + + void ResizeInteractionTable(); + + void AddEntityRefToArea( idRenderEntityLocal *def, portalArea_t *area ); + void AddLightRefToArea( idRenderLightLocal *light, portalArea_t *area ); + + void RecurseProcBSP_r( modelTrace_t *results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3 &p1, const idVec3 &p2 ) const; + + void BoundsInAreas_r( int nodeNum, const idBounds &bounds, int *areas, int *numAreas, int maxAreas ) const; + + float DrawTextLength( const char *text, float scale, int len = 0 ); + + void FreeInteractions(); + + void PushVolumeIntoTree_r( idRenderEntityLocal *def, idRenderLightLocal *light, const idSphere *sphere, int numPoints, const idVec3 (*points), int nodeNum ); + + void PushVolumeIntoTree( idRenderEntityLocal *def, idRenderLightLocal *light, int numPoints, const idVec3 (*points) ); + + //------------------------------- + // tr_light.c + void CreateLightDefInteractions( idRenderLightLocal *ldef ); +}; + +#endif /* !__RENDERWORLDLOCAL_H__ */ diff --git a/renderer/RenderWorld_portals.cpp b/renderer/RenderWorld_portals.cpp new file mode 100644 index 000000000..13d1168ec --- /dev/null +++ b/renderer/RenderWorld_portals.cpp @@ -0,0 +1,1064 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + + +All that is done in these functions is the creation of viewLights +and viewEntitys for the lightDefs and entityDefs that are visible +in the portal areas that can be seen from the current viewpoint. + +*/ + + +// if we hit this many planes, we will just stop cropping the +// view down, which is still correct, just conservative +const int MAX_PORTAL_PLANES = 20; + +typedef struct portalStack_s { + portal_t *p; + const struct portalStack_s *next; + + idScreenRect rect; + + int numPortalPlanes; + idPlane portalPlanes[MAX_PORTAL_PLANES+1]; + // positive side is outside the visible frustum +} portalStack_t; + + +//==================================================================== + + +/* +=================== +idRenderWorldLocal::ScreenRectForWinding +=================== +*/ +idScreenRect idRenderWorldLocal::ScreenRectFromWinding( const idWinding *w, viewEntity_t *space ) { + idScreenRect r; + int i; + idVec3 v; + idVec3 ndc; + float windowX, windowY; + + r.Clear(); + for ( i = 0 ; i < w->GetNumPoints() ; i++ ) { + R_LocalPointToGlobal( space->modelMatrix, (*w)[i].ToVec3(), v ); + R_GlobalToNormalizedDeviceCoordinates( v, ndc ); + + windowX = 0.5f * ( 1.0f + ndc[0] ) * ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ); + windowY = 0.5f * ( 1.0f + ndc[1] ) * ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ); + + r.AddPoint( windowX, windowY ); + } + + r.Expand(); + + return r; +} + +/* +=================== +PortalIsFoggedOut +=================== +*/ +bool idRenderWorldLocal::PortalIsFoggedOut( const portal_t *p ) { + idRenderLightLocal *ldef; + const idWinding *w; + int i; + idPlane forward; + + ldef = p->doublePortal->fogLight; + if ( !ldef ) { + return false; + } + + // find the current density of the fog + const idMaterial *lightShader = ldef->lightShader; + int size = sizeof( float ) *lightShader->GetNumRegisters(); + float *regs =(float *)_alloca( size ); + + lightShader->EvaluateRegisters( regs, ldef->parms.shaderParms, tr.viewDef, ldef->parms.referenceSound ); + + const shaderStage_t *stage = lightShader->GetStage(0); + + float alpha = regs[ stage->color.registers[3] ]; + + + // if they left the default value on, set a fog distance of 500 + float a; + + if ( alpha <= 1.0f ) { + a = -0.5f / DEFAULT_FOG_DISTANCE; + } else { + // otherwise, distance = alpha color + a = -0.5f / alpha; + } + + forward[0] = a * tr.viewDef->worldSpace.modelViewMatrix[2]; + forward[1] = a * tr.viewDef->worldSpace.modelViewMatrix[6]; + forward[2] = a * tr.viewDef->worldSpace.modelViewMatrix[10]; + forward[3] = a * tr.viewDef->worldSpace.modelViewMatrix[14]; + + w = p->w; + for ( i = 0 ; i < w->GetNumPoints() ; i++ ) { + float d; + + d = forward.Distance( (*w)[i].ToVec3() ); + if ( d < 0.5f ) { + return false; // a point not clipped off + } + } + + return true; +} + +/* +=================== +FloodViewThroughArea_r +=================== +*/ +void idRenderWorldLocal::FloodViewThroughArea_r( const idVec3 origin, int areaNum, + const struct portalStack_s *ps ) { + portal_t* p; + float d; + portalArea_t * area; + const portalStack_t *check; + portalStack_t newStack; + int i, j; + idVec3 v1, v2; + int addPlanes; + idFixedWinding w; // we won't overflow because MAX_PORTAL_PLANES = 20 + + area = &portalAreas[ areaNum ]; + + // cull models and lights to the current collection of planes + AddAreaRefs( areaNum, ps ); + + if ( areaScreenRect[areaNum].IsEmpty() ) { + areaScreenRect[areaNum] = ps->rect; + } else { + areaScreenRect[areaNum].Union( ps->rect ); + } + + // go through all the portals + for ( p = area->portals; p; p = p->next ) { + // an enclosing door may have sealed the portal off + if ( p->doublePortal->blockingBits & PS_BLOCK_VIEW ) { + continue; + } + + // make sure this portal is facing away from the view + d = p->plane.Distance( origin ); + if ( d < -0.1f ) { + continue; + } + + // make sure the portal isn't in our stack trace, + // which would cause an infinite loop + for ( check = ps; check; check = check->next ) { + if ( check->p == p ) { + break; // don't recursively enter a stack + } + } + if ( check ) { + continue; // already in stack + } + + // if we are very close to the portal surface, don't bother clipping + // it, which tends to give epsilon problems that make the area vanish + if ( d < 1.0f ) { + + // go through this portal + newStack = *ps; + newStack.p = p; + newStack.next = ps; + FloodViewThroughArea_r( origin, p->intoArea, &newStack ); + continue; + } + + // clip the portal winding to all of the planes + w = *p->w; + for ( j = 0; j < ps->numPortalPlanes; j++ ) { + if ( !w.ClipInPlace( -ps->portalPlanes[j], 0 ) ) { + break; + } + } + if ( !w.GetNumPoints() ) { + continue; // portal not visible + } + + // see if it is fogged out + if ( PortalIsFoggedOut( p ) ) { + continue; + } + + // go through this portal + newStack.p = p; + newStack.next = ps; + + // find the screen pixel bounding box of the remaining portal + // so we can scissor things outside it + newStack.rect = ScreenRectFromWinding( &w, &tr.identitySpace ); + + // slop might have spread it a pixel outside, so trim it back + newStack.rect.Intersect( ps->rect ); + + // generate a set of clipping planes that will further restrict + // the visible view beyond just the scissor rect + + addPlanes = w.GetNumPoints(); + if ( addPlanes > MAX_PORTAL_PLANES ) { + addPlanes = MAX_PORTAL_PLANES; + } + + newStack.numPortalPlanes = 0; + for ( i = 0; i < addPlanes; i++ ) { + j = i+1; + if ( j == w.GetNumPoints() ) { + j = 0; + } + + v1 = origin - w[i].ToVec3(); + v2 = origin - w[j].ToVec3(); + + newStack.portalPlanes[newStack.numPortalPlanes].Normal().Cross( v2, v1 ); + + // if it is degenerate, skip the plane + if ( newStack.portalPlanes[newStack.numPortalPlanes].Normalize() < 0.01f ) { + continue; + } + newStack.portalPlanes[newStack.numPortalPlanes].FitThroughPoint( origin ); + + newStack.numPortalPlanes++; + } + + // the last stack plane is the portal plane + newStack.portalPlanes[newStack.numPortalPlanes] = p->plane; + newStack.numPortalPlanes++; + + FloodViewThroughArea_r( origin, p->intoArea, &newStack ); + } +} + +/* +======================= +FlowViewThroughPortals + +Finds viewLights and viewEntities by flowing from an origin through the visible portals. +origin point can see into. The planes array defines a volume (positive +sides facing in) that should contain the origin, such as a view frustum or a point light box. +Zero planes assumes an unbounded volume. +======================= +*/ +void idRenderWorldLocal::FlowViewThroughPortals( const idVec3 origin, int numPlanes, const idPlane *planes ) { + portalStack_t ps; + int i; + + ps.next = NULL; + ps.p = NULL; + + for ( i = 0 ; i < numPlanes ; i++ ) { + ps.portalPlanes[i] = planes[i]; + } + + ps.numPortalPlanes = numPlanes; + ps.rect = tr.viewDef->scissor; + + if ( tr.viewDef->areaNum < 0 ){ + + for ( i = 0; i < numPortalAreas; i++ ) { + areaScreenRect[i] = tr.viewDef->scissor; + } + + // if outside the world, mark everything + for ( i = 0 ; i < numPortalAreas ; i++ ) { + AddAreaRefs( i, &ps ); + } + } else { + + for ( i = 0; i < numPortalAreas; i++ ) { + areaScreenRect[i].Clear(); + } + + // flood out through portals, setting area viewCount + FloodViewThroughArea_r( origin, tr.viewDef->areaNum, &ps ); + } +} + +//================================================================================================== + + +/* +=================== +FloodLightThroughArea_r +=================== +*/ +void idRenderWorldLocal::FloodLightThroughArea_r( idRenderLightLocal *light, int areaNum, + const struct portalStack_s *ps ) { + portal_t* p; + float d; + portalArea_t * area; + const portalStack_t *check, *firstPortalStack; + portalStack_t newStack; + int i, j; + idVec3 v1, v2; + int addPlanes; + idFixedWinding w; // we won't overflow because MAX_PORTAL_PLANES = 20 + + area = &portalAreas[ areaNum ]; + + // add an areaRef + AddLightRefToArea( light, area ); + + // go through all the portals + for ( p = area->portals; p; p = p->next ) { + // make sure this portal is facing away from the view + d = p->plane.Distance( light->globalLightOrigin ); + if ( d < -0.1f ) { + continue; + } + + // make sure the portal isn't in our stack trace, + // which would cause an infinite loop + for ( check = ps; check; check = check->next ) { + firstPortalStack = check; + if ( check->p == p ) { + break; // don't recursively enter a stack + } + } + if ( check ) { + continue; // already in stack + } + + // if we are very close to the portal surface, don't bother clipping + // it, which tends to give epsilon problems that make the area vanish + if ( d < 1.0f ) { + // go through this portal + newStack = *ps; + newStack.p = p; + newStack.next = ps; + FloodLightThroughArea_r( light, p->intoArea, &newStack ); + continue; + } + + // clip the portal winding to all of the planes + w = *p->w; + for ( j = 0; j < ps->numPortalPlanes; j++ ) { + if ( !w.ClipInPlace( -ps->portalPlanes[j], 0 ) ) { + break; + } + } + if ( !w.GetNumPoints() ) { + continue; // portal not visible + } + // also always clip to the original light planes, because they aren't + // necessarily extending to infinitiy like a view frustum + for ( j = 0; j < firstPortalStack->numPortalPlanes; j++ ) { + if ( !w.ClipInPlace( -firstPortalStack->portalPlanes[j], 0 ) ) { + break; + } + } + if ( !w.GetNumPoints() ) { + continue; // portal not visible + } + + // go through this portal + newStack.p = p; + newStack.next = ps; + + // generate a set of clipping planes that will further restrict + // the visible view beyond just the scissor rect + + addPlanes = w.GetNumPoints(); + if ( addPlanes > MAX_PORTAL_PLANES ) { + addPlanes = MAX_PORTAL_PLANES; + } + + newStack.numPortalPlanes = 0; + for ( i = 0; i < addPlanes; i++ ) { + j = i+1; + if ( j == w.GetNumPoints() ) { + j = 0; + } + + v1 = light->globalLightOrigin - w[i].ToVec3(); + v2 = light->globalLightOrigin - w[j].ToVec3(); + + newStack.portalPlanes[newStack.numPortalPlanes].Normal().Cross( v2, v1 ); + + // if it is degenerate, skip the plane + if ( newStack.portalPlanes[newStack.numPortalPlanes].Normalize() < 0.01f ) { + continue; + } + newStack.portalPlanes[newStack.numPortalPlanes].FitThroughPoint( light->globalLightOrigin ); + + newStack.numPortalPlanes++; + } + + FloodLightThroughArea_r( light, p->intoArea, &newStack ); + } +} + + +/* +======================= +FlowLightThroughPortals + +Adds an arearef in each area that the light center flows into. +This can only be used for shadow casting lights that have a generated +prelight, because shadows are cast from back side which may not be in visible areas. +======================= +*/ +void idRenderWorldLocal::FlowLightThroughPortals( idRenderLightLocal *light ) { + portalStack_t ps; + int i; + const idVec3 origin = light->globalLightOrigin; + + // if the light origin areaNum is not in a valid area, + // the light won't have any area refs + if ( light->areaNum == -1 ) { + return; + } + + memset( &ps, 0, sizeof( ps ) ); + + ps.numPortalPlanes = 6; + for ( i = 0 ; i < 6 ; i++ ) { + ps.portalPlanes[i] = light->frustum[i]; + } + + FloodLightThroughArea_r( light, light->areaNum, &ps ); +} + +//====================================================================================================== + +/* +=================== +idRenderWorldLocal::FloodFrustumAreas_r +=================== +*/ +areaNumRef_t *idRenderWorldLocal::FloodFrustumAreas_r( const idFrustum &frustum, const int areaNum, const idBounds &bounds, areaNumRef_t *areas ) { + portal_t *p; + portalArea_t *portalArea; + idBounds newBounds; + areaNumRef_t *a; + + portalArea = &portalAreas[ areaNum ]; + + // go through all the portals + for ( p = portalArea->portals; p; p = p->next ) { + + // check if we already visited the area the portal leads to + for ( a = areas; a; a = a->next ) { + if ( a->areaNum == p->intoArea ) { + break; + } + } + if ( a ) { + continue; + } + + // the frustum origin must be at the front of the portal plane + if ( p->plane.Side( frustum.GetOrigin(), 0.1f ) == SIDE_BACK ) { + continue; + } + + // the frustum must cross the portal plane + if ( frustum.PlaneSide( p->plane, 0.0f ) != PLANESIDE_CROSS ) { + continue; + } + + // get the bounds for the portal winding projected in the frustum + frustum.ProjectionBounds( *p->w, newBounds ); + + newBounds.IntersectSelf( bounds ); + + if ( newBounds[0][0] > newBounds[1][0] || newBounds[0][1] > newBounds[1][1] || newBounds[0][2] > newBounds[1][2] ) { + continue; + } + + newBounds[1][0] = frustum.GetFarDistance(); + + a = areaNumRefAllocator.Alloc(); + a->areaNum = p->intoArea; + a->next = areas; + areas = a; + + areas = FloodFrustumAreas_r( frustum, p->intoArea, newBounds, areas ); + } + + return areas; +} + +/* +=================== +idRenderWorldLocal::FloodFrustumAreas + + Retrieves all the portal areas the frustum floods into where the frustum starts in the given areas. + All portals are assumed to be open. +=================== +*/ +areaNumRef_t *idRenderWorldLocal::FloodFrustumAreas( const idFrustum &frustum, areaNumRef_t *areas ) { + idBounds bounds; + areaNumRef_t *a; + + // bounds that cover the whole frustum + bounds[0].Set( frustum.GetNearDistance(), -1.0f, -1.0f ); + bounds[1].Set( frustum.GetFarDistance(), 1.0f, 1.0f ); + + for ( a = areas; a; a = a->next ) { + areas = FloodFrustumAreas_r( frustum, a->areaNum, bounds, areas ); + } + + return areas; +} + + +/* +======================================================================= + +R_FindViewLightsAndEntities + +======================================================================= +*/ + +/* +================ +CullEntityByPortals + +Return true if the entity reference bounds do not intersect the current portal chain. +================ +*/ +bool idRenderWorldLocal::CullEntityByPortals( const idRenderEntityLocal *entity, const portalStack_t *ps ) { + + if ( !r_useEntityCulling.GetBool() ) { + return false; + } + + // try to cull the entire thing using the reference bounds. + // we do not yet do callbacks or dynamic model creation, + // because we want to do all touching of the model after + // we have determined all the lights that may effect it, + // which optimizes cache usage + if ( R_CullLocalBox( entity->referenceBounds, entity->modelMatrix, + ps->numPortalPlanes, ps->portalPlanes ) ) { + return true; + } + + return false; +} + +/* +=================== +AddAreaEntityRefs + +Any models that are visible through the current portalStack will +have their scissor +=================== +*/ +void idRenderWorldLocal::AddAreaEntityRefs( int areaNum, const portalStack_t *ps ) { + areaReference_t *ref; + idRenderEntityLocal *entity; + portalArea_t *area; + viewEntity_t *vEnt; + idBounds b; + + area = &portalAreas[ areaNum ]; + + for ( ref = area->entityRefs.areaNext ; ref != &area->entityRefs ; ref = ref->areaNext ) { + entity = ref->entity; + + // debug tool to allow viewing of only one entity at a time + if ( r_singleEntity.GetInteger() >= 0 && r_singleEntity.GetInteger() != entity->index ) { + continue; + } + + // remove decals that are completely faded away + R_FreeEntityDefFadedDecals( entity, tr.viewDef->renderView.time ); + + // check for completely suppressing the model + if ( !r_skipSuppress.GetBool() ) { + if ( entity->parms.suppressSurfaceInViewID + && entity->parms.suppressSurfaceInViewID == tr.viewDef->renderView.viewID ) { + continue; + } + if ( entity->parms.allowSurfaceInViewID + && entity->parms.allowSurfaceInViewID != tr.viewDef->renderView.viewID ) { + continue; + } + } + + // cull reference bounds + if ( CullEntityByPortals( entity, ps ) ) { + // we are culled out through this portal chain, but it might + // still be visible through others + continue; + } + + vEnt = R_SetEntityDefViewEntity( entity ); + + // possibly expand the scissor rect + vEnt->scissorRect.Union( ps->rect ); + } +} + +/* +================ +CullLightByPortals + +Return true if the light frustum does not intersect the current portal chain. +The last stack plane is not used because lights are not near clipped. +================ +*/ +bool idRenderWorldLocal::CullLightByPortals( const idRenderLightLocal *light, const portalStack_t *ps ) { + int i, j; + const srfTriangles_t *tri; + float d; + idFixedWinding w; // we won't overflow because MAX_PORTAL_PLANES = 20 + + if ( r_useLightCulling.GetInteger() == 0 ) { + return false; + } + + if ( r_useLightCulling.GetInteger() >= 2 ) { + // exact clip of light faces against all planes + for ( i = 0; i < 6; i++ ) { + // the light frustum planes face out from the light, + // so the planes that have the view origin on the negative + // side will be the "back" faces of the light, which must have + // some fragment inside the portalStack to be visible + if ( light->frustum[i].Distance( tr.viewDef->renderView.vieworg ) >= 0 ) { + continue; + } + + // get the exact winding for this side + const idWinding *ow = light->frustumWindings[i]; + + // projected lights may have one of the frustums degenerated + if ( !ow ) { + continue; + } + + w = *ow; + + // now check the winding against each of the portalStack planes + for ( j = 0; j < ps->numPortalPlanes - 1; j++ ) { + if ( !w.ClipInPlace( -ps->portalPlanes[j] ) ) { + break; + } + } + + if ( w.GetNumPoints() ) { + // part of the winding is visible through the portalStack, + // so the light is not culled + return false; + } + } + // none of the light surfaces were visible + return true; + + } else { + + // simple point check against each plane + tri = light->frustumTris; + + // check against frustum planes + for ( i = 0; i < ps->numPortalPlanes - 1; i++ ) { + for ( j = 0; j < tri->numVerts; j++ ) { + d = ps->portalPlanes[i].Distance( tri->verts[j].xyz ); + if ( d < 0.0f ) { + break; // point is inside this plane + } + } + if ( j == tri->numVerts ) { + // all points were outside one of the planes + tr.pc.c_box_cull_out++; + return true; + } + } + } + + return false; +} + +/* +=================== +AddAreaLightRefs + +This is the only point where lights get added to the viewLights list +=================== +*/ +void idRenderWorldLocal::AddAreaLightRefs( int areaNum, const portalStack_t *ps ) { + areaReference_t *lref; + portalArea_t *area; + idRenderLightLocal *light; + viewLight_t *vLight; + + area = &portalAreas[ areaNum ]; + + for ( lref = area->lightRefs.areaNext ; lref != &area->lightRefs ; lref = lref->areaNext ) { + light = lref->light; + + // debug tool to allow viewing of only one light at a time + if ( r_singleLight.GetInteger() >= 0 && r_singleLight.GetInteger() != light->index ) { + continue; + } + + // check for being closed off behind a door + // a light that doesn't cast shadows will still light even if it is behind a door + if ( r_useLightCulling.GetInteger() >= 3 && + !light->parms.noShadows && light->lightShader->LightCastsShadows() + && light->areaNum != -1 && !tr.viewDef->connectedAreas[ light->areaNum ] ) { + continue; + } + + // cull frustum + if ( CullLightByPortals( light, ps ) ) { + // we are culled out through this portal chain, but it might + // still be visible through others + continue; + } + + vLight = R_SetLightDefViewLight( light ); + + // expand the scissor rect + vLight->scissorRect.Union( ps->rect ); + } +} + +/* +=================== +AddAreaRefs + +This may be entered multiple times with different planes +if more than one portal sees into the area +=================== +*/ +void idRenderWorldLocal::AddAreaRefs( int areaNum, const portalStack_t *ps ) { + // mark the viewCount, so r_showPortals can display the + // considered portals + portalAreas[ areaNum ].viewCount = tr.viewCount; + + // add the models and lights, using more precise culling to the planes + AddAreaEntityRefs( areaNum, ps ); + AddAreaLightRefs( areaNum, ps ); +} + +/* +=================== +BuildConnectedAreas_r +=================== +*/ +void idRenderWorldLocal::BuildConnectedAreas_r( int areaNum ) { + portalArea_t *area; + portal_t *portal; + + if ( tr.viewDef->connectedAreas[areaNum] ) { + return; + } + + tr.viewDef->connectedAreas[areaNum] = true; + + // flood through all non-blocked portals + area = &portalAreas[ areaNum ]; + for ( portal = area->portals ; portal ; portal = portal->next ) { + if ( !(portal->doublePortal->blockingBits & PS_BLOCK_VIEW) ) { + BuildConnectedAreas_r( portal->intoArea ); + } + } +} + +/* +=================== +BuildConnectedAreas + +This is only valid for a given view, not all views in a frame +=================== +*/ +void idRenderWorldLocal::BuildConnectedAreas( void ) { + int i; + + tr.viewDef->connectedAreas = (bool *)R_FrameAlloc( numPortalAreas + * sizeof( tr.viewDef->connectedAreas[0] ) ); + + // if we are outside the world, we can see all areas + if ( tr.viewDef->areaNum == -1 ) { + for ( i = 0 ; i < numPortalAreas ; i++ ) { + tr.viewDef->connectedAreas[i] = true; + } + return; + } + + // start with none visible, and flood fill from the current area + memset( tr.viewDef->connectedAreas, 0, numPortalAreas * sizeof( tr.viewDef->connectedAreas[0] ) ); + BuildConnectedAreas_r( tr.viewDef->areaNum ); +} + +/* +============= +FindViewLightsAndEntites + +All the modelrefs and lightrefs that are in visible areas +will have viewEntitys and viewLights created for them. + +The scissorRects on the viewEntitys and viewLights may be empty if +they were considered, but not actually visible. +============= +*/ +void idRenderWorldLocal::FindViewLightsAndEntities( void ) { + // clear the visible lightDef and entityDef lists + tr.viewDef->viewLights = NULL; + tr.viewDef->viewEntitys = NULL; + + // find the area to start the portal flooding in + if ( !r_usePortals.GetBool() ) { + // debug tool to force no portal culling + tr.viewDef->areaNum = -1; + } else { + tr.viewDef->areaNum = PointInArea( tr.viewDef->initialViewAreaOrigin ); + } + + // determine all possible connected areas for + // light-behind-door culling + BuildConnectedAreas(); + + // bump the view count, invalidating all + // visible areas + tr.viewCount++; + + // flow through all the portals and add models / lights + if ( r_singleArea.GetBool() ) { + // if debugging, only mark this area + // if we are outside the world, don't draw anything + if ( tr.viewDef->areaNum >= 0 ) { + portalStack_t ps; + int i; + static int lastPrintedAreaNum; + + if ( tr.viewDef->areaNum != lastPrintedAreaNum ) { + lastPrintedAreaNum = tr.viewDef->areaNum; + common->Printf( "entering portal area %i\n", tr.viewDef->areaNum ); + } + + for ( i = 0 ; i < 5 ; i++ ) { + ps.portalPlanes[i] = tr.viewDef->frustum[i]; + } + ps.numPortalPlanes = 5; + ps.rect = tr.viewDef->scissor; + + AddAreaRefs( tr.viewDef->areaNum, &ps ); + } + } else { + // note that the center of projection for flowing through portals may + // be a different point than initialViewAreaOrigin for subviews that + // may have the viewOrigin in a solid/invalid area + FlowViewThroughPortals( tr.viewDef->renderView.vieworg, 5, tr.viewDef->frustum ); + } +} + +/* +============== +NumPortals +============== +*/ +int idRenderWorldLocal::NumPortals( void ) const { + return numInterAreaPortals; +} + +/* +============== +FindPortal + +Game code uses this to identify which portals are inside doors. +Returns 0 if no portal contacts the bounds +============== +*/ +qhandle_t idRenderWorldLocal::FindPortal( const idBounds &b ) const { + int i, j; + idBounds wb; + doublePortal_t *portal; + idWinding *w; + + for ( i = 0 ; i < numInterAreaPortals ; i++ ) { + portal = &doublePortals[i]; + w = portal->portals[0]->w; + + wb.Clear(); + for ( j = 0 ; j < w->GetNumPoints() ; j++ ) { + wb.AddPoint( (*w)[j].ToVec3() ); + } + if ( wb.IntersectsBounds( b ) ) { + return i + 1; + } + } + + return 0; +} + +/* +============= +FloodConnectedAreas +============= +*/ +void idRenderWorldLocal::FloodConnectedAreas( portalArea_t *area, int portalAttributeIndex ) { + if ( area->connectedAreaNum[portalAttributeIndex] == connectedAreaNum ) { + return; + } + area->connectedAreaNum[portalAttributeIndex] = connectedAreaNum; + + for ( portal_t *p = area->portals ; p ; p = p->next ) { + if ( !(p->doublePortal->blockingBits & (1<intoArea], portalAttributeIndex ); + } + } +} + +/* +============== +AreasAreConnected + +============== +*/ +bool idRenderWorldLocal::AreasAreConnected( int areaNum1, int areaNum2, portalConnection_t connection ) { + if ( areaNum1 == -1 || areaNum2 == -1 ) { + return false; + } + if ( areaNum1 > numPortalAreas || areaNum2 > numPortalAreas || areaNum1 < 0 || areaNum2 < 0 ) { + common->Error( "idRenderWorldLocal::AreAreasConnected: bad parms: %i, %i", areaNum1, areaNum2 ); + } + + int attribute = 0; + + int intConnection = (int)connection; + + while ( intConnection > 1 ) { + attribute++; + intConnection >>= 1; + } + if ( attribute >= NUM_PORTAL_ATTRIBUTES || ( 1 << attribute ) != (int)connection ) { + common->Error( "idRenderWorldLocal::AreasAreConnected: bad connection number: %i\n", (int)connection ); + } + + return portalAreas[areaNum1].connectedAreaNum[attribute] == portalAreas[areaNum2].connectedAreaNum[attribute]; +} + + +/* +============== +SetPortalState + +doors explicitly close off portals when shut +============== +*/ +void idRenderWorldLocal::SetPortalState( qhandle_t portal, int blockTypes ) { + if ( portal == 0 ) { + return; + } + + if ( portal < 1 || portal > numInterAreaPortals ) { + common->Error( "SetPortalState: bad portal number %i", portal ); + } + int old = doublePortals[portal-1].blockingBits; + if ( old == blockTypes ) { + return; + } + doublePortals[portal-1].blockingBits = blockTypes; + + // leave the connectedAreaGroup the same on one side, + // then flood fill from the other side with a new number for each changed attribute + for ( int i = 0 ; i < NUM_PORTAL_ATTRIBUTES ; i++ ) { + if ( ( old ^ blockTypes ) & ( 1 << i ) ) { + connectedAreaNum++; + FloodConnectedAreas( &portalAreas[doublePortals[portal-1].portals[1]->intoArea], i ); + } + } + + if ( session->writeDemo ) { + session->writeDemo->WriteInt( DS_RENDER ); + session->writeDemo->WriteInt( DC_SET_PORTAL_STATE ); + session->writeDemo->WriteInt( portal ); + session->writeDemo->WriteInt( blockTypes ); + } +} + +/* +============== +GetPortalState +============== +*/ +int idRenderWorldLocal::GetPortalState( qhandle_t portal ) { + if ( portal == 0 ) { + return 0; + } + + if ( portal < 1 || portal > numInterAreaPortals ) { + common->Error( "GetPortalState: bad portal number %i", portal ); + } + + return doublePortals[portal-1].blockingBits; +} + +/* +===================== +idRenderWorldLocal::ShowPortals + +Debugging tool, won't work correctly with SMP or when mirrors are present +===================== +*/ +void idRenderWorldLocal::ShowPortals() { + int i, j; + portalArea_t *area; + portal_t *p; + idWinding *w; + + // flood out through portals, setting area viewCount + for ( i = 0 ; i < numPortalAreas ; i++ ) { + area = &portalAreas[i]; + if ( area->viewCount != tr.viewCount ) { + continue; + } + for ( p = area->portals ; p ; p = p->next ) { + w = p->w; + if ( !w ) { + continue; + } + + if ( portalAreas[ p->intoArea ].viewCount != tr.viewCount ) { + // red = can't see + qglColor3f( 1, 0, 0 ); + } else { + // green = see through + qglColor3f( 0, 1, 0 ); + } + + qglBegin( GL_LINE_LOOP ); + for ( j = 0 ; j < w->GetNumPoints() ; j++ ) { + qglVertex3fv( (*w)[j].ToFloatPtr() ); + } + qglEnd(); + } + } +} diff --git a/renderer/VertexCache.cpp b/renderer/VertexCache.cpp new file mode 100644 index 000000000..ffa7f68c6 --- /dev/null +++ b/renderer/VertexCache.cpp @@ -0,0 +1,554 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +static const int FRAME_MEMORY_BYTES = 0x200000; +static const int EXPAND_HEADERS = 1024; + +idCVar idVertexCache::r_showVertexCache( "r_showVertexCache", "0", CVAR_INTEGER|CVAR_RENDERER, "" ); +idCVar idVertexCache::r_vertexBufferMegs( "r_vertexBufferMegs", "32", CVAR_INTEGER|CVAR_RENDERER, "" ); + +idVertexCache vertexCache; + +/* +============== +R_ListVertexCache_f +============== +*/ +static void R_ListVertexCache_f( const idCmdArgs &args ) { + vertexCache.List(); +} + +/* +============== +idVertexCache::ActuallyFree +============== +*/ +void idVertexCache::ActuallyFree( vertCache_t *block ) { + if (!block) { + common->Error( "idVertexCache Free: NULL pointer" ); + } + + if ( block->user ) { + // let the owner know we have purged it + *block->user = NULL; + block->user = NULL; + } + + // temp blocks are in a shared space that won't be freed + if ( block->tag != TAG_TEMP ) { + staticAllocTotal -= block->size; + staticCountTotal--; + + if ( block->vbo ) { +#if 0 // this isn't really necessary, it will be reused soon enough + // filling with zero length data is the equivalent of freeing + qglBindBufferARB(GL_ARRAY_BUFFER_ARB, block->vbo); + qglBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, 0, GL_DYNAMIC_DRAW_ARB); +#endif + } else if ( block->virtMem ) { + Mem_Free( block->virtMem ); + block->virtMem = NULL; + } + } + block->tag = TAG_FREE; // mark as free + + // unlink stick it back on the free list + block->next->prev = block->prev; + block->prev->next = block->next; + +#if 1 + // stick it on the front of the free list so it will be reused immediately + block->next = freeStaticHeaders.next; + block->prev = &freeStaticHeaders; +#else + // stick it on the back of the free list so it won't be reused soon (just for debugging) + block->next = &freeStaticHeaders; + block->prev = freeStaticHeaders.prev; +#endif + + block->next->prev = block; + block->prev->next = block; +} + +/* +============== +idVertexCache::Position + +this will be a real pointer with virtual memory, +but it will be an int offset cast to a pointer with +ARB_vertex_buffer_object + +The ARB_vertex_buffer_object will be bound +============== +*/ +void *idVertexCache::Position( vertCache_t *buffer ) { + if ( !buffer || buffer->tag == TAG_FREE ) { + common->FatalError( "idVertexCache::Position: bad vertCache_t" ); + } + + // the ARB vertex object just uses an offset + if ( buffer->vbo ) { + if ( r_showVertexCache.GetInteger() == 2 ) { + if ( buffer->tag == TAG_TEMP ) { + common->Printf( "GL_ARRAY_BUFFER_ARB = %i + %i (%i bytes)\n", buffer->vbo, buffer->offset, buffer->size ); + } else { + common->Printf( "GL_ARRAY_BUFFER_ARB = %i (%i bytes)\n", buffer->vbo, buffer->size ); + } + } + if ( buffer->indexBuffer ) { + qglBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, buffer->vbo ); + } else { + qglBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer->vbo ); + } + return (void *)buffer->offset; + } + + // virtual memory is a real pointer + return (void *)((byte *)buffer->virtMem + buffer->offset); +} + +void idVertexCache::UnbindIndex() { + qglBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); +} + + +//================================================================================ + +/* +=========== +idVertexCache::Init +=========== +*/ +void idVertexCache::Init() { + cmdSystem->AddCommand( "listVertexCache", R_ListVertexCache_f, CMD_FL_RENDERER, "lists vertex cache" ); + + if ( r_vertexBufferMegs.GetInteger() < 8 ) { + r_vertexBufferMegs.SetInteger( 8 ); + } + + virtualMemory = false; + + // use ARB_vertex_buffer_object unless explicitly disabled + if( r_useVertexBuffers.GetInteger() && glConfig.ARBVertexBufferObjectAvailable ) { + common->Printf( "using ARB_vertex_buffer_object memory\n" ); + } else { + virtualMemory = true; + r_useIndexBuffers.SetBool( false ); + common->Printf( "WARNING: vertex array range in virtual memory (SLOW)\n" ); + } + + // initialize the cache memory blocks + freeStaticHeaders.next = freeStaticHeaders.prev = &freeStaticHeaders; + staticHeaders.next = staticHeaders.prev = &staticHeaders; + freeDynamicHeaders.next = freeDynamicHeaders.prev = &freeDynamicHeaders; + dynamicHeaders.next = dynamicHeaders.prev = &dynamicHeaders; + deferredFreeList.next = deferredFreeList.prev = &deferredFreeList; + + // set up the dynamic frame memory + frameBytes = FRAME_MEMORY_BYTES; + staticAllocTotal = 0; + + byte *junk = (byte *)Mem_Alloc( frameBytes ); + for ( int i = 0 ; i < NUM_VERTEX_FRAMES ; i++ ) { + allocatingTempBuffer = true; // force the alloc to use GL_STREAM_DRAW_ARB + Alloc( junk, frameBytes, &tempBuffers[i] ); + allocatingTempBuffer = false; + tempBuffers[i]->tag = TAG_FIXED; + // unlink these from the static list, so they won't ever get purged + tempBuffers[i]->next->prev = tempBuffers[i]->prev; + tempBuffers[i]->prev->next = tempBuffers[i]->next; + } + Mem_Free( junk ); + + EndFrame(); +} + +/* +=========== +idVertexCache::PurgeAll + +Used when toggling vertex programs on or off, because +the cached data isn't valid +=========== +*/ +void idVertexCache::PurgeAll() { + while( staticHeaders.next != &staticHeaders ) { + ActuallyFree( staticHeaders.next ); + } +} + +/* +=========== +idVertexCache::Shutdown +=========== +*/ +void idVertexCache::Shutdown() { +// PurgeAll(); // !@#: also purge the temp buffers + + headerAllocator.Shutdown(); +} + +/* +=========== +idVertexCache::Alloc +=========== +*/ +void idVertexCache::Alloc( void *data, int size, vertCache_t **buffer, bool indexBuffer ) { + vertCache_t *block; + + if ( size <= 0 ) { + common->Error( "idVertexCache::Alloc: size = %i\n", size ); + } + + // if we can't find anything, it will be NULL + *buffer = NULL; + + // if we don't have any remaining unused headers, allocate some more + if ( freeStaticHeaders.next == &freeStaticHeaders ) { + + for ( int i = 0; i < EXPAND_HEADERS; i++ ) { + block = headerAllocator.Alloc(); + block->next = freeStaticHeaders.next; + block->prev = &freeStaticHeaders; + block->next->prev = block; + block->prev->next = block; + + if( !virtualMemory ) { + qglGenBuffersARB( 1, & block->vbo ); + } + } + } + + // move it from the freeStaticHeaders list to the staticHeaders list + block = freeStaticHeaders.next; + block->next->prev = block->prev; + block->prev->next = block->next; + block->next = staticHeaders.next; + block->prev = &staticHeaders; + block->next->prev = block; + block->prev->next = block; + + block->size = size; + block->offset = 0; + block->tag = TAG_USED; + + // save data for debugging + staticAllocThisFrame += block->size; + staticCountThisFrame++; + staticCountTotal++; + staticAllocTotal += block->size; + + // this will be set to zero when it is purged + block->user = buffer; + *buffer = block; + + // allocation doesn't imply used-for-drawing, because at level + // load time lots of things may be created, but they aren't + // referenced by the GPU yet, and can be purged if needed. + block->frameUsed = currentFrame - NUM_VERTEX_FRAMES; + + block->indexBuffer = indexBuffer; + + // copy the data + if ( block->vbo ) { + if ( indexBuffer ) { + qglBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, block->vbo ); + qglBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STATIC_DRAW_ARB ); + } else { + qglBindBufferARB( GL_ARRAY_BUFFER_ARB, block->vbo ); + if ( allocatingTempBuffer ) { + qglBufferDataARB( GL_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STREAM_DRAW_ARB ); + } else { + qglBufferDataARB( GL_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STATIC_DRAW_ARB ); + } + } + } else { + block->virtMem = Mem_Alloc( size ); + SIMDProcessor->Memcpy( block->virtMem, data, size ); + } +} + +/* +=========== +idVertexCache::Touch +=========== +*/ +void idVertexCache::Touch( vertCache_t *block ) { + if ( !block ) { + common->Error( "idVertexCache Touch: NULL pointer" ); + } + + if ( block->tag == TAG_FREE ) { + common->FatalError( "idVertexCache Touch: freed pointer" ); + } + if ( block->tag == TAG_TEMP ) { + common->FatalError( "idVertexCache Touch: temporary pointer" ); + } + + block->frameUsed = currentFrame; + + // move to the head of the LRU list + block->next->prev = block->prev; + block->prev->next = block->next; + + block->next = staticHeaders.next; + block->prev = &staticHeaders; + staticHeaders.next->prev = block; + staticHeaders.next = block; +} + +/* +=========== +idVertexCache::Free +=========== +*/ +void idVertexCache::Free( vertCache_t *block ) { + if (!block) { + return; + } + + if ( block->tag == TAG_FREE ) { + common->FatalError( "idVertexCache Free: freed pointer" ); + } + if ( block->tag == TAG_TEMP ) { + common->FatalError( "idVertexCache Free: temporary pointer" ); + } + + // this block still can't be purged until the frame count has expired, + // but it won't need to clear a user pointer when it is + block->user = NULL; + + block->next->prev = block->prev; + block->prev->next = block->next; + + block->next = deferredFreeList.next; + block->prev = &deferredFreeList; + deferredFreeList.next->prev = block; + deferredFreeList.next = block; +} + +/* +=========== +idVertexCache::AllocFrameTemp + +A frame temp allocation must never be allowed to fail due to overflow. +We can't simply sync with the GPU and overwrite what we have, because +there may still be future references to dynamically created surfaces. +=========== +*/ +vertCache_t *idVertexCache::AllocFrameTemp( void *data, int size ) { + vertCache_t *block; + + if ( size <= 0 ) { + common->Error( "idVertexCache::AllocFrameTemp: size = %i\n", size ); + } + + if ( dynamicAllocThisFrame + size > frameBytes ) { + // if we don't have enough room in the temp block, allocate a static block, + // but immediately free it so it will get freed at the next frame + tempOverflow = true; + Alloc( data, size, &block ); + Free( block); + return block; + } + + // this data is just going on the shared dynamic list + + // if we don't have any remaining unused headers, allocate some more + if ( freeDynamicHeaders.next == &freeDynamicHeaders ) { + + for ( int i = 0; i < EXPAND_HEADERS; i++ ) { + block = headerAllocator.Alloc(); + block->next = freeDynamicHeaders.next; + block->prev = &freeDynamicHeaders; + block->next->prev = block; + block->prev->next = block; + } + } + + // move it from the freeDynamicHeaders list to the dynamicHeaders list + block = freeDynamicHeaders.next; + block->next->prev = block->prev; + block->prev->next = block->next; + block->next = dynamicHeaders.next; + block->prev = &dynamicHeaders; + block->next->prev = block; + block->prev->next = block; + + block->size = size; + block->tag = TAG_TEMP; + block->indexBuffer = false; + block->offset = dynamicAllocThisFrame; + dynamicAllocThisFrame += block->size; + dynamicCountThisFrame++; + block->user = NULL; + block->frameUsed = 0; + + // copy the data + block->virtMem = tempBuffers[listNum]->virtMem; + block->vbo = tempBuffers[listNum]->vbo; + + if ( block->vbo ) { + qglBindBufferARB( GL_ARRAY_BUFFER_ARB, block->vbo ); + qglBufferSubDataARB( GL_ARRAY_BUFFER_ARB, block->offset, (GLsizeiptrARB)size, data ); + } else { + SIMDProcessor->Memcpy( (byte *)block->virtMem + block->offset, data, size ); + } + + return block; +} + +/* +=========== +idVertexCache::EndFrame +=========== +*/ +void idVertexCache::EndFrame() { + // display debug information + if ( r_showVertexCache.GetBool() ) { + int staticUseCount = 0; + int staticUseSize = 0; + + for ( vertCache_t *block = staticHeaders.next ; block != &staticHeaders ; block = block->next ) { + if ( block->frameUsed == currentFrame ) { + staticUseCount++; + staticUseSize += block->size; + } + } + + const char *frameOverflow = tempOverflow ? "(OVERFLOW)" : ""; + + common->Printf( "vertex dynamic:%i=%ik%s, static alloc:%i=%ik used:%i=%ik total:%i=%ik\n", + dynamicCountThisFrame, dynamicAllocThisFrame/1024, frameOverflow, + staticCountThisFrame, staticAllocThisFrame/1024, + staticUseCount, staticUseSize/1024, + staticCountTotal, staticAllocTotal/1024 ); + } + +#if 0 + // if our total static count is above our working memory limit, start purging things + while ( staticAllocTotal > r_vertexBufferMegs.GetInteger() * 1024 * 1024 ) { + // free the least recently used + + } +#endif + + if( !virtualMemory ) { + // unbind vertex buffers so normal virtual memory will be used in case + // r_useVertexBuffers / r_useIndexBuffers + qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + qglBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); + } + + + currentFrame = tr.frameCount; + listNum = currentFrame % NUM_VERTEX_FRAMES; + staticAllocThisFrame = 0; + staticCountThisFrame = 0; + dynamicAllocThisFrame = 0; + dynamicCountThisFrame = 0; + tempOverflow = false; + + // free all the deferred free headers + while( deferredFreeList.next != &deferredFreeList ) { + ActuallyFree( deferredFreeList.next ); + } + + // free all the frame temp headers + vertCache_t *block = dynamicHeaders.next; + if ( block != &dynamicHeaders ) { + block->prev = &freeDynamicHeaders; + dynamicHeaders.prev->next = freeDynamicHeaders.next; + freeDynamicHeaders.next->prev = dynamicHeaders.prev; + freeDynamicHeaders.next = block; + + dynamicHeaders.next = dynamicHeaders.prev = &dynamicHeaders; + } +} + +/* +============= +idVertexCache::List +============= +*/ +void idVertexCache::List( void ) { + int numActive = 0; + int numDeferred = 0; + int frameStatic = 0; + int totalStatic = 0; + int deferredSpace = 0; + + vertCache_t *block; + for ( block = staticHeaders.next ; block != &staticHeaders ; block = block->next) { + numActive++; + + totalStatic += block->size; + if ( block->frameUsed == currentFrame ) { + frameStatic += block->size; + } + } + + int numFreeStaticHeaders = 0; + for ( block = freeStaticHeaders.next ; block != &freeStaticHeaders ; block = block->next ) { + numFreeStaticHeaders++; + } + + int numFreeDynamicHeaders = 0; + for ( block = freeDynamicHeaders.next ; block != &freeDynamicHeaders ; block = block->next ) { + numFreeDynamicHeaders++; + } + + common->Printf( "%i megs working set\n", r_vertexBufferMegs.GetInteger() ); + common->Printf( "%i dynamic temp buffers of %ik\n", NUM_VERTEX_FRAMES, frameBytes / 1024 ); + common->Printf( "%5i active static headers\n", numActive ); + common->Printf( "%5i free static headers\n", numFreeStaticHeaders ); + common->Printf( "%5i free dynamic headers\n", numFreeDynamicHeaders ); + + if ( !virtualMemory ) { + common->Printf( "Vertex cache is in ARB_vertex_buffer_object memory (FAST).\n"); + } else { + common->Printf( "Vertex cache is in virtual memory (SLOW)\n" ); + } + + if ( r_useIndexBuffers.GetBool() ) { + common->Printf( "Index buffers are accelerated.\n" ); + } else { + common->Printf( "Index buffers are not used.\n" ); + } +} + +/* +============= +idVertexCache::IsFast + +just for gfxinfo printing +============= +*/ +bool idVertexCache::IsFast() { + if ( virtualMemory ) { + return false; + } + return true; +} diff --git a/renderer/VertexCache.h b/renderer/VertexCache.h new file mode 100644 index 000000000..75de74cc0 --- /dev/null +++ b/renderer/VertexCache.h @@ -0,0 +1,134 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// vertex cache calls should only be made by the front end + +const int NUM_VERTEX_FRAMES = 2; + +typedef enum { + TAG_FREE, + TAG_USED, + TAG_FIXED, // for the temp buffers + TAG_TEMP // in frame temp area, not static area +} vertBlockTag_t; + +typedef struct vertCache_s { + GLuint vbo; + void *virtMem; // only one of vbo / virtMem will be set + bool indexBuffer; // holds indexes instead of vertexes + + int offset; + int size; // may be larger than the amount asked for, due + // to round up and minimum fragment sizes + int tag; // a tag of 0 is a free block + struct vertCache_s ** user; // will be set to zero when purged + struct vertCache_s *next, *prev; // may be on the static list or one of the frame lists + int frameUsed; // it can't be purged if near the current frame +} vertCache_t; + + +class idVertexCache { +public: + void Init(); + void Shutdown(); + + // just for gfxinfo printing + bool IsFast(); + + // called when vertex programs are enabled or disabled, because + // the cached data is no longer valid + void PurgeAll(); + + // Tries to allocate space for the given data in fast vertex + // memory, and copies it over. + // Alloc does NOT do a touch, which allows purging of things + // created at level load time even if a frame hasn't passed yet. + // These allocations can be purged, which will zero the pointer. + void Alloc( void *data, int bytes, vertCache_t **buffer, bool indexBuffer = false ); + + // This will be a real pointer with virtual memory, + // but it will be an int offset cast to a pointer of ARB_vertex_buffer_object + void * Position( vertCache_t *buffer ); + + // if r_useIndexBuffers is enabled, but you need to draw something without + // an indexCache, this must be called to reset GL_ELEMENT_ARRAY_BUFFER_ARB + void UnbindIndex(); + + // automatically freed at the end of the next frame + // used for specular texture coordinates and gui drawing, which + // will change every frame. + // will return NULL if the vertex cache is completely full + // As with Position(), this may not actually be a pointer you can access. + vertCache_t * AllocFrameTemp( void *data, int bytes ); + + // notes that a buffer is used this frame, so it can't be purged + // out from under the GPU + void Touch( vertCache_t *buffer ); + + // this block won't have to zero a buffer pointer when it is purged, + // but it must still wait for the frames to pass, in case the GPU + // is still referencing it + void Free( vertCache_t *buffer ); + + // updates the counter for determining which temp space to use + // and which blocks can be purged + // Also prints debugging info when enabled + void EndFrame(); + + // listVertexCache calls this + void List(); + +private: + void InitMemoryBlocks( int size ); + void ActuallyFree( vertCache_t *block ); + + static idCVar r_showVertexCache; + static idCVar r_vertexBufferMegs; + + int staticCountTotal; + int staticAllocTotal; // for end of frame purging + + int staticAllocThisFrame; // debug counter + int staticCountThisFrame; + int dynamicAllocThisFrame; + int dynamicCountThisFrame; + + int currentFrame; // for purgable block tracking + int listNum; // currentFrame % NUM_VERTEX_FRAMES, determines which tempBuffers to use + + bool virtualMemory; // not fast stuff + + bool allocatingTempBuffer; // force GL_STREAM_DRAW_ARB + + vertCache_t *tempBuffers[NUM_VERTEX_FRAMES]; // allocated at startup + bool tempOverflow; // had to alloc a temp in static memory + + idBlockAlloc headerAllocator; + + vertCache_t freeStaticHeaders; // head of doubly linked list + vertCache_t freeDynamicHeaders; // head of doubly linked list + vertCache_t dynamicHeaders; // head of doubly linked list + vertCache_t deferredFreeList; // head of doubly linked list + vertCache_t staticHeaders; // head of doubly linked list in MRU order, + // staticHeaders.next is most recently used + + int frameBytes; // for each of NUM_VERTEX_FRAMES frames +}; + +extern idVertexCache vertexCache; diff --git a/renderer/cg_explicit.cpp b/renderer/cg_explicit.cpp new file mode 100644 index 000000000..bb18cf11e --- /dev/null +++ b/renderer/cg_explicit.cpp @@ -0,0 +1,414 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +//#include +//#include +#include "cg_explicit.h" + +PFNCGCREATECONTEXTPROC cgCreateContext; +PFNCGDESTROYCONTEXTPROC cgDestroyContext; +PFNCGISCONTEXTPROC cgIsContext; +PFNCGGETLASTLISTINGPROC cgGetLastListing; +PFNCGCREATEPROGRAMPROC cgCreateProgram; +PFNCGCREATEPROGRAMFROMFILEPROC cgCreateProgramFromFile; +PFNCGCOPYPROGRAMPROC cgCopyProgram; +PFNCGDESTROYPROGRAMPROC cgDestroyProgram; +PFNCGGETFIRSTPROGRAMPROC cgGetFirstProgram; +PFNCGGETNEXTPROGRAMPROC cgGetNextProgram; +PFNCGGETPROGRAMCONTEXTPROC cgGetProgramContext; +PFNCGISPROGRAMPROC cgIsProgram; +PFNCGCOMPILEPROGRAMPROC cgCompileProgram; +PFNCGISPROGRAMCOMPILEDPROC cgIsProgramCompiled; +PFNCGGETPROGRAMSTRINGPROC cgGetProgramString; +PFNCGGETPROGRAMPROFILEPROC cgGetProgramProfile; +PFNCGGETNAMEDPARAMETERPROC cgGetNamedParameter; +PFNCGGETFIRSTPARAMETERPROC cgGetFirstParameter; +PFNCGGETNEXTPARAMETERPROC cgGetNextParameter; +PFNCGGETFIRSTLEAFPARAMETERPROC cgGetFirstLeafParameter; +PFNCGGETNEXTLEAFPARAMETERPROC cgGetNextLeafParameter; +PFNCGGETFIRSTSTRUCTPARAMETERPROC cgGetFirstStructParameter; +PFNCGGETFIRSTDEPENDENTPARAMETERPROC cgGetFirstDependentParameter; +PFNCGGETARRAYPARAMETERPROC cgGetArrayParameter; +PFNCGGETARRAYDIMENSIONPROC cgGetArrayDimension; +PFNCGGETARRAYSIZEPROC cgGetArraySize; +PFNCGGETPARAMETERPROGRAMPROC cgGetParameterProgram; +PFNCGISPARAMETERPROC cgIsParameter; +PFNCGGETPARAMETERNAMEPROC cgGetParameterName; +PFNCGGETPARAMETERTYPEPROC cgGetParameterType; +PFNCGGETPARAMETERSEMANTICPROC cgGetParameterSemantic; +PFNCGGETPARAMETERRESOURCEPROC cgGetParameterResource; +PFNCGGETPARAMETERBASERESOURCEPROC cgGetParameterBaseResource; +PFNCGGETPARAMETERRESOURCEINDEXPROC cgGetParameterResourceIndex; +PFNCGGETPARAMETERVARIABILITYPROC cgGetParameterVariability; +PFNCGGETPARAMETERDIRECTIONPROC cgGetParameterDirection; +PFNCGISPARAMETERREFERENCEDPROC cgIsParameterReferenced; +PFNCGGETPARAMETERVALUESPROC cgGetParameterValues; +PFNCGGETTYPESTRINGPROC cgGetTypeString; +PFNCGGETTYPEPROC cgGetType; +PFNCGGETRESOURCESTRINGPROC cgGetResourceString; +PFNCGGETRESOURCEPROC cgGetResource; +PFNCGGETPROFILESTRINGPROC cgGetProfileString; +PFNCGGETPROFILEPROC cgGetProfile; +PFNCGGETERRORPROC cgGetError; +PFNCGGETERRORSTRINGPROC cgGetErrorString; +PFNCGSETERRORCALLBACKPROC cgSetErrorCallback; +PFNCGGETERRORCALLBACKPROC cgGetErrorCallback; +PFNCGGLISPROFILESUPPORTEDPROC cgGLIsProfileSupported; +PFNCGGLENABLEPROFILEPROC cgGLEnableProfile; +PFNCGGLDISABLEPROFILEPROC cgGLDisableProfile; +PFNCGGLGETLATESTPROFILEPROC cgGLGetLatestProfile; +PFNCGGLSETOPTIMALOPTIONSPROC cgGLSetOptimalOptions; +PFNCGGLLOADPROGRAMPROC cgGLLoadProgram; +PFNCGGLBINDPROGRAMPROC cgGLBindProgram; +PFNCGGLSETPARAMETER1FPROC cgGLSetParameter1f; +PFNCGGLSETPARAMETER2FPROC cgGLSetParameter2f; +PFNCGGLSETPARAMETER3FPROC cgGLSetParameter3f; +PFNCGGLSETPARAMETER4FPROC cgGLSetParameter4f; +PFNCGGLSETPARAMETER1FVPROC cgGLSetParameter1fv; +PFNCGGLSETPARAMETER2FVPROC cgGLSetParameter2fv; +PFNCGGLSETPARAMETER3FVPROC cgGLSetParameter3fv; +PFNCGGLSETPARAMETER4FVPROC cgGLSetParameter4fv; +PFNCGGLSETPARAMETER1DPROC cgGLSetParameter1d; +PFNCGGLSETPARAMETER2DPROC cgGLSetParameter2d; +PFNCGGLSETPARAMETER3DPROC cgGLSetParameter3d; +PFNCGGLSETPARAMETER4DPROC cgGLSetParameter4d; +PFNCGGLSETPARAMETER1DVPROC cgGLSetParameter1dv; +PFNCGGLSETPARAMETER2DVPROC cgGLSetParameter2dv; +PFNCGGLSETPARAMETER3DVPROC cgGLSetParameter3dv; +PFNCGGLSETPARAMETER4DVPROC cgGLSetParameter4dv; +PFNCGGLGETPARAMETER1FPROC cgGLGetParameter1f; +PFNCGGLGETPARAMETER2FPROC cgGLGetParameter2f; +PFNCGGLGETPARAMETER3FPROC cgGLGetParameter3f; +PFNCGGLGETPARAMETER4FPROC cgGLGetParameter4f; +PFNCGGLGETPARAMETER1DPROC cgGLGetParameter1d; +PFNCGGLGETPARAMETER2DPROC cgGLGetParameter2d; +PFNCGGLGETPARAMETER3DPROC cgGLGetParameter3d; +PFNCGGLGETPARAMETER4DPROC cgGLGetParameter4d; +PFNCGGLSETPARAMETERARRAY1FPROC cgGLSetParameterArray1f; +PFNCGGLSETPARAMETERARRAY2FPROC cgGLSetParameterArray2f; +PFNCGGLSETPARAMETERARRAY3FPROC cgGLSetParameterArray3f; +PFNCGGLSETPARAMETERARRAY4FPROC cgGLSetParameterArray4f; +PFNCGGLSETPARAMETERARRAY1DPROC cgGLSetParameterArray1d; +PFNCGGLSETPARAMETERARRAY2DPROC cgGLSetParameterArray2d; +PFNCGGLSETPARAMETERARRAY3DPROC cgGLSetParameterArray3d; +PFNCGGLSETPARAMETERARRAY4DPROC cgGLSetParameterArray4d; +PFNCGGLGETPARAMETERARRAY1FPROC cgGLGetParameterArray1f; +PFNCGGLGETPARAMETERARRAY2FPROC cgGLGetParameterArray2f; +PFNCGGLGETPARAMETERARRAY3FPROC cgGLGetParameterArray3f; +PFNCGGLGETPARAMETERARRAY4FPROC cgGLGetParameterArray4f; +PFNCGGLGETPARAMETERARRAY1DPROC cgGLGetParameterArray1d; +PFNCGGLGETPARAMETERARRAY2DPROC cgGLGetParameterArray2d; +PFNCGGLGETPARAMETERARRAY3DPROC cgGLGetParameterArray3d; +PFNCGGLGETPARAMETERARRAY4DPROC cgGLGetParameterArray4d; +PFNCGGLSETPARAMETERPOINTERPROC cgGLSetParameterPointer; +PFNCGGLENABLECLIENTSTATEPROC cgGLEnableClientState; +PFNCGGLDISABLECLIENTSTATEPROC cgGLDisableClientState; +PFNCGGLSETMATRIXPARAMETERDRPROC cgGLSetMatrixParameterdr; +PFNCGGLSETMATRIXPARAMETERFRPROC cgGLSetMatrixParameterfr; +PFNCGGLSETMATRIXPARAMETERDCPROC cgGLSetMatrixParameterdc; +PFNCGGLSETMATRIXPARAMETERFCPROC cgGLSetMatrixParameterfc; +PFNCGGLGETMATRIXPARAMETERDRPROC cgGLGetMatrixParameterdr; +PFNCGGLGETMATRIXPARAMETERFRPROC cgGLGetMatrixParameterfr; +PFNCGGLGETMATRIXPARAMETERDCPROC cgGLGetMatrixParameterdc; +PFNCGGLGETMATRIXPARAMETERFCPROC cgGLGetMatrixParameterfc; +PFNCGGLSETSTATEMATRIXPARAMETERPROC cgGLSetStateMatrixParameter; +PFNCGGLSETMATRIXPARAMETERARRAYFCPROC cgGLSetMatrixParameterArrayfc; +PFNCGGLSETMATRIXPARAMETERARRAYFRPROC cgGLSetMatrixParameterArrayfr; +PFNCGGLSETMATRIXPARAMETERARRAYDCPROC cgGLSetMatrixParameterArraydc; +PFNCGGLSETMATRIXPARAMETERARRAYDRPROC cgGLSetMatrixParameterArraydr; +PFNCGGLGETMATRIXPARAMETERARRAYFCPROC cgGLGetMatrixParameterArrayfc; +PFNCGGLGETMATRIXPARAMETERARRAYFRPROC cgGLGetMatrixParameterArrayfr; +PFNCGGLGETMATRIXPARAMETERARRAYDCPROC cgGLGetMatrixParameterArraydc; +PFNCGGLGETMATRIXPARAMETERARRAYDRPROC cgGLGetMatrixParameterArraydr; +PFNCGGLSETTEXTUREPARAMETERPROC cgGLSetTextureParameter; +PFNCGGLGETTEXTUREPARAMETERPROC cgGLGetTextureParameter; +PFNCGGLENABLETEXTUREPARAMETERPROC cgGLEnableTextureParameter; +PFNCGGLDISABLETEXTUREPARAMETERPROC cgGLDisableTextureParameter; +PFNCGGLGETTEXTUREENUMPROC cgGLGetTextureEnum; + +#ifndef _WIN32 +bool init_explicit_Cg() +{ + return false; +} +#else +bool init_explicit_Cg() +{ + HMODULE hmod; + int failed = 0; + + hmod = LoadLibrary("cg.dll"); + + if(0 == (cgCreateContext = (PFNCGCREATECONTEXTPROC)GetProcAddress( hmod, "cgCreateContext" ))) + failed++; + if(0 == (cgDestroyContext = (PFNCGDESTROYCONTEXTPROC)GetProcAddress( hmod, "cgDestroyContext" ))) + failed++; + if(0 == (cgIsContext = (PFNCGISCONTEXTPROC)GetProcAddress( hmod, "cgIsContext" ))) + failed++; + if(0 == (cgGetLastListing = (PFNCGGETLASTLISTINGPROC)GetProcAddress( hmod, "cgGetLastListing" ))) + failed++; + if(0 == (cgCreateProgram = (PFNCGCREATEPROGRAMPROC)GetProcAddress( hmod, "cgCreateProgram" ))) + failed++; + if(0 == (cgCreateProgramFromFile = (PFNCGCREATEPROGRAMFROMFILEPROC)GetProcAddress( hmod, "cgCreateProgramFromFile" ))) + failed++; + if(0 == (cgCopyProgram = (PFNCGCOPYPROGRAMPROC)GetProcAddress( hmod, "cgCopyProgram" ))) + failed++; + if(0 == (cgDestroyProgram = (PFNCGDESTROYPROGRAMPROC)GetProcAddress( hmod, "cgDestroyProgram" ))) + failed++; + if(0 == (cgGetFirstProgram = (PFNCGGETFIRSTPROGRAMPROC)GetProcAddress( hmod, "cgGetFirstProgram" ))) + failed++; + if(0 == (cgGetNextProgram = (PFNCGGETNEXTPROGRAMPROC)GetProcAddress( hmod, "cgGetNextProgram" ))) + failed++; + if(0 == (cgGetProgramContext = (PFNCGGETPROGRAMCONTEXTPROC)GetProcAddress( hmod, "cgGetProgramContext" ))) + failed++; + if(0 == (cgIsProgram = (PFNCGISPROGRAMPROC)GetProcAddress( hmod, "cgIsProgram" ))) + failed++; + if(0 == (cgCompileProgram = (PFNCGCOMPILEPROGRAMPROC)GetProcAddress( hmod, "cgCompileProgram" ))) + failed++; + if(0 == (cgIsProgramCompiled = (PFNCGISPROGRAMCOMPILEDPROC)GetProcAddress( hmod, "cgIsProgramCompiled" ))) + failed++; + if(0 == (cgGetProgramString = (PFNCGGETPROGRAMSTRINGPROC)GetProcAddress( hmod, "cgGetProgramString" ))) + failed++; + if(0 == (cgGetProgramProfile = (PFNCGGETPROGRAMPROFILEPROC)GetProcAddress( hmod, "cgGetProgramProfile" ))) + failed++; + if(0 == (cgGetNamedParameter = (PFNCGGETNAMEDPARAMETERPROC)GetProcAddress( hmod, "cgGetNamedParameter" ))) + failed++; + if(0 == (cgGetFirstParameter = (PFNCGGETFIRSTPARAMETERPROC)GetProcAddress( hmod, "cgGetFirstParameter" ))) + failed++; + if(0 == (cgGetNextParameter = (PFNCGGETNEXTPARAMETERPROC)GetProcAddress( hmod, "cgGetNextParameter" ))) + failed++; + if(0 == (cgGetFirstLeafParameter = (PFNCGGETFIRSTLEAFPARAMETERPROC)GetProcAddress( hmod, "cgGetFirstLeafParameter" ))) + failed++; + if(0 == (cgGetNextLeafParameter = (PFNCGGETNEXTLEAFPARAMETERPROC)GetProcAddress( hmod, "cgGetNextLeafParameter" ))) + failed++; + if(0 == (cgGetFirstStructParameter = (PFNCGGETFIRSTSTRUCTPARAMETERPROC)GetProcAddress( hmod, "cgGetFirstStructParameter" ))) + failed++; + if(0 == (cgGetFirstDependentParameter = (PFNCGGETFIRSTDEPENDENTPARAMETERPROC)GetProcAddress( hmod, "cgGetFirstDependentParameter" ))) + failed++; + if(0 == (cgGetArrayParameter = (PFNCGGETARRAYPARAMETERPROC)GetProcAddress( hmod, "cgGetArrayParameter" ))) + failed++; + if(0 == (cgGetArrayDimension = (PFNCGGETARRAYDIMENSIONPROC)GetProcAddress( hmod, "cgGetArrayDimension" ))) + failed++; + if(0 == (cgGetArraySize = (PFNCGGETARRAYSIZEPROC)GetProcAddress( hmod, "cgGetArraySize" ))) + failed++; + if(0 == (cgGetParameterProgram = (PFNCGGETPARAMETERPROGRAMPROC)GetProcAddress( hmod, "cgGetParameterProgram" ))) + failed++; + if(0 == (cgIsParameter = (PFNCGISPARAMETERPROC)GetProcAddress( hmod, "cgIsParameter" ))) + failed++; + if(0 == (cgGetParameterName = (PFNCGGETPARAMETERNAMEPROC)GetProcAddress( hmod, "cgGetParameterName" ))) + failed++; + if(0 == (cgGetParameterType = (PFNCGGETPARAMETERTYPEPROC)GetProcAddress( hmod, "cgGetParameterType" ))) + failed++; + if(0 == (cgGetParameterSemantic = (PFNCGGETPARAMETERSEMANTICPROC)GetProcAddress( hmod, "cgGetParameterSemantic" ))) + failed++; + if(0 == (cgGetParameterResource = (PFNCGGETPARAMETERRESOURCEPROC)GetProcAddress( hmod, "cgGetParameterResource" ))) + failed++; + if(0 == (cgGetParameterBaseResource = (PFNCGGETPARAMETERBASERESOURCEPROC)GetProcAddress( hmod, "cgGetParameterBaseResource" ))) + failed++; + if(0 == (cgGetParameterResourceIndex = (PFNCGGETPARAMETERRESOURCEINDEXPROC)GetProcAddress( hmod, "cgGetParameterResourceIndex" ))) + failed++; + if(0 == (cgGetParameterVariability = (PFNCGGETPARAMETERVARIABILITYPROC)GetProcAddress( hmod, "cgGetParameterVariability" ))) + failed++; + if(0 == (cgGetParameterDirection = (PFNCGGETPARAMETERDIRECTIONPROC)GetProcAddress( hmod, "cgGetParameterDirection" ))) + failed++; + if(0 == (cgIsParameterReferenced = (PFNCGISPARAMETERREFERENCEDPROC)GetProcAddress( hmod, "cgIsParameterReferenced" ))) + failed++; + if(0 == (cgGetParameterValues = (PFNCGGETPARAMETERVALUESPROC)GetProcAddress( hmod, "cgGetParameterValues" ))) + failed++; + if(0 == (cgGetTypeString = (PFNCGGETTYPESTRINGPROC)GetProcAddress( hmod, "cgGetTypeString" ))) + failed++; + if(0 == (cgGetType = (PFNCGGETTYPEPROC)GetProcAddress( hmod, "cgGetType" ))) + failed++; + if(0 == (cgGetResourceString = (PFNCGGETRESOURCESTRINGPROC)GetProcAddress( hmod, "cgGetResourceString" ))) + failed++; + if(0 == (cgGetResource = (PFNCGGETRESOURCEPROC)GetProcAddress( hmod, "cgGetResource" ))) + failed++; + if(0 == (cgGetProfileString = (PFNCGGETPROFILESTRINGPROC)GetProcAddress( hmod, "cgGetProfileString" ))) + failed++; + if(0 == (cgGetProfile = (PFNCGGETPROFILEPROC)GetProcAddress( hmod, "cgGetProfile" ))) + failed++; + if(0 == (cgGetError = (PFNCGGETERRORPROC)GetProcAddress( hmod, "cgGetError" ))) + failed++; + if(0 == (cgGetErrorString = (PFNCGGETERRORSTRINGPROC)GetProcAddress( hmod, "cgGetErrorString" ))) + failed++; + if(0 == (cgSetErrorCallback = (PFNCGSETERRORCALLBACKPROC)GetProcAddress( hmod, "cgSetErrorCallback" ))) + failed++; + if(0 == (cgGetErrorCallback = (PFNCGGETERRORCALLBACKPROC)GetProcAddress( hmod, "cgGetErrorCallback" ))) + failed++; + + + + hmod = LoadLibrary("cgGL.dll"); + + + + if(0 == (cgGLIsProfileSupported = (PFNCGGLISPROFILESUPPORTEDPROC)GetProcAddress( hmod, "cgGLIsProfileSupported" ))) + failed++; + if(0 == (cgGLEnableProfile = (PFNCGGLENABLEPROFILEPROC)GetProcAddress( hmod, "cgGLEnableProfile" ))) + failed++; + if(0 == (cgGLDisableProfile = (PFNCGGLDISABLEPROFILEPROC)GetProcAddress( hmod, "cgGLDisableProfile" ))) + failed++; + if(0 == (cgGLGetLatestProfile = (PFNCGGLGETLATESTPROFILEPROC)GetProcAddress( hmod, "cgGLGetLatestProfile" ))) + failed++; + if(0 == (cgGLSetOptimalOptions = (PFNCGGLSETOPTIMALOPTIONSPROC)GetProcAddress( hmod, "cgGLSetOptimalOptions" ))) + failed++; + if(0 == (cgGLLoadProgram = (PFNCGGLLOADPROGRAMPROC)GetProcAddress( hmod, "cgGLLoadProgram" ))) + failed++; + if(0 == (cgGLBindProgram = (PFNCGGLBINDPROGRAMPROC)GetProcAddress( hmod, "cgGLBindProgram" ))) + failed++; + if(0 == (cgGLSetParameter1f = (PFNCGGLSETPARAMETER1FPROC)GetProcAddress( hmod, "cgGLSetParameter1f" ))) + failed++; + if(0 == (cgGLSetParameter2f = (PFNCGGLSETPARAMETER2FPROC)GetProcAddress( hmod, "cgGLSetParameter2f" ))) + failed++; + if(0 == (cgGLSetParameter3f = (PFNCGGLSETPARAMETER3FPROC)GetProcAddress( hmod, "cgGLSetParameter3f" ))) + failed++; + if(0 == (cgGLSetParameter4f = (PFNCGGLSETPARAMETER4FPROC)GetProcAddress( hmod, "cgGLSetParameter4f" ))) + failed++; + if(0 == (cgGLSetParameter1fv = (PFNCGGLSETPARAMETER1FVPROC)GetProcAddress( hmod, "cgGLSetParameter1fv" ))) + failed++; + if(0 == (cgGLSetParameter2fv = (PFNCGGLSETPARAMETER2FVPROC)GetProcAddress( hmod, "cgGLSetParameter2fv" ))) + failed++; + if(0 == (cgGLSetParameter3fv = (PFNCGGLSETPARAMETER3FVPROC)GetProcAddress( hmod, "cgGLSetParameter3fv" ))) + failed++; + if(0 == (cgGLSetParameter4fv = (PFNCGGLSETPARAMETER4FVPROC)GetProcAddress( hmod, "cgGLSetParameter4fv" ))) + failed++; + if(0 == (cgGLSetParameter1d = (PFNCGGLSETPARAMETER1DPROC)GetProcAddress( hmod, "cgGLSetParameter1d" ))) + failed++; + if(0 == (cgGLSetParameter2d = (PFNCGGLSETPARAMETER2DPROC)GetProcAddress( hmod, "cgGLSetParameter2d" ))) + failed++; + if(0 == (cgGLSetParameter3d = (PFNCGGLSETPARAMETER3DPROC)GetProcAddress( hmod, "cgGLSetParameter3d" ))) + failed++; + if(0 == (cgGLSetParameter4d = (PFNCGGLSETPARAMETER4DPROC)GetProcAddress( hmod, "cgGLSetParameter4d" ))) + failed++; + if(0 == (cgGLSetParameter1dv = (PFNCGGLSETPARAMETER1DVPROC)GetProcAddress( hmod, "cgGLSetParameter1dv" ))) + failed++; + if(0 == (cgGLSetParameter2dv = (PFNCGGLSETPARAMETER2DVPROC)GetProcAddress( hmod, "cgGLSetParameter2dv" ))) + failed++; + if(0 == (cgGLSetParameter3dv = (PFNCGGLSETPARAMETER3DVPROC)GetProcAddress( hmod, "cgGLSetParameter3dv" ))) + failed++; + if(0 == (cgGLSetParameter4dv = (PFNCGGLSETPARAMETER4DVPROC)GetProcAddress( hmod, "cgGLSetParameter4dv" ))) + failed++; + if(0 == (cgGLSetParameter4dv = (PFNCGGLSETPARAMETER4DVPROC)GetProcAddress( hmod, "cgGLSetParameter4dv" ))) + failed++; + if(0 == (cgGLGetParameter1f = (PFNCGGLGETPARAMETER1FPROC)GetProcAddress( hmod, "cgGLGetParameter1f" ))) + failed++; + if(0 == (cgGLGetParameter2f = (PFNCGGLGETPARAMETER2FPROC)GetProcAddress( hmod, "cgGLGetParameter2f" ))) + failed++; + if(0 == (cgGLGetParameter3f = (PFNCGGLGETPARAMETER3FPROC)GetProcAddress( hmod, "cgGLGetParameter3f" ))) + failed++; + if(0 == (cgGLGetParameter4f = (PFNCGGLGETPARAMETER4FPROC)GetProcAddress( hmod, "cgGLGetParameter4f" ))) + failed++; + if(0 == (cgGLGetParameter1d = (PFNCGGLGETPARAMETER1DPROC)GetProcAddress( hmod, "cgGLGetParameter1d" ))) + failed++; + if(0 == (cgGLGetParameter2d = (PFNCGGLGETPARAMETER2DPROC)GetProcAddress( hmod, "cgGLGetParameter2d" ))) + failed++; + if(0 == (cgGLGetParameter3d = (PFNCGGLGETPARAMETER3DPROC)GetProcAddress( hmod, "cgGLGetParameter3d" ))) + failed++; + if(0 == (cgGLGetParameter4d = (PFNCGGLGETPARAMETER4DPROC)GetProcAddress( hmod, "cgGLGetParameter4d" ))) + failed++; + if(0 == (cgGLSetParameterArray1f = (PFNCGGLSETPARAMETERARRAY1FPROC)GetProcAddress( hmod, "cgGLSetParameterArray1f" ))) + failed++; + if(0 == (cgGLSetParameterArray2f = (PFNCGGLSETPARAMETERARRAY2FPROC)GetProcAddress( hmod, "cgGLSetParameterArray2f" ))) + failed++; + if(0 == (cgGLSetParameterArray3f = (PFNCGGLSETPARAMETERARRAY3FPROC)GetProcAddress( hmod, "cgGLSetParameterArray3f" ))) + failed++; + if(0 == (cgGLSetParameterArray4f = (PFNCGGLSETPARAMETERARRAY4FPROC)GetProcAddress( hmod, "cgGLSetParameterArray4f" ))) + failed++; + if(0 == (cgGLSetParameterArray1d = (PFNCGGLSETPARAMETERARRAY1DPROC)GetProcAddress( hmod, "cgGLSetParameterArray1d" ))) + failed++; + if(0 == (cgGLSetParameterArray2d = (PFNCGGLSETPARAMETERARRAY2DPROC)GetProcAddress( hmod, "cgGLSetParameterArray2d" ))) + failed++; + if(0 == (cgGLSetParameterArray3d = (PFNCGGLSETPARAMETERARRAY3DPROC)GetProcAddress( hmod, "cgGLSetParameterArray3d" ))) + failed++; + if(0 == (cgGLSetParameterArray4d = (PFNCGGLSETPARAMETERARRAY4DPROC)GetProcAddress( hmod, "cgGLSetParameterArray4d" ))) + failed++; + if(0 == (cgGLGetParameterArray1f = (PFNCGGLGETPARAMETERARRAY1FPROC)GetProcAddress( hmod, "cgGLGetParameterArray1f" ))) + failed++; + if(0 == (cgGLGetParameterArray2f = (PFNCGGLGETPARAMETERARRAY2FPROC)GetProcAddress( hmod, "cgGLGetParameterArray2f" ))) + failed++; + if(0 == (cgGLGetParameterArray3f = (PFNCGGLGETPARAMETERARRAY3FPROC)GetProcAddress( hmod, "cgGLGetParameterArray3f" ))) + failed++; + if(0 == (cgGLGetParameterArray4f = (PFNCGGLGETPARAMETERARRAY4FPROC)GetProcAddress( hmod, "cgGLGetParameterArray4f" ))) + failed++; + if(0 == (cgGLGetParameterArray1d = (PFNCGGLGETPARAMETERARRAY1DPROC)GetProcAddress( hmod, "cgGLGetParameterArray1d" ))) + failed++; + if(0 == (cgGLGetParameterArray2d = (PFNCGGLGETPARAMETERARRAY2DPROC)GetProcAddress( hmod, "cgGLGetParameterArray2d" ))) + failed++; + if(0 == (cgGLGetParameterArray3d = (PFNCGGLGETPARAMETERARRAY3DPROC)GetProcAddress( hmod, "cgGLGetParameterArray3d" ))) + failed++; + if(0 == (cgGLGetParameterArray4d = (PFNCGGLGETPARAMETERARRAY4DPROC)GetProcAddress( hmod, "cgGLGetParameterArray4d" ))) + failed++; + if(0 == (cgGLSetParameterPointer = (PFNCGGLSETPARAMETERPOINTERPROC)GetProcAddress( hmod, "cgGLSetParameterPointer" ))) + failed++; + if(0 == (cgGLEnableClientState = (PFNCGGLENABLECLIENTSTATEPROC)GetProcAddress( hmod, "cgGLEnableClientState" ))) + failed++; + if(0 == (cgGLDisableClientState = (PFNCGGLDISABLECLIENTSTATEPROC)GetProcAddress( hmod, "cgGLDisableClientState" ))) + failed++; + if(0 == (cgGLSetMatrixParameterdr = (PFNCGGLSETMATRIXPARAMETERDRPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterdr" ))) + failed++; + if(0 == (cgGLSetMatrixParameterfr = (PFNCGGLSETMATRIXPARAMETERFRPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterfr" ))) + failed++; + if(0 == (cgGLSetMatrixParameterdc = (PFNCGGLSETMATRIXPARAMETERDCPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterdc" ))) + failed++; + if(0 == (cgGLSetMatrixParameterfc = (PFNCGGLSETMATRIXPARAMETERFCPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterfc" ))) + failed++; + if(0 == (cgGLGetMatrixParameterdr = (PFNCGGLGETMATRIXPARAMETERDRPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterdr" ))) + failed++; + if(0 == (cgGLGetMatrixParameterfr = (PFNCGGLGETMATRIXPARAMETERFRPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterfr" ))) + failed++; + if(0 == (cgGLGetMatrixParameterdc = (PFNCGGLGETMATRIXPARAMETERDCPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterdc" ))) + failed++; + if(0 == (cgGLGetMatrixParameterfc = (PFNCGGLGETMATRIXPARAMETERFCPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterfc" ))) + failed++; + if(0 == (cgGLSetStateMatrixParameter = (PFNCGGLSETSTATEMATRIXPARAMETERPROC)GetProcAddress( hmod, "cgGLSetStateMatrixParameter" ))) + failed++; + //if(0 == (cgGLSetMatrixParameterArrayfc = (PFNCGGLSETMATRIXPARAMETERARRAYFCPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterArrayfc" ))) + // failed++; + //if(0 == (cgGLSetMatrixParameterArrayfr = (PFNCGGLSETMATRIXPARAMETERARRAYFRPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterArrayfr" ))) + // failed++; + //if(0 == (cgGLSetMatrixParameterArraydc = (PFNCGGLSETMATRIXPARAMETERARRAYDCPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterArraydc" ))) + // failed++; + //if(0 == (cgGLSetMatrixParameterArraydr = (PFNCGGLSETMATRIXPARAMETERARRAYDRPROC)GetProcAddress( hmod, "cgGLSetMatrixParameterArraydr" ))) + // failed++; + //if(0 == (cgGLGetMatrixParameterArrayfc = (PFNCGGLGETMATRIXPARAMETERARRAYFCPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterArrayfc" ))) + // failed++; + //if(0 == (cgGLGetMatrixParameterArrayfr = (PFNCGGLGETMATRIXPARAMETERARRAYFRPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterArrayfr" ))) + // failed++; + //if(0 == (cgGLGetMatrixParameterArraydc = (PFNCGGLGETMATRIXPARAMETERARRAYDCPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterArraydc" ))) + // failed++; + //if(0 == (cgGLGetMatrixParameterArraydr = (PFNCGGLGETMATRIXPARAMETERARRAYDRPROC)GetProcAddress( hmod, "cgGLGetMatrixParameterArraydr" ))) + // failed++; + if(0 == (cgGLSetTextureParameter = (PFNCGGLSETTEXTUREPARAMETERPROC)GetProcAddress( hmod, "cgGLSetTextureParameter" ))) + failed++; + if(0 == (cgGLGetTextureParameter = (PFNCGGLGETTEXTUREPARAMETERPROC)GetProcAddress( hmod, "cgGLGetTextureParameter" ))) + failed++; + if(0 == (cgGLEnableTextureParameter = (PFNCGGLENABLETEXTUREPARAMETERPROC)GetProcAddress( hmod, "cgGLEnableTextureParameter" ))) + failed++; + if(0 == (cgGLDisableTextureParameter = (PFNCGGLDISABLETEXTUREPARAMETERPROC)GetProcAddress( hmod, "cgGLDisableTextureParameter" ))) + failed++; + if(0 == (cgGLGetTextureEnum = (PFNCGGLGETTEXTUREENUMPROC)GetProcAddress( hmod, "cgGLGetTextureEnum" ))) + failed++; + + return failed == 0; + +} +#endif diff --git a/renderer/cg_explicit.h b/renderer/cg_explicit.h new file mode 100644 index 000000000..d38772a69 --- /dev/null +++ b/renderer/cg_explicit.h @@ -0,0 +1,857 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef CG_EXTERNAL___H +#define CG_EXTERNAL___H + + + +typedef int CGbool; +typedef struct _CGcontext *CGcontext; +typedef struct _CGprogram *CGprogram; +typedef struct _CGparameter *CGparameter; + + +typedef enum +{ + CG_UNKNOWN_TYPE, + CG_STRUCT, + CG_ARRAY, + + CG_TYPE_START_ENUM = 1024, + + + CG_HALF , + CG_HALF2 , + CG_HALF3 , + CG_HALF4 , + CG_HALF1x1 , + CG_HALF1x2 , + CG_HALF1x3 , + CG_HALF1x4 , + CG_HALF2x1 , + CG_HALF2x2 , + CG_HALF2x3 , + CG_HALF2x4 , + CG_HALF3x1 , + CG_HALF3x2 , + CG_HALF3x3 , + CG_HALF3x4 , + CG_HALF4x1 , + CG_HALF4x2 , + CG_HALF4x3 , + CG_HALF4x4 , + CG_FLOAT , + CG_FLOAT2 , + CG_FLOAT3 , + CG_FLOAT4 , + CG_FLOAT1x1 , + CG_FLOAT1x2 , + CG_FLOAT1x3 , + CG_FLOAT1x4 , + CG_FLOAT2x1 , + CG_FLOAT2x2 , + CG_FLOAT2x3 , + CG_FLOAT2x4 , + CG_FLOAT3x1 , + CG_FLOAT3x2 , + CG_FLOAT3x3 , + CG_FLOAT3x4 , + CG_FLOAT4x1 , + CG_FLOAT4x2 , + CG_FLOAT4x3 , + CG_FLOAT4x4 , + CG_SAMPLER1D , + CG_SAMPLER2D , + CG_SAMPLER3D , + CG_SAMPLERRECT , + CG_SAMPLERCUBE , + CG_FIXED , + CG_FIXED2 , + CG_FIXED3 , + CG_FIXED4 , + CG_FIXED1x1 , + CG_FIXED1x2 , + CG_FIXED1x3 , + CG_FIXED1x4 , + CG_FIXED2x1 , + CG_FIXED2x2 , + CG_FIXED2x3 , + CG_FIXED2x4 , + CG_FIXED3x1 , + CG_FIXED3x2 , + CG_FIXED3x3 , + CG_FIXED3x4 , + CG_FIXED4x1 , + CG_FIXED4x2 , + CG_FIXED4x3 , + CG_FIXED4x4 , + CG_HALF1 , + CG_FLOAT1 , + CG_FIXED1 , + + +} CGtype; + +typedef enum +{ + + CG_TEXUNIT0 = 2048, + CG_TEXUNIT1 = 2049, + CG_TEXUNIT2 = 2050, + CG_TEXUNIT3 = 2051, + CG_TEXUNIT4 = 2052, + CG_TEXUNIT5 = 2053, + CG_TEXUNIT6 = 2054, + CG_TEXUNIT7 = 2055, + CG_TEXUNIT8 = 2056, + CG_TEXUNIT9 = 2057, + CG_TEXUNIT10 = 2058, + CG_TEXUNIT11 = 2059, + CG_TEXUNIT12 = 2060, + CG_TEXUNIT13 = 2061, + CG_TEXUNIT14 = 2062, + CG_TEXUNIT15 = 2063, + + CG_ATTR0 = 2113, + CG_ATTR1 = 2114, + CG_ATTR2 = 2115, + CG_ATTR3 = 2116, + CG_ATTR4 = 2117, + CG_ATTR5 = 2118, + CG_ATTR6 = 2119, + CG_ATTR7 = 2120, + CG_ATTR8 = 2121, + CG_ATTR9 = 2122, + CG_ATTR10 = 2123, + CG_ATTR11 = 2124, + CG_ATTR12 = 2125, + CG_ATTR13 = 2126, + CG_ATTR14 = 2127, + CG_ATTR15 = 2128, + + CG_C = 2178, + + CG_TEX0 = 2179, + CG_TEX1 = 2180, + CG_TEX2 = 2181, + CG_TEX3 = 2192, + CG_TEX4 = 2193, + CG_TEX5 = 2194, + CG_TEX6 = 2195, + CG_TEX7 = 2196, + + CG_HPOS = 2243, + CG_COL0 = 2245, + CG_COL1 = 2246, + CG_COL2 = 2247, + CG_COL3 = 2248, + CG_PSIZ = 2309, + CG_WPOS = 2373, + + CG_POSITION0 = 2437, + CG_POSITION1 = 2438, + CG_POSITION2 = 2439, + CG_POSITION3 = 2440, + CG_POSITION4 = 2441, + CG_POSITION5 = 2442, + CG_POSITION6 = 2443, + CG_POSITION7 = 2444, + CG_POSITION8 = 2445, + CG_POSITION9 = 2446, + CG_POSITION10 = 2447, + CG_POSITION11 = 2448, + CG_POSITION12 = 2449, + CG_POSITION13 = 2450, + CG_POSITION14 = 2451, + CG_POSITION15 = 2452, + CG_DIFFUSE0 = 2501, + CG_TANGENT0 = 2565, + CG_TANGENT1 = 2566, + CG_TANGENT2 = 2567, + CG_TANGENT3 = 2568, + CG_TANGENT4 = 2569, + CG_TANGENT5 = 2570, + CG_TANGENT6 = 2571, + CG_TANGENT7 = 2572, + CG_TANGENT8 = 2573, + CG_TANGENT9 = 2574, + CG_TANGENT10 = 2575, + CG_TANGENT11 = 2576, + CG_TANGENT12 = 2577, + CG_TANGENT13 = 2578, + CG_TANGENT14 = 2579, + CG_TANGENT15 = 2580, + CG_SPECULAR0 = 2629, + CG_BLENDINDICES0 = 2693, + CG_BLENDINDICES1 = 2694, + CG_BLENDINDICES2 = 2695, + CG_BLENDINDICES3 = 2696, + CG_BLENDINDICES4 = 2697, + CG_BLENDINDICES5 = 2698, + CG_BLENDINDICES6 = 2699, + CG_BLENDINDICES7 = 2700, + CG_BLENDINDICES8 = 2701, + CG_BLENDINDICES9 = 2702, + CG_BLENDINDICES10 = 2703, + CG_BLENDINDICES11 = 2704, + CG_BLENDINDICES12 = 2705, + CG_BLENDINDICES13 = 2706, + CG_BLENDINDICES14 = 2707, + CG_BLENDINDICES15 = 2708, + CG_COLOR0 = 2757, + CG_COLOR1 = 2758, + CG_COLOR2 = 2759, + CG_COLOR3 = 2760, + CG_COLOR4 = 2761, + CG_COLOR5 = 2762, + CG_COLOR6 = 2763, + CG_COLOR7 = 2764, + CG_COLOR8 = 2765, + CG_COLOR9 = 2766, + CG_COLOR10 = 2767, + CG_COLOR11 = 2768, + CG_COLOR12 = 2769, + CG_COLOR13 = 2770, + CG_COLOR14 = 2771, + CG_COLOR15 = 2772, + CG_PSIZE0 = 2821, + CG_PSIZE1 = 2822, + CG_PSIZE2 = 2823, + CG_PSIZE3 = 2824, + CG_PSIZE4 = 2825, + CG_PSIZE5 = 2826, + CG_PSIZE6 = 2827, + CG_PSIZE7 = 2828, + CG_PSIZE8 = 2829, + CG_PSIZE9 = 2830, + CG_PSIZE10 = 2831, + CG_PSIZE11 = 2832, + CG_PSIZE12 = 2833, + CG_PSIZE13 = 2834, + CG_PSIZE14 = 2835, + CG_PSIZE15 = 2836, + CG_BINORMAL0 = 2885, + CG_BINORMAL1 = 2886, + CG_BINORMAL2 = 2887, + CG_BINORMAL3 = 2888, + CG_BINORMAL4 = 2889, + CG_BINORMAL5 = 2890, + CG_BINORMAL6 = 2891, + CG_BINORMAL7 = 2892, + CG_BINORMAL8 = 2893, + CG_BINORMAL9 = 2894, + CG_BINORMAL10 = 2895, + CG_BINORMAL11 = 2896, + CG_BINORMAL12 = 2897, + CG_BINORMAL13 = 2898, + CG_BINORMAL14 = 2899, + CG_BINORMAL15 = 2900, + CG_FOG0 = 2917, + CG_FOG1 = 2918, + CG_FOG2 = 2919, + CG_FOG3 = 2920, + CG_FOG4 = 2921, + CG_FOG5 = 2922, + CG_FOG6 = 2923, + CG_FOG7 = 2924, + CG_FOG8 = 2925, + CG_FOG9 = 2926, + CG_FOG10 = 2927, + CG_FOG11 = 2928, + CG_FOG12 = 2929, + CG_FOG13 = 2930, + CG_FOG14 = 2931, + CG_FOG15 = 2932, + CG_DEPTH0 = 2933, + CG_DEPTH1 = 2934, + CG_DEPTH2 = 2935, + CG_DEPTH3 = 2936, + CG_DEPTH4 = 2937, + CG_DEPTH5 = 2938, + CG_DEPTH6 = 2939, + CG_DEPTH7 = 2940, + CG_DEPTH8 = 2941, + CG_DEPTH9 = 29542, + CG_DEPTH10 = 2943, + CG_DEPTH11 = 2944, + CG_DEPTH12 = 2945, + CG_DEPTH13 = 2946, + CG_DEPTH14 = 2947, + CG_DEPTH15 = 2948, + CG_SAMPLE0 = 2949, + CG_SAMPLE1 = 2950, + CG_SAMPLE2 = 2951, + CG_SAMPLE3 = 2952, + CG_SAMPLE4 = 2953, + CG_SAMPLE5 = 2954, + CG_SAMPLE6 = 2955, + CG_SAMPLE7 = 2956, + CG_SAMPLE8 = 2957, + CG_SAMPLE9 = 2958, + CG_SAMPLE10 = 2959, + CG_SAMPLE11 = 2960, + CG_SAMPLE12 = 2961, + CG_SAMPLE13 = 2962, + CG_SAMPLE14 = 2963, + CG_SAMPLE15 = 2964, + CG_BLENDWEIGHT0 = 3028, + CG_BLENDWEIGHT1 = 3029, + CG_BLENDWEIGHT2 = 3030, + CG_BLENDWEIGHT3 = 3031, + CG_BLENDWEIGHT4 = 3032, + CG_BLENDWEIGHT5 = 3033, + CG_BLENDWEIGHT6 = 3034, + CG_BLENDWEIGHT7 = 3035, + CG_BLENDWEIGHT8 = 3036, + CG_BLENDWEIGHT9 = 3037, + CG_BLENDWEIGHT10 = 3038, + CG_BLENDWEIGHT11 = 3039, + CG_BLENDWEIGHT12 = 3040, + CG_BLENDWEIGHT13 = 3041, + CG_BLENDWEIGHT14 = 3042, + CG_BLENDWEIGHT15 = 3043, + CG_NORMAL0 = 3092, + CG_NORMAL1 = 3093, + CG_NORMAL2 = 3094, + CG_NORMAL3 = 3095, + CG_NORMAL4 = 3096, + CG_NORMAL5 = 3097, + CG_NORMAL6 = 3098, + CG_NORMAL7 = 3099, + CG_NORMAL8 = 3100, + CG_NORMAL9 = 3101, + CG_NORMAL10 = 3102, + CG_NORMAL11 = 3103, + CG_NORMAL12 = 3104, + CG_NORMAL13 = 3105, + CG_NORMAL14 = 3106, + CG_NORMAL15 = 3107, + CG_FOGCOORD = 3156, + CG_TEXCOORD0 = 3220, + CG_TEXCOORD1 = 3221, + CG_TEXCOORD2 = 3222, + CG_TEXCOORD3 = 3223, + CG_TEXCOORD4 = 3224, + CG_TEXCOORD5 = 3225, + CG_TEXCOORD6 = 3226, + CG_TEXCOORD7 = 3227, + CG_TEXCOORD8 = 3228, + CG_TEXCOORD9 = 3229, + CG_TEXCOORD10 = 3230, + CG_TEXCOORD11 = 3231, + CG_TEXCOORD12 = 3232, + CG_TEXCOORD13 = 3233, + CG_TEXCOORD14 = 3234, + CG_TEXCOORD15 = 3235, + CG_COMBINER_CONST0 = 3284, + CG_COMBINER_CONST1 = 3285, + CG_COMBINER_STAGE_CONST0 = 3286, + CG_COMBINER_STAGE_CONST1 = 3287, + CG_OFFSET_TEXTURE_MATRIX = 3288, + CG_OFFSET_TEXTURE_SCALE = 3289, + CG_OFFSET_TEXTURE_BIAS = 3290, + CG_CONST_EYE = 3291, + CG_TESSFACTOR = 3255, + + + CG_UNDEFINED, + + } CGresource; + + typedef enum + { + CG_PROFILE_START = 6144, + CG_PROFILE_UNKNOWN, + + CG_PROFILE_VP20 = 6146, + CG_PROFILE_FP20 = 6147, + CG_PROFILE_VP30 = 6148, + CG_PROFILE_FP30 = 6149, + CG_PROFILE_ARBVP1 = 6150, + CG_PROFILE_ARBFP1 = 7000, + + + CG_PROFILE_VS_1_1 = 6153, + CG_PROFILE_VS_2_0 = 6154, + CG_PROFILE_VS_2_X = 6155, + + CG_PROFILE_PS_1_1 = 6159, + CG_PROFILE_PS_1_2 = 6160, + CG_PROFILE_PS_1_3 = 6161, + CG_PROFILE_PS_2_0 = 6162, + CG_PROFILE_PS_2_X = 6163, + + CG_PROFILE_MAX, + } CGprofile; + + typedef enum + { + + + CG_NO_ERROR = 0, + CG_COMPILER_ERROR = 1, + CG_INVALID_PARAMETER_ERROR = 2, + CG_INVALID_PROFILE_ERROR = 3, + CG_PROGRAM_LOAD_ERROR = 4, + CG_PROGRAM_BIND_ERROR = 5, + CG_PROGRAM_NOT_LOADED_ERROR = 6, + CG_UNSUPPORTED_GL_EXTENSION_ERROR = 7, + CG_INVALID_VALUE_TYPE_ERROR = 8, + CG_NOT_MATRIX_PARAM_ERROR = 9, + CG_INVALID_ENUMERANT_ERROR = 10, + CG_NOT_4x4_MATRIX_ERROR = 11, + CG_FILE_READ_ERROR = 12, + CG_FILE_WRITE_ERROR = 13, + CG_NVPARSE_ERROR = 14, + CG_MEMORY_ALLOC_ERROR = 15, + CG_INVALID_CONTEXT_HANDLE_ERROR = 16, + CG_INVALID_PROGRAM_HANDLE_ERROR = 17, + CG_INVALID_PARAM_HANDLE_ERROR = 18, + CG_UNKNOWN_PROFILE_ERROR = 19, + CG_VAR_ARG_ERROR = 20, + CG_INVALID_DIMENSION_ERROR = 21, + CG_ARRAY_PARAM_ERROR = 22, + CG_OUT_OF_ARRAY_BOUNDS_ERROR = 23, + } CGerror; + + typedef enum + { + CG_UNKNOWN = 4096, + CG_IN, + CG_OUT, + CG_INOUT, + CG_MIXED, + CG_VARYING, + CG_UNIFORM, + CG_CONSTANT, + CG_PROGRAM_SOURCE, + CG_PROGRAM_ENTRY, + CG_COMPILED_PROGRAM, + CG_PROGRAM_PROFILE, + + CG_GLOBAL, + CG_PROGRAM, + + CG_DEFAULT, + CG_ERROR, + + CG_SOURCE, + CG_OBJECT, + + } CGenum; + + + extern "C" { + + typedef void (*CGerrorCallbackFunc)(void); + + + + typedef CGcontext (*PFNCGCREATECONTEXTPROC)(void); + typedef void (*PFNCGDESTROYCONTEXTPROC)(CGcontext ctx); + typedef CGbool (*PFNCGISCONTEXTPROC)(CGcontext ctx); + typedef const char * (*PFNCGGETLASTLISTINGPROC)(CGcontext ctx); + typedef CGprogram (*PFNCGCREATEPROGRAMPROC)(CGcontext ctx, + CGenum program_type, + const char *program, + CGprofile profile, + const char *entry, + const char **args); + typedef CGprogram (*PFNCGCREATEPROGRAMFROMFILEPROC)(CGcontext ctx, + CGenum program_type, + const char *program_file, + CGprofile profile, + const char *entry, + const char **args); + typedef CGprogram (*PFNCGCOPYPROGRAMPROC)(CGprogram program); + typedef void (*PFNCGDESTROYPROGRAMPROC)(CGprogram program); + typedef CGprogram (*PFNCGGETFIRSTPROGRAMPROC)(CGcontext ctx); + typedef CGprogram (*PFNCGGETNEXTPROGRAMPROC)(CGprogram current); + typedef CGcontext (*PFNCGGETPROGRAMCONTEXTPROC)(CGprogram prog); + typedef CGbool (*PFNCGISPROGRAMPROC)(CGprogram program); + typedef void (*PFNCGCOMPILEPROGRAMPROC)(CGprogram program); + typedef CGbool (*PFNCGISPROGRAMCOMPILEDPROC)(CGprogram program); + typedef const char * (*PFNCGGETPROGRAMSTRINGPROC)(CGprogram prog, CGenum pname); + typedef CGprofile (*PFNCGGETPROGRAMPROFILEPROC)(CGprogram prog); + typedef CGparameter (*PFNCGGETNAMEDPARAMETERPROC)(CGprogram prog, const char *name); + typedef CGparameter (*PFNCGGETFIRSTPARAMETERPROC)(CGprogram prog, CGenum name_space); + typedef CGparameter (*PFNCGGETNEXTPARAMETERPROC)(CGparameter current); + typedef CGparameter (*PFNCGGETFIRSTLEAFPARAMETERPROC)(CGprogram prog, CGenum name_space); + typedef CGparameter (*PFNCGGETNEXTLEAFPARAMETERPROC)(CGparameter current); + typedef CGparameter (*PFNCGGETFIRSTSTRUCTPARAMETERPROC)(CGparameter param); + typedef CGparameter (*PFNCGGETFIRSTDEPENDENTPARAMETERPROC)(CGparameter param); + typedef CGparameter (*PFNCGGETARRAYPARAMETERPROC)(CGparameter aparam, int index); + typedef int (*PFNCGGETARRAYDIMENSIONPROC)(CGparameter param); + typedef int (*PFNCGGETARRAYSIZEPROC)(CGparameter param, int dimension); + typedef CGprogram (*PFNCGGETPARAMETERPROGRAMPROC)(CGparameter prog); + typedef CGbool (*PFNCGISPARAMETERPROC)(CGparameter param); + typedef const char * (*PFNCGGETPARAMETERNAMEPROC)(CGparameter param); + typedef CGtype (*PFNCGGETPARAMETERTYPEPROC)(CGparameter param); + typedef const char * (*PFNCGGETPARAMETERSEMANTICPROC)(CGparameter param); + typedef CGresource (*PFNCGGETPARAMETERRESOURCEPROC)(CGparameter param); + typedef CGresource (*PFNCGGETPARAMETERBASERESOURCEPROC)(CGparameter param); + typedef unsigned long (*PFNCGGETPARAMETERRESOURCEINDEXPROC)(CGparameter param); + typedef CGenum (*PFNCGGETPARAMETERVARIABILITYPROC)(CGparameter param); + typedef CGenum (*PFNCGGETPARAMETERDIRECTIONPROC)(CGparameter param); + typedef CGbool (*PFNCGISPARAMETERREFERENCEDPROC)(CGparameter param); + typedef void (*PFNCGGETPARAMETERVALUESPROC)(CGparameter param, + CGenum value_type, + int *nvalues); + typedef const char * (*PFNCGGETTYPESTRINGPROC)(CGtype type); + typedef CGtype (*PFNCGGETTYPEPROC)(const char *type_string); + typedef const char * (*PFNCGGETRESOURCESTRINGPROC)(CGresource resource); + typedef CGresource (*PFNCGGETRESOURCEPROC)(const char *resource_string); + typedef const char * (*PFNCGGETPROFILESTRINGPROC)(CGprofile profile); + typedef CGprofile (*PFNCGGETPROFILEPROC)(const char *profile_string); + typedef CGerror (*PFNCGGETERRORPROC)(void); + typedef const char * (*PFNCGGETERRORSTRINGPROC)(CGerror error); + typedef void (*PFNCGSETERRORCALLBACKPROC)(CGerrorCallbackFunc func); + typedef CGerrorCallbackFunc (*PFNCGGETERRORCALLBACKPROC)(void); + + + extern PFNCGCREATECONTEXTPROC cgCreateContext; + extern PFNCGDESTROYCONTEXTPROC cgDestroyContext; + extern PFNCGISCONTEXTPROC cgIsContext; + extern PFNCGGETLASTLISTINGPROC cgGetLastListing; + extern PFNCGCREATEPROGRAMPROC cgCreateProgram; + extern PFNCGCREATEPROGRAMFROMFILEPROC cgCreateProgramFromFile; + extern PFNCGCOPYPROGRAMPROC cgCopyProgram; + extern PFNCGDESTROYPROGRAMPROC cgDestroyProgram; + extern PFNCGGETFIRSTPROGRAMPROC cgGetFirstProgram; + extern PFNCGGETNEXTPROGRAMPROC cgGetNextProgram; + extern PFNCGGETPROGRAMCONTEXTPROC cgGetProgramContext; + extern PFNCGISPROGRAMPROC cgIsProgram; + extern PFNCGCOMPILEPROGRAMPROC cgCompileProgram; + extern PFNCGISPROGRAMCOMPILEDPROC cgIsProgramCompiled; + extern PFNCGGETPROGRAMSTRINGPROC cgGetProgramString; + extern PFNCGGETPROGRAMPROFILEPROC cgGetProgramProfile; + extern PFNCGGETNAMEDPARAMETERPROC cgGetNamedParameter; + extern PFNCGGETFIRSTPARAMETERPROC cgGetFirstParameter; + extern PFNCGGETNEXTPARAMETERPROC cgGetNextParameter; + extern PFNCGGETFIRSTLEAFPARAMETERPROC cgGetFirstLeafParameter; + extern PFNCGGETNEXTLEAFPARAMETERPROC cgGetNextLeafParameter; + extern PFNCGGETFIRSTSTRUCTPARAMETERPROC cgGetFirstStructParameter; + extern PFNCGGETFIRSTDEPENDENTPARAMETERPROC cgGetFirstDependentParameter; + extern PFNCGGETARRAYPARAMETERPROC cgGetArrayParameter; + extern PFNCGGETARRAYDIMENSIONPROC cgGetArrayDimension; + extern PFNCGGETARRAYSIZEPROC cgGetArraySize; + extern PFNCGGETPARAMETERPROGRAMPROC cgGetParameterProgram; + extern PFNCGISPARAMETERPROC cgIsParameter; + extern PFNCGGETPARAMETERNAMEPROC cgGetParameterName; + extern PFNCGGETPARAMETERTYPEPROC cgGetParameterType; + extern PFNCGGETPARAMETERSEMANTICPROC cgGetParameterSemantic; + extern PFNCGGETPARAMETERRESOURCEPROC cgGetParameterResource; + extern PFNCGGETPARAMETERBASERESOURCEPROC cgGetParameterBaseResource; + extern PFNCGGETPARAMETERRESOURCEINDEXPROC cgGetParameterResourceIndex; + extern PFNCGGETPARAMETERVARIABILITYPROC cgGetParameterVariability; + extern PFNCGGETPARAMETERDIRECTIONPROC cgGetParameterDirection; + extern PFNCGISPARAMETERREFERENCEDPROC cgIsParameterReferenced; + extern PFNCGGETPARAMETERVALUESPROC cgGetParameterValues; + extern PFNCGGETTYPESTRINGPROC cgGetTypeString; + extern PFNCGGETTYPEPROC cgGetType; + extern PFNCGGETRESOURCESTRINGPROC cgGetResourceString; + extern PFNCGGETRESOURCEPROC cgGetResource; + extern PFNCGGETPROFILESTRINGPROC cgGetProfileString; + extern PFNCGGETPROFILEPROC cgGetProfile; + extern PFNCGGETERRORPROC cgGetError; + extern PFNCGGETERRORSTRINGPROC cgGetErrorString; + extern PFNCGSETERRORCALLBACKPROC cgSetErrorCallback; + extern PFNCGGETERRORCALLBACKPROC cgGetErrorCallback; + + + } + + + + extern "C" { + + typedef enum + { + CG_GL_MATRIX_IDENTITY = 0, + CG_GL_MATRIX_TRANSPOSE = 1, + CG_GL_MATRIX_INVERSE = 2, + CG_GL_MATRIX_INVERSE_TRANSPOSE = 3, + + CG_GL_MODELVIEW_MATRIX, + CG_GL_PROJECTION_MATRIX, + CG_GL_TEXTURE_MATRIX, + CG_GL_MODELVIEW_PROJECTION_MATRIX, + + CG_GL_VERTEX, + CG_GL_FRAGMENT, + + } CGGLenum; + + + + + typedef CGbool (*PFNCGGLISPROFILESUPPORTEDPROC)(CGprofile profile); + typedef void (*PFNCGGLENABLEPROFILEPROC)(CGprofile profile); + typedef void (*PFNCGGLDISABLEPROFILEPROC)(CGprofile profile); + typedef CGprofile (*PFNCGGLGETLATESTPROFILEPROC)(CGGLenum profile_type); + typedef void (*PFNCGGLSETOPTIMALOPTIONSPROC)(CGprofile profile); + typedef void (*PFNCGGLLOADPROGRAMPROC)(CGprogram program); + typedef void (*PFNCGGLBINDPROGRAMPROC)(CGprogram program); + typedef void (*PFNCGGLSETPARAMETER1FPROC)(CGparameter param, + float x); + typedef void (*PFNCGGLSETPARAMETER2FPROC)(CGparameter param, + float x, + float y); + typedef void (*PFNCGGLSETPARAMETER3FPROC)(CGparameter param, + float x, + float y, + float z); + typedef void (*PFNCGGLSETPARAMETER4FPROC)(CGparameter param, + float x, + float y, + float z, + float w); + typedef void (*PFNCGGLSETPARAMETER1FVPROC)(CGparameter param, const float *v); + typedef void (*PFNCGGLSETPARAMETER2FVPROC)(CGparameter param, const float *v); + typedef void (*PFNCGGLSETPARAMETER3FVPROC)(CGparameter param, const float *v); + typedef void (*PFNCGGLSETPARAMETER4FVPROC)(CGparameter param, const float *v); + typedef void (*PFNCGGLSETPARAMETER1DPROC)(CGparameter param, + double x); + typedef void (*PFNCGGLSETPARAMETER2DPROC)(CGparameter param, + double x, + double y); + typedef void (*PFNCGGLSETPARAMETER3DPROC)(CGparameter param, + double x, + double y, + double z); + typedef void (*PFNCGGLSETPARAMETER4DPROC)(CGparameter param, + double x, + double y, + double z, + double w); + typedef void (*PFNCGGLSETPARAMETER1DVPROC)(CGparameter param, const double *v); + typedef void (*PFNCGGLSETPARAMETER2DVPROC)(CGparameter param, const double *v); + typedef void (*PFNCGGLSETPARAMETER3DVPROC)(CGparameter param, const double *v); + typedef void (*PFNCGGLSETPARAMETER4DVPROC)(CGparameter param, const double *v); + typedef void (*PFNCGGLSETPARAMETER4DVPROC)(CGparameter param, const double *v); + typedef void (*PFNCGGLGETPARAMETER1FPROC)(CGparameter param, float *v); + typedef void (*PFNCGGLGETPARAMETER2FPROC)(CGparameter param, float *v); + typedef void (*PFNCGGLGETPARAMETER3FPROC)(CGparameter param, float *v); + typedef void (*PFNCGGLGETPARAMETER4FPROC)(CGparameter param, float *v); + typedef void (*PFNCGGLGETPARAMETER1DPROC)(CGparameter param, double *v); + typedef void (*PFNCGGLGETPARAMETER2DPROC)(CGparameter param, double *v); + typedef void (*PFNCGGLGETPARAMETER3DPROC)(CGparameter param, double *v); + typedef void (*PFNCGGLGETPARAMETER4DPROC)(CGparameter param, double *v); + typedef void (*PFNCGGLSETPARAMETERARRAY1FPROC)(CGparameter param, + long offset, + long nelements, + const float *v); + typedef void (*PFNCGGLSETPARAMETERARRAY2FPROC)(CGparameter param, + long offset, + long nelements, + const float *v); + typedef void (*PFNCGGLSETPARAMETERARRAY3FPROC)(CGparameter param, + long offset, + long nelements, + const float *v); + typedef void (*PFNCGGLSETPARAMETERARRAY4FPROC)(CGparameter param, + long offset, + long nelements, + const float *v); + typedef void (*PFNCGGLSETPARAMETERARRAY1DPROC)(CGparameter param, + long offset, + long nelements, + const double *v); + typedef void (*PFNCGGLSETPARAMETERARRAY2DPROC)(CGparameter param, + long offset, + long nelements, + const double *v); + typedef void (*PFNCGGLSETPARAMETERARRAY3DPROC)(CGparameter param, + long offset, + long nelements, + const double *v); + typedef void (*PFNCGGLSETPARAMETERARRAY4DPROC)(CGparameter param, + long offset, + long nelements, + const double *v); + typedef void (*PFNCGGLGETPARAMETERARRAY1FPROC)(CGparameter param, + long offset, + long nelements, + float *v); + typedef void (*PFNCGGLGETPARAMETERARRAY2FPROC)(CGparameter param, + long offset, + long nelements, + float *v); + typedef void (*PFNCGGLGETPARAMETERARRAY3FPROC)(CGparameter param, + long offset, + long nelements, + float *v); + typedef void (*PFNCGGLGETPARAMETERARRAY4FPROC)(CGparameter param, + long offset, + long nelements, + float *v); + typedef void (*PFNCGGLGETPARAMETERARRAY1DPROC)(CGparameter param, + long offset, + long nelements, + double *v); + typedef void (*PFNCGGLGETPARAMETERARRAY2DPROC)(CGparameter param, + long offset, + long nelements, + double *v); + typedef void (*PFNCGGLGETPARAMETERARRAY3DPROC)(CGparameter param, + long offset, + long nelements, + double *v); + typedef void (*PFNCGGLGETPARAMETERARRAY4DPROC)(CGparameter param, + long offset, + long nelements, + double *v); + typedef void (*PFNCGGLSETPARAMETERPOINTERPROC)(CGparameter param, + GLint fsize, + GLenum type, + GLsizei stride, + GLvoid *pointer); + typedef void (*PFNCGGLENABLECLIENTSTATEPROC)(CGparameter param); + typedef void (*PFNCGGLDISABLECLIENTSTATEPROC)(CGparameter param); + typedef void (*PFNCGGLSETMATRIXPARAMETERDRPROC)(CGparameter param, const double *matrix); + typedef void (*PFNCGGLSETMATRIXPARAMETERFRPROC)(CGparameter param, const float *matrix); + typedef void (*PFNCGGLSETMATRIXPARAMETERDCPROC)(CGparameter param, const double *matrix); + typedef void (*PFNCGGLSETMATRIXPARAMETERFCPROC)(CGparameter param, const float *matrix); + typedef void (*PFNCGGLGETMATRIXPARAMETERDRPROC)(CGparameter param, double *matrix); + typedef void (*PFNCGGLGETMATRIXPARAMETERFRPROC)(CGparameter param, float *matrix); + typedef void (*PFNCGGLGETMATRIXPARAMETERDCPROC)(CGparameter param, double *matrix); + typedef void (*PFNCGGLGETMATRIXPARAMETERFCPROC)(CGparameter param, float *matrix); + typedef void (*PFNCGGLSETSTATEMATRIXPARAMETERPROC)(CGparameter param, + GLenum matrix, + GLenum transform); + typedef void (*PFNCGGLSETMATRIXPARAMETERARRAYFCPROC)(CGparameter param, + long offset, + long nelements, + const float *matrices); + typedef void (*PFNCGGLSETMATRIXPARAMETERARRAYFRPROC)(CGparameter param, + long offset, + long nelements, + const float *matrices); + typedef void (*PFNCGGLSETMATRIXPARAMETERARRAYDCPROC)(CGparameter param, + long offset, + long nelements, + const double *matrices); + typedef void (*PFNCGGLSETMATRIXPARAMETERARRAYDRPROC)(CGparameter param, + long offset, + long nelements, + const double *matrices); + typedef void (*PFNCGGLGETMATRIXPARAMETERARRAYFCPROC)(CGparameter param, + long offset, + long nelements, + float *matrices); + typedef void (*PFNCGGLGETMATRIXPARAMETERARRAYFRPROC)(CGparameter param, + long offset, + long nelements, + float *matrices); + typedef void (*PFNCGGLGETMATRIXPARAMETERARRAYDCPROC)(CGparameter param, + long offset, + long nelements, + double *matrices); + typedef void (*PFNCGGLGETMATRIXPARAMETERARRAYDRPROC)(CGparameter param, + long offset, + long nelements, + double *matrices); + typedef void (*PFNCGGLSETTEXTUREPARAMETERPROC)(CGparameter param, GLuint texobj); + typedef GLuint (*PFNCGGLGETTEXTUREPARAMETERPROC)(CGparameter param); + typedef void (*PFNCGGLENABLETEXTUREPARAMETERPROC)(CGparameter param); + typedef void (*PFNCGGLDISABLETEXTUREPARAMETERPROC)(CGparameter param); + typedef GLenum (*PFNCGGLGETTEXTUREENUMPROC)(CGparameter param); + + + extern PFNCGGLISPROFILESUPPORTEDPROC cgGLIsProfileSupported; + extern PFNCGGLENABLEPROFILEPROC cgGLEnableProfile; + extern PFNCGGLDISABLEPROFILEPROC cgGLDisableProfile; + extern PFNCGGLGETLATESTPROFILEPROC cgGLGetLatestProfile; + extern PFNCGGLSETOPTIMALOPTIONSPROC cgGLSetOptimalOptions; + extern PFNCGGLLOADPROGRAMPROC cgGLLoadProgram; + extern PFNCGGLBINDPROGRAMPROC cgGLBindProgram; + extern PFNCGGLSETPARAMETER1FPROC cgGLSetParameter1f; + extern PFNCGGLSETPARAMETER2FPROC cgGLSetParameter2f; + extern PFNCGGLSETPARAMETER3FPROC cgGLSetParameter3f; + extern PFNCGGLSETPARAMETER4FPROC cgGLSetParameter4f; + extern PFNCGGLSETPARAMETER1FVPROC cgGLSetParameter1fv; + extern PFNCGGLSETPARAMETER2FVPROC cgGLSetParameter2fv; + extern PFNCGGLSETPARAMETER3FVPROC cgGLSetParameter3fv; + extern PFNCGGLSETPARAMETER4FVPROC cgGLSetParameter4fv; + extern PFNCGGLSETPARAMETER1DPROC cgGLSetParameter1d; + extern PFNCGGLSETPARAMETER2DPROC cgGLSetParameter2d; + extern PFNCGGLSETPARAMETER3DPROC cgGLSetParameter3d; + extern PFNCGGLSETPARAMETER4DPROC cgGLSetParameter4d; + extern PFNCGGLSETPARAMETER1DVPROC cgGLSetParameter1dv; + extern PFNCGGLSETPARAMETER2DVPROC cgGLSetParameter2dv; + extern PFNCGGLSETPARAMETER3DVPROC cgGLSetParameter3dv; + extern PFNCGGLSETPARAMETER4DVPROC cgGLSetParameter4dv; + extern PFNCGGLGETPARAMETER1FPROC cgGLGetParameter1f; + extern PFNCGGLGETPARAMETER2FPROC cgGLGetParameter2f; + extern PFNCGGLGETPARAMETER3FPROC cgGLGetParameter3f; + extern PFNCGGLGETPARAMETER4FPROC cgGLGetParameter4f; + extern PFNCGGLGETPARAMETER1DPROC cgGLGetParameter1d; + extern PFNCGGLGETPARAMETER2DPROC cgGLGetParameter2d; + extern PFNCGGLGETPARAMETER3DPROC cgGLGetParameter3d; + extern PFNCGGLGETPARAMETER4DPROC cgGLGetParameter4d; + extern PFNCGGLSETPARAMETERARRAY1FPROC cgGLSetParameterArray1f; + extern PFNCGGLSETPARAMETERARRAY2FPROC cgGLSetParameterArray2f; + extern PFNCGGLSETPARAMETERARRAY3FPROC cgGLSetParameterArray3f; + extern PFNCGGLSETPARAMETERARRAY4FPROC cgGLSetParameterArray4f; + extern PFNCGGLSETPARAMETERARRAY1DPROC cgGLSetParameterArray1d; + extern PFNCGGLSETPARAMETERARRAY2DPROC cgGLSetParameterArray2d; + extern PFNCGGLSETPARAMETERARRAY3DPROC cgGLSetParameterArray3d; + extern PFNCGGLSETPARAMETERARRAY4DPROC cgGLSetParameterArray4d; + extern PFNCGGLGETPARAMETERARRAY1FPROC cgGLGetParameterArray1f; + extern PFNCGGLGETPARAMETERARRAY2FPROC cgGLGetParameterArray2f; + extern PFNCGGLGETPARAMETERARRAY3FPROC cgGLGetParameterArray3f; + extern PFNCGGLGETPARAMETERARRAY4FPROC cgGLGetParameterArray4f; + extern PFNCGGLGETPARAMETERARRAY1DPROC cgGLGetParameterArray1d; + extern PFNCGGLGETPARAMETERARRAY2DPROC cgGLGetParameterArray2d; + extern PFNCGGLGETPARAMETERARRAY3DPROC cgGLGetParameterArray3d; + extern PFNCGGLGETPARAMETERARRAY4DPROC cgGLGetParameterArray4d; + extern PFNCGGLSETPARAMETERPOINTERPROC cgGLSetParameterPointer; + extern PFNCGGLENABLECLIENTSTATEPROC cgGLEnableClientState; + extern PFNCGGLDISABLECLIENTSTATEPROC cgGLDisableClientState; + extern PFNCGGLSETMATRIXPARAMETERDRPROC cgGLSetMatrixParameterdr; + extern PFNCGGLSETMATRIXPARAMETERFRPROC cgGLSetMatrixParameterfr; + extern PFNCGGLSETMATRIXPARAMETERDCPROC cgGLSetMatrixParameterdc; + extern PFNCGGLSETMATRIXPARAMETERFCPROC cgGLSetMatrixParameterfc; + extern PFNCGGLGETMATRIXPARAMETERDRPROC cgGLGetMatrixParameterdr; + extern PFNCGGLGETMATRIXPARAMETERFRPROC cgGLGetMatrixParameterfr; + extern PFNCGGLGETMATRIXPARAMETERDCPROC cgGLGetMatrixParameterdc; + extern PFNCGGLGETMATRIXPARAMETERFCPROC cgGLGetMatrixParameterfc; + extern PFNCGGLSETSTATEMATRIXPARAMETERPROC cgGLSetStateMatrixParameter; + extern PFNCGGLSETMATRIXPARAMETERARRAYFCPROC cgGLSetMatrixParameterArrayfc; + extern PFNCGGLSETMATRIXPARAMETERARRAYFRPROC cgGLSetMatrixParameterArrayfr; + extern PFNCGGLSETMATRIXPARAMETERARRAYDCPROC cgGLSetMatrixParameterArraydc; + extern PFNCGGLSETMATRIXPARAMETERARRAYDRPROC cgGLSetMatrixParameterArraydr; + extern PFNCGGLGETMATRIXPARAMETERARRAYFCPROC cgGLGetMatrixParameterArrayfc; + extern PFNCGGLGETMATRIXPARAMETERARRAYFRPROC cgGLGetMatrixParameterArrayfr; + extern PFNCGGLGETMATRIXPARAMETERARRAYDCPROC cgGLGetMatrixParameterArraydc; + extern PFNCGGLGETMATRIXPARAMETERARRAYDRPROC cgGLGetMatrixParameterArraydr; + extern PFNCGGLSETTEXTUREPARAMETERPROC cgGLSetTextureParameter; + extern PFNCGGLGETTEXTUREPARAMETERPROC cgGLGetTextureParameter; + extern PFNCGGLENABLETEXTUREPARAMETERPROC cgGLEnableTextureParameter; + extern PFNCGGLDISABLETEXTUREPARAMETERPROC cgGLDisableTextureParameter; + extern PFNCGGLGETTEXTUREENUMPROC cgGLGetTextureEnum; + + +} + +bool init_explicit_Cg(); + +#endif + diff --git a/renderer/cinematic.h b/renderer/cinematic.h deleted file mode 100644 index 61127c9e6..000000000 --- a/renderer/cinematic.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __CINEMATIC_H__ -#define __CINEMATIC_H__ - -/* -=============================================================================== - - RoQ cinematic - - Multiple idCinematics can run simultaniously. - A single idCinematic can be reused for multiple files if desired. - -=============================================================================== -*/ - -// cinematic states -typedef enum { - FMV_IDLE, - FMV_PLAY, // play - FMV_EOF, // all other conditions, i.e. stop/EOF/abort - FMV_ID_BLT, - FMV_ID_IDLE, - FMV_LOOPED, - FMV_ID_WAIT -} cinStatus_t; - -// a cinematic stream generates an image buffer, which the caller will upload to a texture -struct cinData_t { - int imageWidth, imageHeight; // will be a power of 2 - const byte * image; // RGBA format, alpha will be 255 - int status; -}; - -class idCinematic { -public: - // initialize cinematic play back data - static void InitCinematic( void ); - - // shutdown cinematic play back data - static void ShutdownCinematic( void ); - - // allocates and returns a private subclass that implements the methods - // This should be used instead of new - static idCinematic *Alloc(); - - // frees all allocated memory - virtual ~idCinematic(); - - // returns false if it failed to load - virtual bool InitFromFile( const char *qpath, bool looping ); - - // returns the length of the animation in milliseconds - virtual int AnimationLength(); - - // the pointers in cinData_t will remain valid until the next UpdateForTime() call - virtual cinData_t ImageForTime( int milliseconds ); - - // closes the file and frees all allocated memory - virtual void Close(); - - // closes the file and frees all allocated memory - virtual void ResetTime(int time); -}; - -/* -=============================================== - - Sound meter. - -=============================================== -*/ - -class idSndWindow : public idCinematic { -public: - - idSndWindow() { showWaveform = false; } - ~idSndWindow() {} - - bool InitFromFile( const char *qpath, bool looping ); - cinData_t ImageForTime( int milliseconds ); - int AnimationLength(); - -private: - bool showWaveform; -}; - -#endif /* !__CINEMATIC_H__ */ diff --git a/renderer/draw_arb.cpp b/renderer/draw_arb.cpp new file mode 100644 index 000000000..8f8c7c35e --- /dev/null +++ b/renderer/draw_arb.cpp @@ -0,0 +1,520 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + + with standard calls, we can't do bump mapping or vertex colors with + shader colors + + 2 texture units: + +falloff +-- +light cube +bump +-- +light projection +diffuse + + + 3 texture units: + +light cube +bump +-- +falloff +light projection +diffuse + + + 5 texture units: + +light cube +bump +falloff +light projection +diffuse + +*/ + +/* +================== +RB_ARB_DrawInteraction + +backEnd.vLight + +backEnd.depthFunc must be equal for alpha tested surfaces to work right, +it is set to lessThan for blended transparent surfaces + +================== +*/ +static void RB_ARB_DrawInteraction( const drawInteraction_t *din ) { + const drawSurf_t *surf = din->surf; + const srfTriangles_t *tri = din->surf->geo; + + // set the vertex arrays, which may not all be enabled on a given pass + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + GL_SelectTexture( 0 ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st ); + + //----------------------------------------------------- + // + // bump / falloff + // + //----------------------------------------------------- + // render light falloff * bumpmap lighting + + // + // draw light falloff to the alpha channel + // + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc ); + + qglColor3f( 1, 1, 1 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[3].ToFloatPtr() ); + qglTexCoord2f( 0, 0.5 ); + +// ATI R100 can't do partial texgens +#define NO_MIXED_TEXGEN + +#ifdef NO_MIXED_TEXGEN +idVec4 plane; +plane[0] = 0; +plane[1] = 0; +plane[2] = 0; +plane[3] = 0.5; +qglEnable( GL_TEXTURE_GEN_T ); +qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane.ToFloatPtr() ); + +plane[0] = 0; +plane[1] = 0; +plane[2] = 0; +plane[3] = 1; +qglEnable( GL_TEXTURE_GEN_Q ); +qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane.ToFloatPtr() ); + +#endif + + din->lightFalloffImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( tri ); + + qglDisable( GL_TEXTURE_GEN_S ); +#ifdef NO_MIXED_TEXGEN +qglDisable( GL_TEXTURE_GEN_T ); +qglDisable( GL_TEXTURE_GEN_Q ); +#endif + +#if 0 +GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK + | backEnd.depthFunc ); +// the texccords are the non-normalized vector towards the light origin +GL_SelectTexture( 0 ); +globalImages->normalCubeMapImage->Bind(); +qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() ); +// draw it +RB_DrawElementsWithCounters( tri ); +return; +#endif + + // we can't do bump mapping with standard calls, so skip it + if ( glConfig.envDot3Available && glConfig.cubeMapAvailable ) { + // + // draw the bump map result onto the alpha channel + // + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_COLORMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will be the per-surface bump map + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +// FIXME: matrix work! RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + din->bumpImage->Bind(); + + // texture 1 is the normalization cube map + // the texccords are the non-normalized vector towards the light origin + GL_SelectTexture( 1 ); + if ( din->ambientLight ) { + globalImages->ambientNormalMap->Bind(); // fixed value + } else { + globalImages->normalCubeMapImage->Bind(); + } + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() ); + + // I just want alpha = Dot( texture0, texture1 ) + GL_TexEnv( GL_COMBINE_ARB ); + + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + GL_TexEnv( GL_MODULATE ); + + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); +// RB_FinishStageTexture( &surfaceStage->texture, surf ); + } + + //----------------------------------------------------- + // + // projected light / surface color for diffuse maps + // + //----------------------------------------------------- + // don't trash alpha + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_ALPHAMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will get the surface color texture + GL_SelectTexture( 0 ); + + // select the vertex color source + if ( din->vertexColor == SVC_IGNORE ) { + qglColor4fv( din->diffuseColor.ToFloatPtr() ); + } else { + // FIXME: does this not get diffuseColor blended in? + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); + qglEnableClientState( GL_COLOR_ARRAY ); + + if ( din->vertexColor == SVC_INVERSE_MODULATE ) { + GL_TexEnv( GL_COMBINE_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + } + } + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + // FIXME: does this not get the texture matrix? +// RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + din->diffuseImage->Bind(); + + // texture 1 will get the light projected texture + GL_SelectTexture( 1 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[0].ToFloatPtr() ); + qglTexGenfv( GL_T, GL_OBJECT_PLANE, din->lightProjection[1].ToFloatPtr() ); + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, din->lightProjection[2].ToFloatPtr() ); + + din->lightImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( tri ); + + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + + globalImages->BindNull(); + GL_SelectTexture( 0 ); + + if ( din->vertexColor != SVC_IGNORE ) { + qglDisableClientState( GL_COLOR_ARRAY ); + GL_TexEnv( GL_MODULATE ); + } + +// RB_FinishStageTexture( &surfaceStage->texture, surf ); +} + +/* +================== +RB_ARB_DrawThreeTextureInteraction + +Used by radeon R100 and Intel graphics parts + +backEnd.vLight + +backEnd.depthFunc must be equal for alpha tested surfaces to work right, +it is set to lessThan for blended transparent surfaces + +================== +*/ +static void RB_ARB_DrawThreeTextureInteraction( const drawInteraction_t *din ) { + const drawSurf_t *surf = din->surf; + const srfTriangles_t *tri = din->surf->geo; + + // set the vertex arrays, which may not all be enabled on a given pass + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + GL_SelectTexture( 0 ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st ); + qglColor3f( 1, 1, 1 ); + + // + // bump map dot cubeMap into the alpha channel + // + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_COLORMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will be the per-surface bump map + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +// FIXME: matrix work! RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + din->bumpImage->Bind(); + + // texture 1 is the normalization cube map + // the texccords are the non-normalized vector towards the light origin + GL_SelectTexture( 1 ); + if ( din->ambientLight ) { + globalImages->ambientNormalMap->Bind(); // fixed value + } else { + globalImages->normalCubeMapImage->Bind(); + } + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() ); + + // I just want alpha = Dot( texture0, texture1 ) + GL_TexEnv( GL_COMBINE_ARB ); + + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + GL_TexEnv( GL_MODULATE ); + + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); +// RB_FinishStageTexture( &surfaceStage->texture, surf ); + + + //----------------------------------------------------- + // + // light falloff / projected light / surface color for diffuse maps + // + //----------------------------------------------------- + // multiply result by alpha, but don't trash alpha + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_ALPHAMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will get the surface color texture + GL_SelectTexture( 0 ); + + // select the vertex color source + if ( din->vertexColor == SVC_IGNORE ) { + qglColor4fv( din->diffuseColor.ToFloatPtr() ); + } else { + // FIXME: does this not get diffuseColor blended in? + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); + qglEnableClientState( GL_COLOR_ARRAY ); + + if ( din->vertexColor == SVC_INVERSE_MODULATE ) { + GL_TexEnv( GL_COMBINE_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + } + } + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + // FIXME: does this not get the texture matrix? +// RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + din->diffuseImage->Bind(); + + // texture 1 will get the light projected texture + GL_SelectTexture( 1 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[0].ToFloatPtr() ); + qglTexGenfv( GL_T, GL_OBJECT_PLANE, din->lightProjection[1].ToFloatPtr() ); + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, din->lightProjection[2].ToFloatPtr() ); + din->lightImage->Bind(); + + // texture 2 will get the light falloff texture + GL_SelectTexture( 2 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + + qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[3].ToFloatPtr() ); + + idVec4 plane; + plane[0] = 0; + plane[1] = 0; + plane[2] = 0; + plane[3] = 0.5; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane.ToFloatPtr() ); + + plane[0] = 0; + plane[1] = 0; + plane[2] = 0; + plane[3] = 1; + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane.ToFloatPtr() ); + + din->lightFalloffImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( tri ); + + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + globalImages->BindNull(); + + GL_SelectTexture( 1 ); + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + globalImages->BindNull(); + + GL_SelectTexture( 0 ); + + if ( din->vertexColor != SVC_IGNORE ) { + qglDisableClientState( GL_COLOR_ARRAY ); + GL_TexEnv( GL_MODULATE ); + } + +// RB_FinishStageTexture( &surfaceStage->texture, surf ); +} + + +/* +================== +RB_CreateDrawInteractions +================== +*/ +static void RB_CreateDrawInteractions( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + + // force a space calculation + backEnd.currentSpace = NULL; + + if ( r_useTripleTextureARB.GetBool() && glConfig.maxTextureUnits >= 3 ) { + for ( ; surf ; surf = surf->nextOnLight ) { + // break it up into multiple primitive draw interactions if necessary + RB_CreateSingleDrawInteractions( surf, RB_ARB_DrawThreeTextureInteraction ); + } + } else { + for ( ; surf ; surf = surf->nextOnLight ) { + // break it up into multiple primitive draw interactions if necessary + RB_CreateSingleDrawInteractions( surf, RB_ARB_DrawInteraction ); + } + } +} + + + +/* +================== +RB_RenderViewLight + +================== +*/ +static void RB_RenderViewLight( viewLight_t *vLight ) { + backEnd.vLight = vLight; + + // do fogging later + if ( vLight->lightShader->IsFogLight() ) { + return; + } + if ( vLight->lightShader->IsBlendLight() ) { + return; + } + + RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight ); + + // clear the stencil buffer if needed + if ( vLight->globalShadows || vLight->localShadows ) { + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + } else { + // no shadows, so no need to read or write the stencil buffer + // we might in theory want to use GL_ALWAYS instead of disabling + // completely, to satisfy the invarience rules + qglStencilFunc( GL_ALWAYS, 128, 255 ); + } + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + RB_StencilShadowPass( vLight->globalShadows ); + RB_CreateDrawInteractions( vLight->localInteractions ); + RB_StencilShadowPass( vLight->localShadows ); + RB_CreateDrawInteractions( vLight->globalInteractions ); + + if ( r_skipTranslucent.GetBool() ) { + return; + } + + // disable stencil testing for translucent interactions, because + // the shadow isn't calculated at their point, and the shadow + // behind them may be depth fighting with a back side, so there + // isn't any reasonable thing to do + qglStencilFunc( GL_ALWAYS, 128, 255 ); + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_CreateDrawInteractions( vLight->translucentInteractions ); +} + + +/* +================== +RB_ARB_DrawInteractions +================== +*/ +void RB_ARB_DrawInteractions( void ) { + qglEnable( GL_STENCIL_TEST ); + + for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + RB_RenderViewLight( vLight ); + } +} + diff --git a/renderer/draw_arb2.cpp b/renderer/draw_arb2.cpp new file mode 100644 index 000000000..2d5f3a33e --- /dev/null +++ b/renderer/draw_arb2.cpp @@ -0,0 +1,528 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +#include "cg_explicit.h" + +CGcontext cg_context; + +static void cg_error_callback( void ) { + CGerror i = cgGetError(); + common->Printf( "Cg error (%d): %s\n", i, cgGetErrorString(i) ); +} + +/* +========================================================================================= + +GENERAL INTERACTION RENDERING + +========================================================================================= +*/ + +/* +==================== +GL_SelectTextureNoClient +==================== +*/ +static void GL_SelectTextureNoClient( int unit ) { + backEnd.glState.currenttmu = unit; + qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); + RB_LogComment( "glActiveTextureARB( %i )\n", unit ); +} + +/* +================== +RB_ARB2_DrawInteraction +================== +*/ +void RB_ARB2_DrawInteraction( const drawInteraction_t *din ) { + // load all the vertex program parameters + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() ); + + // testing fragment based normal mapping + if ( r_testARBProgram.GetBool() ) { + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.ToFloatPtr() ); + } + + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + static const float negOne[4] = { -1, -1, -1, -1 }; + + switch ( din->vertexColor ) { + case SVC_IGNORE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + case SVC_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero ); + break; + case SVC_INVERSE_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + } + + // set the constant colors + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr() ); + + // set the textures + + // texture 1 will be the per-surface bump map + GL_SelectTextureNoClient( 1 ); + din->bumpImage->Bind(); + + // texture 2 will be the light falloff texture + GL_SelectTextureNoClient( 2 ); + din->lightFalloffImage->Bind(); + + // texture 3 will be the light projection texture + GL_SelectTextureNoClient( 3 ); + din->lightImage->Bind(); + + // texture 4 is the per-surface diffuse map + GL_SelectTextureNoClient( 4 ); + din->diffuseImage->Bind(); + + // texture 5 is the per-surface specular map + GL_SelectTextureNoClient( 5 ); + din->specularImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( din->surf->geo ); +} + + +/* +============= +RB_ARB2_CreateDrawInteractions + +============= +*/ +void RB_ARB2_CreateDrawInteractions( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + + // perform setup here that will be constant for all interactions + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); + + // bind the vertex program + if ( r_testARBProgram.GetBool() ) { + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST ); + } else { + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION ); + } + + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + // enable the vertex arrays + qglEnableVertexAttribArrayARB( 8 ); + qglEnableVertexAttribArrayARB( 9 ); + qglEnableVertexAttribArrayARB( 10 ); + qglEnableVertexAttribArrayARB( 11 ); + qglEnableClientState( GL_COLOR_ARRAY ); + + // texture 0 is the normalization cube map for the vector towards the light + GL_SelectTextureNoClient( 0 ); + if ( backEnd.vLight->lightShader->IsAmbientLight() ) { + globalImages->ambientNormalMap->Bind(); + } else { + globalImages->normalCubeMapImage->Bind(); + } + + // texture 6 is the specular lookup table + GL_SelectTextureNoClient( 6 ); + if ( r_testARBProgram.GetBool() ) { + globalImages->specular2DTableImage->Bind(); // variable specularity in alpha channel + } else { + globalImages->specularTableImage->Bind(); + } + + + for ( ; surf ; surf=surf->nextOnLight ) { + // perform setup here that will not change over multiple interaction passes + + // set the vertex pointers + idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); + qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + + // this may cause RB_ARB2_DrawInteraction to be exacuted multiple + // times with different colors and images if the surface or light have multiple layers + RB_CreateSingleDrawInteractions( surf, RB_ARB2_DrawInteraction ); + } + + qglDisableVertexAttribArrayARB( 8 ); + qglDisableVertexAttribArrayARB( 9 ); + qglDisableVertexAttribArrayARB( 10 ); + qglDisableVertexAttribArrayARB( 11 ); + qglDisableClientState( GL_COLOR_ARRAY ); + + // disable features + GL_SelectTextureNoClient( 6 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 5 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 4 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 3 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 2 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 1 ); + globalImages->BindNull(); + + backEnd.glState.currenttmu = -1; + GL_SelectTexture( 0 ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); +} + + +/* +================== +RB_ARB2_DrawInteractions +================== +*/ +void RB_ARB2_DrawInteractions( void ) { + viewLight_t *vLight; + const idMaterial *lightShader; + + GL_SelectTexture( 0 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + // + // for each light, perform adding and shadowing + // + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + backEnd.vLight = vLight; + + // do fogging later + if ( vLight->lightShader->IsFogLight() ) { + continue; + } + if ( vLight->lightShader->IsBlendLight() ) { + continue; + } + + if ( !vLight->localInteractions && !vLight->globalInteractions + && !vLight->translucentInteractions ) { + continue; + } + + lightShader = vLight->lightShader; + + // clear the stencil buffer if needed + if ( vLight->globalShadows || vLight->localShadows ) { + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + } else { + // no shadows, so no need to read or write the stencil buffer + // we might in theory want to use GL_ALWAYS instead of disabling + // completely, to satisfy the invarience rules + qglStencilFunc( GL_ALWAYS, 128, 255 ); + } + + if ( r_useShadowVertexProgram.GetBool() ) { + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->globalShadows ); + RB_ARB2_CreateDrawInteractions( vLight->localInteractions ); + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->localShadows ); + RB_ARB2_CreateDrawInteractions( vLight->globalInteractions ); + qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on + } else { + RB_StencilShadowPass( vLight->globalShadows ); + RB_ARB2_CreateDrawInteractions( vLight->localInteractions ); + RB_StencilShadowPass( vLight->localShadows ); + RB_ARB2_CreateDrawInteractions( vLight->globalInteractions ); + } + + // translucent surfaces never get stencil shadowed + if ( r_skipTranslucent.GetBool() ) { + continue; + } + + qglStencilFunc( GL_ALWAYS, 128, 255 ); + + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_ARB2_CreateDrawInteractions( vLight->translucentInteractions ); + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + } + + // disable stencil shadow test + qglStencilFunc( GL_ALWAYS, 128, 255 ); + + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +} + +//=================================================================================== + + +typedef struct { + GLenum target; + GLuint ident; + char name[64]; +} progDef_t; + +static const int MAX_GLPROGS = 200; + +// a single file can have both a vertex program and a fragment program +static progDef_t progs[MAX_GLPROGS] = { + { GL_VERTEX_PROGRAM_ARB, VPROG_TEST, "test.vfp" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST, "test.vfp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION, "interaction.vfp" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION, "interaction.vfp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT, "ambientLight.vfp" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT, "ambientLight.vfp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW, "shadow.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION, "R200_interaction.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT, "nv20_bumpAndLight.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR, "nv20_diffuseColor.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR, "nv20_specularColor.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, "nv20_diffuseAndSpecularColor.vp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT, "environment.vfp" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT, "environment.vfp" }, + { GL_VERTEX_PROGRAM_ARB, VPROG_GLASSWARP, "arbVP_glasswarp.txt" }, + { GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP, "arbFP_glasswarp.txt" }, + + // additional programs can be dynamically specified in materials +}; + +/* +================= +R_LoadARBProgram +================= +*/ +void R_LoadARBProgram( int progIndex ) { + int ofs; + int err; + idStr fullPath = "glprogs/"; + fullPath += progs[progIndex].name; + char *fileBuffer; + char *buffer; + char *start, *end; + + common->Printf( "%s", fullPath.c_str() ); + + // load the program even if we don't support it, so + // fs_copyfiles can generate cross-platform data dumps + fileSystem->ReadFile( fullPath.c_str(), (void **)&fileBuffer, NULL ); + if ( !fileBuffer ) { + common->Printf( ": File not found\n" ); + return; + } + + // copy to stack memory and free + buffer = (char *)_alloca( strlen( fileBuffer ) + 1 ); + strcpy( buffer, fileBuffer ); + fileSystem->FreeFile( fileBuffer ); + + if ( !glConfig.isInitialized ) { + return; + } + + // + // submit the program string at start to GL + // + if ( progs[progIndex].ident == 0 ) { + // allocate a new identifier for this program + progs[progIndex].ident = PROG_USER + progIndex; + } + + // vertex and fragment programs can both be present in a single file, so + // scan for the proper header to be the start point, and stamp a 0 in after the end + + if ( progs[progIndex].target == GL_VERTEX_PROGRAM_ARB ) { + if ( !glConfig.ARBVertexProgramAvailable ) { + common->Printf( ": GL_VERTEX_PROGRAM_ARB not available\n" ); + return; + } + start = strstr( (char *)buffer, "!!ARBvp" ); + } + if ( progs[progIndex].target == GL_FRAGMENT_PROGRAM_ARB ) { + if ( !glConfig.ARBFragmentProgramAvailable ) { + common->Printf( ": GL_FRAGMENT_PROGRAM_ARB not available\n" ); + return; + } + start = strstr( (char *)buffer, "!!ARBfp" ); + } + if ( !start ) { + common->Printf( ": !!ARB not found\n" ); + return; + } + end = strstr( start, "END" ); + + if ( !end ) { + common->Printf( ": END not found\n" ); + return; + } + end[3] = 0; + + qglBindProgramARB( progs[progIndex].target, progs[progIndex].ident ); + qglGetError(); + + qglProgramStringARB( progs[progIndex].target, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen( start ), (unsigned char *)start ); + + err = qglGetError(); + qglGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, (GLint *)&ofs ); + if ( err == GL_INVALID_OPERATION ) { + const GLubyte *str = qglGetString( GL_PROGRAM_ERROR_STRING_ARB ); + common->Printf( "\nGL_PROGRAM_ERROR_STRING_ARB: %s\n", str ); + if ( ofs < 0 ) { + common->Printf( "GL_PROGRAM_ERROR_POSITION_ARB < 0 with error\n" ); + } else if ( ofs >= (int)strlen( (char *)start ) ) { + common->Printf( "error at end of program\n" ); + } else { + common->Printf( "error at %i:\n%s", ofs, start + ofs ); + } + return; + } + if ( ofs != -1 ) { + common->Printf( "\nGL_PROGRAM_ERROR_POSITION_ARB != -1 without error\n" ); + return; + } + + common->Printf( "\n" ); +} + +/* +================== +R_FindARBProgram + +Returns a GL identifier that can be bound to the given target, parsing +a text file if it hasn't already been loaded. +================== +*/ +int R_FindARBProgram( GLenum target, const char *program ) { + int i; + idStr stripped = program; + + stripped.StripFileExtension(); + + // see if it is already loaded + for ( i = 0 ; progs[i].name[0] ; i++ ) { + if ( progs[i].target != target ) { + continue; + } + + idStr compare = progs[i].name; + compare.StripFileExtension(); + + if ( !idStr::Icmp( stripped.c_str(), compare.c_str() ) ) { + return progs[i].ident; + } + } + + if ( i == MAX_GLPROGS ) { + common->Error( "R_FindARBProgram: MAX_GLPROGS" ); + } + + // add it to the list and load it + progs[i].ident = (program_t)0; // will be gen'd by R_LoadARBProgram + progs[i].target = target; + strncpy( progs[i].name, program, sizeof( progs[i].name ) - 1 ); + + R_LoadARBProgram( i ); + + return progs[i].ident; +} + +/* +================== +R_ReloadARBPrograms_f +================== +*/ +void R_ReloadARBPrograms_f( const idCmdArgs &args ) { + int i; + + common->Printf( "----- R_ReloadARBPrograms -----\n" ); + for ( i = 0 ; progs[i].name[0] ; i++ ) { + R_LoadARBProgram( i ); + } + common->Printf( "-------------------------------\n" ); +} + +/* +================== +R_ARB2_Init + +================== +*/ +void R_ARB2_Init( void ) { + glConfig.allowARB2Path = false; + + common->Printf( "---------- R_ARB2_Init ----------\n" ); + + if ( !glConfig.ARBVertexProgramAvailable || !glConfig.ARBFragmentProgramAvailable ) { + common->Printf( "Not available.\n" ); + return; + } + + common->Printf( "Available.\n" ); + + common->Printf( "---------------------------------\n" ); + + glConfig.allowARB2Path = true; +} + diff --git a/renderer/draw_common.cpp b/renderer/draw_common.cpp new file mode 100644 index 000000000..61a4ec393 --- /dev/null +++ b/renderer/draw_common.cpp @@ -0,0 +1,1716 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +===================== +RB_BakeTextureMatrixIntoTexgen +===================== +*/ +void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float *textureMatrix ) { + float genMatrix[16]; + float final[16]; + + genMatrix[0] = lightProject[0][0]; + genMatrix[4] = lightProject[0][1]; + genMatrix[8] = lightProject[0][2]; + genMatrix[12] = lightProject[0][3]; + + genMatrix[1] = lightProject[1][0]; + genMatrix[5] = lightProject[1][1]; + genMatrix[9] = lightProject[1][2]; + genMatrix[13] = lightProject[1][3]; + + genMatrix[2] = 0; + genMatrix[6] = 0; + genMatrix[10] = 0; + genMatrix[14] = 0; + + genMatrix[3] = lightProject[2][0]; + genMatrix[7] = lightProject[2][1]; + genMatrix[11] = lightProject[2][2]; + genMatrix[15] = lightProject[2][3]; + + myGlMultMatrix( genMatrix, backEnd.lightTextureMatrix, final ); + + lightProject[0][0] = final[0]; + lightProject[0][1] = final[4]; + lightProject[0][2] = final[8]; + lightProject[0][3] = final[12]; + + lightProject[1][0] = final[1]; + lightProject[1][1] = final[5]; + lightProject[1][2] = final[9]; + lightProject[1][3] = final[13]; +} + +/* +================ +RB_PrepareStageTexturing +================ +*/ +void RB_PrepareStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) { + // set privatePolygonOffset if necessary + if ( pStage->privatePolygonOffset ) { + qglEnable( GL_POLYGON_OFFSET_FILL ); + qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset ); + } + + // set the texture matrix if needed + if ( pStage->texture.hasMatrix ) { + RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture ); + } + + // texgens + if ( pStage->texture.texgen == TG_DIFFUSE_CUBE ) { + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + } + if ( pStage->texture.texgen == TG_SKYBOX_CUBE || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) { + qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) ); + } + if ( pStage->texture.texgen == TG_SCREEN ) { + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + + float mat[16], plane[4]; + myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); + + plane[0] = mat[0]; + plane[1] = mat[4]; + plane[2] = mat[8]; + plane[3] = mat[12]; + qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[1]; + plane[1] = mat[5]; + plane[2] = mat[9]; + plane[3] = mat[13]; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[3]; + plane[1] = mat[7]; + plane[2] = mat[11]; + plane[3] = mat[15]; + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); + } + + if ( pStage->texture.texgen == TG_SCREEN2 ) { + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + + float mat[16], plane[4]; + myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); + + plane[0] = mat[0]; + plane[1] = mat[4]; + plane[2] = mat[8]; + plane[3] = mat[12]; + qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[1]; + plane[1] = mat[5]; + plane[2] = mat[9]; + plane[3] = mat[13]; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[3]; + plane[1] = mat[7]; + plane[2] = mat[11]; + plane[3] = mat[15]; + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); + } + + if ( pStage->texture.texgen == TG_GLASSWARP ) { + if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) { + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP ); + qglEnable( GL_FRAGMENT_PROGRAM_ARB ); + + GL_SelectTexture( 2 ); + globalImages->scratchImage->Bind(); + + GL_SelectTexture( 1 ); + globalImages->scratchImage2->Bind(); + + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + + float mat[16], plane[4]; + myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); + + plane[0] = mat[0]; + plane[1] = mat[4]; + plane[2] = mat[8]; + plane[3] = mat[12]; + qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[1]; + plane[1] = mat[5]; + plane[2] = mat[9]; + plane[3] = mat[13]; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); + + plane[0] = mat[3]; + plane[1] = mat[7]; + plane[2] = mat[11]; + plane[3] = mat[15]; + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); + + GL_SelectTexture( 0 ); + } + } + + if ( pStage->texture.texgen == TG_REFLECT_CUBE ) { + if ( tr.backEndRenderer == BE_ARB2 ) { + // see if there is also a bump map specified + const shaderStage_t *bumpStage = surf->material->GetBumpStage(); + if ( bumpStage ) { + // per-pixel reflection mapping with bump mapping + GL_SelectTexture( 1 ); + bumpStage->texture.image->Bind(); + GL_SelectTexture( 0 ); + + qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + + qglEnableVertexAttribArrayARB( 9 ); + qglEnableVertexAttribArrayARB( 10 ); + qglEnableClientState( GL_NORMAL_ARRAY ); + + // Program env 5, 6, 7, 8 have been set in RB_SetProgramEnvironmentSpace + + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT ); + qglEnable( GL_FRAGMENT_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT ); + qglEnable( GL_VERTEX_PROGRAM_ARB ); + } else { + // per-pixel reflection mapping without a normal map + qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + qglEnableClientState( GL_NORMAL_ARRAY ); + + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT ); + qglEnable( GL_FRAGMENT_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT ); + qglEnable( GL_VERTEX_PROGRAM_ARB ); + } + } else { + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_R ); + qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglEnableClientState( GL_NORMAL_ARRAY ); + qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + + qglMatrixMode( GL_TEXTURE ); + float mat[16]; + + R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat ); + + qglLoadMatrixf( mat ); + qglMatrixMode( GL_MODELVIEW ); + } + } +} + +/* +================ +RB_FinishStageTexturing +================ +*/ +void RB_FinishStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) { + // unset privatePolygonOffset if necessary + if ( pStage->privatePolygonOffset && !surf->material->TestMaterialFlag(MF_POLYGONOFFSET) ) { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } + + if ( pStage->texture.texgen == TG_DIFFUSE_CUBE || pStage->texture.texgen == TG_SKYBOX_CUBE + || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) { + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st ); + } + + if ( pStage->texture.texgen == TG_SCREEN ) { + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + } + if ( pStage->texture.texgen == TG_SCREEN2 ) { + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + } + + if ( pStage->texture.texgen == TG_GLASSWARP ) { + if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) { + GL_SelectTexture( 2 ); + globalImages->BindNull(); + + GL_SelectTexture( 1 ); + if ( pStage->texture.hasMatrix ) { + RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture ); + } + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + qglDisable( GL_FRAGMENT_PROGRAM_ARB ); + globalImages->BindNull(); + GL_SelectTexture( 0 ); + } + } + + if ( pStage->texture.texgen == TG_REFLECT_CUBE ) { + if ( tr.backEndRenderer == BE_ARB2 ) { + // see if there is also a bump map specified + const shaderStage_t *bumpStage = surf->material->GetBumpStage(); + if ( bumpStage ) { + // per-pixel reflection mapping with bump mapping + GL_SelectTexture( 1 ); + globalImages->BindNull(); + GL_SelectTexture( 0 ); + + qglDisableVertexAttribArrayARB( 9 ); + qglDisableVertexAttribArrayARB( 10 ); + } else { + // per-pixel reflection mapping without bump mapping + } + + qglDisableClientState( GL_NORMAL_ARRAY ); + qglDisable( GL_FRAGMENT_PROGRAM_ARB ); + qglDisable( GL_VERTEX_PROGRAM_ARB ); + // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed. + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 ); + } else { + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_R ); + qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglDisableClientState( GL_NORMAL_ARRAY ); + + qglMatrixMode( GL_TEXTURE ); + qglLoadIdentity(); + qglMatrixMode( GL_MODELVIEW ); + } + } + + if ( pStage->texture.hasMatrix ) { + qglMatrixMode( GL_TEXTURE ); + qglLoadIdentity(); + qglMatrixMode( GL_MODELVIEW ); + } +} + +/* +============================================================================================= + +FILL DEPTH BUFFER + +============================================================================================= +*/ + + +/* +================== +RB_T_FillDepthBuffer +================== +*/ +void RB_T_FillDepthBuffer( const drawSurf_t *surf ) { + int stage; + const idMaterial *shader; + const shaderStage_t *pStage; + const float *regs; + float color[4]; + const srfTriangles_t *tri; + + tri = surf->geo; + shader = surf->material; + + // update the clip plane if needed + if ( backEnd.viewDef->numClipPlanes && surf->space != backEnd.currentSpace ) { + GL_SelectTexture( 1 ); + + idPlane plane; + + R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.viewDef->clipPlanes[0], plane ); + plane[3] += 0.5; // the notch is in the middle + qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane.ToFloatPtr() ); + GL_SelectTexture( 0 ); + } + + if ( !shader->IsDrawn() ) { + return; + } + + // some deforms may disable themselves by setting numIndexes = 0 + if ( !tri->numIndexes ) { + return; + } + + // translucent surfaces don't put anything in the depth buffer and don't + // test against it, which makes them fail the mirror clip plane operation + if ( shader->Coverage() == MC_TRANSLUCENT ) { + return; + } + + if ( !tri->ambientCache ) { + common->Printf( "RB_T_FillDepthBuffer: !tri->ambientCache\n" ); + return; + } + + // get the expressions for conditionals / color / texcoords + regs = surf->shaderRegisters; + + // if all stages of a material have been conditioned off, don't do anything + for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) { + pStage = shader->GetStage(stage); + // check the stage enable condition + if ( regs[ pStage->conditionRegister ] != 0 ) { + break; + } + } + if ( stage == shader->GetNumStages() ) { + return; + } + + // set polygon offset if necessary + if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { + qglEnable( GL_POLYGON_OFFSET_FILL ); + qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() ); + } + + // subviews will just down-modulate the color buffer by overbright + if ( shader->GetSort() == SS_SUBVIEW ) { + GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHFUNC_LESS ); + color[0] = + color[1] = + color[2] = ( 1.0 / backEnd.overBright ); + color[3] = 1; + } else { + // others just draw black + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 1; + } + + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast(&ac->st) ); + + bool drawSolid = false; + + if ( shader->Coverage() == MC_OPAQUE ) { + drawSolid = true; + } + + // we may have multiple alpha tested stages + if ( shader->Coverage() == MC_PERFORATED ) { + // if the only alpha tested stages are condition register omitted, + // draw a normal opaque surface + bool didDraw = false; + + qglEnable( GL_ALPHA_TEST ); + // perforated surfaces may have multiple alpha tested stages + for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) { + pStage = shader->GetStage(stage); + + if ( !pStage->hasAlphaTest ) { + continue; + } + + // check the stage enable condition + if ( regs[ pStage->conditionRegister ] == 0 ) { + continue; + } + + // if we at least tried to draw an alpha tested stage, + // we won't draw the opaque surface + didDraw = true; + + // set the alpha modulate + color[3] = regs[ pStage->color.registers[3] ]; + + // skip the entire stage if alpha would be black + if ( color[3] <= 0 ) { + continue; + } + qglColor4fv( color ); + + qglAlphaFunc( GL_GREATER, regs[ pStage->alphaTestRegister ] ); + + // bind the texture + pStage->texture.image->Bind(); + + // set texture matrix and texGens + RB_PrepareStageTexturing( pStage, surf, ac ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + RB_FinishStageTexturing( pStage, surf, ac ); + } + qglDisable( GL_ALPHA_TEST ); + if ( !didDraw ) { + drawSolid = true; + } + } + + // draw the entire surface solid + if ( drawSolid ) { + qglColor4fv( color ); + globalImages->whiteImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( tri ); + } + + + // reset polygon offset + if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } + + // reset blending + if ( shader->GetSort() == SS_SUBVIEW ) { + GL_State( GLS_DEPTHFUNC_LESS ); + } + +} + +/* +===================== +RB_STD_FillDepthBuffer + +If we are rendering a subview with a near clip plane, use a second texture +to force the alpha test to fail when behind that clip plane +===================== +*/ +void RB_STD_FillDepthBuffer( drawSurf_t **drawSurfs, int numDrawSurfs ) { + // if we are just doing 2D rendering, no need to fill the depth buffer + if ( !backEnd.viewDef->viewEntitys ) { + return; + } + + RB_LogComment( "---------- RB_STD_FillDepthBuffer ----------\n" ); + + // enable the second texture for mirror plane clipping if needed + if ( backEnd.viewDef->numClipPlanes ) { + GL_SelectTexture( 1 ); + globalImages->alphaNotchImage->Bind(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglTexCoord2f( 1, 0.5 ); + } + + // the first texture will be used for alpha tested surfaces + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + // decal surfaces may enable polygon offset + qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() ); + + GL_State( GLS_DEPTHFUNC_LESS ); + + // Enable stencil test if we are going to be using it for shadows. + // If we didn't do this, it would be legal behavior to get z fighting + // from the ambient pass and the light passes. + qglEnable( GL_STENCIL_TEST ); + qglStencilFunc( GL_ALWAYS, 1, 255 ); + + RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_T_FillDepthBuffer ); + + if ( backEnd.viewDef->numClipPlanes ) { + GL_SelectTexture( 1 ); + globalImages->BindNull(); + qglDisable( GL_TEXTURE_GEN_S ); + GL_SelectTexture( 0 ); + } + +} + +/* +============================================================================================= + +SHADER PASSES + +============================================================================================= +*/ + +/* +================== +RB_SetProgramEnvironment + +Sets variables that can be used by all vertex programs +================== +*/ +void RB_SetProgramEnvironment( void ) { + float parm[4]; + int pot; + + if ( !glConfig.ARBVertexProgramAvailable ) { + return; + } + +#if 0 + // screen power of two correction factor, one pixel in so we don't get a bilerp + // of an uncopied pixel + int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; + pot = globalImages->currentRenderImage->uploadWidth; + if ( w == pot ) { + parm[0] = 1.0; + } else { + parm[0] = (float)(w-1) / pot; + } + + int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; + pot = globalImages->currentRenderImage->uploadHeight; + if ( h == pot ) { + parm[1] = 1.0; + } else { + parm[1] = (float)(h-1) / pot; + } + + parm[2] = 0; + parm[3] = 1; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm ); +#else + // screen power of two correction factor, assuming the copy to _currentRender + // also copied an extra row and column for the bilerp + int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; + pot = globalImages->currentRenderImage->uploadWidth; + parm[0] = (float)w / pot; + + int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; + pot = globalImages->currentRenderImage->uploadHeight; + parm[1] = (float)h / pot; + + parm[2] = 0; + parm[3] = 1; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm ); +#endif + + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + + // window coord to 0.0 to 1.0 conversion + parm[0] = 1.0 / w; + parm[1] = 1.0 / h; + parm[2] = 0; + parm[3] = 1; + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm ); + + // + // set eye position in global space + // + parm[0] = backEnd.viewDef->renderView.vieworg[0]; + parm[1] = backEnd.viewDef->renderView.vieworg[1]; + parm[2] = backEnd.viewDef->renderView.vieworg[2]; + parm[3] = 1.0; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 1, parm ); + + +} + +/* +================== +RB_SetProgramEnvironmentSpace + +Sets variables related to the current space that can be used by all vertex programs +================== +*/ +void RB_SetProgramEnvironmentSpace( void ) { + if ( !glConfig.ARBVertexProgramAvailable ) { + return; + } + + const struct viewEntity_s *space = backEnd.currentSpace; + float parm[4]; + + // set eye position in local space + R_GlobalPointToLocal( space->modelMatrix, backEnd.viewDef->renderView.vieworg, *(idVec3 *)parm ); + parm[3] = 1.0; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 5, parm ); + + // we need the model matrix without it being combined with the view matrix + // so we can transform local vectors to global coordinates + parm[0] = space->modelMatrix[0]; + parm[1] = space->modelMatrix[4]; + parm[2] = space->modelMatrix[8]; + parm[3] = space->modelMatrix[12]; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 6, parm ); + parm[0] = space->modelMatrix[1]; + parm[1] = space->modelMatrix[5]; + parm[2] = space->modelMatrix[9]; + parm[3] = space->modelMatrix[13]; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 7, parm ); + parm[0] = space->modelMatrix[2]; + parm[1] = space->modelMatrix[6]; + parm[2] = space->modelMatrix[10]; + parm[3] = space->modelMatrix[14]; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 8, parm ); +} + +/* +================== +RB_STD_T_RenderShaderPasses + +This is also called for the generated 2D rendering +================== +*/ +void RB_STD_T_RenderShaderPasses( const drawSurf_t *surf ) { + int stage; + const idMaterial *shader; + const shaderStage_t *pStage; + const float *regs; + float color[4]; + const srfTriangles_t *tri; + + tri = surf->geo; + shader = surf->material; + + if ( !shader->HasAmbient() ) { + return; + } + + if ( shader->IsPortalSky() ) { + return; + } + + // change the matrix if needed + if ( surf->space != backEnd.currentSpace ) { + qglLoadMatrixf( surf->space->modelViewMatrix ); + backEnd.currentSpace = surf->space; + RB_SetProgramEnvironmentSpace(); + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) { + backEnd.currentScissor = surf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + + // some deforms may disable themselves by setting numIndexes = 0 + if ( !tri->numIndexes ) { + return; + } + + if ( !tri->ambientCache ) { + common->Printf( "RB_T_RenderShaderPasses: !tri->ambientCache\n" ); + return; + } + + // get the expressions for conditionals / color / texcoords + regs = surf->shaderRegisters; + + // set face culling appropriately + GL_Cull( shader->GetCullType() ); + + // set polygon offset if necessary + if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { + qglEnable( GL_POLYGON_OFFSET_FILL ); + qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() ); + } + + if ( surf->space->weaponDepthHack ) { + RB_EnterWeaponDepthHack(); + } + + if ( surf->space->modelDepthHack != 0.0f ) { + RB_EnterModelDepthHack( surf->space->modelDepthHack ); + } + + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast(&ac->st) ); + + for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) { + pStage = shader->GetStage(stage); + + // check the enable condition + if ( regs[ pStage->conditionRegister ] == 0 ) { + continue; + } + + // skip the stages involved in lighting + if ( pStage->lighting != SL_AMBIENT ) { + continue; + } + + // skip if the stage is ( GL_ZERO, GL_ONE ), which is used for some alpha masks + if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE ) ) { + continue; + } + + // see if we are a new-style stage + newShaderStage_t *newStage = pStage->newStage; + if ( newStage ) { + //-------------------------- + // + // new style stages + // + //-------------------------- + + // completely skip the stage if we don't have the capability + if ( tr.backEndRenderer != BE_ARB2 ) { + continue; + } + if ( r_skipNewAmbient.GetBool() ) { + continue; + } + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); + qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + + qglEnableClientState( GL_COLOR_ARRAY ); + qglEnableVertexAttribArrayARB( 9 ); + qglEnableVertexAttribArrayARB( 10 ); + qglEnableClientState( GL_NORMAL_ARRAY ); + + GL_State( pStage->drawStateBits ); + + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, newStage->vertexProgram ); + qglEnable( GL_VERTEX_PROGRAM_ARB ); + + // megaTextures bind a lot of images and set a lot of parameters + if ( newStage->megaTexture ) { + newStage->megaTexture->SetMappingForSurface( tri ); + idVec3 localViewer; + R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewer ); + newStage->megaTexture->BindForViewOrigin( localViewer ); + } + + for ( int i = 0 ; i < newStage->numVertexParms ; i++ ) { + float parm[4]; + parm[0] = regs[ newStage->vertexParms[i][0] ]; + parm[1] = regs[ newStage->vertexParms[i][1] ]; + parm[2] = regs[ newStage->vertexParms[i][2] ]; + parm[3] = regs[ newStage->vertexParms[i][3] ]; + qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, parm ); + } + + for ( int i = 0 ; i < newStage->numFragmentProgramImages ; i++ ) { + if ( newStage->fragmentProgramImages[i] ) { + GL_SelectTexture( i ); + newStage->fragmentProgramImages[i]->Bind(); + } + } + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, newStage->fragmentProgram ); + qglEnable( GL_FRAGMENT_PROGRAM_ARB ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + for ( int i = 1 ; i < newStage->numFragmentProgramImages ; i++ ) { + if ( newStage->fragmentProgramImages[i] ) { + GL_SelectTexture( i ); + globalImages->BindNull(); + } + } + if ( newStage->megaTexture ) { + newStage->megaTexture->Unbind(); + } + + GL_SelectTexture( 0 ); + + qglDisable( GL_VERTEX_PROGRAM_ARB ); + qglDisable( GL_FRAGMENT_PROGRAM_ARB ); + // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed. + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 ); + + qglDisableClientState( GL_COLOR_ARRAY ); + qglDisableVertexAttribArrayARB( 9 ); + qglDisableVertexAttribArrayARB( 10 ); + qglDisableClientState( GL_NORMAL_ARRAY ); + continue; + } + + //-------------------------- + // + // old style stages + // + //-------------------------- + + // set the color + color[0] = regs[ pStage->color.registers[0] ]; + color[1] = regs[ pStage->color.registers[1] ]; + color[2] = regs[ pStage->color.registers[2] ]; + color[3] = regs[ pStage->color.registers[3] ]; + + // skip the entire stage if an add would be black + if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ) + && color[0] <= 0 && color[1] <= 0 && color[2] <= 0 ) { + continue; + } + + // skip the entire stage if a blend would be completely transparent + if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) + && color[3] <= 0 ) { + continue; + } + + // select the vertex color source + if ( pStage->vertexColor == SVC_IGNORE ) { + qglColor4fv( color ); + } else { + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color ); + qglEnableClientState( GL_COLOR_ARRAY ); + + if ( pStage->vertexColor == SVC_INVERSE_MODULATE ) { + GL_TexEnv( GL_COMBINE_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + } + + // for vertex color and modulated color, we need to enable a second + // texture stage + if ( color[0] != 1 || color[1] != 1 || color[2] != 1 || color[3] != 1 ) { + GL_SelectTexture( 1 ); + + globalImages->whiteImage->Bind(); + GL_TexEnv( GL_COMBINE_ARB ); + + qglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color ); + + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); + qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 ); + + qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT_ARB ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA ); + qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); + qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 ); + + GL_SelectTexture( 0 ); + } + } + + // bind the texture + RB_BindVariableStageImage( &pStage->texture, regs ); + + // set the state + GL_State( pStage->drawStateBits ); + + RB_PrepareStageTexturing( pStage, surf, ac ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + RB_FinishStageTexturing( pStage, surf, ac ); + + if ( pStage->vertexColor != SVC_IGNORE ) { + qglDisableClientState( GL_COLOR_ARRAY ); + + GL_SelectTexture( 1 ); + GL_TexEnv( GL_MODULATE ); + globalImages->BindNull(); + GL_SelectTexture( 0 ); + GL_TexEnv( GL_MODULATE ); + } + } + + // reset polygon offset + if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } + if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) { + RB_LeaveDepthHack(); + } +} + +/* +===================== +RB_STD_DrawShaderPasses + +Draw non-light dependent passes +===================== +*/ +int RB_STD_DrawShaderPasses( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i; + + // only obey skipAmbient if we are rendering a view + if ( backEnd.viewDef->viewEntitys && r_skipAmbient.GetBool() ) { + return numDrawSurfs; + } + + RB_LogComment( "---------- RB_STD_DrawShaderPasses ----------\n" ); + + // if we are about to draw the first surface that needs + // the rendering in a texture, copy it over + if ( drawSurfs[0]->material->GetSort() >= SS_POST_PROCESS ) { + if ( r_skipPostProcess.GetBool() ) { + return 0; + } + + // only dump if in a 3d view + if ( backEnd.viewDef->viewEntitys && tr.backEndRenderer == BE_ARB2 ) { + globalImages->currentRenderImage->CopyFramebuffer( backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y1, backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1, + backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1, true ); + } + backEnd.currentRenderCopied = true; + } + + GL_SelectTexture( 1 ); + globalImages->BindNull(); + + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + RB_SetProgramEnvironment(); + + // we don't use RB_RenderDrawSurfListWithFunction() + // because we want to defer the matrix load because many + // surfaces won't draw any ambient passes + backEnd.currentSpace = NULL; + for (i = 0 ; i < numDrawSurfs ; i++ ) { + if ( drawSurfs[i]->material->SuppressInSubview() ) { + continue; + } + + if ( backEnd.viewDef->isXraySubview && drawSurfs[i]->space->entityDef ) { + if ( drawSurfs[i]->space->entityDef->parms.xrayIndex != 2 ) { + continue; + } + } + + // we need to draw the post process shaders after we have drawn the fog lights + if ( drawSurfs[i]->material->GetSort() >= SS_POST_PROCESS + && !backEnd.currentRenderCopied ) { + break; + } + + RB_STD_T_RenderShaderPasses( drawSurfs[i] ); + } + + GL_Cull( CT_FRONT_SIDED ); + qglColor3f( 1, 1, 1 ); + + return i; +} + + + +/* +============================================================================== + +BACK END RENDERING OF STENCIL SHADOWS + +============================================================================== +*/ + +/* +===================== +RB_T_Shadow + +the shadow volumes face INSIDE +===================== +*/ +static void RB_T_Shadow( const drawSurf_t *surf ) { + const srfTriangles_t *tri; + + // set the light position if we are using a vertex program to project the rear surfaces + if ( tr.backEndRendererHasVertexPrograms && r_useShadowVertexProgram.GetBool() + && surf->space != backEnd.currentSpace ) { + idVec4 localLight; + + R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.vLight->globalLightOrigin, localLight.ToVec3() ); + localLight.w = 0.0f; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, localLight.ToFloatPtr() ); + } + + tri = surf->geo; + + if ( !tri->shadowCache ) { + return; + } + + qglVertexPointer( 4, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position(tri->shadowCache) ); + + // we always draw the sil planes, but we may not need to draw the front or rear caps + int numIndexes; + bool external = false; + + if ( !r_useExternalShadows.GetInteger() ) { + numIndexes = tri->numIndexes; + } else if ( r_useExternalShadows.GetInteger() == 2 ) { // force to no caps for testing + numIndexes = tri->numShadowIndexesNoCaps; + } else if ( !(surf->dsFlags & DSF_VIEW_INSIDE_SHADOW) ) { + // if we aren't inside the shadow projection, no caps are ever needed needed + numIndexes = tri->numShadowIndexesNoCaps; + external = true; + } else if ( !backEnd.vLight->viewInsideLight && !(surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE) ) { + // if we are inside the shadow projection, but outside the light, and drawing + // a non-infinite shadow, we can skip some caps + if ( backEnd.vLight->viewSeesShadowPlaneBits & surf->geo->shadowCapPlaneBits ) { + // we can see through a rear cap, so we need to draw it, but we can skip the + // caps on the actual surface + numIndexes = tri->numShadowIndexesNoFrontCaps; + } else { + // we don't need to draw any caps + numIndexes = tri->numShadowIndexesNoCaps; + } + external = true; + } else { + // must draw everything + numIndexes = tri->numIndexes; + } + + // set depth bounds + if( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) { + qglDepthBoundsEXT( surf->scissorRect.zmin, surf->scissorRect.zmax ); + } + + // debug visualization + if ( r_showShadows.GetInteger() ) { + if ( r_showShadows.GetInteger() == 3 ) { + if ( external ) { + qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright ); + } else { + // these are the surfaces that require the reverse + qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright ); + } + } else { + // draw different color for turboshadows + if ( surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE ) { + if ( numIndexes == tri->numIndexes ) { + qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright ); + } else { + qglColor3f( 1/backEnd.overBright, 0.4/backEnd.overBright, 0.1/backEnd.overBright ); + } + } else { + if ( numIndexes == tri->numIndexes ) { + qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright ); + } else if ( numIndexes == tri->numShadowIndexesNoFrontCaps ) { + qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.6/backEnd.overBright ); + } else { + qglColor3f( 0.6/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright ); + } + } + } + + qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + qglDisable( GL_STENCIL_TEST ); + GL_Cull( CT_TWO_SIDED ); + RB_DrawShadowElementsWithCounters( tri, numIndexes ); + GL_Cull( CT_FRONT_SIDED ); + qglEnable( GL_STENCIL_TEST ); + + return; + } + + // patent-free work around + if ( !external ) { + // "preload" the stencil buffer with the number of volumes + // that get clipped by the near or far clip plane + qglStencilOp( GL_KEEP, tr.stencilDecr, tr.stencilDecr ); + GL_Cull( CT_FRONT_SIDED ); + RB_DrawShadowElementsWithCounters( tri, numIndexes ); + qglStencilOp( GL_KEEP, tr.stencilIncr, tr.stencilIncr ); + GL_Cull( CT_BACK_SIDED ); + RB_DrawShadowElementsWithCounters( tri, numIndexes ); + } + + // traditional depth-pass stencil shadows + qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilIncr ); + GL_Cull( CT_FRONT_SIDED ); + RB_DrawShadowElementsWithCounters( tri, numIndexes ); + + qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilDecr ); + GL_Cull( CT_BACK_SIDED ); + RB_DrawShadowElementsWithCounters( tri, numIndexes ); +} + +/* +===================== +RB_StencilShadowPass + +Stencil test should already be enabled, and the stencil buffer should have +been set to 128 on any surfaces that might receive shadows +===================== +*/ +void RB_StencilShadowPass( const drawSurf_t *drawSurfs ) { + if ( !r_shadows.GetBool() ) { + return; + } + + if ( !drawSurfs ) { + return; + } + + RB_LogComment( "---------- RB_StencilShadowPass ----------\n" ); + + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + // for visualizing the shadows + if ( r_showShadows.GetInteger() ) { + if ( r_showShadows.GetInteger() == 2 ) { + // draw filled in + GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_LESS ); + } else { + // draw as lines, filling the depth buffer + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); + } + } else { + // don't write to the color buffer, just the stencil buffer + GL_State( GLS_DEPTHMASK | GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHFUNC_LESS ); + } + + if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) { + qglPolygonOffset( r_shadowPolygonFactor.GetFloat(), -r_shadowPolygonOffset.GetFloat() ); + qglEnable( GL_POLYGON_OFFSET_FILL ); + } + + qglStencilFunc( GL_ALWAYS, 1, 255 ); + + if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) { + qglEnable( GL_DEPTH_BOUNDS_TEST_EXT ); + } + + RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_Shadow ); + + GL_Cull( CT_FRONT_SIDED ); + + if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } + + if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) { + qglDisable( GL_DEPTH_BOUNDS_TEST_EXT ); + } + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + qglStencilFunc( GL_GEQUAL, 128, 255 ); + qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); +} + + + +/* +============================================================================================= + +BLEND LIGHT PROJECTION + +============================================================================================= +*/ + +/* +===================== +RB_T_BlendLight + +===================== +*/ +static void RB_T_BlendLight( const drawSurf_t *surf ) { + const srfTriangles_t *tri; + + tri = surf->geo; + + if ( backEnd.currentSpace != surf->space ) { + idPlane lightProject[4]; + int i; + + for ( i = 0 ; i < 4 ; i++ ) { + R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] ); + } + + GL_SelectTexture( 0 ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[0].ToFloatPtr() ); + qglTexGenfv( GL_T, GL_OBJECT_PLANE, lightProject[1].ToFloatPtr() ); + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, lightProject[2].ToFloatPtr() ); + + GL_SelectTexture( 1 ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[3].ToFloatPtr() ); + } + + // this gets used for both blend lights and shadow draws + if ( tri->ambientCache ) { + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + } else if ( tri->shadowCache ) { + shadowCache_t *sc = (shadowCache_t *)vertexCache.Position( tri->shadowCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), sc->xyz.ToFloatPtr() ); + } + + RB_DrawElementsWithCounters( tri ); +} + + +/* +===================== +RB_BlendLight + +Dual texture together the falloff and projection texture with a blend +mode to the framebuffer, instead of interacting with the surface texture +===================== +*/ +static void RB_BlendLight( const drawSurf_t *drawSurfs, const drawSurf_t *drawSurfs2 ) { + const idMaterial *lightShader; + const shaderStage_t *stage; + int i; + const float *regs; + + if ( !drawSurfs ) { + return; + } + if ( r_skipBlendLights.GetBool() ) { + return; + } + RB_LogComment( "---------- RB_BlendLight ----------\n" ); + + lightShader = backEnd.vLight->lightShader; + regs = backEnd.vLight->shaderRegisters; + + // texture 1 will get the falloff texture + GL_SelectTexture( 1 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglTexCoord2f( 0, 0.5 ); + backEnd.vLight->falloffImage->Bind(); + + // texture 0 will get the projected texture + GL_SelectTexture( 0 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + + for ( i = 0 ; i < lightShader->GetNumStages() ; i++ ) { + stage = lightShader->GetStage(i); + + if ( !regs[ stage->conditionRegister ] ) { + continue; + } + + GL_State( GLS_DEPTHMASK | stage->drawStateBits | GLS_DEPTHFUNC_EQUAL ); + + GL_SelectTexture( 0 ); + stage->texture.image->Bind(); + + if ( stage->texture.hasMatrix ) { + RB_LoadShaderTextureMatrix( regs, &stage->texture ); + } + + // get the modulate values from the light, including alpha, unlike normal lights + backEnd.lightColor[0] = regs[ stage->color.registers[0] ]; + backEnd.lightColor[1] = regs[ stage->color.registers[1] ]; + backEnd.lightColor[2] = regs[ stage->color.registers[2] ]; + backEnd.lightColor[3] = regs[ stage->color.registers[3] ]; + qglColor4fv( backEnd.lightColor ); + + RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BlendLight ); + RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BlendLight ); + + if ( stage->texture.hasMatrix ) { + GL_SelectTexture( 0 ); + qglMatrixMode( GL_TEXTURE ); + qglLoadIdentity(); + qglMatrixMode( GL_MODELVIEW ); + } + } + + GL_SelectTexture( 1 ); + qglDisable( GL_TEXTURE_GEN_S ); + globalImages->BindNull(); + + GL_SelectTexture( 0 ); + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); +} + + +//======================================================================== + +static idPlane fogPlanes[4]; + +/* +===================== +RB_T_BasicFog + +===================== +*/ +static void RB_T_BasicFog( const drawSurf_t *surf ) { + if ( backEnd.currentSpace != surf->space ) { + idPlane local; + + GL_SelectTexture( 0 ); + + R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[0], local ); + local[3] += 0.5; + qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() ); + +// R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[1], local ); +// local[3] += 0.5; +local[0] = local[1] = local[2] = 0; local[3] = 0.5; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() ); + + GL_SelectTexture( 1 ); + + // GL_S is constant per viewer + R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[2], local ); + local[3] += FOG_ENTER; + qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() ); + + R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[3], local ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() ); + } + + RB_T_RenderTriangleSurface( surf ); +} + + + +/* +================== +RB_FogPass +================== +*/ +static void RB_FogPass( const drawSurf_t *drawSurfs, const drawSurf_t *drawSurfs2 ) { + const srfTriangles_t*frustumTris; + drawSurf_t ds; + const idMaterial *lightShader; + const shaderStage_t *stage; + const float *regs; + + RB_LogComment( "---------- RB_FogPass ----------\n" ); + + // create a surface for the light frustom triangles, which are oriented drawn side out + frustumTris = backEnd.vLight->frustumTris; + + // if we ran out of vertex cache memory, skip it + if ( !frustumTris->ambientCache ) { + return; + } + memset( &ds, 0, sizeof( ds ) ); + ds.space = &backEnd.viewDef->worldSpace; + ds.geo = frustumTris; + ds.scissorRect = backEnd.viewDef->scissor; + + // find the current color and density of the fog + lightShader = backEnd.vLight->lightShader; + regs = backEnd.vLight->shaderRegisters; + // assume fog shaders have only a single stage + stage = lightShader->GetStage(0); + + backEnd.lightColor[0] = regs[ stage->color.registers[0] ]; + backEnd.lightColor[1] = regs[ stage->color.registers[1] ]; + backEnd.lightColor[2] = regs[ stage->color.registers[2] ]; + backEnd.lightColor[3] = regs[ stage->color.registers[3] ]; + + qglColor3fv( backEnd.lightColor ); + + // calculate the falloff planes + float a; + + // if they left the default value on, set a fog distance of 500 + if ( backEnd.lightColor[3] <= 1.0 ) { + a = -0.5f / DEFAULT_FOG_DISTANCE; + } else { + // otherwise, distance = alpha color + a = -0.5f / backEnd.lightColor[3]; + } + + GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); + + // texture 0 is the falloff image + GL_SelectTexture( 0 ); + globalImages->fogImage->Bind(); + //GL_Bind( tr.whiteImage ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglTexCoord2f( 0.5f, 0.5f ); // make sure Q is set + + fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[2]; + fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[6]; + fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[10]; + fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[14]; + + fogPlanes[1][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[0]; + fogPlanes[1][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[4]; + fogPlanes[1][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[8]; + fogPlanes[1][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[12]; + + + // texture 1 is the entering plane fade correction + GL_SelectTexture( 1 ); + globalImages->fogEnterImage->Bind(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + + // T will get a texgen for the fade plane, which is always the "top" plane on unrotated lights + fogPlanes[2][0] = 0.001f * backEnd.vLight->fogPlane[0]; + fogPlanes[2][1] = 0.001f * backEnd.vLight->fogPlane[1]; + fogPlanes[2][2] = 0.001f * backEnd.vLight->fogPlane[2]; + fogPlanes[2][3] = 0.001f * backEnd.vLight->fogPlane[3]; + + // S is based on the view origin + float s = backEnd.viewDef->renderView.vieworg * fogPlanes[2].Normal() + fogPlanes[2][3]; + + fogPlanes[3][0] = 0; + fogPlanes[3][1] = 0; + fogPlanes[3][2] = 0; + fogPlanes[3][3] = FOG_ENTER + s; + + qglTexCoord2f( FOG_ENTER + s, FOG_ENTER ); + + + // draw it + RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BasicFog ); + RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BasicFog ); + + // the light frustum bounding planes aren't in the depth buffer, so use depthfunc_less instead + // of depthfunc_equal + GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_LESS ); + GL_Cull( CT_BACK_SIDED ); + RB_RenderDrawSurfChainWithFunction( &ds, RB_T_BasicFog ); + GL_Cull( CT_FRONT_SIDED ); + + GL_SelectTexture( 1 ); + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + globalImages->BindNull(); + + GL_SelectTexture( 0 ); + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); +} + + +/* +================== +RB_STD_FogAllLights +================== +*/ +void RB_STD_FogAllLights( void ) { + viewLight_t *vLight; + + if ( r_skipFogLights.GetBool() || r_showOverDraw.GetInteger() != 0 + || backEnd.viewDef->isXraySubview /* dont fog in xray mode*/ + ) { + return; + } + + RB_LogComment( "---------- RB_STD_FogAllLights ----------\n" ); + + qglDisable( GL_STENCIL_TEST ); + + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + backEnd.vLight = vLight; + + if ( !vLight->lightShader->IsFogLight() && !vLight->lightShader->IsBlendLight() ) { + continue; + } + +#if 0 // _D3XP disabled that + if ( r_ignore.GetInteger() ) { + // we use the stencil buffer to guarantee that no pixels will be + // double fogged, which happens in some areas that are thousands of + // units from the origin + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + + qglEnable( GL_STENCIL_TEST ); + + // only pass on the cleared stencil values + qglStencilFunc( GL_EQUAL, 128, 255 ); + + // when we pass the stencil test and depth test and are going to draw, + // increment the stencil buffer so we don't ever draw on that pixel again + qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR ); + } +#endif + + if ( vLight->lightShader->IsFogLight() ) { + RB_FogPass( vLight->globalInteractions, vLight->localInteractions ); + } else if ( vLight->lightShader->IsBlendLight() ) { + RB_BlendLight( vLight->globalInteractions, vLight->localInteractions ); + } + qglDisable( GL_STENCIL_TEST ); + } + + qglEnable( GL_STENCIL_TEST ); +} + +//========================================================================================= + +/* +================== +RB_STD_LightScale + +Perform extra blending passes to multiply the entire buffer by +a floating point value +================== +*/ +void RB_STD_LightScale( void ) { + float v, f; + + if ( backEnd.overBright == 1.0f ) { + return; + } + + if ( r_skipLightScale.GetBool() ) { + return; + } + + RB_LogComment( "---------- RB_STD_LightScale ----------\n" ); + + // the scissor may be smaller than the viewport for subviews + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, + backEnd.viewDef->scissor.x2 - backEnd.viewDef->scissor.x1 + 1, + backEnd.viewDef->scissor.y2 - backEnd.viewDef->scissor.y1 + 1 ); + backEnd.currentScissor = backEnd.viewDef->scissor; + } + + // full screen blends + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + qglPushMatrix(); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + + GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_SRC_COLOR ); + GL_Cull( CT_TWO_SIDED ); // so mirror views also get it + globalImages->BindNull(); + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_STENCIL_TEST ); + + v = 1; + while ( idMath::Fabs( v - backEnd.overBright ) > 0.01 ) { // a little extra slop + f = backEnd.overBright / v; + f /= 2; + if ( f > 1 ) { + f = 1; + } + qglColor3f( f, f, f ); + v = v * f * 2; + + qglBegin( GL_QUADS ); + qglVertex2f( 0,0 ); + qglVertex2f( 0,1 ); + qglVertex2f( 1,1 ); + qglVertex2f( 1,0 ); + qglEnd(); + } + + + qglPopMatrix(); + qglEnable( GL_DEPTH_TEST ); + qglMatrixMode( GL_MODELVIEW ); + GL_Cull( CT_FRONT_SIDED ); +} + +//========================================================================================= + +/* +============= +RB_STD_DrawView + +============= +*/ +void RB_STD_DrawView( void ) { + drawSurf_t **drawSurfs; + int numDrawSurfs; + + RB_LogComment( "---------- RB_STD_DrawView ----------\n" ); + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + + drawSurfs = (drawSurf_t **)&backEnd.viewDef->drawSurfs[0]; + numDrawSurfs = backEnd.viewDef->numDrawSurfs; + + // clear the z buffer, set the projection matrix, etc + RB_BeginDrawingView(); + + // decide how much overbrighting we are going to do + RB_DetermineLightScale(); + + // fill the depth buffer and clear color buffer to black except on + // subviews + RB_STD_FillDepthBuffer( drawSurfs, numDrawSurfs ); + + // main light renderer + switch( tr.backEndRenderer ) { + case BE_ARB: + RB_ARB_DrawInteractions(); + break; + case BE_ARB2: + RB_ARB2_DrawInteractions(); + break; + case BE_NV20: + RB_NV20_DrawInteractions(); + break; + case BE_NV10: + RB_NV10_DrawInteractions(); + break; + case BE_R200: + RB_R200_DrawInteractions(); + break; + } + + // disable stencil shadow test + qglStencilFunc( GL_ALWAYS, 128, 255 ); + + // uplight the entire screen to crutch up not having better blending range + RB_STD_LightScale(); + + // now draw any non-light dependent shading passes + int processed = RB_STD_DrawShaderPasses( drawSurfs, numDrawSurfs ); + + // fob and blend lights + RB_STD_FogAllLights(); + + // now draw any post-processing effects using _currentRender + if ( processed < numDrawSurfs ) { + RB_STD_DrawShaderPasses( drawSurfs+processed, numDrawSurfs-processed ); + } + + RB_RenderDebugTools( drawSurfs, numDrawSurfs ); + +} diff --git a/renderer/draw_exp.cpp b/renderer/draw_exp.cpp new file mode 100644 index 000000000..7353c8571 --- /dev/null +++ b/renderer/draw_exp.cpp @@ -0,0 +1,2609 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "../sys/win32/win_local.h" + +/* + +strictly experimental / research codepaths + +!!!if we use front facing occluders, we can portal flow from light centers + +try depth_component_16 rendering + +do we care about portals from light perspective? back / front face issues. + +how do we do weapon depth hacks with shadow buffers? + distort their world space vertexes instead of offsetting their depth? + +jittering off the side of a projection will give wrong shadows + +really huge lights, like sunlight, are going to be problematic with fixed projections + we could tile the projections and let the auto-resize cut them down as necessary + +It sucks that depth buffers are non-linear, because the bias and compares change with distance + +polygon offset factor causes occasional texture holes from highly angled textures + +*/ + +static bool initialized; + +static int lightBufferSize = 1024; +static int maxLightBufferSize = 1024; +static float lightBufferSizeFraction = 0.5; + +static int viewBufferSize = 1024; +static int viewBufferHeight = 768; +static int maxViewBufferSize = 1024; +static float viewBufferSizeFraction = 0.5; +static float viewBufferHeightFraction = 0.5; +static bool nativeViewBuffer = false; // true if viewBufferSize is the viewport width + +static HPBUFFERARB floatPbuffer; +static HDC floatPbufferDC; +static idImage *floatPbufferImage; + +static HPBUFFERARB floatPbuffer2; +static HDC floatPbuffer2DC; +static idImage *floatPbuffer2Image; + +static HPBUFFERARB floatPbufferQuarter; +static HDC floatPbufferQuarterDC; +static idImage *floatPbufferQuarterImage; + +static HGLRC floatContext; + +static HPBUFFERARB shadowPbuffer; +static HDC shadowPbufferDC; + +static HPBUFFERARB viewPbuffer; +static HDC viewPbufferDC; + +static idImage *shadowImage[3]; + +static idImage *viewDepthImage; +static idImage *viewAlphaImage; + +static idImage *viewShadowImage; + +static idImage *jitterImage16; +static idImage *jitterImage4; +static idImage *jitterImage1; + +static idImage *random256Image; + +static int shadowVertexProgram; +static int shadowFragmentProgram16; +static int shadowFragmentProgram4; +static int shadowFragmentProgram1; +static int shadowFragmentProgram0; + +static int screenSpaceShadowVertexProgram; +static int screenSpaceShadowFragmentProgram16; +static int screenSpaceShadowFragmentProgram4; +static int screenSpaceShadowFragmentProgram1; +static int screenSpaceShadowFragmentProgram0; + +static int depthMidpointVertexProgram; +static int depthMidpointFragmentProgram; + +static int shadowResampleVertexProgram; +static int shadowResampleFragmentProgram; + +static int gammaDitherVertexProgram; +static int gammaDitherFragmentProgram; + +static int downSampleVertexProgram; +static int downSampleFragmentProgram; + +static int bloomVertexProgram; +static int bloomFragmentProgram; + +static float viewLightAxialSize; + +idCVar r_sb_lightResolution( "r_sb_lightResolution", "1024", CVAR_RENDERER | CVAR_INTEGER, "Pixel dimensions for each shadow buffer, 64 - 2048" ); +idCVar r_sb_viewResolution( "r_sb_viewResolution", "1024", CVAR_RENDERER | CVAR_INTEGER, "Width of screen space shadow sampling" ); +idCVar r_sb_noShadows( "r_sb_noShadows", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw any occluders" ); +idCVar r_sb_usePbuffer( "r_sb_usePbuffer", "1", CVAR_RENDERER | CVAR_BOOL, "draw offscreen" ); +idCVar r_sb_jitterScale( "r_sb_jitterScale", "0.006", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter offset" ); +idCVar r_sb_biasScale( "r_sb_biasScale", "0.0001", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter bias" ); +idCVar r_sb_samples( "r_sb_samples", "4", CVAR_RENDERER | CVAR_INTEGER, "0, 1, 4, or 16" ); +idCVar r_sb_randomize( "r_sb_randomize", "1", CVAR_RENDERER | CVAR_BOOL, "randomly offset jitter texture each draw" ); +// polyOfsFactor causes holes in low res images +idCVar r_sb_polyOfsFactor( "r_sb_polyOfsFactor", "2", CVAR_RENDERER | CVAR_FLOAT, "polygonOffset factor for drawing shadow buffer" ); +idCVar r_sb_polyOfsUnits( "r_sb_polyOfsUnits", "3000", CVAR_RENDERER | CVAR_FLOAT, "polygonOffset units for drawing shadow buffer" ); +idCVar r_sb_occluderFacing( "r_sb_occluderFacing", "0", CVAR_RENDERER | CVAR_INTEGER, "0 = front faces, 1 = back faces, 2 = midway between" ); +// r_sb_randomizeBufferOrientation? + +idCVar r_sb_frustomFOV( "r_sb_frustomFOV", "92", CVAR_RENDERER | CVAR_FLOAT, "oversize FOV for point light side matching" ); +idCVar r_sb_showFrustumPixels( "r_sb_showFrustumPixels", "0", CVAR_RENDERER | CVAR_BOOL, "color the pixels contained in the frustum" ); +idCVar r_sb_singleSide( "r_sb_singleSide", "-1", CVAR_RENDERER | CVAR_INTEGER, "only draw a single side (0-5) of point lights" ); +idCVar r_sb_useCulling( "r_sb_useCulling", "1", CVAR_RENDERER | CVAR_BOOL, "cull geometry to individual side frustums" ); +idCVar r_sb_linearFilter( "r_sb_linearFilter", "1", CVAR_RENDERER | CVAR_BOOL, "use GL_LINEAR instead of GL_NEAREST on shadow maps" ); + +idCVar r_sb_screenSpaceShadow( "r_sb_screenSpaceShadow", "1", CVAR_RENDERER | CVAR_BOOL, "build shadows in screen space instead of on surfaces" ); + +idCVar r_hdr_useFloats( "r_hdr_useFloats", "0", CVAR_RENDERER | CVAR_BOOL, "use a floating point rendering buffer" ); +idCVar r_hdr_exposure( "r_hdr_exposure", "1.0", CVAR_RENDERER | CVAR_FLOAT, "maximum light scale" ); +idCVar r_hdr_bloomFraction( "r_hdr_bloomFraction", "0.1", CVAR_RENDERER | CVAR_FLOAT, "fraction to smear across neighbors" ); +idCVar r_hdr_gamma( "r_hdr_gamma", "1", CVAR_RENDERER | CVAR_FLOAT, "monitor gamma power" ); +idCVar r_hdr_monitorDither( "r_hdr_monitorDither", "0.01", CVAR_RENDERER | CVAR_FLOAT, "random dither in monitor space" ); + +// from world space to light origin, looking down the X axis +static float unflippedLightMatrix[16]; + +// from world space to OpenGL view space, looking down the negative Z axis +static float lightMatrix[16]; + +// from OpenGL view space to OpenGL NDC ( -1 : 1 in XYZ ) +static float lightProjectionMatrix[16]; + + +void RB_ARB2_DrawInteraction( const drawInteraction_t *din ); + +typedef struct { + const char *name; + int num; +} wglString_t; + +wglString_t wglString[] = { +{ "WGL_NUMBER_PIXEL_FORMATS_ARB", 0x2000 }, +{ "WGL_DRAW_TO_WINDOW_ARB", 0x2001 }, +{ "WGL_DRAW_TO_BITMAP_ARB", 0x2002 }, +{ "WGL_ACCELERATION_ARB", 0x2003 }, +{ "WGL_NEED_PALETTE_ARB", 0x2004 }, +{ "WGL_NEED_SYSTEM_PALETTE_ARB", 0x2005 }, +{ "WGL_SWAP_LAYER_BUFFERS_ARB", 0x2006 }, +{ "WGL_SWAP_METHOD_ARB", 0x2007 }, +{ "WGL_NUMBER_OVERLAYS_ARB", 0x2008 }, +{ "WGL_NUMBER_UNDERLAYS_ARB", 0x2009 }, +{ "WGL_TRANSPARENT_ARB", 0x200A }, +{ "WGL_TRANSPARENT_RED_VALUE_ARB", 0x2037 }, +{ "WGL_TRANSPARENT_GREEN_VALUE_ARB", 0x2038 }, +{ "WGL_TRANSPARENT_BLUE_VALUE_ARB", 0x2039 }, +{ "WGL_TRANSPARENT_ALPHA_VALUE_ARB", 0x203A }, +{ "WGL_TRANSPARENT_INDEX_VALUE_ARB", 0x203B }, +{ "WGL_SHARE_DEPTH_ARB", 0x200C }, +{ "WGL_SHARE_STENCIL_ARB", 0x200D }, +{ "WGL_SHARE_ACCUM_ARB", 0x200E }, +{ "WGL_SUPPORT_GDI_ARB", 0x200F }, +{ "WGL_SUPPORT_OPENGL_ARB", 0x2010 }, +{ "WGL_DOUBLE_BUFFER_ARB", 0x2011 }, +{ "WGL_STEREO_ARB", 0x2012 }, +{ "WGL_PIXEL_TYPE_ARB", 0x2013 }, +{ "WGL_COLOR_BITS_ARB", 0x2014 }, +{ "WGL_RED_BITS_ARB", 0x2015 }, +{ "WGL_RED_SHIFT_ARB", 0x2016 }, +{ "WGL_GREEN_BITS_ARB", 0x2017 }, +{ "WGL_GREEN_SHIFT_ARB", 0x2018 }, +{ "WGL_BLUE_BITS_ARB", 0x2019 }, +{ "WGL_BLUE_SHIFT_ARB", 0x201A }, +{ "WGL_ALPHA_BITS_ARB", 0x201B }, +{ "WGL_ALPHA_SHIFT_ARB", 0x201C }, +{ "WGL_ACCUM_BITS_ARB", 0x201D }, +{ "WGL_ACCUM_RED_BITS_ARB", 0x201E }, +{ "WGL_ACCUM_GREEN_BITS_ARB", 0x201F }, +{ "WGL_ACCUM_BLUE_BITS_ARB", 0x2020 }, +{ "WGL_ACCUM_ALPHA_BITS_ARB", 0x2021 }, +{ "WGL_DEPTH_BITS_ARB", 0x2022 }, +{ "WGL_STENCIL_BITS_ARB", 0x2023 }, +{ "WGL_AUX_BUFFERS_ARB", 0x2024 }, + +{ "WGL_NO_ACCELERATION_ARB", 0x2025 }, +{ "WGL_GENERIC_ACCELERATION_ARB", 0x2026 }, +{ "WGL_FULL_ACCELERATION_ARB", 0x2027 }, + +{ "WGL_SWAP_EXCHANGE_ARB", 0x2028 }, +{ "WGL_SWAP_COPY_ARB", 0x2029 }, +{ "WGL_SWAP_UNDEFINED_ARB", 0x202A }, + +{ "WGL_TYPE_RGBA_ARB", 0x202B }, +{ "WGL_TYPE_COLORINDEX_ARB", 0x202C }, +}; + +static const int NUM_WGL_STRINGS = sizeof( wglString ) / sizeof( wglString[0] ); + +static void R_CheckWglErrors( void ) { + int err = GetLastError(); + char *name; + +#if 0 + LPVOID lpMsgBuf; + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); +#endif + err &= 0xffff; + switch ( err ) { + case 13: name = "ERROR_INVALID_DATA"; break; + case 6: name = "ERROR_INVALID_HANDLE"; break; + case 4317: name = "ERROR_INVALID_OPERATION"; break; + default: name = va( "code %i", err ); break; + } + + common->Printf( "GetLastError: %s\n", name ); +} + +static void R_MakeCurrent( HDC dc, HGLRC context, HPBUFFERARB pbuffer ) { + if ( pbuffer ) { + if ( !wglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) { + R_CheckWglErrors(); + common->Error( "wglReleaseTexImageARB failed" ); + } + } + if ( !qwglMakeCurrent( dc, context ) ) { + R_CheckWglErrors(); + common->FatalError( "qwglMakeCurrent failed" ); + } +} + +static void R_BindTexImage( HPBUFFERARB pbuffer ) { + if ( !wglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) { + R_CheckWglErrors(); + common->Error( "wglReleaseTexImageARB failed" ); + } + if ( !wglBindTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) { + R_CheckWglErrors(); + common->Error( "failed wglBindTexImageARB" ); + } +} + +static void R_ReportTextureParms( void ) { + int parms[8]; + +// q glGetTexParameteriv( GL_TEXTURE_RECTANGLE_NV, + qglGetIntegerv( GL_TEXTURE_BINDING_RECTANGLE_NV, parms ); + +} + +/* +==================== +RB_CreateBloomTable +==================== +*/ +static const int BLOOM_RADIUS = 8; +static void RB_CreateBloomTable( void ) { + float bloom[BLOOM_RADIUS]; + float total = 0; + + // gaussian + float stdDev = 2.0; + for ( int i = 0 ; i < BLOOM_RADIUS ; i++ ) { + float f = (float)i / stdDev; + bloom[i] = exp( -0.5 * f * f ); + total += bloom[i]; + } + + total = ( total - bloom[0] ) * 2 + bloom[0]; + + // normalize to 1.0 contribution, so a full row or column will equal 1.0 + for ( int i = 0 ; i < BLOOM_RADIUS ; i++ ) { + bloom[i] *= 1.0 / total; + common->Printf( "PARAM bloom%i = { %f };\n", i, bloom[i] ); + } + +} + +/* +==================== +GL_SelectTextureNoClient +==================== +*/ +static void GL_SelectTextureNoClient( int unit ) { + backEnd.glState.currenttmu = unit; + qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); + RB_LogComment( "glActiveTextureARB( %i )\n", unit ); +} + + +/* +================ +R_CreateShadowBufferImage + +================ +*/ +static void R_CreateShadowBufferImage( idImage *image ) { + byte *data = (byte *)Mem_Alloc( lightBufferSize*lightBufferSize ); + + memset( data, 0, lightBufferSize*lightBufferSize ); + + image->GenerateImage( (byte *)data, 4, 4, + TF_LINEAR, false, TR_CLAMP_TO_BORDER, TD_HIGH_QUALITY ); + + // now reset it to a shadow depth image + GL_CheckErrors(); + image->uploadWidth = image->uploadHeight = lightBufferSize; + qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, lightBufferSize, lightBufferSize, + 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, data ); + + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE ); +// qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); + + // explicit zero depth border + float color[4]; + color[0] = color[1] = color[2] = color[3] = 0; + qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color ); + + GL_CheckErrors(); + + Mem_Free( data ); +} + +static void R_CreateViewAlphaImage( idImage *image ) { + int c = viewBufferSize*viewBufferSize*4; + byte *data = (byte *)Mem_Alloc( c ); + + // don't let it pick an intensity format + for ( int i = 0 ; i < c ; i++ ) { + data[i] = i; + } + memset( data, 0, viewBufferSize*viewBufferSize ); + + image->GenerateImage( (byte *)data, viewBufferSize, viewBufferSize, + TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY ); +} + +static void R_CreateStubImage( idImage *image ) { + float data[3][4][4]; + + // generate the texture number + qglGenTextures( 1, &image->texnum ); + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, image->texnum ); + memset( data, 0, sizeof( data ) ); + glTexImage2D( GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA16_NV, 4, 3, 0, GL_RGBA, GL_FLOAT, &data ); +} + +/* +================ +R_CreateJitterImage + +================ +*/ +const static int JITTER_SIZE = 128; +static void R_CreateJitterImage16( idImage *image ) { + byte data[JITTER_SIZE][JITTER_SIZE*16][4]; + + for ( int i = 0 ; i < JITTER_SIZE ; i++ ) { + for ( int s = 0 ; s < 16 ; s++ ) { + int sOfs = 64 * ( s & 3 ); + int tOfs = 64 * ( ( s >> 2 ) & 3 ); + + for ( int j = 0 ; j < JITTER_SIZE ; j++ ) { + data[i][s*JITTER_SIZE+j][0] = (rand() & 63 ) | sOfs; + data[i][s*JITTER_SIZE+j][1] = (rand() & 63 ) | tOfs; + data[i][s*JITTER_SIZE+j][2] = rand(); + data[i][s*JITTER_SIZE+j][3] = 0; + } + } + } + + image->GenerateImage( (byte *)data, JITTER_SIZE*16, JITTER_SIZE, + TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_CreateJitterImage4( idImage *image ) { + byte data[JITTER_SIZE][JITTER_SIZE*4][4]; + + for ( int i = 0 ; i < JITTER_SIZE ; i++ ) { + for ( int s = 0 ; s < 4 ; s++ ) { + int sOfs = 128 * ( s & 1 ); + int tOfs = 128 * ( ( s >> 1 ) & 1 ); + + for ( int j = 0 ; j < JITTER_SIZE ; j++ ) { + data[i][s*JITTER_SIZE+j][0] = (rand() & 127 ) | sOfs; + data[i][s*JITTER_SIZE+j][1] = (rand() & 127 ) | tOfs; + data[i][s*JITTER_SIZE+j][2] = rand(); + data[i][s*JITTER_SIZE+j][3] = 0; + } + } + } + + image->GenerateImage( (byte *)data, JITTER_SIZE*4, JITTER_SIZE, + TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_CreateJitterImage1( idImage *image ) { + byte data[JITTER_SIZE][JITTER_SIZE][4]; + + for ( int i = 0 ; i < JITTER_SIZE ; i++ ) { + for ( int j = 0 ; j < JITTER_SIZE ; j++ ) { + data[i][j][0] = rand(); + data[i][j][1] = rand(); + data[i][j][2] = rand(); + data[i][j][3] = 0; + } + } + + image->GenerateImage( (byte *)data, JITTER_SIZE, JITTER_SIZE, + TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + +static void R_CreateRandom256Image( idImage *image ) { + byte data[256][256][4]; + + for ( int i = 0 ; i < 256 ; i++ ) { + for ( int j = 0 ; j < 256 ; j++ ) { + data[i][j][0] = rand(); + data[i][j][1] = rand(); + data[i][j][2] = rand(); + data[i][j][3] = rand(); + } + } + + image->GenerateImage( (byte *)data, 256, 256, + TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY ); +} + + +/* +================== +R_PrintPixelFormat +================== +*/ +void R_PrintPixelFormat( int pixelFormat ) { + int res; + int iAttribute; + int iValue; + + common->Printf( "----- pixelFormat %i -----\n", pixelFormat ); + + for ( int i = 1 ; i < NUM_WGL_STRINGS ; i++ ) { + iAttribute = wglString[i].num; + res = wglGetPixelFormatAttribivARB( win32.hDC, pixelFormat, 0, 1, &iAttribute, &iValue ); + if ( res && iValue ) { + common->Printf( "%s : %i\n", wglString[i].name, iValue ); + } + } +} + + +/* +================== +R_Exp_Allocate +================== +*/ +void R_Exp_Allocate( void ) { + // find a pixel format for our floating point pbuffer + int iAttributes[NUM_WGL_STRINGS*2], *atr_p; + FLOAT fAttributes[] = {0, 0}; + UINT numFormats; + int pixelformats[1024]; + int ret; + int pbiAttributes[] = {0, 0}; + + initialized = true; + +#if 1 + // + // allocate the floating point rendering buffer + // + atr_p = iAttributes; + + *atr_p++ = WGL_DRAW_TO_PBUFFER_ARB; + *atr_p++ = TRUE; + *atr_p++ = WGL_FLOAT_COMPONENTS_NV; + *atr_p++ = TRUE; + *atr_p++ = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV; + *atr_p++ = TRUE; +// *atr_p++ = WGL_BIND_TO_TEXTURE_RGBA_ARB; +// *atr_p++ = TRUE; + *atr_p++ = WGL_DEPTH_BITS_ARB; + *atr_p++ = 24; + *atr_p++ = WGL_STENCIL_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = 0; + *atr_p++ = 0; + + ret = wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes, + sizeof( pixelformats ) / sizeof( pixelformats[0] ), pixelformats, &numFormats ); + +#if 0 + for ( int i = 0 ; i < (int)numFormats ; i++ ) { + R_PrintPixelFormat( pixelformats[i] ); + } +#endif + common->Printf( "\nfloatPbuffer:\n" ); + R_PrintPixelFormat( pixelformats[0] ); + + // allocate a pbuffer with this pixel format + int pbiAttributesTexture[] = { + WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_FLOAT_RGBA_NV, + WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_RECTANGLE_NV, // WGL_TEXTURE_2D_ARB, + 0, 0}; + + floatPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth, + glConfig.vidHeight, pbiAttributesTexture ); + if ( !floatPbuffer ) { + common->Printf( "failed to create floatPbuffer.\n" ); + GL_CheckErrors(); + } + floatPbufferDC = wglGetPbufferDCARB( floatPbuffer ); + floatPbufferImage = globalImages->ImageFromFunction( "_floatPbuffer", R_CreateStubImage ); + + // create a second buffer for ping-pong operations + floatPbuffer2 = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth, + glConfig.vidHeight, pbiAttributesTexture ); + if ( !floatPbuffer2 ) { + common->Printf( "failed to create floatPbuffer.\n" ); + GL_CheckErrors(); + } + floatPbuffer2DC = wglGetPbufferDCARB( floatPbuffer2 ); + floatPbuffer2Image = globalImages->ImageFromFunction( "_floatPbuffer2", R_CreateStubImage ); + + // create a third buffer for down sampling operations + floatPbufferQuarter = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth / 4, + glConfig.vidHeight / 4, pbiAttributesTexture ); + if ( !floatPbufferQuarter ) { + common->Printf( "failed to create floatPbuffer.\n" ); + GL_CheckErrors(); + } + floatPbufferQuarterDC = wglGetPbufferDCARB( floatPbufferQuarter ); + floatPbufferQuarterImage = globalImages->ImageFromFunction( "floatPbufferQuarter", R_CreateStubImage ); + + // create a new GL context for this pixel format and share textures + floatContext = wglCreateContext( floatPbufferDC ); + if ( !floatContext ) { + common->Printf( "failed to create context for floatPbufferDC.\n" ); + GL_CheckErrors(); + } + + if ( !wglShareLists( floatContext, win32.hGLRC ) ) { + common->Printf( "failed to share lists.\n" ); + } + + // create a rendering context for this pixel format and share textures + + // allocate a texture for the rendering + +#endif + + //================================================================================= + + // + // allocate the shadow pbuffer + // + atr_p = iAttributes; + + *atr_p++ = WGL_DRAW_TO_PBUFFER_ARB; + *atr_p++ = TRUE; + *atr_p++ = WGL_RED_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = WGL_GREEN_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = WGL_BLUE_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = WGL_ALPHA_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = WGL_DEPTH_BITS_ARB; + *atr_p++ = 24; + *atr_p++ = WGL_STENCIL_BITS_ARB; + *atr_p++ = 8; + *atr_p++ = 0; + *atr_p++ = 0; + + ret = wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes, + sizeof( pixelformats ) / sizeof( pixelformats[0] ), pixelformats, &numFormats ); +#if 0 + for ( int i = 0 ; i < (int)numFormats ; i++ ) { + R_PrintPixelFormat( pixelformats[i] ); + } +#endif + common->Printf( "\nshadowPbuffer:\n" ); + R_PrintPixelFormat( pixelformats[0] ); + +pixelformats[0] = win32.pixelformat; // forced to do this by wgl... + + //----------------------------------- + + lightBufferSize = maxLightBufferSize; + + // allocate a pbuffer with this pixel format + shadowPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], lightBufferSize, + lightBufferSize, pbiAttributes ); + + // allocate a rendering context for the pbuffer + shadowPbufferDC = wglGetPbufferDCARB( shadowPbuffer ); + + // generate the texture number + shadowImage[0] = globalImages->ImageFromFunction( va("_shadowBuffer%i_0",lightBufferSize), R_CreateShadowBufferImage ); + shadowImage[1] = globalImages->ImageFromFunction( va("_shadowBuffer%i_1",lightBufferSize), R_CreateShadowBufferImage ); + shadowImage[2] = globalImages->ImageFromFunction( va("_shadowBuffer%i_2",lightBufferSize), R_CreateShadowBufferImage ); + + //----------------------------------- + + lightBufferSize = maxViewBufferSize; + + // allocate a pbuffer with this pixel format + viewPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], maxViewBufferSize, + maxViewBufferSize, pbiAttributes ); + + // allocate a rendering context for the pbuffer + viewPbufferDC = wglGetPbufferDCARB( viewPbuffer ); + + // create the image space depth buffer for image-space shadow trnasforms + viewDepthImage = globalImages->ImageFromFunction("_viewDepth", R_CreateShadowBufferImage ); + + // create the image space shadow alpha buffer for subsampling the shadow calculation + viewAlphaImage = globalImages->ImageFromFunction("_viewAlpha", R_CreateViewAlphaImage ); + + //----------------------------------- + + // generate the jitter image + jitterImage16 = globalImages->ImageFromFunction( "_jitter16", R_CreateJitterImage16 ); + jitterImage4 = globalImages->ImageFromFunction( "_jitter4", R_CreateJitterImage4 ); + jitterImage1 = globalImages->ImageFromFunction( "_jitter1", R_CreateJitterImage1 ); + + depthMidpointVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "depthMidpoint.vfp" ); + depthMidpointFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "depthMidpoint.vfp" ); + + shadowResampleVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "shadowResample.vfp" ); + shadowResampleFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowResample.vfp" ); + + screenSpaceShadowVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "screenSpaceShadow1.vfp" ); + + screenSpaceShadowFragmentProgram0 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow0.vfp" ); + screenSpaceShadowFragmentProgram1 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow1.vfp" ); + screenSpaceShadowFragmentProgram4 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow4.vfp" ); + screenSpaceShadowFragmentProgram16 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow16.vfp" ); + + shadowVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "shadowBufferInteraction1.vfp" ); + + shadowFragmentProgram0 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction0.vfp" ); + shadowFragmentProgram1 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction1.vfp" ); + shadowFragmentProgram4 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction4.vfp" ); + shadowFragmentProgram16 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction16.vfp" ); + + gammaDitherVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "gammaDither.vfp" ); + gammaDitherFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "gammaDither.vfp" ); + + downSampleVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "downSample.vfp" ); + downSampleFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "downSample.vfp" ); + + bloomVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "bloom.vfp" ); + bloomFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "bloom.vfp" ); + + random256Image = globalImages->ImageFromFunction( "_random256", R_CreateRandom256Image ); +} + +//=========================================================================================== + +static const int CULL_RECEIVER = 1; // still draw occluder, but it is out of the view +static const int CULL_OCCLUDER_AND_RECEIVER = 2; // the surface doesn't effect the view at all + +/* +================== +RB_EXP_CullInteractions + +Sets surfaceInteraction_t->cullBits +================== +*/ +void RB_EXP_CullInteractions( viewLight_t *vLight, idPlane frustumPlanes[6] ) { + for ( idInteraction *inter = vLight->lightDef->firstInteraction ; inter ; inter = inter->lightNext ) { + const idRenderEntityLocal *entityDef = inter->entityDef; + if ( !entityDef ) { + continue; + } + if ( inter->numSurfaces < 1 ) { + continue; + } + + int culled = 0; + + if ( r_sb_useCulling.GetBool() ) { + // transform light frustum into object space, positive side points outside the light + idPlane localPlanes[6]; + int plane; + for ( plane = 0 ; plane < 6 ; plane++ ) { + R_GlobalPlaneToLocal( entityDef->modelMatrix, frustumPlanes[plane], localPlanes[plane] ); + } + + // cull the entire entity bounding box + // has referenceBounds been tightened to the actual model bounds? + idVec3 corners[8]; + for ( int i = 0 ; i < 8 ; i++ ) { + corners[i][0] = entityDef->referenceBounds[i&1][0]; + corners[i][1] = entityDef->referenceBounds[(i>>1)&1][1]; + corners[i][2] = entityDef->referenceBounds[(i>>2)&1][2]; + } + + for ( plane = 0 ; plane < 6 ; plane++ ) { + int j; + for ( j = 0 ; j < 8 ; j++ ) { + // if a corner is on the negative side (inside) of the frustum, the surface is not culled + // by this plane + if ( corners[j] * localPlanes[plane].ToVec4().ToVec3() + localPlanes[plane][3] < 0 ) { + break; + } + } + if ( j == 8 ) { + break; // all points outside the light + } + } + if ( plane < 6 ) { + culled = CULL_OCCLUDER_AND_RECEIVER; + } + } + + for ( int i = 0 ; i < inter->numSurfaces ; i++ ) { + surfaceInteraction_t *surfInt = &inter->surfaces[i]; + + if ( !surfInt->ambientTris ) { + continue; + } + surfInt->expCulled = culled; + } + + } +} + +/* +================== +RB_EXP_RenderOccluders +================== +*/ +void RB_EXP_RenderOccluders( viewLight_t *vLight ) { + for ( idInteraction *inter = vLight->lightDef->firstInteraction ; inter ; inter = inter->lightNext ) { + const idRenderEntityLocal *entityDef = inter->entityDef; + if ( !entityDef ) { + continue; + } + if ( inter->numSurfaces < 1 ) { + continue; + } + + // no need to check for current on this, because each interaction is always + // a different space + float matrix[16]; + myGlMultMatrix( inter->entityDef->modelMatrix, lightMatrix, matrix ); + qglLoadMatrixf( matrix ); + + // draw each surface + for ( int i = 0 ; i < inter->numSurfaces ; i++ ) { + surfaceInteraction_t *surfInt = &inter->surfaces[i]; + + if ( !surfInt->ambientTris ) { + continue; + } + if ( surfInt->shader && !surfInt->shader->SurfaceCastsShadow() ) { + continue; + } + + // cull it + if ( surfInt->expCulled == CULL_OCCLUDER_AND_RECEIVER ) { + continue; + } + + // render it + const srfTriangles_t *tri = surfInt->ambientTris; + if ( !tri->ambientCache ) { + R_CreateAmbientCache( const_cast(tri), false ); + } + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + if ( surfInt->shader ) { + surfInt->shader->GetEditorImage()->Bind(); + } + RB_DrawElementsWithCounters( tri ); + } + } +} + +/* +================== +RB_RenderShadowBuffer +================== +*/ +void RB_RenderShadowBuffer( viewLight_t *vLight, int side ) { + float xmin, xmax, ymin, ymax; + float width, height; + float zNear; + + float fov = r_sb_frustomFOV.GetFloat(); + + // + // set up 90 degree projection matrix + // + zNear = 4; + + ymax = zNear * tan( fov * idMath::PI / 360.0f ); + ymin = -ymax; + + xmax = zNear * tan( fov * idMath::PI / 360.0f ); + xmin = -xmax; + + width = xmax - xmin; + height = ymax - ymin; + + lightProjectionMatrix[0] = 2 * zNear / width; + lightProjectionMatrix[4] = 0; + lightProjectionMatrix[8] = 0; + lightProjectionMatrix[12] = 0; + + lightProjectionMatrix[1] = 0; + lightProjectionMatrix[5] = 2 * zNear / height; + lightProjectionMatrix[9] = 0; + lightProjectionMatrix[13] = 0; + + // this is the far-plane-at-infinity formulation, and + // crunches the Z range slightly so w=0 vertexes do not + // rasterize right at the wraparound point + lightProjectionMatrix[2] = 0; + lightProjectionMatrix[6] = 0; + lightProjectionMatrix[10] = -0.999f; + lightProjectionMatrix[14] = -2.0f * zNear; + + lightProjectionMatrix[3] = 0; + lightProjectionMatrix[7] = 0; + lightProjectionMatrix[11] = -1; + lightProjectionMatrix[15] = 0; + + + if ( r_sb_usePbuffer.GetBool() ) { + // set the current openGL drawable to the shadow buffer + R_MakeCurrent( shadowPbufferDC, win32.hGLRC, NULL /* !@# shadowPbuffer */ ); + } + + qglMatrixMode( GL_PROJECTION ); + qglLoadMatrixf( lightProjectionMatrix ); + qglMatrixMode( GL_MODELVIEW ); + + qglViewport( 0, 0, lightBufferSize, lightBufferSize ); + qglScissor( 0, 0, lightBufferSize, lightBufferSize ); + qglStencilFunc( GL_ALWAYS, 0, 255 ); + +qglClearColor( 0, 1, 0, 0 ); +GL_State( GLS_DEPTHFUNC_LESS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); // make sure depth mask is off before clear +qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + +// draw all the occluders +qglColor3f( 1, 1, 1 ); +GL_SelectTexture( 0 ); +qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + backEnd.currentSpace = NULL; + + static float s_flipMatrix[16] = { + // convert from our coordinate system (looking down X) + // to OpenGL's coordinate system (looking down -Z) + 0, 0, -1, 0, + -1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 + }; + + float viewMatrix[16]; + + idVec3 vec; + idVec3 origin = vLight->lightDef->globalLightOrigin; + + if ( side == -1 ) { + // projected light + vec = vLight->lightDef->parms.target; + vec.Normalize(); + viewMatrix[0] = vec[0]; + viewMatrix[4] = vec[1]; + viewMatrix[8] = vec[2]; + + vec = vLight->lightDef->parms.right; + vec.Normalize(); + viewMatrix[1] = -vec[0]; + viewMatrix[5] = -vec[1]; + viewMatrix[9] = -vec[2]; + + vec = vLight->lightDef->parms.up; + vec.Normalize(); + viewMatrix[2] = vec[0]; + viewMatrix[6] = vec[1]; + viewMatrix[10] = vec[2]; + } else { + // side of a point light + memset( viewMatrix, 0, sizeof( viewMatrix ) ); + switch ( side ) { + case 0: + viewMatrix[0] = 1; + viewMatrix[9] = 1; + viewMatrix[6] = -1; + break; + case 1: + viewMatrix[0] = -1; + viewMatrix[9] = -1; + viewMatrix[6] = -1; + break; + case 2: + viewMatrix[4] = 1; + viewMatrix[1] = -1; + viewMatrix[10] = 1; + break; + case 3: + viewMatrix[4] = -1; + viewMatrix[1] = -1; + viewMatrix[10] = -1; + break; + case 4: + viewMatrix[8] = 1; + viewMatrix[1] = -1; + viewMatrix[6] = -1; + break; + case 5: + viewMatrix[8] = -1; + viewMatrix[1] = 1; + viewMatrix[6] = -1; + break; + } + } + + viewMatrix[12] = -origin[0] * viewMatrix[0] + -origin[1] * viewMatrix[4] + -origin[2] * viewMatrix[8]; + viewMatrix[13] = -origin[0] * viewMatrix[1] + -origin[1] * viewMatrix[5] + -origin[2] * viewMatrix[9]; + viewMatrix[14] = -origin[0] * viewMatrix[2] + -origin[1] * viewMatrix[6] + -origin[2] * viewMatrix[10]; + + viewMatrix[3] = 0; + viewMatrix[7] = 0; + viewMatrix[11] = 0; + viewMatrix[15] = 1; + + memcpy( unflippedLightMatrix, viewMatrix, sizeof( unflippedLightMatrix ) ); + myGlMultMatrix( viewMatrix, s_flipMatrix,lightMatrix); + + // create frustum planes + idPlane globalFrustum[6]; + + // near clip + globalFrustum[0][0] = -viewMatrix[0]; + globalFrustum[0][1] = -viewMatrix[4]; + globalFrustum[0][2] = -viewMatrix[8]; + globalFrustum[0][3] = -(origin[0] * globalFrustum[0][0] + origin[1] * globalFrustum[0][1] + origin[2] * globalFrustum[0][2]); + + // far clip + globalFrustum[1][0] = viewMatrix[0]; + globalFrustum[1][1] = viewMatrix[4]; + globalFrustum[1][2] = viewMatrix[8]; + globalFrustum[1][3] = -globalFrustum[0][3] - viewLightAxialSize; + + // side clips + globalFrustum[2][0] = -viewMatrix[0] + viewMatrix[1]; + globalFrustum[2][1] = -viewMatrix[4] + viewMatrix[5]; + globalFrustum[2][2] = -viewMatrix[8] + viewMatrix[9]; + + globalFrustum[3][0] = -viewMatrix[0] - viewMatrix[1]; + globalFrustum[3][1] = -viewMatrix[4] - viewMatrix[5]; + globalFrustum[3][2] = -viewMatrix[8] - viewMatrix[9]; + + globalFrustum[4][0] = -viewMatrix[0] + viewMatrix[2]; + globalFrustum[4][1] = -viewMatrix[4] + viewMatrix[6]; + globalFrustum[4][2] = -viewMatrix[8] + viewMatrix[10]; + + globalFrustum[5][0] = -viewMatrix[0] - viewMatrix[2]; + globalFrustum[5][1] = -viewMatrix[4] - viewMatrix[6]; + globalFrustum[5][2] = -viewMatrix[8] - viewMatrix[10]; + + // is this nromalization necessary? + for ( int i = 0 ; i < 6 ; i++ ) { + globalFrustum[i].ToVec4().ToVec3().Normalize(); + } + + for ( int i = 2 ; i < 6 ; i++ ) { + globalFrustum[i][3] = - (origin * globalFrustum[i].ToVec4().ToVec3() ); + } + + RB_EXP_CullInteractions( vLight, globalFrustum ); + + + // FIXME: we want to skip the sampling as well as the generation when not casting shadows + if ( !r_sb_noShadows.GetBool() && vLight->lightShader->LightCastsShadows() ) { + // + // set polygon offset for the rendering + // + switch ( r_sb_occluderFacing.GetInteger() ) { + case 0: // front sides + qglPolygonOffset( r_sb_polyOfsFactor.GetFloat(), r_sb_polyOfsUnits.GetFloat() ); + qglEnable( GL_POLYGON_OFFSET_FILL ); + RB_EXP_RenderOccluders( vLight ); + qglDisable( GL_POLYGON_OFFSET_FILL ); + break; + case 1: // back sides + qglPolygonOffset( -r_sb_polyOfsFactor.GetFloat(), -r_sb_polyOfsUnits.GetFloat() ); + qglEnable( GL_POLYGON_OFFSET_FILL ); + GL_Cull( CT_BACK_SIDED ); + RB_EXP_RenderOccluders( vLight ); + GL_Cull( CT_FRONT_SIDED ); + qglDisable( GL_POLYGON_OFFSET_FILL ); + break; + case 2: // both sides + GL_Cull( CT_BACK_SIDED ); + RB_EXP_RenderOccluders( vLight ); + GL_Cull( CT_FRONT_SIDED ); + shadowImage[2]->Bind(); + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize ); + + RB_EXP_RenderOccluders( vLight ); + shadowImage[1]->Bind(); + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize ); + + // fragment program to combine the two depth images + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, depthMidpointVertexProgram ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, depthMidpointFragmentProgram ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + GL_SelectTextureNoClient( 1 ); + shadowImage[1]->Bind(); + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + + GL_SelectTextureNoClient( 0 ); + shadowImage[2]->Bind(); + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + + // draw a full screen quad + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + GL_State( GLS_DEPTHFUNC_ALWAYS ); + + qglBegin( GL_TRIANGLE_FAN ); + qglTexCoord2f( 0, 0 ); + qglVertex2f( 0, 0 ); + qglTexCoord2f( 0, lightBufferSizeFraction ); + qglVertex2f( 0, 1 ); + qglTexCoord2f( lightBufferSizeFraction, lightBufferSizeFraction ); + qglVertex2f( 1, 1 ); + qglTexCoord2f( lightBufferSizeFraction, 0 ); + qglVertex2f( 1, 0 ); + qglEnd(); + + qglDisable( GL_VERTEX_PROGRAM_ARB ); + qglDisable( GL_FRAGMENT_PROGRAM_ARB ); + + break; + } + } + + // copy to the texture + shadowImage[0]->Bind(); + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize ); + +qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + + // reset the normal view matrix + + qglMatrixMode( GL_PROJECTION ); + qglLoadMatrixf( backEnd.viewDef->projectionMatrix ); + qglMatrixMode( GL_MODELVIEW ); + + // the current modelView matrix is not valid + backEnd.currentSpace = NULL; +} + +/* +================== +RB_EXP_DrawInteraction +================== +*/ +void RB_EXP_DrawInteraction( const drawInteraction_t *din ) { + // load all the vertex program parameters + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() ); + + +// calculate depth projection for shadow buffer +float sRow[4]; +float tRow[4]; +float rRow[4]; +float qRow[4]; +float matrix[16]; +float matrix2[16]; +myGlMultMatrix( din->surf->space->modelMatrix, lightMatrix, matrix ); +myGlMultMatrix( matrix, lightProjectionMatrix, matrix2 ); + +// the final values need to be in 0.0 : 1.0 range instead of -1 : 1 +sRow[0] = 0.5 * lightBufferSizeFraction * ( matrix2[0] + matrix2[3] ); +sRow[1] = 0.5 * lightBufferSizeFraction * ( matrix2[4] + matrix2[7] ); +sRow[2] = 0.5 * lightBufferSizeFraction * ( matrix2[8] + matrix2[11] ); +sRow[3] = 0.5 * lightBufferSizeFraction * ( matrix2[12] + matrix2[15] ); +qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 18, sRow ); +tRow[0] = 0.5 * lightBufferSizeFraction * ( matrix2[1] + matrix2[3] ); +tRow[1] = 0.5 * lightBufferSizeFraction * ( matrix2[5] + matrix2[7] ); +tRow[2] = 0.5 * lightBufferSizeFraction * ( matrix2[9] + matrix2[11] ); +tRow[3] = 0.5 * lightBufferSizeFraction * ( matrix2[13] + matrix2[15] ); +qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 19, tRow ); +rRow[0] = 0.5 * ( matrix2[2] + matrix2[3] ); +rRow[1] = 0.5 * ( matrix2[6] + matrix2[7] ); +rRow[2] = 0.5 * ( matrix2[10] + matrix2[11] ); +rRow[3] = 0.5 * ( matrix2[14] + matrix2[15] ); +qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 20, rRow ); +qRow[0] = matrix2[3]; +qRow[1] = matrix2[7]; +qRow[2] = matrix2[11]; +qRow[3] = matrix2[15]; +qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 21, qRow ); + + + // testing fragment based normal mapping + if ( r_testARBProgram.GetBool() ) { + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.ToFloatPtr() ); + } + + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + static const float negOne[4] = { -1, -1, -1, -1 }; + + switch ( din->vertexColor ) { + case SVC_IGNORE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + case SVC_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero ); + break; + case SVC_INVERSE_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + } + + // set the constant colors + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr() ); + + //----------------------------------------------------- + // screen power of two correction factor + + float parm[4]; + parm[0] = 1.0 / ( JITTER_SIZE * r_sb_samples.GetInteger() ) ; + parm[1] = 1.0 / JITTER_SIZE; + parm[2] = 0; + parm[3] = 1; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm ); + + // jitter tex scale + parm[0] = + parm[1] = r_sb_jitterScale.GetFloat() * lightBufferSizeFraction; + parm[2] = -r_sb_biasScale.GetFloat(); + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, parm ); + + // jitter tex offset + if ( r_sb_randomize.GetBool() ) { + parm[0] = (rand()&255) / 255.0; + parm[1] = (rand()&255) / 255.0; + } else { + parm[0] = parm[1] = 0; + } + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, parm ); + //----------------------------------------------------- + + // set the textures + + // texture 1 will be the per-surface bump map + GL_SelectTextureNoClient( 1 ); + din->bumpImage->Bind(); + + // texture 2 will be the light falloff texture + GL_SelectTextureNoClient( 2 ); + din->lightFalloffImage->Bind(); + + // texture 3 will be the light projection texture + GL_SelectTextureNoClient( 3 ); + din->lightImage->Bind(); + + // texture 4 is the per-surface diffuse map + GL_SelectTextureNoClient( 4 ); + din->diffuseImage->Bind(); + + // texture 5 is the per-surface specular map + GL_SelectTextureNoClient( 5 ); + din->specularImage->Bind(); + + // draw it + RB_DrawElementsWithCounters( din->surf->geo ); +} + +/* +============= +RB_EXP_CreateDrawInteractions + +============= +*/ +void RB_EXP_CreateDrawInteractions( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + if ( r_sb_screenSpaceShadow.GetBool() ) { + // perform setup here that will be constant for all interactions + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); + + if ( r_testARBProgram.GetBool() ) { + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST ); + } else { + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION ); + } + } else { + // perform setup here that will be constant for all interactions + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); +GL_State( GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );//!@# + + // bind the vertex program + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, shadowVertexProgram ); + if ( r_sb_samples.GetInteger() == 16 ) { + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram16 ); + } else if ( r_sb_samples.GetInteger() == 4 ) { + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram4 ); + } else if ( r_sb_samples.GetInteger() == 1 ) { + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram1 ); + } else { + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram0 ); + } + } + + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + // enable the vertex arrays + qglEnableVertexAttribArrayARB( 8 ); + qglEnableVertexAttribArrayARB( 9 ); + qglEnableVertexAttribArrayARB( 10 ); + qglEnableVertexAttribArrayARB( 11 ); + qglEnableClientState( GL_COLOR_ARRAY ); + + // texture 0 is the normalization cube map for the vector towards the light + GL_SelectTextureNoClient( 0 ); + if ( backEnd.vLight->lightShader->IsAmbientLight() ) { + globalImages->normalCubeMapImage->Bind(); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT); + } else { + globalImages->normalCubeMapImage->Bind(); + } + + // texture 6 is the specular lookup table + GL_SelectTextureNoClient( 6 ); + if ( r_testARBProgram.GetBool() ) { + globalImages->specular2DTableImage->Bind(); // variable specularity in alpha channel + } else { + globalImages->specularTableImage->Bind(); + } + + + for ( ; surf ; surf=surf->nextOnLight ) { + // perform setup here that will not change over multiple interaction passes + if ( backEnd.vLight->lightShader->IsAmbientLight() ) { + float parm[4]; + + parm[0] = surf->space->modelMatrix[0]; + parm[1] = surf->space->modelMatrix[4]; + parm[2] = surf->space->modelMatrix[8]; + parm[3] = 0; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 20, parm ); + parm[0] = surf->space->modelMatrix[1]; + parm[1] = surf->space->modelMatrix[5]; + parm[2] = surf->space->modelMatrix[9]; + parm[3] = 0; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 21, parm ); + parm[0] = surf->space->modelMatrix[2]; + parm[1] = surf->space->modelMatrix[6]; + parm[2] = surf->space->modelMatrix[10]; + parm[3] = 0; + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 22, parm ); + + GL_SelectTextureNoClient( 0 ); + const shaderStage_t *stage = backEnd.vLight->lightShader->GetStage( 0 ); + if ( stage->newStage ) { + stage->newStage->fragmentProgramImages[7]->BindFragment(); + } + } + + // set the vertex pointers + idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); + qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + + // this may cause RB_ARB2_DrawInteraction to be exacuted multiple + // times with different colors and images if the surface or light have multiple layers + if ( r_sb_screenSpaceShadow.GetBool() ) { + RB_CreateSingleDrawInteractions( surf, RB_ARB2_DrawInteraction ); + } else { + RB_CreateSingleDrawInteractions( surf, RB_EXP_DrawInteraction ); + } + } + + qglDisableVertexAttribArrayARB( 8 ); + qglDisableVertexAttribArrayARB( 9 ); + qglDisableVertexAttribArrayARB( 10 ); + qglDisableVertexAttribArrayARB( 11 ); + qglDisableClientState( GL_COLOR_ARRAY ); + + // disable features + GL_SelectTextureNoClient( 6 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 5 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 4 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 3 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 2 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 1 ); + globalImages->BindNull(); + + backEnd.glState.currenttmu = -1; + GL_SelectTexture( 0 ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); +} + +void InvertByTranspose( const float a[16], float r[16] ) { + r[ 0] = a[ 0]; + r[ 1] = a[ 4]; + r[ 2] = a[ 8]; + r[ 3] = 0; + r[ 4] = a[ 1]; + r[ 5] = a[ 5]; + r[ 6] = a[ 9]; + r[ 7] = 0; + r[ 8] = a[ 2]; + r[ 9] = a[ 6]; + r[10] = a[10]; + r[11] = 0; + r[12] = -(r[ 0]*a[12] + r[ 4]*a[13] + r[ 8]*a[14]); + r[13] = -(r[ 1]*a[12] + r[ 5]*a[13] + r[ 9]*a[14]); + r[14] = -(r[ 2]*a[12] + r[ 6]*a[13] + r[10]*a[14]); + r[15] = 1; +} + +void FullInvert( const float a[16], float r[16] ) { + idMat4 am; + + for ( int i = 0 ; i < 4 ; i++ ) { + for ( int j = 0 ; j < 4 ; j++ ) { + am[i][j] = a[j*4+i]; + } + } + +// idVec4 test( 100, 100, 100, 1 ); +// idVec4 transformed, inverted; +// transformed = test * am; + + if ( !am.InverseSelf() ) { + common->Error( "Invert failed" ); + } +// inverted = transformed * am; + + for ( int i = 0 ; i < 4 ; i++ ) { + for ( int j = 0 ; j < 4 ; j++ ) { + r[j*4+i] = am[i][j]; + } + } +} + +/* +================== +RB_Exp_TrianglesForFrustum +================== +*/ +const srfTriangles_t *RB_Exp_TrianglesForFrustum( viewLight_t *vLight, int side ) { + const srfTriangles_t *tri; + + static srfTriangles_t frustumTri; + static idDrawVert verts[5]; + static glIndex_t indexes[18] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 2, 1, 4, 2, 4, 3 }; + + if ( side == -1 ) { + tri = vLight->frustumTris; + } else { + memset( verts, 0, sizeof( verts ) ); + + for ( int i = 0 ; i < 5 ; i++ ) { + verts[i].xyz = vLight->globalLightOrigin; + } + + memset( &frustumTri, 0, sizeof( frustumTri ) ); + frustumTri.indexes = indexes; + frustumTri.verts = verts; + frustumTri.numIndexes = 18; + frustumTri.numVerts = 5; + + tri = &frustumTri; + + float size = viewLightAxialSize; + + switch ( side ) { + case 0: + verts[1].xyz[0] += size; + verts[2].xyz[0] += size; + verts[3].xyz[0] += size; + verts[4].xyz[0] += size; + verts[1].xyz[1] += size; + verts[1].xyz[2] += size; + verts[2].xyz[1] -= size; + verts[2].xyz[2] += size; + verts[3].xyz[1] -= size; + verts[3].xyz[2] -= size; + verts[4].xyz[1] += size; + verts[4].xyz[2] -= size; + break; + case 1: + verts[1].xyz[0] -= size; + verts[2].xyz[0] -= size; + verts[3].xyz[0] -= size; + verts[4].xyz[0] -= size; + verts[1].xyz[1] -= size; + verts[1].xyz[2] += size; + verts[2].xyz[1] += size; + verts[2].xyz[2] += size; + verts[3].xyz[1] += size; + verts[3].xyz[2] -= size; + verts[4].xyz[1] -= size; + verts[4].xyz[2] -= size; + break; + case 2: + verts[1].xyz[1] += size; + verts[2].xyz[1] += size; + verts[3].xyz[1] += size; + verts[4].xyz[1] += size; + verts[1].xyz[0] -= size; + verts[1].xyz[2] += size; + verts[2].xyz[0] += size; + verts[2].xyz[2] += size; + verts[3].xyz[0] += size; + verts[3].xyz[2] -= size; + verts[4].xyz[0] -= size; + verts[4].xyz[2] -= size; + break; + case 3: + verts[1].xyz[1] -= size; + verts[2].xyz[1] -= size; + verts[3].xyz[1] -= size; + verts[4].xyz[1] -= size; + verts[1].xyz[0] += size; + verts[1].xyz[2] += size; + verts[2].xyz[0] -= size; + verts[2].xyz[2] += size; + verts[3].xyz[0] -= size; + verts[3].xyz[2] -= size; + verts[4].xyz[0] += size; + verts[4].xyz[2] -= size; + break; + case 4: + verts[1].xyz[2] += size; + verts[2].xyz[2] += size; + verts[3].xyz[2] += size; + verts[4].xyz[2] += size; + verts[1].xyz[0] += size; + verts[1].xyz[1] += size; + verts[2].xyz[0] -= size; + verts[2].xyz[1] += size; + verts[3].xyz[0] -= size; + verts[3].xyz[1] -= size; + verts[4].xyz[0] += size; + verts[4].xyz[1] -= size; + break; + case 5: + verts[1].xyz[2] -= size; + verts[2].xyz[2] -= size; + verts[3].xyz[2] -= size; + verts[4].xyz[2] -= size; + verts[1].xyz[0] -= size; + verts[1].xyz[1] += size; + verts[2].xyz[0] += size; + verts[2].xyz[1] += size; + verts[3].xyz[0] += size; + verts[3].xyz[1] -= size; + verts[4].xyz[0] -= size; + verts[4].xyz[1] -= size; + break; + } + + frustumTri.ambientCache = vertexCache.AllocFrameTemp( verts, sizeof( verts ) ); + } + + return tri; +} + + +/* +================== +RB_Exp_SelectFrustum +================== +*/ +void RB_Exp_SelectFrustum( viewLight_t *vLight, int side ) { + qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix ); + + const srfTriangles_t *tri = RB_Exp_TrianglesForFrustum( vLight, side ); + + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + + qglDisable( GL_TEXTURE_2D ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + // clear stencil buffer + qglEnable( GL_SCISSOR_TEST ); + qglEnable( GL_STENCIL_TEST ); + qglClearStencil( 1 ); + qglClear( GL_STENCIL_BUFFER_BIT ); + + // draw front faces of the light frustum, incrementing the stencil buffer on depth fail + // so we can't draw on those pixels + GL_State( GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglStencilFunc( GL_ALWAYS, 0, 255 ); + qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP ); + GL_Cull( CT_FRONT_SIDED ); + + RB_DrawElementsWithCounters( tri ); + + // draw back faces of the light frustum with + // depth test greater + // stencil test of equal 1 + // zero stencil stencil when depth test passes, so subsequent surface drawing + // can occur on those pixels + + // this pass does all the shadow filtering + qglStencilFunc( GL_EQUAL, 1, 255 ); + qglStencilOp( GL_KEEP, GL_KEEP, GL_ZERO ); + + GL_Cull( CT_BACK_SIDED ); + qglDepthFunc( GL_GREATER ); + + // write to destination alpha + if ( r_sb_showFrustumPixels.GetBool() ) { + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglDisable( GL_TEXTURE_2D ); + qglColor4f( 0, 0.25, 0, 1 ); + } else { + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, screenSpaceShadowVertexProgram ); + switch ( r_sb_samples.GetInteger() ) { + case 0: + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram0 ); + break; + case 1: + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram1 ); + break; + case 4: + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram4 ); + break; + case 16: + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram16 ); + break; + } + } + +/* +texture[0] = view depth texture +texture[1] = jitter texture +texture[2] = light depth texture +*/ + GL_SelectTextureNoClient( 2 ); + shadowImage[0]->Bind(); + + GL_SelectTextureNoClient( 1 ); + if ( r_sb_samples.GetInteger() == 16 ) { + jitterImage16->Bind(); + } else if ( r_sb_samples.GetInteger() == 4 ) { + jitterImage4->Bind(); + } else { + jitterImage1->Bind(); + } + + GL_SelectTextureNoClient( 0 ); + viewDepthImage->Bind(); + + /* +PARAM positionToDepthTexScale = program.local[0]; # fragment.position to screen depth texture transformation +PARAM zProject = program.local[1]; # projection[10], projection[14], 0, 0 +PARAM positionToViewSpace = program.local[2]; # X add, Y add, X mul, Y mul +PARAM viewToLightS = program.local[3]; +PARAM viewToLightT = program.local[4]; +PARAM viewToLightR = program.local[5]; +PARAM viewToLightQ = program.local[6]; +PARAM positionToJitterTexScale = program.local[7]; # fragment.position to jitter texture +PARAM jitterTexScale = program.local[8]; +PARAM jitterTexOffset = program.local[9]; +*/ + float parm[4]; + int pot; + + // calculate depth projection for shadow buffer + float sRow[4]; + float tRow[4]; + float rRow[4]; + float qRow[4]; + float invertedView[16]; + float invertedProjection[16]; + float matrix[16]; + float matrix2[16]; + + // we need the inverse of the projection matrix to go from NDC to view + FullInvert( backEnd.viewDef->projectionMatrix, invertedProjection ); + + /* + from window to NDC: + ( x - xMid ) * 1.0 / xMid + ( y - yMid ) * 1.0 / yMid + ( z - 0.5 ) * 2 + + from NDC to clip coordinates: + rcp(1/w) + + */ + + // we need the inverse of the viewMatrix to go from view (looking down negative Z) to world + InvertByTranspose( backEnd.viewDef->worldSpace.modelViewMatrix, invertedView ); + + // then we go from world to light view space (looking down negative Z) + myGlMultMatrix( invertedView, lightMatrix, matrix ); + + // then to light projection, giving X/w, Y/w, Z/w in the -1 : 1 range + myGlMultMatrix( matrix, lightProjectionMatrix, matrix2 ); + + // the final values need to be in 0.0 : 1.0 range instead of -1 : 1 + sRow[0] = 0.5 * ( matrix2[0] + matrix2[3] ) * lightBufferSizeFraction; + sRow[1] = 0.5 * ( matrix2[4] + matrix2[7] ) * lightBufferSizeFraction; + sRow[2] = 0.5 * ( matrix2[8] + matrix2[11] ) * lightBufferSizeFraction; + sRow[3] = 0.5 * ( matrix2[12] + matrix2[15] ) * lightBufferSizeFraction; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, sRow ); + tRow[0] = 0.5 * ( matrix2[1] + matrix2[3] ) * lightBufferSizeFraction; + tRow[1] = 0.5 * ( matrix2[5] + matrix2[7] ) * lightBufferSizeFraction; + tRow[2] = 0.5 * ( matrix2[9] + matrix2[11] ) * lightBufferSizeFraction; + tRow[3] = 0.5 * ( matrix2[13] + matrix2[15] ) * lightBufferSizeFraction; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, tRow ); + rRow[0] = 0.5 * ( matrix2[2] + matrix2[3] ); + rRow[1] = 0.5 * ( matrix2[6] + matrix2[7] ); + rRow[2] = 0.5 * ( matrix2[10] + matrix2[11] ); + rRow[3] = 0.5 * ( matrix2[14] + matrix2[15] ); + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 5, rRow ); + qRow[0] = matrix2[3]; + qRow[1] = matrix2[7]; + qRow[2] = matrix2[11]; + qRow[3] = matrix2[15]; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 6, qRow ); + + //----------------------------------------------------- + // these should be constant for the entire frame + + // convert 0..viewport-1 sizes to fractions inside the POT screen depth texture + int w = viewBufferSize; + pot = MakePowerOfTwo( w ); + parm[0] = 1.0 / maxViewBufferSize; // * ( (float)viewBufferSize / w ); + int h = viewBufferHeight; + pot = MakePowerOfTwo( h ); + parm[1] = parm[0]; // 1.0 / pot; + parm[2] = 0; + parm[3] = 1; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + + // zProject values + parm[0] = backEnd.viewDef->projectionMatrix[10]; + parm[1] = backEnd.viewDef->projectionMatrix[14]; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm ); + + // positionToViewSpace + parm[0] = -1.0 / backEnd.viewDef->projectionMatrix[0]; + parm[1] = -1.0 / backEnd.viewDef->projectionMatrix[5]; + parm[2] = 2.0/viewBufferSize; + parm[3] = 2.0/viewBufferSize; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm ); + + // positionToJitterTexScale + parm[0] = 1.0 / ( JITTER_SIZE * r_sb_samples.GetInteger() ) ; + parm[1] = 1.0 / JITTER_SIZE; + parm[2] = 0; + parm[3] = 1; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 7, parm ); + + // jitter tex scale + parm[0] = + parm[1] = r_sb_jitterScale.GetFloat() * lightBufferSizeFraction; + parm[2] = -r_sb_biasScale.GetFloat(); + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 8, parm ); + + // jitter tex offset + if ( r_sb_randomize.GetBool() ) { + parm[0] = (rand()&255) / 255.0; + parm[1] = (rand()&255) / 255.0; + } else { + parm[0] = parm[1] = 0; + } + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 9, parm ); + //----------------------------------------------------- + + + + RB_DrawElementsWithCounters( tri ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); + + GL_Cull( CT_FRONT_SIDED ); +// qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + qglDepthFunc( GL_LEQUAL ); + if ( r_sb_showFrustumPixels.GetBool() ) { + qglEnable( GL_TEXTURE_2D ); + qglColor3f( 1, 1, 1 ); + } + + // after all the frustums have been drawn, the surfaces that have been drawn on will get interactions + // scissor may still be a win even with the stencil test for very fast rejects + qglStencilFunc( GL_EQUAL, 0, 255 ); + qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + + // we can avoid clearing the stencil buffer by changing the hasLight value for each light +} + +/* +================== +R_EXP_CalcLightAxialSize + +all light side projections must currently match, so non-centered +and non-cubic lights must take the largest length +================== +*/ +float R_EXP_CalcLightAxialSize( viewLight_t *vLight ) { + float max = 0; + + if ( !vLight->lightDef->parms.pointLight ) { + idVec3 dir = vLight->lightDef->parms.target - vLight->lightDef->parms.origin; + max = dir.Length(); + return max; + } + + for ( int i = 0 ; i < 3 ; i++ ) { + float dist = fabs(vLight->lightDef->parms.lightCenter[i] ); + dist += vLight->lightDef->parms.lightRadius[i]; + if ( dist > max ) { + max = dist; + } + } + return max; +} + +/* +================== +R_EXP_RenderViewDepthImage + +This could be avoided by drop sampling the native view depth buffer with render to texture +Bilerp might even be aprorpiate, although it would cause issues at edges +================== +*/ +void RB_T_FillDepthBuffer( const drawSurf_t *surf ); + +void R_EXP_RenderViewDepthImage( void ) { + if ( !r_sb_screenSpaceShadow.GetBool() ) { + return; + } + + // if the screen resolution is exactly the window width, we can + // use the depth buffer we already have + if ( 0 ) { // nativeViewBuffer ) { + viewDepthImage->CopyDepthbuffer( backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y1, backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1, + backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1 ); + } else { + RB_LogComment( "---------- R_EXP_RenderViewDepthImage ----------\n" ); + + if ( r_sb_usePbuffer.GetBool() ) { + GL_CheckErrors(); + // set the current openGL drawable to the shadow buffer + R_MakeCurrent( viewPbufferDC, win32.hGLRC, NULL /* !@# viewPbuffer */ ); + } + + // render the depth to the new size + qglViewport( 0, 0, viewBufferSize, viewBufferHeight ); + qglScissor( 0, 0, viewBufferSize, viewBufferHeight ); + qglClear( GL_DEPTH_BUFFER_BIT ); + qglStencilFunc( GL_ALWAYS, 0, 255 ); + + // the first texture will be used for alpha tested surfaces + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_State( GLS_DEPTHFUNC_LESS ); + + RB_RenderDrawSurfListWithFunction( backEnd.viewDef->drawSurfs, backEnd.viewDef->numDrawSurfs, RB_T_FillDepthBuffer ); + + // + // copy it to a texture + // + viewDepthImage->Bind(); + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, viewBufferSize, viewBufferHeight ); + + if ( r_sb_usePbuffer.GetBool() ) { + // set the normal screen drawable current + R_MakeCurrent( win32.hDC, win32.hGLRC, NULL ); + } + + // reset the window clipping + qglMatrixMode( GL_PROJECTION ); + qglLoadMatrixf( backEnd.viewDef->projectionMatrix ); + qglMatrixMode( GL_MODELVIEW ); + + qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, + backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + qglScissor( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, + backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + + // the current modelView matrix is not valid + backEnd.currentSpace = NULL; + } + + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); +} + +/* +================== +RB_EXP_SetNativeBuffer + +This is always the back buffer, and scissor is set full screen +================== +*/ +void RB_EXP_SetNativeBuffer( void ) { + // set the normal screen drawable current + R_MakeCurrent( win32.hDC, win32.hGLRC, NULL ); + + qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, + backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + + backEnd.currentScissor = backEnd.viewDef->viewport; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } +} + +/* +================== +RB_EXP_SetRenderBuffer + +This may be to a float pBuffer, and scissor is set to cover only the light +================== +*/ +void RB_EXP_SetRenderBuffer( viewLight_t *vLight ) { + if ( r_hdr_useFloats.GetBool() ) { + R_MakeCurrent( floatPbufferDC, floatContext, floatPbuffer ); + } else { + if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) { + GL_CheckErrors(); + common->FatalError( "Couldn't return to normal drawing context" ); + } + } + + qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, + backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + + if ( !vLight ) { + backEnd.currentScissor = backEnd.viewDef->viewport; + } else { + backEnd.currentScissor = vLight->scissorRect; + } + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } +} + +/* +================== +RB_shadowResampleAlpha + +================== +*/ +void RB_shadowResampleAlpha( void ) { + viewAlphaImage->Bind(); + // we could make this a subimage, but it isn't relevent once we have render-to-texture + qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, viewBufferSize, viewBufferHeight ); + + RB_EXP_SetRenderBuffer( backEnd.vLight ); + +//===================== + + qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix ); + + // this uses the full light, not side frustums + const srfTriangles_t *tri = backEnd.vLight->frustumTris; + + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + + // clear stencil buffer + qglEnable( GL_SCISSOR_TEST ); + qglEnable( GL_STENCIL_TEST ); + qglClearStencil( 1 ); + qglClear( GL_STENCIL_BUFFER_BIT ); + + // draw front faces of the light frustum, incrementing the stencil buffer on depth fail + // so we can't draw on those pixels + GL_State( GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglStencilFunc( GL_ALWAYS, 0, 255 ); + qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP ); + GL_Cull( CT_FRONT_SIDED ); + + // set fragment / vertex program? + + RB_DrawElementsWithCounters( tri ); + + // draw back faces of the light frustum with + // depth test greater + // stencil test of equal 1 + // zero stencil stencil when depth test passes, so subsequent interaction drawing + // can occur on those pixels + + // this pass does all the shadow filtering + qglStencilFunc( GL_EQUAL, 1, 255 ); + qglStencilOp( GL_KEEP, GL_KEEP, GL_ZERO ); + + // write to destination alpha + if ( r_sb_showFrustumPixels.GetBool() ) { + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglDisable( GL_TEXTURE_2D ); + qglColor4f( 0, 0.25, 0, 1 ); + } else { + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, shadowResampleVertexProgram ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowResampleFragmentProgram ); + + // convert 0..viewport-1 sizes to fractions inside the POT screen depth texture + // shrink by one unit for bilerp + float parm[4]; + parm[0] = 1.0 / (maxViewBufferSize+1) * viewBufferSize / maxViewBufferSize; + parm[1] = parm[0]; + parm[2] = 0; + parm[3] = 1; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + } + + GL_Cull( CT_BACK_SIDED ); + qglDepthFunc( GL_GREATER ); + + RB_DrawElementsWithCounters( tri ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); + + GL_Cull( CT_FRONT_SIDED ); + + qglDepthFunc( GL_LEQUAL ); + if ( r_sb_showFrustumPixels.GetBool() ) { + qglEnable( GL_TEXTURE_2D ); + qglColor3f( 1, 1, 1 ); + } + + // after all the frustums have been drawn, the surfaces that have been drawn on will get interactions + // scissor may still be a win even with the stencil test for very fast rejects + qglStencilFunc( GL_EQUAL, 0, 255 ); + qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); +} + + +/* +================== +RB_EXP_CoverScreen +================== +*/ +void RB_EXP_CoverScreen( void ) { + // draw a full screen quad + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + qglBegin( GL_TRIANGLE_FAN ); + qglVertex2f( 0, 0 ); + qglVertex2f( 0, 1 ); + qglVertex2f( 1, 1 ); + qglVertex2f( 1, 0 ); + qglEnd(); +} + +/* +================== +RB_EXP_ReadFloatBuffer +================== +*/ +void RB_EXP_ReadFloatBuffer( void ) { + int pixels = glConfig.vidWidth * glConfig.vidHeight; + float *buf = (float *)R_StaticAlloc( pixels * 4 * sizeof( float ) ); + + qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_FLOAT, buf ); + + float mins[4] = { 9999, 9999, 9999, 9999 }; + float maxs[4] = { -9999, -9999, -9999, -9999 }; + for ( int i = 0 ; i < pixels ; i++ ) { + for ( int j = 0 ; j < 4 ; j++ ) { + float v = buf[ i*4 + j ]; + if ( v < mins[j] ) { + mins[j] = v; + } + if ( v > maxs[j] ) { + maxs[j] = v; + } + } + } + + RB_EXP_SetNativeBuffer(); + + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + qglColor3f( 1, 1, 1 ); + qglPushMatrix(); + qglLoadIdentity(); + qglDisable( GL_TEXTURE_2D ); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglRasterPos2f( 0.01f, 0.01f ); + qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_FLOAT, buf ); + qglPopMatrix(); + qglEnable( GL_TEXTURE_2D ); + qglMatrixMode( GL_MODELVIEW ); + + R_StaticFree( buf ); +} + + +void RB_TestGamma( void ); + +/* +================== +RB_EXP_GammaDither +================== +*/ +void RB_EXP_GammaDither( void ) { + if ( !r_hdr_useFloats.GetBool() ) { + return; + } + +#if 0 +r_testGamma.SetBool( true ); +RB_TestGamma(); +r_testGamma.SetBool( false ); +#endif + + RB_EXP_SetNativeBuffer(); + + /* +# texture 0 is the high dynamic range buffer +# texture 1 is the random dither texture +# texture 2 is the light bloom texture + +# writes result.color as the 32 bit dithered and gamma corrected values + +PARAM exposure = program.local[0]; # multiply HDR value by this to get screen pixels +PARAM gammaPower = program.local[1]; +PARAM monitorDither = program.local[2]; +PARAM positionToDitherScale = program.local[3]; +PARAM bloomFraction = program.local[4]; +PARAM positionToBloomScale = program.local[5]; + + */ + + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB,gammaDitherVertexProgram ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, gammaDitherFragmentProgram ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + qglActiveTextureARB( GL_TEXTURE2_ARB ); + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferQuarterImage->texnum ); + R_BindTexImage( floatPbufferQuarter ); + + qglActiveTextureARB( GL_TEXTURE1_ARB ); + random256Image->BindFragment(); + + qglActiveTextureARB( GL_TEXTURE0_ARB ); + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferImage->texnum ); + R_BindTexImage( floatPbuffer ); + + float parm[4]; + + parm[0] = r_hdr_exposure.GetFloat(); + parm[1] = 0; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + + parm[0] = r_hdr_gamma.GetFloat(); + parm[1] = 0; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm ); + + parm[0] = r_hdr_monitorDither.GetFloat(); + parm[1] = 0; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm ); + + parm[0] = 1.0 / 256; + parm[1] = parm[0]; + parm[2] = rand()/65535.0; + parm[3] = rand()/65535.0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, parm ); + + parm[0] = 1.0 - r_hdr_bloomFraction.GetFloat(); + parm[1] = r_hdr_bloomFraction.GetFloat(); + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, parm ); + + parm[0] = 0.25; + parm[1] = 0.25; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 5, parm ); + + qglDisable( GL_STENCIL_TEST ); + qglDisable( GL_SCISSOR_TEST ); + qglDisable( GL_DEPTH_TEST ); + + RB_EXP_CoverScreen(); + + qglEnable( GL_DEPTH_TEST ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); +} + +/* +================== +RB_EXP_Bloom +================== +*/ +void RB_EXP_Bloom( void ) { + if ( !r_hdr_useFloats.GetBool() ) { + return; + } + + if ( r_hdr_bloomFraction.GetFloat() == 0 ) { + return; + } + + GL_CheckErrors(); + + // + // mip map + // + + // draw to the second floatPbuffer + R_MakeCurrent( floatPbuffer2DC, floatContext, floatPbuffer2 ); + + GL_State( 0 ); + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_SCISSOR_TEST ); + + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + qglClearColor( 1.0, 0.5, 0, 0 ); + qglClear( GL_COLOR_BUFFER_BIT ); + qglViewport( 0, 0, glConfig.vidWidth>>1, glConfig.vidHeight>>1 ); + + // read from the original floatPbuffer + qglActiveTextureARB( GL_TEXTURE0_ARB ); + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferImage->texnum ); + R_BindTexImage( floatPbuffer ); + + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, downSampleVertexProgram ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, downSampleFragmentProgram ); + + RB_EXP_CoverScreen(); + + // + // mip map again + // + qglViewport( 0, 0, glConfig.vidWidth>>2, glConfig.vidHeight>>2 ); + + // draw to the second floatPbuffer + R_MakeCurrent( floatPbufferQuarterDC, floatContext, floatPbufferQuarter ); + + // read from the original floatPbuffer + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbuffer2Image->texnum ); + R_BindTexImage( floatPbuffer2 ); + + RB_EXP_CoverScreen(); + + // + // blur horizontally + // + /* +# texture 0 is the high dynamic range buffer +# writes result.color as the fp16 result of a smeared bloom + +PARAM step = program.local[0]; # { 1, 0 } or { 0, 1 } for horizontal / vertical separation + */ + + // draw to the second floatPbuffer + R_MakeCurrent( floatPbuffer2DC, floatContext, floatPbuffer2 ); + + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, bloomVertexProgram ); + qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, bloomFragmentProgram ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + qglEnable(GL_FRAGMENT_PROGRAM_ARB); + + GL_SelectTextureNoClient( 0 ); + + // blur horizontally first to the second floatPbuffer + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferQuarterImage->texnum ); + R_BindTexImage( floatPbufferQuarter ); + + float parm[4]; + + parm[0] = 1; + parm[1] = 0; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + + RB_EXP_CoverScreen(); + + // + // now blur vertically back to the quarter pbuffer + // + R_MakeCurrent( floatPbufferQuarterDC, floatContext, floatPbufferQuarter ); + + qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbuffer2Image->texnum ); + R_BindTexImage( floatPbuffer2 ); + + parm[0] = 0; + parm[1] = 1; + parm[2] = 0; + parm[3] = 0; + qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm ); + + RB_EXP_CoverScreen(); + + //======================== + + qglEnable( GL_DEPTH_TEST ); + qglEnable( GL_SCISSOR_TEST ); + + qglDisable(GL_VERTEX_PROGRAM_ARB); + qglDisable(GL_FRAGMENT_PROGRAM_ARB); + + GL_CheckErrors(); +} + +/* +================== +RB_Exp_DrawInteractions +================== +*/ +void RB_Exp_DrawInteractions( void ) { + if ( !initialized ) { + R_Exp_Allocate(); + } + + if ( !backEnd.viewDef->viewLights ) { + return; + } + + // validate the samples + if ( r_sb_samples.GetInteger() != 16 && r_sb_samples.GetInteger() != 4 && r_sb_samples.GetInteger() != 1 ) { + r_sb_samples.SetInteger( 0 ); + } + + // validate the light resolution + if ( r_sb_lightResolution.GetInteger() < 64 ) { + r_sb_lightResolution.SetInteger( 64 ); + } else if ( r_sb_lightResolution.GetInteger() > maxLightBufferSize ) { + r_sb_lightResolution.SetInteger( maxLightBufferSize ); + } + lightBufferSize = r_sb_lightResolution.GetInteger(); + lightBufferSizeFraction = (float)lightBufferSize / maxLightBufferSize; + + // validate the view resolution + if ( r_sb_viewResolution.GetInteger() < 64 ) { + r_sb_viewResolution.SetInteger( 64 ); + } else if ( r_sb_viewResolution.GetInteger() > maxViewBufferSize ) { + r_sb_viewResolution.SetInteger( maxViewBufferSize ); + } + viewBufferSize = r_sb_viewResolution.GetInteger(); + viewBufferHeight = viewBufferSize * 3 / 4; + viewBufferSizeFraction = (float)viewBufferSize / maxViewBufferSize; + viewBufferHeightFraction = (float)viewBufferHeight / maxViewBufferSize; + if ( viewBufferSize == backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1 ) { + nativeViewBuffer = true; + } else { + nativeViewBuffer = false; + } + + // set up for either point sampled or percentage-closer filtering for the shadow sampling + shadowImage[0]->BindFragment(); + if ( r_sb_linearFilter.GetBool() ) { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + } else { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + } + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE ); + + globalImages->BindNull(); + + // copy the current depth buffer to a texture for image-space shadowing, + // or re-render at a lower resolution + R_EXP_RenderViewDepthImage(); + + GL_SelectTexture( 0 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + // disable stencil shadow test + qglStencilFunc( GL_ALWAYS, 128, 255 ); + + // the jitter image will be used to offset sample centers + GL_SelectTextureNoClient( 8 ); + if ( r_sb_samples.GetInteger() == 16 ) { + jitterImage16->BindFragment(); + } else if ( r_sb_samples.GetInteger() == 4 ) { + jitterImage4->BindFragment(); + } else { + jitterImage1->BindFragment(); + } + + // if we are using a float buffer, clear it now + if ( r_hdr_useFloats.GetBool() ) { + RB_EXP_SetRenderBuffer( NULL ); + // we need to set a lot of things, because this is a completely different context + RB_SetDefaultGLState(); + qglClearColor( 0.001f, 1.0f, 0.01f, 0.1f ); + qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + // clear the z buffer, set the projection matrix, etc + RB_BeginDrawingView(); + RB_STD_FillDepthBuffer( (drawSurf_t **)&backEnd.viewDef->drawSurfs[0], backEnd.viewDef->numDrawSurfs ); + } + + + // + // for each light, perform adding and shadowing + // + for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + backEnd.vLight = vLight; + + const idMaterial *lightShader = vLight->lightShader; + + // do fogging later + if ( lightShader->IsFogLight() ) { + continue; + } + if ( lightShader->IsBlendLight() ) { + continue; + } + + if ( !vLight->localInteractions && !vLight->globalInteractions + && !vLight->translucentInteractions ) { + continue; + } + + if ( !vLight->frustumTris->ambientCache ) { + R_CreateAmbientCache( const_cast(vLight->frustumTris), false ); + } + + // all light side projections must currently match, so non-centered + // and non-cubic lights must take the largest length + viewLightAxialSize = R_EXP_CalcLightAxialSize( vLight ); + + int side, sideStop; + + if ( vLight->lightDef->parms.pointLight ) { + if ( r_sb_singleSide.GetInteger() != -1 ) { + side = r_sb_singleSide.GetInteger(); + sideStop = side+1; + } else { + side = 0; + sideStop = 6; + } + } else { + side = -1; + sideStop = 0; + } + + for ( ; side < sideStop ; side++ ) { + // FIXME: check for frustums completely off the screen + + // render a shadow buffer + RB_RenderShadowBuffer( vLight, side ); + + // back to view rendering, possibly in the off-screen buffer + if ( nativeViewBuffer || !r_sb_screenSpaceShadow.GetBool() ) { + // directly to screen + RB_EXP_SetRenderBuffer( vLight ); + } else { + // to off screen buffer + if ( r_sb_usePbuffer.GetBool() ) { + GL_CheckErrors(); + // set the current openGL drawable to the shadow buffer + R_MakeCurrent( viewPbufferDC, win32.hGLRC, viewPbuffer ); + } + qglViewport( 0, 0, viewBufferSize, viewBufferHeight ); + qglScissor( 0, 0, viewBufferSize, viewBufferHeight ); // !@# FIXME: scale light scissor + } + + // render the shadows into destination alpha on the included pixels + RB_Exp_SelectFrustum( vLight, side ); + + if ( !r_sb_screenSpaceShadow.GetBool() ) { + // bind shadow buffer to texture + GL_SelectTextureNoClient( 7 ); + shadowImage[0]->BindFragment(); + + RB_EXP_CreateDrawInteractions( vLight->localInteractions ); + RB_EXP_CreateDrawInteractions( vLight->globalInteractions ); + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_EXP_CreateDrawInteractions( vLight->translucentInteractions ); + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + } + } + + // render the native window coordinates interactions + if ( r_sb_screenSpaceShadow.GetBool() ) { + if ( !nativeViewBuffer ) { + RB_shadowResampleAlpha(); + qglEnable( GL_STENCIL_TEST ); + } else { + RB_EXP_SetRenderBuffer( vLight ); +if ( r_ignore.GetBool() ) { +qglEnable( GL_STENCIL_TEST ); //!@# +} else { +qglDisable( GL_STENCIL_TEST ); //!@# +} + } + RB_EXP_CreateDrawInteractions( vLight->localInteractions ); + RB_EXP_CreateDrawInteractions( vLight->globalInteractions ); + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_EXP_CreateDrawInteractions( vLight->translucentInteractions ); + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + } + } + + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + // experimental transfer function + for ( int i = 7 ; i >= 0 ; i-- ) { + GL_SelectTextureNoClient( i ); + globalImages->BindNull(); + } + GL_State( 0 ); + + RB_EXP_Bloom(); + RB_EXP_GammaDither(); + + // these haven't been state saved + for ( int i = 0 ; i < 8 ; i++ ) { + backEnd.glState.tmu[i].current2DMap = -1; + } + + // take it out of texture compare mode so I can testImage it for debugging + shadowImage[0]->BindFragment(); + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); + + +} + + + +/* +================== +R_Exp_Init +================== +*/ +void R_Exp_Init( void ) { + glConfig.allowExpPath = false; + + common->Printf( "---------- R_Exp_Init ----------\n" ); + + if ( !glConfig.ARBVertexProgramAvailable || !glConfig.ARBFragmentProgramAvailable ) { + common->Printf( "Not available.\n" ); + return; + } +RB_CreateBloomTable(); +#if 0 + if ( !R_CheckExtension( "GL_NV_float_buffer" ) ) { + common->Printf( "Not available.\n" ); + return; + } + if ( !R_CheckExtension( "GL_NV_texture_rectangle" ) ) { + common->Printf( "Not available.\n" ); + return; + } +#endif + +#if 0 + qglCombinerParameterfvNV = (void (APIENTRY *)( GLenum pname, const GLfloat *params )) + GLimp_ExtensionPointer( "glCombinerParameterfvNV" ); +#endif + + common->Printf( "Available.\n" ); + + if ( !idStr::Icmp( r_renderer.GetString(), "exp" ) ) { + R_Exp_Allocate(); + } + + common->Printf( "--------------------------------------------\n" ); + + glConfig.allowExpPath = true; +} diff --git a/renderer/draw_exp_stub.cpp b/renderer/draw_exp_stub.cpp new file mode 100644 index 000000000..587e027ed --- /dev/null +++ b/renderer/draw_exp_stub.cpp @@ -0,0 +1,29 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +void R_Exp_Init( void ) { + common->Printf( "---------- R_Exp_Init -----------\n" ); + common->Printf( "Disabled at compile time.\n" ); + common->Printf( "---------------------------------\n" ); +} + +void RB_Exp_DrawInteractions( void ) { } diff --git a/renderer/draw_nv10.cpp b/renderer/draw_nv10.cpp new file mode 100644 index 000000000..f4c97bbb5 --- /dev/null +++ b/renderer/draw_nv10.cpp @@ -0,0 +1,638 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +/* +================== +RB_RenderInteraction + +backEnd.vLight +backEnd.lightScale + + +backEnd.depthFunc must be equal for alpha tested surfaces to work right, +it is set to lessThan for blended transparent surfaces + +This expects a bumpmap stage before a diffuse stage before a specular stage +The material code is responsible for guaranteeing that, but conditional stages +can still make it invalid. + +you can't blend two bumpmaps, but you can change bump maps between +blended diffuse / specular maps to get the same effect + + +================== +*/ +static void RB_RenderInteraction( const drawSurf_t *surf ) { + const idMaterial *surfaceShader = surf->material; + const float *surfaceRegs = surf->shaderRegisters; + const viewLight_t *vLight = backEnd.vLight; + const idMaterial *lightShader = vLight->lightShader; + const float *lightRegs = vLight->shaderRegisters; + static idPlane lightProject[4]; // reused across function calls + const srfTriangles_t *tri = surf->geo; + const shaderStage_t *lastBumpStage = NULL; + + RB_LogComment( "---------- RB_RenderInteraction %s on %s ----------\n", + lightShader->GetName(), surfaceShader->GetName() ); + + // change the matrix and light projection vectors if needed + if ( surf->space != backEnd.currentSpace ) { + backEnd.currentSpace = surf->space; + qglLoadMatrixf( surf->space->modelViewMatrix ); + + for ( int i = 0 ; i < 4 ; i++ ) { + R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] ); + } + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) { + backEnd.currentScissor = surf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + + // hack depth range if needed + if ( surf->space->weaponDepthHack ) { + RB_EnterWeaponDepthHack(); + } + + if ( surf->space->modelDepthHack != 0.0f ) { + RB_EnterModelDepthHack( surf->space->modelDepthHack ); + } + + + // set the vertex arrays, which may not all be enabled on a given pass + idDrawVert *ac = (idDrawVert *)vertexCache.Position(tri->ambientCache); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + GL_SelectTexture( 0 ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); + + + // go through the individual stages + for ( int i = 0 ; i < surfaceShader->GetNumStages() ; i++ ) { + const shaderStage_t *surfaceStage = surfaceShader->GetStage( i ); + + // ignore ambient stages while drawing interactions + if ( surfaceStage->lighting == SL_AMBIENT ) { + continue; + } + + // ignore stages that fail the condition + if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) { + continue; + } + + //----------------------------------------------------- + // + // bump / falloff + // + //----------------------------------------------------- + if ( surfaceStage->lighting == SL_BUMP ) { + // render light falloff * bumpmap lighting + + if ( surfaceStage->vertexColor != SVC_IGNORE ) { + common->Printf( "shader %s: vertexColor on a bump stage\n", + surfaceShader->GetName() ); + } + + // check for RGBA modulations in the stage, which are also illegal? + + // save the bump map stage for the specular calculation and diffuse + // error checking + lastBumpStage = surfaceStage; + + // + // ambient lights combine non-directional bump and falloff + // and write to the alpha channel + // + if ( lightShader->IsAmbientLight() ) { + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc ); + + // texture 0 will be the per-surface bump map + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + // development aid + if ( r_skipBump.GetBool() ) { + globalImages->flatNormalMap->Bind(); + } + + // texture 1 will be the light falloff + GL_SelectTexture( 1 ); + + qglEnable( GL_TEXTURE_GEN_S ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[3].ToFloatPtr() ); + qglTexCoord2f( 0, 0.5 ); + vLight->falloffImage->Bind(); + + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 ); + + // set the constant color to a bit of an angle + qglCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV, tr.ambientLightVector.ToFloatPtr() ); + + // stage 0 sets primary_color = bump dot constant color + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_CONSTANT_COLOR0_NV, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_PRIMARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); + + // stage 1 alpha sets primary_color = primary_color * falloff + qglCombinerInputNV( GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_A_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + qglCombinerInputNV( GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_B_NV, + GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + qglCombinerOutputNV( GL_COMBINER1_NV, GL_ALPHA, + GL_PRIMARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // final combiner takes the result for the alpha channel + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_PRIMARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + globalImages->BindNull(); + qglDisable( GL_TEXTURE_GEN_S ); + + GL_SelectTexture( 0 ); + RB_FinishStageTexture( &surfaceStage->texture, surf ); + continue; + } + + // + // draw light falloff to the alpha channel + // + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglDisableClientState( GL_COLOR_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[3].ToFloatPtr() ); + qglTexCoord2f( 0, 0.5 ); + vLight->falloffImage->Bind(); + + // make sure a combiner output doesn't step on the texture + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_ALPHA, + GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // final combiner + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_TEXTURE0_ARB, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + qglDisable( GL_TEXTURE_GEN_S ); + + // + // draw the bump map result onto the alpha channel + // + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_COLORMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will be the per-surface bump map + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + + // texture 1 is the normalization cube map + // the texccords are the non-normalized vector towards the light origin + GL_SelectTexture( 1 ); + globalImages->normalCubeMapImage->Bind(); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() ); + + qglDisableClientState( GL_COLOR_ARRAY ); + + // program the nvidia register combiners + // I just want alpha = Dot( texture0, texture1 ) + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 ); + + // stage 0 rgb performs the dot product + // SPARE0 = TEXTURE0 dot TEXTURE1 + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); + + // final combiner just takes the dot result and puts it in alpha + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); + RB_FinishStageTexture( &surfaceStage->texture, surf ); + continue; + } + + if ( surfaceStage->lighting == SL_DIFFUSE ) { + if ( !lastBumpStage ) { + common->Printf( "shader %s: diffuse stage without a preceeding bumpmap stage\n", + surfaceShader->GetName() ); + continue; + } + } + + //----------------------------------------------------- + // + // specular exponent modification of the bump / falloff + // + //----------------------------------------------------- + if ( surfaceStage->lighting == SL_SPECULAR ) { + // put specular bump map into alpha channel, then treat as a diffuse + + // allow the specular to be skipped as a user speed optimization + if ( r_skipSpecular.GetBool() ) { + continue; + } + + // ambient lights don't have specular + if ( lightShader->IsAmbientLight() ) { + continue; + } + + if ( !lastBumpStage ) { + common->Printf( "shader %s: specular stage without a preceeding bumpmap stage\n", + surfaceShader->GetName() ); + continue; + } + + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_SRC_ALPHA | GLS_COLORMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will be the per-surface bump map + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + RB_BindStageTexture( surfaceRegs, &lastBumpStage->texture, surf ); + + // development aid + if ( r_skipBump.GetBool() ) { + globalImages->flatNormalMap->Bind(); + } + + // texture 1 is the normalization cube map + // indexed by the dynamic halfangle texcoords + GL_SelectTexture( 1 ); + globalImages->normalCubeMapImage->Bind(); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + qglTexCoordPointer( 4, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) ); + + // program the nvidia register combiners + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 ); + + // stage 0 rgb performs the dot product + // GL_PRIMARY_COLOR_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2 + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_PRIMARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE ); + + // stage 0 alpha does nothing + qglCombinerOutputNV( GL_COMBINER0_NV, GL_ALPHA, + GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 1 rgb does nothing + qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, + GL_PRIMARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 1 alpha takes bump * bump + // PRIMARY_COLOR = ( GL_PRIMARY_COLOR_NV * GL_PRIMARY_COLOR_NV - 0.5 ) * 2 + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_A_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + qglCombinerInputNV( GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + qglCombinerOutputNV( GL_COMBINER1_NV, GL_ALPHA, + GL_PRIMARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE ); + + // final combiner + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_PRIMARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_PRIMARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + + // draw it + RB_DrawElementsWithCounters( tri ); + + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); + + RB_FinishStageTexture( &lastBumpStage->texture, surf ); + + // the bump map in the alpha channel is now corrupted, so a normal diffuse + // map can't be drawn unless a new bumpmap is put down + lastBumpStage = NULL; + + // fall through to the common handling of diffuse and specular projected lighting + } + + //----------------------------------------------------- + // + // projected light / surface color for diffuse and specular maps + // + //----------------------------------------------------- + if ( surfaceStage->lighting == SL_DIFFUSE || surfaceStage->lighting == SL_SPECULAR ) { + // don't trash alpha + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_ALPHAMASK | GLS_DEPTHMASK + | backEnd.depthFunc ); + + // texture 0 will get the surface color texture + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf ); + + // development aid + if ( ( surfaceStage->lighting == SL_DIFFUSE && r_skipDiffuse.GetBool() ) + || ( surfaceStage->lighting == SL_SPECULAR && r_skipSpecular.GetBool() ) ) { + globalImages->blackImage->Bind(); + } + + // texture 1 will get the light projected texture + GL_SelectTexture( 1 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_Q ); + qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[0].ToFloatPtr() ); + qglTexGenfv( GL_T, GL_OBJECT_PLANE, lightProject[1].ToFloatPtr() ); + qglTexGenfv( GL_Q, GL_OBJECT_PLANE, lightProject[2].ToFloatPtr() ); + + // texture0 * texture1 * primaryColor * constantColor + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 ); + + // SPARE0 = TEXTURE0 * PRIMARY_COLOR + // SPARE1 = TEXTURE1 * CONSTANT_COLOR + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + // variable B will be overriden based on the stage vertexColor option + if ( surfaceStage->vertexColor == SVC_MODULATE ) { + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglEnableClientState( GL_COLOR_ARRAY ); + } else if ( surfaceStage->vertexColor == SVC_INVERSE_MODULATE ) { + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB ); + qglEnableClientState( GL_COLOR_ARRAY ); + } else { // SVC_IGNORE + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB ); + qglDisableClientState( GL_COLOR_ARRAY ); + } + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, + GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, + GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // final combiner + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE1_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + + // for all light stages, multiply the projected color by the surface + // color, and blend with the framebuffer + for ( int j = 0 ; j < lightShader->GetNumStages() ; j++ ) { + const shaderStage_t *lightStage = lightShader->GetStage( j ); + float color[4]; + + // ignore stages that fail the condition + if ( !lightRegs[ lightStage->conditionRegister ] ) { + continue; + } + + // set the color to the light color times the surface color + color[0] = backEnd.lightScale + * lightRegs[ lightStage->color.registers[0] ] + * surfaceRegs[ surfaceStage->color.registers[0] ]; + color[1] = backEnd.lightScale + * lightRegs[ lightStage->color.registers[1] ] + * surfaceRegs[ surfaceStage->color.registers[1] ]; + color[2] = backEnd.lightScale + * lightRegs[ lightStage->color.registers[2] ] + * surfaceRegs[ surfaceStage->color.registers[2] ]; + color[3] = 1; + + // don't draw if it would be all black + if ( color[0] == 0 && color[1] == 0 && color[2] == 0 ) { + continue; + } + + qglCombinerParameterfvNV( GL_CONSTANT_COLOR1_NV, color ); + + RB_BindStageTexture( lightRegs, &lightStage->texture, surf ); + + RB_DrawElementsWithCounters( tri ); + + RB_FinishStageTexture( &lightStage->texture, surf ); + } + + if ( surfaceStage->vertexColor != SVC_IGNORE ) { + qglDisableClientState( GL_COLOR_ARRAY ); + } + + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_Q ); + + globalImages->BindNull(); + GL_SelectTexture( 0 ); + RB_FinishStageTexture( &surfaceStage->texture, surf ); + + continue; + } + + } + // unhack depth range if needed + if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) { + RB_LeaveDepthHack(); + } +} + +/* +================== +RB_RenderInteractionList +================== +*/ +static void RB_RenderInteractionList( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + + qglEnable( GL_REGISTER_COMBINERS_NV ); + + // force a space calculation for light vectors + backEnd.currentSpace = NULL; + + for ( const drawSurf_t *s = surf ; s ; s = s->nextOnLight ) { + RB_RenderInteraction( s ); + } + + qglDisable( GL_REGISTER_COMBINERS_NV ); +} + + + +/* +================== +RB_RenderViewLight + +================== +*/ +static void RB_RenderViewLight( viewLight_t *vLight ) { + backEnd.vLight = vLight; + + // do fogging later + if ( vLight->lightShader->IsFogLight() ) { + return; + } + if ( vLight->lightShader->IsBlendLight() ) { + return; + } + + RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight ); + + // clear the stencil buffer if needed + if ( vLight->globalShadows || vLight->localShadows ) { + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + } else { + // no shadows, so no need to read or write the stencil buffer + // we might in theory want to use GL_ALWAYS instead of disabling + // completely, to satisfy the invarience rules + qglStencilFunc( GL_ALWAYS, 128, 255 ); + } + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + RB_StencilShadowPass( vLight->globalShadows ); + RB_RenderInteractionList( vLight->localInteractions ); + RB_StencilShadowPass( vLight->localShadows ); + RB_RenderInteractionList( vLight->globalInteractions ); + + if ( r_skipTranslucent.GetBool() ) { + return; + } + + // disable stencil testing for translucent interactions, because + // the shadow isn't calculated at their point, and the shadow + // behind them may be depth fighting with a back side, so there + // isn't any reasonable thing to do + qglStencilFunc( GL_ALWAYS, 128, 255 ); + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_RenderInteractionList( vLight->translucentInteractions ); +} + + +/* +================== +RB_NV10_DrawInteractions +================== +*/ +void RB_NV10_DrawInteractions( void ) { + qglEnable( GL_STENCIL_TEST ); + + for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + RB_RenderViewLight( vLight ); + } +} + + +/* +================== +R_NV10_Init + +================== +*/ +void R_NV10_Init( void ) { + glConfig.allowNV10Path = false; + + if ( !glConfig.registerCombinersAvailable ) { + return; + } + + glConfig.allowNV10Path = true; +} diff --git a/renderer/draw_nv20.cpp b/renderer/draw_nv20.cpp new file mode 100644 index 000000000..cbca0e2a4 --- /dev/null +++ b/renderer/draw_nv20.cpp @@ -0,0 +1,876 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +typedef enum { + FPROG_BUMP_AND_LIGHT, + FPROG_DIFFUSE_COLOR, + FPROG_SPECULAR_COLOR, + FPROG_DIFFUSE_AND_SPECULAR_COLOR, + + FPROG_NUM_FRAGMENT_PROGRAMS +} fragmentProgram_t; + +GLuint fragmentDisplayListBase; // FPROG_NUM_FRAGMENT_PROGRAMS lists + +void RB_NV20_DependentSpecularPass( const drawInteraction_t *din ); +void RB_NV20_DependentAmbientPass( void ); + +/* +========================================================================================= + +GENERAL INTERACTION RENDERING + +========================================================================================= +*/ + +/* +==================== +GL_SelectTextureNoClient +==================== +*/ +void GL_SelectTextureNoClient( int unit ) { + backEnd.glState.currenttmu = unit; + qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); + RB_LogComment( "glActiveTextureARB( %i )\n", unit ); +} + +/* +================== +RB_NV20_BumpAndLightFragment +================== +*/ +static void RB_NV20_BumpAndLightFragment( void ) { + if ( r_useCombinerDisplayLists.GetBool() ) { + qglCallList( fragmentDisplayListBase + FPROG_BUMP_AND_LIGHT ); + return; + } + + // program the nvidia register combiners + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 ); + + // stage 0 rgb performs the dot product + // SPARE0 = TEXTURE0 dot TEXTURE1 + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); + + + // stage 1 rgb multiplies texture 2 and 3 together + // SPARE1 = TEXTURE2 * TEXTURE3 + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, + GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 1 alpha does nohing + + // stage 2 color multiplies spare0 * spare 1 just for debugging + // SPARE0 = SPARE0 * SPARE1 + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 2 alpha multiples spare0 * spare 1 + // SPARE0 = SPARE0 * SPARE1 + qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_B_NV, + GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE ); + qglCombinerOutputNV( GL_COMBINER2_NV, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // final combiner + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); +} + +/* +================== +RB_NV20_DI_BumpAndLightPass + +We are going to write alpha as light falloff * ( bump dot light ) * lightProjection +If the light isn't a monoLightShader, the lightProjection will be skipped, because +it will have to be done on an itterated basis +================== +*/ +static void RB_NV20_DI_BumpAndLightPass( const drawInteraction_t *din, bool monoLightShader ) { + RB_LogComment( "---------- RB_NV_BumpAndLightPass ----------\n" ); + + GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc ); + + // texture 0 is the normalization cube map + // GL_TEXTURE0_ARB will be the normalized vector + // towards the light source +#ifdef MACOS_X + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 0 ); +#endif + if ( din->ambientLight ) { + globalImages->ambientNormalMap->Bind(); + } else { + globalImages->normalCubeMapImage->Bind(); + } + + // texture 1 will be the per-surface bump map +#ifdef MACOS_X + GL_SelectTexture( 1 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 1 ); +#endif + din->bumpImage->Bind(); + + // texture 2 will be the light falloff texture +#ifdef MACOS_X + GL_SelectTexture( 2 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 2 ); +#endif + din->lightFalloffImage->Bind(); + + // texture 3 will be the light projection texture +#ifdef MACOS_X + GL_SelectTexture( 3 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 3 ); +#endif + if ( monoLightShader ) { + din->lightImage->Bind(); + } else { + // if the projected texture is multi-colored, we + // will need to do it in subsequent passes + globalImages->whiteImage->Bind(); + } + + // bind our "fragment program" + RB_NV20_BumpAndLightFragment(); + + // draw it + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT ); + RB_DrawElementsWithCounters( din->surf->geo ); +} + + +/* +================== +RB_NV20_DiffuseColorFragment +================== +*/ +static void RB_NV20_DiffuseColorFragment( void ) { + if ( r_useCombinerDisplayLists.GetBool() ) { + qglCallList( fragmentDisplayListBase + FPROG_DIFFUSE_COLOR ); + return; + } + + // program the nvidia register combiners + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 ); + + // stage 0 is free, so we always do the multiply of the vertex color + // when the vertex color is inverted, qglCombinerInputNV(GL_VARIABLE_B_NV) will be changed + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_TEXTURE0_ARB, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + qglCombinerOutputNV( GL_COMBINER0_NV, GL_ALPHA, + GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + + // for GL_CONSTANT_COLOR0_NV * TEXTURE0 * TEXTURE1 + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_E_TIMES_F_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE0_ARB, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_TEXTURE1_ARB, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); + +} + +/* +================== +RB_NV20_DI_DiffuseColorPass + +================== +*/ +static void RB_NV20_DI_DiffuseColorPass( const drawInteraction_t *din ) { + RB_LogComment( "---------- RB_NV20_DiffuseColorPass ----------\n" ); + + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_ALPHAMASK + | backEnd.depthFunc ); + + // texture 0 will be the per-surface diffuse map +#ifdef MACOS_X + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 0 ); +#endif + din->diffuseImage->Bind(); + + // texture 1 will be the light projected texture +#ifdef MACOS_X + GL_SelectTexture( 1 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 1 ); +#endif + din->lightImage->Bind(); + + // texture 2 is disabled +#ifdef MACOS_X + GL_SelectTexture( 2 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 2 ); +#endif + globalImages->BindNull(); + + // texture 3 is disabled +#ifdef MACOS_X + GL_SelectTexture( 3 ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 3 ); +#endif + globalImages->BindNull(); + + // bind our "fragment program" + RB_NV20_DiffuseColorFragment(); + + // override one parameter for inverted vertex color + if ( din->vertexColor == SVC_INVERSE_MODULATE ) { + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB ); + } + + // draw it + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR ); + RB_DrawElementsWithCounters( din->surf->geo ); +} + + +/* +================== +RB_NV20_SpecularColorFragment +================== +*/ +static void RB_NV20_SpecularColorFragment( void ) { + if ( r_useCombinerDisplayLists.GetBool() ) { + qglCallList( fragmentDisplayListBase + FPROG_SPECULAR_COLOR ); + return; + } + + // program the nvidia register combiners + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 4 ); + + // we want GL_CONSTANT_COLOR1_NV * PRIMARY_COLOR * TEXTURE2 * TEXTURE3 * specular( TEXTURE0 * TEXTURE1 ) + + // stage 0 rgb performs the dot product + // GL_SPARE0_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2 + // TEXTURE2 = TEXTURE2 * PRIMARY_COLOR + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE ); + + // stage 0 alpha does nothing + + // stage 1 color takes bump * bump + // GL_SPARE0_NV = ( GL_SPARE0_NV * GL_SPARE0_NV - 0.5 ) * 2 + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 1 alpha does nothing + + // stage 2 color + // GL_SPARE0_NV = GL_SPARE0_NV * TEXTURE3 + // SECONDARY_COLOR = CONSTANT_COLOR * TEXTURE2 + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV, + GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV, + GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB, + GL_SPARE0_NV, GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 2 alpha does nothing + + + // stage 3 scales the texture by the vertex color + qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER3_NV, GL_RGB, + GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 3 alpha does nothing + + // final combiner = GL_SPARE0_NV * SECONDARY_COLOR + PRIMARY_COLOR * SECONDARY_COLOR + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_SECONDARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); +} + + +/* +================== +RB_NV20_DI_SpecularColorPass + +================== +*/ +static void RB_NV20_DI_SpecularColorPass( const drawInteraction_t *din ) { + RB_LogComment( "---------- RB_NV20_SpecularColorPass ----------\n" ); + + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_ALPHAMASK + | backEnd.depthFunc ); + + // texture 0 is the normalization cube map for the half angle +#ifdef MACOS_X + GL_SelectTexture( 0 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 0 ); +#endif + globalImages->normalCubeMapImage->Bind(); + + // texture 1 will be the per-surface bump map +#ifdef MACOS_X + GL_SelectTexture( 1 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 1 ); +#endif + din->bumpImage->Bind(); + + // texture 2 will be the per-surface specular map +#ifdef MACOS_X + GL_SelectTexture( 2 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 2 ); +#endif + din->specularImage->Bind(); + + // texture 3 will be the light projected texture +#ifdef MACOS_X + GL_SelectTexture( 3 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 3 ); +#endif + din->lightImage->Bind(); + + // bind our "fragment program" + RB_NV20_SpecularColorFragment(); + + // override one parameter for inverted vertex color + if ( din->vertexColor == SVC_INVERSE_MODULATE ) { + qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB ); + } + + // draw it + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR ); + RB_DrawElementsWithCounters( din->surf->geo ); +} + + + +/* +================== +RB_NV20_DiffuseAndSpecularColorFragment +================== +*/ +static void RB_NV20_DiffuseAndSpecularColorFragment( void ) { + if ( r_useCombinerDisplayLists.GetBool() ) { + qglCallList( fragmentDisplayListBase + FPROG_DIFFUSE_AND_SPECULAR_COLOR ); + return; + } + + // program the nvidia register combiners + qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 ); + + // GL_CONSTANT_COLOR0_NV will be the diffuse color + // GL_CONSTANT_COLOR1_NV will be the specular color + + // stage 0 rgb performs the dot product + // GL_SECONDARY_COLOR_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2 + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, + GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE ); + + // stage 0 alpha does nothing + + // stage 1 color takes bump * bump + // PRIMARY_COLOR = ( GL_SECONDARY_COLOR_NV * GL_SECONDARY_COLOR_NV - 0.5 ) * 2 + // the scale and bias steepen the specular curve + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, + GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 1 alpha does nothing + + // stage 2 color + // PRIMARY_COLOR = ( PRIMARY_COLOR * TEXTURE3 ) * 2 + // SPARE0 = 1.0 * 1.0 (needed for final combiner) + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV, + GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV, + GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB ); + qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB ); + qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB, + GL_SECONDARY_COLOR_NV, GL_SPARE0_NV, GL_DISCARD_NV, + GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); + + // stage 2 alpha does nothing + + // final combiner = TEXTURE2_ARB * CONSTANT_COLOR0_NV + PRIMARY_COLOR_NV * CONSTANT_COLOR1_NV + // alpha = GL_ZERO + qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR1_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE2_ARB, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB ); + qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA ); +} + + +/* +================== +RB_NV20_DI_DiffuseAndSpecularColorPass + +================== +*/ +static void RB_NV20_DI_DiffuseAndSpecularColorPass( const drawInteraction_t *din ) { + RB_LogComment( "---------- RB_NV20_DI_DiffuseAndSpecularColorPass ----------\n" ); + + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); + + // texture 0 is the normalization cube map for the half angle +// still bound from RB_NV_BumpAndLightPass +// GL_SelectTextureNoClient( 0 ); +// GL_Bind( tr.normalCubeMapImage ); + + // texture 1 is the per-surface bump map +// still bound from RB_NV_BumpAndLightPass +// GL_SelectTextureNoClient( 1 ); +// GL_Bind( din->bumpImage ); + + // texture 2 is the per-surface diffuse map +#ifdef MACOS_X + GL_SelectTexture( 2 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 2 ); +#endif + din->diffuseImage->Bind(); + + // texture 3 is the per-surface specular map +#ifdef MACOS_X + GL_SelectTexture( 3 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 3 ); +#endif + din->specularImage->Bind(); + + // bind our "fragment program" + RB_NV20_DiffuseAndSpecularColorFragment(); + + // draw it + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR ); + RB_DrawElementsWithCounters( din->surf->geo ); +} + + +/* +================== +RB_NV20_DrawInteraction +================== +*/ +static void RB_NV20_DrawInteraction( const drawInteraction_t *din ) { + const drawSurf_t *surf = din->surf; + + // load all the vertex program parameters + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() ); + + // set the constant colors + qglCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV, din->diffuseColor.ToFloatPtr() ); + qglCombinerParameterfvNV( GL_CONSTANT_COLOR1_NV, din->specularColor.ToFloatPtr() ); + + // vertex color passes should be pretty rare (cross-faded bump map surfaces), so always + // run them down as three-passes + if ( din->vertexColor != SVC_IGNORE ) { + qglEnableClientState( GL_COLOR_ARRAY ); + RB_NV20_DI_BumpAndLightPass( din, false ); + RB_NV20_DI_DiffuseColorPass( din ); + RB_NV20_DI_SpecularColorPass( din ); + qglDisableClientState( GL_COLOR_ARRAY ); + return; + } + + qglColor3f( 1, 1, 1 ); + + // on an ideal card, we would now just bind the textures and call a + // single pass vertex / fragment program, but + // on NV20, we need to decide which single / dual / tripple pass set of programs to use + + // ambient light could be done as a single pass if we want to optimize for it + + // monochrome light is two passes + int internalFormat = din->lightImage->internalFormat; + if ( ( r_useNV20MonoLights.GetInteger() == 2 ) || + ( din->lightImage->isMonochrome && r_useNV20MonoLights.GetInteger() ) ) { + // do a two-pass rendering + RB_NV20_DI_BumpAndLightPass( din, true ); + RB_NV20_DI_DiffuseAndSpecularColorPass( din ); + } else { + // general case is three passes + // ( bump dot lightDir ) * lightFalloff + // diffuse * lightProject + // specular * ( bump dot halfAngle extended ) * lightProject + RB_NV20_DI_BumpAndLightPass( din, false ); + RB_NV20_DI_DiffuseColorPass( din ); + RB_NV20_DI_SpecularColorPass( din ); + } +} + + +/* +============= +RB_NV20_CreateDrawInteractions + +============= +*/ +static void RB_NV20_CreateDrawInteractions( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglEnable( GL_REGISTER_COMBINERS_NV ); + +#ifdef MACOS_X + GL_SelectTexture(0); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + qglEnableVertexAttribArrayARB( 8 ); + qglEnableVertexAttribArrayARB( 9 ); + qglEnableVertexAttribArrayARB( 10 ); + qglEnableVertexAttribArrayARB( 11 ); +#endif + + for ( ; surf ; surf=surf->nextOnLight ) { + // set the vertex pointers + idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color ); +#ifdef MACOS_X + GL_SelectTexture( 0 ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + GL_SelectTexture( 1 ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + GL_SelectTexture( 2 ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + GL_SelectTexture( 3 ); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + GL_SelectTexture( 0 ); +#else + qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); + qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); + qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); + qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); +#endif + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + + RB_CreateSingleDrawInteractions( surf, RB_NV20_DrawInteraction ); + } + +#ifndef MACOS_X + qglDisableVertexAttribArrayARB( 8 ); + qglDisableVertexAttribArrayARB( 9 ); + qglDisableVertexAttribArrayARB( 10 ); + qglDisableVertexAttribArrayARB( 11 ); +#endif + + // disable features +#ifdef MACOS_X + GL_SelectTexture( 3 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 2 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 1 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); +#else + GL_SelectTextureNoClient( 3 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 2 ); + globalImages->BindNull(); + + GL_SelectTextureNoClient( 1 ); + globalImages->BindNull(); +#endif + + backEnd.glState.currenttmu = -1; + GL_SelectTexture( 0 ); + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + qglDisable( GL_VERTEX_PROGRAM_ARB ); + qglDisable( GL_REGISTER_COMBINERS_NV ); +} + + +//====================================================================================== + + +/* +================== +RB_NV20_DrawInteractions +================== +*/ +void RB_NV20_DrawInteractions( void ) { + viewLight_t *vLight; + + // + // for each light, perform adding and shadowing + // + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + // do fogging later + if ( vLight->lightShader->IsFogLight() ) { + continue; + } + if ( vLight->lightShader->IsBlendLight() ) { + continue; + } + if ( !vLight->localInteractions && !vLight->globalInteractions + && !vLight->translucentInteractions ) { + continue; + } + + backEnd.vLight = vLight; + + RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight ); + + // clear the stencil buffer if needed + if ( vLight->globalShadows || vLight->localShadows ) { + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + } else { + // no shadows, so no need to read or write the stencil buffer + // we might in theory want to use GL_ALWAYS instead of disabling + // completely, to satisfy the invarience rules + qglStencilFunc( GL_ALWAYS, 128, 255 ); + } + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + + if ( r_useShadowVertexProgram.GetBool() ) { + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->globalShadows ); + RB_NV20_CreateDrawInteractions( vLight->localInteractions ); + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->localShadows ); + RB_NV20_CreateDrawInteractions( vLight->globalInteractions ); + qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on + } else { + RB_StencilShadowPass( vLight->globalShadows ); + RB_NV20_CreateDrawInteractions( vLight->localInteractions ); + RB_StencilShadowPass( vLight->localShadows ); + RB_NV20_CreateDrawInteractions( vLight->globalInteractions ); + } + + // translucent surfaces never get stencil shadowed + if ( r_skipTranslucent.GetBool() ) { + continue; + } + + qglStencilFunc( GL_ALWAYS, 128, 255 ); + + backEnd.depthFunc = GLS_DEPTHFUNC_LESS; + RB_NV20_CreateDrawInteractions( vLight->translucentInteractions ); + + backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL; + } +} + +//======================================================================= + +/* +================== +R_NV20_Init + +================== +*/ +void R_NV20_Init( void ) { + glConfig.allowNV20Path = false; + + common->Printf( "---------- R_NV20_Init ----------\n" ); + + if ( !glConfig.registerCombinersAvailable || !glConfig.ARBVertexProgramAvailable || glConfig.maxTextureUnits < 4 ) { + common->Printf( "Not available.\n" ); + return; + } + + GL_CheckErrors(); + + // create our "fragment program" display lists + fragmentDisplayListBase = qglGenLists( FPROG_NUM_FRAGMENT_PROGRAMS ); + + // force them to issue commands to build the list + bool temp = r_useCombinerDisplayLists.GetBool(); + r_useCombinerDisplayLists.SetBool( false ); + + qglNewList( fragmentDisplayListBase + FPROG_BUMP_AND_LIGHT, GL_COMPILE ); + RB_NV20_BumpAndLightFragment(); + qglEndList(); + + qglNewList( fragmentDisplayListBase + FPROG_DIFFUSE_COLOR, GL_COMPILE ); + RB_NV20_DiffuseColorFragment(); + qglEndList(); + + qglNewList( fragmentDisplayListBase + FPROG_SPECULAR_COLOR, GL_COMPILE ); + RB_NV20_SpecularColorFragment(); + qglEndList(); + + qglNewList( fragmentDisplayListBase + FPROG_DIFFUSE_AND_SPECULAR_COLOR, GL_COMPILE ); + RB_NV20_DiffuseAndSpecularColorFragment(); + qglEndList(); + + r_useCombinerDisplayLists.SetBool( temp ); + + common->Printf( "---------------------------------\n" ); + + glConfig.allowNV20Path = true; +} + diff --git a/renderer/draw_r200.cpp b/renderer/draw_r200.cpp new file mode 100644 index 000000000..a73bc28be --- /dev/null +++ b/renderer/draw_r200.cpp @@ -0,0 +1,507 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + + There are not enough vertex program texture coordinate outputs + to have unique texture coordinates for bump, specular, and diffuse, + so diffuse and specular are assumed to be the same mapping. + + To handle properly, those cases with different diffuse and specular + mapping will need to be run as two passes. + +*/ + +// changed from 1 to 255 to not conflict with ARB2 program names +static int FPROG_FAST_PATH = 255; + +typedef struct { + GLint numFragmentRegisters; // 6 + GLint numFragmentConstants; // 8 + GLint numPasses; // 2 + GLint numInstructionsPerPass; // 8 + GLint numInstructionsTotal; // 16 + GLint colorAlphaPairing; // 1 + GLint numLoopbackComponenets; // 3 + GLint numInputInterpolatorComponents; // 3 +} atiFragmentShaderInfo_t; + +static atiFragmentShaderInfo_t fsi; + +typedef struct { + // vertex shader invariants + int lightPos; // light position in object coordinates + int viewerPos; // viewer position in object coordinates + int lightProjectS; // projected light s texgen + int lightProjectT; // projected light t texgen + int lightProjectQ; // projected light q texgen + int lightFalloffS; // projected light falloff s texgen + int bumpTransformS; // bump TEX0 S transformation + int bumpTransformT; // bump TEX0 T transformation + int colorTransformS; // diffuse/specular texture matrix + int colorTransformT; // diffuse/specular texture matrix + + // vertex shader variants + int texCoords; + int vertexColors; + int normals; + int tangents; + int biTangents; + +} atiVertexShaderInfo_t; + +static atiVertexShaderInfo_t vsi; + +/* +=================== +RB_R200_ARB_DrawInteraction + +=================== +*/ +static void RB_R200_ARB_DrawInteraction( const drawInteraction_t *din ) { + // check for the case we can't handle in a single pass (we could calculate this at shader parse time to optimize) + if ( din->diffuseImage != globalImages->blackImage && din->specularImage != globalImages->blackImage + && memcmp( din->specularMatrix, din->diffuseMatrix, sizeof( din->diffuseMatrix ) ) ) { +// common->Printf( "Note: Shader %s drawn as two pass on R200\n", din->surf->shader->getName() ); + + // draw the specular as a separate pass with a black diffuse map + drawInteraction_t d; + d = *din; + d.diffuseImage = globalImages->blackImage; + memcpy( d.diffuseMatrix, d.specularMatrix, sizeof( d.diffuseMatrix ) ); + RB_R200_ARB_DrawInteraction( &d ); + + // now fall through and draw the diffuse pass with a black specular map + d = *din; + din = &d; + d.specularImage = globalImages->blackImage; + } + + // load all the vertex program parameters + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() ); + + const srfTriangles_t *tri = din->surf->geo; + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->xyz ); + + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + static const float negOne[4] = { -1, -1, -1, -1 }; + + switch ( din->vertexColor ) { + case SVC_IGNORE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + case SVC_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero ); + break; + case SVC_INVERSE_MODULATE: + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne ); + qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one ); + break; + } + + + // texture 0 = light projection + // texture 1 = light falloff + // texture 2 = surface diffuse + // texture 3 = surface specular + // texture 4 = surface bump + // texture 5 = normalization cube map + + GL_SelectTexture( 5 ); + if ( din->ambientLight ) { + globalImages->ambientNormalMap->Bind(); + } else { + globalImages->normalCubeMapImage->Bind(); + } + + GL_SelectTexture( 4 ); + din->bumpImage->Bind(); + + GL_SelectTexture( 3 ); + din->specularImage->Bind(); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->normal ); + + GL_SelectTexture( 2 ); + din->diffuseImage->Bind(); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->tangents[1][0] ); + + GL_SelectTexture( 1 ); + din->lightFalloffImage->Bind(); + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->tangents[0][0] ); + + GL_SelectTexture( 0 ); + din->lightImage->Bind(); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st[0] ); + + qglSetFragmentShaderConstantATI( GL_CON_0_ATI, din->diffuseColor.ToFloatPtr() ); + qglSetFragmentShaderConstantATI( GL_CON_1_ATI, din->specularColor.ToFloatPtr() ); + + if ( din->vertexColor != SVC_IGNORE ) { + qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(idDrawVert), (void *)&ac->color ); + qglEnableClientState( GL_COLOR_ARRAY ); + + RB_DrawElementsWithCounters( tri ); + + qglDisableClientState( GL_COLOR_ARRAY ); + qglColor4f( 1, 1, 1, 1 ); + } else { + RB_DrawElementsWithCounters( tri ); + } +} + +/* +================== +RB_R200_ARB_CreateDrawInteractions +================== +*/ +static void RB_R200_ARB_CreateDrawInteractions( const drawSurf_t *surf ) { + if ( !surf ) { + return; + } + + // force a space calculation for light vectors + backEnd.currentSpace = NULL; + + // set the depth test + if ( surf->material->Coverage() == MC_TRANSLUCENT /* != C_PERFORATED */ ) { + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS ); + } else { + // only draw on the alpha tested pixels that made it to the depth buffer + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL ); + } + + // start the vertex shader + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION ); + qglEnable(GL_VERTEX_PROGRAM_ARB); + + // start the fragment shader + qglBindFragmentShaderATI( FPROG_FAST_PATH ); +#if defined( MACOS_X ) + qglEnable( GL_TEXT_FRAGMENT_SHADER_ATI ); +#else + qglEnable( GL_FRAGMENT_SHADER_ATI ); +#endif + + qglColor4f( 1, 1, 1, 1 ); + + GL_SelectTexture( 1 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + GL_SelectTexture( 2 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + GL_SelectTexture( 3 ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + for ( ; surf ; surf=surf->nextOnLight ) { + RB_CreateSingleDrawInteractions( surf, RB_R200_ARB_DrawInteraction ); + } + + GL_SelectTexture( 5 ); + globalImages->BindNull(); + + GL_SelectTexture( 4 ); + globalImages->BindNull(); + + GL_SelectTexture( 3 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 2 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 1 ); + globalImages->BindNull(); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + GL_SelectTexture( 0 ); + + qglDisable( GL_VERTEX_PROGRAM_ARB ); +#if defined( MACOS_X ) + qglDisable( GL_TEXT_FRAGMENT_SHADER_ATI ); +#else + qglDisable( GL_FRAGMENT_SHADER_ATI ); +#endif +} + + + +/* +================== +RB_R200_DrawInteractions + +================== +*/ +void RB_R200_DrawInteractions( void ) { + qglEnable( GL_STENCIL_TEST ); + + for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + // do fogging later + if ( vLight->lightShader->IsFogLight() ) { + continue; + } + if ( vLight->lightShader->IsBlendLight() ) { + continue; + } + + backEnd.vLight = vLight; + + RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight ); + + // clear the stencil buffer if needed + if ( vLight->globalShadows || vLight->localShadows ) { + backEnd.currentScissor = vLight->scissorRect; + if ( r_useScissor.GetBool() ) { + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + qglClear( GL_STENCIL_BUFFER_BIT ); + } else { + // no shadows, so no need to read or write the stencil buffer + // we might in theory want to use GL_ALWAYS instead of disabling + // completely, to satisfy the invarience rules + qglStencilFunc( GL_ALWAYS, 128, 255 ); + } + + if ( r_useShadowVertexProgram.GetBool() ) { + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->globalShadows ); + + RB_R200_ARB_CreateDrawInteractions( vLight->localInteractions ); + + qglEnable( GL_VERTEX_PROGRAM_ARB ); + qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW ); + RB_StencilShadowPass( vLight->localShadows ); + + RB_R200_ARB_CreateDrawInteractions( vLight->globalInteractions ); + + qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on + } else { + RB_StencilShadowPass( vLight->globalShadows ); + RB_R200_ARB_CreateDrawInteractions( vLight->localInteractions ); + + RB_StencilShadowPass( vLight->localShadows ); + RB_R200_ARB_CreateDrawInteractions( vLight->globalInteractions ); + } + + if ( r_skipTranslucent.GetBool() ) { + continue; + } + + // disable stencil testing for translucent interactions, because + // the shadow isn't calculated at their point, and the shadow + // behind them may be depth fighting with a back side, so there + // isn't any reasonable thing to do + qglStencilFunc( GL_ALWAYS, 128, 255 ); + RB_R200_ARB_CreateDrawInteractions( vLight->translucentInteractions ); + } +} + + +/* +================= +R_BuildSurfaceFragmentProgram +================= +*/ +static void R_BuildSurfaceFragmentProgram( int programNum ) { + qglBindFragmentShaderATI( programNum ); + + qglBeginFragmentShaderATI(); + + // texture 0 = light projection + // texture 1 = light falloff + // texture 2 = surface diffuse + // texture 3 = surface specular + // texture 4 = surface bump + // texture 5 = normalization cube map + + // texcoord 0 = light projection texGen + // texcoord 1 = light falloff texGen + // texcoord 2 = bumpmap texCoords + // texcoord 3 = specular / diffuse texCoords + // texcoord 4 = halfangle vector in local tangent space + // texcoord 5 = vector to light in local tangent space + + // constant 0 = diffuse modulate + // constant 1 = specular modulate + // constant 5 = internal use for 0.75 constant + + qglSampleMapATI( GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STQ_DQ_ATI ); + qglSampleMapATI( GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI ); + qglSampleMapATI( GL_REG_4_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI ); + qglSampleMapATI( GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI ); + + // move the alpha component to the red channel to support rxgb normal map compression + if ( globalImages->image_useNormalCompression.GetInteger() == 2 ) { + qglColorFragmentOp1ATI( GL_MOV_ATI, GL_REG_4_ATI, GL_RED_BIT_ATI, GL_NONE, + GL_REG_4_ATI, GL_ALPHA, GL_NONE ); + } + + // light projection * light falloff + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_1_ATI, GL_NONE, GL_NONE ); + + // vectorToLight dot bumpMap + qglColorFragmentOp2ATI( GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, + GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI ); + + // bump * light + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_1_ATI, GL_NONE, GL_NONE ); + + //------------------- + + // carry over the incomingLight calculation + qglPassTexCoordATI( GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI ); + + // sample the diffuse surface map + qglSampleMapATI( GL_REG_2_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI ); + + // sample the specular surface map + qglSampleMapATI( GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI ); + + // we will use the surface bump map again + qglPassTexCoordATI( GL_REG_4_ATI, GL_REG_4_ATI, GL_SWIZZLE_STR_ATI ); + + // normalize the specular halfangle + qglSampleMapATI( GL_REG_5_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI ); + + // R1 = halfangle dot surfaceNormal + qglColorFragmentOp2ATI( GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, + GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI ); + + // R1 = 4 * ( R1 - 0.75 ) + // subtract 0.75 and quadruple to tighten the specular spot + float data[4] = { 0.75, 0.75, 0.75, 0.75 }; + qglSetFragmentShaderConstantATI( GL_CON_5_ATI, data ); + qglColorFragmentOp2ATI( GL_SUB_ATI, GL_REG_1_ATI, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_CON_5_ATI, GL_NONE, GL_NONE ); + + // R1 = R1 * R1 + // sqare the stretched specular result + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_REG_1_ATI, GL_NONE, GL_NONE ); + + // R1 = R1 * R3 + // R1 = specular power * specular texture * 2 + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI | GL_SATURATE_BIT_ATI, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_REG_3_ATI, GL_NONE, GL_NONE ); + + // R2 = R2 * CONST0 + // down modulate the diffuse map + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_2_ATI, GL_NONE, GL_NONE, + GL_CON_0_ATI, GL_NONE, GL_NONE ); + + // R2 = R2 + R1 * CONST1 + // diffuse + specular * specular color + qglColorFragmentOp3ATI( GL_MAD_ATI, GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_CON_1_ATI, GL_NONE, GL_NONE, + GL_REG_2_ATI, GL_NONE, GL_NONE ); + + // out = reflectance * incoming light + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_2_ATI, GL_NONE, GL_NONE ); + + // out * vertex color + qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE ); + + // out alpha = 0 to allow blending optimization + qglAlphaFragmentOp1ATI( GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, + GL_ZERO, GL_NONE, GL_NONE ); + + qglEndFragmentShaderATI(); + + GL_CheckErrors(); +} + +/* +================= +R_R200_Init +================= +*/ +void R_R200_Init( void ) { + glConfig.allowR200Path = false; + + common->Printf( "----------- R200_Init -----------\n" ); + + if ( !glConfig.atiFragmentShaderAvailable || !glConfig.ARBVertexProgramAvailable || !glConfig.ARBVertexBufferObjectAvailable ) { + common->Printf( "Not available.\n" ); + return; + } + + GL_CheckErrors(); + + qglGetIntegerv( GL_NUM_FRAGMENT_REGISTERS_ATI, &fsi.numFragmentRegisters ); + qglGetIntegerv( GL_NUM_FRAGMENT_CONSTANTS_ATI, &fsi.numFragmentConstants ); + qglGetIntegerv( GL_NUM_PASSES_ATI, &fsi.numPasses ); + qglGetIntegerv( GL_NUM_INSTRUCTIONS_PER_PASS_ATI, &fsi.numInstructionsPerPass ); + qglGetIntegerv( GL_NUM_INSTRUCTIONS_TOTAL_ATI, &fsi.numInstructionsTotal ); + qglGetIntegerv( GL_COLOR_ALPHA_PAIRING_ATI, &fsi.colorAlphaPairing ); + qglGetIntegerv( GL_NUM_LOOPBACK_COMPONENTS_ATI, &fsi.numLoopbackComponenets ); + qglGetIntegerv( GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI, &fsi.numInputInterpolatorComponents ); + + common->Printf( "GL_NUM_FRAGMENT_REGISTERS_ATI: %i\n", fsi.numFragmentRegisters ); + common->Printf( "GL_NUM_FRAGMENT_CONSTANTS_ATI: %i\n", fsi.numFragmentConstants ); + common->Printf( "GL_NUM_PASSES_ATI: %i\n", fsi.numPasses ); + common->Printf( "GL_NUM_INSTRUCTIONS_PER_PASS_ATI: %i\n", fsi.numInstructionsPerPass ); + common->Printf( "GL_NUM_INSTRUCTIONS_TOTAL_ATI: %i\n", fsi.numInstructionsTotal ); + common->Printf( "GL_COLOR_ALPHA_PAIRING_ATI: %i\n", fsi.colorAlphaPairing ); + common->Printf( "GL_NUM_LOOPBACK_COMPONENTS_ATI: %i\n", fsi.numLoopbackComponenets ); + common->Printf( "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI: %i\n", fsi.numInputInterpolatorComponents ); + + common->Printf( "FPROG_FAST_PATH\n" ); + R_BuildSurfaceFragmentProgram( FPROG_FAST_PATH ); + + common->Printf( "---------------------\n" ); + + glConfig.allowR200Path = true; +} diff --git a/renderer/glext.h b/renderer/glext.h index 15020b823..7f15730f7 100644 --- a/renderer/glext.h +++ b/renderer/glext.h @@ -1,14 +1,3 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// #ifndef __glext_h_ #define __glext_h_ @@ -5928,4 +5917,3 @@ typedef void (APIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax) #endif #endif - diff --git a/renderer/jpeg-6/jcapimin.c b/renderer/jpeg-6/jcapimin.c new file mode 100644 index 000000000..1cd9736d5 --- /dev/null +++ b/renderer/jpeg-6/jcapimin.c @@ -0,0 +1,228 @@ +/* + * jcapimin.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-compression case or the transcoding-only + * case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jcapistd.c. But also see jcparam.c for + * parameter-setup helper routines, jcomapi.c for routines shared by + * compression and decompression, and jctrans.c for the transcoding case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG compression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL void +jpeg_create_compress (j_compress_ptr cinfo) +{ + int i; + + /* For debugging purposes, zero the whole master structure. + * But error manager pointer is already there, so save and restore it. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); + cinfo->err = err; + } + cinfo->is_decompressor = FALSE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->dest = NULL; + + cinfo->comp_info = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + cinfo->input_gamma = 1.0; /* in case application forgets */ + + /* OK, I'm ready */ + cinfo->global_state = CSTATE_START; +} + + +/* + * Destruction of a JPEG compression object + */ + +GLOBAL void +jpeg_destroy_compress (j_compress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG compression operation, + * but don't destroy the object itself. + */ + +GLOBAL void +jpeg_abort_compress (j_compress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Forcibly suppress or un-suppress all quantization and Huffman tables. + * Marks all currently defined tables as already written (if suppress) + * or not written (if !suppress). This will control whether they get emitted + * by a subsequent jpeg_start_compress call. + * + * This routine is exported for use by applications that want to produce + * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + * since it is called by jpeg_start_compress, we put it here --- otherwise + * jcparam.o would be linked whether the application used it or not. + */ + +GLOBAL void +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) +{ + int i; + JQUANT_TBL * qtbl; + JHUFF_TBL * htbl; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL) + qtbl->sent_table = suppress; + } + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + } +} + + +/* + * Finish JPEG compression. + * + * If a multipass operating mode was selected, this may do a great deal of + * work including most of the actual output. + */ + +GLOBAL void +jpeg_finish_compress (j_compress_ptr cinfo) +{ + JDIMENSION iMCU_row; + + if (cinfo->global_state == CSTATE_SCANNING || + cinfo->global_state == CSTATE_RAW_OK) { + /* Terminate first pass */ + if (cinfo->next_scanline < cinfo->image_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_pass) (cinfo); + } else if (cinfo->global_state != CSTATE_WRCOEFS) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any remaining passes */ + while (! cinfo->master->is_last_pass) { + (*cinfo->master->prepare_for_pass) (cinfo); + for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) iMCU_row; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* We bypass the main controller and invoke coef controller directly; + * all work is being done from the coefficient buffer. + */ + if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + (*cinfo->master->finish_pass) (cinfo); + } + /* Write EOI, do final cleanup */ + (*cinfo->marker->write_file_trailer) (cinfo); + (*cinfo->dest->term_destination) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); +} + + +/* + * Write a special marker. + * This is only recommended for writing COM or APPn markers. + * Must be called after jpeg_start_compress() and before + * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). + */ + +GLOBAL void +jpeg_write_marker (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen) +{ + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen); +} + + +/* + * Alternate compression function: just write an abbreviated table file. + * Before calling this, all parameters and a data destination must be set up. + * + * To produce a pair of files containing abbreviated tables and abbreviated + * image data, one would proceed as follows: + * + * initialize JPEG object + * set JPEG parameters + * set destination to table file + * jpeg_write_tables(cinfo); + * set destination to image file + * jpeg_start_compress(cinfo, FALSE); + * write data... + * jpeg_finish_compress(cinfo); + * + * jpeg_write_tables has the side effect of marking all tables written + * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + * will not re-emit the tables unless it is passed write_all_tables=TRUE. + */ + +GLOBAL void +jpeg_write_tables (j_compress_ptr cinfo) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Initialize the marker writer ... bit of a crock to do it here. */ + jinit_marker_writer(cinfo); + /* Write them tables! */ + (*cinfo->marker->write_tables_only) (cinfo); + /* And clean up. */ + (*cinfo->dest->term_destination) (cinfo); + /* We can use jpeg_abort to release memory. */ + jpeg_abort((j_common_ptr) cinfo); +} diff --git a/renderer/jpeg-6/jcapistd.c b/renderer/jpeg-6/jcapistd.c new file mode 100644 index 000000000..b99e560bf --- /dev/null +++ b/renderer/jpeg-6/jcapistd.c @@ -0,0 +1,161 @@ +/* + * jcapistd.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-compression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_compress, it will end up linking in the entire compressor. + * We thus must separate this file from jcapimin.c to avoid linking the + * whole compression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Compression initialization. + * Before calling this, all parameters and a data destination must be set up. + * + * We require a write_all_tables parameter as a failsafe check when writing + * multiple datastreams from the same compression object. Since prior runs + * will have left all the tables marked sent_table=TRUE, a subsequent run + * would emit an abbreviated stream (no tables) by default. This may be what + * is wanted, but for safety's sake it should not be the default behavior: + * programmers should have to make a deliberate choice to emit abbreviated + * images. Therefore the documentation and examples should encourage people + * to pass write_all_tables=TRUE; then it will take active thought to do the + * wrong thing. + */ + +GLOBAL void +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (write_all_tables) + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + jinit_compress_master(cinfo); + /* Set up for the first pass */ + (*cinfo->master->prepare_for_pass) (cinfo); + /* Ready for application to drive first pass through jpeg_write_scanlines + * or jpeg_write_raw_data. + */ + cinfo->next_scanline = 0; + cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); +} + + +/* + * Write some scanlines of data to the JPEG compressor. + * + * The return value will be the number of lines actually written. + * This should be less than the supplied num_lines only in case that + * the data destination module has requested suspension of the compressor, + * or if more than image_height scanlines are passed in. + * + * Note: we warn about excess calls to jpeg_write_scanlines() since + * this likely signals an application programmer error. However, + * excess scanlines passed in the last valid call are *silently* ignored, + * so that the application need not adjust num_lines for end-of-image + * when using a multiple-scanline buffer. + */ + +GLOBAL JDIMENSION +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION num_lines) +{ + JDIMENSION row_ctr, rows_left; + + if (cinfo->global_state != CSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_scanlines. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_scanlines. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Ignore any extra scanlines at bottom of image. */ + rows_left = cinfo->image_height - cinfo->next_scanline; + if (num_lines > rows_left) + num_lines = rows_left; + + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); + cinfo->next_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to write raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL JDIMENSION +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION num_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != CSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_raw_data. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_raw_data. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Verify that at least one iMCU row has been passed. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Directly compress the row. */ + if (! (*cinfo->coef->compress_data) (cinfo, data)) { + /* If compressor did not consume the whole row, suspend processing. */ + return 0; + } + + /* OK, we processed one iMCU row. */ + cinfo->next_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} diff --git a/renderer/jpeg-6/jccoefct.c b/renderer/jpeg-6/jccoefct.c new file mode 100644 index 000000000..ea3169b8f --- /dev/null +++ b/renderer/jpeg-6/jccoefct.c @@ -0,0 +1,448 @@ +/* + * jccoefct.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for compression. + * This controller is the top level of the JPEG compressor proper. + * The coefficient buffer lies between forward-DCT and entropy encoding steps. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* We use a full-image coefficient buffer when doing Huffman optimization, + * and also for writing multiple-scan JPEG files. In all cases, the DCT + * step is run during the first pass, and subsequent passes need only read + * the buffered coefficients. + */ +#ifdef ENTROPY_OPT_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#else +#ifdef C_MULTISCAN_FILES_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#endif +#endif + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* For single-pass compression, it's sufficient to buffer just one MCU + * (although this may prove a bit slow in practice). We allocate a + * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + * MCU constructed and sent. (On 80x86, the workspace is FAR even though + * it's not really very big; this is to keep the module interfaces unchanged + * when a large coefficient buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays. + */ + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +/* Forward declarations */ +METHODDEF boolean compress_data + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#ifdef FULL_COEF_BUFFER_SUPPORTED +METHODDEF boolean compress_first_pass + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +METHODDEF boolean compress_output + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#endif + + +LOCAL void +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (coef->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_data; + break; +#ifdef FULL_COEF_BUFFER_SUPPORTED + case JBUF_SAVE_AND_PASS: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_first_pass; + break; + case JBUF_CRANK_DEST: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_output; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data in the single-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf contains a plane for each component in image. + * For single pass, this is the same as the components in the scan. + */ + +METHODDEF boolean +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, bi, ci, yindex, yoffset, blockcnt; + JDIMENSION ypos, xpos; + jpeg_component_info *compptr; + + /* Loop to write as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Determine where data comes from in input_buf and do the DCT thing. + * Each call on forward_DCT processes a horizontal row of DCT blocks + * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + * sequentially. Dummy blocks at the right or bottom edge are filled in + * specially. The data in them does not matter for image reconstruction, + * so we fill them with values that will encode to the smallest amount of + * data, viz: all zeroes in the AC entries, DC entries equal to previous + * block's DC value. (Thanks to Thomas Kinsman for this idea.) + */ + blkn = 0; + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + xpos = MCU_col_num * compptr->MCU_sample_width; + ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[ci], coef->MCU_buffer[blkn], + ypos, xpos, (JDIMENSION) blockcnt); + if (blockcnt < compptr->MCU_width) { + /* Create some dummy blocks at the right edge of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], + (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for (bi = blockcnt; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; + } + } + } else { + /* Create a row of dummy blocks at the bottom of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn], + compptr->MCU_width * SIZEOF(JBLOCK)); + for (bi = 0; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; + } + } + blkn += compptr->MCU_width; + ypos += DCTSIZE; + } + } + /* Try to write the MCU. In event of a suspension failure, we will + * re-DCT the MCU on restart (a bit inefficient, could be fixed...) + */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +#ifdef FULL_COEF_BUFFER_SUPPORTED + +/* + * Process some data in the first pass of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * This amount of data is read from the source buffer, DCT'd and quantized, + * and saved into the virtual arrays. We also generate suitable dummy blocks + * as needed at the right and lower edges. (The dummy blocks are constructed + * in the virtual arrays, which have been padded appropriately.) This makes + * it possible for subsequent passes not to worry about real vs. dummy blocks. + * + * We must also emit the data to the entropy encoder. This is conveniently + * done by calling compress_output() after we've loaded the current strip + * of the virtual arrays. + * + * NB: input_buf contains a plane for each component in image. All + * components are DCT'd and loaded into the virtual arrays in this pass. + * However, it may be that only a subset of the components are emitted to + * the entropy encoder during this first pass; be careful about looking + * at the scan-dependent variables (MCU dimensions, etc). + */ + +METHODDEF boolean +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION blocks_across, MCUs_across, MCUindex; + int bi, ci, h_samp_factor, block_row, block_rows, ndummy; + JCOEF lastDC; + jpeg_component_info *compptr; + JBLOCKARRAY buffer; + JBLOCKROW thisblockrow, lastblockrow; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (coef->iMCU_row_num < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + blocks_across = compptr->width_in_blocks; + h_samp_factor = compptr->h_samp_factor; + /* Count number of dummy blocks to be added at the right margin. */ + ndummy = (int) (blocks_across % h_samp_factor); + if (ndummy > 0) + ndummy = h_samp_factor - ndummy; + /* Perform DCT for all non-dummy blocks in this iMCU row. Each call + * on forward_DCT processes a complete horizontal row of DCT blocks. + */ + for (block_row = 0; block_row < block_rows; block_row++) { + thisblockrow = buffer[block_row]; + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[ci], thisblockrow, + (JDIMENSION) (block_row * DCTSIZE), + (JDIMENSION) 0, blocks_across); + if (ndummy > 0) { + /* Create dummy blocks at the right edge of the image. */ + thisblockrow += blocks_across; /* => first dummy block */ + jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); + lastDC = thisblockrow[-1][0]; + for (bi = 0; bi < ndummy; bi++) { + thisblockrow[bi][0] = lastDC; + } + } + } + /* If at end of image, create dummy block rows as needed. + * The tricky part here is that within each MCU, we want the DC values + * of the dummy blocks to match the last real block's DC value. + * This squeezes a few more bytes out of the resulting file... + */ + if (coef->iMCU_row_num == last_iMCU_row) { + blocks_across += ndummy; /* include lower right corner */ + MCUs_across = blocks_across / h_samp_factor; + for (block_row = block_rows; block_row < compptr->v_samp_factor; + block_row++) { + thisblockrow = buffer[block_row]; + lastblockrow = buffer[block_row-1]; + jzero_far((void FAR *) thisblockrow, + (size_t) (blocks_across * SIZEOF(JBLOCK))); + for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { + lastDC = lastblockrow[h_samp_factor-1][0]; + for (bi = 0; bi < h_samp_factor; bi++) { + thisblockrow[bi][0] = lastDC; + } + thisblockrow += h_samp_factor; /* advance to next MCU in row */ + lastblockrow += h_samp_factor; + } + } + } + } + /* NB: compress_output will increment iMCU_row_num if successful. + * A suspension return will result in redoing all the work above next time. + */ + + /* Emit data to the entropy encoder, sharing code with subsequent passes */ + return compress_output(cinfo, input_buf); +} + + +/* + * Process some data in subsequent passes of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF boolean +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. + * NB: during first pass, this is safe only because the buffers will + * already be aligned properly, so jmemmgr.c won't need to do any I/O. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + +#endif /* FULL_COEF_BUFFER_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL void +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef FULL_COEF_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + int ci; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->whole_image[0] = NULL; /* flag for no virtual arrays */ + } +} diff --git a/renderer/jpeg-6/jccolor.c b/renderer/jpeg-6/jccolor.c new file mode 100644 index 000000000..670791182 --- /dev/null +++ b/renderer/jpeg-6/jccolor.c @@ -0,0 +1,459 @@ +/* + * jccolor.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_converter pub; /* public fields */ + + /* Private state for RGB->YCC conversion */ + INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ +} my_color_converter; + +typedef my_color_converter * my_cconvert_ptr; + + +/**************** RGB -> YCbCr conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + * were not represented exactly. Now we sacrifice exact representation of + * maximum red and maximum blue in order to get exact grayscales. + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times R,G,B for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + * in the tables to save adding them separately in the inner loop. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS) +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L< Y section */ +#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ +#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ +#define R_CB_OFF (3*(MAXJSAMPLE+1)) +#define G_CB_OFF (4*(MAXJSAMPLE+1)) +#define B_CB_OFF (5*(MAXJSAMPLE+1)) +#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ +#define G_CR_OFF (6*(MAXJSAMPLE+1)) +#define B_CR_OFF (7*(MAXJSAMPLE+1)) +#define TABLE_SIZE (8*(MAXJSAMPLE+1)) + + +/* + * Initialize for RGB->YCC colorspace conversion. + */ + +METHODDEF void +rgb_ycc_start (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + INT32 * rgb_ycc_tab; + INT32 i; + + /* Allocate and fill in the conversion tables. */ + cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))); + + for (i = 0; i <= MAXJSAMPLE; i++) { + rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; + rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; + rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; + rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; + /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + * This ensures that the maximum output will round to MAXJSAMPLE + * not MAXJSAMPLE+1, and thus that we don't have to range-limit. + */ + rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +/* B=>Cb and R=>Cr tables are the same + rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +*/ + rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; + rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * + * Note that we change from the application's interleaved-pixel format + * to our internal noninterleaved, one-plane-per-component format. + * The input buffer is therefore three times as wide as the output buffer. + * + * A starting row offset is provided only for the output buffer. The caller + * can easily adjust the passed input_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF void +rgb_ycc_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/**************** Cases other than RGB -> YCbCr **************/ + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles RGB->grayscale conversion, which is the same + * as the RGB->Y portion of RGB->YCbCr. + * We assume rgb_ycc_start has been called (we only use the Y tables). + */ + +METHODDEF void +rgb_gray_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* Y */ + outptr[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles Adobe-style CMYK->YCCK conversion, + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + * conversion as above, while passing K (black) unchanged. + * We assume rgb_ycc_start has been called. + */ + +METHODDEF void +cmyk_ycck_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2, outptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + outptr3 = output_buf[3][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); + g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); + b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); + /* K passes through as-is */ + outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ + inptr += 4; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles grayscale output with no conversion. + * The source can be either plain grayscale or YCbCr (since Y == gray). + */ + +METHODDEF void +grayscale_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + int instride = cinfo->input_components; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ + inptr += instride; + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles multi-component colorspaces without conversion. + * We assume input_components == num_components. + */ + +METHODDEF void +null_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + register int ci; + int nc = cinfo->num_components; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + /* It seems fastest to make a separate pass for each component. */ + for (ci = 0; ci < nc; ci++) { + inptr = *input_buf; + outptr = output_buf[ci][output_row]; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ + inptr += nc; + } + } + input_buf++; + output_row++; + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF void +null_method (j_compress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for input colorspace conversion. + */ + +GLOBAL void +jinit_color_converter (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_converter)); + cinfo->cconvert = (struct jpeg_color_converter *) cconvert; + /* set start_pass to null method until we find out differently */ + cconvert->pub.start_pass = null_method; + + /* Make sure input_components agrees with in_color_space */ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + if (cinfo->input_components != 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + if (cinfo->input_components != RGB_PIXELSIZE) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; +#endif /* else share code with YCbCr */ + + case JCS_YCbCr: + if (cinfo->input_components != 3) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->input_components != 4) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->input_components < 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + } + + /* Check num_components, set conversion method based on requested space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_GRAYSCALE) + cconvert->pub.color_convert = grayscale_convert; + else if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_gray_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = grayscale_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_ycc_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = cmyk_ycck_convert; + } else if (cinfo->in_color_space == JCS_YCCK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: /* allow null conversion of JCS_UNKNOWN */ + if (cinfo->jpeg_color_space != cinfo->in_color_space || + cinfo->num_components != cinfo->input_components) + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + cconvert->pub.color_convert = null_convert; + break; + } +} diff --git a/renderer/jpeg-6/jcdctmgr.c b/renderer/jpeg-6/jcdctmgr.c new file mode 100644 index 000000000..6f24fbd09 --- /dev/null +++ b/renderer/jpeg-6/jcdctmgr.c @@ -0,0 +1,388 @@ +/* + * jcdctmgr.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the forward-DCT management logic. + * This code selects a particular DCT implementation to be used, + * and it performs related housekeeping chores including coefficient + * quantization. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_forward_dct pub; /* public fields */ + + /* Pointer to the DCT routine actually in use */ + forward_DCT_method_ptr do_dct; + + /* The actual post-DCT divisors --- not identical to the quant table + * entries, because of scaling (especially for an unnormalized DCT). + * Each table is given in normal array order; note that this must + * be converted from the zigzag order of the quantization tables. + */ + DCTELEM * divisors[NUM_QUANT_TBLS]; + +#ifdef DCT_FLOAT_SUPPORTED + /* Same as above for the floating-point case. */ + float_DCT_method_ptr do_float_dct; + FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; +#endif +} my_fdct_controller; + +typedef my_fdct_controller * my_fdct_ptr; + + +/* + * Initialize for a processing pass. + * Verify that all referenced Q-tables are present, and set up + * the divisor table for each one. + * In the current implementation, DCT of all components is done during + * the first pass, even if only some components will be output in the + * first scan. Hence all components should be examined here. + */ + +METHODDEF void +start_pass_fdctmgr (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + int ci, qtblno, i; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + //DCTELEM * dtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + qtblno = compptr->quant_tbl_no; + /* Make sure specified quantization table is present */ + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + qtbl = cinfo->quant_tbl_ptrs[qtblno]; + /* Compute divisors for this quant table */ + /* We may do this more than once for same table, but it's not a big deal */ + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + /* For LL&M IDCT method, divisors are equal to raw quantization + * coefficients multiplied by 8 (to counteract scaling). + */ + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = ((DCTELEM) qtbl->quantval[jpeg_zigzag_order[i]]) << 3; + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + */ +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits: in natural order */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = (DCTELEM) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], + (INT32) aanscales[i]), + CONST_BITS-3); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + FAST_FLOAT * fdtbl; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + if (fdct->float_divisors[qtblno] == NULL) { + fdct->float_divisors[qtblno] = (FAST_FLOAT *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)); + } + fdtbl = fdct->float_divisors[qtblno]; + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fdtbl[i] = (FAST_FLOAT) + (1.0 / (((double) qtbl->quantval[jpeg_zigzag_order[i]] * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Perform forward DCT on one or more blocks of a component. + * + * The input samples are taken from the sample_data[] array starting at + * position start_row/start_col, and moving to the right for any additional + * blocks. The quantized coefficients are returned in coef_blocks[]. + */ + +METHODDEF void +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for integer DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + forward_DCT_method_ptr do_dct = fdct->do_dct; + DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register DCTELEM *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register DCTELEM temp, qval; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ +#ifdef FAST_DIVIDE +#define DIVIDE_BY(a,b) a /= b +#else +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#endif + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; + } + } + } +} + + +#ifdef DCT_FLOAT_SUPPORTED + +METHODDEF void +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for floating-point DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + float_DCT_method_ptr do_dct = fdct->do_float_dct; + FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; + FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register FAST_FLOAT *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = (FAST_FLOAT) + (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register FAST_FLOAT temp; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + /* Apply the quantization and scaling factor */ + temp = workspace[i] * divisors[i]; + /* Round to nearest integer. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * The maximum coefficient size is +-16K (for 12-bit data), so this + * code should work for either 16-bit or 32-bit ints. + */ + output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); + } + } + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ + + +/* + * Initialize FDCT manager. + */ + +GLOBAL void +jinit_forward_dct (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct; + int i; + + fdct = (my_fdct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_fdct_controller)); + cinfo->fdct = (struct jpeg_forward_dct *) fdct; + fdct->pub.start_pass = start_pass_fdctmgr; + + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_islow; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_ifast; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + fdct->pub.forward_DCT = forward_DCT_float; + fdct->do_float_dct = jpeg_fdct_float; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + + /* Mark divisor tables unallocated */ + for (i = 0; i < NUM_QUANT_TBLS; i++) { + fdct->divisors[i] = NULL; +#ifdef DCT_FLOAT_SUPPORTED + fdct->float_divisors[i] = NULL; +#endif + } +} diff --git a/renderer/jpeg-6/jchuff.c b/renderer/jpeg-6/jchuff.c new file mode 100644 index 000000000..59f7865c6 --- /dev/null +++ b/renderer/jpeg-6/jchuff.c @@ -0,0 +1,846 @@ +/* + * jchuff.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jcphuff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + savable_state saved; /* Bit buffer & DC state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * dc_count_ptrs[NUM_HUFF_TBLS]; + long * ac_count_ptrs[NUM_HUFF_TBLS]; +#endif +} huff_entropy_encoder; + +typedef huff_entropy_encoder * huff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF boolean encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF void finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF boolean encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF void +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + entropy->pub.encode_mcu = encode_mcu_gather; + entropy->pub.finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + entropy->pub.encode_mcu = encode_mcu_huff; + entropy->pub.finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Make sure requested tables are present */ + /* (In gather mode, tables need not be allocated yet) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || + (cinfo->dc_huff_tbl_ptrs[dctbl] == NULL && !gather_statistics)) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS || + (cinfo->ac_huff_tbl_ptrs[actbl] == NULL && !gather_statistics)) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->dc_count_ptrs[dctbl] == NULL) + entropy->dc_count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy->ac_count_ptrs[actbl] == NULL) + entropy->ac_count_ptrs[actbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], + & entropy->ac_derived_tbls[actbl]); + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* + * Compute the derived values for a Huffman table. + * Note this is also used by jcphuff.c. + */ + +GLOBAL void +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, + c_derived_tbl ** pdtbl) +{ + c_derived_tbl *dtbl; + int p, i, l, lastp, si; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (c_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_derived_tbl)); + dtbl = *pdtbl; + + /* Figure C.1: make table of Huffman code length for each symbol */ + /* Note that this is in code-length order. */ + + p = 0; + for (l = 1; l <= 16; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + lastp = p; + + /* Figure C.2: generate the codes themselves */ + /* Note that this is in code-length order. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + code <<= 1; + si++; + } + + /* Figure C.3: generate encoding tables */ + /* These are code and size indexed by symbol value */ + + /* Set any codeless symbols to have code length 0; + * this allows emit_bits to detect any attempt to emit such symbols. + */ + MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); + + for (p = 0; p < lastp; p++) { + dtbl->ehufco[htbl->huffval[p]] = huffcode[p]; + dtbl->ehufsi[htbl->huffval[p]] = huffsize[p]; + } +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL boolean +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL boolean +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL boolean +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* Encode a single block's worth of coefficients */ + +LOCAL boolean +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, + c_derived_tbl *dctbl, c_derived_tbl *actbl) +{ + register int temp, temp2; + register int nbits; + register int k, r, i; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = temp2 = block[0] - last_dc_val; + + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + + /* Emit Huffman symbol for run length / number of bits */ + i = (r << 4) + nbits; + if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) + return FALSE; + + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL boolean +emit_restart (working_state * state, int restart_num) +{ + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +METHODDEF boolean +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], state.cur.last_dc_val[ci], + entropy->dc_derived_tbls[compptr->dc_tbl_no], + entropy->ac_derived_tbls[compptr->ac_tbl_no])) + return FALSE; + /* Update last_dc_val */ + state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF void +finish_pass_huff (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * This actually is optimization, in the sense that we find the best possible + * Huffman table(s) for the given data. We first scan the supplied data and + * count the number of uses of each symbol that is to be Huffman-coded. + * (This process must agree with the code above.) Then we build an + * optimal Huffman coding tree for the observed counts. + * + * The JPEG standard requires Huffman codes to be no more than 16 bits long. + * If some symbols have a very small but nonzero probability, the Huffman tree + * must be adjusted to meet the code length restriction. We currently use + * the adjustment method suggested in the JPEG spec. This method is *not* + * optimal; it may not choose the best possible limited-length code. But + * since the symbols involved are infrequently used, it's not clear that + * going to extra trouble is worthwhile. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + + +/* Process a single block's worth of coefficients */ + +LOCAL void +htest_one_block (JCOEFPTR block, int last_dc_val, + long dc_counts[], long ac_counts[]) +{ + register int temp; + register int nbits; + register int k, r; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = block[0] - last_dc_val; + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + ac_counts[0]++; +} + + +/* + * Trial-encode one MCU's worth of Huffman-compressed coefficients. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF boolean +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn, ci; + jpeg_component_info * compptr; + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + htest_one_block(MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + entropy->dc_count_ptrs[compptr->dc_tbl_no], + entropy->ac_count_ptrs[compptr->ac_tbl_no]); + entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + return TRUE; +} + + +/* + * Generate the optimal coding for the given counts, fill htbl. + * Note this is also used by jcphuff.c. + */ + +GLOBAL void +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) +{ +#define MAX_CLEN 32 /* assumed maximum initial code length */ + UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ + int codesize[257]; /* codesize[k] = code length of symbol k */ + int others[257]; /* next symbol in current branch of tree */ + int c1, c2; + int p, i, j; + long v; + + /* This algorithm is explained in section K.2 of the JPEG standard */ + + MEMZERO(bits, SIZEOF(bits)); + MEMZERO(codesize, SIZEOF(codesize)); + for (i = 0; i < 257; i++) + others[i] = -1; /* init links to empty */ + + freq[256] = 1; /* make sure there is a nonzero count */ + /* Including the pseudo-symbol 256 in the Huffman procedure guarantees + * that no real symbol is given code-value of all ones, because 256 + * will be placed in the largest codeword category. + */ + + /* Huffman's basic algorithm to assign optimal code lengths to symbols */ + + for (;;) { + /* Find the smallest nonzero frequency, set c1 = its symbol */ + /* In case of ties, take the larger symbol number */ + c1 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v) { + v = freq[i]; + c1 = i; + } + } + + /* Find the next smallest nonzero frequency, set c2 = its symbol */ + /* In case of ties, take the larger symbol number */ + c2 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v && i != c1) { + v = freq[i]; + c2 = i; + } + } + + /* Done if we've merged everything into one frequency */ + if (c2 < 0) + break; + + /* Else merge the two counts/trees */ + freq[c1] += freq[c2]; + freq[c2] = 0; + + /* Increment the codesize of everything in c1's tree branch */ + codesize[c1]++; + while (others[c1] >= 0) { + c1 = others[c1]; + codesize[c1]++; + } + + others[c1] = c2; /* chain c2 onto c1's tree branch */ + + /* Increment the codesize of everything in c2's tree branch */ + codesize[c2]++; + while (others[c2] >= 0) { + c2 = others[c2]; + codesize[c2]++; + } + } + + /* Now count the number of symbols of each code length */ + for (i = 0; i <= 256; i++) { + if (codesize[i]) { + /* The JPEG standard seems to think that this can't happen, */ + /* but I'm paranoid... */ + if (codesize[i] > MAX_CLEN) + ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); + + bits[codesize[i]]++; + } + } + + /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + * Huffman procedure assigned any such lengths, we must adjust the coding. + * Here is what the JPEG spec says about how this next bit works: + * Since symbols are paired for the longest Huffman code, the symbols are + * removed from this length category two at a time. The prefix for the pair + * (which is one bit shorter) is allocated to one of the pair; then, + * skipping the BITS entry for that prefix length, a code word from the next + * shortest nonzero BITS entry is converted into a prefix for two code words + * one bit longer. + */ + + for (i = MAX_CLEN; i > 16; i--) { + while (bits[i] > 0) { + j = i - 2; /* find length of new prefix to be used */ + while (bits[j] == 0) + j--; + + bits[i] -= 2; /* remove two symbols */ + bits[i-1]++; /* one goes in this length */ + bits[j+1] += 2; /* two new symbols in this length */ + bits[j]--; /* symbol of this length is now a prefix */ + } + } + + /* Remove the count for the pseudo-symbol 256 from the largest codelength */ + while (bits[i] == 0) /* find largest codelength still in use */ + i--; + bits[i]--; + + /* Return final symbol counts (only for lengths 0..16) */ + MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits)); + + /* Return a list of the symbols sorted by code length */ + /* It's not real clear to me why we don't need to consider the codelength + * changes made above, but the JPEG spec seems to think this works. + */ + p = 0; + for (i = 1; i <= MAX_CLEN; i++) { + for (j = 0; j <= 255; j++) { + if (codesize[j] == i) { + htbl->huffval[p] = (UINT8) j; + p++; + } + } + } + + /* Set sent_table FALSE so updated table will be written to JPEG file. */ + htbl->sent_table = FALSE; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF void +finish_pass_gather (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + boolean did_ac[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + MEMZERO(did_ac, SIZEOF(did_ac)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + if (! did_ac[actbl]) { + htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); + did_ac[actbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL void +jinit_huff_encoder (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_huff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; +#endif + } +} diff --git a/renderer/jpeg-6/jchuff.h b/renderer/jpeg-6/jchuff.h new file mode 100644 index 000000000..f43d571d6 --- /dev/null +++ b/renderer/jpeg-6/jchuff.h @@ -0,0 +1,34 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* Derived data constructed for each Huffman table */ + +typedef struct { + unsigned int ehufco[256]; /* code for each symbol */ + char ehufsi[256]; /* length of code for each symbol */ + /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Expand a Huffman table definition into the derived format */ +EXTERN void jpeg_make_c_derived_tbl JPP((j_compress_ptr cinfo, + JHUFF_TBL * htbl, c_derived_tbl ** pdtbl)); + +/* Generate an optimal table definition given the specified counts */ +EXTERN void jpeg_gen_optimal_table JPP((j_compress_ptr cinfo, + JHUFF_TBL * htbl, long freq[])); diff --git a/renderer/jpeg-6/jcinit.c b/renderer/jpeg-6/jcinit.c new file mode 100644 index 000000000..2cc82b253 --- /dev/null +++ b/renderer/jpeg-6/jcinit.c @@ -0,0 +1,72 @@ +/* + * jcinit.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains initialization logic for the JPEG compressor. + * This routine is in charge of selecting the modules to be executed and + * making an initialization call to each one. + * + * Logically, this code belongs in jcmaster.c. It's split out because + * linking this routine implies linking the entire compression library. + * For a transcoding-only application, we want to be able to use jcmaster.c + * without linking in the whole library. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Master selection of compression modules. + * This is done once at the start of processing an image. We determine + * which modules will be used and give them appropriate initialization calls. + */ + +GLOBAL void +jinit_compress_master (j_compress_ptr cinfo) +{ + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, FALSE /* full compression */); + + /* Preprocessing */ + if (! cinfo->raw_data_in) { + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); + } + /* Forward DCT */ + jinit_forward_dct(cinfo); + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* Need a full-image coefficient buffer in any multi-pass mode. */ + jinit_c_coef_controller(cinfo, + (cinfo->num_scans > 1 || cinfo->optimize_coding)); + jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} diff --git a/renderer/jpeg-6/jcmainct.c b/renderer/jpeg-6/jcmainct.c new file mode 100644 index 000000000..65b113f40 --- /dev/null +++ b/renderer/jpeg-6/jcmainct.c @@ -0,0 +1,293 @@ +/* + * jcmainct.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for compression. + * The main buffer lies between the pre-processor and the JPEG + * compressor proper; it holds downsampled data in the JPEG colorspace. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Note: currently, there is no operating mode in which a full-image buffer + * is needed at this step. If there were, that mode could not be used with + * "raw data" input, since this module is bypassed in that case. However, + * we've left the code here for possible use in special applications. + */ +#undef FULL_MAIN_BUFFER_SUPPORTED + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_main_controller pub; /* public fields */ + + JDIMENSION cur_iMCU_row; /* number of current iMCU row */ + JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ + boolean suspended; /* remember if we suspended output */ + J_BUF_MODE pass_mode; /* current operating mode */ + + /* If using just a strip buffer, this points to the entire set of buffers + * (we allocate one for each component). In the full-image case, this + * points to the currently accessible strips of the virtual arrays. + */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* If using full-image storage, this array holds pointers to virtual-array + * control blocks for each component. Unused if not full-image storage. + */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +#endif +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + + +/* Forward declarations */ +METHODDEF void process_data_simple_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#ifdef FULL_MAIN_BUFFER_SUPPORTED +METHODDEF void process_data_buffer_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + main->cur_iMCU_row = 0; /* initialize counters */ + main->rowgroup_ctr = 0; + main->suspended = FALSE; + main->pass_mode = pass_mode; /* save mode for use by process_data */ + + switch (pass_mode) { + case JBUF_PASS_THRU: +#ifdef FULL_MAIN_BUFFER_SUPPORTED + if (main->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + main->pub.process_data = process_data_simple_main; + break; +#ifdef FULL_MAIN_BUFFER_SUPPORTED + case JBUF_SAVE_SOURCE: + case JBUF_CRANK_DEST: + case JBUF_SAVE_AND_PASS: + if (main->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + main->pub.process_data = process_data_buffer_main; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This routine handles the simple pass-through mode, + * where we have only a strip buffer. + */ + +METHODDEF void +process_data_simple_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Read input data if we haven't filled the main buffer yet */ + if (main->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + + /* If we don't have a full iMCU row buffered, return to application for + * more data. Note that preprocessor will always pad to fill the iMCU row + * at the bottom of the image. + */ + if (main->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + +/* + * Process some data. + * This routine handles all of the modes that use a full-size buffer. + */ + +METHODDEF void +process_data_buffer_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ + if (main->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main->whole_image[ci], + main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + } + /* In a read pass, pretend we just read some source data. */ + if (! writing) { + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; + main->rowgroup_ctr = DCTSIZE; + } + } + + /* If a write pass, read input data until the current iMCU row is full. */ + /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ + if (writing) { + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ + if (main->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ + if (main->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL void +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_c_main_controller *) main; + main->pub.start_pass = start_pass_main; + + /* We don't need to create a buffer in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + /* Create the buffer. It holds downsampled data, so each component + * may be of a different size. + */ + if (need_full_buffer) { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component */ + /* Note we pad the bottom to a multiple of the iMCU height */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor) * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + main->whole_image[0] = NULL; /* flag for no virtual arrays */ +#endif + /* Allocate a strip buffer for each component */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } + } +} diff --git a/renderer/jpeg-6/jcmarker.c b/renderer/jpeg-6/jcmarker.c new file mode 100644 index 000000000..f4d290b99 --- /dev/null +++ b/renderer/jpeg-6/jcmarker.c @@ -0,0 +1,639 @@ +/* + * jcmarker.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write JPEG datastream markers. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* + * Basic output routines. + * + * Note that we do not support suspension while writing a marker. + * Therefore, an application using suspension must ensure that there is + * enough buffer space for the initial markers (typ. 600-700 bytes) before + * calling jpeg_start_compress, and enough space to write the trailing EOI + * (a few bytes) before calling jpeg_finish_compress. Multipass compression + * modes are not supported at all with suspension, so those two are the only + * points where markers will be written. + */ + +LOCAL void +emit_byte (j_compress_ptr cinfo, int val) +/* Emit a byte */ +{ + struct jpeg_destination_mgr * dest = cinfo->dest; + + *(dest->next_output_byte)++ = (JOCTET) val; + if (--dest->free_in_buffer == 0) { + if (! (*dest->empty_output_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } +} + + +LOCAL void +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) +/* Emit a marker code */ +{ + emit_byte(cinfo, 0xFF); + emit_byte(cinfo, (int) mark); +} + + +LOCAL void +emit_2bytes (j_compress_ptr cinfo, int value) +/* Emit a 2-byte integer; these are always MSB first in JPEG files */ +{ + emit_byte(cinfo, (value >> 8) & 0xFF); + emit_byte(cinfo, value & 0xFF); +} + + +/* + * Routines to write specific marker types. + */ + +LOCAL int +emit_dqt (j_compress_ptr cinfo, int index) +/* Emit a DQT marker */ +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ +{ + JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; + int prec; + int i; + + if (qtbl == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); + + prec = 0; + for (i = 0; i < DCTSIZE2; i++) { + if (qtbl->quantval[i] > 255) + prec = 1; + } + + if (! qtbl->sent_table) { + emit_marker(cinfo, M_DQT); + + emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec<<4)); + + for (i = 0; i < DCTSIZE2; i++) { + if (prec) + emit_byte(cinfo, qtbl->quantval[i] >> 8); + emit_byte(cinfo, qtbl->quantval[i] & 0xFF); + } + + qtbl->sent_table = TRUE; + } + + return prec; +} + + +LOCAL void +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) +/* Emit a DHT marker */ +{ + JHUFF_TBL * htbl; + int length, i; + + if (is_ac) { + htbl = cinfo->ac_huff_tbl_ptrs[index]; + index += 0x10; /* output index has AC bit set */ + } else { + htbl = cinfo->dc_huff_tbl_ptrs[index]; + } + + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); + + if (! htbl->sent_table) { + emit_marker(cinfo, M_DHT); + + length = 0; + for (i = 1; i <= 16; i++) + length += htbl->bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for (i = 1; i <= 16; i++) + emit_byte(cinfo, htbl->bits[i]); + + for (i = 0; i < length; i++) + emit_byte(cinfo, htbl->huffval[i]); + + htbl->sent_table = TRUE; + } +} + + +LOCAL void +emit_dac (j_compress_ptr cinfo) +/* Emit a DAC marker */ +/* Since the useful info is so small, we want to emit all the tables in */ +/* one DAC marker. Therefore this routine does its own scan of the table. */ +{ +#ifdef C_ARITH_CODING_SUPPORTED + char dc_in_use[NUM_ARITH_TBLS]; + char ac_in_use[NUM_ARITH_TBLS]; + int length, i; + jpeg_component_info *compptr; + + for (i = 0; i < NUM_ARITH_TBLS; i++) + dc_in_use[i] = ac_in_use[i] = 0; + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + dc_in_use[compptr->dc_tbl_no] = 1; + ac_in_use[compptr->ac_tbl_no] = 1; + } + + length = 0; + for (i = 0; i < NUM_ARITH_TBLS; i++) + length += dc_in_use[i] + ac_in_use[i]; + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + if (dc_in_use[i]) { + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); + } + if (ac_in_use[i]) { + emit_byte(cinfo, i + 0x10); + emit_byte(cinfo, cinfo->arith_ac_K[i]); + } + } +#endif /* C_ARITH_CODING_SUPPORTED */ +} + + +LOCAL void +emit_dri (j_compress_ptr cinfo) +/* Emit a DRI marker */ +{ + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); /* fixed length */ + + emit_2bytes(cinfo, (int) cinfo->restart_interval); +} + + +LOCAL void +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) +/* Emit a SOF marker */ +{ + int ci; + jpeg_component_info *compptr; + + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ + + /* Make sure image isn't bigger than SOF field can handle */ + if ((long) cinfo->image_height > 65535L || + (long) cinfo->image_width > 65535L) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); + + emit_byte(cinfo, cinfo->data_precision); + emit_2bytes(cinfo, (int) cinfo->image_height); + emit_2bytes(cinfo, (int) cinfo->image_width); + + emit_byte(cinfo, cinfo->num_components); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + emit_byte(cinfo, compptr->component_id); + emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); + emit_byte(cinfo, compptr->quant_tbl_no); + } +} + + +LOCAL void +emit_sos (j_compress_ptr cinfo) +/* Emit a SOS marker */ +{ + int i, td, ta; + jpeg_component_info *compptr; + + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ + + emit_byte(cinfo, cinfo->comps_in_scan); + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + emit_byte(cinfo, compptr->component_id); + td = compptr->dc_tbl_no; + ta = compptr->ac_tbl_no; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan; + * furthermore, Huffman coding of DC refinement uses no table at all. + * We emit 0 for unused field(s); this is recommended by the P&M text + * but does not seem to be specified in the standard. + */ + if (cinfo->Ss == 0) { + ta = 0; /* DC scan */ + if (cinfo->Ah != 0 && !cinfo->arith_code) + td = 0; /* no DC table either */ + } else { + td = 0; /* AC scan */ + } + } + emit_byte(cinfo, (td << 4) + ta); + } + + emit_byte(cinfo, cinfo->Ss); + emit_byte(cinfo, cinfo->Se); + emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); +} + + +LOCAL void +emit_jfif_app0 (j_compress_ptr cinfo) +/* Emit a JFIF-compliant APP0 marker */ +{ + /* + * Length of APP0 block (2 bytes) + * Block ID (4 bytes - ASCII "JFIF") + * Zero byte (1 byte to terminate the ID string) + * Version Major, Minor (2 bytes - 0x01, 0x01) + * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) + * Xdpu (2 bytes - dots per unit horizontal) + * Ydpu (2 bytes - dots per unit vertical) + * Thumbnail X size (1 byte) + * Thumbnail Y size (1 byte) + */ + + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ + + emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0x49); + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0); + /* We currently emit version code 1.01 since we use no 1.02 features. + * This may avoid complaints from some older decoders. + */ + emit_byte(cinfo, 1); /* Major version */ + emit_byte(cinfo, 1); /* Minor version */ + emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ + emit_2bytes(cinfo, (int) cinfo->X_density); + emit_2bytes(cinfo, (int) cinfo->Y_density); + emit_byte(cinfo, 0); /* No thumbnail image */ + emit_byte(cinfo, 0); +} + + +LOCAL void +emit_adobe_app14 (j_compress_ptr cinfo) +/* Emit an Adobe APP14 marker */ +{ + /* + * Length of APP14 block (2 bytes) + * Block ID (5 bytes - ASCII "Adobe") + * Version Number (2 bytes - currently 100) + * Flags0 (2 bytes - currently 0) + * Flags1 (2 bytes - currently 0) + * Color transform (1 byte) + * + * Although Adobe TN 5116 mentions Version = 101, all the Adobe files + * now in circulation seem to use Version = 100, so that's what we write. + * + * We write the color transform byte as 1 if the JPEG color space is + * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + * whether the encoder performed a transformation, which is pretty useless. + */ + + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ + + emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ + emit_byte(cinfo, 0x64); + emit_byte(cinfo, 0x6F); + emit_byte(cinfo, 0x62); + emit_byte(cinfo, 0x65); + emit_2bytes(cinfo, 100); /* Version */ + emit_2bytes(cinfo, 0); /* Flags0 */ + emit_2bytes(cinfo, 0); /* Flags1 */ + switch (cinfo->jpeg_color_space) { + case JCS_YCbCr: + emit_byte(cinfo, 1); /* Color transform = 1 */ + break; + case JCS_YCCK: + emit_byte(cinfo, 2); /* Color transform = 2 */ + break; + default: + emit_byte(cinfo, 0); /* Color transform = 0 */ + break; + } +} + + +/* + * This routine is exported for possible use by applications. + * The intended use is to emit COM or APPn markers after calling + * jpeg_start_compress() and before the first jpeg_write_scanlines() call + * (hence, after write_file_header but before write_frame_header). + * Other uses are not guaranteed to produce desirable results. + */ + +METHODDEF void +write_any_marker (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen) +/* Emit an arbitrary marker with parameters */ +{ + if (datalen <= (unsigned int) 65533) { /* safety check */ + emit_marker(cinfo, (JPEG_MARKER) marker); + + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ + + while (datalen--) { + emit_byte(cinfo, *dataptr); + dataptr++; + } + } +} + + +/* + * Write datastream header. + * This consists of an SOI and optional APPn markers. + * We recommend use of the JFIF marker, but not the Adobe marker, + * when using YCbCr or grayscale data. The JFIF marker should NOT + * be used for any other JPEG colorspace. The Adobe marker is helpful + * to distinguish RGB, CMYK, and YCCK colorspaces. + * Note that an application can write additional header markers after + * jpeg_start_compress returns. + */ + +METHODDEF void +write_file_header (j_compress_ptr cinfo) +{ + emit_marker(cinfo, M_SOI); /* first the SOI */ + + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ + emit_jfif_app0(cinfo); + if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ + emit_adobe_app14(cinfo); +} + + +/* + * Write frame header. + * This consists of DQT and SOFn markers. + * Note that we do not emit the SOF until we have emitted the DQT(s). + * This avoids compatibility problems with incorrect implementations that + * try to error-check the quant table numbers as soon as they see the SOF. + */ + +METHODDEF void +write_frame_header (j_compress_ptr cinfo) +{ + int ci, prec; + boolean is_baseline; + jpeg_component_info *compptr; + + /* Emit DQT for each quantization table. + * Note that emit_dqt() suppresses any duplicate tables. + */ + prec = 0; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prec += emit_dqt(cinfo, compptr->quant_tbl_no); + } + /* now prec is nonzero iff there are any 16-bit quant tables. */ + + /* Check for a non-baseline specification. + * Note we assume that Huffman table numbers won't be changed later. + */ + if (cinfo->arith_code || cinfo->progressive_mode || + cinfo->data_precision != 8) { + is_baseline = FALSE; + } else { + is_baseline = TRUE; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) + is_baseline = FALSE; + } + if (prec && is_baseline) { + is_baseline = FALSE; + /* If it's baseline except for quantizer size, warn the user */ + TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); + } + } + + /* Emit the proper SOF marker */ + if (cinfo->arith_code) { + emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ + } else { + if (cinfo->progressive_mode) + emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ + else if (is_baseline) + emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ + else + emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ + } +} + + +/* + * Write scan header. + * This consists of DHT or DAC markers, optional DRI, and SOS. + * Compressed data will be written following the SOS. + */ + +METHODDEF void +write_scan_header (j_compress_ptr cinfo) +{ + int i; + jpeg_component_info *compptr; + + if (cinfo->arith_code) { + /* Emit arith conditioning info. We may have some duplication + * if the file has multiple scans, but it's so small it's hardly + * worth worrying about. + */ + emit_dac(cinfo); + } else { + /* Emit Huffman tables. + * Note that emit_dht() suppresses any duplicate tables. + */ + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan */ + if (cinfo->Ss == 0) { + if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + } else { + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } else { + /* Sequential mode: need both DC and AC tables */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } + } + + /* Emit DRI if required --- note that DRI value could change for each scan. + * If it doesn't, a tiny amount of space is wasted in multiple-scan files. + * We assume DRI will never be nonzero for one scan and zero for a later one. + */ + if (cinfo->restart_interval) + emit_dri(cinfo); + + emit_sos(cinfo); +} + + +/* + * Write datastream trailer. + */ + +METHODDEF void +write_file_trailer (j_compress_ptr cinfo) +{ + emit_marker(cinfo, M_EOI); +} + + +/* + * Write an abbreviated table-specification datastream. + * This consists of SOI, DQT and DHT tables, and EOI. + * Any table that is defined and not marked sent_table = TRUE will be + * emitted. Note that all tables will be marked sent_table = TRUE at exit. + */ + +METHODDEF void +write_tables_only (j_compress_ptr cinfo) +{ + int i; + + emit_marker(cinfo, M_SOI); + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if (cinfo->quant_tbl_ptrs[i] != NULL) + (void) emit_dqt(cinfo, i); + } + + if (! cinfo->arith_code) { + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, FALSE); + if (cinfo->ac_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, TRUE); + } + } + + emit_marker(cinfo, M_EOI); +} + + +/* + * Initialize the marker writer module. + */ + +GLOBAL void +jinit_marker_writer (j_compress_ptr cinfo) +{ + /* Create the subobject */ + cinfo->marker = (struct jpeg_marker_writer *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_writer)); + /* Initialize method pointers */ + cinfo->marker->write_any_marker = write_any_marker; + cinfo->marker->write_file_header = write_file_header; + cinfo->marker->write_frame_header = write_frame_header; + cinfo->marker->write_scan_header = write_scan_header; + cinfo->marker->write_file_trailer = write_file_trailer; + cinfo->marker->write_tables_only = write_tables_only; +} diff --git a/renderer/jpeg-6/jcmaster.c b/renderer/jpeg-6/jcmaster.c new file mode 100644 index 000000000..84494e628 --- /dev/null +++ b/renderer/jpeg-6/jcmaster.c @@ -0,0 +1,578 @@ +/* + * jcmaster.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG compressor. + * These routines are concerned with parameter validation, initial setup, + * and inter-pass control (determining the number of passes and the work + * to be done in each pass). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef enum { + main_pass, /* input data, also do first output step */ + huff_opt_pass, /* Huffman code optimization pass */ + output_pass /* data output pass */ +} c_pass_type; + +typedef struct { + struct jpeg_comp_master pub; /* public fields */ + + c_pass_type pass_type; /* the type of the current pass */ + + int pass_number; /* # of passes completed */ + int total_passes; /* total # of passes needed */ + + int scan_number; /* current index in scan_info[] */ +} my_comp_master; + +typedef my_comp_master * my_master_ptr; + + +/* + * Support routines that do various essential calculations. + */ + +LOCAL void +initial_setup (j_compress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ + int ci; + jpeg_component_info *compptr; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Sanity check on image dimensions */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0 || cinfo->input_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* Width of an input scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Fill in the correct component_index value; don't rely on application */ + compptr->component_index = ci; + /* For compression, we never do DCT scaling. */ + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed (this flag isn't actually used for compression) */ + compptr->component_needed = TRUE; + } + + /* Compute number of fully interleaved MCU rows (number of times that + * main controller will call coefficient controller). + */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL void +validate_script (j_compress_ptr cinfo) +/* Verify that the scan script in cinfo->scan_info[] is valid; also + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. + */ +{ + const jpeg_scan_info * scanptr; + int scanno, ncomps, ci, coefi, thisi; + int Ss, Se, Ah, Al; + boolean component_sent[MAX_COMPONENTS]; +#ifdef C_PROGRESSIVE_SUPPORTED + int * last_bitpos_ptr; + int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; + /* -1 until that coefficient has been seen; then last Al for it */ +#endif + + if (cinfo->num_scans <= 0) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); + + /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + * for progressive JPEG, no scan can have this. + */ + scanptr = cinfo->scan_info; + if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { +#ifdef C_PROGRESSIVE_SUPPORTED + cinfo->progressive_mode = TRUE; + last_bitpos_ptr = & last_bitpos[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (coefi = 0; coefi < DCTSIZE2; coefi++) + *last_bitpos_ptr++ = -1; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + for (ci = 0; ci < cinfo->num_components; ci++) + component_sent[ci] = FALSE; + } + + for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) { + /* Validate component indexes */ + ncomps = scanptr->comps_in_scan; + if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (thisi < 0 || thisi >= cinfo->num_components) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + /* Components must appear in SOF order within each scan */ + if (ci > 0 && thisi <= scanptr->component_index[ci-1]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + } + /* Validate progression parameters */ + Ss = scanptr->Ss; + Se = scanptr->Se; + Ah = scanptr->Ah; + Al = scanptr->Al; + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || + Ah < 0 || Ah > 13 || Al < 0 || Al > 13) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + if (Ss == 0) { + if (Se != 0) /* DC and AC together not OK */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + if (ncomps != 1) /* AC scans must be for only one component */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + for (ci = 0; ci < ncomps; ci++) { + last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0]; + if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + for (coefi = Ss; coefi <= Se; coefi++) { + if (last_bitpos_ptr[coefi] < 0) { + /* first scan of this coefficient */ + if (Ah != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + /* not first scan */ + if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + last_bitpos_ptr[coefi] = Al; + } + } +#endif + } else { + /* For sequential JPEG, all progression parameters must be these: */ + if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + /* Make sure components are not sent twice */ + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (component_sent[thisi]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] = TRUE; + } + } + } + + /* Now verify that everything got sent. */ + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* For progressive mode, we only check that at least some DC data + * got sent for each component; the spec does not require that all bits + * of all coefficients be transmitted. Would it be wiser to enforce + * transmission of all coefficient bits?? + */ + for (ci = 0; ci < cinfo->num_components; ci++) { + if (last_bitpos[ci][0] < 0) + ERREXIT(cinfo, JERR_MISSING_DATA); + } +#endif + } else { + for (ci = 0; ci < cinfo->num_components; ci++) { + if (! component_sent[ci]) + ERREXIT(cinfo, JERR_MISSING_DATA); + } + } +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +LOCAL void +select_scan_parameters (j_compress_ptr cinfo) +/* Set up the scan parameters for the current scan */ +{ + int ci; + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (cinfo->scan_info != NULL) { + /* Prepare for current scan --- the script is already validated */ + my_master_ptr master = (my_master_ptr) cinfo->master; + const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number; + + cinfo->comps_in_scan = scanptr->comps_in_scan; + for (ci = 0; ci < scanptr->comps_in_scan; ci++) { + cinfo->cur_comp_info[ci] = + &cinfo->comp_info[scanptr->component_index[ci]]; + } + cinfo->Ss = scanptr->Ss; + cinfo->Se = scanptr->Se; + cinfo->Ah = scanptr->Ah; + cinfo->Al = scanptr->Al; + } + else +#endif + { + /* Prepare for single sequential-JPEG scan containing all components */ + if (cinfo->num_components > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPS_IN_SCAN); + cinfo->comps_in_scan = cinfo->num_components; + for (ci = 0; ci < cinfo->num_components; ci++) { + cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; + } + cinfo->Ss = 0; + cinfo->Se = DCTSIZE2-1; + cinfo->Ah = 0; + cinfo->Al = 0; + } +} + + +LOCAL void +per_scan_setup (j_compress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = DCTSIZE; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } + + /* Convert restart specified in rows to actual MCU count. */ + /* Note that count must fit in 16 bits, so we provide limiting. */ + if (cinfo->restart_in_rows > 0) { + long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row; + cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L); + } +} + + +/* + * Per-pass setup. + * This is called at the beginning of each pass. We determine which modules + * will be active during this pass and give them appropriate start_pass calls. + * We also set is_last_pass to indicate whether any more passes will be + * required. + */ + +METHODDEF void +prepare_for_pass (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + switch (master->pass_type) { + case main_pass: + /* Initial pass: will collect input data, and do either Huffman + * optimization or data output for the first scan. + */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (! cinfo->raw_data_in) { + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->downsample->start_pass) (cinfo); + (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); + } + (*cinfo->fdct->start_pass) (cinfo); + (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding); + (*cinfo->coef->start_pass) (cinfo, + (master->total_passes > 1 ? + JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + if (cinfo->optimize_coding) { + /* No immediate data output; postpone writing frame/scan headers */ + master->pub.call_pass_startup = FALSE; + } else { + /* Will write frame/scan headers at first jpeg_write_scanlines call */ + master->pub.call_pass_startup = TRUE; + } + break; +#ifdef ENTROPY_OPT_SUPPORTED + case huff_opt_pass: + /* Do Huffman optimization for a scan after the first one. */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { + (*cinfo->entropy->start_pass) (cinfo, TRUE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + master->pub.call_pass_startup = FALSE; + break; + } + /* Special case: Huffman DC refinement scans need no Huffman table + * and therefore we can skip the optimization pass for them. + */ + master->pass_type = output_pass; + master->pass_number++; + /*FALLTHROUGH*/ +#endif + case output_pass: + /* Do a data-output pass. */ + /* We need not repeat per-scan setup if prior optimization pass did it. */ + if (! cinfo->optimize_coding) { + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + } + (*cinfo->entropy->start_pass) (cinfo, FALSE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + /* We emit frame/scan headers now */ + if (master->scan_number == 0) + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); + master->pub.call_pass_startup = FALSE; + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + } + + master->pub.is_last_pass = (master->pass_number == master->total_passes-1); + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->total_passes; + } +} + + +/* + * Special start-of-pass hook. + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + * In single-pass processing, we need this hook because we don't want to + * write frame/scan headers during jpeg_start_compress; we want to let the + * application write COM markers etc. between jpeg_start_compress and the + * jpeg_write_scanlines loop. + * In multi-pass processing, this routine is not used. + */ + +METHODDEF void +pass_startup (j_compress_ptr cinfo) +{ + cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ + + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); +} + + +/* + * Finish up at end of pass. + */ + +METHODDEF void +finish_pass_master (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* The entropy coder always needs an end-of-pass call, + * either to analyze statistics or to flush its output buffer. + */ + (*cinfo->entropy->finish_pass) (cinfo); + + /* Update state for next pass */ + switch (master->pass_type) { + case main_pass: + /* next pass is either output of scan 0 (after optimization) + * or output of scan 1 (if no optimization). + */ + master->pass_type = output_pass; + if (! cinfo->optimize_coding) + master->scan_number++; + break; + case huff_opt_pass: + /* next pass is always output of current scan */ + master->pass_type = output_pass; + break; + case output_pass: + /* next pass is either optimization or output of next scan */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + master->scan_number++; + break; + } + + master->pass_number++; +} + + +/* + * Initialize master compression control. + */ + +GLOBAL void +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_comp_master)); + cinfo->master = (struct jpeg_comp_master *) master; + master->pub.prepare_for_pass = prepare_for_pass; + master->pub.pass_startup = pass_startup; + master->pub.finish_pass = finish_pass_master; + master->pub.is_last_pass = FALSE; + + /* Validate parameters, determine derived values */ + initial_setup(cinfo); + + if (cinfo->scan_info != NULL) { +#ifdef C_MULTISCAN_FILES_SUPPORTED + validate_script(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + cinfo->num_scans = 1; + } + + if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ + cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + + /* Initialize my private state */ + if (transcode_only) { + /* no main pass in transcoding */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + else + master->pass_type = output_pass; + } else { + /* for normal compression, first pass is always this type: */ + master->pass_type = main_pass; + } + master->scan_number = 0; + master->pass_number = 0; + if (cinfo->optimize_coding) + master->total_passes = cinfo->num_scans * 2; + else + master->total_passes = cinfo->num_scans; +} diff --git a/renderer/jpeg-6/jcomapi.c b/renderer/jpeg-6/jcomapi.c new file mode 100644 index 000000000..c10903f07 --- /dev/null +++ b/renderer/jpeg-6/jcomapi.c @@ -0,0 +1,94 @@ +/* + * jcomapi.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Abort processing of a JPEG compression or decompression operation, + * but don't destroy the object itself. + * + * For this, we merely clean up all the nonpermanent memory pools. + * Note that temp files (virtual arrays) are not allowed to belong to + * the permanent pool, so we will be able to close all temp files here. + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL void +jpeg_abort (j_common_ptr cinfo) +{ + int pool; + + /* Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { + (*cinfo->mem->free_pool) (cinfo, pool); + } + + /* Reset overall state for possible reuse of object */ + cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START); +} + + +/* + * Destruction of a JPEG object. + * + * Everything gets deallocated except the master jpeg_compress_struct itself + * and the error manager struct. Both of these are supplied by the application + * and must be freed, if necessary, by the application. (Often they are on + * the stack and so don't need to be freed anyway.) + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL void +jpeg_destroy (j_common_ptr cinfo) +{ + /* We need only tell the memory manager to release everything. */ + /* NB: mem pointer is NULL if memory mgr failed to initialize. */ + if (cinfo->mem != NULL) + (*cinfo->mem->self_destruct) (cinfo); + cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ + cinfo->global_state = 0; /* mark it destroyed */ +} + + +/* + * Convenience routines for allocating quantization and Huffman tables. + * (Would jutils.c be a more reasonable place to put these?) + */ + +GLOBAL JQUANT_TBL * +jpeg_alloc_quant_table (j_common_ptr cinfo) +{ + JQUANT_TBL *tbl; + + tbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} + + +GLOBAL JHUFF_TBL * +jpeg_alloc_huff_table (j_common_ptr cinfo) +{ + JHUFF_TBL *tbl; + + tbl = (JHUFF_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} diff --git a/renderer/jpeg-6/jconfig.h b/renderer/jpeg-6/jconfig.h new file mode 100644 index 000000000..7d2f733b2 --- /dev/null +++ b/renderer/jpeg-6/jconfig.h @@ -0,0 +1,41 @@ +/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#define CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#define JDCT_DEFAULT JDCT_FLOAT +#define JDCT_FASTEST JDCT_FLOAT + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Needed to make one-file style work in Watcom */ +#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/renderer/jpeg-6/jcparam.c b/renderer/jpeg-6/jcparam.c new file mode 100644 index 000000000..29862d364 --- /dev/null +++ b/renderer/jpeg-6/jcparam.c @@ -0,0 +1,575 @@ +/* + * jcparam.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains optional default-setting code for the JPEG compressor. + * Applications do not have to use this file, but those that don't use it + * must know a lot more about the innards of the JPEG code. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Quantization table setup routines + */ + +GLOBAL void +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) +/* Define a quantization table equal to the basic_table times + * a scale factor (given as a percentage). + * If force_baseline is TRUE, the computed quantization table entries + * are limited to 1..255 for JPEG baseline compatibility. + */ +{ + JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + int i; + long temp; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); + + for (i = 0; i < DCTSIZE2; i++) { + temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; + /* limit the values to the valid range */ + if (temp <= 0L) temp = 1L; + if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ + if (force_baseline && temp > 255L) + temp = 255L; /* limit to baseline range if requested */ + (*qtblptr)->quantval[i] = (UINT16) temp; + } + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*qtblptr)->sent_table = FALSE; +} + + +GLOBAL void +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables + * and a straight percentage-scaling quality scale. In most cases it's better + * to use jpeg_set_quality (below); this entry point is provided for + * applications that insist on a linear percentage scaling. + */ +{ + /* This is the sample quantization table given in the JPEG spec section K.1, + * but expressed in zigzag order (as are all of our quant. tables). + * The spec says that the values given produce "good" quality, and + * when divided by 2, "very good" quality. + */ + static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { + 16, 11, 12, 14, 12, 10, 16, 14, + 13, 14, 18, 17, 16, 19, 24, 40, + 26, 24, 22, 22, 24, 49, 35, 37, + 29, 40, 58, 51, 61, 60, 57, 51, + 56, 55, 64, 72, 92, 78, 64, 68, + 87, 69, 55, 56, 80, 109, 81, 87, + 95, 98, 103, 104, 103, 62, 77, 113, + 121, 112, 100, 120, 92, 101, 103, 99 + }; + static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { + 17, 18, 18, 24, 21, 24, 47, 26, + 26, 47, 99, 66, 56, 66, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + + /* Set up two quantization tables using the specified scaling */ + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +} + + +GLOBAL int +jpeg_quality_scaling (int quality) +/* Convert a user-specified quality rating to a percentage scaling factor + * for an underlying quantization table, using our recommended scaling curve. + * The input 'quality' factor should be 0 (terrible) to 100 (very good). + */ +{ + /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ + if (quality <= 0) quality = 1; + if (quality > 100) quality = 100; + + /* The basic table is used as-is (scaling 100) for a quality of 50. + * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + * note that at Q=100 the scaling is 0, which will cause j_add_quant_table + * to make all the table entries 1 (hence, no quantization loss). + * Qualities 1..50 are converted to scaling percentage 5000/Q. + */ + if (quality < 50) + quality = 5000 / quality; + else + quality = 200 - quality*2; + + return quality; +} + + +GLOBAL void +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables. + * This is the standard quality-adjusting entry point for typical user + * interfaces; only those who want detailed control over quantization tables + * would use the preceding three routines directly. + */ +{ + /* Convert user 0-100 rating to percentage scaling */ + quality = jpeg_quality_scaling(quality); + + /* Set up standard quality tables */ + jpeg_set_linear_quality(cinfo, quality, force_baseline); +} + + +/* + * Huffman table setup routines + */ + +LOCAL void +add_huff_table (j_compress_ptr cinfo, + JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) +/* Define a Huffman table */ +{ + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval)); + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*htblptr)->sent_table = FALSE; +} + + +LOCAL void +std_huff_tables (j_compress_ptr cinfo) +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ +/* IMPORTANT: these are only valid for 8-bit data precision! */ +{ + static const UINT8 bits_dc_luminance[17] = + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_luminance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_dc_chrominance[17] = + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_chrominance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_ac_luminance[17] = + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; + static const UINT8 val_ac_luminance[] = + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + static const UINT8 bits_ac_chrominance[17] = + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; + static const UINT8 val_ac_chrominance[] = + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +} + + +/* + * Default parameter setup for compression. + * + * Applications that don't choose to use this routine must do their + * own setup of all these parameters. Alternately, you can call this + * to establish defaults and then alter parameters selectively. This + * is the recommended approach since, if we add any new parameters, + * your code will still work (they'll be set to reasonable defaults). + */ + +GLOBAL void +jpeg_set_defaults (j_compress_ptr cinfo) +{ + int i; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Allocate comp_info array large enough for maximum component count. + * Array is made permanent in case application wants to compress + * multiple images at same param settings. + */ + if (cinfo->comp_info == NULL) + cinfo->comp_info = (jpeg_component_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)); + + /* Initialize everything not dependent on the color space */ + + cinfo->data_precision = BITS_IN_JSAMPLE; + /* Set up two quantization tables using default quality of 75 */ + jpeg_set_quality(cinfo, 75, TRUE); + /* Set up two Huffman tables */ + std_huff_tables(cinfo); + + /* Initialize default arithmetic coding conditioning */ + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + + /* Default is no multiple-scan output */ + cinfo->scan_info = NULL; + cinfo->num_scans = 0; + + /* Expect normal source image, not raw downsampled data */ + cinfo->raw_data_in = FALSE; + + /* Use Huffman coding, not arithmetic coding, by default */ + cinfo->arith_code = FALSE; + + /* By default, don't do extra passes to optimize entropy coding */ + cinfo->optimize_coding = FALSE; + /* The standard Huffman tables are only valid for 8-bit data precision. + * If the precision is higher, force optimization on so that usable + * tables will be computed. This test can be removed if default tables + * are supplied that are valid for the desired precision. + */ + if (cinfo->data_precision > 8) + cinfo->optimize_coding = TRUE; + + /* By default, use the simpler non-cosited sampling alignment */ + cinfo->CCIR601_sampling = FALSE; + + /* No input smoothing */ + cinfo->smoothing_factor = 0; + + /* DCT algorithm preference */ + cinfo->dct_method = JDCT_DEFAULT; + + /* No restart markers */ + cinfo->restart_interval = 0; + cinfo->restart_in_rows = 0; + + /* Fill in default JFIF marker parameters. Note that whether the marker + * will actually be written is determined by jpeg_set_colorspace. + */ + cinfo->density_unit = 0; /* Pixel size is unknown by default */ + cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ + cinfo->Y_density = 1; + + /* Choose JPEG colorspace based on input space, set defaults accordingly */ + + jpeg_default_colorspace(cinfo); +} + + +/* + * Select an appropriate JPEG colorspace for in_color_space. + */ + +GLOBAL void +jpeg_default_colorspace (j_compress_ptr cinfo) +{ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + break; + case JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ + break; + case JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + break; + case JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + break; + default: + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + } +} + + +/* + * Set the JPEG colorspace, and choose colorspace-dependent default values. + */ + +GLOBAL void +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) +{ + jpeg_component_info * compptr; + int ci; + +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \ + (compptr = &cinfo->comp_info[index], \ + compptr->component_id = (id), \ + compptr->h_samp_factor = (hsamp), \ + compptr->v_samp_factor = (vsamp), \ + compptr->quant_tbl_no = (quant), \ + compptr->dc_tbl_no = (dctbl), \ + compptr->ac_tbl_no = (actbl) ) + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* For all colorspaces, we use Q and Huff tables 0 for luminance components, + * tables 1 for chrominance components. + */ + + cinfo->jpeg_color_space = colorspace; + + cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */ + cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */ + + switch (colorspace) { + case JCS_GRAYSCALE: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 1; + /* JFIF specifies component ID 1 */ + SET_COMP(0, 1, 1,1, 0, 0,0); + break; + case JCS_RGB: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ + cinfo->num_components = 3; + SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); + SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); + SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); + break; + case JCS_YCbCr: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 3; + /* JFIF specifies component IDs 1,2,3 */ + /* We default to 2x2 subsamples of chrominance */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + break; + case JCS_CMYK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ + cinfo->num_components = 4; + SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0); + SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0); + SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0); + SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0); + break; + case JCS_YCCK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ + cinfo->num_components = 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + break; + case JCS_UNKNOWN: + cinfo->num_components = cinfo->input_components; + if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + for (ci = 0; ci < cinfo->num_components; ci++) { + SET_COMP(ci, ci, 1,1, 0, 0,0); + } + break; + default: + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + } +} + + +#ifdef C_PROGRESSIVE_SUPPORTED + +LOCAL jpeg_scan_info * +fill_a_scan (jpeg_scan_info * scanptr, int ci, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for specified component */ +{ + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + return scanptr; +} + +LOCAL jpeg_scan_info * +fill_scans (jpeg_scan_info * scanptr, int ncomps, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for each component */ +{ + int ci; + + for (ci = 0; ci < ncomps; ci++) { + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } + return scanptr; +} + +LOCAL jpeg_scan_info * +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) +/* Support routine: generate interleaved DC scan if possible, else N scans */ +{ + int ci; + + if (ncomps <= MAX_COMPS_IN_SCAN) { + /* Single interleaved DC scan */ + scanptr->comps_in_scan = ncomps; + for (ci = 0; ci < ncomps; ci++) + scanptr->component_index[ci] = ci; + scanptr->Ss = scanptr->Se = 0; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } else { + /* Noninterleaved DC scan for each component */ + scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + } + return scanptr; +} + + +/* + * Create a recommended progressive-JPEG script. + * cinfo->num_components and cinfo->jpeg_color_space must be correct. + */ + +GLOBAL void +jpeg_simple_progression (j_compress_ptr cinfo) +{ + int ncomps = cinfo->num_components; + int nscans; + jpeg_scan_info * scanptr; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Figure space needed for script. Calculation must match code below! */ + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + nscans = 10; + } else { + /* All-purpose script for other color spaces. */ + if (ncomps > MAX_COMPS_IN_SCAN) + nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ + else + nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ + } + + /* Allocate space for script. */ + /* We use permanent pool just in case application re-uses script. */ + scanptr = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + nscans * SIZEOF(jpeg_scan_info)); + cinfo->scan_info = scanptr; + cinfo->num_scans = nscans; + + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + /* Initial DC scan */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + /* Initial AC scan: get some luma data out in a hurry */ + scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); + /* Chroma data is too small to be worth expending many scans on */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1); + /* Complete spectral selection for luma AC */ + scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2); + /* Refine next bit of luma AC */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1); + /* Finish DC successive approximation */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + /* Finish AC successive approximation */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); + /* Luma bottom bit comes last since it's usually largest scan */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); + } else { + /* All-purpose script for other color spaces. */ + /* Successive approximation first pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); + /* Successive approximation second pass */ + scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1); + /* Successive approximation final pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); + } +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/renderer/jpeg-6/jcphuff.c b/renderer/jpeg-6/jcphuff.c new file mode 100644 index 000000000..922c17c6b --- /dev/null +++ b/renderer/jpeg-6/jcphuff.c @@ -0,0 +1,829 @@ +/* + * jcphuff.c + * + * Copyright (C) 1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for progressive JPEG. + * + * We do not support output suspension in this module, since the library + * currently does not allow multiple-scan files to be written with output + * suspension. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jchuff.c */ + +#ifdef C_PROGRESSIVE_SUPPORTED + +/* Expanded entropy encoder object for progressive Huffman encoding. */ + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + /* Mode flag: TRUE for optimization, FALSE for actual data output */ + boolean gather_statistics; + + /* Bit-level coding status. + * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. + */ + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ + + /* Coding status for DC components */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ + + /* Coding status for AC components */ + int ac_tbl_no; /* the table number of the single component */ + unsigned int EOBRUN; /* run length of EOBs */ + unsigned int BE; /* # of buffered correction bits before MCU */ + char * bit_buffer; /* buffer for correction bits (1 per char) */ + /* packing correction bits tightly would save some space but cost time... */ + + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan). + * Since any one scan codes only DC or only AC, we only need one set + * of tables, not one for DC and one for AC. + */ + c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Statistics tables for optimization; again, one set is enough */ + long * count_ptrs[NUM_HUFF_TBLS]; +} phuff_entropy_encoder; + +typedef phuff_entropy_encoder * phuff_entropy_ptr; + +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit + * buffer can hold. Larger sizes may slightly improve compression, but + * 1000 is already well into the realm of overkill. + * The minimum safe size is 64 bits. + */ + +#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ + +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. + * We assume that int right shift is unsigned if INT32 right shift is, + * which should be safe. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS int ishift_temp; +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +/* Forward declarations */ +METHODDEF boolean encode_mcu_DC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean encode_mcu_AC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean encode_mcu_DC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean encode_mcu_AC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF void finish_pass_phuff JPP((j_compress_ptr cinfo)); +METHODDEF void finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); + + +/* + * Initialize for a Huffman-compressed scan using progressive JPEG. + */ + +METHODDEF void +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + + entropy->cinfo = cinfo; + entropy->gather_statistics = gather_statistics; + + is_DC_band = (cinfo->Ss == 0); + + /* We assume jcmaster.c already validated the scan parameters. */ + + /* Select execution routines */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_first; + else + entropy->pub.encode_mcu = encode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_refine; + else { + entropy->pub.encode_mcu = encode_mcu_AC_refine; + /* AC refinement needs a correction bit buffer */ + if (entropy->bit_buffer == NULL) + entropy->bit_buffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(char)); + } + } + if (gather_statistics) + entropy->pub.finish_pass = finish_pass_gather_phuff; + else + entropy->pub.finish_pass = finish_pass_phuff; + + /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 + * for AC coefficients. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Initialize DC predictions to 0 */ + entropy->last_dc_val[ci] = 0; + /* Make sure requested tables are present */ + /* (In gather mode, tables need not be allocated yet) */ + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + if (tbl < 0 || tbl >= NUM_HUFF_TBLS || + (cinfo->dc_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) + ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); + } else { + entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; + if (tbl < 0 || tbl >= NUM_HUFF_TBLS || + (cinfo->ac_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) + ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); + } + if (gather_statistics) { + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->count_ptrs[tbl] == NULL) + entropy->count_ptrs[tbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + if (is_DC_band) + jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], + & entropy->derived_tbls[tbl]); + else + jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], + & entropy->derived_tbls[tbl]); + } + } + + /* Initialize AC stuff */ + entropy->EOBRUN = 0; + entropy->BE = 0; + + /* Initialize bit buffer to empty */ + entropy->put_buffer = 0; + entropy->put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file. + * NB: these must be called only when actually outputting, + * that is, entropy->gather_statistics == FALSE. + */ + +/* Emit a byte */ +#define emit_byte(entropy,val) \ + { *(entropy)->next_output_byte++ = (JOCTET) (val); \ + if (--(entropy)->free_in_buffer == 0) \ + dump_buffer(entropy); } + + +LOCAL void +dump_buffer (phuff_entropy_ptr entropy) +/* Empty the output buffer; we do not support suspension in this module. */ +{ + struct jpeg_destination_mgr * dest = entropy->cinfo->dest; + + if (! (*dest->empty_output_buffer) (entropy->cinfo)) + ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); + /* After a successful buffer dump, must reset buffer pointers */ + entropy->next_output_byte = dest->next_output_byte; + entropy->free_in_buffer = dest->free_in_buffer; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL void +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) +/* Emit some bits, unless we are in gather mode */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = entropy->put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + if (entropy->gather_statistics) + return; /* do nothing if we're only getting stats */ + + put_buffer &= (((INT32) 1)<put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(entropy, c); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(entropy, 0); + } + put_buffer <<= 8; + put_bits -= 8; + } + + entropy->put_buffer = put_buffer; /* update variables */ + entropy->put_bits = put_bits; +} + + +LOCAL void +flush_bits (phuff_entropy_ptr entropy) +{ + emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ + entropy->put_buffer = 0; /* and reset bit-buffer to empty */ + entropy->put_bits = 0; +} + + +/* + * Emit (or just count) a Huffman symbol. + */ + +INLINE +LOCAL void +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) +{ + if (entropy->gather_statistics) + entropy->count_ptrs[tbl_no][symbol]++; + else { + c_derived_tbl * tbl = entropy->derived_tbls[tbl_no]; + emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]); + } +} + + +/* + * Emit bits from a correction bit buffer. + */ + +LOCAL void +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, + unsigned int nbits) +{ + if (entropy->gather_statistics) + return; /* no real work */ + + while (nbits > 0) { + emit_bits(entropy, (unsigned int) (*bufstart), 1); + bufstart++; + nbits--; + } +} + + +/* + * Emit any pending EOBRUN symbol. + */ + +LOCAL void +emit_eobrun (phuff_entropy_ptr entropy) +{ + register int temp, nbits; + + if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ + temp = entropy->EOBRUN; + nbits = 0; + while ((temp >>= 1)) + nbits++; + + emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); + if (nbits) + emit_bits(entropy, entropy->EOBRUN, nbits); + + entropy->EOBRUN = 0; + + /* Emit any buffered correction bits */ + emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); + entropy->BE = 0; + } +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL void +emit_restart (phuff_entropy_ptr entropy, int restart_num) +{ + int ci; + + emit_eobrun(entropy); + + if (! entropy->gather_statistics) { + flush_bits(entropy); + emit_byte(entropy, 0xFF); + emit_byte(entropy, JPEG_RST0 + restart_num); + } + + if (entropy->cinfo->Ss == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) + entropy->last_dc_val[ci] = 0; + } else { + /* Re-initialize all AC-related fields to 0 */ + entropy->EOBRUN = 0; + entropy->BE = 0; + } +} + + +/* + * MCU encoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF boolean +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + int blkn, ci; + int Al = cinfo->Al; + JBLOCKROW block; + jpeg_component_info * compptr; + ISHIFT_TEMPS + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + + /* Compute the DC value after the required point transform by Al. + * This is simply an arithmetic right shift. + */ + temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al); + + /* DC differences are figured on the point-transformed values. */ + temp = temp2 - entropy->last_dc_val[ci]; + entropy->last_dc_val[ci] = temp2; + + /* Encode the DC coefficient difference per section G.1.2.1 */ + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_symbol(entropy, compptr->dc_tbl_no, nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + emit_bits(entropy, (unsigned int) temp2, nbits); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF boolean +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + register int r, k; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ + + r = 0; /* r = run length of zeros */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { + r++; + continue; + } + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value; so the code is + * interwoven with finding the abs value (temp) and output bits (temp2). + */ + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + temp2 = ~temp; + } else { + temp >>= Al; /* apply the point transform */ + temp2 = temp; + } + /* Watch out for case that nonzero coef is zero after point transform */ + if (temp == 0) { + r++; + continue; + } + + /* Emit any pending EOBRUN */ + if (entropy->EOBRUN > 0) + emit_eobrun(entropy); + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + emit_bits(entropy, (unsigned int) temp2, nbits); + + r = 0; /* reset zero run length */ + } + + if (r > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + if (entropy->EOBRUN == 0x7FFF) + emit_eobrun(entropy); /* force it out to avoid overflow */ + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF boolean +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + int blkn; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* We simply emit the Al'th bit of the DC coefficient value. */ + temp = (*block)[0]; + emit_bits(entropy, (unsigned int) (temp >> Al), 1); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC successive approximation refinement scan. + */ + +METHODDEF boolean +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + register int r, k; + int EOB; + char *BR_buffer; + unsigned int BR; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + int absvalues[DCTSIZE2]; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* It is convenient to make a pre-pass to determine the transformed + * coefficients' absolute values and the EOB position. + */ + EOB = 0; + for (k = cinfo->Ss; k <= Se; k++) { + temp = (*block)[jpeg_natural_order[k]]; + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value. + */ + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + absvalues[k] = temp; /* save abs value for main pass */ + if (temp == 1) + EOB = k; /* EOB = index of last newly-nonzero coef */ + } + + /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ + + r = 0; /* r = run length of zeros */ + BR = 0; /* BR = count of buffered bits added now */ + BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = absvalues[k]) == 0) { + r++; + continue; + } + + /* Emit any required ZRLs, but not if they can be folded into EOB */ + while (r > 15 && k <= EOB) { + /* emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + /* Emit ZRL */ + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + /* Emit buffered correction bits that must be associated with ZRL */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + } + + /* If the coef was previously nonzero, it only needs a correction bit. + * NOTE: a straight translation of the spec's figure G.7 would suggest + * that we also need to test r > 15. But if r > 15, we can only get here + * if k > EOB, which implies that this coefficient is not 1. + */ + if (temp > 1) { + /* The correction bit is the next bit of the absolute value. */ + BR_buffer[BR++] = (char) (temp & 1); + continue; + } + + /* Emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); + + /* Emit output bit for newly-nonzero coef */ + temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; + emit_bits(entropy, (unsigned int) temp, 1); + + /* Emit buffered correction bits that must be associated with this code */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + r = 0; /* reset zero run length */ + } + + if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + entropy->BE += BR; /* concat my correction bits to older ones */ + /* We force out the EOB if we risk either: + * 1. overflow of the EOB counter; + * 2. overflow of the correction bit buffer during the next MCU. + */ + if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) + emit_eobrun(entropy); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed progressive scan. + */ + +METHODDEF void +finish_pass_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Flush out any buffered data */ + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF void +finish_pass_gather_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did[NUM_HUFF_TBLS]; + + /* Flush out buffered data (all we care about is counting the EOB symbol) */ + emit_eobrun(entropy); + + is_DC_band = (cinfo->Ss == 0); + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did, SIZEOF(did)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + tbl = compptr->ac_tbl_no; + } + if (! did[tbl]) { + if (is_DC_band) + htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; + else + htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); + did[tbl] = TRUE; + } + } +} + + +/* + * Module initialization routine for progressive Huffman entropy encoding. + */ + +GLOBAL void +jinit_phuff_encoder (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_phuff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + entropy->count_ptrs[i] = NULL; + } + entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/renderer/jpeg-6/jcprepct.c b/renderer/jpeg-6/jcprepct.c new file mode 100644 index 000000000..7e6094623 --- /dev/null +++ b/renderer/jpeg-6/jcprepct.c @@ -0,0 +1,371 @@ +/* + * jcprepct.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the compression preprocessing controller. + * This controller manages the color conversion, downsampling, + * and edge expansion steps. + * + * Most of the complexity here is associated with buffering input rows + * as required by the downsampler. See the comments at the head of + * jcsample.c for the downsampler's needs. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* At present, jcsample.c can request context rows only for smoothing. + * In the future, we might also need context rows for CCIR601 sampling + * or other more-complex downsampling procedures. The code to support + * context rows should be compiled only if needed. + */ +#ifdef INPUT_SMOOTHING_SUPPORTED +#define CONTEXT_ROWS_SUPPORTED +#endif + + +/* + * For the simple (no-context-row) case, we just need to buffer one + * row group's worth of pixels for the downsampling step. At the bottom of + * the image, we pad to a full row group by replicating the last pixel row. + * The downsampler's last output row is then replicated if needed to pad + * out to a full iMCU row. + * + * When providing context rows, we must buffer three row groups' worth of + * pixels. Three row groups are physically allocated, but the row pointer + * arrays are made five row groups high, with the extra pointers above and + * below "wrapping around" to point to the last and first real row groups. + * This allows the downsampler to access the proper context rows. + * At the top and bottom of the image, we create dummy context rows by + * copying the first or last real pixel row. This copying could be avoided + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + * trouble on the compression side. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_prep_controller pub; /* public fields */ + + /* Downsampling input buffer. This buffer holds color-converted data + * until we have enough to do a downsample step. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + JDIMENSION rows_to_go; /* counts rows remaining in source image */ + int next_buf_row; /* index of next row to store in color_buf */ + +#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ + int this_row_group; /* starting row index of group to process */ + int next_buf_stop; /* downsample when we reach this index */ +#endif +} my_prep_controller; + +typedef my_prep_controller * my_prep_ptr; + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + + if (pass_mode != JBUF_PASS_THRU) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Initialize total-height counter for detecting bottom of image */ + prep->rows_to_go = cinfo->image_height; + /* Mark the conversion buffer empty */ + prep->next_buf_row = 0; +#ifdef CONTEXT_ROWS_SUPPORTED + /* Preset additional state variables for context mode. + * These aren't used in non-context mode, so we needn't test which mode. + */ + prep->this_row_group = 0; + /* Set next_buf_stop to stop after two row groups have been read in. */ + prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; +#endif +} + + +/* + * Expand an image vertically from height input_rows to height output_rows, + * by duplicating the bottom row. + */ + +LOCAL void +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, + int input_rows, int output_rows) +{ + register int row; + + for (row = input_rows; row < output_rows; row++) { + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + } +} + + +/* + * Process some data in the simple no-context case. + * + * Preprocessor output data is counted in "row groups". A row group + * is defined to be v_samp_factor sample rows of each component. + * Downsampling will produce this much data from each max_v_samp_factor + * input rows. + */ + +METHODDEF void +pre_process_data (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + JDIMENSION inrows; + jpeg_component_info * compptr; + + while (*in_row_ctr < in_rows_avail && + *out_row_group_ctr < out_row_groups_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = cinfo->max_v_samp_factor - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + /* If at bottom of image, pad to fill the conversion buffer. */ + if (prep->rows_to_go == 0 && + prep->next_buf_row < cinfo->max_v_samp_factor) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, cinfo->max_v_samp_factor); + } + prep->next_buf_row = cinfo->max_v_samp_factor; + } + /* If we've filled the conversion buffer, empty it. */ + if (prep->next_buf_row == cinfo->max_v_samp_factor) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, (JDIMENSION) 0, + output_buf, *out_row_group_ctr); + prep->next_buf_row = 0; + (*out_row_group_ctr)++; + } + /* If at bottom of image, pad the output to a full iMCU height. + * Note we assume the caller is providing a one-iMCU-height output buffer! + */ + if (prep->rows_to_go == 0 && + *out_row_group_ctr < out_row_groups_avail) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_blocks * DCTSIZE, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); + } + *out_row_group_ctr = out_row_groups_avail; + break; /* can exit outer loop without test */ + } + } +} + + +#ifdef CONTEXT_ROWS_SUPPORTED + +/* + * Process some data in the context case. + */ + +METHODDEF void +pre_process_context (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + int buf_height = cinfo->max_v_samp_factor * 3; + JDIMENSION inrows; + jpeg_component_info * compptr; + + while (*out_row_group_ctr < out_row_groups_avail) { + if (*in_row_ctr < in_rows_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = prep->next_buf_stop - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + /* Pad at top of image, if first time through */ + if (prep->rows_to_go == cinfo->image_height) { + for (ci = 0; ci < cinfo->num_components; ci++) { + int row; + for (row = 1; row <= cinfo->max_v_samp_factor; row++) { + jcopy_sample_rows(prep->color_buf[ci], 0, + prep->color_buf[ci], -row, + 1, cinfo->image_width); + } + } + } + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + } else { + /* Return for more data, unless we are at the bottom of the image. */ + if (prep->rows_to_go != 0) + break; + } + /* If at bottom of image, pad to fill the conversion buffer. */ + if (prep->rows_to_go == 0 && + prep->next_buf_row < prep->next_buf_stop) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; + } + /* If we've gotten enough data, downsample a row group. */ + if (prep->next_buf_row == prep->next_buf_stop) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, + (JDIMENSION) prep->this_row_group, + output_buf, *out_row_group_ctr); + (*out_row_group_ctr)++; + /* Advance pointers with wraparound as necessary. */ + prep->this_row_group += cinfo->max_v_samp_factor; + if (prep->this_row_group >= buf_height) + prep->this_row_group = 0; + if (prep->next_buf_row >= buf_height) + prep->next_buf_row = 0; + prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; + } + /* If at bottom of image, pad the output to a full iMCU height. + * Note we assume the caller is providing a one-iMCU-height output buffer! + */ + if (prep->rows_to_go == 0 && + *out_row_group_ctr < out_row_groups_avail) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_blocks * DCTSIZE, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); + } + *out_row_group_ctr = out_row_groups_avail; + break; /* can exit outer loop without test */ + } + } +} + + +/* + * Create the wrapped-around downsampling input buffer needed for context mode. + */ + +LOCAL void +create_context_buffer (j_compress_ptr cinfo) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int rgroup_height = cinfo->max_v_samp_factor; + int ci, i; + jpeg_component_info * compptr; + JSAMPARRAY true_buffer, fake_buffer; + + /* Grab enough space for fake row pointers for all the components; + * we need five row groups' worth of pointers for each component. + */ + fake_buffer = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate the actual buffer space (3 row groups) for this component. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + true_buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) (3 * rgroup_height)); + /* Copy true buffer row pointers into the middle of the fake row array */ + MEMCOPY(fake_buffer + rgroup_height, true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + /* Fill in the above and below wraparound pointers */ + for (i = 0; i < rgroup_height; i++) { + fake_buffer[i] = true_buffer[2 * rgroup_height + i]; + fake_buffer[4 * rgroup_height + i] = true_buffer[i]; + } + prep->color_buf[ci] = fake_buffer + rgroup_height; + fake_buffer += 5 * rgroup_height; /* point to space for next component */ + } +} + +#endif /* CONTEXT_ROWS_SUPPORTED */ + + +/* + * Initialize preprocessing controller. + */ + +GLOBAL void +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_prep_ptr prep; + int ci; + jpeg_component_info * compptr; + + if (need_full_buffer) /* safety check */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + prep = (my_prep_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_prep_controller)); + cinfo->prep = (struct jpeg_c_prep_controller *) prep; + prep->pub.start_pass = start_pass_prep; + + /* Allocate the color conversion buffer. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + if (cinfo->downsample->need_context_rows) { + /* Set up to provide context rows */ +#ifdef CONTEXT_ROWS_SUPPORTED + prep->pub.pre_process_data = pre_process_context; + create_context_buffer(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* No context, just make it tall enough for one row group */ + prep->pub.pre_process_data = pre_process_data; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/renderer/jpeg-6/jcsample.c b/renderer/jpeg-6/jcsample.c new file mode 100644 index 000000000..bf0fb46bb --- /dev/null +++ b/renderer/jpeg-6/jcsample.c @@ -0,0 +1,519 @@ +/* + * jcsample.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains downsampling routines. + * + * Downsampling input data is counted in "row groups". A row group + * is defined to be max_v_samp_factor pixel rows of each component, + * from which the downsampler produces v_samp_factor sample rows. + * A single row group is processed in each call to the downsampler module. + * + * The downsampler is responsible for edge-expansion of its output data + * to fill an integral number of DCT blocks horizontally. The source buffer + * may be modified if it is helpful for this purpose (the source buffer is + * allocated wide enough to correspond to the desired output width). + * The caller (the prep controller) is responsible for vertical padding. + * + * The downsampler may request "context rows" by setting need_context_rows + * during startup. In this case, the input arrays will contain at least + * one row group's worth of pixels above and below the passed-in data; + * the caller will create dummy rows at image top and bottom by replicating + * the first or last real pixel row. + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + * + * The downsampling algorithm used here is a simple average of the source + * pixels covered by the output pixel. The hi-falutin sampling literature + * refers to this as a "box filter". In general the characteristics of a box + * filter are not very good, but for the specific cases we normally use (1:1 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + * nearly so bad. If you intend to use other sampling ratios, you'd be well + * advised to improve this code. + * + * A simple input-smoothing capability is provided. This is mainly intended + * for cleaning up color-dithered GIF input files (if you find it inadequate, + * we suggest using an external filtering program such as pnmconvol). When + * enabled, each input pixel P is replaced by a weighted sum of itself and its + * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + * where SF = (smoothing_factor / 1024). + * Currently, smoothing is only supported for 2h2v sampling factors. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to downsample a single component */ +typedef JMETHOD(void, downsample1_ptr, + (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data)); + +/* Private subobject */ + +typedef struct { + struct jpeg_downsampler pub; /* public fields */ + + /* Downsampling method pointers, one per component */ + downsample1_ptr methods[MAX_COMPONENTS]; +} my_downsampler; + +typedef my_downsampler * my_downsample_ptr; + + +/* + * Initialize for a downsampling pass. + */ + +METHODDEF void +start_pass_downsample (j_compress_ptr cinfo) +{ + /* no work for now */ +} + + +/* + * Expand a component horizontally from width input_cols to width output_cols, + * by duplicating the rightmost samples. + */ + +LOCAL void +expand_right_edge (JSAMPARRAY image_data, int num_rows, + JDIMENSION input_cols, JDIMENSION output_cols) +{ + register JSAMPROW ptr; + register JSAMPLE pixval; + register int count; + int row; + int numcols = (int) (output_cols - input_cols); + + if (numcols > 0) { + for (row = 0; row < num_rows; row++) { + ptr = image_data[row] + input_cols; + pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ + for (count = numcols; count > 0; count--) + *ptr++ = pixval; + } + } +} + + +/* + * Do downsampling for a whole row group (all components). + * + * In this version we simply downsample each component independently. + */ + +METHODDEF void +sep_downsample (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) +{ + my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; + int ci; + jpeg_component_info * compptr; + JSAMPARRAY in_ptr, out_ptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + in_ptr = input_buf[ci] + in_row_index; + out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); + (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); + } +} + + +/* + * Downsample pixel values of a single component. + * One row group is processed per call. + * This version handles arbitrary integral sampling ratios, without smoothing. + * Note that this version is not actually used for customary sampling ratios. + */ + +METHODDEF void +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; + JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JSAMPROW inptr, outptr; + INT32 outvalue; + + h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; + v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; + numpix = h_expand * v_expand; + numpix2 = numpix/2; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * h_expand); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + for (outcol = 0, outcol_h = 0; outcol < output_cols; + outcol++, outcol_h += h_expand) { + outvalue = 0; + for (v = 0; v < v_expand; v++) { + inptr = input_data[inrow+v] + outcol_h; + for (h = 0; h < h_expand; h++) { + outvalue += (INT32) GETJSAMPLE(*inptr++); + } + } + *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); + } + inrow += v_expand; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * without smoothing. + */ + +METHODDEF void +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + /* Copy the data */ + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo->max_v_samp_factor, cinfo->image_width); + /* Edge-expand */ + expand_right_edge(output_data, cinfo->max_v_samp_factor, + cinfo->image_width, compptr->width_in_blocks * DCTSIZE); +} + + +/* + * Downsample pixel values of a single component. + * This version handles the common case of 2:1 horizontal and 1:1 vertical, + * without smoothing. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF void +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + bias = 0; /* bias = 0,1,0,1,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + + bias) >> 1); + bias ^= 1; /* 0=>1, 1=>0 */ + inptr += 2; + } + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * without smoothing. + */ + +METHODDEF void +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + bias = 1; /* bias = 1,2,1,2,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + + bias) >> 2); + bias ^= 3; /* 1=>2, 2=>1 */ + inptr0 += 2; inptr1 += 2; + } + inrow += 2; + } +} + + +#ifdef INPUT_SMOOTHING_SUPPORTED + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * with smoothing. One row of context is required. + */ + +METHODDEF void +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols * 2); + + /* We don't bother to form the individual "smoothed" input pixel values; + * we can directly compute the output which is the average of the four + * smoothed values. Each of the four member pixels contributes a fraction + * (1-8*SF) to its own smoothed image and a fraction SF to each of the three + * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + * output. The four corner-adjacent neighbor pixels contribute a fraction + * SF to just one smoothed pixel, or SF/4 to the final output; while the + * eight edge-adjacent neighbors contribute SF to each of two smoothed + * pixels, or SF/2 overall. In order to use integer arithmetic, these + * factors are scaled by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ + neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + above_ptr = input_data[inrow-1]; + below_ptr = input_data[inrow+2]; + + /* Special case for first column: pretend column -1 is same as column 0 */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); + neighsum += neighsum; + neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + /* sum of pixels directly mapped to this output element */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + /* sum of edge-neighbor pixels */ + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); + /* The edge-neighbors count twice as much as corner-neighbors */ + neighsum += neighsum; + /* Add in the corner-neighbors */ + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); + /* form final output scaled up by 2^16 */ + membersum = membersum * memberscale + neighsum * neighscale; + /* round, descale and output it */ + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); + neighsum += neighsum; + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + inrow += 2; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * with smoothing. One row of context is required. + */ + +METHODDEF void +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + int colsum, lastcolsum, nextcolsum; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols); + + /* Each of the eight neighbor pixels contributes a fraction SF to the + * smoothed pixel, while the main pixel contributes (1-8*SF). In order + * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ + neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + above_ptr = input_data[outrow-1]; + below_ptr = input_data[outrow+1]; + + /* Special case for first column */ + colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + + GETJSAMPLE(*inptr); + membersum = GETJSAMPLE(*inptr++); + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = colsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + membersum = GETJSAMPLE(*inptr++); + above_ptr++; below_ptr++; + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + colsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + } +} + +#endif /* INPUT_SMOOTHING_SUPPORTED */ + + +/* + * Module initialization routine for downsampling. + * Note that we must select a routine for each component. + */ + +GLOBAL void +jinit_downsampler (j_compress_ptr cinfo) +{ + my_downsample_ptr downsample; + int ci; + jpeg_component_info * compptr; + boolean smoothok = TRUE; + + downsample = (my_downsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_downsampler)); + cinfo->downsample = (struct jpeg_downsampler *) downsample; + downsample->pub.start_pass = start_pass_downsample; + downsample->pub.downsample = sep_downsample; + downsample->pub.need_context_rows = FALSE; + + if (cinfo->CCIR601_sampling) + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* Verify we can handle the sampling factors, and set up method pointers */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = fullsize_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = fullsize_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { + smoothok = FALSE; + downsample->methods[ci] = h2v1_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = h2v2_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = h2v2_downsample; + } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && + (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { + smoothok = FALSE; + downsample->methods[ci] = int_downsample; + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + } + +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor && !smoothok) + TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); +#endif +} diff --git a/renderer/jpeg-6/jctrans.c b/renderer/jpeg-6/jctrans.c new file mode 100644 index 000000000..8fc53b19d --- /dev/null +++ b/renderer/jpeg-6/jctrans.c @@ -0,0 +1,371 @@ +/* + * jctrans.c + * + * Copyright (C) 1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding compression, + * that is, writing raw DCT coefficient arrays to an output JPEG file. + * The routines in jcapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL void transencode_master_selection + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); +LOCAL void transencode_coef_controller + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); + + +/* + * Compression initialization for writing raw-coefficient data. + * Before calling this, all parameters and a data destination must be set up. + * Call jpeg_finish_compress() to actually write the data. + * + * The number of passed virtual arrays must match cinfo->num_components. + * Note that the virtual arrays need not be filled or even realized at + * the time write_coefficients is called; indeed, if the virtual arrays + * were requested from this compression object's memory manager, they + * typically will be realized during this routine and filled afterwards. + */ + +GLOBAL void +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Mark all tables to be written */ + jpeg_suppress_tables(cinfo, FALSE); + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + transencode_master_selection(cinfo, coef_arrays); + /* Wait for jpeg_finish_compress() call */ + cinfo->next_scanline = 0; /* so jpeg_write_marker works */ + cinfo->global_state = CSTATE_WRCOEFS; +} + + +/* + * Initialize the compression object with default parameters, + * then copy from the source object all parameters needed for lossless + * transcoding. Parameters that can be varied without loss (such as + * scan script and Huffman optimization) are left in their default states. + */ + +GLOBAL void +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo) +{ + JQUANT_TBL ** qtblptr; + jpeg_component_info *incomp, *outcomp; + JQUANT_TBL *c_quant, *slot_quant; + int tblno, ci, coefi; + + /* Safety check to ensure start_compress not called yet. */ + if (dstinfo->global_state != CSTATE_START) + ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); + /* Copy fundamental image dimensions */ + dstinfo->image_width = srcinfo->image_width; + dstinfo->image_height = srcinfo->image_height; + dstinfo->input_components = srcinfo->num_components; + dstinfo->in_color_space = srcinfo->jpeg_color_space; + /* Initialize all parameters to default values */ + jpeg_set_defaults(dstinfo); + /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + * Fix it to get the right header markers for the image colorspace. + */ + jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); + dstinfo->data_precision = srcinfo->data_precision; + dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; + /* Copy the source's quantization tables. */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { + qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); + MEMCOPY((*qtblptr)->quantval, + srcinfo->quant_tbl_ptrs[tblno]->quantval, + SIZEOF((*qtblptr)->quantval)); + (*qtblptr)->sent_table = FALSE; + } + } + /* Copy the source's per-component info. + * Note we assume jpeg_set_defaults has allocated the dest comp_info array. + */ + dstinfo->num_components = srcinfo->num_components; + if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) + ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, + MAX_COMPONENTS); + for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; + ci < dstinfo->num_components; ci++, incomp++, outcomp++) { + outcomp->component_id = incomp->component_id; + outcomp->h_samp_factor = incomp->h_samp_factor; + outcomp->v_samp_factor = incomp->v_samp_factor; + outcomp->quant_tbl_no = incomp->quant_tbl_no; + /* Make sure saved quantization table for component matches the qtable + * slot. If not, the input file re-used this qtable slot. + * IJG encoder currently cannot duplicate this. + */ + tblno = outcomp->quant_tbl_no; + if (tblno < 0 || tblno >= NUM_QUANT_TBLS || + srcinfo->quant_tbl_ptrs[tblno] == NULL) + ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); + slot_quant = srcinfo->quant_tbl_ptrs[tblno]; + c_quant = incomp->quant_table; + if (c_quant != NULL) { + for (coefi = 0; coefi < DCTSIZE2; coefi++) { + if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) + ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); + } + } + /* Note: we do not copy the source's Huffman table assignments; + * instead we rely on jpeg_set_colorspace to have made a suitable choice. + */ + } +} + + +/* + * Master selection of compression modules for transcoding. + * This substitutes for jcinit.c's initialization of the full compressor. + */ + +LOCAL void +transencode_master_selection (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + /* Although we don't actually use input_components for transcoding, + * jcmaster.c's initial_setup will complain if input_components is 0. + */ + cinfo->input_components = 1; + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, TRUE /* transcode only */); + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* We need a special coefficient buffer controller. */ + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} + + +/* + * The rest of this file is a special implementation of the coefficient + * buffer controller. This is similar to jccoefct.c, but it handles only + * output from presupplied virtual arrays. Furthermore, we generate any + * dummy padding blocks on-the-fly rather than expecting them to be present + * in the arrays. + */ + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* Virtual block array for each component. */ + jvirt_barray_ptr * whole_image; + + /* Workspace for constructing dummy blocks at right/bottom edges. */ + JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +LOCAL void +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + if (pass_mode != JBUF_CRANK_DEST) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); +} + + +/* + * Process some data. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF boolean +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, blockcnt; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yindex+yoffset < compptr->last_row_height) { + /* Fill in pointers to real blocks in this row */ + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < blockcnt; xindex++) + MCU_buffer[blkn++] = buffer_ptr++; + } else { + /* At bottom of image, need a whole row of dummy blocks */ + xindex = 0; + } + /* Fill in any dummy blocks needed in this row. + * Dummy blocks are filled in the same way as in jccoefct.c: + * all zeroes in the AC entries, DC entries equal to previous + * block's DC value. The init routine has already zeroed the + * AC entries, so we need only set the DC entries correctly. + */ + for (; xindex < compptr->MCU_width; xindex++) { + MCU_buffer[blkn] = coef->dummy_buffer[blkn]; + MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; + blkn++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +/* + * Initialize coefficient buffer controller. + * + * Each passed coefficient array must be the right size for that + * coefficient: width_in_blocks wide and height_in_blocks high, + * with unitheight at least v_samp_factor. + */ + +LOCAL void +transencode_coef_controller (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + my_coef_ptr coef; + JBLOCKROW buffer; + int i; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + coef->pub.compress_data = compress_output; + + /* Save pointer to virtual arrays */ + coef->whole_image = coef_arrays; + + /* Allocate and pre-zero space for dummy DCT blocks. */ + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->dummy_buffer[i] = buffer + i; + } +} diff --git a/renderer/jpeg-6/jdapimin.c b/renderer/jpeg-6/jdapimin.c new file mode 100644 index 000000000..d56818762 --- /dev/null +++ b/renderer/jpeg-6/jdapimin.c @@ -0,0 +1,398 @@ +/* + * jdapimin.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c. But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG decompression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL void +jpeg_create_decompress (j_decompress_ptr cinfo) +{ + int i; + + /* For debugging purposes, zero the whole master structure. + * But error manager pointer is already there, so save and restore it. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); + cinfo->err = err; + } + cinfo->is_decompressor = TRUE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->src = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + /* Initialize marker processor so application can override methods + * for COM, APPn markers before calling jpeg_read_header. + */ + jinit_marker_reader(cinfo); + + /* And initialize the overall input controller. */ + jinit_input_controller(cinfo); + + /* OK, I'm ready */ + cinfo->global_state = DSTATE_START; +} + + +/* + * Destruction of a JPEG decompression object + */ + +GLOBAL void +jpeg_destroy_decompress (j_decompress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG decompression operation, + * but don't destroy the object itself. + */ + +GLOBAL void +jpeg_abort_decompress (j_decompress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Install a special processing method for COM or APPn markers. + */ + +GLOBAL void +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine) +{ + if (marker_code == JPEG_COM) + cinfo->marker->process_COM = routine; + else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15) + cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine; + else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} + + +/* + * Set default decompression parameters. + */ + +LOCAL void +default_decompress_parms (j_decompress_ptr cinfo) +{ + /* Guess the input colorspace, and set output colorspace accordingly. */ + /* (Wish JPEG committee had provided a real way to specify this...) */ + /* Note application may override our guesses. */ + switch (cinfo->num_components) { + case 1: + cinfo->jpeg_color_space = JCS_GRAYSCALE; + cinfo->out_color_space = JCS_GRAYSCALE; + break; + + case 3: + if (cinfo->saw_JFIF_marker) { + cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ + } else if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_RGB; + break; + case 1: + cinfo->jpeg_color_space = JCS_YCbCr; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + break; + } + } else { + /* Saw no special markers, try to guess from the component IDs */ + int cid0 = cinfo->comp_info[0].component_id; + int cid1 = cinfo->comp_info[1].component_id; + int cid2 = cinfo->comp_info[2].component_id; + + if (cid0 == 1 && cid1 == 2 && cid2 == 3) + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ + else { + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + } + } + /* Always guess RGB is proper output colorspace. */ + cinfo->out_color_space = JCS_RGB; + break; + + case 4: + if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_CMYK; + break; + case 2: + cinfo->jpeg_color_space = JCS_YCCK; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ + break; + } + } else { + /* No special markers, assume straight CMYK. */ + cinfo->jpeg_color_space = JCS_CMYK; + } + cinfo->out_color_space = JCS_CMYK; + break; + + default: + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->out_color_space = JCS_UNKNOWN; + break; + } + + /* Set defaults for other decompression parameters. */ + cinfo->scale_num = 1; /* 1:1 scaling */ + cinfo->scale_denom = 1; + cinfo->output_gamma = 1.0; + cinfo->buffered_image = FALSE; + cinfo->raw_data_out = FALSE; + cinfo->dct_method = JDCT_DEFAULT; + cinfo->do_fancy_upsampling = TRUE; + cinfo->do_block_smoothing = TRUE; + cinfo->quantize_colors = FALSE; + /* We set these in case application only sets quantize_colors. */ + cinfo->dither_mode = JDITHER_FS; +#ifdef QUANT_2PASS_SUPPORTED + cinfo->two_pass_quantize = TRUE; +#else + cinfo->two_pass_quantize = FALSE; +#endif + cinfo->desired_number_of_colors = 256; + cinfo->colormap = NULL; + /* Initialize for no mode change in buffered-image mode. */ + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; +} + + +/* + * Decompression startup: read start of JPEG datastream to see what's there. + * Need only initialize JPEG object and supply a data source before calling. + * + * This routine will read as far as the first SOS marker (ie, actual start of + * compressed data), and will save all tables and parameters in the JPEG + * object. It will also initialize the decompression parameters to default + * values, and finally return JPEG_HEADER_OK. On return, the application may + * adjust the decompression parameters and then call jpeg_start_decompress. + * (Or, if the application only wanted to determine the image parameters, + * the data need not be decompressed. In that case, call jpeg_abort or + * jpeg_destroy to release any temporary space.) + * If an abbreviated (tables only) datastream is presented, the routine will + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + * re-use the JPEG object to read the abbreviated image datastream(s). + * It is unnecessary (but OK) to call jpeg_abort in this case. + * The JPEG_SUSPENDED return code only occurs if the data source module + * requests suspension of the decompressor. In this case the application + * should load more source data and then re-call jpeg_read_header to resume + * processing. + * If a non-suspending data source is used and require_image is TRUE, then the + * return code need not be inspected since only JPEG_HEADER_OK is possible. + * + * This routine is now just a front end to jpeg_consume_input, with some + * extra error checking. + */ + +GLOBAL int +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) +{ + int retcode; + + if (cinfo->global_state != DSTATE_START && + cinfo->global_state != DSTATE_INHEADER) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + retcode = jpeg_consume_input(cinfo); + + switch (retcode) { + case JPEG_REACHED_SOS: + retcode = JPEG_HEADER_OK; + break; + case JPEG_REACHED_EOI: + if (require_image) /* Complain if application wanted an image */ + ERREXIT(cinfo, JERR_NO_IMAGE); + /* Reset to start state; it would be safer to require the application to + * call jpeg_abort, but we can't change it now for compatibility reasons. + * A side effect is to free any temporary memory (there shouldn't be any). + */ + jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ + retcode = JPEG_HEADER_TABLES_ONLY; + break; + case JPEG_SUSPENDED: + /* no work */ + break; + } + + return retcode; +} + + +/* + * Consume data in advance of what the decompressor requires. + * This can be called at any time once the decompressor object has + * been created and a data source has been set up. + * + * This routine is essentially a state machine that handles a couple + * of critical state-transition actions, namely initial setup and + * transition from header scanning to ready-for-start_decompress. + * All the actual input is done via the input controller's consume_input + * method. + */ + +GLOBAL int +jpeg_consume_input (j_decompress_ptr cinfo) +{ + int retcode = JPEG_SUSPENDED; + + /* NB: every possible DSTATE value should be listed in this switch */ + switch (cinfo->global_state) { + case DSTATE_START: + /* Start-of-datastream actions: reset appropriate modules */ + (*cinfo->inputctl->reset_input_controller) (cinfo); + /* Initialize application's data source module */ + (*cinfo->src->init_source) (cinfo); + cinfo->global_state = DSTATE_INHEADER; + /*FALLTHROUGH*/ + case DSTATE_INHEADER: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ + /* Set up default parameters based on header data */ + default_decompress_parms(cinfo); + /* Set global state: ready for start_decompress */ + cinfo->global_state = DSTATE_READY; + } + break; + case DSTATE_READY: + /* Can't advance past first SOS until start_decompress is called */ + retcode = JPEG_REACHED_SOS; + break; + case DSTATE_PRELOAD: + case DSTATE_PRESCAN: + case DSTATE_SCANNING: + case DSTATE_RAW_OK: + case DSTATE_BUFIMAGE: + case DSTATE_BUFPOST: + case DSTATE_STOPPING: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + break; + default: + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + return retcode; +} + + +/* + * Have we finished reading the input file? + */ + +GLOBAL boolean +jpeg_input_complete (j_decompress_ptr cinfo) +{ + /* Check for valid jpeg object */ + if (cinfo->global_state < DSTATE_START || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->eoi_reached; +} + + +/* + * Is there more than one scan? + */ + +GLOBAL boolean +jpeg_has_multiple_scans (j_decompress_ptr cinfo) +{ + /* Only valid after jpeg_read_header completes */ + if (cinfo->global_state < DSTATE_READY || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->has_multiple_scans; +} + + +/* + * Finish JPEG decompression. + * + * This will normally just verify the file trailer and release temp storage. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_finish_decompress (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { + /* Terminate final pass of non-buffered mode */ + if (cinfo->output_scanline < cinfo->output_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state == DSTATE_BUFIMAGE) { + /* Finishing after a buffered-image operation */ + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state != DSTATE_STOPPING) { + /* STOPPING = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read until EOI */ + while (! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + /* Do final cleanup */ + (*cinfo->src->term_source) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); + return TRUE; +} diff --git a/renderer/jpeg-6/jdapistd.c b/renderer/jpeg-6/jdapistd.c new file mode 100644 index 000000000..e36f25c27 --- /dev/null +++ b/renderer/jpeg-6/jdapistd.c @@ -0,0 +1,275 @@ +/* + * jdapistd.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-decompression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); + + +/* + * Decompression initialization. + * jpeg_read_header must be completed before calling this. + * + * If a multipass operating mode was selected, this will do all but the + * last pass, and thus may take a great deal of time. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_start_decompress (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize master control, select active modules */ + jinit_master_decompress(cinfo); + if (cinfo->buffered_image) { + /* No more work here; expecting jpeg_start_output next */ + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; + } + cinfo->global_state = DSTATE_PRELOAD; + } + if (cinfo->global_state == DSTATE_PRELOAD) { + /* If file has multiple scans, absorb them all into the coef buffer */ + if (cinfo->inputctl->has_multiple_scans) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return FALSE; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* jdmaster underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + } + cinfo->output_scan_number = cinfo->input_scan_number; + } else if (cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any dummy output passes, and set up for the final pass */ + return output_pass_setup(cinfo); +} + + +/* + * Set up for an output pass, and perform any dummy pass(es) needed. + * Common subroutine for jpeg_start_decompress and jpeg_start_output. + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. + * Exit: If done, returns TRUE and sets global_state for proper output mode. + * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. + */ + +LOCAL boolean +output_pass_setup (j_decompress_ptr cinfo) +{ + if (cinfo->global_state != DSTATE_PRESCAN) { + /* First call: do pass setup */ + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; + cinfo->global_state = DSTATE_PRESCAN; + } + /* Loop over any required dummy passes */ + while (cinfo->master->is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Crank through the dummy pass */ + while (cinfo->output_scanline < cinfo->output_height) { + JDIMENSION last_scanline; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* Process some data */ + last_scanline = cinfo->output_scanline; + (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, + &cinfo->output_scanline, (JDIMENSION) 0); + if (cinfo->output_scanline == last_scanline) + return FALSE; /* No progress made, must suspend */ + } + /* Finish up dummy pass, and set up for another one */ + (*cinfo->master->finish_output_pass) (cinfo); + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } + /* Ready for application to drive output pass through + * jpeg_read_scanlines or jpeg_read_raw_data. + */ + cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; + return TRUE; +} + + +/* + * Read some scanlines of data from the JPEG decompressor. + * + * The return value will be the number of lines actually read. + * This may be less than the number requested in several cases, + * including bottom of image, data source suspension, and operating + * modes that emit multiple scanlines at a time. + * + * Note: we warn about excess calls to jpeg_read_scanlines() since + * this likely signals an application programmer error. However, + * an oversize buffer (max_lines > scanlines remaining) is not an error. + */ + +GLOBAL JDIMENSION +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION max_lines) +{ + JDIMENSION row_ctr; + + if (cinfo->global_state != DSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Process some data */ + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); + cinfo->output_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to read raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL JDIMENSION +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION max_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != DSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Verify that at least one iMCU row can be returned. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Decompress directly into user's buffer. */ + if (! (*cinfo->coef->decompress_data) (cinfo, data)) + return 0; /* suspension forced, can do nothing more */ + + /* OK, we processed one iMCU row. */ + cinfo->output_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} + + +/* Additional entry points for buffered-image mode. */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Initialize for an output pass in buffered-image mode. + */ + +GLOBAL boolean +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) +{ + if (cinfo->global_state != DSTATE_BUFIMAGE && + cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Limit scan number to valid range */ + if (scan_number <= 0) + scan_number = 1; + if (cinfo->inputctl->eoi_reached && + scan_number > cinfo->input_scan_number) + scan_number = cinfo->input_scan_number; + cinfo->output_scan_number = scan_number; + /* Perform any dummy output passes, and set up for the real pass */ + return output_pass_setup(cinfo); +} + + +/* + * Finish up after an output pass in buffered-image mode. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_finish_output (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { + /* Terminate this pass. */ + /* We do not require the whole pass to have been completed. */ + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_BUFPOST; + } else if (cinfo->global_state != DSTATE_BUFPOST) { + /* BUFPOST = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read markers looking for SOS or EOI */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/renderer/jpeg-6/jdatadst.c b/renderer/jpeg-6/jdatadst.c new file mode 100644 index 000000000..08c4dafd5 --- /dev/null +++ b/renderer/jpeg-6/jdatadst.c @@ -0,0 +1,151 @@ +/* + * jdatadst.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains compression data destination routines for the case of + * emitting JPEG data to a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * destination manager. + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of + * JOCTETs into 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +METHODDEF void +init_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +METHODDEF boolean +empty_output_buffer (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != + (size_t) OUTPUT_BUF_SIZE) + ERREXIT(cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF void +term_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + fflush(dest->outfile); + /* Make sure we wrote the output file OK */ + if (ferror(dest->outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +GLOBAL void +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) +{ + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} diff --git a/renderer/jpeg-6/jdatasrc.c b/renderer/jpeg-6/jdatasrc.c new file mode 100644 index 000000000..0bf786603 --- /dev/null +++ b/renderer/jpeg-6/jdatasrc.c @@ -0,0 +1,204 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + unsigned char *infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF void +init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF boolean +fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); + + src->infile += INPUT_BUF_SIZE; + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = INPUT_BUF_SIZE; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF void +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF void +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL void +jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} diff --git a/renderer/jpeg-6/jdcoefct.c b/renderer/jpeg-6/jdcoefct.c new file mode 100644 index 000000000..ba153f5bd --- /dev/null +++ b/renderer/jpeg-6/jdcoefct.c @@ -0,0 +1,725 @@ +/* + * jdcoefct.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* Block smoothing is only applicable for progressive JPEG, so: */ +#ifndef D_PROGRESSIVE_SUPPORTED +#undef BLOCK_SMOOTHING_SUPPORTED +#endif + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_coef_controller pub; /* public fields */ + + /* These variables keep track of the current location of the input side. */ + /* cinfo->input_iMCU_row is also used for this. */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* The output side's location is represented by cinfo->output_iMCU_row. */ + + /* In single-pass modes, it's sufficient to buffer just one MCU. + * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * and let the entropy decoder write into that workspace each time. + * (On 80x86, the workspace is FAR even though it's not really very big; + * this is to keep the module interfaces unchanged when a large coefficient + * buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays; it is used only by the input side. + */ + JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +#endif + +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* When doing block smoothing, we latch coefficient Al values here */ + int * coef_bits_latch; +#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ +#endif +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* Forward declarations */ +METHODDEF int decompress_onepass + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +METHODDEF int decompress_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif +#ifdef BLOCK_SMOOTHING_SUPPORTED +LOCAL boolean smoothing_ok JPP((j_decompress_ptr cinfo)); +METHODDEF int decompress_smooth_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL void +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->MCU_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF void +start_input_pass (j_decompress_ptr cinfo) +{ + cinfo->input_iMCU_row = 0; + start_iMCU_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF void +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* If multipass, check to see whether to use block smoothing on this pass */ + if (coef->pub.coef_arrays != NULL) { + if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) + coef->pub.decompress_data = decompress_smooth_data; + else + coef->pub.decompress_data = decompress_data; + } +#endif + cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the single-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Input and output must run in lockstep since we have only a one-MCU buffer. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + * For single pass, this is the same as the components in the scan. + */ + +METHODDEF int +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, useful_width; + JSAMPARRAY output_ptr; + JDIMENSION start_col, output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Loop to process as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ + jzero_far((void FAR *) coef->MCU_buffer[0], + (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + /* Determine where data should go in output_buf and do the IDCT thing. + * We skip dummy blocks at the right and bottom edges (but blkn gets + * incremented past them!). Note the inner loop relies on having + * allocated the MCU_buffer[] blocks sequentially. + */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) { + blkn += compptr->MCU_blocks; + continue; + } + inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; + useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size; + start_col = MCU_col_num * compptr->MCU_sample_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (cinfo->input_iMCU_row < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + output_col = start_col; + for (xindex = 0; xindex < useful_width; xindex++) { + (*inverse_DCT) (cinfo, compptr, + (JCOEFPTR) coef->MCU_buffer[blkn+xindex], + output_ptr, output_col); + output_col += compptr->DCT_scaled_size; + } + } + blkn += compptr->MCU_width; + output_ptr += compptr->DCT_scaled_size; + } + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + cinfo->output_iMCU_row++; + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF int +dummy_consume_data (j_decompress_ptr cinfo) +{ + return JPEG_SUSPENDED; /* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image coefficient buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor block rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF int +consume_data (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + cinfo->input_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Note: entropy decoder expects buffer to be zeroed, + * but this is handled automatically by the memory manager + * because we requested a pre-zeroed array. + */ + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to fetch the MCU. */ + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Decompress and return some data in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF int +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num; + int ci, block_row, block_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number < cinfo->output_scan_number || + (cinfo->input_scan_number == cinfo->output_scan_number && + cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + cinfo->output_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + output_col = 0; + for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, + output_ptr, output_col); + buffer_ptr++; + output_col += compptr->DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +#ifdef BLOCK_SMOOTHING_SUPPORTED + +/* + * This code applies interblock smoothing as described by section K.8 + * of the JPEG standard: the first 5 AC coefficients are estimated from + * the DC values of a DCT block and its 8 neighboring blocks. + * We apply smoothing only for progressive JPEG decoding, and only if + * the coefficients it can estimate are not yet known to full precision. + */ + +/* + * Determine whether block smoothing is applicable and safe. + * We also latch the current states of the coef_bits[] entries for the + * AC coefficients; otherwise, if the input side of the decompressor + * advances into a new scan, we might think the coefficients are known + * more accurately than they really are. + */ + +LOCAL boolean +smoothing_ok (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + boolean smoothing_useful = FALSE; + int ci, coefi; + jpeg_component_info *compptr; + JQUANT_TBL * qtable; + int * coef_bits; + int * coef_bits_latch; + + if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) + return FALSE; + + /* Allocate latch area if not already done */ + if (coef->coef_bits_latch == NULL) + coef->coef_bits_latch = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * + (SAVED_COEFS * SIZEOF(int))); + coef_bits_latch = coef->coef_bits_latch; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* All components' quantization values must already be latched. */ + if ((qtable = compptr->quant_table) == NULL) + return FALSE; + /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ + for (coefi = 0; coefi <= 5; coefi++) { + if (qtable->quantval[coefi] == 0) + return FALSE; + } + /* DC values must be at least partly known for all components. */ + coef_bits = cinfo->coef_bits[ci]; + if (coef_bits[0] < 0) + return FALSE; + /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ + for (coefi = 1; coefi <= 5; coefi++) { + coef_bits_latch[coefi] = coef_bits[coefi]; + if (coef_bits[coefi] != 0) + smoothing_useful = TRUE; + } + coef_bits_latch += SAVED_COEFS; + } + + return smoothing_useful; +} + + +/* + * Variant of decompress_data for use when doing block smoothing. + */ + +METHODDEF int +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num, last_block_column; + int ci, block_row, block_rows, access_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr, prev_block_row, next_block_row; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + boolean first_row, last_row; + JBLOCK workspace; + int *coef_bits; + JQUANT_TBL *quanttbl; + INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; + int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; + int Al, pred; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if (cinfo->input_scan_number == cinfo->output_scan_number) { + /* If input is working on current scan, we ordinarily want it to + * have completed the current row. But if input scan is DC, + * we want it to keep one row ahead so that next block row's DC + * values are up to date. + */ + JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; + if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) + break; + } + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) { + block_rows = compptr->v_samp_factor; + access_rows = block_rows * 2; /* this and next iMCU row */ + last_row = FALSE; + } else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + access_rows = block_rows; /* this iMCU row only */ + last_row = TRUE; + } + /* Align the virtual buffer for this component. */ + if (cinfo->output_iMCU_row > 0) { + access_rows += compptr->v_samp_factor; /* prior iMCU row too */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, + (JDIMENSION) access_rows, FALSE); + buffer += compptr->v_samp_factor; /* point to current iMCU row */ + first_row = FALSE; + } else { + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); + first_row = TRUE; + } + /* Fetch component-dependent info */ + coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + quanttbl = compptr->quant_table; + Q00 = quanttbl->quantval[0]; + Q01 = quanttbl->quantval[1]; + Q10 = quanttbl->quantval[2]; + Q20 = quanttbl->quantval[3]; + Q11 = quanttbl->quantval[4]; + Q02 = quanttbl->quantval[5]; + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + if (first_row && block_row == 0) + prev_block_row = buffer_ptr; + else + prev_block_row = buffer[block_row-1]; + if (last_row && block_row == block_rows-1) + next_block_row = buffer_ptr; + else + next_block_row = buffer[block_row+1]; + /* We fetch the surrounding DC values using a sliding-register approach. + * Initialize all nine here so as to do the right thing on narrow pics. + */ + DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; + DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; + DC7 = DC8 = DC9 = (int) next_block_row[0][0]; + output_col = 0; + last_block_column = compptr->width_in_blocks - 1; + for (block_num = 0; block_num <= last_block_column; block_num++) { + /* Fetch current DCT block into workspace so we can modify it. */ + jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); + /* Update DC values */ + if (block_num < last_block_column) { + DC3 = (int) prev_block_row[1][0]; + DC6 = (int) buffer_ptr[1][0]; + DC9 = (int) next_block_row[1][0]; + } + /* Compute coefficient estimates per K.8. + * An estimate is applied only if coefficient is still zero, + * and is not known to be fully accurate. + */ + /* AC01 */ + if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { + num = 36 * Q00 * (DC4 - DC6); + if (num >= 0) { + pred = (int) (((Q01<<7) + num) / (Q01<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q10<<7) + num) / (Q10<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q20<<7) + num) / (Q20<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q11<<7) + num) / (Q11<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q02<<7) + num) / (Q02<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* BLOCK_SMOOTHING_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL void +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_d_coef_controller *) coef; + coef->pub.start_input_pass = start_input_pass; + coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED + coef->coef_bits_latch = NULL; +#endif + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + /* Note we ask for a pre-zeroed array. */ + int ci, access_rows; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + access_rows = compptr->v_samp_factor; +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* If block smoothing could be used, need a bigger window */ + if (cinfo->progressive_mode) + access_rows *= 3; +#endif + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) access_rows); + } + coef->pub.consume_data = consume_data; + coef->pub.decompress_data = decompress_data; + coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->pub.consume_data = dummy_consume_data; + coef->pub.decompress_data = decompress_onepass; + coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ + } +} diff --git a/renderer/jpeg-6/jdcolor.c b/renderer/jpeg-6/jdcolor.c new file mode 100644 index 000000000..b2bdf6ee6 --- /dev/null +++ b/renderer/jpeg-6/jdcolor.c @@ -0,0 +1,367 @@ +/* + * jdcolor.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_deconverter pub; /* public fields */ + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ +} my_color_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** YCbCr -> RGB conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less CENTERJSAMPLE. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + */ + +LOCAL void +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + int i; + INT32 x; + SHIFT_TEMPS + + cconvert->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + cconvert->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + cconvert->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Convert some rows of samples to the output colorspace. + * + * Note that we change from noninterleaved, one-plane-per-component format + * to interleaved-pixel format. The output buffer is therefore three times + * as wide as the input buffer. + * A starting row offset is provided only for the input buffer. The caller + * can easily adjust the passed output_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF void +ycc_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/**************** Cases other than YCbCr -> RGB **************/ + + +/* + * Color conversion for no colorspace change: just copy the data, + * converting from separate-planes to interleaved representation. + */ + +METHODDEF void +null_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION count; + register int num_components = cinfo->num_components; + JDIMENSION num_cols = cinfo->output_width; + int ci; + + while (--num_rows >= 0) { + for (ci = 0; ci < num_components; ci++) { + inptr = input_buf[ci][input_row]; + outptr = output_buf[0] + ci; + for (count = num_cols; count > 0; count--) { + *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ + outptr += num_components; + } + } + input_row++; + output_buf++; + } +} + + +/* + * Color conversion for grayscale: just copy the data. + * This also works for YCbCr -> grayscale conversion, in which + * we just copy the Y (luminance) component and ignore chrominance. + */ + +METHODDEF void +grayscale_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, + num_rows, cinfo->output_width); +} + + +/* + * Adobe-style YCCK->CMYK conversion. + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + * conversion as above, while passing K (black) unchanged. + * We assume build_ycc_rgb_table has been called. + */ + +METHODDEF void +ycck_cmyk_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2, inptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + inptr3 = input_buf[3][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ + outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS)))]; + outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ + /* K passes through unchanged */ + outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr += 4; + } + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF void +start_pass_dcolor (j_decompress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for output colorspace conversion. + */ + +GLOBAL void +jinit_color_deconverter (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + int ci; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_deconverter)); + cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; + cconvert->pub.start_pass = start_pass_dcolor; + + /* Make sure num_components agrees with jpeg_color_space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_RGB: + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->num_components < 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + } + + /* Set out_color_components and conversion method based on requested space. + * Also clear the component_needed flags for any unused components, + * so that earlier pipeline stages can avoid useless computation. + */ + + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + if (cinfo->jpeg_color_space == JCS_GRAYSCALE || + cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = grayscale_convert; + /* For color->grayscale conversion, only the Y (0) component is needed */ + for (ci = 1; ci < cinfo->num_components; ci++) + cinfo->comp_info[ci].component_needed = FALSE; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + cinfo->out_color_components = RGB_PIXELSIZE; + if (cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + cinfo->out_color_components = 4; + if (cinfo->jpeg_color_space == JCS_YCCK) { + cconvert->pub.color_convert = ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_CMYK) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: + /* Permit null conversion to same output space */ + if (cinfo->out_color_space == cinfo->jpeg_color_space) { + cinfo->out_color_components = cinfo->num_components; + cconvert->pub.color_convert = null_convert; + } else /* unsupported non-null conversion */ + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + } + + if (cinfo->quantize_colors) + cinfo->output_components = 1; /* single colormapped output component */ + else + cinfo->output_components = cinfo->out_color_components; +} diff --git a/renderer/jpeg-6/jdct.h b/renderer/jpeg-6/jdct.h new file mode 100644 index 000000000..3ce790bc8 --- /dev/null +++ b/renderer/jpeg-6/jdct.h @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer. Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM; /* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM; /* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array. The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table. The output data is to be placed into the + * sample array starting at a specified column. (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required. We use a mask-and-table-lookup method + * to do the combined operations quickly. See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Extern declarations for the forward and inverse DCT routines. */ + +EXTERN void jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN void jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN void jpeg_fdct_float JPP((FAST_FLOAT * data)); + +EXTERN void jpeg_idct_islow + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN void jpeg_idct_ifast + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN void jpeg_idct_float + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN void jpeg_idct_4x4 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN void jpeg_idct_2x2 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN void jpeg_idct_1x1 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE ((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply. This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16 /* default definition */ +#define MULTIPLY16C16(var,const) ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16 /* default definition */ +#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) +#endif diff --git a/renderer/jpeg-6/jddctmgr.c b/renderer/jpeg-6/jddctmgr.c new file mode 100644 index 000000000..71215f197 --- /dev/null +++ b/renderer/jpeg-6/jddctmgr.c @@ -0,0 +1,270 @@ +/* + * jddctmgr.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores. No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper. This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* + * The decompressor input side (jdinput.c) saves away the appropriate + * quantization table for each component at the start of the first scan + * involving that component. (This is necessary in order to correctly + * decode files that reuse Q-table slots.) + * When we are ready to make an output pass, the saved Q-table is converted + * to a multiplier table that will actually be used by the IDCT routine. + * The multiplier table contents are IDCT-method-dependent. To support + * application changes in IDCT method between scans, we can remake the + * multiplier tables if necessary. + * In buffered-image mode, the first output pass may occur before any data + * has been seen for some components, and thus before their Q-tables have + * been saved away. To handle this case, multiplier tables are preset + * to zeroes; the result of the IDCT will be a neutral gray level. + */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_inverse_dct pub; /* public fields */ + + /* This array contains the IDCT method code that each multiplier table + * is currently set up for, or -1 if it's not yet set up. + * The actual multiplier tables are pointed to by dct_table in the + * per-component comp_info structures. + */ + int cur_method[MAX_COMPONENTS]; +} my_idct_controller; + +typedef my_idct_controller * my_idct_ptr; + + +/* Allocated multiplier tables: big enough for any supported variant */ + +typedef union { + ISLOW_MULT_TYPE islow_array[DCTSIZE2]; +#ifdef DCT_IFAST_SUPPORTED + IFAST_MULT_TYPE ifast_array[DCTSIZE2]; +#endif +#ifdef DCT_FLOAT_SUPPORTED + FLOAT_MULT_TYPE float_array[DCTSIZE2]; +#endif +} multiplier_table; + + +/* The current scaled-IDCT routines require ISLOW-style multiplier tables, + * so be sure to compile that code if either ISLOW or SCALING is requested. + */ +#ifdef DCT_ISLOW_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#else +#ifdef IDCT_SCALING_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#endif +#endif + + +/* + * Prepare for an output pass. + * Here we select the proper IDCT routine for each component and build + * a matching multiplier table. + */ + +METHODDEF void +start_pass (j_decompress_ptr cinfo) +{ + my_idct_ptr idct = (my_idct_ptr) cinfo->idct; + int ci, i; + jpeg_component_info *compptr; + int method = 0; + inverse_DCT_method_ptr method_ptr = NULL; + JQUANT_TBL * qtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Select the proper IDCT routine for this component's scaling */ + switch (compptr->DCT_scaled_size) { +#ifdef IDCT_SCALING_SUPPORTED + case 1: + method_ptr = jpeg_idct_1x1; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 2: + method_ptr = jpeg_idct_2x2; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 4: + method_ptr = jpeg_idct_4x4; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; +#endif + case DCTSIZE: + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + method_ptr = jpeg_idct_float; + method = JDCT_FLOAT; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + break; + default: + ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); + break; + } + idct->pub.inverse_DCT[ci] = method_ptr; + /* Create multiplier table from quant table. + * However, we can skip this if the component is uninteresting + * or if we already built the table. Also, if no quant table + * has yet been saved for the component, we leave the + * multiplier table all-zero; we'll be reading zeroes from the + * coefficient controller's buffer anyway. + */ + if (! compptr->component_needed || idct->cur_method[ci] == method) + continue; + qtbl = compptr->quant_table; + if (qtbl == NULL) /* happens if no data yet for component */ + continue; + idct->cur_method[ci] = method; + switch (method) { +#ifdef PROVIDE_ISLOW_TABLES + case JDCT_ISLOW: + { + /* For LL&M IDCT method, multipliers are equal to raw quantization + * coefficients, but are stored in natural order as ints. + */ + ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; + for (i = 0; i < DCTSIZE2; i++) { + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]]; + } + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * For integer operation, the multiplier table is to be scaled by + * IFAST_SCALE_BITS. The multipliers are stored in natural order. + */ + IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + for (i = 0; i < DCTSIZE2; i++) { + ifmtbl[i] = (IFAST_MULT_TYPE) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], + (INT32) aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * The multipliers are stored in natural order. + */ + FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fmtbl[i] = (FLOAT_MULT_TYPE) + ((double) qtbl->quantval[jpeg_zigzag_order[i]] * + aanscalefactor[row] * aanscalefactor[col]); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Initialize IDCT manager. + */ + +GLOBAL void +jinit_inverse_dct (j_decompress_ptr cinfo) +{ + my_idct_ptr idct; + int ci; + jpeg_component_info *compptr; + + idct = (my_idct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_idct_controller)); + cinfo->idct = (struct jpeg_inverse_dct *) idct; + idct->pub.start_pass = start_pass; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate and pre-zero a multiplier table for each component */ + compptr->dct_table = + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); + /* Mark multiplier table not yet set up for any method */ + idct->cur_method[ci] = -1; + } +} diff --git a/renderer/jpeg-6/jdhuff.c b/renderer/jpeg-6/jdhuff.c new file mode 100644 index 000000000..95174b17b --- /dev/null +++ b/renderer/jpeg-6/jdhuff.c @@ -0,0 +1,574 @@ +/* + * jdhuff.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdphuff.c */ + + +/* + * Expanded entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; +} huff_entropy_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF void +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + * This ought to be an error condition, but we make it a warning because + * there are some baseline files out there with all zeroes in these bytes. + */ + if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || + cinfo->Ah != 0 || cinfo->Al != 0) + WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Make sure requested tables are present */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || + cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS || + cinfo->ac_huff_tbl_ptrs[actbl] == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], + & entropy->ac_derived_tbls[actbl]); + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->bitstate.printed_eod = FALSE; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Compute the derived values for a Huffman table. + * Note this is also used by jdphuff.c. + */ + +GLOBAL void +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, + d_derived_tbl ** pdtbl) +{ + d_derived_tbl *dtbl; + int p, i, l, si; + int lookbits, ctr; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (d_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(d_derived_tbl)); + dtbl = *pdtbl; + dtbl->pub = htbl; /* fill in back link */ + + /* Figure C.1: make table of Huffman code length for each symbol */ + /* Note that this is in code-length order. */ + + p = 0; + for (l = 1; l <= 16; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + + /* Figure C.2: generate the codes themselves */ + /* Note that this is in code-length order. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + code <<= 1; + si++; + } + + /* Figure F.15: generate decoding tables for bit-sequential decoding */ + + p = 0; + for (l = 1; l <= 16; l++) { + if (htbl->bits[l]) { + dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */ + dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */ + p += htbl->bits[l]; + dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ + } else { + dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ + } + } + dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ + + /* Compute lookahead tables to speed up decoding. + * First we set all the table entries to 0, indicating "too long"; + * then we iterate through the Huffman codes that are short enough and + * fill in all the entries that correspond to bit sequences starting + * with that code. + */ + + MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); + + p = 0; + for (l = 1; l <= HUFF_LOOKAHEAD; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { + /* l = current code's length, p = its index in huffcode[] & huffval[]. */ + /* Generate left-justified code followed by all possible bit sequences */ + lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); + for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { + dtbl->look_nbits[lookbits] = l; + dtbl->look_sym[lookbits] = htbl->huffval[p]; + lookbits++; + } + } + } +} + + +/* + * Out-of-line code for bit fetching (shared with jdphuff.c). + * See jdhuff.h for info about usage. + * Note: current values of get_buffer and bits_left are passed as parameters, + * but are returned in the corresponding fields of the state struct. + * + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + * of get_buffer to be used. (On machines with wider words, an even larger + * buffer could be used.) However, on some machines 32-bit shifts are + * quite slow and take time proportional to the number of places shifted. + * (This is true with most PC compilers, for instance.) In this case it may + * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. + */ + +#ifdef SLOW_SHIFT_32 +#define MIN_GET_BITS 15 /* minimum allowable value */ +#else +#define MIN_GET_BITS (BIT_BUF_SIZE-7) +#endif + + +GLOBAL boolean +jpeg_fill_bit_buffer (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + int nbits) +/* Load up the bit buffer to a depth of at least nbits */ +{ + /* Copy heavily used state fields into locals (hopefully registers) */ + register const JOCTET * next_input_byte = state->next_input_byte; + register size_t bytes_in_buffer = state->bytes_in_buffer; + register int c; + + /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ + /* (It is assumed that no request will be for more than that many bits.) */ + + while (bits_left < MIN_GET_BITS) { + /* Attempt to read a byte */ + if (state->unread_marker != 0) + goto no_more_data; /* can't advance past a marker */ + + if (bytes_in_buffer == 0) { + if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) + return FALSE; + next_input_byte = state->cinfo->src->next_input_byte; + bytes_in_buffer = state->cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + + /* If it's 0xFF, check and discard stuffed zero byte */ + if (c == 0xFF) { + do { + if (bytes_in_buffer == 0) { + if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) + return FALSE; + next_input_byte = state->cinfo->src->next_input_byte; + bytes_in_buffer = state->cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + } while (c == 0xFF); + + if (c == 0) { + /* Found FF/00, which represents an FF data byte */ + c = 0xFF; + } else { + /* Oops, it's actually a marker indicating end of compressed data. */ + /* Better put it back for use later */ + state->unread_marker = c; + + no_more_data: + /* There should be enough bits still left in the data segment; */ + /* if so, just break out of the outer while loop. */ + if (bits_left >= nbits) + break; + /* Uh-oh. Report corrupted data to user and stuff zeroes into + * the data stream, so that we can produce some kind of image. + * Note that this code will be repeated for each byte demanded + * for the rest of the segment. We use a nonvolatile flag to ensure + * that only one warning message appears. + */ + if (! *(state->printed_eod_ptr)) { + WARNMS(state->cinfo, JWRN_HIT_MARKER); + *(state->printed_eod_ptr) = TRUE; + } + c = 0; /* insert a zero byte into bit buffer */ + } + } + + /* OK, load c into get_buffer */ + get_buffer = (get_buffer << 8) | c; + bits_left += 8; + } + + /* Unload the local registers */ + state->next_input_byte = next_input_byte; + state->bytes_in_buffer = bytes_in_buffer; + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + return TRUE; +} + + +/* + * Out-of-line code for Huffman code decoding. + * See jdhuff.h for info about usage. + */ + +GLOBAL int +jpeg_huff_decode (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + d_derived_tbl * htbl, int min_bits) +{ + register int l = min_bits; + register INT32 code; + + /* HUFF_DECODE has determined that the code is at least min_bits */ + /* bits long, so fetch that many bits in one swoop. */ + + CHECK_BIT_BUFFER(*state, l, return -1); + code = GET_BITS(l); + + /* Collect the rest of the Huffman code one bit at a time. */ + /* This is per Figure F.16 in the JPEG spec. */ + + while (code > htbl->maxcode[l]) { + code <<= 1; + CHECK_BIT_BUFFER(*state, 1, return -1); + code |= GET_BITS(1); + l++; + } + + /* Unload the local registers */ + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + /* With garbage input we may reach the sentinel value l = 17. */ + + if (l > 16) { + WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); + return 0; /* fake a zero as the safest result */ + } + + return htbl->pub->huffval[ htbl->valptr[l] + + ((int) (code - htbl->mincode[l])) ]; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL boolean +process_restart (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Next segment can get another out-of-data warning */ + entropy->bitstate.printed_eod = FALSE; + + return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +METHODDEF boolean +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + register int s, k, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state state; + d_derived_tbl * dctbl; + d_derived_tbl * actbl; + jpeg_component_info * compptr; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + /* Shortcut if component's values are not interesting */ + if (! compptr->component_needed) + goto skip_ACs; + + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + + /* Do we need to decode the AC coefficients for this component? */ + if (compptr->DCT_scaled_size > 1) { + + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } + } + + } else { +skip_ACs: + + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } + } + + } + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL void +jinit_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_huff_decoder; + entropy->pub.decode_mcu = decode_mcu; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; + } +} diff --git a/renderer/jpeg-6/jdhuff.h b/renderer/jpeg-6/jdhuff.h new file mode 100644 index 000000000..d375c7819 --- /dev/null +++ b/renderer/jpeg-6/jdhuff.h @@ -0,0 +1,202 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ + +typedef struct { + /* Basic tables: (element [0] of each array is unused) */ + INT32 mincode[17]; /* smallest code of length k */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ + int valptr[17]; /* huffval[] index of 1st symbol of length k */ + + /* Link to public Huffman table (needed only in jpeg_huff_decode) */ + JHUFF_TBL *pub; + + /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + * the input data stream. If the next Huffman code is no more + * than HUFF_LOOKAHEAD bits long, we can obtain its length and + * the corresponding symbol directly from these tables. + */ + int look_nbits[1< 32 bits on your machine, and shifting/masking longs is + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + * appropriately should be a win. Unfortunately we can't do this with + * something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * because not all machines measure sizeof in 8-bit bytes. + */ + +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + boolean printed_eod; /* flag to suppress multiple warning msgs */ +} bitread_perm_state; + +typedef struct { /* Bitreading working state within an MCU */ + /* current data source state */ + const JOCTET * next_input_byte; /* => next byte to read from source */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + int unread_marker; /* nonzero if we have hit a marker */ + /* bit input buffer --- note these values are kept in register variables, + * not in this struct, inside the inner loops. + */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + /* pointers needed by jpeg_fill_bit_buffer */ + j_decompress_ptr cinfo; /* back link to decompress master record */ + boolean * printed_eod_ptr; /* => flag in permanent state */ +} bitread_working_state; + +/* Macros to declare and load/save bitread local variables. */ +#define BITREAD_STATE_VARS \ + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state + +#define BITREAD_LOAD_STATE(cinfop,permstate) \ + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + br_state.unread_marker = cinfop->unread_marker; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; \ + br_state.printed_eod_ptr = & permstate.printed_eod + +#define BITREAD_SAVE_STATE(cinfop,permstate) \ + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + cinfop->unread_marker = br_state.unread_marker; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. + * val = GET_BITS(n); + * Fetch next N bits. + * val = PEEK_BITS(n); + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ + (bits_left -= (nbits)) + +/* Load up the bit buffer to a depth of at least nbits */ +EXTERN boolean jpeg_fill_bit_buffer JPP((bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + int nbits)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping. Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long. The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + * for a lookahead. In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + * more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + nb = 1; goto slowlabel; \ + } \ + } \ + look = PEEK_BITS(HUFF_LOOKAHEAD); \ + if ((nb = htbl->look_nbits[look]) != 0) { \ + DROP_BITS(nb); \ + result = htbl->look_sym[look]; \ + } else { \ + nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ + if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ + { failaction; } \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + } \ +} + +/* Out-of-line case for Huffman code fetching */ +EXTERN int jpeg_huff_decode JPP((bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + d_derived_tbl * htbl, int min_bits)); diff --git a/renderer/jpeg-6/jdinput.c b/renderer/jpeg-6/jdinput.c new file mode 100644 index 000000000..3061a17bd --- /dev/null +++ b/renderer/jpeg-6/jdinput.c @@ -0,0 +1,381 @@ +/* + * jdinput.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding). The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_input_controller pub; /* public fields */ + + boolean inheaders; /* TRUE until first SOS is reached */ +} my_input_controller; + +typedef my_input_controller * my_inputctl_ptr; + + +/* Forward declarations */ +METHODDEF int consume_markers JPP((j_decompress_ptr cinfo)); + + +/* + * Routines to calculate various quantities related to the size of the image. + */ + +LOCAL void +initial_setup (j_decompress_ptr cinfo) +/* Called once, when first SOS marker is reached */ +{ + int ci; + jpeg_component_info *compptr; + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + * In the full decompressor, this will be overridden by jdmaster.c; + * but in the transcoder, jdmaster.c is not used, so we must do it here. + */ + cinfo->min_DCT_scaled_size = DCTSIZE; + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* downsampled_width and downsampled_height will also be overridden by + * jdmaster.c if we are doing full decompression. The transcoder library + * doesn't use these values, but the calling application might. + */ + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed, until color conversion says otherwise */ + compptr->component_needed = TRUE; + /* Mark no quantization table yet saved for component */ + compptr->quant_table = NULL; + } + + /* Compute number of fully interleaved MCU rows. */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + /* Decide whether file contains multiple scans */ + if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) + cinfo->inputctl->has_multiple_scans = TRUE; + else + cinfo->inputctl->has_multiple_scans = FALSE; +} + + +LOCAL void +per_scan_setup (j_decompress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = compptr->DCT_scaled_size; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table. (The IJG encoder is not + * currently capable of doing this, but other encoders might.) Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot. If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL void +latch_quant_tables (j_decompress_ptr cinfo) +{ + int ci, qtblno; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* No work if we already saved Q-table for this component */ + if (compptr->quant_table != NULL) + continue; + /* Make sure specified quantization table is present */ + qtblno = compptr->quant_tbl_no; + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + /* OK, save away the quantization table */ + qtbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)); + MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr->quant_table = qtbl; + } +} + + +/* + * Initialize the input modules to read a scan of compressed data. + * The first call to this is done by jdmaster.c after initializing + * the entire decompressor (during jpeg_start_decompress). + * Subsequent calls come from consume_markers, below. + */ + +METHODDEF void +start_input_pass (j_decompress_ptr cinfo) +{ + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + (*cinfo->entropy->start_pass) (cinfo); + (*cinfo->coef->start_input_pass) (cinfo); + cinfo->inputctl->consume_input = cinfo->coef->consume_data; +} + + +/* + * Finish up after inputting a compressed-data scan. + * This is called by the coefficient controller after it's read all + * the expected data of the scan. + */ + +METHODDEF void +finish_input_pass (j_decompress_ptr cinfo) +{ + cinfo->inputctl->consume_input = consume_markers; +} + + +/* + * Read JPEG markers before, between, or after compressed-data scans. + * Change state as necessary when a new scan is reached. + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * The consume_input method pointer points either here or to the + * coefficient controller's consume_data routine, depending on whether + * we are reading a compressed data segment or inter-segment markers. + */ + +METHODDEF int +consume_markers (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + int val; + + if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ + return JPEG_REACHED_EOI; + + val = (*cinfo->marker->read_markers) (cinfo); + + switch (val) { + case JPEG_REACHED_SOS: /* Found SOS */ + if (inputctl->inheaders) { /* 1st SOS */ + initial_setup(cinfo); + inputctl->inheaders = FALSE; + /* Note: start_input_pass must be called by jdmaster.c + * before any more input can be consumed. jdapi.c is + * responsible for enforcing this sequencing. + */ + } else { /* 2nd or later SOS marker */ + if (! inputctl->pub.has_multiple_scans) + ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ + start_input_pass(cinfo); + } + break; + case JPEG_REACHED_EOI: /* Found EOI */ + inputctl->pub.eoi_reached = TRUE; + if (inputctl->inheaders) { /* Tables-only datastream, apparently */ + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_NO_SOS); + } else { + /* Prevent infinite loop in coef ctlr's decompress_data routine + * if user set output_scan_number larger than number of scans. + */ + if (cinfo->output_scan_number > cinfo->input_scan_number) + cinfo->output_scan_number = cinfo->input_scan_number; + } + break; + case JPEG_SUSPENDED: + break; + } + + return val; +} + + +/* + * Reset state to begin a fresh datastream. + */ + +METHODDEF void +reset_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + + inputctl->pub.consume_input = consume_markers; + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; + /* Reset other modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->marker->reset_marker_reader) (cinfo); + /* Reset progression state -- would be cleaner if entropy decoder did this */ + cinfo->coef_bits = NULL; +} + + +/* + * Initialize the input controller module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL void +jinit_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl; + + /* Create subobject in permanent pool */ + inputctl = (my_inputctl_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_input_controller)); + cinfo->inputctl = (struct jpeg_input_controller *) inputctl; + /* Initialize method pointers */ + inputctl->pub.consume_input = consume_markers; + inputctl->pub.reset_input_controller = reset_input_controller; + inputctl->pub.start_input_pass = start_input_pass; + inputctl->pub.finish_input_pass = finish_input_pass; + /* Initialize state: can't use reset_input_controller since we don't + * want to try to reset other modules yet. + */ + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; +} diff --git a/renderer/jpeg-6/jdmainct.c b/renderer/jpeg-6/jdmainct.c new file mode 100644 index 000000000..f3a06e590 --- /dev/null +++ b/renderer/jpeg-6/jdmainct.c @@ -0,0 +1,512 @@ +/* + * jdmainct.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for decompression. + * The main buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers. Nonetheless, the main controller is not + * trivial. Its responsibility is to provide context rows for upsampling/ + * rescaling, and doing this in an efficient fashion is a bit tricky. + * + * Postprocessor input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. (We require DCT_scaled_size values to be + * chosen such that these numbers are integers. In practice DCT_scaled_size + * values will likely be powers of two, so we actually have the stronger + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * Upsampling will typically produce max_v_samp_factor pixel rows from each + * row group (times any additional scale factor that the upsampler is + * applying). + * + * The coefficient controller will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + * exactly min_DCT_scaled_size row groups. (This amount of data corresponds + * to one row of MCUs when the image is fully interleaved.) Note that the + * number of sample rows varies across components, but the number of row + * groups does not. Some garbage sample rows may be included in the last iMCU + * row at the bottom of the image. + * + * Depending on the vertical scaling algorithm used, the upsampler may need + * access to the sample row(s) above and below its current input row group. + * The upsampler is required to set need_context_rows TRUE at global selection + * time if so. When need_context_rows is FALSE, this controller can simply + * obtain one iMCU row at a time from the coefficient controller and dole it + * out as row groups to the postprocessor. + * + * When need_context_rows is TRUE, this controller guarantees that the buffer + * passed to postprocessing contains at least one row group's worth of samples + * above and below the row group(s) being processed. Note that the context + * rows "above" the first passed row group appear at negative row offsets in + * the passed buffer. At the top and bottom of the image, the required + * context rows are manufactured by duplicating the first or last real sample + * row; this avoids having special cases in the upsampling inner loops. + * + * The amount of context is fixed at one row group just because that's a + * convenient number for this controller to work with. The existing + * upsamplers really only need one sample row of context. An upsampler + * supporting arbitrary output rescaling might wish for more than one row + * group of context when shrinking the image; tough, we don't handle that. + * (This is justified by the assumption that downsizing will be handled mostly + * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * the upsample step needn't be much less than one.) + * + * To provide the desired context, we have to retain the last two row groups + * of one iMCU row while reading in the next iMCU row. (The last row group + * can't be processed until we have another row group for its below-context, + * and so we have to save the next-to-last group too for its above-context.) + * We could do this most simply by copying data around in our buffer, but + * that'd be very slow. We can avoid copying any data by creating a rather + * strange pointer structure. Here's how it works. We allocate a workspace + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * of row groups per iMCU row). We create two sets of redundant pointers to + * the workspace. Labeling the physical row groups 0 to M+1, the synthesized + * pointer lists look like this: + * M+1 M-1 + * master pointer --> 0 master pointer --> 0 + * 1 1 + * ... ... + * M-3 M-3 + * M-2 M + * M-1 M+1 + * M M-2 + * M+1 M-1 + * 0 0 + * We read alternate iMCU rows using each master pointer; thus the last two + * row groups of the previous iMCU row remain un-overwritten in the workspace. + * The pointer lists are set up so that the required context rows appear to + * be adjacent to the proper places when we pass the pointer lists to the + * upsampler. + * + * The above pictures describe the normal state of the pointer lists. + * At top and bottom of the image, we diddle the pointer lists to duplicate + * the first or last sample row as necessary (this is cheaper than copying + * sample rows around). + * + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + * situation each iMCU row provides only one row group so the buffering logic + * must be different (eg, we must read two iMCU rows before we can emit the + * first row group). For now, we simply do not support providing context + * rows when min_DCT_scaled_size is 1. That combination seems unlikely to + * be worth providing --- if someone wants a 1/8th-size preview, they probably + * want it quick and dirty, so a context-free upsampler is sufficient. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_main_controller pub; /* public fields */ + + /* Pointer to allocated workspace (M or M+2 row groups). */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + + boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ + JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ + + /* Remaining fields are only used in the context case. */ + + /* These are the master pointers to the funny-order pointer lists. */ + JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ + + int whichptr; /* indicates which pointer set is now in use */ + int context_state; /* process_data state machine status */ + JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ + JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + +/* context_state values: */ +#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ +#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ +#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ + + +/* Forward declarations */ +METHODDEF void process_data_simple_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +METHODDEF void process_data_context_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF void process_data_crank_post + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#endif + + +LOCAL void +alloc_funny_pointers (j_decompress_ptr cinfo) +/* Allocate space for the funny pointer lists. + * This is done only once, not once per pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + /* Get top-level space for component array pointers. + * We alloc both arrays with one call to save a few cycles. + */ + main->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + /* Get space for pointer lists --- M+4 row groups in each list. + * We alloc both pointer lists with one call to save a few cycles. + */ + xbuf = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf += rgroup; /* want one row group at negative offsets */ + main->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); + main->xbuffer[1][ci] = xbuf; + } +} + + +LOCAL void +make_funny_pointers (j_decompress_ptr cinfo) +/* Create the funny pointer lists discussed in the comments above. + * The actual workspace is already allocated (in main->buffer), + * and the space for the pointer lists is allocated too. + * This routine just fills in the curiously ordered lists. + * This will be repeated at the beginning of each pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY buf, xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ + buf = main->buffer[ci]; + for (i = 0; i < rgroup * (M + 2); i++) { + xbuf0[i] = xbuf1[i] = buf[i]; + } + /* In the second list, put the last four row groups in swapped order */ + for (i = 0; i < rgroup * 2; i++) { + xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; + xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; + } + /* The wraparound pointers at top and bottom will be filled later + * (see set_wraparound_pointers, below). Initially we want the "above" + * pointers to duplicate the first actual data line. This only needs + * to happen in xbuffer[0]. + */ + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[0]; + } + } +} + + +LOCAL void +set_wraparound_pointers (j_decompress_ptr cinfo) +/* Set up the "wraparound" pointers at top and bottom of the pointer lists. + * This changes the pointer list state from top-of-image to the normal state. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; + xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; + xbuf0[rgroup*(M+2) + i] = xbuf0[i]; + xbuf1[rgroup*(M+2) + i] = xbuf1[i]; + } + } +} + + +LOCAL void +set_bottom_pointers (j_decompress_ptr cinfo) +/* Change the pointer lists to duplicate the last sample row at the bottom + * of the image. whichptr indicates which xbuffer holds the final iMCU row. + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup, iMCUheight, rows_left; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Count sample rows in one iMCU row and in one row group */ + iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; + rgroup = iMCUheight / cinfo->min_DCT_scaled_size; + /* Count nondummy sample rows remaining for this component */ + rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); + if (rows_left == 0) rows_left = iMCUheight; + /* Count nondummy row groups. Should get same answer for each component, + * so we need only do it once. + */ + if (ci == 0) { + main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + } + /* Duplicate the last real sample row rgroup*2 times; this pads out the + * last partial rowgroup and ensures at least one full rowgroup of context. + */ + xbuf = main->xbuffer[main->whichptr][ci]; + for (i = 0; i < rgroup * 2; i++) { + xbuf[rows_left + i] = xbuf[rows_left-1]; + } + } +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { + main->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ + main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main->context_state = CTX_PREPARE_FOR_IMCU; + main->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ + main->pub.process_data = process_data_simple_main; + } + main->buffer_full = FALSE; /* Mark buffer empty */ + main->rowgroup_ctr = 0; + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ + main->pub.process_data = process_data_crank_post; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This handles the simple case where no context is required. + */ + +METHODDEF void +process_data_simple_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + } + + /* There are always min_DCT_scaled_size row groups in an iMCU row. */ + rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; + /* Note: at the bottom of the image, we may pass extra garbage row groups + * to the postprocessor. The postprocessor has to check for bottom + * of image anyway (at row resolution), so no point in us doing it too. + */ + + /* Feed the postprocessor */ + (*cinfo->post->post_process_data) (cinfo, main->buffer, + &main->rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ + if (main->rowgroup_ctr >= rowgroups_avail) { + main->buffer_full = FALSE; + main->rowgroup_ctr = 0; + } +} + + +/* + * Process some data. + * This handles the case where context rows must be provided. + */ + +METHODDEF void +process_data_context_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, + main->xbuffer[main->whichptr])) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->iMCU_row_ctr++; /* count rows received */ + } + + /* Postprocessor typically will not swallow all the input data it is handed + * in one call (due to filling the output buffer first). Must be prepared + * to exit and restart. This switch lets us keep track of how far we got. + * Note that each case falls through to the next on successful completion. + */ + switch (main->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + main->context_state = CTX_PREPARE_FOR_IMCU; + if (*out_row_ctr >= out_rows_avail) + return; /* Postprocessor exactly filled output buf */ + /*FALLTHROUGH*/ + case CTX_PREPARE_FOR_IMCU: + /* Prepare to process first M-1 row groups of this iMCU row */ + main->rowgroup_ctr = 0; + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + /* Check for bottom of image: if so, tweak pointers to "duplicate" + * the last sample row, and adjust rowgroups_avail to ignore padding rows. + */ + if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); + main->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ + if (main->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ + main->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main->buffer_full = FALSE; + /* Still need to process last row group of this iMCU row, */ + /* which is saved at index M+1 of the other xbuffer */ + main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); + main->context_state = CTX_POSTPONED_ROW; + } +} + + +/* + * Process some data. + * Final pass of two-pass quantization: just call the postprocessor. + * Source data will be the postprocessor controller's internal buffer. + */ + +#ifdef QUANT_2PASS_SUPPORTED + +METHODDEF void +process_data_crank_post (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, + (JDIMENSION *) NULL, (JDIMENSION) 0, + output_buf, out_row_ctr, out_rows_avail); +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL void +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_d_main_controller *) main; + main->pub.start_pass = start_pass_main; + + if (need_full_buffer) /* shouldn't happen */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Allocate the workspace. + * ngroups is the number of row groups we need. + */ + if (cinfo->upsample->need_context_rows) { + if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ + ERREXIT(cinfo, JERR_NOTIMPL); + alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ + ngroups = cinfo->min_DCT_scaled_size + 2; + } else { + ngroups = cinfo->min_DCT_scaled_size; + } + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); + } +} diff --git a/renderer/jpeg-6/jdmarker.c b/renderer/jpeg-6/jdmarker.c new file mode 100644 index 000000000..80e5f7834 --- /dev/null +++ b/renderer/jpeg-6/jdmarker.c @@ -0,0 +1,1052 @@ +/* + * jdmarker.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application. On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* + * Macros for fetching data from the data source module. + * + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect + * the current restart point; we update them only when we have reached a + * suitable place to restart if a suspension occurs. + */ + +/* Declare and initialize local copies of input pointer/count */ +#define INPUT_VARS(cinfo) \ + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo) \ + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) + +/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */ +#define INPUT_RELOAD(cinfo) \ + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action) \ + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } \ + bytes_in_buffer-- + +/* Read a byte into variable V. + * If must suspend, take the specified action (typically "return FALSE"). + */ +#define INPUT_BYTE(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + V += GETJOCTET(*next_input_byte++); ) + + +/* + * Routines to process JPEG markers. + * + * Entry condition: JPEG marker itself has been read and its code saved + * in cinfo->unread_marker; input restart point is just after the marker. + * + * Exit: if return TRUE, have read and processed any parameters, and have + * updated the restart point to point after the parameters. + * If return FALSE, was forced to suspend before reaching end of + * marker parameters; restart point has not been moved. Same routine + * will be called again after application supplies more input data. + * + * This approach to suspension assumes that all of a marker's parameters can + * fit into a single input bufferload. This should hold for "normal" + * markers. Some COM/APPn markers might have large parameter segments, + * but we use skip_input_data to get past those, and thereby put the problem + * on the source manager's shoulders. + * + * Note that we don't bother to avoid duplicate trace messages if a + * suspension occurs within marker parameters. Other side effects + * require more care. + */ + + +LOCAL boolean +get_soi (j_decompress_ptr cinfo) +/* Process an SOI marker */ +{ + int i; + + TRACEMS(cinfo, 1, JTRC_SOI); + + if (cinfo->marker->saw_SOI) + ERREXIT(cinfo, JERR_SOI_DUPLICATE); + + /* Reset all parameters that are defined to be reset by SOI */ + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + cinfo->restart_interval = 0; + + /* Set initial assumptions for colorspace etc */ + + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ + + cinfo->saw_JFIF_marker = FALSE; + cinfo->density_unit = 0; /* set default JFIF APP0 values */ + cinfo->X_density = 1; + cinfo->Y_density = 1; + cinfo->saw_Adobe_marker = FALSE; + cinfo->Adobe_transform = 0; + + cinfo->marker->saw_SOI = TRUE; + + return TRUE; +} + + +LOCAL boolean +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +/* Process a SOFn marker */ +{ + INT32 length; + int c, ci; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + cinfo->progressive_mode = is_prog; + cinfo->arith_code = is_arith; + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); + INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); + + length -= 8; + + TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, + (int) cinfo->image_width, (int) cinfo->image_height, + cinfo->num_components); + + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_DUPLICATE); + + /* We don't support files in which the image height is initially specified */ + /* as 0 and is later redefined by DNL. As long as we have to check that, */ + /* might as well have a general sanity check. */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + if (length != (cinfo->num_components * 3)) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + if (cinfo->comp_info == NULL) /* do only once, even if suspend */ + cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * SIZEOF(jpeg_component_info)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->component_index = ci; + INPUT_BYTE(cinfo, compptr->component_id, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + compptr->h_samp_factor = (c >> 4) & 15; + compptr->v_samp_factor = (c ) & 15; + INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); + + TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, + compptr->component_id, compptr->h_samp_factor, + compptr->v_samp_factor, compptr->quant_tbl_no); + } + + cinfo->marker->saw_SOF = TRUE; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL boolean +get_sos (j_decompress_ptr cinfo) +/* Process a SOS marker */ +{ + INT32 length; + int i, ci, n, c, cc; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + if (! cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOS_NO_SOF); + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + + if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + TRACEMS1(cinfo, 1, JTRC_SOS, n); + + cinfo->comps_in_scan = n; + + /* Collect the component-spec parameters */ + + for (i = 0; i < n; i++) { + INPUT_BYTE(cinfo, cc, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (cc == compptr->component_id) + goto id_found; + } + + ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo->cur_comp_info[i] = compptr; + compptr->dc_tbl_no = (c >> 4) & 15; + compptr->ac_tbl_no = (c ) & 15; + + TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, + compptr->dc_tbl_no, compptr->ac_tbl_no); + } + + /* Collect the additional scan parameters Ss, Se, Ah/Al. */ + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ss = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Se = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ah = (c >> 4) & 15; + cinfo->Al = (c ) & 15; + + TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, + cinfo->Ah, cinfo->Al); + + /* Prepare to scan data & restart markers */ + cinfo->marker->next_restart_num = 0; + + /* Count another SOS marker */ + cinfo->input_scan_number++; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +METHODDEF boolean +get_app0 (j_decompress_ptr cinfo) +/* Process an APP0 marker */ +{ +#define JFIF_LEN 14 + INT32 length; + UINT8 b[JFIF_LEN]; + int buffp; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* See if a JFIF APP0 marker is present */ + + if (length >= JFIF_LEN) { + for (buffp = 0; buffp < JFIF_LEN; buffp++) + INPUT_BYTE(cinfo, b[buffp], return FALSE); + length -= JFIF_LEN; + + if (b[0]==0x4A && b[1]==0x46 && b[2]==0x49 && b[3]==0x46 && b[4]==0) { + /* Found JFIF APP0 marker: check version */ + /* Major version must be 1, anything else signals an incompatible change. + * We used to treat this as an error, but now it's a nonfatal warning, + * because some bozo at Hijaak couldn't read the spec. + * Minor version should be 0..2, but process anyway if newer. + */ + if (b[5] != 1) + WARNMS2(cinfo, JWRN_JFIF_MAJOR, b[5], b[6]); + else if (b[6] > 2) + TRACEMS2(cinfo, 1, JTRC_JFIF_MINOR, b[5], b[6]); + /* Save info */ + cinfo->saw_JFIF_marker = TRUE; + cinfo->density_unit = b[7]; + cinfo->X_density = (b[8] << 8) + b[9]; + cinfo->Y_density = (b[10] << 8) + b[11]; + TRACEMS3(cinfo, 1, JTRC_JFIF, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + if (b[12] | b[13]) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, b[12], b[13]); + if (length != ((INT32) b[12] * (INT32) b[13] * (INT32) 3)) + TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) length); + } else { + /* Start of APP0 does not match "JFIF" */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) length + JFIF_LEN); + } + } else { + /* Too short to be JFIF marker */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) length); + } + + INPUT_SYNC(cinfo); + if (length > 0) /* skip any remaining data -- could be lots */ + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +METHODDEF boolean +get_app14 (j_decompress_ptr cinfo) +/* Process an APP14 marker */ +{ +#define ADOBE_LEN 12 + INT32 length; + UINT8 b[ADOBE_LEN]; + int buffp; + unsigned int version, flags0, flags1, transform; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* See if an Adobe APP14 marker is present */ + + if (length >= ADOBE_LEN) { + for (buffp = 0; buffp < ADOBE_LEN; buffp++) + INPUT_BYTE(cinfo, b[buffp], return FALSE); + length -= ADOBE_LEN; + + if (b[0]==0x41 && b[1]==0x64 && b[2]==0x6F && b[3]==0x62 && b[4]==0x65) { + /* Found Adobe APP14 marker */ + version = (b[5] << 8) + b[6]; + flags0 = (b[7] << 8) + b[8]; + flags1 = (b[9] << 8) + b[10]; + transform = b[11]; + TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); + cinfo->saw_Adobe_marker = TRUE; + cinfo->Adobe_transform = (UINT8) transform; + } else { + /* Start of APP14 does not match "Adobe" */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) length + ADOBE_LEN); + } + } else { + /* Too short to be Adobe marker */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) length); + } + + INPUT_SYNC(cinfo); + if (length > 0) /* skip any remaining data -- could be lots */ + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +LOCAL boolean +get_dac (j_decompress_ptr cinfo) +/* Process a DAC marker */ +{ + INT32 length; + int index, val; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, index, return FALSE); + INPUT_BYTE(cinfo, val, return FALSE); + + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_DAC, index, val); + + if (index < 0 || index >= (2*NUM_ARITH_TBLS)) + ERREXIT1(cinfo, JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) { /* define AC table */ + cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; + } else { /* define DC table */ + cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); + cinfo->arith_dc_U[index] = (UINT8) (val >> 4); + if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) + ERREXIT1(cinfo, JERR_DAC_VALUE, val); + } + } + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL boolean +get_dht (j_decompress_ptr cinfo) +/* Process a DHT marker */ +{ + INT32 length; + UINT8 bits[17]; + UINT8 huffval[256]; + int i, index, count; + JHUFF_TBL **htblptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, index, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DHT, index); + + bits[0] = 0; + count = 0; + for (i = 1; i <= 16; i++) { + INPUT_BYTE(cinfo, bits[i], return FALSE); + count += bits[i]; + } + + length -= 1 + 16; + + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + + if (count > 256 || ((INT32) count) > length) + ERREXIT(cinfo, JERR_DHT_COUNTS); + + for (i = 0; i < count; i++) + INPUT_BYTE(cinfo, huffval[i], return FALSE); + + length -= count; + + if (index & 0x10) { /* AC table definition */ + index -= 0x10; + htblptr = &cinfo->ac_huff_tbl_ptrs[index]; + } else { /* DC table definition */ + htblptr = &cinfo->dc_huff_tbl_ptrs[index]; + } + + if (index < 0 || index >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_DHT_INDEX, index); + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); + } + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL boolean +get_dqt (j_decompress_ptr cinfo) +/* Process a DQT marker */ +{ + INT32 length; + int n, i, prec; + unsigned int tmp; + JQUANT_TBL *quant_ptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, n, return FALSE); + prec = n >> 4; + n &= 0x0F; + + TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); + + if (n >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, n); + + if (cinfo->quant_tbl_ptrs[n] == NULL) + cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); + quant_ptr = cinfo->quant_tbl_ptrs[n]; + + for (i = 0; i < DCTSIZE2; i++) { + if (prec) + INPUT_2BYTES(cinfo, tmp, return FALSE); + else + INPUT_BYTE(cinfo, tmp, return FALSE); + quant_ptr->quantval[i] = (UINT16) tmp; + } + + for (i = 0; i < DCTSIZE2; i += 8) { + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i ], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + } + + length -= DCTSIZE2+1; + if (prec) length -= DCTSIZE2; + } + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL boolean +get_dri (j_decompress_ptr cinfo) +/* Process a DRI marker */ +{ + INT32 length; + unsigned int tmp; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + + if (length != 4) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_2BYTES(cinfo, tmp, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DRI, tmp); + + cinfo->restart_interval = tmp; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +METHODDEF boolean +skip_variable (j_decompress_ptr cinfo) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + INT32 length; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); + + INPUT_SYNC(cinfo); /* do before skip_input_data */ + (*cinfo->src->skip_input_data) (cinfo, (long) length - 2L); + + return TRUE; +} + + +/* + * Find the next JPEG marker, save it in cinfo->unread_marker. + * Returns FALSE if had to suspend before reaching a marker; + * in that case cinfo->unread_marker is unchanged. + * + * Note that the result might not be a valid marker code, + * but it will never be 0 or FF. + */ + +LOCAL boolean +next_marker (j_decompress_ptr cinfo) +{ + int c; + INPUT_VARS(cinfo); + + for (;;) { + INPUT_BYTE(cinfo, c, return FALSE); + /* Skip any non-FF bytes. + * This may look a bit inefficient, but it will not occur in a valid file. + * We sync after each discarded byte so that a suspending data source + * can discard the byte from its buffer. + */ + while (c != 0xFF) { + cinfo->marker->discarded_bytes++; + INPUT_SYNC(cinfo); + INPUT_BYTE(cinfo, c, return FALSE); + } + /* This loop swallows any duplicate FF bytes. Extra FFs are legal as + * pad bytes, so don't count them in discarded_bytes. We assume there + * will not be so many consecutive FF bytes as to overflow a suspending + * data source's input buffer. + */ + do { + INPUT_BYTE(cinfo, c, return FALSE); + } while (c == 0xFF); + if (c != 0) + break; /* found a valid marker, exit loop */ + /* Reach here if we found a stuffed-zero data sequence (FF/00). + * Discard it and loop back to try again. + */ + cinfo->marker->discarded_bytes += 2; + INPUT_SYNC(cinfo); + } + + if (cinfo->marker->discarded_bytes != 0) { + WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); + cinfo->marker->discarded_bytes = 0; + } + + cinfo->unread_marker = c; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL boolean +first_marker (j_decompress_ptr cinfo) +/* Like next_marker, but used to obtain the initial SOI marker. */ +/* For this marker, we do not allow preceding garbage or fill; otherwise, + * we might well scan an entire input file before realizing it ain't JPEG. + * If an application wants to process non-JFIF files, it must seek to the + * SOI before calling the JPEG library. + */ +{ + int c, c2; + INPUT_VARS(cinfo); + + INPUT_BYTE(cinfo, c, return FALSE); + INPUT_BYTE(cinfo, c2, return FALSE); + if (c != 0xFF || c2 != (int) M_SOI) + ERREXIT2(cinfo, JERR_NO_SOI, c, c2); + + cinfo->unread_marker = c2; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Read markers until SOS or EOI. + * + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + +METHODDEF int +read_markers (j_decompress_ptr cinfo) +{ + /* Outer loop repeats once for each marker. */ + for (;;) { + /* Collect the marker proper, unless we already did. */ + /* NB: first_marker() enforces the requirement that SOI appear first. */ + if (cinfo->unread_marker == 0) { + if (! cinfo->marker->saw_SOI) { + if (! first_marker(cinfo)) + return JPEG_SUSPENDED; + } else { + if (! next_marker(cinfo)) + return JPEG_SUSPENDED; + } + } + /* At this point cinfo->unread_marker contains the marker code and the + * input point is just past the marker proper, but before any parameters. + * A suspension will cause us to return with this state still true. + */ + switch (cinfo->unread_marker) { + case M_SOI: + if (! get_soi(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + if (! get_sof(cinfo, FALSE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF2: /* Progressive, Huffman */ + if (! get_sof(cinfo, TRUE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF9: /* Extended sequential, arithmetic */ + if (! get_sof(cinfo, FALSE, TRUE)) + return JPEG_SUSPENDED; + break; + + case M_SOF10: /* Progressive, arithmetic */ + if (! get_sof(cinfo, TRUE, TRUE)) + return JPEG_SUSPENDED; + break; + + /* Currently unsupported SOFn types */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_JPG: /* Reserved for JPEG extensions */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); + break; + + case M_SOS: + if (! get_sos(cinfo)) + return JPEG_SUSPENDED; + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_SOS; + + case M_EOI: + TRACEMS(cinfo, 1, JTRC_EOI); + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_EOI; + + case M_DAC: + if (! get_dac(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DHT: + if (! get_dht(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DQT: + if (! get_dqt(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DRI: + if (! get_dri(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_COM: + if (! (*cinfo->marker->process_COM) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_RST0: /* these are all parameterless */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); + break; + + case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ + if (! skip_variable(cinfo)) + return JPEG_SUSPENDED; + break; + + default: /* must be DHP, EXP, JPGn, or RESn */ + /* For now, we treat the reserved markers as fatal errors since they are + * likely to be used to signal incompatible JPEG Part 3 extensions. + * Once the JPEG 3 version-number marker is well defined, this code + * ought to change! + */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + /* Successfully processed marker, so reset state variable */ + cinfo->unread_marker = 0; + } /* end loop */ +} + + +/* + * Read a restart marker, which is expected to appear next in the datastream; + * if the marker is not there, take appropriate recovery action. + * Returns FALSE if suspension is required. + * + * This is called by the entropy decoder after it has read an appropriate + * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder + * has already read a marker from the data source. Under normal conditions + * cinfo->unread_marker will be reset to 0 before returning; if not reset, + * it holds a marker which the decoder will be unable to read past. + */ + +METHODDEF boolean +read_restart_marker (j_decompress_ptr cinfo) +{ + /* Obtain a marker unless we already did. */ + /* Note that next_marker will complain if it skips any data. */ + if (cinfo->unread_marker == 0) { + if (! next_marker(cinfo)) + return FALSE; + } + + if (cinfo->unread_marker == + ((int) M_RST0 + cinfo->marker->next_restart_num)) { + /* Normal case --- swallow the marker and let entropy decoder continue */ + TRACEMS1(cinfo, 2, JTRC_RST, cinfo->marker->next_restart_num); + cinfo->unread_marker = 0; + } else { + /* Uh-oh, the restart markers have been messed up. */ + /* Let the data source manager determine how to resync. */ + if (! (*cinfo->src->resync_to_restart) (cinfo, + cinfo->marker->next_restart_num)) + return FALSE; + } + + /* Update next-restart state */ + cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; + + return TRUE; +} + + +/* + * This is the default resync_to_restart method for data source managers + * to use if they don't have any better approach. Some data source managers + * may be able to back up, or may have additional knowledge about the data + * which permits a more intelligent recovery strategy; such managers would + * presumably supply their own resync method. + * + * read_restart_marker calls resync_to_restart if it finds a marker other than + * the restart marker it was expecting. (This code is *not* used unless + * a nonzero restart interval has been declared.) cinfo->unread_marker is + * the marker code actually found (might be anything, except 0 or FF). + * The desired restart marker number (0..7) is passed as a parameter. + * This routine is supposed to apply whatever error recovery strategy seems + * appropriate in order to position the input stream to the next data segment. + * Note that cinfo->unread_marker is treated as a marker appearing before + * the current data-source input point; usually it should be reset to zero + * before returning. + * Returns FALSE if suspension is required. + * + * This implementation is substantially constrained by wanting to treat the + * input as a data stream; this means we can't back up. Therefore, we have + * only the following actions to work with: + * 1. Simply discard the marker and let the entropy decoder resume at next + * byte of file. + * 2. Read forward until we find another marker, discarding intervening + * data. (In theory we could look ahead within the current bufferload, + * without having to discard data if we don't find the desired marker. + * This idea is not implemented here, in part because it makes behavior + * dependent on buffer size and chance buffer-boundary positions.) + * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). + * This will cause the entropy decoder to process an empty data segment, + * inserting dummy zeroes, and then we will reprocess the marker. + * + * #2 is appropriate if we think the desired marker lies ahead, while #3 is + * appropriate if the found marker is a future restart marker (indicating + * that we have missed the desired restart marker, probably because it got + * corrupted). + * We apply #2 or #3 if the found marker is a restart marker no more than + * two counts behind or ahead of the expected one. We also apply #2 if the + * found marker is not a legal JPEG marker code (it's certainly bogus data). + * If the found marker is a restart marker more than 2 counts away, we do #1 + * (too much risk that the marker is erroneous; with luck we will be able to + * resync at some future point). + * For any valid non-restart JPEG marker, we apply #3. This keeps us from + * overrunning the end of a scan. An implementation limited to single-scan + * files might find it better to apply #2 for markers other than EOI, since + * any other marker would have to be bogus data in that case. + */ + +GLOBAL boolean +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + int marker = cinfo->unread_marker; + int action = 1; + + /* Always put up a warning. */ + WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); + + /* Outer loop handles repeated decision after scanning forward. */ + for (;;) { + if (marker < (int) M_SOF0) + action = 2; /* invalid marker */ + else if (marker < (int) M_RST0 || marker > (int) M_RST7) + action = 3; /* valid non-restart marker */ + else { + if (marker == ((int) M_RST0 + ((desired+1) & 7)) || + marker == ((int) M_RST0 + ((desired+2) & 7))) + action = 3; /* one of the next two expected restarts */ + else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || + marker == ((int) M_RST0 + ((desired-2) & 7))) + action = 2; /* a prior restart, so advance */ + else + action = 1; /* desired restart or too far away */ + } + TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); + switch (action) { + case 1: + /* Discard marker and let entropy decoder resume processing. */ + cinfo->unread_marker = 0; + return TRUE; + case 2: + /* Scan to the next marker, and repeat the decision loop. */ + if (! next_marker(cinfo)) + return FALSE; + marker = cinfo->unread_marker; + break; + case 3: + /* Return without advancing past this marker. */ + /* Entropy decoder will be forced to process an empty segment. */ + return TRUE; + } + } /* end loop */ +} + + +/* + * Reset marker processing state to begin a fresh datastream. + */ + +METHODDEF void +reset_marker_reader (j_decompress_ptr cinfo) +{ + cinfo->comp_info = NULL; /* until allocated by get_sof */ + cinfo->input_scan_number = 0; /* no SOS seen yet */ + cinfo->unread_marker = 0; /* no pending marker */ + cinfo->marker->saw_SOI = FALSE; /* set internal state too */ + cinfo->marker->saw_SOF = FALSE; + cinfo->marker->discarded_bytes = 0; +} + + +/* + * Initialize the marker reader module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL void +jinit_marker_reader (j_decompress_ptr cinfo) +{ + int i; + + /* Create subobject in permanent pool */ + cinfo->marker = (struct jpeg_marker_reader *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(struct jpeg_marker_reader)); + /* Initialize method pointers */ + cinfo->marker->reset_marker_reader = reset_marker_reader; + cinfo->marker->read_markers = read_markers; + cinfo->marker->read_restart_marker = read_restart_marker; + cinfo->marker->process_COM = skip_variable; + for (i = 0; i < 16; i++) + cinfo->marker->process_APPn[i] = skip_variable; + cinfo->marker->process_APPn[0] = get_app0; + cinfo->marker->process_APPn[14] = get_app14; + /* Reset marker processing state */ + reset_marker_reader(cinfo); +} diff --git a/renderer/jpeg-6/jdmaster.c b/renderer/jpeg-6/jdmaster.c new file mode 100644 index 000000000..18e088094 --- /dev/null +++ b/renderer/jpeg-6/jdmaster.c @@ -0,0 +1,557 @@ +/* + * jdmaster.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_decomp_master pub; /* public fields */ + + int pass_number; /* # of passes completed */ + + boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ + + /* Saved references to initialized quantizer modules, + * in case we need to switch modes. + */ + struct jpeg_color_quantizer * quantizer_1pass; + struct jpeg_color_quantizer * quantizer_2pass; +} my_decomp_master; + +typedef my_decomp_master * my_master_ptr; + + +/* + * Determine whether merged upsample/color conversion should be used. + * CRUCIAL: this must match the actual capabilities of jdmerge.c! + */ + +LOCAL boolean +use_merged_upsample (j_decompress_ptr cinfo) +{ +#ifdef UPSAMPLE_MERGING_SUPPORTED + /* Merging is the equivalent of plain box-filter upsampling */ + if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) + return FALSE; + /* jdmerge.c only supports YCC=>RGB color conversion */ + if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || + cinfo->out_color_space != JCS_RGB || + cinfo->out_color_components != RGB_PIXELSIZE) + return FALSE; + /* and it only handles 2h1v or 2h2v sampling ratios */ + if (cinfo->comp_info[0].h_samp_factor != 2 || + cinfo->comp_info[1].h_samp_factor != 1 || + cinfo->comp_info[2].h_samp_factor != 1 || + cinfo->comp_info[0].v_samp_factor > 2 || + cinfo->comp_info[1].v_samp_factor != 1 || + cinfo->comp_info[2].v_samp_factor != 1) + return FALSE; + /* furthermore, it doesn't work if we've scaled the IDCTs differently */ + if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) + return FALSE; + /* ??? also need to test for upsample-time rescaling, when & if supported */ + return TRUE; /* by golly, it'll work... */ +#else + return FALSE; +#endif +} + + +/* + * Compute output image dimensions and related values. + * NOTE: this is exported for possible use by application. + * Hence it mustn't do anything that can't be done twice. + * Also note that it may be called before the master module is initialized! + */ + +GLOBAL void +jpeg_calc_output_dimensions (j_decompress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ +#if 0 // JDC: commented out to remove warning + int ci; + jpeg_component_info *compptr; +#endif + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_READY) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +#ifdef IDCT_SCALING_SUPPORTED + + /* Compute actual output image dimensions and DCT scaling choices. */ + if (cinfo->scale_num * 8 <= cinfo->scale_denom) { + /* Provide 1/8 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 8L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 8L); + cinfo->min_DCT_scaled_size = 1; + } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { + /* Provide 1/4 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 4L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 4L); + cinfo->min_DCT_scaled_size = 2; + } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { + /* Provide 1/2 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 2L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 2L); + cinfo->min_DCT_scaled_size = 4; + } else { + /* Provide 1/1 scaling */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + cinfo->min_DCT_scaled_size = DCTSIZE; + } + /* In selecting the actual DCT scaling for each component, we try to + * scale up the chroma components via IDCT scaling rather than upsampling. + * This saves time if the upsampler gets to use 1:1 scaling. + * Note this code assumes that the supported DCT scalings are powers of 2. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + int ssize = cinfo->min_DCT_scaled_size; + while (ssize < DCTSIZE && + (compptr->h_samp_factor * ssize * 2 <= + cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && + (compptr->v_samp_factor * ssize * 2 <= + cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { + ssize = ssize * 2; + } + compptr->DCT_scaled_size = ssize; + } + + /* Recompute downsampled dimensions of components; + * application needs to know these if using raw downsampled data. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Size in samples, after IDCT scaling */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * + (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * + (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + } + +#else /* !IDCT_SCALING_SUPPORTED */ + + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + * and has computed unscaled downsampled_width and downsampled_height. + */ + +#endif /* IDCT_SCALING_SUPPORTED */ + + /* Report number of components in selected colorspace. */ + /* Probably this should be in the color conversion module... */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + break; + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + cinfo->out_color_components = RGB_PIXELSIZE; + break; +#endif /* else share code with YCbCr */ + case JCS_YCbCr: + cinfo->out_color_components = 3; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo->out_color_components = 4; + break; + default: /* else must be same colorspace as in file */ + cinfo->out_color_components = cinfo->num_components; + break; + } + cinfo->output_components = (cinfo->quantize_colors ? 1 : + cinfo->out_color_components); + + /* See if upsampler will want to emit more than one row at a time */ + if (use_merged_upsample(cinfo)) + cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; + else + cinfo->rec_outbuf_height = 1; +} + + +/* + * Several decompression processes need to range-limit values to the range + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range + * due to noise introduced by quantization, roundoff error, etc. These + * processes are inner loops and need to be as fast as possible. On most + * machines, particularly CPUs with pipelines or instruction prefetch, + * a (subscript-check-less) C table lookup + * x = sample_range_limit[x]; + * is faster than explicit tests + * if (x < 0) x = 0; + * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; + * These processes all use a common table prepared by the routine below. + * + * For most steps we can mathematically guarantee that the initial value + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + * limiting step (just after the IDCT), a wildly out-of-range value is + * possible if the input data is corrupt. To avoid any chance of indexing + * off the end of memory and getting a bad-pointer trap, we perform the + * post-IDCT limiting thus: + * x = range_limit[x & MASK]; + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + * samples. Under normal circumstances this is more than enough range and + * a correct output will be generated; with bogus input data the mask will + * cause wraparound, and we will safely generate a bogus-but-in-range output. + * For the post-IDCT step, we want to convert the data from signed to unsigned + * representation by adding CENTERJSAMPLE at the same time that we limit it. + * So the post-IDCT limiting table ends up looking like this: + * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0,1,...,CENTERJSAMPLE-1 + * Negative inputs select values from the upper half of the table after + * masking. + * + * We can save some space by overlapping the start of the post-IDCT table + * with the simpler range limiting table. The post-IDCT table begins at + * sample_range_limit + CENTERJSAMPLE. + * + * Note that the table is allocated in near data space on PCs; it's small + * enough and used often enough to justify this. + */ + +LOCAL void +prepare_range_limit_table (j_decompress_ptr cinfo) +/* Allocate and fill in the sample_range_limit table */ +{ + JSAMPLE * table; + int i; + + table = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ + cinfo->sample_range_limit = table; + /* First segment of "simple" table: limit[x] = 0 for x < 0 */ + MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + /* Main part of "simple" table: limit[x] = x */ + for (i = 0; i <= MAXJSAMPLE; i++) + table[i] = (JSAMPLE) i; + table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ + /* End of simple table, rest of first half of post-IDCT table */ + for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) + table[i] = MAXJSAMPLE; + /* Second half of post-IDCT table */ + MEMZERO(table + (2 * (MAXJSAMPLE+1)), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), + cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); +} + + +/* + * Master selection of decompression modules. + * This is done once at jpeg_start_decompress time. We determine + * which modules will be used and give them appropriate initialization calls. + * We also initialize the decompressor input side to begin consuming data. + * + * Since jpeg_read_header has finished, we know what is in the SOF + * and (first) SOS markers. We also have all the application parameter + * settings. + */ + +LOCAL void +master_selection (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + boolean use_c_buffer; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Initialize dimensions and other stuff */ + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + /* Width of an output scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* Initialize my private state */ + master->pass_number = 0; + master->using_merged_upsample = use_merged_upsample(cinfo); + + /* Color quantizer selection */ + master->quantizer_1pass = NULL; + master->quantizer_2pass = NULL; + /* No mode changes if not using buffered-image mode. */ + if (! cinfo->quantize_colors || ! cinfo->buffered_image) { + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + } + if (cinfo->quantize_colors) { + if (cinfo->raw_data_out) + ERREXIT(cinfo, JERR_NOTIMPL); + /* 2-pass quantizer only works in 3-component color space. */ + if (cinfo->out_color_components != 3) { + cinfo->enable_1pass_quant = TRUE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + cinfo->colormap = NULL; + } else if (cinfo->colormap != NULL) { + cinfo->enable_external_quant = TRUE; + } else if (cinfo->two_pass_quantize) { + cinfo->enable_2pass_quant = TRUE; + } else { + cinfo->enable_1pass_quant = TRUE; + } + + if (cinfo->enable_1pass_quant) { +#ifdef QUANT_1PASS_SUPPORTED + jinit_1pass_quantizer(cinfo); + master->quantizer_1pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + /* We use the 2-pass code to map to external colormaps. */ + if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { +#ifdef QUANT_2PASS_SUPPORTED + jinit_2pass_quantizer(cinfo); + master->quantizer_2pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + /* If both quantizers are initialized, the 2-pass one is left active; + * this is necessary for starting with quantization to an external map. + */ + } + + /* Post-processing: in particular, color conversion first */ + if (! cinfo->raw_data_out) { + if (master->using_merged_upsample) { +#ifdef UPSAMPLE_MERGING_SUPPORTED + jinit_merged_upsampler(cinfo); /* does color conversion too */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + } + jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); + } + /* Inverse DCT */ + jinit_inverse_dct(cinfo); + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Initialize principal buffer controllers. */ + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (! cinfo->raw_data_out) + jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* If jpeg_start_decompress will read the whole file, initialize + * progress monitoring appropriately. The input step is counted + * as one pass. + */ + if (cinfo->progress != NULL && ! cinfo->buffered_image && + cinfo->inputctl->has_multiple_scans) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); + /* Count the input pass as done */ + master->pass_number++; + } +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +} + + +/* + * Per-pass setup. + * This is called at the beginning of each output pass. We determine which + * modules will be active during this pass and give them appropriate + * start_pass calls. We also set is_dummy_pass to indicate whether this + * is a "real" output pass or a dummy pass for color quantization. + * (In the latter case, jdapi.c will crank the pass to completion.) + */ + +METHODDEF void +prepare_for_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (master->pub.is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Final pass of 2-pass quantization */ + master->pub.is_dummy_pass = FALSE; + (*cinfo->cquantize->start_pass) (cinfo, FALSE); + (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); + (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + if (cinfo->quantize_colors && cinfo->colormap == NULL) { + /* Select new quantization method */ + if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { + cinfo->cquantize = master->quantizer_2pass; + master->pub.is_dummy_pass = TRUE; + } else if (cinfo->enable_1pass_quant) { + cinfo->cquantize = master->quantizer_1pass; + } else { + ERREXIT(cinfo, JERR_MODE_CHANGE); + } + } + (*cinfo->idct->start_pass) (cinfo); + (*cinfo->coef->start_output_pass) (cinfo); + if (! cinfo->raw_data_out) { + if (! master->using_merged_upsample) + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->upsample->start_pass) (cinfo); + if (cinfo->quantize_colors) + (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); + (*cinfo->post->start_pass) (cinfo, + (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + } + } + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->pass_number + + (master->pub.is_dummy_pass ? 2 : 1); + /* In buffered-image mode, we assume one more output pass if EOI not + * yet reached, but no more passes if EOI has been reached. + */ + if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { + cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); + } + } +} + + +/* + * Finish up at end of an output pass. + */ + +METHODDEF void +finish_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (cinfo->quantize_colors) + (*cinfo->cquantize->finish_pass) (cinfo); + master->pass_number++; +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Switch to a new external colormap between output passes. + */ + +GLOBAL void +jpeg_new_colormap (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_BUFIMAGE) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (cinfo->quantize_colors && cinfo->enable_external_quant && + cinfo->colormap != NULL) { + /* Select 2-pass quantizer for external colormap use */ + cinfo->cquantize = master->quantizer_2pass; + /* Notify quantizer of colormap change */ + (*cinfo->cquantize->new_color_map) (cinfo); + master->pub.is_dummy_pass = FALSE; /* just in case */ + } else + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize master decompression control and select active modules. + * This is performed at the start of jpeg_start_decompress. + */ + +GLOBAL void +jinit_master_decompress (j_decompress_ptr cinfo) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_decomp_master)); + cinfo->master = (struct jpeg_decomp_master *) master; + master->pub.prepare_for_output_pass = prepare_for_output_pass; + master->pub.finish_output_pass = finish_output_pass; + + master->pub.is_dummy_pass = FALSE; + + master_selection(cinfo); +} diff --git a/renderer/jpeg-6/jdmerge.c b/renderer/jpeg-6/jdmerge.c new file mode 100644 index 000000000..95585fb83 --- /dev/null +++ b/renderer/jpeg-6/jdmerge.c @@ -0,0 +1,400 @@ +/* + * jdmerge.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains code for merged upsampling/color conversion. + * + * This file combines functions from jdsample.c and jdcolor.c; + * read those files first to understand what's going on. + * + * When the chroma components are to be upsampled by simple replication + * (ie, box filtering), we can save some work in color conversion by + * calculating all the output pixels corresponding to a pair of chroma + * samples at one time. In the conversion equations + * R = Y + K1 * Cr + * G = Y + K2 * Cb + K3 * Cr + * B = Y + K4 * Cb + * only the Y term varies among the group of pixels corresponding to a pair + * of chroma samples, so the rest of the terms can be calculated just once. + * At typical sampling ratios, this eliminates half or three-quarters of the + * multiplications needed for color conversion. + * + * This file currently provides implementations for the following cases: + * YCbCr => RGB color conversion only. + * Sampling ratios of 2h1v or 2h2v. + * No scaling needed at upsample time. + * Corner-aligned (non-CCIR601) sampling alignment. + * Other special cases could be added, but in most applications these are + * the only common cases. (For uncommon cases we fall back on the more + * general code in jdsample.c and jdcolor.c.) + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef UPSAMPLE_MERGING_SUPPORTED + + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Pointer to routine to do actual upsampling/conversion of one row group */ + JMETHOD(void, upmethod, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf)); + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ + + /* For 2:1 vertical sampling, we produce two output rows at a time. + * We need a "spare" row buffer to hold the second output row if the + * application provides just a one-row buffer; we also use the spare + * to discard the dummy last row if the image height is odd. + */ + JSAMPROW spare_row; + boolean spare_full; /* T if spare buffer is occupied */ + + JDIMENSION out_row_width; /* samples per output row */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + * This is taken directly from jdcolor.c; see that file for more info. + */ + +LOCAL void +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int i; + INT32 x; + SHIFT_TEMPS + + upsample->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + upsample->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + upsample->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + upsample->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF void +start_pass_merged_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the spare buffer empty */ + upsample->spare_full = FALSE; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * The control routine just handles the row buffering considerations. + */ + +METHODDEF void +merged_2v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 2:1 vertical sampling case: may need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPROW work_ptrs[2]; + JDIMENSION num_rows; /* number of rows returned to caller */ + + if (upsample->spare_full) { + /* If we have a spare row saved from a previous cycle, just return it. */ + jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, + 1, upsample->out_row_width); + num_rows = 1; + upsample->spare_full = FALSE; + } else { + /* Figure number of rows to return to caller. */ + num_rows = 2; + /* Not more than the distance to the end of the image. */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + /* Create output pointer array for upsampler. */ + work_ptrs[0] = output_buf[*out_row_ctr]; + if (num_rows > 1) { + work_ptrs[1] = output_buf[*out_row_ctr + 1]; + } else { + work_ptrs[1] = upsample->spare_row; + upsample->spare_full = TRUE; + } + /* Now do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); + } + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (! upsample->spare_full) + (*in_row_group_ctr)++; +} + + +METHODDEF void +merged_1v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 1:1 vertical sampling case: much easier, never need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Just do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, + output_buf + *out_row_ctr); + /* Adjust counts */ + (*out_row_ctr)++; + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by the control routines to do + * the actual upsampling/conversion. One row group is processed per call. + * + * Note: since we may be writing directly into application-supplied buffers, + * we have to be honest about the output width; we can't assume the buffer + * has been rounded up to an even width. + */ + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. + */ + +METHODDEF void +h2v1_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr0 = input_buf[0][in_row_group_ctr]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr = output_buf[0]; + /* Loop for each pair of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 2 Y values and emit 2 pixels */ + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr0); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. + */ + +METHODDEF void +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Module initialization routine for merged upsampling/color conversion. + * + * NB: this is called under the conditions determined by use_merged_upsample() + * in jdmaster.c. That routine MUST correspond to the actual capabilities + * of this module; no safety checks are made here. + */ + +GLOBAL void +jinit_merged_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_merged_upsample; + upsample->pub.need_context_rows = FALSE; + + upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; + + if (cinfo->max_v_samp_factor == 2) { + upsample->pub.upsample = merged_2v_upsample; + upsample->upmethod = h2v2_merged_upsample; + /* Allocate a spare row buffer */ + upsample->spare_row = (JSAMPROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); + } else { + upsample->pub.upsample = merged_1v_upsample; + upsample->upmethod = h2v1_merged_upsample; + /* No spare row needed */ + upsample->spare_row = NULL; + } + + build_ycc_rgb_table(cinfo); +} + +#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/renderer/jpeg-6/jdphuff.c b/renderer/jpeg-6/jdphuff.c new file mode 100644 index 000000000..025bfd80c --- /dev/null +++ b/renderer/jpeg-6/jdphuff.c @@ -0,0 +1,642 @@ +/* + * jdphuff.c + * + * Copyright (C) 1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for progressive JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdhuff.c */ + + +#ifdef D_PROGRESSIVE_SUPPORTED + +/* + * Expanded entropy decoder object for progressive Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).EOBRUN = (src).EOBRUN, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ +} phuff_entropy_decoder; + +typedef phuff_entropy_decoder * phuff_entropy_ptr; + +/* Forward declarations */ +METHODDEF boolean decode_mcu_DC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean decode_mcu_AC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF boolean decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF void +start_pass_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band, bad; + int ci, coefi, tbl; + int *coef_bit_ptr; + jpeg_component_info * compptr; + + is_DC_band = (cinfo->Ss == 0); + + /* Validate scan parameters */ + bad = FALSE; + if (is_DC_band) { + if (cinfo->Se != 0) + bad = TRUE; + } else { + /* need not check Ss/Se < 0 since they came from unsigned bytes */ + if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) + bad = TRUE; + /* AC scans may have only one component */ + if (cinfo->comps_in_scan != 1) + bad = TRUE; + } + if (cinfo->Ah != 0) { + /* Successive approximation refinement scan: must have Al = Ah-1. */ + if (cinfo->Al != cinfo->Ah-1) + bad = TRUE; + } + if (cinfo->Al > 13) /* need not check for < 0 */ + bad = TRUE; + if (bad) + ERREXIT4(cinfo, JERR_BAD_PROGRESSION, + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + /* Update progression status, and verify that scan order is legal. + * Note that inter-scan inconsistencies are treated as warnings + * not fatal errors ... not clear if this is right way to behave. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + int cindex = cinfo->cur_comp_info[ci]->component_index; + coef_bit_ptr = & cinfo->coef_bits[cindex][0]; + if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { + int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; + if (cinfo->Ah != expected) + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr[coefi] = cinfo->Al; + } + } + + /* Select MCU decoding routine */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_first; + else + entropy->pub.decode_mcu = decode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_refine; + else + entropy->pub.decode_mcu = decode_mcu_AC_refine; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Make sure requested tables are present, and compute derived tables. + * We may build same derived table more than once, but it's not expensive. + */ + if (is_DC_band) { + if (cinfo->Ah == 0) { /* DC refinement needs no table */ + tbl = compptr->dc_tbl_no; + if (tbl < 0 || tbl >= NUM_HUFF_TBLS || + cinfo->dc_huff_tbl_ptrs[tbl] == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); + jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], + & entropy->derived_tbls[tbl]); + } + } else { + tbl = compptr->ac_tbl_no; + if (tbl < 0 || tbl >= NUM_HUFF_TBLS || + cinfo->ac_huff_tbl_ptrs[tbl] == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); + jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], + & entropy->derived_tbls[tbl]); + /* remember the single active table */ + entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->bitstate.printed_eod = FALSE; + + /* Initialize private state variables */ + entropy->saved.EOBRUN = 0; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL boolean +process_restart (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Re-init EOB run count, too */ + entropy->saved.EOBRUN = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Next segment can get another out-of-data warning */ + entropy->bitstate.printed_eod = FALSE; + + return TRUE; +} + + +/* + * Huffman MCU decoding. + * Each of these routines decodes and returns one MCU's worth of + * Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + * + * We return FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * spectral selection, since we'll just re-assign them on the next call. + * Successive approximation AC refinement has to be more careful, however.) + */ + +/* + * MCU decoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF boolean +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Al = cinfo->Al; + register int s, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state state; + d_derived_tbl * tbl; + jpeg_component_info * compptr; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, tbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */ + (*block)[0] = (JCOEF) (s << Al); + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF boolean +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int Al = cinfo->Al; + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Load up working state. + * We can avoid loading/saving bitread state if in an EOB run. + */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ + + /* There is always only one block per MCU */ + + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ + else { + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + for (k = cinfo->Ss; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } + } + } + + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + } + + /* Completed MCU, so update state */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF boolean +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int blkn; + JBLOCKROW block; + BITREAD_STATE_VARS; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* Encoded data is simply the next bit of the two's-complement DC value */ + CHECK_BIT_BUFFER(br_state, 1, return FALSE); + if (GET_BITS(1)) + (*block)[0] |= p1; + /* Note: since we use |=, repeating the assignment later is safe */ + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC successive approximation refinement scan. + */ + +METHODDEF boolean +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + JCOEFPTR thiscoef; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + int num_newnz; + int newnz_pos[DCTSIZE2]; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ + + /* There is always only one block per MCU */ + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + /* If we are forced to suspend, we must undo the assignments to any newly + * nonzero coefficients in the block, because otherwise we'd get confused + * next time about which coefficients were already nonzero. + * But we need not undo addition of bits to already-nonzero coefficients; + * instead, we can test the current bit position to see if we already did it. + */ + num_newnz = 0; + + /* initialize coefficient loop counter to start of band */ + k = cinfo->Ss; + + if (EOBRUN == 0) { + for (; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ + } + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; + } + } + } + + if (EOBRUN > 0) { + /* Scan any remaining coefficient positions after the end-of-band + * (the last newly nonzero coefficient, if any). Append a correction + * bit to each already-nonzero coefficient. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + for (; k <= Se; k++) { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } + } + /* Count one block completed in EOB run */ + EOBRUN--; + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; + +undoit: + /* Re-zero any output coefficients that we made newly nonzero */ + while (num_newnz > 0) + (*block)[newnz_pos[--num_newnz]] = 0; + + return FALSE; +} + + +/* + * Module initialization routine for progressive Huffman entropy decoding. + */ + +GLOBAL void +jinit_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int *coef_bit_ptr; + int ci, i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_phuff_decoder; + + /* Mark derived tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + } + + /* Create progression status table */ + cinfo->coef_bits = (int (*)[DCTSIZE2]) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components*DCTSIZE2*SIZEOF(int)); + coef_bit_ptr = & cinfo->coef_bits[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (i = 0; i < DCTSIZE2; i++) + *coef_bit_ptr++ = -1; +} + +#endif /* D_PROGRESSIVE_SUPPORTED */ diff --git a/renderer/jpeg-6/jdpostct.c b/renderer/jpeg-6/jdpostct.c new file mode 100644 index 000000000..f61200235 --- /dev/null +++ b/renderer/jpeg-6/jdpostct.c @@ -0,0 +1,290 @@ +/* + * jdpostct.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_post_controller pub; /* public fields */ + + /* Color quantization source buffer: this holds output data from + * the upsample/color conversion step to be passed to the quantizer. + * For two-pass color quantization, we need a full-image buffer; + * for one-pass operation, a strip buffer is sufficient. + */ + jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ + JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ + JDIMENSION strip_height; /* buffer size in rows */ + /* for two-pass mode only: */ + JDIMENSION starting_row; /* row # of first row in current strip */ + JDIMENSION next_row; /* index of next row to fill/empty in strip */ +} my_post_controller; + +typedef my_post_controller * my_post_ptr; + + +/* Forward declarations */ +METHODDEF void post_process_1pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF void post_process_prepass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +METHODDEF void post_process_2pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->quantize_colors) { + /* Single-pass processing with color quantization. */ + post->pub.post_process_data = post_process_1pass; + /* We could be doing buffered-image output before starting a 2-pass + * color quantization; in that case, jinit_d_post_controller did not + * allocate a strip buffer. Use the virtual-array buffer as workspace. + */ + if (post->buffer == NULL) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + (JDIMENSION) 0, post->strip_height, TRUE); + } + } else { + /* For single-pass processing without color quantization, + * I have no work to do; just call the upsampler directly. + */ + post->pub.post_process_data = cinfo->upsample->upsample; + } + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_SAVE_AND_PASS: + /* First pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_prepass; + break; + case JBUF_CRANK_DEST: + /* Second pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_2pass; + break; +#endif /* QUANT_2PASS_SUPPORTED */ + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } + post->starting_row = post->next_row = 0; +} + + +/* + * Process some data in the one-pass (strip buffer) case. + * This is used for color precision reduction as well as one-pass quantization. + */ + +METHODDEF void +post_process_1pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Fill the buffer, but not more than what we can dump out in one go. */ + /* Note we rely on the upsampler to detect bottom of image. */ + max_rows = out_rows_avail - *out_row_ctr; + if (max_rows > post->strip_height) + max_rows = post->strip_height; + num_rows = 0; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &num_rows, max_rows); + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer, output_buf + *out_row_ctr, (int) num_rows); + *out_row_ctr += num_rows; +} + + +#ifdef QUANT_2PASS_SUPPORTED + +/* + * Process some data in the first pass of 2-pass quantization. + */ + +METHODDEF void +post_process_prepass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION old_next_row, num_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, TRUE); + } + + /* Upsample some data (up to a strip height's worth). */ + old_next_row = post->next_row; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &post->next_row, post->strip_height); + + /* Allow quantizer to scan new data. No data is emitted, */ + /* but we advance out_row_ctr so outer loop can tell when we're done. */ + if (post->next_row > old_next_row) { + num_rows = post->next_row - old_next_row; + (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, + (JSAMPARRAY) NULL, (int) num_rows); + *out_row_ctr += num_rows; + } + + /* Advance if we filled the strip. */ + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + + +/* + * Process some data in the second pass of 2-pass quantization. + */ + +METHODDEF void +post_process_2pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, FALSE); + } + + /* Determine number of rows to emit. */ + num_rows = post->strip_height - post->next_row; /* available in strip */ + max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ + if (num_rows > max_rows) + num_rows = max_rows; + /* We have to check bottom of image here, can't depend on upsampler. */ + max_rows = cinfo->output_height - post->starting_row; + if (num_rows > max_rows) + num_rows = max_rows; + + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer + post->next_row, output_buf + *out_row_ctr, + (int) num_rows); + *out_row_ctr += num_rows; + + /* Advance if we filled the strip. */ + post->next_row += num_rows; + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize postprocessing controller. + */ + +GLOBAL void +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_post_ptr post; + + post = (my_post_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_post_controller)); + cinfo->post = (struct jpeg_d_post_controller *) post; + post->pub.start_pass = start_pass_dpost; + post->whole_image = NULL; /* flag for no virtual arrays */ + post->buffer = NULL; /* flag for no strip buffer */ + + /* Create the quantization buffer, if needed */ + if (cinfo->quantize_colors) { + /* The buffer strip height is max_v_samp_factor, which is typically + * an efficient number of rows for upsampling to return. + * (In the presence of output rescaling, we might want to be smarter?) + */ + post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; + if (need_full_buffer) { + /* Two-pass color quantization: need full-image storage. */ + /* We round up the number of rows to a multiple of the strip height. */ +#ifdef QUANT_2PASS_SUPPORTED + post->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + cinfo->output_width * cinfo->out_color_components, + (JDIMENSION) jround_up((long) cinfo->output_height, + (long) post->strip_height), + post->strip_height); +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + /* One-pass color quantization: just make a strip buffer. */ + post->buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->out_color_components, + post->strip_height); + } + } +} diff --git a/renderer/jpeg-6/jdsample.c b/renderer/jpeg-6/jdsample.c new file mode 100644 index 000000000..661e198dc --- /dev/null +++ b/renderer/jpeg-6/jdsample.c @@ -0,0 +1,478 @@ +/* + * jdsample.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains upsampling routines. + * + * Upsampling input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to upsample a single component */ +typedef JMETHOD(void, upsample1_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Color conversion buffer. When using separate upsampling and color + * conversion steps, this buffer holds one upsampled row group until it + * has been color converted and output. + * Note: we do not allocate any storage for component(s) which are full-size, + * ie do not need rescaling. The corresponding entry of color_buf[] is + * simply set to point to the input data array, thereby avoiding copying. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + /* Per-component upsampling method pointers */ + upsample1_ptr methods[MAX_COMPONENTS]; + + int next_row_out; /* counts rows emitted from color_buf */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ + + /* Height of an input row group for each component. */ + int rowgroup_height[MAX_COMPONENTS]; + + /* These arrays save pixel expansion factors so that int_expand need not + * recompute them each time. They are unused for other upsampling methods. + */ + UINT8 h_expand[MAX_COMPONENTS]; + UINT8 v_expand[MAX_COMPONENTS]; +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF void +start_pass_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the conversion buffer empty */ + upsample->next_row_out = cinfo->max_v_samp_factor; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * In this version we upsample each component independently. + * We upsample one row group into the conversion buffer, then apply + * color conversion a row at a time. + */ + +METHODDEF void +sep_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int ci; + jpeg_component_info * compptr; + JDIMENSION num_rows; + + /* Fill the conversion buffer, if it's empty */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Invoke per-component upsample method. Notice we pass a POINTER + * to color_buf[ci], so that fullsize_upsample can change it. + */ + (*upsample->methods[ci]) (cinfo, compptr, + input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), + upsample->color_buf + ci); + } + upsample->next_row_out = 0; + } + + /* Color-convert and emit rows */ + + /* How many we have in the buffer: */ + num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); + /* Not more than the distance to the end of the image. Need this test + * in case the image height is not a multiple of max_v_samp_factor: + */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + + (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, + (JDIMENSION) upsample->next_row_out, + output_buf + *out_row_ctr, + (int) num_rows); + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + upsample->next_row_out += num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by sep_upsample to upsample pixel values + * of a single component. One row group is processed per call. + */ + + +/* + * For full-size components, we just make color_buf[ci] point at the + * input buffer, and thus avoid copying any data. Note that this is + * safe only because sep_upsample doesn't declare the input row group + * "consumed" until we are done color converting and emitting it. + */ + +METHODDEF void +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = input_data; +} + + +/* + * This is a no-op version used for "uninteresting" components. + * These components will not be referenced by color conversion. + */ + +METHODDEF void +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = NULL; /* safety check */ +} + + +/* + * This version handles any integral sampling ratios. + * This is not used for typical JPEG files, so it need not be fast. + * Nor, for that matter, is it particularly accurate: the algorithm is + * simple replication of the input pixel onto the corresponding output + * pixels. The hi-falutin sampling literature refers to this as a + * "box filter". A box filter tends to introduce visible artifacts, + * so if you are actually going to use 3:1 or 4:1 sampling ratios + * you would be well advised to improve this code. + */ + +METHODDEF void +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + register int h; + JSAMPROW outend; + int h_expand, v_expand; + int inrow, outrow; + + h_expand = upsample->h_expand[compptr->component_index]; + v_expand = upsample->v_expand[compptr->component_index]; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + /* Generate one output row with proper horizontal expansion */ + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + for (h = h_expand; h > 0; h--) { + *outptr++ = invalue; + } + } + /* Generate any additional output rows by duplicating the first one */ + if (v_expand > 1) { + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo->output_width); + } + inrow++; + outrow += v_expand; + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + * It's still a box filter. + */ + +METHODDEF void +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + * It's still a box filter. + */ + +METHODDEF void +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow, outrow; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo->output_width); + inrow++; + outrow += 2; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + * + * The upsampling algorithm is linear interpolation between pixel centers, + * also known as a "triangle filter". This is a good compromise between + * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + * of the way between input pixel centers. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF void +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register int invalue; + register JDIMENSION colctr; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + /* Special case for first column */ + invalue = GETJSAMPLE(*inptr++); + *outptr++ = (JSAMPLE) invalue; + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ + invalue = GETJSAMPLE(*inptr++) * 3; + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); + } + + /* Special case for last column */ + invalue = GETJSAMPLE(*inptr); + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); + *outptr++ = (JSAMPLE) invalue; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + * Again a triangle filter; see comments for h2v1 case, above. + * + * It is OK for us to reference the adjacent input rows because we demanded + * context from the main buffer controller (see initialization code). + */ + +METHODDEF void +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 + register int thiscolsum, lastcolsum, nextcolsum; +#else + register INT32 thiscolsum, lastcolsum, nextcolsum; +#endif + register JDIMENSION colctr; + int inrow, outrow, v; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + for (v = 0; v < 2; v++) { + /* inptr0 points to nearest input row, inptr1 points to next nearest */ + inptr0 = input_data[inrow]; + if (v == 0) /* next nearest is row above */ + inptr1 = input_data[inrow-1]; + else /* next nearest is row below */ + inptr1 = input_data[inrow+1]; + outptr = output_data[outrow++]; + + /* Special case for first column */ + thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ + /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + } + + /* Special case for last column */ + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); + } + inrow++; + } +} + + +/* + * Module initialization routine for upsampling. + */ + +GLOBAL void +jinit_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + int ci; + jpeg_component_info * compptr; + boolean need_buffer, do_fancy; + int h_in_group, v_in_group, h_out_group, v_out_group; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_upsample; + upsample->pub.upsample = sep_upsample; + upsample->pub.need_context_rows = FALSE; /* until we find out differently */ + + if (cinfo->CCIR601_sampling) /* this isn't supported */ + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, + * so don't ask for it. + */ + do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + + /* Verify we can handle the sampling factors, select per-component methods, + * and create storage as needed. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Compute size of an "input group" after IDCT scaling. This many samples + * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. + */ + h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + h_out_group = cinfo->max_h_samp_factor; + v_out_group = cinfo->max_v_samp_factor; + upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ + need_buffer = TRUE; + if (! compptr->component_needed) { + /* Don't bother to upsample an uninteresting component. */ + upsample->methods[ci] = noop_upsample; + need_buffer = FALSE; + } else if (h_in_group == h_out_group && v_in_group == v_out_group) { + /* Fullsize components can be processed without any work. */ + upsample->methods[ci] = fullsize_upsample; + need_buffer = FALSE; + } else if (h_in_group * 2 == h_out_group && + v_in_group == v_out_group) { + /* Special cases for 2h1v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) + upsample->methods[ci] = h2v1_fancy_upsample; + else + upsample->methods[ci] = h2v1_upsample; + } else if (h_in_group * 2 == h_out_group && + v_in_group * 2 == v_out_group) { + /* Special cases for 2h2v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) { + upsample->methods[ci] = h2v2_fancy_upsample; + upsample->pub.need_context_rows = TRUE; + } else + upsample->methods[ci] = h2v2_upsample; + } else if ((h_out_group % h_in_group) == 0 && + (v_out_group % v_in_group) == 0) { + /* Generic integral-factors upsampling method */ + upsample->methods[ci] = int_upsample; + upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); + upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) { + upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) cinfo->output_width, + (long) cinfo->max_h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/renderer/jpeg-6/jdtrans.c b/renderer/jpeg-6/jdtrans.c new file mode 100644 index 000000000..5c14adc6a --- /dev/null +++ b/renderer/jpeg-6/jdtrans.c @@ -0,0 +1,122 @@ +/* + * jdtrans.c + * + * Copyright (C) 1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); + + +/* + * Read the coefficient arrays from a JPEG file. + * jpeg_read_header must be completed before calling this. + * + * The entire image is read into a set of virtual coefficient-block arrays, + * one per component. The return value is a pointer to the array of + * virtual-array descriptors. These can be manipulated directly via the + * JPEG memory manager, or handed off to jpeg_write_coefficients(). + * To release the memory occupied by the virtual arrays, call + * jpeg_finish_decompress() when done with the data. + * + * Returns NULL if suspended. This case need be checked only if + * a suspending data source is used. + */ + +GLOBAL jvirt_barray_ptr * +jpeg_read_coefficients (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize active modules */ + transdecode_master_selection(cinfo); + cinfo->global_state = DSTATE_RDCOEFS; + } else if (cinfo->global_state != DSTATE_RDCOEFS) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Absorb whole file into the coef buffer */ + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return NULL; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } + /* Set state so that jpeg_finish_decompress does the right thing */ + cinfo->global_state = DSTATE_STOPPING; + return cinfo->coef->coef_arrays; +} + + +/* + * Master selection of decompression modules for transcoding. + * This substitutes for jdmaster.c's initialization of the full decompressor. + */ + +LOCAL void +transdecode_master_selection (j_decompress_ptr cinfo) +{ + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Always get a full-image coefficient buffer. */ + jinit_d_coef_controller(cinfo, TRUE); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + + /* Initialize progress monitoring. */ + if (cinfo->progress != NULL) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else if (cinfo->inputctl->has_multiple_scans) { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } else { + nscans = 1; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = 1; + } +} diff --git a/renderer/jpeg-6/jerror.c b/renderer/jpeg-6/jerror.c new file mode 100644 index 000000000..06c447042 --- /dev/null +++ b/renderer/jpeg-6/jerror.c @@ -0,0 +1,234 @@ +/* + * jerror.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do. Many applications will want to replace + * some or all of these routines. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ + +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" + +extern jpg_Error( const char *fmt, ... ); +extern jpg_Printf( const char *fmt, ... ); + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" + NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error. Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object. Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF void +error_exit (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + jpg_Error( "%s\n", buffer ); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + */ + +METHODDEF void +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + + /* Send it to stderr, adding a newline */ + jpg_Printf( "%s\n", buffer ); +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF void +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF void +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF void +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; + * + * cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL struct jpeg_error_mgr * +jpeg_std_error (struct jpeg_error_mgr * err) +{ + err->error_exit = error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/renderer/jpeg-6/jerror.h b/renderer/jpeg-6/jerror.h new file mode 100644 index 000000000..bf60e7ecc --- /dev/null +++ b/renderer/jpeg-6/jerror.h @@ -0,0 +1,273 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_MINOR, "Unknown JFIF minor revision number %d.%02d") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/renderer/jpeg-6/jfdctflt.c b/renderer/jpeg-6/jfdctflt.c new file mode 100644 index 000000000..21371eb8f --- /dev/null +++ b/renderer/jpeg-6/jfdctflt.c @@ -0,0 +1,168 @@ +/* + * jfdctflt.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL void +jpeg_fdct_float (FAST_FLOAT * data) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; + FAST_FLOAT *dataptr; + int ctr; + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/renderer/jpeg-6/jfdctfst.c b/renderer/jpeg-6/jfdctfst.c new file mode 100644 index 000000000..a52d7b73c --- /dev/null +++ b/renderer/jpeg-6/jfdctfst.c @@ -0,0 +1,224 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jfdctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * Again to save a few shifts, the intermediate results between pass 1 and + * pass 2 are not upscaled, but are represented only to integral precision. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#define CONST_BITS 8 + + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ +#else +#define FIX_0_382683433 FIX(0.382683433) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_707106781 FIX(0.707106781) +#define FIX_1_306562965 FIX(1.306562965) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL void +jpeg_fdct_ifast (DCTELEM * data) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/renderer/jpeg-6/jfdctint.c b/renderer/jpeg-6/jfdctint.c new file mode 100644 index 000000000..7df043306 --- /dev/null +++ b/renderer/jpeg-6/jfdctint.c @@ -0,0 +1,283 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (For 12-bit sample data, the intermediate + * array is INT32 anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL void +jpeg_fdct_islow (DCTELEM * data) +{ + INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true DCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); + dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/renderer/jpeg-6/jidctflt.c b/renderer/jpeg-6/jidctflt.c new file mode 100644 index 000000000..847919eef --- /dev/null +++ b/renderer/jpeg-6/jidctflt.c @@ -0,0 +1,241 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a float result. + */ + +#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL void +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z5, z10, z11, z12, z13; + JCOEFPTR inptr; + FLOAT_MULT_TYPE * quantptr; + FAST_FLOAT * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | + inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero */ + FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = tmp0 + tmp7; + wsptr[DCTSIZE*7] = tmp0 - tmp7; + wsptr[DCTSIZE*1] = tmp1 + tmp6; + wsptr[DCTSIZE*6] = tmp1 - tmp6; + wsptr[DCTSIZE*2] = tmp2 + tmp5; + wsptr[DCTSIZE*5] = tmp2 - tmp5; + wsptr[DCTSIZE*4] = tmp3 + tmp4; + wsptr[DCTSIZE*3] = tmp3 - tmp4; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * And testing floats for zero is relatively expensive, so we don't bother. + */ + + /* Even part */ + + tmp10 = wsptr[0] + wsptr[4]; + tmp11 = wsptr[0] - wsptr[4]; + + tmp13 = wsptr[2] + wsptr[6]; + tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = wsptr[5] + wsptr[3]; + z10 = wsptr[5] - wsptr[3]; + z11 = wsptr[1] + wsptr[7]; + z12 = wsptr[1] - wsptr[7]; + + tmp7 = z11 + z13; + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/renderer/jpeg-6/jidctfst.c b/renderer/jpeg-6/jidctfst.c new file mode 100644 index 000000000..5736817e4 --- /dev/null +++ b/renderer/jpeg-6/jidctfst.c @@ -0,0 +1,367 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jidctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * The dequantized coefficients are not integers because the AA&N scaling + * factors have been incorporated. We represent them scaled up by PASS1_BITS, + * so that the first and second IDCT rounds have the same input scaling. + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + * avoid a descaling shift; this compromises accuracy rather drastically + * for small quantization table entries, but it saves a lot of shifts. + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + * so we use a much larger scaling factor to preserve accuracy. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 8 +#define PASS1_BITS 2 +#else +#define CONST_BITS 8 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ +#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ +#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ +#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ +#else +#define FIX_1_082392200 FIX(1.082392200) +#define FIX_1_414213562 FIX(1.414213562) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_613125930 FIX(2.613125930) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + * multiplication will do. For 12-bit data, the multiplier table is + * declared INT32, so a 32-bit multiply will be used. + */ + +#if BITS_IN_JSAMPLE == 8 +#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) +#else +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +#endif + + +/* Like DESCALE, but applies to a DCTELEM and produces an int. + * We assume that int right shift is unsigned if INT32 right shift is. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS DCTELEM ishift_temp; +#if BITS_IN_JSAMPLE == 8 +#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ +#else +#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ +#endif +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +#ifdef USE_ACCURATE_ROUNDING +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n)) +#else +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n)) +#endif + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL void +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z5, z10, z11, z12, z13; + JCOEFPTR inptr; + IFAST_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | + inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero */ + int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); + wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | + wsptr[7]) == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); + tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); + + tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); + tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) + - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; + z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; + z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; + z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/renderer/jpeg-6/jidctint.c b/renderer/jpeg-6/jidctint.c new file mode 100644 index 000000000..f25b08de1 --- /dev/null +++ b/renderer/jpeg-6/jidctint.c @@ -0,0 +1,388 @@ +/* + * jidctint.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + * larger than the true IDCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D IDCT, + * because the y0 and y4 inputs need not be divided by sqrt(N). + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (To scale up 12-bit sample data further, an + * intermediate INT32 array would be needed.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL void +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp1, tmp2, tmp3; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | + inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + + tmp0 = (z2 + z3) << CONST_BITS; + tmp1 = (z2 - z3) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | + wsptr[7]) == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = (INT32) wsptr[2]; + z3 = (INT32) wsptr[6]; + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS; + tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = (INT32) wsptr[7]; + tmp1 = (INT32) wsptr[5]; + tmp2 = (INT32) wsptr[3]; + tmp3 = (INT32) wsptr[1]; + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/renderer/jpeg-6/jidctred.c b/renderer/jpeg-6/jidctred.c new file mode 100644 index 000000000..019c339cc --- /dev/null +++ b/renderer/jpeg-6/jidctred.c @@ -0,0 +1,397 @@ +/* + * jidctred.c + * + * Copyright (C) 1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains inverse-DCT routines that produce reduced-size output: + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + * + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + * with an 8-to-4 step that produces the four averages of two adjacent outputs + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + * These steps were derived by computing the corresponding values at the end + * of the normal LL&M code, then simplifying as much as possible. + * + * 1x1 is trivial: just take the DC coefficient divided by 8. + * + * See jidctint.c for additional comments. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef IDCT_SCALING_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling is the same as in jidctint.c. */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ +#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ +#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ +#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ +#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ +#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ +#else +#define FIX_0_211164243 FIX(0.211164243) +#define FIX_0_509795579 FIX(0.509795579) +#define FIX_0_601344887 FIX(0.601344887) +#define FIX_0_720959822 FIX(0.720959822) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_850430095 FIX(0.850430095) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_061594337 FIX(1.061594337) +#define FIX_1_272758580 FIX(1.272758580) +#define FIX_1_451774981 FIX(1.451774981) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_172734803 FIX(2.172734803) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_624509785 FIX(3.624509785) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 4x4 output block. + */ + +GLOBAL void +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp2, tmp10, tmp12; + INT32 z1, z2, z3, z4; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*4]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process column 4, because second pass won't use it */ + if (ctr == DCTSIZE-4) + continue; + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero; we need not examine term 4 for 4x4 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp0 <<= (CONST_BITS+1); + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1); + } + + /* Pass 2: process 4 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 4; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] | + wsptr[7]) == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); + + tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) + + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = (INT32) wsptr[7]; + z2 = (INT32) wsptr[5]; + z3 = (INT32) wsptr[3]; + z4 = (INT32) wsptr[1]; + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 2x2 output block. + */ + +GLOBAL void +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp10, z1; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process columns 2,4,6 */ + if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) + continue; + if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] | + inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) { + /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + + continue; + } + + /* Even part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp10 = z1 << (CONST_BITS+2); + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2); + } + + /* Pass 2: process 2 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 2; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2); + + /* Odd part */ + + tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ + + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ + + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 1x1 output block. + */ + +GLOBAL void +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + int dcval; + ISLOW_MULT_TYPE * quantptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + SHIFT_TEMPS + + /* We hardly need an inverse DCT routine for this: just take the + * average pixel value, which is one-eighth of the DC coefficient. + */ + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + dcval = DEQUANTIZE(coef_block[0], quantptr[0]); + dcval = (int) DESCALE((INT32) dcval, 3); + + output_buf[0][output_col] = range_limit[dcval & RANGE_MASK]; +} + +#endif /* IDCT_SCALING_SUPPORTED */ diff --git a/renderer/jpeg-6/jinclude.h b/renderer/jpeg-6/jinclude.h new file mode 100644 index 000000000..9f93f465a --- /dev/null +++ b/renderer/jpeg-6/jinclude.h @@ -0,0 +1,91 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "../jpeg-6/jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include . + * Otherwise, we get them from or ; we may have to + * pull in as well. + * Note that the core JPEG library does not require ; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without . + */ + +#ifdef HAVE_STDDEF_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef NEED_SYS_TYPES_H +#include +#endif + +#include + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in . + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in . + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof(). However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long. To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object) ((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros. On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/renderer/jpeg-6/jload.c b/renderer/jpeg-6/jload.c new file mode 100644 index 000000000..8b39c5db6 --- /dev/null +++ b/renderer/jpeg-6/jload.c @@ -0,0 +1,145 @@ + +#include "../Shared/Shared.h" +#include "..\Common\Common.h" + +/* + * Include file for users of JPEG library. + * You will need to have included system headers that define at least + * the typedefs FILE and size_t before you can include jpeglib.h. + * (stdio.h is sufficient on ANSI-conforming systems.) + * You may also wish to include "jerror.h". + */ + +#include "jpeglib.h" + + +int LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) { + /* This struct contains the JPEG decompression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct cinfo; + /* We use our private extension JPEG error handler. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + fileHandle_t infile; /* source file */ + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + unsigned char *out; + + /* In this example we want to open the input file before doing anything else, + * so that the setjmp() error recovery below can assume the file is open. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to read binary files. + */ + + FS_FOpenFileRead( filename, &infile, qfalse ); + if (infile == 0) { + return 0; + } + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_stdio_src(&cinfo, infile); + + /* Step 3: read file parameters with jpeg_read_header() */ + + (void) jpeg_read_header(&cinfo, TRUE); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + + /* In this example, we don't need to change any of the defaults set by + * jpeg_read_header(), so we do nothing here. + */ + + /* Step 5: Start decompressor */ + + (void) jpeg_start_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = cinfo.output_width * cinfo.output_components; + + out = Z_Malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components); + + *pic = out; + *width = cinfo.output_width; + *height = cinfo.output_height; + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo.output_scanline < cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + buffer = (JSAMPARRAY)out+(row_stride*cinfo.output_scanline); + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + } + + /* Step 7: Finish decompression */ + + (void) jpeg_finish_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* Step 8: Release JPEG decompression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_decompress(&cinfo); + + /* After finish_decompress, we can close the input file. + * Here we postpone it until after no more JPEG errors are possible, + * so as to simplify the setjmp error logic above. (Actually, I don't + * think that jpeg_destroy can do an error exit, but why assume anything...) + */ + FS_FCloseFile(infile); + + /* At this point you may want to check to see whether any corrupt-data + * warnings occurred (test whether jerr.pub.num_warnings is nonzero). + */ + + /* And we're done! */ + return 1; +} + diff --git a/renderer/jpeg-6/jmemansi.c b/renderer/jpeg-6/jmemansi.c new file mode 100644 index 000000000..70010f96d --- /dev/null +++ b/renderer/jpeg-6/jmemansi.c @@ -0,0 +1,167 @@ +/* + * jmemansi.c + * + * Copyright (C) 1992-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a simple generic implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that you have the ANSI-standard library routine tmpfile(). + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL void * +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL void FAR * +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL long +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF void +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF void +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF void +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); + /* Since this implementation uses tmpfile() to create the file, + * no explicit file deletion is needed. + */ +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses tmpfile(), which constructs a suitable file name + * behind the scenes. We don't have to use info->temp_name[] at all; + * indeed, we can't even find out the actual name of the temp file. + */ + +GLOBAL void +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + if ((info->temp_file = tmpfile()) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL long +jpeg_mem_init (j_common_ptr cinfo) +{ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL void +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/renderer/jpeg-6/jmemdos.c b/renderer/jpeg-6/jmemdos.c new file mode 100644 index 000000000..4db8ec574 --- /dev/null +++ b/renderer/jpeg-6/jmemdos.c @@ -0,0 +1,634 @@ +/* + * jmemdos.c + * + * Copyright (C) 1992-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides an MS-DOS-compatible implementation of the system- + * dependent portion of the JPEG memory manager. Temporary data can be + * stored in extended or expanded memory as well as in regular DOS files. + * + * If you use this file, you must be sure that NEED_FAR_POINTERS is defined + * if you compile in a small-data memory model; it should NOT be defined if + * you use a large-data memory model. This file is not recommended if you + * are using a flat-memory-space 386 environment such as DJGCC or Watcom C. + * Also, this code will NOT work if struct fields are aligned on greater than + * 2-byte boundaries. + * + * Based on code contributed by Ge' Weijers. + */ + +/* + * If you have both extended and expanded memory, you may want to change the + * order in which they are tried in jopen_backing_store. On a 286 machine + * expanded memory is usually faster, since extended memory access involves + * an expensive protected-mode-and-back switch. On 386 and better, extended + * memory is usually faster. As distributed, the code tries extended memory + * first (what? not everyone has a 386? :-). + * + * You can disable use of extended/expanded memory entirely by altering these + * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0). + */ + +#ifndef XMS_SUPPORTED +#define XMS_SUPPORTED 1 +#endif +#ifndef EMS_SUPPORTED +#define EMS_SUPPORTED 1 +#endif + + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare these */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +extern char * getenv JPP((const char * name)); +#endif + +#ifdef NEED_FAR_POINTERS + +#ifdef __TURBOC__ +/* These definitions work for Borland C (Turbo C) */ +#include /* need farmalloc(), farfree() */ +#define far_malloc(x) farmalloc(x) +#define far_free(x) farfree(x) +#else +/* These definitions work for Microsoft C and compatible compilers */ +#include /* need _fmalloc(), _ffree() */ +#define far_malloc(x) _fmalloc(x) +#define far_free(x) _ffree(x) +#endif + +#else /* not NEED_FAR_POINTERS */ + +#define far_malloc(x) malloc(x) +#define far_free(x) free(x) + +#endif /* NEED_FAR_POINTERS */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#else +#define READ_BINARY "rb" +#endif + +#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ + MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ +#endif + + +/* + * Declarations for assembly-language support routines (see jmemdosa.asm). + * + * The functions are declared "far" as are all pointer arguments; + * this ensures the assembly source code will work regardless of the + * compiler memory model. We assume "short" is 16 bits, "long" is 32. + */ + +typedef void far * XMSDRIVER; /* actually a pointer to code */ +typedef struct { /* registers for calling XMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } XMScontext; +typedef struct { /* registers for calling EMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } EMScontext; + +EXTERN short far jdos_open JPP((short far * handle, char far * filename)); +EXTERN short far jdos_close JPP((short handle)); +EXTERN short far jdos_seek JPP((short handle, long offset)); +EXTERN short far jdos_read JPP((short handle, void far * buffer, + unsigned short count)); +EXTERN short far jdos_write JPP((short handle, void far * buffer, + unsigned short count)); +EXTERN void far jxms_getdriver JPP((XMSDRIVER far *)); +EXTERN void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); +EXTERN short far jems_available JPP((void)); +EXTERN void far jems_calldriver JPP((EMScontext far *)); + + +/* + * Selection of a file name for a temporary file. + * This is highly system-dependent, and you may want to customize it. + */ + +static int next_file_num; /* to distinguish among several temp files */ + +LOCAL void +select_file_name (char * fname) +{ + const char * env; + char * ptr; + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + /* Get temp directory name from environment TMP or TEMP variable; + * if none, use "." + */ + if ((env = (const char *) getenv("TMP")) == NULL) + if ((env = (const char *) getenv("TEMP")) == NULL) + env = "."; + if (*env == '\0') /* null string means "." */ + env = "."; + ptr = fname; /* copy name to fname */ + while (*env != '\0') + *ptr++ = *env++; + if (ptr[-1] != '\\' && ptr[-1] != '/') + *ptr++ = '\\'; /* append backslash if not in env variable */ + /* Append a suitable file name */ + next_file_num++; /* advance counter */ + sprintf(ptr, "JPG%03d.TMP", next_file_num); + /* Probe to see if file name is already in use */ + if ((tfile = fopen(fname, READ_BINARY)) == NULL) + break; + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + + +/* + * Near-memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL void * +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are allocated in far memory, if possible + */ + +GLOBAL void FAR * +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) far_malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + far_free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ +#endif + +GLOBAL long +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + +/* + * For MS-DOS we support three types of backing storage: + * 1. Conventional DOS files. We access these by direct DOS calls rather + * than via the stdio package. This provides a bit better performance, + * but the real reason is that the buffers to be read or written are FAR. + * The stdio library for small-data memory models can't cope with that. + * 2. Extended memory, accessed per the XMS V2.0 specification. + * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. + * You'll need copies of those specs to make sense of the related code. + * The specs are available by Internet FTP from the SIMTEL archives + * (oak.oakland.edu and its various mirror sites). See files + * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. + */ + + +/* + * Access methods for a DOS file. + */ + + +METHODDEF void +read_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_read(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF void +write_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_write(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF void +close_file_store (j_common_ptr cinfo, backing_store_ptr info) +{ + jdos_close(info->handle.file_handle); /* close the file */ + remove(info->temp_name); /* delete the file */ +/* If your system doesn't have remove(), try unlink() instead. + * remove() is the ANSI-standard name for this function, but + * unlink() was more common in pre-ANSI systems. + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +LOCAL boolean +open_file_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + short handle; + + select_file_name(info->temp_name); + if (jdos_open((short far *) & handle, (char far *) info->temp_name)) { + /* might as well exit since jpeg_open_backing_store will fail anyway */ + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + return FALSE; + } + info->handle.file_handle = handle; + info->read_backing_store = read_file_store; + info->write_backing_store = write_file_store; + info->close_backing_store = close_file_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); + return TRUE; /* succeeded */ +} + + +/* + * Access methods for extended memory. + */ + +#if XMS_SUPPORTED + +static XMSDRIVER xms_driver; /* saved address of XMS driver */ + +typedef union { /* either long offset or real-mode pointer */ + long offset; + void far * ptr; + } XMSPTR; + +typedef struct { /* XMS move specification structure */ + long length; + XMSH src_handle; + XMSPTR src; + XMSH dst_handle; + XMSPTR dst; + } XMSspec; + +#define ODD(X) (((X) & 1L) != 0) + + +METHODDEF void +read_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = info->handle.xms_handle; + spec.src.offset = file_offset; + spec.dst_handle = 0; + spec.dst.ptr = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_READ); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0]; + } +} + + +METHODDEF void +write_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = 0; + spec.src.ptr = buffer_address; + spec.dst_handle = info->handle.xms_handle; + spec.dst.offset = file_offset; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_WRITE); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L]; + write_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + } +} + + +METHODDEF void +close_xms_store (j_common_ptr cinfo, backing_store_ptr info) +{ + XMScontext ctx; + + ctx.dx = info->handle.xms_handle; + ctx.ax = 0x0a00; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL boolean +open_xms_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + XMScontext ctx; + + /* Get address of XMS driver */ + jxms_getdriver((XMSDRIVER far *) & xms_driver); + if (xms_driver == NULL) + return FALSE; /* no driver to be had */ + + /* Get version number, must be >= 2.00 */ + ctx.ax = 0x0000; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax < (unsigned short) 0x0200) + return FALSE; + + /* Try to get space (expressed in kilobytes) */ + ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10); + ctx.ax = 0x0900; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.xms_handle = ctx.dx; + info->read_backing_store = read_xms_store; + info->write_backing_store = write_xms_store; + info->close_backing_store = close_xms_store; + TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* XMS_SUPPORTED */ + + +/* + * Access methods for expanded memory. + */ + +#if EMS_SUPPORTED + +/* The EMS move specification structure requires word and long fields aligned + * at odd byte boundaries. Some compilers will align struct fields at even + * byte boundaries. While it's usually possible to force byte alignment, + * that causes an overall performance penalty and may pose problems in merging + * JPEG into a larger application. Instead we accept some rather dirty code + * here. Note this code would fail if the hardware did not allow odd-byte + * word & long accesses, but all 80x86 CPUs do. + */ + +typedef void far * EMSPTR; + +typedef union { /* EMS move specification structure */ + long length; /* It's easy to access first 4 bytes */ + char bytes[18]; /* Misaligned fields in here! */ + } EMSspec; + +/* Macros for accessing misaligned fields */ +#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset]))) +#define SRC_TYPE(spec) FIELD_AT(spec,4,char) +#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH) +#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short) +#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short) +#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR) +#define DST_TYPE(spec) FIELD_AT(spec,11,char) +#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH) +#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short) +#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short) +#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR) + +#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */ + +#define HIBYTE(W) (((W) >> 8) & 0xFF) +#define LOBYTE(W) ((W) & 0xFF) + + +METHODDEF void +read_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 1; + SRC_HANDLE(spec) = info->handle.ems_handle; + SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + DST_TYPE(spec) = 0; + DST_HANDLE(spec) = 0; + DST_PTR(spec) = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_READ); +} + + +METHODDEF void +write_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 0; + SRC_HANDLE(spec) = 0; + SRC_PTR(spec) = buffer_address; + DST_TYPE(spec) = 1; + DST_HANDLE(spec) = info->handle.ems_handle; + DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_WRITE); +} + + +METHODDEF void +close_ems_store (j_common_ptr cinfo, backing_store_ptr info) +{ + EMScontext ctx; + + ctx.ax = 0x4500; + ctx.dx = info->handle.ems_handle; + jems_calldriver((EMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL boolean +open_ems_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + EMScontext ctx; + + /* Is EMS driver there? */ + if (! jems_available()) + return FALSE; + + /* Get status, make sure EMS is OK */ + ctx.ax = 0x4000; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Get version, must be >= 4.0 */ + ctx.ax = 0x4600; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40) + return FALSE; + + /* Try to allocate requested space */ + ctx.ax = 0x4300; + ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE); + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.ems_handle = ctx.dx; + info->read_backing_store = read_ems_store; + info->write_backing_store = write_ems_store; + info->close_backing_store = close_ems_store; + TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* EMS_SUPPORTED */ + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL void +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + /* Try extended memory, then expanded memory, then regular file. */ +#if XMS_SUPPORTED + if (open_xms_store(cinfo, info, total_bytes_needed)) + return; +#endif +#if EMS_SUPPORTED + if (open_ems_store(cinfo, info, total_bytes_needed)) + return; +#endif + if (open_file_store(cinfo, info, total_bytes_needed)) + return; + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL long +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL void +jpeg_mem_term (j_common_ptr cinfo) +{ + /* Microsoft C, at least in v6.00A, will not successfully reclaim freed + * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: + */ +#ifdef NEED_FHEAPMIN + _fheapmin(); +#endif +} diff --git a/renderer/jpeg-6/jmemmgr.c b/renderer/jpeg-6/jmemmgr.c new file mode 100644 index 000000000..dc3e1c76a --- /dev/null +++ b/renderer/jpeg-6/jmemmgr.c @@ -0,0 +1,1115 @@ +/* + * jmemmgr.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the JPEG system-independent memory management + * routines. This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + * * pool-based allocation and freeing of memory; + * * policy decisions about how to divide available memory among the + * virtual arrays; + * * control logic for swapping virtual arrays between main memory and + * backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems. For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed. (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H /* should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + + +/* + * Some important notes: + * The allocation routines provided here must never return NULL. + * They should exit to error_exit if unsuccessful. + * + * It's not a good idea to try to merge the sarray and barray routines, + * even though they are textually almost the same, because samples are + * usually stored as bytes while coefficients are shorts or ints. Thus, + * in machines where byte pointers have a different representation from + * word pointers, the resulting machine code could not be the same. + */ + + +/* + * Many machines require storage alignment: longs must start on 4-byte + * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + * always returns pointers that are multiples of the worst-case alignment + * requirement, and we had better do so too. + * There isn't any really portable way to determine the worst-case alignment + * requirement. This module assumes that the alignment requirement is + * multiples of sizeof(ALIGN_TYPE). + * By default, we define ALIGN_TYPE as double. This is necessary on some + * workstations (where doubles really do need 8-byte alignment) and will work + * fine on nearly everything. If your machine has lesser alignment needs, + * you can save a few bytes by making ALIGN_TYPE smaller. + * The only place I know of where this will NOT work is certain Macintosh + * 680x0 compilers that define double as a 10-byte IEEE extended float. + * Doing 10-byte alignment is counterproductive because longwords won't be + * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + * such a compiler. + */ + +#ifndef ALIGN_TYPE /* so can override from jconfig.h */ +#define ALIGN_TYPE double +#endif + + +/* + * We allocate objects from "pools", where each pool is gotten with a single + * request to jpeg_get_small() or jpeg_get_large(). There is no per-object + * overhead within a pool, except for alignment padding. Each pool has a + * header with a link to the next pool of the same class. + * Small and large pool headers are identical except that the latter's + * link pointer must be FAR on 80x86 machines. + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + * of the alignment requirement of ALIGN_TYPE. + */ + +typedef union small_pool_struct * small_pool_ptr; + +typedef union small_pool_struct { + struct { + small_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} small_pool_hdr; + +typedef union large_pool_struct FAR * large_pool_ptr; + +typedef union large_pool_struct { + struct { + large_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} large_pool_hdr; + + +/* + * Here is the full definition of a memory manager object. + */ + +typedef struct { + struct jpeg_memory_mgr pub; /* public fields */ + + /* Each pool identifier (lifetime class) names a linked list of pools. */ + small_pool_ptr small_list[JPOOL_NUMPOOLS]; + large_pool_ptr large_list[JPOOL_NUMPOOLS]; + + /* Since we only have one lifetime class of virtual arrays, only one + * linked list is necessary (for each datatype). Note that the virtual + * array control blocks being linked together are actually stored somewhere + * in the small-pool list. + */ + jvirt_sarray_ptr virt_sarray_list; + jvirt_barray_ptr virt_barray_list; + + /* This counts total space obtained from jpeg_get_small/large */ + long total_space_allocated; + + /* alloc_sarray and alloc_barray set this value for use by virtual + * array routines. + */ + JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ +} my_memory_mgr; + +typedef my_memory_mgr * my_mem_ptr; + + +/* + * The control blocks for virtual arrays. + * Note that these blocks are allocated in the "small" pool area. + * System-dependent info for the associated backing store (if any) is hidden + * inside the backing_store_info struct. + */ + +struct jvirt_sarray_control { + JSAMPARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_sarray_ptr next; /* link to next virtual sarray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + +struct jvirt_barray_control { + JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_barray_ptr next; /* link to next virtual barray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + + +#ifdef MEM_STATS /* optional extra stuff for statistics */ + +LOCAL void +print_mem_stats (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + + /* Since this is only a debugging stub, we can cheat a little by using + * fprintf directly rather than going through the trace message code. + * This is helpful because message parm array can't handle longs. + */ + fprintf(stderr, "Freeing pool %d, total space = %ld\n", + pool_id, mem->total_space_allocated); + + for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; + lhdr_ptr = lhdr_ptr->hdr.next) { + fprintf(stderr, " Large chunk used %ld\n", + (long) lhdr_ptr->hdr.bytes_used); + } + + for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; + shdr_ptr = shdr_ptr->hdr.next) { + fprintf(stderr, " Small chunk used %ld free %ld\n", + (long) shdr_ptr->hdr.bytes_used, + (long) shdr_ptr->hdr.bytes_left); + } +} + +#endif /* MEM_STATS */ + + +LOCAL void +out_of_memory (j_common_ptr cinfo, int which) +/* Report an out-of-memory error and stop execution */ +/* If we compiled MEM_STATS support, report alloc requests before dying */ +{ +#ifdef MEM_STATS + cinfo->err->trace_level = 2; /* force self_destruct to report stats */ +#endif + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +} + + +/* + * Allocation of "small" objects. + * + * For these, we use pooled storage. When a new pool must be created, + * we try to get enough space for the current request plus a "slop" factor, + * where the slop will be the amount of leftover space in the new pool. + * The speed vs. space tradeoff is largely determined by the slop values. + * A different slop value is provided for each pool class (lifetime), + * and we also distinguish the first pool of a class from later ones. + * NOTE: the values given work fairly well on both 16- and 32-bit-int + * machines, but may be too small if longs are 64 bits or more. + */ + +static const size_t first_pool_slop[JPOOL_NUMPOOLS] = +{ + 1600, /* first PERMANENT pool */ + 16000 /* first IMAGE pool */ +}; + +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = +{ + 0, /* additional PERMANENT pools */ + 5000 /* additional IMAGE pools */ +}; + +#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ + + +METHODDEF void * +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "small" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr hdr_ptr, prev_hdr_ptr; + char * data_ptr; + size_t odd_bytes, min_request, slop; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) + out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* See if space is available in any existing pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + prev_hdr_ptr = NULL; + hdr_ptr = mem->small_list[pool_id]; + while (hdr_ptr != NULL) { + if (hdr_ptr->hdr.bytes_left >= sizeofobject) + break; /* found pool with enough space */ + prev_hdr_ptr = hdr_ptr; + hdr_ptr = hdr_ptr->hdr.next; + } + + /* Time to make a new pool? */ + if (hdr_ptr == NULL) { + /* min_request is what we need now, slop is what will be leftover */ + min_request = sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr == NULL) /* first pool in class? */ + slop = first_pool_slop[pool_id]; + else + slop = extra_pool_slop[pool_id]; + /* Don't ask for more than MAX_ALLOC_CHUNK */ + if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) + slop = (size_t) (MAX_ALLOC_CHUNK-min_request); + /* Try to get space, if fail reduce slop and try again */ + for (;;) { + hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); + if (hdr_ptr != NULL) + break; + slop /= 2; + if (slop < MIN_SLOP) /* give up when it gets real small */ + out_of_memory(cinfo, 2); /* jpeg_get_small failed */ + } + mem->total_space_allocated += min_request + slop; + /* Success, initialize the new pool header and add to end of list */ + hdr_ptr->hdr.next = NULL; + hdr_ptr->hdr.bytes_used = 0; + hdr_ptr->hdr.bytes_left = sizeofobject + slop; + if (prev_hdr_ptr == NULL) /* first pool in class? */ + mem->small_list[pool_id] = hdr_ptr; + else + prev_hdr_ptr->hdr.next = hdr_ptr; + } + + /* OK, allocate the object from the current pool */ + data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ + data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ + hdr_ptr->hdr.bytes_used += sizeofobject; + hdr_ptr->hdr.bytes_left -= sizeofobject; + + return (void *) data_ptr; +} + + +/* + * Allocation of "large" objects. + * + * The external semantics of these are the same as "small" objects, + * except that FAR pointers are used on 80x86. However the pool + * management heuristics are quite different. We assume that each + * request is large enough that it may as well be passed directly to + * jpeg_get_large; the pool management just links everything together + * so that we can free it all on demand. + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + * structures. The routines that create these structures (see below) + * deliberately bunch rows together to ensure a large request size. + */ + +METHODDEF void FAR * +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "large" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + large_pool_ptr hdr_ptr; + size_t odd_bytes; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) + out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* Always make a new pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr)); + if (hdr_ptr == NULL) + out_of_memory(cinfo, 4); /* jpeg_get_large failed */ + mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); + + /* Success, initialize the new pool header and add to list */ + hdr_ptr->hdr.next = mem->large_list[pool_id]; + /* We maintain space counts in each pool header for statistical purposes, + * even though they are not needed for allocation. + */ + hdr_ptr->hdr.bytes_used = sizeofobject; + hdr_ptr->hdr.bytes_left = 0; + mem->large_list[pool_id] = hdr_ptr; + + return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ +} + + +/* + * Creation of 2-D sample arrays. + * The pointers are in near heap, the samples themselves in FAR heap. + * + * To minimize allocation overhead and to allow I/O of large contiguous + * blocks, we allocate the sample rows in groups of as many rows as possible + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + * NB: the virtual array control routines, later in this file, know about + * this chunking of rows. The rowsperchunk value is left in the mem manager + * object so that it can be saved away if this sarray is the workspace for + * a virtual array. + */ + +METHODDEF JSAMPARRAY +alloc_sarray (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +/* Allocate a 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JSAMPARRAY result; + JSAMPROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) samplesperrow * SIZEOF(JSAMPLE)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JSAMPARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JSAMPROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JSAMPROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow + * SIZEOF(JSAMPLE))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += samplesperrow; + } + } + + return result; +} + + +/* + * Creation of 2-D coefficient-block arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF JBLOCKARRAY +alloc_barray (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, JDIMENSION numrows) +/* Allocate a 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JBLOCKARRAY result; + JBLOCKROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) blocksperrow * SIZEOF(JBLOCK)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JBLOCKROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow + * SIZEOF(JBLOCK))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += blocksperrow; + } + } + + return result; +} + + +/* + * About virtual array management: + * + * The above "normal" array routines are only used to allocate strip buffers + * (as wide as the image, but just a few rows high). Full-image-sized buffers + * are handled as "virtual" arrays. The array is still accessed a strip at a + * time, but the memory manager must save the whole array for repeated + * accesses. The intended implementation is that there is a strip buffer in + * memory (as high as is possible given the desired memory limit), plus a + * backing file that holds the rest of the array. + * + * The request_virt_array routines are told the total size of the image and + * the maximum number of rows that will be accessed at once. The in-memory + * buffer must be at least as large as the maxaccess value. + * + * The request routines create control blocks but not the in-memory buffers. + * That is postponed until realize_virt_arrays is called. At that time the + * total amount of space needed is known (approximately, anyway), so free + * memory can be divided up fairly. + * + * The access_virt_array routines are responsible for making a specific strip + * area accessible (after reading or writing the backing file, if necessary). + * Note that the access routines are told whether the caller intends to modify + * the accessed strip; during a read-only pass this saves having to rewrite + * data to disk. The access routines are also responsible for pre-zeroing + * any newly accessed rows, if pre-zeroing was requested. + * + * In current usage, the access requests are usually for nonoverlapping + * strips; that is, successive access start_row numbers differ by exactly + * num_rows = maxaccess. This means we can get good performance with simple + * buffer dump/reload logic, by making the in-memory buffer be a multiple + * of the access height; then there will never be accesses across bufferload + * boundaries. The code will still work with overlapping access requests, + * but it doesn't handle bufferload overlaps very efficiently. + */ + + +METHODDEF jvirt_sarray_ptr +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION samplesperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_sarray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_sarray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->samplesperrow = samplesperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ + mem->virt_sarray_list = result; + + return result; +} + + +METHODDEF jvirt_barray_ptr +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION blocksperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_barray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_barray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->blocksperrow = blocksperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_barray_list; /* add to list of virtual arrays */ + mem->virt_barray_list = result; + + return result; +} + + +METHODDEF void +realize_virt_arrays (j_common_ptr cinfo) +/* Allocate the in-memory buffers for any unrealized virtual arrays */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + long space_per_minheight, maximum_space, avail_mem; + long minheights, max_minheights; + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + /* Compute the minimum space needed (maxaccess rows in each buffer) + * and the maximum space needed (full image height in each buffer). + * These may be of use to the system-dependent jpeg_mem_available routine. + */ + space_per_minheight = 0; + maximum_space = 0; + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) sptr->maxaccess * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + maximum_space += (long) sptr->rows_in_array * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + } + } + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) bptr->maxaccess * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + maximum_space += (long) bptr->rows_in_array * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + } + } + + if (space_per_minheight <= 0) + return; /* no unrealized arrays, no work */ + + /* Determine amount of memory to actually use; this is system-dependent. */ + avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem->total_space_allocated); + + /* If the maximum space needed is available, make all the buffers full + * height; otherwise parcel it out with the same number of minheights + * in each buffer. + */ + if (avail_mem >= maximum_space) + max_minheights = 1000000000L; + else { + max_minheights = avail_mem / space_per_minheight; + /* If there doesn't seem to be enough space, try to get the minimum + * anyway. This allows a "stub" implementation of jpeg_mem_available(). + */ + if (max_minheights <= 0) + max_minheights = 1; + } + + /* Allocate the in-memory buffers and initialize backing store as needed. */ + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + sptr->rows_in_mem = sptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); + jpeg_open_backing_store(cinfo, & sptr->b_s_info, + (long) sptr->rows_in_array * + (long) sptr->samplesperrow * + (long) SIZEOF(JSAMPLE)); + sptr->b_s_open = TRUE; + } + sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, + sptr->samplesperrow, sptr->rows_in_mem); + sptr->rowsperchunk = mem->last_rowsperchunk; + sptr->cur_start_row = 0; + sptr->first_undef_row = 0; + sptr->dirty = FALSE; + } + } + + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + bptr->rows_in_mem = bptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); + jpeg_open_backing_store(cinfo, & bptr->b_s_info, + (long) bptr->rows_in_array * + (long) bptr->blocksperrow * + (long) SIZEOF(JBLOCK)); + bptr->b_s_open = TRUE; + } + bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, + bptr->blocksperrow, bptr->rows_in_mem); + bptr->rowsperchunk = mem->last_rowsperchunk; + bptr->cur_start_row = 0; + bptr->first_undef_row = 0; + bptr->dirty = FALSE; + } + } +} + + +LOCAL void +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual sample array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +LOCAL void +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual coefficient-block array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +METHODDEF JSAMPARRAY +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual sample array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_sarray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_sarray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +METHODDEF JBLOCKARRAY +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual block array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_barray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_barray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +/* + * Release all objects belonging to a specified pool. + */ + +METHODDEF void +free_pool (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + size_t space_freed; + + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + +#ifdef MEM_STATS + if (cinfo->err->trace_level > 1) + print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ +#endif + + /* If freeing IMAGE pool, close any virtual arrays first */ + if (pool_id == JPOOL_IMAGE) { + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->b_s_open) { /* there may be no backing store */ + sptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); + } + } + mem->virt_sarray_list = NULL; + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->b_s_open) { /* there may be no backing store */ + bptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); + } + } + mem->virt_barray_list = NULL; + } + + /* Release large objects */ + lhdr_ptr = mem->large_list[pool_id]; + mem->large_list[pool_id] = NULL; + + while (lhdr_ptr != NULL) { + large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; + space_freed = lhdr_ptr->hdr.bytes_used + + lhdr_ptr->hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + lhdr_ptr = next_lhdr_ptr; + } + + /* Release small objects */ + shdr_ptr = mem->small_list[pool_id]; + mem->small_list[pool_id] = NULL; + + while (shdr_ptr != NULL) { + small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; + space_freed = shdr_ptr->hdr.bytes_used + + shdr_ptr->hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + shdr_ptr = next_shdr_ptr; + } +} + + +/* + * Close up shop entirely. + * Note that this cannot be called unless cinfo->mem is non-NULL. + */ + +METHODDEF void +self_destruct (j_common_ptr cinfo) +{ + int pool; + + /* Close all backing store, release all memory. + * Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + free_pool(cinfo, pool); + } + + /* Release the memory manager control block too. */ + jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); + cinfo->mem = NULL; /* ensures I will be called only once */ + + jpeg_mem_term(cinfo); /* system-dependent cleanup */ +} + + +/* + * Memory manager initialization. + * When this is called, only the error manager pointer is valid in cinfo! + */ + +GLOBAL void +jinit_memory_mgr (j_common_ptr cinfo) +{ + my_mem_ptr mem; + long max_to_use; + int pool; + size_t test_mac; + + cinfo->mem = NULL; /* for safety if init fails */ + + /* Check for configuration errors. + * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + * doesn't reflect any real hardware alignment requirement. + * The test is a little tricky: for X>0, X and X-1 have no one-bits + * in common if and only if X is a power of 2, ie has only one one-bit. + * Some compilers may give an "unreachable code" warning here; ignore it. + */ + if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be + * a multiple of SIZEOF(ALIGN_TYPE). + * Again, an "unreachable code" warning may be ignored here. + * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. + */ + test_mac = (size_t) MAX_ALLOC_CHUNK; + if ((long) test_mac != MAX_ALLOC_CHUNK || + (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ + + /* Attempt to allocate memory manager's control block */ + mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); + + if (mem == NULL) { + jpeg_mem_term(cinfo); /* system-dependent cleanup */ + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + } + + /* OK, fill in the method pointers */ + mem->pub.alloc_small = alloc_small; + mem->pub.alloc_large = alloc_large; + mem->pub.alloc_sarray = alloc_sarray; + mem->pub.alloc_barray = alloc_barray; + mem->pub.request_virt_sarray = request_virt_sarray; + mem->pub.request_virt_barray = request_virt_barray; + mem->pub.realize_virt_arrays = realize_virt_arrays; + mem->pub.access_virt_sarray = access_virt_sarray; + mem->pub.access_virt_barray = access_virt_barray; + mem->pub.free_pool = free_pool; + mem->pub.self_destruct = self_destruct; + + /* Initialize working state */ + mem->pub.max_memory_to_use = max_to_use; + + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + mem->small_list[pool] = NULL; + mem->large_list[pool] = NULL; + } + mem->virt_sarray_list = NULL; + mem->virt_barray_list = NULL; + + mem->total_space_allocated = SIZEOF(my_memory_mgr); + + /* Declare ourselves open for business */ + cinfo->mem = & mem->pub; + + /* Check for an environment variable JPEGMEM; if found, override the + * default max_memory setting from jpeg_mem_init. Note that the + * surrounding application may again override this value. + * If your system doesn't support getenv(), define NO_GETENV to disable + * this feature. + */ +#ifndef NO_GETENV + { char * memenv; + + if ((memenv = getenv("JPEGMEM")) != NULL) { + char ch = 'x'; + + if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { + if (ch == 'm' || ch == 'M') + max_to_use *= 1000L; + mem->pub.max_memory_to_use = max_to_use * 1000L; + } + } + } +#endif + +} diff --git a/renderer/jpeg-6/jmemname.c b/renderer/jpeg-6/jmemname.c new file mode 100644 index 000000000..ba826fbb5 --- /dev/null +++ b/renderer/jpeg-6/jmemname.c @@ -0,0 +1,271 @@ +/* + * jmemname.c + * + * Copyright (C) 1992-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a generic implementation of the system-dependent + * portion of the JPEG memory manager. This implementation assumes that + * you must explicitly construct a name for each temp file. + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define RW_BINARY "w+" +#else +#define READ_BINARY "rb" +#define RW_BINARY "w+b" +#endif + + +/* + * Selection of a file name for a temporary file. + * This is system-dependent! + * + * The code as given is suitable for most Unix systems, and it is easily + * modified for most non-Unix systems. Some notes: + * 1. The temp file is created in the directory named by TEMP_DIRECTORY. + * The default value is /usr/tmp, which is the conventional place for + * creating large temp files on Unix. On other systems you'll probably + * want to change the file location. You can do this by editing the + * #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h. + * + * 2. If you need to change the file name as well as its location, + * you can override the TEMP_FILE_NAME macro. (Note that this is + * actually a printf format string; it must contain %s and %d.) + * Few people should need to do this. + * + * 3. mktemp() is used to ensure that multiple processes running + * simultaneously won't select the same file names. If your system + * doesn't have mktemp(), define NO_MKTEMP to do it the hard way. + * (If you don't have , also define NO_ERRNO_H.) + * + * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c + * will cause the temp files to be removed if you stop the program early. + */ + +#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ +#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ +#endif + +static int next_file_num; /* to distinguish among several temp files */ + +#ifdef NO_MKTEMP + +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%03d.TMP" +#endif + +#ifndef NO_ERRNO_H +#include /* to define ENOENT */ +#endif + +/* ANSI C specifies that errno is a macro, but on older systems it's more + * likely to be a plain int variable. And not all versions of errno.h + * bother to declare it, so we have to in order to be most portable. Thus: + */ +#ifndef errno +extern int errno; +#endif + + +LOCAL void +select_file_name (char * fname) +{ + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + if ((tfile = fopen(fname, READ_BINARY)) == NULL) { + /* fopen could have failed for a reason other than the file not + * being there; for example, file there but unreadable. + * If isn't available, then we cannot test the cause. + */ +#ifdef ENOENT + if (errno != ENOENT) + continue; +#endif + break; + } + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + +#else /* ! NO_MKTEMP */ + +/* Note that mktemp() requires the initial filename to end in six X's */ +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%dXXXXXX" +#endif + +LOCAL void +select_file_name (char * fname) +{ + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + mktemp(fname); /* make sure file name is unique */ + /* mktemp replaces the trailing XXXXXX with a unique string of characters */ +} + +#endif /* NO_MKTEMP */ + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL void * +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL void FAR * +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL long +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF void +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF void +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF void +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); /* close the file */ + unlink(info->temp_name); /* delete the file */ +/* If your system doesn't have unlink(), use remove() instead. + * remove() is the ANSI-standard name for this function, but if + * your system was ANSI you'd be using jmemansi.c, right? + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL void +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + select_file_name(info->temp_name); + if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL long +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL void +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/renderer/jpeg-6/jmemnobs.c b/renderer/jpeg-6/jmemnobs.c new file mode 100644 index 000000000..9bafed57b --- /dev/null +++ b/renderer/jpeg-6/jmemnobs.c @@ -0,0 +1,103 @@ +/* + * jmemnobs.c + * + * Copyright (C) 1992-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space + * can be obtained from ri.Malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +/* + * Memory allocation and ri.Freeing are controlled by the regular library + * routines ri.Malloc() and ri.Free(). + */ + +GLOBAL void * +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL void FAR * +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL long +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL void +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL long +jpeg_mem_init (j_common_ptr cinfo) +{ + return 0; /* just set max_memory_to_use to 0 */ +} + +GLOBAL void +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/renderer/jpeg-6/jmemsys.h b/renderer/jpeg-6/jmemsys.h new file mode 100644 index 000000000..033d29a79 --- /dev/null +++ b/renderer/jpeg-6/jmemsys.h @@ -0,0 +1,182 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory. (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free. jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * On an 80x86 machine using small-data memory model, these manage near heap. + */ + +EXTERN void * jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used. On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * in case a different allocation strategy is desirable for large chunks. + */ + +EXTERN void FAR * jpeg_get_large JPP((j_common_ptr cinfo,size_t sizeofobject)); +EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play). This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK 1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large. If more space than this is needed, backing store will be + * used. NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero. The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed. If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure. Hence it's wise to subtract + * a slop factor from the true available space. 5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * Conversely, zero may be returned to always use the minimum amount of memory. + */ + +EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object. The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ + +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ + +typedef union { + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { + /* Methods for reading/writing/closing this backing-store object */ + JMETHOD(void, read_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr info)); + + /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR + /* For the MS-DOS manager (jmemdos.c), we need: */ + handle_union handle; /* reference to backing-store storage object */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else + /* For a typical implementation with temp files, we need: */ + FILE * temp_file; /* stdio reference to temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ +#endif +} backing_store_info; + +/* + * Initial opening of a backing-store object. This must fill in the + * read/write/close pointers in the object. The read/write routines + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer). It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application. (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * all opened backing-store objects have been closed. + */ + +EXTERN long jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN void jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/renderer/jpeg-6/jmorecfg.h b/renderer/jpeg-6/jmorecfg.h new file mode 100644 index 000000000..958381f2a --- /dev/null +++ b/renderer/jpeg-6/jmorecfg.h @@ -0,0 +1,352 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +#ifndef __MWERKS__ +#ifndef _BASETSD_H_ +typedef long INT32; +#endif +#endif + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +//#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +//typedef long INT32; +//#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These defines are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +#define METHODDEF static /* a function called through method pointers */ +#define LOCAL static /* a function used only in its module */ +#define GLOBAL /* a function referenced thru EXTERNs */ +#define EXTERN extern /* a reference to a GLOBAL function */ + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#undef FAR +#define FAR far +#else +#undef FAR +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +//#ifndef HAVE_BOOLEAN +//typedef int boolean; +//#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#undef DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#undef DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#undef D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#undef D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#undef BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#undef IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#undef UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#undef QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#undef QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 4 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/renderer/jpeg-6/jpegint.h b/renderer/jpeg-6/jpegint.h new file mode 100644 index 000000000..ab5bee2ce --- /dev/null +++ b/renderer/jpeg-6/jpegint.h @@ -0,0 +1,388 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* Marker writing */ +struct jpeg_marker_writer { + /* write_any_marker is exported for use by applications */ + /* Probably only COM and APPn markers should be written */ + JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen)); + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, + JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + /* Application-overridable marker processing methods */ + jpeg_marker_parser_method process_COM; + jpeg_marker_parser_method process_APPn[16]; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); + JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity. This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit. But some + * C compilers implement >> with an unsigned shift. For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts. SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x,shft) \ + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_huff_encoder jIHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_marker_writer jIMWriter +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_huff_decoder jIHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Compression module initialization routines */ +EXTERN void jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN void jinit_c_master_control JPP((j_compress_ptr cinfo, + boolean transcode_only)); +EXTERN void jinit_c_main_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_c_prep_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN void jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN void jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN void jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN void jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN void jinit_marker_writer JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN void jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_d_main_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_d_post_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN void jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN void jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +/* Memory manager initialization */ +EXTERN void jinit_memory_mgr JPP((j_common_ptr cinfo)); + +/* Utility routines in jutils.c */ +EXTERN long jdiv_round_up JPP((long a, long b)); +EXTERN long jround_up JPP((long a, long b)); +EXTERN void jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN void jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN void jzero_far JPP((void FAR * target, size_t bytestozero)); +/* Constant tables in jutils.c */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/renderer/jpeg-6/jpeglib.h b/renderer/jpeg-6/jpeglib.h new file mode 100644 index 000000000..edfdda10b --- /dev/null +++ b/renderer/jpeg-6/jpeglib.h @@ -0,0 +1,1051 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +typedef unsigned char boolean; +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "../jpeg-6/jconfig.h" /* widely used configuration options */ +#endif +#include "../jpeg-6/jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 60 /* Version 6 */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This field directly represents the contents of a JPEG DQT marker. + * Note: the values are always given in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is not currently used by the compressor. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + boolean is_decompressor; /* so common code can tell which is which */\ + int global_state /* for checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker: */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_create_compress jCreaCompress +#define jpeg_create_decompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN struct jpeg_error_mgr *jpeg_std_error JPP((struct jpeg_error_mgr *err)); + +/* Initialization and destruction of JPEG compression objects */ +/* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx */ +EXTERN void jpeg_create_compress JPP((j_compress_ptr cinfo)); +EXTERN void jpeg_create_decompress JPP((j_decompress_ptr cinfo)); +EXTERN void jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, unsigned char *infile)); + +/* Default parameter setup for compression */ +EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN void jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN int jpeg_quality_scaling JPP((int quality)); +EXTERN void jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN void jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN JQUANT_TBL * jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN JHUFF_TBL * jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN void jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN JDIMENSION jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN void jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN JDIMENSION jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN void jpeg_write_marker JPP((j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN void jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN boolean jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN JDIMENSION jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN boolean jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN JDIMENSION jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN boolean jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN boolean jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN boolean jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN boolean jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN void jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN void jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN void jpeg_set_marker_processor JPP((j_decompress_ptr cinfo, + int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN jvirt_barray_ptr * jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN void jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN void jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN void jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN void jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN void jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "../jpeg-6/jpegint.h" /* fetch private declarations */ +#include "../jpeg-6/jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/renderer/jpeg-6/jpegtran.c b/renderer/jpeg-6/jpegtran.c new file mode 100644 index 000000000..f602c6b9f --- /dev/null +++ b/renderer/jpeg-6/jpegtran.c @@ -0,0 +1,370 @@ +/* + * jpegtran.c + * + * Copyright (C) 1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for JPEG transcoding. + * It is very similar to cjpeg.c, but provides lossless transcoding between + * different JPEG file formats. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "jversion.h" /* for version message */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks declares it here */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ + + +LOCAL void +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); +#ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); +#endif +#ifdef C_PROGRESSIVE_SUPPORTED + fprintf(stderr, " -progressive Create progressive JPEG file\n"); +#endif + fprintf(stderr, "Switches for advanced users:\n"); + fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + fprintf(stderr, "Switches for wizards:\n"); +#ifdef C_ARITH_CODING_SUPPORTED + fprintf(stderr, " -arithmetic Use arithmetic coding\n"); +#endif +#ifdef C_MULTISCAN_FILES_SUPPORTED + fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); +#endif + exit(EXIT_FAILURE); +} + + +LOCAL int +parse_switches (j_compress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + boolean simple_progressive; + char * scansarg = NULL; /* saves -scans parm if any */ + + /* Set up default JPEG parameters. */ + simple_progressive = FALSE; + outfilename = NULL; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "arithmetic", 1)) { + /* Use arithmetic coding. */ +#ifdef C_ARITH_CODING_SUPPORTED + cinfo->arith_code = TRUE; +#else + fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { + /* Enable entropy parm optimization. */ +#ifdef ENTROPY_OPT_SUPPORTED + cinfo->optimize_coding = TRUE; +#else + fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "progressive", 1)) { + /* Select simple progressive mode. */ +#ifdef C_PROGRESSIVE_SUPPORTED + simple_progressive = TRUE; + /* We must postpone execution until num_components is known. */ +#else + fprintf(stderr, "%s: sorry, progressive output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "restart", 1)) { + /* Restart interval in MCU rows (or in MCUs with 'b'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (lval < 0 || lval > 65535L) + usage(); + if (ch == 'b' || ch == 'B') { + cinfo->restart_interval = (unsigned int) lval; + cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ + } else { + cinfo->restart_in_rows = (int) lval; + /* restart_interval will be computed during startup */ + } + + } else if (keymatch(arg, "scans", 2)) { + /* Set scan script. */ +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + scansarg = argv[argn]; + /* We must postpone reading the file in case -progressive appears. */ +#else + fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else { + usage(); /* bogus switch */ + } + } + + /* Post-switch-scanning cleanup */ + + if (for_real) { + +#ifdef C_PROGRESSIVE_SUPPORTED + if (simple_progressive) /* process -progressive; -scans can override */ + jpeg_simple_progression(cinfo); +#endif + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (scansarg != NULL) /* process -scans if it was present */ + if (! read_scan_script(cinfo, scansarg)) + usage(); +#endif + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * The main program. + */ + +GLOBAL int +main (int argc, char **argv) +{ + struct jpeg_decompress_struct srcinfo; + struct jpeg_compress_struct dstinfo; + struct jpeg_error_mgr jsrcerr, jdsterr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + jvirt_barray_ptr * coef_arrays; + int file_index; + FILE * input_file; + FILE * output_file; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "jpegtran"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG decompression object with default error handling. */ + srcinfo.err = jpeg_std_error(&jsrcerr); + jpeg_create_decompress(&srcinfo); + /* Initialize the JPEG compression object with default error handling. */ + dstinfo.err = jpeg_std_error(&jdsterr); + jpeg_create_compress(&dstinfo); + + /* Now safe to enable signal catcher. + * Note: we assume only the decompression object will have virtual arrays. + */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &srcinfo); +#endif + + /* Scan command line to find file names. + * It is convenient to use just one switch-parsing routine, but the switch + * values read here are ignored; we will rescan the switches after opening + * the input file. + */ + + file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); + jsrcerr.trace_level = jdsterr.trace_level; + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &dstinfo, &progress); +#endif + + /* Specify data source for decompression */ + jpeg_stdio_src(&srcinfo, input_file); + + /* Read file header */ + (void) jpeg_read_header(&srcinfo, TRUE); + + /* Read source file as DCT coefficients */ + coef_arrays = jpeg_read_coefficients(&srcinfo); + + /* Initialize destination compression parameters from source values */ + jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ + jpeg_stdio_dest(&dstinfo, output_file); + + /* Start compressor */ + jpeg_write_coefficients(&dstinfo, coef_arrays); + + /* ought to copy source comments here... */ + + /* Finish compression and release memory */ + jpeg_finish_compress(&dstinfo); + jpeg_destroy_compress(&dstinfo); + (void) jpeg_finish_decompress(&srcinfo); + jpeg_destroy_decompress(&srcinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &dstinfo); +#endif + + /* All done. */ + exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/renderer/jpeg-6/jquant1.c b/renderer/jpeg-6/jquant1.c new file mode 100644 index 000000000..035e79a82 --- /dev/null +++ b/renderer/jpeg-6/jquant1.c @@ -0,0 +1,856 @@ +/* + * jquant1.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 1-pass color quantization (color mapping) routines. + * These routines provide mapping to a fixed color map using equally spaced + * color values. Optional Floyd-Steinberg or ordered dithering is available. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_1PASS_SUPPORTED + + +/* + * The main purpose of 1-pass quantization is to provide a fast, if not very + * high quality, colormapped output capability. A 2-pass quantizer usually + * gives better visual quality; however, for quantized grayscale output this + * quantizer is perfectly adequate. Dithering is highly recommended with this + * quantizer, though you can turn it off if you really want to. + * + * In 1-pass quantization the colormap must be chosen in advance of seeing the + * image. We use a map consisting of all combinations of Ncolors[i] color + * values for the i'th component. The Ncolors[] values are chosen so that + * their product, the total number of colors, is no more than that requested. + * (In most cases, the product will be somewhat less.) + * + * Since the colormap is orthogonal, the representative value for each color + * component can be determined without considering the other components; + * then these indexes can be combined into a colormap index by a standard + * N-dimensional-array-subscript calculation. Most of the arithmetic involved + * can be precalculated and stored in the lookup table colorindex[]. + * colorindex[i][j] maps pixel value j in component i to the nearest + * representative value (grid plane) for that component; this index is + * multiplied by the array stride for component i, so that the + * index of the colormap entry closest to a given pixel value is just + * sum( colorindex[component-number][pixel-component-value] ) + * Aside from being fast, this scheme allows for variable spacing between + * representative values with no additional lookup cost. + * + * If gamma correction has been applied in color conversion, it might be wise + * to adjust the color grid spacing so that the representative colors are + * equidistant in linear space. At this writing, gamma correction is not + * implemented by jdcolor, so nothing is done here. + */ + + +/* Declarations for ordered dithering. + * + * We use a standard 16x16 ordered dither array. The basic concept of ordered + * dithering is described in many references, for instance Dale Schumacher's + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + * In place of Schumacher's comparisons against a "threshold" value, we add a + * "dither" value to the input pixel and then round the result to the nearest + * output value. The dither value is equivalent to (0.5 - threshold) times + * the distance between output values. For ordered dithering, we assume that + * the output colors are equally spaced; if not, results will probably be + * worse, since the dither may be too much or too little at a given point. + * + * The normal calculation would be to form pixel value + dither, range-limit + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + * We can skip the separate range-limiting step by extending the colorindex + * table in both directions. + */ + +#define ODITHER_SIZE 16 /* dimension of dither matrix */ +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ +#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ + +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; + +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { + /* Bayer's order-4 dither array. Generated by the code given in + * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + * The values in this array must range from 0 to ODITHER_CELLS-1. + */ + { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, + { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, + { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, + { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, + { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, + { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, + { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, + { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, + { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, + { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, + { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, + { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, + { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, + { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, + { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, + { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } +}; + + +/* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array is indexed [component#][position]. + * We provide (#columns + 2) entries per component; the extra entry at each + * end saves us from special-casing the first and last pixels. + * + * Note: on a wide image, we might not have enough room in a PC's near data + * segment to hold the error array; so it is allocated with alloc_large. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef INT16 FSERROR; /* 16 bits should be enough */ +typedef int LOCFSERROR; /* use 'int' for calculation temps */ +#else +typedef INT32 FSERROR; /* may need more than 16 bits */ +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ +#endif + +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ + + +/* Private subobject */ + +#define MAX_Q_COMPS 4 /* max components I can handle */ + +typedef struct { + struct jpeg_color_quantizer pub; /* public fields */ + + /* Initially allocated colormap is saved here */ + JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ + int sv_actual; /* number of entries in use */ + + JSAMPARRAY colorindex; /* Precomputed mapping for speed */ + /* colorindex[i][j] = index of color closest to pixel value j in component i, + * premultiplied as described above. Since colormap indexes must fit into + * JSAMPLEs, the entries of this array will too. + */ + boolean is_padded; /* is the colorindex padded for odither? */ + + int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ + + /* Variables for ordered dithering */ + int row_index; /* cur row's vertical index in dither matrix */ + ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ + + /* Variables for Floyd-Steinberg dithering */ + FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ + boolean on_odd_row; /* flag to remember which row we are on */ +} my_cquantizer; + +typedef my_cquantizer * my_cquantize_ptr; + + +/* + * Policy-making subroutines for create_colormap and create_colorindex. + * These routines determine the colormap to be used. The rest of the module + * only assumes that the colormap is orthogonal. + * + * * select_ncolors decides how to divvy up the available colors + * among the components. + * * output_value defines the set of representative values for a component. + * * largest_input_value defines the mapping from input values to + * representative values for a component. + * Note that the latter two routines may impose different policies for + * different components, though this is not currently done. + */ + + +LOCAL int +select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) +/* Determine allocation of desired colors to components, */ +/* and fill in Ncolors[] array to indicate choice. */ +/* Return value is total number of colors (product of Ncolors[] values). */ +{ + int nc = cinfo->out_color_components; /* number of color components */ + int max_colors = cinfo->desired_number_of_colors; + int total_colors, iroot, i, j; + boolean changed; + long temp; + static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; + + /* We can allocate at least the nc'th root of max_colors per component. */ + /* Compute floor(nc'th root of max_colors). */ + iroot = 1; + do { + iroot++; + temp = iroot; /* set temp = iroot ** nc */ + for (i = 1; i < nc; i++) + temp *= iroot; + } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ + iroot--; /* now iroot = floor(root) */ + + /* Must have at least 2 color values per component */ + if (iroot < 2) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); + + /* Initialize to iroot color values for each component */ + total_colors = 1; + for (i = 0; i < nc; i++) { + Ncolors[i] = iroot; + total_colors *= iroot; + } + /* We may be able to increment the count for one or more components without + * exceeding max_colors, though we know not all can be incremented. + * Sometimes, the first component can be incremented more than once! + * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + * In RGB colorspace, try to increment G first, then R, then B. + */ + do { + changed = FALSE; + for (i = 0; i < nc; i++) { + j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); + /* calculate new total_colors if Ncolors[j] is incremented */ + temp = total_colors / Ncolors[j]; + temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ + if (temp > (long) max_colors) + break; /* won't fit, done with this pass */ + Ncolors[j]++; /* OK, apply the increment */ + total_colors = (int) temp; + changed = TRUE; + } + } while (changed); + + return total_colors; +} + + +LOCAL int +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return j'th output value, where j will range from 0 to maxj */ +/* The output values must fall in 0..MAXJSAMPLE in increasing order */ +{ + /* We always provide values 0 and MAXJSAMPLE for each component; + * any additional values are equally spaced between these limits. + * (Forcing the upper and lower values to the limits ensures that + * dithering can't produce a color outside the selected gamut.) + */ + return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); +} + + +LOCAL int +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return largest input value that should map to j'th output value */ +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ +{ + /* Breakpoints are halfway between values returned by output_value */ + return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); +} + + +/* + * Create the colormap. + */ + +LOCAL void +create_colormap (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colormap; /* Created colormap */ + int total_colors; /* Number of distinct output colors */ + int i,j,k, nci, blksize, blkdist, ptr, val; + + /* Select number of colors for each component */ + total_colors = select_ncolors(cinfo, cquantize->Ncolors); + + /* Report selected color counts */ + if (cinfo->out_color_components == 3) + TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize->Ncolors[0], + cquantize->Ncolors[1], cquantize->Ncolors[2]); + else + TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); + + /* Allocate and fill in the colormap. */ + /* The colors are ordered in the map in standard row-major order, */ + /* i.e. rightmost (highest-indexed) color changes most rapidly. */ + + colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + /* blkdist is distance between groups of identical entries for a component */ + blkdist = total_colors; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colormap entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blkdist / nci; + for (j = 0; j < nci; j++) { + /* Compute j'th output value (out of nci) for component */ + val = output_value(cinfo, i, j, nci-1); + /* Fill in all colormap entries that have this value of this component */ + for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { + /* fill in blksize entries beginning at ptr */ + for (k = 0; k < blksize; k++) + colormap[i][ptr+k] = (JSAMPLE) val; + } + } + blkdist = blksize; /* blksize of this color is blkdist of next */ + } + + /* Save the colormap in private storage, + * where it will survive color quantization mode changes. + */ + cquantize->sv_colormap = colormap; + cquantize->sv_actual = total_colors; +} + + +/* + * Create the color index table. + */ + +LOCAL void +create_colorindex (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPROW indexptr; + int i,j,k, nci, blksize, val, pad; + + /* For ordered dither, we pad the color index tables by MAXJSAMPLE in + * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + * This is not necessary in the other dithering modes. However, we + * flag whether it was done in case user changes dithering mode. + */ + if (cinfo->dither_mode == JDITHER_ORDERED) { + pad = MAXJSAMPLE*2; + cquantize->is_padded = TRUE; + } else { + pad = 0; + cquantize->is_padded = FALSE; + } + + cquantize->colorindex = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1 + pad), + (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + blksize = cquantize->sv_actual; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colorindex entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blksize / nci; + + /* adjust colorindex pointers to provide padding at negative indexes. */ + if (pad) + cquantize->colorindex[i] += MAXJSAMPLE; + + /* in loop, val = index of current output value, */ + /* and k = largest j that maps to current val */ + indexptr = cquantize->colorindex[i]; + val = 0; + k = largest_input_value(cinfo, i, 0, nci-1); + for (j = 0; j <= MAXJSAMPLE; j++) { + while (j > k) /* advance val if past boundary */ + k = largest_input_value(cinfo, i, ++val, nci-1); + /* premultiply so that no multiplication needed in main processing */ + indexptr[j] = (JSAMPLE) (val * blksize); + } + /* Pad at both ends if necessary */ + if (pad) + for (j = 1; j <= MAXJSAMPLE; j++) { + indexptr[-j] = indexptr[0]; + indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; + } + } +} + + +/* + * Create an ordered-dither array for a component having ncolors + * distinct output values. + */ + +LOCAL ODITHER_MATRIX_PTR +make_odither_array (j_decompress_ptr cinfo, int ncolors) +{ + ODITHER_MATRIX_PTR odither; + int j,k; + INT32 num,den; + + odither = (ODITHER_MATRIX_PTR) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX)); + /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + * Hence the dither value for the matrix cell with fill order f + * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + * On 16-bit-int machine, be careful to avoid overflow. + */ + den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); + for (j = 0; j < ODITHER_SIZE; j++) { + for (k = 0; k < ODITHER_SIZE; k++) { + num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) + * MAXJSAMPLE; + /* Ensure round towards zero despite C's lack of consistency + * about rounding negative values in integer division... + */ + odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); + } + } + return odither; +} + + +/* + * Create the ordered-dither tables. + * Components having the same number of representative colors may + * share a dither table. + */ + +LOCAL void +create_odither_tables (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + ODITHER_MATRIX_PTR odither; + int i, j, nci; + + for (i = 0; i < cinfo->out_color_components; i++) { + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + odither = NULL; /* search for matching prior component */ + for (j = 0; j < i; j++) { + if (nci == cquantize->Ncolors[j]) { + odither = cquantize->odither[j]; + break; + } + } + if (odither == NULL) /* need a new table? */ + odither = make_odither_array(cinfo, nci); + cquantize->odither[i] = odither; + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF void +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colorindex = cquantize->colorindex; + register int pixcode, ci; + register JSAMPROW ptrin, ptrout; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + register int nc = cinfo->out_color_components; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = 0; + for (ci = 0; ci < nc; ci++) { + pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); + } + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF void +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW ptrin, ptrout; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF void +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + int * dither; /* points to active row of dither matrix */ + int row_index, col_index; /* current indexes into dither matrix */ + int nc = cinfo->out_color_components; + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + row_index = cquantize->row_index; + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + colorindex_ci = cquantize->colorindex[ci]; + dither = cquantize->odither[ci][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + * select output value, accumulate into output code for this pixel. + * Range-limiting need not be done explicitly, as we have extended + * the colorindex table to produce the right answers for out-of-range + * inputs. The maximum dither is +- MAXJSAMPLE; this sets the + * required amount of padding. + */ + *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; + input_ptr += nc; + output_ptr++; + col_index = (col_index + 1) & ODITHER_MASK; + } + } + /* Advance row index for next row */ + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF void +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int * dither0; /* points to active row of dither matrix */ + int * dither1; + int * dither2; + int row_index, col_index; /* current indexes into dither matrix */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + row_index = cquantize->row_index; + input_ptr = input_buf[row]; + output_ptr = output_buf[row]; + dither0 = cquantize->odither[0][row_index]; + dither1 = cquantize->odither[1][row_index]; + dither2 = cquantize->odither[2][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + + dither0[col_index]]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + + dither1[col_index]]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + + dither2[col_index]]); + *output_ptr++ = (JSAMPLE) pixcode; + col_index = (col_index + 1) & ODITHER_MASK; + } + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF void +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register LOCFSERROR cur; /* current error or pixel value */ + LOCFSERROR belowerr; /* error for pixel below cur */ + LOCFSERROR bpreverr; /* error for below/prev col */ + LOCFSERROR bnexterr; /* error for below/next col */ + LOCFSERROR delta; + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + JSAMPROW colormap_ci; + int pixcode; + int nc = cinfo->out_color_components; + int dir; /* 1 for left-to-right, -1 for right-to-left */ + int dirnc; /* dir * nc */ + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + input_ptr += (width-1) * nc; /* so point to rightmost pixel */ + output_ptr += width-1; + dir = -1; + dirnc = -nc; + errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ + } else { + /* work left to right in this row */ + dir = 1; + dirnc = nc; + errorptr = cquantize->fserrors[ci]; /* => entry before first column */ + } + colorindex_ci = cquantize->colorindex[ci]; + colormap_ci = cquantize->sv_colormap[ci]; + /* Preset error values: no error propagated to first pixel from left */ + cur = 0; + /* and no error propagated to row below yet */ + belowerr = bpreverr = 0; + + for (col = width; col > 0; col--) { + /* cur holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE; this sets the required size + * of the range_limit array. + */ + cur += GETJSAMPLE(*input_ptr); + cur = GETJSAMPLE(range_limit[cur]); + /* Select output value, accumulate into output code for this pixel */ + pixcode = GETJSAMPLE(colorindex_ci[cur]); + *output_ptr += (JSAMPLE) pixcode; + /* Compute actual representation error at this pixel */ + /* Note: we can do this even though we don't have the final */ + /* pixel code, because the colormap is orthogonal. */ + cur -= GETJSAMPLE(colormap_ci[pixcode]); + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + bnexterr = cur; + delta = cur * 2; + cur += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr + cur); + cur += delta; /* form error * 5 */ + bpreverr = belowerr + cur; + belowerr = bnexterr; + cur += delta; /* form error * 7 */ + /* At this point cur contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + input_ptr += dirnc; /* advance input ptr to next column */ + output_ptr += dir; /* advance output ptr to next column */ + errorptr += dir; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error value into the + * final fserrors[] entry. Note we need not unload belowerr because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ + } + cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); + } +} + + +/* + * Allocate workspace for Floyd-Steinberg errors. + */ + +LOCAL void +alloc_fs_workspace (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) { + cquantize->fserrors[i] = (FSERRPTR) + (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + } +} + + +/* + * Initialize for one-pass color quantization. + */ + +METHODDEF void +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + /* Install my colormap. */ + cinfo->colormap = cquantize->sv_colormap; + cinfo->actual_number_of_colors = cquantize->sv_actual; + + /* Initialize for desired dithering mode. */ + switch (cinfo->dither_mode) { + case JDITHER_NONE: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = color_quantize3; + else + cquantize->pub.color_quantize = color_quantize; + break; + case JDITHER_ORDERED: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = quantize3_ord_dither; + else + cquantize->pub.color_quantize = quantize_ord_dither; + cquantize->row_index = 0; /* initialize state for ordered dither */ + /* If user changed to ordered dither from another mode, + * we must recreate the color index table with padding. + * This will cost extra space, but probably isn't very likely. + */ + if (! cquantize->is_padded) + create_colorindex(cinfo); + /* Create ordered-dither tables if we didn't already. */ + if (cquantize->odither[0] == NULL) + create_odither_tables(cinfo); + break; + case JDITHER_FS: + cquantize->pub.color_quantize = quantize_fs_dither; + cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ + /* Allocate Floyd-Steinberg workspace if didn't already. */ + if (cquantize->fserrors[0] == NULL) + alloc_fs_workspace(cinfo); + /* Initialize the propagated errors to zero. */ + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) + jzero_far((void FAR *) cquantize->fserrors[i], arraysize); + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } +} + + +/* + * Finish up at the end of the pass. + */ + +METHODDEF void +finish_pass_1_quant (j_decompress_ptr cinfo) +{ + /* no work in 1-pass case */ +} + + +/* + * Switch to a new external colormap between output passes. + * Shouldn't get to this module! + */ + +METHODDEF void +new_color_map_1_quant (j_decompress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + + +/* + * Module initialization routine for 1-pass color quantization. + */ + +GLOBAL void +jinit_1pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_1_quant; + cquantize->pub.finish_pass = finish_pass_1_quant; + cquantize->pub.new_color_map = new_color_map_1_quant; + cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ + cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ + + /* Make sure my internal arrays won't overflow */ + if (cinfo->out_color_components > MAX_Q_COMPS) + ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + /* Create the colormap and color index table. */ + create_colormap(cinfo); + create_colorindex(cinfo); + + /* Allocate Floyd-Steinberg workspace now if requested. + * We do this now since it is FAR storage and may affect the memory + * manager's space calculations. If the user changes to FS dither + * mode in a later pass, we will allocate the space then, and will + * possibly overrun the max_memory_to_use setting. + */ + if (cinfo->dither_mode == JDITHER_FS) + alloc_fs_workspace(cinfo); +} + +#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/renderer/jpeg-6/jquant2.c b/renderer/jpeg-6/jquant2.c new file mode 100644 index 000000000..25043982b --- /dev/null +++ b/renderer/jpeg-6/jquant2.c @@ -0,0 +1,1310 @@ +/* + * jquant2.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 2-pass color quantization (color mapping) routines. + * These routines provide selection of a custom color map for an image, + * followed by mapping of the image to that color map, with optional + * Floyd-Steinberg dithering. + * It is also possible to use just the second pass to map to an arbitrary + * externally-given color map. + * + * Note: ordered dithering is not supported, since there isn't any fast + * way to compute intercolor distances; it's unclear that ordered dither's + * fundamental assumptions even hold with an irregularly spaced color map. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_2PASS_SUPPORTED + + +/* + * This module implements the well-known Heckbert paradigm for color + * quantization. Most of the ideas used here can be traced back to + * Heckbert's seminal paper + * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + * + * In the first pass over the image, we accumulate a histogram showing the + * usage count of each possible color. To keep the histogram to a reasonable + * size, we reduce the precision of the input; typical practice is to retain + * 5 or 6 bits per color, so that 8 or 4 different input values are counted + * in the same histogram cell. + * + * Next, the color-selection step begins with a box representing the whole + * color space, and repeatedly splits the "largest" remaining box until we + * have as many boxes as desired colors. Then the mean color in each + * remaining box becomes one of the possible output colors. + * + * The second pass over the image maps each input pixel to the closest output + * color (optionally after applying a Floyd-Steinberg dithering correction). + * This mapping is logically trivial, but making it go fast enough requires + * considerable care. + * + * Heckbert-style quantizers vary a good deal in their policies for choosing + * the "largest" box and deciding where to cut it. The particular policies + * used here have proved out well in experimental comparisons, but better ones + * may yet be found. + * + * In earlier versions of the IJG code, this module quantized in YCbCr color + * space, processing the raw upsampled data without a color conversion step. + * This allowed the color conversion math to be done only once per colormap + * entry, not once per pixel. However, that optimization precluded other + * useful optimizations (such as merging color conversion with upsampling) + * and it also interfered with desired capabilities such as quantizing to an + * externally-supplied colormap. We have therefore abandoned that approach. + * The present code works in the post-conversion color space, typically RGB. + * + * To improve the visual quality of the results, we actually work in scaled + * RGB space, giving G distances more weight than R, and R in turn more than + * B. To do everything in integer math, we must use integer scale factors. + * The 2/3/1 scale factors used here correspond loosely to the relative + * weights of the colors in the NTSC grayscale equation. + * If you want to use this code to quantize a non-RGB color space, you'll + * probably need to change these scale factors. + */ + +#define R_SCALE 2 /* scale R distances by this much */ +#define G_SCALE 3 /* scale G distances by this much */ +#define B_SCALE 1 /* and B by this much */ + +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + * and B,G,R orders. If you define some other weird order in jmorecfg.h, + * you'll get compile errors until you extend this logic. In that case + * you'll probably want to tweak the histogram sizes too. + */ + +#if RGB_RED == 0 +#define C0_SCALE R_SCALE +#endif +#if RGB_BLUE == 0 +#define C0_SCALE B_SCALE +#endif +#if RGB_GREEN == 1 +#define C1_SCALE G_SCALE +#endif +#if RGB_RED == 2 +#define C2_SCALE R_SCALE +#endif +#if RGB_BLUE == 2 +#define C2_SCALE B_SCALE +#endif + + +/* + * First we have the histogram data structure and routines for creating it. + * + * The number of bits of precision can be adjusted by changing these symbols. + * We recommend keeping 6 bits for G and 5 each for R and B. + * If you have plenty of memory and cycles, 6 bits all around gives marginally + * better results; if you are short of memory, 5 bits all around will save + * some space but degrade the results. + * To maintain a fully accurate histogram, we'd need to allocate a "long" + * (preferably unsigned long) for each cell. In practice this is overkill; + * we can get by with 16 bits per cell. Few of the cell counts will overflow, + * and clamping those that do overflow to the maximum value will give close- + * enough results. This reduces the recommended histogram size from 256Kb + * to 128Kb, which is a useful savings on PC-class machines. + * (In the second pass the histogram space is re-used for pixel mapping data; + * in that capacity, each cell must be able to store zero to the number of + * desired colors. 16 bits/cell is plenty for that too.) + * Since the JPEG code is intended to run in small memory model on 80x86 + * machines, we can't just allocate the histogram in one chunk. Instead + * of a true 3-D array, we use a row of pointers to 2-D arrays. Each + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + * on 80x86 machines, the pointer row is in near memory but the actual + * arrays are in far memory (same arrangement as we use for image arrays). + */ + +#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ + +/* These will do the right thing for either R,G,B or B,G,R color order, + * but you may not like the results for other color orders. + */ +#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ +#define HIST_C1_BITS 6 /* bits of precision in G histogram */ +#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ + +/* Number of elements along histogram axes. */ +#define HIST_C0_ELEMS (1<cquantize; + register JSAMPROW ptr; + register histptr histp; + register hist3d histogram = cquantize->histogram; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptr = input_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the histogram */ + histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] + [GETJSAMPLE(ptr[1]) >> C1_SHIFT] + [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; + /* increment, check for overflow and undo increment if so. */ + if (++(*histp) <= 0) + (*histp)--; + ptr += 3; + } + } +} + + +/* + * Next we have the really interesting routines: selection of a colormap + * given the completed histogram. + * These routines work with a list of "boxes", each representing a rectangular + * subset of the input color space (to histogram precision). + */ + +typedef struct { + /* The bounds of the box (inclusive); expressed as histogram indexes */ + int c0min, c0max; + int c1min, c1max; + int c2min, c2max; + /* The volume (actually 2-norm) of the box */ + INT32 volume; + /* The number of nonzero histogram cells within this box */ + long colorcount; +} box; + +typedef box * boxptr; + + +LOCAL boxptr +find_biggest_color_pop (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest color population */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register long maxc = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->colorcount > maxc && boxp->volume > 0) { + which = boxp; + maxc = boxp->colorcount; + } + } + return which; +} + + +LOCAL boxptr +find_biggest_volume (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest (scaled) volume */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register INT32 maxv = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->volume > maxv) { + which = boxp; + maxv = boxp->volume; + } + } + return which; +} + + +LOCAL void +update_box (j_decompress_ptr cinfo, boxptr boxp) +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ +/* and recompute its volume and population */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + INT32 dist0,dist1,dist2; + long ccount; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + if (c0max > c0min) + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0min = c0min = c0; + goto have_c0min; + } + } + have_c0min: + if (c0max > c0min) + for (c0 = c0max; c0 >= c0min; c0--) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0max = c0max = c0; + goto have_c0max; + } + } + have_c0max: + if (c1max > c1min) + for (c1 = c1min; c1 <= c1max; c1++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1min = c1min = c1; + goto have_c1min; + } + } + have_c1min: + if (c1max > c1min) + for (c1 = c1max; c1 >= c1min; c1--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1max = c1max = c1; + goto have_c1max; + } + } + have_c1max: + if (c2max > c2min) + for (c2 = c2min; c2 <= c2max; c2++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2min = c2min = c2; + goto have_c2min; + } + } + have_c2min: + if (c2max > c2min) + for (c2 = c2max; c2 >= c2min; c2--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2max = c2max = c2; + goto have_c2max; + } + } + have_c2max: + + /* Update box volume. + * We use 2-norm rather than real volume here; this biases the method + * against making long narrow boxes, and it has the side benefit that + * a box is splittable iff norm > 0. + * Since the differences are expressed in histogram-cell units, + * we have to shift back to JSAMPLE units to get consistent distances; + * after which, we scale according to the selected distance scale factors. + */ + dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; + dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; + dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; + boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; + + /* Now scan remaining volume of box and compute population */ + ccount = 0; + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++, histp++) + if (*histp != 0) { + ccount++; + } + } + boxp->colorcount = ccount; +} + + +LOCAL int +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, + int desired_colors) +/* Repeatedly select and split the largest box until we have enough boxes */ +{ + int n,lb; + int c0,c1,c2,cmax; + register boxptr b1,b2; + + while (numboxes < desired_colors) { + /* Select box to split. + * Current algorithm: by population for first half, then by volume. + */ + if (numboxes*2 <= desired_colors) { + b1 = find_biggest_color_pop(boxlist, numboxes); + } else { + b1 = find_biggest_volume(boxlist, numboxes); + } + if (b1 == NULL) /* no splittable boxes left! */ + break; + b2 = &boxlist[numboxes]; /* where new box will go */ + /* Copy the color bounds to the new box. */ + b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; + b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; + /* Choose which axis to split the box on. + * Current algorithm: longest scaled axis. + * See notes in update_box about scaling distances. + */ + c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; + c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; + c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; + /* We want to break any ties in favor of green, then red, blue last. + * This code does the right thing for R,G,B or B,G,R color orders only. + */ +#if RGB_RED == 0 + cmax = c1; n = 1; + if (c0 > cmax) { cmax = c0; n = 0; } + if (c2 > cmax) { n = 2; } +#else + cmax = c1; n = 1; + if (c2 > cmax) { cmax = c2; n = 2; } + if (c0 > cmax) { n = 0; } +#endif + /* Choose split point along selected axis, and update box bounds. + * Current algorithm: split at halfway point. + * (Since the box has been shrunk to minimum volume, + * any split will produce two nonempty subboxes.) + * Note that lb value is max for lower box, so must be < old max. + */ + switch (n) { + case 0: + lb = (b1->c0max + b1->c0min) / 2; + b1->c0max = lb; + b2->c0min = lb+1; + break; + case 1: + lb = (b1->c1max + b1->c1min) / 2; + b1->c1max = lb; + b2->c1min = lb+1; + break; + case 2: + lb = (b1->c2max + b1->c2min) / 2; + b1->c2max = lb; + b2->c2min = lb+1; + break; + } + /* Update stats for boxes */ + update_box(cinfo, b1); + update_box(cinfo, b2); + numboxes++; + } + return numboxes; +} + + +LOCAL void +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) +/* Compute representative color for a box, put it in colormap[icolor] */ +{ + /* Current algorithm: mean weighted by pixels (not colors) */ + /* Note it is important to get the rounding correct! */ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + long count; + long total = 0; + long c0total = 0; + long c1total = 0; + long c2total = 0; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) { + if ((count = *histp++) != 0) { + total += count; + c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count; + } + } + } + + cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); + cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); + cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); +} + + +LOCAL void +select_colors (j_decompress_ptr cinfo, int desired_colors) +/* Master routine for color selection */ +{ + boxptr boxlist; + int numboxes; + int i; + + /* Allocate workspace for box list */ + boxlist = (boxptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); + /* Initialize one box containing whole space */ + numboxes = 1; + boxlist[0].c0min = 0; + boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; + boxlist[0].c1min = 0; + boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; + boxlist[0].c2min = 0; + boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; + /* Shrink it to actually-used volume and set its statistics */ + update_box(cinfo, & boxlist[0]); + /* Perform median-cut to produce final box list */ + numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); + /* Compute the representative color for each box, fill colormap */ + for (i = 0; i < numboxes; i++) + compute_color(cinfo, & boxlist[i], i); + cinfo->actual_number_of_colors = numboxes; + TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); +} + + +/* + * These routines are concerned with the time-critical task of mapping input + * colors to the nearest color in the selected colormap. + * + * We re-use the histogram space as an "inverse color map", essentially a + * cache for the results of nearest-color searches. All colors within a + * histogram cell will be mapped to the same colormap entry, namely the one + * closest to the cell's center. This may not be quite the closest entry to + * the actual input color, but it's almost as good. A zero in the cache + * indicates we haven't found the nearest color for that cell yet; the array + * is cleared to zeroes before starting the mapping pass. When we find the + * nearest color for a cell, its colormap index plus one is recorded in the + * cache for future use. The pass2 scanning routines call fill_inverse_cmap + * when they need to use an unfilled entry in the cache. + * + * Our method of efficiently finding nearest colors is based on the "locally + * sorted search" idea described by Heckbert and on the incremental distance + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics + * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + * the distances from a given colormap entry to each cell of the histogram can + * be computed quickly using an incremental method: the differences between + * distances to adjacent cells themselves differ by a constant. This allows a + * fairly fast implementation of the "brute force" approach of computing the + * distance from every colormap entry to every histogram cell. Unfortunately, + * it needs a work array to hold the best-distance-so-far for each histogram + * cell (because the inner loop has to be over cells, not colormap entries). + * The work array elements have to be INT32s, so the work array would need + * 256Kb at our recommended precision. This is not feasible in DOS machines. + * + * To get around these problems, we apply Thomas' method to compute the + * nearest colors for only the cells within a small subbox of the histogram. + * The work array need be only as big as the subbox, so the memory usage + * problem is solved. Furthermore, we need not fill subboxes that are never + * referenced in pass2; many images use only part of the color gamut, so a + * fair amount of work is saved. An additional advantage of this + * approach is that we can apply Heckbert's locality criterion to quickly + * eliminate colormap entries that are far away from the subbox; typically + * three-fourths of the colormap entries are rejected by Heckbert's criterion, + * and we need not compute their distances to individual cells in the subbox. + * The speed of this approach is heavily influenced by the subbox size: too + * small means too much overhead, too big loses because Heckbert's criterion + * can't eliminate as many colormap entries. Empirically the best subbox + * size seems to be about 1/512th of the histogram (1/8th in each direction). + * + * Thomas' article also describes a refined method which is asymptotically + * faster than the brute-force method, but it is also far more complex and + * cannot efficiently be applied to small subboxes. It is therefore not + * useful for programs intended to be portable to DOS machines. On machines + * with plenty of memory, filling the whole histogram in one shot with Thomas' + * refined method might be faster than the present code --- but then again, + * it might not be any faster, and it's certainly more complicated. + */ + + +/* log2(histogram cells in update box) for each axis; this can be adjusted */ +#define BOX_C0_LOG (HIST_C0_BITS-3) +#define BOX_C1_LOG (HIST_C1_BITS-3) +#define BOX_C2_LOG (HIST_C2_BITS-3) + +#define BOX_C0_ELEMS (1<actual_number_of_colors; + int maxc0, maxc1, maxc2; + int centerc0, centerc1, centerc2; + int i, x, ncolors; + INT32 minmaxdist, min_dist, max_dist, tdist; + INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ + + /* Compute true coordinates of update box's upper corner and center. + * Actually we compute the coordinates of the center of the upper-corner + * histogram cell, which are the upper bounds of the volume we care about. + * Note that since ">>" rounds down, the "center" values may be closer to + * min than to max; hence comparisons to them must be "<=", not "<". + */ + maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); + centerc0 = (minc0 + maxc0) >> 1; + maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); + centerc1 = (minc1 + maxc1) >> 1; + maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); + centerc2 = (minc2 + maxc2) >> 1; + + /* For each color in colormap, find: + * 1. its minimum squared-distance to any point in the update box + * (zero if color is within update box); + * 2. its maximum squared-distance to any point in the update box. + * Both of these can be found by considering only the corners of the box. + * We save the minimum distance for each color in mindist[]; + * only the smallest maximum distance is of interest. + */ + minmaxdist = 0x7FFFFFFFL; + + for (i = 0; i < numcolors; i++) { + /* We compute the squared-c0-distance term, then add in the other two. */ + x = GETJSAMPLE(cinfo->colormap[0][i]); + if (x < minc0) { + tdist = (x - minc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else if (x > maxc0) { + tdist = (x - maxc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + min_dist = 0; + if (x <= centerc0) { + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[1][i]); + if (x < minc1) { + tdist = (x - minc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc1) { + tdist = (x - maxc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc1) { + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[2][i]); + if (x < minc2) { + tdist = (x - minc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc2) { + tdist = (x - maxc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc2) { + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } + } + + mindist[i] = min_dist; /* save away the results */ + if (max_dist < minmaxdist) + minmaxdist = max_dist; + } + + /* Now we know that no cell in the update box is more than minmaxdist + * away from some colormap entry. Therefore, only colors that are + * within minmaxdist of some part of the box need be considered. + */ + ncolors = 0; + for (i = 0; i < numcolors; i++) { + if (mindist[i] <= minmaxdist) + colorlist[ncolors++] = (JSAMPLE) i; + } + return ncolors; +} + + +LOCAL void +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, + int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) +/* Find the closest colormap entry for each cell in the update box, + * given the list of candidate colors prepared by find_nearby_colors. + * Return the indexes of the closest entries in the bestcolor[] array. + * This routine uses Thomas' incremental distance calculation method to + * find the distance from a colormap entry to successive cells in the box. + */ +{ + int ic0, ic1, ic2; + int i, icolor; + register INT32 * bptr; /* pointer into bestdist[] array */ + JSAMPLE * cptr; /* pointer into bestcolor[] array */ + INT32 dist0, dist1; /* initial distance values */ + register INT32 dist2; /* current distance in inner loop */ + INT32 xx0, xx1; /* distance increments */ + register INT32 xx2; + INT32 inc0, inc1, inc2; /* initial values for increments */ + /* This array holds the distance to the nearest-so-far color for each cell */ + INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Initialize best-distance for each cell of the update box */ + bptr = bestdist; + for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) + *bptr++ = 0x7FFFFFFFL; + + /* For each color selected by find_nearby_colors, + * compute its distance to the center of each cell in the box. + * If that's less than best-so-far, update best distance and color number. + */ + + /* Nominal steps between cell centers ("x" in Thomas article) */ +#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) +#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) +#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) + + for (i = 0; i < numcolors; i++) { + icolor = GETJSAMPLE(colorlist[i]); + /* Compute (square of) distance from minc0/c1/c2 to this color */ + inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; + dist0 = inc0*inc0; + inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; + dist0 += inc1*inc1; + inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; + dist0 += inc2*inc2; + /* Form the initial difference increments */ + inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + /* Now loop over all cells in box, updating distance per Thomas method */ + bptr = bestdist; + cptr = bestcolor; + xx0 = inc0; + for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { + dist1 = dist0; + xx1 = inc1; + for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { + dist2 = dist1; + xx2 = inc2; + for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { + if (dist2 < *bptr) { + *bptr = dist2; + *cptr = (JSAMPLE) icolor; + } + dist2 += xx2; + xx2 += 2 * STEP_C2 * STEP_C2; + bptr++; + cptr++; + } + dist1 += xx1; + xx1 += 2 * STEP_C1 * STEP_C1; + } + dist0 += xx0; + xx0 += 2 * STEP_C0 * STEP_C0; + } + } +} + + +LOCAL void +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) +/* Fill the inverse-colormap entries in the update box that contains */ +/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ +/* we can fill as many others as we wish.) */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int minc0, minc1, minc2; /* lower left corner of update box */ + int ic0, ic1, ic2; + register JSAMPLE * cptr; /* pointer into bestcolor[] array */ + register histptr cachep; /* pointer into main cache array */ + /* This array lists the candidate colormap indexes. */ + JSAMPLE colorlist[MAXNUMCOLORS]; + int numcolors; /* number of candidate colors */ + /* This array holds the actually closest colormap index for each cell. */ + JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Convert cell coordinates to update box ID */ + c0 >>= BOX_C0_LOG; + c1 >>= BOX_C1_LOG; + c2 >>= BOX_C2_LOG; + + /* Compute true coordinates of update box's origin corner. + * Actually we compute the coordinates of the center of the corner + * histogram cell, which are the lower bounds of the volume we care about. + */ + minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); + minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); + minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); + + /* Determine which colormap entries are close enough to be candidates + * for the nearest entry to some cell in the update box. + */ + numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + /* Determine the actually nearest colors. */ + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + /* Save the best color numbers (plus 1) in the main cache array */ + c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ + c1 <<= BOX_C1_LOG; + c2 <<= BOX_C2_LOG; + cptr = bestcolor; + for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { + for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { + cachep = & histogram[c0+ic0][c1+ic1][c2]; + for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { + *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); + } + } + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF void +pass2_no_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register JSAMPROW inptr, outptr; + register histptr cachep; + register int c0, c1, c2; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the cache */ + c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; + c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; + c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; + cachep = & histogram[c0][c1][c2]; + /* If we have not seen this color before, find nearest colormap entry */ + /* and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, c0,c1,c2); + /* Now emit the colormap index for this cell */ + *outptr++ = (JSAMPLE) (*cachep - 1); + } + } +} + + +METHODDEF void +pass2_fs_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ + LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + JSAMPROW inptr; /* => current input pixel */ + JSAMPROW outptr; /* => current output pixel */ + histptr cachep; + int dir; /* +1 or -1 depending on direction */ + int dir3; /* 3*dir, for advancing inptr & errorptr */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + int *error_limit = cquantize->error_limiter; + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + inptr += (width-1) * 3; /* so point to rightmost pixel */ + outptr += width-1; + dir = -1; + dir3 = -3; + errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ + cquantize->on_odd_row = FALSE; /* flip for next time */ + } else { + /* work left to right in this row */ + dir = 1; + dir3 = 3; + errorptr = cquantize->fserrors; /* => entry before first real column */ + cquantize->on_odd_row = TRUE; /* flip for next time */ + } + /* Preset error values: no error propagated to first pixel from left */ + cur0 = cur1 = cur2 = 0; + /* and no error propagated to row below yet */ + belowerr0 = belowerr1 = belowerr2 = 0; + bpreverr0 = bpreverr1 = bpreverr2 = 0; + + for (col = width; col > 0; col--) { + /* curN holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); + cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); + cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); + /* Limit the error using transfer function set by init_error_limit. + * See comments with init_error_limit for rationale. + */ + cur0 = error_limit[cur0]; + cur1 = error_limit[cur1]; + cur2 = error_limit[cur2]; + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE (or less with error limiting); + * this sets the required size of the range_limit array. + */ + cur0 += GETJSAMPLE(inptr[0]); + cur1 += GETJSAMPLE(inptr[1]); + cur2 += GETJSAMPLE(inptr[2]); + cur0 = GETJSAMPLE(range_limit[cur0]); + cur1 = GETJSAMPLE(range_limit[cur1]); + cur2 = GETJSAMPLE(range_limit[cur2]); + /* Index into the cache with adjusted pixel value */ + cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; + /* If we have not seen this color before, find nearest colormap */ + /* entry and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); + /* Now emit the colormap index for this cell */ + { register int pixcode = *cachep - 1; + *outptr = (JSAMPLE) pixcode; + /* Compute representation error for this pixel */ + cur0 -= GETJSAMPLE(colormap0[pixcode]); + cur1 -= GETJSAMPLE(colormap1[pixcode]); + cur2 -= GETJSAMPLE(colormap2[pixcode]); + } + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + { register LOCFSERROR bnexterr, delta; + + bnexterr = cur0; /* Process component 0 */ + delta = cur0 * 2; + cur0 += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr0 + cur0); + cur0 += delta; /* form error * 5 */ + bpreverr0 = belowerr0 + cur0; + belowerr0 = bnexterr; + cur0 += delta; /* form error * 7 */ + bnexterr = cur1; /* Process component 1 */ + delta = cur1 * 2; + cur1 += delta; /* form error * 3 */ + errorptr[1] = (FSERROR) (bpreverr1 + cur1); + cur1 += delta; /* form error * 5 */ + bpreverr1 = belowerr1 + cur1; + belowerr1 = bnexterr; + cur1 += delta; /* form error * 7 */ + bnexterr = cur2; /* Process component 2 */ + delta = cur2 * 2; + cur2 += delta; /* form error * 3 */ + errorptr[2] = (FSERROR) (bpreverr2 + cur2); + cur2 += delta; /* form error * 5 */ + bpreverr2 = belowerr2 + cur2; + belowerr2 = bnexterr; + cur2 += delta; /* form error * 7 */ + } + /* At this point curN contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + inptr += dir3; /* Advance pixel pointers to next column */ + outptr += dir; + errorptr += dir3; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error values into the + * final fserrors[] entry. Note we need not unload belowerrN because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ + errorptr[1] = (FSERROR) bpreverr1; + errorptr[2] = (FSERROR) bpreverr2; + } +} + + +/* + * Initialize the error-limiting transfer function (lookup table). + * The raw F-S error computation can potentially compute error values of up to + * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + * much less, otherwise obviously wrong pixels will be created. (Typical + * effects include weird fringes at color-area boundaries, isolated bright + * pixels in a dark area, etc.) The standard advice for avoiding this problem + * is to ensure that the "corners" of the color cube are allocated as output + * colors; then repeated errors in the same direction cannot cause cascading + * error buildup. However, that only prevents the error from getting + * completely out of hand; Aaron Giles reports that error limiting improves + * the results even with corner colors allocated. + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + * well, but the smoother transfer function used below is even better. Thanks + * to Aaron Giles for this idea. + */ + +LOCAL void +init_error_limit (j_decompress_ptr cinfo) +/* Allocate and fill in the error_limiter table */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + int * table; + int in, out; + + table = (int *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); + table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ + cquantize->error_limiter = table; + +#define STEPSIZE ((MAXJSAMPLE+1)/16) + /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ + out = 0; + for (in = 0; in < STEPSIZE; in++, out++) { + table[in] = out; table[-in] = -out; + } + /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ + for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { + table[in] = out; table[-in] = -out; + } + /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ + for (; in <= MAXJSAMPLE; in++) { + table[in] = out; table[-in] = -out; + } +#undef STEPSIZE +} + + +/* + * Finish up at the end of each pass. + */ + +METHODDEF void +finish_pass1 (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Select the representative colors and fill in cinfo->colormap */ + cinfo->colormap = cquantize->sv_colormap; + select_colors(cinfo, cquantize->desired); + /* Force next pass to zero the color index table */ + cquantize->needs_zeroed = TRUE; +} + + +METHODDEF void +finish_pass2 (j_decompress_ptr cinfo) +{ + /* no work */ +} + + +/* + * Initialize for each processing pass. + */ + +METHODDEF void +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int i; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + if (is_pre_scan) { + /* Set up method pointers */ + cquantize->pub.color_quantize = prescan_quantize; + cquantize->pub.finish_pass = finish_pass1; + cquantize->needs_zeroed = TRUE; /* Always zero histogram */ + } else { + /* Set up method pointers */ + if (cinfo->dither_mode == JDITHER_FS) + cquantize->pub.color_quantize = pass2_fs_dither; + else + cquantize->pub.color_quantize = pass2_no_dither; + cquantize->pub.finish_pass = finish_pass2; + + /* Make sure color count is acceptable */ + i = cinfo->actual_number_of_colors; + if (i < 1) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo->dither_mode == JDITHER_FS) { + size_t arraysize = (size_t) ((cinfo->output_width + 2) * + (3 * SIZEOF(FSERROR))); + /* Allocate Floyd-Steinberg workspace if we didn't already. */ + if (cquantize->fserrors == NULL) + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + /* Initialize the propagated errors to zero. */ + jzero_far((void FAR *) cquantize->fserrors, arraysize); + /* Make the error-limit table if we didn't already. */ + if (cquantize->error_limiter == NULL) + init_error_limit(cinfo); + cquantize->on_odd_row = FALSE; + } + + } + /* Zero the histogram or inverse color map, if necessary */ + if (cquantize->needs_zeroed) { + for (i = 0; i < HIST_C0_ELEMS; i++) { + jzero_far((void FAR *) histogram[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = FALSE; + } +} + + +/* + * Switch to a new external colormap between output passes. + */ + +METHODDEF void +new_color_map_2_quant (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Reset the inverse color map */ + cquantize->needs_zeroed = TRUE; +} + + +/* + * Module initialization routine for 2-pass color quantization. + */ + +GLOBAL void +jinit_2pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + int i; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_2_quant; + cquantize->pub.new_color_map = new_color_map_2_quant; + cquantize->fserrors = NULL; /* flag optional arrays not allocated */ + cquantize->error_limiter = NULL; + + /* Make sure jdmaster didn't give me a case I can't handle */ + if (cinfo->out_color_components != 3) + ERREXIT(cinfo, JERR_NOTIMPL); + + /* Allocate the histogram/inverse colormap storage */ + cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); + for (i = 0; i < HIST_C0_ELEMS; i++) { + cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ + + /* Allocate storage for the completed colormap, if required. + * We do this now since it is FAR storage and may affect + * the memory manager's space calculations. + */ + if (cinfo->enable_2pass_quant) { + /* Make sure color count is acceptable */ + int desired = cinfo->desired_number_of_colors; + /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ + if (desired < 8) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (desired > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); + cquantize->desired = desired; + } else + cquantize->sv_colormap = NULL; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + /* Allocate Floyd-Steinberg workspace if necessary. + * This isn't really needed until pass 2, but again it is FAR storage. + * Although we will cope with a later change in dither_mode, + * we do not promise to honor max_memory_to_use if dither_mode changes. + */ + if (cinfo->dither_mode == JDITHER_FS) { + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); + /* Might as well create the error-limiting table too. */ + init_error_limit(cinfo); + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/renderer/jpeg-6/jutils.c b/renderer/jpeg-6/jutils.c new file mode 100644 index 000000000..4ba2a543c --- /dev/null +++ b/renderer/jpeg-6/jutils.c @@ -0,0 +1,175 @@ +/* + * jutils.c + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + * of a DCT block read in natural order (left to right, top to bottom). + */ + +const int jpeg_zigzag_order[DCTSIZE2] = { + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; + +/* + * jpeg_natural_order[i] is the natural-order position of the i'th element + * of zigzag order. + * + * When reading corrupted data, the Huffman decoders could attempt + * to reference an entry beyond the end of this array (if the decoded + * zero run length reaches past the end of the block). To prevent + * wild stores without adding an inner-loop test, we put some extra + * "63"s after the real entries. This will cause the extra coefficient + * to be stored in location 63 of the block, not somewhere random. + * The worst case would be a run-length of 15, which means we need 16 + * fake entries. + */ + +const int jpeg_natural_order[DCTSIZE2+16] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 +}; + + +/* + * Arithmetic utilities + */ + +GLOBAL long +jdiv_round_up (long a, long b) +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ +/* Assumes a >= 0, b > 0 */ +{ + return (a + b - 1L) / b; +} + + +GLOBAL long +jround_up (long a, long b) +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ +/* Assumes a >= 0, b > 0 */ +{ + a += b - 1L; + return a - (a % b); +} + + +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + * and coefficient-block arrays. This won't work on 80x86 because the arrays + * are FAR and we're assuming a small-pointer memory model. However, some + * DOS compilers provide far-pointer versions of memcpy() and memset() even + * in the small-model libraries. These will be used if USE_FMEM is defined. + * Otherwise, the routines below do it the hard way. (The performance cost + * is not all that great, because these routines aren't very heavily used.) + */ + +#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) +#define FMEMZERO(target,size) MEMZERO(target,size) +#else /* 80x86 case, define if we can */ +#ifdef USE_FMEM +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) +#endif +#endif + + +GLOBAL void +jcopy_sample_rows (JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols) +/* Copy some rows of samples from one place to another. + * num_rows rows are copied from input_array[source_row++] + * to output_array[dest_row++]; these areas may overlap for duplication. + * The source and destination arrays must be at least as wide as num_cols. + */ +{ + register JSAMPROW inptr, outptr; +#ifdef FMEMCOPY + register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); +#else + register JDIMENSION count; +#endif + register int row; + + input_array += source_row; + output_array += dest_row; + + for (row = num_rows; row > 0; row--) { + inptr = *input_array++; + outptr = *output_array++; +#ifdef FMEMCOPY + FMEMCOPY(outptr, inptr, count); +#else + for (count = num_cols; count > 0; count--) + *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ +#endif + } +} + + +GLOBAL void +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks) +/* Copy a row of coefficient blocks from one place to another. */ +{ +#ifdef FMEMCOPY + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +#else + register JCOEFPTR inptr, outptr; + register long count; + + inptr = (JCOEFPTR) input_row; + outptr = (JCOEFPTR) output_row; + for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { + *outptr++ = *inptr++; + } +#endif +} + + +GLOBAL void +jzero_far (void FAR * target, size_t bytestozero) +/* Zero out a chunk of FAR memory. */ +/* This might be sample-array data, block-array data, or alloc_large data. */ +{ +#ifdef FMEMZERO + FMEMZERO(target, bytestozero); +#else + register char FAR * ptr = (char FAR *) target; + register size_t count; + + for (count = bytestozero; count > 0; count--) { + *ptr++ = 0; + } +#endif +} diff --git a/renderer/jpeg-6/jversion.h b/renderer/jpeg-6/jversion.h new file mode 100644 index 000000000..f2f1b8da0 --- /dev/null +++ b/renderer/jpeg-6/jversion.h @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1995, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6 2-Aug-95" + +#define JCOPYRIGHT "Copyright (C) 1995, Thomas G. Lane" diff --git a/renderer/material.h b/renderer/material.h deleted file mode 100644 index 31ac013ad..000000000 --- a/renderer/material.h +++ /dev/null @@ -1,682 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MATERIAL_H__ -#define __MATERIAL_H__ - -/* -=============================================================================== - - Material - -=============================================================================== -*/ - -class idImage; -class idCinematic; -class idUserInterface; -class idMegaTexture; - -// moved from image.h for default parm -typedef enum { - TF_LINEAR, - TF_NEAREST, - TF_DEFAULT // use the user-specified r_textureFilter -} textureFilter_t; - -typedef enum { - TR_REPEAT, - TR_CLAMP, - TR_CLAMP_TO_BORDER, // this should replace TR_CLAMP_TO_ZERO and TR_CLAMP_TO_ZERO_ALPHA, - // but I don't want to risk changing it right now - TR_CLAMP_TO_ZERO, // guarantee 0,0,0,255 edge for projected textures, - // set AFTER image format selection - TR_CLAMP_TO_ZERO_ALPHA // guarantee 0 alpha edge for projected textures, - // set AFTER image format selection -} textureRepeat_t; - -typedef struct { - int stayTime; // msec for no change - int fadeTime; // msec to fade vertex colors over - float start[4]; // vertex color at spawn (possibly out of 0.0 - 1.0 range, will clamp after calc) - float end[4]; // vertex color at fade-out (possibly out of 0.0 - 1.0 range, will clamp after calc) -} decalInfo_t; - -typedef enum { - DFRM_NONE, - DFRM_SPRITE, - DFRM_TUBE, - DFRM_FLARE, - DFRM_EXPAND, - DFRM_MOVE, - DFRM_EYEBALL, - DFRM_PARTICLE, - DFRM_PARTICLE2, - DFRM_TURB -} deform_t; - -typedef enum { - DI_STATIC, - DI_SCRATCH, // video, screen wipe, etc - DI_CUBE_RENDER, - DI_MIRROR_RENDER, - DI_XRAY_RENDER, - DI_REMOTE_RENDER -} dynamicidImage_t; - -// note: keep opNames[] in sync with changes -typedef enum { - OP_TYPE_ADD, - OP_TYPE_SUBTRACT, - OP_TYPE_MULTIPLY, - OP_TYPE_DIVIDE, - OP_TYPE_MOD, - OP_TYPE_TABLE, - OP_TYPE_GT, - OP_TYPE_GE, - OP_TYPE_LT, - OP_TYPE_LE, - OP_TYPE_EQ, - OP_TYPE_NE, - OP_TYPE_AND, - OP_TYPE_OR, - OP_TYPE_SOUND -} expOpType_t; - -typedef enum { - EXP_REG_TIME, - - EXP_REG_PARM0, - EXP_REG_PARM1, - EXP_REG_PARM2, - EXP_REG_PARM3, - EXP_REG_PARM4, - EXP_REG_PARM5, - EXP_REG_PARM6, - EXP_REG_PARM7, - EXP_REG_PARM8, - EXP_REG_PARM9, - EXP_REG_PARM10, - EXP_REG_PARM11, - - EXP_REG_GLOBAL0, - EXP_REG_GLOBAL1, - EXP_REG_GLOBAL2, - EXP_REG_GLOBAL3, - EXP_REG_GLOBAL4, - EXP_REG_GLOBAL5, - EXP_REG_GLOBAL6, - EXP_REG_GLOBAL7, - - EXP_REG_NUM_PREDEFINED -} expRegister_t; - -typedef struct { - expOpType_t opType; - int a, b, c; -} expOp_t; - -typedef struct { - int registers[4]; -} colorStage_t; - -typedef enum { - TG_EXPLICIT, - TG_DIFFUSE_CUBE, - TG_REFLECT_CUBE, - TG_SKYBOX_CUBE, - TG_WOBBLESKY_CUBE, - TG_SCREEN, // screen aligned, for mirrorRenders and screen space temporaries - TG_SCREEN2, - TG_GLASSWARP -} texgen_t; - -typedef struct { - idCinematic * cinematic; - idImage * image; - texgen_t texgen; - bool hasMatrix; - int matrix[2][3]; // we only allow a subset of the full projection matrix - - // dynamic image variables - dynamicidImage_t dynamic; - int width, height; - int dynamicFrameCount; -} textureStage_t; - -// the order BUMP / DIFFUSE / SPECULAR is necessary for interactions to draw correctly on low end cards -typedef enum { - SL_AMBIENT, // execute after lighting - SL_BUMP, - SL_DIFFUSE, - SL_SPECULAR -} stageLighting_t; - -// cross-blended terrain textures need to modulate the color by -// the vertex color to smoothly blend between two textures -typedef enum { - SVC_IGNORE, - SVC_MODULATE, - SVC_INVERSE_MODULATE -} stageVertexColor_t; - -static const int MAX_FRAGMENT_IMAGES = 8; -static const int MAX_VERTEX_PARMS = 4; - -typedef struct { - int vertexProgram; - int numVertexParms; - int vertexParms[MAX_VERTEX_PARMS][4]; // evaluated register indexes - - int fragmentProgram; - int numFragmentProgramImages; - idImage * fragmentProgramImages[MAX_FRAGMENT_IMAGES]; - - idMegaTexture *megaTexture; // handles all the binding and parameter setting -} newShaderStage_t; - -typedef struct { - int conditionRegister; // if registers[conditionRegister] == 0, skip stage - stageLighting_t lighting; // determines which passes interact with lights - int drawStateBits; - colorStage_t color; - bool hasAlphaTest; - int alphaTestRegister; - textureStage_t texture; - stageVertexColor_t vertexColor; - bool ignoreAlphaTest; // this stage should act as translucent, even - // if the surface is alpha tested - float privatePolygonOffset; // a per-stage polygon offset - - newShaderStage_t *newStage; // vertex / fragment program based stage -} shaderStage_t; - -typedef enum { - MC_BAD, - MC_OPAQUE, // completely fills the triangle, will have black drawn on fillDepthBuffer - MC_PERFORATED, // may have alpha tested holes - MC_TRANSLUCENT // blended with background -} materialCoverage_t; - -typedef enum { - SS_SUBVIEW = -3, // mirrors, viewscreens, etc - SS_GUI = -2, // guis - SS_BAD = -1, - SS_OPAQUE, // opaque - - SS_PORTAL_SKY, - - SS_DECAL, // scorch marks, etc. - - SS_FAR, - SS_MEDIUM, // normal translucent - SS_CLOSE, - - SS_ALMOST_NEAREST, // gun smoke puffs - - SS_NEAREST, // screen blood blobs - - SS_POST_PROCESS = 100 // after a screen copy to texture -} materialSort_t; - -typedef enum { - CT_FRONT_SIDED, - CT_BACK_SIDED, - CT_TWO_SIDED -} cullType_t; - -// these don't effect per-material storage, so they can be very large -const int MAX_SHADER_STAGES = 256; - -const int MAX_TEXGEN_REGISTERS = 4; - -const int MAX_ENTITY_SHADER_PARMS = 12; - -// material flags -typedef enum { - MF_DEFAULTED = BIT(0), - MF_POLYGONOFFSET = BIT(1), - MF_NOSHADOWS = BIT(2), - MF_FORCESHADOWS = BIT(3), - MF_NOSELFSHADOW = BIT(4), - MF_NOPORTALFOG = BIT(5), // this fog volume won't ever consider a portal fogged out - MF_EDITOR_VISIBLE = BIT(6) // in use (visible) per editor -} materialFlags_t; - -// contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these! -typedef enum { - CONTENTS_SOLID = BIT(0), // an eye is never valid in a solid - CONTENTS_OPAQUE = BIT(1), // blocks visibility (for ai) - CONTENTS_WATER = BIT(2), // used for water - CONTENTS_PLAYERCLIP = BIT(3), // solid to players - CONTENTS_MONSTERCLIP = BIT(4), // solid to monsters - CONTENTS_MOVEABLECLIP = BIT(5), // solid to moveable entities - CONTENTS_IKCLIP = BIT(6), // solid to IK - CONTENTS_BLOOD = BIT(7), // used to detect blood decals - CONTENTS_BODY = BIT(8), // used for actors - CONTENTS_PROJECTILE = BIT(9), // used for projectiles - CONTENTS_CORPSE = BIT(10), // used for dead bodies - CONTENTS_RENDERMODEL = BIT(11), // used for render models for collision detection - CONTENTS_TRIGGER = BIT(12), // used for triggers - CONTENTS_AAS_SOLID = BIT(13), // solid for AAS - CONTENTS_AAS_OBSTACLE = BIT(14), // used to compile an obstacle into AAS that can be enabled/disabled - CONTENTS_FLASHLIGHT_TRIGGER = BIT(15), // used for triggers that are activated by the flashlight - CONTENTS_FROBABLE = BIT(16), // TDM: Used for CMs that are only for frobbing - CONTENTS_RESPONSE = BIT(17), // TDM: Used for stim/response optimization. - CONTENTS_MELEEWEAP = BIT(18), // TDM: Used for melee weapons and shields - - // contents used by utils - CONTENTS_AREAPORTAL = BIT(20), // portal separating renderer areas - CONTENTS_NOCSG = BIT(21), // don't cut this brush with CSG operations in the editor - - CONTENTS_REMOVE_UTIL = ~(CONTENTS_AREAPORTAL|CONTENTS_NOCSG) -} contentsFlags_t; - -// surface types -const int NUM_SURFACE_BITS = 4; -const int MAX_SURFACE_TYPES = 1 << NUM_SURFACE_BITS; - -typedef enum { - SURFTYPE_NONE, // default type - SURFTYPE_METAL, - SURFTYPE_STONE, - SURFTYPE_FLESH, - SURFTYPE_WOOD, - SURFTYPE_CARDBOARD, - SURFTYPE_LIQUID, - SURFTYPE_GLASS, - SURFTYPE_PLASTIC, - SURFTYPE_RICOCHET, - SURFTYPE_10, - SURFTYPE_11, - SURFTYPE_12, - SURFTYPE_13, - SURFTYPE_14, - SURFTYPE_15 -} surfTypes_t; - -// surface flags -typedef enum { - SURF_TYPE_BIT0 = BIT(0), // encodes the material type (metal, flesh, concrete, etc.) - SURF_TYPE_BIT1 = BIT(1), // " - SURF_TYPE_BIT2 = BIT(2), // " - SURF_TYPE_BIT3 = BIT(3), // " - SURF_TYPE_MASK = ( 1 << NUM_SURFACE_BITS ) - 1, - - SURF_NODAMAGE = BIT(4), // never give falling damage - SURF_SLICK = BIT(5), // effects game physics - SURF_COLLISION = BIT(6), // collision surface - SURF_LADDER = BIT(7), // player can climb up this surface - SURF_NOIMPACT = BIT(8), // don't make missile explosions - SURF_NOSTEPS = BIT(9), // no footstep sounds - SURF_DISCRETE = BIT(10), // not clipped or merged by utilities - SURF_NOFRAGMENT = BIT(11), // dmap won't cut surface at each bsp boundary - SURF_NULLNORMAL = BIT(12) // renderbump will draw this surface as 0x80 0x80 0x80, which - // won't collect light from any angle -} surfaceFlags_t; - -class idSoundEmitter; - -class idMaterial : public idDecl { -public: - idMaterial(); - virtual ~idMaterial(); - - virtual size_t Size( void ) const; - virtual bool SetDefaultText( void ); - virtual const char *DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - virtual void Print( void ) const; - - //BSM Nerve: Added for material editor - bool Save( const char *fileName = NULL ); - - // returns the internal image name for stage 0, which can be used - // for the renderer CaptureRenderToImage() call - // I'm not really sure why this needs to be virtual... - virtual const char *ImageName( void ) const; - - void ReloadImages( bool force ) const; - - // returns number of stages this material contains - const int GetNumStages( void ) const { return numStages; } - - // get a specific stage - const shaderStage_t *GetStage( const int index ) const { assert(index >= 0 && index < numStages); return &stages[index]; } - - // get the first bump map stage, or NULL if not present. - // used for bumpy-specular - const shaderStage_t *GetBumpStage( void ) const; - - // returns true if the material will draw anything at all. Triggers, portals, - // etc, will not have anything to draw. A not drawn surface can still castShadow, - // which can be used to make a simplified shadow hull for a complex object set - // as noShadow - bool IsDrawn( void ) const { return ( numStages > 0 || entityGui != 0 || gui != NULL ); } - - // Tels: Added for TDM v1.03 - bool IsSlick( void ) const { return ((surfaceFlags & SURF_SLICK) != 0); }; - bool IsLadder( void ) const { return ((surfaceFlags & SURF_LADDER) != 0); }; - - // returns true if the material will draw any non light interaction stages - bool HasAmbient( void ) const { return ( numAmbientStages > 0 ); } - - // returns true if material has a gui - bool HasGui( void ) const { return ( entityGui != 0 || gui != NULL ); } - - // returns true if the material will generate another view, either as - // a mirror or dynamic rendered image - bool HasSubview( void ) const { return hasSubview; } - - // returns true if the material will generate shadows, not making a - // distinction between global and no-self shadows - bool SurfaceCastsShadow( void ) const { return TestMaterialFlag( MF_FORCESHADOWS ) || !TestMaterialFlag( MF_NOSHADOWS ); } - - // returns true if the material will generate interactions with fog/blend lights - // All non-translucent surfaces receive fog unless they are explicitly noFog - bool ReceivesFog( void ) const { return ( IsDrawn() && !noFog && coverage != MC_TRANSLUCENT ); } - - // returns true if the material will generate interactions with normal lights - // Many special effect surfaces don't have any bump/diffuse/specular - // stages, and don't interact with lights at all - bool ReceivesLighting( void ) const { return numAmbientStages != numStages; } - - // returns true if the material should generate interactions on sides facing away - // from light centers, as with noshadow and noselfshadow options - bool ReceivesLightingOnBackSides( void ) const { return ( materialFlags & (MF_NOSELFSHADOW|MF_NOSHADOWS) ) != 0; } - - // Standard two-sided triangle rendering won't work with bump map lighting, because - // the normal and tangent vectors won't be correct for the back sides. When two - // sided lighting is desired. typically for alpha tested surfaces, this is - // addressed by having CleanupModelSurfaces() create duplicates of all the triangles - // with apropriate order reversal. - bool ShouldCreateBackSides( void ) const { return shouldCreateBackSides; } - - // characters and models that are created by a complete renderbump can use a faster - // method of tangent and normal vector generation than surfaces which have a flat - // renderbump wrapped over them. - bool UseUnsmoothedTangents( void ) const { return unsmoothedTangents; } - - // by default, monsters can have blood overlays placed on them, but this can - // be overrided on a per-material basis with the "noOverlays" material command. - // This will always return false for translucent surfaces - bool AllowOverlays( void ) const { return allowOverlays; } - - // MC_OPAQUE, MC_PERFORATED, or MC_TRANSLUCENT, for interaction list linking and - // dmap flood filling - // The depth buffer will not be filled for MC_TRANSLUCENT surfaces - // FIXME: what do nodraw surfaces return? - materialCoverage_t Coverage( void ) const { return coverage; } - - // returns true if this material takes precedence over other in coplanar cases - bool HasHigherDmapPriority( const idMaterial &other ) const { return ( IsDrawn() && !other.IsDrawn() ) || - ( Coverage() < other.Coverage() ); } - - // returns a idUserInterface if it has a global gui, or NULL if no gui - idUserInterface * GlobalGui( void ) const { return gui; } - - // a discrete surface will never be merged with other surfaces by dmap, which is - // necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other - // special effects from being combined into a single surface - // guis, merging sprites or other effects, mirrors and remote views are always discrete - bool IsDiscrete( void ) const { return ( entityGui || gui || deform != DFRM_NONE || sort == SS_SUBVIEW || - ( surfaceFlags & SURF_DISCRETE ) != 0 ); } - - // Normally, dmap chops each surface by every BSP boundary, then reoptimizes. - // For gigantic polygons like sky boxes, this can cause a huge number of planar - // triangles that make the optimizer take forever to turn back into a single - // triangle. The "noFragment" option causes dmap to only break the polygons at - // area boundaries, instead of every BSP boundary. This has the negative effect - // of not automatically fixing up interpenetrations, so when this is used, you - // should manually make the edges of your sky box exactly meet, instead of poking - // into each other. - bool NoFragment( void ) const { return ( surfaceFlags & SURF_NOFRAGMENT ) != 0; } - - //------------------------------------------------------------------ - // light shader specific functions, only called for light entities - - // lightshader option to fill with fog from viewer instead of light from center - bool IsFogLight() const { return fogLight; } - - // perform simple blending of the projection, instead of interacting with bumps and textures - bool IsBlendLight() const { return blendLight; } - - // an ambient light has non-directional bump mapping and no specular - bool IsAmbientLight() const { return ambientLight; } - - // implicitly no-shadows lights (ambients, fogs, etc) will never cast shadows - // but individual light entities can also override this value - bool LightCastsShadows() const { return TestMaterialFlag( MF_FORCESHADOWS ) || - ( !fogLight && !ambientLight && !blendLight && !TestMaterialFlag( MF_NOSHADOWS ) ); } - - // fog lights, blend lights, ambient lights, etc will all have to have interaction - // triangles generated for sides facing away from the light as well as those - // facing towards the light. It is debatable if noshadow lights should effect back - // sides, making everything "noSelfShadow", but that would make noshadow lights - // potentially slower than normal lights, which detracts from their optimization - // ability, so they currently do not. - bool LightEffectsBackSides() const { return fogLight || ambientLight || blendLight; } - - // NULL unless an image is explicitly specified in the shader with "lightFalloffShader " - idImage * LightFalloffImage() const { return lightFalloffImage; } - - //------------------------------------------------------------------ - - // returns the renderbump command line for this shader, or an empty string if not present - const char * GetRenderBump() const { return renderBump; }; - - // set specific material flag(s) - void SetMaterialFlag( const int flag ) const { materialFlags |= flag; } - - // clear specific material flag(s) - void ClearMaterialFlag( const int flag ) const { materialFlags &= ~flag; } - - // test for existance of specific material flag(s) - bool TestMaterialFlag( const int flag ) const { return ( materialFlags & flag ) != 0; } - - // get content flags - const int GetContentFlags( void ) const { return contentFlags; } - - // get surface flags - const int GetSurfaceFlags( void ) const { return surfaceFlags; } - - // gets name for surface type (stone, metal, flesh, etc.) - const surfTypes_t GetSurfaceType( void ) const { return static_cast( surfaceFlags & SURF_TYPE_MASK ); } - - // get material description - const char * GetDescription( void ) const { return desc; } - - // get sort order - const float GetSort( void ) const { return sort; } - // this is only used by the gui system to force sorting order - // on images referenced from tga's instead of materials. - // this is done this way as there are 2000 tgas the guis use - void SetSort( float s ) const { sort = s; }; - - // DFRM_NONE, DFRM_SPRITE, etc - deform_t Deform( void ) const { return deform; } - - // flare size, expansion size, etc - const int GetDeformRegister( int index ) const { return deformRegisters[index]; } - - // particle system to emit from surface and table for turbulent - const idDecl *GetDeformDecl( void ) const { return deformDecl; } - - // currently a surface can only have one unique texgen for all the stages - texgen_t Texgen() const; - - // wobble sky parms - const int * GetTexGenRegisters( void ) const { return texGenRegisters; } - - // get cull type - const cullType_t GetCullType( void ) const { return cullType; } - - float GetEditorAlpha( void ) const { return editorAlpha; } - - int GetEntityGui( void ) const { return entityGui; } - - decalInfo_t GetDecalInfo( void ) const { return decalInfo; } - - // spectrums are used for "invisible writing" that can only be - // illuminated by a light of matching spectrum - int Spectrum( void ) const { return spectrum; } - - float GetPolygonOffset( void ) const { return polygonOffset; } - - float GetSurfaceArea( void ) const { return surfaceArea; } - void AddToSurfaceArea( float area ) { surfaceArea += area; } - - //------------------------------------------------------------------ - - // returns the length, in milliseconds, of the videoMap on this material, - // or zero if it doesn't have one - int CinematicLength( void ) const; - - void CloseCinematic( void ) const; - - void ResetCinematicTime( int time ) const; - - void UpdateCinematic( int time ) const; - - //------------------------------------------------------------------ - - // gets an image for the editor to use - idImage * GetEditorImage( void ) const; - int GetImageWidth( void ) const; - int GetImageHeight( void ) const; - - void SetGui( const char *_gui ) const; - - // just for resource tracking - void SetImageClassifications( int tag ) const; - - //------------------------------------------------------------------ - - // returns number of registers this material contains - const int GetNumRegisters() const { return numRegisters; } - - // regs should point to a float array large enough to hold GetNumRegisters() floats - void EvaluateRegisters( float *regs, const float entityParms[MAX_ENTITY_SHADER_PARMS], - const struct viewDef_s *view, idSoundEmitter *soundEmitter = NULL ) const; - - // if a material only uses constants (no entityParm or globalparm references), this - // will return a pointer to an internal table, and EvaluateRegisters will not need - // to be called. If NULL is returned, EvaluateRegisters must be used. - const float * ConstantRegisters() const; - - bool SuppressInSubview() const { return suppressInSubview; }; - bool IsPortalSky() const { return portalSky; }; - void AddReference(); - -private: - // parse the entire material - void CommonInit(); - void ParseMaterial( idLexer &src ); - bool MatchToken( idLexer &src, const char *match ); - void ParseSort( idLexer &src ); - void ParseBlend( idLexer &src, shaderStage_t *stage ); - void ParseVertexParm( idLexer &src, newShaderStage_t *newStage ); - void ParseFragmentMap( idLexer &src, newShaderStage_t *newStage ); - void ParseStage( idLexer &src, const textureRepeat_t trpDefault = TR_REPEAT ); - void ParseDeform( idLexer &src ); - void ParseDecalInfo( idLexer &src ); - bool CheckSurfaceParm( idToken *token ); - int GetExpressionConstant( float f ); - int GetExpressionTemporary( void ); - expOp_t * GetExpressionOp( void ); - int EmitOp( int a, int b, expOpType_t opType ); - int ParseEmitOp( idLexer &src, int a, expOpType_t opType, int priority ); - int ParseTerm( idLexer &src ); - int ParseExpressionPriority( idLexer &src, int priority ); - int ParseExpression( idLexer &src ); - void ClearStage( shaderStage_t *ss ); - int NameToSrcBlendMode( const idStr &name ); - int NameToDstBlendMode( const idStr &name ); - void MultiplyTextureMatrix( textureStage_t *ts, int registers[2][3] ); // FIXME: for some reason the const is bad for gcc and Mac - void SortInteractionStages(); - void AddImplicitStages( const textureRepeat_t trpDefault = TR_REPEAT ); - void CheckForConstantRegisters(); - -private: - idStr desc; // description - idStr renderBump; // renderbump command options, without the "renderbump" at the start - - idImage * lightFalloffImage; - - int entityGui; // draw a gui with the idUserInterface from the renderEntity_t - // non zero will draw gui, gui2, or gui3 from renderEnitty_t - mutable idUserInterface *gui; // non-custom guis are shared by all users of a material - - bool noFog; // surface does not create fog interactions - - int spectrum; // for invisible writing, used for both lights and surfaces - - float polygonOffset; - - int contentFlags; // content flags - int surfaceFlags; // surface flags - mutable int materialFlags; // material flags - - decalInfo_t decalInfo; - - - mutable float sort; // lower numbered shaders draw before higher numbered - deform_t deform; - int deformRegisters[4]; // numeric parameter for deforms - const idDecl *deformDecl; // for surface emitted particle deforms and tables - - int texGenRegisters[MAX_TEXGEN_REGISTERS]; // for wobbleSky - - materialCoverage_t coverage; - cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED - bool shouldCreateBackSides; - - bool fogLight; - bool blendLight; - bool ambientLight; - bool unsmoothedTangents; - bool hasSubview; // mirror, remote render, etc - bool allowOverlays; - - int numOps; - expOp_t * ops; // evaluate to make expressionRegisters - - int numRegisters; // - float * expressionRegisters; - - float * constantRegisters; // NULL if ops ever reference globalParms or entityParms - - int numStages; - int numAmbientStages; - - shaderStage_t * stages; - - struct mtrParsingData_s *pd; // only used during parsing - - float surfaceArea; // only for listSurfaceAreas - - // we defer loading of the editor image until it is asked for, so the game doesn't load up - // all the invisible and uncompressed images. - // If editorImage is NULL, it will atempt to load editorImageName, and set editorImage to that or defaultImage - idStr editorImageName; - mutable idImage * editorImage; // image used for non-shaded preview - float editorAlpha; - - bool suppressInSubview; - bool portalSky; - int refCount; -}; - -typedef idList idMatList; - -#endif /* !__MATERIAL_H__ */ diff --git a/renderer/model.h b/renderer/model.h deleted file mode 100644 index f7837e868..000000000 --- a/renderer/model.h +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MODEL_H__ -#define __MODEL_H__ - -/* -=============================================================================== - - Render Model - -=============================================================================== -*/ - -// shared between the renderer, game, and Maya export DLL -#define MD5_VERSION_STRING "MD5Version" -#define MD5_MESH_EXT "md5mesh" -#define MD5_ANIM_EXT "md5anim" -#define MD5_CAMERA_EXT "md5camera" -#define MD5_VERSION 10 - -// using shorts for triangle indexes can save a significant amount of traffic, but -// to support the large models that renderBump loads, they need to be 32 bits -#if 1 - -#define GL_INDEX_TYPE GL_UNSIGNED_INT -typedef int glIndex_t; - -#else - -#define GL_INDEX_TYPE GL_UNSIGNED_SHORT -typedef short glIndex_t; - -#endif - - -typedef struct { - // NOTE: making this a glIndex is dubious, as there can be 2x the faces as verts - glIndex_t p1, p2; // planes defining the edge - glIndex_t v1, v2; // verts defining the edge -} silEdge_t; - -// this is used for calculating unsmoothed normals and tangents for deformed models -typedef struct dominantTri_s { - glIndex_t v2, v3; - float normalizationScale[3]; -} dominantTri_t; - -typedef struct lightingCache_s { - idVec3 localLightVector; // this is the statically computed vector to the light - // in texture space for cards without vertex programs -} lightingCache_t; - -typedef struct shadowCache_s { - idVec4 xyz; // we use homogenous coordinate tricks -} shadowCache_t; - -const int SHADOW_CAP_INFINITE = 64; - -// our only drawing geometry type -typedef struct srfTriangles_s { - idBounds bounds; // for culling - - int ambientViewCount; // if == tr.viewCount, it is visible this view - - bool generateNormals; // create normals from geometry, instead of using explicit ones - bool tangentsCalculated; // set when the vertex tangents have been calculated - bool facePlanesCalculated; // set when the face planes have been calculated - bool perfectHull; // true if there aren't any dangling edges - bool deformedSurface; // if true, indexes, silIndexes, mirrorVerts, and silEdges are - // pointers into the original surface, and should not be freed - - int numVerts; // number of vertices - idDrawVert * verts; // vertices, allocated with special allocator - - int numIndexes; // for shadows, this has both front and rear end caps and silhouette planes - glIndex_t * indexes; // indexes, allocated with special allocator - - glIndex_t * silIndexes; // indexes changed to be the first vertex with same XYZ, ignoring normal and texcoords - - int numMirroredVerts; // this many verts at the end of the vert list are tangent mirrors - int * mirroredVerts; // tri->mirroredVerts[0] is the mirror of tri->numVerts - tri->numMirroredVerts + 0 - - int numDupVerts; // number of duplicate vertexes - int * dupVerts; // pairs of the number of the first vertex and the number of the duplicate vertex - - int numSilEdges; // number of silhouette edges - silEdge_t * silEdges; // silhouette edges - - idPlane * facePlanes; // [numIndexes/3] plane equations - - dominantTri_t * dominantTris; // [numVerts] for deformed surface fast tangent calculation - - int numShadowIndexesNoFrontCaps; // shadow volumes with front caps omitted - int numShadowIndexesNoCaps; // shadow volumes with the front and rear caps omitted - - int shadowCapPlaneBits; // bits 0-5 are set when that plane of the interacting light has triangles - // projected on it, which means that if the view is on the outside of that - // plane, we need to draw the rear caps of the shadow volume - // turboShadows will have SHADOW_CAP_INFINITE - - shadowCache_t * shadowVertexes; // these will be copied to shadowCache when it is going to be drawn. - // these are NULL when vertex programs are available - - struct srfTriangles_s * ambientSurface; // for light interactions, point back at the original surface that generated - // the interaction, which we will get the ambientCache from - - struct srfTriangles_s * nextDeferredFree; // chain of tris to free next frame - - // data in vertex object space, not directly readable by the CPU - struct vertCache_s * indexCache; // int - struct vertCache_s * ambientCache; // idDrawVert - struct vertCache_s * lightingCache; // lightingCache_t - struct vertCache_s * shadowCache; // shadowCache_t -} srfTriangles_t; - -typedef idList idTriList; - -class idMaterial; - -typedef struct modelSurface_s { - int id; - const idMaterial * shader; - srfTriangles_t * geometry; -} modelSurface_t; - -typedef enum { - DM_STATIC, // never creates a dynamic model - DM_CACHED, // once created, stays constant until the entity is updated (animating characters) - DM_CONTINUOUS // must be recreated for every single view (time dependent things like particles) -} dynamicModel_t; - -typedef enum { - INVALID_JOINT = -1 -} jointHandle_t; - -class idMD5Joint { -public: - idMD5Joint() { parent = NULL; } - idStr name; - const idMD5Joint * parent; -}; - - -// the init methods may be called again on an already created model when -// a reloadModels is issued - -class idRenderModel { -public: - virtual ~idRenderModel() {}; - - // Loads static models only, dynamic models must be loaded by the modelManager - virtual void InitFromFile( const char *fileName ) = 0; - - // renderBump uses this to load the very high poly count models, skipping the - // shadow and tangent generation, along with some surface cleanup to make it load faster - virtual void PartialInitFromFile( const char *fileName ) = 0; - - // this is used for dynamically created surfaces, which are assumed to not be reloadable. - // It can be called again to clear out the surfaces of a dynamic model for regeneration. - virtual void InitEmpty( const char *name ) = 0; - - // dynamic model instantiations will be created with this - // the geometry data will be owned by the model, and freed when it is freed - // the geoemtry should be raw triangles, with no extra processing - virtual void AddSurface( modelSurface_t surface ) = 0; - - // cleans all the geometry and performs cross-surface processing - // like shadow hulls - // Creates the duplicated back side geometry for two sided, alpha tested, lit materials - // This does not need to be called if none of the surfaces added with AddSurface require - // light interaction, and all the triangles are already well formed. - virtual void FinishSurfaces() = 0; - - // frees all the data, but leaves the class around for dangling references, - // which can regenerate the data with LoadModel() - virtual void PurgeModel() = 0; - - // resets any model information that needs to be reset on a same level load etc.. - // currently only implemented for liquids - virtual void Reset() = 0; - - // used for initial loads, reloadModel, and reloading the data of purged models - // Upon exit, the model will absolutely be valid, but possibly as a default model - virtual void LoadModel() = 0; - - // internal use - virtual bool IsLoaded() = 0; - virtual void SetLevelLoadReferenced( bool referenced ) = 0; - virtual bool IsLevelLoadReferenced() = 0; - - // models that are already loaded at level start time - // will still touch their data to make sure they - // are kept loaded - virtual void TouchData() = 0; - - // dump any ambient caches on the model surfaces - virtual void FreeVertexCache() = 0; - - // returns the name of the model - virtual const char * Name() const = 0; - - // prints a detailed report on the model for printModel - virtual void Print() const = 0; - - // prints a single line report for listModels - virtual void List() const = 0; - - // reports the amount of memory (roughly) consumed by the model - virtual int Memory() const = 0; - - // for reloadModels - virtual unsigned int Timestamp() const = 0; - - // returns the number of surfaces - virtual int NumSurfaces() const = 0; - - // NumBaseSurfaces will not count any overlays added to dynamic models - virtual int NumBaseSurfaces() const = 0; - - // get a pointer to a surface - virtual const modelSurface_t *Surface( int surfaceNum ) const = 0; - - // Allocates surface triangles. - // Allocates memory for srfTriangles_t::verts and srfTriangles_t::indexes - // The allocated memory is not initialized. - // srfTriangles_t::numVerts and srfTriangles_t::numIndexes are set to zero. - virtual srfTriangles_t * AllocSurfaceTriangles( int numVerts, int numIndexes ) const = 0; - - // Frees surfaces triangles. - virtual void FreeSurfaceTriangles( srfTriangles_t *tris ) const = 0; - - // created at load time by stitching together all surfaces and sharing - // the maximum number of edges. This may be incorrect if a skin file - // remaps surfaces between shadow casting and non-shadow casting, or - // if some surfaces are noSelfShadow and others aren't - virtual srfTriangles_t * ShadowHull() const = 0; - - // models of the form "_area*" may have a prelight shadow model associated with it - virtual bool IsStaticWorldModel() const = 0; - - // models parsed from inside map files or dynamically created cannot be reloaded by - // reloadmodels - virtual bool IsReloadable() const = 0; - - // md3, md5, particles, etc - virtual dynamicModel_t IsDynamicModel() const = 0; - - // if the load failed for any reason, this will return true - virtual bool IsDefaultModel() const = 0; - - // dynamic models should return a fast, conservative approximation - // static models should usually return the exact value - virtual idBounds Bounds( const struct renderEntity_s *ent = NULL ) const = 0; - - // returns value != 0.0f if the model requires the depth hack - virtual float DepthHack() const = 0; - - // returns a static model based on the definition and view - // currently, this will be regenerated for every view, even though - // some models, like character meshes, could be used for multiple (mirror) - // views in a frame, or may stay static for multiple frames (corpses) - // The renderer will delete the returned dynamic model the next view - // This isn't const, because it may need to reload a purged model if it - // wasn't precached correctly. - virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) = 0; - - // Returns the number of joints or 0 if the model is not an MD5 - virtual int NumJoints( void ) const = 0; - - // Returns the MD5 joints or NULL if the model is not an MD5 - virtual const idMD5Joint * GetJoints( void ) const = 0; - - // Returns the handle for the joint with the given name. - virtual jointHandle_t GetJointHandle( const char *name ) const = 0; - - // Returns the name for the joint with the given handle. - virtual const char * GetJointName( jointHandle_t handle ) const = 0; - - // Returns the default animation pose or NULL if the model is not an MD5. - virtual const idJointQuat * GetDefaultPose( void ) const = 0; - - // Returns number of the joint nearest to the given triangle. - virtual int NearestJoint( int surfaceNum, int a, int c, int b ) const = 0; - - // Writing to and reading from a demo file. - virtual void ReadFromDemoFile( class idDemoFile *f ) = 0; - virtual void WriteToDemoFile( class idDemoFile *f ) = 0; -}; - -#endif /* !__MODEL_H__ */ diff --git a/renderer/modelmanager.h b/renderer/modelmanager.h deleted file mode 100644 index 29bf65432..000000000 --- a/renderer/modelmanager.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __MODELMANAGER_H__ -#define __MODELMANAGER_H__ - -/* -=============================================================================== - - Model Manager - - Temporarily created models do not need to be added to the model manager. - -=============================================================================== -*/ - -class idRenderModelManager { -public: - virtual ~idRenderModelManager() {} - - // registers console commands and clears the list - virtual void Init() = 0; - - // frees all the models - virtual void Shutdown() = 0; - - // called only by renderer::BeginLevelLoad - virtual void BeginLevelLoad() = 0; - - // called only by renderer::EndLevelLoad - virtual void EndLevelLoad() = 0; - - // allocates a new empty render model. - virtual idRenderModel * AllocModel() = 0; - - // frees a render model - virtual void FreeModel( idRenderModel *model ) = 0; - - // returns NULL if modelName is NULL or an empty string, otherwise - // it will create a default model if not loadable - virtual idRenderModel * FindModel( const char *modelName ) = 0; - - // returns NULL if not loadable - virtual idRenderModel * CheckModel( const char *modelName ) = 0; - - // returns the default cube model - virtual idRenderModel * DefaultModel() = 0; - - // world map parsing will add all the inline models with this call - virtual void AddModel( idRenderModel *model ) = 0; - - // when a world map unloads, it removes its internal models from the list - // before freeing them. - // There may be an issue with multiple renderWorlds that share data... - virtual void RemoveModel( idRenderModel *model ) = 0; - - // the reloadModels console command calls this, but it can - // also be explicitly invoked - virtual void ReloadModels( bool forceAll = false ) = 0; - - // write "touchModel " commands for each non-world-map model - virtual void WritePrecacheCommands( idFile *f ) = 0; - - // called during vid_restart - virtual void FreeModelVertexCaches() = 0; - - // print memory info - virtual void PrintMemInfo( MemInfo_t *mi ) = 0; -}; - -// this will be statically pointed at a private implementation -extern idRenderModelManager *renderModelManager; - -#endif /* !__MODELMANAGER_H__ */ diff --git a/renderer/qgl.h b/renderer/qgl.h index d173c0463..fdfdbf6b0 100644 --- a/renderer/qgl.h +++ b/renderer/qgl.h @@ -1,5 +1,21 @@ -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /* ** QGL.H */ diff --git a/renderer/qgl_linked.h b/renderer/qgl_linked.h index 2d72aa445..7a036c0b1 100644 --- a/renderer/qgl_linked.h +++ b/renderer/qgl_linked.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #define qglAccum glAccum #define qglAlphaFunc glAlphaFunc diff --git a/renderer/rendersystem.h b/renderer/rendersystem.h deleted file mode 100644 index b5f24be84..000000000 --- a/renderer/rendersystem.h +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __RENDERER_H__ -#define __RENDERER_H__ - -/* -=============================================================================== - - idRenderSystem is responsible for managing the screen, which can have - multiple idRenderWorld and 2D drawing done on it. - -=============================================================================== -*/ - - -// Contains variables specific to the OpenGL configuration being run right now. -// These are constant once the OpenGL subsystem is initialized. -typedef struct glconfig_s { - const char *renderer_string; - const char *vendor_string; - const char *version_string; - const char *extensions_string; - const char *wgl_extensions_string; - - float glVersion; // atof( version_string ) - - - int maxTextureSize; // queried from GL - int maxTextureUnits; - int maxTextureCoords; - int maxTextureImageUnits; - float maxTextureAnisotropy; - - int colorBits, depthBits, stencilBits; - - bool multitextureAvailable; - bool textureCompressionAvailable; - bool anisotropicAvailable; - bool textureLODBiasAvailable; - bool textureEnvAddAvailable; - bool textureEnvCombineAvailable; - bool registerCombinersAvailable; - bool cubeMapAvailable; - bool envDot3Available; - bool texture3DAvailable; - bool sharedTexturePaletteAvailable; - bool ARBVertexBufferObjectAvailable; - bool ARBVertexProgramAvailable; - bool ARBFragmentProgramAvailable; - bool twoSidedStencilAvailable; - bool textureNonPowerOfTwoAvailable; - bool depthBoundsTestAvailable; - - // ati r200 extensions - bool atiFragmentShaderAvailable; - - // ati r300 - bool atiTwoSidedStencilAvailable; - - int vidWidth, vidHeight; // passed to R_BeginFrame - - int displayFrequency; - - bool isFullscreen; - - bool allowNV30Path; - bool allowNV20Path; - bool allowNV10Path; - bool allowR200Path; - bool allowARB2Path; - - bool isInitialized; -} glconfig_t; - - -// font support -const int GLYPH_START = 0; -const int GLYPH_END = 255; -const int GLYPH_CHARSTART = 32; -const int GLYPH_CHAREND = 127; -const int GLYPHS_PER_FONT = GLYPH_END - GLYPH_START + 1; - -typedef struct { - int height; // number of scan lines - int top; // top of glyph in buffer - int bottom; // bottom of glyph in buffer - int pitch; // width for copying - int xSkip; // x adjustment - int imageWidth; // width of actual image - int imageHeight; // height of actual image - float s; // x offset in image where glyph starts - float t; // y offset in image where glyph starts - float s2; - float t2; - const idMaterial * glyph; // shader with the glyph - char shaderName[32]; -} glyphInfo_t; - -typedef struct { - glyphInfo_t glyphs [GLYPHS_PER_FONT]; - float glyphScale; - char name[64]; -} fontInfo_t; - -typedef struct { - fontInfo_t fontInfoSmall; - fontInfo_t fontInfoMedium; - fontInfo_t fontInfoLarge; - int maxHeight; - int maxWidth; - int maxHeightSmall; - int maxWidthSmall; - int maxHeightMedium; - int maxWidthMedium; - int maxHeightLarge; - int maxWidthLarge; - char name[64]; -} fontInfoEx_t; - -const int SMALLCHAR_WIDTH = 8; -const int SMALLCHAR_HEIGHT = 16; -const int BIGCHAR_WIDTH = 16; -const int BIGCHAR_HEIGHT = 16; - -// all drawing is done to a 640 x 480 virtual screen size -// and will be automatically scaled to the real resolution -const int SCREEN_WIDTH = 640; -const int SCREEN_HEIGHT = 480; - -class idRenderWorld; - - -class idRenderSystem { -public: - - virtual ~idRenderSystem() {} - - // set up cvars and basic data structures, but don't - // init OpenGL, so it can also be used for dedicated servers - virtual void Init( void ) = 0; - - // only called before quitting - virtual void Shutdown( void ) = 0; - - virtual void InitOpenGL( void ) = 0; - - virtual void ShutdownOpenGL( void ) = 0; - - virtual bool IsOpenGLRunning( void ) const = 0; - - virtual bool IsFullScreen( void ) const = 0; - virtual int GetScreenWidth( void ) const = 0; - virtual int GetScreenHeight( void ) const = 0; - - // allocate a renderWorld to be used for drawing - virtual idRenderWorld * AllocRenderWorld( void ) = 0; - virtual void FreeRenderWorld( idRenderWorld * rw ) = 0; - - // All data that will be used in a level should be - // registered before rendering any frames to prevent disk hits, - // but they can still be registered at a later time - // if necessary. - virtual void BeginLevelLoad( void ) = 0; - virtual void EndLevelLoad( void ) = 0; - - // font support - virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ) = 0; - - // GUI drawing just involves shader parameter setting and axial image subsections - virtual void SetColor( const idVec4 &rgba ) = 0; - virtual void SetColor4( float r, float g, float b, float a ) = 0; - - virtual void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, - bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f ) = 0; - virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) = 0; - - virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) = 0; - virtual void GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ) = 0; - virtual void GetGLSettings( int& width, int& height ) = 0; - virtual void PrintMemInfo( MemInfo_t *mi ) = 0; - - virtual void DrawSmallChar( int x, int y, int ch, const idMaterial *material ) = 0; - virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0; - virtual void DrawBigChar( int x, int y, int ch, const idMaterial *material ) = 0; - virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0; - - // dump all 2D drawing so far this frame to the demo file - virtual void WriteDemoPics() = 0; - - // draw the 2D pics that were saved out with the current demo frame - virtual void DrawDemoPics() = 0; - - // FIXME: add an interface for arbitrary point/texcoord drawing - - - // a frame cam consist of 2D drawing and potentially multiple 3D scenes - // window sizes are needed to convert SCREEN_WIDTH / SCREEN_HEIGHT values - virtual void BeginFrame( int windowWidth, int windowHeight ) = 0; - - // if the pointers are not NULL, timing info will be returned - virtual void EndFrame( int *frontEndMsec, int *backEndMsec ) = 0; - - // aviDemo uses this. - // Will automatically tile render large screen shots if necessary - // Samples is the number of jittered frames for anti-aliasing - // If ref == NULL, session->updateScreen will be used - // This will perform swapbuffers, so it is NOT an approppriate way to - // generate image files that happen during gameplay, as for savegame - // markers. Use WriteRender() instead. - virtual void TakeScreenshot( int width, int height, const char *fileName, int samples, struct renderView_s *ref ) = 0; - - // the render output can be cropped down to a subset of the real screen, as - // for save-game reviews and split-screen multiplayer. Users of the renderer - // will not know the actual pixel size of the area they are rendering to - - // the x,y,width,height values are in virtual SCREEN_WIDTH / SCREEN_HEIGHT coordinates - - // to render to a texture, first set the crop size with makePowerOfTwo = true, - // then perform all desired rendering, then capture to an image - // if the specified physical dimensions are larger than the current cropped region, they will be cut down to fit - virtual void CropRenderSize( int width, int height, bool makePowerOfTwo = false, bool forceDimensions = false ) = 0; - virtual void CaptureRenderToImage( const char *imageName ) = 0; - // fixAlpha will set all the alpha channel values to 0xff, which allows screen captures - // to use the default tga loading code without having dimmed down areas in many places - virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha = false ) = 0; - virtual void UnCrop() = 0; - virtual void GetCardCaps( bool &oldCard, bool &nv10or20 ) = 0; - - // the image has to be already loaded ( most straightforward way would be through a FindMaterial ) - // texture filter / mipmapping / repeat won't be modified by the upload - // returns false if the image wasn't found - virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ) = 0; -}; - -extern idRenderSystem * renderSystem; - -// -// functions mainly intended for editor and dmap integration -// - -// returns the frustum planes in world space -void R_RenderLightFrustum( const struct renderLight_s &renderLight, idPlane lightFrustum[6] ); - -// for use by dmap to do the carving-on-light-boundaries and for the editor for display -void R_LightProjectionMatrix( const idVec3 &origin, const idPlane &rearPlane, idVec4 mat[4] ); - -// used by the view shot taker -void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ); - -void PrintMessage( int x, int y, const char *szMessage, idVec4 colour, fontInfoEx_t &font ); -#endif /* !__RENDERER_H__ */ diff --git a/renderer/renderworld.h b/renderer/renderworld.h deleted file mode 100644 index 64769c4fc..000000000 --- a/renderer/renderworld.h +++ /dev/null @@ -1,410 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __RENDERWORLD_H__ -#define __RENDERWORLD_H__ - -#include "material.h" - -/* -=============================================================================== - - Render World - -=============================================================================== -*/ - -#define PROC_FILE_EXT "proc" -#define PROC_FILE_ID "mapProcFile003" - -// shader parms -const int MAX_GLOBAL_SHADER_PARMS = 12; - -const int SHADERPARM_RED = 0; -const int SHADERPARM_GREEN = 1; -const int SHADERPARM_BLUE = 2; -const int SHADERPARM_ALPHA = 3; -const int SHADERPARM_TIMESCALE = 3; -const int SHADERPARM_TIMEOFFSET = 4; -const int SHADERPARM_DIVERSITY = 5; // random between 0.0 and 1.0 for some effects (muzzle flashes, etc) -const int SHADERPARM_MODE = 7; // for selecting which shader passes to enable -const int SHADERPARM_TIME_OF_DEATH = 7; // for the monster skin-burn-away effect enable and time offset - -// model parms -const int SHADERPARM_MD5_SKINSCALE = 8; // for scaling vertex offsets on md5 models (jack skellington effect) - -const int SHADERPARM_MD3_FRAME = 8; -const int SHADERPARM_MD3_LASTFRAME = 9; -const int SHADERPARM_MD3_BACKLERP = 10; - -const int SHADERPARM_BEAM_END_X = 8; // for _beam models -const int SHADERPARM_BEAM_END_Y = 9; -const int SHADERPARM_BEAM_END_Z = 10; -const int SHADERPARM_BEAM_WIDTH = 11; - -const int SHADERPARM_SPRITE_WIDTH = 8; -const int SHADERPARM_SPRITE_HEIGHT = 9; - -const int SHADERPARM_PARTICLE_STOPTIME = 8; // don't spawn any more particles after this time - -// guis -const int MAX_RENDERENTITY_GUI = 3; - - -typedef bool(*deferredEntityCallback_t)( renderEntity_s *, const renderView_s * ); - - -typedef struct renderEntity_s { - idRenderModel * hModel; // this can only be null if callback is set - - int entityNum; - int bodyId; - - // Entities that are expensive to generate, like skeletal models, can be - // deferred until their bounds are found to be in view, in the frustum - // of a shadowing light that is in view, or contacted by a trace / overlay test. - // This is also used to do visual cueing on items in the view - // The renderView may be NULL if the callback is being issued for a non-view related - // source. - // The callback function should clear renderEntity->callback if it doesn't - // want to be called again next time the entity is referenced (ie, if the - // callback has now made the entity valid until the next updateEntity) - idBounds bounds; // only needs to be set for deferred models and md5s - deferredEntityCallback_t callback; - - void * callbackData; // used for whatever the callback wants - - // player bodies and possibly player shadows should be suppressed in views from - // that player's eyes, but will show up in mirrors and other subviews - // security cameras could suppress their model in their subviews if we add a way - // of specifying a view number for a remoteRenderMap view - int suppressSurfaceInViewID; - int suppressShadowInViewID; - - // world models for the player and weapons will not cast shadows from view weapon - // muzzle flashes - int suppressShadowInLightID; - - // if non-zero, the surface and shadow (if it casts one) - // will only show up in the specific view, ie: player weapons - int allowSurfaceInViewID; - - // positioning - // axis rotation vectors must be unit length for many - // R_LocalToGlobal functions to work, so don't scale models! - // axis vectors are [0] = forward, [1] = left, [2] = up - idVec3 origin; - idMat3 axis; - - // texturing - const idMaterial * customShader; // if non-0, all surfaces will use this - const idMaterial * referenceShader; // used so flares can reference the proper light shader - const idDeclSkin * customSkin; // 0 for no remappings - class idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds - float shaderParms[ MAX_ENTITY_SHADER_PARMS ]; // can be used in any way by shader or model generation - - // networking: see WriteGUIToSnapshot / ReadGUIFromSnapshot - class idUserInterface * gui[ MAX_RENDERENTITY_GUI ]; - - struct renderView_s * remoteRenderView; // any remote camera surfaces will use this - - int numJoints; - idJointMat * joints; // array of joints that will modify vertices. - // NULL if non-deformable model. NOT freed by renderer - - float modelDepthHack; // squash depth range so particle effects don't clip into walls - - // options to override surface shader flags (replace with material parameters?) - bool noSelfShadow; // cast shadows onto other objects,but not self - bool noShadow; // no shadow at all - - bool noDynamicInteractions; // don't create any light / shadow interactions after - // the level load is completed. This is a performance hack - // for the gigantic outdoor meshes in the monorail map, so - // all the lights in the moving monorail don't touch the meshes - - bool weaponDepthHack; // squash depth range so view weapons don't poke into walls - // this automatically implies noShadow - int forceUpdate; // force an update (NOTE: not a bool to keep this struct a multiple of 4 bytes) - int timeGroup; - int xrayIndex; -} renderEntity_t; - - -typedef struct renderLight_s { - idMat3 axis; // rotation vectors, must be unit length - idVec3 origin; - - // if non-zero, the light will not show up in the specific view, - // which may be used if we want to have slightly different muzzle - // flash lights for the player and other views - int suppressLightInViewID; - - // if non-zero, the light will only show up in the specific view - // which can allow player gun gui lights and such to not effect everyone - int allowLightInViewID; - - // I am sticking the four bools together so there are no unused gaps in - // the padded structure, which could confuse the memcmp that checks for redundant - // updates - bool noShadows; // (should we replace this with material parameters on the shader?) - bool noSpecular; // (should we replace this with material parameters on the shader?) - - bool pointLight; // otherwise a projection light (should probably invert the sense of this, because points are way more common) - bool parallel; // lightCenter gives the direction to the light at infinity - idVec3 lightRadius; // xyz radius for point lights - idVec3 lightCenter; // offset the lighting direction for shading and - // shadows, relative to origin - - // frustum definition for projected lights, all reletive to origin - // FIXME: we should probably have real plane equations here, and offer - // a helper function for conversion from this format - idVec3 target; - idVec3 right; - idVec3 up; - idVec3 start; - idVec3 end; - - // Dmap will generate an optimized shadow volume named _prelight_ - // for the light against all the _area* models in the map. The renderer will - // ignore this value if the light has been moved after initial creation - idRenderModel * prelightModel; - - // muzzle flash lights will not cast shadows from player and weapon world models - int lightId; - - - const idMaterial * shader; // NULL = either lights/defaultPointLight or lights/defaultProjectedLight - float shaderParms[MAX_ENTITY_SHADER_PARMS]; // can be used in any way by shader - idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds -} renderLight_t; - - -typedef struct renderView_s { - // player views will set this to a non-zero integer for model suppress / allow - // subviews (mirrors, cameras, etc) will always clear it to zero - int viewID; - - // sized from 0 to SCREEN_WIDTH / SCREEN_HEIGHT (640/480), not actual resolution - int x, y, width, height; - - float fov_x, fov_y; - idVec3 vieworg; - idMat3 viewaxis; // transformation matrix, view looks down the positive X axis - - bool cramZNear; // for cinematics, we want to set ZNear much lower - bool forceUpdate; // for an update - - // time in milliseconds for shader effects and other time dependent rendering issues - int time; - float shaderParms[MAX_GLOBAL_SHADER_PARMS]; // can be used in any way by shader - const idMaterial *globalMaterial; // used to override everything draw -} renderView_t; - - -// exitPortal_t is returned by idRenderWorld::GetPortal() -typedef struct { - int areas[2]; // areas connected by this portal - const idWinding * w; // winding points have counter clockwise ordering seen from areas[0] - int blockingBits; // PS_BLOCK_VIEW, PS_BLOCK_AIR, etc - qhandle_t portalHandle; -} exitPortal_t; - - -// guiPoint_t is returned by idRenderWorld::GuiTrace() -typedef struct { - float x, y; // 0.0 to 1.0 range if trace hit a gui, otherwise -1 - int guiId; // id of gui ( 0, 1, or 2 ) that the trace happened against -} guiPoint_t; - - -// modelTrace_t is for tracing vs. visual geometry -typedef struct modelTrace_s { - float fraction; // fraction of trace completed - idVec3 point; // end point of trace in global space - idVec3 normal; // hit triangle normal vector in global space - const idMaterial * material; // material of hit surface - const renderEntity_t * entity; // render entity that was hit - int jointNumber; // md5 joint nearest to the hit triangle -} modelTrace_t; - - -static const int NUM_PORTAL_ATTRIBUTES = 3; - -typedef enum { - PS_BLOCK_NONE = 0, - - PS_BLOCK_VIEW = 1, - PS_BLOCK_LOCATION = 2, // game map location strings often stop in hallways - PS_BLOCK_AIR = 4, // windows between pressurized and unpresurized areas - - PS_BLOCK_ALL = (1<= 0 ; i-- ) { + GL_SelectTexture( i ); + + // object linear texgen is our default + qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + + GL_TexEnv( GL_MODULATE ); + qglDisable( GL_TEXTURE_2D ); + if ( glConfig.texture3DAvailable ) { + qglDisable( GL_TEXTURE_3D ); + } + if ( glConfig.cubeMapAvailable ) { + qglDisable( GL_TEXTURE_CUBE_MAP_EXT ); + } + } +} + + +/* +==================== +RB_LogComment +==================== +*/ +void RB_LogComment( const char *comment, ... ) { + va_list marker; + + if ( !tr.logFile ) { + return; + } + + fprintf( tr.logFile, "// " ); + va_start( marker, comment ); + vfprintf( tr.logFile, comment, marker ); + va_end( marker ); +} + + +//============================================================================= + + + +/* +==================== +GL_SelectTexture +==================== +*/ +void GL_SelectTexture( int unit ) { + if ( backEnd.glState.currenttmu == unit ) { + return; + } + + if ( unit < 0 || unit >= glConfig.maxTextureUnits && unit >= glConfig.maxTextureImageUnits ) { + common->Warning( "GL_SelectTexture: unit = %i", unit ); + return; + } + + qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); + qglClientActiveTextureARB( GL_TEXTURE0_ARB + unit ); + RB_LogComment( "glActiveTextureARB( %i );\nglClientActiveTextureARB( %i );\n", unit, unit ); + + backEnd.glState.currenttmu = unit; +} + + +/* +==================== +GL_Cull + +This handles the flipping needed when the view being +rendered is a mirored view. +==================== +*/ +void GL_Cull( int cullType ) { + if ( backEnd.glState.faceCulling == cullType ) { + return; + } + + if ( cullType == CT_TWO_SIDED ) { + qglDisable( GL_CULL_FACE ); + } else { + if ( backEnd.glState.faceCulling == CT_TWO_SIDED ) { + qglEnable( GL_CULL_FACE ); + } + + if ( cullType == CT_BACK_SIDED ) { + if ( backEnd.viewDef->isMirror ) { + qglCullFace( GL_FRONT ); + } else { + qglCullFace( GL_BACK ); + } + } else { + if ( backEnd.viewDef->isMirror ) { + qglCullFace( GL_BACK ); + } else { + qglCullFace( GL_FRONT ); + } + } + } + + backEnd.glState.faceCulling = cullType; +} + +/* +==================== +GL_TexEnv +==================== +*/ +void GL_TexEnv( int env ) { + tmu_t *tmu; + + tmu = &backEnd.glState.tmu[backEnd.glState.currenttmu]; + if ( env == tmu->texEnv ) { + return; + } + + tmu->texEnv = env; + + switch ( env ) { + case GL_COMBINE_EXT: + case GL_MODULATE: + case GL_REPLACE: + case GL_DECAL: + case GL_ADD: + qglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env ); + break; + default: + common->Error( "GL_TexEnv: invalid env '%d' passed\n", env ); + break; + } +} + +/* +================= +GL_ClearStateDelta + +Clears the state delta bits, so the next GL_State +will set every item +================= +*/ +void GL_ClearStateDelta( void ) { + backEnd.glState.forceGlState = true; +} + +/* +==================== +GL_State + +This routine is responsible for setting the most commonly changed state +==================== +*/ +void GL_State( int stateBits ) { + int diff; + + if ( !r_useStateCaching.GetBool() || backEnd.glState.forceGlState ) { + // make sure everything is set all the time, so we + // can see if our delta checking is screwing up + diff = -1; + backEnd.glState.forceGlState = false; + } else { + diff = stateBits ^ backEnd.glState.glStateBits; + if ( !diff ) { + return; + } + } + + // + // check depthFunc bits + // + if ( diff & ( GLS_DEPTHFUNC_EQUAL | GLS_DEPTHFUNC_LESS | GLS_DEPTHFUNC_ALWAYS ) ) { + if ( stateBits & GLS_DEPTHFUNC_EQUAL ) { + qglDepthFunc( GL_EQUAL ); + } else if ( stateBits & GLS_DEPTHFUNC_ALWAYS ) { + qglDepthFunc( GL_ALWAYS ); + } else { + qglDepthFunc( GL_LEQUAL ); + } + } + + + // + // check blend bits + // + if ( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) { + GLenum srcFactor, dstFactor; + + switch ( stateBits & GLS_SRCBLEND_BITS ) { + case GLS_SRCBLEND_ZERO: + srcFactor = GL_ZERO; + break; + case GLS_SRCBLEND_ONE: + srcFactor = GL_ONE; + break; + case GLS_SRCBLEND_DST_COLOR: + srcFactor = GL_DST_COLOR; + break; + case GLS_SRCBLEND_ONE_MINUS_DST_COLOR: + srcFactor = GL_ONE_MINUS_DST_COLOR; + break; + case GLS_SRCBLEND_SRC_ALPHA: + srcFactor = GL_SRC_ALPHA; + break; + case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA: + srcFactor = GL_ONE_MINUS_SRC_ALPHA; + break; + case GLS_SRCBLEND_DST_ALPHA: + srcFactor = GL_DST_ALPHA; + break; + case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA: + srcFactor = GL_ONE_MINUS_DST_ALPHA; + break; + case GLS_SRCBLEND_ALPHA_SATURATE: + srcFactor = GL_SRC_ALPHA_SATURATE; + break; + default: + srcFactor = GL_ONE; // to get warning to shut up + common->Error( "GL_State: invalid src blend state bits\n" ); + break; + } + + switch ( stateBits & GLS_DSTBLEND_BITS ) { + case GLS_DSTBLEND_ZERO: + dstFactor = GL_ZERO; + break; + case GLS_DSTBLEND_ONE: + dstFactor = GL_ONE; + break; + case GLS_DSTBLEND_SRC_COLOR: + dstFactor = GL_SRC_COLOR; + break; + case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR: + dstFactor = GL_ONE_MINUS_SRC_COLOR; + break; + case GLS_DSTBLEND_SRC_ALPHA: + dstFactor = GL_SRC_ALPHA; + break; + case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA: + dstFactor = GL_ONE_MINUS_SRC_ALPHA; + break; + case GLS_DSTBLEND_DST_ALPHA: + dstFactor = GL_DST_ALPHA; + break; + case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA: + dstFactor = GL_ONE_MINUS_DST_ALPHA; + break; + default: + dstFactor = GL_ONE; // to get warning to shut up + common->Error( "GL_State: invalid dst blend state bits\n" ); + break; + } + + qglBlendFunc( srcFactor, dstFactor ); + } + + // + // check depthmask + // + if ( diff & GLS_DEPTHMASK ) { + if ( stateBits & GLS_DEPTHMASK ) { + qglDepthMask( GL_FALSE ); + } else { + qglDepthMask( GL_TRUE ); + } + } + + // + // check colormask + // + if ( diff & (GLS_REDMASK|GLS_GREENMASK|GLS_BLUEMASK|GLS_ALPHAMASK) ) { + GLboolean r, g, b, a; + r = ( stateBits & GLS_REDMASK ) ? 0 : 1; + g = ( stateBits & GLS_GREENMASK ) ? 0 : 1; + b = ( stateBits & GLS_BLUEMASK ) ? 0 : 1; + a = ( stateBits & GLS_ALPHAMASK ) ? 0 : 1; + qglColorMask( r, g, b, a ); + } + + // + // fill/line mode + // + if ( diff & GLS_POLYMODE_LINE ) { + if ( stateBits & GLS_POLYMODE_LINE ) { + qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } else { + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } + + // + // alpha test + // + if ( diff & GLS_ATEST_BITS ) { + switch ( stateBits & GLS_ATEST_BITS ) { + case 0: + qglDisable( GL_ALPHA_TEST ); + break; + case GLS_ATEST_EQ_255: + qglEnable( GL_ALPHA_TEST ); + qglAlphaFunc( GL_EQUAL, 1 ); + break; + case GLS_ATEST_LT_128: + qglEnable( GL_ALPHA_TEST ); + qglAlphaFunc( GL_LESS, 0.5 ); + break; + case GLS_ATEST_GE_128: + qglEnable( GL_ALPHA_TEST ); + qglAlphaFunc( GL_GEQUAL, 0.5 ); + break; + default: + assert( 0 ); + break; + } + } + + backEnd.glState.glStateBits = stateBits; +} + + + + +/* +============================================================================ + +RENDER BACK END THREAD FUNCTIONS + +============================================================================ +*/ + +/* +============= +RB_SetGL2D + +This is not used by the normal game paths, just by some tools +============= +*/ +void RB_SetGL2D( void ) { + // set 2D virtual screen size + qglViewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); + if ( r_useScissor.GetBool() ) { + qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); + } + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + qglOrtho( 0, 640, 480, 0, 0, 1 ); // always assume 640x480 virtual coordinates + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + GL_State( GLS_DEPTHFUNC_ALWAYS | + GLS_SRCBLEND_SRC_ALPHA | + GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + GL_Cull( CT_TWO_SIDED ); + + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_STENCIL_TEST ); +} + + + +/* +============= +RB_SetBuffer + +============= +*/ +static void RB_SetBuffer( const void *data ) { + const setBufferCommand_t *cmd; + + // see which draw buffer we want to render the frame to + + cmd = (const setBufferCommand_t *)data; + + backEnd.frameCount = cmd->frameCount; + + qglDrawBuffer( cmd->buffer ); + + // clear screen for debugging + // automatically enable this with several other debug tools + // that might leave unrendered portions of the screen + if ( r_clear.GetFloat() || idStr::Length( r_clear.GetString() ) != 1 || r_lockSurfaces.GetBool() || r_singleArea.GetBool() || r_showOverDraw.GetBool() ) { + float c[3]; + if ( sscanf( r_clear.GetString(), "%f %f %f", &c[0], &c[1], &c[2] ) == 3 ) { + qglClearColor( c[0], c[1], c[2], 1 ); + } else if ( r_clear.GetInteger() == 2 ) { + qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + } else if ( r_showOverDraw.GetBool() ) { + qglClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); + } else { + qglClearColor( 0.4f, 0.0f, 0.25f, 1.0f ); + } + qglClear( GL_COLOR_BUFFER_BIT ); + } +} + +/* +=============== +RB_ShowImages + +Draw all the images to the screen, on top of whatever +was there. This is used to test for texture thrashing. +=============== +*/ +void RB_ShowImages( void ) { + int i; + idImage *image; + float x, y, w, h; + int start, end; + + RB_SetGL2D(); + + //qglClearColor( 0.2, 0.2, 0.2, 1 ); + //qglClear( GL_COLOR_BUFFER_BIT ); + + qglFinish(); + + start = Sys_Milliseconds(); + + for ( i = 0 ; i < globalImages->images.Num() ; i++ ) { + image = globalImages->images[i]; + + if ( image->texnum == idImage::TEXTURE_NOT_LOADED && image->partialImage == NULL ) { + continue; + } + + w = glConfig.vidWidth / 20; + h = glConfig.vidHeight / 15; + x = i % 20 * w; + y = i / 20 * h; + + // show in proportional size in mode 2 + if ( r_showImages.GetInteger() == 2 ) { + w *= image->uploadWidth / 512.0f; + h *= image->uploadHeight / 512.0f; + } + + image->Bind(); + qglBegin (GL_QUADS); + qglTexCoord2f( 0, 0 ); + qglVertex2f( x, y ); + qglTexCoord2f( 1, 0 ); + qglVertex2f( x + w, y ); + qglTexCoord2f( 1, 1 ); + qglVertex2f( x + w, y + h ); + qglTexCoord2f( 0, 1 ); + qglVertex2f( x, y + h ); + qglEnd(); + } + + qglFinish(); + + end = Sys_Milliseconds(); + common->Printf( "%i msec to draw all images\n", end - start ); +} + + +/* +============= +RB_SwapBuffers + +============= +*/ +const void RB_SwapBuffers( const void *data ) { + // texture swapping test + if ( r_showImages.GetInteger() != 0 ) { + RB_ShowImages(); + } + + // force a gl sync if requested + if ( r_finish.GetBool() ) { + qglFinish(); + } + + RB_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); + + // don't flip if drawing to front buffer + if ( !r_frontBuffer.GetBool() ) { + GLimp_SwapBuffers(); + } +} + +/* +============= +RB_CopyRender + +Copy part of the current framebuffer to an image +============= +*/ +const void RB_CopyRender( const void *data ) { + const copyRenderCommand_t *cmd; + + cmd = (const copyRenderCommand_t *)data; + + if ( r_skipCopyTexture.GetBool() ) { + return; + } + + RB_LogComment( "***************** RB_CopyRender *****************\n" ); + + if (cmd->image) { + cmd->image->CopyFramebuffer( cmd->x, cmd->y, cmd->imageWidth, cmd->imageHeight, false ); + } +} + +/* +==================== +RB_ExecuteBackEndCommands + +This function will be called syncronously if running without +smp extensions, or asyncronously by another thread. +==================== +*/ +int backEndStartTime, backEndFinishTime; +void RB_ExecuteBackEndCommands( const emptyCommand_t *cmds ) { + // r_debugRenderToTexture + int c_draw3d = 0, c_draw2d = 0, c_setBuffers = 0, c_swapBuffers = 0, c_copyRenders = 0; + + if ( cmds->commandId == RC_NOP && !cmds->next ) { + return; + } + + backEndStartTime = Sys_Milliseconds(); + + // needed for editor rendering + RB_SetDefaultGLState(); + + // upload any image loads that have completed + globalImages->CompleteBackgroundImageLoads(); + + for ( ; cmds ; cmds = (const emptyCommand_t *)cmds->next ) { + switch ( cmds->commandId ) { + case RC_NOP: + break; + case RC_DRAW_VIEW: + RB_DrawView( cmds ); + if ( ((const drawSurfsCommand_t *)cmds)->viewDef->viewEntitys ) { + c_draw3d++; + } + else { + c_draw2d++; + } + break; + case RC_SET_BUFFER: + RB_SetBuffer( cmds ); + c_setBuffers++; + break; + case RC_SWAP_BUFFERS: + RB_SwapBuffers( cmds ); + c_swapBuffers++; + break; + case RC_COPY_RENDER: + RB_CopyRender( cmds ); + c_copyRenders++; + break; + default: + common->Error( "RB_ExecuteBackEndCommands: bad commandId" ); + break; + } + } + + // go back to the default texture so the editor doesn't mess up a bound image + qglBindTexture( GL_TEXTURE_2D, 0 ); + backEnd.glState.tmu[0].current2DMap = -1; + + // stop rendering on this thread + backEndFinishTime = Sys_Milliseconds(); + backEnd.pc.msec = backEndFinishTime - backEndStartTime; + + if ( r_debugRenderToTexture.GetInteger() == 1 ) { + common->Printf( "3d: %i, 2d: %i, SetBuf: %i, SwpBuf: %i, CpyRenders: %i, CpyFrameBuf: %i\n", c_draw3d, c_draw2d, c_setBuffers, c_swapBuffers, c_copyRenders, backEnd.c_copyFrameBuffer ); + backEnd.c_copyFrameBuffer = 0; + } +} diff --git a/renderer/tr_deform.cpp b/renderer/tr_deform.cpp new file mode 100644 index 000000000..c2225f8f3 --- /dev/null +++ b/renderer/tr_deform.cpp @@ -0,0 +1,1258 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +/* +================= +R_FinishDeform + +The ambientCache is on the stack, so we don't want to leave a reference +to it that would try to be freed later. Create the ambientCache immediately. +================= +*/ +static void R_FinishDeform( drawSurf_t *drawSurf, srfTriangles_t *newTri, idDrawVert *ac ) { + if ( !newTri ) { + return; + } + + // generate current normals, tangents, and bitangents + // We might want to support the possibility of deform functions generating + // explicit normals, and we might also want to allow the cached deformInfo + // optimization for these. + // FIXME: this doesn't work, because the deformed surface is just the + // ambient one, and there isn't an opportunity to generate light interactions + if ( drawSurf->material->ReceivesLighting() ) { + newTri->verts = ac; + R_DeriveTangents( newTri, false ); + newTri->verts = NULL; + } + + newTri->ambientCache = vertexCache.AllocFrameTemp( ac, newTri->numVerts * sizeof( idDrawVert ) ); + // if we are out of vertex cache, leave it the way it is + if ( newTri->ambientCache ) { + drawSurf->geo = newTri; + } +} + +/* +===================== +R_AutospriteDeform + +Assuming all the triangles for this shader are independant +quads, rebuild them as forward facing sprites +===================== +*/ +static void R_AutospriteDeform( drawSurf_t *surf ) { + int i; + const idDrawVert *v; + idVec3 mid, delta; + float radius; + idVec3 left, up; + idVec3 leftDir, upDir; + const srfTriangles_t *tri; + srfTriangles_t *newTri; + + tri = surf->geo; + + if ( tri->numVerts & 3 ) { + common->Warning( "R_AutospriteDeform: shader had odd vertex count" ); + return; + } + if ( tri->numIndexes != ( tri->numVerts >> 2 ) * 6 ) { + common->Warning( "R_AutospriteDeform: autosprite had odd index count" ); + return; + } + + R_GlobalVectorToLocal( surf->space->modelMatrix, tr.viewDef->renderView.viewaxis[1], leftDir ); + R_GlobalVectorToLocal( surf->space->modelMatrix, tr.viewDef->renderView.viewaxis[2], upDir ); + + if ( tr.viewDef->isMirror ) { + leftDir = vec3_origin - leftDir; + } + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + for ( i = 0 ; i < tri->numVerts ; i+=4 ) { + // find the midpoint + v = &tri->verts[i]; + + mid[0] = 0.25 * (v->xyz[0] + (v+1)->xyz[0] + (v+2)->xyz[0] + (v+3)->xyz[0]); + mid[1] = 0.25 * (v->xyz[1] + (v+1)->xyz[1] + (v+2)->xyz[1] + (v+3)->xyz[1]); + mid[2] = 0.25 * (v->xyz[2] + (v+1)->xyz[2] + (v+2)->xyz[2] + (v+3)->xyz[2]); + + delta = v->xyz - mid; + radius = delta.Length() * 0.707; // / sqrt(2) + + left = leftDir * radius; + up = upDir * radius; + + ac[i+0].xyz = mid + left + up; + ac[i+0].st[0] = 0; + ac[i+0].st[1] = 0; + ac[i+1].xyz = mid - left + up; + ac[i+1].st[0] = 1; + ac[i+1].st[1] = 0; + ac[i+2].xyz = mid - left - up; + ac[i+2].st[0] = 1; + ac[i+2].st[1] = 1; + ac[i+3].xyz = mid + left - up; + ac[i+3].st[0] = 0; + ac[i+3].st[1] = 1; + + newTri->indexes[6*(i>>2)+0] = i; + newTri->indexes[6*(i>>2)+1] = i+1; + newTri->indexes[6*(i>>2)+2] = i+2; + + newTri->indexes[6*(i>>2)+3] = i; + newTri->indexes[6*(i>>2)+4] = i+2; + newTri->indexes[6*(i>>2)+5] = i+3; + } + + R_FinishDeform( surf, newTri, ac ); +} + +/* +===================== +R_TubeDeform + +will pivot a rectangular quad along the center of its long axis + +Note that a geometric tube with even quite a few sides tube will almost certainly render much faster +than this, so this should only be for faked volumetric tubes. +Make sure this is used with twosided translucent shaders, because the exact side +order may not be correct. +===================== +*/ +static void R_TubeDeform( drawSurf_t *surf ) { + int i, j; + int indexes; + const srfTriangles_t *tri; +static int edgeVerts[6][2] = { + { 0, 1 }, + { 1, 2 }, + { 2, 0 }, + { 3, 4 }, + { 4, 5 }, + { 5, 3 } +}; + + tri = surf->geo; + + if ( tri->numVerts & 3 ) { + common->Error( "R_AutospriteDeform: shader had odd vertex count" ); + } + if ( tri->numIndexes != ( tri->numVerts >> 2 ) * 6 ) { + common->Error( "R_AutospriteDeform: autosprite had odd index count" ); + } + + // we need the view direction to project the minor axis of the tube + // as the view changes + idVec3 localView; + R_GlobalPointToLocal( surf->space->modelMatrix, tr.viewDef->renderView.vieworg, localView ); + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + srfTriangles_t *newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + memcpy( newTri->indexes, tri->indexes, newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + memset( ac, 0, sizeof( idDrawVert ) * newTri->numVerts ); + + // this is a lot of work for two triangles... + // we could precalculate a lot if it is an issue, but it would mess up + // the shader abstraction + for ( i = 0, indexes = 0 ; i < tri->numVerts ; i+=4, indexes+=6 ) { + float lengths[2]; + int nums[2]; + idVec3 mid[2]; + idVec3 major, minor; + const idDrawVert *v1, *v2; + + // identify the two shortest edges out of the six defined by the indexes + nums[0] = nums[1] = 0; + lengths[0] = lengths[1] = 999999; + + for ( j = 0 ; j < 6 ; j++ ) { + float l; + + v1 = &tri->verts[tri->indexes[i+edgeVerts[j][0]]]; + v2 = &tri->verts[tri->indexes[i+edgeVerts[j][1]]]; + + l = ( v1->xyz - v2->xyz ).Length(); + if ( l < lengths[0] ) { + nums[1] = nums[0]; + lengths[1] = lengths[0]; + nums[0] = j; + lengths[0] = l; + } else if ( l < lengths[1] ) { + nums[1] = j; + lengths[1] = l; + } + } + + // find the midpoints of the two short edges, which + // will give us the major axis in object coordinates + for ( j = 0 ; j < 2 ; j++ ) { + v1 = &tri->verts[tri->indexes[i+edgeVerts[nums[j]][0]]]; + v2 = &tri->verts[tri->indexes[i+edgeVerts[nums[j]][1]]]; + + mid[j][0] = 0.5 * (v1->xyz[0] + v2->xyz[0]); + mid[j][1] = 0.5 * (v1->xyz[1] + v2->xyz[1]); + mid[j][2] = 0.5 * (v1->xyz[2] + v2->xyz[2]); + } + + // find the vector of the major axis + major = mid[1] - mid[0]; + + // re-project the points + for ( j = 0 ; j < 2 ; j++ ) { + float l; + int i1 = tri->indexes[i+edgeVerts[nums[j]][0]]; + int i2 = tri->indexes[i+edgeVerts[nums[j]][1]]; + + idDrawVert *av1 = &ac[i1]; + idDrawVert *av2 = &ac[i2]; + + *av1 = *(idDrawVert *)&tri->verts[i1]; + *av2 = *(idDrawVert *)&tri->verts[i2]; + + l = 0.5 * lengths[j]; + + // cross this with the view direction to get minor axis + idVec3 dir = mid[j] - localView; + minor.Cross( major, dir ); + minor.Normalize(); + + if ( j ) { + av1->xyz = mid[j] - l * minor; + av2->xyz = mid[j] + l * minor; + } else { + av1->xyz = mid[j] + l * minor; + av2->xyz = mid[j] - l * minor; + } + } + } + + R_FinishDeform( surf, newTri, ac ); +} + +/* +===================== +R_WindingFromTriangles + +===================== +*/ +#define MAX_TRI_WINDING_INDEXES 16 +int R_WindingFromTriangles( const srfTriangles_t *tri, glIndex_t indexes[MAX_TRI_WINDING_INDEXES] ) { + int i, j, k, l; + + indexes[0] = tri->indexes[0]; + int numIndexes = 1; + int numTris = tri->numIndexes / 3; + + do { + // find an edge that goes from the current index to another + // index that isn't already used, and isn't an internal edge + for ( i = 0 ; i < numTris ; i++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + if ( tri->indexes[i*3+j] != indexes[numIndexes-1] ) { + continue; + } + int next = tri->indexes[i*3+(j+1)%3]; + + // make sure it isn't already used + if ( numIndexes == 1 ) { + if ( next == indexes[0] ) { + continue; + } + } else { + for ( k = 1 ; k < numIndexes ; k++ ) { + if ( indexes[k] == next ) { + break; + } + } + if ( k != numIndexes ) { + continue; + } + } + + // make sure it isn't an interior edge + for ( k = 0 ; k < numTris ; k++ ) { + if ( k == i ) { + continue; + } + for ( l = 0 ; l < 3 ; l++ ) { + int a, b; + + a = tri->indexes[k*3+l]; + if ( a != next ) { + continue; + } + b = tri->indexes[k*3+(l+1)%3]; + if ( b != indexes[numIndexes-1] ) { + continue; + } + + // this is an interior edge + break; + } + if ( l != 3 ) { + break; + } + } + if ( k != numTris ) { + continue; + } + + // add this to the list + indexes[numIndexes] = next; + numIndexes++; + break; + } + if ( j != 3 ) { + break; + } + } + if ( numIndexes == tri->numVerts ) { + break; + } + } while ( i != numTris ); + + return numIndexes; +} + +/* +===================== +R_FlareDeform + +===================== +*/ +/* +static void R_FlareDeform( drawSurf_t *surf ) { + const srfTriangles_t *tri; + srfTriangles_t *newTri; + idPlane plane; + float dot; + idVec3 localViewer; + int j; + + tri = surf->geo; + + if ( tri->numVerts != 4 || tri->numIndexes != 6 ) { + //FIXME: temp hack for flares on tripleted models + common->Warning( "R_FlareDeform: not a single quad" ); + return; + } + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = 4; + newTri->numIndexes = 2*3; + newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + // find the plane + plane.FromPoints( tri->verts[tri->indexes[0]].xyz, tri->verts[tri->indexes[1]].xyz, tri->verts[tri->indexes[2]].xyz ); + + // if viewer is behind the plane, draw nothing + R_GlobalPointToLocal( surf->space->modelMatrix, tr.viewDef->renderView.vieworg, localViewer ); + float distFromPlane = localViewer * plane.Normal() + plane[3]; + if ( distFromPlane <= 0 ) { + newTri->numIndexes = 0; + surf->geo = newTri; + return; + } + + idVec3 center; + center = tri->verts[0].xyz; + for ( j = 1 ; j < tri->numVerts ; j++ ) { + center += tri->verts[j].xyz; + } + center *= 1.0/tri->numVerts; + + idVec3 dir = localViewer - center; + dir.Normalize(); + + dot = dir * plane.Normal(); + + // set vertex colors based on plane angle + int color = (int)(dot * 8 * 256); + if ( color > 255 ) { + color = 255; + } + for ( j = 0 ; j < newTri->numVerts ; j++ ) { + ac[j].color[0] = + ac[j].color[1] = + ac[j].color[2] = color; + ac[j].color[3] = 255; + } + + float spread = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ] * r_flareSize.GetFloat(); + idVec3 edgeDir[4][3]; + glIndex_t indexes[MAX_TRI_WINDING_INDEXES]; + int numIndexes = R_WindingFromTriangles( tri, indexes ); + + surf->material = declManager->FindMaterial( "textures/smf/anamorphicFlare" ); + + // only deal with quads + if ( numIndexes != 4 ) { + return; + } + + // compute centroid + idVec3 centroid, toeye, forward, up, left; + centroid.Set( 0, 0, 0 ); + for ( int i = 0; i < 4; i++ ) { + centroid += tri->verts[ indexes[i] ].xyz; + } + centroid /= 4; + + // compute basis vectors + up.Set( 0, 0, 1 ); + + toeye = centroid - localViewer; + toeye.Normalize(); + left = toeye.Cross( up ); + up = left.Cross( toeye ); + + left = left * 40 * 6; + up = up * 40; + + // compute flares + struct flare_t { + float angle; + float length; + }; + + static flare_t flares[] = { + { 0, 100 }, + { 90, 100 } + }; + + for ( int i = 0; i < 4; i++ ) { + memset( ac + i, 0, sizeof( ac[i] ) ); + } + + ac[0].xyz = centroid - left; + ac[0].st[0] = 0; ac[0].st[1] = 0; + + ac[1].xyz = centroid + up; + ac[1].st[0] = 1; ac[1].st[1] = 0; + + ac[2].xyz = centroid + left; + ac[2].st[0] = 1; ac[2].st[1] = 1; + + ac[3].xyz = centroid - up; + ac[3].st[0] = 0; ac[3].st[1] = 1; + + // setup colors + for ( j = 0 ; j < newTri->numVerts ; j++ ) { + ac[j].color[0] = + ac[j].color[1] = + ac[j].color[2] = 255; + ac[j].color[3] = 255; + } + + // setup indexes + static glIndex_t triIndexes[2*3] = { + 0,1,2, 0,2,3 + }; + + memcpy( newTri->indexes, triIndexes, sizeof( triIndexes ) ); + + R_FinishDeform( surf, newTri, ac ); +} +*/ + +static void R_FlareDeform( drawSurf_t *surf ) { + const srfTriangles_t *tri; + srfTriangles_t *newTri; + idPlane plane; + float dot; + idVec3 localViewer; + int j; + + tri = surf->geo; + + if ( tri->numVerts != 4 || tri->numIndexes != 6 ) { + //FIXME: temp hack for flares on tripleted models + common->Warning( "R_FlareDeform: not a single quad" ); + return; + } + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = 16; + newTri->numIndexes = 18*3; + newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + // find the plane + plane.FromPoints( tri->verts[tri->indexes[0]].xyz, tri->verts[tri->indexes[1]].xyz, tri->verts[tri->indexes[2]].xyz ); + + // if viewer is behind the plane, draw nothing + R_GlobalPointToLocal( surf->space->modelMatrix, tr.viewDef->renderView.vieworg, localViewer ); + float distFromPlane = localViewer * plane.Normal() + plane[3]; + if ( distFromPlane <= 0 ) { + newTri->numIndexes = 0; + surf->geo = newTri; + return; + } + + idVec3 center; + center = tri->verts[0].xyz; + for ( j = 1 ; j < tri->numVerts ; j++ ) { + center += tri->verts[j].xyz; + } + center *= 1.0/tri->numVerts; + + idVec3 dir = localViewer - center; + dir.Normalize(); + + dot = dir * plane.Normal(); + + // set vertex colors based on plane angle + int color = (int)(dot * 8 * 256); + if ( color > 255 ) { + color = 255; + } + for ( j = 0 ; j < newTri->numVerts ; j++ ) { + ac[j].color[0] = + ac[j].color[1] = + ac[j].color[2] = color; + ac[j].color[3] = 255; + } + + float spread = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ] * r_flareSize.GetFloat(); + idVec3 edgeDir[4][3]; + glIndex_t indexes[MAX_TRI_WINDING_INDEXES]; + int numIndexes = R_WindingFromTriangles( tri, indexes ); + + + // only deal with quads + if ( numIndexes != 4 ) { + return; + } + int i; + // calculate vector directions + for ( i = 0 ; i < 4 ; i++ ) { + ac[i].xyz = tri->verts[ indexes[i] ].xyz; + ac[i].st[0] = + ac[i].st[1] = 0.5; + + idVec3 toEye = tri->verts[ indexes[i] ].xyz - localViewer; + toEye.Normalize(); + + idVec3 d1 = tri->verts[ indexes[(i+1)%4] ].xyz - localViewer; + d1.Normalize(); + edgeDir[i][1].Cross( toEye, d1 ); + edgeDir[i][1].Normalize(); + edgeDir[i][1] = vec3_origin - edgeDir[i][1]; + + idVec3 d2 = tri->verts[ indexes[(i+3)%4] ].xyz - localViewer; + d2.Normalize(); + edgeDir[i][0].Cross( toEye, d2 ); + edgeDir[i][0].Normalize(); + + edgeDir[i][2] = edgeDir[i][0] + edgeDir[i][1]; + edgeDir[i][2].Normalize(); + } + + // build all the points + ac[4].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][0]; + ac[4].st[0] = 0; + ac[4].st[1] = 0.5; + + ac[5].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][2]; + ac[5].st[0] = 0; + ac[5].st[1] = 0; + + ac[6].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][1]; + ac[6].st[0] = 0.5; + ac[6].st[1] = 0; + + + ac[7].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][0]; + ac[7].st[0] = 0.5; + ac[7].st[1] = 0; + + ac[8].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][2]; + ac[8].st[0] = 1; + ac[8].st[1] = 0; + + ac[9].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][1]; + ac[9].st[0] = 1; + ac[9].st[1] = 0.5; + + + ac[10].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][0]; + ac[10].st[0] = 1; + ac[10].st[1] = 0.5; + + ac[11].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][2]; + ac[11].st[0] = 1; + ac[11].st[1] = 1; + + ac[12].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][1]; + ac[12].st[0] = 0.5; + ac[12].st[1] = 1; + + + ac[13].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][0]; + ac[13].st[0] = 0.5; + ac[13].st[1] = 1; + + ac[14].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][2]; + ac[14].st[0] = 0; + ac[14].st[1] = 1; + + ac[15].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][1]; + ac[15].st[0] = 0; + ac[15].st[1] = 0.5; + + for ( i = 4 ; i < 16 ; i++ ) { + idVec3 dir = ac[i].xyz - localViewer; + float len = dir.Normalize(); + + float ang = dir * plane.Normal(); + +// ac[i].xyz -= dir * spread * 2; + float newLen = -( distFromPlane / ang ); + + if ( newLen > 0 && newLen < len ) { + ac[i].xyz = localViewer + dir * newLen; + } + + ac[i].st[0] = 0; + ac[i].st[1] = 0.5; + } + +#if 1 + static glIndex_t triIndexes[18*3] = { + 0,4,5, 0,5,6, 0,6,7, 0,7,1, 1,7,8, 1,8,9, + 15,4,0, 15,0,3, 3,0,1, 3,1,2, 2,1,9, 2,9,10, + 14,15,3, 14,3,13, 13,3,2, 13,2,12, 12,2,11, 11,2,10 + }; +#else + newTri->numIndexes = 12; + static glIndex_t triIndexes[4*3] = { + 0,1,2, 0,2,3, 0,4,5,0,5,6 + }; +#endif + + memcpy( newTri->indexes, triIndexes, sizeof( triIndexes ) ); + + R_FinishDeform( surf, newTri, ac ); +} + + + +/* +===================== +R_ExpandDeform + +Expands the surface along it's normals by a shader amount +===================== +*/ +static void R_ExpandDeform( drawSurf_t *surf ) { + int i; + const srfTriangles_t *tri; + srfTriangles_t *newTri; + + tri = surf->geo; + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = tri->indexes; + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + float dist = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ]; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + ac[i] = *(idDrawVert *)&tri->verts[i]; + ac[i].xyz = tri->verts[i].xyz + tri->verts[i].normal * dist; + } + + R_FinishDeform( surf, newTri, ac ); +} + +/* +===================== +R_MoveDeform + +Moves the surface along the X axis, mostly just for demoing the deforms +===================== +*/ +static void R_MoveDeform( drawSurf_t *surf ) { + int i; + const srfTriangles_t *tri; + srfTriangles_t *newTri; + + tri = surf->geo; + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = tri->indexes; + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + float dist = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ]; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + ac[i] = *(idDrawVert *)&tri->verts[i]; + ac[i].xyz[0] += dist; + } + + R_FinishDeform( surf, newTri, ac ); +} + +//===================================================================================== + +/* +===================== +R_TurbulentDeform + +Turbulently deforms the XYZ, S, and T values +===================== +*/ +static void R_TurbulentDeform( drawSurf_t *surf ) { + int i; + const srfTriangles_t *tri; + srfTriangles_t *newTri; + + tri = surf->geo; + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = tri->indexes; + + idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) ); + + idDeclTable *table = (idDeclTable *)surf->material->GetDeformDecl(); + float range = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ]; + float timeOfs = surf->shaderRegisters[ surf->material->GetDeformRegister(1) ]; + float domain = surf->shaderRegisters[ surf->material->GetDeformRegister(2) ]; + float tOfs = 0.5; + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + float f = tri->verts[i].xyz[0] * 0.003 + tri->verts[i].xyz[1] * 0.007 + tri->verts[i].xyz[2] * 0.011; + + f = timeOfs + domain * f; + f += timeOfs; + + ac[i] = *(idDrawVert *)&tri->verts[i]; + + ac[i].st[0] += range * table->TableLookup( f ); + ac[i].st[1] += range * table->TableLookup( f + tOfs ); + } + + R_FinishDeform( surf, newTri, ac ); +} + +//===================================================================================== + +/* +===================== +AddTriangleToIsland_r + +===================== +*/ +#define MAX_EYEBALL_TRIS 10 +#define MAX_EYEBALL_ISLANDS 6 + +typedef struct { + int tris[MAX_EYEBALL_TRIS]; + int numTris; + idBounds bounds; + idVec3 mid; +} eyeIsland_t; + +static void AddTriangleToIsland_r( const srfTriangles_t *tri, int triangleNum, bool *usedList, eyeIsland_t *island ) { + int a, b, c; + + usedList[triangleNum] = true; + + // add to the current island + if ( island->numTris == MAX_EYEBALL_TRIS ) { + common->Error( "MAX_EYEBALL_TRIS" ); + } + island->tris[island->numTris] = triangleNum; + island->numTris++; + + // recurse into all neighbors + a = tri->indexes[triangleNum*3]; + b = tri->indexes[triangleNum*3+1]; + c = tri->indexes[triangleNum*3+2]; + + island->bounds.AddPoint( tri->verts[a].xyz ); + island->bounds.AddPoint( tri->verts[b].xyz ); + island->bounds.AddPoint( tri->verts[c].xyz ); + + int numTri = tri->numIndexes / 3; + for ( int i = 0 ; i < numTri ; i++ ) { + if ( usedList[i] ) { + continue; + } + if ( tri->indexes[i*3+0] == a + || tri->indexes[i*3+1] == a + || tri->indexes[i*3+2] == a + || tri->indexes[i*3+0] == b + || tri->indexes[i*3+1] == b + || tri->indexes[i*3+2] == b + || tri->indexes[i*3+0] == c + || tri->indexes[i*3+1] == c + || tri->indexes[i*3+2] == c ) { + AddTriangleToIsland_r( tri, i, usedList, island ); + } + } +} + +/* +===================== +R_EyeballDeform + +Each eyeball surface should have an separate upright triangle behind it, long end +pointing out the eye, and another single triangle in front of the eye for the focus point. +===================== +*/ +static void R_EyeballDeform( drawSurf_t *surf ) { + int i, j, k; + const srfTriangles_t *tri; + srfTriangles_t *newTri; + eyeIsland_t islands[MAX_EYEBALL_ISLANDS]; + int numIslands; + bool triUsed[MAX_EYEBALL_ISLANDS*MAX_EYEBALL_TRIS]; + + tri = surf->geo; + + // separate all the triangles into islands + int numTri = tri->numIndexes / 3; + if ( numTri > MAX_EYEBALL_ISLANDS*MAX_EYEBALL_TRIS ) { + common->Printf( "R_EyeballDeform: too many triangles in surface" ); + return; + } + memset( triUsed, 0, sizeof( triUsed ) ); + + for ( numIslands = 0 ; numIslands < MAX_EYEBALL_ISLANDS ; numIslands++ ) { + islands[numIslands].numTris = 0; + islands[numIslands].bounds.Clear(); + for ( i = 0 ; i < numTri ; i++ ) { + if ( !triUsed[i] ) { + AddTriangleToIsland_r( tri, i, triUsed, &islands[numIslands] ); + break; + } + } + if ( i == numTri ) { + break; + } + } + + // assume we always have two eyes, two origins, and two targets + if ( numIslands != 3 ) { + common->Printf( "R_EyeballDeform: %i triangle islands\n", numIslands ); + return; + } + + // this srfTriangles_t and all its indexes and caches are in frame + // memory, and will be automatically disposed of + + // the surface cannot have more indexes or verts than the original + newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) ); + memset( newTri, 0, sizeof( *newTri ) ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + newTri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( newTri->indexes[0] ) ); + idDrawVert *ac = (idDrawVert *)_alloca16( tri->numVerts * sizeof( idDrawVert ) ); + + newTri->numIndexes = 0; + + // decide which islands are the eyes and points + for ( i = 0 ; i < numIslands ; i++ ) { + islands[i].mid = islands[i].bounds.GetCenter(); + } + + for ( i = 0 ; i < numIslands ; i++ ) { + eyeIsland_t *island = &islands[i]; + + if ( island->numTris == 1 ) { + continue; + } + + // the closest single triangle point will be the eye origin + // and the next-to-farthest will be the focal point + idVec3 origin, focus; + int originIsland = 0; + float dist[MAX_EYEBALL_ISLANDS]; + int sortOrder[MAX_EYEBALL_ISLANDS]; + + for ( j = 0 ; j < numIslands ; j++ ) { + idVec3 dir = islands[j].mid - island->mid; + dist[j] = dir.Length(); + sortOrder[j] = j; + for ( k = j-1 ; k >= 0 ; k-- ) { + if ( dist[k] > dist[k+1] ) { + int temp = sortOrder[k]; + sortOrder[k] = sortOrder[k+1]; + sortOrder[k+1] = temp; + float ftemp = dist[k]; + dist[k] = dist[k+1]; + dist[k+1] = ftemp; + } + } + } + + originIsland = sortOrder[1]; + origin = islands[originIsland].mid; + + focus = islands[sortOrder[2]].mid; + + // determine the projection directions based on the origin island triangle + idVec3 dir = focus - origin; + dir.Normalize(); + + const idVec3 &p1 = tri->verts[tri->indexes[islands[originIsland].tris[0]+0]].xyz; + const idVec3 &p2 = tri->verts[tri->indexes[islands[originIsland].tris[0]+1]].xyz; + const idVec3 &p3 = tri->verts[tri->indexes[islands[originIsland].tris[0]+2]].xyz; + + idVec3 v1 = p2 - p1; + v1.Normalize(); + idVec3 v2 = p3 - p1; + v2.Normalize(); + + // texVec[0] will be the normal to the origin triangle + idVec3 texVec[2]; + + texVec[0].Cross( v1, v2 ); + + texVec[1].Cross( texVec[0], dir ); + + for ( j = 0 ; j < 2 ; j++ ) { + texVec[j] -= dir * ( texVec[j] * dir ); + texVec[j].Normalize(); + } + + // emit these triangles, generating the projected texcoords + + for ( j = 0 ; j < islands[i].numTris ; j++ ) { + for ( k = 0 ; k < 3 ; k++ ) { + int index = islands[i].tris[j] * 3; + + index = tri->indexes[index+k]; + newTri->indexes[newTri->numIndexes++] = index; + + ac[index].xyz = tri->verts[index].xyz; + + idVec3 local = tri->verts[index].xyz - origin; + + ac[index].st[0] = 0.5 + local * texVec[0]; + ac[index].st[1] = 0.5 + local * texVec[1]; + } + } + } + + R_FinishDeform( surf, newTri, ac ); +} + +//========================================================================================== + + +/* +===================== +R_ParticleDeform + +Emit particles from the surface instead of drawing it +===================== +*/ +static void R_ParticleDeform( drawSurf_t *surf, bool useArea ) { + const struct renderEntity_s *renderEntity = &surf->space->entityDef->parms; + const struct viewDef_s *viewDef = tr.viewDef; + const idDeclParticle *particleSystem = (idDeclParticle *)surf->material->GetDeformDecl(); + + if ( r_skipParticles.GetBool() ) { + return; + } + +#if 0 + if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && + viewDef->renderView.time*0.001 >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) { + // the entire system has faded out + return NULL; + } +#endif + + // + // calculate the area of all the triangles + // + int numSourceTris = surf->geo->numIndexes / 3; + float totalArea = 0; + float *sourceTriAreas = NULL; + const srfTriangles_t *srcTri = surf->geo; + + if ( useArea ) { + sourceTriAreas = (float *)_alloca( sizeof( *sourceTriAreas ) * numSourceTris ); + int triNum = 0; + for ( int i = 0 ; i < srcTri->numIndexes ; i += 3, triNum++ ) { + float area; + area = idWinding::TriangleArea( srcTri->verts[srcTri->indexes[i]].xyz, srcTri->verts[srcTri->indexes[i+1]].xyz, srcTri->verts[srcTri->indexes[i+2]].xyz ); + sourceTriAreas[triNum] = totalArea; + totalArea += area; + } + } + + // + // create the particles almost exactly the way idRenderModelPrt does + // + particleGen_t g; + + g.renderEnt = renderEntity; + g.renderView = &viewDef->renderView; + g.origin.Zero(); + g.axis = mat3_identity; + + for ( int currentTri = 0; currentTri < ( ( useArea ) ? 1 : numSourceTris ); currentTri++ ) { + + for ( int stageNum = 0 ; stageNum < particleSystem->stages.Num() ; stageNum++ ) { + idParticleStage *stage = particleSystem->stages[stageNum]; + + if ( !stage->material ) { + continue; + } + if ( !stage->cycleMsec ) { + continue; + } + if ( stage->hidden ) { // just for gui particle editor use + continue; + } + + // we interpret stage->totalParticles as "particles per map square area" + // so the systems look the same on different size surfaces + int totalParticles = ( useArea ) ? stage->totalParticles * totalArea / 4096.0 : ( stage->totalParticles ); + + int count = totalParticles * stage->NumQuadsPerParticle(); + + // allocate a srfTriangles in temp memory that can hold all the particles + srfTriangles_t *tri; + + tri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *tri ) ); + tri->numVerts = 4 * count; + tri->numIndexes = 6 * count; + tri->verts = (idDrawVert *)R_FrameAlloc( tri->numVerts * sizeof( tri->verts[0] ) ); + tri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( tri->indexes[0] ) ); + + // just always draw the particles + tri->bounds = stage->bounds; + + tri->numVerts = 0; + + idRandom steppingRandom, steppingRandom2; + + int stageAge = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000; + int stageCycle = stageAge / stage->cycleMsec; + int inCycleTime = stageAge - stageCycle * stage->cycleMsec; + + // some particles will be in this cycle, some will be in the previous cycle + steppingRandom.SetSeed( (( stageCycle << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) ); + steppingRandom2.SetSeed( (( (stageCycle-1) << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) ); + + for ( int index = 0 ; index < totalParticles ; index++ ) { + g.index = index; + + // bump the random + steppingRandom.RandomInt(); + steppingRandom2.RandomInt(); + + // calculate local age for this index + int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / totalParticles; + + int particleAge = stageAge - bunchOffset; + int particleCycle = particleAge / stage->cycleMsec; + if ( particleCycle < 0 ) { + // before the particleSystem spawned + continue; + } + if ( stage->cycles && particleCycle >= stage->cycles ) { + // cycled systems will only run cycle times + continue; + } + + if ( particleCycle == stageCycle ) { + g.random = steppingRandom; + } else { + g.random = steppingRandom2; + } + + int inCycleTime = particleAge - particleCycle * stage->cycleMsec; + + if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && + g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME]*1000 ) { + // don't fire any more particles + continue; + } + + // supress particles before or after the age clamp + g.frac = (float)inCycleTime / ( stage->particleLife * 1000 ); + if ( g.frac < 0 ) { + // yet to be spawned + continue; + } + if ( g.frac > 1.0 ) { + // this particle is in the deadTime band + continue; + } + + //--------------- + // locate the particle origin and axis somewhere on the surface + //--------------- + + int pointTri = currentTri; + + if ( useArea ) { + // select a triangle based on an even area distribution + pointTri = idBinSearch_LessEqual( sourceTriAreas, numSourceTris, g.random.RandomFloat() * totalArea ); + } + + // now pick a random point inside pointTri + const idDrawVert *v1 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 0 ] ]; + const idDrawVert *v2 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 1 ] ]; + const idDrawVert *v3 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 2 ] ]; + + float f1 = g.random.RandomFloat(); + float f2 = g.random.RandomFloat(); + float f3 = g.random.RandomFloat(); + + float ft = 1.0f / ( f1 + f2 + f3 + 0.0001f ); + + f1 *= ft; + f2 *= ft; + f3 *= ft; + + g.origin = v1->xyz * f1 + v2->xyz * f2 + v3->xyz * f3; + g.axis[0] = v1->tangents[0] * f1 + v2->tangents[0] * f2 + v3->tangents[0] * f3; + g.axis[1] = v1->tangents[1] * f1 + v2->tangents[1] * f2 + v3->tangents[1] * f3; + g.axis[2] = v1->normal * f1 + v2->normal * f2 + v3->normal * f3; + + //----------------------- + + // this is needed so aimed particles can calculate origins at different times + g.originalRandom = g.random; + + g.age = g.frac * stage->particleLife; + + // if the particle doesn't get drawn because it is faded out or beyond a kill region, + // don't increment the verts + tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts ); + } + + if ( tri->numVerts > 0 ) { + // build the index list + int indexes = 0; + for ( int i = 0 ; i < tri->numVerts ; i += 4 ) { + tri->indexes[indexes+0] = i; + tri->indexes[indexes+1] = i+2; + tri->indexes[indexes+2] = i+3; + tri->indexes[indexes+3] = i; + tri->indexes[indexes+4] = i+3; + tri->indexes[indexes+5] = i+1; + indexes += 6; + } + tri->numIndexes = indexes; + tri->ambientCache = vertexCache.AllocFrameTemp( tri->verts, tri->numVerts * sizeof( idDrawVert ) ); + if ( tri->ambientCache ) { + // add the drawsurf + R_AddDrawSurf( tri, surf->space, renderEntity, stage->material, surf->scissorRect ); + } + } + } + } +} + +//======================================================================================== + +/* +================= +R_DeformDrawSurf +================= +*/ +void R_DeformDrawSurf( drawSurf_t *drawSurf ) { + if ( !drawSurf->material ) { + return; + } + + if ( r_skipDeforms.GetBool() ) { + return; + } + switch ( drawSurf->material->Deform() ) { + case DFRM_NONE: + return; + case DFRM_SPRITE: + R_AutospriteDeform( drawSurf ); + break; + case DFRM_TUBE: + R_TubeDeform( drawSurf ); + break; + case DFRM_FLARE: + R_FlareDeform( drawSurf ); + break; + case DFRM_EXPAND: + R_ExpandDeform( drawSurf ); + break; + case DFRM_MOVE: + R_MoveDeform( drawSurf ); + break; + case DFRM_TURB: + R_TurbulentDeform( drawSurf ); + break; + case DFRM_EYEBALL: + R_EyeballDeform( drawSurf ); + break; + case DFRM_PARTICLE: + R_ParticleDeform( drawSurf, true ); + break; + case DFRM_PARTICLE2: + R_ParticleDeform( drawSurf, false ); + break; + } +} diff --git a/renderer/tr_font.cpp b/renderer/tr_font.cpp new file mode 100644 index 000000000..68f441f47 --- /dev/null +++ b/renderer/tr_font.cpp @@ -0,0 +1,544 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +#ifdef BUILD_FREETYPE +#include "../ft2/fterrors.h" +#include "../ft2/ftsystem.h" +#include "../ft2/ftimage.h" +#include "../ft2/freetype.h" +#include "../ft2/ftoutln.h" + +#define _FLOOR(x) ((x) & -64) +#define _CEIL(x) (((x)+63) & -64) +#define _TRUNC(x) ((x) >> 6) + +FT_Library ftLibrary = NULL; +#endif + + +#ifdef BUILD_FREETYPE + +/* +============ +R_GetGlyphInfo +============ +*/ +void R_GetGlyphInfo(FT_GlyphSlot glyph, int *left, int *right, int *width, int *top, int *bottom, int *height, int *pitch) { + + *left = _FLOOR( glyph->metrics.horiBearingX ); + *right = _CEIL( glyph->metrics.horiBearingX + glyph->metrics.width ); + *width = _TRUNC(*right - *left); + + *top = _CEIL( glyph->metrics.horiBearingY ); + *bottom = _FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height ); + *height = _TRUNC( *top - *bottom ); + *pitch = ( qtrue ? (*width+3) & -4 : (*width+7) >> 3 ); +} + +/* +============ +R_RenderGlyph +============ +*/ +FT_Bitmap *R_RenderGlyph(FT_GlyphSlot glyph, glyphInfo_t* glyphOut) { + FT_Bitmap *bit2; + int left, right, width, top, bottom, height, pitch, size; + + R_GetGlyphInfo(glyph, &left, &right, &width, &top, &bottom, &height, &pitch); + + if ( glyph->format == ft_glyph_format_outline ) { + size = pitch*height; + + bit2 = Mem_Alloc(sizeof(FT_Bitmap)); + + bit2->width = width; + bit2->rows = height; + bit2->pitch = pitch; + bit2->pixel_mode = ft_pixel_mode_grays; + //bit2->pixel_mode = ft_pixel_mode_mono; + bit2->buffer = Mem_Alloc(pitch*height); + bit2->num_grays = 256; + + memset( bit2->buffer, 0, size ); + + FT_Outline_Translate( &glyph->outline, -left, -bottom ); + + FT_Outline_Get_Bitmap( ftLibrary, &glyph->outline, bit2 ); + + glyphOut->height = height; + glyphOut->pitch = pitch; + glyphOut->top = (glyph->metrics.horiBearingY >> 6) + 1; + glyphOut->bottom = bottom; + + return bit2; + } + else { + common->Printf( "Non-outline fonts are not supported\n" ); + } + return NULL; +} + +/* +============ +RE_ConstructGlyphInfo +============ +*/ +glyphInfo_t *RE_ConstructGlyphInfo( unsigned char *imageOut, int *xOut, int *yOut, int *maxHeight, FT_Face face, const unsigned char c, qboolean calcHeight ) { + int i; + static glyphInfo_t glyph; + unsigned char *src, *dst; + float scaled_width, scaled_height; + FT_Bitmap *bitmap = NULL; + + memset(&glyph, 0, sizeof(glyphInfo_t)); + // make sure everything is here + if (face != NULL) { + FT_Load_Glyph(face, FT_Get_Char_Index( face, c), FT_LOAD_DEFAULT ); + bitmap = R_RenderGlyph(face->glyph, &glyph); + if (bitmap) { + glyph.xSkip = (face->glyph->metrics.horiAdvance >> 6) + 1; + } else { + return &glyph; + } + + if (glyph.height > *maxHeight) { + *maxHeight = glyph.height; + } + + if (calcHeight) { + Mem_Free(bitmap->buffer); + Mem_Free(bitmap); + return &glyph; + } + +/* + // need to convert to power of 2 sizes so we do not get + // any scaling from the gl upload + for (scaled_width = 1 ; scaled_width < glyph.pitch ; scaled_width<<=1) + ; + for (scaled_height = 1 ; scaled_height < glyph.height ; scaled_height<<=1) + ; +*/ + + scaled_width = glyph.pitch; + scaled_height = glyph.height; + + // we need to make sure we fit + if (*xOut + scaled_width + 1 >= 255) { + if (*yOut + *maxHeight + 1 >= 255) { + *yOut = -1; + *xOut = -1; + Mem_Free(bitmap->buffer); + Mem_Free(bitmap); + return &glyph; + } else { + *xOut = 0; + *yOut += *maxHeight + 1; + } + } else if (*yOut + *maxHeight + 1 >= 255) { + *yOut = -1; + *xOut = -1; + Mem_Free(bitmap->buffer); + Mem_Free(bitmap); + return &glyph; + } + + src = bitmap->buffer; + dst = imageOut + (*yOut * 256) + *xOut; + + if (bitmap->pixel_mode == ft_pixel_mode_mono) { + for (i = 0; i < glyph.height; i++) { + int j; + unsigned char *_src = src; + unsigned char *_dst = dst; + unsigned char mask = 0x80; + unsigned char val = *_src; + for (j = 0; j < glyph.pitch; j++) { + if (mask == 0x80) { + val = *_src++; + } + if (val & mask) { + *_dst = 0xff; + } + mask >>= 1; + + if ( mask == 0 ) { + mask = 0x80; + } + _dst++; + } + + src += glyph.pitch; + dst += 256; + + } + } else { + for (i = 0; i < glyph.height; i++) { + memcpy( dst, src, glyph.pitch ); + src += glyph.pitch; + dst += 256; + } + } + + // we now have an 8 bit per pixel grey scale bitmap + // that is width wide and pf->ftSize->metrics.y_ppem tall + + glyph.imageHeight = scaled_height; + glyph.imageWidth = scaled_width; + glyph.s = (float)*xOut / 256; + glyph.t = (float)*yOut / 256; + glyph.s2 = glyph.s + (float)scaled_width / 256; + glyph.t2 = glyph.t + (float)scaled_height / 256; + + *xOut += scaled_width + 1; + } + + Mem_Free(bitmap->buffer); + Mem_Free(bitmap); + + return &glyph; +} + +#endif + +static int fdOffset; +static byte *fdFile; + +/* +============ +readInt +============ +*/ +int readInt( void ) { + int i = fdFile[fdOffset]+(fdFile[fdOffset+1]<<8)+(fdFile[fdOffset+2]<<16)+(fdFile[fdOffset+3]<<24); + fdOffset += 4; + return i; +} + +typedef union { + byte fred[4]; + float ffred; +} poor; + +/* +============ +readFloat +============ +*/ +float readFloat( void ) { + poor me; +#ifdef __ppc__ + me.fred[0] = fdFile[fdOffset+3]; + me.fred[1] = fdFile[fdOffset+2]; + me.fred[2] = fdFile[fdOffset+1]; + me.fred[3] = fdFile[fdOffset+0]; +#else + me.fred[0] = fdFile[fdOffset+0]; + me.fred[1] = fdFile[fdOffset+1]; + me.fred[2] = fdFile[fdOffset+2]; + me.fred[3] = fdFile[fdOffset+3]; +#endif + fdOffset += 4; + return me.ffred; +} + +/* +============ +RegisterFont + +Loads 3 point sizes, 12, 24, and 48 +============ +*/ +bool idRenderSystemLocal::RegisterFont( const char *fontName, fontInfoEx_t &font ) { +#ifdef BUILD_FREETYPE + FT_Face face; + int j, k, xOut, yOut, lastStart, imageNumber; + int scaledSize, newSize, maxHeight, left, satLevels; + unsigned char *out, *imageBuff; + glyphInfo_t *glyph; + idImage *image; + idMaterial *h; + float max; +#endif + void *faceData; + ID_TIME_T ftime; + int i, len, fontCount; + char name[1024]; + + int pointSize = 12; +/* + if ( registeredFontCount >= MAX_FONTS ) { + common->Warning( "RegisterFont: Too many fonts registered already." ); + return false; + } + + int pointSize = 12; + idStr::snPrintf( name, sizeof(name), "%s/fontImage_%i.dat", fontName, pointSize ); + for ( i = 0; i < registeredFontCount; i++ ) { + if ( idStr::Icmp(name, registeredFont[i].fontInfoSmall.name) == 0 ) { + memcpy( &font, ®isteredFont[i], sizeof( fontInfoEx_t ) ); + return true; + } + } +*/ + + memset( &font, 0, sizeof( font ) ); + + for ( fontCount = 0; fontCount < 3; fontCount++ ) { + + if ( fontCount == 0) { + pointSize = 12; + } else if ( fontCount == 1 ) { + pointSize = 24; + } else { + pointSize = 48; + } + // we also need to adjust the scale based on point size relative to 48 points as the ui scaling is based on a 48 point font + float glyphScale = 1.0f; // change the scale to be relative to 1 based on 72 dpi ( so dpi of 144 means a scale of .5 ) + glyphScale *= 48.0f / pointSize; + + idStr::snPrintf( name, sizeof(name), "%s/fontImage_%i.dat", fontName, pointSize ); + + fontInfo_t *outFont; + if ( fontCount == 0 ) { + outFont = &font.fontInfoSmall; + } + else if ( fontCount == 1 ) { + outFont = &font.fontInfoMedium; + } + else { + outFont = &font.fontInfoLarge; + } + + idStr::Copynz( outFont->name, name, sizeof( outFont->name ) ); + + len = fileSystem->ReadFile( name, NULL, &ftime ); + if ( len != sizeof( fontInfo_t ) ) { + common->Warning( "RegisterFont: couldn't find font: '%s'", name ); + return false; + } + + fileSystem->ReadFile( name, &faceData, &ftime ); + fdOffset = 0; + fdFile = reinterpret_cast(faceData); + for( i = 0; i < GLYPHS_PER_FONT; i++ ) { + outFont->glyphs[i].height = readInt(); + outFont->glyphs[i].top = readInt(); + outFont->glyphs[i].bottom = readInt(); + outFont->glyphs[i].pitch = readInt(); + outFont->glyphs[i].xSkip = readInt(); + outFont->glyphs[i].imageWidth = readInt(); + outFont->glyphs[i].imageHeight = readInt(); + outFont->glyphs[i].s = readFloat(); + outFont->glyphs[i].t = readFloat(); + outFont->glyphs[i].s2 = readFloat(); + outFont->glyphs[i].t2 = readFloat(); + int junk /* font.glyphs[i].glyph */ = readInt(); + //FIXME: the +6, -6 skips the embedded fonts/ + memcpy( outFont->glyphs[i].shaderName, &fdFile[fdOffset + 6], 32 - 6 ); + fdOffset += 32; + } + outFont->glyphScale = readFloat(); + + int mw = 0; + int mh = 0; + for (i = GLYPH_START; i < GLYPH_END; i++) { + idStr::snPrintf(name, sizeof(name), "%s/%s", fontName, outFont->glyphs[i].shaderName); + outFont->glyphs[i].glyph = declManager->FindMaterial(name); + outFont->glyphs[i].glyph->SetSort( SS_GUI ); + if (mh < outFont->glyphs[i].height) { + mh = outFont->glyphs[i].height; + } + if (mw < outFont->glyphs[i].xSkip) { + mw = outFont->glyphs[i].xSkip; + } + } + if (fontCount == 0) { + font.maxWidthSmall = mw; + font.maxHeightSmall = mh; + } else if (fontCount == 1) { + font.maxWidthMedium = mw; + font.maxHeightMedium = mh; + } else { + font.maxWidthLarge = mw; + font.maxHeightLarge = mh; + } + fileSystem->FreeFile( faceData ); + } + + //memcpy( ®isteredFont[registeredFontCount++], &font, sizeof( fontInfoEx_t ) ); + + return true ; + +#ifndef BUILD_FREETYPE + common->Warning( "RegisterFont: couldn't load FreeType code %s", name ); +#else + + if (ftLibrary == NULL) { + common->Warning( "RegisterFont: FreeType not initialized." ); + return; + } + + len = fileSystem->ReadFile(fontName, &faceData, &ftime); + if ( len <= 0 ) { + common->Warning( "RegisterFont: Unable to read font file" ); + return; + } + + // allocate on the stack first in case we fail + if ( FT_New_Memory_Face( ftLibrary, faceData, len, 0, &face ) ) { + common->Warning( "RegisterFont: FreeType2, unable to allocate new face." ); + return; + } + + + if ( FT_Set_Char_Size( face, pointSize << 6, pointSize << 6, dpi, dpi) ) { + common->Warning( "RegisterFont: FreeType2, Unable to set face char size." ); + return; + } + + // font = registeredFonts[registeredFontCount++]; + + // make a 256x256 image buffer, once it is full, register it, clean it and keep going + // until all glyphs are rendered + + out = Mem_Alloc( 1024*1024 ); + if ( out == NULL ) { + common->Warning( "RegisterFont: Mem_Alloc failure during output image creation." ); + return; + } + memset( out, 0, 1024*1024 ); + + maxHeight = 0; + + for (i = GLYPH_START; i < GLYPH_END; i++) { + glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qtrue); + } + + xOut = 0; + yOut = 0; + i = GLYPH_START; + lastStart = i; + imageNumber = 0; + + while ( i <= GLYPH_END ) { + + glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qfalse); + + if (xOut == -1 || yOut == -1 || i == GLYPH_END) { + // ran out of room + // we need to create an image from the bitmap, set all the handles in the glyphs to this point + // + + scaledSize = 256*256; + newSize = scaledSize * 4; + imageBuff = Mem_Alloc(newSize); + left = 0; + max = 0; + satLevels = 255; + for ( k = 0; k < (scaledSize) ; k++ ) { + if (max < out[k]) { + max = out[k]; + } + } + + if (max > 0) { + max = 255/max; + } + + for ( k = 0; k < (scaledSize) ; k++ ) { + imageBuff[left++] = 255; + imageBuff[left++] = 255; + imageBuff[left++] = 255; + imageBuff[left++] = ((float)out[k] * max); + } + + idStr::snprintf( name, sizeof(name), "fonts/fontImage_%i_%i.tga", imageNumber++, pointSize ); + if (r_saveFontData->integer) { + R_WriteTGA(name, imageBuff, 256, 256); + } + + //idStr::snprintf( name, sizeof(name), "fonts/fontImage_%i_%i", imageNumber++, pointSize ); + image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP); + h = RE_RegisterShaderFromImage(name, LIGHTMAP_2D, image, qfalse); + for (j = lastStart; j < i; j++) { + font.glyphs[j].glyph = h; + idStr::Copynz( font.glyphs[j].shaderName, name, sizeof( font.glyphs[j].shaderName ) ); + } + lastStart = i; + memset( out, 0, 1024*1024 ); + xOut = 0; + yOut = 0; + Mem_Free( imageBuff ); + i++; + } else { + memcpy( &font.glyphs[i], glyph, sizeof( glyphInfo_t ) ); + i++; + } + } + + registeredFont[registeredFontCount].glyphScale = glyphScale; + font.glyphScale = glyphScale; + memcpy( ®isteredFont[registeredFontCount++], &font, sizeof( fontInfo_t ) ); + + if ( r_saveFontData->integer ) { + fileSystem->WriteFile( va( "fonts/fontImage_%i.dat", pointSize), &font, sizeof( fontInfo_t ) ); + } + + Mem_Free( out ); + + fileSystem->FreeFile( faceData ); +#endif + return true; +} + +/* +============ +R_InitFreeType +============ +*/ +void R_InitFreeType( void ) { +#ifdef BUILD_FREETYPE + if ( FT_Init_FreeType( &ftLibrary ) ) { + common->Printf( "R_InitFreeType: Unable to initialize FreeType.\n" ); + } +#endif +// registeredFontCount = 0; +} + +/* +============ +R_DoneFreeType +============ +*/ +void R_DoneFreeType( void ) { +#ifdef BUILD_FREETYPE + if ( ftLibrary ) { + FT_Done_FreeType( ftLibrary ); + ftLibrary = NULL; + } +#endif +// registeredFontCount = 0; +} diff --git a/renderer/tr_guisurf.cpp b/renderer/tr_guisurf.cpp new file mode 100644 index 000000000..dd463688d --- /dev/null +++ b/renderer/tr_guisurf.cpp @@ -0,0 +1,210 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +========================================================================================== + +GUI SHADERS + +========================================================================================== +*/ + +/* +================ +R_SurfaceToTextureAxis + +Calculates two axis for the surface sutch that a point dotted against +the axis will give a 0.0 to 1.0 range in S and T when inside the gui surface +================ +*/ +void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] ) { + float area, inva; + float d0[5], d1[5]; + idDrawVert *a, *b, *c; + float bounds[2][2]; + float boundsOrg[2]; + int i, j; + float v; + + // find the bounds of the texture + bounds[0][0] = bounds[0][1] = 999999; + bounds[1][0] = bounds[1][1] = -999999; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + for ( j = 0 ; j < 2 ; j++ ) { + v = tri->verts[i].st[j]; + if ( v < bounds[0][j] ) { + bounds[0][j] = v; + } + if ( v > bounds[1][j] ) { + bounds[1][j] = v; + } + } + } + + // use the floor of the midpoint as the origin of the + // surface, which will prevent a slight misalignment + // from throwing it an entire cycle off + boundsOrg[0] = floor( ( bounds[0][0] + bounds[1][0] ) * 0.5 ); + boundsOrg[1] = floor( ( bounds[0][1] + bounds[1][1] ) * 0.5 ); + + + // determine the world S and T vectors from the first drawSurf triangle + a = tri->verts + tri->indexes[0]; + b = tri->verts + tri->indexes[1]; + c = tri->verts + tri->indexes[2]; + + VectorSubtract( b->xyz, a->xyz, d0 ); + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + VectorSubtract( c->xyz, a->xyz, d1 ); + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + if ( area == 0.0 ) { + axis[0].Zero(); + axis[1].Zero(); + axis[2].Zero(); + return; // degenerate + } + inva = 1.0 / area; + + axis[0][0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva; + axis[0][1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva; + axis[0][2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva; + + axis[1][0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva; + axis[1][1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva; + axis[1][2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva; + + idPlane plane; + plane.FromPoints( a->xyz, b->xyz, c->xyz ); + axis[2][0] = plane[0]; + axis[2][1] = plane[1]; + axis[2][2] = plane[2]; + + // take point 0 and project the vectors to the texture origin + VectorMA( a->xyz, boundsOrg[0] - a->st[0], axis[0], origin ); + VectorMA( origin, boundsOrg[1] - a->st[1], axis[1], origin ); +} + +/* +================= +R_RenderGuiSurf + +Create a texture space on the given surface and +call the GUI generator to create quads for it. +================= +*/ +void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ) { + idVec3 origin, axis[3]; + + // for testing the performance hit + if ( r_skipGuiShaders.GetInteger() == 1 ) { + return; + } + + // don't allow an infinite recursion loop + if ( tr.guiRecursionLevel == 4 ) { + return; + } + + tr.pc.c_guiSurfs++; + + // create the new matrix to draw on this surface + R_SurfaceToTextureAxis( drawSurf->geo, origin, axis ); + + float guiModelMatrix[16]; + float modelMatrix[16]; + + guiModelMatrix[0] = axis[0][0] / 640.0; + guiModelMatrix[4] = axis[1][0] / 480.0; + guiModelMatrix[8] = axis[2][0]; + guiModelMatrix[12] = origin[0]; + + guiModelMatrix[1] = axis[0][1] / 640.0; + guiModelMatrix[5] = axis[1][1] / 480.0; + guiModelMatrix[9] = axis[2][1]; + guiModelMatrix[13] = origin[1]; + + guiModelMatrix[2] = axis[0][2] / 640.0; + guiModelMatrix[6] = axis[1][2] / 480.0; + guiModelMatrix[10] = axis[2][2]; + guiModelMatrix[14] = origin[2]; + + guiModelMatrix[3] = 0; + guiModelMatrix[7] = 0; + guiModelMatrix[11] = 0; + guiModelMatrix[15] = 1; + + myGlMultMatrix( guiModelMatrix, drawSurf->space->modelMatrix, + modelMatrix ); + + tr.guiRecursionLevel++; + + // call the gui, which will call the 2D drawing functions + tr.guiModel->Clear(); + gui->Redraw( tr.viewDef->renderView.time ); + tr.guiModel->EmitToCurrentView( modelMatrix, drawSurf->space->weaponDepthHack ); + tr.guiModel->Clear(); + + tr.guiRecursionLevel--; +} + + + + +/* +================, +R_ReloadGuis_f + +Reloads any guis that have had their file timestamps changed. +An optional "all" parameter will cause all models to reload, even +if they are not out of date. + +Should we also reload the map models? +================ +*/ +void R_ReloadGuis_f( const idCmdArgs &args ) { + bool all; + + if ( !idStr::Icmp( args.Argv(1), "all" ) ) { + all = true; + common->Printf( "Reloading all gui files...\n" ); + } else { + all = false; + common->Printf( "Checking for changed gui files...\n" ); + } + + uiManager->Reload( all ); +} + +/* +================, +R_ListGuis_f + +================ +*/ +void R_ListGuis_f( const idCmdArgs &args ) { + uiManager->ListGuis(); +} diff --git a/renderer/tr_light.cpp b/renderer/tr_light.cpp new file mode 100644 index 000000000..f10caebe0 --- /dev/null +++ b/renderer/tr_light.cpp @@ -0,0 +1,1610 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +static const float CHECK_BOUNDS_EPSILON = 1.0f; + + +/* +=========================================================================================== + +VERTEX CACHE GENERATORS + +=========================================================================================== +*/ + +/* +================== +R_CreateAmbientCache + +Create it if needed +================== +*/ +bool R_CreateAmbientCache( srfTriangles_t *tri, bool needsLighting ) { + if ( tri->ambientCache ) { + return true; + } + // we are going to use it for drawing, so make sure we have the tangents and normals + if ( needsLighting && !tri->tangentsCalculated ) { + R_DeriveTangents( tri ); + } + + vertexCache.Alloc( tri->verts, tri->numVerts * sizeof( tri->verts[0] ), &tri->ambientCache ); + if ( !tri->ambientCache ) { + return false; + } + return true; +} + +/* +================== +R_CreateLightingCache + +Returns false if the cache couldn't be allocated, in which case the surface should be skipped. +================== +*/ +bool R_CreateLightingCache( const idRenderEntityLocal *ent, const idRenderLightLocal *light, srfTriangles_t *tri ) { + idVec3 localLightOrigin; + + // fogs and blends don't need light vectors + if ( light->lightShader->IsFogLight() || light->lightShader->IsBlendLight() ) { + return true; + } + + // not needed if we have vertex programs + if ( tr.backEndRendererHasVertexPrograms ) { + return true; + } + + R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, localLightOrigin ); + + int size = tri->ambientSurface->numVerts * sizeof( lightingCache_t ); + lightingCache_t *cache = (lightingCache_t *)_alloca16( size ); + +#if 1 + + SIMDProcessor->CreateTextureSpaceLightVectors( &cache[0].localLightVector, localLightOrigin, + tri->ambientSurface->verts, tri->ambientSurface->numVerts, tri->indexes, tri->numIndexes ); + +#else + + bool *used = (bool *)_alloca16( tri->ambientSurface->numVerts * sizeof( used[0] ) ); + memset( used, 0, tri->ambientSurface->numVerts * sizeof( used[0] ) ); + + // because the interaction may be a very small subset of the full surface, + // it makes sense to only deal with the verts used + for ( int j = 0; j < tri->numIndexes; j++ ) { + int i = tri->indexes[j]; + if ( used[i] ) { + continue; + } + used[i] = true; + + idVec3 lightDir; + const idDrawVert *v; + + v = &tri->ambientSurface->verts[i]; + + lightDir = localLightOrigin - v->xyz; + + cache[i].localLightVector[0] = lightDir * v->tangents[0]; + cache[i].localLightVector[1] = lightDir * v->tangents[1]; + cache[i].localLightVector[2] = lightDir * v->normal; + } + +#endif + + vertexCache.Alloc( cache, size, &tri->lightingCache ); + if ( !tri->lightingCache ) { + return false; + } + return true; +} + +/* +================== +R_CreatePrivateShadowCache + +This is used only for a specific light +================== +*/ +void R_CreatePrivateShadowCache( srfTriangles_t *tri ) { + if ( !tri->shadowVertexes ) { + return; + } + + vertexCache.Alloc( tri->shadowVertexes, tri->numVerts * sizeof( *tri->shadowVertexes ), &tri->shadowCache ); +} + +/* +================== +R_CreateVertexProgramShadowCache + +This is constant for any number of lights, the vertex program +takes care of projecting the verts to infinity. +================== +*/ +void R_CreateVertexProgramShadowCache( srfTriangles_t *tri ) { + if ( tri->verts == NULL ) { + return; + } + + shadowCache_t *temp = (shadowCache_t *)_alloca16( tri->numVerts * 2 * sizeof( shadowCache_t ) ); + +#if 1 + + SIMDProcessor->CreateVertexProgramShadowCache( &temp->xyz, tri->verts, tri->numVerts ); + +#else + + int numVerts = tri->numVerts; + const idDrawVert *verts = tri->verts; + for ( int i = 0; i < numVerts; i++ ) { + const float *v = verts[i].xyz.ToFloatPtr(); + temp[i*2+0].xyz[0] = v[0]; + temp[i*2+1].xyz[0] = v[0]; + temp[i*2+0].xyz[1] = v[1]; + temp[i*2+1].xyz[1] = v[1]; + temp[i*2+0].xyz[2] = v[2]; + temp[i*2+1].xyz[2] = v[2]; + temp[i*2+0].xyz[3] = 1.0f; // on the model surface + temp[i*2+1].xyz[3] = 0.0f; // will be projected to infinity + } + +#endif + + vertexCache.Alloc( temp, tri->numVerts * 2 * sizeof( shadowCache_t ), &tri->shadowCache ); +} + +/* +================== +R_SkyboxTexGen +================== +*/ +void R_SkyboxTexGen( drawSurf_t *surf, const idVec3 &viewOrg ) { + int i; + idVec3 localViewOrigin; + + R_GlobalPointToLocal( surf->space->modelMatrix, viewOrg, localViewOrigin ); + + int numVerts = surf->geo->numVerts; + int size = numVerts * sizeof( idVec3 ); + idVec3 *texCoords = (idVec3 *) _alloca16( size ); + + const idDrawVert *verts = surf->geo->verts; + for ( i = 0; i < numVerts; i++ ) { + texCoords[i][0] = verts[i].xyz[0] - localViewOrigin[0]; + texCoords[i][1] = verts[i].xyz[1] - localViewOrigin[1]; + texCoords[i][2] = verts[i].xyz[2] - localViewOrigin[2]; + } + + surf->dynamicTexCoords = vertexCache.AllocFrameTemp( texCoords, size ); +} + +/* +================== +R_WobbleskyTexGen +================== +*/ +void R_WobbleskyTexGen( drawSurf_t *surf, const idVec3 &viewOrg ) { + int i; + idVec3 localViewOrigin; + + const int *parms = surf->material->GetTexGenRegisters(); + + float wobbleDegrees = surf->shaderRegisters[ parms[0] ]; + float wobbleSpeed = surf->shaderRegisters[ parms[1] ]; + float rotateSpeed = surf->shaderRegisters[ parms[2] ]; + + wobbleDegrees = wobbleDegrees * idMath::PI / 180; + wobbleSpeed = wobbleSpeed * 2 * idMath::PI / 60; + rotateSpeed = rotateSpeed * 2 * idMath::PI / 60; + + // very ad-hoc "wobble" transform + float transform[16]; + float a = tr.viewDef->floatTime * wobbleSpeed; + float s = sin( a ) * sin( wobbleDegrees ); + float c = cos( a ) * sin( wobbleDegrees ); + float z = cos( wobbleDegrees ); + + idVec3 axis[3]; + + axis[2][0] = c; + axis[2][1] = s; + axis[2][2] = z; + + axis[1][0] = -sin( a * 2 ) * sin( wobbleDegrees ); + axis[1][2] = -s * sin( wobbleDegrees ); + axis[1][1] = sqrt( 1.0f - ( axis[1][0] * axis[1][0] + axis[1][2] * axis[1][2] ) ); + + // make the second vector exactly perpendicular to the first + axis[1] -= ( axis[2] * axis[1] ) * axis[2]; + axis[1].Normalize(); + + // construct the third with a cross + axis[0].Cross( axis[1], axis[2] ); + + // add the rotate + s = sin( rotateSpeed * tr.viewDef->floatTime ); + c = cos( rotateSpeed * tr.viewDef->floatTime ); + + transform[0] = axis[0][0] * c + axis[1][0] * s; + transform[4] = axis[0][1] * c + axis[1][1] * s; + transform[8] = axis[0][2] * c + axis[1][2] * s; + + transform[1] = axis[1][0] * c - axis[0][0] * s; + transform[5] = axis[1][1] * c - axis[0][1] * s; + transform[9] = axis[1][2] * c - axis[0][2] * s; + + transform[2] = axis[2][0]; + transform[6] = axis[2][1]; + transform[10] = axis[2][2]; + + transform[3] = transform[7] = transform[11] = 0.0f; + transform[12] = transform[13] = transform[14] = 0.0f; + + R_GlobalPointToLocal( surf->space->modelMatrix, viewOrg, localViewOrigin ); + + int numVerts = surf->geo->numVerts; + int size = numVerts * sizeof( idVec3 ); + idVec3 *texCoords = (idVec3 *) _alloca16( size ); + + const idDrawVert *verts = surf->geo->verts; + for ( i = 0; i < numVerts; i++ ) { + idVec3 v; + + v[0] = verts[i].xyz[0] - localViewOrigin[0]; + v[1] = verts[i].xyz[1] - localViewOrigin[1]; + v[2] = verts[i].xyz[2] - localViewOrigin[2]; + + R_LocalPointToGlobal( transform, v, texCoords[i] ); + } + + surf->dynamicTexCoords = vertexCache.AllocFrameTemp( texCoords, size ); +} + +/* +================= +R_SpecularTexGen + +Calculates the specular coordinates for cards without vertex programs. +================= +*/ +static void R_SpecularTexGen( drawSurf_t *surf, const idVec3 &globalLightOrigin, const idVec3 &viewOrg ) { + const srfTriangles_t *tri; + idVec3 localLightOrigin; + idVec3 localViewOrigin; + + R_GlobalPointToLocal( surf->space->modelMatrix, globalLightOrigin, localLightOrigin ); + R_GlobalPointToLocal( surf->space->modelMatrix, viewOrg, localViewOrigin ); + + tri = surf->geo; + + // FIXME: change to 3 component? + int size = tri->numVerts * sizeof( idVec4 ); + idVec4 *texCoords = (idVec4 *) _alloca16( size ); + +#if 1 + + SIMDProcessor->CreateSpecularTextureCoords( texCoords, localLightOrigin, localViewOrigin, + tri->verts, tri->numVerts, tri->indexes, tri->numIndexes ); + +#else + + bool *used = (bool *)_alloca16( tri->numVerts * sizeof( used[0] ) ); + memset( used, 0, tri->numVerts * sizeof( used[0] ) ); + + // because the interaction may be a very small subset of the full surface, + // it makes sense to only deal with the verts used + for ( int j = 0; j < tri->numIndexes; j++ ) { + int i = tri->indexes[j]; + if ( used[i] ) { + continue; + } + used[i] = true; + + float ilength; + + const idDrawVert *v = &tri->verts[i]; + + idVec3 lightDir = localLightOrigin - v->xyz; + idVec3 viewDir = localViewOrigin - v->xyz; + + ilength = idMath::RSqrt( lightDir * lightDir ); + lightDir[0] *= ilength; + lightDir[1] *= ilength; + lightDir[2] *= ilength; + + ilength = idMath::RSqrt( viewDir * viewDir ); + viewDir[0] *= ilength; + viewDir[1] *= ilength; + viewDir[2] *= ilength; + + lightDir += viewDir; + + texCoords[i][0] = lightDir * v->tangents[0]; + texCoords[i][1] = lightDir * v->tangents[1]; + texCoords[i][2] = lightDir * v->normal; + texCoords[i][3] = 1; + } + +#endif + + surf->dynamicTexCoords = vertexCache.AllocFrameTemp( texCoords, size ); +} + + +//======================================================================================================= + +/* +============= +R_SetEntityDefViewEntity + +If the entityDef isn't already on the viewEntity list, create +a viewEntity and add it to the list with an empty scissor rect. + +This does not instantiate dynamic models for the entity yet. +============= +*/ +viewEntity_t *R_SetEntityDefViewEntity( idRenderEntityLocal *def ) { + viewEntity_t *vModel; + + if ( def->viewCount == tr.viewCount ) { + return def->viewEntity; + } + def->viewCount = tr.viewCount; + + // set the model and modelview matricies + vModel = (viewEntity_t *)R_ClearedFrameAlloc( sizeof( *vModel ) ); + vModel->entityDef = def; + + // the scissorRect will be expanded as the model bounds is accepted into visible portal chains + vModel->scissorRect.Clear(); + + // copy the model and weapon depth hack for back-end use + vModel->modelDepthHack = def->parms.modelDepthHack; + vModel->weaponDepthHack = def->parms.weaponDepthHack; + + R_AxisToModelMatrix( def->parms.axis, def->parms.origin, vModel->modelMatrix ); + + // we may not have a viewDef if we are just creating shadows at entity creation time + if ( tr.viewDef ) { + myGlMultMatrix( vModel->modelMatrix, tr.viewDef->worldSpace.modelViewMatrix, vModel->modelViewMatrix ); + + vModel->next = tr.viewDef->viewEntitys; + tr.viewDef->viewEntitys = vModel; + } + + def->viewEntity = vModel; + + return vModel; +} + +/* +==================== +R_TestPointInViewLight +==================== +*/ +static const float INSIDE_LIGHT_FRUSTUM_SLOP = 32; +// this needs to be greater than the dist from origin to corner of near clip plane +static bool R_TestPointInViewLight( const idVec3 &org, const idRenderLightLocal *light ) { + int i; + idVec3 local; + + for ( i = 0 ; i < 6 ; i++ ) { + float d = light->frustum[i].Distance( org ); + if ( d > INSIDE_LIGHT_FRUSTUM_SLOP ) { + return false; + } + } + + return true; +} + +/* +=================== +R_PointInFrustum + +Assumes positive sides face outward +=================== +*/ +static bool R_PointInFrustum( idVec3 &p, idPlane *planes, int numPlanes ) { + for ( int i = 0 ; i < numPlanes ; i++ ) { + float d = planes[i].Distance( p ); + if ( d > 0 ) { + return false; + } + } + return true; +} + +/* +============= +R_SetLightDefViewLight + +If the lightDef isn't already on the viewLight list, create +a viewLight and add it to the list with an empty scissor rect. +============= +*/ +viewLight_t *R_SetLightDefViewLight( idRenderLightLocal *light ) { + viewLight_t *vLight; + + if ( light->viewCount == tr.viewCount ) { + return light->viewLight; + } + light->viewCount = tr.viewCount; + + // add to the view light chain + vLight = (viewLight_t *)R_ClearedFrameAlloc( sizeof( *vLight ) ); + vLight->lightDef = light; + + // the scissorRect will be expanded as the light bounds is accepted into visible portal chains + vLight->scissorRect.Clear(); + + // calculate the shadow cap optimization states + vLight->viewInsideLight = R_TestPointInViewLight( tr.viewDef->renderView.vieworg, light ); + if ( !vLight->viewInsideLight ) { + vLight->viewSeesShadowPlaneBits = 0; + for ( int i = 0 ; i < light->numShadowFrustums ; i++ ) { + float d = light->shadowFrustums[i].planes[5].Distance( tr.viewDef->renderView.vieworg ); + if ( d < INSIDE_LIGHT_FRUSTUM_SLOP ) { + vLight->viewSeesShadowPlaneBits|= 1 << i; + } + } + } else { + // this should not be referenced in this case + vLight->viewSeesShadowPlaneBits = 63; + } + + // see if the light center is in view, which will allow us to cull invisible shadows + vLight->viewSeesGlobalLightOrigin = R_PointInFrustum( light->globalLightOrigin, tr.viewDef->frustum, 4 ); + + // copy data used by backend + vLight->globalLightOrigin = light->globalLightOrigin; + vLight->lightProject[0] = light->lightProject[0]; + vLight->lightProject[1] = light->lightProject[1]; + vLight->lightProject[2] = light->lightProject[2]; + vLight->lightProject[3] = light->lightProject[3]; + vLight->fogPlane = light->frustum[5]; + vLight->frustumTris = light->frustumTris; + vLight->falloffImage = light->falloffImage; + vLight->lightShader = light->lightShader; + vLight->shaderRegisters = NULL; // allocated and evaluated in R_AddLightSurfaces + + // link the view light + vLight->next = tr.viewDef->viewLights; + tr.viewDef->viewLights = vLight; + + light->viewLight = vLight; + + return vLight; +} + +/* +================= +idRenderWorldLocal::CreateLightDefInteractions + +When a lightDef is determined to effect the view (contact the frustum and non-0 light), it will check to +make sure that it has interactions for all the entityDefs that it might possibly contact. + +This does not guarantee that all possible interactions for this light are generated, only that +the ones that may effect the current view are generated. so it does need to be called every view. + +This does not cause entityDefs to create dynamic models, all work is done on the referenceBounds. + +All entities that have non-empty interactions with viewLights will +have viewEntities made for them and be put on the viewEntity list, +even if their surfaces aren't visible, because they may need to cast shadows. + +Interactions are usually removed when a entityDef or lightDef is modified, unless the change +is known to not effect them, so there is no danger of getting a stale interaction, we just need to +check that needed ones are created. + +An interaction can be at several levels: + +Don't interact (but share an area) (numSurfaces = 0) +Entity reference bounds touches light frustum, but surfaces haven't been generated (numSurfaces = -1) +Shadow surfaces have been generated, but light surfaces have not. The shadow surface may still be empty due to bounds being conservative. +Both shadow and light surfaces have been generated. Either or both surfaces may still be empty due to conservative bounds. + +================= +*/ +void idRenderWorldLocal::CreateLightDefInteractions( idRenderLightLocal *ldef ) { + areaReference_t *eref; + areaReference_t *lref; + idRenderEntityLocal *edef; + portalArea_t *area; + idInteraction *inter; + + for ( lref = ldef->references ; lref ; lref = lref->ownerNext ) { + area = lref->area; + + // check all the models in this area + for ( eref = area->entityRefs.areaNext ; eref != &area->entityRefs ; eref = eref->areaNext ) { + edef = eref->entity; + + // if the entity doesn't have any light-interacting surfaces, we could skip this, + // but we don't want to instantiate dynamic models yet, so we can't check that on + // most things + + // if the entity isn't viewed + if ( tr.viewDef && edef->viewCount != tr.viewCount ) { + // if the light doesn't cast shadows, skip + if ( !ldef->lightShader->LightCastsShadows() ) { + continue; + } + // if we are suppressing its shadow in this view, skip + if ( !r_skipSuppress.GetBool() ) { + if ( edef->parms.suppressShadowInViewID && edef->parms.suppressShadowInViewID == tr.viewDef->renderView.viewID ) { + continue; + } + if ( edef->parms.suppressShadowInLightID && edef->parms.suppressShadowInLightID == ldef->parms.lightId ) { + continue; + } + } + } + + // some big outdoor meshes are flagged to not create any dynamic interactions + // when the level designer knows that nearby moving lights shouldn't actually hit them + if ( edef->parms.noDynamicInteractions && edef->world->generateAllInteractionsCalled ) { + continue; + } + + // if any of the edef's interaction match this light, we don't + // need to consider it. + if ( r_useInteractionTable.GetBool() && this->interactionTable ) { + // allocating these tables may take several megs on big maps, but it saves 3% to 5% of + // the CPU time. The table is updated at interaction::AllocAndLink() and interaction::UnlinkAndFree() + int index = ldef->index * this->interactionTableWidth + edef->index; + inter = this->interactionTable[ index ]; + if ( inter ) { + // if this entity wasn't in view already, the scissor rect will be empty, + // so it will only be used for shadow casting + if ( !inter->IsEmpty() ) { + R_SetEntityDefViewEntity( edef ); + } + continue; + } + } else { + // scan the doubly linked lists, which may have several dozen entries + + // we could check either model refs or light refs for matches, but it is + // assumed that there will be less lights in an area than models + // so the entity chains should be somewhat shorter (they tend to be fairly close). + for ( inter = edef->firstInteraction; inter != NULL; inter = inter->entityNext ) { + if ( inter->lightDef == ldef ) { + break; + } + } + + // if we already have an interaction, we don't need to do anything + if ( inter != NULL ) { + // if this entity wasn't in view already, the scissor rect will be empty, + // so it will only be used for shadow casting + if ( !inter->IsEmpty() ) { + R_SetEntityDefViewEntity( edef ); + } + continue; + } + } + + // + // create a new interaction, but don't do any work other than bbox to frustum culling + // + idInteraction *inter = idInteraction::AllocAndLink( edef, ldef ); + + // do a check of the entity reference bounds against the light frustum, + // trying to avoid creating a viewEntity if it hasn't been already + float modelMatrix[16]; + float *m; + + if ( edef->viewCount == tr.viewCount ) { + m = edef->viewEntity->modelMatrix; + } else { + R_AxisToModelMatrix( edef->parms.axis, edef->parms.origin, modelMatrix ); + m = modelMatrix; + } + + if ( R_CullLocalBox( edef->referenceBounds, m, 6, ldef->frustum ) ) { + inter->MakeEmpty(); + continue; + } + + // we will do a more precise per-surface check when we are checking the entity + + // if this entity wasn't in view already, the scissor rect will be empty, + // so it will only be used for shadow casting + R_SetEntityDefViewEntity( edef ); + } + } +} + +//=============================================================================================================== + +/* +================= +R_LinkLightSurf +================= +*/ +void R_LinkLightSurf( const drawSurf_t **link, const srfTriangles_t *tri, const viewEntity_t *space, + const idRenderLightLocal *light, const idMaterial *shader, const idScreenRect &scissor, bool viewInsideShadow ) { + drawSurf_t *drawSurf; + + if ( !space ) { + space = &tr.viewDef->worldSpace; + } + + drawSurf = (drawSurf_t *)R_FrameAlloc( sizeof( *drawSurf ) ); + + drawSurf->geo = tri; + drawSurf->space = space; + drawSurf->material = shader; + drawSurf->scissorRect = scissor; + drawSurf->dsFlags = 0; + if ( viewInsideShadow ) { + drawSurf->dsFlags |= DSF_VIEW_INSIDE_SHADOW; + } + + if ( !shader ) { + // shadows won't have a shader + drawSurf->shaderRegisters = NULL; + } else { + // process the shader expressions for conditionals / color / texcoords + const float *constRegs = shader->ConstantRegisters(); + if ( constRegs ) { + // this shader has only constants for parameters + drawSurf->shaderRegisters = constRegs; + } else { + // FIXME: share with the ambient surface? + float *regs = (float *)R_FrameAlloc( shader->GetNumRegisters() * sizeof( float ) ); + drawSurf->shaderRegisters = regs; + shader->EvaluateRegisters( regs, space->entityDef->parms.shaderParms, tr.viewDef, space->entityDef->parms.referenceSound ); + } + + // calculate the specular coordinates if we aren't using vertex programs + if ( !tr.backEndRendererHasVertexPrograms && !r_skipSpecular.GetBool() && tr.backEndRenderer != BE_ARB ) { + R_SpecularTexGen( drawSurf, light->globalLightOrigin, tr.viewDef->renderView.vieworg ); + // if we failed to allocate space for the specular calculations, drop the surface + if ( !drawSurf->dynamicTexCoords ) { + return; + } + } + } + + // actually link it in + drawSurf->nextOnLight = *link; + *link = drawSurf; +} + +/* +====================== +R_ClippedLightScissorRectangle +====================== +*/ +idScreenRect R_ClippedLightScissorRectangle( viewLight_t *vLight ) { + int i, j; + const idRenderLightLocal *light = vLight->lightDef; + idScreenRect r; + idFixedWinding w; + + r.Clear(); + + for ( i = 0 ; i < 6 ; i++ ) { + const idWinding *ow = light->frustumWindings[i]; + + // projected lights may have one of the frustums degenerated + if ( !ow ) { + continue; + } + + // the light frustum planes face out from the light, + // so the planes that have the view origin on the negative + // side will be the "back" faces of the light, which must have + // some fragment inside the portalStack to be visible + if ( light->frustum[i].Distance( tr.viewDef->renderView.vieworg ) >= 0 ) { + continue; + } + + w = *ow; + + // now check the winding against each of the frustum planes + for ( j = 0; j < 5; j++ ) { + if ( !w.ClipInPlace( -tr.viewDef->frustum[j] ) ) { + break; + } + } + + // project these points to the screen and add to bounds + for ( j = 0; j < w.GetNumPoints(); j++ ) { + idPlane eye, clip; + idVec3 ndc; + + R_TransformModelToClip( w[j].ToVec3(), tr.viewDef->worldSpace.modelViewMatrix, tr.viewDef->projectionMatrix, eye, clip ); + + if ( clip[3] <= 0.01f ) { + clip[3] = 0.01f; + } + + R_TransformClipToDevice( clip, tr.viewDef, ndc ); + + float windowX = 0.5f * ( 1.0f + ndc[0] ) * ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ); + float windowY = 0.5f * ( 1.0f + ndc[1] ) * ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ); + + if ( windowX > tr.viewDef->scissor.x2 ) { + windowX = tr.viewDef->scissor.x2; + } else if ( windowX < tr.viewDef->scissor.x1 ) { + windowX = tr.viewDef->scissor.x1; + } + if ( windowY > tr.viewDef->scissor.y2 ) { + windowY = tr.viewDef->scissor.y2; + } else if ( windowY < tr.viewDef->scissor.y1 ) { + windowY = tr.viewDef->scissor.y1; + } + + r.AddPoint( windowX, windowY ); + } + } + + // add the fudge boundary + r.Expand(); + + return r; +} + +/* +================== +R_CalcLightScissorRectangle + +The light screen bounds will be used to crop the scissor rect during +stencil clears and interaction drawing +================== +*/ +int c_clippedLight, c_unclippedLight; + +idScreenRect R_CalcLightScissorRectangle( viewLight_t *vLight ) { + idScreenRect r; + srfTriangles_t *tri; + idPlane eye, clip; + idVec3 ndc; + + if ( vLight->lightDef->parms.pointLight ) { + idBounds bounds; + idRenderLightLocal *lightDef = vLight->lightDef; + tr.viewDef->viewFrustum.ProjectionBounds( idBox( lightDef->parms.origin, lightDef->parms.lightRadius, lightDef->parms.axis ), bounds ); + return R_ScreenRectFromViewFrustumBounds( bounds ); + } + + if ( r_useClippedLightScissors.GetInteger() == 2 ) { + return R_ClippedLightScissorRectangle( vLight ); + } + + r.Clear(); + + tri = vLight->lightDef->frustumTris; + for ( int i = 0 ; i < tri->numVerts ; i++ ) { + R_TransformModelToClip( tri->verts[i].xyz, tr.viewDef->worldSpace.modelViewMatrix, + tr.viewDef->projectionMatrix, eye, clip ); + + // if it is near clipped, clip the winding polygons to the view frustum + if ( clip[3] <= 1 ) { + c_clippedLight++; + if ( r_useClippedLightScissors.GetInteger() ) { + return R_ClippedLightScissorRectangle( vLight ); + } else { + r.x1 = r.y1 = 0; + r.x2 = ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ) - 1; + r.y2 = ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ) - 1; + return r; + } + } + + R_TransformClipToDevice( clip, tr.viewDef, ndc ); + + float windowX = 0.5f * ( 1.0f + ndc[0] ) * ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ); + float windowY = 0.5f * ( 1.0f + ndc[1] ) * ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ); + + if ( windowX > tr.viewDef->scissor.x2 ) { + windowX = tr.viewDef->scissor.x2; + } else if ( windowX < tr.viewDef->scissor.x1 ) { + windowX = tr.viewDef->scissor.x1; + } + if ( windowY > tr.viewDef->scissor.y2 ) { + windowY = tr.viewDef->scissor.y2; + } else if ( windowY < tr.viewDef->scissor.y1 ) { + windowY = tr.viewDef->scissor.y1; + } + + r.AddPoint( windowX, windowY ); + } + + // add the fudge boundary + r.Expand(); + + c_unclippedLight++; + + return r; +} + +/* +================= +R_AddLightSurfaces + +Calc the light shader values, removing any light from the viewLight list +if it is determined to not have any visible effect due to being flashed off or turned off. + +Adds entities to the viewEntity list if they are needed for shadow casting. + +Add any precomputed shadow volumes. + +Removes lights from the viewLights list if they are completely +turned off, or completely off screen. + +Create any new interactions needed between the viewLights +and the viewEntitys due to game movement +================= +*/ +void R_AddLightSurfaces( void ) { + viewLight_t *vLight; + idRenderLightLocal *light; + viewLight_t **ptr; + + // go through each visible light, possibly removing some from the list + ptr = &tr.viewDef->viewLights; + while ( *ptr ) { + vLight = *ptr; + light = vLight->lightDef; + + const idMaterial *lightShader = light->lightShader; + if ( !lightShader ) { + common->Error( "R_AddLightSurfaces: NULL lightShader" ); + } + + // see if we are suppressing the light in this view + if ( !r_skipSuppress.GetBool() ) { + if ( light->parms.suppressLightInViewID + && light->parms.suppressLightInViewID == tr.viewDef->renderView.viewID ) { + *ptr = vLight->next; + light->viewCount = -1; + continue; + } + if ( light->parms.allowLightInViewID + && light->parms.allowLightInViewID != tr.viewDef->renderView.viewID ) { + *ptr = vLight->next; + light->viewCount = -1; + continue; + } + } + + // evaluate the light shader registers + float *lightRegs =(float *)R_FrameAlloc( lightShader->GetNumRegisters() * sizeof( float ) ); + vLight->shaderRegisters = lightRegs; + lightShader->EvaluateRegisters( lightRegs, light->parms.shaderParms, tr.viewDef, light->parms.referenceSound ); + + // if this is a purely additive light and no stage in the light shader evaluates + // to a positive light value, we can completely skip the light + if ( !lightShader->IsFogLight() && !lightShader->IsBlendLight() ) { + int lightStageNum; + for ( lightStageNum = 0 ; lightStageNum < lightShader->GetNumStages() ; lightStageNum++ ) { + const shaderStage_t *lightStage = lightShader->GetStage( lightStageNum ); + + // ignore stages that fail the condition + if ( !lightRegs[ lightStage->conditionRegister ] ) { + continue; + } + + const int *registers = lightStage->color.registers; + + // snap tiny values to zero to avoid lights showing up with the wrong color + if ( lightRegs[ registers[0] ] < 0.001f ) { + lightRegs[ registers[0] ] = 0.0f; + } + if ( lightRegs[ registers[1] ] < 0.001f ) { + lightRegs[ registers[1] ] = 0.0f; + } + if ( lightRegs[ registers[2] ] < 0.001f ) { + lightRegs[ registers[2] ] = 0.0f; + } + + // FIXME: when using the following values the light shows up bright red when using nvidia drivers/hardware + // this seems to have been fixed ? + //lightRegs[ registers[0] ] = 1.5143074e-005f; + //lightRegs[ registers[1] ] = 1.5483369e-005f; + //lightRegs[ registers[2] ] = 1.7014690e-005f; + + if ( lightRegs[ registers[0] ] > 0.0f || + lightRegs[ registers[1] ] > 0.0f || + lightRegs[ registers[2] ] > 0.0f ) { + break; + } + } + if ( lightStageNum == lightShader->GetNumStages() ) { + // we went through all the stages and didn't find one that adds anything + // remove the light from the viewLights list, and change its frame marker + // so interaction generation doesn't think the light is visible and + // create a shadow for it + *ptr = vLight->next; + light->viewCount = -1; + continue; + } + } + + if ( r_useLightScissors.GetBool() ) { + // calculate the screen area covered by the light frustum + // which will be used to crop the stencil cull + idScreenRect scissorRect = R_CalcLightScissorRectangle( vLight ); + // intersect with the portal crossing scissor rectangle + vLight->scissorRect.Intersect( scissorRect ); + + if ( r_showLightScissors.GetBool() ) { + R_ShowColoredScreenRect( vLight->scissorRect, light->index ); + } + } + +#if 0 + // this never happens, because CullLightByPortals() does a more precise job + if ( vLight->scissorRect.IsEmpty() ) { + // this light doesn't touch anything on screen, so remove it from the list + *ptr = vLight->next; + continue; + } +#endif + + // this one stays on the list + ptr = &vLight->next; + + // if we are doing a soft-shadow novelty test, regenerate the light with + // a random offset every time + if ( r_lightSourceRadius.GetFloat() != 0.0f ) { + for ( int i = 0 ; i < 3 ; i++ ) { + light->globalLightOrigin[i] += r_lightSourceRadius.GetFloat() * ( -1 + 2 * (rand()&0xfff)/(float)0xfff ); + } + } + + // create interactions with all entities the light may touch, and add viewEntities + // that may cast shadows, even if they aren't directly visible. Any real work + // will be deferred until we walk through the viewEntities + tr.viewDef->renderWorld->CreateLightDefInteractions( light ); + tr.pc.c_viewLights++; + + // fog lights will need to draw the light frustum triangles, so make sure they + // are in the vertex cache + if ( lightShader->IsFogLight() ) { + if ( !light->frustumTris->ambientCache ) { + if ( !R_CreateAmbientCache( light->frustumTris, false ) ) { + // skip if we are out of vertex memory + continue; + } + } + // touch the surface so it won't get purged + vertexCache.Touch( light->frustumTris->ambientCache ); + } + + // add the prelight shadows for the static world geometry + if ( light->parms.prelightModel && r_useOptimizedShadows.GetBool() ) { + + if ( !light->parms.prelightModel->NumSurfaces() ) { + common->Error( "no surfs in prelight model '%s'", light->parms.prelightModel->Name() ); + } + + srfTriangles_t *tri = light->parms.prelightModel->Surface( 0 )->geometry; + if ( !tri->shadowVertexes ) { + common->Error( "R_AddLightSurfaces: prelight model '%s' without shadowVertexes", light->parms.prelightModel->Name() ); + } + + // these shadows will all have valid bounds, and can be culled normally + if ( r_useShadowCulling.GetBool() ) { + if ( R_CullLocalBox( tri->bounds, tr.viewDef->worldSpace.modelMatrix, 5, tr.viewDef->frustum ) ) { + continue; + } + } + + // if we have been purged, re-upload the shadowVertexes + if ( !tri->shadowCache ) { + R_CreatePrivateShadowCache( tri ); + if ( !tri->shadowCache ) { + continue; + } + } + + // touch the shadow surface so it won't get purged + vertexCache.Touch( tri->shadowCache ); + + if ( !tri->indexCache && r_useIndexBuffers.GetBool() ) { + vertexCache.Alloc( tri->indexes, tri->numIndexes * sizeof( tri->indexes[0] ), &tri->indexCache, true ); + } + if ( tri->indexCache ) { + vertexCache.Touch( tri->indexCache ); + } + + R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, true /* FIXME? */ ); + } + } +} + +//=============================================================================================================== + +/* +================== +R_IssueEntityDefCallback +================== +*/ +bool R_IssueEntityDefCallback( idRenderEntityLocal *def ) { + bool update; + idBounds oldBounds; + + if ( r_checkBounds.GetBool() ) { + oldBounds = def->referenceBounds; + } + + def->archived = false; // will need to be written to the demo file + tr.pc.c_entityDefCallbacks++; + if ( tr.viewDef ) { + update = def->parms.callback( &def->parms, &tr.viewDef->renderView ); + } else { + update = def->parms.callback( &def->parms, NULL ); + } + + if ( !def->parms.hModel ) { + common->Error( "R_IssueEntityDefCallback: dynamic entity callback didn't set model" ); + } + + if ( r_checkBounds.GetBool() ) { + if ( oldBounds[0][0] > def->referenceBounds[0][0] + CHECK_BOUNDS_EPSILON || + oldBounds[0][1] > def->referenceBounds[0][1] + CHECK_BOUNDS_EPSILON || + oldBounds[0][2] > def->referenceBounds[0][2] + CHECK_BOUNDS_EPSILON || + oldBounds[1][0] < def->referenceBounds[1][0] - CHECK_BOUNDS_EPSILON || + oldBounds[1][1] < def->referenceBounds[1][1] - CHECK_BOUNDS_EPSILON || + oldBounds[1][2] < def->referenceBounds[1][2] - CHECK_BOUNDS_EPSILON ) { + common->Printf( "entity %i callback extended reference bounds\n", def->index ); + } + } + + return update; +} + +/* +=================== +R_EntityDefDynamicModel + +Issues a deferred entity callback if necessary. +If the model isn't dynamic, it returns the original. +Returns the cached dynamic model if present, otherwise creates +it and any necessary overlays +=================== +*/ +idRenderModel *R_EntityDefDynamicModel( idRenderEntityLocal *def ) { + bool callbackUpdate; + + // allow deferred entities to construct themselves + if ( def->parms.callback ) { + callbackUpdate = R_IssueEntityDefCallback( def ); + } else { + callbackUpdate = false; + } + + idRenderModel *model = def->parms.hModel; + + if ( !model ) { + common->Error( "R_EntityDefDynamicModel: NULL model" ); + } + + if ( model->IsDynamicModel() == DM_STATIC ) { + def->dynamicModel = NULL; + def->dynamicModelFrameCount = 0; + return model; + } + + // continously animating models (particle systems, etc) will have their snapshot updated every single view + if ( callbackUpdate || ( model->IsDynamicModel() == DM_CONTINUOUS && def->dynamicModelFrameCount != tr.frameCount ) ) { + R_ClearEntityDefDynamicModel( def ); + } + + // if we don't have a snapshot of the dynamic model, generate it now + if ( !def->dynamicModel ) { + + // instantiate the snapshot of the dynamic model, possibly reusing memory from the cached snapshot + def->cachedDynamicModel = model->InstantiateDynamicModel( &def->parms, tr.viewDef, def->cachedDynamicModel ); + + if ( def->cachedDynamicModel ) { + + // add any overlays to the snapshot of the dynamic model + if ( def->overlay && !r_skipOverlays.GetBool() ) { + def->overlay->AddOverlaySurfacesToModel( def->cachedDynamicModel ); + } else { + idRenderModelOverlay::RemoveOverlaySurfacesFromModel( def->cachedDynamicModel ); + } + + if ( r_checkBounds.GetBool() ) { + idBounds b = def->cachedDynamicModel->Bounds(); + if ( b[0][0] < def->referenceBounds[0][0] - CHECK_BOUNDS_EPSILON || + b[0][1] < def->referenceBounds[0][1] - CHECK_BOUNDS_EPSILON || + b[0][2] < def->referenceBounds[0][2] - CHECK_BOUNDS_EPSILON || + b[1][0] > def->referenceBounds[1][0] + CHECK_BOUNDS_EPSILON || + b[1][1] > def->referenceBounds[1][1] + CHECK_BOUNDS_EPSILON || + b[1][2] > def->referenceBounds[1][2] + CHECK_BOUNDS_EPSILON ) { + common->Printf( "entity %i dynamic model exceeded reference bounds\n", def->index ); + } + } + } + + def->dynamicModel = def->cachedDynamicModel; + def->dynamicModelFrameCount = tr.frameCount; + } + + // set model depth hack value + if ( def->dynamicModel && model->DepthHack() != 0.0f && tr.viewDef ) { + idPlane eye, clip; + idVec3 ndc; + R_TransformModelToClip( def->parms.origin, tr.viewDef->worldSpace.modelViewMatrix, tr.viewDef->projectionMatrix, eye, clip ); + R_TransformClipToDevice( clip, tr.viewDef, ndc ); + def->parms.modelDepthHack = model->DepthHack() * ( 1.0f - ndc.z ); + } + + // FIXME: if any of the surfaces have deforms, create a frame-temporary model with references to the + // undeformed surfaces. This would allow deforms to be light interacting. + + return def->dynamicModel; +} + +/* +================= +R_AddDrawSurf +================= +*/ +void R_AddDrawSurf( const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, + const idMaterial *shader, const idScreenRect &scissor ) { + drawSurf_t *drawSurf; + const float *shaderParms; + static float refRegs[MAX_EXPRESSION_REGISTERS]; // don't put on stack, or VC++ will do a page touch + float generatedShaderParms[MAX_ENTITY_SHADER_PARMS]; + + drawSurf = (drawSurf_t *)R_FrameAlloc( sizeof( *drawSurf ) ); + drawSurf->geo = tri; + drawSurf->space = space; + drawSurf->material = shader; + drawSurf->scissorRect = scissor; + drawSurf->sort = shader->GetSort() + tr.sortOffset; + drawSurf->dsFlags = 0; + + // bumping this offset each time causes surfaces with equal sort orders to still + // deterministically draw in the order they are added + tr.sortOffset += 0.000001f; + + // if it doesn't fit, resize the list + if ( tr.viewDef->numDrawSurfs == tr.viewDef->maxDrawSurfs ) { + drawSurf_t **old = tr.viewDef->drawSurfs; + int count; + + if ( tr.viewDef->maxDrawSurfs == 0 ) { + tr.viewDef->maxDrawSurfs = INITIAL_DRAWSURFS; + count = 0; + } else { + count = tr.viewDef->maxDrawSurfs * sizeof( tr.viewDef->drawSurfs[0] ); + tr.viewDef->maxDrawSurfs *= 2; + } + tr.viewDef->drawSurfs = (drawSurf_t **)R_FrameAlloc( tr.viewDef->maxDrawSurfs * sizeof( tr.viewDef->drawSurfs[0] ) ); + memcpy( tr.viewDef->drawSurfs, old, count ); + } + tr.viewDef->drawSurfs[tr.viewDef->numDrawSurfs] = drawSurf; + tr.viewDef->numDrawSurfs++; + + // process the shader expressions for conditionals / color / texcoords + const float *constRegs = shader->ConstantRegisters(); + if ( constRegs ) { + // shader only uses constant values + drawSurf->shaderRegisters = constRegs; + } else { + float *regs = (float *)R_FrameAlloc( shader->GetNumRegisters() * sizeof( float ) ); + drawSurf->shaderRegisters = regs; + + // a reference shader will take the calculated stage color value from another shader + // and use that for the parm0-parm3 of the current shader, which allows a stage of + // a light model and light flares to pick up different flashing tables from + // different light shaders + if ( renderEntity->referenceShader ) { + // evaluate the reference shader to find our shader parms + const shaderStage_t *pStage; + + renderEntity->referenceShader->EvaluateRegisters( refRegs, renderEntity->shaderParms, tr.viewDef, renderEntity->referenceSound ); + pStage = renderEntity->referenceShader->GetStage(0); + + memcpy( generatedShaderParms, renderEntity->shaderParms, sizeof( generatedShaderParms ) ); + generatedShaderParms[0] = refRegs[ pStage->color.registers[0] ]; + generatedShaderParms[1] = refRegs[ pStage->color.registers[1] ]; + generatedShaderParms[2] = refRegs[ pStage->color.registers[2] ]; + + shaderParms = generatedShaderParms; + } else { + // evaluate with the entityDef's shader parms + shaderParms = renderEntity->shaderParms; + } + + float oldFloatTime; + int oldTime; + + if ( space->entityDef && space->entityDef->parms.timeGroup ) { + oldFloatTime = tr.viewDef->floatTime; + oldTime = tr.viewDef->renderView.time; + + tr.viewDef->floatTime = game->GetTimeGroupTime( space->entityDef->parms.timeGroup ) * 0.001; + tr.viewDef->renderView.time = game->GetTimeGroupTime( space->entityDef->parms.timeGroup ); + } + + shader->EvaluateRegisters( regs, shaderParms, tr.viewDef, renderEntity->referenceSound ); + + if ( space->entityDef && space->entityDef->parms.timeGroup ) { + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + } + + // check for deformations + R_DeformDrawSurf( drawSurf ); + + // skybox surfaces need a dynamic texgen + switch( shader->Texgen() ) { + case TG_SKYBOX_CUBE: + R_SkyboxTexGen( drawSurf, tr.viewDef->renderView.vieworg ); + break; + case TG_WOBBLESKY_CUBE: + R_WobbleskyTexGen( drawSurf, tr.viewDef->renderView.vieworg ); + break; + } + + // check for gui surfaces + idUserInterface *gui = NULL; + + if ( !space->entityDef ) { + gui = shader->GlobalGui(); + } else { + int guiNum = shader->GetEntityGui() - 1; + if ( guiNum >= 0 && guiNum < MAX_RENDERENTITY_GUI ) { + gui = renderEntity->gui[ guiNum ]; + } + if ( gui == NULL ) { + gui = shader->GlobalGui(); + } + } + + if ( gui ) { + // force guis on the fast time + float oldFloatTime; + int oldTime; + + oldFloatTime = tr.viewDef->floatTime; + oldTime = tr.viewDef->renderView.time; + + tr.viewDef->floatTime = game->GetTimeGroupTime( 1 ) * 0.001; + tr.viewDef->renderView.time = game->GetTimeGroupTime( 1 ); + + idBounds ndcBounds; + + if ( !R_PreciseCullSurface( drawSurf, ndcBounds ) ) { + // did we ever use this to forward an entity color to a gui that didn't set color? +// memcpy( tr.guiShaderParms, shaderParms, sizeof( tr.guiShaderParms ) ); + R_RenderGuiSurf( gui, drawSurf ); + } + + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + + // we can't add subviews at this point, because that would + // increment tr.viewCount, messing up the rest of the surface + // adds for this view +} + +/* +=============== +R_AddAmbientDrawsurfs + +Adds surfaces for the given viewEntity +Walks through the viewEntitys list and creates drawSurf_t for each surface of +each viewEntity that has a non-empty scissorRect +=============== +*/ +static void R_AddAmbientDrawsurfs( viewEntity_t *vEntity ) { + int i, total; + idRenderEntityLocal *def; + srfTriangles_t *tri; + idRenderModel *model; + const idMaterial *shader; + + def = vEntity->entityDef; + + if ( def->dynamicModel ) { + model = def->dynamicModel; + } else { + model = def->parms.hModel; + } + + // add all the surfaces + total = model->NumSurfaces(); + for ( i = 0 ; i < total ; i++ ) { + const modelSurface_t *surf = model->Surface( i ); + + // for debugging, only show a single surface at a time + if ( r_singleSurface.GetInteger() >= 0 && i != r_singleSurface.GetInteger() ) { + continue; + } + + tri = surf->geometry; + if ( !tri ) { + continue; + } + if ( !tri->numIndexes ) { + continue; + } + shader = surf->shader; + shader = R_RemapShaderBySkin( shader, def->parms.customSkin, def->parms.customShader ); + + R_GlobalShaderOverride( &shader ); + + if ( !shader ) { + continue; + } + if ( !shader->IsDrawn() ) { + continue; + } + + // debugging tool to make sure we are have the correct pre-calculated bounds + if ( r_checkBounds.GetBool() ) { + int j, k; + for ( j = 0 ; j < tri->numVerts ; j++ ) { + for ( k = 0 ; k < 3 ; k++ ) { + if ( tri->verts[j].xyz[k] > tri->bounds[1][k] + CHECK_BOUNDS_EPSILON + || tri->verts[j].xyz[k] < tri->bounds[0][k] - CHECK_BOUNDS_EPSILON ) { + common->Printf( "bad tri->bounds on %s:%s\n", def->parms.hModel->Name(), shader->GetName() ); + break; + } + if ( tri->verts[j].xyz[k] > def->referenceBounds[1][k] + CHECK_BOUNDS_EPSILON + || tri->verts[j].xyz[k] < def->referenceBounds[0][k] - CHECK_BOUNDS_EPSILON ) { + common->Printf( "bad referenceBounds on %s:%s\n", def->parms.hModel->Name(), shader->GetName() ); + break; + } + } + if ( k != 3 ) { + break; + } + } + } + + if ( !R_CullLocalBox( tri->bounds, vEntity->modelMatrix, 5, tr.viewDef->frustum ) ) { + + def->visibleCount = tr.viewCount; + + // make sure we have an ambient cache + if ( !R_CreateAmbientCache( tri, shader->ReceivesLighting() ) ) { + // don't add anything if the vertex cache was too full to give us an ambient cache + return; + } + // touch it so it won't get purged + vertexCache.Touch( tri->ambientCache ); + + if ( r_useIndexBuffers.GetBool() && !tri->indexCache ) { + vertexCache.Alloc( tri->indexes, tri->numIndexes * sizeof( tri->indexes[0] ), &tri->indexCache, true ); + } + if ( tri->indexCache ) { + vertexCache.Touch( tri->indexCache ); + } + + // add the surface for drawing + R_AddDrawSurf( tri, vEntity, &vEntity->entityDef->parms, shader, vEntity->scissorRect ); + + // ambientViewCount is used to allow light interactions to be rejected + // if the ambient surface isn't visible at all + tri->ambientViewCount = tr.viewCount; + } + } + + // add the lightweight decal surfaces + for ( idRenderModelDecal *decal = def->decals; decal; decal = decal->Next() ) { + decal->AddDecalDrawSurf( vEntity ); + } +} + +/* +================== +R_CalcEntityScissorRectangle +================== +*/ +idScreenRect R_CalcEntityScissorRectangle( viewEntity_t *vEntity ) { + idBounds bounds; + idRenderEntityLocal *def = vEntity->entityDef; + + tr.viewDef->viewFrustum.ProjectionBounds( idBox( def->referenceBounds, def->parms.origin, def->parms.axis ), bounds ); + + return R_ScreenRectFromViewFrustumBounds( bounds ); +} + +/* +=================== +R_AddModelSurfaces + +Here is where dynamic models actually get instantiated, and necessary +interactions get created. This is all done on a sort-by-model basis +to keep source data in cache (most likely L2) as any interactions and +shadows are generated, since dynamic models will typically be lit by +two or more lights. +=================== +*/ +void R_AddModelSurfaces( void ) { + viewEntity_t *vEntity; + idInteraction *inter, *next; + idRenderModel *model; + + // clear the ambient surface list + tr.viewDef->numDrawSurfs = 0; + tr.viewDef->maxDrawSurfs = 0; // will be set to INITIAL_DRAWSURFS on R_AddDrawSurf + + // go through each entity that is either visible to the view, or to + // any light that intersects the view (for shadows) + for ( vEntity = tr.viewDef->viewEntitys; vEntity; vEntity = vEntity->next ) { + + if ( r_useEntityScissors.GetBool() ) { + // calculate the screen area covered by the entity + idScreenRect scissorRect = R_CalcEntityScissorRectangle( vEntity ); + // intersect with the portal crossing scissor rectangle + vEntity->scissorRect.Intersect( scissorRect ); + + if ( r_showEntityScissors.GetBool() ) { + R_ShowColoredScreenRect( vEntity->scissorRect, vEntity->entityDef->index ); + } + } + + float oldFloatTime; + int oldTime; + + game->SelectTimeGroup( vEntity->entityDef->parms.timeGroup ); + + if ( vEntity->entityDef->parms.timeGroup ) { + oldFloatTime = tr.viewDef->floatTime; + oldTime = tr.viewDef->renderView.time; + + tr.viewDef->floatTime = game->GetTimeGroupTime( vEntity->entityDef->parms.timeGroup ) * 0.001; + tr.viewDef->renderView.time = game->GetTimeGroupTime( vEntity->entityDef->parms.timeGroup ); + } + + if ( tr.viewDef->isXraySubview && vEntity->entityDef->parms.xrayIndex == 1 ) { + if ( vEntity->entityDef->parms.timeGroup ) { + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + continue; + } else if ( !tr.viewDef->isXraySubview && vEntity->entityDef->parms.xrayIndex == 2 ) { + if ( vEntity->entityDef->parms.timeGroup ) { + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + continue; + } + + // add the ambient surface if it has a visible rectangle + if ( !vEntity->scissorRect.IsEmpty() ) { + model = R_EntityDefDynamicModel( vEntity->entityDef ); + if ( model == NULL || model->NumSurfaces() <= 0 ) { + if ( vEntity->entityDef->parms.timeGroup ) { + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + continue; + } + + R_AddAmbientDrawsurfs( vEntity ); + tr.pc.c_visibleViewEntities++; + } else { + tr.pc.c_shadowViewEntities++; + } + + // + // for all the entity / light interactions on this entity, add them to the view + // + if ( tr.viewDef->isXraySubview ) { + if ( vEntity->entityDef->parms.xrayIndex == 2 ) { + for ( inter = vEntity->entityDef->firstInteraction; inter != NULL && !inter->IsEmpty(); inter = next ) { + next = inter->entityNext; + if ( inter->lightDef->viewCount != tr.viewCount ) { + continue; + } + inter->AddActiveInteraction(); + } + } + } else { + // all empty interactions are at the end of the list so once the + // first is encountered all the remaining interactions are empty + for ( inter = vEntity->entityDef->firstInteraction; inter != NULL && !inter->IsEmpty(); inter = next ) { + next = inter->entityNext; + + // skip any lights that aren't currently visible + // this is run after any lights that are turned off have already + // been removed from the viewLights list, and had their viewCount cleared + if ( inter->lightDef->viewCount != tr.viewCount ) { + continue; + } + inter->AddActiveInteraction(); + } + } + + if ( vEntity->entityDef->parms.timeGroup ) { + tr.viewDef->floatTime = oldFloatTime; + tr.viewDef->renderView.time = oldTime; + } + + } +} + +/* +===================== +R_RemoveUnecessaryViewLights +===================== +*/ +void R_RemoveUnecessaryViewLights( void ) { + viewLight_t *vLight; + + // go through each visible light + for ( vLight = tr.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + // if the light didn't have any lit surfaces visible, there is no need to + // draw any of the shadows. We still keep the vLight for debugging + // draws + if ( !vLight->localInteractions && !vLight->globalInteractions && !vLight->translucentInteractions ) { + vLight->localShadows = NULL; + vLight->globalShadows = NULL; + } + } + + if ( r_useShadowSurfaceScissor.GetBool() ) { + // shrink the light scissor rect to only intersect the surfaces that will actually be drawn. + // This doesn't seem to actually help, perhaps because the surface scissor + // rects aren't actually the surface, but only the portal clippings. + for ( vLight = tr.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + const drawSurf_t *surf; + idScreenRect surfRect; + + if ( !vLight->lightShader->LightCastsShadows() ) { + continue; + } + + surfRect.Clear(); + + for ( surf = vLight->globalInteractions ; surf ; surf = surf->nextOnLight ) { + surfRect.Union( surf->scissorRect ); + } + for ( surf = vLight->localShadows ; surf ; surf = surf->nextOnLight ) { + const_cast(surf)->scissorRect.Intersect( surfRect ); + } + + for ( surf = vLight->localInteractions ; surf ; surf = surf->nextOnLight ) { + surfRect.Union( surf->scissorRect ); + } + for ( surf = vLight->globalShadows ; surf ; surf = surf->nextOnLight ) { + const_cast(surf)->scissorRect.Intersect( surfRect ); + } + + for ( surf = vLight->translucentInteractions ; surf ; surf = surf->nextOnLight ) { + surfRect.Union( surf->scissorRect ); + } + + vLight->scissorRect.Intersect( surfRect ); + } + } +} diff --git a/renderer/tr_lightrun.cpp b/renderer/tr_lightrun.cpp new file mode 100644 index 000000000..beb9c3a9b --- /dev/null +++ b/renderer/tr_lightrun.cpp @@ -0,0 +1,863 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + + +Prelight models + +"_prelight_", ie "_prelight_light1" + +Static surfaces available to dmap will be processed to optimized +shadow and lit surface geometry + +Entity models are never prelighted. + +Light entity can have a "noPrelight 1" key set to avoid the preprocessing +and carving of the world. A light that will move should usually have this +set. + +Prelight models will usually have multiple surfaces + +Shadow volume surfaces will have the material "_shadowVolume" + +The exact same vertexes as the ambient surfaces will be used for the +non-shadow surfaces, so there is opportunity to share + + +Reference their parent surfaces? +Reference their parent area? + + +If we don't track parts that are in different areas, there will be huge +losses when an areaportal closed door has a light poking slightly +through it. + +There is potential benefit to splitting even the shadow volumes +at area boundaries, but it would involve the possibility of an +extra plane of shadow drawing at the area boundary. + + +interaction lightName numIndexes + +Shadow volume surface + +Surfaces in the world cannot have "no self shadow" properties, because all +the surfaces are considered together for the optimized shadow volume. If +you want no self shadow on a static surface, you must still make it into an +entity so it isn't considered in the prelight. + + +r_hidePrelights +r_hideNonPrelights + + + +each surface could include prelight indexes + +generation procedure in dmap: + +carve original surfaces into areas + +for each light + build shadow volume and beam tree + cut all potentially lit surfaces into the beam tree + move lit fragments into a new optimize group + +optimize groups + +build light models + + + + +*/ + +/* +================================================================================= + +LIGHT TESTING + +================================================================================= +*/ + + +/* +==================== +R_ModulateLights_f + +Modifies the shaderParms on all the lights so the level +designers can easily test different color schemes +==================== +*/ +void R_ModulateLights_f( const idCmdArgs &args ) { + if ( !tr.primaryWorld ) { + return; + } + if ( args.Argc() != 4 ) { + common->Printf( "usage: modulateLights \n" ); + return; + } + + float modulate[3]; + int i; + for ( i = 0 ; i < 3 ; i++ ) { + modulate[i] = atof( args.Argv( i+1 ) ); + } + + int count = 0; + for ( i = 0 ; i < tr.primaryWorld->lightDefs.Num() ; i++ ) { + idRenderLightLocal *light; + + light = tr.primaryWorld->lightDefs[i]; + if ( light ) { + count++; + for ( int j = 0 ; j < 3 ; j++ ) { + light->parms.shaderParms[j] *= modulate[j]; + } + } + } + common->Printf( "modulated %i lights\n", count ); +} + + + +//====================================================================================== + + +/* +=============== +R_CreateEntityRefs + +Creates all needed model references in portal areas, +chaining them to both the area and the entityDef. + +Bumps tr.viewCount. +=============== +*/ +void R_CreateEntityRefs( idRenderEntityLocal *def ) { + int i; + idVec3 transformed[8]; + idVec3 v; + + if ( !def->parms.hModel ) { + def->parms.hModel = renderModelManager->DefaultModel(); + } + + // if the entity hasn't been fully specified due to expensive animation calcs + // for md5 and particles, use the provided conservative bounds. + if ( def->parms.callback ) { + def->referenceBounds = def->parms.bounds; + } else { + def->referenceBounds = def->parms.hModel->Bounds( &def->parms ); + } + + // some models, like empty particles, may not need to be added at all + if ( def->referenceBounds.IsCleared() ) { + return; + } + + if ( r_showUpdates.GetBool() && + ( def->referenceBounds[1][0] - def->referenceBounds[0][0] > 1024 || + def->referenceBounds[1][1] - def->referenceBounds[0][1] > 1024 ) ) { + common->Printf( "big entityRef: %f,%f\n", def->referenceBounds[1][0] - def->referenceBounds[0][0], + def->referenceBounds[1][1] - def->referenceBounds[0][1] ); + } + + for (i = 0 ; i < 8 ; i++) { + v[0] = def->referenceBounds[i&1][0]; + v[1] = def->referenceBounds[(i>>1)&1][1]; + v[2] = def->referenceBounds[(i>>2)&1][2]; + + R_LocalPointToGlobal( def->modelMatrix, v, transformed[i] ); + } + + // bump the view count so we can tell if an + // area already has a reference + tr.viewCount++; + + // push these points down the BSP tree into areas + def->world->PushVolumeIntoTree( def, NULL, 8, transformed ); +} + + +/* +================================================================================= + +CREATE LIGHT REFS + +================================================================================= +*/ + +/* +===================== +R_SetLightProject + +All values are reletive to the origin +Assumes that right and up are not normalized +This is also called by dmap during map processing. +===================== +*/ +void R_SetLightProject( idPlane lightProject[4], const idVec3 origin, const idVec3 target, + const idVec3 rightVector, const idVec3 upVector, const idVec3 start, const idVec3 stop ) { + float dist; + float scale; + float rLen, uLen; + idVec3 normal; + float ofs; + idVec3 right, up; + idVec3 startGlobal; + idVec4 targetGlobal; + + right = rightVector; + rLen = right.Normalize(); + up = upVector; + uLen = up.Normalize(); + normal = up.Cross( right ); +//normal = right.Cross( up ); + normal.Normalize(); + + dist = target * normal; // - ( origin * normal ); + if ( dist < 0 ) { + dist = -dist; + normal = -normal; + } + + scale = ( 0.5f * dist ) / rLen; + right *= scale; + scale = -( 0.5f * dist ) / uLen; + up *= scale; + + lightProject[2] = normal; + lightProject[2][3] = -( origin * lightProject[2].Normal() ); + + lightProject[0] = right; + lightProject[0][3] = -( origin * lightProject[0].Normal() ); + + lightProject[1] = up; + lightProject[1][3] = -( origin * lightProject[1].Normal() ); + + // now offset to center + targetGlobal.ToVec3() = target + origin; + targetGlobal[3] = 1; + ofs = 0.5f - ( targetGlobal * lightProject[0].ToVec4() ) / ( targetGlobal * lightProject[2].ToVec4() ); + lightProject[0].ToVec4() += ofs * lightProject[2].ToVec4(); + ofs = 0.5f - ( targetGlobal * lightProject[1].ToVec4() ) / ( targetGlobal * lightProject[2].ToVec4() ); + lightProject[1].ToVec4() += ofs * lightProject[2].ToVec4(); + + // set the falloff vector + normal = stop - start; + dist = normal.Normalize(); + if ( dist <= 0 ) { + dist = 1; + } + lightProject[3] = normal * ( 1.0f / dist ); + startGlobal = start + origin; + lightProject[3][3] = -( startGlobal * lightProject[3].Normal() ); +} + +/* +=================== +R_SetLightFrustum + +Creates plane equations from the light projection, positive sides +face out of the light +=================== +*/ +void R_SetLightFrustum( const idPlane lightProject[4], idPlane frustum[6] ) { + int i; + + // we want the planes of s=0, s=q, t=0, and t=q + frustum[0] = lightProject[0]; + frustum[1] = lightProject[1]; + frustum[2] = lightProject[2] - lightProject[0]; + frustum[3] = lightProject[2] - lightProject[1]; + + // we want the planes of s=0 and s=1 for front and rear clipping planes + frustum[4] = lightProject[3]; + + frustum[5] = lightProject[3]; + frustum[5][3] -= 1.0f; + frustum[5] = -frustum[5]; + + for ( i = 0 ; i < 6 ; i++ ) { + float l; + + frustum[i] = -frustum[i]; + l = frustum[i].Normalize(); + frustum[i][3] /= l; + } +} + +/* +==================== +R_FreeLightDefFrustum +==================== +*/ +void R_FreeLightDefFrustum( idRenderLightLocal *ldef ) { + int i; + + // free the frustum tris + if ( ldef->frustumTris ) { + R_FreeStaticTriSurf( ldef->frustumTris ); + ldef->frustumTris = NULL; + } + // free frustum windings + for ( i = 0; i < 6; i++ ) { + if ( ldef->frustumWindings[i] ) { + delete ldef->frustumWindings[i]; + ldef->frustumWindings[i] = NULL; + } + } +} + +/* +================= +R_DeriveLightData + +Fills everything in based on light->parms +================= +*/ +void R_DeriveLightData( idRenderLightLocal *light ) { + int i; + + // decide which light shader we are going to use + if ( light->parms.shader ) { + light->lightShader = light->parms.shader; + } + if ( !light->lightShader ) { + if ( light->parms.pointLight ) { + light->lightShader = declManager->FindMaterial( "lights/defaultPointLight" ); + } else { + light->lightShader = declManager->FindMaterial( "lights/defaultProjectedLight" ); + } + } + + // get the falloff image + light->falloffImage = light->lightShader->LightFalloffImage(); + if ( !light->falloffImage ) { + // use the falloff from the default shader of the correct type + const idMaterial *defaultShader; + + if ( light->parms.pointLight ) { + defaultShader = declManager->FindMaterial( "lights/defaultPointLight" ); + light->falloffImage = defaultShader->LightFalloffImage(); + } else { + // projected lights by default don't diminish with distance + defaultShader = declManager->FindMaterial( "lights/defaultProjectedLight" ); + light->falloffImage = defaultShader->LightFalloffImage(); + } + } + + // set the projection + if ( !light->parms.pointLight ) { + // projected light + + R_SetLightProject( light->lightProject, vec3_origin /* light->parms.origin */, light->parms.target, + light->parms.right, light->parms.up, light->parms.start, light->parms.end); + } else { + // point light + memset( light->lightProject, 0, sizeof( light->lightProject ) ); + light->lightProject[0][0] = 0.5f / light->parms.lightRadius[0]; + light->lightProject[1][1] = 0.5f / light->parms.lightRadius[1]; + light->lightProject[3][2] = 0.5f / light->parms.lightRadius[2]; + light->lightProject[0][3] = 0.5f; + light->lightProject[1][3] = 0.5f; + light->lightProject[2][3] = 1.0f; + light->lightProject[3][3] = 0.5f; + } + + // set the frustum planes + R_SetLightFrustum( light->lightProject, light->frustum ); + + // rotate the light planes and projections by the axis + R_AxisToModelMatrix( light->parms.axis, light->parms.origin, light->modelMatrix ); + + for ( i = 0 ; i < 6 ; i++ ) { + idPlane temp; + temp = light->frustum[i]; + R_LocalPlaneToGlobal( light->modelMatrix, temp, light->frustum[i] ); + } + for ( i = 0 ; i < 4 ; i++ ) { + idPlane temp; + temp = light->lightProject[i]; + R_LocalPlaneToGlobal( light->modelMatrix, temp, light->lightProject[i] ); + } + + // adjust global light origin for off center projections and parallel projections + // we are just faking parallel by making it a very far off center for now + if ( light->parms.parallel ) { + idVec3 dir; + + dir = light->parms.lightCenter; + if ( !dir.Normalize() ) { + // make point straight up if not specified + dir[2] = 1; + } + light->globalLightOrigin = light->parms.origin + dir * 100000; + } else { + light->globalLightOrigin = light->parms.origin + light->parms.axis * light->parms.lightCenter; + } + + R_FreeLightDefFrustum( light ); + + light->frustumTris = R_PolytopeSurface( 6, light->frustum, light->frustumWindings ); + + // a projected light will have one shadowFrustum, a point light will have + // six unless the light center is outside the box + R_MakeShadowFrustums( light ); +} + +/* +================= +R_CreateLightRefs +================= +*/ +#define MAX_LIGHT_VERTS 40 +void R_CreateLightRefs( idRenderLightLocal *light ) { + idVec3 points[MAX_LIGHT_VERTS]; + int i; + srfTriangles_t *tri; + + tri = light->frustumTris; + + // because a light frustum is made of only six intersecting planes, + // we should never be able to get a stupid number of points... + if ( tri->numVerts > MAX_LIGHT_VERTS ) { + common->Error( "R_CreateLightRefs: %i points in frustumTris!", tri->numVerts ); + } + for ( i = 0 ; i < tri->numVerts ; i++ ) { + points[i] = tri->verts[i].xyz; + } + + if ( r_showUpdates.GetBool() && ( tri->bounds[1][0] - tri->bounds[0][0] > 1024 || + tri->bounds[1][1] - tri->bounds[0][1] > 1024 ) ) { + common->Printf( "big lightRef: %f,%f\n", tri->bounds[1][0] - tri->bounds[0][0] + ,tri->bounds[1][1] - tri->bounds[0][1] ); + } + + // determine the areaNum for the light origin, which may let us + // cull the light if it is behind a closed door + // it is debatable if we want to use the entity origin or the center offset origin, + // but we definitely don't want to use a parallel offset origin + light->areaNum = light->world->PointInArea( light->globalLightOrigin ); + if ( light->areaNum == -1 ) { + light->areaNum = light->world->PointInArea( light->parms.origin ); + } + + // bump the view count so we can tell if an + // area already has a reference + tr.viewCount++; + + // if we have a prelight model that includes all the shadows for the major world occluders, + // we can limit the area references to those visible through the portals from the light center. + // We can't do this in the normal case, because shadows are cast from back facing triangles, which + // may be in areas not directly visible to the light projection center. + if ( light->parms.prelightModel && r_useLightPortalFlow.GetBool() && light->lightShader->LightCastsShadows() ) { + light->world->FlowLightThroughPortals( light ); + } else { + // push these points down the BSP tree into areas + light->world->PushVolumeIntoTree( NULL, light, tri->numVerts, points ); + } +} + +/* +=============== +R_RenderLightFrustum + +Called by the editor and dmap to operate on light volumes +=============== +*/ +void R_RenderLightFrustum( const renderLight_t &renderLight, idPlane lightFrustum[6] ) { + idRenderLightLocal fakeLight; + + memset( &fakeLight, 0, sizeof( fakeLight ) ); + fakeLight.parms = renderLight; + + R_DeriveLightData( &fakeLight ); + + R_FreeStaticTriSurf( fakeLight.frustumTris ); + + for ( int i = 0 ; i < 6 ; i++ ) { + lightFrustum[i] = fakeLight.frustum[i]; + } +} + + +//================================================================================= + +/* +=============== +WindingCompletelyInsideLight +=============== +*/ +bool WindingCompletelyInsideLight( const idWinding *w, const idRenderLightLocal *ldef ) { + int i, j; + + for ( i = 0 ; i < w->GetNumPoints() ; i++ ) { + for ( j = 0 ; j < 6 ; j++ ) { + float d; + + d = (*w)[i].ToVec3() * ldef->frustum[j].Normal() + ldef->frustum[j][3]; + if ( d > 0 ) { + return false; + } + } + } + return true; +} + +/* +====================== +R_CreateLightDefFogPortals + +When a fog light is created or moved, see if it completely +encloses any portals, which may allow them to be fogged closed. +====================== +*/ +void R_CreateLightDefFogPortals( idRenderLightLocal *ldef ) { + areaReference_t *lref; + portalArea_t *area; + + ldef->foggedPortals = NULL; + + if ( !ldef->lightShader->IsFogLight() ) { + return; + } + + // some fog lights will explicitly disallow portal fogging + if ( ldef->lightShader->TestMaterialFlag( MF_NOPORTALFOG ) ) { + return; + } + + for ( lref = ldef->references ; lref ; lref = lref->ownerNext ) { + // check all the models in this area + area = lref->area; + + portal_t *prt; + doublePortal_t *dp; + + for ( prt = area->portals ; prt ; prt = prt->next ) { + dp = prt->doublePortal; + + // we only handle a single fog volume covering a portal + // this will never cause incorrect drawing, but it may + // fail to cull a portal + if ( dp->fogLight ) { + continue; + } + + if ( WindingCompletelyInsideLight( prt->w, ldef ) ) { + dp->fogLight = ldef; + dp->nextFoggedPortal = ldef->foggedPortals; + ldef->foggedPortals = dp; + } + } + } +} + +/* +==================== +R_FreeLightDefDerivedData + +Frees all references and lit surfaces from the light +==================== +*/ +void R_FreeLightDefDerivedData( idRenderLightLocal *ldef ) { + areaReference_t *lref, *nextRef; + + // rmove any portal fog references + for ( doublePortal_t *dp = ldef->foggedPortals ; dp ; dp = dp->nextFoggedPortal ) { + dp->fogLight = NULL; + } + + // free all the interactions + while ( ldef->firstInteraction != NULL ) { + ldef->firstInteraction->UnlinkAndFree(); + } + + // free all the references to the light + for ( lref = ldef->references ; lref ; lref = nextRef ) { + nextRef = lref->ownerNext; + + // unlink from the area + lref->areaNext->areaPrev = lref->areaPrev; + lref->areaPrev->areaNext = lref->areaNext; + + // put it back on the free list for reuse + ldef->world->areaReferenceAllocator.Free( lref ); + } + ldef->references = NULL; + + R_FreeLightDefFrustum( ldef ); +} + +/* +=================== +R_FreeEntityDefDerivedData + +Used by both RE_FreeEntityDef and RE_UpdateEntityDef +Does not actually free the entityDef. +=================== +*/ +void R_FreeEntityDefDerivedData( idRenderEntityLocal *def, bool keepDecals, bool keepCachedDynamicModel ) { + int i; + areaReference_t *ref, *next; + + // demo playback needs to free the joints, while normal play + // leaves them in the control of the game + if ( session->readDemo ) { + if ( def->parms.joints ) { + Mem_Free16( def->parms.joints ); + def->parms.joints = NULL; + } + if ( def->parms.callbackData ) { + Mem_Free( def->parms.callbackData ); + def->parms.callbackData = NULL; + } + for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { + if ( def->parms.gui[ i ] ) { + delete def->parms.gui[ i ]; + def->parms.gui[ i ] = NULL; + } + } + } + + // free all the interactions + while ( def->firstInteraction != NULL ) { + def->firstInteraction->UnlinkAndFree(); + } + + // clear the dynamic model if present + if ( def->dynamicModel ) { + def->dynamicModel = NULL; + } + + if ( !keepDecals ) { + R_FreeEntityDefDecals( def ); + R_FreeEntityDefOverlay( def ); + } + + if ( !keepCachedDynamicModel ) { + delete def->cachedDynamicModel; + def->cachedDynamicModel = NULL; + } + + // free the entityRefs from the areas + for ( ref = def->entityRefs ; ref ; ref = next ) { + next = ref->ownerNext; + + // unlink from the area + ref->areaNext->areaPrev = ref->areaPrev; + ref->areaPrev->areaNext = ref->areaNext; + + // put it back on the free list for reuse + def->world->areaReferenceAllocator.Free( ref ); + } + def->entityRefs = NULL; +} + +/* +================== +R_ClearEntityDefDynamicModel + +If we know the reference bounds stays the same, we +only need to do this on entity update, not the full +R_FreeEntityDefDerivedData +================== +*/ +void R_ClearEntityDefDynamicModel( idRenderEntityLocal *def ) { + // free all the interaction surfaces + for( idInteraction *inter = def->firstInteraction; inter != NULL && !inter->IsEmpty(); inter = inter->entityNext ) { + inter->FreeSurfaces(); + } + + // clear the dynamic model if present + if ( def->dynamicModel ) { + def->dynamicModel = NULL; + } +} + +/* +=================== +R_FreeEntityDefDecals +=================== +*/ +void R_FreeEntityDefDecals( idRenderEntityLocal *def ) { + while( def->decals ) { + idRenderModelDecal *next = def->decals->Next(); + idRenderModelDecal::Free( def->decals ); + def->decals = next; + } +} + +/* +=================== +R_FreeEntityDefFadedDecals +=================== +*/ +void R_FreeEntityDefFadedDecals( idRenderEntityLocal *def, int time ) { + def->decals = idRenderModelDecal::RemoveFadedDecals( def->decals, time ); +} + +/* +=================== +R_FreeEntityDefOverlay +=================== +*/ +void R_FreeEntityDefOverlay( idRenderEntityLocal *def ) { + if ( def->overlay ) { + idRenderModelOverlay::Free( def->overlay ); + def->overlay = NULL; + } +} + +/* +=================== +R_FreeDerivedData + +ReloadModels and RegenerateWorld call this +// FIXME: need to do this for all worlds +=================== +*/ +void R_FreeDerivedData( void ) { + int i, j; + idRenderWorldLocal *rw; + idRenderEntityLocal *def; + idRenderLightLocal *light; + + for ( j = 0; j < tr.worlds.Num(); j++ ) { + rw = tr.worlds[j]; + + for ( i = 0; i < rw->entityDefs.Num(); i++ ) { + def = rw->entityDefs[i]; + if ( !def ) { + continue; + } + R_FreeEntityDefDerivedData( def, false, false ); + } + + for ( i = 0; i < rw->lightDefs.Num(); i++ ) { + light = rw->lightDefs[i]; + if ( !light ) { + continue; + } + R_FreeLightDefDerivedData( light ); + } + } +} + +/* +=================== +R_CheckForEntityDefsUsingModel +=================== +*/ +void R_CheckForEntityDefsUsingModel( idRenderModel *model ) { + int i, j; + idRenderWorldLocal *rw; + idRenderEntityLocal *def; + + for ( j = 0; j < tr.worlds.Num(); j++ ) { + rw = tr.worlds[j]; + + for ( i = 0 ; i < rw->entityDefs.Num(); i++ ) { + def = rw->entityDefs[i]; + if ( !def ) { + continue; + } + if ( def->parms.hModel == model ) { + //assert( 0 ); + // this should never happen but Radiant messes it up all the time so just free the derived data + R_FreeEntityDefDerivedData( def, false, false ); + } + } + } +} + +/* +=================== +R_ReCreateWorldReferences + +ReloadModels and RegenerateWorld call this +// FIXME: need to do this for all worlds +=================== +*/ +void R_ReCreateWorldReferences( void ) { + int i, j; + idRenderWorldLocal *rw; + idRenderEntityLocal *def; + idRenderLightLocal *light; + + // let the interaction generation code know this shouldn't be optimized for + // a particular view + tr.viewDef = NULL; + + for ( j = 0; j < tr.worlds.Num(); j++ ) { + rw = tr.worlds[j]; + + for ( i = 0 ; i < rw->entityDefs.Num() ; i++ ) { + def = rw->entityDefs[i]; + if ( !def ) { + continue; + } + // the world model entities are put specifically in a single + // area, instead of just pushing their bounds into the tree + if ( i < rw->numPortalAreas ) { + rw->AddEntityRefToArea( def, &rw->portalAreas[i] ); + } else { + R_CreateEntityRefs( def ); + } + } + + for ( i = 0 ; i < rw->lightDefs.Num() ; i++ ) { + light = rw->lightDefs[i]; + if ( !light ) { + continue; + } + renderLight_t parms = light->parms; + + light->world->FreeLightDef( i ); + rw->UpdateLightDef( i, &parms ); + } + } +} + +/* +=================== +R_RegenerateWorld_f + +Frees and regenerates all references and interactions, which +must be done when switching between display list mode and immediate mode +=================== +*/ +void R_RegenerateWorld_f( const idCmdArgs &args ) { + R_FreeDerivedData(); + + // watch how much memory we allocate + tr.staticAllocCount = 0; + + R_ReCreateWorldReferences(); + + common->Printf( "Regenerated world, staticAllocCount = %i.\n", tr.staticAllocCount ); +} diff --git a/renderer/tr_local.h b/renderer/tr_local.h new file mode 100644 index 000000000..27119ad8b --- /dev/null +++ b/renderer/tr_local.h @@ -0,0 +1,1678 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __TR_LOCAL_H__ +#define __TR_LOCAL_H__ + +#include "Image.h" +#include "MegaTexture.h" + +class idRenderWorldLocal; + +// everything that is needed by the backend needs +// to be double buffered to allow it to run in +// parallel on a dual cpu machine +const int SMP_FRAMES = 1; + +const int FALLOFF_TEXTURE_SIZE = 64; + +const float DEFAULT_FOG_DISTANCE = 500.0f; + +const int FOG_ENTER_SIZE = 64; +const float FOG_ENTER = (FOG_ENTER_SIZE+1.0f)/(FOG_ENTER_SIZE*2); +// picky to get the bilerp correct at terminator + + +// idScreenRect gets carried around with each drawSurf, so it makes sense +// to keep it compact, instead of just using the idBounds class +class idScreenRect { +public: + short x1, y1, x2, y2; // inclusive pixel bounds inside viewport + float zmin, zmax; // for depth bounds test + + void Clear(); // clear to backwards values + void AddPoint( float x, float y ); // adds a point + void Expand(); // expand by one pixel each way to fix roundoffs + void Intersect( const idScreenRect &rect ); + void Union( const idScreenRect &rect ); + bool Equals( const idScreenRect &rect ) const; + bool IsEmpty() const; +}; + +idScreenRect R_ScreenRectFromViewFrustumBounds( const idBounds &bounds ); +void R_ShowColoredScreenRect( const idScreenRect &rect, int colorIndex ); + +typedef enum { + DC_BAD, + DC_RENDERVIEW, + DC_UPDATE_ENTITYDEF, + DC_DELETE_ENTITYDEF, + DC_UPDATE_LIGHTDEF, + DC_DELETE_LIGHTDEF, + DC_LOADMAP, + DC_CROP_RENDER, + DC_UNCROP_RENDER, + DC_CAPTURE_RENDER, + DC_END_FRAME, + DC_DEFINE_MODEL, + DC_SET_PORTAL_STATE, + DC_UPDATE_SOUNDOCCLUSION, + DC_GUI_MODEL +} demoCommand_t; + +/* +============================================================================== + +SURFACES + +============================================================================== +*/ + +#include "ModelDecal.h" +#include "ModelOverlay.h" +#include "Interaction.h" + + +// drawSurf_t structures command the back end to render surfaces +// a given srfTriangles_t may be used with multiple viewEntity_t, +// as when viewed in a subview or multiple viewport render, or +// with multiple shaders when skinned, or, possibly with multiple +// lights, although currently each lighting interaction creates +// unique srfTriangles_t + +// drawSurf_t are always allocated and freed every frame, they are never cached +static const int DSF_VIEW_INSIDE_SHADOW = 1; + +typedef struct drawSurf_s { + const srfTriangles_t *geo; + const struct viewEntity_s *space; + const idMaterial *material; // may be NULL for shadow volumes + float sort; // material->sort, modified by gui / entity sort offsets + const float *shaderRegisters; // evaluated and adjusted for referenceShaders + const struct drawSurf_s *nextOnLight; // viewLight chains + idScreenRect scissorRect; // for scissor clipping, local inside renderView viewport + int dsFlags; // DSF_VIEW_INSIDE_SHADOW, etc + struct vertCache_s *dynamicTexCoords; // float * in vertex cache memory + // specular directions for non vertex program cards, skybox texcoords, etc +} drawSurf_t; + + +typedef struct { + int numPlanes; // this is always 6 for now + idPlane planes[6]; + // positive sides facing inward + // plane 5 is always the plane the projection is going to, the + // other planes are just clip planes + // all planes are in global coordinates + + bool makeClippedPlanes; + // a projected light with a single frustum needs to make sil planes + // from triangles that clip against side planes, but a point light + // that has adjacent frustums doesn't need to +} shadowFrustum_t; + + +// areas have references to hold all the lights and entities in them +typedef struct areaReference_s { + struct areaReference_s *areaNext; // chain in the area + struct areaReference_s *areaPrev; + struct areaReference_s *ownerNext; // chain on either the entityDef or lightDef + idRenderEntityLocal * entity; // only one of entity / light will be non-NULL + idRenderLightLocal * light; // only one of entity / light will be non-NULL + struct portalArea_s * area; // so owners can find all the areas they are in +} areaReference_t; + + +// idRenderLight should become the new public interface replacing the qhandle_t to light defs in the idRenderWorld interface +class idRenderLight { +public: + virtual ~idRenderLight() {} + + virtual void FreeRenderLight() = 0; + virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false ) = 0; + virtual void GetRenderLight( renderLight_t *re ) = 0; + virtual void ForceUpdate() = 0; + virtual int GetIndex() = 0; +}; + + +// idRenderEntity should become the new public interface replacing the qhandle_t to entity defs in the idRenderWorld interface +class idRenderEntity { +public: + virtual ~idRenderEntity() {} + + virtual void FreeRenderEntity() = 0; + virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false ) = 0; + virtual void GetRenderEntity( renderEntity_t *re ) = 0; + virtual void ForceUpdate() = 0; + virtual int GetIndex() = 0; + + // overlays are extra polygons that deform with animating models for blood and damage marks + virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ) = 0; + virtual void RemoveDecals() = 0; +}; + + +class idRenderLightLocal : public idRenderLight { +public: + idRenderLightLocal(); + + virtual void FreeRenderLight(); + virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false ); + virtual void GetRenderLight( renderLight_t *re ); + virtual void ForceUpdate(); + virtual int GetIndex(); + + renderLight_t parms; // specification + + bool lightHasMoved; // the light has changed its position since it was + // first added, so the prelight model is not valid + + float modelMatrix[16]; // this is just a rearrangement of parms.axis and parms.origin + + idRenderWorldLocal * world; + int index; // in world lightdefs + + int areaNum; // if not -1, we may be able to cull all the light's + // interactions if !viewDef->connectedAreas[areaNum] + + int lastModifiedFrameNum; // to determine if it is constantly changing, + // and should go in the dynamic frame memory, or kept + // in the cached memory + bool archived; // for demo writing + + + // derived information + idPlane lightProject[4]; + + const idMaterial * lightShader; // guaranteed to be valid, even if parms.shader isn't + idImage * falloffImage; + + idVec3 globalLightOrigin; // accounting for lightCenter and parallel + + + idPlane frustum[6]; // in global space, positive side facing out, last two are front/back + idWinding * frustumWindings[6]; // used for culling + srfTriangles_t * frustumTris; // triangulated frustumWindings[] + + int numShadowFrustums; // one for projected lights, usually six for point lights + shadowFrustum_t shadowFrustums[6]; + + int viewCount; // if == tr.viewCount, the light is on the viewDef->viewLights list + struct viewLight_s * viewLight; + + areaReference_t * references; // each area the light is present in will have a lightRef + idInteraction * firstInteraction; // doubly linked list + idInteraction * lastInteraction; + + struct doublePortal_s * foggedPortals; +}; + + +class idRenderEntityLocal : public idRenderEntity { +public: + idRenderEntityLocal(); + + virtual void FreeRenderEntity(); + virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false ); + virtual void GetRenderEntity( renderEntity_t *re ); + virtual void ForceUpdate(); + virtual int GetIndex(); + + // overlays are extra polygons that deform with animating models for blood and damage marks + virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ); + virtual void RemoveDecals(); + + renderEntity_t parms; + + float modelMatrix[16]; // this is just a rearrangement of parms.axis and parms.origin + + idRenderWorldLocal * world; + int index; // in world entityDefs + + int lastModifiedFrameNum; // to determine if it is constantly changing, + // and should go in the dynamic frame memory, or kept + // in the cached memory + bool archived; // for demo writing + + idRenderModel * dynamicModel; // if parms.model->IsDynamicModel(), this is the generated data + int dynamicModelFrameCount; // continuously animating dynamic models will recreate + // dynamicModel if this doesn't == tr.viewCount + idRenderModel * cachedDynamicModel; + + idBounds referenceBounds; // the local bounds used to place entityRefs, either from parms or a model + + // a viewEntity_t is created whenever a idRenderEntityLocal is considered for inclusion + // in a given view, even if it turns out to not be visible + int viewCount; // if tr.viewCount == viewCount, viewEntity is valid, + // but the entity may still be off screen + struct viewEntity_s * viewEntity; // in frame temporary memory + + int visibleCount; + // if tr.viewCount == visibleCount, at least one ambient + // surface has actually been added by R_AddAmbientDrawsurfs + // note that an entity could still be in the view frustum and not be visible due + // to portal passing + + idRenderModelDecal * decals; // chain of decals that have been projected on this model + idRenderModelOverlay * overlay; // blood overlays on animated models + + areaReference_t * entityRefs; // chain of all references + idInteraction * firstInteraction; // doubly linked list + idInteraction * lastInteraction; + + bool needsPortalSky; +}; + + +// viewLights are allocated on the frame temporary stack memory +// a viewLight contains everything that the back end needs out of an idRenderLightLocal, +// which the front end may be modifying simultaniously if running in SMP mode. +// a viewLight may exist even without any surfaces, and may be relevent for fogging, +// but should never exist if its volume does not intersect the view frustum +typedef struct viewLight_s { + struct viewLight_s * next; + + // back end should NOT reference the lightDef, because it can change when running SMP + idRenderLightLocal * lightDef; + + // for scissor clipping, local inside renderView viewport + // scissorRect.Empty() is true if the viewEntity_t was never actually + // seen through any portals + idScreenRect scissorRect; + + // if the view isn't inside the light, we can use the non-reversed + // shadow drawing, avoiding the draws of the front and rear caps + bool viewInsideLight; + + // true if globalLightOrigin is inside the view frustum, even if it may + // be obscured by geometry. This allows us to skip shadows from non-visible objects + bool viewSeesGlobalLightOrigin; + + // if !viewInsideLight, the corresponding bit for each of the shadowFrustum + // projection planes that the view is on the negative side of will be set, + // allowing us to skip drawing the projected caps of shadows if we can't see the face + int viewSeesShadowPlaneBits; + + idVec3 globalLightOrigin; // global light origin used by backend + idPlane lightProject[4]; // light project used by backend + idPlane fogPlane; // fog plane for backend fog volume rendering + const srfTriangles_t * frustumTris; // light frustum for backend fog volume rendering + const idMaterial * lightShader; // light shader used by backend + const float * shaderRegisters; // shader registers used by backend + idImage * falloffImage; // falloff image used by backend + + const struct drawSurf_s *globalShadows; // shadow everything + const struct drawSurf_s *localInteractions; // don't get local shadows + const struct drawSurf_s *localShadows; // don't shadow local Surfaces + const struct drawSurf_s *globalInteractions; // get shadows from everything + const struct drawSurf_s *translucentInteractions; // get shadows from everything +} viewLight_t; + + +// a viewEntity is created whenever a idRenderEntityLocal is considered for inclusion +// in the current view, but it may still turn out to be culled. +// viewEntity are allocated on the frame temporary stack memory +// a viewEntity contains everything that the back end needs out of a idRenderEntityLocal, +// which the front end may be modifying simultaniously if running in SMP mode. +// A single entityDef can generate multiple viewEntity_t in a single frame, as when seen in a mirror +typedef struct viewEntity_s { + struct viewEntity_s *next; + + // back end should NOT reference the entityDef, because it can change when running SMP + idRenderEntityLocal *entityDef; + + // for scissor clipping, local inside renderView viewport + // scissorRect.Empty() is true if the viewEntity_t was never actually + // seen through any portals, but was created for shadow casting. + // a viewEntity can have a non-empty scissorRect, meaning that an area + // that it is in is visible, and still not be visible. + idScreenRect scissorRect; + + bool weaponDepthHack; + float modelDepthHack; + + float modelMatrix[16]; // local coords to global coords + float modelViewMatrix[16]; // local coords to eye coords +} viewEntity_t; + + +const int MAX_CLIP_PLANES = 1; // we may expand this to six for some subview issues + +// viewDefs are allocated on the frame temporary stack memory +typedef struct viewDef_s { + // specified in the call to DrawScene() + renderView_t renderView; + + float projectionMatrix[16]; + viewEntity_t worldSpace; + + idRenderWorldLocal *renderWorld; + + float floatTime; + + idVec3 initialViewAreaOrigin; + // Used to find the portalArea that view flooding will take place from. + // for a normal view, the initialViewOrigin will be renderView.viewOrg, + // but a mirror may put the projection origin outside + // of any valid area, or in an unconnected area of the map, so the view + // area must be based on a point just off the surface of the mirror / subview. + // It may be possible to get a failed portal pass if the plane of the + // mirror intersects a portal, and the initialViewAreaOrigin is on + // a different side than the renderView.viewOrg is. + + bool isSubview; // true if this view is not the main view + bool isMirror; // the portal is a mirror, invert the face culling + bool isXraySubview; + + bool isEditor; + + int numClipPlanes; // mirrors will often use a single clip plane + idPlane clipPlanes[MAX_CLIP_PLANES]; // in world space, the positive side + // of the plane is the visible side + idScreenRect viewport; // in real pixels and proper Y flip + + idScreenRect scissor; + // for scissor clipping, local inside renderView viewport + // subviews may only be rendering part of the main view + // these are real physical pixel values, possibly scaled and offset from the + // renderView x/y/width/height + + struct viewDef_s * superView; // never go into an infinite subview loop + struct drawSurf_s * subviewSurface; + + // drawSurfs are the visible surfaces of the viewEntities, sorted + // by the material sort parameter + drawSurf_t ** drawSurfs; // we don't use an idList for this, because + int numDrawSurfs; // it is allocated in frame temporary memory + int maxDrawSurfs; // may be resized + + struct viewLight_s *viewLights; // chain of all viewLights effecting view + struct viewEntity_s *viewEntitys; // chain of all viewEntities effecting view, including off screen ones casting shadows + // we use viewEntities as a check to see if a given view consists solely + // of 2D rendering, which we can optimize in certain ways. A 2D view will + // not have any viewEntities + + idPlane frustum[5]; // positive sides face outward, [4] is the front clip plane + idFrustum viewFrustum; + + int areaNum; // -1 = not in a valid area + + bool * connectedAreas; + // An array in frame temporary memory that lists if an area can be reached without + // crossing a closed door. This is used to avoid drawing interactions + // when the light is behind a closed door. + +} viewDef_t; + + +// complex light / surface interactions are broken up into multiple passes of a +// simple interaction shader +typedef struct { + const drawSurf_t * surf; + + idImage * lightImage; + idImage * lightFalloffImage; + idImage * bumpImage; + idImage * diffuseImage; + idImage * specularImage; + + idVec4 diffuseColor; // may have a light color baked into it, will be < tr.backEndRendererMaxLight + idVec4 specularColor; // may have a light color baked into it, will be < tr.backEndRendererMaxLight + stageVertexColor_t vertexColor; // applies to both diffuse and specular + + int ambientLight; // use tr.ambientNormalMap instead of normalization cube map + // (not a bool just to avoid an uninitialized memory check of the pad region by valgrind) + + // these are loaded into the vertex program + idVec4 localLightOrigin; + idVec4 localViewOrigin; + idVec4 lightProjection[4]; // in local coordinates, possibly with a texture matrix baked in + idVec4 bumpMatrix[2]; + idVec4 diffuseMatrix[2]; + idVec4 specularMatrix[2]; +} drawInteraction_t; + + +/* +============================================================= + +RENDERER BACK END COMMAND QUEUE + +TR_CMDS + +============================================================= +*/ + +typedef enum { + RC_NOP, + RC_DRAW_VIEW, + RC_SET_BUFFER, + RC_COPY_RENDER, + RC_SWAP_BUFFERS // can't just assume swap at end of list because + // of forced list submission before syncs +} renderCommand_t; + +typedef struct { + renderCommand_t commandId, *next; +} emptyCommand_t; + +typedef struct { + renderCommand_t commandId, *next; + GLenum buffer; + int frameCount; +} setBufferCommand_t; + +typedef struct { + renderCommand_t commandId, *next; + viewDef_t *viewDef; +} drawSurfsCommand_t; + +typedef struct { + renderCommand_t commandId, *next; + int x, y, imageWidth, imageHeight; + idImage *image; + int cubeFace; // when copying to a cubeMap +} copyRenderCommand_t; + + +//======================================================================= + +// this is the inital allocation for max number of drawsurfs +// in a given view, but it will automatically grow if needed +const int INITIAL_DRAWSURFS = 0x4000; + +// a request for frame memory will never fail +// (until malloc fails), but it may force the +// allocation of a new memory block that will +// be discontinuous with the existing memory +typedef struct frameMemoryBlock_s { + struct frameMemoryBlock_s *next; + int size; + int used; + int poop; // so that base is 16 byte aligned + byte base[4]; // dynamically allocated as [size] +} frameMemoryBlock_t; + +// all of the information needed by the back end must be +// contained in a frameData_t. This entire structure is +// duplicated so the front and back end can run in parallel +// on an SMP machine (OBSOLETE: this capability has been removed) +typedef struct { + // one or more blocks of memory for all frame + // temporary allocations + frameMemoryBlock_t *memory; + + // alloc will point somewhere into the memory chain + frameMemoryBlock_t *alloc; + + srfTriangles_t * firstDeferredFreeTriSurf; + srfTriangles_t * lastDeferredFreeTriSurf; + + int memoryHighwater; // max used on any frame + + // the currently building command list + // commands can be inserted at the front if needed, as for required + // dynamically generated textures + emptyCommand_t *cmdHead, *cmdTail; // may be of other command type based on commandId +} frameData_t; + +extern frameData_t *frameData; + +//======================================================================= + +void R_LockSurfaceScene( viewDef_t *parms ); +void R_ClearCommandChain( void ); +void R_AddDrawViewCmd( viewDef_t *parms ); + +void R_ReloadGuis_f( const idCmdArgs &args ); +void R_ListGuis_f( const idCmdArgs &args ); + +void *R_GetCommandBuffer( int bytes ); + +// this allows a global override of all materials +bool R_GlobalShaderOverride( const idMaterial **shader ); + +// this does various checks before calling the idDeclSkin +const idMaterial *R_RemapShaderBySkin( const idMaterial *shader, const idDeclSkin *customSkin, const idMaterial *customShader ); + + +//==================================================== + + +/* +** performanceCounters_t +*/ +typedef struct { + int c_sphere_cull_in, c_sphere_cull_clip, c_sphere_cull_out; + int c_box_cull_in, c_box_cull_out; + int c_createInteractions; // number of calls to idInteraction::CreateInteraction + int c_createLightTris; + int c_createShadowVolumes; + int c_generateMd5; + int c_entityDefCallbacks; + int c_alloc, c_free; // counts for R_StaticAllc/R_StaticFree + int c_visibleViewEntities; + int c_shadowViewEntities; + int c_viewLights; + int c_numViews; // number of total views rendered + int c_deformedSurfaces; // idMD5Mesh::GenerateSurface + int c_deformedVerts; // idMD5Mesh::GenerateSurface + int c_deformedIndexes; // idMD5Mesh::GenerateSurface + int c_tangentIndexes; // R_DeriveTangents() + int c_entityUpdates, c_lightUpdates, c_entityReferences, c_lightReferences; + int c_guiSurfs; + int frontEndMsec; // sum of time in all RE_RenderScene's in a frame +} performanceCounters_t; + + +typedef struct { + int current2DMap; + int current3DMap; + int currentCubeMap; + int texEnv; + textureType_t textureType; +} tmu_t; + +const int MAX_MULTITEXTURE_UNITS = 8; +typedef struct { + tmu_t tmu[MAX_MULTITEXTURE_UNITS]; + int currenttmu; + + int faceCulling; + int glStateBits; + bool forceGlState; // the next GL_State will ignore glStateBits and set everything +} glstate_t; + + +typedef struct { + int c_surfaces; + int c_shaders; + int c_vertexes; + int c_indexes; // one set per pass + int c_totalIndexes; // counting all passes + + int c_drawElements; + int c_drawIndexes; + int c_drawVertexes; + int c_drawRefIndexes; + int c_drawRefVertexes; + + int c_shadowElements; + int c_shadowIndexes; + int c_shadowVertexes; + + int c_vboIndexes; + float c_overDraw; + + float maxLightValue; // for light scale + int msec; // total msec for backend run +} backEndCounters_t; + +// all state modified by the back end is separated +// from the front end state +typedef struct { + int frameCount; // used to track all images used in a frame + const viewDef_t * viewDef; + backEndCounters_t pc; + + const viewEntity_t *currentSpace; // for detecting when a matrix must change + idScreenRect currentScissor; + // for scissor clipping, local inside renderView viewport + + viewLight_t * vLight; + int depthFunc; // GLS_DEPTHFUNC_EQUAL, or GLS_DEPTHFUNC_LESS for translucent + float lightTextureMatrix[16]; // only if lightStage->texture.hasMatrix + float lightColor[4]; // evaluation of current light's color stage + + float lightScale; // Every light color calaculation will be multiplied by this, + // which will guarantee that the result is < tr.backEndRendererMaxLight + // A card with high dynamic range will have this set to 1.0 + float overBright; // The amount that all light interactions must be multiplied by + // with post processing to get the desired total light level. + // A high dynamic range card will have this set to 1.0. + + bool currentRenderCopied; // true if any material has already referenced _currentRender + + // our OpenGL state deltas + glstate_t glState; + + int c_copyFrameBuffer; +} backEndState_t; + + +const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for guis, will + // be automatically expanded as needed + +typedef enum { + BE_ARB, + BE_NV10, + BE_NV20, + BE_R200, + BE_ARB2, + BE_BAD +} backEndName_t; + +typedef struct { + int x, y, width, height; // these are in physical, OpenGL Y-at-bottom pixels +} renderCrop_t; +static const int MAX_RENDER_CROPS = 8; + +/* +** Most renderer globals are defined here. +** backend functions should never modify any of these fields, +** but may read fields that aren't dynamically modified +** by the frontend. +*/ +class idRenderSystemLocal : public idRenderSystem { +public: + // external functions + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void InitOpenGL( void ); + virtual void ShutdownOpenGL( void ); + virtual bool IsOpenGLRunning( void ) const; + virtual bool IsFullScreen( void ) const; + virtual int GetScreenWidth( void ) const; + virtual int GetScreenHeight( void ) const; + virtual idRenderWorld * AllocRenderWorld( void ); + virtual void FreeRenderWorld( idRenderWorld *rw ); + virtual void BeginLevelLoad( void ); + virtual void EndLevelLoad( void ); + virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ); + virtual void SetColor( const idVec4 &rgba ); + virtual void SetColor4( float r, float g, float b, float a ); + virtual void DrawStretchPic ( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, + bool clip = true, float x = 0.0f, float y = 0.0f, float w = 640.0f, float h = 0.0f ); + virtual void DrawStretchPic ( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ); + + virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ); + virtual void GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ); + virtual void GetGLSettings( int& width, int& height ); + virtual void PrintMemInfo( MemInfo_t *mi ); + + virtual void DrawSmallChar( int x, int y, int ch, const idMaterial *material ); + virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ); + virtual void DrawBigChar( int x, int y, int ch, const idMaterial *material ); + virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ); + virtual void WriteDemoPics(); + virtual void DrawDemoPics(); + virtual void BeginFrame( int windowWidth, int windowHeight ); + virtual void EndFrame( int *frontEndMsec, int *backEndMsec ); + virtual void TakeScreenshot( int width, int height, const char *fileName, int downSample, renderView_t *ref ); + virtual void CropRenderSize( int width, int height, bool makePowerOfTwo = false, bool forceDimensions = false ); + virtual void CaptureRenderToImage( const char *imageName ); + virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha ); + virtual void UnCrop(); + virtual void GetCardCaps( bool &oldCard, bool &nv10or20 ); + virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ); + +public: + // internal functions + idRenderSystemLocal( void ); + ~idRenderSystemLocal( void ); + + void Clear( void ); + void SetBackEndRenderer(); // sets tr.backEndRenderer based on cvars + void RenderViewToViewport( const renderView_t *renderView, idScreenRect *viewport ); + +public: + // renderer globals + bool registered; // cleared at shutdown, set at InitOpenGL + + bool takingScreenshot; + + int frameCount; // incremented every frame + int viewCount; // incremented every view (twice a scene if subviewed) + // and every R_MarkFragments call + + int staticAllocCount; // running total of bytes allocated + + float frameShaderTime; // shader time for all non-world 2D rendering + + int viewportOffset[2]; // for doing larger-than-window tiled renderings + int tiledViewport[2]; + + // determines which back end to use, and if vertex programs are in use + backEndName_t backEndRenderer; + bool backEndRendererHasVertexPrograms; + float backEndRendererMaxLight; // 1.0 for standard, unlimited for floats + // determines how much overbrighting needs + // to be done post-process + + idVec4 ambientLightVector; // used for "ambient bump mapping" + + float sortOffset; // for determinist sorting of equal sort materials + + idListworlds; + + idRenderWorldLocal * primaryWorld; + renderView_t primaryRenderView; + viewDef_t * primaryView; + // many console commands need to know which world they should operate on + + const idMaterial * defaultMaterial; + idImage * testImage; + idCinematic * testVideo; + float testVideoStartTime; + + idImage * ambientCubeImage; // hack for testing dependent ambient lighting + + viewDef_t * viewDef; + + performanceCounters_t pc; // performance counters + + drawSurfsCommand_t lockSurfacesCmd; // use this when r_lockSurfaces = 1 + + viewEntity_t identitySpace; // can use if we don't know viewDef->worldSpace is valid + FILE * logFile; // for logging GL calls and frame breaks + + int stencilIncr, stencilDecr; // GL_INCR / INCR_WRAP_EXT, GL_DECR / GL_DECR_EXT + + renderCrop_t renderCrops[MAX_RENDER_CROPS]; + int currentRenderCrop; + + // GUI drawing variables for surface creation + int guiRecursionLevel; // to prevent infinite overruns + class idGuiModel * guiModel; + class idGuiModel * demoGuiModel; + + unsigned short gammaTable[256]; // brightness / gamma modify this +}; + +extern backEndState_t backEnd; +extern idRenderSystemLocal tr; +extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init + + +// +// cvars +// +extern idCVar r_ext_vertex_array_range; + +extern idCVar r_glDriver; // "opengl32", etc +extern idCVar r_mode; // video mode number +extern idCVar r_displayRefresh; // optional display refresh rate option for vid mode +extern idCVar r_fullscreen; // 0 = windowed, 1 = full screen +extern idCVar r_multiSamples; // number of antialiasing samples + +extern idCVar r_ignore; // used for random debugging without defining new vars +extern idCVar r_ignore2; // used for random debugging without defining new vars +extern idCVar r_znear; // near Z clip plane + +extern idCVar r_finish; // force a call to glFinish() every frame +extern idCVar r_frontBuffer; // draw to front buffer for debugging +extern idCVar r_swapInterval; // changes wglSwapIntarval +extern idCVar r_offsetFactor; // polygon offset parameter +extern idCVar r_offsetUnits; // polygon offset parameter +extern idCVar r_singleTriangle; // only draw a single triangle per primitive +extern idCVar r_logFile; // number of frames to emit GL logs +extern idCVar r_clear; // force screen clear every frame +extern idCVar r_shadows; // enable shadows +extern idCVar r_subviewOnly; // 1 = don't render main view, allowing subviews to be debugged +extern idCVar r_lightScale; // all light intensities are multiplied by this, which is normally 2 +extern idCVar r_flareSize; // scale the flare deforms from the material def + +extern idCVar r_gamma; // changes gamma tables +extern idCVar r_brightness; // changes gamma tables + +extern idCVar r_renderer; // arb, nv10, nv20, r200, gl2, etc + +extern idCVar r_cgVertexProfile; // arbvp1, vp20, vp30 +extern idCVar r_cgFragmentProfile; // arbfp1, fp30 + +extern idCVar r_checkBounds; // compare all surface bounds with precalculated ones + +extern idCVar r_useNV20MonoLights; // 1 = allow an interaction pass optimization +extern idCVar r_useLightPortalFlow; // 1 = do a more precise area reference determination +extern idCVar r_useTripleTextureARB; // 1 = cards with 3+ texture units do a two pass instead of three pass +extern idCVar r_useShadowSurfaceScissor;// 1 = scissor shadows by the scissor rect of the interaction surfaces +extern idCVar r_useConstantMaterials; // 1 = use pre-calculated material registers if possible +extern idCVar r_useInteractionTable; // create a full entityDefs * lightDefs table to make finding interactions faster +extern idCVar r_useNodeCommonChildren; // stop pushing reference bounds early when possible +extern idCVar r_useSilRemap; // 1 = consider verts with the same XYZ, but different ST the same for shadows +extern idCVar r_useCulling; // 0 = none, 1 = sphere, 2 = sphere + box +extern idCVar r_useLightCulling; // 0 = none, 1 = box, 2 = exact clip of polyhedron faces +extern idCVar r_useLightScissors; // 1 = use custom scissor rectangle for each light +extern idCVar r_useClippedLightScissors;// 0 = full screen when near clipped, 1 = exact when near clipped, 2 = exact always +extern idCVar r_useEntityCulling; // 0 = none, 1 = box +extern idCVar r_useEntityScissors; // 1 = use custom scissor rectangle for each entity +extern idCVar r_useInteractionCulling; // 1 = cull interactions +extern idCVar r_useInteractionScissors; // 1 = use a custom scissor rectangle for each interaction +extern idCVar r_useFrustumFarDistance; // if != 0 force the view frustum far distance to this distance +extern idCVar r_useShadowCulling; // try to cull shadows from partially visible lights +extern idCVar r_usePreciseTriangleInteractions; // 1 = do winding clipping to determine if each ambiguous tri should be lit +extern idCVar r_useTurboShadow; // 1 = use the infinite projection with W technique for dynamic shadows +extern idCVar r_useExternalShadows; // 1 = skip drawing caps when outside the light volume +extern idCVar r_useOptimizedShadows; // 1 = use the dmap generated static shadow volumes +extern idCVar r_useShadowVertexProgram; // 1 = do the shadow projection in the vertex program on capable cards +extern idCVar r_useShadowProjectedCull; // 1 = discard triangles outside light volume before shadowing +extern idCVar r_useDeferredTangents; // 1 = don't always calc tangents after deform +extern idCVar r_useCachedDynamicModels; // 1 = cache snapshots of dynamic models +extern idCVar r_useTwoSidedStencil; // 1 = do stencil shadows in one pass with different ops on each side +extern idCVar r_useInfiniteFarZ; // 1 = use the no-far-clip-plane trick +extern idCVar r_useScissor; // 1 = scissor clip as portals and lights are processed +extern idCVar r_usePortals; // 1 = use portals to perform area culling, otherwise draw everything +extern idCVar r_useStateCaching; // avoid redundant state changes in GL_*() calls +extern idCVar r_useCombinerDisplayLists;// if 1, put all nvidia register combiner programming in display lists +extern idCVar r_useVertexBuffers; // if 0, don't use ARB_vertex_buffer_object for vertexes +extern idCVar r_useIndexBuffers; // if 0, don't use ARB_vertex_buffer_object for indexes +extern idCVar r_useEntityCallbacks; // if 0, issue the callback immediately at update time, rather than defering +extern idCVar r_lightAllBackFaces; // light all the back faces, even when they would be shadowed +extern idCVar r_useDepthBoundsTest; // use depth bounds test to reduce shadow fill + +extern idCVar r_skipPostProcess; // skip all post-process renderings +extern idCVar r_skipSuppress; // ignore the per-view suppressions +extern idCVar r_skipInteractions; // skip all light/surface interaction drawing +extern idCVar r_skipFrontEnd; // bypasses all front end work, but 2D gui rendering still draws +extern idCVar r_skipBackEnd; // don't draw anything +extern idCVar r_skipCopyTexture; // do all rendering, but don't actually copyTexSubImage2D +extern idCVar r_skipRender; // skip 3D rendering, but pass 2D +extern idCVar r_skipRenderContext; // NULL the rendering context during backend 3D rendering +extern idCVar r_skipTranslucent; // skip the translucent interaction rendering +extern idCVar r_skipAmbient; // bypasses all non-interaction drawing +extern idCVar r_skipNewAmbient; // bypasses all vertex/fragment program ambients +extern idCVar r_skipBlendLights; // skip all blend lights +extern idCVar r_skipFogLights; // skip all fog lights +extern idCVar r_skipSubviews; // 1 = don't render any mirrors / cameras / etc +extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces +extern idCVar r_skipParticles; // 1 = don't render any particles +extern idCVar r_skipUpdates; // 1 = don't accept any entity or light updates, making everything static +extern idCVar r_skipDeforms; // leave all deform materials in their original state +extern idCVar r_skipDynamicTextures; // don't dynamically create textures +extern idCVar r_skipLightScale; // don't do any post-interaction light scaling, makes things dim on low-dynamic range cards +extern idCVar r_skipBump; // uses a flat surface instead of the bump map +extern idCVar r_skipSpecular; // use black for specular +extern idCVar r_skipDiffuse; // use black for diffuse +extern idCVar r_skipOverlays; // skip overlay surfaces +extern idCVar r_skipROQ; + +extern idCVar r_ignoreGLErrors; + +extern idCVar r_forceLoadImages; // draw all images to screen after registration +extern idCVar r_demonstrateBug; // used during development to show IHV's their problems +extern idCVar r_screenFraction; // for testing fill rate, the resolution of the entire screen can be changed + +extern idCVar r_showUnsmoothedTangents; // highlight geometry rendered with unsmoothed tangents +extern idCVar r_showSilhouette; // highlight edges that are casting shadow planes +extern idCVar r_showVertexColor; // draws all triangles with the solid vertex color +extern idCVar r_showUpdates; // report entity and light updates and ref counts +extern idCVar r_showDemo; // report reads and writes to the demo file +extern idCVar r_showDynamic; // report stats on dynamic surface generation +extern idCVar r_showLightScale; // report the scale factor applied to drawing for overbrights +extern idCVar r_showIntensity; // draw the screen colors based on intensity, red = 0, green = 128, blue = 255 +extern idCVar r_showDefs; // report the number of modeDefs and lightDefs in view +extern idCVar r_showTrace; // show the intersection of an eye trace with the world +extern idCVar r_showSmp; // show which end (front or back) is blocking +extern idCVar r_showDepth; // display the contents of the depth buffer and the depth range +extern idCVar r_showImages; // draw all images to screen instead of rendering +extern idCVar r_showTris; // enables wireframe rendering of the world +extern idCVar r_showSurfaceInfo; // show surface material name under crosshair +extern idCVar r_showNormals; // draws wireframe normals +extern idCVar r_showEdges; // draw the sil edges +extern idCVar r_showViewEntitys; // displays the bounding boxes of all view models and optionally the index +extern idCVar r_showTexturePolarity; // shade triangles by texture area polarity +extern idCVar r_showTangentSpace; // shade triangles by tangent space +extern idCVar r_showDominantTri; // draw lines from vertexes to center of dominant triangles +extern idCVar r_showTextureVectors; // draw each triangles texture (tangent) vectors +extern idCVar r_showLights; // 1 = print light info, 2 = also draw volumes +extern idCVar r_showLightCount; // colors surfaces based on light count +extern idCVar r_showShadows; // visualize the stencil shadow volumes +extern idCVar r_showShadowCount; // colors screen based on shadow volume depth complexity +extern idCVar r_showLightScissors; // show light scissor rectangles +extern idCVar r_showEntityScissors; // show entity scissor rectangles +extern idCVar r_showInteractionFrustums;// show a frustum for each interaction +extern idCVar r_showInteractionScissors;// show screen rectangle which contains the interaction frustum +extern idCVar r_showMemory; // print frame memory utilization +extern idCVar r_showCull; // report sphere and box culling stats +extern idCVar r_showInteractions; // report interaction generation activity +extern idCVar r_showSurfaces; // report surface/light/shadow counts +extern idCVar r_showPrimitives; // report vertex/index/draw counts +extern idCVar r_showPortals; // draw portal outlines in color based on passed / not passed +extern idCVar r_showAlloc; // report alloc/free counts +extern idCVar r_showSkel; // draw the skeleton when model animates +extern idCVar r_showOverDraw; // show overdraw +extern idCVar r_jointNameScale; // size of joint names when r_showskel is set to 1 +extern idCVar r_jointNameOffset; // offset of joint names when r_showskel is set to 1 + +extern idCVar r_testGamma; // draw a grid pattern to test gamma levels +extern idCVar r_testStepGamma; // draw a grid pattern to test gamma levels +extern idCVar r_testGammaBias; // draw a grid pattern to test gamma levels + +extern idCVar r_testARBProgram; // experiment with vertex/fragment programs + +extern idCVar r_singleLight; // suppress all but one light +extern idCVar r_singleEntity; // suppress all but one entity +extern idCVar r_singleArea; // only draw the portal area the view is actually in +extern idCVar r_singleSurface; // suppress all but one surface on each entity +extern idCVar r_shadowPolygonOffset; // bias value added to depth test for stencil shadow drawing +extern idCVar r_shadowPolygonFactor; // scale value for stencil shadow drawing + +extern idCVar r_jitter; // randomly subpixel jitter the projection matrix +extern idCVar r_lightSourceRadius; // for soft-shadow sampling +extern idCVar r_lockSurfaces; +extern idCVar r_orderIndexes; // perform index reorganization to optimize vertex use + +extern idCVar r_debugLineDepthTest; // perform depth test on debug lines +extern idCVar r_debugLineWidth; // width of debug lines +extern idCVar r_debugArrowStep; // step size of arrow cone line rotation in degrees +extern idCVar r_debugPolygonFilled; + +extern idCVar r_materialOverride; // override all materials + +extern idCVar r_debugRenderToTexture; + +/* +==================================================================== + +GL wrapper/helper functions + +==================================================================== +*/ + +void GL_SelectTexture( int unit ); +void GL_CheckErrors( void ); +void GL_ClearStateDelta( void ); +void GL_State( int stateVector ); +void GL_TexEnv( int env ); +void GL_Cull( int cullType ); + +const int GLS_SRCBLEND_ZERO = 0x00000001; +const int GLS_SRCBLEND_ONE = 0x0; +const int GLS_SRCBLEND_DST_COLOR = 0x00000003; +const int GLS_SRCBLEND_ONE_MINUS_DST_COLOR = 0x00000004; +const int GLS_SRCBLEND_SRC_ALPHA = 0x00000005; +const int GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA = 0x00000006; +const int GLS_SRCBLEND_DST_ALPHA = 0x00000007; +const int GLS_SRCBLEND_ONE_MINUS_DST_ALPHA = 0x00000008; +const int GLS_SRCBLEND_ALPHA_SATURATE = 0x00000009; +const int GLS_SRCBLEND_BITS = 0x0000000f; + +const int GLS_DSTBLEND_ZERO = 0x0; +const int GLS_DSTBLEND_ONE = 0x00000020; +const int GLS_DSTBLEND_SRC_COLOR = 0x00000030; +const int GLS_DSTBLEND_ONE_MINUS_SRC_COLOR = 0x00000040; +const int GLS_DSTBLEND_SRC_ALPHA = 0x00000050; +const int GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA = 0x00000060; +const int GLS_DSTBLEND_DST_ALPHA = 0x00000070; +const int GLS_DSTBLEND_ONE_MINUS_DST_ALPHA = 0x00000080; +const int GLS_DSTBLEND_BITS = 0x000000f0; + + +// these masks are the inverse, meaning when set the glColorMask value will be 0, +// preventing that channel from being written +const int GLS_DEPTHMASK = 0x00000100; +const int GLS_REDMASK = 0x00000200; +const int GLS_GREENMASK = 0x00000400; +const int GLS_BLUEMASK = 0x00000800; +const int GLS_ALPHAMASK = 0x00001000; +const int GLS_COLORMASK = (GLS_REDMASK|GLS_GREENMASK|GLS_BLUEMASK); + +const int GLS_POLYMODE_LINE = 0x00002000; + +const int GLS_DEPTHFUNC_ALWAYS = 0x00010000; +const int GLS_DEPTHFUNC_EQUAL = 0x00020000; +const int GLS_DEPTHFUNC_LESS = 0x0; + +const int GLS_ATEST_EQ_255 = 0x10000000; +const int GLS_ATEST_LT_128 = 0x20000000; +const int GLS_ATEST_GE_128 = 0x40000000; +const int GLS_ATEST_BITS = 0x70000000; + +const int GLS_DEFAULT = GLS_DEPTHFUNC_ALWAYS; + +void R_Init( void ); +void R_InitOpenGL( void ); + +void R_DoneFreeType( void ); + +void R_SetColorMappings( void ); + +void R_ScreenShot_f( const idCmdArgs &args ); +void R_StencilShot( void ); + +bool R_CheckExtension( char *name ); + + +/* +==================================================================== + +IMPLEMENTATION SPECIFIC FUNCTIONS + +==================================================================== +*/ + +typedef struct { + int width; + int height; + bool fullScreen; + bool stereo; + int displayHz; + int multiSamples; +} glimpParms_t; + +bool GLimp_Init( glimpParms_t parms ); +// If the desired mode can't be set satisfactorily, false will be returned. +// The renderer will then reset the glimpParms to "safe mode" of 640x480 +// fullscreen and try again. If that also fails, the error will be fatal. + +bool GLimp_SetScreenParms( glimpParms_t parms ); +// will set up gl up with the new parms + +void GLimp_Shutdown( void ); +// Destroys the rendering context, closes the window, resets the resolution, +// and resets the gamma ramps. + +void GLimp_SwapBuffers( void ); +// Calls the system specific swapbuffers routine, and may also perform +// other system specific cvar checks that happen every frame. +// This will not be called if 'r_drawBuffer GL_FRONT' + +void GLimp_SetGamma( unsigned short red[256], + unsigned short green[256], + unsigned short blue[256] ); +// Sets the hardware gamma ramps for gamma and brightness adjustment. +// These are now taken as 16 bit values, so we can take full advantage +// of dacs with >8 bits of precision + + +bool GLimp_SpawnRenderThread( void (*function)( void ) ); +// Returns false if the system only has a single processor + +void * GLimp_BackEndSleep( void ); +void GLimp_FrontEndSleep( void ); +void GLimp_WakeBackEnd( void *data ); +// these functions implement the dual processor syncronization + +void GLimp_ActivateContext( void ); +void GLimp_DeactivateContext( void ); +// These are used for managing SMP handoffs of the OpenGL context +// between threads, and as a performance tunining aid. Setting +// 'r_skipRenderContext 1' will call GLimp_DeactivateContext() before +// the 3D rendering code, and GLimp_ActivateContext() afterwards. On +// most OpenGL implementations, this will result in all OpenGL calls +// being immediate returns, which lets us guage how much time is +// being spent inside OpenGL. + +void GLimp_EnableLogging( bool enable ); + + +/* +==================================================================== + +MAIN + +==================================================================== +*/ + +void R_RenderView( viewDef_t *parms ); + +// performs radius cull first, then corner cull +bool R_CullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); +bool R_RadiusCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); +bool R_CornerCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); + +void R_AxisToModelMatrix( const idMat3 &axis, const idVec3 &origin, float modelMatrix[16] ); + +// note that many of these assume a normalized matrix, and will not work with scaled axis +void R_GlobalPointToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); +void R_GlobalVectorToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); +void R_GlobalPlaneToLocal( const float modelMatrix[16], const idPlane &in, idPlane &out ); +void R_PointTimesMatrix( const float modelMatrix[16], const idVec4 &in, idVec4 &out ); +void R_LocalPointToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); +void R_LocalVectorToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); +void R_LocalPlaneToGlobal( const float modelMatrix[16], const idPlane &in, idPlane &out ); +void R_TransformEyeZToWin( float src_z, const float *projectionMatrix, float &dst_z ); + +void R_GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ); + +void R_TransformModelToClip( const idVec3 &src, const float *modelMatrix, const float *projectionMatrix, idPlane &eye, idPlane &dst ); + +void R_TransformClipToDevice( const idPlane &clip, const viewDef_t *view, idVec3 &normalized ); + +void R_TransposeGLMatrix( const float in[16], float out[16] ); + +void R_SetViewMatrix( viewDef_t *viewDef ); + +void myGlMultMatrix( const float *a, const float *b, float *out ); + +/* +============================================================ + +LIGHT + +============================================================ +*/ + +void R_ListRenderLightDefs_f( const idCmdArgs &args ); +void R_ListRenderEntityDefs_f( const idCmdArgs &args ); + +bool R_IssueEntityDefCallback( idRenderEntityLocal *def ); +idRenderModel *R_EntityDefDynamicModel( idRenderEntityLocal *def ); + +viewEntity_t *R_SetEntityDefViewEntity( idRenderEntityLocal *def ); +viewLight_t *R_SetLightDefViewLight( idRenderLightLocal *def ); + +void R_AddDrawSurf( const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, + const idMaterial *shader, const idScreenRect &scissor ); + +void R_LinkLightSurf( const drawSurf_t **link, const srfTriangles_t *tri, const viewEntity_t *space, + const idRenderLightLocal *light, const idMaterial *shader, const idScreenRect &scissor, bool viewInsideShadow ); + +bool R_CreateAmbientCache( srfTriangles_t *tri, bool needsLighting ); +bool R_CreateLightingCache( const idRenderEntityLocal *ent, const idRenderLightLocal *light, srfTriangles_t *tri ); +void R_CreatePrivateShadowCache( srfTriangles_t *tri ); +void R_CreateVertexProgramShadowCache( srfTriangles_t *tri ); + +/* +============================================================ + +LIGHTRUN + +============================================================ +*/ + +void R_RegenerateWorld_f( const idCmdArgs &args ); + +void R_ModulateLights_f( const idCmdArgs &args ); + +void R_SetLightProject( idPlane lightProject[4], const idVec3 origin, const idVec3 targetPoint, + const idVec3 rightVector, const idVec3 upVector, const idVec3 start, const idVec3 stop ); + +void R_AddLightSurfaces( void ); +void R_AddModelSurfaces( void ); +void R_RemoveUnecessaryViewLights( void ); + +void R_FreeDerivedData( void ); +void R_ReCreateWorldReferences( void ); + +void R_CreateEntityRefs( idRenderEntityLocal *def ); +void R_CreateLightRefs( idRenderLightLocal *light ); + +void R_DeriveLightData( idRenderLightLocal *light ); +void R_FreeLightDefDerivedData( idRenderLightLocal *light ); +void R_CheckForEntityDefsUsingModel( idRenderModel *model ); + +void R_ClearEntityDefDynamicModel( idRenderEntityLocal *def ); +void R_FreeEntityDefDerivedData( idRenderEntityLocal *def, bool keepDecals, bool keepCachedDynamicModel ); +void R_FreeEntityDefCachedDynamicModel( idRenderEntityLocal *def ); +void R_FreeEntityDefDecals( idRenderEntityLocal *def ); +void R_FreeEntityDefOverlay( idRenderEntityLocal *def ); +void R_FreeEntityDefFadedDecals( idRenderEntityLocal *def, int time ); + +void R_CreateLightDefFogPortals( idRenderLightLocal *ldef ); + +/* +============================================================ + +POLYTOPE + +============================================================ +*/ + +srfTriangles_t *R_PolytopeSurface( int numPlanes, const idPlane *planes, idWinding **windings ); + +/* +============================================================ + +RENDER + +============================================================ +*/ + +void RB_EnterWeaponDepthHack(); +void RB_EnterModelDepthHack( float depth ); +void RB_LeaveDepthHack(); +void RB_DrawElementsImmediate( const srfTriangles_t *tri ); +void RB_RenderTriangleSurface( const srfTriangles_t *tri ); +void RB_T_RenderTriangleSurface( const drawSurf_t *surf ); +void RB_RenderDrawSurfListWithFunction( drawSurf_t **drawSurfs, int numDrawSurfs, + void (*triFunc_)( const drawSurf_t *) ); +void RB_RenderDrawSurfChainWithFunction( const drawSurf_t *drawSurfs, + void (*triFunc_)( const drawSurf_t *) ); +void RB_DrawShaderPasses( drawSurf_t **drawSurfs, int numDrawSurfs ); +void RB_LoadShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture ); +void RB_GetShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture, float matrix[16] ); +void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInteraction)(const drawInteraction_t *) ); + +const shaderStage_t *RB_SetLightTexture( const idRenderLightLocal *light ); + +void RB_DrawView( const void *data ); + +void RB_DetermineLightScale( void ); +void RB_STD_LightScale( void ); +void RB_BeginDrawingView (void); + +/* +============================================================ + +DRAW_STANDARD + +============================================================ +*/ + +void RB_DrawElementsWithCounters( const srfTriangles_t *tri ); +void RB_DrawShadowElementsWithCounters( const srfTriangles_t *tri, int numIndexes ); +void RB_STD_FillDepthBuffer( drawSurf_t **drawSurfs, int numDrawSurfs ); +void RB_BindVariableStageImage( const textureStage_t *texture, const float *shaderRegisters ); +void RB_BindStageTexture( const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf ); +void RB_FinishStageTexture( const textureStage_t *texture, const drawSurf_t *surf ); +void RB_StencilShadowPass( const drawSurf_t *drawSurfs ); +void RB_STD_DrawView( void ); +void RB_STD_FogAllLights( void ); +void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float textureMatrix[16] ); + +/* +============================================================ + +DRAW_* + +============================================================ +*/ + +void RB_ARB_DrawInteractions( void ); + +void R_R200_Init( void ); +void RB_R200_DrawInteractions( void ); + +void R_NV10_Init( void ); +void RB_NV10_DrawInteractions( void ); + +void R_NV20_Init( void ); +void RB_NV20_DrawInteractions( void ); + +void R_ARB2_Init( void ); +void RB_ARB2_DrawInteractions( void ); +void R_ReloadARBPrograms_f( const idCmdArgs &args ); +int R_FindARBProgram( GLenum target, const char *program ); + +typedef enum { + PROG_INVALID, + VPROG_INTERACTION, + VPROG_ENVIRONMENT, + VPROG_BUMPY_ENVIRONMENT, + VPROG_R200_INTERACTION, + VPROG_STENCIL_SHADOW, + VPROG_NV20_BUMP_AND_LIGHT, + VPROG_NV20_DIFFUSE_COLOR, + VPROG_NV20_SPECULAR_COLOR, + VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, + VPROG_TEST, + FPROG_INTERACTION, + FPROG_ENVIRONMENT, + FPROG_BUMPY_ENVIRONMENT, + FPROG_TEST, + VPROG_AMBIENT, + FPROG_AMBIENT, + VPROG_GLASSWARP, + FPROG_GLASSWARP, + PROG_USER +} program_t; + +/* + + All vertex programs use the same constant register layout: + +c[4] localLightOrigin +c[5] localViewOrigin +c[6] lightProjection S +c[7] lightProjection T +c[8] lightProjection Q +c[9] lightFalloff S +c[10] bumpMatrix S +c[11] bumpMatrix T +c[12] diffuseMatrix S +c[13] diffuseMatrix T +c[14] specularMatrix S +c[15] specularMatrix T + + +c[20] light falloff tq constant + +// texture 0 was cube map +// texture 1 will be the per-surface bump map +// texture 2 will be the light falloff texture +// texture 3 will be the light projection texture +// texture 4 is the per-surface diffuse map +// texture 5 is the per-surface specular map +// texture 6 is the specular half angle cube map + +*/ + +typedef enum { + PP_LIGHT_ORIGIN = 4, + PP_VIEW_ORIGIN, + PP_LIGHT_PROJECT_S, + PP_LIGHT_PROJECT_T, + PP_LIGHT_PROJECT_Q, + PP_LIGHT_FALLOFF_S, + PP_BUMP_MATRIX_S, + PP_BUMP_MATRIX_T, + PP_DIFFUSE_MATRIX_S, + PP_DIFFUSE_MATRIX_T, + PP_SPECULAR_MATRIX_S, + PP_SPECULAR_MATRIX_T, + PP_COLOR_MODULATE, + PP_COLOR_ADD, + + PP_LIGHT_FALLOFF_TQ = 20 // only for NV programs +} programParameter_t; + + +/* +============================================================ + +TR_STENCILSHADOWS + +"facing" should have one more element than tri->numIndexes / 3, which should be set to 1 + +============================================================ +*/ + +void R_MakeShadowFrustums( idRenderLightLocal *def ); + +typedef enum { + SG_DYNAMIC, // use infinite projections + SG_STATIC, // clip to bounds + SG_OFFLINE // perform very time consuming optimizations +} shadowGen_t; + +srfTriangles_t *R_CreateShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + shadowGen_t optimize, srfCullInfo_t &cullInfo ); + +/* +============================================================ + +TR_TURBOSHADOW + +Fast, non-clipped overshoot shadow volumes + +"facing" should have one more element than tri->numIndexes / 3, which should be set to 1 +calling this function may modify "facing" based on culling + +============================================================ +*/ + +srfTriangles_t *R_CreateVertexProgramTurboShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + srfCullInfo_t &cullInfo ); + +srfTriangles_t *R_CreateTurboShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + srfCullInfo_t &cullInfo ); + +/* +============================================================ + +util/shadowopt3 + +dmap time optimization of shadow volumes, called from R_CreateShadowVolume + +============================================================ +*/ + + +typedef struct { + idVec3 *verts; // includes both front and back projections, caller should free + int numVerts; + glIndex_t *indexes; // caller should free + + // indexes must be sorted frontCap, rearCap, silPlanes so the caps can be removed + // when the viewer is in a position that they don't need to see them + int numFrontCapIndexes; + int numRearCapIndexes; + int numSilPlaneIndexes; + int totalIndexes; +} optimizedShadow_t; + +optimizedShadow_t SuperOptimizeOccluders( idVec4 *verts, glIndex_t *indexes, int numIndexes, + idPlane projectionPlane, idVec3 projectionOrigin ); + +void CleanupOptimizedShadowTris( srfTriangles_t *tri ); + +/* +============================================================ + +TRISURF + +============================================================ +*/ + +#define USE_TRI_DATA_ALLOCATOR + +void R_InitTriSurfData( void ); +void R_ShutdownTriSurfData( void ); +void R_PurgeTriSurfData( frameData_t *frame ); +void R_ShowTriSurfMemory_f( const idCmdArgs &args ); + +srfTriangles_t * R_AllocStaticTriSurf( void ); +srfTriangles_t * R_CopyStaticTriSurf( const srfTriangles_t *tri ); +void R_AllocStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ); +void R_AllocStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ); +void R_AllocStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ); +void R_AllocStaticTriSurfPlanes( srfTriangles_t *tri, int numIndexes ); +void R_ResizeStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ); +void R_ResizeStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ); +void R_ResizeStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ); +void R_ReferenceStaticTriSurfVerts( srfTriangles_t *tri, const srfTriangles_t *reference ); +void R_ReferenceStaticTriSurfIndexes( srfTriangles_t *tri, const srfTriangles_t *reference ); +void R_FreeStaticTriSurfSilIndexes( srfTriangles_t *tri ); +void R_FreeStaticTriSurf( srfTriangles_t *tri ); +void R_FreeStaticTriSurfVertexCaches( srfTriangles_t *tri ); +void R_ReallyFreeStaticTriSurf( srfTriangles_t *tri ); +void R_FreeDeferredTriSurfs( frameData_t *frame ); +int R_TriSurfMemory( const srfTriangles_t *tri ); + +void R_BoundTriSurf( srfTriangles_t *tri ); +void R_RemoveDuplicatedTriangles( srfTriangles_t *tri ); +void R_CreateSilIndexes( srfTriangles_t *tri ); +void R_RemoveDegenerateTriangles( srfTriangles_t *tri ); +void R_RemoveUnusedVerts( srfTriangles_t *tri ); +void R_RangeCheckIndexes( const srfTriangles_t *tri ); +void R_CreateVertexNormals( srfTriangles_t *tri ); // also called by dmap +void R_DeriveFacePlanes( srfTriangles_t *tri ); // also called by renderbump +void R_CleanupTriangles( srfTriangles_t *tri, bool createNormals, bool identifySilEdges, bool useUnsmoothedTangents ); +void R_ReverseTriangles( srfTriangles_t *tri ); + +// Only deals with vertexes and indexes, not silhouettes, planes, etc. +// Does NOT perform a cleanup triangles, so there may be duplicated verts in the result. +srfTriangles_t * R_MergeSurfaceList( const srfTriangles_t **surfaces, int numSurfaces ); +srfTriangles_t * R_MergeTriangles( const srfTriangles_t *tri1, const srfTriangles_t *tri2 ); + +// if the deformed verts have significant enough texture coordinate changes to reverse the texture +// polarity of a triangle, the tangents will be incorrect +void R_DeriveTangents( srfTriangles_t *tri, bool allocFacePlanes = true ); + +// deformable meshes precalculate as much as possible from a base frame, then generate +// complete srfTriangles_t from just a new set of vertexes +typedef struct deformInfo_s { + int numSourceVerts; + + // numOutputVerts may be smaller if the input had duplicated or degenerate triangles + // it will often be larger if the input had mirrored texture seams that needed + // to be busted for proper tangent spaces + int numOutputVerts; + + int numMirroredVerts; + int * mirroredVerts; + + int numIndexes; + glIndex_t * indexes; + + glIndex_t * silIndexes; + + int numDupVerts; + int * dupVerts; + + int numSilEdges; + silEdge_t * silEdges; + + dominantTri_t * dominantTris; +} deformInfo_t; + + +deformInfo_t * R_BuildDeformInfo( int numVerts, const idDrawVert *verts, int numIndexes, const int *indexes, bool useUnsmoothedTangents ); +void R_FreeDeformInfo( deformInfo_t *deformInfo ); +int R_DeformInfoMemoryUsed( deformInfo_t *deformInfo ); + +/* +============================================================ + +SUBVIEW + +============================================================ +*/ + +bool R_PreciseCullSurface( const drawSurf_t *drawSurf, idBounds &ndcBounds ); +bool R_GenerateSubViews( void ); + +/* +============================================================ + +SCENE GENERATION + +============================================================ +*/ + +void R_InitFrameData( void ); +void R_ShutdownFrameData( void ); +int R_CountFrameData( void ); +void R_ToggleSmpFrame( void ); +void *R_FrameAlloc( int bytes ); +void *R_ClearedFrameAlloc( int bytes ); +void R_FrameFree( void *data ); + +void *R_StaticAlloc( int bytes ); // just malloc with error checking +void *R_ClearedStaticAlloc( int bytes ); // with memset +void R_StaticFree( void *data ); + + +/* +============================================================= + +RENDERER DEBUG TOOLS + +============================================================= +*/ + +float RB_DrawTextLength( const char *text, float scale, int len ); +void RB_AddDebugText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ); +void RB_ClearDebugText( int time ); +void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest ); +void RB_ClearDebugLines( int time ); +void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ); +void RB_ClearDebugPolygons( int time ); +void RB_DrawBounds( const idBounds &bounds ); +void RB_ShowLights( drawSurf_t **drawSurfs, int numDrawSurfs ); +void RB_ShowLightCount( drawSurf_t **drawSurfs, int numDrawSurfs ); +void RB_PolygonClear( void ); +void RB_ScanStencilBuffer( void ); +void RB_ShowDestinationAlpha( void ); +void RB_ShowOverdraw( void ); +void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs ); +void RB_ShutdownDebugTools( void ); + +/* +============================================================= + +TR_BACKEND + +============================================================= +*/ + +void RB_SetDefaultGLState( void ); +void RB_SetGL2D( void ); + +// write a comment to the r_logFile if it is enabled +void RB_LogComment( const char *comment, ... ) id_attribute((format(printf,1,2))); + +void RB_ShowImages( void ); + +void RB_ExecuteBackEndCommands( const emptyCommand_t *cmds ); + + +/* +============================================================= + +TR_GUISURF + +============================================================= +*/ + +void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] ); +void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ); + +/* +============================================================= + +TR_ORDERINDEXES + +============================================================= +*/ + +void R_OrderIndexes( int numIndexes, glIndex_t *indexes ); + +/* +============================================================= + +TR_DEFORM + +============================================================= +*/ + +void R_DeformDrawSurf( drawSurf_t *drawSurf ); + +/* +============================================================= + +TR_TRACE + +============================================================= +*/ + +typedef struct { + float fraction; + // only valid if fraction < 1.0 + idVec3 point; + idVec3 normal; + int indexes[3]; +} localTrace_t; + +localTrace_t R_LocalTrace( const idVec3 &start, const idVec3 &end, const float radius, const srfTriangles_t *tri ); +void RB_ShowTrace( drawSurf_t **drawSurfs, int numDrawSurfs ); + +/* +============================================================= + +TR_SHADOWBOUNDS + +============================================================= +*/ +idScreenRect R_CalcIntersectionScissor( const idRenderLightLocal * lightDef, + const idRenderEntityLocal * entityDef, + const viewDef_t * viewDef ); + +//============================================= + +#include "RenderWorld_local.h" +#include "GuiModel.h" +#include "VertexCache.h" + +#endif /* !__TR_LOCAL_H__ */ diff --git a/renderer/tr_main.cpp b/renderer/tr_main.cpp new file mode 100644 index 000000000..69cdb2712 --- /dev/null +++ b/renderer/tr_main.cpp @@ -0,0 +1,1154 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#ifdef __ppc__ +#include +#endif +#if defined(MACOS_X) && defined(__i386__) +#include +#endif + +//==================================================================== + +/* +====================== +idScreenRect::Clear +====================== +*/ +void idScreenRect::Clear() { + x1 = y1 = 32000; + x2 = y2 = -32000; + zmin = 0.0f; zmax = 1.0f; +} + +/* +====================== +idScreenRect::AddPoint +====================== +*/ +void idScreenRect::AddPoint( float x, float y ) { + int ix = idMath::FtoiFast( x ); + int iy = idMath::FtoiFast( y ); + + if ( ix < x1 ) { + x1 = ix; + } + if ( ix > x2 ) { + x2 = ix; + } + if ( iy < y1 ) { + y1 = iy; + } + if ( iy > y2 ) { + y2 = iy; + } +} + +/* +====================== +idScreenRect::Expand +====================== +*/ +void idScreenRect::Expand() { + x1--; + y1--; + x2++; + y2++; +} + +/* +====================== +idScreenRect::Intersect +====================== +*/ +void idScreenRect::Intersect( const idScreenRect &rect ) { + if ( rect.x1 > x1 ) { + x1 = rect.x1; + } + if ( rect.x2 < x2 ) { + x2 = rect.x2; + } + if ( rect.y1 > y1 ) { + y1 = rect.y1; + } + if ( rect.y2 < y2 ) { + y2 = rect.y2; + } +} + +/* +====================== +idScreenRect::Union +====================== +*/ +void idScreenRect::Union( const idScreenRect &rect ) { + if ( rect.x1 < x1 ) { + x1 = rect.x1; + } + if ( rect.x2 > x2 ) { + x2 = rect.x2; + } + if ( rect.y1 < y1 ) { + y1 = rect.y1; + } + if ( rect.y2 > y2 ) { + y2 = rect.y2; + } +} + +/* +====================== +idScreenRect::Equals +====================== +*/ +bool idScreenRect::Equals( const idScreenRect &rect ) const { + return ( x1 == rect.x1 && x2 == rect.x2 && y1 == rect.y1 && y2 == rect.y2 ); +} + +/* +====================== +idScreenRect::IsEmpty +====================== +*/ +bool idScreenRect::IsEmpty() const { + return ( x1 > x2 || y1 > y2 ); +} + +/* +====================== +R_ScreenRectFromViewFrustumBounds +====================== +*/ +idScreenRect R_ScreenRectFromViewFrustumBounds( const idBounds &bounds ) { + idScreenRect screenRect; + + screenRect.x1 = idMath::FtoiFast( 0.5f * ( 1.0f - bounds[1].y ) * ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ) ); + screenRect.x2 = idMath::FtoiFast( 0.5f * ( 1.0f - bounds[0].y ) * ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 ) ); + screenRect.y1 = idMath::FtoiFast( 0.5f * ( 1.0f + bounds[0].z ) * ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ) ); + screenRect.y2 = idMath::FtoiFast( 0.5f * ( 1.0f + bounds[1].z ) * ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 ) ); + + if ( r_useDepthBoundsTest.GetInteger() ) { + R_TransformEyeZToWin( -bounds[0].x, tr.viewDef->projectionMatrix, screenRect.zmin ); + R_TransformEyeZToWin( -bounds[1].x, tr.viewDef->projectionMatrix, screenRect.zmax ); + } + + return screenRect; +} + +/* +====================== +R_ShowColoredScreenRect +====================== +*/ +void R_ShowColoredScreenRect( const idScreenRect &rect, int colorIndex ) { + if ( !rect.IsEmpty() ) { + static idVec4 colors[] = { colorRed, colorGreen, colorBlue, colorYellow, colorMagenta, colorCyan, colorWhite, colorPurple }; + tr.viewDef->renderWorld->DebugScreenRect( colors[colorIndex & 7], rect, tr.viewDef ); + } +} + +/* +==================== +R_ToggleSmpFrame +==================== +*/ +void R_ToggleSmpFrame( void ) { + if ( r_lockSurfaces.GetBool() ) { + return; + } + R_FreeDeferredTriSurfs( frameData ); + + // clear frame-temporary data + frameData_t *frame; + frameMemoryBlock_t *block; + + // update the highwater mark + R_CountFrameData(); + + frame = frameData; + + // reset the memory allocation to the first block + frame->alloc = frame->memory; + + // clear all the blocks + for ( block = frame->memory ; block ; block = block->next ) { + block->used = 0; + } + + R_ClearCommandChain(); +} + + +//===================================================== + +#define MEMORY_BLOCK_SIZE 0x100000 + +/* +===================== +R_ShutdownFrameData +===================== +*/ +void R_ShutdownFrameData( void ) { + frameData_t *frame; + frameMemoryBlock_t *block; + + // free any current data + frame = frameData; + if ( !frame ) { + return; + } + + R_FreeDeferredTriSurfs( frame ); + + frameMemoryBlock_t *nextBlock; + for ( block = frame->memory ; block ; block = nextBlock ) { + nextBlock = block->next; + Mem_Free( block ); + } + Mem_Free( frame ); + frameData = NULL; +} + +/* +===================== +R_InitFrameData +===================== +*/ +void R_InitFrameData( void ) { + int size; + frameData_t *frame; + frameMemoryBlock_t *block; + + R_ShutdownFrameData(); + + frameData = (frameData_t *)Mem_ClearedAlloc( sizeof( *frameData )); + frame = frameData; + size = MEMORY_BLOCK_SIZE; + block = (frameMemoryBlock_t *)Mem_Alloc( size + sizeof( *block ) ); + if ( !block ) { + common->FatalError( "R_InitFrameData: Mem_Alloc() failed" ); + } + block->size = size; + block->used = 0; + block->next = NULL; + frame->memory = block; + frame->memoryHighwater = 0; + + R_ToggleSmpFrame(); +} + +/* +================ +R_CountFrameData +================ +*/ +int R_CountFrameData( void ) { + frameData_t *frame; + frameMemoryBlock_t *block; + int count; + + count = 0; + frame = frameData; + for ( block = frame->memory ; block ; block=block->next ) { + count += block->used; + if ( block == frame->alloc ) { + break; + } + } + + // note if this is a new highwater mark + if ( count > frame->memoryHighwater ) { + frame->memoryHighwater = count; + } + + return count; +} + +/* +================= +R_StaticAlloc +================= +*/ +void *R_StaticAlloc( int bytes ) { + void *buf; + + tr.pc.c_alloc++; + + tr.staticAllocCount += bytes; + + buf = Mem_Alloc( bytes ); + + // don't exit on failure on zero length allocations since the old code didn't + if ( !buf && ( bytes != 0 ) ) { + common->FatalError( "R_StaticAlloc failed on %i bytes", bytes ); + } + return buf; +} + +/* +================= +R_ClearedStaticAlloc +================= +*/ +void *R_ClearedStaticAlloc( int bytes ) { + void *buf; + + buf = R_StaticAlloc( bytes ); + SIMDProcessor->Memset( buf, 0, bytes ); + return buf; +} + +/* +================= +R_StaticFree +================= +*/ +void R_StaticFree( void *data ) { + tr.pc.c_free++; + Mem_Free( data ); +} + +/* +================ +R_FrameAlloc + +This data will be automatically freed when the +current frame's back end completes. + +This should only be called by the front end. The +back end shouldn't need to allocate memory. + +If we passed smpFrame in, the back end could +alloc memory, because it will always be a +different frameData than the front end is using. + +All temporary data, like dynamic tesselations +and local spaces are allocated here. + +The memory will not move, but it may not be +contiguous with previous allocations even +from this frame. + +The memory is NOT zero filled. +Should part of this be inlined in a macro? +================ +*/ +void *R_FrameAlloc( int bytes ) { + frameData_t *frame; + frameMemoryBlock_t *block; + void *buf; + + bytes = (bytes+16)&~15; + // see if it can be satisfied in the current block + frame = frameData; + block = frame->alloc; + + if ( block->size - block->used >= bytes ) { + buf = block->base + block->used; + block->used += bytes; + return buf; + } + + // advance to the next memory block if available + block = block->next; + // create a new block if we are at the end of + // the chain + if ( !block ) { + int size; + + size = MEMORY_BLOCK_SIZE; + block = (frameMemoryBlock_t *)Mem_Alloc( size + sizeof( *block ) ); + if ( !block ) { + common->FatalError( "R_FrameAlloc: Mem_Alloc() failed" ); + } + block->size = size; + block->used = 0; + block->next = NULL; + frame->alloc->next = block; + } + + // we could fix this if we needed to... + if ( bytes > block->size ) { + common->FatalError( "R_FrameAlloc of %i exceeded MEMORY_BLOCK_SIZE", + bytes ); + } + + frame->alloc = block; + + block->used = bytes; + + return block->base; +} + +/* +================== +R_ClearedFrameAlloc +================== +*/ +void *R_ClearedFrameAlloc( int bytes ) { + void *r; + + r = R_FrameAlloc( bytes ); + SIMDProcessor->Memset( r, 0, bytes ); + return r; +} + + +/* +================== +R_FrameFree + +This does nothing at all, as the frame data is reused every frame +and can only be stack allocated. + +The only reason for it's existance is so functions that can +use either static or frame memory can set function pointers +to both alloc and free. +================== +*/ +void R_FrameFree( void *data ) { +} + + + +//========================================================================== + +void R_AxisToModelMatrix( const idMat3 &axis, const idVec3 &origin, float modelMatrix[16] ) { + modelMatrix[0] = axis[0][0]; + modelMatrix[4] = axis[1][0]; + modelMatrix[8] = axis[2][0]; + modelMatrix[12] = origin[0]; + + modelMatrix[1] = axis[0][1]; + modelMatrix[5] = axis[1][1]; + modelMatrix[9] = axis[2][1]; + modelMatrix[13] = origin[1]; + + modelMatrix[2] = axis[0][2]; + modelMatrix[6] = axis[1][2]; + modelMatrix[10] = axis[2][2]; + modelMatrix[14] = origin[2]; + + modelMatrix[3] = 0; + modelMatrix[7] = 0; + modelMatrix[11] = 0; + modelMatrix[15] = 1; +} + + +// FIXME: these assume no skewing or scaling transforms + +void R_LocalPointToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ) { +#if defined(MACOS_X) && defined(__i386__) + __m128 m0, m1, m2, m3; + __m128 in0, in1, in2; + float i0,i1,i2; + i0 = in[0]; + i1 = in[1]; + i2 = in[2]; + + m0 = _mm_loadu_ps(&modelMatrix[0]); + m1 = _mm_loadu_ps(&modelMatrix[4]); + m2 = _mm_loadu_ps(&modelMatrix[8]); + m3 = _mm_loadu_ps(&modelMatrix[12]); + + in0 = _mm_load1_ps(&i0); + in1 = _mm_load1_ps(&i1); + in2 = _mm_load1_ps(&i2); + + m0 = _mm_mul_ps(m0, in0); + m1 = _mm_mul_ps(m1, in1); + m2 = _mm_mul_ps(m2, in2); + + m0 = _mm_add_ps(m0, m1); + m0 = _mm_add_ps(m0, m2); + m0 = _mm_add_ps(m0, m3); + + _mm_store_ss(&out[0], m0); + m1 = (__m128) _mm_shuffle_epi32((__m128i)m0, 0x55); + _mm_store_ss(&out[1], m1); + m2 = _mm_movehl_ps(m2, m0); + _mm_store_ss(&out[2], m2); +#else + out[0] = in[0] * modelMatrix[0] + in[1] * modelMatrix[4] + + in[2] * modelMatrix[8] + modelMatrix[12]; + out[1] = in[0] * modelMatrix[1] + in[1] * modelMatrix[5] + + in[2] * modelMatrix[9] + modelMatrix[13]; + out[2] = in[0] * modelMatrix[2] + in[1] * modelMatrix[6] + + in[2] * modelMatrix[10] + modelMatrix[14]; +#endif +} + +void R_PointTimesMatrix( const float modelMatrix[16], const idVec4 &in, idVec4 &out ) { + out[0] = in[0] * modelMatrix[0] + in[1] * modelMatrix[4] + + in[2] * modelMatrix[8] + modelMatrix[12]; + out[1] = in[0] * modelMatrix[1] + in[1] * modelMatrix[5] + + in[2] * modelMatrix[9] + modelMatrix[13]; + out[2] = in[0] * modelMatrix[2] + in[1] * modelMatrix[6] + + in[2] * modelMatrix[10] + modelMatrix[14]; + out[3] = in[0] * modelMatrix[3] + in[1] * modelMatrix[7] + + in[2] * modelMatrix[11] + modelMatrix[15]; +} + +void R_GlobalPointToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ) { + idVec3 temp; + + VectorSubtract( in, &modelMatrix[12], temp ); + + out[0] = DotProduct( temp, &modelMatrix[0] ); + out[1] = DotProduct( temp, &modelMatrix[4] ); + out[2] = DotProduct( temp, &modelMatrix[8] ); +} + +void R_LocalVectorToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ) { + out[0] = in[0] * modelMatrix[0] + in[1] * modelMatrix[4] + + in[2] * modelMatrix[8]; + out[1] = in[0] * modelMatrix[1] + in[1] * modelMatrix[5] + + in[2] * modelMatrix[9]; + out[2] = in[0] * modelMatrix[2] + in[1] * modelMatrix[6] + + in[2] * modelMatrix[10]; +} + +void R_GlobalVectorToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ) { + out[0] = DotProduct( in, &modelMatrix[0] ); + out[1] = DotProduct( in, &modelMatrix[4] ); + out[2] = DotProduct( in, &modelMatrix[8] ); +} + +void R_GlobalPlaneToLocal( const float modelMatrix[16], const idPlane &in, idPlane &out ) { + out[0] = DotProduct( in, &modelMatrix[0] ); + out[1] = DotProduct( in, &modelMatrix[4] ); + out[2] = DotProduct( in, &modelMatrix[8] ); + out[3] = in[3] + modelMatrix[12] * in[0] + modelMatrix[13] * in[1] + modelMatrix[14] * in[2]; +} + +void R_LocalPlaneToGlobal( const float modelMatrix[16], const idPlane &in, idPlane &out ) { + float offset; + + R_LocalVectorToGlobal( modelMatrix, in.Normal(), out.Normal() ); + + offset = modelMatrix[12] * out[0] + modelMatrix[13] * out[1] + modelMatrix[14] * out[2]; + out[3] = in[3] - offset; +} + +// transform Z in eye coordinates to window coordinates +void R_TransformEyeZToWin( float src_z, const float *projectionMatrix, float &dst_z ) { + float clip_z, clip_w; + + // projection + clip_z = src_z * projectionMatrix[ 2 + 2 * 4 ] + projectionMatrix[ 2 + 3 * 4 ]; + clip_w = src_z * projectionMatrix[ 3 + 2 * 4 ] + projectionMatrix[ 3 + 3 * 4 ]; + + if ( clip_w <= 0.0f ) { + dst_z = 0.0f; // clamp to near plane + } else { + dst_z = clip_z / clip_w; + dst_z = dst_z * 0.5f + 0.5f; // convert to window coords + } +} + +/* +================= +R_RadiusCullLocalBox + +A fast, conservative center-to-corner culling test +Returns true if the box is outside the given global frustum, (positive sides are out) +================= +*/ +bool R_RadiusCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ) { + int i; + float d; + idVec3 worldOrigin; + float worldRadius; + const idPlane *frust; + + if ( r_useCulling.GetInteger() == 0 ) { + return false; + } + + // transform the surface bounds into world space + idVec3 localOrigin = ( bounds[0] + bounds[1] ) * 0.5; + + R_LocalPointToGlobal( modelMatrix, localOrigin, worldOrigin ); + + worldRadius = (bounds[0] - localOrigin).Length(); // FIXME: won't be correct for scaled objects + + for ( i = 0 ; i < numPlanes ; i++ ) { + frust = planes + i; + d = frust->Distance( worldOrigin ); + if ( d > worldRadius ) { + return true; // culled + } + } + + return false; // no culled +} + +/* +================= +R_CornerCullLocalBox + +Tests all corners against the frustum. +Can still generate a few false positives when the box is outside a corner. +Returns true if the box is outside the given global frustum, (positive sides are out) +================= +*/ +bool R_CornerCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ) { + int i, j; + idVec3 transformed[8]; + float dists[8]; + idVec3 v; + const idPlane *frust; + + // we can disable box culling for experimental timing purposes + if ( r_useCulling.GetInteger() < 2 ) { + return false; + } + + // transform into world space + for ( i = 0 ; i < 8 ; i++ ) { + v[0] = bounds[i&1][0]; + v[1] = bounds[(i>>1)&1][1]; + v[2] = bounds[(i>>2)&1][2]; + + R_LocalPointToGlobal( modelMatrix, v, transformed[i] ); + } + + // check against frustum planes + for ( i = 0 ; i < numPlanes ; i++ ) { + frust = planes + i; + for ( j = 0 ; j < 8 ; j++ ) { + dists[j] = frust->Distance( transformed[j] ); + if ( dists[j] < 0 ) { + break; + } + } + if ( j == 8 ) { + // all points were behind one of the planes + tr.pc.c_box_cull_out++; + return true; + } + } + + tr.pc.c_box_cull_in++; + + return false; // not culled +} + +/* +================= +R_CullLocalBox + +Performs quick test before expensive test +Returns true if the box is outside the given global frustum, (positive sides are out) +================= +*/ +bool R_CullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ) { + if ( R_RadiusCullLocalBox( bounds, modelMatrix, numPlanes, planes ) ) { + return true; + } + return R_CornerCullLocalBox( bounds, modelMatrix, numPlanes, planes ); +} + +/* +========================== +R_TransformModelToClip +========================== +*/ +void R_TransformModelToClip( const idVec3 &src, const float *modelMatrix, const float *projectionMatrix, idPlane &eye, idPlane &dst ) { + int i; + + for ( i = 0 ; i < 4 ; i++ ) { + eye[i] = + src[0] * modelMatrix[ i + 0 * 4 ] + + src[1] * modelMatrix[ i + 1 * 4 ] + + src[2] * modelMatrix[ i + 2 * 4 ] + + 1 * modelMatrix[ i + 3 * 4 ]; + } + + for ( i = 0 ; i < 4 ; i++ ) { + dst[i] = + eye[0] * projectionMatrix[ i + 0 * 4 ] + + eye[1] * projectionMatrix[ i + 1 * 4 ] + + eye[2] * projectionMatrix[ i + 2 * 4 ] + + eye[3] * projectionMatrix[ i + 3 * 4 ]; + } +} + +/* +========================== +R_GlobalToNormalizedDeviceCoordinates + +-1 to 1 range in x, y, and z +========================== +*/ +void R_GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ) { + int i; + idPlane view; + idPlane clip; + + // _D3XP added work on primaryView when no viewDef + if ( !tr.viewDef ) { + + for ( i = 0 ; i < 4 ; i ++ ) { + view[i] = + global[0] * tr.primaryView->worldSpace.modelViewMatrix[ i + 0 * 4 ] + + global[1] * tr.primaryView->worldSpace.modelViewMatrix[ i + 1 * 4 ] + + global[2] * tr.primaryView->worldSpace.modelViewMatrix[ i + 2 * 4 ] + + tr.primaryView->worldSpace.modelViewMatrix[ i + 3 * 4 ]; + } + + for ( i = 0 ; i < 4 ; i ++ ) { + clip[i] = + view[0] * tr.primaryView->projectionMatrix[ i + 0 * 4 ] + + view[1] * tr.primaryView->projectionMatrix[ i + 1 * 4 ] + + view[2] * tr.primaryView->projectionMatrix[ i + 2 * 4 ] + + view[3] * tr.primaryView->projectionMatrix[ i + 3 * 4 ]; + } + + } else { + + for ( i = 0 ; i < 4 ; i ++ ) { + view[i] = + global[0] * tr.viewDef->worldSpace.modelViewMatrix[ i + 0 * 4 ] + + global[1] * tr.viewDef->worldSpace.modelViewMatrix[ i + 1 * 4 ] + + global[2] * tr.viewDef->worldSpace.modelViewMatrix[ i + 2 * 4 ] + + tr.viewDef->worldSpace.modelViewMatrix[ i + 3 * 4 ]; + } + + + for ( i = 0 ; i < 4 ; i ++ ) { + clip[i] = + view[0] * tr.viewDef->projectionMatrix[ i + 0 * 4 ] + + view[1] * tr.viewDef->projectionMatrix[ i + 1 * 4 ] + + view[2] * tr.viewDef->projectionMatrix[ i + 2 * 4 ] + + view[3] * tr.viewDef->projectionMatrix[ i + 3 * 4 ]; + } + + } + + ndc[0] = clip[0] / clip[3]; + ndc[1] = clip[1] / clip[3]; + ndc[2] = ( clip[2] + clip[3] ) / ( 2 * clip[3] ); +} + +/* +========================== +R_TransformClipToDevice + +Clip to normalized device coordinates +========================== +*/ +void R_TransformClipToDevice( const idPlane &clip, const viewDef_t *view, idVec3 &normalized ) { + normalized[0] = clip[0] / clip[3]; + normalized[1] = clip[1] / clip[3]; + normalized[2] = clip[2] / clip[3]; +} + + +/* +========================== +myGlMultMatrix +========================== +*/ +void myGlMultMatrix( const float a[16], const float b[16], float out[16] ) { +#if 0 + int i, j; + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + out[ i * 4 + j ] = + a [ i * 4 + 0 ] * b [ 0 * 4 + j ] + + a [ i * 4 + 1 ] * b [ 1 * 4 + j ] + + a [ i * 4 + 2 ] * b [ 2 * 4 + j ] + + a [ i * 4 + 3 ] * b [ 3 * 4 + j ]; + } + } +#else + out[0*4+0] = a[0*4+0]*b[0*4+0] + a[0*4+1]*b[1*4+0] + a[0*4+2]*b[2*4+0] + a[0*4+3]*b[3*4+0]; + out[0*4+1] = a[0*4+0]*b[0*4+1] + a[0*4+1]*b[1*4+1] + a[0*4+2]*b[2*4+1] + a[0*4+3]*b[3*4+1]; + out[0*4+2] = a[0*4+0]*b[0*4+2] + a[0*4+1]*b[1*4+2] + a[0*4+2]*b[2*4+2] + a[0*4+3]*b[3*4+2]; + out[0*4+3] = a[0*4+0]*b[0*4+3] + a[0*4+1]*b[1*4+3] + a[0*4+2]*b[2*4+3] + a[0*4+3]*b[3*4+3]; + out[1*4+0] = a[1*4+0]*b[0*4+0] + a[1*4+1]*b[1*4+0] + a[1*4+2]*b[2*4+0] + a[1*4+3]*b[3*4+0]; + out[1*4+1] = a[1*4+0]*b[0*4+1] + a[1*4+1]*b[1*4+1] + a[1*4+2]*b[2*4+1] + a[1*4+3]*b[3*4+1]; + out[1*4+2] = a[1*4+0]*b[0*4+2] + a[1*4+1]*b[1*4+2] + a[1*4+2]*b[2*4+2] + a[1*4+3]*b[3*4+2]; + out[1*4+3] = a[1*4+0]*b[0*4+3] + a[1*4+1]*b[1*4+3] + a[1*4+2]*b[2*4+3] + a[1*4+3]*b[3*4+3]; + out[2*4+0] = a[2*4+0]*b[0*4+0] + a[2*4+1]*b[1*4+0] + a[2*4+2]*b[2*4+0] + a[2*4+3]*b[3*4+0]; + out[2*4+1] = a[2*4+0]*b[0*4+1] + a[2*4+1]*b[1*4+1] + a[2*4+2]*b[2*4+1] + a[2*4+3]*b[3*4+1]; + out[2*4+2] = a[2*4+0]*b[0*4+2] + a[2*4+1]*b[1*4+2] + a[2*4+2]*b[2*4+2] + a[2*4+3]*b[3*4+2]; + out[2*4+3] = a[2*4+0]*b[0*4+3] + a[2*4+1]*b[1*4+3] + a[2*4+2]*b[2*4+3] + a[2*4+3]*b[3*4+3]; + out[3*4+0] = a[3*4+0]*b[0*4+0] + a[3*4+1]*b[1*4+0] + a[3*4+2]*b[2*4+0] + a[3*4+3]*b[3*4+0]; + out[3*4+1] = a[3*4+0]*b[0*4+1] + a[3*4+1]*b[1*4+1] + a[3*4+2]*b[2*4+1] + a[3*4+3]*b[3*4+1]; + out[3*4+2] = a[3*4+0]*b[0*4+2] + a[3*4+1]*b[1*4+2] + a[3*4+2]*b[2*4+2] + a[3*4+3]*b[3*4+2]; + out[3*4+3] = a[3*4+0]*b[0*4+3] + a[3*4+1]*b[1*4+3] + a[3*4+2]*b[2*4+3] + a[3*4+3]*b[3*4+3]; +#endif +} + +/* +================ +R_TransposeGLMatrix +================ +*/ +void R_TransposeGLMatrix( const float in[16], float out[16] ) { + int i, j; + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + out[i*4+j] = in[j*4+i]; + } + } +} + +/* +================= +R_SetViewMatrix + +Sets up the world to view matrix for a given viewParm +================= +*/ +void R_SetViewMatrix( viewDef_t *viewDef ) { + idVec3 origin; + viewEntity_t *world; + float viewerMatrix[16]; + static float s_flipMatrix[16] = { + // convert from our coordinate system (looking down X) + // to OpenGL's coordinate system (looking down -Z) + 0, 0, -1, 0, + -1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 + }; + + world = &viewDef->worldSpace; + + memset( world, 0, sizeof(*world) ); + + // the model matrix is an identity + world->modelMatrix[0*4+0] = 1; + world->modelMatrix[1*4+1] = 1; + world->modelMatrix[2*4+2] = 1; + + // transform by the camera placement + origin = viewDef->renderView.vieworg; + + viewerMatrix[0] = viewDef->renderView.viewaxis[0][0]; + viewerMatrix[4] = viewDef->renderView.viewaxis[0][1]; + viewerMatrix[8] = viewDef->renderView.viewaxis[0][2]; + viewerMatrix[12] = -origin[0] * viewerMatrix[0] + -origin[1] * viewerMatrix[4] + -origin[2] * viewerMatrix[8]; + + viewerMatrix[1] = viewDef->renderView.viewaxis[1][0]; + viewerMatrix[5] = viewDef->renderView.viewaxis[1][1]; + viewerMatrix[9] = viewDef->renderView.viewaxis[1][2]; + viewerMatrix[13] = -origin[0] * viewerMatrix[1] + -origin[1] * viewerMatrix[5] + -origin[2] * viewerMatrix[9]; + + viewerMatrix[2] = viewDef->renderView.viewaxis[2][0]; + viewerMatrix[6] = viewDef->renderView.viewaxis[2][1]; + viewerMatrix[10] = viewDef->renderView.viewaxis[2][2]; + viewerMatrix[14] = -origin[0] * viewerMatrix[2] + -origin[1] * viewerMatrix[6] + -origin[2] * viewerMatrix[10]; + + viewerMatrix[3] = 0; + viewerMatrix[7] = 0; + viewerMatrix[11] = 0; + viewerMatrix[15] = 1; + + // convert from our coordinate system (looking down X) + // to OpenGL's coordinate system (looking down -Z) + myGlMultMatrix( viewerMatrix, s_flipMatrix, world->modelViewMatrix ); +} + +/* +=============== +R_SetupProjection + +This uses the "infinite far z" trick +=============== +*/ +void R_SetupProjection( void ) { + float xmin, xmax, ymin, ymax; + float width, height; + float zNear; + float jitterx, jittery; + static idRandom random; + + // random jittering is usefull when multiple + // frames are going to be blended together + // for motion blurred anti-aliasing + if ( r_jitter.GetBool() ) { + jitterx = random.RandomFloat(); + jittery = random.RandomFloat(); + } else { + jitterx = jittery = 0; + } + + // + // set up projection matrix + // + zNear = r_znear.GetFloat(); + if ( tr.viewDef->renderView.cramZNear ) { + zNear *= 0.25; + } + + ymax = zNear * tan( tr.viewDef->renderView.fov_y * idMath::PI / 360.0f ); + ymin = -ymax; + + xmax = zNear * tan( tr.viewDef->renderView.fov_x * idMath::PI / 360.0f ); + xmin = -xmax; + + width = xmax - xmin; + height = ymax - ymin; + + jitterx = jitterx * width / ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 + 1 ); + xmin += jitterx; + xmax += jitterx; + jittery = jittery * height / ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 + 1 ); + ymin += jittery; + ymax += jittery; + + tr.viewDef->projectionMatrix[0] = 2 * zNear / width; + tr.viewDef->projectionMatrix[4] = 0; + tr.viewDef->projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0 + tr.viewDef->projectionMatrix[12] = 0; + + tr.viewDef->projectionMatrix[1] = 0; + tr.viewDef->projectionMatrix[5] = 2 * zNear / height; + tr.viewDef->projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 + tr.viewDef->projectionMatrix[13] = 0; + + // this is the far-plane-at-infinity formulation, and + // crunches the Z range slightly so w=0 vertexes do not + // rasterize right at the wraparound point + tr.viewDef->projectionMatrix[2] = 0; + tr.viewDef->projectionMatrix[6] = 0; + tr.viewDef->projectionMatrix[10] = -0.999f; + tr.viewDef->projectionMatrix[14] = -2.0f * zNear; + + tr.viewDef->projectionMatrix[3] = 0; + tr.viewDef->projectionMatrix[7] = 0; + tr.viewDef->projectionMatrix[11] = -1; + tr.viewDef->projectionMatrix[15] = 0; +} + +/* +================= +R_SetupViewFrustum + +Setup that culling frustum planes for the current view +FIXME: derive from modelview matrix times projection matrix +================= +*/ +static void R_SetupViewFrustum( void ) { + int i; + float xs, xc; + float ang; + + ang = DEG2RAD( tr.viewDef->renderView.fov_x ) * 0.5f; + idMath::SinCos( ang, xs, xc ); + + tr.viewDef->frustum[0] = xs * tr.viewDef->renderView.viewaxis[0] + xc * tr.viewDef->renderView.viewaxis[1]; + tr.viewDef->frustum[1] = xs * tr.viewDef->renderView.viewaxis[0] - xc * tr.viewDef->renderView.viewaxis[1]; + + ang = DEG2RAD( tr.viewDef->renderView.fov_y ) * 0.5f; + idMath::SinCos( ang, xs, xc ); + + tr.viewDef->frustum[2] = xs * tr.viewDef->renderView.viewaxis[0] + xc * tr.viewDef->renderView.viewaxis[2]; + tr.viewDef->frustum[3] = xs * tr.viewDef->renderView.viewaxis[0] - xc * tr.viewDef->renderView.viewaxis[2]; + + // plane four is the front clipping plane + tr.viewDef->frustum[4] = /* vec3_origin - */ tr.viewDef->renderView.viewaxis[0]; + + for ( i = 0; i < 5; i++ ) { + // flip direction so positive side faces out (FIXME: globally unify this) + tr.viewDef->frustum[i] = -tr.viewDef->frustum[i].Normal(); + tr.viewDef->frustum[i][3] = -( tr.viewDef->renderView.vieworg * tr.viewDef->frustum[i].Normal() ); + } + + // eventually, plane five will be the rear clipping plane for fog + + float dNear, dFar, dLeft, dUp; + + dNear = r_znear.GetFloat(); + if ( tr.viewDef->renderView.cramZNear ) { + dNear *= 0.25f; + } + + dFar = MAX_WORLD_SIZE; + dLeft = dFar * tan( DEG2RAD( tr.viewDef->renderView.fov_x * 0.5f ) ); + dUp = dFar * tan( DEG2RAD( tr.viewDef->renderView.fov_y * 0.5f ) ); + tr.viewDef->viewFrustum.SetOrigin( tr.viewDef->renderView.vieworg ); + tr.viewDef->viewFrustum.SetAxis( tr.viewDef->renderView.viewaxis ); + tr.viewDef->viewFrustum.SetSize( dNear, dFar, dLeft, dUp ); +} + +/* +=================== +R_ConstrainViewFrustum +=================== +*/ +static void R_ConstrainViewFrustum( void ) { + idBounds bounds; + + // constrain the view frustum to the total bounds of all visible lights and visible entities + bounds.Clear(); + for ( viewLight_t *vLight = tr.viewDef->viewLights; vLight; vLight = vLight->next ) { + bounds.AddBounds( vLight->lightDef->frustumTris->bounds ); + } + for ( viewEntity_t *vEntity = tr.viewDef->viewEntitys; vEntity; vEntity = vEntity->next ) { + bounds.AddBounds( vEntity->entityDef->referenceBounds ); + } + tr.viewDef->viewFrustum.ConstrainToBounds( bounds ); + + if ( r_useFrustumFarDistance.GetFloat() > 0.0f ) { + tr.viewDef->viewFrustum.MoveFarDistance( r_useFrustumFarDistance.GetFloat() ); + } +} + +/* +========================================================================================== + +DRAWSURF SORTING + +========================================================================================== +*/ + + +/* +======================= +R_QsortSurfaces + +======================= +*/ +static int R_QsortSurfaces( const void *a, const void *b ) { + const drawSurf_t *ea, *eb; + + ea = *(drawSurf_t **)a; + eb = *(drawSurf_t **)b; + + if ( ea->sort < eb->sort ) { + return -1; + } + if ( ea->sort > eb->sort ) { + return 1; + } + return 0; +} + + +/* +================= +R_SortDrawSurfs +================= +*/ +static void R_SortDrawSurfs( void ) { + // sort the drawsurfs by sort type, then orientation, then shader + qsort( tr.viewDef->drawSurfs, tr.viewDef->numDrawSurfs, sizeof( tr.viewDef->drawSurfs[0] ), + R_QsortSurfaces ); +} + + + +//======================================================================== + + +//============================================================================== + + + +/* +================ +R_RenderView + +A view may be either the actual camera view, +a mirror / remote location, or a 3D view on a gui surface. + +Parms will typically be allocated with R_FrameAlloc +================ +*/ +void R_RenderView( viewDef_t *parms ) { + viewDef_t *oldView; + + if ( parms->renderView.width <= 0 || parms->renderView.height <= 0 ) { + return; + } + + tr.viewCount++; + + // save view in case we are a subview + oldView = tr.viewDef; + + tr.viewDef = parms; + + tr.sortOffset = 0; + + // set the matrix for world space to eye space + R_SetViewMatrix( tr.viewDef ); + + // the four sides of the view frustum are needed + // for culling and portal visibility + R_SetupViewFrustum(); + + // we need to set the projection matrix before doing + // portal-to-screen scissor box calculations + R_SetupProjection(); + + // identify all the visible portalAreas, and the entityDefs and + // lightDefs that are in them and pass culling. + static_cast(parms->renderWorld)->FindViewLightsAndEntities(); + + // constrain the view frustum to the view lights and entities + R_ConstrainViewFrustum(); + + // make sure that interactions exist for all light / entity combinations + // that are visible + // add any pre-generated light shadows, and calculate the light shader values + R_AddLightSurfaces(); + + // adds ambient surfaces and create any necessary interaction surfaces to add to the light + // lists + R_AddModelSurfaces(); + + // any viewLight that didn't have visible surfaces can have it's shadows removed + R_RemoveUnecessaryViewLights(); + + // sort all the ambient surfaces for translucency ordering + R_SortDrawSurfs(); + + // generate any subviews (mirrors, cameras, etc) before adding this view + if ( R_GenerateSubViews() ) { + // if we are debugging subviews, allow the skipping of the + // main view draw + if ( r_subviewOnly.GetBool() ) { + return; + } + } + + // write everything needed to the demo file + if ( session->writeDemo ) { + static_cast(parms->renderWorld)->WriteVisibleDefs( tr.viewDef ); + } + + // add the rendering commands for this viewDef + R_AddDrawViewCmd( parms ); + + // restore view in case we are a subview + tr.viewDef = oldView; +} diff --git a/renderer/tr_orderIndexes.cpp b/renderer/tr_orderIndexes.cpp new file mode 100644 index 000000000..658a75fc1 --- /dev/null +++ b/renderer/tr_orderIndexes.cpp @@ -0,0 +1,203 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +/* +=============== +R_MeshCost +=============== +*/ +#define CACHE_SIZE 24 +#define STALL_SIZE 8 +int R_MeshCost( int numIndexes, glIndex_t *indexes ) { + int inCache[CACHE_SIZE]; + int i, j, v; + int c_stalls; + int c_loads; + int fifo; + + for ( i = 0 ; i < CACHE_SIZE ; i++ ) { + inCache[i] = -1; + } + + c_loads = 0; + c_stalls = 0; + fifo = 0; + + for ( i = 0 ; i < numIndexes ; i++ ) { + v = indexes[i]; + for ( j = 0 ; j < CACHE_SIZE ; j++ ) { + if ( inCache[ ( fifo + j ) % CACHE_SIZE ] == v ) { + break; + } + } + if ( j == CACHE_SIZE ) { + c_loads++; + inCache[ fifo % CACHE_SIZE ] = v; + fifo++; + } else if ( j < STALL_SIZE ) { + c_stalls++; + } + } + + return c_loads; +} + + +typedef struct vertRef_s { + struct vertRef_s *next; + int tri; +} vertRef_t; + +/* +==================== +R_OrderIndexes + +Reorganizes the indexes so they will take best advantage +of the internal GPU vertex caches +==================== +*/ +void R_OrderIndexes( int numIndexes, glIndex_t *indexes ) { + bool *triangleUsed; + int numTris; + glIndex_t *oldIndexes; + glIndex_t *base; + int numOldIndexes; + int tri; + int i; + vertRef_t *vref, **vrefs, *vrefTable; + int numVerts; + int v1, v2; + int c_starts; + int c_cost; + + if ( !r_orderIndexes.GetBool() ) { + return; + } + + // save off the original indexes + oldIndexes = (glIndex_t *)_alloca( numIndexes * sizeof( *oldIndexes ) ); + memcpy( oldIndexes, indexes, numIndexes * sizeof( *oldIndexes ) ); + numOldIndexes = numIndexes; + + // make a table to mark the triangles when they are emited + numTris = numIndexes / 3; + triangleUsed = (bool *)_alloca( numTris * sizeof( *triangleUsed ) ); + memset( triangleUsed, 0, numTris * sizeof( *triangleUsed ) ); + + // find the highest vertex number + numVerts = 0; + for ( i = 0 ; i < numIndexes ; i++ ) { + if ( indexes[i] > numVerts ) { + numVerts = indexes[i]; + } + } + numVerts++; + + // create a table of triangles used by each vertex + vrefs = (vertRef_t **)_alloca( numVerts * sizeof( *vrefs ) ); + memset( vrefs, 0, numVerts * sizeof( *vrefs ) ); + + vrefTable = (vertRef_t *)_alloca( numIndexes * sizeof( *vrefTable ) ); + for ( i = 0 ; i < numIndexes ; i++ ) { + tri = i / 3; + + vrefTable[i].tri = tri; + vrefTable[i].next = vrefs[oldIndexes[i]]; + vrefs[oldIndexes[i]] = &vrefTable[i]; + } + + // generate new indexes + numIndexes = 0; + c_starts = 0; + while ( numIndexes != numOldIndexes ) { + // find a triangle that hasn't been used + for ( tri = 0 ; tri < numTris ; tri++ ) { + if ( !triangleUsed[tri] ) { + break; + } + } + if ( tri == numTris ) { + common->Error( "R_OrderIndexes: ran out of unused tris" ); + } + + c_starts++; + + do { + // emit this tri + base = oldIndexes + tri * 3; + indexes[numIndexes+0] = base[0]; + indexes[numIndexes+1] = base[1]; + indexes[numIndexes+2] = base[2]; + numIndexes += 3; + + triangleUsed[tri] = true; + + // try to find a shared edge to another unused tri + for ( i = 0 ; i < 3 ; i++ ) { + v1 = base[i]; + v2 = base[(i+1)%3]; + + for ( vref = vrefs[v1] ; vref ; vref = vref->next ) { + tri = vref->tri; + if ( triangleUsed[tri] ) { + continue; + } + + // if this triangle also uses v2, grab it + if ( oldIndexes[tri*3+0] == v2 + || oldIndexes[tri*3+1] == v2 + || oldIndexes[tri*3+2] == v2 ) { + break; + } + } + if ( vref ) { + break; + } + } + + // if we couldn't chain off of any verts, we need to find a new one + if ( i == 3 ) { + break; + } + } while ( 1 ); + } + + c_cost = R_MeshCost( numIndexes, indexes ); + +} + + +/* + + add all triangles that can be specified by the vertexes in the last 14 cache positions + + pick a new vert to add to the cache + don't pick one in the 24 previous cache positions + try to pick one that will enable the creation of as many triangles as possible + + look for a vert that shares an edge with the vert about to be evicted + + +*/ + diff --git a/renderer/tr_polytope.cpp b/renderer/tr_polytope.cpp new file mode 100644 index 000000000..3b4e98f86 --- /dev/null +++ b/renderer/tr_polytope.cpp @@ -0,0 +1,102 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +#define MAX_POLYTOPE_PLANES 6 + +/* +===================== +R_PolytopeSurface + +Generate vertexes and indexes for a polytope, and optionally returns the polygon windings. +The positive sides of the planes will be visible. +===================== +*/ +srfTriangles_t *R_PolytopeSurface( int numPlanes, const idPlane *planes, idWinding **windings ) { + int i, j; + srfTriangles_t *tri; + idFixedWinding planeWindings[MAX_POLYTOPE_PLANES]; + int numVerts, numIndexes; + + if ( numPlanes > MAX_POLYTOPE_PLANES ) { + common->Error( "R_PolytopeSurface: more than %d planes", MAX_POLYTOPE_PLANES ); + } + + numVerts = 0; + numIndexes = 0; + for ( i = 0; i < numPlanes; i++ ) { + const idPlane &plane = planes[i]; + idFixedWinding &w = planeWindings[i]; + + w.BaseForPlane( plane ); + for ( j = 0; j < numPlanes; j++ ) { + const idPlane &plane2 = planes[j]; + if ( j == i ) { + continue; + } + if ( !w.ClipInPlace( -plane2, ON_EPSILON ) ) { + break; + } + } + if ( w.GetNumPoints() <= 2 ) { + continue; + } + numVerts += w.GetNumPoints(); + numIndexes += ( w.GetNumPoints() - 2 ) * 3; + } + + // allocate the surface + tri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( tri, numVerts ); + R_AllocStaticTriSurfIndexes( tri, numIndexes ); + + // copy the data from the windings + for ( i = 0; i < numPlanes; i++ ) { + idFixedWinding &w = planeWindings[i]; + if ( !w.GetNumPoints() ) { + continue; + } + for ( j = 0 ; j < w.GetNumPoints() ; j++ ) { + tri->verts[tri->numVerts + j ].Clear(); + tri->verts[tri->numVerts + j ].xyz = w[j].ToVec3(); + } + + for ( j = 1 ; j < w.GetNumPoints() - 1 ; j++ ) { + tri->indexes[ tri->numIndexes + 0 ] = tri->numVerts; + tri->indexes[ tri->numIndexes + 1 ] = tri->numVerts + j; + tri->indexes[ tri->numIndexes + 2 ] = tri->numVerts + j + 1; + tri->numIndexes += 3; + } + tri->numVerts += w.GetNumPoints(); + + // optionally save the winding + if ( windings ) { + windings[i] = new idWinding( w.GetNumPoints() ); + *windings[i] = w; + } + } + + R_BoundTriSurf( tri ); + + return tri; +} diff --git a/renderer/tr_render.cpp b/renderer/tr_render.cpp new file mode 100644 index 000000000..0adc03da4 --- /dev/null +++ b/renderer/tr_render.cpp @@ -0,0 +1,881 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* + + back end scene + lights rendering functions + +*/ + + +/* +================= +RB_DrawElementsImmediate + +Draws with immediate mode commands, which is going to be very slow. +This should never happen if the vertex cache is operating properly. +================= +*/ +void RB_DrawElementsImmediate( const srfTriangles_t *tri ) { + + backEnd.pc.c_drawElements++; + backEnd.pc.c_drawIndexes += tri->numIndexes; + backEnd.pc.c_drawVertexes += tri->numVerts; + + if ( tri->ambientSurface != NULL ) { + if ( tri->indexes == tri->ambientSurface->indexes ) { + backEnd.pc.c_drawRefIndexes += tri->numIndexes; + } + if ( tri->verts == tri->ambientSurface->verts ) { + backEnd.pc.c_drawRefVertexes += tri->numVerts; + } + } + + qglBegin( GL_TRIANGLES ); + for ( int i = 0 ; i < tri->numIndexes ; i++ ) { + qglTexCoord2fv( tri->verts[ tri->indexes[i] ].st.ToFloatPtr() ); + qglVertex3fv( tri->verts[ tri->indexes[i] ].xyz.ToFloatPtr() ); + } + qglEnd(); +} + + +/* +================ +RB_DrawElementsWithCounters +================ +*/ +void RB_DrawElementsWithCounters( const srfTriangles_t *tri ) { + + backEnd.pc.c_drawElements++; + backEnd.pc.c_drawIndexes += tri->numIndexes; + backEnd.pc.c_drawVertexes += tri->numVerts; + + if ( tri->ambientSurface != NULL ) { + if ( tri->indexes == tri->ambientSurface->indexes ) { + backEnd.pc.c_drawRefIndexes += tri->numIndexes; + } + if ( tri->verts == tri->ambientSurface->verts ) { + backEnd.pc.c_drawRefVertexes += tri->numVerts; + } + } + + if ( tri->indexCache && r_useIndexBuffers.GetBool() ) { + qglDrawElements( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : tri->numIndexes, + GL_INDEX_TYPE, + (int *)vertexCache.Position( tri->indexCache ) ); + backEnd.pc.c_vboIndexes += tri->numIndexes; + } else { + if ( r_useIndexBuffers.GetBool() ) { + vertexCache.UnbindIndex(); + } + qglDrawElements( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : tri->numIndexes, + GL_INDEX_TYPE, + tri->indexes ); + } +} + +/* +================ +RB_DrawShadowElementsWithCounters + +May not use all the indexes in the surface if caps are skipped +================ +*/ +void RB_DrawShadowElementsWithCounters( const srfTriangles_t *tri, int numIndexes ) { + backEnd.pc.c_shadowElements++; + backEnd.pc.c_shadowIndexes += numIndexes; + backEnd.pc.c_shadowVertexes += tri->numVerts; + + if ( tri->indexCache && r_useIndexBuffers.GetBool() ) { + qglDrawElements( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : numIndexes, + GL_INDEX_TYPE, + (int *)vertexCache.Position( tri->indexCache ) ); + backEnd.pc.c_vboIndexes += numIndexes; + } else { + if ( r_useIndexBuffers.GetBool() ) { + vertexCache.UnbindIndex(); + } + qglDrawElements( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : numIndexes, + GL_INDEX_TYPE, + tri->indexes ); + } +} + + +/* +=============== +RB_RenderTriangleSurface + +Sets texcoord and vertex pointers +=============== +*/ +void RB_RenderTriangleSurface( const srfTriangles_t *tri ) { + if ( !tri->ambientCache ) { + RB_DrawElementsImmediate( tri ); + return; + } + + + idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() ); + + RB_DrawElementsWithCounters( tri ); +} + +/* +=============== +RB_T_RenderTriangleSurface + +=============== +*/ +void RB_T_RenderTriangleSurface( const drawSurf_t *surf ) { + RB_RenderTriangleSurface( surf->geo ); +} + +/* +=============== +RB_EnterWeaponDepthHack +=============== +*/ +void RB_EnterWeaponDepthHack() { + qglDepthRange( 0, 0.5 ); + + float matrix[16]; + + memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) ); + + matrix[14] *= 0.25; + + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf( matrix ); + qglMatrixMode(GL_MODELVIEW); +} + +/* +=============== +RB_EnterModelDepthHack +=============== +*/ +void RB_EnterModelDepthHack( float depth ) { + qglDepthRange( 0.0f, 1.0f ); + + float matrix[16]; + + memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) ); + + matrix[14] -= depth; + + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf( matrix ); + qglMatrixMode(GL_MODELVIEW); +} + +/* +=============== +RB_LeaveDepthHack +=============== +*/ +void RB_LeaveDepthHack() { + qglDepthRange( 0, 1 ); + + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf( backEnd.viewDef->projectionMatrix ); + qglMatrixMode(GL_MODELVIEW); +} + +/* +==================== +RB_RenderDrawSurfListWithFunction + +The triangle functions can check backEnd.currentSpace != surf->space +to see if they need to perform any new matrix setup. The modelview +matrix will already have been loaded, and backEnd.currentSpace will +be updated after the triangle function completes. +==================== +*/ +void RB_RenderDrawSurfListWithFunction( drawSurf_t **drawSurfs, int numDrawSurfs, + void (*triFunc_)( const drawSurf_t *) ) { + int i; + const drawSurf_t *drawSurf; + + backEnd.currentSpace = NULL; + + for (i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + // change the matrix if needed + if ( drawSurf->space != backEnd.currentSpace ) { + qglLoadMatrixf( drawSurf->space->modelViewMatrix ); + } + + if ( drawSurf->space->weaponDepthHack ) { + RB_EnterWeaponDepthHack(); + } + + if ( drawSurf->space->modelDepthHack != 0.0f ) { + RB_EnterModelDepthHack( drawSurf->space->modelDepthHack ); + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) { + backEnd.currentScissor = drawSurf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + + // render it + triFunc_( drawSurf ); + + if ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) { + RB_LeaveDepthHack(); + } + + backEnd.currentSpace = drawSurf->space; + } +} + +/* +====================== +RB_RenderDrawSurfChainWithFunction +====================== +*/ +void RB_RenderDrawSurfChainWithFunction( const drawSurf_t *drawSurfs, + void (*triFunc_)( const drawSurf_t *) ) { + const drawSurf_t *drawSurf; + + backEnd.currentSpace = NULL; + + for ( drawSurf = drawSurfs ; drawSurf ; drawSurf = drawSurf->nextOnLight ) { + // change the matrix if needed + if ( drawSurf->space != backEnd.currentSpace ) { + qglLoadMatrixf( drawSurf->space->modelViewMatrix ); + } + + if ( drawSurf->space->weaponDepthHack ) { + RB_EnterWeaponDepthHack(); + } + + if ( drawSurf->space->modelDepthHack ) { + RB_EnterModelDepthHack( drawSurf->space->modelDepthHack ); + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) { + backEnd.currentScissor = drawSurf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + + // render it + triFunc_( drawSurf ); + + if ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) { + RB_LeaveDepthHack(); + } + + backEnd.currentSpace = drawSurf->space; + } +} + +/* +====================== +RB_GetShaderTextureMatrix +====================== +*/ +void RB_GetShaderTextureMatrix( const float *shaderRegisters, + const textureStage_t *texture, float matrix[16] ) { + matrix[0] = shaderRegisters[ texture->matrix[0][0] ]; + matrix[4] = shaderRegisters[ texture->matrix[0][1] ]; + matrix[8] = 0; + matrix[12] = shaderRegisters[ texture->matrix[0][2] ]; + + // we attempt to keep scrolls from generating incredibly large texture values, but + // center rotations and center scales can still generate offsets that need to be > 1 + if ( matrix[12] < -40 || matrix[12] > 40 ) { + matrix[12] -= (int)matrix[12]; + } + + matrix[1] = shaderRegisters[ texture->matrix[1][0] ]; + matrix[5] = shaderRegisters[ texture->matrix[1][1] ]; + matrix[9] = 0; + matrix[13] = shaderRegisters[ texture->matrix[1][2] ]; + if ( matrix[13] < -40 || matrix[13] > 40 ) { + matrix[13] -= (int)matrix[13]; + } + + matrix[2] = 0; + matrix[6] = 0; + matrix[10] = 1; + matrix[14] = 0; + + matrix[3] = 0; + matrix[7] = 0; + matrix[11] = 0; + matrix[15] = 1; +} + +/* +====================== +RB_LoadShaderTextureMatrix +====================== +*/ +void RB_LoadShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture ) { + float matrix[16]; + + RB_GetShaderTextureMatrix( shaderRegisters, texture, matrix ); + qglMatrixMode( GL_TEXTURE ); + qglLoadMatrixf( matrix ); + qglMatrixMode( GL_MODELVIEW ); +} + +/* +====================== +RB_BindVariableStageImage + +Handles generating a cinematic frame if needed +====================== +*/ +void RB_BindVariableStageImage( const textureStage_t *texture, const float *shaderRegisters ) { + if ( texture->cinematic ) { + cinData_t cin; + + if ( r_skipDynamicTextures.GetBool() ) { + globalImages->defaultImage->Bind(); + return; + } + + // offset time by shaderParm[7] (FIXME: make the time offset a parameter of the shader?) + // We make no attempt to optimize for multiple identical cinematics being in view, or + // for cinematics going at a lower framerate than the renderer. + cin = texture->cinematic->ImageForTime( (int)(1000 * ( backEnd.viewDef->floatTime + backEnd.viewDef->renderView.shaderParms[11] ) ) ); + + if ( cin.image ) { + globalImages->cinematicImage->UploadScratch( cin.image, cin.imageWidth, cin.imageHeight ); + } else { + globalImages->blackImage->Bind(); + } + } else { + //FIXME: see why image is invalid + if (texture->image) { + texture->image->Bind(); + } + } +} + +/* +====================== +RB_BindStageTexture +====================== +*/ +void RB_BindStageTexture( const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf ) { + // image + RB_BindVariableStageImage( texture, shaderRegisters ); + + // texgens + if ( texture->texgen == TG_DIFFUSE_CUBE ) { + qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() ); + } + if ( texture->texgen == TG_SKYBOX_CUBE || texture->texgen == TG_WOBBLESKY_CUBE ) { + qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) ); + } + if ( texture->texgen == TG_REFLECT_CUBE ) { + qglEnable( GL_TEXTURE_GEN_S ); + qglEnable( GL_TEXTURE_GEN_T ); + qglEnable( GL_TEXTURE_GEN_R ); + qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); + qglEnableClientState( GL_NORMAL_ARRAY ); + qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() ); + + qglMatrixMode( GL_TEXTURE ); + float mat[16]; + + R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat ); + + qglLoadMatrixf( mat ); + qglMatrixMode( GL_MODELVIEW ); + } + + // matrix + if ( texture->hasMatrix ) { + RB_LoadShaderTextureMatrix( shaderRegisters, texture ); + } +} + +/* +====================== +RB_FinishStageTexture +====================== +*/ +void RB_FinishStageTexture( const textureStage_t *texture, const drawSurf_t *surf ) { + if ( texture->texgen == TG_DIFFUSE_CUBE || texture->texgen == TG_SKYBOX_CUBE + || texture->texgen == TG_WOBBLESKY_CUBE ) { + qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), + (void *)&(((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->st) ); + } + + if ( texture->texgen == TG_REFLECT_CUBE ) { + qglDisable( GL_TEXTURE_GEN_S ); + qglDisable( GL_TEXTURE_GEN_T ); + qglDisable( GL_TEXTURE_GEN_R ); + qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + qglDisableClientState( GL_NORMAL_ARRAY ); + + qglMatrixMode( GL_TEXTURE ); + qglLoadIdentity(); + qglMatrixMode( GL_MODELVIEW ); + } + + if ( texture->hasMatrix ) { + qglMatrixMode( GL_TEXTURE ); + qglLoadIdentity(); + qglMatrixMode( GL_MODELVIEW ); + } +} + + + +//============================================================================================= + + +/* +================= +RB_DetermineLightScale + +Sets: +backEnd.lightScale +backEnd.overBright + +Find out how much we are going to need to overscale the lighting, so we +can down modulate the pre-lighting passes. + +We only look at light calculations, but an argument could be made that +we should also look at surface evaluations, which would let surfaces +overbright past 1.0 +================= +*/ +void RB_DetermineLightScale( void ) { + viewLight_t *vLight; + const idMaterial *shader; + float max; + int i, j, numStages; + const shaderStage_t *stage; + + // the light scale will be based on the largest color component of any surface + // that will be drawn. + // should we consider separating rgb scales? + + // if there are no lights, this will remain at 1.0, so GUI-only + // rendering will not lose any bits of precision + max = 1.0; + + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + // lights with no surfaces or shaderparms may still be present + // for debug display + if ( !vLight->localInteractions && !vLight->globalInteractions + && !vLight->translucentInteractions ) { + continue; + } + + shader = vLight->lightShader; + numStages = shader->GetNumStages(); + for ( i = 0 ; i < numStages ; i++ ) { + stage = shader->GetStage( i ); + for ( j = 0 ; j < 3 ; j++ ) { + float v = r_lightScale.GetFloat() * vLight->shaderRegisters[ stage->color.registers[j] ]; + if ( v > max ) { + max = v; + } + } + } + } + + backEnd.pc.maxLightValue = max; + if ( max <= tr.backEndRendererMaxLight ) { + backEnd.lightScale = r_lightScale.GetFloat(); + backEnd.overBright = 1.0; + } else { + backEnd.lightScale = r_lightScale.GetFloat() * tr.backEndRendererMaxLight / max; + backEnd.overBright = max / tr.backEndRendererMaxLight; + } +} + + +/* +================= +RB_BeginDrawingView + +Any mirrored or portaled views have already been drawn, so prepare +to actually render the visible surfaces for this view +================= +*/ +void RB_BeginDrawingView (void) { + // set the modelview matrix for the viewer + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf( backEnd.viewDef->projectionMatrix ); + qglMatrixMode(GL_MODELVIEW); + + // set the window clipping + qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, + backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, + backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + + // the scissor may be smaller than the viewport for subviews + qglScissor( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, + tr.viewportOffset[1] + backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, + backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1, + backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 ); + backEnd.currentScissor = backEnd.viewDef->scissor; + + // ensures that depth writes are enabled for the depth clear + GL_State( GLS_DEFAULT ); + + // we don't have to clear the depth / stencil buffer for 2D rendering + if ( backEnd.viewDef->viewEntitys ) { + qglStencilMask( 0xff ); + // some cards may have 7 bit stencil buffers, so don't assume this + // should be 128 + qglClearStencil( 1<<(glConfig.stencilBits-1) ); + qglClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + qglEnable( GL_DEPTH_TEST ); + } else { + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_STENCIL_TEST ); + } + + backEnd.glState.faceCulling = -1; // force face culling to set next time + GL_Cull( CT_FRONT_SIDED ); + +} + +/* +================== +R_SetDrawInteractions +================== +*/ +void R_SetDrawInteraction( const shaderStage_t *surfaceStage, const float *surfaceRegs, + idImage **image, idVec4 matrix[2], float color[4] ) { + *image = surfaceStage->texture.image; + if ( surfaceStage->texture.hasMatrix ) { + matrix[0][0] = surfaceRegs[surfaceStage->texture.matrix[0][0]]; + matrix[0][1] = surfaceRegs[surfaceStage->texture.matrix[0][1]]; + matrix[0][2] = 0; + matrix[0][3] = surfaceRegs[surfaceStage->texture.matrix[0][2]]; + + matrix[1][0] = surfaceRegs[surfaceStage->texture.matrix[1][0]]; + matrix[1][1] = surfaceRegs[surfaceStage->texture.matrix[1][1]]; + matrix[1][2] = 0; + matrix[1][3] = surfaceRegs[surfaceStage->texture.matrix[1][2]]; + + // we attempt to keep scrolls from generating incredibly large texture values, but + // center rotations and center scales can still generate offsets that need to be > 1 + if ( matrix[0][3] < -40 || matrix[0][3] > 40 ) { + matrix[0][3] -= (int)matrix[0][3]; + } + if ( matrix[1][3] < -40 || matrix[1][3] > 40 ) { + matrix[1][3] -= (int)matrix[1][3]; + } + } else { + matrix[0][0] = 1; + matrix[0][1] = 0; + matrix[0][2] = 0; + matrix[0][3] = 0; + + matrix[1][0] = 0; + matrix[1][1] = 1; + matrix[1][2] = 0; + matrix[1][3] = 0; + } + + if ( color ) { + for ( int i = 0 ; i < 4 ; i++ ) { + color[i] = surfaceRegs[surfaceStage->color.registers[i]]; + // clamp here, so card with greater range don't look different. + // we could perform overbrighting like we do for lights, but + // it doesn't currently look worth it. + if ( color[i] < 0 ) { + color[i] = 0; + } else if ( color[i] > 1.0 ) { + color[i] = 1.0; + } + } + } +} + +/* +================= +RB_SubmittInteraction +================= +*/ +static void RB_SubmittInteraction( drawInteraction_t *din, void (*DrawInteraction)(const drawInteraction_t *) ) { + if ( !din->bumpImage ) { + return; + } + + if ( !din->diffuseImage || r_skipDiffuse.GetBool() ) { + din->diffuseImage = globalImages->blackImage; + } + if ( !din->specularImage || r_skipSpecular.GetBool() || din->ambientLight ) { + din->specularImage = globalImages->blackImage; + } + if ( !din->bumpImage || r_skipBump.GetBool() ) { + din->bumpImage = globalImages->flatNormalMap; + } + + // if we wouldn't draw anything, don't call the Draw function + if ( + ( ( din->diffuseColor[0] > 0 || + din->diffuseColor[1] > 0 || + din->diffuseColor[2] > 0 ) && din->diffuseImage != globalImages->blackImage ) + || ( ( din->specularColor[0] > 0 || + din->specularColor[1] > 0 || + din->specularColor[2] > 0 ) && din->specularImage != globalImages->blackImage ) ) { + DrawInteraction( din ); + } +} + +/* +============= +RB_CreateSingleDrawInteractions + +This can be used by different draw_* backends to decompose a complex light / surface +interaction into primitive interactions +============= +*/ +void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInteraction)(const drawInteraction_t *) ) { + const idMaterial *surfaceShader = surf->material; + const float *surfaceRegs = surf->shaderRegisters; + const viewLight_t *vLight = backEnd.vLight; + const idMaterial *lightShader = vLight->lightShader; + const float *lightRegs = vLight->shaderRegisters; + drawInteraction_t inter; + + if ( r_skipInteractions.GetBool() || !surf->geo || !surf->geo->ambientCache ) { + return; + } + + if ( tr.logFile ) { + RB_LogComment( "---------- RB_CreateSingleDrawInteractions %s on %s ----------\n", lightShader->GetName(), surfaceShader->GetName() ); + } + + // change the matrix and light projection vectors if needed + if ( surf->space != backEnd.currentSpace ) { + backEnd.currentSpace = surf->space; + qglLoadMatrixf( surf->space->modelViewMatrix ); + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) { + backEnd.currentScissor = surf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } + + // hack depth range if needed + if ( surf->space->weaponDepthHack ) { + RB_EnterWeaponDepthHack(); + } + + if ( surf->space->modelDepthHack ) { + RB_EnterModelDepthHack( surf->space->modelDepthHack ); + } + + inter.surf = surf; + inter.lightFalloffImage = vLight->falloffImage; + + R_GlobalPointToLocal( surf->space->modelMatrix, vLight->globalLightOrigin, inter.localLightOrigin.ToVec3() ); + R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, inter.localViewOrigin.ToVec3() ); + inter.localLightOrigin[3] = 0; + inter.localViewOrigin[3] = 1; + inter.ambientLight = lightShader->IsAmbientLight(); + + // the base projections may be modified by texture matrix on light stages + idPlane lightProject[4]; + for ( int i = 0 ; i < 4 ; i++ ) { + R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] ); + } + + for ( int lightStageNum = 0 ; lightStageNum < lightShader->GetNumStages() ; lightStageNum++ ) { + const shaderStage_t *lightStage = lightShader->GetStage( lightStageNum ); + + // ignore stages that fail the condition + if ( !lightRegs[ lightStage->conditionRegister ] ) { + continue; + } + + inter.lightImage = lightStage->texture.image; + + memcpy( inter.lightProjection, lightProject, sizeof( inter.lightProjection ) ); + // now multiply the texgen by the light texture matrix + if ( lightStage->texture.hasMatrix ) { + RB_GetShaderTextureMatrix( lightRegs, &lightStage->texture, backEnd.lightTextureMatrix ); + RB_BakeTextureMatrixIntoTexgen( reinterpret_cast(inter.lightProjection), backEnd.lightTextureMatrix ); + } + + inter.bumpImage = NULL; + inter.specularImage = NULL; + inter.diffuseImage = NULL; + inter.diffuseColor[0] = inter.diffuseColor[1] = inter.diffuseColor[2] = inter.diffuseColor[3] = 0; + inter.specularColor[0] = inter.specularColor[1] = inter.specularColor[2] = inter.specularColor[3] = 0; + + float lightColor[4]; + + // backEnd.lightScale is calculated so that lightColor[] will never exceed + // tr.backEndRendererMaxLight + lightColor[0] = backEnd.lightScale * lightRegs[ lightStage->color.registers[0] ]; + lightColor[1] = backEnd.lightScale * lightRegs[ lightStage->color.registers[1] ]; + lightColor[2] = backEnd.lightScale * lightRegs[ lightStage->color.registers[2] ]; + lightColor[3] = lightRegs[ lightStage->color.registers[3] ]; + + // go through the individual stages + for ( int surfaceStageNum = 0 ; surfaceStageNum < surfaceShader->GetNumStages() ; surfaceStageNum++ ) { + const shaderStage_t *surfaceStage = surfaceShader->GetStage( surfaceStageNum ); + + switch( surfaceStage->lighting ) { + case SL_AMBIENT: { + // ignore ambient stages while drawing interactions + break; + } + case SL_BUMP: { + // ignore stage that fails the condition + if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) { + break; + } + // draw any previous interaction + RB_SubmittInteraction( &inter, DrawInteraction ); + inter.diffuseImage = NULL; + inter.specularImage = NULL; + R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.bumpImage, inter.bumpMatrix, NULL ); + break; + } + case SL_DIFFUSE: { + // ignore stage that fails the condition + if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) { + break; + } + if ( inter.diffuseImage ) { + RB_SubmittInteraction( &inter, DrawInteraction ); + } + R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.diffuseImage, + inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() ); + inter.diffuseColor[0] *= lightColor[0]; + inter.diffuseColor[1] *= lightColor[1]; + inter.diffuseColor[2] *= lightColor[2]; + inter.diffuseColor[3] *= lightColor[3]; + inter.vertexColor = surfaceStage->vertexColor; + break; + } + case SL_SPECULAR: { + // ignore stage that fails the condition + if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) { + break; + } + if ( inter.specularImage ) { + RB_SubmittInteraction( &inter, DrawInteraction ); + } + R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.specularImage, + inter.specularMatrix, inter.specularColor.ToFloatPtr() ); + inter.specularColor[0] *= lightColor[0]; + inter.specularColor[1] *= lightColor[1]; + inter.specularColor[2] *= lightColor[2]; + inter.specularColor[3] *= lightColor[3]; + inter.vertexColor = surfaceStage->vertexColor; + break; + } + } + } + + // draw the final interaction + RB_SubmittInteraction( &inter, DrawInteraction ); + } + + // unhack depth range if needed + if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) { + RB_LeaveDepthHack(); + } +} + +/* +============= +RB_DrawView +============= +*/ +void RB_DrawView( const void *data ) { + const drawSurfsCommand_t *cmd; + + cmd = (const drawSurfsCommand_t *)data; + + backEnd.viewDef = cmd->viewDef; + + // we will need to do a new copyTexSubImage of the screen + // when a SS_POST_PROCESS material is used + backEnd.currentRenderCopied = false; + + // if there aren't any drawsurfs, do nothing + if ( !backEnd.viewDef->numDrawSurfs ) { + return; + } + + // skip render bypasses everything that has models, assuming + // them to be 3D views, but leaves 2D rendering visible + if ( r_skipRender.GetBool() && backEnd.viewDef->viewEntitys ) { + return; + } + + // skip render context sets the wgl context to NULL, + // which should factor out the API cost, under the assumption + // that all gl calls just return if the context isn't valid + if ( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys ) { + GLimp_DeactivateContext(); + } + + backEnd.pc.c_surfaces += backEnd.viewDef->numDrawSurfs; + + RB_ShowOverdraw(); + + // render the scene, jumping to the hardware specific interaction renderers + RB_STD_DrawView(); + + // restore the context for 2D drawing if we were stubbing it out + if ( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys ) { + GLimp_ActivateContext(); + RB_SetDefaultGLState(); + } +} diff --git a/renderer/tr_rendertools.cpp b/renderer/tr_rendertools.cpp new file mode 100644 index 000000000..4da99c236 --- /dev/null +++ b/renderer/tr_rendertools.cpp @@ -0,0 +1,2376 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" +#include "simplex.h" // line font definition + +#define MAX_DEBUG_LINES 16384 + +typedef struct debugLine_s { + idVec4 rgb; + idVec3 start; + idVec3 end; + bool depthTest; + int lifeTime; +} debugLine_t; + +debugLine_t rb_debugLines[ MAX_DEBUG_LINES ]; +int rb_numDebugLines = 0; +int rb_debugLineTime = 0; + +#define MAX_DEBUG_TEXT 512 + +typedef struct debugText_s { + idStr text; + idVec3 origin; + float scale; + idVec4 color; + idMat3 viewAxis; + int align; + int lifeTime; + bool depthTest; +} debugText_t; + +debugText_t rb_debugText[ MAX_DEBUG_TEXT ]; +int rb_numDebugText = 0; +int rb_debugTextTime = 0; + +#define MAX_DEBUG_POLYGONS 8192 + +typedef struct debugPolygon_s { + idVec4 rgb; + idWinding winding; + bool depthTest; + int lifeTime; +} debugPolygon_t; + +debugPolygon_t rb_debugPolygons[ MAX_DEBUG_POLYGONS ]; +int rb_numDebugPolygons = 0; +int rb_debugPolygonTime = 0; + +static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align ); + +/* +================ +RB_DrawBounds +================ +*/ +void RB_DrawBounds( const idBounds &bounds ) { + if ( bounds.IsCleared() ) { + return; + } + + qglBegin( GL_LINE_LOOP ); + qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); + qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); + qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); + qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); + qglEnd(); + qglBegin( GL_LINE_LOOP ); + qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); + qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); + qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); + qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); + qglEnd(); + + qglBegin( GL_LINES ); + qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); + qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); + + qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); + qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); + + qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); + qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); + + qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); + qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); + qglEnd(); +} + + +/* +================ +RB_SimpleSurfaceSetup +================ +*/ +void RB_SimpleSurfaceSetup( const drawSurf_t *drawSurf ) { + // change the matrix if needed + if ( drawSurf->space != backEnd.currentSpace ) { + qglLoadMatrixf( drawSurf->space->modelViewMatrix ); + backEnd.currentSpace = drawSurf->space; + } + + // change the scissor if needed + if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) { + backEnd.currentScissor = drawSurf->scissorRect; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + } +} + +/* +================ +RB_SimpleWorldSetup +================ +*/ +void RB_SimpleWorldSetup( void ) { + backEnd.currentSpace = &backEnd.viewDef->worldSpace; + qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix ); + + backEnd.currentScissor = backEnd.viewDef->scissor; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); +} + +/* +================= +RB_PolygonClear + +This will cover the entire screen with normal rasterization. +Texturing is disabled, but the existing glColor, glDepthMask, +glColorMask, and the enabled state of depth buffering and +stenciling will matter. +================= +*/ +void RB_PolygonClear( void ) { + qglPushMatrix(); + qglPushAttrib( GL_ALL_ATTRIB_BITS ); + qglLoadIdentity(); + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_CULL_FACE ); + qglDisable( GL_SCISSOR_TEST ); + qglBegin( GL_POLYGON ); + qglVertex3f( -20, -20, -10 ); + qglVertex3f( 20, -20, -10 ); + qglVertex3f( 20, 20, -10 ); + qglVertex3f( -20, 20, -10 ); + qglEnd(); + qglPopAttrib(); + qglPopMatrix(); +} + +/* +==================== +RB_ShowDestinationAlpha +==================== +*/ +void RB_ShowDestinationAlpha( void ) { + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); + qglColor3f( 1, 1, 1 ); + RB_PolygonClear(); +} + +/* +=================== +RB_ScanStencilBuffer + +Debugging tool to see what values are in the stencil buffer +=================== +*/ +void RB_ScanStencilBuffer( void ) { + int counts[256]; + int i; + byte *stencilReadback; + + memset( counts, 0, sizeof( counts ) ); + + stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight ); + qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); + + for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { + counts[ stencilReadback[i] ]++; + } + + R_StaticFree( stencilReadback ); + + // print some stats (not supposed to do from back end in SMP...) + common->Printf( "stencil values:\n" ); + for ( i = 0 ; i < 255 ; i++ ) { + if ( counts[i] ) { + common->Printf( "%i: %i\n", i, counts[i] ); + } + } +} + + +/* +=================== +RB_CountStencilBuffer + +Print an overdraw count based on stencil index values +=================== +*/ +void RB_CountStencilBuffer( void ) { + int count; + int i; + byte *stencilReadback; + + + stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight ); + qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); + + count = 0; + for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { + count += stencilReadback[i]; + } + + R_StaticFree( stencilReadback ); + + // print some stats (not supposed to do from back end in SMP...) + common->Printf( "overdraw: %5.1f\n", (float)count/(glConfig.vidWidth * glConfig.vidHeight) ); +} + +/* +=================== +R_ColorByStencilBuffer + +Sets the screen colors based on the contents of the +stencil buffer. Stencil of 0 = black, 1 = red, 2 = green, +3 = blue, ..., 7+ = white +=================== +*/ +static void R_ColorByStencilBuffer( void ) { + int i; + static float colors[8][3] = { + {0,0,0}, + {1,0,0}, + {0,1,0}, + {0,0,1}, + {0,1,1}, + {1,0,1}, + {1,1,0}, + {1,1,1}, + }; + + // clear color buffer to white (>6 passes) + qglClearColor( 1, 1, 1, 1 ); + qglDisable( GL_SCISSOR_TEST ); + qglClear( GL_COLOR_BUFFER_BIT ); + + // now draw color for each stencil value + qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + for ( i = 0 ; i < 6 ; i++ ) { + qglColor3fv( colors[i] ); + qglStencilFunc( GL_EQUAL, i, 255 ); + RB_PolygonClear(); + } + + qglStencilFunc( GL_ALWAYS, 0, 255 ); +} + +//====================================================================== + +/* +================== +RB_ShowOverdraw +================== +*/ +void RB_ShowOverdraw( void ) { + const idMaterial * material; + int i; + drawSurf_t * * drawSurfs; + const drawSurf_t * surf; + int numDrawSurfs; + viewLight_t * vLight; + + if ( r_showOverDraw.GetInteger() == 0 ) { + return; + } + + material = declManager->FindMaterial( "textures/common/overdrawtest", false ); + if ( material == NULL ) { + return; + } + + drawSurfs = backEnd.viewDef->drawSurfs; + numDrawSurfs = backEnd.viewDef->numDrawSurfs; + + int interactions = 0; + for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) { + for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) { + interactions++; + } + for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) { + interactions++; + } + } + + drawSurf_t **newDrawSurfs = (drawSurf_t **)R_FrameAlloc( numDrawSurfs + interactions * sizeof( newDrawSurfs[0] ) ); + + for ( i = 0; i < numDrawSurfs; i++ ) { + surf = drawSurfs[i]; + if ( surf->material ) { + const_cast(surf)->material = material; + } + newDrawSurfs[i] = const_cast(surf); + } + + for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) { + for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) { + const_cast(surf)->material = material; + newDrawSurfs[i++] = const_cast(surf); + } + for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) { + const_cast(surf)->material = material; + newDrawSurfs[i++] = const_cast(surf); + } + vLight->localInteractions = NULL; + vLight->globalInteractions = NULL; + } + + switch( r_showOverDraw.GetInteger() ) { + case 1: // geometry overdraw + const_cast(backEnd.viewDef)->drawSurfs = newDrawSurfs; + const_cast(backEnd.viewDef)->numDrawSurfs = numDrawSurfs; + break; + case 2: // light interaction overdraw + const_cast(backEnd.viewDef)->drawSurfs = &newDrawSurfs[numDrawSurfs]; + const_cast(backEnd.viewDef)->numDrawSurfs = interactions; + break; + case 3: // geometry + light interaction overdraw + const_cast(backEnd.viewDef)->drawSurfs = newDrawSurfs; + const_cast(backEnd.viewDef)->numDrawSurfs += interactions; + break; + } +} + +/* +=================== +RB_ShowIntensity + +Debugging tool to see how much dynamic range a scene is using. +The greatest of the rgb values at each pixel will be used, with +the resulting color shading from red at 0 to green at 128 to blue at 255 +=================== +*/ +void RB_ShowIntensity( void ) { + byte *colorReadback; + int i, j, c; + + if ( !r_showIntensity.GetBool() ) { + return; + } + + colorReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight * 4 ); + qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorReadback ); + + c = glConfig.vidWidth * glConfig.vidHeight * 4; + for ( i = 0; i < c ; i+=4 ) { + j = colorReadback[i]; + if ( colorReadback[i+1] > j ) { + j = colorReadback[i+1]; + } + if ( colorReadback[i+2] > j ) { + j = colorReadback[i+2]; + } + if ( j < 128 ) { + colorReadback[i+0] = 2*(128-j); + colorReadback[i+1] = 2*j; + colorReadback[i+2] = 0; + } else { + colorReadback[i+0] = 0; + colorReadback[i+1] = 2*(255-j); + colorReadback[i+2] = 2*(j-128); + } + } + + // draw it back to the screen + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + qglPushMatrix(); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglRasterPos2f( 0, 0 ); + qglPopMatrix(); + qglColor3f( 1, 1, 1 ); + globalImages->BindNull(); + qglMatrixMode( GL_MODELVIEW ); + + qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, colorReadback ); + + R_StaticFree( colorReadback ); +} + + +/* +=================== +RB_ShowDepthBuffer + +Draw the depth buffer as colors +=================== +*/ +void RB_ShowDepthBuffer( void ) { + void *depthReadback; + + if ( !r_showDepth.GetBool() ) { + return; + } + + qglPushMatrix(); + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + qglPushMatrix(); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglRasterPos2f( 0, 0 ); + qglPopMatrix(); + qglMatrixMode( GL_MODELVIEW ); + qglPopMatrix(); + + GL_State( GLS_DEPTHFUNC_ALWAYS ); + qglColor3f( 1, 1, 1 ); + globalImages->BindNull(); + + depthReadback = R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight*4 ); + memset( depthReadback, 0, glConfig.vidWidth * glConfig.vidHeight*4 ); + + qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_DEPTH_COMPONENT , GL_FLOAT, depthReadback ); + +#if 0 + for ( i = 0 ; i < glConfig.vidWidth * glConfig.vidHeight ; i++ ) { + ((byte *)depthReadback)[i*4] = + ((byte *)depthReadback)[i*4+1] = + ((byte *)depthReadback)[i*4+2] = 255 * ((float *)depthReadback)[i]; + ((byte *)depthReadback)[i*4+3] = 1; + } +#endif + + qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, depthReadback ); + R_StaticFree( depthReadback ); +} + +/* +================= +RB_ShowLightCount + +This is a debugging tool that will draw each surface with a color +based on how many lights are effecting it +================= +*/ +void RB_ShowLightCount( void ) { + int i; + const drawSurf_t *surf; + const viewLight_t *vLight; + + if ( !r_showLightCount.GetBool() ) { + return; + } + + GL_State( GLS_DEPTHFUNC_EQUAL ); + + RB_SimpleWorldSetup(); + qglClearStencil( 0 ); + qglClear( GL_STENCIL_BUFFER_BIT ); + + qglEnable( GL_STENCIL_TEST ); + + // optionally count everything through walls + if ( r_showLightCount.GetInteger() >= 2 ) { + qglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); + } else { + qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR ); + } + + qglStencilFunc( GL_ALWAYS, 1, 255 ); + + globalImages->defaultImage->Bind(); + + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + for ( i = 0 ; i < 2 ; i++ ) { + for ( surf = i ? vLight->localInteractions: vLight->globalInteractions; surf; surf = (drawSurf_t *)surf->nextOnLight ) { + RB_SimpleSurfaceSetup( surf ); + if ( !surf->geo->ambientCache ) { + continue; + } + + const idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); + qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), &ac->xyz ); + RB_DrawElementsWithCounters( surf->geo ); + } + } + } + + // display the results + R_ColorByStencilBuffer(); + + if ( r_showLightCount.GetInteger() > 2 ) { + RB_CountStencilBuffer(); + } +} + + +/* +================= +RB_ShowSilhouette + +Blacks out all edges, then adds color for each edge that a shadow +plane extends from, allowing you to see doubled edges +================= +*/ +void RB_ShowSilhouette( void ) { + int i; + const drawSurf_t *surf; + const viewLight_t *vLight; + + if ( !r_showSilhouette.GetBool() ) { + return; + } + + // + // clear all triangle edges to black + // + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_STENCIL_TEST ); + + qglColor3f( 0, 0, 0 ); + + GL_State( GLS_POLYMODE_LINE ); + + GL_Cull( CT_TWO_SIDED ); + qglDisable( GL_DEPTH_TEST ); + + RB_RenderDrawSurfListWithFunction( backEnd.viewDef->drawSurfs, backEnd.viewDef->numDrawSurfs, + RB_T_RenderTriangleSurface ); + + + // + // now blend in edges that cast silhouettes + // + RB_SimpleWorldSetup(); + qglColor3f( 0.5, 0, 0 ); + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + for ( i = 0 ; i < 2 ; i++ ) { + for ( surf = i ? vLight->localShadows : vLight->globalShadows + ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) { + RB_SimpleSurfaceSetup( surf ); + + const srfTriangles_t *tri = surf->geo; + + qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position( tri->shadowCache ) ); + qglBegin( GL_LINES ); + + for ( int j = 0 ; j < tri->numIndexes ; j+=3 ) { + int i1 = tri->indexes[j+0]; + int i2 = tri->indexes[j+1]; + int i3 = tri->indexes[j+2]; + + if ( (i1 & 1) + (i2 & 1) + (i3 & 1) == 1 ) { + if ( (i1 & 1) + (i2 & 1) == 0 ) { + qglArrayElement( i1 ); + qglArrayElement( i2 ); + } else if ( (i1 & 1 ) + (i3 & 1) == 0 ) { + qglArrayElement( i1 ); + qglArrayElement( i3 ); + } + } + } + qglEnd(); + + } + } + } + + qglEnable( GL_DEPTH_TEST ); + + GL_State( GLS_DEFAULT ); + qglColor3f( 1,1,1 ); + GL_Cull( CT_FRONT_SIDED ); +} + + + +/* +================= +RB_ShowShadowCount + +This is a debugging tool that will draw only the shadow volumes +and count up the total fill usage +================= +*/ +static void RB_ShowShadowCount( void ) { + int i; + const drawSurf_t *surf; + const viewLight_t *vLight; + + if ( !r_showShadowCount.GetBool() ) { + return; + } + + GL_State( GLS_DEFAULT ); + + qglClearStencil( 0 ); + qglClear( GL_STENCIL_BUFFER_BIT ); + + qglEnable( GL_STENCIL_TEST ); + + qglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); + + qglStencilFunc( GL_ALWAYS, 1, 255 ); + + globalImages->defaultImage->Bind(); + + // draw both sides + GL_Cull( CT_TWO_SIDED ); + + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + for ( i = 0 ; i < 2 ; i++ ) { + for ( surf = i ? vLight->localShadows : vLight->globalShadows + ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) { + RB_SimpleSurfaceSetup( surf ); + const srfTriangles_t *tri = surf->geo; + if ( !tri->shadowCache ) { + continue; + } + + if ( r_showShadowCount.GetInteger() == 3 ) { + // only show turboshadows + if ( tri->numShadowIndexesNoCaps != tri->numIndexes ) { + continue; + } + } + if ( r_showShadowCount.GetInteger() == 4 ) { + // only show static shadows + if ( tri->numShadowIndexesNoCaps == tri->numIndexes ) { + continue; + } + } + + shadowCache_t *cache = (shadowCache_t *)vertexCache.Position( tri->shadowCache ); + qglVertexPointer( 4, GL_FLOAT, sizeof( *cache ), &cache->xyz ); + RB_DrawElementsWithCounters( tri ); + } + } + } + + // display the results + R_ColorByStencilBuffer(); + + if ( r_showShadowCount.GetInteger() == 2 ) { + common->Printf( "all shadows " ); + } else if ( r_showShadowCount.GetInteger() == 3 ) { + common->Printf( "turboShadows " ); + } else if ( r_showShadowCount.GetInteger() == 4 ) { + common->Printf( "static shadows " ); + } + + if ( r_showShadowCount.GetInteger() >= 2 ) { + RB_CountStencilBuffer(); + } + + GL_Cull( CT_FRONT_SIDED ); +} + + +/* +=============== +RB_T_RenderTriangleSurfaceAsLines + +=============== +*/ +void RB_T_RenderTriangleSurfaceAsLines( const drawSurf_t *surf ) { + const srfTriangles_t *tri = surf->geo; + + if ( !tri->verts ) { + return; + } + + qglBegin( GL_LINES ); + for ( int i = 0 ; i < tri->numIndexes ; i+= 3 ) { + for ( int j = 0 ; j < 3 ; j++ ) { + int k = ( j + 1 ) % 3; + qglVertex3fv( tri->verts[ tri->silIndexes[i+j] ].xyz.ToFloatPtr() ); + qglVertex3fv( tri->verts[ tri->silIndexes[i+k] ].xyz.ToFloatPtr() ); + } + } + qglEnd(); +} + + +/* +===================== +RB_ShowTris + +Debugging tool +===================== +*/ +static void RB_ShowTris( drawSurf_t **drawSurfs, int numDrawSurfs ) { + modelTrace_t mt; + idVec3 end; + + if ( !r_showTris.GetInteger() ) { + return; + } + + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_STENCIL_TEST ); + + qglColor3f( 1, 1, 1 ); + + + GL_State( GLS_POLYMODE_LINE ); + + switch ( r_showTris.GetInteger() ) { + case 1: // only draw visible ones + qglPolygonOffset( -1, -2 ); + qglEnable( GL_POLYGON_OFFSET_LINE ); + break; + default: + case 2: // draw all front facing + GL_Cull( CT_FRONT_SIDED ); + qglDisable( GL_DEPTH_TEST ); + break; + case 3: // draw all + GL_Cull( CT_TWO_SIDED ); + qglDisable( GL_DEPTH_TEST ); + break; + } + + RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_T_RenderTriangleSurface ); + + qglEnable( GL_DEPTH_TEST ); + qglDisable( GL_POLYGON_OFFSET_LINE ); + + qglDepthRange( 0, 1 ); + GL_State( GLS_DEFAULT ); + GL_Cull( CT_FRONT_SIDED ); +} + + +/* +===================== +RB_ShowSurfaceInfo + +Debugging tool +===================== +*/ +static void RB_ShowSurfaceInfo( drawSurf_t **drawSurfs, int numDrawSurfs ) { + modelTrace_t mt; + idVec3 start, end; + + if ( !r_showSurfaceInfo.GetBool() ) { + return; + } + + // start far enough away that we don't hit the player model + start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16; + end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f; + if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) { + return; + } + + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_STENCIL_TEST ); + + qglColor3f( 1, 1, 1 ); + + GL_State( GLS_POLYMODE_LINE ); + + qglPolygonOffset( -1, -2 ); + qglEnable( GL_POLYGON_OFFSET_LINE ); + + idVec3 trans[3]; + float matrix[16]; + + // transform the object verts into global space + R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix ); + + tr.primaryWorld->DrawText( mt.entity->hModel->Name(), mt.point + tr.primaryView->renderView.viewaxis[2] * 12, + 0.35f, colorRed, tr.primaryView->renderView.viewaxis ); + tr.primaryWorld->DrawText( mt.material->GetName(), mt.point, + 0.35f, colorBlue, tr.primaryView->renderView.viewaxis ); + + qglEnable( GL_DEPTH_TEST ); + qglDisable( GL_POLYGON_OFFSET_LINE ); + + qglDepthRange( 0, 1 ); + GL_State( GLS_DEFAULT ); + GL_Cull( CT_FRONT_SIDED ); +} + + +/* +===================== +RB_ShowViewEntitys + +Debugging tool +===================== +*/ +static void RB_ShowViewEntitys( viewEntity_t *vModels ) { + if ( !r_showViewEntitys.GetBool() ) { + return; + } + if ( r_showViewEntitys.GetInteger() == 2 ) { + common->Printf( "view entities: " ); + for ( ; vModels ; vModels = vModels->next ) { + common->Printf( "%i ", vModels->entityDef->index ); + } + common->Printf( "\n" ); + return; + } + + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_STENCIL_TEST ); + + qglColor3f( 1, 1, 1 ); + + + GL_State( GLS_POLYMODE_LINE ); + + GL_Cull( CT_TWO_SIDED ); + qglDisable( GL_DEPTH_TEST ); + qglDisable( GL_SCISSOR_TEST ); + + for ( ; vModels ; vModels = vModels->next ) { + idBounds b; + + qglLoadMatrixf( vModels->modelViewMatrix ); + + if ( !vModels->entityDef ) { + continue; + } + + // draw the reference bounds in yellow + qglColor3f( 1, 1, 0 ); + RB_DrawBounds( vModels->entityDef->referenceBounds ); + + + // draw the model bounds in white + qglColor3f( 1, 1, 1 ); + + idRenderModel *model = R_EntityDefDynamicModel( vModels->entityDef ); + if ( !model ) { + continue; // particles won't instantiate without a current view + } + b = model->Bounds( &vModels->entityDef->parms ); + RB_DrawBounds( b ); + } + + qglEnable( GL_DEPTH_TEST ); + qglDisable( GL_POLYGON_OFFSET_LINE ); + + qglDepthRange( 0, 1 ); + GL_State( GLS_DEFAULT ); + GL_Cull( CT_FRONT_SIDED ); +} + +/* +===================== +RB_ShowTexturePolarity + +Shade triangle red if they have a positive texture area +green if they have a negative texture area, or blue if degenerate area +===================== +*/ +static void RB_ShowTexturePolarity( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( !r_showTexturePolarity.GetBool() ) { + return; + } + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + qglColor3f( 1, 1, 1 ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + tri = drawSurf->geo; + if ( !tri->verts ) { + continue; + } + + RB_SimpleSurfaceSetup( drawSurf ); + + qglBegin( GL_TRIANGLES ); + for ( j = 0 ; j < tri->numIndexes ; j+=3 ) { + idDrawVert *a, *b, *c; + float d0[5], d1[5]; + float area; + + a = tri->verts + tri->indexes[j]; + b = tri->verts + tri->indexes[j+1]; + c = tri->verts + tri->indexes[j+2]; + + // VectorSubtract( b->xyz, a->xyz, d0 ); + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + // VectorSubtract( c->xyz, a->xyz, d1 ); + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + + if ( idMath::Fabs( area ) < 0.0001 ) { + qglColor4f( 0, 0, 1, 0.5 ); + } else if ( area < 0 ) { + qglColor4f( 1, 0, 0, 0.5 ); + } else { + qglColor4f( 0, 1, 0, 0.5 ); + } + qglVertex3fv( a->xyz.ToFloatPtr() ); + qglVertex3fv( b->xyz.ToFloatPtr() ); + qglVertex3fv( c->xyz.ToFloatPtr() ); + } + qglEnd(); + } + + GL_State( GLS_DEFAULT ); +} + + +/* +===================== +RB_ShowUnsmoothedTangents + +Shade materials that are using unsmoothed tangents +===================== +*/ +static void RB_ShowUnsmoothedTangents( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( !r_showUnsmoothedTangents.GetBool() ) { + return; + } + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + qglColor4f( 0, 1, 0, 0.5 ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + if ( !drawSurf->material->UseUnsmoothedTangents() ) { + continue; + } + + RB_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->geo; + qglBegin( GL_TRIANGLES ); + for ( j = 0 ; j < tri->numIndexes ; j+=3 ) { + idDrawVert *a, *b, *c; + + a = tri->verts + tri->indexes[j]; + b = tri->verts + tri->indexes[j+1]; + c = tri->verts + tri->indexes[j+2]; + + qglVertex3fv( a->xyz.ToFloatPtr() ); + qglVertex3fv( b->xyz.ToFloatPtr() ); + qglVertex3fv( c->xyz.ToFloatPtr() ); + } + qglEnd(); + } + + GL_State( GLS_DEFAULT ); +} + + +/* +===================== +RB_ShowTangentSpace + +Shade a triangle by the RGB colors of its tangent space +1 = tangents[0] +2 = tangents[1] +3 = normal +===================== +*/ +static void RB_ShowTangentSpace( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( !r_showTangentSpace.GetInteger() ) { + return; + } + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + RB_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->geo; + if ( !tri->verts ) { + continue; + } + qglBegin( GL_TRIANGLES ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + const idDrawVert *v; + + v = &tri->verts[tri->indexes[j]]; + + if ( r_showTangentSpace.GetInteger() == 1 ) { + qglColor4f( 0.5 + 0.5 * v->tangents[0][0], 0.5 + 0.5 * v->tangents[0][1], + 0.5 + 0.5 * v->tangents[0][2], 0.5 ); + } else if ( r_showTangentSpace.GetInteger() == 2 ) { + qglColor4f( 0.5 + 0.5 * v->tangents[1][0], 0.5 + 0.5 * v->tangents[1][1], + 0.5 + 0.5 * v->tangents[1][2], 0.5 ); + } else { + qglColor4f( 0.5 + 0.5 * v->normal[0], 0.5 + 0.5 * v->normal[1], + 0.5 + 0.5 * v->normal[2], 0.5 ); + } + qglVertex3fv( v->xyz.ToFloatPtr() ); + } + qglEnd(); + } + + GL_State( GLS_DEFAULT ); +} + +/* +===================== +RB_ShowVertexColor + +Draw each triangle with the solid vertex colors +===================== +*/ +static void RB_ShowVertexColor( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( !r_showVertexColor.GetBool() ) { + return; + } + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + + GL_State( GLS_DEPTHFUNC_LESS ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + RB_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->geo; + if ( !tri->verts ) { + continue; + } + qglBegin( GL_TRIANGLES ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + const idDrawVert *v; + + v = &tri->verts[tri->indexes[j]]; + qglColor4ubv( v->color ); + qglVertex3fv( v->xyz.ToFloatPtr() ); + } + qglEnd(); + } + + GL_State( GLS_DEFAULT ); +} + + +/* +===================== +RB_ShowNormals + +Debugging tool +===================== +*/ +static void RB_ShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + idVec3 end; + const srfTriangles_t *tri; + float size; + bool showNumbers; + idVec3 pos; + + if ( r_showNormals.GetFloat() == 0.0f ) { + return; + } + + GL_State( GLS_POLYMODE_LINE ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + if ( !r_debugLineDepthTest.GetBool() ) { + qglDisable( GL_DEPTH_TEST ); + } else { + qglEnable( GL_DEPTH_TEST ); + } + + size = r_showNormals.GetFloat(); + if ( size < 0.0f ) { + size = -size; + showNumbers = true; + } else { + showNumbers = false; + } + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + RB_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->geo; + if ( !tri->verts ) { + continue; + } + + qglBegin( GL_LINES ); + for ( j = 0 ; j < tri->numVerts ; j++ ) { + qglColor3f( 0, 0, 1 ); + qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, tri->verts[j].normal, end ); + qglVertex3fv( end.ToFloatPtr() ); + + qglColor3f( 1, 0, 0 ); + qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[0], end ); + qglVertex3fv( end.ToFloatPtr() ); + + qglColor3f( 0, 1, 0 ); + qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[1], end ); + qglVertex3fv( end.ToFloatPtr() ); + } + qglEnd(); + } + + if ( showNumbers ) { + RB_SimpleWorldSetup(); + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + tri = drawSurf->geo; + if ( !tri->verts ) { + continue; + } + + for ( j = 0 ; j < tri->numVerts ; j++ ) { + R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tri->verts[j].tangents[0] + tri->verts[j].normal * 0.2f, pos ); + RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, backEnd.viewDef->renderView.viewaxis, 1 ); + } + + for ( j = 0 ; j < tri->numIndexes; j += 3 ) { + R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + tri->verts[ tri->indexes[ j + 0 ] ].normal * 0.2f, pos ); + RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, backEnd.viewDef->renderView.viewaxis, 1 ); + } + } + } + + qglEnable( GL_STENCIL_TEST ); +} + + +/* +===================== +RB_ShowNormals + +Debugging tool +===================== +*/ +static void RB_AltShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j, k; + drawSurf_t *drawSurf; + idVec3 end; + const srfTriangles_t *tri; + + if ( r_showNormals.GetFloat() == 0.0f ) { + return; + } + + GL_State( GLS_DEFAULT ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + qglDisable( GL_DEPTH_TEST ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + RB_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->geo; + qglBegin( GL_LINES ); + for ( j = 0 ; j < tri->numIndexes ; j += 3 ) { + const idDrawVert *v[3]; + idVec3 mid; + + v[0] = &tri->verts[tri->indexes[j+0]]; + v[1] = &tri->verts[tri->indexes[j+1]]; + v[2] = &tri->verts[tri->indexes[j+2]]; + + // make the midpoint slightly above the triangle + mid = ( v[0]->xyz + v[1]->xyz + v[2]->xyz ) * ( 1.0f / 3.0f ); + mid += 0.1f * tri->facePlanes[ j / 3 ].Normal(); + + for ( k = 0 ; k < 3 ; k++ ) { + idVec3 pos; + + pos = ( mid + v[k]->xyz * 3.0f ) * 0.25f; + + qglColor3f( 0, 0, 1 ); + qglVertex3fv( pos.ToFloatPtr() ); + VectorMA( pos, r_showNormals.GetFloat(), v[k]->normal, end ); + qglVertex3fv( end.ToFloatPtr() ); + + qglColor3f( 1, 0, 0 ); + qglVertex3fv( pos.ToFloatPtr() ); + VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[0], end ); + qglVertex3fv( end.ToFloatPtr() ); + + qglColor3f( 0, 1, 0 ); + qglVertex3fv( pos.ToFloatPtr() ); + VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[1], end ); + qglVertex3fv( end.ToFloatPtr() ); + + qglColor3f( 1, 1, 1 ); + qglVertex3fv( pos.ToFloatPtr() ); + qglVertex3fv( v[k]->xyz.ToFloatPtr() ); + } + } + qglEnd(); + } + + qglEnable( GL_DEPTH_TEST ); + qglEnable( GL_STENCIL_TEST ); +} + + + +/* +===================== +RB_ShowTextureVectors + +Draw texture vectors in the center of each triangle +===================== +*/ +static void RB_ShowTextureVectors( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( r_showTextureVectors.GetFloat() == 0.0f ) { + return; + } + + GL_State( GLS_DEPTHFUNC_LESS ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + globalImages->BindNull(); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + tri = drawSurf->geo; + + if ( !tri->verts ) { + continue; + } + if ( !tri->facePlanes ) { + continue; + } + RB_SimpleSurfaceSetup( drawSurf ); + + // draw non-shared edges in yellow + qglBegin( GL_LINES ); + + for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) { + const idDrawVert *a, *b, *c; + float area, inva; + idVec3 temp; + float d0[5], d1[5]; + idVec3 mid; + idVec3 tangents[2]; + + a = &tri->verts[tri->indexes[j+0]]; + b = &tri->verts[tri->indexes[j+1]]; + c = &tri->verts[tri->indexes[j+2]]; + + // make the midpoint slightly above the triangle + mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ); + mid += 0.1f * tri->facePlanes[ j / 3 ].Normal(); + + // calculate the texture vectors + VectorSubtract( b->xyz, a->xyz, d0 ); + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + VectorSubtract( c->xyz, a->xyz, d1 ); + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + if ( area == 0 ) { + continue; + } + inva = 1.0 / area; + + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva; + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva; + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva; + temp.Normalize(); + tangents[0] = temp; + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva; + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva; + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva; + temp.Normalize(); + tangents[1] = temp; + + // draw the tangents + tangents[0] = mid + tangents[0] * r_showTextureVectors.GetFloat(); + tangents[1] = mid + tangents[1] * r_showTextureVectors.GetFloat(); + + qglColor3f( 1, 0, 0 ); + qglVertex3fv( mid.ToFloatPtr() ); + qglVertex3fv( tangents[0].ToFloatPtr() ); + + qglColor3f( 0, 1, 0 ); + qglVertex3fv( mid.ToFloatPtr() ); + qglVertex3fv( tangents[1].ToFloatPtr() ); + } + + qglEnd(); + } +} + +/* +===================== +RB_ShowDominantTris + +Draw lines from each vertex to the dominant triangle center +===================== +*/ +static void RB_ShowDominantTris( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + + if ( !r_showDominantTri.GetBool() ) { + return; + } + + GL_State( GLS_DEPTHFUNC_LESS ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + qglPolygonOffset( -1, -2 ); + qglEnable( GL_POLYGON_OFFSET_LINE ); + + globalImages->BindNull(); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + tri = drawSurf->geo; + + if ( !tri->verts ) { + continue; + } + if ( !tri->dominantTris ) { + continue; + } + RB_SimpleSurfaceSetup( drawSurf ); + + qglColor3f( 1, 1, 0 ); + qglBegin( GL_LINES ); + + for ( j = 0 ; j < tri->numVerts ; j++ ) { + const idDrawVert *a, *b, *c; + idVec3 mid; + + // find the midpoint of the dominant tri + + a = &tri->verts[j]; + b = &tri->verts[tri->dominantTris[j].v2]; + c = &tri->verts[tri->dominantTris[j].v3]; + + mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ); + + qglVertex3fv( mid.ToFloatPtr() ); + qglVertex3fv( a->xyz.ToFloatPtr() ); + } + + qglEnd(); + } + qglDisable( GL_POLYGON_OFFSET_LINE ); +} + +/* +===================== +RB_ShowEdges + +Debugging tool +===================== +*/ +static void RB_ShowEdges( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i, j, k, m, n, o; + drawSurf_t *drawSurf; + const srfTriangles_t *tri; + const silEdge_t *edge; + int danglePlane; + + if ( !r_showEdges.GetBool() ) { + return; + } + + GL_State( GLS_DEFAULT ); + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + globalImages->BindNull(); + qglDisable( GL_DEPTH_TEST ); + + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + drawSurf = drawSurfs[i]; + + tri = drawSurf->geo; + + idDrawVert *ac = (idDrawVert *)tri->verts; + if ( !ac ) { + continue; + } + + RB_SimpleSurfaceSetup( drawSurf ); + + // draw non-shared edges in yellow + qglColor3f( 1, 1, 0 ); + qglBegin( GL_LINES ); + + for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) { + for ( k = 0 ; k < 3 ; k++ ) { + int l, i1, i2; + l = ( k == 2 ) ? 0 : k + 1; + i1 = tri->indexes[j+k]; + i2 = tri->indexes[j+l]; + + // if these are used backwards, the edge is shared + for ( m = 0 ; m < tri->numIndexes ; m += 3 ) { + for ( n = 0 ; n < 3 ; n++ ) { + o = ( n == 2 ) ? 0 : n + 1; + if ( tri->indexes[m+n] == i2 && tri->indexes[m+o] == i1 ) { + break; + } + } + if ( n != 3 ) { + break; + } + } + + // if we didn't find a backwards listing, draw it in yellow + if ( m == tri->numIndexes ) { + qglVertex3fv( ac[ i1 ].xyz.ToFloatPtr() ); + qglVertex3fv( ac[ i2 ].xyz.ToFloatPtr() ); + } + + } + } + + qglEnd(); + + // draw dangling sil edges in red + if ( !tri->silEdges ) { + continue; + } + + // the plane number after all real planes + // is the dangling edge + danglePlane = tri->numIndexes / 3; + + qglColor3f( 1, 0, 0 ); + + qglBegin( GL_LINES ); + for ( j = 0 ; j < tri->numSilEdges ; j++ ) { + edge = tri->silEdges + j; + + if ( edge->p1 != danglePlane && edge->p2 != danglePlane ) { + continue; + } + + qglVertex3fv( ac[ edge->v1 ].xyz.ToFloatPtr() ); + qglVertex3fv( ac[ edge->v2 ].xyz.ToFloatPtr() ); + } + qglEnd(); + } + + qglEnable( GL_DEPTH_TEST ); +} + +/* +============== +RB_ShowLights + +Visualize all light volumes used in the current scene +r_showLights 1 : just print volumes numbers, highlighting ones covering the view +r_showLights 2 : also draw planes of each volume +r_showLights 3 : also draw edges of each volume +============== +*/ +void RB_ShowLights( void ) { + const idRenderLightLocal *light; + int count; + srfTriangles_t *tri; + viewLight_t *vLight; + + if ( !r_showLights.GetInteger() ) { + return; + } + + // all volumes are expressed in world coordinates + RB_SimpleWorldSetup(); + + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + globalImages->BindNull(); + qglDisable( GL_STENCIL_TEST ); + + + GL_Cull( CT_TWO_SIDED ); + qglDisable( GL_DEPTH_TEST ); + + + common->Printf( "volumes: " ); // FIXME: not in back end! + + count = 0; + for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) { + light = vLight->lightDef; + count++; + + tri = light->frustumTris; + + // depth buffered planes + if ( r_showLights.GetInteger() >= 2 ) { + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + qglColor4f( 0, 0, 1, 0.25 ); + qglEnable( GL_DEPTH_TEST ); + RB_RenderTriangleSurface( tri ); + } + + // non-hidden lines + if ( r_showLights.GetInteger() >= 3 ) { + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK ); + qglDisable( GL_DEPTH_TEST ); + qglColor3f( 1, 1, 1 ); + RB_RenderTriangleSurface( tri ); + } + + int index; + + index = backEnd.viewDef->renderWorld->lightDefs.FindIndex( vLight->lightDef ); + if ( vLight->viewInsideLight ) { + // view is in this volume + common->Printf( "[%i] ", index ); + } else { + common->Printf( "%i ", index ); + } + } + + qglEnable( GL_DEPTH_TEST ); + qglDisable( GL_POLYGON_OFFSET_LINE ); + + qglDepthRange( 0, 1 ); + GL_State( GLS_DEFAULT ); + GL_Cull( CT_FRONT_SIDED ); + + common->Printf( " = %i total\n", count ); +} + +/* +===================== +RB_ShowPortals + +Debugging tool, won't work correctly with SMP or when mirrors are present +===================== +*/ +void RB_ShowPortals( void ) { + if ( !r_showPortals.GetBool() ) { + return; + } + + // all portals are expressed in world coordinates + RB_SimpleWorldSetup(); + + globalImages->BindNull(); + qglDisable( GL_DEPTH_TEST ); + + GL_State( GLS_DEFAULT ); + + ((idRenderWorldLocal *)backEnd.viewDef->renderWorld)->ShowPortals(); + + qglEnable( GL_DEPTH_TEST ); +} + +/* +================ +RB_ClearDebugText +================ +*/ +void RB_ClearDebugText( int time ) { + int i; + int num; + debugText_t *text; + + rb_debugTextTime = time; + + if ( !time ) { + // free up our strings + text = rb_debugText; + for ( i = 0 ; i < MAX_DEBUG_TEXT; i++, text++ ) { + text->text.Clear(); + } + rb_numDebugText = 0; + return; + } + + // copy any text that still needs to be drawn + num = 0; + text = rb_debugText; + for ( i = 0 ; i < rb_numDebugText; i++, text++ ) { + if ( text->lifeTime > time ) { + if ( num != i ) { + rb_debugText[ num ] = *text; + } + num++; + } + } + rb_numDebugText = num; +} + +/* +================ +RB_AddDebugText +================ +*/ +void RB_AddDebugText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ) { + debugText_t *debugText; + + if ( rb_numDebugText < MAX_DEBUG_TEXT ) { + debugText = &rb_debugText[ rb_numDebugText++ ]; + debugText->text = text; + debugText->origin = origin; + debugText->scale = scale; + debugText->color = color; + debugText->viewAxis = viewAxis; + debugText->align = align; + debugText->lifeTime = rb_debugTextTime + lifetime; + debugText->depthTest = depthTest; + } +} + +/* +================ +RB_DrawTextLength + + returns the length of the given text +================ +*/ +float RB_DrawTextLength( const char *text, float scale, int len ) { + int i, num, index, charIndex; + float spacing, textLen = 0.0f; + + if ( text && *text ) { + if ( !len ) { + len = strlen(text); + } + for ( i = 0; i < len; i++ ) { + charIndex = text[i] - 32; + if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) { + continue; + } + num = simplex[charIndex][0] * 2; + spacing = simplex[charIndex][1]; + index = 2; + + while( index - 2 < num ) { + if ( simplex[charIndex][index] < 0) { + index++; + continue; + } + index += 2; + if ( simplex[charIndex][index] < 0) { + index++; + continue; + } + } + textLen += spacing * scale; + } + } + return textLen; +} + +/* +================ +RB_DrawText + + oriented on the viewaxis + align can be 0-left, 1-center (default), 2-right +================ +*/ +static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align ) { + int i, j, len, num, index, charIndex, line; + float textLen, spacing; + idVec3 org, p1, p2; + + if ( text && *text ) { + qglBegin( GL_LINES ); + qglColor3fv( color.ToFloatPtr() ); + + if ( text[0] == '\n' ) { + line = 1; + } else { + line = 0; + } + + len = strlen( text ); + for ( i = 0; i < len; i++ ) { + + if ( i == 0 || text[i] == '\n' ) { + org = origin - viewAxis[2] * ( line * 36.0f * scale ); + if ( align != 0 ) { + for ( j = 1; i+j <= len; j++ ) { + if ( i+j == len || text[i+j] == '\n' ) { + textLen = RB_DrawTextLength( text+i, scale, j ); + break; + } + } + if ( align == 2 ) { + // right + org += viewAxis[1] * textLen; + } else { + // center + org += viewAxis[1] * ( textLen * 0.5f ); + } + } + line++; + } + + charIndex = text[i] - 32; + if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) { + continue; + } + num = simplex[charIndex][0] * 2; + spacing = simplex[charIndex][1]; + index = 2; + + while( index - 2 < num ) { + if ( simplex[charIndex][index] < 0) { + index++; + continue; + } + p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2]; + index += 2; + if ( simplex[charIndex][index] < 0) { + index++; + continue; + } + p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2]; + + qglVertex3fv( p1.ToFloatPtr() ); + qglVertex3fv( p2.ToFloatPtr() ); + } + org -= viewAxis[1] * ( spacing * scale ); + } + + qglEnd(); + } +} + +/* +================ +RB_ShowDebugText +================ +*/ +void RB_ShowDebugText( void ) { + int i; + int width; + debugText_t *text; + + if ( !rb_numDebugText ) { + return; + } + + // all lines are expressed in world coordinates + RB_SimpleWorldSetup(); + + globalImages->BindNull(); + + width = r_debugLineWidth.GetInteger(); + if ( width < 1 ) { + width = 1; + } else if ( width > 10 ) { + width = 10; + } + + // draw lines + GL_State( GLS_POLYMODE_LINE ); + qglLineWidth( width ); + + if ( !r_debugLineDepthTest.GetBool() ) { + qglDisable( GL_DEPTH_TEST ); + } + + text = rb_debugText; + for ( i = 0 ; i < rb_numDebugText; i++, text++ ) { + if ( !text->depthTest ) { + RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); + } + } + + if ( !r_debugLineDepthTest.GetBool() ) { + qglEnable( GL_DEPTH_TEST ); + } + + text = rb_debugText; + for ( i = 0 ; i < rb_numDebugText; i++, text++ ) { + if ( text->depthTest ) { + RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); + } + } + + qglLineWidth( 1 ); + GL_State( GLS_DEFAULT ); +} + +/* +================ +RB_ClearDebugLines +================ +*/ +void RB_ClearDebugLines( int time ) { + int i; + int num; + debugLine_t *line; + + rb_debugLineTime = time; + + if ( !time ) { + rb_numDebugLines = 0; + return; + } + + // copy any lines that still need to be drawn + num = 0; + line = rb_debugLines; + for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) { + if ( line->lifeTime > time ) { + if ( num != i ) { + rb_debugLines[ num ] = *line; + } + num++; + } + } + rb_numDebugLines = num; +} + +/* +================ +RB_AddDebugLine +================ +*/ +void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest ) { + debugLine_t *line; + + if ( rb_numDebugLines < MAX_DEBUG_LINES ) { + line = &rb_debugLines[ rb_numDebugLines++ ]; + line->rgb = color; + line->start = start; + line->end = end; + line->depthTest = depthTest; + line->lifeTime = rb_debugLineTime + lifeTime; + } +} + +/* +================ +RB_ShowDebugLines +================ +*/ +void RB_ShowDebugLines( void ) { + int i; + int width; + debugLine_t *line; + + if ( !rb_numDebugLines ) { + return; + } + + // all lines are expressed in world coordinates + RB_SimpleWorldSetup(); + + globalImages->BindNull(); + + width = r_debugLineWidth.GetInteger(); + if ( width < 1 ) { + width = 1; + } else if ( width > 10 ) { + width = 10; + } + + // draw lines + GL_State( GLS_POLYMODE_LINE );//| GLS_DEPTHMASK ); //| GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + qglLineWidth( width ); + + if ( !r_debugLineDepthTest.GetBool() ) { + qglDisable( GL_DEPTH_TEST ); + } + + qglBegin( GL_LINES ); + + line = rb_debugLines; + for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) { + if ( !line->depthTest ) { + qglColor3fv( line->rgb.ToFloatPtr() ); + qglVertex3fv( line->start.ToFloatPtr() ); + qglVertex3fv( line->end.ToFloatPtr() ); + } + } + qglEnd(); + + if ( !r_debugLineDepthTest.GetBool() ) { + qglEnable( GL_DEPTH_TEST ); + } + + qglBegin( GL_LINES ); + + line = rb_debugLines; + for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) { + if ( line->depthTest ) { + qglColor4fv( line->rgb.ToFloatPtr() ); + qglVertex3fv( line->start.ToFloatPtr() ); + qglVertex3fv( line->end.ToFloatPtr() ); + } + } + + qglEnd(); + + qglLineWidth( 1 ); + GL_State( GLS_DEFAULT ); +} + +/* +================ +RB_ClearDebugPolygons +================ +*/ +void RB_ClearDebugPolygons( int time ) { + int i; + int num; + debugPolygon_t *poly; + + rb_debugPolygonTime = time; + + if ( !time ) { + rb_numDebugPolygons = 0; + return; + } + + // copy any polygons that still need to be drawn + num = 0; + + poly = rb_debugPolygons; + for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) { + if ( poly->lifeTime > time ) { + if ( num != i ) { + rb_debugPolygons[ num ] = *poly; + } + num++; + } + } + rb_numDebugPolygons = num; +} + +/* +================ +RB_AddDebugPolygon +================ +*/ +void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ) { + debugPolygon_t *poly; + + if ( rb_numDebugPolygons < MAX_DEBUG_POLYGONS ) { + poly = &rb_debugPolygons[ rb_numDebugPolygons++ ]; + poly->rgb = color; + poly->winding = winding; + poly->depthTest = depthTest; + poly->lifeTime = rb_debugPolygonTime + lifeTime; + } +} + +/* +================ +RB_ShowDebugPolygons +================ +*/ +void RB_ShowDebugPolygons( void ) { + int i, j; + debugPolygon_t *poly; + + if ( !rb_numDebugPolygons ) { + return; + } + + // all lines are expressed in world coordinates + RB_SimpleWorldSetup(); + + globalImages->BindNull(); + + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_STENCIL_TEST ); + + qglEnable( GL_DEPTH_TEST ); + + if ( r_debugPolygonFilled.GetBool() ) { + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + qglPolygonOffset( -1, -2 ); + qglEnable( GL_POLYGON_OFFSET_FILL ); + } else { + GL_State( GLS_POLYMODE_LINE ); + qglPolygonOffset( -1, -2 ); + qglEnable( GL_POLYGON_OFFSET_LINE ); + } + + poly = rb_debugPolygons; + for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) { +// if ( !poly->depthTest ) { + + qglColor4fv( poly->rgb.ToFloatPtr() ); + + qglBegin( GL_POLYGON ); + + for ( j = 0; j < poly->winding.GetNumPoints(); j++) { + qglVertex3fv( poly->winding[j].ToFloatPtr() ); + } + + qglEnd(); +// } + } + + GL_State( GLS_DEFAULT ); + + if ( r_debugPolygonFilled.GetBool() ) { + qglDisable( GL_POLYGON_OFFSET_FILL ); + } else { + qglDisable( GL_POLYGON_OFFSET_LINE ); + } + + qglDepthRange( 0, 1 ); + GL_State( GLS_DEFAULT ); +} + +/* +================ +RB_TestGamma +================ +*/ +#define G_WIDTH 512 +#define G_HEIGHT 512 +#define BAR_HEIGHT 64 + +void RB_TestGamma( void ) { + byte image[G_HEIGHT][G_WIDTH][4]; + int i, j; + int c, comp; + int v, dither; + int mask, y; + + if ( r_testGamma.GetInteger() <= 0 ) { + return; + } + + v = r_testGamma.GetInteger(); + if ( v <= 1 || v >= 196 ) { + v = 128; + } + + memset( image, 0, sizeof( image ) ); + + for ( mask = 0 ; mask < 8 ; mask++ ) { + y = mask * BAR_HEIGHT; + for ( c = 0 ; c < 4 ; c++ ) { + v = c * 64 + 32; + // solid color + for ( i = 0 ; i < BAR_HEIGHT/2 ; i++ ) { + for ( j = 0 ; j < G_WIDTH/4 ; j++ ) { + for ( comp = 0 ; comp < 3 ; comp++ ) { + if ( mask & ( 1 << comp ) ) { + image[y+i][c*G_WIDTH/4+j][comp] = v; + } + } + } + // dithered color + for ( j = 0 ; j < G_WIDTH/4 ; j++ ) { + if ( ( i ^ j ) & 1 ) { + dither = c * 64; + } else { + dither = c * 64 + 63; + } + for ( comp = 0 ; comp < 3 ; comp++ ) { + if ( mask & ( 1 << comp ) ) { + image[y+BAR_HEIGHT/2+i][c*G_WIDTH/4+j][comp] = dither; + } + } + } + } + } + } + + // draw geometrically increasing steps in the bottom row + y = 0 * BAR_HEIGHT; + float scale = 1; + for ( c = 0 ; c < 4 ; c++ ) { + v = (int)(64 * scale); + if ( v < 0 ) { + v = 0; + } else if ( v > 255 ) { + v = 255; + } + scale = scale * 1.5; + for ( i = 0 ; i < BAR_HEIGHT ; i++ ) { + for ( j = 0 ; j < G_WIDTH/4 ; j++ ) { + image[y+i][c*G_WIDTH/4+j][0] = v; + image[y+i][c*G_WIDTH/4+j][1] = v; + image[y+i][c*G_WIDTH/4+j][2] = v; + } + } + } + + + qglLoadIdentity(); + + qglMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + qglColor3f( 1, 1, 1 ); + qglPushMatrix(); + qglLoadIdentity(); + qglDisable( GL_TEXTURE_2D ); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglRasterPos2f( 0.01f, 0.01f ); + qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); + qglPopMatrix(); + qglEnable( GL_TEXTURE_2D ); + qglMatrixMode( GL_MODELVIEW ); +} + + +/* +================== +RB_TestGammaBias +================== +*/ +static void RB_TestGammaBias( void ) { + byte image[G_HEIGHT][G_WIDTH][4]; + + if ( r_testGammaBias.GetInteger() <= 0 ) { + return; + } + + int y = 0; + for ( int bias = -40 ; bias < 40 ; bias+=10, y += BAR_HEIGHT ) { + float scale = 1; + for ( int c = 0 ; c < 4 ; c++ ) { + int v = (int)(64 * scale + bias); + scale = scale * 1.5; + if ( v < 0 ) { + v = 0; + } else if ( v > 255 ) { + v = 255; + } + for ( int i = 0 ; i < BAR_HEIGHT ; i++ ) { + for ( int j = 0 ; j < G_WIDTH/4 ; j++ ) { + image[y+i][c*G_WIDTH/4+j][0] = v; + image[y+i][c*G_WIDTH/4+j][1] = v; + image[y+i][c*G_WIDTH/4+j][2] = v; + } + } + } + } + + + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + qglColor3f( 1, 1, 1 ); + qglPushMatrix(); + qglLoadIdentity(); + qglDisable( GL_TEXTURE_2D ); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + qglRasterPos2f( 0.01f, 0.01f ); + qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); + qglPopMatrix(); + qglEnable( GL_TEXTURE_2D ); + qglMatrixMode( GL_MODELVIEW ); +} + +/* +================ +RB_TestImage + +Display a single image over most of the screen +================ +*/ +void RB_TestImage( void ) { + idImage *image; + int max; + float w, h; + + image = tr.testImage; + if ( !image ) { + return; + } + + if ( tr.testVideo ) { + cinData_t cin; + + cin = tr.testVideo->ImageForTime( (int)(1000 * ( backEnd.viewDef->floatTime - tr.testVideoStartTime ) ) ); + if ( cin.image ) { + image->UploadScratch( cin.image, cin.imageWidth, cin.imageHeight ); + } else { + tr.testImage = NULL; + return; + } + w = 0.25; + h = 0.25; + } else { + max = image->uploadWidth > image->uploadHeight ? image->uploadWidth : image->uploadHeight; + + w = 0.25 * image->uploadWidth / max; + h = 0.25 * image->uploadHeight / max; + + w *= (float)glConfig.vidHeight / glConfig.vidWidth; + } + + qglLoadIdentity(); + + qglMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + qglColor3f( 1, 1, 1 ); + qglPushMatrix(); + qglLoadIdentity(); + qglOrtho( 0, 1, 0, 1, -1, 1 ); + + tr.testImage->Bind(); + qglBegin( GL_QUADS ); + + qglTexCoord2f( 0, 1 ); + qglVertex2f( 0.5 - w, 0 ); + + qglTexCoord2f( 0, 0 ); + qglVertex2f( 0.5 - w, h*2 ); + + qglTexCoord2f( 1, 0 ); + qglVertex2f( 0.5 + w, h*2 ); + + qglTexCoord2f( 1, 1 ); + qglVertex2f( 0.5 + w, 0 ); + + qglEnd(); + + qglPopMatrix(); + qglMatrixMode( GL_MODELVIEW ); +} + +/* +================= +RB_RenderDebugTools +================= +*/ +void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs ) { + // don't do anything if this was a 2D rendering + if ( !backEnd.viewDef->viewEntitys ) { + return; + } + + RB_LogComment( "---------- RB_RenderDebugTools ----------\n" ); + + GL_State( GLS_DEFAULT ); + backEnd.currentScissor = backEnd.viewDef->scissor; + qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, + backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, + backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, + backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + + + RB_ShowLightCount(); + RB_ShowShadowCount(); + RB_ShowTexturePolarity( drawSurfs, numDrawSurfs ); + RB_ShowTangentSpace( drawSurfs, numDrawSurfs ); + RB_ShowVertexColor( drawSurfs, numDrawSurfs ); + RB_ShowTris( drawSurfs, numDrawSurfs ); + RB_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs ); + RB_ShowSurfaceInfo( drawSurfs, numDrawSurfs ); + RB_ShowEdges( drawSurfs, numDrawSurfs ); + RB_ShowNormals( drawSurfs, numDrawSurfs ); + RB_ShowViewEntitys( backEnd.viewDef->viewEntitys ); + RB_ShowLights(); + RB_ShowTextureVectors( drawSurfs, numDrawSurfs ); + RB_ShowDominantTris( drawSurfs, numDrawSurfs ); + if ( r_testGamma.GetInteger() > 0 ) { // test here so stack check isn't so damn slow on debug builds + RB_TestGamma(); + } + if ( r_testGammaBias.GetInteger() > 0 ) { + RB_TestGammaBias(); + } + RB_TestImage(); + RB_ShowPortals(); + RB_ShowSilhouette(); + RB_ShowDepthBuffer(); + RB_ShowIntensity(); + RB_ShowDebugLines(); + RB_ShowDebugText(); + RB_ShowDebugPolygons(); + RB_ShowTrace( drawSurfs, numDrawSurfs ); +} + +/* +================= +RB_ShutdownDebugTools +================= +*/ +void RB_ShutdownDebugTools( void ) { + for ( int i = 0; i < MAX_DEBUG_POLYGONS; i++ ) { + rb_debugPolygons[i].winding.Clear(); + } +} diff --git a/renderer/tr_shadowbounds.cpp b/renderer/tr_shadowbounds.cpp new file mode 100644 index 000000000..18ec6e132 --- /dev/null +++ b/renderer/tr_shadowbounds.cpp @@ -0,0 +1,629 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + + +// Compute conservative shadow bounds as the intersection +// of the object's bounds' shadow volume and the light's bounds. +// +// --cass + + +template +struct MyArray +{ + MyArray() : s(0) {} + + MyArray( const MyArray & cpy ) : s(cpy.s) + { + for(int i=0; i < s; i++) + v[i] = cpy.v[i]; + } + + void push_back(const T & i) { + v[s] = i; + s++; + //if(s > max_size) + // max_size = int(s); + } + + T & operator[](int i) { + return v[i]; + } + + const T & operator[](int i) const { + return v[i]; + } + + unsigned int size() const { + return s; + } + + void empty() { + s = 0; + } + + T v[N]; + int s; +// static int max_size; +}; + +typedef MyArray MyArrayInt; +//int MyArrayInt::max_size = 0; +typedef MyArray MyArrayVec4; +//int MyArrayVec4::max_size = 0; + +struct poly +{ + MyArrayInt vi; + MyArrayInt ni; + idVec4 plane; +}; + +typedef MyArray MyArrayPoly; +//int MyArrayPoly::max_size = 0; + +struct edge +{ + int vi[2]; + int pi[2]; +}; + +typedef MyArray MyArrayEdge; +//int MyArrayEdge::max_size = 0; + +MyArrayInt four_ints(int a, int b, int c, int d) +{ + MyArrayInt vi; + vi.push_back(a); + vi.push_back(b); + vi.push_back(c); + vi.push_back(d); + return vi; +} + +idVec3 homogeneous_difference(idVec4 a, idVec4 b) +{ + idVec3 v; + v.x = b.x * a.w - a.x * b.w; + v.y = b.y * a.w - a.y * b.w; + v.z = b.z * a.w - a.z * b.w; + return v; +} + +// handles positive w only +idVec4 compute_homogeneous_plane(idVec4 a, idVec4 b, idVec4 c) +{ + idVec4 v, t; + + if(a[3] == 0) + { t = a; a = b; b = c; c = t; } + if(a[3] == 0) + { t = a; a = b; b = c; c = t; } + + // can't handle 3 infinite points + if( a[3] == 0 ) + return v; + + idVec3 vb = homogeneous_difference(a, b); + idVec3 vc = homogeneous_difference(a, c); + + idVec3 n = vb.Cross(vc); + n.Normalize(); + + v.x = n.x; + v.y = n.y; + v.z = n.z; + + v.w = - (n * idVec3(a.x, a.y, a.z)) / a.w ; + + return v; +} + +struct polyhedron +{ + MyArrayVec4 v; + MyArrayPoly p; + MyArrayEdge e; + + void add_quad( int va, int vb, int vc, int vd ) + { + poly pg; + pg.vi = four_ints(va, vb, vc, vd); + pg.ni = four_ints(-1, -1, -1, -1); + pg.plane = compute_homogeneous_plane(v[va], v[vb], v[vc]); + p.push_back(pg); + } + + void discard_neighbor_info() + { + for(unsigned int i = 0; i < p.size(); i++ ) + { + MyArrayInt & ni = p[i].ni; + for(unsigned int j = 0; j < ni.size(); j++) + ni[j] = -1; + } + } + + void compute_neighbors() + { + e.empty(); + + discard_neighbor_info(); + + bool found; + int P = p.size(); + // for each polygon + for(int i = 0; i < P-1; i++ ) + { + const MyArrayInt & vi = p[i].vi; + MyArrayInt & ni = p[i].ni; + int Si = vi.size(); + + // for each edge of that polygon + for(int ii=0; ii < Si; ii++) + { + int ii0 = ii; + int ii1 = (ii+1) % Si; + + // continue if we've already found this neighbor + if(ni[ii] != -1) + continue; + found = false; + // check all remaining polygons + for(int j = i+1; j < P; j++ ) + { + const MyArrayInt & vj = p[j].vi; + MyArrayInt & nj = p[j].ni; + int Sj = vj.size(); + + for( int jj = 0; jj < Sj; jj++ ) + { + int jj0 = jj; + int jj1 = (jj+1) % Sj; + if(vi[ii0] == vj[jj1] && vi[ii1] == vj[jj0]) + { + edge ed; + ed.vi[0] = vi[ii0]; + ed.vi[1] = vi[ii1]; + ed.pi[0] = i; + ed.pi[1] = j; + e.push_back(ed); + ni[ii] = j; + nj[jj] = i; + found = true; + break; + } + else if ( vi[ii0] == vj[jj0] && vi[ii1] == vj[jj1] ) + { + fprintf(stderr,"why am I here?\n"); + } + } + if( found ) + break; + } + } + } + } + + void recompute_planes() + { + // for each polygon + for(unsigned int i = 0; i < p.size(); i++ ) + { + p[i].plane = compute_homogeneous_plane(v[p[i].vi[0]], v[p[i].vi[1]], v[p[i].vi[2]]); + } + } + + void transform(const idMat4 & m) + { + for(unsigned int i=0; i < v.size(); i++ ) + v[i] = m * v[i]; + recompute_planes(); + } + +}; + +// make a unit cube +polyhedron PolyhedronFromBounds( const idBounds & b ) +{ + +// 3----------2 +// |\ /| +// | \ / | +// | 7--6 | +// | | | | +// | 4--5 | +// | / \ | +// | / \ | +// 0----------1 +// + + static polyhedron p; + + if( p.e.size() == 0 ) { + + p.v.push_back(idVec4( -1, -1, 1, 1)); + p.v.push_back(idVec4( 1, -1, 1, 1)); + p.v.push_back(idVec4( 1, 1, 1, 1)); + p.v.push_back(idVec4( -1, 1, 1, 1)); + p.v.push_back(idVec4( -1, -1, -1, 1)); + p.v.push_back(idVec4( 1, -1, -1, 1)); + p.v.push_back(idVec4( 1, 1, -1, 1)); + p.v.push_back(idVec4( -1, 1, -1, 1)); + + p.add_quad( 0, 1, 2, 3 ); + p.add_quad( 7, 6, 5, 4 ); + p.add_quad( 1, 0, 4, 5 ); + p.add_quad( 2, 1, 5, 6 ); + p.add_quad( 3, 2, 6, 7 ); + p.add_quad( 0, 3, 7, 4 ); + + p.compute_neighbors(); + p.recompute_planes(); + p.v.empty(); // no need to copy this data since it'll be replaced + } + + polyhedron p2(p); + + const idVec3 & min = b[0]; + const idVec3 & max = b[1]; + + p2.v.empty(); + p2.v.push_back(idVec4( min.x, min.y, max.z, 1)); + p2.v.push_back(idVec4( max.x, min.y, max.z, 1)); + p2.v.push_back(idVec4( max.x, max.y, max.z, 1)); + p2.v.push_back(idVec4( min.x, max.y, max.z, 1)); + p2.v.push_back(idVec4( min.x, min.y, min.z, 1)); + p2.v.push_back(idVec4( max.x, min.y, min.z, 1)); + p2.v.push_back(idVec4( max.x, max.y, min.z, 1)); + p2.v.push_back(idVec4( min.x, max.y, min.z, 1)); + + p2.recompute_planes(); + return p2; +} + + +polyhedron make_sv(const polyhedron & oc, idVec4 light) +{ + static polyhedron lut[64]; + int index = 0; + + for(unsigned int i = 0; i < 6; i++) { + if( ( oc.p[i].plane * light ) > 0 ) + index |= 1< 0) + { + ph.p.push_back(oc.p[i]); + } + } + + if(ph.p.size() == 0) + return ph = polyhedron(); + + ph.compute_neighbors(); + + MyArrayPoly vpg; + int I = ph.p.size(); + + for(int i=0; i < I; i++) + { + MyArrayInt & vi = ph.p[i].vi; + MyArrayInt & ni = ph.p[i].ni; + int S = vi.size(); + + for(int j = 0; j < S; j++) + { + if( ni[j] == -1 ) + { + poly pg; + int a = vi[(j+1)%S]; + int b = vi[j]; + pg.vi = four_ints( a, b, b+V, a+V); + pg.ni = four_ints(-1, -1, -1, -1); + vpg.push_back(pg); + } + } + } + for(unsigned int i = 0; i < vpg.size(); i++) + ph.p.push_back(vpg[i]); + + ph.compute_neighbors(); + ph.v.empty(); // no need to copy this data since it'll be replaced + } + + polyhedron ph2 = lut[index]; + + // initalize vertices + ph2.v = oc.v; + int V = ph2.v.size(); + for( int j = 0; j < V; j++ ) + { + idVec3 proj = homogeneous_difference( light, ph2.v[j] ); + ph2.v.push_back( idVec4(proj.x, proj.y, proj.z, 0) ); + } + + // need to compute planes for the shadow volume (sv) + ph2.recompute_planes(); + + return ph2; +} + +typedef MyArray MySegments; +//int MySegments::max_size = 0; + +void polyhedron_edges(polyhedron & a, MySegments & e) +{ + e.empty(); + if(a.e.size() == 0 && a.p.size() != 0) + a.compute_neighbors(); + + for(unsigned int i = 0; i < a.e.size(); i++) + { + e.push_back(a.v[a.e[i].vi[0]]); + e.push_back(a.v[a.e[i].vi[1]]); + } + +} + +// clip the segments of e by the planes of polyhedron a. +void clip_segments(const polyhedron & ph, MySegments & is, MySegments & os) +{ + const MyArrayPoly & p = ph.p; + + for(unsigned int i = 0; i < is.size(); i+=2 ) + { + idVec4 a = is[i ]; + idVec4 b = is[i+1]; + idVec4 c; + + bool discard = false; + + for(unsigned int j = 0; j < p.size(); j++ ) + { + float da = a * p[j].plane; + float db = b * p[j].plane; + float rdw = 1/(da - db); + + int code = 0; + if( da > 0 ) + code = 2; + if( db > 0 ) + code |= 1; + + + switch ( code ) + { + case 3: + discard = true; + break; + + case 2: + c = -db * rdw * a + da * rdw * b; + a = c; + break; + + case 1: + c = -db * rdw * a + da * rdw * b; + b = c; + break; + + case 0: + break; + + default: + common->Printf("bad clip code!\n"); + break; + } + + if( discard ) + break; + } + + if( ! discard ) + { + os.push_back(a); + os.push_back(b); + } + } + +} + +idMat4 make_idMat4(const float * m) +{ + return idMat4( m[ 0], m[ 4], m[ 8], m[12], + m[ 1], m[ 5], m[ 9], m[13], + m[ 2], m[ 6], m[10], m[14], + m[ 3], m[ 7], m[11], m[15] ); +} + +idVec3 v4to3(const idVec4 & v) +{ + return idVec3(v.x/v.w, v.y/v.w, v.z/v.w); +} + +void draw_polyhedron( const viewDef_t *viewDef, const polyhedron & p, idVec4 color ) +{ + for(unsigned int i = 0; i < p.e.size(); i++) + { + viewDef->renderWorld->DebugLine( color, v4to3(p.v[p.e[i].vi[0]]), v4to3(p.v[p.e[i].vi[1]])); + } +} + +void draw_segments( const viewDef_t *viewDef, const MySegments & s, idVec4 color ) +{ + for(unsigned int i = 0; i < s.size(); i+=2) + { + viewDef->renderWorld->DebugLine( color, v4to3(s[i]), v4to3(s[i+1])); + } +} + +void world_to_hclip( const viewDef_t *viewDef, const idVec4 &global, idVec4 &clip ) { + int i; + idVec4 view; + + for ( i = 0 ; i < 4 ; i ++ ) { + view[i] = + global[0] * viewDef->worldSpace.modelViewMatrix[ i + 0 * 4 ] + + global[1] * viewDef->worldSpace.modelViewMatrix[ i + 1 * 4 ] + + global[2] * viewDef->worldSpace.modelViewMatrix[ i + 2 * 4 ] + + global[3] * viewDef->worldSpace.modelViewMatrix[ i + 3 * 4 ]; + } + + + for ( i = 0 ; i < 4 ; i ++ ) { + clip[i] = + view[0] * viewDef->projectionMatrix[ i + 0 * 4 ] + + view[1] * viewDef->projectionMatrix[ i + 1 * 4 ] + + view[2] * viewDef->projectionMatrix[ i + 2 * 4 ] + + view[3] * viewDef->projectionMatrix[ i + 3 * 4 ]; + } +} + +idScreenRect R_CalcIntersectionScissor( const idRenderLightLocal * lightDef, + const idRenderEntityLocal * entityDef, + const viewDef_t * viewDef ) { + + idMat4 omodel = make_idMat4( entityDef->modelMatrix ); + idMat4 lmodel = make_idMat4( lightDef->modelMatrix ); + + // compute light polyhedron + polyhedron lvol = PolyhedronFromBounds( lightDef->frustumTris->bounds ); + // transform it into world space + //lvol.transform( lmodel ); + + // debug // + if ( r_useInteractionScissors.GetInteger() == -2 ) { + draw_polyhedron( viewDef, lvol, colorRed ); + } + + // compute object polyhedron + polyhedron vol = PolyhedronFromBounds( entityDef->referenceBounds ); + + //viewDef->renderWorld->DebugBounds( colorRed, lightDef->frustumTris->bounds ); + //viewDef->renderWorld->DebugBox( colorBlue, idBox( model->Bounds(), entityDef->parms.origin, entityDef->parms.axis ) ); + + // transform it into world space + vol.transform( omodel ); + + // debug // + if ( r_useInteractionScissors.GetInteger() == -2 ) { + draw_polyhedron( viewDef, vol, colorBlue ); + } + + // transform light position into world space + idVec4 lightpos = idVec4(lightDef->globalLightOrigin.x, + lightDef->globalLightOrigin.y, + lightDef->globalLightOrigin.z, + 1.0f ); + + // generate shadow volume "polyhedron" + polyhedron sv = make_sv(vol, lightpos); + + MySegments in_segs, out_segs; + + // get shadow volume edges + polyhedron_edges(sv, in_segs); + // clip them against light bounds planes + clip_segments(lvol, in_segs, out_segs); + + // get light bounds edges + polyhedron_edges(lvol, in_segs); + // clip them by the shadow volume + clip_segments(sv, in_segs, out_segs); + + // debug // + if ( r_useInteractionScissors.GetInteger() == -2 ) { + draw_segments( viewDef, out_segs, colorGreen ); + } + + idBounds outbounds; + outbounds.Clear(); + for( unsigned int i = 0; i < out_segs.size(); i++ ) { + + idVec4 v; + world_to_hclip( viewDef, out_segs[i], v ); + + if( v.w <= 0.0f ) { + return lightDef->viewLight->scissorRect; + } + + idVec3 rv(v.x, v.y, v.z); + rv /= v.w; + + outbounds.AddPoint( rv ); + } + + // limit the bounds to avoid an inside out scissor rectangle due to floating point to short conversion + if ( outbounds[0].x < -1.0f ) { + outbounds[0].x = -1.0f; + } + if ( outbounds[1].x > 1.0f ) { + outbounds[1].x = 1.0f; + } + if ( outbounds[0].y < -1.0f ) { + outbounds[0].y = -1.0f; + } + if ( outbounds[1].y > 1.0f ) { + outbounds[1].y = 1.0f; + } + + float w2 = ( viewDef->viewport.x2 - viewDef->viewport.x1 + 1 ) / 2.0f; + float x = viewDef->viewport.x1; + float h2 = ( viewDef->viewport.y2 - viewDef->viewport.y1 + 1 ) / 2.0f; + float y = viewDef->viewport.y1; + + idScreenRect rect; + rect.x1 = outbounds[0].x * w2 + w2 + x; + rect.x2 = outbounds[1].x * w2 + w2 + x; + rect.y1 = outbounds[0].y * h2 + h2 + y; + rect.y2 = outbounds[1].y * h2 + h2 + y; + rect.Expand(); + + rect.Intersect( lightDef->viewLight->scissorRect ); + + // debug // + if ( r_useInteractionScissors.GetInteger() == -2 && !rect.IsEmpty() ) { + viewDef->renderWorld->DebugScreenRect( colorYellow, rect, viewDef ); + } + + return rect; +} diff --git a/renderer/tr_stencilshadow.cpp b/renderer/tr_stencilshadow.cpp new file mode 100644 index 000000000..88dd27975 --- /dev/null +++ b/renderer/tr_stencilshadow.cpp @@ -0,0 +1,1386 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +// tr_stencilShadow.c -- creaton of stencil shadow volumes + +/* + + Should we split shadow volume surfaces when they exceed max verts + or max indexes? + + a problem is that the number of vertexes needed for the + shadow volume will be twice the number in the original, + and possibly up to 8/3 when near plane clipped. + + The maximum index count is 7x when not clipped and all + triangles are completely discrete. Near plane clipping + can increase this to 10x. + + The maximum expansions are always with discrete triangles. + Meshes of triangles will result in less index expansion because + there will be less silhouette edges, although it will always be + greater than the source if a cap is present. + + can't just project onto a plane if some surface points are + behind the light. + + The cases when a face is edge on to a light is robustly handled + with closed volumes, because only a single one of it's neighbors + will pass the edge test. It may be an issue with non-closed models. + + It is crucial that the shadow volumes be completely enclosed. + The triangles identified as shadow sources will be projected + directly onto the light far plane. + The sil edges must be handled carefully. + A partially clipped explicit sil edge will still generate a sil + edge. + EVERY new edge generated by clipping the triangles to the view + will generate a sil edge. + + If a triangle has no points inside the frustum, it is completely + culled away. If a sil edge is either in or on the frustum, it is + added. + If a triangle has no points outside the frustum, it does not + need to be clipped. + + + + USING THE STENCIL BUFFER FOR SHADOWING + + basic triangle property + + view plane inside shadow volume problem + + quad triangulation issue + + issues with silhouette optimizations + + the shapes of shadow projections are poor for sphere or box culling + + the gouraud shading problem + + + // epsilon culling rules: + +// the positive side of the frustum is inside +d = tri->verts[i].xyz * frustum[j].Normal() + frustum[j][3]; +if ( d < LIGHT_CLIP_EPSILON ) { + pointCull[i] |= ( 1 << j ); +} +if ( d > -LIGHT_CLIP_EPSILON ) { + pointCull[i] |= ( 1 << (6+j) ); +} + +If a low order bit is set, the point is on or outside the plane +If a high order bit is set, the point is on or inside the plane +If a low order bit is clear, the point is inside the plane (definately positive) +If a high order bit is clear, the point is outside the plane (definately negative) + + +*/ + +#define TRIANGLE_CULLED(p1,p2,p3) ( pointCull[p1] & pointCull[p2] & pointCull[p3] & 0x3f ) + +//#define TRIANGLE_CLIPPED(p1,p2,p3) ( ( pointCull[p1] | pointCull[p2] | pointCull[p3] ) & 0xfc0 ) +#define TRIANGLE_CLIPPED(p1,p2,p3) ( ( ( pointCull[p1] & pointCull[p2] & pointCull[p3] ) & 0xfc0 ) != 0xfc0 ) + +// an edge that is on the plane is NOT culled +#define EDGE_CULLED(p1,p2) ( ( pointCull[p1] ^ 0xfc0 ) & ( pointCull[p2] ^ 0xfc0 ) & 0xfc0 ) + +#define EDGE_CLIPPED(p1,p2) ( ( pointCull[p1] & pointCull[p2] & 0xfc0 ) != 0xfc0 ) + +// a point that is on the plane is NOT culled +//#define POINT_CULLED(p1) ( ( pointCull[p1] ^ 0xfc0 ) & 0xfc0 ) +#define POINT_CULLED(p1) ( ( pointCull[p1] & 0xfc0 ) != 0xfc0 ) + +//#define LIGHT_CLIP_EPSILON 0.001f +#define LIGHT_CLIP_EPSILON 0.1f + +#define MAX_CLIP_SIL_EDGES 2048 +static int numClipSilEdges; +static int clipSilEdges[MAX_CLIP_SIL_EDGES][2]; + +// facing will be 0 if forward facing, 1 if backwards facing +// grabbed with alloca +static byte *globalFacing; + +// faceCastsShadow will be 1 if the face is in the projection +// and facing the apropriate direction +static byte *faceCastsShadow; + +static int *remap; + +#define MAX_SHADOW_INDEXES 0x18000 +#define MAX_SHADOW_VERTS 0x18000 +static int numShadowIndexes; +static glIndex_t shadowIndexes[MAX_SHADOW_INDEXES]; +static int numShadowVerts; +static idVec4 shadowVerts[MAX_SHADOW_VERTS]; +static bool overflowed; + +idPlane pointLightFrustums[6][6] = { + { + idPlane( 1,0,0,0 ), + idPlane( 1,1,0,0 ), + idPlane( 1,-1,0,0 ), + idPlane( 1,0,1,0 ), + idPlane( 1,0,-1,0 ), + idPlane( -1,0,0,0 ), + }, + { + idPlane( -1,0,0,0 ), + idPlane( -1,1,0,0 ), + idPlane( -1,-1,0,0 ), + idPlane( -1,0,1,0 ), + idPlane( -1,0,-1,0 ), + idPlane( 1,0,0,0 ), + }, + + { + idPlane( 0,1,0,0 ), + idPlane( 0,1,1,0 ), + idPlane( 0,1,-1,0 ), + idPlane( 1,1,0,0 ), + idPlane( -1,1,0,0 ), + idPlane( 0,-1,0,0 ), + }, + { + idPlane( 0,-1,0,0 ), + idPlane( 0,-1,1,0 ), + idPlane( 0,-1,-1,0 ), + idPlane( 1,-1,0,0 ), + idPlane( -1,-1,0,0 ), + idPlane( 0,1,0,0 ), + }, + + { + idPlane( 0,0,1,0 ), + idPlane( 1,0,1,0 ), + idPlane( -1,0,1,0 ), + idPlane( 0,1,1,0 ), + idPlane( 0,-1,1,0 ), + idPlane( 0,0,-1,0 ), + }, + { + idPlane( 0,0,-1,0 ), + idPlane( 1,0,-1,0 ), + idPlane( -1,0,-1,0 ), + idPlane( 0,1,-1,0 ), + idPlane( 0,-1,-1,0 ), + idPlane( 0,0,1,0 ), + }, +}; + +int c_caps, c_sils; + +static bool callOptimizer; // call the preprocessor optimizer after clipping occluders + +typedef struct { + int frontCapStart; + int rearCapStart; + int silStart; + int end; +} indexRef_t; +static indexRef_t indexRef[6]; +static int indexFrustumNumber; // which shadow generating side of a light the indexRef is for + +/* +=============== +PointsOrdered + +To make sure the triangulations of the sil edges is consistant, +we need to be able to order two points. We don't care about how +they compare with any other points, just that when the same two +points are passed in (in either order), they will always specify +the same one as leading. + +Currently we need to have separate faces in different surfaces +order the same way, so we must look at the actual coordinates. +If surfaces are ever guaranteed to not have to edge match with +other surfaces, we could just compare indexes. +=============== +*/ +static bool PointsOrdered( const idVec3 &a, const idVec3 &b ) { + float i, j; + + // vectors that wind up getting an equal hash value will + // potentially cause a misorder, which can show as a couple + // crack pixels in a shadow + + // scale by some odd numbers so -8, 8, 8 will not be equal + // to 8, -8, 8 + + // in the very rare case that these might be equal, all that would + // happen is an oportunity for a tiny rasterization shadow crack + i = a[0] + a[1]*127 + a[2]*1023; + j = b[0] + b[1]*127 + b[2]*1023; + + return (bool)(i < j); +} + +/* +==================== +R_LightProjectionMatrix + +==================== +*/ +void R_LightProjectionMatrix( const idVec3 &origin, const idPlane &rearPlane, idVec4 mat[4] ) { + idVec4 lv; + float lg; + + // calculate the homogenious light vector + lv.x = origin.x; + lv.y = origin.y; + lv.z = origin.z; + lv.w = 1; + + lg = rearPlane.ToVec4() * lv; + + // outer product + mat[0][0] = lg -rearPlane[0] * lv[0]; + mat[0][1] = -rearPlane[1] * lv[0]; + mat[0][2] = -rearPlane[2] * lv[0]; + mat[0][3] = -rearPlane[3] * lv[0]; + + mat[1][0] = -rearPlane[0] * lv[1]; + mat[1][1] = lg -rearPlane[1] * lv[1]; + mat[1][2] = -rearPlane[2] * lv[1]; + mat[1][3] = -rearPlane[3] * lv[1]; + + mat[2][0] = -rearPlane[0] * lv[2]; + mat[2][1] = -rearPlane[1] * lv[2]; + mat[2][2] = lg -rearPlane[2] * lv[2]; + mat[2][3] = -rearPlane[3] * lv[2]; + + mat[3][0] = -rearPlane[0] * lv[3]; + mat[3][1] = -rearPlane[1] * lv[3]; + mat[3][2] = -rearPlane[2] * lv[3]; + mat[3][3] = lg -rearPlane[3] * lv[3]; +} + +/* +=================== +R_ProjectPointsToFarPlane + +make a projected copy of the even verts into the odd spots +that is on the far light clip plane +=================== +*/ +static void R_ProjectPointsToFarPlane( const idRenderEntityLocal *ent, const idRenderLightLocal *light, + const idPlane &lightPlaneLocal, + int firstShadowVert, int numShadowVerts ) { + idVec3 lv; + idVec4 mat[4]; + int i; + idVec4 *in; + + R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, lv ); + R_LightProjectionMatrix( lv, lightPlaneLocal, mat ); + +#if 1 + // make a projected copy of the even verts into the odd spots + in = &shadowVerts[firstShadowVert]; + for ( i = firstShadowVert ; i < numShadowVerts ; i+= 2, in += 2 ) { + float w, oow; + + in[0].w = 1; + + w = in->ToVec3() * mat[3].ToVec3() + mat[3][3]; + if ( w == 0 ) { + in[1] = in[0]; + continue; + } + + oow = 1.0 / w; + in[1].x = ( in->ToVec3() * mat[0].ToVec3() + mat[0][3] ) * oow; + in[1].y = ( in->ToVec3() * mat[1].ToVec3() + mat[1][3] ) * oow; + in[1].z = ( in->ToVec3() * mat[2].ToVec3() + mat[2][3] ) * oow; + in[1].w = 1; + } + +#else + // messing with W seems to cause some depth precision problems + + // make a projected copy of the even verts into the odd spots + in = &shadowVerts[firstShadowVert]; + for ( i = firstShadowVert ; i < numShadowVerts ; i+= 2, in += 2 ) { + in[0].w = 1; + in[1].x = *in * mat[0].ToVec3() + mat[0][3]; + in[1].y = *in * mat[1].ToVec3() + mat[1][3]; + in[1].z = *in * mat[2].ToVec3() + mat[2][3]; + in[1].w = *in * mat[3].ToVec3() + mat[3][3]; + } +#endif +} + + + +#define MAX_CLIPPED_POINTS 20 +typedef struct { + int numVerts; + idVec3 verts[MAX_CLIPPED_POINTS]; + int edgeFlags[MAX_CLIPPED_POINTS]; +} clipTri_t; + +/* +============= +R_ChopWinding + +Clips a triangle from one buffer to another, setting edge flags +The returned buffer may be the same as inNum if no clipping is done +If entirely clipped away, clipTris[returned].numVerts == 0 + +I have some worries about edge flag cases when polygons are clipped +multiple times near the epsilon. +============= +*/ +static int R_ChopWinding( clipTri_t clipTris[2], int inNum, const idPlane &plane ) { + clipTri_t *in, *out; + float dists[MAX_CLIPPED_POINTS]; + int sides[MAX_CLIPPED_POINTS]; + int counts[3]; + float dot; + int i, j; + idVec3 *p1, *p2; + idVec3 mid; + + in = &clipTris[inNum]; + out = &clipTris[inNum^1]; + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + for ( i = 0 ; i < in->numVerts ; i++ ) { + dot = plane.Distance( in->verts[i] ); + dists[i] = dot; + if ( dot < -LIGHT_CLIP_EPSILON ) { + sides[i] = SIDE_BACK; + } else if ( dot > LIGHT_CLIP_EPSILON ) { + sides[i] = SIDE_FRONT; + } else { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + + // if none in front, it is completely clipped away + if ( !counts[SIDE_FRONT] ) { + in->numVerts = 0; + return inNum; + } + if ( !counts[SIDE_BACK] ) { + return inNum; // inout stays the same + } + + // avoid wrapping checks by duplicating first value to end + sides[i] = sides[0]; + dists[i] = dists[0]; + in->verts[in->numVerts] = in->verts[0]; + in->edgeFlags[in->numVerts] = in->edgeFlags[0]; + + out->numVerts = 0; + for ( i = 0 ; i < in->numVerts ; i++ ) { + p1 = &in->verts[i]; + + if ( sides[i] != SIDE_BACK ) { + out->verts[out->numVerts] = *p1; + if ( sides[i] == SIDE_ON && sides[i+1] == SIDE_BACK ) { + out->edgeFlags[out->numVerts] = 1; + } else { + out->edgeFlags[out->numVerts] = in->edgeFlags[i]; + } + out->numVerts++; + } + + if ( (sides[i] == SIDE_FRONT && sides[i+1] == SIDE_BACK) + || (sides[i] == SIDE_BACK && sides[i+1] == SIDE_FRONT) ) { + // generate a split point + p2 = &in->verts[i+1]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for ( j=0 ; j<3 ; j++ ) { + mid[j] = (*p1)[j] + dot*((*p2)[j]-(*p1)[j]); + } + + out->verts[out->numVerts] = mid; + + // set the edge flag + if ( sides[i+1] != SIDE_FRONT ) { + out->edgeFlags[out->numVerts] = 1; + } else { + out->edgeFlags[out->numVerts] = in->edgeFlags[i]; + } + + out->numVerts++; + } + } + + return inNum ^ 1; +} + +/* +=================== +R_ClipTriangleToLight + +Returns false if nothing is left after clipping +=================== +*/ +static bool R_ClipTriangleToLight( const idVec3 &a, const idVec3 &b, const idVec3 &c, int planeBits, + const idPlane frustum[6] ) { + int i; + int base; + clipTri_t pingPong[2], *ct; + int p; + + pingPong[0].numVerts = 3; + pingPong[0].edgeFlags[0] = 0; + pingPong[0].edgeFlags[1] = 0; + pingPong[0].edgeFlags[2] = 0; + pingPong[0].verts[0] = a; + pingPong[0].verts[1] = b; + pingPong[0].verts[2] = c; + + p = 0; + for ( i = 0 ; i < 6 ; i++ ) { + if ( planeBits & ( 1 << i ) ) { + p = R_ChopWinding( pingPong, p, frustum[i] ); + if ( pingPong[p].numVerts < 1 ) { + return false; + } + } + } + ct = &pingPong[p]; + + // copy the clipped points out to shadowVerts + if ( numShadowVerts + ct->numVerts * 2 > MAX_SHADOW_VERTS ) { + overflowed = true; + return false; + } + + base = numShadowVerts; + for ( i = 0 ; i < ct->numVerts ; i++ ) { + shadowVerts[ base + i*2 ].ToVec3() = ct->verts[i]; + } + numShadowVerts += ct->numVerts * 2; + + if ( numShadowIndexes + 3 * ( ct->numVerts - 2 ) > MAX_SHADOW_INDEXES ) { + overflowed = true; + return false; + } + + for ( i = 2 ; i < ct->numVerts ; i++ ) { + shadowIndexes[numShadowIndexes++] = base + i * 2; + shadowIndexes[numShadowIndexes++] = base + ( i - 1 ) * 2; + shadowIndexes[numShadowIndexes++] = base; + } + + // any edges that were created by the clipping process will + // have a silhouette quad created for it, because it is one + // of the exterior bounds of the shadow volume + for ( i = 0 ; i < ct->numVerts ; i++ ) { + if ( ct->edgeFlags[i] ) { + if ( numClipSilEdges == MAX_CLIP_SIL_EDGES ) { + break; + } + clipSilEdges[ numClipSilEdges ][0] = base + i * 2; + if ( i == ct->numVerts - 1 ) { + clipSilEdges[ numClipSilEdges ][1] = base; + } else { + clipSilEdges[ numClipSilEdges ][1] = base + ( i + 1 ) * 2; + } + numClipSilEdges++; + } + } + + return true; +} + +/* +=================== +R_ClipLineToLight + +If neither point is clearly behind the clipping +plane, the edge will be passed unmodified. A sil edge that +is on a border plane must be drawn. + +If one point is clearly clipped by the plane and the +other point is on the plane, it will be completely removed. +=================== +*/ +static bool R_ClipLineToLight( const idVec3 &a, const idVec3 &b, const idPlane frustum[4], + idVec3 &p1, idVec3 &p2 ) { + float *clip; + int j; + float d1, d2; + float f; + + p1 = a; + p2 = b; + + // clip it + for ( j = 0 ; j < 6 ; j++ ) { + d1 = frustum[j].Distance( p1 ); + d2 = frustum[j].Distance( p2 ); + + // if both on or in front, not clipped to this plane + if ( d1 > -LIGHT_CLIP_EPSILON && d2 > -LIGHT_CLIP_EPSILON ) { + continue; + } + + // if one is behind and the other isn't clearly in front, the edge is clipped off + if ( d1 <= -LIGHT_CLIP_EPSILON && d2 < LIGHT_CLIP_EPSILON ) { + return false; + } + if ( d2 <= -LIGHT_CLIP_EPSILON && d1 < LIGHT_CLIP_EPSILON ) { + return false; + } + + // clip it, keeping the negative side + if ( d1 < 0 ) { + clip = p1.ToFloatPtr(); + } else { + clip = p2.ToFloatPtr(); + } + +#if 0 + if ( idMath::Fabs(d1 - d2) < 0.001 ) { + d2 = d1 - 0.1; + } +#endif + + f = d1 / ( d1 - d2 ); + clip[0] = p1[0] + f * ( p2[0] - p1[0] ); + clip[1] = p1[1] + f * ( p2[1] - p1[1] ); + clip[2] = p1[2] + f * ( p2[2] - p1[2] ); + } + + return true; // retain a fragment +} + + +/* +================== +R_AddClipSilEdges + +Add sil edges for each triangle clipped to the side of +the frustum. + +Only done for simple projected lights, not point lights. +================== +*/ +static void R_AddClipSilEdges( void ) { + int v1, v2; + int v1_back, v2_back; + int i; + + // don't allow it to overflow + if ( numShadowIndexes + numClipSilEdges * 6 > MAX_SHADOW_INDEXES ) { + overflowed = true; + return; + } + + for ( i = 0 ; i < numClipSilEdges ; i++ ) { + v1 = clipSilEdges[i][0]; + v2 = clipSilEdges[i][1]; + v1_back = v1 + 1; + v2_back = v2 + 1; + if ( PointsOrdered( shadowVerts[ v1 ].ToVec3(), shadowVerts[ v2 ].ToVec3() ) ) { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v1_back; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v2_back; + shadowIndexes[numShadowIndexes++] = v1_back; + } else { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v2_back; + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2_back; + shadowIndexes[numShadowIndexes++] = v1_back; + } + } +} + +/* +================= +R_AddSilEdges + +Add quads from the front points to the projected points +for each silhouette edge in the light +================= +*/ +static void R_AddSilEdges( const srfTriangles_t *tri, unsigned short *pointCull, const idPlane frustum[6] ) { + int v1, v2; + int i; + silEdge_t *sil; + int numPlanes; + + numPlanes = tri->numIndexes / 3; + + // add sil edges for any true silhouette boundaries on the surface + for ( i = 0 ; i < tri->numSilEdges ; i++ ) { + sil = tri->silEdges + i; + if ( sil->p1 < 0 || sil->p1 > numPlanes || sil->p2 < 0 || sil->p2 > numPlanes ) { + common->Error( "Bad sil planes" ); + } + + // an edge will be a silhouette edge if the face on one side + // casts a shadow, but the face on the other side doesn't. + // "casts a shadow" means that it has some surface in the projection, + // not just that it has the correct facing direction + // This will cause edges that are exactly on the frustum plane + // to be considered sil edges if the face inside casts a shadow. + if ( !( faceCastsShadow[ sil->p1 ] ^ faceCastsShadow[ sil->p2 ] ) ) { + continue; + } + + // if the edge is completely off the negative side of + // a frustum plane, don't add it at all. This can still + // happen even if the face is visible and casting a shadow + // if it is partially clipped + if ( EDGE_CULLED( sil->v1, sil->v2 ) ) { + continue; + } + + // see if the edge needs to be clipped + if ( EDGE_CLIPPED( sil->v1, sil->v2 ) ) { + if ( numShadowVerts + 4 > MAX_SHADOW_VERTS ) { + overflowed = true; + return; + } + v1 = numShadowVerts; + v2 = v1 + 2; + if ( !R_ClipLineToLight( tri->verts[ sil->v1 ].xyz, tri->verts[ sil->v2 ].xyz, + frustum, shadowVerts[v1].ToVec3(), shadowVerts[v2].ToVec3() ) ) { + continue; // clipped away + } + + numShadowVerts += 4; + } else { + // use the entire edge + v1 = remap[ sil->v1 ]; + v2 = remap[ sil->v2 ]; + if ( v1 < 0 || v2 < 0 ) { + common->Error( "R_AddSilEdges: bad remap[]" ); + } + } + + // don't overflow + if ( numShadowIndexes + 6 > MAX_SHADOW_INDEXES ) { + overflowed = true; + return; + } + + // we need to choose the correct way of triangulating the silhouette quad + // consistantly between any two points, no matter which order they are specified. + // If this wasn't done, slight rasterization cracks would show in the shadow + // volume when two sil edges were exactly coincident + if ( faceCastsShadow[ sil->p2 ] ) { + if ( PointsOrdered( shadowVerts[ v1 ].ToVec3(), shadowVerts[ v2 ].ToVec3() ) ) { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v1+1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v1+1; + shadowIndexes[numShadowIndexes++] = v2+1; + } else { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2+1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v1+1; + shadowIndexes[numShadowIndexes++] = v2+1; + } + } else { + if ( PointsOrdered( shadowVerts[ v1 ].ToVec3(), shadowVerts[ v2 ].ToVec3() ) ) { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v1+1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v2+1; + shadowIndexes[numShadowIndexes++] = v1+1; + } else { + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2; + shadowIndexes[numShadowIndexes++] = v2+1; + shadowIndexes[numShadowIndexes++] = v1; + shadowIndexes[numShadowIndexes++] = v2+1; + shadowIndexes[numShadowIndexes++] = v1+1; + } + } + } +} + +/* +================ +R_CalcPointCull + +Also inits the remap[] array to all -1 +================ +*/ +static void R_CalcPointCull( const srfTriangles_t *tri, const idPlane frustum[6], unsigned short *pointCull ) { + int i; + int frontBits; + float *planeSide; + byte *side1, *side2; + + SIMDProcessor->Memset( remap, -1, tri->numVerts * sizeof( remap[0] ) ); + + for ( frontBits = 0, i = 0; i < 6; i++ ) { + // get front bits for the whole surface + if ( tri->bounds.PlaneDistance( frustum[i] ) >= LIGHT_CLIP_EPSILON ) { + frontBits |= 1<<(i+6); + } + } + + // initialize point cull + for ( i = 0; i < tri->numVerts; i++ ) { + pointCull[i] = frontBits; + } + + // if the surface is not completely inside the light frustum + if ( frontBits == ( ( ( 1 << 6 ) - 1 ) ) << 6 ) { + return; + } + + planeSide = (float *) _alloca16( tri->numVerts * sizeof( float ) ); + side1 = (byte *) _alloca16( tri->numVerts * sizeof( byte ) ); + side2 = (byte *) _alloca16( tri->numVerts * sizeof( byte ) ); + SIMDProcessor->Memset( side1, 0, tri->numVerts * sizeof( byte ) ); + SIMDProcessor->Memset( side2, 0, tri->numVerts * sizeof( byte ) ); + + for ( i = 0; i < 6; i++ ) { + + if ( frontBits & (1<<(i+6)) ) { + continue; + } + + SIMDProcessor->Dot( planeSide, frustum[i], tri->verts, tri->numVerts ); + SIMDProcessor->CmpLT( side1, i, planeSide, LIGHT_CLIP_EPSILON, tri->numVerts ); + SIMDProcessor->CmpGT( side2, i, planeSide, -LIGHT_CLIP_EPSILON, tri->numVerts ); + } + for ( i = 0; i < tri->numVerts; i++ ) { + pointCull[i] |= side1[i] | (side2[i] << 6); + } +} + +/* +================= +R_CreateShadowVolumeInFrustum + +Adds new verts and indexes to the shadow volume. + +If the frustum completely defines the projected light, +makeClippedPlanes should be true, which will cause sil quads to +be added along all clipped edges. + +If the frustum is just part of a point light, clipped planes don't +need to be added. +================= +*/ +static void R_CreateShadowVolumeInFrustum( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, + const idRenderLightLocal *light, + const idVec3 lightOrigin, + const idPlane frustum[6], + const idPlane &farPlane, + bool makeClippedPlanes ) { + int i; + int numTris; + unsigned short *pointCull; + int numCapIndexes; + int firstShadowIndex; + int firstShadowVert; + int cullBits; + + pointCull = (unsigned short *)_alloca16( tri->numVerts * sizeof( pointCull[0] ) ); + + // test the vertexes for inside the light frustum, which will allow + // us to completely cull away some triangles from consideration. + R_CalcPointCull( tri, frustum, pointCull ); + + // this may not be the first frustum added to the volume + firstShadowIndex = numShadowIndexes; + firstShadowVert = numShadowVerts; + + // decide which triangles front shadow volumes, clipping as needed + numClipSilEdges = 0; + numTris = tri->numIndexes / 3; + for ( i = 0 ; i < numTris ; i++ ) { + int i1, i2, i3; + + faceCastsShadow[i] = 0; // until shown otherwise + + // if it isn't facing the right way, don't add it + // to the shadow volume + if ( globalFacing[i] ) { + continue; + } + + i1 = tri->silIndexes[ i*3 + 0 ]; + i2 = tri->silIndexes[ i*3 + 1 ]; + i3 = tri->silIndexes[ i*3 + 2 ]; + + // if all the verts are off one side of the frustum, + // don't add any of them + if ( TRIANGLE_CULLED( i1, i2, i3 ) ) { + continue; + } + + // make sure the verts that are not on the negative sides + // of the frustum are copied over. + // we need to get the original verts even from clipped triangles + // so the edges reference correctly, because an edge may be unclipped + // even when a triangle is clipped. + if ( numShadowVerts + 6 > MAX_SHADOW_VERTS ) { + overflowed = true; + return; + } + + if ( !POINT_CULLED(i1) && remap[i1] == -1 ) { + remap[i1] = numShadowVerts; + shadowVerts[ numShadowVerts ].ToVec3() = tri->verts[i1].xyz; + numShadowVerts+=2; + } + if ( !POINT_CULLED(i2) && remap[i2] == -1 ) { + remap[i2] = numShadowVerts; + shadowVerts[ numShadowVerts ].ToVec3() = tri->verts[i2].xyz; + numShadowVerts+=2; + } + if ( !POINT_CULLED(i3) && remap[i3] == -1 ) { + remap[i3] = numShadowVerts; + shadowVerts[ numShadowVerts ].ToVec3() = tri->verts[i3].xyz; + numShadowVerts+=2; + } + + // clip the triangle if any points are on the negative sides + if ( TRIANGLE_CLIPPED( i1, i2, i3 ) ) { + cullBits = ( ( pointCull[ i1 ] ^ 0xfc0 ) | ( pointCull[ i2 ] ^ 0xfc0 ) | ( pointCull[ i3 ] ^ 0xfc0 ) ) >> 6; + // this will also define clip edges that will become + // silhouette planes + if ( R_ClipTriangleToLight( tri->verts[i1].xyz, tri->verts[i2].xyz, + tri->verts[i3].xyz, cullBits, frustum ) ) { + faceCastsShadow[i] = 1; + } + } else { + // instead of overflowing or drawing a streamer shadow, don't draw a shadow at all + if ( numShadowIndexes + 3 > MAX_SHADOW_INDEXES ) { + overflowed = true; + return; + } + if ( remap[i1] == -1 || remap[i2] == -1 || remap[i3] == -1 ) { + common->Error( "R_CreateShadowVolumeInFrustum: bad remap[]" ); + } + shadowIndexes[numShadowIndexes++] = remap[i3]; + shadowIndexes[numShadowIndexes++] = remap[i2]; + shadowIndexes[numShadowIndexes++] = remap[i1]; + faceCastsShadow[i] = 1; + } + } + + // add indexes for the back caps, which will just be reversals of the + // front caps using the back vertexes + numCapIndexes = numShadowIndexes - firstShadowIndex; + + // if no faces have been defined for the shadow volume, + // there won't be anything at all + if ( numCapIndexes == 0 ) { + return; + } + + //--------------- off-line processing ------------------ + + // if we are running from dmap, perform the (very) expensive shadow optimizations + // to remove internal sil edges and optimize the caps + if ( callOptimizer ) { + optimizedShadow_t opt; + + // project all of the vertexes to the shadow plane, generating + // an equal number of back vertexes +// R_ProjectPointsToFarPlane( ent, light, farPlane, firstShadowVert, numShadowVerts ); + + opt = SuperOptimizeOccluders( shadowVerts, shadowIndexes + firstShadowIndex, numCapIndexes, farPlane, lightOrigin ); + + // pull off the non-optimized data + numShadowIndexes = firstShadowIndex; + numShadowVerts = firstShadowVert; + + // add the optimized data + if ( numShadowIndexes + opt.totalIndexes > MAX_SHADOW_INDEXES + || numShadowVerts + opt.numVerts > MAX_SHADOW_VERTS ) { + overflowed = true; + common->Printf( "WARNING: overflowed MAX_SHADOW tables, shadow discarded\n" ); + Mem_Free( opt.verts ); + Mem_Free( opt.indexes ); + return; + } + + for ( i = 0 ; i < opt.numVerts ; i++ ) { + shadowVerts[numShadowVerts+i][0] = opt.verts[i][0]; + shadowVerts[numShadowVerts+i][1] = opt.verts[i][1]; + shadowVerts[numShadowVerts+i][2] = opt.verts[i][2]; + shadowVerts[numShadowVerts+i][3] = 1; + } + for ( i = 0 ; i < opt.totalIndexes ; i++ ) { + int index = opt.indexes[i]; + if ( index < 0 || index > opt.numVerts ) { + common->Error( "optimized shadow index out of range" ); + } + shadowIndexes[numShadowIndexes+i] = index + numShadowVerts; + } + + numShadowVerts += opt.numVerts; + numShadowIndexes += opt.totalIndexes; + + // note the index distribution so we can sort all the caps after all the sils + indexRef[indexFrustumNumber].frontCapStart = firstShadowIndex; + indexRef[indexFrustumNumber].rearCapStart = firstShadowIndex+opt.numFrontCapIndexes; + indexRef[indexFrustumNumber].silStart = firstShadowIndex+opt.numFrontCapIndexes+opt.numRearCapIndexes; + indexRef[indexFrustumNumber].end = numShadowIndexes; + indexFrustumNumber++; + + Mem_Free( opt.verts ); + Mem_Free( opt.indexes ); + return; + } + + //--------------- real-time processing ------------------ + + // the dangling edge "face" is never considered to cast a shadow, + // so any face with dangling edges that casts a shadow will have + // it's dangling sil edge trigger a sil plane + faceCastsShadow[numTris] = 0; + + // instead of overflowing or drawing a streamer shadow, don't draw a shadow at all + // if we ran out of space + if ( numShadowIndexes + numCapIndexes > MAX_SHADOW_INDEXES ) { + overflowed = true; + return; + } + for ( i = 0 ; i < numCapIndexes ; i += 3 ) { + shadowIndexes[ numShadowIndexes + i + 0 ] = shadowIndexes[ firstShadowIndex + i + 2 ] + 1; + shadowIndexes[ numShadowIndexes + i + 1 ] = shadowIndexes[ firstShadowIndex + i + 1 ] + 1; + shadowIndexes[ numShadowIndexes + i + 2 ] = shadowIndexes[ firstShadowIndex + i + 0 ] + 1; + } + numShadowIndexes += numCapIndexes; + +c_caps += numCapIndexes * 2; + +int preSilIndexes = numShadowIndexes; + + // if any triangles were clipped, we will have a list of edges + // on the frustum which must now become sil edges + if ( makeClippedPlanes ) { + R_AddClipSilEdges(); + } + + // any edges that are a transition between a shadowing and + // non-shadowing triangle will cast a silhouette edge + R_AddSilEdges( tri, pointCull, frustum ); + +c_sils += numShadowIndexes - preSilIndexes; + + // project all of the vertexes to the shadow plane, generating + // an equal number of back vertexes + R_ProjectPointsToFarPlane( ent, light, farPlane, firstShadowVert, numShadowVerts ); + + // note the index distribution so we can sort all the caps after all the sils + indexRef[indexFrustumNumber].frontCapStart = firstShadowIndex; + indexRef[indexFrustumNumber].rearCapStart = firstShadowIndex+numCapIndexes; + indexRef[indexFrustumNumber].silStart = preSilIndexes; + indexRef[indexFrustumNumber].end = numShadowIndexes; + indexFrustumNumber++; +} + +/* +=================== +R_MakeShadowFrustums + +Called at definition derivation time +=================== +*/ +void R_MakeShadowFrustums( idRenderLightLocal *light ) { + int i, j; + + if ( light->parms.pointLight ) { +#if 0 + idVec3 adjustedRadius; + + // increase the light radius to cover any origin offsets. + // this will cause some shadows to extend out of the exact light + // volume, but is simpler than adjusting all the frustums + adjustedRadius[0] = light->parms.lightRadius[0] + idMath::Fabs( light->parms.lightCenter[0] ); + adjustedRadius[1] = light->parms.lightRadius[1] + idMath::Fabs( light->parms.lightCenter[1] ); + adjustedRadius[2] = light->parms.lightRadius[2] + idMath::Fabs( light->parms.lightCenter[2] ); + + light->numShadowFrustums = 0; + // a point light has to project against six planes + for ( i = 0 ; i < 6 ; i++ ) { + shadowFrustum_t *frust = &light->shadowFrustums[ light->numShadowFrustums ]; + + frust->numPlanes = 6; + frust->makeClippedPlanes = false; + for ( j = 0 ; j < 6 ; j++ ) { + idPlane &plane = frust->planes[j]; + plane[0] = pointLightFrustums[i][j][0] / adjustedRadius[0]; + plane[1] = pointLightFrustums[i][j][1] / adjustedRadius[1]; + plane[2] = pointLightFrustums[i][j][2] / adjustedRadius[2]; + plane.Normalize(); + plane[3] = -( plane.Normal() * light->globalLightOrigin ); + if ( j == 5 ) { + plane[3] += adjustedRadius[i>>1]; + } + } + + light->numShadowFrustums++; + } +#else + // exact projection,taking into account asymetric frustums when + // globalLightOrigin isn't centered + + static int faceCorners[6][4] = { + { 7, 5, 1, 3 }, // positive X side + { 4, 6, 2, 0 }, // negative X side + { 6, 7, 3, 2 }, // positive Y side + { 5, 4, 0, 1 }, // negative Y side + { 6, 4, 5, 7 }, // positive Z side + { 3, 1, 0, 2 } // negative Z side + }; + static int faceEdgeAdjacent[6][4] = { + { 4, 4, 2, 2 }, // positive X side + { 7, 7, 1, 1 }, // negative X side + { 5, 5, 0, 0 }, // positive Y side + { 6, 6, 3, 3 }, // negative Y side + { 0, 0, 3, 3 }, // positive Z side + { 5, 5, 6, 6 } // negative Z side + }; + + bool centerOutside = false; + + // if the light center of projection is outside the light bounds, + // we will need to build the planes a little differently + if ( fabs( light->parms.lightCenter[0] ) > light->parms.lightRadius[0] + || fabs( light->parms.lightCenter[1] ) > light->parms.lightRadius[1] + || fabs( light->parms.lightCenter[2] ) > light->parms.lightRadius[2] ) { + centerOutside = true; + } + + // make the corners + idVec3 corners[8]; + + for ( i = 0 ; i < 8 ; i++ ) { + idVec3 temp; + for ( j = 0 ; j < 3 ; j++ ) { + if ( i & ( 1 << j ) ) { + temp[j] = light->parms.lightRadius[j]; + } else { + temp[j] = -light->parms.lightRadius[j]; + } + } + + // transform to global space + corners[i] = light->parms.origin + light->parms.axis * temp; + } + + light->numShadowFrustums = 0; + for ( int side = 0 ; side < 6 ; side++ ) { + shadowFrustum_t *frust = &light->shadowFrustums[ light->numShadowFrustums ]; + idVec3 &p1 = corners[faceCorners[side][0]]; + idVec3 &p2 = corners[faceCorners[side][1]]; + idVec3 &p3 = corners[faceCorners[side][2]]; + idPlane backPlane; + + // plane will have positive side inward + backPlane.FromPoints( p1, p2, p3 ); + + // if center of projection is on the wrong side, skip + float d = backPlane.Distance( light->globalLightOrigin ); + if ( d < 0 ) { + continue; + } + + frust->numPlanes = 6; + frust->planes[5] = backPlane; + frust->planes[4] = backPlane; // we don't really need the extra plane + + // make planes with positive side facing inwards in light local coordinates + for ( int edge = 0 ; edge < 4 ; edge++ ) { + idVec3 &p1 = corners[faceCorners[side][edge]]; + idVec3 &p2 = corners[faceCorners[side][(edge+1)&3]]; + + // create a plane that goes through the center of projection + frust->planes[edge].FromPoints( p2, p1, light->globalLightOrigin ); + + // see if we should use an adjacent plane instead + if ( centerOutside ) { + idVec3 &p3 = corners[faceEdgeAdjacent[side][edge]]; + idPlane sidePlane; + + sidePlane.FromPoints( p2, p1, p3 ); + d = sidePlane.Distance( light->globalLightOrigin ); + if ( d < 0 ) { + // use this plane instead of the edged plane + frust->planes[edge] = sidePlane; + } + // we can't guarantee a neighbor, so add sill planes at edge + light->shadowFrustums[ light->numShadowFrustums ].makeClippedPlanes = true; + } + } + light->numShadowFrustums++; + } + +#endif + return; + } + + // projected light + + light->numShadowFrustums = 1; + shadowFrustum_t *frust = &light->shadowFrustums[ 0 ]; + + // flip and transform the frustum planes so the positive side faces + // inward in local coordinates + + // it is important to clip against even the near clip plane, because + // many projected lights that are faking area lights will have their + // origin behind solid surfaces. + for ( i = 0 ; i < 6 ; i++ ) { + idPlane &plane = frust->planes[i]; + + plane.SetNormal( -light->frustum[i].Normal() ); + plane.SetDist( -light->frustum[i].Dist() ); + } + + frust->numPlanes = 6; + + frust->makeClippedPlanes = true; + // projected lights don't have shared frustums, so any clipped edges + // right on the planes must have a sil plane created for them +} + +/* +================= +R_CreateShadowVolume + +The returned surface will have a valid bounds and radius for culling. + +Triangles are clipped to the light frustum before projecting. + +A single triangle can clip to as many as 7 vertexes, so +the worst case expansion is 2*(numindexes/3)*7 verts when counting both +the front and back caps, although it will usually only be a modest +increase in vertexes for closed modesl + +The worst case index count is much larger, when the 7 vertex clipped triangle +needs 15 indexes for the front, 15 for the back, and 42 (a quad on seven sides) +for the sides, for a total of 72 indexes from the original 3. Ouch. + +NULL may be returned if the surface doesn't create a shadow volume at all, +as with a single face that the light is behind. + +If an edge is within an epsilon of the border of the volume, it must be treated +as if it is clipped for triangles, generating a new sil edge, and act +as if it was culled for edges, because the sil edge will have been +generated by the triangle irregardless of if it actually was a sil edge. +================= +*/ +srfTriangles_t *R_CreateShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + shadowGen_t optimize, srfCullInfo_t &cullInfo ) { + int i, j; + idVec3 lightOrigin; + srfTriangles_t *newTri; + int capPlaneBits; + + if ( !r_shadows.GetBool() ) { + return NULL; + } + + if ( tri->numSilEdges == 0 || tri->numIndexes == 0 || tri->numVerts == 0 ) { + return NULL; + } + + if ( tri->numIndexes < 0 ) { + common->Error( "R_CreateShadowVolume: tri->numIndexes = %i", tri->numIndexes ); + } + + if ( tri->numVerts < 0 ) { + common->Error( "R_CreateShadowVolume: tri->numVerts = %i", tri->numVerts ); + } + + tr.pc.c_createShadowVolumes++; + + // use the fast infinite projection in dynamic situations, which + // trades somewhat more overdraw and no cap optimizations for + // a very simple generation process + if ( optimize == SG_DYNAMIC && r_useTurboShadow.GetBool() ) { + if ( tr.backEndRendererHasVertexPrograms && r_useShadowVertexProgram.GetBool() ) { + return R_CreateVertexProgramTurboShadowVolume( ent, tri, light, cullInfo ); + } else { + return R_CreateTurboShadowVolume( ent, tri, light, cullInfo ); + } + } + + R_CalcInteractionFacing( ent, tri, light, cullInfo ); + + int numFaces = tri->numIndexes / 3; + int allFront = 1; + for ( i = 0; i < numFaces && allFront; i++ ) { + allFront &= cullInfo.facing[i]; + } + if ( allFront ) { + // if no faces are the right direction, don't make a shadow at all + return NULL; + } + + // clear the shadow volume + numShadowIndexes = 0; + numShadowVerts = 0; + overflowed = false; + indexFrustumNumber = 0; + capPlaneBits = 0; + callOptimizer = (optimize == SG_OFFLINE); + + // the facing information will be the same for all six projections + // from a point light, as well as for any directed lights + globalFacing = cullInfo.facing; + faceCastsShadow = (byte *)_alloca16( tri->numIndexes / 3 + 1 ); // + 1 for fake dangling edge face + remap = (int *)_alloca16( tri->numVerts * sizeof( remap[0] ) ); + + R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, lightOrigin ); + + // run through all the shadow frustums, which is one for a projected light, + // and usually six for a point light, but point lights with centers outside + // the box may have less + for ( int frustumNum = 0 ; frustumNum < light->numShadowFrustums ; frustumNum++ ) { + const shadowFrustum_t *frust = &light->shadowFrustums[frustumNum]; + ALIGN16( idPlane frustum[6] ); + + // transform the planes into entity space + // we could share and reverse some of the planes between frustums for a minor + // speed increase + + // the cull test is redundant for a single shadow frustum projected light, because + // the surface has already been checked against the main light frustums + + for ( j = 0 ; j < frust->numPlanes ; j++ ) { + R_GlobalPlaneToLocal( ent->modelMatrix, frust->planes[j], frustum[j] ); + + // try to cull the entire surface against this frustum + float d = tri->bounds.PlaneDistance( frustum[j] ); + if ( d < -LIGHT_CLIP_EPSILON ) { + break; + } + } + if ( j != frust->numPlanes ) { + continue; + } + // we need to check all the triangles + int oldFrustumNumber = indexFrustumNumber; + + R_CreateShadowVolumeInFrustum( ent, tri, light, lightOrigin, frustum, frustum[5], frust->makeClippedPlanes ); + + // if we couldn't make a complete shadow volume, it is better to + // not draw one at all, avoiding streamer problems + if ( overflowed ) { + return NULL; + } + + if ( indexFrustumNumber != oldFrustumNumber ) { + // note that we have caps projected against this frustum, + // which may allow us to skip drawing the caps if all projected + // planes face away from the viewer and the viewer is outside the light volume + capPlaneBits |= 1< MAX_SHADOW_VERTS || numShadowIndexes > MAX_SHADOW_INDEXES ) { + common->FatalError( "Shadow volume exceeded allocation" ); + } + + // allocate a new surface for the shadow volume + newTri = R_AllocStaticTriSurf(); + + // we might consider setting this, but it would only help for + // large lights that are partially off screen + newTri->bounds.Clear(); + + // copy off the verts and indexes + newTri->numVerts = numShadowVerts; + newTri->numIndexes = numShadowIndexes; + + // the shadow verts will go into a main memory buffer as well as a vertex + // cache buffer, so they can be copied back if they are purged + R_AllocStaticTriSurfShadowVerts( newTri, newTri->numVerts ); + SIMDProcessor->Memcpy( newTri->shadowVertexes, shadowVerts, newTri->numVerts * sizeof( newTri->shadowVertexes[0] ) ); + + R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes ); + + if ( 1 /* sortCapIndexes */ ) { + newTri->shadowCapPlaneBits = capPlaneBits; + + // copy the sil indexes first + newTri->numShadowIndexesNoCaps = 0; + for ( i = 0 ; i < indexFrustumNumber ; i++ ) { + int c = indexRef[i].end - indexRef[i].silStart; + SIMDProcessor->Memcpy( newTri->indexes+newTri->numShadowIndexesNoCaps, + shadowIndexes+indexRef[i].silStart, c * sizeof( newTri->indexes[0] ) ); + newTri->numShadowIndexesNoCaps += c; + } + // copy rear cap indexes next + newTri->numShadowIndexesNoFrontCaps = newTri->numShadowIndexesNoCaps; + for ( i = 0 ; i < indexFrustumNumber ; i++ ) { + int c = indexRef[i].silStart - indexRef[i].rearCapStart; + SIMDProcessor->Memcpy( newTri->indexes+newTri->numShadowIndexesNoFrontCaps, + shadowIndexes+indexRef[i].rearCapStart, c * sizeof( newTri->indexes[0] ) ); + newTri->numShadowIndexesNoFrontCaps += c; + } + // copy front cap indexes last + newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps; + for ( i = 0 ; i < indexFrustumNumber ; i++ ) { + int c = indexRef[i].rearCapStart - indexRef[i].frontCapStart; + SIMDProcessor->Memcpy( newTri->indexes+newTri->numIndexes, + shadowIndexes+indexRef[i].frontCapStart, c * sizeof( newTri->indexes[0] ) ); + newTri->numIndexes += c; + } + + } else { + newTri->shadowCapPlaneBits = 63; // we don't have optimized index lists + SIMDProcessor->Memcpy( newTri->indexes, shadowIndexes, newTri->numIndexes * sizeof( newTri->indexes[0] ) ); + } + + if ( optimize == SG_OFFLINE ) { + CleanupOptimizedShadowTris( newTri ); + } + + return newTri; +} diff --git a/renderer/tr_subview.cpp b/renderer/tr_subview.cpp new file mode 100644 index 000000000..ae6cb8852 --- /dev/null +++ b/renderer/tr_subview.cpp @@ -0,0 +1,569 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + + +typedef struct { + idVec3 origin; + idMat3 axis; +} orientation_t; + + +/* +================= +R_MirrorPoint +================= +*/ +static void R_MirrorPoint( const idVec3 in, orientation_t *surface, orientation_t *camera, idVec3 &out ) { + int i; + idVec3 local; + idVec3 transformed; + float d; + + local = in - surface->origin; + + transformed = vec3_origin; + for ( i = 0 ; i < 3 ; i++ ) { + d = local * surface->axis[i]; + transformed += d * camera->axis[i]; + } + + out = transformed + camera->origin; +} + +/* +================= +R_MirrorVector +================= +*/ +static void R_MirrorVector( const idVec3 in, orientation_t *surface, orientation_t *camera, idVec3 &out ) { + int i; + float d; + + out = vec3_origin; + for ( i = 0 ; i < 3 ; i++ ) { + d = in * surface->axis[i]; + out += d * camera->axis[i]; + } +} + +/* +============= +R_PlaneForSurface + +Returns the plane for the first triangle in the surface +FIXME: check for degenerate triangle? +============= +*/ +static void R_PlaneForSurface( const srfTriangles_t *tri, idPlane &plane ) { + idDrawVert *v1, *v2, *v3; + + v1 = tri->verts + tri->indexes[0]; + v2 = tri->verts + tri->indexes[1]; + v3 = tri->verts + tri->indexes[2]; + plane.FromPoints( v1->xyz, v2->xyz, v3->xyz ); +} + +/* +========================= +R_PreciseCullSurface + +Check the surface for visibility on a per-triangle basis +for cases when it is going to be VERY expensive to draw (subviews) + +If not culled, also returns the bounding box of the surface in +Normalized Device Coordinates, so it can be used to crop the scissor rect. + +OPTIMIZE: we could also take exact portal passing into consideration +========================= +*/ +bool R_PreciseCullSurface( const drawSurf_t *drawSurf, idBounds &ndcBounds ) { + const srfTriangles_t *tri; + int numTriangles; + idPlane clip, eye; + int i, j; + unsigned int pointOr; + unsigned int pointAnd; + idVec3 localView; + idFixedWinding w; + + tri = drawSurf->geo; + + pointOr = 0; + pointAnd = (unsigned int)~0; + + // get an exact bounds of the triangles for scissor cropping + ndcBounds.Clear(); + + for ( i = 0; i < tri->numVerts; i++ ) { + int j; + unsigned int pointFlags; + + R_TransformModelToClip( tri->verts[i].xyz, drawSurf->space->modelViewMatrix, + tr.viewDef->projectionMatrix, eye, clip ); + + pointFlags = 0; + for ( j = 0; j < 3; j++ ) { + if ( clip[j] >= clip[3] ) { + pointFlags |= (1 << (j*2)); + } else if ( clip[j] <= -clip[3] ) { + pointFlags |= ( 1 << (j*2+1)); + } + } + + pointAnd &= pointFlags; + pointOr |= pointFlags; + } + + // trivially reject + if ( pointAnd ) { + return true; + } + + // backface and frustum cull + numTriangles = tri->numIndexes / 3; + + R_GlobalPointToLocal( drawSurf->space->modelMatrix, tr.viewDef->renderView.vieworg, localView ); + + for ( i = 0; i < tri->numIndexes; i += 3 ) { + idVec3 dir, normal; + float dot; + idVec3 d1, d2; + + const idVec3 &v1 = tri->verts[tri->indexes[i]].xyz; + const idVec3 &v2 = tri->verts[tri->indexes[i+1]].xyz; + const idVec3 &v3 = tri->verts[tri->indexes[i+2]].xyz; + + // this is a hack, because R_GlobalPointToLocal doesn't work with the non-normalized + // axis that we get from the gui view transform. It doesn't hurt anything, because + // we know that all gui generated surfaces are front facing + if ( tr.guiRecursionLevel == 0 ) { + // we don't care that it isn't normalized, + // all we want is the sign + d1 = v2 - v1; + d2 = v3 - v1; + normal = d2.Cross( d1 ); + + dir = v1 - localView; + + dot = normal * dir; + if ( dot >= 0.0f ) { + return true; + } + } + + // now find the exact screen bounds of the clipped triangle + w.SetNumPoints( 3 ); + R_LocalPointToGlobal( drawSurf->space->modelMatrix, v1, w[0].ToVec3() ); + R_LocalPointToGlobal( drawSurf->space->modelMatrix, v2, w[1].ToVec3() ); + R_LocalPointToGlobal( drawSurf->space->modelMatrix, v3, w[2].ToVec3() ); + w[0].s = w[0].t = w[1].s = w[1].t = w[2].s = w[2].t = 0.0f; + + for ( j = 0; j < 4; j++ ) { + if ( !w.ClipInPlace( -tr.viewDef->frustum[j], 0.1f ) ) { + break; + } + } + for ( j = 0; j < w.GetNumPoints(); j++ ) { + idVec3 screen; + + R_GlobalToNormalizedDeviceCoordinates( w[j].ToVec3(), screen ); + ndcBounds.AddPoint( screen ); + } + } + + // if we don't enclose any area, return + if ( ndcBounds.IsCleared() ) { + return true; + } + + return false; +} + +/* +======================== +R_MirrorViewBySurface +======================== +*/ +static viewDef_t *R_MirrorViewBySurface( drawSurf_t *drawSurf ) { + viewDef_t *parms; + orientation_t surface, camera; + idPlane originalPlane, plane; + + // copy the viewport size from the original + parms = (viewDef_t *)R_FrameAlloc( sizeof( *parms ) ); + *parms = *tr.viewDef; + parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons + + parms->isSubview = true; + parms->isMirror = true; + + // create plane axis for the portal we are seeing + R_PlaneForSurface( drawSurf->geo, originalPlane ); + R_LocalPlaneToGlobal( drawSurf->space->modelMatrix, originalPlane, plane ); + + surface.origin = plane.Normal() * -plane[3]; + surface.axis[0] = plane.Normal(); + surface.axis[0].NormalVectors( surface.axis[1], surface.axis[2] ); + surface.axis[2] = -surface.axis[2]; + + camera.origin = surface.origin; + camera.axis[0] = -surface.axis[0]; + camera.axis[1] = surface.axis[1]; + camera.axis[2] = surface.axis[2]; + + // set the mirrored origin and axis + R_MirrorPoint( tr.viewDef->renderView.vieworg, &surface, &camera, parms->renderView.vieworg ); + + R_MirrorVector( tr.viewDef->renderView.viewaxis[0], &surface, &camera, parms->renderView.viewaxis[0] ); + R_MirrorVector( tr.viewDef->renderView.viewaxis[1], &surface, &camera, parms->renderView.viewaxis[1] ); + R_MirrorVector( tr.viewDef->renderView.viewaxis[2], &surface, &camera, parms->renderView.viewaxis[2] ); + + // make the view origin 16 units away from the center of the surface + idVec3 viewOrigin = ( drawSurf->geo->bounds[0] + drawSurf->geo->bounds[1] ) * 0.5; + viewOrigin += ( originalPlane.Normal() * 16 ); + + R_LocalPointToGlobal( drawSurf->space->modelMatrix, viewOrigin, parms->initialViewAreaOrigin ); + + // set the mirror clip plane + parms->numClipPlanes = 1; + parms->clipPlanes[0] = -camera.axis[0]; + + parms->clipPlanes[0][3] = -( camera.origin * parms->clipPlanes[0].Normal() ); + + return parms; +} + +/* +======================== +R_XrayViewBySurface +======================== +*/ +static viewDef_t *R_XrayViewBySurface( drawSurf_t *drawSurf ) { + viewDef_t *parms; + orientation_t surface, camera; + idPlane originalPlane, plane; + + // copy the viewport size from the original + parms = (viewDef_t *)R_FrameAlloc( sizeof( *parms ) ); + *parms = *tr.viewDef; + parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons + + parms->isSubview = true; + parms->isXraySubview = true; + + return parms; +} + +/* +=============== +R_RemoteRender +=============== +*/ +static void R_RemoteRender( drawSurf_t *surf, textureStage_t *stage ) { + viewDef_t *parms; + + // remote views can be reused in a single frame + if ( stage->dynamicFrameCount == tr.frameCount ) { + return; + } + + // if the entity doesn't have a remoteRenderView, do nothing + if ( !surf->space->entityDef->parms.remoteRenderView ) { + return; + } + + // copy the viewport size from the original + parms = (viewDef_t *)R_FrameAlloc( sizeof( *parms ) ); + *parms = *tr.viewDef; + + parms->isSubview = true; + parms->isMirror = false; + + parms->renderView = *surf->space->entityDef->parms.remoteRenderView; + parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons + parms->initialViewAreaOrigin = parms->renderView.vieworg; + + tr.CropRenderSize( stage->width, stage->height, true ); + + parms->renderView.x = 0; + parms->renderView.y = 0; + parms->renderView.width = SCREEN_WIDTH; + parms->renderView.height = SCREEN_HEIGHT; + + tr.RenderViewToViewport( &parms->renderView, &parms->viewport ); + + parms->scissor.x1 = 0; + parms->scissor.y1 = 0; + parms->scissor.x2 = parms->viewport.x2 - parms->viewport.x1; + parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1; + + parms->superView = tr.viewDef; + parms->subviewSurface = surf; + + // generate render commands for it + R_RenderView(parms); + + // copy this rendering to the image + stage->dynamicFrameCount = tr.frameCount; + if (!stage->image) { + stage->image = globalImages->scratchImage; + } + + tr.CaptureRenderToImage( stage->image->imgName ); + tr.UnCrop(); +} + +/* +================= +R_MirrorRender +================= +*/ +void R_MirrorRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect scissor ) { + viewDef_t *parms; + + // remote views can be reused in a single frame + if ( stage->dynamicFrameCount == tr.frameCount ) { + return; + } + + // issue a new view command + parms = R_MirrorViewBySurface( surf ); + if ( !parms ) { + return; + } + + tr.CropRenderSize( stage->width, stage->height, true ); + + parms->renderView.x = 0; + parms->renderView.y = 0; + parms->renderView.width = SCREEN_WIDTH; + parms->renderView.height = SCREEN_HEIGHT; + + tr.RenderViewToViewport( &parms->renderView, &parms->viewport ); + + parms->scissor.x1 = 0; + parms->scissor.y1 = 0; + parms->scissor.x2 = parms->viewport.x2 - parms->viewport.x1; + parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1; + + parms->superView = tr.viewDef; + parms->subviewSurface = surf; + + // triangle culling order changes with mirroring + parms->isMirror = ( ( (int)parms->isMirror ^ (int)tr.viewDef->isMirror ) != 0 ); + + // generate render commands for it + R_RenderView( parms ); + + // copy this rendering to the image + stage->dynamicFrameCount = tr.frameCount; + stage->image = globalImages->scratchImage; + + tr.CaptureRenderToImage( stage->image->imgName ); + tr.UnCrop(); +} + +/* +================= +R_XrayRender +================= +*/ +void R_XrayRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect scissor ) { + viewDef_t *parms; + + // remote views can be reused in a single frame + if ( stage->dynamicFrameCount == tr.frameCount ) { + return; + } + + // issue a new view command + parms = R_XrayViewBySurface( surf ); + if ( !parms ) { + return; + } + + tr.CropRenderSize( stage->width, stage->height, true ); + + parms->renderView.x = 0; + parms->renderView.y = 0; + parms->renderView.width = SCREEN_WIDTH; + parms->renderView.height = SCREEN_HEIGHT; + + tr.RenderViewToViewport( &parms->renderView, &parms->viewport ); + + parms->scissor.x1 = 0; + parms->scissor.y1 = 0; + parms->scissor.x2 = parms->viewport.x2 - parms->viewport.x1; + parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1; + + parms->superView = tr.viewDef; + parms->subviewSurface = surf; + + // triangle culling order changes with mirroring + parms->isMirror = ( ( (int)parms->isMirror ^ (int)tr.viewDef->isMirror ) != 0 ); + + // generate render commands for it + R_RenderView( parms ); + + // copy this rendering to the image + stage->dynamicFrameCount = tr.frameCount; + stage->image = globalImages->scratchImage2; + + tr.CaptureRenderToImage( stage->image->imgName ); + tr.UnCrop(); +} + +/* +================== +R_GenerateSurfaceSubview +================== +*/ +bool R_GenerateSurfaceSubview( drawSurf_t *drawSurf ) { + idBounds ndcBounds; + viewDef_t *parms; + const idMaterial *shader; + + // for testing the performance hit + if ( r_skipSubviews.GetBool() ) { + return false; + } + + if ( R_PreciseCullSurface( drawSurf, ndcBounds ) ) { + return false; + } + + shader = drawSurf->material; + + // never recurse through a subview surface that we are + // already seeing through + for ( parms = tr.viewDef ; parms ; parms = parms->superView ) { + if ( parms->subviewSurface + && parms->subviewSurface->geo == drawSurf->geo + && parms->subviewSurface->space->entityDef == drawSurf->space->entityDef ) { + break; + } + } + if ( parms ) { + return false; + } + + // crop the scissor bounds based on the precise cull + idScreenRect scissor; + + idScreenRect *v = &tr.viewDef->viewport; + scissor.x1 = v->x1 + (int)( (v->x2 - v->x1 + 1 ) * 0.5f * ( ndcBounds[0][0] + 1.0f )); + scissor.y1 = v->y1 + (int)( (v->y2 - v->y1 + 1 ) * 0.5f * ( ndcBounds[0][1] + 1.0f )); + scissor.x2 = v->x1 + (int)( (v->x2 - v->x1 + 1 ) * 0.5f * ( ndcBounds[1][0] + 1.0f )); + scissor.y2 = v->y1 + (int)( (v->y2 - v->y1 + 1 ) * 0.5f * ( ndcBounds[1][1] + 1.0f )); + + // nudge a bit for safety + scissor.Expand(); + + scissor.Intersect( tr.viewDef->scissor ); + + if ( scissor.IsEmpty() ) { + // cropped out + return false; + } + + // see what kind of subview we are making + if ( shader->GetSort() != SS_SUBVIEW ) { + for ( int i = 0 ; i < shader->GetNumStages() ; i++ ) { + const shaderStage_t *stage = shader->GetStage( i ); + switch ( stage->texture.dynamic ) { + case DI_REMOTE_RENDER: + R_RemoteRender( drawSurf, const_cast(&stage->texture) ); + break; + case DI_MIRROR_RENDER: + R_MirrorRender( drawSurf, const_cast(&stage->texture), scissor ); + break; + case DI_XRAY_RENDER: + R_XrayRender( drawSurf, const_cast(&stage->texture), scissor ); + break; + } + } + return true; + } + + // issue a new view command + parms = R_MirrorViewBySurface( drawSurf ); + if ( !parms ) { + return false; + } + + parms->scissor = scissor; + parms->superView = tr.viewDef; + parms->subviewSurface = drawSurf; + + // triangle culling order changes with mirroring + parms->isMirror = ( ( (int)parms->isMirror ^ (int)tr.viewDef->isMirror ) != 0 ); + + // generate render commands for it + R_RenderView( parms ); + + return true; +} + +/* +================ +R_GenerateSubViews + +If we need to render another view to complete the current view, +generate it first. + +It is important to do this after all drawSurfs for the current +view have been generated, because it may create a subview which +would change tr.viewCount. +================ +*/ +bool R_GenerateSubViews( void ) { + drawSurf_t *drawSurf; + int i; + bool subviews; + const idMaterial *shader; + + // for testing the performance hit + if ( r_skipSubviews.GetBool() ) { + return false; + } + + subviews = false; + + // scan the surfaces until we either find a subview, or determine + // there are no more subview surfaces. + for ( i = 0 ; i < tr.viewDef->numDrawSurfs ; i++ ) { + drawSurf = tr.viewDef->drawSurfs[i]; + shader = drawSurf->material; + + if ( !shader || !shader->HasSubview() ) { + continue; + } + + if ( R_GenerateSurfaceSubview( drawSurf ) ) { + subviews = true; + } + } + + return subviews; +} diff --git a/renderer/tr_trace.cpp b/renderer/tr_trace.cpp new file mode 100644 index 000000000..73f44aa67 --- /dev/null +++ b/renderer/tr_trace.cpp @@ -0,0 +1,418 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +//#define TEST_TRACE + +/* +================= +R_LocalTrace + +If we resort the vertexes so all silverts come first, we can save some work here. +================= +*/ +localTrace_t R_LocalTrace( const idVec3 &start, const idVec3 &end, const float radius, const srfTriangles_t *tri ) { + int i, j; + byte * cullBits; + idPlane planes[4]; + localTrace_t hit; + int c_testEdges, c_testPlanes, c_intersect; + idVec3 startDir; + byte totalOr; + float radiusSqr; + +#ifdef TEST_TRACE + idTimer trace_timer; + trace_timer.Start(); +#endif + + hit.fraction = 1.0f; + + // create two planes orthogonal to each other that intersect along the trace + startDir = end - start; + startDir.Normalize(); + startDir.NormalVectors( planes[0].Normal(), planes[1].Normal() ); + planes[0][3] = - start * planes[0].Normal(); + planes[1][3] = - start * planes[1].Normal(); + + // create front and end planes so the trace is on the positive sides of both + planes[2] = startDir; + planes[2][3] = - start * planes[2].Normal(); + planes[3] = -startDir; + planes[3][3] = - end * planes[3].Normal(); + + // catagorize each point against the four planes + cullBits = (byte *) _alloca16( tri->numVerts ); + SIMDProcessor->TracePointCull( cullBits, totalOr, radius, planes, tri->verts, tri->numVerts ); + + // if we don't have points on both sides of both the ray planes, no intersection + if ( ( totalOr ^ ( totalOr >> 4 ) ) & 3 ) { + //common->Printf( "nothing crossed the trace planes\n" ); + return hit; + } + + // if we don't have any points between front and end, no intersection + if ( ( totalOr ^ ( totalOr >> 1 ) ) & 4 ) { + //common->Printf( "trace didn't reach any triangles\n" ); + return hit; + } + + // scan for triangles that cross both planes + c_testPlanes = 0; + c_testEdges = 0; + c_intersect = 0; + + radiusSqr = Square( radius ); + startDir = end - start; + + if ( !tri->facePlanes || !tri->facePlanesCalculated ) { + R_DeriveFacePlanes( const_cast( tri ) ); + } + + for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) { + float d1, d2, f, d; + float edgeLengthSqr; + idPlane * plane; + idVec3 point; + idVec3 dir[3]; + idVec3 cross; + idVec3 edge; + byte triOr; + + // get sidedness info for the triangle + triOr = cullBits[ tri->indexes[i+0] ]; + triOr |= cullBits[ tri->indexes[i+1] ]; + triOr |= cullBits[ tri->indexes[i+2] ]; + + // if we don't have points on both sides of both the ray planes, no intersection + if ( ( triOr ^ ( triOr >> 4 ) ) & 3 ) { + continue; + } + + // if we don't have any points between front and end, no intersection + if ( ( triOr ^ ( triOr >> 1 ) ) & 4 ) { + continue; + } + + c_testPlanes++; + + plane = &tri->facePlanes[j]; + d1 = plane->Distance( start ); + d2 = plane->Distance( end ); + + if ( d1 <= d2 ) { + continue; // comning at it from behind or parallel + } + + if ( d1 < 0.0f ) { + continue; // starts past it + } + + if ( d2 > 0.0f ) { + continue; // finishes in front of it + } + + f = d1 / ( d1 - d2 ); + + if ( f < 0.0f ) { + continue; // shouldn't happen + } + + if ( f >= hit.fraction ) { + continue; // have already hit something closer + } + + c_testEdges++; + + // find the exact point of impact with the plane + point = start + f * startDir; + + // see if the point is within the three edges + // if radius > 0 the triangle is expanded with a circle in the triangle plane + + dir[0] = tri->verts[ tri->indexes[i+0] ].xyz - point; + dir[1] = tri->verts[ tri->indexes[i+1] ].xyz - point; + + cross = dir[0].Cross( dir[1] ); + d = plane->Normal() * cross; + if ( d > 0.0f ) { + if ( radiusSqr <= 0.0f ) { + continue; + } + edge = tri->verts[ tri->indexes[i+0] ].xyz - tri->verts[ tri->indexes[i+1] ].xyz; + edgeLengthSqr = edge.LengthSqr(); + if ( cross.LengthSqr() > edgeLengthSqr * radiusSqr ) { + continue; + } + d = edge * dir[0]; + if ( d < 0.0f ) { + edge = tri->verts[ tri->indexes[i+0] ].xyz - tri->verts[ tri->indexes[i+2] ].xyz; + d = edge * dir[0]; + if ( d < 0.0f ) { + if ( dir[0].LengthSqr() > radiusSqr ) { + continue; + } + } + } else if ( d > edgeLengthSqr ) { + edge = tri->verts[ tri->indexes[i+1] ].xyz - tri->verts[ tri->indexes[i+2] ].xyz; + d = edge * dir[1]; + if ( d < 0.0f ) { + if ( dir[1].LengthSqr() > radiusSqr ) { + continue; + } + } + } + } + + dir[2] = tri->verts[ tri->indexes[i+2] ].xyz - point; + + cross = dir[1].Cross( dir[2] ); + d = plane->Normal() * cross; + if ( d > 0.0f ) { + if ( radiusSqr <= 0.0f ) { + continue; + } + edge = tri->verts[ tri->indexes[i+1] ].xyz - tri->verts[ tri->indexes[i+2] ].xyz; + edgeLengthSqr = edge.LengthSqr(); + if ( cross.LengthSqr() > edgeLengthSqr * radiusSqr ) { + continue; + } + d = edge * dir[1]; + if ( d < 0.0f ) { + edge = tri->verts[ tri->indexes[i+1] ].xyz - tri->verts[ tri->indexes[i+0] ].xyz; + d = edge * dir[1]; + if ( d < 0.0f ) { + if ( dir[1].LengthSqr() > radiusSqr ) { + continue; + } + } + } else if ( d > edgeLengthSqr ) { + edge = tri->verts[ tri->indexes[i+2] ].xyz - tri->verts[ tri->indexes[i+0] ].xyz; + d = edge * dir[2]; + if ( d < 0.0f ) { + if ( dir[2].LengthSqr() > radiusSqr ) { + continue; + } + } + } + } + + cross = dir[2].Cross( dir[0] ); + d = plane->Normal() * cross; + if ( d > 0.0f ) { + if ( radiusSqr <= 0.0f ) { + continue; + } + edge = tri->verts[ tri->indexes[i+2] ].xyz - tri->verts[ tri->indexes[i+0] ].xyz; + edgeLengthSqr = edge.LengthSqr(); + if ( cross.LengthSqr() > edgeLengthSqr * radiusSqr ) { + continue; + } + d = edge * dir[2]; + if ( d < 0.0f ) { + edge = tri->verts[ tri->indexes[i+2] ].xyz - tri->verts[ tri->indexes[i+1] ].xyz; + d = edge * dir[2]; + if ( d < 0.0f ) { + if ( dir[2].LengthSqr() > radiusSqr ) { + continue; + } + } + } else if ( d > edgeLengthSqr ) { + edge = tri->verts[ tri->indexes[i+0] ].xyz - tri->verts[ tri->indexes[i+1] ].xyz; + d = edge * dir[0]; + if ( d < 0.0f ) { + if ( dir[0].LengthSqr() > radiusSqr ) { + continue; + } + } + } + } + + // we hit it + c_intersect++; + + hit.fraction = f; + hit.normal = plane->Normal(); + hit.point = point; + hit.indexes[0] = tri->indexes[i]; + hit.indexes[1] = tri->indexes[i+1]; + hit.indexes[2] = tri->indexes[i+2]; + } + + +#ifdef TEST_TRACE + trace_timer.Stop(); + common->Printf( "testVerts:%i c_testPlanes:%i c_testEdges:%i c_intersect:%i msec:%1.4f\n", + tri->numVerts, c_testPlanes, c_testEdges, c_intersect, trace_timer.Milliseconds() ); +#endif + + return hit; +} + +/* +================= +RB_DrawExpandedTriangles +================= +*/ +void RB_DrawExpandedTriangles( const srfTriangles_t *tri, const float radius, const idVec3 &vieworg ) { + int i, j, k; + idVec3 dir[6], normal, point; + + for ( i = 0; i < tri->numIndexes; i += 3 ) { + + idVec3 p[3] = { tri->verts[ tri->indexes[ i + 0 ] ].xyz, tri->verts[ tri->indexes[ i + 1 ] ].xyz, tri->verts[ tri->indexes[ i + 2 ] ].xyz }; + + dir[0] = p[0] - p[1]; + dir[1] = p[1] - p[2]; + dir[2] = p[2] - p[0]; + + normal = dir[0].Cross( dir[1] ); + + if ( normal * p[0] < normal * vieworg ) { + continue; + } + + dir[0] = normal.Cross( dir[0] ); + dir[1] = normal.Cross( dir[1] ); + dir[2] = normal.Cross( dir[2] ); + + dir[0].Normalize(); + dir[1].Normalize(); + dir[2].Normalize(); + + qglBegin( GL_LINE_LOOP ); + + for ( j = 0; j < 3; j++ ) { + k = ( j + 1 ) % 3; + + dir[4] = ( dir[j] + dir[k] ) * 0.5f; + dir[4].Normalize(); + + dir[3] = ( dir[j] + dir[4] ) * 0.5f; + dir[3].Normalize(); + + dir[5] = ( dir[4] + dir[k] ) * 0.5f; + dir[5].Normalize(); + + point = p[k] + dir[j] * radius; + qglVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[3] * radius; + qglVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[4] * radius; + qglVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[5] * radius; + qglVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[k] * radius; + qglVertex3f( point[0], point[1], point[2] ); + } + + qglEnd(); + } +} + +/* +================ +RB_ShowTrace + +Debug visualization +================ +*/ +void RB_ShowTrace( drawSurf_t **drawSurfs, int numDrawSurfs ) { + int i; + const srfTriangles_t *tri; + const drawSurf_t *surf; + idVec3 start, end; + idVec3 localStart, localEnd; + localTrace_t hit; + float radius; + + if ( r_showTrace.GetInteger() == 0 ) { + return; + } + + if ( r_showTrace.GetInteger() == 2 ) { + radius = 5.0f; + } else { + radius = 0.0f; + } + + // determine the points of the trace + start = backEnd.viewDef->renderView.vieworg; + end = start + 4000 * backEnd.viewDef->renderView.viewaxis[0]; + + // check and draw the surfaces + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + GL_TexEnv( GL_MODULATE ); + + globalImages->whiteImage->Bind(); + + // find how many are ambient + for ( i = 0 ; i < numDrawSurfs ; i++ ) { + surf = drawSurfs[i]; + tri = surf->geo; + + if ( tri == NULL || tri->verts == NULL ) { + continue; + } + + // transform the points into local space + R_GlobalPointToLocal( surf->space->modelMatrix, start, localStart ); + R_GlobalPointToLocal( surf->space->modelMatrix, end, localEnd ); + + // check the bounding box + if ( !tri->bounds.Expand( radius ).LineIntersection( localStart, localEnd ) ) { + continue; + } + + qglLoadMatrixf( surf->space->modelViewMatrix ); + + // highlight the surface + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + qglColor4f( 1, 0, 0, 0.25 ); + RB_DrawElementsImmediate( tri ); + + // draw the bounding box + GL_State( GLS_DEPTHFUNC_ALWAYS ); + + qglColor4f( 1, 1, 1, 1 ); + RB_DrawBounds( tri->bounds ); + + if ( radius != 0.0f ) { + // draw the expanded triangles + qglColor4f( 0.5f, 0.5f, 1.0f, 1.0f ); + RB_DrawExpandedTriangles( tri, radius, localStart ); + } + + // check the exact surfaces + hit = R_LocalTrace( localStart, localEnd, radius, tri ); + if ( hit.fraction < 1.0 ) { + qglColor4f( 1, 1, 1, 1 ); + RB_DrawBounds( idBounds( hit.point ).Expand( 1 ) ); + } + } +} diff --git a/renderer/tr_trisurf.cpp b/renderer/tr_trisurf.cpp new file mode 100644 index 000000000..3a51e29dc --- /dev/null +++ b/renderer/tr_trisurf.cpp @@ -0,0 +1,2265 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +/* +============================================================================== + +TRIANGLE MESH PROCESSING + +The functions in this file have no vertex / index count limits. + +Truly identical vertexes that match in position, normal, and texcoord can +be merged away. + +Vertexes that match in position and texcoord, but have distinct normals will +remain distinct for all purposes. This is usually a poor choice for models, +as adding a bevel face will not add any more vertexes, and will tend to +look better. + +Match in position and normal, but differ in texcoords are referenced together +for calculating tangent vectors for bump mapping. +Artists should take care to have identical texels in all maps (bump/diffuse/specular) +in this case + +Vertexes that only match in position are merged for shadow edge finding. + +Degenerate triangles. + +Overlapped triangles, even if normals or texcoords differ, must be removed. +for the silhoette based stencil shadow algorithm to function properly. +Is this true??? +Is the overlapped triangle problem just an example of the trippled edge problem? + +Interpenetrating triangles are not currently clipped to surfaces. +Do they effect the shadows? + +if vertexes are intended to deform apart, make sure that no vertexes +are on top of each other in the base frame, or the sil edges may be +calculated incorrectly. + +We might be able to identify this from topology. + +Dangling edges are acceptable, but three way edges are not. + +Are any combinations of two way edges unacceptable, like one facing +the backside of the other? + + +Topology is determined by a collection of triangle indexes. + +The edge list can be built up from this, and stays valid even under +deformations. + +Somewhat non-intuitively, concave edges cannot be optimized away, or the +stencil shadow algorithm miscounts. + +Face normals are needed for generating shadow volumes and for calculating +the silhouette, but they will change with any deformation. + +Vertex normals and vertex tangents will change with each deformation, +but they may be able to be transformed instead of recalculated. + +bounding volume, both box and sphere will change with deformation. + +silhouette indexes +shade indexes +texture indexes + + shade indexes will only be > silhouette indexes if there is facet shading present + + lookups from texture to sil and texture to shade? + +The normal and tangent vector smoothing is simple averaging, no attempt is +made to better handle the cases where the distribution around the shared vertex +is highly uneven. + + + we may get degenerate triangles even with the uniquing and removal + if the vertexes have different texcoords. + +============================================================================== +*/ + +// this shouldn't change anything, but previously renderbumped models seem to need it +#define USE_INVA + +// instead of using the texture T vector, cross the normal and S vector for an orthogonal axis +#define DERIVE_UNSMOOTHED_BITANGENT + +const int MAX_SIL_EDGES = 0x10000; +const int SILEDGE_HASH_SIZE = 1024; + +static int numSilEdges; +static silEdge_t * silEdges; +static idHashIndex silEdgeHash( SILEDGE_HASH_SIZE, MAX_SIL_EDGES ); +static int numPlanes; + +static idBlockAlloc srfTrianglesAllocator; + +#ifdef USE_TRI_DATA_ALLOCATOR +static idDynamicBlockAlloc triVertexAllocator; +static idDynamicBlockAlloc triIndexAllocator; +static idDynamicBlockAlloc triShadowVertexAllocator; +static idDynamicBlockAlloc triPlaneAllocator; +static idDynamicBlockAlloc triSilIndexAllocator; +static idDynamicBlockAlloc triSilEdgeAllocator; +static idDynamicBlockAlloc triDominantTrisAllocator; +static idDynamicBlockAlloc triMirroredVertAllocator; +static idDynamicBlockAlloc triDupVertAllocator; +#else +static idDynamicAlloc triVertexAllocator; +static idDynamicAlloc triIndexAllocator; +static idDynamicAlloc triShadowVertexAllocator; +static idDynamicAlloc triPlaneAllocator; +static idDynamicAlloc triSilIndexAllocator; +static idDynamicAlloc triSilEdgeAllocator; +static idDynamicAlloc triDominantTrisAllocator; +static idDynamicAlloc triMirroredVertAllocator; +static idDynamicAlloc triDupVertAllocator; +#endif + + +/* +=============== +R_InitTriSurfData +=============== +*/ +void R_InitTriSurfData( void ) { + silEdges = (silEdge_t *)R_StaticAlloc( MAX_SIL_EDGES * sizeof( silEdges[0] ) ); + + // initialize allocators for triangle surfaces + triVertexAllocator.Init(); + triIndexAllocator.Init(); + triShadowVertexAllocator.Init(); + triPlaneAllocator.Init(); + triSilIndexAllocator.Init(); + triSilEdgeAllocator.Init(); + triDominantTrisAllocator.Init(); + triMirroredVertAllocator.Init(); + triDupVertAllocator.Init(); + + // never swap out triangle surfaces + triVertexAllocator.SetLockMemory( true ); + triIndexAllocator.SetLockMemory( true ); + triShadowVertexAllocator.SetLockMemory( true ); + triPlaneAllocator.SetLockMemory( true ); + triSilIndexAllocator.SetLockMemory( true ); + triSilEdgeAllocator.SetLockMemory( true ); + triDominantTrisAllocator.SetLockMemory( true ); + triMirroredVertAllocator.SetLockMemory( true ); + triDupVertAllocator.SetLockMemory( true ); +} + +/* +=============== +R_ShutdownTriSurfData +=============== +*/ +void R_ShutdownTriSurfData( void ) { + R_StaticFree( silEdges ); + silEdgeHash.Free(); + srfTrianglesAllocator.Shutdown(); + triVertexAllocator.Shutdown(); + triIndexAllocator.Shutdown(); + triShadowVertexAllocator.Shutdown(); + triPlaneAllocator.Shutdown(); + triSilIndexAllocator.Shutdown(); + triSilEdgeAllocator.Shutdown(); + triDominantTrisAllocator.Shutdown(); + triMirroredVertAllocator.Shutdown(); + triDupVertAllocator.Shutdown(); +} + +/* +=============== +R_PurgeTriSurfData +=============== +*/ +void R_PurgeTriSurfData( frameData_t *frame ) { + // free deferred triangle surfaces + R_FreeDeferredTriSurfs( frame ); + + // free empty base blocks + triVertexAllocator.FreeEmptyBaseBlocks(); + triIndexAllocator.FreeEmptyBaseBlocks(); + triShadowVertexAllocator.FreeEmptyBaseBlocks(); + triPlaneAllocator.FreeEmptyBaseBlocks(); + triSilIndexAllocator.FreeEmptyBaseBlocks(); + triSilEdgeAllocator.FreeEmptyBaseBlocks(); + triDominantTrisAllocator.FreeEmptyBaseBlocks(); + triMirroredVertAllocator.FreeEmptyBaseBlocks(); + triDupVertAllocator.FreeEmptyBaseBlocks(); +} + +/* +=============== +R_ShowTriMemory_f +=============== +*/ +void R_ShowTriSurfMemory_f( const idCmdArgs &args ) { + common->Printf( "%6d kB in %d triangle surfaces\n", + ( srfTrianglesAllocator.GetAllocCount() * sizeof( srfTriangles_t ) ) >> 10, + srfTrianglesAllocator.GetAllocCount() ); + + common->Printf( "%6d kB vertex memory (%d kB free in %d blocks, %d empty base blocks)\n", + triVertexAllocator.GetBaseBlockMemory() >> 10, triVertexAllocator.GetFreeBlockMemory() >> 10, + triVertexAllocator.GetNumFreeBlocks(), triVertexAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB index memory (%d kB free in %d blocks, %d empty base blocks)\n", + triIndexAllocator.GetBaseBlockMemory() >> 10, triIndexAllocator.GetFreeBlockMemory() >> 10, + triIndexAllocator.GetNumFreeBlocks(), triIndexAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB shadow vert memory (%d kB free in %d blocks, %d empty base blocks)\n", + triShadowVertexAllocator.GetBaseBlockMemory() >> 10, triShadowVertexAllocator.GetFreeBlockMemory() >> 10, + triShadowVertexAllocator.GetNumFreeBlocks(), triShadowVertexAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB tri plane memory (%d kB free in %d blocks, %d empty base blocks)\n", + triPlaneAllocator.GetBaseBlockMemory() >> 10, triPlaneAllocator.GetFreeBlockMemory() >> 10, + triPlaneAllocator.GetNumFreeBlocks(), triPlaneAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB sil index memory (%d kB free in %d blocks, %d empty base blocks)\n", + triSilIndexAllocator.GetBaseBlockMemory() >> 10, triSilIndexAllocator.GetFreeBlockMemory() >> 10, + triSilIndexAllocator.GetNumFreeBlocks(), triSilIndexAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB sil edge memory (%d kB free in %d blocks, %d empty base blocks)\n", + triSilEdgeAllocator.GetBaseBlockMemory() >> 10, triSilEdgeAllocator.GetFreeBlockMemory() >> 10, + triSilEdgeAllocator.GetNumFreeBlocks(), triSilEdgeAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB dominant tri memory (%d kB free in %d blocks, %d empty base blocks)\n", + triDominantTrisAllocator.GetBaseBlockMemory() >> 10, triDominantTrisAllocator.GetFreeBlockMemory() >> 10, + triDominantTrisAllocator.GetNumFreeBlocks(), triDominantTrisAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB mirror vert memory (%d kB free in %d blocks, %d empty base blocks)\n", + triMirroredVertAllocator.GetBaseBlockMemory() >> 10, triMirroredVertAllocator.GetFreeBlockMemory() >> 10, + triMirroredVertAllocator.GetNumFreeBlocks(), triMirroredVertAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB dup vert memory (%d kB free in %d blocks, %d empty base blocks)\n", + triDupVertAllocator.GetBaseBlockMemory() >> 10, triDupVertAllocator.GetFreeBlockMemory() >> 10, + triDupVertAllocator.GetNumFreeBlocks(), triDupVertAllocator.GetNumEmptyBaseBlocks() ); + + common->Printf( "%6d kB total triangle memory\n", + ( srfTrianglesAllocator.GetAllocCount() * sizeof( srfTriangles_t ) + + triVertexAllocator.GetBaseBlockMemory() + + triIndexAllocator.GetBaseBlockMemory() + + triShadowVertexAllocator.GetBaseBlockMemory() + + triPlaneAllocator.GetBaseBlockMemory() + + triSilIndexAllocator.GetBaseBlockMemory() + + triSilEdgeAllocator.GetBaseBlockMemory() + + triDominantTrisAllocator.GetBaseBlockMemory() + + triMirroredVertAllocator.GetBaseBlockMemory() + + triDupVertAllocator.GetBaseBlockMemory() ) >> 10 ); +} + +/* +================= +R_TriSurfMemory + +For memory profiling +================= +*/ +int R_TriSurfMemory( const srfTriangles_t *tri ) { + int total = 0; + + if ( !tri ) { + return total; + } + + // used as a flag in interations + if ( tri == LIGHT_TRIS_DEFERRED ) { + return total; + } + + if ( tri->shadowVertexes != NULL ) { + total += tri->numVerts * sizeof( tri->shadowVertexes[0] ); + } else if ( tri->verts != NULL ) { + if ( tri->ambientSurface == NULL || tri->verts != tri->ambientSurface->verts ) { + total += tri->numVerts * sizeof( tri->verts[0] ); + } + } + if ( tri->facePlanes != NULL ) { + total += tri->numIndexes / 3 * sizeof( tri->facePlanes[0] ); + } + if ( tri->indexes != NULL ) { + if ( tri->ambientSurface == NULL || tri->indexes != tri->ambientSurface->indexes ) { + total += tri->numIndexes * sizeof( tri->indexes[0] ); + } + } + if ( tri->silIndexes != NULL ) { + total += tri->numIndexes * sizeof( tri->silIndexes[0] ); + } + if ( tri->silEdges != NULL ) { + total += tri->numSilEdges * sizeof( tri->silEdges[0] ); + } + if ( tri->dominantTris != NULL ) { + total += tri->numVerts * sizeof( tri->dominantTris[0] ); + } + if ( tri->mirroredVerts != NULL ) { + total += tri->numMirroredVerts * sizeof( tri->mirroredVerts[0] ); + } + if ( tri->dupVerts != NULL ) { + total += tri->numDupVerts * sizeof( tri->dupVerts[0] ); + } + + total += sizeof( *tri ); + + return total; +} + +/* +============== +R_FreeStaticTriSurfVertexCaches +============== +*/ +void R_FreeStaticTriSurfVertexCaches( srfTriangles_t *tri ) { + if ( tri->ambientSurface == NULL ) { + // this is a real model surface + vertexCache.Free( tri->ambientCache ); + tri->ambientCache = NULL; + } else { + // this is a light interaction surface that references + // a different ambient model surface + vertexCache.Free( tri->lightingCache ); + tri->lightingCache = NULL; + } + if ( tri->indexCache ) { + vertexCache.Free( tri->indexCache ); + tri->indexCache = NULL; + } + if ( tri->shadowCache && ( tri->shadowVertexes != NULL || tri->verts != NULL ) ) { + // if we don't have tri->shadowVertexes, these are a reference to a + // shadowCache on the original surface, which a vertex program + // will take care of making unique for each light + vertexCache.Free( tri->shadowCache ); + tri->shadowCache = NULL; + } +} + +/* +============== +R_ReallyFreeStaticTriSurf + +This does the actual free +============== +*/ +void R_ReallyFreeStaticTriSurf( srfTriangles_t *tri ) { + if ( !tri ) { + return; + } + + R_FreeStaticTriSurfVertexCaches( tri ); + + if ( tri->verts != NULL ) { + // R_CreateLightTris points tri->verts at the verts of the ambient surface + if ( tri->ambientSurface == NULL || tri->verts != tri->ambientSurface->verts ) { + triVertexAllocator.Free( tri->verts ); + } + } + + if ( !tri->deformedSurface ) { + if ( tri->indexes != NULL ) { + // if a surface is completely inside a light volume R_CreateLightTris points tri->indexes at the indexes of the ambient surface + if ( tri->ambientSurface == NULL || tri->indexes != tri->ambientSurface->indexes ) { + triIndexAllocator.Free( tri->indexes ); + } + } + if ( tri->silIndexes != NULL ) { + triSilIndexAllocator.Free( tri->silIndexes ); + } + if ( tri->silEdges != NULL ) { + triSilEdgeAllocator.Free( tri->silEdges ); + } + if ( tri->dominantTris != NULL ) { + triDominantTrisAllocator.Free( tri->dominantTris ); + } + if ( tri->mirroredVerts != NULL ) { + triMirroredVertAllocator.Free( tri->mirroredVerts ); + } + if ( tri->dupVerts != NULL ) { + triDupVertAllocator.Free( tri->dupVerts ); + } + } + + if ( tri->facePlanes != NULL ) { + triPlaneAllocator.Free( tri->facePlanes ); + } + + if ( tri->shadowVertexes != NULL ) { + triShadowVertexAllocator.Free( tri->shadowVertexes ); + } + +#ifdef _DEBUG + memset( tri, 0, sizeof( srfTriangles_t ) ); +#endif + + srfTrianglesAllocator.Free( tri ); +} + +/* +============== +R_CheckStaticTriSurfMemory +============== +*/ +void R_CheckStaticTriSurfMemory( const srfTriangles_t *tri ) { + if ( !tri ) { + return; + } + + if ( tri->verts != NULL ) { + // R_CreateLightTris points tri->verts at the verts of the ambient surface + if ( tri->ambientSurface == NULL || tri->verts != tri->ambientSurface->verts ) { + const char *error = triVertexAllocator.CheckMemory( tri->verts ); + assert( error == NULL ); + } + } + + if ( !tri->deformedSurface ) { + if ( tri->indexes != NULL ) { + // if a surface is completely inside a light volume R_CreateLightTris points tri->indexes at the indexes of the ambient surface + if ( tri->ambientSurface == NULL || tri->indexes != tri->ambientSurface->indexes ) { + const char *error = triIndexAllocator.CheckMemory( tri->indexes ); + assert( error == NULL ); + } + } + } + + if ( tri->shadowVertexes != NULL ) { + const char *error = triShadowVertexAllocator.CheckMemory( tri->shadowVertexes ); + assert( error == NULL ); + } +} + +/* +================== +R_FreeDeferredTriSurfs +================== +*/ +void R_FreeDeferredTriSurfs( frameData_t *frame ) { + srfTriangles_t *tri, *next; + + if ( !frame ) { + return; + } + + for ( tri = frame->firstDeferredFreeTriSurf; tri; tri = next ) { + next = tri->nextDeferredFree; + R_ReallyFreeStaticTriSurf( tri ); + } + + frame->firstDeferredFreeTriSurf = NULL; + frame->lastDeferredFreeTriSurf = NULL; +} + +/* +============== +R_FreeStaticTriSurf + +This will defer the free until the current frame has run through the back end. +============== +*/ +void R_FreeStaticTriSurf( srfTriangles_t *tri ) { + frameData_t *frame; + + if ( !tri ) { + return; + } + + if ( tri->nextDeferredFree ) { + common->Error( "R_FreeStaticTriSurf: freed a freed triangle" ); + } + frame = frameData; + + if ( !frame ) { + // command line utility, or rendering in editor preview mode ( force ) + R_ReallyFreeStaticTriSurf( tri ); + } else { +#ifdef ID_DEBUG_MEMORY + R_CheckStaticTriSurfMemory( tri ); +#endif + tri->nextDeferredFree = NULL; + if ( frame->lastDeferredFreeTriSurf ) { + frame->lastDeferredFreeTriSurf->nextDeferredFree = tri; + } else { + frame->firstDeferredFreeTriSurf = tri; + } + frame->lastDeferredFreeTriSurf = tri; + } +} + +/* +============== +R_AllocStaticTriSurf +============== +*/ +srfTriangles_t *R_AllocStaticTriSurf( void ) { + srfTriangles_t *tris = srfTrianglesAllocator.Alloc(); + memset( tris, 0, sizeof( srfTriangles_t ) ); + return tris; +} + +/* +================= +R_CopyStaticTriSurf + +This only duplicates the indexes and verts, not any of the derived data. +================= +*/ +srfTriangles_t *R_CopyStaticTriSurf( const srfTriangles_t *tri ) { + srfTriangles_t *newTri; + + newTri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( newTri, tri->numVerts ); + R_AllocStaticTriSurfIndexes( newTri, tri->numIndexes ); + newTri->numVerts = tri->numVerts; + newTri->numIndexes = tri->numIndexes; + memcpy( newTri->verts, tri->verts, tri->numVerts * sizeof( newTri->verts[0] ) ); + memcpy( newTri->indexes, tri->indexes, tri->numIndexes * sizeof( newTri->indexes[0] ) ); + + return newTri; +} + +/* +================= +R_AllocStaticTriSurfVerts +================= +*/ +void R_AllocStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ) { + assert( tri->verts == NULL ); + tri->verts = triVertexAllocator.Alloc( numVerts ); +} + +/* +================= +R_AllocStaticTriSurfIndexes +================= +*/ +void R_AllocStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ) { + assert( tri->indexes == NULL ); + tri->indexes = triIndexAllocator.Alloc( numIndexes ); +} + +/* +================= +R_AllocStaticTriSurfShadowVerts +================= +*/ +void R_AllocStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ) { + assert( tri->shadowVertexes == NULL ); + tri->shadowVertexes = triShadowVertexAllocator.Alloc( numVerts ); +} + +/* +================= +R_AllocStaticTriSurfPlanes +================= +*/ +void R_AllocStaticTriSurfPlanes( srfTriangles_t *tri, int numIndexes ) { + if ( tri->facePlanes ) { + triPlaneAllocator.Free( tri->facePlanes ); + } + tri->facePlanes = triPlaneAllocator.Alloc( numIndexes / 3 ); +} + +/* +================= +R_ResizeStaticTriSurfVerts +================= +*/ +void R_ResizeStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ) { +#ifdef USE_TRI_DATA_ALLOCATOR + tri->verts = triVertexAllocator.Resize( tri->verts, numVerts ); +#else + assert( false ); +#endif +} + +/* +================= +R_ResizeStaticTriSurfIndexes +================= +*/ +void R_ResizeStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ) { +#ifdef USE_TRI_DATA_ALLOCATOR + tri->indexes = triIndexAllocator.Resize( tri->indexes, numIndexes ); +#else + assert( false ); +#endif +} + +/* +================= +R_ResizeStaticTriSurfShadowVerts +================= +*/ +void R_ResizeStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ) { +#ifdef USE_TRI_DATA_ALLOCATOR + tri->shadowVertexes = triShadowVertexAllocator.Resize( tri->shadowVertexes, numVerts ); +#else + assert( false ); +#endif +} + +/* +================= +R_ReferenceStaticTriSurfVerts +================= +*/ +void R_ReferenceStaticTriSurfVerts( srfTriangles_t *tri, const srfTriangles_t *reference ) { + tri->verts = reference->verts; +} + +/* +================= +R_ReferenceStaticTriSurfIndexes +================= +*/ +void R_ReferenceStaticTriSurfIndexes( srfTriangles_t *tri, const srfTriangles_t *reference ) { + tri->indexes = reference->indexes; +} + +/* +================= +R_FreeStaticTriSurfSilIndexes +================= +*/ +void R_FreeStaticTriSurfSilIndexes( srfTriangles_t *tri ) { + triSilIndexAllocator.Free( tri->silIndexes ); + tri->silIndexes = NULL; +} + +/* +=============== +R_RangeCheckIndexes + +Check for syntactically incorrect indexes, like out of range values. +Does not check for semantics, like degenerate triangles. + +No vertexes is acceptable if no indexes. +No indexes is acceptable. +More vertexes than are referenced by indexes are acceptable. +=============== +*/ +void R_RangeCheckIndexes( const srfTriangles_t *tri ) { + int i; + + if ( tri->numIndexes < 0 ) { + common->Error( "R_RangeCheckIndexes: numIndexes < 0" ); + } + if ( tri->numVerts < 0 ) { + common->Error( "R_RangeCheckIndexes: numVerts < 0" ); + } + + // must specify an integral number of triangles + if ( tri->numIndexes % 3 != 0 ) { + common->Error( "R_RangeCheckIndexes: numIndexes %% 3" ); + } + + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + if ( tri->indexes[i] < 0 || tri->indexes[i] >= tri->numVerts ) { + common->Error( "R_RangeCheckIndexes: index out of range" ); + } + } + + // this should not be possible unless there are unused verts + if ( tri->numVerts > tri->numIndexes ) { + // FIXME: find the causes of these + // common->Printf( "R_RangeCheckIndexes: tri->numVerts > tri->numIndexes\n" ); + } +} + +/* +================= +R_BoundTriSurf +================= +*/ +void R_BoundTriSurf( srfTriangles_t *tri ) { + SIMDProcessor->MinMax( tri->bounds[0], tri->bounds[1], tri->verts, tri->numVerts ); +} + +/* +================= +R_CreateSilRemap +================= +*/ +static int *R_CreateSilRemap( const srfTriangles_t *tri ) { + int c_removed, c_unique; + int *remap; + int i, j, hashKey; + const idDrawVert *v1, *v2; + + remap = (int *)R_ClearedStaticAlloc( tri->numVerts * sizeof( remap[0] ) ); + + if ( !r_useSilRemap.GetBool() ) { + for ( i = 0 ; i < tri->numVerts ; i++ ) { + remap[i] = i; + } + return remap; + } + + idHashIndex hash( 1024, tri->numVerts ); + + c_removed = 0; + c_unique = 0; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + v1 = &tri->verts[i]; + + // see if there is an earlier vert that it can map to + hashKey = hash.GenerateKey( v1->xyz ); + for ( j = hash.First( hashKey ); j >= 0; j = hash.Next( j ) ) { + v2 = &tri->verts[j]; + if ( v2->xyz[0] == v1->xyz[0] + && v2->xyz[1] == v1->xyz[1] + && v2->xyz[2] == v1->xyz[2] ) { + c_removed++; + remap[i] = j; + break; + } + } + if ( j < 0 ) { + c_unique++; + remap[i] = i; + hash.Add( hashKey, i ); + } + } + + return remap; +} + +/* +================= +R_CreateSilIndexes + +Uniquing vertexes only on xyz before creating sil edges reduces +the edge count by about 20% on Q3 models +================= +*/ +void R_CreateSilIndexes( srfTriangles_t *tri ) { + int i; + int *remap; + + if ( tri->silIndexes ) { + triSilIndexAllocator.Free( tri->silIndexes ); + tri->silIndexes = NULL; + } + + remap = R_CreateSilRemap( tri ); + + // remap indexes to the first one + tri->silIndexes = triSilIndexAllocator.Alloc( tri->numIndexes ); + for ( i = 0; i < tri->numIndexes; i++ ) { + tri->silIndexes[i] = remap[tri->indexes[i]]; + } + + R_StaticFree( remap ); +} + +/* +===================== +R_CreateDupVerts +===================== +*/ +void R_CreateDupVerts( srfTriangles_t *tri ) { + int i; + + int *remap = (int *) _alloca16( tri->numVerts * sizeof( remap[0] ) ); + + // initialize vertex remap in case there are unused verts + for ( i = 0; i < tri->numVerts; i++ ) { + remap[i] = i; + } + + // set the remap based on how the silhouette indexes are remapped + for ( i = 0; i < tri->numIndexes; i++ ) { + remap[tri->indexes[i]] = tri->silIndexes[i]; + } + + // create duplicate vertex index based on the vertex remap + int * tempDupVerts = (int *) _alloca16( tri->numVerts * 2 * sizeof( tempDupVerts[0] ) ); + tri->numDupVerts = 0; + for ( i = 0; i < tri->numVerts; i++ ) { + if ( remap[i] != i ) { + tempDupVerts[tri->numDupVerts*2+0] = i; + tempDupVerts[tri->numDupVerts*2+1] = remap[i]; + tri->numDupVerts++; + } + } + + tri->dupVerts = triDupVertAllocator.Alloc( tri->numDupVerts * 2 ); + memcpy( tri->dupVerts, tempDupVerts, tri->numDupVerts * 2 * sizeof( tri->dupVerts[0] ) ); +} + +/* +===================== +R_DeriveFacePlanes + +Writes the facePlanes values, overwriting existing ones if present +===================== +*/ +void R_DeriveFacePlanes( srfTriangles_t *tri ) { + idPlane * planes; + + if ( !tri->facePlanes ) { + R_AllocStaticTriSurfPlanes( tri, tri->numIndexes ); + } + planes = tri->facePlanes; + +#if 1 + + SIMDProcessor->DeriveTriPlanes( planes, tri->verts, tri->numVerts, tri->indexes, tri->numIndexes ); + +#else + + for ( int i = 0; i < tri->numIndexes; i+= 3, planes++ ) { + int i1, i2, i3; + idVec3 d1, d2, normal; + idVec3 *v1, *v2, *v3; + + i1 = tri->indexes[i + 0]; + i2 = tri->indexes[i + 1]; + i3 = tri->indexes[i + 2]; + + v1 = &tri->verts[i1].xyz; + v2 = &tri->verts[i2].xyz; + v3 = &tri->verts[i3].xyz; + + d1[0] = v2->x - v1->x; + d1[1] = v2->y - v1->y; + d1[2] = v2->z - v1->z; + + d2[0] = v3->x - v1->x; + d2[1] = v3->y - v1->y; + d2[2] = v3->z - v1->z; + + normal[0] = d2.y * d1.z - d2.z * d1.y; + normal[1] = d2.z * d1.x - d2.x * d1.z; + normal[2] = d2.x * d1.y - d2.y * d1.x; + + float sqrLength, invLength; + + sqrLength = normal.x * normal.x + normal.y * normal.y + normal.z * normal.z; + invLength = idMath::RSqrt( sqrLength ); + + (*planes)[0] = normal[0] * invLength; + (*planes)[1] = normal[1] * invLength; + (*planes)[2] = normal[2] * invLength; + + planes->FitThroughPoint( *v1 ); + } + +#endif + + tri->facePlanesCalculated = true; +} + +/* +===================== +R_CreateVertexNormals + +Averages together the contributions of all faces that are +used by a vertex, creating drawVert->normal +===================== +*/ +void R_CreateVertexNormals( srfTriangles_t *tri ) { + int i, j; + const idPlane *planes; + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + tri->verts[i].normal.Zero(); + } + + if ( !tri->facePlanes || !tri->facePlanesCalculated ) { + R_DeriveFacePlanes( tri ); + } + if ( !tri->silIndexes ) { + R_CreateSilIndexes( tri ); + } + planes = tri->facePlanes; + for ( i = 0 ; i < tri->numIndexes ; i += 3, planes++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + int index = tri->silIndexes[i+j]; + tri->verts[index].normal += planes->Normal(); + } + } + + // normalize and replicate from silIndexes to all indexes + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + tri->verts[tri->indexes[i]].normal = tri->verts[tri->silIndexes[i]].normal; + tri->verts[tri->indexes[i]].normal.Normalize(); + } +} + +/* +=============== +R_DefineEdge +=============== +*/ +static int c_duplicatedEdges, c_tripledEdges; + +static void R_DefineEdge( int v1, int v2, int planeNum ) { + int i, hashKey; + + // check for degenerate edge + if ( v1 == v2 ) { + return; + } + hashKey = silEdgeHash.GenerateKey( v1, v2 ); + // search for a matching other side + for ( i = silEdgeHash.First( hashKey ); i >= 0 && i < MAX_SIL_EDGES; i = silEdgeHash.Next( i ) ) { + if ( silEdges[i].v1 == v1 && silEdges[i].v2 == v2 ) { + c_duplicatedEdges++; + // allow it to still create a new edge + continue; + } + if ( silEdges[i].v2 == v1 && silEdges[i].v1 == v2 ) { + if ( silEdges[i].p2 != numPlanes ) { + c_tripledEdges++; + // allow it to still create a new edge + continue; + } + // this is a matching back side + silEdges[i].p2 = planeNum; + return; + } + + } + + // define the new edge + if ( numSilEdges == MAX_SIL_EDGES ) { + common->DWarning( "MAX_SIL_EDGES" ); + return; + } + + silEdgeHash.Add( hashKey, numSilEdges ); + + silEdges[numSilEdges].p1 = planeNum; + silEdges[numSilEdges].p2 = numPlanes; + silEdges[numSilEdges].v1 = v1; + silEdges[numSilEdges].v2 = v2; + + numSilEdges++; +} + +/* +================= +SilEdgeSort +================= +*/ +static int SilEdgeSort( const void *a, const void *b ) { + if ( ((silEdge_t *)a)->p1 < ((silEdge_t *)b)->p1 ) { + return -1; + } + if ( ((silEdge_t *)a)->p1 > ((silEdge_t *)b)->p1 ) { + return 1; + } + if ( ((silEdge_t *)a)->p2 < ((silEdge_t *)b)->p2 ) { + return -1; + } + if ( ((silEdge_t *)a)->p2 > ((silEdge_t *)b)->p2 ) { + return 1; + } + return 0; +} + +/* +================= +R_IdentifySilEdges + +If the surface will not deform, coplanar edges (polygon interiors) +can never create silhouette plains, and can be omited +================= +*/ +int c_coplanarSilEdges; +int c_totalSilEdges; + +void R_IdentifySilEdges( srfTriangles_t *tri, bool omitCoplanarEdges ) { + int i; + int numTris; + int shared, single; + + omitCoplanarEdges = false; // optimization doesn't work for some reason + + numTris = tri->numIndexes / 3; + + numSilEdges = 0; + silEdgeHash.Clear(); + numPlanes = numTris; + + c_duplicatedEdges = 0; + c_tripledEdges = 0; + + for ( i = 0 ; i < numTris ; i++ ) { + int i1, i2, i3; + + i1 = tri->silIndexes[ i*3 + 0 ]; + i2 = tri->silIndexes[ i*3 + 1 ]; + i3 = tri->silIndexes[ i*3 + 2 ]; + + // create the edges + R_DefineEdge( i1, i2, i ); + R_DefineEdge( i2, i3, i ); + R_DefineEdge( i3, i1, i ); + } + + if ( c_duplicatedEdges || c_tripledEdges ) { + common->DWarning( "%i duplicated edge directions, %i tripled edges", c_duplicatedEdges, c_tripledEdges ); + } + + // if we know that the vertexes aren't going + // to deform, we can remove interior triangulation edges + // on otherwise planar polygons. + // I earlier believed that I could also remove concave + // edges, because they are never silhouettes in the conventional sense, + // but they are still needed to balance out all the true sil edges + // for the shadow algorithm to function + int c_coplanarCulled; + + c_coplanarCulled = 0; + if ( omitCoplanarEdges ) { + for ( i = 0 ; i < numSilEdges ; i++ ) { + int i1, i2, i3; + idPlane plane; + int base; + int j; + float d; + + if ( silEdges[i].p2 == numPlanes ) { // the fake dangling edge + continue; + } + + base = silEdges[i].p1 * 3; + i1 = tri->silIndexes[ base + 0 ]; + i2 = tri->silIndexes[ base + 1 ]; + i3 = tri->silIndexes[ base + 2 ]; + + plane.FromPoints( tri->verts[i1].xyz, tri->verts[i2].xyz, tri->verts[i3].xyz ); + + // check to see if points of second triangle are not coplanar + base = silEdges[i].p2 * 3; + for ( j = 0 ; j < 3 ; j++ ) { + i1 = tri->silIndexes[ base + j ]; + d = plane.Distance( tri->verts[i1].xyz ); + if ( d != 0 ) { // even a small epsilon causes problems + break; + } + } + + if ( j == 3 ) { + // we can cull this sil edge + memmove( &silEdges[i], &silEdges[i+1], (numSilEdges-i-1) * sizeof( silEdges[i] ) ); + c_coplanarCulled++; + numSilEdges--; + i--; + } + } + if ( c_coplanarCulled ) { + c_coplanarSilEdges += c_coplanarCulled; +// common->Printf( "%i of %i sil edges coplanar culled\n", c_coplanarCulled, +// c_coplanarCulled + numSilEdges ); + } + } + c_totalSilEdges += numSilEdges; + + // sort the sil edges based on plane number + qsort( silEdges, numSilEdges, sizeof( silEdges[0] ), SilEdgeSort ); + + // count up the distribution. + // a perfectly built model should only have shared + // edges, but most models will have some interpenetration + // and dangling edges + shared = 0; + single = 0; + for ( i = 0 ; i < numSilEdges ; i++ ) { + if ( silEdges[i].p2 == numPlanes ) { + single++; + } else { + shared++; + } + } + + if ( !single ) { + tri->perfectHull = true; + } else { + tri->perfectHull = false; + } + + tri->numSilEdges = numSilEdges; + tri->silEdges = triSilEdgeAllocator.Alloc( numSilEdges ); + memcpy( tri->silEdges, silEdges, numSilEdges * sizeof( tri->silEdges[0] ) ); +} + +/* +=============== +R_FaceNegativePolarity + +Returns true if the texture polarity of the face is negative, false if it is positive or zero +=============== +*/ +static bool R_FaceNegativePolarity( const srfTriangles_t *tri, int firstIndex ) { + idDrawVert *a, *b, *c; + float area; + float d0[5], d1[5]; + + a = tri->verts + tri->indexes[firstIndex + 0]; + b = tri->verts + tri->indexes[firstIndex + 1]; + c = tri->verts + tri->indexes[firstIndex + 2]; + + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + if ( area >= 0 ) { + return false; + } + return true; +} + +/* +================== +R_DeriveFaceTangents +================== +*/ +typedef struct { + idVec3 tangents[2]; + bool negativePolarity; + bool degenerate; +} faceTangents_t; + +static void R_DeriveFaceTangents( const srfTriangles_t *tri, faceTangents_t *faceTangents ) { + int i; + int c_textureDegenerateFaces; + int c_positive, c_negative; + faceTangents_t *ft; + idDrawVert *a, *b, *c; + + // + // calculate tangent vectors for each face in isolation + // + c_positive = 0; + c_negative = 0; + c_textureDegenerateFaces = 0; + for ( i = 0 ; i < tri->numIndexes ; i+=3 ) { + float area; + idVec3 temp; + float d0[5], d1[5]; + + ft = &faceTangents[i/3]; + + a = tri->verts + tri->indexes[i + 0]; + b = tri->verts + tri->indexes[i + 1]; + c = tri->verts + tri->indexes[i + 2]; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + if ( fabs( area ) < 1e-20f ) { + ft->negativePolarity = false; + ft->degenerate = true; + ft->tangents[0].Zero(); + ft->tangents[1].Zero(); + c_textureDegenerateFaces++; + continue; + } + if ( area > 0.0f ) { + ft->negativePolarity = false; + c_positive++; + } else { + ft->negativePolarity = true; + c_negative++; + } + ft->degenerate = false; + +#ifdef USE_INVA + float inva = area < 0.0f ? -1 : 1; // was = 1.0f / area; + + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva; + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva; + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva; + temp.Normalize(); + ft->tangents[0] = temp; + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva; + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva; + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva; + temp.Normalize(); + ft->tangents[1] = temp; +#else + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]); + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]); + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]); + temp.Normalize(); + ft->tangents[0] = temp; + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]); + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]); + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]); + temp.Normalize(); + ft->tangents[1] = temp; +#endif + } +} + + + +/* +=================== +R_DuplicateMirroredVertexes + +Modifies the surface to bust apart any verts that are shared by both positive and +negative texture polarities, so tangent space smoothing at the vertex doesn't +degenerate. + +This will create some identical vertexes (which will eventually get different tangent +vectors), so never optimize the resulting mesh, or it will get the mirrored edges back. + +Reallocates tri->verts and changes tri->indexes in place +Silindexes are unchanged by this. + +sets mirroredVerts and mirroredVerts[] + +=================== +*/ +typedef struct { + bool polarityUsed[2]; + int negativeRemap; +} tangentVert_t; + +static void R_DuplicateMirroredVertexes( srfTriangles_t *tri ) { + tangentVert_t *tverts, *vert; + int i, j; + int totalVerts; + int numMirror; + + tverts = (tangentVert_t *)_alloca16( tri->numVerts * sizeof( *tverts ) ); + memset( tverts, 0, tri->numVerts * sizeof( *tverts ) ); + + // determine texture polarity of each surface + + // mark each vert with the polarities it uses + for ( i = 0 ; i < tri->numIndexes ; i+=3 ) { + int polarity; + + polarity = R_FaceNegativePolarity( tri, i ); + for ( j = 0 ; j < 3 ; j++ ) { + tverts[tri->indexes[i+j]].polarityUsed[ polarity ] = true; + } + } + + // now create new verts as needed + totalVerts = tri->numVerts; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + vert = &tverts[i]; + if ( vert->polarityUsed[0] && vert->polarityUsed[1] ) { + vert->negativeRemap = totalVerts; + totalVerts++; + } + } + + tri->numMirroredVerts = totalVerts - tri->numVerts; + + // now create the new list + if ( totalVerts == tri->numVerts ) { + tri->mirroredVerts = NULL; + return; + } + + tri->mirroredVerts = triMirroredVertAllocator.Alloc( tri->numMirroredVerts ); + +#ifdef USE_TRI_DATA_ALLOCATOR + tri->verts = triVertexAllocator.Resize( tri->verts, totalVerts ); +#else + idDrawVert *oldVerts = tri->verts; + R_AllocStaticTriSurfVerts( tri, totalVerts ); + memcpy( tri->verts, oldVerts, tri->numVerts * sizeof( tri->verts[0] ) ); + triVertexAllocator.Free( oldVerts ); +#endif + + // create the duplicates + numMirror = 0; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + j = tverts[i].negativeRemap; + if ( j ) { + tri->verts[j] = tri->verts[i]; + tri->mirroredVerts[numMirror] = i; + numMirror++; + } + } + + tri->numVerts = totalVerts; + // change the indexes + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + if ( tverts[tri->indexes[i]].negativeRemap && + R_FaceNegativePolarity( tri, 3*(i/3) ) ) { + tri->indexes[i] = tverts[tri->indexes[i]].negativeRemap; + } + } + + tri->numVerts = totalVerts; +} + +/* +================= +R_DeriveTangentsWithoutNormals + +Build texture space tangents for bump mapping +If a surface is deformed, this must be recalculated + +This assumes that any mirrored vertexes have already been duplicated, so +any shared vertexes will have the tangent spaces smoothed across. + +Texture wrapping slightly complicates this, but as long as the normals +are shared, and the tangent vectors are projected onto the normals, the +separate vertexes should wind up with identical tangent spaces. + +mirroring a normalmap WILL cause a slightly visible seam unless the normals +are completely flat around the edge's full bilerp support. + +Vertexes which are smooth shaded must have their tangent vectors +in the same plane, which will allow a seamless +rendering as long as the normal map is even on both sides of the +seam. + +A smooth shaded surface may have multiple tangent vectors at a vertex +due to texture seams or mirroring, but it should only have a single +normal vector. + +Each triangle has a pair of tangent vectors in it's plane + +Should we consider having vertexes point at shared tangent spaces +to save space or speed transforms? + +this version only handles bilateral symetry +================= +*/ +void R_DeriveTangentsWithoutNormals( srfTriangles_t *tri ) { + int i, j; + faceTangents_t *faceTangents; + faceTangents_t *ft; + idDrawVert *vert; + + faceTangents = (faceTangents_t *)_alloca16( sizeof(faceTangents[0]) * tri->numIndexes/3 ); + R_DeriveFaceTangents( tri, faceTangents ); + + // clear the tangents + for ( i = 0 ; i < tri->numVerts ; i++ ) { + tri->verts[i].tangents[0].Zero(); + tri->verts[i].tangents[1].Zero(); + } + + // sum up the neighbors + for ( i = 0 ; i < tri->numIndexes ; i+=3 ) { + ft = &faceTangents[i/3]; + + // for each vertex on this face + for ( j = 0 ; j < 3 ; j++ ) { + vert = &tri->verts[tri->indexes[i+j]]; + + vert->tangents[0] += ft->tangents[0]; + vert->tangents[1] += ft->tangents[1]; + } + } + +#if 0 + // sum up both sides of the mirrored verts + // so the S vectors exactly mirror, and the T vectors are equal + for ( i = 0 ; i < tri->numMirroredVerts ; i++ ) { + idDrawVert *v1, *v2; + + v1 = &tri->verts[ tri->numVerts - tri->numMirroredVerts + i ]; + v2 = &tri->verts[ tri->mirroredVerts[i] ]; + + v1->tangents[0] -= v2->tangents[0]; + v1->tangents[1] += v2->tangents[1]; + + v2->tangents[0] = vec3_origin - v1->tangents[0]; + v2->tangents[1] = v1->tangents[1]; + } +#endif + + + // project the summed vectors onto the normal plane + // and normalize. The tangent vectors will not necessarily + // be orthogonal to each other, but they will be orthogonal + // to the surface normal. + for ( i = 0 ; i < tri->numVerts ; i++ ) { + vert = &tri->verts[i]; + for ( j = 0 ; j < 2 ; j++ ) { + float d; + + d = vert->tangents[j] * vert->normal; + vert->tangents[j] = vert->tangents[j] - d * vert->normal; + vert->tangents[j].Normalize(); + } + } + + tri->tangentsCalculated = true; +} + +static ID_INLINE void VectorNormalizeFast2( const idVec3 &v, idVec3 &out) { + float ilength; + + ilength = idMath::RSqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); + out[0] = v[0] * ilength; + out[1] = v[1] * ilength; + out[2] = v[2] * ilength; +} + +/* +=================== +R_BuildDominantTris + +Find the largest triangle that uses each vertex +=================== +*/ +typedef struct { + int vertexNum; + int faceNum; +} indexSort_t; + +static int IndexSort( const void *a, const void *b ) { + if ( ((indexSort_t *)a)->vertexNum < ((indexSort_t *)b)->vertexNum ) { + return -1; + } + if ( ((indexSort_t *)a)->vertexNum > ((indexSort_t *)b)->vertexNum ) { + return 1; + } + return 0; +} + +void R_BuildDominantTris( srfTriangles_t *tri ) { + int i, j; + dominantTri_t *dt; + indexSort_t *ind = (indexSort_t *)R_StaticAlloc( tri->numIndexes * sizeof( *ind ) ); + + for ( i = 0; i < tri->numIndexes; i++ ) { + ind[i].vertexNum = tri->indexes[i]; + ind[i].faceNum = i / 3; + } + qsort( ind, tri->numIndexes, sizeof( *ind ), IndexSort ); + + tri->dominantTris = dt = triDominantTrisAllocator.Alloc( tri->numVerts ); + memset( dt, 0, tri->numVerts * sizeof( dt[0] ) ); + + for ( i = 0; i < tri->numIndexes; i += j ) { + float maxArea = 0; + int vertNum = ind[i].vertexNum; + for ( j = 0; i + j < tri->numIndexes && ind[i+j].vertexNum == vertNum; j++ ) { + float d0[5], d1[5]; + idDrawVert *a, *b, *c; + idVec3 normal, tangent, bitangent; + + int i1 = tri->indexes[ind[i+j].faceNum * 3 + 0]; + int i2 = tri->indexes[ind[i+j].faceNum * 3 + 1]; + int i3 = tri->indexes[ind[i+j].faceNum * 3 + 2]; + + a = tri->verts + i1; + b = tri->verts + i2; + c = tri->verts + i3; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + normal[0] = ( d1[1] * d0[2] - d1[2] * d0[1] ); + normal[1] = ( d1[2] * d0[0] - d1[0] * d0[2] ); + normal[2] = ( d1[0] * d0[1] - d1[1] * d0[0] ); + + float area = normal.Length(); + + // if this is smaller than what we already have, skip it + if ( area < maxArea ) { + continue; + } + maxArea = area; + + if ( i1 == vertNum ) { + dt[vertNum].v2 = i2; + dt[vertNum].v3 = i3; + } else if ( i2 == vertNum ) { + dt[vertNum].v2 = i3; + dt[vertNum].v3 = i1; + } else { + dt[vertNum].v2 = i1; + dt[vertNum].v3 = i2; + } + + float len = area; + if ( len < 0.001f ) { + len = 0.001f; + } + dt[vertNum].normalizationScale[2] = 1.0f / len; // normal + + // texture area + area = d0[3] * d1[4] - d0[4] * d1[3]; + + tangent[0] = ( d0[0] * d1[4] - d0[4] * d1[0] ); + tangent[1] = ( d0[1] * d1[4] - d0[4] * d1[1] ); + tangent[2] = ( d0[2] * d1[4] - d0[4] * d1[2] ); + len = tangent.Length(); + if ( len < 0.001f ) { + len = 0.001f; + } + dt[vertNum].normalizationScale[0] = ( area > 0 ? 1 : -1 ) / len; // tangents[0] + + bitangent[0] = ( d0[3] * d1[0] - d0[0] * d1[3] ); + bitangent[1] = ( d0[3] * d1[1] - d0[1] * d1[3] ); + bitangent[2] = ( d0[3] * d1[2] - d0[2] * d1[3] ); + len = bitangent.Length(); + if ( len < 0.001f ) { + len = 0.001f; + } +#ifdef DERIVE_UNSMOOTHED_BITANGENT + dt[vertNum].normalizationScale[1] = ( area > 0 ? 1 : -1 ); +#else + dt[vertNum].normalizationScale[1] = ( area > 0 ? 1 : -1 ) / len; // tangents[1] +#endif + } + } + + R_StaticFree( ind ); +} + +/* +==================== +R_DeriveUnsmoothedTangents + +Uses the single largest area triangle for each vertex, instead of smoothing over all +==================== +*/ +void R_DeriveUnsmoothedTangents( srfTriangles_t *tri ) { + if ( tri->tangentsCalculated ) { + return; + } + +#if 1 + + SIMDProcessor->DeriveUnsmoothedTangents( tri->verts, tri->dominantTris, tri->numVerts ); + +#else + + for ( int i = 0 ; i < tri->numVerts ; i++ ) { + idVec3 temp; + float d0[5], d1[5]; + idDrawVert *a, *b, *c; + dominantTri_t *dt = &tri->dominantTris[i]; + + a = tri->verts + i; + b = tri->verts + dt->v2; + c = tri->verts + dt->v3; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + a->normal[0] = dt->normalizationScale[2] * ( d1[1] * d0[2] - d1[2] * d0[1] ); + a->normal[1] = dt->normalizationScale[2] * ( d1[2] * d0[0] - d1[0] * d0[2] ); + a->normal[2] = dt->normalizationScale[2] * ( d1[0] * d0[1] - d1[1] * d0[0] ); + + a->tangents[0][0] = dt->normalizationScale[0] * ( d0[0] * d1[4] - d0[4] * d1[0] ); + a->tangents[0][1] = dt->normalizationScale[0] * ( d0[1] * d1[4] - d0[4] * d1[1] ); + a->tangents[0][2] = dt->normalizationScale[0] * ( d0[2] * d1[4] - d0[4] * d1[2] ); + +#ifdef DERIVE_UNSMOOTHED_BITANGENT + // derive the bitangent for a completely orthogonal axis, + // instead of using the texture T vector + a->tangents[1][0] = dt->normalizationScale[1] * ( a->normal[2] * a->tangents[0][1] - a->normal[1] * a->tangents[0][2] ); + a->tangents[1][1] = dt->normalizationScale[1] * ( a->normal[0] * a->tangents[0][2] - a->normal[2] * a->tangents[0][0] ); + a->tangents[1][2] = dt->normalizationScale[1] * ( a->normal[1] * a->tangents[0][0] - a->normal[0] * a->tangents[0][1] ); +#else + // calculate the bitangent from the texture T vector + a->tangents[1][0] = dt->normalizationScale[1] * ( d0[3] * d1[0] - d0[0] * d1[3] ); + a->tangents[1][1] = dt->normalizationScale[1] * ( d0[3] * d1[1] - d0[1] * d1[3] ); + a->tangents[1][2] = dt->normalizationScale[1] * ( d0[3] * d1[2] - d0[2] * d1[3] ); +#endif + } + +#endif + + tri->tangentsCalculated = true; +} + +/* +================== +R_DeriveTangents + +This is called once for static surfaces, and every frame for deforming surfaces + +Builds tangents, normals, and face planes +================== +*/ +void R_DeriveTangents( srfTriangles_t *tri, bool allocFacePlanes ) { + int i; + idPlane *planes; + + if ( tri->dominantTris != NULL ) { + R_DeriveUnsmoothedTangents( tri ); + return; + } + + if ( tri->tangentsCalculated ) { + return; + } + + tr.pc.c_tangentIndexes += tri->numIndexes; + + if ( !tri->facePlanes && allocFacePlanes ) { + R_AllocStaticTriSurfPlanes( tri, tri->numIndexes ); + } + planes = tri->facePlanes; + +#if 1 + + if ( !planes ) { + planes = (idPlane *)_alloca16( ( tri->numIndexes / 3 ) * sizeof( planes[0] ) ); + } + + SIMDProcessor->DeriveTangents( planes, tri->verts, tri->numVerts, tri->indexes, tri->numIndexes ); + +#else + + for ( i = 0; i < tri->numVerts; i++ ) { + tri->verts[i].normal.Zero(); + tri->verts[i].tangents[0].Zero(); + tri->verts[i].tangents[1].Zero(); + } + + for ( i = 0; i < tri->numIndexes; i += 3 ) { + // make face tangents + float d0[5], d1[5]; + idDrawVert *a, *b, *c; + idVec3 temp, normal, tangents[2]; + + a = tri->verts + tri->indexes[i + 0]; + b = tri->verts + tri->indexes[i + 1]; + c = tri->verts + tri->indexes[i + 2]; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + // normal + temp[0] = d1[1] * d0[2] - d1[2] * d0[1]; + temp[1] = d1[2] * d0[0] - d1[0] * d0[2]; + temp[2] = d1[0] * d0[1] - d1[1] * d0[0]; + VectorNormalizeFast2( temp, normal ); + +#ifdef USE_INVA + float area = d0[3] * d1[4] - d0[4] * d1[3]; + float inva = area < 0.0f ? -1 : 1; // was = 1.0f / area; + + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva; + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva; + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva; + VectorNormalizeFast2( temp, tangents[0] ); + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva; + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva; + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva; + VectorNormalizeFast2( temp, tangents[1] ); +#else + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]); + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]); + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]); + VectorNormalizeFast2( temp, tangents[0] ); + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]); + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]); + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]); + VectorNormalizeFast2( temp, tangents[1] ); +#endif + + // sum up the tangents and normals for each vertex on this face + for ( int j = 0 ; j < 3 ; j++ ) { + vert = &tri->verts[tri->indexes[i+j]]; + vert->normal += normal; + vert->tangents[0] += tangents[0]; + vert->tangents[1] += tangents[1]; + } + + if ( planes ) { + planes->Normal() = normal; + planes->FitThroughPoint( a->xyz ); + planes++; + } + } + +#endif + +#if 0 + + if ( tri->silIndexes != NULL ) { + for ( i = 0; i < tri->numVerts; i++ ) { + tri->verts[i].normal.Zero(); + } + for ( i = 0; i < tri->numIndexes; i++ ) { + tri->verts[tri->silIndexes[i]].normal += planes[i/3].Normal(); + } + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + tri->verts[tri->indexes[i]].normal = tri->verts[tri->silIndexes[i]].normal; + } + } + +#else + + int *dupVerts = tri->dupVerts; + idDrawVert *verts = tri->verts; + + // add the normal of a duplicated vertex to the normal of the first vertex with the same XYZ + for ( i = 0; i < tri->numDupVerts; i++ ) { + verts[dupVerts[i*2+0]].normal += verts[dupVerts[i*2+1]].normal; + } + + // copy vertex normals to duplicated vertices + for ( i = 0; i < tri->numDupVerts; i++ ) { + verts[dupVerts[i*2+1]].normal = verts[dupVerts[i*2+0]].normal; + } + +#endif + +#if 0 + // sum up both sides of the mirrored verts + // so the S vectors exactly mirror, and the T vectors are equal + for ( i = 0 ; i < tri->numMirroredVerts ; i++ ) { + idDrawVert *v1, *v2; + + v1 = &tri->verts[ tri->numVerts - tri->numMirroredVerts + i ]; + v2 = &tri->verts[ tri->mirroredVerts[i] ]; + + v1->tangents[0] -= v2->tangents[0]; + v1->tangents[1] += v2->tangents[1]; + + v2->tangents[0] = vec3_origin - v1->tangents[0]; + v2->tangents[1] = v1->tangents[1]; + } +#endif + + // project the summed vectors onto the normal plane + // and normalize. The tangent vectors will not necessarily + // be orthogonal to each other, but they will be orthogonal + // to the surface normal. +#if 1 + + SIMDProcessor->NormalizeTangents( tri->verts, tri->numVerts ); + +#else + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + idDrawVert *vert = &tri->verts[i]; + + VectorNormalizeFast2( vert->normal, vert->normal ); + + // project the tangent vectors + for ( int j = 0 ; j < 2 ; j++ ) { + float d; + + d = vert->tangents[j] * vert->normal; + vert->tangents[j] = vert->tangents[j] - d * vert->normal; + VectorNormalizeFast2( vert->tangents[j], vert->tangents[j] ); + } + } + +#endif + + tri->tangentsCalculated = true; + tri->facePlanesCalculated = true; +} + +/* +================= +R_RemoveDuplicatedTriangles + +silIndexes must have already been calculated + +silIndexes are used instead of indexes, because duplicated +triangles could have different texture coordinates. +================= +*/ +void R_RemoveDuplicatedTriangles( srfTriangles_t *tri ) { + int c_removed; + int i, j, r; + int a, b, c; + + c_removed = 0; + + // check for completely duplicated triangles + // any rotation of the triangle is still the same, but a mirroring + // is considered different + for ( i = 0 ; i < tri->numIndexes ; i+=3 ) { + for ( r = 0 ; r < 3 ; r++ ) { + a = tri->silIndexes[i+r]; + b = tri->silIndexes[i+(r+1)%3]; + c = tri->silIndexes[i+(r+2)%3]; + for ( j = i + 3 ; j < tri->numIndexes ; j+=3 ) { + if ( tri->silIndexes[j] == a && tri->silIndexes[j+1] == b && tri->silIndexes[j+2] == c ) { + c_removed++; + memmove( tri->indexes + j, tri->indexes + j + 3, ( tri->numIndexes - j - 3 ) * sizeof( tri->indexes[0] ) ); + memmove( tri->silIndexes + j, tri->silIndexes + j + 3, ( tri->numIndexes - j - 3 ) * sizeof( tri->silIndexes[0] ) ); + tri->numIndexes -= 3; + j -= 3; + } + } + } + } + + if ( c_removed ) { + common->Printf( "removed %i duplicated triangles\n", c_removed ); + } + +} + +/* +================= +R_RemoveDegenerateTriangles + +silIndexes must have already been calculated +================= +*/ +void R_RemoveDegenerateTriangles( srfTriangles_t *tri ) { + int c_removed; + int i; + int a, b, c; + + // check for completely degenerate triangles + c_removed = 0; + for ( i = 0; i < tri->numIndexes; i += 3 ) { + a = tri->silIndexes[i]; + b = tri->silIndexes[i+1]; + c = tri->silIndexes[i+2]; + if ( a == b || a == c || b == c ) { + c_removed++; + memmove( tri->indexes + i, tri->indexes + i + 3, ( tri->numIndexes - i - 3 ) * sizeof( tri->indexes[0] ) ); + if ( tri->silIndexes ) { + memmove( tri->silIndexes + i, tri->silIndexes + i + 3, ( tri->numIndexes - i - 3 ) * sizeof( tri->silIndexes[0] ) ); + } + tri->numIndexes -= 3; + i -= 3; + } + } + + // this doesn't free the memory used by the unused verts + + if ( c_removed ) { + common->Printf( "removed %i degenerate triangles\n", c_removed ); + } +} + +/* +================= +R_TestDegenerateTextureSpace +================= +*/ +void R_TestDegenerateTextureSpace( srfTriangles_t *tri ) { + int c_degenerate; + int i; + + // check for triangles with a degenerate texture space + c_degenerate = 0; + for ( i = 0; i < tri->numIndexes; i += 3 ) { + const idDrawVert &a = tri->verts[tri->indexes[i+0]]; + const idDrawVert &b = tri->verts[tri->indexes[i+1]]; + const idDrawVert &c = tri->verts[tri->indexes[i+2]]; + + if ( a.st == b.st || b.st == c.st || c.st == a.st ) { + c_degenerate++; + } + } + + if ( c_degenerate ) { +// common->Printf( "%d triangles with a degenerate texture space\n", c_degenerate ); + } +} + +/* +================= +R_RemoveUnusedVerts +================= +*/ +void R_RemoveUnusedVerts( srfTriangles_t *tri ) { + int i; + int *mark; + int index; + int used; + + mark = (int *)R_ClearedStaticAlloc( tri->numVerts * sizeof( *mark ) ); + + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + index = tri->indexes[i]; + if ( index < 0 || index >= tri->numVerts ) { + common->Error( "R_RemoveUnusedVerts: bad index" ); + } + mark[ index ] = 1; + + if ( tri->silIndexes ) { + index = tri->silIndexes[i]; + if ( index < 0 || index >= tri->numVerts ) { + common->Error( "R_RemoveUnusedVerts: bad index" ); + } + mark[ index ] = 1; + } + } + + used = 0; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + if ( !mark[i] ) { + continue; + } + mark[i] = used + 1; + used++; + } + + if ( used != tri->numVerts ) { + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + tri->indexes[i] = mark[ tri->indexes[i] ] - 1; + if ( tri->silIndexes ) { + tri->silIndexes[i] = mark[ tri->silIndexes[i] ] - 1; + } + } + tri->numVerts = used; + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + index = mark[ i ]; + if ( !index ) { + continue; + } + tri->verts[ index - 1 ] = tri->verts[i]; + } + + // this doesn't realloc the arrays to save the memory used by the unused verts + } + + R_StaticFree( mark ); +} + +/* +================= +R_MergeSurfaceList + +Only deals with vertexes and indexes, not silhouettes, planes, etc. +Does NOT perform a cleanup triangles, so there may be duplicated verts in the result. +================= +*/ +srfTriangles_t *R_MergeSurfaceList( const srfTriangles_t **surfaces, int numSurfaces ) { + srfTriangles_t *newTri; + const srfTriangles_t *tri; + int i, j; + int totalVerts; + int totalIndexes; + + totalVerts = 0; + totalIndexes = 0; + for ( i = 0 ; i < numSurfaces ; i++ ) { + totalVerts += surfaces[i]->numVerts; + totalIndexes += surfaces[i]->numIndexes; + } + + newTri = R_AllocStaticTriSurf(); + newTri->numVerts = totalVerts; + newTri->numIndexes = totalIndexes; + R_AllocStaticTriSurfVerts( newTri, newTri->numVerts ); + R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes ); + + totalVerts = 0; + totalIndexes = 0; + for ( i = 0 ; i < numSurfaces ; i++ ) { + tri = surfaces[i]; + memcpy( newTri->verts + totalVerts, tri->verts, tri->numVerts * sizeof( *tri->verts ) ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + newTri->indexes[ totalIndexes + j ] = totalVerts + tri->indexes[j]; + } + totalVerts += tri->numVerts; + totalIndexes += tri->numIndexes; + } + + return newTri; +} + +/* +================= +R_MergeTriangles + +Only deals with vertexes and indexes, not silhouettes, planes, etc. +Does NOT perform a cleanup triangles, so there may be duplicated verts in the result. +================= +*/ +srfTriangles_t *R_MergeTriangles( const srfTriangles_t *tri1, const srfTriangles_t *tri2 ) { + const srfTriangles_t *tris[2]; + + tris[0] = tri1; + tris[1] = tri2; + + return R_MergeSurfaceList( tris, 2 ); +} + +/* +================= +R_ReverseTriangles + +Lit two sided surfaces need to have the triangles actually duplicated, +they can't just turn on two sided lighting, because the normal and tangents +are wrong on the other sides. + +This should be called before R_CleanupTriangles +================= +*/ +void R_ReverseTriangles( srfTriangles_t *tri ) { + int i; + + // flip the normal on each vertex + // If the surface is going to have generated normals, this won't matter, + // but if it has explicit normals, this will keep it on the correct side + for ( i = 0 ; i < tri->numVerts ; i++ ) { + tri->verts[i].normal = vec3_origin - tri->verts[i].normal; + } + + // flip the index order to make them back sided + for ( i = 0 ; i < tri->numIndexes ; i+= 3 ) { + glIndex_t temp; + + temp = tri->indexes[ i + 0 ]; + tri->indexes[ i + 0 ] = tri->indexes[ i + 1 ]; + tri->indexes[ i + 1 ] = temp; + } +} + +/* +================= +R_CleanupTriangles + +FIXME: allow createFlat and createSmooth normals, as well as explicit +================= +*/ +void R_CleanupTriangles( srfTriangles_t *tri, bool createNormals, bool identifySilEdges, bool useUnsmoothedTangents ) { + R_RangeCheckIndexes( tri ); + + R_CreateSilIndexes( tri ); + +// R_RemoveDuplicatedTriangles( tri ); // this may remove valid overlapped transparent triangles + + R_RemoveDegenerateTriangles( tri ); + + R_TestDegenerateTextureSpace( tri ); + +// R_RemoveUnusedVerts( tri ); + + if ( identifySilEdges ) { + R_IdentifySilEdges( tri, true ); // assume it is non-deformable, and omit coplanar edges + } + + // bust vertexes that share a mirrored edge into separate vertexes + R_DuplicateMirroredVertexes( tri ); + + // optimize the index order (not working?) +// R_OrderIndexes( tri->numIndexes, tri->indexes ); + + R_CreateDupVerts( tri ); + + R_BoundTriSurf( tri ); + + if ( useUnsmoothedTangents ) { + R_BuildDominantTris( tri ); + R_DeriveUnsmoothedTangents( tri ); + } else if ( !createNormals ) { + R_DeriveFacePlanes( tri ); + R_DeriveTangentsWithoutNormals( tri ); + } else { + R_DeriveTangents( tri ); + } +} + +/* +=================================================================================== + +DEFORMED SURFACES + +=================================================================================== +*/ + +/* +=================== +R_BuildDeformInfo +=================== +*/ +deformInfo_t *R_BuildDeformInfo( int numVerts, const idDrawVert *verts, int numIndexes, const int *indexes, bool useUnsmoothedTangents ) { + deformInfo_t *deform; + srfTriangles_t tri; + int i; + + memset( &tri, 0, sizeof( tri ) ); + + tri.numVerts = numVerts; + R_AllocStaticTriSurfVerts( &tri, tri.numVerts ); + SIMDProcessor->Memcpy( tri.verts, verts, tri.numVerts * sizeof( tri.verts[0] ) ); + + tri.numIndexes = numIndexes; + R_AllocStaticTriSurfIndexes( &tri, tri.numIndexes ); + + // don't memcpy, so we can change the index type from int to short without changing the interface + for ( i = 0 ; i < tri.numIndexes ; i++ ) { + tri.indexes[i] = indexes[i]; + } + + R_RangeCheckIndexes( &tri ); + R_CreateSilIndexes( &tri ); + +// should we order the indexes here? + +// R_RemoveDuplicatedTriangles( &tri ); +// R_RemoveDegenerateTriangles( &tri ); +// R_RemoveUnusedVerts( &tri ); + R_IdentifySilEdges( &tri, false ); // we cannot remove coplanar edges, because + // they can deform to silhouettes + + R_DuplicateMirroredVertexes( &tri ); // split mirror points into multiple points + + R_CreateDupVerts( &tri ); + + if ( useUnsmoothedTangents ) { + R_BuildDominantTris( &tri ); + } + + deform = (deformInfo_t *)R_ClearedStaticAlloc( sizeof( *deform ) ); + + deform->numSourceVerts = numVerts; + deform->numOutputVerts = tri.numVerts; + + deform->numIndexes = numIndexes; + deform->indexes = tri.indexes; + + deform->silIndexes = tri.silIndexes; + + deform->numSilEdges = tri.numSilEdges; + deform->silEdges = tri.silEdges; + + deform->dominantTris = tri.dominantTris; + + deform->numMirroredVerts = tri.numMirroredVerts; + deform->mirroredVerts = tri.mirroredVerts; + + deform->numDupVerts = tri.numDupVerts; + deform->dupVerts = tri.dupVerts; + + if ( tri.verts ) { + triVertexAllocator.Free( tri.verts ); + } + + if ( tri.facePlanes ) { + triPlaneAllocator.Free( tri.facePlanes ); + } + + return deform; +} + +/* +=================== +R_FreeDeformInfo +=================== +*/ +void R_FreeDeformInfo( deformInfo_t *deformInfo ) { + if ( deformInfo->indexes != NULL ) { + triIndexAllocator.Free( deformInfo->indexes ); + } + if ( deformInfo->silIndexes != NULL ) { + triSilIndexAllocator.Free( deformInfo->silIndexes ); + } + if ( deformInfo->silEdges != NULL ) { + triSilEdgeAllocator.Free( deformInfo->silEdges ); + } + if ( deformInfo->dominantTris != NULL ) { + triDominantTrisAllocator.Free( deformInfo->dominantTris ); + } + if ( deformInfo->mirroredVerts != NULL ) { + triMirroredVertAllocator.Free( deformInfo->mirroredVerts ); + } + if ( deformInfo->dupVerts != NULL ) { + triDupVertAllocator.Free( deformInfo->dupVerts ); + } + R_StaticFree( deformInfo ); +} + +/* +=================== +R_DeformInfoMemoryUsed +=================== +*/ +int R_DeformInfoMemoryUsed( deformInfo_t *deformInfo ) { + int total = 0; + + if ( deformInfo->indexes != NULL ) { + total += deformInfo->numIndexes * sizeof( deformInfo->indexes[0] ); + } + if ( deformInfo->silIndexes != NULL ) { + total += deformInfo->numIndexes * sizeof( deformInfo->silIndexes[0] ); + } + if ( deformInfo->silEdges != NULL ) { + total += deformInfo->numSilEdges * sizeof( deformInfo->silEdges[0] ); + } + if ( deformInfo->dominantTris != NULL ) { + total += deformInfo->numSourceVerts * sizeof( deformInfo->dominantTris[0] ); + } + if ( deformInfo->mirroredVerts != NULL ) { + total += deformInfo->numMirroredVerts * sizeof( deformInfo->mirroredVerts[0] ); + } + if ( deformInfo->dupVerts != NULL ) { + total += deformInfo->numDupVerts * sizeof( deformInfo->dupVerts[0] ); + } + + total += sizeof( *deformInfo ); + return total; +} + diff --git a/renderer/tr_turboshadow.cpp b/renderer/tr_turboshadow.cpp new file mode 100644 index 000000000..908e0f6e0 --- /dev/null +++ b/renderer/tr_turboshadow.cpp @@ -0,0 +1,347 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "tr_local.h" + +int c_turboUsedVerts; +int c_turboUnusedVerts; + + +/* +===================== +R_CreateVertexProgramTurboShadowVolume + +are dangling edges that are outside the light frustum still making planes? +===================== +*/ +srfTriangles_t *R_CreateVertexProgramTurboShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + srfCullInfo_t &cullInfo ) { + int i, j; + srfTriangles_t *newTri; + silEdge_t *sil; + const glIndex_t *indexes; + const byte *facing; + + R_CalcInteractionFacing( ent, tri, light, cullInfo ); + if ( r_useShadowProjectedCull.GetBool() ) { + R_CalcInteractionCullBits( ent, tri, light, cullInfo ); + } + + int numFaces = tri->numIndexes / 3; + int numShadowingFaces = 0; + facing = cullInfo.facing; + + // if all the triangles are inside the light frustum + if ( cullInfo.cullBits == LIGHT_CULL_ALL_FRONT || !r_useShadowProjectedCull.GetBool() ) { + + // count the number of shadowing faces + for ( i = 0; i < numFaces; i++ ) { + numShadowingFaces += facing[i]; + } + numShadowingFaces = numFaces - numShadowingFaces; + + } else { + + // make all triangles that are outside the light frustum "facing", so they won't cast shadows + indexes = tri->indexes; + byte *modifyFacing = cullInfo.facing; + const byte *cullBits = cullInfo.cullBits; + for ( j = i = 0; i < tri->numIndexes; i += 3, j++ ) { + if ( !modifyFacing[j] ) { + int i1 = indexes[i+0]; + int i2 = indexes[i+1]; + int i3 = indexes[i+2]; + if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) { + modifyFacing[j] = 1; + } else { + numShadowingFaces++; + } + } + } + } + + if ( !numShadowingFaces ) { + // no faces are inside the light frustum and still facing the right way + return NULL; + } + + // shadowVerts will be NULL on these surfaces, so the shadowVerts will be taken from the ambient surface + newTri = R_AllocStaticTriSurf(); + + newTri->numVerts = tri->numVerts * 2; + + // alloc the max possible size +#ifdef USE_TRI_DATA_ALLOCATOR + R_AllocStaticTriSurfIndexes( newTri, ( numShadowingFaces + tri->numSilEdges ) * 6 ); + glIndex_t *tempIndexes = newTri->indexes; + glIndex_t *shadowIndexes = newTri->indexes; +#else + glIndex_t *tempIndexes = (glIndex_t *)_alloca16( tri->numSilEdges * 6 * sizeof( tempIndexes[0] ) ); + glIndex_t *shadowIndexes = tempIndexes; +#endif + + // create new triangles along sil planes + for ( sil = tri->silEdges, i = tri->numSilEdges; i > 0; i--, sil++ ) { + + int f1 = facing[sil->p1]; + int f2 = facing[sil->p2]; + + if ( !( f1 ^ f2 ) ) { + continue; + } + + int v1 = sil->v1 << 1; + int v2 = sil->v2 << 1; + + // set the two triangle winding orders based on facing + // without using a poorly-predictable branch + + shadowIndexes[0] = v1; + shadowIndexes[1] = v2 ^ f1; + shadowIndexes[2] = v2 ^ f2; + shadowIndexes[3] = v1 ^ f2; + shadowIndexes[4] = v1 ^ f1; + shadowIndexes[5] = v2 ^ 1; + + shadowIndexes += 6; + } + + int numShadowIndexes = shadowIndexes - tempIndexes; + + // we aren't bothering to separate front and back caps on these + newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps = numShadowIndexes + numShadowingFaces * 6; + newTri->numShadowIndexesNoCaps = numShadowIndexes; + newTri->shadowCapPlaneBits = SHADOW_CAP_INFINITE; + +#ifdef USE_TRI_DATA_ALLOCATOR + // decrease the size of the memory block to only store the used indexes + R_ResizeStaticTriSurfIndexes( newTri, newTri->numIndexes ); +#else + // allocate memory for the indexes + R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes ); + // copy the indexes we created for the sil planes + SIMDProcessor->Memcpy( newTri->indexes, tempIndexes, numShadowIndexes * sizeof( tempIndexes[0] ) ); +#endif + + // these have no effect, because they extend to infinity + newTri->bounds.Clear(); + + // put some faces on the model and some on the distant projection + indexes = tri->indexes; + shadowIndexes = newTri->indexes + numShadowIndexes; + for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) { + if ( facing[j] ) { + continue; + } + + int i0 = indexes[i+0] << 1; + shadowIndexes[2] = i0; + shadowIndexes[3] = i0 ^ 1; + int i1 = indexes[i+1] << 1; + shadowIndexes[1] = i1; + shadowIndexes[4] = i1 ^ 1; + int i2 = indexes[i+2] << 1; + shadowIndexes[0] = i2; + shadowIndexes[5] = i2 ^ 1; + + shadowIndexes += 6; + } + + return newTri; +} + +/* +===================== +R_CreateTurboShadowVolume +===================== +*/ +srfTriangles_t *R_CreateTurboShadowVolume( const idRenderEntityLocal *ent, + const srfTriangles_t *tri, const idRenderLightLocal *light, + srfCullInfo_t &cullInfo ) { + int i, j; + idVec3 localLightOrigin; + srfTriangles_t *newTri; + silEdge_t *sil; + const glIndex_t *indexes; + const byte *facing; + + R_CalcInteractionFacing( ent, tri, light, cullInfo ); + if ( r_useShadowProjectedCull.GetBool() ) { + R_CalcInteractionCullBits( ent, tri, light, cullInfo ); + } + + int numFaces = tri->numIndexes / 3; + int numShadowingFaces = 0; + facing = cullInfo.facing; + + // if all the triangles are inside the light frustum + if ( cullInfo.cullBits == LIGHT_CULL_ALL_FRONT || !r_useShadowProjectedCull.GetBool() ) { + + // count the number of shadowing faces + for ( i = 0; i < numFaces; i++ ) { + numShadowingFaces += facing[i]; + } + numShadowingFaces = numFaces - numShadowingFaces; + + } else { + + // make all triangles that are outside the light frustum "facing", so they won't cast shadows + indexes = tri->indexes; + byte *modifyFacing = cullInfo.facing; + const byte *cullBits = cullInfo.cullBits; + for ( j = i = 0; i < tri->numIndexes; i += 3, j++ ) { + if ( !modifyFacing[j] ) { + int i1 = indexes[i+0]; + int i2 = indexes[i+1]; + int i3 = indexes[i+2]; + if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) { + modifyFacing[j] = 1; + } else { + numShadowingFaces++; + } + } + } + } + + if ( !numShadowingFaces ) { + // no faces are inside the light frustum and still facing the right way + return NULL; + } + + newTri = R_AllocStaticTriSurf(); + +#ifdef USE_TRI_DATA_ALLOCATOR + R_AllocStaticTriSurfShadowVerts( newTri, tri->numVerts * 2 ); + shadowCache_t *shadowVerts = newTri->shadowVertexes; +#else + shadowCache_t *shadowVerts = (shadowCache_t *)_alloca16( tri->numVerts * 2 * sizeof( shadowVerts[0] ) ); +#endif + + R_GlobalPointToLocal( ent->modelMatrix, light->globalLightOrigin, localLightOrigin ); + + int *vertRemap = (int *)_alloca16( tri->numVerts * sizeof( vertRemap[0] ) ); + + SIMDProcessor->Memset( vertRemap, -1, tri->numVerts * sizeof( vertRemap[0] ) ); + + for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) { + if ( facing[j] ) { + continue; + } + // this may pull in some vertexes that are outside + // the frustum, because they connect to vertexes inside + vertRemap[tri->silIndexes[i+0]] = 0; + vertRemap[tri->silIndexes[i+1]] = 0; + vertRemap[tri->silIndexes[i+2]] = 0; + } + + newTri->numVerts = SIMDProcessor->CreateShadowCache( &shadowVerts->xyz, vertRemap, localLightOrigin, tri->verts, tri->numVerts ); + + c_turboUsedVerts += newTri->numVerts; + c_turboUnusedVerts += tri->numVerts * 2 - newTri->numVerts; + +#ifdef USE_TRI_DATA_ALLOCATOR + R_ResizeStaticTriSurfShadowVerts( newTri, newTri->numVerts ); +#else + R_AllocStaticTriSurfShadowVerts( newTri, newTri->numVerts ); + SIMDProcessor->Memcpy( newTri->shadowVertexes, shadowVerts, newTri->numVerts * sizeof( shadowVerts[0] ) ); +#endif + + // alloc the max possible size +#ifdef USE_TRI_DATA_ALLOCATOR + R_AllocStaticTriSurfIndexes( newTri, ( numShadowingFaces + tri->numSilEdges ) * 6 ); + glIndex_t *tempIndexes = newTri->indexes; + glIndex_t *shadowIndexes = newTri->indexes; +#else + glIndex_t *tempIndexes = (glIndex_t *)_alloca16( tri->numSilEdges * 6 * sizeof( tempIndexes[0] ) ); + glIndex_t *shadowIndexes = tempIndexes; +#endif + + // create new triangles along sil planes + for ( sil = tri->silEdges, i = tri->numSilEdges; i > 0; i--, sil++ ) { + + int f1 = facing[sil->p1]; + int f2 = facing[sil->p2]; + + if ( !( f1 ^ f2 ) ) { + continue; + } + + int v1 = vertRemap[sil->v1]; + int v2 = vertRemap[sil->v2]; + + // set the two triangle winding orders based on facing + // without using a poorly-predictable branch + + shadowIndexes[0] = v1; + shadowIndexes[1] = v2 ^ f1; + shadowIndexes[2] = v2 ^ f2; + shadowIndexes[3] = v1 ^ f2; + shadowIndexes[4] = v1 ^ f1; + shadowIndexes[5] = v2 ^ 1; + + shadowIndexes += 6; + } + + int numShadowIndexes = shadowIndexes - tempIndexes; + + // we aren't bothering to separate front and back caps on these + newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps = numShadowIndexes + numShadowingFaces * 6; + newTri->numShadowIndexesNoCaps = numShadowIndexes; + newTri->shadowCapPlaneBits = SHADOW_CAP_INFINITE; + +#ifdef USE_TRI_DATA_ALLOCATOR + // decrease the size of the memory block to only store the used indexes + R_ResizeStaticTriSurfIndexes( newTri, newTri->numIndexes ); +#else + // allocate memory for the indexes + R_AllocStaticTriSurfIndexes( newTri, newTri->numIndexes ); + // copy the indexes we created for the sil planes + SIMDProcessor->Memcpy( newTri->indexes, tempIndexes, numShadowIndexes * sizeof( tempIndexes[0] ) ); +#endif + + // these have no effect, because they extend to infinity + newTri->bounds.Clear(); + + // put some faces on the model and some on the distant projection + indexes = tri->silIndexes; + shadowIndexes = newTri->indexes + numShadowIndexes; + for ( i = 0, j = 0; i < tri->numIndexes; i += 3, j++ ) { + if ( facing[j] ) { + continue; + } + + int i0 = vertRemap[indexes[i+0]]; + shadowIndexes[2] = i0; + shadowIndexes[3] = i0 ^ 1; + int i1 = vertRemap[indexes[i+1]]; + shadowIndexes[1] = i1; + shadowIndexes[4] = i1 ^ 1; + int i2 = vertRemap[indexes[i+2]]; + shadowIndexes[0] = i2; + shadowIndexes[5] = i2 ^ 1; + + shadowIndexes += 6; + } + + return newTri; +} diff --git a/renderer/wglext.h b/renderer/wglext.h new file mode 100644 index 000000000..0a8cc91d2 --- /dev/null +++ b/renderer/wglext.h @@ -0,0 +1,612 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number */ +/* wglext.h last updated 2002/03/22 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define WGL_WGLEXT_VERSION 4 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_I3D_swap_frame_lock +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +extern void WINAPI wglFreeMemoryNV (void *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); +extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); +extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); +extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); +extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); +extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableGenlockI3D (HDC); +extern BOOL WINAPI wglDisableGenlockI3D (HDC); +extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); +extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); +extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); +extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); +extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); +extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#endif + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableFrameLockI3D (void); +extern BOOL WINAPI wglDisableFrameLockI3D (void); +extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); +extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#endif + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetFrameUsageI3D (float *); +extern BOOL WINAPI wglBeginFrameTrackingI3D (void); +extern BOOL WINAPI wglEndFrameTrackingI3D (void); +extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/runrelease.bat b/runrelease.bat new file mode 100644 index 000000000..fa78a084c --- /dev/null +++ b/runrelease.bat @@ -0,0 +1 @@ +releasedll\doom +set fs_basepath c:\games\doom3 +set fs_cdpath \doom + %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/scripts/texture_reorg/DebugMessage.py b/scripts/texture_reorg/DebugMessage.py deleted file mode 100644 index ca809b6f2..000000000 --- a/scripts/texture_reorg/DebugMessage.py +++ /dev/null @@ -1,114 +0,0 @@ -#messaging.py -#this is a module used for messaging. It allows multiple classes -#to handle various types of messages. It should work on all python -#versions >= 1.5.2 -# -# found on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/144838 - -import sys, string, exceptions - -#this flag determines whether debug output is sent to debug handlers themselves -debug = 1 - -def setDebugging(debugging): - global debug - debug = debugging - -class MessagingException(exceptions.Exception): - """an exception class for any errors that may occur in - a messaging function""" - def __init__(self, args=None): - self.args = args - -class FakeException(exceptions.Exception): - """an exception that is thrown and then caught - to get a reference to the current execution frame""" - pass - - -class MessageHandler: - """All message handlers should inherit this class. Each method will be - passed a string when the executing program passes calls a messaging function""" - def handleStdMsg(self, msg): - """do something with a standard message from the program""" - pass - def handleErrMsg(self, msg): - """do something with an error message. This will already include the - class, method, and line of the call""" - pass - def handleDbgMsg(self, msg): - """do something with a debug message. This will already include the - class, method, and line of the call""" - pass - -class defaultMessageHandler(MessageHandler): - """This is a default message handler. It simply spits all strings to - standard out""" - def handleStdMsg(self, msg): - sys.stdout.write(msg + "\n") - def handleErrMsg(self, msg): - sys.stderr.write(msg + "\n") - def handleDbgMsg(self, msg): - sys.stdout.write(msg + "\n") - -#this keeps track of the handlers -_messageHandlers = [] - -#call this with the handler to register it for receiving messages -def registerMessageHandler(handler): - """we're not going to check for inheritance, but we should check to make - sure that it has the correct methods""" - for methodName in ["handleStdMsg", "handleErrMsg", "handleDbgMsg"]: - try: - getattr(handler, methodName) - except: - raise MessagingException, "The class " + handler.__class__.__name__ + " is missing a " + methodName + " method" - _messageHandlers.append(handler) - - -def getCallString(level): - #this gets us the frame of the caller and will work - #in python versions 1.5.2 and greater (there are better - #ways starting in 2.1 - try: - raise FakeException("this is fake") - except Exception, e: - #get the current execution frame - f = sys.exc_info()[2].tb_frame - #go back as many call-frames as was specified - while level >= 0: - f = f.f_back - level = level-1 - #if there is a self variable in the caller's local namespace then - #we'll make the assumption that the caller is a class method - obj = f.f_locals.get("self", None) - functionName = f.f_code.co_name - if obj: - callStr = obj.__class__.__name__+"::"+f.f_code.co_name+" (line "+str(f.f_lineno)+")" - else: - callStr = f.f_code.co_name+" (line "+str(f.f_lineno)+")" - return callStr - -#send this message to all handlers of std messages -def stdMsg(*args): - stdStr = string.join(map(str, args), " ") - for handler in _messageHandlers: - handler.handleStdMsg(stdStr) - -#send this message to all handlers of error messages -def errMsg(*args): - errStr = "Error in "+getCallString(1)+" : "+string.join(map(str, args), " ") - for handler in _messageHandlers: - handler.handleErrMsg(errStr) - -#send this message to all handlers of debug messages -def dbgMsg(*args): - if not debug: - return - errStr = getCallString(1)+" : "+string.join(map(str, args), " ") - for handler in _messageHandlers: - handler.handleDbgMsg(errStr) - - -registerMessageHandler(defaultMessageHandler()) -#end of messaging.py diff --git a/scripts/texture_reorg/broken_models.txt b/scripts/texture_reorg/broken_models.txt deleted file mode 100644 index c96b4e178..000000000 --- a/scripts/texture_reorg/broken_models.txt +++ /dev/null @@ -1,65 +0,0 @@ -darkmod/ - -nature/ -large_bush_01.lwo (+ skins) -mushrooms_01 -mushroom_selflit_red (skin) -mushrooms_02 -mushroom_01 -mushroom_02 -mushroom_03 -small_bush_01 -bc_largepot_tree -bc_medpot_tree -bc_smallpot_tree -pine_tree_* - -props/containers/ -bc_chest3 -bc_chest3_lid -sack1_low - -props/decorative/ -emptypot (decorative/vase/gen_paintedmetal, gen_copper_001, gen_gold_001, gen_rust_001 skins) -vase1 (some skins) -vase_squat - -props/decorative/oversized/ -the_hammer_medium1 (darkstone skin) - -props/decorative/wall/ -banner2 -painting01 landscape_ruin02, farmland, execution, master_builder, sorceress, harbour, woman bathing builder_forge, warriors, knight_and_maiden skins) -painting01_L (standard skin, farmland, execution, master_builder, sorceress, harbour, woman bathing builder_forge, warriors, knight_and_maiden skins) -painting01_m (same as above) - -props/graveyard/ -grave_chain* -grave_fence - -props/lights/non_extinguishable/ -bc_desklamp01 -bc_lantern -bc_sphere_wallight -bc_streetlamp* -bc_wall_lamp -grill_light -hanging_lantern -hooded_lantern -lamp_shaded -round_streetlamp -squarehanginglamp -square_streetlamp -sq_torch -streetlamp1 -wall_light* - -props/misc/ -staff.lwo (staff_weapon skin) - -props/readables -book_t1 (burnt_book1 skin) - -props/tools/mop.lwo - -props/pipekit/tap/tap1.lwo \ No newline at end of file diff --git a/scripts/texture_reorg/logfile.txt b/scripts/texture_reorg/logfile.txt deleted file mode 100644 index 2b57f0fbd..000000000 --- a/scripts/texture_reorg/logfile.txt +++ /dev/null @@ -1,256 +0,0 @@ -Caching material files... - -materials/misc.mtr - -materials/tdm_metal_floor.mtr - -materials/kitchen.mtr -Missing:359: models/renderbump/smspoon_ornamental_local - -materials/tdm_gen_ceramic.mtr -Missing:8: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:9: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:10: textures/darkmod/ceramic/gen/ceramic_001_local -Missing:11: textures/darkmod/ceramic/gen/ceramic_001_s -Missing:21: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:30: textures/darkmod/ceramic/gen/ceramic_002_d -Missing:31: textures/darkmod/ceramic/gen/ceramic_002_d -Missing:32: textures/darkmod/ceramic/gen/ceramic_002_local -Missing:33: textures/darkmod/ceramic/gen/ceramic_002_s -Missing:43: textures/darkmod/ceramic/gen/ceramic_002_d - -materials/tdm_stone_trim.mtr - -materials/tdm_ai_pagans.mtr -Missing:68: models/md5/chars/pagans/pagan_female/pagan_female_head_local - -materials/tdm_gen_metal.mtr -Missing:129: textures/darkmod/metal/gen/goldloot_001_d -Missing:130: textures/darkmod/metal/gen/goldloot_001_d -Missing:131: textures/darkmod/metal/gen/goldloot_001_local -Missing:132: textures/darkmod/metal/gen/goldloot_001_s -Missing:142: textures/darkmod/metal/gen/goldloot_001_d -Missing:184: textures/darkmod/metal/gen/iron_002_local -Missing:185: textures/darkmod/metal/gen/iron_002_s - -materials/pipekit.mtr -Missing:9: models/darkmod/props/textures/wip -Missing:10: models/darkmod/props/textures/bathroom_bath1_local -Missing:11: models/darkmod/props/textures/wip_s -Missing:21: models/darkmod/props/textures/wip -Missing:33: models/darkmod/props/textures/metalpipe1 -Missing:34: models/darkmod/props/textures/metalpipe1_local2 -Missing:35: models/darkmod/props/textures/metalpipe1_s -Missing:45: models/darkmod/props/textures/metalpipe1 - -materials/tools.mtr -Missing:10: models/darmkmod/props/textures/broomst_local -Missing:160: models/darkmod/props/textures/mop_d -Missing:161: models/darkmod/props/textures/mop_local -Missing:172: models/darkmod/props/textures/mop_d - -materials/tdm_stone_wall.mtr - -materials/lights_tdm.mtr -Missing:136: models/darkmod/props/textures/candelabra_ed -Missing:691: models/darkmod/props/textures/rustylamp_d - -materials/weapons.mtr -Missing:524: models/darkmod/props/textures/blackjack_d -Missing:547: models/my -Missing:566: models/my -Missing:585: models/my -Missing:599: models/weapons/shortbow/playerhand_s -Missing:605: models/my -Missing:619: models/darkmod/props/textures/longsword_h - -materials/tdm_ai_thief.mtr -Missing:51: models/md5/chars/thief/thief_leather_s -Missing:74: models/md5/chars/thief/thief_leather_s -Missing:135: models/md5/chars/thief/bow_d - -materials/askave.mtr -Missing:24: textures/darkmod/stone/floor/rough_detail - -materials/potions.mtr -Missing:70: models/darkmod/props/textures/airpotion - -materials/tdm_tile_floor.mtr - -materials/mechanical.mtr -Missing:25: models/my - -materials/tdm_ai_heads_dev.mtr -Missing:54: models/md5/chars/heads/npcs/beard_black -Missing:55: models/md5/chars/heads/npcs/beard_black_local -Missing:56: models/md5/chars/heads/npcs/beard_black_s - -materials/tdm_foliage_wall.mtr - -materials/loot.mtr -Missing:145: models/darkmod/props/textures/gold_tiling - -materials/tdm_snow_floor.mtr - -materials/tdm_ai_guards.mtr -Missing:3: models/chars/chaindisp_local -Missing:28: models/chars/chaindisp_local -Missing:57: models/chars/chaindisp_local -Missing:82: models/chars/chaindisp_local -Missing:135: models/chars/chaindisp_local -Missing:141: models/md5/chars/guards/proguard/proguard2_d -Missing:153: models/chars/guards/proguard/proguard_d -Missing:185: models/chars/elite_citywatch4_local -Missing:235: models/chars/elite_citywatch4_local -Missing:434: models/md5/chars/guards/houseguard/houseguard_head_s - -materials/bonehoard.mtr -Missing:16: textures/darkmod/bonehoard/env/water_entrance - -materials/test_volumetric.mtr - -materials/Perftestmulti.mtr -Missing:5: models/darkmod/props/textures/perftest_d -Missing:6: models/darkmod/props/textures/perftest_s -Missing:7: models/darkmod/props/textures/perftest_local -Missing:14: models/darkmod/props/textures/perftest_d -Missing:15: models/darkmod/props/textures/perftest_s -Missing:16: models/darkmod/props/textures/perftest_local -Missing:23: models/darkmod/props/textures/perftest_d -Missing:24: models/darkmod/props/textures/perftest_s -Missing:25: models/darkmod/props/textures/perftest_local -Missing:32: models/darkmod/props/textures/perftest_d -Missing:33: models/darkmod/props/textures/perftest_s -Missing:34: models/darkmod/props/textures/perftest_local - -materials/nature.mtr -Missing:152: textures/darkmod/nature/rock01_d -Missing:238: models/darkmod/props/textures/mushroom_white_local - -materials/decorative_wall.mtr - -materials/furniture_seating.mtr -Missing:32: models/darkmod/props/textures/tab1_chair2_d -Missing:33: models/darkmod/props/textures/tab1_chair1_local -Missing:43: models/darkmod/props/textures/tab1_chair2_d - -materials/tdm_ai_builders.mtr -Missing:89: models/chars/prelatebottom_local -Missing:115: models/chars/prelatenottom_local -Missing:122: models/chars/builders/inquisitor/inquisitornottom_s -Missing:169: models/chars/prelatebottom_local -Missing:195: models/chars/prelatenottom_local -Missing:202: models/chars/builders/prelate/prelatenottom_s -Missing:251: models/chars/builderbottom2_local -Missing:282: models/chars/buildertop2_local -Missing:312: models/chars/buildertop2_local - -materials/wearable.mtr -Missing:50: models/darkmod/props/textures/ponytail_black -Missing:62: models/darkmod/props/textures/generic_s - -materials/tdm_wood_floor.mtr - -materials/tdm_door.mtr - -materials/tdm_sky.mtr -Missing:16: textures/gilsky/white - -materials/furniture_beds.mtr -Missing:55: models/mapobjects/tables/bunkbed/mattress_d -Missing:56: models/mapobjects/tables/bunkbed/mattress_local -Missing:57: models/mapobjects/tables/bunkbed/mattress_s -Missing:67: models/mapobjects/tables/bunkbed/mattress_d - -materials/readable.mtr -Missing:32: models/darkmod/props/textures/burntbook_t1 -Missing:42: models/darkmod/props/textures/burntbook_t1 - -materials/tdm_gen_stone.mtr -Missing:29: textures/darkmod/stone/gen/brick_002_d -Missing:30: textures/darkmod/stone/gen/brick_002_d -Missing:31: textures/darkmod/stone/gen/brick_002_local -Missing:42: textures/darkmod/stone/gen/brick_002_d - -materials/tdm_wood_wall.mtr - -materials/decorative_oversize.mtr - -materials/tdm_ai_townsfolk.mtr -Missing:109: models/md5/chars/townsfolk/town_belt -Missing:138: models/md5/chars/townsfolk/town_ties -Missing:154: models/md5/chars/townsfolk/townsfolk_male1/town_head_local -Missing:181: models/md5/chars/townsfolk/townsfolk_male1/town_hair_local - -materials/player_equipment.mtr -Missing:188: models/darkmod/props/textures/blackjack_d - -materials/graveyard.mtr -Missing:159: models/darkmod/props/textures/TheHammer_medium_stone_dark_d -Missing:160: models/darkmod/props/textures/TheHammer_medium_stone_local -Missing:209: models/darkmod/props/textures/chain1_d -Missing:213: models/darkmod/props/textures/chain1_local -Missing:214: models/darkmod/props/textures/chain1_s -Missing:226: models/darkmod/props/textures/fence1_d -Missing:230: models/darkmod/props/textures/fence1_local - -materials/tdm_gen_tile.mtr -Missing:8: textures/darkmod/tile/gen/tile_001_d -Missing:9: textures/darkmod/tile/gen/tile_001_d -Missing:10: textures/darkmod/tile/gen/tile_001_local -Missing:21: textures/darkmod/tile/gen/tile_001_d -Missing:30: textures/darkmod/tile/gen/tile_002_s -Missing:31: textures/darkmod/tile/gen/tile_002_s -Missing:32: textures/darkmod/tile/gen/tile_local -Missing:43: textures/darkmod/tile/gen/tile_002_s - -materials/tdm_foliage_trim.mtr - -materials/chars.mtr -Missing:90: models/chars/longsword_local -Missing:113: models/chars/chainmail_local - -materials/test_window.mtr - -materials/tdm_wood_trim.mtr - -materials/tdm_stone_floor.mtr -Missing:1311: textures/darkmod/stone/floor/cobble_007_s - -materials/tdm_ceramic_floor.mtr - -materials/tdm_ceramic_wall.mtr -Missing:36: textures/darkmod/pagan/wall/pagwall01_s - -materials/keys.mtr -Missing:75: models/darkmod/player_equipment/lockpick_bent_inv_icon -Missing:76: models/darkmod/player_equipment/lockpick_bent_inv_icon -Missing:81: models/darkmod/player_equipment/lockpick_circle_inv_icon -Missing:82: models/darkmod/player_equipment/lockpick_circle_inv_icon -Missing:87: models/darkmod/player_equipment/lockpick_snake_inv_icon -Missing:88: models/darkmod/player_equipment/lockpick_snake_inv_icon -Missing:93: models/darkmod/player_equipment/lockpick_triangle_inv_icon -Missing:94: models/darkmod/player_equipment/lockpick_triangle_inv_icon - -materials/guard.mtr -Missing:5: models/guard/guard -Missing:15: models/guard/guard -Missing:25: models/guard/guardarmour -Missing:35: models/guard/guardarmour -Missing:47: models/chars/undead/revenant/skirtacol -Missing:51: models/chars/builders/guard/builder_local -Missing:52: models/chars/undead/revenant/skirt_s -Missing:62: models/chars/undead/revenant/skirtacol -Missing:74: models/chars/undead/revenant/hauntarmor_d -Missing:78: models/chars/builders/guard/builderarmor_local -Missing:79: models/chars/undead/revenant/hauntarmor_s -Missing:89: models/chars/undead/revenant/hauntarmor_d - -materials/architecture.mtr -Missing:307: textures/darkmod/nature/plant_02 -Missing:314: textures/darkmod/nature/plant_02 -Missing:326: textures/darkmod/nature/plant_02 -Missing:334: textures/gw_dm1/tree/bark_02 -Missing:338: textures/gw_dm1/tree/bark_02 -Missing:339: textures/gw_dm1/tree/bark_02_local -Missing:349: textures/gw_dm1/tree/bark_02 diff --git a/scripts/texture_reorg/logfile_angua.txt b/scripts/texture_reorg/logfile_angua.txt deleted file mode 100644 index d7c5fc2f0..000000000 --- a/scripts/texture_reorg/logfile_angua.txt +++ /dev/null @@ -1,273 +0,0 @@ -Caching material files... - -materials/misc.mtr - -materials/tdm_metal_floor.mtr - -materials/kitchen.mtr -Missing:359: models/renderbump/smspoon_ornamental_local - -materials/tdm_gen_ceramic.mtr -Missing:8: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:9: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:10: textures/darkmod/ceramic/gen/ceramic_001_local -Missing:11: textures/darkmod/ceramic/gen/ceramic_001_s -Missing:21: textures/darkmod/ceramic/gen/ceramic_001_d -Missing:30: textures/darkmod/ceramic/gen/ceramic_002_d -Missing:31: textures/darkmod/ceramic/gen/ceramic_002_d -Missing:32: textures/darkmod/ceramic/gen/ceramic_002_local -Missing:33: textures/darkmod/ceramic/gen/ceramic_002_s -Missing:43: textures/darkmod/ceramic/gen/ceramic_002_d - -//folder gen nonexistent before reorg >> file removed - -materials/tdm_stone_trim.mtr - -materials/tdm_ai_pagans.mtr -Missing:68: models/md5/chars/pagans/pagan_female/pagan_female_head_local - -materials/tdm_gen_metal.mtr -Missing:129: textures/darkmod/metal/gen/goldloot_001_d -Missing:130: textures/darkmod/metal/gen/goldloot_001_d -Missing:131: textures/darkmod/metal/gen/goldloot_001_local -Missing:132: textures/darkmod/metal/gen/goldloot_001_s -Missing:142: textures/darkmod/metal/gen/goldloot_001_d -//goldloot nonexistant before reorg >> deleted - -Missing:184: textures/darkmod/metal/gen/iron_002_local -Missing:185: textures/darkmod/metal/gen/iron_002_s -//s and local nonexistant before reorg, diffusemap should be there >> references deleted - -materials/pipekit.mtr -Missing:9: models/darkmod/props/textures/wip -Missing:10: models/darkmod/props/textures/bathroom_bath1_local -Missing:11: models/darkmod/props/textures/wip_s -Missing:21: models/darkmod/props/textures/wip -Missing:33: models/darkmod/props/textures/metalpipe1 -Missing:34: models/darkmod/props/textures/metalpipe1_local2 -Missing:35: models/darkmod/props/textures/metalpipe1_s -Missing:45: models/darkmod/props/textures/metalpipe1 - -materials/tools.mtr -Missing:10: models/darmkmod/props/textures/broomst_local -Missing:160: models/darkmod/props/textures/mop_d -Missing:161: models/darkmod/props/textures/mop_local -Missing:172: models/darkmod/props/textures/mop_d - -materials/tdm_stone_wall.mtr - -materials/lights_tdm.mtr -Missing:136: models/darkmod/props/textures/candelabra_ed -Missing:691: models/darkmod/props/textures/rustylamp_d - -materials/weapons.mtr -Missing:524: models/darkmod/props/textures/blackjack_d -Missing:547: models/my -Missing:566: models/my -Missing:585: models/my -Missing:599: models/weapons/shortbow/playerhand_s -Missing:605: models/my -Missing:619: models/darkmod/props/textures/longsword_h - -materials/tdm_ai_thief.mtr -Missing:51: models/md5/chars/thief/thief_leather_s -Missing:74: models/md5/chars/thief/thief_leather_s -Missing:135: models/md5/chars/thief/bow_d - -materials/askave.mtr -Missing:24: textures/darkmod/stone/floor/rough_detail -//old material def, is now darkmod/detail/rough_001 >> corrected - -materials/potions.mtr -Missing:70: models/darkmod/props/textures/airpotion - -materials/tdm_tile_floor.mtr - -materials/mechanical.mtr -Missing:25: models/my - -materials/tdm_ai_heads_dev.mtr -Missing:54: models/md5/chars/heads/npcs/beard_black -Missing:55: models/md5/chars/heads/npcs/beard_black_local -Missing:56: models/md5/chars/heads/npcs/beard_black_s - -materials/tdm_foliage_wall.mtr - -materials/loot.mtr -Missing:145: models/darkmod/props/textures/gold_tiling - -materials/tdm_snow_floor.mtr - -materials/tdm_ai_guards.mtr -Missing:3: models/chars/chaindisp_local -Missing:28: models/chars/chaindisp_local -Missing:57: models/chars/chaindisp_local -Missing:82: models/chars/chaindisp_local -Missing:135: models/chars/chaindisp_local -Missing:141: models/md5/chars/guards/proguard/proguard2_d -Missing:153: models/chars/guards/proguard/proguard_d -Missing:185: models/chars/elite_citywatch4_local -Missing:235: models/chars/elite_citywatch4_local -Missing:434: models/md5/chars/guards/houseguard/houseguard_head_s - -materials/bonehoard.mtr -Missing:16: textures/darkmod/bonehoard/env/water_entrance -//this is an envshot, there are 6 textures with _up, _left, etc. >> reference correct to map_specific/bonehoard - -materials/test_volumetric.mtr - -materials/Perftestmulti.mtr -Missing:5: models/darkmod/props/textures/perftest_d -Missing:6: models/darkmod/props/textures/perftest_s -Missing:7: models/darkmod/props/textures/perftest_local -Missing:14: models/darkmod/props/textures/perftest_d -Missing:15: models/darkmod/props/textures/perftest_s -Missing:16: models/darkmod/props/textures/perftest_local -Missing:23: models/darkmod/props/textures/perftest_d -Missing:24: models/darkmod/props/textures/perftest_s -Missing:25: models/darkmod/props/textures/perftest_local -Missing:32: models/darkmod/props/textures/perftest_d -Missing:33: models/darkmod/props/textures/perftest_s -Missing:34: models/darkmod/props/textures/perftest_local - -materials/nature.mtr -Missing:152: textures/darkmod/nature/rock01_d -//should be models/darkmod/nature/rock01_d.tga I think this is a typo >> corrected - -Missing:238: models/darkmod/props/textures/mushroom_white_local - -materials/decorative_wall.mtr - -materials/furniture_seating.mtr -Missing:32: models/darkmod/props/textures/tab1_chair2_d -Missing:33: models/darkmod/props/textures/tab1_chair1_local -Missing:43: models/darkmod/props/textures/tab1_chair2_d - -materials/tdm_ai_builders.mtr -Missing:89: models/chars/prelatebottom_local -Missing:115: models/chars/prelatenottom_local -Missing:122: models/chars/builders/inquisitor/inquisitornottom_s -Missing:169: models/chars/prelatebottom_local -Missing:195: models/chars/prelatenottom_local -Missing:202: models/chars/builders/prelate/prelatenottom_s -Missing:251: models/chars/builderbottom2_local -Missing:282: models/chars/buildertop2_local -Missing:312: models/chars/buildertop2_local - -materials/wearable.mtr -Missing:50: models/darkmod/props/textures/ponytail_black -Missing:62: models/darkmod/props/textures/generic_s - -materials/tdm_wood_floor.mtr - -materials/tdm_door.mtr - -materials/tdm_sky.mtr -Missing:16: textures/gilsky/white -//nonexistant before reorg >> corrected to diffusemap _white - -materials/furniture_beds.mtr -Missing:55: models/mapobjects/tables/bunkbed/mattress_d -Missing:56: models/mapobjects/tables/bunkbed/mattress_local -Missing:57: models/mapobjects/tables/bunkbed/mattress_s -Missing:67: models/mapobjects/tables/bunkbed/mattress_d - -materials/readable.mtr -Missing:32: models/darkmod/props/textures/burntbook_t1 -Missing:42: models/darkmod/props/textures/burntbook_t1 - -materials/tdm_gen_stone.mtr -Missing:29: textures/darkmod/stone/gen/brick_002_d -Missing:30: textures/darkmod/stone/gen/brick_002_d -Missing:31: textures/darkmod/stone/gen/brick_002_local -Missing:42: textures/darkmod/stone/gen/brick_002_d -//nonexistent before reorg >> shader removed - -materials/tdm_wood_wall.mtr - -materials/decorative_oversize.mtr - -materials/tdm_ai_townsfolk.mtr -Missing:109: models/md5/chars/townsfolk/town_belt -Missing:138: models/md5/chars/townsfolk/town_ties -Missing:154: models/md5/chars/townsfolk/townsfolk_male1/town_head_local -Missing:181: models/md5/chars/townsfolk/townsfolk_male1/town_hair_local - -materials/player_equipment.mtr -Missing:188: models/darkmod/props/textures/blackjack_d - -materials/graveyard.mtr -Missing:159: models/darkmod/props/textures/TheHammer_medium_stone_dark_d -Missing:160: models/darkmod/props/textures/TheHammer_medium_stone_local -Missing:209: models/darkmod/props/textures/chain1_d -Missing:213: models/darkmod/props/textures/chain1_local -Missing:214: models/darkmod/props/textures/chain1_s -Missing:226: models/darkmod/props/textures/fence1_d -Missing:230: models/darkmod/props/textures/fence1_local - -materials/tdm_gen_tile.mtr -Missing:8: textures/darkmod/tile/gen/tile_001_d -Missing:9: textures/darkmod/tile/gen/tile_001_d -Missing:10: textures/darkmod/tile/gen/tile_001_local -Missing:21: textures/darkmod/tile/gen/tile_001_d -Missing:30: textures/darkmod/tile/gen/tile_002_s -Missing:31: textures/darkmod/tile/gen/tile_002_s -Missing:32: textures/darkmod/tile/gen/tile_local -Missing:43: textures/darkmod/tile/gen/tile_002_s -//folder nonexistant before reorg >> file removed - -materials/tdm_foliage_trim.mtr - -materials/chars.mtr -Missing:90: models/chars/longsword_local -Missing:113: models/chars/chainmail_local - -materials/test_window.mtr - -materials/tdm_wood_trim.mtr - -materials/tdm_stone_floor.mtr -Missing:1311: textures/darkmod/stone/floor/cobble_007_s -//nonexistant before reorg (possibly not needed?) >> reference removed - -materials/tdm_ceramic_floor.mtr - -materials/tdm_ceramic_wall.mtr -Missing:36: textures/darkmod/pagan/wall/pagwall01_s -//nonexistant before reorg >> reference to specular removed - -materials/keys.mtr -Missing:75: models/darkmod/player_equipment/lockpick_bent_inv_icon -Missing:76: models/darkmod/player_equipment/lockpick_bent_inv_icon -Missing:81: models/darkmod/player_equipment/lockpick_circle_inv_icon -Missing:82: models/darkmod/player_equipment/lockpick_circle_inv_icon -Missing:87: models/darkmod/player_equipment/lockpick_snake_inv_icon -Missing:88: models/darkmod/player_equipment/lockpick_snake_inv_icon -Missing:93: models/darkmod/player_equipment/lockpick_triangle_inv_icon -Missing:94: models/darkmod/player_equipment/lockpick_triangle_inv_icon - -materials/guard.mtr -Missing:5: models/guard/guard -Missing:15: models/guard/guard -Missing:25: models/guard/guardarmour -Missing:35: models/guard/guardarmour -Missing:47: models/chars/undead/revenant/skirtacol -Missing:51: models/chars/builders/guard/builder_local -Missing:52: models/chars/undead/revenant/skirt_s -Missing:62: models/chars/undead/revenant/skirtacol -Missing:74: models/chars/undead/revenant/hauntarmor_d -Missing:78: models/chars/builders/guard/builderarmor_local -Missing:79: models/chars/undead/revenant/hauntarmor_s -Missing:89: models/chars/undead/revenant/hauntarmor_d - -materials/architecture.mtr -Missing:307: textures/darkmod/nature/plant_02 -Missing:314: textures/darkmod/nature/plant_02 -Missing:326: textures/darkmod/nature/plant_02 -//this is called plant02 without underscore >> corrected - -Missing:334: textures/gw_dm1/tree/bark_02 -Missing:338: textures/gw_dm1/tree/bark_02 -Missing:339: textures/gw_dm1/tree/bark_02_local -Missing:349: textures/gw_dm1/tree/bark_02 -//there is no gw_dm1 folder, texture might be in darkmod/nature) >> corrected, found it in models/darkmod/props/textures/ \ No newline at end of file diff --git a/scripts/texture_reorg/logfile_rename.txt b/scripts/texture_reorg/logfile_rename.txt deleted file mode 100644 index eaad984ad..000000000 --- a/scripts/texture_reorg/logfile_rename.txt +++ /dev/null @@ -1,2477 +0,0 @@ -Caching material files... -No material: [textures/darkmod/decals/dirt] dripping_slime01 dripping_slime01.tga -No material: [textures/darkmod/decals/dirt] dripping_slime01_light dripping_slime01_light.tga -No material: [textures/darkmod/decals/dirt] dripping_slime02 dripping_slime02.tga -No material: [textures/darkmod/decals/dirt] dripping_slime03 dripping_slime03.tga -No material: [textures/darkmod/decals/dirt] dripping_slime04 dripping_slime04.tga -No material: [textures/darkmod/decals/dirt] long_drip_pattern01 long_drip_pattern01.tga -No material: [textures/darkmod/decals/dirt] scattered_dirt01 scattered_dirt01.tga -No material: [textures/darkmod/decals/dirt] splat01 splat01.tga -No material: [textures/darkmod/decals/dirt] splat02 splat02.tga -No material: [textures/darkmod/decals/dirt] splat_small03 splat_small03.tga -No material: [textures/darkmod/decals/dirt] wall_grime01 wall_grime01.tga -No material: [textures/darkmod/decals/dirt] wall_grime02 wall_grime02.tga -No material: [textures/darkmod/decals/dirt] wall_grime03 wall_grime03.tga -No material: [textures/darkmod/decals/dirt] wall_grime04 wall_grime04.tga -No material: [textures/darkmod/decals/dirt] wall_grime05 wall_grime05.tga -No material: [textures/darkmod/decals/vegetation] autumn_leaves_thick01 autumn_leaves_thick01.tga -No material: [textures/darkmod/decals/vegetation] dead_leaves_few01 dead_leaves_few01.tga -No material: [textures/darkmod/decals/vegetation] ivy_004_ed ivy_scattered_branches_ed.jpg.ivy_004_ed.jpg -No material: [textures/darkmod/decals/vegetation] plant02 tropical_fern01.tga.plant02.tga -No material: [textures/darkmod/door/metal] large_warehouse_old_green01 large_warehouse_old_green01.tga -No material: [textures/darkmod/door/metal] large_warehouse_old_local large_warehouse_old_local.tga -No material: [textures/darkmod/door/metal] large_warehouse_old_s large_warehouse_old_s.tga -No material: [textures/darkmod/door/metal] simple_rough01 simple_rough01.tga -No material: [textures/darkmod/door/metal] simple_rough01_local simple_rough01_local.tga -No material: [textures/darkmod/door/wood] board_plainblue_hinge01 board_plainblue_hinge01.tga -No material: [textures/darkmod/door/wood] board_plainblue_hinge02 board_plainblue_hinge02.tga -No material: [textures/darkmod/door/wood] board_plain_hinge01 board_plain_hinge01.tga -No material: [textures/darkmod/door/wood] board_plain_hinge01_local board_plain_hinge01_local.tga -No material: [textures/darkmod/door/wood] board_plain_hinge02 board_plain_hinge02.tga -No material: [textures/darkmod/door/wood] board_plain_hinge02_local board_plain_hinge02_local.tga -No material: [textures/darkmod/door/wood] board_withwindow_green01 board_withwindow_green01.tga -No material: [textures/darkmod/map_specific/bonehoard/env] water_entrance_back water_entrance_back.tga -No material: [textures/darkmod/map_specific/bonehoard/env] water_entrance_down water_entrance_down.tga -No material: [textures/darkmod/map_specific/bonehoard/env] water_entrance_forward water_entrance_forward.tga -No material: [textures/darkmod/map_specific/bonehoard/env] water_entrance_left water_entrance_left.tga -No material: [textures/darkmod/map_specific/bonehoard/env] water_entrance_right water_entrance_right.tga -No material: [textures/darkmod/metal/flat] gen_detail gen_detail.tga -No material: [textures/darkmod/metal/flat/nontiling] metalpole_d roughedup_steel.tga.metalpole_d.tga -No material: [textures/darkmod/metal/flat/nontiling] metalpole_s roughedup_steel_s.tga.metalpole_s.tga -No material: [textures/darkmod/roof] rt_woodenrooftiles01_d slats_uneven_wood01.tga.rt_woodenrooftiles01_d.tga -No material: [textures/darkmod/roof] rt_woodenrooftiles01_local slats_uneven_wood01_local.tga.rt_woodenrooftiles01_local.tga -No material: [textures/darkmod/stone/flat] concrete2_d slate02_dark.tga.concrete2_d.tga -No material: [textures/darkmod/stone/flat] concrete_local slate02_local.tga.concrete_local.tga -No material: [textures/darkmod/stone/flat/smooth] manfloor02_local marble_pattern01_local.tga.manfloor02_local.tga -No material: [textures/darkmod/window] horizontal_old_smallpanels01_dark horizontal_old_smallpanels01_dark.tga -No material: [textures/darkmod/window] horizontal_old_smallpanels01_dark_s horizontal_old_smallpanels01_dark_s.tga -No material: [textures/darkmod/window] horizontal_old_smallpanels01_local horizontal_old_smallpanels01_local.tga -No material: [textures/darkmod/window] square_old_smallpanels01_dark square_old_smallpanels01_dark.tga -No material: [textures/darkmod/window] square_old_smallpanels01_local square_old_smallpanels01_local.tga -No material: [textures/darkmod/window] square_old_smallpanels01_s square_old_smallpanels01_s.tga -No material: [textures/darkmod/window/ornate] winboth1_blend pointedtop_stainglass01_blend.tga.winboth1_blend.tga -No material: [textures/darkmod/window/ornate] winboth2_blend pointedtop_stainglass01_blend2.tga.winboth2_blend.tga -No material: [textures/darkmod/window/ornate] winboth1 pointedtop_stainglass01_blue.tga.winboth1.tga -No material: [textures/darkmod/window/ornate] winboth1_local pointedtop_stainglass01_local.tga.winboth1_local.tga -No material: [textures/darkmod/window/ornate] winboth1_s pointedtop_stainglass01_s.tga.winboth1_s.tga -No material: [textures/darkmod/wood/boards] medieval010 old_01.tga.medieval010.tga -No material: [textures/darkmod/wood/boards] medieval010_h old_01_h.tga.medieval010_h.tga -No material: [textures/darkmod/wood/boards] medieval010_s old_01_s.tga.medieval010_s.tga -No material: [textures/darkmod/wood/panels] manwtrim05_local thin_panels_with_trim_light_local.tga.manwtrim05_local.tga -svn move textures/darkmod/set/rugs/setrug01.tga textures/darkmod/carpet/rugs/ornate_black_gold01.tga -svn move textures/darkmod/set/rugs/setrug01_local.tga textures/darkmod/carpet/rugs/ornate_black_gold01_local.tga -svn move textures/darkmod/set/rugs/setrug02.tga textures/darkmod/carpet/rugs/ornate_floral_checker01.tga -svn move textures/darkmod/set/rugs/setrug02_local.tga textures/darkmod/carpet/rugs/ornate_floral_checker01_local.tga -svn move textures/darkmod/set/rugs/setrug03sh.tga textures/darkmod/carpet/rugs/ornate_green_black01.tga -svn move textures/darkmod/set/rugs/setrug03sh_local.tga textures/darkmod/carpet/rugs/ornate_green_black01_local.tga -svn move textures/darkmod/set/rugs/setrug03.tga textures/darkmod/carpet/rugs/ornate_rectangles_brown01.tga -svn move textures/darkmod/set/rugs/setrug03_local.tga textures/darkmod/carpet/rugs/ornate_rectangles_brown01_local.tga -svn move textures/darkmod/set/rugs/setrug01sh.tga textures/darkmod/carpet/rugs/ornate_red_tan01.tga -svn move textures/darkmod/set/rugs/setrug01sh_local.tga textures/darkmod/carpet/rugs/ornate_red_tan01_local.tga -svn move textures/darkmod/set/rugs/setrug02sh.tga textures/darkmod/carpet/rugs/ornate_red_tan02.tga -svn move textures/darkmod/set/rugs/setrug02sh_local.tga textures/darkmod/carpet/rugs/ornate_red_tan02_local.tga -svn move textures/darkmod/set/rugs/setrug04end_local.tga textures/darkmod/carpet/runners/geometric01_end_local.tga -svn move textures/darkmod/set/rugs/setrug04cen_local.tga textures/darkmod/carpet/runners/geometric01_local.tga -svn move textures/darkmod/set/rugs/setrug04cen.tga textures/darkmod/carpet/runners/geometric01_red.tga -svn move textures/darkmod/set/rugs/setrug04end.tga textures/darkmod/carpet/runners/geometric01_red_end.tga -No texturefile found: dripping_slime01 -No valid path for: dripping_slime01 -No texturefile found: dripping_slime01_light -No valid path for: dripping_slime01_light -No texturefile found: dripping_slime02 -No valid path for: dripping_slime02 -No texturefile found: dripping_slime03 -No valid path for: dripping_slime03 -No texturefile found: dripping_slime04 -No valid path for: dripping_slime04 -svn move textures/darkmod/bonehoard/dirt_002.tga textures/darkmod/decals/dirt/dripping_slime05.tga -svn move textures/darkmod/bonehoard/dirt_002_edge_left.tga textures/darkmod/decals/dirt/dripping_slime05_left.tga -svn move textures/darkmod/bonehoard/dirt_002_edge_right.tga textures/darkmod/decals/dirt/dripping_slime05_right.tga -No texturefile found: long_drip_pattern01 -No valid path for: long_drip_pattern01 -svn move textures/darkmod/foliage/trim/moss_d.tga textures/darkmod/decals/dirt/moss_patch_thick01.tga -svn move textures/darkmod/foliage/trim/moss_local.tga textures/darkmod/decals/dirt/moss_patch_thick01.tga -No texturefile found: scattered_dirt01 -No valid path for: scattered_dirt01 -svn move textures/darkmod/bonehoard/dirt_001.tga textures/darkmod/decals/dirt/scattered_dirt02.tga -No texturefile found: splat01 -No valid path for: splat01 -No texturefile found: splat02 -No valid path for: splat02 -No texturefile found: splat_small03 -No valid path for: splat_small03 -svn move textures/darkmod/bonehoard/torch_smut_ceiling.tga dds/textures/darkmod/decals/dirt/torch_smut_ceiling.tga -svn move textures/darkmod/bonehoard/torch_smut_wall.tga dds/textures/darkmod/decals/dirt/torch_smut_wall.tga -No texturefile found: wall_grime01 -No valid path for: wall_grime01 -No texturefile found: wall_grime02 -No valid path for: wall_grime02 -No texturefile found: wall_grime03 -No valid path for: wall_grime03 -No texturefile found: wall_grime04 -No valid path for: wall_grime04 -No texturefile found: wall_grime05 -No valid path for: wall_grime05 -svn move textures/darkmod/pagan/decal/pagdecvoyn.tga textures/darkmod/decals/symbols/magical_letters_row01.tga -svn move textures/darkmod/pagan/decal/pagdecfleur.tga textures/darkmod/decals/symbols/magic_symbol_circle01.tga -No texturefile found: autumn_leaves_thick01 -No valid path for: autumn_leaves_thick01 -No texturefile found: dead_leaves_few01 -No valid path for: dead_leaves_few01 -svn move textures/darkmod/nature/natural01.tga textures/darkmod/decals/vegetation/hanging_horizontal_leaves.tga -svn move textures/darkmod/nature/natural01_local.tga textures/darkmod/decals/vegetation/hanging_horizontal_leaves_local.tga -svn move textures/darkmod/nature/natural01_s.tga textures/darkmod/decals/vegetation/hanging_horizontal_leaves_s.tga -svn move dds/textures/darkmod/foliage/trim/ivy_001_patch1.dds dds/textures/darkmod/decals/vegetation/ivypatch_average01.dds -svn move dds/textures/darkmod/foliage/trim/ivy_001_patch2.dds dds/textures/darkmod/decals/vegetation/ivypatch_large01.dds -svn move dds/textures/darkmod/foliage/trim/ivy_001_small1.dds dds/textures/darkmod/decals/vegetation/ivypatch_small01.dds -svn move dds/textures/darkmod/foliage/trim/ivy_001_small2.dds dds/textures/darkmod/decals/vegetation/ivypatch_tiny01.dds -svn move textures/darkmod/foliage/trim/ivy_002.tga textures/darkmod/decals/vegetation/ivy_mixed_pieces.tga -svn move textures/darkmod/foliage/trim/ivy_002_ed.jpg textures/darkmod/decals/vegetation/ivy_mixed_pieces_ed.jpg -svn move textures/darkmod/foliage/trim/ivy_002_local.tga textures/darkmod/decals/vegetation/ivy_mixed_pieces_local.tga -svn move textures/darkmod/foliage/trim/ivy_002_s.tga textures/darkmod/decals/vegetation/ivy_mixed_pieces_s.tga -svn move textures/darkmod/foliage/trim/ivy_004.tga textures/darkmod/decals/vegetation/ivy_scattered_branches.tga -svn move textures/darkmod/foliage/trim/ivy_004_ed.jpg dds/textures/darkmod/decals/vegetation/ivy_scattered_branches_ed.jpg -svn move textures/darkmod/foliage/trim/ivy_004_local.tga textures/darkmod/decals/vegetation/ivy_scattered_branches_local.tga -svn move textures/darkmod/foliage/trim/ivy_004_s.tga textures/darkmod/decals/vegetation/ivy_scattered_branches_s.tga -svn move textures/darkmod/foliage/trim/ivy_003.tga textures/darkmod/decals/vegetation/ivy_vertical_branches.tga -svn move textures/darkmod/foliage/trim/ivy_003_ed.jpg textures/darkmod/decals/vegetation/ivy_vertical_branches_ed.jpg -svn move textures/darkmod/foliage/trim/ivy_003_local.tga textures/darkmod/decals/vegetation/ivy_vertical_branches_local.tga -svn move textures/darkmod/foliage/trim/ivy_003_s.tga textures/darkmod/decals/vegetation/ivy_vertical_branches_s.tga -svn move textures/darkmod/nature/plant01.tga textures/darkmod/decals/vegetation/tropical_broadleaf.tga -svn move textures/darkmod/nature/plant02.tga dds/textures/darkmod/decals/vegetation/tropical_fern01.tga -No texturefile found: large_warehouse_old_green01 -No valid path for: large_warehouse_old_green01 -No texturefile found: large_warehouse_old_local -No valid path for: large_warehouse_old_local -No texturefile found: large_warehouse_old_s -No valid path for: large_warehouse_old_s -No texturefile found: simple_rough01 -No valid path for: simple_rough01 -No texturefile found: simple_rough01_local -No valid path for: simple_rough01_local -No texturefile found: board_plainblue_hinge01 -No valid path for: board_plainblue_hinge01 -No texturefile found: board_plainblue_hinge02 -No valid path for: board_plainblue_hinge02 -No texturefile found: board_plain_hinge01 -No valid path for: board_plain_hinge01 -No texturefile found: board_plain_hinge01_local -No valid path for: board_plain_hinge01_local -No texturefile found: board_plain_hinge02 -No valid path for: board_plain_hinge02 -No texturefile found: board_plain_hinge02_local -No valid path for: board_plain_hinge02_local -No texturefile found: board_withwindow_green01 -No valid path for: board_withwindow_green01 -svn move textures/darkmod/city/door/ctydoor01.tga textures/darkmod/door/wood/diamond_pattern01.tga -svn move textures/darkmod/city/door/ctydoor01_local.tga textures/darkmod/door/wood/diamond_pattern01_local.tag -svn move textures/darkmod/castle/door/casdoor01.tga textures/darkmod/door/wood/metalbands_crisscross01.tga -svn move textures/darkmod/castle/door/casdoor01_local.tga textures/darkmod/door/wood/metalbands_crisscross01_local.tga -svn move textures/darkmod/castle/door/casdoor01_s.tga textures/darkmod/door/wood/metalbands_crisscross01_s.tga -svn move dds/textures/darkmod/wood/door/antique_001.dds dds/textures/darkmod/door/wood/oldboards_metalspirals01.dds -svn move textures/darkmod/wood/door/antique_001_editor.tga textures/darkmod/door/wood/oldboards_metalspirals01_ed.tga -svn move textures/darkmod/wood/door/antique_001_local.tga textures/darkmod/door/wood/oldboards_metalspirals01_local.tga -svn move models/darkmod/door_related/warehouse_frontdoor_d.tga textures/darkmod/door/wood/old_4panels_peelingpaint01.tga -svn move textures/darkmod/mansion/door/mandoor01.tga textures/darkmod/door/wood/old_flat_oak01.tga -svn move textures/darkmod/mansion/door/mandoor01_local.tga textures/darkmod/door/wood/old_flat_oak01_local.tga -svn move textures/darkmod/mansion/door/mandoor01_s.tga textures/darkmod/door/wood/old_flat_oak01_s.tga -svn move textures/darkmod/wood/door/weathered_001_d.tga textures/darkmod/door/wood/old_weathered_boards01.tga -svn move textures/darkmod/wood/door/weathered_001_local.tga textures/darkmod/door/wood/old_weathered_boards01_local.tga -No texturefile found: warehouse_frontdoor_d -No valid path for: warehouse_frontdoor_d -svn move textures/darkmod/mansion/door/mandoor06.tga textures/darkmod/door/wood/smooth_2panels_rich.tga -svn move textures/darkmod/mansion/door/mandoor06_local.tga textures/darkmod/door/wood/smooth_2panels_rich_local.tga -svn move textures/darkmod/mansion/door/mandoor06_s.tga textures/darkmod/door/wood/smooth_2panels_rich_s.tga -svn move textures/darkmod/mansion/door/mandoor01sh.tga textures/darkmod/door/wood/smooth_3panels01_dull01.tga -svn move textures/darkmod/mansion/door/mandoor01sh_s.tga textures/darkmod/door/wood/smooth_3panels01_dull_s.tga -svn move textures/darkmod/mansion/door/mandoor01sh_local.tga textures/darkmod/door/wood/smooth_3panels01_remove_local.tga -svn move textures/darkmod/mansion/door/mandoor03_local.tga textures/darkmod/door/wood/smooth_3panels_local.tga -svn move textures/darkmod/mansion/door/mandoor03.tga textures/darkmod/door/wood/smooth_3panels_red01.tga -svn move textures/darkmod/mansion/door/mandoor02ab_local.tga textures/darkmod/door/wood/smooth_4panels_local.tga -svn move textures/darkmod/mansion/door/mandoor02b.tga textures/darkmod/door/wood/smooth_4panels_red01.tga -svn move textures/darkmod/mansion/door/mandoor02a.tga textures/darkmod/door/wood/smooth_4panels_tan01.tga -svn move textures/darkmod/mansion/door/mandoor04.tga textures/darkmod/door/wood/ornate/smooth_rich_ovalwindow01.tga -svn move textures/darkmod/mansion/door/mandoor04_local.tga textures/darkmod/door/wood/ornate/smooth_rich_ovalwindow01_local.tga -svn move textures/darkmod/mansion/door/mandoor04_s.tga textures/darkmod/door/wood/ornate/smooth_rich_ovalwindow01_s.tga -svn move textures/darkmod/mansion/door/mandoor05.tga textures/darkmod/door/wood/ornate/smooth_rich_squarewindow01.tga -svn move textures/darkmod/sfx/mandoor05_withalpha.tga textures/darkmod/door/wood/ornate/smooth_rich_squarewindow01_alpha.tga -svn move textures/darkmod/mansion/door/mandoor05_local.tga textures/darkmod/door/wood/ornate/smooth_rich_squarewindow01_local.tga -svn move textures/darkmod/mansion/door/mandoor05_s.tga textures/darkmod/door/wood/ornate/smooth_rich_squarewindow01_s.tga -svn move textures/darkmod/bonehoard/env/water_entrance_back.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_back.tga -svn move textures/darkmod/bonehoard/env/water_entrance_down.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_down.tga -svn move textures/darkmod/bonehoard/env/water_entrance_forward.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_forward.tga -svn move textures/darkmod/bonehoard/env/water_entrance_left.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_left.tga -svn move textures/darkmod/bonehoard/env/water_entrance_right.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_right.tga -svn move textures/darkmod/bonehoard/env/water_entrance_up.tga dds/textures/darkmod/map_specific/bonehoard/env/water_entrance_up.tga -svn move textures/darkmod/castle/wall/caswpanel01b.tga textures/darkmod/metal/detailed/panel_circledesign01_brown.tga -svn move textures/darkmod/castle/wall/caswpanel01.tga textures/darkmod/metal/detailed/panel_circledesign01_green.tga -svn move textures/darkmod/castle/wall/caswpanel01_local.tga textures/darkmod/metal/detailed/panel_circledesign01_local.tga -svn move textures/darkmod/castle/wall/caswpanel02.tga dds/textures/darkmod/metal/detailed/panel_circledesign_ornate01_green.tga -svn move textures/darkmod/castle/wall/caswpanel02_local.tga textures/darkmod/metal/detailed/panel_circledesign_ornate01_local.tga -svn move textures/darkmod/metal/gen/gen_detail.tga dds/textures/darkmod/metal/flat/gen_detail.tga -svn move dds/textures/darkmod/metal/floor/rust_002_d.DDS dds/textures/darkmod/metal/flat/heavy_rust_pocked01.dds -svn move textures/darkmod/metal/floor/rust_002_ed.tga textures/darkmod/metal/flat/heavy_rust_pocked01_ed.tga -svn move textures/darkmod/metal/floor/rust_002_local.tga textures/darkmod/metal/flat/heavy_rust_pocked_local.tga -svn move dds/textures/darkmod/metal/floor/rust_002_s.DDS dds/textures/darkmod/metal/flat/heavy_rust_pocked_s.dds -svn move textures/darkmod/city/wall/metal01_d.tga textures/darkmod/metal/flat/simple_grey01.tga -svn move textures/darkmod/city/wall/metal01_local.tga textures/darkmod/metal/flat/simple_grey01_local.tga -svn move textures/darkmod/city/wall/metal01_s.tga textures/darkmod/metal/flat/simple_grey01_s.tga -svn move dds/textures/darkmod/metal/flat/simple_rough_grey01_d.DDS dds/textures/darkmod/metal/flat/simple_rough_grey01.dds -svn move textures/darkmod/metal/flat/simple_rough_grey01_ed.tga textures/darkmod/metal/flat/simple_rough_grey01_ed.tga -svn move textures/darkmod/metal/flat/simple_rough_grey01_local.tga textures/darkmod/metal/flat/simple_rough_grey01_local.tga -svn move dds/textures/darkmod/metal/floor/rust_003_d.DDS dds/textures/darkmod/metal/flat/solid_rust01.dds -svn move textures/darkmod/metal/floor/rust_003_ed.tga textures/darkmod/metal/flat/solid_rust01_ed.tga -svn move textures/darkmod/metal/floor/rust_003_local.tga textures/darkmod/metal/flat/solid_rust01_local.tga -svn move dds/textures/darkmod/metal/floor/rust_005.dds dds/textures/darkmod/metal/flat/solid_rust02.dds -svn move textures/darkmod/metal/floor/rust_005_editor.jpg textures/darkmod/metal/flat/solid_rust02_ed.jpg -svn move textures/darkmod/metal/floor/rust_005_local.tga textures/darkmod/metal/flat/solid_rust02_local.tga -svn move dds/textures/darkmod/metal/floor/rust_005_s.dds dds/textures/darkmod/metal/flat/solid_rust02_s.dds -No texturefile found: metalpole_d -No valid path for: metalpole_d -No texturefile found: metalpole_s -No valid path for: metalpole_s -svn move textures/darkmod/metal/gen/rust_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01.tga -svn move textures/darkmod/metal/gen/rust_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01_local.tga -svn move textures/darkmod/metal/gen/rust_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01_s.tga -svn move textures/darkmod/metal/gen/gen_default_framed_d.tga dds/textures/darkmod/metal/flat/tiling_1d/gen_default_framed_d.tga -svn move textures/darkmod/metal/gen/gen_default_framed_local.tga dds/textures/darkmod/metal/flat/tiling_1d/gen_default_framed_local.tga -svn move textures/darkmod/metal/gen/gen_default_framed_s.tga dds/textures/darkmod/metal/flat/tiling_1d/gen_default_framed_s.tga -svn move textures/darkmod/metal/gen/iron_002_d.tga textures/darkmod/metal/flat/tiling_1d/gen_ornate_iron01.tga -svn move textures/darkmod/metal/gen/paintedmetal_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01.tga -svn move textures/darkmod/metal/gen/paintedmetal_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01_local.tga -svn move textures/darkmod/metal/gen/paintedmetal_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01_s.tga -svn move textures/darkmod/metal/gen/brushedmetal_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01.tga -svn move textures/darkmod/metal/gen/brushedmetal_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01_local.tga -svn move textures/darkmod/metal/gen/brushedmetal_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01_s.tga -svn move textures/darkmod/metal/gen/bronze_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01.tga -svn move textures/darkmod/metal/gen/bronze_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01_local.tga -svn move textures/darkmod/metal/gen/bronze_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01_s.tga -svn move textures/darkmod/metal/gen/copper_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01.tga -svn move textures/darkmod/metal/gen/copper_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01_local.tga -svn move textures/darkmod/metal/gen/copper_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01_s.tga -svn move textures/darkmod/metal/gen/gold_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01.tga -svn move textures/darkmod/metal/gen/gold_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01_local.tga -svn move textures/darkmod/metal/gen/gold_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01_s.tga -svn move textures/darkmod/metal/gen/iron_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01.tga -svn move textures/darkmod/metal/gen/iron_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01_local.tga -svn move textures/darkmod/metal/gen/iron_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01_s.tga -svn move textures/darkmod/metal/gen/silver_001_d.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01.tga -svn move textures/darkmod/metal/gen/silver_001_local.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01_local.tga -svn move textures/darkmod/metal/gen/silver_001_s.tga textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01_s.tga -svn move dds/textures/darkmod/stone/wall/cement_012.dds dds/textures/darkmod/metal/flat/tiling_1d/rough_dirty01.dds -svn move textures/darkmod/stone/wall/cement_012_editor.tga textures/darkmod/metal/flat/tiling_1d/rough_dirty01_ed.tga -svn move textures/darkmod/stone/wall/cement_012_local.tga textures/darkmod/metal/flat/tiling_1d/rough_dirty01_local.tga -svn move dds/textures/darkmod/stone/wall/cement_014.dds dds/textures/darkmod/metal/flat/tiling_1d/rough_iron01.dds -svn move textures/darkmod/stone/wall/cement_014_editor.tga textures/darkmod/metal/flat/tiling_1d/rough_iron01_ed.tga -svn move textures/darkmod/stone/wall/cement_014_local.tga textures/darkmod/metal/flat/tiling_1d/rough_iron01_local.tga -svn move dds/textures/darkmod/stone/wall/cement_011.dds dds/textures/darkmod/metal/flat/tiling_1d/rough_rusted01.dds -svn move textures/darkmod/stone/wall/cement_011_editor.tga textures/darkmod/metal/flat/tiling_1d/rough_rusted01_ed.tga -svn move textures/darkmod/stone/wall/cement_011_local.tga textures/darkmod/metal/flat/tiling_1d/rough_rusted01_local.tga -svn move dds/textures/darkmod/stone/wall/cement_011_s.dds dds/textures/darkmod/metal/flat/tiling_1d/rough_rusted01_s.dds -svn move dds/textures/darkmod/metal/floor/grating_001.dds dds/textures/darkmod/metal/grate/dimpled_grating01.dds -svn move textures/darkmod/metal/floor/grating_001_editor.jpg textures/darkmod/metal/grate/dimpled_grating01_ed.jpg -svn move textures/darkmod/metal/floor/grating_001_local.tga textures/darkmod/metal/grate/dimpled_grating01_local.tga -svn move dds/textures/darkmod/metal/floor/grating_001_s.dds dds/textures/darkmod/metal/grate/dimpled_grating01_s.dds -svn move textures/darkmod/foliage/floor/flowers_pink_01.tga dds/textures/darkmod/nature/foliage/flowers_pink_01.tga -svn move textures/darkmod/foliage/floor/flowers_pink_01_local.tga dds/textures/darkmod/nature/foliage/flowers_pink_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_violet_01.tga dds/textures/darkmod/nature/foliage/flowers_violet_01.tga -svn move textures/darkmod/foliage/floor/flowers_violet_01_local.tga dds/textures/darkmod/nature/foliage/flowers_violet_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_violet_02.tga dds/textures/darkmod/nature/foliage/flowers_violet_02.tga -svn move textures/darkmod/foliage/floor/flowers_violet_02_local.tga dds/textures/darkmod/nature/foliage/flowers_violet_02_local.tga -svn move dds/textures/darkmod/foliage/wall/hedge_001.dds dds/textures/darkmod/nature/foliage/hedge_001.dds -svn move textures/darkmod/foliage/wall/hedge_001_editor.tga dds/textures/darkmod/nature/foliage/hedge_001_editor.tga -svn move textures/darkmod/foliage/wall/hedge_001_local.tga textures/darkmod/nature/foliage/hedge_001_local.tga -svn move textures/darkmod/foliage/floor/flowers_blueviolet_01.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_blueviolet_01.tga -svn move textures/darkmod/foliage/floor/flowers_blueviolet_01_local.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_blueviolet_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_mixed_01.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_mixed_01.tga -svn move textures/darkmod/foliage/floor/flowers_mixed_01_local.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_mixed_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_redyellow_01.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_redyellow_01.tga -svn move textures/darkmod/foliage/floor/flowers_redyellow_01_local.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_redyellow_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_red_01.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_red_01.tga -svn move textures/darkmod/foliage/floor/flowers_red_01_local.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_red_01_local.tga -svn move textures/darkmod/foliage/floor/flowers_white_01.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_white_01.tga -svn move textures/darkmod/foliage/floor/flowers_white_01_local.tga dds/textures/darkmod/nature/foliage/nontiling/flowers_white_01_local.tga -svn move textures/darkmod/nature/grass01.tga dds/textures/darkmod/nature/grass/short_patchy_grass01.tga -svn move textures/darkmod/nature/grass01_local.tga textures/darkmod/nature/grass/short_patchy_grass01_local.tga -svn move textures/darkmod/nature/grass02.tga textures/darkmod/nature/grass/thick_grass01.tga -svn move textures/darkmod/nature/grass02_local.tga textures/darkmod/nature/grass/thick_grass01_local.tga -svn move textures/darkmod/nature/straw01.tga textures/darkmod/nature/grass/nontiling/thick_straw01.tga -svn move textures/darkmod/nature/straw01_local.tga textures/darkmod/nature/grass/nontiling/thick_straw01_local.tga -Multiple textures found: ['/home/sparhawk/darkmod/textures/darkmod/sky/dm_sqsky/dm_sqsky.tga', '/home/sparhawk/darkmod/dds/textures/darkmod/nature/skybox/dm_sqsky/dm_sqsky.tga'] -No valid path for: dm_sqsky -svn move textures/darkmod/sky/starry1/clouds.tga dds/textures/darkmod/nature/skybox/starry1/clouds.tga -svn move textures/darkmod/sky/starry1/clouds2.tga dds/textures/darkmod/nature/skybox/starry1/clouds2.tga -svn move textures/darkmod/sky/starry1/moon.tga dds/textures/darkmod/nature/skybox/starry1/moon.tga -svn move textures/darkmod/sky/starry1/moon_crescent.tga dds/textures/darkmod/nature/skybox/starry1/moon_crescent.tga -svn move textures/darkmod/sky/starry1/moon_crescent_editor.tga dds/textures/darkmod/nature/skybox/starry1/moon_crescent_editor.tga -svn move textures/darkmod/sky/starry1/moon_editor.tga dds/textures/darkmod/nature/skybox/starry1/moon_editor.tga -svn move textures/darkmod/sky/starry1/moon_full.tga dds/textures/darkmod/nature/skybox/starry1/moon_full.tga -svn move textures/darkmod/sky/starry1/moon_full_editor.tga dds/textures/darkmod/nature/skybox/starry1/moon_full_editor.tga -svn move textures/darkmod/sky/starry1/moon_full_glared.tga dds/textures/darkmod/nature/skybox/starry1/moon_full_glared.tga -svn move textures/darkmod/sky/starry1/moon_gibbous.tga dds/textures/darkmod/nature/skybox/starry1/moon_gibbous.tga -svn move textures/darkmod/sky/starry1/moon_gibbous_editor.tga dds/textures/darkmod/nature/skybox/starry1/moon_gibbous_editor.tga -svn move textures/darkmod/sky/starry1/moon_quarter.tga dds/textures/darkmod/nature/skybox/starry1/moon_quarter.tga -svn move textures/darkmod/sky/starry1/moon_quarter_editor.tga dds/textures/darkmod/nature/skybox/starry1/moon_quarter_editor.tga -svn move textures/darkmod/sky/starry1/stars.tga dds/textures/darkmod/nature/skybox/starry1/stars.tga -svn move textures/darkmod/sky/starry1/white.tga dds/textures/darkmod/nature/skybox/starry1/white.tga -svn move dds/textures/darkmod/snow/floor/icy_001.dds dds/textures/darkmod/nature/snow/plain_ice01.dds -svn move textures/darkmod/snow/floor/icy_001_editor.tga textures/darkmod/nature/snow/plain_ice01_ed.tga -svn move textures/darkmod/snow/floor/icy_001_local.tga textures/darkmod/nature/snow/plain_ice01_local.tga -svn move dds/textures/darkmod/snow/floor/icy_001_s.dds dds/textures/darkmod/nature/snow/plain_ice01_s.dds -svn move dds/textures/darkmod/snow/floor/rippled_001.dds dds/textures/darkmod/nature/snow/plain_snow01.dds -svn move textures/darkmod/snow/floor/rippled_001_local.tga textures/darkmod/nature/snow/plain_snow01_local.tga -svn move textures/darkmod/mansion/wall/manwall03.tga textures/darkmod/paint_paper/wallpaper_flowers_01.tga -svn move textures/darkmod/mansion/wall/manwall03_local.tga textures/darkmod/paint_paper/wallpaper_flowers_01_local.tga -svn move textures/darkmod/mansion/wall/manwall04b.tga textures/darkmod/paint_paper/wallpaper_ornamental_01_blue.tga -svn move textures/darkmod/mansion/wall/manwall04c.tga textures/darkmod/paint_paper/wallpaper_ornamental_01_green.tga -svn move textures/darkmod/mansion/wall/manwall04_local.tga textures/darkmod/paint_paper/wallpaper_ornamental_01_local.tga -svn move textures/darkmod/mansion/wall/manwall04a.tga textures/darkmod/paint_paper/wallpaper_ornamental_01_pink.tga -svn move textures/darkmod/mansion/wall/manwall04d.tga textures/darkmod/paint_paper/wallpaper_ornamental_01_red.tga -svn move textures/darkmod/mansion/wall/manwall05.tga textures/darkmod/paint_paper/wallpaper_ornamental_02_white.tga -svn move textures/darkmod/mansion/wall/manwall05_local.tga textures/darkmod/paint_paper/wallpaper_ornamental_02_white_local.tga -svn move textures/darkmod/city/roof/ctyroof02.tga textures/darkmod/roof/shingle_dullbrown01.tga -svn move textures/darkmod/city/roof/ctyroof02_local.tga textures/darkmod/roof/shingle_dullbrown01_local.tga -svn move textures/darkmod/city/roof/rooftile_01_d.tga textures/darkmod/roof/shingle_shiny_greenish01.tga -svn move textures/darkmod/city/roof/rooftile_01_local.tga textures/darkmod/roof/shingle_shiny_greenish01_local.tga -svn move textures/darkmod/city/roof/rooftile_01_s.tga textures/darkmod/roof/shingle_shiny_greenish01_s.tga -svn move textures/darkmod/city/roof/ctyroof01.tga textures/darkmod/roof/slate_uneven_withmoss01.tga -svn move textures/darkmod/city/roof/ctyroof01_local.tga textures/darkmod/roof/slate_uneven_withmoss01_local.tga -svn move textures/darkmod/city/roof/rt_woodenrooftiles01_d.tga dds/textures/darkmod/roof/slats_uneven_wood01.tga -svn move textures/darkmod/city/roof/rt_woodenrooftiles01_local.tga dds/textures/darkmod/roof/slats_uneven_wood01_local.tga -svn move textures/darkmod/sfx/blueglass.tga dds/textures/darkmod/sfx/blueglass.tga -svn move textures/darkmod/sfx/greenglass.tga dds/textures/darkmod/sfx/greenglass.tga -svn move textures/darkmod/sfx/light_rays.tga dds/textures/darkmod/sfx/light_rays.tga -svn move textures/darkmod/mansion/door/mandoor05_local.tga dds/textures/darkmod/sfx/mandoor05_local.tga -svn move textures/darkmod/sfx/mandoor05_withalpha.tga dds/textures/darkmod/sfx/mandoor05_withalpha.tga -svn move textures/darkmod/sfx/manwindow02b_withalpha.tga dds/textures/darkmod/sfx/manwindow02b_withalpha.tga -svn move textures/darkmod/sfx/redglass.tga dds/textures/darkmod/sfx/redglass.tga -svn move textures/darkmod/sfx/whiteglass.tga dds/textures/darkmod/sfx/whiteglass.tga -svn move dds/textures/darkmod/stone/floor/brick_006.dds dds/textures/darkmod/stone/brick/even_greyish01.dds -svn move textures/darkmod/stone/floor/brick_006_editor.tga textures/darkmod/stone/brick/even_greyish01_ed.tga -svn move textures/darkmod/stone/floor/brick_006_local.tga textures/darkmod/stone/brick/even_greyish01_local.tga -svn move dds/textures/darkmod/stone/floor/brick_006_trim.dds dds/textures/darkmod/stone/brick/even_greyish01_trim.dds -svn move textures/darkmod/stone/floor/brick_006_trim_editor.jpg textures/darkmod/stone/brick/even_greyish01_trim_ed.jpg -svn move textures/darkmod/stone/floor/brick_006_trim_local.tga textures/darkmod/stone/brick/even_greyish01_trim_local.tga -svn move textures/darkmod/stone/floor/blocks_019_editor.jpg textures/darkmod/stone/brick/even_small_blocks001_ed.jpg -svn move textures/darkmod/stone/floor/blocks_019_local.tga textures/darkmod/stone/brick/even_small_blocks001_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_019.dds dds/textures/darkmod/stone/brick/even_small_blocks01.dds -svn move textures/darkmod/city/wall/rt_largebrick01_d.tga textures/darkmod/stone/brick/grainy_blocks01.tga -svn move textures/darkmod/city/wall/rt_largebrick01_local.tga textures/darkmod/stone/brick/grainy_blocks01_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_017_d.DDS dds/textures/darkmod/stone/brick/grainy_large_blocks01.dds -svn move textures/darkmod/stone/floor/blocks_017_ed.tga textures/darkmod/stone/brick/grainy_large_blocks01_ed.tga -svn move textures/darkmod/stone/floor/blocks_017_local.tga textures/darkmod/stone/brick/grainy_large_blocks01_local.tga -svn move textures/darkmod/mansion/wall/manwbrick02.tga textures/darkmod/stone/brick/grey_protruding_bricks.tga -svn move textures/darkmod/mansion/wall/manwbrick02_local.tga textures/darkmod/stone/brick/grey_protruding_bricks_local.tga -svn move dds/textures/darkmod/stone/floor/brick_007_dark.dds dds/textures/darkmod/stone/brick/interlocking_angled_darkgrey.dds -svn move dds/textures/darkmod/stone/floor/brick_007.dds dds/textures/darkmod/stone/brick/interlocking_angled_grey.dds -svn move dds/textures/darkmod/stone/floor/brick_007_s.dds dds/textures/darkmod/stone/brick/interlocking_angled_grey01_s.dds -svn move textures/darkmod/stone/floor/brick_007_editor.tga textures/darkmod/stone/brick/interlocking_angled_grey_ed.tga -svn move textures/darkmod/stone/floor/brick_007_local.tga textures/darkmod/stone/brick/interlocking_angled_grey_local.tga -svn move dds/textures/darkmod/stone/floor/brick_007_yellow.dds dds/textures/darkmod/stone/brick/interlocking_angled_yellow.dds -svn move dds/textures/darkmod/stone/floor/cobble_005.dds dds/textures/darkmod/stone/brick/interlocking_mixedsize_dark.dds -svn move textures/darkmod/stone/floor/cobble_005_local.tga textures/darkmod/stone/brick/interlocking_mixedsize_dark.tga -svn move textures/darkmod/stone/floor/cobble_005_editor.tga textures/darkmod/stone/brick/interlocking_mixedsize_dark_ed.tga -svn move dds/textures/darkmod/stone/floor/brick_010_d.DDS dds/textures/darkmod/stone/brick/old_blocks_wornsmooth_dark.dds -svn move textures/darkmod/stone/floor/brick_010_ed.tga textures/darkmod/stone/brick/old_blocks_wornsmooth_dark_ed.tga -svn move textures/darkmod/stone/floor/brick_010_local.tga textures/darkmod/stone/brick/old_blocks_wornsmooth_dark_local.tga -svn move dds/textures/darkmod/stone/wall/brick_old_003.dds dds/textures/darkmod/stone/brick/old_dirty_bricks01.dds -svn move textures/darkmod/stone/wall/brick_old_003_editor.tga textures/darkmod/stone/brick/old_dirty_bricks01_ed.tga -svn move dds/textures/darkmod/stone/wall/brick_old_003_local.dds dds/textures/darkmod/stone/brick/old_dirty_bricks01_local.dds -svn move textures/darkmod/stone/wall/brick_old_003_local.tga dds/textures/darkmod/stone/brick/old_dirty_bricks01_local.tga -svn move dds/textures/darkmod/stone/wall/brick_old_001.dds dds/textures/darkmod/stone/brick/old_small_bricks_grey.dds -svn move textures/darkmod/stone/wall/brick_old_001_local.tga textures/darkmod/stone/brick/old_small_bricks_grey.tga -svn move textures/darkmod/stone/wall/brick_old_001_editor.tga textures/darkmod/stone/brick/old_small_bricks_grey_ed.tga -svn move dds/textures/darkmod/stone/floor/masonry_001_pillar.dds dds/textures/darkmod/stone/brick/pillar_bricks01.dds -svn move textures/darkmod/stone/floor/masonry_001_pillar_editor.jpg textures/darkmod/stone/brick/pillar_bricks01_ed.jpg -svn move textures/darkmod/stone/floor/masonry_001_pillar_local.tga textures/darkmod/stone/brick/pillar_bricks01_local.tga -svn move dds/textures/darkmod/stone/floor/masonry_001_pillar_s.dds dds/textures/darkmod/stone/brick/pillar_bricks01_s.dds -svn move textures/darkmod/city/wall/rt_redbrickvert01_d.tga textures/darkmod/stone/brick/redbrick_dull_small.tga -svn move textures/darkmod/city/wall/rt_redbrickvert01_local.tga textures/darkmod/stone/brick/redbrick_dull_small_local.tga -svn move dds/textures/darkmod/stone/floor/brick_008.dds dds/textures/darkmod/stone/brick/redbrick_mostly_mortar.dds -svn move textures/darkmod/stone/floor/brick_008_editor.tga textures/darkmod/stone/brick/redbrick_mostly_mortar_ed.tga -svn move textures/darkmod/stone/floor/brick_008_local.tga textures/darkmod/stone/brick/redbrick_mostly_mortar_local.tga -svn move dds/textures/darkmod/stone/floor/brick_004.dds dds/textures/darkmod/stone/brick/red_angled_ground.dds -svn move textures/darkmod/stone/floor/brick_004_editor.tga textures/darkmod/stone/brick/red_angled_ground_ed.tga -svn move textures/darkmod/stone/floor/brick_004_local.tga textures/darkmod/stone/brick/red_angled_ground_local.tga -svn move textures/darkmod/city/wall/ctywbrick02.tga textures/darkmod/stone/brick/red_brick_dull01.tga -svn move textures/darkmod/city/wall/ctywbrick02_local.tga textures/darkmod/stone/brick/red_brick_dull01_local.tga -svn move dds/textures/darkmod/stone/floor/brick_005.dds dds/textures/darkmod/stone/brick/red_sloppymortar.dds -svn move dds/textures/darkmod/stone/floor/brick_005_alpha.dds dds/textures/darkmod/stone/brick/red_sloppymortar_alpha.dds -svn move textures/darkmod/stone/floor/brick_005_editor.tga textures/darkmod/stone/brick/red_sloppymortar_ed.tga -svn move textures/darkmod/stone/floor/brick_005_inverted_local.tga textures/darkmod/stone/brick/red_sloppymortar_inverted_local.tga -svn move textures/darkmod/stone/floor/brick_005_local.tga textures/darkmod/stone/brick/red_sloppymortar_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_008.dds dds/textures/darkmod/stone/brick/rough_big_blocks01.dds -svn move textures/darkmod/stone/floor/blocks_008_editor.tga textures/darkmod/stone/brick/rough_big_blocks01_ed.tga -svn move textures/darkmod/stone/floor/blocks_008_local.tga textures/darkmod/stone/brick/rough_big_blocks01_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_009.dds dds/textures/darkmod/stone/brick/rough_big_blocks02.dds -svn move dds/textures/darkmod/stone/floor/blocks_009_cornerstone_dark.dds dds/textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_dark.dds -svn move textures/darkmod/stone/floor/blocks_009_cornerstone_dark_editor.tga textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_dark_ed.tga -svn move dds/textures/darkmod/stone/floor/blocks_009_cornerstone_light.dds dds/textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_light.dds -svn move textures/darkmod/stone/floor/blocks_009_cornerstone_light_editor.tga textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_light_ed.tga -svn move textures/darkmod/stone/floor/blocks_009_cornerstone_local.tga textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_local.tga -svn move textures/darkmod/stone/floor/blocks_009_editor.tga textures/darkmod/stone/brick/rough_big_blocks02_ed.tga -svn move textures/darkmod/stone/floor/blocks_009_local.tga textures/darkmod/stone/brick/rough_big_blocks02_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_010.dds dds/textures/darkmod/stone/brick/rough_big_blocks03.dds -svn move dds/textures/darkmod/stone/floor/blocks_010_cornerstone_dark.dds dds/textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_dark.dds -svn move textures/darkmod/stone/floor/blocks_010_cornerstone_dark_editor.tga textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_dark_ed.tga -svn move dds/textures/darkmod/stone/floor/blocks_010_cornerstone_light.dds dds/textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_light.dds -svn move textures/darkmod/stone/floor/blocks_010_cornerstone_light_editor.tga textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_light_ed.tga -svn move textures/darkmod/stone/floor/blocks_010_editor.tga textures/darkmod/stone/brick/rough_big_blocks03_ed.tga -svn move dds/textures/darkmod/stone/floor/blocks_013.dds dds/textures/darkmod/stone/brick/rough_big_blocks04_brown.dds -svn move dds/textures/darkmod/stone/floor/blocks_013_cornerstone_light.dds dds/textures/darkmod/stone/brick/rough_big_blocks04_brown_cornerstone_light.dds -svn move textures/darkmod/stone/floor/blocks_013_cornerstone_light_editor.tga textures/darkmod/stone/brick/rough_big_blocks04_brown_cornerstone_light_ed.tga -svn move textures/darkmod/stone/floor/blocks_013_editor.tga textures/darkmod/stone/brick/rough_big_blocks04_brown_ed.tga -svn move dds/textures/darkmod/stone/floor/blocks_014.dds dds/textures/darkmod/stone/brick/rough_big_blocks05.dds -svn move textures/darkmod/stone/floor/blocks_014_editor.tga textures/darkmod/stone/brick/rough_big_blocks05_ed.tga -svn move dds/textures/darkmod/stone/floor/brick_009_d.DDS dds/textures/darkmod/stone/brick/rough_blocks01.dds -svn move textures/darkmod/stone/floor/brick_009_ed.tga textures/darkmod/stone/brick/rough_blocks01_ed.tga -svn move textures/darkmod/stone/floor/brick_009_local.tga textures/darkmod/stone/brick/rough_blocks01_local.tga -svn move textures/darkmod/city/wall/ctywbrick01.tga textures/darkmod/stone/brick/rough_blocks02.tga -svn move textures/darkmod/city/wall/ctywbrick01_local.tga textures/darkmod/stone/brick/rough_blocks02_local.tga -svn move textures/darkmod/city/wall/ctywbrick04.tga textures/darkmod/stone/brick/rough_blocks_tight02.tga -svn move textures/darkmod/city/wall/ctywbrick04_local.tga textures/darkmod/stone/brick/rough_blocks_tight02_local.tga -svn move textures/darkmod/city/wall/ctywbrick04b.tga textures/darkmod/stone/brick/rough_blocks_tight02_moss.tga -svn move textures/darkmod/city/wall/ctywbrick04b_local.tga textures/darkmod/stone/brick/rough_blocks_tight02_moss_local.tga -svn move textures/darkmod/city/wall/ctywbrick03b.tga textures/darkmod/stone/brick/rough_blocks_tight_dark.tga -svn move textures/darkmod/city/wall/ctywbrick03.tga textures/darkmod/stone/brick/rough_blocks_tight_light.tga -svn move textures/darkmod/city/wall/ctywbrick03_local.tga textures/darkmod/stone/brick/rough_blocks_tight_local.tga -svn move textures/darkmod/city/wall/brick_dark_d.tga textures/darkmod/stone/brick/rough_brick_grey.tga -svn move textures/darkmod/city/wall/brick_dark_local.tga textures/darkmod/stone/brick/rough_brick_grey_local.tga -svn move textures/darkmod/city/wall/brick_dark_s.tga textures/darkmod/stone/brick/rough_brick_grey_s.tga -svn move dds/textures/darkmod/stone/trim/trim_003_d.DDS dds/textures/darkmod/stone/brick/single_grey_block01.dds -svn move textures/darkmod/stone/trim/trim_003_ed.tga textures/darkmod/stone/brick/single_grey_block01_ed.tga -svn move textures/darkmod/stone/trim/trim_003_local.tga textures/darkmod/stone/brick/single_grey_block01_local.tga -svn move dds/textures/darkmod/stone/floor/masonry_001_brick.dds dds/textures/darkmod/stone/brick/small_brown_bricks01.dds -svn move dds/textures/darkmod/stone/floor/masonry_001_brick_s.dds dds/textures/darkmod/stone/brick/small_brown_bricks01_s.dds -svn move textures/darkmod/stone/floor/masonry_001_brick_editor.jpg textures/darkmod/stone/brick/small_brown_bricks01_ed.jpg -svn move textures/darkmod/stone/floor/masonry_001_brick_local.tga textures/darkmod/stone/brick/small_brown_bricks01_local.tga -svn move textures/darkmod/mansion/wall/manwbrick01.tga textures/darkmod/stone/brick/tight_large_blocks.tga -svn move dds/textures/darkmod/stone/floor/blocks_015_d.DDS dds/textures/darkmod/stone/brick/tight_large_blocks01.dds -svn move textures/darkmod/stone/floor/blocks_015_ed.tga textures/darkmod/stone/brick/tight_large_blocks01_ed.tga -svn move textures/darkmod/stone/floor/blocks_015_local.tga textures/darkmod/stone/brick/tight_large_blocks01_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_015_s.DDS dds/textures/darkmod/stone/brick/tight_large_blocks01_s.dds -svn move textures/darkmod/mansion/wall/manwbrick01_local.tga textures/darkmod/stone/brick/tight_large_blocks_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_016_d.DDS dds/textures/darkmod/stone/brick/tight_large_singleblock01.dds -svn move textures/darkmod/stone/floor/blocks_016_ed.tga textures/darkmod/stone/brick/tight_large_singleblock01_ed.tga -svn move textures/darkmod/stone/floor/blocks_016_local.tga textures/darkmod/stone/brick/tight_large_singleblock01_local.tga -svn move textures/darkmod/city/wall/rt_sizes01_d.tga textures/darkmod/stone/brick/tight_randomsize_blocks.tga -svn move textures/darkmod/city/wall/rt_sizes01_local.tga textures/darkmod/stone/brick/tight_randomsize_blocks_local.tga -svn move textures/darkmod/city/wall/rt_framedwall01_d.tga textures/darkmod/stone/brick/nontiling/chiseled_brick_frame.tga -svn move textures/darkmod/city/wall/rt_framedwall01_local.tga textures/darkmod/stone/brick/nontiling/chiseled_brick_frame_local.tga -svn move textures/darkmod/stone/gen/brick_001_d.tga textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_grey.tga -svn move textures/darkmod/stone/gen/brick_001_local.tga textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_local.tga -svn move textures/darkmod/stone/gen/brick_001_s.tga textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_s.tga -svn move dds/textures/darkmod/stone/wall/brick_old_002.dds dds/textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick.dds -svn move textures/darkmod/stone/wall/brick_old_002_editor.tga textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick_ed.tga -svn move textures/darkmod/stone/wall/brick_old_002_local.tga textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_005.dds dds/textures/darkmod/stone/cobblestones/blocks_mixedsize01.dds -svn move textures/darkmod/stone/wall/masonry_005_editor.tga textures/darkmod/stone/cobblestones/blocks_mixedsize01_ed.tga -svn move textures/darkmod/stone/wall/masonry_005_local.tga textures/darkmod/stone/cobblestones/blocks_mixedsize01_local.tga -svn move textures/darkmod/castle/wall/rt_casstone02_d.tga textures/darkmod/stone/cobblestones/blocks_mixed_multicolour.tga -svn move textures/darkmod/castle/wall/rt_casstone01_d.tga textures/darkmod/stone/cobblestones/blocks_mixed_multicolour_framed.tga -svn move textures/darkmod/castle/wall/rt_casstone01_local.tga textures/darkmod/stone/cobblestones/blocks_mixed_multicolour_framed_local.tga -svn move textures/darkmod/castle/wall/rt_casstone02_local.tga textures/darkmod/stone/cobblestones/blocks_mixed_multicolour_local.tga -svn move dds/textures/darkmod/stone/floor/cobble_004.dds dds/textures/darkmod/stone/cobblestones/cobblestones01_light.dds -svn move textures/darkmod/stone/floor/cobble_004_editor.tga textures/darkmod/stone/cobblestones/cobblestones01_square_light_ed.tga -svn move textures/darkmod/stone/floor/cobble_004_local.tga textures/darkmod/stone/cobblestones/cobblestones01_square_light_local.tga -svn move dds/textures/darkmod/stone/floor/cobble_004_s.dds dds/textures/darkmod/stone/cobblestones/cobblestones01_square_light_s.dds -svn move dds/textures/darkmod/stone/floor/cobble_008.dds dds/textures/darkmod/stone/cobblestones/cobblestones02_square_dark.dds -svn move textures/darkmod/stone/floor/cobble_008_editor.jpg textures/darkmod/stone/cobblestones/cobblestones02_square_dark.jpg -svn move textures/darkmod/stone/floor/cobble_008_local.tga textures/darkmod/stone/cobblestones/cobblestones02_square_dark_local.tga -svn move dds/textures/darkmod/stone/floor/cobble_008_s.dds dds/textures/darkmod/stone/cobblestones/cobblestones02_square_dark_s.dds -svn move textures/darkmod/city/floor/ctyground01.tga textures/darkmod/stone/cobblestones/cobblestones03_dark.tga -svn move textures/darkmod/city/floor/ctyground01_local.tga textures/darkmod/stone/cobblestones/cobblestones03_dark_local.tga -svn move textures/darkmod/city/floor/ctyground02.tga textures/darkmod/stone/cobblestones/cobblestones04_multicolour.tga -svn move textures/darkmod/city/floor/ctyground02_local.tga textures/darkmod/stone/cobblestones/cobblestones04_multicolour_local.tga -svn move textures/darkmod/pagan/floor/pagfloor03.tga textures/darkmod/stone/cobblestones/cobblestones_loose_ongrass.tga -svn move textures/darkmod/pagan/floor/pagfloor03_local.tga textures/darkmod/stone/cobblestones/cobblestones_loose_ongrass_local.tga -svn move dds/textures/darkmod/stone/floor/fan_001_dirt.dds dds/textures/darkmod/stone/cobblestones/cobblestone_fan_pattern.dds -svn move textures/darkmod/stone/floor/fan_001_dirt_editor.tga textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_ed.tga -svn move dds/textures/darkmod/stone/floor/fan_001_grass.dds dds/textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_grass.dds -svn move textures/darkmod/stone/floor/fan_001_grass_editor.tga textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_grass_ed.tga -svn move textures/darkmod/stone/floor/fan_001_local.tga textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_local.tga -svn move dds/textures/darkmod/stone/floor/fan_001_s.dds dds/textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_s.dds -svn move dds/textures/darkmod/stone/floor/masonry_001.dds dds/textures/darkmod/stone/cobblestones/flagstones01_light.dds -svn move textures/darkmod/stone/floor/masonry_001_local.tga textures/darkmod/stone/cobblestones/flagstones01_light_local.tga -svn move textures/darkmod/stone/floor/blocks_018.tga textures/darkmod/stone/cobblestones/flagstones02_plain.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_l.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_left.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_l_ed.jpg textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_left_ed.jpg -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_r_ed.jpg textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_right_ed.jpg -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_l_local.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_left_local.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_l_s.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_left_s.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_r_s.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_right_s.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_r.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_right.tga -svn move textures/darkmod/stone/floor/blocks_018_cornerstone_r_local.tga textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_right_local.tga -svn move textures/darkmod/stone/floor/blocks_018_ed.jpg textures/darkmod/stone/cobblestones/flagstones02_plain_ed.jpg -svn move textures/darkmod/stone/floor/blocks_018_local.tga textures/darkmod/stone/cobblestones/flagstones02_plain_local.tga -svn move textures/darkmod/stone/floor/blocks_018_s.tga textures/darkmod/stone/cobblestones/flagstones02_plain_s.tga -svn move textures/darkmod/stone/floor/blocks_018_window01.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window01.tga -svn move textures/darkmod/stone/floor/blocks_018_window01_ed.jpg textures/darkmod/stone/cobblestones/flagstones02_plain_window01_ed.jpg -svn move textures/darkmod/stone/floor/blocks_018_window01_local.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window01_local.tga -svn move textures/darkmod/stone/floor/blocks_018_window01_s.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window01_s.tga -svn move textures/darkmod/stone/floor/blocks_018_window02.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window02.tga -svn move textures/darkmod/stone/floor/blocks_018_window02_ed.jpg textures/darkmod/stone/cobblestones/flagstones02_plain_window02_ed.jpg -svn move textures/darkmod/stone/floor/blocks_018_window02_local.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window02_local.tga -svn move textures/darkmod/stone/floor/blocks_018_window02_s.tga textures/darkmod/stone/cobblestones/flagstones02_plain_window02_s.tga -svn move dds/textures/darkmod/stone/floor/cobble_006.dds dds/textures/darkmod/stone/cobblestones/flagstones03_shiny.dds -svn move textures/darkmod/stone/floor/cobble_006_editor.tga textures/darkmod/stone/cobblestones/flagstones03_shiny_ed.tga -svn move textures/darkmod/stone/floor/cobble_006_local.tga textures/darkmod/stone/cobblestones/flagstones03_shiny_local.tga -svn move dds/textures/darkmod/stone/floor/cobble_006_s.dds dds/textures/darkmod/stone/cobblestones/flagstones03_shiny_s.dds -svn move dds/textures/darkmod/stone/floor/cobble_007.dds dds/textures/darkmod/stone/cobblestones/flagstones04_uneven.dds -svn move textures/darkmod/stone/floor/cobble_007_editor.tga textures/darkmod/stone/cobblestones/flagstones04_uneven_ed.tga -svn move textures/darkmod/stone/floor/cobble_007_local.tga textures/darkmod/stone/cobblestones/flagstones04_uneven_local.tga -svn move textures/darkmod/city/floor/cobblestone01sh.tga textures/darkmod/stone/cobblestones/flagstones05_pinkish.tga -svn move textures/darkmod/city/floor/cobblestone01sh_local.tga textures/darkmod/stone/cobblestones/flagstones05_pinkish_local.tga -svn move textures/darkmod/city/floor/cobblestone01sh_s.tga textures/darkmod/stone/cobblestones/flagstones05_pinkish_s.tga -svn move dds/textures/darkmod/stone/floor/granite_001.dds dds/textures/darkmod/stone/cobblestones/flagstones06_granite.dds -svn move textures/darkmod/stone/floor/granite_001_editor.tga textures/darkmod/stone/cobblestones/flagstones06_granite_ed.tga -svn move textures/darkmod/stone/floor/granite_001_local.tga textures/darkmod/stone/cobblestones/flagstones06_granite_local.tga -svn move dds/textures/darkmod/stone/floor/granite_001_s.dds dds/textures/darkmod/stone/cobblestones/flagstones06_granite_s.dds -svn move dds/textures/darkmod/stone/wall/masonry_old_004.dds dds/textures/darkmod/stone/cobblestones/rough_masonry01.dds -svn move textures/darkmod/stone/wall/masonry_old_004_editor.tga textures/darkmod/stone/cobblestones/rough_masonry01_ed.tga -svn move textures/darkmod/stone/wall/masonry_old_004_local.tga textures/darkmod/stone/cobblestones/rough_masonry01_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_012.dds dds/textures/darkmod/stone/cobblestones/uneven_blocks01_brown.dds -svn move textures/darkmod/stone/floor/blocks_012_editor.tga textures/darkmod/stone/cobblestones/uneven_blocks01_brown_ed.tga -svn move textures/darkmod/stone/floor/blocks_012_local.tga textures/darkmod/stone/cobblestones/uneven_blocks01_brown_local.tga -svn move dds/textures/darkmod/stone/floor/blocks_011.dds dds/textures/darkmod/stone/cobblestones/uneven_blocks01_dark.dds -svn move textures/darkmod/stone/floor/blocks_011_editor.tga textures/darkmod/stone/cobblestones/uneven_blocks01_dark_ed.tga -svn move textures/darkmod/stone/floor/blocks_011_local.tga textures/darkmod/stone/cobblestones/uneven_blocks01_dark_local.tga -svn move textures/darkmod/castle/floor/casfloor04.tga textures/darkmod/stone/cobblestones/nontiling/flagstones_jagged_grey.tga -svn move textures/darkmod/castle/floor/casfloor04_local.tga textures/darkmod/stone/cobblestones/nontiling/flagstones_jagged_grey_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_001.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey.dds -svn move textures/darkmod/stone/wall/masonry_001_editor.tga dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey_local.tga -svn move textures/darkmod/stone/wall/masonry_001_local.tga dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_002.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey.dds -svn move textures/darkmod/stone/wall/masonry_002_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey_ed.tga -svn move textures/darkmod/stone/wall/masonry_002_local.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_003.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown.dds -svn move textures/darkmod/stone/wall/masonry_003_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown_ed.tga -svn move textures/darkmod/stone/wall/masonry_003_local.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_004.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey.dds -svn move textures/darkmod/stone/wall/masonry_004_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey_ed.tga -svn move textures/darkmod/stone/wall/masonry_004_local.tga textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_old_001.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix.dds -svn move textures/darkmod/stone/wall/masonry_old_001_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix_ed.tga -svn move textures/darkmod/stone/wall/masonry_old_001_local.tga textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_old_002.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix.dds -svn move textures/darkmod/stone/wall/masonry_old_002_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix_ed.tga -svn move textures/darkmod/stone/wall/masonry_old_002_local.tga textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix_local.tga -svn move dds/textures/darkmod/stone/wall/rounded_001.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded.dds -svn move textures/darkmod/stone/wall/rounded_001_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded_ed.tga -svn move textures/darkmod/stone/wall/rounded_001_local.tga textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_old_003.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse.dds -svn move textures/darkmod/stone/wall/masonry_old_003_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse_ed.tga -svn move textures/darkmod/stone/wall/masonry_old_003_local.tga textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse_local.tga -svn move dds/textures/darkmod/stone/wall/masonry_old_005.dds dds/textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven.dds -svn move textures/darkmod/stone/wall/masonry_old_005_editor.tga textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven_ed.tga -svn move textures/darkmod/stone/wall/masonry_old_005_local.tga textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven_local.tga -svn move dds/textures/darkmod/stone/floor/decorative_001.dds dds/textures/darkmod/stone/flat/ceramic_mosaic_decorative01.dds -svn move textures/darkmod/stone/floor/decorative_001_editor.tga dds/textures/darkmod/stone/flat/ceramic_mosaic_decorative01_ed.tga -svn move textures/darkmod/stone/floor/decorative_001_local.tga dds/textures/darkmod/stone/flat/ceramic_mosaic_decorative01_local.tga -svn move dds/textures/darkmod/stone/floor/decorative_001_s.dds dds/textures/darkmod/stone/flat/ceramic_mosaic_decorative01_s.dds -svn move dds/textures/darkmod/stone/floor/marble_004_d.DDS dds/textures/darkmod/stone/flat/rough_marble_dark01.dds -svn move textures/darkmod/stone/floor/marble_004_ed.tga textures/darkmod/stone/flat/rough_marble_dark01_ed.tga -svn move textures/darkmod/stone/floor/marble_004_local.tga textures/darkmod/stone/flat/rough_marble_dark01_local.tga -svn move dds/textures/darkmod/stone/floor/rough_006_d.DDS dds/textures/darkmod/stone/flat/rough_marble_dark02.dds -svn move textures/darkmod/stone/floor/rough_006_ed.tga textures/darkmod/stone/flat/rough_marble_dark02_ed.tga -svn move textures/darkmod/stone/floor/rough_006_local.tga textures/darkmod/stone/flat/rough_marble_dark02_local.tga -svn move dds/textures/darkmod/stone/floor/rough_007_d.DDS dds/textures/darkmod/stone/flat/rough_marble_light01.dds -svn move textures/darkmod/stone/floor/rough_007_ed.tga textures/darkmod/stone/flat/rough_marble_light01_ed.tga -svn move textures/darkmod/stone/floor/rough_007_local.tga textures/darkmod/stone/flat/rough_marble_light01_local.tga -svn move dds/textures/darkmod/stone/floor/tiled_009.dds dds/textures/darkmod/stone/flat/rough_plain_tiles01.dds -svn move textures/darkmod/stone/floor/tiled_009_editor.tga textures/darkmod/stone/flat/rough_plain_tiles01_ed.tga -svn move textures/darkmod/stone/floor/tiled_009_local.tga textures/darkmod/stone/flat/rough_plain_tiles01_local.tga -svn move textures/darkmod/mansion/floor/manfslate1.tga textures/darkmod/stone/flat/rough_slate_dark01.tga -svn move textures/darkmod/mansion/floor/manfslate1_local.tga textures/darkmod/stone/flat/rough_slate_dark01_local.tga -svn move dds/textures/darkmod/stone/floor/tiled_010_d.DDS dds/textures/darkmod/stone/flat/rough_slate_tiles01_dark.dds -svn move textures/darkmod/stone/floor/tiled_010_ed.tga textures/darkmod/stone/flat/rough_slate_tiles01_dark_ed.tga -svn move textures/darkmod/stone/floor/tiled_010_local.tga textures/darkmod/stone/flat/rough_slate_tiles01_local.tga -svn move textures/darkmod/city/wall/concrete01_d.tga textures/darkmod/stone/flat/slate01_light.tga -svn move textures/darkmod/city/wall/concrete01_local.tga textures/darkmod/stone/flat/slate01_local.tga -svn move textures/darkmod/city/wall/concrete01_s.tga textures/darkmod/stone/flat/slate01_s.tga -No texturefile found: concrete2_d -No valid path for: concrete2_d -Multiple textures found: ['/home/sparhawk/darkmod/textures/darkmod/city/wall/concrete_dirt01_s.tga', '/home/sparhawk/darkmod/textures/darkmod/city/wall/concrete_dirt01_d.tga', '/home/sparhawk/darkmod/textures/darkmod/city/wall/concrete_dirt01_local.tga', '/home/sparhawk/darkmod/textures/darkmod/stone/gen/concrete_dirt_001_d.tga', '/home/sparhawk/darkmod/textures/darkmod/stone/gen/concrete_dirt_001_s.tga', '/home/sparhawk/darkmod/textures/darkmod/stone/gen/concrete_dirt_001_local.tga', '/home/sparhawk/darkmod/dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_s.tga', '/home/sparhawk/darkmod/dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_d.tga', '/home/sparhawk/darkmod/dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_local.tga'] -No valid path for: concrete_d -No texturefile found: concrete_local -No valid path for: concrete_local -svn move textures/darkmod/castle/floor/casfloor03.tga textures/darkmod/stone/flat/tiles_rough_grey.tga -svn move textures/darkmod/castle/floor/casfloor03_local.tga textures/darkmod/stone/flat/tiles_rough_grey_local.tga -svn move textures/darkmod/mansion/floor/manfloor01.tga textures/darkmod/stone/flat/tile_plain_diamond01_brown.tga -svn move textures/darkmod/mansion/floor/manfloor01_s.tga textures/darkmod/stone/flat/tile_plain_diamond01_brown_s.tga -svn move textures/darkmod/mansion/floor/manfloor01_local.tga textures/darkmod/stone/flat/tile_plain_diamond01_local.tga -svn move textures/darkmod/mansion/floor/manfloor01sh_s.tga textures/darkmod/stone/flat/smooth/ceramic_tile_generic01_s.tga -svn move textures/darkmod/mansion/floor/manfloor03sh.tga textures/darkmod/stone/flat/smooth/ceramic_tile_gold01.tga -svn move textures/darkmod/mansion/floor/manfloor01sh.tga textures/darkmod/stone/flat/smooth/ceramic_tile_reddish01.tga -svn move textures/darkmod/mansion/floor/manfloor02sh.tga textures/darkmod/stone/flat/smooth/ceramic_tile_tan01.tga -svn move textures/darkmod/mansion/floor/manfloor05sh.tga textures/darkmod/stone/flat/smooth/ceramic_tile_tan02.tga -svn move textures/darkmod/mansion/floor/manfloor06sh.tga textures/darkmod/stone/flat/smooth/ceramic_tile_tan03.tga -svn move textures/darkmod/mansion/floor/manfloor02.tga textures/darkmod/stone/flat/smooth/marble_pattern01.tga -svn move textures/darkmod/mansion/floor/manfloor02cen2.tga textures/darkmod/stone/flat/smooth/marble_pattern01_centerrose.tga -svn move textures/darkmod/mansion/floor/manfloor02cen2_s.tga textures/darkmod/stone/flat/smooth/marble_pattern01_centerrose_s.tga -svn move textures/darkmod/mansion/floor/manfloor02cen1.tga textures/darkmod/stone/flat/smooth/marble_pattern01_centersun.tga -svn move textures/darkmod/mansion/floor/manfloor02cen1_s.tga textures/darkmod/stone/flat/smooth/marble_pattern01_centersun_s.tga -svn move textures/darkmod/mansion/floor/manfloor02_local.tga dds/textures/darkmod/stone/flat/smooth/marble_pattern01_local.tga -svn move textures/darkmod/mansion/floor/manfloor02_s.tga textures/darkmod/stone/flat/smooth/marble_pattern01_s.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center1.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_checker.dds -svn move textures/darkmod/tile/floor/marble_002_center1_editor.tga textures/darkmod/stone/flat/smooth/marble_pattern02_checker_ed.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center1_s.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_checker_s.dds -svn move dds/textures/darkmod/tile/floor/marble_002_center2.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_crosshair.dds -svn move textures/darkmod/tile/floor/marble_002_center2_editor.tga textures/darkmod/stone/flat/smooth/marble_pattern02_crosshair_ed.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center2_s.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_crosshair_s.dds -svn move dds/textures/darkmod/tile/floor/marble_002_center5.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_rings.dds -svn move textures/darkmod/tile/floor/marble_002_center5_editor.tga textures/darkmod/stone/flat/smooth/marble_pattern02_rings_ed.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center5_s.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_rings_s.dds -svn move dds/textures/darkmod/tile/floor/marble_002_center3.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_star.dds -svn move dds/textures/darkmod/tile/floor/marble_002_center4.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_star02.dds -svn move textures/darkmod/tile/floor/marble_002_center4_editor.tga textures/darkmod/stone/flat/smooth/marble_pattern02_star02_ed.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center4_s.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_star02_s.dds -svn move textures/darkmod/tile/floor/marble_002_center3_editor.tga textures/darkmod/stone/flat/smooth/marble_pattern02_star_ed.tga -svn move dds/textures/darkmod/tile/floor/marble_002_center3_s.dds dds/textures/darkmod/stone/flat/smooth/marble_pattern02_star_s.dds -svn move dds/textures/darkmod/tile/floor/marble_003_d.DDS dds/textures/darkmod/stone/flat/smooth/marble_pattern03_brownish.dds -svn move textures/darkmod/tile/floor/marble_003_ed.tga textures/darkmod/stone/flat/smooth/marble_pattern03_brownish_ed.tga -svn move textures/darkmod/tile/floor/marble_003_local.tga textures/darkmod/stone/flat/smooth/marble_pattern03_brownish_local.tga -svn move dds/textures/darkmod/tile/floor/marble_003_s.DDS dds/textures/darkmod/stone/flat/smooth/marble_pattern03_brownish_s.dds -svn move textures/darkmod/mansion/wall/manwtrim03.tga textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_brown.tga -svn move textures/darkmod/mansion/wall/manwtrim03_local.tga textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_local.tga -svn move textures/darkmod/mansion/wall/manwtrim03_s.tga textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_s.tga -svn move dds/textures/darkmod/stone/wall/cement_002.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_002.dds -svn move textures/darkmod/stone/wall/cement_002_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_002_editor.tga -svn move textures/darkmod/stone/wall/cement_002_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_002_local.tga -svn move dds/textures/darkmod/stone/wall/cement_004.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_004.dds -svn move textures/darkmod/stone/wall/cement_004_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_004_editor.tga -svn move textures/darkmod/stone/wall/cement_004_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_004_local.tga -svn move dds/textures/darkmod/stone/wall/cement_005.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_005.dds -svn move textures/darkmod/stone/wall/cement_005_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_005_editor.tga -svn move textures/darkmod/stone/wall/cement_005_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_005_local.tga -svn move dds/textures/darkmod/stone/wall/cement_007.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_007.dds -svn move textures/darkmod/stone/wall/cement_007_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_007_editor.tga -svn move textures/darkmod/stone/wall/cement_007_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_007_local.tga -svn move dds/textures/darkmod/stone/wall/cement_008.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_008.dds -svn move textures/darkmod/stone/wall/cement_008_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_008_editor.tga -svn move textures/darkmod/stone/wall/cement_008_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_008_local.tga -svn move dds/textures/darkmod/stone/wall/cement_010.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_010.dds -svn move textures/darkmod/stone/wall/cement_010_editor.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_010_editor.tga -svn move textures/darkmod/stone/wall/cement_010_local.tga dds/textures/darkmod/stone/flat/tiling_1d/cement_010_local.tga -svn move dds/textures/darkmod/stone/wall/cement_010_s.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_010_s.dds -svn move dds/textures/darkmod/stone/wall/cement_013_s.dds dds/textures/darkmod/stone/flat/tiling_1d/cement_013_s.dds -svn move textures/darkmod/city/wall/concrete_dirt01_d.tga dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_d.tga -svn move textures/darkmod/city/wall/concrete_dirt01_local.tga dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_local.tga -svn move textures/darkmod/city/wall/concrete_dirt01_s.tga dds/textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_s.tga -svn move dds/textures/darkmod/stone/wall/cement_001.dds dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked.dds -svn move textures/darkmod/stone/wall/cement_001_editor.tga textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked_ed.tga -svn move textures/darkmod/stone/wall/cement_001_local.tga textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked_local.tga -svn move dds/textures/darkmod/stone/wall/cement_013.dds dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked.dds -svn move textures/darkmod/stone/wall/cement_013_editor.tga textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked_ed.tga -svn move textures/darkmod/stone/wall/cement_013_local.tga textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked_local.tga -svn move dds/textures/darkmod/stone/wall/cement_003.dds dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01.dds -svn move textures/darkmod/stone/wall/cement_003_editor.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01_ed.tga -svn move textures/darkmod/stone/wall/cement_003_local.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01_local.tga -svn move textures/darkmod/stone/wall/cement_009_local.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02_local.tga -svn move dds/textures/darkmod/stone/wall/cement_009.dds dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02.dds -svn move textures/darkmod/stone/wall/cement_009_editor.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02_ed.tga -svn move dds/textures/darkmod/stone/wall/cement_006.dds dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly.dds -svn move textures/darkmod/stone/wall/cement_006_editor.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly_ed.tga -svn move textures/darkmod/stone/wall/cement_006_local.tga textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly_local.tga -svn move textures/darkmod/stone/gen/concrete_dirt_001_local.tga textures/darkmod/stone/flat/tiling_1d/gen_slate_dirt_local.tga -svn move textures/darkmod/stone/gen/concrete_dirt_001_s.tga textures/darkmod/stone/flat/tiling_1d/gen_slate_dirt_s.tga -svn move textures/darkmod/stone/gen/concrete_dirt_001_d.tga textures/darkmod/stone/flat/tiling_1d/gen_slate_light_dirt.tga -svn move dds/textures/darkmod/stone/floor/rough_010_d.DDS dds/textures/darkmod/stone/natural/dark_dirty.dds -svn move textures/darkmod/stone/floor/rough_010_ed.tga textures/darkmod/stone/natural/dark_dirty_ed.tga -svn move textures/darkmod/stone/floor/rough_010_local.tga textures/darkmod/stone/natural/dark_dirty_local.tga -svn move dds/textures/darkmod/detail/rough_001.dds dds/textures/darkmod/stone/natural/dark_dirt_smeary.dds -svn move textures/darkmod/stone/floor/rough_001_editor.tga textures/darkmod/stone/natural/dark_dirt_smeary_ed.tga -svn move textures/darkmod/stone/floor/rough_001_local.tga textures/darkmod/stone/natural/dark_dirt_smeary_local.tga -svn move dds/textures/darkmod/stone/floor/rough_009_d.DDS dds/textures/darkmod/stone/natural/dark_rough.dds -svn move textures/darkmod/stone/floor/rough_009_ed.tga textures/darkmod/stone/natural/dark_rough_ed.tga -svn move textures/darkmod/stone/floor/rough_009_local.tga textures/darkmod/stone/natural/dark_rough_local.tga -svn move dds/textures/darkmod/stone/floor/rough_005_d.DDS dds/textures/darkmod/stone/natural/light_grey_rough.dds -svn move textures/darkmod/stone/floor/rough_005_ed.tga textures/darkmod/stone/natural/light_grey_rough_ed.tga -svn move textures/darkmod/stone/floor/rough_005_local.tga textures/darkmod/stone/natural/light_grey_rough_local.tga -svn move textures/darkmod/nature/mossyrock_002.tga textures/darkmod/stone/natural/mossy_rock_brown.tga -svn move textures/darkmod/nature/mossyrock_002_ed.jpg textures/darkmod/stone/natural/mossy_rock_brown_ed.jpg -svn move textures/darkmod/nature/mossyrock_002_local.tga textures/darkmod/stone/natural/mossy_rock_brown_local.tga -svn move textures/darkmod/nature/mossyrock_002_s.tga textures/darkmod/stone/natural/mossy_rock_brown_s.tga -svn move textures/darkmod/nature/mossyrock_003.tga textures/darkmod/stone/natural/mossy_rock_bumpy.tga -svn move textures/darkmod/nature/mossyrock_003_ed.jpg textures/darkmod/stone/natural/mossy_rock_bumpy_ed.jpg -svn move textures/darkmod/nature/mossyrock_003_local.tga textures/darkmod/stone/natural/mossy_rock_bumpy_local.tga -svn move textures/darkmod/nature/mossyrock_003_s.tga textures/darkmod/stone/natural/mossy_rock_bumpy_s.tga -svn move textures/darkmod/nature/mossyrock_001.tga textures/darkmod/stone/natural/mossy_rock_green.tga -svn move textures/darkmod/nature/mossyrock_001_ed.jpg textures/darkmod/stone/natural/mossy_rock_green_ed.jpg -svn move textures/darkmod/nature/mossyrock_001_local.tga textures/darkmod/stone/natural/mossy_rock_green_local.tga -svn move textures/darkmod/nature/mossyrock_001_s.tga textures/darkmod/stone/natural/mossy_rock_green_s.tga -svn move dds/textures/darkmod/stone/floor/rough_004_d.DDS dds/textures/darkmod/stone/natural/rock_brown_mottled.dds -svn move textures/darkmod/stone/floor/rough_004_ed.tga textures/darkmod/stone/natural/rock_brown_mottled_ed.tga -svn move textures/darkmod/stone/floor/rough_004_local.tga textures/darkmod/stone/natural/rock_brown_mottled_local.tga -svn move dds/textures/darkmod/stone/floor/rough_003_d.DDS dds/textures/darkmod/stone/natural/rock_grey.dds -svn move textures/darkmod/stone/floor/rough_003_dark_ed.tga textures/darkmod/stone/natural/rock_grey_dark_ed.tga -svn move textures/darkmod/stone/floor/rough_003_ed.tga textures/darkmod/stone/natural/rock_grey_ed.tga -svn move textures/darkmod/stone/floor/rough_003_local.tga textures/darkmod/stone/natural/rock_grey_local.tga -svn move dds/textures/darkmod/stone/floor/rough_012_mossy_d.DDS dds/textures/darkmod/stone/natural/rock_grey_mossy.dds -svn move textures/darkmod/stone/floor/rough_012_mossy_ed.tga textures/darkmod/stone/natural/rock_grey_mossy_ed.tga -svn move textures/darkmod/stone/floor/rough_012_mossy_local.tga textures/darkmod/stone/natural/rock_grey_mossy_local.tga -svn move dds/textures/darkmod/stone/floor/rough_011_d.DDS dds/textures/darkmod/stone/natural/rough_grey_dirty.dds -svn move textures/darkmod/stone/floor/rough_011_ed.tga textures/darkmod/stone/natural/rough_grey_dirty_ed.tga -svn move textures/darkmod/stone/floor/rough_011_local.tga textures/darkmod/stone/natural/rough_grey_dirty_local.tga -svn move dds/textures/darkmod/stone/floor/rough_008_d.DDS dds/textures/darkmod/stone/natural/rough_old.dds -svn move textures/darkmod/stone/floor/rough_008_ed.tga textures/darkmod/stone/natural/rough_old_ed.tga -svn move textures/darkmod/stone/floor/rough_008_local.tga textures/darkmod/stone/natural/rough_old_local.tga -svn move dds/textures/darkmod/stone/floor/rough_002_d.DDS dds/textures/darkmod/stone/natural/sandstone.dds -svn move textures/darkmod/stone/floor/rough_002_ed.tga textures/darkmod/stone/natural/sandstone_ed.tga -svn move textures/darkmod/stone/floor/rough_002_local.tga textures/darkmod/stone/natural/sandstone_local.tga -svn move textures/darkmod/city/floor/ctygravel01.tga textures/darkmod/stone/natural/tiling_1d/gravel_grey_01.tga -svn move textures/darkmod/city/floor/ctygravel01_local.tga textures/darkmod/stone/natural/tiling_1d/gravel_grey_01_local.tga -svn move textures/darkmod/stone/trim/ornament_011_bones_ed.tga textures/darkmod/stone/sculpted/carved_design_bones01_ed.tga -svn move textures/darkmod/stone/trim/ornament_011_bones_local.tga textures/darkmod/stone/sculpted/carved_design_bones01_local.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_ed.tga textures/darkmod/stone/sculpted/carved_design_bones02_ed.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_left_ed.tga textures/darkmod/stone/sculpted/carved_design_bones02_left_ed.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_left_local.tga textures/darkmod/stone/sculpted/carved_design_bones02_left_local.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_local.tga textures/darkmod/stone/sculpted/carved_design_bones02_local.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_right_ed.tga textures/darkmod/stone/sculpted/carved_design_bones02_right_ed.tga -svn move textures/darkmod/stone/trim/ornament_013_bones_tile_right_local.tga textures/darkmod/stone/sculpted/carved_design_bones02_right_local.tga -svn move textures/darkmod/stone/trim/ornament_010_ed.tga textures/darkmod/stone/sculpted/carved_design_diamonds01_ed.tga -svn move textures/darkmod/stone/trim/ornament_010_local.tga dds/textures/darkmod/stone/sculpted/carved_design_diamonds01_local.tga -svn move textures/darkmod/stone/trim/ornament_014_skull_ed.tga textures/darkmod/stone/sculpted/carved_design_skull01_ed.tga -svn move textures/darkmod/stone/trim/ornament_014_skull_local.tga textures/darkmod/stone/sculpted/carved_design_skull01_local.tga -svn move textures/darkmod/stone/trim/ornament_012_snakes_ed.tga textures/darkmod/stone/sculpted/carved_design_snakes_ed.tga -svn move textures/darkmod/stone/trim/ornament_012_snakes_local.tga textures/darkmod/stone/sculpted/carved_design_snakes_local.tga -svn move dds/textures/darkmod/stone/trim/trim_002_d.DDS dds/textures/darkmod/stone/sculpted/carved_diamond_trim.dds -svn move dds/textures/darkmod/stone/trim/trim_001_d.DDS dds/textures/darkmod/stone/sculpted/carved_diamond_trim02.dds -svn move textures/darkmod/stone/trim/trim_001_ed.tga textures/darkmod/stone/sculpted/carved_diamond_trim02_ed.tga -svn move textures/darkmod/stone/trim/trim_001_local.tga textures/darkmod/stone/sculpted/carved_diamond_trim02_local.tga -svn move textures/darkmod/stone/trim/trim_002_ed.tga textures/darkmod/stone/sculpted/carved_diamond_trim_ed.tga -svn move textures/darkmod/stone/trim/trim_002_local.tga textures/darkmod/stone/sculpted/carved_diamond_trim_local.tga -svn move dds/textures/darkmod/stone/trim/ornament_002_d.DDS dds/textures/darkmod/stone/sculpted/carved_tiles01_x4_dark.dds -svn move textures/darkmod/stone/trim/ornament_002_ed.tga textures/darkmod/stone/sculpted/carved_tiles01_x4_dark_ed.tga -svn move dds/textures/darkmod/stone/trim/ornament_001_d.DDS dds/textures/darkmod/stone/sculpted/carved_tiles01_x4_light.dds -svn move textures/darkmod/stone/trim/ornament_001_ed.tga textures/darkmod/stone/sculpted/carved_tiles01_x4_light_ed.tga -svn move textures/darkmod/stone/trim/ornament_001_local.tga dds/textures/darkmod/stone/sculpted/carved_tiles01_x4_local.tga -svn move textures/darkmod/stone/trim/grave_005_ed.tga textures/darkmod/stone/sculpted/engraved_tile_cup01_ed.tga -svn move textures/darkmod/stone/trim/grave_005_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_cup01_local.tga -svn move textures/darkmod/stone/trim/grave_005_roughness_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_cup01_roughness_local.tga -svn move dds/textures/darkmod/stone/trim/ornament_009_d.DDS dds/textures/darkmod/stone/sculpted/engraved_tile_face01.dds -svn move textures/darkmod/stone/trim/ornament_009_ed.tga textures/darkmod/stone/sculpted/engraved_tile_face01_ed.tga -svn move textures/darkmod/stone/trim/ornament_009_local.tga textures/darkmod/stone/sculpted/engraved_tile_face01_local.tga -svn move dds/textures/darkmod/stone/trim/grave_007_d.DDS dds/textures/darkmod/stone/sculpted/engraved_tile_impface.dds -svn move textures/darkmod/stone/trim/grave_007_ed.tga textures/darkmod/stone/sculpted/engraved_tile_impface_ed.tga -svn move textures/darkmod/stone/trim/grave_007_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_impface_local.tga -svn move textures/darkmod/stone/trim/deco_002_ed.tga textures/darkmod/stone/sculpted/engraved_tile_ovals_ed.tga -svn move textures/darkmod/stone/trim/deco_002_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_ovals_local.tga -svn move dds/textures/darkmod/stone/trim/grave_008_d.DDS dds/textures/darkmod/stone/sculpted/engraved_tile_ring.dds -svn move textures/darkmod/stone/trim/grave_008_ed.tga textures/darkmod/stone/sculpted/engraved_tile_ring_ed.tga -svn move textures/darkmod/stone/trim/grave_008_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_ring_local.tga -svn move textures/darkmod/stone/trim/deco_001_ed.tga textures/darkmod/stone/sculpted/engraved_tile_star_ed.tga -svn move textures/darkmod/stone/trim/deco_001_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_star_local.tga -svn move textures/darkmod/stone/trim/grave_006_ed.tga textures/darkmod/stone/sculpted/engraved_tile_x_ed.tga -svn move textures/darkmod/stone/trim/grave_006_local.tga dds/textures/darkmod/stone/sculpted/engraved_tile_x_local.tga -svn move textures/darkmod/stone/trim/ornament_003_ed.tga textures/darkmod/stone/sculpted/royal_emblem01_ed.tga -svn move textures/darkmod/stone/trim/ornament_003_local.tga textures/darkmod/stone/sculpted/royal_emblem01_local.tga -svn move dds/textures/darkmod/stone/trim/ornament_003_d.DDS dds/textures/darkmod/stone/sculpted/royal_symbol01.dds -svn move textures/darkmod/stone/trim/grave_002_ed.tga textures/darkmod/stone/sculpted/sarcophagus_cup&hammer01_ed.tga -svn move textures/darkmod/stone/trim/grave_002_local.tga dds/textures/darkmod/stone/sculpted/sarcophagus_cup&hammer01_local.tga -svn move textures/darkmod/stone/trim/grave_003_local.tga dds/textures/darkmod/stone/sculpted/sarcophagus_cup&hammer01_local.tga -svn move dds/textures/darkmod/stone/trim/grave_001_d.DDS dds/textures/darkmod/stone/sculpted/sarcophagus_stone01.dds -svn move dds/textures/darkmod/stone/trim/grave_005_d.DDS dds/textures/darkmod/stone/sculpted/sarcophagus_stone02.dds -svn move textures/darkmod/stone/trim/grave_004_ed.tga textures/darkmod/stone/sculpted/sarcophagus_swords&shield01_ed.tga -svn move textures/darkmod/stone/trim/grave_004_local.tga dds/textures/darkmod/stone/sculpted/sarcophagus_swords&shield01_local.tga -svn move textures/darkmod/stone/trim/grave_001_ed.tga textures/darkmod/stone/sculpted/sarcophagus_warrior01_ed.tga -svn move textures/darkmod/stone/trim/grave_001_local.tga dds/textures/darkmod/stone/sculpted/sarcophagus_warrior01_local.tga -svn move textures/darkmod/stone/trim/grave_001_roughness_local.tga dds/textures/darkmod/stone/sculpted/sarcophagus_warrior01_roughness_local.tga -svn move textures/darkmod/stone/trim/grave_003_ed.tga textures/darkmod/stone/sculpted/sarcophagus_wings01_ed.tga -svn move dds/textures/darkmod/stone/trim/ornament_005_d.DDS dds/textures/darkmod/stone/sculpted/tiles_bars_diamondshape.dds -svn move textures/darkmod/stone/trim/ornament_005_ed.tga textures/darkmod/stone/sculpted/tiles_bars_diamondshape_ed.tga -svn move textures/darkmod/stone/trim/ornament_005_local.tga textures/darkmod/stone/sculpted/tiles_bars_diamondshape_local.tga -svn move textures/darkmod/stone/trim/ornament_008_ed.tga textures/darkmod/stone/sculpted/tile_diamond_trapezoid_ed.tga -svn move textures/darkmod/stone/trim/ornament_006_ed.tga textures/darkmod/stone/sculpted/tile_empty_square_ed.tga -svn move textures/darkmod/stone/trim/ornament_006_local.tga dds/textures/darkmod/stone/sculpted/tile_empty_square_local.tga -svn move textures/darkmod/stone/trim/ornament_007_ed.tga textures/darkmod/stone/sculpted/tile_empty_trapezoid_ed.tga -svn move textures/darkmod/stone/trim/ornament_007_local.tga dds/textures/darkmod/stone/sculpted/tile_empty_trapezoid_local.tga -svn move textures/darkmod/stone/trim/ornament_008_local.tga dds/textures/darkmod/stone/sculpted/tile_empty_trapezoid_local.tga -svn move textures/darkmod/stone/trim/border_1x1_ed.tga textures/darkmod/stone/sculpted/trapezoid_tile_1x1_ed.tga -svn move textures/darkmod/stone/trim/border_1x1_local.tga textures/darkmod/stone/sculpted/trapezoid_tile_1x1_local.tga -svn move textures/darkmod/stone/trim/border_2x1_ed.tga textures/darkmod/stone/sculpted/trapezoid_tile_2x1_ed.tga -svn move textures/darkmod/stone/trim/border_2x1_local.tga textures/darkmod/stone/sculpted/trapezoid_tile_2x1_local.tga -svn move textures/darkmod/stone/trim/border_4x1_ed.tga textures/darkmod/stone/sculpted/trapezoid_tile_4x1_ed.tga -svn move textures/darkmod/stone/trim/border_4x1_local.tga textures/darkmod/stone/sculpted/trapezoid_tile_4x1_local.tga -svn move textures/darkmod/stone/trim/border_8x1_ed.tga textures/darkmod/stone/sculpted/trapezoid_tile_8x1_ed.tga -svn move textures/darkmod/stone/trim/border_8x1_local.tga textures/darkmod/stone/sculpted/trapezoid_tile_8x1_local.tga -svn move dds/textures/darkmod/stone/trim/ornament_004_d.DDS dds/textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing.dds -svn move textures/darkmod/stone/trim/ornament_004_local.tga textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing.tga -svn move textures/darkmod/stone/trim/ornament_004_ed.tga textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing_ed.tga -svn move textures/darkmod/city/window/ctywindow01b.tga textures/darkmod/window/diamond_pattern01_dark.tga -svn move textures/darkmod/city/window/ctywindow01.tga textures/darkmod/window/diamond_pattern01_lit.tga -svn move textures/darkmod/city/window/ctywindow01_local.tga textures/darkmod/window/diamond_pattern01_local.tga -svn move textures/darkmod/city/window/ctywindow01_s.tga textures/darkmod/window/diamond_pattern01_s.tga -svn move textures/darkmod/litwindows/cwindow02_d.tga textures/darkmod/window/diamond_pattern_andbars01_lit.tga -svn move textures/darkmod/city/wall/ctywfacade01_local.tga textures/darkmod/window/frame_ornate_wallsection_lit.tga -svn move textures/darkmod/city/wall/ctywfacade01.tga textures/darkmod/window/frame_ornate_wallsection_local.tga -No texturefile found: horizontal_old_smallpanels01_dark -No valid path for: horizontal_old_smallpanels01_dark -No texturefile found: horizontal_old_smallpanels01_dark_s -No valid path for: horizontal_old_smallpanels01_dark_s -No texturefile found: horizontal_old_smallpanels01_local -No valid path for: horizontal_old_smallpanels01_local -svn move textures/darkmod/litwindows/largesquare100.tga textures/darkmod/window/largesquare01_brightlit.tga -svn move textures/darkmod/litwindows/largesquare90.tga textures/darkmod/window/largesquare01_lit.tga -svn move textures/darkmod/litwindows/largesquare70.tga textures/darkmod/window/largesquare01_softerlit.tga -svn move textures/darkmod/litwindows/largesquare80.tga textures/darkmod/window/largesquare01_softlit.tga -svn move textures/darkmod/mansion/window/manwindow01.tga textures/darkmod/window/largesquare02_dark.tga -svn move textures/darkmod/mansion/window/manwindow01b.tga textures/darkmod/window/largesquare02_lit.tga -svn move textures/darkmod/mansion/window/manwindow01_local.tga textures/darkmod/window/largesquare02_local.tga -svn move textures/darkmod/mansion/window/manwindow01_s.tga textures/darkmod/window/largesquare02_s.tga -svn move textures/darkmod/sfx/manwindow02b_withalpha.tga dds/textures/darkmod/window/manwindow02b_withalpha.tga -svn move textures/darkmod/litwindows/hlamp_window01_d.tga textures/darkmod/window/pebbly_glass_noframe01_lit.tga -svn move textures/darkmod/mansion/window/manwindow03.tga textures/darkmod/window/pointedtop_thin01_dark.tga -svn move textures/darkmod/mansion/window/manwindow03_local.tga textures/darkmod/window/pointedtop_thin01_local.tga -svn move textures/darkmod/mansion/window/manwindow03_s.tga textures/darkmod/window/pointedtop_thin01_s.tga -svn move textures/darkmod/mansion/window/manwindow04.tga textures/darkmod/window/roundtop_diamond_pattern01_brightlit.tga -svn move textures/darkmod/mansion/window/manwindow02b.tga textures/darkmod/window/roundtop_diamond_pattern01_dark.tga -svn move textures/darkmod/mansion/window/manwindow02d.tga textures/darkmod/window/roundtop_diamond_pattern01_grey.tga -svn move textures/darkmod/mansion/window/manwindow02.tga textures/darkmod/window/roundtop_diamond_pattern01_lit.tga -svn move textures/darkmod/mansion/window/manwindow02_local.tga textures/darkmod/window/roundtop_diamond_pattern01_local.tga -svn move textures/darkmod/mansion/window/manwindow02_s.tga textures/darkmod/window/roundtop_diamond_pattern01_s.tga -svn move textures/darkmod/mansion/window/manwindow02c.tga textures/darkmod/window/roundtop_diamond_pattern01_verydark.tga -svn move textures/darkmod/city/window/ctywindow02_local.tga textures/darkmod/window/shutters_closed_local.tga -svn move textures/darkmod/city/window/ctywindow02.tga textures/darkmod/window/shutters_grey_closed.tga -svn move textures/darkmod/litwindows/smallsquare100.tga textures/darkmod/window/simple_square01_brightlit.tga -svn move textures/darkmod/litwindows/smallsquare90.tga textures/darkmod/window/simple_square01_lit.tga -svn move textures/darkmod/litwindows/smallsquare80.tga textures/darkmod/window/simple_square01_softerlit.tga -svn move textures/darkmod/litwindows/smallsquare70.tga textures/darkmod/window/simple_square01_softlit.tga -No texturefile found: square_old_smallpanels01_dark -No valid path for: square_old_smallpanels01_dark -No texturefile found: square_old_smallpanels01_local -No valid path for: square_old_smallpanels01_local -No texturefile found: square_old_smallpanels01_s -No valid path for: square_old_smallpanels01_s -svn move textures/darkmod/litwindows/cwindow01_d.tga textures/darkmod/window/square_pattern01_lit.tga -svn move textures/darkmod/litwindows/cwindow01_dark_d.tga textures/darkmod/window/square_pattern01_softlit.tga -No texturefile found: winboth1_blend -No valid path for: winboth1_blend -No texturefile found: winboth2_blend -No valid path for: winboth2_blend -No texturefile found: winboth1 -No valid path for: winboth1 -No texturefile found: winboth1_local -No valid path for: winboth1_local -No texturefile found: winboth1_s -No valid path for: winboth1_s -svn move textures/darkmod/litwindows/largeround100.tga textures/darkmod/window/ornate/round_spokes01_brightlit.tga -svn move textures/darkmod/litwindows/largeround90.tga textures/darkmod/window/ornate/round_spokes01_lit.tga -svn move textures/darkmod/litwindows/largeround70.tga textures/darkmod/window/ornate/round_spokes01_softerlit.tga -svn move textures/darkmod/litwindows/largeround80.tga textures/darkmod/window/ornate/round_spokes01_softlit.tga -svn move dds/textures/darkmod/wood/floor/boards_old_004.dds dds/textures/darkmod/wood/boards/dark_rough.dds -svn move textures/darkmod/wood/floor/boards_old_004_editor.tga textures/darkmod/wood/boards/dark_rough_ed.tga -svn move textures/darkmod/wood/floor/boards_old_004_local.tga textures/darkmod/wood/boards/dark_rough_local.tga -svn move dds/textures/darkmod/wood/floor/boards_old_007.dds dds/textures/darkmod/wood/boards/dark_varnished.dds -svn move textures/darkmod/wood/floor/boards_old_007_editor.jpg textures/darkmod/wood/boards/dark_varnished_ed.jpg -svn move textures/darkmod/wood/floor/boards_old_007_local.tga textures/darkmod/wood/boards/dark_varnished_local.tga -svn move textures/darkmod/wood/floor/boards_polished_002_dim_editor.jpg textures/darkmod/wood/boards/dim_01_ed.jpg -svn move textures/darkmod/mansion/ceiling/manceiling04.tga textures/darkmod/wood/boards/metal_decorated.tga -svn move textures/darkmod/mansion/ceiling/manceiling04_local.tga textures/darkmod/wood/boards/metal_decorated_local.tga -svn move textures/darkmod/mansion/ceiling/manceiling04_s.tga textures/darkmod/wood/boards/metal_decorated_s.tga -No texturefile found: medieval010 -No valid path for: medieval010 -No texturefile found: medieval010_h -No valid path for: medieval010_h -No texturefile found: medieval010_s -No valid path for: medieval010_s -svn move textures/darkmod/pagan/floor/pagfloor01.tga textures/darkmod/wood/boards/old_small_grainy.tga -svn move textures/darkmod/pagan/floor/pagfloor01_local.tga textures/darkmod/wood/boards/old_small_grainy_local.tga -svn move textures/darkmod/pagan/ceiling/pagceiling01.tga textures/darkmod/wood/boards/plastered_grey.tga -svn move textures/darkmod/pagan/ceiling/pagceiling01_ed.jpg textures/darkmod/wood/boards/plastered_grey_ed.jpg -svn move textures/darkmod/pagan/ceiling/pagceiling01_local.tga textures/darkmod/wood/boards/plastered_grey_local.tga -svn move dds/textures/darkmod/wood/floor/boards_polished_002.dds dds/textures/darkmod/wood/boards/polished_01.dds -svn move textures/darkmod/wood/floor/boards_polished_002_editor.jpg textures/darkmod/wood/boards/polished_01_ed.jpg -svn move textures/darkmod/wood/floor/boards_polished_002_local.tga textures/darkmod/wood/boards/polished_01_local.tga -svn move dds/textures/darkmod/wood/floor/boards_polished_002_s.dds dds/textures/darkmod/wood/boards/polished_01_s.dds -svn move dds/textures/darkmod/wood/floor/boards_polished_001.dds dds/textures/darkmod/wood/boards/polished_shiny.dds -svn move textures/darkmod/wood/floor/boards_polished_001_editor.jpg textures/darkmod/wood/boards/polished_shiny_ed.jpg -svn move dds/textures/darkmod/wood/floor/boards_polished_001_s.dds dds/textures/darkmod/wood/boards/polished_shiny_s.dds -svn move textures/darkmod/castle/floor/casfloor02.tga textures/darkmod/wood/boards/scratched.tga -svn move textures/darkmod/castle/floor/casfloor02_local.tga textures/darkmod/wood/boards/scratched_local.tga -svn move textures/darkmod/castle/floor/casfloor02_s.tga textures/darkmod/wood/boards/scratched_s.tga -svn move textures/darkmod/castle/floor/casfloor01.tga textures/darkmod/wood/boards/weathered.tga -svn move textures/darkmod/castle/floor/casfloor01_local.tga textures/darkmod/wood/boards/weathered_local.tga -svn move textures/darkmod/castle/floor/casfloor01_s.tga textures/darkmod/wood/boards/weathered_s.tga -svn move dds/textures/darkmod/wood/floor/boards_old_005.dds dds/textures/darkmod/wood/boards/worn_01.dds -svn move textures/darkmod/wood/floor/boards_old_005_editor.tga textures/darkmod/wood/boards/worn_01_ed.tga -svn move textures/darkmod/wood/floor/boards_old_005_local.tga textures/darkmod/wood/boards/worn_01_local.tga -svn move dds/textures/darkmod/wood/floor/boards_old_005_s.dds dds/textures/darkmod/wood/boards/worn_01_s.dds -svn move dds/textures/darkmod/wood/floor/boards_old_006.dds dds/textures/darkmod/wood/boards/worn_02.dds -svn move textures/darkmod/wood/floor/boards_old_006_editor.jpg textures/darkmod/wood/boards/worn_02_ed.jpg -svn move textures/darkmod/wood/floor/boards_old_006_local.tga textures/darkmod/wood/boards/worn_02_local.tga -svn move textures/darkmod/pagan/floor/pagfloor02.tga textures/darkmod/wood/boards/worn_large.tga -svn move textures/darkmod/pagan/floor/pagfloor02_local.tga textures/darkmod/wood/boards/worn_large_local.tga -svn move textures/darkmod/wood/gen/wood_001_d.tga textures/darkmod/wood/boards/tiling_1d/gen_old_boards.tga -svn move textures/darkmod/wood/gen/wood_001_local.tga textures/darkmod/wood/boards/tiling_1d/gen_old_boards_local.tga -svn move dds/textures/darkmod/wood/wall/boards_new_001.dds dds/textures/darkmod/wood/boards/tiling_1d/new_grainy.dds -svn move textures/darkmod/wood/wall/boards_new_001_editor.tga textures/darkmod/wood/boards/tiling_1d/new_grainy_ed.tga -svn move textures/darkmod/wood/wall/boards_new_001_local.tga textures/darkmod/wood/boards/tiling_1d/new_grainy_local.tga -svn move dds/textures/darkmod/wood/wall/boards_new_001_s.dds dds/textures/darkmod/wood/boards/tiling_1d/new_grainy_s.dds -svn move dds/textures/darkmod/wood/trim/beam_003_d.DDS dds/textures/darkmod/wood/panels/beam_brown_old.DDS -svn move textures/darkmod/wood/trim/beam_003_ed.tga textures/darkmod/wood/panels/beam_brown_old_ed.tga -svn move textures/darkmod/wood/trim/beam_003_local.tga textures/darkmod/wood/panels/beam_brown_old_local.tga -svn move textures/darkmod/pagan/trim/pagtrim01.tga textures/darkmod/wood/panels/beam_old_mossy.tga -svn move textures/darkmod/pagan/trim/pagtrim01_local.tga textures/darkmod/wood/panels/beam_old_mossy_local.tga -svn move textures/darkmod/pagan/trim/pagtrim01_s.tga textures/darkmod/wood/panels/beam_old_mossy_s.tga -svn move dds/textures/darkmod/wood/trim/beam_002.dds dds/textures/darkmod/wood/panels/beam_rough_brown.dds -svn move textures/darkmod/wood/trim/beam_002_editor.jpg textures/darkmod/wood/panels/beam_rough_brown_ed.jpg -svn move dds/textures/darkmod/wood/trim/beam_002_local.dds dds/textures/darkmod/wood/panels/beam_rough_local.dds -svn move textures/darkmod/wood/trim/beam_002_local.tga dds/textures/darkmod/wood/panels/beam_rough_local.tga -svn move dds/textures/darkmod/wood/trim/beam_002_s.dds dds/textures/darkmod/wood/panels/beam_rough_s.dds -svn move dds/textures/darkmod/wood/trim/beam_002_weathered.dds dds/textures/darkmod/wood/panels/beam_rough_weathered.dds -svn move textures/darkmod/wood/trim/beam_002_weathered_editor.jpg textures/darkmod/wood/panels/beam_rough_weathered_ed.jpg -svn move textures/darkmod/mansion/wall/manwtrim04.tga textures/darkmod/wood/panels/molding_decorative_dark.tga -svn move textures/darkmod/mansion/wall/manwtrim04_local.tga textures/darkmod/wood/panels/molding_decorative_dark_local.tga -svn move textures/darkmod/mansion/wall/manwtrim01.tga textures/darkmod/wood/panels/molding_grey.tga -svn move textures/darkmod/mansion/wall/manwtrim01_local.tga textures/darkmod/wood/panels/molding_grey_local.tga -svn move textures/darkmod/mansion/wall/manwtrim02.tga textures/darkmod/wood/panels/molding_leaves.tga -svn move textures/darkmod/mansion/wall/manwtrim02_local.tga textures/darkmod/wood/panels/molding_leaves_local.tga -svn move textures/darkmod/mansion/wall/manwall01.tga textures/darkmod/wood/panels/panels_decorative_arched.tga -svn move textures/darkmod/mansion/wall/manwall01_local.tga textures/darkmod/wood/panels/panels_decorative_arched_local.tga -svn move textures/darkmod/mansion/wall/manwpanel01.tga textures/darkmod/wood/panels/panels_grey_long.tga -svn move textures/darkmod/mansion/wall/manwpanel01_local.tga textures/darkmod/wood/panels/panels_grey_long_local.tga -svn move textures/darkmod/mansion/ceiling/manceiling06.tga textures/darkmod/wood/panels/panel_carved_rectangles_01.tga -svn move textures/darkmod/mansion/ceiling/manceiling06_local.tga textures/darkmod/wood/panels/panel_carved_rectangles_01_local.tga -svn move textures/darkmod/mansion/ceiling/manceiling03.tga textures/darkmod/wood/panels/panel_carved_rectangles_02_dark.tga -svn move textures/darkmod/mansion/ceiling/manceiling03b.tga textures/darkmod/wood/panels/panel_carved_rectangles_02_light.tga -svn move textures/darkmod/mansion/ceiling/manceiling03_local.tga textures/darkmod/wood/panels/panel_carved_rectangles_02_local.tga -svn move textures/darkmod/mansion/wall/manwpanel03.tga textures/darkmod/wood/panels/panel_carved_round_dark.tga -svn move textures/darkmod/mansion/wall/manwpanel03_local.tga textures/darkmod/wood/panels/panel_carved_round_dark_local.tga -svn move textures/darkmod/mansion/ceiling/manceiling05.tga textures/darkmod/wood/panels/panel_carved_star.tga -svn move textures/darkmod/mansion/ceiling/manceiling02.tga textures/darkmod/wood/panels/panel_carved_star_dusty.tga -svn move textures/darkmod/mansion/ceiling/manceiling02_local.tga textures/darkmod/wood/panels/panel_carved_star_dusty_local.tga -svn move textures/darkmod/mansion/ceiling/manceiling05_local.tga textures/darkmod/wood/panels/panel_carved_star_local.tga -svn move textures/darkmod/mansion/wall/manwpanel05.tga textures/darkmod/wood/panels/panel_circle_face.tga -svn move textures/darkmod/mansion/wall/manwpanel05_local.tga textures/darkmod/wood/panels/panel_circle_face_local.tga -svn move textures/darkmod/mansion/wall/manwpanel07.tga textures/darkmod/wood/panels/panel_decorative_frame.tga -svn move textures/darkmod/mansion/wall/manwpanel07_local.tga textures/darkmod/wood/panels/panel_decorative_frame_local.tga -svn move textures/darkmod/mansion/wall/manwpanel08.tga textures/darkmod/wood/panels/panel_decorative_frame_long.tga -svn move textures/darkmod/mansion/wall/manwpanel08_local.tga textures/darkmod/wood/panels/panel_decorative_frame_long_local.tga -svn move textures/darkmod/mansion/wall/manwpanel04.tga textures/darkmod/wood/panels/panel_decorative_rectangles.tga -svn move textures/darkmod/mansion/wall/manwpanel04_local.tga textures/darkmod/wood/panels/panel_decorative_rectangles_local.tga -svn move textures/darkmod/mansion/wall/manwall01sh.tga textures/darkmod/wood/panels/panel_floral_ornaments.tga -svn move textures/darkmod/mansion/wall/manwall01sh_local.tga textures/darkmod/wood/panels/panel_floral_ornaments_local.tga -svn move textures/darkmod/mansion/wall/manwall01sh_s.tga textures/darkmod/wood/panels/panel_floral_ornaments_s.tga -svn move textures/darkmod/mansion/ceiling/manceiling01.tga textures/darkmod/wood/panels/panel_grey.tga -svn move textures/darkmod/mansion/ceiling/manceiling01_local.tga textures/darkmod/wood/panels/panel_grey_local.tga -svn move textures/darkmod/mansion/wall/manwpanel02.tga textures/darkmod/wood/panels/panel_hammer.tga -svn move textures/darkmod/mansion/wall/manwpanel02_local.tga textures/darkmod/wood/panels/panel_hammer_local.tga -svn move textures/darkmod/mansion/wall/manwpanel02_s.tga textures/darkmod/wood/panels/panel_hammer_s.tga -svn move textures/darkmod/mansion/wall/manwcapital01_local.tga textures/darkmod/wood/panels/panel_pillar_capital_local.tga -svn move textures/darkmod/mansion/wall/manwpanel06.tga textures/darkmod/wood/panels/panel_warrior.tga -svn move textures/darkmod/mansion/wall/manwpanel06_local.tga textures/darkmod/wood/panels/panel_warrior_local.tga -svn move textures/darkmod/mansion/wall/manwtrim07.tga textures/darkmod/wood/panels/thin_panels_with_trim_dark.tga -svn move textures/darkmod/mansion/wall/manwtrim07_local.tga textures/darkmod/wood/panels/thin_panels_with_trim_dark_local.tga -svn move textures/darkmod/mansion/wall/manwtrim05.tga textures/darkmod/wood/panels/thin_panels_with_trim_light.tga -svn move textures/darkmod/mansion/wall/manwtrim05_local.tga dds/textures/darkmod/wood/panels/thin_panels_with_trim_light_local.tga -svn move dds/textures/darkmod/wood/floor/tile_decorative_001.dds dds/textures/darkmod/wood/panels/tile_pattern_star.dds -svn move textures/darkmod/wood/floor/tile_decorative_001_editor.jpg dds/textures/darkmod/wood/panels/tile_pattern_star_ed.jpg -svn move textures/darkmod/wood/floor/tile_decorative_001_local.tga dds/textures/darkmod/wood/panels/tile_pattern_star_local.tga -svn move dds/textures/darkmod/wood/floor/tile_decorative_001_s.dds dds/textures/darkmod/wood/panels/tile_pattern_star_s.dds -svn move dds/textures/darkmod/wood/floor/tile_weave_001.dds dds/textures/darkmod/wood/panels/tile_weave.dds -svn move textures/darkmod/wood/floor/tile_weave_001_editor.jpg textures/darkmod/wood/panels/tile_weave_ed.jpg -svn move textures/darkmod/wood/floor/tile_weave_001_local.tga textures/darkmod/wood/panels/tile_weave_local.tga -svn move dds/textures/darkmod/wood/floor/tile_weave_001_s.dds dds/textures/darkmod/wood/panels/tile_weave_s.dds -svn move textures/darkmod/mansion/wall/manwpillar01.tga textures/darkmod/wood/panels/trim_carved_long.tga -svn move textures/darkmod/mansion/wall/manwpillar01_local.tga textures/darkmod/wood/panels/trim_carved_long_local.tga -svn move textures/darkmod/mansion/wall/manwtrim06.tga textures/darkmod/wood/panels/trim_carved_rounded.tga -svn move textures/darkmod/mansion/wall/manwtrim06_local.tga textures/darkmod/wood/panels/trim_carved_rounded_local.tga -svn move textures/darkmod/wood/trim/beam_003_burnt_d.tga textures/darkmod/wood/panels/nontiling/beam_brown_old_burnt.tga -svn move dds/textures/darkmod/wood/trim/beam_003_endcap_d.DDS dds/textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap.dds -svn move textures/darkmod/wood/trim/beam_003_endcap_ed.tga textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap_ed.tga -svn move textures/darkmod/wood/trim/beam_003_endcap_local.tga textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap_local.tga -svn move dds/textures/darkmod/wood/trim/beam_002_endcap.dds dds/textures/darkmod/wood/panels/nontiling/beam_rough_brown_endcap.dds -svn move textures/darkmod/wood/trim/beam_002_endcap_editor.jpg textures/darkmod/wood/panels/nontiling/beam_rough_brown_endcap_ed.jpg -svn move textures/darkmod/wood/trim/beam_002_endcap_local.tga textures/darkmod/wood/panels/nontiling/beam_rough_endcap_local.tga -svn move dds/textures/darkmod/wood/trim/beam_002_weathered_endcap.dds dds/textures/darkmod/wood/panels/nontiling/beam_rough_weathered_endcap.dds -svn move textures/darkmod/wood/trim/beam_002_weathered_endcap_editor.jpg textures/darkmod/wood/panels/nontiling/beam_rough_weathered_endcap_ed.jpg -svn move textures/darkmod/wood/gen/wood_002_d.tga textures/darkmod/wood/panels/tiling_1d/gen_panel_x_pattern.tga -svn move textures/darkmod/wood/gen/wood_002_local.tga textures/darkmod/wood/panels/tiling_1d/gen_panel_x_pattern_local.tga -svn move textures/darkmod/city/wall/cwall_frame02_d.tga textures/darkmod/wood/plaster/framed_01.tga -svn move textures/darkmod/city/wall/cwall_frame02_local.tga textures/darkmod/wood/plaster/framed_01_local.tga -svn move textures/darkmod/city/wall/cwall_frame02_s.tga textures/darkmod/wood/plaster/framed_01_s.tga -svn move textures/darkmod/city/wall/cwall_frame01_d.tga textures/darkmod/wood/plaster/framed_02.tga -svn move textures/darkmod/city/wall/cwall_frame01_local.tga textures/darkmod/wood/plaster/framed_02_local.tga -svn move textures/darkmod/city/wall/cwall_frame01_s.tga textures/darkmod/wood/plaster/framed_02_s.tga -svn move textures/darkmod/city/wall/ctywall03.tga textures/darkmod/wood/plaster/framed_old_01.tga -svn move textures/darkmod/city/wall/ctywall03_local.tga textures/darkmod/wood/plaster/framed_old_01_local.tga -svn move textures/darkmod/city/wall/ctywall02.tga textures/darkmod/wood/plaster/framed_old_decorative_01.tga -svn move textures/darkmod/city/wall/ctywall02_local.tga textures/darkmod/wood/plaster/framed_old_decorative_01_local.tga -svn move textures/darkmod/city/wall/cwall_framebrick02_d.tga textures/darkmod/wood/plaster/framed_with_bricks.tga -svn move textures/darkmod/city/wall/cwall_framebrick02_d.tga dds/textures/darkmod/wood/plaster/framed_with_bricks_02.tga -svn move textures/darkmod/city/wall/cwall_framebrick02_local.tga textures/darkmod/wood/plaster/framed_with_bricks_02_local.tga -svn move textures/darkmod/city/wall/cwall_framebrick02_s.tga textures/darkmod/wood/plaster/framed_with_bricks_02_s.tga -svn move textures/darkmod/city/wall/cwall_framebrick_local.tga textures/darkmod/wood/plaster/framed_with_bricks_local.tga -svn move textures/darkmod/city/wall/cwall_framebrick_s.tga textures/darkmod/wood/plaster/framed_with_bricks_s.tga -svn move dds/textures/darkmod/ceramic/floor/plaster_002.dds dds/textures/darkmod/wood/plaster/panel_decorative_white.dds -svn move textures/darkmod/ceramic/floor/plaster_002_editor.tga textures/darkmod/wood/plaster/panel_decorative_white_ed.tga -svn move textures/darkmod/ceramic/floor/plaster_002_local.tga textures/darkmod/wood/plaster/panel_decorative_white_local.tga -svn move textures/darkmod/city/wall/cwall_01.tga textures/darkmod/wood/plaster/plaster_01.tga -svn move textures/darkmod/city/wall/cwall_01_local.tga dds/textures/darkmod/wood/plaster/plaster_01_local.tga -svn move textures/darkmod/city/wall/cwall_01_s.tga dds/textures/darkmod/wood/plaster/plaster_01_s.tga -svn move textures/darkmod/mansion/wall/manwall02.tga textures/darkmod/wood/plaster/stucco_01.tga -svn move textures/darkmod/mansion/wall/manwall02_local.tga textures/darkmod/wood/plaster/stucco_01_local.tga -svn move textures/darkmod/mansion/wall/manwall02_s.tga textures/darkmod/wood/plaster/stucco_01_s.tga - -materials/misc.mtr - tdm_straw_bale - straw01_local thick_straw01_local - straw01 thick_straw01 - models/misc/vine - grass01 short_patchy_grass01 - grass01_local short_patchy_grass01_local - -materials/tdm_wood_wall.mtr - textures/darkmod/wood/wall/wallpaper_002_blue - manwall04_local wallpaper_ornamental_01_local - manwall04b wallpaper_ornamental_01_blue - textures/darkmod/wood/wall/wallpaper_001 - manwall03 wallpaper_flowers_01 - manwall03_local wallpaper_flowers_01_local - textures/darkmod/wood/wall/wallpaper_003 - manwall05 wallpaper_ornamental_02_white - manwall05_local wallpaper_ornamental_02_white_local - textures/darkmod/wood/wall/panel_008 - manwpanel08 panel_decorative_frame_long - manwpanel08_local panel_decorative_frame_long_local - textures/darkmod/wood/wall/panel_009 - manwcapital01_local panel_pillar_capital_local - textures/darkmod/wood/wall/wallpaper_002_green - manwall04_local wallpaper_ornamental_01_local - manwall04c wallpaper_ornamental_01_green - textures/darkmod/wood/wall/panel_005 - manwpanel05_local panel_circle_face_local - manwpanel05 panel_circle_face - textures/darkmod/wood/wall/wallpaper_002_red - manwall04d wallpaper_ornamental_01_red - manwall04_local wallpaper_ornamental_01_local - textures/darkmod/wood/wall/panel_007 - manwpanel07_local panel_decorative_frame_local - manwpanel07 panel_decorative_frame - textures/darkmod/wood/wall/panel_001 - manwall01 panels_decorative_arched - manwall01_local panels_decorative_arched_local - textures/darkmod/wood/wall/panel_002 - manwpanel01 panels_grey_long - manwpanel01_local panels_grey_long_local - textures/darkmod/wood/wall/panel_003 - manwpanel02 panel_hammer - manwpanel02_local panel_hammer_local - manwpanel02_s panel_hammer_s - textures/darkmod/wood/wall/panel_004 - manwpanel04 panel_decorative_rectangles - manwpanel04_local panel_decorative_rectangles_local - textures/darkmod/wood/wall/boards_new_001 - boards_new_001_s new_grainy_s - boards_new_001_local new_grainy_local - boards_new_001_editor new_grainy_ed - boards_new_001 new_grainy - textures/darkmod/wood/wall/wallpaper_002_pink - manwall04_local wallpaper_ornamental_01_local - manwall04a wallpaper_ornamental_01_pink - textures/darkmod/wood/wall/panel_006 - manwpanel06_local panel_warrior_local - manwpanel06 panel_warrior - -materials/decorative_wall.mtr - tdm_boar_mount - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - -materials/glass_test.mtr - textures/glass_test/window - manwindow01 largesquare02_dark - manwindow01_local largesquare02_local - manwindow01_s largesquare02_s - textures/glass_test/window_glaze - manwindow01 largesquare02_dark - -materials/tdm_metal_trim.mtr - textures/darkmod/metal/trim/panel_001 - caswpanel01 panel_circledesign01_green - caswpanel01_local panel_circledesign01_local - textures/darkmod/metal/trim/panel_001_etched - caswpanel01 panel_circledesign01_green - caswpanel02_local panel_circledesign_ornate01_local - -materials/tdm_gen_stone.mtr - textures/darkmod/stone/gen/brick_001 - brick_001_local gen_plainbrick_local - brick_001_d gen_plainbrick_grey - brick_001_s gen_plainbrick_s - textures/darkmod/stone/gen/concrete_dirt_001 - concrete_dirt_001_local gen_slate_dirt_local - concrete_dirt_001_d gen_slate_light_dirt - concrete_dirt_001_s gen_slate_dirt_s - -materials/tdm_metal_floor.mtr - textures/darkmod/metal/floor/rust_003 - rust_003_d solid_rust01 - rust_003_local solid_rust01_local - rust_003_ed solid_rust01_ed - textures/darkmod/metal/floor/rust_002 - rust_002_d heavy_rust_pocked01 - rust_002_local heavy_rust_pocked_local - rust_002_ed heavy_rust_pocked01_ed - rust_002_s heavy_rust_pocked_s - textures/darkmod/metal/floor/grating_001 - grating_001_s dimpled_grating01_s - grating_001_local dimpled_grating01_local - grating_001_editor dimpled_grating01_ed - grating_001 dimpled_grating01 - textures/darkmod/metal/floor/rust_005 - rust_005_editor solid_rust02_ed - rust_005_local solid_rust02_local - rust_005_s solid_rust02_s - rust_005 solid_rust02 - textures/darkmod/metal/flat/simple_rough_grey01 - rust_004_d simple_rough_grey01 - rust_004_local simple_rough_grey01_local - rust_004_ed simple_rough_grey01_ed - -materials/tdm_stone_floor.mtr - textures/darkmod/stone/floor/cobble_002 - ctyground02_local cobblestones04_multicolour_local - ctyground02 cobblestones04_multicolour - textures/darkmod/stone/floor/cobble_003 - cobblestone01sh flagstones05_pinkish - cobblestone01sh_s flagstones05_pinkish_s - cobblestone01sh_local flagstones05_pinkish_local - textures/darkmod/stone/floor/cobble_001 - ctyground01_local cobblestones03_dark_local - ctyground01 cobblestones03_dark - textures/darkmod/stone/floor/cobble_006 - cobble_006_s flagstones03_shiny_s - cobble_006_local flagstones03_shiny_local - cobble_006_editor flagstones03_shiny_ed - cobble_006 flagstones03_shiny - textures/darkmod/stone/floor/cobble_007 - cobble_007_local flagstones04_uneven_local - cobble_007_editor flagstones04_uneven_ed - cobble_007 flagstones04_uneven - textures/darkmod/stone/floor/cobble_004 - cobble_004_s cobblestones01_square_light_s - cobble_004_local cobblestones01_square_light_local - cobble_004 cobblestones01_light - cobble_004_editor cobblestones01_square_light_ed - textures/darkmod/stone/floor/cobble_005 - cobble_005_editor interlocking_mixedsize_dark_ed - cobble_005 interlocking_mixedsize_dark - cobble_005_local interlocking_mixedsize_dark - textures/darkmod/stone/floor/cobble_008 - cobble_008 cobblestones02_square_dark - cobble_008_editor cobblestones02_square_dark - cobble_008_s cobblestones02_square_dark_s - cobble_008_local cobblestones02_square_dark_local - textures/darkmod/stone/floor/masonry_001 - masonry_001 flagstones01_light - masonry_001_local flagstones01_light_local - masonry_001_editor blocks_uneven02_grey_local - textures/darkmod/stone/floor/cobble_mossy_001 - pagfloor03_local cobblestones_loose_ongrass_local - pagfloor03 cobblestones_loose_ongrass - textures/darkmod/stone/floor/tiled_008 - manfloor02sh ceramic_tile_tan01 - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/tiled_009 - tiled_009_local rough_plain_tiles01_local - tiled_009_editor rough_plain_tiles01_ed - tiled_009 rough_plain_tiles01 - textures/darkmod/stone/floor/tiled_002 - casfloor04 flagstones_jagged_grey - casfloor04_local flagstones_jagged_grey_local - textures/darkmod/stone/floor/tiled_003 - manfloor01_s tile_plain_diamond01_brown_s - manfloor01 tile_plain_diamond01_brown - manfloor01_local tile_plain_diamond01_local - textures/darkmod/stone/floor/decorative_001 - decorative_001_s ceramic_mosaic_decorative01_s - decorative_001_local ceramic_mosaic_decorative01_local - decorative_001 ceramic_mosaic_decorative01 - decorative_001_editor ceramic_mosaic_decorative01_ed - textures/darkmod/stone/floor/tiled_001 - casfloor03_local tiles_rough_grey_local - casfloor03 tiles_rough_grey - textures/darkmod/stone/floor/tiled_006 - manfloor05sh ceramic_tile_tan02 - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/tiled_007 - manfloor06sh ceramic_tile_tan03 - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/tiled_004 - manfloor01sh ceramic_tile_reddish01 - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/tiled_005 - manfloor03sh ceramic_tile_gold01 - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/blocks_003_mossy - ctywbrick04b_local rough_blocks_tight02_moss_local - ctywbrick04b rough_blocks_tight02_moss - textures/darkmod/stone/floor/masonry_001_brick - masonry_001_brick_editor small_brown_bricks01_ed - masonry_001_brick small_brown_bricks01 - masonry_001_brick_local small_brown_bricks01_local - masonry_001_brick_s small_brown_bricks01 - textures/darkmod/stone/floor/brick_007_dark - brick_007_local interlocking_angled_grey_local - brick_007_s interlocking_angled_grey01_s - brick_007_dark interlocking_angled_darkgrey - brick_007_editor interlocking_angled_grey_ed - textures/darkmod/stone/floor/tiled_008_small - manfloor01sh_s ceramic_tile_generic01_s - textures/darkmod/stone/floor/blocks_018_window02 - blocks_018_window02_local flagstones02_plain_window02_local - blocks_018_window02_s flagstones02_plain_window02_s - blocks_018_window02_ed flagstones02_plain_window02_ed - blocks_018_window02 flagstones02_plain_window02 - textures/darkmod/stone/floor/rough_003_dark - rough_003_dark_ed rock_grey_dark_ed - rough_003_local rock_grey_local - rough_003_d rock_grey - textures/darkmod/stone/floor/blocks_018_window01 - blocks_018_window01_s flagstones02_plain_window01_s - blocks_018_window01_local flagstones02_plain_window01_local - blocks_018_window01_ed flagstones02_plain_window01_ed - blocks_018_window01 flagstones02_plain_window01 - textures/darkmod/stone/floor/tiled_010 - tiled_010_local rough_slate_tiles01_local - tiled_010_ed rough_slate_tiles01_dark_ed - tiled_010_d rough_slate_tiles01_dark - textures/darkmod/stone/floor/masonry_001_pillar - masonry_001_pillar_local pillar_bricks01_local - masonry_001_pillar_editor pillar_bricks01_ed - masonry_001_pillar pillar_bricks01 - masonry_001_pillar_s pillar_bricks01_s - textures/darkmod/stone/floor/fan_001_grass - fan_001_grass_editor cobblestone_fan_pattern_grass_ed - fan_001_grass cobblestone_fan_pattern_grass - fan_001_local cobblestone_fan_pattern_local - fan_001_s cobblestone_fan_pattern_s - textures/darkmod/stone/floor/blocks_016 - blocks_016_local tight_large_singleblock01_local - blocks_016_ed tight_large_singleblock01_ed - blocks_016_d tight_large_singleblock01 - textures/darkmod/stone/floor/blocks_002_blue - ctywbrick03_local rough_blocks_tight_local - ctywbrick03b rough_blocks_tight_dark - textures/darkmod/stone/floor/blocks_013 - blocks_013_editor rough_big_blocks04_brown_ed - blocks_013 rough_big_blocks04_brown - blocks_009_local rough_big_blocks02_local - textures/darkmod/stone/floor/rough_012_mossy - rough_012_mossy_ed rock_grey_mossy_ed - rough_012_mossy_local rock_grey_mossy_local - rough_012_mossy_d rock_grey_mossy - textures/darkmod/stone/floor/blocks_009_cornerstone_light - blocks_009_cornerstone_light rough_big_blocks02_cornerstone_light - blocks_009_cornerstone_local rough_big_blocks02_cornerstone_local - blocks_009_cornerstone_light_editor rough_big_blocks02_cornerstone_light_ed - textures/darkmod/stone/floor/cobble_004_nospecular - cobble_004_local cobblestones01_square_light_local - cobble_004 cobblestones01_light - cobble_004_editor cobblestones01_square_light_ed - textures/darkmod/stone/floor/rough_010 - rough_010_ed dark_dirty_ed - rough_010_local dark_dirty_local - rough_010_d dark_dirty - textures/darkmod/stone/floor/rough_011 - rough_011_ed rough_grey_dirty_ed - rough_011_d rough_grey_dirty - rough_011_local rough_grey_dirty_local - textures/darkmod/stone/floor/brick_010 - brick_010_ed old_blocks_wornsmooth_dark_ed - brick_010_local old_blocks_wornsmooth_dark_local - brick_010_d old_blocks_wornsmooth_dark - textures/darkmod/stone/floor/blocks_010_cornerstone_light - blocks_010_cornerstone_light rough_big_blocks03_cornerstone_light - blocks_009_cornerstone_local rough_big_blocks02_cornerstone_local - blocks_010_cornerstone_light_editor rough_big_blocks03_cornerstone_light_ed - textures/darkmod/stone/floor/brick_005_dark - brick_005_alpha red_sloppymortar_alpha - brick_005 red_sloppymortar - brick_005_local red_sloppymortar_local - brick_005_editor red_sloppymortar_ed - textures/darkmod/stone/floor/blocks_007 - rt_sizes01_local tight_randomsize_blocks_local - rt_sizes01_d tight_randomsize_blocks - textures/darkmod/stone/floor/blocks_006 - rt_largebrick01_local grainy_blocks01_local - rt_largebrick01_d grainy_blocks01 - textures/darkmod/stone/floor/blocks_005 - manwbrick02_local grey_protruding_bricks_local - manwbrick02 grey_protruding_bricks - textures/darkmod/stone/floor/blocks_004 - manwbrick01 tight_large_blocks - manwbrick01_local tight_large_blocks_local - textures/darkmod/stone/floor/blocks_003 - ctywbrick04_local rough_blocks_tight02_local - ctywbrick04 rough_blocks_tight02 - textures/darkmod/stone/floor/blocks_001 - ctywbrick01 rough_blocks02 - ctywbrick01_local rough_blocks02_local - textures/darkmod/stone/floor/blocks_009 - blocks_009 rough_big_blocks02 - blocks_009_editor rough_big_blocks02_ed - blocks_009_local rough_big_blocks02_local - textures/darkmod/stone/floor/blocks_008 - blocks_008_editor rough_big_blocks01_ed - blocks_008 rough_big_blocks01 - blocks_008_local rough_big_blocks01_local - textures/darkmod/stone/floor/rough_001 - rough_001_local dark_dirt_smeary_local - rough_001_editor dark_dirt_smeary_ed - rough_001 dark_dirt_smeary - textures/darkmod/stone/floor/rough_003 - rough_003_ed rock_grey_ed - rough_003_local rock_grey_local - rough_003_d rock_grey - textures/darkmod/stone/floor/blocks_002_yellow - ctywbrick03 rough_blocks_tight_light - ctywbrick03_local rough_blocks_tight_local - textures/darkmod/stone/floor/brick_009 - brick_009_local rough_blocks01_local - brick_009_d rough_blocks01 - brick_009_ed rough_blocks01_ed - textures/darkmod/stone/floor/rough_004 - rough_004_local rock_brown_mottled_local - rough_004_ed rock_brown_mottled_ed - rough_004_d rock_brown_mottled - textures/darkmod/stone/floor/rough_007 - rough_007_ed rough_marble_light01_ed - rough_007_d rough_marble_light01 - rough_007_local rough_marble_light01_local - textures/darkmod/stone/floor/rough_006 - rough_006_ed rough_marble_dark02_ed - rough_006_d rough_marble_dark02 - rough_006_local rough_marble_dark02_local - textures/darkmod/stone/floor/rough_009 - rough_009_local dark_rough_local - rough_009_d dark_rough - rough_009_ed dark_rough_ed - textures/darkmod/stone/floor/brick_004 - brick_004_local red_angled_ground_local - brick_004_editor red_angled_ground_ed - brick_004 red_angled_ground - textures/darkmod/stone/floor/brick_007 - brick_007 interlocking_angled_grey - brick_007_local interlocking_angled_grey_local - brick_007_s interlocking_angled_grey01_s - brick_007_editor interlocking_angled_grey_ed - textures/darkmod/stone/floor/brick_006 - brick_006_editor even_greyish01_ed - brick_006 even_greyish01 - brick_006_local even_greyish01_local - textures/darkmod/stone/floor/brick_001 - ctywbrick02 red_brick_dull01 - ctywbrick02_local red_brick_dull01_local - textures/darkmod/stone/floor/brick_002 - rt_redbrickvert01_local redbrick_dull_small_local - rt_redbrickvert01_d redbrick_dull_small - textures/darkmod/stone/floor/marble_004 - marble_004_local rough_marble_dark01_local - marble_004_ed rough_marble_dark01_ed - marble_004_d rough_marble_dark01 - textures/darkmod/stone/floor/blocks_018_cornerstone_l - blocks_018_cornerstone_l_local flagstones02_plain_cornerstone_left_local - blocks_018_cornerstone_l_s flagstones02_plain_cornerstone_left_s - blocks_018_cornerstone_l flagstones02_plain_cornerstone_left - blocks_018_cornerstone_l_ed flagstones02_plain_cornerstone_left_ed - textures/darkmod/stone/floor/granite_001 - granite_001_s flagstones06_granite_s - granite_001_local flagstones06_granite_local - granite_001_editor flagstones06_granite_ed - granite_001 flagstones06_granite - textures/darkmod/stone/floor/blocks_014 - blocks_014 rough_big_blocks05 - blocks_009_local rough_big_blocks02_local - blocks_014_editor rough_big_blocks05_ed - textures/darkmod/stone/floor/blocks_015 - blocks_015_d tight_large_blocks01 - blocks_015_local tight_large_blocks01_local - blocks_015_ed tight_large_blocks01_ed - blocks_015_s tight_large_blocks01_s - textures/darkmod/stone/floor/blocks_018_cornerstone_r - blocks_018_cornerstone_r_s flagstones02_plain_cornerstone_left_s - blocks_018_cornerstone_r_local flagstones02_plain_cornerstone_right_local - blocks_018_cornerstone_r_ed flagstones02_plain_cornerstone_left_ed - blocks_018_cornerstone_r flagstones02_plain_cornerstone_right - textures/darkmod/stone/floor/blocks_017 - blocks_017_ed grainy_large_blocks01_ed - blocks_017_d grainy_large_blocks01 - blocks_017_local grainy_large_blocks01_local - textures/darkmod/stone/floor/blocks_010 - blocks_010_editor rough_big_blocks03_ed - blocks_010 rough_big_blocks03 - blocks_009_local rough_big_blocks02_local - textures/darkmod/stone/floor/blocks_011 - blocks_011 uneven_blocks01_dark - blocks_011_local uneven_blocks01_dark_local - blocks_011_editor uneven_blocks01_dark_ed - textures/darkmod/stone/floor/blocks_012 - blocks_012 uneven_blocks01_brown - blocks_012_editor uneven_blocks01_brown_ed - blocks_012_local uneven_blocks01_brown_local - textures/darkmod/stone/floor/blocks_013_cornerstone_light - blocks_013_cornerstone_light_editor rough_big_blocks04_brown_cornerstone_light_ed - blocks_013_cornerstone_light rough_big_blocks04_brown_cornerstone_light - blocks_009_cornerstone_local rough_big_blocks02_cornerstone_local - textures/darkmod/stone/floor/blocks_018 - blocks_018_local flagstones02_plain_local - blocks_018_ed flagstones02_plain_ed - blocks_018 flagstones02_plain - blocks_018_s flagstones02_plain_s - textures/darkmod/stone/floor/blocks_019 - blocks_019 even_small_blocks01 - blocks_019_local even_small_blocks001_local - blocks_019_editor even_small_blocks001_ed - textures/darkmod/stone/floor/brick_005_colored - brick_005_alpha red_sloppymortar_alpha - brick_005 red_sloppymortar - brick_005_local red_sloppymortar_local - brick_005_editor red_sloppymortar_ed - textures/darkmod/stone/floor/rough_002 - rough_002_local sandstone_local - rough_002_ed sandstone_ed - rough_002_d sandstone - textures/darkmod/stone/floor/rough_005 - rough_005_local light_grey_rough_local - rough_005_d light_grey_rough - rough_005_ed light_grey_rough_ed - textures/darkmod/stone/floor/brick_008 - brick_008_local redbrick_mostly_mortar_local - brick_008_editor redbrick_mostly_mortar_ed - brick_008 redbrick_mostly_mortar - textures/darkmod/stone/floor/fan_001_dirt - fan_001_s cobblestone_fan_pattern_s - fan_001_local cobblestone_fan_pattern_local - fan_001_dirt_editor cobblestone_fan_pattern_ed - fan_001_dirt cobblestone_fan_pattern - textures/darkmod/stone/floor/brick_005 - brick_005_editor red_sloppymortar_ed - brick_005 red_sloppymortar - brick_005_local red_sloppymortar_local - textures/darkmod/stone/floor/brick_007_yellow - brick_007_yellow interlocking_angled_yellow - brick_007_local interlocking_angled_grey_local - brick_007_s interlocking_angled_grey01_s - brick_007_editor interlocking_angled_grey_ed - textures/darkmod/stone/floor/rough_008 - rough_008_d rough_old - rough_008_local rough_old_local - rough_008_ed rough_old_ed - textures/darkmod/stone/floor/blocks_009_cornerstone_dark - blocks_009_cornerstone_local rough_big_blocks02_cornerstone_local - blocks_009_cornerstone_dark_editor rough_big_blocks02_cornerstone_dark_ed - blocks_009_cornerstone_dark rough_big_blocks02_cornerstone_dark - textures/darkmod/stone/floor/blocks_010_cornerstone_dark - blocks_010_cornerstone_dark_editor rough_big_blocks03_cornerstone_dark_ed - blocks_009_cornerstone_local rough_big_blocks02_cornerstone_local - blocks_010_cornerstone_dark rough_big_blocks03_cornerstone_dark - textures/darkmod/stone/floor/brick_005_inverted - brick_005_editor red_sloppymortar_ed - brick_005 red_sloppymortar - brick_005_inverted_local red_sloppymortar_inverted_local - textures/darkmod/stone/floor/mortared_001 - rt_casstone02_local blocks_mixed_multicolour_local - rt_casstone02_d blocks_mixed_multicolour - textures/darkmod/stone/floor/brick_006_trim - brick_006_trim_editor even_greyish01_trim_ed - brick_006_trim even_greyish01_trim - brick_006_trim_local even_greyish01_trim_local - -materials/tdm_stone_trim.mtr - textures/darkmod/stone/trim/grave_004 - grave_001_d sarcophagus_stone01 - grave_004_ed sarcophagus_swords&shield01_ed - textures/darkmod/stone/trim/grave_005 - grave_005_ed engraved_tile_cup01_ed - grave_005_d sarcophagus_stone02 - textures/darkmod/stone/trim/grave_006 - grave_005_d sarcophagus_stone02 - grave_006_ed engraved_tile_x_ed - textures/darkmod/stone/trim/grave_007 - grave_007_ed engraved_tile_impface_ed - grave_007_d engraved_tile_impface - textures/darkmod/stone/trim/grave_001 - grave_001_d sarcophagus_stone01 - grave_001_ed sarcophagus_warrior01_ed - textures/darkmod/stone/trim/grave_002 - grave_002_ed sarcophagus_cup&hammer01_ed - grave_001_d sarcophagus_stone01 - textures/darkmod/stone/trim/grave_003 - grave_003_ed sarcophagus_wings01_ed - grave_001_d sarcophagus_stone01 - textures/darkmod/stone/trim/grave_008 - grave_008_ed engraved_tile_ring_ed - grave_008_d engraved_tile_ring - textures/darkmod/stone/trim/trim_001 - trim_001_d carved_diamond_trim02 - trim_001_local carved_diamond_trim02_local - trim_001_ed carved_diamond_trim02_ed - textures/darkmod/stone/trim/trim_002 - trim_002_ed carved_diamond_trim_ed - trim_002_d carved_diamond_trim - trim_002_local carved_diamond_trim_local - textures/darkmod/stone/trim/border_2x1 - border_2x1_local trapezoid_tile_2x1_local - rough_009_d dark_rough - border_2x1_ed trapezoid_tile_2x1_ed - textures/darkmod/stone/trim/border_1x1 - rough_009_d dark_rough - border_1x1_local trapezoid_tile_1x1_local - border_1x1_ed trapezoid_tile_1x1_ed - textures/darkmod/stone/trim/ornament_013_tile_left - rough_009_d dark_rough - ornament_013_bones_tile_left_local carved_design_bones02_left_local - ornament_013_bones_tile_left_ed carved_design_bones02_left_ed - textures/darkmod/stone/trim/ornament_013_tile_mid - rough_009_d dark_rough - ornament_013_bones_tile_ed carved_design_bones02_ed - ornament_013_bones_tile_local carved_design_bones02_local - textures/darkmod/stone/trim/deco_002 - deco_002_ed engraved_tile_ovals_ed - rough_005_d light_grey_rough - textures/darkmod/stone/trim/deco_001 - rough_005_d light_grey_rough - deco_001_ed engraved_tile_star_ed - textures/darkmod/stone/trim/ornament_008 - rough_008_d rough_old - ornament_008_ed tile_diamond_trapezoid_ed - textures/darkmod/stone/trim/ornament_009 - ornament_009_local engraved_tile_face01_local - ornament_009_ed engraved_tile_face01_ed - ornament_009_d engraved_tile_face01 - textures/darkmod/stone/trim/ornament_001 - ornament_001_ed carved_tiles01_x4_light_ed - ornament_001_d carved_tiles01_x4_light - textures/darkmod/stone/trim/ornament_002 - ornament_002_d carved_tiles01_x4_dark - ornament_002_ed carved_tiles01_x4_dark_ed - textures/darkmod/stone/trim/ornament_003 - ornament_003_ed royal_emblem01_ed - ornament_003_local royal_emblem01_local - ornament_003_d royal_symbol01 - textures/darkmod/stone/trim/ornament_004 - ornament_004_d marble_ancient_writing - ornament_004_local marble_ancient_writing - ornament_004_ed marble_ancient_writing_ed - textures/darkmod/stone/trim/ornament_005 - ornament_005_d tiles_bars_diamondshape - ornament_005_local tiles_bars_diamondshape_local - ornament_005_ed tiles_bars_diamondshape_ed - textures/darkmod/stone/trim/ornament_006 - rough_008_d rough_old - ornament_006_ed tile_empty_square_ed - textures/darkmod/stone/trim/ornament_007 - rough_008_d rough_old - ornament_007_ed tile_empty_trapezoid_ed - textures/darkmod/stone/trim/border_4x1 - rough_009_d dark_rough - border_4x1_local trapezoid_tile_4x1_local - border_4x1_ed trapezoid_tile_4x1_ed - textures/darkmod/stone/trim/trim_003 - trim_003_local single_grey_block01_local - trim_003_d single_grey_block01 - trim_003_ed single_grey_block01_ed - textures/darkmod/stone/trim/ornament_013_tile_right - ornament_013_bones_tile_right_local carved_design_bones02_right_local - rough_009_d dark_rough - ornament_013_bones_tile_right_ed carved_design_bones02_right_ed - textures/darkmod/stone/trim/ornament_014_skull - rough_009_d dark_rough - ornament_014_skull_local carved_design_skull01_local - ornament_014_skull_ed carved_design_skull01_ed - textures/darkmod/stone/trim/border_8x1 - rough_009_d dark_rough - border_8x1_ed trapezoid_tile_8x1_ed - border_8x1_local trapezoid_tile_8x1_local - textures/darkmod/stone/trim/ornament_012 - rough_005_d light_grey_rough - ornament_012_snakes_ed carved_design_snakes_ed - ornament_012_snakes_local carved_design_snakes_local - textures/darkmod/stone/trim/ornament_011 - ornament_011_bones_local carved_design_bones01_local - rough_007_d rough_marble_light01 - ornament_011_bones_ed carved_design_bones01_ed - textures/darkmod/stone/trim/ornament_010 - rough_005_d light_grey_rough - ornament_010_ed carved_design_diamonds01_ed - -materials/test_movers.mtr - numberwheel_lever - caswpanel01_local panel_circledesign01_local - -materials/tdm_ai_builders.mtr - models/md5/chars/builders/priest/priestmetal - bronze_001_d gen_smooth_bronze01 - bronze_001_s gen_smooth_bronze01_s - -materials/askave.mtr - textures/darkmod/stone/floor/rough_001 - rough_001_local dark_dirt_smeary_local - rough_001_editor dark_dirt_smeary_ed - -materials/tdm_snow_floor.mtr - textures/darkmod/snow/floor/icy_001 - icy_001_s plain_ice01_s - icy_001 plain_ice01 - icy_001_local plain_ice01_local - icy_001_editor plain_ice01_ed - textures/darkmod/snow/floor/rippled_001 - rippled_001_local plain_snow01_local - rippled_001 plain_snow01 - -materials/tdm_tile_trim.mtr - textures/darkmod/tile/trim/molding_001 - manwtrim03_local marble_trim01_local - manwtrim03_s marble_trim01_s - manwtrim03 marble_trim01_brown - -materials/tdm_wood_floor.mtr - textures/darkmod/wood/floor/boards_polished_002_dim - boards_polished_002_dim_editor dim_01_ed - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - textures/darkmod/wood/floor/tile_decorative_001 - decorative_001_s ceramic_mosaic_decorative01_s - decorative_001_local ceramic_mosaic_decorative01_local - decorative_001 ceramic_mosaic_decorative01 - decorative_001_editor ceramic_mosaic_decorative01_ed - textures/darkmod/wood/floor/boards_old_005 - boards_old_005 worn_01 - boards_old_005_local worn_01_local - boards_old_005_editor worn_01_ed - boards_old_005_s worn_01_s - textures/darkmod/wood/floor/boards_old_004 - boards_old_004_local dark_rough_local - boards_old_004_editor dark_rough_ed - boards_old_004 dark_rough - textures/darkmod/wood/floor/boards_old_007 - boards_old_007_editor dark_varnished_ed - boards_old_007 dark_varnished - boards_old_007_local dark_varnished_local - textures/darkmod/wood/floor/boards_old_006 - boards_old_006 worn_02 - boards_old_006_editor worn_02_ed - boards_old_006_local worn_02_local - textures/darkmod/wood/floor/boards_old_001 - pagfloor01 old_small_grainy - pagfloor01_local old_small_grainy_local - textures/darkmod/wood/floor/boards_old_003 - casfloor02 scratched - casfloor02_s scratched_s - casfloor02_local scratched_local - textures/darkmod/wood/floor/boards_old_002 - casfloor01 weathered - casfloor01_s weathered_s - casfloor01_local weathered_local - textures/darkmod/wood/floor/boards_polished_001 - boards_polished_001_editor polished_shiny_ed - boards_polished_001 polished_shiny - boards_polished_001_s polished_shiny_s - textures/darkmod/wood/floor/tile_weave_001 - tile_weave_001_s tile_weave_s - tile_weave_001_editor tile_weave_ed - tile_weave_001 tile_weave - tile_weave_001_local tile_weave_local - textures/darkmod/wood/floor/boards_polished_002 - boards_polished_002_s polished_01_s - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_editor polished_01_ed - -materials/tdm_door.mtr - tdm_windowed_door_02 - mandoor05 smooth_rich_squarewindow01 - mandoor05_local smooth_rich_squarewindow01_local - mandoor05_s smooth_rich_squarewindow01_s - textures/darkmod/door/attic_001 - mandoor01_s old_flat_oak01_s - mandoor01 old_flat_oak01 - mandoor01_local old_flat_oak01_local - mansion_door_01_dark - mandoor02ab_local smooth_4panels_local - mandoor02b smooth_4panels_red01 - textures/darkmod/door/sturdy_001 - ctydoor01 diamond_pattern01 - ctydoor01_local diamond_pattern01_local - textures/darkmod/door/mansion_002 - mandoor03_local smooth_3panels_local - mandoor03 smooth_3panels_red01 - textures/darkmod/door/weathered_001 - weathered_001_local old_weathered_boards01_local - weathered_001_d old_weathered_boards01 - tdm_old_door_01 - boards_old_004_local dark_rough_local - boards_old_004_editor dark_rough_ed - boards_old_004 dark_rough - textures/darkmod/door/mansion_001 - mandoor02ab_local smooth_4panels_local - mandoor02b smooth_4panels_red01 - mansion_door_01_light - mandoor02a smooth_4panels_tan01 - mandoor02ab_local smooth_4panels_local - textures/darkmod/door/reinforced_001 - casdoor01_s metalbands_crisscross01_s - casdoor01_local metalbands_crisscross01_local - casdoor01 metalbands_crisscross01 - tdm_windowed_door_02_alpha - mandoor05 smooth_rich_squarewindow01 - mandoor05_local smooth_rich_squarewindow01_local - mandoor05_withalpha smooth_rich_squarewindow01_alpha - mandoor05_s smooth_rich_squarewindow01_s - textures/darkmod/door/mansion_001_light - mandoor02a smooth_4panels_tan01 - mandoor02ab_local smooth_4panels_local - tdm_windowed_door_01 - mandoor04 smooth_rich_ovalwindow01 - mandoor04_s smooth_rich_ovalwindow01_s - mandoor04_local smooth_rich_ovalwindow01_local - textures/darkmod/door/mansion_004 - mandoor06_local smooth_2panels_rich_local - mandoor06 smooth_2panels_rich - textures/darkmod/door/windowed_001 - mandoor04 smooth_rich_ovalwindow01 - mandoor04_local smooth_rich_ovalwindow01_local - textures/darkmod/door/mansion_003 - mandoor01sh_s smooth_3panels01_dull_s - mandoor01sh_local smooth_3panels01_remove_local - mandoor01sh smooth_3panels01_dull01 - textures/darkmod/door/antique_001 - antique_001 oldboards_metalspirals01 - antique_001_local oldboards_metalspirals01_local - antique_001_editor oldboards_metalspirals01_ed - tdm_warehouse_front_door - ctydoor01 diamond_pattern01 - warehouse_frontdoor_d old_4panels_peelingpaint01 - tdm_old_door_01_metal - iron_001_local gen_smooth_iron01_local - iron_001_s gen_smooth_iron01_s - iron_001_d gen_smooth_iron01 - tdm_mansion_door_mahogany - mandoor06_local smooth_2panels_rich_local - mandoor06 smooth_2panels_rich - mandoor06_s smooth_2panels_rich_s - textures/darkmod/door/windowed_002 - mandoor05 smooth_rich_squarewindow01 - mandoor05_local smooth_rich_squarewindow01_local - mandoor05_s smooth_rich_squarewindow01_s - -materials/tdm_tile_floor.mtr - textures/darkmod/tile/floor/marble_001_center2_polished - manfloor02cen2_s marble_pattern01_centerrose_s - manfloor02cen2 marble_pattern01_centerrose - textures/darkmod/tile/floor/marble_002_center5_gear_polished - marble_002_center5_s marble_pattern02_rings_s - marble_002_center5 marble_pattern02_rings - marble_002_center5_editor marble_pattern02_rings_ed - textures/darkmod/tile/floor/marble_002_center3_polished - marble_002_center3_s marble_pattern02_star_s - marble_002_center3_editor marble_pattern02_star_ed - marble_002_center3 marble_pattern02_star - textures/darkmod/tile/floor/marble_003 - marble_003_ed marble_pattern03_brownish_ed - marble_003_s marble_pattern03_brownish_s - marble_003_d marble_pattern03_brownish - marble_003_local marble_pattern03_brownish_local - textures/darkmod/tile/floor/marble_002_center1_squares - marble_002_center1_editor marble_pattern02_checker_ed - marble_002_center1_s marble_pattern02_checker_s - marble_002_center1 marble_pattern02_checker - textures/darkmod/tile/floor/marble_002_center2 - marble_002_center2_s marble_pattern02_crosshair_s - marble_002_center2 marble_pattern02_crosshair - marble_002_center2_editor marble_pattern02_crosshair_ed - textures/darkmod/tile/floor/marble_001_center1_polished - manfloor02cen1_s marble_pattern01_centersun_s - manfloor02cen1 marble_pattern01_centersun - textures/darkmod/tile/floor/marble_002_center5_gear - marble_002_center5_s marble_pattern02_rings_s - marble_002_center5 marble_pattern02_rings - marble_002_center5_editor marble_pattern02_rings_ed - textures/darkmod/tile/floor/marble_001_polished - manfloor02_s marble_pattern01_s - manfloor02 marble_pattern01 - textures/darkmod/tile/floor/marble_002_center2_polished - marble_002_center2_s marble_pattern02_crosshair_s - marble_002_center2 marble_pattern02_crosshair - marble_002_center2_editor marble_pattern02_crosshair_ed - textures/darkmod/tile/floor/marble_001_center2 - manfloor02cen2_s marble_pattern01_centerrose_s - manfloor02cen2 marble_pattern01_centerrose - textures/darkmod/tile/floor/marble_001_center1 - manfloor02cen1_s marble_pattern01_centersun_s - manfloor02cen1 marble_pattern01_centersun - textures/darkmod/tile/floor/marble_002_center3 - marble_002_center3_s marble_pattern02_star_s - marble_002_center3_editor marble_pattern02_star_ed - marble_002_center3 marble_pattern02_star - textures/darkmod/tile/floor/marble_002_center4 - marble_002_center4_editor marble_pattern02_star02_ed - marble_002_center4 marble_pattern02_star02 - marble_002_center4_s marble_pattern02_star02_s - textures/darkmod/tile/floor/marble_002_center1_squares_polished - marble_002_center1_editor marble_pattern02_checker_ed - marble_002_center1_s marble_pattern02_checker_s - marble_002_center1 marble_pattern02_checker - textures/darkmod/tile/floor/marble_002_center4_polished - marble_002_center4_editor marble_pattern02_star02_ed - marble_002_center4 marble_pattern02_star02 - marble_002_center4_s marble_pattern02_star02_s - textures/darkmod/tile/floor/marble_001 - manfloor02_s marble_pattern01_s - manfloor02 marble_pattern01 - -materials/mechanical.mtr - tdm_gear - caswpanel01_local panel_circledesign01_local - caswpanel01b panel_circledesign01_brown - watermill_wheel_metal - rust_004_d simple_rough_grey01 - rust_004_local simple_rough_grey01_local - rust_004_ed simple_rough_grey01_ed - watermill_wheel_wood - casfloor02 scratched - casfloor02_s scratched_s - casfloor02_local scratched_local - -materials/tdm_foliage_trim.mtr - textures/darkmod/foliage/trim/ivy_002_collection - ivy_002_ed ivy_mixed_pieces_ed - ivy_002 ivy_mixed_pieces - ivy_002_local ivy_mixed_pieces_local - ivy_002_s ivy_mixed_pieces_s - textures/darkmod/foliage/trim/hanging_001 - natural01_local hanging_horizontal_leaves_local - natural01 hanging_horizontal_leaves - natural01_s hanging_horizontal_leaves_s - textures/darkmod/foliage/trim/ivy_001_small1 - ivy_001_small1 ivypatch_small01 - textures/darkmod/foliage/trim/ivy_001_small2 - ivy_001_small2 ivypatch_tiny01 - textures/darkmod/foliage/trim/ivy_004 - ivy_004_s ivy_scattered_branches_s - ivy_004 ivy_scattered_branches - ivy_004_local ivy_scattered_branches_local - textures/darkmod/foliage/trim/ivy_001_patch1 - ivy_001_patch1 ivypatch_average01 - textures/darkmod/foliage/trim/ivy_001_patch2 - ivy_001_patch2 ivypatch_large01 - textures/darkmod/foliage/trim/moss - moss_d moss_patch_thick01 - moss_local moss_patch_thick01 - textures/darkmod/foliage/trim/ivy_003 - ivy_003_local ivy_vertical_branches_local - ivy_003_ed ivy_vertical_branches_ed - ivy_003 ivy_vertical_branches - ivy_003_s ivy_vertical_branches_s - textures/darkmod/foliage/trim/ivy_002_collection_dark - ivy_002_ed ivy_mixed_pieces_ed - ivy_002 ivy_mixed_pieces - ivy_002_local ivy_mixed_pieces_local - ivy_002_s ivy_mixed_pieces_s - -materials/loot.mtr - purse01_rope - grass02_local thick_grass01_local - purse01 - grass02_local thick_grass01_local - -materials/tdm_grass_floor.mtr - textures/darkmod/grass/floor/grassy_001 - grass02_local thick_grass01_local - grass02 thick_grass01 - textures/darkmod/grass/floor/mossyrock_003 - mossyrock_003_s mossy_rock_bumpy_s - mossyrock_003_local mossy_rock_bumpy_local - mossyrock_003_ed mossy_rock_bumpy_ed - mossyrock_003 mossy_rock_bumpy - textures/darkmod/grass/floor/mossyrock_002 - mossyrock_002_local mossy_rock_brown_local - mossyrock_002_ed mossy_rock_brown_ed - mossyrock_002_s mossy_rock_brown_s - mossyrock_002 mossy_rock_brown - textures/darkmod/grass/floor/mossyrock_001 - mossyrock_001_s mossy_rock_green_s - mossyrock_001_local mossy_rock_green_local - mossyrock_001_ed mossy_rock_green_ed - mossyrock_001 mossy_rock_green - textures/darkmod/grass/floor/underbrush_001 - grass01 short_patchy_grass01 - grass01_local short_patchy_grass01_local - textures/darkmod/grass/floor/straw_001 - straw01_local thick_straw01_local - straw01 thick_straw01 - -materials/tdm_wood_trim.mtr - textures/darkmod/wood/trim/beam_002_weathered - beam_002_local beam_rough_local - beam_002_s beam_rough_s - beam_002_weathered_editor beam_rough_weathered_ed - beam_002_weathered beam_rough_weathered - textures/darkmod/wood/trim/molding_001 - manwtrim06 trim_carved_rounded - manwtrim06_local trim_carved_rounded_local - textures/darkmod/wood/trim/molding_002 - manwtrim02_local molding_leaves_local - manwtrim02 molding_leaves - textures/darkmod/wood/trim/molding_003 - manwtrim04 molding_decorative_dark - manwtrim04_local molding_decorative_dark_local - textures/darkmod/wood/trim/beam_002 - beam_002_local beam_rough_local - beam_002 beam_rough_brown - beam_002_s beam_rough_s - beam_002_editor beam_rough_brown_ed - textures/darkmod/wood/trim/beam_003 - beam_003_ed beam_brown_old_ed - beam_003_d beam_brown_old - beam_003_local beam_brown_old_local - textures/darkmod/wood/trim/panel_002 - manwtrim07_local thin_panels_with_trim_dark_local - manwtrim07 thin_panels_with_trim_dark - textures/darkmod/wood/trim/beam_001 - pagfloor02_local worn_large_local - pagfloor02 worn_large - textures/darkmod/wood/trim/panel_003 - manwtrim07_local thin_panels_with_trim_dark_local - manwtrim05 thin_panels_with_trim_light - textures/darkmod/wood/trim/beam_002_endcap - beam_002_endcap_local beam_rough_endcap_local - beam_002_endcap_editor beam_rough_brown_endcap_ed - beam_002_endcap beam_rough_brown_endcap - textures/darkmod/wood/trim/beam_003_burnt - beam_003_burnt_d beam_brown_old_burnt - beam_003_local beam_brown_old_local - textures/darkmod/wood/trim/beam_002_weathered_endcap - beam_002_weathered_endcap_editor beam_rough_weathered_endcap_ed - beam_002_weathered_endcap beam_rough_weathered_endcap - beam_002_endcap_local beam_rough_endcap_local - textures/darkmod/wood/trim/beam_003_endcap - beam_003_endcap_local beam_brown_old_endcap_local - beam_003_endcap_d beam_brown_old_endcap - beam_003_endcap_ed beam_brown_old_endcap_ed - textures/darkmod/wood/trim/plastered_001_decorative - ctywall02_local framed_old_decorative_01_local - ctywall02 framed_old_decorative_01 - textures/darkmod/wood/trim/molding_004 - manwtrim01_local molding_grey_local - manwtrim01 molding_grey - textures/darkmod/wood/trim/beam_mossy_001 - pagtrim01 beam_old_mossy - pagtrim01_local beam_old_mossy_local - pagtrim01_s beam_old_mossy_s - textures/darkmod/wood/trim/plastered_001 - ctywall03 framed_old_01 - ctywall03_local framed_old_01_local - textures/darkmod/wood/trim/panel_001 - manwpillar01_local trim_carved_long_local - manwpillar01 trim_carved_long - -materials/tdm_gen_metal.mtr - textures/darkmod/metal/gen/rust_001 - rust_001_local gen_dark_rusted01_local - rust_001_s gen_dark_rusted01_s - rust_001_d gen_dark_rusted01 - textures/darkmod/metal/gen/paintedmetal_001 - paintedmetal_001_d gen_peeling_paint01 - paintedmetal_001_s gen_peeling_paint01_s - paintedmetal_001_local gen_peeling_paint01_local - textures/darkmod/metal/gen/gold_001 - gold_001_local gen_smooth_gold01_local - gold_001_s gen_smooth_gold01_s - gold_001_d gen_smooth_gold01 - textures/darkmod/metal/gen/copper_001 - copper_001_s gen_smooth_copper01_s - copper_001_d gen_smooth_copper01 - copper_001_local gen_smooth_copper01_local - textures/darkmod/metal/gen/iron_001 - iron_001_local gen_smooth_iron01_local - iron_001_s gen_smooth_iron01_s - iron_001_d gen_smooth_iron01 - textures/darkmod/metal/gen/iron_002 - iron_002_d gen_ornate_iron01 - textures/darkmod/metal/gen/bronze_001 - bronze_001_d gen_smooth_bronze01 - bronze_001_local gen_smooth_bronze01_local - bronze_001_s gen_smooth_bronze01_s - textures/darkmod/metal/gen/brushedmetal_001 - brushedmetal_001_s gen_shiny_brushedmetal01_s - brushedmetal_001_local gen_shiny_brushedmetal01_local - brushedmetal_001_d gen_shiny_brushedmetal01 - textures/darkmod/metal/gen/silver_001 - silver_001_d gen_smooth_silver01 - silver_001_local gen_smooth_silver01_local - silver_001_s gen_smooth_silver01_s - -materials/containers.mtr - bc_insidecloth - setrug03 ornate_rectangles_brown01 - -materials/tdm_ceramic_floor.mtr - textures/darkmod/ceramic/floor/stucco_001 - manwall02_local stucco_01_local - manwall02_s stucco_01_s - manwall02 stucco_01 - textures/darkmod/ceramic/floor/plaster_002 - plaster_002_editor panel_decorative_white_ed - plaster_002 panel_decorative_white - plaster_002_local panel_decorative_white_local - -materials/tdm_windows.mtr - textures/darkmod/litwindows/largesquare100 - largesquare100 largesquare01_brightlit - textures/darkmod/litwindows/smallsquare100 - smallsquare100 simple_square01_brightlit - textures/darkmod/litwindows/smallsquare70 - smallsquare70 simple_square01_softlit - textures/darkmod/litwindows/largeround100 - largeround100 round_spokes01_brightlit - textures/darkmod/litwindows/largeround90 - largeround90 round_spokes01_lit - textures/darkmod/litwindows/largesquare70 - largesquare70 largesquare01_softerlit - textures/darkmod/litwindows/smallsquare90 - smallsquare90 simple_square01_lit - textures/darkmod/litwindows/smallsquare80 - smallsquare80 simple_square01_softerlit - textures/darkmod/litwindows/largesquare90 - largesquare90 largesquare01_lit - textures/darkmod/litwindows/largesquare80 - largesquare80 largesquare01_softlit - textures/darkmod/litwindows/largeround80 - largeround80 round_spokes01_softlit - textures/darkmod/litwindows/largeround70 - largeround70 round_spokes01_softerlit - -materials/city_window.mtr - textures/darkmod/city/window/ctywindow02 - ctywindow02_local shutters_closed_local - ctywindow02 shutters_grey_closed - textures/darkmod/city/window/ctywindow01 - ctywindow01 diamond_pattern01_lit - ctywindow01_local diamond_pattern01_local - ctywindow01_s diamond_pattern01_s - textures/darkmod/city/window/ctywindow01b - ctywindow01_local diamond_pattern01_local - ctywindow01_s diamond_pattern01_s - ctywindow01b diamond_pattern01_dark - -materials/pagan_decals.mtr - textures/darkmod/pagan/decal/pagdecfleur.tga - pagdecfleur magic_symbol_circle01 - textures/darkmod/pagan/decal/pagdecvoyn.tga - pagdecvoyn magical_letters_row01 - -materials/tdm_carpet_trim.mtr - textures/darkmod/carpet/trim/rug_red_003_center - setrug04cen_local geometric01_local - setrug04cen geometric01_red - textures/darkmod/carpet/trim/rug_red_002 - setrug02sh_local ornate_red_tan02_local - setrug02sh ornate_red_tan02 - textures/darkmod/carpet/trim/rug_red_001 - setrug01sh ornate_red_tan01 - setrug01sh_local ornate_red_tan01_local - textures/darkmod/carpet/trim/rug_002 - setrug02_local ornate_floral_checker01_local - setrug02 ornate_floral_checker01 - textures/darkmod/carpet/trim/rug_001 - setrug03 ornate_rectangles_brown01 - setrug03_local ornate_rectangles_brown01_local - textures/darkmod/carpet/trim/rug_gold_001 - setrug01_local ornate_black_gold01_local - setrug01 ornate_black_gold01 - textures/darkmod/carpet/trim/rug_red_003_end - setrug04end geometric01_red_end - setrug04end_local geometric01_end_local - textures/darkmod/carpet/trim/rug_blue_001 - setrug03sh_local ornate_green_black01_local - setrug03sh ornate_green_black01 - -materials/tdm_stone_wall.mtr - textures/darkmod/stone/wall/facade_001 - ctywfacade01_local frame_ornate_wallsection_lit - ctywfacade01 frame_ornate_wallsection_local - textures/darkmod/stone/wall/brick_old_002 - brick_old_002_local old_worn_greybrick_local - brick_old_002_editor old_worn_greybrick_ed - brick_old_002 old_worn_greybrick - textures/darkmod/stone/wall/cement_014 - cement_014_local rough_iron01_local - cement_014 rough_iron01 - cement_014_editor rough_iron01_ed - textures/darkmod/stone/wall/blocks_001_framed - rt_framedwall01_local chiseled_brick_frame_local - rt_framedwall01_d chiseled_brick_frame - textures/darkmod/stone/wall/brick_old_001 - brick_old_001 old_small_bricks_grey - brick_old_001_local old_small_bricks_grey - brick_old_001_editor old_small_bricks_grey_ed - textures/darkmod/stone/wall/cement_011 - cement_011_editor rough_rusted01_ed - cement_011 rough_rusted01 - cement_011_local rough_rusted01_local - cement_011_s rough_rusted01_s - textures/darkmod/stone/wall/mortared_001 - rt_casstone01_local blocks_mixed_multicolour_framed_local - rt_casstone01_d blocks_mixed_multicolour_framed - textures/darkmod/stone/wall/cement_013 - cement_013 concrete_light_streaked - cement_013_local concrete_light_streaked_local - cement_013_editor concrete_light_streaked_ed - textures/darkmod/stone/wall/cement_012 - cement_012_local rough_dirty01_local - cement_012_editor rough_dirty01_ed - cement_012 rough_dirty01 - textures/darkmod/stone/wall/masonry_old_002 - masonry_old_002_local bricks_blocks_roughmix_local - masonry_old_002_editor bricks_blocks_roughmix_ed - masonry_old_002 bricks_blocks_roughmix - textures/darkmod/stone/wall/masonry_old_003 - masonry_old_003 flagstones_sparse - masonry_old_003_local flagstones_sparse_local - masonry_old_003_editor flagstones_sparse_ed - textures/darkmod/stone/wall/masonry_old_001 - masonry_old_001 bricks_blocks_mix - masonry_old_001_local bricks_blocks_mix_local - masonry_old_001_editor bricks_blocks_mix_ed - textures/darkmod/stone/wall/masonry_old_004 - masonry_old_004_local rough_masonry01_local - masonry_old_004_editor rough_masonry01_ed - masonry_old_004 rough_masonry01 - textures/darkmod/stone/wall/masonry_old_005 - masonry_old_005 flagstones_uneven - masonry_old_005_local flagstones_uneven_local - masonry_old_005_editor flagstones_uneven_ed - textures/darkmod/stone/wall/cement_006 - cement_006_editor concrete_rough_pebbly_ed - cement_006 concrete_rough_pebbly - cement_006_local concrete_rough_pebbly_local - textures/darkmod/stone/wall/cement_003 - cement_003_local concrete_rough_dark01_local - cement_003 concrete_rough_dark01 - cement_003_editor concrete_rough_dark01_ed - textures/darkmod/stone/wall/cement_001 - cement_001_local concrete_light_cracked_local - cement_001_editor concrete_light_cracked_ed - cement_001 concrete_light_cracked - textures/darkmod/stone/wall/cement_009 - cement_009_local concrete_rough_dark01_local - cement_009_editor concrete_rough_dark02_ed - cement_009 concrete_rough_dark02 - textures/darkmod/stone/wall/brick_old_003 - brick_old_003_editor old_dirty_bricks01_ed - brick_old_003 old_dirty_bricks01 - brick_old_003_local old_dirty_bricks01_local - textures/darkmod/stone/wall/rounded_001 - rounded_001 cobblestones_rounded - rounded_001_local cobblestones_rounded_local - rounded_001_editor cobblestones_rounded_ed - textures/darkmod/stone/wall/masonry_004 - masonry_004_local blocks_uneven05_grey_local - masonry_004_editor blocks_uneven05_grey_ed - masonry_004 blocks_uneven05_grey - textures/darkmod/stone/wall/masonry_005 - masonry_005_local blocks_mixedsize01_local - masonry_005_editor blocks_mixedsize01_ed - masonry_005 blocks_mixedsize01 - textures/darkmod/stone/wall/masonry_001 - masonry_001 flagstones01_light - masonry_001_local flagstones01_light_local - masonry_001_editor blocks_uneven02_grey_local - textures/darkmod/stone/wall/masonry_002 - masonry_002_editor blocks_uneven03_grey_ed - masonry_002 blocks_uneven03_grey - masonry_002_local blocks_uneven03_grey_local - textures/darkmod/stone/wall/masonry_003 - masonry_003 blocks_uneven04_brown - masonry_003_local blocks_uneven04_brown_local - masonry_003_editor blocks_uneven04_brown_ed - -materials/bc_misc.mtr - doorface01 - weathered_001_local old_weathered_boards01_local - weathered_001_d old_weathered_boards01 - doorside02 - antique_001 oldboards_metalspirals01 - antique_001_local oldboards_metalspirals01_local - doorside01 - weathered_001_local old_weathered_boards01_local - weathered_001_d old_weathered_boards01 - bc_doorface02 - antique_001 oldboards_metalspirals01 - antique_001_local oldboards_metalspirals01_local - -materials/tdm_city_props.mtr - textures/darkmod/city/wall/metal02 - metal01_d simple_grey01 - metal01_local simple_grey01_local - metal01_s simple_grey01_s - -materials/mansion_window.mtr - textures/darkmod/mansion/window/manwindow04 - manwindow04 roundtop_diamond_pattern01_brightlit - textures/darkmod/mansion/window/manwindow01b - manwindow01_s largesquare02_s - manwindow01_local largesquare02_local - manwindow01b largesquare02_lit - textures/darkmod/mansion/window/manwindow01 - manwindow01 largesquare02_dark - manwindow01_local largesquare02_local - manwindow01_s largesquare02_s - textures/darkmod/mansion/window/manwindow02 - manwindow02 roundtop_diamond_pattern01_lit - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - textures/darkmod/mansion/window/manwindow03 - manwindow03 pointedtop_thin01_dark - manwindow03_local pointedtop_thin01_local - manwindow03_s pointedtop_thin01_s - textures/darkmod/mansion/window/manwindow02b - manwindow02b roundtop_diamond_pattern01_dark - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - textures/darkmod/mansion/window/manwindow02d - manwindow02_s roundtop_diamond_pattern01_s - manwindow02d roundtop_diamond_pattern01_grey - manwindow02_local roundtop_diamond_pattern01_local - -materials/tdm_gen_wood.mtr - textures/darkmod/wood/gen/wood_002 - wood_002_local gen_panel_x_pattern_local - wood_002_d gen_panel_x_pattern - textures/darkmod/wood/gen/wood_001 - wood_001_d gen_old_boards - wood_001_local gen_old_boards_local - -materials/bonehoard.mtr - textures/bonehoard/decals/dirt_002_edge_right - dirt_002_edge_right dripping_slime05_right - textures/bonehoard/decals/dirt_001 - dirt_001 scattered_dirt02 - textures/bonehoard/decals/dirt_002_edge_left - dirt_002_edge_left dripping_slime05_left - textures/bonehoard/decals/dirt_002 - dirt_002 dripping_slime05 - -materials/architecture.mtr - tdm_greenhouse_wood_polished - boards_polished_002_s polished_01_s - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_editor polished_01_ed - tdm_manwindow02 - manwindow02b roundtop_diamond_pattern01_dark - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - manstairs_01_rug_center - setrug04cen_local geometric01_local - setrug04cen geometric01_red - tdm_balcony_sp_marble01 - manwtrim03_local marble_trim01_local - manwtrim03_s marble_trim01_s - manwtrim03 marble_trim01_brown - manstairs_01_dim - boards_polished_002_dim_editor dim_01_ed - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - manstairs_01 - boards_polished_002_s polished_01_s - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_editor polished_01_ed - tdm_manwindow02_dark - manwindow02c roundtop_diamond_pattern01_verydark - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - tdm_balcony_sp_ceramic01 - plaster_002_editor panel_decorative_white_ed - plaster_002 panel_decorative_white - plaster_002_local panel_decorative_white_local - tdm_manwindowtrim - manwtrim07_local thin_panels_with_trim_dark_local - manwtrim07 thin_panels_with_trim_dark - tdm_skywindow_glass_frame - manwindow02b roundtop_diamond_pattern01_dark - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - tdm_skywindow_frame - boards_polished_002_dim_editor dim_01_ed - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - tdm_balcony_sp_floor01 - manfloor02_s marble_pattern01_s - manfloor02 marble_pattern01 - tdm_greenhouse_cement - cement_001_local concrete_light_cracked_local - cement_001_editor concrete_light_cracked_ed - cement_001 concrete_light_cracked - tdm_manwindow02_lit - manwindow02 roundtop_diamond_pattern01_lit - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - tdm_greenhouse_wood_polished_2 - boards_polished_002_dim_editor dim_01_ed - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - arch_brick01 - manwbrick01 tight_large_blocks - manwbrick01_local tight_large_blocks_local - tdm_greenhouse_panel - manceiling03_local panel_carved_rectangles_02_local - manceiling03 panel_carved_rectangles_02_dark - manstairs_01_rug_end - setrug04end geometric01_red_end - setrug04end_local geometric01_end_local - arch_marble01 - manwtrim03_local marble_trim01_local - manwtrim03_s marble_trim01_s - manwtrim03 marble_trim01_brown - tdm_cover_glass_frame - manwindow02b roundtop_diamond_pattern01_dark - manwindow02_s roundtop_diamond_pattern01_s - manwindow02_local roundtop_diamond_pattern01_local - tdm_manwindow02_white - manwindow02_s roundtop_diamond_pattern01_s - manwindow02d roundtop_diamond_pattern01_grey - manwindow02_local roundtop_diamond_pattern01_local - tdm_skywindow_frame_dim - boards_polished_002_dim_editor dim_01_ed - boards_polished_002 polished_01 - boards_polished_002_local polished_01_local - boards_polished_002_s polished_01_s - tdm_greenhouse_underbrush - grass01 short_patchy_grass01 - grass01_local short_patchy_grass01_local - tdm_balcony_sp_steps01 - manfloor02cen1_s marble_pattern01_centersun_s - manfloor02cen1 marble_pattern01_centersun - -materials/tdm_cityhouses.mtr - textures/darkmod/city/wall/cwall_framebrick02 - cwall_framebrick02_s framed_with_bricks_02_s - cwall_framebrick02_local framed_with_bricks_02_local - cwall_framebrick02_d framed_with_bricks - textures/darkmod/city/wall/metal01 - metal01_d simple_grey01 - metal01_local simple_grey01_local - metal01_s simple_grey01_s - textures/darkmod/city/wall/cwall_frame01 - cwall_frame01_s framed_02_s - cwall_frame01_local framed_02_local - cwall_frame01_d framed_02 - textures/darkmod/litwindows/hlamp_window01 - hlamp_window01_d pebbly_glass_noframe01_lit - textures/darkmod/city/wall/concrete01 - concrete01_local slate01_local - concrete01_s slate01_s - concrete01_d slate01_light - textures/darkmod/city/wall/cwall_framebrick - cwall_framebrick_s framed_with_bricks_s - cwall_framebrick_local framed_with_bricks_local - textures/darkmod/city/roof/rooftile_01 - rooftile_01_d shingle_shiny_greenish01 - rooftile_01_local shingle_shiny_greenish01_local - rooftile_01_s shingle_shiny_greenish01_s - textures/darkmod/city/wall/cwall_frame02 - cwall_frame02_local framed_01_local - cwall_frame02_d framed_01 - cwall_frame02_s framed_01_s - textures/darkmod/city/wall/brick_dark - brick_dark_s rough_brick_grey_s - brick_dark_local rough_brick_grey_local - brick_dark_d rough_brick_grey - textures/darkmod/litwindows/cwindow01_dark - cwindow01_dark_d square_pattern01_softlit - textures/darkmod/city/wall/cwall_01 - cwall_01 plaster_01 - textures/darkmod/litwindows/cwindow01 - cwindow01_d square_pattern01_lit - textures/darkmod/litwindows/cwindow02 - cwindow02_d diamond_pattern_andbars01_lit - -materials/decorative_oversize.mtr - statue_folded_hands - rough_005_d light_grey_rough - -materials/dopefish.mtr - tdm_dopefish_body - grass02_local thick_grass01_local - grass02 thick_grass01 - tdm_dopefish_teeth - manwbrick01 tight_large_blocks - manwbrick01_local tight_large_blocks_local - -materials/weapons.mtr - models/weapons/vinearrow_leaf - plant01 tropical_broadleaf - models/weapons/vinearrow_gen - grass02_local thick_grass01_local - grass02 thick_grass01 - models/weapons/mossarrow_leaf - plant01 tropical_broadleaf - -materials/nature.mtr - tdm_grass_model01 - grass01 short_patchy_grass01 - -materials/tdm_slate_floor.mtr - textures/darkmod/slate/floor/roof_001 - ctyroof01 slate_uneven_withmoss01 - ctyroof01_local slate_uneven_withmoss01_local - textures/darkmod/slate/floor/slate_001 - manfslate1 rough_slate_dark01 - manfslate1_local rough_slate_dark01_local - textures/darkmod/slate/floor/roof_002 - ctyroof02_local shingle_dullbrown01_local - ctyroof02 shingle_dullbrown01 - -materials/tdm_gravel_floor.mtr - textures/darkmod/gravel/floor/gravel_001 - ctygravel01_local gravel_grey_01_local - ctygravel01 gravel_grey_01 - textures/darkmod/gravel/floor/gravel_002 - ctygravel01_local gravel_grey_01_local - -materials/tdm_wood_ceiling.mtr - textures/darkmod/wood/ceiling/panel_002 - manceiling05 panel_carved_star - manceiling05_local panel_carved_star_local - textures/darkmod/wood/ceiling/panel_003 - manceiling06 panel_carved_rectangles_01 - manceiling06_local panel_carved_rectangles_01_local - textures/darkmod/wood/ceiling/panel_001 - manceiling01_local panel_grey_local - manceiling01 panel_grey - textures/darkmod/wood/ceiling/panel_004_dark - manceiling03_local panel_carved_rectangles_02_local - manceiling03 panel_carved_rectangles_02_dark - textures/darkmod/wood/ceiling/panel_004_light - manceiling03b panel_carved_rectangles_02_light - manceiling03_local panel_carved_rectangles_02_local - textures/darkmod/wood/ceiling/panel_005 - manwall01sh_local panel_floral_ornaments_local - manwall01sh_s panel_floral_ornaments_s - manwall01sh panel_floral_ornaments - textures/darkmod/wood/ceiling/pole_supports - manceiling04 metal_decorated - manceiling04_local metal_decorated_local - manceiling04_s metal_decorated_s - textures/darkmod/wood/ceiling/panel_006 - manwpanel03_local panel_carved_round_dark_local - manwpanel03 panel_carved_round_dark - textures/darkmod/wood/ceiling/panel_002_dusty - manceiling02_local panel_carved_star_dusty_local - manceiling02 panel_carved_star_dusty - textures/darkmod/wood/ceiling/plastered_001 - pagceiling01_local plastered_grey_local - pagceiling01_ed plastered_grey_ed - pagceiling01 plastered_grey - diff --git a/scripts/texture_reorg/map_check b/scripts/texture_reorg/map_check deleted file mode 100755 index 138863ad5..000000000 --- a/scripts/texture_reorg/map_check +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/python - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - -material_list = {} - -class MaterialLine: - def __init__(self): - self.LineNumber = -1 - self.Type = 'l' - self.Indentation = 0 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Type + "', " + self.Indentation.__repr__() + ", '" + self.Text + "' ]" - -class Material: - def __init__(self, path, name): - self.Path = path - self.Filename = name - self.Modified = 0 - self.Buffer = None - self.Line = [] - self.CacheMaterial() - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def CacheMaterial(self): - f = open(self.Path + "/" + self.Filename) - self.Buffer = f.read() - self.Buffer = self.Buffer.replace("\r\n", "\n") - self.Buffer = self.Buffer.replace("\r", "\n") - f.close() - - b = self.Buffer.split("\n") - last = None - r = MaterialLine() - ind = 0 - prevind = 0 - nr = 0 - - for l in b: - t = l.split("\r") - if(len(t) > 1): - l = t[0] - - s = l.strip() - if s[0:1] == '{': - ind = ind + 1 - elif s[0:1] == '}': - ind = ind - 1 - elif s[0:2] == '//': - r.Type = 'c' - - nr = nr + 1 - if(len(l) == 0): - continue - r.Indentation = ind - r.Text = l - r.LineNumber = nr - - # Check if we have found a material name - if ind == 1 and prevind == 0: - last.Type = 'n' - try: - n = material_list[last.Text] - #if(n[0].Filename != self.Filename): - # print "DUPLICATE MATERIAL! ["+n[0].Filename + "] [" + self.Filename + "] [" + last.Text + "]" - except KeyError: - material_list[last.Text] = [ self, last.LineNumber ] - - self.Line.append(r) - last = r - r = MaterialLine() - prevind = ind - - return - -class MapCheck: - def __init__(self, d3materialdir, moddir): - self.MaterialFile = {} - self.CacheMaterials(d3materialdir, "*.mtr") - self.CacheMaterials(moddir, "materials/*.mtr") - - def CacheMaterials(self, path, pattern): - print "Caching material files ... "+path - name = glob.glob(path+"/"+pattern) - for i in name: - i = i.split(path+"/")[1] - t = i.split("replacements.txt") - if(len(t) > 1): - continue - - t = i.split("gildoran_notes.txt") - if(len(t) > 1): - continue - - #self.MaterialFile[i] = Material(path, i) - Material(path, i) - - return - - def CheckMap(self, fn): - tex = {} - - f = open(fn) - b = f.read() - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - f.close() - linenr = 0 - - b = b.split("\n") - ind = 0 - for l in b: - linenr = linenr + 1 - l = l.strip() - n = len(l) - if n == 0: - continue - - if n > 2 and l[0] == '/' and l[1] == '/': - continue - if l[0] == '{': - ind = ind + 1 - continue - if l[0] == '}': - ind = ind - 1 - continue - - if ind == 3: - t = l.split('"') - lines = [] - tn = t[1] - try: - lines = tex[tn] - except KeyError: - tex[tn] = lines - - lines.append(linenr) - #print ind, l - - for i in tex: - print i, len(tex[i]) - return - -def Usage(): - print "USAGE: map_check doom_material_dir mod_root { mapfile } ..." - sys.exit(1) - -if __name__ == '__main__': - if len(sys.argv) <= 2: - Usage() - - mp = MapCheck(sys.argv[1], sys.argv[2]) - i = 3 - n = len(sys.argv) - - while i < n: - mp.CheckMap(sys.argv[i]) - i = i + 1 - - sys.exit(0) diff --git a/scripts/texture_reorg/material_check b/scripts/texture_reorg/material_check deleted file mode 100644 index 4b9f1acde..000000000 --- a/scripts/texture_reorg/material_check +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/python - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - -#SrcPath="/cygdrive/d/Home/cygwin/gruberg/darkmod" -#DstPath="/cygdrive/d/Home/cygwin/gruberg/darkmod_reorg" -SrcPath="/home/sparhawk/darkmod" -DstPath="/home/sparhawk/darkmod_reorg" - -material_list = {} - -class MaterialLine: - def __init__(self): - self.LineNumber = -1 - self.Type = 'l' - self.Indentation = 0 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Type + "', " + self.Indentation.__repr__() + ", '" + self.Text + "' ]" - -class Material: - def __init__(self, name): - self.Filename = name - self.Modified = 0 - self.Buffer = None - self.Line = [] - self.CacheFile() - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def CacheFile(self): - f = open(SrcPath+"/"+self.Filename) - self.Buffer = f.read() - f.close() - - b = self.Buffer.split("\n") - last = None - r = MaterialLine() - ind = 0 - prevind = 0 - nr = 0 - - for l in b: - t = l.split("\r") - if(len(t) > 1): - l = t[0] - - s = l.strip() - if s[0:1] == '{': - ind = ind + 1 - elif s[0:1] == '}': - ind = ind - 1 - elif s[0:2] == '//': - r.Type = 'c' - - nr = nr + 1 - r.Indentation = ind - r.Text = l - r.LineNumber = nr - - # Check if we have found a material name - if ind == 1 and prevind == 0: - last.Type = 'n' - - self.Line.append(r) - last = r - r = MaterialLine() - prevind = ind - - return - -class MaterialCheck: - def __init__(self): - self.MaterialFile = {} - self.CacheMaterials() - - def CacheMaterials(self): - print "Caching material files..." - name = glob.glob(SrcPath+"/materials/*") - for i in name: - i = i.split(SrcPath+"/")[1] - t = i.split("replacements.txt") - if(len(t) > 1): - continue - - t = i.split("gildoran_notes.txt") - if(len(t) > 1): - continue - - #print i - self.MaterialFile[i] = Material(i) - return - - def CheckMaterials(self): - for n in self.MaterialFile: - mprint = 0 - m = self.MaterialFile[n] - #print "\n\n"+n - for l in m.Line: - if(l.Type == 'c'): - continue - - if(l.Indentation > 0): - t = l.Text.split("/common/") - if(len(t) > 1): - continue - - t = l.Text.split("/lights/") - if(len(t) > 1): - continue - - t = l.Text.split("/hell/") - if(len(t) > 1): - continue - - t = l.Text.split("/glass/") - if(len(t) > 1): - continue - - t = l.Text.split("/monsters/") - if(len(t) > 1): - continue - - t = l.Text.split("/sfx/") - if(len(t) > 1): - continue - - t = l.Text.split("/editor/") - if(len(t) > 1): - continue - - s = "models/" - t = l.Text.strip().split(s) - if(len(t) == 1): - s = "textures/" - t = l.Text.strip().split(s) - - if(len(t) > 1): - tex = s+t[1] - t = tex.split(",") - if(len(t) > 1): - tex = t[0] - - t = tex.split("(") - if(len(t) > 1): - tex = t[0] - - t = tex.split(")") - if(len(t) > 1): - tex = t[0] - - t = tex.split("//") - if(len(t) > 1): - tex = t[0].strip() - - t = tex.split(" ") - if(len(t) > 1): - tex = t[0].strip() - - t = tex.split("\t") - if(len(t) > 1): - tex = t[0].strip() - - t = tex.split(".") - ext = "*" - wildcard = 1 - if(len(t) > 1): - if(t[1][0:1] == '.'): - ext = t[1] - wildcard = 0 - - tex = t[0] - #print tex+" ."+ext - - dds = 0 - fl = glob.glob(SrcPath+"/"+tex+"."+ext) - if(len(fl) == 0): - dds = 1 - fl = glob.glob(SrcPath+"/dds/"+tex+"."+ext) - - if(len(fl) == 0): - if(mprint == 0): - print "\n"+n - mprint = 1 - - if(wildcard == 1): - print "Missing:"+l.LineNumber.__repr__()+": "+tex - else: - print "Missing:"+l.LineNumber.__repr__()+": "+tex+"."+ext - else: - if(dds == 1): - if(mprint == 0): - print "\n"+n - mprint = 1 - - #if(wildcard == 1): - #print "DDS only:"+l.LineNumber.__repr__()+": "+tex - #else: - #print "DDS only:"+l.LineNumber.__repr__()+":"+tex+"."+ext - - - return - -def Usage(): - print "USAGE: materialcheck mod_root" - sys.exit(1) - -if __name__ == '__main__': - if len(sys.argv) <= 1: - Usage() - - SrcPath = sys.argv[1] - mat = MaterialCheck() - mat.CheckMaterials() - - sys.exit(0) diff --git a/scripts/texture_reorg/model_rename b/scripts/texture_reorg/model_rename deleted file mode 100644 index dfea5fd03..000000000 --- a/scripts/texture_reorg/model_rename +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/python - -# This script replaces a string in a file with another. -# model_rename -i inputfile - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - -class Line: - def __init__(self): - self.LineNumber = -1 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Text + "' ]" - -class File: - def __init__(self, name): - self.Filename = name - self.Modified = 0 - self.Line = [] - self.PreLoadFile(name) - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def PreLoadFile(self, filename): - f = open(filename) - b = f.read() - f.close() - - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - b = b.split("\n") - - r = Line() - nr = 0 - - for l in b: - s = l.strip() - - nr = nr + 1 - r.Text = l - r.LineNumber = nr - - self.Line.append(r) - r = Line() - - return - - def ReplaceString(self, old, new): - rc = 0 - #print old, new - for i in self.Line: - t = i.Text.split(old) - if(len(t) <= 1): - continue - - b = 0 - t = i.Text.split('"model"') - if(len(t) > 1): - b = 1 - - if(b == 0): - t = i.Text.split('model') - if(len(t) <= 1): - continue - - if(b == 0): - i.Text = 'model '+new - else: - i.Text = '"model" "'+new+'"' - - rc = 1 - - return rc - -class ModelRename: - def __init__(self): - self.Map = {} - - def LoadInput(self, fn): - fl = open(fn, "r+b") - b = fl.read() - fl.close() - - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - b = b.split("\n") - - for l in b: - t = l.split(" ") - if(len(t) <= 1): - continue - - o = t[0] - n = t[1] - self.Map[o] = n - #print o, n - return - - def Replace(self, fn): - mat = File(fn) - rc = 0 - for i in self.Map: - o = i.split(" ")[0] - n = self.Map[i].split(" ")[0] - #print o, n - rc = rc + mat.ReplaceString(o, n) - - if(rc != 0): - #fl = open(fn+".new", "w+b") - fl = open(fn, "w+b") - print fn+" ... updating" - for i in mat.Line: - fl.write(i.Text+"\n") - fl.close() - return - -def Usage(): - print "USAGE: texture_rename -i inputfile " - sys.exit(1) - -if __name__ == '__main__': - fl = 0 - if len(sys.argv) <= 1: - Usage() - - sr = ModelRename() - - i = 0 - n = len(sys.argv) - - if(n <= 2): - Usage() - - if sys.argv[1] == '-i': - if(n <= 3): - Usage() - i = 3 - fl = 1 - sr.LoadInput(sys.argv[2]) - - if fl == 0: - Usage() - - while( i < n): - fn = sys.argv[i] - #print "Processing "+fn - sr.Replace(fn) - i = i + 1 - - sys.exit(0) diff --git a/scripts/texture_reorg/model_reorg.txt b/scripts/texture_reorg/model_reorg.txt deleted file mode 100644 index ff2e7823b..000000000 --- a/scripts/texture_reorg/model_reorg.txt +++ /dev/null @@ -1,388 +0,0 @@ -models/darkmod/props/furniture/bookshelf1.lwo models/darkmod/props/furniture/shelves/bookshelf1.lwo -models/darkmod/furniture/wchair1.lwo models/darkmod/furniture/seating/wchair1.lwo -models/darkmod/decorative/stoup_broken.ase models/darkmod/junk/stoup_broken.ase -models/darkmod/decorative/vases/vase2_broken.ase models/darkmod/junk/vase2_broken.ase -models/darkmod/decorative/vases/vase2_broken_bottom.ase models/darkmod/junk/vase2_broken_bottom.ase -models/darkmod/decorative/vases/vase2_broken_handle.ase models/darkmod/junk/vase2_broken_handle.ase -models/darkmod/decorative/vases/vase2_broken_top.ase models/darkmod/junk/vase2_broken_top.ase -models/darkmod/props/gen/gen_bucket.lwo models/darkmod/containers/gen_bucket.lwo -models/darkmod/props/gen/gen_goblet1.lwo models/darkmod/kitchen/gen_goblet1.lwo -models/darkmod/props/gen/gen_squarestreetlamp.lwo models/darkmod/lights/non-extinguishable/streetlamps/gen_squarestreetlamp.lwo -models/darkmod/props/gen/gen_waterpump.lwo models/darkmod/waterworks/gen_waterpump.lwo -models/darkmod/props/graveyard/bone.ase models/darkmod/graveyard/bones/bone.ase -models/darkmod/props/graveyard/bones_arm_left.ase models/darkmod/graveyard/bones/bones_arm_left.ase -models/darkmod/props/graveyard/bones_arm_right.ase models/darkmod/graveyard/bones/bones_arm_right.ase -models/darkmod/props/graveyard/bones_legs.ase models/darkmod/graveyard/bones/bones_legs.ase -models/darkmod/props/graveyard/bones_leg_left.ase models/darkmod/graveyard/bones/bones_leg_left.ase -models/darkmod/props/graveyard/bones_leg_right.ase models/darkmod/graveyard/bones/bones_leg_right.ase -models/darkmod/props/graveyard/bones_spine.ase models/darkmod/graveyard/bones/bones_spine.ase -models/darkmod/props/graveyard/grave_big_1.lwo models/darkmod/graveyard/grave_big_1.lwo -models/darkmod/props/graveyard/grave_big_2.lwo models/darkmod/graveyard/grave_big_2.lwo -models/darkmod/props/graveyard/grave_big_3.lwo models/darkmod/graveyard/grave_big_3.lwo -models/darkmod/props/graveyard/grave_big_4.lwo models/darkmod/graveyard/grave_big_4.lwo -models/darkmod/props/graveyard/grave_big_5.lwo models/darkmod/graveyard/grave_big_5.lwo -models/darkmod/props/graveyard/grave_chain_broken.lwo models/darkmod/graveyard/grave_chain_broken.lwo -models/darkmod/props/graveyard/grave_chain_long.lwo models/darkmod/graveyard/grave_chain_long.lwo -models/darkmod/props/graveyard/grave_chain_short.lwo models/darkmod/graveyard/grave_chain_short.lwo -models/darkmod/props/graveyard/grave_fence.lwo models/darkmod/graveyard/grave_fence.lwo -models/darkmod/props/graveyard/grave_fence_pole.lwo models/darkmod/graveyard/grave_fence_pole.lwo -models/darkmod/props/graveyard/grave_pole.lwo models/darkmod/graveyard/grave_pole.lwo -models/darkmod/props/graveyard/grave_rectangle.lwo models/darkmod/graveyard/grave_rectangle.lwo -models/darkmod/props/graveyard/grave_rect_flinder.lwo models/darkmod/graveyard/grave_rect_flinder.lwo -models/darkmod/props/graveyard/grave_rect_ruined.lwo models/darkmod/props/graveyard/grave_rect_ruined.lwo -models/darkmod/props/graveyard/grave_simple_1.lwo models/darkmod/graveyard/grave_simple_1.lwo -models/darkmod/props/graveyard/grave_simple_2.lwo models/darkmod/graveyard/grave_simple_2.lwo -models/darkmod/props/graveyard/grave_simple_3.lwo models/darkmod/graveyard/grave_simple_3.lwo -models/darkmod/props/graveyard/grave_simple_4.lwo models/darkmod/graveyard/grave_simple_4.lwo -models/darkmod/props/graveyard/grave_simple_5.lwo models/darkmod/graveyard/grave_simple_5.lwo -models/darkmod/props/graveyard/grave_wall_1.lwo models/darkmod/graveyard/grave_wall_1.lwo -models/darkmod/props/graveyard/grave_wall_2.lwo models/darkmod/props/graveyard/grave_wall_2.lwo -models/darkmod/props/graveyard/sarcophagus_closed.lwo models/darkmod/graveyard/sarcophagus_closed.lwo -models/darkmod/props/graveyard/sarcophagus_lid.lwo models/darkmod/graveyard/sarcophagus_lid.lwo -models/darkmod/props/graveyard/sarcophagus_open.lwo models/darkmod/graveyard/sarcophagus_open.lwo -models/darkmod/props/graveyard/sarcophagus_ruined.lwo models/darkmod/graveyard/sarcophagus_ruined.lwo -models/darkmod/props/graveyard/sarcophagus_small_1.lwo models/darkmod/graveyard/sarcophagus_small_1.lwo -models/darkmod/props/graveyard/sarcophagus_small_2.lwo models/darkmod/graveyard/sarcophagus_small_2.lwo -models/darkmod/props/graveyard/skull.lwo models/darkmod/graveyard/bones/skull.lwo -models/darkmod/props/graveyard/skull2.ase models/darkmod/graveyard/bones/skull2.ase -models/darkmod/props/graveyard/skull2.cm models/darkmod/graveyard/bones/skull2.cm -models/darkmod/props/graveyard/urn.ase models/darkmod/graveyard/urn.ase -models/darkmod/props/junk/bc_ceramicpot_b.ase models/darkmod/junk/bc_ceramicpot_b.ase -models/darkmod/props/junk/broken_cart.lwo models/darkmod/junk/broken_cart.lwo -models/darkmod/props/junk/cartwheel.lwo models/darkmod/junk/cartwheel.lwo -models/darkmod/props/junk/plank_long.lwo models/darkmod/junk/plank_long.lwo -models/darkmod/props/junk/plank_longer.lwo models/darkmod/junk/plank_longer.lwo -models/darkmod/props/junk/plank_short.lwo models/darkmod/junk/plank_short.lwo -models/darkmod/props/junk/wbottle01_broken.lwo models/darkmod/junk/wbottle01_broken.lwo -models/darkmod/props/junk/flinders/ceramicflind01.ase models/darkmod/junk/generic_shards/ceramicflind01.ase -models/darkmod/props/junk/flinders/ceramicflind02.ase models/darkmod/junk/generic_shards/ceramicflind02.ase -models/darkmod/props/junk/flinders/ceramicflind03.ase models/darkmod/junk/generic_shards/ceramicflind03.ase -models/darkmod/props/junk/flinders/ceramicflind04.ase models/darkmod/junk/generic_shards/ceramicflind04.ase -models/darkmod/props/kitchen/bottle01.lwo models/darkmod/kitchen/bottle01.lwo -models/darkmod/props/kitchen/bottle02.lwo models/darkmod/kitchen/bottle02.lwo -models/darkmod/props/kitchen/cake.lwo models/darkmod/kitchen/food/cake.lwo -models/darkmod/props/kitchen/chamberpot.lwo models/darkmod/kitchen/chamberpot.lwo -models/darkmod/props/kitchen/cheapbeermug.lwo models/darkmod/kitchen/cheapbeermug.lwo -models/darkmod/props/kitchen/cookpot.lwo models/darkmod/kitchen/cookpot.lwo -models/darkmod/props/kitchen/fork_ornamental.lwo models/darkmod/kitchen/utensils/fork_ornamental.lwo -models/darkmod/props/kitchen/goblet2.lwo models/darkmod/kitchen/goblet2.lwo -models/darkmod/props/kitchen/hanging_goose.ase models/darkmod/kitchen/food/hanging_goose.ase -models/darkmod/props/kitchen/jar1.lwo models/darkmod/kitchen/jar1.lwo -models/darkmod/props/kitchen/knife_ornamental.lwo models/darkmod/kitchen/utensils/knife_ornamental.lwo -models/darkmod/props/kitchen/muffin.lwo models/darkmod/kitchen/food/muffin.lwo -models/darkmod/props/kitchen/plate_s.lwo models/darkmod/kitchen/plate_s.lwo -models/darkmod/props/kitchen/sack1.lwo models/darkmod/containers/sack1.lwo -models/darkmod/props/kitchen/sack_bent.lwo models/darkmod/containers/sack_bent.lwo -models/darkmod/props/kitchen/sack_closed.lwo models/darkmod/containers/sack_closed.lwo -models/darkmod/props/kitchen/smspoon_ornamental.lwo models/darkmod/kitchen/utensils/smspoon_ornamental.lwo -models/darkmod/props/kitchen/spoon_ornamental.lwo models/darkmod/kitchen/utensils/spoon_ornamental.lwo -models/darkmod/props/kitchen/wbottle01.cm models/darkmod/kitchen/wbottle01.cm -models/darkmod/props/kitchen/wbottle01.lwo models/darkmod/kitchen/wbottle01.lwo -models/darkmod/props/kitchen/food/bc_carrot.ase models/darkmod/kitchen/food/bc_carrot.ase -models/darkmod/props/kitchen/food/bc_turnip.ase models/darkmod/kitchen/food/bc_turnip.ase -models/darkmod/props/lights/extinguishable/bracket.lwo models/darkmod/hangers/bracket.lwo -models/darkmod/props/lights/extinguishable/candelabra01.lwo models/darkmod/lights/extinguishable/candelabra01.lwo -models/darkmod/props/lights/extinguishable/candle1.lwo models/darkmod/lights/extinguishable/candle1.lwo -models/darkmod/props/lights/extinguishable/candle2.lwo models/darkmod/lights/extinguishable/candle2.lwo -models/darkmod/props/lights/extinguishable/candlestick1.cm models/darkmod/lights/extinguishable/candlestick1.cm -models/darkmod/props/lights/extinguishable/candlestick1.lwo models/darkmod/lights/extinguishable/candlestick1.lwo -models/darkmod/props/lights/extinguishable/candlestick2.cm models/darkmod/lights/extinguishable/candlestick2.cm -models/darkmod/props/lights/extinguishable/candlestick2.lwo models/darkmod/lights/extinguishable/candlestick2.lwo -models/darkmod/props/lights/extinguishable/candlestickholder.lwo models/darkmod/lights/extinguishable/candlestickholder.lwo -models/darkmod/props/lights/extinguishable/candle_holder.lwo models/darkmod/lights/extinguishable/candle_holder.lwo -models/darkmod/props/lights/extinguishable/chandelier1.lwo models/darkmod/lights/extinguishable/chandelier1.lwo -models/darkmod/props/lights/extinguishable/flame_stand.ase models/darkmod/lights/extinguishable/flame_stand.ase -models/darkmod/props/lights/extinguishable/gaslight4.lwo models/darkmod/lights/extinguishable/gaslight4.lwo -models/darkmod/props/lights/extinguishable/sq_torch.lwo models/darkmod/lights/extinguishable/sq_torch.lwo -models/darkmod/props/lights/extinguishable/standing_torch01.lwo models/darkmod/lights/extinguishable/standing_torch01.lwo -models/darkmod/props/lights/extinguishable/torch.lwo models/darkmod/lights/extinguishable/torch.lwo -models/darkmod/props/lights/extinguishable/torch_metal.ase models/darkmod/lights/extinguishable/torch_metal.ase -models/darkmod/props/lights/extinguishable/torch_metal_wall.ase models/darkmod/lights/extinguishable/torch_metal_wall.ase -models/darkmod/props/lights/extinguishable/wallcandles1.lwo models/darkmod/lights/extinguishable/wallcandles1.lwo -models/darkmod/props/lights/non-extinguishable/arclight.lwo models/darkmod/lights/non-extinguishable/arclight.lwo -models/darkmod/props/lights/non-extinguishable/bc_desklamp01.ase models/darkmod/lights/non-extinguishable/bc_desklamp01.ase -models/darkmod/props/lights/non-extinguishable/bc_lantern.ase models/darkmod/lights/non-extinguishable/bc_lantern.ase -models/darkmod/props/lights/non-extinguishable/bc_sphere_wall_light.ase models/darkmod/lights/non-extinguishable/bc_sphere_wall_light.ase -models/darkmod/props/lights/non-extinguishable/bc_streetlamp01.ase models/darkmod/lights/non-extinguishable/streetlamps/bc_streetlamp01.ase -models/darkmod/props/lights/non-extinguishable/bc_streetlampspot.ase models/darkmod/lights/non-extinguishable/streetlamps/bc_streetlampspot.ase -models/darkmod/props/lights/non-extinguishable/bc_streetlamp_double.ase models/darkmod/lights/non-extinguishable/streetlamps/bc_streetlamp_double.ase -models/darkmod/props/lights/non-extinguishable/bc_wall_lamp.ase models/darkmod/lights/non-extinguishable/bc_wall_lamp.ase -models/darkmod/props/lights/non-extinguishable/grill_light.lwo models/darkmod/lights/non-extinguishable/grill_light.lwo -models/darkmod/props/lights/non-extinguishable/hanging_lantern.lwo models/darkmod/lights/non-extinguishable/hanging_lantern.lwo -models/darkmod/props/lights/non-extinguishable/hlamp.lwo models/darkmod/lights/non-extinguishable/hlamp.lwo -models/darkmod/props/lights/non-extinguishable/hooded_lantern.lwo models/darkmod/lights/non-extinguishable/hooded_lantern.lwo -models/darkmod/props/lights/non-extinguishable/lamp_shaded.lwo models/darkmod/lights/non-extinguishable/lamp_shaded.lwo -models/darkmod/props/lights/non-extinguishable/roundstreetlamp.lwo models/darkmod/lights/non-extinguishable/streetlamps/roundstreetlamp.lwo -models/darkmod/props/lights/non-extinguishable/ship_lamp.lwo models/darkmod/lights/non-extinguishable/ship_lamp.lwo -models/darkmod/props/lights/non-extinguishable/squarehanginglamp.lwo models/darkmod/lights/non-extinguishable/squarehanginglamp.lwo -models/darkmod/props/lights/non-extinguishable/squarestreetlamp.lwo models/darkmod/lights/non-extinguishable/streetlamps/squarestreetlamp.lwo -models/darkmod/props/lights/non-extinguishable/streetlamp1.lwo models/darkmod/lights/non-extinguishable/streetlamps/streetlamp1.lwo -models/darkmod/props/lights/non-extinguishable/wallight1.lwo models/darkmod/lights/non-extinguishable/wallight1.lwo -models/darkmod/props/lights/non-extinguishable/wallight2.lwo models/darkmod/lights/non-extinguishable/wallight2.lwo -models/darkmod/props/lights/non-extinguishable/wallight_outdoor3.lwo models/darkmod/lights/non-extinguishable/wallight_outdoor3.lwo -models/darkmod/props/loot/amulet_round_g.lwo models/darkmod/loot/jewellery/amulet_round_g.lwo -models/darkmod/props/loot/bc_bagdiamond.ase models/darkmod/loot/bc_bagdiamond.ase -models/darkmod/props/loot/bc_baggems.ase models/darkmod/loot/bc_baggems.ase -models/darkmod/props/loot/bc_trophy.ase models/darkmod/loot/bc_trophy.ase -models/darkmod/props/loot/coinsa.lwo models/darkmod/loot/coins/coinsa.lwo -models/darkmod/props/loot/coinsb.lwo models/darkmod/loot/coins/coinsb.lwo -models/darkmod/props/loot/coinsc.lwo models/darkmod/loot/coins/coinsc.lwo -models/darkmod/props/loot/diamond.lwo models/darkmod/loot/diamond.lwo -models/darkmod/props/loot/diamond_large.ase models/darkmod/loot/diamond_large.ase -models/darkmod/props/loot/diamond_large.cm models/darkmod/loot/diamond_large.cm -models/darkmod/props/loot/goblet1.lwo models/darkmod/loot/goblet1.lwo -models/darkmod/props/loot/gold_coin.lwo models/darkmod/loot/coins/gold_coin.lwo -models/darkmod/props/loot/plate_g.lwo models/darkmod/loot/plate_g.lwo -models/darkmod/props/loot/purse_p.lwo models/darkmod/loot/purse_p.lwo -models/darkmod/props/loot/purse_p_belt.lwo models/darkmod/loot/purse_p_belt.lwo -models/darkmod/props/loot/purse_p_goldspilt.lwo models/darkmod/loot/coins/purse_p_goldspilt.lwo -models/darkmod/props/loot/religious_symbol01.lwo models/darkmod/loot/religious_symbol01.lwo -models/darkmod/props/loot/religious_symbol01_small.lwo models/darkmod/loot/religious_symbol01_small.lwo -models/darkmod/props/loot/ring_diamond.lwo models/darkmod/loot/jewellery/ring_diamond.lwo -models/darkmod/props/loot/ring_ruby.lwo models/darkmod/loot/jewellery/ring_ruby.lwo -models/darkmod/props/loot/ruby.lwo models/darkmod/loot/ruby.lwo -models/darkmod/props/loot/scepter.ase models/darkmod/loot/scepter.ase -models/darkmod/props/loot/smallbowl.lwo models/darkmod/loot/smallbowl.lwo -models/darkmod/props/loot/statue_loot.ase models/darkmod/loot/statue_loot.ase -models/darkmod/props/loot/vase_g.lwo models/darkmod/loot/vase_g.lwo -models/darkmod/props/loot/wbottle03.lwo models/darkmod/loot/wbottle03.lwo -models/darkmod/props/mechanical/fan.lwo -models/darkmod/props/mechanical/gear.lwo models/darkmod/mechanical/gears/gear.lwo -models/darkmod/props/mechanical/gear_clock_hand_1.lwo models/darkmod/mechanical/gear_clock_hand_1.lwo -models/darkmod/props/mechanical/gear_clock_hand_2.lwo models/darkmod/mechanical/gear_clock_hand_2.lwo -models/darkmod/props/mechanical/gear_hollow_2_spoke.lwo models/darkmod/mechanical/gears/gear_hollow_2_spoke.lwo -models/darkmod/props/mechanical/gear_hollow_3_spoke.lwo models/darkmod/mechanical/gears/gear_hollow_3_spoke.lwo -models/darkmod/props/mechanical/gear_hollow_4_spoke.lwo models/darkmod/mechanical/gears/gear_hollow_4_spoke.lwo -models/darkmod/props/mechanical/gear_hollow_5_spoke.lwo models/darkmod/mechanical/gears/gear_hollow_5_spoke.lwo -models/darkmod/props/mechanical/gear_large_hollow_5_spoke.lwo models/darkmod/mechanical/gears/gear_large_hollow_5_spoke.lwo -models/darkmod/props/mechanical/gear_small.lwo models/darkmod/mechanical/gears/gear_small.lwo -models/darkmod/props/mechanical/gear_small_hollow_2_spoke.lwo models/darkmod/mechanical/gears/gear_small_hollow_2_spoke.lwo -models/darkmod/props/mechanical/gear_small_hollow_3_spoke.lwo models/darkmod/mechanical/gears/gear_small_hollow_3_spoke.lwo -models/darkmod/props/mechanical/gear_small_hollow_4_spoke.lwo models/darkmod/mechanical/gears/gear_small_hollow_4_spoke.lwo -models/darkmod/props/mechanical/gear_small_hollow_5_spoke.lwo models/darkmod/mechanical/gears/gear_small_hollow_5_spoke.lwo -models/darkmod/props/mechanical/generator1.lwo models/darkmod/mechanical/generator1.lwo -models/darkmod/props/mechanical/generator_big.lwo models/darkmod/mechanical/generator_big.lwo -models/darkmod/props/mechanical/numberwheel.lwo models/darkmod/mechanical/numberwheel.lwo -models/darkmod/props/mechanical/numberwheel_button.lwo models/darkmod/mechanical/numberwheel_button.lwo -models/darkmod/props/mechanical/numberwheel_lever.lwo models/darkmod/mechanical/switches/numberwheel_lever.lwo -models/darkmod/props/mechanical/numberwheel_main.lwo models/darkmod/mechanical/numberwheel_main.lwo -models/darkmod/props/mechanical/watermill_cogwheel_big.ase models/darkmod/mechanical/gears/watermill_cogwheel_big.ase -models/darkmod/props/mechanical/watermill_cogwheel_small.ase models/darkmod/mechanical/gears/watermill_cogwheel_small.ase -models/darkmod/props/mechanical/watermill_pole.ase models/darkmod/mechanical/watermill_pole.ase -models/darkmod/props/mechanical/watermill_wheel.ase models/darkmod/mechanical/watermill_wheel.ase -models/darkmod/props/mechanical/gauges/bc_gaugesteam.ase models/darkmod/mechanical/gauges/bc_gaugesteam.ase -models/darkmod/props/mechanical/gauges/bc_r_gaugeneedle.ase models/darkmod/mechanical/gauges/bc_r_gaugeneedle.ase -models/darkmod/props/mechanical/gauges/bc_squaregauge.ase models/darkmod/mechanical/gauges/bc_squaregauge.ase -models/darkmod/props/mechanical/gauges/bc_s_gaugeneedle.ase models/darkmod/mechanical/gauges/bc_s_gaugeneedle.ase -models/darkmod/props/mechanical/smokestacks/smokestack_short_wall.ase models/darkmod/mechanical/smokestack_short_wall.ase -models/darkmod/props/mechanical/smokestacks/smokestack_tall_wall.ase models/darkmod/mechanical/smokestack_tall_wall.ase -models/darkmod/props/mechanical/valves/valve1_large.ase models/darkmod/mechanical/pipes/valve1_large.ase -models/darkmod/props/mechanical/valves/valve1_small.ase models/darkmod/mechanical/pipes/valve1_small.ase -models/darkmod/props/mechanical/valves/valve1_xl.ase models/darkmod/mechanical/pipes/valve1_xl.ase -models/darkmod/props/mechanical/valves/valve2_large.ase models/darkmod/mechanical/pipes/valve2_large.ase -models/darkmod/props/mechanical/valves/valve2_small.ase models/darkmod/mechanical/pipes/valve2_small.ase -models/darkmod/props/mechanical/valves/valve2_xl.ase models/darkmod/mechanical/pipes/valve2_xl.ase -models/darkmod/props/misc/anchor.lwo models/darkmod/nautical/anchor.lwo -models/darkmod/props/misc/bell01.ase models/darkmod/misc/bell01.ase -models/darkmod/props/misc/bell02.ase models/darkmod/misc/bell02.ase -models/darkmod/props/misc/cart_low.lwo models/darkmod/misc/cart_low.lwo -models/darkmod/props/misc/dice.ase models/darkmod/decorative/games/dice.ase -models/darkmod/props/misc/empty.lwo models/darkmod/misc/empty.lwo -models/darkmod/props/misc/ink&quill.lwo models/darkmod/misc/ink&quill.lwo -models/darkmod/props/misc/marketstall.lwo models/darkmod/misc/marketstall.lwo -models/darkmod/props/misc/perftestmulti.lwo models/darkmod/misc/system/perftestmulti.lwo -models/darkmod/props/misc/perftestmulti0.lwo models/darkmod/misc/system/perftestmulti0.lwo -models/darkmod/props/misc/rope_coil01.lwo models/darkmod/misc/rope_coil01.lwo -models/darkmod/props/misc/staff.lwo models/darkmod/misc/staff.lwo -models/darkmod/props/misc/strawbale_large01.lwo models/darkmod/misc/strawbale_large01.lwo -models/darkmod/props/misc/strawbale_small01.lwo models/darkmod/misc/strawbale_small01.lwo -models/darkmod/props/misc/waterpump.ase models/darkmod/waterworks/waterpump.ase -models/darkmod/props/misc/well.lwo models/darkmod/waterworks/well.lwo -models/darkmod/props/misc/well_square.lwo models/darkmod/waterworks/well_square.lwo -models/darkmod/props/misc/wheelbarrow01.lwo models/darkmod/tools/wheelbarrow01.lwo -models/darkmod/props/misc/wheelbarrow02.lwo models/darkmod/tools/wheelbarrow02.lwo -models/darkmod/props/misc/wood_pallette.lwo models/darkmod/misc/wood_pallette.lwo -models/darkmod/props/musical/bc_doublebass.ase models/darkmod/musical/bc_doublebass.ase -models/darkmod/props/musical/grammo3.ase models/darkmod/musical/grammo3.ase -models/darkmod/props/musical/lyre.lwo models/darkmod/musical/lyre.lwo -models/darkmod/props/musical/notestand.ase models/darkmod/furniture/notestand.ase -models/darkmod/props/nautical/boat1.lwo models/darkmod/nautical/boat1.lwo -models/darkmod/props/nautical/boat2.lwo models/darkmod/nautical/boat2.lwo -models/darkmod/props/nautical/boat_wrecked.lwo models/darkmod/nautical/boat_wrecked.lwo -models/darkmod/props/nautical/oar.lwo models/darkmod/nautical/oar.lwo -models/darkmod/props/readables/bookrow1.lwo models/darkmod/readables/bookrow1.lwo -models/darkmod/props/readables/book_open1.lwo models/darkmod/readables/book_open1.lwo -models/darkmod/props/readables/book_red1.lwo models/darkmod/readables/book_red1.lwo -models/darkmod/props/readables/book_t1.lwo models/darkmod/readables/book_t1.lwo -models/darkmod/props/readables/gui_book_open01.cm models/darkmod/readables/gui_book_open01.cm -models/darkmod/props/readables/gui_book_open01.lwo models/darkmod/readables/gui_book_open01.lwo -models/darkmod/props/readables/gui_paper0.lwo models/darkmod/readables/gui_paper0.lwo -models/darkmod/props/readables/gui_paper01.cm models/darkmod/readables/gui_paper01.cm -models/darkmod/props/readables/gui_paper01.lwo models/darkmod/readables/gui_paper01.lwo -models/darkmod/props/readables/gui_scroll01.cm models/darkmod/readables/gui_scroll01.cm -models/darkmod/props/readables/gui_scroll01.lwo models/darkmod/readables/gui_scroll01.lwo -models/darkmod/props/readables/paper1.lwo models/darkmod/readables/paper1.lwo -models/darkmod/props/readables/scroll1.lwo models/darkmod/readables/scroll1.lwo -models/darkmod/props/tools/anvil.lwo models/darkmod/tools/anvil.lwo -models/darkmod/props/tools/bc_broom.ase models/darkmod/tools/household/bc_broom.ase -models/darkmod/props/tools/broomstick.ase models/darkmod/tools/household/broomstick.ase -models/darkmod/props/tools/brush.lwo models/darkmod/tools/household/brush.lwo -models/darkmod/props/tools/mop.lwo models/darkmod/tools/household/mop.lwo -models/darkmod/props/tools/pickaxe.lwo models/darkmod/tools/pickaxe.lwo -models/darkmod/props/tools/smithyhammer.lwo models/darkmod/tools/smithyhammer.lwo -models/darkmod/props/tools/spade.lwo models/darkmod/tools/spade.lwo -models/darkmod/props/tools/laboratory/bc_flask1.ase models/darkmod/laboratory/bc_flask1.ase -models/darkmod/props/tools/laboratory/bc_flask2.ase models/darkmod/laboratory/bc_flask2.ase -models/darkmod/props/wearable/belt_buckle.lwo models/darkmod/wearable/belt_buckle.lwo -models/darkmod/props/wearable/belt_pouch.lwo models/darkmod/wearable/belt_pouch.lwo -models/darkmod/props/wearable/bg_pauldron_l.lwo models/darkmod/wearable/armour/bg_pauldron_l.lwo -models/darkmod/props/wearable/bg_pauldron_r.lwo models/darkmod/wearable/armour/bg_pauldron_r.lwo -models/darkmod/props/wearable/boot_large.lwo models/darkmod/wearable/boot_large.lwo -models/darkmod/props/wearable/breastplate.lwo models/darkmod/wearable/armour/breastplate.lwo -models/darkmod/props/wearable/broadbrim_hat.lwo models/darkmod/wearable/headgear/broadbrim_hat.lwo -models/darkmod/props/wearable/citywatch_helmet.lwo models/darkmod/wearable/headgear/citywatch_helmet.lwo -models/darkmod/props/wearable/cw_pauldron_l.lwo models/darkmod/wearable/armour/cw_pauldron_l.lwo -models/darkmod/props/wearable/cw_pauldron_r.lwo models/darkmod/wearable/armour/cw_pauldron_r.lwo -models/darkmod/props/wearable/ecw_pauldron_l.lwo models/darkmod/wearable/armour/ecw_pauldron_l.lwo -models/darkmod/props/wearable/ecw_pauldron_r.lwo models/darkmod/wearable/armour/ecw_pauldron_r.lwo -models/darkmod/props/wearable/elitecitywatch_helmet.lwo models/darkmod/wearable/headgear/elitecitywatch_helmet.lwo -models/darkmod/props/wearable/feather.lwo models/darkmod/wearable/feather.lwo -models/darkmod/props/wearable/head_gear.lwo models/darkmod/wearable/headgear/head_gear.lwo -models/darkmod/props/wearable/proguard_helmet.lwo models/darkmod/wearable/headgear/proguard_helmet.lwo -models/darkmod/props/wearable/quiver.lwo models/darkmod/wearable/quiver.lwo -models/darkmod/props/wearable/spectacles.ase models/darkmod/wearable/headgear/spectacles.ase -models/darkmod/props/wearable/woolen_cap.lwo models/darkmod/wearable/headgear/woolen_cap.lwo -models/darkmod/architecture/city_house/balcony1.lwo models/darkmod/architecture/buildings/city_house/balcony1.lwo -models/darkmod/architecture/city_house/chimne_left.lwo models/darkmod/architecture/buildings/city_house/chimne_left.lwo -models/darkmod/architecture/city_house/chimne_right.lwo models/darkmod/architecture/buildings/city_house/chimne_right.lwo -models/darkmod/architecture/city_house/roof_vault.lwo models/darkmod/architecture/buildings/city_house/roof_vault.lwo -models/darkmod/architecture/city_house/stone_ledge.lwo models/darkmod/architecture/buildings/city_house/stone_ledge.lwo -models/darkmod/architecture/city_house/window_stone_medium.lwo models/darkmod/architecture/buildings/city_house/window_stone_medium.lwo -models/darkmod/architecture/city_house/window_stone_small.lwo models/darkmod/architecture/buildings/city_house/window_stone_small.lwo -models/darkmod/architecture/city_house/wood_beams.lwo models/darkmod/architecture/buildings/city_house/wood_beams.lwo -models/darkmod/architecture/city_house2/balcony.lwo models/darkmod/architecture/buildings/city_house2/balcony.lwo -models/darkmod/architecture/city_house2/chimne_base.lwo models/darkmod/architecture/buildings/city_house2/chimne_base.lwo -models/darkmod/architecture/city_house2/window_frame_long.lwo models/darkmod/architecture/buildings/city_house2/window_frame_long.lwo -models/darkmod/architecture/city_house2/window_frame_medium.lwo models/darkmod/architecture/buildings/city_house2/window_frame_medium.lwo -models/darkmod/architecture/city_house2/window_frame_small.lwo models/darkmod/architecture/buildings/city_house2/window_frame_small.lwo -models/darkmod/architecture/city_house2/wood_frames.lwo models/darkmod/architecture/buildings/city_house2/wood_frames.lwo -models/darkmod/architecture/guardhouse/support_beam01.lwo models/darkmod/architecture/buildings/guardhouse/support_beam01.lwo -models/darkmod/architecture/guardhouse/window_frame_longroof.lwo models/darkmod/architecture/buildings/guardhouse/window_frame_longroof.lwo -models/darkmod/architecture/guardhouse/window_frame_smallw.lwo models/darkmod/architecture/buildings/guardhouse/window_frame_smallw.lwo -models/darkmod/architecture/guardhouse/window_frame_wide.lwo models/darkmod/architecture/buildings/guardhouse/window_frame_wide.lwo -models/darkmod/architecture/guardhouse/wood_frames3.lwo models/darkmod/architecture/buildings/guardhouse/wood_frames3.lwo -models/darkmod/architecture/guardhouse/wood_support_beams1.lwo models/darkmod/architecture/buildings/guardhouse/wood_support_beams1.lwo -models/darkmod/architecture/guardhouse/wood_support_beams2.lwo models/darkmod/architecture/buildings/guardhouse/wood_support_beams2.lwo -models/darkmod/architecture/guardhouse/wood_frames1.lwo models/darkmod/architecture/buildings/guardhouse/wood_frames1.lwo -models/darkmod/architecture/small_house/brick_wall.lwo models/darkmod/architecture/buildings/small_house/brick_wall.lwo -models/darkmod/architecture/small_house/chimne_smallh.lwo models/darkmod/architecture/buildings/small_house/chimne_smallh.lwo -models/darkmod/architecture/small_house/support_beams3.lwomodels/darkmod/architecture/buildings/small_house/support_beams3.lwo -models/darkmod/architecture/small_house/wood_beams2.lwo models/darkmod/architecture/buildings/small_house/wood_beams2.lwo -models/darkmod/architecture/small_house/wood_frames2.lwo models/darkmod/architecture/buildings/small_house/wood_frames2.lwo -models/darkmod/architecture/small_house/wood_shelter.lwo models/darkmod/architecture/buildings/small_house/wood_shelter.lwo -models/darkmod/architecture/bc_spiralstair.ase models/darkmod/architecture/stairs/bc_spiralstair.ase -models/darkmod/architecture/bc_spiralstair_norail.ase models/darkmod/architecture/stairs/bc_spiralstair_norail.ase -models/darkmod/architecture/bc_spiralstair_norail_half.ase models/darkmod/architecture/stairs/bc_spiralstair_norail_half.ase -models/darkmod/architecture/bc_spiralstair_norail_quar.ase models/darkmod/architecture/stairs/bc_spiralstair_norail_quar.ase -models/darkmod/architecture/handrail_corner_inside.lwo models/darkmod/architecture/handrails/handrail_corner_inside.lwo -models/darkmod/architecture/handrail_corner_outside.lwo models/darkmod/architecture/handrails/handrail_corner_outside.lwo -models/darkmod/architecture/handrail_section_l.lwo models/darkmod/architecture/handrails/handrail_section_l.lwo -models/darkmod/architecture/handrail_section_r.lwo models/darkmod/architecture/handrails/handrail_section_r.lwo -models/darkmod/architecture/ladder_16steps.ase models/darkmod/architecture/ladders/ladder_16steps.ase -models/darkmod/architecture/ladder_1step.ase models/darkmod/architecture/ladders/ladder_1step.ase -models/darkmod/architecture/ladder_2steps.ase models/darkmod/architecture/ladders/ladder_2steps.ase -models/darkmod/architecture/ladder_32steps.ase models/darkmod/architecture/ladders/ladder_32steps.ase -models/darkmod/architecture/ladder_3steps.ase models/darkmod/architecture/ladders/ladder_3steps.ase -models/darkmod/architecture/ladder_4steps.ase models/darkmod/architecture/ladders/ladder_4steps.ase -models/darkmod/architecture/ladder_8steps.ase models/darkmod/architecture/ladders/ladder_8steps.ase -models/darkmod/architecture/mansion_stairs_01.lwo models/darkmod/architecture/stairs/mansion_stairs_01.lwo -models/darkmod/architecture/mansion_stairs_01b.lwo models/darkmod/architecture/stairs/mansion_stairs_01b.lwo -models/darkmod/architecture/rail1.lwo models/darkmod/architecture/handrails/rail1.lwo -models/darkmod/architecture/stairway.ase models/darkmod/architecture/stairs/stairway.ase -models/darkmod/architecture/bonehoard/alcove.ase models/darkmod/map_specific/bonehoard/alcove.ase -models/darkmod/architecture/bonehoard/arch.ase models/darkmod/map_specific/bonehoard/arch.ase -models/darkmod/architecture/bonehoard/arch_2.ase models/darkmod/map_specific/bonehoard/arch_2.ase -models/darkmod/architecture/bonehoard/entrance.ase models/darkmod/map_specific/bonehoard/entrance.ase -models/darkmod/architecture/bonehoard/pillar.ase models/darkmod/map_specific/bonehoard/pillar.ase -models/darkmod/architecture/bonehoard/pillar_2.ase models/darkmod/map_specific/bonehoard/pillar_2.ase -models/darkmod/architecture/bonehoard/pillar_broken.ase models/darkmod/map_specific/bonehoard/pillar_broken.ase -models/darkmod/architecture/bonehoard/pillar_broken_part.ase models/darkmod/map_specific/bonehoard/pillar_broken_part.ase -models/darkmod/architecture/warehouse/warehouse_roof_d.tga models/darkmod/architecture/warehouse_roof_d.tga -models/darkmod/architecture/warehouse/warehouse_roof_local.tga models/darkmod/architecture/warehouse_roof_local.tga -models/darkmod/architecture/warehouse/wareouse_long_roof.lwo models/darkmod/architecture/wareouse_long_roof.lwo -models/darkmod/architecture/irongate.ase models/darkmod/architecture/fencing/irongate.ase -models/darkmod/architecture/irongatesegment.ase models/darkmod/architecture/fencing/irongatesegment.ase -models/darkmod/door_related/door02.lwo models/darkmod/architecture/doors/door02.lwo -models/darkmod/door_related/door1.lwo models/darkmod/architecture/doors/door1.lwo -models/darkmod/door_related/door104x56_2hinge.ase models/darkmod/architecture/doors/door104x56_2hinge.ase -models/darkmod/door_related/door104x56_3hinge.ase models/darkmod/architecture/doors/door104x56_3hinge.ase -models/darkmod/door_related/door128x56_2hinge.ase models/darkmod/architecture/doors/door128x56_2hinge.ase -models/darkmod/door_related/door128x56_3hinge.ase models/darkmod/architecture/doors/door128x56_3hinge.ase -models/darkmod/door_related/door96x48_2hinge.ase models/darkmod/architecture/doors/door96x48_2hinge.ase -models/darkmod/door_related/door96x48_3hinge.ase models/darkmod/architecture/doors/door96x48_3hinge.ase -models/darkmod/door_related/door_handle1.tga models/darkmod/architecture/doors/door_handle1.tga -models/darkmod/door_related/door_handle1_local.tga models/darkmod/architecture/doors/door_handle1_local.tga -models/darkmod/door_related/door_handle1_s.tga models/darkmod/architecture/doors/door_handle1_s.tga -models/darkmod/door_related/mansion_door_01.lwo models/darkmod/architecture/doors/mansion_door_01.lwo -models/darkmod/door_related/mansion_door_02.lwo models/darkmod/architecture/doors/mansion_door_02.lwo -models/darkmod/door_related/mansion_door_02_handle.lwo models/darkmod/architecture/doors/mansion_door_02_handle.lwo -models/darkmod/door_related/mansion_door_02_small.lwo models/darkmod/architecture/doors/mansion_door_02_small.lwo -models/darkmod/door_related/mansion_door_02_wide.lwo models/darkmod/architecture/doors/mansion_door_02_wide.lwo -models/darkmod/door_related/mansion_front_doorframe.lwo models/darkmod/architecture/doors/mansion_front_doorframe.lwo -models/darkmod/door_related/mansion_front_doorframe_b.lwo models/darkmod/architecture/doors/mansion_front_doorframe_b.lwo -models/darkmod/door_related/mansion_front_doorframe_nowindow.lwo models/darkmod/architecture/doors/mansion_front_doorframe_nowindow.lwo -models/darkmod/door_related/warehouse_front_doorframe.lwo models/darkmod/architecture/doors/warehouse_front_doorframe.lwo -models/darkmod/door_related/windowed_door_01.lwo models/darkmod/architecture/doors/windowed_door_01.lwo -models/darkmod/door_related/windowed_door_01b.lwo models/darkmod/architecture/doors/windowed_door_01b.lwo -models/darkmod/door_related/windowed_door_01_handle.lwo models/darkmod/architecture/doors/windowed_door_01_handle.lwo -models/darkmod/door_related/windowed_door_02.lwo models/darkmod/architecture/doors/windowed_door_02.lwo -models/darkmod/door_related/windowed_door_02b.lwo models/darkmod/architecture/doors/windowed_door_02b.lwo -models/darkmod/door_related/windowed_door_02c.lwo models/darkmod/architecture/doors/windowed_door_02c.lwo -models/darkmod/door_related/old_door_01.lwo models/darkmod/architecture/doors/old_door_01.lwo -models/darkmod/nature/rock_slab_01.lwo models/darkmod/nature/rocks/rock_slab_01.lwo -models/darkmod/nature/rock_slab_02.lwo models/darkmod/nature/rocks/rock_slab_02.lwo -models/darkmod/nature/rubble_huge_1.ase models/darkmod/nature/rocks/rubble_huge_1.ase -models/darkmod/nature/rubble_huge_2.ase models/darkmod/nature/rocks/rubble_huge_2.ase -models/darkmod/nature/rubble_large_1.ase models/darkmod/nature/rocks/rubble_large_1.ase -models/darkmod/nature/rubble_large_2.ase models/darkmod/nature/rocks/rubble_large_2.ase -models/darkmod/nature/rubble_large_3.ase models/darkmod/nature/rocks/rubble_large_3.ase -models/darkmod/nature/rubble_medium_1.ase models/darkmod/nature/rocks/rubble_medium_1.ase -models/darkmod/nature/rubble_medium_2.ase models/darkmod/nature/rocks/rubble_medium_2.ase -models/darkmod/nature/rubble_pieces_1.ase models/darkmod/nature/rocks/rubble_pieces_1.ase -models/props/pipekit/tap/tap1.lwo models/darkmod/mechanical/pipes/tap1.lwo -models/darkmod/nature/smallrock1.lwo models/darkmod/nature/rocks/smallrock1.lwo -models/darkmod/nature/smallrock2.lwo models/darkmod/nature/rocks/smallrock2.lwo -models/weapons/axe_rustic.lwo models/darkmod/weapons/axe_rustic.lwo -models/weapons/battleaxe.lwo models/darkmod/weapons/battleaxe.lwo -models/weapons/blackjack.lwo models/darkmod/weapons/blackjack.lwo -models/weapons/broadhead.lwo models/darkmod/weapons/broadhead.lwo -models/weapons/broadhead_broken1.lwo models/darkmod/junk/broadhead_broken1.lwo -models/weapons/broadhead_broken2.lwo models/darkmod/junk/broadhead_broken2.lwo -models/weapons/broadhead_broken_back.lwo models/darkmod/junk/broadhead_broken_back.lwo -models/weapons/broadhead_broken_tip.lwo models/darkmod/junk/broadhead_broken_tip.lwo -models/weapons/broadhead_collision.lwo models/darkmod/weapons/broadhead_collision.lwo -models/weapons/ceremonial_sword.lwo models/darkmod/weapons/ceremonial_sword.lwo -models/weapons/dagger.lwo models/darkmod/weapons/dagger.lwo -models/weapons/firearrow.lwo models/darkmod/weapons/firearrow.lwo -models/weapons/gasarrow.lwo models/darkmod/weapons/gasarrow.lwo -models/weapons/halberd.lwo models/darkmod/weapons/halberd.lwo -models/weapons/hammer.lwo models/darkmod/weapons/hammer.lwo -models/weapons/handaxe.lwo models/darkmod/weapons/handaxe.lwo -models/weapons/longbow.lwo models/darkmod/weapons/longbow.lwo -models/weapons/longbow_nostring.lwo models/darkmod/weapons/longbow_nostring.lwo -models/weapons/longbow_simple.lwo models/darkmod/weapons/longbow_simple.lwo -models/weapons/longbow_simple_nostring.lwo models/darkmod/weapons/longbow_simple_nostring.lwo -models/weapons/longswordlow.lwo models/darkmod/weapons/longswordlow.lwo -models/weapons/mace.lwo models/darkmod/weapons/mace.lwo -models/weapons/mossarrow.lwo models/darkmod/weapons/mossarrow.lwo -models/weapons/noisemaker.lwo models/darkmod/weapons/noisemaker.lwo -models/weapons/noisemaker_collision.lwo models/darkmod/weapons/noisemaker_collision.lwo -models/weapons/quarterstaff.lwo models/darkmod/weapons/quarterstaff.lwo -models/weapons/ropearrow.lwo models/darkmod/weapons/ropearrow.lwo -models/weapons/shortbow.lwo models/darkmod/weapons/shortbow.lwo -models/weapons/shortbow_simple.lwo models/darkmod/weapons/shortbow_simple.lwo -models/weapons/shortbow_simple_nostring.lwo models/darkmod/weapons/shortbow_simple_nostring.lwo -models/weapons/shortsword.lwo models/darkmod/weapons/shortsword.lwo -models/weapons/spear2.lwo models/darkmod/weapons/spear2.lwo -models/weapons/vinearrow.lwo models/darkmod/weapons/vinearrow.lwo -models/weapons/waterarrow.lwo models/darkmod/weapons/waterarrow.lwo diff --git a/scripts/texture_reorg/reorg b/scripts/texture_reorg/reorg deleted file mode 100644 index 921f07d53..000000000 --- a/scripts/texture_reorg/reorg +++ /dev/null @@ -1,486 +0,0 @@ -#!/usr/bin/python - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - - -LOGFILE="reorg_logfile.txt" -#SrcPath="/cygdrive/d/Home/cygwin/gruberg/darkmod" -#DstPath="/cygdrive/d/Home/cygwin/gruberg/darkmod_reorg" -SrcPath="/home/sparhawk/darkmod" -DstPath="/home/sparhawk/darkmod_reorg" - -material_list = {} - -class MaterialLine: - def __init__(self): - self.LineNumber = -1 - self.Type = 'l' - self.Indentation = 0 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Type + "', " + self.Indentation.__repr__() + ", '" + self.Text + "' ]" - -class Material: - def __init__(self, name): - self.Filename = name - self.Modified = 0 - self.Buffer = None - self.Line = [] - self.CacheFile() - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def CacheFile(self): - f = open(SrcPath+"/"+self.Filename) - self.Buffer = f.read() - f.close() - - b = self.Buffer.split("\n") - last = None - r = MaterialLine() - ind = 0 - prevind = 0 - nr = 0 - - for l in b: - t = l.split("\r") - if(len(t) > 1): - l = t[0] - - s = l.strip() - if s[0:1] == '{': - ind = ind + 1 - elif s[0:1] == '}': - ind = ind - 1 - - nr = nr + 1 - r.Indentation = ind - r.Text = l - r.LineNumber = nr - - # Check if we have found a material name - if ind == 1 and prevind == 0: - last.Type = 'n' - - self.Line.append(r) - last = r - r = MaterialLine() - prevind = ind - - return - -class Texture: - def __init__(self): - self.TextureName = "" - self.TextureExt = "" - self.TextureMaterial = "" - self.TexturePath = "" - - def __repr__(self): - return "['"+self.TexturePath+"', '" +self.TextureName + "', '" + self.TextureExt + "', " + self.TextureMaterial +"']" - -class TextureRecord: - def __init__(self): - self.mNew = Texture() - self.mOld = Texture() - self.MaterialFilename = {} - - def __repr__(self): - mat = "" - if self.MaterialFilename == None: - mat = "None" - else: - for i in self.MaterialFilename: - mat += "'"+i+"', " - - mat = mat[0:len(mat)-2] - - return "[* "+mat + "\n **" + self.mOld.__repr__() + "\n **" + self.mNew.__repr__()+" *]\n" - -class TextureReorg: - def __init__(self, Logfile, SrcPath, DstPath, InputFile): - self.mLogFile = self.OpenFile(Logfile, "w+b") - self.mInput = self.OpenFile(InputFile, "r+b") - self.mSrcPath = SrcPath - self.mDstPath = DstPath - self.TextureRecord = [] - self.MaterialFile = {} - self.CacheMaterials() - - try: - os.mkdir(DstPath + "/textures") - except OSError: - pass - try: - os.mkdir(DstPath + "/dds") - except OSError: - pass - try: - os.mkdir(DstPath + "/dds/textures") - except OSError: - pass - try: - os.mkdir(DstPath + "/materials") - except OSError: - pass - - def CacheMaterials(self): - print "Caching material files..." - name = glob.glob(SrcPath+"/materials/*") - for i in name: - i = i.split(SrcPath+"/")[1] - t = i.split("replacements.txt") - if(len(t) > 1): - continue - - t = i.split("gildoran_notes.txt") - if(len(t) > 1): - continue - - #print i - self.MaterialFile[i] = Material(i) - return - - def OpenFile(self, name, mode): - try: - fl = file(name, mode) - except IOError: - print "Couldn't open "+name - sys.exit(1) - return fl - - def ParseInput(self): - bSVN = 0 - bDir = 0 - dir = [] - path = "" - while 1: - ln = self.mInput.readline() - - if not ln: - break - - ln = ln.strip() - if(len(ln) == 0): - continue - - if(len(ln.split("Volume")) > 1): - continue - - if(len(ln.split("File(s)")) > 1): - continue - - if(len(ln.split("Total Files Listed:")) > 1): - continue - - if(len(ln.split("Dir(s)")) > 1): - continue - - if(len(ln.split("")) > 1): - continue - - # We need to get all directory names ... - t = ln.split("Directory of") - if(len(t) > 1): - bSVN = 0 - bDir = 1 - - # ... but only if it's not part of SVN - if(len(ln.split(".svn")) > 1): - bSVN = 1 - - if(bSVN == 1): - continue - - if(bDir == 1): - bDir = 0 - if(len(dir) != 0): - self.TextureRecord.append(dir) - - path = (t[1].strip().replace("\\", "/").split("D:/temp2/")[1]).strip() - try: - os.mkdir(DstPath + "/" + path) - os.mkdir(DstPath + "/dds/" + path) - except OSError: - pass - #print path - dir = [] - continue - - t = ln[39:] - v = t.split(".") - record = TextureRecord() - record.mNew.TexturePath = path - if(len(v) == 2): - #print "Texture has only one name:"+t - record.mNew.TextureName = v[0].strip() - record.mNew.TextureExt = v[1].strip() - record.mOld.TextureName = v[0].strip() - record.mOld.TextureExt = v[1].strip() - elif(len(v) == 4): - record.mOld.TextureName = v[2].strip() - record.mOld.TextureExt = v[3].strip() - record.mNew.TextureName = v[0].strip() - record.mNew.TextureExt = v[1].strip() - else: - print "Wrong number of arguments: "+ln - - dir.append(record) - m = self.TextureMaterial(record.mOld.TextureName, record.MaterialFilename) - if(m == None): - record.MaterialFilename = {} - print "No material: ["+ path +"] "+record.mOld.TextureName, t - - self.mInput.close() - - def SearchTexture(self, path, texname): - rc = None - - flist = scriptutil.ffind(path, namefs=(lambda s: '.svn' not in s, lambda s: texname in s,)) - #print len(flist), flist, path, texname - - if len(flist) == 1: - rc = flist[0] - elif len(flist) > 1: - print "File ["+texname+"] in more then one directory!", flist - - return rc - - def Exists(self, matarray, matname): - b = 0; - - for i in matarray: - if(matname == i): - #print matname + " Exists", matarray - b = 1 - break - - return b - - def TextureMaterial(self, tname, matarray): - rc = None - for n in self.MaterialFile: - m = self.MaterialFile[n] - t = m.Buffer.split(tname) - if(len(t) > 1): - matarray[n] = m - rc = m - - return rc - - def ReplaceTexture(self, mat, oname, nname, record): - rc = 0 - - if oname == nname: - return rc - - m = self.MaterialFile[mat] - ind = 0 - for l in m.Line: - if(l.Type == 'n'): - ind = l.LineNumber-1 - continue - - # Only check lins where the indentation is not 0 - # as this definitely can not be a valid textureline - if(l.Indentation > 0): - # Check if the texture is contained in that - # material line and if it is the real name. - # We have to check for the real name because - # otherwise partial names would also match - # which causes wrong entries. - t = l.Text.split(oname) - if(len(t) > 1): - if(len(t[1]) == 0 or t[1][0] == '.'): - sl = "textures/" - p = t[0].split(sl) - if(len(p) == 1): - p = t[0].split("textures\\") - - if(len(p) == 1): - sl = "models/" - p = t[0].split(sl) - - if(len(p) == 1): - p = t[0].split("models\\") - - t = p[1] - t = t[0:len(t)-1].replace("\\", "/") - record.mOld.TexturePath = sl+t - # Update the line in the material with the new texturepath - l.Text = p[0]+record.mNew.TexturePath+"/"+nname - m.Modified = m.Modified+1 - rc = 1 - - #print "Updating material: "+mat,m.Line[ind].Text, oname, nname, rc - list = {} - try: - list = material_list[mat] - except KeyError: - list = {} - material_list[mat] = list - - namelist = [] - try: - namelist = list[m.Line[ind].Text] - except KeyError: - namelist = {} - list[m.Line[ind].Text] = namelist - - namelist[oname] = nname - return rc - - def DumpMaterial(self, name): - #print "Material: "+name - m = self.MaterialFile[name] - - if(m.Modified == 0): - return - - #print "Updating: "+DstPath+"/"+name - fl = self.OpenFile(DstPath+"/"+name, "w+b") - for i in m.Line: - fl.write(i.Text+"\n") - fl.close() - return - - def ProcessReorg(self): - for dir in self.TextureRecord: - for record in dir: - for matname in record.MaterialFilename: - self.ReplaceTexture(matname, record.mOld.TextureName, record.mNew.TextureName, record) - - for n in self.MaterialFile: - self.DumpMaterial(n) - return - - def CreateUnusedTextureMaterials(self): - fl = self.OpenFile(DstPath+"/materials/"+"unknown.mtr", "w+b") - fl.write("# This file was automatically created by sparhawk for the texture reorganization\n") - fl.write("# materials here should be reviewed and then copied to the appropriate file.\n\n\n") - for dir in self.TextureRecord: - for record in dir: - if(len(record.MaterialFilename) == 0): - fl.write(record.mNew.TexturePath+"/"+record.mNew.TextureName+"\n") - fl.write("{\n") - fl.write(" diffusemap "+record.mNew.TexturePath+"/"+record.mNew.TextureName+"\n") - fl.write(" {\n") - fl.write(" if ( parm11 > 0 )\n") - fl.write(" blend gl_dst_color, gl_one\n") - fl.write(" map _white.tga\n") - fl.write(" rgb 0.40 * parm11\n") - fl.write(" }\n") - fl.write(" {\n") - fl.write(" if ( parm11 > 0 )\n") - fl.write(" blend add\n") - fl.write(" map "+record.mNew.TexturePath+"/"+record.mNew.TextureName+"\n") - fl.write(" rgb 0.15 * parm11\n") - fl.write(" }\n") - fl.write("}\n\n\n") - - fl.close() - return - - def SearchTexturePath(self, tname): - rc = None - - p1 = scriptutil.ffind(SrcPath+"/textures", namefs=(lambda s: '.svn' not in s, lambda s: tname in s,)) - p2 = scriptutil.ffind(SrcPath+"/dds/textures", namefs=(lambda s: '.svn' not in s, lambda s: tname in s,)) - path = p1 + p2 - - if(len(path) == 0): - print "No texturefile found: "+tname - elif(len(path) > 1): - for i in path: - t = i.split(tname) - if(len(t[1]) == 0 or t[1][0] == '.'): - rc = [i] - break - - if(rc == None): - print "Multiple textures found: ", path - else: - rc = path - - return rc - - def CopyTextures(self): - for dir in self.TextureRecord: - for record in dir: - sname = SrcPath+"/"+record.mOld.TexturePath+"/"+record.mOld.TextureName+"."+record.mOld.TextureExt - if(len(record.mOld.TexturePath) == 0): - if(self.SearchTexturePath(record.mOld.TextureName) == None): - print "No valid path for: "+record.mOld.TextureName - continue - - tname = DstPath+"/"+record.mNew.TexturePath+"/"+record.mNew.TextureName+"."+record.mNew.TextureExt - - b = None - try: - sfl = file(sname, "r+b") - b = sfl.read() - except IOError: - try: - sname = SrcPath+"/dds/"+record.mOld.TexturePath+"/"+record.mOld.TextureName+"."+record.mOld.TextureExt - tname = DstPath+"/dds/"+record.mNew.TexturePath+"/"+record.mNew.TextureName+"."+record.mNew.TextureExt - sfl = file(sname, "r+b") - b = sfl.read() - except IOError: - path = self.SearchTexturePath(record.mOld.TextureName) - if(path == None): - print "path lookup failed, giving up: ", record.mOld.TextureName - continue - - try: - sname = path[0] - sfl = file(sname, "r+b") - b = sfl.read() - except IOError: - print "Couldn't open target: "+sname - continue - - try: - tfl = file(tname, "w+b") - tfl.write(b) - except IOError: - print "Couldn't open target: "+tname - sfl.close() - continue - - sfl.close() - tfl.close() - - print "svn move " + sname.split(SrcPath+"/")[1] + " " + tname.split(DstPath+"/")[1] - return - -if __name__ == '__main__': - if len(sys.argv) <= 1: - print "USAGE: reorg Inputfile" - sys.exit(1) - - reorg = TextureReorg(LOGFILE, SrcPath, DstPath, sys.argv[1]) - reorg.ParseInput() - reorg.ProcessReorg() - reorg.CreateUnusedTextureMaterials() - reorg.CopyTextures() - - for n in material_list: - print "\n"+n - ml = material_list[n] - for n in ml: - print " "+n - names = ml[n] - for old in names: - print " ", old, names[old] - print - - sys.exit(0) diff --git a/scripts/texture_reorg/scriptutil.py b/scripts/texture_reorg/scriptutil.py deleted file mode 100644 index b0ae7333f..000000000 --- a/scripts/texture_reorg/scriptutil.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -""" -Module providing functions commonly used in shell scripting: - - - ffind() : finds files in a directory tree - - ffindgrep(): finds files in a directory tree and matches their - content to regular expressions - - freplace() : in-place search/replace of files in a directory tree - with regular expressions - - printr() : prints the results of the ffind()/ffindgrep() functions - -Please see the documentation strings of the particular functions for -detailed information. -""" - -# Copyright: (c) 2007 Muharem Hrnjadovic -# created: 15/04/2007 09:31:25 - -__version__ = "$Id:$" -# $HeadURL $ - -import os, sys, types, re, fnmatch - -class ScriptError(Exception): pass - -def ffind(path, shellglobs=None, namefs=None, relative=True): - """ - Finds files in the directory tree starting at 'path' (filtered by - Unix shell-style wildcards ('shellglobs') and/or the functions in - the 'namefs' sequence). - - The parameters are as follows: - - - path: starting path of the directory tree to be searched - - shellglobs: an optional sequence of Unix shell-style wildcards - that are to be applied to the file *names* found - - namefs: an optional sequence of functions to be applied to the - file *paths* found - - relative: a boolean flag that determines whether absolute or - relative paths should be returned - - Please not that the shell wildcards work in a cumulative fashion - i.e. each of them is applied to the full set of file *names* found. - - Conversely, all the functions in 'namefs' - * only get to see the output of their respective predecessor - function in the sequence (with the obvious exception of the - first function) - * are applied to the full file *path* (whereas the shell-style - wildcards are only applied to the file *names*) - - Returns a sequence of paths for files found. - """ - if not os.access(path, os.R_OK): - raise ScriptError("cannot access path: '%s'" % path) - - fileList = [] # result list - try: - for dir, subdirs, files in os.walk(path): - if shellglobs: - matched = [] - for pattern in shellglobs: - filterf = lambda s: fnmatch.fnmatchcase(s, pattern) - matched.extend(filter(filterf, files)) - fileList.extend(['%s%s%s' % (dir, os.sep, f) for f in matched]) - else: - fileList.extend(['%s%s%s' % (dir, os.sep, f) for f in files]) - if not relative: fileList = map(os.path.abspath, fileList) - if namefs: - for ff in namefs: fileList = filter(ff, fileList) - except Exception, e: raise ScriptError(str(e)) - return(fileList) - -def ffindgrep(path, regexl, shellglobs=None, namefs=None, relative=True): - """ - Finds files in the directory tree starting at 'path' (filtered by - Unix shell-style wildcards ('shellglobs') and/or the functions in - the 'namefs' sequence) and searches inside these. - - The parameters are as follows: - - - path: starting path of the directory tree to be searched - - shellglobs: an optional sequence of Unix shell-style wildcards - that are to be applied to the file *names* found - - namefs: an optional sequence of functions to be applied to the - file *paths* found - - relative: a boolean flag that determines whether absolute or - relative paths should be returned - - Additionaly, the file content will be filtered by the regular - expressions in the 'regexl' sequence. Each entry in the latter - is a - - - either a string (with the regex definition) - - or a tuple with arguments accepted by re.compile() (the - re.M and re.S flags will have no effect though) - - For all the files that pass the file name/content tests the function - returns a dictionary where the - - - key is the file name and the - - value is a string with lines filtered by 'regexl' - """ - fileList = ffind(path, shellglobs=shellglobs, - namefs=namefs, relative=relative) - if not fileList: return dict() - - result = dict() - - try: - # first compile the regular expressions - ffuncs = [] - for redata in regexl: - if type(redata) == types.StringType: - ffuncs.append(re.compile(redata).search) - elif type(redata) == types.TupleType: - ffuncs.append(re.compile(*redata).search) - # now grep in the files found - for file in fileList: - # read file content - fhandle = open(file, 'r') - fcontent = fhandle.read() - fhandle.close() - # split file content in lines - lines = fcontent.splitlines() - for ff in ffuncs: - lines = filter(ff, lines) - # there's no point in applying the remaining regular - # expressions if we don't have any matching lines any more - if not lines: break - else: - # the loop terminated normally; add this file to the - # result set if there are any lines that matched - if lines: result[file] = '\n'.join(map(str, lines)) - except Exception, e: raise ScriptError(str(e)) - return(result) - -def freplace(path, regexl, shellglobs=None, namefs=None, bext='.bak'): - """ - Finds files in the directory tree starting at 'path' (filtered by - Unix shell-style wildcards ('shellglobs') and/or the functions in - the 'namefs' sequence) and performs an in-place search/replace - operation on these. - - The parameters are as follows: - - - path: starting path of the directory tree to be searched - - shellglobs: an optional sequence of Unix shell-style wildcards - that are to be applied to the file *names* found - - namefs: an optional sequence of functions to be applied to the - file *paths* found - - relative: a boolean flag that determines whether absolute or - relative paths should be returned - - Additionally, an in-place search/replace operation is performed - on the content of all the files (whose names passed the tests) - using the regular expressions in 'regexl'. - - Please note: 'regexl' is a sequence of 3-tuples, each having the - following elements: - - - search string (Python regex syntax) - - replace string (Python regex syntax) - - regex flags or 'None' (re.compile syntax) - - Copies of the modified files are saved in backup files using the - extension specified in 'bext'. - - The function returns the total number of files modified. - """ - fileList = ffind(path, shellglobs=shellglobs, namefs=namefs) - - # return if no files found - if not fileList: return 0 - - filesChanged = 0 - - try: - cffl = [] - for searchs, replaces, reflags in regexl: - # prepare the required regex objects, check whether we need - # to pass any regex compilation flags - if reflags is not None: regex = re.compile(searchs, reflags) - else: regex = re.compile(searchs) - cffl.append((regex.subn, replaces)) - for file in fileList: - # read file content - fhandle = open(file, 'r') - text = fhandle.read() - fhandle.close() - substitutions = 0 - # unpack the subn() function and the replace string - for subnfunc, replaces in cffl: - text, numOfChanges = subnfunc(replaces, text) - substitutions += numOfChanges - if substitutions: - # first move away the original file - bakFileName = '%s%s' % (file, bext) - if os.path.exists(bakFileName): os.unlink(bakFileName) - os.rename(file, bakFileName) - # now write the new file content - fhandle = open(file, 'w') - fhandle.write(text) - fhandle.close() - filesChanged += 1 - except Exception, e: raise ScriptError(str(e)) - - # return the number of files that had some of their content changed - return(filesChanged) - -def printr(results): - """ - prints the results of ffind()/ffindgrep() in a manner similar to - the UNIX find utility - """ - if type(results) == types.DictType: - for f in sorted(results.keys()): - sys.stdout.write("%s\n%s\n" % (results[f],f)) - else: - for f in sorted(results): - sys.stdout.write("%s\n" % f) - -if __name__ == '__main__': - pass diff --git a/scripts/texture_reorg/shader_rename b/scripts/texture_reorg/shader_rename deleted file mode 100644 index f337a6894..000000000 --- a/scripts/texture_reorg/shader_rename +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/python - -# This script replaces a string in a file with another. The old and new -# string can either be specified on the commandline: -# shader_renamd -o oldname -n newname -# or it can be specified with a tab delimited inputfile where each -# line must contain two names, the old and the new one seperated by a TAB -# character. - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - -class Line: - def __init__(self): - self.LineNumber = -1 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Text + "' ]" - -class File: - def __init__(self, name): - self.Filename = name - self.Modified = 0 - self.Line = [] - self.PreLoadFile(name) - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def PreLoadFile(self, filename): - f = open(filename) - b = f.read() - f.close() - - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - b = b.split("\n") - - r = Line() - nr = 0 - - for l in b: - s = l.strip() - - nr = nr + 1 - r.Text = l - r.LineNumber = nr - - self.Line.append(r) - r = Line() - - return - - def ReplaceString(self, old, new): - rc = 0 - #print old, new - for i in self.Line: - t = i.Text.split(old) - if(len(t) <= 1): - continue - - #print len(t), t - - #print old, new - if(len(t[1]) > 0): - #print len(t), t - b = 0 - if(t[1][0:1] == "\"" - or t[1][0:1] == "\t" - or t[1][0:1] == "," - or t[1][0:1] == "(" - or t[1][0:1] == ")" - or t[1][0:1] == " "): - b = 1 - - if(b != 1): - continue - - i.Text = t[0]+new+t[1] - rc = 1 - - return rc - -class ShaderRename: - def __init__(self): - self.Map = {} - - def LoadInputfile(self, filename): - #name = glob.glob(filename) - f = open(filename) - b = f.read() - f.close() - - b = b.replace("\r\n", "\r") - b = b.split("\r") - - n = 0 - for l in b: - n = n + 1 - l = l.strip() - if(len(l) == 0): - continue - - t = l.split("\t") - if(len(t) <= 1): - print "ERROR("+n.__repr__()+"): "+l - continue - - self.Map[t[0]] = t[1] - return - - def SetShadername(self, old, new): - self.Map[old] = new - return - - def Replace(self, fn): - mat = File(fn) - rc = 0 - for i in self.Map: - rc = rc + mat.ReplaceString(i, self.Map[i]) - - if(rc != 0): - #print "... updating" - fl = open(fn, "w+b") - for i in mat.Line: - fl.write(i.Text+"\n") - fl.close() - return - -def Usage(): - print "USAGE: reorg -if " - print " reorg -o -n " - sys.exit(1) - -if __name__ == '__main__': - if len(sys.argv) <= 1: - Usage() - - sr = ShaderRename() - - i = 0 - n = len(sys.argv) - - old = None - new = None - input = None - try: - opt = sys.argv[1] - if(opt == "-o"): - old = sys.argv[2] - opt = sys.argv[3] - if(opt == "-n"): - new = sys.argv[4] - i = 5 - fl = sys.argv[i] - elif(opt == "-if"): - input = sys.argv[2] - i = 3 - fl = sys.argv[i] - except IndexError: - Usage() - - if(input != None): - sr.LoadInputfile(input) - else: - if(old == None or new == None): - Usage() - sr.SetShadername(old, new) - - while( i < n): - fn = sys.argv[i] - print "Processing "+fn - sr.Replace(fn) - i = i + 1 - - sys.exit(0) diff --git a/scripts/texture_reorg/shader_rename.txt b/scripts/texture_reorg/shader_rename.txt deleted file mode 100644 index 1314b45dc..000000000 --- a/scripts/texture_reorg/shader_rename.txt +++ /dev/null @@ -1,394 +0,0 @@ -textures/darkmod/stone/floor/blocks_001 textures/darkmod/stone/brick/rough_blocks02 -textures/darkmod/stone/floor/blocks_002_yellow textures/darkmod/stone/brick/rough_blocks_tight_light -textures/darkmod/stone/floor/blocks_002_blue textures/darkmod/stone/brick/rough_blocks_tight_dark -textures/darkmod/stone/floor/blocks_003 textures/darkmod/stone/brick/rough_blocks_tight02 -textures/darkmod/stone/floor/blocks_003_mossy textures/darkmod/stone/brick/rough_blocks_tight02_moss -textures/darkmod/stone/floor/blocks_004 textures/darkmod/stone/brick/tight_large_blocks -textures/darkmod/stone/floor/blocks_005 textures/darkmod/stone/brick/grey_protruding_bricks -textures/darkmod/stone/floor/blocks_006 textures/darkmod/stone/brick/grainy_blocks01 -textures/darkmod/stone/floor/blocks_007 textures/darkmod/stone/brick/tight_randomsize_blocks -textures/darkmod/stone/floor/blocks_008 textures/darkmod/stone/brick/rough_big_blocks01 -textures/darkmod/stone/floor/blocks_009 textures/darkmod/stone/brick/rough_big_blocks02 -textures/darkmod/stone/floor/blocks_009_cornerstone_dark textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_dark -textures/darkmod/stone/floor/blocks_009_cornerstone_light textures/darkmod/stone/brick/rough_big_blocks02_cornerstone_light -textures/darkmod/stone/floor/blocks_010 textures/darkmod/stone/brick/rough_big_blocks03 -textures/darkmod/stone/floor/blocks_010_cornerstone_dark textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_dark -textures/darkmod/stone/floor/blocks_010_cornerstone_light textures/darkmod/stone/brick/rough_big_blocks03_cornerstone_light -textures/darkmod/stone/floor/blocks_011 textures/darkmod/stone/cobblestones/uneven_blocks01_dark -textures/darkmod/stone/floor/blocks_012 textures/darkmod/stone/cobblestones/uneven_blocks01_brown -textures/darkmod/stone/floor/blocks_013 textures/darkmod/stone/brick/rough_big_blocks04_brown -textures/darkmod/stone/floor/blocks_013_cornerstone_light textures/darkmod/stone/brick/rough_big_blocks04_brown_cornerstone_light -textures/darkmod/stone/floor/blocks_014 textures/darkmod/stone/brick/rough_big_blocks05 -textures/darkmod/stone/floor/blocks_015 textures/darkmod/stone/brick/tight_large_blocks01 -textures/darkmod/stone/floor/blocks_016 textures/darkmod/stone/brick/tight_large_singleblock01 -textures/darkmod/stone/floor/blocks_017 textures/darkmod/stone/brick/grainy_large_blocks01 -textures/darkmod/stone/floor/blocks_018 textures/darkmod/stone/cobblestones/flagstones02_plain -textures/darkmod/stone/floor/blocks_018_cornerstone_l textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_left -textures/darkmod/stone/floor/blocks_018_cornerstone_r textures/darkmod/stone/cobblestones/flagstones02_plain_cornerstone_right -textures/darkmod/stone/floor/blocks_018_window01 textures/darkmod/stone/cobblestones/flagstones02_plain_window01 -textures/darkmod/stone/floor/blocks_018_window02 textures/darkmod/stone/cobblestones/flagstones02_plain_window02 -textures/darkmod/stone/floor/blocks_019 textures/darkmod/stone/brick/even_small_blocks01 -textures/darkmod/stone/floor/brick_001 textures/darkmod/stone/brick/red_brick_dull01 -textures/darkmod/stone/floor/brick_002 textures/darkmod/stone/brick/redbrick_dull_small -textures/darkmod/stone/floor/brick_004 textures/darkmod/stone/brick/red_angled_ground -textures/darkmod/stone/floor/brick_005 textures/darkmod/stone/brick/red_sloppymortar -textures/darkmod/stone/floor/brick_005_colored textures/darkmod/stone/brick/sloppymortar_colored -textures/darkmod/stone/floor/brick_005_dark textures/darkmod/stone/brick/red_sloppymortar_dark -textures/darkmod/stone/floor/brick_005_inverted textures/darkmod/stone/brick/red_sloppymortar_inverted -textures/darkmod/stone/floor/brick_006 textures/darkmod/stone/brick/even_greyish01 -textures/darkmod/stone/floor/brick_006_trim textures/darkmod/stone/brick/even_greyish01_trim -textures/darkmod/stone/floor/brick_007 textures/darkmod/stone/brick/interlocking_angled_grey -textures/darkmod/stone/floor/brick_007_dark textures/darkmod/stone/brick/interlocking_angled_darkgrey -textures/darkmod/stone/floor/brick_007_yellow textures/darkmod/stone/brick/interlocking_angled_yellow -textures/darkmod/stone/floor/brick_008 textures/darkmod/stone/brick/redbrick_mostly_mortar -textures/darkmod/stone/floor/brick_009 textures/darkmod/stone/brick/rough_blocks01 -textures/darkmod/stone/floor/brick_010 textures/darkmod/stone/brick/old_blocks_wornsmooth_dark -textures/darkmod/stone/floor/cobble_001 textures/darkmod/stone/cobblestones/cobblestones03_dark -textures/darkmod/stone/floor/cobble_002 textures/darkmod/stone/cobblestones/cobblestones04_multicolour -textures/darkmod/stone/floor/cobble_003 textures/darkmod/stone/cobblestones/flagstones05_pinkish -textures/darkmod/stone/floor/cobble_004 textures/darkmod/stone/cobblestones/cobblestones01_square_light -textures/darkmod/stone/floor/cobble_004_nospecular textures/darkmod/stone/cobblestones/cobblestones01_square_light_nospecular -textures/darkmod/stone/floor/cobble_005 textures/darkmod/stone/brick/interlocking_mixedsize_dark -textures/darkmod/stone/floor/cobble_006 textures/darkmod/stone/cobblestones/flagstones03_shiny -textures/darkmod/stone/floor/cobble_007 textures/darkmod/stone/cobblestones/flagstones04_uneven -textures/darkmod/stone/floor/cobble_008 textures/darkmod/stone/cobblestones/cobblestones02_square_dark -textures/darkmod/stone/floor/cobble_mossy_001 textures/darkmod/stone/cobblestones/cobblestones_loose_ongrass -textures/darkmod/stone/floor/decorative_001 textures/darkmod/stone/flat/ceramic_mosaic_decorative01 -textures/darkmod/stone/floor/fan_001_dirt textures/darkmod/stone/cobblestones/cobblestone_fan_pattern -textures/darkmod/stone/floor/fan_001_grass textures/darkmod/stone/cobblestones/cobblestone_fan_pattern_grass -textures/darkmod/stone/floor/granite_001 textures/darkmod/stone/cobblestones/flagstones06_granite -textures/darkmod/stone/floor/marble_004 textures/darkmod/stone/flat/rough_marble_dark01 -textures/darkmod/stone/floor/masonry_001 textures/darkmod/stone/cobblestones/flagstones01_light -textures/darkmod/stone/floor/masonry_001_brick textures/darkmod/stone/brick/small_brown_bricks01 -textures/darkmod/stone/floor/masonry_001_pillar textures/darkmod/stone/brick/pillar_bricks01 -textures/darkmod/stone/floor/mortared_001 textures/darkmod/stone/cobblestones/blocks_mixed_multicolour -textures/darkmod/stone/floor/rough_001 textures/darkmod/stone/natural/dark_dirt_smeary -textures/darkmod/stone/floor/rough_002 textures/darkmod/stone/natural/sandstone -textures/darkmod/stone/floor/rough_003 textures/darkmod/stone/natural/rock_grey -textures/darkmod/stone/floor/rough_003_dark textures/darkmod/stone/natural/rock_grey_dark -textures/darkmod/stone/floor/rough_004 textures/darkmod/stone/natural/rock_brown_mottled -textures/darkmod/stone/floor/rough_005 textures/darkmod/stone/natural/light_grey_rough -textures/darkmod/stone/floor/rough_006 textures/darkmod/stone/flat/rough_marble_dark02 -textures/darkmod/stone/floor/rough_007 textures/darkmod/stone/flat/rough_marble_light01 -textures/darkmod/stone/floor/rough_008 textures/darkmod/stone/natural/rough_old -textures/darkmod/stone/floor/rough_009 textures/darkmod/stone/natural/dark_rough -textures/darkmod/stone/floor/rough_010 textures/darkmod/stone/natural/dark_dirty -textures/darkmod/stone/floor/rough_011 textures/darkmod/stone/natural/rough_grey_dirty -textures/darkmod/stone/floor/rough_012_mossy textures/darkmod/stone/natural/rock_grey_mossy -textures/darkmod/stone/floor/tiled_001 textures/darkmod/stone/flat/tiles_rough_grey -textures/darkmod/stone/floor/tiled_002 textures/darkmod/stone/cobblestones/nontiling/flagstones_jagged_grey -textures/darkmod/stone/floor/tiled_003 textures/darkmod/stone/flat/tile_plain_diamond01_brown -textures/darkmod/stone/floor/tiled_004 textures/darkmod/stone/flat/smooth/ceramic_tile_reddish01 -textures/darkmod/stone/floor/tiled_005 textures/darkmod/stone/flat/smooth/ceramic_tile_gold01 -textures/darkmod/stone/floor/tiled_006 textures/darkmod/stone/flat/smooth/ceramic_tile_tan02 -textures/darkmod/stone/floor/tiled_007 textures/darkmod/stone/flat/smooth/ceramic_tile_tan03 -textures/darkmod/stone/floor/tiled_008 textures/darkmod/stone/flat/smooth/ceramic_tile_tan01 -textures/darkmod/stone/floor/tiled_009 textures/darkmod/stone/flat/rough_plain_tiles01 -textures/darkmod/stone/floor/tiled_010 textures/darkmod/stone/flat/rough_slate_tiles01_dark - -textures/darkmod/stone/trim/border_8x1 textures/darkmod/stone/sculpted/trapezoid_tile_8x1 -textures/darkmod/stone/trim/border_4x1 textures/darkmod/stone/sculpted/trapezoid_tile_4x1 -textures/darkmod/stone/trim/border_2x1 textures/darkmod/stone/sculpted/trapezoid_tile_2x1 -textures/darkmod/stone/trim/border_1x1 textures/darkmod/stone/sculpted/trapezoid_tile_1x1 -textures/darkmod/stone/trim/deco_001 textures/darkmod/stone/sculpted/engraved_tile_star -textures/darkmod/stone/trim/deco_002 textures/darkmod/stone/sculpted/engraved_tile_ovals -textures/darkmod/stone/trim/grave_001 textures/darkmod/stone/sculpted/sarcophagus_warrior01 -textures/darkmod/stone/trim/grave_002 textures/darkmod/stone/sculpted/sarcophagus_cup_hammer01 -textures/darkmod/stone/trim/grave_003 textures/darkmod/stone/sculpted/sarcophagus_wings01 -textures/darkmod/stone/trim/grave_004 textures/darkmod/stone/sculpted/sarcophagus_swords_shield01 -textures/darkmod/stone/trim/grave_005 textures/darkmod/stone/sculpted/engraved_tile_cup01 -textures/darkmod/stone/trim/grave_006 textures/darkmod/stone/sculpted/engraved_tile_x -textures/darkmod/stone/trim/grave_007 textures/darkmod/stone/sculpted/engraved_tile_impface -textures/darkmod/stone/trim/grave_008 textures/darkmod/stone/sculpted/engraved_tile_ring -textures/darkmod/stone/trim/ornament_001 textures/darkmod/stone/sculpted/carved_tiles01_x4_light -textures/darkmod/stone/trim/ornament_002 textures/darkmod/stone/sculpted/carved_tiles01_x4_dark -textures/darkmod/stone/trim/ornament_003 textures/darkmod/stone/sculpted/royal_emblem01 -textures/darkmod/stone/trim/ornament_004 textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing -textures/darkmod/stone/trim/ornament_005 textures/darkmod/stone/sculpted/tiles_bars_diamondshape -textures/darkmod/stone/trim/ornament_006 textures/darkmod/stone/sculpted/tile_empty_square -textures/darkmod/stone/trim/ornament_007 textures/darkmod/stone/sculpted/tile_empty_trapezoid -textures/darkmod/stone/trim/ornament_008 textures/darkmod/stone/sculpted/tile_diamond_trapezoid -textures/darkmod/stone/trim/ornament_009 textures/darkmod/stone/sculpted/engraved_tile_face01 -textures/darkmod/stone/trim/ornament_010 textures/darkmod/stone/sculpted/carved_design_diamonds01 -textures/darkmod/stone/trim/ornament_011 textures/darkmod/stone/sculpted/carved_design_bones01 -textures/darkmod/stone/trim/ornament_012 textures/darkmod/stone/sculpted/carved_design_snakes -textures/darkmod/stone/trim/ornament_013_tile_mid textures/darkmod/stone/sculpted/carved_design_bones02 -textures/darkmod/stone/trim/ornament_013_tile_right textures/darkmod/stone/sculpted/carved_design_bones02_right -textures/darkmod/stone/trim/ornament_013_tile_left textures/darkmod/stone/sculpted/carved_design_bones02_left -textures/darkmod/stone/trim/ornament_014_skull textures/darkmod/stone/sculpted/carved_design_skull01 -textures/darkmod/stone/trim/trim_001 textures/darkmod/stone/sculpted/carved_diamond_trim02 -textures/darkmod/stone/trim/trim_002 textures/darkmod/stone/sculpted/carved_diamond_trim -textures/darkmod/stone/trim/trim_003 textures/darkmod/stone/brick/single_grey_block01 - -textures/darkmod/stone/wall/blocks_001_framed textures/darkmod/stone/brick/nontiling/chiseled_brick_frame -textures/darkmod/stone/wall/brick_old_001 textures/darkmod/stone/brick/old_small_bricks_grey -textures/darkmod/stone/wall/brick_old_002 textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick -textures/darkmod/stone/wall/brick_old_003 textures/darkmod/stone/brick/old_dirty_bricks01 -textures/darkmod/stone/wall/cement_001 textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked -textures/darkmod/stone/wall/cement_003 textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01 -textures/darkmod/stone/wall/cement_006 textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly -textures/darkmod/stone/wall/cement_009 textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02 -textures/darkmod/stone/wall/cement_011 textures/darkmod/metal/flat/tiling_1d/rough_rusted01 -textures/darkmod/stone/wall/cement_012 textures/darkmod/metal/flat/tiling_1d/rough_dirty01 -textures/darkmod/stone/wall/cement_013 textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked -textures/darkmod/stone/wall/cement_014 textures/darkmod/metal/flat/tiling_1d/rough_iron01 -textures/darkmod/stone/wall/facade_001 textures/darkmod/window/frame_ornate_wallsection_lit -textures/darkmod/stone/wall/masonry_001 textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey -textures/darkmod/stone/wall/masonry_002 textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey -textures/darkmod/stone/wall/masonry_003 textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown -textures/darkmod/stone/wall/masonry_004 textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey -textures/darkmod/stone/wall/masonry_005 textures/darkmod/stone/cobblestones/blocks_mixedsize01 -textures/darkmod/stone/wall/masonry_old_001 textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix -textures/darkmod/stone/wall/masonry_old_002 textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix -textures/darkmod/stone/wall/masonry_old_003 textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse -textures/darkmod/stone/wall/masonry_old_004 textures/darkmod/stone/cobblestones/rough_masonry01 -textures/darkmod/stone/wall/masonry_old_005 textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven -textures/darkmod/stone/wall/mortared_001 textures/darkmod/stone/cobblestones/blocks_mixed_multicolour_framed -textures/darkmod/stone/wall/rounded_001 textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded - -textures/darkmod/foliage/trim/hanging_001 textures/darkmod/decals/vegetation/hanging_horizontal_leaves -textures/darkmod/foliage/trim/ivy_001_patch1 textures/darkmod/decals/vegetation/ivypatch_average01 -textures/darkmod/foliage/trim/ivy_001_patch2 textures/darkmod/decals/vegetation/ivypatch_large01 -textures/darkmod/foliage/trim/ivy_001_small1 textures/darkmod/decals/vegetation/ivypatch_small01 -textures/darkmod/foliage/trim/ivy_001_small2 textures/darkmod/decals/vegetation/ivypatch_tiny01 -textures/darkmod/foliage/trim/ivy_002_collection textures/darkmod/decals/vegetation/ivy_mixed_pieces -textures/darkmod/foliage/trim/ivy_002_collection_dark textures/darkmod/decals/vegetation/ivy_mixed_pieces_dark -textures/darkmod/foliage/trim/ivy_003 textures/darkmod/decals/vegetation/ivy_vertical_branches -textures/darkmod/foliage/trim/ivy_004 textures/darkmod/decals/vegetation/ivy_scattered_branches -textures/darkmod/foliage/trim/moss textures/darkmod/decals/vegetation/moss_patch_thick01 -textures/darkmod/foliage/trim/moss_burn textures/darkmod/decals/vegetation/moss_patch_thick01_burning - -textures/darkmod/pagan/decal/pagdecfleur.tga textures/darkmod/decals/symbols/magic_symbol_circle01 -textures/darkmod/pagan/decal/pagdecvoyn.tga textures/darkmod/decals/symbols/magical_letters_row01 - -textures/darkmod/door/antique_001 textures/darkmod/door/wood/oldboards_metalspirals01 -textures/darkmod/door/attic_001 textures/darkmod/door/wood/old_flat_oak01 -textures/darkmod/door/mansion_001 textures/darkmod/door/wood/smooth_4panels_red01 -textures/darkmod/door/mansion_001_light textures/darkmod/door/wood/smooth_4panels_tan01 -textures/darkmod/door/mansion_002 textures/darkmod/door/wood/smooth_3panels_red01 -textures/darkmod/door/mansion_003 textures/darkmod/door/wood/smooth_3panels01_dull01 -textures/darkmod/door/mansion_004 textures/darkmod/door/wood/smooth_2panels_rich -textures/darkmod/door/reinforced_001 textures/darkmod/door/wood/metalbands_crisscross01 -textures/darkmod/door/sturdy_001 textures/darkmod/door/wood/diamond_pattern01 -textures/darkmod/door/weathered_001 textures/darkmod/door/wood/old_weathered_boards01 -textures/darkmod/door/windowed_001 textures/darkmod/door/wood/ornate/smooth_rich_ovalwindow01 -textures/darkmod/door/windowed_002 textures/darkmod/door/wood/ornate/smooth_rich_squarewindow01 - -textures/darkmod/wood/ceiling/panel_001 textures/darkmod/wood/panels/panel_grey -textures/darkmod/wood/ceiling/panel_002 textures/darkmod/wood/panels/panel_carved_star -textures/darkmod/wood/ceiling/panel_002_dusty textures/darkmod/wood/panels/panel_carved_star_dusty -textures/darkmod/wood/ceiling/panel_003 textures/darkmod/wood/panels/panel_carved_rectangles_01 -textures/darkmod/wood/ceiling/panel_004_dark textures/darkmod/wood/panels/panel_carved_rectangles_02_dark -textures/darkmod/wood/ceiling/panel_004_light textures/darkmod/wood/panels/panel_carved_rectangles_02_light -textures/darkmod/wood/ceiling/panel_005 textures/darkmod/wood/panels/panel_floral_ornaments -textures/darkmod/wood/ceiling/panel_006 textures/darkmod/wood/panels/panel_carved_round_dark -textures/darkmod/wood/ceiling/plastered_001 textures/darkmod/wood/boards/plastered_grey -textures/darkmod/wood/ceiling/pole_supports textures/darkmod/wood/boards/metal_decorated -textures/darkmod/wood/floor/bark_001 textures/darkmod/nature/natural02 -textures/darkmod/wood/floor/boards_old_001 textures/darkmod/wood/boards/old_small_grainy -textures/darkmod/wood/floor/boards_old_002 textures/darkmod/wood/boards/weathered -textures/darkmod/wood/floor/boards_old_003 textures/darkmod/wood/boards/scratched -textures/darkmod/wood/floor/boards_old_004 textures/darkmod/wood/boards/dark_rough -textures/darkmod/wood/floor/boards_old_005 textures/darkmod/wood/boards/worn_01 -textures/darkmod/wood/floor/boards_old_006 textures/darkmod/wood/boards/worn_02 -textures/darkmod/wood/floor/boards_old_007 textures/darkmod/wood/boards/dark_varnished -textures/darkmod/wood/floor/boards_polished_001 textures/darkmod/wood/boards/polished_shiny -textures/darkmod/wood/floor/boards_polished_002 textures/darkmod/wood/boards/polished_01 -textures/darkmod/wood/floor/boards_polished_002_dim textures/darkmod/wood/boards/polished_01_dim -textures/darkmod/wood/floor/tile_decorative_001 textures/darkmod/wood/panels/tile_pattern_star -textures/darkmod/wood/floor/tile_weave_001 textures/darkmod/wood/panels/tile_weave -textures/darkmod/wood/trim/beam_001 textures/darkmod/wood/boards/worn_large -textures/darkmod/wood/trim/beam_002 textures/darkmod/wood/panels/beam_rough_brown -textures/darkmod/wood/trim/beam_002_endcap textures/darkmod/wood/panels/nontiling/beam_rough_brown_endcap -textures/darkmod/wood/trim/beam_002_weathered textures/darkmod/wood/panels/beam_rough_weathered -textures/darkmod/wood/trim/beam_002_weathered_endcap textures/darkmod/wood/panels/nontiling/beam_rough_weathered_endcap -textures/darkmod/wood/trim/beam_003 textures/darkmod/wood/panels/beam_brown_old -textures/darkmod/wood/trim/beam_003_burnt textures/darkmod/wood/panels/nontiling/beam_brown_old_burnt -textures/darkmod/wood/trim/beam_003_endcap textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap -textures/darkmod/wood/trim/beam_mossy_001 textures/darkmod/wood/panels/beam_old_mossy -textures/darkmod/wood/trim/molding_001 textures/darkmod/wood/panels/trim_carved_rounded -textures/darkmod/wood/trim/molding_002 textures/darkmod/wood/panels/molding_leaves -textures/darkmod/wood/trim/molding_003 textures/darkmod/wood/panels/molding_decorative_dark -textures/darkmod/wood/trim/molding_004 textures/darkmod/wood/panels/molding_grey -textures/darkmod/wood/trim/panel_001 textures/darkmod/wood/panels/trim_carved_long -textures/darkmod/wood/trim/panel_002 textures/darkmod/wood/panels/thin_panels_with_trim_dark -textures/darkmod/wood/trim/panel_003 textures/darkmod/wood/panels/thin_panels_with_trim_light -textures/darkmod/wood/trim/plastered_001 textures/darkmod/plaster/framed_old_01 -textures/darkmod/wood/trim/plastered_001_decorative textures/darkmod/plaster/framed_old_decorative_01 -textures/darkmod/wood/wall/boards_new_001 textures/darkmod/wood/boards/tiling_1d/new_grainy -textures/darkmod/wood/wall/building_001 textures/darkmod/city/wall/ctywall04 -textures/darkmod/wood/wall/panel_001 textures/darkmod/wood/panels/panels_decorative_arched -textures/darkmod/wood/wall/panel_002 textures/darkmod/wood/panels/panels_grey_long -textures/darkmod/wood/wall/panel_003 textures/darkmod/wood/panels/panel_hammer -textures/darkmod/wood/wall/panel_004 textures/darkmod/wood/panels/panel_decorative_rectangles -textures/darkmod/wood/wall/panel_005 textures/darkmod/wood/panels/panel_circle_face -textures/darkmod/wood/wall/panel_006 textures/darkmod/wood/panels/panel_warrior -textures/darkmod/wood/wall/panel_007 textures/darkmod/wood/panels/panel_decorative_frame -textures/darkmod/wood/wall/panel_008 textures/darkmod/wood/panels/panel_decorative_frame_long -textures/darkmod/wood/wall/panel_009 textures/darkmod/mansion/wall/manwcapital01.tga -textures/darkmod/wood/wall/wallpaper_001 textures/darkmod/paint_paper/wallpaper_flowers_01 -textures/darkmod/wood/wall/wallpaper_002_blue textures/darkmod/paint_paper/wallpaper_ornamental_01_blue -textures/darkmod/wood/wall/wallpaper_002_green textures/darkmod/paint_paper/wallpaper_ornamental_01_green -textures/darkmod/wood/wall/wallpaper_002_pink textures/darkmod/paint_paper/wallpaper_ornamental_01_pink -textures/darkmod/wood/wall/wallpaper_002_red textures/darkmod/paint_paper/wallpaper_ornamental_01_red -textures/darkmod/wood/wall/wallpaper_003 textures/darkmod/paint_paper/wallpaper_ornamental_02_white -textures/darkmod/litwindows/largeround100 textures/darkmod/window/ornate/round_spokes01_brightlit -textures/darkmod/litwindows/largesquare100 textures/darkmod/window/largesquare01_brightlit -textures/darkmod/litwindows/smallsquare100 textures/darkmod/window/simple_square01_brightlit -textures/darkmod/litwindows/largeround90 textures/darkmod/window/ornate/round_spokes01_lit -textures/darkmod/litwindows/largesquare90 textures/darkmod/window/largesquare01_lit -textures/darkmod/litwindows/smallsquare90 textures/darkmod/window/simple_square01_lit -textures/darkmod/litwindows/largeround80 textures/darkmod/window/ornate/round_spokes01_softlit -textures/darkmod/litwindows/largesquare80 textures/darkmod/window/largesquare01_softlit -textures/darkmod/litwindows/smallsquare80 textures/darkmod/window/simple_square01_softerlit -textures/darkmod/litwindows/largeround70 textures/darkmod/window/ornate/round_spokes01_softerlit -textures/darkmod/litwindows/largesquare70 textures/darkmod/window/largesquare01_softerlit -textures/darkmod/litwindows/smallsquare70 textures/darkmod/window/simple_square01_softlit -textures/darkmod/tile/trim/molding_001 textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_brown -textures/darkmod/tile/floor/marble_001 textures/darkmod/stone/flat/smooth/marble_pattern01 -textures/darkmod/tile/floor/marble_001_center1 textures/darkmod/stone/flat/smooth/marble_pattern01_centersun -textures/darkmod/tile/floor/marble_001_center2 textures/darkmod/stone/flat/smooth/marble_pattern01_centerrose -textures/darkmod/tile/floor/marble_002_center1_squares textures/darkmod/stone/flat/smooth/marble_pattern02_checker -textures/darkmod/tile/floor/marble_002_center2 textures/darkmod/stone/flat/smooth/marble_pattern02_crosshair -textures/darkmod/tile/floor/marble_002_center3 textures/darkmod/stone/flat/smooth/marble_pattern02_star -textures/darkmod/tile/floor/marble_002_center4 textures/darkmod/stone/flat/smooth/marble_pattern02_star02 -textures/darkmod/tile/floor/marble_002_center5_gear textures/darkmod/stone/flat/smooth/marble_pattern02_rings -textures/darkmod/tile/floor/marble_001_polished textures/darkmod/stone/flat/smooth/marble_pattern01_polished -textures/darkmod/tile/floor/marble_001_center1_polished textures/darkmod/stone/flat/smooth/marble_pattern01_centersun_polished -textures/darkmod/tile/floor/marble_001_center2_polished textures/darkmod/stone/flat/smooth/marble_pattern01_centerrose_polished -textures/darkmod/tile/floor/marble_002_center1_squares_polished textures/darkmod/stone/flat/smooth/marble_pattern02_checker_polished -textures/darkmod/tile/floor/marble_002_center2_polished textures/darkmod/stone/flat/smooth/marble_pattern02_crosshair_polished -textures/darkmod/tile/floor/marble_002_center3_polished textures/darkmod/stone/flat/smooth/marble_pattern02_star_polished -textures/darkmod/tile/floor/marble_002_center4_polished textures/darkmod/stone/flat/smooth/marble_pattern02_star02_polished -textures/darkmod/tile/floor/marble_002_center5_gear_polished textures/darkmod/stone/flat/smooth/marble_pattern02_rings_polished -textures/darkmod/tile/floor/marble_003 textures/darkmod/stone/flat/smooth/marble_pattern03_brownish -textures/darkmod/metal/trim/panel_001 textures/darkmod/metal/detailed/panel_circledesign01_green -textures/darkmod/metal/trim/panel_001_etched textures/darkmod/metal/detailed/panel_circledesign01_green_etched -textures/darkmod/metal/floor/grating_001 textures/darkmod/metal/grate/dimpled_grating01 -textures/darkmod/metal/floor/rust_002 textures/darkmod/metal/flat/heavy_rust_pocked01 -textures/darkmod/metal/floor/rust_003 textures/darkmod/metal/flat/solid_rust01 -textures/darkmod/metal/floor/rust_004 textures/darkmod/metal/flat/simple_rough_grey01 -textures/darkmod/metal/floor/rust_005 textures/darkmod/metal/flat/solid_rust02 -textures/darkmod/gravel/floor/gravel_001 textures/darkmod/stone/natural/tiling_1d/gravel_grey_01 -textures/darkmod/grass/floor/grassy_001 textures/darkmod/nature/grass/thick_grass01 -textures/darkmod/grass/floor/grassy_002 textures/darkmod/nature/grass03 -textures/darkmod/grass/floor/grassy_003 textures/darkmod/nature/grass04 -textures/darkmod/grass/floor/mossyrock_001 textures/darkmod/stone/natural/mossy_rock_green -textures/darkmod/grass/floor/mossyrock_002 textures/darkmod/stone/natural/mossy_rock_brown -textures/darkmod/grass/floor/mossyrock_003 textures/darkmod/stone/natural/mossy_rock_bumpy -textures/darkmod/grass/floor/underbrush_001 textures/darkmod/nature/grass/short_patchy_grass01 -textures/darkmod/grass/floor/straw_001 textures/darkmod/nature/grass/nontiling/thick_straw01 -textures/darkmod/carpet/trim/rug_001 textures/darkmod/carpet/rugs/ornate_rectangles_brown01 -textures/darkmod/carpet/trim/rug_002 textures/darkmod/carpet/rugs/ornate_floral_checker01 -textures/darkmod/carpet/trim/rug_blue_001 textures/darkmod/carpet/rugs/ornate_green_black01 -textures/darkmod/carpet/trim/rug_gold_001 textures/darkmod/carpet/rugs/ornate_black_gold01 -textures/darkmod/carpet/trim/rug_red_001 textures/darkmod/carpet/rugs/ornate_red_tan01 -textures/darkmod/carpet/trim/rug_red_002 textures/darkmod/carpet/rugs/ornate_red_tan02 -textures/darkmod/carpet/trim/rug_red_003_center textures/darkmod/carpet/runners/geometric01_red -textures/darkmod/carpet/trim/rug_red_003_end textures/darkmod/carpet/runners/geometric01_red_end -textures/darkmod/city/wall/metal02 textures/darkmod/metal/flat/simple_grey01 -textures/darkmod/city/wall/brick_dark textures/darkmod/stone/brick/rough_brick_grey -textures/darkmod/city/wall/concrete01 textures/darkmod/stone/flat/slate01_light -textures/darkmod/city/wall/cwall_frame01 textures/darkmod/plaster/framed_02 -textures/darkmod/city/wall/cwall_frame02 textures/darkmod/plaster/framed_01 -textures/darkmod/city/wall/cwall_framebrick textures/darkmod/plaster/framed_with_bricks01 -textures/darkmod/city/wall/cwall_framebrick02 textures/darkmod/plaster/framed_with_bricks02 -textures/darkmod/city/wall/metal01 textures/darkmod/metal/flat/simple_grey01 -textures/darkmod/city/roof/rooftile_01 textures/darkmod/roof/shingle_shiny_greenish01 -textures/darkmod/litwindows/cwindow01 textures/darkmod/window/square_pattern01_lit -textures/darkmod/litwindows/cwindow01_dark textures/darkmod/window/square_pattern01_softlit -textures/darkmod/litwindows/cwindow02 textures/darkmod/window/diamond_pattern_andbars01_lit -textures/darkmod/litwindows/hlamp_window01 textures/darkmod/window/pebbly_glass_noframe01_lit -textures/darkmod/city/window/ctywindow01 textures/darkmod/window/diamond_pattern01_lit -textures/darkmod/city/window/ctywindow01b textures/darkmod/window/diamond_pattern01_dark -textures/darkmod/city/window/ctywindow02 textures/darkmod/window/shutters_grey_closed - -textures/darkmod/slate/floor/roof_001 textures/darkmod/roof/slate_uneven_withmoss01 -textures/darkmod/slate/floor/roof_002 textures/darkmod/roof/shingle_dullbrown01 -textures/darkmod/slate/floor/slate_001 textures/darkmod/stone/flat/rough_slate_dark01 - -textures/darkmod/metal/gen/bronze_001 textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01 -textures/darkmod/metal/gen/brushedmetal_001 textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01 -textures/darkmod/metal/gen/copper_001 textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01 -textures/darkmod/metal/gen/gold_001 textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01 -textures/darkmod/metal/gen/iron_001 textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01 -textures/darkmod/metal/gen/iron_002 textures/darkmod/metal/flat/tiling_1d/gen_ornate_iron01 -textures/darkmod/metal/gen/paintedmetal_001 textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01 -textures/darkmod/metal/gen/rust_001 textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01 -textures/darkmod/metal/gen/silver_001 textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01 - -textures/darkmod/grass/floor/dirt_001 textures/darkmod/nature/dirt/dirt_001 - -textures/darkmod/wood/gen/wood_001 textures/darkmod/wood/boards/tiling_1d/gen_old_boards -textures/darkmod/wood/gen/wood_002 textures/darkmod/wood/panels/tiling_1d/gen_panel_x_pattern - -textures/darkmod/ceramic/floor/plaster_002 textures/darkmod/plaster/panel_decorative_white -textures/darkmod/ceramic/floor/stucco_001 textures/darkmod/plaster/stucco_01 - -textures/darkmod/mansion/wall/manwcapital01.tga textures/darkmod/wood/panels/panel_pillar_capital - -textures/darkmod/sky/starry1/skyfade textures/darkmod/nature/skybox/starry1/skyfade -textures/darkmod/sky/starry1/twinkle_stars textures/darkmod/nature/skybox/starry1/twinkle_stars -textures/darkmod/sky/starry1/clouds textures/darkmod/nature/skybox/starry1/clouds -textures/darkmod/sky/starry1/clouds2 textures/darkmod/nature/skybox/starry1/clouds2 -textures/darkmod/sky/starry1/moon textures/darkmod/nature/skybox/starry1/moon -textures/darkmod/sky/starry1/moon_full textures/darkmod/nature/skybox/starry1/moon_full -textures/darkmod/sky/starry1/moon_quarter textures/darkmod/nature/skybox/starry1/moon_quarter -textures/darkmod/sky/starry1/moon_gibbous textures/darkmod/nature/skybox/starry1/moon_gibbous -textures/darkmod/sky/starry1/moon_crescent textures/darkmod/nature/skybox/starry1/moon_crescent -textures/darkmod/sky/starry1/moon_full_glared textures/darkmod/nature/skybox/starry1/moon_full_glared -textures/darkmod/sky/dm_sqsky textures/darkmod/nature/skybox/sqsky - -textures/darkmod/ceramic/wall/plaster_001 textures/darkmod/plaster/plaster02 -textures/darkmod/ceramic/wall/stucco_001 textures/darkmod/plaster/tiling_1d/plaster_dirty01_brown -textures/darkmod/ceramic/wall/stucco_001_grey textures/darkmod/plaster/tiling_1d/plaster_dirty01_grey - -textures/darkmod/foliage/wall/hedge_001 textures/darkmod/nature/foliage/hedge_001 -textures/darkmod/city/wall/ctywall04 textures/darkmod/plaster/framed_trim_lions - -textures/darkmod/snow/floor/rippled_001 textures/darkmod/nature/snow/plain_snow01 -textures/darkmod/snow/floor/icy_001 textures/darkmod/nature/snow/plain_ice01 - -textures/darkmod/stone/floor/brick_003 textures/darkmod/stone/brick/diagonal_cross - -textures/darkmod/mansion/window/manwindow01 textures/darkmod/window/largesquare02_dark -textures/darkmod/mansion/window/manwindow01b textures/darkmod/window/largesquare02_lit -textures/darkmod/mansion/window/manwindow02 textures/darkmod/window/roundtop_diamond_pattern01_lit -textures/darkmod/mansion/window/manwindow02b textures/darkmod/window/roundtop_diamond_pattern01_dark -textures/darkmod/mansion/window/manwindow02d textures/darkmod/window/roundtop_diamond_pattern01_grey -textures/darkmod/mansion/window/manwindow03 textures/darkmod/window/pointedtop_thin01_dark -textures/darkmod/mansion/window/manwindow04 textures/darkmod/window/roundtop_diamond_pattern01_brightlit - -textures/darkmod/nature/grass03 textures/darkmod/nature/grass/short_dry_grass -textures/darkmod/nature/grass04 textures/darkmod/nature/grass/short_dry_grass_dark -textures/darkmod/nature/natural02 textures/darkmod/nature/bark/old_rough01 - -textures/darkmod/city/wall/concrete_dirt01 textures/darkmod/stone/flat/tiling_1d/concrete_dirt01 -textures/darkmod/city/wall/cwall_01 textures/darkmod/plaster/plaster_01 - -textures/darkmod/stone/wall/cement_002 textures/darkmod/stone/flat/tiling_1d/cement_002 -textures/darkmod/stone/wall/cement_004 textures/darkmod/stone/flat/tiling_1d/cement_004 -textures/darkmod/stone/wall/cement_005 textures/darkmod/stone/flat/tiling_1d/cement_005 -textures/darkmod/stone/wall/cement_007 textures/darkmod/stone/flat/tiling_1d/cement_007 -textures/darkmod/stone/wall/cement_008 textures/darkmod/stone/flat/tiling_1d/cement_008 -textures/darkmod/stone/wall/cement_010 textures/darkmod/stone/flat/tiling_1d/cement_010 - -gold_tile textures/darkmod/metal/flat/gold01 -textures/darkmod/decals/smut_black_round textures/darkmod/decals/dirt/smut_black_round -textures/bonehoard/decals/dirt_001 textures/darkmod/decals/dirt/scattered_dirt02 -textures/bonehoard/decals/dirt_002 textures/darkmod/decals/dirt/dripping_slime05 -textures/bonehoard/decals/dirt_002_edge_left textures/darkmod/decals/dirt/dripping_slime05_left -textures/bonehoard/decals/dirt_002_edge_right textures/darkmod/decals/dirt/dripping_slime05_right -textures/bonehoard/decals/torch_smut_ceiling textures/darkmod/decals/dirt/smut_black_round -textures/bonehoard/decals/torch_smut_wall textures/darkmod/decals/dirt/torch_smut_wall - -textures/darkmod/foliage/floor/flowers_blueviolet_001 textures/darkmod/nature/foliage/nontiling/flowers_blueviolet_01 -textures/darkmod/foliage/floor/flowers_mixed_001 textures/darkmod/nature/foliage/nontiling/flowers_mixed_01 -textures/darkmod/foliage/floor/flowers_pink_001 textures/darkmod/nature/foliage/flowers_pink_01 -textures/darkmod/foliage/floor/flowers_red_001 textures/darkmod/nature/foliage/nontiling/flowers_red_01 -textures/darkmod/foliage/floor/flowers_redyellow_001 textures/darkmod/nature/foliage/nontiling/flowers_redyellow_01 -textures/darkmod/foliage/floor/flowers_violet_001 textures/darkmod/nature/foliage/flowers_violet_01 -textures/darkmod/foliage/floor/flowers_violet_002 textures/darkmod/nature/foliage/flowers_violet_02 -textures/darkmod/foliage/floor/flowers_white_001 textures/darkmod/nature/foliage/nontiling/flowers_white_01 - -textures/darkmod/metal/gen/default_framed textures/darkmod/metal/flat/tiling_1d/gen_default_framed \ No newline at end of file diff --git a/scripts/texture_reorg/texture_rename b/scripts/texture_reorg/texture_rename deleted file mode 100755 index 63b954e6b..000000000 --- a/scripts/texture_reorg/texture_rename +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/python - -# This script replaces a string in a file with another. The old and new -# string can either be specified on the commandline: -# shader_renamd -o oldname -n newname -# or it can be specified with a tab delimited inputfile where each -# line must contain two names, the old and the new one seperated by a TAB -# character. - -import os -import string -import sys -import re -import glob -import scriptutil - -#from DebugMessage import stdMsg, dbgMsg, errMsg, setDebugging - -class Line: - def __init__(self): - self.LineNumber = -1 - self.Text = "" - - def __repr__(self): - return "[ " + self.LineNumber.__repr__() + ", '" + self.Text + "' ]" - -class File: - def __init__(self, name): - self.Filename = name - self.Modified = 0 - self.Line = [] - self.PreLoadFile(name) - - def __repr__(self): - return "[ '"+self.Filename+"', "+self.Modified.__repr__()+", "+len(self.Line).__repr__()+" ]" - - def PreLoadFile(self, filename): - f = open(filename) - b = f.read() - f.close() - - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - b = b.split("\n") - - r = Line() - nr = 0 - - for l in b: - s = l.strip() - - nr = nr + 1 - r.Text = l - r.LineNumber = nr - - self.Line.append(r) - r = Line() - - return - - def ReplaceString(self, old, new): - rc = 0 - #print old, new - for i in self.Line: - t = i.Text.split(old) - if(len(t) <= 1): - continue - - #print len(t), t - - #print old, new - if(len(t[1]) > 0): - #print len(t), t - b = 0 - if(t[1][0:1] == "\"" - or t[1][0:1] == "\t" - or t[1][0:1] == "," - or t[1][0:1] == "(" - or t[1][0:1] == ")" - or t[1][0:1] == " "): - b = 1 - - if(b != 1): - continue - - i.Text = t[0]+new+t[1] - rc = 1 - - return rc - -class TextureRename: - def __init__(self): - self.Map = {} - - def Rename(self, root): - flist = scriptutil.ffind(root, namefs=(lambda s: '.svn' not in s, lambda s: 'tiling' in s,)) - - for n in flist: - s = n.split(root)[1][1:] - mode = "nontiling" - t = s.split(mode) - if len(t) <= 1: - mode = "tiling_1d" - t = s.split(mode) - - if(len(t) <= 1): - print s - continue - - p = t[0] - tn = t[1][1:] - t = tn.split(".") - tn = t[0] - ext = t[1] - print s+" "+p+tn+"_"+mode+"."+ext - self.Map[s] = tn+"_"+mode+"."+ext - - return - - def LoadInput(self, fn): - fl = open(fn, "r+b") - b = fl.read() - fl.close() - - b = b.replace("\r\n", "\n") - b = b.replace("\r", "\n") - b = b.split("\n") - - for l in b: - t = l.split(" ") - if(len(t) <= 1): - continue - - o = t[0] - n = t[1] - self.Map[o] = n - #print o, n - return - - def Replace(self, fn): - mat = File(fn) - rc = 0 - for i in self.Map: - o = i.split(".")[0] - n = self.Map[i].split(".")[0] - rc = rc + mat.ReplaceString(o, n) - - if(rc != 0): - #fl = open(fn+".new", "w+b") - fl = open(fn, "w+b") - print fn+" ... updating" - for i in mat.Line: - fl.write(i.Text+"\n") - fl.close() - return - -def Usage(): - print "USAGE: texture_rename -r texturerootpath " - print "USAGE: texture_rename -i inputfile " - sys.exit(1) - -if __name__ == '__main__': - fl = 0 - if len(sys.argv) <= 1: - Usage() - - sr = TextureRename() - - i = 0 - n = len(sys.argv) - - if(n <= 2): - Usage() - - if sys.argv[1] == '-r': - if(n <= 3): - Usage() - i = 3 - fl = 1 - sr.Rename(sys.argv[2]) - - if sys.argv[1] == '-i': - if(n <= 3): - Usage() - i = 3 - fl = 1 - sr.LoadInput(sys.argv[2]) - - if fl == 0: - Usage() - - while( i < n): - fn = sys.argv[i] - #print "Processing "+fn - sr.Replace(fn) - i = i + 1 - - sys.exit(0) diff --git a/scripts/texture_reorg/texture_rename.txt b/scripts/texture_reorg/texture_rename.txt deleted file mode 100644 index 2357c7197..000000000 --- a/scripts/texture_reorg/texture_rename.txt +++ /dev/null @@ -1,185 +0,0 @@ -textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01.tga textures/darkmod/metal/flat/gen_dark_rusted01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01_local.tga textures/darkmod/metal/flat/gen_dark_rusted01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_dark_rusted01_s.tga textures/darkmod/metal/flat/gen_dark_rusted01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_default_framed.tga textures/darkmod/metal/flat/gen_default_framed_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_default_framed_local.tga textures/darkmod/metal/flat/gen_default_framed_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_ornate_iron01.tga textures/darkmod/metal/flat/gen_ornate_iron01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_ornate_iron01_s.tga textures/darkmod/metal/flat/gen_ornate_iron01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01.tga textures/darkmod/metal/flat/gen_peeling_paint01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01_local.tga textures/darkmod/metal/flat/gen_peeling_paint01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_peeling_paint01_s.tga textures/darkmod/metal/flat/gen_peeling_paint01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01.tga textures/darkmod/metal/flat/gen_shiny_brushedmetal01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01_local.tga textures/darkmod/metal/flat/gen_shiny_brushedmetal01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_shiny_brushedmetal01_s.tga textures/darkmod/metal/flat/gen_shiny_brushedmetal01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01.tga textures/darkmod/metal/flat/gen_smooth_bronze01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01_local.tga textures/darkmod/metal/flat/gen_smooth_bronze01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_bronze01_s.tga textures/darkmod/metal/flat/gen_smooth_bronze01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01.tga textures/darkmod/metal/flat/gen_smooth_copper01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01_local.tga textures/darkmod/metal/flat/gen_smooth_copper01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_copper01_s.tga textures/darkmod/metal/flat/gen_smooth_copper01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01.tga textures/darkmod/metal/flat/gen_smooth_gold01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01_local.tga textures/darkmod/metal/flat/gen_smooth_gold01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_gold01_s.tga textures/darkmod/metal/flat/gen_smooth_gold01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01.tga textures/darkmod/metal/flat/gen_smooth_iron01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01_local.tga textures/darkmod/metal/flat/gen_smooth_iron01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_iron01_s.tga textures/darkmod/metal/flat/gen_smooth_iron01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01.tga textures/darkmod/metal/flat/gen_smooth_silver01_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01_local.tga textures/darkmod/metal/flat/gen_smooth_silver01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/gen_smooth_silver01_s.tga textures/darkmod/metal/flat/gen_smooth_silver01_s_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_dirty01_ed.tga textures/darkmod/metal/flat/rough_dirty01_ed_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_dirty01_local.tga textures/darkmod/metal/flat/rough_dirty01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_iron01_ed.tga textures/darkmod/metal/flat/rough_iron01_ed_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_iron01_local.tga textures/darkmod/metal/flat/rough_iron01_local_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_rusted01_ed.tga textures/darkmod/metal/flat/rough_rusted01_ed_tiling_1d.tga -textures/darkmod/metal/flat/tiling_1d/rough_rusted01_local.tga textures/darkmod/metal/flat/rough_rusted01_local_tiling_1d.tga -textures/darkmod/nature/foliage/nontiling/flowers_blueviolet_01.tga textures/darkmod/nature/foliage/flowers_blueviolet_01_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_blueviolet_01_local.tga textures/darkmod/nature/foliage/flowers_blueviolet_01_local_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_mixed_01.tga textures/darkmod/nature/foliage/flowers_mixed_01_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_mixed_01_local.tga textures/darkmod/nature/foliage/flowers_mixed_01_local_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_redyellow_01.tga textures/darkmod/nature/foliage/flowers_redyellow_01_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_redyellow_01_local.tga textures/darkmod/nature/foliage/flowers_redyellow_01_local_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_red_01.tga textures/darkmod/nature/foliage/flowers_red_01_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_red_01_local.tga textures/darkmod/nature/foliage/flowers_red_01_local_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_white_01.tga textures/darkmod/nature/foliage/flowers_white_01_nontiling.tga -textures/darkmod/nature/foliage/nontiling/flowers_white_01_local.tga textures/darkmod/nature/foliage/flowers_white_01_local_nontiling.tga -textures/darkmod/nature/grass/nontiling/thick_straw01.tga textures/darkmod/nature/grass/thick_straw01_nontiling.tga -textures/darkmod/nature/grass/nontiling/thick_straw01_local.tga textures/darkmod/nature/grass/thick_straw01_local_nontiling.tga -textures/darkmod/plaster/tiling_1d/plaster02_ed.tga textures/darkmod/plaster/plaster02_ed_tiling_1d.tga -textures/darkmod/plaster/tiling_1d/plaster02_local.tga textures/darkmod/plaster/plaster02_local_tiling_1d.tga -textures/darkmod/plaster/tiling_1d/plaster_dirty01_brown.tga textures/darkmod/plaster/plaster_dirty01_brown_tiling_1d.tga -textures/darkmod/plaster/tiling_1d/plaster_dirty01_grey.tga textures/darkmod/plaster/plaster_dirty01_grey_tiling_1d.tga -textures/darkmod/plaster/tiling_1d/plaster_dirty01_local.tga textures/darkmod/plaster/plaster_dirty01_local_tiling_1d.tga -textures/darkmod/stone/brick/nontiling/chiseled_brick_frame.tga textures/darkmod/stone/brick/chiseled_brick_frame_nontiling.tga -textures/darkmod/stone/brick/nontiling/chiseled_brick_frame_local.tga textures/darkmod/stone/brick/chiseled_brick_frame_local_nontiling.tga -textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_grey.tga textures/darkmod/stone/brick/gen_plainbrick_grey_tiling_1d.tga -textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_local.tga textures/darkmod/stone/brick/gen_plainbrick_local_tiling_1d.tga -textures/darkmod/stone/brick/tiling_1d/gen_plainbrick_s.tga textures/darkmod/stone/brick/gen_plainbrick_s_tiling_1d.tga -textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick_ed.tga textures/darkmod/stone/brick/old_worn_greybrick_ed_tiling_1d.tga -textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick_local.tga textures/darkmod/stone/brick/old_worn_greybrick_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/nontiling/flagstones_jagged_grey.tga textures/darkmod/stone/cobblestones/flagstones_jagged_grey_nontiling.tga -textures/darkmod/stone/cobblestones/nontiling/flagstones_jagged_grey_local.tga textures/darkmod/stone/cobblestones/flagstones_jagged_grey_local_nontiling.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey_ed.tga textures/darkmod/stone/cobblestones/blocks_uneven02_grey_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey_local.tga textures/darkmod/stone/cobblestones/blocks_uneven02_grey_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey_ed.tga textures/darkmod/stone/cobblestones/blocks_uneven03_grey_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey_local.tga textures/darkmod/stone/cobblestones/blocks_uneven03_grey_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown_ed.tga textures/darkmod/stone/cobblestones/blocks_uneven04_brown_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown_local.tga textures/darkmod/stone/cobblestones/blocks_uneven04_brown_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey_ed.tga textures/darkmod/stone/cobblestones/blocks_uneven05_grey_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey_local.tga textures/darkmod/stone/cobblestones/blocks_uneven05_grey_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix_ed.tga textures/darkmod/stone/cobblestones/bricks_blocks_mix_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix_local.tga textures/darkmod/stone/cobblestones/bricks_blocks_mix_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix_ed.tga textures/darkmod/stone/cobblestones/bricks_blocks_roughmix_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix_local.tga textures/darkmod/stone/cobblestones/bricks_blocks_roughmix_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded_ed.tga textures/darkmod/stone/cobblestones/cobblestones_rounded_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded_local.tga textures/darkmod/stone/cobblestones/cobblestones_rounded_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse_ed.tga textures/darkmod/stone/cobblestones/flagstones_sparse_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse_local.tga textures/darkmod/stone/cobblestones/flagstones_sparse_local_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven_ed.tga textures/darkmod/stone/cobblestones/flagstones_uneven_ed_tiling_1d.tga -textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven_local.tga textures/darkmod/stone/cobblestones/flagstones_uneven_local_tiling_1d.tga -textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_brown.tga textures/darkmod/stone/flat/smooth/marble_trim01_brown_tiling_1d.tga -textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_local.tga textures/darkmod/stone/flat/smooth/marble_trim01_local_tiling_1d.tga -textures/darkmod/stone/flat/smooth/tiling_1d/marble_trim01_s.tga textures/darkmod/stone/flat/smooth/marble_trim01_s_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_002_ed.tga textures/darkmod/stone/flat/cement_002_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_002_local.tga textures/darkmod/stone/flat/cement_002_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_004_ed.tga textures/darkmod/stone/flat/cement_004_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_004_local.tga textures/darkmod/stone/flat/cement_004_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_005_ed.tga textures/darkmod/stone/flat/cement_005_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_005_local.tga textures/darkmod/stone/flat/cement_005_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_007_ed.tga textures/darkmod/stone/flat/cement_007_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_007_local.tga textures/darkmod/stone/flat/cement_007_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_008_ed.tga textures/darkmod/stone/flat/cement_008_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_008_local.tga textures/darkmod/stone/flat/cement_008_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_010_ed.tga textures/darkmod/stone/flat/cement_010_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/cement_010_local.tga textures/darkmod/stone/flat/cement_010_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_dirt01.tga textures/darkmod/stone/flat/concrete_dirt01_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_local.tga textures/darkmod/stone/flat/concrete_dirt01_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_dirt01_s.tga textures/darkmod/stone/flat/concrete_dirt01_s_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked_ed.tga textures/darkmod/stone/flat/concrete_light_cracked_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked_local.tga textures/darkmod/stone/flat/concrete_light_cracked_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked_ed.tga textures/darkmod/stone/flat/concrete_light_streaked_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked_local.tga textures/darkmod/stone/flat/concrete_light_streaked_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01_ed.tga textures/darkmod/stone/flat/concrete_rough_dark01_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01_local.tga textures/darkmod/stone/flat/concrete_rough_dark01_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02_ed.tga textures/darkmod/stone/flat/concrete_rough_dark02_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02_local.tga textures/darkmod/stone/flat/concrete_rough_dark02_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly_ed.tga textures/darkmod/stone/flat/concrete_rough_pebbly_ed_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly_local.tga textures/darkmod/stone/flat/concrete_rough_pebbly_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/gen_slate_dirt_local.tga textures/darkmod/stone/flat/gen_slate_dirt_local_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/gen_slate_dirt_s.tga textures/darkmod/stone/flat/gen_slate_dirt_s_tiling_1d.tga -textures/darkmod/stone/flat/tiling_1d/gen_slate_light_dirt.tga textures/darkmod/stone/flat/gen_slate_light_dirt_tiling_1d.tga -textures/darkmod/stone/natural/tiling_1d/gravel_grey_01.tga textures/darkmod/stone/natural/gravel_grey_01_tiling_1d.tga -textures/darkmod/stone/natural/tiling_1d/gravel_grey_01_local.tga textures/darkmod/stone/natural/gravel_grey_01_local_tiling_1d.tga -textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing.tga textures/darkmod/stone/sculpted/marble_ancient_writing_tiling_1d.tga -textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing_ed.tga textures/darkmod/stone/sculpted/marble_ancient_writing_ed_tiling_1d.tga -textures/darkmod/wood/boards/tiling_1d/gen_old_boards.tga textures/darkmod/wood/boards/gen_old_boards_tiling_1d.tga -textures/darkmod/wood/boards/tiling_1d/gen_old_boards_local.tga textures/darkmod/wood/boards/gen_old_boards_local_tiling_1d.tga -textures/darkmod/wood/boards/tiling_1d/new_grainy_ed.tga textures/darkmod/wood/boards/new_grainy_ed_tiling_1d.tga -textures/darkmod/wood/boards/tiling_1d/new_grainy_local.tga textures/darkmod/wood/boards/new_grainy_local_tiling_1d.tga -textures/darkmod/wood/panels/nontiling/beam_brown_old_burnt.tga textures/darkmod/wood/panels/beam_brown_old_burnt_nontiling.tga -textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap_ed.tga textures/darkmod/wood/panels/beam_brown_old_endcap_ed_nontiling.tga -textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap_local.tga textures/darkmod/wood/panels/beam_brown_old_endcap_local_nontiling.tga -textures/darkmod/wood/panels/nontiling/beam_rough_brown_endcap_ed.jpg textures/darkmod/wood/panels/beam_rough_brown_endcap_ed_nontiling.jpg -textures/darkmod/wood/panels/nontiling/beam_rough_endcap_local.tga textures/darkmod/wood/panels/beam_rough_endcap_local_nontiling.tga -textures/darkmod/wood/panels/nontiling/beam_rough_weathered_endcap_ed.jpg textures/darkmod/wood/panels/beam_rough_weathered_endcap_ed_nontiling.jpg -textures/darkmod/wood/panels/tiling_1d/gen_panel_x_pattern.tga textures/darkmod/wood/panels/gen_panel_x_pattern_tiling_1d.tga -textures/darkmod/wood/panels/tiling_1d/gen_panel_x_pattern_local.tga textures/darkmod/wood/panels/gen_panel_x_pattern_local_tiling_1d.tga - -dds/textures/darkmod/metal/flat/tiling_1d/rough_dirty01.dds dds/textures/darkmod/metal/flat/rough_dirty01_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_dirty01_local.dds dds/textures/darkmod/metal/flat/rough_dirty01_local_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_iron01.dds dds/textures/darkmod/metal/flat/rough_iron01_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_iron01_local.dds dds/textures/darkmod/metal/flat/rough_iron01_local_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_rusted01.dds dds/textures/darkmod/metal/flat/rough_rusted01_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_rusted01_local.dds dds/textures/darkmod/metal/flat/rough_rusted01_local_tiling_1d.dds -dds/textures/darkmod/metal/flat/tiling_1d/rough_rusted01_s.dds dds/textures/darkmod/metal/flat/rough_rusted01_s_tiling_1d.dds -dds/textures/darkmod/plaster/tiling_1d/plaster02.dds dds/textures/darkmod/plaster/plaster02_tiling_1d.dds -dds/textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick.dds dds/textures/darkmod/stone/brick/old_worn_greybrick_tiling_1d.dds -dds/textures/darkmod/stone/brick/tiling_1d/old_worn_greybrick_local.dds dds/textures/darkmod/stone/brick/old_worn_greybrick_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/nontiling/flagstones_sparse_local.dds dds/textures/darkmod/stone/cobblestones/flagstones_sparse_local_nontiling.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven02_grey_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven02_grey_local.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven02_grey_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven03_grey_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven03_grey_local.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven03_grey_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven04_brown_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven04_brown_local.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven04_brown_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven05_grey_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/blocks_uneven05_grey_local.dds dds/textures/darkmod/stone/cobblestones/blocks_uneven05_grey_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix.dds dds/textures/darkmod/stone/cobblestones/bricks_blocks_mix_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_mix_local.dds dds/textures/darkmod/stone/cobblestones/bricks_blocks_mix_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix.dds dds/textures/darkmod/stone/cobblestones/bricks_blocks_roughmix_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/bricks_blocks_roughmix_local.dds dds/textures/darkmod/stone/cobblestones/bricks_blocks_roughmix_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded.dds dds/textures/darkmod/stone/cobblestones/cobblestones_rounded_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/cobblestones_rounded_local.dds dds/textures/darkmod/stone/cobblestones/cobblestones_rounded_local_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/flagstones_sparse.dds dds/textures/darkmod/stone/cobblestones/flagstones_sparse_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven.dds dds/textures/darkmod/stone/cobblestones/flagstones_uneven_tiling_1d.dds -dds/textures/darkmod/stone/cobblestones/tiling_1d/flagstones_uneven_local.dds dds/textures/darkmod/stone/cobblestones/flagstones_uneven_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_002.dds dds/textures/darkmod/stone/flat/cement_002_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_002_local.dds dds/textures/darkmod/stone/flat/cement_002_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_004.dds dds/textures/darkmod/stone/flat/cement_004_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_004_local.dds dds/textures/darkmod/stone/flat/cement_004_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_005.dds dds/textures/darkmod/stone/flat/cement_005_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_005_local.dds dds/textures/darkmod/stone/flat/cement_005_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_007.dds dds/textures/darkmod/stone/flat/cement_007_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_007_local.dds dds/textures/darkmod/stone/flat/cement_007_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_008.dds dds/textures/darkmod/stone/flat/cement_008_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_008_local.dds dds/textures/darkmod/stone/flat/cement_008_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_010.dds dds/textures/darkmod/stone/flat/cement_010_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_010_local.dds dds/textures/darkmod/stone/flat/cement_010_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/cement_010_s.dds dds/textures/darkmod/stone/flat/cement_010_s_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked.dds dds/textures/darkmod/stone/flat/concrete_light_cracked_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_cracked_local.dds dds/textures/darkmod/stone/flat/concrete_light_cracked_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked.dds dds/textures/darkmod/stone/flat/concrete_light_streaked_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_light_streaked_local.dds dds/textures/darkmod/stone/flat/concrete_light_streaked_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01.dds dds/textures/darkmod/stone/flat/concrete_rough_dark01_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark01_local.dds dds/textures/darkmod/stone/flat/concrete_rough_dark01_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02.dds dds/textures/darkmod/stone/flat/concrete_rough_dark02_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_dark02_local.dds dds/textures/darkmod/stone/flat/concrete_rough_dark02_local_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly.dds dds/textures/darkmod/stone/flat/concrete_rough_pebbly_tiling_1d.dds -dds/textures/darkmod/stone/flat/tiling_1d/concrete_rough_pebbly_local.dds dds/textures/darkmod/stone/flat/concrete_rough_pebbly_local_tiling_1d.dds -dds/textures/darkmod/stone/sculpted/tiling_1d/marble_ancient_writing.dds dds/textures/darkmod/stone/sculpted/marble_ancient_writing_tiling_1d.dds -dds/textures/darkmod/wood/boards/tiling_1d/new_grainy.dds dds/textures/darkmod/wood/boards/new_grainy_tiling_1d.dds -dds/textures/darkmod/wood/boards/tiling_1d/new_grainy_local.dds dds/textures/darkmod/wood/boards/new_grainy_local_tiling_1d.dds -dds/textures/darkmod/wood/boards/tiling_1d/new_grainy_s.dds dds/textures/darkmod/wood/boards/new_grainy_s_tiling_1d.dds -dds/textures/darkmod/wood/panels/nontiling/beam_brown_old_endcap.dds dds/textures/darkmod/wood/panels/beam_brown_old_endcap_nontiling.dds -dds/textures/darkmod/wood/panels/nontiling/beam_rough_brown_endcap.dds dds/textures/darkmod/wood/panels/beam_rough_brown_endcap_nontiling.dds -dds/textures/darkmod/wood/panels/nontiling/beam_rough_endcap_local.dds dds/textures/darkmod/wood/panels/beam_rough_endcap_local_nontiling.dds -dds/textures/darkmod/wood/panels/nontiling/beam_rough_weathered_endcap.dds dds/textures/darkmod/wood/panels/beam_rough_weathered_endcap_nontiling.dds diff --git a/scripts/texture_reorg/texture_reorg_folders.txt b/scripts/texture_reorg/texture_reorg_folders.txt deleted file mode 100644 index 957d299c9..000000000 --- a/scripts/texture_reorg/texture_reorg_folders.txt +++ /dev/null @@ -1,1859 +0,0 @@ - Volume in drive D is Main Drive - Volume Serial Number is 58DB-10F0 - - Directory of D:\temp2\textures - -04/21/2007 03:42 PM . -04/21/2007 03:42 PM .. -05/31/2007 08:20 PM darkmod - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod - -05/31/2007 08:20 PM . -05/31/2007 08:20 PM .. -05/31/2007 08:15 PM carpet -04/23/2007 07:41 PM decals -04/23/2007 07:43 PM door -05/09/2007 08:00 PM map_specific -05/12/2007 11:15 AM metal -04/23/2007 08:03 PM nature -05/26/2007 11:48 AM paint_paper -05/01/2007 07:32 PM roof -05/05/2007 07:25 PM sfx -05/31/2007 08:20 PM stone -05/05/2007 03:40 PM window -05/31/2007 08:26 PM wood - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\carpet - -05/31/2007 08:15 PM . -05/31/2007 08:15 PM .. -05/09/2007 07:55 PM rugs -05/09/2007 07:57 PM runners - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\carpet\rugs - -05/09/2007 07:55 PM . -05/09/2007 07:55 PM .. -02/24/2007 09:22 PM 393,260 ornate_black_gold01.tga.setrug01.tga -02/24/2007 09:22 PM 393,260 ornate_black_gold01_local.tga.setrug01_local.tga -02/24/2007 09:22 PM 393,260 ornate_floral_checker01.tga.setrug02.tga -02/24/2007 09:22 PM 393,260 ornate_floral_checker01_local.tga.setrug02_local.tga -05/09/2007 07:54 PM 393,260 ornate_green_black01.tga.setrug03sh.tga -02/24/2007 09:22 PM 394,185 ornate_green_black01_local.tga.setrug03sh_local.tga -02/24/2007 09:22 PM 394,138 ornate_rectangles_brown01.tga.setrug03.tga -02/24/2007 09:22 PM 394,087 ornate_rectangles_brown01_local.tga.setrug03_local.tga -02/24/2007 09:22 PM 394,251 ornate_red_tan01.tga.setrug01sh.tga -02/24/2007 09:22 PM 394,186 ornate_red_tan01_local.tga.setrug01sh_local.tga -05/09/2007 07:49 PM 393,260 ornate_red_tan02.tga.setrug02sh.tga -02/24/2007 09:22 PM 393,980 ornate_red_tan02_local.tga.setrug02sh_local.tga - 12 File(s) 4,724,387 bytes - - Directory of D:\temp2\textures\darkmod\carpet\runners - -05/09/2007 07:57 PM . -05/09/2007 07:57 PM .. -02/24/2007 09:22 PM 197,103 geometric01_end_local.tga.setrug04end_local.tga -02/24/2007 09:22 PM 393,722 geometric01_local.tga.setrug04cen_local.tga -02/24/2007 09:22 PM 394,172 geometric01_red.tga.setrug04cen.tga -02/24/2007 09:22 PM 196,922 geometric01_red_end.tga.setrug04end.tga - 4 File(s) 1,181,919 bytes - - Directory of D:\temp2\textures\darkmod\decals - -04/23/2007 07:41 PM . -04/23/2007 07:41 PM .. -04/23/2007 07:40 PM blood -05/04/2007 08:14 PM dirt -05/03/2007 08:20 PM symbols -05/05/2007 12:23 PM vegetation - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\decals\blood - -04/23/2007 07:40 PM . -04/23/2007 07:40 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\decals\dirt - -05/04/2007 08:14 PM . -05/04/2007 08:14 PM .. -12/10/2005 07:54 PM 91,680 dripping_slime01.tga -12/11/2005 04:10 PM 91,487 dripping_slime01_light.tga -12/11/2005 04:13 PM 490,632 dripping_slime02.tga -12/11/2005 05:45 PM 268,595 dripping_slime03.tga -12/11/2005 05:46 PM 317,951 dripping_slime04.tga -03/11/2007 02:56 PM 476,814 dripping_slime05.tga.dirt_002.tga -03/11/2007 02:56 PM 410,960 dripping_slime05_left.tga.dirt_002_edge_left.tga -03/11/2007 02:56 PM 445,051 dripping_slime05_right.tga.dirt_002_edge_right.tga -12/10/2005 06:23 PM 327,519 long_drip_pattern01.tga -03/20/2007 08:50 PM 1,046,985 moss_patch_thick01.tga.moss_d.tga -03/20/2007 08:50 PM 788,363 moss_patch_thick01.tga.moss_local.tga -12/10/2005 06:27 PM 67,836 scattered_dirt01.tga -03/11/2007 02:56 PM 678,910 scattered_dirt02.tga.dirt_001.tga -12/10/2005 04:59 PM 53,634 splat01.tga -12/10/2005 06:25 PM 139,282 splat02.tga -12/10/2005 06:27 PM 165,966 splat_small03.tga -03/11/2007 07:12 PM 496,244 torch_smut_ceiling.tga -03/11/2007 07:12 PM 467,708 torch_smut_wall.tga -12/10/2005 07:36 PM 1,048,620 wall_grime01.tga -12/10/2005 06:51 PM 675,636 wall_grime02.tga -12/10/2005 07:50 PM 105,894 wall_grime03.tga -12/10/2005 07:49 PM 786,476 wall_grime04.tga -12/10/2005 06:45 PM 406,879 wall_grime05.tga - 23 File(s) 9,849,122 bytes - - Directory of D:\temp2\textures\darkmod\decals\symbols - -05/03/2007 08:20 PM . -05/03/2007 08:20 PM .. -02/24/2007 07:50 PM 131,116 magical_letters_row01.tga.pagdecvoyn.tga -02/24/2007 07:50 PM 262,188 magic_symbol_circle01.tga.pagdecfleur.tga - 2 File(s) 393,304 bytes - - Directory of D:\temp2\textures\darkmod\decals\vegetation - -05/05/2007 12:23 PM . -05/05/2007 12:23 PM .. -12/14/2005 12:03 AM 1,048,620 autumn_leaves_thick01.tga -12/14/2005 12:00 AM 262,188 dead_leaves_few01.tga -05/05/2007 12:20 PM 393,260 hanging_horizontal_leaves.tga.natural01.tga -02/24/2007 09:29 PM 48,057 hanging_horizontal_leaves_local.tga.natural01_local.tga -02/24/2007 09:29 PM 10,727 hanging_horizontal_leaves_s.tga.natural01_s.tga -02/25/2007 01:14 AM 87,528 ivypatch_average01.dds.ivy_001_patch1.dds -02/25/2007 01:14 AM 174,904 ivypatch_large01.dds.ivy_001_patch2.dds -02/25/2007 01:14 AM 5,608 ivypatch_small01.dds.ivy_001_small1.dds -02/25/2007 01:14 AM 11,064 ivypatch_tiny01.dds.ivy_001_small2.dds -03/18/2007 03:28 PM 4,194,348 ivy_mixed_pieces.tga.ivy_002.tga -03/18/2007 03:28 PM 22,364 ivy_mixed_pieces_ed.jpg.ivy_002_ed.jpg -03/18/2007 03:28 PM 3,146,267 ivy_mixed_pieces_local.tga.ivy_002_local.tga -03/18/2007 03:28 PM 786,971 ivy_mixed_pieces_s.tga.ivy_002_s.tga -03/18/2007 03:28 PM 524,332 ivy_scattered_branches.tga.ivy_004.tga -03/18/2007 03:28 PM 20,168 ivy_scattered_branches_ed.jpg.ivy_004_ed.jpg -03/18/2007 03:28 PM 393,260 ivy_scattered_branches_local.tga.ivy_004_local.tga -03/18/2007 03:28 PM 393,260 ivy_scattered_branches_s.tga.ivy_004_s.tga -03/18/2007 03:28 PM 524,332 ivy_vertical_branches.tga.ivy_003.tga -03/18/2007 03:28 PM 17,514 ivy_vertical_branches_ed.jpg.ivy_003_ed.jpg -03/18/2007 03:28 PM 393,260 ivy_vertical_branches_local.tga.ivy_003_local.tga -03/18/2007 03:28 PM 393,260 ivy_vertical_branches_s.tga.ivy_003_s.tga -02/24/2007 09:29 PM 262,188 tropical_broadleaf.tga.plant01.tga -02/24/2007 09:29 PM 262,188 tropical_fern01.tga.plant02.tga - 23 File(s) 13,375,668 bytes - - Directory of D:\temp2\textures\darkmod\door - -04/23/2007 07:43 PM . -04/23/2007 07:43 PM .. -05/26/2007 07:05 PM metal -05/03/2007 07:31 PM wood - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\door\metal - -05/26/2007 07:05 PM . -05/26/2007 07:05 PM .. -04/23/2007 07:41 PM bars -03/07/2006 02:09 PM 1,572,908 large_warehouse_old_green01.tga -03/07/2006 02:32 PM 1,560,648 large_warehouse_old_local.tga -03/15/2006 07:39 PM 1,496,963 large_warehouse_old_s.tga -05/26/2007 07:05 PM 393,260 simple_rough01.tga -05/26/2007 07:02 PM 393,260 simple_rough01_local.tga - 5 File(s) 5,417,039 bytes - - Directory of D:\temp2\textures\darkmod\door\metal\bars - -04/23/2007 07:41 PM . -04/23/2007 07:41 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\door\wood - -05/03/2007 07:31 PM . -05/03/2007 07:31 PM .. -04/30/2007 06:34 PM 393,260 board_plainblue_hinge01.tga -04/30/2007 06:34 PM 393,260 board_plainblue_hinge02.tga -04/30/2007 06:22 PM 393,260 board_plain_hinge01.tga -04/30/2007 06:22 PM 393,260 board_plain_hinge01_local.tga -04/30/2007 06:32 PM 393,260 board_plain_hinge02.tga -04/30/2007 06:31 PM 393,260 board_plain_hinge02_local.tga -12/12/2005 11:18 PM 1,570,089 board_withwindow_green01.tga -02/24/2007 10:53 PM 393,615 diamond_pattern01.tga.ctydoor01.tga -04/26/2007 07:41 PM 393,260 diamond_pattern01_local.tag.ctydoor01_local.tga -04/26/2007 06:46 PM 393,260 metalbands_crisscross01.tga.casdoor01.tga -02/24/2007 11:16 PM 281,463 metalbands_crisscross01_local.tga.casdoor01_local.tga -02/24/2007 11:16 PM 67,557 metalbands_crisscross01_s.tga.casdoor01_s.tga -02/25/2007 02:03 AM 87,528 oldboards_metalspirals01.dds.antique_001.dds -02/24/2007 11:06 PM 98,843 oldboards_metalspirals01_ed.tga.antique_001_editor.tga -02/24/2007 11:06 PM 393,260 oldboards_metalspirals01_local.tga.antique_001_local.tga -02/24/2007 02:12 PM 774,211 old_4panels_peelingpaint01.tga.warehouse_frontdoor_d.tga -04/26/2007 07:43 PM 393,260 old_flat_oak01.tga.mandoor01.tga -04/26/2007 07:44 PM 393,260 old_flat_oak01_local.tga.mandoor01_local.tga -04/26/2007 07:47 PM 98,348 old_flat_oak01_s.tga.mandoor01_s.tga -04/27/2007 08:07 PM 1,572,908 old_weathered_boards01.tga.weathered_001_d.tga -02/24/2007 11:06 PM 1,575,457 old_weathered_boards01_local.tga.weathered_001_local.tga -05/01/2007 07:48 PM ornate -02/24/2007 02:12 PM 774,211 rough_4panels_peelingpaint.tga.warehouse_frontdoor_d.tga -02/24/2007 10:03 PM 393,088 smooth_2panels_rich.tga.mandoor06.tga -02/24/2007 10:03 PM 387,511 smooth_2panels_rich_local.tga.mandoor06_local.tga -02/24/2007 10:03 PM 95,566 smooth_2panels_rich_s.tga.mandoor06_s.tga -02/24/2007 10:03 PM 393,260 smooth_3panels01_dull01.tga.mandoor01sh.tga -04/27/2007 08:19 PM 24,620 smooth_3panels01_dull_s.tga.mandoor01sh_s.tga -02/24/2007 10:03 PM 393,260 smooth_3panels01_remove_local.tga.mandoor01sh_local.tga -02/24/2007 10:03 PM 393,260 smooth_3panels_local.tga.mandoor03_local.tga -02/24/2007 10:03 PM 393,260 smooth_3panels_red01.tga.mandoor03.tga -02/24/2007 10:03 PM 389,788 smooth_4panels_local.tga.mandoor02ab_local.tga -02/24/2007 10:03 PM 364,211 smooth_4panels_red01.tga.mandoor02b.tga -02/24/2007 10:03 PM 387,862 smooth_4panels_tan01.tga.mandoor02a.tga - 33 File(s) 15,235,776 bytes - - Directory of D:\temp2\textures\darkmod\door\wood\ornate - -05/01/2007 07:48 PM . -05/01/2007 07:48 PM .. -02/24/2007 10:03 PM 393,844 smooth_rich_ovalwindow01.tga.mandoor04.tga -02/24/2007 10:03 PM 394,427 smooth_rich_ovalwindow01_local.tga.mandoor04_local.tga -02/24/2007 10:03 PM 94,637 smooth_rich_ovalwindow01_s.tga.mandoor04_s.tga -02/24/2007 10:03 PM 392,193 smooth_rich_squarewindow01.tga.mandoor05.tga -02/24/2007 09:29 PM 80,446 smooth_rich_squarewindow01_alpha.tga.mandoor05_withalpha.tga -02/24/2007 10:03 PM 376,983 smooth_rich_squarewindow01_local.tga.mandoor05_local.tga -02/24/2007 10:03 PM 92,516 smooth_rich_squarewindow01_s.tga.mandoor05_s.tga - 7 File(s) 1,825,046 bytes - - Directory of D:\temp2\textures\darkmod\map_specific - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -05/09/2007 08:00 PM bonehoard - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -05/09/2007 08:00 PM env - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn - -05/06/2007 09:04 PM 932 all-wcprops -05/08/2007 07:32 PM 1,117 entries -03/11/2007 02:56 PM 2 format -05/09/2007 08:00 PM prop-base -05/09/2007 08:00 PM props -05/09/2007 08:00 PM text-base -05/09/2007 08:00 PM tmp - 3 File(s) 2,051 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\prop-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -03/11/2007 02:56 PM 53 dirt_001.tga.svn-base -03/11/2007 02:56 PM 53 dirt_002.tga.svn-base -03/11/2007 02:56 PM 53 dirt_002_edge_left.tga.svn-base -03/11/2007 02:56 PM 53 dirt_002_edge_right.tga.svn-base -03/11/2007 07:12 PM 53 torch_smut_ceiling.tga.svn-base -03/11/2007 07:11 PM 53 torch_smut_wall.tga.svn-base - 6 File(s) 318 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\props - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\text-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -03/11/2007 02:56 PM 678,910 dirt_001.tga.svn-base -03/11/2007 02:56 PM 476,814 dirt_002.tga.svn-base -03/11/2007 02:56 PM 410,960 dirt_002_edge_left.tga.svn-base -03/11/2007 02:56 PM 445,051 dirt_002_edge_right.tga.svn-base -03/11/2007 07:12 PM 496,244 torch_smut_ceiling.tga.svn-base -03/11/2007 07:11 PM 467,708 torch_smut_wall.tga.svn-base - 6 File(s) 2,975,687 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\tmp - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -05/09/2007 08:00 PM prop-base -05/09/2007 08:00 PM props -05/09/2007 08:00 PM text-base - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\tmp\prop-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\tmp\props - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\.svn\tmp\text-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -04/28/2007 06:25 PM 786,476 water_entrance_back.tga -04/28/2007 06:25 PM 8,236 water_entrance_down.tga -04/28/2007 06:25 PM 786,476 water_entrance_forward.tga -04/28/2007 06:25 PM 786,476 water_entrance_left.tga -04/28/2007 06:25 PM 786,476 water_entrance_right.tga -04/28/2007 06:25 PM 786,476 water_entrance_up.tga - 6 File(s) 3,940,616 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn - -04/28/2007 06:25 PM 1,020 all-wcprops -05/08/2007 07:32 PM 1,140 entries -04/28/2007 06:25 PM 2 format -05/09/2007 08:00 PM prop-base -05/09/2007 08:00 PM props -05/09/2007 08:00 PM text-base -05/09/2007 08:00 PM tmp - 3 File(s) 2,162 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\prop-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -04/28/2007 06:25 PM 53 water_entrance_back.tga.svn-base -04/28/2007 06:25 PM 53 water_entrance_down.tga.svn-base -04/28/2007 06:25 PM 53 water_entrance_forward.tga.svn-base -04/28/2007 06:25 PM 53 water_entrance_left.tga.svn-base -04/28/2007 06:25 PM 53 water_entrance_right.tga.svn-base -04/28/2007 06:25 PM 53 water_entrance_up.tga.svn-base - 6 File(s) 318 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\props - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\text-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -04/28/2007 06:25 PM 786,476 water_entrance_back.tga.svn-base -04/28/2007 06:25 PM 8,236 water_entrance_down.tga.svn-base -04/28/2007 06:25 PM 786,476 water_entrance_forward.tga.svn-base -04/28/2007 06:25 PM 786,476 water_entrance_left.tga.svn-base -04/28/2007 06:25 PM 786,476 water_entrance_right.tga.svn-base -04/28/2007 06:25 PM 786,476 water_entrance_up.tga.svn-base - 6 File(s) 3,940,616 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\tmp - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. -05/09/2007 08:00 PM prop-base -05/09/2007 08:00 PM props -05/09/2007 08:00 PM text-base - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\tmp\prop-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\tmp\props - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\map_specific\bonehoard\env\.svn\tmp\text-base - -05/09/2007 08:00 PM . -05/09/2007 08:00 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\metal - -05/12/2007 11:15 AM . -05/12/2007 11:15 AM .. -05/10/2007 09:23 PM detailed -06/01/2007 07:56 PM flat -06/01/2007 07:57 PM grate - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\metal\detailed - -05/10/2007 09:23 PM . -05/10/2007 09:23 PM .. -04/23/2007 07:49 PM nontiling -02/24/2007 11:12 PM 197,448 panel_circledesign01_brown.tga.caswpanel01b.tga -02/24/2007 11:12 PM 195,114 panel_circledesign01_green.tga.caswpanel01.tga -02/24/2007 11:12 PM 188,810 panel_circledesign01_local.tga.caswpanel01_local.tga -02/24/2007 11:12 PM 196,652 panel_circledesign_ornate01_green.tga.caswpanel02.tga -02/24/2007 11:12 PM 186,464 panel_circledesign_ornate01_local.tga.caswpanel02_local.tga -04/23/2007 07:50 PM tiling_1d - 5 File(s) 964,488 bytes - - Directory of D:\temp2\textures\darkmod\metal\detailed\nontiling - -04/23/2007 07:49 PM . -04/23/2007 07:49 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\metal\detailed\tiling_1d - -04/23/2007 07:50 PM . -04/23/2007 07:50 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\metal\flat - -06/01/2007 07:56 PM . -06/01/2007 07:56 PM .. -02/24/2007 09:38 PM 780,275 gen_detail.tga -02/25/2007 01:13 AM 699,192 heavy_rust_pocked01.dds.rust_002_d.DDS -02/24/2007 09:33 PM 196,652 heavy_rust_pocked01_ed.tga.rust_002_ed.tga -02/24/2007 09:33 PM 3,145,772 heavy_rust_pocked_local.tga.rust_002_local.tga -02/25/2007 01:13 AM 699,192 heavy_rust_pocked_s.dds.rust_002_s.DDS -05/10/2007 09:23 PM nontiling -02/24/2007 10:47 PM 786,476 simple_grey01.tga.metal01_d.tga -02/24/2007 10:47 PM 786,476 simple_grey01_local.tga.metal01_local.tga -02/24/2007 10:47 PM 786,476 simple_grey01_s.tga.metal01_s.tga -03/04/2007 05:11 PM 699,192 simple_rough_grey01.dds.rust_004_d.DDS -03/04/2007 05:10 PM 196,713 simple_rough_grey01_ed.tga.rust_004_ed.tga -03/04/2007 05:10 PM 3,153,901 simple_rough_grey01_local.tga.rust_004_local.tga -02/25/2007 01:13 AM 699,192 solid_rust01.dds.rust_003_d.DDS -02/24/2007 09:33 PM 197,149 solid_rust01_ed.tga.rust_003_ed.tga -02/24/2007 09:33 PM 3,153,219 solid_rust01_local.tga.rust_003_local.tga -04/15/2007 04:11 PM 699,192 solid_rust02.dds.rust_005.dds -04/15/2007 04:09 PM 18,755 solid_rust02_ed.jpg.rust_005_editor.jpg -04/15/2007 04:09 PM 3,145,772 solid_rust02_local.tga.rust_005_local.tga -04/15/2007 04:11 PM 174,904 solid_rust02_s.dds.rust_005_s.dds -05/23/2007 07:26 PM tiling_1d - 18 File(s) 20,018,500 bytes - - Directory of D:\temp2\textures\darkmod\metal\flat\nontiling - -05/10/2007 09:23 PM . -05/10/2007 09:23 PM .. -03/07/2006 03:08 PM 391,562 roughedup_steel.tga.metalpole_d.tga -03/07/2006 03:12 PM 354,981 roughedup_steel_s.tga.metalpole_s.tga - 2 File(s) 746,543 bytes - - Directory of D:\temp2\textures\darkmod\metal\flat\tiling_1d - -05/23/2007 07:26 PM . -05/23/2007 07:26 PM .. -02/24/2007 09:38 PM 716,116 gen_dark_rusted01.tga.rust_001_d.tga -02/24/2007 09:38 PM 717,252 gen_dark_rusted01_local.tga.rust_001_local.tga -02/24/2007 09:38 PM 500,493 gen_dark_rusted01_s.tga.rust_001_s.tga -02/24/2007 09:38 PM 564,102 gen_default_framed_d.tga -02/24/2007 09:38 PM 8,236 gen_default_framed_local.tga -02/24/2007 09:38 PM 242,089 gen_default_framed_s.tga -02/24/2007 09:38 PM 646,312 gen_ornate_iron01.tga.iron_002_d.tga -02/24/2007 09:38 PM 692,620 gen_peeling_paint01.tga.paintedmetal_001_d.tga -02/24/2007 09:38 PM 684,534 gen_peeling_paint01_local.tga.paintedmetal_001_local.tga -02/24/2007 09:38 PM 470,097 gen_peeling_paint01_s.tga.paintedmetal_001_s.tga -02/24/2007 09:38 PM 524,939 gen_shiny_brushedmetal01.tga.brushedmetal_001_d.tga -02/24/2007 09:38 PM 695,750 gen_shiny_brushedmetal01_local.tga.brushedmetal_001_local.tga -02/24/2007 09:38 PM 368,931 gen_shiny_brushedmetal01_s.tga.brushedmetal_001_s.tga -05/10/2007 09:33 PM 786,476 gen_smooth_bronze01.tga.bronze_001_d.tga -02/24/2007 09:38 PM 361,498 gen_smooth_bronze01_local.tga.bronze_001_local.tga -02/24/2007 09:38 PM 114,580 gen_smooth_bronze01_s.tga.bronze_001_s.tga -02/24/2007 09:38 PM 220,395 gen_smooth_copper01.tga.copper_001_d.tga -02/24/2007 09:38 PM 606,726 gen_smooth_copper01_local.tga.copper_001_local.tga -02/24/2007 09:38 PM 392,118 gen_smooth_copper01_s.tga.copper_001_s.tga -02/24/2007 09:38 PM 716,365 gen_smooth_gold01.tga.gold_001_d.tga -02/24/2007 09:38 PM 8,236 gen_smooth_gold01_local.tga.gold_001_local.tga -02/24/2007 09:38 PM 565,217 gen_smooth_gold01_s.tga.gold_001_s.tga -02/24/2007 09:38 PM 512,858 gen_smooth_iron01.tga.iron_001_d.tga -02/24/2007 09:38 PM 756,144 gen_smooth_iron01_local.tga.iron_001_local.tga -02/24/2007 09:38 PM 513,754 gen_smooth_iron01_s.tga.iron_001_s.tga -02/24/2007 09:38 PM 570,766 gen_smooth_silver01.tga.silver_001_d.tga -02/24/2007 09:38 PM 8,236 gen_smooth_silver01_local.tga.silver_001_local.tga -02/24/2007 09:38 PM 491,194 gen_smooth_silver01_s.tga.silver_001_s.tga -02/25/2007 01:30 AM 349,672 rough_dirty01.dds.cement_012.dds -02/24/2007 08:20 PM 394,128 rough_dirty01_ed.tga.cement_012_editor.tga -02/24/2007 08:20 PM 1,576,194 rough_dirty01_local.tga.cement_012_local.tga -02/25/2007 01:30 AM 349,672 rough_iron01.dds.cement_014.dds -02/24/2007 08:20 PM 1,537,807 rough_iron01_ed.tga.cement_014_editor.tga -02/24/2007 08:20 PM 1,576,335 rough_iron01_local.tga.cement_014_local.tga -02/25/2007 01:30 AM 349,672 rough_rusted01.dds.cement_011.dds -02/24/2007 08:20 PM 394,199 rough_rusted01_ed.tga.cement_011_editor.tga -02/24/2007 08:20 PM 1,574,147 rough_rusted01_local.tga.cement_011_local.tga -02/25/2007 01:30 AM 349,672 rough_rusted01_s.dds.cement_011_s.dds - 38 File(s) 21,907,532 bytes - - Directory of D:\temp2\textures\darkmod\metal\grate - -06/01/2007 07:57 PM . -06/01/2007 07:57 PM .. -04/15/2007 04:11 PM 699,192 dimpled_grating01.dds.grating_001.dds -04/15/2007 04:09 PM 23,060 dimpled_grating01_ed.jpg.grating_001_editor.jpg -04/15/2007 04:09 PM 3,145,772 dimpled_grating01_local.tga.grating_001_local.tga -04/15/2007 04:11 PM 43,832 dimpled_grating01_s.dds.grating_001_s.dds -04/23/2007 07:52 PM nontiling -04/23/2007 07:50 PM tiling_1d - 4 File(s) 3,911,856 bytes - - Directory of D:\temp2\textures\darkmod\metal\grate\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\metal\grate\tiling_1d - -04/23/2007 07:50 PM . -04/23/2007 07:50 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature - -04/23/2007 08:03 PM . -04/23/2007 08:03 PM .. -05/12/2007 11:33 AM dirt -05/12/2007 11:33 AM foliage -05/12/2007 11:41 AM grass -05/05/2007 07:26 PM skybox -06/01/2007 07:58 PM snow -04/23/2007 07:44 PM water - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\dirt - -05/12/2007 11:33 AM . -05/12/2007 11:33 AM .. -04/23/2007 07:52 PM nontiling -04/23/2007 07:51 PM tiling_1d - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\dirt\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\dirt\tiling_1d - -04/23/2007 07:51 PM . -04/23/2007 07:51 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\foliage - -05/12/2007 11:33 AM . -05/12/2007 11:33 AM .. -05/12/2007 11:25 AM 1,572,908 flowers_pink_01.tga -05/12/2007 11:26 AM 1,572,908 flowers_pink_01_local.tga -05/12/2007 11:28 AM 1,572,908 flowers_violet_01.tga -05/12/2007 11:28 AM 1,572,908 flowers_violet_01_local.tga -05/12/2007 11:30 AM 786,476 flowers_violet_02.tga -05/12/2007 11:30 AM 786,476 flowers_violet_02_local.tga -02/25/2007 01:14 AM 174,904 hedge_001.dds -02/24/2007 10:12 PM 262,640 hedge_001_editor.tga -02/25/2007 01:14 AM 349,680 hedge_001_local.dds -02/24/2007 10:12 PM 788,471 hedge_001_local.tga -05/12/2007 11:32 AM nontiling -04/23/2007 07:51 PM tiling_1d - 10 File(s) 9,440,279 bytes - - Directory of D:\temp2\textures\darkmod\nature\foliage\nontiling - -05/12/2007 11:32 AM . -05/12/2007 11:32 AM .. -05/12/2007 11:21 AM 1,572,908 flowers_blueviolet_01.tga -05/12/2007 11:21 AM 1,572,908 flowers_blueviolet_01_local.tga -05/12/2007 11:22 AM 1,572,908 flowers_mixed_01.tga -05/12/2007 11:22 AM 1,572,908 flowers_mixed_01_local.tga -05/12/2007 11:27 AM 196,652 flowers_redyellow_01.tga -05/12/2007 11:27 AM 196,652 flowers_redyellow_01_local.tga -02/24/2007 10:24 PM 197,659 flowers_red_01.tga -02/24/2007 10:24 PM 197,093 flowers_red_01_local.tga -05/12/2007 11:31 AM 786,476 flowers_white_01.tga -05/12/2007 11:32 AM 786,476 flowers_white_01_local.tga - 10 File(s) 8,652,640 bytes - - Directory of D:\temp2\textures\darkmod\nature\foliage\tiling_1d - -04/23/2007 07:51 PM . -04/23/2007 07:51 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\grass - -05/12/2007 11:41 AM . -05/12/2007 11:41 AM .. -05/12/2007 11:41 AM nontiling -02/24/2007 09:29 PM 1,049,115 short_patchy_grass01.tga.grass01.tga -02/24/2007 09:29 PM 1,049,115 short_patchy_grass01_local.tga.grass01_local.tga -02/24/2007 09:29 PM 788,991 thick_grass01.tga.grass02.tga -02/24/2007 09:29 PM 789,019 thick_grass01_local.tga.grass02_local.tga -04/23/2007 07:51 PM tiling_1d - 4 File(s) 3,676,240 bytes - - Directory of D:\temp2\textures\darkmod\nature\grass\nontiling - -05/12/2007 11:41 AM . -05/12/2007 11:41 AM .. -05/12/2007 11:40 AM 1,572,908 thick_straw01.tga.straw01.tga -05/12/2007 11:40 AM 1,572,908 thick_straw01_local.tga.straw01_local.tga - 2 File(s) 3,145,816 bytes - - Directory of D:\temp2\textures\darkmod\nature\grass\tiling_1d - -04/23/2007 07:51 PM . -04/23/2007 07:51 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -05/05/2007 07:26 PM dm_sqsky -05/05/2007 07:26 PM starry1 - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:11 PM 196,652 dm_sqsky.tga - 1 File(s) 196,652 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn - -02/24/2007 10:11 PM 232 all-wcprops -05/04/2007 06:48 PM 403 entries -02/24/2007 10:11 PM 2 format -05/05/2007 07:26 PM prop-base -05/05/2007 07:26 PM props -05/05/2007 07:26 PM text-base -05/05/2007 07:26 PM tmp - 3 File(s) 637 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\prop-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:11 PM 53 dm_sqsky.tga.svn-base - 1 File(s) 53 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\props - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\text-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:11 PM 196,652 dm_sqsky.tga.svn-base - 1 File(s) 196,652 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\tmp - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -05/05/2007 07:26 PM prop-base -05/05/2007 07:26 PM props -05/05/2007 07:26 PM text-base - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\tmp\prop-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\tmp\props - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\dm_sqsky\.svn\tmp\text-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1 - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:11 PM 2,896,280 clouds.tga -02/24/2007 10:11 PM 1,048,620 clouds2.tga -02/24/2007 10:11 PM 121,556 moon.tga -02/24/2007 10:11 PM 262,188 moon_crescent.tga -02/24/2007 10:11 PM 16,428 moon_crescent_editor.tga -02/24/2007 10:11 PM 49,691 moon_editor.tga -02/24/2007 10:11 PM 262,683 moon_full.tga -02/24/2007 10:11 PM 16,428 moon_full_editor.tga -02/24/2007 10:11 PM 176,388 moon_full_glared.tga -02/24/2007 10:11 PM 262,683 moon_gibbous.tga -02/24/2007 10:11 PM 49,196 moon_gibbous_editor.tga -02/24/2007 10:11 PM 262,683 moon_quarter.tga -02/24/2007 10:11 PM 16,428 moon_quarter_editor.tga -02/24/2007 10:11 PM 4,109,358 stars.tga -02/24/2007 10:11 PM 48 white.tga - 15 File(s) 9,550,658 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn - -02/24/2007 10:11 PM 2,126 all-wcprops -05/04/2007 06:48 PM 2,418 entries -02/24/2007 10:09 PM 2 format -05/05/2007 07:26 PM prop-base -05/05/2007 07:26 PM props -05/05/2007 07:26 PM text-base -05/05/2007 07:26 PM tmp - 3 File(s) 4,546 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\prop-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:09 PM 53 clouds.tga.svn-base -02/24/2007 10:10 PM 53 clouds2.tga.svn-base -02/24/2007 10:09 PM 53 moon.tga.svn-base -02/24/2007 10:11 PM 53 moon_crescent.tga.svn-base -02/24/2007 10:11 PM 53 moon_crescent_editor.tga.svn-base -02/24/2007 10:11 PM 53 moon_editor.tga.svn-base -02/24/2007 10:10 PM 53 moon_full.tga.svn-base -02/24/2007 10:11 PM 53 moon_full_editor.tga.svn-base -02/24/2007 10:09 PM 53 moon_full_glared.tga.svn-base -02/24/2007 10:11 PM 53 moon_gibbous.tga.svn-base -02/24/2007 10:09 PM 53 moon_gibbous_editor.tga.svn-base -02/24/2007 10:10 PM 53 moon_quarter.tga.svn-base -02/24/2007 10:11 PM 53 moon_quarter_editor.tga.svn-base -02/24/2007 10:11 PM 53 stars.tga.svn-base -02/24/2007 10:11 PM 53 white.tga.svn-base - 15 File(s) 795 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\props - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\text-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -02/24/2007 10:09 PM 2,896,280 clouds.tga.svn-base -02/24/2007 10:10 PM 1,048,620 clouds2.tga.svn-base -02/24/2007 10:09 PM 121,556 moon.tga.svn-base -02/24/2007 10:11 PM 262,188 moon_crescent.tga.svn-base -02/24/2007 10:11 PM 16,428 moon_crescent_editor.tga.svn-base -02/24/2007 10:11 PM 49,691 moon_editor.tga.svn-base -02/24/2007 10:10 PM 262,683 moon_full.tga.svn-base -02/24/2007 10:11 PM 16,428 moon_full_editor.tga.svn-base -02/24/2007 10:09 PM 176,388 moon_full_glared.tga.svn-base -02/24/2007 10:11 PM 262,683 moon_gibbous.tga.svn-base -02/24/2007 10:09 PM 49,196 moon_gibbous_editor.tga.svn-base -02/24/2007 10:10 PM 262,683 moon_quarter.tga.svn-base -02/24/2007 10:11 PM 16,428 moon_quarter_editor.tga.svn-base -02/24/2007 10:11 PM 4,109,358 stars.tga.svn-base -02/24/2007 10:11 PM 48 white.tga.svn-base - 15 File(s) 9,550,658 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\tmp - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. -05/05/2007 07:26 PM prop-base -05/05/2007 07:26 PM props -05/05/2007 07:26 PM text-base - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\tmp\prop-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\tmp\props - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\skybox\starry1\.svn\tmp\text-base - -05/05/2007 07:26 PM . -05/05/2007 07:26 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\snow - -06/01/2007 07:58 PM . -06/01/2007 07:58 PM .. -04/23/2007 07:52 PM nontiling -02/25/2007 01:15 AM 174,904 plain_ice01.dds.icy_001.dds -02/24/2007 07:47 PM 196,652 plain_ice01_ed.tga.icy_001_editor.tga -02/24/2007 07:47 PM 786,476 plain_ice01_local.tga.icy_001_local.tga -02/25/2007 01:15 AM 174,904 plain_ice01_s.dds.icy_001_s.dds -02/25/2007 01:15 AM 699,192 plain_snow01.dds.rippled_001.dds -02/24/2007 07:47 PM 3,145,772 plain_snow01_local.tga.rippled_001_local.tga -04/23/2007 07:51 PM tiling_1d - 6 File(s) 5,177,900 bytes - - Directory of D:\temp2\textures\darkmod\nature\snow\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\snow\tiling_1d - -04/23/2007 07:51 PM . -04/23/2007 07:51 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\nature\water - -04/23/2007 07:44 PM . -04/23/2007 07:44 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\paint_paper - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. -05/26/2007 11:48 AM nontiling -05/26/2007 11:48 AM tiling_1d -02/24/2007 09:54 PM 786,450 wallpaper_flowers_01.tga.manwall03.tga -02/24/2007 09:54 PM 786,476 wallpaper_flowers_01_local.tga.manwall03_local.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_01_blue.tga.manwall04b.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_01_green.tga.manwall04c.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_01_local.tga.manwall04_local.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_01_pink.tga.manwall04a.tga -05/18/2007 10:26 PM 786,476 wallpaper_ornamental_01_red.tga.manwall04d.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_02_white.tga.manwall05.tga -02/24/2007 09:54 PM 786,476 wallpaper_ornamental_02_white_local.tga.manwall05_local.tga - 9 File(s) 7,078,258 bytes - - Directory of D:\temp2\textures\darkmod\paint_paper\nontiling - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\paint_paper\tiling_1d - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\roof - -05/01/2007 07:32 PM . -05/01/2007 07:32 PM .. -04/23/2007 07:52 PM nontiling -02/24/2007 10:57 PM 1,011,879 shingle_dullbrown01.tga.ctyroof02.tga -02/24/2007 10:57 PM 1,046,020 shingle_dullbrown01_local.tga.ctyroof02_local.tga -02/24/2007 10:57 PM 393,260 shingle_shiny_greenish01.tga.rooftile_01_d.tga -02/24/2007 10:57 PM 393,260 shingle_shiny_greenish01_local.tga.rooftile_01_local.tga -02/24/2007 10:57 PM 393,260 shingle_shiny_greenish01_s.tga.rooftile_01_s.tga -02/24/2007 10:57 PM 786,476 slate_uneven_withmoss01.tga.ctyroof01.tga -02/24/2007 10:57 PM 786,476 slate_uneven_withmoss01_local.tga.ctyroof01_local.tga -02/24/2007 10:57 PM 392,764 slats_uneven_wood01.tga.rt_woodenrooftiles01_d.tga -02/24/2007 10:57 PM 392,099 slats_uneven_wood01_local.tga.rt_woodenrooftiles01_local.tga -04/23/2007 07:51 PM tiling_1d - 9 File(s) 5,595,494 bytes - - Directory of D:\temp2\textures\darkmod\roof\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\roof\tiling_1d - -04/23/2007 07:51 PM . -04/23/2007 07:51 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\sfx - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. -02/24/2007 09:29 PM 64,021 blueglass.tga -02/24/2007 09:29 PM 63,499 greenglass.tga -02/24/2007 09:29 PM 25,115 light_rays.tga -02/24/2007 09:29 PM 376,983 mandoor05_local.tga -02/24/2007 09:29 PM 80,446 mandoor05_withalpha.tga -02/24/2007 09:29 PM 524,753 manwindow02b_withalpha.tga -02/24/2007 09:29 PM 66,025 redglass.tga -02/24/2007 09:29 PM 65,190 whiteglass.tga - 8 File(s) 1,266,032 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn - -02/24/2007 09:29 PM 1,128 all-wcprops -05/04/2007 06:48 PM 1,356 entries -02/24/2007 09:29 PM 2 format -05/05/2007 07:25 PM prop-base -05/05/2007 07:25 PM props -05/05/2007 07:25 PM text-base -05/05/2007 07:25 PM tmp - 3 File(s) 2,486 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\prop-base - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. -02/24/2007 09:29 PM 53 blueglass.tga.svn-base -02/24/2007 09:29 PM 53 greenglass.tga.svn-base -02/24/2007 09:29 PM 53 light_rays.tga.svn-base -02/24/2007 09:29 PM 53 mandoor05_local.tga.svn-base -02/24/2007 09:29 PM 53 mandoor05_withalpha.tga.svn-base -02/24/2007 09:29 PM 53 manwindow02b_withalpha.tga.svn-base -02/24/2007 09:29 PM 53 redglass.tga.svn-base -02/24/2007 09:29 PM 53 whiteglass.tga.svn-base - 8 File(s) 424 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\props - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\text-base - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. -02/24/2007 09:29 PM 64,021 blueglass.tga.svn-base -02/24/2007 09:29 PM 63,499 greenglass.tga.svn-base -02/24/2007 09:29 PM 25,115 light_rays.tga.svn-base -02/24/2007 09:29 PM 376,983 mandoor05_local.tga.svn-base -02/24/2007 09:29 PM 80,446 mandoor05_withalpha.tga.svn-base -02/24/2007 09:29 PM 524,753 manwindow02b_withalpha.tga.svn-base -02/24/2007 09:29 PM 66,025 redglass.tga.svn-base -02/24/2007 09:29 PM 65,190 whiteglass.tga.svn-base - 8 File(s) 1,266,032 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\tmp - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. -05/05/2007 07:25 PM prop-base -05/05/2007 07:25 PM props -05/05/2007 07:25 PM text-base - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\tmp\prop-base - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\tmp\props - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\sfx\.svn\tmp\text-base - -05/05/2007 07:25 PM . -05/05/2007 07:25 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone - -05/31/2007 08:20 PM . -05/31/2007 08:20 PM .. -05/24/2007 07:46 PM brick -06/01/2007 08:01 PM cobblestones -05/29/2007 07:52 PM flat -05/31/2007 08:21 PM natural -05/25/2007 08:21 PM sculpted - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone\brick - -05/24/2007 07:46 PM . -05/24/2007 07:46 PM .. -02/25/2007 01:56 AM 699,192 even_greyish01.dds.brick_006.dds -02/24/2007 09:05 PM 262,513 even_greyish01_ed.tga.brick_006_editor.tga -02/24/2007 09:05 PM 3,029,510 even_greyish01_local.tga.brick_006_local.tga -02/25/2007 01:56 AM 174,920 even_greyish01_trim.dds.brick_006_trim.dds -02/24/2007 09:05 PM 5,531 even_greyish01_trim_ed.jpg.brick_006_trim_editor.jpg -02/24/2007 09:05 PM 786,476 even_greyish01_trim_local.tga.brick_006_trim_local.tga -04/15/2007 04:06 PM 24,838 even_small_blocks001_ed.jpg.blocks_019_editor.jpg -04/15/2007 04:06 PM 3,145,772 even_small_blocks001_local.tga.blocks_019_local.tga -04/15/2007 04:11 PM 699,192 even_small_blocks01.dds.blocks_019.dds -02/24/2007 10:47 PM 788,308 grainy_blocks01.tga.rt_largebrick01_d.tga -02/24/2007 10:47 PM 787,850 grainy_blocks01_local.tga.rt_largebrick01_local.tga -02/25/2007 01:56 AM 174,904 grainy_large_blocks01.dds.blocks_017_d.DDS -02/24/2007 09:05 PM 197,007 grainy_large_blocks01_ed.tga.blocks_017_ed.tga -02/24/2007 09:05 PM 788,015 grainy_large_blocks01_local.tga.blocks_017_local.tga -02/24/2007 09:54 PM 392,320 grey_protruding_bricks.tga.manwbrick02.tga -02/24/2007 09:54 PM 391,889 grey_protruding_bricks_local.tga.manwbrick02_local.tga -02/25/2007 01:56 AM 174,904 interlocking_angled_darkgrey.dds.brick_007_dark.dds -02/25/2007 01:56 AM 174,904 interlocking_angled_grey.dds.brick_007.dds -02/25/2007 01:56 AM 174,904 interlocking_angled_grey01_s.dds.brick_007_s.dds -02/24/2007 09:05 PM 196,579 interlocking_angled_grey_ed.tga.brick_007_editor.tga -02/24/2007 09:05 PM 788,417 interlocking_angled_grey_local.tga.brick_007_local.tga -02/25/2007 01:56 AM 174,904 interlocking_angled_yellow.dds.brick_007_yellow.dds -02/25/2007 01:56 AM 174,904 interlocking_mixedsize_dark.dds.cobble_005.dds -02/24/2007 09:05 PM 786,476 interlocking_mixedsize_dark.tga.cobble_005_local.tga -02/24/2007 09:05 PM 197,147 interlocking_mixedsize_dark_ed.tga.cobble_005_editor.tga -05/18/2007 07:51 PM nontiling -02/25/2007 01:56 AM 174,904 old_blocks_wornsmooth_dark.dds.brick_010_d.DDS -02/24/2007 09:05 PM 196,640 old_blocks_wornsmooth_dark_ed.tga.brick_010_ed.tga -02/24/2007 09:05 PM 786,476 old_blocks_wornsmooth_dark_local.tga.brick_010_local.tga -04/16/2007 07:47 PM 349,672 old_dirty_bricks01.dds.brick_old_003.dds -04/28/2007 06:10 PM 393,555 old_dirty_bricks01_ed.tga.brick_old_003_editor.tga -04/16/2007 07:47 PM 699,216 old_dirty_bricks01_local.dds.brick_old_003_local.dds -04/16/2007 07:47 PM 1,576,359 old_dirty_bricks01_local.tga.brick_old_003_local.tga -02/25/2007 01:30 AM 174,904 old_small_bricks_grey.dds.brick_old_001.dds -02/24/2007 08:20 PM 787,459 old_small_bricks_grey.tga.brick_old_001_local.tga -02/24/2007 08:20 PM 196,647 old_small_bricks_grey_ed.tga.brick_old_001_editor.tga -02/25/2007 01:56 AM 174,920 pillar_bricks01.dds.masonry_001_pillar.dds -02/24/2007 09:05 PM 5,506 pillar_bricks01_ed.jpg.masonry_001_pillar_editor.jpg -02/24/2007 09:05 PM 1,048,620 pillar_bricks01_local.tga.masonry_001_pillar_local.tga -02/25/2007 01:56 AM 43,848 pillar_bricks01_s.dds.masonry_001_pillar_s.dds -02/24/2007 10:47 PM 1,167,855 redbrick_dull_small.tga.rt_redbrickvert01_d.tga -02/24/2007 10:47 PM 1,182,405 redbrick_dull_small_local.tga.rt_redbrickvert01_local.tga -02/25/2007 01:56 AM 524,440 redbrick_mostly_mortar.dds.brick_008.dds -02/24/2007 09:05 PM 197,147 redbrick_mostly_mortar_ed.tga.brick_008_editor.tga -05/13/2007 03:45 PM 1,572,908 redbrick_mostly_mortar_local.tga.brick_008_local.tga -02/25/2007 01:56 AM 174,904 red_angled_ground.dds.brick_004.dds -02/24/2007 09:05 PM 49,291 red_angled_ground_ed.tga.brick_004_editor.tga -02/24/2007 09:05 PM 786,476 red_angled_ground_local.tga.brick_004_local.tga -02/24/2007 10:47 PM 786,476 red_brick_dull01.tga.ctywbrick02.tga -02/24/2007 10:47 PM 786,476 red_brick_dull01_local.tga.ctywbrick02_local.tga -02/25/2007 01:56 AM 174,904 red_sloppymortar.dds.brick_005.dds -02/25/2007 01:56 AM 43,832 red_sloppymortar_alpha.dds.brick_005_alpha.dds -02/24/2007 09:05 PM 197,029 red_sloppymortar_ed.tga.brick_005_editor.tga -02/24/2007 09:05 PM 788,317 red_sloppymortar_inverted_local.tga.brick_005_inverted_local.tga -02/24/2007 09:05 PM 786,476 red_sloppymortar_local.tga.brick_005_local.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks01.dds.blocks_008.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks01_ed.tga.blocks_008_editor.tga -02/24/2007 09:05 PM 3,145,772 rough_big_blocks01_local.tga.blocks_008_local.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks02.dds.blocks_009.dds -02/25/2007 01:56 AM 699,192 rough_big_blocks02_cornerstone_dark.dds.blocks_009_cornerstone_dark.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks02_cornerstone_dark_ed.tga.blocks_009_cornerstone_dark_editor.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks02_cornerstone_light.dds.blocks_009_cornerstone_light.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks02_cornerstone_light_ed.tga.blocks_009_cornerstone_light_editor.tga -02/24/2007 09:05 PM 3,145,772 rough_big_blocks02_cornerstone_local.tga.blocks_009_cornerstone_local.tga -02/24/2007 09:05 PM 197,147 rough_big_blocks02_ed.tga.blocks_009_editor.tga -02/24/2007 09:05 PM 3,145,772 rough_big_blocks02_local.tga.blocks_009_local.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks03.dds.blocks_010.dds -02/25/2007 01:56 AM 699,192 rough_big_blocks03_cornerstone_dark.dds.blocks_010_cornerstone_dark.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks03_cornerstone_dark_ed.tga.blocks_010_cornerstone_dark_editor.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks03_cornerstone_light.dds.blocks_010_cornerstone_light.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks03_cornerstone_light_ed.tga.blocks_010_cornerstone_light_editor.tga -02/24/2007 09:05 PM 197,147 rough_big_blocks03_ed.tga.blocks_010_editor.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks04_brown.dds.blocks_013.dds -02/25/2007 01:56 AM 699,192 rough_big_blocks04_brown_cornerstone_light.dds.blocks_013_cornerstone_light.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks04_brown_cornerstone_light_ed.tga.blocks_013_cornerstone_light_editor.tga -02/24/2007 09:05 PM 197,147 rough_big_blocks04_brown_ed.tga.blocks_013_editor.tga -02/25/2007 01:56 AM 699,192 rough_big_blocks05.dds.blocks_014.dds -02/24/2007 09:05 PM 197,147 rough_big_blocks05_ed.tga.blocks_014_editor.tga -02/25/2007 01:56 AM 1,398,248 rough_blocks01.dds.brick_009_d.DDS -02/24/2007 09:05 PM 98,348 rough_blocks01_ed.tga.brick_009_ed.tga -02/24/2007 09:05 PM 1,572,908 rough_blocks01_local.tga.brick_009_local.tga -02/24/2007 10:47 PM 786,476 rough_blocks02.tga.ctywbrick01.tga -02/24/2007 10:47 PM 786,476 rough_blocks02_local.tga.ctywbrick01_local.tga -02/24/2007 10:47 PM 786,476 rough_blocks_tight02.tga.ctywbrick04.tga -02/24/2007 10:47 PM 786,476 rough_blocks_tight02_local.tga.ctywbrick04_local.tga -02/24/2007 10:47 PM 786,476 rough_blocks_tight02_moss.tga.ctywbrick04b.tga -02/24/2007 10:47 PM 786,476 rough_blocks_tight02_moss_local.tga.ctywbrick04b_local.tga -02/24/2007 10:47 PM 786,909 rough_blocks_tight_dark.tga.ctywbrick03b.tga -02/24/2007 10:47 PM 788,217 rough_blocks_tight_light.tga.ctywbrick03.tga -02/24/2007 10:47 PM 786,476 rough_blocks_tight_local.tga.ctywbrick03_local.tga -02/24/2007 10:47 PM 786,476 rough_brick_grey.tga.brick_dark_d.tga -02/24/2007 10:47 PM 786,476 rough_brick_grey_local.tga.brick_dark_local.tga -05/14/2007 07:32 PM 196,652 rough_brick_grey_s.tga.brick_dark_s.tga -02/25/2007 01:59 AM 174,920 single_grey_block01.dds.trim_003_d.DDS -02/24/2007 09:19 PM 190,232 single_grey_block01_ed.tga.trim_003_ed.tga -02/24/2007 09:19 PM 787,053 single_grey_block01_local.tga.trim_003_local.tga -02/25/2007 01:56 AM 699,192 small_brown_bricks01.dds.masonry_001_brick.dds -02/25/2007 01:56 AM 174,904 small_brown_bricks01.dds.masonry_001_brick_s.dds -02/24/2007 09:05 PM 22,761 small_brown_bricks01_ed.jpg.masonry_001_brick_editor.jpg -02/24/2007 09:05 PM 3,145,772 small_brown_bricks01_local.tga.masonry_001_brick_local.tga -02/24/2007 09:54 PM 786,476 tight_large_blocks.tga.manwbrick01.tga -02/25/2007 01:56 AM 699,192 tight_large_blocks01.dds.blocks_015_d.DDS -02/24/2007 09:05 PM 196,652 tight_large_blocks01_ed.tga.blocks_015_ed.tga -02/24/2007 09:05 PM 3,145,772 tight_large_blocks01_local.tga.blocks_015_local.tga -02/25/2007 01:56 AM 174,904 tight_large_blocks01_s.dds.blocks_015_s.DDS -02/24/2007 09:54 PM 786,476 tight_large_blocks_local.tga.manwbrick01_local.tga -02/25/2007 01:56 AM 699,192 tight_large_singleblock01.dds.blocks_016_d.DDS -02/24/2007 09:05 PM 194,303 tight_large_singleblock01_ed.tga.blocks_016_ed.tga -02/24/2007 09:05 PM 3,145,772 tight_large_singleblock01_local.tga.blocks_016_local.tga -02/24/2007 10:47 PM 393,190 tight_randomsize_blocks.tga.rt_sizes01_d.tga -02/24/2007 10:47 PM 393,857 tight_randomsize_blocks_local.tga.rt_sizes01_local.tga -05/21/2007 12:50 PM tiling_1d - 110 File(s) 77,149,930 bytes - - Directory of D:\temp2\textures\darkmod\stone\brick\nontiling - -05/18/2007 07:51 PM . -05/18/2007 07:51 PM .. -02/24/2007 10:47 PM 3,108,726 chiseled_brick_frame.tga.rt_framedwall01_d.tga -02/24/2007 10:47 PM 3,134,629 chiseled_brick_frame_local.tga.rt_framedwall01_local.tga - 2 File(s) 6,243,355 bytes - - Directory of D:\temp2\textures\darkmod\stone\brick\tiling_1d - -05/21/2007 12:50 PM . -05/21/2007 12:50 PM .. -02/24/2007 09:07 PM 783,058 gen_plainbrick_grey.tga.brick_001_d.tga -02/24/2007 09:07 PM 767,607 gen_plainbrick_local.tga.brick_001_local.tga -02/24/2007 09:07 PM 650,394 gen_plainbrick_s.tga.brick_001_s.tga -02/25/2007 01:30 AM 349,672 old_worn_greybrick.dds.brick_old_002.dds -02/24/2007 08:20 PM 393,603 old_worn_greybrick_ed.tga.brick_old_002_editor.tga -02/24/2007 08:20 PM 1,574,232 old_worn_greybrick_local.tga.brick_old_002_local.tga - 6 File(s) 4,518,566 bytes - - Directory of D:\temp2\textures\darkmod\stone\cobblestones - -06/01/2007 08:01 PM . -06/01/2007 08:01 PM .. -02/25/2007 01:30 AM 524,440 blocks_mixedsize01.dds.masonry_005.dds -02/24/2007 08:20 PM 147,995 blocks_mixedsize01_ed.tga.masonry_005_editor.tga -02/24/2007 08:20 PM 2,359,340 blocks_mixedsize01_local.tga.masonry_005_local.tga -02/24/2007 11:12 PM 787,453 blocks_mixed_multicolour.tga.rt_casstone02_d.tga -02/24/2007 11:12 PM 393,805 blocks_mixed_multicolour_framed.tga.rt_casstone01_d.tga -02/24/2007 11:12 PM 391,826 blocks_mixed_multicolour_framed_local.tga.rt_casstone01_local.tga -02/24/2007 11:12 PM 786,028 blocks_mixed_multicolour_local.tga.rt_casstone02_local.tga -02/25/2007 01:56 AM 174,904 cobblestones01_light.dds.cobble_004.dds -02/24/2007 09:05 PM 49,298 cobblestones01_square_light_ed.tga.cobble_004_editor.tga -02/24/2007 09:05 PM 786,476 cobblestones01_square_light_local.tga.cobble_004_local.tga -02/25/2007 01:56 AM 174,904 cobblestones01_square_light_s.dds.cobble_004_s.dds -02/25/2007 01:56 AM 174,904 cobblestones02_square_dark.dds.cobble_008.dds -02/24/2007 09:05 PM 25,232 cobblestones02_square_dark.jpg.cobble_008_editor.jpg -02/24/2007 09:05 PM 786,476 cobblestones02_square_dark_local.tga.cobble_008_local.tga -02/25/2007 01:56 AM 43,832 cobblestones02_square_dark_s.dds.cobble_008_s.dds -02/24/2007 10:53 PM 786,476 cobblestones03_dark.tga.ctyground01.tga -02/24/2007 10:53 PM 786,476 cobblestones03_dark_local.tga.ctyground01_local.tga -02/24/2007 10:53 PM 786,476 cobblestones04_multicolour.tga.ctyground02.tga -02/24/2007 10:53 PM 786,085 cobblestones04_multicolour_local.tga.ctyground02_local.tga -02/24/2007 07:50 PM 787,433 cobblestones_loose_ongrass.tga.pagfloor03.tga -02/24/2007 07:50 PM 787,276 cobblestones_loose_ongrass_local.tga.pagfloor03_local.tga -02/25/2007 01:56 AM 87,528 cobblestone_fan_pattern.dds.fan_001_dirt.dds -02/24/2007 09:05 PM 98,535 cobblestone_fan_pattern_ed.tga.fan_001_dirt_editor.tga -02/25/2007 01:56 AM 87,528 cobblestone_fan_pattern_grass.dds.fan_001_grass.dds -02/24/2007 09:05 PM 98,524 cobblestone_fan_pattern_grass_ed.tga.fan_001_grass_editor.tga -02/24/2007 09:05 PM 394,241 cobblestone_fan_pattern_local.tga.fan_001_local.tga -02/25/2007 01:56 AM 87,528 cobblestone_fan_pattern_s.dds.fan_001_s.dds -02/25/2007 01:56 AM 699,192 flagstones01_light.dds.masonry_001.dds -02/24/2007 09:05 PM 3,145,772 flagstones01_light_local.tga.masonry_001_local.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain.tga.blocks_018.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_cornerstone_left.tga.blocks_018_cornerstone_l.tga -03/18/2007 03:20 PM 10,523 flagstones02_plain_cornerstone_left_ed.jpg.blocks_018_cornerstone_l_ed.jpg -03/18/2007 03:20 PM 10,496 flagstones02_plain_cornerstone_left_ed.jpg.blocks_018_cornerstone_r_ed.jpg -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_cornerstone_left_local.tga.blocks_018_cornerstone_l_local.tga -03/18/2007 03:20 PM 393,755 flagstones02_plain_cornerstone_left_s.tga.blocks_018_cornerstone_l_s.tga -03/18/2007 03:20 PM 393,755 flagstones02_plain_cornerstone_left_s.tga.blocks_018_cornerstone_r_s.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_cornerstone_right.tga.blocks_018_cornerstone_r.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_cornerstone_right_local.tga.blocks_018_cornerstone_r_local.tga -03/18/2007 03:20 PM 10,406 flagstones02_plain_ed.jpg.blocks_018_ed.jpg -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_local.tga.blocks_018_local.tga -03/18/2007 03:20 PM 393,755 flagstones02_plain_s.tga.blocks_018_s.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_window01.tga.blocks_018_window01.tga -03/18/2007 03:20 PM 10,156 flagstones02_plain_window01_ed.jpg.blocks_018_window01_ed.jpg -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_window01_local.tga.blocks_018_window01_local.tga -03/18/2007 03:20 PM 393,755 flagstones02_plain_window01_s.tga.blocks_018_window01_s.tga -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_window02.tga.blocks_018_window02.tga -03/18/2007 03:20 PM 10,493 flagstones02_plain_window02_ed.jpg.blocks_018_window02_ed.jpg -03/18/2007 03:20 PM 1,572,908 flagstones02_plain_window02_local.tga.blocks_018_window02_local.tga -03/18/2007 03:20 PM 393,755 flagstones02_plain_window02_s.tga.blocks_018_window02_s.tga -02/25/2007 01:56 AM 699,192 flagstones03_shiny.dds.cobble_006.dds -02/24/2007 09:05 PM 197,151 flagstones03_shiny_ed.tga.cobble_006_editor.tga -02/24/2007 09:05 PM 3,153,369 flagstones03_shiny_local.tga.cobble_006_local.tga -02/25/2007 01:56 AM 699,192 flagstones03_shiny_s.dds.cobble_006_s.dds -02/25/2007 01:56 AM 174,904 flagstones04_uneven.dds.cobble_007.dds -02/24/2007 09:05 PM 197,156 flagstones04_uneven_ed.tga.cobble_007_editor.tga -02/24/2007 09:05 PM 788,490 flagstones04_uneven_local.tga.cobble_007_local.tga -02/24/2007 10:53 PM 779,507 flagstones05_pinkish.tga.cobblestone01sh.tga -02/24/2007 10:53 PM 780,887 flagstones05_pinkish_local.tga.cobblestone01sh_local.tga -02/24/2007 10:53 PM 86,306 flagstones05_pinkish_s.tga.cobblestone01sh_s.tga -02/25/2007 01:56 AM 699,192 flagstones06_granite.dds.granite_001.dds -02/24/2007 09:05 PM 197,044 flagstones06_granite_ed.tga.granite_001_editor.tga -02/24/2007 09:05 PM 3,145,772 flagstones06_granite_local.tga.granite_001_local.tga -02/25/2007 01:56 AM 699,192 flagstones06_granite_s.dds.granite_001_s.dds -05/30/2007 07:48 PM nontiling -02/25/2007 01:30 AM 174,904 rough_masonry01.dds.masonry_old_004.dds -02/24/2007 08:20 PM 197,078 rough_masonry01_ed.tga.masonry_old_004_editor.tga -02/24/2007 08:20 PM 788,401 rough_masonry01_local.tga.masonry_old_004_local.tga -05/30/2007 07:59 PM tiling_1d -02/25/2007 01:56 AM 174,904 uneven_blocks01_brown.dds.blocks_012.dds -02/24/2007 09:05 PM 197,100 uneven_blocks01_brown_ed.tga.blocks_012_editor.tga -02/24/2007 09:05 PM 786,476 uneven_blocks01_brown_local.tga.blocks_012_local.tga -02/25/2007 01:56 AM 174,904 uneven_blocks01_dark.dds.blocks_011.dds -02/24/2007 09:05 PM 196,248 uneven_blocks01_dark_ed.tga.blocks_011_editor.tga -02/24/2007 09:05 PM 786,476 uneven_blocks01_dark_local.tga.blocks_011_local.tga - 72 File(s) 50,549,757 bytes - - Directory of D:\temp2\textures\darkmod\stone\cobblestones\nontiling - -05/30/2007 07:48 PM . -05/30/2007 07:48 PM .. -02/24/2007 11:15 PM 788,820 flagstones_jagged_grey.tga.casfloor04.tga -02/24/2007 11:15 PM 788,369 flagstones_jagged_grey_local.tga.casfloor04_local.tga - 2 File(s) 1,577,189 bytes - - Directory of D:\temp2\textures\darkmod\stone\cobblestones\tiling_1d - -05/30/2007 07:59 PM . -05/30/2007 07:59 PM .. -02/25/2007 01:30 AM 349,672 blocks_uneven02_grey.dds.masonry_001.dds -02/24/2007 08:20 PM 393,858 blocks_uneven02_grey_local.tga.masonry_001_editor.tga -02/24/2007 08:20 PM 1,576,750 blocks_uneven02_grey_local.tga.masonry_001_local.tga -02/25/2007 01:30 AM 349,672 blocks_uneven03_grey.dds.masonry_002.dds -02/24/2007 08:20 PM 393,452 blocks_uneven03_grey_ed.tga.masonry_002_editor.tga -02/24/2007 08:20 PM 1,576,449 blocks_uneven03_grey_local.tga.masonry_002_local.tga -02/25/2007 01:30 AM 349,672 blocks_uneven04_brown.dds.masonry_003.dds -02/24/2007 08:20 PM 394,052 blocks_uneven04_brown_ed.tga.masonry_003_editor.tga -02/24/2007 08:20 PM 1,576,867 blocks_uneven04_brown_local.tga.masonry_003_local.tga -02/25/2007 01:30 AM 349,672 blocks_uneven05_grey.dds.masonry_004.dds -02/24/2007 08:20 PM 393,817 blocks_uneven05_grey_ed.tga.masonry_004_editor.tga -02/24/2007 08:20 PM 1,575,507 blocks_uneven05_grey_local.tga.masonry_004_local.tga -02/25/2007 01:30 AM 349,672 bricks_blocks_mix.dds.masonry_old_001.dds -02/24/2007 08:20 PM 393,521 bricks_blocks_mix_ed.tga.masonry_old_001_editor.tga -02/24/2007 08:20 PM 1,576,321 bricks_blocks_mix_local.tga.masonry_old_001_local.tga -02/25/2007 01:30 AM 349,672 bricks_blocks_roughmix.dds.masonry_old_002.dds -02/24/2007 08:20 PM 394,160 bricks_blocks_roughmix_ed.tga.masonry_old_002_editor.tga -02/24/2007 08:20 PM 1,576,743 bricks_blocks_roughmix_local.tga.masonry_old_002_local.tga -02/25/2007 01:30 AM 349,672 cobblestones_rounded.dds.rounded_001.dds -02/24/2007 08:20 PM 393,525 cobblestones_rounded_ed.tga.rounded_001_editor.tga -02/24/2007 08:20 PM 1,572,908 cobblestones_rounded_local.tga.rounded_001_local.tga -02/25/2007 01:30 AM 349,672 flagstones_sparse.dds.masonry_old_003.dds -02/24/2007 08:20 PM 394,194 flagstones_sparse_ed.tga.masonry_old_003_editor.tga -02/24/2007 08:20 PM 1,572,908 flagstones_sparse_local.tga.masonry_old_003_local.tga -02/25/2007 01:30 AM 349,672 flagstones_uneven.dds.masonry_old_005.dds -02/24/2007 08:20 PM 393,845 flagstones_uneven_ed.tga.masonry_old_005_editor.tga -02/24/2007 08:20 PM 1,557,680 flagstones_uneven_local.tga.masonry_old_005_local.tga - 27 File(s) 20,853,605 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat - -05/29/2007 07:52 PM . -05/29/2007 07:52 PM .. -02/25/2007 01:56 AM 349,672 ceramic_mosaic_decorative01.dds.decorative_001.dds -02/24/2007 09:05 PM 394,197 ceramic_mosaic_decorative01_ed.tga.decorative_001_editor.tga -02/24/2007 09:05 PM 1,572,908 ceramic_mosaic_decorative01_local.tga.decorative_001_local.tga -02/25/2007 01:56 AM 349,672 ceramic_mosaic_decorative01_s.dds.decorative_001_s.dds -04/23/2007 07:52 PM nontiling -02/25/2007 01:56 AM 349,672 rough_marble_dark01.dds.marble_004_d.DDS -02/24/2007 09:05 PM 393,260 rough_marble_dark01_ed.tga.marble_004_ed.tga -02/24/2007 09:05 PM 1,572,908 rough_marble_dark01_local.tga.marble_004_local.tga -02/25/2007 01:56 AM 699,192 rough_marble_dark02.dds.rough_006_d.DDS -02/24/2007 09:05 PM 197,075 rough_marble_dark02_ed.tga.rough_006_ed.tga -02/24/2007 09:05 PM 3,145,772 rough_marble_dark02_local.tga.rough_006_local.tga -02/25/2007 01:56 AM 349,672 rough_marble_light01.dds.rough_007_d.DDS -02/24/2007 09:05 PM 98,348 rough_marble_light01_ed.tga.rough_007_ed.tga -02/24/2007 09:05 PM 1,572,908 rough_marble_light01_local.tga.rough_007_local.tga -02/25/2007 01:56 AM 174,904 rough_plain_tiles01.dds.tiled_009.dds -02/24/2007 09:05 PM 49,691 rough_plain_tiles01_ed.tga.tiled_009_editor.tga -02/24/2007 09:05 PM 786,476 rough_plain_tiles01_local.tga.tiled_009_local.tga -02/24/2007 09:59 PM 786,476 rough_slate_dark01.tga.manfslate1.tga -02/24/2007 09:59 PM 786,476 rough_slate_dark01_local.tga.manfslate1_local.tga -02/25/2007 01:56 AM 699,192 rough_slate_tiles01_dark.dds.tiled_010_d.DDS -02/24/2007 09:05 PM 196,096 rough_slate_tiles01_dark_ed.tga.tiled_010_ed.tga -02/24/2007 09:05 PM 786,476 rough_slate_tiles01_local.tga.tiled_010_local.tga -02/24/2007 10:47 PM 786,476 slate01_light.tga.concrete01_d.tga -02/24/2007 10:47 PM 786,476 slate01_local.tga.concrete01_local.tga -02/24/2007 10:47 PM 786,476 slate01_s.tga.concrete01_s.tga -03/07/2006 03:35 PM 788,172 slate02_dark.tga.concrete2_d.tga -12/10/2005 03:43 PM 788,492 slate02_light.tga.concrete_d.tga -12/10/2005 03:43 PM 786,476 slate02_local.tga.concrete_local.tga -05/21/2007 12:44 PM smooth -02/24/2007 11:15 PM 786,476 tiles_rough_grey.tga.casfloor03.tga -02/24/2007 11:15 PM 786,476 tiles_rough_grey_local.tga.casfloor03_local.tga -02/24/2007 09:59 PM 786,476 tile_plain_diamond01_brown.tga.manfloor01.tga -02/24/2007 09:59 PM 786,450 tile_plain_diamond01_brown_s.tga.manfloor01_s.tga -02/24/2007 09:59 PM 786,476 tile_plain_diamond01_local.tga.manfloor01_local.tga -05/23/2007 07:33 PM tiling_1d - 32 File(s) 23,965,965 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat\smooth - -05/21/2007 12:44 PM . -05/21/2007 12:44 PM .. -02/24/2007 09:59 PM 196,652 ceramic_tile_generic01_s.tga.manfloor01sh_s.tga -02/24/2007 09:59 PM 164,312 ceramic_tile_gold01.tga.manfloor03sh.tga -02/24/2007 09:59 PM 196,652 ceramic_tile_reddish01.tga.manfloor01sh.tga -02/24/2007 09:59 PM 196,652 ceramic_tile_tan01.tga.manfloor02sh.tga -02/24/2007 09:59 PM 167,132 ceramic_tile_tan02.tga.manfloor05sh.tga -02/24/2007 09:59 PM 196,652 ceramic_tile_tan03.tga.manfloor06sh.tga -02/24/2007 09:59 PM 393,943 marble_pattern01.tga.manfloor02.tga -02/24/2007 09:59 PM 785,660 marble_pattern01_centerrose.tga.manfloor02cen2.tga -02/24/2007 09:59 PM 262,188 marble_pattern01_centerrose_s.tga.manfloor02cen2_s.tga -02/24/2007 09:59 PM 780,813 marble_pattern01_centersun.tga.manfloor02cen1.tga -02/24/2007 09:59 PM 262,188 marble_pattern01_centersun_s.tga.manfloor02cen1_s.tga -02/24/2007 09:59 PM 390,758 marble_pattern01_local.tga.manfloor02_local.tga -02/24/2007 09:59 PM 524,332 marble_pattern01_s.tga.manfloor02_s.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_checker.dds.marble_002_center1.dds -02/24/2007 09:23 PM 259,703 marble_pattern02_checker_ed.tga.marble_002_center1_editor.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_checker_s.dds.marble_002_center1_s.dds -02/25/2007 02:07 AM 174,904 marble_pattern02_crosshair.dds.marble_002_center2.dds -02/24/2007 09:23 PM 260,256 marble_pattern02_crosshair_ed.tga.marble_002_center2_editor.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_crosshair_s.dds.marble_002_center2_s.dds -02/25/2007 02:07 AM 174,904 marble_pattern02_rings.dds.marble_002_center5.dds -02/24/2007 09:23 PM 250,053 marble_pattern02_rings_ed.tga.marble_002_center5_editor.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_rings_s.dds.marble_002_center5_s.dds -02/25/2007 02:07 AM 174,904 marble_pattern02_star.dds.marble_002_center3.dds -02/25/2007 02:07 AM 174,904 marble_pattern02_star02.dds.marble_002_center4.dds -02/24/2007 09:23 PM 240,649 marble_pattern02_star02_ed.tga.marble_002_center4_editor.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_star02_s.dds.marble_002_center4_s.dds -02/24/2007 09:23 PM 199,099 marble_pattern02_star_ed.tga.marble_002_center3_editor.tga -02/25/2007 02:07 AM 174,904 marble_pattern02_star_s.dds.marble_002_center3_s.dds -02/25/2007 02:07 AM 699,192 marble_pattern03_brownish.dds.marble_003_d.DDS -02/24/2007 09:23 PM 196,956 marble_pattern03_brownish_ed.tga.marble_003_ed.tga -02/24/2007 09:23 PM 786,476 marble_pattern03_brownish_local.tga.marble_003_local.tga -02/25/2007 02:07 AM 699,192 marble_pattern03_brownish_s.dds.marble_003_s.DDS -05/21/2007 12:31 PM nontiling -05/21/2007 12:46 PM tiling_1d - 32 File(s) 9,858,550 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat\smooth\nontiling - -05/21/2007 12:31 PM . -05/21/2007 12:31 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat\smooth\tiling_1d - -05/21/2007 12:46 PM . -05/21/2007 12:46 PM .. -02/24/2007 09:54 PM 393,260 marble_trim01_brown.tga.manwtrim03.tga -02/24/2007 09:54 PM 393,260 marble_trim01_local.tga.manwtrim03_local.tga -02/24/2007 09:54 PM 141,760 marble_trim01_s.tga.manwtrim03_s.tga - 3 File(s) 928,280 bytes - - Directory of D:\temp2\textures\darkmod\stone\flat\tiling_1d - -05/23/2007 07:33 PM . -05/23/2007 07:33 PM .. -02/25/2007 01:30 AM 349,672 cement_002.dds -02/24/2007 08:20 PM 392,736 cement_002_editor.tga -02/24/2007 08:20 PM 1,576,293 cement_002_local.tga -02/25/2007 01:30 AM 349,672 cement_004.dds -02/24/2007 08:20 PM 393,899 cement_004_editor.tga -02/24/2007 08:20 PM 1,576,762 cement_004_local.tga -02/25/2007 01:30 AM 349,672 cement_005.dds -02/24/2007 08:20 PM 392,507 cement_005_editor.tga -02/24/2007 08:20 PM 1,576,426 cement_005_local.tga -02/25/2007 01:30 AM 349,672 cement_007.dds -02/24/2007 08:20 PM 394,018 cement_007_editor.tga -02/24/2007 08:20 PM 1,576,822 cement_007_local.tga -02/25/2007 01:30 AM 349,672 cement_008.dds -02/24/2007 08:20 PM 393,950 cement_008_editor.tga -02/24/2007 08:20 PM 1,576,767 cement_008_local.tga -02/25/2007 01:30 AM 349,672 cement_010.dds -02/24/2007 08:20 PM 394,228 cement_010_editor.tga -02/24/2007 08:20 PM 1,576,440 cement_010_local.tga -02/25/2007 01:30 AM 349,672 cement_010_s.dds -02/25/2007 01:30 AM 349,672 cement_013_s.dds -02/24/2007 10:47 PM 786,476 concrete_dirt01_d.tga -02/24/2007 10:47 PM 786,476 concrete_dirt01_local.tga -02/24/2007 10:47 PM 786,476 concrete_dirt01_s.tga -02/25/2007 01:30 AM 349,672 concrete_light_cracked.dds.cement_001.dds -02/24/2007 08:20 PM 393,773 concrete_light_cracked_ed.tga.cement_001_editor.tga -02/24/2007 08:20 PM 1,572,908 concrete_light_cracked_local.tga.cement_001_local.tga -02/25/2007 01:30 AM 349,672 concrete_light_streaked.dds.cement_013.dds -02/24/2007 08:20 PM 394,090 concrete_light_streaked_ed.tga.cement_013_editor.tga -02/24/2007 08:20 PM 1,576,928 concrete_light_streaked_local.tga.cement_013_local.tga -02/25/2007 01:30 AM 349,672 concrete_rough_dark01.dds.cement_003.dds -02/24/2007 08:20 PM 393,863 concrete_rough_dark01_ed.tga.cement_003_editor.tga -02/24/2007 08:20 PM 1,576,821 concrete_rough_dark01_local.tga.cement_003_local.tga -02/24/2007 08:20 PM 1,575,417 concrete_rough_dark01_local.tga.cement_009_local.tga -02/25/2007 01:30 AM 349,672 concrete_rough_dark02.dds.cement_009.dds -02/24/2007 08:20 PM 393,032 concrete_rough_dark02_ed.tga.cement_009_editor.tga -02/25/2007 01:30 AM 349,672 concrete_rough_pebbly.dds.cement_006.dds -02/24/2007 08:20 PM 394,148 concrete_rough_pebbly_ed.tga.cement_006_editor.tga -02/24/2007 08:20 PM 1,572,908 concrete_rough_pebbly_local.tga.cement_006_local.tga -02/24/2007 09:07 PM 780,128 gen_slate_dirt_local.tga.concrete_dirt_001_local.tga -02/24/2007 09:07 PM 786,476 gen_slate_dirt_s.tga.concrete_dirt_001_s.tga -02/24/2007 09:07 PM 778,122 gen_slate_light_dirt.tga.concrete_dirt_001_d.tga - 41 File(s) 30,914,626 bytes - - Directory of D:\temp2\textures\darkmod\stone\natural - -05/31/2007 08:21 PM . -05/31/2007 08:21 PM .. -02/25/2007 01:56 AM 699,192 dark_dirty.dds.rough_010_d.DDS -02/24/2007 09:05 PM 196,619 dark_dirty_ed.tga.rough_010_ed.tga -02/24/2007 09:05 PM 3,145,772 dark_dirty_local.tga.rough_010_local.tga -02/25/2007 01:56 AM 174,904 dark_dirt_smeary.dds.rough_001.dds -02/24/2007 09:05 PM 196,530 dark_dirt_smeary_ed.tga.rough_001_editor.tga -02/24/2007 09:05 PM 786,256 dark_dirt_smeary_local.tga.rough_001_local.tga -02/25/2007 01:56 AM 174,904 dark_rough.dds.rough_009_d.DDS -02/24/2007 09:05 PM 196,058 dark_rough_ed.tga.rough_009_ed.tga -02/24/2007 09:05 PM 786,476 dark_rough_local.tga.rough_009_local.tga -02/25/2007 01:56 AM 699,192 light_grey_rough.dds.rough_005_d.DDS -02/24/2007 09:05 PM 196,652 light_grey_rough_ed.tga.rough_005_ed.tga -02/24/2007 09:05 PM 3,145,772 light_grey_rough_local.tga.rough_005_local.tga -03/18/2007 03:27 PM 3,145,772 mossy_rock_brown.tga.mossyrock_002.tga -03/18/2007 03:27 PM 19,920 mossy_rock_brown_ed.jpg.mossyrock_002_ed.jpg -03/18/2007 03:27 PM 3,145,772 mossy_rock_brown_local.tga.mossyrock_002_local.tga -03/18/2007 03:27 PM 786,971 mossy_rock_brown_s.tga.mossyrock_002_s.tga -03/18/2007 03:27 PM 3,145,772 mossy_rock_bumpy.tga.mossyrock_003.tga -03/18/2007 03:27 PM 19,376 mossy_rock_bumpy_ed.jpg.mossyrock_003_ed.jpg -03/18/2007 03:27 PM 3,145,772 mossy_rock_bumpy_local.tga.mossyrock_003_local.tga -03/18/2007 03:27 PM 786,971 mossy_rock_bumpy_s.tga.mossyrock_003_s.tga -03/18/2007 03:27 PM 3,145,772 mossy_rock_green.tga.mossyrock_001.tga -03/18/2007 03:27 PM 19,555 mossy_rock_green_ed.jpg.mossyrock_001_ed.jpg -03/18/2007 03:27 PM 3,145,772 mossy_rock_green_local.tga.mossyrock_001_local.tga -03/18/2007 03:27 PM 786,971 mossy_rock_green_s.tga.mossyrock_001_s.tga -04/23/2007 07:52 PM nontiling -02/25/2007 01:56 AM 699,192 rock_brown_mottled.dds.rough_004_d.DDS -02/24/2007 09:05 PM 196,652 rock_brown_mottled_ed.tga.rough_004_ed.tga -02/24/2007 09:05 PM 3,121,571 rock_brown_mottled_local.tga.rough_004_local.tga -02/25/2007 01:56 AM 699,192 rock_grey.dds.rough_003_d.DDS -04/28/2007 06:11 PM 196,652 rock_grey_dark_ed.tga.rough_003_dark_ed.tga -02/24/2007 09:05 PM 197,139 rock_grey_ed.tga.rough_003_ed.tga -02/24/2007 09:05 PM 3,110,875 rock_grey_local.tga.rough_003_local.tga -02/25/2007 07:26 PM 699,192 rock_grey_mossy.dds.rough_012_mossy_d.DDS -02/24/2007 09:05 PM 197,145 rock_grey_mossy_ed.tga.rough_012_mossy_ed.tga -02/24/2007 09:05 PM 3,145,772 rock_grey_mossy_local.tga.rough_012_mossy_local.tga -02/25/2007 01:56 AM 174,904 rough_grey_dirty.dds.rough_011_d.DDS -02/24/2007 09:05 PM 196,652 rough_grey_dirty_ed.tga.rough_011_ed.tga -02/24/2007 09:05 PM 787,751 rough_grey_dirty_local.tga.rough_011_local.tga -02/25/2007 01:56 AM 174,904 rough_old.dds.rough_008_d.DDS -02/24/2007 09:05 PM 197,020 rough_old_ed.tga.rough_008_ed.tga -02/24/2007 09:05 PM 786,476 rough_old_local.tga.rough_008_local.tga -02/25/2007 01:56 AM 699,192 sandstone.dds.rough_002_d.DDS -02/24/2007 09:05 PM 197,140 sandstone_ed.tga.rough_002_ed.tga -02/24/2007 09:05 PM 3,145,772 sandstone_local.tga.rough_002_local.tga -05/31/2007 08:21 PM tiling_1d - 43 File(s) 50,315,916 bytes - - Directory of D:\temp2\textures\darkmod\stone\natural\nontiling - -04/23/2007 07:52 PM . -04/23/2007 07:52 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone\natural\tiling_1d - -05/31/2007 08:21 PM . -05/31/2007 08:21 PM .. -02/24/2007 10:53 PM 788,812 gravel_grey_01.tga.ctygravel01.tga -02/24/2007 10:53 PM 789,019 gravel_grey_01_local.tga.ctygravel01_local.tga - 2 File(s) 1,577,831 bytes - - Directory of D:\temp2\textures\darkmod\stone\sculpted - -05/25/2007 08:21 PM . -05/25/2007 08:21 PM .. -04/28/2007 06:25 PM 391,585 carved_design_bones01_ed.tga.ornament_011_bones_ed.tga -04/28/2007 06:25 PM 1,572,908 carved_design_bones01_local.tga.ornament_011_bones_local.tga -04/28/2007 06:25 PM 98,308 carved_design_bones02_ed.tga.ornament_013_bones_tile_ed.tga -04/28/2007 06:25 PM 49,196 carved_design_bones02_left_ed.tga.ornament_013_bones_tile_left_ed.tga -04/28/2007 06:25 PM 786,476 carved_design_bones02_left_local.tga.ornament_013_bones_tile_left_local.tga -04/28/2007 06:25 PM 1,572,908 carved_design_bones02_local.tga.ornament_013_bones_tile_local.tga -04/28/2007 06:25 PM 49,196 carved_design_bones02_right_ed.tga.ornament_013_bones_tile_right_ed.tga -04/28/2007 06:25 PM 786,476 carved_design_bones02_right_local.tga.ornament_013_bones_tile_right_local.tga -03/03/2007 10:26 AM 391,578 carved_design_diamonds01_ed.tga.ornament_010_ed.tga -03/03/2007 10:26 AM 794,089 carved_design_diamonds01_local.tga.ornament_010_local.tga -04/28/2007 06:25 PM 49,196 carved_design_skull01_ed.tga.ornament_014_skull_ed.tga -04/28/2007 06:25 PM 786,476 carved_design_skull01_local.tga.ornament_014_skull_local.tga -04/28/2007 06:25 PM 196,652 carved_design_snakes_ed.tga.ornament_012_snakes_ed.tga -04/28/2007 06:25 PM 3,145,772 carved_design_snakes_local.tga.ornament_012_snakes_local.tga -02/25/2007 01:59 AM 87,560 carved_diamond_trim.dds.trim_002_d.DDS -02/25/2007 01:59 AM 174,984 carved_diamond_trim02.dds.trim_001_d.DDS -02/24/2007 09:19 PM 12,332 carved_diamond_trim02_ed.tga.trim_001_ed.tga -02/24/2007 09:19 PM 786,476 carved_diamond_trim02_local.tga.trim_001_local.tga -02/24/2007 09:19 PM 24,620 carved_diamond_trim_ed.tga.trim_002_ed.tga -02/24/2007 09:19 PM 393,260 carved_diamond_trim_local.tga.trim_002_local.tga -02/25/2007 01:59 AM 699,208 carved_tiles01_x4_dark.dds.ornament_002_d.DDS -02/24/2007 09:19 PM 194,391 carved_tiles01_x4_dark_ed.tga.ornament_002_ed.tga -02/25/2007 01:59 AM 699,208 carved_tiles01_x4_light.dds.ornament_001_d.DDS -02/24/2007 09:19 PM 196,132 carved_tiles01_x4_light_ed.tga.ornament_001_ed.tga -02/24/2007 09:19 PM 1,005,004 carved_tiles01_x4_local.tga.ornament_001_local.tga -02/24/2007 09:19 PM 194,405 engraved_tile_cup01_ed.tga.grave_005_ed.tga -02/24/2007 09:19 PM 125,951 engraved_tile_cup01_local.tga.grave_005_local.tga -02/24/2007 09:19 PM 786,476 engraved_tile_cup01_roughness_local.tga.grave_005_roughness_local.tga -02/25/2007 01:59 AM 699,192 engraved_tile_face01.dds.ornament_009_d.DDS -02/24/2007 09:19 PM 195,689 engraved_tile_face01_ed.tga.ornament_009_ed.tga -02/24/2007 09:19 PM 3,145,772 engraved_tile_face01_local.tga.ornament_009_local.tga -02/25/2007 01:59 AM 699,192 engraved_tile_impface.dds.grave_007_d.DDS -02/24/2007 09:19 PM 194,770 engraved_tile_impface_ed.tga.grave_007_ed.tga -02/24/2007 09:19 PM 562,959 engraved_tile_impface_local.tga.grave_007_local.tga -02/24/2007 09:19 PM 196,474 engraved_tile_ovals_ed.tga.deco_002_ed.tga -02/24/2007 09:19 PM 2,639,524 engraved_tile_ovals_local.tga.deco_002_local.tga -02/25/2007 01:59 AM 174,904 engraved_tile_ring.dds.grave_008_d.DDS -02/24/2007 09:19 PM 194,851 engraved_tile_ring_ed.tga.grave_008_ed.tga -02/24/2007 09:19 PM 98,130 engraved_tile_ring_local.tga.grave_008_local.tga -02/24/2007 09:19 PM 196,202 engraved_tile_star_ed.tga.deco_001_ed.tga -02/24/2007 09:19 PM 593,118 engraved_tile_star_local.tga.deco_001_local.tga -02/24/2007 09:19 PM 187,679 engraved_tile_x_ed.tga.grave_006_ed.tga -02/24/2007 09:19 PM 126,777 engraved_tile_x_local.tga.grave_006_local.tga -05/25/2007 08:20 PM nontiling -02/24/2007 09:19 PM 195,436 royal_emblem01_ed.tga.ornament_003_ed.tga -02/24/2007 09:19 PM 787,670 royal_emblem01_local.tga.ornament_003_local.tga -02/25/2007 01:59 AM 174,904 royal_symbol01.dds.ornament_003_d.DDS -02/24/2007 09:19 PM 393,260 sarcophagus_cup&hammer01_ed.tga.grave_002_ed.tga -02/24/2007 09:19 PM 1,572,908 sarcophagus_cup&hammer01_local.tga.grave_002_local.tga -02/24/2007 09:19 PM 1,572,908 sarcophagus_cup&hammer01_local.tga.grave_003_local.tga -02/25/2007 01:59 AM 349,672 sarcophagus_stone01.dds.grave_001_d.DDS -02/25/2007 01:59 AM 174,904 sarcophagus_stone02.dds.grave_005_d.DDS -02/24/2007 09:19 PM 390,659 sarcophagus_swords&shield01_ed.tga.grave_004_ed.tga -02/24/2007 09:19 PM 1,572,908 sarcophagus_swords&shield01_local.tga.grave_004_local.tga -02/24/2007 09:19 PM 393,260 sarcophagus_warrior01_ed.tga.grave_001_ed.tga -02/24/2007 09:19 PM 1,572,908 sarcophagus_warrior01_local.tga.grave_001_local.tga -02/24/2007 09:19 PM 1,572,908 sarcophagus_warrior01_roughness_local.tga.grave_001_roughness_local.tga -02/24/2007 09:19 PM 390,460 sarcophagus_wings01_ed.tga.grave_003_ed.tga -02/25/2007 01:59 AM 699,192 tiles_bars_diamondshape.dds.ornament_005_d.DDS -02/24/2007 09:19 PM 196,766 tiles_bars_diamondshape_ed.tga.ornament_005_ed.tga -02/24/2007 09:19 PM 2,824,193 tiles_bars_diamondshape_local.tga.ornament_005_local.tga -02/24/2007 09:19 PM 196,704 tile_diamond_trapezoid_ed.tga.ornament_008_ed.tga -02/24/2007 09:19 PM 196,769 tile_empty_square_ed.tga.ornament_006_ed.tga -02/24/2007 09:19 PM 85,804 tile_empty_square_local.tga.ornament_006_local.tga -02/24/2007 09:19 PM 196,801 tile_empty_trapezoid_ed.tga.ornament_007_ed.tga -02/24/2007 09:19 PM 85,499 tile_empty_trapezoid_local.tga.ornament_007_local.tga -02/24/2007 09:19 PM 259,940 tile_empty_trapezoid_local.tga.ornament_008_local.tga -05/25/2007 08:21 PM tiling_1d -04/28/2007 06:25 PM 49,196 trapezoid_tile_1x1_ed.tga.border_1x1_ed.tga -04/28/2007 06:25 PM 786,476 trapezoid_tile_1x1_local.tga.border_1x1_local.tga -04/28/2007 06:25 PM 98,348 trapezoid_tile_2x1_ed.tga.border_2x1_ed.tga -04/28/2007 06:25 PM 1,572,908 trapezoid_tile_2x1_local.tga.border_2x1_local.tga -04/28/2007 06:25 PM 196,652 trapezoid_tile_4x1_ed.tga.border_4x1_ed.tga -04/28/2007 06:25 PM 3,145,772 trapezoid_tile_4x1_local.tga.border_4x1_local.tga -04/28/2007 06:25 PM 24,620 trapezoid_tile_8x1_ed.tga.border_8x1_ed.tga -04/28/2007 06:25 PM 6,291,500 trapezoid_tile_8x1_local.tga.border_8x1_local.tga - 74 File(s) 53,977,961 bytes - - Directory of D:\temp2\textures\darkmod\stone\sculpted\nontiling - -05/25/2007 08:20 PM . -05/25/2007 08:20 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\stone\sculpted\tiling_1d - -05/25/2007 08:21 PM . -05/25/2007 08:21 PM .. -02/25/2007 01:59 AM 174,904 marble_ancient_writing.dds.ornament_004_d.DDS -02/24/2007 09:19 PM 749,986 marble_ancient_writing.tga.ornament_004_local.tga -02/24/2007 09:19 PM 196,997 marble_ancient_writing_ed.tga.ornament_004_ed.tga - 3 File(s) 1,121,887 bytes - - Directory of D:\temp2\textures\darkmod\window - -05/05/2007 03:40 PM . -05/05/2007 03:40 PM .. -02/24/2007 10:59 PM 389,540 diamond_pattern01_dark.tga.ctywindow01b.tga -02/24/2007 10:59 PM 393,234 diamond_pattern01_lit.tga.ctywindow01.tga -02/24/2007 10:59 PM 393,260 diamond_pattern01_local.tga.ctywindow01_local.tga -02/24/2007 10:59 PM 32,812 diamond_pattern01_s.tga.ctywindow01_s.tga -02/24/2007 09:41 PM 393,260 diamond_pattern_andbars01_lit.tga.cwindow02_d.tga -02/24/2007 10:47 PM 317,537 frame_ornate_wallsection_lit.tga.ctywfacade01_local.tga -02/24/2007 10:47 PM 389,409 frame_ornate_wallsection_local.tga.ctywfacade01.tga -12/01/2005 02:32 PM 388,301 horizontal_old_smallpanels01_dark.tga -12/01/2005 05:37 PM 122,538 horizontal_old_smallpanels01_dark_s.tga -12/01/2005 05:39 PM 393,260 horizontal_old_smallpanels01_local.tga -02/24/2007 09:41 PM 782,749 largesquare01_brightlit.tga.largesquare100.tga -02/24/2007 09:41 PM 783,209 largesquare01_lit.tga.largesquare90.tga -02/24/2007 09:41 PM 693,385 largesquare01_softerlit.tga.largesquare70.tga -02/24/2007 09:41 PM 764,380 largesquare01_softlit.tga.largesquare80.tga -02/24/2007 10:05 PM 686,650 largesquare02_dark.tga.manwindow01.tga -02/24/2007 10:05 PM 759,631 largesquare02_lit.tga.manwindow01b.tga -02/24/2007 10:05 PM 689,815 largesquare02_local.tga.manwindow01_local.tga -02/24/2007 10:05 PM 65,580 largesquare02_s.tga.manwindow01_s.tga -02/24/2007 09:29 PM 524,753 manwindow02b_withalpha.tga -05/04/2007 08:04 PM ornate -02/24/2007 09:41 PM 393,260 pebbly_glass_noframe01_lit.tga.hlamp_window01_d.tga -02/24/2007 10:05 PM 196,652 pointedtop_thin01_dark.tga.manwindow03.tga -02/24/2007 10:05 PM 196,652 pointedtop_thin01_local.tga.manwindow03_local.tga -02/24/2007 10:05 PM 65,580 pointedtop_thin01_s.tga.manwindow03_s.tga -03/06/2007 07:35 PM 393,260 roundtop_diamond_pattern01_brightlit.tga.manwindow04.tga -02/24/2007 10:05 PM 391,622 roundtop_diamond_pattern01_dark.tga.manwindow02b.tga -02/24/2007 10:05 PM 392,208 roundtop_diamond_pattern01_grey.tga.manwindow02d.tga -02/24/2007 10:05 PM 394,074 roundtop_diamond_pattern01_lit.tga.manwindow02.tga -02/24/2007 10:05 PM 393,612 roundtop_diamond_pattern01_local.tga.manwindow02_local.tga -02/24/2007 10:05 PM 524,332 roundtop_diamond_pattern01_s.tga.manwindow02_s.tga -02/24/2007 10:05 PM 339,869 roundtop_diamond_pattern01_verydark.tga.manwindow02c.tga -02/24/2007 10:59 PM 393,260 shutters_closed_local.tga.ctywindow02_local.tga -02/24/2007 10:59 PM 393,260 shutters_grey_closed.tga.ctywindow02.tga -02/24/2007 09:41 PM 384,101 simple_square01_brightlit.tga.smallsquare100.tga -02/24/2007 09:41 PM 386,377 simple_square01_lit.tga.smallsquare90.tga -02/24/2007 09:41 PM 353,804 simple_square01_softerlit.tga.smallsquare80.tga -02/24/2007 09:41 PM 307,509 simple_square01_softlit.tga.smallsquare70.tga -03/21/2006 08:01 PM 786,476 square_old_smallpanels01_dark.tga -12/11/2005 12:49 AM 727,961 square_old_smallpanels01_local.tga -12/11/2005 12:37 AM 536,829 square_old_smallpanels01_s.tga -02/24/2007 09:41 PM 393,260 square_pattern01_lit.tga.cwindow01_d.tga -02/24/2007 09:41 PM 393,260 square_pattern01_softlit.tga.cwindow01_dark_d.tga -04/23/2007 07:47 PM transparent_glass - 41 File(s) 17,700,521 bytes - - Directory of D:\temp2\textures\darkmod\window\ornate - -05/04/2007 08:04 PM . -05/04/2007 08:04 PM .. -02/20/2006 09:36 AM 786,450 pointedtop_stainglass01_blend.tga.winboth1_blend.tga -02/20/2006 10:49 AM 786,450 pointedtop_stainglass01_blend2.tga.winboth2_blend.tga -02/20/2006 09:36 AM 786,450 pointedtop_stainglass01_blue.tga.winboth1.tga -01/20/2006 04:36 PM 786,450 pointedtop_stainglass01_local.tga.winboth1_local.tga -02/20/2006 09:48 AM 196,626 pointedtop_stainglass01_s.tga.winboth1_s.tga -02/24/2007 09:41 PM 195,274 round_spokes01_brightlit.tga.largeround100.tga -02/24/2007 09:41 PM 195,318 round_spokes01_lit.tga.largeround90.tga -02/24/2007 09:41 PM 112,802 round_spokes01_softerlit.tga.largeround70.tga -02/24/2007 09:41 PM 171,936 round_spokes01_softlit.tga.largeround80.tga - 9 File(s) 4,017,756 bytes - - Directory of D:\temp2\textures\darkmod\window\transparent_glass - -04/23/2007 07:47 PM . -04/23/2007 07:47 PM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\wood - -05/31/2007 08:26 PM . -05/31/2007 08:26 PM .. -05/31/2007 08:17 PM boards -05/31/2007 08:18 PM panels -05/26/2007 11:48 AM plaster - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\wood\boards - -05/31/2007 08:17 PM . -05/31/2007 08:17 PM .. -02/25/2007 02:03 AM 699,192 dark_rough.dds.boards_old_004.dds -02/24/2007 11:04 PM 197,147 dark_rough_ed.tga.boards_old_004_editor.tga -02/24/2007 11:04 PM 3,145,772 dark_rough_local.tga.boards_old_004_local.tga -04/15/2007 04:12 PM 174,904 dark_varnished.dds.boards_old_007.dds -04/15/2007 04:10 PM 11,182 dark_varnished_ed.jpg.boards_old_007_editor.jpg -04/15/2007 04:10 PM 3,145,772 dark_varnished_local.tga.boards_old_007_local.tga -02/24/2007 11:04 PM 2,133 dim_01_ed.jpg.boards_polished_002_dim_editor.jpg -02/24/2007 10:09 PM 783,783 metal_decorated.tga.manceiling04.tga -02/24/2007 10:09 PM 673,122 metal_decorated_local.tga.manceiling04_local.tga -02/24/2007 10:09 PM 65,580 metal_decorated_s.tga.manceiling04_s.tga -05/26/2007 11:48 AM nontiling -05/06/2005 08:42 PM 786,476 old_01.tga.medieval010.tga -05/06/2005 08:42 PM 786,476 old_01_h.tga.medieval010_h.tga -05/06/2005 08:42 PM 786,476 old_01_s.tga.medieval010_s.tga -02/24/2007 07:50 PM 783,748 old_small_grainy.tga.pagfloor01.tga -02/24/2007 07:50 PM 786,114 old_small_grainy_local.tga.pagfloor01_local.tga -02/24/2007 07:51 PM 788,425 plastered_grey.tga.pagceiling01.tga -03/20/2007 08:49 PM 31,014 plastered_grey_ed.jpg.pagceiling01_ed.jpg -03/20/2007 08:49 PM 786,476 plastered_grey_local.tga.pagceiling01_local.tga -02/25/2007 02:03 AM 174,904 polished_01.dds.boards_polished_002.dds -02/24/2007 11:04 PM 2,511 polished_01_ed.jpg.boards_polished_002_editor.jpg -02/24/2007 11:04 PM 786,476 polished_01_local.tga.boards_polished_002_local.tga -02/25/2007 02:03 AM 174,904 polished_01_s.dds.boards_polished_002_s.dds -02/25/2007 02:03 AM 174,904 polished_shiny.dds.boards_polished_001.dds -02/24/2007 11:04 PM 2,900 polished_shiny_ed.jpg.boards_polished_001_editor.jpg -02/25/2007 02:03 AM 174,904 polished_shiny_s.dds.boards_polished_001_s.dds -02/24/2007 11:15 PM 786,476 scratched.tga.casfloor02.tga -02/24/2007 11:15 PM 786,476 scratched_local.tga.casfloor02_local.tga -02/24/2007 11:15 PM 196,386 scratched_s.tga.casfloor02_s.tga -05/31/2007 08:25 PM tiling_1d -02/24/2007 11:15 PM 784,085 weathered.tga.casfloor01.tga -02/24/2007 11:15 PM 786,476 weathered_local.tga.casfloor01_local.tga -02/24/2007 11:15 PM 195,314 weathered_s.tga.casfloor01_s.tga -02/25/2007 02:03 AM 174,904 worn_01.dds.boards_old_005.dds -02/24/2007 11:04 PM 196,924 worn_01_ed.tga.boards_old_005_editor.tga -02/24/2007 11:04 PM 786,476 worn_01_local.tga.boards_old_005_local.tga -02/25/2007 02:03 AM 174,904 worn_01_s.dds.boards_old_005_s.dds -04/15/2007 04:12 PM 174,904 worn_02.dds.boards_old_006.dds -04/15/2007 04:10 PM 16,811 worn_02_ed.jpg.boards_old_006_editor.jpg -04/15/2007 04:10 PM 786,476 worn_02_local.tga.boards_old_006_local.tga -02/24/2007 07:50 PM 786,476 worn_large.tga.pagfloor02.tga -02/24/2007 07:50 PM 786,476 worn_large_local.tga.pagfloor02_local.tga - 40 File(s) 23,344,859 bytes - - Directory of D:\temp2\textures\darkmod\wood\boards\nontiling - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\wood\boards\tiling_1d - -05/31/2007 08:25 PM . -05/31/2007 08:25 PM .. -02/24/2007 11:08 PM 786,850 gen_old_boards.tga.wood_001_d.tga -02/24/2007 11:08 PM 777,825 gen_old_boards_local.tga.wood_001_local.tga -02/25/2007 02:00 AM 349,672 new_grainy.dds.boards_new_001.dds -02/24/2007 11:00 PM 294,956 new_grainy_ed.tga.boards_new_001_editor.tga -02/24/2007 11:00 PM 1,572,908 new_grainy_local.tga.boards_new_001_local.tga -02/25/2007 02:00 AM 349,672 new_grainy_s.dds.boards_new_001_s.dds - 6 File(s) 4,131,883 bytes - - Directory of D:\temp2\textures\darkmod\wood\panels - -05/31/2007 08:18 PM . -05/31/2007 08:18 PM .. -02/25/2007 02:05 AM 349,672 beam_brown_old.DDS.beam_003_d.DDS -02/24/2007 11:10 PM 98,348 beam_brown_old_ed.tga.beam_003_ed.tga -02/24/2007 11:10 PM 1,504,488 beam_brown_old_local.tga.beam_003_local.tga -02/24/2007 07:51 PM 393,260 beam_old_mossy.tga.pagtrim01.tga -02/24/2007 07:51 PM 196,652 beam_old_mossy_local.tga.pagtrim01_local.tga -02/24/2007 07:51 PM 196,652 beam_old_mossy_s.tga.pagtrim01_s.tga -02/25/2007 02:05 AM 699,272 beam_rough_brown.dds.beam_002.dds -02/24/2007 11:10 PM 2,265 beam_rough_brown_ed.jpg.beam_002_editor.jpg -02/25/2007 02:05 AM 1,398,416 beam_rough_local.dds.beam_002_local.dds -02/24/2007 11:10 PM 4,194,348 beam_rough_local.tga.beam_002_local.tga -02/25/2007 02:05 AM 699,272 beam_rough_s.dds.beam_002_s.dds -02/25/2007 02:05 AM 699,272 beam_rough_weathered.dds.beam_002_weathered.dds -02/24/2007 11:10 PM 2,604 beam_rough_weathered_ed.jpg.beam_002_weathered_editor.jpg -02/24/2007 09:54 PM 393,260 molding_decorative_dark.tga.manwtrim04.tga -02/24/2007 09:54 PM 393,260 molding_decorative_dark_local.tga.manwtrim04_local.tga -02/24/2007 09:54 PM 388,757 molding_grey.tga.manwtrim01.tga -02/24/2007 09:54 PM 389,308 molding_grey_local.tga.manwtrim01_local.tga -02/24/2007 09:54 PM 383,066 molding_leaves.tga.manwtrim02.tga -02/24/2007 09:54 PM 385,671 molding_leaves_local.tga.manwtrim02_local.tga -05/31/2007 08:18 PM nontiling -02/24/2007 09:54 PM 788,195 panels_decorative_arched.tga.manwall01.tga -02/24/2007 09:54 PM 740,376 panels_decorative_arched_local.tga.manwall01_local.tga -02/24/2007 09:54 PM 786,476 panels_grey_long.tga.manwpanel01.tga -02/24/2007 09:54 PM 786,450 panels_grey_long_local.tga.manwpanel01_local.tga -02/24/2007 10:09 PM 196,652 panel_carved_rectangles_01.tga.manceiling06.tga -02/24/2007 10:09 PM 196,652 panel_carved_rectangles_01_local.tga.manceiling06_local.tga -02/24/2007 10:09 PM 786,476 panel_carved_rectangles_02_dark.tga.manceiling03.tga -02/24/2007 10:09 PM 786,476 panel_carved_rectangles_02_light.tga.manceiling03b.tga -02/24/2007 10:09 PM 786,476 panel_carved_rectangles_02_local.tga.manceiling03_local.tga -02/24/2007 09:54 PM 786,450 panel_carved_round_dark.tga.manwpanel03.tga -02/24/2007 09:54 PM 786,450 panel_carved_round_dark_local.tga.manwpanel03_local.tga -02/24/2007 10:09 PM 786,476 panel_carved_star.tga.manceiling05.tga -02/24/2007 10:09 PM 786,476 panel_carved_star_dusty.tga.manceiling02.tga -02/24/2007 10:09 PM 786,476 panel_carved_star_dusty_local.tga.manceiling02_local.tga -02/24/2007 10:09 PM 786,476 panel_carved_star_local.tga.manceiling05_local.tga -02/24/2007 09:54 PM 786,476 panel_circle_face.tga.manwpanel05.tga -02/24/2007 09:54 PM 786,476 panel_circle_face_local.tga.manwpanel05_local.tga -02/24/2007 09:54 PM 196,652 panel_decorative_frame.tga.manwpanel07.tga -02/24/2007 09:54 PM 196,652 panel_decorative_frame_local.tga.manwpanel07_local.tga -02/24/2007 09:54 PM 393,260 panel_decorative_frame_long.tga.manwpanel08.tga -02/24/2007 09:54 PM 393,260 panel_decorative_frame_long_local.tga.manwpanel08_local.tga -02/24/2007 09:54 PM 786,476 panel_decorative_rectangles.tga.manwpanel04.tga -02/24/2007 09:54 PM 786,476 panel_decorative_rectangles_local.tga.manwpanel04_local.tga -02/24/2007 09:54 PM 786,476 panel_floral_ornaments.tga.manwall01sh.tga -02/24/2007 09:54 PM 786,476 panel_floral_ornaments_local.tga.manwall01sh_local.tga -02/24/2007 09:54 PM 786,476 panel_floral_ornaments_s.tga.manwall01sh_s.tga -02/24/2007 10:09 PM 786,476 panel_grey.tga.manceiling01.tga -02/24/2007 10:09 PM 786,476 panel_grey_local.tga.manceiling01_local.tga -02/24/2007 09:54 PM 786,476 panel_hammer.tga.manwpanel02.tga -02/24/2007 09:54 PM 786,476 panel_hammer_local.tga.manwpanel02_local.tga -02/24/2007 09:54 PM 262,188 panel_hammer_s.tga.manwpanel02_s.tga -02/24/2007 09:54 PM 196,652 panel_pillar_capital_local.tga.manwcapital01_local.tga -02/24/2007 09:54 PM 393,958 panel_warrior.tga.manwpanel06.tga -02/24/2007 09:54 PM 385,768 panel_warrior_local.tga.manwpanel06_local.tga -02/24/2007 09:54 PM 786,476 thin_panels_with_trim_dark.tga.manwtrim07.tga -02/24/2007 09:54 PM 786,476 thin_panels_with_trim_dark_local.tga.manwtrim07_local.tga -02/24/2007 09:54 PM 786,476 thin_panels_with_trim_light.tga.manwtrim05.tga -02/24/2007 09:54 PM 786,476 thin_panels_with_trim_light_local.tga.manwtrim05_local.tga -04/15/2007 04:12 PM 174,904 tile_pattern_star.dds.tile_decorative_001.dds -04/15/2007 04:10 PM 29,173 tile_pattern_star_ed.jpg.tile_decorative_001_editor.jpg -04/15/2007 04:10 PM 786,476 tile_pattern_star_local.tga.tile_decorative_001_local.tga -04/15/2007 04:12 PM 43,832 tile_pattern_star_s.dds.tile_decorative_001_s.dds -02/25/2007 02:03 AM 174,904 tile_weave.dds.tile_weave_001.dds -02/24/2007 11:04 PM 5,306 tile_weave_ed.jpg.tile_weave_001_editor.jpg -02/24/2007 11:04 PM 786,476 tile_weave_local.tga.tile_weave_001_local.tga -02/25/2007 02:03 AM 174,904 tile_weave_s.dds.tile_weave_001_s.dds -05/31/2007 08:25 PM tiling_1d -02/24/2007 09:54 PM 196,652 trim_carved_long.tga.manwpillar01.tga -02/24/2007 09:54 PM 196,652 trim_carved_long_local.tga.manwpillar01_local.tga -02/24/2007 09:54 PM 393,260 trim_carved_rounded.tga.manwtrim06.tga -02/24/2007 09:54 PM 393,260 trim_carved_rounded_local.tga.manwtrim06_local.tga - 69 File(s) 40,912,205 bytes - - Directory of D:\temp2\textures\darkmod\wood\panels\nontiling - -05/31/2007 08:18 PM . -05/31/2007 08:18 PM .. -04/01/2007 10:54 AM 1,572,908 beam_brown_old_burnt.tga.beam_003_burnt_d.tga -02/25/2007 02:05 AM 349,672 beam_brown_old_endcap.dds.beam_003_endcap_d.DDS -02/24/2007 11:10 PM 98,348 beam_brown_old_endcap_ed.tga.beam_003_endcap_ed.tga -02/24/2007 11:10 PM 1,554,385 beam_brown_old_endcap_local.tga.beam_003_endcap_local.tga -02/25/2007 02:05 AM 43,832 beam_rough_brown_endcap.dds.beam_002_endcap.dds -02/24/2007 11:10 PM 526 beam_rough_brown_endcap_ed.jpg.beam_002_endcap_editor.jpg -02/24/2007 11:10 PM 262,188 beam_rough_endcap_local.tga.beam_002_endcap_local.tga -02/25/2007 02:05 AM 43,832 beam_rough_weathered_endcap.dds.beam_002_weathered_endcap.dds -02/24/2007 11:11 PM 509 beam_rough_weathered_endcap_ed.jpg.beam_002_weathered_endcap_editor.jpg - 9 File(s) 3,926,200 bytes - - Directory of D:\temp2\textures\darkmod\wood\panels\tiling_1d - -05/31/2007 08:25 PM . -05/31/2007 08:25 PM .. -02/24/2007 11:08 PM 729,010 gen_panel_x_pattern.tga.wood_002_d.tga -02/24/2007 11:08 PM 523,332 gen_panel_x_pattern_local.tga.wood_002_local.tga - 2 File(s) 1,252,342 bytes - - Directory of D:\temp2\textures\darkmod\wood\plaster - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. -02/24/2007 10:47 PM 393,260 framed_01.tga.cwall_frame02_d.tga -02/24/2007 10:47 PM 393,260 framed_01_local.tga.cwall_frame02_local.tga -02/24/2007 10:47 PM 393,260 framed_01_s.tga.cwall_frame02_s.tga -02/24/2007 10:47 PM 393,260 framed_02.tga.cwall_frame01_d.tga -02/24/2007 10:47 PM 393,260 framed_02_local.tga.cwall_frame01_local.tga -02/24/2007 10:47 PM 393,260 framed_02_s.tga.cwall_frame01_s.tga -02/24/2007 10:47 PM 524,332 framed_old_01.tga.ctywall03.tga -02/24/2007 10:47 PM 393,260 framed_old_01_local.tga.ctywall03_local.tga -02/24/2007 10:47 PM 524,306 framed_old_decorative_01.tga.ctywall02.tga -02/24/2007 10:47 PM 393,260 framed_old_decorative_01_local.tga.ctywall02_local.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks.tga.cwall_framebrick02_d.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks_02.tga.cwall_framebrick02_d.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks_02_local.tga.cwall_framebrick02_local.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks_02_s.tga.cwall_framebrick02_s.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks_local.tga.cwall_framebrick_local.tga -02/24/2007 10:47 PM 393,260 framed_with_bricks_s.tga.cwall_framebrick_s.tga -05/26/2007 11:48 AM nontiling -02/25/2007 01:13 AM 174,904 panel_decorative_white.dds.plaster_002.dds -02/24/2007 09:42 PM 197,147 panel_decorative_white_ed.tga.plaster_002_editor.tga -02/24/2007 09:42 PM 786,476 panel_decorative_white_local.tga.plaster_002_local.tga -03/14/2007 08:16 PM 524,332 plaster_01.tga.cwall_01.tga -03/14/2007 08:16 PM 524,332 plaster_01_local.tga.cwall_01_local.tga -03/14/2007 08:16 PM 524,332 plaster_01_s.tga.cwall_01_s.tga -02/24/2007 09:54 PM 786,476 stucco_01.tga.manwall02.tga -02/24/2007 09:54 PM 196,626 stucco_01_local.tga.manwall02_local.tga -02/24/2007 09:54 PM 786,476 stucco_01_s.tga.manwall02_s.tga -05/26/2007 11:48 AM tiling_1d - 25 File(s) 11,055,379 bytes - - Directory of D:\temp2\textures\darkmod\wood\plaster\nontiling - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. - 0 File(s) 0 bytes - - Directory of D:\temp2\textures\darkmod\wood\plaster\tiling_1d - -05/26/2007 11:48 AM . -05/26/2007 11:48 AM .. -02/24/2007 10:47 PM 775,127 framed_trim_lions.tga.ctywall04.tga -02/24/2007 10:47 PM 755,322 framed_trim_lions_local.tga.ctywall04_local.tga -02/25/2007 01:13 AM 174,904 plaster_02.dds.plaster_001.dds -02/24/2007 09:42 PM 196,725 plaster_02_ed.tga.plaster_001_editor.tga -02/24/2007 09:42 PM 786,476 plaster_02_local.tga.plaster_001_local.tga -02/24/2007 07:48 PM 788,137 plaster_dirty_01_brown.tga.pagwall01.tga -02/24/2007 07:48 PM 787,921 plaster_dirty_01_grey.tga.pagwall01a.tga -02/24/2007 07:48 PM 787,115 plaster_dirty_01_local.tga.pagwall01_local.tga - 8 File(s) 5,051,727 bytes - - Total Files Listed: - 1001 File(s) 620,161,490 bytes - 356 Dir(s) 97,214,095,360 bytes free diff --git a/sound/OggVorbis/ogg/AUTHORS b/sound/OggVorbis/ogg/AUTHORS new file mode 100644 index 000000000..80c787cb8 --- /dev/null +++ b/sound/OggVorbis/ogg/AUTHORS @@ -0,0 +1,4 @@ +Monty + +and the rest of the Xiph.Org Foundation. + diff --git a/sound/OggVorbis/ogg/COPYING b/sound/OggVorbis/ogg/COPYING new file mode 100644 index 000000000..6111c6c5a --- /dev/null +++ b/sound/OggVorbis/ogg/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sound/OggVorbis/ogg/README b/sound/OggVorbis/ogg/README new file mode 100644 index 000000000..1bbe0aba6 --- /dev/null +++ b/sound/OggVorbis/ogg/README @@ -0,0 +1,103 @@ +******************************************************************** +* * +* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * +* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * +* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * +* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * +* * +* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * +* by the Xiph.Org Foundation http://www.xiph.org/ * +* * +******************************************************************** + +WHAT'S HERE: + +This source distribution includes libogg and nothing else. Other modules +(eg, the modules vorbis, vorbis-tools and vorbis-plugins for the Vorbis +codec) contain the codec libraries for use with Ogg bitstreams. + +Directory: + +./src The source for libogg, a BSD-license inplementation of + the public domain Ogg bitstream format + +./include Library API headers and codebooks + +./debian Rules/spec files for building Debian .deb packages + +./doc Ogg specification documents + +./win32 Win32 projects and build automation + +./mac MacOS 9 projects and build automation + +WHAT IS OGG?: + +Ogg project codecs use the Ogg bitstream format to arrange the raw, +compressed bitstream into a more robust, useful form. For example, +the Ogg bitstream makes seeking, time stamping and error recovery +possible, as well as mixing several sepearate, concurrent media +streams into a single physical bitstream. + +CONTACT: + +The Ogg homepage is located at 'http://www.xiph.org/ogg/'. +Up to date technical documents, contact information, source code and +pre-built utilities may be found there. + +BUILDING FROM CVS: + +A standard cvs build should consist of nothing more than: + +./autogen.sh +make + +and as root if desired : + +make install + +This will install the Ogg libraries (static and shared) into +/usr/local/lib, includes into /usr/local/include and API manpages +(once we write some) into /usr/local/man. + +BUILDING FROM TARBALL DISTRIBUTIONS: + +./configure +make + +and optionally (as root): +make install + +BUILDING RPMS: + +RPMs may be built by: + +make dist +rpm -ta libogg-.tar.gz + +BUILDING ON WIN32: + +Use the project file in the win32 directory. It should compile out of the box. +You can also run one of the batch files from the commandline. + +E.g.: build_ogg_dynamic + +BUILDING ON MACOS 9: + +Ogg on MacOS 9 is built using CodeWarrior 5.3. To build it, first +open ogg/mac/libogg.mcp, switch to the "Targets" pane, select +everything, and make the project. In ogg/mac/Output you will now have +both debug and final versions of Ogg shared libraries to link your +projects against. + +To build a project using Ogg, add access paths to your CodeWarrior +project for the ogg/include and ogg/mac/Output folders. Be sure that +"interpret DOS and Unix paths" is turned on in your project; it can be +found in the "access paths" pane in your project settings. Now simply +add the shared libraries you need to your project (OggLib at least) +and #include "ogg/ogg.h" wherever you need to acces Ogg functionality. + +(Build instructions for Ogg codecs such as vorbis are similar and may +be found in those source modules' README files) + +$Id: README,v 1.10 2002/07/11 09:09:06 xiphmont Exp $ diff --git a/sound/OggVorbis/ogg/config_types.h.in b/sound/OggVorbis/ogg/config_types.h.in new file mode 100644 index 000000000..568a001fd --- /dev/null +++ b/sound/OggVorbis/ogg/config_types.h.in @@ -0,0 +1,11 @@ +#ifndef __CONFIG_TYPES_H__ +#define __CONFIG_TYPES_H__ + +/* these are filled in by configure */ +typedef @SIZE16@ ogg_int16_t; +typedef @USIZE16@ ogg_uint16_t; +typedef @SIZE32@ ogg_int32_t; +typedef @USIZE32@ ogg_uint32_t; +typedef @SIZE64@ ogg_int64_t; + +#endif diff --git a/sound/OggVorbis/ogg/ogg.h b/sound/OggVorbis/ogg/ogg.h new file mode 100644 index 000000000..7f869c0e4 --- /dev/null +++ b/sound/OggVorbis/ogg/ogg.h @@ -0,0 +1,202 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id$ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os_types.h" + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(ogg_page *og); +extern int ogg_page_continued(ogg_page *og); +extern int ogg_page_bos(ogg_page *og); +extern int ogg_page_eos(ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(ogg_page *og); +extern int ogg_page_serialno(ogg_page *og); +extern long ogg_page_pageno(ogg_page *og); +extern int ogg_page_packets(ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ + + + + + + diff --git a/sound/OggVorbis/ogg/os_types.h b/sound/OggVorbis/ogg/os_types.h new file mode 100644 index 000000000..a79771f02 --- /dev/null +++ b/sound/OggVorbis/ogg/os_types.h @@ -0,0 +1,145 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id$ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ + +// using private thread safe memory allocator for DOOM +#if 1 + +#include +#if !__MACH__ && __MWERKS__ +#include +#else +#include +#endif + +void *_decoder_malloc( size_t size ); +void *_decoder_calloc( size_t num, size_t size ); +void *_decoder_realloc( void *memblock, size_t size ); +void _decoder_free( void *memblock ); + +#define _ogg_malloc _decoder_malloc +#define _ogg_calloc _decoder_calloc +#define _ogg_realloc _decoder_realloc +#define _ogg_free _decoder_free + +#else + +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#endif + +#ifdef _WIN32 + +# ifndef __GNUC__ + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; + +#pragma warning(disable : 4018) // signed/unsigned mismatch +#pragma warning(disable : 4146) // unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable : 4244) // conversion to smaller type, possible loss of data +#pragma warning(disable : 4305) // truncation from 'double' to 'float' + +# else + /* Cygwin */ + #include <_G_config.h> + typedef _G_int64_t ogg_int64_t; + typedef _G_int32_t ogg_int32_t; + typedef _G_uint32_t ogg_uint32_t; + typedef _G_int16_t ogg_int16_t; + typedef _G_uint16_t ogg_uint16_t; +# endif + +#elif defined(MACOS_X) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__MACOS__) + +# include + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#else + +# include +//# include +// copied from a system install of config_types.h +/* these are filled in by configure */ +typedef int16_t ogg_int16_t; +typedef u_int16_t ogg_uint16_t; +typedef int32_t ogg_int32_t; +typedef u_int32_t ogg_uint32_t; +typedef int64_t ogg_int64_t; + + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/sound/OggVorbis/oggsrc/bitwise.c b/sound/OggVorbis/oggsrc/bitwise.c new file mode 100644 index 000000000..8467b2e7f --- /dev/null +++ b/sound/OggVorbis/oggsrc/bitwise.c @@ -0,0 +1,782 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: packing variable sized words into an octet stream + last mod: $Id: bitwise.c,v 1.17 2003/11/10 13:06:08 xiphmont Exp $ + + ********************************************************************/ + +/* We're 'LSb' endian; if we write a word but read individual bits, + then we'll read the lsb first */ + +#include +#include +#include "../ogg/ogg.h" + +#define BUFFER_INCREMENT 256 + +static unsigned long mask[]= +{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, + 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, + 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, + 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, + 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, + 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, + 0x3fffffff,0x7fffffff,0xffffffff }; + +static unsigned int mask8B[]= +{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; + +void oggpack_writeinit(oggpack_buffer *b){ + memset(b,0,sizeof(*b)); + b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); + b->buffer[0]='\0'; + b->storage=BUFFER_INCREMENT; +} + +void oggpackB_writeinit(oggpack_buffer *b){ + oggpack_writeinit(b); +} + +void oggpack_writetrunc(oggpack_buffer *b,long bits){ + long bytes=bits>>3; + bits-=bytes*8; + b->ptr=b->buffer+bytes; + b->endbit=bits; + b->endbyte=bytes; + *b->ptr&=mask[bits]; +} + +void oggpackB_writetrunc(oggpack_buffer *b,long bits){ + long bytes=bits>>3; + bits-=bytes*8; + b->ptr=b->buffer+bytes; + b->endbit=bits; + b->endbyte=bytes; + *b->ptr&=mask8B[bits]; +} + +/* Takes only up to 32 bits. */ +void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ + if(b->endbyte+4>=b->storage){ + b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->storage+=BUFFER_INCREMENT; + b->ptr=b->buffer+b->endbyte; + } + + value&=mask[bits]; + bits+=b->endbit; + + b->ptr[0]|=value<endbit; + + if(bits>=8){ + b->ptr[1]=value>>(8-b->endbit); + if(bits>=16){ + b->ptr[2]=value>>(16-b->endbit); + if(bits>=24){ + b->ptr[3]=value>>(24-b->endbit); + if(bits>=32){ + if(b->endbit) + b->ptr[4]=value>>(32-b->endbit); + else + b->ptr[4]=0; + } + } + } + } + + b->endbyte+=bits/8; + b->ptr+=bits/8; + b->endbit=bits&7; +} + +/* Takes only up to 32 bits. */ +void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ + if(b->endbyte+4>=b->storage){ + b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->storage+=BUFFER_INCREMENT; + b->ptr=b->buffer+b->endbyte; + } + + value=(value&mask[bits])<<(32-bits); + bits+=b->endbit; + + b->ptr[0]|=value>>(24+b->endbit); + + if(bits>=8){ + b->ptr[1]=value>>(16+b->endbit); + if(bits>=16){ + b->ptr[2]=value>>(8+b->endbit); + if(bits>=24){ + b->ptr[3]=value>>(b->endbit); + if(bits>=32){ + if(b->endbit) + b->ptr[4]=value<<(8-b->endbit); + else + b->ptr[4]=0; + } + } + } + } + + b->endbyte+=bits/8; + b->ptr+=bits/8; + b->endbit=bits&7; +} + +void oggpack_writealign(oggpack_buffer *b){ + int bits=8-b->endbit; + if(bits<8) + oggpack_write(b,0,bits); +} + +void oggpackB_writealign(oggpack_buffer *b){ + int bits=8-b->endbit; + if(bits<8) + oggpackB_write(b,0,bits); +} + +static void oggpack_writecopy_helper(oggpack_buffer *b, + void *source, + long bits, + void (*w)(oggpack_buffer *, + unsigned long, + int), + int msb){ + unsigned char *ptr=(unsigned char *)source; + + long bytes=bits/8; + bits-=bytes*8; + + if(b->endbit){ + int i; + /* unaligned copy. Do it the hard way. */ + for(i=0;iendbyte+bytes+1>=b->storage){ + b->storage=b->endbyte+bytes+BUFFER_INCREMENT; + b->buffer=_ogg_realloc(b->buffer,b->storage); + b->ptr=b->buffer+b->endbyte; + } + + memmove(b->ptr,source,bytes); + b->ptr+=bytes; + b->buffer+=bytes; + *b->ptr=0; + + } + if(bits){ + if(msb) + w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); + else + w(b,(unsigned long)(ptr[bytes]),bits); + } +} + +void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ + oggpack_writecopy_helper(b,source,bits,oggpack_write,0); +} + +void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ + oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); +} + +void oggpack_reset(oggpack_buffer *b){ + b->ptr=b->buffer; + b->buffer[0]=0; + b->endbit=b->endbyte=0; +} + +void oggpackB_reset(oggpack_buffer *b){ + oggpack_reset(b); +} + +void oggpack_writeclear(oggpack_buffer *b){ + _ogg_free(b->buffer); + memset(b,0,sizeof(*b)); +} + +void oggpackB_writeclear(oggpack_buffer *b){ + oggpack_writeclear(b); +} + +void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ + memset(b,0,sizeof(*b)); + b->buffer=b->ptr=buf; + b->storage=bytes; +} + +void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ + oggpack_readinit(b,buf,bytes); +} + +/* Read in bits without advancing the bitptr; bits <= 32 */ +long oggpack_look(oggpack_buffer *b,int bits){ + unsigned long ret; + unsigned long m=mask[bits]; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + if(b->endbyte*8+bits>b->storage*8)return(-1); + } + + ret=b->ptr[0]>>b->endbit; + if(bits>8){ + ret|=b->ptr[1]<<(8-b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(16-b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(24-b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]<<(32-b->endbit); + } + } + } + return(m&ret); +} + +/* Read in bits without advancing the bitptr; bits <= 32 */ +long oggpackB_look(oggpack_buffer *b,int bits){ + unsigned long ret; + int m=32-bits; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + if(b->endbyte*8+bits>b->storage*8)return(-1); + } + + ret=b->ptr[0]<<(24+b->endbit); + if(bits>8){ + ret|=b->ptr[1]<<(16+b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(8+b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]>>(8-b->endbit); + } + } + } + return (ret>>(m>>1))>>((m+1)>>1); +} + +long oggpack_look1(oggpack_buffer *b){ + if(b->endbyte>=b->storage)return(-1); + return((b->ptr[0]>>b->endbit)&1); +} + +long oggpackB_look1(oggpack_buffer *b){ + if(b->endbyte>=b->storage)return(-1); + return((b->ptr[0]>>(7-b->endbit))&1); +} + +void oggpack_adv(oggpack_buffer *b,int bits){ + bits+=b->endbit; + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; +} + +void oggpackB_adv(oggpack_buffer *b,int bits){ + oggpack_adv(b,bits); +} + +void oggpack_adv1(oggpack_buffer *b){ + if(++(b->endbit)>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } +} + +void oggpackB_adv1(oggpack_buffer *b){ + oggpack_adv1(b); +} + +/* bits <= 32 */ +long oggpack_read(oggpack_buffer *b,int bits){ + unsigned long ret; + unsigned long m=mask[bits]; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + ret=-1UL; + if(b->endbyte*8+bits>b->storage*8)goto overflow; + } + + ret=b->ptr[0]>>b->endbit; + if(bits>8){ + ret|=b->ptr[1]<<(8-b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(16-b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(24-b->endbit); + if(bits>32 && b->endbit){ + ret|=b->ptr[4]<<(32-b->endbit); + } + } + } + } + ret&=m; + + overflow: + + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; + return(ret); +} + +/* bits <= 32 */ +long oggpackB_read(oggpack_buffer *b,int bits){ + unsigned long ret; + long m=32-bits; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + ret=-1UL; + if(b->endbyte*8+bits>b->storage*8)goto overflow; + } + + ret=b->ptr[0]<<(24+b->endbit); + if(bits>8){ + ret|=b->ptr[1]<<(16+b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(8+b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]>>(8-b->endbit); + } + } + } + ret=(ret>>(m>>1))>>((m+1)>>1); + + overflow: + + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; + return(ret); +} + +long oggpack_read1(oggpack_buffer *b){ + unsigned long ret; + + if(b->endbyte>=b->storage){ + /* not the main path */ + ret=-1UL; + goto overflow; + } + + ret=(b->ptr[0]>>b->endbit)&1; + + overflow: + + b->endbit++; + if(b->endbit>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } + return(ret); +} + +long oggpackB_read1(oggpack_buffer *b){ + unsigned long ret; + + if(b->endbyte>=b->storage){ + /* not the main path */ + ret=-1UL; + goto overflow; + } + + ret=(b->ptr[0]>>(7-b->endbit))&1; + + overflow: + + b->endbit++; + if(b->endbit>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } + return(ret); +} + +long oggpack_bytes(oggpack_buffer *b){ + return(b->endbyte+(b->endbit+7)/8); +} + +long oggpack_bits(oggpack_buffer *b){ + return(b->endbyte*8+b->endbit); +} + +long oggpackB_bytes(oggpack_buffer *b){ + return oggpack_bytes(b); +} + +long oggpackB_bits(oggpack_buffer *b){ + return oggpack_bits(b); +} + +unsigned char *oggpack_get_buffer(oggpack_buffer *b){ + return(b->buffer); +} + +unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ + return oggpack_get_buffer(b); +} + +/* Self test of the bitwise routines; everything else is based on + them, so they damned well better be solid. */ + +#ifdef _V_SELFTEST +#include + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +oggpack_buffer o; +oggpack_buffer r; + +void report(char *in){ + fprintf(stderr,"%s",in); + exit(1); +} + +void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ + long bytes,i; + unsigned char *buffer; + + oggpack_reset(&o); + for(i=0;i +#include +#include "../ogg/ogg.h" + +/* A complete description of Ogg framing exists in docs/framing.html */ + +int ogg_page_version(ogg_page *og){ + return((int)(og->header[4])); +} + +int ogg_page_continued(ogg_page *og){ + return((int)(og->header[5]&0x01)); +} + +int ogg_page_bos(ogg_page *og){ + return((int)(og->header[5]&0x02)); +} + +int ogg_page_eos(ogg_page *og){ + return((int)(og->header[5]&0x04)); +} + +ogg_int64_t ogg_page_granulepos(ogg_page *og){ + unsigned char *page=og->header; + ogg_int64_t granulepos=page[13]&(0xff); + granulepos= (granulepos<<8)|(page[12]&0xff); + granulepos= (granulepos<<8)|(page[11]&0xff); + granulepos= (granulepos<<8)|(page[10]&0xff); + granulepos= (granulepos<<8)|(page[9]&0xff); + granulepos= (granulepos<<8)|(page[8]&0xff); + granulepos= (granulepos<<8)|(page[7]&0xff); + granulepos= (granulepos<<8)|(page[6]&0xff); + return(granulepos); +} + +int ogg_page_serialno(ogg_page *og){ + return(og->header[14] | + (og->header[15]<<8) | + (og->header[16]<<16) | + (og->header[17]<<24)); +} + +long ogg_page_pageno(ogg_page *og){ + return(og->header[18] | + (og->header[19]<<8) | + (og->header[20]<<16) | + (og->header[21]<<24)); +} + + + +/* returns the number of packets that are completed on this page (if + the leading packet is begun on a previous page, but ends on this + page, it's counted */ + +/* NOTE: +If a page consists of a packet begun on a previous page, and a new +packet begun (but not completed) on this page, the return will be: + ogg_page_packets(page) ==1, + ogg_page_continued(page) !=0 + +If a page happens to be a single packet that was begun on a +previous page, and spans to the next page (in the case of a three or +more page packet), the return will be: + ogg_page_packets(page) ==0, + ogg_page_continued(page) !=0 +*/ + +int ogg_page_packets(ogg_page *og){ + int i,n=og->header[26],count=0; + for(i=0;iheader[27+i]<255)count++; + return(count); +} + + +#if 0 +/* helper to initialize lookup for direct-table CRC (illustrative; we + use the static init below) */ + +static ogg_uint32_t _ogg_crc_entry(unsigned long index){ + int i; + unsigned long r; + + r = index << 24; + for (i=0; i<8; i++) + if (r & 0x80000000UL) + r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator + polynomial, although we use an + unreflected alg and an init/final + of 0, not 0xffffffff */ + else + r<<=1; + return (r & 0xffffffffUL); +} +#endif + +static ogg_uint32_t crc_lookup[256]={ + 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9, + 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, + 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, + 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, + 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9, + 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, + 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011, + 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, + 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, + 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, + 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81, + 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, + 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49, + 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, + 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, + 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, + 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae, + 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, + 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16, + 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, + 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, + 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, + 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066, + 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, + 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e, + 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, + 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, + 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, + 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e, + 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, + 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686, + 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, + 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, + 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, + 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f, + 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, + 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47, + 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, + 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, + 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, + 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7, + 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, + 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f, + 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, + 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, + 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, + 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f, + 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, + 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640, + 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, + 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, + 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, + 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30, + 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, + 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088, + 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, + 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, + 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, + 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18, + 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, + 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0, + 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, + 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, + 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4}; + +/* init the encode/decode logical stream state */ + +int ogg_stream_init(ogg_stream_state *os,int serialno){ + if(os){ + memset(os,0,sizeof(*os)); + // lowered for DOOM + os->body_storage=8*1024; + os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data)); + + os->lacing_storage=1024; + os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals)); + + os->serialno=serialno; + + return(0); + } + return(-1); +} + +/* _clear does not free os, only the non-flat storage within */ +int ogg_stream_clear(ogg_stream_state *os){ + if(os){ + if(os->body_data)_ogg_free(os->body_data); + if(os->lacing_vals)_ogg_free(os->lacing_vals); + if(os->granule_vals)_ogg_free(os->granule_vals); + + memset(os,0,sizeof(*os)); + } + return(0); +} + +int ogg_stream_destroy(ogg_stream_state *os){ + if(os){ + ogg_stream_clear(os); + _ogg_free(os); + } + return(0); +} + +/* Helpers for ogg_stream_encode; this keeps the structure and + what's happening fairly clear */ + +static void _os_body_expand(ogg_stream_state *os,int needed){ + if(os->body_storage<=os->body_fill+needed){ + os->body_storage+=(needed+1024); + os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data)); + } +} + +static void _os_lacing_expand(ogg_stream_state *os,int needed){ + if(os->lacing_storage<=os->lacing_fill+needed){ + os->lacing_storage+=(needed+32); + os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals)); + } +} + +/* checksum the page */ +/* Direct table CRC; note that this will be faster in the future if we + perform the checksum silmultaneously with other copies */ + +void ogg_page_checksum_set(ogg_page *og){ + if(og){ + ogg_uint32_t crc_reg=0; + int i; + + /* safety; needed for API behavior, but not framing code */ + og->header[22]=0; + og->header[23]=0; + og->header[24]=0; + og->header[25]=0; + + for(i=0;iheader_len;i++) + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]]; + for(i=0;ibody_len;i++) + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]]; + + og->header[22]=crc_reg&0xff; + og->header[23]=(crc_reg>>8)&0xff; + og->header[24]=(crc_reg>>16)&0xff; + og->header[25]=(crc_reg>>24)&0xff; + } +} + +/* submit data to the internal buffer of the framing engine */ +int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ + int lacing_vals=op->bytes/255+1,i; + + if(os->body_returned){ + /* advance packet data according to the body_returned pointer. We + had to keep it around to return a pointer into the buffer last + call */ + + os->body_fill-=os->body_returned; + if(os->body_fill) + memmove(os->body_data,os->body_data+os->body_returned, + os->body_fill); + os->body_returned=0; + } + + /* make sure we have the buffer storage */ + _os_body_expand(os,op->bytes); + _os_lacing_expand(os,lacing_vals); + + /* Copy in the submitted packet. Yes, the copy is a waste; this is + the liability of overly clean abstraction for the time being. It + will actually be fairly easy to eliminate the extra copy in the + future */ + + memcpy(os->body_data+os->body_fill,op->packet,op->bytes); + os->body_fill+=op->bytes; + + /* Store lacing vals for this packet */ + for(i=0;ilacing_vals[os->lacing_fill+i]=255; + os->granule_vals[os->lacing_fill+i]=os->granulepos; + } + os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255; + os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos; + + /* flag the first segment as the beginning of the packet */ + os->lacing_vals[os->lacing_fill]|= 0x100; + + os->lacing_fill+=lacing_vals; + + /* for the sake of completeness */ + os->packetno++; + + if(op->e_o_s)os->e_o_s=1; + + return(0); +} + +/* This will flush remaining packets into a page (returning nonzero), + even if there is not enough data to trigger a flush normally + (undersized page). If there are no packets or partial packets to + flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will + try to flush a normal sized page like ogg_stream_pageout; a call to + ogg_stream_flush does not guarantee that all packets have flushed. + Only a return value of 0 from ogg_stream_flush indicates all packet + data is flushed into pages. + + since ogg_stream_flush will flush the last page in a stream even if + it's undersized, you almost certainly want to use ogg_stream_pageout + (and *not* ogg_stream_flush) unless you specifically need to flush + an page regardless of size in the middle of a stream. */ + +int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ + int i; + int vals=0; + int maxvals=(os->lacing_fill>255?255:os->lacing_fill); + int bytes=0; + long acc=0; + ogg_int64_t granule_pos=os->granule_vals[0]; + + if(maxvals==0)return(0); + + /* construct a page */ + /* decide how many segments to include */ + + /* If this is the initial header case, the first page must only include + the initial header packet */ + if(os->b_o_s==0){ /* 'initial header page' case */ + granule_pos=0; + for(vals=0;valslacing_vals[vals]&0x0ff)<255){ + vals++; + break; + } + } + }else{ + for(vals=0;vals4096)break; + acc+=os->lacing_vals[vals]&0x0ff; + granule_pos=os->granule_vals[vals]; + } + } + + /* construct the header in temp storage */ + memcpy(os->header,"OggS",4); + + /* stream structure version */ + os->header[4]=0x00; + + /* continued packet flag? */ + os->header[5]=0x00; + if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01; + /* first page flag? */ + if(os->b_o_s==0)os->header[5]|=0x02; + /* last page flag? */ + if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04; + os->b_o_s=1; + + /* 64 bits of PCM position */ + for(i=6;i<14;i++){ + os->header[i]=(granule_pos&0xff); + granule_pos>>=8; + } + + /* 32 bits of stream serial number */ + { + long serialno=os->serialno; + for(i=14;i<18;i++){ + os->header[i]=(serialno&0xff); + serialno>>=8; + } + } + + /* 32 bits of page counter (we have both counter and page header + because this val can roll over) */ + if(os->pageno==-1)os->pageno=0; /* because someone called + stream_reset; this would be a + strange thing to do in an + encode stream, but it has + plausible uses */ + { + long pageno=os->pageno++; + for(i=18;i<22;i++){ + os->header[i]=(pageno&0xff); + pageno>>=8; + } + } + + /* zero for computation; filled in later */ + os->header[22]=0; + os->header[23]=0; + os->header[24]=0; + os->header[25]=0; + + /* segment table */ + os->header[26]=vals&0xff; + for(i=0;iheader[i+27]=(os->lacing_vals[i]&0xff); + + /* set pointers in the ogg_page struct */ + og->header=os->header; + og->header_len=os->header_fill=vals+27; + og->body=os->body_data+os->body_returned; + og->body_len=bytes; + + /* advance the lacing data and set the body_returned pointer */ + + os->lacing_fill-=vals; + memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals)); + memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals)); + os->body_returned+=bytes; + + /* calculate the checksum */ + + ogg_page_checksum_set(og); + + /* done */ + return(1); +} + + +/* This constructs pages from buffered packet segments. The pointers +returned are to static buffers; do not free. The returned buffers are +good only until the next call (using the same ogg_stream_state) */ + +int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ + + if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ + os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */ + os->lacing_fill>=255 || /* 'segment table full' case */ + (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */ + + return(ogg_stream_flush(os,og)); + } + + /* not enough data to construct a page and not end of stream */ + return(0); +} + +int ogg_stream_eos(ogg_stream_state *os){ + return os->e_o_s; +} + +/* DECODING PRIMITIVES: packet streaming layer **********************/ + +/* This has two layers to place more of the multi-serialno and paging + control in the application's hands. First, we expose a data buffer + using ogg_sync_buffer(). The app either copies into the + buffer, or passes it directly to read(), etc. We then call + ogg_sync_wrote() to tell how many bytes we just added. + + Pages are returned (pointers into the buffer in ogg_sync_state) + by ogg_sync_pageout(). The page is then submitted to + ogg_stream_pagein() along with the appropriate + ogg_stream_state* (ie, matching serialno). We then get raw + packets out calling ogg_stream_packetout() with a + ogg_stream_state. See the 'frame-prog.txt' docs for details and + example code. */ + +/* initialize the struct to a known state */ +int ogg_sync_init(ogg_sync_state *oy){ + if(oy){ + memset(oy,0,sizeof(*oy)); + } + return(0); +} + +/* clear non-flat storage within */ +int ogg_sync_clear(ogg_sync_state *oy){ + if(oy){ + if(oy->data)_ogg_free(oy->data); + ogg_sync_init(oy); + } + return(0); +} + +int ogg_sync_destroy(ogg_sync_state *oy){ + if(oy){ + ogg_sync_clear(oy); + _ogg_free(oy); + } + return(0); +} + +char *ogg_sync_buffer(ogg_sync_state *oy, long size){ + + /* first, clear out any space that has been previously returned */ + if(oy->returned){ + oy->fill-=oy->returned; + if(oy->fill>0) + memmove(oy->data,oy->data+oy->returned,oy->fill); + oy->returned=0; + } + + if(size>oy->storage-oy->fill){ + /* We need to extend the internal buffer */ + long newsize=size+oy->fill+4096; /* an extra page to be nice */ + + if(oy->data) + oy->data=_ogg_realloc(oy->data,newsize); + else + oy->data=_ogg_malloc(newsize); + oy->storage=newsize; + } + + /* expose a segment at least as large as requested at the fill mark */ + return((char *)oy->data+oy->fill); +} + +int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ + if(oy->fill+bytes>oy->storage)return(-1); + oy->fill+=bytes; + return(0); +} + +/* sync the stream. This is meant to be useful for finding page + boundaries. + + return values for this: + -n) skipped n bytes + 0) page not ready; more data (no bytes skipped) + n) page synced at current location; page length n bytes + +*/ + +long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ + unsigned char *page=oy->data+oy->returned; + unsigned char *next; + long bytes=oy->fill-oy->returned; + + if(oy->headerbytes==0){ + int headerbytes,i; + if(bytes<27)return(0); /* not enough for a header */ + + /* verify capture pattern */ + if(memcmp(page,"OggS",4))goto sync_fail; + + headerbytes=page[26]+27; + if(bytesbodybytes+=page[27+i]; + oy->headerbytes=headerbytes; + } + + if(oy->bodybytes+oy->headerbytes>bytes)return(0); + + /* The whole test page is buffered. Verify the checksum */ + { + /* Grab the checksum bytes, set the header field to zero */ + char chksum[4]; + ogg_page log; + + memcpy(chksum,page+22,4); + memset(page+22,0,4); + + /* set up a temp page struct and recompute the checksum */ + log.header=page; + log.header_len=oy->headerbytes; + log.body=page+oy->headerbytes; + log.body_len=oy->bodybytes; + ogg_page_checksum_set(&log); + + /* Compare */ + if(memcmp(chksum,page+22,4)){ + /* D'oh. Mismatch! Corrupt page (or miscapture and not a page + at all) */ + /* replace the computed checksum with the one actually read in */ + memcpy(page+22,chksum,4); + + /* Bad checksum. Lose sync */ + goto sync_fail; + } + } + + /* yes, have a whole page all ready to go */ + { + unsigned char *page=oy->data+oy->returned; + long bytes; + + if(og){ + og->header=page; + og->header_len=oy->headerbytes; + og->body=page+oy->headerbytes; + og->body_len=oy->bodybytes; + } + + oy->unsynced=0; + oy->returned+=(bytes=oy->headerbytes+oy->bodybytes); + oy->headerbytes=0; + oy->bodybytes=0; + return(bytes); + } + + sync_fail: + + oy->headerbytes=0; + oy->bodybytes=0; + + /* search for possible capture */ + next=memchr(page+1,'O',bytes-1); + if(!next) + next=oy->data+oy->fill; + + oy->returned=next-oy->data; + return(-(next-page)); +} + +/* sync the stream and get a page. Keep trying until we find a page. + Supress 'sync errors' after reporting the first. + + return values: + -1) recapture (hole in data) + 0) need more data + 1) page returned + + Returns pointers into buffered data; invalidated by next call to + _stream, _clear, _init, or _buffer */ + +int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ + + /* all we need to do is verify a page at the head of the stream + buffer. If it doesn't verify, we look for the next potential + frame */ + + while(1){ + long ret=ogg_sync_pageseek(oy,og); + if(ret>0){ + /* have a page */ + return(1); + } + if(ret==0){ + /* need more data */ + return(0); + } + + /* head did not start a synced page... skipped some bytes */ + if(!oy->unsynced){ + oy->unsynced=1; + return(-1); + } + + /* loop. keep looking */ + + } +} + +/* add the incoming page to the stream state; we decompose the page + into packet segments here as well. */ + +int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ + unsigned char *header=og->header; + unsigned char *body=og->body; + long bodysize=og->body_len; + int segptr=0; + + int version=ogg_page_version(og); + int continued=ogg_page_continued(og); + int bos=ogg_page_bos(og); + int eos=ogg_page_eos(og); + ogg_int64_t granulepos=ogg_page_granulepos(og); + int serialno=ogg_page_serialno(og); + long pageno=ogg_page_pageno(og); + int segments=header[26]; + + /* clean up 'returned data' */ + { + long lr=os->lacing_returned; + long br=os->body_returned; + + /* body data */ + if(br){ + os->body_fill-=br; + if(os->body_fill) + memmove(os->body_data,os->body_data+br,os->body_fill); + os->body_returned=0; + } + + if(lr){ + /* segment table */ + if(os->lacing_fill-lr){ + memmove(os->lacing_vals,os->lacing_vals+lr, + (os->lacing_fill-lr)*sizeof(*os->lacing_vals)); + memmove(os->granule_vals,os->granule_vals+lr, + (os->lacing_fill-lr)*sizeof(*os->granule_vals)); + } + os->lacing_fill-=lr; + os->lacing_packet-=lr; + os->lacing_returned=0; + } + } + + /* check the serial number */ + if(serialno!=os->serialno)return(-1); + if(version>0)return(-1); + + _os_lacing_expand(os,segments+1); + + /* are we in sequence? */ + if(pageno!=os->pageno){ + int i; + + /* unroll previous partial packet (if any) */ + for(i=os->lacing_packet;ilacing_fill;i++) + os->body_fill-=os->lacing_vals[i]&0xff; + os->lacing_fill=os->lacing_packet; + + /* make a note of dropped data in segment table */ + if(os->pageno!=-1){ + os->lacing_vals[os->lacing_fill++]=0x400; + os->lacing_packet++; + } + + /* are we a 'continued packet' page? If so, we'll need to skip + some segments */ + if(continued){ + bos=0; + for(;segptrbody_data+os->body_fill,body,bodysize); + os->body_fill+=bodysize; + } + + { + int saved=-1; + while(segptrlacing_vals[os->lacing_fill]=val; + os->granule_vals[os->lacing_fill]=-1; + + if(bos){ + os->lacing_vals[os->lacing_fill]|=0x100; + bos=0; + } + + if(val<255)saved=os->lacing_fill; + + os->lacing_fill++; + segptr++; + + if(val<255)os->lacing_packet=os->lacing_fill; + } + + /* set the granulepos on the last granuleval of the last full packet */ + if(saved!=-1){ + os->granule_vals[saved]=granulepos; + } + + } + + if(eos){ + os->e_o_s=1; + if(os->lacing_fill>0) + os->lacing_vals[os->lacing_fill-1]|=0x200; + } + + os->pageno=pageno+1; + + return(0); +} + +/* clear things to an initial state. Good to call, eg, before seeking */ +int ogg_sync_reset(ogg_sync_state *oy){ + oy->fill=0; + oy->returned=0; + oy->unsynced=0; + oy->headerbytes=0; + oy->bodybytes=0; + return(0); +} + +int ogg_stream_reset(ogg_stream_state *os){ + os->body_fill=0; + os->body_returned=0; + + os->lacing_fill=0; + os->lacing_packet=0; + os->lacing_returned=0; + + os->header_fill=0; + + os->e_o_s=0; + os->b_o_s=0; + os->pageno=-1; + os->packetno=0; + os->granulepos=0; + + return(0); +} + +int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){ + ogg_stream_reset(os); + os->serialno=serialno; + return(0); +} + +static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){ + + /* The last part of decode. We have the stream broken into packet + segments. Now we need to group them into packets (or return the + out of sync markers) */ + + int ptr=os->lacing_returned; + + if(os->lacing_packet<=ptr)return(0); + + if(os->lacing_vals[ptr]&0x400){ + /* we need to tell the codec there's a gap; it might need to + handle previous packet dependencies. */ + os->lacing_returned++; + os->packetno++; + return(-1); + } + + if(!op && !adv)return(1); /* just using peek as an inexpensive way + to ask if there's a whole packet + waiting */ + + /* Gather the whole packet. We'll have no holes or a partial packet */ + { + int size=os->lacing_vals[ptr]&0xff; + int bytes=size; + int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */ + int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */ + + while(size==255){ + int val=os->lacing_vals[++ptr]; + size=val&0xff; + if(val&0x200)eos=0x200; + bytes+=size; + } + + if(op){ + op->e_o_s=eos; + op->b_o_s=bos; + op->packet=os->body_data+os->body_returned; + op->packetno=os->packetno; + op->granulepos=os->granule_vals[ptr]; + op->bytes=bytes; + } + + if(adv){ + os->body_returned+=bytes; + os->lacing_returned=ptr+1; + os->packetno++; + } + } + return(1); +} + +int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,1); +} + +int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,0); +} + +void ogg_packet_clear(ogg_packet *op) { + _ogg_free(op->packet); + memset(op, 0, sizeof(*op)); +} + +#ifdef _V_SELFTEST +#include + +ogg_stream_state os_en, os_de; +ogg_sync_state oy; + +void checkpacket(ogg_packet *op,int len, int no, int pos){ + long j; + static int sequence=0; + static int lastno=0; + + if(op->bytes!=len){ + fprintf(stderr,"incorrect packet length!\n"); + exit(1); + } + if(op->granulepos!=pos){ + fprintf(stderr,"incorrect packet position!\n"); + exit(1); + } + + /* packet number just follows sequence/gap; adjust the input number + for that */ + if(no==0){ + sequence=0; + }else{ + sequence++; + if(no>lastno+1) + sequence++; + } + lastno=no; + if(op->packetno!=sequence){ + fprintf(stderr,"incorrect packet sequence %ld != %d\n", + (long)(op->packetno),sequence); + exit(1); + } + + /* Test data */ + for(j=0;jbytes;j++) + if(op->packet[j]!=((j+no)&0xff)){ + fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n", + j,op->packet[j],(j+no)&0xff); + exit(1); + } +} + +void check_page(unsigned char *data,const int *header,ogg_page *og){ + long j; + /* Test data */ + for(j=0;jbody_len;j++) + if(og->body[j]!=data[j]){ + fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n", + j,data[j],og->body[j]); + exit(1); + } + + /* Test header */ + for(j=0;jheader_len;j++){ + if(og->header[j]!=header[j]){ + fprintf(stderr,"header content mismatch at pos %ld:\n",j); + for(j=0;jheader[j]); + fprintf(stderr,"\n"); + exit(1); + } + } + if(og->header_len!=header[26]+27){ + fprintf(stderr,"header length incorrect! (%ld!=%d)\n", + og->header_len,header[26]+27); + exit(1); + } +} + +void print_header(ogg_page *og){ + int j; + fprintf(stderr,"\nHEADER:\n"); + fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n", + og->header[0],og->header[1],og->header[2],og->header[3], + (int)og->header[4],(int)og->header[5]); + + fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", + (og->header[9]<<24)|(og->header[8]<<16)| + (og->header[7]<<8)|og->header[6], + (og->header[17]<<24)|(og->header[16]<<16)| + (og->header[15]<<8)|og->header[14], + ((long)(og->header[21])<<24)|(og->header[20]<<16)| + (og->header[19]<<8)|og->header[18]); + + fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", + (int)og->header[22],(int)og->header[23], + (int)og->header[24],(int)og->header[25], + (int)og->header[26]); + + for(j=27;jheader_len;j++) + fprintf(stderr,"%d ",(int)og->header[j]); + fprintf(stderr,")\n\n"); +} + +void copy_page(ogg_page *og){ + unsigned char *temp=_ogg_malloc(og->header_len); + memcpy(temp,og->header,og->header_len); + og->header=temp; + + temp=_ogg_malloc(og->body_len); + memcpy(temp,og->body,og->body_len); + og->body=temp; +} + +void error(void){ + fprintf(stderr,"error!\n"); + exit(1); +} + +/* 17 only */ +const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x15,0xed,0xec,0x91, + 1, + 17}; + +/* 17, 254, 255, 256, 500, 510, 600 byte, pad */ +const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x59,0x10,0x6c,0x2c, + 1, + 17}; +const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x89,0x33,0x85,0xce, + 13, + 254,255,0,255,1,255,245,255,255,0, + 255,255,90}; + +/* nil packets; beginning,middle,end */ +const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; +const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x5c,0x3f,0x66,0xcb, + 17, + 17,254,255,0,0,255,1,0,255,245,255,255,0, + 255,255,90,0}; + +/* large initial packet */ +const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x01,0x27,0x31,0xaa, + 18, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,10}; + +const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x7f,0x4e,0x8a,0xd2, + 4, + 255,4,255,0}; + + +/* continuing packet test */ +const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x34,0x24,0xd5,0x29, + 17, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255}; + +const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0xc8,0xc3,0xcb,0xed, + 5, + 10,255,4,255,0}; + + +/* page with the 255 segment limit */ +const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0xed,0x2a,0x2e,0xa7, + 255, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10}; + +const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0x6c,0x3b,0x82,0x3d, + 1, + 50}; + + +/* packet that overspans over an entire page */ +const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x3c,0xd9,0x4d,0x3f, + 17, + 100,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255}; + +const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01, + 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0xbd,0xd5,0xb5,0x8b, + 17, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255}; + +const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,3,0,0,0, + 0xef,0xdd,0x88,0xde, + 7, + 255,255,75,255,4,255,0}; + +/* packet that overspans over an entire page */ +const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x3c,0xd9,0x4d,0x3f, + 17, + 100,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255}; + +const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0xd4,0xe0,0x60,0xe5, + 1,0}; + +void test_pack(const int *pl, const int **headers){ + unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ + long inptr=0; + long outptr=0; + long deptr=0; + long depacket=0; + long granule_pos=7,pageno=0; + int i,j,packets,pageout=0; + int eosflag=0; + int bosflag=0; + + ogg_stream_reset(&os_en); + ogg_stream_reset(&os_de); + ogg_sync_reset(&oy); + + for(packets=0;;packets++)if(pl[packets]==-1)break; + + for(i=0;i0){ + /* got a page. Happy happy. Verify that it's good. */ + + check_page(data+deptr,headers[pageout],&og_de); + deptr+=og_de.body_len; + pageout++; + + /* submit it to deconstitution */ + ogg_stream_pagein(&os_de,&og_de); + + /* packets out? */ + while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ + ogg_stream_packetpeek(&os_de,NULL); + ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ + + /* verify peek and out match */ + if(memcmp(&op_de,&op_de2,sizeof(op_de))){ + fprintf(stderr,"packetout != packetpeek! pos=%ld\n", + depacket); + exit(1); + } + + /* verify the packet! */ + /* check data */ + if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ + fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", + depacket); + exit(1); + } + /* check bos flag */ + if(bosflag==0 && op_de.b_o_s==0){ + fprintf(stderr,"b_o_s flag not set on packet!\n"); + exit(1); + } + if(bosflag && op_de.b_o_s){ + fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); + exit(1); + } + bosflag=1; + depacket+=op_de.bytes; + + /* check eos flag */ + if(eosflag){ + fprintf(stderr,"Multiple decoded packets with eos flag!\n"); + exit(1); + } + + if(op_de.e_o_s)eosflag=1; + + /* check granulepos flag */ + if(op_de.granulepos!=-1){ + fprintf(stderr," granule:%ld ",(long)op_de.granulepos); + } + } + } + } + } + } + } + _ogg_free(data); + if(headers[pageno]!=NULL){ + fprintf(stderr,"did not write last page!\n"); + exit(1); + } + if(headers[pageout]!=NULL){ + fprintf(stderr,"did not decode last page!\n"); + exit(1); + } + if(inptr!=outptr){ + fprintf(stderr,"encoded page data incomplete!\n"); + exit(1); + } + if(inptr!=deptr){ + fprintf(stderr,"decoded page data incomplete!\n"); + exit(1); + } + if(inptr!=depacket){ + fprintf(stderr,"decoded packet data incomplete!\n"); + exit(1); + } + if(!eosflag){ + fprintf(stderr,"Never got a packet with EOS set!\n"); + exit(1); + } + fprintf(stderr,"ok.\n"); +} + +int main(void){ + + ogg_stream_init(&os_en,0x04030201); + ogg_stream_init(&os_de,0x04030201); + ogg_sync_init(&oy); + + /* Exercise each code path in the framing code. Also verify that + the checksums are working. */ + + { + /* 17 only */ + const int packets[]={17, -1}; + const int *headret[]={head1_0,NULL}; + + fprintf(stderr,"testing single page encoding... "); + test_pack(packets,headret); + } + + { + /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ + const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; + const int *headret[]={head1_1,head2_1,NULL}; + + fprintf(stderr,"testing basic page encoding... "); + test_pack(packets,headret); + } + + { + /* nil packets; beginning,middle,end */ + const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; + const int *headret[]={head1_2,head2_2,NULL}; + + fprintf(stderr,"testing basic nil packets... "); + test_pack(packets,headret); + } + + { + /* large initial packet */ + const int packets[]={4345,259,255,-1}; + const int *headret[]={head1_3,head2_3,NULL}; + + fprintf(stderr,"testing initial-packet lacing > 4k... "); + test_pack(packets,headret); + } + + { + /* continuing packet test */ + const int packets[]={0,4345,259,255,-1}; + const int *headret[]={head1_4,head2_4,head3_4,NULL}; + + fprintf(stderr,"testing single packet page span... "); + test_pack(packets,headret); + } + + /* page with the 255 segment limit */ + { + + const int packets[]={0,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,50,-1}; + const int *headret[]={head1_5,head2_5,head3_5,NULL}; + + fprintf(stderr,"testing max packet segments... "); + test_pack(packets,headret); + } + + { + /* packet that overspans over an entire page */ + const int packets[]={0,100,9000,259,255,-1}; + const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; + + fprintf(stderr,"testing very large packets... "); + test_pack(packets,headret); + } + + { + /* term only page. why not? */ + const int packets[]={0,100,4080,-1}; + const int *headret[]={head1_7,head2_7,head3_7,NULL}; + + fprintf(stderr,"testing zero data page (1 nil packet)... "); + test_pack(packets,headret); + } + + + + { + /* build a bunch of pages for testing */ + unsigned char *data=_ogg_malloc(1024*1024); + int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1}; + int inptr=0,i,j; + ogg_page og[5]; + + ogg_stream_reset(&os_en); + + for(i=0;pl[i]!=-1;i++){ + ogg_packet op; + int len=pl[i]; + + op.packet=data+inptr; + op.bytes=len; + op.e_o_s=(pl[i+1]<0?1:0); + op.granulepos=(i+1)*1000; + + for(j=0;j0)error(); + + /* Test fractional page inputs: incomplete fixed header */ + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + /* Test fractional page inputs: incomplete header */ + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, + 5); + ogg_sync_wrote(&oy,5); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + /* Test fractional page inputs: incomplete body */ + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, + og[1].header_len-28); + ogg_sync_wrote(&oy,og[1].header_len-28); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); + ogg_sync_wrote(&oy,1000); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, + og[1].body_len-1000); + ogg_sync_wrote(&oy,og[1].body_len-1000); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test fractional page inputs: page + incomplete capture */ + { + ogg_page og_de; + fprintf(stderr,"Testing sync on 1+partial inputs... "); + ogg_sync_reset(&oy); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20, + og[1].header_len-20); + ogg_sync_wrote(&oy,og[1].header_len-20); + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test recapture: garbage + page */ + { + ogg_page og_de; + fprintf(stderr,"Testing search for capture... "); + ogg_sync_reset(&oy); + + /* 'garbage' */ + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20, + og[2].header_len-20); + ogg_sync_wrote(&oy,og[2].header_len-20); + memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, + og[2].body_len); + ogg_sync_wrote(&oy,og[2].body_len); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test recapture: page + garbage + page */ + { + ogg_page og_de; + fprintf(stderr,"Testing recapture... "); + ogg_sync_reset(&oy); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + og[2].header_len); + ogg_sync_wrote(&oy,og[2].header_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + og[2].header_len); + ogg_sync_wrote(&oy,og[2].header_len); + + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, + og[2].body_len-5); + ogg_sync_wrote(&oy,og[2].body_len-5); + + memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header, + og[3].header_len); + ogg_sync_wrote(&oy,og[3].header_len); + + memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body, + og[3].body_len); + ogg_sync_wrote(&oy,og[3].body_len); + + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + } + + return(0); +} + +#endif + + + + diff --git a/sound/OggVorbis/version.txt b/sound/OggVorbis/version.txt new file mode 100644 index 000000000..b29125176 --- /dev/null +++ b/sound/OggVorbis/version.txt @@ -0,0 +1,6 @@ +libogg 1.0.1 (libogg-1.1.zip) +libvorbis 1.0.1 (libvorbis-1.0.1.zip) + +ogg/os_types.h has been modified to redirect memory allocations to the DOOM3 _decoder_ allocator. + +vorbis/vorbisfile.h has been modified to add a "int stream;" to the OggVorbis_File structure. diff --git a/sound/OggVorbis/vorbis/AUTHORS b/sound/OggVorbis/vorbis/AUTHORS new file mode 100644 index 000000000..0da10363c --- /dev/null +++ b/sound/OggVorbis/vorbis/AUTHORS @@ -0,0 +1,3 @@ +Monty + +and the rest of the Xiph.org Foundation. diff --git a/sound/OggVorbis/vorbis/COPYING b/sound/OggVorbis/vorbis/COPYING new file mode 100644 index 000000000..6111c6c5a --- /dev/null +++ b/sound/OggVorbis/vorbis/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sound/OggVorbis/vorbis/README b/sound/OggVorbis/vorbis/README new file mode 100644 index 000000000..e242ead12 --- /dev/null +++ b/sound/OggVorbis/vorbis/README @@ -0,0 +1,140 @@ +******************************************************************** +* * +* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * +* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * +* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * +* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * +* * +* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * +* by the Xiph.org Foundation, http://www.xiph.org/ * +* * +******************************************************************** + +NEW AND IMPORTANT: + +If you're used to the source distribution from the first two beta +releases, things are now rearranged a bit. Specifically, the +'vorbis' CVS module contains only the libvorbis, libvorbisfile, and +libvorbisenc libraries. Because Ogg bitstreams are to be used by other +Ogg codecs, Ogg framing and streaming functionality is now in libogg +(the 'ogg' CVS module). Vorbis utilities are in 'vorbis-tools' and various +player plugins are in 'vorbis-plugins'. For now, you'll need to check +out these other modules seperately. (Note: the xmms plugin is in the xmms +CVS tree in xmms/Input/vorbis.) + +Secondly, the Ogg/Vorbis build systems now use automake. Instead of +'./configure; make', the proper build sequence (in each module) is +'./autogen.sh; make'. + +You will also need the newest versions of autoconf, automake, and libtool +in order to compile vorbis from CVS. configure scripts are provided for you +in tarball distributions. + +WHAT'S HERE: + +This source distribution includes libvorbis and an example +encoder/player to demonstrate use of libvorbis and documentation on +the Ogg Vorbis audio coding format. + +Directory: + +./lib The source for the libraries, a BSD-license implementation + of the public domain Ogg Vorbis audio encoding format. + +./include Library API headers + +./debian Rules/spec files for building Debian .deb packages + +./doc Vorbis documentation + +./examples Example code illustrating programmatic use of libvorbis, + libvorbisfile and libvorbisenc + +./mac Codewarrior project files and build tweaks for MacOS. + +./macosx Project files for MacOS X. + +./win32 Win32 projects files and build automation + +./vq Internal utilities for training/building new LSP/residue + and auxiliary codebooks. + +WHAT IS VORBIS: + +Vorbis is a general purpose audio and music encoding format +contemporary to MPEG-4's AAC and TwinVQ, the next generation beyond +MPEG audio layer 3. Unlike the MPEG sponsored formats (and other +proprietary formats such as RealAudio G2 and Windows' flavor of the +month), the Vorbis CODEC specification belongs to the public domain. +All the technical details are published and documented, and any +software entity may make full use of the format without royalty or +patent concerns. + +This package contains: + +.) libvorbis, a BSD-style license software implementation of +the Vorbis specification by the Xiph.Org Foundation (http://www.xiph.org/) + +.) libvorbisfile, a BSD-style license convenience library +built on Vorbis designed to simplify common uses and a number of GPL +example programs + +.) libvorbisenc, a BSD-style license library that provides a simple, +programmatic encoding setup interface + +.) example code making use of libogg, libvorbis, libvorbisfile and +libvorbisenc + +CONTACT: + +The Ogg homepage is located at 'http://www.xiph.org/ogg/'. +Vorbis's homepage is located at 'http://www.xiph.org/ogg/vorbis/'. +Up to date technical documents, contact information, source code and +pre-built utilities may be found there. + +BUILDING FROM CVS: + +./autogen.sh +make + +and as root if desired: + +make install + +This will install the vorbis libraries (static and shared) into +/usr/local/lib, includes into /usr/local/include and API manpages +(once we write some) into /usr/local/man. + +BUILDING FROM TARBALL DISTRIBUTIONS: + +./configure +make + +and optionally (as root): +make install + +BUILDING RPMS: + +after normal configuring: + +make dist +rpm -ta libvorbis-.tar.gz + +BUILDING ON MACOS 9: + +Vorbis on MacOS 9 is built using CodeWarrior 5.3. To build it, first +verify that the Ogg libraries are already built following the +instructions in the Ogg module README. Open vorbis/mac/libvorbis.mcp, +switch to the "Targets" pane, select everything, and make the project. +Do the same thing to build libvorbisenc.mcp, and libvorbisfile.mcp (in +that order). In vorbis/mac/Output you will now have both debug and final +versions of Vorbis shared libraries to link your projects against. + +To build a project using Ogg Vorbis, add access paths to your +CodeWarrior project for the ogg/include, ogg/mac/Output, +vorbis/include, and vorbis/mac/Output folders. Be sure that +"interpret DOS and Unix paths" is turned on in your project; it can +be found in the "access paths" pane in your project settings. Now +simply add the shared libraries you need to your project (OggLib and +VorbisLib at least) and #include "ogg/ogg.h" and "vorbis/codec.h" +wherever you need to access Ogg and Vorbis functionality. diff --git a/sound/OggVorbis/vorbis/codec.h b/sound/OggVorbis/vorbis/codec.h new file mode 100644 index 000000000..32f4dae18 --- /dev/null +++ b/sound/OggVorbis/vorbis/codec.h @@ -0,0 +1,240 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id$ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "../ogg/ogg.h" + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independant from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + char *tag, char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/sound/OggVorbis/vorbis/vorbisenc.h b/sound/OggVorbis/vorbis/vorbisenc.h new file mode 100644 index 000000000..11424c2b8 --- /dev/null +++ b/sound/OggVorbis/vorbis/vorbisenc.h @@ -0,0 +1,93 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id$ + + ********************************************************************/ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_setup_init(vorbis_info *vi); + +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + +#define OV_ECTL_RATEMANAGE_GET 0x10 + +#define OV_ECTL_RATEMANAGE_SET 0x11 +#define OV_ECTL_RATEMANAGE_AVG 0x12 +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +#define OV_ECTL_LOWPASS_GET 0x20 +#define OV_ECTL_LOWPASS_SET 0x21 + +#define OV_ECTL_IBLOCK_GET 0x30 +#define OV_ECTL_IBLOCK_SET 0x31 + +struct ovectl_ratemanage_arg { + int management_active; + + long bitrate_hard_min; + long bitrate_hard_max; + double bitrate_hard_window; + + long bitrate_av_lo; + long bitrate_av_hi; + double bitrate_av_window; + double bitrate_av_window_center; +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/sound/OggVorbis/vorbis/vorbisfile.h b/sound/OggVorbis/vorbis/vorbisfile.h new file mode 100644 index 000000000..c2a2aab7c --- /dev/null +++ b/sound/OggVorbis/vorbis/vorbisfile.h @@ -0,0 +1,144 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id$ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatability; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + + int stream; +} OggVorbis_File; + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_TIME_Total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_TIME_Tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/sound/OggVorbis/vorbissrc/analysis.c b/sound/OggVorbis/vorbissrc/analysis.c new file mode 100644 index 000000000..39baefee1 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/analysis.c @@ -0,0 +1,119 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: single-block PCM analysis mode dispatch + last mod: $Id: analysis.c,v 1.55 2002/07/11 06:40:48 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "scales.h" +#include "os.h" +#include "misc.h" + +int analysis_noisy=1; + +/* decides between modes, dispatches to the appropriate mapping. */ +int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ + int ret; + + vb->glue_bits=0; + vb->time_bits=0; + vb->floor_bits=0; + vb->res_bits=0; + + /* first things first. Make sure encode is ready */ + oggpack_reset(&vb->opb); + + /* we only have one mapping type (0), and we let the mapping code + itself figure out what soft mode to use. This allows easier + bitrate management */ + + if((ret=_mapping_P[0]->forward(vb))) + return(ret); + + if(op){ + if(vorbis_bitrate_managed(vb)) + /* The app is using a bitmanaged mode... but not using the + bitrate management interface. */ + return(OV_EINVAL); + + op->packet=oggpack_get_buffer(&vb->opb); + op->bytes=oggpack_bytes(&vb->opb); + op->b_o_s=0; + op->e_o_s=vb->eofflag; + op->granulepos=vb->granulepos; + op->packetno=vb->sequence; /* for sake of completeness */ + } + return(0); +} + +/* there was no great place to put this.... */ +void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){ + int j; + FILE *of; + char buffer[80]; + + /* if(i==5870){*/ + sprintf(buffer,"%s_%d.m",base,i); + of=fopen(buffer,"w"); + + if(!of)perror("failed to open data dump file"); + + for(j=0;j +#include "scales.h" +int main(){ + int i; + double rate; + for(i=64;i<32000;i*=2){ + rate=48000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=44100.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=32000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=22050.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=16000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=11025.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=8000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + + } + { + float i; + int j; + for(i=0.,j=0;i<28;i+=1,j++){ + fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n", + j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.)); + } + } + return(0); +} + diff --git a/sound/OggVorbis/vorbissrc/bitrate.c b/sound/OggVorbis/vorbissrc/bitrate.c new file mode 100644 index 000000000..8f11cd75d --- /dev/null +++ b/sound/OggVorbis/vorbissrc/bitrate.c @@ -0,0 +1,531 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: bitrate tracking and management + last mod: $Id: bitrate.c,v 1.21 2002/10/11 11:14:41 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" +#include "misc.h" +#include "bitrate.h" + + +static long BINBYTES(bitrate_manager_state *bm,long pos,long bin){ + int bins=bm->queue_bins; + return(bm->queue_binned[pos*bins+bin]); +} + +#define LIMITBYTES(pos,bin) (bm->minmax_binstack[(pos)*bins*2+((bin)+bins)]) + +static long LACING_ADJUST(long bytes){ + int addto=bytes/255+1; + return(bytes+addto); +} + +static int floater_interpolate(bitrate_manager_state *bm,vorbis_info *vi, + double desired_rate){ + int bin=rint(bm->avgfloat); + double lobitrate,hibitrate; + + + lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate; + while(lobitrate>desired_rate && bin>0){ + bin--; + lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate; + } + + if(bin+1queue_bins){ + hibitrate=(double)(bm->avg_binacc[bin+1]*8)/bm->avg_sampleacc*vi->rate; + if(fabs(hibitrate-desired_rate) < fabs(lobitrate-desired_rate))bin++; + } + return(bin); +} + +/* try out a new limit */ +static long limit_sum(bitrate_manager_state *bm,int limit){ + int i=bm->minmax_stackptr; + long acc=bm->minmax_acctotal; + long bins=bm->queue_bins; + + acc-=LIMITBYTES(i,0); + acc+=LIMITBYTES(i,limit); + + while(i-->0){ + if(bm->minmax_limitstack[i]<=limit)break; + acc-=LIMITBYTES(i,bm->minmax_limitstack[i]); + acc+=LIMITBYTES(i,limit); + } + return(acc); +} + +/* compute bitrate tracking setup, allocate circular packet size queue */ +void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ + int i; + codec_setup_info *ci=vi->codec_setup; + bitrate_manager_info *bi=&ci->bi; + long maxlatency; + + memset(bm,0,sizeof(*bm)); + + if(bi){ + + bm->avg_sampledesired=bi->queue_avg_time*vi->rate; + bm->avg_centerdesired=bi->queue_avg_time*vi->rate*bi->queue_avg_center; + bm->minmax_sampledesired=bi->queue_minmax_time*vi->rate; + + /* first find the max possible needed queue size */ + maxlatency=max(bm->avg_sampledesired-bm->avg_centerdesired, + bm->minmax_sampledesired)+bm->avg_centerdesired; + + if(maxlatency>0 && + (bi->queue_avgmin>0 || bi->queue_avgmax>0 || bi->queue_hardmax>0 || + bi->queue_hardmin>0)){ + long maxpackets=maxlatency/(ci->blocksizes[0]>>1)+3; + long bins=PACKETBLOBS; + + bm->queue_size=maxpackets; + bm->queue_bins=bins; + bm->queue_binned=_ogg_calloc(maxpackets,bins*sizeof(*bm->queue_binned)); + bm->queue_actual=_ogg_calloc(maxpackets,sizeof(*bm->queue_actual)); + + if((bi->queue_avgmin>0 || bi->queue_avgmax>0) && + bi->queue_avg_time>0){ + + bm->avg_binacc=_ogg_calloc(bins,sizeof(*bm->avg_binacc)); + bm->avgfloat=PACKETBLOBS/2; + + }else{ + bm->avg_tail= -1; + } + + if((bi->queue_hardmin>0 || bi->queue_hardmax>0) && + bi->queue_minmax_time>0){ + + bm->minmax_binstack=_ogg_calloc((bins*2+1)*bins*2, + sizeof(*bm->minmax_binstack)); + bm->minmax_posstack=_ogg_calloc((bins*2+1), + sizeof(*bm->minmax_posstack)); + bm->minmax_limitstack=_ogg_calloc((bins*2+1), + sizeof(*bm->minmax_limitstack)); + }else{ + bm->minmax_tail= -1; + } + + /* space for the packet queueing */ + bm->packetbuffers=_ogg_calloc(maxpackets,sizeof(*bm->packetbuffers)); + bm->packets=_ogg_calloc(maxpackets,sizeof(*bm->packets)); + for(i=0;ipacketbuffers+i); + + }else{ + bm->packetbuffers=_ogg_calloc(1,sizeof(*bm->packetbuffers)); + bm->packets=_ogg_calloc(1,sizeof(*bm->packets)); + oggpack_writeinit(bm->packetbuffers); + + } + } +} + +void vorbis_bitrate_clear(bitrate_manager_state *bm){ + int i; + if(bm){ + if(bm->queue_binned)_ogg_free(bm->queue_binned); + if(bm->queue_actual)_ogg_free(bm->queue_actual); + if(bm->avg_binacc)_ogg_free(bm->avg_binacc); + if(bm->minmax_binstack)_ogg_free(bm->minmax_binstack); + if(bm->minmax_posstack)_ogg_free(bm->minmax_posstack); + if(bm->minmax_limitstack)_ogg_free(bm->minmax_limitstack); + + if(bm->packetbuffers){ + if(bm->queue_size==0){ + oggpack_writeclear(bm->packetbuffers); + }else{ + for(i=0;iqueue_size;i++) + oggpack_writeclear(bm->packetbuffers+i); + } + _ogg_free(bm->packetbuffers); + } + if(bm->packets)_ogg_free(bm->packets); + + memset(bm,0,sizeof(*bm)); + } +} + +int vorbis_bitrate_managed(vorbis_block *vb){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + + if(bm->queue_binned)return(1); + return(0); +} + +/* finish taking in the block we just processed */ +int vorbis_bitrate_addblock(vorbis_block *vb){ + int i; + vorbis_block_internal *vbi=vb->internal; + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + bitrate_manager_info *bi=&ci->bi; + int eofflag=vb->eofflag; + int head=bm->queue_head; + int next_head=head+1; + int bins=bm->queue_bins; + int minmax_head,new_minmax_head; + + ogg_uint32_t *head_ptr; + oggpack_buffer temp; + + if(!bm->queue_binned){ + oggpack_buffer temp; + /* not a bitrate managed stream, but for API simplicity, we'll + buffer one packet to keep the code path clean */ + + if(bm->queue_head)return(-1); /* one has been submitted without + being claimed */ + bm->queue_head++; + + bm->packets[0].packet=oggpack_get_buffer(&vb->opb); + bm->packets[0].bytes=oggpack_bytes(&vb->opb); + bm->packets[0].b_o_s=0; + bm->packets[0].e_o_s=vb->eofflag; + bm->packets[0].granulepos=vb->granulepos; + bm->packets[0].packetno=vb->sequence; /* for sake of completeness */ + + memcpy(&temp,bm->packetbuffers,sizeof(vb->opb)); + memcpy(bm->packetbuffers,&vb->opb,sizeof(vb->opb)); + memcpy(&vb->opb,&temp,sizeof(vb->opb)); + + return(0); + } + + /* add encoded packet to head */ + if(next_head>=bm->queue_size)next_head=0; + head_ptr=bm->queue_binned+bins*head; + + /* is there room to add a block? In proper use of the API, this will + never come up... but guard it anyway */ + if(next_head==bm->avg_tail || next_head==bm->minmax_tail)return(-1); + + /* add the block to the toplevel queue */ + bm->queue_head=next_head; + bm->queue_actual[head]=(vb->W?0x80000000UL:0); + + /* buffer packet fields */ + bm->packets[head].packet=oggpack_get_buffer(&vb->opb); + bm->packets[head].bytes=oggpack_bytes(&vb->opb); + bm->packets[head].b_o_s=0; + bm->packets[head].e_o_s=vb->eofflag; + bm->packets[head].granulepos=vb->granulepos; + bm->packets[head].packetno=vb->sequence; /* for sake of completeness */ + + /* swap packet buffers */ + memcpy(&temp,bm->packetbuffers+head,sizeof(vb->opb)); + memcpy(bm->packetbuffers+head,&vb->opb,sizeof(vb->opb)); + memcpy(&vb->opb,&temp,sizeof(vb->opb)); + + /* save markers */ + head_ptr[0]=vbi->packetblob_markers[0]; + for(i=1;ipacketblob_markers[i]-vbi->packetblob_markers[i-1]; + } + + if(bm->avg_binacc) + new_minmax_head=minmax_head=bm->avg_center; + else + new_minmax_head=minmax_head=head; + + /* the average tracking queue is updated first; its results (if it's + in use) are taken into account by the min/max limiter (if min/max + is in use) */ + if(bm->avg_binacc){ + unsigned long desired_center=bm->avg_centerdesired; + if(eofflag)desired_center=0; + + /* update the avg head */ + for(i=0;iavg_binacc[i]+=LACING_ADJUST(head_ptr[i]); + bm->avg_sampleacc+=ci->blocksizes[vb->W]>>1; + bm->avg_centeracc+=ci->blocksizes[vb->W]>>1; + + if(bm->avg_sampleacc>bm->avg_sampledesired || eofflag){ + + /* update the avg center */ + if(bm->avg_centeracc>desired_center){ + /* choose the new average floater */ + int samples=ci->blocksizes[vb->W]>>1; + double upper=floater_interpolate(bm,vi,bi->queue_avgmax); + double lower=floater_interpolate(bm,vi,bi->queue_avgmin); + double new=PACKETBLOBS/2.,slew; + int bin; + + if(uppernew)new=lower; + + slew=(new-bm->avgfloat)/samples*vi->rate; + + if(slewavgfloat_downslew_max) + new=bm->avgfloat+bi->avgfloat_downslew_max/vi->rate*samples; + if(slew>bi->avgfloat_upslew_max) + new=bm->avgfloat+bi->avgfloat_upslew_max/vi->rate*samples; + + bm->avgfloat=new; + /* apply the average floater to new blocks */ + bin=rint(bm->avgfloat); + + /*fprintf(stderr,"%d ",bin);*/ + + while(bm->avg_centeracc>desired_center){ + samples=ci->blocksizes[bm->queue_actual[bm->avg_center]& + 0x80000000UL?1:0]>>1; + + bm->queue_actual[bm->avg_center]|=bin; + + bm->avg_centeracc-=samples; + bm->avg_center++; + if(bm->avg_center>=bm->queue_size)bm->avg_center=0; + } + new_minmax_head=bm->avg_center; + + } + + /* update the avg tail if needed */ + while(bm->avg_sampleacc>bm->avg_sampledesired){ + int samples= + ci->blocksizes[bm->queue_actual[bm->avg_tail]&0x80000000UL?1:0]>>1; + for(i=0;iqueue_bins;i++) + bm->avg_binacc[i]-=LACING_ADJUST(bm->queue_binned[bins*bm->avg_tail+i]); + bm->avg_sampleacc-=samples; + bm->avg_tail++; + if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0; + } + + + } + }else{ + /* if we're not using an average tracker, the 'float' is nailed to + the avgfloat_initial value. It needs to be set for the min/max + to deal properly */ + long bin=PACKETBLOBS/2; + bm->queue_actual[head]|=bin; + new_minmax_head=next_head; + } + + /* update the min/max queues and enforce limits */ + if(bm->minmax_binstack){ + unsigned long sampledesired=eofflag?0:bm->minmax_sampledesired; + + /* add to stack recent */ + while(minmax_head!=new_minmax_head){ + unsigned int i; + int samples=ci->blocksizes[bm->queue_actual[minmax_head]& + 0x80000000UL?1:0]>>1; + int actual=bm->queue_actual[minmax_head]&0x7fffffffUL; + + for(i=0;i<(unsigned int)bins;i++){ + bm->minmax_binstack[bm->minmax_stackptr*bins*2+bins+i]+= + LACING_ADJUST(BINBYTES(bm,minmax_head, + actual>i?actual:i)); + + bm->minmax_binstack[bm->minmax_stackptr*bins*2+i]+= + LACING_ADJUST(BINBYTES(bm,minmax_head, + actualminmax_posstack[bm->minmax_stackptr]=minmax_head; /* not one + past + like + typical */ + bm->minmax_limitstack[bm->minmax_stackptr]=0; + bm->minmax_sampleacc+=samples; + bm->minmax_acctotal+= + LACING_ADJUST(BINBYTES(bm,minmax_head,actual)); + + minmax_head++; + if(minmax_head>=bm->queue_size)minmax_head=0; + + + } + + /* check limits, enforce changes */ + if(bm->minmax_sampleacc>sampledesired){ + double bitrate=(double)(bm->minmax_acctotal*8)/ + bm->minmax_sampleacc*vi->rate; + int limit=0; + + if((bi->queue_hardmax>0 && bitrate>bi->queue_hardmax) || + (bi->queue_hardmin>0 && bitratequeue_hardmin)){ + int newstack; + int stackctr; + long bitsum=bm->minmax_acctotal*8; + + bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate; + + /* we're off rate. Iteratively try out new hard floater + limits until we find one that brings us inside. Here's + where we see the whole point of the limit stacks. */ + if(bi->queue_hardmax>0 && bitrate>bi->queue_hardmax){ + for(limit=-1;limit>-bins+1;limit--){ + long bitsum=limit_sum(bm,limit)*8; + bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate; + if(bitrate<=bi->queue_hardmax)break; + } + }else if(bitratequeue_hardmin){ + for(limit=1;limitminmax_sampleacc*vi->rate; + if(bitrate>=bi->queue_hardmin)break; + } + if(bitrate>bi->queue_hardmax)limit--; + } + + /* trace the limit backward, stop when we see a lower limit */ + newstack=bm->minmax_stackptr-1; + while(newstack>=0){ + if(bm->minmax_limitstack[newstack]minmax_stackptr; + while(stackctr>newstack){ + bm->minmax_acctotal-= + LIMITBYTES(stackctr,bm->minmax_limitstack[stackctr]); + bm->minmax_acctotal+=LIMITBYTES(stackctr,limit); + + if(stackctrminmax_stackptr) + for(i=0;iminmax_binstack[stackctr*bins*2+i]+= + bm->minmax_binstack[(stackctr+1)*bins*2+i]; + + stackctr--; + } + stackctr++; + bm->minmax_posstack[stackctr]=bm->minmax_posstack[bm->minmax_stackptr]; + bm->minmax_limitstack[stackctr]=limit; + + /* set up new blank stack entry */ + stackctr++; + bm->minmax_stackptr=stackctr; + memset(&bm->minmax_binstack[stackctr*bins*2], + 0, + sizeof(*bm->minmax_binstack)*bins*2); + bm->minmax_limitstack[stackctr]=0; + bm->minmax_posstack[stackctr]=-1; + + } + } + + /* remove from tail */ + while(bm->minmax_sampleacc>sampledesired){ + int samples= + ci->blocksizes[bm->queue_actual[bm->minmax_tail]&0x80000000UL?1:0]>>1; + int actual=bm->queue_actual[bm->minmax_tail]&0x7fffffffUL; + + for(i=0;iminmax_binstack[bins+i]-= /* always comes off the stack bottom */ + LACING_ADJUST(BINBYTES(bm,bm->minmax_tail, + actual>i? + actual:i)); + bm->minmax_binstack[i]-= + LACING_ADJUST(BINBYTES(bm,bm->minmax_tail, + actualminmax_limitstack[0]>actual) + actual=bm->minmax_limitstack[0]; + if(bins+bm->minmax_limitstack[0]minmax_limitstack[0]; + + bm->minmax_acctotal-=LACING_ADJUST(BINBYTES(bm,bm->minmax_tail,actual)); + bm->minmax_sampleacc-=samples; + + /* revise queue_actual to reflect the limit */ + bm->queue_actual[bm->minmax_tail]&=0x80000000UL; + bm->queue_actual[bm->minmax_tail]|=actual; + + if(bm->minmax_tail==bm->minmax_posstack[0]){ + /* the stack becomes a FIFO; the first data has fallen off */ + memmove(bm->minmax_binstack,bm->minmax_binstack+bins*2, + sizeof(*bm->minmax_binstack)*bins*2*bm->minmax_stackptr); + memmove(bm->minmax_posstack,bm->minmax_posstack+1, + sizeof(*bm->minmax_posstack)*bm->minmax_stackptr); + memmove(bm->minmax_limitstack,bm->minmax_limitstack+1, + sizeof(*bm->minmax_limitstack)*bm->minmax_stackptr); + bm->minmax_stackptr--; + } + + bm->minmax_tail++; + if(bm->minmax_tail>=bm->queue_size)bm->minmax_tail=0; + + } + + + bm->last_to_flush=bm->minmax_tail; + }else{ + bm->last_to_flush=bm->avg_center; + } + if(eofflag) + bm->last_to_flush=bm->queue_head; + return(0); +} + +int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){ + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + + if(bm->queue_size==0){ + if(bm->queue_head==0)return(0); + + memcpy(op,bm->packets,sizeof(*op)); + bm->queue_head=0; + + }else{ + + if(bm->next_to_flush==bm->last_to_flush)return(0); + + { + long bin=bm->queue_actual[bm->next_to_flush]&0x7fffffff,i; + long bins=bm->queue_bins; + ogg_uint32_t *markers=bm->queue_binned+bins*bm->next_to_flush; + long bytes=markers[bin]; + + memcpy(op,bm->packets+bm->next_to_flush,sizeof(*op)); + + /* we have [PACKETBLOBS] possible packets all squished together in + the buffer, in sequence. count in to number [bin] */ + for(i=0;ipacket+=markers[i]; + op->bytes=bytes; + + } + + bm->next_to_flush++; + if(bm->next_to_flush>=bm->queue_size)bm->next_to_flush=0; + + } + + return(1); +} diff --git a/sound/OggVorbis/vorbissrc/bitrate.h b/sound/OggVorbis/vorbissrc/bitrate.h new file mode 100644 index 000000000..4ecd0d866 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/bitrate.h @@ -0,0 +1,84 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: bitrate tracking and management + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_BITRATE_H_ +#define _V_BITRATE_H_ + +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" + +/* encode side bitrate tracking */ +typedef struct bitrate_manager_state { + ogg_uint32_t *queue_binned; + ogg_uint32_t *queue_actual; + int queue_size; + + int queue_head; + int queue_bins; + + long *avg_binacc; + int avg_center; + int avg_tail; + ogg_uint32_t avg_centeracc; + ogg_uint32_t avg_sampleacc; + ogg_uint32_t avg_sampledesired; + ogg_uint32_t avg_centerdesired; + + long *minmax_binstack; + long *minmax_posstack; + long *minmax_limitstack; + long minmax_stackptr; + + long minmax_acctotal; + int minmax_tail; + ogg_uint32_t minmax_sampleacc; + ogg_uint32_t minmax_sampledesired; + + int next_to_flush; + int last_to_flush; + + double avgfloat; + + /* unfortunately, we need to hold queued packet data somewhere */ + oggpack_buffer *packetbuffers; + ogg_packet *packets; + +} bitrate_manager_state; + +typedef struct bitrate_manager_info{ + /* detailed bitrate management setup */ + double queue_avg_time; + double queue_avg_center; + double queue_minmax_time; + double queue_hardmin; + double queue_hardmax; + double queue_avgmin; + double queue_avgmax; + + double avgfloat_downslew_max; + double avgfloat_upslew_max; + +} bitrate_manager_info; + +extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs); +extern void vorbis_bitrate_clear(bitrate_manager_state *bs); +extern int vorbis_bitrate_managed(vorbis_block *vb); +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op); + +#endif diff --git a/sound/OggVorbis/vorbissrc/block.c b/sound/OggVorbis/vorbissrc/block.c new file mode 100644 index 000000000..e22eb1082 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/block.c @@ -0,0 +1,971 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data vector blocking, windowing and dis/reassembly + last mod: $Id: block.c,v 1.75 2003/09/02 04:39:26 xiphmont Exp $ + + Handle windowing, overlap-add, etc of the PCM vectors. This is made + more amusing by Vorbis' current two allowed block sizes. + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" + +#include "window.h" +#include "mdct.h" +#include "lpc.h" +#include "registry.h" +#include "misc.h" + +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* pcm accumulator examples (not exhaustive): + + <-------------- lW ----------------> + <--------------- W ----------------> +: .....|..... _______________ | +: .''' | '''_--- | |\ | +:.....''' |_____--- '''......| | \_______| +:.................|__________________|_______|__|______| + |<------ Sl ------>| > Sr < |endW + |beginSl |endSl | |endSr + |beginW |endlW |beginSr + + + |< lW >| + <--------------- W ----------------> + | | .. ______________ | + | | ' `/ | ---_ | + |___.'___/`. | ---_____| + |_______|__|_______|_________________| + | >|Sl|< |<------ Sr ----->|endW + | | |endSl |beginSr |endSr + |beginW | |endlW + mult[0] |beginSl mult[n] + + <-------------- lW -----------------> + |<--W-->| +: .............. ___ | | +: .''' |`/ \ | | +:.....''' |/`....\|...| +:.........................|___|___|___| + |Sl |Sr |endW + | | |endSr + | |beginSr + | |endSl + |beginSl + |beginW +*/ + +/* block abstraction setup *********************************************/ + +#ifndef WORD_ALIGN +#define WORD_ALIGN 8 +#endif + +int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ + memset(vb,0,sizeof(*vb)); + vb->vd=v; + vb->localalloc=0; + vb->localstore=NULL; + if(v->analysisp){ + vorbis_block_internal *vbi= + vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal)); + oggpack_writeinit(&vb->opb); + vbi->ampmax=-9999; + } + + return(0); +} + +void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ + bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); + if(bytes+vb->localtop>vb->localalloc){ + /* can't just _ogg_realloc... there are outstanding pointers */ + if(vb->localstore){ + struct alloc_chain *link=_ogg_malloc(sizeof(*link)); + vb->totaluse+=vb->localtop; + link->next=vb->reap; + link->ptr=vb->localstore; + vb->reap=link; + } + /* highly conservative */ + vb->localalloc=bytes; + vb->localstore=_ogg_malloc(vb->localalloc); + vb->localtop=0; + } + { + void *ret=(void *)(((char *)vb->localstore)+vb->localtop); + vb->localtop+=bytes; + return ret; + } +} + +/* reap the chain, pull the ripcord */ +void _vorbis_block_ripcord(vorbis_block *vb){ + /* reap the chain */ + struct alloc_chain *reap=vb->reap; + while(reap){ + struct alloc_chain *next=reap->next; + _ogg_free(reap->ptr); + memset(reap,0,sizeof(*reap)); + _ogg_free(reap); + reap=next; + } + /* consolidate storage */ + if(vb->totaluse){ + vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); + vb->localalloc+=vb->totaluse; + vb->totaluse=0; + } + + /* pull the ripcord */ + vb->localtop=0; + vb->reap=NULL; +} + +int vorbis_block_clear(vorbis_block *vb){ + if(vb->vd) + if(vb->vd->analysisp) + oggpack_writeclear(&vb->opb); + _vorbis_block_ripcord(vb); + if(vb->localstore)_ogg_free(vb->localstore); + + if(vb->internal) + _ogg_free(vb->internal); + + memset(vb,0,sizeof(*vb)); + return(0); +} + +/* Analysis side code, but directly related to blocking. Thus it's + here and not in analysis.c (which is for analysis transforms only). + The init is here because some of it is shared */ + +static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ + int i; + codec_setup_info *ci=vi->codec_setup; + private_state *b=NULL; + int hs; + + if(ci==NULL) return 1; + hs=ci->halfrate_flag; + + memset(v,0,sizeof(*v)); + b=v->backend_state=_ogg_calloc(1,sizeof(*b)); + + v->vi=vi; + b->modebits=ilog2(ci->modes); + + b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0])); + b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1])); + + /* MDCT is tranform 0 */ + + b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup)); + b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup)); + mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs); + mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs); + + /* Vorbis I uses only window type 0 */ + b->window[0]=ilog2(ci->blocksizes[0])-6; + b->window[1]=ilog2(ci->blocksizes[1])-6; + + if(encp){ /* encode/decode differ here */ + + /* analysis always needs an fft */ + drft_init(&b->fft_look[0],ci->blocksizes[0]); + drft_init(&b->fft_look[1],ci->blocksizes[1]); + + /* finish the codebooks */ + if(!ci->fullbooks){ + ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++) + vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); + } + + b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy)); + for(i=0;ipsys;i++){ + _vp_psy_init(b->psy+i, + ci->psy_param[i], + &ci->psy_g_param, + ci->blocksizes[ci->psy_param[i]->blockflag]/2, + vi->rate); + } + + v->analysisp=1; + }else{ + /* finish the codebooks */ + if(!ci->fullbooks){ + ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++){ + vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); + /* decode codebooks are now standalone after init */ + vorbis_staticbook_destroy(ci->book_param[i]); + ci->book_param[i]=NULL; + } + } + } + + /* initialize the storage vectors. blocksize[1] is small for encode, + but the correct size for decode */ + v->pcm_storage=ci->blocksizes[1]; + v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm)); + v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret)); + { + int i; + for(i=0;ichannels;i++) + v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); + } + + /* all 1 (large block) or 0 (small block) */ + /* explicitly set for the sake of clarity */ + v->lW=0; /* previous window size */ + v->W=0; /* current window size */ + + /* all vector indexes */ + v->centerW=ci->blocksizes[1]/2; + + v->pcm_current=v->centerW; + + /* initialize all the backend lookups */ + b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr)); + b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue)); + + for(i=0;ifloors;i++) + b->flr[i]=_floor_P[ci->floor_type[i]]-> + look(v,ci->floor_param[i]); + + for(i=0;iresidues;i++) + b->residue[i]=_residue_P[ci->residue_type[i]]-> + look(v,ci->residue_param[i]); + + return 0; +} + +/* arbitrary settings and spec-mandated numbers get filled in here */ +int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){ + private_state *b=NULL; + + if(_vds_shared_init(v,vi,1))return 1; + b=v->backend_state; + b->psy_g_look=_vp_global_look(vi); + + /* Initialize the envelope state storage */ + b->ve=_ogg_calloc(1,sizeof(*b->ve)); + _ve_envelope_init(b->ve,vi); + + vorbis_bitrate_init(vi,&b->bms); + + return(0); +} + +void vorbis_dsp_clear(vorbis_dsp_state *v){ + int i; + if(v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=(vi?vi->codec_setup:NULL); + private_state *b=v->backend_state; + + if(b){ + + if(b->ve){ + _ve_envelope_clear(b->ve); + _ogg_free(b->ve); + } + + if(b->transform[0]){ + mdct_clear(b->transform[0][0]); + _ogg_free(b->transform[0][0]); + _ogg_free(b->transform[0]); + } + if(b->transform[1]){ + mdct_clear(b->transform[1][0]); + _ogg_free(b->transform[1][0]); + _ogg_free(b->transform[1]); + } + + if(b->flr){ + for(i=0;ifloors;i++) + _floor_P[ci->floor_type[i]]-> + free_look(b->flr[i]); + _ogg_free(b->flr); + } + if(b->residue){ + for(i=0;iresidues;i++) + _residue_P[ci->residue_type[i]]-> + free_look(b->residue[i]); + _ogg_free(b->residue); + } + if(b->psy){ + for(i=0;ipsys;i++) + _vp_psy_clear(b->psy+i); + _ogg_free(b->psy); + } + + if(b->psy_g_look)_vp_global_free(b->psy_g_look); + vorbis_bitrate_clear(&b->bms); + + drft_clear(&b->fft_look[0]); + drft_clear(&b->fft_look[1]); + + } + + if(v->pcm){ + for(i=0;ichannels;i++) + if(v->pcm[i])_ogg_free(v->pcm[i]); + _ogg_free(v->pcm); + if(v->pcmret)_ogg_free(v->pcmret); + } + + if(b){ + /* free header, header1, header2 */ + if(b->header)_ogg_free(b->header); + if(b->header1)_ogg_free(b->header1); + if(b->header2)_ogg_free(b->header2); + _ogg_free(b); + } + + memset(v,0,sizeof(*v)); + } +} + +float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){ + int i; + vorbis_info *vi=v->vi; + private_state *b=v->backend_state; + + /* free header, header1, header2 */ + if(b->header)_ogg_free(b->header);b->header=NULL; + if(b->header1)_ogg_free(b->header1);b->header1=NULL; + if(b->header2)_ogg_free(b->header2);b->header2=NULL; + + /* Do we have enough storage space for the requested buffer? If not, + expand the PCM (and envelope) storage */ + + if(v->pcm_current+vals>=v->pcm_storage){ + v->pcm_storage=v->pcm_current+vals*2; + + for(i=0;ichannels;i++){ + v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i])); + } + } + + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_current; + + return(v->pcmret); +} + +static void _preextrapolate_helper(vorbis_dsp_state *v){ + int i; + int order=32; + float *lpc=alloca(order*sizeof(*lpc)); + float *work=alloca(v->pcm_current*sizeof(*work)); + long j; + v->preextrapolate=1; + + if(v->pcm_current-v->centerW>order*2){ /* safety */ + for(i=0;ivi->channels;i++){ + /* need to run the extrapolation in reverse! */ + for(j=0;jpcm_current;j++) + work[j]=v->pcm[i][v->pcm_current-j-1]; + + /* prime as above */ + vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order); + + /* run the predictor filter */ + vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order, + order, + work+v->pcm_current-v->centerW, + v->centerW); + + for(j=0;jpcm_current;j++) + v->pcm[i][v->pcm_current-j-1]=work[j]; + + } + } +} + + +/* call with val<=0 to set eof */ + +int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + + if(vals<=0){ + int order=32; + int i; + float *lpc=alloca(order*sizeof(*lpc)); + + /* if it wasn't done earlier (very short sample) */ + if(!v->preextrapolate) + _preextrapolate_helper(v); + + /* We're encoding the end of the stream. Just make sure we have + [at least] a few full blocks of zeroes at the end. */ + /* actually, we don't want zeroes; that could drop a large + amplitude off a cliff, creating spread spectrum noise that will + suck to encode. Extrapolate for the sake of cleanliness. */ + + vorbis_analysis_buffer(v,ci->blocksizes[1]*3); + v->eofflag=v->pcm_current; + v->pcm_current+=ci->blocksizes[1]*3; + + for(i=0;ichannels;i++){ + if(v->eofflag>order*2){ + /* extrapolate with LPC to fill in */ + long n; + + /* make a predictor filter */ + n=v->eofflag; + if(n>ci->blocksizes[1])n=ci->blocksizes[1]; + vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order); + + /* run the predictor filter */ + vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order, + v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag); + }else{ + /* not enough data to extrapolate (unlikely to happen due to + guarding the overlap, but bulletproof in case that + assumtion goes away). zeroes will do. */ + memset(v->pcm[i]+v->eofflag,0, + (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i])); + + } + } + }else{ + + if(v->pcm_current+vals>v->pcm_storage) + return(OV_EINVAL); + + v->pcm_current+=vals; + + /* we may want to reverse extrapolate the beginning of a stream + too... in case we're beginning on a cliff! */ + /* clumsy, but simple. It only runs once, so simple is good. */ + if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1]) + _preextrapolate_helper(v); + + } + return(0); +} + +/* do the deltas, envelope shaping, pre-echo and determine the size of + the next block on which to continue analysis */ +int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){ + int i; + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=v->backend_state; + vorbis_look_psy_global *g=b->psy_g_look; + long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext; + vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; + + /* check to see if we're started... */ + if(!v->preextrapolate)return(0); + + /* check to see if we're done... */ + if(v->eofflag==-1)return(0); + + /* By our invariant, we have lW, W and centerW set. Search for + the next boundary so we can determine nW (the next window size) + which lets us compute the shape of the current block's window */ + + /* we do an envelope search even on a single blocksize; we may still + be throwing more bits at impulses, and envelope search handles + marking impulses too. */ + { + long bp=_ve_envelope_search(v); + if(bp==-1){ + + if(v->eofflag==0)return(0); /* not enough data currently to search for a + full long block */ + v->nW=0; + }else{ + + if(ci->blocksizes[0]==ci->blocksizes[1]) + v->nW=0; + else + v->nW=bp; + } + } + + centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4; + + { + /* center of next block + next block maximum right side. */ + + long blockbound=centerNext+ci->blocksizes[v->nW]/2; + if(v->pcm_currentlW=v->lW; + vb->W=v->W; + vb->nW=v->nW; + + if(v->W){ + if(!v->lW || !v->nW){ + vbi->blocktype=BLOCKTYPE_TRANSITION; + /*fprintf(stderr,"-");*/ + }else{ + vbi->blocktype=BLOCKTYPE_LONG; + /*fprintf(stderr,"_");*/ + } + }else{ + if(_ve_envelope_mark(v)){ + vbi->blocktype=BLOCKTYPE_IMPULSE; + /*fprintf(stderr,"|");*/ + + }else{ + vbi->blocktype=BLOCKTYPE_PADDING; + /*fprintf(stderr,".");*/ + + } + } + + vb->vd=v; + vb->sequence=v->sequence++; + vb->granulepos=v->granulepos; + vb->pcmend=ci->blocksizes[v->W]; + + /* copy the vectors; this uses the local storage in vb */ + + /* this tracks 'strongest peak' for later psychoacoustics */ + /* moved to the global psy state; clean this mess up */ + if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax; + g->ampmax=_vp_ampmax_decay(g->ampmax,v); + vbi->ampmax=g->ampmax; + + vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); + vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels); + for(i=0;ichannels;i++){ + vbi->pcmdelay[i]= + _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); + memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); + vb->pcm[i]=vbi->pcmdelay[i]+beginW; + + /* before we added the delay + vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i])); + */ + + } + + /* handle eof detection: eof==0 means that we've not yet received EOF + eof>0 marks the last 'real' sample in pcm[] + eof<0 'no more to do'; doesn't get here */ + + if(v->eofflag){ + if(v->centerW>=v->eofflag){ + v->eofflag=-1; + vb->eofflag=1; + return(1); + } + } + + /* advance storage vectors and clean up */ + { + int new_centerNext=ci->blocksizes[1]/2; + int movementW=centerNext-new_centerNext; + + if(movementW>0){ + + _ve_envelope_shift(b->ve,movementW); + v->pcm_current-=movementW; + + for(i=0;ichannels;i++) + memmove(v->pcm[i],v->pcm[i]+movementW, + v->pcm_current*sizeof(*v->pcm[i])); + + + v->lW=v->W; + v->W=v->nW; + v->centerW=new_centerNext; + + if(v->eofflag){ + v->eofflag-=movementW; + if(v->eofflag<=0)v->eofflag=-1; + /* do not add padding to end of stream! */ + if(v->centerW>=v->eofflag){ + v->granulepos+=movementW-(v->centerW-v->eofflag); + }else{ + v->granulepos+=movementW; + } + }else{ + v->granulepos+=movementW; + } + } + } + + /* done */ + return(1); +} + +int vorbis_synthesis_restart(vorbis_dsp_state *v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci; + int hs; + + if(!v->backend_state)return -1; + if(!vi)return -1; + ci=vi->codec_setup; + if(!ci)return -1; + hs=ci->halfrate_flag; + + v->centerW=ci->blocksizes[1]>>(hs+1); + v->pcm_current=v->centerW>>hs; + + v->pcm_returned=-1; + v->granulepos=-1; + v->sequence=-1; + v->eofflag=0; + ((private_state *)(v->backend_state))->sample_count=-1; + + return(0); +} + +int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ + if(_vds_shared_init(v,vi,0)) return 1; + vorbis_synthesis_restart(v); + + return 0; +} + +/* Unlike in analysis, the window is only partially applied for each + block. The time domain envelope is not yet handled at the point of + calling (as it relies on the previous block). */ + +int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=v->backend_state; + int hs=ci->halfrate_flag; + int i,j; + + if(!vb)return(OV_EINVAL); + if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); + + v->lW=v->W; + v->W=vb->W; + v->nW=-1; + + if((v->sequence==-1)|| + (v->sequence+1 != vb->sequence)){ + v->granulepos=-1; /* out of sequence; lose count */ + b->sample_count=-1; + } + + v->sequence=vb->sequence; + + if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly + was called on block */ + int n=ci->blocksizes[v->W]>>(hs+1); + int n0=ci->blocksizes[0]>>(hs+1); + int n1=ci->blocksizes[1]>>(hs+1); + + int thisCenter; + int prevCenter; + + v->glue_bits+=vb->glue_bits; + v->time_bits+=vb->time_bits; + v->floor_bits+=vb->floor_bits; + v->res_bits+=vb->res_bits; + + if(v->centerW){ + thisCenter=n1; + prevCenter=0; + }else{ + thisCenter=0; + prevCenter=n1; + } + + /* v->pcm is now used like a two-stage double buffer. We don't want + to have to constantly shift *or* adjust memory usage. Don't + accept a new block until the old is shifted out */ + + for(j=0;jchannels;j++){ + /* the overlap/add section */ + if(v->lW){ + if(v->W){ + /* large/large */ + float *w=_vorbis_window_get(b->window[1]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]; + for(i=0;iwindow[0]-hs); + float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; + float *p=vb->pcm[j]; + for(i=0;iW){ + /* small/large */ + float *w=_vorbis_window_get(b->window[0]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]+n1/2-n0/2; + for(i=0;iwindow[0]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]; + for(i=0;ipcm[j]+thisCenter; + float *p=vb->pcm[j]+n; + for(i=0;icenterW) + v->centerW=0; + else + v->centerW=n1; + + /* deal with initial packet state; we do this using the explicit + pcm_returned==-1 flag otherwise we're sensitive to first block + being short or long */ + + if(v->pcm_returned==-1){ + v->pcm_returned=thisCenter; + v->pcm_current=thisCenter; + }else{ + v->pcm_returned=prevCenter; + v->pcm_current=prevCenter+ + ((ci->blocksizes[v->lW]/4+ + ci->blocksizes[v->W]/4)>>hs); + } + + } + + /* track the frame number... This is for convenience, but also + making sure our last packet doesn't end with added padding. If + the last packet is partial, the number of samples we'll have to + return will be past the vb->granulepos. + + This is not foolproof! It will be confused if we begin + decoding at the last page after a seek or hole. In that case, + we don't have a starting point to judge where the last frame + is. For this reason, vorbisfile will always try to make sure + it reads the last two marked pages in proper sequence */ + + if(b->sample_count==-1){ + b->sample_count=0; + }else{ + b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + } + + if(v->granulepos==-1){ + if(vb->granulepos!=-1){ /* only set if we have a position to set to */ + + v->granulepos=vb->granulepos; + + /* is this a short page? */ + if(b->sample_count>v->granulepos){ + /* corner case; if this is both the first and last audio page, + then spec says the end is cut, not beginning */ + if(vb->eofflag){ + /* trim the end */ + /* no preceeding granulepos; assume we started at zero (we'd + have to in a short single-page stream) */ + /* granulepos could be -1 due to a seek, but that would result + in a long count, not short count */ + + v->pcm_current-=(b->sample_count-v->granulepos)>>hs; + }else{ + /* trim the beginning */ + v->pcm_returned+=(b->sample_count-v->granulepos)>>hs; + if(v->pcm_returned>v->pcm_current) + v->pcm_returned=v->pcm_current; + } + + } + + } + }else{ + v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ + + if(v->granulepos>vb->granulepos){ + long extra=v->granulepos-vb->granulepos; + + if(extra) + if(vb->eofflag){ + /* partial last frame. Strip the extra samples off */ + v->pcm_current-=extra>>hs; + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + v->granulepos=vb->granulepos; + } + } + + /* Update, cleanup */ + + if(vb->eofflag)v->eofflag=1; + return(0); + +} + +/* pcm==NULL indicates we just want the pending samples, no more */ +int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){ + vorbis_info *vi=v->vi; + + if(v->pcm_returned>-1 && v->pcm_returnedpcm_current){ + if(pcm){ + int i; + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_returned; + *pcm=v->pcmret; + } + return(v->pcm_current-v->pcm_returned); + } + return(0); +} + +int vorbis_synthesis_read(vorbis_dsp_state *v,int n){ + if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL); + v->pcm_returned+=n; + return(0); +} + +/* intended for use with a specific vorbisfile feature; we want access + to the [usually synthetic/postextrapolated] buffer and lapping at + the end of a decode cycle, specifically, a half-short-block worth. + This funtion works like pcmout above, except it will also expose + this implicit buffer data not normally decoded. */ +int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + int hs=ci->halfrate_flag; + + int n=ci->blocksizes[v->W]>>(hs+1); + int n0=ci->blocksizes[0]>>(hs+1); + int n1=ci->blocksizes[1]>>(hs+1); + int i,j; + + if(v->pcm_returned<0)return 0; + + /* our returned data ends at pcm_returned; because the synthesis pcm + buffer is a two-fragment ring, that means our data block may be + fragmented by buffering, wrapping or a short block not filling + out a buffer. To simplify things, we unfragment if it's at all + possibly needed. Otherwise, we'd need to call lapout more than + once as well as hold additional dsp state. Opt for + simplicity. */ + + /* centerW was advanced by blockin; it would be the center of the + *next* block */ + if(v->centerW==n1){ + /* the data buffer wraps; swap the halves */ + /* slow, sure, small */ + for(j=0;jchannels;j++){ + float *p=v->pcm[j]; + for(i=0;ipcm_current-=n1; + v->pcm_returned-=n1; + v->centerW=0; + } + + /* solidify buffer into contiguous space */ + if((v->lW^v->W)==1){ + /* long/short or short/long */ + for(j=0;jchannels;j++){ + float *s=v->pcm[j]; + float *d=v->pcm[j]+(n1-n0)/2; + for(i=(n1+n0)/2-1;i>=0;--i) + d[i]=s[i]; + } + v->pcm_returned+=(n1-n0)/2; + v->pcm_current+=(n1-n0)/2; + }else{ + if(v->lW==0){ + /* short/short */ + for(j=0;jchannels;j++){ + float *s=v->pcm[j]; + float *d=v->pcm[j]+n1-n0; + for(i=n0-1;i>=0;--i) + d[i]=s[i]; + } + v->pcm_returned+=n1-n0; + v->pcm_current+=n1-n0; + } + } + + if(pcm){ + int i; + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_returned; + *pcm=v->pcmret; + } + + return(n1+n-v->pcm_returned); + +} + +float *vorbis_window(vorbis_dsp_state *v,int W){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + int hs=ci->halfrate_flag; + private_state *b=v->backend_state; + + if(b->window[W]-1<0)return NULL; + return _vorbis_window_get(b->window[W]-hs); +} + diff --git a/sound/OggVorbis/vorbissrc/books/coupled/res_books_stereo.h b/sound/OggVorbis/vorbissrc/books/coupled/res_books_stereo.h new file mode 100644 index 000000000..7a5647b2a --- /dev/null +++ b/sound/OggVorbis/vorbissrc/books/coupled/res_books_stereo.h @@ -0,0 +1,19080 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id$ + + ********************************************************************/ + +#include "codebook.h" +static long _vq_quantlist__16c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p1_0[] = { + 1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, + 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0, + 0, 0, 0, 9, 9,12, 0, 0, 0, 0, 0, 0,10,12,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, + 0, 0, 0, 0, 9,12,10, 0, 0, 0, 0, 0, 0,10,11,12, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, + 0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,12,11, 0, + 0, 0, 0, 0, 0, 9,10,12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,12, + 0, 0, 0, 0, 0, 0, 9,12, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p1_0 = { + _vq_quantthresh__16c0_s_p1_0, + _vq_quantmap__16c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__16c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c0_s_p1_0, + NULL, + &_vq_auxt__16c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p2_0 = { + _vq_quantthresh__16c0_s_p2_0, + _vq_quantmap__16c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p2_0, + NULL, + &_vq_auxt__16c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 7, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p3_0 = { + _vq_quantthresh__16c0_s_p3_0, + _vq_quantmap__16c0_s_p3_0, + 5, + 5 +}; + +static static_codebook _16c0_s_p3_0 = { + 4, 625, + _vq_lengthlist__16c0_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p3_0, + NULL, + &_vq_auxt__16c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c0_s_p4_0[] = { + 1, 3, 2, 7, 8, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p4_0 = { + _vq_quantthresh__16c0_s_p4_0, + _vq_quantmap__16c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _16c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__16c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p4_0, + NULL, + &_vq_auxt__16c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c0_s_p5_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 8, 0, 0, 0, 7, 7, + 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, 0, 0, + 8, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__16c0_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c0_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p5_0 = { + _vq_quantthresh__16c0_s_p5_0, + _vq_quantmap__16c0_s_p5_0, + 9, + 9 +}; + +static static_codebook _16c0_s_p5_0 = { + 2, 81, + _vq_lengthlist__16c0_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p5_0, + NULL, + &_vq_auxt__16c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c0_s_p6_0[] = { + 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11, + 11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,12,13, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10,10,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, 0, 0, + 10,10,10,11,11,11,12,12,13,13,13,14, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,13,13,14,15,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,14,14,15, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,13,14, + 14, +}; + +static float _vq_quantthresh__16c0_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c0_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p6_0 = { + _vq_quantthresh__16c0_s_p6_0, + _vq_quantmap__16c0_s_p6_0, + 17, + 17 +}; + +static static_codebook _16c0_s_p6_0 = { + 2, 289, + _vq_lengthlist__16c0_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c0_s_p6_0, + NULL, + &_vq_auxt__16c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,11,10,10,11, + 11,10, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11, + 11,11,11,10, 6, 9, 9,11,12,12,11, 9, 9, 6, 9,10, + 11,12,12,11, 9,10, 7,11,11,11,11,11,12,13,12, 6, + 9,10,11,10,10,12,13,13, 6,10, 9,11,10,10,11,12, + 13, +}; + +static float _vq_quantthresh__16c0_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c0_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p7_0 = { + _vq_quantthresh__16c0_s_p7_0, + _vq_quantmap__16c0_s_p7_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p7_0 = { + 4, 81, + _vq_lengthlist__16c0_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c0_s_p7_0, + NULL, + &_vq_auxt__16c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c0_s_p7_1[] = { + 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, + 8, 8, 8, 9, 9, 9,10,10,10, 6, 7, 8, 8, 8, 8, 9, + 8,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, 7, + 7, 8, 8, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9, 9, + 9, 9,11,11,11, 8, 8, 9, 9, 9, 9, 9,10,10,11,11, + 9, 9, 9, 9, 9, 9, 9,10,11,11,11,10,11, 9, 9, 9, + 9,10, 9,11,11,11,10,11,10,10, 9, 9,10,10,11,11, + 11,11,11, 9, 9, 9, 9,10,10, +}; + +static float _vq_quantthresh__16c0_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c0_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p7_1 = { + _vq_quantthresh__16c0_s_p7_1, + _vq_quantmap__16c0_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c0_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c0_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p7_1, + NULL, + &_vq_auxt__16c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c0_s_p8_0[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8,10,10, 6, 5, 6, + 8, 8, 8, 8, 8, 8, 8, 9,10,10, 7, 6, 6, 8, 8, 8, + 8, 8, 8, 8, 8,10,10, 0, 8, 8, 8, 8, 9, 8, 9, 9, + 9,10,10,10, 0, 9, 8, 8, 8, 9, 9, 8, 8, 9, 9,10, + 10, 0,12,11, 8, 8, 9, 9, 9, 9,10,10,11,10, 0,12, + 13, 8, 8, 9,10, 9, 9,11,11,11,12, 0, 0, 0, 8, 8, + 8, 8,10, 9,12,13,12,14, 0, 0, 0, 8, 8, 8, 9,10, + 10,12,12,13,14, 0, 0, 0,13,13, 9, 9,11,11, 0, 0, + 14, 0, 0, 0, 0,14,14,10,10,12,11,12,14,14,14, 0, + 0, 0, 0, 0,11,11,13,13,14,13,14,14, 0, 0, 0, 0, + 0,12,13,13,12,13,14,14,14, +}; + +static float _vq_quantthresh__16c0_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c0_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p8_0 = { + _vq_quantthresh__16c0_s_p8_0, + _vq_quantmap__16c0_s_p8_0, + 13, + 13 +}; + +static static_codebook _16c0_s_p8_0 = { + 2, 169, + _vq_lengthlist__16c0_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c0_s_p8_0, + NULL, + &_vq_auxt__16c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p8_1[] = { + 1, 4, 3, 5, 5, 7, 7, 7, 6, 6, 7, 7, 7, 5, 5, 7, + 7, 7, 6, 6, 7, 7, 7, 6, 6, +}; + +static float _vq_quantthresh__16c0_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p8_1 = { + _vq_quantthresh__16c0_s_p8_1, + _vq_quantmap__16c0_s_p8_1, + 5, + 5 +}; + +static static_codebook _16c0_s_p8_1 = { + 2, 25, + _vq_lengthlist__16c0_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p8_1, + NULL, + &_vq_auxt__16c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p9_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__16c0_s_p9_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__16c0_s_p9_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_0 = { + _vq_quantthresh__16c0_s_p9_0, + _vq_quantmap__16c0_s_p9_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p9_0 = { + 4, 81, + _vq_lengthlist__16c0_s_p9_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__16c0_s_p9_0, + NULL, + &_vq_auxt__16c0_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c0_s_p9_1[] = { + 1, 5, 5, 5, 5, 9,11,11,10,10,10,10,10,10,10, 7, + 6, 6, 6, 6,10,10,10,10,10,10,10,10,10,10, 7, 6, + 6, 6, 6,10, 9,10,10,10,10,10,10,10,10,10, 7, 7, + 8, 9,10,10,10,10,10,10,10,10,10,10,10, 8, 7,10, + 10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16c0_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c0_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_1 = { + _vq_quantthresh__16c0_s_p9_1, + _vq_quantmap__16c0_s_p9_1, + 15, + 15 +}; + +static static_codebook _16c0_s_p9_1 = { + 2, 225, + _vq_lengthlist__16c0_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c0_s_p9_1, + NULL, + &_vq_auxt__16c0_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c0_s_p9_2[] = { + 1, 5, 5, 7, 8, 8, 7, 9, 9, 9,12,12,11,12,12,10, + 10,11,12,12,12,11,12,12, 8, 9, 8, 7, 9,10,10,11, + 11,10,11,12,10,12,10,12,12,12,11,12,11, 9, 8, 8, + 9,10, 9, 8, 9,10,12,12,11,11,12,11,10,11,12,11, + 12,12, 8, 9, 9, 9,10,11,12,11,12,11,11,11,11,12, + 12,11,11,12,12,11,11, 9, 9, 8, 9, 9,11, 9, 9,10, + 9,11,11,11,11,12,11,11,10,12,12,12, 9,12,11,10, + 11,11,11,11,12,12,12,11,11,11,12,10,12,12,12,10, + 10, 9,10, 9,10,10, 9, 9, 9,10,10,12,10,11,11, 9, + 11,11,10,11,11,11,10,10,10, 9, 9,10,10, 9, 9,10, + 11,11,10,11,10,11,10,11,11,10,11,11,11,10, 9,10, + 10, 9,10, 9, 9,11, 9, 9,11,10,10,11,11,10,10,11, + 10,11, 8, 9,11,11,10, 9,10,11,11,10,11,11,10,10, + 10,11,10, 9,10,10,11, 9,10,10, 9,11,10,10,10,10, + 11,10,11,11, 9,11,10,11,10,10,11,11,10,10,10, 9, + 10,10,11,11,11, 9,10,10,10,10,10,11,10,10,10, 9, + 10,10,11,10,10,10,10,10, 9,10,11,10,10,10,10,11, + 11,11,10,10,10,10,10,11,10,11,10,11,10,10,10, 9, + 11,11,10,10,10,11,11,10,10,10,10,10,10,10,10,11, + 11, 9,10,10,10,11,10,11,10,10,10,11, 9,10,11,10, + 11,10,10, 9,10,10,10,11,10,11,10,10,10,10,10,11, + 11,10,11,11,10,10,11,11,10, 9, 9,10,10,10,10,10, + 9,11, 9,10,10,10,11,11,10,10,10,10,11,11,11,10, + 9, 9,10,10,11,10,10,10,10,10,11,11,11,10,10,10, + 11,11,11, 9,10,10,10,10, 9,10, 9,10,11,10,11,10, + 10,11,11,10,11,11,11,11,11,10,11,10,10,10, 9,11, + 11,10,11,11,11,11,11,11,11,11,11,10,11,10,10,10, + 10,11,10,10,11, 9,10,10,10, +}; + +static float _vq_quantthresh__16c0_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c0_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_2 = { + _vq_quantthresh__16c0_s_p9_2, + _vq_quantmap__16c0_s_p9_2, + 21, + 21 +}; + +static static_codebook _16c0_s_p9_2 = { + 2, 441, + _vq_lengthlist__16c0_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c0_s_p9_2, + NULL, + &_vq_auxt__16c0_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c0_s_single[] = { + 3, 4,19, 7, 9, 7, 8,11, 9,12, 4, 1,19, 6, 7, 7, + 8,10,11,13,18,18,18,18,18,18,18,18,18,18, 8, 6, + 18, 8, 9, 9,11,12,14,18, 9, 6,18, 9, 7, 8, 9,11, + 12,18, 7, 6,18, 8, 7, 7, 7, 9,11,17, 8, 8,18, 9, + 7, 6, 6, 8,11,17,10,10,18,12, 9, 8, 7, 9,12,18, + 13,15,18,15,13,11,10,11,15,18,14,18,18,18,18,18, + 16,16,18,18, +}; + +static static_codebook _huff_book__16c0_s_single = { + 2, 100, + _huff_lengthlist__16c0_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16c1_s_long[] = { + 2, 5,20, 7,10, 7, 8,10,11,11, 4, 2,20, 5, 8, 6, + 7, 9,10,10,20,20,20,20,19,19,19,19,19,19, 7, 5, + 19, 6,10, 7, 9,11,13,17,11, 8,19,10, 7, 7, 8,10, + 11,15, 7, 5,19, 7, 7, 5, 6, 9,11,16, 7, 6,19, 8, + 7, 6, 6, 7, 9,13, 9, 9,19,11, 9, 8, 6, 7, 8,13, + 12,14,19,16,13,10, 9, 8, 9,13,14,17,19,18,18,17, + 12,11,11,13, +}; + +static static_codebook _huff_book__16c1_s_long = { + 2, 100, + _huff_lengthlist__16c1_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c1_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p1_0 = { + _vq_quantthresh__16c1_s_p1_0, + _vq_quantmap__16c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__16c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c1_s_p1_0, + NULL, + &_vq_auxt__16c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p2_0 = { + _vq_quantthresh__16c1_s_p2_0, + _vq_quantmap__16c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p2_0, + NULL, + &_vq_auxt__16c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p3_0 = { + _vq_quantthresh__16c1_s_p3_0, + _vq_quantmap__16c1_s_p3_0, + 5, + 5 +}; + +static static_codebook _16c1_s_p3_0 = { + 4, 625, + _vq_lengthlist__16c1_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p3_0, + NULL, + &_vq_auxt__16c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c1_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p4_0 = { + _vq_quantthresh__16c1_s_p4_0, + _vq_quantmap__16c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _16c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__16c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p4_0, + NULL, + &_vq_auxt__16c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c1_s_p5_0[] = { + 1, 3, 3, 5, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 8, 8, + 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__16c1_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c1_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p5_0 = { + _vq_quantthresh__16c1_s_p5_0, + _vq_quantmap__16c1_s_p5_0, + 9, + 9 +}; + +static static_codebook _16c1_s_p5_0 = { + 2, 81, + _vq_lengthlist__16c1_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p5_0, + NULL, + &_vq_auxt__16c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c1_s_p6_0[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,12, + 12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 0, 0, 8, 8, 8, 9,10, 9,10,10,10,10, + 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,11, + 11,11,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__16c1_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c1_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p6_0 = { + _vq_quantthresh__16c1_s_p6_0, + _vq_quantmap__16c1_s_p6_0, + 17, + 17 +}; + +static static_codebook _16c1_s_p6_0 = { + 2, 289, + _vq_lengthlist__16c1_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c1_s_p6_0, + NULL, + &_vq_auxt__16c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9,10,10, + 10, 9, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11, + 11,11,10,10, 6,10, 9,11,11,11,11,10,10, 6,10,10, + 11,11,11,11,10,10, 7,11,11,11,11,11,12,12,11, 6, + 10,10,11,10,10,11,11,11, 6,10,10,10,11,10,11,11, + 11, +}; + +static float _vq_quantthresh__16c1_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c1_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p7_0 = { + _vq_quantthresh__16c1_s_p7_0, + _vq_quantmap__16c1_s_p7_0, + 3, + 3 +}; + +static static_codebook _16c1_s_p7_0 = { + 4, 81, + _vq_lengthlist__16c1_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c1_s_p7_0, + NULL, + &_vq_auxt__16c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c1_s_p7_1[] = { + 2, 3, 3, 5, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6, + 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8, + 8, 9, 9,10,10,10,10,10, 9, 9, 8, 8, 9, 9,10,10, + 10,10,10, 8, 8, 8, 8, 9, 9, +}; + +static float _vq_quantthresh__16c1_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c1_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p7_1 = { + _vq_quantthresh__16c1_s_p7_1, + _vq_quantmap__16c1_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c1_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c1_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p7_1, + NULL, + &_vq_auxt__16c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c1_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5, + 7, 8, 8, 9, 8, 8, 9, 9,10,11, 6, 5, 5, 8, 8, 9, + 9, 8, 8, 9,10,10,11, 0, 8, 8, 8, 9, 9, 9, 9, 9, + 10,10,11,11, 0, 9, 9, 9, 8, 9, 9, 9, 9,10,10,11, + 11, 0,13,13, 9, 9,10,10,10,10,11,11,12,12, 0,14, + 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10, + 9, 9,11,11,12,12,13,12, 0, 0, 0,10,10, 9, 9,10, + 10,12,12,13,13, 0, 0, 0,13,14,11,10,11,11,12,12, + 13,14, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,12,12,13,13,14,15, 0, 0, 0, 0, + 0,12,12,12,12,13,13,14,15, +}; + +static float _vq_quantthresh__16c1_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p8_0 = { + _vq_quantthresh__16c1_s_p8_0, + _vq_quantmap__16c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _16c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__16c1_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c1_s_p8_0, + NULL, + &_vq_auxt__16c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p8_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__16c1_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p8_1 = { + _vq_quantthresh__16c1_s_p8_1, + _vq_quantmap__16c1_s_p8_1, + 5, + 5 +}; + +static static_codebook _16c1_s_p8_1 = { + 2, 25, + _vq_lengthlist__16c1_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p8_1, + NULL, + &_vq_auxt__16c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c1_s_p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c1_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__16c1_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_0 = { + _vq_quantthresh__16c1_s_p9_0, + _vq_quantmap__16c1_s_p9_0, + 13, + 13 +}; + +static static_codebook _16c1_s_p9_0 = { + 2, 169, + _vq_lengthlist__16c1_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__16c1_s_p9_0, + NULL, + &_vq_auxt__16c1_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c1_s_p9_1[] = { + 1, 4, 4, 4, 4, 8, 8,12,13,14,14,14,14,14,14, 6, + 6, 6, 6, 6,10, 9,14,14,14,14,14,14,14,14, 7, 6, + 5, 6, 6,10, 9,12,13,13,13,13,13,13,13,13, 7, 7, + 9, 9,11,11,12,13,13,13,13,13,13,13,13, 7, 7, 8, + 8,11,12,13,13,13,13,13,13,13,13,13,12,12,10,10, + 13,12,13,13,13,13,13,13,13,13,13,12,12,10,10,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,12,13,12, + 13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13, +}; + +static float _vq_quantthresh__16c1_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c1_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_1 = { + _vq_quantthresh__16c1_s_p9_1, + _vq_quantmap__16c1_s_p9_1, + 15, + 15 +}; + +static static_codebook _16c1_s_p9_1 = { + 2, 225, + _vq_lengthlist__16c1_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c1_s_p9_1, + NULL, + &_vq_auxt__16c1_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c1_s_p9_2[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9,10, + 10,10, 9,10,10,11,12,12, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,10,10,10,11,11,10,12,11,11,13,11, 7, 7, 8, + 8, 8, 8, 9, 9, 9,10,10,10,10, 9,10,10,11,11,12, + 11,11, 8, 8, 8, 8, 9, 9,10,10,10,10,11,11,11,11, + 11,11,11,12,11,12,12, 8, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,11,11,11,11,11,11,12,11, 9, 9, 9, 9, + 10,10,10,10,11,10,11,11,11,11,11,11,12,12,12,12, + 11, 9, 9, 9, 9,10,10,10,10,11,11,11,11,11,11,11, + 11,11,12,12,12,13, 9,10,10, 9,11,10,10,10,10,11, + 11,11,11,11,10,11,12,11,12,12,11,12,11,10, 9,10, + 10,11,10,11,11,11,11,11,11,11,11,11,12,12,11,12, + 12,12,10,10,10,11,10,11,11,11,11,11,11,11,11,11, + 11,11,12,13,12,12,11, 9,10,10,11,11,10,11,11,11, + 12,11,11,11,11,11,12,12,13,13,12,13,10,10,12,10, + 11,11,11,11,11,11,11,11,11,12,12,11,13,12,12,12, + 12,13,12,11,11,11,11,11,11,12,11,12,11,11,11,11, + 12,12,13,12,11,12,12,11,11,11,11,11,12,11,11,11, + 11,12,11,11,12,11,12,13,13,12,12,12,12,11,11,11, + 11,11,12,11,11,12,11,12,11,11,11,11,13,12,12,12, + 12,13,11,11,11,12,12,11,11,11,12,11,12,12,12,11, + 12,13,12,11,11,12,12,11,12,11,11,11,12,12,11,12, + 11,11,11,12,12,12,12,13,12,13,12,12,12,12,11,11, + 12,11,11,11,11,11,11,12,12,12,13,12,11,13,13,12, + 12,11,12,10,11,11,11,11,12,11,12,12,11,12,12,13, + 12,12,13,12,12,12,12,12,11,12,12,12,11,12,11,11, + 11,12,13,12,13,13,13,13,13,12,13,13,12,12,13,11, + 11,11,11,11,12,11,11,12,11, +}; + +static float _vq_quantthresh__16c1_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c1_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_2 = { + _vq_quantthresh__16c1_s_p9_2, + _vq_quantmap__16c1_s_p9_2, + 21, + 21 +}; + +static static_codebook _16c1_s_p9_2 = { + 2, 441, + _vq_lengthlist__16c1_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c1_s_p9_2, + NULL, + &_vq_auxt__16c1_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c1_s_short[] = { + 5, 6,17, 8,12, 9,10,10,12,13, 5, 2,17, 4, 9, 5, + 7, 8,11,13,16,16,16,16,16,16,16,16,16,16, 6, 4, + 16, 5,10, 5, 7,10,14,16,13, 9,16,11, 8, 7, 8, 9, + 13,16, 7, 4,16, 5, 7, 4, 6, 8,11,13, 8, 6,16, 7, + 8, 5, 5, 7, 9,13, 9, 8,16, 9, 8, 6, 6, 7, 9,13, + 11,11,16,10,10, 7, 7, 7, 9,13,13,13,16,13,13, 9, + 9, 9,10,13, +}; + +static static_codebook _huff_book__16c1_s_short = { + 2, 100, + _huff_lengthlist__16c1_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16c2_s_long[] = { + 4, 7, 9, 9, 9, 8, 9,10,15,19, 5, 4, 5, 6, 7, 7, + 8, 9,14,16, 6, 5, 4, 5, 6, 7, 8,10,12,19, 7, 6, + 5, 4, 5, 6, 7, 9,11,18, 8, 7, 6, 5, 5, 5, 7, 9, + 10,17, 8, 7, 7, 5, 5, 5, 6, 7,12,18, 8, 8, 8, 7, + 7, 5, 5, 7,12,18, 8, 9,10, 9, 9, 7, 6, 7,12,17, + 14,18,16,16,15,12,11,10,12,18,15,17,18,18,18,15, + 14,14,16,18, +}; + +static static_codebook _huff_book__16c2_s_long = { + 2, 100, + _huff_lengthlist__16c2_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c2_s_p1_0[] = { + 1, 3, 3, 0, 0, 0, 0, 0, 0, 4, 5, 5, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c2_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p1_0 = { + _vq_quantthresh__16c2_s_p1_0, + _vq_quantmap__16c2_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c2_s_p1_0 = { + 4, 81, + _vq_lengthlist__16c2_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c2_s_p1_0, + NULL, + &_vq_auxt__16c2_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c2_s_p2_0[] = { + 2, 4, 3, 7, 7, 0, 0, 0, 7, 8, 0, 0, 0, 8, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 4, 5, 4, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, + 9, 9, 4, 4, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, + 8, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 7, 8, 8,10,10, + 0, 0, 0,12,11, 0, 0, 0,11,11, 0, 0, 0,14,13, 0, + 0, 0,14,13, 7, 8, 8, 9,10, 0, 0, 0,11,12, 0, 0, + 0,11,11, 0, 0, 0,14,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,11,11, 0, 0, 0, + 11,11, 0, 0, 0,12,11, 0, 0, 0,12,12, 0, 0, 0,13, + 13, 8, 8, 8,11,11, 0, 0, 0,11,11, 0, 0, 0,11,12, + 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 8, 8,12,11, 0, 0, 0,12,11, 0, + 0, 0,11,11, 0, 0, 0,13,13, 0, 0, 0,13,12, 8, 8, + 8,11,12, 0, 0, 0,11,12, 0, 0, 0,11,11, 0, 0, 0, + 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 9, 9,14,13, 0, 0, 0,13,12, 0, 0, 0,13, + 13, 0, 0, 0,13,12, 0, 0, 0,13,13, 8, 9, 9,13,14, + 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 9, 9,14,13, 0, 0, 0,13,13, 0, 0, 0,13,12, 0, 0, + 0,13,13, 0, 0, 0,13,12, 8, 9, 9,14,14, 0, 0, 0, + 13,13, 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12, + 13, +}; + +static float _vq_quantthresh__16c2_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c2_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p2_0 = { + _vq_quantthresh__16c2_s_p2_0, + _vq_quantmap__16c2_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c2_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c2_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c2_s_p2_0, + NULL, + &_vq_auxt__16c2_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c2_s_p3_0[] = { + 1, 3, 3, 6, 6, 7, 7, 8, 8, 0, 0, 0, 6, 6, 7, 7, + 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c2_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p3_0 = { + _vq_quantthresh__16c2_s_p3_0, + _vq_quantmap__16c2_s_p3_0, + 9, + 9 +}; + +static static_codebook _16c2_s_p3_0 = { + 2, 81, + _vq_lengthlist__16c2_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p3_0, + NULL, + &_vq_auxt__16c2_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c2_s_p4_0[] = { + 2, 3, 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9,10, + 10, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10, + 11,11, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10, + 10,10,11, 0, 0, 0, 6, 6, 8, 8, 8, 8, 9, 9,10,10, + 10,11,11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c2_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p4_0 = { + _vq_quantthresh__16c2_s_p4_0, + _vq_quantmap__16c2_s_p4_0, + 17, + 17 +}; + +static static_codebook _16c2_s_p4_0 = { + 2, 289, + _vq_lengthlist__16c2_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p4_0, + NULL, + &_vq_auxt__16c2_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c2_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,10,10,10, + 10,10, 4, 7, 6,10,10,10,10,10,10, 5, 9, 9, 9,12, + 11,10,11,12, 7,10,10,12,12,12,12,12,12, 7,10,10, + 11,12,12,12,12,13, 6,10,10,10,12,12,10,12,12, 7, + 10,10,11,13,12,12,12,12, 7,10,10,11,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__16c2_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c2_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p5_0 = { + _vq_quantthresh__16c2_s_p5_0, + _vq_quantmap__16c2_s_p5_0, + 3, + 3 +}; + +static static_codebook _16c2_s_p5_0 = { + 4, 81, + _vq_lengthlist__16c2_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c2_s_p5_0, + NULL, + &_vq_auxt__16c2_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c2_s_p5_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11, 6, 6, + 7, 7, 8, 8, 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, + 8,11,11,11, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6, + 6, 8, 8, 8, 8, 9, 9,11,11,11, 7, 7, 8, 8, 8, 8, + 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 9,11,11,11, + 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,11,11, 8, 8, 8, + 8, 8, 8,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11, + 11,11,11, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c2_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p5_1 = { + _vq_quantthresh__16c2_s_p5_1, + _vq_quantmap__16c2_s_p5_1, + 11, + 11 +}; + +static static_codebook _16c2_s_p5_1 = { + 2, 121, + _vq_lengthlist__16c2_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p5_1, + NULL, + &_vq_auxt__16c2_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p6_0[] = { + 1, 4, 4, 7, 6, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 9, 9, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9,10,10,11,11,12,12, 0, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,12,12, + 12, 0,11,11, 8, 8,10,10,11,11,12,12,13,13, 0,11, + 12, 8, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__16c2_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c2_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p6_0 = { + _vq_quantthresh__16c2_s_p6_0, + _vq_quantmap__16c2_s_p6_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p6_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c2_s_p6_0, + NULL, + &_vq_auxt__16c2_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c2_s_p6_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__16c2_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c2_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p6_1 = { + _vq_quantthresh__16c2_s_p6_1, + _vq_quantmap__16c2_s_p6_1, + 5, + 5 +}; + +static static_codebook _16c2_s_p6_1 = { + 2, 25, + _vq_lengthlist__16c2_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c2_s_p6_1, + NULL, + &_vq_auxt__16c2_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 8, 8, 9, 9,10,10,11,11,12,12, 6, 5, 5, 8, 8, 9, + 9,10,10,11,11,12,13,18, 6, 6, 7, 7, 9, 9,10,10, + 12,12,13,13,18, 6, 6, 7, 7, 9, 9,10,10,12,12,13, + 13,18,11,10, 8, 8,10,10,11,11,12,12,13,13,18,11, + 11, 8, 8,10,10,11,11,12,13,13,13,18,18,18,10,11, + 11,11,12,12,13,13,14,14,18,18,18,11,11,11,11,12, + 12,13,13,14,14,18,18,18,14,14,12,12,12,12,14,14, + 15,14,18,18,18,15,15,11,12,12,12,13,13,15,15,18, + 18,18,18,18,13,13,13,13,13,14,17,16,18,18,18,18, + 18,13,14,13,13,14,13,15,14, +}; + +static float _vq_quantthresh__16c2_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__16c2_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p7_0 = { + _vq_quantthresh__16c2_s_p7_0, + _vq_quantmap__16c2_s_p7_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p7_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__16c2_s_p7_0, + NULL, + &_vq_auxt__16c2_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c2_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 6, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 6, 6, 7, 7, 8, 8, 8, + 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, + 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 9, 7, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 8, 8, 7, 7, 8, 8, 9, 9, + 9, 9, 9, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c2_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p7_1 = { + _vq_quantthresh__16c2_s_p7_1, + _vq_quantmap__16c2_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c2_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c2_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p7_1, + NULL, + &_vq_auxt__16c2_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c2_s_p8_0[] = { + 1, 4, 4, 7, 6, 7, 7, 6, 6, 8, 8, 9, 9,10,10, 6, + 6, 6, 8, 8, 9, 8, 8, 8, 9, 9,11,10,11,11, 7, 6, + 6, 8, 8, 9, 8, 7, 7, 9, 9,10,10,12,11,14, 8, 8, + 8, 9, 9, 9, 9, 9,10, 9,10,10,11,13,14, 8, 8, 8, + 8, 9, 9, 8, 8, 9, 9,10,10,11,12,14,13,11, 9, 9, + 9, 9, 9, 9, 9,10,11,10,13,12,14,11,13, 8, 9, 9, + 9, 9, 9,10,10,11,10,13,12,14,14,14, 8, 9, 9, 9, + 11,11,11,11,11,12,13,13,14,14,14, 9, 8, 9, 9,10, + 10,12,10,11,12,12,14,14,14,14,11,12,10,10,12,12, + 12,12,13,14,12,12,14,14,14,12,12, 9,10,11,11,12, + 14,12,14,14,14,14,14,14,14,14,11,11,12,11,12,14, + 14,14,14,14,14,14,14,14,14,12,11,11,11,11,14,14, + 14,14,14,14,14,14,14,14,14,14,13,12,14,14,14,14, + 14,14,14,14,14,14,14,14,14,12,12,12,13,14,14,13, + 13, +}; + +static float _vq_quantthresh__16c2_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c2_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p8_0 = { + _vq_quantthresh__16c2_s_p8_0, + _vq_quantmap__16c2_s_p8_0, + 15, + 15 +}; + +static static_codebook _16c2_s_p8_0 = { + 2, 225, + _vq_lengthlist__16c2_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c2_s_p8_0, + NULL, + &_vq_auxt__16c2_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c2_s_p8_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,11,12,11, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9,11,11,10, 7, 7, 8, + 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 11,11, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 9,10, + 10, 9,10,10,11,11,12, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10, 9,10,10,10,10,11,11,11, 8, 8, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 9, 8, 9, 9, 9, 9,10, 9, 9, 9,10,10,10, + 10, 9,10,11,11,11, 9, 9, 9, 9,10, 9, 9, 9,10,10, + 9,10, 9,10,10,10,10,10,11,12,11,11,11, 9, 9, 9, + 9, 9,10,10, 9,10,10,10,10,10,10,10,10,12,11,13, + 13,11, 9, 9, 9, 9,10,10, 9,10,10,10,10,11,10,10, + 10,10,11,12,11,12,11, 9, 9, 9,10,10, 9,10,10,10, + 10,10,10,10,10,10,10,11,11,11,12,11, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,11,12,12,12, + 11,11,11,10, 9,10,10,10,10,10,10,10,10,11,10,10, + 10,11,11,11,11,11,11,11,10,10,10,11,10,10,10,10, + 10,10,10,10,10,10,11,11,11,11,12,12,11,10,10,10, + 10,10,10,10,10,11,10,10,10,11,10,12,11,11,12,11, + 11,11,10,10,10,10,10,11,10,10,10,10,10,11,10,10, + 11,11,11,12,11,12,11,11,12,10,10,10,10,10,10,10, + 11,10,10,11,10,12,11,11,11,12,11,11,11,11,10,10, + 10,10,10,10,10,11,11,11,10,11,12,11,11,11,12,11, + 12,11,12,10,11,10,10,10,10,11,10,10,10,10,10,10, + 12,11,11,11,11,11,12,12,10,10,10,10,10,11,10,10, + 11,10,11,11,11,11,11,11,11,11,11,11,11,11,12,11, + 10,11,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__16c2_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c2_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p8_1 = { + _vq_quantthresh__16c2_s_p8_1, + _vq_quantmap__16c2_s_p8_1, + 21, + 21 +}; + +static static_codebook _16c2_s_p8_1 = { + 2, 441, + _vq_lengthlist__16c2_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p8_1, + NULL, + &_vq_auxt__16c2_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p9_0[] = { + -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5, + 2327.5, 3258.5, 4189.5, 5120.5, +}; + +static long _vq_quantmap__16c2_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_0 = { + _vq_quantthresh__16c2_s_p9_0, + _vq_quantmap__16c2_s_p9_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p9_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p9_0, + 1, -510275072, 1631393792, 4, 0, + _vq_quantlist__16c2_s_p9_0, + NULL, + &_vq_auxt__16c2_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_1[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c2_s_p9_1[] = { + 1, 5, 5, 9, 8, 7, 7, 7, 6,10,11,11,11,11,11,11, + 11, 8, 7, 6, 8, 8,10, 9,10,10,10, 9,11,10,10,10, + 10,10, 8, 6, 6, 8, 8, 9, 8, 9, 8, 9,10,10,10,10, + 10,10,10,10, 8,10, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10,10, 8, 9, 9, 9,10,10, 9,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 8, 9, 9,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 8, 8, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9,10, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 8, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9,10, 9,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16c2_s_p9_1[] = { + -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, + 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, 367.5, +}; + +static long _vq_quantmap__16c2_s_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_1 = { + _vq_quantthresh__16c2_s_p9_1, + _vq_quantmap__16c2_s_p9_1, + 17, + 17 +}; + +static static_codebook _16c2_s_p9_1 = { + 2, 289, + _vq_lengthlist__16c2_s_p9_1, + 1, -518488064, 1622704128, 5, 0, + _vq_quantlist__16c2_s_p9_1, + NULL, + &_vq_auxt__16c2_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_2[] = { + 13, + 12, + 14, + 11, + 15, + 10, + 16, + 9, + 17, + 8, + 18, + 7, + 19, + 6, + 20, + 5, + 21, + 4, + 22, + 3, + 23, + 2, + 24, + 1, + 25, + 0, + 26, +}; + +static long _vq_lengthlist__16c2_s_p9_2[] = { + 1, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 8, 7, 8, 7, 7, 4, 4, +}; + +static float _vq_quantthresh__16c2_s_p9_2[] = { + -12.5, -11.5, -10.5, -9.5, -8.5, -7.5, -6.5, -5.5, + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, + 11.5, 12.5, +}; + +static long _vq_quantmap__16c2_s_p9_2[] = { + 25, 23, 21, 19, 17, 15, 13, 11, + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, 12, 14, 16, 18, 20, + 22, 24, 26, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_2 = { + _vq_quantthresh__16c2_s_p9_2, + _vq_quantmap__16c2_s_p9_2, + 27, + 27 +}; + +static static_codebook _16c2_s_p9_2 = { + 1, 27, + _vq_lengthlist__16c2_s_p9_2, + 1, -528875520, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p9_2, + NULL, + &_vq_auxt__16c2_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c2_s_short[] = { + 7,10,11,11,11,14,15,15,17,14, 8, 6, 7, 7, 8, 9, + 11,11,14,17, 9, 6, 6, 6, 7, 7,10,11,15,16, 9, 6, + 6, 4, 4, 5, 8, 9,12,16,10, 6, 6, 4, 4, 4, 6, 9, + 13,16,10, 7, 6, 5, 4, 3, 5, 7,13,16,11, 9, 8, 7, + 6, 5, 5, 6,12,15,10,10,10, 9, 7, 6, 6, 7,11,15, + 13,13,13,13,11,10,10, 9,12,16,16,16,16,14,16,15, + 15,12,14,14, +}; + +static static_codebook _huff_book__16c2_s_short = { + 2, 100, + _huff_lengthlist__16c2_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_s_long[] = { + 3, 4,18, 8, 8, 8, 9,10,11,13, 3, 2,18, 5, 5, 6, + 8,11,12,12,18,18,18,18,18,18,18,18,18,18, 8, 5, + 18, 7, 8, 8,10,14,14,16, 8, 5,18, 7, 5, 6, 7,11, + 12,13, 8, 6,18, 7, 5, 6, 7,10,12,14, 8, 7,18,10, + 7, 6, 6, 8,11,14, 9,10,18,13, 9, 7, 6, 8,10,13, + 11,13,18,16,13,10, 9, 8, 8,11,12,17,18,17,18,14, + 11, 9,10,14, +}; + +static static_codebook _huff_book__44c0_s_long = { + 2, 100, + _huff_lengthlist__44c0_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p1_0 = { + _vq_quantthresh__44c0_s_p1_0, + _vq_quantmap__44c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c0_s_p1_0, + NULL, + &_vq_auxt__44c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p2_0 = { + _vq_quantthresh__44c0_s_p2_0, + _vq_quantmap__44c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_s_p2_0, + NULL, + &_vq_auxt__44c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p3_0 = { + _vq_quantthresh__44c0_s_p3_0, + _vq_quantmap__44c0_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c0_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c0_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_s_p3_0, + NULL, + &_vq_auxt__44c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_s_p4_0[] = { + 1, 3, 2, 8, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p4_0 = { + _vq_quantthresh__44c0_s_p4_0, + _vq_quantmap__44c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p4_0, + NULL, + &_vq_auxt__44c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_s_p5_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 6, 7, 7, 7, + 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8,10, 9, 0, 0, 0, + 8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10, 9, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c0_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p5_0 = { + _vq_quantthresh__44c0_s_p5_0, + _vq_quantmap__44c0_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c0_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c0_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p5_0, + NULL, + &_vq_auxt__44c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_s_p6_0[] = { + 1, 3, 4, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9,10,10,10, + 10,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 9,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10, 9,10,10,11,11,11,12,12,13,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13, + 14, +}; + +static float _vq_quantthresh__44c0_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p6_0 = { + _vq_quantthresh__44c0_s_p6_0, + _vq_quantmap__44c0_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c0_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c0_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_s_p6_0, + NULL, + &_vq_auxt__44c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11, + 10,11,10,10, 6, 9, 9,11,10,10,11, 9,10, 6, 9, 9, + 11,10,10,11, 9, 9, 7,10,10,11,11,11,12,11,11, 7, + 9, 9,10, 9, 9,11,11,10, 7, 9, 9,10,10,10,12,10, + 11, +}; + +static float _vq_quantthresh__44c0_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c0_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p7_0 = { + _vq_quantthresh__44c0_s_p7_0, + _vq_quantmap__44c0_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c0_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c0_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c0_s_p7_0, + NULL, + &_vq_auxt__44c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c0_s_p7_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 7, 7,10, 9, 9, 6, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 6, 6, 7, 7, 8, 8, 8, + 8,10, 9,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c0_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c0_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p7_1 = { + _vq_quantthresh__44c0_s_p7_1, + _vq_quantmap__44c0_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c0_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c0_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p7_1, + NULL, + &_vq_auxt__44c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 9, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 8, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 8, 9, 9,10,10,10,11,12,11, 0,13, + 13, 9, 8, 9, 9,10,10,10,11,11,11, 0, 0, 0,10,10, + 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 8,10, + 10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 12,12, 0, 0, 0,15,15,10,10,11, 9,12,12,13,13, 0, + 0, 0, 0, 0,12,11,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,11,12,11,14,13, +}; + +static float _vq_quantthresh__44c0_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c0_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p8_0 = { + _vq_quantthresh__44c0_s_p8_0, + _vq_quantmap__44c0_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c0_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c0_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c0_s_p8_0, + NULL, + &_vq_auxt__44c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p8_1[] = { + 2, 3, 4, 4, 4, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c0_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p8_1 = { + _vq_quantthresh__44c0_s_p8_1, + _vq_quantmap__44c0_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c0_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c0_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_s_p8_1, + NULL, + &_vq_auxt__44c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p9_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p9_0[] = { + 1, 7, 7,11,11,10,11,11,11,11, 9,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11, 8,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11, 8,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44c0_s_p9_0[] = { + -331.5, -110.5, 110.5, 331.5, +}; + +static long _vq_quantmap__44c0_s_p9_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p9_0 = { + _vq_quantthresh__44c0_s_p9_0, + _vq_quantmap__44c0_s_p9_0, + 5, + 5 +}; + +static static_codebook _44c0_s_p9_0 = { + 4, 625, + _vq_lengthlist__44c0_s_p9_0, + 1, -518283264, 1627103232, 3, 0, + _vq_quantlist__44c0_s_p9_0, + NULL, + &_vq_auxt__44c0_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,12,12,13,12, 6, 5, 5, + 7, 7, 8, 8,10,10,12,11,14,13, 6, 5, 5, 7, 7, 7, + 8, 9, 9,11,12,13,12,15, 7, 7, 7, 7, 9, 9,11,11, + 14,13,14,13,15, 7, 7, 8, 8, 8, 9,10,10,11,11,12, + 11,15,10,10, 8, 8,10,10,12,11,13,15,14,14,15,11, + 10, 8, 8,11,11,11,11,13,13,12,13,15,15,15,10,10, + 10,10,12,13,13,13,15,14,15,15,15,10,10,10,11,13, + 14,13,14,14,14,15,15,15,15,15,11,12,11,13,14,14, + 15,15,15,15,15,14,15,11,11,13,12,14,13,15,15,15, + 15,15,15,15,13,12,13,12,15,15,15,15,15,15,15,15, + 15,12,13,12,12,15,14,15,15, +}; + +static float _vq_quantthresh__44c0_s_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c0_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p9_1 = { + _vq_quantthresh__44c0_s_p9_1, + _vq_quantmap__44c0_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c0_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c0_s_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c0_s_p9_1, + NULL, + &_vq_auxt__44c0_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_s_p9_2[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, + 9,10,10,10, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,11,10,10, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9,10, 9, 9,10,10,11, 9, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11, 9, 8, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,11,11,10,11,11, 9, 9, + 9, 9, 9, 9,10, 9, 9, 9,10, 9,10,10,10,11,11, 9, + 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10,11,10,10,10,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10, + 11,11,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 11,11,10,10, 9,10,10,10, 9,10, 9, 9, 9, 9,10,10, + 11,10,11,11,11, 9,10, 9, 9, 9, 9, 9, 9, 9,10,10, + 11,10,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,11,11,10,11,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c0_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p9_2 = { + _vq_quantthresh__44c0_s_p9_2, + _vq_quantmap__44c0_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c0_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c0_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_s_p9_2, + NULL, + &_vq_auxt__44c0_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_s_short[] = { + 6, 8,17,12,12,12,14,15,17,16, 5, 1,16, 5, 6, 6, + 9,12,14,13,16,16,16,16,16,16,16,16,16,16, 9, 4, + 16, 6, 9, 7,10,14,14,14, 8, 5,16, 8, 6, 7,10,13, + 15,16, 9, 6,16, 7, 7, 7,10,12,15,14,10, 8,16, 9, + 9, 9,10,12,15,14,13, 7,16, 8, 7, 7,10,12,14,13, + 15, 6,16, 7, 5, 5, 7, 9,13,16,14, 7,16, 8, 6, 6, + 8, 9,11,14, +}; + +static static_codebook _huff_book__44c0_s_short = { + 2, 100, + _huff_lengthlist__44c0_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_sm_long[] = { + 3, 4,10, 8,11, 9,10,10,11,13, 3, 2,10, 5, 8, 6, + 8,11,12,13,10, 8, 7,10, 7, 8, 9,11,12,13, 8, 5, + 12, 6, 9, 7,10,13,14,16,11, 7, 7, 9, 5, 6, 7,10, + 13,13, 8, 6, 7, 7, 5, 5, 6, 9,12,13, 9, 8, 8, 8, + 7, 6, 6, 8,11,14,10,10,10,11, 9, 8, 7, 8,10,13, + 11,14,12,15,13,11, 9, 8, 9,12,12,18,15,18,17,15, + 12,10,10,14, +}; + +static static_codebook _huff_book__44c0_sm_long = { + 2, 100, + _huff_lengthlist__44c0_sm_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_sm_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c0_sm_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p1_0 = { + _vq_quantthresh__44c0_sm_p1_0, + _vq_quantmap__44c0_sm_p1_0, + 3, + 3 +}; + +static static_codebook _44c0_sm_p1_0 = { + 8, 6561, + _vq_lengthlist__44c0_sm_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c0_sm_p1_0, + NULL, + &_vq_auxt__44c0_sm_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_sm_p2_0[] = { + 1, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 6, 6, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 8, + 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0,10, 9, 0, 0, 0, 0, 0, 0, 0, 6, + 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, + 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8,10,10, 0, 0, 0,10,10, 0, 0, 0, 9,10, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0,10, + 10, 0, 0, 0,10, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_sm_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p2_0 = { + _vq_quantthresh__44c0_sm_p2_0, + _vq_quantmap__44c0_sm_p2_0, + 5, + 5 +}; + +static static_codebook _44c0_sm_p2_0 = { + 4, 625, + _vq_lengthlist__44c0_sm_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_sm_p2_0, + NULL, + &_vq_auxt__44c0_sm_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_sm_p3_0[] = { + 2, 3, 4, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_sm_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p3_0 = { + _vq_quantthresh__44c0_sm_p3_0, + _vq_quantmap__44c0_sm_p3_0, + 5, + 5 +}; + +static static_codebook _44c0_sm_p3_0 = { + 4, 625, + _vq_lengthlist__44c0_sm_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_sm_p3_0, + NULL, + &_vq_auxt__44c0_sm_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_sm_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p4_0 = { + _vq_quantthresh__44c0_sm_p4_0, + _vq_quantmap__44c0_sm_p4_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p4_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p4_0, + NULL, + &_vq_auxt__44c0_sm_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p5_0[] = { + 1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, 8, 8, + 9, 9, 0, 6, 6, 7, 7, 8, 8,10,10, 0, 7, 7, 8, 8, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 8, 8, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c0_sm_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_sm_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p5_0 = { + _vq_quantthresh__44c0_sm_p5_0, + _vq_quantmap__44c0_sm_p5_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p5_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p5_0, + NULL, + &_vq_auxt__44c0_sm_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_sm_p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8,10,10,10,10,11, + 11, 0, 6, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 6, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 7, 7, 8, 8, 8, 8,10,10,10,10,11,11, + 11,11,12,12, 0, 0, 0, 8, 7, 8, 8,10,10,10,10,11, + 11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,12,13, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0, 0, 9, + 9,10, 9,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c0_sm_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_sm_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p6_0 = { + _vq_quantthresh__44c0_sm_p6_0, + _vq_quantmap__44c0_sm_p6_0, + 17, + 17 +}; + +static static_codebook _44c0_sm_p6_0 = { + 2, 289, + _vq_lengthlist__44c0_sm_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_sm_p6_0, + NULL, + &_vq_auxt__44c0_sm_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_sm_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 5, 7, 6,10, 9, 9,10, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10,10,10,11, 9,10, 6, 9, 9, + 10,10,10,11,10, 9, 7,10,10,11,11,11,11,11,11, 6, + 9, 9,10, 9,10,11,11,10, 6, 9, 9,10,10,10,11,10, + 11, +}; + +static float _vq_quantthresh__44c0_sm_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c0_sm_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_0 = { + _vq_quantthresh__44c0_sm_p7_0, + _vq_quantmap__44c0_sm_p7_0, + 3, + 3 +}; + +static static_codebook _44c0_sm_p7_0 = { + 4, 81, + _vq_lengthlist__44c0_sm_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c0_sm_p7_0, + NULL, + &_vq_auxt__44c0_sm_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c0_sm_p7_1[] = { + 2, 4, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 5, 5, 7, 7, + 7, 7, 8, 8, 8, 8, 9, 5, 5, 7, 7, 7, 7, 8, 8, 8, + 8,10, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c0_sm_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c0_sm_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_1 = { + _vq_quantthresh__44c0_sm_p7_1, + _vq_quantmap__44c0_sm_p7_1, + 11, + 11 +}; + +static static_codebook _44c0_sm_p7_1 = { + 2, 121, + _vq_lengthlist__44c0_sm_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p7_1, + NULL, + &_vq_auxt__44c0_sm_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_sm_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9,10,10, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10,10,11,11,12,11, 0,12, + 12, 9, 9, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9, 9, + 9,10,11,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,10,12,12,13,13, 0, + 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,10,12,11,14,14, +}; + +static float _vq_quantthresh__44c0_sm_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c0_sm_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_0 = { + _vq_quantthresh__44c0_sm_p8_0, + _vq_quantmap__44c0_sm_p8_0, + 13, + 13 +}; + +static static_codebook _44c0_sm_p8_0 = { + 2, 169, + _vq_lengthlist__44c0_sm_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c0_sm_p8_0, + NULL, + &_vq_auxt__44c0_sm_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_sm_p8_1[] = { + 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c0_sm_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_sm_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_1 = { + _vq_quantthresh__44c0_sm_p8_1, + _vq_quantmap__44c0_sm_p8_1, + 5, + 5 +}; + +static static_codebook _44c0_sm_p8_1 = { + 2, 25, + _vq_lengthlist__44c0_sm_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_sm_p8_1, + NULL, + &_vq_auxt__44c0_sm_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p9_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p9_0[] = { + 1, 3, 4,11,11,11,11,11,11, 4, 6, 6,10,10,10,10, + 10,10, 4, 6, 5,10,10,10,10,10,10,10, 6, 7,10, 9, + 10,10,10,10,10, 7, 9,10, 9,10,10,10,10,10, 9,10, + 7, 9,10,10,10,10,10,10,10, 9,10,10,10,10,10,10, + 10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44c0_sm_p9_0[] = { + -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, 552.5, 773.5, +}; + +static long _vq_quantmap__44c0_sm_p9_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p9_0 = { + _vq_quantthresh__44c0_sm_p9_0, + _vq_quantmap__44c0_sm_p9_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p9_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p9_0, + 1, -516186112, 1627103232, 4, 0, + _vq_quantlist__44c0_sm_p9_0, + NULL, + &_vq_auxt__44c0_sm_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_sm_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,12,12,13,13, 6, 5, 5, + 7, 7, 8, 8,10,10,12,12,14,13, 6, 5, 5, 6, 7, 8, + 8,10, 9,11,12,13,12,18, 7, 7, 7, 7, 9, 9,11,11, + 14,14,14,13,17, 7, 7, 8, 7, 9, 9,10,10,12,11,13, + 12,18,10,10, 8, 8,10,10,12,11,13,14,16,15,17,11, + 11, 8, 8,11,11,11,12,13,13,13,15,18,18,18,10,11, + 10,10,12,13,14,13,17,14,17,17,17,10,10,11,11,14, + 14,14,13,14,14,18,18,18,17,15,11,12,12,13,15,15, + 16,17,18,16,18,14,15,11,11,14,13,14,14,16,17,18, + 17,17,17,18,14,13,13,12,17,15,17,16,18,17,18,18, + 18,12,13,12,13,16,14,18,18, +}; + +static float _vq_quantthresh__44c0_sm_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c0_sm_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p9_1 = { + _vq_quantthresh__44c0_sm_p9_1, + _vq_quantmap__44c0_sm_p9_1, + 13, + 13 +}; + +static static_codebook _44c0_sm_p9_1 = { + 2, 169, + _vq_lengthlist__44c0_sm_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c0_sm_p9_1, + NULL, + &_vq_auxt__44c0_sm_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_sm_p9_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9,10, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,11,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10, 9,10,11,10, 9, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11, 9, 8, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,11,10,11,11, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, + 11,11,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,11,10, + 11,11,10,10, 9,10,10,10, 9, 9, 9, 9, 9, 9,10,10, + 10,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, + 11,10,11,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,11,11,11,10,11,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c0_sm_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_sm_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p9_2 = { + _vq_quantthresh__44c0_sm_p9_2, + _vq_quantmap__44c0_sm_p9_2, + 17, + 17 +}; + +static static_codebook _44c0_sm_p9_2 = { + 2, 289, + _vq_lengthlist__44c0_sm_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_sm_p9_2, + NULL, + &_vq_auxt__44c0_sm_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_sm_short[] = { + 5, 7,12,12,13,13,13,15,16,18, 4, 2,11, 5, 9, 7, + 9,12,13,14,13, 7, 8, 9, 8, 9,11,13,19,19, 9, 4, + 12, 5,10, 7, 9,12,15,14,11, 6, 7, 7, 5, 6, 8,11, + 15,17,10, 5, 8, 6, 6, 5, 6, 9,14,14,10, 5, 9, 7, + 7, 6, 6, 9,12,14,12, 6,10, 7, 7, 7, 8, 9,13,14, + 14, 7, 9, 7, 5, 5, 6, 9,11,13,14, 9,10, 9, 6, 6, + 7, 8,10,13, +}; + +static static_codebook _huff_book__44c0_sm_short = { + 2, 100, + _huff_lengthlist__44c0_sm_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_s_long[] = { + 3, 4,19, 9,10, 9, 9,10,11,12, 4, 2,19, 5, 6, 6, + 8,10,12,11,19,19,19,19,19,19,19,19,18,18, 8, 4, + 18, 6, 8, 7,10,13,14,13,10, 5,18, 7, 4, 6, 7,10, + 12,13, 9, 6,18, 7, 5, 6, 7,10,12,13, 9, 7,18, 9, + 7, 6, 6, 7,10,13, 9, 9,18,12, 9, 8, 6, 6, 9,12, + 10,12,18,15,12,11, 9, 8, 8,11,11,14,18,17,15,13, + 12, 9,10,12, +}; + +static static_codebook _huff_book__44c1_s_long = { + 2, 100, + _huff_lengthlist__44c1_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p1_0 = { + _vq_quantthresh__44c1_s_p1_0, + _vq_quantmap__44c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c1_s_p1_0, + NULL, + &_vq_auxt__44c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p2_0 = { + _vq_quantthresh__44c1_s_p2_0, + _vq_quantmap__44c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_s_p2_0, + NULL, + &_vq_auxt__44c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_s_p3_0[] = { + 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p3_0 = { + _vq_quantthresh__44c1_s_p3_0, + _vq_quantmap__44c1_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c1_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c1_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_s_p3_0, + NULL, + &_vq_auxt__44c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_s_p4_0[] = { + 1, 3, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p4_0 = { + _vq_quantthresh__44c1_s_p4_0, + _vq_quantmap__44c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p4_0, + NULL, + &_vq_auxt__44c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_s_p5_0[] = { + 1, 3, 3, 5, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 8, 7, + 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, 0, 0, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 8, 8, 9, 9,10,10, 0, 0, 0, 8, 8, 9, 9,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c1_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p5_0 = { + _vq_quantthresh__44c1_s_p5_0, + _vq_quantmap__44c1_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c1_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c1_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p5_0, + NULL, + &_vq_auxt__44c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_s_p6_0[] = { + 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9,10,10, + 10,11,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,12,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,11,12,12,12,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c1_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p6_0 = { + _vq_quantthresh__44c1_s_p6_0, + _vq_quantmap__44c1_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c1_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c1_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_s_p6_0, + NULL, + &_vq_auxt__44c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10,11,10,10, 9, 9, 6, 9, 9, + 10,10,10,10, 9, 9, 7,10,10,11,10,10,11,11,11, 6, + 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10, 9, 9,11,10, + 10, +}; + +static float _vq_quantthresh__44c1_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c1_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p7_0 = { + _vq_quantthresh__44c1_s_p7_0, + _vq_quantmap__44c1_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c1_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c1_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c1_s_p7_0, + NULL, + &_vq_auxt__44c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c1_s_p7_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6, + 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c1_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c1_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p7_1 = { + _vq_quantthresh__44c1_s_p7_1, + _vq_quantmap__44c1_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c1_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c1_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p7_1, + NULL, + &_vq_auxt__44c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 9, 8,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10,10,10,11,12,11, 0,12, + 13, 9, 8, 9, 9,10,10,11,11,11,11, 0, 0, 0, 9, 9, + 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10, + 10,11,11,12,12, 0, 0, 0,13,14,10,10,11,11,12,12, + 12,13, 0, 0, 0,14,14,10,10,11,10,12,12,13,13, 0, + 0, 0, 0, 0,12,11,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,10,12,11,14,13, +}; + +static float _vq_quantthresh__44c1_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p8_0 = { + _vq_quantthresh__44c1_s_p8_0, + _vq_quantmap__44c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c1_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c1_s_p8_0, + NULL, + &_vq_auxt__44c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_s_p8_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c1_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p8_1 = { + _vq_quantthresh__44c1_s_p8_1, + _vq_quantmap__44c1_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c1_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c1_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_s_p8_1, + NULL, + &_vq_auxt__44c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p9_0[] = { + 1, 6, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 7, 6, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 6, 6, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, +}; + +static float _vq_quantthresh__44c1_s_p9_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c1_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p9_0 = { + _vq_quantthresh__44c1_s_p9_0, + _vq_quantmap__44c1_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c1_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c1_s_p9_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c1_s_p9_0, + NULL, + &_vq_auxt__44c1_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,12,12,13,12, 6, 5, 5, + 7, 7, 8, 8,10,10,11,12,13,13, 6, 5, 5, 7, 7, 8, + 8, 9, 9,11,11,12,12,15, 7, 7, 7, 7, 9, 9,11,11, + 13,13,14,13,15, 7, 7, 8, 7, 9, 9,10,10,12,11,14, + 12,15,10,10, 8, 8,10,10,12,11,12,13,14,13,15,10, + 10, 8, 8,11,10,11,11,13,12,13,15,14,15,15,10,10, + 10,10,12,13,13,12,15,14,15,15,13,10,10,11,11,13, + 13,13,12,13,13,15,15,15,14,15,11,11,13,13,13,13, + 14,15,15,15,15,13,13,11,11,12,13,13,14,13,15,15, + 15,14,15,15,13,12,12,11,13,13,15,15,15,15,15,15, + 14,13,12,13,12,15,13,15,15, +}; + +static float _vq_quantthresh__44c1_s_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c1_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p9_1 = { + _vq_quantthresh__44c1_s_p9_1, + _vq_quantmap__44c1_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c1_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c1_s_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c1_s_p9_1, + NULL, + &_vq_auxt__44c1_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_s_p9_2[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 8, 9, 9, + 9,10,10,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9,10,10,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9,10,10,11,10, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,11, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 9, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,11,11,11,11, 9, 9, + 9, 9, 9, 9,10, 9,10, 9, 9, 9,10,10,10,11,10, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,11,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, + 11,11,10, 9, 9,10, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 11,11,11,10, 9,10,10,10, 9, 9, 9, 9,10, 9,10,10, + 10,10,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 11,10,10,10,10,10,10, 9, 9, 9, 9,10, 9, 9, 9, 9, + 10,10,10,11,11,10,10,11,11, 9, 9,10, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c1_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p9_2 = { + _vq_quantthresh__44c1_s_p9_2, + _vq_quantmap__44c1_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c1_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c1_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_s_p9_2, + NULL, + &_vq_auxt__44c1_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_s_short[] = { + 5, 7,17,13,12,12,14,16,15,16, 4, 2,17, 5, 7, 6, + 8,11,14,13,16,16,16,16,16,16,16,16,16,16,10, 4, + 16, 4, 8, 6, 7,11,14,14,10, 5,16, 6, 5, 6, 8,12, + 15,15,10, 5,16, 5, 6, 5, 7,10,14,15,11, 6,16, 7, + 8, 7, 7,10,14,14,13, 8,16, 8, 7, 7, 8,10,12,13, + 12, 8,16, 7, 5, 5, 6, 8,11,13,13, 9,16, 9, 6, 6, + 7, 8,10,13, +}; + +static static_codebook _huff_book__44c1_s_short = { + 2, 100, + _huff_lengthlist__44c1_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_sm_long[] = { + 3, 4,10, 9,11, 9,10,11,11,13, 4, 2,11, 5, 7, 7, + 8,10,12,13,10,10, 7,12, 8, 9, 9,10,12,13, 8, 5, + 13, 6, 9, 7,10,12,15,15,10, 6, 7, 8, 5, 5, 7,10, + 12,13, 9, 6, 8, 7, 5, 5, 6, 9,11,12, 9, 8, 9, 9, + 6, 5, 5, 7,10,13,10,10,10,12, 9, 7, 6, 7, 9,13, + 10,13,11,17,11,11, 9, 8, 9,12,12,16,14,17,15,14, + 12,10,10,12, +}; + +static static_codebook _huff_book__44c1_sm_long = { + 2, 100, + _huff_lengthlist__44c1_sm_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_sm_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c1_sm_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p1_0 = { + _vq_quantthresh__44c1_sm_p1_0, + _vq_quantmap__44c1_sm_p1_0, + 3, + 3 +}; + +static static_codebook _44c1_sm_p1_0 = { + 8, 6561, + _vq_lengthlist__44c1_sm_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c1_sm_p1_0, + NULL, + &_vq_auxt__44c1_sm_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_sm_p2_0[] = { + 1, 5, 5, 0, 0, 0, 5, 6, 0, 0, 0, 5, 6, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 8, + 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0,10, 9, 0, 0, 0, 0, 0, 0, 0, 6, + 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, + 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8,10,10, 0, 0, 0,10,10, 0, 0, 0, 9,10, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0,10, + 10, 0, 0, 0,10, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_sm_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p2_0 = { + _vq_quantthresh__44c1_sm_p2_0, + _vq_quantmap__44c1_sm_p2_0, + 5, + 5 +}; + +static static_codebook _44c1_sm_p2_0 = { + 4, 625, + _vq_lengthlist__44c1_sm_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_sm_p2_0, + NULL, + &_vq_auxt__44c1_sm_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_sm_p3_0[] = { + 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 7, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_sm_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p3_0 = { + _vq_quantthresh__44c1_sm_p3_0, + _vq_quantmap__44c1_sm_p3_0, + 5, + 5 +}; + +static static_codebook _44c1_sm_p3_0 = { + 4, 625, + _vq_lengthlist__44c1_sm_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_sm_p3_0, + NULL, + &_vq_auxt__44c1_sm_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_sm_p4_0[] = { + 1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0, + 0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_sm_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p4_0 = { + _vq_quantthresh__44c1_sm_p4_0, + _vq_quantmap__44c1_sm_p4_0, + 9, + 9 +}; + +static static_codebook _44c1_sm_p4_0 = { + 2, 81, + _vq_lengthlist__44c1_sm_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p4_0, + NULL, + &_vq_auxt__44c1_sm_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_sm_p5_0[] = { + 2, 3, 3, 5, 5, 6, 6, 8, 8, 0, 5, 5, 6, 6, 7, 7, + 9, 9, 0, 5, 5, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 7, 7, 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, + 7, 7, 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, + 0, 0, 9, 9, 9, 9,10,10, 0, 0, 0, 0, 0, 8, 8,10, + 10, +}; + +static float _vq_quantthresh__44c1_sm_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_sm_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p5_0 = { + _vq_quantthresh__44c1_sm_p5_0, + _vq_quantmap__44c1_sm_p5_0, + 9, + 9 +}; + +static static_codebook _44c1_sm_p5_0 = { + 2, 81, + _vq_lengthlist__44c1_sm_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p5_0, + NULL, + &_vq_auxt__44c1_sm_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_sm_p6_0[] = { + 2, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, + 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, + 8, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 9, 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,10,10,11,11,11,11,13,12,13,13, 0, 0, + 0, 0, 0, 0, 0,10,10,11,11,11,11,13,13,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,12,12,13,12,14, + 14, +}; + +static float _vq_quantthresh__44c1_sm_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_sm_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p6_0 = { + _vq_quantthresh__44c1_sm_p6_0, + _vq_quantmap__44c1_sm_p6_0, + 17, + 17 +}; + +static static_codebook _44c1_sm_p6_0 = { + 2, 289, + _vq_lengthlist__44c1_sm_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_sm_p6_0, + NULL, + &_vq_auxt__44c1_sm_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_sm_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,10,10,10, 6, 9, 9,10,10,10,10, 9, 9, 6, 9, 9, + 10,10,10,10,10, 9, 7,10,10,11,10,10,11,11,11, 6, + 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10, 9, 9,11,10, + 10, +}; + +static float _vq_quantthresh__44c1_sm_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c1_sm_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_0 = { + _vq_quantthresh__44c1_sm_p7_0, + _vq_quantmap__44c1_sm_p7_0, + 3, + 3 +}; + +static static_codebook _44c1_sm_p7_0 = { + 4, 81, + _vq_lengthlist__44c1_sm_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c1_sm_p7_0, + NULL, + &_vq_auxt__44c1_sm_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c1_sm_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 9, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c1_sm_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c1_sm_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_1 = { + _vq_quantthresh__44c1_sm_p7_1, + _vq_quantmap__44c1_sm_p7_1, + 11, + 11 +}; + +static static_codebook _44c1_sm_p7_1 = { + 2, 121, + _vq_lengthlist__44c1_sm_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p7_1, + NULL, + &_vq_auxt__44c1_sm_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8, + 8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10,10,11,11,12,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, + 9, 9,10,10,11,12,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,12,12,13,13, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,10,12,12,13,13, 0, + 0, 0, 0, 0,12,11,11,11,12,12,14,13, 0, 0, 0, 0, + 0,12,12,11,10,12,12,14,13, +}; + +static float _vq_quantthresh__44c1_sm_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c1_sm_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_0 = { + _vq_quantthresh__44c1_sm_p8_0, + _vq_quantmap__44c1_sm_p8_0, + 13, + 13 +}; + +static static_codebook _44c1_sm_p8_0 = { + 2, 169, + _vq_lengthlist__44c1_sm_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c1_sm_p8_0, + NULL, + &_vq_auxt__44c1_sm_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_sm_p8_1[] = { + 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c1_sm_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_sm_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_1 = { + _vq_quantthresh__44c1_sm_p8_1, + _vq_quantmap__44c1_sm_p8_1, + 5, + 5 +}; + +static static_codebook _44c1_sm_p8_1 = { + 2, 25, + _vq_lengthlist__44c1_sm_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_sm_p8_1, + NULL, + &_vq_auxt__44c1_sm_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p9_0[] = { + 1, 5, 5,11,11,11,11,11,11,11,11,11,11, 4, 5, 5, + 11,10,11,11,11,11,11,11,11,11, 4, 5, 4,11,11,11, + 11,11,11,11,11,11,11,11, 6, 7,11, 9,11,11,11,11, + 11,11,11,11,11, 6, 7, 9, 8,11,11,11,11,11,11,11, + 11,11, 9, 9, 7, 8,11,11,11,11,11,11,11,11,11,10, + 10, 9,10,11,11,11,11,11,11,11,11,11,11,11, 8,11, + 10,10,11,11,11,11,11,11,11,11,11, 9,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11, 9,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c1_sm_p9_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c1_sm_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p9_0 = { + _vq_quantthresh__44c1_sm_p9_0, + _vq_quantmap__44c1_sm_p9_0, + 13, + 13 +}; + +static static_codebook _44c1_sm_p9_0 = { + 2, 169, + _vq_lengthlist__44c1_sm_p9_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c1_sm_p9_0, + NULL, + &_vq_auxt__44c1_sm_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7,10,10,12,12,13,13, 6, 5, 5, + 7, 7, 8, 8,10,10,12,12,14,13, 6, 5, 5, 7, 7, 8, + 8,10,10,12,12,13,13,16, 7, 7, 7, 7, 9, 9,11,11, + 13,14,13,15,18, 7, 6, 8, 7, 9, 9,11,10,12,12,14, + 12,19,10,10, 8, 8,10,10,12,11,13,15,15,15,17,11, + 11, 8, 7,11,10,12,12,13,13,14,15,16,17,17,10,11, + 10,10,13,13,14,13,16,15,17,17,16,10,10,11,11,14, + 14,16,13,14,14,17,19,17,15,14,11,11,13,13,15,14, + 16,15,17,16,17,14,14,11,11,14,13,14,14,14,15,17, + 16,16,16,17,13,13,13,13,16,14,17,15,16,17,18,18, + 17,13,13,13,13,15,15,16,16, +}; + +static float _vq_quantthresh__44c1_sm_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c1_sm_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p9_1 = { + _vq_quantthresh__44c1_sm_p9_1, + _vq_quantmap__44c1_sm_p9_1, + 13, + 13 +}; + +static static_codebook _44c1_sm_p9_1 = { + 2, 169, + _vq_lengthlist__44c1_sm_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c1_sm_p9_1, + NULL, + &_vq_auxt__44c1_sm_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_sm_p9_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9,10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 7, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10, 9,10,10,10, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9,10,11,10,11,11, 9, 9, + 9, 9, 9, 9, 9,10,10, 9, 9, 9,10,11,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,11,10,11, + 11,10,11, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10, + 11,11,11,11, 9,10,10,10, 9, 9, 9, 9,10, 9,10,10, + 10,11,11,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, + 11,10,11,10,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,11,11,10,10,10,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c1_sm_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_sm_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p9_2 = { + _vq_quantthresh__44c1_sm_p9_2, + _vq_quantmap__44c1_sm_p9_2, + 17, + 17 +}; + +static static_codebook _44c1_sm_p9_2 = { + 2, 289, + _vq_lengthlist__44c1_sm_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_sm_p9_2, + NULL, + &_vq_auxt__44c1_sm_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_sm_short[] = { + 4, 7,13,13,13,13,14,16,16,19, 4, 2,13, 5, 8, 7, + 9,12,14,13,16, 9,10,10, 9,10,11,13,17,19, 9, 4, + 13, 5,10, 6, 8,11,15,15,11, 6, 9, 7, 6, 6, 8,11, + 14,18,11, 5, 9, 6, 6, 5, 6, 9,13,15,12, 6, 9, 7, + 6, 5, 5, 8,12,15,13, 7,10, 8, 6, 6, 7, 9,12,13, + 13, 9,11, 9, 6, 5, 6, 8,11,13,13,11,13,11, 7, 6, + 7, 8,10,12, +}; + +static static_codebook _huff_book__44c1_sm_short = { + 2, 100, + _huff_lengthlist__44c1_sm_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c2_s_long[] = { + 5, 5,12,10,11,10,10,10,11,13, 5, 1, 9, 5, 8, 7, + 8,10,13,13,12, 9, 8,11, 7, 8, 9,11,13,15, 9, 5, + 12, 6, 9, 8,10,12,15,14,12, 7, 6, 8, 5, 6, 7,10, + 12,13,10, 7, 8, 7, 6, 6, 7, 9,12,12,10, 8, 9, 9, + 7, 6, 6, 7,10,11,10, 9,10,11, 9, 8, 6, 6, 8,11, + 10,12,13,15,11,10, 8, 7, 8,11,11,13,16,16,14,13, + 11, 9, 9,10, +}; + +static static_codebook _huff_book__44c2_s_long = { + 2, 100, + _huff_lengthlist__44c2_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c2_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c2_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p1_0 = { + _vq_quantthresh__44c2_s_p1_0, + _vq_quantmap__44c2_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c2_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c2_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c2_s_p1_0, + NULL, + &_vq_auxt__44c2_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p2_0[] = { + 1, 4, 4, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8, + 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 4, 6, 6, 0, 0, 0, 8, 9, 0, 0, 0, 8, 8, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,11,10, 0, 0, + 0,11,11, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 7, + 8, 8, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0, 0,11, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0,11,11, 0, 0, 0,11,11, + 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, + 0, 0,11,11, 0, 0, 0,11,11, 0, 0, 0,11,11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 9, 9, 0, 0, 0,11,12, 0, 0, 0,11,12, 0, 0, 0, + 12,11, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,12, + 11, 0, 0, 0,11,11, 0, 0, 0,11,11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p2_0 = { + _vq_quantthresh__44c2_s_p2_0, + _vq_quantmap__44c2_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c2_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c2_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p2_0, + NULL, + &_vq_auxt__44c2_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p3_0[] = { + 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p3_0 = { + _vq_quantthresh__44c2_s_p3_0, + _vq_quantmap__44c2_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c2_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c2_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p3_0, + NULL, + &_vq_auxt__44c2_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c2_s_p4_0[] = { + 1, 3, 3, 6, 6, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0, + 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c2_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p4_0 = { + _vq_quantthresh__44c2_s_p4_0, + _vq_quantmap__44c2_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c2_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c2_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p4_0, + NULL, + &_vq_auxt__44c2_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c2_s_p5_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 7, 7, 7, 7, 8, 8, + 9, 9, 0, 7, 7, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 7, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 8, 8, 9, 9,10,10, 0, 0, 0, 8, 8, 9, 9,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c2_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c2_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p5_0 = { + _vq_quantthresh__44c2_s_p5_0, + _vq_quantmap__44c2_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c2_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c2_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p5_0, + NULL, + &_vq_auxt__44c2_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c2_s_p6_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9, 9, + 9,10,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, + 9, 9, 9,10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, + 10,10,10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,11,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,11,11,12,12,13,12,14,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,12,12,12,13,13, + 14, +}; + +static float _vq_quantthresh__44c2_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c2_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p6_0 = { + _vq_quantthresh__44c2_s_p6_0, + _vq_quantmap__44c2_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c2_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c2_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c2_s_p6_0, + NULL, + &_vq_auxt__44c2_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c2_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10, 9,10,10, + 10,11,10,10, 6, 9, 9,10,10,10,11, 9, 9, 6, 9, 9, + 10,10,10,11, 9, 9, 7,10,10,11,10,10,11,11,10, 6, + 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10, 9,10,11,10, + 10, +}; + +static float _vq_quantthresh__44c2_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c2_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p7_0 = { + _vq_quantthresh__44c2_s_p7_0, + _vq_quantmap__44c2_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c2_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c2_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c2_s_p7_0, + NULL, + &_vq_auxt__44c2_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c2_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7,10, 6, 6, 6, 6, + 7, 7, 8, 7, 8, 8, 9, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10, 9, 9, 6, + 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10, 9, 8, 8, 8, + 8, 8, 8,10,10,10, 9,10, 8, 8, 8, 8, 8, 8,10,10, + 10,10, 9, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c2_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c2_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p7_1 = { + _vq_quantthresh__44c2_s_p7_1, + _vq_quantmap__44c2_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c2_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c2_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p7_1, + NULL, + &_vq_auxt__44c2_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8, + 8, 8, 9,10, 9,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9,10,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,12,12, 0,13, + 12, 9, 9,10, 9,10,10,11,11,11,12, 0, 0, 0,10,10, + 10,10,11,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,12,12,12,13, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,11,12,12,12,14,13, 0, 0, 0, 0, + 0,12,12,12,12,12,12,14,13, +}; + +static float _vq_quantthresh__44c2_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c2_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p8_0 = { + _vq_quantthresh__44c2_s_p8_0, + _vq_quantmap__44c2_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c2_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c2_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c2_s_p8_0, + NULL, + &_vq_auxt__44c2_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p8_1[] = { + 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c2_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p8_1 = { + _vq_quantthresh__44c2_s_p8_1, + _vq_quantmap__44c2_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c2_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c2_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p8_1, + NULL, + &_vq_auxt__44c2_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p9_0[] = { + 1, 5, 4,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 5, 7, 7, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 9, 6, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c2_s_p9_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c2_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_0 = { + _vq_quantthresh__44c2_s_p9_0, + _vq_quantmap__44c2_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c2_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c2_s_p9_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c2_s_p9_0, + NULL, + &_vq_auxt__44c2_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,11,11,12,12, 6, 5, 5, + 7, 7, 8, 8,10,10,12,11,13,13, 6, 5, 5, 7, 7, 8, + 8, 9, 9,11,11,12,13,16, 7, 7, 8, 8, 9, 9,10,10, + 13,13,16,14,16, 7, 7, 8, 8, 9, 9,10,10,13,13,15, + 13,16,10,10, 8, 8,10,10,11,11,12,12,15,14,16,11, + 11, 8, 8,10,10,11,11,12,12,14,13,16,16,16,10,11, + 10,10,12,12,14,13,13,13,16,16,16,10, 9,10, 7,13, + 12,13,13,13,13,16,16,16,14,15,11,11,12,12,13,13, + 15,14,16,16,16,16,14,11, 9,12, 9,15,13,13,14,16, + 16,16,16,16,13,13,12,12,14,15,16,15,16,16,15,16, + 16,13,12,12,11,15,13,14,15, +}; + +static float _vq_quantthresh__44c2_s_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c2_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_1 = { + _vq_quantthresh__44c2_s_p9_1, + _vq_quantmap__44c2_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c2_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c2_s_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c2_s_p9_1, + NULL, + &_vq_auxt__44c2_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c2_s_p9_2[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, + 9,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,11,10, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 7, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,10,11,10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,10, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,11,10,10,11, + 10,10,11, 9, 9,10,10, 9, 9,10,10, 9, 9,10,10,10, + 11,10,11,10,10, 9, 9,10, 9, 9, 9, 9, 9, 9,10,10, + 10,10,11,10,10, 9,10, 9, 9, 9, 9,10, 9, 9, 9,10, + 10,10,11,11,10,10,10,10, 9, 9,10, 9, 9, 9,10, 9, + 10,10,10,10,11,10,11,11,10, 9, 9, 9, 9, 9, 9, 9, + 10, +}; + +static float _vq_quantthresh__44c2_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c2_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_2 = { + _vq_quantthresh__44c2_s_p9_2, + _vq_quantmap__44c2_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c2_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c2_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c2_s_p9_2, + NULL, + &_vq_auxt__44c2_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c2_s_short[] = { + 9, 9,12,11,11,11,12,12,12,13, 6, 2, 9, 4, 7, 6, + 8,11,15,17,12, 7, 8, 9, 7, 9,10,13,15,17,11, 4, + 12, 4, 9, 5, 8,11,16,17,12, 6, 7, 6, 6, 6, 8,11, + 15,17,11, 5, 9, 5, 6, 5, 6,10,15,15,12, 7,11, 7, + 7, 6, 7,10,13,16,13, 8,11, 9, 8, 6, 7,10,12,16, + 13, 9, 9, 8, 5, 5, 6, 9,12,14,16,10, 9, 9, 6, 5, + 6, 8,11,14, +}; + +static static_codebook _huff_book__44c2_s_short = { + 2, 100, + _huff_lengthlist__44c2_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c3_s_long[] = { + 4, 5,11,10,12,10,10,10,11,12, 4, 2,11, 5,11, 6, + 7, 9,13,16,11,11, 7,11, 6, 8, 8, 9,11,12,10, 5, + 11, 6,10, 7, 9,11,16,16,14, 9, 6, 9, 4, 5, 7, 8, + 11,13,10, 6, 7, 7, 5, 5, 6, 8,10,11,10, 7, 8, 8, + 6, 6, 5, 7, 9,10,10, 9, 8,11, 8, 7, 6, 6, 7,10, + 10,12,10,14, 9, 9, 7, 7, 7, 9,10,14,11,16,12,12, + 9, 8, 8, 9, +}; + +static static_codebook _huff_book__44c3_s_long = { + 2, 100, + _huff_lengthlist__44c3_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c3_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c3_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p1_0 = { + _vq_quantthresh__44c3_s_p1_0, + _vq_quantmap__44c3_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c3_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c3_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c3_s_p1_0, + NULL, + &_vq_auxt__44c3_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p2_0[] = { + 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 8, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 8, + 7, 0, 0, 0, 7, 7, 0, 0, 0,10, 9, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 6, 0, 0, 0, 7, 8, 0, 0, 0, 7, 7, 0, + 0, 0, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 8, 0, + 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 9, + 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p2_0 = { + _vq_quantthresh__44c3_s_p2_0, + _vq_quantmap__44c3_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c3_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c3_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p2_0, + NULL, + &_vq_auxt__44c3_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p3_0[] = { + 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p3_0 = { + _vq_quantthresh__44c3_s_p3_0, + _vq_quantmap__44c3_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c3_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c3_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p3_0, + NULL, + &_vq_auxt__44c3_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c3_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c3_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p4_0 = { + _vq_quantthresh__44c3_s_p4_0, + _vq_quantmap__44c3_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c3_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c3_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p4_0, + NULL, + &_vq_auxt__44c3_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c3_s_p5_0[] = { + 2, 3, 3, 5, 5, 7, 7, 9, 8, 0, 4, 4, 7, 7, 7, 7, + 9, 9, 0, 5, 5, 6, 7, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 7, 7, 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, + 8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__44c3_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c3_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p5_0 = { + _vq_quantthresh__44c3_s_p5_0, + _vq_quantmap__44c3_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c3_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c3_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p5_0, + NULL, + &_vq_auxt__44c3_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c3_s_p6_0[] = { + 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10, 9, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10, + 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,11,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, + 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, + 8, 9, 9,10,10,11,11,12,12,13,12, 0, 0, 0, 0, 0, + 9, 9,10,10,11,10,11,11,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, + 0, 0, 0, 0, 0,10,10,11,11,11,11,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,12,13,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13, + 13, +}; + +static float _vq_quantthresh__44c3_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c3_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p6_0 = { + _vq_quantthresh__44c3_s_p6_0, + _vq_quantmap__44c3_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c3_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c3_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c3_s_p6_0, + NULL, + &_vq_auxt__44c3_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c3_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10,10,10,10, 9, 9, 6, 9, 9, + 10,10,10,10, 9, 9, 7,10,10,10,11,11,11,10,11, 6, + 9, 9,10,10, 9,11,10,10, 6, 9, 9,10, 9, 9,10,10, + 10, +}; + +static float _vq_quantthresh__44c3_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c3_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p7_0 = { + _vq_quantthresh__44c3_s_p7_0, + _vq_quantmap__44c3_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c3_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c3_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c3_s_p7_0, + NULL, + &_vq_auxt__44c3_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c3_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 9, +}; + +static float _vq_quantthresh__44c3_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c3_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p7_1 = { + _vq_quantthresh__44c3_s_p7_1, + _vq_quantmap__44c3_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c3_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c3_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p7_1, + NULL, + &_vq_auxt__44c3_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c3_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 8, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 5, 5, 7, 7, 8, + 8, 9, 9, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,11,12, 9, 9, 9,10,10,10,11,11,11,12, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0,10, 9, + 9, 9,10,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,11,11,12,13, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,11,12,12,13,13, +}; + +static float _vq_quantthresh__44c3_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c3_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p8_0 = { + _vq_quantthresh__44c3_s_p8_0, + _vq_quantmap__44c3_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c3_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c3_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c3_s_p8_0, + NULL, + &_vq_auxt__44c3_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c3_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p8_1 = { + _vq_quantthresh__44c3_s_p8_1, + _vq_quantmap__44c3_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c3_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c3_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p8_1, + NULL, + &_vq_auxt__44c3_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c3_s_p9_0[] = { + 1, 4, 4,10,10,10,10,10,10,10,10,10,10, 5,10, 7, + 10,10,10,10,10,10,10,10,10,10, 5, 8, 6,10,10,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c3_s_p9_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44c3_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_0 = { + _vq_quantthresh__44c3_s_p9_0, + _vq_quantmap__44c3_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c3_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c3_s_p9_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44c3_s_p9_0, + NULL, + &_vq_auxt__44c3_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c3_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,11,11,11,12,12,12, 6, + 5, 5, 7, 7, 8, 8,10, 9,11,11,13,12,13,14, 6, 5, + 5, 7, 7, 8, 8,10,10,11,11,12,12,13,13,17, 7, 7, + 8, 8, 9, 9,10,10,12,12,14,13,14,14,17, 8, 7, 8, + 7, 9, 9,10,10,12,12,13,13,13,14,17,11,11, 8, 8, + 10,10,11,11,12,12,13,13,15,14,17,11,11, 8, 7,10, + 10,11,11,12,12,13,14,14,13,17,17,17,10,11,10,10, + 12,12,13,12,13,13,14,14,17,16,16,10,10,11, 9,13, + 12,13,13,13,13,14,14,16,16,15,13,15,11,12,12,12, + 14,14,14,14,14,15,16,16,16,14,14,11, 9,12,10,13, + 13,14,14,14,14,16,16,16,16,16,12,13,12,12,13,14, + 14,14,15,15,15,16,16,15,16,13,11,13,10,14,12,15, + 14,16,14,15,16,16,16,16,15,15,13,13,13,13,14,14, + 16,16,16,16,16,15,16,16,14,13,12,13,13,14,16,16, + 16, +}; + +static float _vq_quantthresh__44c3_s_p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44c3_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_1 = { + _vq_quantthresh__44c3_s_p9_1, + _vq_quantmap__44c3_s_p9_1, + 15, + 15 +}; + +static static_codebook _44c3_s_p9_1 = { + 2, 225, + _vq_lengthlist__44c3_s_p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44c3_s_p9_1, + NULL, + &_vq_auxt__44c3_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c3_s_p9_2[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, + 8,10, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 8, 7, 8, 8, 9, 8, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,10, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,10, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10, + 10,10,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 11,10,11,10, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,10,10, + 10,10,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, 9, + 10,10,10,10,11,10,11,10,10, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c3_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c3_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_2 = { + _vq_quantthresh__44c3_s_p9_2, + _vq_quantmap__44c3_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c3_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c3_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c3_s_p9_2, + NULL, + &_vq_auxt__44c3_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c3_s_short[] = { + 10,10,13,12,13,12,12,12,12,13, 8, 3,11, 5,10, 5, + 7,11,14,16,11, 6, 9, 8, 7, 7, 9,12,15,16,12, 4, + 12, 4,10, 5, 8,12,15,16,12, 6, 8, 7, 5, 5, 7,11, + 14,15,11, 4, 9, 4, 6, 4, 6, 9,13,15,10, 6,10, 7, + 7, 5, 6, 9,13,15,12, 9,11, 9, 8, 6, 7, 9,12,15, + 13,11,10, 9, 6, 5, 5, 8,11,14,16,12,11,10, 6, 5, + 6, 8,10,14, +}; + +static static_codebook _huff_book__44c3_s_short = { + 2, 100, + _huff_lengthlist__44c3_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c4_s_long[] = { + 3, 5,11,11,13,11,11,11,12,12, 5, 2,11, 6,10, 7, + 8,10,13,16,10, 9, 6,10, 6, 7, 8, 9,11,12,11, 5, + 11, 7,10, 8,10,12,15,17,12, 8, 5, 9, 4, 5, 7, 8, + 10,12,10, 6, 7, 8, 5, 5, 6, 8,10,11,10, 8, 8, 9, + 6, 6, 6, 7, 9,10,11,10, 9,11, 8, 7, 6, 6, 7, 9, + 11,13,10,15, 9, 9, 7, 7, 7, 8,10,15,11,17,11,11, + 9, 8, 7, 8, +}; + +static static_codebook _huff_book__44c4_s_long = { + 2, 100, + _huff_lengthlist__44c4_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c4_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, + 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8,10, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, + 0, 0, 0, 0, 0, 8, 8,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c4_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p1_0 = { + _vq_quantthresh__44c4_s_p1_0, + _vq_quantmap__44c4_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c4_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c4_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c4_s_p1_0, + NULL, + &_vq_auxt__44c4_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p2_0[] = { + 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 8, + 7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 8, 0, + 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0, 9, + 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p2_0 = { + _vq_quantthresh__44c4_s_p2_0, + _vq_quantmap__44c4_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c4_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c4_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p2_0, + NULL, + &_vq_auxt__44c4_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p3_0[] = { + 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p3_0 = { + _vq_quantthresh__44c4_s_p3_0, + _vq_quantmap__44c4_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c4_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c4_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p3_0, + NULL, + &_vq_auxt__44c4_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c4_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c4_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p4_0 = { + _vq_quantthresh__44c4_s_p4_0, + _vq_quantmap__44c4_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c4_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c4_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p4_0, + NULL, + &_vq_auxt__44c4_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c4_s_p5_0[] = { + 2, 3, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 7, 7, 7, 7, + 9, 9, 0, 4, 4, 7, 7, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c4_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c4_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p5_0 = { + _vq_quantthresh__44c4_s_p5_0, + _vq_quantmap__44c4_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c4_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c4_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p5_0, + NULL, + &_vq_auxt__44c4_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c4_s_p6_0[] = { + 2, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10, 9,10,10,11, + 11, 0, 4, 4, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10, 9, + 10,11,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10, + 10,11,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,11,12,12, 0, 0, 0, 0, 0, 8, 8, + 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, + 8, 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, + 9, 9,10,10,11,10,11,11,12,12,12,12, 0, 0, 0, 0, + 0, 0, 0,10,10,10,10,11,11,12,12,13,12, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,11,12,12,12,13,12, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,11,11,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,12,12,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13, + 13, +}; + +static float _vq_quantthresh__44c4_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c4_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p6_0 = { + _vq_quantthresh__44c4_s_p6_0, + _vq_quantmap__44c4_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c4_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c4_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c4_s_p6_0, + NULL, + &_vq_auxt__44c4_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c4_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10,10,10,10,10, 9, 6, 9, 9, + 10, 9,10,11, 9, 9, 7,10,10,11,11,11,11,10,10, 6, + 9, 9,10, 9, 9,10,10, 9, 6, 9, 9,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44c4_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c4_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p7_0 = { + _vq_quantthresh__44c4_s_p7_0, + _vq_quantmap__44c4_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c4_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c4_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c4_s_p7_0, + NULL, + &_vq_auxt__44c4_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c4_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 9,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c4_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c4_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p7_1 = { + _vq_quantthresh__44c4_s_p7_1, + _vq_quantmap__44c4_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c4_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c4_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p7_1, + NULL, + &_vq_auxt__44c4_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c4_s_p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9,10,10,11,11, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10,10,10,10,11,11, 0,12, + 12, 9, 8, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9,10, + 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10, + 10,11,11,12,12, 0, 0, 0,13,13,10,10,10,11,12,12, + 12,12, 0, 0, 0,14,14,10,10,11,11,11,11,12,12, 0, + 0, 0, 0, 0,11,12,11,11,12,12,12,13, 0, 0, 0, 0, + 0,12,12,11,11,12,12,13,13, +}; + +static float _vq_quantthresh__44c4_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c4_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p8_0 = { + _vq_quantthresh__44c4_s_p8_0, + _vq_quantmap__44c4_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c4_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c4_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c4_s_p8_0, + NULL, + &_vq_auxt__44c4_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c4_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p8_1 = { + _vq_quantthresh__44c4_s_p8_1, + _vq_quantmap__44c4_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c4_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c4_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p8_1, + NULL, + &_vq_auxt__44c4_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c4_s_p9_0[] = { + 1, 3, 3,10,10,10,10,10,10,10,10,10,10, 5, 7, 7, + 10,10,10,10,10,10,10,10,10,10, 5, 7, 8,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c4_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__44c4_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_0 = { + _vq_quantthresh__44c4_s_p9_0, + _vq_quantmap__44c4_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c4_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c4_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__44c4_s_p9_0, + NULL, + &_vq_auxt__44c4_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c4_s_p9_1[] = { + 1, 4, 4, 5, 6, 7, 7, 9, 9,11,11,12,12,12,13, 6, + 5, 5, 6, 7, 8, 8,10,10,11,11,13,13,13,13, 6, 5, + 5, 7, 7, 8, 8,11,10,11,11,12,13,12,13,17, 7, 7, + 8, 8, 9, 9,11,11,12,12,12,13,15,14,17, 7, 7, 8, + 8, 9, 9,11,10,12,12,13,13,14,13,17,11,12, 9, 9, + 10,10,12,12,13,13,14,14,14,14,17,12,11, 9, 8,11, + 10,11,12,13,13,13,14,14,14,17,17,17,11,11,11,11, + 13,13,13,13,14,13,15,14,17,17,17,11,10,11, 9,13, + 12,13,14,15,14,15,14,17,17,17,14,14,11,12,12,13, + 14,14,16,15,15,15,17,17,17,15,15,12,11,13,11,13, + 13,13,15,16,14,17,17,17,17,17,13,13,14,13,14,14, + 15,15,16,15,17,17,17,17,17,14,14,14,12,14,12,16, + 14,15,14,17,17,17,17,17,16,17,13,14,14,15,15,15, + 17,15,17,17,17,17,17,16,17,13,14,14,14,15,17,15, + 15, +}; + +static float _vq_quantthresh__44c4_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c4_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_1 = { + _vq_quantthresh__44c4_s_p9_1, + _vq_quantmap__44c4_s_p9_1, + 15, + 15 +}; + +static static_codebook _44c4_s_p9_1 = { + 2, 225, + _vq_lengthlist__44c4_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c4_s_p9_1, + NULL, + &_vq_auxt__44c4_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c4_s_p9_2[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9,11, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,11, 5, 5, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10, 9,10,10,10, + 10,10,10,11,11,11, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9, 9,10,10,10,10, + 10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11, + 11,11,11, 9, 9, 9,10,10,10,10,10,10,10,10,10,10, + 10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,11,11,11,11,11,11,11,10,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10, + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 12,11,11,10,10,10,10,10,10,10,10,10,10,10,10,12, + 11,12,12,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c4_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c4_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_2 = { + _vq_quantthresh__44c4_s_p9_2, + _vq_quantmap__44c4_s_p9_2, + 21, + 21 +}; + +static static_codebook _44c4_s_p9_2 = { + 2, 441, + _vq_lengthlist__44c4_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c4_s_p9_2, + NULL, + &_vq_auxt__44c4_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c4_s_short[] = { + 4, 9,13,12,16,11,12,15,15,16, 4, 2,11, 5,10, 6, + 8,11,14,14,13,11, 8,11, 7, 8,10,13,17,17,10, 4, + 11, 5, 9, 6, 9,13,17,17,13, 9, 6, 9, 5, 5, 7,11, + 15,17,10, 5, 7, 6, 5, 4, 7,10,15,15,10, 7, 9, 8, + 7, 6, 7,10,14,13,13,10,11,10, 8, 7, 8,10,14,14, + 12,11,10, 9, 6, 5, 6, 9,13,17,14,13,11,10, 6, 6, + 6, 8,11,16, +}; + +static static_codebook _huff_book__44c4_s_short = { + 2, 100, + _huff_lengthlist__44c4_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c5_s_long[] = { + 3, 6, 9,14,11,13,12,12,12,12, 6, 3, 5, 8, 6, 8, + 10,11,12,14, 9, 5, 4,10, 5, 7, 8, 9,11,12,13, 8, + 10, 9, 9, 9,12,15,16,17,10, 6, 5, 9, 3, 5, 6, 8, + 10,12,10, 8, 7, 9, 5, 5, 6, 8,10,11,10, 9, 8,11, + 6, 6, 6, 7, 8,10,12,11, 9,13, 8, 7, 6, 6, 7, 9, + 11,13,10,15, 9, 9, 7, 7, 7, 8,10,15,10,17,11,10, + 9, 8, 7, 7, +}; + +static static_codebook _huff_book__44c5_s_long = { + 2, 100, + _huff_lengthlist__44c5_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c5_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 4, 7, 6, 0, 0, 0, 0, + 0, 0, 4, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 8, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 9, 8, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c5_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p1_0 = { + _vq_quantthresh__44c5_s_p1_0, + _vq_quantmap__44c5_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c5_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c5_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c5_s_p1_0, + NULL, + &_vq_auxt__44c5_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p2_0[] = { + 2, 4, 4, 0, 0, 0, 6, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 4, 6, 5, 0, 0, 0, 8, + 7, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 6, 0, 0, 0, 7, 8, 0, 0, 0, 7, 8, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 6, + 7, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, + 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 9, 9, 0, 0, 0,10,10, 0, 0, 0,10,10, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,10, + 10, 0, 0, 0,10,10, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p2_0 = { + _vq_quantthresh__44c5_s_p2_0, + _vq_quantmap__44c5_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c5_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c5_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p2_0, + NULL, + &_vq_auxt__44c5_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p3_0[] = { + 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p3_0 = { + _vq_quantthresh__44c5_s_p3_0, + _vq_quantmap__44c5_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c5_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c5_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p3_0, + NULL, + &_vq_auxt__44c5_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c5_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 8, 7, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c5_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p4_0 = { + _vq_quantthresh__44c5_s_p4_0, + _vq_quantmap__44c5_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c5_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c5_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p4_0, + NULL, + &_vq_auxt__44c5_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c5_s_p5_0[] = { + 2, 3, 4, 5, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 7, 7, 8, 8,10,10, 0, 0, 0, 7, 8, 8, 8,10,10, 0, + 0, 0, 9, 9, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__44c5_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c5_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p5_0 = { + _vq_quantthresh__44c5_s_p5_0, + _vq_quantmap__44c5_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c5_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c5_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p5_0, + NULL, + &_vq_auxt__44c5_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c5_s_p6_0[] = { + 2, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,12, + 12, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 6, 6, 7, 7, 8, 8, 9,10,10,10,11,11, + 11,12,12,12, 0, 0, 0, 7, 7, 8, 8,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 7, 7, 8, 9,10,10,10, + 10,11,11,12,12,12,13, 0, 0, 0, 8, 8, 9, 9,10,10, + 10,10,11,11,12,12,13,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, + 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, + 8, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 9, 9,10,10,11,11,11,12,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,11,12,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,12,13,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13, + 13, +}; + +static float _vq_quantthresh__44c5_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c5_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p6_0 = { + _vq_quantthresh__44c5_s_p6_0, + _vq_quantmap__44c5_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c5_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c5_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c5_s_p6_0, + NULL, + &_vq_auxt__44c5_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c5_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10,10, 9,11,10,10, 6, 9, 9, + 10, 9,10,11,10, 9, 7,10,10,11,11,11,11,10,10, 6, + 9, 9,10,10, 9,10, 9, 9, 6, 9, 9,10,10,10,11, 9, + 9, +}; + +static float _vq_quantthresh__44c5_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c5_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p7_0 = { + _vq_quantthresh__44c5_s_p7_0, + _vq_quantmap__44c5_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c5_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c5_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c5_s_p7_0, + NULL, + &_vq_auxt__44c5_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c5_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c5_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c5_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p7_1 = { + _vq_quantthresh__44c5_s_p7_1, + _vq_quantmap__44c5_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c5_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c5_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p7_1, + NULL, + &_vq_auxt__44c5_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c5_s_p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9,10,10,10,10, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,11,12, 9, 9, 9, 9, 9,10,10,10,11,11, 0,13, + 12, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0, 9,10, + 9, 9,10,10,11,11,12,11, 0, 0, 0,10,10, 9, 9,10, + 10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,11,12, + 12,12, 0, 0, 0,14,14,10,10,11,11,11,11,12,12, 0, + 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,11,12,12,13,13, +}; + +static float _vq_quantthresh__44c5_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c5_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p8_0 = { + _vq_quantthresh__44c5_s_p8_0, + _vq_quantmap__44c5_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c5_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c5_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c5_s_p8_0, + NULL, + &_vq_auxt__44c5_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c5_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p8_1 = { + _vq_quantthresh__44c5_s_p8_1, + _vq_quantmap__44c5_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c5_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c5_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p8_1, + NULL, + &_vq_auxt__44c5_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c5_s_p9_0[] = { + 1, 3, 3,11,11,11,11,11,11,11,11,11,11,11,11, 5, + 7, 7,11,11,11,11,11,11,11,11,11,11,11,11, 5, 9, + 7,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44c5_s_p9_0[] = { + -2320.5, -1963.5, -1606.5, -1249.5, -892.5, -535.5, -178.5, 178.5, + 535.5, 892.5, 1249.5, 1606.5, 1963.5, 2320.5, +}; + +static long _vq_quantmap__44c5_s_p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_0 = { + _vq_quantthresh__44c5_s_p9_0, + _vq_quantmap__44c5_s_p9_0, + 15, + 15 +}; + +static static_codebook _44c5_s_p9_0 = { + 2, 225, + _vq_lengthlist__44c5_s_p9_0, + 1, -512522752, 1628852224, 4, 0, + _vq_quantlist__44c5_s_p9_0, + NULL, + &_vq_auxt__44c5_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_1[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c5_s_p9_1[] = { + 1, 4, 4, 6, 6, 8, 7, 9, 9,10,10,11,11,12,12,13, + 13, 6, 5, 5, 6, 6, 8, 8,10,10,11,11,12,12,13,13, + 13,13, 6, 5, 5, 7, 7, 8, 8,10,10,11,11,12,12,13, + 13,13,13,18, 7, 7, 8, 8, 9, 9,10,11,11,11,12,12, + 13,13,13,14,18, 7, 7, 8, 8, 9, 9,11,10,12,12,13, + 13,13,13,14,15,18,12,12, 9, 9,10,10,11,11,12,12, + 13,13,13,14,14,14,18,12,12, 9, 8,10,10,11,11,12, + 12,14,13,13,14,15,15,18,16,18,11,11,11,11,12,12, + 13,13,13,14,14,14,14,15,17,18,17,11,10,11, 9,12, + 13,13,13,14,14,13,14,14,14,18,18,18,13,14,11,12, + 12,12,13,14,13,13,14,15,16,15,18,18,18,15,13,12, + 9,12,11,13,14,14,15,14,14,16,14,18,18,18,18,18, + 12,13,13,13,13,14,15,14,15,15,15,15,18,18,18,18, + 17,14,12,13,11,14,12,15,14,14,15,16,15,18,18,18, + 17,18,15,18,13,13,14,13,15,14,16,15,17,16,18,18, + 17,18,18,15,17,14,13,14,12,14,14,15,15,15,15,18, + 18,18,17,17,18,18,14,15,14,14,14,14,15,14,16,16, + 17,18,18,18,18,17,17,15,15,13,13,15,13,15,13,15, + 15, +}; + +static float _vq_quantthresh__44c5_s_p9_1[] = { + -157.5, -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, + 10.5, 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, 157.5, +}; + +static long _vq_quantmap__44c5_s_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_1 = { + _vq_quantthresh__44c5_s_p9_1, + _vq_quantmap__44c5_s_p9_1, + 17, + 17 +}; + +static static_codebook _44c5_s_p9_1 = { + 2, 289, + _vq_lengthlist__44c5_s_p9_1, + 1, -520814592, 1620377600, 5, 0, + _vq_quantlist__44c5_s_p9_1, + NULL, + &_vq_auxt__44c5_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c5_s_p9_2[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,11, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11, 5, 5, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,11,11,11, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,11,11,11,11, + 11,11,11, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,11,11,11,11,11,11,11,10, 9,10,10,10,10,10,10, + 10,10,10, 9,10,10,11,11,11,11,11,11,11, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,10,10,10,10,10, 9,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10, + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11, + 11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c5_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c5_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_2 = { + _vq_quantthresh__44c5_s_p9_2, + _vq_quantmap__44c5_s_p9_2, + 21, + 21 +}; + +static static_codebook _44c5_s_p9_2 = { + 2, 441, + _vq_lengthlist__44c5_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c5_s_p9_2, + NULL, + &_vq_auxt__44c5_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c5_s_short[] = { + 3, 9,10,15,10,10,11,15,15,17, 4, 5, 7, 8, 7, 7, + 9,13,15,16, 7, 6, 6,10, 6, 8, 9,12,12,16,10, 8, + 11, 8, 8, 7,11,15,17,17, 8, 5, 5, 8, 3, 4, 6,10, + 15,17,10, 7, 7, 7, 4, 4, 5,10,14,17,10, 9, 8, 9, + 6, 5, 6,10,14,17,12,12,11,12, 9, 8, 8,11,14,17, + 13,14,13,10, 7, 5, 6, 9,13,17,14,14,14,10, 7, 5, + 6, 7,10,15, +}; + +static static_codebook _huff_book__44c5_s_short = { + 2, 100, + _huff_lengthlist__44c5_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c6_s_long[] = { + 3, 8,11,13,13,13,12,12,13,18, 6, 3, 4, 7, 9, 9, + 11,11,13,16, 9, 4, 3, 5, 7, 7, 9,10,14,18,11, 7, + 4, 4, 6, 6, 8,10,14,15,11, 9, 6, 6, 6, 6, 8,10, + 13,15,10, 9, 7, 6, 6, 6, 7, 8,12,12,12,10, 9, 8, + 7, 6, 6, 7,11,12,11,10,10, 9, 9, 7, 7, 6, 9,12, + 12,12,13,13,13,10, 9, 8,10,12,13,14,16,16,17,14, + 12,11,11,13, +}; + +static static_codebook _huff_book__44c6_s_long = { + 2, 100, + _huff_lengthlist__44c6_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c6_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 8, 0, + 8, 8, 6, 7, 8, 0, 8, 9, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 8, 8, 0, 8, 8, 0, 8, 8, 5, 8, 8, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8, + 8, +}; + +static float _vq_quantthresh__44c6_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c6_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p1_0 = { + _vq_quantthresh__44c6_s_p1_0, + _vq_quantmap__44c6_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c6_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c6_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c6_s_p1_0, + NULL, + &_vq_auxt__44c6_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c6_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 9, 9, 0, 5, 5, 9, 9, 0, + 7, 7,10,10, 0, 0, 0,10,10, 5, 7, 7, 9, 9, 0, 8, + 7,10, 9, 0, 8, 8,10,10, 0,10,10,11,11, 0, 0, 0, + 11,11, 5, 7, 7, 9, 9, 0, 7, 8, 9,10, 0, 7, 8,10, + 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10, + 0,11,10,12,12, 0,11,11,12,12, 0,13,13,14,14, 0, + 0, 0,14,14, 8, 9, 9,10,11, 0,10,11,12,12, 0,11, + 11,12,12, 0,13,13,14,14, 0, 0, 0,14,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 8,11,10, 0, 0, 0,11,11, 5, + 7, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 8, + 9,10,11, 0, 0, 0,11,11, 9,10,10,12,12, 0,10,10, + 12,11, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13, + 13, 9,10,10,12,12, 0,10,10,11,12, 0,10,10,12,12, + 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7, + 10,10, 0, 8, 9,11,11, 0, 0, 0,11,10, 5, 7, 8,10, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 8,11,11, + 0, 0, 0,11,11, 9,10,10,12,12, 0,10,10,12,12, 0, + 10,10,12,12, 0,12,12,13,13, 0, 0, 0,13,13, 9, 9, + 10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,12,12, + 13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10,13,13, 0, 9, 8,12,12, 0, 8, 9,12,12, 0, + 10, 9,12,12, 0, 0, 0,12,12, 7,10,10,13,13, 0, 9, + 9,12,12, 0, 9, 8,12,12, 0, 9,10,12,12, 0, 0, 0, + 12,12,10,11,11,14,14, 0,11,10,13,13, 0,11,11,13, + 13, 0,12,12,13,13, 0, 0, 0,13,13,10,11,11,14,14, + 0,10,11,13,13, 0,11,11,13,13, 0,12,12,13,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, + 11,11,14,14, 0,11,11,13,13, 0,11,10,13,13, 0,12, + 12,13,13, 0, 0, 0,13,13,10,11,11,14,14, 0,11,11, + 13,13, 0,10,11,13,13, 0,12,12,13,13, 0, 0, 0,13, + 13, +}; + +static float _vq_quantthresh__44c6_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c6_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p2_0 = { + _vq_quantthresh__44c6_s_p2_0, + _vq_quantmap__44c6_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c6_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c6_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c6_s_p2_0, + NULL, + &_vq_auxt__44c6_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c6_s_p3_0[] = { + 2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6, + 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 8, 8,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c6_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c6_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p3_0 = { + _vq_quantthresh__44c6_s_p3_0, + _vq_quantmap__44c6_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c6_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c6_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p3_0, + NULL, + &_vq_auxt__44c6_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c6_s_p4_0[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 8, 9,10,10,11,11, + 11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11,11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12,12,12, 0, 0, 0, 6, 6, 7, 7, 9, 9, + 10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 7, 7, 9, + 9,10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c6_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c6_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p4_0 = { + _vq_quantthresh__44c6_s_p4_0, + _vq_quantmap__44c6_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c6_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c6_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c6_s_p4_0, + NULL, + &_vq_auxt__44c6_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c6_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 4, 7, 7, 9,10,10,10, + 10,10, 4, 7, 7, 9,10,10,10,10,10, 5, 9, 9, 9,11, + 11, 9,11,11, 7,10,10,11,12,11,12,12,12, 7,10,10, + 11,12,12,12,12,12, 6,10,10, 9,11,11,10,11,11, 7, + 10, 9,11,12,12,11,12,11, 7,10,10,11,12,12,11,12, + 12, +}; + +static float _vq_quantthresh__44c6_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c6_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p5_0 = { + _vq_quantthresh__44c6_s_p5_0, + _vq_quantmap__44c6_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c6_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c6_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c6_s_p5_0, + NULL, + &_vq_auxt__44c6_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c6_s_p5_1[] = { + 3, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,11, 4, 4, 6, 6, + 8, 8, 9, 9, 9, 9,11, 4, 4, 6, 6, 8, 8, 9, 8, 9, + 9,12, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,12,12,12, 6, + 6, 8, 8, 9, 9, 9, 9,11,11,11, 7, 7, 8, 8, 9, 9, + 9, 9,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9,11,11,11, + 7, 7, 8, 8, 8, 8, 9, 9,11,11,11,11,11, 8, 8, 8, + 8, 9, 9,11,11,11,11,11, 7, 7, 8, 8, 8, 8,11,11, + 11,11,11, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c6_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c6_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p5_1 = { + _vq_quantthresh__44c6_s_p5_1, + _vq_quantmap__44c6_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c6_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c6_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p5_1, + NULL, + &_vq_auxt__44c6_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p6_0[] = { + 1, 4, 4, 6, 7, 8, 8, 8, 8, 9, 9,10,10, 5, 5, 5, + 7, 7, 9, 9, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 9, + 9, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10, + 11,11,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12, 0,11,11, 8, 8,10, 9,10,11,11,11,12,12, 0,12, + 12, 8, 8,10, 9,11,11,12,11,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c6_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c6_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p6_0 = { + _vq_quantthresh__44c6_s_p6_0, + _vq_quantmap__44c6_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c6_s_p6_0, + NULL, + &_vq_auxt__44c6_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c6_s_p6_1[] = { + 3, 4, 4, 5, 5, 6, 4, 4, 5, 5, 6, 4, 4, 5, 4, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c6_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c6_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p6_1 = { + _vq_quantthresh__44c6_s_p6_1, + _vq_quantmap__44c6_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c6_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c6_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c6_s_p6_1, + NULL, + &_vq_auxt__44c6_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 8, 8, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9, 9, 9,11,11,12,12,19, 7, 7, 7, 7, 9, 9,10,10, + 11,11,12,12,19, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12,19,11,11, 8, 8,10,10,11,11,11,12,12,12,19,12, + 12, 8, 8,10, 9,11,11,12,12,13,12,19,19,19,11,11, + 10,10,11,11,12,12,13,13,19,19,19,11,11,10,10,11, + 11,12,12,13,13,19,19,19,14,14,11,11,11,12,13,13, + 13,13,19,19,19,15,15,11,11,12,12,13,12,14,14,19, + 19,19,19,18,13,13,12,12,13,13,14,14,18,18,18,18, + 18,13,12,12,12,13,13,14,14, +}; + +static float _vq_quantthresh__44c6_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c6_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p7_0 = { + _vq_quantthresh__44c6_s_p7_0, + _vq_quantmap__44c6_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c6_s_p7_0, + NULL, + &_vq_auxt__44c6_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c6_s_p7_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 9, 5, 5, 7, 7, + 7, 7, 7, 7, 8, 8, 9, 5, 5, 6, 6, 7, 7, 7, 7, 7, + 7, 9, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 9, 9, 9, 7, + 7, 7, 7, 7, 8, 7, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, + 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 8, 9, 8, 8, 7, + 7, 7, 7, 9, 9, 8, 8, 9, 8, 8, 7, 7, 8, 8, 9, 9, + 9, 9, 8, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c6_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c6_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p7_1 = { + _vq_quantthresh__44c6_s_p7_1, + _vq_quantmap__44c6_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c6_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c6_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p7_1, + NULL, + &_vq_auxt__44c6_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c6_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 7, 7, 9, 9, 9,10,11,11, 6, + 5, 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11, 6, 5, + 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11,17, 8, 8, + 8, 8,10,10, 8, 9,10,10,11,11,12,11,17, 8, 8, 9, + 9,10,10, 9, 9,10,10,11,12,12,12,17,12,13, 9, 9, + 10,10, 9,10,10,10,11,11,13,12,17,13,13,10, 9,10, + 10,10,10,10,11,12,11,12,12,17,17,17, 9, 9, 9, 9, + 10,10,11,11,11,12,12,13,17,17,17, 9, 9, 9, 9,11, + 10,11,11,12,12,12,13,17,17,17,13,13,10,10,11,11, + 12,11,12,13,13,13,17,17,17,14,13,10, 9,11, 9,12, + 12,12,13,13,14,17,17,17,17,17,11,12,11,11,12,12, + 13,14,13,14,17,17,17,17,17,12,10,11, 8,12,11,13, + 14,14,14,17,17,16,16,16,13,15,11,12,12,13,13,13, + 14,14,16,16,16,16,16,14,13,12, 9,13,10,14,13,14, + 13, +}; + +static float _vq_quantthresh__44c6_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c6_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p8_0 = { + _vq_quantthresh__44c6_s_p8_0, + _vq_quantmap__44c6_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c6_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c6_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c6_s_p8_0, + NULL, + &_vq_auxt__44c6_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c6_s_p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, + 9, 8, 9, 9, 9,11, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,11,10,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 9,10, 9, + 10,10, 9,11,11,11, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10, 9,10, 9, 9, 9, 9,11,11,11,11,11, 8, 8, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10,10, 9, 9, + 9, 9,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,10,10, + 9,10, 9,10,10,10,10,11,11,11,11,11, 9, 9, 9, 9, + 9, 9,10,10,10,10, 9,10,10, 9,10, 9,11,11,11,11, + 11,11,11, 9, 9, 9, 9,10, 9,10, 9, 9,10,10,10,10, + 10,10,11,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10, + 9,10, 9,10,10, 9,11,11,11,11,11,11,10, 9, 9, 9, + 9, 9,10, 9,10,10,10,10,10,10,10,11,11,11,11,11, + 11,11, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11, 9,10, 9,10, 9,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10, + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10, 9,10,10,10,10, 9,10, 9,10,10,11, + 11,11,11,11,11,11,11,11,10,10,10, 9,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10, + 10, 9,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c6_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c6_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p8_1 = { + _vq_quantthresh__44c6_s_p8_1, + _vq_quantmap__44c6_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c6_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c6_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c6_s_p8_1, + NULL, + &_vq_auxt__44c6_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p9_0[] = { + 1, 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c6_s_p9_0[] = { + -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, + 1592.5, 2229.5, 2866.5, 3503.5, +}; + +static long _vq_quantmap__44c6_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_0 = { + _vq_quantthresh__44c6_s_p9_0, + _vq_quantmap__44c6_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p9_0, + 1, -511845376, 1630791680, 4, 0, + _vq_quantlist__44c6_s_p9_0, + NULL, + &_vq_auxt__44c6_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 7, 8, 9,10,11, 6, 6, 6, + 7, 8, 8, 8, 7, 8, 9,10,11,10, 6, 5, 6, 7, 8, 8, + 8, 8, 8, 9,10,10,11,14, 9, 8, 8, 8, 9, 8, 8, 9, + 10,10,12,11,14, 8, 8, 9, 8, 9, 8, 8, 8,11,10,11, + 11,14,14,13, 8, 9, 9, 9, 9,10,11,11,12,12,13,12, + 12, 8, 7,10, 9, 9, 9,11,11,11,10,13,13,13, 8, 9, + 9, 8,12,11,11,11,13,11,13,13,13, 9, 8, 9, 8,10, + 10,11,10,11,10,13,13,13,12,12, 9,10,11,11,11,12, + 13,12,13,13,13,13,12,10,10,10, 9,13,12,12,13,13, + 13,13,13,13,12,12,10,10,12,12,13,13,13,13,13,13, + 13,12,12,11,12,12,12,12,13, +}; + +static float _vq_quantthresh__44c6_s_p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44c6_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_1 = { + _vq_quantthresh__44c6_s_p9_1, + _vq_quantmap__44c6_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c6_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c6_s_p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44c6_s_p9_1, + NULL, + &_vq_auxt__44c6_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c6_s_p9_2[] = { + 2, 4, 3, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c6_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c6_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_2 = { + _vq_quantthresh__44c6_s_p9_2, + _vq_quantmap__44c6_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c6_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c6_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c6_s_p9_2, + NULL, + &_vq_auxt__44c6_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c6_s_short[] = { + 4, 9,11,11,13,13,17,16,17,17, 4, 4, 6, 7, 9, 9, + 12,15,17,17, 7, 5, 4, 5, 7, 8,11,12,17,17, 9, 6, + 4, 3, 5, 6,10,14,17,17,11, 8, 6, 4, 5, 6, 9,13, + 17,17,11,10, 7, 5, 5, 5, 8,12,17,17,13,12, 9, 8, + 7, 6, 8,11,17,17,13,13, 9, 6, 6, 5, 6, 9,17,17, + 17,16,10, 8, 7, 7, 8, 9,17,17,17,17,14,12,11,11, + 11,13,17,17, +}; + +static static_codebook _huff_book__44c6_s_short = { + 2, 100, + _huff_lengthlist__44c6_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c7_s_long[] = { + 3, 8,11,13,14,13,13,12,14,16, 6, 4, 5, 7, 9,10, + 11,11,13,15,10, 4, 3, 5, 7, 7,10,10,14,16,11, 7, + 4, 4, 5, 6, 8,10,13,15,12, 9, 6, 5, 5, 6, 8, 9, + 13,15,11, 9, 7, 6, 5, 5, 6, 8,11,13,11,10, 9, 8, + 7, 6, 6, 7,11,12,12,11,10, 9, 8, 7, 6, 6, 9,11, + 12,12,12,12,12,10, 9, 8,10,12,12,14,15,16,16,14, + 12,10,11,13, +}; + +static static_codebook _huff_book__44c7_s_long = { + 2, 100, + _huff_lengthlist__44c7_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c7_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 8, 7, 0, 9, 8, 0, + 8, 8, 5, 7, 8, 0, 8, 9, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 8, 8, 0, 8, 8, 0, 8, 8, 5, 8, 8, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8, + 8, +}; + +static float _vq_quantthresh__44c7_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c7_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p1_0 = { + _vq_quantthresh__44c7_s_p1_0, + _vq_quantmap__44c7_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c7_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c7_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c7_s_p1_0, + NULL, + &_vq_auxt__44c7_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c7_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 9, 9, 0, 5, 5, 9, 9, 0, + 7, 7,10, 9, 0, 0, 0, 9,10, 5, 7, 7, 9, 9, 0, 8, + 7,10, 9, 0, 8, 7,10, 9, 0,10, 9,11,11, 0, 0, 0, + 11,11, 6, 7, 7, 9, 9, 0, 7, 8, 9,10, 0, 7, 8,10, + 10, 0, 9, 9,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10, + 0,11,10,12,12, 0,11,11,12,12, 0,13,13,14,14, 0, + 0, 0,14,14, 8, 9, 9,10,11, 0,10,11,11,12, 0,11, + 11,12,12, 0,13,13,14,14, 0, 0, 0,14,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7,11,11, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 8,11,10, 0, 0, 0,11,11, 5, + 7, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 8, + 9,10,11, 0, 0, 0,11,11, 9,10,10,12,12, 0,10,10, + 12,11, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13, + 13, 9,10,10,12,12, 0,10,10,11,12, 0,10,10,12,12, + 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7, + 10,10, 0, 9, 9,11,11, 0, 0, 0,11,10, 5, 7, 8,10, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,11, + 0, 0, 0,10,11, 9,10, 9,12,11, 0,10,10,12,12, 0, + 10,10,12,11, 0,12,12,13,13, 0, 0, 0,13,13, 9, 9, + 10,11,12, 0,10,10,12,12, 0,10,10,11,12, 0,12,12, + 13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 9, 9,13,13, 0, 9, 8,12,12, 0, 8, 9,12,12, 0, + 10, 9,12,12, 0, 0, 0,12,12, 7,10, 9,13,13, 0, 9, + 9,12,12, 0, 9, 8,12,12, 0, 9,10,12,12, 0, 0, 0, + 12,12,10,11,11,14,14, 0,11,10,13,12, 0,11,11,13, + 13, 0,12,12,13,13, 0, 0, 0,13,13,10,11,11,14,14, + 0,10,11,12,13, 0,11,11,13,13, 0,12,12,13,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, + 11,11,14,14, 0,11,11,13,13, 0,11,10,13,13, 0,12, + 12,13,13, 0, 0, 0,13,13,10,11,11,14,14, 0,11,11, + 13,13, 0,10,11,13,13, 0,12,12,13,13, 0, 0, 0,13, + 13, +}; + +static float _vq_quantthresh__44c7_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c7_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p2_0 = { + _vq_quantthresh__44c7_s_p2_0, + _vq_quantmap__44c7_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c7_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c7_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c7_s_p2_0, + NULL, + &_vq_auxt__44c7_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c7_s_p3_0[] = { + 2, 4, 4, 5, 5, 7, 7, 8, 8, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6, + 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c7_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c7_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p3_0 = { + _vq_quantthresh__44c7_s_p3_0, + _vq_quantmap__44c7_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c7_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c7_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p3_0, + NULL, + &_vq_auxt__44c7_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c7_s_p4_0[] = { + 3, 4, 4, 6, 5, 7, 7, 7, 7, 8, 8, 9, 9,10,10,11, + 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9,10,10,10, + 11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, + 11,11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c7_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c7_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p4_0 = { + _vq_quantthresh__44c7_s_p4_0, + _vq_quantmap__44c7_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c7_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c7_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c7_s_p4_0, + NULL, + &_vq_auxt__44c7_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c7_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 4, 7, 7,10,11,10,10, + 11,11, 4, 7, 7,10,10,11,10,10,11, 5,10,10, 9,12, + 11,10,12,12, 7,11,10,12,12,12,12,13,13, 7,10,11, + 11,12,12,12,13,13, 5,10,10,10,12,12,10,12,12, 7, + 11,10,12,13,13,12,12,12, 7,10,11,12,13,13,12,12, + 12, +}; + +static float _vq_quantthresh__44c7_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c7_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p5_0 = { + _vq_quantthresh__44c7_s_p5_0, + _vq_quantmap__44c7_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c7_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c7_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c7_s_p5_0, + NULL, + &_vq_auxt__44c7_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c7_s_p5_1[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9,12, 4, 4, 6, 6, + 7, 7, 8, 8, 9, 9,11, 5, 5, 6, 6, 7, 7, 8, 8, 9, + 9,12, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,12,12,12, 6, + 6, 7, 7, 8, 8, 9, 9,12,12,12, 6, 6, 7, 7, 8, 8, + 9, 9,12,11,11, 6, 6, 7, 7, 8, 8, 9, 9,12,12,11, + 7, 7, 8, 8, 8, 8, 8, 8,12,12,12,11,11, 8, 8, 8, + 8, 8, 8,12,12,12,11,11, 7, 7, 7, 7, 8, 8,12,12, + 12,11,11, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c7_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c7_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p5_1 = { + _vq_quantthresh__44c7_s_p5_1, + _vq_quantmap__44c7_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c7_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c7_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p5_1, + NULL, + &_vq_auxt__44c7_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p6_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10, 9,10,10, 5, 5, 5, + 7, 7, 9, 9, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 9, + 9, 9, 9,11,10,11,11, 0, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12, 0,11,10, 8, 8,10,10,11,11,11,12,12,12, 0,11, + 11, 8, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c7_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c7_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p6_0 = { + _vq_quantthresh__44c7_s_p6_0, + _vq_quantmap__44c7_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c7_s_p6_0, + NULL, + &_vq_auxt__44c7_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c7_s_p6_1[] = { + 3, 4, 4, 5, 5, 6, 4, 4, 5, 5, 6, 4, 4, 4, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c7_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c7_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p6_1 = { + _vq_quantthresh__44c7_s_p6_1, + _vq_quantmap__44c7_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c7_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c7_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c7_s_p6_1, + NULL, + &_vq_auxt__44c7_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 9, 8, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9, 9,10,11,11,12,12,20, 7, 7, 7, 7, 9, 9,10,10, + 11,11,12,12,20, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12,20,11,11, 8, 8,10, 9,11,11,11,11,12,12,20,12, + 12, 8, 8, 9, 9,11,11,12,12,12,12,20,20,20,11,11, + 10,10,11,11,12,12,13,13,20,20,20,11,11,10,10,11, + 11,12,12,13,13,20,20,20,14,14,11,11,11,12,13,13, + 13,13,20,20,20,15,14,11,11,11,11,13,13,14,14,20, + 20,20,20,19,12,12,12,12,13,13,14,14,19,19,19,19, + 19,13,12,12,12,13,13,14,14, +}; + +static float _vq_quantthresh__44c7_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c7_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p7_0 = { + _vq_quantthresh__44c7_s_p7_0, + _vq_quantmap__44c7_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c7_s_p7_0, + NULL, + &_vq_auxt__44c7_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c7_s_p7_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 9, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8, 9, 5, 5, 6, 6, 7, 7, 7, 7, 7, + 7, 9, 6, 6, 7, 7, 7, 7, 8, 8, 7, 8, 9, 9, 9, 7, + 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, + 7, 7, 8, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 7, 7, 7, + 7, 8, 7, 9, 9, 9, 9, 9, 8, 8, 7, 7, 8, 8, 9, 9, + 9, 9, 9, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c7_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c7_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p7_1 = { + _vq_quantthresh__44c7_s_p7_1, + _vq_quantmap__44c7_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c7_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c7_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p7_1, + NULL, + &_vq_auxt__44c7_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c7_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,11,11, 6, + 5, 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11, 6, 5, + 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11,17, 8, 8, + 8, 8,10, 9, 8, 9,10,10,11,11,11,11,17, 8, 8, 8, + 8,10,10, 9, 9,10,10,11,11,12,12,17,12,13, 9, 9, + 10,10, 9, 9,10,11,11,11,12,12,17,13,13, 9, 9,10, + 10,10,10,10,10,11,11,12,12,17,17,17, 9, 9, 9, 9, + 10,10,11,11,11,12,12,12,17,17,17, 9, 9, 9, 9,11, + 10,11,12,11,12,13,12,17,17,17,13,14,10,10,10,11, + 12,11,12,12,12,13,17,17,17,14,14,10, 9,10, 9,12, + 12,12,12,13,13,17,17,17,17,17,11,11,11,11,11,12, + 13,13,13,14,17,17,17,17,17,12,10,11, 9,12,11,13, + 15,14,14,17,17,17,17,17,14,15,11,12,12,13,13,12, + 14,14,17,16,16,16,16,15,13,12, 9,12,10,14,12,15, + 14, +}; + +static float _vq_quantthresh__44c7_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c7_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p8_0 = { + _vq_quantthresh__44c7_s_p8_0, + _vq_quantmap__44c7_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c7_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c7_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c7_s_p8_0, + NULL, + &_vq_auxt__44c7_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c7_s_p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,11,11,11, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, + 10,10, 9,11,11,11, 8, 9, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10, 9, 9,10, 9,11,11,11,11,11, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,11,10,11, + 11,11, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10, 9, + 9,10,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10, 9, 9,10,10,10,10,11,11,11,11,11, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 9,10,10,10,10, 9,11,11,10,11, + 11,11,11, 9, 9, 9, 9,10,10,10,10,10,10,10, 9,10, + 10,10,11,11,11,11,11,11, 9, 9, 9, 9, 9,10,10,10, + 10,10, 9, 9,10, 9,11,10,11,11,11,11,11, 9, 9, 9, + 9, 9,10,10, 9,10,10,10,10,10,10,11,11,11,11,11, + 11,11,10, 9,10, 9,10,10,10,10,10,10,10,10,10, 9, + 10,11,10,11,11,11,11,11,10, 9, 9,10,10,10,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,10,11,10,10, + 10,10,10,10,10,10, 9,10,10, 9,11,11,11,11,11,10, + 11,11,11,10,10, 9, 9,10,10,10,10,10, 9,10,10,11, + 11,11,11,11,10,11,11,11,10,10, 9, 9,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11, 9, + 9, 9, 9,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c7_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c7_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p8_1 = { + _vq_quantthresh__44c7_s_p8_1, + _vq_quantmap__44c7_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c7_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c7_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c7_s_p8_1, + NULL, + &_vq_auxt__44c7_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p9_0[] = { + 1, 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, 8, +}; + +static float _vq_quantthresh__44c7_s_p9_0[] = { + -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, + 1592.5, 2229.5, 2866.5, 3503.5, +}; + +static long _vq_quantmap__44c7_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_0 = { + _vq_quantthresh__44c7_s_p9_0, + _vq_quantmap__44c7_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p9_0, + 1, -511845376, 1630791680, 4, 0, + _vq_quantlist__44c7_s_p9_0, + NULL, + &_vq_auxt__44c7_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 7, 9, 8,10,10, 6, 6, 6, + 7, 8, 8, 8, 8, 8, 9, 9,10,11, 6, 5, 6, 8, 7, 8, + 8, 8, 8, 9, 9,10,11,14, 9, 8, 9, 8, 9, 8, 8, 9, + 10,10,11,11,14, 8, 9, 8, 8, 8, 9, 9, 8,12,10,11, + 11,14,13,13, 8, 9, 9, 9, 9,10,10,12,12,12,14,14, + 13, 8, 7,10, 9, 9,10,10,11,11,10,14,14,14, 8, 9, + 9, 8,11,10,12,11,11,11,14,14,14, 9, 7, 9, 8,10, + 10,11,11,11,10,14,14,14,12,12,10, 9,11,11,11,13, + 12,13,14,14,14,12,12,10,10,11, 8,11,11,14,13,14, + 14,14,14,14,12,13,11,12,12,11,14,13,13,13,13,13, + 13,12,11,11, 9,12,12,12,13, +}; + +static float _vq_quantthresh__44c7_s_p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44c7_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_1 = { + _vq_quantthresh__44c7_s_p9_1, + _vq_quantmap__44c7_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c7_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c7_s_p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44c7_s_p9_1, + NULL, + &_vq_auxt__44c7_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c7_s_p9_2[] = { + 2, 4, 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c7_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c7_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_2 = { + _vq_quantthresh__44c7_s_p9_2, + _vq_quantmap__44c7_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c7_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c7_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c7_s_p9_2, + NULL, + &_vq_auxt__44c7_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c7_s_short[] = { + 4,10,12,13,15,15,16,16,17,17, 5, 5, 7, 8, 9, 9, + 12,17,18,18, 7, 5, 4, 5, 7, 8,10,13,18,18, 8, 6, + 5, 4, 5, 6, 9,12,17,18,10, 9, 6, 4, 4, 5, 8,12, + 18,17,11, 9, 7, 5, 4, 4, 6,10,17,17,13,12,10, 8, + 6, 5, 6, 9,17,17,14,13,12, 7, 6, 5, 5, 8,16,17, + 16,15,14, 8, 8, 7, 7, 9,14,17,17,17,17,12,11,11, + 11,12,16,17, +}; + +static static_codebook _huff_book__44c7_s_short = { + 2, 100, + _huff_lengthlist__44c7_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c8_s_long[] = { + 3, 8,12,14,14,13,13,12,13,15, 6, 4, 6, 8,10,10, + 11,11,13,15, 9, 5, 4, 5, 7, 8, 9,10,13,15,11, 7, + 4, 4, 5, 6, 8, 9,13,14,12, 9, 6, 5, 5, 5, 7, 9, + 12,14,11,10, 7, 6, 5, 4, 6, 7,11,12,11,10, 9, 8, + 7, 5, 6, 6,10,11,12,11,10, 9, 8, 6, 6, 5, 8,10, + 12,12,12,11,11,10, 9, 7, 8,11,12,13,14,14,15,13, + 10, 9, 9,11, +}; + +static static_codebook _huff_book__44c8_s_long = { + 2, 100, + _huff_lengthlist__44c8_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c8_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 7, 7, 0, 9, 8, 0, + 8, 8, 6, 7, 8, 0, 8, 9, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 8, 8, 0, 8, 8, 0, 8, 8, 5, 8, 8, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 8, 8, 0, 8, 8, 0, 8, 7, 5, 8, 8, 0, 8, 8, 0, 7, + 8, +}; + +static float _vq_quantthresh__44c8_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c8_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p1_0 = { + _vq_quantthresh__44c8_s_p1_0, + _vq_quantmap__44c8_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c8_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c8_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c8_s_p1_0, + NULL, + &_vq_auxt__44c8_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c8_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 6, 6, 8, 8, 0, 5, 6, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 6, 9, 9, 0, 7, + 7,10, 9, 0, 7, 7,10, 9, 0, 9, 9,11,11, 0, 0, 0, + 11,11, 5, 6, 7, 9, 9, 0, 7, 7, 9,10, 0, 7, 7, 9, + 10, 0, 9, 9,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10, + 0,11,10,12,11, 0,10,10,12,11, 0,13,13,14,13, 0, + 0, 0,14,13, 8, 9, 9,10,11, 0,10,11,11,12, 0,10, + 10,12,12, 0,13,13,13,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 7, 7,10,10, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 8,10,10, 0, 0, 0,10,10, 6, + 7, 7,10,10, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 8, + 9,10,10, 0, 0, 0,10,10, 8,10, 9,12,12, 0,10, 9, + 12,11, 0,10,10,11,12, 0,12,11,13,12, 0, 0, 0,13, + 13, 8, 9,10,11,12, 0, 9,10,11,12, 0,10,10,11,12, + 0,11,12,12,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7, + 10, 9, 0, 8, 9,10,10, 0, 0, 0,10,10, 6, 7, 8,10, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 8,10,10, + 0, 0, 0,10,10, 8,10, 9,12,11, 0,10,10,12,11, 0, + 10,10,12,11, 0,11,12,13,12, 0, 0, 0,13,12, 9, 9, + 10,11,12, 0,10,10,11,12, 0,10,10,11,12, 0,12,11, + 12,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 9, 9,12,13, 0, 9, 8,12,11, 0, 8, 9,11,12, 0, + 10, 9,12,11, 0, 0, 0,11,12, 7, 9, 9,13,13, 0, 9, + 9,11,12, 0, 9, 8,12,11, 0, 9,10,11,12, 0, 0, 0, + 12,11, 9,11,11,14,13, 0,10,10,13,12, 0,10,10,13, + 13, 0,12,11,13,12, 0, 0, 0,13,13, 9,11,11,13,14, + 0,10,10,12,13, 0,10,10,13,13, 0,11,12,12,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,11,14,13, 0,10,10,13,12, 0,10,10,13,12, 0,11, + 12,13,13, 0, 0, 0,13,12, 9,11,11,13,14, 0,10,10, + 13,13, 0,10,10,12,13, 0,12,11,13,13, 0, 0, 0,12, + 13, +}; + +static float _vq_quantthresh__44c8_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c8_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p2_0 = { + _vq_quantthresh__44c8_s_p2_0, + _vq_quantmap__44c8_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c8_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c8_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c8_s_p2_0, + NULL, + &_vq_auxt__44c8_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c8_s_p3_0[] = { + 3, 3, 4, 5, 5, 7, 6, 8, 8, 0, 4, 4, 5, 5, 7, 7, + 9, 9, 0, 4, 4, 5, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6, + 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c8_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c8_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p3_0 = { + _vq_quantthresh__44c8_s_p3_0, + _vq_quantmap__44c8_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c8_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c8_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p3_0, + NULL, + &_vq_auxt__44c8_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c8_s_p4_0[] = { + 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10, + 10, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10,10, + 11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 10,11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c8_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c8_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p4_0 = { + _vq_quantthresh__44c8_s_p4_0, + _vq_quantmap__44c8_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c8_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c8_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c8_s_p4_0, + NULL, + &_vq_auxt__44c8_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c8_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,10,10,10, + 10,10, 4, 6, 6,10,10,10,10,10,10, 5,10,10, 9,12, + 12,10,12,12, 7,10,10,12,12,12,12,12,12, 7,10,10, + 12,12,12,12,12,13, 6,10,10,10,12,12,11,12,12, 8, + 10,10,12,13,12,12,12,12, 7,10,10,12,12,13,12,13, + 12, +}; + +static float _vq_quantthresh__44c8_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c8_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p5_0 = { + _vq_quantthresh__44c8_s_p5_0, + _vq_quantmap__44c8_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c8_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c8_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c8_s_p5_0, + NULL, + &_vq_auxt__44c8_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c8_s_p5_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7,10, 4, 4, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, 6, + 6, 7, 7, 8, 8, 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, + 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, + 7, 7, 7, 7, 8, 8, 8, 8,11,11,11,11,11, 7, 7, 8, + 8, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 8, 8,11,11, + 11,11,11, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c8_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c8_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p5_1 = { + _vq_quantthresh__44c8_s_p5_1, + _vq_quantmap__44c8_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c8_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c8_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p5_1, + NULL, + &_vq_auxt__44c8_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c8_s_p6_0[] = { + 1, 4, 4, 7, 6, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 9, 9,10, 9,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9,10,10,11,11,12,12, 0, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,12,12,12, + 12, 0,10,10, 8, 8,10,10,11,11,12,12,13,13, 0,11, + 11, 8, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c8_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c8_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p6_0 = { + _vq_quantthresh__44c8_s_p6_0, + _vq_quantmap__44c8_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c8_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c8_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c8_s_p6_0, + NULL, + &_vq_auxt__44c8_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c8_s_p6_1[] = { + 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c8_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c8_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p6_1 = { + _vq_quantthresh__44c8_s_p6_1, + _vq_quantmap__44c8_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c8_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c8_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c8_s_p6_1, + NULL, + &_vq_auxt__44c8_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c8_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 9, 9,10,10,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9,10,10,11,11,12,12,20, 6, 7, 7, 7, 9, 9,10,10, + 11,11,12,12,20, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12,20,11,11, 8, 8,10,10,11,11,12,12,12,12,20,12, + 12, 8, 8,10, 9,11,11,12,12,13,13,20,20,20,11,10, + 10,10,11,11,12,12,13,13,20,20,20,10,11,10,10,11, + 11,12,12,13,13,20,20,20,14,15,11,11,12,12,13,13, + 14,13,20,20,20,15,15,11,11,12,12,13,13,14,14,20, + 20,20,20,19,13,13,12,12,13,13,14,14,19,19,19,19, + 19,13,13,12,12,13,13,14,14, +}; + +static float _vq_quantthresh__44c8_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c8_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p7_0 = { + _vq_quantthresh__44c8_s_p7_0, + _vq_quantmap__44c8_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c8_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c8_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c8_s_p7_0, + NULL, + &_vq_auxt__44c8_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c8_s_p7_1[] = { + 4, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 5, 5, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 5, 5, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c8_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c8_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p7_1 = { + _vq_quantthresh__44c8_s_p7_1, + _vq_quantmap__44c8_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c8_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c8_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p7_1, + NULL, + &_vq_auxt__44c8_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c8_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,11, 6, + 5, 5, 7, 7, 9, 9, 8, 8,10,10,11,11,11,12, 6, 5, + 5, 7, 7, 9, 9, 9, 8,10,10,11,10,11,12,18, 8, 8, + 8, 8, 9, 9, 9, 9,10,10,11,11,12,12,18, 8, 8, 8, + 8, 9, 9, 9, 9,10,10,11,11,12,13,18,12,12, 9, 9, + 10,10, 9, 9,10,11,11,12,13,12,18,12,12, 9, 9,10, + 10,10,10,10,11,11,12,13,13,18,18,18, 9, 9, 9, 9, + 10,10,11,11,12,12,12,12,18,18,18, 9, 9, 9, 9,10, + 10,11,11,12,12,13,13,18,18,18,13,13,10,10,11,11, + 12,11,12,12,13,13,18,18,18,14,14,10, 9,11,10,12, + 12,12,12,13,13,18,18,18,18,18,11,12,11,11,12,12, + 13,13,14,13,18,18,18,18,18,12,11,11,10,12,11,13, + 13,13,14,18,18,18,18,18,15,16,12,12,12,13,13,13, + 14,14,18,17,17,17,17,16,14,12,11,12,11,13,12,15, + 14, +}; + +static float _vq_quantthresh__44c8_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c8_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p8_0 = { + _vq_quantthresh__44c8_s_p8_0, + _vq_quantmap__44c8_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c8_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c8_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c8_s_p8_0, + NULL, + &_vq_auxt__44c8_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c8_s_p8_1[] = { + 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,11, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,11,11,10,11,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10, + 9, 9,10,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,11,10,10, 9, 9, 9, 9, + 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, 9,11,10,11,10, + 10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, + 9,11,11,11,10,10,11,10, 9, 9, 9, 9, 9, 9,10,10, + 9, 9, 9, 9, 9, 9,10,11,10,10,10,11,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,10,10,10, + 10,10, 9, 9, 9,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,11,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,11,11,10,11,10,10,10,10,10,10, 9, + 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9,10, 9, 9,10, 9, 9, +}; + +static float _vq_quantthresh__44c8_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c8_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p8_1 = { + _vq_quantthresh__44c8_s_p8_1, + _vq_quantmap__44c8_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c8_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c8_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c8_s_p8_1, + NULL, + &_vq_auxt__44c8_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c8_s_p9_0[] = { + 1, 5, 5,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, 7,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10, 6, 8,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c8_s_p9_0[] = { + -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, + 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, 6982.5, +}; + +static long _vq_quantmap__44c8_s_p9_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_0 = { + _vq_quantthresh__44c8_s_p9_0, + _vq_quantmap__44c8_s_p9_0, + 17, + 17 +}; + +static static_codebook _44c8_s_p9_0 = { + 2, 289, + _vq_lengthlist__44c8_s_p9_0, + 1, -509798400, 1631393792, 5, 0, + _vq_quantlist__44c8_s_p9_0, + NULL, + &_vq_auxt__44c8_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c8_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 7, 9, 9,10,10,11,10,13, + 12,11,12, 6, 6, 6, 8, 8, 8, 8, 8, 8, 9,10,10,10, + 12,12,12,12,13,15, 5, 5, 5, 8, 8, 8, 8, 8, 8,10, + 9,10,11,12,13,12,13,13,12,15, 9, 8, 9, 9, 9, 9, + 9, 9,10,10,10,11,14,12,13,15,12,14,15, 8, 9, 9, + 9, 9, 9, 9, 9,10,10,12,11,12,11,12,13,13,13,15, + 13,13, 9, 9,10, 9,10,10,11,10,11,12,12,12,14,13, + 14,15,15,13,13, 9, 8,10, 9,10,10,11,10,12,12,13, + 13,14,13,14,15,15,15,15, 9, 9, 9, 9,10,11,12,12, + 12,13,13,13,14,15,15,14,15,15,15, 9, 7, 9, 8,12, + 11,11,13,12,12,13,12,14,13,13,14,15,15,15,13,13, + 10,10,12,11,13,13,12,12,13,13,14,13,13,15,15,15, + 15,12,13,11, 9,11,10,12,12,15,13,13,13,14,13,14, + 13,15,15,15,15,15,12,12,11,11,12,13,15,13,13,14, + 14,14,15,14,15,15,15,15,15,13,11,12,11,12,11,13, + 14,13,13,14,14,13,14,15,15,15,15,15,15,15,12,12, + 12,13,15,13,15,14,15,14,13,15,15,15,15,15,15,14, + 15,13,13,12,11,14,12,15,13,14,14,14,13,15,15,15, + 15,15,15,15,14,13,14,13,15,13,15,15,15,14,15,14, + 15,15,15,15,15,15,15,14,14,14,13,13,13,15,15,15, + 15,14,15,15,15,15,15,15,15,15,15,15,12,13,13,13, + 14,15,15,13,15,15,15,15,15,15,15,15,15,15,15,15, + 15,14,14,15,15,15,14,14,15, +}; + +static float _vq_quantthresh__44c8_s_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44c8_s_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_1 = { + _vq_quantthresh__44c8_s_p9_1, + _vq_quantmap__44c8_s_p9_1, + 19, + 19 +}; + +static static_codebook _44c8_s_p9_1 = { + 2, 361, + _vq_lengthlist__44c8_s_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44c8_s_p9_1, + NULL, + &_vq_auxt__44c8_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c8_s_p9_2[] = { + 3, 4, 3, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c8_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c8_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_2 = { + _vq_quantthresh__44c8_s_p9_2, + _vq_quantmap__44c8_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c8_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c8_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c8_s_p9_2, + NULL, + &_vq_auxt__44c8_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c8_s_short[] = { + 4,11,13,14,16,15,16,16,17,16, 5, 6, 8, 9,10, 9, + 11,17,16,17, 6, 6, 6, 6, 7, 8, 9,14,16,17, 8, 6, + 5, 4, 6, 7, 9,12,14,17, 9, 7, 6, 5, 5, 5, 8,11, + 14,17,10, 9, 7, 6, 5, 3, 5, 8,13,17,12,11, 9, 8, + 7, 4, 4, 6,14,17,13,13,12, 8, 7, 5, 4, 5,12,17, + 17,14,15,10, 8, 7, 7, 7,11,17,17,16,17,14,12,10, + 11,11,15,17, +}; + +static static_codebook _huff_book__44c8_s_short = { + 2, 100, + _huff_lengthlist__44c8_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c9_s_long[] = { + 3, 8,13,14,15,15,13,13,14,14, 6, 5, 8,10,12,12, + 13,12,13,14,10, 6, 5, 6, 8, 9,11,11,13,14,13, 8, + 5, 4, 5, 6, 9,10,13,14,14,11, 7, 5, 4, 5, 8, 9, + 12,14,12,11, 8, 6, 5, 3, 5, 7,10,13,12,10,10, 8, + 7, 5, 4, 6, 9,12,13,12,11,10, 9, 6, 5, 5, 7,10, + 13,12,12,11,11, 9, 8, 7, 8,10,12,12,13,13,14,12, + 10, 9, 9,10, +}; + +static static_codebook _huff_book__44c9_s_long = { + 2, 100, + _huff_lengthlist__44c9_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c9_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 8, 8, 0, 9, 8, 0, + 8, 8, 6, 8, 8, 0, 8, 9, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 8, 8, 0, 8, 7, 0, 8, 8, 5, 8, 8, + 0, 7, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 8, 0, 8, 8, 0, 7, 7, 5, 8, 9, 0, 8, 8, 0, 7, + 7, +}; + +static float _vq_quantthresh__44c9_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c9_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p1_0 = { + _vq_quantthresh__44c9_s_p1_0, + _vq_quantmap__44c9_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c9_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c9_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c9_s_p1_0, + NULL, + &_vq_auxt__44c9_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c9_s_p2_0[] = { + 3, 6, 6, 8, 8, 0, 6, 6, 8, 8, 0, 5, 5, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 6, 7, 7, 9, 8, 0, 8, + 7, 9, 9, 0, 7, 7, 9, 9, 0, 9, 9,11,10, 0, 0, 0, + 10,10, 6, 7, 7, 8, 9, 0, 7, 8, 9, 9, 0, 7, 7, 9, + 9, 0, 9, 9,10,11, 0, 0, 0,10,10, 8, 9, 9,10,10, + 0,10,10,11,11, 0,10,10,11,11, 0,12,12,13,12, 0, + 0, 0,13,13, 8, 8, 9,10,10, 0,10,10,11,12, 0,10, + 10,11,11, 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 8, 7,10,10, 0, 7, 7,10, 9, + 0, 7, 7,10,10, 0, 9, 8,10,10, 0, 0, 0,10,10, 6, + 7, 7,10,10, 0, 7, 7, 9,10, 0, 7, 7,10,10, 0, 8, + 9,10,10, 0, 0, 0,10,10, 8, 9, 9,11,11, 0,10, 9, + 11,11, 0,10,10,11,11, 0,11,11,12,12, 0, 0, 0,12, + 12, 8, 9, 9,11,11, 0, 9,10,11,11, 0,10,10,11,11, + 0,11,11,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7,10,10, 0, 7, 7,10,10, 0, 7, 7, + 10, 9, 0, 8, 9,10,10, 0, 0, 0,10, 9, 5, 7, 8,10, + 10, 0, 7, 7,10,10, 0, 7, 7, 9,10, 0, 9, 8,10,10, + 0, 0, 0,10,10, 8, 9, 9,12,11, 0,10,10,11,11, 0, + 10, 9,11,11, 0,11,11,12,12, 0, 0, 0,12,12, 8, 9, + 9,11,11, 0,10,10,11,11, 0, 9,10,11,11, 0,11,11, + 12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 9, 9,12,12, 0, 9, 9,11,11, 0, 8, 9,11,11, 0, + 10, 9,12,11, 0, 0, 0,11,11, 7, 9, 9,12,12, 0, 8, + 9,11,11, 0, 9, 8,11,11, 0, 9,10,11,11, 0, 0, 0, + 11,11, 9,11,11,13,13, 0,10,10,12,12, 0,10,10,12, + 12, 0,12,11,12,12, 0, 0, 0,13,13, 9,10,11,13,13, + 0,10,10,12,12, 0,10,10,12,12, 0,11,11,12,12, 0, + 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,10,13,13, 0,10,10,12,12, 0,10, 9,12,12, 0,11, + 11,12,13, 0, 0, 0,12,11, 9,10,10,12,13, 0,10,10, + 12,12, 0,10,10,12,12, 0,11,11,13,12, 0, 0, 0,12, + 12, +}; + +static float _vq_quantthresh__44c9_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c9_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p2_0 = { + _vq_quantthresh__44c9_s_p2_0, + _vq_quantmap__44c9_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c9_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c9_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c9_s_p2_0, + NULL, + &_vq_auxt__44c9_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c9_s_p3_0[] = { + 3, 4, 4, 5, 5, 6, 6, 8, 8, 0, 4, 4, 5, 5, 7, 6, + 8, 8, 0, 4, 4, 5, 5, 7, 7, 8, 8, 0, 5, 5, 6, 6, + 7, 7, 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, + 7, 7, 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c9_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c9_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p3_0 = { + _vq_quantthresh__44c9_s_p3_0, + _vq_quantmap__44c9_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c9_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c9_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p3_0, + NULL, + &_vq_auxt__44c9_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c9_s_p4_0[] = { + 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9,10, + 10, 0, 5, 5, 5, 5, 6, 6, 8, 7, 8, 8, 9, 9,10,10, + 11,11, 0, 5, 5, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10, + 10,11,11, 0, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 6, 6, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 7, 7, 9, 9, 9, 9, + 11,11,11,11,12,12, 0, 0, 0, 7, 7, 7, 8, 9, 9, 9, + 9,11,10,11,11,12,12, 0, 0, 0, 7, 7, 7, 7, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 7, 7, 9, + 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c9_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c9_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p4_0 = { + _vq_quantthresh__44c9_s_p4_0, + _vq_quantmap__44c9_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c9_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c9_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c9_s_p4_0, + NULL, + &_vq_auxt__44c9_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c9_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,10,10,10, + 10,10, 4, 6, 6,10,10,10,10,10,10, 5,10,10, 9,12, + 12,10,12,12, 7,10,10,12,12,12,12,12,13, 7,10,10, + 12,12,12,12,13,13, 6,10,10,10,12,12,11,12,12, 8, + 10,10,12,12,12,12,12,12, 7,10,10,12,12,13,12,12, + 12, +}; + +static float _vq_quantthresh__44c9_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c9_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p5_0 = { + _vq_quantthresh__44c9_s_p5_0, + _vq_quantmap__44c9_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c9_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c9_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c9_s_p5_0, + NULL, + &_vq_auxt__44c9_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c9_s_p5_1[] = { + 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7,10, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, 7, 7, 7, 7, 8, + 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, 6, + 6, 7, 7, 8, 8, 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, + 8, 8,11,11,11, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11, + 7, 7, 7, 7, 7, 7, 8, 8,11,11,11,11,11, 7, 7, 7, + 7, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 7, 7,11,11, + 11,11,11, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c9_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c9_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p5_1 = { + _vq_quantthresh__44c9_s_p5_1, + _vq_quantmap__44c9_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c9_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c9_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p5_1, + NULL, + &_vq_auxt__44c9_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c9_s_p6_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 5, 4, 4, + 6, 6, 8, 8, 9, 9,10,10,11,11, 6, 4, 4, 6, 6, 8, + 8, 9, 9,10,10,12,12, 0, 6, 6, 6, 6, 8, 8,10,10, + 11,11,12,12, 0, 6, 6, 6, 6, 8, 8,10,10,11,11,12, + 12, 0,10,10, 8, 8, 9, 9,11,11,12,12,13,13, 0,11, + 11, 8, 8, 9,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c9_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c9_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p6_0 = { + _vq_quantthresh__44c9_s_p6_0, + _vq_quantmap__44c9_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c9_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c9_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c9_s_p6_0, + NULL, + &_vq_auxt__44c9_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c9_s_p6_1[] = { + 4, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44c9_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c9_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p6_1 = { + _vq_quantthresh__44c9_s_p6_1, + _vq_quantmap__44c9_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c9_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c9_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c9_s_p6_1, + NULL, + &_vq_auxt__44c9_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c9_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 6, 5, 5, + 7, 7, 9, 8,10,10,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9,10,10,11,11,12,12,20, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12,20, 7, 7, 7, 7, 9, 9,10,10,11,11,13, + 12,20,10,10, 8, 8, 9, 9,11,11,12,12,13,13,20,11, + 11, 8, 8, 9, 9,11,11,12,12,13,13,20,20,20,10,10, + 10,10,11,11,12,12,13,13,20,20,20,10,10,10,10,11, + 11,12,12,13,13,20,20,20,14,14,11,11,12,12,13,13, + 14,13,20,20,20,14,15,11,11,11,11,13,13,14,13,20, + 20,20,20,19,12,12,12,12,13,13,14,14,19,19,19,19, + 19,13,13,12,12,13,13,14,14, +}; + +static float _vq_quantthresh__44c9_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c9_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p7_0 = { + _vq_quantthresh__44c9_s_p7_0, + _vq_quantmap__44c9_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c9_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c9_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c9_s_p7_0, + NULL, + &_vq_auxt__44c9_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c9_s_p7_1[] = { + 5, 6, 6, 6, 6, 7, 6, 7, 7, 7, 7, 8, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 6, + 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c9_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c9_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p7_1 = { + _vq_quantthresh__44c9_s_p7_1, + _vq_quantmap__44c9_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c9_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c9_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p7_1, + NULL, + &_vq_auxt__44c9_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c9_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,11, 6, + 5, 5, 7, 7, 9, 9, 8, 9,10,10,11,11,12,12, 6, 5, + 5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,19, 7, 8, + 8, 8, 9, 9, 9, 9,10,10,11,11,12,13,19, 8, 8, 8, + 8, 9, 9, 9, 9,10,10,11,12,12,12,19,12,12, 9, 9, + 9,10, 9,10,10,10,12,12,12,12,19,12,12, 9, 9,10, + 9,10,10,11,11,12,11,13,13,19,19,19, 9, 9, 9, 9, + 10,10,11,11,12,12,12,12,19,19,19, 9, 9, 9, 9,10, + 10,11,11,12,12,13,13,19,19,19,13,13,10,10,10,10, + 12,12,12,12,13,13,19,19,19,13,13,10,10,10,10,12, + 12,12,12,13,13,19,19,19,19,19,11,12,11,11,12,12, + 13,12,13,13,19,19,19,18,18,12,11,11,10,12,11,13, + 13,13,14,18,18,18,18,18,15,16,12,12,13,12,13,13, + 14,14,18,18,18,18,18,16,15,12,11,12,11,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c9_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c9_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p8_0 = { + _vq_quantthresh__44c9_s_p8_0, + _vq_quantmap__44c9_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c9_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c9_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c9_s_p8_0, + NULL, + &_vq_auxt__44c9_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c9_s_p8_1[] = { + 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10, + 10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10, 9, 9, 9, 9,10,10,10,10, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, + 10,10, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10, 9, 9, 9,10, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c9_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c9_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p8_1 = { + _vq_quantthresh__44c9_s_p8_1, + _vq_quantmap__44c9_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c9_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c9_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c9_s_p8_1, + NULL, + &_vq_auxt__44c9_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_0[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c9_s_p9_0[] = { + 1, 4, 4,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10, 7, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10, 7, 9,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c9_s_p9_0[] = { + -7913.5, -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, + -465.5, 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, + 6982.5, 7913.5, +}; + +static long _vq_quantmap__44c9_s_p9_0[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_0 = { + _vq_quantthresh__44c9_s_p9_0, + _vq_quantmap__44c9_s_p9_0, + 19, + 19 +}; + +static static_codebook _44c9_s_p9_0 = { + 2, 361, + _vq_lengthlist__44c9_s_p9_0, + 1, -508535424, 1631393792, 5, 0, + _vq_quantlist__44c9_s_p9_0, + NULL, + &_vq_auxt__44c9_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c9_s_p9_1[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9,10,10,10,12,11,12, + 13,13,12, 6, 5, 5, 8, 8, 8, 9, 8, 9,10,10,11,11, + 12,12,14,13,13,12, 5, 5, 5, 8, 8, 9, 8, 8, 9,10, + 10,11,11,12,12,14,12,13,13,16, 8, 8, 9, 9, 9, 9, + 9, 9,10,10,11,12,13,13,13,13,14,14,16, 8, 8, 9, + 9, 9, 9, 9, 9,11,11,12,11,13,13,14,13,13,13,16, + 14,13, 9, 9, 9, 9,10,10,11,12,12,13,13,13,14,13, + 15,14,16,13,13, 9, 8, 9, 9,10,10,12,11,13,13,14, + 14,14,14,15,14,16,16,16, 9, 9, 9, 9,10,10,12,12, + 12,13,13,13,15,13,15,15,16,16,16, 9, 7, 9, 8,10, + 11,11,12,12,13,13,16,15,14,14,14,16,16,16,13,13, + 10,10,11,11,13,15,13,14,13,14,14,13,14,14,16,16, + 16,13,12,10, 9,11,11,12,12,14,14,13,14,14,14,14, + 14,16,16,16,16,16,12,13,11,11,12,13,13,13,14,15, + 14,14,16,15,16,16,16,16,16,12,11,12,12,15,13,13, + 13,14,13,15,14,15,14,16,16,16,16,16,14,15,12,13, + 13,12,14,15,15,14,15,14,15,13,16,16,16,16,16,16, + 16,13,13,14,12,16,12,16,15,14,15,14,14,16,16,16, + 16,16,16,16,15,14,14,14,15,16,16,16,16,14,16,16, + 16,16,16,16,16,16,16,14,14,14,12,15,11,15,13,16, + 15,16,15,16,16,16,16,16,16,16,15,16,14,14,15,13, + 15,16,16,16,16,15,16,16,16,16,16,16,16,16,16,15, + 15,14,13,14,16,16,14,15,16, +}; + +static float _vq_quantthresh__44c9_s_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44c9_s_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_1 = { + _vq_quantthresh__44c9_s_p9_1, + _vq_quantmap__44c9_s_p9_1, + 19, + 19 +}; + +static static_codebook _44c9_s_p9_1 = { + 2, 361, + _vq_lengthlist__44c9_s_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44c9_s_p9_1, + NULL, + &_vq_auxt__44c9_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c9_s_p9_2[] = { + 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c9_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c9_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_2 = { + _vq_quantthresh__44c9_s_p9_2, + _vq_quantmap__44c9_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c9_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c9_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c9_s_p9_2, + NULL, + &_vq_auxt__44c9_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c9_s_short[] = { + 5,13,17,15,16,16,18,17,18,18, 5, 7,10,12,12,12, + 12,17,18,17, 7, 6, 7, 8, 9, 9, 9,13,17,17, 8, 6, + 6, 5, 6, 7, 8,11,16,18, 9, 7, 7, 5, 5, 6, 7,10, + 15,18, 9, 8, 7, 6, 5, 4, 5, 7,13,17,11,11, 9, 8, + 7, 4, 3, 5,12,18,13,13,12,10, 7, 5, 4, 3, 8,13, + 16,16,16,13, 8, 8, 7, 5, 8,12,15,18,17,15,11,10, + 9, 8,10,14, +}; + +static static_codebook _huff_book__44c9_s_short = { + 2, 100, + _huff_lengthlist__44c9_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p1_0[] = { + 1, 5, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0, + 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 9,11,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9,10, 0, 0, + 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 9,11,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,11, 0, + 0, 0, 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,11,11, + 0, 0, 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p1_0 = { + _vq_quantthresh__8c0_s_p1_0, + _vq_quantmap__8c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__8c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8c0_s_p1_0, + NULL, + &_vq_auxt__8c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p2_0 = { + _vq_quantthresh__8c0_s_p2_0, + _vq_quantmap__8c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _8c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__8c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p2_0, + NULL, + &_vq_auxt__8c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p3_0 = { + _vq_quantthresh__8c0_s_p3_0, + _vq_quantmap__8c0_s_p3_0, + 5, + 5 +}; + +static static_codebook _8c0_s_p3_0 = { + 4, 625, + _vq_lengthlist__8c0_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p3_0, + NULL, + &_vq_auxt__8c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c0_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p4_0 = { + _vq_quantthresh__8c0_s_p4_0, + _vq_quantmap__8c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _8c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__8c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p4_0, + NULL, + &_vq_auxt__8c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c0_s_p5_0[] = { + 1, 3, 3, 5, 5, 7, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 9, 0, 0, 0, 8, 8, + 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8, 9, 9, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__8c0_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c0_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p5_0 = { + _vq_quantthresh__8c0_s_p5_0, + _vq_quantmap__8c0_s_p5_0, + 9, + 9 +}; + +static static_codebook _8c0_s_p5_0 = { + 2, 81, + _vq_lengthlist__8c0_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p5_0, + NULL, + &_vq_auxt__8c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8c0_s_p6_0[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 8, 8,10, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,11, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,11, + 10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,10, + 11,11,11,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0,10,10,10,10,11,11, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10, 9,10, + 11,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10, 9,10,11,12,12,13,13,14,13, 0, 0, 0, 0, 0, 9, + 9, 9,10,10,10,11,11,13,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,14,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,13,13,14,14,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__8c0_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8c0_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p6_0 = { + _vq_quantthresh__8c0_s_p6_0, + _vq_quantmap__8c0_s_p6_0, + 17, + 17 +}; + +static static_codebook _8c0_s_p6_0 = { + 2, 289, + _vq_lengthlist__8c0_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8c0_s_p6_0, + NULL, + &_vq_auxt__8c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,11, 9,10,12, + 9,10, 4, 7, 7,10,10,10,11, 9, 9, 6,11,10,11,11, + 12,11,11,11, 6,10,10,11,11,12,11,10,10, 6, 9,10, + 11,11,11,11,10,10, 7,10,11,12,11,11,12,11,12, 6, + 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__8c0_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8c0_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p7_0 = { + _vq_quantthresh__8c0_s_p7_0, + _vq_quantmap__8c0_s_p7_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p7_0 = { + 4, 81, + _vq_lengthlist__8c0_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8c0_s_p7_0, + NULL, + &_vq_auxt__8c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8c0_s_p7_1[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, 7, 7, + 8, 8, 9, 9, 9, 9,10,10, 9, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,10, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10, 8, + 8, 9, 9, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9,10, + 10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,11,10,11, + 9, 9, 9, 9,10,10,10,10,11,11,11,10,10, 9, 9,10, + 10,10, 9,11,10,10,10,10,10,10, 9, 9,10,10,11,11, + 10,10,10, 9, 9, 9,10,10,10, +}; + +static float _vq_quantthresh__8c0_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8c0_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p7_1 = { + _vq_quantthresh__8c0_s_p7_1, + _vq_quantmap__8c0_s_p7_1, + 11, + 11 +}; + +static static_codebook _8c0_s_p7_1 = { + 2, 121, + _vq_lengthlist__8c0_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p7_1, + NULL, + &_vq_auxt__8c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c0_s_p8_0[] = { + 1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 6, 6, + 7, 7, 8, 8, 7, 7, 8, 9,10,10, 7, 6, 6, 7, 7, 8, + 7, 7, 7, 9, 9,10,12, 0, 8, 8, 8, 8, 8, 9, 8, 8, + 9, 9,10,10, 0, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9,11, + 10, 0, 0,13, 9, 8, 9, 9, 9, 9,10,10,11,11, 0,13, + 0, 9, 9, 9, 9, 9, 9,11,10,11,11, 0, 0, 0, 8, 9, + 10, 9,10,10,13,11,12,12, 0, 0, 0, 8, 9, 9, 9,10, + 10,13,12,12,13, 0, 0, 0,12, 0,10,10,12,11,10,11, + 12,12, 0, 0, 0,13,13,10,10,10,11,12, 0,13, 0, 0, + 0, 0, 0, 0,13,11, 0,12,12,12,13,12, 0, 0, 0, 0, + 0, 0,13,13,11,13,13,11,12, +}; + +static float _vq_quantthresh__8c0_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8c0_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p8_0 = { + _vq_quantthresh__8c0_s_p8_0, + _vq_quantmap__8c0_s_p8_0, + 13, + 13 +}; + +static static_codebook _8c0_s_p8_0 = { + 2, 169, + _vq_lengthlist__8c0_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8c0_s_p8_0, + NULL, + &_vq_auxt__8c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p8_1[] = { + 1, 3, 4, 5, 5, 7, 6, 6, 6, 5, 7, 7, 7, 6, 6, 7, + 7, 7, 6, 6, 7, 7, 7, 6, 6, +}; + +static float _vq_quantthresh__8c0_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p8_1 = { + _vq_quantthresh__8c0_s_p8_1, + _vq_quantmap__8c0_s_p8_1, + 5, + 5 +}; + +static static_codebook _8c0_s_p8_1 = { + 2, 25, + _vq_lengthlist__8c0_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p8_1, + NULL, + &_vq_auxt__8c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p9_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__8c0_s_p9_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__8c0_s_p9_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_0 = { + _vq_quantthresh__8c0_s_p9_0, + _vq_quantmap__8c0_s_p9_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p9_0 = { + 4, 81, + _vq_lengthlist__8c0_s_p9_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__8c0_s_p9_0, + NULL, + &_vq_auxt__8c0_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8c0_s_p9_1[] = { + 1, 4, 4, 5, 5,10, 8,11,11,11,11,11,11,11,11, 6, + 6, 6, 7, 6,11,10,11,11,11,11,11,11,11,11, 7, 5, + 6, 6, 6, 8, 7,11,11,11,11,11,11,11,11,11, 7, 8, + 8, 8, 9, 9,11,11,11,11,11,11,11,11,11, 9, 8, 7, + 8, 9,11,11,11,11,11,11,11,11,11,11,11,10,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11, +}; + +static float _vq_quantthresh__8c0_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8c0_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_1 = { + _vq_quantthresh__8c0_s_p9_1, + _vq_quantmap__8c0_s_p9_1, + 15, + 15 +}; + +static static_codebook _8c0_s_p9_1 = { + 2, 225, + _vq_lengthlist__8c0_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8c0_s_p9_1, + NULL, + &_vq_auxt__8c0_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8c0_s_p9_2[] = { + 1, 5, 5, 7, 7, 8, 7, 8, 8,10,10, 9, 9,10,10,10, + 11,11,10,12,11,12,12,12, 9, 8, 8, 8, 8, 8, 9,10, + 10,10,10,11,11,11,10,11,11,12,12,11,12, 8, 8, 7, + 7, 8, 9,10,10,10, 9,10,10, 9,10,10,11,11,11,11, + 11,11, 9, 9, 9, 9, 8, 9,10,10,11,10,10,11,11,12, + 10,10,12,12,11,11,10, 9, 9,10, 8, 9,10,10,10, 9, + 10,10,11,11,10,11,10,10,10,12,12,12, 9,10, 9,10, + 9, 9,10,10,11,11,11,11,10,10,10,11,12,11,12,11, + 12,10,11,10,11, 9,10, 9,10, 9,10,10, 9,10,10,11, + 10,11,11,11,11,12,11, 9,10,10,10,10,11,11,11,11, + 11,10,11,11,11,11,10,12,10,12,12,11,12,10,10,11, + 10, 9,11,10,11, 9,10,11,10,10,10,11,11,11,11,12, + 12,10, 9, 9,11,10, 9,12,11,10,12,12,11,11,11,11, + 10,11,11,12,11,10,12, 9,11,10,11,10,10,11,10,11, + 9,10,10,10,11,12,11,11,12,11,10,10,11,11, 9,10, + 10,12,10,11,10,10,10, 9,10,10,10,10, 9,10,10,11, + 11,11,11,12,11,10,10,10,10,11,11,10,11,11, 9,11, + 10,12,10,12,11,10,11,10,10,10,11,10,10,11,11,10, + 11,10,10,10,10,11,11,12,10,10,10,11,10,11,12,11, + 10,11,10,10,11,11,10,12,10, 9,10,10,11,11,11,10, + 12,10,10,11,11,11,10,10,11,10,10,10,11,10,11,10, + 12,11,11,10,10,10,12,10,10,11, 9,10,11,11,11,10, + 10,11,10,10, 9,11,11,12,12,11,12,11,11,11,11,11, + 11, 9,10,11,10,12,10,10,10,10,11,10,10,11,10,10, + 12,10,10,10,10,10, 9,12,10,10,10,10,12, 9,11,10, + 10,11,10,12,12,10,12,12,12,10,10,10,10, 9,10,11, + 10,10,12,10,10,12,11,10,11,10,10,12,11,10,12,10, + 10,11, 9,11,10, 9,10, 9,10, +}; + +static float _vq_quantthresh__8c0_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8c0_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_2 = { + _vq_quantthresh__8c0_s_p9_2, + _vq_quantmap__8c0_s_p9_2, + 21, + 21 +}; + +static static_codebook _8c0_s_p9_2 = { + 2, 441, + _vq_lengthlist__8c0_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8c0_s_p9_2, + NULL, + &_vq_auxt__8c0_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8c0_s_single[] = { + 4, 5,18, 7,10, 6, 7, 8, 9,10, 5, 2,18, 5, 7, 5, + 6, 7, 8,11,17,17,17,17,17,17,17,17,17,17, 7, 4, + 17, 6, 9, 6, 8,10,12,15,11, 7,17, 9, 6, 6, 7, 9, + 11,15, 6, 4,17, 6, 6, 4, 5, 8,11,16, 6, 6,17, 8, + 6, 5, 6, 9,13,16, 8, 9,17,11, 9, 8, 8,11,13,17, + 9,12,17,15,14,13,12,13,14,17,12,15,17,17,17,17, + 17,16,17,17, +}; + +static static_codebook _huff_book__8c0_s_single = { + 2, 100, + _huff_lengthlist__8c0_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c1_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 8, 8,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 8,10, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p1_0 = { + _vq_quantthresh__8c1_s_p1_0, + _vq_quantmap__8c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _8c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__8c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8c1_s_p1_0, + NULL, + &_vq_auxt__8c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p2_0 = { + _vq_quantthresh__8c1_s_p2_0, + _vq_quantmap__8c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _8c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__8c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p2_0, + NULL, + &_vq_auxt__8c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p3_0[] = { + 2, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p3_0 = { + _vq_quantthresh__8c1_s_p3_0, + _vq_quantmap__8c1_s_p3_0, + 5, + 5 +}; + +static static_codebook _8c1_s_p3_0 = { + 4, 625, + _vq_lengthlist__8c1_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p3_0, + NULL, + &_vq_auxt__8c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c1_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p4_0 = { + _vq_quantthresh__8c1_s_p4_0, + _vq_quantmap__8c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _8c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__8c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p4_0, + NULL, + &_vq_auxt__8c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c1_s_p5_0[] = { + 1, 3, 3, 4, 5, 6, 6, 8, 8, 0, 0, 0, 8, 8, 7, 7, + 9, 9, 0, 0, 0, 8, 8, 7, 7, 9, 9, 0, 0, 0, 9,10, + 8, 8, 9, 9, 0, 0, 0,10,10, 8, 8, 9, 9, 0, 0, 0, + 11,10, 8, 8,10,10, 0, 0, 0,11,11, 8, 8,10,10, 0, + 0, 0,12,12, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__8c1_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c1_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p5_0 = { + _vq_quantthresh__8c1_s_p5_0, + _vq_quantmap__8c1_s_p5_0, + 9, + 9 +}; + +static static_codebook _8c1_s_p5_0 = { + 2, 81, + _vq_lengthlist__8c1_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p5_0, + NULL, + &_vq_auxt__8c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8c1_s_p6_0[] = { + 1, 3, 3, 5, 5, 8, 8, 8, 8, 9, 9,10,10,11,11,11, + 11, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,11, + 12,12,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0,10,10, 9, 9,10,10,10,10, + 11,11,12,12,13,13, 0, 0, 0,10,10, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0,11,11, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,11,11,11,12,12,13,12,13,13, 0, 0, 0, 0, + 0, 0, 0,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__8c1_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8c1_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p6_0 = { + _vq_quantthresh__8c1_s_p6_0, + _vq_quantmap__8c1_s_p6_0, + 17, + 17 +}; + +static static_codebook _8c1_s_p6_0 = { + 2, 289, + _vq_lengthlist__8c1_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8c1_s_p6_0, + NULL, + &_vq_auxt__8c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10, 9,10,11,10,10, 6, 9, 9, + 10, 9, 9,11, 9,10, 7,10,10,11,11,11,11,10,10, 6, + 9, 9,10,10,10,11, 9, 9, 6, 9, 9,10,10,10,10, 9, + 9, +}; + +static float _vq_quantthresh__8c1_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8c1_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p7_0 = { + _vq_quantthresh__8c1_s_p7_0, + _vq_quantmap__8c1_s_p7_0, + 3, + 3 +}; + +static static_codebook _8c1_s_p7_0 = { + 4, 81, + _vq_lengthlist__8c1_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8c1_s_p7_0, + NULL, + &_vq_auxt__8c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8c1_s_p7_1[] = { + 2, 3, 3, 5, 5, 7, 7, 7, 7, 7, 7,10,10, 9, 7, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 8, 8, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__8c1_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8c1_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p7_1 = { + _vq_quantthresh__8c1_s_p7_1, + _vq_quantmap__8c1_s_p7_1, + 11, + 11 +}; + +static static_codebook _8c1_s_p7_1 = { + 2, 121, + _vq_lengthlist__8c1_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p7_1, + NULL, + &_vq_auxt__8c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c1_s_p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10, 9,10,11,11,11, 0,13, + 12, 9, 8, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9, 9, + 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10, + 10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,11, + 13,12, 0, 0, 0,14,14,10,10,11,10,11,11,12,12, 0, + 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,10,12,11,13,12, +}; + +static float _vq_quantthresh__8c1_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p8_0 = { + _vq_quantthresh__8c1_s_p8_0, + _vq_quantmap__8c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _8c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__8c1_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8c1_s_p8_0, + NULL, + &_vq_auxt__8c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p8_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__8c1_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p8_1 = { + _vq_quantthresh__8c1_s_p8_1, + _vq_quantmap__8c1_s_p8_1, + 5, + 5 +}; + +static static_codebook _8c1_s_p8_1 = { + 2, 25, + _vq_lengthlist__8c1_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p8_1, + NULL, + &_vq_auxt__8c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c1_s_p9_0[] = { + 1, 3, 3,10,10,10,10,10,10,10,10,10,10, 5, 6, 6, + 10,10,10,10,10,10,10,10,10,10, 6, 7, 8,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__8c1_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__8c1_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_0 = { + _vq_quantthresh__8c1_s_p9_0, + _vq_quantmap__8c1_s_p9_0, + 13, + 13 +}; + +static static_codebook _8c1_s_p9_0 = { + 2, 169, + _vq_lengthlist__8c1_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__8c1_s_p9_0, + NULL, + &_vq_auxt__8c1_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8c1_s_p9_1[] = { + 1, 4, 4, 5, 5, 7, 7, 9, 9,11,11,12,12,13,13, 6, + 5, 5, 6, 6, 9, 9,10,10,12,12,12,13,15,14, 6, 5, + 5, 7, 7, 9, 9,10,10,12,12,12,13,14,13,17, 7, 7, + 8, 8,10,10,11,11,12,13,13,13,13,13,17, 7, 7, 8, + 8,10,10,11,11,13,13,13,13,14,14,17,11,11, 9, 9, + 11,11,12,12,12,13,13,14,15,13,17,12,12, 9, 9,11, + 11,12,12,13,13,13,13,14,16,17,17,17,11,12,12,12, + 13,13,13,14,15,14,15,15,17,17,17,12,12,11,11,13, + 13,14,14,15,14,15,15,17,17,17,15,15,13,13,14,14, + 15,14,15,15,16,15,17,17,17,15,15,13,13,13,14,14, + 15,15,15,15,16,17,17,17,17,16,14,15,14,14,15,14, + 14,15,15,15,17,17,17,17,17,14,14,16,14,15,15,15, + 15,15,15,17,17,17,17,17,17,16,16,15,17,15,15,14, + 17,15,17,16,17,17,17,17,16,15,14,15,15,15,15,15, + 15, +}; + +static float _vq_quantthresh__8c1_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8c1_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_1 = { + _vq_quantthresh__8c1_s_p9_1, + _vq_quantmap__8c1_s_p9_1, + 15, + 15 +}; + +static static_codebook _8c1_s_p9_1 = { + 2, 225, + _vq_lengthlist__8c1_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8c1_s_p9_1, + NULL, + &_vq_auxt__8c1_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8c1_s_p9_2[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9,11,11,12, 7, 7, 7, 7, 8, 8, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,11,11,11, 7, 7, 7, + 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,11, + 11,12, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10, + 10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,11,12,11, 9, 9, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,12,11, + 12,11, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,12,11,12,11,11, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,12,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,12,11,11,12,11,10,10,10,10,10,10,10,10, + 10,10,10,10,11,10,11,11,11,11,11,11,11,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,11,11,12,11,12, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,12,11,12,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,12,11,11,12,11,11,12,10,10, + 11,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,12, + 12,11,12,11,11,12,12,12,11,11,10,10,10,10,10,10, + 10,10,10,11,12,12,11,12,12,11,12,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__8c1_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8c1_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_2 = { + _vq_quantthresh__8c1_s_p9_2, + _vq_quantmap__8c1_s_p9_2, + 21, + 21 +}; + +static static_codebook _8c1_s_p9_2 = { + 2, 441, + _vq_lengthlist__8c1_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8c1_s_p9_2, + NULL, + &_vq_auxt__8c1_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8c1_s_single[] = { + 4, 6,18, 8,11, 8, 8, 9, 9,10, 4, 4,18, 5, 9, 5, + 6, 7, 8,10,18,18,18,18,17,17,17,17,17,17, 7, 5, + 17, 6,11, 6, 7, 8, 9,12,12, 9,17,12, 8, 8, 9,10, + 10,13, 7, 5,17, 6, 8, 4, 5, 6, 8,10, 6, 5,17, 6, + 8, 5, 4, 5, 7, 9, 7, 7,17, 8, 9, 6, 5, 5, 6, 8, + 8, 8,17, 9,11, 8, 6, 6, 6, 7, 9,10,17,12,12,10, + 9, 7, 7, 8, +}; + +static static_codebook _huff_book__8c1_s_single = { + 2, 100, + _huff_lengthlist__8c1_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/sound/OggVorbis/vorbissrc/books/floor/floor_books.h b/sound/OggVorbis/vorbissrc/books/floor/floor_books.h new file mode 100644 index 000000000..fa115d717 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/books/floor/floor_books.h @@ -0,0 +1,1455 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id$ + + ********************************************************************/ + +#include "codebook.h" +static long _huff_lengthlist_line_1024x27_0sub0[] = { + 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 6, + 8, 6, 9, 6, 9, 6, 9, 6,10, 6,10, 6,11, 6,11, 6, + 11, 6,12, 6,12, 7,12, 7,12, 7,12, 7,12, 7,12, 7, + 12, 7,12, 7,12, 7,12, 7,12, 8,12, 8,11, 8,11, 8, + 12, 9,11, 9, 9,10,11, 9,12, 9,12,12,14,13,13,14, + 13,13,13,12,14,16,20,20,21,14,14,15,21,21,21,20, + 21,21,21,21,21,21,21,21,21,21,20,20,20,20,20,20, +}; + +static static_codebook _huff_book_line_1024x27_0sub0 = { + 1, 128, + _huff_lengthlist_line_1024x27_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_1sub0[] = { + 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 4, 6, 5, 6, 5, + 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6,10, 6,10, 6, +}; + +static static_codebook _huff_book_line_1024x27_1sub0 = { + 1, 32, + _huff_lengthlist_line_1024x27_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 5,10, 4,10, 4, 9, 4, 9, 3, 9, 4, 9, 4, 9, 4, + 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 8, 5, 9, 5, 9, 6, + 8, 6, 9, 7,10, 8,10, 9,10,10,10,12,11,13,12,13, + 13,15,13,14,13,14,12,15,13,15,14,15,13,16,14,16, + 14,15,14,14,14,16,15,18,15,18,16,18,18,18,18,18, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,17, +}; + +static static_codebook _huff_book_line_1024x27_1sub1 = { + 1, 128, + _huff_lengthlist_line_1024x27_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_2sub0[] = { + 1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 6, 7, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9,10,10, +}; + +static static_codebook _huff_book_line_1024x27_2sub0 = { + 1, 32, + _huff_lengthlist_line_1024x27_2sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_2sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 4, 3, 4, 4, 5, 4, 5, 5, 5, 5, 6, 5, 6, 6, + 7, 6, 7, 7, 7, 7, 7, 7, 8, 9, 8, 9, 8,10, 8,11, + 8,12, 9,13, 9,14, 9,14, 8,12, 8,14, 9,14, 8,12, + 8,11, 8,11, 8,11, 9,11,10,11,10,12,10,12,11,12, + 12,12,12,12,11,12,11,13,11,13,12,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,13, +}; + +static static_codebook _huff_book_line_1024x27_2sub1 = { + 1, 128, + _huff_lengthlist_line_1024x27_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub1[] = { + 0, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 5, 4, + 5, 5, +}; + +static static_codebook _huff_book_line_1024x27_3sub1 = { + 1, 18, + _huff_lengthlist_line_1024x27_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 3, 4, 4, 4, 5, 4, 6, 5, 6, 5, 7, + 5, 9, 5,10, 6,11, 6,12, 7,13, 8,15, 8,15, 9,15, + 9,15, +}; + +static static_codebook _huff_book_line_1024x27_3sub2 = { + 1, 50, + _huff_lengthlist_line_1024x27_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 9, 2, 9, 2, 9, 4, 9, 6, 9, 7, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static static_codebook _huff_book_line_1024x27_3sub3 = { + 1, 128, + _huff_lengthlist_line_1024x27_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub1[] = { + 0, 4, 5, 4, 5, 4, 6, 3, 6, 3, 5, 3, 5, 3, 6, 4, + 6, 4, +}; + +static static_codebook _huff_book_line_1024x27_4sub1 = { + 1, 18, + _huff_lengthlist_line_1024x27_4sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 6, 7, 7, + 7, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9,10,10,11, + 10,11, +}; + +static static_codebook _huff_book_line_1024x27_4sub2 = { + 1, 50, + _huff_lengthlist_line_1024x27_4sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 6, 4, 6, 4, 5, 5, 7, 4, 8, 5, 9, + 4, 9, 5, 9, 5, 9, 6, 9, 5, 9, 7, 9, 7, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static static_codebook _huff_book_line_1024x27_4sub3 = { + 1, 128, + _huff_lengthlist_line_1024x27_4sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class1[] = { + 2, 9, 8,14, 7,13,11,14, 1, 5, 3, 7, 4,10, 7,12, +}; + +static static_codebook _huff_book_line_1024x27_class1 = { + 1, 16, + _huff_lengthlist_line_1024x27_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class2[] = { + 1, 3, 2, 5, 4, 7, 6, 7, +}; + +static static_codebook _huff_book_line_1024x27_class2 = { + 1, 8, + _huff_lengthlist_line_1024x27_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class3[] = { + 1, 5, 6,19, 5, 8,10,19, 9,10,15,19,19,19,19,19, + 4, 7, 9,19, 6, 7,10,19,11,11,15,19,19,19,19,19, + 8,11,13,19, 8,11,14,19,13,13,17,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 3, 7, 9,19, 6, 8,11,19,11,11,15,19,19,19,19,19, + 5, 7,11,19, 6, 7,11,19,11,10,14,19,19,19,19,19, + 8,11,15,19, 8,10,14,19,13,13,16,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 6, 9,11,19, 8,10,12,19,15,14,17,19,19,19,19,19, + 5, 8,11,19, 7, 9,12,19,14,11,16,19,19,19,19,19, + 9,10,18,19, 9,10,15,19,14,16,19,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 16,17,19,19,16,17,17,19,19,19,19,19,19,19,19,19, + 12,14,16,19,12,12,16,19,19,19,19,19,19,19,19,19, + 18,18,19,19,17,16,19,19,19,19,19,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,18, +}; + +static static_codebook _huff_book_line_1024x27_class3 = { + 1, 256, + _huff_lengthlist_line_1024x27_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class4[] = { + 1, 4, 8,12, 4, 6, 8,21, 9, 8,10,21,20,16,18,20, + 2, 6, 8,20, 7, 6, 9,19,11, 9,10,20,17,15,16,20, + 5, 8,11,19, 8, 8,10,15,12,10,12,15,20,20,15,20, + 17,20,20,20,15,20,20,19,20,20,16,19,20,20,20,20, +}; + +static static_codebook _huff_book_line_1024x27_class4 = { + 1, 64, + _huff_lengthlist_line_1024x27_class4, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_0sub0[] = { + 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, + 8, 7, 8, 7, 8, 7, 8, 7, 9, 7, 9, 7, 9, 8,10, 8, + 10, 8,10, 8,10, 8,10, 9,11, 9,11, 9,10, 9,10,10, + 11,10,11,11,11,11,12,12,13,14,13,14,16,16,16,16, + 16,16,15,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,15,15,15, +}; + +static static_codebook _huff_book_line_128x11_0sub0 = { + 1, 128, + _huff_lengthlist_line_128x11_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_1sub0[] = { + 2, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 5, 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6, +}; + +static static_codebook _huff_book_line_128x11_1sub0 = { + 1, 32, + _huff_lengthlist_line_128x11_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 3, 6, 3, 7, 3, 7, 4, 8, 4, 8, 4, 8, 4, 9, 4, + 10, 5, 9, 5,10, 5,10, 5,10, 5,12, 6,12, 6,10, 6, + 10, 7,10, 8,10, 8,10, 9,11, 9,12,11,10,11,11,13, + 12,12,12,13,10,13,10,13,10,13,10,13,11,13,10,13, + 10,13,10,13,10,13,10,13,11,12,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +}; + +static static_codebook _huff_book_line_128x11_1sub1 = { + 1, 128, + _huff_lengthlist_line_128x11_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub1[] = { + 0, 4, 5, 4, 5, 4, 5, 3, 4, 3, 4, 4, 4, 4, 4, 5, + 5, 5, +}; + +static static_codebook _huff_book_line_128x11_2sub1 = { + 1, 18, + _huff_lengthlist_line_128x11_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 3, 4, 3, 5, 4, 5, 5, 6, 5, 6, 6, 6, + 6, 8, 6,10, 7,10, 8,10, 8,10,10,10,10,10,10,10, + 10,10, +}; + +static static_codebook _huff_book_line_128x11_2sub2 = { + 1, 50, + _huff_lengthlist_line_128x11_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static static_codebook _huff_book_line_128x11_2sub3 = { + 1, 128, + _huff_lengthlist_line_128x11_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, + 5, 4, +}; + +static static_codebook _huff_book_line_128x11_3sub1 = { + 1, 18, + _huff_lengthlist_line_128x11_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 3, 5, 3, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4, + 8, 4, 9, 4, 9, 4, 9, 5,10, 5,11, 5,12, 6,13, 6, + 13, 7, +}; + +static static_codebook _huff_book_line_128x11_3sub2 = { + 1, 50, + _huff_lengthlist_line_128x11_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 2, 6, 2, 7, 3, 8, 4, 7, 6, 9, 7, 9, 7, + 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static static_codebook _huff_book_line_128x11_3sub3 = { + 1, 128, + _huff_lengthlist_line_128x11_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class1[] = { + 1, 6, 3, 7, 2, 5, 4, 7, +}; + +static static_codebook _huff_book_line_128x11_class1 = { + 1, 8, + _huff_lengthlist_line_128x11_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class2[] = { + 1, 5,11,14, 4,11,13,14,10,14,13,14,14,14,13,13, + 2, 6,11,13, 5,11,12,13,11,12,13,13,13,13,13,13, + 4, 8,12,13, 5, 9,11,13,12,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +}; + +static static_codebook _huff_book_line_128x11_class2 = { + 1, 64, + _huff_lengthlist_line_128x11_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class3[] = { + 6, 7,11,16, 6, 7,10,16,11, 9,13,15,15,15,15,15, + 4, 4, 7,14, 4, 4, 6,14, 8, 6, 8,15,15,15,15,15, + 4, 4, 6,15, 3, 2, 4,13, 6, 5, 6,14,15,12,11,14, + 11,11,13,15, 9, 8,10,15,11,10,11,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_128x11_class3 = { + 1, 64, + _huff_lengthlist_line_128x11_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_0sub0[] = { + 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 6, 7, 6, + 7, 6, 8, 6, 8, 6, 8, 6, 8, 6, 8, 6, 8, 7, 9, 7, + 9, 7, 9, 7, 9, 7, 9, 7, 9, 7,10, 7,10, 8,10, 8, + 11, 8,11, 8,11, 8,12, 8,12, 8,12, 8,12, 9,12, 9, + 12, 9,12, 9,13, 9,13,10,13,10,13,11,14,12,14,13, + 14,14,16,15,17,17,19,18,19,19,19,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,18,18,18,18,18, +}; + +static static_codebook _huff_book_line_128x17_0sub0 = { + 1, 128, + _huff_lengthlist_line_128x17_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_1sub0[] = { + 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 7, 6, 7, 6, 8, 6, 8, 7, 9, 7, 9, 8, +}; + +static static_codebook _huff_book_line_128x17_1sub0 = { + 1, 32, + _huff_lengthlist_line_128x17_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 2, 5, 3, 5, 3, 6, 4, 6, 4, 7, 4, 8, 5, 8, 5, + 8, 6, 9, 6, 9, 7, 9, 8,10, 8,10, 9,10,10,10,10, + 10,12,10,14,11,15,12,15,11,15,11,15,11,14,11,15, + 11,14,11,13,10,12,10,14,10,14,11,13,10,12,11,15, + 12,15,13,15,12,13,14,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,14,14,14, +}; + +static static_codebook _huff_book_line_128x17_1sub1 = { + 1, 128, + _huff_lengthlist_line_128x17_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub1[] = { + 0, 4, 5, 4, 7, 3, 8, 3, 9, 3,10, 2,12, 3,12, 4, + 11, 6, +}; + +static static_codebook _huff_book_line_128x17_2sub1 = { + 1, 18, + _huff_lengthlist_line_128x17_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 8, 2, 9, 3, 9, 7, 9, 7, 9, 7, 8, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, +}; + +static static_codebook _huff_book_line_128x17_2sub2 = { + 1, 50, + _huff_lengthlist_line_128x17_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static static_codebook _huff_book_line_128x17_2sub3 = { + 1, 128, + _huff_lengthlist_line_128x17_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub1[] = { + 0, 4, 4, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 6, 4, + 6, 4, +}; + +static static_codebook _huff_book_line_128x17_3sub1 = { + 1, 18, + _huff_lengthlist_line_128x17_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 3, 6, 3, 6, 3, 7, 4, 8, 4, 8, 4, 9, 4, + 9, 4,10, 4,10, 5,11, 5,11, 5,12, 5,12, 6,12, 6, + 12, 7, +}; + +static static_codebook _huff_book_line_128x17_3sub2 = { + 1, 50, + _huff_lengthlist_line_128x17_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 7, 3, 6, 3, 6, 4, 6, 5, 6, 8, 7,10, + 7,11, 7,11, 8,11, 9,11, 7,11, 8,11, 8,11,10,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +}; + +static static_codebook _huff_book_line_128x17_3sub3 = { + 1, 128, + _huff_lengthlist_line_128x17_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class1[] = { + 1, 3, 4, 7, 2, 6, 5, 7, +}; + +static static_codebook _huff_book_line_128x17_class1 = { + 1, 8, + _huff_lengthlist_line_128x17_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class2[] = { + 1, 2, 7,14, 4, 9,13,14, 8,14,14,14,14,14,14,14, + 3, 5,10,14, 8,14,14,14,11,14,14,14,14,14,14,14, + 7,10,14,14,12,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,13, +}; + +static static_codebook _huff_book_line_128x17_class2 = { + 1, 64, + _huff_lengthlist_line_128x17_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class3[] = { + 2, 6,11,19, 5, 9,12,19,10,11,13,19,19,19,19,19, + 2, 5, 8,19, 4, 6, 8,19, 8, 8, 9,19,19,16,19,19, + 3, 6, 8,19, 3, 5, 7,18, 8, 8, 9,16,16,11,16,19, + 14,14,14,19,10,10,11,19,16,12,14,19,19,19,19,19, +}; + +static static_codebook _huff_book_line_128x17_class3 = { + 1, 64, + _huff_lengthlist_line_128x17_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub0[] = { + 2, 2, 2, 2, +}; + +static static_codebook _huff_book_line_128x4_0sub0 = { + 1, 4, + _huff_lengthlist_line_128x4_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub1[] = { + 0, 0, 0, 0, 3, 2, 3, 2, 3, 3, +}; + +static static_codebook _huff_book_line_128x4_0sub1 = { + 1, 10, + _huff_lengthlist_line_128x4_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 4, 4, 4, + 4, 3, 4, 4, 5, 3, 6, 4, 6, +}; + +static static_codebook _huff_book_line_128x4_0sub2 = { + 1, 25, + _huff_lengthlist_line_128x4_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 2, 6, 3, 6, 3, + 7, 4, 7, 5, 7, 5, 7, 6, 8, 8, 9,10,10,16,10,16, + 10,14,10,14,11,15,15,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_128x4_0sub3 = { + 1, 64, + _huff_lengthlist_line_128x4_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_class0[] = { + 8, 8, 8,14, 7, 7, 8,13, 7, 6, 7,11,11,11,10,13, + 9, 9,10,16, 8, 8, 9,12, 7, 7, 7,11,11,11,10,12, + 11,11,11,14,10,10,10,14, 9, 8, 9,12,13,14,12,14, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 8, 7, 8,11, 7, 7, 7,11, 6, 6, 6,10,10,10,10,14, + 8, 8, 8,12, 7, 7, 8,11, 6, 7, 7,10,10,10,10,13, + 10,10,10,12,10, 9, 9,12, 9, 9, 9,12,12,13,12,14, + 16,16,16,16,16,14,16,16,14,14,16,16,16,16,16,16, + 7, 6, 5, 7, 6, 6, 5, 6, 6, 5, 5, 5, 9,10, 9,10, + 8, 7, 6, 7, 7, 6, 5, 6, 6, 6, 5, 6,10,10, 9, 9, + 10, 9, 7, 8, 9, 8, 7, 7, 8, 7, 6, 7,11,11,10, 9, + 16,13,14,16,14,14,13,15,16,14,12,13,16,16,14,16, + 9, 8, 7, 8, 8, 8, 7, 8, 8, 7, 6, 7,10,10, 9,12, + 9, 9, 8, 8, 9, 8, 7, 8, 8, 8, 6, 7,10,10, 9,12, + 11,10, 9,10,10, 9, 7, 9, 9, 8, 6, 9,12,11,10,13, + 12,16,16,16,12,13,12,16,15,12,11,14,16,16,16,16, +}; + +static static_codebook _huff_book_line_128x4_class0 = { + 1, 256, + _huff_lengthlist_line_128x4_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub1[] = { + 0, 3, 3, 3, 3, 3, 3, 3, 3, +}; + +static static_codebook _huff_book_line_128x7_0sub1 = { + 1, 9, + _huff_lengthlist_line_128x7_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 3, 4, 4, 4, + 5, 4, 5, 4, 5, 4, 6, 4, 6, +}; + +static static_codebook _huff_book_line_128x7_0sub2 = { + 1, 25, + _huff_lengthlist_line_128x7_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 3, 5, 3, 6, 4, + 6, 4, 6, 4, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 5, 5, + 6, 7, 8,10,12,12,12,12,12,12,12,12,12,12,12,12, +}; + +static static_codebook _huff_book_line_128x7_0sub3 = { + 1, 64, + _huff_lengthlist_line_128x7_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub1[] = { + 0, 3, 3, 3, 3, 2, 4, 3, 4, +}; + +static static_codebook _huff_book_line_128x7_1sub1 = { + 1, 9, + _huff_lengthlist_line_128x7_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 3, 6, 3, 7, 3, + 8, 3, 9, 3,10, 3,11, 4,11, +}; + +static static_codebook _huff_book_line_128x7_1sub2 = { + 1, 25, + _huff_lengthlist_line_128x7_1sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,12, 2, 9, 3,10, 4, + 12, 5,12, 6,12,10,12,11,12,12,12,12,12,12,12,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +}; + +static static_codebook _huff_book_line_128x7_1sub3 = { + 1, 64, + _huff_lengthlist_line_128x7_1sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_class0[] = { + 10, 7, 8,14,10, 7, 7,12,11, 8, 8,13,16,16,16,16, + 8, 5, 5,10, 7, 4, 4, 8, 8, 5, 5, 9,16,16,16,16, + 7, 4, 5, 7, 6, 3, 3, 6, 8, 5, 5, 7,16,14,13,16, + 9, 7, 7,10, 7, 4, 4, 7, 9, 6, 5, 6,15,13,11,14, +}; + +static static_codebook _huff_book_line_128x7_class0 = { + 1, 64, + _huff_lengthlist_line_128x7_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_class1[] = { + 8,12,16,16,10,14,16,16,12,15,16,16,16,16,16,16, + 7,11,15,16, 7,11,16,16,10,12,16,16,16,16,16,16, + 9,15,16,16, 9,12,16,16,11,15,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 6,10,13,16, 7,10,15,16, 9,11,16,16,16,16,16,16, + 4, 8,13,16, 5, 8,15,16, 7, 9,15,16,16,16,16,16, + 6,12,16,16, 6,10,15,16, 9,10,14,16,16,16,16,16, + 14,16,16,16,12,14,16,16,15,16,16,16,16,16,16,16, + 4, 9,11,16, 5, 9,13,16, 7, 9,15,16,16,16,16,16, + 2, 7,11,16, 3, 6,11,16, 5, 7,12,16,16,16,16,16, + 4, 9,14,16, 4, 7,13,16, 6, 8,13,16,16,16,16,16, + 11,14,16,16,10,16,14,16,11,16,16,16,16,16,16,16, + 7,13,16,16, 9,13,15,16,11,13,16,16,16,16,16,16, + 5,10,14,16, 6,10,15,16, 9,10,16,16,16,16,16,16, + 7,13,16,16, 6,10,16,16, 9,12,16,16,16,16,16,16, + 11,16,16,16,10,16,16,16,13,16,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_128x7_class1 = { + 1, 256, + _huff_lengthlist_line_128x7_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub0[] = { + 1, 3, 2, 3, +}; + +static static_codebook _huff_book_line_256x4_0sub0 = { + 1, 4, + _huff_lengthlist_line_256x4_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub1[] = { + 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, +}; + +static static_codebook _huff_book_line_256x4_0sub1 = { + 1, 10, + _huff_lengthlist_line_256x4_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 3, 4, + 4, 4, 5, 4, 5, 5, 6, 4, 6, +}; + +static static_codebook _huff_book_line_256x4_0sub2 = { + 1, 25, + _huff_lengthlist_line_256x4_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 4, 3, 4, 4, + 5, 4, 5, 5, 6, 5, 7, 6, 8, 7, 9, 8, 9, 9,10,12, + 15,15,15,15,15,15,15,15,14,14,14,14,14,14,14,14, +}; + +static static_codebook _huff_book_line_256x4_0sub3 = { + 1, 64, + _huff_lengthlist_line_256x4_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_class0[] = { + 4, 5, 6,11, 5, 5, 6,10, 7, 6, 5, 6,14,13,10,10, + 6, 6, 6,10, 6, 6, 6,10, 7, 7, 7, 9, 9,10, 9,12, + 9, 8, 8,11, 8, 8, 8,10, 8, 8, 9,11, 8, 9, 9,13, + 18,18,18,18,16,17,18,18,12,13,14,18,14,14,10,12, + 5, 5, 6,12, 6, 5, 6,10, 7, 7, 6, 7,13,12, 9,12, + 6, 6, 6,11, 6, 6, 6, 9, 7, 7, 7,10,10,10, 9,12, + 9, 8, 8,12, 8, 8, 7,11, 8, 8, 8,11, 9, 9, 8,10, + 18,18,17,18,18,18,15,18,16,14,12,18,14,12,10,11, + 8, 7, 7,12, 8, 7, 7,10, 8, 7, 6, 6,11,10, 9,10, + 8, 8, 7,11, 8, 7, 7, 9, 8, 8, 7, 9,10,10, 9, 9, + 10, 9, 8,12, 9, 9, 8,11,10, 9, 8, 9, 8, 8, 7, 9, + 18,18,18,18,18,18,18,18,17,16,14,18,13,12,11,13, + 12,12,13,16,11,10,10,16,12,12, 9, 7,15,12,11,11, + 14,14,14,14,12,11,11,18,14,12,10,11,18,13,11,13, + 18,18,18,17,17,16,15,17,18,15,16,18,16,12,11,11, + 18,18,18,18,18,18,18,18,18,18,17,18,18,13,12,15, +}; + +static static_codebook _huff_book_line_256x4_class0 = { + 1, 256, + _huff_lengthlist_line_256x4_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_0sub1[] = { + 0, 2, 3, 3, 3, 3, 4, 3, 4, +}; + +static static_codebook _huff_book_line_256x7_0sub1 = { + 1, 9, + _huff_lengthlist_line_256x7_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 4, 3, 5, 3, + 6, 3, 6, 4, 6, 4, 7, 5, 7, +}; + +static static_codebook _huff_book_line_256x7_0sub2 = { + 1, 25, + _huff_lengthlist_line_256x7_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 3, 5, 3, + 6, 3, 6, 4, 7, 6, 7, 8, 7, 9, 8, 9, 9, 9,10, 9, + 11,13,11,13,10,10,13,13,13,13,13,13,12,12,12,12, +}; + +static static_codebook _huff_book_line_256x7_0sub3 = { + 1, 64, + _huff_lengthlist_line_256x7_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub1[] = { + 0, 3, 3, 3, 3, 2, 4, 3, 4, +}; + +static static_codebook _huff_book_line_256x7_1sub1 = { + 1, 9, + _huff_lengthlist_line_256x7_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 4, 3, 4, 4, + 5, 4, 6, 5, 6, 7, 6, 8, 8, +}; + +static static_codebook _huff_book_line_256x7_1sub2 = { + 1, 25, + _huff_lengthlist_line_256x7_1sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 4, 3, 6, 3, 7, + 3, 8, 5, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, +}; + +static static_codebook _huff_book_line_256x7_1sub3 = { + 1, 64, + _huff_lengthlist_line_256x7_1sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_class0[] = { + 7, 5, 5, 9, 9, 6, 6, 9,12, 8, 7, 8,11, 8, 9,15, + 6, 3, 3, 7, 7, 4, 3, 6, 9, 6, 5, 6, 8, 6, 8,15, + 8, 5, 5, 9, 8, 5, 4, 6,10, 7, 5, 5,11, 8, 7,15, + 14,15,13,13,13,13, 8,11,15,10, 7, 6,11, 9,10,15, +}; + +static static_codebook _huff_book_line_256x7_class0 = { + 1, 64, + _huff_lengthlist_line_256x7_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_class1[] = { + 5, 6, 8,15, 6, 9,10,15,10,11,12,15,15,15,15,15, + 4, 6, 7,15, 6, 7, 8,15, 9, 8, 9,15,15,15,15,15, + 6, 8, 9,15, 7, 7, 8,15,10, 9,10,15,15,15,15,15, + 15,13,15,15,15,10,11,15,15,13,13,15,15,15,15,15, + 4, 6, 7,15, 6, 8, 9,15,10,10,12,15,15,15,15,15, + 2, 5, 6,15, 5, 6, 7,15, 8, 6, 7,15,15,15,15,15, + 5, 6, 8,15, 5, 6, 7,15, 9, 6, 7,15,15,15,15,15, + 14,12,13,15,12,10,11,15,15,15,15,15,15,15,15,15, + 7, 8, 9,15, 9,10,10,15,15,14,14,15,15,15,15,15, + 5, 6, 7,15, 7, 8, 9,15,12, 9,10,15,15,15,15,15, + 7, 7, 9,15, 7, 7, 8,15,12, 8, 9,15,15,15,15,15, + 13,13,14,15,12,11,12,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,12,13,15,15,12,13,15,15,14,15,15,15,15,15,15, + 15,15,15,15,15,15,13,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_256x7_class1 = { + 1, 256, + _huff_lengthlist_line_256x7_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_0sub0[] = { + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 5, 6, 6, 6, 6, 5, 6, 6, 7, 6, 7, 6, 7, 6, + 7, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 9, 7, 9, 7, + 9, 7, 9, 8, 9, 8,10, 8,10, 8,10, 7,10, 6,10, 8, + 10, 8,11, 7,10, 7,11, 8,11,11,12,12,11,11,12,11, + 13,11,13,11,13,12,15,12,13,13,14,14,14,14,14,15, + 15,15,16,14,17,19,19,18,18,18,18,18,18,18,18,18, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +}; + +static static_codebook _huff_book_line_512x17_0sub0 = { + 1, 128, + _huff_lengthlist_line_512x17_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_1sub0[] = { + 2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 8, 7, +}; + +static static_codebook _huff_book_line_512x17_1sub0 = { + 1, 32, + _huff_lengthlist_line_512x17_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 3, 5, 3, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5, + 6, 5, 7, 5, 8, 6, 8, 6, 8, 6, 8, 6, 8, 7, 9, 7, + 9, 7,11, 9,11,11,12,11,14,12,14,16,14,16,13,16, + 14,16,12,15,13,16,14,16,13,14,12,15,13,15,13,13, + 13,15,12,14,14,15,13,15,12,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_512x17_1sub1 = { + 1, 128, + _huff_lengthlist_line_512x17_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub1[] = { + 0, 4, 5, 4, 4, 4, 5, 4, 4, 4, 5, 4, 5, 4, 5, 3, + 5, 3, +}; + +static static_codebook _huff_book_line_512x17_2sub1 = { + 1, 18, + _huff_lengthlist_line_512x17_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5, + 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 7, 8, 7, 9, 7, + 9, 8, +}; + +static static_codebook _huff_book_line_512x17_2sub2 = { + 1, 50, + _huff_lengthlist_line_512x17_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 3, 4, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8,11, 8, 9, 9, 9,10,11,11,11, 9,10,10,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, +}; + +static static_codebook _huff_book_line_512x17_2sub3 = { + 1, 128, + _huff_lengthlist_line_512x17_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 5, 4, 5, + 5, 5, +}; + +static static_codebook _huff_book_line_512x17_3sub1 = { + 1, 18, + _huff_lengthlist_line_512x17_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 3, 4, 3, 5, 4, 6, 4, 6, 5, 7, 6, 7, + 6, 8, 6, 8, 7, 9, 8,10, 8,12, 9,13,10,15,10,15, + 11,14, +}; + +static static_codebook _huff_book_line_512x17_3sub2 = { + 1, 50, + _huff_lengthlist_line_512x17_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 8, 4, 8, 4, 8, 4, 8, 5, 8, 5, 8, 6, 8, + 4, 8, 4, 8, 5, 8, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +}; + +static static_codebook _huff_book_line_512x17_3sub3 = { + 1, 128, + _huff_lengthlist_line_512x17_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class1[] = { + 1, 2, 3, 6, 5, 4, 7, 7, +}; + +static static_codebook _huff_book_line_512x17_class1 = { + 1, 8, + _huff_lengthlist_line_512x17_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class2[] = { + 3, 3, 3,14, 5, 4, 4,11, 8, 6, 6,10,17,12,11,17, + 6, 5, 5,15, 5, 3, 4,11, 8, 5, 5, 8,16, 9,10,14, + 10, 8, 9,17, 8, 6, 6,13,10, 7, 7,10,16,11,13,14, + 17,17,17,17,17,16,16,16,16,15,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_512x17_class2 = { + 1, 64, + _huff_lengthlist_line_512x17_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class3[] = { + 2, 4, 6,17, 4, 5, 7,17, 8, 7,10,17,17,17,17,17, + 3, 4, 6,15, 3, 3, 6,15, 7, 6, 9,17,17,17,17,17, + 6, 8,10,17, 6, 6, 8,16, 9, 8,10,17,17,15,16,17, + 17,17,17,17,12,15,15,16,12,15,15,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_512x17_class3 = { + 1, 64, + _huff_lengthlist_line_512x17_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/sound/OggVorbis/vorbissrc/books/uncoupled/res_books_uncoupled.h b/sound/OggVorbis/vorbissrc/books/uncoupled/res_books_uncoupled.h new file mode 100644 index 000000000..3e2a59da7 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/books/uncoupled/res_books_uncoupled.h @@ -0,0 +1,10907 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id$ + + ********************************************************************/ + +#include "codebook.h" +static long _vq_quantlist__16u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 8, 5, 8, 8, 8,10,10, 8, + 10,11, 5, 8, 8, 8,10,10, 8,10,10, 4, 9, 9, 9,12, + 11, 8,11,11, 8,12,11,10,12,14,10,13,13, 7,11,11, + 10,14,12,11,14,14, 4, 9, 9, 8,11,11, 9,11,12, 7, + 11,11,10,13,14,10,12,14, 8,11,12,10,14,14,10,13, + 12, +}; + +static float _vq_quantthresh__16u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p1_0 = { + _vq_quantthresh__16u0__p1_0, + _vq_quantmap__16u0__p1_0, + 3, + 3 +}; + +static static_codebook _16u0__p1_0 = { + 4, 81, + _vq_lengthlist__16u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u0__p1_0, + NULL, + &_vq_auxt__16u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 9, 7, + 8, 9, 5, 7, 7, 7, 9, 8, 7, 9, 7, 4, 7, 7, 7, 9, + 9, 7, 8, 8, 6, 9, 8, 7, 8,11, 9,11,10, 6, 8, 9, + 8,11, 8, 9,10,11, 4, 7, 7, 7, 8, 8, 7, 9, 9, 6, + 9, 8, 9,11,10, 8, 8,11, 6, 8, 9, 9,10,11, 8,11, + 8, +}; + +static float _vq_quantthresh__16u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p2_0 = { + _vq_quantthresh__16u0__p2_0, + _vq_quantmap__16u0__p2_0, + 3, + 3 +}; + +static static_codebook _16u0__p2_0 = { + 4, 81, + _vq_lengthlist__16u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u0__p2_0, + NULL, + &_vq_auxt__16u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 8, 8, 6, 7, 8, 8, 8, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 9, 8,10,10, 8,10, + 10,11,11, 8,10,10,11,11,10,11,10,13,12, 9,11,10, + 13,13, 6, 8, 9,10,10, 8,10,10,11,11, 8,10,10,11, + 11, 9,10,11,13,12,10,10,11,12,12, 8,11,11,14,13, + 10,12,11,15,13, 9,12,11,15,14,12,14,13,16,14,12, + 13,13,17,14, 8,11,11,13,14, 9,11,12,14,15,10,11, + 12,13,15,11,13,13,14,16,12,13,14,14,16, 5, 9, 9, + 11,11, 9,11,11,12,12, 8,11,11,12,12,11,12,12,15, + 14,10,12,12,15,15, 8,11,11,13,12,10,12,12,13,13, + 10,12,12,14,13,12,12,13,14,15,11,13,13,17,16, 7, + 11,11,13,13,10,12,12,14,13,10,12,12,13,14,12,13, + 12,15,14,11,13,13,15,14, 9,12,12,16,15,11,13,13, + 17,16,10,13,13,16,16,13,14,15,15,16,13,15,14,19, + 17, 9,12,12,14,16,11,13,13,15,16,10,13,13,17,16, + 13,14,13,17,15,12,15,15,16,17, 5, 9, 9,11,11, 8, + 11,11,13,12, 9,11,11,12,12,10,12,12,14,15,11,12, + 12,14,14, 7,11,10,13,12,10,12,12,14,13,10,11,12, + 13,13,11,13,13,15,16,12,12,13,15,15, 7,11,11,13, + 13,10,13,13,14,14,10,12,12,13,13,11,13,13,16,15, + 12,13,13,15,14, 9,12,12,15,15,10,13,13,17,16,11, + 12,13,15,15,12,15,14,18,18,13,14,14,16,17, 9,12, + 12,15,16,10,13,13,15,16,11,13,13,15,16,13,15,15, + 17,17,13,15,14,16,15, 7,11,11,15,16,10,13,12,16, + 17,10,12,13,15,17,15,16,16,18,17,13,15,15,17,18, + 8,12,12,16,16,11,13,14,17,18,11,13,13,18,16,15, + 17,16,17,19,14,15,15,17,16, 8,12,12,16,15,11,14, + 13,18,17,11,13,14,18,17,15,16,16,18,17,13,16,16, + 18,18,11,15,14,18,17,13,14,15,18, 0,12,15,15, 0, + 17,17,16,17,17,18,14,16,18,18, 0,11,14,14,17, 0, + 12,15,14,17,19,12,15,14,18, 0,15,18,16, 0,17,14, + 18,16,18, 0, 7,11,11,16,15,10,12,12,18,16,10,13, + 13,16,15,13,15,14,17,17,14,16,16,19,18, 8,12,12, + 16,16,11,13,13,18,16,11,13,14,17,16,14,15,15,19, + 18,15,16,16, 0,19, 8,12,12,16,17,11,13,13,17,17, + 11,14,13,17,17,13,15,15,17,19,15,17,17,19, 0,11, + 14,15,19,17,12,15,16,18,18,12,14,15,19,17,14,16, + 17, 0,18,16,16,19,17, 0,11,14,14,18,19,12,15,14, + 17,17,13,16,14,17,16,14,17,16,18,18,15,18,15, 0, + 18, +}; + +static float _vq_quantthresh__16u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p3_0 = { + _vq_quantthresh__16u0__p3_0, + _vq_quantmap__16u0__p3_0, + 5, + 5 +}; + +static static_codebook _16u0__p3_0 = { + 4, 625, + _vq_lengthlist__16u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p3_0, + NULL, + &_vq_auxt__16u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p4_0[] = { + 3, 5, 5, 8, 8, 6, 6, 6, 9, 9, 6, 6, 6, 9, 9, 9, + 10, 9,11,11, 9, 9, 9,11,11, 6, 7, 7,10,10, 7, 7, + 8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10, + 11,12, 6, 7, 7,10,10, 7, 8, 7,10,10, 7, 8, 7,10, + 10,10,11,10,12,11,10,10,10,13,10, 9,10,10,12,12, + 10,11,10,14,12, 9,11,11,13,13,11,12,13,13,13,11, + 12,12,15,13, 9,10,10,12,13, 9,11,10,12,13,10,10, + 11,12,13,11,12,12,12,13,11,12,12,13,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12, + 13,10,10,11,12,12, 6, 8, 8,11,10, 7, 8, 9,10,12, + 8, 9, 9,11,11,11,10,11,11,12,10,11,11,13,12, 7, + 8, 8,10,11, 8, 9, 8,11,10, 8, 9, 9,11,11,10,12, + 10,13,11,10,11,11,13,13,10,11,10,14,13,10,10,11, + 13,13,10,12,11,14,13,12,11,13,12,13,13,12,13,14, + 14,10,11,11,13,13,10,11,10,12,13,10,12,12,12,14, + 12,12,12,14,12,12,13,12,17,15, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,11,10,10,10,11,12,12,10,11, + 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,11,11,11,12,12,10,10,11,12,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,12,12,13,13, + 11,11,10,13,11, 9,11,10,14,13,11,11,11,15,13,10, + 10,11,13,13,12,13,13,14,14,12,11,12,12,13,10,11, + 11,12,13,10,11,12,13,13,10,11,10,13,12,12,12,13, + 14, 0,12,13,11,13,11, 8,10,10,13,13,10,11,11,14, + 13,10,11,11,13,12,13,14,14,14,15,12,12,12,15,14, + 9,11,10,13,12,10,10,11,13,14,11,11,11,15,12,13, + 12,14,15,16,13,13,13,14,13, 9,11,11,12,12,10,12, + 11,13,13,10,11,11,13,14,13,13,13,15,15,13,13,14, + 17,15,11,12,12,14,14,10,11,12,13,15,12,13,13, 0, + 15,13,11,14,12,16,14,16,14, 0,15,11,12,12,14,16, + 11,13,12,16,15,12,13,13,14,15,12,14,12,15,13,15, + 14,14,16,16, 8,10,10,13,13,10,11,10,13,14,10,11, + 11,13,13,13,13,12,14,14,14,13,13,16,17, 9,10,10, + 12,14,10,12,11,14,13,10,11,12,13,14,12,12,12,15, + 15,13,13,13,14,14, 9,10,10,13,13,10,11,12,12,14, + 10,11,10,13,13,13,13,13,14,16,13,13,13,14,14,11, + 12,13,15,13,12,14,13,14,16,12,12,13,13,14,13,14, + 14,17,15,13,12,17,13,16,11,12,13,14,15,12,13,14, + 14,17,11,12,11,14,14,13,16,14,16, 0,14,15,11,15, + 11, +}; + +static float _vq_quantthresh__16u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p4_0 = { + _vq_quantthresh__16u0__p4_0, + _vq_quantmap__16u0__p4_0, + 5, + 5 +}; + +static static_codebook _16u0__p4_0 = { + 4, 625, + _vq_lengthlist__16u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p4_0, + NULL, + &_vq_auxt__16u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u0__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9, + 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9, 9,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__16u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p5_0 = { + _vq_quantthresh__16u0__p5_0, + _vq_quantmap__16u0__p5_0, + 9, + 9 +}; + +static static_codebook _16u0__p5_0 = { + 2, 81, + _vq_lengthlist__16u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u0__p5_0, + NULL, + &_vq_auxt__16u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u0__p6_0[] = { + 1, 4, 4, 7, 7,10,10,12,12,13,13,18,17, 3, 6, 6, + 9, 9,11,11,13,13,14,14,18,17, 3, 6, 6, 9, 9,11, + 11,13,13,14,14,17,18, 7, 9, 9,11,11,13,13,14,14, + 15,15, 0, 0, 7, 9, 9,11,11,13,13,14,14,15,16,19, + 18,10,11,11,13,13,14,14,16,15,17,18, 0, 0,10,11, + 11,13,13,14,14,15,15,16,18, 0, 0,11,13,13,14,14, + 15,15,17,17, 0,19, 0, 0,11,13,13,14,14,14,15,16, + 18, 0,19, 0, 0,13,14,14,15,15,18,17,18,18, 0,19, + 0, 0,13,14,14,15,16,16,16,18,18,19, 0, 0, 0,16, + 17,17, 0,17,19,19, 0,19, 0, 0, 0, 0,16,19,16,17, + 18, 0,19, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__16u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p6_0 = { + _vq_quantthresh__16u0__p6_0, + _vq_quantmap__16u0__p6_0, + 13, + 13 +}; + +static static_codebook _16u0__p6_0 = { + 2, 169, + _vq_lengthlist__16u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16u0__p6_0, + NULL, + &_vq_auxt__16u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p6_1[] = { + 1, 4, 5, 6, 6, 4, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, + 6, 6, 7, 7, 6, 6, 6, 7, 7, +}; + +static float _vq_quantthresh__16u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p6_1 = { + _vq_quantthresh__16u0__p6_1, + _vq_quantmap__16u0__p6_1, + 5, + 5 +}; + +static static_codebook _16u0__p6_1 = { + 2, 25, + _vq_lengthlist__16u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p6_1, + NULL, + &_vq_auxt__16u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p7_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__16u0__p7_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__16u0__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_0 = { + _vq_quantthresh__16u0__p7_0, + _vq_quantmap__16u0__p7_0, + 3, + 3 +}; + +static static_codebook _16u0__p7_0 = { + 4, 81, + _vq_lengthlist__16u0__p7_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__16u0__p7_0, + NULL, + &_vq_auxt__16u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u0__p7_1[] = { + 1, 5, 5, 6, 5, 9,10,11,11,10,10,10,10,10,10, 5, + 8, 8, 8,10,10,10,10,10,10,10,10,10,10,10, 5, 8, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10, 5,10, 8, + 10,10,10,10,10,10,10,10,10,10,10,10, 4, 8, 9,10, + 10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16u0__p7_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16u0__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_1 = { + _vq_quantthresh__16u0__p7_1, + _vq_quantmap__16u0__p7_1, + 15, + 15 +}; + +static static_codebook _16u0__p7_1 = { + 2, 225, + _vq_lengthlist__16u0__p7_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16u0__p7_1, + NULL, + &_vq_auxt__16u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16u0__p7_2[] = { + 1, 6, 6, 7, 8, 7, 7,10, 9,10, 9,11,10, 9,11,10, + 9, 9, 9, 9,10, 6, 8, 7, 9, 9, 8, 8,10,10, 9,11, + 11,12,12,10, 9,11, 9,12,10, 9, 6, 9, 8, 9,12, 8, + 8,11, 9,11,11,12,11,12,12,10,11,11,10,10,11, 7, + 10, 9, 9, 9, 9, 9,10, 9,10, 9,10,10,12,10,10,10, + 11,12,10,10, 7, 9, 9, 9,10, 9, 9,10,10, 9, 9, 9, + 11,11,10,10,10,10, 9, 9,12, 7, 9,10, 9,11, 9,10, + 9,10,11,11,11,10,11,12, 9,12,11,10,10,10, 7, 9, + 9, 9, 9,10,12,10, 9,11,12,10,11,12,12,11, 9,10, + 11,10,11, 7, 9,10,10,11,10, 9,10,11,11,11,10,12, + 12,12,11,11,10,11,11,12, 8, 9,10,12,11,10,10,12, + 12,12,12,12,10,11,11, 9,11,10,12,11,11, 8, 9,10, + 10,11,12,11,11,10,10,10,12,12,12, 9,10,12,12,12, + 12,12, 8,10,11,10,10,12, 9,11,12,12,11,12,12,12, + 12,10,12,10,10,10,10, 8,12,11,11,11,10,10,11,12, + 12,12,12,11,12,12,12,11,11,11,12,10, 9,10,10,12, + 10,12,10,12,12,10,10,10,11,12,12,12,11,12,12,12, + 11,10,11,12,12,12,11,12,12,11,12,12,11,12,12,12, + 12,11,12,12,10,10,10,10,11,11,12,11,12,12,12,12, + 12,12,12,11,12,11,10,11,11,12,11,11, 9,10,10,10, + 12,10,10,11, 9,11,12,11,12,11,12,12,10,11,10,12, + 9, 9, 9,12,11,10,11,10,12,10,12,10,12,12,12,11, + 11,11,11,11,10, 9,10,10,11,10,11,11,12,11,10,11, + 12,12,12,11,11, 9,12,10,12, 9,10,12,10,10,11,10, + 11,11,12,11,10,11,10,11,11,11,11,12,11,11,10, 9, + 10,10,10, 9,11,11,10, 9,12,10,11,12,11,12,12,11, + 12,11,12,11,10,11,10,12,11,12,11,12,11,12,10,11, + 10,10,12,11,10,11,11,11,10, +}; + +static float _vq_quantthresh__16u0__p7_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16u0__p7_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_2 = { + _vq_quantthresh__16u0__p7_2, + _vq_quantmap__16u0__p7_2, + 21, + 21 +}; + +static static_codebook _16u0__p7_2 = { + 2, 441, + _vq_lengthlist__16u0__p7_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16u0__p7_2, + NULL, + &_vq_auxt__16u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16u0__single[] = { + 3, 5, 8, 7,14, 8, 9,19, 5, 2, 5, 5, 9, 6, 9,19, + 8, 4, 5, 7, 8, 9,13,19, 7, 4, 6, 5, 9, 6, 9,19, + 12, 8, 7, 9,10,11,13,19, 8, 5, 8, 6, 9, 6, 7,19, + 8, 8,10, 7, 7, 4, 5,19,12,17,19,15,18,13,11,18, +}; + +static static_codebook _huff_book__16u0__single = { + 2, 64, + _huff_lengthlist__16u0__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u1__long[] = { + 3, 6,10, 8,12, 8,14, 8,14,19, 5, 3, 5, 5, 7, 6, + 11, 7,16,19, 7, 5, 6, 7, 7, 9,11,12,19,19, 6, 4, + 7, 5, 7, 6,10, 7,18,18, 8, 6, 7, 7, 7, 7, 8, 9, + 18,18, 7, 5, 8, 5, 7, 5, 8, 6,18,18,12, 9,10, 9, + 9, 9, 8, 9,18,18, 8, 7,10, 6, 8, 5, 6, 4,11,18, + 11,15,16,12,11, 8, 8, 6, 9,18,14,18,18,18,16,16, + 16,13,16,18, +}; + +static static_codebook _huff_book__16u1__long = { + 2, 100, + _huff_lengthlist__16u1__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7,10,10, 7, + 9,10, 5, 7, 8, 7,10, 9, 7,10,10, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10,10,11,12,10,12,13, 7,10,10, + 9,13,11,10,12,13, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10,10,12,12, 9,11,12, 7,10,11,10,12,12,10,13, + 11, +}; + +static float _vq_quantthresh__16u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p1_0 = { + _vq_quantthresh__16u1__p1_0, + _vq_quantmap__16u1__p1_0, + 3, + 3 +}; + +static static_codebook _16u1__p1_0 = { + 4, 81, + _vq_lengthlist__16u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u1__p1_0, + NULL, + &_vq_auxt__16u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 6, 8, + 8, 6, 8, 8, 6, 8, 8, 7, 7,10, 8, 9, 9, 6, 8, 8, + 7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 7,10, + 8, +}; + +static float _vq_quantthresh__16u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p2_0 = { + _vq_quantthresh__16u1__p2_0, + _vq_quantmap__16u1__p2_0, + 3, + 3 +}; + +static static_codebook _16u1__p2_0 = { + 4, 81, + _vq_lengthlist__16u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u1__p2_0, + NULL, + &_vq_auxt__16u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u1__p3_0[] = { + 1, 5, 5, 8, 8, 6, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9, + 10, 9,11,11, 9, 9,10,11,11, 6, 8, 8,10,10, 8, 9, + 10,11,11, 8, 9,10,11,11,10,11,11,12,13,10,11,11, + 13,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11, + 11,10,11,11,13,13,10,11,11,13,12, 9,11,11,14,13, + 10,12,12,15,14,10,12,11,14,13,12,13,13,15,15,12, + 13,13,16,14, 9,11,11,13,14,10,11,12,14,14,10,12, + 12,14,15,12,13,13,14,15,12,13,14,15,16, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14, + 14,11,12,12,14,14, 8,10,10,12,12, 9,11,12,12,13, + 10,12,12,13,13,12,12,13,14,15,11,13,13,15,15, 7, + 10,10,12,12, 9,12,11,13,12,10,11,12,13,13,12,13, + 12,15,14,11,12,13,15,15,10,12,12,15,14,11,13,13, + 16,15,11,13,13,16,15,14,13,14,15,16,13,15,15,17, + 17,10,12,12,14,15,11,12,12,15,15,11,13,13,15,16, + 13,15,13,16,15,13,15,15,16,17, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12, + 12,14,14, 7,10,10,12,12,10,12,12,14,13, 9,11,12, + 12,13,12,13,13,15,15,12,12,13,13,15, 7,10,10,12, + 13,10,11,12,13,13,10,12,11,13,13,11,13,13,15,15, + 12,13,12,15,14, 9,12,12,15,14,11,13,13,15,15,11, + 12,13,15,15,13,14,14,17,19,13,13,14,16,16,10,12, + 12,14,15,11,13,13,15,16,11,13,12,16,15,13,15,15, + 17,18,14,15,13,16,15, 8,11,11,15,14,10,12,12,16, + 15,10,12,12,16,16,14,15,15,18,17,13,14,15,16,18, + 9,12,12,15,15,11,12,14,16,17,11,13,13,16,15,15, + 15,15,17,18,14,15,16,17,17, 9,12,12,15,15,11,14, + 13,16,16,11,13,13,16,16,15,16,15,17,18,14,16,15, + 17,16,12,14,14,17,16,12,14,15,18,17,13,15,15,17, + 17,15,15,18,16,20,15,16,17,18,18,11,14,14,16,17, + 13,15,14,18,17,13,15,15,17,17,15,17,15,18,17,15, + 17,16,19,18, 8,11,11,14,15,10,12,12,15,15,10,12, + 12,16,16,13,14,14,17,16,14,15,15,17,17, 9,12,12, + 15,16,11,13,13,16,16,11,12,13,16,16,14,16,15,20, + 17,14,16,16,17,17, 9,12,12,15,16,11,13,13,16,17, + 11,13,13,17,16,14,15,15,17,18,15,15,15,18,18,11, + 14,14,17,16,13,15,15,17,17,13,14,14,18,17,15,16, + 16,18,19,15,15,17,17,19,11,14,14,16,17,13,15,14, + 17,19,13,15,14,18,17,15,17,16,18,18,15,17,15,18, + 16, +}; + +static float _vq_quantthresh__16u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p3_0 = { + _vq_quantthresh__16u1__p3_0, + _vq_quantmap__16u1__p3_0, + 5, + 5 +}; + +static static_codebook _16u1__p3_0 = { + 4, 625, + _vq_lengthlist__16u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u1__p3_0, + NULL, + &_vq_auxt__16u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u1__p4_0[] = { + 4, 5, 5, 8, 8, 6, 6, 7, 9, 9, 6, 6, 6, 9, 9, 9, + 10, 9,11,11, 9, 9,10,11,11, 6, 7, 7,10, 9, 7, 7, + 8, 9,10, 7, 7, 8,10,10,10,10,10,10,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 7,10, + 10, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11, + 10,10,10,12,12, 9,10,10,12,12,12,11,12,13,13,11, + 11,12,12,13, 9,10,10,11,12, 9,10,10,12,12,10,10, + 10,12,12,11,12,11,14,13,11,12,12,14,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 7,10,10,10,10,10,12, + 12,10,10,10,12,12, 6, 8, 7,10,10, 7, 7, 9,10,11, + 8, 9, 9,11,10,10,10,11,11,13,10,10,11,12,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,10,11,10,11, + 10,13,11,10,11,10,12,12,10,11,10,12,11,10,10,10, + 12,13,10,11,11,13,12,11,11,13,11,14,12,12,13,14, + 14, 9,10,10,12,13,10,11,10,13,12,10,11,11,12,13, + 11,12,11,14,12,12,13,13,15,14, 5, 7, 7,10,10, 7, + 7, 8,10,10, 7, 8, 8,10,10,10,10,10,11,12,10,10, + 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,11,11,12,12,10,10,11,11,13, 7, 7, 8,10, + 10, 8, 8, 9,10,11, 7, 9, 7,11,10,10,11,11,13,12, + 11,11,10,13,11, 9,10,10,12,12,10,11,11,13,12,10, + 10,11,12,12,12,13,13,14,14,11,11,12,12,14,10,10, + 11,12,12,10,11,11,12,13,10,10,10,13,12,12,13,13, + 15,14,12,13,10,14,11, 8,10,10,12,12,10,11,10,13, + 13, 9,10,10,12,12,12,13,13,15,14,11,12,12,13,13, + 9,10,10,13,12,10,10,11,13,13,10,11,10,13,12,12, + 12,13,14,15,12,13,12,15,13, 9,10,10,12,13,10,11, + 10,13,12,10,10,11,12,13,12,14,12,15,13,12,12,13, + 14,15,11,12,11,14,13,11,11,12,14,15,12,13,12,15, + 14,13,11,15,11,16,13,14,14,16,15,11,12,12,14,14, + 11,12,11,14,13,12,12,13,14,15,13,14,12,16,12,14, + 14,14,15,15, 8,10,10,12,12, 9,10,10,12,12,10,10, + 11,13,13,11,12,12,13,13,12,13,13,14,15, 9,10,10, + 13,12,10,11,11,13,12,10,10,11,13,13,12,13,12,15, + 14,12,12,13,13,16, 9, 9,10,12,13,10,10,11,12,13, + 10,11,10,13,13,12,12,13,13,15,13,13,12,15,13,11, + 12,12,14,14,12,13,12,15,14,11,11,12,13,14,14,14, + 14,16,15,13,12,15,12,16,11,11,12,13,14,12,13,13, + 14,15,10,12,11,14,13,14,15,14,16,16,13,14,11,15, + 11, +}; + +static float _vq_quantthresh__16u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p4_0 = { + _vq_quantthresh__16u1__p4_0, + _vq_quantmap__16u1__p4_0, + 5, + 5 +}; + +static static_codebook _16u1__p4_0 = { + 4, 625, + _vq_lengthlist__16u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u1__p4_0, + NULL, + &_vq_auxt__16u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u1__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8, + 10, 9,11,11,12,11, 7, 8, 8, 9, 9,11,11,12,12, 9, + 10,10,11,11,12,12,13,12, 9,10,10,11,11,12,12,12, + 13, +}; + +static float _vq_quantthresh__16u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p5_0 = { + _vq_quantthresh__16u1__p5_0, + _vq_quantmap__16u1__p5_0, + 9, + 9 +}; + +static static_codebook _16u1__p5_0 = { + 2, 81, + _vq_lengthlist__16u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u1__p5_0, + NULL, + &_vq_auxt__16u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u1__p6_0[] = { + 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 4, 6, 6, 8, 8, + 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7, + 8, 8,10, 9, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7, + 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9, + 9, 9,10,10,10,10,11,11, 9, 9, 9,10,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__16u1__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u1__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p6_0 = { + _vq_quantthresh__16u1__p6_0, + _vq_quantmap__16u1__p6_0, + 9, + 9 +}; + +static static_codebook _16u1__p6_0 = { + 2, 81, + _vq_lengthlist__16u1__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u1__p6_0, + NULL, + &_vq_auxt__16u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p7_0[] = { + 1, 4, 4, 4, 8, 8, 4, 8, 8, 5,11, 9, 8,12,11, 8, + 12,11, 5,10,11, 8,11,12, 8,11,12, 4,11,11,11,14, + 13,10,13,13, 8,14,13,12,14,16,12,16,15, 8,14,14, + 13,16,14,12,15,16, 4,11,11,10,14,13,11,14,14, 8, + 15,14,12,15,15,12,14,16, 8,14,14,11,16,15,12,15, + 13, +}; + +static float _vq_quantthresh__16u1__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16u1__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p7_0 = { + _vq_quantthresh__16u1__p7_0, + _vq_quantmap__16u1__p7_0, + 3, + 3 +}; + +static static_codebook _16u1__p7_0 = { + 4, 81, + _vq_lengthlist__16u1__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16u1__p7_0, + NULL, + &_vq_auxt__16u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 5, 7, 7, + 8, 8, 8, 8, 8, 8, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8, + 8, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 9, 9,10, + 9,10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, 9, 8, 8, 8, + 9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9,10, + 10,10,10, 8, 8, 8, 9, 9, 9,10,10,10,10,10, 8, 8, + 8, 9, 9,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__16u1__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u1__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p7_1 = { + _vq_quantthresh__16u1__p7_1, + _vq_quantmap__16u1__p7_1, + 11, + 11 +}; + +static static_codebook _16u1__p7_1 = { + 2, 121, + _vq_lengthlist__16u1__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u1__p7_1, + NULL, + &_vq_auxt__16u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p8_0[] = { + 1, 4, 4, 5, 5, 8, 8,10,10,12,12, 4, 7, 7, 8, 8, + 9, 9,12,11,14,13, 4, 7, 7, 7, 8, 9,10,11,11,13, + 12, 5, 8, 8, 9, 9,11,11,12,13,15,14, 5, 7, 8, 9, + 9,11,11,13,13,17,15, 8, 9,10,11,11,12,13,17,14, + 17,16, 8,10, 9,11,11,12,12,13,15,15,17,10,11,11, + 12,13,14,15,15,16,16,17, 9,11,11,12,12,14,15,17, + 15,15,16,11,14,12,14,15,16,15,16,16,16,15,11,13, + 13,14,14,15,15,16,16,15,16, +}; + +static float _vq_quantthresh__16u1__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__16u1__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p8_0 = { + _vq_quantthresh__16u1__p8_0, + _vq_quantmap__16u1__p8_0, + 11, + 11 +}; + +static static_codebook _16u1__p8_0 = { + 2, 121, + _vq_lengthlist__16u1__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__16u1__p8_0, + NULL, + &_vq_auxt__16u1__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p8_1[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, + 8, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__16u1__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u1__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p8_1 = { + _vq_quantthresh__16u1__p8_1, + _vq_quantmap__16u1__p8_1, + 11, + 11 +}; + +static static_codebook _16u1__p8_1 = { + 2, 121, + _vq_lengthlist__16u1__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u1__p8_1, + NULL, + &_vq_auxt__16u1__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u1__p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__16u1__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__16u1__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_0 = { + _vq_quantthresh__16u1__p9_0, + _vq_quantmap__16u1__p9_0, + 15, + 15 +}; + +static static_codebook _16u1__p9_0 = { + 2, 225, + _vq_lengthlist__16u1__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__16u1__p9_0, + NULL, + &_vq_auxt__16u1__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u1__p9_1[] = { + 1, 6, 5, 9, 9,10,10, 6, 7, 9, 9,10,10,10,10, 5, + 10, 8,10, 8,10,10, 8, 8,10, 9,10,10,10,10, 5, 8, + 9,10,10,10,10, 8,10,10,10,10,10,10,10, 9,10,10, + 10,10,10,10, 9, 9,10,10,10,10,10,10, 9, 9, 8, 9, + 10,10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 8,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 6, 8, 8,10,10,10, 8, + 10,10,10,10,10,10,10,10, 5, 8, 8,10,10,10, 9, 9, + 10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__16u1__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__16u1__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_1 = { + _vq_quantthresh__16u1__p9_1, + _vq_quantmap__16u1__p9_1, + 15, + 15 +}; + +static static_codebook _16u1__p9_1 = { + 2, 225, + _vq_lengthlist__16u1__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__16u1__p9_1, + NULL, + &_vq_auxt__16u1__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16u1__p9_2[] = { + 1, 6, 6, 7, 8, 8,11,10, 9, 9,11, 9,10, 9,11,11, + 9, 6, 7, 6,11, 8,11, 9,10,10,11, 9,11,10,10,10, + 11, 9, 5, 7, 7, 8, 8,10,11, 8, 8,11, 9, 9,10,11, + 9,10,11, 8, 9, 6, 8, 8, 9, 9,10,10,11,11,11, 9, + 11,10, 9,11, 8, 8, 8, 9, 8, 9,10,11, 9, 9,11,11, + 10, 9, 9,11,10, 8,11, 8, 9, 8,11, 9,10, 9,10,11, + 11,10,10, 9,10,10, 8, 8, 9,10,10,10, 9,11, 9,10, + 11,11,11,11,10, 9,11, 9, 9,11,11,10, 8,11,11,11, + 9,10,10,11,10,11,11, 9,11,10, 9,11,10,10,10,10, + 9,11,10,11,10, 9, 9,10,11, 9, 8,10,11,11,10,10, + 11, 9,11,10,11,11,10,11, 9, 9, 8,10, 8, 9,11, 9, + 8,10,10, 9,11,10,11,10,11, 9,11, 8,10,11,11,11, + 11,10,10,11,11,11,11,10,11,11,10, 9, 8,10,10, 9, + 11,10,11,11,11, 9, 9, 9,11,11,11,10,10, 9, 9,10, + 9,11,11,11,11, 8,10,11,10,11,11,10,11,11, 9, 9, + 9,10, 9,11, 9,11,11,11,11,11,10,11,11,10,11,10, + 11,11, 9,11,10,11,10, 9,10, 9,10,10,11,11,11,11, + 9,10, 9,10,11,11,10,11,11,11,11,11,11,10,11,11, + 10, +}; + +static float _vq_quantthresh__16u1__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16u1__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_2 = { + _vq_quantthresh__16u1__p9_2, + _vq_quantmap__16u1__p9_2, + 17, + 17 +}; + +static static_codebook _16u1__p9_2 = { + 2, 289, + _vq_lengthlist__16u1__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16u1__p9_2, + NULL, + &_vq_auxt__16u1__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16u1__short[] = { + 5, 7,10, 9,11,10,15,11,13,16, 6, 4, 6, 6, 7, 7, + 10, 9,12,16,10, 6, 5, 6, 6, 7,10,11,16,16, 9, 6, + 7, 6, 7, 7,10, 8,14,16,11, 6, 5, 4, 5, 6, 8, 9, + 15,16, 9, 6, 6, 5, 6, 6, 9, 8,14,16,12, 7, 6, 6, + 5, 6, 6, 7,13,16, 8, 6, 7, 6, 5, 5, 4, 4,11,16, + 9, 8, 9, 9, 7, 7, 6, 5,13,16,14,14,16,15,16,15, + 16,16,16,16, +}; + +static static_codebook _huff_book__16u1__short = { + 2, 100, + _huff_lengthlist__16u1__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u2__long[] = { + 5, 7,10,10,10,11,11,13,18,19, 6, 5, 5, 6, 7, 8, + 9,12,19,19, 8, 5, 4, 4, 6, 7, 9,13,19,19, 8, 5, + 4, 4, 5, 6, 8,12,17,19, 7, 5, 5, 4, 4, 5, 7,12, + 18,18, 8, 7, 7, 6, 5, 5, 6,10,18,18, 9, 9, 9, 8, + 6, 5, 6, 9,18,18,11,13,13,13, 8, 7, 7, 9,16,18, + 13,17,18,16,11, 9, 9, 9,17,18,15,18,18,18,15,13, + 13,14,18,18, +}; + +static static_codebook _huff_book__16u2__long = { + 2, 100, + _huff_lengthlist__16u2__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u2__short[] = { + 8,11,12,12,14,15,16,16,16,16, 9, 7, 7, 8, 9,11, + 13,14,16,16,13, 7, 6, 6, 7, 9,12,13,15,16,15, 7, + 6, 5, 4, 6,10,11,14,16,12, 8, 7, 4, 2, 4, 7,10, + 14,16,11, 9, 7, 5, 3, 4, 6, 9,14,16,11,10, 9, 7, + 5, 5, 6, 9,16,16,10,10, 9, 8, 6, 6, 7,10,16,16, + 11,11,11,10,10,10,11,14,16,16,16,14,14,13,14,16, + 16,16,16,16, +}; + +static static_codebook _huff_book__16u2__short = { + 2, 100, + _huff_lengthlist__16u2__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u2_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7, + 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 8, 9, + 9, 7, 9, 9, 7, 9, 9, 9,10,10, 9,10,10, 7, 9, 9, + 9,10,10, 9,10,11, 5, 7, 8, 8, 9, 9, 8, 9, 9, 7, + 9, 9, 9,10,10, 9, 9,10, 7, 9, 9, 9,10,10, 9,11, + 10, +}; + +static float _vq_quantthresh__16u2_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u2_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p1_0 = { + _vq_quantthresh__16u2_p1_0, + _vq_quantmap__16u2_p1_0, + 3, + 3 +}; + +static static_codebook _16u2_p1_0 = { + 4, 81, + _vq_lengthlist__16u2_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u2_p1_0, + NULL, + &_vq_auxt__16u2_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u2_p2_0[] = { + 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9, + 10, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 8, 8,10,10,10,10,10,12,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 7, 8, 8,10,10, 7, 8, 8,10, + 10, 9,10,10,12,11,10,10,10,12,12, 9,10,10,12,12, + 10,11,10,13,12, 9,10,10,12,12,12,12,12,14,14,11, + 12,12,13,14, 9,10,10,12,12, 9,10,10,12,12,10,10, + 10,12,12,11,12,12,14,13,12,13,12,14,14, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12, + 12,10,10,11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, + 8, 9, 9,11,11,11,11,11,12,13,10,11,11,12,13, 7, + 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,12,10,11,11,13,13, 9,11,10,13,13,10,11,11, + 13,13,10,11,11,13,13,12,12,13,13,15,12,12,13,14, + 15, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13, + 11,13,11,14,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10, + 11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9, + 10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,12, + 11,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10, + 10,11,12,13,12,13,13,15,14,11,11,13,12,14,10,10, + 11,13,13,10,11,11,13,13,10,11,11,13,13,12,13,13, + 14,14,12,13,12,14,13, 8,10, 9,12,12, 9,11,10,13, + 13, 9,10,10,12,13,12,13,13,14,14,12,12,13,14,14, + 9,11,10,13,13,10,11,11,13,13,10,11,11,13,13,12, + 13,13,15,15,13,13,13,14,15, 9,10,10,12,13,10,11, + 10,13,12,10,11,11,13,13,12,13,12,15,14,13,13,13, + 14,15,11,12,12,15,14,12,12,13,15,15,12,13,13,15, + 14,14,13,15,14,16,13,14,15,16,16,11,12,12,14,14, + 11,12,12,15,14,12,13,13,15,15,13,14,13,16,14,14, + 14,14,16,16, 8, 9, 9,12,12, 9,10,10,13,12, 9,10, + 10,13,13,12,12,12,14,14,12,12,13,15,15, 9,10,10, + 13,12,10,11,11,13,13,10,10,11,13,14,12,13,13,15, + 15,12,12,13,14,15, 9,10,10,13,13,10,11,11,13,13, + 10,11,11,13,13,12,13,13,14,14,13,14,13,15,14,11, + 12,12,14,14,12,13,13,15,14,11,12,12,14,15,14,14, + 14,16,15,13,12,14,14,16,11,12,13,14,15,12,13,13, + 14,16,12,13,12,15,14,13,15,14,16,16,14,15,13,16, + 13, +}; + +static float _vq_quantthresh__16u2_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u2_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p2_0 = { + _vq_quantthresh__16u2_p2_0, + _vq_quantmap__16u2_p2_0, + 5, + 5 +}; + +static static_codebook _16u2_p2_0 = { + 4, 625, + _vq_lengthlist__16u2_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u2_p2_0, + NULL, + &_vq_auxt__16u2_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u2_p3_0[] = { + 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 5, 6, 6, 8, 7, + 9, 9, 4, 5, 5, 6, 6, 7, 8, 9, 9, 6, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7, + 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9, + 9, 9,10, 9,10,10,11,11, 9, 9, 9,10,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__16u2_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u2_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p3_0 = { + _vq_quantthresh__16u2_p3_0, + _vq_quantmap__16u2_p3_0, + 9, + 9 +}; + +static static_codebook _16u2_p3_0 = { + 2, 81, + _vq_lengthlist__16u2_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u2_p3_0, + NULL, + &_vq_auxt__16u2_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16u2_p4_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,11, + 11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,12,12,12, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,11,11,12,12,13,13, 8, 9, 9, 9, 9,10, 9,10, + 10,10,10,11,11,12,12,13,13, 9, 9, 9, 9, 9,10,10, + 10,10,11,11,11,12,12,12,13,13, 9, 9, 9, 9, 9,10, + 10,10,10,11,11,12,11,12,12,13,13,10,10,10,10,10, + 11,11,11,11,11,12,12,12,12,13,13,14,10,10,10,10, + 10,11,11,11,11,12,11,12,12,13,12,13,13,11,11,11, + 11,11,12,12,12,12,12,12,13,13,13,13,14,14,11,11, + 11,11,11,12,12,12,12,12,12,13,12,13,13,14,14,11, + 12,12,12,12,12,12,13,13,13,13,13,13,14,14,14,14, + 11,12,12,12,12,12,12,13,13,13,13,14,13,14,14,14, + 14, +}; + +static float _vq_quantthresh__16u2_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16u2_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p4_0 = { + _vq_quantthresh__16u2_p4_0, + _vq_quantmap__16u2_p4_0, + 17, + 17 +}; + +static static_codebook _16u2_p4_0 = { + 2, 289, + _vq_lengthlist__16u2_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16u2_p4_0, + NULL, + &_vq_auxt__16u2_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u2_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10, 9, 7, + 10, 9, 5, 8, 9, 7, 9,10, 7, 9,10, 4, 9, 9, 9,11, + 11, 8,11,11, 7,11,11,10,10,13,10,14,13, 7,11,11, + 10,13,11,10,13,14, 5, 9, 9, 8,11,11, 9,11,11, 7, + 11,11,10,14,13,10,12,14, 7,11,11,10,13,13,10,13, + 10, +}; + +static float _vq_quantthresh__16u2_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16u2_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p5_0 = { + _vq_quantthresh__16u2_p5_0, + _vq_quantmap__16u2_p5_0, + 3, + 3 +}; + +static static_codebook _16u2_p5_0 = { + 4, 81, + _vq_lengthlist__16u2_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16u2_p5_0, + NULL, + &_vq_auxt__16u2_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u2_p5_1[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 5, 5, 5, 7, 7, + 7, 7, 8, 8, 8, 8, 5, 5, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__16u2_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u2_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p5_1 = { + _vq_quantthresh__16u2_p5_1, + _vq_quantmap__16u2_p5_1, + 11, + 11 +}; + +static static_codebook _16u2_p5_1 = { + 2, 121, + _vq_lengthlist__16u2_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u2_p5_1, + NULL, + &_vq_auxt__16u2_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u2_p6_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, + 8, 8, 9, 9, 9, 9,10,10,12,11, 4, 6, 6, 8, 8, 9, + 9, 9, 9,10,10,11,12, 7, 8, 8, 9, 9,10,10,10,10, + 12,12,13,12, 7, 8, 8, 9, 9,10,10,10,10,11,12,12, + 12, 8, 9, 9,10,10,11,11,11,11,12,12,13,13, 8, 9, + 9,10,10,11,11,11,11,12,13,13,13, 8, 9, 9,10,10, + 11,11,12,12,13,13,14,14, 8, 9, 9,10,10,11,11,12, + 12,13,13,14,14, 9,10,10,11,12,13,12,13,14,14,14, + 14,14, 9,10,10,11,12,12,13,13,13,14,14,14,14,10, + 11,11,12,12,13,13,14,14,15,15,15,15,10,11,11,12, + 12,13,13,14,14,14,14,15,15, +}; + +static float _vq_quantthresh__16u2_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16u2_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p6_0 = { + _vq_quantthresh__16u2_p6_0, + _vq_quantmap__16u2_p6_0, + 13, + 13 +}; + +static static_codebook _16u2_p6_0 = { + 2, 169, + _vq_lengthlist__16u2_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16u2_p6_0, + NULL, + &_vq_auxt__16u2_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u2_p6_1[] = { + 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 6, 6, 5, 5, 5, 6, 6, +}; + +static float _vq_quantthresh__16u2_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u2_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p6_1 = { + _vq_quantthresh__16u2_p6_1, + _vq_quantmap__16u2_p6_1, + 5, + 5 +}; + +static static_codebook _16u2_p6_1 = { + 2, 25, + _vq_lengthlist__16u2_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u2_p6_1, + NULL, + &_vq_auxt__16u2_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u2_p7_0[] = { + 1, 4, 4, 7, 7, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 6, + 9, 9, 9, 9, 9, 9,10,10,11,11, 4, 6, 6, 8, 9, 9, + 9, 9, 9,10,11,12,11, 7, 8, 9,10,10,10,10,11,10, + 11,12,12,13, 7, 9, 9,10,10,10,10,10,10,11,12,13, + 13, 7, 9, 8,10,10,11,11,11,12,12,13,13,14, 7, 9, + 9,10,10,11,11,11,12,13,13,13,13, 8, 9, 9,10,11, + 11,12,12,12,13,13,13,13, 8, 9, 9,10,11,11,11,12, + 12,13,13,14,14, 9,10,10,12,11,12,13,13,13,14,13, + 13,13, 9,10,10,11,11,12,12,13,14,13,13,14,13,10, + 11,11,12,13,14,14,14,15,14,14,14,14,10,11,11,12, + 12,13,13,13,14,14,14,15,14, +}; + +static float _vq_quantthresh__16u2_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__16u2_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p7_0 = { + _vq_quantthresh__16u2_p7_0, + _vq_quantmap__16u2_p7_0, + 13, + 13 +}; + +static static_codebook _16u2_p7_0 = { + 2, 169, + _vq_lengthlist__16u2_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__16u2_p7_0, + NULL, + &_vq_auxt__16u2_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u2_p7_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, + 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, + 8, 6, 6, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16u2_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u2_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p7_1 = { + _vq_quantthresh__16u2_p7_1, + _vq_quantmap__16u2_p7_1, + 11, + 11 +}; + +static static_codebook _16u2_p7_1 = { + 2, 121, + _vq_lengthlist__16u2_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u2_p7_1, + NULL, + &_vq_auxt__16u2_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u2_p8_0[] = { + 1, 5, 5, 7, 7, 8, 8, 7, 7, 8, 8,10, 9,11,11, 4, + 6, 6, 8, 8,10, 9, 9, 8, 9, 9,10,10,12,14, 4, 6, + 7, 8, 9, 9,10, 9, 8, 9, 9,10,12,12,11, 7, 8, 8, + 10,10,10,10, 9, 9,10,10,11,13,13,12, 7, 8, 8, 9, + 11,11,10, 9, 9,11,10,12,11,11,14, 8, 9, 9,11,10, + 11,11,10,10,11,11,13,12,14,12, 8, 9, 9,11,12,11, + 11,10,10,12,11,12,12,12,14, 7, 8, 8, 9, 9,10,10, + 10,11,12,11,13,13,14,12, 7, 8, 9, 9, 9,10,10,11, + 11,11,12,12,14,14,14, 8,10, 9,10,11,11,11,11,14, + 12,12,13,14,14,13, 9, 9, 9,10,11,11,11,12,12,12, + 14,12,14,13,14,10,10,10,12,11,12,11,14,13,14,13, + 14,14,13,14, 9,10,10,11,12,11,13,12,13,13,14,14, + 14,13,14,10,13,13,12,12,11,12,14,13,14,13,14,12, + 14,13,10,11,11,12,11,12,12,14,14,14,13,14,14,14, + 14, +}; + +static float _vq_quantthresh__16u2_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16u2_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p8_0 = { + _vq_quantthresh__16u2_p8_0, + _vq_quantmap__16u2_p8_0, + 15, + 15 +}; + +static static_codebook _16u2_p8_0 = { + 2, 225, + _vq_lengthlist__16u2_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16u2_p8_0, + NULL, + &_vq_auxt__16u2_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16u2_p8_1[] = { + 2, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,10, 9, 9, + 9,10,10,10,10, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, + 10, 9,10,10,10,10,10,10,11,10, 5, 6, 6, 7, 7, 8, + 8, 8, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 7, + 7, 7, 8, 8, 9, 8, 9, 9,10, 9,10,10,10,10,10,10, + 11,10,11,10, 7, 7, 7, 8, 8, 8, 9, 9, 9,10, 9,10, + 10,10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, + 10, 9,10,10,10,10,10,10,10,11,10,10,11,10, 8, 8, + 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11, + 11,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 11,10,11,10,11,10,11,10, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,11,11,10,10,10, 9,10, 9, + 9,10,10,10,11,10,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9,10, 9,10,10,10,10,10,10,11,10,11, + 10,11,11,11,11,10,10, 9,10, 9,10,10,10,10,11,10, + 10,10,10,10,11,10,11,10,11,10,10,11, 9,10,10,10, + 10,10,10,10,10,10,11,10,10,11,11,10,11,11,11,11, + 11, 9, 9,10,10,10,10,10,11,10,10,11,10,10,11,10, + 10,11,11,11,11,11, 9,10,10,10,10,10,10,10,11,10, + 11,10,11,10,11,11,11,11,11,10,11,10,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,10,11,11, + 10,10,10,10,10,11,10,10,10,11,10,11,11,11,11,10, + 12,11,11,11,10,10,10,10,10,10,11,10,10,10,11,11, + 12,11,11,11,11,11,11,11,11,11,10,10,10,11,10,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10, + 10,10,11,10,11,10,10,11,11,11,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,11,11,10,11,11,10, + 11,11,10,11,11,11,10,11,11, +}; + +static float _vq_quantthresh__16u2_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16u2_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p8_1 = { + _vq_quantthresh__16u2_p8_1, + _vq_quantmap__16u2_p8_1, + 21, + 21 +}; + +static static_codebook _16u2_p8_1 = { + 2, 441, + _vq_lengthlist__16u2_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16u2_p8_1, + NULL, + &_vq_auxt__16u2_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_0[] = { + 5586, + 4655, + 6517, + 3724, + 7448, + 2793, + 8379, + 1862, + 9310, + 931, + 10241, + 0, + 11172, + 5521, + 5651, +}; + +static long _vq_lengthlist__16u2_p9_0[] = { + 1,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10, 4,10,10,10,10,10,10,10,10,10,10,10,10, + 6, 6, 5,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 5, + 5, +}; + +static float _vq_quantthresh__16u2_p9_0[] = { + -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -498, -32.5, 32.5, + 498, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, +}; + +static long _vq_quantmap__16u2_p9_0[] = { + 11, 9, 7, 5, 3, 1, 13, 0, + 14, 2, 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_0 = { + _vq_quantthresh__16u2_p9_0, + _vq_quantmap__16u2_p9_0, + 15, + 15 +}; + +static static_codebook _16u2_p9_0 = { + 2, 225, + _vq_lengthlist__16u2_p9_0, + 1, -510275072, 1611661312, 14, 0, + _vq_quantlist__16u2_p9_0, + NULL, + &_vq_auxt__16u2_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_1[] = { + 392, + 343, + 441, + 294, + 490, + 245, + 539, + 196, + 588, + 147, + 637, + 98, + 686, + 49, + 735, + 0, + 784, + 388, + 396, +}; + +static long _vq_lengthlist__16u2_p9_1[] = { + 1,12,10,12,10,12,10,12,11,12,12,12,12,12,12,12, + 12, 5, 5, 9,10,12,11,11,12,12,12,12,12,12,12,12, + 12,12,12,12,10, 9, 9,11, 9,11,11,12,11,12,12,12, + 12,12,12,12,12,12,12, 8, 8,10,11, 9,12,11,12,12, + 12,12,12,12,12,12,12,12,12,12, 9, 8,10,11,12,11, + 12,11,12,12,12,12,12,12,12,12,12,12,12, 8, 9,11, + 11,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 9,10,11,12,11,12,11,12,12,12,12,12,12,12,12,12, + 12,12,12, 9, 9,11,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11, 5, 8, 9, 9, 8,11, 9,11,11,11,11,11,11, + 11,11,11,11, 5, 5, 4, 8, 8, 8, 8,10, 9,10,10,11, + 11,11,11,11,11,11,11, 5, 4, +}; + +static float _vq_quantthresh__16u2_p9_1[] = { + -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -26.5, + -2, 2, 26.5, 73.5, 122.5, 171.5, 220.5, 269.5, + 318.5, 367.5, +}; + +static long _vq_quantmap__16u2_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 17, 0, 18, 2, 4, 6, 8, 10, + 12, 14, 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_1 = { + _vq_quantthresh__16u2_p9_1, + _vq_quantmap__16u2_p9_1, + 19, + 19 +}; + +static static_codebook _16u2_p9_1 = { + 2, 361, + _vq_lengthlist__16u2_p9_1, + 1, -518488064, 1611661312, 10, 0, + _vq_quantlist__16u2_p9_1, + NULL, + &_vq_auxt__16u2_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__16u2_p9_2[] = { + 1, 3, 3, 4, 7, 7, 7, 8, 7, 7, 7, 7, 8, 8, 8, 8, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 9, 9, 8, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,12,12,10, + 11, +}; + +static float _vq_quantthresh__16u2_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__16u2_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_2 = { + _vq_quantthresh__16u2_p9_2, + _vq_quantmap__16u2_p9_2, + 49, + 49 +}; + +static static_codebook _16u2_p9_2 = { + 1, 49, + _vq_lengthlist__16u2_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__16u2_p9_2, + NULL, + &_vq_auxt__16u2_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u0__long[] = { + 3, 7,12,10,15,10, 9,18, 5, 2, 5, 6, 8, 7, 9,20, + 10, 4, 4, 6, 6, 8,11,20, 9, 5, 6, 5, 7, 6, 9,20, + 11, 7, 5, 7, 5, 7,10,20,10, 6, 7, 6, 6, 6, 8,17, + 9, 8,10, 7, 7, 5, 5,17,11,18,19,14,13, 9, 8,19, +}; + +static static_codebook _huff_book__44u0__long = { + 2, 64, + _huff_lengthlist__44u0__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u0__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,10,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,13,14, 7,11,11, + 10,14,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,11, 8, + 11,11,11,14,13,10,12,13, 8,11,12,11,14,14,11,14, + 13, +}; + +static float _vq_quantthresh__44u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p1_0 = { + _vq_quantthresh__44u0__p1_0, + _vq_quantmap__44u0__p1_0, + 3, + 3 +}; + +static static_codebook _44u0__p1_0 = { + 4, 81, + _vq_lengthlist__44u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u0__p1_0, + NULL, + &_vq_auxt__44u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 6, 7, 8, 8, 6, + 7, 8, 5, 6, 7, 6, 8, 7, 7, 8, 8, 5, 7, 7, 7, 8, + 8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 7,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10,10, 7, 8,10, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p2_0 = { + _vq_quantthresh__44u0__p2_0, + _vq_quantmap__44u0__p2_0, + 3, + 3 +}; + +static static_codebook _44u0__p2_0 = { + 4, 81, + _vq_lengthlist__44u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u0__p2_0, + NULL, + &_vq_auxt__44u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p3_0[] = { + 1, 5, 5, 8, 8, 5, 7, 7, 9, 9, 5, 7, 8, 9, 9, 8, + 10, 9,12,11, 8, 9,10,11,12, 6, 8, 8,10,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,12,11,13,13,10,11,11, + 13,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10,10,11, + 11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14, + 10,12,11,15,14,10,12,11,15,14,12,14,13,16,15,12, + 13,13,17,15, 9,11,11,14,14,10,11,12,14,15,10,11, + 12,14,17,12,13,14,15,16,13,13,14,15,17, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,15, + 14,11,12,12,14,15, 8,10,10,13,12,10,12,12,13,13, + 10,12,12,14,14,12,13,13,15,15,11,13,13,15,16, 7, + 10,10,12,12, 9,12,11,14,13,10,12,12,13,14,12,13, + 12,15,15,12,13,13,16,17,10,12,12,15,16,12,13,13, + 17,15,11,13,13,17,16,15,15,15,17,17,13,15,16,18, + 18, 9,12,12,15,17,11,13,12,16,16,11,13,13,16,18, + 14,15,14,16,16,13,15,15,17,18, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,10,12,12,15,15,11,12, + 12,14,15, 7,10,10,12,12,10,12,12,14,14, 9,11,12, + 13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,12, + 13,10,12,12,13,14,10,12,12,13,13,12,13,13,16,16, + 12,13,13,15,15,10,12,12,15,16,11,13,13,17,16,11, + 12,13,17,16,13,15,15,18,19,14,14,14,17,16,10,12, + 12,15,15,11,13,13,15,16,11,13,13,15,17,13,15,15, + 18,20,14,15,15,17,17, 8,11,11,15,16,10,13,12,17, + 16,10,12,13,16,17,15,16,15,20,19,14,15,16,18,19, + 9,12,12,15,17,11,13,14,18,18,11,13,14,17,17,16, + 17,18,19,19,15,16,18,19,20, 9,12,12,16,16,11,14, + 12,17,17,11,13,13,16,19,15,16,15,20,19,15,15,15, + 19,17,12,14,14,18,19,14,15,15,19,18,13,15,15,18, + 17,17,18,19,20, 0,15,16,17,20, 0,12,15,14,17,18, + 13,16,14,20,20,13,16,15,19,18,16,20,17,20,19,16, + 17,16, 0,19, 8,11,11,15,15,10,12,12,17,17,10,12, + 13,16,16,13,14,15,17,17,15,16,17,19,19, 9,12,12, + 16,17,11,13,13,18,16,11,13,13,16,17,14,15,16,19, + 18,15,16,17,17,18, 9,12,12,17,16,11,14,13,16,16, + 12,14,13,17,18,14,16,15,18,19,17,17,17,19,18,12, + 14,14,19,17,13,15,15,17, 0,13,14,16, 0, 0,15,16, + 16,19, 0,16,16,19,19, 0,12,15,14,19,18,13,15,15, + 19, 0,14,16,15, 0,19,15,17,17, 0,19,17,18,17, 0, + 19, +}; + +static float _vq_quantthresh__44u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p3_0 = { + _vq_quantthresh__44u0__p3_0, + _vq_quantmap__44u0__p3_0, + 5, + 5 +}; + +static static_codebook _44u0__p3_0 = { + 4, 625, + _vq_lengthlist__44u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p3_0, + NULL, + &_vq_auxt__44u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p4_0[] = { + 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10,10,10,10,11,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 6, 8, 7,10,10, 7, 8, 8,10, + 10, 9,10,10,12,11,10,10,10,12,11, 9,10,10,12,12, + 10,11,10,13,13, 9,10,10,13,13,12,12,12,14,14,11, + 12,12,14,14, 9,10,10,12,12, 9,10,10,13,13,10,10, + 10,12,13,11,12,12,14,14,12,13,12,14,14, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,13, + 12,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11, + 8, 9, 9,11,11,10,10,11,12,13,10,11,11,13,14, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,11,10,11,11,13,13,10,11,10,13,13,10,10,11, + 13,14,10,11,11,14,13,12,11,13,12,14,12,13,13,15, + 15, 9,10,10,13,13,10,11,10,13,13,10,11,11,13,14, + 12,13,11,15,12,12,13,13,14,15, 5, 7, 7,10, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10, + 10,12,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,14, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 8,11,10,10,11,11,13,13, + 10,11,10,13,11, 9,10,10,13,13,10,11,11,14,13,10, + 10,11,12,13,13,13,13,15,14,12,11,13,12,15, 9,10, + 11,13,13,10,11,11,13,14,10,11,10,13,13,12,13,13, + 15,15,12,13,11,15,12, 8,10,10,13,12,10,11,11,13, + 13, 9,10,11,13,13,13,13,13,15,15,12,13,13,15,15, + 9,10,10,13,13,10,11,11,13,14,10,11,11,14,13,13, + 13,14,14,15,13,13,13,14,15, 9,10,10,13,13,10,11, + 10,14,13,10,11,11,13,14,13,14,13,15,14,12,13,13, + 14,15,11,13,13,15,14,11,11,13,14,15,12,14,13,15, + 15,13,12,15,12,16,14,14,15,17,16,11,12,12,14,15, + 11,13,11,15,14,12,13,13,15,15,14,14,12,17,13,14, + 15,15,18,16, 8,10,10,13,12, 9,10,10,13,13,10,10, + 11,13,13,12,13,13,14,14,12,13,13,15,15, 9,10,10, + 13,13,10,11,11,14,13,10,10,11,13,14,12,13,13,17, + 15,12,12,13,14,16, 9,10,10,13,13,10,11,11,13,13, + 10,11,10,14,13,13,13,13,14,15,13,14,13,15,15,11, + 13,12,14,14,12,13,13,16,14,11,12,13,15,15,14,15, + 16,17,18,14,12,15,14,16,11,12,13,14,15,12,13,13, + 15,16,11,13,11,15,14,14,16,14,16,17,14,15,12,16, + 12, +}; + +static float _vq_quantthresh__44u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p4_0 = { + _vq_quantthresh__44u0__p4_0, + _vq_quantmap__44u0__p4_0, + 5, + 5 +}; + +static static_codebook _44u0__p4_0 = { + 4, 625, + _vq_lengthlist__44u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p4_0, + NULL, + &_vq_auxt__44u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u0__p5_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 8, 8, 8, + 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8, + 10, 9,10,11,12,12, 8, 8, 8, 9, 9,11,11,12,12, 9, + 10,10,11,11,12,12,13,13, 9,10,10,11,11,12,12,13, + 13, +}; + +static float _vq_quantthresh__44u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p5_0 = { + _vq_quantthresh__44u0__p5_0, + _vq_quantmap__44u0__p5_0, + 9, + 9 +}; + +static static_codebook _44u0__p5_0 = { + 2, 81, + _vq_lengthlist__44u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u0__p5_0, + NULL, + &_vq_auxt__44u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8,10, 9,10,10,14,14, 4, 6, 5, + 8, 8, 9, 9,10,10,11,11,14,14, 4, 5, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 7, 8, 8, 9, 9,10,10,11,11, + 12,12,15,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,14, + 15, 9, 9, 9,10,10,11,11,12,11,12,12,15,16, 9, 9, + 9,10,10,11,11,11,11,12,12,15,15,10,10,10,11,11, + 12,11,12,12,13,13,16,16,10,10,10,11,11,12,12,12, + 12,13,13,16,17,11,11,12,12,12,13,13,14,13,14,14, + 18,17,11,11,11,12,12,12,12,13,14,14,14,18,18,14, + 14,14,15,15,15,16,16,16,17,17, 0,19,14,14,14,15, + 15,16,17,16,17,17,17,19, 0, +}; + +static float _vq_quantthresh__44u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p6_0 = { + _vq_quantthresh__44u0__p6_0, + _vq_quantmap__44u0__p6_0, + 13, + 13 +}; + +static static_codebook _44u0__p6_0 = { + 2, 169, + _vq_lengthlist__44u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u0__p6_0, + NULL, + &_vq_auxt__44u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 5, 6, 6, 6, 6, +}; + +static float _vq_quantthresh__44u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p6_1 = { + _vq_quantthresh__44u0__p6_1, + _vq_quantmap__44u0__p6_1, + 5, + 5 +}; + +static static_codebook _44u0__p6_1 = { + 2, 25, + _vq_lengthlist__44u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p6_1, + NULL, + &_vq_auxt__44u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p7_0[] = { + 1, 5, 5,11,11, 9,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, 8,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11, 9,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11, 8,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u0__p7_0[] = { + -253.5, -84.5, 84.5, 253.5, +}; + +static long _vq_quantmap__44u0__p7_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_0 = { + _vq_quantthresh__44u0__p7_0, + _vq_quantmap__44u0__p7_0, + 5, + 5 +}; + +static static_codebook _44u0__p7_0 = { + 4, 625, + _vq_lengthlist__44u0__p7_0, + 1, -518709248, 1626677248, 3, 0, + _vq_quantlist__44u0__p7_0, + NULL, + &_vq_auxt__44u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p7_1[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 7, 7, + 8, 8, 8, 8, 9, 9,11,10,12,11, 4, 6, 7, 8, 8, 7, + 8, 9, 9,10,11,12,11, 7, 8, 8, 9, 9,10,10,11,11, + 12,11,13,13, 7, 8, 8, 9,10,10,10,11,11,12,12,12, + 13, 7, 8, 8,10,10,12,12,13,12,16,13,13,14, 7, 8, + 8,10,11,12,12,13,12,13,13,14,14, 8, 9,10,12,12, + 14,13,16,15,16,16,16,15, 8,10,10,12,12,14,13,14, + 15,16,16,15,16,10,11,12,14,14,14,14,16,13,16,15, + 16,16,10,11,12,13,13,15,14,14,15,16,16,14,14,13, + 14,13,15,16,16,16,15,15,16,16,16,16,11,15,14,16, + 16,14,14,16,15,16,14,16,15, +}; + +static float _vq_quantthresh__44u0__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u0__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_1 = { + _vq_quantthresh__44u0__p7_1, + _vq_quantmap__44u0__p7_1, + 13, + 13 +}; + +static static_codebook _44u0__p7_1 = { + 2, 169, + _vq_lengthlist__44u0__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u0__p7_1, + NULL, + &_vq_auxt__44u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p7_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 5, 5, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 5, 5, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 7, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 8, 9, + 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u0__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u0__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_2 = { + _vq_quantthresh__44u0__p7_2, + _vq_quantmap__44u0__p7_2, + 13, + 13 +}; + +static static_codebook _44u0__p7_2 = { + 2, 169, + _vq_lengthlist__44u0__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u0__p7_2, + NULL, + &_vq_auxt__44u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u0__short[] = { + 6,10,11,12,13,12,12,12, 4, 6, 6, 9, 9,10,11,13, + 3, 4, 3, 7, 6, 8,10,15, 5, 7, 7, 9, 8, 9,11,16, + 6, 7, 5, 8, 5, 7,10,16, 7, 8, 7, 9, 6, 7,10,16, + 10, 6, 3, 5, 4, 5, 7,16,13, 8, 5, 7, 6, 7,10,15, +}; + +static static_codebook _huff_book__44u0__short = { + 2, 64, + _huff_lengthlist__44u0__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u1__long[] = { + 4, 8,13,11,14,11,10,14, 6, 3, 5, 6, 8, 7, 9,14, + 12, 4, 3, 6, 5, 7,10,18,11, 6, 6, 6, 6, 6, 8,16, + 13, 7, 4, 6, 4, 6, 9,19,11, 6, 6, 5, 5, 5, 7,16, + 10, 8, 9, 7, 9, 6, 4,12,11,16,18,19,18,10, 7,11, +}; + +static static_codebook _huff_book__44u1__long = { + 2, 64, + _huff_lengthlist__44u1__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u1__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,13,14, 8,11,11, + 10,14,11,11,13,14, 4, 8, 8, 8,11,11, 8,11,11, 7, + 11,11,11,14,13,10,12,13, 8,11,11,11,14,14,11,14, + 13, +}; + +static float _vq_quantthresh__44u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p1_0 = { + _vq_quantthresh__44u1__p1_0, + _vq_quantmap__44u1__p1_0, + 3, + 3 +}; + +static static_codebook _44u1__p1_0 = { + 4, 81, + _vq_lengthlist__44u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u1__p1_0, + NULL, + &_vq_auxt__44u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u1__p2_0[] = { + 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 7, 8, 8, 5, 6, 6, 7, 8, + 8, 6, 8, 8, 7, 8, 8, 8, 9,10, 8, 9, 9, 6, 8, 8, + 7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10, 9, 7, 8, 9, 7, 8, 8, 8, 9, 9, 8,10, + 9, +}; + +static float _vq_quantthresh__44u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p2_0 = { + _vq_quantthresh__44u1__p2_0, + _vq_quantmap__44u1__p2_0, + 3, + 3 +}; + +static static_codebook _44u1__p2_0 = { + 4, 81, + _vq_lengthlist__44u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u1__p2_0, + NULL, + &_vq_auxt__44u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p3_0[] = { + 2, 5, 4, 7, 7, 5, 7, 7, 9, 8, 5, 7, 7, 8, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7,10,10, 7, 9, + 9,11,10, 7, 9, 9,10,10, 9,11,10,13,12, 9,10,10, + 12,13, 5, 7, 7,10, 9, 7, 9, 9,11,10, 7, 9, 9,10, + 11, 9,10,10,12,12,10,10,11,12,13, 8,10,10,14,13, + 9,11,11,15,13, 9,11,11,15,13,12,14,12,16,14,12, + 13,12,15,14, 8,10,10,13,14, 9,11,11,13,14,10,11, + 11,13,15,12,12,13,14,15,12,13,14,14,16, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14, + 14,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,12, + 9,11,11,13,13,12,12,12,14,14,11,12,13,15,15, 7, + 9, 9,12,11, 9,11,10,12,12, 9,11,11,12,13,11,12, + 11,14,14,11,12,12,15,16, 9,11,11,15,15,11,12,12, + 16,15,10,12,12,16,15,14,15,15,17,16,13,14,14,17, + 17, 9,11,11,14,15,10,12,11,15,15,10,12,12,15,17, + 13,14,13,16,15,13,14,15,17,17, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,12,10,11,11,14,14,10,11, + 11,13,14, 7, 9, 9,11,12, 9,11,11,13,13, 9,10,11, + 12,12,11,12,12,15,15,11,12,12,13,14, 7,10, 9,12, + 12, 9,11,11,13,13, 9,11,11,12,12,11,12,12,16,15, + 11,12,12,14,14, 9,11,11,15,14,10,12,12,16,15,10, + 11,12,15,15,13,14,14,17,18,13,13,14,15,16, 9,11, + 11,15,16,10,12,12,15,15,11,12,12,14,17,13,14,14, + 17,17,14,14,14,16,18, 7,10,10,14,15,10,12,12,16, + 15,10,11,12,16,16,14,16,15,18,17,13,15,14,17,19, + 9,11,12,16,15,11,13,13,17,16,10,13,13,16,16,15, + 16,16,17,19,13,15,15,17,17, 8,11,11,15,15,10,13, + 11,16,16,10,13,13,16,17,14,16,15,18,19,13,15,15, + 17,17,12,14,14,18,18,13,14,15,18,19,12,14,15,17, + 18,16,18,18,19, 0,14,15,16,18,18,11,14,13,17,18, + 12,16,14,19,19,12,15,14, 0,18,15,17,16,18,17,14, + 17,16,18,18, 7,10,10,15,14,10,12,11,16,16,10,11, + 12,16,16,13,15,14,19,18,14,15,16,18,18, 8,11,11, + 15,15,10,13,12,17,16,10,12,13,16,17,14,14,15,19, + 18,14,15,16,18, 0, 9,11,11,16,15,11,13,12,15,16, + 11,13,13,16,16,14,15,14, 0,17,15,16,16,19,18,11, + 14,14,18,17,12,14,15,17,17,12,13,15, 0,17,14,15, + 16,18,17,16,17,18,17,19,11,14,13,17,19,12,15,14, + 18,19,13,16,14, 0,19,14,17,15, 0,18,15,18,16, 0, + 0, +}; + +static float _vq_quantthresh__44u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p3_0 = { + _vq_quantthresh__44u1__p3_0, + _vq_quantmap__44u1__p3_0, + 5, + 5 +}; + +static static_codebook _44u1__p3_0 = { + 4, 625, + _vq_lengthlist__44u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p3_0, + NULL, + &_vq_auxt__44u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p4_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10,10,10,10,11,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11,10,10,10,12,11, 9,10,10,12,12, + 10,10,10,13,12, 9,10,10,12,12,12,12,12,14,14,11, + 12,12,13,14, 9,10,10,12,12, 9,10,10,13,12,10,10, + 10,12,13,12,12,12,14,13,12,12,12,14,14, 5, 7, 7, + 9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10,10,10,10,12, + 12,10,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,10,11, + 8, 8, 8,11,11,10,10,11,11,13,10,11,11,12,13, 6, + 7, 7,10,10, 7, 8, 8,11,10, 8, 8, 9,11,11,10,11, + 10,13,11,10,11,11,13,12,10,11,10,13,12,10,10,11, + 13,13,10,11,11,13,13,12,11,13,12,14,12,13,13,15, + 15, 9,10,10,12,13,10,11,10,13,13,10,11,11,13,14, + 12,13,11,14,12,12,13,13,14,15, 5, 7, 7, 9,10, 7, + 8, 7,10,10, 7, 7, 8,10,10,10,10,10,12,12,10,10, + 10,12,12, 6, 7, 7,10,10, 8, 9, 8,11,11, 7, 8, 8, + 10,11,10,11,11,12,13,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 8, 8,11,11, 8, 9, 8,11,10,10,11,10,13,12, + 10,11,10,13,12, 9,10,10,13,12,10,11,11,13,13, 9, + 10,10,12,13,13,13,13,15,14,12,11,13,12,15,10,10, + 11,12,13,10,11,11,13,13,10,11,10,13,13,12,13,13, + 15,15,12,13,11,14,12, 8,10, 9,12,12, 9,10,10,13, + 13, 9,10,10,13,13,13,13,13,14,15,12,12,12,14,14, + 9,10,10,13,12,10,11,11,13,13,10,11,11,13,12,13, + 13,14,14,16,12,13,13,15,14, 9,10,10,13,13,10,11, + 10,13,13,10,11,11,13,13,13,14,12,15,14,12,13,13, + 14,15,12,12,12,14,14,11,12,12,14,15,12,13,13,15, + 14,14,12,15,12,16,14,14,15,17,16,11,12,12,14,14, + 11,12,11,15,14,12,13,13,15,15,13,14,12,16,13,14, + 14,15,17,16, 8,10,10,12,12, 9,10,10,13,12,10,10, + 10,13,13,12,13,12,14,14,12,13,13,15,14, 9,10,10, + 13,13,10,11,11,13,13,10,10,11,12,13,13,13,13,15, + 15,12,12,13,14,15, 9,10,10,12,13,10,11,11,12,13, + 10,11,10,13,13,12,13,13,14,15,13,14,13,15,14,11, + 12,12,15,14,12,13,13,15,14,11,12,12,14,15,14,14, + 14,17,15,13,12,15,13,16,12,12,12,14,15,12,13,13, + 14,15,11,12,12,15,14,14,15,14,16,17,13,15,12,16, + 12, +}; + +static float _vq_quantthresh__44u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p4_0 = { + _vq_quantthresh__44u1__p4_0, + _vq_quantmap__44u1__p4_0, + 5, + 5 +}; + +static static_codebook _44u1__p4_0 = { + 4, 625, + _vq_lengthlist__44u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p4_0, + NULL, + &_vq_auxt__44u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u1__p5_0[] = { + 1, 4, 4, 7, 7, 8, 8,10,10, 4, 6, 5, 8, 8, 8, 8, + 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 7, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8, + 9, 9,10,11,12,12, 8, 8, 9, 9, 9,10,10,12,12,10, + 10,10,11,11,12,12,13,13,10,10,10,11,11,12,12,13, + 13, +}; + +static float _vq_quantthresh__44u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p5_0 = { + _vq_quantthresh__44u1__p5_0, + _vq_quantmap__44u1__p5_0, + 9, + 9 +}; + +static static_codebook _44u1__p5_0 = { + 2, 81, + _vq_lengthlist__44u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u1__p5_0, + NULL, + &_vq_auxt__44u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p6_0[] = { + 1, 4, 4, 7, 7, 9, 8,10, 9,11,10,14,13, 4, 5, 5, + 8, 8, 9, 9,11,11,11,11,14,14, 4, 5, 5, 8, 8, 9, + 9,10,11,11,11,14,14, 7, 8, 8, 9, 9,11,10,11,11, + 12,12,16,15, 7, 8, 8, 9, 9,10,11,11,11,12,12,15, + 15, 9,10,10,11,11,11,11,12,12,13,13,16,16, 9,10, + 10,11,11,11,11,12,12,12,13,16,15,10,11,11,11,11, + 12,12,13,13,13,13,16,17,10,11,11,11,11,12,12,12, + 12,13,14,16,16,11,12,12,12,12,13,13,14,14,14,15, + 18,17,11,12,12,12,12,13,13,13,14,14,15,18,18,15, + 14,15,15,15,16,16,17,17,18,17,20,20,14,15,15,15, + 15,16,17,17,16,18, 0,19, 0, +}; + +static float _vq_quantthresh__44u1__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u1__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p6_0 = { + _vq_quantthresh__44u1__p6_0, + _vq_quantmap__44u1__p6_0, + 13, + 13 +}; + +static static_codebook _44u1__p6_0 = { + 2, 169, + _vq_lengthlist__44u1__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u1__p6_0, + NULL, + &_vq_auxt__44u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u1__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p6_1 = { + _vq_quantthresh__44u1__p6_1, + _vq_quantmap__44u1__p6_1, + 5, + 5 +}; + +static static_codebook _44u1__p6_1 = { + 2, 25, + _vq_lengthlist__44u1__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p6_1, + NULL, + &_vq_auxt__44u1__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_0[] = { + 3, + 2, + 4, + 1, + 5, + 0, + 6, +}; + +static long _vq_lengthlist__44u1__p7_0[] = { + 1, 3, 3, 9, 9, 9, 9, 5, 7, 7, 9, 9, 9, 9, 5, 6, + 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u1__p7_0[] = { + -422.5, -253.5, -84.5, 84.5, 253.5, 422.5, +}; + +static long _vq_quantmap__44u1__p7_0[] = { + 5, 3, 1, 0, 2, 4, 6, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_0 = { + _vq_quantthresh__44u1__p7_0, + _vq_quantmap__44u1__p7_0, + 7, + 7 +}; + +static static_codebook _44u1__p7_0 = { + 2, 49, + _vq_lengthlist__44u1__p7_0, + 1, -518017024, 1626677248, 3, 0, + _vq_quantlist__44u1__p7_0, + NULL, + &_vq_auxt__44u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p7_1[] = { + 1, 4, 4, 6, 6, 6, 7, 8, 8, 9, 9,11,10, 4, 7, 7, + 8, 8, 8, 8, 9, 9,11,10,12,11, 4, 6, 7, 8, 8, 8, + 8,10,10,10,11,12,11, 7, 8, 8, 9, 9,10,10,11,11, + 12,12,13,13, 7, 8, 8, 9, 9,10,10,11,11,12,12,13, + 13, 7, 8, 8,10,10,13,12,13,13,16,13,13,14, 7, 8, + 8,10,11,12,12,13,13,14,14,14,14, 8,10,10,13,12, + 13,13,16,14,15,15,16,15, 8,10,11,12,13,13,13,13, + 16,15,16,16,14,10,12,13,14,15,15,14,14,14,15,16, + 15,16,10,11,12,13,13,15,15,16,16,16,14,16,16,12, + 13,13,15,14,15,14,15,15,14,15,16,16,11,14,14,15, + 14,16,15,16,14,15,16,14,15, +}; + +static float _vq_quantthresh__44u1__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u1__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_1 = { + _vq_quantthresh__44u1__p7_1, + _vq_quantmap__44u1__p7_1, + 13, + 13 +}; + +static static_codebook _44u1__p7_1 = { + 2, 169, + _vq_lengthlist__44u1__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u1__p7_1, + NULL, + &_vq_auxt__44u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p7_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 5, 6, 6, + 6, 7, 8, 7, 8, 8, 8, 9, 9, 9, 5, 6, 6, 7, 7, 8, + 8, 8, 8, 8, 8, 8, 9, 6, 7, 7, 7, 7, 8, 8, 8, 9, + 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, + 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 8, 9, + 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u1__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u1__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_2 = { + _vq_quantthresh__44u1__p7_2, + _vq_quantmap__44u1__p7_2, + 13, + 13 +}; + +static static_codebook _44u1__p7_2 = { + 2, 169, + _vq_lengthlist__44u1__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u1__p7_2, + NULL, + &_vq_auxt__44u1__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u1__short[] = { + 7,12,12,14,16,13,12,15, 6, 9,10,13,11,11,12,12, + 4, 5, 5, 8, 5, 7, 9,12, 6, 7, 8,10, 8, 9,11,16, + 5, 5, 4, 7, 4, 5, 7,15, 6, 5, 5, 8, 5, 5, 6,15, + 8, 7, 4, 7, 3, 4, 5,16,15,11, 6, 8, 5, 6, 8,16, +}; + +static static_codebook _huff_book__44u1__short = { + 2, 64, + _huff_lengthlist__44u1__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u2__long[] = { + 8,14,15,15,17,15,12,13,13, 3, 4, 7, 8, 7, 8,11, + 20, 4, 3, 6, 5, 7, 9,16,15, 6, 5, 6, 6, 6, 8,15, + 20, 7, 4, 6, 4, 5, 8,18,16, 7, 6, 6, 5, 5, 6,14, + 11, 7, 8, 7, 7, 5, 4,10,10,13,15,16,19,10, 6,10, +}; + +static static_codebook _huff_book__44u2__long = { + 2, 64, + _huff_lengthlist__44u2__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u2__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,13,13, 8,11,11, + 10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,11, 7, + 11,11,11,14,13,10,12,13, 8,11,11,11,14,13,11,13, + 13, +}; + +static float _vq_quantthresh__44u2__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u2__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p1_0 = { + _vq_quantthresh__44u2__p1_0, + _vq_quantmap__44u2__p1_0, + 3, + 3 +}; + +static static_codebook _44u2__p1_0 = { + 4, 81, + _vq_lengthlist__44u2__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u2__p1_0, + NULL, + &_vq_auxt__44u2__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u2__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 7, 6, 7, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 8, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 8, 6, 7, 8, 6, + 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u2__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u2__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p2_0 = { + _vq_quantthresh__44u2__p2_0, + _vq_quantmap__44u2__p2_0, + 3, + 3 +}; + +static static_codebook _44u2__p2_0 = { + 4, 81, + _vq_lengthlist__44u2__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u2__p2_0, + NULL, + &_vq_auxt__44u2__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p3_0[] = { + 2, 4, 4, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 9, 9,12,12, 8, 9,10,11,12, 5, 7, 7,10,10, 7, 9, + 9,11,10, 7, 8, 9,10,11,10,11,10,14,13, 9,10,10, + 12,13, 5, 7, 7,10,10, 7, 9, 8,11,10, 7, 9, 9,11, + 11, 9,10,10,13,12,10,10,11,13,13, 8,10,10,15,13, + 10,11,11,15,13, 9,11,11,14,13,13,14,13,17,15,12, + 13,13,15,15, 8,10,10,13,14, 9,11,11,13,14,10,11, + 12,13,16,12,13,13,15,15,13,13,14,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14, + 14,10,11,12,14,14, 7, 9, 9,12,12, 9,11,11,13,12, + 9,11,11,13,13,12,13,12,14,14,11,12,12,15,14, 7, + 9, 9,12,11, 9,11,10,13,11, 9,11,11,12,13,11,12, + 11,14,13,11,12,12,15,15,10,12,12,16,15,11,13,13, + 16,16,10,12,12,16,16,14,14,14,17,16,13,14,14,17, + 18, 9,11,11,14,15,10,12,11,15,15,10,12,12,15,17, + 13,15,13,17,16,13,14,15,17,19, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,11,10,11,11,15,14,10,11, + 12,13,14, 7, 9, 9,12,12, 9,11,11,13,12, 8,10,11, + 12,12,11,12,12,15,15,11,11,12,14,14, 7, 9, 9,12, + 12, 9,11,11,13,13, 9,11,11,12,12,11,12,12,16,15, + 11,12,13,14,14, 9,11,11,16,15,10,12,12,16,15,10, + 11,12,14,14,13,14,15,18,17,13,13,14,16,16,10,12, + 12,15,15,10,13,12,15,17,11,13,12,15,16,13,15,14, + 17,18,14,15,14,15,17, 8,10,10,15,15,10,12,12,17, + 15,10,12,12,17,16,14,16,15,17,17,13,14,15,16,16, + 9,11,12,16,16,11,13,13,16,17,11,13,13,16,16,15, + 16,16, 0, 0,14,15,15,19,17, 9,11,11,17,16,10,13, + 11,16,16,11,12,12,16,17,15,16,15,19,19,14,16,15, + 0,18,12,14,15, 0, 0,14,15,16,18,18,13,14,15,17, + 17,16,18,18, 0, 0,15,16,16,19,18,11,14,13, 0,18, + 13,16,13,17,17,13,15,14, 0, 0,17,17,15,19,18,14, + 16,16,19, 0, 8,10,10,15,15,10,12,11,16,16,10,11, + 12,17,16,14,15,15,17,18,15,15,16, 0, 0, 9,11,11, + 15,15,11,13,12,16,18,10,12,13,17,17,13,15,15,17, + 19,15,15,16,19,18, 9,12,11, 0,16,11,13,12,16,16, + 11,13,13,16,17,14,16,15,19,19,15,15,16,18,18,12, + 14,14,17,18,13,14,15,18, 0,13,14,15,18,19,15,17, + 16, 0,19,16,15,18,17,19,12,14,14,19,19,13,15,15, + 0,18,13,17,15,18,18,15,16,17, 0,19,17,19,18,18, + 0, +}; + +static float _vq_quantthresh__44u2__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p3_0 = { + _vq_quantthresh__44u2__p3_0, + _vq_quantmap__44u2__p3_0, + 5, + 5 +}; + +static static_codebook _44u2__p3_0 = { + 4, 625, + _vq_lengthlist__44u2__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p3_0, + NULL, + &_vq_auxt__44u2__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p4_0[] = { + 4, 5, 5, 9, 9, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 9, + 10, 9,12,11, 9, 9,10,11,12, 6, 7, 7,10,10, 7, 8, + 7,10,10, 7, 7, 8,10,10,10,10,10,12,12, 9,10,10, + 11,12, 6, 7, 7,10,10, 7, 8, 7,10,10, 7, 7, 7,10, + 10, 9,10,10,12,11,10,10,10,12,12, 9,10,10,13,12, + 10,10,10,13,13,10,10,10,13,12,12,12,12,14,14,12, + 12,12,14,14, 9,10,10,12,13, 9,10,10,13,13,10,10, + 10,13,13,12,12,12,15,14,12,13,12,14,14, 5, 7, 7, + 10,10, 7, 8, 7,10,10, 7, 7, 8,10,10,10,10,10,12, + 12,10,10,10,12,12, 7, 8, 8,10,10, 8, 8, 8,10,11, + 8, 8, 8,11,10,10,10,11,11,13,10,10,11,12,13, 6, + 7, 7,10,10, 7, 8, 7,11,10, 8, 8, 8,10,11,10,11, + 10,13,11,10,10,10,13,12,10,11,10,13,13,10,10,10, + 12,13,10,11,11,13,13,12,11,13,11,14,12,13,13,14, + 14, 9,10,10,12,13,10,10,10,13,12,10,10,11,13,13, + 12,13,11,14,12,13,13,13,15,14, 5, 7, 7,10,10, 7, + 7, 7,10,10, 7, 7, 8,10,10,10,10,10,12,12,10,10, + 10,12,13, 6, 7, 7,10,10, 8, 8, 8,11,10, 7, 7, 8, + 10,11,10,10,10,12,12,10,10,11,11,13, 7, 8, 8,10, + 10, 7, 8, 8,10,11, 8, 8, 8,11,10,10,11,10,13,12, + 10,11,10,13,11, 9,10,10,13,13,10,11,11,13,13,10, + 10,10,12,13,13,13,13,14,14,12,11,13,12,14,10,10, + 11,13,13,10,11,11,13,13,10,10,10,13,12,12,13,13, + 14,14,12,13,11,15,12, 9,10,10,13,13,10,10,10,13, + 13,10,10,10,13,13,13,13,13,15,15,12,13,13,14,14, + 9,10,10,13,13,10,10,11,13,13,10,11,10,13,12,13, + 12,13,14,15,13,13,13,15,14, 9,10,10,13,13,10,10, + 10,13,12,10,10,11,12,13,13,13,12,15,14,13,13,13, + 14,14,12,13,12,15,14,12,11,12,14,14,12,13,12,15, + 14,14,12,15,12,16,14,14,15,16,16,12,12,12,14,15, + 11,12,11,15,14,12,13,13,14,15,14,14,12,16,13,14, + 14,15,16,16, 9,10,10,13,13,10,10,10,13,13,10,10, + 10,13,13,12,13,12,14,14,13,13,13,15,15, 9,10,10, + 13,13,10,11,10,13,12,10,10,10,12,13,13,13,13,14, + 14,12,12,13,14,15, 9,10,10,13,13,10,10,11,12,13, + 10,11,10,13,13,13,13,13,14,15,13,13,13,15,14,12, + 12,12,15,14,12,13,12,15,14,11,11,12,14,15,14,14, + 14,17,16,14,12,14,13,17,12,12,13,14,16,13,13,13, + 13,15,12,12,11,14,14,14,15,14,16,16,14,14,12,16, + 12, +}; + +static float _vq_quantthresh__44u2__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p4_0 = { + _vq_quantthresh__44u2__p4_0, + _vq_quantmap__44u2__p4_0, + 5, + 5 +}; + +static static_codebook _44u2__p4_0 = { + 4, 625, + _vq_lengthlist__44u2__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p4_0, + NULL, + &_vq_auxt__44u2__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u2__p5_0[] = { + 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 4, 7, 7, 8, 7, + 9, 9, 4, 4, 4, 7, 7, 7, 8, 9, 9, 6, 7, 7, 8, 8, + 8, 9,10,10, 6, 7, 7, 8, 8, 9, 8,10,10, 7, 8, 7, + 8, 9, 9,10,11,11, 7, 7, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9, 9,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u2__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u2__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p5_0 = { + _vq_quantthresh__44u2__p5_0, + _vq_quantmap__44u2__p5_0, + 9, + 9 +}; + +static static_codebook _44u2__p5_0 = { + 2, 81, + _vq_lengthlist__44u2__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u2__p5_0, + NULL, + &_vq_auxt__44u2__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9,10,11,11,14,14, 4, 6, 5, + 8, 8, 9, 9,11,11,11,11,14,14, 4, 5, 5, 8, 8, 9, + 9,10,11,11,12,14,14, 7, 8, 8, 9, 9,11,10,11,11, + 12,12,15,15, 7, 8, 8, 9, 9,11,11,11,11,12,12,15, + 14, 9,10,10,11,11,11,11,12,12,13,12,16,16, 9,10, + 10,11,11,11,11,12,12,13,13,15,16,10,11,11,11,11, + 12,12,13,13,13,13,17,16,10,11,11,12,12,12,12,12, + 13,14,14,16,16,11,12,12,12,12,13,13,14,14,14,14, + 17,17,11,12,12,12,12,13,13,14,14,15,14,18,17,15, + 14,15,15,15,16,16,17,18,19,17,19, 0,15,15,15,15, + 15,16,17,16,16,18,17, 0, 0, +}; + +static float _vq_quantthresh__44u2__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u2__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p6_0 = { + _vq_quantthresh__44u2__p6_0, + _vq_quantmap__44u2__p6_0, + 13, + 13 +}; + +static static_codebook _44u2__p6_0 = { + 2, 169, + _vq_lengthlist__44u2__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u2__p6_0, + NULL, + &_vq_auxt__44u2__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u2__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p6_1 = { + _vq_quantthresh__44u2__p6_1, + _vq_quantmap__44u2__p6_1, + 5, + 5 +}; + +static static_codebook _44u2__p6_1 = { + 2, 25, + _vq_lengthlist__44u2__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p6_1, + NULL, + &_vq_auxt__44u2__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u2__p7_0[] = { + 1, 3, 3,10,10,10,10,10,10, 4,10,10,10,10,10,10, + 10,10, 4,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44u2__p7_0[] = { + -591.5, -422.5, -253.5, -84.5, 84.5, 253.5, 422.5, 591.5, +}; + +static long _vq_quantmap__44u2__p7_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_0 = { + _vq_quantthresh__44u2__p7_0, + _vq_quantmap__44u2__p7_0, + 9, + 9 +}; + +static static_codebook _44u2__p7_0 = { + 2, 81, + _vq_lengthlist__44u2__p7_0, + 1, -516612096, 1626677248, 4, 0, + _vq_quantlist__44u2__p7_0, + NULL, + &_vq_auxt__44u2__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p7_1[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9,10,10, 4, 7, 6, + 8, 8, 8, 8,10, 9,11,10,12,12, 4, 6, 7, 8, 8, 8, + 8,10,10,11,11,12,12, 7, 8, 8,10, 9,10,10,12,11, + 13,12,13,13, 7, 8, 8, 9, 9,10,10,11,11,13,13,14, + 15, 7, 8, 9,10,10,12,11,14,13,13,14,14,15, 7, 8, + 9,10,10,11,12,13,13,15,14,14,15, 8,10,10,12,11, + 13,13,15,15,15,17,15,15, 8,10,10,11,12,14,13,14, + 15,17,15,15,15,10,11,11,14,13,14,14,15,15,17,17, + 16,17,10,11,12,13,13,14,14,14,15,16,15,15,17,11, + 12,13,14,13,16,16,16,14,17,16,17,17,11,12,13,15, + 15,15,15,16,15,15,15,15,17, +}; + +static float _vq_quantthresh__44u2__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u2__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_1 = { + _vq_quantthresh__44u2__p7_1, + _vq_quantmap__44u2__p7_1, + 13, + 13 +}; + +static static_codebook _44u2__p7_1 = { + 2, 169, + _vq_lengthlist__44u2__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u2__p7_1, + NULL, + &_vq_auxt__44u2__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p7_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 5, 6, 6, 7, 7, 8, + 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u2__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u2__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_2 = { + _vq_quantthresh__44u2__p7_2, + _vq_quantmap__44u2__p7_2, + 13, + 13 +}; + +static static_codebook _44u2__p7_2 = { + 2, 169, + _vq_lengthlist__44u2__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u2__p7_2, + NULL, + &_vq_auxt__44u2__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u2__short[] = { + 16,15,15,16,14,16,16,16,16, 9, 8,11,10,10,10,15, + 16, 6, 3, 7, 5, 7, 9,16,16,11, 7,11, 9,10,12,16, + 16, 9, 4, 8, 3, 5, 8,16,16,11, 6, 9, 4, 4, 7,16, + 16,11, 5, 9, 3, 3, 5,12,16,15, 6,11, 5, 5, 6,14, +}; + +static static_codebook _huff_book__44u2__short = { + 2, 64, + _huff_lengthlist__44u2__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u3__long[] = { + 7,11,14,13,14,12,12,12,12, 2, 5, 8, 9, 8, 9,11, + 17, 4, 3, 6, 5, 7, 9,15,14, 6, 6, 7, 7, 7, 8,14, + 17, 8, 5, 7, 4, 5, 7,15,13, 7, 6, 7, 5, 5, 6,14, + 10, 8, 8, 7, 7, 5, 4, 9,10,12,15,14,16,10, 6, 9, +}; + +static static_codebook _huff_book__44u3__long = { + 2, 64, + _huff_lengthlist__44u3__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u3__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,13,14, 7,11,11, + 10,13,11,11,13,14, 4, 8, 8, 8,11,11, 8,11,11, 8, + 11,11,11,14,14,10,12,14, 8,11,11,11,14,13,11,14, + 13, +}; + +static float _vq_quantthresh__44u3__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u3__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p1_0 = { + _vq_quantthresh__44u3__p1_0, + _vq_quantmap__44u3__p1_0, + 3, + 3 +}; + +static static_codebook _44u3__p1_0 = { + 4, 81, + _vq_lengthlist__44u3__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u3__p1_0, + NULL, + &_vq_auxt__44u3__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u3__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 7, 6, 8, 8, 6, 8, 8, 8, 8, 9, 8, 9, 9, 6, 8, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 8, 6, 8, 8, 6, + 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 8, +}; + +static float _vq_quantthresh__44u3__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u3__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p2_0 = { + _vq_quantthresh__44u3__p2_0, + _vq_quantmap__44u3__p2_0, + 3, + 3 +}; + +static static_codebook _44u3__p2_0 = { + 4, 81, + _vq_lengthlist__44u3__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u3__p2_0, + NULL, + &_vq_auxt__44u3__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p3_0[] = { + 2, 4, 4, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 10, 9,12,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9, + 9,11,11, 7, 8, 9,10,11,10,11,10,14,13, 9,10,11, + 13,13, 5, 7, 7,10,10, 7, 9, 8,11,10, 7, 9, 9,11, + 11, 9,10,10,13,12,10,10,11,13,14, 8,10,10,14,13, + 10,11,11,15,13, 9,11,11,14,13,13,14,13,17,15,12, + 13,13,17,14, 8,10,10,14,14, 9,11,11,14,15,10,11, + 12,14,16,12,13,13,14,17,13,13,14,14,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,15, + 14,10,11,11,15,14, 7, 9, 9,12,12, 9,11,11,13,13, + 9,11,11,13,13,11,12,12,15,14,11,12,12,15,16, 7, + 9, 9,12,11, 8,11,10,13,12, 9,11,11,12,13,11,12, + 11,16,14,11,12,13,15,16,10,12,12,17,15,11,12,13, + 16,15,11,12,12,16,16,15,15,15,16,16,13,14,15, 0, + 17, 9,11,11,15,15,10,12,11,16,15,11,12,12,15,17, + 13,15,13,16,15,13,15,14, 0,18, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,11,10,11,11,14,14,10,11, + 11,14,15, 7, 9, 9,12,11, 9,11,11,13,12, 8,10,11, + 11,12,11,12,12,16,15,11,11,12,13,14, 7, 9, 9,12, + 12, 9,11,11,13,13, 9,11,11,13,13,11,12,12,16,15, + 12,12,12,15,15, 9,11,11,17,15,11,12,12,17,16,10, + 11,12,15,15,13,14,15,18,17,13,13,14,15,15, 9,12, + 12,15,14,11,13,12,16,16,11,12,12,15,15,13,15,14, + 0, 0,14,15,14,16,18, 8,10,10,15,15,10,12,12,16, + 14,10,11,11,16,16,15,16,16,18,16,13,15,14,17,18, + 9,11,11,16,15,11,12,13,17,17,11,13,13,16,15,15, + 16,16,18,18,14,16,15,18,17, 9,11,11,16,16,10,13, + 12,16,16,11,12,12,16,16,14,16,16,17, 0,14,15,15, + 18,16,12,14,14, 0, 0,14,15,16, 0, 0,14,15,15, 0, + 0,17,17,16, 0, 0,15,16,18,17, 0,11,14,14,18, 0, + 12,15,13, 0,18,13,15,14,18, 0,15,16,15, 0,18,15, + 18,17, 0,18, 8,10,10,15,15,10,12,11,15,15,10,11, + 12,15,15,13,14,15,17, 0,14,15,16,17, 0, 9,11,11, + 15,15,11,12,12,17,15,10,12,13,16,15,13,15,15,18, + 18,15,16,17,18,18, 9,12,11,16,16,11,13,13,16,16, + 11,13,13,18,15,14,15,15,18, 0,16,16,17, 0,17,12, + 13,13,18,18,13,14,14,17,18,13,14,15,18,17,17,18, + 18, 0,18,16,16,18,16, 0,12,15,13,18,18,13,14,15, + 18,18,13,16,14,17,18,15,17,16, 0,18,17, 0,17, 0, + 0, +}; + +static float _vq_quantthresh__44u3__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p3_0 = { + _vq_quantthresh__44u3__p3_0, + _vq_quantmap__44u3__p3_0, + 5, + 5 +}; + +static static_codebook _44u3__p3_0 = { + 4, 625, + _vq_lengthlist__44u3__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p3_0, + NULL, + &_vq_auxt__44u3__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p4_0[] = { + 4, 6, 6, 9, 9, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 9, + 10, 9,12,11, 9, 9,10,11,12, 6, 7, 7, 9, 9, 7, 7, + 7,10,10, 6, 7, 7, 9,10,10,10,10,12,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 7, 7,10, 9, 7, 7, 7,10, + 10, 9,10, 9,12,11,10,10,10,12,12, 9,10,10,12,12, + 10,10,10,13,12, 9,10,10,12,12,12,12,12,14,14,12, + 12,12,13,14, 9,10,10,12,12, 9,10,10,12,12,10,10, + 10,12,13,11,12,12,14,13,12,12,12,14,14, 6, 7, 7, + 10, 9, 7, 8, 7,10,10, 7, 7, 7,10,10,10,10,10,12, + 12,10,10,10,12,12, 7, 8, 8,10,10, 8, 8, 8,10,10, + 7, 8, 8,10,10,10,10,11,11,13,10,10,11,12,13, 6, + 7, 7,10,10, 7, 8, 7,10,10, 8, 8, 8,10,10,10,11, + 10,13,11,10,10,10,12,12,10,10,10,13,12,10,10,10, + 12,13,10,10,10,13,12,12,11,13,12,14,12,12,13,14, + 14, 9,10,10,12,13, 9,10,10,12,12,10,10,11,12,13, + 12,12,11,14,12,12,12,13,14,14, 6, 7, 7, 9, 9, 7, + 7, 7,10,10, 7, 7, 8,10,10,10,10,10,12,12,10,10, + 10,12,12, 6, 7, 7,10,10, 8, 8, 8,10,10, 7, 7, 8, + 10,10,10,10,10,12,12,10,10,11,11,13, 7, 8, 8,10, + 10, 7, 8, 8,10,10, 8, 8, 8,10,10,10,10,10,12,12, + 10,11,10,13,11, 9,10,10,13,12,10,11,10,13,12, 9, + 10,10,12,13,12,13,12,14,14,12,11,12,12,14,10,10, + 10,12,13,10,10,11,12,13,10,10,10,12,12,12,13,12, + 14,14,12,12,11,14,12, 9,10, 9,12,12,10,10,10,13, + 13, 9,10,10,13,13,12,13,13,15,14,12,12,13,14,14, + 9,10,10,13,13,10,10,10,12,13,10,10,10,13,12,13, + 12,13,14,15,12,13,13,15,14, 9,10,10,13,12,10,10, + 10,13,12,10,10,10,12,13,12,13,12,14,14,13,12,12, + 14,14,12,12,12,15,14,12,11,12,14,14,12,13,12,14, + 14,14,12,14,12,16,14,14,14,16,16,11,12,12,14,14, + 11,12,11,15,13,12,12,12,14,15,13,14,12,16,13,14, + 14,15,16,16, 9,10,10,12,12, 9,10,10,13,12, 9,10, + 10,13,13,12,12,12,14,14,12,13,13,14,15, 9,10,10, + 13,12,10,11,10,13,12,10,10,10,12,13,12,13,12,14, + 14,12,12,13,14,15, 9,10,10,13,13,10,10,10,12,13, + 10,10,10,13,13,12,13,13,14,15,13,13,12,14,14,11, + 12,12,14,14,12,13,12,15,14,11,11,12,14,15,14,14, + 14,16,16,14,12,14,13,16,12,12,12,14,15,12,12,13, + 14,15,12,12,11,14,14,14,14,14,16,16,14,14,12,16, + 12, +}; + +static float _vq_quantthresh__44u3__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p4_0 = { + _vq_quantthresh__44u3__p4_0, + _vq_quantmap__44u3__p4_0, + 5, + 5 +}; + +static static_codebook _44u3__p4_0 = { + 4, 625, + _vq_lengthlist__44u3__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p4_0, + NULL, + &_vq_auxt__44u3__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u3__p5_0[] = { + 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 4, 7, 6, 8, 8, + 9, 9, 4, 4, 4, 6, 7, 8, 8, 9, 9, 6, 7, 6, 8, 8, + 9, 9,10,10, 6, 6, 7, 8, 8, 9, 9,10,10, 8, 8, 8, + 9, 9,10,10,11,11, 8, 8, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9,10,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u3__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u3__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p5_0 = { + _vq_quantthresh__44u3__p5_0, + _vq_quantmap__44u3__p5_0, + 9, + 9 +}; + +static static_codebook _44u3__p5_0 = { + 2, 81, + _vq_lengthlist__44u3__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u3__p5_0, + NULL, + &_vq_auxt__44u3__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u3__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9,10,10,11,13,14, 4, 6, 5, + 8, 8, 9, 9,10,10,11,11,14,14, 4, 5, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 7, 8, 8, 9, 9,10,10,11,11, + 12,12,15,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,14, + 15, 8, 9, 9,10,10,11,11,12,12,13,12,16,16, 8, 9, + 9,10,10,11,11,12,12,12,12,16,16,10,11,10,11,11, + 12,12,13,13,13,13,17,16,10,11,11,11,11,12,12,12, + 12,13,13,17,17,11,11,12,12,12,13,13,13,14,14,14, + 16,17,11,12,11,12,12,13,13,14,14,14,14,19,17,14, + 14,14,16,15,16,16,16,17,17,17,20,19,14,15,15,15, + 15,15,16,16,17,17,17,20,19, +}; + +static float _vq_quantthresh__44u3__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u3__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p6_0 = { + _vq_quantthresh__44u3__p6_0, + _vq_quantmap__44u3__p6_0, + 13, + 13 +}; + +static static_codebook _44u3__p6_0 = { + 2, 169, + _vq_lengthlist__44u3__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u3__p6_0, + NULL, + &_vq_auxt__44u3__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u3__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p6_1 = { + _vq_quantthresh__44u3__p6_1, + _vq_quantmap__44u3__p6_1, + 5, + 5 +}; + +static static_codebook _44u3__p6_1 = { + 2, 25, + _vq_lengthlist__44u3__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p6_1, + NULL, + &_vq_auxt__44u3__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u3__p7_0[] = { + 1, 4, 4, 9, 9, 9, 9, 9, 9, 4, 9, 9, 9, 9, 9, 9, + 9, 9, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u3__p7_0[] = { + -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, 637.5, 892.5, +}; + +static long _vq_quantmap__44u3__p7_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_0 = { + _vq_quantthresh__44u3__p7_0, + _vq_quantmap__44u3__p7_0, + 9, + 9 +}; + +static static_codebook _44u3__p7_0 = { + 2, 81, + _vq_lengthlist__44u3__p7_0, + 1, -515907584, 1627381760, 4, 0, + _vq_quantlist__44u3__p7_0, + NULL, + &_vq_auxt__44u3__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u3__p7_1[] = { + 1, 4, 4, 6, 5, 7, 7, 9, 8,10,10,11,11,12,13, 4, + 7, 6, 7, 7, 9, 9,10,10,11,11,14,13,14,13, 4, 6, + 7, 7, 8, 9, 9,10,10,12,12,13,13,13,13, 6, 8, 8, + 10, 9,11,11,12,12,13,13,14,14,15,14, 6, 8, 8, 9, + 9,11,11,12,12,14,14,14,15,15,15, 8, 9, 9,11,10, + 13,12,14,14,14,14,15,16,15,15, 8, 9, 9,11,11,12, + 12,14,14,15,14,15,15,14,17, 9,10,10,13,12,14,14, + 15,14,14,17,15,15,16,15, 9,11,11,12,13,14,14,15, + 15,15,16,15,17,16,17,11,12,12,14,14,15,14,16,16, + 16,15,15,17,16,16,11,12,13,14,15,15,15,15,15,16, + 16,17,17,16,17,12,13,13,15,14,15,15,15,15,16,16, + 16,17,17,17,13,12,14,14,15,15,15,15,16,17,17,15, + 17,17,17,12,14,14,16,15,17,16,17,16,17,16,17,17, + 17,17,14,13,14,15,16,17,17,17,15,17,17,17,16,17, + 16, +}; + +static float _vq_quantthresh__44u3__p7_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u3__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_1 = { + _vq_quantthresh__44u3__p7_1, + _vq_quantmap__44u3__p7_1, + 15, + 15 +}; + +static static_codebook _44u3__p7_1 = { + 2, 225, + _vq_lengthlist__44u3__p7_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u3__p7_1, + NULL, + &_vq_auxt__44u3__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u3__p7_2[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9,10, 9, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 9, 9,10, 9,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9,10,10, 9,10, 9,10,10,10,10,10,10,10,10,10,10, + 9,10, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u3__p7_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u3__p7_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_2 = { + _vq_quantthresh__44u3__p7_2, + _vq_quantmap__44u3__p7_2, + 17, + 17 +}; + +static static_codebook _44u3__p7_2 = { + 2, 289, + _vq_lengthlist__44u3__p7_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u3__p7_2, + NULL, + &_vq_auxt__44u3__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u3__short[] = { + 17,17,17,17,17,17,16,16,16,12,11,13,11,12,11,15, + 16, 9, 4, 8, 5, 7, 9,15,16,14, 9,12,10,10,12,16, + 16,11, 4, 9, 3, 4, 8,16,16,12, 6,10, 3, 4, 7,16, + 16,12, 6,11, 3, 3, 4,12,16,16, 7,13, 5, 5, 6,13, +}; + +static static_codebook _huff_book__44u3__short = { + 2, 64, + _huff_lengthlist__44u3__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u4__long[] = { + 3, 7,11,11,12,11,11,12, 5, 3, 5, 7, 8, 8, 9,11, + 9, 4, 4, 6, 6, 7, 9,15,10, 6, 6, 7, 7, 7, 8,14, + 12, 7, 5, 6, 4, 5, 7,15,10, 7, 6, 7, 5, 5, 6,13, + 9, 8, 8, 7, 7, 5, 4, 8,10,12,14,13,14,10, 5, 7, +}; + +static static_codebook _huff_book__44u4__long = { + 2, 64, + _huff_lengthlist__44u4__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u4__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,14,14, 7,11,10, + 10,14,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 8, + 11,11,11,14,14,10,12,14, 8,11,11,11,14,14,11,14, + 13, +}; + +static float _vq_quantthresh__44u4__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u4__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p1_0 = { + _vq_quantthresh__44u4__p1_0, + _vq_quantmap__44u4__p1_0, + 3, + 3 +}; + +static static_codebook _44u4__p1_0 = { + 4, 81, + _vq_lengthlist__44u4__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u4__p1_0, + NULL, + &_vq_auxt__44u4__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u4__p2_0[] = { + 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 7, 8, 8, 5, 6, 6, 7, 8, + 8, 6, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10, 9, 8, 8, 9, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u4__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u4__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p2_0 = { + _vq_quantthresh__44u4__p2_0, + _vq_quantmap__44u4__p2_0, + 3, + 3 +}; + +static static_codebook _44u4__p2_0 = { + 4, 81, + _vq_lengthlist__44u4__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u4__p2_0, + NULL, + &_vq_auxt__44u4__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p3_0[] = { + 2, 4, 4, 7, 7, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 10, 9,12,12, 8, 9, 9,12,12, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 7, 8, 9,10,11,10,11,11,13,13, 9,10,11, + 13,13, 5, 7, 7, 9,10, 7, 9, 9,11,11, 7, 9, 9,11, + 11, 9,11,10,13,12,10,11,11,13,13, 8,10,10,13,13, + 10,11,11,15,13, 9,11,11,14,13,13,15,13,16,15,12, + 13,13,15,15, 8,10,10,13,14, 9,11,11,14,14,10,11, + 12,14,16,12,13,13,14,16,13,14,14,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,15, + 14,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13, + 9,11,11,13,13,11,12,13,15,15,11,13,13,16,15, 7, + 9, 9,11,11, 9,11,10,13,12, 9,11,12,13,13,11,13, + 12,16,14,11,13,13,15,16,10,12,12,18,15,11,12,13, + 16,15,11,13,13,17,16,15,15,15,17,17,14,15,16,18, + 19, 9,11,11,15,15,10,12,11,15,16,11,13,13,15,16, + 13,15,13,18,15,14,15,15,17,19, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,12,10,12,11,14,14,10,11, + 12,14,15, 7, 9, 9,11,11, 9,11,11,13,12, 9,10,11, + 12,13,11,13,13,16,17,11,11,13,14,15, 7, 9, 9,12, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,12,15,16, + 11,13,13,16,15, 9,11,11,16,15,11,13,12,16,15,10, + 12,12,16,15,14,15,16,19,17,13,14,15,15,16,10,11, + 12,15,15,11,13,13,16,16,11,13,12,16,17,14,15,15, + 18,17,14,16,14,16,19, 7,10,10,15,14,10,12,12,16, + 15,10,11,11,16,15,14,16,16,19,18,13,15,14,17,17, + 9,11,11,17,16,11,13,14,18,17,11,13,13,16,16,15, + 16,17,19, 0,14,15,18,16,19, 9,11,11,16,15,11,13, + 12,18,16,11,13,13,17,16,14,16,16,17,19,15,16,15, + 18, 0,12,14,15,18,19,13,15,16,19,17,14,16,15,18, + 0,17,16,19, 0,18,16,17,18, 0, 0,11,13,14,18,19, + 13,15,13,19,19,14,15,15,17,17,15,17,15,19,17,16, + 18,18,19, 0, 8,10,10,14,14,10,12,11,15,15,10,11, + 12,15,17,13,15,15,17,16,14,15,15,18, 0, 9,11,11, + 15,15,11,13,13,18,16,10,12,13,16,17,14,15,16,17, + 18,14,15,17,19,19, 9,12,12,15,16,11,13,13,16,17, + 11,14,13,19,16,14,16,15,18,19,15,16,18,19,18,12, + 14,14,19,18,13,15,17,18,17,13,14,15,18, 0,16, 0, + 0,18,18,16,15, 0,17,19,12,15,14,17, 0,13,15,16, + 19,18,13,16,15, 0,19,16,18,16,19,18,17,19,16, 0, + 19, +}; + +static float _vq_quantthresh__44u4__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p3_0 = { + _vq_quantthresh__44u4__p3_0, + _vq_quantmap__44u4__p3_0, + 5, + 5 +}; + +static static_codebook _44u4__p3_0 = { + 4, 625, + _vq_lengthlist__44u4__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p3_0, + NULL, + &_vq_auxt__44u4__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p4_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 9, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 9, 9, 9,12,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11, + 11,12,13,14, 9, 9, 9,11,12, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,14,13,11,12,12,13,13, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 7, 8,10,10, 9,10,10,12, + 12, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,10,11, + 8, 9, 9,11,11,10,10,11,11,13,10,10,11,12,13, 6, + 7, 8,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11, + 10,13,11,10,11,11,13,12, 9,10,10,12,12,10,10,11, + 12,13,10,11,11,13,13,12,11,13,12,15,12,13,13,14, + 14, 9,10,10,12,12, 9,11,10,13,12,10,11,11,13,13, + 11,13,11,14,12,12,13,13,14,15, 5, 7, 7, 9, 9, 7, + 8, 7,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10, + 10,12,12, 6, 8, 7,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,11,11,12,13,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,10,11, 8, 9, 8,11,10,10,11,11,13,12, + 10,11,10,13,11, 9,10,10,13,12,10,11,11,13,13, 9, + 10,10,12,13,12,13,13,15,14,11,11,13,12,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,10,13,12,12,13,13, + 14,14,12,13,11,15,12, 8, 9, 9,12,12, 9,10,10,13, + 12, 9,10,10,12,12,12,13,12,14,14,11,12,12,14,13, + 9,10,10,12,12,10,10,11,13,13,10,11,11,13,12,12, + 13,13,14,15,12,13,13,15,14, 9,10,10,12,12, 9,11, + 10,13,12,10,10,11,12,13,12,13,12,15,14,12,13,13, + 14,14,11,12,12,14,13,11,11,12,13,14,12,13,13,15, + 14,13,12,14,12,16,14,15,14,16,16,11,12,12,14,14, + 11,12,11,15,13,12,13,13,14,15,13,14,12,16,13,14, + 14,15,16,16, 8, 9, 9,12,12, 9,10,10,12,12, 9,10, + 10,12,13,11,12,12,14,13,12,12,13,14,14, 9,10,10, + 12,12,10,11,11,13,12,10,10,11,12,13,12,13,13,14, + 14,12,12,13,14,15, 9,10,10,12,13,10,11,11,12,13, + 10,11,10,13,13,12,13,13,14,15,12,13,13,15,14,11, + 12,12,14,14,12,13,13,15,14,11,11,12,14,15,14,14, + 14,17,16,13,12,14,13,16,11,12,12,13,15,12,13,13, + 14,15,11,12,11,14,14,14,15,14,15,17,13,14,12,16, + 12, +}; + +static float _vq_quantthresh__44u4__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p4_0 = { + _vq_quantthresh__44u4__p4_0, + _vq_quantmap__44u4__p4_0, + 5, + 5 +}; + +static static_codebook _44u4__p4_0 = { + 4, 625, + _vq_lengthlist__44u4__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p4_0, + NULL, + &_vq_auxt__44u4__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u4__p5_0[] = { + 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 4, 7, 6, 8, 7, + 10, 9, 4, 4, 5, 6, 7, 7, 8, 9, 9, 6, 7, 6, 8, 8, + 8, 8,10,10, 6, 6, 7, 8, 8, 8, 9,10,10, 7, 8, 7, + 9, 8,10,10,11,11, 7, 7, 8, 8, 9,10,10,11,11, 9, + 10, 9,10,10,11,11,12,12, 9, 9,10,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u4__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u4__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p5_0 = { + _vq_quantthresh__44u4__p5_0, + _vq_quantmap__44u4__p5_0, + 9, + 9 +}; + +static static_codebook _44u4__p5_0 = { + 2, 81, + _vq_lengthlist__44u4__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u4__p5_0, + NULL, + &_vq_auxt__44u4__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u4__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9,10,10,11,13,13, 4, 6, 5, + 8, 8, 9, 9,10,10,11,11,14,14, 4, 5, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 7, 8, 8, 9, 9,10,10,11,11, + 12,12,15,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15, + 15, 8, 9, 9,10,10,11,11,12,12,13,13,16,16, 8, 9, + 9,10,10,11,11,12,12,13,13,16,16,10,10,10,11,11, + 12,12,13,13,14,13,16,16,10,10,11,11,12,12,12,13, + 13,13,14,16,17,11,12,11,12,12,13,13,13,14,14,14, + 17,16,11,11,12,12,12,13,13,14,14,15,14,17,17,14, + 14,14,15,15,16,16,17,17,17,19,19, 0,14,15,15,15, + 15,16,16,16,17,17,19,20,20, +}; + +static float _vq_quantthresh__44u4__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u4__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p6_0 = { + _vq_quantthresh__44u4__p6_0, + _vq_quantmap__44u4__p6_0, + 13, + 13 +}; + +static static_codebook _44u4__p6_0 = { + 2, 169, + _vq_lengthlist__44u4__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u4__p6_0, + NULL, + &_vq_auxt__44u4__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u4__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p6_1 = { + _vq_quantthresh__44u4__p6_1, + _vq_quantmap__44u4__p6_1, + 5, + 5 +}; + +static static_codebook _44u4__p6_1 = { + 2, 25, + _vq_lengthlist__44u4__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p6_1, + NULL, + &_vq_auxt__44u4__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u4__p7_0[] = { + 1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4,10, 9, + 11,11,11,11,11,11,11,11,11,11, 4,10,10,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44u4__p7_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44u4__p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_0 = { + _vq_quantthresh__44u4__p7_0, + _vq_quantmap__44u4__p7_0, + 13, + 13 +}; + +static static_codebook _44u4__p7_0 = { + 2, 169, + _vq_lengthlist__44u4__p7_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44u4__p7_0, + NULL, + &_vq_auxt__44u4__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u4__p7_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 8,10,10,11,11,12,12, 4, + 7, 6, 8, 7, 9, 9,10,10,11,10,12,11,12,12, 4, 6, + 6, 7, 8, 9, 9,10,10,11,11,12,12,13,13, 6, 8, 8, + 10, 9,11,10,11,11,12,12,14,13,13,13, 6, 8, 8, 9, + 9,11,11,12,12,12,12,13,14,13,14, 8, 9, 9,11,10, + 12,12,13,12,13,14,14,14,14,14, 8, 9, 9,10,11,12, + 11,12,13,13,14,14,13,14,14, 9,10,10,12,12,14,13, + 14,14,15,15,16,15,15,15, 9,10,10,11,12,13,13,13, + 14,15,15,18,16,17,15,10,12,12,13,13,15,14,15,14, + 16,16,16,15,16,15,10,11,11,13,13,14,14,17,16,15, + 16,18,16,15,16,11,12,13,14,13,15,14,15,16,17,15, + 16,16,15,16,11,12,13,14,15,14,16,15,15,16,15,15, + 17,17,17,12,13,13,14,14,14,15,16,14,15,15,16,16, + 16,16,12,13,13,13,14,15,15,15,14,16,16,16,16,16, + 17, +}; + +static float _vq_quantthresh__44u4__p7_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u4__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_1 = { + _vq_quantthresh__44u4__p7_1, + _vq_quantmap__44u4__p7_1, + 15, + 15 +}; + +static static_codebook _44u4__p7_1 = { + 2, 225, + _vq_lengthlist__44u4__p7_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u4__p7_1, + NULL, + &_vq_auxt__44u4__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u4__p7_2[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 9, 9,10, 9, 9,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9,10, 9,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, + 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u4__p7_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u4__p7_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_2 = { + _vq_quantthresh__44u4__p7_2, + _vq_quantmap__44u4__p7_2, + 17, + 17 +}; + +static static_codebook _44u4__p7_2 = { + 2, 289, + _vq_lengthlist__44u4__p7_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u4__p7_2, + NULL, + &_vq_auxt__44u4__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u4__short[] = { + 3, 9,14,12,17,13,13,13, 4, 7, 8, 9,12,10,11,12, + 6, 5, 4, 7, 6, 7, 9,14, 8, 8, 7, 9, 8, 9,10,13, + 9, 8, 5, 7, 3, 5, 8,15, 9, 9, 6, 8, 4, 5, 7,16, + 11,10, 6, 9, 4, 3, 6,15,17,16, 8,11, 5, 5, 7,16, +}; + +static static_codebook _huff_book__44u4__short = { + 2, 64, + _huff_lengthlist__44u4__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u5__long[] = { + 3, 8,13,12,14,13,16,11,12,13, 5, 4, 5, 6, 8, 9, + 10, 9,12,12,10, 5, 4, 6, 6, 8, 9,10,14,16,10, 6, + 6, 6, 6, 7, 9, 8,12,13,13, 7, 5, 6, 4, 6, 6, 7, + 11,16,10, 7, 7, 7, 6, 6, 7, 7,11,14,14, 9, 8, 8, + 5, 6, 6, 7,11,16, 9, 8, 8, 8, 6, 6, 6, 4, 7,12, + 11,10,12,11,10, 9,10, 5, 6,10,10,13,15,15,15,15, + 14, 8, 7, 9, +}; + +static static_codebook _huff_book__44u5__long = { + 2, 100, + _huff_lengthlist__44u5__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 4, 8, 8, 8,11, + 10, 8,10,10, 8,11,11,10,12,13,10,13,13, 7,10,10, + 9,13,11,10,13,13, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u5__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u5__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p1_0 = { + _vq_quantthresh__44u5__p1_0, + _vq_quantmap__44u5__p1_0, + 3, + 3 +}; + +static static_codebook _44u5__p1_0 = { + 4, 81, + _vq_lengthlist__44u5__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u5__p1_0, + NULL, + &_vq_auxt__44u5__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 7, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 7, 8, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6, + 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u5__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u5__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p2_0 = { + _vq_quantthresh__44u5__p2_0, + _vq_quantmap__44u5__p2_0, + 3, + 3 +}; + +static static_codebook _44u5__p2_0 = { + 4, 81, + _vq_lengthlist__44u5__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u5__p2_0, + NULL, + &_vq_auxt__44u5__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u5__p3_0[] = { + 2, 4, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 10, 9,12,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 7, 8, 9,10,11,10,11,11,13,14, 9,10,11, + 13,13, 5, 7, 7, 9, 9, 7, 9, 8,11,10, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,13,14, 8,10,10,13,13, + 10,11,11,15,14, 9,11,11,14,14,13,15,14,18,16,12, + 13,14,16,16, 8,10,10,13,13, 9,11,11,14,14,10,11, + 12,14,15,12,13,13,16,16,13,14,14,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,15, + 14,10,11,11,14,14, 7, 9, 9,12,11, 9,11,11,13,13, + 9,11,11,13,13,12,12,13,15,15,11,12,13,16,15, 6, + 9, 9,11,11, 8,11,10,13,12, 9,10,11,12,14,11,13, + 11,16,14,11,13,13,15,16,10,11,11,15,15,11,12,13, + 16,15,11,13,13,16,16,14,15,15,17,18,14,15,16,17, + 18, 9,11,11,14,15,10,12,11,15,15,11,12,13,15,16, + 13,15,13,17,15,14,15,16,18,19, 5, 7, 7,10,10, 7, + 9, 9,11,11, 7, 9, 9,11,11,10,11,11,15,14,10,11, + 11,14,15, 6, 9, 9,11,11, 9,11,10,13,13, 8,10,11, + 12,13,11,13,13,15,15,11,11,13,13,15, 7, 9, 9,11, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,12,17,16, + 11,13,12,16,15, 9,11,11,15,14,11,13,13,16,16,10, + 11,12,15,15,14,15,15,17,17,13,13,15,15,17,10,11, + 12,15,15,11,13,13,16,19,11,13,12,17,17,14,16,15, + 19,17,14,15,15,18,18, 8,10,10,14,14,10,12,11,16, + 15, 9,11,11,15,16,14,16,15,17,17,13,14,14,18,17, + 9,11,11,16,15,11,13,13,16,18,11,13,13,17,16,15, + 16,17,18, 0,15,15,16, 0,18, 9,11,11,16,15,10,13, + 12,17,15,11,13,13,16,17,14,18,15,19,18,15,16,16, + 19,18,13,15,15,19,17,13,15,15,18,18,14,15,15,19, + 0,17,18, 0,19,19,16,17,17, 0,18,12,14,13,18,17, + 13,15,13,19,18,14,15,15,19,19,16,17,15, 0,17,16, + 19,17,19,18, 8,10,10,14,14,10,11,11,15,15,10,11, + 11,16,16,13,15,15,17,16,14,15,15,18,19, 9,11,11, + 16,15,11,13,13,19,16,10,12,13,15,17,15,15,15,19, + 19,15,16,16,17, 0, 9,11,11,16,16,11,13,13,16,17, + 11,13,13,18,18,14,16,15,18,18,15,17,16,19, 0,12, + 14,14,17,18,13,16,16,18,18,13,14,15,17, 0,16,17, + 17, 0, 0,16,15, 0,19,17,12,15,14,17,18,14,15,16, + 0,18,14,16,16,18, 0,16,17,17, 0, 0,17,19,17,19, + 0, +}; + +static float _vq_quantthresh__44u5__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u5__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p3_0 = { + _vq_quantthresh__44u5__p3_0, + _vq_quantmap__44u5__p3_0, + 5, + 5 +}; + +static static_codebook _44u5__p3_0 = { + 4, 625, + _vq_lengthlist__44u5__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u5__p3_0, + NULL, + &_vq_auxt__44u5__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u5__p4_0[] = { + 4, 6, 6, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10, 9,10,10,11,11, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,12,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,13,11, + 11,12,12,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,13,13,11,12,12,14,13, 6, 7, 7, + 9, 9, 7, 8, 7,10,10, 7, 7, 8, 9,10, 9,10,10,12, + 11, 9,10,10,11,11, 7, 8, 8,10,10, 8, 8, 9,10,11, + 8, 8, 8,11,10,10,10,11,11,12,10,10,11,12,12, 6, + 7, 7,10,10, 7, 8, 8,11,10, 8, 8, 9,10,11,10,11, + 10,13,11,10,10,11,12,12, 9,10,10,12,12,10,10,10, + 12,13,10,11,11,13,13,12,11,12,11,14,12,12,13,13, + 14, 9,10,10,12,12, 9,10,10,12,12,10,10,11,12,13, + 11,12,11,14,12,12,12,12,14,14, 6, 7, 7, 9, 9, 7, + 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,11,11, 9,10, + 10,12,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 8, + 10,11,10,10,11,12,12,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 8, 8,10,11, 8, 9, 8,11,10,10,11,10,12,12, + 10,11,10,12,11, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,12,12,12,12,14,14,11,11,12,12,14, 9,10, + 10,12,12,10,11,11,12,12,10,10,10,12,12,12,13,12, + 14,14,11,12,11,14,11, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,14,14,11,12,12,13,13, + 9,10,10,12,12,10,10,11,12,13,10,11,10,13,12,12, + 12,13,14,14,12,12,12,14,13, 9,10,10,12,12, 9,10, + 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,13, + 13,14,11,12,11,14,13,11,11,12,13,14,12,13,12,14, + 14,13,12,14,11,16,13,14,14,16,15,11,11,11,13,13, + 11,12,11,14,13,12,12,13,14,15,12,14,12,16,12,14, + 14,14,16,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,13,13,12,12,12,14,14, 9,10,10, + 12,12,10,11,10,13,12, 9,10,10,12,13,12,12,12,14, + 13,12,12,13,13,15, 9,10,10,12,12,10,10,11,12,13, + 10,11,10,13,12,12,13,12,14,14,12,13,12,14,13,11, + 11,11,13,13,12,13,12,14,14,11,11,12,13,14,13,14, + 14,16,15,13,12,14,12,15,11,12,12,13,14,12,12,13, + 14,14,11,12,11,14,13,13,14,14,15,16,13,14,11,16, + 11, +}; + +static float _vq_quantthresh__44u5__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u5__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p4_0 = { + _vq_quantthresh__44u5__p4_0, + _vq_quantmap__44u5__p4_0, + 5, + 5 +}; + +static static_codebook _44u5__p4_0 = { + 4, 625, + _vq_lengthlist__44u5__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u5__p4_0, + NULL, + &_vq_auxt__44u5__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u5__p5_0[] = { + 2, 4, 3, 6, 6, 8, 7,10,10, 3, 5, 5, 8, 7, 8, 8, + 11,11, 3, 5, 5, 7, 8, 8, 8,10,11, 6, 8, 7, 9, 9, + 10, 9,12,11, 7, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8, + 10, 9,11,11,13,12, 8, 8, 8, 9,10,11,12,12,13,10, + 11,10,12,11,13,12,14,14,10,10,11,11,12,12,13,14, + 14, +}; + +static float _vq_quantthresh__44u5__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u5__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p5_0 = { + _vq_quantthresh__44u5__p5_0, + _vq_quantmap__44u5__p5_0, + 9, + 9 +}; + +static static_codebook _44u5__p5_0 = { + 2, 81, + _vq_lengthlist__44u5__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u5__p5_0, + NULL, + &_vq_auxt__44u5__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u5__p6_0[] = { + 3, 4, 4, 5, 6, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7, + 8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9, + 9, 9,10,10,11,10,11,11, 9, 9, 9,10,10,11,11,11, + 11, +}; + +static float _vq_quantthresh__44u5__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u5__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p6_0 = { + _vq_quantthresh__44u5__p6_0, + _vq_quantmap__44u5__p6_0, + 9, + 9 +}; + +static static_codebook _44u5__p6_0 = { + 2, 81, + _vq_lengthlist__44u5__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u5__p6_0, + NULL, + &_vq_auxt__44u5__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8,11,10, 7, + 10,10, 5, 9, 9, 8,10,10, 8,10,11, 4, 9, 9, 9,11, + 11, 9,12,11, 8,11,11,11,12,12,10,12,12, 7,11,11, + 10,12,12,10,12,12, 4, 9, 9, 9,11,11, 9,11,11, 7, + 11,11,10,12,12,10,11,12, 8,11,11,10,12,12,11,12, + 12, +}; + +static float _vq_quantthresh__44u5__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u5__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p7_0 = { + _vq_quantthresh__44u5__p7_0, + _vq_quantmap__44u5__p7_0, + 3, + 3 +}; + +static static_codebook _44u5__p7_0 = { + 4, 81, + _vq_lengthlist__44u5__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u5__p7_0, + NULL, + &_vq_auxt__44u5__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7, + 8, 8, 9, 8, 9, 8, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, + 9, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, + 9, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, + 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10, + 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9, + 9, 9, 9, 9, 9,10,10,10,10, +}; + +static float _vq_quantthresh__44u5__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u5__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p7_1 = { + _vq_quantthresh__44u5__p7_1, + _vq_quantmap__44u5__p7_1, + 11, + 11 +}; + +static static_codebook _44u5__p7_1 = { + 2, 121, + _vq_lengthlist__44u5__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u5__p7_1, + NULL, + &_vq_auxt__44u5__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, + 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11, + 11, 6, 8, 8, 9, 9,10,10,12,11,13,12, 6, 7, 8, 9, + 9,10,10,11,11,12,12, 8, 9, 9,10,10,11,12,12,12, + 14,13, 8, 9, 9,10,10,11,11,12,13,14,13,10,11,10, + 12,12,13,13,14,13,15,14,10,11,11,12,12,12,13,13, + 13,15,15,11,12,12,13,12,13,14,14,14,15,14,11,11, + 12,13,13,13,14,14,14,15,15, +}; + +static float _vq_quantthresh__44u5__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u5__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p8_0 = { + _vq_quantthresh__44u5__p8_0, + _vq_quantmap__44u5__p8_0, + 11, + 11 +}; + +static static_codebook _44u5__p8_0 = { + 2, 121, + _vq_lengthlist__44u5__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u5__p8_0, + NULL, + &_vq_auxt__44u5__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, + 8, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u5__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u5__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p8_1 = { + _vq_quantthresh__44u5__p8_1, + _vq_quantmap__44u5__p8_1, + 11, + 11 +}; + +static static_codebook _44u5__p8_1 = { + 2, 121, + _vq_lengthlist__44u5__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u5__p8_1, + NULL, + &_vq_auxt__44u5__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u5__p9_0[] = { + 1, 3, 3,12,10,12,12,12,12,12,12,12,12, 3, 8, 9, + 12,12,12,12,12,12,12,12,12,12, 4, 9, 9,12,12,12, + 12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12, + 12,12,12,12, 9,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44u5__p9_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44u5__p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_0 = { + _vq_quantthresh__44u5__p9_0, + _vq_quantmap__44u5__p9_0, + 13, + 13 +}; + +static static_codebook _44u5__p9_0 = { + 2, 169, + _vq_lengthlist__44u5__p9_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44u5__p9_0, + NULL, + &_vq_auxt__44u5__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u5__p9_1[] = { + 1, 4, 4, 7, 7, 8, 9, 7, 7, 8, 8, 9, 9,10,10, 5, + 6, 6, 9, 8,10,10, 9, 8, 9, 9,10, 9,11,10, 4, 6, + 6, 8, 9, 9,10, 8, 9, 9,10,10,10,11,10, 7, 8, 8, + 10,10,11,11,10,10,11,11,11,11,11,11, 7, 8, 8,10, + 10,11,11,10,10,11,11,11,11,11,12, 8, 9,10,11,10, + 12,12,11,11,11,11,12,12,12,13, 8, 9, 9,11,11,11, + 12,11,11,11,11,12,12,12,12, 8, 9, 9,10,10,11,11, + 12,11,12,12,12,13,13,13, 8, 9, 9,10,10,11,11,12, + 11,12,12,13,13,12,13, 9,10,10,11,11,12,11,12,13, + 14,14,15,15,15,14, 9,10,10,11,11,12,12,12,12,13, + 13,14,14,14,14, 9,10,11,12,11,12,13,14,13,14,13, + 14,14,14,14, 9,11,11,11,11,12,13,13,13,14,13,15, + 15,14,14,10,11,11,12,12,13,13,13,13,14,14,14,15, + 15,15,10,11,11,12,12,12,13,13,13,15,14,15,14,14, + 14, +}; + +static float _vq_quantthresh__44u5__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u5__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_1 = { + _vq_quantthresh__44u5__p9_1, + _vq_quantmap__44u5__p9_1, + 15, + 15 +}; + +static static_codebook _44u5__p9_1 = { + 2, 225, + _vq_lengthlist__44u5__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u5__p9_1, + NULL, + &_vq_auxt__44u5__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u5__p9_2[] = { + 3, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10, 9,10,10,10,10, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9,10, + 9, 9, 9, 9, 9, 9, 9,10, 9,10, 9, 9, 9,10,10, 9, + 9, +}; + +static float _vq_quantthresh__44u5__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u5__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_2 = { + _vq_quantthresh__44u5__p9_2, + _vq_quantmap__44u5__p9_2, + 17, + 17 +}; + +static static_codebook _44u5__p9_2 = { + 2, 289, + _vq_lengthlist__44u5__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u5__p9_2, + NULL, + &_vq_auxt__44u5__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u5__short[] = { + 4,11,16,14,18,15,18,15,17,17, 4, 6, 9, 9,12, 9, + 14,10,14,17, 6, 6, 5, 7, 6, 8,10,10,16,17, 7, 8, + 7, 9, 9,10,12,12,14,17, 8, 6, 5, 7, 4, 7, 5, 7, + 14,17, 9, 9, 8, 9, 7,10, 8,10,14,17,11, 9, 7, 9, + 4, 7, 3, 6,15,17,11,10,10,10, 6, 9, 5, 6,14,17, + 17,17,10,15, 4, 8, 3, 5,12,17,17,17,12,16, 7,11, + 6, 8,16,17, +}; + +static static_codebook _huff_book__44u5__short = { + 2, 100, + _huff_lengthlist__44u5__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u6__long[] = { + 3, 9,14,13,15,13,16,12,12,12, 5, 4, 6, 7, 8, 9, + 10,10,13,12,10, 5, 5, 6, 6, 9, 9,10,14,14,10, 6, + 6, 7, 6, 8, 9, 9,13,12,13, 7, 5, 6, 4, 6, 6, 7, + 11,15,10, 8, 7, 7, 6, 7, 7, 7,11,13,16,10, 8, 8, + 5, 6, 4, 6,10,14, 9, 9, 9, 8, 6, 6, 5, 4, 7,11, + 11,11,12,11,10, 9, 9, 5, 5, 9,10,13,14,14,14,14, + 15, 8, 7, 8, +}; + +static static_codebook _huff_book__44u6__long = { + 2, 100, + _huff_lengthlist__44u6__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p1_0[] = { + 1, 4, 4, 4, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,11, + 10, 8,10,10, 8,11,10,10,12,13,10,13,13, 7,10,10, + 10,13,11,10,13,13, 5, 8, 8, 8,11,10, 8,10,10, 7, + 10,10,10,13,13, 9,11,13, 8,10,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u6__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u6__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p1_0 = { + _vq_quantthresh__44u6__p1_0, + _vq_quantmap__44u6__p1_0, + 3, + 3 +}; + +static static_codebook _44u6__p1_0 = { + 4, 81, + _vq_lengthlist__44u6__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u6__p1_0, + NULL, + &_vq_auxt__44u6__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p2_0[] = { + 3, 5, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 6, 8, + 7, 6, 7, 8, 6, 8, 8, 8, 8, 9, 8, 9, 9, 6, 7, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 7, 8, 6, + 7, 7, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 8, +}; + +static float _vq_quantthresh__44u6__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u6__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p2_0 = { + _vq_quantthresh__44u6__p2_0, + _vq_quantmap__44u6__p2_0, + 3, + 3 +}; + +static static_codebook _44u6__p2_0 = { + 4, 81, + _vq_lengthlist__44u6__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u6__p2_0, + NULL, + &_vq_auxt__44u6__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u6__p3_0[] = { + 2, 4, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 10, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 7, 8, 9,10,11,10,11,11,13,14, 9,10,11, + 13,13, 5, 7, 7, 9, 9, 7, 9, 8,11,10, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,14,13, 8,10,10,14,13, + 10,12,11,15,14, 9,11,11,15,14,13,15,14,20,16,13, + 13,14,16,16, 8,10,10,13,14, 9,11,11,14,15,10,11, + 12,14,15,13,13,14,16,16,13,14,14,16,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,15, + 14,10,11,11,14,14, 7, 9, 9,12,11, 9,11,11,12,13, + 9,11,11,13,13,11,12,13,14,16,11,12,13,16,16, 6, + 9, 8,11,11, 8,11,10,13,12, 9,10,11,12,13,11,13, + 11,15,14,11,13,13,15,15,10,12,11,15,14,11,12,13, + 17,16,11,13,13,16,17,14,15,16,17,17,14,15,16,20, + 0, 9,11,11,14,15,10,13,12,16,16,11,13,13,17,17, + 13,15,14,17,15,15,16,16, 0, 0, 5, 7, 7,10,10, 7, + 9, 9,11,11, 7, 8, 9,11,11,10,11,11,14,14,10,11, + 11,14,14, 6, 9, 9,11,11, 9,11,11,14,12, 8,10,11, + 12,13,11,13,13,16,16,11,11,13,14,16, 7, 9, 9,11, + 12, 9,11,11,13,13, 9,11,11,13,12,11,13,12,16,16, + 12,13,12,16,14, 9,11,11,16,15,11,13,13,17,15,10, + 12,12,15,16,14,16,16, 0,17,13,14,15,15,17,10,11, + 12,15,15,11,13,13,17,17,11,13,13,15,16,14,15,15, + 19,18,14,15,15,19,16, 8,10,10,14,14,10,12,11,15, + 16,10,11,11,15,17,13,16,15,19,19,13,15,14,17,17, + 9,11,12,15,16,11,13,13,18,19,11,13,13,16,17,16, + 16,17, 0, 0,15,15,16, 0,19, 9,11,11,15,16,10,13, + 12,17,15,11,13,13,16,17,14,17,15,18,17,15,16,15, + 18, 0,13,14,15, 0,19,14,16,16, 0,17,15,16,16, 0, + 17,16,17, 0, 0, 0,16,17,19, 0, 0,12,14,14,17,17, + 13,15,13, 0,19,14,16,16,18,19,16,18,15,19,18,17, + 18,17,19, 0, 8,10,10,14,13,10,11,11,16,15,10,11, + 11,15,15,13,15,15,19,18,14,15,16, 0,18, 9,11,11, + 15,14,11,13,13, 0,16,10,12,13,15,17,14,16,16, 0, + 18,15,16,17,17, 0, 9,11,11,16,15,11,13,13,16,16, + 11,14,13,18,18,15,17,15,18,17,15,16,18, 0, 0,12, + 14,14,18,19,14,15,16, 0,18,13,14,15,18, 0,17,17, + 17, 0, 0,16,15,18,17, 0,12,14,15,17,19,14,16,16, + 19, 0,14,17,16, 0,18,17,19,17, 0, 0,16,18,17, 0, + 17, +}; + +static float _vq_quantthresh__44u6__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u6__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p3_0 = { + _vq_quantthresh__44u6__p3_0, + _vq_quantmap__44u6__p3_0, + 5, + 5 +}; + +static static_codebook _44u6__p3_0 = { + 4, 625, + _vq_lengthlist__44u6__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u6__p3_0, + NULL, + &_vq_auxt__44u6__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u6__p4_0[] = { + 4, 6, 6, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11, + 9,10,10,12,12, 9, 9,10,12,12,11,12,12,13,13,11, + 11,12,12,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,13,13,11,12,12,13,13, 6, 7, 7, + 9, 9, 7, 8, 7,10, 9, 7, 7, 8, 9,10, 9,10,10,12, + 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 8, 9,10,10, + 8, 8, 8,10,10,10,10,11,12,12,10,10,11,12,12, 6, + 7, 7,10,10, 7, 8, 8,11,10, 8, 8, 9,10,11,10,11, + 10,12,11,10,10,11,12,12, 9,10,10,12,12,10,10,11, + 12,12,10,11,10,13,12,12,12,12,12,14,12,12,12,13, + 14, 9,10,10,12,12, 9,10,10,12,12,10,10,11,12,13, + 11,12,11,14,12,12,12,13,14,14, 6, 7, 7, 9, 9, 7, + 8, 7,10, 9, 7, 7, 8,10,10, 9,10,10,12,11, 9,10, + 10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 8, + 10,10,10,10,11,12,12,10,10,10,11,12, 7, 8, 8,10, + 10, 8, 8, 8,10,10, 8, 8, 8,10,10,10,11,10,12,12, + 10,11,10,12,11, 9,10,10,12,12,10,11,10,13,12, 9, + 10,10,12,12,12,12,12,14,14,11,11,12,12,13, 9,10, + 10,12,12,10,11,11,12,12,10,11,10,12,12,12,12,12, + 14,14,12,12,12,14,12, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,13,13,11,12,12,13,13, + 9,10,10,12,12,10,10,11,12,13,10,11,10,12,12,12, + 12,13,13,14,12,12,12,14,14, 9,10,10,12,12, 9,10, + 10,12,12,10,10,10,12,12,12,12,12,14,13,12,12,12, + 14,14,11,12,12,13,13,11,12,12,14,14,12,12,12,14, + 14,13,12,14,12,15,13,14,14,15,15,11,11,11,13,13, + 11,12,11,14,13,12,12,12,14,14,12,14,12,15,12,13, + 14,14,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,13,13,11,12,12,13,14, 9,10,10, + 12,12,10,11,10,13,12, 9,10,10,12,13,12,12,12,15, + 14,12,12,13,13,14, 9,10,10,12,12,10,10,11,12,12, + 10,11,10,12,12,12,13,12,14,14,12,13,12,14,13,11, + 11,11,13,13,12,12,12,14,13,11,11,12,13,14,13,14, + 14,15,15,12,12,14,12,15,11,12,12,13,14,12,12,12, + 14,14,11,12,12,14,14,13,14,14,15,15,13,14,12,16, + 12, +}; + +static float _vq_quantthresh__44u6__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u6__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p4_0 = { + _vq_quantthresh__44u6__p4_0, + _vq_quantmap__44u6__p4_0, + 5, + 5 +}; + +static static_codebook _44u6__p4_0 = { + 4, 625, + _vq_lengthlist__44u6__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u6__p4_0, + NULL, + &_vq_auxt__44u6__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u6__p5_0[] = { + 2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8, + 11,11, 3, 5, 5, 7, 8, 8, 8,11,11, 6, 8, 7,10, 9, + 10, 9,12,12, 6, 7, 8, 9,10, 9,10,12,12, 8, 8, 8, + 10, 9,12,11,13,13, 8, 8, 8, 9,10,11,12,12,13,10, + 11,11,12,11,13,12,14,14,10,10,11,11,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44u6__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u6__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p5_0 = { + _vq_quantthresh__44u6__p5_0, + _vq_quantmap__44u6__p5_0, + 9, + 9 +}; + +static static_codebook _44u6__p5_0 = { + 2, 81, + _vq_lengthlist__44u6__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u6__p5_0, + NULL, + &_vq_auxt__44u6__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u6__p6_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7, + 8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9, + 9, 9,10,10,11,11,11,11, 9, 9, 9,10,10,10,11,11, + 11, +}; + +static float _vq_quantthresh__44u6__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u6__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p6_0 = { + _vq_quantthresh__44u6__p6_0, + _vq_quantmap__44u6__p6_0, + 9, + 9 +}; + +static static_codebook _44u6__p6_0 = { + 2, 81, + _vq_lengthlist__44u6__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u6__p6_0, + NULL, + &_vq_auxt__44u6__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8,11,10, 8, + 11,10, 5, 8, 9, 7,10,10, 8,10,11, 4, 9, 9, 9,12, + 11, 9,11,12, 8,11,12,11,12,13,10,13,12, 7,12,11, + 10,12,12,10,13,13, 4, 9, 9, 8,11,11, 9,11,12, 7, + 12,12,10,13,13,10,12,13, 8,12,12,10,13,13,11,13, + 12, +}; + +static float _vq_quantthresh__44u6__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u6__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p7_0 = { + _vq_quantthresh__44u6__p7_0, + _vq_quantmap__44u6__p7_0, + 3, + 3 +}; + +static static_codebook _44u6__p7_0 = { + 4, 81, + _vq_lengthlist__44u6__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u6__p7_0, + NULL, + &_vq_auxt__44u6__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p7_1[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, + 8, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8, + 8, 6, 7, 6, 7, 7, 8, 8, 9, 9, 9, 9, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 7, 8, 7, 8, 8, 9, 9, 9, 9, + 9, 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 8, 8, + 8, 9, 9, 9, 9, 9, 9,10,10, +}; + +static float _vq_quantthresh__44u6__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u6__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p7_1 = { + _vq_quantthresh__44u6__p7_1, + _vq_quantmap__44u6__p7_1, + 11, + 11 +}; + +static static_codebook _44u6__p7_1 = { + 2, 121, + _vq_lengthlist__44u6__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u6__p7_1, + NULL, + &_vq_auxt__44u6__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, + 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11, + 11, 6, 8, 8, 9, 9,10,10,11,11,12,12, 6, 8, 8, 9, + 9,10,10,11,11,12,12, 8, 9, 9,10,10,11,11,12,12, + 13,13, 8, 9, 9,10,10,11,11,12,12,13,13,10,10,10, + 11,11,12,12,13,13,14,14,10,10,10,11,11,12,13,13, + 13,14,14,11,12,12,13,13,13,13,14,14,15,14,11,11, + 11,13,13,14,13,14,14,15,14, +}; + +static float _vq_quantthresh__44u6__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u6__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p8_0 = { + _vq_quantthresh__44u6__p8_0, + _vq_quantmap__44u6__p8_0, + 11, + 11 +}; + +static static_codebook _44u6__p8_0 = { + 2, 121, + _vq_lengthlist__44u6__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u6__p8_0, + NULL, + &_vq_auxt__44u6__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 6, + 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, + 8, 6, 7, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u6__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u6__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p8_1 = { + _vq_quantthresh__44u6__p8_1, + _vq_quantmap__44u6__p8_1, + 11, + 11 +}; + +static static_codebook _44u6__p8_1 = { + 2, 121, + _vq_lengthlist__44u6__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u6__p8_1, + NULL, + &_vq_auxt__44u6__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u6__p9_0[] = { + 1, 3, 3,10,12,13,13,13,13,13,13,13,13,13,13, 3, + 9, 9,13,13,13,13,13,13,13,13,13,13,12,12, 4, 9, + 9,12,12,12,12,12,12,12,12,12,12,12,12, 9,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12, 9,11,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44u6__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__44u6__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_0 = { + _vq_quantthresh__44u6__p9_0, + _vq_quantmap__44u6__p9_0, + 15, + 15 +}; + +static static_codebook _44u6__p9_0 = { + 2, 225, + _vq_lengthlist__44u6__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__44u6__p9_0, + NULL, + &_vq_auxt__44u6__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u6__p9_1[] = { + 1, 4, 4, 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 5, + 6, 6, 8, 8,10,10, 9, 9,10, 9,10, 9,10,10, 4, 6, + 6, 8, 9,10,10, 8, 9, 9,10,10,10,10,10, 7, 9, 8, + 10,10,11,11,10,10,11,11,11,11,12,12, 7, 8, 8,10, + 10,11,11,10,10,10,11,11,11,11,12, 8,10,10,11,11, + 12,12,11,11,11,11,12,12,12,13, 8, 9, 9,11,11,12, + 12,11,11,12,12,12,12,12,12, 8, 9, 9,10,10,11,11, + 13,12,13,12,13,13,13,13, 8, 9, 9,10,10,11,11,12, + 12,12,12,13,12,13,12, 9,10,10,11,11,12,12,13,13, + 14,12,13,13,14,13, 9,10,10,11,11,12,12,12,12,13, + 13,13,13,14,14, 9,11,10,11,11,12,13,13,12,13,13, + 15,13,14,14, 9,10,10,11,12,12,13,13,13,13,13,14, + 14,14,14,10,11,11,12,12,13,12,13,13,14,14,14,14, + 14,15,10,11,11,11,12,13,13,13,13,14,14,14,14,14, + 14, +}; + +static float _vq_quantthresh__44u6__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u6__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_1 = { + _vq_quantthresh__44u6__p9_1, + _vq_quantmap__44u6__p9_1, + 15, + 15 +}; + +static static_codebook _44u6__p9_1 = { + 2, 225, + _vq_lengthlist__44u6__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u6__p9_1, + NULL, + &_vq_auxt__44u6__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u6__p9_2[] = { + 3, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9,10,10, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10, 9, 9, 9,10, + 9, +}; + +static float _vq_quantthresh__44u6__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u6__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_2 = { + _vq_quantthresh__44u6__p9_2, + _vq_quantmap__44u6__p9_2, + 17, + 17 +}; + +static static_codebook _44u6__p9_2 = { + 2, 289, + _vq_lengthlist__44u6__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u6__p9_2, + NULL, + &_vq_auxt__44u6__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u6__short[] = { + 5,11,15,14,17,14,17,15,17,17, 4, 6, 9, 9,14, 9, + 17,10,15,17, 6, 6, 5, 7, 7, 9,11,10,15,17, 6, 8, + 8,10, 9,11,14,13,16,17, 7, 6, 5, 7, 5, 7, 5, 8, + 15,17, 9, 8, 8, 9, 8,10,10,11,14,17,10, 8, 7, 9, + 4, 7, 3, 5,11,17,10,10,10,10, 6, 9, 4, 5,11,17, + 16,16,13,15, 5,10, 4, 3, 9,16,17,17,14,17, 7,11, + 6, 6,11,17, +}; + +static static_codebook _huff_book__44u6__short = { + 2, 100, + _huff_lengthlist__44u6__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u7__long[] = { + 3, 9,15,13,16,13,16,12,12,12, 5, 5, 7, 8, 8,10, + 11,10,13,13,10, 5, 5, 6, 6, 9, 9,10,14,14, 9, 6, + 6, 7, 6, 8, 9,10,13,12,13, 7, 5, 6, 4, 6, 6, 8, + 12,13,11, 8, 7, 8, 6, 7, 7, 7,11,13,15,10, 8, 8, + 5, 6, 4, 5, 9,13, 9, 9, 8, 9, 7, 7, 4, 4, 6,11, + 11,11,12,12,10,10, 8, 5, 5, 9,10,12,13,15,13,13, + 12, 7, 6, 8, +}; + +static static_codebook _huff_book__44u7__long = { + 2, 100, + _huff_lengthlist__44u7__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p1_0[] = { + 1, 4, 4, 5, 7, 7, 4, 7, 7, 5, 8, 8, 8,10,10, 7, + 10,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,11, + 10, 8,10,10, 8,11,10,10,12,13,11,13,13, 7,10,10, + 10,13,11,11,13,13, 5, 8, 8, 8,11,10, 8,10,10, 7, + 10,10,11,13,13,10,11,13, 8,11,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u7__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u7__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p1_0 = { + _vq_quantthresh__44u7__p1_0, + _vq_quantmap__44u7__p1_0, + 3, + 3 +}; + +static static_codebook _44u7__p1_0 = { + 4, 81, + _vq_lengthlist__44u7__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u7__p1_0, + NULL, + &_vq_auxt__44u7__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p2_0[] = { + 3, 5, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6, + 7, 7, 5, 6, 6, 6, 7, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 7, 6, 7, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 7, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 7, 8, 6, + 7, 7, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u7__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u7__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p2_0 = { + _vq_quantthresh__44u7__p2_0, + _vq_quantmap__44u7__p2_0, + 3, + 3 +}; + +static static_codebook _44u7__p2_0 = { + 4, 81, + _vq_lengthlist__44u7__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u7__p2_0, + NULL, + &_vq_auxt__44u7__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u7__p3_0[] = { + 2, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 9, 9,12,12, 8, 9, 9,12,12, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 6, 8, 9,10,11,10,11,11,13,14, 9,10,11, + 13,13, 5, 7, 7, 9, 9, 6, 9, 8,11,10, 7, 9, 9,11, + 11, 9,11,10,13,13,10,11,11,14,13, 8,10,10,14,13, + 10,11,11,16,14, 9,11,11,14,14,13,15,14,17,16,12, + 13,14,16,15, 8, 9,10,13,14, 9,11,11,14,14,10,11, + 11,14,15,13,13,14,17,17,13,14,15,16,17, 5, 7, 7, + 10,10, 7, 9, 8,11,11, 7, 8, 9,11,11,10,11,11,14, + 14,10,11,11,14,14, 7, 9, 9,11,11, 9,11,11,13,13, + 9,11,11,13,13,11,12,13,15,17,11,12,13,16,18, 6, + 8, 8,11,11, 8,10,10,13,12, 9,11,11,12,13,11,13, + 11,16,14,11,13,12,16,16,10,11,11,15,15,11,13,13, + 16,16,11,13,13,18,16,14,14,15,17,16,14,15,17,19, + 0, 9,11,11,14,15,10,12,12,15,17,11,13,13,15,17, + 14,15,13, 0,15,15,17,16,18, 0, 5, 7, 7, 9,10, 7, + 9, 9,11,11, 7, 8, 9,11,11,10,11,11,14,14,10,11, + 11,14,14, 6, 8, 9,11,11, 9,11,11,14,13, 8,10,10, + 11,14,11,13,13,17,15,11,12,13,14,16, 7, 9, 9,11, + 11, 9,11,11,13,12, 9,11,11,12,13,11,13,12,15,15, + 11,13,12,16,15, 9,11,11,15,15,11,12,13,16,15,10, + 11,12,16,15,15,16,16, 0, 0,14,13,15,16,19, 9,11, + 12,15,15,11,13,13,17,16,11,13,12,15,17,14,16,16, + 18, 0,15,15,16,18,17, 8,10,10,13,14,10,11,11,15, + 16,10,11,11,15,16,14,15,15,17,19,14,14,15,19,19, + 9,11,11,16,15,11,13,13,17,17,11,13,13,17,17,15, + 17,16, 0, 0,15,17,17, 0,17, 9,11,11,15,15,11,13, + 12,16,16,11,13,13,18,17,15,16,15,19,19,14,16,18, + 17,19,13,15,15, 0,18,14,16,17,17,18,14,16,16,19, + 19,18,19,19, 0, 0,16,17,18,19, 0,12,14,14,16,18, + 13,16,14, 0,19,14,16,17,19, 0,16,19,16,19,17,17, + 18,18, 0, 0, 8,10,10,14,13, 9,11,11,15,14,10,11, + 12,14,16,13,15,14,19,19,14,16,16,18,17, 9,11,11, + 16,15,11,13,13, 0,17,10,12,13,15,16,15,18,16,19, + 19,14,15,16,18,18, 9,11,12,15,15,11,13,13,17,19, + 11,13,13,17,17,15,17,16,19,19,15,17,16, 0, 0,12, + 14,14, 0,19,14,16,15, 0,19,13,14,16,19, 0,16,18, + 18, 0, 0,16,16,17,17, 0,13,14,14,17, 0,14,17,16, + 0,19,14,16,16,19,18,17,19,17, 0, 0,18,18,17, 0, + 0, +}; + +static float _vq_quantthresh__44u7__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u7__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p3_0 = { + _vq_quantthresh__44u7__p3_0, + _vq_quantmap__44u7__p3_0, + 5, + 5 +}; + +static static_codebook _44u7__p3_0 = { + 4, 625, + _vq_lengthlist__44u7__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u7__p3_0, + NULL, + &_vq_auxt__44u7__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u7__p4_0[] = { + 5, 6, 6, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 7,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 6, 7, 7,10, 9, 7, 7, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11, + 9,10,10,12,12, 9,10,10,11,12,11,12,12,13,13,11, + 11,12,12,13, 8, 9, 9,11,11, 9,10,10,12,11, 9,10, + 10,12,12,11,12,11,13,12,11,12,12,13,14, 6, 7, 7, + 9, 9, 7, 8, 7,10, 9, 7, 7, 8, 9,10, 9,10,10,12, + 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 8, 8,10,10, + 8, 8, 8,10,10,10,10,11,12,12,10,10,11,12,12, 6, + 7, 7,10,10, 7, 8, 8,10,10, 8, 8, 8,10,11, 9,10, + 10,12,11,10,10,11,12,12, 9,10,10,12,12,10,10,10, + 12,12,10,11,10,12,12,12,12,12,13,14,12,12,12,13, + 14, 9,10,10,11,12, 9,10,10,12,12,10,10,11,12,12, + 11,12,11,14,12,12,12,12,14,14, 6, 7, 7, 9, 9, 7, + 8, 7,10, 9, 7, 7, 8, 9,10, 9,10,10,12,11, 9,10, + 10,11,12, 6, 7, 7,10,10, 8, 8, 8,11,10, 7, 8, 8, + 10,10,10,10,10,12,12,10,10,10,11,12, 7, 8, 8,10, + 10, 8, 8, 8,10,10, 8, 8, 8,10,10,10,11,10,12,12, + 10,11,10,12,12, 9,10,10,12,12,10,11,10,13,12, 9, + 10,10,12,12,12,12,12,14,14,11,11,12,12,14, 9,10, + 10,12,12,10,10,10,12,12,10,11,10,12,12,12,12,12, + 14,14,12,12,12,14,13, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,13, + 9,10,10,12,12,10,10,10,12,12,10,11,11,12,12,12, + 12,13,14,14,12,12,12,14,14, 9,10, 9,12,12, 9,10, + 10,12,12,10,10,11,12,12,12,12,11,14,13,12,12,12, + 13,14,11,12,12,13,13,12,12,12,14,14,12,13,12,14, + 14,13,13,14,13,15,14,14,14,15,15,11,11,11,13,13, + 11,12,11,14,13,12,12,12,14,14,12,13,12,15,12,13, + 14,14,15,15, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,13,13,11,12,12,13,14, 9,10,10, + 12,11,10,10,10,12,12, 9,10,10,12,12,12,13,12,14, + 13,11,12,12,13,14, 9,10,10,12,12,10,10,10,12,12, + 10,11,11,12,12,12,12,12,14,14,12,13,12,14,13,11, + 11,11,13,13,12,12,12,14,13,11,11,12,13,14,13,14, + 14,15,15,13,12,13,12,15,11,12,12,13,14,12,12,12, + 14,14,11,12,12,14,14,13,14,14,15,15,13,14,13,15, + 13, +}; + +static float _vq_quantthresh__44u7__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u7__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p4_0 = { + _vq_quantthresh__44u7__p4_0, + _vq_quantmap__44u7__p4_0, + 5, + 5 +}; + +static static_codebook _44u7__p4_0 = { + 4, 625, + _vq_lengthlist__44u7__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u7__p4_0, + NULL, + &_vq_auxt__44u7__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u7__p5_0[] = { + 2, 3, 3, 6, 6, 8, 8,10,10, 3, 5, 5, 8, 7, 8, 8, + 11,11, 4, 5, 5, 7, 8, 8, 8,11,11, 6, 8, 7, 9, 9, + 10, 9,12,12, 6, 7, 8, 9,10, 9,10,12,12, 8, 8, 8, + 10, 9,12,11,13,13, 8, 8, 8, 9,10,11,12,13,13,10, + 11,11,12,11,13,13,14,14,10,11,11,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44u7__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u7__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p5_0 = { + _vq_quantthresh__44u7__p5_0, + _vq_quantmap__44u7__p5_0, + 9, + 9 +}; + +static static_codebook _44u7__p5_0 = { + 2, 81, + _vq_lengthlist__44u7__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u7__p5_0, + NULL, + &_vq_auxt__44u7__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u7__p6_0[] = { + 4, 4, 4, 5, 5, 7, 7, 9, 9, 4, 4, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 5, 6, 6, 6, 7, 8, 8, 9, 9, 7, 7, 7, + 8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,10, 9, + 9, 9,10, 9,10,10,11,11, 9, 9, 9, 9,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__44u7__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u7__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p6_0 = { + _vq_quantthresh__44u7__p6_0, + _vq_quantmap__44u7__p6_0, + 9, + 9 +}; + +static static_codebook _44u7__p6_0 = { + 2, 81, + _vq_lengthlist__44u7__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u7__p6_0, + NULL, + &_vq_auxt__44u7__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8,10,10, 8, + 10,10, 5, 8, 9, 8,10,10, 8,10,10, 4, 9, 9, 9,11, + 12, 8,12,11, 8,12,11,11,12,13,10,13,13, 7,12,11, + 10,13,12,10,13,13, 4, 9, 9, 8,11,12, 9,11,12, 7, + 11,12,10,13,13,10,12,13, 8,11,12,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u7__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u7__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p7_0 = { + _vq_quantthresh__44u7__p7_0, + _vq_quantmap__44u7__p7_0, + 3, + 3 +}; + +static static_codebook _44u7__p7_0 = { + 4, 81, + _vq_lengthlist__44u7__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u7__p7_0, + NULL, + &_vq_auxt__44u7__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p7_1[] = { + 3, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8, 6, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 6, 6, 6, 7, + 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 8, 7, 8, 8, 9, 9, + 9, 9, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u7__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u7__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p7_1 = { + _vq_quantthresh__44u7__p7_1, + _vq_quantmap__44u7__p7_1, + 11, + 11 +}; + +static static_codebook _44u7__p7_1 = { + 2, 121, + _vq_lengthlist__44u7__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u7__p7_1, + NULL, + &_vq_auxt__44u7__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, + 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11, + 11, 6, 8, 8, 9, 9,10,10,11,11,12,12, 6, 8, 8, 9, + 9,10,10,11,11,12,12, 8, 9, 9,10,10,11,11,12,12, + 14,13, 8, 9, 9,10,10,11,11,12,12,13,13,10,10,10, + 11,11,12,12,13,13,14,14,10,10,10,11,11,12,13,13, + 13,14,14,11,12,11,13,12,13,14,14,14,15,15,11,11, + 12,13,13,13,13,14,14,15,15, +}; + +static float _vq_quantthresh__44u7__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u7__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p8_0 = { + _vq_quantthresh__44u7__p8_0, + _vq_quantmap__44u7__p8_0, + 11, + 11 +}; + +static static_codebook _44u7__p8_0 = { + 2, 121, + _vq_lengthlist__44u7__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u7__p8_0, + NULL, + &_vq_auxt__44u7__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 6, + 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, + 8, 6, 7, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u7__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u7__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p8_1 = { + _vq_quantthresh__44u7__p8_1, + _vq_quantmap__44u7__p8_1, + 11, + 11 +}; + +static static_codebook _44u7__p8_1 = { + 2, 121, + _vq_lengthlist__44u7__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u7__p8_1, + NULL, + &_vq_auxt__44u7__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p9_0[] = { + 1, 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 5, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u7__p9_0[] = { + -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, 1592.5, + 2229.5, 2866.5, +}; + +static long _vq_quantmap__44u7__p9_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_0 = { + _vq_quantthresh__44u7__p9_0, + _vq_quantmap__44u7__p9_0, + 11, + 11 +}; + +static static_codebook _44u7__p9_0 = { + 2, 121, + _vq_lengthlist__44u7__p9_0, + 1, -512171520, 1630791680, 4, 0, + _vq_quantlist__44u7__p9_0, + NULL, + &_vq_auxt__44u7__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u7__p9_1[] = { + 1, 4, 4, 5, 5, 7, 7,10, 9,11,11,12,12, 4, 7, 6, + 8, 8, 9, 9,11,10,13,12,13,13, 4, 6, 7, 8, 8, 9, + 9,10,11,13,13,12,13, 5, 8, 8,10, 9,12,11,12,12, + 13,13,15,14, 6, 8, 8,10,10,11,11,13,12,13,14,14, + 15, 8,10,10,12,11,13,13,14,15,15,16,15,16, 8, 9, + 10,12,12,13,13,16,15,15,15,15,15,10,11,11,14,13, + 14,14,16,16,15,16,16,16,10,12,12,12,14,14,14,15, + 16,15,16,15,16,11,12,12,14,14,16,16,15,16,16,16, + 16,16,12,12,13,13,15,15,14,15,16,16,16,16,16,12, + 14,14,15,14,16,16,16,16,16,16,16,16,13,14,13,14, + 15,16,15,16,16,16,16,16,16, +}; + +static float _vq_quantthresh__44u7__p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44u7__p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_1 = { + _vq_quantthresh__44u7__p9_1, + _vq_quantmap__44u7__p9_1, + 13, + 13 +}; + +static static_codebook _44u7__p9_1 = { + 2, 169, + _vq_lengthlist__44u7__p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44u7__p9_1, + NULL, + &_vq_auxt__44u7__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u7__p9_2[] = { + 2, 4, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u7__p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u7__p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_2 = { + _vq_quantthresh__44u7__p9_2, + _vq_quantmap__44u7__p9_2, + 49, + 49 +}; + +static static_codebook _44u7__p9_2 = { + 1, 49, + _vq_lengthlist__44u7__p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u7__p9_2, + NULL, + &_vq_auxt__44u7__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u7__short[] = { + 6,14,18,18,18,18,17,17,17,17, 4, 8,11,12,13,11, + 13,11,16,17, 6, 7, 8, 9, 8, 9,12, 9,14,17, 6, 9, + 11,12,12,12,15,12,17,17, 6, 6, 6, 8, 5, 7, 7, 8, + 14,17, 7, 9, 9,11, 8,10,10,11,14,16, 8, 7, 7, 8, + 5, 7, 4, 5,11,17, 9, 8,10, 9, 7, 9, 4, 2, 9,16, + 15,14,16,14, 8,14, 4, 3, 7,16,17,17,16,17, 9,15, + 6, 5,10,17, +}; + +static static_codebook _huff_book__44u7__short = { + 2, 100, + _huff_lengthlist__44u7__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u8__long[] = { + 3, 9,13,13,14,13,13,13,13,14, 5, 4, 6, 8,10,12, + 13,15,13,14, 9, 5, 3, 5, 8,10,12,14,13,13,11, 7, + 4, 3, 5, 7,10,11,12,14,11, 9, 7, 4, 4, 6, 8,10, + 13,14,10,11, 9, 7, 6, 6, 7, 9,12,15,12,11,11, 8, + 7, 6, 6, 7,11,14,12,12,12,10, 8, 7, 6, 7, 9,13, + 11,12,13,12,11, 8, 8, 7, 9,12,11,14,16,16,15,11, + 10, 9, 9,11, +}; + +static static_codebook _huff_book__44u8__long = { + 2, 100, + _huff_lengthlist__44u8__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u8__short[] = { + 7,15,18,18,18,18,18,18,18,18, 4, 6, 9,10,10,11, + 16,15,18,18, 5, 6, 6, 6, 8,10,15,15,18,18, 5, 6, + 5, 4, 6, 9,12,15,17,18, 7, 6, 6, 5, 6, 5, 8,11, + 15,18,10, 9, 9, 7, 4, 3, 6,10,16,17,13,12,12, 6, + 6, 4, 5, 9,14,16,16,17,13, 5, 5, 4, 5, 8,13,16, + 17,17,14, 7, 7, 6, 7,10,15,17,17,17,17,11,12,12, + 12,14,17,17, +}; + +static static_codebook _huff_book__44u8__short = { + 2, 100, + _huff_lengthlist__44u8__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u8_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 8, 9, 9, 7, + 8, 9, 5, 7, 7, 7, 9, 8, 8, 9, 9, 5, 7, 7, 7, 9, + 9, 7, 9, 9, 8, 9, 9, 9,10,11, 9,10,10, 7, 9, 9, + 9,10, 9, 9,10,11, 5, 7, 7, 7, 9, 9, 8, 9, 9, 7, + 9, 9, 9,11,10, 9, 9,10, 8, 9, 9, 9,10,10, 9,11, + 10, +}; + +static float _vq_quantthresh__44u8_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u8_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p1_0 = { + _vq_quantthresh__44u8_p1_0, + _vq_quantmap__44u8_p1_0, + 3, + 3 +}; + +static static_codebook _44u8_p1_0 = { + 4, 81, + _vq_lengthlist__44u8_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u8_p1_0, + NULL, + &_vq_auxt__44u8_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u8_p2_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 7, 8, 9,10, 9,10,10,12,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,12, 8, 9, 9,11,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,13,11, + 11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,13,13,11,12,12,14,13, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12, + 12, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11, + 8, 9, 9,10,11,10,11,11,12,12,10,10,11,12,13, 6, + 8, 8,10,10, 7, 8, 8,11,10, 8, 8, 9,10,11,10,11, + 10,12,11,10,11,11,12,12, 9,10,10,12,12,10,11,11, + 13,13,10,11,11,13,13,12,12,13,13,14,12,12,13,14, + 14, 9,10,10,12,12, 9,10,10,12,12,10,11,11,12,13, + 11,12,11,14,12,12,12,12,14,14, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,11, 9,10, + 10,12,12, 6, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 8, + 10,11,10,11,11,13,12,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,11,10, 8, 9, 9,11,11,10,11,10,13,12, + 10,11,11,12,12, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,12,12,13,13,14,14,11,11,12,12,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,11,13,12,12,13,12, + 14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,14, + 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12, + 13,13,14,15,12,12,13,14,14, 9,10,10,12,12, 9,11, + 10,13,12,10,11,11,12,13,12,13,12,14,13,12,12,13, + 14,14,11,12,12,14,14,12,12,12,14,14,12,13,13,14, + 14,13,13,14,14,16,14,14,14,15,15,11,12,12,14,14, + 11,12,11,14,13,12,12,13,14,14,13,14,12,15,13,14, + 14,14,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,14,13,11,12,12,13,14, 9,10,10, + 12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14, + 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13, + 10,11,11,13,13,12,12,12,14,14,12,13,12,15,14,11, + 12,11,14,13,12,13,12,14,14,11,11,12,13,14,13,14, + 14,16,15,13,12,14,13,15,11,12,12,13,14,12,13,13, + 14,14,12,13,12,14,14,14,14,14,15,16,13,14,13,15, + 14, +}; + +static float _vq_quantthresh__44u8_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u8_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p2_0 = { + _vq_quantthresh__44u8_p2_0, + _vq_quantmap__44u8_p2_0, + 5, + 5 +}; + +static static_codebook _44u8_p2_0 = { + 4, 625, + _vq_lengthlist__44u8_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u8_p2_0, + NULL, + &_vq_auxt__44u8_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u8_p3_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 7, 7, + 8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9, + 9, 9,10,10,11,10,12,12, 9, 9, 9,10,10,10,11,12, + 12, +}; + +static float _vq_quantthresh__44u8_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u8_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p3_0 = { + _vq_quantthresh__44u8_p3_0, + _vq_quantmap__44u8_p3_0, + 9, + 9 +}; + +static static_codebook _44u8_p3_0 = { + 2, 81, + _vq_lengthlist__44u8_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u8_p3_0, + NULL, + &_vq_auxt__44u8_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u8_p4_0[] = { + 4, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,11,11,11, + 11, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11, + 12,12, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11,11,12, 6, 6, 6, 7, 7, 8, 7, 9, 9, 9, 9,10,10, + 11,11,12,12, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9,10, + 10,11,11,12,12, 7, 7, 7, 8, 7, 9, 8, 9, 9,10, 9, + 11,10,11,11,12,12, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, + 10,10,10,11,11,12,12, 8, 8, 8, 9, 9, 9, 9,10,10, + 10,10,11,11,11,11,12,12, 8, 8, 8, 8, 9, 9, 9,10, + 10,10,10,11,11,11,12,12,12, 9, 9, 9, 9, 9,10, 9, + 10,10,11,10,11,11,12,12,12,12, 9, 9, 9, 9, 9, 9, + 10,10,10,11,11,11,11,12,12,12,13,10,10,10,10,10, + 11,10,11,11,11,11,12,12,12,12,12,13,10,10,10,10, + 10,10,11,11,11,11,11,12,12,12,12,13,12,11,11,11, + 11,11,11,11,12,12,12,12,12,12,12,13,13,13,11,11, + 11,11,11,11,11,12,12,12,12,12,12,13,12,13,13,11, + 12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13, + 12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13, + 13, +}; + +static float _vq_quantthresh__44u8_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u8_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p4_0 = { + _vq_quantthresh__44u8_p4_0, + _vq_quantmap__44u8_p4_0, + 17, + 17 +}; + +static static_codebook _44u8_p4_0 = { + 2, 289, + _vq_lengthlist__44u8_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u8_p4_0, + NULL, + &_vq_auxt__44u8_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u8_p5_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7, 8, 9, 7, + 9, 9, 5, 7, 8, 7, 9, 9, 7, 9, 8, 5, 7, 7, 8, 9, + 9, 7, 9, 9, 7, 9, 9, 8, 9,11, 9,11,11, 7, 9, 9, + 9,11,10, 9,11,11, 5, 7, 8, 7, 9, 9, 8, 9, 9, 7, + 9, 9, 9,11,11, 9,10,11, 7, 9, 9, 9,11,11, 8,11, + 9, +}; + +static float _vq_quantthresh__44u8_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u8_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p5_0 = { + _vq_quantthresh__44u8_p5_0, + _vq_quantmap__44u8_p5_0, + 3, + 3 +}; + +static static_codebook _44u8_p5_0 = { + 4, 81, + _vq_lengthlist__44u8_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u8_p5_0, + NULL, + &_vq_auxt__44u8_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u8_p5_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8, 5, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, + 8, 6, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 6, 6, 6, 7, + 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u8_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u8_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p5_1 = { + _vq_quantthresh__44u8_p5_1, + _vq_quantmap__44u8_p5_1, + 11, + 11 +}; + +static static_codebook _44u8_p5_1 = { + 2, 121, + _vq_lengthlist__44u8_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u8_p5_1, + NULL, + &_vq_auxt__44u8_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u8_p6_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9,10,10,10, 5, 6, 6, + 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 6, 6, 7, 7, 8, + 9, 9, 9,10,10,11,11, 7, 7, 7, 8, 8, 9, 9,10,10, + 11,11,11,11, 7, 7, 7, 8, 8, 9, 9,10,10,10,11,11, + 11, 8, 9, 9, 9, 9,10,10,10,10,11,11,12,12, 8, 9, + 9, 9, 9,10,10,10,11,11,11,12,12, 8, 9, 9,10,10, + 11,10,11,11,12,12,12,12, 9, 9, 9,10,10,11,11,11, + 11,12,12,12,12,10,10,10,11,11,11,11,12,12,12,12, + 13,13,10,10,10,11,11,11,11,12,12,12,12,13,13,11, + 11,11,12,12,12,12,12,12,13,13,13,13,11,11,11,12, + 12,12,12,12,12,13,13,13,13, +}; + +static float _vq_quantthresh__44u8_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u8_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p6_0 = { + _vq_quantthresh__44u8_p6_0, + _vq_quantmap__44u8_p6_0, + 13, + 13 +}; + +static static_codebook _44u8_p6_0 = { + 2, 169, + _vq_lengthlist__44u8_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u8_p6_0, + NULL, + &_vq_auxt__44u8_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u8_p6_1[] = { + 3, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44u8_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u8_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p6_1 = { + _vq_quantthresh__44u8_p6_1, + _vq_quantmap__44u8_p6_1, + 5, + 5 +}; + +static static_codebook _44u8_p6_1 = { + 2, 25, + _vq_lengthlist__44u8_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u8_p6_1, + NULL, + &_vq_auxt__44u8_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u8_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, + 8, 8, 9, 8, 9, 9,10,10,11,11, 4, 6, 6, 8, 8, 8, + 9, 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12, 7, 8, 8, 9, 9,10,10,10,10,11,11,12, + 12, 8, 9, 9,10,10,10,10,11,11,12,12,13,13, 8, 9, + 9,10,10,10,11,11,11,12,13,13,13, 9, 9, 9,10,10, + 11,11,12,12,13,13,14,14, 9, 9, 9,10,10,11,11,12, + 12,13,13,14,14,10,10,10,11,11,12,12,13,13,14,14, + 14,14,10,10,11,11,12,12,12,13,13,13,14,14,15,11, + 11,11,12,12,13,13,14,14,14,14,16,15,11,11,11,12, + 12,13,13,14,14,14,14,16,15, +}; + +static float _vq_quantthresh__44u8_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44u8_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p7_0 = { + _vq_quantthresh__44u8_p7_0, + _vq_quantmap__44u8_p7_0, + 13, + 13 +}; + +static static_codebook _44u8_p7_0 = { + 2, 169, + _vq_lengthlist__44u8_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44u8_p7_0, + NULL, + &_vq_auxt__44u8_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u8_p7_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u8_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u8_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p7_1 = { + _vq_quantthresh__44u8_p7_1, + _vq_quantmap__44u8_p7_1, + 11, + 11 +}; + +static static_codebook _44u8_p7_1 = { + 2, 121, + _vq_lengthlist__44u8_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u8_p7_1, + NULL, + &_vq_auxt__44u8_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u8_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8,10,10,11,11, 4, + 6, 6, 8, 8,10,10, 9, 9,10,10,11,10,12,12, 4, 6, + 6, 8, 8, 9,10, 9, 9,10,10,11,11,11,12, 7, 8, 8, + 10,10,11,11,11,10,11,11,13,12,13,12, 7, 8, 8,10, + 10,11,11,10,11,11,11,12,12,13,13, 8,10, 9,11,11, + 12,12,11,11,12,12,13,13,14,14, 8, 9, 9,11,11,12, + 12,11,11,12,12,14,13,13,13, 8, 9, 9,11,10,12,11, + 12,12,13,13,14,13,14,13, 8, 9, 9,11,11,11,12,12, + 12,13,13,13,14,14,14, 9,10,10,12,11,12,12,13,13, + 14,14,15,13,14,14, 9,10,10,11,12,12,12,13,13,14, + 14,15,14,14,14,10,11,11,12,12,13,13,14,13,14,14, + 15,14,15,15,10,11,11,12,12,13,13,13,14,14,14,14, + 15,16,15,11,12,12,13,12,14,14,14,13,15,14,16,15, + 16,15,11,12,12,13,13,13,14,14,15,15,15,15,16,15, + 15, +}; + +static float _vq_quantthresh__44u8_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44u8_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p8_0 = { + _vq_quantthresh__44u8_p8_0, + _vq_quantmap__44u8_p8_0, + 15, + 15 +}; + +static static_codebook _44u8_p8_0 = { + 2, 225, + _vq_lengthlist__44u8_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44u8_p8_0, + NULL, + &_vq_auxt__44u8_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44u8_p8_1[] = { + 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 7, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9,10, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 9,10,10, 9,10, 9,10, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10, 9,10,10, 9,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9,10, 9,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10, 9, 9,10,10,10,10,10,10,10,10, + 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44u8_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44u8_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p8_1 = { + _vq_quantthresh__44u8_p8_1, + _vq_quantmap__44u8_p8_1, + 21, + 21 +}; + +static static_codebook _44u8_p8_1 = { + 2, 441, + _vq_lengthlist__44u8_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44u8_p8_1, + NULL, + &_vq_auxt__44u8_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u8_p9_0[] = { + 1, 4, 4, 9, 9, 9, 9, 9, 9, 5, 9, 9, 8, 8, 8, 8, + 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u8_p9_0[] = { + -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5, 2327.5, 3258.5, +}; + +static long _vq_quantmap__44u8_p9_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_0 = { + _vq_quantthresh__44u8_p9_0, + _vq_quantmap__44u8_p9_0, + 9, + 9 +}; + +static static_codebook _44u8_p9_0 = { + 2, 81, + _vq_lengthlist__44u8_p9_0, + 1, -511895552, 1631393792, 4, 0, + _vq_quantlist__44u8_p9_0, + NULL, + &_vq_auxt__44u8_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44u8_p9_1[] = { + 1, 4, 4, 7, 7, 8, 8, 7, 8, 9, 9,10,10,11,11,12, + 12,12,12, 4, 7, 6, 9, 9, 9, 9, 9, 8, 9, 9,11,10, + 12,11,13,12,13,14, 4, 6, 6, 9, 9, 9, 9, 8, 9, 9, + 10,10,11,12,12,12,12,13,12, 7, 9, 8,11,10,10,10, + 10,10,11,11,12,11,14,12,13,14,14,13, 7, 8, 9,10, + 10,10,10,10,10,11,11,12,13,13,13,14,15,15,13, 8, + 9, 9,11,11,11,11,11,12,13,12,14,14,14,14,14,14, + 15,13, 8, 9, 9,10,11,11,11,12,12,13,12,13,14,13, + 15,14,15,15,15, 8, 9, 9,10,10,12,11,13,12,13,13, + 14,14,13,15,14,15,14,14, 8, 9, 9,10,11,12,12,13, + 13,14,14,14,14,15,15,15,12,14,14, 9,11,10,11,11, + 14,12,13,14,15,14,14,14,14,15,15,15,15,15, 9,10, + 11,11,12,12,13,13,14,14,14,14,15,15,14,15,15,15, + 15,10,11,11,12,12,14,14,13,14,14,15,15,15,15,15, + 15,15,15,15,10,11,11,12,13,13,13,14,14,15,15,14, + 14,15,15,15,15,14,15,11,12,13,15,13,14,15,15,15, + 15,14,15,15,15,15,15,15,15,15,11,12,12,14,14,14, + 13,14,15,15,14,15,15,15,15,15,15,15,15,13,13,14, + 13,13,14,14,15,14,15,15,15,15,15,15,15,15,15,15, + 11,14,13,14,14,15,14,14,15,15,15,15,15,15,15,15, + 15,15,15,12,12,13,14,13,13,14,15,14,15,15,15,15, + 15,15,15,15,15,15,13,13,14,14,13,15,14,14,15,15, + 14,15,15,15,15,15,15,15,15, +}; + +static float _vq_quantthresh__44u8_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44u8_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_1 = { + _vq_quantthresh__44u8_p9_1, + _vq_quantmap__44u8_p9_1, + 19, + 19 +}; + +static static_codebook _44u8_p9_1 = { + 2, 361, + _vq_lengthlist__44u8_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44u8_p9_1, + NULL, + &_vq_auxt__44u8_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u8_p9_2[] = { + 2, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44u8_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u8_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_2 = { + _vq_quantthresh__44u8_p9_2, + _vq_quantmap__44u8_p9_2, + 49, + 49 +}; + +static static_codebook _44u8_p9_2 = { + 1, 49, + _vq_lengthlist__44u8_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u8_p9_2, + NULL, + &_vq_auxt__44u8_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u9__long[] = { + 3, 9,13,13,14,14,13,14,14,13, 5, 5, 9,10,12,13, + 13,14,14,14, 9, 5, 6, 6, 8,11,12,14,14,14,11, 7, + 5, 3, 5, 8,10,12,13,12,12,10, 7, 4, 3, 5, 8,10, + 12,13,10,12, 9, 7, 4, 4, 6, 8,11,13,12,12,11, 9, + 7, 5, 6, 7, 9,13,12,12,12,11, 8, 7, 6, 6, 8,12, + 12,12,13,12,10, 9, 7, 7, 8,11,11,13,15,15,14,12, + 10, 9, 9,10, +}; + +static static_codebook _huff_book__44u9__long = { + 2, 100, + _huff_lengthlist__44u9__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u9__short[] = { + 10,17,18,18,18,18,18,18,18,18, 5, 8,12,13,14,13, + 16,17,16,17, 5, 6, 8, 8,10, 9,12,16,16,17, 5, 6, + 7, 5, 6, 9,12,15,16,16, 7, 6, 6, 4, 5, 7, 9,14, + 15,17,10, 8, 8, 6, 6, 3, 5, 9,13,18,14,11,11,10, + 6, 3, 4, 7,13,17,15,16,16,10, 5, 6, 4, 4, 9,13, + 18,18,18,11, 6, 8, 5, 6,10,15,18,18,18,14,10,11, + 9,10,16,18, +}; + +static static_codebook _huff_book__44u9__short = { + 2, 100, + _huff_lengthlist__44u9__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u9_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 8, 9, 9, 7, + 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 7, 9, + 9, 7, 9, 9, 8, 9, 9, 9,10,11, 9,11,10, 7, 9, 9, + 9,11,10, 9,10,11, 5, 7, 7, 7, 9, 9, 7, 9, 9, 7, + 9, 9, 9,11,11, 9,10,11, 8, 9, 9, 9,10,10, 9,11, + 10, +}; + +static float _vq_quantthresh__44u9_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u9_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p1_0 = { + _vq_quantthresh__44u9_p1_0, + _vq_quantmap__44u9_p1_0, + 3, + 3 +}; + +static static_codebook _44u9_p1_0 = { + 4, 81, + _vq_lengthlist__44u9_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u9_p1_0, + NULL, + &_vq_auxt__44u9_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u9_p2_0[] = { + 3, 6, 5, 8, 8, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 9, 9,11,10, 8, 9, 9,10,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 8, 8, 9,10, 9,10,10,11,11, 9, 9,10, + 11,11, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,11,11, 9,10,10,11,11, 8, 9, 9,11,11, + 9,10,10,12,11, 9,10,10,11,11,11,12,12,13,13,11, + 11,11,12,13, 8, 9, 9,11,11, 9,10,10,11,11, 9,10, + 10,12,12,11,11,11,13,12,11,11,11,13,13, 6, 7, 7, + 9, 9, 7, 8, 8,10, 9, 7, 8, 8, 9,10, 9,10,10,11, + 11, 9,10,10,11,11, 7, 8, 8,10,10, 8, 9, 9,10,10, + 8, 9, 9,10,10,10,10,10,12,12,10,10,10,11,12, 7, + 8, 8,10,10, 8, 9, 8,10,10, 8, 9, 9,10,10, 9,10, + 10,12,11,10,10,10,12,12, 9,10,10,12,11,10,10,10, + 12,12,10,10,10,12,12,12,12,12,12,13,11,12,12,13, + 13, 9,10,10,11,11, 9,10,10,12,11,10,10,10,12,12, + 11,12,11,13,12,12,12,12,13,13, 6, 7, 7, 9, 9, 7, + 8, 8,10, 9, 7, 8, 8, 9,10, 9,10,10,12,11, 9,10, + 10,11,11, 7, 8, 8,10, 9, 8, 9, 9,11,10, 8, 8, 9, + 10,10,10,10,10,12,12,10,10,10,11,12, 7, 8, 8,10, + 10, 8, 9, 9,10,10, 8, 9, 9,10,10,10,10,10,12,12, + 10,10,10,12,12, 9,10,10,11,11,10,11,10,12,12, 9, + 10,10,11,12,11,12,12,13,13,11,11,12,11,13, 9,10, + 10,11,12,10,10,10,12,12,10,10,10,12,12,11,12,12, + 13,13,12,12,12,13,13, 8, 9, 9,11,11, 9,10,10,12, + 11, 9,10,10,11,12,11,12,12,13,13,11,11,12,13,13, + 9,10,10,12,12,10,10,10,12,12,10,11,10,12,12,12, + 12,12,13,13,12,12,12,13,13, 9,10,10,12,11,10,10, + 10,12,11,10,10,10,12,12,11,12,12,13,13,12,12,12, + 13,14,11,12,12,13,13,11,12,12,13,13,11,12,12,13, + 13,13,13,14,13,15,13,13,13,14,14,11,11,11,13,13, + 11,12,11,13,13,11,12,12,13,13,12,13,12,14,12,13, + 13,13,15,14, 8, 9, 9,11,11, 9,10,10,11,11, 9,10, + 10,11,12,11,12,11,13,13,11,12,12,13,13, 9,10,10, + 11,11,10,11,10,12,12, 9,10,10,12,12,12,12,12,13, + 13,11,11,12,12,13, 9,10,10,12,12,10,10,11,12,12, + 10,11,10,12,12,11,12,12,13,13,12,12,12,13,13,11, + 11,11,13,13,11,12,12,13,13,11,11,12,13,13,13,13, + 13,14,14,12,12,13,12,14,11,11,12,13,13,12,12,12, + 14,13,11,12,12,13,13,13,13,13,14,14,13,13,13,14, + 13, +}; + +static float _vq_quantthresh__44u9_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u9_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p2_0 = { + _vq_quantthresh__44u9_p2_0, + _vq_quantmap__44u9_p2_0, + 5, + 5 +}; + +static static_codebook _44u9_p2_0 = { + 4, 625, + _vq_lengthlist__44u9_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u9_p2_0, + NULL, + &_vq_auxt__44u9_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u9_p3_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 8, 4, 5, 5, 6, 6, 7, 7, + 9, 9, 4, 5, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 6, + 8, 7, 9, 9, 5, 6, 6, 6, 7, 7, 8, 9, 9, 7, 7, 7, + 8, 7, 9, 8,10,10, 7, 7, 7, 7, 8, 8, 9,10,10, 9, + 9, 9, 9, 9,10,10,11,11, 9, 9, 9, 9, 9,10,10,11, + 11, +}; + +static float _vq_quantthresh__44u9_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u9_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p3_0 = { + _vq_quantthresh__44u9_p3_0, + _vq_quantmap__44u9_p3_0, + 9, + 9 +}; + +static static_codebook _44u9_p3_0 = { + 2, 81, + _vq_lengthlist__44u9_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u9_p3_0, + NULL, + &_vq_auxt__44u9_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u9_p4_0[] = { + 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,10, 9,11,10, + 12,11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9,10,10, + 11,11,11, 6, 6, 6, 7, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12, 7, 7, 7, 7, 7, 8, 8, 9, 8, 9, 9, + 10,10,11,11,12,12, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, + 9,10,10,11,11,12,12, 8, 8, 8, 8, 8, 9, 8, 9, 9, + 10,10,11,10,12,11,12,12, 8, 8, 8, 8, 8, 8, 9, 9, + 9,10,10,10,11,11,12,12,13, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,10,11,11,12,12,13,12, 8, 8, 9, 9, 9, 9, + 9,10,10,10,11,11,11,12,12,12,13, 9,10, 9,10,10, + 10,10,11,10,11,11,12,11,13,12,13,13, 9, 9,10,10, + 10,10,10,10,11,11,11,11,12,12,13,13,13,10,11,10, + 11,11,11,11,12,11,12,12,13,12,13,13,14,13,10,10, + 11,11,11,11,11,11,12,12,12,12,13,13,13,13,14,11, + 12,11,12,12,12,12,12,12,13,13,13,13,14,13,14,14, + 11,11,12,12,12,12,12,12,12,12,13,13,13,13,14,14, + 14, +}; + +static float _vq_quantthresh__44u9_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u9_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p4_0 = { + _vq_quantthresh__44u9_p4_0, + _vq_quantmap__44u9_p4_0, + 17, + 17 +}; + +static static_codebook _44u9_p4_0 = { + 2, 289, + _vq_lengthlist__44u9_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u9_p4_0, + NULL, + &_vq_auxt__44u9_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u9_p5_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7, 8, 9, 7, + 8, 9, 5, 7, 8, 7, 9, 8, 7, 9, 8, 5, 8, 8, 8, 9, + 9, 7, 9, 9, 7, 9, 9, 8, 9,11, 9,11,10, 7, 9, 9, + 9,11, 9, 9,10,11, 5, 7, 8, 7, 9, 9, 8, 9, 9, 7, + 9, 9, 9,11,10, 9, 9,11, 7, 9, 9, 9,10,11, 8,11, + 9, +}; + +static float _vq_quantthresh__44u9_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u9_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p5_0 = { + _vq_quantthresh__44u9_p5_0, + _vq_quantmap__44u9_p5_0, + 3, + 3 +}; + +static static_codebook _44u9_p5_0 = { + 4, 81, + _vq_lengthlist__44u9_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u9_p5_0, + NULL, + &_vq_auxt__44u9_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u9_p5_1[] = { + 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u9_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u9_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p5_1 = { + _vq_quantthresh__44u9_p5_1, + _vq_quantmap__44u9_p5_1, + 11, + 11 +}; + +static static_codebook _44u9_p5_1 = { + 2, 121, + _vq_lengthlist__44u9_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u9_p5_1, + NULL, + &_vq_auxt__44u9_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u9_p6_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 5, 5, + 7, 7, 8, 8, 8, 8,10,10,11,11, 4, 5, 5, 7, 7, 8, + 8, 8, 8,10,10,11,11, 6, 7, 7, 8, 7, 8, 8, 9, 9, + 10,10,11,11, 6, 7, 7, 8, 7, 8, 8, 9, 9,10,10,11, + 11, 7, 8, 8, 8, 8, 9, 9, 9,10,11,11,12,12, 7, 8, + 8, 8, 8, 9, 9,10, 9,11,11,12,12, 8, 9, 8, 9, 9, + 10,10,10,10,11,11,12,12, 8, 8, 8, 9, 9,10, 9,10, + 10,11,11,12,12, 9,10,10,10,10,11,11,11,11,12,12, + 13,13, 9,10,10,10,10,11,11,11,11,12,12,13,12,10, + 11,11,11,11,12,12,12,12,12,12,13,13,10,11,11,11, + 11,12,12,12,12,13,12,13,13, +}; + +static float _vq_quantthresh__44u9_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u9_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p6_0 = { + _vq_quantthresh__44u9_p6_0, + _vq_quantmap__44u9_p6_0, + 13, + 13 +}; + +static static_codebook _44u9_p6_0 = { + 2, 169, + _vq_lengthlist__44u9_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u9_p6_0, + NULL, + &_vq_auxt__44u9_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u9_p6_1[] = { + 4, 4, 4, 5, 5, 4, 5, 4, 5, 5, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44u9_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u9_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p6_1 = { + _vq_quantthresh__44u9_p6_1, + _vq_quantmap__44u9_p6_1, + 5, + 5 +}; + +static static_codebook _44u9_p6_1 = { + 2, 25, + _vq_lengthlist__44u9_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u9_p6_1, + NULL, + &_vq_auxt__44u9_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u9_p7_0[] = { + 1, 5, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 5, 6, 6, + 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 6, 6, 7, 7, 8, + 8, 9, 9,10,10,11,11, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12, 7, 7, 7, 8, 8, 9, 9,10,10,11,11,12, + 12, 8, 8, 8, 9, 9,10,10,11,10,12,12,13,12, 8, 8, + 8, 9, 9,10,10,11,11,12,12,12,13, 9, 9, 9,10,10, + 11,11,12,11,13,13,13,14, 9, 9, 9,10,10,11,11,11, + 12,13,12,13,13,10,10,10,11,11,12,12,13,12,13,13, + 14,14,10,10,10,11,11,11,12,12,12,13,13,14,14,11, + 11,11,12,12,13,13,13,13,14,14,15,14,11,11,11,12, + 12,13,13,13,14,14,15,15,15, +}; + +static float _vq_quantthresh__44u9_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44u9_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p7_0 = { + _vq_quantthresh__44u9_p7_0, + _vq_quantmap__44u9_p7_0, + 13, + 13 +}; + +static static_codebook _44u9_p7_0 = { + 2, 169, + _vq_lengthlist__44u9_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44u9_p7_0, + NULL, + &_vq_auxt__44u9_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u9_p7_1[] = { + 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, 8, +}; + +static float _vq_quantthresh__44u9_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u9_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p7_1 = { + _vq_quantthresh__44u9_p7_1, + _vq_quantmap__44u9_p7_1, + 11, + 11 +}; + +static static_codebook _44u9_p7_1 = { + 2, 121, + _vq_lengthlist__44u9_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u9_p7_1, + NULL, + &_vq_auxt__44u9_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u9_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 9,10,10,11,11, 4, + 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,10,12,11, 4, 6, + 6, 8, 8, 9,10, 9, 9,10,10,11,11,12,12, 7, 8, 8, + 10,10,11,11,11,10,11,11,12,12,13,12, 7, 8, 8,10, + 10,11,11,10,10,11,12,12,12,13,13, 8,10, 9,11,11, + 12,12,11,12,12,12,13,13,14,14, 8, 9, 9,11,11,12, + 12,11,12,12,13,13,13,14,14, 8, 9, 9,10,10,11,11, + 13,12,13,13,14,14,15,14, 8, 9, 9,10,10,11,12,12, + 13,13,13,14,14,14,15, 9,10,10,11,11,13,12,13,13, + 14,14,15,15,15,15, 9,10,10,11,12,12,12,13,13,14, + 15,14,15,15,15,10,11,11,12,12,13,13,14,14,15,15, + 15,16,16,15,10,11,11,12,12,13,14,14,14,15,14,15, + 16,16,17,11,12,12,13,13,14,14,15,14,16,15,15,16, + 16,16,11,12,12,13,13,14,14,14,15,15,15,16,16,17, + 16, +}; + +static float _vq_quantthresh__44u9_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44u9_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p8_0 = { + _vq_quantthresh__44u9_p8_0, + _vq_quantmap__44u9_p8_0, + 15, + 15 +}; + +static static_codebook _44u9_p8_0 = { + 2, 225, + _vq_lengthlist__44u9_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44u9_p8_0, + NULL, + &_vq_auxt__44u9_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44u9_p8_1[] = { + 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 8, 8, + 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, + 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10, 9,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, + 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9, 9, 9, 9, 9, 9,10,10, 9,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44u9_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44u9_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p8_1 = { + _vq_quantthresh__44u9_p8_1, + _vq_quantmap__44u9_p8_1, + 21, + 21 +}; + +static static_codebook _44u9_p8_1 = { + 2, 441, + _vq_lengthlist__44u9_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44u9_p8_1, + NULL, + &_vq_auxt__44u9_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u9_p9_0[] = { + 1, 5, 5,10,10,10,10,10,10,10,10,10,10,10,10, 5, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 5,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44u9_p9_0[] = { + -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5, + 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, +}; + +static long _vq_quantmap__44u9_p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_0 = { + _vq_quantthresh__44u9_p9_0, + _vq_quantmap__44u9_p9_0, + 15, + 15 +}; + +static static_codebook _44u9_p9_0 = { + 2, 225, + _vq_lengthlist__44u9_p9_0, + 1, -510036736, 1631393792, 4, 0, + _vq_quantlist__44u9_p9_0, + NULL, + &_vq_auxt__44u9_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44u9_p9_1[] = { + 1, 4, 4, 7, 7, 8, 8, 7, 7, 9, 9,10,10,12,11,12, + 11,12,12, 4, 7, 6, 9, 9, 9, 9, 9, 9,10, 9,11, 9, + 11,11,13,12,14,12, 4, 6, 6, 9, 9, 9, 9, 8, 9,10, + 10,11,11,12,12,12,13,13,13, 7, 9, 8,11,11,11,11, + 10,10,11,11,12,12,14,13,14,14,15,13, 7, 9, 9,10, + 10,10,10,10,10,11,11,12,13,13,13,14,14,15,13, 8, + 9, 9,12,10,11,11,12,11,12,12,13,13,14,14,15,16, + 15,14, 8, 9, 9,10,11,12,11,11,12,13,12,14,14,13, + 15,16,15,14,16, 7, 9, 9,10,10,12,11,12,13,16,13, + 14,16,14,15,15,15,15,15, 7, 9, 9,10,11,11,12,12, + 13,14,16,14,14,16,16,14,14,14,15, 9,10,11,12,12, + 12,13,13,13,16,15,16,15,14,15,15,15,16,16, 9,10, + 11,12,13,13,14,13,14,15,14,14,16,16,16,16,16,16, + 16,10,11,11,13,13,15,13,15,13,14,16,16,16,16,16, + 16,15,14,16,11,11,12,12,13,13,15,13,15,14,15,16, + 16,16,16,16,16,16,16,12,13,13,13,13,15,14,15,16, + 16,16,16,14,16,16,16,16,16,16,13,12,12,14,14,13, + 15,14,16,15,16,16,16,16,16,16,16,16,15,12,12,13, + 13,14,16,15,16,15,16,16,16,16,16,16,16,16,16,16, + 12,13,13,14,15,14,14,16,16,15,16,16,16,16,16,16, + 15,16,16,13,14,14,13,14,14,15,16,15,16,16,16,16, + 16,16,16,16,15,16,12,13,13,14,14,14,14,16,16,16, + 16,16,16,15,16,16,16,16,16, +}; + +static float _vq_quantthresh__44u9_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44u9_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_1 = { + _vq_quantthresh__44u9_p9_1, + _vq_quantmap__44u9_p9_1, + 19, + 19 +}; + +static static_codebook _44u9_p9_1 = { + 2, 361, + _vq_lengthlist__44u9_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44u9_p9_1, + NULL, + &_vq_auxt__44u9_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u9_p9_2[] = { + 2, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44u9_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u9_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_2 = { + _vq_quantthresh__44u9_p9_2, + _vq_quantmap__44u9_p9_2, + 49, + 49 +}; + +static static_codebook _44u9_p9_2 = { + 1, 49, + _vq_lengthlist__44u9_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u9_p9_2, + NULL, + &_vq_auxt__44u9_p9_2, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 10,10, 5, 8, 8, 7,10,10, 8,10,10, 4, 9, 8, 8,11, + 11, 8,11,11, 7,11,11,10,11,13,10,13,13, 7,11,11, + 10,13,12,10,13,13, 5, 9, 8, 8,11,11, 8,11,11, 7, + 11,11, 9,13,13,10,12,13, 7,11,11,10,13,13,10,13, + 11, +}; + +static float _vq_quantthresh__8u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p1_0 = { + _vq_quantthresh__8u0__p1_0, + _vq_quantmap__8u0__p1_0, + 3, + 3 +}; + +static static_codebook _8u0__p1_0 = { + 4, 81, + _vq_lengthlist__8u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u0__p1_0, + NULL, + &_vq_auxt__8u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 6, 7, 8, 6, + 7, 8, 5, 7, 7, 6, 8, 8, 7, 9, 7, 5, 7, 7, 7, 9, + 9, 7, 8, 8, 6, 9, 8, 7, 7,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 9, 8,10,10, 7,10, + 8, +}; + +static float _vq_quantthresh__8u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p2_0 = { + _vq_quantthresh__8u0__p2_0, + _vq_quantmap__8u0__p2_0, + 3, + 3 +}; + +static static_codebook _8u0__p2_0 = { + 4, 81, + _vq_lengthlist__8u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u0__p2_0, + NULL, + &_vq_auxt__8u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 10, 9,11,11, 8, 9, 9,11,11, 6, 8, 8,10,10, 8,10, + 10,11,11, 8,10,10,11,11,10,11,11,12,12,10,11,11, + 12,13, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11, + 11, 9,10,11,12,12,10,11,11,12,12, 8,11,11,14,13, + 10,12,11,15,13,10,12,11,14,14,12,13,12,16,14,12, + 14,12,16,15, 8,11,11,13,14,10,11,12,13,15,10,11, + 12,13,15,11,12,13,14,15,12,12,14,14,16, 5, 8, 8, + 11,11, 9,11,11,12,12, 8,10,11,12,12,11,12,12,15, + 14,11,12,12,14,14, 7,11,10,13,12,10,11,12,13,14, + 10,12,12,14,13,12,13,13,14,15,12,13,13,15,15, 7, + 10,11,12,13,10,12,11,14,13,10,12,13,13,15,12,13, + 12,14,14,11,13,13,15,16, 9,12,12,15,14,11,13,13, + 15,16,11,13,13,16,16,13,14,15,15,15,12,14,15,17, + 16, 9,12,12,14,15,11,13,13,15,16,11,13,13,16,18, + 13,14,14,17,16,13,15,15,17,18, 5, 8, 9,11,11, 8, + 11,11,12,12, 8,10,11,12,12,11,12,12,14,14,11,12, + 12,14,15, 7,11,10,12,13,10,12,12,14,13,10,11,12, + 13,14,11,13,13,15,14,12,13,13,14,15, 7,10,11,13, + 13,10,12,12,13,14,10,12,12,13,13,11,13,13,16,16, + 12,13,13,15,14, 9,12,12,16,15,10,13,13,15,15,11, + 13,13,17,15,12,15,15,18,17,13,14,14,15,16, 9,12, + 12,15,15,11,13,13,15,16,11,13,13,15,15,12,15,15, + 16,16,13,15,14,17,15, 7,11,11,15,15,10,13,13,16, + 15,10,13,13,15,16,14,15,15,17,19,13,15,14,15,18, + 9,12,12,16,16,11,13,14,17,16,11,13,13,17,16,15, + 15,16,17,19,13,15,16, 0,18, 9,12,12,16,15,11,14, + 13,17,17,11,13,14,16,16,15,16,16,19,18,13,15,15, + 17,19,11,14,14,19,16,12,14,15, 0,18,12,16,15,18, + 17,15,15,18,16,19,14,15,17,19,19,11,14,14,18,19, + 13,15,14,19,19,12,16,15,18,17,15,17,15, 0,16,14, + 17,16,19, 0, 7,11,11,14,14,10,12,12,15,15,10,13, + 13,16,15,13,15,15,17, 0,14,15,15,16,19, 9,12,12, + 16,16,11,14,14,16,16,11,13,13,16,16,14,17,16,19, + 0,14,18,17,17,19, 9,12,12,15,16,11,13,13,15,17, + 12,14,13,19,16,13,15,15,17,19,15,17,16,17,19,11, + 14,14,19,16,12,15,15,19,17,13,14,15,17,19,14,16, + 17,19,19,16,15,16,17,19,11,15,14,16,16,12,15,15, + 19, 0,12,14,15,19,19,14,16,16, 0,18,15,19,14,18, + 16, +}; + +static float _vq_quantthresh__8u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p3_0 = { + _vq_quantthresh__8u0__p3_0, + _vq_quantmap__8u0__p3_0, + 5, + 5 +}; + +static static_codebook _8u0__p3_0 = { + 4, 625, + _vq_lengthlist__8u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p3_0, + NULL, + &_vq_auxt__8u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p4_0[] = { + 3, 5, 5, 8, 8, 5, 6, 7, 9, 9, 6, 7, 6, 9, 9, 9, + 9, 9,10,11, 9, 9, 9,11,10, 6, 7, 7,10,10, 7, 7, + 8,10,10, 7, 8, 8,10,10,10,10,10,10,11, 9,10,10, + 11,12, 6, 7, 7,10,10, 7, 8, 8,10,10, 7, 8, 7,10, + 10, 9,10,10,12,11,10,10,10,11,10, 9,10,10,12,11, + 10,10,10,13,11, 9,10,10,12,12,11,11,12,12,13,11, + 11,11,12,13, 9,10,10,12,12,10,10,11,12,12,10,10, + 11,12,12,11,11,11,13,13,11,12,12,13,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,11,12, + 12,10,11,10,12,12, 7, 8, 8,11,11, 7, 8, 9,10,11, + 8, 9, 9,11,11,11,10,11,10,12,10,11,11,12,13, 7, + 8, 8,10,11, 8, 9, 8,12,10, 8, 9, 9,11,12,10,11, + 10,13,11,10,11,11,13,12, 9,11,10,13,12,10,10,11, + 12,12,10,11,11,13,13,12,10,13,11,14,11,12,12,15, + 13, 9,11,11,13,13,10,11,11,13,12,10,11,11,12,14, + 12,13,11,14,12,12,12,12,14,14, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,11,10,10,11,11,12,12,10,11, + 10,12,12, 7, 8, 8,10,11, 8, 9, 9,12,11, 8, 8, 9, + 10,11,10,11,11,12,13,11,10,11,11,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,11,11,12,12, + 10,11,10,13,10, 9,11,10,13,12,10,12,11,13,13,10, + 10,11,12,13,11,12,13,15,14,11,11,13,12,13, 9,10, + 11,12,13,10,11,11,12,13,10,11,10,13,12,12,13,13, + 13,14,12,12,11,14,11, 8,10,10,12,13,10,11,11,13, + 13,10,11,10,13,13,12,13,14,15,14,12,12,12,14,13, + 9,10,10,13,12,10,10,12,13,13,10,11,11,15,12,12, + 12,13,15,14,12,13,13,15,13, 9,10,11,12,13,10,12, + 10,13,12,10,11,11,12,13,12,14,12,15,13,12,12,12, + 15,14,11,12,11,14,13,11,11,12,14,14,12,13,13,14, + 13,13,11,15,11,15,14,14,14,16,15,11,12,12,13,14, + 11,13,11,14,14,12,12,13,14,15,12,14,12,15,12,13, + 15,14,16,15, 8,10,10,12,12,10,10,10,12,13,10,11, + 11,13,13,12,12,12,13,14,13,13,13,15,15, 9,10,10, + 12,12,10,11,11,13,12,10,10,11,13,13,12,12,12,14, + 14,12,12,13,15,14, 9,10,10,13,12,10,10,12,12,13, + 10,11,10,13,13,12,13,13,14,14,12,13,12,14,13,11, + 12,12,14,13,12,13,12,14,14,10,12,12,14,14,14,14, + 14,16,14,13,12,14,12,15,10,12,12,14,15,12,13,13, + 14,16,11,12,11,15,14,13,14,14,14,15,13,14,11,14, + 12, +}; + +static float _vq_quantthresh__8u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p4_0 = { + _vq_quantthresh__8u0__p4_0, + _vq_quantmap__8u0__p4_0, + 5, + 5 +}; + +static static_codebook _8u0__p4_0 = { + 4, 625, + _vq_lengthlist__8u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p4_0, + NULL, + &_vq_auxt__8u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u0__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 7, 8, 8, + 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 6, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8, + 9, 9,10,10,12,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,11,11,12,12,12, 9,10,10,11,11,12,12,12, + 12, +}; + +static float _vq_quantthresh__8u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p5_0 = { + _vq_quantthresh__8u0__p5_0, + _vq_quantmap__8u0__p5_0, + 9, + 9 +}; + +static static_codebook _8u0__p5_0 = { + 2, 81, + _vq_lengthlist__8u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u0__p5_0, + NULL, + &_vq_auxt__8u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8u0__p6_0[] = { + 1, 4, 4, 7, 7, 9, 9,11,11,12,12,16,16, 3, 6, 6, + 9, 9,11,11,12,12,13,14,18,16, 3, 6, 7, 9, 9,11, + 11,13,12,14,14,17,16, 7, 9, 9,11,11,12,12,14,14, + 14,14,17,16, 7, 9, 9,11,11,13,12,13,13,14,14,17, + 0, 9,11,11,12,13,14,14,14,13,15,14,17,17, 9,11, + 11,12,12,14,14,13,14,14,15, 0, 0,11,12,12,15,14, + 15,14,15,14,15,16,17, 0,11,12,13,13,13,14,14,15, + 14,15,15, 0, 0,12,14,14,15,15,14,16,15,15,17,16, + 0,18,13,14,14,15,14,15,14,15,16,17,16, 0, 0,17, + 17,18, 0,16,18,16, 0, 0, 0,17, 0, 0,16, 0, 0,16, + 16, 0,15, 0,17, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__8u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p6_0 = { + _vq_quantthresh__8u0__p6_0, + _vq_quantmap__8u0__p6_0, + 13, + 13 +}; + +static static_codebook _8u0__p6_0 = { + 2, 169, + _vq_lengthlist__8u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8u0__p6_0, + NULL, + &_vq_auxt__8u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p6_1[] = { + 1, 4, 4, 6, 6, 4, 6, 5, 7, 7, 4, 5, 6, 7, 7, 6, + 7, 7, 7, 7, 6, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__8u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p6_1 = { + _vq_quantthresh__8u0__p6_1, + _vq_quantmap__8u0__p6_1, + 5, + 5 +}; + +static static_codebook _8u0__p6_1 = { + 2, 25, + _vq_lengthlist__8u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p6_1, + NULL, + &_vq_auxt__8u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p7_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__8u0__p7_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__8u0__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_0 = { + _vq_quantthresh__8u0__p7_0, + _vq_quantmap__8u0__p7_0, + 3, + 3 +}; + +static static_codebook _8u0__p7_0 = { + 4, 81, + _vq_lengthlist__8u0__p7_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__8u0__p7_0, + NULL, + &_vq_auxt__8u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u0__p7_1[] = { + 1, 5, 5, 5, 5,10,10,11,11,11,11,11,11,11,11, 5, + 7, 6, 8, 8, 9,10,11,11,11,11,11,11,11,11, 6, 6, + 7, 9, 7,11,10,11,11,11,11,11,11,11,11, 5, 6, 6, + 11, 8,11,11,11,11,11,11,11,11,11,11, 5, 6, 6, 9, + 10,11,10,11,11,11,11,11,11,11,11, 7,10,10,11,11, + 11,11,11,11,11,11,11,11,11,11, 7,11, 8,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u0__p7_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8u0__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_1 = { + _vq_quantthresh__8u0__p7_1, + _vq_quantmap__8u0__p7_1, + 15, + 15 +}; + +static static_codebook _8u0__p7_1 = { + 2, 225, + _vq_lengthlist__8u0__p7_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8u0__p7_1, + NULL, + &_vq_auxt__8u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8u0__p7_2[] = { + 1, 6, 5, 7, 7, 9, 9, 9, 9,10,12,12,10,11,11,10, + 11,11,11,10,11, 6, 8, 8, 9, 9,10,10, 9,10,11,11, + 10,11,11,11,11,10,11,11,11,11, 6, 7, 8, 9, 9, 9, + 10,11,10,11,12,11,10,11,11,11,11,11,11,12,10, 8, + 9, 9,10, 9,10,10, 9,10,10,10,10,10, 9,10,10,10, + 10, 9,10,10, 9, 9, 9, 9,10,10, 9, 9,10,10,11,10, + 9,12,10,11,10, 9,10,10,10, 8, 9, 9,10, 9,10, 9, + 9,10,10, 9,10, 9,11,10,10,10,10,10, 9,10, 8, 8, + 9, 9,10, 9,11, 9, 8, 9, 9,10,11,10,10,10,11,12, + 9, 9,11, 8, 9, 8,11,10,11,10,10, 9,11,10,10,10, + 10,10,10,10,11,11,11,11, 8, 9, 9, 9,10,10,10,11, + 11,12,11,12,11,10,10,10,12,11,11,11,10, 8,10, 9, + 11,10,10,11,12,10,11,12,11,11,12,11,12,12,10,11, + 11,10, 9, 9,10,11,12,10,10,10,11,10,11,11,10,12, + 12,10,11,10,11,12,10, 9,10,10,11,10,11,11,11,11, + 11,12,11,11,11, 9,11,10,11,10,11,10, 9, 9,10,11, + 11,11,10,10,11,12,12,11,12,11,11,11,12,12,12,12, + 11, 9,11,11,12,10,11,11,11,11,11,11,12,11,11,12, + 11,11,11,10,11,11, 9,11,10,11,11,11,10,10,10,11, + 11,11,12,10,11,10,11,11,11,11,12, 9,11,10,11,11, + 10,10,11,11, 9,11,11,12,10,10,10,10,10,11,11,10, + 9,10,11,11,12,11,10,10,12,11,11,12,11,12,11,11, + 10,10,11,11,10,12,11,10,11,10,11,10,10,10,11,11, + 10,10,11,11,11,11,10,10,10,12,11,11,11,11,10, 9, + 10,11,11,11,12,11,11,11,12,10,11,11,11, 9,10,11, + 11,11,11,11,11,10,10,11,11,12,11,10,11,12,11,10, + 10,11, 9,10,11,11,11,11,11,10,11,11,10,12,11,11, + 11,12,11,11,11,10,10,11,11, +}; + +static float _vq_quantthresh__8u0__p7_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8u0__p7_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_2 = { + _vq_quantthresh__8u0__p7_2, + _vq_quantmap__8u0__p7_2, + 21, + 21 +}; + +static static_codebook _8u0__p7_2 = { + 2, 441, + _vq_lengthlist__8u0__p7_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8u0__p7_2, + NULL, + &_vq_auxt__8u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8u0__single[] = { + 4, 7,11, 9,12, 8, 7,10, 6, 4, 5, 5, 7, 5, 6,16, + 9, 5, 5, 6, 7, 7, 9,16, 7, 4, 6, 5, 7, 5, 7,17, + 10, 7, 7, 8, 7, 7, 8,18, 7, 5, 6, 4, 5, 4, 5,15, + 7, 6, 7, 5, 6, 4, 5,15,12,13,18,12,17,11, 9,17, +}; + +static static_codebook _huff_book__8u0__single = { + 2, 64, + _huff_lengthlist__8u0__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 7, 9,10, 7, + 9, 9, 5, 8, 8, 7,10, 9, 7, 9, 9, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10, 9,10,12,10,12,12, 7,10,10, + 9,12,11,10,12,12, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10,10,12,12, 9,11,12, 7,10,10,10,12,12, 9,12, + 10, +}; + +static float _vq_quantthresh__8u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p1_0 = { + _vq_quantthresh__8u1__p1_0, + _vq_quantmap__8u1__p1_0, + 3, + 3 +}; + +static static_codebook _8u1__p1_0 = { + 4, 81, + _vq_lengthlist__8u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u1__p1_0, + NULL, + &_vq_auxt__8u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p2_0[] = { + 3, 4, 5, 5, 6, 6, 5, 6, 6, 5, 7, 6, 6, 7, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 7, 8, + 8, 6, 7, 7, 6, 8, 7, 7, 7, 9, 8, 9, 9, 6, 7, 8, + 7, 9, 7, 8, 9, 9, 5, 6, 6, 6, 7, 7, 7, 8, 8, 6, + 8, 7, 8, 9, 9, 7, 7, 9, 6, 7, 8, 8, 9, 9, 7, 9, + 7, +}; + +static float _vq_quantthresh__8u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p2_0 = { + _vq_quantthresh__8u1__p2_0, + _vq_quantmap__8u1__p2_0, + 3, + 3 +}; + +static static_codebook _8u1__p2_0 = { + 4, 81, + _vq_lengthlist__8u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u1__p2_0, + NULL, + &_vq_auxt__8u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u1__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 10, 9,11,11, 9, 9, 9,11,11, 6, 8, 8,10,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,11,11,12,12,10,11,11, + 12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11, + 11,10,11,11,12,12,10,11,11,12,12, 9,11,11,14,13, + 10,12,11,14,14,10,12,11,14,13,12,13,13,15,14,12, + 13,13,15,14, 8,11,11,13,14,10,11,12,13,15,10,11, + 12,14,14,12,13,13,14,15,12,13,13,14,15, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14, + 13,11,12,12,13,14, 8,10,10,12,12, 9,11,12,13,14, + 10,12,12,13,13,12,12,13,14,14,11,13,13,15,15, 7, + 10,10,12,12, 9,12,11,14,12,10,11,12,13,14,12,13, + 12,14,14,12,13,13,15,16,10,12,12,15,14,11,12,13, + 15,15,11,13,13,15,16,14,14,15,15,16,13,14,15,17, + 15, 9,12,12,14,15,11,13,12,15,15,11,13,13,15,15, + 13,14,13,15,14,13,14,14,17, 0, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12, + 12,14,14, 7,10,10,12,12,10,12,12,13,13, 9,11,12, + 12,13,11,12,13,15,15,11,12,13,14,15, 8,10,10,12, + 12,10,12,11,13,13,10,12,11,13,13,11,13,13,15,14, + 12,13,12,15,13, 9,12,12,14,14,11,13,13,16,15,11, + 12,13,16,15,13,14,15,16,16,13,13,15,15,16,10,12, + 12,15,14,11,13,13,14,16,11,13,13,15,16,13,15,15, + 16,17,13,15,14,16,15, 8,11,11,14,15,10,12,12,15, + 15,10,12,12,15,16,14,15,15,16,17,13,14,14,16,16, + 9,12,12,15,15,11,13,14,15,17,11,13,13,15,16,14, + 15,16,19,17,13,15,15, 0,17, 9,12,12,15,15,11,14, + 13,16,15,11,13,13,15,16,15,15,15,18,17,13,15,15, + 17,17,11,15,14,18,16,12,14,15,17,17,12,15,15,18, + 18,15,15,16,15,19,14,16,16, 0, 0,11,14,14,16,17, + 12,15,14,18,17,12,15,15,18,18,15,17,15,18,16,14, + 16,16,18,18, 7,11,11,14,14,10,12,12,15,15,10,12, + 13,15,15,13,14,15,16,16,14,15,15,18,18, 9,12,12, + 15,15,11,13,13,16,15,11,12,13,16,16,14,15,15,17, + 16,15,16,16,17,17, 9,12,12,15,15,11,13,13,15,17, + 11,14,13,16,15,13,15,15,17,17,15,15,15,18,17,11, + 14,14,17,15,12,14,15,17,18,13,13,15,17,17,14,16, + 16,19,18,16,15,17,17, 0,11,14,14,17,17,12,15,15, + 18, 0,12,15,14,18,16,14,17,17,19, 0,16,18,15, 0, + 16, +}; + +static float _vq_quantthresh__8u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p3_0 = { + _vq_quantthresh__8u1__p3_0, + _vq_quantmap__8u1__p3_0, + 5, + 5 +}; + +static static_codebook _8u1__p3_0 = { + 4, 625, + _vq_lengthlist__8u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u1__p3_0, + NULL, + &_vq_auxt__8u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u1__p4_0[] = { + 4, 5, 5, 9, 9, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 7, + 8, 9,10, 7, 7, 8, 9,10, 9, 9,10,10,11, 9, 9,10, + 10,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 7,10, + 9, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11, + 9,10,10,12,11, 9,10,10,12,12,11,11,12,12,13,11, + 11,12,12,13, 9, 9,10,12,11, 9,10,10,12,12,10,10, + 10,12,12,11,12,11,13,12,11,12,11,13,12, 6, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 7,10, 9,10,10,10,12, + 12,10,10,10,12,11, 7, 8, 7,10,10, 7, 7, 9,10,11, + 8, 9, 9,11,10,10,10,11,10,12,10,10,11,12,12, 7, + 8, 8,10,10, 7, 9, 8,11,10, 8, 8, 9,11,11,10,11, + 10,12,11,10,11,11,12,12, 9,10,10,12,12, 9,10,10, + 12,12,10,11,11,13,12,11,10,12,10,14,12,12,12,13, + 14, 9,10,10,12,12, 9,11,10,12,12,10,11,11,12,12, + 11,12,11,14,12,12,12,12,14,14, 5, 7, 7, 9, 9, 7, + 7, 7, 9,10, 7, 8, 8,10,10,10,10,10,11,11,10,10, + 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,10,10,11,12,10,10,11,11,13, 6, 7, 8,10, + 10, 8, 9, 9,10,10, 7, 9, 7,11,10,10,11,10,12,12, + 10,11,10,12,10, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,12,12,12,12,14,13,11,11,12,11,14, 9,10, + 10,11,12,10,11,11,12,13, 9,10,10,12,12,12,12,12, + 14,13,11,12,10,14,11, 9, 9,10,11,12, 9,10,10,12, + 12, 9,10,10,12,12,12,12,12,14,14,11,12,12,13,12, + 9,10, 9,12,12, 9,10,11,12,13,10,11,10,13,11,12, + 12,13,13,14,12,12,12,13,13, 9,10,10,12,12,10,11, + 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,12, + 13,14,11,12,11,14,13,10,10,11,13,13,12,12,12,14, + 13,12,10,14,10,15,13,14,14,14,14,11,11,12,13,14, + 10,12,11,13,13,12,12,12,13,15,12,13,11,15,12,13, + 13,14,14,14, 9,10, 9,12,12, 9,10,10,12,12,10,10, + 10,12,12,11,11,12,12,13,12,12,12,14,14, 9,10,10, + 12,12,10,11,10,13,12,10,10,11,12,13,12,12,12,14, + 13,12,12,13,13,14, 9,10,10,12,13,10,10,11,11,12, + 9,11,10,13,12,12,12,12,13,14,12,13,12,14,13,11, + 12,11,13,13,12,13,12,14,13,10,11,12,13,13,13,13, + 13,14,15,12,11,14,12,14,11,11,12,12,13,12,12,12, + 13,14,10,12,10,14,13,13,13,13,14,15,12,14,11,15, + 10, +}; + +static float _vq_quantthresh__8u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p4_0 = { + _vq_quantthresh__8u1__p4_0, + _vq_quantmap__8u1__p4_0, + 5, + 5 +}; + +static static_codebook _8u1__p4_0 = { + 4, 625, + _vq_lengthlist__8u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u1__p4_0, + NULL, + &_vq_auxt__8u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u1__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 5, 8, 7, 8, 8, + 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8, + 9, 9,10,10,12,11, 8, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,11,11,11,13,12, 9,10,10,11,11,12,12,12, + 13, +}; + +static float _vq_quantthresh__8u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p5_0 = { + _vq_quantthresh__8u1__p5_0, + _vq_quantmap__8u1__p5_0, + 9, + 9 +}; + +static static_codebook _8u1__p5_0 = { + 2, 81, + _vq_lengthlist__8u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u1__p5_0, + NULL, + &_vq_auxt__8u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u1__p6_0[] = { + 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 5, 6, 6, 7, 7, + 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7, + 8, 8, 9, 9, 6, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7, + 8, 8, 8, 9,10,10, 7, 7, 7, 8, 8, 9, 8,10,10, 9, + 9, 9, 9, 9,10,10,10,10, 9, 9, 9, 9, 9,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u1__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p6_0 = { + _vq_quantthresh__8u1__p6_0, + _vq_quantmap__8u1__p6_0, + 9, + 9 +}; + +static static_codebook _8u1__p6_0 = { + 2, 81, + _vq_lengthlist__8u1__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u1__p6_0, + NULL, + &_vq_auxt__8u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,10,10, 8, + 10,10, 5, 9, 9, 7,10,10, 8,10,10, 4,10,10, 9,12, + 12, 9,11,11, 7,12,11,10,11,13,10,13,13, 7,12,12, + 10,13,12,10,13,13, 4,10,10, 9,12,12, 9,12,12, 7, + 12,12,10,13,13,10,12,13, 7,11,12,10,13,13,10,13, + 11, +}; + +static float _vq_quantthresh__8u1__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8u1__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p7_0 = { + _vq_quantthresh__8u1__p7_0, + _vq_quantmap__8u1__p7_0, + 3, + 3 +}; + +static static_codebook _8u1__p7_0 = { + 4, 81, + _vq_lengthlist__8u1__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8u1__p7_0, + NULL, + &_vq_auxt__8u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7, + 8, 8, 9, 9, 9, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 9, + 9, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9, + 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10, + 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9, + 9, 9, 9, 9, 9,10,10,10,10, +}; + +static float _vq_quantthresh__8u1__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8u1__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p7_1 = { + _vq_quantthresh__8u1__p7_1, + _vq_quantmap__8u1__p7_1, + 11, + 11 +}; + +static static_codebook _8u1__p7_1 = { + 2, 121, + _vq_lengthlist__8u1__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8u1__p7_1, + NULL, + &_vq_auxt__8u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7, + 9, 9,11,11,13,12, 4, 6, 6, 7, 7, 9, 9,11,11,12, + 12, 6, 7, 7, 9, 9,11,11,12,12,13,13, 6, 7, 7, 9, + 9,11,11,12,12,13,13, 8, 9, 9,11,11,12,12,13,13, + 14,14, 8, 9, 9,11,11,12,12,13,13,14,14, 9,11,11, + 12,12,13,13,14,14,15,15, 9,11,11,12,12,13,13,14, + 14,15,14,11,12,12,13,13,14,14,15,15,16,16,11,12, + 12,13,13,14,14,15,15,15,15, +}; + +static float _vq_quantthresh__8u1__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__8u1__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p8_0 = { + _vq_quantthresh__8u1__p8_0, + _vq_quantmap__8u1__p8_0, + 11, + 11 +}; + +static static_codebook _8u1__p8_0 = { + 2, 121, + _vq_lengthlist__8u1__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__8u1__p8_0, + NULL, + &_vq_auxt__8u1__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p8_1[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 7, + 7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, + 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__8u1__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8u1__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p8_1 = { + _vq_quantthresh__8u1__p8_1, + _vq_quantmap__8u1__p8_1, + 11, + 11 +}; + +static static_codebook _8u1__p8_1 = { + 2, 121, + _vq_lengthlist__8u1__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8u1__p8_1, + NULL, + &_vq_auxt__8u1__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u1__p9_0[] = { + 1, 4, 4,11,11,11,11,11,11,11,11,11,11,11,11, 3, + 11, 8,11,11,11,11,11,11,11,11,11,11,11,11, 3, 9, + 9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__8u1__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_0 = { + _vq_quantthresh__8u1__p9_0, + _vq_quantmap__8u1__p9_0, + 15, + 15 +}; + +static static_codebook _8u1__p9_0 = { + 2, 225, + _vq_lengthlist__8u1__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__8u1__p9_0, + NULL, + &_vq_auxt__8u1__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u1__p9_1[] = { + 1, 4, 4, 7, 7, 9, 9, 7, 7, 8, 8,10,10,11,11, 4, + 7, 7, 9, 9,10,10, 8, 8,10,10,10,11,10,11, 4, 7, + 7, 9, 9,10,10, 8, 8,10, 9,11,11,11,11, 7, 9, 9, + 12,12,11,12,10,10,11,10,12,11,11,11, 7, 9, 9,11, + 11,13,12, 9, 9,11,10,11,11,12,11, 9,10,10,12,12, + 14,14,10,10,11,12,12,11,11,11, 9,10,11,11,13,14, + 13,10,11,11,11,12,11,12,12, 7, 8, 8,10, 9,11,10, + 11,12,12,11,12,14,12,13, 7, 8, 8, 9,10,10,11,12, + 12,12,11,12,12,12,13, 9, 9, 9,11,11,13,12,12,12, + 12,11,12,12,13,12, 8,10,10,11,10,11,12,12,12,12, + 12,12,14,12,12, 9,11,11,11,12,12,12,12,13,13,12, + 12,13,13,12,10,11,11,12,11,12,12,12,11,12,13,12, + 12,12,13,11,11,12,12,12,13,12,12,11,12,13,13,12, + 12,13,12,11,12,12,13,13,12,13,12,13,13,13,13,14, + 13, +}; + +static float _vq_quantthresh__8u1__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__8u1__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_1 = { + _vq_quantthresh__8u1__p9_1, + _vq_quantmap__8u1__p9_1, + 15, + 15 +}; + +static static_codebook _8u1__p9_1 = { + 2, 225, + _vq_lengthlist__8u1__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__8u1__p9_1, + NULL, + &_vq_auxt__8u1__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8u1__p9_2[] = { + 2, 5, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10,10, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10, 8, 8, 8, 9, 9, 9, 9,10,10,10, 9, + 10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8u1__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_2 = { + _vq_quantthresh__8u1__p9_2, + _vq_quantmap__8u1__p9_2, + 17, + 17 +}; + +static static_codebook _8u1__p9_2 = { + 2, 289, + _vq_lengthlist__8u1__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8u1__p9_2, + NULL, + &_vq_auxt__8u1__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8u1__single[] = { + 4, 7,13, 9,15, 9,16, 8,10,13, 7, 5, 8, 6, 9, 7, + 10, 7,10,11,11, 6, 7, 8, 8, 9, 9, 9,12,16, 8, 5, + 8, 6, 8, 6, 9, 7,10,12,11, 7, 7, 7, 6, 7, 7, 7, + 11,15, 7, 5, 8, 6, 7, 5, 7, 6, 9,13,13, 9, 9, 8, + 6, 6, 5, 5, 9,14, 8, 6, 8, 6, 6, 4, 5, 3, 5,13, + 9, 9,11, 8,10, 7, 8, 4, 5,12,11,16,17,15,17,12, + 13, 8, 8,15, +}; + +static static_codebook _huff_book__8u1__single = { + 2, 100, + _huff_lengthlist__8u1__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/sound/OggVorbis/vorbissrc/codebook.c b/sound/OggVorbis/vorbissrc/codebook.c new file mode 100644 index 000000000..8c13f83c5 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/codebook.c @@ -0,0 +1,615 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic codebook pack/unpack/code/decode operations + last mod: $Id: codebook.c,v 1.39 2002/06/28 22:19:35 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" + +/* packs the given codebook into the bitstream **************************/ + +int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ + long i,j; + int ordered=0; + + /* first the basic parameters */ + oggpack_write(opb,0x564342,24); + oggpack_write(opb,c->dim,16); + oggpack_write(opb,c->entries,24); + + /* pack the codewords. There are two packings; length ordered and + length random. Decide between the two now. */ + + for(i=1;ientries;i++) + if(c->lengthlist[i-1]==0 || c->lengthlist[i]lengthlist[i-1])break; + if(i==c->entries)ordered=1; + + if(ordered){ + /* length ordered. We only need to say how many codewords of + each length. The actual codewords are generated + deterministically */ + + long count=0; + oggpack_write(opb,1,1); /* ordered */ + oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ + + for(i=1;ientries;i++){ + long this=c->lengthlist[i]; + long last=c->lengthlist[i-1]; + if(this>last){ + for(j=last;jentries-count)); + count=i; + } + } + } + oggpack_write(opb,i-count,_ilog(c->entries-count)); + + }else{ + /* length random. Again, we don't code the codeword itself, just + the length. This time, though, we have to encode each length */ + oggpack_write(opb,0,1); /* unordered */ + + /* algortihmic mapping has use for 'unused entries', which we tag + here. The algorithmic mapping happens as usual, but the unused + entry has no codeword. */ + for(i=0;ientries;i++) + if(c->lengthlist[i]==0)break; + + if(i==c->entries){ + oggpack_write(opb,0,1); /* no unused entries */ + for(i=0;ientries;i++) + oggpack_write(opb,c->lengthlist[i]-1,5); + }else{ + oggpack_write(opb,1,1); /* we have unused entries; thus we tag */ + for(i=0;ientries;i++){ + if(c->lengthlist[i]==0){ + oggpack_write(opb,0,1); + }else{ + oggpack_write(opb,1,1); + oggpack_write(opb,c->lengthlist[i]-1,5); + } + } + } + } + + /* is the entry number the desired return value, or do we have a + mapping? If we have a mapping, what type? */ + oggpack_write(opb,c->maptype,4); + switch(c->maptype){ + case 0: + /* no mapping */ + break; + case 1:case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ + + if(!c->quantlist){ + /* no quantlist? error */ + return(-1); + } + + /* values that define the dequantization */ + oggpack_write(opb,c->q_min,32); + oggpack_write(opb,c->q_delta,32); + oggpack_write(opb,c->q_quant-1,4); + oggpack_write(opb,c->q_sequencep,1); + + { + int quantvals; + switch(c->maptype){ + case 1: + /* a single column of (c->entries/c->dim) quantized values for + building a full value list algorithmically (square lattice) */ + quantvals=_book_maptype1_quantvals(c); + break; + case 2: + /* every value (c->entries*c->dim total) specified explicitly */ + quantvals=c->entries*c->dim; + break; + default: /* NOT_REACHABLE */ + quantvals=-1; + } + + /* quantized values */ + for(i=0;iquantlist[i]),c->q_quant); + + } + break; + default: + /* error case; we don't have any other map types now */ + return(-1); + } + + return(0); +} + +/* unpacks a codebook from the packet buffer into the codebook struct, + readies the codebook auxiliary structures for decode *************/ +int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ + long i,j; + memset(s,0,sizeof(*s)); + s->allocedp=1; + + /* make sure alignment is correct */ + if(oggpack_read(opb,24)!=0x564342)goto _eofout; + + /* first the basic parameters */ + s->dim=oggpack_read(opb,16); + s->entries=oggpack_read(opb,24); + if(s->entries==-1)goto _eofout; + + /* codeword ordering.... length ordered or unordered? */ + switch((int)oggpack_read(opb,1)){ + case 0: + /* unordered */ + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + /* allocated but unused entries? */ + if(oggpack_read(opb,1)){ + /* yes, unused entries */ + + for(i=0;ientries;i++){ + if(oggpack_read(opb,1)){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + }else + s->lengthlist[i]=0; + } + }else{ + /* all entries used; no tagging */ + for(i=0;ientries;i++){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + } + } + + break; + case 1: + /* ordered */ + { + long length=oggpack_read(opb,5)+1; + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + for(i=0;ientries;){ + long num=oggpack_read(opb,_ilog(s->entries-i)); + if(num==-1)goto _eofout; + for(j=0;jentries;j++,i++) + s->lengthlist[i]=length; + length++; + } + } + break; + default: + /* EOF */ + return(-1); + } + + /* Do we have a mapping to unpack? */ + switch((s->maptype=oggpack_read(opb,4))){ + case 0: + /* no mapping */ + break; + case 1: case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ + + s->q_min=oggpack_read(opb,32); + s->q_delta=oggpack_read(opb,32); + s->q_quant=oggpack_read(opb,4)+1; + s->q_sequencep=oggpack_read(opb,1); + + { + int quantvals=0; + switch(s->maptype){ + case 1: + quantvals=_book_maptype1_quantvals(s); + break; + case 2: + quantvals=s->entries*s->dim; + break; + } + + /* quantized values */ + s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals); + for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); + + if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; + } + break; + default: + goto _errout; + } + + /* all set */ + return(0); + + _errout: + _eofout: + vorbis_staticbook_clear(s); + return(-1); +} + +/* returns the number of bits ************************************************/ +int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ + oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); + return(book->c->lengthlist[a]); +} + +/* One the encode side, our vector writers are each designed for a +specific purpose, and the encoder is not flexible without modification: + +The LSP vector coder uses a single stage nearest-match with no +interleave, so no step and no error return. This is specced by floor0 +and doesn't change. + +Residue0 encoding interleaves, uses multiple stages, and each stage +peels of a specific amount of resolution from a lattice (thus we want +to match by threshold, not nearest match). Residue doesn't *have* to +be encoded that way, but to change it, one will need to add more +infrastructure on the encode side (decode side is specced and simpler) */ + +/* floor0 LSP (single stage, non interleaved, nearest match) */ +/* returns entry number and *modifies a* to the quantization value *****/ +int vorbis_book_errorv(codebook *book,float *a){ + int dim=book->dim,k; + int best=_best(book,a,1); + for(k=0;kvaluelist+best*dim)[k]; + return(best); +} + +/* returns the number of bits and *modifies a* to the quantization value *****/ +int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){ + int k,dim=book->dim; + for(k=0;kvaluelist+best*dim)[k]; + return(vorbis_book_encode(book,best,b)); +} + +/* the 'eliminate the decode tree' optimization actually requires the + codewords to be MSb first, not LSb. This is an annoying inelegancy + (and one of the first places where carefully thought out design + turned out to be wrong; Vorbis II and future Ogg codecs should go + to an MSb bitpacker), but not actually the huge hit it appears to + be. The first-stage decode table catches most words so that + bitreverse is not in the main execution path. */ + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); + x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); + x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); + x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); + return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); +} + +STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ + int read=book->dec_maxlength; + long lo,hi; + long lok = oggpack_look(b,book->dec_firsttablen); + + if (lok >= 0) { + long entry = book->dec_firsttable[lok]; + if(entry&0x80000000UL){ + lo=(entry>>15)&0x7fff; + hi=book->used_entries-(entry&0x7fff); + }else{ + oggpack_adv(b, book->dec_codelengths[entry-1]); + return(entry-1); + } + }else{ + lo=0; + hi=book->used_entries; + } + + lok = oggpack_look(b, read); + + while(lok<0 && read>1) + lok = oggpack_look(b, --read); + if(lok<0)return -1; + + /* bisect search for the codeword in the ordered list */ + { + ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); + + while(hi-lo>1){ + long p=(hi-lo)>>1; + long test=book->codelist[lo+p]>testword; + lo+=p&(test-1); + hi-=p&(-test); + } + + if(book->dec_codelengths[lo]<=read){ + oggpack_adv(b, book->dec_codelengths[lo]); + return(lo); + } + } + + oggpack_adv(b, read); + return(-1); +} + +/* Decode side is specced and easier, because we don't need to find + matches using different criteria; we simply read and map. There are + two things we need to do 'depending': + + We may need to support interleave. We don't really, but it's + convenient to do it here rather than rebuild the vector later. + + Cascades may be additive or multiplicitive; this is not inherent in + the codebook, but set in the code using the codebook. Like + interleaving, it's easiest to do it here. + addmul==0 -> declarative (set the value) + addmul==1 -> additive + addmul==2 -> multiplicitive */ + +/* returns the [original, not compacted] entry number or -1 on eof *********/ +long vorbis_book_decode(codebook *book, oggpack_buffer *b){ + long packed_entry=decode_packed_entry_number(book,b); + if(packed_entry>=0) + return(book->dec_index[packed_entry]); + + /* if there's no dec_index, the codebook unpacking isn't collapsed */ + return(packed_entry); +} + +/* returns 0 on OK or -1 on eof *************************************/ +long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ + int step=n/book->dim; + long *entry = alloca(sizeof(*entry)*step); + float **t = alloca(sizeof(*t)*step); + int i,j,o; + + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;idim;i++,o+=step) + for (j=0;jdim>8){ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]; + } + }else{ + for(i=0;ivaluelist+entry*book->dim; + j=0; + switch((int)book->dim){ + case 8: + a[i++]+=t[j++]; + case 7: + a[i++]+=t[j++]; + case 6: + a[i++]+=t[j++]; + case 5: + a[i++]+=t[j++]; + case 4: + a[i++]+=t[j++]; + case 3: + a[i++]+=t[j++]; + case 2: + a[i++]+=t[j++]; + case 1: + a[i++]+=t[j++]; + case 0: + break; + } + } + } + return(0); +} + +long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){ + int i,j,entry; + float *t; + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]=t[j++]; + } + return(0); +} + +long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch, + oggpack_buffer *b,int n){ + long i,j,entry; + int chptr=0; + + for(i=offset/ch;i<(offset+n)/ch;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + { + const float *t = book->valuelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]; + if(chptr==ch){ + chptr=0; + i++; + } + } + } + } + return(0); +} + +#ifdef _V_SELFTEST +/* Simple enough; pack a few candidate codebooks, unpack them. Code a + number of vectors through (keeping track of the quantized values), + and decode using the unpacked book. quantized version of in should + exactly equal out */ + +#include + +#include "vorbis/book/lsp20_0.vqh" +#include "vorbis/book/res0a_13.vqh" +#define TESTSIZE 40 + +float test1[TESTSIZE]={ + 0.105939f, + 0.215373f, + 0.429117f, + 0.587974f, + + 0.181173f, + 0.296583f, + 0.515707f, + 0.715261f, + + 0.162327f, + 0.263834f, + 0.342876f, + 0.406025f, + + 0.103571f, + 0.223561f, + 0.368513f, + 0.540313f, + + 0.136672f, + 0.395882f, + 0.587183f, + 0.652476f, + + 0.114338f, + 0.417300f, + 0.525486f, + 0.698679f, + + 0.147492f, + 0.324481f, + 0.643089f, + 0.757582f, + + 0.139556f, + 0.215795f, + 0.324559f, + 0.399387f, + + 0.120236f, + 0.267420f, + 0.446940f, + 0.608760f, + + 0.115587f, + 0.287234f, + 0.571081f, + 0.708603f, +}; + +float test3[TESTSIZE]={ + 0,1,-2,3,4,-5,6,7,8,9, + 8,-2,7,-1,4,6,8,3,1,-9, + 10,11,12,13,14,15,26,17,18,19, + 30,-25,-30,-1,-5,-32,4,3,-2,0}; + +static_codebook *testlist[]={&_vq_book_lsp20_0, + &_vq_book_res0a_13,NULL}; +float *testvec[]={test1,test3}; + +int main(){ + oggpack_buffer write; + oggpack_buffer read; + long ptr=0,i; + oggpack_writeinit(&write); + + fprintf(stderr,"Testing codebook abstraction...:\n"); + + while(testlist[ptr]){ + codebook c; + static_codebook s; + float *qv=alloca(sizeof(*qv)*TESTSIZE); + float *iv=alloca(sizeof(*iv)*TESTSIZE); + memcpy(qv,testvec[ptr],sizeof(*qv)*TESTSIZE); + memset(iv,0,sizeof(*iv)*TESTSIZE); + + fprintf(stderr,"\tpacking/coding %ld... ",ptr); + + /* pack the codebook, write the testvector */ + oggpack_reset(&write); + vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory + we can write */ + vorbis_staticbook_pack(testlist[ptr],&write); + fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write)); + for(i=0;i.000001){ + fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n", + iv[i],qv[i],i); + exit(1); + } + + fprintf(stderr,"OK\n"); + ptr++; + } + + /* The above is the trivial stuff; now try unquantizing a log scale codebook */ + + exit(0); +} + +#endif diff --git a/sound/OggVorbis/vorbissrc/codebook.h b/sound/OggVorbis/vorbissrc/codebook.h new file mode 100644 index 000000000..de9102ae1 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/codebook.h @@ -0,0 +1,160 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_CODEBOOK_H_ +#define _V_CODEBOOK_H_ + +#include "../ogg/ogg.h" + +/* This structure encapsulates huffman and VQ style encoding books; it + doesn't do anything specific to either. + + valuelist/quantlist are nonNULL (and q_* significant) only if + there's entry->value mapping to be done. + + If encode-side mapping must be done (and thus the entry needs to be + hunted), the auxiliary encode pointer will point to a decision + tree. This is true of both VQ and huffman, but is mostly useful + with VQ. + +*/ + +typedef struct static_codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long *lengthlist; /* codeword lengths in bits */ + + /* mapping ***************************************************************/ + int maptype; /* 0=none + 1=implicitly populated values from map column + 2=listed arbitrary values */ + + /* The below does a linear, single monotonic sequence mapping. */ + long q_min; /* packed 32 bit float; quant value 0 maps to minval */ + long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ + int q_quant; /* bits: 0 < quant <= 16 */ + int q_sequencep; /* bitflag */ + + long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map + map == 2: list of dim*entries quantized entry vals + */ + + /* encode helpers ********************************************************/ + struct encode_aux_nearestmatch *nearest_tree; + struct encode_aux_threshmatch *thresh_tree; + struct encode_aux_pigeonhole *pigeon_tree; + + int allocedp; +} static_codebook; + +/* this structures an arbitrary trained book to quickly find the + nearest cell match */ +typedef struct encode_aux_nearestmatch{ + /* pre-calculated partitioning tree */ + long *ptr0; + long *ptr1; + + long *p; /* decision points (each is an entry) */ + long *q; /* decision points (each is an entry) */ + long aux; /* number of tree entries */ + long alloc; +} encode_aux_nearestmatch; + +/* assumes a maptype of 1; encode side only, so that's OK */ +typedef struct encode_aux_threshmatch{ + float *quantthresh; + long *quantmap; + int quantvals; + int threshvals; +} encode_aux_threshmatch; + +typedef struct encode_aux_pigeonhole{ + float min; + float del; + + int mapentries; + int quantvals; + long *pigeonmap; + + long fittotal; + long *fitlist; + long *fitmap; + long *fitlength; +} encode_aux_pigeonhole; + +typedef struct codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long used_entries; /* populated codebook entries */ + const static_codebook *c; + + /* for encode, the below are entry-ordered, fully populated */ + /* for decode, the below are ordered by bitreversed codeword and only + used entries are populated */ + float *valuelist; /* list of dim*entries actual entry values */ + ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */ + + int *dec_index; /* only used if sparseness collapsed */ + char *dec_codelengths; + ogg_uint32_t *dec_firsttable; + int dec_firsttablen; + int dec_maxlength; + +} codebook; + +extern void vorbis_staticbook_clear(static_codebook *b); +extern void vorbis_staticbook_destroy(static_codebook *b); +extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source); +extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); +extern void vorbis_book_clear(codebook *b); + +extern float *_book_unquantize(const static_codebook *b,int n,int *map); +extern float *_book_logdist(const static_codebook *b,float *vals); +extern float _float32_unpack(long val); +extern long _float32_pack(float val); +extern int _best(codebook *book, float *a, int step); +extern int _ilog(unsigned int v); +extern long _book_maptype1_quantvals(const static_codebook *b); + +extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); +extern long vorbis_book_codeword(codebook *book,int entry); +extern long vorbis_book_codelen(codebook *book,int entry); + + + +extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b); +extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); + +extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b); +extern int vorbis_book_errorv(codebook *book, float *a); +extern int vorbis_book_encodev(codebook *book, int best,float *a, + oggpack_buffer *b); + +extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); +extern long vorbis_book_decodevs_add(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodev_set(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodev_add(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodevv_add(codebook *book, float **a, + long off,int ch, + oggpack_buffer *b,int n); + + + +#endif diff --git a/sound/OggVorbis/vorbissrc/codec_internal.h b/sound/OggVorbis/vorbissrc/codec_internal.h new file mode 100644 index 000000000..41aa9ebe0 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/codec_internal.h @@ -0,0 +1,134 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_CODECI_H_ +#define _V_CODECI_H_ + +#include "envelope.h" +#include "codebook.h" + +#define BLOCKTYPE_IMPULSE 0 +#define BLOCKTYPE_PADDING 1 +#define BLOCKTYPE_TRANSITION 0 +#define BLOCKTYPE_LONG 1 + +#define PACKETBLOBS 15 + +typedef struct vorbis_block_internal{ + float **pcmdelay; /* this is a pointer into local storage */ + float ampmax; + int blocktype; + + ogg_uint32_t packetblob_markers[PACKETBLOBS]; +} vorbis_block_internal; + +typedef void vorbis_look_floor; +typedef void vorbis_look_residue; +typedef void vorbis_look_transform; + +/* mode ************************************************************/ +typedef struct { + int blockflag; + int windowtype; + int transformtype; + int mapping; +} vorbis_info_mode; + +typedef void vorbis_info_floor; +typedef void vorbis_info_residue; +typedef void vorbis_info_mapping; + +#include "psy.h" +#include "bitrate.h" + +typedef struct private_state { + /* local lookup storage */ + envelope_lookup *ve; /* envelope lookup */ + int window[2]; + vorbis_look_transform **transform[2]; /* block, type */ + drft_lookup fft_look[2]; + + int modebits; + vorbis_look_floor **flr; + vorbis_look_residue **residue; + vorbis_look_psy *psy; + vorbis_look_psy_global *psy_g_look; + + /* local storage, only used on the encoding side. This way the + application does not need to worry about freeing some packets' + memory and not others'; packet storage is always tracked. + Cleared next call to a _dsp_ function */ + unsigned char *header; + unsigned char *header1; + unsigned char *header2; + + bitrate_manager_state bms; + + ogg_int64_t sample_count; +} private_state; + +/* codec_setup_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). +*********************************************************************/ + +#include "highlevel.h" +typedef struct codec_setup_info { + + /* Vorbis supports only short and long blocks, but allows the + encoder to choose the sizes */ + + long blocksizes[2]; + + /* modes are the primary means of supporting on-the-fly different + blocksizes, different channel mappings (LR or M/A), + different residue backends, etc. Each mode consists of a + blocksize flag and a mapping (along with the mapping setup */ + + int modes; + int maps; + int floors; + int residues; + int books; + int psys; /* encode only */ + + vorbis_info_mode *mode_param[64]; + int map_type[64]; + vorbis_info_mapping *map_param[64]; + int floor_type[64]; + vorbis_info_floor *floor_param[64]; + int residue_type[64]; + vorbis_info_residue *residue_param[64]; + static_codebook *book_param[256]; + codebook *fullbooks; + + vorbis_info_psy *psy_param[4]; /* encode only */ + vorbis_info_psy_global psy_g_param; + + bitrate_manager_info bi; + highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a + highly redundant structure, but + improves clarity of program flow. */ + int halfrate_flag; /* painless downsample for decode */ +} codec_setup_info; + +extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi); +extern void _vp_global_free(vorbis_look_psy_global *look); + +#endif + diff --git a/sound/OggVorbis/vorbissrc/envelope.c b/sound/OggVorbis/vorbissrc/envelope.c new file mode 100644 index 000000000..f6ce038b1 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/envelope.c @@ -0,0 +1,382 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data envelope analysis + last mod: $Id: envelope.c,v 1.54 2003/09/05 23:17:49 giles Exp $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" + +#include "os.h" +#include "scales.h" +#include "envelope.h" +#include "mdct.h" +#include "misc.h" + +void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + int ch=vi->channels; + int i,j; + int n=e->winlength=128; + e->searchstep=64; /* not random */ + + e->minenergy=gi->preecho_minenergy; + e->ch=ch; + e->storage=128; + e->cursor=ci->blocksizes[1]/2; + e->mdct_win=_ogg_calloc(n,sizeof(*e->mdct_win)); + mdct_init(&e->mdct,n); + + for(i=0;imdct_win[i]=sin(i/(n-1.)*M_PI); + e->mdct_win[i]*=e->mdct_win[i]; + } + + /* magic follows */ + e->band[0].begin=2; e->band[0].end=4; + e->band[1].begin=4; e->band[1].end=5; + e->band[2].begin=6; e->band[2].end=6; + e->band[3].begin=9; e->band[3].end=8; + e->band[4].begin=13; e->band[4].end=8; + e->band[5].begin=17; e->band[5].end=8; + e->band[6].begin=22; e->band[6].end=8; + + for(j=0;jband[j].end; + e->band[j].window=_ogg_malloc(n*sizeof(*e->band[0].window)); + for(i=0;iband[j].window[i]=sin((i+.5)/n*M_PI); + e->band[j].total+=e->band[j].window[i]; + } + e->band[j].total=1./e->band[j].total; + } + + e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter)); + e->mark=_ogg_calloc(e->storage,sizeof(*e->mark)); + +} + +void _ve_envelope_clear(envelope_lookup *e){ + int i; + mdct_clear(&e->mdct); + for(i=0;iband[i].window); + _ogg_free(e->mdct_win); + _ogg_free(e->filter); + _ogg_free(e->mark); + memset(e,0,sizeof(*e)); +} + +/* fairly straight threshhold-by-band based until we find something + that works better and isn't patented. */ + +static int _ve_amp(envelope_lookup *ve, + vorbis_info_psy_global *gi, + float *data, + envelope_band *bands, + envelope_filter_state *filters, + long pos){ + long n=ve->winlength; + int ret=0; + long i,j; + float decay; + + /* we want to have a 'minimum bar' for energy, else we're just + basing blocks on quantization noise that outweighs the signal + itself (for low power signals) */ + + float minV=ve->minenergy; + float *vec=alloca(n*sizeof(*vec)); + + /* stretch is used to gradually lengthen the number of windows + considered prevoius-to-potential-trigger */ + int stretch=max(VE_MINSTRETCH,ve->stretch/2); + float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH); + if(penalty<0.f)penalty=0.f; + if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty; + + /*_analysis_output_always("lpcm",seq2,data,n,0,0, + totalshift+pos*ve->searchstep);*/ + + /* window and transform */ + for(i=0;imdct_win[i]; + mdct_forward(&ve->mdct,vec,vec); + + /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */ + + /* near-DC spreading function; this has nothing to do with + psychoacoustics, just sidelobe leakage and window size */ + { + float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2]; + int ptr=filters->nearptr; + + /* the accumulation is regularly refreshed from scratch to avoid + floating point creep */ + if(ptr==0){ + decay=filters->nearDC_acc=filters->nearDC_partialacc+temp; + filters->nearDC_partialacc=temp; + }else{ + decay=filters->nearDC_acc+=temp; + filters->nearDC_partialacc+=temp; + } + filters->nearDC_acc-=filters->nearDC[ptr]; + filters->nearDC[ptr]=temp; + + decay*=(1./(VE_NEARDC+1)); + filters->nearptr++; + if(filters->nearptr>=VE_NEARDC)filters->nearptr=0; + decay=todB(&decay)*.5-15.f; + } + + /* perform spreading and limiting, also smooth the spectrum. yes, + the MDCT results in all real coefficients, but it still *behaves* + like real/imaginary pairs */ + for(i=0;i>1]=val; + decay-=8.; + } + + /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/ + + /* perform preecho/postecho triggering by band */ + for(j=0;j=VE_AMP)filters[j].ampptr=0; + } + + /* look at min/max, decide trigger */ + if(valmax>gi->preecho_thresh[j]+penalty){ + ret|=1; + ret|=4; + } + if(valminpostecho_thresh[j]-penalty)ret|=2; + } + + return(ret); +} + +#if 0 +static int seq=0; +static ogg_int64_t totalshift=-1024; +#endif + +long _ve_envelope_search(vorbis_dsp_state *v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + envelope_lookup *ve=((private_state *)(v->backend_state))->ve; + long i,j; + + int first=ve->current/ve->searchstep; + int last=v->pcm_current/ve->searchstep-VE_WIN; + if(first<0)first=0; + + /* make sure we have enough storage to match the PCM */ + if(last+VE_WIN+VE_POST>ve->storage){ + ve->storage=last+VE_WIN+VE_POST; /* be sure */ + ve->mark=_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark)); + } + + for(j=first;jstretch++; + if(ve->stretch>VE_MAXSTRETCH*2) + ve->stretch=VE_MAXSTRETCH*2; + + for(i=0;ich;i++){ + float *pcm=v->pcm[i]+ve->searchstep*(j); + ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS,j); + } + + ve->mark[j+VE_POST]=0; + if(ret&1){ + ve->mark[j]=1; + ve->mark[j+1]=1; + } + + if(ret&2){ + ve->mark[j]=1; + if(j>0)ve->mark[j-1]=1; + } + + if(ret&4)ve->stretch=-1; + } + + ve->current=last*ve->searchstep; + + { + long centerW=v->centerW; + long testW= + centerW+ + ci->blocksizes[v->W]/4+ + ci->blocksizes[1]/2+ + ci->blocksizes[0]/4; + + j=ve->cursor; + + while(jcurrent-(ve->searchstep)){/* account for postecho + working back one window */ + if(j>=testW)return(1); + + ve->cursor=j; + + if(ve->mark[j/ve->searchstep]){ + if(j>centerW){ + + #if 0 + if(j>ve->curmark){ + float *marker=alloca(v->pcm_current*sizeof(*marker)); + int l,m; + memset(marker,0,sizeof(*marker)*v->pcm_current); + fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", + seq, + (totalshift+ve->cursor)/44100., + (totalshift+j)/44100.); + _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift); + _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift); + + _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift); + _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift); + + for(m=0;msearchstep]=ve->filter[m].markers[l]*.1; + _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); + } + + for(m=0;msearchstep]=ve->filter[m+VE_BANDS].markers[l]*.1; + _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); + } + + for(l=0;lsearchstep]=ve->mark[l]*.4; + _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift); + + + seq++; + + } +#endif + + ve->curmark=j; + if(j>=testW)return(1); + return(0); + } + } + j+=ve->searchstep; + } + } + + return(-1); +} + +int _ve_envelope_mark(vorbis_dsp_state *v){ + envelope_lookup *ve=((private_state *)(v->backend_state))->ve; + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + long centerW=v->centerW; + long beginW=centerW-ci->blocksizes[v->W]/4; + long endW=centerW+ci->blocksizes[v->W]/4; + if(v->W){ + beginW-=ci->blocksizes[v->lW]/4; + endW+=ci->blocksizes[v->nW]/4; + }else{ + beginW-=ci->blocksizes[0]/4; + endW+=ci->blocksizes[0]/4; + } + + if(ve->curmark>=beginW && ve->curmarksearchstep; + long last=endW/ve->searchstep; + long i; + for(i=first;imark[i])return(1); + } + return(0); +} + +void _ve_envelope_shift(envelope_lookup *e,long shift){ + int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks + ahead of ve->current */ + int smallshift=shift/e->searchstep; + + memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark)); + + #if 0 + for(i=0;ich;i++) + memmove(e->filter[i].markers, + e->filter[i].markers+smallshift, + (1024-smallshift)*sizeof(*(*e->filter).markers)); + totalshift+=shift; + #endif + + e->current-=shift; + if(e->curmark>=0) + e->curmark-=shift; + e->cursor-=shift; +} + + + + + + diff --git a/sound/OggVorbis/vorbissrc/envelope.h b/sound/OggVorbis/vorbissrc/envelope.h new file mode 100644 index 000000000..3087c80fb --- /dev/null +++ b/sound/OggVorbis/vorbissrc/envelope.h @@ -0,0 +1,81 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data envelope analysis and manipulation + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_ENVELOPE_ +#define _V_ENVELOPE_ + +#include "mdct.h" + +#define VE_PRE 16 +#define VE_WIN 4 +#define VE_POST 2 +#define VE_AMP (VE_PRE+VE_POST-1) + +#define VE_BANDS 7 +#define VE_NEARDC 15 + +#define VE_MINSTRETCH 2 /* a bit less than short block */ +#define VE_MAXSTRETCH 12 /* one-third full block */ + +typedef struct { + float ampbuf[VE_AMP]; + int ampptr; + + float nearDC[VE_NEARDC]; + float nearDC_acc; + float nearDC_partialacc; + int nearptr; + +} envelope_filter_state; + +typedef struct { + int begin; + int end; + float *window; + float total; +} envelope_band; + +typedef struct { + int ch; + int winlength; + int searchstep; + float minenergy; + + mdct_lookup mdct; + float *mdct_win; + + envelope_band band[VE_BANDS]; + envelope_filter_state *filter; + int stretch; + + int *mark; + + long storage; + long current; + long curmark; + long cursor; +} envelope_lookup; + +extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi); +extern void _ve_envelope_clear(envelope_lookup *e); +extern long _ve_envelope_search(vorbis_dsp_state *v); +extern void _ve_envelope_shift(envelope_lookup *e,long shift); +extern int _ve_envelope_mark(vorbis_dsp_state *v); + + +#endif + diff --git a/sound/OggVorbis/vorbissrc/floor0.c b/sound/OggVorbis/vorbissrc/floor0.c new file mode 100644 index 000000000..8c253ccad --- /dev/null +++ b/sound/OggVorbis/vorbissrc/floor0.c @@ -0,0 +1,223 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 0 implementation + last mod: $Id: floor0.c,v 1.55 2003/09/05 23:17:49 giles Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "lpc.h" +#include "lsp.h" +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" + +#include "misc.h" +#include + +typedef struct { + int ln; + int m; + int **linearmap; + int n[2]; + + vorbis_info_floor0 *vi; + + long bits; + long frames; +} vorbis_look_floor0; + + +/***********************************************/ + +static void floor0_free_info(vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor0_free_look(vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + if(look){ + + if(look->linearmap){ + + if(look->linearmap[0])_ogg_free(look->linearmap[0]); + if(look->linearmap[1])_ogg_free(look->linearmap[1]); + + _ogg_free(look->linearmap); + } + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int j; + + vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info)); + info->order=oggpack_read(opb,8); + info->rate=oggpack_read(opb,16); + info->barkmap=oggpack_read(opb,16); + info->ampbits=oggpack_read(opb,6); + info->ampdB=oggpack_read(opb,8); + info->numbooks=oggpack_read(opb,4)+1; + + if(info->order<1)goto err_out; + if(info->rate<1)goto err_out; + if(info->barkmap<1)goto err_out; + if(info->numbooks<1)goto err_out; + + for(j=0;jnumbooks;j++){ + info->books[j]=oggpack_read(opb,8); + if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; + } + return(info); + + err_out: + floor0_free_info(info); + return(NULL); +} + +/* initialize Bark scale and normalization lookups. We could do this + with static tables, but Vorbis allows a number of possible + combinations, so it's best to do it computationally. + + The below is authoritative in terms of defining scale mapping. + Note that the scale depends on the sampling rate as well as the + linear block and mapping sizes */ + +static void floor0_map_lazy_init(vorbis_block *vb, + vorbis_info_floor *infoX, + vorbis_look_floor0 *look){ + if(!look->linearmap[vb->W]){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; + int W=vb->W; + int n=ci->blocksizes[W]/2,j; + + /* we choose a scaling constant so that: + floor(bark(rate/2-1)*C)=mapped-1 + floor(bark(rate/2)*C)=mapped */ + float scale=look->ln/toBARK(info->rate/2.f); + + /* the mapping from a linear scale to a smaller bark scale is + straightforward. We do *not* make sure that the linear mapping + does not skip bark-scale bins; the decoder simply skips them and + the encoder may do what it wishes in filling them. They're + necessary in some mapping combinations to keep the scale spacing + accurate */ + look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); + for(j=0;jrate/2.f)/n*j) + *scale); /* bark numbers represent band edges */ + if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ + look->linearmap[W][j]=val; + } + look->linearmap[W][j]=-1; + look->n[W]=n; + } +} + +static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, + vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); + look->m=info->order; + look->ln=info->barkmap; + look->vi=info; + + look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); + + return look; +} + +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + int j,k; + + int ampraw=oggpack_read(&vb->opb,info->ampbits); + if(ampraw>0){ /* also handles the -1 out of data case */ + long maxval=(1<ampbits)-1; + float amp=(float)ampraw/maxval*info->ampdB; + int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + + if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ + codec_setup_info *ci=vb->vd->vi->codec_setup; + codebook *b=ci->fullbooks+info->books[booknum]; + float last=0.f; + + /* the additional b->dim is a guard against any possible stack + smash; b->dim is provably more than we can overflow the + vector */ + float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); + + for(j=0;jm;j+=b->dim) + if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop; + for(j=0;jm;){ + for(k=0;kdim;k++,j++)lsp[j]+=last; + last=lsp[j-1]; + } + + lsp[look->m]=amp; + return(lsp); + } + } + eop: + return(NULL); +} + +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, + void *memo,float *out){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + + floor0_map_lazy_init(vb,info,look); + + if(memo){ + float *lsp=(float *)memo; + float amp=lsp[look->m]; + + /* take the coefficients back to a spectral envelope curve */ + vorbis_lsp_to_curve(out, + look->linearmap[vb->W], + look->n[vb->W], + look->ln, + lsp,look->m,amp,(float)info->ampdB); + return(1); + } + memset(out,0,sizeof(*out)*look->n[vb->W]); + return(0); +} + +/* export hooks */ +vorbis_func_floor floor0_exportbundle={ + NULL,&floor0_unpack,&floor0_look,&floor0_free_info, + &floor0_free_look,&floor0_inverse1,&floor0_inverse2 +}; + + + diff --git a/sound/OggVorbis/vorbissrc/floor1.c b/sound/OggVorbis/vorbissrc/floor1.c new file mode 100644 index 000000000..b5db5318c --- /dev/null +++ b/sound/OggVorbis/vorbissrc/floor1.c @@ -0,0 +1,1089 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 1 implementation + last mod: $Id: floor1.c,v 1.26 2003/02/15 07:10:07 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "scales.h" + +#include + +#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ + +typedef struct { + int sorted_index[VIF_POSIT+2]; + int forward_index[VIF_POSIT+2]; + int reverse_index[VIF_POSIT+2]; + + int hineighbor[VIF_POSIT]; + int loneighbor[VIF_POSIT]; + int posts; + + int n; + int quant_q; + vorbis_info_floor1 *vi; + + long phrasebits; + long postbits; + long frames; +} vorbis_look_floor1; + +typedef struct lsfit_acc{ + long x0; + long x1; + + long xa; + long ya; + long x2a; + long y2a; + long xya; + long an; +} lsfit_acc; + +/***********************************************/ + +static void floor1_free_info(vorbis_info_floor *i){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor1_free_look(vorbis_look_floor *i){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; + if(look){ + /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n", + (float)look->phrasebits/look->frames, + (float)look->postbits/look->frames, + (float)(look->postbits+look->phrasebits)/look->frames);*/ + + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + int j,k; + int count=0; + int rangebits; + int maxposit=info->postlist[1]; + int maxclass=-1; + + /* save out partitions */ + oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */ + for(j=0;jpartitions;j++){ + oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */ + if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; + } + + /* save out partition classes */ + for(j=0;jclass_dim[j]-1,3); /* 1 to 8 */ + oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */ + if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8); + for(k=0;k<(1<class_subs[j]);k++) + oggpack_write(opb,info->class_subbook[j][k]+1,8); + } + + /* save out the post list */ + oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */ + oggpack_write(opb,ilog2(maxposit),4); + rangebits=ilog2(maxposit); + + for(j=0,k=0;jpartitions;j++){ + count+=info->class_dim[info->partitionclass[j]]; + for(;kpostlist[k+2],rangebits); + } +} + + +static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int j,k,count=0,maxclass=-1,rangebits; + + vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info)); + /* read partitions */ + info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ + for(j=0;jpartitions;j++){ + info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ + if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; + } + + /* read partition classes */ + for(j=0;jclass_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */ + info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */ + if(info->class_subs[j]<0) + goto err_out; + if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8); + if(info->class_book[j]<0 || info->class_book[j]>=ci->books) + goto err_out; + for(k=0;k<(1<class_subs[j]);k++){ + info->class_subbook[j][k]=oggpack_read(opb,8)-1; + if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books) + goto err_out; + } + } + + /* read the post list */ + info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ + rangebits=oggpack_read(opb,4); + + for(j=0,k=0;jpartitions;j++){ + count+=info->class_dim[info->partitionclass[j]]; + for(;kpostlist[k+2]=oggpack_read(opb,rangebits); + if(t<0 || t>=(1<postlist[0]=0; + info->postlist[1]=1<vi=info; + look->n=info->postlist[1]; + + /* we drop each position value in-between already decoded values, + and use linear interpolation to predict each new value past the + edges. The positions are read in the order of the position + list... we precompute the bounding positions in the lookup. Of + course, the neighbors can change (if a position is declined), but + this is an initial mapping */ + + for(i=0;ipartitions;i++)n+=info->class_dim[info->partitionclass[i]]; + n+=2; + look->posts=n; + + /* also store a sorted position index */ + for(i=0;ipostlist+i; + qsort(sortpointer,n,sizeof(*sortpointer),icomp); + + /* points from sort order back to range number */ + for(i=0;iforward_index[i]=sortpointer[i]-info->postlist; + /* points from range order to sorted position */ + for(i=0;ireverse_index[look->forward_index[i]]=i; + /* we actually need the post values too */ + for(i=0;isorted_index[i]=info->postlist[look->forward_index[i]]; + + /* quantize values to multiplier spec */ + switch(info->mult){ + case 1: /* 1024 -> 256 */ + look->quant_q=256; + break; + case 2: /* 1024 -> 128 */ + look->quant_q=128; + break; + case 3: /* 1024 -> 86 */ + look->quant_q=86; + break; + case 4: /* 1024 -> 64 */ + look->quant_q=64; + break; + } + + /* discover our neighbors for decode where we don't use fit flags + (that would push the neighbors outward) */ + for(i=0;in; + int currentx=info->postlist[i+2]; + for(j=0;jpostlist[j]; + if(x>lx && xcurrentx){ + hi=j; + hx=x; + } + } + look->loneighbor[i]=lo; + look->hineighbor[i]=hi; + } + + return(look); +} + +static int render_point(int x0,int x1,int y0,int y1,int x){ + y0&=0x7fff; /* mask off flag */ + y1&=0x7fff; + + { + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int err=ady*(x-x0); + + int off=err/adx; + if(dy<0)return(y0-off); + return(y0+off); + } +} + +static int vorbis_dBquant(const float *x){ + int i= *x*7.3142857f+1023.5f; + if(i>1023)return(1023); + if(i<0)return(0); + return i; +} + +static float FLOOR1_fromdB_LOOKUP[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +static void render_line(int x0,int x1,int y0,int y1,float *d){ + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int base=dy/adx; + int sy=(dy<0?base-1:base+1); + int x=x0; + int y=y0; + int err=0; + + ady-=abs(base*adx); + + d[x]*=FLOOR1_fromdB_LOOKUP[y]; + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + d[x]*=FLOOR1_fromdB_LOOKUP[y]; + } +} + +static void render_line0(int x0,int x1,int y0,int y1,int *d){ + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int base=dy/adx; + int sy=(dy<0?base-1:base+1); + int x=x0; + int y=y0; + int err=0; + + ady-=abs(base*adx); + + d[x]=y; + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + d[x]=y; + } +} + +/* the floor has already been filtered to only include relevant sections */ +static int accumulate_fit(const float *flr,const float *mdct, + int x0, int x1,lsfit_acc *a, + int n,vorbis_info_floor1 *info){ + long i; + int quantized=vorbis_dBquant(flr+x0); + + long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0; + + memset(a,0,sizeof(*a)); + a->x0=x0; + a->x1=x1; + if(x1>=n)x1=n-1; + + for(i=x0;i<=x1;i++){ + int quantized=vorbis_dBquant(flr+i); + if(quantized){ + if(mdct[i]+info->twofitatten>=flr[i]){ + xa += i; + ya += quantized; + x2a += i*i; + y2a += quantized*quantized; + xya += i*quantized; + na++; + }else{ + xb += i; + yb += quantized; + x2b += i*i; + y2b += quantized*quantized; + xyb += i*quantized; + nb++; + } + } + } + + xb+=xa; + yb+=ya; + x2b+=x2a; + y2b+=y2a; + xyb+=xya; + nb+=na; + + /* weight toward the actually used frequencies if we meet the threshhold */ + { + int weight=nb*info->twofitweight/(na+1); + + a->xa=xa*weight+xb; + a->ya=ya*weight+yb; + a->x2a=x2a*weight+x2b; + a->y2a=y2a*weight+y2b; + a->xya=xya*weight+xyb; + a->an=na*weight+nb; + } + + return(na); +} + +static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){ + long x=0,y=0,x2=0,y2=0,xy=0,an=0,i; + long x0=a[0].x0; + long x1=a[fits-1].x1; + + for(i=0;i=0){ + x+= x0; + y+= *y0; + x2+= x0 * x0; + y2+= *y0 * *y0; + xy+= *y0 * x0; + an++; + } + + if(*y1>=0){ + x+= x1; + y+= *y1; + x2+= x1 * x1; + y2+= *y1 * *y1; + xy+= *y1 * x1; + an++; + } + + if(an){ + /* need 64 bit multiplies, which C doesn't give portably as int */ + double fx=x; + double fy=y; + double fx2=x2; + double fxy=xy; + double denom=1./(an*fx2-fx*fx); + double a=(fy*fx2-fxy*fx)*denom; + double b=(an*fxy-fx*fy)*denom; + *y0=rint(a+b*x0); + *y1=rint(a+b*x1); + + /* limit to our range! */ + if(*y0>1023)*y0=1023; + if(*y1>1023)*y1=1023; + if(*y0<0)*y0=0; + if(*y1<0)*y1=0; + + }else{ + *y0=0; + *y1=0; + } +} + +/*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){ + long y=0; + int i; + + for(i=0;itwofitatten>=mask[x]){ + if(y+info->maxovermaxunder>val)return(1); + } + + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + + val=vorbis_dBquant(mask+x); + mse+=((y-val)*(y-val)); + n++; + if(mdct[x]+info->twofitatten>=mask[x]){ + if(val){ + if(y+info->maxovermaxunder>val)return(1); + } + } + } + + if(info->maxover*info->maxover/n>info->maxerr)return(0); + if(info->maxunder*info->maxunder/n>info->maxerr)return(0); + if(mse/n>info->maxerr)return(1); + return(0); +} + +static int post_Y(int *A,int *B,int pos){ + if(A[pos]<0) + return B[pos]; + if(B[pos]<0) + return A[pos]; + + return (A[pos]+B[pos])>>1; +} + +static int seq=0; + +int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look, + const float *logmdct, /* in */ + const float *logmask){ + long i,j; + vorbis_info_floor1 *info=look->vi; + long n=look->n; + long posts=look->posts; + long nonzero=0; + lsfit_acc fits[VIF_POSIT+1]; + int fit_valueA[VIF_POSIT+2]; /* index by range list position */ + int fit_valueB[VIF_POSIT+2]; /* index by range list position */ + + int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */ + int hineighbor[VIF_POSIT+2]; + int *output=NULL; + int memo[VIF_POSIT+2]; + + for(i=0;isorted_index[i], + look->sorted_index[i+1],fits+i, + n,info); + } + + if(nonzero){ + /* start by fitting the implicit base case.... */ + int y0=-200; + int y1=-200; + fit_line(fits,posts-1,&y0,&y1); + + fit_valueA[0]=y0; + fit_valueB[0]=y0; + fit_valueB[1]=y1; + fit_valueA[1]=y1; + + /* Non degenerate case */ + /* start progressive splitting. This is a greedy, non-optimal + algorithm, but simple and close enough to the best + answer. */ + for(i=2;ireverse_index[i]; + int ln=loneighbor[sortpos]; + int hn=hineighbor[sortpos]; + + /* eliminate repeat searches of a particular range with a memo */ + if(memo[ln]!=hn){ + /* haven't performed this error search yet */ + int lsortpos=look->reverse_index[ln]; + int hsortpos=look->reverse_index[hn]; + memo[ln]=hn; + + { + /* A note: we want to bound/minimize *local*, not global, error */ + int lx=info->postlist[ln]; + int hx=info->postlist[hn]; + int ly=post_Y(fit_valueA,fit_valueB,ln); + int hy=post_Y(fit_valueA,fit_valueB,hn); + + if(ly==-1 || hy==-1){ + exit(1); + } + + if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){ + /* outside error bounds/begin search area. Split it. */ + int ly0=-200; + int ly1=-200; + int hy0=-200; + int hy1=-200; + fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1); + fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1); + + /* store new edge values */ + fit_valueB[ln]=ly0; + if(ln==0)fit_valueA[ln]=ly0; + fit_valueA[i]=ly1; + fit_valueB[i]=hy0; + fit_valueA[hn]=hy1; + if(hn==1)fit_valueB[hn]=hy1; + + if(ly1>=0 || hy0>=0){ + /* store new neighbor values */ + for(j=sortpos-1;j>=0;j--) + if(hineighbor[j]==hn) + hineighbor[j]=i; + else + break; + for(j=sortpos+1;jloneighbor[i-2]; + int hn=look->hineighbor[i-2]; + int x0=info->postlist[ln]; + int x1=info->postlist[hn]; + int y0=output[ln]; + int y1=output[hn]; + + int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); + int vx=post_Y(fit_valueA,fit_valueB,i); + + if(vx>=0 && predicted!=vx){ + output[i]=vx; + }else{ + output[i]= predicted|0x8000; + } + } + } + + return(output); + +} + +int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look, + int *A,int *B, + int del){ + + long i; + long posts=look->posts; + int *output=NULL; + + if(A && B){ + output=_vorbis_block_alloc(vb,sizeof(*output)*posts); + + for(i=0;i>16; + if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000; + } + } + + return(output); +} + + +int floor1_encode(vorbis_block *vb,vorbis_look_floor1 *look, + int *post,int *ilogmask){ + + long i,j; + vorbis_info_floor1 *info=look->vi; + long n=look->n; + long posts=look->posts; + codec_setup_info *ci=vb->vd->vi->codec_setup; + int out[VIF_POSIT+2]; + static_codebook **sbooks=ci->book_param; + codebook *books=ci->fullbooks; + static long seq=0; + + /* quantize values to multiplier spec */ + if(post){ + for(i=0;imult){ + case 1: /* 1024 -> 256 */ + val>>=2; + break; + case 2: /* 1024 -> 128 */ + val>>=3; + break; + case 3: /* 1024 -> 86 */ + val/=12; + break; + case 4: /* 1024 -> 64 */ + val>>=4; + break; + } + post[i]=val | (post[i]&0x8000); + } + + out[0]=post[0]; + out[1]=post[1]; + + /* find prediction values for each post and subtract them */ + for(i=2;iloneighbor[i-2]; + int hn=look->hineighbor[i-2]; + int x0=info->postlist[ln]; + int x1=info->postlist[hn]; + int y0=post[ln]; + int y1=post[hn]; + + int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); + + if((post[i]&0x8000) || (predicted==post[i])){ + post[i]=predicted|0x8000; /* in case there was roundoff jitter + in interpolation */ + out[i]=0; + }else{ + int headroom=(look->quant_q-predictedquant_q-predicted:predicted); + + int val=post[i]-predicted; + + /* at this point the 'deviation' value is in the range +/- max + range, but the real, unique range can always be mapped to + only [0-maxrange). So we want to wrap the deviation into + this limited range, but do it in the way that least screws + an essentially gaussian probability distribution. */ + + if(val<0) + if(val<-headroom) + val=headroom-val-1; + else + val=-1-(val<<1); + else + if(val>=headroom) + val= val+headroom; + else + val<<=1; + + out[i]=val; + post[ln]&=0x7fff; + post[hn]&=0x7fff; + } + } + + /* we have everything we need. pack it out */ + /* mark nontrivial floor */ + oggpack_write(&vb->opb,1,1); + + /* beginning/end post */ + look->frames++; + look->postbits+=ilog(look->quant_q-1)*2; + oggpack_write(&vb->opb,out[0],ilog(look->quant_q-1)); + oggpack_write(&vb->opb,out[1],ilog(look->quant_q-1)); + + + /* partition by partition */ + for(i=0,j=2;ipartitions;i++){ + int class=info->partitionclass[i]; + int cdim=info->class_dim[class]; + int csubbits=info->class_subs[class]; + int csub=1<class_subbook[class][k]; + if(booknum<0){ + maxval[k]=1; + }else{ + maxval[k]=sbooks[info->class_subbook[class][k]]->entries; + } + } + for(k=0;kphrasebits+= + vorbis_book_encode(books+info->class_book[class],cval,&vb->opb); + +#ifdef TRAIN_FLOOR1 + { + FILE *of; + char buffer[80]; + sprintf(buffer,"line_%dx%ld_class%d.vqd", + vb->pcmend/2,posts-2,class); + of=fopen(buffer,"a"); + fprintf(of,"%d\n",cval); + fclose(of); + } +#endif + } + + /* write post values */ + for(k=0;kclass_subbook[class][bookas[k]]; + if(book>=0){ + /* hack to allow training with 'bad' books */ + if(out[j+k]<(books+book)->entries) + look->postbits+=vorbis_book_encode(books+book, + out[j+k],&vb->opb); + /*else + fprintf(stderr,"+!");*/ + +#ifdef TRAIN_FLOOR1 + { + FILE *of; + char buffer[80]; + sprintf(buffer,"line_%dx%ld_%dsub%d.vqd", + vb->pcmend/2,posts-2,class,bookas[k]); + of=fopen(buffer,"a"); + fprintf(of,"%d\n",out[j+k]); + fclose(of); + } +#endif + } + } + j+=cdim; + } + + { + /* generate quantized floor equivalent to what we'd unpack in decode */ + /* render the lines */ + int hx=0; + int lx=0; + int ly=post[0]*info->mult; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; + int hy=post[current]&0x7fff; + if(hy==post[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line0(lx,hx,ly,hy,ilogmask); + + lx=hx; + ly=hy; + } + } + for(j=hx;jpcmend/2;j++)ilogmask[j]=ly; /* be certain */ + seq++; + return(1); + } + }else{ + oggpack_write(&vb->opb,0,1); + memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask)); + seq++; + return(0); + } +} + +static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + codec_setup_info *ci=vb->vd->vi->codec_setup; + + int i,j,k; + codebook *books=ci->fullbooks; + + /* unpack wrapped/predicted values from stream */ + if(oggpack_read(&vb->opb,1)==1){ + int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); + + fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + + /* partition by partition */ + for(i=0,j=2;ipartitions;i++){ + int class=info->partitionclass[i]; + int cdim=info->class_dim[class]; + int csubbits=info->class_subs[class]; + int csub=1<class_book[class],&vb->opb); + + if(cval==-1)goto eop; + } + + for(k=0;kclass_subbook[class][cval&(csub-1)]; + cval>>=csubbits; + if(book>=0){ + if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) + goto eop; + }else{ + fit_value[j+k]=0; + } + } + j+=cdim; + } + + /* unwrap positive values and reconsitute via linear interpolation */ + for(i=2;iposts;i++){ + int predicted=render_point(info->postlist[look->loneighbor[i-2]], + info->postlist[look->hineighbor[i-2]], + fit_value[look->loneighbor[i-2]], + fit_value[look->hineighbor[i-2]], + info->postlist[i]); + int hiroom=look->quant_q-predicted; + int loroom=predicted; + int room=(hiroom=room){ + if(hiroom>loroom){ + val = val-loroom; + }else{ + val = -1-(val-hiroom); + } + }else{ + if(val&1){ + val= -((val+1)>>1); + }else{ + val>>=1; + } + } + + fit_value[i]=val+predicted; + fit_value[look->loneighbor[i-2]]&=0x7fff; + fit_value[look->hineighbor[i-2]]&=0x7fff; + + }else{ + fit_value[i]=predicted|0x8000; + } + + } + + return(fit_value); + } + eop: + return(NULL); +} + +static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, + float *out){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + + codec_setup_info *ci=vb->vd->vi->codec_setup; + int n=ci->blocksizes[vb->W]/2; + int j; + + if(memo){ + /* render the lines */ + int *fit_value=(int *)memo; + int hx=0; + int lx=0; + int ly=fit_value[0]*info->mult; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; + int hy=fit_value[current]&0x7fff; + if(hy==fit_value[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line(lx,hx,ly,hy,out); + + lx=hx; + ly=hy; + } + } + for(j=hx;j header packets + last mod: $Id: info.c,v 1.62 2003/09/10 01:10:18 xiphmont Exp $ + + ********************************************************************/ + +/* general handling of the header and the vorbis_info structure (and + substructures) */ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "codebook.h" +#include "registry.h" +#include "window.h" +#include "psy.h" +#include "misc.h" +#include "os.h" + +/* helpers */ +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void _v_writestring(oggpack_buffer *o,char *s, int bytes){ + + while(bytes--){ + oggpack_write(o,*s++,8); + } +} + +static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ + while(bytes--){ + *buf++=oggpack_read(o,8); + } +} + +void vorbis_comment_init(vorbis_comment *vc){ + memset(vc,0,sizeof(*vc)); +} + +void vorbis_comment_add(vorbis_comment *vc,char *comment){ + vc->user_comments=_ogg_realloc(vc->user_comments, + (vc->comments+2)*sizeof(*vc->user_comments)); + vc->comment_lengths=_ogg_realloc(vc->comment_lengths, + (vc->comments+2)*sizeof(*vc->comment_lengths)); + vc->comment_lengths[vc->comments]=strlen(comment); + vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1); + strcpy(vc->user_comments[vc->comments], comment); + vc->comments++; + vc->user_comments[vc->comments]=NULL; +} + +void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){ + char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */ + strcpy(comment, tag); + strcat(comment, "="); + strcat(comment, contents); + vorbis_comment_add(vc, comment); +} + +/* This is more or less the same as strncasecmp - but that doesn't exist + * everywhere, and this is a fairly trivial function, so we include it */ +static int tagcompare(const char *s1, const char *s2, int n){ + int c=0; + while(c < n){ + if(toupper(s1[c]) != toupper(s2[c])) + return !0; + c++; + } + return 0; +} + +char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ + long i; + int found = 0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = alloca(taglen+ 1); + + strcpy(fulltag, tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ + if(count == found) + /* We return a pointer to the data, not a copy */ + return vc->user_comments[i] + taglen; + else + found++; + } + } + return NULL; /* didn't find anything */ +} + +int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ + int i,count=0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = alloca(taglen+1); + strcpy(fulltag,tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)) + count++; + } + + return count; +} + +void vorbis_comment_clear(vorbis_comment *vc){ + if(vc){ + long i; + for(i=0;icomments;i++) + if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); + if(vc->user_comments)_ogg_free(vc->user_comments); + if(vc->comment_lengths)_ogg_free(vc->comment_lengths); + if(vc->vendor)_ogg_free(vc->vendor); + } + memset(vc,0,sizeof(*vc)); +} + +/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. + They may be equal, but short will never ge greater than long */ +int vorbis_info_blocksize(vorbis_info *vi,int zo){ + codec_setup_info *ci = vi->codec_setup; + return ci ? ci->blocksizes[zo] : -1; +} + +/* used by synthesis, which has a full, alloced vi */ +void vorbis_info_init(vorbis_info *vi){ + memset(vi,0,sizeof(*vi)); + vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info)); +} + +void vorbis_info_clear(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + int i; + + if(ci){ + + for(i=0;imodes;i++) + if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); + + for(i=0;imaps;i++) /* unpack does the range checking */ + _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); + + for(i=0;ifloors;i++) /* unpack does the range checking */ + _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); + + for(i=0;iresidues;i++) /* unpack does the range checking */ + _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); + + for(i=0;ibooks;i++){ + if(ci->book_param[i]){ + /* knows if the book was not alloced */ + vorbis_staticbook_destroy(ci->book_param[i]); + } + if(ci->fullbooks) + vorbis_book_clear(ci->fullbooks+i); + } + if(ci->fullbooks) + _ogg_free(ci->fullbooks); + + for(i=0;ipsys;i++) + _vi_psy_free(ci->psy_param[i]); + + _ogg_free(ci); + } + + memset(vi,0,sizeof(*vi)); +} + +/* Header packing/unpacking ********************************************/ + +static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + if(!ci)return(OV_EFAULT); + + vi->version=oggpack_read(opb,32); + if(vi->version!=0)return(OV_EVERSION); + + vi->channels=oggpack_read(opb,8); + vi->rate=oggpack_read(opb,32); + + vi->bitrate_upper=oggpack_read(opb,32); + vi->bitrate_nominal=oggpack_read(opb,32); + vi->bitrate_lower=oggpack_read(opb,32); + + ci->blocksizes[0]=1<blocksizes[1]=1<rate<1)goto err_out; + if(vi->channels<1)goto err_out; + if(ci->blocksizes[0]<8)goto err_out; + if(ci->blocksizes[1]blocksizes[0])goto err_out; + + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ + int i; + int vendorlen=oggpack_read(opb,32); + if(vendorlen<0)goto err_out; + vc->vendor=_ogg_calloc(vendorlen+1,1); + _v_readstring(opb,vc->vendor,vendorlen); + vc->comments=oggpack_read(opb,32); + if(vc->comments<0)goto err_out; + vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); + vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); + + for(i=0;icomments;i++){ + int len=oggpack_read(opb,32); + if(len<0)goto err_out; + vc->comment_lengths[i]=len; + vc->user_comments[i]=_ogg_calloc(len+1,1); + _v_readstring(opb,vc->user_comments[i],len); + } + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_comment_clear(vc); + return(OV_EBADHEADER); +} + +/* all of the real encoding details are here. The modes, books, + everything */ +static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int i; + if(!ci)return(OV_EFAULT); + + /* codebooks */ + ci->books=oggpack_read(opb,8)+1; + /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ + for(i=0;ibooks;i++){ + ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i])); + if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; + } + + /* time backend settings; hooks are unused */ + { + int times=oggpack_read(opb,6)+1; + for(i=0;i=VI_TIMEB)goto err_out; + } + } + + /* floor backend settings */ + ci->floors=oggpack_read(opb,6)+1; + /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ + /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ + for(i=0;ifloors;i++){ + ci->floor_type[i]=oggpack_read(opb,16); + if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; + ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); + if(!ci->floor_param[i])goto err_out; + } + + /* residue backend settings */ + ci->residues=oggpack_read(opb,6)+1; + /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ + /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ + for(i=0;iresidues;i++){ + ci->residue_type[i]=oggpack_read(opb,16); + if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; + ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); + if(!ci->residue_param[i])goto err_out; + } + + /* map backend settings */ + ci->maps=oggpack_read(opb,6)+1; + /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ + /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ + for(i=0;imaps;i++){ + ci->map_type[i]=oggpack_read(opb,16); + if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; + ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); + if(!ci->map_param[i])goto err_out; + } + + /* mode settings */ + ci->modes=oggpack_read(opb,6)+1; + /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ + for(i=0;imodes;i++){ + ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i])); + ci->mode_param[i]->blockflag=oggpack_read(opb,1); + ci->mode_param[i]->windowtype=oggpack_read(opb,16); + ci->mode_param[i]->transformtype=oggpack_read(opb,16); + ci->mode_param[i]->mapping=oggpack_read(opb,8); + + if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; + } + + if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +/* The Vorbis header is in three packets; the initial small packet in + the first page that identifies basic parameters, a second packet + with bitstream comments and a third packet that holds the + codebook. */ + +int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ + oggpack_buffer opb; + + if(op){ + oggpack_readinit(&opb,op->packet,op->bytes); + + /* Which of the three types of header is this? */ + /* Also verify header-ness, vorbis */ + { + char buffer[6]; + int packtype=oggpack_read(&opb,8); + memset(buffer,0,6); + _v_readstring(&opb,buffer,6); + if(memcmp(buffer,"vorbis",6)){ + /* not a vorbis header */ + return(OV_ENOTVORBIS); + } + switch(packtype){ + case 0x01: /* least significant *bit* is read first */ + if(!op->b_o_s){ + /* Not the initial packet */ + return(OV_EBADHEADER); + } + if(vi->rate!=0){ + /* previously initialized info header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_info(vi,&opb)); + + case 0x03: /* least significant *bit* is read first */ + if(vi->rate==0){ + /* um... we didn't get the initial header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_comment(vc,&opb)); + + case 0x05: /* least significant *bit* is read first */ + if(vi->rate==0 || vc->vendor==NULL){ + /* um... we didn;t get the initial header or comments yet */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_books(vi,&opb)); + + default: + /* Not a valid vorbis header type */ + return(OV_EBADHEADER); + break; + } + } + } + return(OV_EBADHEADER); +} + +/* pack side **********************************************************/ + +static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + if(!ci)return(OV_EFAULT); + + /* preamble */ + oggpack_write(opb,0x01,8); + _v_writestring(opb,"vorbis", 6); + + /* basic information about the stream */ + oggpack_write(opb,0x00,32); + oggpack_write(opb,vi->channels,8); + oggpack_write(opb,vi->rate,32); + + oggpack_write(opb,vi->bitrate_upper,32); + oggpack_write(opb,vi->bitrate_nominal,32); + oggpack_write(opb,vi->bitrate_lower,32); + + oggpack_write(opb,ilog2(ci->blocksizes[0]),4); + oggpack_write(opb,ilog2(ci->blocksizes[1]),4); + oggpack_write(opb,1,1); + + return(0); +} + +static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){ + char temp[]="Xiph.Org libVorbis I 20030909"; + int bytes = strlen(temp); + + /* preamble */ + oggpack_write(opb,0x03,8); + _v_writestring(opb,"vorbis", 6); + + /* vendor */ + oggpack_write(opb,bytes,32); + _v_writestring(opb,temp, bytes); + + /* comments */ + + oggpack_write(opb,vc->comments,32); + if(vc->comments){ + int i; + for(i=0;icomments;i++){ + if(vc->user_comments[i]){ + oggpack_write(opb,vc->comment_lengths[i],32); + _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]); + }else{ + oggpack_write(opb,0,32); + } + } + } + oggpack_write(opb,1,1); + + return(0); +} + +static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + int i; + if(!ci)return(OV_EFAULT); + + oggpack_write(opb,0x05,8); + _v_writestring(opb,"vorbis", 6); + + /* books */ + oggpack_write(opb,ci->books-1,8); + for(i=0;ibooks;i++) + if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out; + + /* times; hook placeholders */ + oggpack_write(opb,0,6); + oggpack_write(opb,0,16); + + /* floors */ + oggpack_write(opb,ci->floors-1,6); + for(i=0;ifloors;i++){ + oggpack_write(opb,ci->floor_type[i],16); + if(_floor_P[ci->floor_type[i]]->pack) + _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb); + else + goto err_out; + } + + /* residues */ + oggpack_write(opb,ci->residues-1,6); + for(i=0;iresidues;i++){ + oggpack_write(opb,ci->residue_type[i],16); + _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb); + } + + /* maps */ + oggpack_write(opb,ci->maps-1,6); + for(i=0;imaps;i++){ + oggpack_write(opb,ci->map_type[i],16); + _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb); + } + + /* modes */ + oggpack_write(opb,ci->modes-1,6); + for(i=0;imodes;i++){ + oggpack_write(opb,ci->mode_param[i]->blockflag,1); + oggpack_write(opb,ci->mode_param[i]->windowtype,16); + oggpack_write(opb,ci->mode_param[i]->transformtype,16); + oggpack_write(opb,ci->mode_param[i]->mapping,8); + } + oggpack_write(opb,1,1); + + return(0); +err_out: + return(-1); +} + +int vorbis_commentheader_out(vorbis_comment *vc, + ogg_packet *op){ + + oggpack_buffer opb; + + oggpack_writeinit(&opb); + if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; + + op->packet = _ogg_malloc(oggpack_bytes(&opb)); + memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); + + op->bytes=oggpack_bytes(&opb); + op->b_o_s=0; + op->e_o_s=0; + op->granulepos=0; + + return 0; +} + +int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code){ + int ret=OV_EIMPL; + vorbis_info *vi=v->vi; + oggpack_buffer opb; + private_state *b=v->backend_state; + + if(!b){ + ret=OV_EFAULT; + goto err_out; + } + + /* first header packet **********************************************/ + + oggpack_writeinit(&opb); + if(_vorbis_pack_info(&opb,vi))goto err_out; + + /* build the packet */ + if(b->header)_ogg_free(b->header); + b->header=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); + op->packet=b->header; + op->bytes=oggpack_bytes(&opb); + op->b_o_s=1; + op->e_o_s=0; + op->granulepos=0; + + /* second header packet (comments) **********************************/ + + oggpack_reset(&opb); + if(_vorbis_pack_comment(&opb,vc))goto err_out; + + if(b->header1)_ogg_free(b->header1); + b->header1=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); + op_comm->packet=b->header1; + op_comm->bytes=oggpack_bytes(&opb); + op_comm->b_o_s=0; + op_comm->e_o_s=0; + op_comm->granulepos=0; + + /* third header packet (modes/codebooks) ****************************/ + + oggpack_reset(&opb); + if(_vorbis_pack_books(&opb,vi))goto err_out; + + if(b->header2)_ogg_free(b->header2); + b->header2=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); + op_code->packet=b->header2; + op_code->bytes=oggpack_bytes(&opb); + op_code->b_o_s=0; + op_code->e_o_s=0; + op_code->granulepos=0; + + oggpack_writeclear(&opb); + return(0); + err_out: + oggpack_writeclear(&opb); + memset(op,0,sizeof(*op)); + memset(op_comm,0,sizeof(*op_comm)); + memset(op_code,0,sizeof(*op_code)); + + if(b->header)_ogg_free(b->header); + if(b->header1)_ogg_free(b->header1); + if(b->header2)_ogg_free(b->header2); + b->header=NULL; + b->header1=NULL; + b->header2=NULL; + return(ret); +} + +double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){ + if(granulepos>=0) + return((double)granulepos/v->vi->rate); + return(-1); +} diff --git a/sound/OggVorbis/vorbissrc/lookup.c b/sound/OggVorbis/vorbissrc/lookup.c new file mode 100644 index 000000000..de145de2c --- /dev/null +++ b/sound/OggVorbis/vorbissrc/lookup.c @@ -0,0 +1,94 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup based functions + last mod: $Id: lookup.c,v 1.9 2002/01/22 08:06:07 xiphmont Exp $ + + ********************************************************************/ + +#include +#include "lookup.h" +#include "lookup_data.h" +#include "os.h" +#include "misc.h" + +#ifdef FLOAT_LOOKUP + +/* interpolated lookup based cos function, domain 0 to PI only */ +float vorbis_coslook(float a){ + double d=a*(.31830989*(float)COS_LOOKUP_SZ); + int i=vorbis_ftoi(d-.5); + + return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]); +} + +/* interpolated 1./sqrt(p) where .5 <= p < 1. */ +float vorbis_invsqlook(float a){ + double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ; + int i=vorbis_ftoi(d-.5f); + return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]); +} + +/* interpolated 1./sqrt(p) where .5 <= p < 1. */ +float vorbis_invsq2explook(int a){ + return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN]; +} + +#include +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ +float vorbis_fromdBlook(float a){ + int i=vorbis_ftoi(a*((float)(-(1<=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); +} + +#endif + +#ifdef INT_LOOKUP +/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in + 16.16 format + + returns in m.8 format */ +long vorbis_invsqlook_i(long a,long e){ + long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); + long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */ + long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ + (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */ + d)>>16); /* result 1.16 */ + + e+=32; + if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */ + e=(e>>1)-8; + + return(val>>e); +} + +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ +/* a is in n.12 format */ +float vorbis_fromdBlook_i(long a){ + int i=(-a)>>(12-FROMdB2_SHIFT); + return (i<0)?1.f: + ((i>=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); +} + +/* interpolated lookup based cos function, domain 0 to PI only */ +/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */ +long vorbis_coslook_i(long a){ + int i=a>>COS_LOOKUP_I_SHIFT; + int d=a&COS_LOOKUP_I_MASK; + return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>> + COS_LOOKUP_I_SHIFT); +} + +#endif diff --git a/sound/OggVorbis/vorbissrc/lookup.h b/sound/OggVorbis/vorbissrc/lookup.h new file mode 100644 index 000000000..778c3f6c1 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/lookup.h @@ -0,0 +1,32 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup based functions + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_LOOKUP_H_ + +#ifdef FLOAT_LOOKUP +extern float vorbis_coslook(float a); +extern float vorbis_invsqlook(float a); +extern float vorbis_invsq2explook(int a); +extern float vorbis_fromdBlook(float a); +#endif +#ifdef INT_LOOKUP +extern long vorbis_invsqlook_i(long a,long e); +extern long vorbis_coslook_i(long a); +extern float vorbis_fromdBlook_i(long a); +#endif + +#endif diff --git a/sound/OggVorbis/vorbissrc/lookup_data.h b/sound/OggVorbis/vorbissrc/lookup_data.h new file mode 100644 index 000000000..a2266eac4 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/lookup_data.h @@ -0,0 +1,189 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup data; generated by lookups.pl; edit there + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_LOOKUP_DATA_H_ + +#ifdef FLOAT_LOOKUP +#define COS_LOOKUP_SZ 128 +static float COS_LOOKUP[COS_LOOKUP_SZ+1]={ + +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f, + +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f, + +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f, + +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f, + +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f, + +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f, + +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f, + +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f, + +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f, + +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f, + +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f, + +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f, + +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f, + +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f, + +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f, + +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f, + +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f, + -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f, + -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f, + -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f, + -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f, + -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f, + -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f, + -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f, + -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f, + -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f, + -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f, + -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f, + -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f, + -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f, + -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f, + -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f, + -1.0000000000000f, +}; + +#define INVSQ_LOOKUP_SZ 32 +static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={ + 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f, + 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f, + 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f, + 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f, + 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f, + 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f, + 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f, + 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f, + 1.000000000000f, +}; + +#define INVSQ2EXP_LOOKUP_MIN (-32) +#define INVSQ2EXP_LOOKUP_MAX 32 +static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\ + INVSQ2EXP_LOOKUP_MIN+1]={ + 65536.f, 46340.95001f, 32768.f, 23170.47501f, + 16384.f, 11585.2375f, 8192.f, 5792.618751f, + 4096.f, 2896.309376f, 2048.f, 1448.154688f, + 1024.f, 724.0773439f, 512.f, 362.038672f, + 256.f, 181.019336f, 128.f, 90.50966799f, + 64.f, 45.254834f, 32.f, 22.627417f, + 16.f, 11.3137085f, 8.f, 5.656854249f, + 4.f, 2.828427125f, 2.f, 1.414213562f, + 1.f, 0.7071067812f, 0.5f, 0.3535533906f, + 0.25f, 0.1767766953f, 0.125f, 0.08838834765f, + 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f, + 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f, + 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f, + 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f, + 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f, + 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f, + 1.525878906e-05f, +}; + +#endif + +#define FROMdB_LOOKUP_SZ 35 +#define FROMdB2_LOOKUP_SZ 32 +#define FROMdB_SHIFT 5 +#define FROMdB2_SHIFT 3 +#define FROMdB2_MASK 31 +static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={ + 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f, + 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f, + 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f, + 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f, + 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f, + 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f, + 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f, + 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f, + 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f, +}; + +static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={ + 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f, + 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f, + 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f, + 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f, + 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f, + 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f, + 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f, + 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f, +}; + +#ifdef INT_LOOKUP + +#define INVSQ_LOOKUP_I_SHIFT 10 +#define INVSQ_LOOKUP_I_MASK 1023 +static long INVSQ_LOOKUP_I[64+1]={ + 92682l, 91966l, 91267l, 90583l, + 89915l, 89261l, 88621l, 87995l, + 87381l, 86781l, 86192l, 85616l, + 85051l, 84497l, 83953l, 83420l, + 82897l, 82384l, 81880l, 81385l, + 80899l, 80422l, 79953l, 79492l, + 79039l, 78594l, 78156l, 77726l, + 77302l, 76885l, 76475l, 76072l, + 75674l, 75283l, 74898l, 74519l, + 74146l, 73778l, 73415l, 73058l, + 72706l, 72359l, 72016l, 71679l, + 71347l, 71019l, 70695l, 70376l, + 70061l, 69750l, 69444l, 69141l, + 68842l, 68548l, 68256l, 67969l, + 67685l, 67405l, 67128l, 66855l, + 66585l, 66318l, 66054l, 65794l, + 65536l, +}; + +#define COS_LOOKUP_I_SHIFT 9 +#define COS_LOOKUP_I_MASK 511 +#define COS_LOOKUP_I_SZ 128 +static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={ + 16384l, 16379l, 16364l, 16340l, + 16305l, 16261l, 16207l, 16143l, + 16069l, 15986l, 15893l, 15791l, + 15679l, 15557l, 15426l, 15286l, + 15137l, 14978l, 14811l, 14635l, + 14449l, 14256l, 14053l, 13842l, + 13623l, 13395l, 13160l, 12916l, + 12665l, 12406l, 12140l, 11866l, + 11585l, 11297l, 11003l, 10702l, + 10394l, 10080l, 9760l, 9434l, + 9102l, 8765l, 8423l, 8076l, + 7723l, 7366l, 7005l, 6639l, + 6270l, 5897l, 5520l, 5139l, + 4756l, 4370l, 3981l, 3590l, + 3196l, 2801l, 2404l, 2006l, + 1606l, 1205l, 804l, 402l, + 0l, -401l, -803l, -1204l, + -1605l, -2005l, -2403l, -2800l, + -3195l, -3589l, -3980l, -4369l, + -4755l, -5138l, -5519l, -5896l, + -6269l, -6638l, -7004l, -7365l, + -7722l, -8075l, -8422l, -8764l, + -9101l, -9433l, -9759l, -10079l, + -10393l, -10701l, -11002l, -11296l, + -11584l, -11865l, -12139l, -12405l, + -12664l, -12915l, -13159l, -13394l, + -13622l, -13841l, -14052l, -14255l, + -14448l, -14634l, -14810l, -14977l, + -15136l, -15285l, -15425l, -15556l, + -15678l, -15790l, -15892l, -15985l, + -16068l, -16142l, -16206l, -16260l, + -16304l, -16339l, -16363l, -16378l, + -16383l, +}; + +#endif + +#endif diff --git a/sound/OggVorbis/vorbissrc/lookups.pl b/sound/OggVorbis/vorbissrc/lookups.pl new file mode 100644 index 000000000..f8d2a5051 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/lookups.pl @@ -0,0 +1,142 @@ +#!/usr/bin/perl +print <<'EOD'; +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup data; generated by lookups.pl; edit there + last mod: $Id: lookups.pl,v 1.7 2002/07/11 06:40:49 xiphmont Exp $ + + ********************************************************************/ + +#ifndef _V_LOOKUP_DATA_H_ + +#ifdef FLOAT_LOOKUP +EOD + +$cos_sz=128; +$invsq_sz=32; +$invsq2exp_min=-32; +$invsq2exp_max=32; + +$fromdB_sz=35; +$fromdB_shift=5; +$fromdB2_shift=3; + +$invsq_i_shift=10; +$cos_i_shift=9; +$delta_shift=6; + +print "#define COS_LOOKUP_SZ $cos_sz\n"; +print "static float COS_LOOKUP[COS_LOOKUP_SZ+1]={\n"; + +for($i=0;$i<=$cos_sz;){ + print "\t"; + for($j=0;$j<4 && $i<=$cos_sz;$j++){ + printf "%+.13f,", cos(3.14159265358979323846*($i++)/$cos_sz) ; + } + print "\n"; +} +print "};\n\n"; + +print "#define INVSQ_LOOKUP_SZ $invsq_sz\n"; +print "static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={\n"; + +for($i=0;$i<=$invsq_sz;){ + print "\t"; + for($j=0;$j<4 && $i<=$invsq_sz;$j++){ + my$indexmap=$i++/$invsq_sz*.5+.5; + printf "%.12f,", 1./sqrt($indexmap); + } + print "\n"; +} +print "};\n\n"; + +print "#define INVSQ2EXP_LOOKUP_MIN $invsq2exp_min\n"; +print "#define INVSQ2EXP_LOOKUP_MAX $invsq2exp_max\n"; +print "static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\\\n". + " INVSQ2EXP_LOOKUP_MIN+1]={\n"; + +for($i=$invsq2exp_min;$i<=$invsq2exp_max;){ + print "\t"; + for($j=0;$j<4 && $i<=$invsq2exp_max;$j++){ + printf "%15.10g,", 2**($i++*-.5); + } + print "\n"; +} +print "};\n\n#endif\n\n"; + + +# 0 to -140 dB +$fromdB2_sz=1<<$fromdB_shift; +$fromdB_gran=1<<($fromdB_shift-$fromdB2_shift); +print "#define FROMdB_LOOKUP_SZ $fromdB_sz\n"; +print "#define FROMdB2_LOOKUP_SZ $fromdB2_sz\n"; +print "#define FROMdB_SHIFT $fromdB_shift\n"; +print "#define FROMdB2_SHIFT $fromdB2_shift\n"; +print "#define FROMdB2_MASK ".((1<<$fromdB_shift)-1)."\n"; + +print "static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={\n"; + +for($i=0;$i<$fromdB_sz;){ + print "\t"; + for($j=0;$j<4 && $i<$fromdB_sz;$j++){ + printf "%15.10g,", 10**(.05*(-$fromdB_gran*$i++)); + } + print "\n"; +} +print "};\n\n"; + +print "static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={\n"; + +for($i=0;$i<$fromdB2_sz;){ + print "\t"; + for($j=0;$j<4 && $i<$fromdB_sz;$j++){ + printf "%15.10g,", 10**(.05*(-$fromdB_gran/$fromdB2_sz*(.5+$i++))); + } + print "\n"; +} +print "};\n\n#ifdef INT_LOOKUP\n\n"; + + +$iisz=0x10000>>$invsq_i_shift; +print "#define INVSQ_LOOKUP_I_SHIFT $invsq_i_shift\n"; +print "#define INVSQ_LOOKUP_I_MASK ".(0x0ffff>>(16-$invsq_i_shift))."\n"; +print "static long INVSQ_LOOKUP_I[$iisz+1]={\n"; +for($i=0;$i<=$iisz;){ + print "\t"; + for($j=0;$j<4 && $i<=$iisz;$j++){ + my$indexmap=$i++/$iisz*.5+.5; + printf "%8d,", int(1./sqrt($indexmap)*65536.+.5); + } + print "\n"; +} +print "};\n\n"; + +$cisz=0x10000>>$cos_i_shift; +print "#define COS_LOOKUP_I_SHIFT $cos_i_shift\n"; +print "#define COS_LOOKUP_I_MASK ".(0x0ffff>>(16-$cos_i_shift))."\n"; +print "#define COS_LOOKUP_I_SZ $cisz\n"; +print "static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={\n"; + +for($i=0;$i<=$cisz;){ + print "\t"; + for($j=0;$j<4 && $i<=$cisz;$j++){ + printf "%8d,", int(cos(3.14159265358979323846*($i++)/$cos_sz)*16384.+.5) ; + } + print "\n"; +} +print "};\n\n"; + + +print "#endif\n\n#endif\n"; + + diff --git a/sound/OggVorbis/vorbissrc/lpc.c b/sound/OggVorbis/vorbissrc/lpc.c new file mode 100644 index 000000000..7fabe84fa --- /dev/null +++ b/sound/OggVorbis/vorbissrc/lpc.c @@ -0,0 +1,149 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: LPC low level routines + last mod: $Id: lpc.c,v 1.37 2003/03/08 07:15:32 xiphmont Exp $ + + ********************************************************************/ + +/* Some of these routines (autocorrelator, LPC coefficient estimator) + are derived from code written by Jutta Degener and Carsten Bormann; + thus we include their copyright below. The entirety of this file + is freely redistributable on the condition that both of these + copyright notices are preserved without modification. */ + +/* Preserved Copyright: *********************************************/ + +/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universita"t Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universita"t +Berlin are deemed to have made any representations as to the +suitability of this software for any purpose nor are held responsible +for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR +THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann + +*********************************************************************/ + +#include +#include +#include +#include "os.h" +#include "smallft.h" +#include "lpc.h" +#include "scales.h" +#include "misc.h" + +/* Autocorrelation LPC coeff generation algorithm invented by + N. Levinson in 1947, modified by J. Durbin in 1959. */ + +/* Input : n elements of time doamin data + Output: m lpc coefficients, excitation energy */ + +float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ + double *aut=alloca(sizeof(*aut)*(m+1)); + double *lpc=alloca(sizeof(*lpc)*(m)); + double error; + int i,j; + + /* autocorrelation, p+1 lag coefficients */ + j=m+1; + while(j--){ + double d=0; /* double needed for accumulator depth */ + for(i=j;i +#include +#include +#include "lsp.h" +#include "os.h" +#include "misc.h" +#include "lookup.h" +#include "scales.h" + +/* three possible LSP to f curve functions; the exact computation + (float), a lookup based float implementation, and an integer + implementation. The float lookup is likely the optimal choice on + any machine with an FPU. The integer implementation is *not* fixed + point (due to the need for a large dynamic range and thus a + seperately tracked exponent) and thus much more complex than the + relatively simple float implementations. It's mostly for future + work on a fully fixed point implementation for processors like the + ARM family. */ + +/* undefine both for the 'old' but more precise implementation */ +#define FLOAT_LOOKUP +#undef INT_LOOKUP + +#ifdef FLOAT_LOOKUP +#include "lookup.c" /* catch this in the build system; we #include for + compilers (like gcc) that can't inline across + modules */ + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + int i; + float wdel=M_PI/ln; + vorbis_fpu_control fpu; + + vorbis_fpu_setround(&fpu); + for(i=0;i>1; + + do{ + q*=ftmp[0]-w; + p*=ftmp[1]-w; + ftmp+=2; + }while(--c); + + if(m&1){ + /* odd order filter; slightly assymetric */ + /* the last coefficient */ + q*=ftmp[0]-w; + q*=q; + p*=p*(1.f-w*w); + }else{ + /* even order filter; still symmetric */ + q*=q*(1.f+w); + p*=p*(1.f-w); + } + + q=frexp(p+q,&qexp); + q=vorbis_fromdBlook(amp* + vorbis_invsqlook(q)* + vorbis_invsq2explook(qexp+m)- + ampoffset); + + do{ + curve[i++]*=q; + }while(map[i]==k); + } + vorbis_fpu_restore(fpu); +} + +#else + +#ifdef INT_LOOKUP +#include "lookup.c" /* catch this in the build system; we #include for + compilers (like gcc) that can't inline across + modules */ + +static int MLOOP_1[64]={ + 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13, + 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, +}; + +static int MLOOP_2[64]={ + 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7, + 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8, + 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, + 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, +}; + +static int MLOOP_3[8]={0,1,2,2,3,3,3,3}; + + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + + /* 0 <= m < 256 */ + + /* set up for using all int later */ + int i; + int ampoffseti=rint(ampoffset*4096.f); + int ampi=rint(amp*16.f); + long *ilsp=alloca(m*sizeof(*ilsp)); + for(i=0;i>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)*labs(ilsp[j]-wi); + qexp+=shift; + } + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + /* pi,qi normalized collectively, both tracked using qexp */ + + if(m&1){ + /* odd order filter; slightly assymetric */ + /* the last coefficient */ + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)<<14; + qexp+=shift; + + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + pi>>=shift; + qi>>=shift; + qexp+=shift-14*((m+1)>>1); + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-((wi*wi)>>14); + qi+=pi>>14; + + }else{ + /* even order filter; still symmetric */ + + /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't + worth tracking step by step */ + + pi>>=shift; + qi>>=shift; + qexp+=shift-7*m; + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-wi; + qi*=(1<<14)+wi; + qi=(qi+pi)>>14; + + } + + + /* we've let the normalization drift because it wasn't important; + however, for the lookup, things must be normalized again. We + need at most one right shift or a number of left shifts */ + + if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ + qi>>=1; qexp++; + }else + while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/ + qi<<=1; qexp--; + } + + amp=vorbis_fromdBlook_i(ampi* /* n.4 */ + vorbis_invsqlook_i(qi,qexp)- + /* m.8, m+n<=8 */ + ampoffseti); /* 8.12[0] */ + + curve[i]*=amp; + while(map[++i]==k)curve[i]*=amp; + } +} + +#else + +/* old, nonoptimized but simple version for any poor sap who needs to + figure out what the hell this code does, or wants the other + fraction of a dB precision */ + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + int i; + float wdel=M_PI/ln; + for(i=0;i= i; j--) { + g[j-2] -= g[j]; + g[j] += g[j]; + } + } +} + +static int comp(const void *a,const void *b){ + return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b); +} + +/* Newton-Raphson-Maehly actually functioned as a decent root finder, + but there are root sets for which it gets into limit cycles + (exacerbated by zero suppression) and fails. We can't afford to + fail, even if the failure is 1 in 100,000,000, so we now use + Laguerre and later polish with Newton-Raphson (which can then + afford to fail) */ + +#define EPSILON 10e-7 +static int Laguerre_With_Deflation(float *a,int ord,float *r){ + int i,m; + double lastdelta=0.f; + double *defl=alloca(sizeof(*defl)*(ord+1)); + for(i=0;i<=ord;i++)defl[i]=a[i]; + + for(m=ord;m>0;m--){ + double new=0.f,delta; + + /* iterate a root */ + while(1){ + double p=defl[m],pp=0.f,ppp=0.f,denom; + + /* eval the polynomial and its first two derivatives */ + for(i=m;i>0;i--){ + ppp = new*ppp + pp; + pp = new*pp + p; + p = new*p + defl[i-1]; + } + + /* Laguerre's method */ + denom=(m-1) * ((m-1)*pp*pp - m*p*ppp); + if(denom<0) + return(-1); /* complex root! The LPC generator handed us a bad filter */ + + if(pp>0){ + denom = pp + sqrt(denom); + if(denom-(EPSILON))denom=-(EPSILON); + } + + delta = m*p/denom; + new -= delta; + + if(delta<0.f)delta*=-1; + + if(fabs(delta/new)<10e-12)break; + lastdelta=delta; + } + + r[m-1]=new; + + /* forward deflation */ + + for(i=m;i>0;i--) + defl[i-1]+=new*defl[i]; + defl++; + + } + return(0); +} + + +/* for spit-and-polish only */ +static int Newton_Raphson(float *a,int ord,float *r){ + int i, k, count=0; + double error=1.f; + double *root=alloca(ord*sizeof(*root)); + + for(i=0; i1e-20){ + error=0; + + for(i=0; i= 0; k--) { + + pp= pp* rooti + p; + p = p * rooti + a[k]; + } + + delta = p/pp; + root[i] -= delta; + error+= delta*delta; + } + + if(count>40)return(-1); + + count++; + } + + /* Replaced the original bubble sort with a real sort. With your + help, we can eliminate the bubble sort in our lifetime. --Monty */ + + for(i=0; i>1; + int g1_order,g2_order; + float *g1=alloca(sizeof(*g1)*(order2+1)); + float *g2=alloca(sizeof(*g2)*(order2+1)); + float *g1r=alloca(sizeof(*g1r)*(order2+1)); + float *g2r=alloca(sizeof(*g2r)*(order2+1)); + int i; + + /* even and odd are slightly different base cases */ + g1_order=(m+1)>>1; + g2_order=(m) >>1; + + /* Compute the lengths of the x polynomials. */ + /* Compute the first half of K & R F1 & F2 polynomials. */ + /* Compute half of the symmetric and antisymmetric polynomials. */ + /* Remove the roots at +1 and -1. */ + + g1[g1_order] = 1.f; + for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i]; + g2[g2_order] = 1.f; + for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i]; + + if(g1_order>g2_order){ + for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2]; + }else{ + for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1]; + for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1]; + } + + /* Convert into polynomials in cos(alpha) */ + cheby(g1,g1_order); + cheby(g2,g2_order); + + /* Find the roots of the 2 even polynomials.*/ + if(Laguerre_With_Deflation(g1,g1_order,g1r) || + Laguerre_With_Deflation(g2,g2_order,g2r)) + return(-1); + + Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */ + Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */ + + qsort(g1r,g1_order,sizeof(*g1r),comp); + qsort(g2r,g2_order,sizeof(*g2r),comp); + + for(i=0;i +#include +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "codebook.h" +#include "window.h" +#include "registry.h" +#include "psy.h" +#include "misc.h" + +/* simplistic, wasteful way of doing this (unique lookup for each + mode/submapping); there should be a central repository for + identical lookups. That will require minor work, so I'm putting it + off as low priority. + + Why a lookup for each backend in a given mode? Because the + blocksize is set by the mode, and low backend lookups may require + parameters from other areas of the mode/mapping */ + +static void mapping0_free_info(vorbis_info_mapping *i){ + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static int ilog(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, + oggpack_buffer *opb){ + int i; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm; + + /* another 'we meant to do it this way' hack... up to beta 4, we + packed 4 binary zeros here to signify one submapping in use. We + now redefine that to mean four bitflags that indicate use of + deeper features; bit0:submappings, bit1:coupling, + bit2,3:reserved. This is backward compatable with all actual uses + of the beta code. */ + + if(info->submaps>1){ + oggpack_write(opb,1,1); + oggpack_write(opb,info->submaps-1,4); + }else + oggpack_write(opb,0,1); + + if(info->coupling_steps>0){ + oggpack_write(opb,1,1); + oggpack_write(opb,info->coupling_steps-1,8); + + for(i=0;icoupling_steps;i++){ + oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels)); + oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels)); + } + }else + oggpack_write(opb,0,1); + + oggpack_write(opb,0,2); /* 2,3:reserved */ + + /* we don't write the channel submappings if we only have one... */ + if(info->submaps>1){ + for(i=0;ichannels;i++) + oggpack_write(opb,info->chmuxlist[i],4); + } + for(i=0;isubmaps;i++){ + oggpack_write(opb,0,8); /* time submap unused */ + oggpack_write(opb,info->floorsubmap[i],8); + oggpack_write(opb,info->residuesubmap[i],8); + } +} + +/* also responsible for range checking */ +static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int i; + vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=vi->codec_setup; + memset(info,0,sizeof(*info)); + + if(oggpack_read(opb,1)) + info->submaps=oggpack_read(opb,4)+1; + else + info->submaps=1; + + if(oggpack_read(opb,1)){ + info->coupling_steps=oggpack_read(opb,8)+1; + + for(i=0;icoupling_steps;i++){ + int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); + int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); + + if(testM<0 || + testA<0 || + testM==testA || + testM>=vi->channels || + testA>=vi->channels) goto err_out; + } + + } + + if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ + + if(info->submaps>1){ + for(i=0;ichannels;i++){ + info->chmuxlist[i]=oggpack_read(opb,4); + if(info->chmuxlist[i]>=info->submaps)goto err_out; + } + } + for(i=0;isubmaps;i++){ + oggpack_read(opb,8); /* time submap unused */ + info->floorsubmap[i]=oggpack_read(opb,8); + if(info->floorsubmap[i]>=ci->floors)goto err_out; + info->residuesubmap[i]=oggpack_read(opb,8); + if(info->residuesubmap[i]>=ci->residues)goto err_out; + } + + return info; + + err_out: + mapping0_free_info(info); + return(NULL); +} + +#include "os.h" +#include "lpc.h" +#include "lsp.h" +#include "envelope.h" +#include "mdct.h" +#include "psy.h" +#include "scales.h" + +#if 0 +static long seq=0; +static ogg_int64_t total=0; +static float FLOOR1_fromdB_LOOKUP[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +#endif + +extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor *look, + const float *logmdct, /* in */ + const float *logmask); +extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor *look, + int *A,int *B, + int del); +extern int floor1_encode(vorbis_block *vb,vorbis_look_floor *look, + int *post,int *ilogmask); + + +static int mapping0_forward(vorbis_block *vb){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=vb->vd->backend_state; + vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; + int n=vb->pcmend; + int i,j,k; + + int *nonzero = alloca(sizeof(*nonzero)*vi->channels); + float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); + int **ilogmaskch= _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch)); + int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); + + float global_ampmax=vbi->ampmax; + float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels); + int blocktype=vbi->blocktype; + + int modenumber=vb->W; + vorbis_info_mapping0 *info=ci->map_param[modenumber]; + vorbis_look_psy *psy_look= + b->psy+blocktype+(vb->W?2:0); + + vb->mode=modenumber; + + for(i=0;ichannels;i++){ + float scale=4.f/n; + float scale_dB; + + float *pcm =vb->pcm[i]; + float *logfft =pcm; + + gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); + + scale_dB=todB(&scale); + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2); + else + _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2); +#endif + + /* window the PCM data */ + _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2); + else + _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2); +#endif + + /* transform the PCM data */ + /* only MDCT right now.... */ + mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]); + + /* FFT yields more accurate tonal estimation (not phase sensitive) */ + drft_forward(&b->fft_look[vb->W],pcm); + logfft[0]=scale_dB+todB(pcm); + local_ampmax[i]=logfft[0]; + for(j=1;j>1]=scale_dB+.5f*todB(&temp); + if(temp>local_ampmax[i])local_ampmax[i]=temp; + } + + if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; + if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("fftL",seq,logfft,n/2,1,0,0); + else + _analysis_output("fftR",seq,logfft,n/2,1,0,0); +#endif + + } + + { + float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise)); + float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone)); + + for(i=0;ichannels;i++){ + /* the encoder setup assumes that all the modes used by any + specific bitrate tweaking use the same floor */ + + int submap=info->chmuxlist[i]; + + /* the following makes things clearer to *me* anyway */ + float *mdct =gmdct[i]; + float *logfft =vb->pcm[i]; + + float *logmdct =logfft+n/2; + float *logmask =logfft; + + vb->mode=modenumber; + + floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts)); + memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS); + + for(j=0;jchannels==2){ + if(i==0) + _analysis_output("mdctL",seq,logmdct,n/2,1,0,0); + else + _analysis_output("mdctR",seq,logmdct,n/2,1,0,0); + }else{ + _analysis_output("mdct",seq,logmdct,n/2,1,0,0); + } +#endif + + /* first step; noise masking. Not only does 'noise masking' + give us curves from which we can decide how much resolution + to give noise parts of the spectrum, it also implicitly hands + us a tonality estimate (the larger the value in the + 'noise_depth' vector, the more tonal that area is) */ + + _vp_noisemask(psy_look, + logmdct, + noise); /* noise does not have by-frequency offset + bias applied yet */ +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("noiseL",seq,noise,n/2,1,0,0); + else + _analysis_output("noiseR",seq,noise,n/2,1,0,0); + } +#endif + + /* second step: 'all the other crap'; all the stuff that isn't + computed/fit for bitrate management goes in the second psy + vector. This includes tone masking, peak limiting and ATH */ + + _vp_tonemask(psy_look, + logfft, + tone, + global_ampmax, + local_ampmax[i]); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("toneL",seq,tone,n/2,1,0,0); + else + _analysis_output("toneR",seq,tone,n/2,1,0,0); + } +#endif + + /* third step; we offset the noise vectors, overlay tone + masking. We then do a floor1-specific line fit. If we're + performing bitrate management, the line fit is performed + multiple times for up/down tweakage on demand. */ + + _vp_offset_and_mix(psy_look, + noise, + tone, + 1, + logmask); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("mask1L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask1R",seq,logmask,n/2,1,0,0); + } +#endif + + /* this algorithm is hardwired to floor 1 for now; abort out if + we're *not* floor1. This won't happen unless someone has + broken the encode setup lib. Guard it anyway. */ + if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); + + floor_posts[i][PACKETBLOBS/2]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* are we managing bitrate? If so, perform two more fits for + later rate tweaking (fits represent hi/lo) */ + if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ + /* higher rate by way of lower noise curve */ + + _vp_offset_and_mix(psy_look, + noise, + tone, + 2, + logmask); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("mask2L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask2R",seq,logmask,n/2,1,0,0); + } +#endif + + floor_posts[i][PACKETBLOBS-1]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* lower rate by way of higher noise curve */ + _vp_offset_and_mix(psy_look, + noise, + tone, + 0, + logmask); + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("mask0L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask0R",seq,logmask,n/2,1,0,0); +#endif + + floor_posts[i][0]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* we also interpolate a range of intermediate curves for + intermediate rates */ + for(k=1;kflr[info->floorsubmap[submap]], + floor_posts[i][0], + floor_posts[i][PACKETBLOBS/2], + k*65536/(PACKETBLOBS/2)); + for(k=PACKETBLOBS/2+1;kflr[info->floorsubmap[submap]], + floor_posts[i][PACKETBLOBS/2], + floor_posts[i][PACKETBLOBS-1], + (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); + } + } + } + vbi->ampmax=global_ampmax; + + /* + the next phases are performed once for vbr-only and PACKETBLOB + times for bitrate managed modes. + + 1) encode actual mode being used + 2) encode the floor for each channel, compute coded mask curve/res + 3) normalize and couple. + 4) encode residue + 5) save packet bytes to the packetblob vector + + */ + + /* iterate over the many masking curve fits we've created */ + + { + float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels); + float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); + int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + int **sortindex=alloca(sizeof(*sortindex)*vi->channels); + float **mag_memo; + int **mag_sort; + + if(info->coupling_steps){ + mag_memo=_vp_quantize_couple_memo(vb, + &ci->psy_g_param, + psy_look, + info, + gmdct); + + mag_sort=_vp_quantize_couple_sort(vb, + psy_look, + info, + mag_memo); + } + + memset(sortindex,0,sizeof(*sortindex)*vi->channels); + if(psy_look->vi->normal_channel_p){ + for(i=0;ichannels;i++){ + float *mdct =gmdct[i]; + sortindex[i]=alloca(sizeof(**sortindex)*n/2); + _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]); + } + } + + for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); + k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); + k++){ + + /* start out our new packet blob with packet type and mode */ + /* Encode the packet type */ + oggpack_write(&vb->opb,0,1); + /* Encode the modenumber */ + /* Encode frame mode, pre,post windowsize, then dispatch */ + oggpack_write(&vb->opb,modenumber,b->modebits); + if(vb->W){ + oggpack_write(&vb->opb,vb->lW,1); + oggpack_write(&vb->opb,vb->nW,1); + } + + /* encode floor, compute masking curve, sep out residue */ + for(i=0;ichannels;i++){ + int submap=info->chmuxlist[i]; + float *mdct =gmdct[i]; + float *res =vb->pcm[i]; + int *ilogmask=ilogmaskch[i]= + _vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); + + nonzero[i]=floor1_encode(vb,b->flr[info->floorsubmap[submap]], + floor_posts[i][k], + ilogmask); +#if 0 + { + char buf[80]; + sprintf(buf,"maskI%c%d",i?'R':'L',k); + float work[n/2]; + for(j=0;jpsy_g_param.sliding_lowpass[vb->W][k]); + + _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]); + + +#if 0 + { + char buf[80]; + float work[n/2]; + for(j=0;jcoupling_steps){ + _vp_couple(k, + &ci->psy_g_param, + psy_look, + info, + vb->pcm, + mag_memo, + mag_sort, + ilogmaskch, + nonzero, + ci->psy_g_param.sliding_lowpass[vb->W][k]); + } + + /* classify and encode by submap */ + for(i=0;isubmaps;i++){ + int ch_in_bundle=0; + long **classifications; + int resnum=info->residuesubmap[i]; + + for(j=0;jchannels;j++){ + if(info->chmuxlist[j]==i){ + zerobundle[ch_in_bundle]=0; + if(nonzero[j])zerobundle[ch_in_bundle]=1; + res_bundle[ch_in_bundle]=vb->pcm[j]; + couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2; + } + } + + classifications=_residue_P[ci->residue_type[resnum]]-> + class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); + + _residue_P[ci->residue_type[resnum]]-> + forward(vb,b->residue[resnum], + couple_bundle,NULL,zerobundle,ch_in_bundle,classifications); + } + + /* ok, done encoding. Mark this protopacket and prepare next. */ + oggpack_writealign(&vb->opb); + vbi->packetblob_markers[k]=oggpack_bytes(&vb->opb); + + } + + } + +#if 0 + seq++; + total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; +#endif + return(0); +} + +static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=vd->backend_state; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l; + int hs=ci->halfrate_flag; + + int i,j; + long n=vb->pcmend=ci->blocksizes[vb->W]; + + float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); + int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + + int *nonzero =alloca(sizeof(*nonzero)*vi->channels); + void **floormemo=alloca(sizeof(*floormemo)*vi->channels); + + /* recover the spectral envelope; store it in the PCM vector for now */ + for(i=0;ichannels;i++){ + int submap=info->chmuxlist[i]; + floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]-> + inverse1(vb,b->flr[info->floorsubmap[submap]]); + if(floormemo[i]) + nonzero[i]=1; + else + nonzero[i]=0; + memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); + } + + /* channel coupling can 'dirty' the nonzero listing */ + for(i=0;icoupling_steps;i++){ + if(nonzero[info->coupling_mag[i]] || + nonzero[info->coupling_ang[i]]){ + nonzero[info->coupling_mag[i]]=1; + nonzero[info->coupling_ang[i]]=1; + } + } + + /* recover the residue into our working vectors */ + for(i=0;isubmaps;i++){ + int ch_in_bundle=0; + for(j=0;jchannels;j++){ + if(info->chmuxlist[j]==i){ + if(nonzero[j]) + zerobundle[ch_in_bundle]=1; + else + zerobundle[ch_in_bundle]=0; + pcmbundle[ch_in_bundle++]=vb->pcm[j]; + } + } + + _residue_P[ci->residue_type[info->residuesubmap[i]]]-> + inverse(vb,b->residue[info->residuesubmap[i]], + pcmbundle,zerobundle,ch_in_bundle); + } + + /* channel coupling */ + for(i=info->coupling_steps-1;i>=0;i--){ + float *pcmM=vb->pcm[info->coupling_mag[i]]; + float *pcmA=vb->pcm[info->coupling_ang[i]]; + + for(j=0;j0) + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag-ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag+ang; + } + else + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag+ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag-ang; + } + } + } + + /* compute and apply spectral envelope */ + for(i=0;ichannels;i++){ + float *pcm=vb->pcm[i]; + int submap=info->chmuxlist[i]; + _floor_P[ci->floor_type[info->floorsubmap[submap]]]-> + inverse2(vb,b->flr[info->floorsubmap[submap]], + floormemo[i],pcm); + } + + /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ + /* only MDCT right now.... */ + for(i=0;ichannels;i++){ + float *pcm=vb->pcm[i]; + mdct_backward(b->transform[vb->W][0],pcm,pcm); + } + + /* all done! */ + return(0); +} + +/* export hooks */ +vorbis_func_mapping mapping0_exportbundle={ + &mapping0_pack, + &mapping0_unpack, + &mapping0_free_info, + &mapping0_forward, + &mapping0_inverse +}; + diff --git a/sound/OggVorbis/vorbissrc/masking.h b/sound/OggVorbis/vorbissrc/masking.h new file mode 100644 index 000000000..ad64e5bd9 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/masking.h @@ -0,0 +1,785 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: masking curve data for psychoacoustics + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_MASKING_H_ +#define _V_MASKING_H_ + +/* more detailed ATH; the bass if flat to save stressing the floor + overly for only a bin or two of savings. */ + +#define MAX_ATH 88 +static float ATH[]={ + /*15*/ -51, -52, -53, -54, -55, -56, -57, -58, + /*31*/ -59, -60, -61, -62, -63, -64, -65, -66, + /*63*/ -67, -68, -69, -70, -71, -72, -73, -74, + /*125*/ -75, -76, -77, -78, -80, -81, -82, -83, + /*250*/ -84, -85, -86, -87, -88, -88, -89, -89, + /*500*/ -90, -91, -91, -92, -93, -94, -95, -96, + /*1k*/ -96, -97, -98, -98, -99, -99,-100,-100, + /*2k*/ -101,-102,-103,-104,-106,-107,-107,-107, + /*4k*/ -107,-105,-103,-102,-101, -99, -98, -96, + /*8k*/ -95, -95, -96, -97, -96, -95, -93, -90, + /*16k*/ -80, -70, -50, -40, -30, -30, -30, -30 +}; + +/* The tone masking curves from Ehmer's and Fielder's papers have been + replaced by an empirically collected data set. The previously + published values were, far too often, simply on crack. */ + +#define EHMER_OFFSET 16 +#define EHMER_MAX 56 + +/* masking tones from -50 to 0dB, 62.5 through 16kHz at half octaves + test tones from -2 octaves to +5 octaves sampled at eighth octaves */ +/* (Vorbis 0dB, the loudest possible tone, is assumed to be ~100dB SPL + for collection of these curves) */ + +static float tonemasks[P_BANDS][6][EHMER_MAX]={ + /* 62.5 Hz */ + {{ -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -62, -62, -65, -73, + -69, -68, -68, -67, -70, -70, -72, -74, + -75, -79, -79, -80, -83, -88, -93, -100, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -53, -61, -66, + -66, -68, -67, -70, -76, -76, -72, -73, + -75, -76, -78, -79, -83, -88, -93, -100, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -37, -37, -37, -37, -37, -37, -37, -37, + -38, -40, -42, -46, -48, -53, -55, -62, + -65, -58, -56, -56, -61, -60, -65, -67, + -69, -71, -77, -77, -78, -80, -82, -84, + -88, -93, -98, -106, -112, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -25, -25, -25, -25, -25, -25, -25, -25, + -25, -26, -27, -29, -32, -38, -48, -52, + -52, -50, -48, -48, -51, -52, -54, -60, + -67, -67, -66, -68, -69, -73, -73, -76, + -80, -81, -81, -85, -85, -86, -88, -93, + -100, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -16, -16, -16, -16, -16, -16, -16, -16, + -17, -19, -20, -22, -26, -28, -31, -40, + -47, -39, -39, -40, -42, -43, -47, -51, + -57, -52, -55, -55, -60, -58, -62, -63, + -70, -67, -69, -72, -73, -77, -80, -82, + -83, -87, -90, -94, -98, -104, -115, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -10, -11, -15, -19, -25, -30, + -34, -31, -30, -31, -29, -32, -35, -42, + -48, -42, -44, -46, -50, -50, -51, -52, + -59, -54, -55, -55, -58, -62, -63, -66, + -72, -73, -76, -75, -78, -80, -80, -81, + -84, -88, -90, -94, -98, -101, -106, -110}}, + /* 88Hz */ + {{ -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -67, -67, -67, + -76, -72, -71, -74, -76, -76, -75, -78, + -79, -79, -81, -83, -86, -89, -93, -97, + -100, -105, -110, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -48, -51, -55, -59, -66, + -66, -66, -67, -66, -68, -69, -70, -74, + -79, -77, -77, -78, -80, -81, -82, -84, + -86, -88, -91, -95, -100, -108, -116, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -36, -36, -36, -36, -36, -36, -36, -36, + -36, -37, -37, -41, -44, -48, -51, -58, + -62, -60, -57, -59, -59, -60, -63, -65, + -72, -71, -70, -72, -74, -77, -76, -78, + -81, -81, -80, -83, -86, -91, -96, -100, + -105, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -28, -28, -28, -28, -28, -28, -28, -28, + -28, -30, -32, -32, -33, -35, -41, -49, + -50, -49, -47, -48, -48, -52, -51, -57, + -65, -61, -59, -61, -64, -69, -70, -74, + -77, -77, -78, -81, -84, -85, -87, -90, + -92, -96, -100, -107, -112, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -19, -19, -19, -19, -19, -19, -19, -19, + -20, -21, -23, -27, -30, -35, -36, -41, + -46, -44, -42, -40, -41, -41, -43, -48, + -55, -53, -52, -53, -56, -59, -58, -60, + -67, -66, -69, -71, -72, -75, -79, -81, + -84, -87, -90, -93, -97, -101, -107, -114, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -9, -9, -9, -9, -9, -9, -9, -9, + -11, -12, -12, -15, -16, -20, -23, -30, + -37, -34, -33, -34, -31, -32, -32, -38, + -47, -44, -41, -40, -47, -49, -46, -46, + -58, -50, -50, -54, -58, -62, -64, -67, + -67, -70, -72, -76, -79, -83, -87, -91, + -96, -100, -104, -110, -999, -999, -999, -999}}, + /* 125 Hz */ + {{ -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -63, -64, -66, -67, -66, -68, + -75, -72, -76, -75, -76, -78, -79, -82, + -84, -85, -90, -94, -101, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -60, -60, -61, -63, -66, + -71, -68, -70, -70, -71, -72, -72, -75, + -81, -78, -79, -82, -83, -86, -90, -97, + -103, -113, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -53, -53, -53, -53, -53, -53, -53, -53, + -53, -54, -55, -57, -56, -57, -55, -61, + -65, -60, -60, -62, -63, -63, -66, -68, + -74, -73, -75, -75, -78, -80, -80, -82, + -85, -90, -96, -101, -108, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -47, -47, -47, -47, -48, -51, + -57, -51, -49, -50, -51, -53, -54, -59, + -66, -60, -62, -67, -67, -70, -72, -75, + -76, -78, -81, -85, -88, -94, -97, -104, + -112, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -36, -36, -36, -36, -36, -36, -36, -36, + -39, -41, -42, -42, -39, -38, -41, -43, + -52, -44, -40, -39, -37, -37, -40, -47, + -54, -50, -48, -50, -55, -61, -59, -62, + -66, -66, -66, -69, -69, -73, -74, -74, + -75, -77, -79, -82, -87, -91, -95, -100, + -108, -115, -999, -999, -999, -999, -999, -999}, + { -28, -26, -24, -22, -20, -20, -23, -29, + -30, -31, -28, -27, -28, -28, -28, -35, + -40, -33, -32, -29, -30, -30, -30, -37, + -45, -41, -37, -38, -45, -47, -47, -48, + -53, -49, -48, -50, -49, -49, -51, -52, + -58, -56, -57, -56, -60, -61, -62, -70, + -72, -74, -78, -83, -88, -93, -100, -106}}, + /* 177 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -110, -105, -100, -95, -91, -87, -83, + -80, -78, -76, -78, -78, -81, -83, -85, + -86, -85, -86, -87, -90, -97, -107, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -110, -105, -100, -95, -90, + -85, -81, -77, -73, -70, -67, -67, -68, + -75, -73, -70, -69, -70, -72, -75, -79, + -84, -83, -84, -86, -88, -89, -89, -93, + -98, -105, -112, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-105, -100, -95, -90, -85, -80, -76, -71, + -68, -68, -65, -63, -63, -62, -62, -64, + -65, -64, -61, -62, -63, -64, -66, -68, + -73, -73, -74, -75, -76, -81, -83, -85, + -88, -89, -92, -95, -100, -108, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -80, -75, -71, -68, -65, -63, -62, -61, + -61, -61, -61, -59, -56, -57, -53, -50, + -58, -52, -50, -50, -52, -53, -54, -58, + -67, -63, -67, -68, -72, -75, -78, -80, + -81, -81, -82, -85, -89, -90, -93, -97, + -101, -107, -114, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -65, -61, -59, -57, -56, -55, -55, -56, + -56, -57, -55, -53, -52, -47, -44, -44, + -50, -44, -41, -39, -39, -42, -40, -46, + -51, -49, -50, -53, -54, -63, -60, -61, + -62, -66, -66, -66, -70, -73, -74, -75, + -76, -75, -79, -85, -89, -91, -96, -102, + -110, -999, -999, -999, -999, -999, -999, -999}, + { -52, -50, -49, -49, -48, -48, -48, -49, + -50, -50, -49, -46, -43, -39, -35, -33, + -38, -36, -32, -29, -32, -32, -32, -35, + -44, -39, -38, -38, -46, -50, -45, -46, + -53, -50, -50, -50, -54, -54, -53, -53, + -56, -57, -59, -66, -70, -72, -74, -79, + -83, -85, -90, -97, -114, -999, -999, -999}}, + /* 250 Hz */ + {{-999, -999, -999, -999, -999, -999, -110, -105, + -100, -95, -90, -86, -80, -75, -75, -79, + -80, -79, -80, -81, -82, -88, -95, -103, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -108, -103, -98, -93, + -88, -83, -79, -78, -75, -71, -67, -68, + -73, -73, -72, -73, -75, -77, -80, -82, + -88, -93, -100, -107, -114, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -110, -105, -101, -96, -90, + -86, -81, -77, -73, -69, -66, -61, -62, + -66, -64, -62, -65, -66, -70, -72, -76, + -81, -80, -84, -90, -95, -102, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -107, -103, -97, -92, -88, + -83, -79, -74, -70, -66, -59, -53, -58, + -62, -55, -54, -54, -54, -58, -61, -62, + -72, -70, -72, -75, -78, -80, -81, -80, + -83, -83, -88, -93, -100, -107, -115, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -105, -100, -95, -90, -85, + -80, -75, -70, -66, -62, -56, -48, -44, + -48, -46, -46, -43, -46, -48, -48, -51, + -58, -58, -59, -60, -62, -62, -61, -61, + -65, -64, -65, -68, -70, -74, -75, -78, + -81, -86, -95, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -105, -100, -95, -90, -85, -80, + -75, -70, -65, -61, -55, -49, -39, -33, + -40, -35, -32, -38, -40, -33, -35, -37, + -46, -41, -45, -44, -46, -42, -45, -46, + -52, -50, -50, -50, -54, -54, -55, -57, + -62, -64, -66, -68, -70, -76, -81, -90, + -100, -110, -999, -999, -999, -999, -999, -999}}, + /* 354 hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -85, -82, -83, -80, -78, + -84, -79, -80, -83, -87, -89, -91, -93, + -99, -106, -117, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -85, -80, -75, -70, -68, + -74, -72, -74, -77, -80, -82, -85, -87, + -92, -89, -91, -95, -100, -106, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -83, -75, -71, -63, -64, + -67, -62, -64, -67, -70, -73, -77, -81, + -84, -83, -85, -89, -90, -93, -98, -104, + -109, -114, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -103, -96, -88, -81, -75, -68, -58, -54, + -56, -54, -56, -56, -58, -60, -63, -66, + -74, -69, -72, -72, -75, -74, -77, -81, + -81, -82, -84, -87, -93, -96, -99, -104, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -108, -102, -96, + -91, -85, -80, -74, -68, -60, -51, -46, + -48, -46, -43, -45, -47, -47, -49, -48, + -56, -53, -55, -58, -57, -63, -58, -60, + -66, -64, -67, -70, -70, -74, -77, -84, + -86, -89, -91, -93, -94, -101, -109, -118, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -108, -103, -98, -93, -88, + -83, -78, -73, -68, -60, -53, -44, -35, + -38, -38, -34, -34, -36, -40, -41, -44, + -51, -45, -46, -47, -46, -54, -50, -49, + -50, -50, -50, -51, -54, -57, -58, -60, + -66, -66, -66, -64, -65, -68, -77, -82, + -87, -95, -110, -999, -999, -999, -999, -999}}, + /* 500 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -107, -102, -97, -92, -87, -83, -78, -75, + -82, -79, -83, -85, -89, -92, -95, -98, + -101, -105, -109, -113, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -106, + -100, -95, -90, -86, -81, -78, -74, -69, + -74, -74, -76, -79, -83, -84, -86, -89, + -92, -97, -93, -100, -103, -107, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -100, + -95, -90, -87, -83, -80, -75, -69, -60, + -66, -66, -68, -70, -74, -78, -79, -81, + -81, -83, -84, -87, -93, -96, -99, -103, + -107, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -108, -103, -98, + -93, -89, -85, -82, -78, -71, -62, -55, + -58, -58, -54, -54, -55, -59, -61, -62, + -70, -66, -66, -67, -70, -72, -75, -78, + -84, -84, -84, -88, -91, -90, -95, -98, + -102, -103, -106, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -108, -103, -98, -94, + -90, -87, -82, -79, -73, -67, -58, -47, + -50, -45, -41, -45, -48, -44, -44, -49, + -54, -51, -48, -47, -49, -50, -51, -57, + -58, -60, -63, -69, -70, -69, -71, -74, + -78, -82, -90, -95, -101, -105, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -105, -101, -97, -93, -90, + -85, -80, -77, -72, -65, -56, -48, -37, + -40, -36, -34, -40, -50, -47, -38, -41, + -47, -38, -35, -39, -38, -43, -40, -45, + -50, -45, -44, -47, -50, -55, -48, -48, + -52, -66, -70, -76, -82, -90, -97, -105, + -110, -999, -999, -999, -999, -999, -999, -999}}, + /* 707 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -108, -103, -98, -93, -86, -79, -76, + -83, -81, -85, -87, -89, -93, -98, -102, + -107, -112, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -108, -103, -98, -93, -86, -79, -71, + -77, -74, -77, -79, -81, -84, -85, -90, + -92, -93, -92, -98, -101, -108, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -108, -103, -98, -93, -87, -78, -68, -65, + -66, -62, -65, -67, -70, -73, -75, -78, + -82, -82, -83, -84, -91, -93, -98, -102, + -106, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -100, -95, -90, -82, -74, -62, -57, + -58, -56, -51, -52, -52, -54, -54, -58, + -66, -59, -60, -63, -66, -69, -73, -79, + -83, -84, -80, -81, -81, -82, -88, -92, + -98, -105, -113, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -102, -97, -92, -84, -79, -69, -57, -47, + -52, -47, -44, -45, -50, -52, -42, -42, + -53, -43, -43, -48, -51, -56, -55, -52, + -57, -59, -61, -62, -67, -71, -78, -83, + -86, -94, -98, -103, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -105, -100, + -95, -90, -84, -78, -70, -61, -51, -41, + -40, -38, -40, -46, -52, -51, -41, -40, + -46, -40, -38, -38, -41, -46, -41, -46, + -47, -43, -43, -45, -41, -45, -56, -67, + -68, -83, -87, -90, -95, -102, -107, -113, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 1000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -109, -105, -101, -96, -91, -84, -77, + -82, -82, -85, -89, -94, -100, -106, -110, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -106, -103, -98, -92, -85, -80, -71, + -75, -72, -76, -80, -84, -86, -89, -93, + -100, -107, -113, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -104, -101, -97, -92, -88, -84, -80, -64, + -66, -63, -64, -66, -69, -73, -77, -83, + -83, -86, -91, -98, -104, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -104, -101, -97, -92, -90, -84, -74, -57, + -58, -52, -55, -54, -50, -52, -50, -52, + -63, -62, -69, -76, -77, -78, -78, -79, + -82, -88, -94, -100, -106, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -102, + -98, -95, -90, -85, -83, -78, -70, -50, + -50, -41, -44, -49, -47, -50, -50, -44, + -55, -46, -47, -48, -48, -54, -49, -49, + -58, -62, -71, -81, -87, -92, -97, -102, + -108, -114, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -102, + -98, -95, -90, -85, -83, -78, -70, -45, + -43, -41, -47, -50, -51, -50, -49, -45, + -47, -41, -44, -41, -39, -43, -38, -37, + -40, -41, -44, -50, -58, -65, -73, -79, + -85, -92, -97, -101, -105, -109, -113, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 1414 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -107, -100, -95, -87, -81, + -85, -83, -88, -93, -100, -107, -114, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -107, -101, -95, -88, -83, -76, + -73, -72, -79, -84, -90, -95, -100, -105, + -110, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -104, -98, -92, -87, -81, -70, + -65, -62, -67, -71, -74, -80, -85, -91, + -95, -99, -103, -108, -111, -114, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -103, -97, -90, -85, -76, -60, + -56, -54, -60, -62, -61, -56, -63, -65, + -73, -74, -77, -75, -78, -81, -86, -87, + -88, -91, -94, -98, -103, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -105, + -100, -97, -92, -86, -81, -79, -70, -57, + -51, -47, -51, -58, -60, -56, -53, -50, + -58, -52, -50, -50, -53, -55, -64, -69, + -71, -85, -82, -78, -81, -85, -95, -102, + -112, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -105, + -100, -97, -92, -85, -83, -79, -72, -49, + -40, -43, -43, -54, -56, -51, -50, -40, + -43, -38, -36, -35, -37, -38, -37, -44, + -54, -60, -57, -60, -70, -75, -84, -92, + -103, -112, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 2000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -102, -95, -89, -82, + -83, -84, -90, -92, -99, -107, -113, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -107, -101, -95, -89, -83, -72, + -74, -78, -85, -88, -88, -90, -92, -98, + -105, -111, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -109, -103, -97, -93, -87, -81, -70, + -70, -67, -75, -73, -76, -79, -81, -83, + -88, -89, -97, -103, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -107, -100, -94, -88, -83, -75, -63, + -59, -59, -63, -66, -60, -62, -67, -67, + -77, -76, -81, -88, -86, -92, -96, -102, + -109, -116, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -105, -98, -92, -86, -81, -73, -56, + -52, -47, -55, -60, -58, -52, -51, -45, + -49, -50, -53, -54, -61, -71, -70, -69, + -78, -79, -87, -90, -96, -104, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -103, -96, -90, -86, -78, -70, -51, + -42, -47, -48, -55, -54, -54, -53, -42, + -35, -28, -33, -38, -37, -44, -47, -49, + -54, -63, -68, -78, -82, -89, -94, -99, + -104, -109, -114, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 2828 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -100, -90, -79, + -85, -81, -82, -82, -89, -94, -99, -103, + -109, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -105, -97, -85, -72, + -74, -70, -70, -70, -76, -85, -91, -93, + -97, -103, -109, -115, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -112, -93, -81, -68, + -62, -60, -60, -57, -63, -70, -77, -82, + -90, -93, -98, -104, -109, -113, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -113, -100, -93, -84, -63, + -58, -48, -53, -54, -52, -52, -57, -64, + -66, -76, -83, -81, -85, -85, -90, -95, + -98, -101, -103, -106, -108, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -105, -95, -86, -74, -53, + -50, -38, -43, -49, -43, -42, -39, -39, + -46, -52, -57, -56, -72, -69, -74, -81, + -87, -92, -94, -97, -99, -102, -105, -108, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -108, -99, -90, -76, -66, -45, + -43, -41, -44, -47, -43, -47, -40, -30, + -31, -31, -39, -33, -40, -41, -43, -53, + -59, -70, -73, -77, -79, -82, -84, -87, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 4000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -91, -76, + -75, -85, -93, -98, -104, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -91, -70, + -70, -75, -86, -89, -94, -98, -101, -106, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -60, + -65, -64, -74, -83, -88, -91, -95, -99, + -103, -107, -110, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -58, + -55, -49, -66, -68, -71, -78, -78, -80, + -88, -85, -89, -97, -100, -105, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -53, + -52, -41, -59, -59, -49, -58, -56, -63, + -86, -79, -90, -93, -98, -103, -107, -112, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -97, -91, -73, -45, + -40, -33, -53, -61, -49, -54, -50, -50, + -60, -52, -67, -74, -81, -92, -96, -100, + -105, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 5657 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -113, -106, -99, -92, -77, + -80, -88, -97, -106, -115, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -116, -109, -102, -95, -89, -74, + -72, -88, -87, -95, -102, -109, -116, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -116, -109, -102, -95, -89, -75, + -66, -74, -77, -78, -86, -87, -90, -96, + -105, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -115, -108, -101, -94, -88, -66, + -56, -61, -70, -65, -78, -72, -83, -84, + -93, -98, -105, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -110, -105, -95, -89, -82, -57, + -52, -52, -59, -56, -59, -58, -69, -67, + -88, -82, -82, -89, -94, -100, -108, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -110, -101, -96, -90, -83, -77, -54, + -43, -38, -50, -48, -52, -48, -42, -42, + -51, -52, -53, -59, -65, -71, -78, -85, + -95, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 8000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -120, -105, -86, -68, + -78, -79, -90, -100, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -120, -105, -86, -66, + -73, -77, -88, -96, -105, -115, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -120, -105, -92, -80, -61, + -64, -68, -80, -87, -92, -100, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -120, -104, -91, -79, -52, + -60, -54, -64, -69, -77, -80, -82, -84, + -85, -87, -88, -90, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -118, -100, -87, -77, -49, + -50, -44, -58, -61, -61, -67, -65, -62, + -62, -62, -65, -68, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -115, -98, -84, -62, -49, + -44, -38, -46, -49, -49, -46, -39, -37, + -39, -40, -42, -43, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 11314 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -74, + -77, -82, -82, -85, -90, -94, -99, -104, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -66, + -70, -81, -80, -81, -84, -88, -91, -93, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -61, + -63, -70, -71, -74, -77, -80, -83, -85, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -86, -62, + -63, -62, -62, -58, -52, -50, -50, -52, + -54, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -118, -108, -84, -53, + -50, -50, -50, -55, -47, -45, -40, -40, + -40, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -118, -100, -73, -43, + -37, -42, -43, -53, -38, -37, -35, -35, + -38, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 16000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -91, -84, -74, + -80, -80, -80, -80, -80, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -91, -84, -74, + -68, -68, -68, -68, -68, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -86, -78, -70, + -60, -45, -30, -21, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -87, -78, -67, + -48, -38, -29, -21, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -86, -69, -56, + -45, -35, -33, -29, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -83, -71, -48, + -27, -38, -37, -34, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}} +}; + +#endif diff --git a/sound/OggVorbis/vorbissrc/mdct.c b/sound/OggVorbis/vorbissrc/mdct.c new file mode 100644 index 000000000..1ea8c4d19 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/mdct.c @@ -0,0 +1,564 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: normalized modified discrete cosine transform + power of two length transform only [64 <= n ] + last mod: $Id: mdct.c,v 1.32 2002/10/16 02:43:48 xiphmont Exp $ + + Original algorithm adapted long ago from _The use of multirate filter + banks for coding of high quality digital audio_, by T. Sporer, + K. Brandenburg and B. Edler, collection of the European Signal + Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp + 211-214 + + The below code implements an algorithm that no longer looks much like + that presented in the paper, but the basic structure remains if you + dig deep enough to see it. + + This module DOES NOT INCLUDE code to generate/apply the window + function. Everybody has their own weird favorite including me... I + happen to like the properties of y=sin(.5PI*sin^2(x)), but others may + vehemently disagree. + + ********************************************************************/ + +/* this can also be run as an integer transform by uncommenting a + define in mdct.h; the integerization is a first pass and although + it's likely stable for Vorbis, the dynamic range is constrained and + roundoff isn't done (so it's noisy). Consider it functional, but + only a starting point. There's no point on a machine with an FPU */ + +#include +#include +#include +#include +#include "../vorbis/codec.h" +#include "mdct.h" +#include "os.h" +#include "misc.h" + +/* build lookups for trig functions; also pre-figure scaling and + some window function algebra. */ + +void mdct_init(mdct_lookup *lookup,int n){ + int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4)); + DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4)); + + int i; + int n2=n>>1; + int log2n=lookup->log2n=rint(log((float)n)/log(2.f)); + lookup->n=n; + lookup->trig=T; + lookup->bitrev=bitrev; + +/* trig lookups... */ + + for(i=0;i>j;j++) + if((msb>>j)&i)acc|=1<scale=FLOAT_CONV(4.f/n); +} + +/* 8 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_8(DATA_TYPE *x){ + REG_TYPE r0 = x[6] + x[2]; + REG_TYPE r1 = x[6] - x[2]; + REG_TYPE r2 = x[4] + x[0]; + REG_TYPE r3 = x[4] - x[0]; + + x[6] = r0 + r2; + x[4] = r0 - r2; + + r0 = x[5] - x[1]; + r2 = x[7] - x[3]; + x[0] = r1 + r0; + x[2] = r1 - r0; + + r0 = x[5] + x[1]; + r1 = x[7] + x[3]; + x[3] = r2 + r3; + x[1] = r2 - r3; + x[7] = r1 + r0; + x[5] = r1 - r0; + +} + +/* 16 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_16(DATA_TYPE *x){ + REG_TYPE r0 = x[1] - x[9]; + REG_TYPE r1 = x[0] - x[8]; + + x[8] += x[0]; + x[9] += x[1]; + x[0] = MULT_NORM((r0 + r1) * cPI2_8); + x[1] = MULT_NORM((r0 - r1) * cPI2_8); + + r0 = x[3] - x[11]; + r1 = x[10] - x[2]; + x[10] += x[2]; + x[11] += x[3]; + x[2] = r0; + x[3] = r1; + + r0 = x[12] - x[4]; + r1 = x[13] - x[5]; + x[12] += x[4]; + x[13] += x[5]; + x[4] = MULT_NORM((r0 - r1) * cPI2_8); + x[5] = MULT_NORM((r0 + r1) * cPI2_8); + + r0 = x[14] - x[6]; + r1 = x[15] - x[7]; + x[14] += x[6]; + x[15] += x[7]; + x[6] = r0; + x[7] = r1; + + mdct_butterfly_8(x); + mdct_butterfly_8(x+8); +} + +/* 32 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_32(DATA_TYPE *x){ + REG_TYPE r0 = x[30] - x[14]; + REG_TYPE r1 = x[31] - x[15]; + + x[30] += x[14]; + x[31] += x[15]; + x[14] = r0; + x[15] = r1; + + r0 = x[28] - x[12]; + r1 = x[29] - x[13]; + x[28] += x[12]; + x[29] += x[13]; + x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 ); + x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 ); + + r0 = x[26] - x[10]; + r1 = x[27] - x[11]; + x[26] += x[10]; + x[27] += x[11]; + x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8); + x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8); + + r0 = x[24] - x[8]; + r1 = x[25] - x[9]; + x[24] += x[8]; + x[25] += x[9]; + x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 ); + x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); + + r0 = x[22] - x[6]; + r1 = x[7] - x[23]; + x[22] += x[6]; + x[23] += x[7]; + x[6] = r1; + x[7] = r0; + + r0 = x[4] - x[20]; + r1 = x[5] - x[21]; + x[20] += x[4]; + x[21] += x[5]; + x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 ); + x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 ); + + r0 = x[2] - x[18]; + r1 = x[3] - x[19]; + x[18] += x[2]; + x[19] += x[3]; + x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8); + x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8); + + r0 = x[0] - x[16]; + r1 = x[1] - x[17]; + x[16] += x[0]; + x[17] += x[1]; + x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); + x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 ); + + mdct_butterfly_16(x); + mdct_butterfly_16(x+16); + +} + +/* N point first stage butterfly (in place, 2 register) */ +STIN void mdct_butterfly_first(DATA_TYPE *T, + DATA_TYPE *x, + int points){ + + DATA_TYPE *x1 = x + points - 8; + DATA_TYPE *x2 = x + (points>>1) - 8; + REG_TYPE r0; + REG_TYPE r1; + + do{ + + r0 = x1[6] - x2[6]; + r1 = x1[7] - x2[7]; + x1[6] += x2[6]; + x1[7] += x2[7]; + x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + r0 = x1[4] - x2[4]; + r1 = x1[5] - x2[5]; + x1[4] += x2[4]; + x1[5] += x2[5]; + x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]); + x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]); + + r0 = x1[2] - x2[2]; + r1 = x1[3] - x2[3]; + x1[2] += x2[2]; + x1[3] += x2[3]; + x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]); + x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]); + + r0 = x1[0] - x2[0]; + r1 = x1[1] - x2[1]; + x1[0] += x2[0]; + x1[1] += x2[1]; + x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]); + x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]); + + x1-=8; + x2-=8; + T+=16; + + }while(x2>=x); +} + +/* N/stage point generic N stage butterfly (in place, 2 register) */ +STIN void mdct_butterfly_generic(DATA_TYPE *T, + DATA_TYPE *x, + int points, + int trigint){ + + DATA_TYPE *x1 = x + points - 8; + DATA_TYPE *x2 = x + (points>>1) - 8; + REG_TYPE r0; + REG_TYPE r1; + + do{ + + r0 = x1[6] - x2[6]; + r1 = x1[7] - x2[7]; + x1[6] += x2[6]; + x1[7] += x2[7]; + x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[4] - x2[4]; + r1 = x1[5] - x2[5]; + x1[4] += x2[4]; + x1[5] += x2[5]; + x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[2] - x2[2]; + r1 = x1[3] - x2[3]; + x1[2] += x2[2]; + x1[3] += x2[3]; + x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[0] - x2[0]; + r1 = x1[1] - x2[1]; + x1[0] += x2[0]; + x1[1] += x2[1]; + x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + x1-=8; + x2-=8; + + }while(x2>=x); +} + +STIN void mdct_butterflies(mdct_lookup *init, + DATA_TYPE *x, + int points){ + + DATA_TYPE *T=init->trig; + int stages=init->log2n-5; + int i,j; + + if(--stages>0){ + mdct_butterfly_first(T,x,points); + } + + for(i=1;--stages>0;i++){ + for(j=0;j<(1<>i)*j,points>>i,4<trig)_ogg_free(l->trig); + if(l->bitrev)_ogg_free(l->bitrev); + memset(l,0,sizeof(*l)); + } +} + +STIN void mdct_bitreverse(mdct_lookup *init, + DATA_TYPE *x){ + int n = init->n; + int *bit = init->bitrev; + DATA_TYPE *w0 = x; + DATA_TYPE *w1 = x = w0+(n>>1); + DATA_TYPE *T = init->trig+n; + + do{ + DATA_TYPE *x0 = x+bit[0]; + DATA_TYPE *x1 = x+bit[1]; + + REG_TYPE r0 = x0[1] - x1[1]; + REG_TYPE r1 = x0[0] + x1[0]; + REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]); + REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]); + + w1 -= 4; + + r0 = HALVE(x0[1] + x1[1]); + r1 = HALVE(x0[0] - x1[0]); + + w0[0] = r0 + r2; + w1[2] = r0 - r2; + w0[1] = r1 + r3; + w1[3] = r3 - r1; + + x0 = x+bit[2]; + x1 = x+bit[3]; + + r0 = x0[1] - x1[1]; + r1 = x0[0] + x1[0]; + r2 = MULT_NORM(r1 * T[2] + r0 * T[3]); + r3 = MULT_NORM(r1 * T[3] - r0 * T[2]); + + r0 = HALVE(x0[1] + x1[1]); + r1 = HALVE(x0[0] - x1[0]); + + w0[2] = r0 + r2; + w1[0] = r0 - r2; + w0[3] = r1 + r3; + w1[1] = r3 - r1; + + T += 4; + bit += 4; + w0 += 4; + + }while(w0n; + int n2=n>>1; + int n4=n>>2; + + /* rotate */ + + DATA_TYPE *iX = in+n2-7; + DATA_TYPE *oX = out+n2+n4; + DATA_TYPE *T = init->trig+n4; + + do{ + oX -= 4; + oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]); + oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]); + oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]); + oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]); + iX -= 8; + T += 4; + }while(iX>=in); + + iX = in+n2-8; + oX = out+n2+n4; + T = init->trig+n4; + + do{ + T -= 4; + oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]); + oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]); + oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]); + oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]); + iX -= 8; + oX += 4; + }while(iX>=in); + + mdct_butterflies(init,out+n2,n2); + mdct_bitreverse(init,out); + + /* roatate + window */ + + { + DATA_TYPE *oX1=out+n2+n4; + DATA_TYPE *oX2=out+n2+n4; + DATA_TYPE *iX =out; + T =init->trig+n2; + + do{ + oX1-=4; + + oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]); + oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]); + + oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]); + oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]); + + oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]); + oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]); + + oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]); + oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]); + + oX2+=4; + iX += 8; + T += 8; + }while(iXoX2); + } +} + +void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ + int n=init->n; + int n2=n>>1; + int n4=n>>2; + int n8=n>>3; + DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */ + DATA_TYPE *w2=w+n2; + + /* rotate */ + + /* window + rotate + step 1 */ + + REG_TYPE r0; + REG_TYPE r1; + DATA_TYPE *x0=in+n2+n4; + DATA_TYPE *x1=x0+1; + DATA_TYPE *T=init->trig+n2; + + int i=0; + + for(i=0;itrig+n2; + x0=out+n2; + + for(i=0;iscale); + x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale); + w+=2; + T+=2; + } +} + diff --git a/sound/OggVorbis/vorbissrc/mdct.h b/sound/OggVorbis/vorbissrc/mdct.h new file mode 100644 index 000000000..050b03ef4 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/mdct.h @@ -0,0 +1,83 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: modified discrete cosine transform prototypes + last mod: $Id$ + + ********************************************************************/ + +#ifndef _OGG_mdct_H_ +#define _OGG_mdct_H_ + +#include "../vorbis/codec.h" + + + + + +/*#define MDCT_INTEGERIZED <- be warned there could be some hurt left here*/ +#ifdef MDCT_INTEGERIZED + +#define DATA_TYPE int +#define REG_TYPE register int +#define TRIGBITS 14 +#define cPI3_8 6270 +#define cPI2_8 11585 +#define cPI1_8 15137 + +#define FLOAT_CONV(x) ((int)((x)*(1<>TRIGBITS) +#define HALVE(x) ((x)>>1) + +#else + +#define DATA_TYPE float +#define REG_TYPE float +#define cPI3_8 .38268343236508977175F +#define cPI2_8 .70710678118654752441F +#define cPI1_8 .92387953251128675613F + +#define FLOAT_CONV(x) (x) +#define MULT_NORM(x) (x) +#define HALVE(x) ((x)*.5f) + +#endif + + +typedef struct { + int n; + int log2n; + + DATA_TYPE *trig; + int *bitrev; + + DATA_TYPE scale; +} mdct_lookup; + +extern void mdct_init(mdct_lookup *lookup,int n); +extern void mdct_clear(mdct_lookup *l); +extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); +extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); + +#endif + + + + + + + + + + + + diff --git a/sound/OggVorbis/vorbissrc/misc.h b/sound/OggVorbis/vorbissrc/misc.h new file mode 100644 index 000000000..65f95fe49 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/misc.h @@ -0,0 +1,52 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: miscellaneous prototypes + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_RANDOM_H_ +#define _V_RANDOM_H_ +#include "../vorbis/codec.h" + +extern int analysis_noisy; + +extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); +extern void _vorbis_block_ripcord(vorbis_block *vb); +extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB, + ogg_int64_t off); + +#ifdef DEBUG_MALLOC + +#define _VDBG_GRAPHFILE "malloc.m" +extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line); +extern void _VDBG_free(void *ptr,char *file,long line); + +#ifndef MISC_C +#undef _ogg_malloc +#undef _ogg_calloc +#undef _ogg_realloc +#undef _ogg_free + +#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__) +#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__) +#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__) +#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__) +#endif +#endif + +#endif + + + + diff --git a/sound/OggVorbis/vorbissrc/modes/floor_all.h b/sound/OggVorbis/vorbissrc/modes/floor_all.h new file mode 100644 index 000000000..a010d3771 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/floor_all.h @@ -0,0 +1,226 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: key floor settings + last mod: $Id$ + + ********************************************************************/ + +#include "../vorbis/codec.h" +#include "backends.h" +#include "books/floor/floor_books.h" + +static static_codebook *_floor_128x4_books[]={ + &_huff_book_line_128x4_class0, + &_huff_book_line_128x4_0sub0, + &_huff_book_line_128x4_0sub1, + &_huff_book_line_128x4_0sub2, + &_huff_book_line_128x4_0sub3, +}; +static static_codebook *_floor_256x4_books[]={ + &_huff_book_line_256x4_class0, + &_huff_book_line_256x4_0sub0, + &_huff_book_line_256x4_0sub1, + &_huff_book_line_256x4_0sub2, + &_huff_book_line_256x4_0sub3, +}; +static static_codebook *_floor_128x7_books[]={ + &_huff_book_line_128x7_class0, + &_huff_book_line_128x7_class1, + + &_huff_book_line_128x7_0sub1, + &_huff_book_line_128x7_0sub2, + &_huff_book_line_128x7_0sub3, + &_huff_book_line_128x7_1sub1, + &_huff_book_line_128x7_1sub2, + &_huff_book_line_128x7_1sub3, +}; +static static_codebook *_floor_256x7_books[]={ + &_huff_book_line_256x7_class0, + &_huff_book_line_256x7_class1, + + &_huff_book_line_256x7_0sub1, + &_huff_book_line_256x7_0sub2, + &_huff_book_line_256x7_0sub3, + &_huff_book_line_256x7_1sub1, + &_huff_book_line_256x7_1sub2, + &_huff_book_line_256x7_1sub3, +}; +static static_codebook *_floor_128x11_books[]={ + &_huff_book_line_128x11_class1, + &_huff_book_line_128x11_class2, + &_huff_book_line_128x11_class3, + + &_huff_book_line_128x11_0sub0, + &_huff_book_line_128x11_1sub0, + &_huff_book_line_128x11_1sub1, + &_huff_book_line_128x11_2sub1, + &_huff_book_line_128x11_2sub2, + &_huff_book_line_128x11_2sub3, + &_huff_book_line_128x11_3sub1, + &_huff_book_line_128x11_3sub2, + &_huff_book_line_128x11_3sub3, +}; +static static_codebook *_floor_128x17_books[]={ + &_huff_book_line_128x17_class1, + &_huff_book_line_128x17_class2, + &_huff_book_line_128x17_class3, + + &_huff_book_line_128x17_0sub0, + &_huff_book_line_128x17_1sub0, + &_huff_book_line_128x17_1sub1, + &_huff_book_line_128x17_2sub1, + &_huff_book_line_128x17_2sub2, + &_huff_book_line_128x17_2sub3, + &_huff_book_line_128x17_3sub1, + &_huff_book_line_128x17_3sub2, + &_huff_book_line_128x17_3sub3, +}; +static static_codebook *_floor_512x17_books[]={ + &_huff_book_line_512x17_class1, + &_huff_book_line_512x17_class2, + &_huff_book_line_512x17_class3, + + &_huff_book_line_512x17_0sub0, + &_huff_book_line_512x17_1sub0, + &_huff_book_line_512x17_1sub1, + &_huff_book_line_512x17_2sub1, + &_huff_book_line_512x17_2sub2, + &_huff_book_line_512x17_2sub3, + &_huff_book_line_512x17_3sub1, + &_huff_book_line_512x17_3sub2, + &_huff_book_line_512x17_3sub3, +}; +static static_codebook *_floor_1024x27_books[]={ + &_huff_book_line_1024x27_class1, + &_huff_book_line_1024x27_class2, + &_huff_book_line_1024x27_class3, + &_huff_book_line_1024x27_class4, + + &_huff_book_line_1024x27_0sub0, + &_huff_book_line_1024x27_1sub0, + &_huff_book_line_1024x27_1sub1, + &_huff_book_line_1024x27_2sub0, + &_huff_book_line_1024x27_2sub1, + &_huff_book_line_1024x27_3sub1, + &_huff_book_line_1024x27_3sub2, + &_huff_book_line_1024x27_3sub3, + &_huff_book_line_1024x27_4sub1, + &_huff_book_line_1024x27_4sub2, + &_huff_book_line_1024x27_4sub3, +}; + +static static_codebook **_floor_books[10]={ + _floor_128x4_books, + _floor_256x4_books, + _floor_128x7_books, + _floor_256x7_books, + _floor_128x11_books, + _floor_128x17_books, + _floor_128x17_books, + _floor_1024x27_books, + _floor_1024x27_books, + _floor_512x17_books, +}; + +static vorbis_info_floor1 _floor[10]={ + /* 128 x 4 */ + { + 1,{0},{4},{2},{0}, + {{1,2,3,4}}, + 4,{0,128, 33,8,16,70}, + + 60,30,500, 1.,18., -1 + }, + /* 256 x 4 */ + { + 1,{0},{4},{2},{0}, + {{1,2,3,4}}, + 4,{0,256, 66,16,32,140}, + + 60,30,500, 1.,18., -1 + }, + /* 128 x 7 */ + { + 2,{0,1},{3,4},{2,2},{0,1}, + {{-1,2,3,4},{-1,5,6,7}}, + 4,{0,128, 14,4,58, 2,8,28,90}, + + 60,30,500, 1.,18., -1 + }, + /* 256 x 7 */ + { + 2,{0,1},{3,4},{2,2},{0,1}, + {{-1,2,3,4},{-1,5,6,7}}, + 4,{0,256, 28,8,116, 4,16,56,180}, + + 60,30,500, 1.,18., -1 + }, + + /* 128 x 11 */ + { + 4,{0,1,2,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + + 2,{0,128, 8,33, 4,16,70, 2,6,12, 23,46,90}, + + 60,30,500, 1,18., -1 + }, + + /* 128 x 17 */ + { + 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + 2,{0,128, 12,46, 4,8,16, 23,33,70, 2,6,10, 14,19,28, 39,58,90}, + + 60,30,500, 1,18., -1 + }, + + /* 1024 x 17 */ + { + 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + 2,{0,1024, 93,372, 33,65,130, 186,260,556, + 14,46,79, 111,158,220, 312,464,720}, + + 60,30,500, 1,18., -1 /* lowpass! */ + }, + /* 1024 x 27 */ + { + 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3}, + {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}}, + 2,{0,1024, 93,23,372, 6,46,186,750, 14,33,65, 130,260,556, + 3,10,18,28, 39,55,79,111, 158,220,312, 464,650,850}, + + 60,30,500, 3,18., -1 /* lowpass */ + }, + /* 2048 x 27 */ + { + 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3}, + {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}}, + 2,{0,2048, 186,46,744, 12,92,372,1500, 28,66,130, 260,520,1112, + 6,20,36,56, 78,110,158,222, 316,440,624, 928,1300,1700}, + + 60,30,500, 3,18., -1 /* lowpass */ + }, + /* 512 x 17 */ + { + 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + 2,{0,512, 46,186, 16,33,65, 93,130,278, + 7,23,39, 55,79,110, 156,232,360}, + + 60,30,500, 1,18., -1 /* lowpass! */ + }, + +}; + diff --git a/sound/OggVorbis/vorbissrc/modes/psych_11.h b/sound/OggVorbis/vorbissrc/modes/psych_11.h new file mode 100644 index 000000000..193dc3a32 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/psych_11.h @@ -0,0 +1,51 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 11kHz settings + last mod: $Id$ + + ********************************************************************/ + +static double _psy_lowpass_11[3]={4.5,5.5,30.,}; + +static att3 _psy_tone_masteratt_11[3]={ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 20, 0, -14}, 0, 1.}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_11[3]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 2, 0,99,99,99}}, /* 0 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 5, 0, 0,99,99,99}}, /* 1 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 2 */ +}; + + +static noise3 _psy_noisebias_11[3]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99}, + {-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 4, 5, 5, 10, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99}, + {-15,-15,-15,-15,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}}, +}; + +static double _noise_thresh_11[3]={ .3,.5,.5 }; + diff --git a/sound/OggVorbis/vorbissrc/modes/psych_16.h b/sound/OggVorbis/vorbissrc/modes/psych_16.h new file mode 100644 index 000000000..2f3c60344 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/psych_16.h @@ -0,0 +1,129 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 16kHz settings + last mod: $Id$ + + ********************************************************************/ + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_16[4]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +static double _psy_lowpass_16[4]={6.5,8,30.,99.}; + +static att3 _psy_tone_masteratt_16[4]={ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 25, 22, 12}, 0, 0}, /* 0 */ + {{ 20, 12, 0}, 0, 0}, /* 0 */ + {{ 15, 0, -14}, 0, 0}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_16[4]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 1 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ + {{-30,-30,-30,-30,-30,-26,-20,-10, -5, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ +}; + + +static noise3 _psy_noisebias_16_short[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20}, + {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 6, 6, 6, 6, 8, 10, 12, 20}, + {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12}, + {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10, -8, 0, 0, 0, 0, 2, 5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static noise3 _psy_noisebias_16_impulse[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20}, + {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 4, 4, 4, 5, 5, 6, 8, 15}, + {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 0, 0, 0, 0, 4, 10}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 4, 10}, + {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10,-10,-10,-10,-10,-10, -7, -5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-18,-18,-18,-20,-20,-20,-20,-20,-20,-16}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static noise3 _psy_noisebias_16[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 8, 8, 10, 10, 10, 14, 20}, + {-10,-10,-10,-10,-10, -5, -2, -2, 0, 0, 0, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 6, 6, 6, 8, 10, 12, 20}, + {-15,-15,-15,-15,-15,-10, -5, -5, 0, 0, 0, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12}, + {-20,-20,-20,-20,-16,-12,-20,-10, -5, -5, 0, 0, 0, 0, 0, 2, 5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static double _noise_thresh_16[4]={ .3,.5,.5,.5 }; + +static int _noise_start_16[3]={ 256,256,9999 }; +static int _noise_part_16[4]={ 8,8,8,8 }; + +static int _psy_ath_floater_16[4]={ + -100,-100,-100,-105, +}; + +static int _psy_ath_abs_16[4]={ + -130,-130,-130,-140, +}; + + + diff --git a/sound/OggVorbis/vorbissrc/modes/psych_44.h b/sound/OggVorbis/vorbissrc/modes/psych_44.h new file mode 100644 index 000000000..93ed88715 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/psych_44.h @@ -0,0 +1,532 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: key psychoacoustic settings for 44.1/48kHz + last mod: $Id$ + + ********************************************************************/ + + +/* preecho trigger settings *****************************************/ + +static vorbis_info_psy_global _psy_global_44[5]={ + + {8, /* lines per eighth octave */ + {20.f,14.f,12.f,12.f,12.f,12.f,12.f}, + {-60.f,-30.f,-40.f,-40.f,-40.f,-40.f,-40.f}, 2,-75.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {14.f,10.f,10.f,10.f,10.f,10.f,10.f}, + {-40.f,-30.f,-25.f,-25.f,-25.f,-25.f,-25.f}, 2,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {12.f,10.f,10.f,10.f,10.f,10.f,10.f}, + {-20.f,-20.f,-15.f,-15.f,-15.f,-15.f,-15.f}, 0,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {10.f,8.f,8.f,8.f,8.f,8.f,8.f}, + {-20.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {10.f,6.f,6.f,6.f,6.f,6.f,6.f}, + {-15.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-85.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, +}; + +/* noise compander lookups * low, mid, high quality ****************/ +static compandblock _psy_compand_44[6]={ + /* sub-mode Z short */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,13,14, 15, /* 15dB */ + 16,17,18,19,20,21,22, 23, /* 23dB */ + 24,25,26,27,28,29,30, 31, /* 31dB */ + 32,33,34,35,36,37,38, 39, /* 39dB */ + }}, + /* mode_Z nominal short*/ + {{ + 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */ + 7, 7, 7, 7, 6, 6, 6, 7, /* 15dB */ + 7, 8, 9,10,11,12,13, 14, /* 23dB */ + 15,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + /* mode A short */ + {{ + 0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */ + 6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */ + 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */ + 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */ + 11,12,13,14,15,16,17, 18, /* 39dB */ + }}, + /* sub-mode Z long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,13,14, 15, /* 15dB */ + 16,17,18,19,20,21,22, 23, /* 23dB */ + 24,25,26,27,28,29,30, 31, /* 31dB */ + 32,33,34,35,36,37,38, 39, /* 39dB */ + }}, + /* mode_Z nominal long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,12,13, 13, /* 15dB */ + 13,14,14,14,15,15,15, 15, /* 23dB */ + 16,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + /* mode A long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 8, 7, 6, 5, 4, 4, 4, /* 15dB */ + 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */ + 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */ + 11,12,13,14,15,16,17, 18, /* 39dB */ + }} +}; + +/* tonal masking curve level adjustments *************************/ +static vp_adjblock _vp_tonemask_adj_longblock[11]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-15,-15,-15,-15,-10, -8, -4,-2, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 5, 0, 0, 0, 0, 0}}, /* 1 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */ + {{-15,-15,-15,-15,-15,-12,-10,-8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */ +}; +static vp_adjblock _vp_tonemask_adj_otherblock[11]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-20,-20,-20,-20,-14,-12,-10, -8, -4, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 5, 0, 0, 0, 0, 0}}, /* 1 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */ + {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */ +}; + +static noise3 _psy_noisebias_trans_low[2]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 4, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + /* 1 */ + {{{-15,-15,-15,-15,-15,-10, -5, 0, 2, 2, 6, 6, 6, 8, 10, 12, 15}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, 0, 0, 0, 2, 4, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}}, +}; +static noise3 _psy_noisebias_long_low[2]={ + /*63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 0, 6, 6, 6, 6, 10, 10, 12, 20}, + {-20,-20,-20,-20,-20,-20,-10, -2, 0, 0, 0, 0, 0, 2, 4, 6, 15}, + {-20,-20,-20,-20,-20,-20,-20,-10, -6, -6, -6, -6, -6, -4, -4, -4, -2}}}, + /* 1 */ + {{{-10,-10,-10,-10,-10,-10, -8, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -8, -2, 0, 0, 0, 0, 2, 4, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -6, -6, -6, -6, -6, -4, -4, -4, -2}}}, +}; + +static noise3 _psy_noisebias_trans[11]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4, 0, 0, 0, 0, 2, 4, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}}, + /* 1 */ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}}, + /* 2 */ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 3 */ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 4 */ + {{{-20,-20,-20,-20,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 5 */ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2}, + {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, + /* 6 */ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1}, + {-34,-34,-34,-34,-30,-26,-24,-18,-17,-15,-15,-15,-15,-13,-13,-12, -8}}}, + /* 7 */ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-18,-14,-12,-10, -8, -8, -8, -6, -4, 0}, + {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}}, + /* 8 */ + {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2, 0, 0, 0, 1, 2, 3, 7}, + {-36,-36,-36,-36,-30,-30,-30,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2}, + {-36,-36,-36,-36,-34,-30,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}}, + /* 9 */ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-36,-36,-36,-36,-34,-32,-32,-28,-20,-16,-16,-16,-16,-14,-12,-10, -7}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-30,-30,-28,-20,-14,-14,-14,-14,-14,-14,-12,-10}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-20}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +static noise3 _psy_noisebias_long[11]={ + /*63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-10,-10,-10,-10,-10,-10, -8, 2, 2, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -6, 0, 0, 0, 0, 0, 2, 4, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}}, + /* 1 */ + {{{-10,-10,-10,-10,-10,-10, -8, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}}, + /* 2 */ + {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 3 */ + {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 4 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 5 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, + /* 6 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1}, + {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12, -8}}}, + /* 7 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14,-10, -8, -8, -8, -8, -6, -4, 0}, + {-26,-26,-26,-26,-26,-26,-26,-22,-20,-19,-19,-19,-19,-18,-17,-16,-12}}}, + /* 8 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 0, 0, 0, 0, 1, 2, 3, 7}, + {-26,-26,-26,-26,-26,-26,-26,-20,-16,-12,-10,-10,-10,-10, -8, -6, -2}, + {-28,-28,-28,-28,-28,-28,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}}, + /* 9 */ + {{{-22,-22,-22,-22,-22,-22,-22,-18,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-26,-26,-26,-26,-26,-26,-26,-22,-18,-16,-16,-16,-16,-14,-12,-10, -7}, + {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 10 */ + {{{-24,-24,-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-14,-14,-14,-12,-10}, + {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-20}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +static noise3 _psy_noisebias_impulse[11]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 4, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2, 0, 0, 0, 0, 2, 4, 10}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + /* 1 */ + {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -4, -4, -2, -2, -2, -2, 2}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8,-10,-10, -8, -8, -8, -6, -4}}}, + /* 2 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 3 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 4 */ + {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 5 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11}, + {-32,-32,-32,-32,-28,-24,-22,-16,-10, -6, -8, -8, -6, -6, -6, -4, -2}, + {-34,-34,-34,-34,-30,-26,-24,-18,-14,-12,-12,-12,-12,-12,-10, -9, -5}}}, + /* 6 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-24,-20,-12,-12,-14,-14,-10, -9, -8, -6, -4}, + {-34,-34,-34,-34,-34,-30,-26,-20,-16,-15,-15,-15,-15,-15,-13,-12, -8}}}, + /* 7 */ + {{{-22,-22,-22,-22,-22,-20,-14,-10, -6, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10,-10}, + {-34,-34,-34,-34,-32,-32,-30,-24,-20,-19,-19,-19,-19,-19,-17,-16,-12}}}, + /* 8 */ + {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1, 3, 3, 5, 10}, + {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14}, + {-36,-36,-36,-36,-36,-34,-28,-24,-24,-24,-24,-24,-24,-24,-24,-20,-16}}}, + /* 9 */ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-22,-20,-20,-18}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-16,-16,-16,-16,-16,-14,-12}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-26}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + + +static noise3 _psy_noisebias_padding[11]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* 0 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, 2, 3, 6, 6, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -4, -4, -2, 0, 2}}}, + /* 1 */ + {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -6, -4, -2, 0}}}, + /* 2 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 3 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, 0, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 4 */ + {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, -1, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 5 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -3, -3, -3, -3, -2, 0, 4}, + {-34,-34,-34,-34,-30,-26,-24,-18,-14,-10,-10,-10,-10,-10, -8, -5, -3}}}, + /* 6 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -4, -4, -4, -4, -3, -1, 4}, + {-34,-34,-34,-34,-34,-30,-26,-20,-16,-13,-13,-13,-13,-13,-11, -8, -6}}}, + /* 7 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-34,-34,-34,-34,-30,-30,-30,-24,-16,-10, -8, -6, -6, -6, -5, -3, 1}, + {-34,-34,-34,-34,-32,-32,-28,-22,-18,-16,-16,-16,-16,-16,-14,-12,-10}}}, + /* 8 */ + {{{-22,-22,-22,-22,-22,-20,-14,-10, -4, 0, 0, 0, 0, 3, 5, 5, 11}, + {-34,-34,-34,-34,-30,-30,-30,-24,-16,-12,-10, -8, -8, -8, -7, -5, -2}, + {-36,-36,-36,-36,-36,-34,-28,-22,-20,-20,-20,-20,-20,-20,-20,-16,-14}}}, + /* 9 */ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -2, -2, -2, -2, 0, 2, 6}, + {-36,-36,-36,-36,-34,-32,-32,-24,-16,-12,-12,-12,-12,-12,-10, -8, -5}, + {-40,-40,-40,-40,-40,-40,-40,-32,-26,-24,-24,-24,-24,-24,-24,-20,-18}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-12,-12,-12,-12,-12,-10, -8}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-25,-25,-25,-25,-25,-25,-15}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +static noiseguard _psy_noiseguards_44[4]={ + {3,3,15}, + {3,3,15}, + {10,10,100}, + {10,10,100}, +}; + +static int _psy_tone_suppress[11]={ + -20,-20,-20,-20,-24,-30,-40,-40,-45,-45,-45, +}; + +static int _psy_tone_0dB[11]={ + 90,95,95,95,95,105,105,105,105,105,105, +}; + +static int _psy_noise_suppress[11]={ + -20,-24,-24,-24,-24,-30,-40,-40,-45,-45,-45, +}; + +static vorbis_info_psy _psy_info_template={ + -1, + -140.,-140., + /* tonemask att boost/decay,suppr,curves */ + {0.f,0.f,0.f}, 0.,0., -40.f, {0.}, + + /*noisemaskp,supp, low/high window, low/hi guard, minimum */ + 1, -0.f, .5f, .5f, 0,0,0, + {{-1},{-1},{-1}},{-1},105.f, + + 0,0,-1,-1,0., +}; + +/* ath ****************/ + +static int _psy_ath_floater[11]={ + -100,-100,-100,-100,-100,-105,-105,-105,-105,-110,-120, +}; + +static int _psy_ath_abs[11]={ + -130,-130,-130,-140,-140,-140,-140,-140,-140,-140,-150, +}; + +/* stereo setup. These don't map directly to quality level, there's + an additional indirection as several of the below may be used in a + single bitmanaged stream + +****************/ + +/* various stereo possibilities */ + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_44_low[2]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 */ + {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3}, + { 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 */ + {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3}, + { 1, 2, 3, 4, 5, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +static adj_stereo _psy_stereo_modes_44[11]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 */ + {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3}, + { 1, 2, 3, 4, 5, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 */ + {{ 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3}, + { 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 */ + {{ 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0}, + { 8, 8, 8, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1}, + { 3, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 3 */ + {{ 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + { 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1}, + { 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 4 */ + {{ 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0}, + { 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 5 */ + {{ 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, + { 6, 6, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 6 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 7 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 8 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 9 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 10 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +/* tone master attenuation by base quality mode and bitrate tweak */ + +static att3 _psy_tone_masteratt_44_low[2]={ + {{ 34, 20, 8}, 0, 1.25}, /* 0 */ + {{ 34, 20, 8}, -2, 1.25}, /* 1 */ +}; +static att3 _psy_tone_masteratt_44[11]={ + {{ 30, 20, 8}, -2, 1.25}, /* 0 */ + {{ 25, 14, 4}, 0, 0}, /* 1 */ + {{ 20, 10, -2}, 0, 0}, /* 2 */ + {{ 20, 9, -4}, 0, 0}, /* 3 */ + {{ 20, 9, -4}, 0, 0}, /* 4 */ + {{ 20, 6, -6}, 0, 0}, /* 5 */ + {{ 20, 3, -10}, 0, 0}, /* 6 */ + {{ 18, 1, -14}, 0, 0}, /* 7 */ + {{ 18, 0, -16}, 0, 0}, /* 8 */ + {{ 18, -2, -16}, 0, 0}, /* 9 */ + {{ 12, -2, -20}, 0, 0}, /* 10 */ +}; + +/* lowpass by mode **************/ +static double _psy_lowpass_44_low[2]={ + 15.1,15.1, +}; +static double _psy_lowpass_44[11]={ + 15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999. +}; + +/* noise normalization **********/ + +static int _noise_start_short_44[10]={ + 16,16,16,16,32,32,9999,9999,9999,9999 +}; +static int _noise_start_long_44[10]={ + 128,128,128,256,512,512,9999,9999,9999,9999 +}; +static int _noise_part_short_44[10]={ + 8,8,8,8,8,8,8,8,8,8 +}; +static int _noise_part_long_44[10]={ + 32,32,32,32,32,32,32,32,32,32 +}; +static double _noise_thresh_44[10]={ + .2,.2,.3,.4,.5,.5,9999.,9999.,9999.,9999., +}; +static double _noise_thresh_44_2[2]={ + .5,.5, +}; + + +static int _noise_start_short_44_low[2]={ + 32,32 +}; +static int _noise_start_long_44_low[2]={ + 256,256 +}; diff --git a/sound/OggVorbis/vorbissrc/modes/psych_8.h b/sound/OggVorbis/vorbissrc/modes/psych_8.h new file mode 100644 index 000000000..b6c8bc3a3 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/psych_8.h @@ -0,0 +1,102 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 8kHz psychoacoustic settings + last mod: $Id$ + + ********************************************************************/ + +static att3 _psy_tone_masteratt_8[3]={ + {{ 32, 25, 12}, 0, 0}, /* 0 */ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 20, 0, -14}, 0, 0}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_8[3]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 1 */ +}; + + +static noise3 _psy_noisebias_8[3]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99}, + {-10,-10,-10,-10, -5, -5, -5, 0, 0, 4, 4, 4, 4, 4, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99}, + {-10,-10,-10,-10,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}}, +}; + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_8[3]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +static noiseguard _psy_noiseguards_8[2]={ + {10,10,-1}, + {10,10,-1}, +}; + +static compandblock _psy_compand_8[2]={ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 8, 9, 9,10,10,11, 11, /* 15dB */ + 12,12,13,13,14,14,15, 15, /* 23dB */ + 16,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + {{ + 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */ + 7, 7, 6, 6, 5, 5, 4, 4, /* 15dB */ + 3, 3, 3, 4, 5, 6, 7, 8, /* 23dB */ + 9,10,11,12,13,14,15, 16, /* 31dB */ + 17,18,19,20,21,22,23, 24, /* 39dB */ + }}, +}; + +static double _psy_lowpass_8[3]={3.,4.,4.}; +static int _noise_start_8[2]={ + 64,64, +}; +static int _noise_part_8[2]={ + 8,8, +}; + +static int _psy_ath_floater_8[3]={ + -100,-100,-105, +}; + +static int _psy_ath_abs_8[3]={ + -130,-130,-140, +}; + diff --git a/sound/OggVorbis/vorbissrc/modes/residue_16.h b/sound/OggVorbis/vorbissrc/modes/residue_16.h new file mode 100644 index 000000000..62ba23b1c --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/residue_16.h @@ -0,0 +1,163 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates 16/22kHz + last mod: $Id$ + + ********************************************************************/ + +/***** residue backends *********************************************/ + +static static_bookblock _resbook_16s_0={ + { + {0}, + {0,0,&_16c0_s_p1_0}, + {0,0,&_16c0_s_p2_0}, + {0,0,&_16c0_s_p3_0}, + {0,0,&_16c0_s_p4_0}, + {0,0,&_16c0_s_p5_0}, + {0,0,&_16c0_s_p6_0}, + {&_16c0_s_p7_0,&_16c0_s_p7_1}, + {&_16c0_s_p8_0,&_16c0_s_p8_1}, + {&_16c0_s_p9_0,&_16c0_s_p9_1,&_16c0_s_p9_2} + } +}; +static static_bookblock _resbook_16s_1={ + { + {0}, + {0,0,&_16c1_s_p1_0}, + {0,0,&_16c1_s_p2_0}, + {0,0,&_16c1_s_p3_0}, + {0,0,&_16c1_s_p4_0}, + {0,0,&_16c1_s_p5_0}, + {0,0,&_16c1_s_p6_0}, + {&_16c1_s_p7_0,&_16c1_s_p7_1}, + {&_16c1_s_p8_0,&_16c1_s_p8_1}, + {&_16c1_s_p9_0,&_16c1_s_p9_1,&_16c1_s_p9_2} + } +}; +static static_bookblock _resbook_16s_2={ + { + {0}, + {0,0,&_16c2_s_p1_0}, + {0,0,&_16c2_s_p2_0}, + {0,0,&_16c2_s_p3_0}, + {0,0,&_16c2_s_p4_0}, + {&_16c2_s_p5_0,&_16c2_s_p5_1}, + {&_16c2_s_p6_0,&_16c2_s_p6_1}, + {&_16c2_s_p7_0,&_16c2_s_p7_1}, + {&_16c2_s_p8_0,&_16c2_s_p8_1}, + {&_16c2_s_p9_0,&_16c2_s_p9_1,&_16c2_s_p9_2} + } +}; + +static vorbis_residue_template _res_16s_0[]={ + {2,0, &_residue_44_mid, + &_huff_book__16c0_s_single,&_huff_book__16c0_s_single, + &_resbook_16s_0,&_resbook_16s_0}, +}; +static vorbis_residue_template _res_16s_1[]={ + {2,0, &_residue_44_mid, + &_huff_book__16c1_s_short,&_huff_book__16c1_s_short, + &_resbook_16s_1,&_resbook_16s_1}, + + {2,0, &_residue_44_mid, + &_huff_book__16c1_s_long,&_huff_book__16c1_s_long, + &_resbook_16s_1,&_resbook_16s_1} +}; +static vorbis_residue_template _res_16s_2[]={ + {2,0, &_residue_44_high, + &_huff_book__16c2_s_short,&_huff_book__16c2_s_short, + &_resbook_16s_2,&_resbook_16s_2}, + + {2,0, &_residue_44_high, + &_huff_book__16c2_s_long,&_huff_book__16c2_s_long, + &_resbook_16s_2,&_resbook_16s_2} +}; + +static vorbis_mapping_template _mapres_template_16_stereo[3]={ + { _map_nominal, _res_16s_0 }, /* 0 */ + { _map_nominal, _res_16s_1 }, /* 1 */ + { _map_nominal, _res_16s_2 }, /* 2 */ +}; + +static static_bookblock _resbook_16u_0={ + { + {0}, + {0,0,&_16u0__p1_0}, + {0,0,&_16u0__p2_0}, + {0,0,&_16u0__p3_0}, + {0,0,&_16u0__p4_0}, + {0,0,&_16u0__p5_0}, + {&_16u0__p6_0,&_16u0__p6_1}, + {&_16u0__p7_0,&_16u0__p7_1,&_16u0__p7_2} + } +}; +static static_bookblock _resbook_16u_1={ + { + {0}, + {0,0,&_16u1__p1_0}, + {0,0,&_16u1__p2_0}, + {0,0,&_16u1__p3_0}, + {0,0,&_16u1__p4_0}, + {0,0,&_16u1__p5_0}, + {0,0,&_16u1__p6_0}, + {&_16u1__p7_0,&_16u1__p7_1}, + {&_16u1__p8_0,&_16u1__p8_1}, + {&_16u1__p9_0,&_16u1__p9_1,&_16u1__p9_2} + } +}; +static static_bookblock _resbook_16u_2={ + { + {0}, + {0,0,&_16u2_p1_0}, + {0,0,&_16u2_p2_0}, + {0,0,&_16u2_p3_0}, + {0,0,&_16u2_p4_0}, + {&_16u2_p5_0,&_16u2_p5_1}, + {&_16u2_p6_0,&_16u2_p6_1}, + {&_16u2_p7_0,&_16u2_p7_1}, + {&_16u2_p8_0,&_16u2_p8_1}, + {&_16u2_p9_0,&_16u2_p9_1,&_16u2_p9_2} + } +}; + +static vorbis_residue_template _res_16u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__16u0__single,&_huff_book__16u0__single, + &_resbook_16u_0,&_resbook_16u_0}, +}; +static vorbis_residue_template _res_16u_1[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__16u1__short,&_huff_book__16u1__short, + &_resbook_16u_1,&_resbook_16u_1}, + + {1,0, &_residue_44_mid_un, + &_huff_book__16u1__long,&_huff_book__16u1__long, + &_resbook_16u_1,&_resbook_16u_1} +}; +static vorbis_residue_template _res_16u_2[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__16u2__short,&_huff_book__16u2__short, + &_resbook_16u_2,&_resbook_16u_2}, + + {1,0, &_residue_44_hi_un, + &_huff_book__16u2__long,&_huff_book__16u2__long, + &_resbook_16u_2,&_resbook_16u_2} +}; + + +static vorbis_mapping_template _mapres_template_16_uncoupled[3]={ + { _map_nominal_u, _res_16u_0 }, /* 0 */ + { _map_nominal_u, _res_16u_1 }, /* 1 */ + { _map_nominal_u, _res_16u_2 }, /* 2 */ +}; diff --git a/sound/OggVorbis/vorbissrc/modes/residue_44.h b/sound/OggVorbis/vorbissrc/modes/residue_44.h new file mode 100644 index 000000000..4a24cb6c7 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/residue_44.h @@ -0,0 +1,254 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates for 32/44.1/48kHz + last mod: $Id$ + + ********************************************************************/ + +#include "../vorbis/codec.h" +#include "backends.h" +#include "books/coupled/res_books_stereo.h" + +/***** residue backends *********************************************/ + +static vorbis_info_residue0 _residue_44_mid={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 */ + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 8.5, 16.5, 32.5}, + { .5, .5, 999., .5, 999., 4.5, 8.5, 16.5, 32.5}, +}; + +static vorbis_info_residue0 _residue_44_high={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 */ + {0}, + {-1}, + { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5}, + { .5, 1.5, 2.5, 3.5, 4.5, 8.5, 16.5, 71.5,157.5}, +}; + +static static_bookblock _resbook_44s_0={ + { + {0},{0,0,&_44c0_s_p1_0},{0,0,&_44c0_s_p2_0},{0,0,&_44c0_s_p3_0}, + {0,0,&_44c0_s_p4_0},{0,0,&_44c0_s_p5_0},{0,0,&_44c0_s_p6_0}, + {&_44c0_s_p7_0,&_44c0_s_p7_1},{&_44c0_s_p8_0,&_44c0_s_p8_1}, + {&_44c0_s_p9_0,&_44c0_s_p9_1,&_44c0_s_p9_2} + } +}; +static static_bookblock _resbook_44sm_0={ + { + {0},{0,0,&_44c0_sm_p1_0},{0,0,&_44c0_sm_p2_0},{0,0,&_44c0_sm_p3_0}, + {0,0,&_44c0_sm_p4_0},{0,0,&_44c0_sm_p5_0},{0,0,&_44c0_sm_p6_0}, + {&_44c0_sm_p7_0,&_44c0_sm_p7_1},{&_44c0_sm_p8_0,&_44c0_sm_p8_1}, + {&_44c0_sm_p9_0,&_44c0_sm_p9_1,&_44c0_sm_p9_2} + } +}; +static static_bookblock _resbook_44s_1={ + { + {0},{0,0,&_44c1_s_p1_0},{0,0,&_44c1_s_p2_0},{0,0,&_44c1_s_p3_0}, + {0,0,&_44c1_s_p4_0},{0,0,&_44c1_s_p5_0},{0,0,&_44c1_s_p6_0}, + {&_44c1_s_p7_0,&_44c1_s_p7_1},{&_44c1_s_p8_0,&_44c1_s_p8_1}, + {&_44c1_s_p9_0,&_44c1_s_p9_1,&_44c1_s_p9_2} + } +}; +static static_bookblock _resbook_44sm_1={ + { + {0},{0,0,&_44c1_sm_p1_0},{0,0,&_44c1_sm_p2_0},{0,0,&_44c1_sm_p3_0}, + {0,0,&_44c1_sm_p4_0},{0,0,&_44c1_sm_p5_0},{0,0,&_44c1_sm_p6_0}, + {&_44c1_sm_p7_0,&_44c1_sm_p7_1},{&_44c1_sm_p8_0,&_44c1_sm_p8_1}, + {&_44c1_sm_p9_0,&_44c1_sm_p9_1,&_44c1_sm_p9_2} + } +}; +static static_bookblock _resbook_44s_2={ + { + {0},{0,0,&_44c2_s_p1_0},{0,0,&_44c2_s_p2_0},{0,0,&_44c2_s_p3_0}, + {0,0,&_44c2_s_p4_0},{0,0,&_44c2_s_p5_0},{0,0,&_44c2_s_p6_0}, + {&_44c2_s_p7_0,&_44c2_s_p7_1},{&_44c2_s_p8_0,&_44c2_s_p8_1}, + {&_44c2_s_p9_0,&_44c2_s_p9_1,&_44c2_s_p9_2} + } +}; +static static_bookblock _resbook_44s_3={ + { + {0},{0,0,&_44c3_s_p1_0},{0,0,&_44c3_s_p2_0},{0,0,&_44c3_s_p3_0}, + {0,0,&_44c3_s_p4_0},{0,0,&_44c3_s_p5_0},{0,0,&_44c3_s_p6_0}, + {&_44c3_s_p7_0,&_44c3_s_p7_1},{&_44c3_s_p8_0,&_44c3_s_p8_1}, + {&_44c3_s_p9_0,&_44c3_s_p9_1,&_44c3_s_p9_2} + } +}; +static static_bookblock _resbook_44s_4={ + { + {0},{0,0,&_44c4_s_p1_0},{0,0,&_44c4_s_p2_0},{0,0,&_44c4_s_p3_0}, + {0,0,&_44c4_s_p4_0},{0,0,&_44c4_s_p5_0},{0,0,&_44c4_s_p6_0}, + {&_44c4_s_p7_0,&_44c4_s_p7_1},{&_44c4_s_p8_0,&_44c4_s_p8_1}, + {&_44c4_s_p9_0,&_44c4_s_p9_1,&_44c4_s_p9_2} + } +}; +static static_bookblock _resbook_44s_5={ + { + {0},{0,0,&_44c5_s_p1_0},{0,0,&_44c5_s_p2_0},{0,0,&_44c5_s_p3_0}, + {0,0,&_44c5_s_p4_0},{0,0,&_44c5_s_p5_0},{0,0,&_44c5_s_p6_0}, + {&_44c5_s_p7_0,&_44c5_s_p7_1},{&_44c5_s_p8_0,&_44c5_s_p8_1}, + {&_44c5_s_p9_0,&_44c5_s_p9_1,&_44c5_s_p9_2} + } +}; +static static_bookblock _resbook_44s_6={ + { + {0},{0,0,&_44c6_s_p1_0},{0,0,&_44c6_s_p2_0},{0,0,&_44c6_s_p3_0}, + {0,0,&_44c6_s_p4_0}, + {&_44c6_s_p5_0,&_44c6_s_p5_1}, + {&_44c6_s_p6_0,&_44c6_s_p6_1}, + {&_44c6_s_p7_0,&_44c6_s_p7_1}, + {&_44c6_s_p8_0,&_44c6_s_p8_1}, + {&_44c6_s_p9_0,&_44c6_s_p9_1,&_44c6_s_p9_2} + } +}; +static static_bookblock _resbook_44s_7={ + { + {0},{0,0,&_44c7_s_p1_0},{0,0,&_44c7_s_p2_0},{0,0,&_44c7_s_p3_0}, + {0,0,&_44c7_s_p4_0}, + {&_44c7_s_p5_0,&_44c7_s_p5_1}, + {&_44c7_s_p6_0,&_44c7_s_p6_1}, + {&_44c7_s_p7_0,&_44c7_s_p7_1}, + {&_44c7_s_p8_0,&_44c7_s_p8_1}, + {&_44c7_s_p9_0,&_44c7_s_p9_1,&_44c7_s_p9_2} + } +}; +static static_bookblock _resbook_44s_8={ + { + {0},{0,0,&_44c8_s_p1_0},{0,0,&_44c8_s_p2_0},{0,0,&_44c8_s_p3_0}, + {0,0,&_44c8_s_p4_0}, + {&_44c8_s_p5_0,&_44c8_s_p5_1}, + {&_44c8_s_p6_0,&_44c8_s_p6_1}, + {&_44c8_s_p7_0,&_44c8_s_p7_1}, + {&_44c8_s_p8_0,&_44c8_s_p8_1}, + {&_44c8_s_p9_0,&_44c8_s_p9_1,&_44c8_s_p9_2} + } +}; +static static_bookblock _resbook_44s_9={ + { + {0},{0,0,&_44c9_s_p1_0},{0,0,&_44c9_s_p2_0},{0,0,&_44c9_s_p3_0}, + {0,0,&_44c9_s_p4_0}, + {&_44c9_s_p5_0,&_44c9_s_p5_1}, + {&_44c9_s_p6_0,&_44c9_s_p6_1}, + {&_44c9_s_p7_0,&_44c9_s_p7_1}, + {&_44c9_s_p8_0,&_44c9_s_p8_1}, + {&_44c9_s_p9_0,&_44c9_s_p9_1,&_44c9_s_p9_2} + } +}; + + +static vorbis_residue_template _res_44s_0[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c0_s_short,&_huff_book__44c0_sm_short, + &_resbook_44s_0,&_resbook_44sm_0}, + + {2,0, &_residue_44_mid, + &_huff_book__44c0_s_long,&_huff_book__44c0_sm_long, + &_resbook_44s_0,&_resbook_44sm_0} +}; +static vorbis_residue_template _res_44s_1[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c1_s_short,&_huff_book__44c1_sm_short, + &_resbook_44s_1,&_resbook_44sm_1}, + + {2,0, &_residue_44_mid, + &_huff_book__44c1_s_long,&_huff_book__44c1_sm_long, + &_resbook_44s_1,&_resbook_44sm_1} +}; +static vorbis_residue_template _res_44s_2[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c2_s_short,&_huff_book__44c2_s_short, + &_resbook_44s_2,&_resbook_44s_2}, + + {2,0, &_residue_44_mid, + &_huff_book__44c2_s_long,&_huff_book__44c2_s_long, + &_resbook_44s_2,&_resbook_44s_2} +}; +static vorbis_residue_template _res_44s_3[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c3_s_short,&_huff_book__44c3_s_short, + &_resbook_44s_3,&_resbook_44s_3}, + + {2,0, &_residue_44_mid, + &_huff_book__44c3_s_long,&_huff_book__44c3_s_long, + &_resbook_44s_3,&_resbook_44s_3} +}; +static vorbis_residue_template _res_44s_4[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c4_s_short,&_huff_book__44c4_s_short, + &_resbook_44s_4,&_resbook_44s_4}, + + {2,0, &_residue_44_mid, + &_huff_book__44c4_s_long,&_huff_book__44c4_s_long, + &_resbook_44s_4,&_resbook_44s_4} +}; +static vorbis_residue_template _res_44s_5[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c5_s_short,&_huff_book__44c5_s_short, + &_resbook_44s_5,&_resbook_44s_5}, + + {2,0, &_residue_44_mid, + &_huff_book__44c5_s_long,&_huff_book__44c5_s_long, + &_resbook_44s_5,&_resbook_44s_5} +}; +static vorbis_residue_template _res_44s_6[]={ + {2,0, &_residue_44_high, + &_huff_book__44c6_s_short,&_huff_book__44c6_s_short, + &_resbook_44s_6,&_resbook_44s_6}, + + {2,0, &_residue_44_high, + &_huff_book__44c6_s_long,&_huff_book__44c6_s_long, + &_resbook_44s_6,&_resbook_44s_6} +}; +static vorbis_residue_template _res_44s_7[]={ + {2,0, &_residue_44_high, + &_huff_book__44c7_s_short,&_huff_book__44c7_s_short, + &_resbook_44s_7,&_resbook_44s_7}, + + {2,0, &_residue_44_high, + &_huff_book__44c7_s_long,&_huff_book__44c7_s_long, + &_resbook_44s_7,&_resbook_44s_7} +}; +static vorbis_residue_template _res_44s_8[]={ + {2,0, &_residue_44_high, + &_huff_book__44c8_s_short,&_huff_book__44c8_s_short, + &_resbook_44s_8,&_resbook_44s_8}, + + {2,0, &_residue_44_high, + &_huff_book__44c8_s_long,&_huff_book__44c8_s_long, + &_resbook_44s_8,&_resbook_44s_8} +}; +static vorbis_residue_template _res_44s_9[]={ + {2,0, &_residue_44_high, + &_huff_book__44c9_s_short,&_huff_book__44c9_s_short, + &_resbook_44s_9,&_resbook_44s_9}, + + {2,0, &_residue_44_high, + &_huff_book__44c9_s_long,&_huff_book__44c9_s_long, + &_resbook_44s_9,&_resbook_44s_9} +}; + +static vorbis_mapping_template _mapres_template_44_stereo[]={ + { _map_nominal, _res_44s_0 }, /* 0 */ + { _map_nominal, _res_44s_1 }, /* 1 */ + { _map_nominal, _res_44s_2 }, /* 2 */ + { _map_nominal, _res_44s_3 }, /* 3 */ + { _map_nominal, _res_44s_4 }, /* 4 */ + { _map_nominal, _res_44s_5 }, /* 5 */ + { _map_nominal, _res_44s_6 }, /* 6 */ + { _map_nominal, _res_44s_7 }, /* 7 */ + { _map_nominal, _res_44s_8 }, /* 8 */ + { _map_nominal, _res_44s_9 }, /* 9 */ +}; diff --git a/sound/OggVorbis/vorbissrc/modes/residue_44u.h b/sound/OggVorbis/vorbissrc/modes/residue_44u.h new file mode 100644 index 000000000..58e5c8e77 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/residue_44u.h @@ -0,0 +1,296 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates for 32/44.1/48kHz uncoupled + last mod: $Id$ + + ********************************************************************/ + +#include "../vorbis/codec.h" +#include "backends.h" +#include "books/uncoupled/res_books_uncoupled.h" + +/***** residue backends *********************************************/ + + +static vorbis_info_residue0 _residue_44_low_un={ + 0,-1, -1, 8,-1, + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 28.5}, + { -1, 25, -1, 45, -1, -1, -1} +}; + +static vorbis_info_residue0 _residue_44_mid_un={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 9 */ + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 4.5, 16.5, 60.5}, + { -1, 30, -1, 50, -1, 80, -1, -1, -1} +}; + +static vorbis_info_residue0 _residue_44_hi_un={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 9 */ + {0}, + {-1}, + { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5}, + { -1, -1, -1, -1, -1, -1, -1, -1, -1} +}; + +/* mapping conventions: + only one submap (this would change for efficient 5.1 support for example)*/ +/* Four psychoacoustic profiles are used, one for each blocktype */ +static vorbis_info_mapping0 _map_nominal_u[2]={ + {1, {0,0}, {0}, {0}, 0,{0},{0}}, + {1, {0,0}, {1}, {1}, 0,{0},{0}} +}; + +static static_bookblock _resbook_44u_0={ + { + {0}, + {0,0,&_44u0__p1_0}, + {0,0,&_44u0__p2_0}, + {0,0,&_44u0__p3_0}, + {0,0,&_44u0__p4_0}, + {0,0,&_44u0__p5_0}, + {&_44u0__p6_0,&_44u0__p6_1}, + {&_44u0__p7_0,&_44u0__p7_1,&_44u0__p7_2} + } +}; +static static_bookblock _resbook_44u_1={ + { + {0}, + {0,0,&_44u1__p1_0}, + {0,0,&_44u1__p2_0}, + {0,0,&_44u1__p3_0}, + {0,0,&_44u1__p4_0}, + {0,0,&_44u1__p5_0}, + {&_44u1__p6_0,&_44u1__p6_1}, + {&_44u1__p7_0,&_44u1__p7_1,&_44u1__p7_2} + } +}; +static static_bookblock _resbook_44u_2={ + { + {0}, + {0,0,&_44u2__p1_0}, + {0,0,&_44u2__p2_0}, + {0,0,&_44u2__p3_0}, + {0,0,&_44u2__p4_0}, + {0,0,&_44u2__p5_0}, + {&_44u2__p6_0,&_44u2__p6_1}, + {&_44u2__p7_0,&_44u2__p7_1,&_44u2__p7_2} + } +}; +static static_bookblock _resbook_44u_3={ + { + {0}, + {0,0,&_44u3__p1_0}, + {0,0,&_44u3__p2_0}, + {0,0,&_44u3__p3_0}, + {0,0,&_44u3__p4_0}, + {0,0,&_44u3__p5_0}, + {&_44u3__p6_0,&_44u3__p6_1}, + {&_44u3__p7_0,&_44u3__p7_1,&_44u3__p7_2} + } +}; +static static_bookblock _resbook_44u_4={ + { + {0}, + {0,0,&_44u4__p1_0}, + {0,0,&_44u4__p2_0}, + {0,0,&_44u4__p3_0}, + {0,0,&_44u4__p4_0}, + {0,0,&_44u4__p5_0}, + {&_44u4__p6_0,&_44u4__p6_1}, + {&_44u4__p7_0,&_44u4__p7_1,&_44u4__p7_2} + } +}; +static static_bookblock _resbook_44u_5={ + { + {0}, + {0,0,&_44u5__p1_0}, + {0,0,&_44u5__p2_0}, + {0,0,&_44u5__p3_0}, + {0,0,&_44u5__p4_0}, + {0,0,&_44u5__p5_0}, + {0,0,&_44u5__p6_0}, + {&_44u5__p7_0,&_44u5__p7_1}, + {&_44u5__p8_0,&_44u5__p8_1}, + {&_44u5__p9_0,&_44u5__p9_1,&_44u5__p9_2} + } +}; +static static_bookblock _resbook_44u_6={ + { + {0}, + {0,0,&_44u6__p1_0}, + {0,0,&_44u6__p2_0}, + {0,0,&_44u6__p3_0}, + {0,0,&_44u6__p4_0}, + {0,0,&_44u6__p5_0}, + {0,0,&_44u6__p6_0}, + {&_44u6__p7_0,&_44u6__p7_1}, + {&_44u6__p8_0,&_44u6__p8_1}, + {&_44u6__p9_0,&_44u6__p9_1,&_44u6__p9_2} + } +}; +static static_bookblock _resbook_44u_7={ + { + {0}, + {0,0,&_44u7__p1_0}, + {0,0,&_44u7__p2_0}, + {0,0,&_44u7__p3_0}, + {0,0,&_44u7__p4_0}, + {0,0,&_44u7__p5_0}, + {0,0,&_44u7__p6_0}, + {&_44u7__p7_0,&_44u7__p7_1}, + {&_44u7__p8_0,&_44u7__p8_1}, + {&_44u7__p9_0,&_44u7__p9_1,&_44u7__p9_2} + } +}; +static static_bookblock _resbook_44u_8={ + { + {0}, + {0,0,&_44u8_p1_0}, + {0,0,&_44u8_p2_0}, + {0,0,&_44u8_p3_0}, + {0,0,&_44u8_p4_0}, + {&_44u8_p5_0,&_44u8_p5_1}, + {&_44u8_p6_0,&_44u8_p6_1}, + {&_44u8_p7_0,&_44u8_p7_1}, + {&_44u8_p8_0,&_44u8_p8_1}, + {&_44u8_p9_0,&_44u8_p9_1,&_44u8_p9_2} + } +}; +static static_bookblock _resbook_44u_9={ + { + {0}, + {0,0,&_44u9_p1_0}, + {0,0,&_44u9_p2_0}, + {0,0,&_44u9_p3_0}, + {0,0,&_44u9_p4_0}, + {&_44u9_p5_0,&_44u9_p5_1}, + {&_44u9_p6_0,&_44u9_p6_1}, + {&_44u9_p7_0,&_44u9_p7_1}, + {&_44u9_p8_0,&_44u9_p8_1}, + {&_44u9_p9_0,&_44u9_p9_1,&_44u9_p9_2} + } +}; + +static vorbis_residue_template _res_44u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u0__short,&_huff_book__44u0__short, + &_resbook_44u_0,&_resbook_44u_0}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u0__long,&_huff_book__44u0__long, + &_resbook_44u_0,&_resbook_44u_0} +}; +static vorbis_residue_template _res_44u_1[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u1__short,&_huff_book__44u1__short, + &_resbook_44u_1,&_resbook_44u_1}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u1__long,&_huff_book__44u1__long, + &_resbook_44u_1,&_resbook_44u_1} +}; +static vorbis_residue_template _res_44u_2[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u2__short,&_huff_book__44u2__short, + &_resbook_44u_2,&_resbook_44u_2}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u2__long,&_huff_book__44u2__long, + &_resbook_44u_2,&_resbook_44u_2} +}; +static vorbis_residue_template _res_44u_3[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u3__short,&_huff_book__44u3__short, + &_resbook_44u_3,&_resbook_44u_3}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u3__long,&_huff_book__44u3__long, + &_resbook_44u_3,&_resbook_44u_3} +}; +static vorbis_residue_template _res_44u_4[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u4__short,&_huff_book__44u4__short, + &_resbook_44u_4,&_resbook_44u_4}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u4__long,&_huff_book__44u4__long, + &_resbook_44u_4,&_resbook_44u_4} +}; + +static vorbis_residue_template _res_44u_5[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u5__short,&_huff_book__44u5__short, + &_resbook_44u_5,&_resbook_44u_5}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u5__long,&_huff_book__44u5__long, + &_resbook_44u_5,&_resbook_44u_5} +}; + +static vorbis_residue_template _res_44u_6[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u6__short,&_huff_book__44u6__short, + &_resbook_44u_6,&_resbook_44u_6}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u6__long,&_huff_book__44u6__long, + &_resbook_44u_6,&_resbook_44u_6} +}; + +static vorbis_residue_template _res_44u_7[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u7__short,&_huff_book__44u7__short, + &_resbook_44u_7,&_resbook_44u_7}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u7__long,&_huff_book__44u7__long, + &_resbook_44u_7,&_resbook_44u_7} +}; + +static vorbis_residue_template _res_44u_8[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__44u8__short,&_huff_book__44u8__short, + &_resbook_44u_8,&_resbook_44u_8}, + + {1,0, &_residue_44_hi_un, + &_huff_book__44u8__long,&_huff_book__44u8__long, + &_resbook_44u_8,&_resbook_44u_8} +}; +static vorbis_residue_template _res_44u_9[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__44u9__short,&_huff_book__44u9__short, + &_resbook_44u_9,&_resbook_44u_9}, + + {1,0, &_residue_44_hi_un, + &_huff_book__44u9__long,&_huff_book__44u9__long, + &_resbook_44u_9,&_resbook_44u_9} +}; + +static vorbis_mapping_template _mapres_template_44_uncoupled[]={ + { _map_nominal_u, _res_44u_0 }, /* 0 */ + { _map_nominal_u, _res_44u_1 }, /* 1 */ + { _map_nominal_u, _res_44u_2 }, /* 2 */ + { _map_nominal_u, _res_44u_3 }, /* 3 */ + { _map_nominal_u, _res_44u_4 }, /* 4 */ + { _map_nominal_u, _res_44u_5 }, /* 5 */ + { _map_nominal_u, _res_44u_6 }, /* 6 */ + { _map_nominal_u, _res_44u_7 }, /* 7 */ + { _map_nominal_u, _res_44u_8 }, /* 8 */ + { _map_nominal_u, _res_44u_9 }, /* 9 */ +}; diff --git a/sound/OggVorbis/vorbissrc/modes/residue_8.h b/sound/OggVorbis/vorbissrc/modes/residue_8.h new file mode 100644 index 000000000..3f6d51fe6 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/residue_8.h @@ -0,0 +1,97 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates 8/11kHz + last mod: $Id$ + + ********************************************************************/ + +#include "../vorbis/codec.h" +#include "backends.h" + +/***** residue backends *********************************************/ + +static static_bookblock _resbook_8s_0={ + { + {0},{0,0,&_8c0_s_p1_0},{0,0,&_8c0_s_p2_0},{0,0,&_8c0_s_p3_0}, + {0,0,&_8c0_s_p4_0},{0,0,&_8c0_s_p5_0},{0,0,&_8c0_s_p6_0}, + {&_8c0_s_p7_0,&_8c0_s_p7_1},{&_8c0_s_p8_0,&_8c0_s_p8_1}, + {&_8c0_s_p9_0,&_8c0_s_p9_1,&_8c0_s_p9_2} + } +}; +static static_bookblock _resbook_8s_1={ + { + {0},{0,0,&_8c1_s_p1_0},{0,0,&_8c1_s_p2_0},{0,0,&_8c1_s_p3_0}, + {0,0,&_8c1_s_p4_0},{0,0,&_8c1_s_p5_0},{0,0,&_8c1_s_p6_0}, + {&_8c1_s_p7_0,&_8c1_s_p7_1},{&_8c1_s_p8_0,&_8c1_s_p8_1}, + {&_8c1_s_p9_0,&_8c1_s_p9_1,&_8c1_s_p9_2} + } +}; + +static vorbis_residue_template _res_8s_0[]={ + {2,0, &_residue_44_mid, + &_huff_book__8c0_s_single,&_huff_book__8c0_s_single, + &_resbook_8s_0,&_resbook_8s_0}, +}; +static vorbis_residue_template _res_8s_1[]={ + {2,0, &_residue_44_mid, + &_huff_book__8c1_s_single,&_huff_book__8c1_s_single, + &_resbook_8s_1,&_resbook_8s_1}, +}; + +static vorbis_mapping_template _mapres_template_8_stereo[2]={ + { _map_nominal, _res_8s_0 }, /* 0 */ + { _map_nominal, _res_8s_1 }, /* 1 */ +}; + +static static_bookblock _resbook_8u_0={ + { + {0}, + {0,0,&_8u0__p1_0}, + {0,0,&_8u0__p2_0}, + {0,0,&_8u0__p3_0}, + {0,0,&_8u0__p4_0}, + {0,0,&_8u0__p5_0}, + {&_8u0__p6_0,&_8u0__p6_1}, + {&_8u0__p7_0,&_8u0__p7_1,&_8u0__p7_2} + } +}; +static static_bookblock _resbook_8u_1={ + { + {0}, + {0,0,&_8u1__p1_0}, + {0,0,&_8u1__p2_0}, + {0,0,&_8u1__p3_0}, + {0,0,&_8u1__p4_0}, + {0,0,&_8u1__p5_0}, + {0,0,&_8u1__p6_0}, + {&_8u1__p7_0,&_8u1__p7_1}, + {&_8u1__p8_0,&_8u1__p8_1}, + {&_8u1__p9_0,&_8u1__p9_1,&_8u1__p9_2} + } +}; + +static vorbis_residue_template _res_8u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__8u0__single,&_huff_book__8u0__single, + &_resbook_8u_0,&_resbook_8u_0}, +}; +static vorbis_residue_template _res_8u_1[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__8u1__single,&_huff_book__8u1__single, + &_resbook_8u_1,&_resbook_8u_1}, +}; + +static vorbis_mapping_template _mapres_template_8_uncoupled[2]={ + { _map_nominal_u, _res_8u_0 }, /* 0 */ + { _map_nominal_u, _res_8u_1 }, /* 1 */ +}; diff --git a/sound/OggVorbis/vorbissrc/modes/setup_11.h b/sound/OggVorbis/vorbissrc/modes/setup_11.h new file mode 100644 index 000000000..07658f637 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_11.h @@ -0,0 +1,141 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 11kHz settings + last mod: $Id$ + + ********************************************************************/ + +#include "psych_11.h" + +static int blocksize_11[2]={ + 512,512 +}; + +static int _floor_mapping_11[2]={ + 1,1, +}; + +static double rate_mapping_11[3]={ + 8000.,13000.,44000., +}; + +static double rate_mapping_11_uncoupled[3]={ + 12000.,20000.,50000., +}; + +static double quality_mapping_11[3]={ + -.1,.0,1. +}; + +ve_setup_data_template ve_setup_11_stereo={ + 2, + rate_mapping_11, + quality_mapping_11, + 2, + 9000, + 15000, + + blocksize_11, + blocksize_11, + + _psy_tone_masteratt_11, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_11, + NULL, + _vp_tonemask_adj_11, + + _psy_noiseguards_8, + _psy_noisebias_11, + _psy_noisebias_11, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_11, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_11, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_11, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_11_uncoupled={ + 2, + rate_mapping_11_uncoupled, + quality_mapping_11, + -1, + 9000, + 15000, + + blocksize_11, + blocksize_11, + + _psy_tone_masteratt_11, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_11, + NULL, + _vp_tonemask_adj_11, + + _psy_noiseguards_8, + _psy_noisebias_11, + _psy_noisebias_11, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_11, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_11, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_11, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/sound/OggVorbis/vorbissrc/modes/setup_16.h b/sound/OggVorbis/vorbissrc/modes/setup_16.h new file mode 100644 index 000000000..87f998ce2 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_16.h @@ -0,0 +1,149 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 16kHz settings + last mod: $Id$ + + ********************************************************************/ + +#include "psych_16.h" +#include "residue_16.h" + +static int blocksize_16_short[3]={ + 1024,512,512 +}; +static int blocksize_16_long[3]={ + 1024,1024,1024 +}; + +static int _floor_mapping_16_short[3]={ + 9,3,3 +}; +static int _floor_mapping_16[3]={ + 9,9,9 +}; + +static double rate_mapping_16[4]={ + 12000.,20000.,44000.,86000. +}; + +static double rate_mapping_16_uncoupled[4]={ + 16000.,28000.,64000.,100000. +}; + +static double _global_mapping_16[4]={ 1., 2., 3., 4. }; + +static double quality_mapping_16[4]={ -.1,.05,.5,1. }; + +static double _psy_compand_16_mapping[4]={ 0., .8, 1., 1.}; + +ve_setup_data_template ve_setup_16_stereo={ + 3, + rate_mapping_16, + quality_mapping_16, + 2, + 15000, + 19000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_16_mapping, + _psy_compand_16_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_16, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_stereo +}; + +ve_setup_data_template ve_setup_16_uncoupled={ + 3, + rate_mapping_16_uncoupled, + quality_mapping_16, + -1, + 15000, + 19000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_16_mapping, + _psy_compand_16_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_16, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_uncoupled +}; diff --git a/sound/OggVorbis/vorbissrc/modes/setup_22.h b/sound/OggVorbis/vorbissrc/modes/setup_22.h new file mode 100644 index 000000000..f45c8082b --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_22.h @@ -0,0 +1,128 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 22kHz settings + last mod: $Id$ + + ********************************************************************/ + +static double rate_mapping_22[4]={ + 15000.,20000.,44000.,86000. +}; + +static double rate_mapping_22_uncoupled[4]={ + 16000.,28000.,50000.,90000. +}; + +static double _psy_lowpass_22[4]={9.5,11.,30.,99.}; + +ve_setup_data_template ve_setup_22_stereo={ + 3, + rate_mapping_22, + quality_mapping_16, + 2, + 19000, + 26000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + _psy_compand_8_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_22, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_stereo +}; + +ve_setup_data_template ve_setup_22_uncoupled={ + 3, + rate_mapping_22_uncoupled, + quality_mapping_16, + -1, + 19000, + 26000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + _psy_compand_8_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_22, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_uncoupled +}; diff --git a/sound/OggVorbis/vorbissrc/modes/setup_32.h b/sound/OggVorbis/vorbissrc/modes/setup_32.h new file mode 100644 index 000000000..17263444b --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_32.h @@ -0,0 +1,246 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 32kHz + last mod: $Id$ + + ********************************************************************/ + +static double rate_mapping_32[11]={ + 28000.,35000.,45000.,56000.,60000., + 75000.,90000.,100000.,115000.,150000.,190000., +}; + +static double rate_mapping_32_un[11]={ + 42000.,52000.,64000.,72000.,78000., + 86000.,92000.,110000.,120000.,140000.,190000., +}; + +static double rate_mapping_32_low[2]={ + 20000.,28000. +}; + +static double rate_mapping_32_un_low[2]={ + 24000.,42000., +}; + +static double _psy_lowpass_32_low[2]={ + 13.,13., +}; +static double _psy_lowpass_32[11]={ + 13.,13.,14.,15.,99.,99.,99.,99.,99.,99.,99. +}; + +ve_setup_data_template ve_setup_32_stereo={ + 10, + rate_mapping_32, + quality_mapping_44, + 2, + 26000, + 40000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + +ve_setup_data_template ve_setup_32_uncoupled={ + 10, + rate_mapping_32_un, + quality_mapping_44, + -1, + 26000, + 40000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; + +ve_setup_data_template ve_setup_32_stereo_low={ + 1, + rate_mapping_32_low, + quality_mapping_44_stereo_low, + 2, + 26000, + 40000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32_low, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44_low, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_stereo +}; + + +ve_setup_data_template ve_setup_32_uncoupled_low={ + 1, + rate_mapping_32_un_low, + quality_mapping_44_stereo_low, + -1, + 26000, + 40000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32_low, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_uncoupled +}; diff --git a/sound/OggVorbis/vorbissrc/modes/setup_44.h b/sound/OggVorbis/vorbissrc/modes/setup_44.h new file mode 100644 index 000000000..1bca77a43 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_44.h @@ -0,0 +1,176 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 44.1/48kHz + last mod: $Id$ + + ********************************************************************/ + +#include "modes/floor_all.h" +#include "modes/residue_44.h" +#include "modes/psych_44.h" + +static double rate_mapping_44_stereo_low[2]={ + 22500.,32000. +}; + +static double rate_mapping_44_stereo[11]={ + 32000.,40000.,48000.,56000.,64000., + 80000.,96000.,112000.,128000.,160000.,250001. +}; +static double quality_mapping_44_stereo_low[2]={ + -.1,.0, +}; +static double quality_mapping_44[11]={ + .0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0 +}; + +static int blocksize_short_44_low[1]={ + 512 +}; +static int blocksize_long_44_low[1]={ + 4096 +}; + +static int blocksize_short_44[10]={ + 256,256,256,256,256,256,256,256,256,256 +}; +static int blocksize_long_44[10]={ + 2048,2048,2048,2048,2048,2048,2048,2048,2048,2048 +}; +static double _psy_compand_short_mapping[11]={ + 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2. +}; +static double _psy_compand_long_mapping[11]={ + 4., 4., 4.3, 4.6, 5., 5., 5., 5., 5., 5., 5. +}; +static double _global_mapping_44[11]={ + 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.5, 4., 4. +}; +static double _global_mapping_44_low[2]={ + 0., 1., +}; +static int _floor_short_mapping_44_low[1]={ + 1, +}; +static int _floor_long_mapping_44_low[1]={ + 8 +}; +static int _floor_short_mapping_44[10]={ + 0,0,2,2,4,5,5,5,5,5 +}; +static int _floor_long_mapping_44[10]={ + 7,7,7,7,7,7,7,7,7,7 +}; + +ve_setup_data_template ve_setup_44_stereo={ + 10, + rate_mapping_44_stereo, + quality_mapping_44, + 2, + 40000, + 50000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + +ve_setup_data_template ve_setup_44_stereo_low={ + 1, + rate_mapping_44_stereo_low, + quality_mapping_44_stereo_low, + 2, + 40000, + 50000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44_low, + + _psy_global_44, + _global_mapping_44_low, + _psy_stereo_modes_44_low, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_stereo +}; + diff --git a/sound/OggVorbis/vorbissrc/modes/setup_44u.h b/sound/OggVorbis/vorbissrc/modes/setup_44u.h new file mode 100644 index 000000000..5ddd88c7c --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_44u.h @@ -0,0 +1,129 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 44.1/48kHz uncoupled modes + last mod: $Id$ + + ********************************************************************/ + +#include "modes/residue_44u.h" + +static double rate_mapping_44_un[11]={ + 48000.,60000.,70000.,80000.,86000., + 96000.,110000.,120000.,140000.,160000.,240001. +}; + +static double rate_mapping_44_un_low[2]={ + 32000.,48000. +}; + +ve_setup_data_template ve_setup_44_uncoupled={ + 10, + rate_mapping_44_un, + quality_mapping_44, + -1, + 40000, + 50000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; + +ve_setup_data_template ve_setup_44_uncoupled_low={ + 1, + rate_mapping_44_un_low, + quality_mapping_44_stereo_low, + -1, + 40000, + 50000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44_low, + + _psy_global_44, + _global_mapping_44_low, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_uncoupled +}; diff --git a/sound/OggVorbis/vorbissrc/modes/setup_8.h b/sound/OggVorbis/vorbissrc/modes/setup_8.h new file mode 100644 index 000000000..4cbf73a55 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_8.h @@ -0,0 +1,146 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 8kHz settings + last mod: $Id$ + + ********************************************************************/ + +#include "psych_8.h" +#include "residue_8.h" + +static int blocksize_8[2]={ + 512,512 +}; + +static int _floor_mapping_8[2]={ + 1,1, +}; + +static double rate_mapping_8[3]={ + 6000.,9000.,32000., +}; + +static double rate_mapping_8_uncoupled[3]={ + 8000.,14000.,42000., +}; + +static double quality_mapping_8[3]={ + -.1,.0,1. +}; + +static double _psy_compand_8_mapping[3]={ 0., 1., 1.}; + +static double _global_mapping_8[3]={ 1., 2., 3. }; + +ve_setup_data_template ve_setup_8_stereo={ + 2, + rate_mapping_8, + quality_mapping_8, + 2, + 8000, + 9000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_44_2, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_8_uncoupled={ + 2, + rate_mapping_8_uncoupled, + quality_mapping_8, + -1, + 8000, + 9000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_44_2, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/sound/OggVorbis/vorbissrc/modes/setup_X.h b/sound/OggVorbis/vorbissrc/modes/setup_X.h new file mode 100644 index 000000000..df8dd4188 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/modes/setup_X.h @@ -0,0 +1,329 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: catch-all toplevel settings for q modes only + last mod: $Id$ + + ********************************************************************/ + +static double rate_mapping_X[11]={ + -1.,-1.,-1.,-1.,-1., + -1.,-1.,-1.,-1.,-1.,-1. +}; + +ve_setup_data_template ve_setup_X_stereo={ + 10, + rate_mapping_X, + quality_mapping_44, + 2, + 50000, + 200000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + +ve_setup_data_template ve_setup_X_uncoupled={ + 10, + rate_mapping_X, + quality_mapping_44, + -1, + 50000, + 200000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; + +ve_setup_data_template ve_setup_X_stereo_low={ + 1, + rate_mapping_X, + quality_mapping_44_stereo_low, + 2, + 50000, + 200000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44_low, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44_low, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_stereo +}; + + +ve_setup_data_template ve_setup_X_uncoupled_low={ + 1, + rate_mapping_X, + quality_mapping_44_stereo_low, + -1, + 50000, + 200000, + + blocksize_short_44_low, + blocksize_long_44_low, + + _psy_tone_masteratt_44_low, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_trans_low, + _psy_noisebias_long_low, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44_low,_noise_start_long_44_low}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44_2, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44_low, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44_low, + _floor_long_mapping_44_low, + + _mapres_template_44_uncoupled +}; + +ve_setup_data_template ve_setup_XX_stereo={ + 2, + rate_mapping_X, + quality_mapping_8, + 2, + 0, + 8000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_44_2, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_XX_uncoupled={ + 2, + rate_mapping_X, + quality_mapping_8, + -1, + 0, + 8000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_44_2, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/sound/OggVorbis/vorbissrc/os.h b/sound/OggVorbis/vorbissrc/os.h new file mode 100644 index 000000000..d0b958b8c --- /dev/null +++ b/sound/OggVorbis/vorbissrc/os.h @@ -0,0 +1,147 @@ +#ifndef _OS_H +#define _OS_H +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id$ + + ********************************************************************/ + +#include +#include "../ogg/os_types.h" + +#include "misc.h" + +#ifndef _V_IFDEFJAIL_H_ +# define _V_IFDEFJAIL_H_ + +# ifdef __GNUC__ +# define STIN static __inline__ +# elif _WIN32 +# define STIN static __inline +# else +# define STIN static +# endif + +#ifdef DJGPP +# define rint(x) (floor((x)+0.5f)) +#endif + +#ifndef M_PI +# define M_PI (3.1415926536f) +#endif + +#ifdef _WIN32 +# include +# define rint(x) (floor((x)+0.5f)) +# define NO_FLOAT_MATH_LIB +# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b)) +#endif + +#ifndef FAST_HYPOT +# define FAST_HYPOT hypot +#endif + +#endif + +#ifdef HAVE_ALLOCA_H +# include +#endif + +#ifdef USE_MEMORY_H +# include +#endif + +#ifndef min +# define min(x,y) ((x)>(y)?(y):(x)) +#endif + +#ifndef max +# define max(x,y) ((x)<(y)?(y):(x)) +#endif + +#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) +# define VORBIS_FPU_CONTROL +/* both GCC and MSVC are kinda stupid about rounding/casting to int. + Because of encapsulation constraints (GCC can't see inside the asm + block and so we end up doing stupid things like a store/load that + is collectively a noop), we do it this way */ + +/* we must set up the fpu before this works!! */ + +typedef ogg_int16_t vorbis_fpu_control; + +static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ + ogg_int16_t ret; + ogg_int16_t temp; + __asm__ __volatile__("fnstcw %0\n\t" + "movw %0,%%dx\n\t" + "orw $62463,%%dx\n\t" + "movw %%dx,%1\n\t" + "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx"); + *fpu=ret; +} + +static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ + __asm__ __volatile__("fldcw %0":: "m"(fpu)); +} + +/* assumes the FPU is in round mode! */ +static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise, + we get extra fst/fld to + truncate precision */ + int i; + __asm__("fistl %0": "=m"(i) : "t"(f)); + return(i); +} +#endif + + +#if defined(_WIN32) && !defined(__GNUC__) && !defined(__BORLANDC__) +# define VORBIS_FPU_CONTROL + +typedef ogg_int16_t vorbis_fpu_control; + +static __inline int vorbis_ftoi(double f){ + int i; + __asm{ + fld f + fistp i + } + return i; +} + +static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ +} + +static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ +} + +#endif + + +#ifndef VORBIS_FPU_CONTROL + +typedef int vorbis_fpu_control; + +static int vorbis_ftoi(double f){ + return (int)(f+.5); +} + +/* We don't have special code for this compiler/arch, so do it the slow way */ +# define vorbis_fpu_setround(vorbis_fpu_control) {} +# define vorbis_fpu_restore(vorbis_fpu_control) {} + +#endif + +#endif /* _OS_H */ diff --git a/sound/OggVorbis/vorbissrc/psy.c b/sound/OggVorbis/vorbissrc/psy.c new file mode 100644 index 000000000..71f87a838 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/psy.c @@ -0,0 +1,1148 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: psychoacoustics not including preecho + last mod: $Id: psy.c,v 1.81 2002/10/21 07:00:11 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../vorbis/codec.h" +#include "codec_internal.h" + +#include "masking.h" +#include "psy.h" +#include "os.h" +#include "lpc.h" +#include "smallft.h" +#include "scales.h" +#include "misc.h" + +#define NEGINF -9999.f +static double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10}; + +vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look)); + + look->channels=vi->channels; + + look->ampmax=-9999.; + look->gi=gi; + return(look); +} + +void _vp_global_free(vorbis_look_psy_global *look){ + if(look){ + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +void _vi_gpsy_free(vorbis_info_psy_global *i){ + if(i){ + memset(i,0,sizeof(*i)); + _ogg_free(i); + } +} + +void _vi_psy_free(vorbis_info_psy *i){ + if(i){ + memset(i,0,sizeof(*i)); + _ogg_free(i); + } +} + +static void min_curve(float *c, + float *c2){ + int i; + for(i=0;ic[i])c[i]=c2[i]; +} + +static void attenuate_curve(float *c,float att){ + int i; + for(i=0;iATH[j+k+ath_offset])min=ATH[j+k+ath_offset]; + }else{ + if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1]; + } + ath[j]=min; + } + + /* copy curves into working space, replicate the 50dB curve to 30 + and 40, replicate the 100dB curve to 110 */ + for(j=0;j<6;j++) + memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j])); + memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); + memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); + + /* apply centered curve boost/decay */ + for(j=0;j0)adj=0.; + if(adj>0. && center_boost<0)adj=0.; + workc[i][j][k]+=adj; + } + } + + /* normalize curves so the driving amplitude is 0dB */ + /* make temp curves with the ATH overlayed */ + for(j=0;j an eighth of an octave and that the eighth + octave values may also be composited. */ + + /* which octave curves will we be compositing? */ + bin=floor(fromOC(i*.5)/binHz); + lo_curve= ceil(toOC(bin*binHz+1)*2); + hi_curve= floor(toOC((bin+1)*binHz)*2); + if(lo_curve>i)lo_curve=i; + if(lo_curve<0)lo_curve=0; + if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1; + + for(m=0;mn)lo_bin=n; + if(lo_binn)hi_bin=n; + + for(;lworkc[k][m][j]) + brute_buffer[l]=workc[k][m][j]; + } + + for(;lworkc[k][m][EHMER_MAX-1]) + brute_buffer[l]=workc[k][m][EHMER_MAX-1]; + + } + + /* be equally paranoid about being valid up to next half ocatve */ + if(i+1n)lo_bin=n; + if(lo_binn)hi_bin=n; + + for(;lworkc[k][m][j]) + brute_buffer[l]=workc[k][m][j]; + } + + for(;lworkc[k][m][EHMER_MAX-1]) + brute_buffer[l]=workc[k][m][EHMER_MAX-1]; + + } + + + for(j=0;j=n){ + ret[i][m][j+2]=-999.; + }else{ + ret[i][m][j+2]=brute_buffer[bin]; + } + } + } + + /* add fenceposts */ + for(j=0;j-200.f)break; + ret[i][m][0]=j; + + for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--) + if(ret[i][m][j+2]>-200.f) + break; + ret[i][m][1]=j; + + } + } + + return(ret); +} + +void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, + vorbis_info_psy_global *gi,int n,long rate){ + long i,j,lo=-99,hi=1; + long maxoc; + memset(p,0,sizeof(*p)); + + p->eighth_octave_lines=gi->eighth_octave_lines; + p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1; + + p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines; + maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f; + p->total_octave_lines=maxoc-p->firstoc+1; + p->ath=_ogg_malloc(n*sizeof(*p->ath)); + + p->octave=_ogg_malloc(n*sizeof(*p->octave)); + p->bark=_ogg_malloc(n*sizeof(*p->bark)); + p->vi=vi; + p->n=n; + p->rate=rate; + + /* set up the lookups for a given blocksize and sample rate */ + + for(i=0,j=0;iath[j]=base+100.; + base+=delta; + } + } + } + + for(i=0;inoisewindowlominnoisewindowlo);lo++); + + for(;hi<=n && (hinoisewindowhimin || + toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++); + + p->bark[i]=((lo-1)<<16)+(hi-1); + + } + + for(i=0;ioctave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f; + + p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n, + vi->tone_centerboost,vi->tone_decay); + + /* set up rolling noise median */ + p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset)); + for(i=0;inoiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset)); + + for(i=0;i=P_BANDS-1)halfoc=P_BANDS-1; + inthalfoc=(int)halfoc; + del=halfoc-inthalfoc; + + for(j=0;jnoiseoffset[j][i]= + p->vi->noiseoff[j][inthalfoc]*(1.-del) + + p->vi->noiseoff[j][inthalfoc+1]*del; + + } +#if 0 + { + static int ls=0; + _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0); + _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0); + _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0); + } +#endif +} + +void _vp_psy_clear(vorbis_look_psy *p){ + int i,j; + if(p){ + if(p->ath)_ogg_free(p->ath); + if(p->octave)_ogg_free(p->octave); + if(p->bark)_ogg_free(p->bark); + if(p->tonecurves){ + for(i=0;itonecurves[i][j]); + } + _ogg_free(p->tonecurves[i]); + } + _ogg_free(p->tonecurves); + } + if(p->noiseoffset){ + for(i=0;inoiseoffset[i]); + } + _ogg_free(p->noiseoffset); + } + memset(p,0,sizeof(*p)); + } +} + +/* octave/(8*eighth_octave_lines) x scale and dB y scale */ +static void seed_curve(float *seed, + const float **curves, + float amp, + int oc, int n, + int linesper,float dBoffset){ + int i,post1; + int seedptr; + const float *posts,*curve; + + int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f); + choice=max(choice,0); + choice=min(choice,P_LEVELS-1); + posts=curves[choice]; + curve=posts+2; + post1=(int)posts[1]; + seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1); + + for(i=posts[0];i0){ + float lin=amp+curve[i]; + if(seed[seedptr]=n)break; + } +} + +static void seed_loop(vorbis_look_psy *p, + const float ***curves, + const float *f, + const float *flr, + float *seed, + float specmax){ + vorbis_info_psy *vi=p->vi; + long n=p->n,i; + float dBoffset=vi->max_curve_dB-specmax; + + /* prime the working vector with peak values */ + + for(i=0;ioctave[i]; + while(i+1octave[i+1]==oc){ + i++; + if(f[i]>max)max=f[i]; + } + + if(max+6.f>flr[i]){ + oc=oc>>p->shiftoc; + + if(oc>=P_BANDS)oc=P_BANDS-1; + if(oc<0)oc=0; + + seed_curve(seed, + curves[oc], + max, + p->octave[i]-p->firstoc, + p->total_octave_lines, + p->eighth_octave_lines, + dBoffset); + } + } +} + +static void seed_chase(float *seeds, int linesper, long n){ + long *posstack=alloca(n*sizeof(*posstack)); + float *ampstack=alloca(n*sizeof(*ampstack)); + long stack=0; + long pos=0; + long i; + + for(i=0;i1 && ampstack[stack-1]<=ampstack[stack-2] && + iampstack[i]){ + endpos=posstack[i+1]; + }else{ + endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is + discarded in short frames */ + } + if(endpos>n)endpos=n; + for(;pos +static void max_seeds(vorbis_look_psy *p, + float *seed, + float *flr){ + long n=p->total_octave_lines; + int linesper=p->eighth_octave_lines; + long linpos=0; + long pos; + + seed_chase(seed,linesper,n); /* for masking */ + + pos=p->octave[0]-p->firstoc-(linesper>>1); + + while(linpos+1n){ + float minV=seed[pos]; + long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc; + if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit; + while(pos+1<=end){ + pos++; + if((seed[pos]>NEGINF && seed[pos]firstoc; + for(;linposn && p->octave[linpos]<=end;linpos++) + if(flr[linpos]total_octave_lines-1]; + for(;linposn;linpos++) + if(flr[linpos]> 16; + if( lo>=0 ) break; + hi = b[i] & 0xffff; + + tN = N[hi] + N[-lo]; + tX = X[hi] - X[-lo]; + tXX = XX[hi] + XX[-lo]; + tY = Y[hi] + Y[-lo]; + tXY = XY[hi] - XY[-lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + if (R < 0.f) + R = 0.f; + + noise[i] = R - offset; + } + + for ( ;; i++, x += 1.f) { + + lo = b[i] >> 16; + hi = b[i] & 0xffff; + if(hi>=n)break; + + tN = N[hi] - N[lo]; + tX = X[hi] - X[lo]; + tXX = XX[hi] - XX[lo]; + tY = Y[hi] - Y[lo]; + tXY = XY[hi] - XY[lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + if (R < 0.f) R = 0.f; + + noise[i] = R - offset; + } + for ( ; i < n; i++, x += 1.f) { + + R = (A + x * B) / D; + if (R < 0.f) R = 0.f; + + noise[i] = R - offset; + } + + if (fixed <= 0) return; + + for (i = 0, x = 0.f;; i++, x += 1.f) { + hi = i + fixed / 2; + lo = hi - fixed; + if(lo>=0)break; + + tN = N[hi] + N[-lo]; + tX = X[hi] - X[-lo]; + tXX = XX[hi] + XX[-lo]; + tY = Y[hi] + Y[-lo]; + tXY = XY[hi] - XY[-lo]; + + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + + if (R - offset < noise[i]) noise[i] = R - offset; + } + for ( ;; i++, x += 1.f) { + + hi = i + fixed / 2; + lo = hi - fixed; + if(hi>=n)break; + + tN = N[hi] - N[lo]; + tX = X[hi] - X[lo]; + tXX = XX[hi] - XX[lo]; + tY = Y[hi] - Y[lo]; + tXY = XY[hi] - XY[lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + + if (R - offset < noise[i]) noise[i] = R - offset; + } + for ( ; i < n; i++, x += 1.f) { + R = (A + x * B) / D; + if (R - offset < noise[i]) noise[i] = R - offset; + } +} + +static float FLOOR1_fromdB_INV_LOOKUP[256]={ + 0.F, 8.81683e+06F, 8.27882e+06F, 7.77365e+06F, + 7.29930e+06F, 6.85389e+06F, 6.43567e+06F, 6.04296e+06F, + 5.67422e+06F, 5.32798e+06F, 5.00286e+06F, 4.69759e+06F, + 4.41094e+06F, 4.14178e+06F, 3.88905e+06F, 3.65174e+06F, + 3.42891e+06F, 3.21968e+06F, 3.02321e+06F, 2.83873e+06F, + 2.66551e+06F, 2.50286e+06F, 2.35014e+06F, 2.20673e+06F, + 2.07208e+06F, 1.94564e+06F, 1.82692e+06F, 1.71544e+06F, + 1.61076e+06F, 1.51247e+06F, 1.42018e+06F, 1.33352e+06F, + 1.25215e+06F, 1.17574e+06F, 1.10400e+06F, 1.03663e+06F, + 973377.F, 913981.F, 858210.F, 805842.F, + 756669.F, 710497.F, 667142.F, 626433.F, + 588208.F, 552316.F, 518613.F, 486967.F, + 457252.F, 429351.F, 403152.F, 378551.F, + 355452.F, 333762.F, 313396.F, 294273.F, + 276316.F, 259455.F, 243623.F, 228757.F, + 214798.F, 201691.F, 189384.F, 177828.F, + 166977.F, 156788.F, 147221.F, 138237.F, + 129802.F, 121881.F, 114444.F, 107461.F, + 100903.F, 94746.3F, 88964.9F, 83536.2F, + 78438.8F, 73652.5F, 69158.2F, 64938.1F, + 60975.6F, 57254.9F, 53761.2F, 50480.6F, + 47400.3F, 44507.9F, 41792.0F, 39241.9F, + 36847.3F, 34598.9F, 32487.7F, 30505.3F, + 28643.8F, 26896.0F, 25254.8F, 23713.7F, + 22266.7F, 20908.0F, 19632.2F, 18434.2F, + 17309.4F, 16253.1F, 15261.4F, 14330.1F, + 13455.7F, 12634.6F, 11863.7F, 11139.7F, + 10460.0F, 9821.72F, 9222.39F, 8659.64F, + 8131.23F, 7635.06F, 7169.17F, 6731.70F, + 6320.93F, 5935.23F, 5573.06F, 5232.99F, + 4913.67F, 4613.84F, 4332.30F, 4067.94F, + 3819.72F, 3586.64F, 3367.78F, 3162.28F, + 2969.31F, 2788.13F, 2617.99F, 2458.24F, + 2308.24F, 2167.39F, 2035.14F, 1910.95F, + 1794.35F, 1684.85F, 1582.04F, 1485.51F, + 1394.86F, 1309.75F, 1229.83F, 1154.78F, + 1084.32F, 1018.15F, 956.024F, 897.687F, + 842.910F, 791.475F, 743.179F, 697.830F, + 655.249F, 615.265F, 577.722F, 542.469F, + 509.367F, 478.286F, 449.101F, 421.696F, + 395.964F, 371.803F, 349.115F, 327.812F, + 307.809F, 289.026F, 271.390F, 254.830F, + 239.280F, 224.679F, 210.969F, 198.096F, + 186.008F, 174.658F, 164.000F, 153.993F, + 144.596F, 135.773F, 127.488F, 119.708F, + 112.404F, 105.545F, 99.1046F, 93.0572F, + 87.3788F, 82.0469F, 77.0404F, 72.3394F, + 67.9252F, 63.7804F, 59.8885F, 56.2341F, + 52.8027F, 49.5807F, 46.5553F, 43.7144F, + 41.0470F, 38.5423F, 36.1904F, 33.9821F, + 31.9085F, 29.9614F, 28.1332F, 26.4165F, + 24.8045F, 23.2910F, 21.8697F, 20.5352F, + 19.2822F, 18.1056F, 17.0008F, 15.9634F, + 14.9893F, 14.0746F, 13.2158F, 12.4094F, + 11.6522F, 10.9411F, 10.2735F, 9.64662F, + 9.05798F, 8.50526F, 7.98626F, 7.49894F, + 7.04135F, 6.61169F, 6.20824F, 5.82941F, + 5.47370F, 5.13970F, 4.82607F, 4.53158F, + 4.25507F, 3.99542F, 3.75162F, 3.52269F, + 3.30774F, 3.10590F, 2.91638F, 2.73842F, + 2.57132F, 2.41442F, 2.26709F, 2.12875F, + 1.99885F, 1.87688F, 1.76236F, 1.65482F, + 1.55384F, 1.45902F, 1.36999F, 1.28640F, + 1.20790F, 1.13419F, 1.06499F, 1.F +}; + +void _vp_remove_floor(vorbis_look_psy *p, + float *mdct, + int *codedflr, + float *residue, + int sliding_lowpass){ + + int i,n=p->n; + + if(sliding_lowpass>n)sliding_lowpass=n; + + for(i=0;in; + float *work=alloca(n*sizeof(*work)); + + bark_noise_hybridmp(n,p->bark,logmdct,logmask, + 140.,-1); + + for(i=0;ibark,work,logmask,0., + p->vi->noisewindowfixed); + + for(i=0;i=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1; + if(dB<0)dB=0; + logmask[i]= work[i]+p->vi->noisecompand[dB]; + } + +} + +void _vp_tonemask(vorbis_look_psy *p, + float *logfft, + float *logmask, + float global_specmax, + float local_specmax){ + + int i,n=p->n; + + float *seed=alloca(sizeof(*seed)*p->total_octave_lines); + float att=local_specmax+p->vi->ath_adjatt; + for(i=0;itotal_octave_lines;i++)seed[i]=NEGINF; + + /* set the ATH (floating below localmax, not global max by a + specified att) */ + if(attvi->ath_maxatt)att=p->vi->ath_maxatt; + + for(i=0;iath[i]+att; + + /* tone masking */ + seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax); + max_seeds(p,seed,logmask); + +} + +void _vp_offset_and_mix(vorbis_look_psy *p, + float *noise, + float *tone, + int offset_select, + float *logmask){ + int i,n=p->n; + float toneatt=p->vi->tone_masteratt[offset_select]; + + for(i=0;inoiseoffset[offset_select][i]; + if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp; + logmask[i]=max(val,tone[i]+toneatt); + } +} + +float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){ + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + + int n=ci->blocksizes[vd->W]/2; + float secs=(float)n/vi->rate; + + amp+=secs*gi->ampmax_att_per_sec; + if(amp<-9999)amp=-9999; + return(amp); +} + +static void couple_lossless(float A, float B, + float *qA, float *qB){ + int test1=fabs(*qA)>fabs(*qB); + test1-= fabs(*qA)fabs(B))<<1)-1; + if(test1==1){ + *qB=(*qA>0.f?*qA-*qB:*qB-*qA); + }else{ + float temp=*qB; + *qB=(*qB>0.f?*qA-*qB:*qB-*qA); + *qA=temp; + } + + if(*qB>fabs(*qA)*1.9999f){ + *qB= -fabs(*qA)*2.f; + *qA= -*qA; + } +} + +static float hypot_lookup[32]={ + -0.009935, -0.011245, -0.012726, -0.014397, + -0.016282, -0.018407, -0.020800, -0.023494, + -0.026522, -0.029923, -0.033737, -0.038010, + -0.042787, -0.048121, -0.054064, -0.060671, + -0.068000, -0.076109, -0.085054, -0.094892, + -0.105675, -0.117451, -0.130260, -0.144134, + -0.159093, -0.175146, -0.192286, -0.210490, + -0.229718, -0.249913, -0.271001, -0.292893}; + +static void precomputed_couple_point(float premag, + int floorA,int floorB, + float *mag, float *ang){ + + int test=(floorA>floorB)-1; + int offset=31-abs(floorA-floorB); + float floormag=hypot_lookup[((offset<0)-1)&offset]+1.f; + + floormag*=FLOOR1_fromdB_INV_LOOKUP[(floorB&test)|(floorA&(~test))]; + + *mag=premag*floormag; + *ang=0.f; +} + +/* just like below, this is currently set up to only do + single-step-depth coupling. Otherwise, we'd have to do more + copying (which will be inevitable later) */ + +/* doing the real circular magnitude calculation is audibly superior + to (A+B)/sqrt(2) */ +static float dipole_hypot(float a, float b){ + if(a>0.){ + if(b>0.)return sqrt(a*a+b*b); + if(a>-b)return sqrt(a*a-b*b); + return -sqrt(b*b-a*a); + } + if(b<0.)return -sqrt(a*a+b*b); + if(-a>b)return -sqrt(a*a-b*b); + return sqrt(b*b-a*a); +} +static float round_hypot(float a, float b){ + if(a>0.){ + if(b>0.)return sqrt(a*a+b*b); + if(a>-b)return sqrt(a*a+b*b); + return -sqrt(b*b+a*a); + } + if(b<0.)return -sqrt(a*a+b*b); + if(-a>b)return -sqrt(a*a+b*b); + return sqrt(b*b+a*a); +} + +/* revert to round hypot for now */ +float **_vp_quantize_couple_memo(vorbis_block *vb, + vorbis_info_psy_global *g, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mdct){ + + int i,j,n=p->n; + float **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); + int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2]; + + for(i=0;icoupling_steps;i++){ + float *mdctM=mdct[vi->coupling_mag[i]]; + float *mdctA=mdct[vi->coupling_ang[i]]; + ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); + for(j=0;jf2); +} + +int **_vp_quantize_couple_sort(vorbis_block *vb, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mags){ + + + if(p->vi->normal_point_p){ + int i,j,k,n=p->n; + int **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); + int partition=p->vi->normal_partition; + float **work=alloca(sizeof(*work)*partition); + + for(i=0;icoupling_steps;i++){ + ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); + + for(j=0;jn; + vorbis_info_psy *vi=p->vi; + int partition=vi->normal_partition; + float **work=alloca(sizeof(*work)*partition); + int start=vi->normal_start; + + for(j=start;jn)partition=n-j; + for(i=0;in; + vorbis_info_psy *vi=p->vi; + int partition=vi->normal_partition; + int start=vi->normal_start; + + if(start>n)start=n; + + if(vi->normal_channel_p){ + for(;j=.25f){ + out[k]=rint(in[k]); + acc-=in[k]*in[k]; + flag=1; + }else{ + if(accnormal_thresh)break; + out[k]=unitnorm(in[k]); + acc-=1.; + } + } + + for(;in; + + /* perform any requested channel coupling */ + /* point stereo can only be used in a first stage (in this encoder) + because of the dependency on floor lookups */ + for(i=0;icoupling_steps;i++){ + + /* once we're doing multistage coupling in which a channel goes + through more than one coupling step, the floor vector + magnitudes will also have to be recalculated an propogated + along with PCM. Right now, we're not (that will wait until 5.1 + most likely), so the code isn't here yet. The memory management + here is all assuming single depth couplings anyway. */ + + /* make sure coupling a zero and a nonzero channel results in two + nonzero channels. */ + if(nonzero[vi->coupling_mag[i]] || + nonzero[vi->coupling_ang[i]]){ + + + float *rM=res[vi->coupling_mag[i]]; + float *rA=res[vi->coupling_ang[i]]; + float *qM=rM+n; + float *qA=rA+n; + int *floorM=ifloor[vi->coupling_mag[i]]; + int *floorA=ifloor[vi->coupling_ang[i]]; + float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]]; + float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]]; + int partition=(p->vi->normal_point_p?p->vi->normal_partition:p->n); + int limit=g->coupling_pointlimit[p->vi->blockflag][blobno]; + int pointlimit=limit; + + nonzero[vi->coupling_mag[i]]=1; + nonzero[vi->coupling_ang[i]]=1; + + for(j=0;jn;j+=partition){ + float acc=0.f; + + for(k=0;k=limit && fabs(rM[l])vi->normal_point_p){ + for(k=0;k=p->vi->normal_thresh;k++){ + int l=mag_sort[i][j+k]; + if(l=pointlimit && rint(qM[l])==0.f){ + qM[l]=unitnorm(qM[l]); + acc-=1.f; + } + } + } + } + } + } +} + diff --git a/sound/OggVorbis/vorbissrc/psy.h b/sound/OggVorbis/vorbissrc/psy.h new file mode 100644 index 000000000..81b97ea4d --- /dev/null +++ b/sound/OggVorbis/vorbissrc/psy.h @@ -0,0 +1,175 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: random psychoacoustics (not including preecho) + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_PSY_H_ +#define _V_PSY_H_ +#include "smallft.h" + +#include "backends.h" +#include "envelope.h" + +#ifndef EHMER_MAX +#define EHMER_MAX 56 +#endif + +/* psychoacoustic setup ********************************************/ +#define P_BANDS 17 /* 62Hz to 16kHz */ +#define P_LEVELS 8 /* 30dB to 100dB */ +#define P_LEVEL_0 30. /* 30 dB */ +#define P_NOISECURVES 3 + +#define NOISE_COMPAND_LEVELS 40 +typedef struct vorbis_info_psy{ + int blockflag; + + float ath_adjatt; + float ath_maxatt; + + float tone_masteratt[P_NOISECURVES]; + float tone_centerboost; + float tone_decay; + float tone_abs_limit; + float toneatt[P_BANDS]; + + int noisemaskp; + float noisemaxsupp; + float noisewindowlo; + float noisewindowhi; + int noisewindowlomin; + int noisewindowhimin; + int noisewindowfixed; + float noiseoff[P_NOISECURVES][P_BANDS]; + float noisecompand[NOISE_COMPAND_LEVELS]; + + float max_curve_dB; + + int normal_channel_p; + int normal_point_p; + int normal_start; + int normal_partition; + double normal_thresh; +} vorbis_info_psy; + +typedef struct{ + int eighth_octave_lines; + + /* for block long/short tuning; encode only */ + float preecho_thresh[VE_BANDS]; + float postecho_thresh[VE_BANDS]; + float stretch_penalty; + float preecho_minenergy; + + float ampmax_att_per_sec; + + /* channel coupling config */ + int coupling_pkHz[PACKETBLOBS]; + int coupling_pointlimit[2][PACKETBLOBS]; + int coupling_prepointamp[PACKETBLOBS]; + int coupling_postpointamp[PACKETBLOBS]; + int sliding_lowpass[2][PACKETBLOBS]; + +} vorbis_info_psy_global; + +typedef struct { + float ampmax; + int channels; + + vorbis_info_psy_global *gi; + int coupling_pointlimit[2][P_NOISECURVES]; +} vorbis_look_psy_global; + + +typedef struct { + int n; + struct vorbis_info_psy *vi; + + float ***tonecurves; + float **noiseoffset; + + float *ath; + long *octave; /* in n.ocshift format */ + long *bark; + + long firstoc; + long shiftoc; + int eighth_octave_lines; /* power of two, please */ + int total_octave_lines; + long rate; /* cache it */ +} vorbis_look_psy; + +extern void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, + vorbis_info_psy_global *gi,int n,long rate); +extern void _vp_psy_clear(vorbis_look_psy *p); +extern void *_vi_psy_dup(void *source); + +extern void _vi_psy_free(vorbis_info_psy *i); +extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i); + +extern void _vp_remove_floor(vorbis_look_psy *p, + float *mdct, + int *icodedflr, + float *residue, + int sliding_lowpass); + +extern void _vp_noisemask(vorbis_look_psy *p, + float *logmdct, + float *logmask); + +extern void _vp_tonemask(vorbis_look_psy *p, + float *logfft, + float *logmask, + float global_specmax, + float local_specmax); + +extern void _vp_offset_and_mix(vorbis_look_psy *p, + float *noise, + float *tone, + int offset_select, + float *logmask); + +extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd); + +extern float **_vp_quantize_couple_memo(vorbis_block *vb, + vorbis_info_psy_global *g, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mdct); + +extern void _vp_couple(int blobno, + vorbis_info_psy_global *g, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **res, + float **mag_memo, + int **mag_sort, + int **ifloor, + int *nonzero, + int sliding_lowpass); + +extern void _vp_noise_normalize(vorbis_look_psy *p, + float *in,float *out,int *sortedindex); + +extern void _vp_noise_normalize_sort(vorbis_look_psy *p, + float *magnitudes,int *sortedindex); + +extern int **_vp_quantize_couple_sort(vorbis_block *vb, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mags); + +#endif + diff --git a/sound/OggVorbis/vorbissrc/psytune.c b/sound/OggVorbis/vorbissrc/psytune.c new file mode 100644 index 000000000..0b040138e --- /dev/null +++ b/sound/OggVorbis/vorbissrc/psytune.c @@ -0,0 +1,521 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple utility that runs audio through the psychoacoustics + without encoding + last mod: $Id: psytune.c,v 1.20 2003/03/04 21:22:11 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include + +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" +#include "misc.h" +#include "psy.h" +#include "mdct.h" +#include "smallft.h" +#include "window.h" +#include "scales.h" +#include "lpc.h" +#include "lsp.h" +#include "masking.h" +#include "registry.h" + +static vorbis_info_psy_global _psy_set0G={ + 0, /* decaydBpms */ + 8, /* lines per eighth octave */ + + /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, + -6.f, + + 0, + + 0., + 0., +}; + +static vp_part _vp_part0[]={ + { 1,9e10f, 9e10f, 1.f,9999.f}, + { 9999, .75f, 9e10f, .5f,9999.f}, +/*{ 9999, 1.5f, 9e10f, .5f,9999.f},*/ + { 18,9e10f, 9e10f, .5f, 30.f}, + { 9999,9e10f, 9e10f, .5f, 30.f} +}; + +static vp_couple _vp_couple0[]={ + { 1, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, + { 18, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, + { 9999, {9e10f,9e10f,0}, { 0.f, 9e10f,0}, { 0.f,22.f,1}, {0.f,0.f,0}} +}; + +static vorbis_info_psy _psy_set0={ + ATH_Bark_dB_lineaggressive, + + -100.f, + -140.f, + 6.f, /* floor master att */ + + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ + /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */ + /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */ + 1, /* tonemaskp */ + 0.f, /* tone master att */ + /* 0 10 20 30 40 50 60 70 80 90 100 */ + { + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/ + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/ + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/ + + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/ + + {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/ + + {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/ + {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/ + {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/ + + }, + + 1,/* peakattp */ + {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/ + {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/ + {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/ + {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/ + {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/ + }, + + 1,/*noisemaskp */ + -10.f, /* suppress any noise curve over maxspec+n */ + .5f, /* low window */ + .5f, /* high window */ + 10, + 10, + 25, + {.000f, 0.f, /*63*/ + .000f, 0.f, /*88*/ + .000f, 0.f, /*125*/ + .000f, 0.f, /*175*/ + .000f, 0.f, /*250*/ + .000f, 0.f, /*350*/ + .000f, 0.f, /*500*/ + .000f, 0.f, /*700*/ + .000f, 0.f, /*1000*/ + .300f, 0.f, /*1400*/ + .300f, 0.f, /*2000*/ + .300f, 0.f, /*2800*/ + .500f, 0.f, /*4000*/ + .700f, 0.f, /*5600*/ + .850f, 0.f, /*8000*/ + .900f, 0.f, /*11500*/ + .900f, 1.f, /*16000*/ + }, + + 95.f, /* even decade + 5 is important; saves an rint() later in a + tight loop) */ + -44., + + 32, + _vp_part0,_vp_couple0 +}; + +static vorbis_info_floor1 _floor_set0={1, + {0}, + + {32}, + {0}, + {0}, + {{-1}}, + + 2, + {0,1024, + + 88,31,243, + + 14,54,143,460, + + 6,3,10, 22,18,26, 41,36,47, + 69,61,78, 112,99,126, 185,162,211, + 329,282,387, 672,553,825 + }, + + 60,30,400, + 20,8,1,18., + 20,600, + 960}; + + +static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}}; +static codec_setup_info codec_setup0={ {0,0}, + 1,1,1,1,1,0,1, + {NULL}, + {0},{&mapping_info}, + {0},{NULL}, + {1},{&_floor_set0}, + {2},{NULL}, + {NULL}, + {&_psy_set0}, + &_psy_set0G}; + +static int noisy=0; +void analysis(char *base,int i,float *v,int n,int bark,int dB){ + if(noisy){ + int j; + FILE *of; + char buffer[80]; + sprintf(buffer,"%s_%d.m",base,i); + of=fopen(buffer,"w"); + + for(j=0;jlook(NULL,NULL,&_floor_set0); + + /* we cheat on the WAV header; we just bypass 44 bytes and never + verify that it matches 16bit/stereo/44.1kHz. */ + + fread(buffer,1,44,stdin); + fwrite(buffer,1,44,stdout); + memset(buffer,0,framesize*2); + + analysis("window",0,window,framesize,0,0); + + fprintf(stderr,"Processing for frame size %d...\n",framesize); + + while(!eos){ + long bytes=fread(buffer2,1,framesize*2,stdin); + if(bytes>1]=todB(&temp); + if(temp>local_ampmax[i])local_ampmax[i]=temp; + } + if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i]; + + mdct_forward(&m_look,pcm[i],mdct); + for(j=0;jforward(&vb,floor_look, + mdct, + logmdct, + mask, + logmax, + + flr[i]); + } + + _vp_remove_floor(&p_look, + pg_look, + logmdct, + mdct, + flr[i], + pcm[i], + local_ampmax[i]); + + for(j=0;j1500) + fprintf(stderr,"%ld ",frameno+i); + + analysis("res",frameno+i,pcm[i],framesize/2,1,0); + analysis("codedflr",frameno+i,flr[i],framesize/2,1,1); + } + + /* residue prequantization */ + _vp_partition_prequant(&p_look, + &vi, + pcm, + nonzero); + + for(i=0;i<2;i++) + analysis("quant",frameno+i,pcm[i],framesize/2,1,0); + + /* channel coupling / stereo quantization */ + + _vp_couple(&p_look, + &mapping_info, + pcm, + nonzero); + + for(i=0;i<2;i++) + analysis("coupled",frameno+i,pcm[i],framesize/2,1,0); + + /* decoupling */ + for(i=mapping_info.coupling_steps-1;i>=0;i--){ + float *pcmM=pcm[mapping_info.coupling_mag[i]]; + float *pcmA=pcm[mapping_info.coupling_ang[i]]; + + for(j=0;j0) + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag-ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag+ang; + } + else + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag+ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag-ang; + } + } + } + + for(i=0;i<2;i++) + analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0); + + for(i=0;i<2;i++){ + float amp; + + for(j=0;j32767){ + if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); + flag=1; + val=32767; + } + if(val<-32768){ + if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); + flag=1; + val=-32768; + } + ptr[0]=val&0xff; + ptr[1]=(val>>8)&0xff; + ptr+=4; + } + } + + fprintf(stderr,"*"); + fwrite(buffer,1,framesize*2,stdout); + memmove(buffer,buffer2,framesize*2); + + for(i=0;i<2;i++){ + for(j=0,k=framesize/2;j +#include +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "os.h" + +#ifdef TRAIN_RES +#include +#endif + +typedef struct { + vorbis_info_residue0 *info; + + int parts; + int stages; + codebook *fullbooks; + codebook *phrasebook; + codebook ***partbooks; + + int partvals; + int **decodemap; + + long postbits; + long phrasebits; + long frames; + +#ifdef TRAIN_RES + int train_seq; + long *training_data[8][64]; + float training_max[8][64]; + float training_min[8][64]; + float tmin; + float tmax; +#endif + +} vorbis_look_residue0; + +void res0_free_info(vorbis_info_residue *i){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +void res0_free_look(vorbis_look_residue *i){ + int j; + if(i){ + + vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; + +#ifdef TRAIN_RES + { + int j,k,l; + for(j=0;jparts;j++){ + /*fprintf(stderr,"partition %d: ",j);*/ + for(k=0;k<8;k++) + if(look->training_data[k][j]){ + char buffer[80]; + FILE *of; + codebook *statebook=look->partbooks[j][k]; + + /* long and short into the same bucket by current convention */ + sprintf(buffer,"res_part%d_pass%d.vqd",j,k); + of=fopen(buffer,"a"); + + for(l=0;lentries;l++) + fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]); + + fclose(of); + + /*fprintf(stderr,"%d(%.2f|%.2f) ",k, + look->training_min[k][j],look->training_max[k][j]);*/ + + _ogg_free(look->training_data[k][j]); + } + /*fprintf(stderr,"\n");*/ + } + } + fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax); + + /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", + (float)look->phrasebits/look->frames, + (float)look->postbits/look->frames, + (float)(look->postbits+look->phrasebits)/look->frames);*/ +#endif + + + /*vorbis_info_residue0 *info=look->info; + + fprintf(stderr, + "%ld frames encoded in %ld phrasebits and %ld residue bits " + "(%g/frame) \n",look->frames,look->phrasebits, + look->resbitsflat, + (look->phrasebits+look->resbitsflat)/(float)look->frames); + + for(j=0;jparts;j++){ + long acc=0; + fprintf(stderr,"\t[%d] == ",j); + for(k=0;kstages;k++) + if((info->secondstages[j]>>k)&1){ + fprintf(stderr,"%ld,",look->resbits[j][k]); + acc+=look->resbits[j][k]; + } + + fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], + acc?(float)acc/(look->resvals[j]*info->grouping):0); + } + fprintf(stderr,"\n");*/ + + for(j=0;jparts;j++) + if(look->partbooks[j])_ogg_free(look->partbooks[j]); + _ogg_free(look->partbooks); + for(j=0;jpartvals;j++) + _ogg_free(look->decodemap[j]); + _ogg_free(look->decodemap); + + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static int icount(unsigned int v){ + int ret=0; + while(v){ + ret+=v&1; + v>>=1; + } + return(ret); +} + + +void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + int j,acc=0; + oggpack_write(opb,info->begin,24); + oggpack_write(opb,info->end,24); + + oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and + code with a partitioned book */ + oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ + oggpack_write(opb,info->groupbook,8); /* group huffman book */ + + /* secondstages is a bitmask; as encoding progresses pass by pass, a + bitmask of one indicates this partition class has bits to write + this pass */ + for(j=0;jpartitions;j++){ + if(ilog(info->secondstages[j])>3){ + /* yes, this is a minor hack due to not thinking ahead */ + oggpack_write(opb,info->secondstages[j],3); + oggpack_write(opb,1,1); + oggpack_write(opb,info->secondstages[j]>>3,5); + }else + oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ + acc+=icount(info->secondstages[j]); + } + for(j=0;jbooklist[j],8); + +} + +/* vorbis_info is for range checking */ +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int j,acc=0; + vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=vi->codec_setup; + + info->begin=oggpack_read(opb,24); + info->end=oggpack_read(opb,24); + info->grouping=oggpack_read(opb,24)+1; + info->partitions=oggpack_read(opb,6)+1; + info->groupbook=oggpack_read(opb,8); + + for(j=0;jpartitions;j++){ + int cascade=oggpack_read(opb,3); + if(oggpack_read(opb,1)) + cascade|=(oggpack_read(opb,5)<<3); + info->secondstages[j]=cascade; + + acc+=icount(cascade); + } + for(j=0;jbooklist[j]=oggpack_read(opb,8); + + if(info->groupbook>=ci->books)goto errout; + for(j=0;jbooklist[j]>=ci->books)goto errout; + + return(info); + errout: + res0_free_info(info); + return(NULL); +} + +vorbis_look_residue *res0_look(vorbis_dsp_state *vd, + vorbis_info_residue *vr){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); + codec_setup_info *ci=vd->vi->codec_setup; + + int j,k,acc=0; + int dim; + int maxstage=0; + look->info=info; + + look->parts=info->partitions; + look->fullbooks=ci->fullbooks; + look->phrasebook=ci->fullbooks+info->groupbook; + dim=look->phrasebook->dim; + + look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); + + for(j=0;jparts;j++){ + int stages=ilog(info->secondstages[j]); + if(stages){ + if(stages>maxstage)maxstage=stages; + look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); + for(k=0;ksecondstages[j]&(1<partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; +#ifdef TRAIN_RES + look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries, + sizeof(***look->training_data)); +#endif + } + } + } + + look->partvals=rint(pow((float)look->parts,(float)dim)); + look->stages=maxstage; + look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); + for(j=0;jpartvals;j++){ + long val=j; + long mult=look->partvals/look->parts; + look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); + for(k=0;kparts; + look->decodemap[j][k]=deco; + } + } +#ifdef TRAIN_RES + { + static int train_seq=0; + look->train_seq=train_seq++; + } +#endif + return(look); +} + +/* break an abstraction and copy some code for performance purposes */ +static int local_book_besterror(codebook *book,float *a){ + int dim=book->dim,i,k,o; + int best=0; + encode_aux_threshmatch *tt=book->c->thresh_tree; + + /* find the quant val of each scalar */ + for(k=0,o=dim;kthreshvals>>1; + + if(valquantthresh[i]){ + if(valquantthresh[i-1]){ + for(--i;i>0;--i) + if(val>=tt->quantthresh[i-1]) + break; + } + }else{ + + for(++i;ithreshvals-1;++i) + if(valquantthresh[i])break; + + } + + best=(best*tt->quantvals)+tt->quantmap[i]; + } + /* regular lattices are easy :-) */ + + if(book->c->lengthlist[best]<=0){ + const static_codebook *c=book->c; + int i,j; + float bestf=0.f; + float *e=book->valuelist; + best=-1; + for(i=0;ientries;i++){ + if(c->lengthlist[i]>0){ + float this=0.f; + for(j=0;jvaluelist+best*dim; + for(i=0;idim; + int step=n/dim; + + for(i=0;iinfo; + vorbis_info *vi=vb->vd->vi; + codec_setup_info *ci=vi->codec_setup; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword)); + float scale=100./samples_per_partition; + + /* we find the partition type for each partition of each + channel. We'll go back and do the interleaved encoding in a + bit. For now, clarity */ + + for(i=0;ibegin; + for(j=0;jmax)max=fabs(in[j][offset+k]); + ent+=fabs(rint(in[j][offset+k])); + } + ent*=scale; + + for(k=0;kclassmetric1[k] && + (info->classmetric2[k]<0 || (int)entclassmetric2[k])) + break; + + partword[j][i]=k; + } + } + +#ifdef TRAIN_RESAUX + { + FILE *of; + char buffer[80]; + + for(i=0;itrain_seq); + of=fopen(buffer,"a"); + for(j=0;jframes++; + + return(partword); +} + +/* designed for stereo or other modes where the partition size is an + integer multiple of the number of channels encoded in the current + submap */ +static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in, + int ch){ + long i,j,k,l; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long **partword=_vorbis_block_alloc(vb,sizeof(*partword)); + +#ifdef TRAIN_RES + FILE *of; + char buffer[80]; +#endif + + partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0])); + memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0])); + + for(i=0,l=info->begin/ch;imagmax)magmax=fabs(in[0][l]); + for(k=1;kangmax)angmax=fabs(in[k][l]); + l++; + } + + for(j=0;jclassmetric1[j] && + angmax<=info->classmetric2[j]) + break; + + partword[0][i]=j; + + } + +#ifdef TRAIN_RESAUX + sprintf(buffer,"resaux_%d.vqd",look->train_seq); + of=fopen(buffer,"a"); + for(i=0;iframes++; + + return(partword); +} + +static int _01forward(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + long **partword, + int (*encode)(oggpack_buffer *,float *,int, + codebook *,long *)){ + long i,j,k,s; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + vorbis_dsp_state *vd=vb->vd; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long resbits[128]; + long resvals[128]; + +#ifdef TRAIN_RES + for(i=0;ibegin;jend;j++){ + if(in[i][j]>look->tmax)look->tmax=in[i][j]; + if(in[i][j]tmin)look->tmin=in[i][j]; + } +#endif + + memset(resbits,0,sizeof(resbits)); + memset(resvals,0,sizeof(resvals)); + + /* we code the partition words for each channel, then the residual + words for a partition per channel until we've written all the + residual words for that partition word. Then write the next + partition channel words... */ + + for(s=0;sstages;s++){ + + for(i=0;iphrasebook->entries) + look->phrasebits+=vorbis_book_encode(look->phrasebook,val,&vb->opb); +#if 0 /*def TRAIN_RES*/ + else + fprintf(stderr,"!"); +#endif + + } + } + + /* now we encode interleaved residual values for the partitions */ + for(k=0;kbegin; + + for(j=0;jsecondstages[partword[j][i]]&(1<partbooks[partword[j][i]][s]; + if(statebook){ + int ret; + long *accumulator=NULL; + +#ifdef TRAIN_RES + accumulator=look->training_data[s][partword[j][i]]; + { + int l; + float *samples=in[j]+offset; + for(l=0;ltraining_min[s][partword[j][i]]) + look->training_min[s][partword[j][i]]=samples[l]; + if(samples[l]>look->training_max[s][partword[j][i]]) + look->training_max[s][partword[j][i]]=samples[l]; + } + } +#endif + + ret=encode(&vb->opb,in[j]+offset,samples_per_partition, + statebook,accumulator); + + look->postbits+=ret; + resbits[partword[j][i]]+=ret; + } + } + } + } + } + } + + /*{ + long total=0; + long totalbits=0; + fprintf(stderr,"%d :: ",vb->mode); + for(k=0;kinfo; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int ***partword=alloca(ch*sizeof(*partword)); + + for(j=0;jstages;s++){ + + /* each loop decodes on partition codeword containing + partitions_pre_word partitions */ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } + } + + /* now we decode residual values for the partitions */ + for(k=0;kbegin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition)==-1)goto eopbreak; + } + } + } + } + } + + errout: + eopbreak: + return(0); +} + +#if 0 +/* residue 0 and 1 are just slight variants of one another. 0 is + interleaved, 1 is not */ +long **res0_class(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int *nonzero,int ch){ + /* we encode only the nonzero parts of a bundle */ + int i,used=0; + for(i=0;ipcmend/2; + for(i=0;ipcmend/2; + for(i=0;ipcmend/2,used=0; + + /* don't duplicate the code; use a working vector hack for now and + reshape ourselves into a single channel res1 */ + /* ugly; reallocs for each coupling pass :-( */ + float *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work)); + for(i=0;iinfo; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); + + for(i=0;istages;s++){ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; + } + + /* now we decode residual values for the partitions */ + for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; + + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+info->begin,ch, + &vb->opb,samples_per_partition)==-1) + goto eopbreak; + } + } + } + } + + errout: + eopbreak: + return(0); +} + + +vorbis_func_residue residue0_exportbundle={ + NULL, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + NULL, + NULL, + &res0_inverse +}; + +vorbis_func_residue residue1_exportbundle={ + &res0_pack, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res1_class, + &res1_forward, + &res1_inverse +}; + +vorbis_func_residue residue2_exportbundle={ + &res0_pack, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res2_class, + &res2_forward, + &res2_inverse +}; + diff --git a/sound/OggVorbis/vorbissrc/scales.h b/sound/OggVorbis/vorbissrc/scales.h new file mode 100644 index 000000000..7ce0db098 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/scales.h @@ -0,0 +1,88 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: linear scale -> dB, Bark and Mel scales + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_SCALES_H_ +#define _V_SCALES_H_ + +#include +#include "os.h" + +/* 20log10(x) */ +#define VORBIS_IEEE_FLOAT32 1 +#ifdef VORBIS_IEEE_FLOAT32 + +static float unitnorm(float x){ + ogg_uint32_t *ix=(ogg_uint32_t *)&x; + *ix=(*ix&0x80000000UL)|(0x3f800000UL); + return(x); +} + +static float FABS(float *x){ + ogg_uint32_t *ix=(ogg_uint32_t *)x; + *ix&=0x7fffffffUL; + return(*x); +} + +static float todB(const float *x){ + float calc; + ogg_int32_t *i=(ogg_int32_t *)x; + calc = ((*i) & 0x7fffffff); + calc *= 7.1771144e-7f; + calc += -764.27118f; + return calc; +} + +#define todB_nn(x) todB(x) + +#else + +static float unitnorm(float x){ + if(x<0)return(-1.f); + return(1.f); +} + +#define FABS(x) fabs(*(x)) + +#define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f) +#define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f) + +#endif + +#define fromdB(x) (exp((x)*.11512925f)) + +/* The bark scale equations are approximations, since the original + table was somewhat hand rolled. The below are chosen to have the + best possible fit to the rolled tables, thus their somewhat odd + appearance (these are more accurate and over a longer range than + the oft-quoted bark equations found in the texts I have). The + approximations are valid from 0 - 30kHz (nyquist) or so. + + all f in Hz, z in Bark */ + +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f) +#define toMEL(n) (log(1.f+(n)*.001f)*1442.695f) +#define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f) + +/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave + 0.0 */ + +#define toOC(n) (log(n)*1.442695f-5.965784f) +#define fromOC(o) (exp(((o)+5.965784f)*.693147f)) + +#endif + diff --git a/sound/OggVorbis/vorbissrc/sharedbook.c b/sound/OggVorbis/vorbissrc/sharedbook.c new file mode 100644 index 000000000..63d8dc945 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/sharedbook.c @@ -0,0 +1,734 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + last mod: $Id: sharedbook.c,v 1.29 2002/10/11 07:44:28 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include "../ogg/ogg.h" +#include "os.h" +#include "misc.h" +#include "../vorbis/codec.h" +#include "codebook.h" +#include "scales.h" + +/**** pack/unpack helpers ******************************************/ +int _ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* 32 bit float (not IEEE; nonnormalized mantissa + + biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm + Why not IEEE? It's just not that important here. */ + +#define VQ_FEXP 10 +#define VQ_FMAN 21 +#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */ + +/* doesn't currently guard under/overflow */ +long _float32_pack(float val){ + int sign=0; + long exp; + long mant; + if(val<0){ + sign=0x80000000; + val= -val; + } + exp= floor(log(val)/log(2.f)); + mant=rint(ldexp(val,(VQ_FMAN-1)-exp)); + exp=(exp+VQ_FEXP_BIAS)<>VQ_FMAN; + if(sign)mant= -mant; + return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS)); +} + +/* given a list of word lengths, generate a list of codewords. Works + for length ordered or unordered, always assigns the lowest valued + codewords first. Extended to handle unused entries (length 0) */ +ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ + long i,j,count=0; + ogg_uint32_t marker[33]; + ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); + memset(marker,0,sizeof(marker)); + + for(i=0;i0){ + ogg_uint32_t entry=marker[length]; + + /* when we claim a node for an entry, we also claim the nodes + below it (pruning off the imagined tree that may have dangled + from it) as well as blocking the use of any nodes directly + above for leaves */ + + /* update ourself */ + if(length<32 && (entry>>length)){ + /* error condition; the lengths must specify an overpopulated tree */ + _ogg_free(r); + return(NULL); + } + r[count++]=entry; + + /* Look to see if the next shorter marker points to the node + above. if so, update it and repeat. */ + { + for(j=length;j>0;j--){ + + if(marker[j]&1){ + /* have to jump branches */ + if(j==1) + marker[1]++; + else + marker[j]=marker[j-1]<<1; + break; /* invariant says next upper marker would already + have been moved if it was on the same path */ + } + marker[j]++; + } + } + + /* prune the tree; the implicit invariant says all the longer + markers were dangling from our just-taken node. Dangle them + from our *new* node. */ + for(j=length+1;j<33;j++) + if((marker[j]>>1) == entry){ + entry=marker[j]; + marker[j]=marker[j-1]<<1; + }else + break; + }else + if(sparsecount==0)count++; + } + + /* bitreverse the words because our bitwise packer/unpacker is LSb + endian */ + for(i=0,count=0;i>j)&1; + } + + if(sparsecount){ + if(l[i]) + r[count++]=temp; + }else + r[count++]=temp; + } + + return(r); +} + +/* there might be a straightforward one-line way to do the below + that's portable and totally safe against roundoff, but I haven't + thought of it. Therefore, we opt on the side of caution */ +long _book_maptype1_quantvals(const static_codebook *b){ + long vals=floor(pow((float)b->entries,1.f/b->dim)); + + /* the above *should* be reliable, but we'll not assume that FP is + ever reliable when bitstream sync is at stake; verify via integer + means that vals really is the greatest value of dim for which + vals^b->bim <= b->entries */ + /* treat the above as an initial guess */ + while(1){ + long acc=1; + long acc1=1; + int i; + for(i=0;idim;i++){ + acc*=vals; + acc1*=vals+1; + } + if(acc<=b->entries && acc1>b->entries){ + return(vals); + }else{ + if(acc>b->entries){ + vals--; + }else{ + vals++; + } + } + } +} + +/* unpack the quantized list of values for encode/decode ***********/ +/* we need to deal with two map types: in map type 1, the values are + generated algorithmically (each column of the vector counts through + the values in the quant vector). in map type 2, all the values came + in in an explicit list. Both value lists must be unpacked */ +float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){ + long j,k,count=0; + if(b->maptype==1 || b->maptype==2){ + int quantvals; + float mindel=_float32_unpack(b->q_min); + float delta=_float32_unpack(b->q_delta); + float *r=_ogg_calloc(n*b->dim,sizeof(*r)); + + /* maptype 1 and 2 both use a quantized value vector, but + different sizes */ + switch(b->maptype){ + case 1: + /* most of the time, entries%dimensions == 0, but we need to be + well defined. We define that the possible vales at each + scalar is values == entries/dim. If entries%dim != 0, we'll + have 'too few' values (values*dimentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + float last=0.f; + int indexdiv=1; + for(k=0;kdim;k++){ + int index= (j/indexdiv)%quantvals; + float val=b->quantlist[index]; + val=fabs(val)*delta+mindel+last; + if(b->q_sequencep)last=val; + if(sparsemap) + r[sparsemap[count]*b->dim+k]=val; + else + r[count*b->dim+k]=val; + indexdiv*=quantvals; + } + count++; + } + + } + break; + case 2: + for(j=0;jentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + float last=0.f; + + for(k=0;kdim;k++){ + float val=b->quantlist[j*b->dim+k]; + val=fabs(val)*delta+mindel+last; + if(b->q_sequencep)last=val; + if(sparsemap) + r[sparsemap[count]*b->dim+k]=val; + else + r[count*b->dim+k]=val; + } + count++; + } + } + break; + } + + return(r); + } + return(NULL); +} + +void vorbis_staticbook_clear(static_codebook *b){ + if(b->allocedp){ + if(b->quantlist)_ogg_free(b->quantlist); + if(b->lengthlist)_ogg_free(b->lengthlist); + if(b->nearest_tree){ + _ogg_free(b->nearest_tree->ptr0); + _ogg_free(b->nearest_tree->ptr1); + _ogg_free(b->nearest_tree->p); + _ogg_free(b->nearest_tree->q); + memset(b->nearest_tree,0,sizeof(*b->nearest_tree)); + _ogg_free(b->nearest_tree); + } + if(b->thresh_tree){ + _ogg_free(b->thresh_tree->quantthresh); + _ogg_free(b->thresh_tree->quantmap); + memset(b->thresh_tree,0,sizeof(*b->thresh_tree)); + _ogg_free(b->thresh_tree); + } + + memset(b,0,sizeof(*b)); + } +} + +void vorbis_staticbook_destroy(static_codebook *b){ + if(b->allocedp){ + vorbis_staticbook_clear(b); + _ogg_free(b); + } +} + +void vorbis_book_clear(codebook *b){ + /* static book is not cleared; we're likely called on the lookup and + the static codebook belongs to the info struct */ + if(b->valuelist)_ogg_free(b->valuelist); + if(b->codelist)_ogg_free(b->codelist); + + if(b->dec_index)_ogg_free(b->dec_index); + if(b->dec_codelengths)_ogg_free(b->dec_codelengths); + if(b->dec_firsttable)_ogg_free(b->dec_firsttable); + + memset(b,0,sizeof(*b)); +} + +int vorbis_book_init_encode(codebook *c,const static_codebook *s){ + + memset(c,0,sizeof(*c)); + c->c=s; + c->entries=s->entries; + c->used_entries=s->entries; + c->dim=s->dim; + c->codelist=_make_words(s->lengthlist,s->entries,0); + c->valuelist=_book_unquantize(s,s->entries,NULL); + + return(0); +} + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL); + x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL); + x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL); + x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL); + return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL); +} + +static int sort32a(const void *a,const void *b){ + return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)- + ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b); +} + +/* decode codebook arrangement is more heavily optimized than encode */ +int vorbis_book_init_decode(codebook *c,const static_codebook *s){ + int i,j,n=0,tabn; + int *sortindex; + memset(c,0,sizeof(*c)); + + /* count actually used entries */ + for(i=0;ientries;i++) + if(s->lengthlist[i]>0) + n++; + + c->entries=s->entries; + c->used_entries=n; + c->dim=s->dim; + + /* two different remappings go on here. + + First, we collapse the likely sparse codebook down only to + actually represented values/words. This collapsing needs to be + indexed as map-valueless books are used to encode original entry + positions as integers. + + Second, we reorder all vectors, including the entry index above, + by sorted bitreversed codeword to allow treeless decode. */ + + { + /* perform sort */ + ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); + ogg_uint32_t **codep=alloca(sizeof(*codep)*n); + + if(codes==NULL)goto err_out; + + for(i=0;icodelist=_ogg_malloc(n*sizeof(*c->codelist)); + /* the index is a reverse index */ + for(i=0;icodelist[sortindex[i]]=codes[i]; + _ogg_free(codes); + } + + c->valuelist=_book_unquantize(s,n,sortindex); + c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index)); + + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_index[sortindex[n++]]=i; + + c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths)); + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; + + c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ + if(c->dec_firsttablen<5)c->dec_firsttablen=5; + if(c->dec_firsttablen>8)c->dec_firsttablen=8; + + tabn=1<dec_firsttablen; + c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); + c->dec_maxlength=0; + + for(i=0;idec_maxlengthdec_codelengths[i]) + c->dec_maxlength=c->dec_codelengths[i]; + if(c->dec_codelengths[i]<=c->dec_firsttablen){ + ogg_uint32_t orig=bitreverse(c->codelist[i]); + for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) + c->dec_firsttable[orig|(j<dec_codelengths[i])]=i+1; + } + } + + /* now fill in 'unused' entries in the firsttable with hi/lo search + hints for the non-direct-hits */ + { + ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); + long lo=0,hi=0; + + for(i=0;idec_firsttablen); + if(c->dec_firsttable[bitreverse(word)]==0){ + while((lo+1)codelist[lo+1]<=word)lo++; + while( hi=(c->codelist[hi]&mask))hi++; + + /* we only actually have 15 bits per hint to play with here. + In order to overflow gracefully (nothing breaks, efficiency + just drops), encode as the difference from the extremes. */ + { + unsigned long loval=lo; + unsigned long hival=n-hi; + + if(loval>0x7fff)loval=0x7fff; + if(hival>0x7fff)hival=0x7fff; + c->dec_firsttable[bitreverse(word)]= + 0x80000000UL | (loval<<15) | hival; + } + } + } + } + + + return(0); + err_out: + vorbis_book_clear(c); + return(-1); +} + +static float _dist(int el,float *ref, float *b,int step){ + int i; + float acc=0.f; + for(i=0;ic->thresh_tree; + +#if 0 + encode_aux_nearestmatch *nt=book->c->nearest_tree; + encode_aux_pigeonhole *pt=book->c->pigeon_tree; +#endif + int dim=book->dim; + int k,o; + /*int savebest=-1; + float saverr;*/ + + /* do we have a threshhold encode hint? */ + if(tt){ + int index=0,i; + /* find the quant val of each scalar */ + for(k=0,o=step*(dim-1);kthreshvals>>1; + if(a[o]quantthresh[i]){ + + for(;i>0;i--) + if(a[o]>=tt->quantthresh[i-1]) + break; + + }else{ + + for(i++;ithreshvals-1;i++) + if(a[o]quantthresh[i])break; + + } + + index=(index*tt->quantvals)+tt->quantmap[i]; + } + /* regular lattices are easy :-) */ + if(book->c->lengthlist[index]>0) /* is this unused? If so, we'll + use a decision tree after all + and fall through*/ + return(index); + } + +#if 0 + /* do we have a pigeonhole encode hint? */ + if(pt){ + const static_codebook *c=book->c; + int i,besti=-1; + float best=0.f; + int entry=0; + + /* dealing with sequentialness is a pain in the ass */ + if(c->q_sequencep){ + int pv; + long mul=1; + float qlast=0; + for(k=0,o=0;kmin)/pt->del); + if(pv<0 || pv>=pt->mapentries)break; + entry+=pt->pigeonmap[pv]*mul; + mul*=pt->quantvals; + qlast+=pv*pt->del+pt->min; + } + }else{ + for(k=0,o=step*(dim-1);kmin)/pt->del); + if(pv<0 || pv>=pt->mapentries)break; + entry=entry*pt->quantvals+pt->pigeonmap[pv]; + } + } + + /* must be within the pigeonholable range; if we quant outside (or + in an entry that we define no list for), brute force it */ + if(k==dim && pt->fitlength[entry]){ + /* search the abbreviated list */ + long *list=pt->fitlist+pt->fitmap[entry]; + for(i=0;ifitlength[entry];i++){ + float this=_dist(dim,book->valuelist+list[i]*dim,a,step); + if(besti==-1 || thisvaluelist+nt->p[ptr]; + float *q=book->valuelist+nt->q[ptr]; + + for(k=0,o=0;k0.f) /* in A */ + ptr= -nt->ptr0[ptr]; + else /* in B */ + ptr= -nt->ptr1[ptr]; + if(ptr<=0)break; + } + return(-ptr); + } +#endif + + /* brute force it! */ + { + const static_codebook *c=book->c; + int i,besti=-1; + float best=0.f; + float *e=book->valuelist; + for(i=0;ientries;i++){ + if(c->lengthlist[i]>0){ + float this=_dist(dim,e,a,step); + if(besti==-1 || thisvaluelist+savebest*dim)[i]); + fprintf(stderr,"\n" + "bruteforce (entry %d, err %g):",besti,best); + for(i=0;ivaluelist+besti*dim)[i]); + fprintf(stderr,"\n"); + }*/ + return(besti); + } +} + +long vorbis_book_codeword(codebook *book,int entry){ + if(book->c) /* only use with encode; decode optimizations are + allowed to break this */ + return book->codelist[entry]; + return -1; +} + +long vorbis_book_codelen(codebook *book,int entry){ + if(book->c) /* only use with encode; decode optimizations are + allowed to break this */ + return book->c->lengthlist[entry]; + return -1; +} + +#ifdef _V_SELFTEST + +/* Unit tests of the dequantizer; this stuff will be OK + cross-platform, I simply want to be sure that special mapping cases + actually work properly; a bug could go unnoticed for a while */ + +#include + +/* cases: + + no mapping + full, explicit mapping + algorithmic mapping + + nonsequential + sequential +*/ + +static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1}; +static long partial_quantlist1[]={0,7,2}; + +/* no mapping */ +static_codebook test1={ + 4,16, + NULL, + 0, + 0,0,0,0, + NULL, + NULL,NULL +}; +static float *test1_result=NULL; + +/* linear, full mapping, nonsequential */ +static_codebook test2={ + 4,3, + NULL, + 2, + -533200896,1611661312,4,0, + full_quantlist1, + NULL,NULL +}; +static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2}; + +/* linear, full mapping, sequential */ +static_codebook test3={ + 4,3, + NULL, + 2, + -533200896,1611661312,4,1, + full_quantlist1, + NULL,NULL +}; +static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6}; + +/* linear, algorithmic mapping, nonsequential */ +static_codebook test4={ + 3,27, + NULL, + 1, + -533200896,1611661312,4,0, + partial_quantlist1, + NULL,NULL +}; +static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3, + -3, 4,-3, 4, 4,-3, -1, 4,-3, + -3,-1,-3, 4,-1,-3, -1,-1,-3, + -3,-3, 4, 4,-3, 4, -1,-3, 4, + -3, 4, 4, 4, 4, 4, -1, 4, 4, + -3,-1, 4, 4,-1, 4, -1,-1, 4, + -3,-3,-1, 4,-3,-1, -1,-3,-1, + -3, 4,-1, 4, 4,-1, -1, 4,-1, + -3,-1,-1, 4,-1,-1, -1,-1,-1}; + +/* linear, algorithmic mapping, sequential */ +static_codebook test5={ + 3,27, + NULL, + 1, + -533200896,1611661312,4,1, + partial_quantlist1, + NULL,NULL +}; +static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7, + -3, 1,-2, 4, 8, 5, -1, 3, 0, + -3,-4,-7, 4, 3, 0, -1,-2,-5, + -3,-6,-2, 4, 1, 5, -1,-4, 0, + -3, 1, 5, 4, 8,12, -1, 3, 7, + -3,-4, 0, 4, 3, 7, -1,-2, 2, + -3,-6,-7, 4, 1, 0, -1,-4,-5, + -3, 1, 0, 4, 8, 7, -1, 3, 2, + -3,-4,-5, 4, 3, 2, -1,-2,-3}; + +void run_test(static_codebook *b,float *comp){ + float *out=_book_unquantize(b,b->entries,NULL); + int i; + + if(comp){ + if(!out){ + fprintf(stderr,"_book_unquantize incorrectly returned NULL\n"); + exit(1); + } + + for(i=0;ientries*b->dim;i++) + if(fabs(out[i]-comp[i])>.0001){ + fprintf(stderr,"disagreement in unquantized and reference data:\n" + "position %d, %g != %g\n",i,out[i],comp[i]); + exit(1); + } + + }else{ + if(out){ + fprintf(stderr,"_book_unquantize returned a value array: \n" + " correct result should have been NULL\n"); + exit(1); + } + } +} + +int main(){ + /* run the nine dequant tests, and compare to the hand-rolled results */ + fprintf(stderr,"Dequant test 1... "); + run_test(&test1,test1_result); + fprintf(stderr,"OK\nDequant test 2... "); + run_test(&test2,test2_result); + fprintf(stderr,"OK\nDequant test 3... "); + run_test(&test3,test3_result); + fprintf(stderr,"OK\nDequant test 4... "); + run_test(&test4,test4_result); + fprintf(stderr,"OK\nDequant test 5... "); + run_test(&test5,test5_result); + fprintf(stderr,"OK\n\n"); + + return(0); +} + +#endif diff --git a/sound/OggVorbis/vorbissrc/smallft.c b/sound/OggVorbis/vorbissrc/smallft.c new file mode 100644 index 000000000..3d30f4dfe --- /dev/null +++ b/sound/OggVorbis/vorbissrc/smallft.c @@ -0,0 +1,1254 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: *unnormalized* fft transform + last mod: $Id: smallft.c,v 1.17 2002/07/11 06:40:50 xiphmont Exp $ + + ********************************************************************/ + +/* FFT implementation from OggSquish, minus cosine transforms, + * minus all but radix 2/4 case. In Vorbis we only need this + * cut-down version. + * + * To do more than just power-of-two sized vectors, see the full + * version I wrote for NetLib. + * + * Note that the packing is a little strange; rather than the FFT r/i + * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, + * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the + * FORTRAN version + */ + +#include +#include +#include +#include "smallft.h" +#include "misc.h" + +static void drfti1(int n, float *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static float tpi = 6.28318530717958648f; + float arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if(ntry!=2)goto L107; + if(nf==1)goto L107; + + for (i=1;i>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if(ido==1)goto L119; + for(ik=0;ikl1){ + for(j=1;j>1; + ipp2=ip; + ipph=(ip+1)>>1; + if(idol1)goto L139; + + is= -ido-1; + t1=0; + for(j=1;jn==1)return; + drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void drft_backward(drft_lookup *l,float *data){ + if (l->n==1)return; + drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void drft_init(drft_lookup *l,int n){ + l->n=n; + l->trigcache=_ogg_calloc(3*n,sizeof(*l->trigcache)); + l->splitcache=_ogg_calloc(32,sizeof(*l->splitcache)); + fdrffti(n, l->trigcache, l->splitcache); +} + +void drft_clear(drft_lookup *l){ + if(l){ + if(l->trigcache)_ogg_free(l->trigcache); + if(l->splitcache)_ogg_free(l->splitcache); + memset(l,0,sizeof(*l)); + } +} diff --git a/sound/OggVorbis/vorbissrc/smallft.h b/sound/OggVorbis/vorbissrc/smallft.h new file mode 100644 index 000000000..392ec96cc --- /dev/null +++ b/sound/OggVorbis/vorbissrc/smallft.h @@ -0,0 +1,34 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_SMFT_H_ +#define _V_SMFT_H_ + +#include "../vorbis/codec.h" + +typedef struct { + int n; + float *trigcache; + int *splitcache; +} drft_lookup; + +extern void drft_forward(drft_lookup *l,float *data); +extern void drft_backward(drft_lookup *l,float *data); +extern void drft_init(drft_lookup *l,int n); +extern void drft_clear(drft_lookup *l); + +#endif diff --git a/sound/OggVorbis/vorbissrc/synthesis.c b/sound/OggVorbis/vorbissrc/synthesis.c new file mode 100644 index 000000000..84b9b4985 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/synthesis.c @@ -0,0 +1,170 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: single-block PCM synthesis + last mod: $Id: synthesis.c,v 1.30 2003/08/18 05:34:01 xiphmont Exp $ + + ********************************************************************/ + +#include +#include "../ogg/ogg.h" +#include "../vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "misc.h" +#include "os.h" + +int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer *opb=&vb->opb; + int type,mode,i; + + /* first things first. Make sure decode is ready */ + _vorbis_block_ripcord(vb); + oggpack_readinit(opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(opb,b->modebits); + if(mode==-1)return(OV_EBADPACKET); + + vb->mode=mode; + vb->W=ci->mode_param[mode]->blockflag; + if(vb->W){ + + /* this doesn;t get mapped through mode selection as it's used + only for window selection */ + vb->lW=oggpack_read(opb,1); + vb->nW=oggpack_read(opb,1); + if(vb->nW==-1) return(OV_EBADPACKET); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->granulepos=op->granulepos; + vb->sequence=op->packetno; + vb->eofflag=op->e_o_s; + + /* alloc pcm passback storage */ + vb->pcmend=ci->blocksizes[vb->W]; + vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); + for(i=0;ichannels;i++) + vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + + /* unpack_header enforces range checking */ + type=ci->map_type[ci->mode_param[mode]->mapping]; + + return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> + mapping])); +} + +/* used to track pcm position without actually performing decode. + Useful for sequential 'fast forward' */ +int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer *opb=&vb->opb; + int mode; + + /* first things first. Make sure decode is ready */ + _vorbis_block_ripcord(vb); + oggpack_readinit(opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(opb,b->modebits); + if(mode==-1)return(OV_EBADPACKET); + + vb->mode=mode; + vb->W=ci->mode_param[mode]->blockflag; + if(vb->W){ + vb->lW=oggpack_read(opb,1); + vb->nW=oggpack_read(opb,1); + if(vb->nW==-1) return(OV_EBADPACKET); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->granulepos=op->granulepos; + vb->sequence=op->packetno; + vb->eofflag=op->e_o_s; + + /* no pcm */ + vb->pcmend=0; + vb->pcm=NULL; + + return(0); +} + +long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer opb; + int mode; + + oggpack_readinit(&opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(&opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + { + int modebits=0; + int v=ci->modes; + while(v>1){ + modebits++; + v>>=1; + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(&opb,modebits); + } + if(mode==-1)return(OV_EBADPACKET); + return(ci->blocksizes[ci->mode_param[mode]->blockflag]); +} + +int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){ + /* set / clear half-sample-rate mode */ + codec_setup_info *ci=vi->codec_setup; + + /* right now, our MDCT can't handle < 64 sample windows. */ + if(ci->blocksizes[0]<=64 && flag)return -1; + ci->halfrate_flag=(flag?1:0); + return 0; +} + +int vorbis_synthesis_halfrate_p(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + return ci->halfrate_flag; +} + + diff --git a/sound/OggVorbis/vorbissrc/tone.c b/sound/OggVorbis/vorbissrc/tone.c new file mode 100644 index 000000000..daf2f9313 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/tone.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +void usage(){ + fprintf(stderr,"tone ,[] [,[]...]\n"); + exit(1); +} + +int main (int argc,char *argv[]){ + int i,j; + double *f; + double *amp; + + if(argc<2)usage(); + + f=alloca(sizeof(*f)*(argc-1)); + amp=alloca(sizeof(*amp)*(argc-1)); + + i=0; + while(argv[i+1]){ + char *pos=strchr(argv[i+1],','); + + f[i]=atof(argv[i+1]); + if(pos) + amp[i]=atof(pos+1)*32767.f; + else + amp[i]=32767.f; + + fprintf(stderr,"%g Hz, %g amp\n",f[i],amp[i]); + + i++; + } + + for(i=0;i<44100*10;i++){ + float val=0; + int ival; + for(j=0;j32767.f)ival=32767.f; + if(ival<-32768.f)ival=-32768.f; + + fprintf(stdout,"%c%c%c%c", + (char)(ival&0xff), + (char)((ival>>8)&0xff), + (char)(ival&0xff), + (char)((ival>>8)&0xff)); + } + return(0); +} + diff --git a/sound/OggVorbis/vorbissrc/vorbisenc.c b/sound/OggVorbis/vorbissrc/vorbisenc.c new file mode 100644 index 000000000..374fd4b1f --- /dev/null +++ b/sound/OggVorbis/vorbissrc/vorbisenc.c @@ -0,0 +1,1134 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple programmatic interface for encoder mode setup + last mod: $Id: vorbisenc.c,v 1.47 2002/07/11 06:40:50 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include + +#include "../vorbis/codec.h" +#include "../vorbis/vorbisenc.h" + +#include "codec_internal.h" + +#include "os.h" +#include "misc.h" + +/* careful with this; it's using static array sizing to make managing + all the modes a little less annoying. If we use a residue backend + with > 12 partition types, or a different division of iteration, + this needs to be updated. */ +typedef struct { + static_codebook *books[12][3]; +} static_bookblock; + +typedef struct { + int res_type; + int limit_type; /* 0 lowpass limited, 1 point stereo limited */ + vorbis_info_residue0 *res; + static_codebook *book_aux; + static_codebook *book_aux_managed; + static_bookblock *books_base; + static_bookblock *books_base_managed; +} vorbis_residue_template; + +typedef struct { + vorbis_info_mapping0 *map; + vorbis_residue_template *res; +} vorbis_mapping_template; + +typedef struct vp_adjblock{ + int block[P_BANDS]; +} vp_adjblock; + +typedef struct { + int data[NOISE_COMPAND_LEVELS]; +} compandblock; + +/* high level configuration information for setting things up + step-by-step with the detailed vorbis_encode_ctl interface. + There's a fair amount of redundancy such that interactive setup + does not directly deal with any vorbis_info or codec_setup_info + initialization; it's all stored (until full init) in this highlevel + setup, then flushed out to the real codec setup structs later. */ + +typedef struct { + int att[P_NOISECURVES]; + float boost; + float decay; +} att3; +typedef struct { int data[P_NOISECURVES]; } adj3; + +typedef struct { + int pre[PACKETBLOBS]; + int post[PACKETBLOBS]; + float kHz[PACKETBLOBS]; + float lowpasskHz[PACKETBLOBS]; +} adj_stereo; + +typedef struct { + int lo; + int hi; + int fixed; +} noiseguard; +typedef struct { + int data[P_NOISECURVES][17]; +} noise3; + +typedef struct { + int mappings; + double *rate_mapping; + double *quality_mapping; + int coupling_restriction; + long samplerate_min_restriction; + long samplerate_max_restriction; + + + int *blocksize_short; + int *blocksize_long; + + att3 *psy_tone_masteratt; + int *psy_tone_0dB; + int *psy_tone_dBsuppress; + + vp_adjblock *psy_tone_adj_impulse; + vp_adjblock *psy_tone_adj_long; + vp_adjblock *psy_tone_adj_other; + + noiseguard *psy_noiseguards; + noise3 *psy_noise_bias_impulse; + noise3 *psy_noise_bias_padding; + noise3 *psy_noise_bias_trans; + noise3 *psy_noise_bias_long; + int *psy_noise_dBsuppress; + + compandblock *psy_noise_compand; + double *psy_noise_compand_short_mapping; + double *psy_noise_compand_long_mapping; + + int *psy_noise_normal_start[2]; + int *psy_noise_normal_partition[2]; + double *psy_noise_normal_thresh; + + int *psy_ath_float; + int *psy_ath_abs; + + double *psy_lowpass; + + vorbis_info_psy_global *global_params; + double *global_mapping; + adj_stereo *stereo_modes; + + static_codebook ***floor_books; + vorbis_info_floor1 *floor_params; + int *floor_short_mapping; + int *floor_long_mapping; + + vorbis_mapping_template *maps; +} ve_setup_data_template; + +/* a few static coder conventions */ +static vorbis_info_mode _mode_template[2]={ + {0,0,0,0}, + {1,0,0,1} +}; + +static vorbis_info_mapping0 _map_nominal[2]={ + {1, {0,0}, {0}, {0}, 1,{0},{1}}, + {1, {0,0}, {1}, {1}, 1,{0},{1}} +}; + +#include "modes/setup_44.h" +#include "modes/setup_44u.h" +#include "modes/setup_32.h" +#include "modes/setup_8.h" +#include "modes/setup_11.h" +#include "modes/setup_16.h" +#include "modes/setup_22.h" +#include "modes/setup_X.h" + +static ve_setup_data_template *setup_list[]={ + &ve_setup_44_stereo, + &ve_setup_44_stereo_low, + &ve_setup_44_uncoupled, + &ve_setup_44_uncoupled_low, + + &ve_setup_32_stereo, + &ve_setup_32_stereo_low, + &ve_setup_32_uncoupled, + &ve_setup_32_uncoupled_low, + + &ve_setup_22_stereo, + &ve_setup_22_uncoupled, + &ve_setup_16_stereo, + &ve_setup_16_uncoupled, + + &ve_setup_11_stereo, + &ve_setup_11_uncoupled, + &ve_setup_8_stereo, + &ve_setup_8_uncoupled, + + &ve_setup_X_stereo, + &ve_setup_X_uncoupled, + &ve_setup_X_stereo_low, + &ve_setup_X_uncoupled_low, + &ve_setup_XX_stereo, + &ve_setup_XX_uncoupled, + 0 +}; + +static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){ + if(vi && vi->codec_setup){ + + vi->version=0; + vi->channels=ch; + vi->rate=rate; + + return(0); + } + return(OV_EINVAL); +} + +static void vorbis_encode_floor_setup(vorbis_info *vi,double s,int block, + static_codebook ***books, + vorbis_info_floor1 *in, + int *x){ + int i,k,is=s; + vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f)); + codec_setup_info *ci=vi->codec_setup; + + memcpy(f,in+x[is],sizeof(*f)); + /* fill in the lowpass field, even if it's temporary */ + f->n=ci->blocksizes[block]>>1; + + /* books */ + { + int partitions=f->partitions; + int maxclass=-1; + int maxbook=-1; + for(i=0;ipartitionclass[i]>maxclass)maxclass=f->partitionclass[i]; + for(i=0;i<=maxclass;i++){ + if(f->class_book[i]>maxbook)maxbook=f->class_book[i]; + f->class_book[i]+=ci->books; + for(k=0;k<(1<class_subs[i]);k++){ + if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k]; + if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books; + } + } + + for(i=0;i<=maxbook;i++) + ci->book_param[ci->books++]=books[x[is]][i]; + } + + /* for now, we're only using floor 1 */ + ci->floor_type[ci->floors]=1; + ci->floor_param[ci->floors]=f; + ci->floors++; + + return; +} + +static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s, + vorbis_info_psy_global *in, + double *x){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *g=&ci->psy_g_param; + + memcpy(g,in+(int)x[is],sizeof(*g)); + + ds=x[is]*(1.-ds)+x[is+1]*ds; + is=(int)ds; + ds-=is; + if(ds==0 && is>0){ + is--; + ds=1.; + } + + /* interpolate the trigger threshholds */ + for(i=0;i<4;i++){ + g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds; + g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds; + } + g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec; + return; +} + +static void vorbis_encode_global_stereo(vorbis_info *vi, + highlevel_encode_setup *hi, + adj_stereo *p){ + float s=hi->stereo_point_setting; + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *g=&ci->psy_g_param; + + if(p){ + memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS); + memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS); + + if(hi->managed){ + /* interpolate the kHz threshholds */ + for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + g->coupling_pkHz[i]=kHz; + + kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds; + g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + + } + }else{ + float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds; + for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + g->coupling_pkHz[i]=kHz; + } + + kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds; + for(i=0;isliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + } + } + }else{ + for(i=0;isliding_lowpass[0][i]=ci->blocksizes[0]; + g->sliding_lowpass[1][i]=ci->blocksizes[1]; + } + } + return; +} + +static void vorbis_encode_psyset_setup(vorbis_info *vi,double s, + int *nn_start, + int *nn_partition, + double *nn_thresh, + int block){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + highlevel_encode_setup *hi=&ci->hi; + int is=s; + + if(block>=ci->psys) + ci->psys=block+1; + if(!p){ + p=_ogg_calloc(1,sizeof(*p)); + ci->psy_param[block]=p; + } + + memcpy(p,&_psy_info_template,sizeof(*p)); + p->blockflag=block>>1; + + if(hi->noise_normalize_p){ + p->normal_channel_p=1; + p->normal_point_p=1; + p->normal_start=nn_start[is]; + p->normal_partition=nn_partition[is]; + p->normal_thresh=nn_thresh[is]; + } + + return; +} + +static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block, + att3 *att, + int *max, + vp_adjblock *in){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + /* 0 and 2 are only used by bitmanagement, but there's no harm to always + filling the values in here */ + p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds; + p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds; + p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds; + p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds; + p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds; + + p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds; + + for(i=0;itoneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds; + return; +} + + +static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block, + compandblock *in, double *x){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + ds=x[is]*(1.-ds)+x[is+1]*ds; + is=(int)ds; + ds-=is; + if(ds==0 && is>0){ + is--; + ds=1.; + } + + /* interpolate the compander settings */ + for(i=0;inoisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds; + return; +} + +static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block, + int *suppress){ + int is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds; + + return; +} + +static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block, + int *suppress, + noise3 *in, + noiseguard *guard, + double userbias){ + int i,is=s,j; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds; + p->noisewindowlomin=guard[block].lo; + p->noisewindowhimin=guard[block].hi; + p->noisewindowfixed=guard[block].fixed; + + for(j=0;jnoiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds; + + /* impulse blocks may take a user specified bias to boost the + nominal/high noise encoding depth */ + for(j=0;jnoiseoff[j][0]+6; /* the lowest it can go */ + for(i=0;inoiseoff[j][i]+=userbias; + if(p->noiseoff[j][i]noiseoff[j][i]=min; + } + } + + return; +} + +static void vorbis_encode_ath_setup(vorbis_info *vi,int block){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->ath_adjatt=ci->hi.ath_floating_dB; + p->ath_maxatt=ci->hi.ath_absolute_dB; + return; +} + + +static int book_dup_or_new(codec_setup_info *ci,static_codebook *book){ + int i; + for(i=0;ibooks;i++) + if(ci->book_param[i]==book)return(i); + + return(ci->books++); +} + +static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s, + int *shortb,int *longb){ + + codec_setup_info *ci=vi->codec_setup; + int is=s; + + int blockshort=shortb[is]; + int blocklong=longb[is]; + ci->blocksizes[0]=blockshort; + ci->blocksizes[1]=blocklong; + +} + +static void vorbis_encode_residue_setup(vorbis_info *vi, + int number, int block, + vorbis_residue_template *res){ + + codec_setup_info *ci=vi->codec_setup; + int i,n; + + vorbis_info_residue0 *r=ci->residue_param[number]= + _ogg_malloc(sizeof(*r)); + + memcpy(r,res->res,sizeof(*r)); + if(ci->residues<=number)ci->residues=number+1; + + switch(ci->blocksizes[block]){ + case 64:case 128:case 256: + r->grouping=16; + break; + default: + r->grouping=32; + break; + } + ci->residue_type[number]=res->res_type; + + /* to be adjusted by lowpass/pointlimit later */ + n=r->end=ci->blocksizes[block]>>1; + if(res->res_type==2) + n=r->end*=vi->channels; + + /* fill in all the books */ + { + int booklist=0,k; + + if(ci->hi.managed){ + for(i=0;ipartitions;i++) + for(k=0;k<3;k++) + if(res->books_base_managed->books[i][k]) + r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux_managed); + ci->book_param[r->groupbook]=res->book_aux_managed; + + for(i=0;ipartitions;i++){ + for(k=0;k<3;k++){ + if(res->books_base_managed->books[i][k]){ + int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); + r->booklist[booklist++]=bookid; + ci->book_param[bookid]=res->books_base_managed->books[i][k]; + } + } + } + + }else{ + + for(i=0;ipartitions;i++) + for(k=0;k<3;k++) + if(res->books_base->books[i][k]) + r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux); + ci->book_param[r->groupbook]=res->book_aux; + + for(i=0;ipartitions;i++){ + for(k=0;k<3;k++){ + if(res->books_base->books[i][k]){ + int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); + r->booklist[booklist++]=bookid; + ci->book_param[bookid]=res->books_base->books[i][k]; + } + } + } + } + } + + /* lowpass setup/pointlimit */ + { + double freq=ci->hi.lowpass_kHz*1000.; + vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */ + double nyq=vi->rate/2.; + long blocksize=ci->blocksizes[block]>>1; + + /* lowpass needs to be set in the floor and the residue. */ + if(freq>nyq)freq=nyq; + /* in the floor, the granularity can be very fine; it doesn't alter + the encoding structure, only the samples used to fit the floor + approximation */ + f->n=freq/nyq*blocksize; + + /* this res may by limited by the maximum pointlimit of the mode, + not the lowpass. the floor is always lowpass limited. */ + if(res->limit_type){ + if(ci->hi.managed) + freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.; + else + freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.; + if(freq>nyq)freq=nyq; + } + + /* in the residue, we're constrained, physically, by partition + boundaries. We still lowpass 'wherever', but we have to round up + here to next boundary, or the vorbis spec will round it *down* to + previous boundary in encode/decode */ + if(ci->residue_type[block]==2) + r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + else + r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + } +} + +/* we assume two maps in this encoder */ +static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s, + vorbis_mapping_template *maps){ + + codec_setup_info *ci=vi->codec_setup; + int i,j,is=s,modes=2; + vorbis_info_mapping0 *map=maps[is].map; + vorbis_info_mode *mode=_mode_template; + vorbis_residue_template *res=maps[is].res; + + if(ci->blocksizes[0]==ci->blocksizes[1])modes=1; + + for(i=0;imap_param[i]=_ogg_calloc(1,sizeof(*map)); + ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode)); + + memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template)); + if(i>=ci->modes)ci->modes=i+1; + + ci->map_type[i]=0; + memcpy(ci->map_param[i],map+i,sizeof(*map)); + if(i>=ci->maps)ci->maps=i+1; + + for(j=0;jcodec_setup; + highlevel_encode_setup *hi=&ci->hi; + ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup; + int is=hi->base_setting; + double ds=hi->base_setting-is; + int ch=vi->channels; + double *r=setup->rate_mapping; + + if(r==NULL) + return(-1); + + return((r[is]*(1.-ds)+r[is+1]*ds)*ch); +} + +static void get_setup_template(vorbis_info *vi, + long ch,long srate, + double req,int q_or_bitrate){ + int i=0,j; + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + if(q_or_bitrate)req/=ch; + + while(setup_list[i]){ + if(setup_list[i]->coupling_restriction==-1 || + setup_list[i]->coupling_restriction==ch){ + if(srate>=setup_list[i]->samplerate_min_restriction && + srate<=setup_list[i]->samplerate_max_restriction){ + int mappings=setup_list[i]->mappings; + double *map=(q_or_bitrate? + setup_list[i]->rate_mapping: + setup_list[i]->quality_mapping); + + /* the template matches. Does the requested quality mode + fall within this template's modes? */ + if(reqmap[setup_list[i]->mappings]){++i;continue;} + for(j=0;j=map[j] && reqsetup=setup_list[i]; + if(j==mappings) + hi->base_setting=j-.001; + else{ + float low=map[j]; + float high=map[j+1]; + float del=(req-low)/(high-low); + hi->base_setting=j+del; + } + return; + } + } + i++; + } + + hi->setup=NULL; +} + +/* encoders will need to use vorbis_info_init beforehand and call + vorbis_info clear when all done */ + +/* two interfaces; this, more detailed one, and later a convenience + layer on top */ + +/* the final setup call */ +int vorbis_encode_setup_init(vorbis_info *vi){ + int i0=0,singleblock=0; + codec_setup_info *ci=vi->codec_setup; + ve_setup_data_template *setup=NULL; + highlevel_encode_setup *hi=&ci->hi; + + if(ci==NULL)return(OV_EINVAL); + if(!hi->impulse_block_p)i0=1; + + /* too low/high an ATH floater is nonsensical, but doesn't break anything */ + if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80; + if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200; + + /* again, bound this to avoid the app shooting itself int he foot + too badly */ + if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.; + if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.; + + /* get the appropriate setup template; matches the fetch in previous + stages */ + setup=(ve_setup_data_template *)hi->setup; + if(setup==NULL)return(OV_EINVAL); + + hi->set_in_stone=1; + /* choose block sizes from configured sizes as well as paying + attention to long_block_p and short_block_p. If the configured + short and long blocks are the same length, we set long_block_p + and unset short_block_p */ + vorbis_encode_blocksize_setup(vi,hi->base_setting, + setup->blocksize_short, + setup->blocksize_long); + if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1; + + /* floor setup; choose proper floor params. Allocated on the floor + stack in order; if we alloc only long floor, it's 0 */ + vorbis_encode_floor_setup(vi,hi->short_setting,0, + setup->floor_books, + setup->floor_params, + setup->floor_short_mapping); + if(!singleblock) + vorbis_encode_floor_setup(vi,hi->long_setting,1, + setup->floor_books, + setup->floor_params, + setup->floor_long_mapping); + + /* setup of [mostly] short block detection and stereo*/ + vorbis_encode_global_psych_setup(vi,hi->trigger_setting, + setup->global_params, + setup->global_mapping); + vorbis_encode_global_stereo(vi,hi,setup->stereo_modes); + + /* basic psych setup and noise normalization */ + vorbis_encode_psyset_setup(vi,hi->short_setting, + setup->psy_noise_normal_start[0], + setup->psy_noise_normal_partition[0], + setup->psy_noise_normal_thresh, + 0); + vorbis_encode_psyset_setup(vi,hi->short_setting, + setup->psy_noise_normal_start[0], + setup->psy_noise_normal_partition[0], + setup->psy_noise_normal_thresh, + 1); + if(!singleblock){ + vorbis_encode_psyset_setup(vi,hi->long_setting, + setup->psy_noise_normal_start[1], + setup->psy_noise_normal_partition[1], + setup->psy_noise_normal_thresh, + 2); + vorbis_encode_psyset_setup(vi,hi->long_setting, + setup->psy_noise_normal_start[1], + setup->psy_noise_normal_partition[1], + setup->psy_noise_normal_thresh, + 3); + } + + /* tone masking setup */ + vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_impulse); + vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_other); + if(!singleblock){ + vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_other); + vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_long); + } + + /* noise companding setup */ + vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0, + setup->psy_noise_compand, + setup->psy_noise_compand_short_mapping); + vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1, + setup->psy_noise_compand, + setup->psy_noise_compand_short_mapping); + if(!singleblock){ + vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2, + setup->psy_noise_compand, + setup->psy_noise_compand_long_mapping); + vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3, + setup->psy_noise_compand, + setup->psy_noise_compand_long_mapping); + } + + /* peak guarding setup */ + vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0, + setup->psy_tone_dBsuppress); + vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1, + setup->psy_tone_dBsuppress); + if(!singleblock){ + vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2, + setup->psy_tone_dBsuppress); + vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3, + setup->psy_tone_dBsuppress); + } + + /* noise bias setup */ + vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_impulse, + setup->psy_noiseguards, + (i0==0?hi->impulse_noisetune:0.)); + vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_padding, + setup->psy_noiseguards,0.); + if(!singleblock){ + vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_trans, + setup->psy_noiseguards,0.); + vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_long, + setup->psy_noiseguards,0.); + } + + vorbis_encode_ath_setup(vi,0); + vorbis_encode_ath_setup(vi,1); + if(!singleblock){ + vorbis_encode_ath_setup(vi,2); + vorbis_encode_ath_setup(vi,3); + } + + vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps); + + /* set bitrate readonlies and management */ + vi->bitrate_nominal=setting_to_approx_bitrate(vi); + vi->bitrate_lower=hi->bitrate_min; + vi->bitrate_upper=hi->bitrate_max; + vi->bitrate_window=hi->bitrate_limit_window; + + if(hi->managed){ + ci->bi.queue_avg_time=hi->bitrate_av_window; + ci->bi.queue_avg_center=hi->bitrate_av_window_center; + ci->bi.queue_minmax_time=hi->bitrate_limit_window; + ci->bi.queue_hardmin=hi->bitrate_min; + ci->bi.queue_hardmax=hi->bitrate_max; + ci->bi.queue_avgmin=hi->bitrate_av_lo; + ci->bi.queue_avgmax=hi->bitrate_av_hi; + ci->bi.avgfloat_downslew_max=-999999.f; + ci->bi.avgfloat_upslew_max=999999.f; + } + + return(0); + +} + +static int vorbis_encode_setup_setting(vorbis_info *vi, + long channels, + long rate){ + int ret=0,i,is; + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + ve_setup_data_template *setup=hi->setup; + double ds; + + ret=vorbis_encode_toplevel_setup(vi,channels,rate); + if(ret)return(ret); + + is=hi->base_setting; + ds=hi->base_setting-is; + + hi->short_setting=hi->base_setting; + hi->long_setting=hi->base_setting; + + hi->managed=0; + + hi->impulse_block_p=1; + hi->noise_normalize_p=1; + + hi->stereo_point_setting=hi->base_setting; + hi->lowpass_kHz= + setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds; + + hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+ + setup->psy_ath_float[is+1]*ds; + hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+ + setup->psy_ath_abs[is+1]*ds; + + hi->amplitude_track_dBpersec=-6.; + hi->trigger_setting=hi->base_setting; + + for(i=0;i<4;i++){ + hi->block[i].tone_mask_setting=hi->base_setting; + hi->block[i].tone_peaklimit_setting=hi->base_setting; + hi->block[i].noise_bias_setting=hi->base_setting; + hi->block[i].noise_compand_setting=hi->base_setting; + } + + return(ret); +} + +int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + float quality){ + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + + quality+=.00001; + if(quality>=1.)quality=.9999; + + get_setup_template(vi,channels,rate,quality,0); + if(!hi->setup)return OV_EIMPL; + + return vorbis_encode_setup_setting(vi,channels,rate); +} + +int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality /* 0. to 1. */ + ){ + int ret=0; + + ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality); + + if(ret){ + vorbis_info_clear(vi); + return ret; + } + ret=vorbis_encode_setup_init(vi); + if(ret) + vorbis_info_clear(vi); + return(ret); +} + +int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate){ + + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + double tnominal=nominal_bitrate; + int ret=0; + + if(nominal_bitrate<=0.){ + if(max_bitrate>0.){ + nominal_bitrate=max_bitrate*.875; + }else{ + if(min_bitrate>0.){ + nominal_bitrate=min_bitrate; + }else{ + return(OV_EINVAL); + } + } + } + + get_setup_template(vi,channels,rate,nominal_bitrate,1); + if(!hi->setup)return OV_EIMPL; + + ret=vorbis_encode_setup_setting(vi,channels,rate); + if(ret){ + vorbis_info_clear(vi); + return ret; + } + + /* initialize management with sane defaults */ + /* initialize management with sane defaults */ + hi->managed=1; + hi->bitrate_av_window=4.; + hi->bitrate_av_window_center=.5; + hi->bitrate_limit_window=2.; + hi->bitrate_min=min_bitrate; + hi->bitrate_max=max_bitrate; + hi->bitrate_av_lo=tnominal; + hi->bitrate_av_hi=tnominal; + + return(ret); + +} + +int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate){ + + int ret=vorbis_encode_setup_managed(vi,channels,rate, + max_bitrate, + nominal_bitrate, + min_bitrate); + if(ret){ + vorbis_info_clear(vi); + return(ret); + } + + ret=vorbis_encode_setup_init(vi); + if(ret) + vorbis_info_clear(vi); + return(ret); +} + +int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ + if(vi){ + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + int setp=(number&0xf); /* a read request has a low nibble of 0 */ + + if(setp && hi->set_in_stone)return(OV_EINVAL); + + switch(number){ + case OV_ECTL_RATEMANAGE_GET: + { + + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + + ai->management_active=hi->managed; + ai->bitrate_av_window=hi->bitrate_av_window; + ai->bitrate_av_window_center=hi->bitrate_av_window_center; + ai->bitrate_hard_window=hi->bitrate_limit_window; + ai->bitrate_hard_min=hi->bitrate_min; + ai->bitrate_hard_max=hi->bitrate_max; + ai->bitrate_av_lo=hi->bitrate_av_lo; + ai->bitrate_av_hi=hi->bitrate_av_hi; + + } + return(0); + + case OV_ECTL_RATEMANAGE_SET: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->managed=0; + }else{ + hi->managed=ai->management_active; + vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg); + vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg); + } + } + return 0; + + case OV_ECTL_RATEMANAGE_AVG: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->bitrate_av_lo=0; + hi->bitrate_av_hi=0; + hi->bitrate_av_window=0; + }else{ + hi->bitrate_av_window=ai->bitrate_av_window; + hi->bitrate_av_window_center=ai->bitrate_av_window_center; + hi->bitrate_av_lo=ai->bitrate_av_lo; + hi->bitrate_av_hi=ai->bitrate_av_hi; + } + + if(hi->bitrate_av_window<.25)hi->bitrate_av_window=.25; + if(hi->bitrate_av_window>10.)hi->bitrate_av_window=10.; + if(hi->bitrate_av_window_center<0.)hi->bitrate_av_window=0.; + if(hi->bitrate_av_window_center>1.)hi->bitrate_av_window=1.; + + if( ( (hi->bitrate_av_lo<=0 && hi->bitrate_av_hi<=0)|| + (hi->bitrate_av_window<=0) ) && + ( (hi->bitrate_min<=0 && hi->bitrate_max<=0)|| + (hi->bitrate_limit_window<=0) )) + hi->managed=0; + } + return(0); + case OV_ECTL_RATEMANAGE_HARD: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->bitrate_min=0; + hi->bitrate_max=0; + hi->bitrate_limit_window=0; + }else{ + hi->bitrate_limit_window=ai->bitrate_hard_window; + hi->bitrate_min=ai->bitrate_hard_min; + hi->bitrate_max=ai->bitrate_hard_max; + } + if(hi->bitrate_limit_window<0.)hi->bitrate_limit_window=0.; + if(hi->bitrate_limit_window>10.)hi->bitrate_limit_window=10.; + + if( ( (hi->bitrate_av_lo<=0 && hi->bitrate_av_hi<=0)|| + (hi->bitrate_av_window<=0) ) && + ( (hi->bitrate_min<=0 && hi->bitrate_max<=0)|| + (hi->bitrate_limit_window<=0) )) + hi->managed=0; + } + return(0); + + case OV_ECTL_LOWPASS_GET: + { + double *farg=(double *)arg; + *farg=hi->lowpass_kHz; + } + return(0); + case OV_ECTL_LOWPASS_SET: + { + double *farg=(double *)arg; + hi->lowpass_kHz=*farg; + + if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.; + if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.; + } + return(0); + case OV_ECTL_IBLOCK_GET: + { + double *farg=(double *)arg; + *farg=hi->impulse_noisetune; + } + return(0); + case OV_ECTL_IBLOCK_SET: + { + double *farg=(double *)arg; + hi->impulse_noisetune=*farg; + + if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.; + if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.; + } + return(0); + } + + + return(OV_EIMPL); + } + return(OV_EINVAL); +} diff --git a/sound/OggVorbis/vorbissrc/vorbisfile.c b/sound/OggVorbis/vorbissrc/vorbisfile.c new file mode 100644 index 000000000..9093ec4b8 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/vorbisfile.c @@ -0,0 +1,1981 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.c,v 1.75 2003/09/16 20:28:14 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include +#include + +#include "../vorbis/codec.h" +#include "../vorbis/vorbisfile.h" + +#include "os.h" +#include "misc.h" + +/* A 'chained bitstream' is a Vorbis bitstream that contains more than + one logical bitstream arranged end to end (the only form of Ogg + multiplexing allowed in a Vorbis bitstream; grouping [parallel + multiplexing] is not allowed in Vorbis) */ + +/* A Vorbis file can be played beginning to end (streamed) without + worrying ahead of time about chaining (see decoder_example.c). If + we have the whole file, however, and want random access + (seeking/scrubbing) or desire to know the total length/time of a + file, we need to account for the possibility of chaining. */ + +/* We can handle things a number of ways; we can determine the entire + bitstream structure right off the bat, or find pieces on demand. + This example determines and caches structure for the entire + bitstream, but builds a virtual decoder on the fly when moving + between links in the chain. */ + +/* There are also different ways to implement seeking. Enough + information exists in an Ogg bitstream to seek to + sample-granularity positions in the output. Or, one can seek by + picking some portion of the stream roughly in the desired area if + we only want coarse navigation through the stream. */ + +/************************************************************************* + * Many, many internal helpers. The intention is not to be confusing; + * rampant duplication and monolithic function implementation would be + * harder to understand anyway. The high level functions are last. Begin + * grokking near the end of the file */ + +/* read a little more data from the file/pipe into the ogg_sync framer +*/ +#define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well + over 8k gets what they deserve */ +static long _get_data(OggVorbis_File *vf){ + errno=0; + if(vf->datasource){ + char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE); + long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); + if(bytes>0)ogg_sync_wrote(&vf->oy,bytes); + if(bytes==0 && errno)return(-1); + return(bytes); + }else + return(0); +} + +/* save a tiny smidge of verbosity to make the code more readable */ +static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){ + if(vf->datasource){ + (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET); + vf->offset=offset; + ogg_sync_reset(&vf->oy); + }else{ + /* shouldn't happen unless someone writes a broken callback */ + return; + } +} + +/* The read/seek functions track absolute position within the stream */ + +/* from the head of the stream, get the next page. boundary specifies + if the function is allowed to fetch more data from the stream (and + how much) or only use internally buffered data. + + boundary: -1) unbounded search + 0) read no additional data; use cached only + n) search for a new page beginning for n bytes + + return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) + n) found a page at absolute offset n */ + +static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, + ogg_int64_t boundary){ + if(boundary>0)boundary+=vf->offset; + while(1){ + long more; + + if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); + more=ogg_sync_pageseek(&vf->oy,og); + + if(more<0){ + /* skipped n bytes */ + vf->offset-=more; + }else{ + if(more==0){ + /* send more paramedics */ + if(!boundary)return(OV_FALSE); + { + long ret=_get_data(vf); + if(ret==0)return(OV_EOF); + if(ret<0)return(OV_EREAD); + } + }else{ + /* got a page. Return the offset at the page beginning, + advance the internal offset past the page end */ + ogg_int64_t ret=vf->offset; + vf->offset+=more; + return(ret); + + } + } + } +} + +/* find the latest page beginning before the current stream cursor + position. Much dirtier than the above as Ogg doesn't have any + backward search linkage. no 'readp' as it will certainly have to + read. */ +/* returns offset or OV_EREAD, OV_FAULT */ +static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ + ogg_int64_t begin=vf->offset; + ogg_int64_t end=begin; + ogg_int64_t ret; + ogg_int64_t offset=-1; + + while(offset==-1){ + begin-=CHUNKSIZE; + if(begin<0) + begin=0; + _seek_helper(vf,begin); + while(vf->offsetoffset); + if(ret==OV_EREAD)return(OV_EREAD); + if(ret<0){ + break; + }else{ + offset=ret; + } + } + } + + /* we have the offset. Actually snork and hold the page now */ + _seek_helper(vf,offset); + ret=_get_next_page(vf,og,CHUNKSIZE); + if(ret<0) + /* this shouldn't be possible */ + return(OV_EFAULT); + + return(offset); +} + +/* finds each bitstream link one at a time using a bisection search + (has to begin by knowing the offset of the lb's initial page). + Recurses for each link so it can alloc the link storage after + finding them all, then unroll and fill the cache at the same time */ +static int _bisect_forward_serialno(OggVorbis_File *vf, + ogg_int64_t begin, + ogg_int64_t searched, + ogg_int64_t end, + long currentno, + long m){ + ogg_int64_t endsearched=end; + ogg_int64_t next=end; + ogg_page og; + ogg_int64_t ret; + + /* the below guards against garbage seperating the last and + first pages of two links. */ + while(searched=0)next=ret; + }else{ + searched=ret+og.header_len+og.body_len; + } + } + + _seek_helper(vf,next); + ret=_get_next_page(vf,&og,-1); + if(ret==OV_EREAD)return(OV_EREAD); + + if(searched>=end || ret<0){ + vf->links=m+1; + vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); + vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); + vf->offsets[m+1]=searched; + }else{ + ret=_bisect_forward_serialno(vf,next,vf->offset, + end,ogg_page_serialno(&og),m+1); + if(ret==OV_EREAD)return(OV_EREAD); + } + + vf->offsets[m]=begin; + vf->serialnos[m]=currentno; + return(0); +} + +/* uses the local ogg_stream storage in vf; this is important for + non-streaming input sources */ +static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, + long *serialno,ogg_page *og_ptr){ + ogg_page og; + ogg_packet op; + int i,ret; + + if(!og_ptr){ + ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); + if(llret==OV_EREAD)return(OV_EREAD); + if(llret<0)return OV_ENOTVORBIS; + og_ptr=&og; + } + + ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); + if(serialno)*serialno=vf->os.serialno; + vf->ready_state=STREAMSET; + + /* extract the initial header from the first page and verify that the + Ogg bitstream is in fact Vorbis data */ + + vorbis_info_init(vi); + vorbis_comment_init(vc); + + i=0; + while(i<3){ + ogg_stream_pagein(&vf->os,og_ptr); + while(i<3){ + int result=ogg_stream_packetout(&vf->os,&op); + if(result==0)break; + if(result==-1){ + ret=OV_EBADHEADER; + goto bail_header; + } + if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ + goto bail_header; + } + i++; + } + if(i<3) + if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){ + ret=OV_EBADHEADER; + goto bail_header; + } + } + return 0; + + bail_header: + vorbis_info_clear(vi); + vorbis_comment_clear(vc); + vf->ready_state=OPENED; + + return ret; +} + +/* last step of the OggVorbis_File initialization; get all the + vorbis_info structs and PCM positions. Only called by the seekable + initialization (local stream storage is hacked slightly; pay + attention to how that's done) */ + +/* this is void and does not propogate errors up because we want to be + able to open and use damaged bitstreams as well as we can. Just + watch out for missing information for links in the OggVorbis_File + struct */ +static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){ + ogg_page og; + int i; + ogg_int64_t ret; + + vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); + vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); + vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); + vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); + + for(i=0;ilinks;i++){ + if(i==0){ + /* we already grabbed the initial header earlier. Just set the offset */ + vf->dataoffsets[i]=dataoffset; + _seek_helper(vf,dataoffset); + + }else{ + + /* seek to the location of the initial header */ + + _seek_helper(vf,vf->offsets[i]); + if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){ + vf->dataoffsets[i]=-1; + }else{ + vf->dataoffsets[i]=vf->offset; + } + } + + /* fetch beginning PCM offset */ + + if(vf->dataoffsets[i]!=-1){ + ogg_int64_t accumulated=0; + long lastblock=-1; + int result; + + ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]); + + while(1){ + ogg_packet op; + + ret=_get_next_page(vf,&og,-1); + if(ret<0) + /* this should not be possible unless the file is + truncated/mangled */ + break; + + if(ogg_page_serialno(&og)!=vf->serialnos[i]) + break; + + /* count blocksizes of all frames in the page */ + ogg_stream_pagein(&vf->os,&og); + while((result=ogg_stream_packetout(&vf->os,&op))){ + if(result>0){ /* ignore holes */ + long thisblock=vorbis_packet_blocksize(vf->vi+i,&op); + if(lastblock!=-1) + accumulated+=(lastblock+thisblock)>>2; + lastblock=thisblock; + } + } + + if(ogg_page_granulepos(&og)!=-1){ + /* pcm offset of last packet on the first audio page */ + accumulated= ogg_page_granulepos(&og)-accumulated; + break; + } + } + + /* less than zero? This is a stream with samples trimmed off + the beginning, a normal occurrence; set the offset to zero */ + if(accumulated<0)accumulated=0; + + vf->pcmlengths[i*2]=accumulated; + } + + /* get the PCM length of this link. To do this, + get the last page of the stream */ + { + ogg_int64_t end=vf->offsets[i+1]; + _seek_helper(vf,end); + + while(1){ + ret=_get_prev_page(vf,&og); + if(ret<0){ + /* this should not be possible */ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + break; + } + if(ogg_page_granulepos(&og)!=-1){ + vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2]; + break; + } + vf->offset=ret; + } + } + } +} + +static int _make_decode_ready(OggVorbis_File *vf){ + if(vf->ready_state>STREAMSET)return 0; + if(vf->ready_stateseekable){ + if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link)) + return OV_EBADLINK; + }else{ + if(vorbis_synthesis_init(&vf->vd,vf->vi)) + return OV_EBADLINK; + } + vorbis_block_init(&vf->vd,&vf->vb); + vf->ready_state=INITSET; + vf->bittrack=0.f; + vf->samptrack=0.f; + return 0; +} + +static int _open_seekable2(OggVorbis_File *vf){ + long serialno=vf->current_serialno; + ogg_int64_t dataoffset=vf->offset, end; + ogg_page og; + + /* we're partially open and have a first link header state in + storage in vf */ + /* we can seek, so set out learning all about this file */ + (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END); + vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource); + + /* We get the offset for the last page of the physical bitstream. + Most OggVorbis files will contain a single logical bitstream */ + end=_get_prev_page(vf,&og); + if(end<0)return(end); + + /* more than one logical bitstream? */ + if(ogg_page_serialno(&og)!=serialno){ + + /* Chained bitstream. Bisect-search each logical bitstream + section. Do so based on serial number only */ + if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD); + + }else{ + + /* Only one logical bitstream */ + if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD); + + } + + /* the initial header memory is referenced by vf after; don't free it */ + _prefetch_all_headers(vf,dataoffset); + return(ov_raw_seek(vf,0)); +} + +/* clear out the current logical bitstream decoder */ +static void _decode_clear(OggVorbis_File *vf){ + vorbis_dsp_clear(&vf->vd); + vorbis_block_clear(&vf->vb); + vf->ready_state=OPENED; +} + +/* fetch and process a packet. Handles the case where we're at a + bitstream boundary and dumps the decoding machine. If the decoding + machine is unloaded, it loads it. It also keeps pcm_offset up to + date (seek and read both use this. seek uses a special hack with + readp). + + return: <0) error, OV_HOLE (lost packet) or OV_EOF + 0) need more data (only if readp==0) + 1) got a packet +*/ + +static int _fetch_and_process_packet(OggVorbis_File *vf, + ogg_packet *op_in, + int readp, + int spanp){ + ogg_page og; + + /* handle one packet. Try to fetch it from current stream state */ + /* extract packets from page */ + while(1){ + + /* process a packet if we can. If the machine isn't loaded, + neither is a page */ + if(vf->ready_state==INITSET){ + while(1) { + ogg_packet op; + ogg_packet *op_ptr=(op_in?op_in:&op); + int result=ogg_stream_packetout(&vf->os,op_ptr); + ogg_int64_t granulepos; + + op_in=NULL; + if(result==-1)return(OV_HOLE); /* hole in the data. */ + if(result>0){ + /* got a packet. process it */ + granulepos=op_ptr->granulepos; + if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy + header handling. The + header packets aren't + audio, so if/when we + submit them, + vorbis_synthesis will + reject them */ + + /* suck in the synthesis data and track bitrate */ + { + int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); + /* for proper use of libvorbis within libvorbisfile, + oldsamples will always be zero. */ + if(oldsamples)return(OV_EFAULT); + + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; + vf->bittrack+=op_ptr->bytes*8; + } + + /* update the pcm offset. */ + if(granulepos!=-1 && !op_ptr->e_o_s){ + int link=(vf->seekable?vf->current_link:0); + int i,samples; + + /* this packet has a pcm_offset on it (the last packet + completed on a page carries the offset) After processing + (above), we know the pcm position of the *last* sample + ready to be returned. Find the offset of the *first* + + As an aside, this trick is inaccurate if we begin + reading anew right at the last page; the end-of-stream + granulepos declares the last frame in the stream, and the + last packet of the last page may be a partial frame. + So, we need a previous granulepos from an in-sequence page + to have a reference point. Thus the !op_ptr->e_o_s clause + above */ + + if(vf->seekable && link>0) + granulepos-=vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; /* actually, this + shouldn't be possible + here unless the stream + is very broken */ + + samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + granulepos-=samples; + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos; + } + return(1); + } + } + else + break; + } + } + + if(vf->ready_state>=OPENED){ + int ret; + if(!readp)return(0); + if((ret=_get_next_page(vf,&og,-1))<0){ + return(OV_EOF); /* eof. + leave unitialized */ + } + + /* bitrate tracking; add the header's bytes here, the body bytes + are done by packet above */ + vf->bittrack+=og.header_len*8; + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state==INITSET){ + if(vf->current_serialno!=ogg_page_serialno(&og)){ + if(!spanp) + return(OV_EOF); + + _decode_clear(vf); + + if(!vf->seekable){ + vorbis_info_clear(vf->vi); + vorbis_comment_clear(vf->vc); + } + } + } + } + + /* Do we need to load a new machine before submitting the page? */ + /* This is different in the seekable and non-seekable cases. + + In the seekable case, we already have all the header + information loaded and cached; we just initialize the machine + with it and continue on our merry way. + + In the non-seekable (streaming) case, we'll only be at a + boundary if we just left the previous logical bitstream and + we're now nominally at the header of the next bitstream + */ + + if(vf->ready_state!=INITSET){ + int link; + + if(vf->ready_stateseekable){ + vf->current_serialno=ogg_page_serialno(&og); + + /* match the serialno to bitstream section. We use this rather than + offset positions to avoid problems near logical bitstream + boundaries */ + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus + stream. error out, + leave machine + uninitialized */ + + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + + }else{ + /* we're streaming */ + /* fetch the three header packets, build the info struct */ + + int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og); + if(ret)return(ret); + vf->current_link++; + link=0; + } + } + + { + int ret=_make_decode_ready(vf); + if(ret<0)return ret; + } + } + ogg_stream_pagein(&vf->os,&og); + } +} + +/* if, eg, 64 bit stdio is configured by default, this will build with + fseek64 */ +static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + return fseek(f,off,whence); +} + +static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, + long ibytes, ov_callbacks callbacks){ + int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1); + int ret; + + memset(vf,0,sizeof(*vf)); + vf->datasource=f; + vf->callbacks = callbacks; + + /* init the framing state */ + ogg_sync_init(&vf->oy); + + /* perhaps some data was previously read into a buffer for testing + against other stream types. Allow initialization from this + previously read data (as we may be reading from a non-seekable + stream) */ + if(initial){ + char *buffer=ogg_sync_buffer(&vf->oy,ibytes); + memcpy(buffer,initial,ibytes); + ogg_sync_wrote(&vf->oy,ibytes); + } + + /* can we seek? Stevens suggests the seek test was portable */ + if(offsettest!=-1)vf->seekable=1; + + /* No seeking yet; Set up a 'single' (current) logical bitstream + entry for partial open */ + vf->links=1; + vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); + vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); + ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ + + /* Try to fetch the headers, maintaining all the storage */ + if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){ + vf->datasource=NULL; + ov_clear(vf); + }else + vf->ready_state=PARTOPEN; + return(ret); +} + +static int _ov_open2(OggVorbis_File *vf){ + if(vf->ready_state != PARTOPEN) return OV_EINVAL; + vf->ready_state=OPENED; + if(vf->seekable){ + int ret=_open_seekable2(vf); + if(ret){ + vf->datasource=NULL; + ov_clear(vf); + } + return(ret); + }else + vf->ready_state=STREAMSET; + + return 0; +} + + +/* clear out the OggVorbis_File struct */ +int ov_clear(OggVorbis_File *vf){ + if(vf){ + vorbis_block_clear(&vf->vb); + vorbis_dsp_clear(&vf->vd); + ogg_stream_clear(&vf->os); + + if(vf->vi && vf->links){ + int i; + for(i=0;ilinks;i++){ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + } + _ogg_free(vf->vi); + _ogg_free(vf->vc); + } + if(vf->dataoffsets)_ogg_free(vf->dataoffsets); + if(vf->pcmlengths)_ogg_free(vf->pcmlengths); + if(vf->serialnos)_ogg_free(vf->serialnos); + if(vf->offsets)_ogg_free(vf->offsets); + ogg_sync_clear(&vf->oy); + if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); + memset(vf,0,sizeof(*vf)); + } +#ifdef DEBUG_LEAKS + _VDBG_dump(); +#endif + return(0); +} + +/* inspects the OggVorbis file and finds/documents all the logical + bitstreams contained in it. Tries to be tolerant of logical + bitstream sections that are truncated/woogie. + + return: -1) error + 0) OK +*/ + +int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks){ + int ret=_ov_open1(f,vf,initial,ibytes,callbacks); + if(ret)return ret; + return _ov_open2(vf); +} + +int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +/* cheap hack for game usage where downsampling is desirable; there's + no need for SRC as we can just do it cheaply in libvorbis. */ + +int ov_halfrate(OggVorbis_File *vf,int flag){ + int i; + if(vf->vi==NULL)return OV_EINVAL; + if(!vf->seekable)return OV_EINVAL; + if(vf->ready_state>=STREAMSET) + _decode_clear(vf); /* clear out stream state; later on libvorbis + will be able to swap this on the fly, but + for now dumping the decode machine is needed + to reinit the MDCT lookups. 1.1 libvorbis + is planned to be able to switch on the fly */ + + for(i=0;ilinks;i++){ + if(vorbis_synthesis_halfrate(vf->vi+i,flag)){ + ov_halfrate(vf,0); + return OV_EINVAL; + } + } + return 0; +} + +int ov_halfrate_p(OggVorbis_File *vf){ + if(vf->vi==NULL)return OV_EINVAL; + return vorbis_synthesis_halfrate_p(vf->vi); +} + +/* Only partially open the vorbis file; test for Vorbisness, and load + the headers for the first chain. Do not seek (although test for + seekability). Use ov_test_open to finish opening the file, else + ov_clear to close/free it. Same return codes as open. */ + +int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks) +{ + return _ov_open1(f,vf,initial,ibytes,callbacks); +} + +int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +int ov_test_open(OggVorbis_File *vf){ + if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); + return _ov_open2(vf); +} + +/* How many logical bitstreams in this physical bitstream? */ +long ov_streams(OggVorbis_File *vf){ + return vf->links; +} + +/* Is the FILE * associated with vf seekable? */ +long ov_seekable(OggVorbis_File *vf){ + return vf->seekable; +} + +/* returns the bitrate for a given logical bitstream or the entire + physical bitstream. If the file is open for random access, it will + find the *actual* average bitrate. If the file is streaming, it + returns the nominal bitrate (if set) else the average of the + upper/lower bounds (if set) else -1 (unset). + + If you want the actual bitrate field settings, get them from the + vorbis_info structs */ + +long ov_bitrate(OggVorbis_File *vf,int i){ + if(vf->ready_state=vf->links)return(OV_EINVAL); + if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); + if(i<0){ + ogg_int64_t bits=0; + int i; + float br; + for(i=0;ilinks;i++) + bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8; + /* This once read: return(rint(bits/ov_TIME_Total(vf,-1))); + * gcc 3.x on x86 miscompiled this at optimisation level 2 and above, + * so this is slightly transformed to make it work. + */ + br = bits/ov_TIME_Total(vf,-1); + return(rint(br)); + }else{ + if(vf->seekable){ + /* return the actual bitrate */ + return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_TIME_Total(vf,i))); + }else{ + /* return nominal if set */ + if(vf->vi[i].bitrate_nominal>0){ + return vf->vi[i].bitrate_nominal; + }else{ + if(vf->vi[i].bitrate_upper>0){ + if(vf->vi[i].bitrate_lower>0){ + return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2; + }else{ + return vf->vi[i].bitrate_upper; + } + } + return(OV_FALSE); + } + } + } +} + +/* returns the actual bitrate since last call. returns -1 if no + additional data to offer since last call (or at beginning of stream), + EINVAL if stream is only partially open +*/ +long ov_bitrate_instant(OggVorbis_File *vf){ + int link=(vf->seekable?vf->current_link:0); + long ret; + if(vf->ready_statesamptrack==0)return(OV_FALSE); + ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5; + vf->bittrack=0.f; + vf->samptrack=0.f; + return(ret); +} + +/* Guess */ +long ov_serialnumber(OggVorbis_File *vf,int i){ + if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1)); + if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1)); + if(i<0){ + return(vf->current_serialno); + }else{ + return(vf->serialnos[i]); + } +} + +/* returns: total raw (compressed) length of content if i==-1 + raw (compressed) length of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the length) + or if stream is only partially open +*/ +ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_raw_total(vf,i); + return(acc); + }else{ + return(vf->offsets[i+1]-vf->offsets[i]); + } +} + +/* returns: total PCM length (samples) of content if i==-1 PCM length + (samples) of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_pcm_total(vf,i); + return(acc); + }else{ + return(vf->pcmlengths[i*2+1]); + } +} + +/* returns: total seconds of content if i==-1 + seconds in that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +double ov_TIME_Total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + double acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_TIME_Total(vf,i); + return(acc); + }else{ + return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate); + } +} + +/* seek to an offset relative to the *compressed* data. This also + scans packets to update the PCM cursor. It will cross a logical + bitstream boundary, but only if it can't get any packets out of the + tail of the bitstream we seek to (so no surprises). + + returns zero on success, nonzero on failure */ + +int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ + ogg_stream_state work_os; + + if(vf->ready_stateseekable) + return(OV_ENOSEEK); /* don't dump machine if we can't seek */ + + if(pos<0 || pos>vf->end)return(OV_EINVAL); + + /* don't yet clear out decoding machine (if it's initialized), in + the case we're in the same link. Restart the decode lapping, and + let _fetch_and_process_packet deal with a potential bitstream + boundary */ + vf->pcm_offset=-1; + ogg_stream_reset_serialno(&vf->os, + vf->current_serialno); /* must set serialno */ + vorbis_synthesis_restart(&vf->vd); + + _seek_helper(vf,pos); + + /* we need to make sure the pcm_offset is set, but we don't want to + advance the raw cursor past good packets just to get to the first + with a granulepos. That's not equivalent behavior to beginning + decoding as immediately after the seek position as possible. + + So, a hack. We use two stream states; a local scratch state and + the shared vf->os stream state. We use the local state to + scan, and the shared state as a buffer for later decode. + + Unfortuantely, on the last page we still advance to last packet + because the granulepos on the last page is not necessarily on a + packet boundary, and we need to make sure the granpos is + correct. + */ + + { + ogg_page og; + ogg_packet op; + int lastblock=0; + int accblock=0; + int thisblock; + int eosflag; + + ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */ + ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE + return from not necessarily + starting from the beginning */ + + while(1){ + if(vf->ready_state>=STREAMSET){ + /* snarf/scan a packet if we can */ + int result=ogg_stream_packetout(&work_os,&op); + + if(result>0){ + + if(vf->vi[vf->current_link].codec_setup){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(&vf->os,NULL); + thisblock=0; + }else{ + + if(eosflag) + ogg_stream_packetout(&vf->os,NULL); + else + if(lastblock)accblock+=(lastblock+thisblock)>>2; + } + + if(op.granulepos!=-1){ + int i,link=vf->current_link; + ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; + + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos-accblock; + break; + } + lastblock=thisblock; + continue; + }else + ogg_stream_packetout(&vf->os,NULL); + } + } + + if(!lastblock){ + if(_get_next_page(vf,&og,-1)<0){ + vf->pcm_offset=ov_pcm_total(vf,-1); + break; + } + }else{ + /* huh? Bogus stream with packets but no granulepos */ + vf->pcm_offset=-1; + break; + } + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state>=STREAMSET) + if(vf->current_serialno!=ogg_page_serialno(&og)){ + _decode_clear(vf); /* clear out stream state */ + ogg_stream_clear(&work_os); + } + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)goto seek_error; /* sign of a bogus stream. + error out, leave + machine uninitialized */ + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + ogg_stream_reset_serialno(&work_os,vf->current_serialno); + vf->ready_state=STREAMSET; + + } + + ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&work_os,&og); + eosflag=ogg_page_eos(&og); + } + } + + ogg_stream_clear(&work_os); + vf->bittrack=0.f; + vf->samptrack=0.f; + return(0); + + seek_error: + /* dump the machine so we're in a known state */ + vf->pcm_offset=-1; + ogg_stream_clear(&work_os); + _decode_clear(vf); + return OV_EBADLINK; +} + +/* Page granularity seek (faster than sample granularity because we + don't do the last bit of decode to find a specific sample). + + Seek to the last [granule marked] page preceeding the specified pos + location, such that decoding past the returned point will quickly + arrive at the requested position. */ +int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ + int link=-1; + ogg_int64_t result=0; + ogg_int64_t total=ov_pcm_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + + if(pos<0 || pos>total)return(OV_EINVAL); + + /* which bitstream section does this pcm offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + total-=vf->pcmlengths[link*2+1]; + if(pos>=total)break; + } + + /* search within the logical bitstream for the page with the highest + pcm_pos preceeding (or equal to) pos. There is a danger here; + missing pages or incorrect frame number information in the + bitstream could make our task impossible. Account for that (it + would be an error condition) */ + + /* new search algorithm by HB (Nicholas Vinen) */ + { + ogg_int64_t end=vf->offsets[link+1]; + ogg_int64_t begin=vf->offsets[link]; + ogg_int64_t begintime = vf->pcmlengths[link*2]; + ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; + ogg_int64_t target=pos-total+begintime; + ogg_int64_t best=begin; + + ogg_page og; + while(beginoffset); + if(result==OV_EREAD) goto seek_error; + if(result<0){ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(bisect==0) goto seek_error; + bisect-=CHUNKSIZE; + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + } + }else{ + ogg_int64_t granulepos=ogg_page_granulepos(&og); + if(granulepos==-1)continue; + if(granuleposoffset; /* raw offset of next page */ + begintime=granulepos; + + if(target-begintime>44100)break; + bisect=begin; /* *not* begin + 1 */ + }else{ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(end==vf->offset){ /* we're pretty close - we'd be stuck in */ + end=result; + bisect-=CHUNKSIZE; /* an endless loop otherwise. */ + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + }else{ + end=result; + endtime=granulepos; + break; + } + } + } + } + } + } + + /* found our page. seek to it, update pcm offset. Easier case than + raw_seek, don't keep packets preceeding granulepos. */ + { + ogg_page og; + ogg_packet op; + + /* seek */ + _seek_helper(vf,best); + vf->pcm_offset=-1; + + if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */ + + if(link!=vf->current_link){ + /* Different link; dump entire decode machine */ + _decode_clear(vf); + + vf->current_link=link; + vf->current_serialno=ogg_page_serialno(&og); + vf->ready_state=STREAMSET; + + }else{ + vorbis_synthesis_restart(&vf->vd); + } + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + ogg_stream_pagein(&vf->os,&og); + + /* pull out all but last packet; the one with granulepos */ + while(1){ + result=ogg_stream_packetpeek(&vf->os,&op); + if(result==0){ + /* !!! the packet finishing this page originated on a + preceeding page. Keep fetching previous pages until we + get one with a granulepos or without the 'continued' flag + set. Then just use raw_seek for simplicity. */ + + _seek_helper(vf,best); + + while(1){ + result=_get_prev_page(vf,&og); + if(result<0) goto seek_error; + if(ogg_page_granulepos(&og)>-1 || + !ogg_page_continued(&og)){ + return ov_raw_seek(vf,result); + } + vf->offset=result; + } + } + if(result<0){ + result = OV_EBADPACKET; + goto seek_error; + } + if(op.granulepos!=-1){ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + vf->pcm_offset+=total; + break; + }else + result=ogg_stream_packetout(&vf->os,NULL); + } + } + } + + /* verify result */ + if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ + result=OV_EFAULT; + goto seek_error; + } + vf->bittrack=0.f; + vf->samptrack=0.f; + return(0); + + seek_error: + /* dump machine so we're in a known state */ + vf->pcm_offset=-1; + _decode_clear(vf); + return (int)result; +} + +/* seek to a sample offset relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ + +int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ + int thisblock,lastblock=0; + int ret=ov_pcm_seek_page(vf,pos); + if(ret<0)return(ret); + if((ret=_make_decode_ready(vf)))return ret; + + /* discard leading packets we don't need for the lapping of the + position we want; don't decode them */ + + while(1){ + ogg_packet op; + ogg_page og; + + int ret=ogg_stream_packetpeek(&vf->os,&op); + if(ret>0){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(&vf->os,NULL); + continue; /* non audio packet */ + } + if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; + + if(vf->pcm_offset+((thisblock+ + vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; + + /* remove the packet from packet queue and track its granulepos */ + ogg_stream_packetout(&vf->os,NULL); + vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with + only tracking, no + pcm_decode */ + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + + /* end of logical stream case is hard, especially with exact + length positioning. */ + + if(op.granulepos>-1){ + int i; + /* always believe the stream markers */ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + for(i=0;icurrent_link;i++) + vf->pcm_offset+=vf->pcmlengths[i*2+1]; + } + + lastblock=thisblock; + + }else{ + if(ret<0 && ret!=OV_HOLE)break; + + /* suck in a new page */ + if(_get_next_page(vf,&og,-1)<0)break; + if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf); + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)return(OV_EBADLINK); + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + ret=_make_decode_ready(vf); + if(ret)return ret; + lastblock=0; + } + + ogg_stream_pagein(&vf->os,&og); + } + } + + vf->bittrack=0.f; + vf->samptrack=0.f; + /* discard samples until we reach the desired position. Crossing a + logical bitstream boundary with abandon is OK. */ + while(vf->pcm_offsetpcm_offset; + long samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + if(samples>target)samples=target; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + + if(samplespcm_offset=ov_pcm_total(vf,-1); /* eof */ + } + return 0; +} + +/* seek to a playback time relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ +int ov_time_seek(OggVorbis_File *vf,double seconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + double TIME_Total=ov_TIME_Total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(seconds<0 || seconds>TIME_Total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + TIME_Total-=ov_TIME_Total(vf,link); + if(seconds>=TIME_Total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(seconds-TIME_Total)*vf->vi[link].rate; + return(ov_pcm_seek(vf,target)); + } +} + +/* page-granularity version of ov_time_seek + returns zero on success, nonzero on failure */ +int ov_time_seek_page(OggVorbis_File *vf,double seconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + double TIME_Total=ov_TIME_Total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(seconds<0 || seconds>TIME_Total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + TIME_Total-=ov_TIME_Total(vf,link); + if(seconds>=TIME_Total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(seconds-TIME_Total)*vf->vi[link].rate; + return(ov_pcm_seek_page(vf,target)); + } +} + +/* tell the current stream offset cursor. Note that seek followed by + tell will likely not give the set offset due to caching */ +ogg_int64_t ov_raw_tell(OggVorbis_File *vf){ + if(vf->ready_stateoffset); +} + +/* return PCM offset (sample) of next PCM sample to be read */ +ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ + if(vf->ready_statepcm_offset); +} + +/* return time offset (seconds) of next PCM sample to be read */ +double ov_TIME_Tell(OggVorbis_File *vf){ + int link=0; + ogg_int64_t pcm_total=0; + double TIME_Total=0.f; + + if(vf->ready_stateseekable){ + pcm_total=ov_pcm_total(vf,-1); + TIME_Total=ov_TIME_Total(vf,-1); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + TIME_Total-=ov_TIME_Total(vf,link); + if(vf->pcm_offset>=pcm_total)break; + } + } + + return((double)TIME_Total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate); +} + +/* link: -1) return the vorbis_info struct for the bitstream section + currently being decoded + 0-n) to request information for a specific bitstream section + + In the case of a non-seekable bitstream, any call returns the + current bitstream. NULL in the case that the machine is not + initialized */ + +vorbis_info *ov_info(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vi+vf->current_link; + else + return vf->vi; + else + if(link>=vf->links) + return NULL; + else + return vf->vi+link; + }else{ + return vf->vi; + } +} + +/* grr, strong typing, grr, no templates/inheritence, grr */ +vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vc+vf->current_link; + else + return vf->vc; + else + if(link>=vf->links) + return NULL; + else + return vf->vc+link; + }else{ + return vf->vc; + } +} + +static int host_is_big_endian() { + ogg_int32_t pattern = 0xfeedface; /* deadbeef */ + unsigned char *bytewise = (unsigned char *)&pattern; + if (bytewise[0] == 0xfe) return 1; + return 0; +} + +/* up to this point, everything could more or less hide the multiple + logical bitstream nature of chaining from the toplevel application + if the toplevel application didn't particularly care. However, at + the point that we actually read audio back, the multiple-section + nature must surface: Multiple bitstream sections do not necessarily + have to have the same number of channels or sampling rate. + + ov_read returns the sequential logical bitstream number currently + being decoded along with the PCM data in order that the toplevel + application can take action on channel/sample rate changes. This + number will be incremented even for streamed (non-seekable) streams + (for seekable streams, it represents the actual logical bitstream + index within the physical bitstream. Note that the accessor + functions above are aware of this dichotomy). + + input values: buffer) a buffer to hold packed PCM data for return + length) the byte length requested to be placed into buffer + bigendianp) should the data be packed LSB first (0) or + MSB first (1) + word) word size for output. currently 1 (byte) or + 2 (16 bit short) + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of bytes of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + +long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream){ + int i,j; + int host_endian = host_is_big_endian(); + + float **pcm; + long samples; + + if(vf->ready_stateready_state==INITSET){ + samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples)break; + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,1); + if(ret==OV_EOF) + return(0); + if(ret<=0) + return(ret); + } + + } + + if(samples>0){ + + /* yay! proceed to pack data into the byte buffer */ + + long channels=ov_info(vf,-1)->channels; + long bytespersample=word * channels; + vorbis_fpu_control fpu; + if(samples>length/bytespersample)samples=length/bytespersample; + + if(samples <= 0) + return OV_EINVAL; + + /* a tight loop to pack each size */ + { + int val; + if(word==1){ + int off=(sgned?0:128); + vorbis_fpu_setround(&fpu); + for(j=0;j127)val=127; + else if(val<-128)val=-128; + *buffer++=val+off; + } + vorbis_fpu_restore(fpu); + }else{ + int off=(sgned?0:32768); + + if(host_endian==bigendianp){ + if(sgned){ + + vorbis_fpu_setround(&fpu); + for(i=0;i32767)val=32767; + else if(val<-32768)val=-32768; + *dest=val; + dest+=channels; + } + } + vorbis_fpu_restore(fpu); + + }else{ + + vorbis_fpu_setround(&fpu); + for(i=0;i32767)val=32767; + else if(val<-32768)val=-32768; + *dest=val+off; + dest+=channels; + } + } + vorbis_fpu_restore(fpu); + + } + }else if(bigendianp){ + + vorbis_fpu_setround(&fpu); + for(j=0;j32767)val=32767; + else if(val<-32768)val=-32768; + val+=off; + *buffer++=(val>>8); + *buffer++=(val&0xff); + } + vorbis_fpu_restore(fpu); + + }else{ + int val; + vorbis_fpu_setround(&fpu); + for(j=0;j32767)val=32767; + else if(val<-32768)val=-32768; + val+=off; + *buffer++=(val&0xff); + *buffer++=(val>>8); + } + vorbis_fpu_restore(fpu); + + } + } + } + + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return(samples*bytespersample); + }else{ + return(samples); + } +} + +/* input values: pcm_channels) a float vector per channel of output + length) the sample length being read by the app + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of samples of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + + + +long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length, + int *bitstream){ + + if(vf->ready_stateready_state==INITSET){ + float **pcm; + long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples){ + if(pcm_channels)*pcm_channels=pcm; + if(samples>length)samples=length; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return samples; + + } + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,1); + if(ret==OV_EOF)return(0); + if(ret<=0)return(ret); + } + + } +} + +extern float *vorbis_window(vorbis_dsp_state *v,int W); +extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB, + ogg_int64_t off); + +static void _ov_splice(float **pcm,float **lappcm, + int n1, int n2, + int ch1, int ch2, + float *w1, float *w2){ + int i,j; + float *w=w1; + int n=n1; + + if(n1>n2){ + n=n2; + w=w2; + } + + /* splice */ + for(j=0;jready_state==INITSET)break; + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,0); + if(ret<0 && ret!=OV_HOLE)return(ret); + } + } + return 0; +} + +/* make sure vf is INITSET and that we have a primed buffer; if + we're crosslapping at a stream section boundary, this also makes + sure we're sanity checking against the right stream information */ +static int _ov_initprime(OggVorbis_File *vf){ + vorbis_dsp_state *vd=&vf->vd; + while(1){ + if(vf->ready_state==INITSET) + if(vorbis_synthesis_pcmout(vd,NULL))break; + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,0); + if(ret<0 && ret!=OV_HOLE)return(ret); + } + } + return 0; +} + +/* grab enough data for lapping from vf; this may be in the form of + unreturned, already-decoded pcm, remaining PCM we will need to + decode, or synthetic postextrapolation from last packets. */ +static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd, + float **lappcm,int lapsize){ + int lapcount=0,i; + float **pcm; + + /* try first to decode the lapping data */ + while(lapcountlapsize-lapcount)samples=lapsize-lapcount; + for(i=0;ichannels;i++) + memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); + lapcount+=samples; + vorbis_synthesis_read(vd,samples); + }else{ + /* suck in another packet */ + int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */ + if(ret==OV_EOF)break; + } + } + if(lapcountvd,&pcm); + if(samples==0){ + for(i=0;ichannels;i++) + memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount); + lapcount=lapsize; + }else{ + if(samples>lapsize-lapcount)samples=lapsize-lapcount; + for(i=0;ichannels;i++) + memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); + lapcount+=samples; + } + } +} + +/* this sets up crosslapping of a sample by using trailing data from + sample 1 and lapping it into the windowing buffer of sample 2 */ +int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){ + vorbis_info *vi1,*vi2; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,i,ret,hs1,hs2; + + if(vf1==vf2)return(0); /* degenerate case */ + if(vf1->ready_stateready_statechannels); + n1=vorbis_info_blocksize(vi1,0)>>(1+hs1); + n2=vorbis_info_blocksize(vi2,0)>>(1+hs2); + w1=vorbis_window(&vf1->vd,0); + w2=vorbis_window(&vf2->vd,0); + + for(i=0;ichannels;i++) + lappcm[i]=alloca(sizeof(**lappcm)*n1); + + _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1); + + /* have a lapping buffer from vf1; now to splice it into the lapping + buffer of vf2 */ + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf2->vd,&pcm); + _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0); + _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2); + + /* done */ + return(0); +} + +static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos, + int (*localseek)(OggVorbis_File *,ogg_int64_t)){ + vorbis_info *vi; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,ch1,ch2,hs; + int i,ret; + + if(vf->ready_statechannels; + n1=vorbis_info_blocksize(vi,0)>>(1+hs); + w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are + persistent; even if the decode state + from this link gets dumped, this + window array continues to exist */ + + lappcm=alloca(sizeof(*lappcm)*ch1); + for(i=0;ivd,lappcm,n1); + + /* have lapping data; seek and prime the buffer */ + ret=localseek(vf,pos); + if(ret)return ret; + ret=_ov_initprime(vf); + if(ret)return(ret); + + /* Guard against cross-link changes; they're perfectly legal */ + vi=ov_info(vf,-1); + ch2=vi->channels; + n2=vorbis_info_blocksize(vi,0)>>(1+hs); + w2=vorbis_window(&vf->vd,0); + + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf->vd,&pcm); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); + + /* done */ + return(0); +} + +int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_raw_seek); +} + +int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_pcm_seek); +} + +int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page); +} + +static int _ov_d_seek_lap(OggVorbis_File *vf,double pos, + int (*localseek)(OggVorbis_File *,double)){ + vorbis_info *vi; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,ch1,ch2,hs; + int i,ret; + + if(vf->ready_statechannels; + n1=vorbis_info_blocksize(vi,0)>>(1+hs); + w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are + persistent; even if the decode state + from this link gets dumped, this + window array continues to exist */ + + lappcm=alloca(sizeof(*lappcm)*ch1); + for(i=0;ivd,lappcm,n1); + + /* have lapping data; seek and prime the buffer */ + ret=localseek(vf,pos); + if(ret)return ret; + ret=_ov_initprime(vf); + if(ret)return(ret); + + /* Guard against cross-link changes; they're perfectly legal */ + vi=ov_info(vf,-1); + ch2=vi->channels; + n2=vorbis_info_blocksize(vi,0)>>(1+hs); + w2=vorbis_window(&vf->vd,0); + + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf->vd,&pcm); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); + + /* done */ + return(0); +} + +int ov_time_seek_lap(OggVorbis_File *vf,double pos){ + return _ov_d_seek_lap(vf,pos,ov_time_seek); +} + +int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){ + return _ov_d_seek_lap(vf,pos,ov_time_seek_page); +} diff --git a/sound/OggVorbis/vorbissrc/window.h b/sound/OggVorbis/vorbissrc/window.h new file mode 100644 index 000000000..6ce52a25d --- /dev/null +++ b/sound/OggVorbis/vorbissrc/window.h @@ -0,0 +1,26 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: window functions + last mod: $Id$ + + ********************************************************************/ + +#ifndef _V_WINDOW_ +#define _V_WINDOW_ + +extern float *_vorbis_window_get(int n); +extern void _vorbis_apply_window(float *d,int *winno,long *blocksizes, + int lW,int W,int nW); + + +#endif diff --git a/sound/OggVorbis/vorbissrc/windowvb.c b/sound/OggVorbis/vorbissrc/windowvb.c new file mode 100644 index 000000000..35e670f34 --- /dev/null +++ b/sound/OggVorbis/vorbissrc/windowvb.c @@ -0,0 +1,2136 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: window functions + last mod: $Id: window.c,v 1.23 2003/09/01 22:59:54 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include "os.h" +#include "misc.h" + +static float vwin64[32] = { + 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F, + 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F, + 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F, + 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F, + 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F, + 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F, + 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F, + 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F, +}; + +static float vwin128[64] = { + 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F, + 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F, + 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F, + 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F, + 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F, + 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F, + 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F, + 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F, + 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F, + 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F, + 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F, + 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F, + 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F, + 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F, + 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F, + 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F, +}; + +static float vwin256[128] = { + 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F, + 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F, + 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F, + 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F, + 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F, + 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F, + 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F, + 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F, + 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F, + 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F, + 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F, + 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F, + 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F, + 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F, + 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F, + 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F, + 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F, + 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F, + 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F, + 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F, + 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F, + 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F, + 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F, + 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F, + 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F, + 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F, + 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F, + 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F, + 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F, + 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F, + 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F, + 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F, +}; + +static float vwin512[256] = { + 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F, + 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F, + 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F, + 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F, + 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F, + 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F, + 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F, + 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F, + 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F, + 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F, + 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F, + 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F, + 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F, + 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F, + 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F, + 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F, + 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F, + 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F, + 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F, + 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F, + 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F, + 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F, + 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F, + 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F, + 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F, + 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F, + 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F, + 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F, + 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F, + 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F, + 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F, + 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F, + 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F, + 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F, + 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F, + 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F, + 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F, + 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F, + 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F, + 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F, + 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F, + 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F, + 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F, + 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F, + 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F, + 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F, + 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F, + 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F, + 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F, + 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F, + 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F, + 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F, + 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F, + 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F, + 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F, + 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F, + 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F, + 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F, + 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F, + 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F, + 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F, + 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F, + 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F, + 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F, +}; + +static float vwin1024[512] = { + 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F, + 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F, + 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F, + 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F, + 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F, + 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F, + 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F, + 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F, + 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F, + 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F, + 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F, + 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F, + 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F, + 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F, + 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F, + 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F, + 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F, + 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F, + 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F, + 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F, + 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F, + 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F, + 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F, + 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F, + 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F, + 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F, + 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F, + 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F, + 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F, + 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F, + 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F, + 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F, + 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F, + 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F, + 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F, + 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F, + 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F, + 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F, + 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F, + 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F, + 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F, + 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F, + 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F, + 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F, + 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F, + 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F, + 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F, + 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F, + 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F, + 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F, + 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F, + 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F, + 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F, + 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F, + 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F, + 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F, + 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F, + 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F, + 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F, + 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F, + 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F, + 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F, + 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F, + 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F, + 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F, + 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F, + 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F, + 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F, + 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F, + 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F, + 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F, + 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F, + 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F, + 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F, + 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F, + 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F, + 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F, + 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F, + 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F, + 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F, + 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F, + 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F, + 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F, + 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F, + 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F, + 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F, + 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F, + 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F, + 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F, + 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F, + 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F, + 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F, + 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F, + 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F, + 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F, + 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F, + 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F, + 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F, + 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F, + 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F, + 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F, + 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F, + 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F, + 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F, + 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F, + 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F, + 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F, + 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F, + 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F, + 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F, + 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F, + 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F, + 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F, + 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F, + 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F, + 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F, + 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F, + 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F, + 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F, + 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F, + 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F, + 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F, + 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F, + 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F, + 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F, + 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F, + 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F, + 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F, +}; + +static float vwin2048[1024] = { + 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F, + 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F, + 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F, + 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F, + 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F, + 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F, + 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F, + 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F, + 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F, + 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F, + 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F, + 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F, + 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F, + 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F, + 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F, + 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F, + 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F, + 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F, + 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F, + 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F, + 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F, + 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F, + 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F, + 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F, + 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F, + 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F, + 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F, + 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F, + 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F, + 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F, + 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F, + 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F, + 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F, + 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F, + 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F, + 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F, + 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F, + 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F, + 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F, + 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F, + 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F, + 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F, + 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F, + 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F, + 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F, + 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F, + 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F, + 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F, + 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F, + 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F, + 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F, + 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F, + 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F, + 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F, + 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F, + 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F, + 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F, + 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F, + 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F, + 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F, + 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F, + 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F, + 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F, + 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F, + 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F, + 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F, + 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F, + 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F, + 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F, + 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F, + 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F, + 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F, + 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F, + 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F, + 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F, + 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F, + 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F, + 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F, + 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F, + 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F, + 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F, + 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F, + 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F, + 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F, + 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F, + 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F, + 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F, + 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F, + 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F, + 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F, + 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F, + 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F, + 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F, + 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F, + 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F, + 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F, + 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F, + 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F, + 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F, + 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F, + 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F, + 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F, + 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F, + 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F, + 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F, + 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F, + 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F, + 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F, + 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F, + 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F, + 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F, + 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F, + 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F, + 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F, + 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F, + 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F, + 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F, + 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F, + 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F, + 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F, + 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F, + 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F, + 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F, + 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F, + 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F, + 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F, + 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F, + 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F, + 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F, + 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F, + 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F, + 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F, + 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F, + 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F, + 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F, + 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F, + 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F, + 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F, + 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F, + 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F, + 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F, + 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F, + 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F, + 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F, + 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F, + 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F, + 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F, + 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F, + 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F, + 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F, + 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F, + 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F, + 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F, + 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F, + 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F, + 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F, + 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F, + 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F, + 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F, + 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F, + 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F, + 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F, + 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F, + 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F, + 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F, + 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F, + 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F, + 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F, + 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F, + 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F, + 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F, + 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F, + 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F, + 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F, + 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F, + 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F, + 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F, + 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F, + 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F, + 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F, + 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F, + 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F, + 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F, + 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F, + 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F, + 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F, + 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F, + 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F, + 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F, + 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F, + 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F, + 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F, + 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F, + 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F, + 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F, + 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F, + 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F, + 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F, + 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F, + 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F, + 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F, + 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F, + 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F, + 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F, + 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F, + 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F, + 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F, + 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F, + 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F, + 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F, + 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F, + 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F, + 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F, + 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F, + 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F, + 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F, + 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F, + 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F, + 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F, + 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F, + 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F, + 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F, + 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F, + 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F, + 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F, + 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F, + 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F, + 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F, + 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F, + 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F, + 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F, + 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F, + 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F, + 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F, + 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F, + 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F, + 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F, + 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F, + 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F, + 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F, + 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F, + 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F, + 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F, + 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F, + 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F, + 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F, + 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F, + 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F, + 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F, + 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F, + 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F, + 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F, + 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F, + 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F, + 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F, + 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F, +}; + +static float vwin4096[2048] = { + 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F, + 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F, + 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F, + 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F, + 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F, + 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F, + 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F, + 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F, + 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F, + 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F, + 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F, + 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F, + 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F, + 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F, + 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F, + 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F, + 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F, + 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F, + 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F, + 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F, + 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F, + 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F, + 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F, + 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F, + 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F, + 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F, + 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F, + 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F, + 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F, + 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F, + 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F, + 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F, + 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F, + 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F, + 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F, + 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F, + 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F, + 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F, + 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F, + 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F, + 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F, + 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F, + 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F, + 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F, + 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F, + 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F, + 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F, + 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F, + 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F, + 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F, + 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F, + 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F, + 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F, + 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F, + 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F, + 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F, + 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F, + 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F, + 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F, + 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F, + 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F, + 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F, + 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F, + 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F, + 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F, + 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F, + 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F, + 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F, + 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F, + 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F, + 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F, + 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F, + 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F, + 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F, + 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F, + 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F, + 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F, + 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F, + 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F, + 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F, + 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F, + 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F, + 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F, + 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F, + 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F, + 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F, + 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F, + 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F, + 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F, + 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F, + 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F, + 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F, + 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F, + 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F, + 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F, + 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F, + 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F, + 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F, + 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F, + 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F, + 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F, + 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F, + 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F, + 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F, + 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F, + 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F, + 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F, + 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F, + 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F, + 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F, + 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F, + 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F, + 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F, + 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F, + 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F, + 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F, + 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F, + 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F, + 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F, + 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F, + 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F, + 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F, + 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F, + 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F, + 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F, + 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F, + 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F, + 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F, + 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F, + 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F, + 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F, + 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F, + 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F, + 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F, + 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F, + 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F, + 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F, + 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F, + 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F, + 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F, + 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F, + 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F, + 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F, + 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F, + 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F, + 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F, + 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F, + 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F, + 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F, + 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F, + 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F, + 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F, + 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F, + 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F, + 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F, + 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F, + 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F, + 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F, + 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F, + 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F, + 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F, + 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F, + 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F, + 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F, + 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F, + 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F, + 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F, + 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F, + 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F, + 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F, + 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F, + 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F, + 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F, + 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F, + 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F, + 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F, + 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F, + 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F, + 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F, + 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F, + 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F, + 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F, + 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F, + 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F, + 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F, + 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F, + 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F, + 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F, + 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F, + 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F, + 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F, + 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F, + 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F, + 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F, + 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F, + 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F, + 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F, + 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F, + 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F, + 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F, + 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F, + 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F, + 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F, + 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F, + 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F, + 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F, + 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F, + 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F, + 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F, + 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F, + 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F, + 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F, + 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F, + 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F, + 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F, + 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F, + 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F, + 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F, + 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F, + 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F, + 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F, + 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F, + 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F, + 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F, + 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F, + 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F, + 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F, + 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F, + 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F, + 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F, + 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F, + 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F, + 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F, + 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F, + 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F, + 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F, + 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F, + 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F, + 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F, + 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F, + 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F, + 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F, + 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F, + 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F, + 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F, + 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F, + 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F, + 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F, + 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F, + 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F, + 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F, + 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F, + 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F, + 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F, + 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F, + 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F, + 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F, + 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F, + 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F, + 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F, + 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F, + 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F, + 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F, + 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F, + 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F, + 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F, + 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F, + 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F, + 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F, + 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F, + 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F, + 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F, + 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F, + 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F, + 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F, + 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F, + 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F, + 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F, + 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F, + 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F, + 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F, + 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F, + 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F, + 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F, + 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F, + 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F, + 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F, + 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F, + 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F, + 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F, + 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F, + 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F, + 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F, + 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F, + 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F, + 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F, + 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F, + 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F, + 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F, + 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F, + 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F, + 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F, + 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F, + 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F, + 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F, + 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F, + 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F, + 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F, + 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F, + 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F, + 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F, + 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F, + 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F, + 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F, + 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F, + 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F, + 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F, + 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F, + 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F, + 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F, + 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F, + 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F, + 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F, + 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F, + 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F, + 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F, + 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F, + 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F, + 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F, + 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F, + 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F, + 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F, + 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F, + 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F, + 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F, + 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F, + 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F, + 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F, + 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F, + 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F, + 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F, + 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F, + 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F, + 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F, + 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F, + 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F, + 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F, + 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F, + 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F, + 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F, + 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F, + 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F, + 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F, + 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F, + 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F, + 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F, + 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F, + 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F, + 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F, + 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F, + 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F, + 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F, + 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F, + 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F, + 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F, + 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F, + 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F, + 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F, + 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F, + 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F, + 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F, + 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F, + 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F, + 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F, + 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F, + 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F, + 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F, + 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F, + 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F, + 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F, + 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F, + 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F, + 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F, + 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F, + 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F, + 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F, + 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F, + 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F, + 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F, + 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F, + 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F, + 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F, + 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F, + 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F, + 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F, + 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F, + 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F, + 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F, + 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F, + 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F, + 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F, + 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F, + 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F, + 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F, + 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F, + 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F, + 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F, + 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F, + 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F, + 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F, + 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F, + 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F, + 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F, + 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F, + 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F, + 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F, + 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F, + 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F, + 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F, + 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F, + 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F, + 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F, + 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F, + 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F, + 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F, + 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F, + 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F, + 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F, + 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F, + 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F, + 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F, + 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F, + 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F, + 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F, + 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F, + 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F, + 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F, + 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F, + 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F, + 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F, + 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F, + 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F, + 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F, + 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F, + 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F, + 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F, + 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F, + 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F, + 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F, + 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F, + 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F, + 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F, + 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F, + 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F, + 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F, + 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F, + 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F, + 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F, + 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F, + 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F, + 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F, + 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F, + 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F, + 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F, + 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F, + 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F, + 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F, + 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F, + 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F, + 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F, + 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F, + 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F, + 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F, + 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F, + 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F, + 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F, + 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F, + 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F, + 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F, + 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F, + 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F, + 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F, + 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F, + 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F, + 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F, + 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F, + 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F, + 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F, + 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F, + 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F, + 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F, + 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F, + 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F, + 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F, + 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F, + 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F, + 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F, + 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F, + 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F, + 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F, + 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F, + 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F, + 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F, + 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F, + 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F, + 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F, + 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F, + 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F, + 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F, + 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F, + 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +static float vwin8192[4096] = { + 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F, + 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F, + 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F, + 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F, + 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F, + 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F, + 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F, + 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F, + 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F, + 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F, + 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F, + 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F, + 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F, + 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F, + 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F, + 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F, + 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F, + 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F, + 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F, + 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F, + 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F, + 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F, + 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F, + 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F, + 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F, + 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F, + 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F, + 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F, + 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F, + 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F, + 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F, + 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F, + 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F, + 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F, + 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F, + 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F, + 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F, + 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F, + 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F, + 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F, + 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F, + 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F, + 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F, + 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F, + 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F, + 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F, + 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F, + 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F, + 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F, + 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F, + 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F, + 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F, + 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F, + 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F, + 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F, + 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F, + 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F, + 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F, + 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F, + 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F, + 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F, + 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F, + 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F, + 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F, + 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F, + 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F, + 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F, + 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F, + 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F, + 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F, + 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F, + 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F, + 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F, + 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F, + 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F, + 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F, + 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F, + 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F, + 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F, + 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F, + 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F, + 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F, + 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F, + 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F, + 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F, + 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F, + 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F, + 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F, + 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F, + 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F, + 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F, + 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F, + 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F, + 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F, + 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F, + 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F, + 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F, + 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F, + 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F, + 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F, + 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F, + 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F, + 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F, + 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F, + 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F, + 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F, + 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F, + 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F, + 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F, + 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F, + 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F, + 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F, + 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F, + 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F, + 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F, + 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F, + 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F, + 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F, + 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F, + 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F, + 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F, + 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F, + 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F, + 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F, + 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F, + 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F, + 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F, + 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F, + 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F, + 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F, + 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F, + 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F, + 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F, + 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F, + 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F, + 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F, + 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F, + 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F, + 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F, + 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F, + 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F, + 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F, + 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F, + 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F, + 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F, + 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F, + 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F, + 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F, + 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F, + 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F, + 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F, + 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F, + 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F, + 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F, + 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F, + 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F, + 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F, + 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F, + 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F, + 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F, + 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F, + 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F, + 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F, + 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F, + 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F, + 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F, + 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F, + 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F, + 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F, + 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F, + 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F, + 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F, + 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F, + 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F, + 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F, + 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F, + 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F, + 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F, + 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F, + 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F, + 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F, + 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F, + 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F, + 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F, + 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F, + 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F, + 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F, + 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F, + 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F, + 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F, + 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F, + 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F, + 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F, + 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F, + 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F, + 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F, + 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F, + 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F, + 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F, + 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F, + 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F, + 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F, + 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F, + 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F, + 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F, + 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F, + 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F, + 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F, + 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F, + 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F, + 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F, + 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F, + 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F, + 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F, + 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F, + 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F, + 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F, + 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F, + 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F, + 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F, + 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F, + 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F, + 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F, + 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F, + 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F, + 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F, + 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F, + 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F, + 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F, + 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F, + 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F, + 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F, + 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F, + 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F, + 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F, + 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F, + 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F, + 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F, + 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F, + 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F, + 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F, + 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F, + 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F, + 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F, + 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F, + 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F, + 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F, + 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F, + 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F, + 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F, + 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F, + 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F, + 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F, + 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F, + 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F, + 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F, + 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F, + 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F, + 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F, + 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F, + 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F, + 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F, + 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F, + 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F, + 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F, + 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F, + 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F, + 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F, + 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F, + 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F, + 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F, + 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F, + 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F, + 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F, + 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F, + 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F, + 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F, + 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F, + 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F, + 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F, + 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F, + 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F, + 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F, + 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F, + 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F, + 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F, + 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F, + 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F, + 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F, + 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F, + 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F, + 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F, + 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F, + 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F, + 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F, + 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F, + 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F, + 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F, + 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F, + 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F, + 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F, + 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F, + 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F, + 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F, + 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F, + 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F, + 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F, + 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F, + 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F, + 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F, + 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F, + 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F, + 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F, + 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F, + 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F, + 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F, + 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F, + 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F, + 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F, + 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F, + 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F, + 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F, + 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F, + 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F, + 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F, + 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F, + 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F, + 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F, + 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F, + 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F, + 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F, + 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F, + 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F, + 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F, + 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F, + 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F, + 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F, + 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F, + 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F, + 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F, + 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F, + 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F, + 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F, + 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F, + 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F, + 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F, + 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F, + 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F, + 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F, + 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F, + 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F, + 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F, + 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F, + 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F, + 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F, + 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F, + 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F, + 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F, + 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F, + 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F, + 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F, + 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F, + 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F, + 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F, + 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F, + 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F, + 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F, + 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F, + 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F, + 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F, + 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F, + 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F, + 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F, + 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F, + 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F, + 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F, + 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F, + 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F, + 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F, + 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F, + 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F, + 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F, + 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F, + 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F, + 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F, + 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F, + 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F, + 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F, + 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F, + 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F, + 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F, + 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F, + 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F, + 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F, + 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F, + 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F, + 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F, + 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F, + 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F, + 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F, + 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F, + 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F, + 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F, + 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F, + 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F, + 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F, + 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F, + 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F, + 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F, + 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F, + 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F, + 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F, + 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F, + 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F, + 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F, + 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F, + 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F, + 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F, + 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F, + 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F, + 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F, + 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F, + 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F, + 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F, + 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F, + 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F, + 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F, + 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F, + 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F, + 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F, + 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F, + 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F, + 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F, + 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F, + 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F, + 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F, + 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F, + 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F, + 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F, + 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F, + 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F, + 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F, + 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F, + 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F, + 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F, + 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F, + 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F, + 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F, + 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F, + 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F, + 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F, + 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F, + 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F, + 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F, + 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F, + 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F, + 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F, + 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F, + 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F, + 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F, + 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F, + 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F, + 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F, + 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F, + 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F, + 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F, + 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F, + 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F, + 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F, + 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F, + 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F, + 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F, + 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F, + 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F, + 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F, + 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F, + 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F, + 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F, + 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F, + 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F, + 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F, + 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F, + 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F, + 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F, + 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F, + 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F, + 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F, + 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F, + 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F, + 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F, + 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F, + 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F, + 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F, + 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F, + 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F, + 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F, + 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F, + 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F, + 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F, + 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F, + 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F, + 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F, + 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F, + 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F, + 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F, + 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F, + 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F, + 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F, + 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F, + 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F, + 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F, + 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F, + 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F, + 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F, + 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F, + 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F, + 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F, + 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F, + 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F, + 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F, + 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F, + 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F, + 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F, + 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F, + 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F, + 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F, + 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F, + 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F, + 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F, + 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F, + 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F, + 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F, + 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F, + 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F, + 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F, + 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F, + 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F, + 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F, + 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F, + 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F, + 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F, + 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F, + 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F, + 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F, + 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F, + 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F, + 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F, + 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F, + 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F, + 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F, + 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F, + 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F, + 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F, + 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F, + 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F, + 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F, + 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F, + 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F, + 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F, + 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F, + 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F, + 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F, + 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F, + 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F, + 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F, + 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F, + 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F, + 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F, + 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F, + 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F, + 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F, + 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F, + 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F, + 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F, + 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F, + 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F, + 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F, + 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F, + 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F, + 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F, + 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F, + 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F, + 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F, + 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F, + 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F, + 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F, + 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F, + 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F, + 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F, + 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F, + 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F, + 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F, + 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F, + 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F, + 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F, + 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F, + 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F, + 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F, + 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F, + 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F, + 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F, + 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F, + 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F, + 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F, + 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F, + 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F, + 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F, + 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F, + 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F, + 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F, + 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F, + 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F, + 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F, + 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F, + 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F, + 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F, + 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F, + 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F, + 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F, + 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F, + 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F, + 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F, + 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F, + 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F, + 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F, + 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F, + 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F, + 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F, + 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F, + 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F, + 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F, + 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F, + 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F, + 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F, + 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F, + 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F, + 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F, + 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F, + 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F, + 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F, + 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F, + 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F, + 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F, + 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F, + 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F, + 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F, + 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F, + 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F, + 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F, + 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F, + 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F, + 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F, + 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F, + 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F, + 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F, + 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F, + 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F, + 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F, + 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F, + 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F, + 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F, + 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F, + 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F, + 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F, + 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F, + 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F, + 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F, + 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F, + 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F, + 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F, + 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F, + 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F, + 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F, + 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F, + 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F, + 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F, + 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F, + 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F, + 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F, + 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F, + 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F, + 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F, + 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F, + 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F, + 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F, + 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F, + 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F, + 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F, + 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F, + 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F, + 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F, + 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F, + 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F, + 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F, + 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F, + 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F, + 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F, + 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F, + 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F, + 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F, + 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F, + 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F, + 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F, + 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F, + 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F, + 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F, + 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F, + 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F, + 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F, + 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F, + 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F, + 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F, + 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F, + 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F, + 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F, + 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F, + 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F, + 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F, + 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F, + 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F, + 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F, + 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F, + 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F, + 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F, + 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F, + 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F, + 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F, + 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F, + 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F, + 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F, + 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F, + 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F, + 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F, + 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F, + 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F, + 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F, + 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F, + 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F, + 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F, + 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F, + 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F, + 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F, + 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F, + 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F, + 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F, + 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F, + 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F, + 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F, + 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F, + 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F, + 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F, + 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F, + 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F, + 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F, + 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F, + 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F, + 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F, + 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F, + 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F, + 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F, + 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F, + 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F, + 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F, + 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F, + 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F, + 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F, + 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F, + 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F, + 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F, + 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F, + 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F, + 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F, + 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F, + 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F, + 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F, + 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F, + 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F, + 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F, + 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F, + 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F, + 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F, + 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F, + 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F, + 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F, + 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F, + 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F, + 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F, + 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F, + 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F, + 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F, + 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F, + 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F, + 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F, + 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F, + 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F, + 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F, + 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F, + 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F, + 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F, + 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F, + 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F, + 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F, + 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F, + 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F, + 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F, + 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F, + 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F, + 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F, + 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F, + 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F, + 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F, + 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F, + 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F, + 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F, + 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F, + 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F, + 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F, + 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F, + 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F, + 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F, + 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F, + 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F, + 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F, + 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F, + 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F, + 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F, + 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F, + 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F, + 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F, + 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F, + 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F, + 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F, + 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F, + 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F, + 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F, + 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F, + 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F, + 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F, + 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F, + 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F, + 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F, + 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F, + 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F, + 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F, + 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F, + 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F, + 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F, + 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F, + 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F, + 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F, + 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F, + 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F, + 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F, + 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F, + 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F, + 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F, + 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F, + 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F, + 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F, + 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F, + 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F, + 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F, + 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F, + 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F, + 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F, + 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F, + 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F, + 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F, + 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F, + 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F, + 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F, + 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F, + 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F, + 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F, + 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F, + 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F, + 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F, + 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F, + 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F, + 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F, + 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F, + 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F, + 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F, + 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F, + 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F, + 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F, + 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F, + 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F, + 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F, + 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F, + 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F, + 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F, + 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F, + 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F, + 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F, + 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F, + 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F, + 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F, + 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F, + 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F, + 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F, + 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F, + 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F, + 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F, + 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F, + 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F, + 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F, + 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F, + 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F, + 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F, + 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F, + 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F, + 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F, + 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F, + 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F, + 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F, + 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F, + 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F, + 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F, + 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F, + 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F, + 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F, + 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F, + 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F, + 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F, + 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F, + 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F, + 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F, + 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F, + 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F, + 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F, + 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F, + 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F, + 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F, + 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F, + 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F, + 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F, + 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F, + 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F, + 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F, + 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F, + 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F, + 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F, + 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F, + 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F, + 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F, + 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F, + 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F, + 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F, + 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F, + 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F, + 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F, + 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F, + 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F, + 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F, + 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F, + 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F, + 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F, + 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F, + 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F, + 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F, + 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F, + 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F, + 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F, + 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F, + 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F, + 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F, + 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F, + 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F, + 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F, + 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F, + 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F, + 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F, + 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F, + 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F, + 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F, + 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F, + 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F, + 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F, + 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F, + 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F, + 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F, + 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F, + 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F, + 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F, + 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F, + 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F, + 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F, + 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F, + 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F, + 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F, + 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F, + 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F, + 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F, + 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F, + 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F, + 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F, + 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F, + 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F, + 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F, + 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F, + 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F, + 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F, + 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F, + 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F, + 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F, + 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F, + 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F, + 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F, + 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F, + 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F, + 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F, + 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F, + 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F, + 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F, + 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F, + 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F, + 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F, + 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F, + 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F, + 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F, + 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, + 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +static float *vwin[8] = { + vwin64, + vwin128, + vwin256, + vwin512, + vwin1024, + vwin2048, + vwin4096, + vwin8192, +}; + +float *_vorbis_window_get(int n){ + return vwin[n]; +} + +void _vorbis_apply_window(float *d,int *winno,long *blocksizes, + int lW,int W,int nW){ + lW=(W?lW:0); + nW=(W?nW:0); + + { + float *windowLW=vwin[winno[lW]]; + float *windowNW=vwin[winno[nW]]; + + long n=blocksizes[W]; + long ln=blocksizes[lW]; + long rn=blocksizes[nW]; + + long leftbegin=n/4-ln/4; + long leftend=leftbegin+ln/2; + + long rightbegin=n/2+n/4-rn/4; + long rightend=rightbegin+rn/2; + + int i,p; + + for(i=0;i soundCacheAllocator; +#else +static idDynamicAlloc soundCacheAllocator; +#endif + + +/* +=================== +idSoundCache::idSoundCache() +=================== +*/ +idSoundCache::idSoundCache() { + soundCacheAllocator.Init(); + soundCacheAllocator.SetLockMemory( true ); + listCache.AssureSize( 1024, NULL ); + listCache.SetGranularity( 256 ); + insideLevelLoad = false; +} + +/* +=================== +idSoundCache::~idSoundCache() +=================== +*/ +idSoundCache::~idSoundCache() { + listCache.DeleteContents( true ); + soundCacheAllocator.Shutdown(); +} + +/* +=================== +idSoundCache::::GetObject + +returns a single cached object pointer +=================== +*/ +const idSoundSample* idSoundCache::GetObject( const int index ) const { + if (index<0 || index>listCache.Num()) { + return NULL; + } + return listCache[index]; +} + +/* +=================== +idSoundCache::FindSound + +Adds a sound object to the cache and returns a handle for it. +=================== +*/ +idSoundSample *idSoundCache::FindSound( const idStr& filename, bool loadOnDemandOnly ) { + idStr fname; + + fname = filename; + fname.BackSlashesToSlashes(); + fname.ToLower(); + + declManager->MediaPrint( "%s\n", fname.c_str() ); + + // check to see if object is already in cache + for( int i = 0; i < listCache.Num(); i++ ) { + idSoundSample *def = listCache[i]; + if ( def && def->name == fname ) { + def->levelLoadReferenced = true; + if ( def->purged && !loadOnDemandOnly ) { + def->Load(); + } + return def; + } + } + + // create a new entry + idSoundSample *def = new idSoundSample; + + int shandle = listCache.FindNull(); + if ( shandle != -1 ) { + listCache[shandle] = def; + } else { + shandle = listCache.Append( def ); + } + + def->name = fname; + def->levelLoadReferenced = true; + def->onDemand = loadOnDemandOnly; + def->purged = true; + + if ( !loadOnDemandOnly ) { + // this may make it a default sound if it can't be loaded + def->Load(); + } + + return def; +} + +/* +=================== +idSoundCache::ReloadSounds + +Completely nukes the current cache +=================== +*/ +void idSoundCache::ReloadSounds( bool force ) { + int i; + + for( i = 0; i < listCache.Num(); i++ ) { + idSoundSample *def = listCache[i]; + if ( def ) { + def->Reload( force ); + } + } +} + +/* +==================== +BeginLevelLoad + +Mark all file based images as currently unused, +but don't free anything. Calls to ImageFromFile() will +either mark the image as used, or create a new image without +loading the actual data. +==================== +*/ +void idSoundCache::BeginLevelLoad() { + insideLevelLoad = true; + + for ( int i = 0 ; i < listCache.Num() ; i++ ) { + idSoundSample *sample = listCache[ i ]; + if ( !sample ) { + continue; + } + + if ( com_purgeAll.GetBool() ) { + sample->PurgeSoundSample(); + } + + sample->levelLoadReferenced = false; + } + + soundCacheAllocator.FreeEmptyBaseBlocks(); +} + +/* +==================== +EndLevelLoad + +Free all samples marked as unused +==================== +*/ +void idSoundCache::EndLevelLoad() { + int useCount, purgeCount; + common->Printf( "----- idSoundCache::EndLevelLoad -----\n" ); + + insideLevelLoad = false; + + // purge the ones we don't need + useCount = 0; + purgeCount = 0; + for ( int i = 0 ; i < listCache.Num() ; i++ ) { + idSoundSample *sample = listCache[ i ]; + if ( !sample ) { + continue; + } + if ( sample->purged ) { + continue; + } + if ( !sample->levelLoadReferenced ) { +// common->Printf( "Purging %s\n", sample->name.c_str() ); + purgeCount += sample->objectMemSize; + sample->PurgeSoundSample(); + } else { + useCount += sample->objectMemSize; + } + } + + soundCacheAllocator.FreeEmptyBaseBlocks(); + + common->Printf( "%5ik referenced\n", useCount / 1024 ); + common->Printf( "%5ik purged\n", purgeCount / 1024 ); + common->Printf( "----------------------------------------\n" ); +} + +/* +=================== +idSoundCache::PrintMemInfo +=================== +*/ +void idSoundCache::PrintMemInfo( MemInfo_t *mi ) { + int i, j, num = 0, total = 0; + int *sortIndex; + idFile *f; + + f = fileSystem->OpenFileWrite( mi->filebase + "_sounds.txt" ); + if ( !f ) { + return; + } + + // count + for ( i = 0; i < listCache.Num(); i++, num++ ) { + if ( !listCache[i] ) { + break; + } + } + + // sort first + sortIndex = new int[num]; + + for ( i = 0; i < num; i++ ) { + sortIndex[i] = i; + } + + for ( i = 0; i < num - 1; i++ ) { + for ( j = i + 1; j < num; j++ ) { + if ( listCache[sortIndex[i]]->objectMemSize < listCache[sortIndex[j]]->objectMemSize ) { + int temp = sortIndex[i]; + sortIndex[i] = sortIndex[j]; + sortIndex[j] = temp; + } + } + } + + // print next + for ( i = 0; i < num; i++ ) { + idSoundSample *sample = listCache[sortIndex[i]]; + + // this is strange + if ( !sample ) { + continue; + } + + total += sample->objectMemSize; + f->Printf( "%s %s\n", idStr::FormatNumber( sample->objectMemSize ).c_str(), sample->name.c_str() ); + } + + mi->soundAssetsTotal = total; + + f->Printf( "\nTotal sound bytes allocated: %s\n", idStr::FormatNumber( total ).c_str() ); + fileSystem->CloseFile( f ); +} + + +/* +========================================================================== + +idSoundSample + +========================================================================== +*/ + +/* +=================== +idSoundSample::idSoundSample +=================== +*/ +idSoundSample::idSoundSample() { + memset( &objectInfo, 0, sizeof(waveformatex_t) ); + objectSize = 0; + objectMemSize = 0; + nonCacheData = NULL; + amplitudeData = NULL; + openalBuffer = NULL; + hardwareBuffer = false; + defaultSound = false; + onDemand = false; + purged = false; + levelLoadReferenced = false; +} + +/* +=================== +idSoundSample::~idSoundSample +=================== +*/ +idSoundSample::~idSoundSample() { + PurgeSoundSample(); +} + +/* +=================== +idSoundSample::LengthIn44kHzSamples +=================== +*/ +int idSoundSample::LengthIn44kHzSamples( void ) const { + // objectSize is samples + if ( objectInfo.nSamplesPerSec == 11025 ) { + return objectSize << 2; + } else if ( objectInfo.nSamplesPerSec == 22050 ) { + return objectSize << 1; + } else { + return objectSize << 0; + } +} + +/* +=================== +idSoundSample::MakeDefault +=================== +*/ +void idSoundSample::MakeDefault( void ) { + int i; + float v; + int sample; + + memset( &objectInfo, 0, sizeof( objectInfo ) ); + + objectInfo.nChannels = 1; + objectInfo.wBitsPerSample = 16; + objectInfo.nSamplesPerSec = 44100; + + objectSize = MIXBUFFER_SAMPLES * 2; + objectMemSize = objectSize * sizeof( short ); + + nonCacheData = (byte *)soundCacheAllocator.Alloc( objectMemSize ); + + short *ncd = (short *)nonCacheData; + + for ( i = 0; i < MIXBUFFER_SAMPLES; i ++ ) { + v = sin( idMath::PI * 2 * i / 64 ); + sample = v * 0x4000; + ncd[i*2+0] = sample; + ncd[i*2+1] = sample; + } + + if ( idSoundSystemLocal::useOpenAL ) { + alGetError(); + alGenBuffers( 1, &openalBuffer ); + if ( alGetError() != AL_NO_ERROR ) { + common->Error( "idSoundCache: error generating OpenAL hardware buffer" ); + } + + alGetError(); + alBufferData( openalBuffer, objectInfo.nChannels==1?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec ); + if ( alGetError() != AL_NO_ERROR ) { + common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" ); + } else { + hardwareBuffer = true; + } + } + + defaultSound = true; +} + +/* +=================== +idSoundSample::CheckForDownSample +=================== +*/ +void idSoundSample::CheckForDownSample( void ) { + if ( !idSoundSystemLocal::s_force22kHz.GetBool() ) { + return; + } + if ( objectInfo.wFormatTag != WAVE_FORMAT_TAG_PCM || objectInfo.nSamplesPerSec != 44100 ) { + return; + } + int shortSamples = objectSize >> 1; + short *converted = (short *)soundCacheAllocator.Alloc( shortSamples * sizeof( short ) ); + + if ( objectInfo.nChannels == 1 ) { + for ( int i = 0; i < shortSamples; i++ ) { + converted[i] = ((short *)nonCacheData)[i*2]; + } + } else { + for ( int i = 0; i < shortSamples; i += 2 ) { + converted[i+0] = ((short *)nonCacheData)[i*2+0]; + converted[i+1] = ((short *)nonCacheData)[i*2+1]; + } + } + soundCacheAllocator.Free( nonCacheData ); + nonCacheData = (byte *)converted; + objectSize >>= 1; + objectMemSize >>= 1; + objectInfo.nAvgBytesPerSec >>= 1; + objectInfo.nSamplesPerSec >>= 1; +} + +/* +=================== +idSoundSample::GetNewTimeStamp +=================== +*/ +ID_TIME_T idSoundSample::GetNewTimeStamp( void ) const { + ID_TIME_T timestamp; + + fileSystem->ReadFile( name, NULL, ×tamp ); + if ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) { + idStr oggName = name; + oggName.SetFileExtension( ".ogg" ); + fileSystem->ReadFile( oggName, NULL, ×tamp ); + } + return timestamp; +} + +/* +=================== +idSoundSample::Load + +Loads based on name, possibly doing a MakeDefault if necessary +=================== +*/ +void idSoundSample::Load( void ) { + defaultSound = false; + purged = false; + hardwareBuffer = false; + + timestamp = GetNewTimeStamp(); + + if ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) { + common->Warning( "Couldn't load sound '%s' using default", name.c_str() ); + MakeDefault(); + return; + } + + // load it + idWaveFile fh; + waveformatex_t info; + + if ( fh.Open( name, &info ) == -1 ) { + common->Warning( "Couldn't load sound '%s' using default", name.c_str() ); + MakeDefault(); + return; + } + + if ( info.nChannels != 1 && info.nChannels != 2 ) { + common->Warning( "idSoundSample: %s has %i channels, using default", name.c_str(), info.nChannels ); + fh.Close(); + MakeDefault(); + return; + } + + if ( info.wBitsPerSample != 16 ) { + common->Warning( "idSoundSample: %s is %dbits, expected 16bits using default", name.c_str(), info.wBitsPerSample ); + fh.Close(); + MakeDefault(); + return; + } + + if ( info.nSamplesPerSec != 44100 && info.nSamplesPerSec != 22050 && info.nSamplesPerSec != 11025 ) { + common->Warning( "idSoundCache: %s is %dHz, expected 11025, 22050 or 44100 Hz. Using default", name.c_str(), info.nSamplesPerSec ); + fh.Close(); + MakeDefault(); + return; + } + + objectInfo = info; + objectSize = fh.GetOutputSize(); + objectMemSize = fh.GetMemorySize(); + + nonCacheData = (byte *)soundCacheAllocator.Alloc( objectMemSize ); + fh.Read( nonCacheData, objectMemSize, NULL ); + + // optionally convert it to 22kHz to save memory + CheckForDownSample(); + + // create hardware audio buffers + if ( idSoundSystemLocal::useOpenAL ) { + // PCM loads directly + if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_PCM ) { + alGetError(); + alGenBuffers( 1, &openalBuffer ); + if ( alGetError() != AL_NO_ERROR ) + common->Error( "idSoundCache: error generating OpenAL hardware buffer" ); + if ( alIsBuffer( openalBuffer ) ) { + alGetError(); + alBufferData( openalBuffer, objectInfo.nChannels==1?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec ); + if ( alGetError() != AL_NO_ERROR ) { + common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" ); + } else { + // Compute amplitude block size + int blockSize = 512 * objectInfo.nSamplesPerSec / 44100 ; + + // Allocate amplitude data array + amplitudeData = (byte *)soundCacheAllocator.Alloc( ( objectSize / blockSize + 1 ) * 2 * sizeof( short) ); + + // Creating array of min/max amplitude pairs per blockSize samples + int i; + for ( i = 0; i < objectSize; i+=blockSize ) { + short min = 32767; + short max = -32768; + + int j; + for ( j = 0; j < Min( objectSize - i, blockSize ); j++ ) { + min = ((short *)nonCacheData)[ i + j ] < min ? ((short *)nonCacheData)[ i + j ] : min; + max = ((short *)nonCacheData)[ i + j ] > max ? ((short *)nonCacheData)[ i + j ] : max; + } + + ((short *)amplitudeData)[ ( i / blockSize ) * 2 ] = min; + ((short *)amplitudeData)[ ( i / blockSize ) * 2 + 1 ] = max; + } + + hardwareBuffer = true; + } + } + } + + // OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default) + if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) { +#if defined(MACOS_X) + if ( ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) { +#else + if ( ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) && ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) { +#endif + alGetError(); + alGenBuffers( 1, &openalBuffer ); + if ( alGetError() != AL_NO_ERROR ) + common->Error( "idSoundCache: error generating OpenAL hardware buffer" ); + if ( alIsBuffer( openalBuffer ) ) { + idSampleDecoder *decoder = idSampleDecoder::Alloc(); + float *destData = (float *)soundCacheAllocator.Alloc( ( LengthIn44kHzSamples() + 1 ) * sizeof( float ) ); + + // Decoder *always* outputs 44 kHz data + decoder->Decode( this, 0, LengthIn44kHzSamples(), destData ); + + // Downsample back to original frequency (save memory) + if ( objectInfo.nSamplesPerSec == 11025 ) { + for ( int i = 0; i < objectSize; i++ ) { + if ( destData[i*4] < -32768.0f ) + ((short *)destData)[i] = -32768; + else if ( destData[i*4] > 32767.0f ) + ((short *)destData)[i] = 32767; + else + ((short *)destData)[i] = idMath::FtoiFast( destData[i*4] ); + } + } else if ( objectInfo.nSamplesPerSec == 22050 ) { + for ( int i = 0; i < objectSize; i++ ) { + if ( destData[i*2] < -32768.0f ) + ((short *)destData)[i] = -32768; + else if ( destData[i*2] > 32767.0f ) + ((short *)destData)[i] = 32767; + else + ((short *)destData)[i] = idMath::FtoiFast( destData[i*2] ); + } + } else { + for ( int i = 0; i < objectSize; i++ ) { + if ( destData[i] < -32768.0f ) + ((short *)destData)[i] = -32768; + else if ( destData[i] > 32767.0f ) + ((short *)destData)[i] = 32767; + else + ((short *)destData)[i] = idMath::FtoiFast( destData[i] ); + } + } + + alGetError(); + alBufferData( openalBuffer, objectInfo.nChannels==1?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, destData, objectSize * sizeof( short ), objectInfo.nSamplesPerSec ); + if ( alGetError() != AL_NO_ERROR ) + common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" ); + else { + // Compute amplitude block size + int blockSize = 512 * objectInfo.nSamplesPerSec / 44100 ; + + // Allocate amplitude data array + amplitudeData = (byte *)soundCacheAllocator.Alloc( ( objectSize / blockSize + 1 ) * 2 * sizeof( short ) ); + + // Creating array of min/max amplitude pairs per blockSize samples + int i; + for ( i = 0; i < objectSize; i+=blockSize ) { + short min = 32767; + short max = -32768; + + int j; + for ( j = 0; j < Min( objectSize - i, blockSize ); j++ ) { + min = ((short *)destData)[ i + j ] < min ? ((short *)destData)[ i + j ] : min; + max = ((short *)destData)[ i + j ] > max ? ((short *)destData)[ i + j ] : max; + } + + ((short *)amplitudeData)[ ( i / blockSize ) * 2 ] = min; + ((short *)amplitudeData)[ ( i / blockSize ) * 2 + 1 ] = max; + } + + hardwareBuffer = true; + } + + soundCacheAllocator.Free( (byte *)destData ); + idSampleDecoder::Free( decoder ); + } + } + } + + // Free memory if sample was loaded into hardware + if ( hardwareBuffer ) { + soundCacheAllocator.Free( nonCacheData ); + nonCacheData = NULL; + } + } + + fh.Close(); +} + +/* +=================== +idSoundSample::PurgeSoundSample +=================== +*/ +void idSoundSample::PurgeSoundSample() { + purged = true; + + if ( hardwareBuffer && idSoundSystemLocal::useOpenAL ) { + alGetError(); + alDeleteBuffers( 1, &openalBuffer ); + if ( alGetError() != AL_NO_ERROR ) { + common->Error( "idSoundCache: error unloading data from OpenAL hardware buffer" ); + } else { + openalBuffer = 0; + hardwareBuffer = false; + } + } + + if ( amplitudeData ) { + soundCacheAllocator.Free( amplitudeData ); + amplitudeData = NULL; + } + + if ( nonCacheData ) { + soundCacheAllocator.Free( nonCacheData ); + nonCacheData = NULL; + } +} + +/* +=================== +idSoundSample::Reload +=================== +*/ +void idSoundSample::Reload( bool force ) { + if ( !force ) { + ID_TIME_T newTimestamp; + + // check the timestamp + newTimestamp = GetNewTimeStamp(); + + if ( newTimestamp == FILE_NOT_FOUND_TIMESTAMP ) { + if ( !defaultSound ) { + common->Warning( "Couldn't load sound '%s' using default", name.c_str() ); + MakeDefault(); + } + return; + } + if ( newTimestamp == timestamp ) { + return; // don't need to reload it + } + } + + common->Printf( "reloading %s\n", name.c_str() ); + PurgeSoundSample(); + Load(); +} + +/* +=================== +idSoundSample::FetchFromCache + +Returns true on success. +=================== +*/ +bool idSoundSample::FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO ) { + offset &= 0xfffffffe; + + if ( objectSize == 0 || offset < 0 || offset > objectSize * (int)sizeof( short ) || !nonCacheData ) { + return false; + } + + if ( output ) { + *output = nonCacheData + offset; + } + if ( position ) { + *position = 0; + } + if ( size ) { + *size = objectSize * sizeof( short ) - offset; + if ( *size > SCACHE_SIZE ) { + *size = SCACHE_SIZE; + } + } + return true; +} diff --git a/sound/snd_decoder.cpp b/sound/snd_decoder.cpp new file mode 100644 index 000000000..f1addd53d --- /dev/null +++ b/sound/snd_decoder.cpp @@ -0,0 +1,563 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" +#include "OggVorbis/vorbis/codec.h" +#include "OggVorbis/vorbis/vorbisfile.h" + + +/* +=================================================================================== + + Thread safe decoder memory allocator. + + Each OggVorbis decoder consumes about 150kB of memory. + +=================================================================================== +*/ + +idDynamicBlockAlloc decoderMemoryAllocator; + +const int MIN_OGGVORBIS_MEMORY = 768 * 1024; + +extern "C" { + void *_decoder_malloc( size_t size ); + void *_decoder_calloc( size_t num, size_t size ); + void *_decoder_realloc( void *memblock, size_t size ); + void _decoder_free( void *memblock ); +} + +void *_decoder_malloc( size_t size ) { + void *ptr = decoderMemoryAllocator.Alloc( size ); + assert( size == 0 || ptr != NULL ); + return ptr; +} + +void *_decoder_calloc( size_t num, size_t size ) { + void *ptr = decoderMemoryAllocator.Alloc( num * size ); + assert( ( num * size ) == 0 || ptr != NULL ); + memset( ptr, 0, num * size ); + return ptr; +} + +void *_decoder_realloc( void *memblock, size_t size ) { + void *ptr = decoderMemoryAllocator.Resize( (byte *)memblock, size ); + assert( size == 0 || ptr != NULL ); + return ptr; +} + +void _decoder_free( void *memblock ) { + decoderMemoryAllocator.Free( (byte *)memblock ); +} + + +/* +=================================================================================== + + OggVorbis file loading/decoding. + +=================================================================================== +*/ + +/* +==================== +FS_ReadOGG +==================== +*/ +size_t FS_ReadOGG( void *dest, size_t size1, size_t size2, void *fh ) { + idFile *f = reinterpret_cast(fh); + return f->Read( dest, size1 * size2 ); +} + +/* +==================== +FS_SeekOGG +==================== +*/ +int FS_SeekOGG( void *fh, ogg_int64_t to, int type ) { + fsOrigin_t retype = FS_SEEK_SET; + + if ( type == SEEK_CUR ) { + retype = FS_SEEK_CUR; + } else if ( type == SEEK_END ) { + retype = FS_SEEK_END; + } else if ( type == SEEK_SET ) { + retype = FS_SEEK_SET; + } else { + common->FatalError( "fs_seekOGG: seek without type\n" ); + } + idFile *f = reinterpret_cast(fh); + return f->Seek( to, retype ); +} + +/* +==================== +FS_CloseOGG +==================== +*/ +int FS_CloseOGG( void *fh ) { + return 0; +} + +/* +==================== +FS_TellOGG +==================== +*/ +long FS_TellOGG( void *fh ) { + idFile *f = reinterpret_cast(fh); + return f->Tell(); +} + +/* +==================== +ov_openFile +==================== +*/ +int ov_openFile( idFile *f, OggVorbis_File *vf ) { + ov_callbacks callbacks; + + memset( vf, 0, sizeof( OggVorbis_File ) ); + + callbacks.read_func = FS_ReadOGG; + callbacks.seek_func = FS_SeekOGG; + callbacks.close_func = FS_CloseOGG; + callbacks.tell_func = FS_TellOGG; + return ov_open_callbacks((void *)f, vf, NULL, -1, callbacks); +} + +/* +==================== +idWaveFile::OpenOGG +==================== +*/ +int idWaveFile::OpenOGG( const char* strFileName, waveformatex_t *pwfx ) { + OggVorbis_File *ov; + + memset( pwfx, 0, sizeof( waveformatex_t ) ); + + mhmmio = fileSystem->OpenFileRead( strFileName ); + if ( !mhmmio ) { + return -1; + } + + Sys_EnterCriticalSection( CRITICAL_SECTION_ONE ); + + ov = new OggVorbis_File; + + if( ov_openFile( mhmmio, ov ) < 0 ) { + delete ov; + Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE ); + fileSystem->CloseFile( mhmmio ); + mhmmio = NULL; + return -1; + } + + mfileTime = mhmmio->Timestamp(); + + vorbis_info *vi = ov_info( ov, -1 ); + + mpwfx.Format.nSamplesPerSec = vi->rate; + mpwfx.Format.nChannels = vi->channels; + mpwfx.Format.wBitsPerSample = sizeof(short) * 8; + mdwSize = ov_pcm_total( ov, -1 ) * vi->channels; // pcm samples * num channels + mbIsReadingFromMemory = false; + + if ( idSoundSystemLocal::s_realTimeDecoding.GetBool() ) { + + ov_clear( ov ); + fileSystem->CloseFile( mhmmio ); + mhmmio = NULL; + delete ov; + + mpwfx.Format.wFormatTag = WAVE_FORMAT_TAG_OGG; + mhmmio = fileSystem->OpenFileRead( strFileName ); + mMemSize = mhmmio->Length(); + + } else { + + ogg = ov; + + mpwfx.Format.wFormatTag = WAVE_FORMAT_TAG_PCM; + mMemSize = mdwSize * sizeof( short ); + } + + memcpy( pwfx, &mpwfx, sizeof( waveformatex_t ) ); + + Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE ); + + isOgg = true; + + return 0; +} + +/* +==================== +idWaveFile::ReadOGG +==================== +*/ +int idWaveFile::ReadOGG( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ) { + int total = dwSizeToRead; + char *bufferPtr = (char *)pBuffer; + OggVorbis_File *ov = (OggVorbis_File *) ogg; + + do { + int ret = ov_read( ov, bufferPtr, total >= 4096 ? 4096 : total, Swap_IsBigEndian(), 2, 1, &ov->stream ); + if ( ret == 0 ) { + break; + } + if ( ret < 0 ) { + return -1; + } + bufferPtr += ret; + total -= ret; + } while( total > 0 ); + + dwSizeToRead = (byte *)bufferPtr - pBuffer; + + if ( pdwSizeRead != NULL ) { + *pdwSizeRead = dwSizeToRead; + } + + return dwSizeToRead; +} + +/* +==================== +idWaveFile::CloseOGG +==================== +*/ +int idWaveFile::CloseOGG( void ) { + OggVorbis_File *ov = (OggVorbis_File *) ogg; + if ( ov != NULL ) { + Sys_EnterCriticalSection( CRITICAL_SECTION_ONE ); + ov_clear( ov ); + delete ov; + Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE ); + fileSystem->CloseFile( mhmmio ); + mhmmio = NULL; + ogg = NULL; + return 0; + } + return -1; +} + + +/* +=================================================================================== + + idSampleDecoderLocal + +=================================================================================== +*/ + +class idSampleDecoderLocal : public idSampleDecoder { +public: + virtual void Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ); + virtual void ClearDecoder( void ); + virtual idSoundSample * GetSample( void ) const; + virtual int GetLastDecodeTime( void ) const; + + void Clear( void ); + int DecodePCM( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ); + int DecodeOGG( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ); + +private: + bool failed; // set if decoding failed + int lastFormat; // last format being decoded + idSoundSample * lastSample; // last sample being decoded + int lastSampleOffset; // last offset into the decoded sample + int lastDecodeTime; // last time decoding sound + idFile_Memory file; // encoded file in memory + + OggVorbis_File ogg; // OggVorbis file +}; + +idBlockAlloc sampleDecoderAllocator; + +/* +==================== +idSampleDecoder::Init +==================== +*/ +void idSampleDecoder::Init( void ) { + decoderMemoryAllocator.Init(); + decoderMemoryAllocator.SetLockMemory( true ); + decoderMemoryAllocator.SetFixedBlocks( idSoundSystemLocal::s_realTimeDecoding.GetBool() ? 10 : 1 ); +} + +/* +==================== +idSampleDecoder::Shutdown +==================== +*/ +void idSampleDecoder::Shutdown( void ) { + decoderMemoryAllocator.Shutdown(); + sampleDecoderAllocator.Shutdown(); +} + +/* +==================== +idSampleDecoder::Alloc +==================== +*/ +idSampleDecoder *idSampleDecoder::Alloc( void ) { + idSampleDecoderLocal *decoder = sampleDecoderAllocator.Alloc(); + decoder->Clear(); + return decoder; +} + +/* +==================== +idSampleDecoder::Free +==================== +*/ +void idSampleDecoder::Free( idSampleDecoder *decoder ) { + idSampleDecoderLocal *localDecoder = static_cast( decoder ); + localDecoder->ClearDecoder(); + sampleDecoderAllocator.Free( localDecoder ); +} + +/* +==================== +idSampleDecoder::GetNumUsedBlocks +==================== +*/ +int idSampleDecoder::GetNumUsedBlocks( void ) { + return decoderMemoryAllocator.GetNumUsedBlocks(); +} + +/* +==================== +idSampleDecoder::GetUsedBlockMemory +==================== +*/ +int idSampleDecoder::GetUsedBlockMemory( void ) { + return decoderMemoryAllocator.GetUsedBlockMemory(); +} + +/* +==================== +idSampleDecoderLocal::Clear +==================== +*/ +void idSampleDecoderLocal::Clear( void ) { + failed = false; + lastFormat = WAVE_FORMAT_TAG_PCM; + lastSample = NULL; + lastSampleOffset = 0; + lastDecodeTime = 0; +} + +/* +==================== +idSampleDecoderLocal::ClearDecoder +==================== +*/ +void idSampleDecoderLocal::ClearDecoder( void ) { + Sys_EnterCriticalSection( CRITICAL_SECTION_ONE ); + + switch( lastFormat ) { + case WAVE_FORMAT_TAG_PCM: { + break; + } + case WAVE_FORMAT_TAG_OGG: { + ov_clear( &ogg ); + memset( &ogg, 0, sizeof( ogg ) ); + break; + } + } + + Clear(); + + Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE ); +} + +/* +==================== +idSampleDecoderLocal::GetSample +==================== +*/ +idSoundSample *idSampleDecoderLocal::GetSample( void ) const { + return lastSample; +} + +/* +==================== +idSampleDecoderLocal::GetLastDecodeTime +==================== +*/ +int idSampleDecoderLocal::GetLastDecodeTime( void ) const { + return lastDecodeTime; +} + +/* +==================== +idSampleDecoderLocal::Decode +==================== +*/ +void idSampleDecoderLocal::Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) { + int readSamples44k; + + if ( sample->objectInfo.wFormatTag != lastFormat || sample != lastSample ) { + ClearDecoder(); + } + + lastDecodeTime = soundSystemLocal.CurrentSoundTime; + + if ( failed ) { + memset( dest, 0, sampleCount44k * sizeof( dest[0] ) ); + return; + } + + // samples can be decoded both from the sound thread and the main thread for shakes + Sys_EnterCriticalSection( CRITICAL_SECTION_ONE ); + + switch( sample->objectInfo.wFormatTag ) { + case WAVE_FORMAT_TAG_PCM: { + readSamples44k = DecodePCM( sample, sampleOffset44k, sampleCount44k, dest ); + break; + } + case WAVE_FORMAT_TAG_OGG: { + readSamples44k = DecodeOGG( sample, sampleOffset44k, sampleCount44k, dest ); + break; + } + default: { + readSamples44k = 0; + break; + } + } + + Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE ); + + if ( readSamples44k < sampleCount44k ) { + memset( dest + readSamples44k, 0, ( sampleCount44k - readSamples44k ) * sizeof( dest[0] ) ); + } +} + +/* +==================== +idSampleDecoderLocal::DecodePCM +==================== +*/ +int idSampleDecoderLocal::DecodePCM( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) { + const byte *first; + int pos, size, readSamples; + + lastFormat = WAVE_FORMAT_TAG_PCM; + lastSample = sample; + + int shift = 22050 / sample->objectInfo.nSamplesPerSec; + int sampleOffset = sampleOffset44k >> shift; + int sampleCount = sampleCount44k >> shift; + + if ( sample->nonCacheData == NULL ) { + assert( false ); // this should never happen ( note: I've seen that happen with the main thread down in idGameLocal::MapClear clearing entities - TTimo ) + failed = true; + return 0; + } + + if ( !sample->FetchFromCache( sampleOffset * sizeof( short ), &first, &pos, &size, false ) ) { + failed = true; + return 0; + } + + if ( size - pos < sampleCount * sizeof( short ) ) { + readSamples = ( size - pos ) / sizeof( short ); + } else { + readSamples = sampleCount; + } + + // duplicate samples for 44kHz output + SIMDProcessor->UpSamplePCMTo44kHz( dest, (const short *)(first+pos), readSamples, sample->objectInfo.nSamplesPerSec, sample->objectInfo.nChannels ); + + return ( readSamples << shift ); +} + +/* +==================== +idSampleDecoderLocal::DecodeOGG +==================== +*/ +int idSampleDecoderLocal::DecodeOGG( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) { + int readSamples, totalSamples; + + int shift = 22050 / sample->objectInfo.nSamplesPerSec; + int sampleOffset = sampleOffset44k >> shift; + int sampleCount = sampleCount44k >> shift; + + // open OGG file if not yet opened + if ( lastSample == NULL ) { + // make sure there is enough space for another decoder + if ( decoderMemoryAllocator.GetFreeBlockMemory() < MIN_OGGVORBIS_MEMORY ) { + return 0; + } + if ( sample->nonCacheData == NULL ) { + assert( false ); // this should never happen + failed = true; + return 0; + } + file.SetData( (const char *)sample->nonCacheData, sample->objectMemSize ); + if ( ov_openFile( &file, &ogg ) < 0 ) { + failed = true; + return 0; + } + lastFormat = WAVE_FORMAT_TAG_OGG; + lastSample = sample; + } + + // seek to the right offset if necessary + if ( sampleOffset != lastSampleOffset ) { + if ( ov_pcm_seek( &ogg, sampleOffset / sample->objectInfo.nChannels ) != 0 ) { + failed = true; + return 0; + } + } + + lastSampleOffset = sampleOffset; + + // decode OGG samples + totalSamples = sampleCount; + readSamples = 0; + do { + float **samples; + int ret = ov_read_float( &ogg, &samples, totalSamples / sample->objectInfo.nChannels, &ogg.stream ); + if ( ret == 0 ) { + failed = true; + break; + } + if ( ret < 0 ) { + failed = true; + return 0; + } + ret *= sample->objectInfo.nChannels; + + SIMDProcessor->UpSampleOGGTo44kHz( dest + ( readSamples << shift ), samples, ret, sample->objectInfo.nSamplesPerSec, sample->objectInfo.nChannels ); + + readSamples += ret; + totalSamples -= ret; + } while( totalSamples > 0 ); + + lastSampleOffset += readSamples; + + return ( readSamples << shift ); +} diff --git a/sound/snd_efxfile.cpp b/sound/snd_efxfile.cpp new file mode 100644 index 000000000..923ffccce --- /dev/null +++ b/sound/snd_efxfile.cpp @@ -0,0 +1,223 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + +/* +=============== +idEFXFile::idEFXFile +=============== +*/ +idEFXFile::idEFXFile( void ) { } + +/* +=============== +idEFXFile::Clear +=============== +*/ +void idEFXFile::Clear( void ) { + effects.DeleteContents( true ); +} + +/* +=============== +idEFXFile::~idEFXFile +=============== +*/ +idEFXFile::~idEFXFile( void ) { + Clear(); +} + +/* +=============== +idEFXFile::FindEffect +=============== +*/ +bool idEFXFile::FindEffect( idStr &name, idSoundEffect **effect, int *index ) { + int i; + + for ( i = 0; i < effects.Num(); i++ ) { + if ( ( effects[i] ) && ( effects[i]->name == name ) ) { + *effect = effects[i]; + *index = i; + return true; + } + } + return false; +} + +/* +=============== +idEFXFile::ReadEffect +=============== +*/ +bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) { + idToken name, token; + + if ( !src.ReadToken( &token ) ) + return false; + + // reverb effect + if ( token == "reverb" ) { + EAXREVERBPROPERTIES *reverb = ( EAXREVERBPROPERTIES * )Mem_Alloc( sizeof( EAXREVERBPROPERTIES ) ); + if ( reverb ) { + src.ReadTokenOnLine( &token ); + name = token; + + if ( !src.ReadToken( &token ) ) { + Mem_Free( reverb ); + return false; + } + + if ( token != "{" ) { + src.Error( "idEFXFile::ReadEffect: { not found, found %s", token.c_str() ); + Mem_Free( reverb ); + return false; + } + + do { + if ( !src.ReadToken( &token ) ) { + src.Error( "idEFXFile::ReadEffect: EOF without closing brace" ); + Mem_Free( reverb ); + return false; + } + + if ( token == "}" ) { + effect->name = name; + effect->data = ( void * )reverb; + effect->datasize = sizeof( EAXREVERBPROPERTIES ); + break; + } + + if ( token == "environment" ) { + src.ReadTokenOnLine( &token ); + reverb->ulEnvironment = token.GetUnsignedLongValue(); + } else if ( token == "environment size" ) { + reverb->flEnvironmentSize = src.ParseFloat(); + } else if ( token == "environment diffusion" ) { + reverb->flEnvironmentDiffusion = src.ParseFloat(); + } else if ( token == "room" ) { + reverb->lRoom = src.ParseInt(); + } else if ( token == "room hf" ) { + reverb->lRoomHF = src.ParseInt(); + } else if ( token == "room lf" ) { + reverb->lRoomLF = src.ParseInt(); + } else if ( token == "decay time" ) { + reverb->flDecayTime = src.ParseFloat(); + } else if ( token == "decay hf ratio" ) { + reverb->flDecayHFRatio = src.ParseFloat(); + } else if ( token == "decay lf ratio" ) { + reverb->flDecayLFRatio = src.ParseFloat(); + } else if ( token == "reflections" ) { + reverb->lReflections = src.ParseInt(); + } else if ( token == "reflections delay" ) { + reverb->flReflectionsDelay = src.ParseFloat(); + } else if ( token == "reflections pan" ) { + reverb->vReflectionsPan.x = src.ParseFloat(); + reverb->vReflectionsPan.y = src.ParseFloat(); + reverb->vReflectionsPan.z = src.ParseFloat(); + } else if ( token == "reverb" ) { + reverb->lReverb = src.ParseInt(); + } else if ( token == "reverb delay" ) { + reverb->flReverbDelay = src.ParseFloat(); + } else if ( token == "reverb pan" ) { + reverb->vReverbPan.x = src.ParseFloat(); + reverb->vReverbPan.y = src.ParseFloat(); + reverb->vReverbPan.z = src.ParseFloat(); + } else if ( token == "echo time" ) { + reverb->flEchoTime = src.ParseFloat(); + } else if ( token == "echo depth" ) { + reverb->flEchoDepth = src.ParseFloat(); + } else if ( token == "modulation time" ) { + reverb->flModulationTime = src.ParseFloat(); + } else if ( token == "modulation depth" ) { + reverb->flModulationDepth = src.ParseFloat(); + } else if ( token == "air absorption hf" ) { + reverb->flAirAbsorptionHF = src.ParseFloat(); + } else if ( token == "hf reference" ) { + reverb->flHFReference = src.ParseFloat(); + } else if ( token == "lf reference" ) { + reverb->flLFReference = src.ParseFloat(); + } else if ( token == "room rolloff factor" ) { + reverb->flRoomRolloffFactor = src.ParseFloat(); + } else if ( token == "flags" ) { + src.ReadTokenOnLine( &token ); + reverb->ulFlags = token.GetUnsignedLongValue(); + } else { + src.ReadTokenOnLine( &token ); + src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" ); + Mem_Free( reverb ); + } + } while ( 1 ); + + return true; + } + } else { + // other effect (not supported at the moment) + src.Error( "idEFXFile::ReadEffect: Unknown effect definition" ); + } + + return false; +} + + +/* +=============== +idEFXFile::LoadFile +=============== +*/ +bool idEFXFile::LoadFile( const char *filename, bool OSPath ) { + idLexer src( LEXFL_NOSTRINGCONCAT ); + idToken token; + + src.LoadFile( filename, OSPath ); + if ( !src.IsLoaded() ) { + return false; + } + + if ( !src.ExpectTokenString( "Version" ) ) { + return NULL; + } + + if ( src.ParseInt() != 1 ) { + src.Error( "idEFXFile::LoadFile: Unknown file version" ); + return false; + } + + while ( !src.EndOfFile() ) { + idSoundEffect *effect = new idSoundEffect; + if ( ReadEffect( src, effect ) ) { + effects.Append( effect ); + } + }; + + return true; +} + + +/* +=============== +idEFXFile::UnloadFile +=============== +*/ +void idEFXFile::UnloadFile( void ) { + Clear(); +} diff --git a/sound/snd_emitter.cpp b/sound/snd_emitter.cpp new file mode 100644 index 000000000..e7078d7f2 --- /dev/null +++ b/sound/snd_emitter.cpp @@ -0,0 +1,1224 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + + +/* +=================== +idSoundFade::Clear +=================== +*/ +void idSoundFade::Clear() { + fadeStart44kHz = 0; + fadeEnd44kHz = 0; + fadeStartVolume = 0; + fadeEndVolume = 0; +} + +/* +=================== +idSoundFade::FadeDbAt44kHz +=================== +*/ +float idSoundFade::FadeDbAt44kHz( int current44kHz ) { + float fadeDb; + + if ( current44kHz >= fadeEnd44kHz ) { + fadeDb = fadeEndVolume; + } else if ( current44kHz > fadeStart44kHz ) { + float fraction = ( fadeEnd44kHz - fadeStart44kHz ); + float over = ( current44kHz - fadeStart44kHz ); + fadeDb = fadeStartVolume + ( fadeEndVolume - fadeStartVolume ) * over / fraction; + } else { + fadeDb = fadeStartVolume; + } + return fadeDb; +} + +//======================================================================== + + +/* +======================= +GeneratePermutedList + +Fills in elements[0] .. elements[numElements-1] with a permutation of +0 .. numElements-1 based on the permute parameter + +numElements == 3 +maxPermute = 6 +permute 0 = 012 +permute 1 = 021 +permute 2 = 102 +permute 3 = 120 +permute 4 = 201 +permute 5 = 210 +======================= +*/ +void PermuteList_r( int *list, int listLength, int permute, int maxPermute ) { + if ( listLength < 2 ) { + return; + } + permute %= maxPermute; + int swap = permute * listLength / maxPermute; + int old = list[swap]; + list[swap] = list[0]; + list[0] = old; + + maxPermute /= listLength; + PermuteList_r( list + 1, listLength - 1, permute, maxPermute ); +} + +int Factorial( int val ) { + int fact = val; + while ( val > 1 ) { + val--; + fact *= val; + } + return fact; +} + +void GeneratePermutedList( int *list, int listLength, int permute ) { + for ( int i = 0 ; i < listLength ; i++ ) { + list[i] = i; + } + + // we can't calculate > 12 factorial, so we can't easily build a permuted list + if ( listLength > 12 ) { + return; + } + + // calculate listLength factorial + int maxPermute = Factorial( listLength ); + + // recursively permute + PermuteList_r( list, listLength, permute, maxPermute ); +} + +void TestPermutations( void ) { + int list[SOUND_MAX_LIST_WAVS]; + + for ( int len = 1 ; len < 5 ; len++ ) { + common->Printf( "list length: %i\n", len ); + + int max = Factorial( len ); + for ( int j = 0 ; j < max * 2 ; j++ ) { + GeneratePermutedList( list, len, j ); + common->Printf( "%4i : ", j ); + for ( int k = 0 ; k < len ; k++ ) { + common->Printf( "%i", list[k] ); + } + common->Printf( "\n" ); + } + } +} + +//===================================================================================== + +/* +=================== +idSoundChannel::idSoundChannel +=================== +*/ +idSoundChannel::idSoundChannel( void ) { + decoder = NULL; + Clear(); +} + +/* +=================== +idSoundChannel::~idSoundChannel +=================== +*/ +idSoundChannel::~idSoundChannel( void ) { + Clear(); +} + +/* +=================== +idSoundChannel::Clear +=================== +*/ +void idSoundChannel::Clear( void ) { + int j; + + Stop(); + soundShader = NULL; + lastVolume = 0.0f; + triggerChannel = SCHANNEL_ANY; + channelFade.Clear(); + diversity = 0.0f; + leadinSample = NULL; + trigger44kHzTime = 0; + for( j = 0; j < 6; j++ ) { + lastV[j] = 0.0f; + } + memset( &parms, 0, sizeof(parms) ); + + triggered = false; + openalSource = NULL; + openalStreamingOffset = 0; + openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0; + lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0; +} + +/* +=================== +idSoundChannel::Start +=================== +*/ +void idSoundChannel::Start( void ) { + triggerState = true; + if ( decoder == NULL ) { + decoder = idSampleDecoder::Alloc(); + } +} + +/* +=================== +idSoundChannel::Stop +=================== +*/ +void idSoundChannel::Stop( void ) { + triggerState = false; + if ( decoder != NULL ) { + idSampleDecoder::Free( decoder ); + decoder = NULL; + } +} + +/* +=================== +idSoundChannel::ALStop +=================== +*/ +void idSoundChannel::ALStop( void ) { + if ( idSoundSystemLocal::useOpenAL ) { + + if ( alIsSource( openalSource ) ) { + alSourceStop( openalSource ); + alSourcei( openalSource, AL_BUFFER, 0 ); + soundSystemLocal.FreeOpenALSource( openalSource ); + } + + if ( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] ) { + alGetError(); + alDeleteBuffers( 3, &openalStreamingBuffer[0] ); + if ( alGetError() == AL_NO_ERROR ) { + openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0; + } + } + + if ( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] ) { + alGetError(); + alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] ); + if ( alGetError() == AL_NO_ERROR ) { + lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0; + } + } + } +} + +/* +=================== +idSoundChannel::GatherChannelSamples + +Will always return 44kHz samples for the given range, even if it deeply looped or +out of the range of the unlooped samples. Handles looping between multiple different +samples and leadins +=================== +*/ +void idSoundChannel::GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) const { + float *dest_p = dest; + int len; + +//Sys_DebugPrintf( "msec:%i sample:%i : %i : %i\n", Sys_Milliseconds(), soundSystemLocal.GetCurrent44kHzTime(), sampleOffset44k, sampleCount44k ); //!@# + + // negative offset times will just zero fill + if ( sampleOffset44k < 0 ) { + len = -sampleOffset44k; + if ( len > sampleCount44k ) { + len = sampleCount44k; + } + memset( dest_p, 0, len * sizeof( dest_p[0] ) ); + dest_p += len; + sampleCount44k -= len; + sampleOffset44k += len; + } + + // grab part of the leadin sample + idSoundSample *leadin = leadinSample; + if ( !leadin || sampleOffset44k < 0 || sampleCount44k <= 0 ) { + memset( dest_p, 0, sampleCount44k * sizeof( dest_p[0] ) ); + return; + } + + if ( sampleOffset44k < leadin->LengthIn44kHzSamples() ) { + len = leadin->LengthIn44kHzSamples() - sampleOffset44k; + if ( len > sampleCount44k ) { + len = sampleCount44k; + } + + // decode the sample + decoder->Decode( leadin, sampleOffset44k, len, dest_p ); + + dest_p += len; + sampleCount44k -= len; + sampleOffset44k += len; + } + + // if not looping, zero fill any remaining spots + if ( !soundShader || !( parms.soundShaderFlags & SSF_LOOPING ) ) { + memset( dest_p, 0, sampleCount44k * sizeof( dest_p[0] ) ); + return; + } + + // fill the remainder with looped samples + idSoundSample *loop = soundShader->entries[0]; + + if ( !loop ) { + memset( dest_p, 0, sampleCount44k * sizeof( dest_p[0] ) ); + return; + } + + sampleOffset44k -= leadin->LengthIn44kHzSamples(); + + while( sampleCount44k > 0 ) { + int totalLen = loop->LengthIn44kHzSamples(); + + sampleOffset44k %= totalLen; + + len = totalLen - sampleOffset44k; + if ( len > sampleCount44k ) { + len = sampleCount44k; + } + + // decode the sample + decoder->Decode( loop, sampleOffset44k, len, dest_p ); + + dest_p += len; + sampleCount44k -= len; + sampleOffset44k += len; + } +} + + +//===================================================================================== + +/* +=============== +idSoundEmitterLocal::idSoundEmitterLocal + +=============== +*/ +idSoundEmitterLocal::idSoundEmitterLocal( void ) { + soundWorld = NULL; + Clear(); +} + +/* +=============== +idSoundEmitterLocal::~idSoundEmitterLocal +=============== +*/ +idSoundEmitterLocal::~idSoundEmitterLocal( void ) { + Clear(); +} + +/* +=============== +idSoundEmitterLocal::Clear +=============== +*/ +void idSoundEmitterLocal::Clear( void ) { + int i; + + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + channels[i].ALStop(); + channels[i].Clear(); + } + + removeStatus = REMOVE_STATUS_SAMPLEFINISHED; + distance = 0.0f; + + lastValidPortalArea = -1; + + playing = false; + hasShakes = false; + ampTime = 0; // last time someone queried + amplitude = 0; + maxDistance = 10.0f; // meters + spatializedOrigin.Zero(); + + memset( &parms, 0, sizeof( parms ) ); +} + +/* +================== +idSoundEmitterLocal::OverrideParms +================== +*/ +void idSoundEmitterLocal::OverrideParms( const soundShaderParms_t *base, + const soundShaderParms_t *over, soundShaderParms_t *out ) { + if ( !over ) { + *out = *base; + return; + } + if ( over->minDistance ) { + out->minDistance = over->minDistance; + } else { + out->minDistance = base->minDistance; + } + if ( over->maxDistance ) { + out->maxDistance = over->maxDistance; + } else { + out->maxDistance = base->maxDistance; + } + if ( over->shakes ) { + out->shakes = over->shakes; + } else { + out->shakes = base->shakes; + } + if ( over->volume ) { + out->volume = over->volume; + } else { + out->volume = base->volume; + } + if ( over->soundClass ) { + out->soundClass = over->soundClass; + } else { + out->soundClass = base->soundClass; + } + out->soundShaderFlags = base->soundShaderFlags | over->soundShaderFlags; +} + +/* +================== +idSoundEmitterLocal::CheckForCompletion + +Checks to see if all the channels have completed, clearing the playing flag if necessary. +Sets the playing and shakes bools. +================== +*/ +void idSoundEmitterLocal::CheckForCompletion( int current44kHzTime ) { + bool hasActive; + int i; + + hasActive = false; + hasShakes = false; + + if ( playing ) { + for ( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + + if ( !chan->triggerState ) { + continue; + } + const idSoundShader *shader = chan->soundShader; + if ( !shader ) { + continue; + } + + // see if this channel has completed + if ( !( chan->parms.soundShaderFlags & SSF_LOOPING ) ) { + ALint state = AL_PLAYING; + + if ( idSoundSystemLocal::useOpenAL && alIsSource( chan->openalSource ) ) { + alGetSourcei( chan->openalSource, AL_SOURCE_STATE, &state ); + } + idSlowChannel slow = GetSlowChannel( chan ); + + if ( soundWorld->slowmoActive && slow.IsActive() ) { + if ( slow.GetCurrentPosition().time >= chan->leadinSample->LengthIn44kHzSamples() / 2 ) { + chan->Stop(); + // if this was an onDemand sound, purge the sample now + if ( chan->leadinSample->onDemand ) { + chan->leadinSample->PurgeSoundSample(); + } + continue; + } + } else if ( ( chan->trigger44kHzTime + chan->leadinSample->LengthIn44kHzSamples() < current44kHzTime ) || ( state == AL_STOPPED ) ) { + chan->Stop(); + + // free hardware resources + chan->ALStop(); + + // if this was an onDemand sound, purge the sample now + if ( chan->leadinSample->onDemand ) { + chan->leadinSample->PurgeSoundSample(); + } + continue; + } + } + + // free decoder memory if no sound was decoded for a while + if ( chan->decoder != NULL && chan->decoder->GetLastDecodeTime() < current44kHzTime - SOUND_DECODER_FREE_DELAY ) { + chan->decoder->ClearDecoder(); + } + + hasActive = true; + + if ( chan->parms.shakes > 0.0f ) { + hasShakes = true; + } + } + } + + // mark the entire sound emitter as non-playing if there aren't any active channels + if ( !hasActive ) { + playing = false; + if ( removeStatus == REMOVE_STATUS_WAITSAMPLEFINISHED ) { + // this can now be reused by the next request for a new soundEmitter + removeStatus = REMOVE_STATUS_SAMPLEFINISHED; + } + } +} + +/* +=================== +idSoundEmitterLocal::Spatialize + +Called once each sound frame by the main thread from idSoundWorldLocal::PlaceOrigin +=================== +*/ +void idSoundEmitterLocal::Spatialize( idVec3 listenerPos, int listenerArea, idRenderWorld *rw ) { + int i; + bool hasActive = false; + + // + // work out the maximum distance of all the playing channels + // + maxDistance = 0; + + for ( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + + if ( !chan->triggerState ) { + continue; + } + if ( chan->parms.maxDistance > maxDistance ) { + maxDistance = chan->parms.maxDistance; + } + } + + // + // work out where the sound comes from + // + idVec3 realOrigin = origin * DOOM_TO_METERS; + idVec3 len = listenerPos - realOrigin; + realDistance = len.LengthFast(); + + if ( realDistance >= maxDistance ) { + // no way to possibly hear it + distance = realDistance; + return; + } + + // + // work out virtual origin and distance, which may be from a portal instead of the actual origin + // + distance = maxDistance * METERS_TO_DOOM; + if ( listenerArea == -1 ) { // listener is outside the world + return; + } + if ( rw ) { + // we have a valid renderWorld + int soundInArea = rw->PointInArea( origin ); + if ( soundInArea == -1 ) { + if ( lastValidPortalArea == -1 ) { // sound is outside the world + distance = realDistance; + spatializedOrigin = origin; // sound is in our area + return; + } + soundInArea = lastValidPortalArea; + } + lastValidPortalArea = soundInArea; + if ( soundInArea == listenerArea ) { + distance = realDistance; + spatializedOrigin = origin; // sound is in our area + return; + } + + soundWorld->ResolveOrigin( 0, NULL, soundInArea, 0.0f, origin, this ); + distance /= METERS_TO_DOOM; + } else { + // no portals available + distance = realDistance; + spatializedOrigin = origin; // sound is in our area + } +} + +/* +=========================================================================================== + +PUBLIC FUNCTIONS + +=========================================================================================== +*/ + +/* +===================== +idSoundEmitterLocal::UpdateEmitter +===================== +*/ +void idSoundEmitterLocal::UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ) { + if ( !parms ) { + common->Error( "idSoundEmitterLocal::UpdateEmitter: NULL parms" ); + } + if ( soundWorld && soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_UPDATE ); + soundWorld->writeDemo->WriteInt( index ); + soundWorld->writeDemo->WriteVec3( origin ); + soundWorld->writeDemo->WriteInt( listenerId ); + soundWorld->writeDemo->WriteFloat( parms->minDistance ); + soundWorld->writeDemo->WriteFloat( parms->maxDistance ); + soundWorld->writeDemo->WriteFloat( parms->volume ); + soundWorld->writeDemo->WriteFloat( parms->shakes ); + soundWorld->writeDemo->WriteInt( parms->soundShaderFlags ); + soundWorld->writeDemo->WriteInt( parms->soundClass ); + } + + this->origin = origin; + this->listenerId = listenerId; + this->parms = *parms; + + // FIXME: change values on all channels? +} + +/* +===================== +idSoundEmitterLocal::Free + +They are never truly freed, just marked so they can be reused by the soundWorld +===================== +*/ +void idSoundEmitterLocal::Free( bool immediate ) { + if ( removeStatus != REMOVE_STATUS_ALIVE ) { + return; + } + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "FreeSound (%i,%i)\n", index, (int)immediate ); + } + if ( soundWorld && soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_FREE ); + soundWorld->writeDemo->WriteInt( index ); + soundWorld->writeDemo->WriteInt( immediate ); + } + + if ( !immediate ) { + removeStatus = REMOVE_STATUS_WAITSAMPLEFINISHED; + } else { + Clear(); + } +} + +/* +===================== +idSoundEmitterLocal::StartSound + +returns the length of the started sound in msec +===================== +*/ +int idSoundEmitterLocal::StartSound( const idSoundShader *shader, const s_channelType channel, float diversity, int soundShaderFlags, bool allowSlow ) { + int i; + + if ( !shader ) { + return 0; + } + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "StartSound %ims (%i,%i,%s) = ", soundWorld->gameMsec, index, (int)channel, shader->GetName() ); + } + + if ( soundWorld && soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_START ); + soundWorld->writeDemo->WriteInt( index ); + + soundWorld->writeDemo->WriteHashString( shader->GetName() ); + + soundWorld->writeDemo->WriteInt( channel ); + soundWorld->writeDemo->WriteFloat( diversity ); + soundWorld->writeDemo->WriteInt( soundShaderFlags ); + } + + // build the channel parameters by taking the shader parms and optionally overriding + soundShaderParms_t chanParms; + + chanParms = shader->parms; + OverrideParms( &chanParms, &this->parms, &chanParms ); + chanParms.soundShaderFlags |= soundShaderFlags; + + if ( chanParms.shakes > 0.0f ) { + shader->CheckShakesAndOgg(); + } + + // this is the sample time it will be first mixed + int start44kHz; + + if ( soundWorld->fpa[0] ) { + // if we are recording an AVI demo, don't use hardware time + start44kHz = soundWorld->lastAVI44kHz + MIXBUFFER_SAMPLES; + } else { + start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES; + } + + // + // pick which sound to play from the shader + // + if ( !shader->numEntries ) { + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "no samples in sound shader\n" ); + } + return 0; // no sounds + } + int choice; + + // pick a sound from the list based on the passed diversity + choice = (int)(diversity * shader->numEntries); + if ( choice < 0 || choice >= shader->numEntries ) { + choice = 0; + } + + // bump the choice if the exact sound was just played and we are NO_DUPS + if ( chanParms.soundShaderFlags & SSF_NO_DUPS ) { + idSoundSample *sample; + if ( shader->leadins[ choice ] ) { + sample = shader->leadins[ choice ]; + } else { + sample = shader->entries[ choice ]; + } + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + if ( chan->leadinSample == sample ) { + choice = ( choice + 1 ) % shader->numEntries; + break; + } + } + } + + // PLAY_ONCE sounds will never be restarted while they are running + if ( chanParms.soundShaderFlags & SSF_PLAY_ONCE ) { + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + if ( chan->triggerState && chan->soundShader == shader ) { + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "PLAY_ONCE not restarting\n" ); + } + return 0; + } + } + } + + // never play the same sound twice with the same starting time, even + // if they are on different channels + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + if ( chan->triggerState && chan->soundShader == shader && chan->trigger44kHzTime == start44kHz ) { + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "already started this frame\n" ); + } + return 0; + } + } + + Sys_EnterCriticalSection(); + + // kill any sound that is currently playing on this channel + if ( channel != SCHANNEL_ANY ) { + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + if ( chan->triggerState && chan->soundShader && chan->triggerChannel == channel ) { + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "(override %s)", chan->soundShader->base->GetName() ); + } + + chan->Stop(); + + // if this was an onDemand sound, purge the sample now + if ( chan->leadinSample->onDemand ) { + chan->ALStop(); + chan->leadinSample->PurgeSoundSample(); + } + break; + } + } + } + + // find a free channel to play the sound on + idSoundChannel *chan; + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + chan = &channels[i]; + if ( !chan->triggerState ) { + break; + } + } + + if ( i == SOUND_MAX_CHANNELS ) { + // we couldn't find a channel for it + Sys_LeaveCriticalSection(); + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "no channels available\n" ); + } + return 0; + } + + chan = &channels[i]; + + if ( shader->leadins[ choice ] ) { + chan->leadinSample = shader->leadins[ choice ]; + } else { + chan->leadinSample = shader->entries[ choice ]; + } + + // if the sample is onDemand (voice mails, etc), load it now + if ( chan->leadinSample->purged ) { + int start = Sys_Milliseconds(); + chan->leadinSample->Load(); + int end = Sys_Milliseconds(); + session->TimeHitch( end - start ); + // recalculate start44kHz, because loading may have taken a fair amount of time + if ( !soundWorld->fpa[0] ) { + start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES; + } + } + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "'%s'\n", chan->leadinSample->name.c_str() ); + } + + if ( idSoundSystemLocal::s_skipHelltimeFX.GetBool() ) { + chan->disallowSlow = true; + } else { + chan->disallowSlow = !allowSlow; + } + + ResetSlowChannel( chan ); + + // the sound will start mixing in the next async mix block + chan->triggered = true; + chan->openalStreamingOffset = 0; + chan->trigger44kHzTime = start44kHz; + chan->parms = chanParms; + chan->triggerGame44kHzTime = soundWorld->game44kHz; + chan->soundShader = shader; + chan->triggerChannel = channel; + chan->Start(); + + // we need to start updating the def and mixing it in + playing = true; + + // spatialize it immediately, so it will start the next mix block + // even if that happens before the next PlaceOrigin() + Spatialize( soundWorld->listenerPos, soundWorld->listenerArea, soundWorld->rw ); + + // return length of sound in milliseconds + int length = chan->leadinSample->LengthIn44kHzSamples(); + + if ( chan->leadinSample->objectInfo.nChannels == 2 ) { + length /= 2; // stereo samples + } + + // adjust the start time based on diversity for looping sounds, so they don't all start + // at the same point + if ( chan->parms.soundShaderFlags & SSF_LOOPING && !chan->leadinSample->LengthIn44kHzSamples() ) { + chan->trigger44kHzTime -= diversity * length; + chan->trigger44kHzTime &= ~7; // so we don't have to worry about the 22kHz and 11kHz expansions + // starting in fractional samples + chan->triggerGame44kHzTime -= diversity * length; + chan->triggerGame44kHzTime &= ~7; + } + + length *= 1000 / (float)PRIMARYFREQ; + + Sys_LeaveCriticalSection(); + + return length; +} + +/* +=================== +idSoundEmitterLocal::ModifySound +=================== +*/ +void idSoundEmitterLocal::ModifySound( const s_channelType channel, const soundShaderParms_t *parms ) { + if ( !parms ) { + common->Error( "idSoundEmitterLocal::ModifySound: NULL parms" ); + } + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "ModifySound(%i,%i)\n", index, channel ); + } + if ( soundWorld && soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_MODIFY ); + soundWorld->writeDemo->WriteInt( index ); + soundWorld->writeDemo->WriteInt( channel ); + soundWorld->writeDemo->WriteFloat( parms->minDistance ); + soundWorld->writeDemo->WriteFloat( parms->maxDistance ); + soundWorld->writeDemo->WriteFloat( parms->volume ); + soundWorld->writeDemo->WriteFloat( parms->shakes ); + soundWorld->writeDemo->WriteInt( parms->soundShaderFlags ); + soundWorld->writeDemo->WriteInt( parms->soundClass ); + } + + for ( int i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + + if ( !chan->triggerState ) { + continue; + } + if ( channel != SCHANNEL_ANY && chan->triggerChannel != channel ) { + continue; + } + + OverrideParms( &chan->parms, parms, &chan->parms ); + + if ( chan->parms.shakes > 0.0f && chan->soundShader != NULL ) { + chan->soundShader->CheckShakesAndOgg(); + } + } +} + +/* +=================== +idSoundEmitterLocal::StopSound + +can pass SCHANNEL_ANY +=================== +*/ +void idSoundEmitterLocal::StopSound( const s_channelType channel ) { + int i; + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "StopSound(%i,%i)\n", index, channel ); + } + + if ( soundWorld && soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_STOP ); + soundWorld->writeDemo->WriteInt( index ); + soundWorld->writeDemo->WriteInt( channel ); + } + + Sys_EnterCriticalSection(); + + for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) { + idSoundChannel *chan = &channels[i]; + + if ( !chan->triggerState ) { + continue; + } + if ( channel != SCHANNEL_ANY && chan->triggerChannel != channel ) { + continue; + } + + // stop it + chan->Stop(); + + // free hardware resources + chan->ALStop(); + + // if this was an onDemand sound, purge the sample now + if ( chan->leadinSample->onDemand ) { + chan->leadinSample->PurgeSoundSample(); + } + + chan->leadinSample = NULL; + chan->soundShader = NULL; + } + + Sys_LeaveCriticalSection(); +} + +/* +=================== +idSoundEmitterLocal::FadeSound + +to is in Db (sigh), over is in seconds +=================== +*/ +void idSoundEmitterLocal::FadeSound( const s_channelType channel, float to, float over ) { + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "FadeSound(%i,%i,%f,%f )\n", index, channel, to, over ); + } + if ( !soundWorld ) { + return; + } + if ( soundWorld->writeDemo ) { + soundWorld->writeDemo->WriteInt( DS_SOUND ); + soundWorld->writeDemo->WriteInt( SCMD_FADE ); + soundWorld->writeDemo->WriteInt( index ); + soundWorld->writeDemo->WriteInt( channel ); + soundWorld->writeDemo->WriteFloat( to ); + soundWorld->writeDemo->WriteFloat( over ); + } + + int start44kHz; + + if ( soundWorld->fpa[0] ) { + // if we are recording an AVI demo, don't use hardware time + start44kHz = soundWorld->lastAVI44kHz + MIXBUFFER_SAMPLES; + } else { + start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES; + } + + int length44kHz = soundSystemLocal.MillisecondsToSamples( over * 1000 ); + + for( int i = 0; i < SOUND_MAX_CHANNELS ; i++ ) { + idSoundChannel *chan = &channels[i]; + + if ( !chan->triggerState ) { + continue; + } + if ( channel != SCHANNEL_ANY && chan->triggerChannel != channel ) { + continue; + } + + // if it is already fading to this volume at this rate, don't change it + if ( chan->channelFade.fadeEndVolume == to && + chan->channelFade.fadeEnd44kHz - chan->channelFade.fadeStart44kHz == length44kHz ) { + continue; + } + + // fade it + chan->channelFade.fadeStartVolume = chan->channelFade.FadeDbAt44kHz( start44kHz ); + chan->channelFade.fadeStart44kHz = start44kHz; + chan->channelFade.fadeEnd44kHz = start44kHz + length44kHz; + chan->channelFade.fadeEndVolume = to; + } +} + +/* +=================== +idSoundEmitterLocal::CurrentlyPlaying +=================== +*/ +bool idSoundEmitterLocal::CurrentlyPlaying( void ) const { + return playing; +} + +/* +=================== +idSoundEmitterLocal::Index +=================== +*/ +int idSoundEmitterLocal::Index( void ) const { + return index; +} + +/* +=================== +idSoundEmitterLocal::CurrentAmplitude + +this is called from the main thread by the material shader system +to allow lights and surface flares to vary with the sound amplitude +=================== +*/ +float idSoundEmitterLocal::CurrentAmplitude( void ) { + if ( idSoundSystemLocal::s_constantAmplitude.GetFloat() >= 0.0f ) { + return idSoundSystemLocal::s_constantAmplitude.GetFloat(); + } + + if ( removeStatus > REMOVE_STATUS_WAITSAMPLEFINISHED ) { + return 0.0; + } + + int localTime = soundSystemLocal.GetCurrent44kHzTime(); + + // see if we can use our cached value + if ( ampTime == localTime ) { + return amplitude; + } + + // calculate a new value + ampTime = localTime; + amplitude = soundWorld->FindAmplitude( this, localTime, NULL, SCHANNEL_ANY, false ); + + return amplitude; +} + +/* +=================== +idSoundEmitterLocal::GetSlowChannel +=================== +*/ +idSlowChannel idSoundEmitterLocal::GetSlowChannel( const idSoundChannel *chan ) { + return slowChannels[chan - channels]; +} + +/* +=================== +idSoundEmitterLocal::SetSlowChannel +=================== +*/ +void idSoundEmitterLocal::SetSlowChannel( const idSoundChannel *chan, idSlowChannel slow ) { + slowChannels[chan - channels] = slow; +} + +/* +=================== +idSoundEmitterLocal::ResetSlowChannel +=================== +*/ +void idSoundEmitterLocal::ResetSlowChannel( const idSoundChannel *chan ) { + int index = chan - channels; + slowChannels[index].Reset(); +} + +/* +=================== +idSlowChannel::Reset +=================== +*/ +void idSlowChannel::Reset() { + memset( this, 0, sizeof( *this ) ); + + this->chan = chan; + + curPosition.Set( 0 ); + newPosition.Set( 0 ); + + curSampleOffset = -10000; + newSampleOffset = -10000; + + triggerOffset = 0; +} + +/* +=================== +idSlowChannel::AttachSoundChannel +=================== +*/ +void idSlowChannel::AttachSoundChannel( const idSoundChannel *chan ) { + this->chan = chan; +} + +/* +=================== +idSlowChannel::GetSlowmoSpeed +=================== +*/ +float idSlowChannel::GetSlowmoSpeed() { + idSoundWorldLocal *sw = static_cast( soundSystemLocal.GetPlayingSoundWorld() ); + + if ( sw ) { + return sw->slowmoSpeed; + } else { + return 0; + } +} + +/* +=================== +idSlowChannel::GenerateSlowChannel +=================== +*/ +void idSlowChannel::GenerateSlowChannel( FracTime& playPos, int sampleCount44k, float* finalBuffer ) { + idSoundWorldLocal *sw = static_cast( soundSystemLocal.GetPlayingSoundWorld() ); + float in[MIXBUFFER_SAMPLES+3], out[MIXBUFFER_SAMPLES+3], *src, *spline, slowmoSpeed; + int i, neededSamples, orgTime, zeroedPos, count = 0; + + src = in + 2; + spline = out + 2; + + if ( sw ) { + slowmoSpeed = sw->slowmoSpeed; + } + else { + slowmoSpeed = 1; + } + + neededSamples = sampleCount44k * slowmoSpeed + 4; + orgTime = playPos.time; + + // get the channel's samples + chan->GatherChannelSamples( playPos.time * 2, neededSamples, src ); + for ( i = 0; i < neededSamples >> 1; i++ ) { + spline[i] = src[i*2]; + } + + // interpolate channel + zeroedPos = playPos.time; + playPos.time = 0; + + for ( i = 0; i < sampleCount44k >> 1; i++, count += 2 ) { + float val; + val = spline[playPos.time]; + src[i] = val; + playPos.Increment( slowmoSpeed ); + } + + // lowpass filter + float *in_p = in + 2, *out_p = out + 2; + int numSamples = sampleCount44k >> 1; + + lowpass.GetContinuitySamples( in_p[-1], in_p[-2], out_p[-1], out_p[-2] ); + lowpass.SetParms( slowmoSpeed * 15000, 1.2f ); + + for ( int i = 0, count = 0; i < numSamples; i++, count += 2 ) { + lowpass.ProcessSample( in_p + i, out_p + i ); + finalBuffer[count] = finalBuffer[count+1] = out[i]; + } + + lowpass.SetContinuitySamples( in_p[numSamples-2], in_p[numSamples-3], out_p[numSamples-2], out_p[numSamples-3] ); + + playPos.time += zeroedPos; +} + +/* +=================== +idSlowChannel::GatherChannelSamples +=================== +*/ +void idSlowChannel::GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) { + int state = 0; + + // setup chan + active = true; + newSampleOffset = sampleOffset44k >> 1; + + // set state + if ( newSampleOffset < curSampleOffset ) { + state = PLAYBACK_RESET; + } else if ( newSampleOffset > curSampleOffset ) { + state = PLAYBACK_ADVANCING; + } + + if ( state == PLAYBACK_RESET ) { + curPosition.Set( newSampleOffset ); + } + + // set current vars + curSampleOffset = newSampleOffset; + newPosition = curPosition; + + // do the slow processing + GenerateSlowChannel( newPosition, sampleCount44k, dest ); + + // finish off + if ( state == PLAYBACK_ADVANCING ) + curPosition = newPosition; +} diff --git a/sound/snd_local.h b/sound/snd_local.h new file mode 100644 index 000000000..d83c920b8 --- /dev/null +++ b/sound/snd_local.h @@ -0,0 +1,915 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SND_LOCAL_H__ +#define __SND_LOCAL_H__ + +// you need the OpenAL headers for build, even if AL is not enabled - http://www.openal.org/ +#ifdef _WIN32 +#include "../openal/include/al.h" +#include "../openal/include/alc.h" +#include "../openal/idal.h" +// broken OpenAL SDK ? +#define ID_ALCHAR (ALubyte *) +#elif defined( MACOS_X ) +#include +#include +#define ID_ALCHAR +#else +#include +#include +#define ID_ALCHAR +#endif +#include "../openal/include/efxlib.h" + +// demo sound commands +typedef enum { + SCMD_STATE, // followed by a load game state + SCMD_PLACE_LISTENER, + SCMD_ALLOC_EMITTER, + + SCMD_FREE, + SCMD_UPDATE, + SCMD_START, + SCMD_MODIFY, + SCMD_STOP, + SCMD_FADE +} soundDemoCommand_t; + +const int SOUND_MAX_CHANNELS = 8; +const int SOUND_DECODER_FREE_DELAY = 1000 * MIXBUFFER_SAMPLES / USERCMD_MSEC; // four seconds + +const int PRIMARYFREQ = 44100; // samples per second +const float SND_EPSILON = 1.0f / 32768.0f; // if volume is below this, it will always multiply to zero + +const int ROOM_SLICES_IN_BUFFER = 10; + +class idAudioHardware; +class idAudioBuffer; +class idWaveFile; +class idSoundCache; +class idSoundSample; +class idSampleDecoder; +class idSoundWorldLocal; + + +/* +=================================================================================== + + General extended waveform format structure. + Use this for all NON PCM formats. + +=================================================================================== +*/ + +#ifdef WIN32 +#pragma pack(1) +#endif +#ifdef __MWERKS__ +#pragma pack (push, 1) +#endif +struct waveformatex_s { + word wFormatTag; /* format type */ + word nChannels; /* number of channels (i.e. mono, stereo...) */ + dword nSamplesPerSec; /* sample rate */ + dword nAvgBytesPerSec; /* for buffer estimation */ + word nBlockAlign; /* block size of data */ + word wBitsPerSample; /* Number of bits per sample of mono data */ + word cbSize; /* The count in bytes of the size of + extra information (after cbSize) */ +} PACKED; + +typedef waveformatex_s waveformatex_t; + +/* OLD general waveform format structure (information common to all formats) */ +struct waveformat_s { + word wFormatTag; /* format type */ + word nChannels; /* number of channels (i.e. mono, stereo, etc.) */ + dword nSamplesPerSec; /* sample rate */ + dword nAvgBytesPerSec; /* for buffer estimation */ + word nBlockAlign; /* block size of data */ +} PACKED; + +typedef waveformat_s waveformat_t; + +/* flags for wFormatTag field of WAVEFORMAT */ +enum { + WAVE_FORMAT_TAG_PCM = 1, + WAVE_FORMAT_TAG_OGG = 2 +}; + +/* specific waveform format structure for PCM data */ +struct pcmwaveformat_s { + waveformat_t wf; + word wBitsPerSample; +} PACKED; + +typedef pcmwaveformat_s pcmwaveformat_t; + +#ifndef mmioFOURCC +#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ + ( (dword)(byte)(ch0) | ( (dword)(byte)(ch1) << 8 ) | \ + ( (dword)(byte)(ch2) << 16 ) | ( (dword)(byte)(ch3) << 24 ) ) +#endif + +#define fourcc_riff mmioFOURCC('R', 'I', 'F', 'F') + +struct waveformatextensible_s { + waveformatex_t Format; + union { + word wValidBitsPerSample; /* bits of precision */ + word wSamplesPerBlock; /* valid if wBitsPerSample==0*/ + word wReserved; /* If neither applies, set to zero*/ + } Samples; + dword dwChannelMask; /* which channels are */ + /* present in stream */ + int SubFormat; +} PACKED; + +typedef waveformatextensible_s waveformatextensible_t; + +typedef dword fourcc; + +/* RIFF chunk information data structure */ +struct mminfo_s { + fourcc ckid; /* chunk ID */ + dword cksize; /* chunk size */ + fourcc fccType; /* form type or list type */ + dword dwDataOffset; /* offset of data portion of chunk */ +} PACKED; + +typedef mminfo_s mminfo_t; + +#ifdef WIN32 +#pragma pack() +#endif +#ifdef __MWERKS__ +#pragma pack (pop) +#endif + +/* +=================================================================================== + +idWaveFile + +=================================================================================== +*/ + +class idWaveFile { +public: + idWaveFile( void ); + ~idWaveFile( void ); + + int Open( const char* strFileName, waveformatex_t* pwfx = NULL ); + int OpenFromMemory( short* pbData, int ulDataSize, waveformatextensible_t* pwfx ); + int Read( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ); + int Seek( int offset ); + int Close( void ); + int ResetFile( void ); + + int GetOutputSize( void ) { return mdwSize; } + int GetMemorySize( void ) { return mMemSize; } + + waveformatextensible_t mpwfx; // Pointer to waveformatex structure + +private: + idFile * mhmmio; // I/O handle for the WAVE + mminfo_t mck; // Multimedia RIFF chunk + mminfo_t mckRiff; // used when opening a WAVE file + dword mdwSize; // size in samples + dword mMemSize; // size of the wave data in memory + dword mseekBase; + ID_TIME_T mfileTime; + + bool mbIsReadingFromMemory; + short * mpbData; + short * mpbDataCur; + dword mulDataSize; + + void * ogg; // only !NULL when !s_realTimeDecoding + bool isOgg; + +private: + int ReadMMIO( void ); + + int OpenOGG( const char* strFileName, waveformatex_t* pwfx = NULL ); + int ReadOGG( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ); + int CloseOGG( void ); +}; + + +/* +=================================================================================== + +idAudioHardware + +=================================================================================== +*/ + +class idAudioHardware { +public: + static idAudioHardware *Alloc(); + + virtual ~idAudioHardware(); + + virtual bool Initialize( ) = 0; + + virtual bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) = 0; + virtual bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) = 0; + virtual bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) = 0; + + // try to write as many sound samples to the device as possible without blocking and prepare for a possible new mixing call + // returns wether there is *some* space for writing available + virtual bool Flush( void ) = 0; + + virtual void Write( bool flushing ) = 0; + + virtual int GetNumberOfSpeakers( void )= 0; + virtual int GetMixBufferSize( void ) = 0; + virtual short* GetMixBuffer( void ) = 0; +}; + + +/* +=================================================================================== + +Encapsulates functionality of a DirectSound buffer. + +=================================================================================== +*/ + +class idAudioBuffer { +public: + virtual int Play( dword dwPriority=0, dword dwFlags=0 ) = 0; + virtual int Stop( void ) = 0; + virtual int Reset( void ) = 0; + virtual bool IsSoundPlaying( void ) = 0; + virtual void SetVolume( float x ) = 0; +}; + + +/* +=================================================================================== + +idSoundEmitterLocal + +=================================================================================== +*/ + +typedef enum { + REMOVE_STATUS_INVALID = -1, + REMOVE_STATUS_ALIVE = 0, + REMOVE_STATUS_WAITSAMPLEFINISHED = 1, + REMOVE_STATUS_SAMPLEFINISHED = 2 +} removeStatus_t; + +class idSoundFade { +public: + int fadeStart44kHz; + int fadeEnd44kHz; + float fadeStartVolume; // in dB + float fadeEndVolume; // in dB + + void Clear(); + float FadeDbAt44kHz( int current44kHz ); +}; + +class SoundFX { +protected: + bool initialized; + + int channel; + int maxlen; + + float* buffer; + float continuitySamples[4]; + + float param; + +public: + SoundFX() { channel = 0; buffer = NULL; initialized = false; maxlen = 0; memset( continuitySamples, 0, sizeof( float ) * 4 ); }; + virtual ~SoundFX() { if ( buffer ) delete buffer; }; + + virtual void Initialize() { }; + virtual void ProcessSample( float* in, float* out ) = 0; + + void SetChannel( int chan ) { channel = chan; }; + int GetChannel() { return channel; }; + + void SetContinuitySamples( float in1, float in2, float out1, float out2 ) { continuitySamples[0] = in1; continuitySamples[1] = in2; continuitySamples[2] = out1; continuitySamples[3] = out2; }; // FIXME? + void GetContinuitySamples( float& in1, float& in2, float& out1, float& out2 ) { in1 = continuitySamples[0]; in2 = continuitySamples[1]; out1 = continuitySamples[2]; out2 = continuitySamples[3]; }; + + void SetParameter( float val ) { param = val; }; +}; + +class SoundFX_Lowpass : public SoundFX { +public: + virtual void ProcessSample( float* in, float* out ); +}; + +class SoundFX_LowpassFast : public SoundFX { + float freq; + float res; + float a1, a2, a3; + float b1, b2; + +public: + virtual void ProcessSample( float* in, float* out ); + void SetParms( float p1 = 0, float p2 = 0, float p3 = 0 ); +}; + +class SoundFX_Comb : public SoundFX { + int currentTime; + +public: + virtual void Initialize(); + virtual void ProcessSample( float* in, float* out ); +}; + +class FracTime { +public: + int time; + float frac; + + void Set( int val ) { time = val; frac = 0; }; + void Increment( float val ) { frac += val; while ( frac >= 1.f ) { time++; frac--; } }; +}; + +enum { + PLAYBACK_RESET, + PLAYBACK_ADVANCING +}; + +class idSoundChannel; + +class idSlowChannel { + bool active; + const idSoundChannel* chan; + + int playbackState; + int triggerOffset; + + FracTime newPosition; + int newSampleOffset; + + FracTime curPosition; + int curSampleOffset; + + SoundFX_LowpassFast lowpass; + + // functions + void GenerateSlowChannel( FracTime& playPos, int sampleCount44k, float* finalBuffer ); + + float GetSlowmoSpeed(); + +public: + + void AttachSoundChannel( const idSoundChannel *chan ); + void Reset(); + + void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ); + + bool IsActive() { return active; }; + FracTime GetCurrentPosition() { return curPosition; }; +}; + +class idSoundChannel { +public: + idSoundChannel( void ); + ~idSoundChannel( void ); + + void Clear( void ); + void Start( void ); + void Stop( void ); + void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) const; + void ALStop( void ); // free OpenAL resources if any + + bool triggerState; + int trigger44kHzTime; // hardware time sample the channel started + int triggerGame44kHzTime; // game time sample time the channel started + soundShaderParms_t parms; // combines the shader parms and the per-channel overrides + idSoundSample * leadinSample; // if not looped, this is the only sample + s_channelType triggerChannel; + const idSoundShader *soundShader; + idSampleDecoder * decoder; + float diversity; + float lastVolume; // last calculated volume based on distance + float lastV[6]; // last calculated volume for each speaker, so we can smoothly fade + idSoundFade channelFade; + bool triggered; + ALuint openalSource; + ALuint openalStreamingOffset; + ALuint openalStreamingBuffer[3]; + ALuint lastopenalStreamingBuffer[3]; + + bool disallowSlow; + +}; + +class idSoundEmitterLocal : public idSoundEmitter { +public: + + idSoundEmitterLocal( void ); + virtual ~idSoundEmitterLocal( void ); + + //---------------------------------------------- + + // the "time" parameters should be game time in msec, which is used to make queries + // return deterministic values regardless of async buffer scheduling + + // a non-immediate free will let all currently playing sounds complete + virtual void Free( bool immediate ); + + // the parms specified will be the default overrides for all sounds started on this emitter. + // NULL is acceptable for parms + virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ); + + // returns the length of the started sound in msec + virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true /* D3XP */ ); + + // can pass SCHANNEL_ANY + virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms ); + virtual void StopSound( const s_channelType channel ); + virtual void FadeSound( const s_channelType channel, float to, float over ); + + virtual bool CurrentlyPlaying( void ) const; + + // can pass SCHANNEL_ANY + virtual float CurrentAmplitude( void ); + + // used for save games + virtual int Index( void ) const; + + //---------------------------------------------- + + void Clear( void ); + + void OverrideParms( const soundShaderParms_t *base, const soundShaderParms_t *over, soundShaderParms_t *out ); + void CheckForCompletion( int current44kHzTime ); + void Spatialize( idVec3 listenerPos, int listenerArea, idRenderWorld *rw ); + + idSoundWorldLocal * soundWorld; // the world that holds this emitter + + int index; // in world emitter list + removeStatus_t removeStatus; + + idVec3 origin; + int listenerId; + soundShaderParms_t parms; // default overrides for all channels + + + // the following are calculated in UpdateEmitter, and don't need to be archived + float maxDistance; // greatest of all playing channel distances + int lastValidPortalArea; // so an emitter that slides out of the world continues playing + bool playing; // if false, no channel is active + bool hasShakes; + idVec3 spatializedOrigin; // the virtual sound origin, either the real sound origin, + // or a point through a portal chain + float realDistance; // in meters + float distance; // in meters, this may be the straight-line distance, or + // it may go through a chain of portals. If there + // is not an open-portal path, distance will be > maxDistance + + // a single soundEmitter can have many channels playing from the same point + idSoundChannel channels[SOUND_MAX_CHANNELS]; + + idSlowChannel slowChannels[SOUND_MAX_CHANNELS]; + + idSlowChannel GetSlowChannel( const idSoundChannel *chan ); + void SetSlowChannel( const idSoundChannel *chan, idSlowChannel slow ); + void ResetSlowChannel( const idSoundChannel *chan ); + + // this is just used for feedback to the game or rendering system: + // flashing lights and screen shakes. Because the material expression + // evaluation doesn't do common subexpression removal, we cache the + // last generated value + int ampTime; + float amplitude; +}; + + +/* +=================================================================================== + +idSoundWorldLocal + +=================================================================================== +*/ + +class s_stats { +public: + s_stats( void ) { + rinuse = 0; + runs = 1; + timeinprocess = 0; + missedWindow = 0; + missedUpdateWindow = 0; + activeSounds = 0; + } + int rinuse; + int runs; + int timeinprocess; + int missedWindow; + int missedUpdateWindow; + int activeSounds; +}; + +typedef struct soundPortalTrace_s { + int portalArea; + const struct soundPortalTrace_s *prevStack; +} soundPortalTrace_t; + +class idSoundWorldLocal : public idSoundWorld { +public: + virtual ~idSoundWorldLocal( void ); + + // call at each map start + virtual void ClearAllSoundEmitters( void ); + virtual void StopAllSounds( void ); + + // get a new emitter that can play sounds in this world + virtual idSoundEmitter *AllocSoundEmitter( void ); + + // for load games + virtual idSoundEmitter *EmitterForIndex( int index ); + + // query data from all emitters in the world + virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listererPosition ); + + // where is the camera/microphone + // listenerId allows listener-private sounds to be added + virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName ); + + // fade all sounds in the world with a given shader soundClass + // to is in Db (sigh), over is in seconds + virtual void FadeSoundClasses( const int soundClass, const float to, const float over ); + + // dumps the current state and begins archiving commands + virtual void StartWritingDemo( idDemoFile *demo ); + virtual void StopWritingDemo( void ); + + // read a sound command from a demo file + virtual void ProcessDemoCommand( idDemoFile *readDemo ); + + // background music + virtual void PlayShaderDirectly( const char *name, int channel = -1 ); + + // pause and unpause the sound world + virtual void Pause( void ); + virtual void UnPause( void ); + virtual bool IsPaused( void ); + + // avidump + virtual void AVIOpen( const char *path, const char *name ); + virtual void AVIClose( void ); + + // SaveGame Support + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + + virtual void ReadFromSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ); + virtual void ReadFromSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ); + virtual void WriteToSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ); + virtual void WriteToSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ); + + virtual void SetSlowmo( bool active ); + virtual void SetSlowmoSpeed( float speed ); + virtual void SetEnviroSuit( bool active ); + + //======================================= + + idSoundWorldLocal( void ); + + void Shutdown( void ); + void Init( idRenderWorld *rw ); + void ClearBuffer( void ); + + // update + void ForegroundUpdate( int currentTime ); + void OffsetSoundTime( int offset44kHz ); + + idSoundEmitterLocal * AllocLocalSoundEmitter(); + void CalcEars( int numSpeakers, idVec3 realOrigin, idVec3 listenerPos, idMat3 listenerAxis, float ears[6], float spatialize ); + void AddChannelContribution( idSoundEmitterLocal *sound, idSoundChannel *chan, + int current44kHz, int numSpeakers, float *finalMixBuffer ); + void MixLoop( int current44kHz, int numSpeakers, float *finalMixBuffer ); + void AVIUpdate( void ); + void ResolveOrigin( const int stackDepth, const soundPortalTrace_t *prevStack, const int soundArea, const float dist, const idVec3& soundOrigin, idSoundEmitterLocal *def ); + float FindAmplitude( idSoundEmitterLocal *sound, const int localTime, const idVec3 *listenerPosition, const s_channelType channel, bool shakesOnly ); + + //============================================ + + idRenderWorld * rw; // for portals and debug drawing + idDemoFile * writeDemo; // if not NULL, archive commands here + + idMat3 listenerAxis; + idVec3 listenerPos; // position in meters + int listenerPrivateId; + idVec3 listenerQU; // position in "quake units" + int listenerArea; + idStr listenerAreaName; + int listenerEnvironmentID; + + int gameMsec; + int game44kHz; + int pause44kHz; + int lastAVI44kHz; // determine when we need to mix and write another block + + idListemitters; + + idSoundFade soundClassFade[SOUND_MAX_CLASSES]; // for global sound fading + + // avi stuff + idFile * fpa[6]; + idStr aviDemoPath; + idStr aviDemoName; + + idSoundEmitterLocal * localSound; // just for playShaderDirectly() + + bool slowmoActive; + float slowmoSpeed; + bool enviroSuitActive; +}; + +/* +=================================================================================== + +idSoundSystemLocal + +=================================================================================== +*/ + +typedef struct { + ALuint handle; + int startTime; + idSoundChannel *chan; + bool inUse; + bool looping; + bool stereo; +} openalSource_t; + +class idSoundSystemLocal : public idSoundSystem { +public: + idSoundSystemLocal( ) { + isInitialized = false; + } + + // all non-hardware initialization + virtual void Init( void ); + + // shutdown routine + virtual void Shutdown( void ); + virtual void ClearBuffer( void ); + + // sound is attached to the window, and must be recreated when the window is changed + virtual bool ShutdownHW( void ); + virtual bool InitHW( void ); + + // async loop, called at 60Hz + virtual int AsyncUpdate( int time ); + // async loop, when the sound driver uses a write strategy + virtual int AsyncUpdateWrite( int time ); + // direct mixing called from the sound driver thread for OSes that support it + virtual int AsyncMix( int soundTime, float *mixBuffer ); + + virtual void SetMute( bool mute ); + + virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ); + + int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo ); + + // if rw == NULL, no portal occlusion or rendered debugging is available + virtual idSoundWorld *AllocSoundWorld( idRenderWorld *rw ); + + // specifying NULL will cause silence to be played + virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld ); + + // some tools, like the sound dialog, may be used in both the game and the editor + // This can return NULL, so check! + virtual idSoundWorld *GetPlayingSoundWorld( void ); + + virtual void BeginLevelLoad( void ); + virtual void EndLevelLoad( const char *mapString ); + + virtual void PrintMemInfo( MemInfo_t *mi ); + + virtual int IsEAXAvailable( void ); + + //------------------------- + + int GetCurrent44kHzTime( void ) const; + float dB2Scale( const float val ) const; + int SamplesToMilliseconds( int samples ) const; + int MillisecondsToSamples( int ms ) const; + + void DoEnviroSuit( float* samples, int numSamples, int numSpeakers ); + + ALuint AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo ); + void FreeOpenALSource( ALuint handle ); + + idAudioHardware * snd_audio_hw; + idSoundCache * soundCache; + + idSoundWorldLocal * currentSoundWorld; // the one to mix each async tic + + int olddwCurrentWritePos; // statistics + int buffers; // statistics + int CurrentSoundTime; // set by the async thread and only used by the main thread + + unsigned int nextWriteBlock; + + float realAccum[6*MIXBUFFER_SAMPLES+16]; + float * finalMixBuffer; // points inside realAccum at a 16 byte aligned boundary + + bool isInitialized; + bool muted; + bool shutdown; + + s_stats soundStats; // NOTE: updated throughout the code, not displayed anywhere + + int meterTops[256]; + int meterTopsTime[256]; + + dword * graph; + + float volumesDB[1200]; // dB to float volume conversion + + idList fxList; + + ALCdevice *openalDevice; + ALCcontext *openalContext; + ALsizei openalSourceCount; + openalSource_t openalSources[256]; + EAXSet alEAXSet; + EAXGet alEAXGet; + EAXSetBufferMode alEAXSetBufferMode; + EAXGetBufferMode alEAXGetBufferMode; + idEFXFile EFXDatabase; + bool efxloaded; + // latches + static bool useOpenAL; + static bool useEAXReverb; + // mark available during initialization, or through an explicit test + static int EAXAvailable; + + + static idCVar s_noSound; + static idCVar s_quadraticFalloff; + static idCVar s_drawSounds; + static idCVar s_minVolume6; + static idCVar s_dotbias6; + static idCVar s_minVolume2; + static idCVar s_dotbias2; + static idCVar s_spatializationDecay; + static idCVar s_showStartSound; + static idCVar s_maxSoundsPerShader; + static idCVar s_reverse; + static idCVar s_showLevelMeter; + static idCVar s_meterTopTime; + static idCVar s_volume; + static idCVar s_constantAmplitude; + static idCVar s_playDefaultSound; + static idCVar s_useOcclusion; + static idCVar s_subFraction; + static idCVar s_globalFraction; + static idCVar s_doorDistanceAdd; + static idCVar s_singleEmitter; + static idCVar s_numberOfSpeakers; + static idCVar s_force22kHz; + static idCVar s_clipVolumes; + static idCVar s_realTimeDecoding; + static idCVar s_libOpenAL; + static idCVar s_useOpenAL; + static idCVar s_useEAXReverb; + static idCVar s_muteEAXReverb; + static idCVar s_decompressionLimit; + + static idCVar s_slowAttenuate; + + static idCVar s_enviroSuitCutoffFreq; + static idCVar s_enviroSuitCutoffQ; + static idCVar s_enviroSuitSkipLowpass; + static idCVar s_enviroSuitSkipReverb; + + static idCVar s_reverbTime; + static idCVar s_reverbFeedback; + static idCVar s_enviroSuitVolumeScale; + static idCVar s_skipHelltimeFX; +}; + +extern idSoundSystemLocal soundSystemLocal; + + +/* +=================================================================================== + + This class holds the actual wavefile bitmap, size, and info. + +=================================================================================== +*/ + +const int SCACHE_SIZE = MIXBUFFER_SAMPLES*20; // 1/2 of a second (aroundabout) + +class idSoundSample { +public: + idSoundSample(); + ~idSoundSample(); + + idStr name; // name of the sample file + ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command + + waveformatex_t objectInfo; // what are we caching + int objectSize; // size of waveform in samples, excludes the header + int objectMemSize; // object size in memory + byte * nonCacheData; // if it's not cached + byte * amplitudeData; // precomputed min,max amplitude pairs + ALuint openalBuffer; // openal buffer + bool hardwareBuffer; + bool defaultSound; + bool onDemand; + bool purged; + bool levelLoadReferenced; // so we can tell which samples aren't needed any more + + int LengthIn44kHzSamples() const; + ID_TIME_T GetNewTimeStamp( void ) const; + void MakeDefault(); // turns it into a beep + void Load(); // loads the current sound based on name + void Reload( bool force ); // reloads if timestamp has changed, or always if force + void PurgeSoundSample(); // frees all data + void CheckForDownSample(); // down sample if required + bool FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO ); +}; + + +/* +=================================================================================== + + Sound sample decoder. + +=================================================================================== +*/ + +class idSampleDecoder { +public: + static void Init( void ); + static void Shutdown( void ); + static idSampleDecoder *Alloc( void ); + static void Free( idSampleDecoder *decoder ); + static int GetNumUsedBlocks( void ); + static int GetUsedBlockMemory( void ); + + virtual ~idSampleDecoder( void ) {} + virtual void Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) = 0; + virtual void ClearDecoder( void ) = 0; + virtual idSoundSample * GetSample( void ) const = 0; + virtual int GetLastDecodeTime( void ) const = 0; +}; + + +/* +=================================================================================== + + The actual sound cache. + +=================================================================================== +*/ + +class idSoundCache { +public: + idSoundCache(); + ~idSoundCache(); + + idSoundSample * FindSound( const idStr &fname, bool loadOnDemandOnly ); + + const int GetNumObjects( void ) { return listCache.Num(); } + const idSoundSample * GetObject( const int index ) const; + + void ReloadSounds( bool force ); + + void BeginLevelLoad(); + void EndLevelLoad(); + + void PrintMemInfo( MemInfo_t *mi ); + +private: + bool insideLevelLoad; + idList listCache; +}; + +#endif /* !__SND_LOCAL_H__ */ diff --git a/sound/snd_shader.cpp b/sound/snd_shader.cpp new file mode 100644 index 000000000..67e9bf535 --- /dev/null +++ b/sound/snd_shader.cpp @@ -0,0 +1,501 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + + +/* +=============== +idSoundShader::Init +=============== +*/ +void idSoundShader::Init( void ) { + desc = ""; + errorDuringParse = false; + onDemand = false; + numEntries = 0; + numLeadins = 0; + leadinVolume = 0; + altSound = NULL; +} + +/* +=============== +idSoundShader::idSoundShader +=============== +*/ +idSoundShader::idSoundShader( void ) { + Init(); +} + +/* +=============== +idSoundShader::~idSoundShader +=============== +*/ +idSoundShader::~idSoundShader( void ) { +} + +/* +================= +idSoundShader::Size +================= +*/ +size_t idSoundShader::Size( void ) const { + return sizeof( idSoundShader ); +} + +/* +=============== +idSoundShader::idSoundShader::FreeData +=============== +*/ +void idSoundShader::FreeData() { + numEntries = 0; + numLeadins = 0; +} + +/* +=================== +idSoundShader::SetDefaultText +=================== +*/ +bool idSoundShader::SetDefaultText( void ) { + idStr wavname; + + wavname = GetName(); + wavname.DefaultFileExtension( ".wav" ); // if the name has .ogg in it, that will stay + + // if there exists a wav file with the same name + if ( 1 ) { //fileSystem->ReadFile( wavname, NULL ) != -1 ) { + char generated[2048]; + idStr::snPrintf( generated, sizeof( generated ), + "sound %s // IMPLICITLY GENERATED\n" + "{\n" + "%s\n" + "}\n", GetName(), wavname.c_str() ); + SetText( generated ); + return true; + } else { + return false; + } +} + +/* +=================== +DefaultDefinition +=================== +*/ +const char *idSoundShader::DefaultDefinition() const { + return + "{\n" + "\t" "_default.wav\n" + "}"; +} + +/* +=============== +idSoundShader::Parse + + this is called by the declManager +=============== +*/ +bool idSoundShader::Parse( const char *text, const int textLength ) { + idLexer src; + + src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + // deeper functions can set this, which will cause MakeDefault() to be called at the end + errorDuringParse = false; + + if ( !ParseShader( src ) || errorDuringParse ) { + MakeDefault(); + return false; + } + return true; +} + +/* +=============== +idSoundShader::ParseShader +=============== +*/ +bool idSoundShader::ParseShader( idLexer &src ) { + int i; + idToken token; + + parms.minDistance = 1; + parms.maxDistance = 10; + parms.volume = 1; + parms.shakes = 0; + parms.soundShaderFlags = 0; + parms.soundClass = 0; + + speakerMask = 0; + altSound = NULL; + + for( i = 0; i < SOUND_MAX_LIST_WAVS; i++ ) { + leadins[i] = NULL; + entries[i] = NULL; + } + numEntries = 0; + numLeadins = 0; + + int maxSamples = idSoundSystemLocal::s_maxSoundsPerShader.GetInteger(); + if ( com_makingBuild.GetBool() || maxSamples <= 0 || maxSamples > SOUND_MAX_LIST_WAVS ) { + maxSamples = SOUND_MAX_LIST_WAVS; + } + + while ( 1 ) { + if ( !src.ExpectAnyToken( &token ) ) { + return false; + } + // end of definition + else if ( token == "}" ) { + break; + } + // minimum number of sounds + else if ( !token.Icmp( "minSamples" ) ) { + maxSamples = idMath::ClampInt( src.ParseInt(), SOUND_MAX_LIST_WAVS, maxSamples ); + } + // description + else if ( !token.Icmp( "description" ) ) { + src.ReadTokenOnLine( &token ); + desc = token.c_str(); + } + // mindistance + else if ( !token.Icmp( "mindistance" ) ) { + parms.minDistance = src.ParseFloat(); + } + // maxdistance + else if ( !token.Icmp( "maxdistance" ) ) { + parms.maxDistance = src.ParseFloat(); + } + // shakes screen + else if ( !token.Icmp( "shakes" ) ) { + src.ExpectAnyToken( &token ); + if ( token.type == TT_NUMBER ) { + parms.shakes = token.GetFloatValue(); + } else { + src.UnreadToken( &token ); + parms.shakes = 1.0f; + } + } + // reverb + else if ( !token.Icmp( "reverb" ) ) { + int reg0 = src.ParseFloat(); + if ( !src.ExpectTokenString( "," ) ) { + src.FreeSource(); + return false; + } + int reg1 = src.ParseFloat(); + // no longer supported + } + // volume + else if ( !token.Icmp( "volume" ) ) { + parms.volume = src.ParseFloat(); + } + // leadinVolume is used to allow light breaking leadin sounds to be much louder than the broken loop + else if ( !token.Icmp( "leadinVolume" ) ) { + leadinVolume = src.ParseFloat(); + } + // speaker mask + else if ( !token.Icmp( "mask_center" ) ) { + speakerMask |= 1<= SOUND_MAX_CLASSES ) { + src.Warning( "SoundClass out of range" ); + return false; + } + } + // altSound + else if ( !token.Icmp( "altSound" ) ) { + if ( !src.ExpectAnyToken( &token ) ) { + return false; + } + altSound = declManager->FindSound( token.c_str() ); + } + // ordered + else if ( !token.Icmp( "ordered" ) ) { + // no longer supported + } + // no_dups + else if ( !token.Icmp( "no_dups" ) ) { + parms.soundShaderFlags |= SSF_NO_DUPS; + } + // no_flicker + else if ( !token.Icmp( "no_flicker" ) ) { + parms.soundShaderFlags |= SSF_NO_FLICKER; + } + // plain + else if ( !token.Icmp( "plain" ) ) { + // no longer supported + } + // looping + else if ( !token.Icmp( "looping" ) ) { + parms.soundShaderFlags |= SSF_LOOPING; + } + // no occlusion + else if ( !token.Icmp( "no_occlusion" ) ) { + parms.soundShaderFlags |= SSF_NO_OCCLUSION; + } + // private + else if ( !token.Icmp( "private" ) ) { + parms.soundShaderFlags |= SSF_PRIVATE_SOUND; + } + // antiPrivate + else if ( !token.Icmp( "antiPrivate" ) ) { + parms.soundShaderFlags |= SSF_ANTI_PRIVATE_SOUND; + } + // once + else if ( !token.Icmp( "playonce" ) ) { + parms.soundShaderFlags |= SSF_PLAY_ONCE; + } + // global + else if ( !token.Icmp( "global" ) ) { + parms.soundShaderFlags |= SSF_GLOBAL; + } + // unclamped + else if ( !token.Icmp( "unclamped" ) ) { + parms.soundShaderFlags |= SSF_UNCLAMPED; + } + // omnidirectional + else if ( !token.Icmp( "omnidirectional" ) ) { + parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL; + } + // onDemand can't be a parms, because we must track all references and overrides would confuse it + else if ( !token.Icmp( "onDemand" ) ) { + // no longer loading sounds on demand + //onDemand = true; + } + + // the wave files + else if ( !token.Icmp( "leadin" ) ) { + // add to the leadin list + if ( !src.ReadToken( &token ) ) { + src.Warning( "Expected sound after leadin" ); + return false; + } + if ( soundSystemLocal.soundCache && numLeadins < maxSamples ) { + leadins[ numLeadins ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand ); + numLeadins++; + } + } else if ( token.Find( ".wav", false ) != -1 || token.Find( ".ogg", false ) != -1 ) { + // add to the wav list + if ( soundSystemLocal.soundCache && numEntries < maxSamples ) { + token.BackSlashesToSlashes(); + idStr lang = cvarSystem->GetCVarString( "sys_lang" ); + if ( lang.Icmp( "english" ) != 0 && token.Find( "sound/vo/", false ) >= 0 ) { + idStr work = token; + work.ToLower(); + work.StripLeading( "sound/vo/" ); + work = va( "sound/vo/%s/%s", lang.c_str(), work.c_str() ); + if ( fileSystem->ReadFile( work, NULL, NULL ) > 0 ) { + token = work; + } else { + // also try to find it with the .ogg extension + work.SetFileExtension( ".ogg" ); + if ( fileSystem->ReadFile( work, NULL, NULL ) > 0 ) { + token = work; + } + } + } + entries[ numEntries ] = soundSystemLocal.soundCache->FindSound( token.c_str(), onDemand ); + numEntries++; + } + } else { + src.Warning( "unknown token '%s'", token.c_str() ); + return false; + } + } + + if ( parms.shakes > 0.0f ) { + CheckShakesAndOgg(); + } + + return true; +} + +/* +=============== +idSoundShader::CheckShakesAndOgg +=============== +*/ +bool idSoundShader::CheckShakesAndOgg( void ) const { + int i; + bool ret = false; + + for ( i = 0; i < numLeadins; i++ ) { + if ( leadins[ i ]->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) { + common->Warning( "sound shader '%s' has shakes and uses OGG file '%s'", + GetName(), leadins[ i ]->name.c_str() ); + ret = true; + } + } + for ( i = 0; i < numEntries; i++ ) { + if ( entries[ i ]->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) { + common->Warning( "sound shader '%s' has shakes and uses OGG file '%s'", + GetName(), entries[ i ]->name.c_str() ); + ret = true; + } + } + return ret; +} + +/* +=============== +idSoundShader::List +=============== +*/ +void idSoundShader::List() const { + idStrList shaders; + + common->Printf( "%4i: %s\n", Index(), GetName() ); + if ( idStr::Icmp( GetDescription(), "" ) != 0 ) { + common->Printf( " description: %s\n", GetDescription() ); + } + for( int k = 0; k < numLeadins ; k++ ) { + const idSoundSample *objectp = leadins[k]; + if ( objectp ) { + common->Printf( " %5dms %4dKb %s (LEADIN)\n", soundSystemLocal.SamplesToMilliseconds(objectp->LengthIn44kHzSamples()), (objectp->objectMemSize/1024) + ,objectp->name.c_str() ); + } + } + for( int k = 0; k < numEntries; k++ ) { + const idSoundSample *objectp = entries[k]; + if ( objectp ) { + common->Printf( " %5dms %4dKb %s\n", soundSystemLocal.SamplesToMilliseconds(objectp->LengthIn44kHzSamples()), (objectp->objectMemSize/1024) + ,objectp->name.c_str() ); + } + } +} + +/* +=============== +idSoundShader::GetAltSound +=============== +*/ +const idSoundShader *idSoundShader::GetAltSound( void ) const { + return altSound; +} + +/* +=============== +idSoundShader::GetMinDistance +=============== +*/ +float idSoundShader::GetMinDistance() const { + return parms.minDistance; +} + +/* +=============== +idSoundShader::GetMaxDistance +=============== +*/ +float idSoundShader::GetMaxDistance() const { + return parms.maxDistance; +} + +/* +=============== +idSoundShader::GetDescription +=============== +*/ +const char *idSoundShader::GetDescription() const { + return desc; +} + +/* +=============== +idSoundShader::HasDefaultSound +=============== +*/ +bool idSoundShader::HasDefaultSound() const { + for ( int i = 0; i < numEntries; i++ ) { + if ( entries[i] && entries[i]->defaultSound ) { + return true; + } + } + return false; +} + +/* +=============== +idSoundShader::GetParms +=============== +*/ +const soundShaderParms_t *idSoundShader::GetParms() const { + return &parms; +} + +/* +=============== +idSoundShader::GetNumSounds +=============== +*/ +int idSoundShader::GetNumSounds() const { + return numLeadins + numEntries; +} + +/* +=============== +idSoundShader::GetSound +=============== +*/ +const char *idSoundShader::GetSound( int index ) const { + if ( index >= 0 ) { + if ( index < numLeadins ) { + return leadins[index]->name.c_str(); + } + index -= numLeadins; + if ( index < numEntries ) { + return entries[index]->name.c_str(); + } + } + return ""; +} diff --git a/sound/snd_system.cpp b/sound/snd_system.cpp new file mode 100644 index 000000000..c3f914b11 --- /dev/null +++ b/sound/snd_system.cpp @@ -0,0 +1,1452 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + +#ifdef ID_DEDICATED +idCVar idSoundSystemLocal::s_noSound( "s_noSound", "1", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "" ); +#else +idCVar idSoundSystemLocal::s_noSound( "s_noSound", "0", CVAR_SOUND | CVAR_BOOL | CVAR_NOCHEAT, "" ); +#endif +idCVar idSoundSystemLocal::s_quadraticFalloff( "s_quadraticFalloff", "1", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_drawSounds( "s_drawSounds", "0", CVAR_SOUND | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar idSoundSystemLocal::s_showStartSound( "s_showStartSound", "0", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_useOcclusion( "s_useOcclusion", "1", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_maxSoundsPerShader( "s_maxSoundsPerShader", "0", CVAR_SOUND | CVAR_ARCHIVE, "", 0, 10, idCmdSystem::ArgCompletion_Integer<0,10> ); +idCVar idSoundSystemLocal::s_showLevelMeter( "s_showLevelMeter", "0", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_constantAmplitude( "s_constantAmplitude", "-1", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_minVolume6( "s_minVolume6", "0", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_dotbias6( "s_dotbias6", "0.8", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_minVolume2( "s_minVolume2", "0.25", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_dotbias2( "s_dotbias2", "1.1", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_spatializationDecay( "s_spatializationDecay", "2", CVAR_SOUND | CVAR_ARCHIVE | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_reverse( "s_reverse", "0", CVAR_SOUND | CVAR_ARCHIVE | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_meterTopTime( "s_meterTopTime", "2000", CVAR_SOUND | CVAR_ARCHIVE | CVAR_INTEGER, "" ); +idCVar idSoundSystemLocal::s_volume( "s_volume_dB", "0", CVAR_SOUND | CVAR_ARCHIVE | CVAR_FLOAT, "volume in dB" ); +idCVar idSoundSystemLocal::s_playDefaultSound( "s_playDefaultSound", "1", CVAR_SOUND | CVAR_ARCHIVE | CVAR_BOOL, "play a beep for missing sounds" ); +idCVar idSoundSystemLocal::s_subFraction( "s_subFraction", "0.75", CVAR_SOUND | CVAR_ARCHIVE | CVAR_FLOAT, "volume to subwoofer in 5.1" ); +idCVar idSoundSystemLocal::s_globalFraction( "s_globalFraction", "0.8", CVAR_SOUND | CVAR_ARCHIVE | CVAR_FLOAT, "volume to all speakers when not spatialized" ); +idCVar idSoundSystemLocal::s_doorDistanceAdd( "s_doorDistanceAdd", "150", CVAR_SOUND | CVAR_ARCHIVE | CVAR_FLOAT, "reduce sound volume with this distance when going through a door" ); +idCVar idSoundSystemLocal::s_singleEmitter( "s_singleEmitter", "0", CVAR_SOUND | CVAR_INTEGER, "mute all sounds but this emitter" ); +idCVar idSoundSystemLocal::s_numberOfSpeakers( "s_numberOfSpeakers", "2", CVAR_SOUND | CVAR_ARCHIVE, "number of speakers" ); +idCVar idSoundSystemLocal::s_force22kHz( "s_force22kHz", "0", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_clipVolumes( "s_clipVolumes", "1", CVAR_SOUND | CVAR_BOOL, "" ); +idCVar idSoundSystemLocal::s_realTimeDecoding( "s_realTimeDecoding", "1", CVAR_SOUND | CVAR_BOOL | CVAR_INIT, "" ); + +idCVar idSoundSystemLocal::s_slowAttenuate( "s_slowAttenuate", "1", CVAR_SOUND | CVAR_BOOL, "slowmo sounds attenuate over shorted distance" ); +idCVar idSoundSystemLocal::s_enviroSuitCutoffFreq( "s_enviroSuitCutoffFreq", "2000", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_enviroSuitCutoffQ( "s_enviroSuitCutoffQ", "2", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_reverbTime( "s_reverbTime", "1000", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_reverbFeedback( "s_reverbFeedback", "0.333", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_enviroSuitVolumeScale( "s_enviroSuitVolumeScale", "0.9", CVAR_SOUND | CVAR_FLOAT, "" ); +idCVar idSoundSystemLocal::s_skipHelltimeFX( "s_skipHelltimeFX", "0", CVAR_SOUND | CVAR_BOOL, "" ); + +#if ID_OPENAL +// off by default. OpenAL DLL gets loaded on-demand +idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL DLL name/path" ); +idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use OpenAL" ); +idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use EAX reverb" ); +idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL, "mute eax reverb" ); +idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ARCHIVE, "specifies maximum uncompressed sample length in seconds" ); +#else +idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL is not supported in this build" ); +idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "OpenAL is not supported in this build" ); +idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "EAX not available in this build" ); +idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "mute eax reverb" ); +idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ROM, "specifies maximum uncompressed sample length in seconds" ); +#endif + +bool idSoundSystemLocal::useOpenAL = false; +bool idSoundSystemLocal::useEAXReverb = false; +int idSoundSystemLocal::EAXAvailable = -1; + +idSoundSystemLocal soundSystemLocal; +idSoundSystem *soundSystem = &soundSystemLocal; + +/* +=============== +SoundReloadSounds_f + + this is called from the main thread +=============== +*/ +void SoundReloadSounds_f( const idCmdArgs &args ) { + if ( !soundSystemLocal.soundCache ) { + return; + } + bool force = false; + if ( args.Argc() == 2 ) { + force = true; + } + soundSystem->SetMute( true ); + soundSystemLocal.soundCache->ReloadSounds( force ); + soundSystem->SetMute( false ); + common->Printf( "sound: changed sounds reloaded\n" ); +} + +/* +=============== +ListSounds_f + +Optional parameter to only list sounds containing that string +=============== +*/ +void ListSounds_f( const idCmdArgs &args ) { + int i; + const char *snd = args.Argv( 1 ); + + if ( !soundSystemLocal.soundCache ) { + common->Printf( "No sound.\n" ); + return; + } + + int totalSounds = 0; + int totalSamples = 0; + int totalMemory = 0; + int totalPCMMemory = 0; + for( i = 0; i < soundSystemLocal.soundCache->GetNumObjects(); i++ ) { + const idSoundSample *sample = soundSystemLocal.soundCache->GetObject(i); + if ( !sample ) { + continue; + } + if ( snd && sample->name.Find( snd, false ) < 0 ) { + continue; + } + + const waveformatex_t &info = sample->objectInfo; + + const char *stereo = ( info.nChannels == 2 ? "ST" : " " ); + const char *format = ( info.wFormatTag == WAVE_FORMAT_TAG_OGG ) ? "OGG" : "WAV"; + const char *defaulted = ( sample->defaultSound ? "(DEFAULTED)" : sample->purged ? "(PURGED)" : "" ); + + common->Printf( "%s %dkHz %6dms %5dkB %4s %s%s\n", stereo, sample->objectInfo.nSamplesPerSec / 1000, + soundSystemLocal.SamplesToMilliseconds( sample->LengthIn44kHzSamples() ), + sample->objectMemSize >> 10, format, sample->name.c_str(), defaulted ); + + if ( !sample->purged ) { + totalSamples += sample->objectSize; + if ( info.wFormatTag != WAVE_FORMAT_TAG_OGG ) + totalPCMMemory += sample->objectMemSize; + if ( !sample->hardwareBuffer ) + totalMemory += sample->objectMemSize; + } + totalSounds++; + } + common->Printf( "%8d total sounds\n", totalSounds ); + common->Printf( "%8d total samples loaded\n", totalSamples ); + common->Printf( "%8d kB total system memory used\n", totalMemory >> 10 ); +#if ID_OPENAL + common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( (ALubyte*)"AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( (ALubyte*)"AL_EAX_RAM_FREE" ) ) ) >> 10 ); +#endif +} + +/* +=============== +ListSoundDecoders_f +=============== +*/ +void ListSoundDecoders_f( const idCmdArgs &args ) { + int i, j, numActiveDecoders, numWaitingDecoders; + idSoundWorldLocal *sw = soundSystemLocal.currentSoundWorld; + + numActiveDecoders = numWaitingDecoders = 0; + + for ( i = 0; i < sw->emitters.Num(); i++ ) { + idSoundEmitterLocal *sound = sw->emitters[i]; + + if ( !sound ) { + continue; + } + + // run through all the channels + for ( j = 0; j < SOUND_MAX_CHANNELS; j++ ) { + idSoundChannel *chan = &sound->channels[j]; + + if ( chan->decoder == NULL ) { + continue; + } + + idSoundSample *sample = chan->decoder->GetSample(); + + if ( sample != NULL ) { + continue; + } + + const char *format = ( chan->leadinSample->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) ? "OGG" : "WAV"; + common->Printf( "%3d waiting %s: %s\n", numWaitingDecoders, format, chan->leadinSample->name.c_str() ); + + numWaitingDecoders++; + } + } + + for ( i = 0; i < sw->emitters.Num(); i++ ) { + idSoundEmitterLocal *sound = sw->emitters[i]; + + if ( !sound ) { + continue; + } + + // run through all the channels + for ( j = 0; j < SOUND_MAX_CHANNELS; j++ ) { + idSoundChannel *chan = &sound->channels[j]; + + if ( chan->decoder == NULL ) { + continue; + } + + idSoundSample *sample = chan->decoder->GetSample(); + + if ( sample == NULL ) { + continue; + } + + const char *format = ( sample->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) ? "OGG" : "WAV"; + + int localTime = soundSystemLocal.GetCurrent44kHzTime() - chan->trigger44kHzTime; + int sampleTime = sample->LengthIn44kHzSamples() * sample->objectInfo.nChannels; + int percent; + if ( localTime > sampleTime ) { + if ( chan->parms.soundShaderFlags & SSF_LOOPING ) { + percent = ( localTime % sampleTime ) * 100 / sampleTime; + } else { + percent = 100; + } + } else { + percent = localTime * 100 / sampleTime; + } + + common->Printf( "%3d decoding %3d%% %s: %s\n", numActiveDecoders, percent, format, sample->name.c_str() ); + + numActiveDecoders++; + } + } + + common->Printf( "%d decoders\n", numWaitingDecoders + numActiveDecoders ); + common->Printf( "%d waiting decoders\n", numWaitingDecoders ); + common->Printf( "%d active decoders\n", numActiveDecoders ); + common->Printf( "%d kB decoder memory in %d blocks\n", idSampleDecoder::GetUsedBlockMemory() >> 10, idSampleDecoder::GetNumUsedBlocks() ); +} + +/* +=============== +TestSound_f + + this is called from the main thread +=============== +*/ +void TestSound_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Printf( "Usage: testSound \n" ); + return; + } + if ( soundSystemLocal.currentSoundWorld ) { + soundSystemLocal.currentSoundWorld->PlayShaderDirectly( args.Argv( 1 ) ); + } +} + +/* +=============== +SoundSystemRestart_f + +restart the sound thread + + this is called from the main thread +=============== +*/ +void SoundSystemRestart_f( const idCmdArgs &args ) { + soundSystem->SetMute( true ); + soundSystemLocal.ShutdownHW(); + soundSystemLocal.InitHW(); + soundSystem->SetMute( false ); +} + +/* +=============== +idSoundSystemLocal::Init + +initialize the sound system +=============== +*/ +void idSoundSystemLocal::Init() { + + common->Printf( "----- Initializing Sound System ------\n" ); + + isInitialized = false; + muted = false; + shutdown = false; + + currentSoundWorld = NULL; + soundCache = NULL; + + olddwCurrentWritePos = 0; + buffers = 0; + CurrentSoundTime = 0; + + nextWriteBlock = 0xffffffff; + + memset( meterTops, 0, sizeof( meterTops ) ); + memset( meterTopsTime, 0, sizeof( meterTopsTime ) ); + + for( int i = -600; i < 600; i++ ) { + float pt = i * 0.1f; + volumesDB[i+600] = pow( 2.0f,( pt * ( 1.0f / 6.0f ) ) ); + } + + // make a 16 byte aligned finalMixBuffer + finalMixBuffer = (float *) ( ( ( (int)realAccum ) + 15 ) & ~15 ); + + graph = NULL; + + if ( !s_noSound.GetBool() ) { + idSampleDecoder::Init(); + soundCache = new idSoundCache(); + } + + // set up openal device and context + common->StartupVariable( "s_useOpenAL", true ); + common->StartupVariable( "s_useEAXReverb", true ); + + if ( idSoundSystemLocal::s_useOpenAL.GetBool() || idSoundSystemLocal::s_useEAXReverb.GetBool() ) { + if ( !Sys_LoadOpenAL() ) { + idSoundSystemLocal::s_useOpenAL.SetBool( false ); + } else { + common->Printf( "Setup OpenAL device and context... " ); + openalDevice = alcOpenDevice( NULL ); + openalContext = alcCreateContext( openalDevice, NULL ); + alcMakeContextCurrent( openalContext ); + common->Printf( "Done.\n" ); + + // try to obtain EAX extensions + if ( idSoundSystemLocal::s_useEAXReverb.GetBool() && alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) { + idSoundSystemLocal::s_useOpenAL.SetBool( true ); // EAX presence causes AL enable + alEAXSet = (EAXSet)alGetProcAddress( ID_ALCHAR "EAXSet" ); + alEAXGet = (EAXGet)alGetProcAddress( ID_ALCHAR "EAXGet" ); + common->Printf( "OpenAL: found EAX 4.0 extension\n" ); + } else { + common->Printf( "OpenAL: EAX 4.0 extension not found\n" ); + idSoundSystemLocal::s_useEAXReverb.SetBool( false ); + alEAXSet = (EAXSet)NULL; + alEAXGet = (EAXGet)NULL; + } + + // try to obtain EAX-RAM extension - not required for operation + if ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) { + alEAXSetBufferMode = (EAXSetBufferMode)alGetProcAddress( ID_ALCHAR "EAXSetBufferMode" ); + alEAXGetBufferMode = (EAXGetBufferMode)alGetProcAddress( ID_ALCHAR "EAXGetBufferMode" ); + common->Printf( "OpenAL: found EAX-RAM extension, %dkB\\%dkB\n", alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_FREE" ) ) / 1024, alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_SIZE" ) ) / 1024 ); + } else { + alEAXSetBufferMode = (EAXSetBufferMode)NULL; + alEAXGetBufferMode = (EAXGetBufferMode)NULL; + common->Printf( "OpenAL: no EAX-RAM extension\n" ); + } + + if ( !idSoundSystemLocal::s_useOpenAL.GetBool() ) { + common->Printf( "OpenAL: disabling ( no EAX ). Using legacy mixer.\n" ); + + alcMakeContextCurrent( NULL ); + + alcDestroyContext( openalContext ); + openalContext = NULL; + + alcCloseDevice( openalDevice ); + openalDevice = NULL; + } else { + + ALuint handle; + openalSourceCount = 0; + + while ( openalSourceCount < 256 ) { + alGetError(); + alGenSources( 1, &handle ); + if ( alGetError() != AL_NO_ERROR ) { + break; + } else { + // store in source array + openalSources[openalSourceCount].handle = handle; + openalSources[openalSourceCount].startTime = 0; + openalSources[openalSourceCount].chan = NULL; + openalSources[openalSourceCount].inUse = false; + openalSources[openalSourceCount].looping = false; + + // initialise sources + alSourcef( handle, AL_ROLLOFF_FACTOR, 0.0f ); + + // found one source + openalSourceCount++; + } + } + + common->Printf( "OpenAL: found %s\n", alcGetString( openalDevice, ALC_DEVICE_SPECIFIER ) ); + common->Printf( "OpenAL: found %d hardware voices\n", openalSourceCount ); + + // adjust source count to allow for at least eight stereo sounds to play + openalSourceCount -= 8; + + EAXAvailable = 1; + } + } + } + + useOpenAL = idSoundSystemLocal::s_useOpenAL.GetBool(); + useEAXReverb = idSoundSystemLocal::s_useEAXReverb.GetBool(); + + cmdSystem->AddCommand( "listSounds", ListSounds_f, CMD_FL_SOUND, "lists all sounds" ); + cmdSystem->AddCommand( "listSoundDecoders", ListSoundDecoders_f, CMD_FL_SOUND, "list active sound decoders" ); + cmdSystem->AddCommand( "reloadSounds", SoundReloadSounds_f, CMD_FL_SOUND|CMD_FL_CHEAT, "reloads all sounds" ); + cmdSystem->AddCommand( "testSound", TestSound_f, CMD_FL_SOUND | CMD_FL_CHEAT, "tests a sound", idCmdSystem::ArgCompletion_SoundName ); + cmdSystem->AddCommand( "s_restart", SoundSystemRestart_f, CMD_FL_SOUND, "restarts the sound system" ); + + common->Printf( "sound system initialized.\n" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +=============== +idSoundSystemLocal::Shutdown +=============== +*/ +void idSoundSystemLocal::Shutdown() { + ShutdownHW(); + + // EAX or not, the list needs to be cleared + EFXDatabase.Clear(); + + // destroy openal sources + if ( useOpenAL ) { + + efxloaded = false; + + // adjust source count back up to allow for freeing of all resources + openalSourceCount += 8; + + for ( ALsizei i = 0; i < openalSourceCount; i++ ) { + // stop source + alSourceStop( openalSources[i].handle ); + alSourcei( openalSources[i].handle, AL_BUFFER, 0 ); + + // delete source + alDeleteSources( 1, &openalSources[i].handle ); + + // clear entry in source array + openalSources[i].handle = NULL; + openalSources[i].startTime = 0; + openalSources[i].chan = NULL; + openalSources[i].inUse = false; + openalSources[i].looping = false; + + } + } + + // destroy all the sounds (hardware buffers as well) + delete soundCache; + soundCache = NULL; + + // destroy openal device and context + if ( useOpenAL ) { + alcMakeContextCurrent( NULL ); + + alcDestroyContext( openalContext ); + openalContext = NULL; + + alcCloseDevice( openalDevice ); + openalDevice = NULL; + } + + Sys_FreeOpenAL(); + + idSampleDecoder::Shutdown(); +} + +/* +=============== +idSoundSystemLocal::InitHW +=============== +*/ +bool idSoundSystemLocal::InitHW() { + + if ( s_noSound.GetBool() ) { + return false; + } + + delete snd_audio_hw; + snd_audio_hw = idAudioHardware::Alloc(); + + if ( snd_audio_hw == NULL ) { + return false; + } + + if ( !useOpenAL ) { + if ( !snd_audio_hw->Initialize() ) { + delete snd_audio_hw; + snd_audio_hw = NULL; + return false; + } + + if ( snd_audio_hw->GetNumberOfSpeakers() == 0 ) { + return false; + } + // put the real number in there + s_numberOfSpeakers.SetInteger( snd_audio_hw->GetNumberOfSpeakers() ); + } + + isInitialized = true; + shutdown = false; + + return true; +} + +/* +=============== +idSoundSystemLocal::ShutdownHW +=============== +*/ +bool idSoundSystemLocal::ShutdownHW() { + if ( !isInitialized ) { + return false; + } + + shutdown = true; // don't do anything at AsyncUpdate() time + Sys_Sleep( 100 ); // sleep long enough to make sure any async sound talking to hardware has returned + + common->Printf( "Shutting down sound hardware\n" ); + + delete snd_audio_hw; + snd_audio_hw = NULL; + + isInitialized = false; + + if ( graph ) { + Mem_Free( graph ); + graph = NULL; + } + + return true; +} + +/* +=============== +idSoundSystemLocal::GetCurrent44kHzTime +=============== +*/ +int idSoundSystemLocal::GetCurrent44kHzTime( void ) const { + if ( snd_audio_hw ) { + return CurrentSoundTime; + } else { + // NOTE: this would overflow 31bits within about 1h20 ( not that important since we get a snd_audio_hw right away pbly ) + //return ( ( Sys_Milliseconds()*441 ) / 10 ) * 4; + return idMath::FtoiFast( (float)Sys_Milliseconds() * 176.4f ); + } +} + +/* +=================== +idSoundSystemLocal::ClearBuffer +=================== +*/ +void idSoundSystemLocal::ClearBuffer( void ) { + + // check to make sure hardware actually exists + if ( !snd_audio_hw ) { + return; + } + + short *fBlock; + ulong fBlockLen; + + if ( !snd_audio_hw->Lock( (void **)&fBlock, &fBlockLen ) ) { + return; + } + + if ( fBlock ) { + SIMDProcessor->Memset( fBlock, 0, fBlockLen ); + snd_audio_hw->Unlock( fBlock, fBlockLen ); + } +} + +/* +=================== +idSoundSystemLocal::AsyncMix +Mac OSX version. The system uses it's own thread and an IOProc callback +=================== +*/ +int idSoundSystemLocal::AsyncMix( int soundTime, float *mixBuffer ) { + int inTime, numSpeakers; + + if ( !isInitialized || shutdown || !snd_audio_hw ) { + return 0; + } + + inTime = Sys_Milliseconds(); + numSpeakers = snd_audio_hw->GetNumberOfSpeakers(); + + // let the active sound world mix all the channels in unless muted or avi demo recording + if ( !muted && currentSoundWorld && !currentSoundWorld->fpa[0] ) { + currentSoundWorld->MixLoop( soundTime, numSpeakers, mixBuffer ); + } + + CurrentSoundTime = soundTime; + + return Sys_Milliseconds() - inTime; +} + +/* +=================== +idSoundSystemLocal::AsyncUpdate +called from async sound thread when com_asyncSound == 1 ( Windows ) +=================== +*/ +int idSoundSystemLocal::AsyncUpdate( int inTime ) { + + if ( !isInitialized || shutdown || !snd_audio_hw ) { + return 0; + } + + ulong dwCurrentWritePos; + dword dwCurrentBlock; + + // If not using openal, get actual playback position from sound hardware + if ( useOpenAL ) { + // here we do it in samples ( overflows in 27 hours or so ) + dwCurrentWritePos = idMath::Ftol( (float)Sys_Milliseconds() * 44.1f ) % ( MIXBUFFER_SAMPLES * ROOM_SLICES_IN_BUFFER ); + dwCurrentBlock = dwCurrentWritePos / MIXBUFFER_SAMPLES; + } else { + // and here in bytes + // get the current byte position in the buffer where the sound hardware is currently reading + if ( !snd_audio_hw->GetCurrentPosition( &dwCurrentWritePos ) ) { + return 0; + } + // mixBufferSize is in bytes + dwCurrentBlock = dwCurrentWritePos / snd_audio_hw->GetMixBufferSize(); + } + + if ( nextWriteBlock == 0xffffffff ) { + nextWriteBlock = dwCurrentBlock; + } + + if ( dwCurrentBlock != nextWriteBlock ) { + return 0; + } + + // lock the buffer so we can actually write to it + short *fBlock = NULL; + ulong fBlockLen = 0; + if ( !useOpenAL ) { + snd_audio_hw->Lock( (void **)&fBlock, &fBlockLen ); + if ( !fBlock ) { + return 0; + } + } + + int j; + soundStats.runs++; + soundStats.activeSounds = 0; + + int numSpeakers = snd_audio_hw->GetNumberOfSpeakers(); + + nextWriteBlock++; + nextWriteBlock %= ROOM_SLICES_IN_BUFFER; + + int newPosition = nextWriteBlock * MIXBUFFER_SAMPLES; + + if ( newPosition < olddwCurrentWritePos ) { + buffers++; // buffer wrapped + } + + // nextWriteSample is in multi-channel samples inside the buffer + int nextWriteSamples = nextWriteBlock * MIXBUFFER_SAMPLES; + + olddwCurrentWritePos = newPosition; + + // newSoundTime is in multi-channel samples since the sound system was started + int newSoundTime = ( buffers * MIXBUFFER_SAMPLES * ROOM_SLICES_IN_BUFFER ) + nextWriteSamples; + + // check for impending overflow + // FIXME: we don't handle sound wrap-around correctly yet + if ( newSoundTime > 0x6fffffff ) { + buffers = 0; + } + + if ( (newSoundTime - CurrentSoundTime) > (int)MIXBUFFER_SAMPLES ) { + soundStats.missedWindow++; + } + + if ( useOpenAL ) { + // enable audio hardware caching + alcSuspendContext( openalContext ); + } else { + // clear the buffer for all the mixing output + SIMDProcessor->Memset( finalMixBuffer, 0, MIXBUFFER_SAMPLES * sizeof(float) * numSpeakers ); + } + + // let the active sound world mix all the channels in unless muted or avi demo recording + if ( !muted && currentSoundWorld && !currentSoundWorld->fpa[0] ) { + currentSoundWorld->MixLoop( newSoundTime, numSpeakers, finalMixBuffer ); + } + + if ( useOpenAL ) { + // disable audio hardware caching (this updates ALL settings since last alcSuspendContext) + alcProcessContext( openalContext ); + } else { + short *dest = fBlock + nextWriteSamples * numSpeakers; + + SIMDProcessor->MixedSoundToSamples( dest, finalMixBuffer, MIXBUFFER_SAMPLES * numSpeakers ); + + // allow swapping the left / right speaker channels for people with miswired systems + if ( numSpeakers == 2 && s_reverse.GetBool() ) { + for( j = 0; j < MIXBUFFER_SAMPLES; j++ ) { + short temp = dest[j*2]; + dest[j*2] = dest[j*2+1]; + dest[j*2+1] = temp; + } + } + snd_audio_hw->Unlock( fBlock, fBlockLen ); + } + + CurrentSoundTime = newSoundTime; + + soundStats.timeinprocess = Sys_Milliseconds() - inTime; + + return soundStats.timeinprocess; +} + +/* +=================== +idSoundSystemLocal::AsyncUpdateWrite +sound output using a write API. all the scheduling based on time +we mix MIXBUFFER_SAMPLES at a time, but we feed the audio device with smaller chunks (and more often) +called by the sound thread when com_asyncSound is 3 ( Linux ) +=================== +*/ +int idSoundSystemLocal::AsyncUpdateWrite( int inTime ) { + + if ( !isInitialized || shutdown || !snd_audio_hw ) { + return 0; + } + + if ( !useOpenAL ) { + snd_audio_hw->Flush(); + } + + unsigned int dwCurrentBlock = (unsigned int)( inTime * 44.1f / MIXBUFFER_SAMPLES ); + + if ( nextWriteBlock == 0xffffffff ) { + nextWriteBlock = dwCurrentBlock; + } + + if ( dwCurrentBlock < nextWriteBlock ) { + return 0; + } + + if ( nextWriteBlock != dwCurrentBlock ) { + Sys_Printf( "missed %d sound updates\n", dwCurrentBlock - nextWriteBlock ); + } + + int sampleTime = dwCurrentBlock * MIXBUFFER_SAMPLES; + int numSpeakers = snd_audio_hw->GetNumberOfSpeakers(); + + if ( useOpenAL ) { + // enable audio hardware caching + alcSuspendContext( openalContext ); + } else { + // clear the buffer for all the mixing output + SIMDProcessor->Memset( finalMixBuffer, 0, MIXBUFFER_SAMPLES * sizeof(float) * numSpeakers ); + } + + // let the active sound world mix all the channels in unless muted or avi demo recording + if ( !muted && currentSoundWorld && !currentSoundWorld->fpa[0] ) { + currentSoundWorld->MixLoop( sampleTime, numSpeakers, finalMixBuffer ); + } + + if ( useOpenAL ) { + // disable audio hardware caching (this updates ALL settings since last alcSuspendContext) + alcProcessContext( openalContext ); + } else { + short *dest = snd_audio_hw->GetMixBuffer(); + + SIMDProcessor->MixedSoundToSamples( dest, finalMixBuffer, MIXBUFFER_SAMPLES * numSpeakers ); + + // allow swapping the left / right speaker channels for people with miswired systems + if ( numSpeakers == 2 && s_reverse.GetBool() ) { + int j; + for( j = 0; j < MIXBUFFER_SAMPLES; j++ ) { + short temp = dest[j*2]; + dest[j*2] = dest[j*2+1]; + dest[j*2+1] = temp; + } + } + snd_audio_hw->Write( false ); + } + + // only move to the next block if the write was successful + nextWriteBlock = dwCurrentBlock + 1; + CurrentSoundTime = sampleTime; + + return Sys_Milliseconds() - inTime; +} + +/* +=================== +idSoundSystemLocal::dB2Scale +=================== +*/ +float idSoundSystemLocal::dB2Scale( const float val ) const { + if ( val == 0.0f ) { + return 1.0f; // most common + } else if ( val <= -60.0f ) { + return 0.0f; + } else if ( val >= 60.0f ) { + return powf( 2.0f, val * ( 1.0f / 6.0f ) ); + } + int ival = (int)( ( val + 60.0f ) * 10.0f ); + return volumesDB[ival]; +} + +/* +=================== +idSoundSystemLocal::ImageForTime +=================== +*/ +cinData_t idSoundSystemLocal::ImageForTime( const int milliseconds, const bool waveform ) { + cinData_t ret; + int i, j; + + if ( !isInitialized || !snd_audio_hw ) { + memset( &ret, 0, sizeof( ret ) ); + return ret; + } + + Sys_EnterCriticalSection(); + + if ( !graph ) { + graph = (dword *)Mem_Alloc( 256*128 * 4); + } + memset( graph, 0, 256*128 * 4 ); + float *accum = finalMixBuffer; // unfortunately, these are already clamped + int time = Sys_Milliseconds(); + + int numSpeakers = snd_audio_hw->GetNumberOfSpeakers(); + + if ( !waveform ) { + for( j = 0; j < numSpeakers; j++ ) { + int meter = 0; + for( i = 0; i < MIXBUFFER_SAMPLES; i++ ) { + float result = idMath::Fabs(accum[i*numSpeakers+j]); + if ( result > meter ) { + meter = result; + } + } + + meter /= 256; // 32768 becomes 128 + if ( meter > 128 ) { + meter = 128; + } + int offset; + int xsize; + if ( numSpeakers == 6 ) { + offset = j * 40; + xsize = 20; + } else { + offset = j * 128; + xsize = 63; + } + int x,y; + dword color = 0xff00ff00; + for ( y = 0; y < 128; y++ ) { + for ( x = 0; x < xsize; x++ ) { + graph[(127-y)*256 + offset + x ] = color; + } +#if 0 + if ( y == 80 ) { + color = 0xff00ffff; + } else if ( y == 112 ) { + color = 0xff0000ff; + } +#endif + if ( y > meter ) { + break; + } + } + + if ( meter > meterTops[j] ) { + meterTops[j] = meter; + meterTopsTime[j] = time + s_meterTopTime.GetInteger(); + } else if ( time > meterTopsTime[j] && meterTops[j] > 0 ) { + meterTops[j]--; + if (meterTops[j]) { + meterTops[j]--; + } + } + } + + for( j = 0; j < numSpeakers; j++ ) { + int meter = meterTops[j]; + + int offset; + int xsize; + if ( numSpeakers == 6 ) { + offset = j*40; + xsize = 20; + } else { + offset = j*128; + xsize = 63; + } + int x,y; + dword color; + if ( meter <= 80 ) { + color = 0xff007f00; + } else if ( meter <= 112 ) { + color = 0xff007f7f; + } else { + color = 0xff00007f; + } + for ( y = meter; y < 128 && y < meter + 4; y++ ) { + for ( x = 0; x < xsize; x++ ) { + graph[(127-y)*256 + offset + x ] = color; + } + } + } + } else { + dword colors[] = { 0xff007f00, 0xff007f7f, 0xff00007f, 0xff00ff00, 0xff00ffff, 0xff0000ff }; + + for( j = 0; j < numSpeakers; j++ ) { + int xx = 0; + float fmeter; + int step = MIXBUFFER_SAMPLES / 256; + for( i = 0; i < MIXBUFFER_SAMPLES; i += step ) { + fmeter = 0.0f; + for( int x = 0; x < step; x++ ) { + float result = accum[(i+x)*numSpeakers+j]; + result = result / 32768.0f; + fmeter += result; + } + fmeter /= 4.0f; + if ( fmeter < -1.0f ) { + fmeter = -1.0f; + } else if ( fmeter > 1.0f ) { + fmeter = 1.0f; + } + int meter = (fmeter * 63.0f); + graph[ (meter + 64) * 256 + xx ] = colors[j]; + + if ( meter < 0 ) { + meter = -meter; + } + if ( meter > meterTops[xx] ) { + meterTops[xx] = meter; + meterTopsTime[xx] = time + 100; + } else if ( time>meterTopsTime[xx] && meterTops[xx] > 0 ) { + meterTops[xx]--; + if ( meterTops[xx] ) { + meterTops[xx]--; + } + } + xx++; + } + } + for( i = 0; i < 256; i++ ) { + int meter = meterTops[i]; + for ( int y = -meter; y < meter; y++ ) { + graph[ (y+64)*256 + i ] = colors[j]; + } + } + } + ret.imageHeight = 128; + ret.imageWidth = 256; + ret.image = (unsigned char *)graph; + + Sys_LeaveCriticalSection(); + + return ret; +} + +/* +=================== +idSoundSystemLocal::GetSoundDecoderInfo +=================== +*/ +int idSoundSystemLocal::GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo ) { + int i, j, firstEmitter, firstChannel; + idSoundWorldLocal *sw = soundSystemLocal.currentSoundWorld; + + if ( index < 0 ) { + firstEmitter = 0; + firstChannel = 0; + } else { + firstEmitter = index / SOUND_MAX_CHANNELS; + firstChannel = index - firstEmitter * SOUND_MAX_CHANNELS + 1; + } + + for ( i = firstEmitter; i < sw->emitters.Num(); i++ ) { + idSoundEmitterLocal *sound = sw->emitters[i]; + + if ( !sound ) { + continue; + } + + // run through all the channels + for ( j = firstChannel; j < SOUND_MAX_CHANNELS; j++ ) { + idSoundChannel *chan = &sound->channels[j]; + + if ( chan->decoder == NULL ) { + continue; + } + + idSoundSample *sample = chan->decoder->GetSample(); + + if ( sample == NULL ) { + continue; + } + + decoderInfo.name = sample->name; + decoderInfo.format = ( sample->objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) ? "OGG" : "WAV"; + decoderInfo.numChannels = sample->objectInfo.nChannels; + decoderInfo.numSamplesPerSecond = sample->objectInfo.nSamplesPerSec; + decoderInfo.num44kHzSamples = sample->LengthIn44kHzSamples(); + decoderInfo.numBytes = sample->objectMemSize; + decoderInfo.looping = ( chan->parms.soundShaderFlags & SSF_LOOPING ) != 0; + decoderInfo.lastVolume = chan->lastVolume; + decoderInfo.start44kHzTime = chan->trigger44kHzTime; + decoderInfo.current44kHzTime = soundSystemLocal.GetCurrent44kHzTime(); + + return ( i * SOUND_MAX_CHANNELS + j ); + } + + firstChannel = 0; + } + return -1; +} + +/* +=================== +idSoundSystemLocal::AllocSoundWorld +=================== +*/ +idSoundWorld *idSoundSystemLocal::AllocSoundWorld( idRenderWorld *rw ) { + idSoundWorldLocal *local = new idSoundWorldLocal; + + local->Init( rw ); + + return local; +} + +/* +=================== +idSoundSystemLocal::SetMute +=================== +*/ +void idSoundSystemLocal::SetMute( bool muteOn ) { + muted = muteOn; +} + +/* +=================== +idSoundSystemLocal::SamplesToMilliseconds +=================== +*/ +int idSoundSystemLocal::SamplesToMilliseconds( int samples ) const { + return ( samples / (PRIMARYFREQ/1000) ); +} + +/* +=================== +idSoundSystemLocal::SamplesToMilliseconds +=================== +*/ +int idSoundSystemLocal::MillisecondsToSamples( int ms ) const { + return ( ms * (PRIMARYFREQ/1000) ); +} + +/* +=================== +idSoundSystemLocal::SetPlayingSoundWorld + +specifying NULL will cause silence to be played +=================== +*/ +void idSoundSystemLocal::SetPlayingSoundWorld( idSoundWorld *soundWorld ) { + currentSoundWorld = static_cast(soundWorld); +} + +/* +=================== +idSoundSystemLocal::GetPlayingSoundWorld +=================== +*/ +idSoundWorld *idSoundSystemLocal::GetPlayingSoundWorld( void ) { + return currentSoundWorld; +} + +/* +=================== +idSoundSystemLocal::BeginLevelLoad +=================== +*/ + +void idSoundSystemLocal::BeginLevelLoad() { + if ( !isInitialized ) { + return; + } + soundCache->BeginLevelLoad(); + + if ( efxloaded ) { + EFXDatabase.UnloadFile(); + efxloaded = false; + } +} + +/* +=================== +idSoundSystemLocal::EndLevelLoad +=================== +*/ +void idSoundSystemLocal::EndLevelLoad( const char *mapstring ) { + if ( !isInitialized ) { + return; + } + soundCache->EndLevelLoad(); + + idStr efxname( "efxs/" ); + idStr mapname( mapstring ); + + mapname.SetFileExtension( ".efx" ); + mapname.StripPath(); + efxname += mapname; + + efxloaded = EFXDatabase.LoadFile( efxname ); + + if ( efxloaded ) { + common->Printf("sound: found %s\n", efxname.c_str() ); + } else { + common->Printf("sound: missing %s\n", efxname.c_str() ); + } +} + +/* +=================== +idSoundSystemLocal::AllocOpenALSource +=================== +*/ +ALuint idSoundSystemLocal::AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo ) { + int timeOldestZeroVolSingleShot = Sys_Milliseconds(); + int timeOldestZeroVolLooping = Sys_Milliseconds(); + int timeOldestSingle = Sys_Milliseconds(); + int iOldestZeroVolSingleShot = -1; + int iOldestZeroVolLooping = -1; + int iOldestSingle = -1; + int iUnused = -1; + int index = -1; + ALsizei i; + + // Grab current msec time + int time = Sys_Milliseconds(); + + // Cycle through all sources + for ( i = 0; i < openalSourceCount; i++ ) { + // Use any unused source first, + // Then find oldest single shot quiet source, + // Then find oldest looping quiet source and + // Lastly find oldest single shot non quiet source.. + if ( !openalSources[i].inUse ) { + iUnused = i; + break; + } else if ( !openalSources[i].looping && openalSources[i].chan->lastVolume < SND_EPSILON ) { + if ( openalSources[i].startTime < timeOldestZeroVolSingleShot ) { + timeOldestZeroVolSingleShot = openalSources[i].startTime; + iOldestZeroVolSingleShot = i; + } + } else if ( openalSources[i].looping && openalSources[i].chan->lastVolume < SND_EPSILON ) { + if ( openalSources[i].startTime < timeOldestZeroVolLooping ) { + timeOldestZeroVolLooping = openalSources[i].startTime; + iOldestZeroVolLooping = i; + } + } else if ( !openalSources[i].looping ) { + if ( openalSources[i].startTime < timeOldestSingle ) { + timeOldestSingle = openalSources[i].startTime; + iOldestSingle = i; + } + } + } + + if ( iUnused != -1 ) { + index = iUnused; + } else if ( iOldestZeroVolSingleShot != - 1 ) { + index = iOldestZeroVolSingleShot; + } else if ( iOldestZeroVolLooping != -1 ) { + index = iOldestZeroVolLooping; + } else if ( iOldestSingle != -1 ) { + index = iOldestSingle; + } + + if ( index != -1 ) { + // stop the channel that is being ripped off + if ( openalSources[index].chan ) { + // stop the channel only when not looping + if ( !openalSources[index].looping ) { + openalSources[index].chan->Stop(); + } else { + openalSources[index].chan->triggered = true; + } + + // Free hardware resources + openalSources[index].chan->ALStop(); + } + + // Initialize structure + openalSources[index].startTime = time; + openalSources[index].chan = chan; + openalSources[index].inUse = true; + openalSources[index].looping = looping; + openalSources[index].stereo = stereo; + + return openalSources[index].handle; + } else { + return NULL; + } +} + +/* +=================== +idSoundSystemLocal::FreeOpenALSource +=================== +*/ +void idSoundSystemLocal::FreeOpenALSource( ALuint handle ) { + ALsizei i; + for ( i = 0; i < openalSourceCount; i++ ) { + if ( openalSources[i].handle == handle ) { + if ( openalSources[i].chan ) { + openalSources[i].chan->openalSource = NULL; + } +#if ID_OPENAL + // Reset source EAX ROOM level when freeing stereo source + if ( openalSources[i].stereo && alEAXSet ) { + long Room = EAXSOURCE_DEFAULTROOM; + alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_ROOM, openalSources[i].handle, &Room, sizeof(Room)); + } +#endif + // Initialize structure + openalSources[i].startTime = 0; + openalSources[i].chan = NULL; + openalSources[i].inUse = false; + openalSources[i].looping = false; + openalSources[i].stereo = false; + } + } +} + +/* +============================================================ +SoundFX and misc effects +============================================================ +*/ + +/* +=================== +idSoundSystemLocal::ProcessSample +=================== +*/ +void SoundFX_Lowpass::ProcessSample( float* in, float* out ) { + float c, a1, a2, a3, b1, b2; + float resonance = idSoundSystemLocal::s_enviroSuitCutoffQ.GetFloat(); + float cutoffFrequency = idSoundSystemLocal::s_enviroSuitCutoffFreq.GetFloat(); + + Initialize(); + + c = 1.0 / idMath::Tan16( idMath::PI * cutoffFrequency / 44100 ); + + // compute coefs + a1 = 1.0 / ( 1.0 + resonance * c + c * c ); + a2 = 2* a1; + a3 = a1; + b1 = 2.0 * ( 1.0 - c * c) * a1; + b2 = ( 1.0 - resonance * c + c * c ) * a1; + + // compute output value + out[0] = a1 * in[0] + a2 * in[-1] + a3 * in[-2] - b1 * out[-1] - b2 * out[-2]; +} + +void SoundFX_LowpassFast::ProcessSample( float* in, float* out ) { + // compute output value + out[0] = a1 * in[0] + a2 * in[-1] + a3 * in[-2] - b1 * out[-1] - b2 * out[-2]; +} + +void SoundFX_LowpassFast::SetParms( float p1, float p2, float p3 ) { + float c; + + // set the vars + freq = p1; + res = p2; + + // precompute the coefs + c = 1.0 / idMath::Tan( idMath::PI * freq / 44100 ); + + // compute coefs + a1 = 1.0 / ( 1.0 + res * c + c * c ); + a2 = 2* a1; + a3 = a1; + + b1 = 2.0 * ( 1.0 - c * c) * a1; + b2 = ( 1.0 - res * c + c * c ) * a1; +} + +void SoundFX_Comb::Initialize() { + if ( initialized ) + return; + + initialized = true; + maxlen = 50000; + buffer = new float[maxlen]; + currentTime = 0; +} + +void SoundFX_Comb::ProcessSample( float* in, float* out ) { + float gain = idSoundSystemLocal::s_reverbFeedback.GetFloat(); + int len = idSoundSystemLocal::s_reverbTime.GetFloat() + param; + + Initialize(); + + // sum up and output + out[0] = buffer[currentTime]; + buffer[currentTime] = buffer[currentTime] * gain + in[0]; + + // increment current time + currentTime++; + if ( currentTime >= len ) + currentTime -= len; +} + +/* +=================== +idSoundSystemLocal::DoEnviroSuit +=================== +*/ +void idSoundSystemLocal::DoEnviroSuit( float* samples, int numSamples, int numSpeakers ) { + float out[10000], *out_p = out + 2; + float in[10000], *in_p = in + 2; + + assert( !idSoundSystemLocal::useOpenAL ); + + if ( !fxList.Num() ) { + for ( int i = 0; i < 6; i++ ) { + SoundFX* fx; + + // lowpass filter + fx = new SoundFX_Lowpass(); + fx->SetChannel( i ); + fxList.Append( fx ); + + // comb + fx = new SoundFX_Comb(); + fx->SetChannel( i ); + fx->SetParameter( i * 100 ); + fxList.Append( fx ); + + // comb + fx = new SoundFX_Comb(); + fx->SetChannel( i ); + fx->SetParameter( i * 100 + 5 ); + fxList.Append( fx ); + } + } + + for ( int i = 0; i < numSpeakers; i++ ) { + int j; + + // restore previous samples + memset( in, 0, 10000 * sizeof( float ) ); + memset( out, 0, 10000 * sizeof( float ) ); + + // fx loop + for ( int k = 0; k < fxList.Num(); k++ ) { + SoundFX* fx = fxList[k]; + + // skip if we're not the right channel + if ( fx->GetChannel() != i ) + continue; + + // get samples and continuity + fx->GetContinuitySamples( in_p[-1], in_p[-2], out_p[-1], out_p[-2] ); + for ( j = 0; j < numSamples; j++ ) { + in_p[j] = samples[j * numSpeakers + i] * s_enviroSuitVolumeScale.GetFloat(); + } + + // process fx loop + for ( j = 0; j < numSamples; j++ ) { + fx->ProcessSample( in_p + j, out_p + j ); + } + + // store samples and continuity + fx->SetContinuitySamples( in_p[numSamples-2], in_p[numSamples-3], out_p[numSamples-2], out_p[numSamples-3] ); + + for ( j = 0; j < numSamples; j++ ) { + samples[j * numSpeakers + i] = out_p[j]; + } + } + } +} + +/* +================= +idSoundSystemLocal::PrintMemInfo +================= +*/ +void idSoundSystemLocal::PrintMemInfo( MemInfo_t *mi ) { + soundCache->PrintMemInfo( mi ); +} + +/* +=============== +idSoundSystemLocal::EAXAvailable +=============== +*/ +int idSoundSystemLocal::IsEAXAvailable( void ) { +#if !ID_OPENAL + return -1; +#else + ALCdevice *device; + ALCcontext *context; + + if ( EAXAvailable != -1 ) { + return EAXAvailable; + } + + if ( !Sys_LoadOpenAL() ) { + EAXAvailable = 2; + return 2; + } + // when dynamically loading the OpenAL subsystem, we need to get a context before alIsExtensionPresent would work + device = alcOpenDevice( NULL ); + context = alcCreateContext( device, NULL ); + alcMakeContextCurrent( context ); + if ( alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) { + alcMakeContextCurrent( NULL ); + alcDestroyContext( context ); + alcCloseDevice( device ); + EAXAvailable = 1; + return 1; + } + alcMakeContextCurrent( NULL ); + alcDestroyContext( context ); + alcCloseDevice( device ); + EAXAvailable = 0; + return 0; +#endif +} diff --git a/sound/snd_wavefile.cpp b/sound/snd_wavefile.cpp new file mode 100644 index 000000000..7a3a0af06 --- /dev/null +++ b/sound/snd_wavefile.cpp @@ -0,0 +1,345 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + +//----------------------------------------------------------------------------- +// Name: idWaveFile::idWaveFile() +// Desc: Constructs the class. Call Open() to open a wave file for reading. +// Then call Read() as needed. Calling the destructor or Close() +// will close the file. +//----------------------------------------------------------------------------- +idWaveFile::idWaveFile( void ) { + memset( &mpwfx, 0, sizeof( waveformatextensible_t ) ); + mhmmio = NULL; + mdwSize = 0; + mseekBase = 0; + mbIsReadingFromMemory = false; + mpbData = NULL; + ogg = NULL; + isOgg = false; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::~idWaveFile() +// Desc: Destructs the class +//----------------------------------------------------------------------------- +idWaveFile::~idWaveFile( void ) { + Close(); + + if ( mbIsReadingFromMemory && mpbData ) { + Mem_Free( mpbData ); + } + + memset( &mpwfx, 0, sizeof( waveformatextensible_t ) ); +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::Open() +// Desc: Opens a wave file for reading +//----------------------------------------------------------------------------- +int idWaveFile::Open( const char* strFileName, waveformatex_t* pwfx ) { + + mbIsReadingFromMemory = false; + + mpbData = NULL; + mpbDataCur = mpbData; + + if( strFileName == NULL ) { + return -1; + } + + idStr name = strFileName; + + // note: used to only check for .wav when making a build + name.SetFileExtension( ".ogg" ); + if ( fileSystem->ReadFile( name, NULL, NULL ) != -1 ) { + return OpenOGG( name, pwfx ); + } + + memset( &mpwfx, 0, sizeof( waveformatextensible_t ) ); + + mhmmio = fileSystem->OpenFileRead( strFileName ); + if ( !mhmmio ) { + mdwSize = 0; + return -1; + } + if ( mhmmio->Length() <= 0 ) { + mhmmio = NULL; + return -1; + } + if ( ReadMMIO() != 0 ) { + // ReadMMIO will fail if its an not a wave file + Close(); + return -1; + } + + mfileTime = mhmmio->Timestamp(); + + if ( ResetFile() != 0 ) { + Close(); + return -1; + } + + // After the reset, the size of the wav file is mck.cksize so store it now + mdwSize = mck.cksize / sizeof( short ); + mMemSize = mck.cksize; + + if ( mck.cksize != 0xffffffff ) { + if ( pwfx ) { + memcpy( pwfx, (waveformatex_t *)&mpwfx, sizeof(waveformatex_t)); + } + return 0; + } + return -1; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::OpenFromMemory() +// Desc: copy data to idWaveFile member variable from memory +//----------------------------------------------------------------------------- +int idWaveFile::OpenFromMemory( short* pbData, int ulDataSize, waveformatextensible_t* pwfx ) { + mpwfx = *pwfx; + mulDataSize = ulDataSize; + mpbData = pbData; + mpbDataCur = mpbData; + mdwSize = ulDataSize / sizeof( short ); + mMemSize = ulDataSize; + mbIsReadingFromMemory = true; + + return 0; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::ReadMMIO() +// Desc: Support function for reading from a multimedia I/O stream. +// mhmmio must be valid before calling. This function uses it to +// update mckRiff, and mpwfx. +//----------------------------------------------------------------------------- +int idWaveFile::ReadMMIO( void ) { + mminfo_t ckIn; // chunk info. for general use. + pcmwaveformat_t pcmWaveFormat; // Temp PCM structure to load in. + + memset( &mpwfx, 0, sizeof( waveformatextensible_t ) ); + + mhmmio->Read( &mckRiff, 12 ); + assert( !isOgg ); + mckRiff.ckid = LittleLong( mckRiff.ckid ); + mckRiff.cksize = LittleLong( mckRiff.cksize ); + mckRiff.fccType = LittleLong( mckRiff.fccType ); + mckRiff.dwDataOffset = 12; + + // Check to make sure this is a valid wave file + if( (mckRiff.ckid != fourcc_riff) || (mckRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E') ) ) { + return -1; + } + + // Search the input file for for the 'fmt ' chunk. + ckIn.dwDataOffset = 12; + do { + if (8 != mhmmio->Read( &ckIn, 8 ) ) { + return -1; + } + assert( !isOgg ); + ckIn.ckid = LittleLong( ckIn.ckid ); + ckIn.cksize = LittleLong( ckIn.cksize ); + ckIn.dwDataOffset += ckIn.cksize-8; + } while (ckIn.ckid != mmioFOURCC('f', 'm', 't', ' ')); + + // Expect the 'fmt' chunk to be at least as large as ; + // if there are extra parameters at the end, we'll ignore them + if( ckIn.cksize < sizeof(pcmwaveformat_t) ) { + return -1; + } + + // Read the 'fmt ' chunk into . + if( mhmmio->Read( &pcmWaveFormat, sizeof(pcmWaveFormat) ) != sizeof(pcmWaveFormat) ) { + return -1; + } + assert( !isOgg ); + pcmWaveFormat.wf.wFormatTag = LittleShort( pcmWaveFormat.wf.wFormatTag ); + pcmWaveFormat.wf.nChannels = LittleShort( pcmWaveFormat.wf.nChannels ); + pcmWaveFormat.wf.nSamplesPerSec = LittleLong( pcmWaveFormat.wf.nSamplesPerSec ); + pcmWaveFormat.wf.nAvgBytesPerSec = LittleLong( pcmWaveFormat.wf.nAvgBytesPerSec ); + pcmWaveFormat.wf.nBlockAlign = LittleShort( pcmWaveFormat.wf.nBlockAlign ); + pcmWaveFormat.wBitsPerSample = LittleShort( pcmWaveFormat.wBitsPerSample ); + + // Copy the bytes from the pcm structure to the waveformatex_t structure + memcpy( &mpwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) ); + + // Allocate the waveformatex_t, but if its not pcm format, read the next + // word, and thats how many extra bytes to allocate. + if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_TAG_PCM ) { + mpwfx.Format.cbSize = 0; + } else { + return -1; // we don't handle these (32 bit wavefiles, etc) +#if 0 + // Read in length of extra bytes. + word cbExtraBytes = 0L; + if( mhmmio->Read( (char*)&cbExtraBytes, sizeof(word) ) != sizeof(word) ) + return -1; + + mpwfx.Format.cbSize = cbExtraBytes; + + // Now, read those extra bytes into the structure, if cbExtraAlloc != 0. + if( mhmmio->Read( (char*)(((byte*)&(mpwfx.Format.cbSize))+sizeof(word)), cbExtraBytes ) != cbExtraBytes ) { + memset( &mpwfx, 0, sizeof( waveformatextensible_t ) ); + return -1; + } +#endif + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::ResetFile() +// Desc: Resets the internal mck pointer so reading starts from the +// beginning of the file again +//----------------------------------------------------------------------------- +int idWaveFile::ResetFile( void ) { + if( mbIsReadingFromMemory ) { + mpbDataCur = mpbData; + } else { + if( mhmmio == NULL ) { + return -1; + } + + // Seek to the data + if( -1 == mhmmio->Seek( mckRiff.dwDataOffset + sizeof(fourcc), FS_SEEK_SET ) ) { + return -1; + } + + // Search the input file for for the 'fmt ' chunk. + mck.ckid = 0; + do { + byte ioin; + if ( !mhmmio->Read( &ioin, 1 ) ) { + return -1; + } + mck.ckid = (mck.ckid>>8) | (ioin<<24); + } while (mck.ckid != mmioFOURCC('d', 'a', 't', 'a')); + + mhmmio->Read( &mck.cksize, 4 ); + assert( !isOgg ); + mck.cksize = LittleLong( mck.cksize ); + mseekBase = mhmmio->Tell(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::Read() +// Desc: Reads section of data from a wave file into pBuffer and returns +// how much read in pdwSizeRead, reading not more than dwSizeToRead. +// This uses mck to determine where to start reading from. So +// subsequent calls will be continue where the last left off unless +// Reset() is called. +//----------------------------------------------------------------------------- +int idWaveFile::Read( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ) { + + if ( ogg != NULL ) { + + return ReadOGG( pBuffer, dwSizeToRead, pdwSizeRead ); + + } else if ( mbIsReadingFromMemory ) { + + if( mpbDataCur == NULL ) { + return -1; + } + if( (byte*)(mpbDataCur + dwSizeToRead) > (byte*)(mpbData + mulDataSize) ) { + dwSizeToRead = mulDataSize - (int)(mpbDataCur - mpbData); + } + SIMDProcessor->Memcpy( pBuffer, mpbDataCur, dwSizeToRead ); + mpbDataCur += dwSizeToRead; + + if ( pdwSizeRead != NULL ) { + *pdwSizeRead = dwSizeToRead; + } + + return dwSizeToRead; + + } else { + + if( mhmmio == NULL ) { + return -1; + } + if( pBuffer == NULL ) { + return -1; + } + + dwSizeToRead = mhmmio->Read( pBuffer, dwSizeToRead ); + // this is hit by ogg code, which does it's own byte swapping internally + if ( !isOgg ) { + LittleRevBytes( pBuffer, 2, dwSizeToRead / 2 ); + } + + if ( pdwSizeRead != NULL ) { + *pdwSizeRead = dwSizeToRead; + } + + return dwSizeToRead; + } +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::Close() +// Desc: Closes the wave file +//----------------------------------------------------------------------------- +int idWaveFile::Close( void ) { + if ( ogg != NULL ) { + return CloseOGG(); + } + if( mhmmio != NULL ) { + fileSystem->CloseFile( mhmmio ); + mhmmio = NULL; + } + return 0; +} + +//----------------------------------------------------------------------------- +// Name: idWaveFile::Seek() +//----------------------------------------------------------------------------- +int idWaveFile::Seek( int offset ) { + + if ( ogg != NULL ) { + + common->FatalError( "idWaveFile::Seek: cannot seek on an OGG file\n" ); + + } else if( mbIsReadingFromMemory ) { + + mpbDataCur = mpbData + offset; + + } else { + if( mhmmio == NULL ) { + return -1; + } + + if ((int)(offset+mseekBase) == mhmmio->Tell()) { + return 0; + } + mhmmio->Seek( offset + mseekBase, FS_SEEK_SET ); + return 0; + } + return -1; +} diff --git a/sound/snd_world.cpp b/sound/snd_world.cpp new file mode 100644 index 000000000..465a6a7f5 --- /dev/null +++ b/sound/snd_world.cpp @@ -0,0 +1,2132 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "snd_local.h" + +/* +================== +idSoundWorldLocal::Init +================== +*/ +void idSoundWorldLocal::Init( idRenderWorld *renderWorld ) { + rw = renderWorld; + writeDemo = NULL; + + listenerAxis.Identity(); + listenerPos.Zero(); + listenerPrivateId = 0; + listenerQU.Zero(); + listenerArea = 0; + listenerAreaName = "Undefined"; + listenerEnvironmentID = -2; + + gameMsec = 0; + game44kHz = 0; + pause44kHz = -1; + lastAVI44kHz = 0; + + for ( int i = 0 ; i < SOUND_MAX_CLASSES ; i++ ) { + soundClassFade[i].Clear(); + } + + // fill in the 0 index spot + idSoundEmitterLocal *placeHolder = new idSoundEmitterLocal; + emitters.Append( placeHolder ); + + fpa[0] = fpa[1] = fpa[2] = fpa[3] = fpa[4] = fpa[5] = NULL; + + aviDemoPath = ""; + aviDemoName = ""; + + localSound = NULL; + + slowmoActive = false; + slowmoSpeed = 0; + enviroSuitActive = false; +} + +/* +=============== +idSoundWorldLocal::idSoundWorldLocal +=============== +*/ +idSoundWorldLocal::idSoundWorldLocal() { +} + +/* +=============== +idSoundWorldLocal::~idSoundWorldLocal +=============== +*/ +idSoundWorldLocal::~idSoundWorldLocal() { + Shutdown(); +} + +/* +=============== +idSoundWorldLocal::Shutdown + + this is called from the main thread +=============== +*/ +void idSoundWorldLocal::Shutdown() { + int i; + + if ( soundSystemLocal.currentSoundWorld == this ) { + soundSystemLocal.currentSoundWorld = NULL; + } + + AVIClose(); + + for ( i = 0; i < emitters.Num(); i++ ) { + if ( emitters[i] ) { + delete emitters[i]; + emitters[i] = NULL; + } + } + localSound = NULL; +} + +/* +=================== +idSoundWorldLocal::ClearAllSoundEmitters +=================== +*/ +void idSoundWorldLocal::ClearAllSoundEmitters() { + int i; + + Sys_EnterCriticalSection(); + + AVIClose(); + + for ( i = 0; i < emitters.Num(); i++ ) { + idSoundEmitterLocal *sound = emitters[i]; + sound->Clear(); + } + localSound = NULL; + + Sys_LeaveCriticalSection(); +} + +/* +=================== +idSoundWorldLocal::AllocLocalSoundEmitter +=================== +*/ +idSoundEmitterLocal *idSoundWorldLocal::AllocLocalSoundEmitter() { + int i, index; + idSoundEmitterLocal *def = NULL; + + index = -1; + + // never use the 0 index spot + + for ( i = 1 ; i < emitters.Num() ; i++ ) { + def = emitters[i]; + + // check for a completed and freed spot + if ( def->removeStatus >= REMOVE_STATUS_SAMPLEFINISHED ) { + index = i; + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "sound: recycling sound def %d\n", i ); + } + break; + } + } + + if ( index == -1 ) { + // append a brand new one + def = new idSoundEmitterLocal; + + // we need to protect this from the async thread + Sys_EnterCriticalSection(); + index = emitters.Append( def ); + Sys_LeaveCriticalSection(); + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "sound: appended new sound def %d\n", index ); + } + } + + def->Clear(); + def->index = index; + def->removeStatus = REMOVE_STATUS_ALIVE; + def->soundWorld = this; + + return def; +} + +/* +=================== +idSoundWorldLocal::AllocSoundEmitter + + this is called from the main thread +=================== +*/ +idSoundEmitter *idSoundWorldLocal::AllocSoundEmitter() { + idSoundEmitterLocal *emitter = AllocLocalSoundEmitter(); + + if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) { + common->Printf( "AllocSoundEmitter = %i\n", emitter->index ); + } + if ( writeDemo ) { + writeDemo->WriteInt( DS_SOUND ); + writeDemo->WriteInt( SCMD_ALLOC_EMITTER ); + writeDemo->WriteInt( emitter->index ); + } + + return emitter; +} + +/* +=================== +idSoundWorldLocal::StartWritingDemo + + this is called from the main thread +=================== +*/ +void idSoundWorldLocal::StartWritingDemo( idDemoFile *demo ) { + writeDemo = demo; + + writeDemo->WriteInt( DS_SOUND ); + writeDemo->WriteInt( SCMD_STATE ); + + // use the normal save game code to archive all the emitters + WriteToSaveGame( writeDemo ); +} + +/* +=================== +idSoundWorldLocal::StopWritingDemo + + this is called from the main thread +=================== +*/ +void idSoundWorldLocal::StopWritingDemo() { + writeDemo = NULL; +} + +/* +=================== +idSoundWorldLocal::ProcessDemoCommand + + this is called from the main thread +=================== +*/ +void idSoundWorldLocal::ProcessDemoCommand( idDemoFile *readDemo ) { + int index; + idSoundEmitterLocal *def; + + if ( !readDemo ) { + return; + } + + soundDemoCommand_t dc; + + if ( !readDemo->ReadInt( (int&)dc ) ) { + return; + } + + switch( dc ) { + case SCMD_STATE: + // we need to protect this from the async thread + // other instances of calling idSoundWorldLocal::ReadFromSaveGame do this while the sound code is muted + // setting muted and going right in may not be good enough here, as we async thread may already be in an async tick (in which case we could still race to it) + Sys_EnterCriticalSection(); + ReadFromSaveGame( readDemo ); + Sys_LeaveCriticalSection(); + UnPause(); + break; + case SCMD_PLACE_LISTENER: + { + idVec3 origin; + idMat3 axis; + int listenerId; + int gameTime; + + readDemo->ReadVec3( origin ); + readDemo->ReadMat3( axis ); + readDemo->ReadInt( listenerId ); + readDemo->ReadInt( gameTime ); + + PlaceListener( origin, axis, listenerId, gameTime, "" ); + }; + break; + case SCMD_ALLOC_EMITTER: + readDemo->ReadInt( index ); + if ( index < 1 || index > emitters.Num() ) { + common->Error( "idSoundWorldLocal::ProcessDemoCommand: bad emitter number" ); + } + if ( index == emitters.Num() ) { + // append a brand new one + def = new idSoundEmitterLocal; + emitters.Append( def ); + } + def = emitters[ index ]; + def->Clear(); + def->index = index; + def->removeStatus = REMOVE_STATUS_ALIVE; + def->soundWorld = this; + break; + case SCMD_FREE: + { + int immediate; + + readDemo->ReadInt( index ); + readDemo->ReadInt( immediate ); + EmitterForIndex( index )->Free( immediate != 0 ); + } + break; + case SCMD_UPDATE: + { + idVec3 origin; + int listenerId; + soundShaderParms_t parms; + + readDemo->ReadInt( index ); + readDemo->ReadVec3( origin ); + readDemo->ReadInt( listenerId ); + readDemo->ReadFloat( parms.minDistance ); + readDemo->ReadFloat( parms.maxDistance ); + readDemo->ReadFloat( parms.volume ); + readDemo->ReadFloat( parms.shakes ); + readDemo->ReadInt( parms.soundShaderFlags ); + readDemo->ReadInt( parms.soundClass ); + EmitterForIndex( index )->UpdateEmitter( origin, listenerId, &parms ); + } + break; + case SCMD_START: + { + const idSoundShader *shader; + int channel; + float diversity; + int shaderFlags; + + readDemo->ReadInt( index ); + shader = declManager->FindSound( readDemo->ReadHashString() ); + readDemo->ReadInt( channel ); + readDemo->ReadFloat( diversity ); + readDemo->ReadInt( shaderFlags ); + EmitterForIndex( index )->StartSound( shader, (s_channelType)channel, diversity, shaderFlags ); + } + break; + case SCMD_MODIFY: + { + int channel; + soundShaderParms_t parms; + + readDemo->ReadInt( index ); + readDemo->ReadInt( channel ); + readDemo->ReadFloat( parms.minDistance ); + readDemo->ReadFloat( parms.maxDistance ); + readDemo->ReadFloat( parms.volume ); + readDemo->ReadFloat( parms.shakes ); + readDemo->ReadInt( parms.soundShaderFlags ); + readDemo->ReadInt( parms.soundClass ); + EmitterForIndex( index )->ModifySound( (s_channelType)channel, &parms ); + } + break; + case SCMD_STOP: + { + int channel; + + readDemo->ReadInt( index ); + readDemo->ReadInt( channel ); + EmitterForIndex( index )->StopSound( (s_channelType)channel ); + } + break; + case SCMD_FADE: + { + int channel; + float to, over; + + readDemo->ReadInt( index ); + readDemo->ReadInt( channel ); + readDemo->ReadFloat( to ); + readDemo->ReadFloat( over ); + EmitterForIndex( index )->FadeSound((s_channelType)channel, to, over ); + } + break; + } +} + +/* +=================== +idSoundWorldLocal::CurrentShakeAmplitudeForPosition + + this is called from the main thread +=================== +*/ +float idSoundWorldLocal::CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listererPosition ) { + float amp = 0.0f; + int localTime; + + if ( idSoundSystemLocal::s_constantAmplitude.GetFloat() >= 0.0f ) { + return 0.0f; + } + + localTime = soundSystemLocal.GetCurrent44kHzTime(); + + for ( int i = 1; i < emitters.Num(); i++ ) { + idSoundEmitterLocal *sound = emitters[i]; + if ( !sound->hasShakes ) { + continue; + } + amp += FindAmplitude( sound, localTime, &listererPosition, SCHANNEL_ANY, true ); + } + return amp; +} + +/* +=================== +idSoundWorldLocal::MixLoop + +Sum all sound contributions into finalMixBuffer, an unclamped float buffer holding +all output channels. MIXBUFFER_SAMPLES samples will be created, with each sample consisting +of 2 or 6 floats depending on numSpeakers. + +this is normally called from the sound thread, but also from the main thread +for AVIdemo writing +=================== +*/ +void idSoundWorldLocal::MixLoop( int current44kHz, int numSpeakers, float *finalMixBuffer ) { + int i, j; + idSoundEmitterLocal *sound; + + // if noclip flying outside the world, leave silence + if ( listenerArea == -1 ) { + if ( idSoundSystemLocal::useOpenAL ) + alListenerf( AL_GAIN, 0.0f ); + return; + } + + // update the listener position and orientation + if ( idSoundSystemLocal::useOpenAL ) { + ALfloat listenerPosition[3]; + + listenerPosition[0] = -listenerPos.y; + listenerPosition[1] = listenerPos.z; + listenerPosition[2] = -listenerPos.x; + + ALfloat listenerOrientation[6]; + + listenerOrientation[0] = -listenerAxis[0].y; + listenerOrientation[1] = listenerAxis[0].z; + listenerOrientation[2] = -listenerAxis[0].x; + + listenerOrientation[3] = -listenerAxis[2].y; + listenerOrientation[4] = listenerAxis[2].z; + listenerOrientation[5] = -listenerAxis[2].x; + + alListenerf( AL_GAIN, 1.0f ); + alListenerfv( AL_POSITION, listenerPosition ); + alListenerfv( AL_ORIENTATION, listenerOrientation ); + +#if ID_OPENAL + if ( soundSystemLocal.s_useEAXReverb.GetBool() ) { + if ( soundSystemLocal.efxloaded ) { + idSoundEffect *effect = NULL; + int EnvironmentID = -1; + idStr defaultStr( "default" ); + idStr listenerAreaStr( listenerArea ); + + soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect, &EnvironmentID ); + if (!effect) + soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect, &EnvironmentID ); + if (!effect) + soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect, &EnvironmentID ); + + // only update if change in settings + if ( soundSystemLocal.s_muteEAXReverb.GetBool() || ( listenerEnvironmentID != EnvironmentID ) ) { + EAXREVERBPROPERTIES EnvironmentParameters; + + // get area reverb setting from EAX Manager + if ( ( effect ) && ( effect->data) && ( memcpy( &EnvironmentParameters, effect->data, effect->datasize ) ) ) { + if ( soundSystemLocal.s_muteEAXReverb.GetBool() ) { + EnvironmentParameters.lRoom = -10000; + EnvironmentID = -2; + } + if ( soundSystemLocal.alEAXSet ) { + soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_FXSlot0, EAXREVERB_ALLPARAMETERS, 0, &EnvironmentParameters, sizeof( EnvironmentParameters ) ); + } + } + listenerEnvironmentID = EnvironmentID; + } + } + } +#endif + } + + // debugging option to mute all but a single soundEmitter + if ( idSoundSystemLocal::s_singleEmitter.GetInteger() > 0 && idSoundSystemLocal::s_singleEmitter.GetInteger() < emitters.Num() ) { + sound = emitters[idSoundSystemLocal::s_singleEmitter.GetInteger()]; + + if ( sound && sound->playing ) { + // run through all the channels + for ( j = 0; j < SOUND_MAX_CHANNELS ; j++ ) { + idSoundChannel *chan = &sound->channels[j]; + + // see if we have a sound triggered on this channel + if ( !chan->triggerState ) { + chan->ALStop(); + continue; + } + + AddChannelContribution( sound, chan, current44kHz, numSpeakers, finalMixBuffer ); + } + } + return; + } + + for ( i = 1; i < emitters.Num(); i++ ) { + sound = emitters[i]; + + if ( !sound ) { + continue; + } + // if no channels are active, do nothing + if ( !sound->playing ) { + continue; + } + // run through all the channels + for ( j = 0; j < SOUND_MAX_CHANNELS ; j++ ) { + idSoundChannel *chan = &sound->channels[j]; + + // see if we have a sound triggered on this channel + if ( !chan->triggerState ) { + chan->ALStop(); + continue; + } + + AddChannelContribution( sound, chan, current44kHz, numSpeakers, finalMixBuffer ); + } + } + + if ( !idSoundSystemLocal::useOpenAL && enviroSuitActive ) { + soundSystemLocal.DoEnviroSuit( finalMixBuffer, MIXBUFFER_SAMPLES, numSpeakers ); + } +} + +//============================================================================== + +/* +=================== +idSoundWorldLocal::AVIOpen + + this is called by the main thread +=================== +*/ +void idSoundWorldLocal::AVIOpen( const char *path, const char *name ) { + aviDemoPath = path; + aviDemoName = name; + + lastAVI44kHz = game44kHz - game44kHz % MIXBUFFER_SAMPLES; + + if ( soundSystemLocal.snd_audio_hw->GetNumberOfSpeakers() == 6 ) { + fpa[0] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_left.raw" ); + fpa[1] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_right.raw" ); + fpa[2] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_center.raw" ); + fpa[3] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_lfe.raw" ); + fpa[4] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_backleft.raw" ); + fpa[5] = fileSystem->OpenFileWrite( aviDemoPath + "channel_51_backright.raw" ); + } else { + fpa[0] = fileSystem->OpenFileWrite( aviDemoPath + "channel_left.raw" ); + fpa[1] = fileSystem->OpenFileWrite( aviDemoPath + "channel_right.raw" ); + } + + soundSystemLocal.SetMute( true ); +} + +/* +=================== +idSoundWorldLocal::AVIUpdate + +this is called by the main thread +writes one block of sound samples if enough time has passed +This can be used to write wave files even if no sound hardware exists +=================== +*/ +void idSoundWorldLocal::AVIUpdate() { + int numSpeakers; + + if ( game44kHz - lastAVI44kHz < MIXBUFFER_SAMPLES ) { + return; + } + + if ( !soundSystemLocal.snd_audio_hw ) { + numSpeakers = 2; + } else { + numSpeakers = soundSystemLocal.snd_audio_hw->GetNumberOfSpeakers(); + } + + float mix[MIXBUFFER_SAMPLES*6+16]; + float *mix_p = (float *)((( int)mix + 15 ) & ~15); // SIMD align + + SIMDProcessor->Memset( mix_p, 0, MIXBUFFER_SAMPLES*sizeof(float)*numSpeakers ); + + MixLoop( lastAVI44kHz, numSpeakers, mix_p ); + + for ( int i = 0; i < numSpeakers; i++ ) { + short outD[MIXBUFFER_SAMPLES]; + + for( int j = 0; j < MIXBUFFER_SAMPLES; j++ ) { + float s = mix_p[ j*numSpeakers + i]; + if ( s < -32768.0f ) { + outD[j] = -32768; + } else if ( s > 32767.0f ) { + outD[j] = 32767; + } else { + outD[j] = idMath::FtoiFast( s ); + } + } + // write to file + fpa[i]->Write( outD, MIXBUFFER_SAMPLES*sizeof(short) ); + } + + lastAVI44kHz += MIXBUFFER_SAMPLES; + + return; +} + +/* +=================== +idSoundWorldLocal::AVIClose +=================== +*/ +void idSoundWorldLocal::AVIClose( void ) { + int i; + + if ( !fpa[0] ) { + return; + } + + // make sure the final block is written + game44kHz += MIXBUFFER_SAMPLES; + AVIUpdate(); + game44kHz -= MIXBUFFER_SAMPLES; + + for ( i = 0; i < 6; i++ ) { + if ( fpa[i] != NULL ) { + fileSystem->CloseFile( fpa[i] ); + fpa[i] = NULL; + } + } + if ( soundSystemLocal.snd_audio_hw->GetNumberOfSpeakers() == 2 ) { + // convert it to a wave file + idFile *rL, *lL, *wO; + idStr name; + + name = aviDemoPath + aviDemoName + ".wav"; + wO = fileSystem->OpenFileWrite( name ); + if ( !wO ) { + common->Error( "Couldn't write %s", name.c_str() ); + } + + name = aviDemoPath + "channel_right.raw"; + rL = fileSystem->OpenFileRead( name ); + if ( !rL ) { + common->Error( "Couldn't open %s", name.c_str() ); + } + + name = aviDemoPath + "channel_left.raw"; + lL = fileSystem->OpenFileRead( name ); + if ( !lL ) { + common->Error( "Couldn't open %s", name.c_str() ); + } + + int numSamples = rL->Length()/2; + mminfo_t info; + pcmwaveformat_t format; + + info.ckid = fourcc_riff; + info.fccType = mmioFOURCC( 'W', 'A', 'V', 'E' ); + info.cksize = (rL->Length()*2) - 8 + 4 + 16 + 8 + 8; + info.dwDataOffset = 12; + + wO->Write( &info, 12 ); + + info.ckid = mmioFOURCC( 'f', 'm', 't', ' ' ); + info.cksize = 16; + + wO->Write( &info, 8 ); + + format.wBitsPerSample = 16; + format.wf.nAvgBytesPerSec = 44100*4; // sample rate * block align + format.wf.nChannels = 2; + format.wf.nSamplesPerSec = 44100; + format.wf.wFormatTag = WAVE_FORMAT_TAG_PCM; + format.wf.nBlockAlign = 4; // channels * bits/sample / 8 + + wO->Write( &format, 16 ); + + info.ckid = mmioFOURCC( 'd', 'a', 't', 'a' ); + info.cksize = rL->Length() * 2; + + wO->Write( &info, 8 ); + + short s0, s1; + for( i = 0; i < numSamples; i++ ) { + lL->Read( &s0, 2 ); + rL->Read( &s1, 2 ); + wO->Write( &s0, 2 ); + wO->Write( &s1, 2 ); + } + + fileSystem->CloseFile( wO ); + fileSystem->CloseFile( lL ); + fileSystem->CloseFile( rL ); + + fileSystem->RemoveFile( aviDemoPath + "channel_right.raw" ); + fileSystem->RemoveFile( aviDemoPath + "channel_left.raw" ); + } + + soundSystemLocal.SetMute( false ); +} + +//============================================================================== + + +/* +=================== +idSoundWorldLocal::ResolveOrigin + +Find out of the sound is completely occluded by a closed door portal, or +the virtual sound origin position at the portal closest to the listener. + this is called by the main thread + +dist is the distance from the orignial sound origin to the current portal that enters soundArea +def->distance is the distance we are trying to reduce. + +If there is no path through open portals from the sound to the listener, def->distance will remain +set at maxDistance +=================== +*/ +static const int MAX_PORTAL_TRACE_DEPTH = 10; + +void idSoundWorldLocal::ResolveOrigin( const int stackDepth, const soundPortalTrace_t *prevStack, const int soundArea, const float dist, const idVec3& soundOrigin, idSoundEmitterLocal *def ) { + + if ( dist >= def->distance ) { + // we can't possibly hear the sound through this chain of portals + return; + } + + if ( soundArea == listenerArea ) { + float fullDist = dist + (soundOrigin - listenerQU).LengthFast(); + if ( fullDist < def->distance ) { + def->distance = fullDist; + def->spatializedOrigin = soundOrigin; + } + return; + } + + if ( stackDepth == MAX_PORTAL_TRACE_DEPTH ) { + // don't spend too much time doing these calculations in big maps + return; + } + + soundPortalTrace_t newStack; + newStack.portalArea = soundArea; + newStack.prevStack = prevStack; + + int numPortals = rw->NumPortalsInArea( soundArea ); + for( int p = 0; p < numPortals; p++ ) { + exitPortal_t re = rw->GetPortal( soundArea, p ); + + float occlusionDistance = 0; + + // air blocking windows will block sound like closed doors + if ( (re.blockingBits & ( PS_BLOCK_VIEW | PS_BLOCK_AIR ) ) ) { + // we could just completely cut sound off, but reducing the volume works better + // continue; + occlusionDistance = idSoundSystemLocal::s_doorDistanceAdd.GetFloat(); + } + + // what area are we about to go look at + int otherArea = re.areas[0]; + if ( re.areas[0] == soundArea ) { + otherArea = re.areas[1]; + } + + // if this area is already in our portal chain, don't bother looking into it + const soundPortalTrace_t *prev; + for ( prev = prevStack ; prev ; prev = prev->prevStack ) { + if ( prev->portalArea == otherArea ) { + break; + } + } + if ( prev ) { + continue; + } + + // pick a point on the portal to serve as our virtual sound origin +#if 1 + idVec3 source; + + idPlane pl; + re.w->GetPlane( pl ); + + float scale; + idVec3 dir = listenerQU - soundOrigin; + if ( !pl.RayIntersection( soundOrigin, dir, scale ) ) { + source = re.w->GetCenter(); + } else { + source = soundOrigin + scale * dir; + + // if this point isn't inside the portal edges, slide it in + for ( int i = 0 ; i < re.w->GetNumPoints() ; i++ ) { + int j = ( i + 1 ) % re.w->GetNumPoints(); + idVec3 edgeDir = (*(re.w))[j].ToVec3() - (*(re.w))[i].ToVec3(); + idVec3 edgeNormal; + + edgeNormal.Cross( pl.Normal(), edgeDir ); + + idVec3 fromVert = source - (*(re.w))[j].ToVec3(); + + float d = edgeNormal * fromVert; + if ( d > 0 ) { + // move it in + float div = edgeNormal.Normalize(); + d /= div; + + source -= d * edgeNormal; + } + } + } +#else + // clip the ray from the listener to the center of the portal by + // all the portal edge planes, then project that point (or the original if not clipped) + // onto the portal plane to get the spatialized origin + + idVec3 start = listenerQU; + idVec3 mid = re.w->GetCenter(); + bool wasClipped = false; + + for ( int i = 0 ; i < re.w->GetNumPoints() ; i++ ) { + int j = ( i + 1 ) % re.w->GetNumPoints(); + idVec3 v1 = (*(re.w))[j].ToVec3() - soundOrigin; + idVec3 v2 = (*(re.w))[i].ToVec3() - soundOrigin; + + v1.Normalize(); + v2.Normalize(); + + idVec3 edgeNormal; + + edgeNormal.Cross( v1, v2 ); + + idVec3 fromVert = start - soundOrigin; + float d1 = edgeNormal * fromVert; + + if ( d1 > 0.0f ) { + fromVert = mid - (*(re.w))[j].ToVec3(); + float d2 = edgeNormal * fromVert; + + // move it in + float f = d1 / ( d1 - d2 ); + + idVec3 clipped = start * ( 1.0f - f ) + mid * f; + start = clipped; + wasClipped = true; + } + } + + idVec3 source; + if ( wasClipped ) { + // now project it onto the portal plane + idPlane pl; + re.w->GetPlane( pl ); + + float f1 = pl.Distance( start ); + float f2 = pl.Distance( soundOrigin ); + + float f = f1 / ( f1 - f2 ); + source = start * ( 1.0f - f ) + soundOrigin * f; + } else { + source = soundOrigin; + } +#endif + + idVec3 tlen = source - soundOrigin; + float tlenLength = tlen.LengthFast(); + + ResolveOrigin( stackDepth+1, &newStack, otherArea, dist+tlenLength+occlusionDistance, source, def ); + } +} + + +/* +=================== +idSoundWorldLocal::PlaceListener + + this is called by the main thread +=================== +*/ +void idSoundWorldLocal::PlaceListener( const idVec3& origin, const idMat3& axis, + const int listenerId, const int gameTime, const idStr& areaName ) { + + int current44kHzTime; + + if ( !soundSystemLocal.isInitialized ) { + return; + } + + if ( pause44kHz >= 0 ){ + return; + } + + if ( writeDemo ) { + writeDemo->WriteInt( DS_SOUND ); + writeDemo->WriteInt( SCMD_PLACE_LISTENER ); + writeDemo->WriteVec3( origin ); + writeDemo->WriteMat3( axis ); + writeDemo->WriteInt( listenerId ); + writeDemo->WriteInt( gameTime ); + } + + current44kHzTime = soundSystemLocal.GetCurrent44kHzTime(); + + // we usually expect gameTime to be increasing by 16 or 32 msec, but when + // a cinematic is fast-forward skipped through, it can jump by a significant + // amount, while the hardware 44kHz position will not have changed accordingly, + // which would make sounds (like long character speaches) continue from the + // old time. Fix this by killing all non-looping sounds + if ( gameTime > gameMsec + 500 ) { + OffsetSoundTime( - ( gameTime - gameMsec ) * 0.001f * 44100.0f ); + } + + gameMsec = gameTime; + if ( fpa[0] ) { + // exactly 30 fps so the wave file can be used for exact video frames + game44kHz = idMath::FtoiFast( gameMsec * ( ( 1000.0f / 60.0f ) / 16.0f ) * 0.001f * 44100.0f ); + } else { + // the normal 16 msec / frame + game44kHz = idMath::FtoiFast( gameMsec * 0.001f * 44100.0f ); + } + + listenerPrivateId = listenerId; + + listenerQU = origin; // Doom units + listenerPos = origin * DOOM_TO_METERS; // meters + listenerAxis = axis; + listenerAreaName = areaName; + listenerAreaName.ToLower(); + + if ( rw ) { + listenerArea = rw->PointInArea( listenerQU ); // where are we? + } else { + listenerArea = 0; + } + + if ( listenerArea < 0 ) { + return; + } + + ForegroundUpdate( current44kHzTime ); +} + +/* +================== +idSoundWorldLocal::ForegroundUpdate +================== +*/ +void idSoundWorldLocal::ForegroundUpdate( int current44kHzTime ) { + int j, k; + idSoundEmitterLocal *def; + + if ( !soundSystemLocal.isInitialized ) { + return; + } + + Sys_EnterCriticalSection(); + + // if we are recording an AVI demo, don't use hardware time + if ( fpa[0] ) { + current44kHzTime = lastAVI44kHz; + } + + // + // check to see if each sound is visible or not + // speed up by checking maxdistance to origin + // although the sound may still need to play if it has + // just become occluded so it can ramp down to 0 + // + for ( j = 1; j < emitters.Num(); j++ ) { + def = emitters[j]; + + if ( def->removeStatus >= REMOVE_STATUS_SAMPLEFINISHED ) { + continue; + } + + // see if our last channel just finished + def->CheckForCompletion( current44kHzTime ); + + if ( !def->playing ) { + continue; + } + + // update virtual origin / distance, etc + def->Spatialize( listenerPos, listenerArea, rw ); + + // per-sound debug options + if ( idSoundSystemLocal::s_drawSounds.GetInteger() && rw ) { + if ( def->distance < def->maxDistance || idSoundSystemLocal::s_drawSounds.GetInteger() > 1 ) { + idBounds ref; + ref.Clear(); + ref.AddPoint( idVec3( -10, -10, -10 ) ); + ref.AddPoint( idVec3( 10, 10, 10 ) ); + float vis = (1.0f - (def->distance / def->maxDistance)); + + // draw a box + rw->DebugBounds( idVec4( vis, 0.25f, vis, vis ), ref, def->origin ); + + // draw an arrow to the audible position, possible a portal center + if ( def->origin != def->spatializedOrigin ) { + rw->DebugArrow( colorRed, def->origin, def->spatializedOrigin, 4 ); + } + + // draw the index + idVec3 textPos = def->origin; + textPos[2] -= 8; + rw->DrawText( va("%i", def->index), textPos, 0.1f, idVec4(1,0,0,1), listenerAxis ); + textPos[2] += 8; + + // run through all the channels + for ( k = 0; k < SOUND_MAX_CHANNELS ; k++ ) { + idSoundChannel *chan = &def->channels[k]; + + // see if we have a sound triggered on this channel + if ( !chan->triggerState ) { + continue; + } + + char text[1024]; + float min = chan->parms.minDistance; + float max = chan->parms.maxDistance; + const char *defaulted = chan->leadinSample->defaultSound ? "(DEFAULTED)" : ""; + sprintf( text, "%s (%i/%i %i/%i)%s", chan->soundShader->GetName(), (int)def->distance, + (int)def->realDistance, (int)min, (int)max, defaulted ); + rw->DrawText( text, textPos, 0.1f, idVec4(1,0,0,1), listenerAxis ); + textPos[2] += 8; + } + } + } + } + + Sys_LeaveCriticalSection(); + + // + // the sound meter + // + if ( idSoundSystemLocal::s_showLevelMeter.GetInteger() ) { + const idMaterial *gui = declManager->FindMaterial( "guis/assets/soundmeter/audiobg", false ); + if ( gui ) { + const shaderStage_t *foo = gui->GetStage(0); + if ( !foo->texture.cinematic ) { + ((shaderStage_t *)foo)->texture.cinematic = new idSndWindow; + } + } + } + + // + // optionally dump out the generated sound + // + if ( fpa[0] ) { + AVIUpdate(); + } +} + +/* +=================== +idSoundWorldLocal::OffsetSoundTime +=================== +*/ +void idSoundWorldLocal::OffsetSoundTime( int offset44kHz ) { + int i, j; + + for ( i = 0; i < emitters.Num(); i++ ) { + if ( emitters[i] == NULL ) { + continue; + } + for ( j = 0; j < SOUND_MAX_CHANNELS; j++ ) { + idSoundChannel *chan = &emitters[i]->channels[ j ]; + + if ( !chan->triggerState ) { + continue; + } + + chan->trigger44kHzTime += offset44kHz; + } + } +} + +/* +=================== +idSoundWorldLocal::WriteToSaveGame +=================== +*/ +void idSoundWorldLocal::WriteToSaveGame( idFile *savefile ) { + int i, j, num, currentSoundTime; + const char *name; + + // the game soundworld is always paused at this point, save that time down + if ( pause44kHz > 0 ) { + currentSoundTime = pause44kHz; + } else { + currentSoundTime = soundSystemLocal.GetCurrent44kHzTime(); + } + + // write listener data + savefile->WriteVec3(listenerQU); + savefile->WriteMat3(listenerAxis); + savefile->WriteInt(listenerPrivateId); + savefile->WriteInt(gameMsec); + savefile->WriteInt(game44kHz); + savefile->WriteInt(currentSoundTime); + + num = emitters.Num(); + savefile->WriteInt(num); + + for ( i = 1; i < emitters.Num(); i++ ) { + idSoundEmitterLocal *def = emitters[i]; + + if ( def->removeStatus != REMOVE_STATUS_ALIVE ) { + int skip = -1; + savefile->Write( &skip, sizeof( skip ) ); + continue; + } + + savefile->WriteInt(i); + + // Write the emitter data + savefile->WriteVec3( def->origin ); + savefile->WriteInt( def->listenerId ); + WriteToSaveGameSoundShaderParams( savefile, &def->parms ); + savefile->WriteFloat( def->amplitude ); + savefile->WriteInt( def->ampTime ); + for (int k = 0; k < SOUND_MAX_CHANNELS; k++) + WriteToSaveGameSoundChannel( savefile, &def->channels[k] ); + savefile->WriteFloat( def->distance ); + savefile->WriteBool( def->hasShakes ); + savefile->WriteInt( def->lastValidPortalArea ); + savefile->WriteFloat( def->maxDistance ); + savefile->WriteBool( def->playing ); + savefile->WriteFloat( def->realDistance ); + savefile->WriteInt( def->removeStatus ); + savefile->WriteVec3( def->spatializedOrigin ); + + // write the channel data + for( j = 0; j < SOUND_MAX_CHANNELS; j++ ) { + idSoundChannel *chan = &def->channels[ j ]; + + // Write out any sound commands for this def + if ( chan->triggerState && chan->soundShader && chan->leadinSample ) { + + savefile->WriteInt( j ); + + // write the pointers out separately + name = chan->soundShader->GetName(); + savefile->WriteString( name ); + + name = chan->leadinSample->name; + savefile->WriteString( name ); + } + } + + // End active channels with -1 + int end = -1; + savefile->WriteInt( end ); + } + + // new in Doom3 v1.2 + savefile->Write( &slowmoActive, sizeof( slowmoActive ) ); + savefile->Write( &slowmoSpeed, sizeof( slowmoSpeed ) ); + savefile->Write( &enviroSuitActive, sizeof( enviroSuitActive ) ); +} + +/* + =================== + idSoundWorldLocal::WriteToSaveGameSoundShaderParams + =================== + */ +void idSoundWorldLocal::WriteToSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ) { + saveGame->WriteFloat(params->minDistance); + saveGame->WriteFloat(params->maxDistance); + saveGame->WriteFloat(params->volume); + saveGame->WriteFloat(params->shakes); + saveGame->WriteInt(params->soundShaderFlags); + saveGame->WriteInt(params->soundClass); +} + +/* + =================== + idSoundWorldLocal::WriteToSaveGameSoundChannel + =================== + */ +void idSoundWorldLocal::WriteToSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ) { + saveGame->WriteBool( ch->triggerState ); + saveGame->WriteUnsignedChar( 0 ); + saveGame->WriteUnsignedChar( 0 ); + saveGame->WriteUnsignedChar( 0 ); + saveGame->WriteInt( ch->trigger44kHzTime ); + saveGame->WriteInt( ch->triggerGame44kHzTime ); + WriteToSaveGameSoundShaderParams( saveGame, &ch->parms ); + saveGame->WriteInt( (int)ch->leadinSample ); + saveGame->WriteInt( ch->triggerChannel ); + saveGame->WriteInt( (int)ch->soundShader ); + saveGame->WriteInt( (int)ch->decoder ); + saveGame->WriteFloat(ch->diversity ); + saveGame->WriteFloat(ch->lastVolume ); + for (int m = 0; m < 6; m++) + saveGame->WriteFloat( ch->lastV[m] ); + saveGame->WriteInt( ch->channelFade.fadeStart44kHz ); + saveGame->WriteInt( ch->channelFade.fadeEnd44kHz ); + saveGame->WriteFloat( ch->channelFade.fadeStartVolume ); + saveGame->WriteFloat( ch->channelFade.fadeEndVolume ); +} + +/* +=================== +idSoundWorldLocal::ReadFromSaveGame +=================== +*/ +void idSoundWorldLocal::ReadFromSaveGame( idFile *savefile ) { + int i, num, handle, listenerId, gameTime, channel; + int savedSoundTime, currentSoundTime, soundTimeOffset; + idSoundEmitterLocal *def; + idVec3 origin; + idMat3 axis; + idStr soundShader; + + ClearAllSoundEmitters(); + + savefile->ReadVec3( origin ); + savefile->ReadMat3( axis ); + savefile->ReadInt( listenerId ); + savefile->ReadInt( gameTime ); + savefile->ReadInt( game44kHz ); + savefile->ReadInt( savedSoundTime ); + + // we will adjust the sound starting times from those saved with the demo + currentSoundTime = soundSystemLocal.GetCurrent44kHzTime(); + soundTimeOffset = currentSoundTime - savedSoundTime; + + // at the end of the level load we unpause the sound world and adjust the sound starting times once more + pause44kHz = currentSoundTime; + + // place listener + PlaceListener( origin, axis, listenerId, gameTime, "Undefined" ); + + // make sure there are enough + // slots to read the saveGame in. We don't shrink the list + // if there are extras. + savefile->ReadInt( num ); + + while( emitters.Num() < num ) { + def = new idSoundEmitterLocal; + def->index = emitters.Append( def ); + def->soundWorld = this; + } + + // read in the state + for ( i = 1; i < num; i++ ) { + + savefile->ReadInt( handle ); + if ( handle < 0 ) { + continue; + } + if ( handle != i ) { + common->Error( "idSoundWorldLocal::ReadFromSaveGame: index mismatch" ); + } + def = emitters[i]; + + def->removeStatus = REMOVE_STATUS_ALIVE; + def->playing = true; // may be reset by the first UpdateListener + + savefile->ReadVec3( def->origin ); + savefile->ReadInt( def->listenerId ); + ReadFromSaveGameSoundShaderParams( savefile, &def->parms ); + savefile->ReadFloat( def->amplitude ); + savefile->ReadInt( def->ampTime ); + for (int k = 0; k < SOUND_MAX_CHANNELS; k++) + ReadFromSaveGameSoundChannel( savefile, &def->channels[k] ); + savefile->ReadFloat( def->distance ); + savefile->ReadBool( def->hasShakes ); + savefile->ReadInt( def->lastValidPortalArea ); + savefile->ReadFloat( def->maxDistance ); + savefile->ReadBool( def->playing ); + savefile->ReadFloat( def->realDistance ); + savefile->ReadInt( (int&)def->removeStatus ); + savefile->ReadVec3( def->spatializedOrigin ); + + // read the individual channels + savefile->ReadInt( channel ); + + while ( channel >= 0 ) { + if ( channel > SOUND_MAX_CHANNELS ) { + common->Error( "idSoundWorldLocal::ReadFromSaveGame: channel > SOUND_MAX_CHANNELS" ); + } + + idSoundChannel *chan = &def->channels[channel]; + + if ( chan->decoder != NULL ) { + // The pointer in the save file is not valid, so we grab a new one + chan->decoder = idSampleDecoder::Alloc(); + } + + savefile->ReadString( soundShader ); + chan->soundShader = declManager->FindSound( soundShader ); + + savefile->ReadString( soundShader ); + // load savegames with s_noSound 1 + if ( soundSystemLocal.soundCache ) { + chan->leadinSample = soundSystemLocal.soundCache->FindSound( soundShader, false ); + } else { + chan->leadinSample = NULL; + } + + // adjust the hardware start time + chan->trigger44kHzTime += soundTimeOffset; + + // make sure we start up the hardware voice if needed + chan->triggered = chan->triggerState; + chan->openalStreamingOffset = currentSoundTime - chan->trigger44kHzTime; + + // adjust the hardware fade time + if ( chan->channelFade.fadeStart44kHz != 0 ) { + chan->channelFade.fadeStart44kHz += soundTimeOffset; + chan->channelFade.fadeEnd44kHz += soundTimeOffset; + } + + // next command + savefile->ReadInt( channel ); + } + } + + if ( session->GetSaveGameVersion() >= 17 ) { + savefile->Read( &slowmoActive, sizeof( slowmoActive ) ); + savefile->Read( &slowmoSpeed, sizeof( slowmoSpeed ) ); + savefile->Read( &enviroSuitActive, sizeof( enviroSuitActive ) ); + } else { + slowmoActive = false; + slowmoSpeed = 0; + enviroSuitActive = false; + } +} + +/* + =================== + idSoundWorldLocal::ReadFromSaveGameSoundShaderParams + =================== + */ +void idSoundWorldLocal::ReadFromSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ) { + saveGame->ReadFloat(params->minDistance); + saveGame->ReadFloat(params->maxDistance); + saveGame->ReadFloat(params->volume); + saveGame->ReadFloat(params->shakes); + saveGame->ReadInt(params->soundShaderFlags); + saveGame->ReadInt(params->soundClass); +} + +/* + =================== + idSoundWorldLocal::ReadFromSaveGameSoundChannel + =================== + */ +void idSoundWorldLocal::ReadFromSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ) { + saveGame->ReadBool( ch->triggerState ); + char tmp; + saveGame->ReadChar( tmp ); + saveGame->ReadChar( tmp ); + saveGame->ReadChar( tmp ); + saveGame->ReadInt( ch->trigger44kHzTime ); + saveGame->ReadInt( ch->triggerGame44kHzTime ); + ReadFromSaveGameSoundShaderParams( saveGame, &ch->parms ); + saveGame->ReadInt( (int&)ch->leadinSample ); + saveGame->ReadInt( ch->triggerChannel ); + saveGame->ReadInt( (int&)ch->soundShader ); + saveGame->ReadInt( (int&)ch->decoder ); + saveGame->ReadFloat(ch->diversity ); + saveGame->ReadFloat(ch->lastVolume ); + for (int m = 0; m < 6; m++) + saveGame->ReadFloat( ch->lastV[m] ); + saveGame->ReadInt( ch->channelFade.fadeStart44kHz ); + saveGame->ReadInt( ch->channelFade.fadeEnd44kHz ); + saveGame->ReadFloat( ch->channelFade.fadeStartVolume ); + saveGame->ReadFloat( ch->channelFade.fadeEndVolume ); +} + +/* +=================== +idSoundWorldLocal::EmitterForIndex +=================== +*/ +idSoundEmitter *idSoundWorldLocal::EmitterForIndex( int index ) { + if ( index == 0 ) { + return NULL; + } + if ( index >= emitters.Num() ) { + common->Error( "idSoundWorldLocal::EmitterForIndex: %i > %i", index, emitters.Num() ); + } + return emitters[index]; +} + +/* +=============== +idSoundWorldLocal::StopAllSounds + + this is called from the main thread +=============== +*/ +void idSoundWorldLocal::StopAllSounds() { + + for ( int i = 0; i < emitters.Num(); i++ ) { + idSoundEmitterLocal * def = emitters[i]; + def->StopSound( SCHANNEL_ANY ); + } +} + +/* +=============== +idSoundWorldLocal::Pause +=============== +*/ +void idSoundWorldLocal::Pause( void ) { + if ( pause44kHz >= 0 ) { + common->Warning( "idSoundWorldLocal::Pause: already paused" ); + return; + } + + pause44kHz = soundSystemLocal.GetCurrent44kHzTime(); +} + +/* +=============== +idSoundWorldLocal::UnPause +=============== +*/ +void idSoundWorldLocal::UnPause( void ) { + int offset44kHz; + + if ( pause44kHz < 0 ) { + common->Warning( "idSoundWorldLocal::UnPause: not paused" ); + return; + } + + offset44kHz = soundSystemLocal.GetCurrent44kHzTime() - pause44kHz; + OffsetSoundTime( offset44kHz ); + + pause44kHz = -1; +} + +/* +=============== +idSoundWorldLocal::IsPaused +=============== +*/ +bool idSoundWorldLocal::IsPaused( void ) { + return ( pause44kHz >= 0 ); +} + +/* +=============== +idSoundWorldLocal::PlayShaderDirectly + +start a music track + + this is called from the main thread +=============== +*/ +void idSoundWorldLocal::PlayShaderDirectly( const char *shaderName, int channel ) { + + if ( localSound && channel == -1 ) { + localSound->StopSound( SCHANNEL_ANY ); + } else if ( localSound ) { + localSound->StopSound( channel ); + } + + if ( !shaderName || !shaderName[0] ) { + return; + } + + const idSoundShader *shader = declManager->FindSound( shaderName ); + if ( !shader ) { + return; + } + + if ( !localSound ) { + localSound = AllocLocalSoundEmitter(); + } + + static idRandom rnd; + float diversity = rnd.RandomFloat(); + + localSound->StartSound( shader, ( channel == -1 ) ? SCHANNEL_ONE : channel , diversity, SSF_GLOBAL ); + + // in case we are at the console without a game doing updates, force an update + ForegroundUpdate( soundSystemLocal.GetCurrent44kHzTime() ); +} + +/* +=============== +idSoundWorldLocal::CalcEars + +Determine the volumes from each speaker for a given sound emitter +=============== +*/ +void idSoundWorldLocal::CalcEars( int numSpeakers, idVec3 spatializedOrigin, idVec3 listenerPos, + idMat3 listenerAxis, float ears[6], float spatialize ) { + idVec3 svec = spatializedOrigin - listenerPos; + idVec3 ovec; + + ovec[0] = svec * listenerAxis[0]; + ovec[1] = svec * listenerAxis[1]; + ovec[2] = svec * listenerAxis[2]; + + ovec.Normalize(); + + if ( numSpeakers == 6 ) { + static idVec3 speakerVector[6] = { + idVec3( 0.707f, 0.707f, 0.0f ), // front left + idVec3( 0.707f, -0.707f, 0.0f ), // front right + idVec3( 0.707f, 0.0f, 0.0f ), // front center + idVec3( 0.0f, 0.0f, 0.0f ), // sub + idVec3( -0.707f, 0.707f, 0.0f ), // rear left + idVec3( -0.707f, -0.707f, 0.0f ) // rear right + }; + for ( int i = 0 ; i < 6 ; i++ ) { + if ( i == 3 ) { + ears[i] = idSoundSystemLocal::s_subFraction.GetFloat(); // subwoofer + continue; + } + float dot = ovec * speakerVector[i]; + ears[i] = (idSoundSystemLocal::s_dotbias6.GetFloat() + dot) / ( 1.0f + idSoundSystemLocal::s_dotbias6.GetFloat() ); + if ( ears[i] < idSoundSystemLocal::s_minVolume6.GetFloat() ) { + ears[i] = idSoundSystemLocal::s_minVolume6.GetFloat(); + } + } + } else { + float dot = ovec.y; + float dotBias = idSoundSystemLocal::s_dotbias2.GetFloat(); + + // when we are inside the minDistance, start reducing the amount of spatialization + // so NPC voices right in front of us aren't quieter that off to the side + dotBias += ( idSoundSystemLocal::s_spatializationDecay.GetFloat() - dotBias ) * ( 1.0f - spatialize ); + + ears[0] = (idSoundSystemLocal::s_dotbias2.GetFloat() + dot) / ( 1.0f + dotBias ); + ears[1] = (idSoundSystemLocal::s_dotbias2.GetFloat() - dot) / ( 1.0f + dotBias ); + + if ( ears[0] < idSoundSystemLocal::s_minVolume2.GetFloat() ) { + ears[0] = idSoundSystemLocal::s_minVolume2.GetFloat(); + } + if ( ears[1] < idSoundSystemLocal::s_minVolume2.GetFloat() ) { + ears[1] = idSoundSystemLocal::s_minVolume2.GetFloat(); + } + + ears[2] = + ears[3] = + ears[4] = + ears[5] = 0.0f; + } +} + +/* +=============== +idSoundWorldLocal::AddChannelContribution + +Adds the contribution of a single sound channel to finalMixBuffer +this is called from the async thread + +Mixes MIXBUFFER_SAMPLES samples starting at current44kHz sample time into +finalMixBuffer +=============== +*/ +void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSoundChannel *chan, + int current44kHz, int numSpeakers, float *finalMixBuffer ) { + int j; + float volume; + + // + // get the sound definition and parameters from the entity + // + soundShaderParms_t *parms = &chan->parms; + + // assume we have a sound triggered on this channel + assert( chan->triggerState ); + + // fetch the actual wave file and see if it's valid + idSoundSample *sample = chan->leadinSample; + if ( sample == NULL ) { + return; + } + + // if you don't want to hear all the beeps from missing sounds + if ( sample->defaultSound && !idSoundSystemLocal::s_playDefaultSound.GetBool() ) { + return; + } + + // get the actual shader + const idSoundShader *shader = chan->soundShader; + + // this might happen if the foreground thread just deleted the sound emitter + if ( !shader ) { + return; + } + + float maxd = parms->maxDistance; + float mind = parms->minDistance; + + int mask = shader->speakerMask; + bool omni = ( parms->soundShaderFlags & SSF_OMNIDIRECTIONAL) != 0; + bool looping = ( parms->soundShaderFlags & SSF_LOOPING ) != 0; + bool global = ( parms->soundShaderFlags & SSF_GLOBAL ) != 0; + bool noOcclusion = ( parms->soundShaderFlags & SSF_NO_OCCLUSION ) || !idSoundSystemLocal::s_useOcclusion.GetBool(); + + // speed goes from 1 to 0.2 + if ( idSoundSystemLocal::s_slowAttenuate.GetBool() && slowmoActive && !chan->disallowSlow ) { + maxd *= slowmoSpeed; + } + + // stereo samples are always omni + if ( sample->objectInfo.nChannels == 2 ) { + omni = true; + } + + // if the sound is playing from the current listener, it will not be spatialized at all + if ( sound->listenerId == listenerPrivateId ) { + global = true; + } + + // + // see if it's in range + // + + // convert volumes from decibels to float scale + + // leadin volume scale for shattering lights + // this isn't exactly correct, because the modified volume will get applied to + // some initial chunk of the loop as well, because the volume is scaled for the + // entire mix buffer + if ( shader->leadinVolume && current44kHz - chan->trigger44kHzTime < sample->LengthIn44kHzSamples() ) { + volume = soundSystemLocal.dB2Scale( shader->leadinVolume ); + } else { + volume = soundSystemLocal.dB2Scale( parms->volume ); + } + + // global volume scale + volume *= soundSystemLocal.dB2Scale( idSoundSystemLocal::s_volume.GetFloat() ); + + + // volume fading + float fadeDb = chan->channelFade.FadeDbAt44kHz( current44kHz ); + volume *= soundSystemLocal.dB2Scale( fadeDb ); + + fadeDb = soundClassFade[parms->soundClass].FadeDbAt44kHz( current44kHz ); + volume *= soundSystemLocal.dB2Scale( fadeDb ); + + + // + // if it's a global sound then + // it's not affected by distance or occlusion + // + float spatialize = 1; + idVec3 spatializedOriginInMeters; + if ( !global ) { + float dlen; + + if ( noOcclusion ) { + // use the real origin and distance + spatializedOriginInMeters = sound->origin * DOOM_TO_METERS; + dlen = sound->realDistance; + } else { + // use the possibly portal-occluded origin and distance + spatializedOriginInMeters = sound->spatializedOrigin * DOOM_TO_METERS; + dlen = sound->distance; + } + + // reduce volume based on distance + if ( dlen >= maxd ) { + volume = 0.0f; + } else if ( dlen > mind ) { + float frac = idMath::ClampFloat( 0.0f, 1.0f, 1.0f - ((dlen - mind) / (maxd - mind))); + if ( idSoundSystemLocal::s_quadraticFalloff.GetBool() ) { + frac *= frac; + } + volume *= frac; + } else if ( mind > 0.0f ) { + // we tweak the spatialization bias when you are inside the minDistance + spatialize = dlen / mind; + } + } + + // + // if it is a private sound, set the volume to zero + // unless we match the listenerId + // + if ( parms->soundShaderFlags & SSF_PRIVATE_SOUND ) { + if ( sound->listenerId != listenerPrivateId ) { + volume = 0; + } + } + if ( parms->soundShaderFlags & SSF_ANTI_PRIVATE_SOUND ) { + if ( sound->listenerId == listenerPrivateId ) { + volume = 0; + } + } + + // + // do we have anything to add? + // + if ( volume < SND_EPSILON && chan->lastVolume < SND_EPSILON ) { + return; + } + chan->lastVolume = volume; + + // + // fetch the sound from the cache as 44kHz, 16 bit samples + // + int offset = current44kHz - chan->trigger44kHzTime; + float inputSamples[MIXBUFFER_SAMPLES*2+16]; + float *alignedInputSamples = (float *) ( ( ( (int)inputSamples ) + 15 ) & ~15 ); + + // + // allocate and initialize hardware source + // + if ( idSoundSystemLocal::useOpenAL && sound->removeStatus < REMOVE_STATUS_SAMPLEFINISHED ) { + if ( !alIsSource( chan->openalSource ) ) { + chan->openalSource = soundSystemLocal.AllocOpenALSource( chan, !chan->leadinSample->hardwareBuffer || !chan->soundShader->entries[0]->hardwareBuffer || looping, chan->leadinSample->objectInfo.nChannels == 2 ); + } + + if ( alIsSource( chan->openalSource ) ) { + + // stop source if needed.. + if ( chan->triggered ) { + alSourceStop( chan->openalSource ); + } + + // update source parameters + if ( global || omni ) { + alSourcei( chan->openalSource, AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f( chan->openalSource, AL_POSITION, 0.0f, 0.0f, 0.0f ); + alSourcef( chan->openalSource, AL_GAIN, ( volume ) < ( 1.0f ) ? ( volume ) : ( 1.0f ) ); + } else { + alSourcei( chan->openalSource, AL_SOURCE_RELATIVE, AL_FALSE); + alSource3f( chan->openalSource, AL_POSITION, -spatializedOriginInMeters.y, spatializedOriginInMeters.z, -spatializedOriginInMeters.x ); + alSourcef( chan->openalSource, AL_GAIN, ( volume ) < ( 1.0f ) ? ( volume ) : ( 1.0f ) ); + } + alSourcei( chan->openalSource, AL_LOOPING, ( looping && chan->soundShader->entries[0]->hardwareBuffer ) ? AL_TRUE : AL_FALSE ); +#if !defined(MACOS_X) + alSourcef( chan->openalSource, AL_REFERENCE_DISTANCE, mind ); + alSourcef( chan->openalSource, AL_MAX_DISTANCE, maxd ); +#endif + alSourcef( chan->openalSource, AL_PITCH, ( slowmoActive && !chan->disallowSlow ) ? ( slowmoSpeed ) : ( 1.0f ) ); +#if ID_OPENAL + long lOcclusion = ( enviroSuitActive ? -1150 : 0); + if ( soundSystemLocal.alEAXSet ) { + soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_OCCLUSION, chan->openalSource, &lOcclusion, sizeof(lOcclusion) ); + } +#endif + if ( ( !looping && chan->leadinSample->hardwareBuffer ) || ( looping && chan->soundShader->entries[0]->hardwareBuffer ) ) { + // handle uncompressed (non streaming) single shot and looping sounds + if ( chan->triggered ) { + alSourcei( chan->openalSource, AL_BUFFER, looping ? chan->soundShader->entries[0]->openalBuffer : chan->leadinSample->openalBuffer ); + } + } else { + ALint finishedbuffers; + ALuint buffers[3]; + + // handle streaming sounds (decode on the fly) both single shot AND looping + if ( chan->triggered ) { + alSourcei( chan->openalSource, AL_BUFFER, NULL ); + alDeleteBuffers( 3, &chan->lastopenalStreamingBuffer[0] ); + chan->lastopenalStreamingBuffer[0] = chan->openalStreamingBuffer[0]; + chan->lastopenalStreamingBuffer[1] = chan->openalStreamingBuffer[1]; + chan->lastopenalStreamingBuffer[2] = chan->openalStreamingBuffer[2]; + alGenBuffers( 3, &chan->openalStreamingBuffer[0] ); + if ( soundSystemLocal.alEAXSetBufferMode ) { + soundSystemLocal.alEAXSetBufferMode( 3, &chan->openalStreamingBuffer[0], alGetEnumValue( ID_ALCHAR "AL_STORAGE_ACCESSIBLE" ) ); + } + buffers[0] = chan->openalStreamingBuffer[0]; + buffers[1] = chan->openalStreamingBuffer[1]; + buffers[2] = chan->openalStreamingBuffer[2]; + finishedbuffers = 3; + } else { + alGetSourcei( chan->openalSource, AL_BUFFERS_PROCESSED, &finishedbuffers ); + alSourceUnqueueBuffers( chan->openalSource, finishedbuffers, &buffers[0] ); + if ( finishedbuffers == 3 ) { + chan->triggered = true; + } + } + + for ( j = 0; j < finishedbuffers; j++ ) { + chan->GatherChannelSamples( chan->openalStreamingOffset * sample->objectInfo.nChannels, MIXBUFFER_SAMPLES * sample->objectInfo.nChannels, alignedInputSamples ); + for ( int i = 0; i < ( MIXBUFFER_SAMPLES * sample->objectInfo.nChannels ); i++ ) { + if ( alignedInputSamples[i] < -32768.0f ) + ((short *)alignedInputSamples)[i] = -32768; + else if ( alignedInputSamples[i] > 32767.0f ) + ((short *)alignedInputSamples)[i] = 32767; + else + ((short *)alignedInputSamples)[i] = idMath::FtoiFast( alignedInputSamples[i] ); + } + alBufferData( buffers[j], chan->leadinSample->objectInfo.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, alignedInputSamples, MIXBUFFER_SAMPLES * sample->objectInfo.nChannels * sizeof( short ), 44100 ); + chan->openalStreamingOffset += MIXBUFFER_SAMPLES; + } + + if ( finishedbuffers ) { + alSourceQueueBuffers( chan->openalSource, finishedbuffers, &buffers[0] ); + } + } + + // (re)start if needed.. + if ( chan->triggered ) { + alSourcePlay( chan->openalSource ); + chan->triggered = false; + } + } + } else { + + if ( slowmoActive && !chan->disallowSlow ) { + idSlowChannel slow = sound->GetSlowChannel( chan ); + + slow.AttachSoundChannel( chan ); + + if ( sample->objectInfo.nChannels == 2 ) { + // need to add a stereo path, but very few samples go through this + memset( alignedInputSamples, 0, sizeof( alignedInputSamples[0] ) * MIXBUFFER_SAMPLES * 2 ); + } else { + slow.GatherChannelSamples( offset, MIXBUFFER_SAMPLES, alignedInputSamples ); + } + + sound->SetSlowChannel( chan, slow ); + } else { + sound->ResetSlowChannel( chan ); + + // if we are getting a stereo sample adjust accordingly + if ( sample->objectInfo.nChannels == 2 ) { + // we should probably check to make sure any looping is also to a stereo sample... + chan->GatherChannelSamples( offset*2, MIXBUFFER_SAMPLES*2, alignedInputSamples ); + } else { + chan->GatherChannelSamples( offset, MIXBUFFER_SAMPLES, alignedInputSamples ); + } + } + + // + // work out the left / right ear values + // + float ears[6]; + if ( global || omni ) { + // same for all speakers + for ( int i = 0 ; i < 6 ; i++ ) { + ears[i] = idSoundSystemLocal::s_globalFraction.GetFloat() * volume; + } + ears[3] = idSoundSystemLocal::s_subFraction.GetFloat() * volume; // subwoofer + + } else { + CalcEars( numSpeakers, spatializedOriginInMeters, listenerPos, listenerAxis, ears, spatialize ); + + for ( int i = 0 ; i < 6 ; i++ ) { + ears[i] *= volume; + } + } + + // if the mask is 0, it really means do every channel + if ( !mask ) { + mask = 255; + } + // cleared mask bits set the mix volume to zero + for ( int i = 0 ; i < 6 ; i++ ) { + if ( !(mask & ( 1 << i ) ) ) { + ears[i] = 0; + } + } + + // if sounds are generally normalized, using a mixing volume over 1.0 will + // almost always cause clipping noise. If samples aren't normalized, there + // is a good call to allow overvolumes + if ( idSoundSystemLocal::s_clipVolumes.GetBool() && !( parms->soundShaderFlags & SSF_UNCLAMPED ) ) { + for ( int i = 0 ; i < 6 ; i++ ) { + if ( ears[i] > 1.0f ) { + ears[i] = 1.0f; + } + } + } + + // if this is the very first mixing block, set the lastV + // to the current volume + if ( current44kHz == chan->trigger44kHzTime ) { + for ( j = 0 ; j < 6 ; j++ ) { + chan->lastV[j] = ears[j]; + } + } + + if ( numSpeakers == 6 ) { + if ( sample->objectInfo.nChannels == 1 ) { + SIMDProcessor->MixSoundSixSpeakerMono( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears ); + } else { + SIMDProcessor->MixSoundSixSpeakerStereo( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears ); + } + } else { + if ( sample->objectInfo.nChannels == 1 ) { + SIMDProcessor->MixSoundTwoSpeakerMono( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears ); + } else { + SIMDProcessor->MixSoundTwoSpeakerStereo( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears ); + } + } + + for ( j = 0 ; j < 6 ; j++ ) { + chan->lastV[j] = ears[j]; + } + + } + + soundSystemLocal.soundStats.activeSounds++; + +} + +/* +=============== +idSoundWorldLocal::FindAmplitude + + this is called from the main thread + + if listenerPosition is NULL, this is being used for shader parameters, + like flashing lights and glows based on sound level. Otherwise, it is being used for + the screen-shake on a player. + + This doesn't do the portal-occlusion currently, because it would have to reset all the defs + which would be problematic in multiplayer +=============== +*/ +float idSoundWorldLocal::FindAmplitude( idSoundEmitterLocal *sound, const int localTime, const idVec3 *listenerPosition, + const s_channelType channel, bool shakesOnly ) { + int i, j; + soundShaderParms_t *parms; + float volume; + int activeChannelCount; + static const int AMPLITUDE_SAMPLES = MIXBUFFER_SAMPLES/8; + float sourceBuffer[AMPLITUDE_SAMPLES]; + float sumBuffer[AMPLITUDE_SAMPLES]; + // work out the distance from the listener to the emitter + float dlen; + + if ( !sound->playing ) { + return 0; + } + + if ( listenerPosition ) { + // this doesn't do the portal spatialization + idVec3 dist = sound->origin - *listenerPosition; + dlen = dist.Length(); + dlen *= DOOM_TO_METERS; + } else { + dlen = 1; + } + + activeChannelCount = 0; + + for ( i = 0; i < SOUND_MAX_CHANNELS ; i++ ) { + idSoundChannel *chan = &sound->channels[ i ]; + + if ( !chan->triggerState ) { + continue; + } + + if ( channel != SCHANNEL_ANY && chan->triggerChannel != channel) { + continue; + } + + parms = &chan->parms; + + int localTriggerTimes = chan->trigger44kHzTime; + + bool looping = ( parms->soundShaderFlags & SSF_LOOPING ) != 0; + + // check for screen shakes + float shakes = parms->shakes; + if ( shakesOnly && shakes <= 0.0f ) { + continue; + } + + // + // calculate volume + // + if ( !listenerPosition ) { + // just look at the raw wav data for light shader evaluation + volume = 1.0; + } else { + volume = parms->volume; + volume = soundSystemLocal.dB2Scale( volume ); + if ( shakesOnly ) { + volume *= shakes; + } + + if ( listenerPosition && !( parms->soundShaderFlags & SSF_GLOBAL ) ) { + // check for overrides + float maxd = parms->maxDistance; + float mind = parms->minDistance; + + if ( dlen >= maxd ) { + volume = 0.0f; + } else if ( dlen > mind ) { + float frac = idMath::ClampFloat( 0, 1, 1.0f - ((dlen - mind) / (maxd - mind))); + if ( idSoundSystemLocal::s_quadraticFalloff.GetBool() ) { + frac *= frac; + } + volume *= frac; + } + } + } + + if ( volume <= 0 ) { + continue; + } + + // + // fetch the sound from the cache + // this doesn't handle stereo samples correctly... + // + if ( !listenerPosition && chan->parms.soundShaderFlags & SSF_NO_FLICKER ) { + // the NO_FLICKER option is to allow a light to still play a sound, but + // not have it effect the intensity + for ( j = 0 ; j < (AMPLITUDE_SAMPLES); j++ ) { + sourceBuffer[j] = j & 1 ? 32767.0f : -32767.0f; + } + } else { + int offset = (localTime - localTriggerTimes); // offset in samples + int size = ( looping ? chan->soundShader->entries[0]->LengthIn44kHzSamples() : chan->leadinSample->LengthIn44kHzSamples() ); + short *amplitudeData = (short *)( looping ? chan->soundShader->entries[0]->amplitudeData : chan->leadinSample->amplitudeData ); + + if ( amplitudeData ) { + // when the amplitudeData is present use that fill a dummy sourceBuffer + // this is to allow for amplitude based effect on hardware audio solutions + if ( looping ) offset %= size; + if ( offset < size ) { + for ( j = 0 ; j < (AMPLITUDE_SAMPLES); j++ ) { + sourceBuffer[j] = j & 1 ? amplitudeData[ ( offset / 512 ) * 2 ] : amplitudeData[ ( offset / 512 ) * 2 + 1 ]; + } + } + } else { + // get actual sample data + chan->GatherChannelSamples( offset, AMPLITUDE_SAMPLES, sourceBuffer ); + } + } + activeChannelCount++; + if ( activeChannelCount == 1 ) { + // store to the buffer + for( j = 0; j < AMPLITUDE_SAMPLES; j++ ) { + sumBuffer[ j ] = volume * sourceBuffer[ j ]; + } + } else { + // add to the buffer + for( j = 0; j < AMPLITUDE_SAMPLES; j++ ) { + sumBuffer[ j ] += volume * sourceBuffer[ j ]; + } + } + } + + if ( activeChannelCount == 0 ) { + return 0.0; + } + + float high = -32767.0f; + float low = 32767.0f; + + // use a 20th of a second + for( i = 0; i < (AMPLITUDE_SAMPLES); i++ ) { + float fabval = sumBuffer[i]; + if ( high < fabval ) { + high = fabval; + } + if ( low > fabval ) { + low = fabval; + } + } + + float sout; + sout = atan( (high - low) / 32767.0f) / DEG2RAD(45); + + return sout; +} + +/* +================= +idSoundWorldLocal::FadeSoundClasses + +fade all sounds in the world with a given shader soundClass +to is in Db (sigh), over is in seconds +================= +*/ +void idSoundWorldLocal::FadeSoundClasses( const int soundClass, const float to, const float over ) { + if ( soundClass < 0 || soundClass >= SOUND_MAX_CLASSES ) { + common->Error( "idSoundWorldLocal::FadeSoundClasses: bad soundClass %i", soundClass ); + } + + idSoundFade *fade = &soundClassFade[ soundClass ]; + + int length44kHz = soundSystemLocal.MillisecondsToSamples( over * 1000 ); + + // if it is already fading to this volume at this rate, don't change it + if ( fade->fadeEndVolume == to && + fade->fadeEnd44kHz - fade->fadeStart44kHz == length44kHz ) { + return; + } + + int start44kHz; + + if ( fpa[0] ) { + // if we are recording an AVI demo, don't use hardware time + start44kHz = lastAVI44kHz + MIXBUFFER_SAMPLES; + } else { + start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES; + } + + // fade it + fade->fadeStartVolume = fade->FadeDbAt44kHz( start44kHz ); + fade->fadeStart44kHz = start44kHz; + fade->fadeEnd44kHz = start44kHz + length44kHz; + fade->fadeEndVolume = to; +} + +/* +================= +idSoundWorldLocal::SetSlowmo +================= +*/ +void idSoundWorldLocal::SetSlowmo( bool active ) { + slowmoActive = active; +} + +/* +================= +idSoundWorldLocal::SetSlowmoSpeed +================= +*/ +void idSoundWorldLocal::SetSlowmoSpeed( float speed ) { + slowmoSpeed = speed; +} + +/* +================= +idSoundWorldLocal::SetEnviroSuit +================= +*/ +void idSoundWorldLocal::SetEnviroSuit( bool active ) { + enviroSuitActive = active; +} diff --git a/sound/sound.h b/sound/sound.h index 5e50bed17..229d3239d 100644 --- a/sound/sound.h +++ b/sound/sound.h @@ -1,23 +1,25 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __SOUND__ #define __SOUND__ -#ifdef __linux__ -#include "framework/declmanager.h" -#include "renderer/cinematic.h" -#endif - /* =============================================================================== @@ -46,14 +48,14 @@ static const int SSF_NO_FLICKER = BIT(8); // always return 1.0 for volume queri static const int SSF_NO_DUPS = BIT(9); // try not to play the same sound twice in a row // these options can be overriden from sound shader defaults on a per-emitter and per-channel basis -struct soundShaderParms_t { +typedef struct { float minDistance; float maxDistance; float volume; // in dB, unfortunately. Negative values get quieter float shakes; int soundShaderFlags; // SSF_* bit flags int soundClass; // for global fading of sounds -}; +} soundShaderParms_t; const int SOUND_MAX_LIST_WAVS = 32; @@ -183,8 +185,6 @@ option existing simultaniously with a live game. =============================================================================== */ -class idDemoFile; - class idSoundWorld { public: virtual ~idSoundWorld( void ) {} @@ -270,8 +270,6 @@ typedef struct { int current44kHzTime; } soundDecoderInfo_t; -class idRenderWorld; -struct MemInfo_t; class idSoundSystem { public: diff --git a/sys/gllog/gl.api b/sys/gllog/gl.api new file mode 100644 index 000000000..0c0a3e7d5 --- /dev/null +++ b/sys/gllog/gl.api @@ -0,0 +1,336 @@ +void;qgl;Accum;GLenum op, GLfloat value +void;qgl;AlphaFunc;GLenum func, GLclampf ref +GLboolean;qgl;AreTexturesResident;GLsizei n, const GLuint *textures, GLboolean *residences +void;qgl;ArrayElement;GLint i +void;qgl;Begin;GLenum mode +void;qgl;BindTexture;GLenum target, GLuint texture +void;qgl;Bitmap;GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap +void;qgl;BlendFunc;GLenum sfactor, GLenum dfactor +void;qgl;CallList;GLuint list +void;qgl;CallLists;GLsizei n, GLenum type, const GLvoid *lists +void;qgl;Clear;GLbitfield mask +void;qgl;ClearAccum;GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha +void;qgl;ClearColor;GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha +void;qgl;ClearDepth;GLclampd depth +void;qgl;ClearIndex;GLfloat c +void;qgl;ClearStencil;GLint s +void;qgl;ClipPlane;GLenum plane, const GLdouble *equation +void;qgl;Color3b;GLbyte red, GLbyte green, GLbyte blue +void;qgl;Color3bv;const GLbyte *v +void;qgl;Color3d;GLdouble red, GLdouble green, GLdouble blue +void;qgl;Color3dv;const GLdouble *v +void;qgl;Color3f;GLfloat red, GLfloat green, GLfloat blue +void;qgl;Color3fv;const GLfloat *v +void;qgl;Color3i;GLint red, GLint green, GLint blue +void;qgl;Color3iv;const GLint *v +void;qgl;Color3s;GLshort red, GLshort green, GLshort blue +void;qgl;Color3sv;const GLshort *v +void;qgl;Color3ub;GLubyte red, GLubyte green, GLubyte blue +void;qgl;Color3ubv;const GLubyte *v +void;qgl;Color3ui;GLuint red, GLuint green, GLuint blue +void;qgl;Color3uiv;const GLuint *v +void;qgl;Color3us;GLushort red, GLushort green, GLushort blue +void;qgl;Color3usv;const GLushort *v +void;qgl;Color4b;GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha +void;qgl;Color4bv;const GLbyte *v +void;qgl;Color4d;GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha +void;qgl;Color4dv;const GLdouble *v +void;qgl;Color4f;GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha +void;qgl;Color4fv;const GLfloat *v +void;qgl;Color4i;GLint red, GLint green, GLint blue, GLint alpha +void;qgl;Color4iv;const GLint *v +void;qgl;Color4s;GLshort red, GLshort green, GLshort blue, GLshort alpha +void;qgl;Color4sv;const GLshort *v +void;qgl;Color4ub;GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha +void;qgl;Color4ubv;const GLubyte *v +void;qgl;Color4ui;GLuint red, GLuint green, GLuint blue, GLuint alpha +void;qgl;Color4uiv;const GLuint *v +void;qgl;Color4us;GLushort red, GLushort green, GLushort blue, GLushort alpha +void;qgl;Color4usv;const GLushort *v +void;qgl;ColorMask;GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha +void;qgl;ColorMaterial;GLenum face, GLenum mode +void;qgl;ColorPointer;GLint size, GLenum type, GLsizei stride, const GLvoid *pointer +void;qgl;CopyPixels;GLint x, GLint y, GLsizei width, GLsizei height, GLenum type +void;qgl;CopyTexImage1D;GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border +void;qgl;CopyTexImage2D;GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border +void;qgl;CopyTexSubImage1D;GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width +void;qgl;CopyTexSubImage2D;GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height +void;qgl;CullFace;GLenum mode +void;qgl;DeleteLists;GLuint list, GLsizei range +void;qgl;DeleteTextures;GLsizei n, const GLuint *textures +void;qgl;DepthFunc;GLenum func +void;qgl;DepthMask;GLboolean flag +void;qgl;DepthRange;GLclampd zNear, GLclampd zFar +void;qgl;Disable;GLenum cap +void;qgl;DisableClientState;GLenum array +void;qgl;DrawArrays;GLenum mode, GLint first, GLsizei count +void;qgl;DrawBuffer;GLenum mode +void;qgl;DrawElements;GLenum mode, GLsizei count, GLenum type, const GLvoid *indices +void;qgl;DrawPixels;GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels +void;qgl;EdgeFlag;GLboolean flag +void;qgl;EdgeFlagPointer;GLsizei stride, const GLvoid *pointer +void;qgl;EdgeFlagv;const GLboolean *flag +void;qgl;Enable;GLenum cap +void;qgl;EnableClientState;GLenum array +void;qgl;End;void +void;qgl;EndList;void +void;qgl;EvalCoord1d;GLdouble u +void;qgl;EvalCoord1dv;const GLdouble *u +void;qgl;EvalCoord1f;GLfloat u +void;qgl;EvalCoord1fv;const GLfloat *u +void;qgl;EvalCoord2d;GLdouble u, GLdouble v +void;qgl;EvalCoord2dv;const GLdouble *u +void;qgl;EvalCoord2f;GLfloat u, GLfloat v +void;qgl;EvalCoord2fv;const GLfloat *u +void;qgl;EvalMesh1;GLenum mode, GLint i1, GLint i2 +void;qgl;EvalMesh2;GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 +void;qgl;EvalPoint1;GLint i +void;qgl;EvalPoint2;GLint i, GLint j +void;qgl;FeedbackBuffer;GLsizei size, GLenum type, GLfloat *buffer +void;qgl;Finish;void +void;qgl;Flush;void +void;qgl;Fogf;GLenum pname, GLfloat param +void;qgl;Fogfv;GLenum pname, const GLfloat *params +void;qgl;Fogi;GLenum pname, GLint param +void;qgl;Fogiv;GLenum pname, const GLint *params +void;qgl;FrontFace;GLenum mode +void;qgl;Frustum;GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar +GLuint;qgl;GenLists;GLsizei range +void;qgl;GenTextures;GLsizei n, GLuint *textures +void;qgl;GetBooleanv;GLenum pname, GLboolean *params +void;qgl;GetClipPlane;GLenum plane, GLdouble *equation +void;qgl;GetDoublev;GLenum pname, GLdouble *params +GLenum;qgl;GetError;void +void;qgl;GetFloatv;GLenum pname, GLfloat *params +void;qgl;GetIntegerv;GLenum pname, GLint *params +void;qgl;GetLightfv;GLenum light, GLenum pname, GLfloat *params +void;qgl;GetLightiv;GLenum light, GLenum pname, GLint *params +void;qgl;GetMapdv;GLenum target, GLenum query, GLdouble *v +void;qgl;GetMapfv;GLenum target, GLenum query, GLfloat *v +void;qgl;GetMapiv;GLenum target, GLenum query, GLint *v +void;qgl;GetMaterialfv;GLenum face, GLenum pname, GLfloat *params +void;qgl;GetMaterialiv;GLenum face, GLenum pname, GLint *params +void;qgl;GetPixelMapfv;GLenum map, GLfloat *values +void;qgl;GetPixelMapuiv;GLenum map, GLuint *values +void;qgl;GetPixelMapusv;GLenum map, GLushort *values +void;qgl;GetPointerv;GLenum pname, GLvoid* *params +void;qgl;GetPolygonStipple;GLubyte *mask +const GLubyte *;qgl;GetString;GLenum name +void;qgl;GetTexEnvfv;GLenum target, GLenum pname, GLfloat *params +void;qgl;GetTexEnviv;GLenum target, GLenum pname, GLint *params +void;qgl;GetTexGendv;GLenum coord, GLenum pname, GLdouble *params +void;qgl;GetTexGenfv;GLenum coord, GLenum pname, GLfloat *params +void;qgl;GetTexGeniv;GLenum coord, GLenum pname, GLint *params +void;qgl;GetTexImage;GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels +void;qgl;GetTexLevelParameterfv;GLenum target, GLint level, GLenum pname, GLfloat *params +void;qgl;GetTexLevelParameteriv;GLenum target, GLint level, GLenum pname, GLint *params +void;qgl;GetTexParameterfv;GLenum target, GLenum pname, GLfloat *params +void;qgl;GetTexParameteriv;GLenum target, GLenum pname, GLint *params +void;qgl;Hint;GLenum target, GLenum mode +void;qgl;IndexMask;GLuint mask +void;qgl;IndexPointer;GLenum type, GLsizei stride, const GLvoid *pointer +void;qgl;Indexd;GLdouble c +void;qgl;Indexdv;const GLdouble *c +void;qgl;Indexf;GLfloat c +void;qgl;Indexfv;const GLfloat *c +void;qgl;Indexi;GLint c +void;qgl;Indexiv;const GLint *c +void;qgl;Indexs;GLshort c +void;qgl;Indexsv;const GLshort *c +void;qgl;Indexub;GLubyte c +void;qgl;Indexubv;const GLubyte *c +void;qgl;InitNames;void +void;qgl;InterleavedArrays;GLenum format, GLsizei stride, const GLvoid *pointer +GLboolean;qgl;IsEnabled;GLenum cap +GLboolean;qgl;IsList;GLuint list +GLboolean;qgl;IsTexture;GLuint texture +void;qgl;LightModelf;GLenum pname, GLfloat param +void;qgl;LightModelfv;GLenum pname, const GLfloat *params +void;qgl;LightModeli;GLenum pname, GLint param +void;qgl;LightModeliv;GLenum pname, const GLint *params +void;qgl;Lightf;GLenum light, GLenum pname, GLfloat param +void;qgl;Lightfv;GLenum light, GLenum pname, const GLfloat *params +void;qgl;Lighti;GLenum light, GLenum pname, GLint param +void;qgl;Lightiv;GLenum light, GLenum pname, const GLint *params +void;qgl;LineStipple;GLint factor, GLushort pattern +void;qgl;LineWidth;GLfloat width +void;qgl;ListBase;GLuint base +void;qgl;LoadIdentity;void +void;qgl;LoadMatrixd;const GLdouble *m +void;qgl;LoadMatrixf;const GLfloat *m +void;qgl;LoadName;GLuint name +void;qgl;LogicOp;GLenum opcode +void;qgl;Map1d;GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points +void;qgl;Map1f;GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points +void;qgl;Map2d;GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points +void;qgl;Map2f;GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points +void;qgl;MapGrid1d;GLint un, GLdouble u1, GLdouble u2 +void;qgl;MapGrid1f;GLint un, GLfloat u1, GLfloat u2 +void;qgl;MapGrid2d;GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 +void;qgl;MapGrid2f;GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 +void;qgl;Materialf;GLenum face, GLenum pname, GLfloat param +void;qgl;Materialfv;GLenum face, GLenum pname, const GLfloat *params +void;qgl;Materiali;GLenum face, GLenum pname, GLint param +void;qgl;Materialiv;GLenum face, GLenum pname, const GLint *params +void;qgl;MatrixMode;GLenum mode +void;qgl;MultMatrixd;const GLdouble *m +void;qgl;MultMatrixf;const GLfloat *m +void;qgl;NewList;GLuint list, GLenum mode +void;qgl;Normal3b;GLbyte nx, GLbyte ny, GLbyte nz +void;qgl;Normal3bv;const GLbyte *v +void;qgl;Normal3d;GLdouble nx, GLdouble ny, GLdouble nz +void;qgl;Normal3dv;const GLdouble *v +void;qgl;Normal3f;GLfloat nx, GLfloat ny, GLfloat nz +void;qgl;Normal3fv;const GLfloat *v +void;qgl;Normal3i;GLint nx, GLint ny, GLint nz +void;qgl;Normal3iv;const GLint *v +void;qgl;Normal3s;GLshort nx, GLshort ny, GLshort nz +void;qgl;Normal3sv;const GLshort *v +void;qgl;NormalPointer;GLenum type, GLsizei stride, const GLvoid *pointer +void;qgl;Ortho;GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar +void;qgl;PassThrough;GLfloat token +void;qgl;PixelMapfv;GLenum map, GLsizei mapsize, const GLfloat *values +void;qgl;PixelMapuiv;GLenum map, GLsizei mapsize, const GLuint *values +void;qgl;PixelMapusv;GLenum map, GLsizei mapsize, const GLushort *values +void;qgl;PixelStoref;GLenum pname, GLfloat param +void;qgl;PixelStorei;GLenum pname, GLint param +void;qgl;PixelTransferf;GLenum pname, GLfloat param +void;qgl;PixelTransferi;GLenum pname, GLint param +void;qgl;PixelZoom;GLfloat xfactor, GLfloat yfactor +void;qgl;PointSize;GLfloat size +void;qgl;PolygonMode;GLenum face, GLenum mode +void;qgl;PolygonOffset;GLfloat factor, GLfloat units +void;qgl;PolygonStipple;const GLubyte *mask +void;qgl;PopAttrib;void +void;qgl;PopClientAttrib;void +void;qgl;PopMatrix;void +void;qgl;PopName;void +void;qgl;PrioritizeTextures;GLsizei n, const GLuint *textures, const GLclampf *priorities +void;qgl;PushAttrib;GLbitfield mask +void;qgl;PushClientAttrib;GLbitfield mask +void;qgl;PushMatrix;void +void;qgl;PushName;GLuint name +void;qgl;RasterPos2d;GLdouble x, GLdouble y +void;qgl;RasterPos2dv;const GLdouble *v +void;qgl;RasterPos2f;GLfloat x, GLfloat y +void;qgl;RasterPos2fv;const GLfloat *v +void;qgl;RasterPos2i;GLint x, GLint y +void;qgl;RasterPos2iv;const GLint *v +void;qgl;RasterPos2s;GLshort x, GLshort y +void;qgl;RasterPos2sv;const GLshort *v +void;qgl;RasterPos3d;GLdouble x, GLdouble y, GLdouble z +void;qgl;RasterPos3dv;const GLdouble *v +void;qgl;RasterPos3f;GLfloat x, GLfloat y, GLfloat z +void;qgl;RasterPos3fv;const GLfloat *v +void;qgl;RasterPos3i;GLint x, GLint y, GLint z +void;qgl;RasterPos3iv;const GLint *v +void;qgl;RasterPos3s;GLshort x, GLshort y, GLshort z +void;qgl;RasterPos3sv;const GLshort *v +void;qgl;RasterPos4d;GLdouble x, GLdouble y, GLdouble z, GLdouble w +void;qgl;RasterPos4dv;const GLdouble *v +void;qgl;RasterPos4f;GLfloat x, GLfloat y, GLfloat z, GLfloat w +void;qgl;RasterPos4fv;const GLfloat *v +void;qgl;RasterPos4i;GLint x, GLint y, GLint z, GLint w +void;qgl;RasterPos4iv;const GLint *v +void;qgl;RasterPos4s;GLshort x, GLshort y, GLshort z, GLshort w +void;qgl;RasterPos4sv;const GLshort *v +void;qgl;ReadBuffer;GLenum mode +void;qgl;ReadPixels;GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels +void;qgl;Rectd;GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 +void;qgl;Rectdv;const GLdouble *v1, const GLdouble *v2 +void;qgl;Rectf;GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 +void;qgl;Rectfv;const GLfloat *v1, const GLfloat *v2 +void;qgl;Recti;GLint x1, GLint y1, GLint x2, GLint y2 +void;qgl;Rectiv;const GLint *v1, const GLint *v2 +void;qgl;Rects;GLshort x1, GLshort y1, GLshort x2, GLshort y2 +void;qgl;Rectsv;const GLshort *v1, const GLshort *v2 +GLint;qgl;RenderMode;GLenum mode +void;qgl;Rotated;GLdouble angle, GLdouble x, GLdouble y, GLdouble z +void;qgl;Rotatef;GLfloat angle, GLfloat x, GLfloat y, GLfloat z +void;qgl;Scaled;GLdouble x, GLdouble y, GLdouble z +void;qgl;Scalef;GLfloat x, GLfloat y, GLfloat z +void;qgl;Scissor;GLint x, GLint y, GLsizei width, GLsizei height +void;qgl;SelectBuffer;GLsizei size, GLuint *buffer +void;qgl;ShadeModel;GLenum mode +void;qgl;StencilFunc;GLenum func, GLint ref, GLuint mask +void;qgl;StencilMask;GLuint mask +void;qgl;StencilOp;GLenum fail, GLenum zfail, GLenum zpass +void;qgl;TexCoord1d;GLdouble s +void;qgl;TexCoord1dv;const GLdouble *v +void;qgl;TexCoord1f;GLfloat s +void;qgl;TexCoord1fv;const GLfloat *v +void;qgl;TexCoord1i;GLint s +void;qgl;TexCoord1iv;const GLint *v +void;qgl;TexCoord1s;GLshort s +void;qgl;TexCoord1sv;const GLshort *v +void;qgl;TexCoord2d;GLdouble s, GLdouble t +void;qgl;TexCoord2dv;const GLdouble *v +void;qgl;TexCoord2f;GLfloat s, GLfloat t +void;qgl;TexCoord2fv;const GLfloat *v +void;qgl;TexCoord2i;GLint s, GLint t +void;qgl;TexCoord2iv;const GLint *v +void;qgl;TexCoord2s;GLshort s, GLshort t +void;qgl;TexCoord2sv;const GLshort *v +void;qgl;TexCoord3d;GLdouble s, GLdouble t, GLdouble r +void;qgl;TexCoord3dv;const GLdouble *v +void;qgl;TexCoord3f;GLfloat s, GLfloat t, GLfloat r +void;qgl;TexCoord3fv;const GLfloat *v +void;qgl;TexCoord3i;GLint s, GLint t, GLint r +void;qgl;TexCoord3iv;const GLint *v +void;qgl;TexCoord3s;GLshort s, GLshort t, GLshort r +void;qgl;TexCoord3sv;const GLshort *v +void;qgl;TexCoord4d;GLdouble s, GLdouble t, GLdouble r, GLdouble q +void;qgl;TexCoord4dv;const GLdouble *v +void;qgl;TexCoord4f;GLfloat s, GLfloat t, GLfloat r, GLfloat q +void;qgl;TexCoord4fv;const GLfloat *v +void;qgl;TexCoord4i;GLint s, GLint t, GLint r, GLint q +void;qgl;TexCoord4iv;const GLint *v +void;qgl;TexCoord4s;GLshort s, GLshort t, GLshort r, GLshort q +void;qgl;TexCoord4sv;const GLshort *v +void;qgl;TexCoordPointer;GLint size, GLenum type, GLsizei stride, const GLvoid *pointer +void;qgl;TexEnvf;GLenum target, GLenum pname, GLfloat param +void;qgl;TexEnvfv;GLenum target, GLenum pname, const GLfloat *params +void;qgl;TexEnvi;GLenum target, GLenum pname, GLint param +void;qgl;TexEnviv;GLenum target, GLenum pname, const GLint *params +void;qgl;TexGend;GLenum coord, GLenum pname, GLdouble param +void;qgl;TexGendv;GLenum coord, GLenum pname, const GLdouble *params +void;qgl;TexGenf;GLenum coord, GLenum pname, GLfloat param +void;qgl;TexGenfv;GLenum coord, GLenum pname, const GLfloat *params +void;qgl;TexGeni;GLenum coord, GLenum pname, GLint param +void;qgl;TexGeniv;GLenum coord, GLenum pname, const GLint *params +void;qgl;TexImage1D;GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels +void;qgl;TexImage2D;GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels +void;qgl;TexParameterf;GLenum target, GLenum pname, GLfloat param +void;qgl;TexParameterfv;GLenum target, GLenum pname, const GLfloat *params +void;qgl;TexParameteri;GLenum target, GLenum pname, GLint param +void;qgl;TexParameteriv;GLenum target, GLenum pname, const GLint *params +void;qgl;TexSubImage1D;GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels +void;qgl;TexSubImage2D;GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels +void;qgl;Translated;GLdouble x, GLdouble y, GLdouble z +void;qgl;Translatef;GLfloat x, GLfloat y, GLfloat z +void;qgl;Vertex2d;GLdouble x, GLdouble y +void;qgl;Vertex2dv;const GLdouble *v +void;qgl;Vertex2f;GLfloat x, GLfloat y +void;qgl;Vertex2fv;const GLfloat *v +void;qgl;Vertex2i;GLint x, GLint y +void;qgl;Vertex2iv;const GLint *v +void;qgl;Vertex2s;GLshort x, GLshort y +void;qgl;Vertex2sv;const GLshort *v +void;qgl;Vertex3d;GLdouble x, GLdouble y, GLdouble z +void;qgl;Vertex3dv;const GLdouble *v +void;qgl;Vertex3f;GLfloat x, GLfloat y, GLfloat z +void;qgl;Vertex3fv;const GLfloat *v +void;qgl;Vertex3i;GLint x, GLint y, GLint z +void;qgl;Vertex3iv;const GLint *v +void;qgl;Vertex3s;GLshort x, GLshort y, GLshort z +void;qgl;Vertex3sv;const GLshort *v +void;qgl;Vertex4d;GLdouble x, GLdouble y, GLdouble z, GLdouble w +void;qgl;Vertex4dv;const GLdouble *v +void;qgl;Vertex4f;GLfloat x, GLfloat y, GLfloat z, GLfloat w +void;qgl;Vertex4fv;const GLfloat *v +void;qgl;Vertex4i;GLint x, GLint y, GLint z, GLint w +void;qgl;Vertex4iv;const GLint *v +void;qgl;Vertex4s;GLshort x, GLshort y, GLshort z, GLshort w +void;qgl;Vertex4sv;const GLshort *v +void;qgl;VertexPointer;GLint size, GLenum type, GLsizei stride, const GLvoid *pointer +void;qgl;Viewport;GLint x, GLint y, GLsizei width, GLsizei height diff --git a/sys/gllog/glX.api b/sys/gllog/glX.api new file mode 100644 index 000000000..bc1946eb3 --- /dev/null +++ b/sys/gllog/glX.api @@ -0,0 +1,6 @@ +XVisualInfo *;qglX;ChooseVisual;Display *dpy, int screen, int *attribList +GLXContext;qglX;CreateContext;Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct +void;qglX;DestroyContext;Display *dpy, GLXContext ctx +Bool;qglX;MakeCurrent;Display *dpy, GLXDrawable drawable, GLXContext ctx +void;qglX;SwapBuffers;Display *dpy, GLXDrawable drawable +GLExtension_t;qglX;GetProcAddressARB;const GLubyte *procName diff --git a/sys/gllog/gl_def.m4 b/sys/gllog/gl_def.m4 new file mode 100644 index 000000000..9de8e7552 --- /dev/null +++ b/sys/gllog/gl_def.m4 @@ -0,0 +1,1099 @@ +define(`gl_start', `0') +define(`gl_end', `335') +define(`wgl_start', `336') +define(`wgl_end', `357') +define(`glX_start', `358') +define(`glX_end', `363') +define(`f0_ret', `void') +define(`f0_name', `Accum') +define(`f0_params', ``GLenum op, GLfloat value'') +define(`f1_ret', `void') +define(`f1_name', `AlphaFunc') +define(`f1_params', ``GLenum func, GLclampf ref'') +define(`f2_ret', `GLboolean') +define(`f2_name', `AreTexturesResident') +define(`f2_params', ``GLsizei n, const GLuint *textures, GLboolean *residences'') +define(`f3_ret', `void') +define(`f3_name', `ArrayElement') +define(`f3_params', ``GLint i'') +define(`f4_ret', `void') +define(`f4_name', `Begin') +define(`f4_params', ``GLenum mode'') +define(`f5_ret', `void') +define(`f5_name', `BindTexture') +define(`f5_params', ``GLenum target, GLuint texture'') +define(`f6_ret', `void') +define(`f6_name', `Bitmap') +define(`f6_params', ``GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap'') +define(`f7_ret', `void') +define(`f7_name', `BlendFunc') +define(`f7_params', ``GLenum sfactor, GLenum dfactor'') +define(`f8_ret', `void') +define(`f8_name', `CallList') +define(`f8_params', ``GLuint list'') +define(`f9_ret', `void') +define(`f9_name', `CallLists') +define(`f9_params', ``GLsizei n, GLenum type, const GLvoid *lists'') +define(`f10_ret', `void') +define(`f10_name', `Clear') +define(`f10_params', ``GLbitfield mask'') +define(`f11_ret', `void') +define(`f11_name', `ClearAccum') +define(`f11_params', ``GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha'') +define(`f12_ret', `void') +define(`f12_name', `ClearColor') +define(`f12_params', ``GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha'') +define(`f13_ret', `void') +define(`f13_name', `ClearDepth') +define(`f13_params', ``GLclampd depth'') +define(`f14_ret', `void') +define(`f14_name', `ClearIndex') +define(`f14_params', ``GLfloat c'') +define(`f15_ret', `void') +define(`f15_name', `ClearStencil') +define(`f15_params', ``GLint s'') +define(`f16_ret', `void') +define(`f16_name', `ClipPlane') +define(`f16_params', ``GLenum plane, const GLdouble *equation'') +define(`f17_ret', `void') +define(`f17_name', `Color3b') +define(`f17_params', ``GLbyte red, GLbyte green, GLbyte blue'') +define(`f18_ret', `void') +define(`f18_name', `Color3bv') +define(`f18_params', ``const GLbyte *v'') +define(`f19_ret', `void') +define(`f19_name', `Color3d') +define(`f19_params', ``GLdouble red, GLdouble green, GLdouble blue'') +define(`f20_ret', `void') +define(`f20_name', `Color3dv') +define(`f20_params', ``const GLdouble *v'') +define(`f21_ret', `void') +define(`f21_name', `Color3f') +define(`f21_params', ``GLfloat red, GLfloat green, GLfloat blue'') +define(`f22_ret', `void') +define(`f22_name', `Color3fv') +define(`f22_params', ``const GLfloat *v'') +define(`f23_ret', `void') +define(`f23_name', `Color3i') +define(`f23_params', ``GLint red, GLint green, GLint blue'') +define(`f24_ret', `void') +define(`f24_name', `Color3iv') +define(`f24_params', ``const GLint *v'') +define(`f25_ret', `void') +define(`f25_name', `Color3s') +define(`f25_params', ``GLshort red, GLshort green, GLshort blue'') +define(`f26_ret', `void') +define(`f26_name', `Color3sv') +define(`f26_params', ``const GLshort *v'') +define(`f27_ret', `void') +define(`f27_name', `Color3ub') +define(`f27_params', ``GLubyte red, GLubyte green, GLubyte blue'') +define(`f28_ret', `void') +define(`f28_name', `Color3ubv') +define(`f28_params', ``const GLubyte *v'') +define(`f29_ret', `void') +define(`f29_name', `Color3ui') +define(`f29_params', ``GLuint red, GLuint green, GLuint blue'') +define(`f30_ret', `void') +define(`f30_name', `Color3uiv') +define(`f30_params', ``const GLuint *v'') +define(`f31_ret', `void') +define(`f31_name', `Color3us') +define(`f31_params', ``GLushort red, GLushort green, GLushort blue'') +define(`f32_ret', `void') +define(`f32_name', `Color3usv') +define(`f32_params', ``const GLushort *v'') +define(`f33_ret', `void') +define(`f33_name', `Color4b') +define(`f33_params', ``GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha'') +define(`f34_ret', `void') +define(`f34_name', `Color4bv') +define(`f34_params', ``const GLbyte *v'') +define(`f35_ret', `void') +define(`f35_name', `Color4d') +define(`f35_params', ``GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha'') +define(`f36_ret', `void') +define(`f36_name', `Color4dv') +define(`f36_params', ``const GLdouble *v'') +define(`f37_ret', `void') +define(`f37_name', `Color4f') +define(`f37_params', ``GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha'') +define(`f38_ret', `void') +define(`f38_name', `Color4fv') +define(`f38_params', ``const GLfloat *v'') +define(`f39_ret', `void') +define(`f39_name', `Color4i') +define(`f39_params', ``GLint red, GLint green, GLint blue, GLint alpha'') +define(`f40_ret', `void') +define(`f40_name', `Color4iv') +define(`f40_params', ``const GLint *v'') +define(`f41_ret', `void') +define(`f41_name', `Color4s') +define(`f41_params', ``GLshort red, GLshort green, GLshort blue, GLshort alpha'') +define(`f42_ret', `void') +define(`f42_name', `Color4sv') +define(`f42_params', ``const GLshort *v'') +define(`f43_ret', `void') +define(`f43_name', `Color4ub') +define(`f43_params', ``GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha'') +define(`f44_ret', `void') +define(`f44_name', `Color4ubv') +define(`f44_params', ``const GLubyte *v'') +define(`f45_ret', `void') +define(`f45_name', `Color4ui') +define(`f45_params', ``GLuint red, GLuint green, GLuint blue, GLuint alpha'') +define(`f46_ret', `void') +define(`f46_name', `Color4uiv') +define(`f46_params', ``const GLuint *v'') +define(`f47_ret', `void') +define(`f47_name', `Color4us') +define(`f47_params', ``GLushort red, GLushort green, GLushort blue, GLushort alpha'') +define(`f48_ret', `void') +define(`f48_name', `Color4usv') +define(`f48_params', ``const GLushort *v'') +define(`f49_ret', `void') +define(`f49_name', `ColorMask') +define(`f49_params', ``GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha'') +define(`f50_ret', `void') +define(`f50_name', `ColorMaterial') +define(`f50_params', ``GLenum face, GLenum mode'') +define(`f51_ret', `void') +define(`f51_name', `ColorPointer') +define(`f51_params', ``GLint size, GLenum type, GLsizei stride, const GLvoid *pointer'') +define(`f52_ret', `void') +define(`f52_name', `CopyPixels') +define(`f52_params', ``GLint x, GLint y, GLsizei width, GLsizei height, GLenum type'') +define(`f53_ret', `void') +define(`f53_name', `CopyTexImage1D') +define(`f53_params', ``GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border'') +define(`f54_ret', `void') +define(`f54_name', `CopyTexImage2D') +define(`f54_params', ``GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border'') +define(`f55_ret', `void') +define(`f55_name', `CopyTexSubImage1D') +define(`f55_params', ``GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width'') +define(`f56_ret', `void') +define(`f56_name', `CopyTexSubImage2D') +define(`f56_params', ``GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height'') +define(`f57_ret', `void') +define(`f57_name', `CullFace') +define(`f57_params', ``GLenum mode'') +define(`f58_ret', `void') +define(`f58_name', `DeleteLists') +define(`f58_params', ``GLuint list, GLsizei range'') +define(`f59_ret', `void') +define(`f59_name', `DeleteTextures') +define(`f59_params', ``GLsizei n, const GLuint *textures'') +define(`f60_ret', `void') +define(`f60_name', `DepthFunc') +define(`f60_params', ``GLenum func'') +define(`f61_ret', `void') +define(`f61_name', `DepthMask') +define(`f61_params', ``GLboolean flag'') +define(`f62_ret', `void') +define(`f62_name', `DepthRange') +define(`f62_params', ``GLclampd zNear, GLclampd zFar'') +define(`f63_ret', `void') +define(`f63_name', `Disable') +define(`f63_params', ``GLenum cap'') +define(`f64_ret', `void') +define(`f64_name', `DisableClientState') +define(`f64_params', ``GLenum array'') +define(`f65_ret', `void') +define(`f65_name', `DrawArrays') +define(`f65_params', ``GLenum mode, GLint first, GLsizei count'') +define(`f66_ret', `void') +define(`f66_name', `DrawBuffer') +define(`f66_params', ``GLenum mode'') +define(`f67_ret', `void') +define(`f67_name', `DrawElements') +define(`f67_params', ``GLenum mode, GLsizei count, GLenum type, const GLvoid *indices'') +define(`f68_ret', `void') +define(`f68_name', `DrawPixels') +define(`f68_params', ``GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels'') +define(`f69_ret', `void') +define(`f69_name', `EdgeFlag') +define(`f69_params', ``GLboolean flag'') +define(`f70_ret', `void') +define(`f70_name', `EdgeFlagPointer') +define(`f70_params', ``GLsizei stride, const GLvoid *pointer'') +define(`f71_ret', `void') +define(`f71_name', `EdgeFlagv') +define(`f71_params', ``const GLboolean *flag'') +define(`f72_ret', `void') +define(`f72_name', `Enable') +define(`f72_params', ``GLenum cap'') +define(`f73_ret', `void') +define(`f73_name', `EnableClientState') +define(`f73_params', ``GLenum array'') +define(`f74_ret', `void') +define(`f74_name', `End') +define(`f74_params', ``void'') +define(`f75_ret', `void') +define(`f75_name', `EndList') +define(`f75_params', ``void'') +define(`f76_ret', `void') +define(`f76_name', `EvalCoord1d') +define(`f76_params', ``GLdouble u'') +define(`f77_ret', `void') +define(`f77_name', `EvalCoord1dv') +define(`f77_params', ``const GLdouble *u'') +define(`f78_ret', `void') +define(`f78_name', `EvalCoord1f') +define(`f78_params', ``GLfloat u'') +define(`f79_ret', `void') +define(`f79_name', `EvalCoord1fv') +define(`f79_params', ``const GLfloat *u'') +define(`f80_ret', `void') +define(`f80_name', `EvalCoord2d') +define(`f80_params', ``GLdouble u, GLdouble v'') +define(`f81_ret', `void') +define(`f81_name', `EvalCoord2dv') +define(`f81_params', ``const GLdouble *u'') +define(`f82_ret', `void') +define(`f82_name', `EvalCoord2f') +define(`f82_params', ``GLfloat u, GLfloat v'') +define(`f83_ret', `void') +define(`f83_name', `EvalCoord2fv') +define(`f83_params', ``const GLfloat *u'') +define(`f84_ret', `void') +define(`f84_name', `EvalMesh1') +define(`f84_params', ``GLenum mode, GLint i1, GLint i2'') +define(`f85_ret', `void') +define(`f85_name', `EvalMesh2') +define(`f85_params', ``GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2'') +define(`f86_ret', `void') +define(`f86_name', `EvalPoint1') +define(`f86_params', ``GLint i'') +define(`f87_ret', `void') +define(`f87_name', `EvalPoint2') +define(`f87_params', ``GLint i, GLint j'') +define(`f88_ret', `void') +define(`f88_name', `FeedbackBuffer') +define(`f88_params', ``GLsizei size, GLenum type, GLfloat *buffer'') +define(`f89_ret', `void') +define(`f89_name', `Finish') +define(`f89_params', ``void'') +define(`f90_ret', `void') +define(`f90_name', `Flush') +define(`f90_params', ``void'') +define(`f91_ret', `void') +define(`f91_name', `Fogf') +define(`f91_params', ``GLenum pname, GLfloat param'') +define(`f92_ret', `void') +define(`f92_name', `Fogfv') +define(`f92_params', ``GLenum pname, const GLfloat *params'') +define(`f93_ret', `void') +define(`f93_name', `Fogi') +define(`f93_params', ``GLenum pname, GLint param'') +define(`f94_ret', `void') +define(`f94_name', `Fogiv') +define(`f94_params', ``GLenum pname, const GLint *params'') +define(`f95_ret', `void') +define(`f95_name', `FrontFace') +define(`f95_params', ``GLenum mode'') +define(`f96_ret', `void') +define(`f96_name', `Frustum') +define(`f96_params', ``GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar'') +define(`f97_ret', `GLuint') +define(`f97_name', `GenLists') +define(`f97_params', ``GLsizei range'') +define(`f98_ret', `void') +define(`f98_name', `GenTextures') +define(`f98_params', ``GLsizei n, GLuint *textures'') +define(`f99_ret', `void') +define(`f99_name', `GetBooleanv') +define(`f99_params', ``GLenum pname, GLboolean *params'') +define(`f100_ret', `void') +define(`f100_name', `GetClipPlane') +define(`f100_params', ``GLenum plane, GLdouble *equation'') +define(`f101_ret', `void') +define(`f101_name', `GetDoublev') +define(`f101_params', ``GLenum pname, GLdouble *params'') +define(`f102_ret', `GLenum') +define(`f102_name', `GetError') +define(`f102_params', ``void'') +define(`f103_ret', `void') +define(`f103_name', `GetFloatv') +define(`f103_params', ``GLenum pname, GLfloat *params'') +define(`f104_ret', `void') +define(`f104_name', `GetIntegerv') +define(`f104_params', ``GLenum pname, GLint *params'') +define(`f105_ret', `void') +define(`f105_name', `GetLightfv') +define(`f105_params', ``GLenum light, GLenum pname, GLfloat *params'') +define(`f106_ret', `void') +define(`f106_name', `GetLightiv') +define(`f106_params', ``GLenum light, GLenum pname, GLint *params'') +define(`f107_ret', `void') +define(`f107_name', `GetMapdv') +define(`f107_params', ``GLenum target, GLenum query, GLdouble *v'') +define(`f108_ret', `void') +define(`f108_name', `GetMapfv') +define(`f108_params', ``GLenum target, GLenum query, GLfloat *v'') +define(`f109_ret', `void') +define(`f109_name', `GetMapiv') +define(`f109_params', ``GLenum target, GLenum query, GLint *v'') +define(`f110_ret', `void') +define(`f110_name', `GetMaterialfv') +define(`f110_params', ``GLenum face, GLenum pname, GLfloat *params'') +define(`f111_ret', `void') +define(`f111_name', `GetMaterialiv') +define(`f111_params', ``GLenum face, GLenum pname, GLint *params'') +define(`f112_ret', `void') +define(`f112_name', `GetPixelMapfv') +define(`f112_params', ``GLenum map, GLfloat *values'') +define(`f113_ret', `void') +define(`f113_name', `GetPixelMapuiv') +define(`f113_params', ``GLenum map, GLuint *values'') +define(`f114_ret', `void') +define(`f114_name', `GetPixelMapusv') +define(`f114_params', ``GLenum map, GLushort *values'') +define(`f115_ret', `void') +define(`f115_name', `GetPointerv') +define(`f115_params', ``GLenum pname, GLvoid* *params'') +define(`f116_ret', `void') +define(`f116_name', `GetPolygonStipple') +define(`f116_params', ``GLubyte *mask'') +define(`f117_ret', `const GLubyte *') +define(`f117_name', `GetString') +define(`f117_params', ``GLenum name'') +define(`f118_ret', `void') +define(`f118_name', `GetTexEnvfv') +define(`f118_params', ``GLenum target, GLenum pname, GLfloat *params'') +define(`f119_ret', `void') +define(`f119_name', `GetTexEnviv') +define(`f119_params', ``GLenum target, GLenum pname, GLint *params'') +define(`f120_ret', `void') +define(`f120_name', `GetTexGendv') +define(`f120_params', ``GLenum coord, GLenum pname, GLdouble *params'') +define(`f121_ret', `void') +define(`f121_name', `GetTexGenfv') +define(`f121_params', ``GLenum coord, GLenum pname, GLfloat *params'') +define(`f122_ret', `void') +define(`f122_name', `GetTexGeniv') +define(`f122_params', ``GLenum coord, GLenum pname, GLint *params'') +define(`f123_ret', `void') +define(`f123_name', `GetTexImage') +define(`f123_params', ``GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels'') +define(`f124_ret', `void') +define(`f124_name', `GetTexLevelParameterfv') +define(`f124_params', ``GLenum target, GLint level, GLenum pname, GLfloat *params'') +define(`f125_ret', `void') +define(`f125_name', `GetTexLevelParameteriv') +define(`f125_params', ``GLenum target, GLint level, GLenum pname, GLint *params'') +define(`f126_ret', `void') +define(`f126_name', `GetTexParameterfv') +define(`f126_params', ``GLenum target, GLenum pname, GLfloat *params'') +define(`f127_ret', `void') +define(`f127_name', `GetTexParameteriv') +define(`f127_params', ``GLenum target, GLenum pname, GLint *params'') +define(`f128_ret', `void') +define(`f128_name', `Hint') +define(`f128_params', ``GLenum target, GLenum mode'') +define(`f129_ret', `void') +define(`f129_name', `IndexMask') +define(`f129_params', ``GLuint mask'') +define(`f130_ret', `void') +define(`f130_name', `IndexPointer') +define(`f130_params', ``GLenum type, GLsizei stride, const GLvoid *pointer'') +define(`f131_ret', `void') +define(`f131_name', `Indexd') +define(`f131_params', ``GLdouble c'') +define(`f132_ret', `void') +define(`f132_name', `Indexdv') +define(`f132_params', ``const GLdouble *c'') +define(`f133_ret', `void') +define(`f133_name', `Indexf') +define(`f133_params', ``GLfloat c'') +define(`f134_ret', `void') +define(`f134_name', `Indexfv') +define(`f134_params', ``const GLfloat *c'') +define(`f135_ret', `void') +define(`f135_name', `Indexi') +define(`f135_params', ``GLint c'') +define(`f136_ret', `void') +define(`f136_name', `Indexiv') +define(`f136_params', ``const GLint *c'') +define(`f137_ret', `void') +define(`f137_name', `Indexs') +define(`f137_params', ``GLshort c'') +define(`f138_ret', `void') +define(`f138_name', `Indexsv') +define(`f138_params', ``const GLshort *c'') +define(`f139_ret', `void') +define(`f139_name', `Indexub') +define(`f139_params', ``GLubyte c'') +define(`f140_ret', `void') +define(`f140_name', `Indexubv') +define(`f140_params', ``const GLubyte *c'') +define(`f141_ret', `void') +define(`f141_name', `InitNames') +define(`f141_params', ``void'') +define(`f142_ret', `void') +define(`f142_name', `InterleavedArrays') +define(`f142_params', ``GLenum format, GLsizei stride, const GLvoid *pointer'') +define(`f143_ret', `GLboolean') +define(`f143_name', `IsEnabled') +define(`f143_params', ``GLenum cap'') +define(`f144_ret', `GLboolean') +define(`f144_name', `IsList') +define(`f144_params', ``GLuint list'') +define(`f145_ret', `GLboolean') +define(`f145_name', `IsTexture') +define(`f145_params', ``GLuint texture'') +define(`f146_ret', `void') +define(`f146_name', `LightModelf') +define(`f146_params', ``GLenum pname, GLfloat param'') +define(`f147_ret', `void') +define(`f147_name', `LightModelfv') +define(`f147_params', ``GLenum pname, const GLfloat *params'') +define(`f148_ret', `void') +define(`f148_name', `LightModeli') +define(`f148_params', ``GLenum pname, GLint param'') +define(`f149_ret', `void') +define(`f149_name', `LightModeliv') +define(`f149_params', ``GLenum pname, const GLint *params'') +define(`f150_ret', `void') +define(`f150_name', `Lightf') +define(`f150_params', ``GLenum light, GLenum pname, GLfloat param'') +define(`f151_ret', `void') +define(`f151_name', `Lightfv') +define(`f151_params', ``GLenum light, GLenum pname, const GLfloat *params'') +define(`f152_ret', `void') +define(`f152_name', `Lighti') +define(`f152_params', ``GLenum light, GLenum pname, GLint param'') +define(`f153_ret', `void') +define(`f153_name', `Lightiv') +define(`f153_params', ``GLenum light, GLenum pname, const GLint *params'') +define(`f154_ret', `void') +define(`f154_name', `LineStipple') +define(`f154_params', ``GLint factor, GLushort pattern'') +define(`f155_ret', `void') +define(`f155_name', `LineWidth') +define(`f155_params', ``GLfloat width'') +define(`f156_ret', `void') +define(`f156_name', `ListBase') +define(`f156_params', ``GLuint base'') +define(`f157_ret', `void') +define(`f157_name', `LoadIdentity') +define(`f157_params', ``void'') +define(`f158_ret', `void') +define(`f158_name', `LoadMatrixd') +define(`f158_params', ``const GLdouble *m'') +define(`f159_ret', `void') +define(`f159_name', `LoadMatrixf') +define(`f159_params', ``const GLfloat *m'') +define(`f160_ret', `void') +define(`f160_name', `LoadName') +define(`f160_params', ``GLuint name'') +define(`f161_ret', `void') +define(`f161_name', `LogicOp') +define(`f161_params', ``GLenum opcode'') +define(`f162_ret', `void') +define(`f162_name', `Map1d') +define(`f162_params', ``GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points'') +define(`f163_ret', `void') +define(`f163_name', `Map1f') +define(`f163_params', ``GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points'') +define(`f164_ret', `void') +define(`f164_name', `Map2d') +define(`f164_params', ``GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points'') +define(`f165_ret', `void') +define(`f165_name', `Map2f') +define(`f165_params', ``GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points'') +define(`f166_ret', `void') +define(`f166_name', `MapGrid1d') +define(`f166_params', ``GLint un, GLdouble u1, GLdouble u2'') +define(`f167_ret', `void') +define(`f167_name', `MapGrid1f') +define(`f167_params', ``GLint un, GLfloat u1, GLfloat u2'') +define(`f168_ret', `void') +define(`f168_name', `MapGrid2d') +define(`f168_params', ``GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2'') +define(`f169_ret', `void') +define(`f169_name', `MapGrid2f') +define(`f169_params', ``GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2'') +define(`f170_ret', `void') +define(`f170_name', `Materialf') +define(`f170_params', ``GLenum face, GLenum pname, GLfloat param'') +define(`f171_ret', `void') +define(`f171_name', `Materialfv') +define(`f171_params', ``GLenum face, GLenum pname, const GLfloat *params'') +define(`f172_ret', `void') +define(`f172_name', `Materiali') +define(`f172_params', ``GLenum face, GLenum pname, GLint param'') +define(`f173_ret', `void') +define(`f173_name', `Materialiv') +define(`f173_params', ``GLenum face, GLenum pname, const GLint *params'') +define(`f174_ret', `void') +define(`f174_name', `MatrixMode') +define(`f174_params', ``GLenum mode'') +define(`f175_ret', `void') +define(`f175_name', `MultMatrixd') +define(`f175_params', ``const GLdouble *m'') +define(`f176_ret', `void') +define(`f176_name', `MultMatrixf') +define(`f176_params', ``const GLfloat *m'') +define(`f177_ret', `void') +define(`f177_name', `NewList') +define(`f177_params', ``GLuint list, GLenum mode'') +define(`f178_ret', `void') +define(`f178_name', `Normal3b') +define(`f178_params', ``GLbyte nx, GLbyte ny, GLbyte nz'') +define(`f179_ret', `void') +define(`f179_name', `Normal3bv') +define(`f179_params', ``const GLbyte *v'') +define(`f180_ret', `void') +define(`f180_name', `Normal3d') +define(`f180_params', ``GLdouble nx, GLdouble ny, GLdouble nz'') +define(`f181_ret', `void') +define(`f181_name', `Normal3dv') +define(`f181_params', ``const GLdouble *v'') +define(`f182_ret', `void') +define(`f182_name', `Normal3f') +define(`f182_params', ``GLfloat nx, GLfloat ny, GLfloat nz'') +define(`f183_ret', `void') +define(`f183_name', `Normal3fv') +define(`f183_params', ``const GLfloat *v'') +define(`f184_ret', `void') +define(`f184_name', `Normal3i') +define(`f184_params', ``GLint nx, GLint ny, GLint nz'') +define(`f185_ret', `void') +define(`f185_name', `Normal3iv') +define(`f185_params', ``const GLint *v'') +define(`f186_ret', `void') +define(`f186_name', `Normal3s') +define(`f186_params', ``GLshort nx, GLshort ny, GLshort nz'') +define(`f187_ret', `void') +define(`f187_name', `Normal3sv') +define(`f187_params', ``const GLshort *v'') +define(`f188_ret', `void') +define(`f188_name', `NormalPointer') +define(`f188_params', ``GLenum type, GLsizei stride, const GLvoid *pointer'') +define(`f189_ret', `void') +define(`f189_name', `Ortho') +define(`f189_params', ``GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar'') +define(`f190_ret', `void') +define(`f190_name', `PassThrough') +define(`f190_params', ``GLfloat token'') +define(`f191_ret', `void') +define(`f191_name', `PixelMapfv') +define(`f191_params', ``GLenum map, GLsizei mapsize, const GLfloat *values'') +define(`f192_ret', `void') +define(`f192_name', `PixelMapuiv') +define(`f192_params', ``GLenum map, GLsizei mapsize, const GLuint *values'') +define(`f193_ret', `void') +define(`f193_name', `PixelMapusv') +define(`f193_params', ``GLenum map, GLsizei mapsize, const GLushort *values'') +define(`f194_ret', `void') +define(`f194_name', `PixelStoref') +define(`f194_params', ``GLenum pname, GLfloat param'') +define(`f195_ret', `void') +define(`f195_name', `PixelStorei') +define(`f195_params', ``GLenum pname, GLint param'') +define(`f196_ret', `void') +define(`f196_name', `PixelTransferf') +define(`f196_params', ``GLenum pname, GLfloat param'') +define(`f197_ret', `void') +define(`f197_name', `PixelTransferi') +define(`f197_params', ``GLenum pname, GLint param'') +define(`f198_ret', `void') +define(`f198_name', `PixelZoom') +define(`f198_params', ``GLfloat xfactor, GLfloat yfactor'') +define(`f199_ret', `void') +define(`f199_name', `PointSize') +define(`f199_params', ``GLfloat size'') +define(`f200_ret', `void') +define(`f200_name', `PolygonMode') +define(`f200_params', ``GLenum face, GLenum mode'') +define(`f201_ret', `void') +define(`f201_name', `PolygonOffset') +define(`f201_params', ``GLfloat factor, GLfloat units'') +define(`f202_ret', `void') +define(`f202_name', `PolygonStipple') +define(`f202_params', ``const GLubyte *mask'') +define(`f203_ret', `void') +define(`f203_name', `PopAttrib') +define(`f203_params', ``void'') +define(`f204_ret', `void') +define(`f204_name', `PopClientAttrib') +define(`f204_params', ``void'') +define(`f205_ret', `void') +define(`f205_name', `PopMatrix') +define(`f205_params', ``void'') +define(`f206_ret', `void') +define(`f206_name', `PopName') +define(`f206_params', ``void'') +define(`f207_ret', `void') +define(`f207_name', `PrioritizeTextures') +define(`f207_params', ``GLsizei n, const GLuint *textures, const GLclampf *priorities'') +define(`f208_ret', `void') +define(`f208_name', `PushAttrib') +define(`f208_params', ``GLbitfield mask'') +define(`f209_ret', `void') +define(`f209_name', `PushClientAttrib') +define(`f209_params', ``GLbitfield mask'') +define(`f210_ret', `void') +define(`f210_name', `PushMatrix') +define(`f210_params', ``void'') +define(`f211_ret', `void') +define(`f211_name', `PushName') +define(`f211_params', ``GLuint name'') +define(`f212_ret', `void') +define(`f212_name', `RasterPos2d') +define(`f212_params', ``GLdouble x, GLdouble y'') +define(`f213_ret', `void') +define(`f213_name', `RasterPos2dv') +define(`f213_params', ``const GLdouble *v'') +define(`f214_ret', `void') +define(`f214_name', `RasterPos2f') +define(`f214_params', ``GLfloat x, GLfloat y'') +define(`f215_ret', `void') +define(`f215_name', `RasterPos2fv') +define(`f215_params', ``const GLfloat *v'') +define(`f216_ret', `void') +define(`f216_name', `RasterPos2i') +define(`f216_params', ``GLint x, GLint y'') +define(`f217_ret', `void') +define(`f217_name', `RasterPos2iv') +define(`f217_params', ``const GLint *v'') +define(`f218_ret', `void') +define(`f218_name', `RasterPos2s') +define(`f218_params', ``GLshort x, GLshort y'') +define(`f219_ret', `void') +define(`f219_name', `RasterPos2sv') +define(`f219_params', ``const GLshort *v'') +define(`f220_ret', `void') +define(`f220_name', `RasterPos3d') +define(`f220_params', ``GLdouble x, GLdouble y, GLdouble z'') +define(`f221_ret', `void') +define(`f221_name', `RasterPos3dv') +define(`f221_params', ``const GLdouble *v'') +define(`f222_ret', `void') +define(`f222_name', `RasterPos3f') +define(`f222_params', ``GLfloat x, GLfloat y, GLfloat z'') +define(`f223_ret', `void') +define(`f223_name', `RasterPos3fv') +define(`f223_params', ``const GLfloat *v'') +define(`f224_ret', `void') +define(`f224_name', `RasterPos3i') +define(`f224_params', ``GLint x, GLint y, GLint z'') +define(`f225_ret', `void') +define(`f225_name', `RasterPos3iv') +define(`f225_params', ``const GLint *v'') +define(`f226_ret', `void') +define(`f226_name', `RasterPos3s') +define(`f226_params', ``GLshort x, GLshort y, GLshort z'') +define(`f227_ret', `void') +define(`f227_name', `RasterPos3sv') +define(`f227_params', ``const GLshort *v'') +define(`f228_ret', `void') +define(`f228_name', `RasterPos4d') +define(`f228_params', ``GLdouble x, GLdouble y, GLdouble z, GLdouble w'') +define(`f229_ret', `void') +define(`f229_name', `RasterPos4dv') +define(`f229_params', ``const GLdouble *v'') +define(`f230_ret', `void') +define(`f230_name', `RasterPos4f') +define(`f230_params', ``GLfloat x, GLfloat y, GLfloat z, GLfloat w'') +define(`f231_ret', `void') +define(`f231_name', `RasterPos4fv') +define(`f231_params', ``const GLfloat *v'') +define(`f232_ret', `void') +define(`f232_name', `RasterPos4i') +define(`f232_params', ``GLint x, GLint y, GLint z, GLint w'') +define(`f233_ret', `void') +define(`f233_name', `RasterPos4iv') +define(`f233_params', ``const GLint *v'') +define(`f234_ret', `void') +define(`f234_name', `RasterPos4s') +define(`f234_params', ``GLshort x, GLshort y, GLshort z, GLshort w'') +define(`f235_ret', `void') +define(`f235_name', `RasterPos4sv') +define(`f235_params', ``const GLshort *v'') +define(`f236_ret', `void') +define(`f236_name', `ReadBuffer') +define(`f236_params', ``GLenum mode'') +define(`f237_ret', `void') +define(`f237_name', `ReadPixels') +define(`f237_params', ``GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels'') +define(`f238_ret', `void') +define(`f238_name', `Rectd') +define(`f238_params', ``GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2'') +define(`f239_ret', `void') +define(`f239_name', `Rectdv') +define(`f239_params', ``const GLdouble *v1, const GLdouble *v2'') +define(`f240_ret', `void') +define(`f240_name', `Rectf') +define(`f240_params', ``GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2'') +define(`f241_ret', `void') +define(`f241_name', `Rectfv') +define(`f241_params', ``const GLfloat *v1, const GLfloat *v2'') +define(`f242_ret', `void') +define(`f242_name', `Recti') +define(`f242_params', ``GLint x1, GLint y1, GLint x2, GLint y2'') +define(`f243_ret', `void') +define(`f243_name', `Rectiv') +define(`f243_params', ``const GLint *v1, const GLint *v2'') +define(`f244_ret', `void') +define(`f244_name', `Rects') +define(`f244_params', ``GLshort x1, GLshort y1, GLshort x2, GLshort y2'') +define(`f245_ret', `void') +define(`f245_name', `Rectsv') +define(`f245_params', ``const GLshort *v1, const GLshort *v2'') +define(`f246_ret', `GLint') +define(`f246_name', `RenderMode') +define(`f246_params', ``GLenum mode'') +define(`f247_ret', `void') +define(`f247_name', `Rotated') +define(`f247_params', ``GLdouble angle, GLdouble x, GLdouble y, GLdouble z'') +define(`f248_ret', `void') +define(`f248_name', `Rotatef') +define(`f248_params', ``GLfloat angle, GLfloat x, GLfloat y, GLfloat z'') +define(`f249_ret', `void') +define(`f249_name', `Scaled') +define(`f249_params', ``GLdouble x, GLdouble y, GLdouble z'') +define(`f250_ret', `void') +define(`f250_name', `Scalef') +define(`f250_params', ``GLfloat x, GLfloat y, GLfloat z'') +define(`f251_ret', `void') +define(`f251_name', `Scissor') +define(`f251_params', ``GLint x, GLint y, GLsizei width, GLsizei height'') +define(`f252_ret', `void') +define(`f252_name', `SelectBuffer') +define(`f252_params', ``GLsizei size, GLuint *buffer'') +define(`f253_ret', `void') +define(`f253_name', `ShadeModel') +define(`f253_params', ``GLenum mode'') +define(`f254_ret', `void') +define(`f254_name', `StencilFunc') +define(`f254_params', ``GLenum func, GLint ref, GLuint mask'') +define(`f255_ret', `void') +define(`f255_name', `StencilMask') +define(`f255_params', ``GLuint mask'') +define(`f256_ret', `void') +define(`f256_name', `StencilOp') +define(`f256_params', ``GLenum fail, GLenum zfail, GLenum zpass'') +define(`f257_ret', `void') +define(`f257_name', `TexCoord1d') +define(`f257_params', ``GLdouble s'') +define(`f258_ret', `void') +define(`f258_name', `TexCoord1dv') +define(`f258_params', ``const GLdouble *v'') +define(`f259_ret', `void') +define(`f259_name', `TexCoord1f') +define(`f259_params', ``GLfloat s'') +define(`f260_ret', `void') +define(`f260_name', `TexCoord1fv') +define(`f260_params', ``const GLfloat *v'') +define(`f261_ret', `void') +define(`f261_name', `TexCoord1i') +define(`f261_params', ``GLint s'') +define(`f262_ret', `void') +define(`f262_name', `TexCoord1iv') +define(`f262_params', ``const GLint *v'') +define(`f263_ret', `void') +define(`f263_name', `TexCoord1s') +define(`f263_params', ``GLshort s'') +define(`f264_ret', `void') +define(`f264_name', `TexCoord1sv') +define(`f264_params', ``const GLshort *v'') +define(`f265_ret', `void') +define(`f265_name', `TexCoord2d') +define(`f265_params', ``GLdouble s, GLdouble t'') +define(`f266_ret', `void') +define(`f266_name', `TexCoord2dv') +define(`f266_params', ``const GLdouble *v'') +define(`f267_ret', `void') +define(`f267_name', `TexCoord2f') +define(`f267_params', ``GLfloat s, GLfloat t'') +define(`f268_ret', `void') +define(`f268_name', `TexCoord2fv') +define(`f268_params', ``const GLfloat *v'') +define(`f269_ret', `void') +define(`f269_name', `TexCoord2i') +define(`f269_params', ``GLint s, GLint t'') +define(`f270_ret', `void') +define(`f270_name', `TexCoord2iv') +define(`f270_params', ``const GLint *v'') +define(`f271_ret', `void') +define(`f271_name', `TexCoord2s') +define(`f271_params', ``GLshort s, GLshort t'') +define(`f272_ret', `void') +define(`f272_name', `TexCoord2sv') +define(`f272_params', ``const GLshort *v'') +define(`f273_ret', `void') +define(`f273_name', `TexCoord3d') +define(`f273_params', ``GLdouble s, GLdouble t, GLdouble r'') +define(`f274_ret', `void') +define(`f274_name', `TexCoord3dv') +define(`f274_params', ``const GLdouble *v'') +define(`f275_ret', `void') +define(`f275_name', `TexCoord3f') +define(`f275_params', ``GLfloat s, GLfloat t, GLfloat r'') +define(`f276_ret', `void') +define(`f276_name', `TexCoord3fv') +define(`f276_params', ``const GLfloat *v'') +define(`f277_ret', `void') +define(`f277_name', `TexCoord3i') +define(`f277_params', ``GLint s, GLint t, GLint r'') +define(`f278_ret', `void') +define(`f278_name', `TexCoord3iv') +define(`f278_params', ``const GLint *v'') +define(`f279_ret', `void') +define(`f279_name', `TexCoord3s') +define(`f279_params', ``GLshort s, GLshort t, GLshort r'') +define(`f280_ret', `void') +define(`f280_name', `TexCoord3sv') +define(`f280_params', ``const GLshort *v'') +define(`f281_ret', `void') +define(`f281_name', `TexCoord4d') +define(`f281_params', ``GLdouble s, GLdouble t, GLdouble r, GLdouble q'') +define(`f282_ret', `void') +define(`f282_name', `TexCoord4dv') +define(`f282_params', ``const GLdouble *v'') +define(`f283_ret', `void') +define(`f283_name', `TexCoord4f') +define(`f283_params', ``GLfloat s, GLfloat t, GLfloat r, GLfloat q'') +define(`f284_ret', `void') +define(`f284_name', `TexCoord4fv') +define(`f284_params', ``const GLfloat *v'') +define(`f285_ret', `void') +define(`f285_name', `TexCoord4i') +define(`f285_params', ``GLint s, GLint t, GLint r, GLint q'') +define(`f286_ret', `void') +define(`f286_name', `TexCoord4iv') +define(`f286_params', ``const GLint *v'') +define(`f287_ret', `void') +define(`f287_name', `TexCoord4s') +define(`f287_params', ``GLshort s, GLshort t, GLshort r, GLshort q'') +define(`f288_ret', `void') +define(`f288_name', `TexCoord4sv') +define(`f288_params', ``const GLshort *v'') +define(`f289_ret', `void') +define(`f289_name', `TexCoordPointer') +define(`f289_params', ``GLint size, GLenum type, GLsizei stride, const GLvoid *pointer'') +define(`f290_ret', `void') +define(`f290_name', `TexEnvf') +define(`f290_params', ``GLenum target, GLenum pname, GLfloat param'') +define(`f291_ret', `void') +define(`f291_name', `TexEnvfv') +define(`f291_params', ``GLenum target, GLenum pname, const GLfloat *params'') +define(`f292_ret', `void') +define(`f292_name', `TexEnvi') +define(`f292_params', ``GLenum target, GLenum pname, GLint param'') +define(`f293_ret', `void') +define(`f293_name', `TexEnviv') +define(`f293_params', ``GLenum target, GLenum pname, const GLint *params'') +define(`f294_ret', `void') +define(`f294_name', `TexGend') +define(`f294_params', ``GLenum coord, GLenum pname, GLdouble param'') +define(`f295_ret', `void') +define(`f295_name', `TexGendv') +define(`f295_params', ``GLenum coord, GLenum pname, const GLdouble *params'') +define(`f296_ret', `void') +define(`f296_name', `TexGenf') +define(`f296_params', ``GLenum coord, GLenum pname, GLfloat param'') +define(`f297_ret', `void') +define(`f297_name', `TexGenfv') +define(`f297_params', ``GLenum coord, GLenum pname, const GLfloat *params'') +define(`f298_ret', `void') +define(`f298_name', `TexGeni') +define(`f298_params', ``GLenum coord, GLenum pname, GLint param'') +define(`f299_ret', `void') +define(`f299_name', `TexGeniv') +define(`f299_params', ``GLenum coord, GLenum pname, const GLint *params'') +define(`f300_ret', `void') +define(`f300_name', `TexImage1D') +define(`f300_params', ``GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels'') +define(`f301_ret', `void') +define(`f301_name', `TexImage2D') +define(`f301_params', ``GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels'') +define(`f302_ret', `void') +define(`f302_name', `TexParameterf') +define(`f302_params', ``GLenum target, GLenum pname, GLfloat param'') +define(`f303_ret', `void') +define(`f303_name', `TexParameterfv') +define(`f303_params', ``GLenum target, GLenum pname, const GLfloat *params'') +define(`f304_ret', `void') +define(`f304_name', `TexParameteri') +define(`f304_params', ``GLenum target, GLenum pname, GLint param'') +define(`f305_ret', `void') +define(`f305_name', `TexParameteriv') +define(`f305_params', ``GLenum target, GLenum pname, const GLint *params'') +define(`f306_ret', `void') +define(`f306_name', `TexSubImage1D') +define(`f306_params', ``GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels'') +define(`f307_ret', `void') +define(`f307_name', `TexSubImage2D') +define(`f307_params', ``GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels'') +define(`f308_ret', `void') +define(`f308_name', `Translated') +define(`f308_params', ``GLdouble x, GLdouble y, GLdouble z'') +define(`f309_ret', `void') +define(`f309_name', `Translatef') +define(`f309_params', ``GLfloat x, GLfloat y, GLfloat z'') +define(`f310_ret', `void') +define(`f310_name', `Vertex2d') +define(`f310_params', ``GLdouble x, GLdouble y'') +define(`f311_ret', `void') +define(`f311_name', `Vertex2dv') +define(`f311_params', ``const GLdouble *v'') +define(`f312_ret', `void') +define(`f312_name', `Vertex2f') +define(`f312_params', ``GLfloat x, GLfloat y'') +define(`f313_ret', `void') +define(`f313_name', `Vertex2fv') +define(`f313_params', ``const GLfloat *v'') +define(`f314_ret', `void') +define(`f314_name', `Vertex2i') +define(`f314_params', ``GLint x, GLint y'') +define(`f315_ret', `void') +define(`f315_name', `Vertex2iv') +define(`f315_params', ``const GLint *v'') +define(`f316_ret', `void') +define(`f316_name', `Vertex2s') +define(`f316_params', ``GLshort x, GLshort y'') +define(`f317_ret', `void') +define(`f317_name', `Vertex2sv') +define(`f317_params', ``const GLshort *v'') +define(`f318_ret', `void') +define(`f318_name', `Vertex3d') +define(`f318_params', ``GLdouble x, GLdouble y, GLdouble z'') +define(`f319_ret', `void') +define(`f319_name', `Vertex3dv') +define(`f319_params', ``const GLdouble *v'') +define(`f320_ret', `void') +define(`f320_name', `Vertex3f') +define(`f320_params', ``GLfloat x, GLfloat y, GLfloat z'') +define(`f321_ret', `void') +define(`f321_name', `Vertex3fv') +define(`f321_params', ``const GLfloat *v'') +define(`f322_ret', `void') +define(`f322_name', `Vertex3i') +define(`f322_params', ``GLint x, GLint y, GLint z'') +define(`f323_ret', `void') +define(`f323_name', `Vertex3iv') +define(`f323_params', ``const GLint *v'') +define(`f324_ret', `void') +define(`f324_name', `Vertex3s') +define(`f324_params', ``GLshort x, GLshort y, GLshort z'') +define(`f325_ret', `void') +define(`f325_name', `Vertex3sv') +define(`f325_params', ``const GLshort *v'') +define(`f326_ret', `void') +define(`f326_name', `Vertex4d') +define(`f326_params', ``GLdouble x, GLdouble y, GLdouble z, GLdouble w'') +define(`f327_ret', `void') +define(`f327_name', `Vertex4dv') +define(`f327_params', ``const GLdouble *v'') +define(`f328_ret', `void') +define(`f328_name', `Vertex4f') +define(`f328_params', ``GLfloat x, GLfloat y, GLfloat z, GLfloat w'') +define(`f329_ret', `void') +define(`f329_name', `Vertex4fv') +define(`f329_params', ``const GLfloat *v'') +define(`f330_ret', `void') +define(`f330_name', `Vertex4i') +define(`f330_params', ``GLint x, GLint y, GLint z, GLint w'') +define(`f331_ret', `void') +define(`f331_name', `Vertex4iv') +define(`f331_params', ``const GLint *v'') +define(`f332_ret', `void') +define(`f332_name', `Vertex4s') +define(`f332_params', ``GLshort x, GLshort y, GLshort z, GLshort w'') +define(`f333_ret', `void') +define(`f333_name', `Vertex4sv') +define(`f333_params', ``const GLshort *v'') +define(`f334_ret', `void') +define(`f334_name', `VertexPointer') +define(`f334_params', ``GLint size, GLenum type, GLsizei stride, const GLvoid *pointer'') +define(`f335_ret', `void') +define(`f335_name', `Viewport') +define(`f335_params', ``GLint x, GLint y, GLsizei width, GLsizei height'') +define(`f336_ret', `int') +define(`f336_name', `SwapIntervalEXT') +define(`f336_params', `` int interval '') +define(`f337_ret', `int') +define(`f337_name', `ChoosePixelFormat ') +define(`f337_params', ``HDC, CONST PIXELFORMATDESCRIPTOR *'') +define(`f338_ret', `int') +define(`f338_name', `DescribePixelFormat') +define(`f338_params', ``HDC, int, UINT, LPPIXELFORMATDESCRIPTOR'') +define(`f339_ret', `int') +define(`f339_name', `GetPixelFormat') +define(`f339_params', ``HDC'') +define(`f340_ret', `BOOL') +define(`f340_name', `SetPixelFormat') +define(`f340_params', ``HDC, int, CONST PIXELFORMATDESCRIPTOR *'') +define(`f341_ret', `BOOL') +define(`f341_name', `SwapBuffers') +define(`f341_params', ``HDC'') +define(`f342_ret', `BOOL') +define(`f342_name', `CopyContext') +define(`f342_params', ``HGLRC, HGLRC, UINT'') +define(`f343_ret', `HGLRC') +define(`f343_name', `CreateContext') +define(`f343_params', ``HDC'') +define(`f344_ret', `HGLRC') +define(`f344_name', `CreateLayerContext') +define(`f344_params', ``HDC, int'') +define(`f345_ret', `BOOL') +define(`f345_name', `DeleteContext') +define(`f345_params', ``HGLRC'') +define(`f346_ret', `HGLRC') +define(`f346_name', `GetCurrentContext') +define(`f346_params', ``VOID'') +define(`f347_ret', `HDC') +define(`f347_name', `GetCurrentDC') +define(`f347_params', ``VOID'') +define(`f348_ret', `PROC') +define(`f348_name', `GetProcAddress') +define(`f348_params', ``LPCSTR'') +define(`f349_ret', `BOOL') +define(`f349_name', `MakeCurrent') +define(`f349_params', ``HDC, HGLRC'') +define(`f350_ret', `BOOL') +define(`f350_name', `ShareLists') +define(`f350_params', ``HGLRC, HGLRC'') +define(`f351_ret', `BOOL') +define(`f351_name', `UseFontBitmaps') +define(`f351_params', ``HDC, DWORD, DWORD, DWORD'') +define(`f352_ret', `BOOL') +define(`f352_name', `UseFontOutlines') +define(`f352_params', ``HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT'') +define(`f353_ret', `BOOL') +define(`f353_name', `DescribeLayerPlane') +define(`f353_params', ``HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR'') +define(`f354_ret', `int') +define(`f354_name', `SetLayerPaletteEntries') +define(`f354_params', ``HDC, int, int, int, CONST COLORREF *'') +define(`f355_ret', `int') +define(`f355_name', `GetLayerPaletteEntries') +define(`f355_params', ``HDC, int, int, int, COLORREF *'') +define(`f356_ret', `BOOL') +define(`f356_name', `RealizeLayerPalette') +define(`f356_params', ``HDC, int, BOOL'') +define(`f357_ret', `BOOL') +define(`f357_name', `SwapLayerBuffers') +define(`f357_params', ``HDC, UINT'') +define(`f358_ret', `XVisualInfo *') +define(`f358_name', `ChooseVisual') +define(`f358_params', ``Display *dpy, int screen, int *attribList'') +define(`f359_ret', `GLXContext') +define(`f359_name', `CreateContext') +define(`f359_params', ``Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct'') +define(`f360_ret', `void') +define(`f360_name', `DestroyContext') +define(`f360_params', ``Display *dpy, GLXContext ctx'') +define(`f361_ret', `Bool') +define(`f361_name', `MakeCurrent') +define(`f361_params', ``Display *dpy, GLXDrawable drawable, GLXContext ctx'') +define(`f362_ret', `void') +define(`f362_name', `SwapBuffers') +define(`f362_params', ``Display *dpy, GLXDrawable drawable'') +define(`f363_ret', `GLExtension_t') +define(`f363_name', `GetProcAddressARB') +define(`f363_params', ``const GLubyte *procname'') + diff --git a/sys/gllog/gl_extensions.cpp.m4 b/sys/gllog/gl_extensions.cpp.m4 new file mode 100644 index 000000000..aaae369c8 --- /dev/null +++ b/sys/gllog/gl_extensions.cpp.m4 @@ -0,0 +1,61 @@ +#include "idlib/precompiled.h" +#pragma hdrstop + +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl GL extensions +dnl ===================================================== + +typedef struct { + const char *ext_name; +} glExtName_t; + +glExtName_t glExtNames[] = { + NULL +}; + +static void StubFunction( void ) { } + +GLExtension_t GLimp_ExtensionPointer( const char *name ) { + if ( strstr( name, "wgl" ) == name ) { + common->DPrintf( "WARNING: GLimp_ExtensionPointer for '%s'\n", name ); + } +#ifdef ID_DEDICATED + common->Printf("GLimp_ExtensionPointer %s\n", name); + return StubFunction; +#else + #if 0 + glExtName_t *n; + for ( n = glExtNames ; n->ext_name ; n++ ) { + if ( !strcmp( name, n->ext_name ) ) { + common->DPrintf("matched GL extension: %s\n", name ); + break; + } + } + if ( ! n->ext_name ) { + common->DPrintf("unmatched GL extension name: %s\n", name ); + } + #endif + GLExtension_t ret; + #if defined(__linux__) + // for some reason glXGetProcAddressARB doesn't work on RH9? + ret = qglXGetProcAddressARB((const GLubyte *) name); + if ( !ret ) { + common->Printf("glXGetProcAddressARB failed: \"%s\"\n", name); + return StubFunction; + } + #else + #error Need OS define + #endif + return ret; +#endif +} diff --git a/sys/gllog/logfunc.py b/sys/gllog/logfunc.py new file mode 100644 index 000000000..3a9e46f0d --- /dev/null +++ b/sys/gllog/logfunc.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# generate logging code +# this requires an analysis of the parameters for verbose and do actual call + +import sys, string, re +from read import read_gl + +def do_logfunc(f_in, f_out): + + (gl, wgl, glX) = read_gl(f_in) + + for l in (gl, glX): + for t in l: + # process ret type to strip trailing spaces + t[0] = string.strip(t[0]) + f_out.write('static %s APIENTRY log%s(%s) {\n' % ( t[0], t[2], t[3] )) + # work on parameters + base_params = string.split(t[3], ',') + #f_out.write('// %s\n' % repr(base_params)) + # init format string and parameter list + params = [] + format = t[1][1:] + t[2] + # a general help list + types = [] + names = [] + for i in base_params: + regex = re.compile('([a-zA-Z0-9]*)$') + name = regex.search(i).group(1) + type = string.strip(i[0:len(i)-len(name)]) + # catch type with no name + if (len(type) == 0): + type = name + name = '' + #f_out.write('// type: "%s" name: "%s"\n' % (type, name)) + types.append(type) + names.append(name) + # verbose the types + if (type == 'GLenum'): + format += ' %s' + params.append( 'EnumString(' + name + ')' ) + elif (type == 'GLfloat' or type == 'GLclampf' or type == 'GLdouble'): + format += ' %g' + params.append( name ) + elif (type == 'GLint' or type == 'GLuint' or type == 'GLsizei' or type == 'GLbyte' or type == 'GLshort' + or type == 'GLubyte' or type == 'GLushort'): + format += ' %d' + params.append( name ) + elif (type == 'GLboolean'): + format += ' %s' + params.append( name + ' ? "Y" : "N"' ) + elif (type == 'void'): + pass + else: + f_out.write('// unknown type: "%s" name: "%s"\n' % (type, name)) + format += ' \'' + type + ' ' + name + '\'' + f_out.write('\tfprintf( tr.logFile, "' + format + '\\n"') + for par in params: + f_out.write(', ' + par) + f_out.write(' );\n') + if (t[0] != 'void'): + f_out.write('\treturn dll%s(' % t[2]) + else: + f_out.write('\tdll%s(' % t[2]) + started = 0 + for i in names: + if (started): + f_out.write(', ') + else: + started = 1 + f_out.write(i) + f_out.write(');\n') + f_out.write('}\n\n') + +if __name__ == '__main__': + do_logfunc(sys.stdin, sys.stdout) diff --git a/sys/gllog/read.py b/sys/gllog/read.py new file mode 100644 index 000000000..502322d43 --- /dev/null +++ b/sys/gllog/read.py @@ -0,0 +1,26 @@ +# utility module to process incoming GL description + +import sys, string + +def read_gl(f_in): + buffer = f_in.read() + lines = string.split(buffer, '\n') + + gl = [] + wgl = [] + glX = [] + + for line in lines: + if ( len(line) ): # drop empty lines + tokens = string.split(line, ';') + if ( tokens[1] == 'qgl' ): + gl.append(tokens) + elif ( tokens[1] == 'qwgl' ): + wgl.append(tokens) + elif ( tokens[1] == 'qglX' ): + glX.append(tokens) + else: + sys.stderr.write('ERROR: unknown type %s\n' % tokens[1]) + raise "abort" + + return (gl, wgl, glX) diff --git a/sys/gllog/wgl.api b/sys/gllog/wgl.api new file mode 100644 index 000000000..736600e9a --- /dev/null +++ b/sys/gllog/wgl.api @@ -0,0 +1,22 @@ +int ;qwgl;SwapIntervalEXT; int interval +int ;qwgl;ChoosePixelFormat ;HDC, CONST PIXELFORMATDESCRIPTOR * +int ;qwgl;DescribePixelFormat;HDC, int, UINT, LPPIXELFORMATDESCRIPTOR +int ;qwgl;GetPixelFormat;HDC +BOOL ;qwgl;SetPixelFormat;HDC, int, CONST PIXELFORMATDESCRIPTOR * +BOOL ;qwgl;SwapBuffers;HDC +BOOL ;qwgl;CopyContext;HGLRC, HGLRC, UINT +HGLRC ;qwgl;CreateContext;HDC +HGLRC ;qwgl;CreateLayerContext;HDC, int +BOOL ;qwgl;DeleteContext;HGLRC +HGLRC ;qwgl;GetCurrentContext;VOID +HDC ;qwgl;GetCurrentDC;VOID +PROC ;qwgl;GetProcAddress;LPCSTR +BOOL ;qwgl;MakeCurrent;HDC, HGLRC +BOOL ;qwgl;ShareLists;HGLRC, HGLRC +BOOL ;qwgl;UseFontBitmaps;HDC, DWORD, DWORD, DWORD +BOOL ;qwgl;UseFontOutlines;HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT +BOOL ;qwgl;DescribeLayerPlane;HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR +int ;qwgl;SetLayerPaletteEntries;HDC, int, int, int, CONST COLORREF * +int ;qwgl;GetLayerPaletteEntries;HDC, int, int, int, COLORREF * +BOOL ;qwgl;RealizeLayerPalette;HDC, int, BOOL +BOOL ;qwgl;SwapLayerBuffers;HDC, UINT diff --git a/sys/linux/SDK-1.3.list.txt b/sys/linux/SDK-1.3.list.txt new file mode 100644 index 000000000..5a0054218 --- /dev/null +++ b/sys/linux/SDK-1.3.list.txt @@ -0,0 +1,557 @@ +378c21cf872ef830445ce18b3d3348f8 *base/animation/mp_greenarmor.md5mesh +7f9b7629c712056e48ceac9dadb16224 *base/animation/mp_jumpsuit.md5mesh +caf59e47ec1988d81fdcc3c8aeb8981f *base/animation/mp_labcoat.md5mesh +3982a493fe0da57c13e96fc8e1d6a795 *base/animation/mp_security.md5mesh +c23ac9aeb96d3ef55595c7d668d948cd *base/animation/mp_soldier.md5mesh +24046a3a459bf42fd1ea555d0b75fdfc *base/animation/mp_suit.md5mesh +6509fbcd1ce02e81bf0f95954405bea4 *base/animation/mp_tshirt.md5mesh +683d3f4c114f803873775a559a43a7c1 *base/def/npcs_as_player.def +20729461e1831236acae7ca5b73b0319 *base/maps/fred/cyberdemon/monster_wakeups.mb +2d7df07f33ffbacaf16c51942524b55c *base/maps/fred/underground/impintro.mb +fce124d3f5d717eee4a7d89ad02eca7a *base/maps/fred/underground/impscurry.mb +b60db9fae92e89f9b5cc25cd0a4253f6 *base/maps/fred/underground/impstairs.mb +185553b6f3ab20b1994f07798cd0a156 *base/models/monsters/imp/animation/cycles/alert_walk.ma +b20bf698a63d5eb0a876f1d41b47aaae *base/models/monsters/imp/animation/cycles/crouched_range1.ma +34c73f22a4a1eeee9bb4eae68688917b *base/models/monsters/imp/animation/cycles/evade_left.ma +76ff5398bcf1aebb08641bc5dfacd716 *base/models/monsters/imp/animation/cycles/evade_left_on4.ma +81203ea3773a820074b2fbc2c2e17e37 *base/models/monsters/imp/animation/cycles/evade_right.ma +a05cba4afb38f709eede99fc8b7fdf83 *base/models/monsters/imp/animation/cycles/evade_right_on4.ma +9ce3fb5c02f00f004c13da995ac8e51f *base/models/monsters/imp/animation/cycles/faster_walk.ma +3d960bbfb56e51ca9735905d49d83c3a *base/models/monsters/imp/animation/cycles/fireball_sight.ma +0779e202728e8b80a48d950bbf74c4e0 *base/models/monsters/imp/animation/cycles/hangonceiling.ma +7fcfc63044c8111485813efe6af5b066 *base/models/monsters/imp/animation/cycles/idle1.ma +110661e6211291d098bace0a26f1a483 *base/models/monsters/imp/animation/cycles/imp.mb +cd0971e695d81001820e9222313a4955 *base/models/monsters/imp/animation/cycles/initial.ma +6ec1b1abe0c585726636149f54f8e9dc *base/models/monsters/imp/animation/cycles/jump_loop.ma +6be7606a2cb7135eed7b583145d0f572 *base/models/monsters/imp/animation/cycles/jump_loop2.ma +e8ae6eb85a5bfe7a9190dbf3279d4ea1 *base/models/monsters/imp/animation/cycles/jump_loop3.ma +6412062ceb0cd3256cc78e49c2e4909a *base/models/monsters/imp/animation/cycles/offwall.ma +ab814d600992f29204655e3415971e3e *base/models/monsters/imp/animation/cycles/on4_idle.ma +b54f250dd00b0b9b24c31c6b14871629 *base/models/monsters/imp/animation/cycles/on4_melee1.ma +64dd04c941a7a7f174583d34d035eebc *base/models/monsters/imp/animation/cycles/on4_melee2.ma +ec39d4020b208de213f56c095c0406d3 *base/models/monsters/imp/animation/cycles/on4_sight.ma +b9133fba76754d0691e31c788d33dcd7 *base/models/monsters/imp/animation/cycles/outofhole.ma +75f00d3a2077f0b9378424fd64cadc1d *base/models/monsters/imp/animation/cycles/pain3.ma +c0cf15bd8e7b331118f3f2a253c8d1a6 *base/models/monsters/imp/animation/cycles/pain_chest.ma +4f3b231d9c0dd5bc144f91aaefa95f9d *base/models/monsters/imp/animation/cycles/pain_chest_on4.ma +a3fda68e30e70c7de009f008832cc849 *base/models/monsters/imp/animation/cycles/pain_head.ma +ebab78e4555f5ce417e7a918b857a299 *base/models/monsters/imp/animation/cycles/pain_head_on4.ma +6a2da31bf0ab40750d93f4f334432271 *base/models/monsters/imp/animation/cycles/pain_luparm.ma +4277b9a5f30f28106f0fd4fadd008d03 *base/models/monsters/imp/animation/cycles/pain_luparm_on4.ma +506a7b9b631f70afcab174b4df6672d2 *base/models/monsters/imp/animation/cycles/pain_ruparm.ma +d72684a507481948165939c762a94d14 *base/models/monsters/imp/animation/cycles/pain_ruparm_on4.ma +2d5f4a7997cfbffd9a9f3aaa93b8cb96 *base/models/monsters/imp/animation/cycles/range1.ma +4a18cb9d675f4fdb20f31bc34d0f126c *base/models/monsters/imp/animation/cycles/range2.ma +e56ceccbeb0b39929e69792e6ca493cd *base/models/monsters/imp/animation/cycles/range3.ma +93d4ee499d9d183e44db78cb49d76128 *base/models/monsters/imp/animation/cycles/run.ma +7d8b78d2414c775e0718857ade6d607c *base/models/monsters/imp/animation/cycles/scurry2.ma +51b92152e848f5df97d37ba1e5ea4937 *base/models/monsters/imp/animation/cycles/scurry_leap2.ma +ef071d4959c55540bf28ec90408537bb *base/models/monsters/imp/animation/cycles/sight.ma +44b4b5bebf62d8a7b5173593dfc2ad9d *base/models/monsters/imp/animation/cycles/sight2.ma +e0eeef3455d1dabcc924c328b24ec236 *base/models/monsters/imp/animation/cycles/slash1.ma +2490f2dab58229e1d37bfe27201c94ac *base/models/monsters/imp/animation/cycles/slash2.ma +7c59693fba6b19053042c65cc8424491 *base/models/monsters/imp/animation/cycles/slash3.ma +db049810b1429fcf53ac482fe1b0fd4c *base/models/monsters/imp/animation/cycles/teleportin.ma +f82822c0fe0b8ddb287af934259d98e9 *base/models/monsters/imp/animation/cycles/turret_attack1.ma +b8828a357c293183b3a6bcec9a8d594e *base/models/monsters/imp/animation/cycles/turret_idle.ma +75b85d1dd46885051553df964e0e8dad *base/models/monsters/imp/fred/imp_setup.mb +fc2e0afe9f6e596709c8635035105697 *base/models/monsters/imp/fred/imp_setup_ik.mb +2645732cd30bfd33309e4b801e74971c *base/models/weapons/machinegun/cycles/empty.ma +162eee06b15fffaabbc267f72f66ad7c *base/models/weapons/machinegun/cycles/fire1.ma +799523e4fb25e9f97e2bc197f1c783b9 *base/models/weapons/machinegun/cycles/fire2.ma +2f8536ac728bb97e163b7fcc3669ba44 *base/models/weapons/machinegun/cycles/fire4.ma +8ccb8b80b363da587015fcce7167f526 *base/models/weapons/machinegun/cycles/idle1.ma +2553b66bdb33e6bd85a1d7bccd936237 *base/models/weapons/machinegun/cycles/pullup1.ma +c703ec87330cdc52d4bad4dd2aac7de7 *base/models/weapons/machinegun/cycles/putaway.ma +4e9a4ba4caa2e209c66761ffe9f6cd8c *base/models/weapons/machinegun/cycles/reload1.ma +6b19b0dbd4bb6554b9b449713d4fd102 *base/models/weapons/machinegun/fred/setup1.mb +326a538229b875b8a9f5506c2bffe4f6 *EULA.Development Kit.rtf +9380e8d182dbf689d65399c090d536b1 *MayaImportx86_Maya45.zip +28fadd7a28667156d79e93c063bf7252 *MayaImportx86_Maya50.zip +ff7e2e1bffcb4283f7333d43e722f02e *MayaImportx86_Maya60.zip +bf55402b75174f2f5a9f4edfea7726ee *src/cm/CollisionModel.h +8f16a997da6fb272f981af6b975b83cc *src/D3Game.sln +6a7b0e721547e7eea469def7bb1020bd *src/D3Game.vcproj +609ef5002dfcd7a4dbbd65fc98985771 *src/d3xp/Actor.cpp +e021ebde2e2c285c1098b47b9c3fd752 *src/d3xp/Actor.h +8ee17110c7f42eecfc7b17d8dce8a896 *src/d3xp/AF.cpp +ec286d2cf851db847021795908d27c12 *src/d3xp/AF.h +be96bde8ab623fba6fed2d7bfef69972 *src/d3xp/AFEntity.cpp +3df4135723036359306ab6f5b70c5b2a *src/d3xp/AFEntity.h +f03ba687f94f1ffb13ac814486de2340 *src/d3xp/ai/AAS.cpp +3ee992286f1b1641cdcfc6d443b99d14 *src/d3xp/ai/AAS.h +8035de9626e57d12c848b77546feccb3 *src/d3xp/ai/AAS_debug.cpp +6c2876fc8190a0d3f3789b1577c45ec1 *src/d3xp/ai/AAS_local.h +b1823e1aad4d2261f9d5d9bc06d5a95f *src/d3xp/ai/AAS_pathing.cpp +62fe990c48174e83fdaeeaf63f58d07a *src/d3xp/ai/AAS_routing.cpp +3a52b74d73d3c7f6075a2c0653a995cb *src/d3xp/ai/AI.cpp +923f30cfee35f577ce6ddb6352c2a395 *src/d3xp/ai/AI.h +642add3259a90045d8c2cf8825ebecc9 *src/d3xp/ai/AI_events.cpp +675d4dbfab5c332c53313d9d9e7ec4d4 *src/d3xp/ai/AI_pathing.cpp +a730df35afccadc7382d140ee28b3aea *src/d3xp/ai/AI_Vagary.cpp +b8bc423a3369d61df9b9b7bc22a7ebd9 *src/d3xp/anim/Anim.cpp +f0d3778c1f07cdd3597dc2e92083e8b2 *src/d3xp/anim/Anim.h +76dc3f6619db3a662c3b48f7cb35a748 *src/d3xp/anim/Anim_Blend.cpp +9e8f6846e171fceb6bbc91a59f8a4b38 *src/d3xp/anim/Anim_Import.cpp +5eaee1875ce7dcf2c00f1f3ed7a46d23 *src/d3xp/anim/Anim_Testmodel.cpp +9e09b5e8640ec36f86761e77dcd855c9 *src/d3xp/anim/Anim_Testmodel.h +373d73b53b5da81ed41c78362529adfd *src/d3xp/BrittleFracture.cpp +dfd92ed51972e5c71a380d7a8dd1d884 *src/d3xp/BrittleFracture.h +feb9a864a3f21e1634d6d4236fe648b4 *src/d3xp/Camera.cpp +302973226944e14dc3a26fed1912d5cf *src/d3xp/Camera.h +d58c6b6f1de81aef4b25abe9b96ed5f9 *src/d3xp/EndLevel.cpp +a44b0e64ba6b4430dbc76363503c8256 *src/d3xp/EndLevel.h +b769dd82e2d36798d36db4c2f4e0b692 *src/d3xp/Entity.cpp +607329b1cb6cfa5ffb84cdf82243c140 *src/d3xp/Entity.h +6d9e2f4eb00479828e8f30316aff738a *src/d3xp/Fx.cpp +a7973abe1874af163b24d9725e60ed0a *src/d3xp/Fx.h +9366293139f568d4f2ed28d9447e7c5e *src/d3xp/Game.def +38a2c8e488554a9be6c131bb0e2da37b *src/d3xp/Game.h +05b14ef43c96a51b4e1fce10cbfb8d2a *src/d3xp/GameEdit.cpp +1d9a0d89c3e2d05fb26c60d68c3e17ad *src/d3xp/GameEdit.h +42cf780f56a4f2c040aac9e81d70b4bb *src/d3xp/gamesys/Callbacks.cpp +d41593aeea150ec1d6440f5ce89a3844 *src/d3xp/gamesys/Class.cpp +e3d5465ac9a9ca711f2ea834e10b5fa6 *src/d3xp/gamesys/Class.h +279bde28025a669dbf47ee435dab52a8 *src/d3xp/gamesys/DebugGraph.cpp +9281bfa4a0c7d44992a5b69acbed0a74 *src/d3xp/gamesys/DebugGraph.h +06dd9ed4044d3730158aabb13f145f61 *src/d3xp/gamesys/Event.cpp +d8bf67cdc20f5d3fce663ac0474cc6ed *src/d3xp/gamesys/Event.h +969aae4b4f3c5a51c342226c5f6b6d66 *src/d3xp/gamesys/NoGameTypeInfo.h +559710b116b86fc5c5acba51b77017b3 *src/d3xp/gamesys/SaveGame.cpp +2f6856143057bf29dcfe38d61b59c863 *src/d3xp/gamesys/SaveGame.h +8d719e9d48a98d06d1989b31445f6888 *src/d3xp/gamesys/SysCmds.cpp +4b62f19c063511dee00c83845ce7f320 *src/d3xp/gamesys/SysCmds.h +7ed932dd12c96aa90512aaf63c72fdb0 *src/d3xp/gamesys/SysCvar.cpp +e31def85db9695c6dd45748a32d8aa27 *src/d3xp/gamesys/SysCvar.h +bff6543d6ab3ebbb7d72aecde1802847 *src/d3xp/gamesys/TypeInfo.cpp +9e29ac4220a128524accb58d587470c2 *src/d3xp/gamesys/TypeInfo.h +4ce41c1583e13dee525c3962599d4344 *src/d3xp/Game_local.cpp +c47b817da63b29e136b1dd15cc6616c5 *src/d3xp/Game_local.h +228d27ea27c967bb957cbe6d79d50628 *src/d3xp/Game_network.cpp +c48750d415082e129b09f411b9d0fbb2 *src/d3xp/Grabber.cpp +406bec75a737035f70b7be3a896fc6d9 *src/d3xp/Grabber.h +24c6f213c515acae0b2ea944ed4f43f7 *src/d3xp/IK.cpp +df74f5d7c6a346ee41a131864ac33a06 *src/d3xp/IK.h +df4cccd9cd3c0c99493ac0f9e47b1dbc *src/d3xp/Item.cpp +5785684b4a10ebf97e10fd0bb41935b9 *src/d3xp/Item.h +25b79617784ac8c64d7bb434e495d165 *src/d3xp/Light.cpp +eccb2ba974b76556f6a4c4ca6eb1dacc *src/d3xp/Light.h +a75990488c6bb8cb16247628284344fa *src/d3xp/Misc.cpp +0ad06a3bd56fe62eba01f5c24f208f75 *src/d3xp/Misc.h +c2824dbb60f8347ececf844948d76b69 *src/d3xp/Moveable.cpp +587639d8691f7d80dece057c17234cb4 *src/d3xp/Moveable.h +8a1385d5eaea984d06a21d97f5e5e048 *src/d3xp/Mover.cpp +26f8c0f67edf54dbd285e13692fcd6d8 *src/d3xp/Mover.h +8e094d0fcfd8f7528550f767467e1071 *src/d3xp/MultiplayerGame.cpp +e95b920500a5362ae56aad165a9c1ea4 *src/d3xp/MultiplayerGame.h +b6fdf3e143262315398b1f6450ee2040 *src/d3xp/physics/Clip.cpp +577044d81536fd081d936705bad6e669 *src/d3xp/physics/Clip.h +db95fc8774df9f0971ffa47db89cd709 *src/d3xp/physics/Force.cpp +9271f887b94b4dd70e8e31582c3cc765 *src/d3xp/physics/Force.h +8891ce4f1b093c485c4838c65d35fa45 *src/d3xp/physics/Force_Constant.cpp +fd9feebfee3a799541f006879eb569c3 *src/d3xp/physics/Force_Constant.h +56187680952cacefb0fb8b689612ec2f *src/d3xp/physics/Force_Drag.cpp +0fb5bef472d8710b8b0c4961ac424309 *src/d3xp/physics/Force_Drag.h +b3805a50b055009e514413935d48eaae *src/d3xp/physics/Force_Field.cpp +39024be5e301ab2949250a90a12e3f1e *src/d3xp/physics/Force_Field.h +9f5f99daf42da885db42e5c4e57bb51b *src/d3xp/physics/Force_Grab.cpp +5e651bd825ca342d7b1aecbc776c347f *src/d3xp/physics/Force_Grab.h +4868787409b28a30fc337721bf52b2d5 *src/d3xp/physics/Force_Spring.cpp +a3079b4e01fa293555d62767e9a75eb5 *src/d3xp/physics/Force_Spring.h +d60b09eced926973a02624fe72c097ad *src/d3xp/physics/Physics.cpp +d2e28cc845e5640d8465214a84c2219c *src/d3xp/physics/Physics.h +03635081f0b4f12746d939b8ae94fc4c *src/d3xp/physics/Physics_Actor.cpp +056e1e0d7f36cac413c78094c63c50e8 *src/d3xp/physics/Physics_Actor.h +cd8c76ad5acbc0fcf7574f24449bdf6b *src/d3xp/physics/Physics_AF.cpp +cb3e0bcb7e1788cfdbdba12d66f9ed00 *src/d3xp/physics/Physics_AF.h +61579ebbcf21ec719e7258d0d1e906c7 *src/d3xp/physics/Physics_Base.cpp +e439ac91101079a93ba687470bbdb713 *src/d3xp/physics/Physics_Base.h +ef50cc527673f51394cf8bf9e823eec6 *src/d3xp/physics/Physics_Monster.cpp +c07dc14cdc28823871ced4cfb834cfc8 *src/d3xp/physics/Physics_Monster.h +280e64fa2d3ee444e26f32305bc3d898 *src/d3xp/physics/Physics_Parametric.cpp +f93bdcc492f50db67878e2274044d7ab *src/d3xp/physics/Physics_Parametric.h +226d608f2cb7d279bad12e84a2558735 *src/d3xp/physics/Physics_Player.cpp +572fe5e12fae49bcd35f264edb765890 *src/d3xp/physics/Physics_Player.h +206f12b48f11aba0d189ba5316171765 *src/d3xp/physics/Physics_RigidBody.cpp +8e3baa7b3e82350a908a3865f6c3a0d3 *src/d3xp/physics/Physics_RigidBody.h +cd1687b82e2361c803bd528e94d393a7 *src/d3xp/physics/Physics_Static.cpp +ca2ae3f0cc147acd3743a97e4184b43d *src/d3xp/physics/Physics_Static.h +e2d822925adc488b22682937303b47f8 *src/d3xp/physics/Physics_StaticMulti.cpp +f6ca48445ad2a16ae42ebd067a3dfc5b *src/d3xp/physics/Physics_StaticMulti.h +39d50cc9f5bb1ceb1beca9c6aab64f68 *src/d3xp/physics/Push.cpp +b1f7b4d666e0d79646aec2c1ada2be19 *src/d3xp/physics/Push.h +76aae671ab2b12cb0022d5859bb2d715 *src/d3xp/Player.cpp +12fe0735c8a24ef83de5f91e13a21887 *src/d3xp/Player.h +6bac787dba83b9aab9d99d037562f0d1 *src/d3xp/PlayerIcon.cpp +e17dd547ff1e2fda1369b05fcb9998b9 *src/d3xp/PlayerIcon.h +1393ea8b429ae7c5e658ea769db5dd3d *src/d3xp/PlayerView.cpp +a9afb5112b1bac6479fef477f22510ac *src/d3xp/PlayerView.h +508628cf9eb4db7770a11977faa4e673 *src/d3xp/Projectile.cpp +2f21b17607d99c6e4abc81b2bc267e33 *src/d3xp/Projectile.h +94b9b826cb3b22efb20214746cc1bf9a *src/d3xp/Pvs.cpp +ffaa9d395efff49ab6ff2a93acdf38b0 *src/d3xp/Pvs.h +729a5e05412a6dd575d6060791ddb182 *src/d3xp/script/Script_Compiler.cpp +91da92aed14ed2748b2016b8bfd13a5b *src/d3xp/script/Script_Compiler.h +9b60efb81c99a2e1c4025a25791c28ba *src/d3xp/script/Script_Interpreter.cpp +edd8ba8f11fce2ad962132e5f5ab8223 *src/d3xp/script/Script_Interpreter.h +c218b13187e3eaea5b9b959b4613b047 *src/d3xp/script/Script_Program.cpp +95a28d256a674129093e3a14f42cea38 *src/d3xp/script/Script_Program.h +946a4187a787ef8120f90e24e3d2dfd8 *src/d3xp/script/Script_Thread.cpp +0df0e56033f991077d9d054b9b18484c *src/d3xp/script/Script_Thread.h +f829cf1a432bb36437a916d7c8597569 *src/d3xp/SecurityCamera.cpp +8ef631e222158b65ee9a4f5c04bff6df *src/d3xp/SecurityCamera.h +99a58d1af9464d796ff4537c072608c8 *src/d3xp/SmokeParticles.cpp +30d41919db27d7600169f5ed886aeb46 *src/d3xp/SmokeParticles.h +7abad18d9f8f26669f7f4bc444a2489c *src/d3xp/Sound.cpp +482b351917af91e26b3c52645674104f *src/d3xp/Sound.h +38c6668315c01520f07dc7f2134ba3c2 *src/d3xp/Target.cpp +079bb3ed19973e52f9944165c8a2cf8c *src/d3xp/Target.h +303efbefe3bee4117e2466a57f56a1d1 *src/d3xp/Trigger.cpp +dd78cff2ac2be9dc7c0beb14aad2a20a *src/d3xp/Trigger.h +e45231d0f27716cdf308fc048c94b7d7 *src/d3xp/Weapon.cpp +c5d570261b1b24b5d90ebad5334e6b59 *src/d3xp/Weapon.h +adba1c884614cd0905abf3cca7ff1fa8 *src/d3xp/WorldSpawn.cpp +ae46f21bfaa3e91ee35f3368971800d1 *src/d3xp/WorldSpawn.h +39efa6ceb0d4a2e49a294abc70e0b16f *src/framework/async/NetworkSystem.h +273611f1a7af9cb6288bea43d2a5ae79 *src/framework/BuildDefines.h +4d0c82a0fc96821e63b2d1d4c7f07f9e *src/framework/BuildVersion.h +644b096ee1860abc9f06bedc06152082 *src/framework/CmdSystem.h +a73c7364daaee253fa2314f720f61948 *src/framework/Common.h +06c73e4fcf5f702cd4bf66f80086cfac *src/framework/CVarSystem.h +52f04ff903d39b681286a1fe2a7ee1c9 *src/framework/DeclAF.h +4f180083323a00d3883dc96883794f2f *src/framework/DeclEntityDef.h +f189f846aed6e295f27010a96b0060f9 *src/framework/DeclFX.h +0125144f1ce930d448dfd34d7f6deb74 *src/framework/DeclManager.h +a6e5cede15b3b172a4aea25033a1ce8a *src/framework/DeclParticle.h +3adfa181f3e77f9d403de8a0a18d0c95 *src/framework/DeclPDA.h +75b9fde04b70378da3bebcfd767b14aa *src/framework/DeclSkin.h +3d69c1de8791eb5c1c48a4ce16386506 *src/framework/DeclTable.h +cde67b0bcd56918e6bf347051cfbb1f2 *src/framework/File.h +2ca611aadf0fc9fc7317b699b94878a3 *src/framework/FileSystem.h +ef0fa4c766607796ae068177cb3c5ed0 *src/framework/Licensee.h +1e732ba0bcceb091e22bd620f875e461 *src/framework/UsercmdGen.h +676dffd79e0e17e643a17c75db07f7eb *src/game/Actor.cpp +87accdd5fdf457551d5853680fafb141 *src/game/Actor.h +8ee17110c7f42eecfc7b17d8dce8a896 *src/game/AF.cpp +ec286d2cf851db847021795908d27c12 *src/game/AF.h +3ab86ad5934be48831b5fdc590a1e0ca *src/game/AFEntity.cpp +7bf66006050beda99b11c8040251b129 *src/game/AFEntity.h +f03ba687f94f1ffb13ac814486de2340 *src/game/ai/AAS.cpp +3ee992286f1b1641cdcfc6d443b99d14 *src/game/ai/AAS.h +8035de9626e57d12c848b77546feccb3 *src/game/ai/AAS_debug.cpp +6c2876fc8190a0d3f3789b1577c45ec1 *src/game/ai/AAS_local.h +b1823e1aad4d2261f9d5d9bc06d5a95f *src/game/ai/AAS_pathing.cpp +62fe990c48174e83fdaeeaf63f58d07a *src/game/ai/AAS_routing.cpp +207d34d5ed57e3d3d79d8d3cbd2d7105 *src/game/ai/AI.cpp +e117ef64f3e28f917ee42d86c71b7738 *src/game/ai/AI.h +e8522f3d8987358fac73f5cb9cd57b23 *src/game/ai/AI_events.cpp +675d4dbfab5c332c53313d9d9e7ec4d4 *src/game/ai/AI_pathing.cpp +a730df35afccadc7382d140ee28b3aea *src/game/ai/AI_Vagary.cpp +b8bc423a3369d61df9b9b7bc22a7ebd9 *src/game/anim/Anim.cpp +b86f393f092421ca83abb354c5b72e91 *src/game/anim/Anim.h +7472f4426325fbaefa626cefd0a3b20d *src/game/anim/Anim_Blend.cpp +40697f546da5b79869176fae43ae032d *src/game/anim/Anim_Import.cpp +435edccefcd102e7fb0b0c80a5eb0245 *src/game/anim/Anim_Testmodel.cpp +9e09b5e8640ec36f86761e77dcd855c9 *src/game/anim/Anim_Testmodel.h +a4b10676ad0e6ee543d3f0b9359cdddd *src/game/BrittleFracture.cpp +a011977466a557e80be87b1556e3c417 *src/game/BrittleFracture.h +f6e5d2601ac1335f82692b61ff1a1db1 *src/game/Camera.cpp +302973226944e14dc3a26fed1912d5cf *src/game/Camera.h +85577e4a1c931b9af59522c7c88f8a84 *src/game/Entity.cpp +b1d0ce6a101bc2eeaa1e94da673c7933 *src/game/Entity.h +502b575f49ac63603fe1edd6fd89745d *src/game/Fx.cpp +a7973abe1874af163b24d9725e60ed0a *src/game/Fx.h +9366293139f568d4f2ed28d9447e7c5e *src/game/Game.def +72d72b2daad9ddbd64e220b55ebe15f1 *src/game/Game.h +05b14ef43c96a51b4e1fce10cbfb8d2a *src/game/GameEdit.cpp +1d9a0d89c3e2d05fb26c60d68c3e17ad *src/game/GameEdit.h +42cf780f56a4f2c040aac9e81d70b4bb *src/game/gamesys/Callbacks.cpp +b514e5d3538868f7eac92c0d0f0c6faf *src/game/gamesys/Class.cpp +e3d5465ac9a9ca711f2ea834e10b5fa6 *src/game/gamesys/Class.h +279bde28025a669dbf47ee435dab52a8 *src/game/gamesys/DebugGraph.cpp +9281bfa4a0c7d44992a5b69acbed0a74 *src/game/gamesys/DebugGraph.h +a36db41f4a68559b7505cad8586dd383 *src/game/gamesys/Event.cpp +2c07d3323c81aed109ef1b1a01f43db7 *src/game/gamesys/Event.h +969aae4b4f3c5a51c342226c5f6b6d66 *src/game/gamesys/NoGameTypeInfo.h +cba93e29ca437d72706091b0a187ab35 *src/game/gamesys/SaveGame.cpp +2f6856143057bf29dcfe38d61b59c863 *src/game/gamesys/SaveGame.h +79e6954325ea82fe62f074e9f9c63740 *src/game/gamesys/SysCmds.cpp +4b62f19c063511dee00c83845ce7f320 *src/game/gamesys/SysCmds.h +45f3407d7c6f51842a57572752d292e5 *src/game/gamesys/SysCvar.cpp +186e41dfe1782ff12375753cb74891db *src/game/gamesys/SysCvar.h +bff6543d6ab3ebbb7d72aecde1802847 *src/game/gamesys/TypeInfo.cpp +9e29ac4220a128524accb58d587470c2 *src/game/gamesys/TypeInfo.h +2773d46ff684e1a598b09942b6cdc476 *src/game/Game_local.cpp +30c65a29b9b4b9e7d45d063716409682 *src/game/Game_local.h +f3f4c7b38f4b934c8b18a1de5ce358ed *src/game/Game_network.cpp +24c6f213c515acae0b2ea944ed4f43f7 *src/game/IK.cpp +df74f5d7c6a346ee41a131864ac33a06 *src/game/IK.h +9a81c3987f89aabad2f17e0b93892203 *src/game/Item.cpp +689d41c13b7503e080d47d1baddf712e *src/game/Item.h +8a425a8d6bb15709fbac61a7fb80c9a7 *src/game/Light.cpp +eccb2ba974b76556f6a4c4ca6eb1dacc *src/game/Light.h +6c83df0e4877006a635a305a59326c32 *src/game/Misc.cpp +a122884d5775ac3043ccd74311ebe5c3 *src/game/Misc.h +a6eda57244d8940f2c07c126f1238b16 *src/game/Moveable.cpp +99be3c44f5831a8d2df4d8c44f81b073 *src/game/Moveable.h +99969c6e999a344d8324bd3a4e19543e *src/game/Mover.cpp +61de1ed47c3c9766db4f0c7741e10e32 *src/game/Mover.h +6a9f69048a0ba6f268c523307b6ee461 *src/game/MultiplayerGame.cpp +cf392661199d7da9fed1bdc7d0247270 *src/game/MultiplayerGame.h +066c3864cf4b5d179e2f9ed4727d89cf *src/game/physics/Clip.cpp +577044d81536fd081d936705bad6e669 *src/game/physics/Clip.h +db95fc8774df9f0971ffa47db89cd709 *src/game/physics/Force.cpp +9271f887b94b4dd70e8e31582c3cc765 *src/game/physics/Force.h +8891ce4f1b093c485c4838c65d35fa45 *src/game/physics/Force_Constant.cpp +fd9feebfee3a799541f006879eb569c3 *src/game/physics/Force_Constant.h +56187680952cacefb0fb8b689612ec2f *src/game/physics/Force_Drag.cpp +0fb5bef472d8710b8b0c4961ac424309 *src/game/physics/Force_Drag.h +b3805a50b055009e514413935d48eaae *src/game/physics/Force_Field.cpp +39024be5e301ab2949250a90a12e3f1e *src/game/physics/Force_Field.h +4868787409b28a30fc337721bf52b2d5 *src/game/physics/Force_Spring.cpp +a3079b4e01fa293555d62767e9a75eb5 *src/game/physics/Force_Spring.h +d60b09eced926973a02624fe72c097ad *src/game/physics/Physics.cpp +d2e28cc845e5640d8465214a84c2219c *src/game/physics/Physics.h +03635081f0b4f12746d939b8ae94fc4c *src/game/physics/Physics_Actor.cpp +056e1e0d7f36cac413c78094c63c50e8 *src/game/physics/Physics_Actor.h +b45998cdb202ebcc3425a0e2f516cf88 *src/game/physics/Physics_AF.cpp +cb3e0bcb7e1788cfdbdba12d66f9ed00 *src/game/physics/Physics_AF.h +61579ebbcf21ec719e7258d0d1e906c7 *src/game/physics/Physics_Base.cpp +e439ac91101079a93ba687470bbdb713 *src/game/physics/Physics_Base.h +ef50cc527673f51394cf8bf9e823eec6 *src/game/physics/Physics_Monster.cpp +c07dc14cdc28823871ced4cfb834cfc8 *src/game/physics/Physics_Monster.h +280e64fa2d3ee444e26f32305bc3d898 *src/game/physics/Physics_Parametric.cpp +f93bdcc492f50db67878e2274044d7ab *src/game/physics/Physics_Parametric.h +226d608f2cb7d279bad12e84a2558735 *src/game/physics/Physics_Player.cpp +572fe5e12fae49bcd35f264edb765890 *src/game/physics/Physics_Player.h +206f12b48f11aba0d189ba5316171765 *src/game/physics/Physics_RigidBody.cpp +8e3baa7b3e82350a908a3865f6c3a0d3 *src/game/physics/Physics_RigidBody.h +cd1687b82e2361c803bd528e94d393a7 *src/game/physics/Physics_Static.cpp +ca2ae3f0cc147acd3743a97e4184b43d *src/game/physics/Physics_Static.h +e2d822925adc488b22682937303b47f8 *src/game/physics/Physics_StaticMulti.cpp +f6ca48445ad2a16ae42ebd067a3dfc5b *src/game/physics/Physics_StaticMulti.h +39d50cc9f5bb1ceb1beca9c6aab64f68 *src/game/physics/Push.cpp +b1f7b4d666e0d79646aec2c1ada2be19 *src/game/physics/Push.h +b157ed4d796ff929e89567c535ad4617 *src/game/Player.cpp +7150bb6badbb3185ded2a63bcd1b2bf3 *src/game/Player.h +fc20717648bbb6ef95f2f4801c1dde00 *src/game/PlayerIcon.cpp +95261c80073066193a603fe646eadced *src/game/PlayerIcon.h +847baf8091ff7bf97908c7367264eb44 *src/game/PlayerView.cpp +db3455c0347cb7bdde4d0339d82f6e1e *src/game/PlayerView.h +e549f11d19ab7c3bfd094ef92a1ab8a3 *src/game/Projectile.cpp +4ec6a4dfc328ecdba3a8f649bbaa7b37 *src/game/Projectile.h +0140739513277028fc53e0e5257b0b97 *src/game/Pvs.cpp +9cffa1c0f5461bd11ccedf27adea899d *src/game/Pvs.h +729a5e05412a6dd575d6060791ddb182 *src/game/script/Script_Compiler.cpp +91da92aed14ed2748b2016b8bfd13a5b *src/game/script/Script_Compiler.h +9b60efb81c99a2e1c4025a25791c28ba *src/game/script/Script_Interpreter.cpp +edd8ba8f11fce2ad962132e5f5ab8223 *src/game/script/Script_Interpreter.h +c218b13187e3eaea5b9b959b4613b047 *src/game/script/Script_Program.cpp +2ff453147489c2b24c1036a321cd8a96 *src/game/script/Script_Program.h +e38cb728413beaf77ab5182398ce274a *src/game/script/Script_Thread.cpp +f64a3e1ea2328fa48cdf5dec04618921 *src/game/script/Script_Thread.h +f829cf1a432bb36437a916d7c8597569 *src/game/SecurityCamera.cpp +8ef631e222158b65ee9a4f5c04bff6df *src/game/SecurityCamera.h +4fa55ba5aa7f92e531b34847f6bee559 *src/game/SmokeParticles.cpp +e964690303add471140f387201c63de0 *src/game/SmokeParticles.h +7abad18d9f8f26669f7f4bc444a2489c *src/game/Sound.cpp +482b351917af91e26b3c52645674104f *src/game/Sound.h +58a53d103ef2f98209d422ecf7df19c3 *src/game/Target.cpp +1c999e2ff6d4bb5c5c409291756e7de5 *src/game/Target.h +7e420d0016eb039561be34a596debd63 *src/game/Trigger.cpp +ea3c3be1c40a32c47e65926082e1566f *src/game/Trigger.h +a8fa6c7f4ef2bec18a4d230d9405aef1 *src/game/Weapon.cpp +4d3ff18f0783184550e4817331da1e8f *src/game/Weapon.h +adba1c884614cd0905abf3cca7ff1fa8 *src/game/WorldSpawn.cpp +ae46f21bfaa3e91ee35f3368971800d1 *src/game/WorldSpawn.h +90cfea89fa17a724b826286d5ffeb269 *src/game-d3xp.vcproj +10bad911c3bdb3eb256a33c8be69265d *src/idlib/Base64.cpp +ea126c0e8ba724d2ac66d4a0d3e2ba04 *src/idlib/Base64.h +8c1312e06abb830cfc2a7f03295eee58 *src/idlib/BitMsg.cpp +28741399100324ca61a779f729f3cd4c *src/idlib/BitMsg.h +d45b2d3d570c176c36b9253925b79230 *src/idlib/bv/Bounds.cpp +14650ac3e9ff1bfb03ba75347819fabd *src/idlib/bv/Bounds.h +5ea635b6c4970372aac953212120efc0 *src/idlib/bv/Box.cpp +cf905028e165369e492bf7d01191a3b2 *src/idlib/bv/Box.h +91404c2190517b252213405d3b5c62a5 *src/idlib/bv/Frustum.cpp +82cd915d980c9283e03c525ac91f9e51 *src/idlib/bv/Frustum.h +0fadc6ec2c20147440bf9f0dc9a4cf43 *src/idlib/bv/Frustum_gcc.cpp +b487fc5a52b3d86eb21428dfd8d9a0e8 *src/idlib/bv/Sphere.cpp +2a1a1452e99fe8c49ee037653b76d216 *src/idlib/bv/Sphere.h +1ea5e9b68ae9d473684bba9af4134b4c *src/idlib/CmdArgs.cpp +bbe225a0932cd8b2f199e6a13e6f479b *src/idlib/CmdArgs.h +5038ebb317e1ae41975aac357d8f302a *src/idlib/containers/BinSearch.h +e1fe7702c576eacb7ae4d2a1bc4af716 *src/idlib/containers/BTree.h +01fd029e4c30f154149cc7a5d10ab851 *src/idlib/containers/HashIndex.cpp +0a55bc9e7c3f19de4c4fd1ee1ece1d6c *src/idlib/containers/HashIndex.h +3ba85097ca7a7a75bef9246a2c649718 *src/idlib/containers/HashTable.h +9f549a7317147b32de8c6938ccf67382 *src/idlib/containers/Hierarchy.h +d2a76dfa43e0648c6c63e521a020bb1e *src/idlib/containers/LinkList.h +3c7564a196935ce1cd79ecb29d448f78 *src/idlib/containers/List.h +6993b764a8b1897dfa095fddedd5dbcc *src/idlib/containers/PlaneSet.h +75f30a0d41cc375f49529f1d4cc90c98 *src/idlib/containers/Queue.h +d39a20aa40b0dee467cd271695923200 *src/idlib/containers/Stack.h +d1d7eca1471555d04d4cb30bef70efbe *src/idlib/containers/StaticList.h +8320894e1a591da60e33602753a1f6fd *src/idlib/containers/StrList.h +14cf4411222c6b09a57ad2e5f6cff3e9 *src/idlib/containers/StrPool.h +a156cd71b2e13828d3d1c6d57570b560 *src/idlib/containers/VectorSet.h +14e6daffa0dd203c281d6e2e6e28307a *src/idlib/Dict.cpp +830f9f2b849215c50794b1e52fe443ab *src/idlib/Dict.h +435819dbcc371bf493ba174162a5cb70 *src/idlib/geometry/DrawVert.cpp +b38ae02207bd99c10c504b5249038c7f *src/idlib/geometry/DrawVert.h +814b29df7f0b5510c467042147f056ea *src/idlib/geometry/JointTransform.cpp +2f5924396160ca6794284dbf0074f007 *src/idlib/geometry/JointTransform.h +5875071c1d9fbf459b0fce95699f705e *src/idlib/geometry/Surface.cpp +3d17b9dc3f2a4c839707ccd0dd505bb6 *src/idlib/geometry/Surface.h +df29ec04b3dd278b835df308786e3052 *src/idlib/geometry/Surface_Patch.cpp +92f08bde7754e5bf04917770b8e0bfe7 *src/idlib/geometry/Surface_Patch.h +cadb910c628a3d4d2425b7216470caa5 *src/idlib/geometry/Surface_Polytope.cpp +fc05791ee6de10600ade4b89a2f7b449 *src/idlib/geometry/Surface_Polytope.h +33325797daff12c12146c93912b43787 *src/idlib/geometry/Surface_SweptSpline.cpp +1524b424da99265d71fa4fe44686d503 *src/idlib/geometry/Surface_SweptSpline.h +8431f682e2a377f7f53e5b9c91786da2 *src/idlib/geometry/TraceModel.cpp +08703ab16c3b26b6dcfbfca5d1f51b59 *src/idlib/geometry/TraceModel.h +e5b52176825082a2c9ea10d7ff9753fe *src/idlib/geometry/Winding.cpp +0e2a2008c99298143f52fed1b6127ceb *src/idlib/geometry/Winding.h +4fd1728745517f10cc970ea0edf3ff72 *src/idlib/geometry/Winding2D.cpp +178f31145e34802391b4af8748fcd21e *src/idlib/geometry/Winding2D.h +43afbaa7210721fa099797ccc2d5c218 *src/idlib/hashing/CRC16.cpp +7fba1646c49bd659758b73406d8549de *src/idlib/hashing/CRC16.h +954899e570a7e1098193dcb3ab32a3aa *src/idlib/hashing/CRC32.cpp +c7d0fb6d29c05419f1034eb980b23039 *src/idlib/hashing/CRC32.h +478a4ed0b8f8c3b8d7ad1f2a4037eac0 *src/idlib/hashing/CRC8.cpp +2e813c1d19c91be6e6b3c3a8a6cdc301 *src/idlib/hashing/CRC8.h +3c6b2ce7c807344cd92caf1d441bca7d *src/idlib/hashing/Honeyman.cpp +c664b62e17653aebbcd04c8701ddd08b *src/idlib/hashing/Honeyman.h +1b907599c03e01614983dea58963757a *src/idlib/hashing/MD4.cpp +d4a497cfc27d4507e53688f19fe8dce0 *src/idlib/hashing/MD4.h +339902d1dbcf1d97208178dc8c98a62e *src/idlib/hashing/MD5.cpp +0a3259f4f2875b733ffbe2708a02dda9 *src/idlib/hashing/MD5.h +5c76357cecac2b6bb7b9764cebfa3035 *src/idlib/Heap.cpp +a20bcd3df1e302a304a152b9e119d0ef *src/idlib/Heap.h +f53750e28c24b851d39b1b2a0a237ac3 *src/idlib/LangDict.cpp +911a3ab827d9a623decbd775ca856c5b *src/idlib/LangDict.h +7ee7ba6a875ed3d3df6dc1ff39e862a5 *src/idlib/Lexer.cpp +295eeb502e21a763627c1bb4f043f8c0 *src/idlib/Lexer.h +bd52dbb10edb077da6fa2621cc853932 *src/idlib/Lib.cpp +f93f32b08697c5f42ba65afcf0a1df21 *src/idlib/Lib.h +17ec37be4bdf61e32d396da844a33325 *src/idlib/MapFile.cpp +77b6b04e39488ea740506c6b359b77c9 *src/idlib/MapFile.h +6847fc795e9b6b842093bc297a694a8f *src/idlib/math/Angles.cpp +5dc4f1e41f7524873cdeadab3f82642b *src/idlib/math/Angles.h +e4f7edaaf05258d9c26007ad7ec5ea24 *src/idlib/math/Complex.cpp +4aafaade6e774171966cc70b7114a8ff *src/idlib/math/Complex.h +42ec8dc549d5552ec15aa378fbb78c69 *src/idlib/math/Curve.h +55e81c917119e99977ed2a9ca019253c *src/idlib/math/Extrapolate.h +a4d0e1c970873a63364f03fb1f4f4b9d *src/idlib/math/Interpolate.h +2364df4b95a02db32a411fd69e63b12a *src/idlib/math/Lcp.cpp +e0bf54026a72d40b686f71525683cb8f *src/idlib/math/Lcp.h +bf2523f0eaa0e1490d43cdb46f44cdd0 *src/idlib/math/Math.cpp +9e8f517806334634081bbc339a26698a *src/idlib/math/Math.h +d9d97ae48dc142a1299ab3d3cde3c353 *src/idlib/math/Matrix.cpp +744fc4a9bf2aeafd18a98c6526b2796f *src/idlib/math/Matrix.h +9e64458de095626b5c552c4fdceb726c *src/idlib/math/Ode.cpp +b2f42b71ebd1b0cb5bd730ca1a23d9dc *src/idlib/math/Ode.h +d3140e8a5fe85ffa1ce556589e23b846 *src/idlib/math/Plane.cpp +e6d9b1b3d596b28ed4098b04389ead00 *src/idlib/math/Plane.h +264260647bb911a1071efbee810d50e8 *src/idlib/math/Pluecker.cpp +e0ce6b004f0005c82abe5cebf38cfe59 *src/idlib/math/Pluecker.h +297af895642ee92c40816decb36e0c4a *src/idlib/math/Polynomial.cpp +e6afdb0c48fcbef5f93165b3af87d303 *src/idlib/math/Polynomial.h +86148234cc2169eb3f5fed753e994539 *src/idlib/math/Quat.cpp +7df4388b58ea67d328ff6107d45f9dbc *src/idlib/math/Quat.h +3a9710abf5882642c09dbddd29a7a08d *src/idlib/math/Random.h +38481abd5916b83422f0f995ae9e1884 *src/idlib/math/Rotation.cpp +cf5b0e0fd91f8499196aee1e616e84a3 *src/idlib/math/Rotation.h +4cd838f1753ec78aae88b71ec05a1896 *src/idlib/math/Simd.cpp +145aed28ff0e099a7982bb659eeebaa2 *src/idlib/math/Simd.h +ba0c6eccbe8bf996a83998eb5d70430d *src/idlib/math/Simd_3DNow.cpp +2d53fb2f5286cec5da2099e0fd1cf290 *src/idlib/math/Simd_3DNow.h +7693decc0682458eb0ad562159d265a8 *src/idlib/math/Simd_AltiVec.cpp +691ec3dede9fa399a434ccd6a7e601de *src/idlib/math/Simd_AltiVec.h +43b93652a8047c9c7bda1f7ba53c12ed *src/idlib/math/Simd_Generic.cpp +d09fb3a0cd76bc807f41398ba1bbc358 *src/idlib/math/Simd_Generic.h +da36ccd911f492f78d8cf6eed7c4ceca *src/idlib/math/Simd_MMX.cpp +f9f3725cbfd4b0eb8b8d0a265c45365d *src/idlib/math/Simd_MMX.h +77d051b2b11c28bfc5e5124d96aaf420 *src/idlib/math/Simd_SSE.cpp +4e6dd9174c46af7a813dac3e308f3de0 *src/idlib/math/Simd_SSE.h +22e7dc426cd3aa25372429a7bd9df059 *src/idlib/math/Simd_SSE2.cpp +fbc4426daca37ebf86f05904f4a5b0bf *src/idlib/math/Simd_SSE2.h +c71ed081a78055ac59244a1df9a7af18 *src/idlib/math/Simd_SSE3.cpp +d93730fba4e34089fbe34e588292cdd4 *src/idlib/math/Simd_SSE3.h +a1483875a16c31f3a50bee0f75dcda33 *src/idlib/math/Vector.cpp +25f68a30acb1e60730b6ff997b897d59 *src/idlib/math/Vector.h +9be71b8af547b601581dda3172c80685 *src/idlib/Parser.cpp +d2e5eb0951c1fd13133cc49d26422c12 *src/idlib/Parser.h +eb50f2476038fafd4ccb7502016381a8 *src/idlib/precompiled.h +7992150d35d20b5451782072c3b08ed6 *src/idlib/Str.cpp +c3729e4773c7ed4df6948321931f96d5 *src/idlib/Str.h +c007a652e5d6f139529853822515cc51 *src/idlib/Timer.cpp +1994f53aee883f68af020e52f1303ded *src/idlib/Timer.h +ac6fb8eafd4616e29a7faeafa032e725 *src/idlib/Token.cpp +20c9b0e0146f5fec26d03bd7948631c0 *src/idlib/Token.h +2e55872065220bf8b65232549f34d261 *src/idlib.vcproj +7a2c051ad61f2f8ddd930130f9c94740 *src/MayaImport/exporter.h +e0e640e984a2398a83122affafd942f5 *src/MayaImport/Maya4.5/maya.h +0c4fa28f8c45eb5c4968cfa07451a640 *src/MayaImport/maya5.0/maya.h +e0e640e984a2398a83122affafd942f5 *src/MayaImport/Maya6.0/maya.h +e95a40bbb2cd5989e74be304b8dfca49 *src/MayaImport/mayaimport.def +d2680e896cc5c2465d25b7b1212855f4 *src/MayaImport/maya_main.cpp +3b1d1d3c06b41cabdf1db20d0c70e799 *src/MayaImport/maya_main.h +e2b87ed822c749ea8fa16283f49fbec3 *src/MayaImport.vcproj +73b268519d1fe463f1cbdc0f629db078 *src/renderer/Cinematic.h +89b029c9dbfb6034c5f333040e986fd2 *src/renderer/glext.h +7dcb19d26a6e770df53bc006777e6476 *src/renderer/Material.h +944070b49e293970d7a0cca123f6d2d9 *src/renderer/Model.h +3ecddb8eabde6caa0c29a0252034da84 *src/renderer/ModelManager.h +df3b6a65299ffcb94b2112fd09454a9d *src/renderer/qgl.h +d7cef91f74111c3f718fbb013f0e89fb *src/renderer/qgl_linked.h +8120ce8cecf1f5c14c9d8fdc51ef76fc *src/renderer/RenderSystem.h +f2dbceca220c1b8aca832dce917b6516 *src/renderer/RenderWorld.h +d53f08c1cd4e79c2d393134c68057d2e *src/SConstruct +58657928eab2a7c4cd3e212f1893433d *src/sound/sound.h +99de5ead06f5526a2bc2e223be36f506 *src/sys/linux/qgl_enforce.h +c097031304dd401e701002d427f79d06 *src/sys/scons/SConscript.game +d41d4564fcaa6da50cdb36482937b827 *src/sys/scons/SConscript.idlib +017d27f219517537234a27a8fe1219f4 *src/sys/scons/scons_utils.py +1956037ab2473b370884ea0639a9e9e0 *src/sys/sys_public.h +125d82621ba140bcbd51b25bc03bf03f *src/tools/compilers/aas/AASFile.h +98b1ef423b759cad4d9fffbc10d4598e *src/tools/compilers/aas/AASFileManager.h +473dc012029bdd1fb49382c43d1904c3 *src/ui/ListGUI.h +7292e8c7c3115150261a9a6f288f2d7c *src/ui/UserInterface.h +80d7d7d37c3dd53790cbf78f31196bc5 *vehicles/af/env_vehicle_simplebuggy.af +9f2394d96b77cc9de7a2e3d7260fb033 *vehicles/def/env_simplevehicle.def +0a02ac09bc92c6e3bf4a97da8e0054ab *vehicles/maps/testmaps/test_vehicle.cm +74fa3ab82f81978e313cb77f07b15efb *vehicles/maps/testmaps/test_vehicle.map +81cb35140c0e38fd7dd86d2235f9eb31 *vehicles/maps/testmaps/test_vehicle.proc +999593e1b407797ddbf0181620670e9a *vehicles/maps/testmaps/test_vehicle.script +c0623dcaea4fbf6ce890a35767be746e *vehicles/maps/testmaps/test_vehicle2.cm +f582d207eabe141349c1c71883bc83e5 *vehicles/maps/testmaps/test_vehicle2.map +281645579d053c47f2f71b9f8661cc44 *vehicles/maps/testmaps/test_vehicle2.proc +341252364d5807e531ba8fc4832983b2 *vehicles/maps/testmaps/test_vehicle2.script +1e39fc8c73c855553ee9f312764f55ca *vehicles/maps/testmaps/test_vehicle_terrain.ase +2375734e8a1eb60f279c780c026cae38 *vehicles/models/md5/vehicles/buggy/buggy.mb +be9227250a5ce53ec365f73526654a93 *vehicles/models/md5/vehicles/buggy/buggy.md5anim +5289507aaf5cc7900d77bd380ae9e0ee *vehicles/models/md5/vehicles/buggy/buggy.md5mesh +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/buggy.tga +39f3a6981658a72625bb8983a962d66f *vehicles/models/md5/vehicles/buggy/buggy_d.tga +147db9b809602de2da99ff5c6b5cb36d *vehicles/models/md5/vehicles/buggy/buggy_local.tga +a97253ee8fff39d798edc7d0536cf9c9 *vehicles/models/md5/vehicles/buggy/buggy_turret_d.tga +966384b9f9373c69781287b5d6079bed *vehicles/models/md5/vehicles/buggy/buggy_turret_local.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/gun.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/turret.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/wheel.tga +6a16211eb7cbbc8a7079a57c4abdf652 *vehicles/models/md5/vehicles/buggy/wheel_d.tga +5e0aac8bfb2ad55cc3b12913c7d8b574 *vehicles/models/md5/vehicles/buggy/wheel_local.tga +e505dce717d443bd61a5b67d7cb12f71 *vehicles/models/md5/vehicles/buggy/wheel_s.tga +07b354a5cb974a8b7ab1f100fe2e264d *vehicles/models/md5/vehicles/locust/initial.md5anim +9e35209909d5299d24007496bff459ca *vehicles/models/md5/vehicles/locust/locust.md5mesh +73bc1d9ae5652b3bf6a1f1b8850ccf42 *vehicles/readme.txt +d329162eec1c3032b09093873cd239ca *vehicles/textures/base_floor/concrete01.tga +be239f082c721c4618a6ea66ee18eaa0 *vehicles/textures/base_floor/concrete01d.tga +640bc8e08c0446019ed832e1c4bf172e *vehicles/textures/base_floor/concrete01s copy.tga +640bc8e08c0446019ed832e1c4bf172e *vehicles/textures/base_floor/concrete01s.tga +b84284d1b85ca5ee877de786531bad54 *vehicles/textures/stone/sand01.tga +508ca81cd2ee9242e41a0b5e8a41cdc7 *vehicles/textures/stone/sand01_d.tga +f666c13e5a5c669c7fed43e00f3a6e94 *vehicles/textures/stone/sand01_s.tga +814bcec5c20cc2658a75fe8f62547692 *vehicles/textures/stone/sand02.tga diff --git a/sys/linux/SDK.list.txt b/sys/linux/SDK.list.txt new file mode 100644 index 000000000..a4a0dad70 --- /dev/null +++ b/sys/linux/SDK.list.txt @@ -0,0 +1,416 @@ +D3 1.1 win32 SDK file list + +378c21cf872ef830445ce18b3d3348f8 *base/animation/mp_greenarmor.md5mesh +7f9b7629c712056e48ceac9dadb16224 *base/animation/mp_jumpsuit.md5mesh +caf59e47ec1988d81fdcc3c8aeb8981f *base/animation/mp_labcoat.md5mesh +3982a493fe0da57c13e96fc8e1d6a795 *base/animation/mp_security.md5mesh +c23ac9aeb96d3ef55595c7d668d948cd *base/animation/mp_soldier.md5mesh +24046a3a459bf42fd1ea555d0b75fdfc *base/animation/mp_suit.md5mesh +6509fbcd1ce02e81bf0f95954405bea4 *base/animation/mp_tshirt.md5mesh +683d3f4c114f803873775a559a43a7c1 *base/def/npcs_as_player.def +20729461e1831236acae7ca5b73b0319 *base/maps/fred/cyberdemon/monster_wakeups.mb +2d7df07f33ffbacaf16c51942524b55c *base/maps/fred/underground/impintro.mb +fce124d3f5d717eee4a7d89ad02eca7a *base/maps/fred/underground/impscurry.mb +b60db9fae92e89f9b5cc25cd0a4253f6 *base/maps/fred/underground/impstairs.mb +185553b6f3ab20b1994f07798cd0a156 *base/models/monsters/imp/animation/cycles/alert_walk.ma +b20bf698a63d5eb0a876f1d41b47aaae *base/models/monsters/imp/animation/cycles/crouched_range1.ma +34c73f22a4a1eeee9bb4eae68688917b *base/models/monsters/imp/animation/cycles/evade_left.ma +76ff5398bcf1aebb08641bc5dfacd716 *base/models/monsters/imp/animation/cycles/evade_left_on4.ma +81203ea3773a820074b2fbc2c2e17e37 *base/models/monsters/imp/animation/cycles/evade_right.ma +a05cba4afb38f709eede99fc8b7fdf83 *base/models/monsters/imp/animation/cycles/evade_right_on4.ma +9ce3fb5c02f00f004c13da995ac8e51f *base/models/monsters/imp/animation/cycles/faster_walk.ma +3d960bbfb56e51ca9735905d49d83c3a *base/models/monsters/imp/animation/cycles/fireball_sight.ma +0779e202728e8b80a48d950bbf74c4e0 *base/models/monsters/imp/animation/cycles/hangonceiling.ma +7fcfc63044c8111485813efe6af5b066 *base/models/monsters/imp/animation/cycles/idle1.ma +110661e6211291d098bace0a26f1a483 *base/models/monsters/imp/animation/cycles/imp.mb +cd0971e695d81001820e9222313a4955 *base/models/monsters/imp/animation/cycles/initial.ma +6ec1b1abe0c585726636149f54f8e9dc *base/models/monsters/imp/animation/cycles/jump_loop.ma +6be7606a2cb7135eed7b583145d0f572 *base/models/monsters/imp/animation/cycles/jump_loop2.ma +e8ae6eb85a5bfe7a9190dbf3279d4ea1 *base/models/monsters/imp/animation/cycles/jump_loop3.ma +6412062ceb0cd3256cc78e49c2e4909a *base/models/monsters/imp/animation/cycles/offwall.ma +ab814d600992f29204655e3415971e3e *base/models/monsters/imp/animation/cycles/on4_idle.ma +b54f250dd00b0b9b24c31c6b14871629 *base/models/monsters/imp/animation/cycles/on4_melee1.ma +64dd04c941a7a7f174583d34d035eebc *base/models/monsters/imp/animation/cycles/on4_melee2.ma +ec39d4020b208de213f56c095c0406d3 *base/models/monsters/imp/animation/cycles/on4_sight.ma +b9133fba76754d0691e31c788d33dcd7 *base/models/monsters/imp/animation/cycles/outofhole.ma +75f00d3a2077f0b9378424fd64cadc1d *base/models/monsters/imp/animation/cycles/pain3.ma +c0cf15bd8e7b331118f3f2a253c8d1a6 *base/models/monsters/imp/animation/cycles/pain_chest.ma +4f3b231d9c0dd5bc144f91aaefa95f9d *base/models/monsters/imp/animation/cycles/pain_chest_on4.ma +a3fda68e30e70c7de009f008832cc849 *base/models/monsters/imp/animation/cycles/pain_head.ma +ebab78e4555f5ce417e7a918b857a299 *base/models/monsters/imp/animation/cycles/pain_head_on4.ma +6a2da31bf0ab40750d93f4f334432271 *base/models/monsters/imp/animation/cycles/pain_luparm.ma +4277b9a5f30f28106f0fd4fadd008d03 *base/models/monsters/imp/animation/cycles/pain_luparm_on4.ma +506a7b9b631f70afcab174b4df6672d2 *base/models/monsters/imp/animation/cycles/pain_ruparm.ma +d72684a507481948165939c762a94d14 *base/models/monsters/imp/animation/cycles/pain_ruparm_on4.ma +2d5f4a7997cfbffd9a9f3aaa93b8cb96 *base/models/monsters/imp/animation/cycles/range1.ma +4a18cb9d675f4fdb20f31bc34d0f126c *base/models/monsters/imp/animation/cycles/range2.ma +e56ceccbeb0b39929e69792e6ca493cd *base/models/monsters/imp/animation/cycles/range3.ma +93d4ee499d9d183e44db78cb49d76128 *base/models/monsters/imp/animation/cycles/run.ma +7d8b78d2414c775e0718857ade6d607c *base/models/monsters/imp/animation/cycles/scurry2.ma +51b92152e848f5df97d37ba1e5ea4937 *base/models/monsters/imp/animation/cycles/scurry_leap2.ma +ef071d4959c55540bf28ec90408537bb *base/models/monsters/imp/animation/cycles/sight.ma +44b4b5bebf62d8a7b5173593dfc2ad9d *base/models/monsters/imp/animation/cycles/sight2.ma +e0eeef3455d1dabcc924c328b24ec236 *base/models/monsters/imp/animation/cycles/slash1.ma +2490f2dab58229e1d37bfe27201c94ac *base/models/monsters/imp/animation/cycles/slash2.ma +7c59693fba6b19053042c65cc8424491 *base/models/monsters/imp/animation/cycles/slash3.ma +db049810b1429fcf53ac482fe1b0fd4c *base/models/monsters/imp/animation/cycles/teleportin.ma +f82822c0fe0b8ddb287af934259d98e9 *base/models/monsters/imp/animation/cycles/turret_attack1.ma +b8828a357c293183b3a6bcec9a8d594e *base/models/monsters/imp/animation/cycles/turret_idle.ma +75b85d1dd46885051553df964e0e8dad *base/models/monsters/imp/fred/imp_setup.mb +fc2e0afe9f6e596709c8635035105697 *base/models/monsters/imp/fred/imp_setup_ik.mb +2645732cd30bfd33309e4b801e74971c *base/models/weapons/machinegun/cycles/empty.ma +162eee06b15fffaabbc267f72f66ad7c *base/models/weapons/machinegun/cycles/fire1.ma +799523e4fb25e9f97e2bc197f1c783b9 *base/models/weapons/machinegun/cycles/fire2.ma +2f8536ac728bb97e163b7fcc3669ba44 *base/models/weapons/machinegun/cycles/fire4.ma +8ccb8b80b363da587015fcce7167f526 *base/models/weapons/machinegun/cycles/idle1.ma +2553b66bdb33e6bd85a1d7bccd936237 *base/models/weapons/machinegun/cycles/pullup1.ma +c703ec87330cdc52d4bad4dd2aac7de7 *base/models/weapons/machinegun/cycles/putaway.ma +4e9a4ba4caa2e209c66761ffe9f6cd8c *base/models/weapons/machinegun/cycles/reload1.ma +6b19b0dbd4bb6554b9b449713d4fd102 *base/models/weapons/machinegun/fred/setup1.mb +326a538229b875b8a9f5506c2bffe4f6 *EULA.Development Kit.rtf +9380e8d182dbf689d65399c090d536b1 *MayaImportx86_Maya45.zip +ff7e2e1bffcb4283f7333d43e722f02e *MayaImportx86_Maya60.zip +bf55402b75174f2f5a9f4edfea7726ee *src/cm/CollisionModel.h +b7107e4f8766d32ec0585a42446a574d *src/D3Game.sln +6a7b0e721547e7eea469def7bb1020bd *src/D3Game.vcproj +39efa6ceb0d4a2e49a294abc70e0b16f *src/framework/async/NetworkSystem.h +3dc9117caac77a292cd70aa873a7207a *src/framework/BuildDefines.h +81d91c2104799156ebe83ec8986e7d20 *src/framework/BuildVersion.h +453240a77802d1ab9cf4ab09ba740639 *src/framework/CmdSystem.h +677c025b011385281e25dc993b4a8499 *src/framework/Common.h +deb4de6d9309529bc6a7bd56b2fcaf55 *src/framework/CVarSystem.h +52f04ff903d39b681286a1fe2a7ee1c9 *src/framework/DeclAF.h +4f180083323a00d3883dc96883794f2f *src/framework/DeclEntityDef.h +8808ba9d72dd869fa1bed98a75a66404 *src/framework/DeclFX.h +814651a1587484b9fece7208c51e2d49 *src/framework/DeclManager.h +a6e5cede15b3b172a4aea25033a1ce8a *src/framework/DeclParticle.h +3adfa181f3e77f9d403de8a0a18d0c95 *src/framework/DeclPDA.h +75b9fde04b70378da3bebcfd767b14aa *src/framework/DeclSkin.h +3d69c1de8791eb5c1c48a4ce16386506 *src/framework/DeclTable.h +11ab17b676bda521cd354dc86dfd3f5b *src/framework/File.h +e92aa99dba6f14290bc0a52e804d396e *src/framework/FileSystem.h +7ade28527ea08cc07a948e432f3ec4ba *src/framework/Licensee.h +2e1a7e1beeb04f0544fce5dae5a60fe3 *src/framework/Licensee.h~ +b7fe4b168ae34a31d5ca772e8c10f236 *src/framework/UsercmdGen.h +56b975ec4265f4d5f729585dc1201df4 *src/game/Actor.cpp +87accdd5fdf457551d5853680fafb141 *src/game/Actor.h +7d66b9397301033f63b2dfa6537c89c5 *src/game/AF.cpp +ec286d2cf851db847021795908d27c12 *src/game/AF.h +3ab86ad5934be48831b5fdc590a1e0ca *src/game/AFEntity.cpp +7bf66006050beda99b11c8040251b129 *src/game/AFEntity.h +f03ba687f94f1ffb13ac814486de2340 *src/game/ai/AAS.cpp +3ee992286f1b1641cdcfc6d443b99d14 *src/game/ai/AAS.h +8035de9626e57d12c848b77546feccb3 *src/game/ai/AAS_debug.cpp +6c2876fc8190a0d3f3789b1577c45ec1 *src/game/ai/AAS_local.h +b1823e1aad4d2261f9d5d9bc06d5a95f *src/game/ai/AAS_pathing.cpp +62fe990c48174e83fdaeeaf63f58d07a *src/game/ai/AAS_routing.cpp +a84f13a41a98b77c76ae23dc2e0c2ee5 *src/game/ai/AI.cpp +a669a1843a7bbf4407d3c70d062dc408 *src/game/ai/AI.h +0f77e62adfea8c29069bca726478ed7d *src/game/ai/AI_events.cpp +675d4dbfab5c332c53313d9d9e7ec4d4 *src/game/ai/AI_pathing.cpp +a730df35afccadc7382d140ee28b3aea *src/game/ai/AI_Vagary.cpp +b8bc423a3369d61df9b9b7bc22a7ebd9 *src/game/anim/Anim.cpp +b86f393f092421ca83abb354c5b72e91 *src/game/anim/Anim.h +d0bf02c14cfd12eda16b69d75fcda19c *src/game/anim/Anim_Blend.cpp +40697f546da5b79869176fae43ae032d *src/game/anim/Anim_Import.cpp +c2c6a164bce3816f6e75ff8261048be0 *src/game/anim/Anim_Testmodel.cpp +9e09b5e8640ec36f86761e77dcd855c9 *src/game/anim/Anim_Testmodel.h +de34c777c4deff12775dd684d16febf3 *src/game/BrittleFracture.cpp +a011977466a557e80be87b1556e3c417 *src/game/BrittleFracture.h +f6e5d2601ac1335f82692b61ff1a1db1 *src/game/Camera.cpp +302973226944e14dc3a26fed1912d5cf *src/game/Camera.h +d58c6b6f1de81aef4b25abe9b96ed5f9 *src/game/EndLevel.cpp +a44b0e64ba6b4430dbc76363503c8256 *src/game/EndLevel.h +346b38062a46e974415b57e1c498d4a9 *src/game/Entity.cpp +b1d0ce6a101bc2eeaa1e94da673c7933 *src/game/Entity.h +502b575f49ac63603fe1edd6fd89745d *src/game/Fx.cpp +a7973abe1874af163b24d9725e60ed0a *src/game/Fx.h +9366293139f568d4f2ed28d9447e7c5e *src/game/Game.def +972d2ce92401cfc4b65cfc357d3472ea *src/game/Game.h +05b14ef43c96a51b4e1fce10cbfb8d2a *src/game/GameEdit.cpp +1d9a0d89c3e2d05fb26c60d68c3e17ad *src/game/GameEdit.h +42cf780f56a4f2c040aac9e81d70b4bb *src/game/gamesys/Callbacks.cpp +d39a837dd7712bd2ea64735a168508cc *src/game/gamesys/Class.cpp +e3d5465ac9a9ca711f2ea834e10b5fa6 *src/game/gamesys/Class.h +279bde28025a669dbf47ee435dab52a8 *src/game/gamesys/DebugGraph.cpp +9281bfa4a0c7d44992a5b69acbed0a74 *src/game/gamesys/DebugGraph.h +363e6574b6a9ff9ace329daaa7404190 *src/game/gamesys/Event.cpp +ce26aec947d6735d37cacb7e98219ab9 *src/game/gamesys/Event.h +1f292a9218d3292c11323d078bc6b0d6 *src/game/gamesys/GameTypeInfo.h +969aae4b4f3c5a51c342226c5f6b6d66 *src/game/gamesys/NoGameTypeInfo.h +7ad6879f350cdbb92a0910ea1a9a7fd1 *src/game/gamesys/SaveGame.cpp +d7bf2021a698a9c6f4504d17f1a79b0a *src/game/gamesys/SaveGame.h +23ccafd508ee1ae008f79d52c0316513 *src/game/gamesys/SysCmds.cpp +4b62f19c063511dee00c83845ce7f320 *src/game/gamesys/SysCmds.h +5412d6d994d3715ddff6a5e82768695d *src/game/gamesys/SysCvar.cpp +c377c1379e4877e7f8edc5debd4b75e0 *src/game/gamesys/SysCvar.h +96a3281440a7ebd0e44ab72c1e8b9009 *src/game/gamesys/TypeInfo.cpp +9e29ac4220a128524accb58d587470c2 *src/game/gamesys/TypeInfo.h +139f571bdd739efbf46212b787d25232 *src/game/Game_local.cpp +f1600c53c7569c056edda6c4620ccd45 *src/game/Game_local.h +c348767fb44983462b051cad65756fb2 *src/game/Game_network.cpp +8737f8f651bcab2b4bc202a5f50d667e *src/game/IK.cpp +df74f5d7c6a346ee41a131864ac33a06 *src/game/IK.h +9a81c3987f89aabad2f17e0b93892203 *src/game/Item.cpp +689d41c13b7503e080d47d1baddf712e *src/game/Item.h +a3a2b1fe87a8b8804939a472ec8a3e84 *src/game/Light.cpp +eccb2ba974b76556f6a4c4ca6eb1dacc *src/game/Light.h +b8bf206f0c303223042e7328b7f156c2 *src/game/Misc.cpp +45255b27221275d1acf8bc2bca2011cc *src/game/Misc.h +a6eda57244d8940f2c07c126f1238b16 *src/game/Moveable.cpp +99be3c44f5831a8d2df4d8c44f81b073 *src/game/Moveable.h +673b9d6354db859ff8841e51b4d90a74 *src/game/Mover.cpp +7bc54954ca08fba3932a519444017612 *src/game/Mover.h +09b7961342bebf27a825acc7c2ced71c *src/game/MultiplayerGame.cpp +df68626bb9306f9bba0dae46011250f6 *src/game/MultiplayerGame.h +7262d1b194228fa6b186cfc29cffdef8 *src/game/physics/Clip.cpp +577044d81536fd081d936705bad6e669 *src/game/physics/Clip.h +db95fc8774df9f0971ffa47db89cd709 *src/game/physics/Force.cpp +9271f887b94b4dd70e8e31582c3cc765 *src/game/physics/Force.h +8891ce4f1b093c485c4838c65d35fa45 *src/game/physics/Force_Constant.cpp +fd9feebfee3a799541f006879eb569c3 *src/game/physics/Force_Constant.h +56187680952cacefb0fb8b689612ec2f *src/game/physics/Force_Drag.cpp +0fb5bef472d8710b8b0c4961ac424309 *src/game/physics/Force_Drag.h +b3805a50b055009e514413935d48eaae *src/game/physics/Force_Field.cpp +39024be5e301ab2949250a90a12e3f1e *src/game/physics/Force_Field.h +4868787409b28a30fc337721bf52b2d5 *src/game/physics/Force_Spring.cpp +a3079b4e01fa293555d62767e9a75eb5 *src/game/physics/Force_Spring.h +d60b09eced926973a02624fe72c097ad *src/game/physics/Physics.cpp +d2e28cc845e5640d8465214a84c2219c *src/game/physics/Physics.h +03635081f0b4f12746d939b8ae94fc4c *src/game/physics/Physics_Actor.cpp +056e1e0d7f36cac413c78094c63c50e8 *src/game/physics/Physics_Actor.h +548912303ec919606fd571409e0d6b3f *src/game/physics/Physics_AF.cpp +cb3e0bcb7e1788cfdbdba12d66f9ed00 *src/game/physics/Physics_AF.h +61579ebbcf21ec719e7258d0d1e906c7 *src/game/physics/Physics_Base.cpp +e439ac91101079a93ba687470bbdb713 *src/game/physics/Physics_Base.h +ef50cc527673f51394cf8bf9e823eec6 *src/game/physics/Physics_Monster.cpp +c07dc14cdc28823871ced4cfb834cfc8 *src/game/physics/Physics_Monster.h +280e64fa2d3ee444e26f32305bc3d898 *src/game/physics/Physics_Parametric.cpp +f93bdcc492f50db67878e2274044d7ab *src/game/physics/Physics_Parametric.h +c06e587495eed3157e38eafb9585dcfc *src/game/physics/Physics_Player.cpp +572fe5e12fae49bcd35f264edb765890 *src/game/physics/Physics_Player.h +2553326601252426098bdae4296fdabb *src/game/physics/Physics_RigidBody.cpp +5ca7efd2006e2de31ada159f7ba8f7be *src/game/physics/Physics_RigidBody.h +cd1687b82e2361c803bd528e94d393a7 *src/game/physics/Physics_Static.cpp +ca2ae3f0cc147acd3743a97e4184b43d *src/game/physics/Physics_Static.h +e2d822925adc488b22682937303b47f8 *src/game/physics/Physics_StaticMulti.cpp +f6ca48445ad2a16ae42ebd067a3dfc5b *src/game/physics/Physics_StaticMulti.h +39d50cc9f5bb1ceb1beca9c6aab64f68 *src/game/physics/Push.cpp +b1f7b4d666e0d79646aec2c1ada2be19 *src/game/physics/Push.h +010c0c56ca82a1ff81b3b12d5312ffe0 *src/game/Player.cpp +7150bb6badbb3185ded2a63bcd1b2bf3 *src/game/Player.h +490d26cd1169a6e76fef196ae6fa2158 *src/game/PlayerIcon.cpp +95261c80073066193a603fe646eadced *src/game/PlayerIcon.h +1540ddffd03de461ff7a39dfe3c7e0e2 *src/game/PlayerView.cpp +db3455c0347cb7bdde4d0339d82f6e1e *src/game/PlayerView.h +800c3289a5da63eb7ecca9bf99c6ff12 *src/game/Projectile.cpp +8afb029a42a7c4939c004885d84380e4 *src/game/Projectile.h +0140739513277028fc53e0e5257b0b97 *src/game/Pvs.cpp +9cffa1c0f5461bd11ccedf27adea899d *src/game/Pvs.h +f7a48566c9644a3d7863a843ef38e18e *src/game/script/Script_Compiler.cpp +3e61acbaddfd43c61deb72109befc0fb *src/game/script/Script_Compiler.h +9b60efb81c99a2e1c4025a25791c28ba *src/game/script/Script_Interpreter.cpp +2a444b3863bfd1f1d505883250b5188e *src/game/script/Script_Interpreter.h +c218b13187e3eaea5b9b959b4613b047 *src/game/script/Script_Program.cpp +ac855d2669cdff1c615a631aecd27f64 *src/game/script/Script_Program.h +e38cb728413beaf77ab5182398ce274a *src/game/script/Script_Thread.cpp +8aca84be8cdedc909443c84f1c0a208c *src/game/script/Script_Thread.h +a10d18197069f6b27c2d494dd946b9b7 *src/game/SecurityCamera.cpp +8ef631e222158b65ee9a4f5c04bff6df *src/game/SecurityCamera.h +4fa55ba5aa7f92e531b34847f6bee559 *src/game/SmokeParticles.cpp +e964690303add471140f387201c63de0 *src/game/SmokeParticles.h +7abad18d9f8f26669f7f4bc444a2489c *src/game/Sound.cpp +482b351917af91e26b3c52645674104f *src/game/Sound.h +58a53d103ef2f98209d422ecf7df19c3 *src/game/Target.cpp +1c999e2ff6d4bb5c5c409291756e7de5 *src/game/Target.h +7e420d0016eb039561be34a596debd63 *src/game/Trigger.cpp +ea3c3be1c40a32c47e65926082e1566f *src/game/Trigger.h +bb00d8a4533a9cc990983021a1049778 *src/game/Weapon.cpp +79b221f36e61e42a72ab340587f93ca6 *src/game/Weapon.h +adba1c884614cd0905abf3cca7ff1fa8 *src/game/WorldSpawn.cpp +ae46f21bfaa3e91ee35f3368971800d1 *src/game/WorldSpawn.h +10bad911c3bdb3eb256a33c8be69265d *src/idlib/Base64.cpp +ea126c0e8ba724d2ac66d4a0d3e2ba04 *src/idlib/Base64.h +8c1312e06abb830cfc2a7f03295eee58 *src/idlib/BitMsg.cpp +28741399100324ca61a779f729f3cd4c *src/idlib/BitMsg.h +d45b2d3d570c176c36b9253925b79230 *src/idlib/bv/Bounds.cpp +14650ac3e9ff1bfb03ba75347819fabd *src/idlib/bv/Bounds.h +5ea635b6c4970372aac953212120efc0 *src/idlib/bv/Box.cpp +cf905028e165369e492bf7d01191a3b2 *src/idlib/bv/Box.h +0fadc6ec2c20147440bf9f0dc9a4cf43 *src/idlib/bv/Frustum-linux.cpp +d7ffd33ea20af13a549ff1e4030aa441 *src/idlib/bv/Frustum.cpp +82cd915d980c9283e03c525ac91f9e51 *src/idlib/bv/Frustum.h +b487fc5a52b3d86eb21428dfd8d9a0e8 *src/idlib/bv/Sphere.cpp +2a1a1452e99fe8c49ee037653b76d216 *src/idlib/bv/Sphere.h +7d2f35652eb37e02da564128b8739a1b *src/idlib/CmdArgs.cpp +de04ca1dd8b19e0aebc74aeefd93c789 *src/idlib/CmdArgs.h +5038ebb317e1ae41975aac357d8f302a *src/idlib/containers/BinSearch.h +e1fe7702c576eacb7ae4d2a1bc4af716 *src/idlib/containers/BTree.h +01fd029e4c30f154149cc7a5d10ab851 *src/idlib/containers/HashIndex.cpp +0a55bc9e7c3f19de4c4fd1ee1ece1d6c *src/idlib/containers/HashIndex.h +3ba85097ca7a7a75bef9246a2c649718 *src/idlib/containers/HashTable.h +9f549a7317147b32de8c6938ccf67382 *src/idlib/containers/Hierarchy.h +d2a76dfa43e0648c6c63e521a020bb1e *src/idlib/containers/LinkList.h +3c7564a196935ce1cd79ecb29d448f78 *src/idlib/containers/List.h +6993b764a8b1897dfa095fddedd5dbcc *src/idlib/containers/PlaneSet.h +75f30a0d41cc375f49529f1d4cc90c98 *src/idlib/containers/Queue.h +d39a20aa40b0dee467cd271695923200 *src/idlib/containers/Stack.h +d1d7eca1471555d04d4cb30bef70efbe *src/idlib/containers/StaticList.h +8320894e1a591da60e33602753a1f6fd *src/idlib/containers/StrList.h +14cf4411222c6b09a57ad2e5f6cff3e9 *src/idlib/containers/StrPool.h +a156cd71b2e13828d3d1c6d57570b560 *src/idlib/containers/VectorSet.h +6fcacc47c0f1a424bbd2d1fbd79683f9 *src/idlib/Dict.cpp +830f9f2b849215c50794b1e52fe443ab *src/idlib/Dict.h +435819dbcc371bf493ba174162a5cb70 *src/idlib/geometry/DrawVert.cpp +d764c88408677ce409672df1a1c1d36a *src/idlib/geometry/DrawVert.h +814b29df7f0b5510c467042147f056ea *src/idlib/geometry/JointTransform.cpp +2f5924396160ca6794284dbf0074f007 *src/idlib/geometry/JointTransform.h +5875071c1d9fbf459b0fce95699f705e *src/idlib/geometry/Surface.cpp +3d17b9dc3f2a4c839707ccd0dd505bb6 *src/idlib/geometry/Surface.h +df29ec04b3dd278b835df308786e3052 *src/idlib/geometry/Surface_Patch.cpp +92f08bde7754e5bf04917770b8e0bfe7 *src/idlib/geometry/Surface_Patch.h +cadb910c628a3d4d2425b7216470caa5 *src/idlib/geometry/Surface_Polytope.cpp +fc05791ee6de10600ade4b89a2f7b449 *src/idlib/geometry/Surface_Polytope.h +33325797daff12c12146c93912b43787 *src/idlib/geometry/Surface_SweptSpline.cpp +1524b424da99265d71fa4fe44686d503 *src/idlib/geometry/Surface_SweptSpline.h +33f8f19e2c89d7287dac2d0639f67516 *src/idlib/geometry/TraceModel.cpp +08703ab16c3b26b6dcfbfca5d1f51b59 *src/idlib/geometry/TraceModel.h +e5b52176825082a2c9ea10d7ff9753fe *src/idlib/geometry/Winding.cpp +0e2a2008c99298143f52fed1b6127ceb *src/idlib/geometry/Winding.h +4fd1728745517f10cc970ea0edf3ff72 *src/idlib/geometry/Winding2D.cpp +178f31145e34802391b4af8748fcd21e *src/idlib/geometry/Winding2D.h +43afbaa7210721fa099797ccc2d5c218 *src/idlib/hashing/CRC16.cpp +7fba1646c49bd659758b73406d8549de *src/idlib/hashing/CRC16.h +954899e570a7e1098193dcb3ab32a3aa *src/idlib/hashing/CRC32.cpp +c7d0fb6d29c05419f1034eb980b23039 *src/idlib/hashing/CRC32.h +478a4ed0b8f8c3b8d7ad1f2a4037eac0 *src/idlib/hashing/CRC8.cpp +2e813c1d19c91be6e6b3c3a8a6cdc301 *src/idlib/hashing/CRC8.h +3c6b2ce7c807344cd92caf1d441bca7d *src/idlib/hashing/Honeyman.cpp +c664b62e17653aebbcd04c8701ddd08b *src/idlib/hashing/Honeyman.h +1b907599c03e01614983dea58963757a *src/idlib/hashing/MD4.cpp +d4a497cfc27d4507e53688f19fe8dce0 *src/idlib/hashing/MD4.h +339902d1dbcf1d97208178dc8c98a62e *src/idlib/hashing/MD5.cpp +0a3259f4f2875b733ffbe2708a02dda9 *src/idlib/hashing/MD5.h +5c76357cecac2b6bb7b9764cebfa3035 *src/idlib/Heap.cpp +a20bcd3df1e302a304a152b9e119d0ef *src/idlib/Heap.h +9f5f712967a20458d52234fb69104435 *src/idlib/LangDict.cpp +57ff18a40f19fbd475ddec81d5b85e0d *src/idlib/LangDict.h +7ddde694748f232429a4e745f69fc5d2 *src/idlib/Lexer.cpp +fa31f2bf2d78bc0a9025fc917e3ed902 *src/idlib/Lexer.h +fb368b07f9711d1df46e7f7fcf15516d *src/idlib/Lib.cpp +16c1bcf4da0bacaef54d6038956f28b9 *src/idlib/Lib.h +17ec37be4bdf61e32d396da844a33325 *src/idlib/MapFile.cpp +77b6b04e39488ea740506c6b359b77c9 *src/idlib/MapFile.h +6847fc795e9b6b842093bc297a694a8f *src/idlib/math/Angles.cpp +5dc4f1e41f7524873cdeadab3f82642b *src/idlib/math/Angles.h +e4f7edaaf05258d9c26007ad7ec5ea24 *src/idlib/math/Complex.cpp +4aafaade6e774171966cc70b7114a8ff *src/idlib/math/Complex.h +42ec8dc549d5552ec15aa378fbb78c69 *src/idlib/math/Curve.h +55e81c917119e99977ed2a9ca019253c *src/idlib/math/Extrapolate.h +a4d0e1c970873a63364f03fb1f4f4b9d *src/idlib/math/Interpolate.h +2364df4b95a02db32a411fd69e63b12a *src/idlib/math/Lcp.cpp +e0bf54026a72d40b686f71525683cb8f *src/idlib/math/Lcp.h +bf2523f0eaa0e1490d43cdb46f44cdd0 *src/idlib/math/Math.cpp +574b0cf28c3d13218fe24167deff99f0 *src/idlib/math/Math.h +d9d97ae48dc142a1299ab3d3cde3c353 *src/idlib/math/Matrix.cpp +744fc4a9bf2aeafd18a98c6526b2796f *src/idlib/math/Matrix.h +9e64458de095626b5c552c4fdceb726c *src/idlib/math/Ode.cpp +b2f42b71ebd1b0cb5bd730ca1a23d9dc *src/idlib/math/Ode.h +d3140e8a5fe85ffa1ce556589e23b846 *src/idlib/math/Plane.cpp +e6d9b1b3d596b28ed4098b04389ead00 *src/idlib/math/Plane.h +264260647bb911a1071efbee810d50e8 *src/idlib/math/Pluecker.cpp +e0ce6b004f0005c82abe5cebf38cfe59 *src/idlib/math/Pluecker.h +297af895642ee92c40816decb36e0c4a *src/idlib/math/Polynomial.cpp +03bc11f2e3d70ec7d4cd83f731c2e1dd *src/idlib/math/Polynomial.h +86148234cc2169eb3f5fed753e994539 *src/idlib/math/Quat.cpp +7df4388b58ea67d328ff6107d45f9dbc *src/idlib/math/Quat.h +3a9710abf5882642c09dbddd29a7a08d *src/idlib/math/Random.h +38481abd5916b83422f0f995ae9e1884 *src/idlib/math/Rotation.cpp +cf5b0e0fd91f8499196aee1e616e84a3 *src/idlib/math/Rotation.h +de5a618cade4cbff94362e12495d5a34 *src/idlib/math/Simd.cpp +145aed28ff0e099a7982bb659eeebaa2 *src/idlib/math/Simd.h +ba0c6eccbe8bf996a83998eb5d70430d *src/idlib/math/Simd_3DNow.cpp +2d53fb2f5286cec5da2099e0fd1cf290 *src/idlib/math/Simd_3DNow.h +b15bab713795d586b16516348309c097 *src/idlib/math/Simd_AltiVec.cpp +2717c4ae65116371440f140d4f1fc5b1 *src/idlib/math/Simd_AltiVec.h +43b93652a8047c9c7bda1f7ba53c12ed *src/idlib/math/Simd_Generic.cpp +d09fb3a0cd76bc807f41398ba1bbc358 *src/idlib/math/Simd_Generic.h +da36ccd911f492f78d8cf6eed7c4ceca *src/idlib/math/Simd_MMX.cpp +f9f3725cbfd4b0eb8b8d0a265c45365d *src/idlib/math/Simd_MMX.h +77d051b2b11c28bfc5e5124d96aaf420 *src/idlib/math/Simd_SSE.cpp +4e6dd9174c46af7a813dac3e308f3de0 *src/idlib/math/Simd_SSE.h +22e7dc426cd3aa25372429a7bd9df059 *src/idlib/math/Simd_SSE2.cpp +fbc4426daca37ebf86f05904f4a5b0bf *src/idlib/math/Simd_SSE2.h +c71ed081a78055ac59244a1df9a7af18 *src/idlib/math/Simd_SSE3.cpp +d93730fba4e34089fbe34e588292cdd4 *src/idlib/math/Simd_SSE3.h +a1483875a16c31f3a50bee0f75dcda33 *src/idlib/math/Vector.cpp +25f68a30acb1e60730b6ff997b897d59 *src/idlib/math/Vector.h +9be71b8af547b601581dda3172c80685 *src/idlib/Parser.cpp +0386adb078ff1c52c07f4b3ccf8e6a3f *src/idlib/Parser.h +7bc75e24b08006a28710dce9762f1e17 *src/idlib/precompiled.h +e272339ca140e674992d2e831c51abb8 *src/idlib/Str.cpp +4309c740635191d0593407dac24655da *src/idlib/Str.h +c007a652e5d6f139529853822515cc51 *src/idlib/Timer.cpp +bcdf86d0dc26dabd83ac3d5bac5c5a5e *src/idlib/Timer.h +ac6fb8eafd4616e29a7faeafa032e725 *src/idlib/Token.cpp +20c9b0e0146f5fec26d03bd7948631c0 *src/idlib/Token.h +be7fa36da9d1f7f14dd995c0b5b10142 *src/idlib.vcproj +3b1d1d3c06b41cabdf1db20d0c70e799 *src/MayaImport/maya_main.h +e2b87ed822c749ea8fa16283f49fbec3 *src/MayaImport.vcproj +73b268519d1fe463f1cbdc0f629db078 *src/renderer/Cinematic.h +89b029c9dbfb6034c5f333040e986fd2 *src/renderer/glext.h +ee942ae4158802dc2e0321813989451f *src/renderer/Material.h +331d2c34c56160603cc9e62c6c5615e3 *src/renderer/Model.h +69e03fb16f187b96760ae60f6dcb25d5 *src/renderer/ModelManager.h +23c1e21454370196b454df0df265e38a *src/renderer/qgl.h +d7cef91f74111c3f718fbb013f0e89fb *src/renderer/qgl_linked.h +1d39d13fd337296384f235f3d3a57832 *src/renderer/RenderSystem.h +8001ab373ca72f0ccdfee104ce65b669 *src/renderer/RenderWorld.h +1c12d01e216c70fd59c38c82123102bc *src/SConstruct +05ff30469c4d330d65d01947aeb49266 *src/sound/sound.h +99de5ead06f5526a2bc2e223be36f506 *src/sys/linux/qgl_enforce.h +f82d3ff93a079bea354f11a1ab4451b7 *src/sys/scons/SConscript.game +14e8eeee647a88f0e8572b6354484249 *src/sys/scons/SConscript.idlib +62cc545dde9c8990fadcb46d0ef13d4b *src/sys/scons/scons_utils.py +bca08bc9a651ee2a4865e2aa89bc8e36 *src/sys/sys_public.h +125d82621ba140bcbd51b25bc03bf03f *src/tools/compilers/aas/AASFile.h +98b1ef423b759cad4d9fffbc10d4598e *src/tools/compilers/aas/AASFileManager.h +473dc012029bdd1fb49382c43d1904c3 *src/ui/ListGUI.h +613d12903b3a0f979d52f697145715c4 *src/ui/UserInterface.h +80d7d7d37c3dd53790cbf78f31196bc5 *vehicles/af/env_vehicle_simplebuggy.af +9f2394d96b77cc9de7a2e3d7260fb033 *vehicles/def/env_simplevehicle.def +05a8defa084e8e2cffb4e26749575133 *vehicles/game00.pk4 +0a02ac09bc92c6e3bf4a97da8e0054ab *vehicles/maps/testmaps/test_vehicle.cm +74fa3ab82f81978e313cb77f07b15efb *vehicles/maps/testmaps/test_vehicle.map +81cb35140c0e38fd7dd86d2235f9eb31 *vehicles/maps/testmaps/test_vehicle.proc +999593e1b407797ddbf0181620670e9a *vehicles/maps/testmaps/test_vehicle.script +c0623dcaea4fbf6ce890a35767be746e *vehicles/maps/testmaps/test_vehicle2.cm +f582d207eabe141349c1c71883bc83e5 *vehicles/maps/testmaps/test_vehicle2.map +281645579d053c47f2f71b9f8661cc44 *vehicles/maps/testmaps/test_vehicle2.proc +341252364d5807e531ba8fc4832983b2 *vehicles/maps/testmaps/test_vehicle2.script +1e39fc8c73c855553ee9f312764f55ca *vehicles/maps/testmaps/test_vehicle_terrain.ase +2375734e8a1eb60f279c780c026cae38 *vehicles/models/md5/vehicles/buggy/buggy.mb +be9227250a5ce53ec365f73526654a93 *vehicles/models/md5/vehicles/buggy/buggy.md5anim +5289507aaf5cc7900d77bd380ae9e0ee *vehicles/models/md5/vehicles/buggy/buggy.md5mesh +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/buggy.tga +39f3a6981658a72625bb8983a962d66f *vehicles/models/md5/vehicles/buggy/buggy_d.tga +147db9b809602de2da99ff5c6b5cb36d *vehicles/models/md5/vehicles/buggy/buggy_local.tga +a97253ee8fff39d798edc7d0536cf9c9 *vehicles/models/md5/vehicles/buggy/buggy_turret_d.tga +966384b9f9373c69781287b5d6079bed *vehicles/models/md5/vehicles/buggy/buggy_turret_local.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/gun.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/turret.tga +180b91d17b3c9341d9dedff4bb34411b *vehicles/models/md5/vehicles/buggy/wheel.tga +6a16211eb7cbbc8a7079a57c4abdf652 *vehicles/models/md5/vehicles/buggy/wheel_d.tga +5e0aac8bfb2ad55cc3b12913c7d8b574 *vehicles/models/md5/vehicles/buggy/wheel_local.tga +e505dce717d443bd61a5b67d7cb12f71 *vehicles/models/md5/vehicles/buggy/wheel_s.tga +07b354a5cb974a8b7ab1f100fe2e264d *vehicles/models/md5/vehicles/locust/initial.md5anim +9e35209909d5299d24007496bff459ca *vehicles/models/md5/vehicles/locust/locust.md5mesh +73bc1d9ae5652b3bf6a1f1b8850ccf42 *vehicles/readme.txt +d329162eec1c3032b09093873cd239ca *vehicles/textures/base_floor/concrete01.tga +be239f082c721c4618a6ea66ee18eaa0 *vehicles/textures/base_floor/concrete01d.tga +640bc8e08c0446019ed832e1c4bf172e *vehicles/textures/base_floor/concrete01s copy.tga +640bc8e08c0446019ed832e1c4bf172e *vehicles/textures/base_floor/concrete01s.tga +b84284d1b85ca5ee877de786531bad54 *vehicles/textures/stone/sand01.tga +508ca81cd2ee9242e41a0b5e8a41cdc7 *vehicles/textures/stone/sand01_d.tga +f666c13e5a5c669c7fed43e00f3a6e94 *vehicles/textures/stone/sand01_s.tga +814bcec5c20cc2658a75fe8f62547692 *vehicles/textures/stone/sand02.tga diff --git a/sys/linux/casedir.patch b/sys/linux/casedir.patch new file mode 100644 index 000000000..abb5eda67 --- /dev/null +++ b/sys/linux/casedir.patch @@ -0,0 +1,213 @@ +Index: framework/FileSystem.cpp +=================================================================== +--- framework/FileSystem.cpp (revision 528) ++++ framework/FileSystem.cpp (working copy) +@@ -159,7 +159,7 @@ + }; + + // 3 search patch (fs_savepath fs_basepath fs_cdpath) +-// .jpg then .tga for ++// often .jpg and .tga patterns + #define MAX_CACHED_DIRS 6 + + class idDEntry : public idStrList { +@@ -173,6 +173,11 @@ + void Init(const char *directory, const char *extension, const idStrList &list ); + }; + ++typedef struct { ++ idStr path; ++ idStr OSpath; ++} casematch_t; ++ + class idFileSystem_local : public idFileSystem { + public: + idFileSystem_local( void ); +@@ -227,11 +232,14 @@ + int numServerPaks; + int serverPaks[MAX_SEARCH_PATHS]; + +- idDEntry dir_cache[MAX_CACHED_DIRS]; // fifo ++ idDEntry dir_cache[MAX_CACHED_DIRS]; // fifo + int dir_cache_index; + int dir_cache_count; ++ ++ idList dir_case; // match directories in a case insensitive way + + private: ++ const char * CaseSearch(const char *in_dir); + void ReplaceSeparators( idStr &path, char sep = PATHSEPERATOR_CHAR ); + long HashFileName( const char *fname ) const; + bool FilenameCompare( const char *s1, const char *s2 ); +@@ -1118,6 +1126,89 @@ + + /* + =============== ++idFileSystem_local::CaseSearch ++=============== ++*/ ++const char* idFileSystem_local::CaseSearch(const char *in_dir) { ++ const char *ret; ++ int i, j; ++ // FIXME: go faster with a hash? ++ for( i=0; i=0; i-- ) { ++ Com_Printf("chunk: %s\n", dirs[i].c_str() ); ++ bMatched = false; ++ for( j=0 ; j +Index: sys/sys_public.h +=================================================================== +--- sys/sys_public.h (revision 528) ++++ sys/sys_public.h (working copy) +@@ -137,6 +137,7 @@ + + // use fs_debug to verbose Sys_ListFiles + // returns -1 if directory was not found (the list is cleared) ++// if there is a / passed as extension, return directories + int Sys_ListFiles( const char *directory, const char *extension, idStrList &list); + + // For the mac, we need to explicitly flush vertex buffer areas before using them diff --git a/sys/linux/dedicated.cpp b/sys/linux/dedicated.cpp new file mode 100644 index 000000000..46b4ec366 --- /dev/null +++ b/sys/linux/dedicated.cpp @@ -0,0 +1,83 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../../renderer/tr_local.h" +#include "../posix/posix_public.h" +#include "local.h" + +/* +========== +input +========== +*/ + +void Sys_InitInput( void ) { } + +void Sys_ShutdownInput( void ) { } + +void Sys_GrabMouseCursor( bool ) { } + +int Sys_PollMouseInputEvents( void ) { return 0; } + +void Sys_EndMouseInputEvents( void ) { } + +int Sys_ReturnMouseInputEvent( const int n, int &action, int &value ) { return 0; } + +int Sys_PollKeyboardInputEvents( void ) { return 0; } + +void Sys_EndKeyboardInputEvents( void ) { } + +int Sys_ReturnKeyboardInputEvent( const int n, int &action, bool &state ) { return 0; } + +unsigned char Sys_MapCharForKey( int key ) { return (unsigned char)key; } + +/* +================ +Sys_GetVideoRam +returns in megabytes +================ +*/ +int Sys_GetVideoRam( void ) { + return 64; +} + +/* +========== +GL +========== +*/ + +void GLimp_EnableLogging( bool enable ) { } + +bool GLimp_Init( glimpParms_t a ) { return true; } + +void GLimp_SetGamma( unsigned short red[256], + unsigned short green[256], + unsigned short blue[256] ) { } + +void GLimp_Shutdown( void ) { } + +void GLimp_SwapBuffers( void ) { } + +void GLimp_DeactivateContext( void ) { } + +void GLimp_ActivateContext( void ) { } + +bool GLimp_SetScreenParms( glimpParms_t parms ) { return true; } + diff --git a/sys/linux/glimp.cpp b/sys/linux/glimp.cpp new file mode 100644 index 000000000..5ab6735ae --- /dev/null +++ b/sys/linux/glimp.cpp @@ -0,0 +1,659 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../../renderer/tr_local.h" +#include "local.h" + +#include +#include +#include +#include + +extern "C" { +# include "libXNVCtrl/NVCtrlLib.h" +} + +idCVar sys_videoRam( "sys_videoRam", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "Texture memory on the video card (in megabytes) - 0: autodetect", 0, 512 ); + +Display *dpy = NULL; +static int scrnum = 0; + +Window win = 0; + +bool dga_found = false; + +static GLXContext ctx = NULL; + +static bool vidmode_ext = false; +static int vidmode_MajorVersion = 0, vidmode_MinorVersion = 0; // major and minor of XF86VidExtensions + +static XF86VidModeModeInfo **vidmodes; +static int num_vidmodes; +static bool vidmode_active = false; + +// backup gamma ramp +static int save_rampsize = 0; +static unsigned short *save_red, *save_green, *save_blue; + +void GLimp_WakeBackEnd(void *a) { + common->DPrintf("GLimp_WakeBackEnd stub\n"); +} + +#ifdef ID_GL_HARDLINK +void GLimp_EnableLogging(bool log) { + static bool logging; + if (log != logging) + { + common->DPrintf("GLimp_EnableLogging - disabled at compile time (ID_GL_HARDLINK)\n"); + logging = log; + } +} +#endif + +void GLimp_FrontEndSleep() { + common->DPrintf("GLimp_FrontEndSleep stub\n"); +} + +void *GLimp_BackEndSleep() { + common->DPrintf("GLimp_BackEndSleep stub\n"); + return 0; +} + +bool GLimp_SpawnRenderThread(void (*a) ()) { + common->DPrintf("GLimp_SpawnRenderThread stub\n"); + return false; +} + +void GLimp_ActivateContext() { + assert( dpy ); + assert( ctx ); + qglXMakeCurrent( dpy, win, ctx ); +} + +void GLimp_DeactivateContext() { + assert( dpy ); + qglXMakeCurrent( dpy, None, NULL ); +} + +/* +================= +GLimp_SaveGamma + +save and restore the original gamma of the system +================= +*/ +void GLimp_SaveGamma() { + if ( save_rampsize ) { + return; + } + + assert( dpy ); + + XF86VidModeGetGammaRampSize( dpy, scrnum, &save_rampsize); + save_red = (unsigned short *)malloc(save_rampsize*sizeof(unsigned short)); + save_green = (unsigned short *)malloc(save_rampsize*sizeof(unsigned short)); + save_blue = (unsigned short *)malloc(save_rampsize*sizeof(unsigned short)); + XF86VidModeGetGammaRamp( dpy, scrnum, save_rampsize, save_red, save_green, save_blue); +} + +/* +================= +GLimp_RestoreGamma + +save and restore the original gamma of the system +================= +*/ +void GLimp_RestoreGamma() { + if (!save_rampsize) + return; + + XF86VidModeSetGammaRamp( dpy, scrnum, save_rampsize, save_red, save_green, save_blue); + + free(save_red); free(save_green); free(save_blue); + save_rampsize = 0; +} + +/* +================= +GLimp_SetGamma + +gamma ramp is generated by the renderer from r_gamma and r_brightness for 256 elements +the size of the gamma ramp can not be changed on X (I need to confirm this) +================= +*/ +void GLimp_SetGamma(unsigned short red[256], unsigned short green[256], unsigned short blue[256]) { + if ( dpy ) { + int size; + + GLimp_SaveGamma(); + XF86VidModeGetGammaRampSize( dpy, scrnum, &size); + common->DPrintf("XF86VidModeGetGammaRampSize: %d\n", size); + if ( size > 256 ) { + // silly generic resample + int i; + unsigned short *l_red, *l_green, *l_blue; + l_red = (unsigned short *)malloc(size*sizeof(unsigned short)); + l_green = (unsigned short *)malloc(size*sizeof(unsigned short)); + l_blue = (unsigned short *)malloc(size*sizeof(unsigned short)); + //int r_size = 256; + int r_i; float r_f; + for(i=0; iPrintf( "Failed to detect DGA DirectVideo Mouse\n" ); + cvarSystem->SetCVarBool( "in_dgamouse", false ); + dga_found = false; + } else { + common->Printf( "DGA DirectVideo Mouse (Version %d.%d) initialized\n", + dga_MajorVersion, dga_MinorVersion ); + dga_found = true; + } +#else + dga_found = false; +#endif +} + +/* +** XErrorHandler +** the default X error handler exits the application +** I found out that on some hosts some operations would raise X errors (GLXUnsupportedPrivateRequest) +** but those don't seem to be fatal .. so the default would be to just ignore them +** our implementation mimics the default handler behaviour (not completely cause I'm lazy) +*/ +int idXErrorHandler(Display * l_dpy, XErrorEvent * ev) { + char buf[1024]; + common->Printf( "Fatal X Error:\n" ); + common->Printf( " Major opcode of failed request: %d\n", ev->request_code ); + common->Printf( " Minor opcode of failed request: %d\n", ev->minor_code ); + common->Printf( " Serial number of failed request: %lu\n", ev->serial ); + XGetErrorText( l_dpy, ev->error_code, buf, 1024 ); + common->Printf( "%s\n", buf ); + return 0; +} + +bool GLimp_OpenDisplay( void ) { + if ( dpy ) { + return true; + } + + if ( cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 1 ) { + common->DPrintf( "not opening the display: dedicated server\n" ); + return false; + } + + common->Printf( "Setup X display connection\n" ); + + // that should be the first call into X + if ( !XInitThreads() ) { + common->Printf("XInitThreads failed\n"); + return false; + } + + // set up our custom error handler for X failures + XSetErrorHandler( &idXErrorHandler ); + + if ( !( dpy = XOpenDisplay(NULL) ) ) { + common->Printf( "Couldn't open the X display\n" ); + return false; + } + scrnum = DefaultScreen( dpy ); + return true; +} + +/* +=============== +GLX_Init +=============== +*/ +int GLX_Init(glimpParms_t a) { + int attrib[] = { + GLX_RGBA, // 0 + GLX_RED_SIZE, 8, // 1, 2 + GLX_GREEN_SIZE, 8, // 3, 4 + GLX_BLUE_SIZE, 8, // 5, 6 + GLX_DOUBLEBUFFER, // 7 + GLX_DEPTH_SIZE, 24, // 8, 9 + GLX_STENCIL_SIZE, 8, // 10, 11 + GLX_ALPHA_SIZE, 8, // 12, 13 + None + }; + // these match in the array +#define ATTR_RED_IDX 2 +#define ATTR_GREEN_IDX 4 +#define ATTR_BLUE_IDX 6 +#define ATTR_DEPTH_IDX 9 +#define ATTR_STENCIL_IDX 11 +#define ATTR_ALPHA_IDX 13 + Window root; + XVisualInfo *visinfo; + XSetWindowAttributes attr; + XSizeHints sizehints; + unsigned long mask; + int colorbits, depthbits, stencilbits; + int tcolorbits, tdepthbits, tstencilbits; + int actualWidth, actualHeight; + int i; + const char *glstring; + + if ( !GLimp_OpenDisplay() ) { + return false; + } + + common->Printf( "Initializing OpenGL display\n" ); + + root = RootWindow( dpy, scrnum ); + + actualWidth = glConfig.vidWidth; + actualHeight = glConfig.vidHeight; + + // Get video mode list + if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { + vidmode_ext = false; + common->Printf("XFree86-VidModeExtension not available\n"); + } else { + vidmode_ext = true; + common->Printf("Using XFree86-VidModeExtension Version %d.%d\n", + vidmode_MajorVersion, vidmode_MinorVersion); + } + + GLX_TestDGA(); + + if ( vidmode_ext ) { + int best_fit, best_dist, dist, x, y; + + XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); + + // Are we going fullscreen? If so, let's change video mode + if ( a.fullScreen ) { + best_dist = 9999999; + best_fit = -1; + + for (i = 0; i < num_vidmodes; i++) { + if (a.width > vidmodes[i]->hdisplay || + a.height > vidmodes[i]->vdisplay) + continue; + + x = a.width - vidmodes[i]->hdisplay; + y = a.height - vidmodes[i]->vdisplay; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit != -1) { + actualWidth = vidmodes[best_fit]->hdisplay; + actualHeight = vidmodes[best_fit]->vdisplay; + + // change to the mode + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + vidmode_active = true; + + // Move the viewport to top left + // FIXME: center? + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + + common->Printf( "Free86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); + + } else { + a.fullScreen = false; + common->Printf( "Free86-VidModeExtension: No acceptable modes found\n" ); + } + } else { + common->Printf( "XFree86-VidModeExtension: not fullscreen, ignored\n" ); + } + } + // color, depth and stencil + colorbits = 24; + depthbits = 24; + stencilbits = 8; + + for (i = 0; i < 16; i++) { + // 0 - default + // 1 - minus colorbits + // 2 - minus depthbits + // 3 - minus stencil + if ((i % 4) == 0 && i) { + // one pass, reduce + switch (i / 4) { + case 2: + if (colorbits == 24) + colorbits = 16; + break; + case 1: + if (depthbits == 24) + depthbits = 16; + else if (depthbits == 16) + depthbits = 8; + case 3: + if (stencilbits == 24) + stencilbits = 16; + else if (stencilbits == 16) + stencilbits = 8; + } + } + + tcolorbits = colorbits; + tdepthbits = depthbits; + tstencilbits = stencilbits; + + if ((i % 4) == 3) { // reduce colorbits + if (tcolorbits == 24) + tcolorbits = 16; + } + + if ((i % 4) == 2) { // reduce depthbits + if (tdepthbits == 24) + tdepthbits = 16; + else if (tdepthbits == 16) + tdepthbits = 8; + } + + if ((i % 4) == 1) { // reduce stencilbits + if (tstencilbits == 24) + tstencilbits = 16; + else if (tstencilbits == 16) + tstencilbits = 8; + else + tstencilbits = 0; + } + + if (tcolorbits == 24) { + attrib[ATTR_RED_IDX] = 8; + attrib[ATTR_GREEN_IDX] = 8; + attrib[ATTR_BLUE_IDX] = 8; + } else { + // must be 16 bit + attrib[ATTR_RED_IDX] = 4; + attrib[ATTR_GREEN_IDX] = 4; + attrib[ATTR_BLUE_IDX] = 4; + } + + attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth + attrib[ATTR_STENCIL_IDX] = tstencilbits; + + visinfo = qglXChooseVisual(dpy, scrnum, attrib); + if (!visinfo) { + continue; + } + + common->Printf( "Using %d/%d/%d Color bits, %d Alpha bits, %d depth, %d stencil display.\n", + attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], + attrib[ATTR_BLUE_IDX], attrib[ATTR_ALPHA_IDX], + attrib[ATTR_DEPTH_IDX], + attrib[ATTR_STENCIL_IDX]); + + glConfig.colorBits = tcolorbits; + glConfig.depthBits = tdepthbits; + glConfig.stencilBits = tstencilbits; + break; + } + + if (!visinfo) { + common->Printf("Couldn't get a visual\n"); + return false; + } + // window attributes + attr.background_pixel = BlackPixel(dpy, scrnum); + attr.border_pixel = 0; + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); + attr.event_mask = X_MASK; + if (vidmode_active) { + mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | + CWEventMask | CWOverrideRedirect; + attr.override_redirect = True; + attr.backing_store = NotUseful; + attr.save_under = False; + } else { + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + } + + win = XCreateWindow(dpy, root, 0, 0, + actualWidth, actualHeight, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr); + + XStoreName(dpy, win, GAME_NAME); + + // don't let the window be resized + // FIXME: allow resize (win32 does) + sizehints.flags = PMinSize | PMaxSize; + sizehints.min_width = sizehints.max_width = actualWidth; + sizehints.min_height = sizehints.max_height = actualHeight; + + XSetWMNormalHints(dpy, win, &sizehints); + + XMapWindow( dpy, win ); + + if ( vidmode_active ) { + XMoveWindow( dpy, win, 0, 0 ); + } + + XFlush(dpy); + XSync(dpy, False); + ctx = qglXCreateContext(dpy, visinfo, NULL, True); + XSync(dpy, False); + + // Free the visinfo after we're done with it + XFree(visinfo); + + qglXMakeCurrent(dpy, win, ctx); + + glstring = (const char *) qglGetString(GL_RENDERER); + common->Printf("GL_RENDERER: %s\n", glstring); + + glstring = (const char *) qglGetString(GL_EXTENSIONS); + common->Printf("GL_EXTENSIONS: %s\n", glstring); + + // FIXME: here, software GL test + + glConfig.isFullscreen = a.fullScreen; + + if ( glConfig.isFullscreen ) { + Sys_GrabMouseCursor( true ); + } + + return true; +} + +/* +=================== +GLimp_Init + +This is the platform specific OpenGL initialization function. It +is responsible for loading OpenGL, initializing it, +creating a window of the appropriate size, doing +fullscreen manipulations, etc. Its overall responsibility is +to make sure that a functional OpenGL subsystem is operating +when it returns to the ref. + +If there is any failure, the renderer will revert back to safe +parameters and try again. +=================== +*/ +bool GLimp_Init( glimpParms_t a ) { + + if ( !GLimp_OpenDisplay() ) { + return false; + } + +#ifndef ID_GL_HARDLINK + if ( !GLimp_dlopen() ) { + return false; + } +#endif + + if (!GLX_Init(a)) { + return false; + } + + return true; +} + +/* +=================== +GLimp_SetScreenParms +=================== +*/ +bool GLimp_SetScreenParms( glimpParms_t parms ) { + return true; +} + +/* +================ +Sys_GetVideoRam +returns in megabytes +open your own display connection for the query and close it +using the one shared with GLimp_Init is not stable +================ +*/ +int Sys_GetVideoRam( void ) { + static int run_once = 0; + int major, minor, value; + Display *l_dpy; + int l_scrnum; + + if ( run_once ) { + return run_once; + } + + if ( sys_videoRam.GetInteger() ) { + run_once = sys_videoRam.GetInteger(); + return sys_videoRam.GetInteger(); + } + + // try a few strategies to guess the amount of video ram + common->Printf( "guessing video ram ( use +set sys_videoRam to force ) ..\n" ); + if ( !GLimp_OpenDisplay( ) ) { + run_once = 64; + return run_once; + } + l_dpy = dpy; + l_scrnum = scrnum; + // go for nvidia ext first + if ( XNVCTRLQueryVersion( l_dpy, &major, &minor ) ) { + common->Printf( "found XNVCtrl extension %d.%d\n", major, minor ); + if ( XNVCTRLIsNvScreen( l_dpy, l_scrnum ) ) { + if ( XNVCTRLQueryAttribute( l_dpy, l_scrnum, 0, NV_CTRL_VIDEO_RAM, &value ) ) { + run_once = value / 1024; + return run_once; + } else { + common->Printf( "XNVCtrlQueryAttribute NV_CTRL_VIDEO_RAM failed\n" ); + } + } else { + common->Printf( "default screen %d is not controlled by NVIDIA driver\n", l_scrnum ); + } + } + // try ATI /proc read ( for the lack of a better option ) + int fd; + if ( ( fd = open( "/proc/dri/0/umm", O_RDONLY ) ) != -1 ) { + int len; + char umm_buf[ 1024 ]; + char *line; + if ( ( len = read( fd, umm_buf, 1024 ) ) != -1 ) { + // should be way enough to get the full file + // grab "free LFB = " line and "free Inv = " lines + umm_buf[ len-1 ] = '\0'; + line = umm_buf; + line = strtok( umm_buf, "\n" ); + int total = 0; + while ( line ) { + if ( strlen( line ) >= 13 && strstr( line, "max LFB =" ) == line ) { + total += atoi( line + 12 ); + } else if ( strlen( line ) >= 13 && strstr( line, "max Inv =" ) == line ) { + total += atoi( line + 12 ); + } + line = strtok( NULL, "\n" ); + } + if ( total ) { + run_once = total / 1048576; + // round to the lower 16Mb + run_once &= ~15; + return run_once; + } + } else { + common->Printf( "read /proc/dri/0/umm failed: %s\n", strerror( errno ) ); + } + } + common->Printf( "guess failed, return default low-end VRAM setting ( 64MB VRAM )\n" ); + run_once = 64; + return run_once; +} diff --git a/sys/linux/glimp_dlopen.cpp.m4 b/sys/linux/glimp_dlopen.cpp.m4 new file mode 100644 index 000000000..a4ec74822 --- /dev/null +++ b/sys/linux/glimp_dlopen.cpp.m4 @@ -0,0 +1,135 @@ +#include "idlib/precompiled.h" +#include "renderer/tr_local.h" +#include "sys/linux/local.h" +#include "glimp_local.h" + +#include + +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl the gl wgl glX definitions +dnl ===================================================== +include(../gllog/gl_def.m4) + +dnl ===================================================== +dnl qgl function ptrs +dnl ===================================================== + +define(`instance_funcptr', ``$1' ( APIENTRY * qgl`$2' )(`$3');') +forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +dnl ===================================================== +dnl glX function ptrs +dnl ===================================================== + +define(`instance_funcptr', ``$1' ( * qglX`$2' )(`$3');') +forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +dnl ===================================================== +dnl dll ptrs +dnl those are the actual dlsym'ed pointers +dnl logging configuration redirects qgl / qglX to either log or dll versions +dnl ===================================================== + +define(`instance_funcptr', ``$1' ( * dll`$2' )(`$3');') +forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') +forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +dnl ===================================================== +dnl code +dnl ===================================================== + +/* +====================== +GLimp_BindNative +====================== +*/ +void GLimp_BindNative() { +define(`assign_funcptr', `qgl`$1' = dll`$1';') +forloop(`i', gl_start, gl_end, `assign_funcptr(indir(`f'i`_name')) +') + +define(`assign_funcptr', `qglX`$1' = dll`$1';') +forloop(`i', glX_start, glX_end, `assign_funcptr(indir(`f'i`_name')) +') +} + +static void *glHandle = NULL; + +/* +====================== +GLimp_dlsym_failed +====================== +*/ +void GLimp_dlsym_failed(const char *name) { + common->DPrintf("dlsym(%s) failed: %s\n", name, dlerror()); +} + +/* +====================== +GLimp_dlopen +====================== +*/ +bool GLimp_dlopen() { + const char *driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "libGL.so.1"; + common->Printf("dlopen(%s)\n", driverName); + if ( !( glHandle = dlopen( driverName, RTLD_NOW | RTLD_GLOBAL ) ) ) { + common->DPrintf("dlopen(%s) failed: %s\n", driverName, dlerror()); + return false; + } + + // dlsym the symbols + +define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "gl`$2'" );') +define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3') +if (!dll`$2') { GLimp_dlsym_failed("gl`$2'"); return false; }') +forloop(`i', gl_start, gl_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "glX`$2'" );') +define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3') +if (!dll`$2') { GLimp_dlsym_failed("glX`$2'"); return false; }') +forloop(`i', glX_start, glX_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + + // make the initial binding + GLimp_BindNative(); + + return true; +} + +/* +====================== +GLimp_dlclose +====================== +*/ +void GLimp_dlclose() { + if ( !glHandle ) { + common->DPrintf("dlclose: GL handle is NULL\n"); + } else { + dlclose( glHandle ); + glHandle = NULL; + } + +define(`reset_funcptr', `qgl`$1' = NULL;') +forloop(`i', gl_start, gl_end, `reset_funcptr(indir(`f'i`_name')) +') + +define(`reset_funcptr', `qglX`$1' = NULL;') +forloop(`i', glX_start, glX_end, `reset_funcptr(indir(`f'i`_name')) +') + +} diff --git a/sys/linux/glimp_glenum.h b/sys/linux/glimp_glenum.h new file mode 100644 index 000000000..ed7ebd7e3 --- /dev/null +++ b/sys/linux/glimp_glenum.h @@ -0,0 +1,425 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +DEF(GL_FALSE) +DEF(GL_TRUE) +DEF(GL_BYTE) +DEF(GL_UNSIGNED_BYTE) +DEF(GL_SHORT) +DEF(GL_UNSIGNED_SHORT) +DEF(GL_INT) +DEF(GL_UNSIGNED_INT) +DEF(GL_FLOAT) +DEF(GL_DOUBLE) +DEF(GL_TEXTURE_CUBE_MAP_EXT) +DEF(GL_TEXTURE_3D) +DEF(GL_TEXTURE_2D) +DEF(GL_BLEND) +DEF(GL_DEPTH_TEST) +DEF(GL_CULL_FACE) +DEF(GL_CLIP_PLANE0) +DEF(GL_COLOR_ARRAY) +DEF(GL_TEXTURE_COORD_ARRAY) +DEF(GL_VERTEX_ARRAY) +DEF(GL_ALPHA_TEST) +DEF(GL_TEXTURE_GEN_S) +DEF(GL_TEXTURE_GEN_T) +DEF(GL_TEXTURE_GEN_R) +DEF(GL_TEXTURE_GEN_Q) +DEF(GL_STENCIL_TEST) +DEF(GL_POLYGON_OFFSET_FILL) +DEF(GL_TRIANGLES) +DEF(GL_TRIANGLE_STRIP) +DEF(GL_TRIANGLE_FAN) +DEF(GL_QUADS) +DEF(GL_QUAD_STRIP) +DEF(GL_POLYGON) +DEF(GL_POINTS) +DEF(GL_LINES) +DEF(GL_LINE_STRIP) +DEF(GL_LINE_LOOP) +DEF(GL_ALWAYS) +DEF(GL_NEVER) +DEF(GL_LEQUAL) +DEF(GL_LESS) +DEF(GL_EQUAL) +DEF(GL_GREATER) +DEF(GL_GEQUAL) +DEF(GL_NOTEQUAL) +DEF(GL_ONE) +DEF(GL_ZERO) +DEF(GL_SRC_ALPHA) +DEF(GL_ONE_MINUS_SRC_ALPHA) +DEF(GL_DST_COLOR) +DEF(GL_ONE_MINUS_DST_COLOR) +DEF(GL_DST_ALPHA) +DEF(GL_MODELVIEW) +DEF(GL_PROJECTION) +DEF(GL_TEXTURE) +DEF(GL_NONE) +DEF(GL_FRONT_LEFT) +DEF(GL_FRONT_RIGHT) +DEF(GL_BACK_LEFT) +DEF(GL_BACK_RIGHT) +DEF(GL_FRONT) +DEF(GL_BACK) +DEF(GL_LEFT) +DEF(GL_RIGHT) +DEF(GL_FRONT_AND_BACK) +DEF(GL_AUX0) +DEF(GL_AUX1) +DEF(GL_AUX2) +DEF(GL_AUX3) +DEF(GL_CURRENT_COLOR) +DEF(GL_CURRENT_INDEX) +DEF(GL_CURRENT_NORMAL) +DEF(GL_CURRENT_TEXTURE_COORDS) +DEF(GL_CURRENT_RASTER_COLOR) +DEF(GL_CURRENT_RASTER_INDEX) +DEF(GL_CURRENT_RASTER_TEXTURE_COORDS) +DEF(GL_CURRENT_RASTER_POSITION) +DEF(GL_CURRENT_RASTER_POSITION_VALID) +DEF(GL_CURRENT_RASTER_DISTANCE) +DEF(GL_POINT_SMOOTH) +DEF(GL_POINT_SIZE) +DEF(GL_POINT_SIZE_RANGE) +DEF(GL_POINT_SIZE_GRANULARITY) +DEF(GL_LINE_SMOOTH) +DEF(GL_LINE_WIDTH) +DEF(GL_LINE_WIDTH_RANGE) +DEF(GL_LINE_WIDTH_GRANULARITY) +DEF(GL_LINE_STIPPLE) +DEF(GL_LINE_STIPPLE_PATTERN) +DEF(GL_LINE_STIPPLE_REPEAT) +DEF(GL_LIST_MODE) +DEF(GL_MAX_LIST_NESTING) +DEF(GL_LIST_BASE) +DEF(GL_LIST_INDEX) +DEF(GL_POLYGON_MODE) +DEF(GL_POLYGON_SMOOTH) +DEF(GL_POLYGON_STIPPLE) +DEF(GL_EDGE_FLAG) +DEF(GL_CULL_FACE) +DEF(GL_CULL_FACE_MODE) +DEF(GL_FRONT_FACE) +DEF(GL_LIGHTING) +DEF(GL_LIGHT_MODEL_LOCAL_VIEWER) +DEF(GL_LIGHT_MODEL_TWO_SIDE) +DEF(GL_LIGHT_MODEL_AMBIENT) +DEF(GL_SHADE_MODEL) +DEF(GL_COLOR_MATERIAL_FACE) +DEF(GL_COLOR_MATERIAL_PARAMETER) +DEF(GL_COLOR_MATERIAL) +DEF(GL_FOG) +DEF(GL_FOG_INDEX) +DEF(GL_FOG_DENSITY) +DEF(GL_FOG_START) +DEF(GL_FOG_END) +DEF(GL_FOG_MODE) +DEF(GL_FOG_COLOR) +DEF(GL_DEPTH_RANGE) +DEF(GL_DEPTH_TEST) +DEF(GL_DEPTH_WRITEMASK) +DEF(GL_DEPTH_CLEAR_VALUE) +DEF(GL_DEPTH_FUNC) +DEF(GL_ACCUM_CLEAR_VALUE) +DEF(GL_STENCIL_TEST) +DEF(GL_STENCIL_CLEAR_VALUE) +DEF(GL_STENCIL_FUNC) +DEF(GL_STENCIL_VALUE_MASK) +DEF(GL_STENCIL_FAIL) +DEF(GL_STENCIL_PASS_DEPTH_FAIL) +DEF(GL_STENCIL_PASS_DEPTH_PASS) +DEF(GL_STENCIL_REF) +DEF(GL_STENCIL_WRITEMASK) +DEF(GL_MATRIX_MODE) +DEF(GL_NORMALIZE) +DEF(GL_VIEWPORT) +DEF(GL_MODELVIEW_STACK_DEPTH) +DEF(GL_PROJECTION_STACK_DEPTH) +DEF(GL_TEXTURE_STACK_DEPTH) +DEF(GL_MODELVIEW_MATRIX) +DEF(GL_PROJECTION_MATRIX) +DEF(GL_TEXTURE_MATRIX) +DEF(GL_ATTRIB_STACK_DEPTH) +DEF(GL_CLIENT_ATTRIB_STACK_DEPTH) +DEF(GL_ALPHA_TEST) +DEF(GL_ALPHA_TEST_FUNC) +DEF(GL_ALPHA_TEST_REF) +DEF(GL_DITHER) +DEF(GL_BLEND_DST) +DEF(GL_BLEND_SRC) +DEF(GL_BLEND) +DEF(GL_LOGIC_OP_MODE) +DEF(GL_INDEX_LOGIC_OP) +DEF(GL_COLOR_LOGIC_OP) +DEF(GL_AUX_BUFFERS) +DEF(GL_DRAW_BUFFER) +DEF(GL_READ_BUFFER) +DEF(GL_SCISSOR_BOX) +DEF(GL_SCISSOR_TEST) +DEF(GL_INDEX_CLEAR_VALUE) +DEF(GL_INDEX_WRITEMASK) +DEF(GL_COLOR_CLEAR_VALUE) +DEF(GL_COLOR_WRITEMASK) +DEF(GL_INDEX_MODE) +DEF(GL_RGBA_MODE) +DEF(GL_DOUBLEBUFFER) +DEF(GL_STEREO) +DEF(GL_RENDER_MODE) +DEF(GL_PERSPECTIVE_CORRECTION_HINT) +DEF(GL_POINT_SMOOTH_HINT) +DEF(GL_LINE_SMOOTH_HINT) +DEF(GL_POLYGON_SMOOTH_HINT) +DEF(GL_FOG_HINT) +DEF(GL_TEXTURE_GEN_S) +DEF(GL_TEXTURE_GEN_T) +DEF(GL_TEXTURE_GEN_R) +DEF(GL_TEXTURE_GEN_Q) +DEF(GL_PIXEL_MAP_I_TO_I) +DEF(GL_PIXEL_MAP_S_TO_S) +DEF(GL_PIXEL_MAP_I_TO_R) +DEF(GL_PIXEL_MAP_I_TO_G) +DEF(GL_PIXEL_MAP_I_TO_B) +DEF(GL_PIXEL_MAP_I_TO_A) +DEF(GL_PIXEL_MAP_R_TO_R) +DEF(GL_PIXEL_MAP_G_TO_G) +DEF(GL_PIXEL_MAP_B_TO_B) +DEF(GL_PIXEL_MAP_A_TO_A) +DEF(GL_PIXEL_MAP_I_TO_I_SIZE) +DEF(GL_PIXEL_MAP_S_TO_S_SIZE) +DEF(GL_PIXEL_MAP_I_TO_R_SIZE) +DEF(GL_PIXEL_MAP_I_TO_G_SIZE) +DEF(GL_PIXEL_MAP_I_TO_B_SIZE) +DEF(GL_PIXEL_MAP_I_TO_A_SIZE) +DEF(GL_PIXEL_MAP_R_TO_R_SIZE) +DEF(GL_PIXEL_MAP_G_TO_G_SIZE) +DEF(GL_PIXEL_MAP_B_TO_B_SIZE) +DEF(GL_PIXEL_MAP_A_TO_A_SIZE) +DEF(GL_UNPACK_SWAP_BYTES) +DEF(GL_UNPACK_LSB_FIRST) +DEF(GL_UNPACK_ROW_LENGTH) +DEF(GL_UNPACK_SKIP_ROWS) +DEF(GL_UNPACK_SKIP_PIXELS) +DEF(GL_UNPACK_ALIGNMENT) +DEF(GL_PACK_SWAP_BYTES) +DEF(GL_PACK_LSB_FIRST) +DEF(GL_PACK_ROW_LENGTH) +DEF(GL_PACK_SKIP_ROWS) +DEF(GL_PACK_SKIP_PIXELS) +DEF(GL_PACK_ALIGNMENT) +DEF(GL_MAP_COLOR) +DEF(GL_MAP_STENCIL) +DEF(GL_INDEX_SHIFT) +DEF(GL_INDEX_OFFSET) +DEF(GL_RED_SCALE) +DEF(GL_RED_BIAS) +DEF(GL_ZOOM_X) +DEF(GL_ZOOM_Y) +DEF(GL_GREEN_SCALE) +DEF(GL_GREEN_BIAS) +DEF(GL_BLUE_SCALE) +DEF(GL_BLUE_BIAS) +DEF(GL_ALPHA_SCALE) +DEF(GL_ALPHA_BIAS) +DEF(GL_DEPTH_SCALE) +DEF(GL_DEPTH_BIAS) +DEF(GL_MAX_EVAL_ORDER) +DEF(GL_MAX_LIGHTS) +DEF(GL_MAX_CLIP_PLANES) +DEF(GL_MAX_TEXTURE_SIZE) +DEF(GL_MAX_PIXEL_MAP_TABLE) +DEF(GL_MAX_ATTRIB_STACK_DEPTH) +DEF(GL_MAX_MODELVIEW_STACK_DEPTH) +DEF(GL_MAX_NAME_STACK_DEPTH) +DEF(GL_MAX_PROJECTION_STACK_DEPTH) +DEF(GL_MAX_TEXTURE_STACK_DEPTH) +DEF(GL_MAX_VIEWPORT_DIMS) +DEF(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH) +DEF(GL_SUBPIXEL_BITS) +DEF(GL_INDEX_BITS) +DEF(GL_RED_BITS) +DEF(GL_GREEN_BITS) +DEF(GL_BLUE_BITS) +DEF(GL_ALPHA_BITS) +DEF(GL_DEPTH_BITS) +DEF(GL_STENCIL_BITS) +DEF(GL_ACCUM_RED_BITS) +DEF(GL_ACCUM_GREEN_BITS) +DEF(GL_ACCUM_BLUE_BITS) +DEF(GL_ACCUM_ALPHA_BITS) +DEF(GL_NAME_STACK_DEPTH) +DEF(GL_AUTO_NORMAL) +DEF(GL_MAP1_COLOR_4) +DEF(GL_MAP1_INDEX) +DEF(GL_MAP1_NORMAL) +DEF(GL_MAP1_TEXTURE_COORD_1) +DEF(GL_MAP1_TEXTURE_COORD_2) +DEF(GL_MAP1_TEXTURE_COORD_3) +DEF(GL_MAP1_TEXTURE_COORD_4) +DEF(GL_MAP1_VERTEX_3) +DEF(GL_MAP1_VERTEX_4) +DEF(GL_MAP2_COLOR_4) +DEF(GL_MAP2_INDEX) +DEF(GL_MAP2_NORMAL) +DEF(GL_MAP2_TEXTURE_COORD_1) +DEF(GL_MAP2_TEXTURE_COORD_2) +DEF(GL_MAP2_TEXTURE_COORD_3) +DEF(GL_MAP2_TEXTURE_COORD_4) +DEF(GL_MAP2_VERTEX_3) +DEF(GL_MAP2_VERTEX_4) +DEF(GL_MAP1_GRID_DOMAIN) +DEF(GL_MAP1_GRID_SEGMENTS) +DEF(GL_MAP2_GRID_DOMAIN) +DEF(GL_MAP2_GRID_SEGMENTS) +DEF(GL_TEXTURE_1D) +DEF(GL_TEXTURE_2D) +DEF(GL_FEEDBACK_BUFFER_POINTER) +DEF(GL_FEEDBACK_BUFFER_SIZE) +DEF(GL_FEEDBACK_BUFFER_TYPE) +DEF(GL_SELECTION_BUFFER_POINTER) +DEF(GL_SELECTION_BUFFER_SIZE) +DEF(GL_COLOR) +DEF(GL_DEPTH) +DEF(GL_STENCIL) +DEF(GL_COLOR_INDEX) +DEF(GL_STENCIL_INDEX) +DEF(GL_DEPTH_COMPONENT) +DEF(GL_RED) +DEF(GL_GREEN) +DEF(GL_BLUE) +DEF(GL_ALPHA) +DEF(GL_RGB) +DEF(GL_RGBA) +DEF(GL_LUMINANCE) +DEF(GL_LUMINANCE_ALPHA) +DEF(GL_PIXEL_MAP_I_TO_I) +DEF(GL_PIXEL_MAP_S_TO_S) +DEF(GL_PIXEL_MAP_I_TO_R) +DEF(GL_PIXEL_MAP_I_TO_G) +DEF(GL_PIXEL_MAP_I_TO_B) +DEF(GL_PIXEL_MAP_I_TO_A) +DEF(GL_PIXEL_MAP_R_TO_R) +DEF(GL_PIXEL_MAP_G_TO_G) +DEF(GL_PIXEL_MAP_B_TO_B) +DEF(GL_PIXEL_MAP_A_TO_A) +DEF(GL_UNPACK_SWAP_BYTES) +DEF(GL_UNPACK_LSB_FIRST) +DEF(GL_UNPACK_ROW_LENGTH) +DEF(GL_UNPACK_SKIP_ROWS) +DEF(GL_UNPACK_SKIP_PIXELS) +DEF(GL_UNPACK_ALIGNMENT) +DEF(GL_PACK_SWAP_BYTES) +DEF(GL_PACK_LSB_FIRST) +DEF(GL_PACK_ROW_LENGTH) +DEF(GL_PACK_SKIP_ROWS) +DEF(GL_PACK_SKIP_PIXELS) +DEF(GL_PACK_ALIGNMENT) +DEF(GL_MAP_COLOR) +DEF(GL_MAP_STENCIL) +DEF(GL_INDEX_SHIFT) +DEF(GL_INDEX_OFFSET) +DEF(GL_RED_SCALE) +DEF(GL_RED_BIAS) +DEF(GL_GREEN_SCALE) +DEF(GL_GREEN_BIAS) +DEF(GL_BLUE_SCALE) +DEF(GL_BLUE_BIAS) +DEF(GL_ALPHA_SCALE) +DEF(GL_ALPHA_BIAS) +DEF(GL_DEPTH_SCALE) +DEF(GL_DEPTH_BIAS) +DEF(GL_BITMAP) +DEF(GL_BYTE) +DEF(GL_UNSIGNED_BYTE) +DEF(GL_SHORT) +DEF(GL_UNSIGNED_SHORT) +DEF(GL_INT) +DEF(GL_UNSIGNED_INT) +DEF(GL_FLOAT) +DEF(GL_POINT) +DEF(GL_LINE) +DEF(GL_FILL) +DEF(GL_RENDER) +DEF(GL_FEEDBACK) +DEF(GL_SELECT) +DEF(GL_FLAT) +DEF(GL_SMOOTH) +DEF(GL_ZERO) +DEF(GL_KEEP) +DEF(GL_REPLACE) +DEF(GL_INCR) +DEF(GL_DECR) +DEF(GL_INVERT) +DEF(GL_VENDOR) +DEF(GL_RENDERER) +DEF(GL_VERSION) +DEF(GL_EXTENSIONS) +DEF(GL_S) +DEF(GL_T) +DEF(GL_R) +DEF(GL_Q) +DEF(GL_SHORT) +DEF(GL_INT) +DEF(GL_FLOAT) +DEF(GL_DOUBLE) +DEF(GL_MODULATE) +DEF(GL_DECAL) +DEF(GL_BLEND) +DEF(GL_REPLACE) +DEF(GL_TEXTURE_ENV_MODE) +DEF(GL_TEXTURE_ENV_COLOR) +DEF(GL_TEXTURE_ENV) +DEF(GL_EYE_LINEAR) +DEF(GL_OBJECT_LINEAR) +DEF(GL_SPHERE_MAP) +DEF(GL_TEXTURE_GEN_MODE) +DEF(GL_OBJECT_PLANE) +DEF(GL_EYE_PLANE) +DEF(GL_NEAREST) +DEF(GL_LINEAR) +DEF(GL_NEAREST) +DEF(GL_LINEAR) +DEF(GL_NEAREST_MIPMAP_NEAREST) +DEF(GL_LINEAR_MIPMAP_NEAREST) +DEF(GL_NEAREST_MIPMAP_LINEAR) +DEF(GL_LINEAR_MIPMAP_LINEAR) +DEF(GL_TEXTURE_MAG_FILTER) +DEF(GL_TEXTURE_MIN_FILTER) +DEF(GL_TEXTURE_WRAP_S) +DEF(GL_TEXTURE_WRAP_T) +DEF(GL_TEXTURE_BORDER_COLOR) +DEF(GL_TEXTURE_PRIORITY) +DEF(GL_TEXTURE_1D) +DEF(GL_TEXTURE_2D) +DEF(GL_PROXY_TEXTURE_1D) +DEF(GL_PROXY_TEXTURE_2D) +DEF(GL_CLAMP) +DEF(GL_REPEAT) +DEF(GL_SHORT) +DEF(GL_INT) +DEF(GL_FLOAT) +DEF(GL_DOUBLE) +DEF(GL_CLIENT_PIXEL_STORE_BIT) +DEF(GL_CLIENT_VERTEX_ARRAY_BIT) +/* DEF(GL_CLIENT_ALL_ATTRIB_BITS) */ +DEF(GL_POLYGON_OFFSET_FACTOR) +DEF(GL_POLYGON_OFFSET_UNITS) +DEF(GL_POLYGON_OFFSET_POINT) +DEF(GL_POLYGON_OFFSET_LINE) +DEF(GL_POLYGON_OFFSET_FILL) diff --git a/sys/linux/glimp_local.h.m4 b/sys/linux/glimp_local.h.m4 new file mode 100644 index 000000000..a43785e56 --- /dev/null +++ b/sys/linux/glimp_local.h.m4 @@ -0,0 +1,24 @@ +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl the gl wgl glX definitions +dnl ===================================================== +include(../gllog/gl_def.m4) + +dnl ===================================================== +dnl dll funcs declare +dnl ===================================================== + +define(`declare_funcptr', `extern `$1' ( * dll`$2' )(`$3');') +forloop(`i', gl_start, gl_end, `declare_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') +forloop(`i', glX_start, glX_end, `declare_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') diff --git a/sys/linux/glimp_logging.cpp.m4 b/sys/linux/glimp_logging.cpp.m4 new file mode 100644 index 000000000..0145e5091 --- /dev/null +++ b/sys/linux/glimp_logging.cpp.m4 @@ -0,0 +1,185 @@ +#include "idlib/precompiled.h" +#include "renderer/tr_local.h" +#include "sys/linux/local.h" +#include "glimp_local.h" +#pragma hdrstop + +#include +#define ID_LOG_TO_STDOUT 0 + +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl the gl wgl glX definitions +dnl ===================================================== +include(../gllog/gl_def.m4) + +dnl ===================================================== +dnl logging functions +dnl ===================================================== + +typedef struct { + GLenum e; + const char *name; +} glEnumName_t; + +#define DEF(x) { x, #x }, + +glEnumName_t glEnumNames[] = { +#include "sys/linux/glimp_glenum.h" + { 0, NULL } +}; + +/* +====================== +EnumString +====================== +*/ +static const char *EnumString( GLenum t ) +{ + static char buffer[8][1024]; + static int index = 0; + + for ( glEnumName_t *n = glEnumNames ; n->name ; n++ ) { + if ( t == n->e ) { + return n->name; + } + } + + int oldIndex = index; + index = ( index + 1 ) & 7; + sprintf( buffer[oldIndex], "0x%x", t ); + + return buffer[oldIndex]; +} + +/* +====================== +FloatData +====================== +*/ +static const char *FloatData( const GLfloat *v, int count ) { + static char buffer[8][1024]; + static int index = 0; + char *name; + + name = buffer[index&7]; + sprintf( name, "f%i", index ); + index++; + + fprintf( tr.logFile, "static float %s[%i] = {", name, count ); + for( int i = 0 ; i < count ; i++ ) { + if ( i < count - 1 ) { + fprintf( tr.logFile, "%f,", v[i] ); + } else { + fprintf( tr.logFile, "%f};\n", v[i] ); + } + } + + return name; +} + +#include "glimp_logfuncs.cpp" + +dnl define(`log_func', `static `$1' APIENTRY log`$2'(`$3') { +dnl }') +dnl forloop(`i', gl_start, gl_end, `log_func(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +dnl ') +dnl forloop(`i', glX_start, glX_end, `log_func(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +dnl ') + +/* +====================== +GLimp_BindLogging +====================== +*/ +void GLimp_BindLogging() { +define(`assign_funcptr', `qgl`$1' = log`$1';') +forloop(`i', gl_start, gl_end, `assign_funcptr(indir(`f'i`_name')) +') + +define(`assign_funcptr', `qglX`$1' = log`$1';') +forloop(`i', glX_start, glX_end, `assign_funcptr(indir(`f'i`_name')) +') +} + +/* +====================== +GLimp_EnableLogging +====================== +*/ +void GLimp_EnableLogging(bool enable) { + static bool isEnabled = false; + static idStr ospath; + static int initialFrames; + + // return if we're already active + if ( isEnabled && enable ) { + // decrement log counter and stop if it has reached 0 + r_logFile.SetInteger( r_logFile.GetInteger() - 1 ); + if ( r_logFile.GetInteger() ) { + return; + } +#if ID_LOG_TO_STDOUT + common->Printf( "end stdout GL loggging after %i frames.\n", initialFrames ); +#else + common->Printf( "closing GL logfile '%s' after %i frames.\n", ospath.c_str(), initialFrames ); + + fclose( tr.logFile ); +#endif + enable = false; + tr.logFile = NULL; + } + + // return if we're already disabled + if ( !enable && !isEnabled ) { + return; + } + + isEnabled = enable; + + if ( enable ) { + if ( !tr.logFile ) { + struct tm *newtime; + time_t aclock; + idStr qpath; + int i; + + initialFrames = r_logFile.GetInteger(); + +#if ID_LOG_TO_STDOUT + tr.logFile = fdopen( STDOUT_FILENO, "w" ); +#else + // scan for an unused filename + for ( i = 0 ; i < 9999 ; i++ ) { + sprintf( qpath, "renderlog_%i.txt", i ); + if ( fileSystem->ReadFile( qpath, NULL, NULL ) == -1 ) { + break; // use this name + } + } + + ospath = fileSystem->RelativePathToOSPath( qpath ); + tr.logFile = fopen( ospath, "wt" ); +#endif + + // write the time out to the top of the file + time( &aclock ); + newtime = localtime( &aclock ); + fprintf( tr.logFile, "// %s", asctime( newtime ) ); + fprintf( tr.logFile, "// %s\n\n", com_version.GetString() ); + } + + GLimp_BindLogging(); + } else { + + GLimp_BindNative(); + } +} diff --git a/sys/linux/glimp_stub.cpp.m4 b/sys/linux/glimp_stub.cpp.m4 new file mode 100644 index 000000000..4c6221564 --- /dev/null +++ b/sys/linux/glimp_stub.cpp.m4 @@ -0,0 +1,66 @@ +// glimp_stub.cpp.m4 +// stub gl/glX APIs + +#include "idlib/precompiled.h" +#include "renderer/tr_local.h" +#pragma hdrstop + +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl the gl wgl glX definitions +dnl ===================================================== +include(../gllog/gl_def.m4) + +dnl ===================================================== +dnl qgl stubs +dnl there is a number of functions for which we have special case code +dnl ===================================================== + +define(`override_GetError', `') +define(`override_GenLists', `') +define(`override_GetIntegerv', `') +define(`override_GetString', `') + +define(`instance_funcptr', ``$1' gl`$2'(`$3'){}') +define(`try_instance_funcptr', `ifdef(`override_'$2, ,`instance_funcptr(`$1', `$2', `$3')')') +forloop(`i', gl_start, gl_end, `try_instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +dnl ===================================================== +dnl glX stubs +dnl ===================================================== + +define(`override_GetProcAddressARB', `') + +define(`instance_funcptr', ``$1' glX`$2'(`$3'){}') +define(`try_instance_funcptr', `ifdef(`override_'$2, ,`instance_funcptr(`$1', `$2', `$3')')') +forloop(`i', glX_start, glX_end, `try_instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params')) +') + +GLenum glGetError(void){return 0;} + +GLuint glGenLists(GLsizei range){return 0;} + +void glGetIntegerv(GLenum pname, GLint *params){ + switch( pname ) { + case GL_MAX_TEXTURE_SIZE: *params = 1024; break; + case GL_MAX_TEXTURE_UNITS_ARB: *params = 2; break; + default: *params = 0; break; + } +} + +const GLubyte * glGetString(GLenum name){ + switch( name ) { + case GL_EXTENSIONS: return (GLubyte *)"GL_ARB_multitexture GL_ARB_texture_env_combine GL_ARB_texture_cube_map GL_ARB_texture_env_dot3"; + } + return (const GLubyte *)""; +} diff --git a/sys/linux/input.cpp b/sys/linux/input.cpp new file mode 100644 index 000000000..853279dfb --- /dev/null +++ b/sys/linux/input.cpp @@ -0,0 +1,553 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../posix/posix_public.h" +#include "local.h" + +#include + +idCVar in_mouse( "in_mouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); +idCVar in_dgamouse( "in_dgamouse", "1", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); +idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "" ); + +// have a working xkb extension +static bool have_xkb = false; + +// toggled by grab calls - decides if we ignore MotionNotify events +static bool mouse_active = false; + +// non-DGA pointer-warping mouse input +static int mwx, mwy; +static int mx = 0, my = 0; + +// time mouse was last reset, we ignore the first 50ms of the mouse to allow settling of events +static int mouse_reset_time = 0; +#define MOUSE_RESET_DELAY 50 + +// backup original values for pointer grab/ungrab +static int mouse_accel_numerator; +static int mouse_accel_denominator; +static int mouse_threshold; + +static byte s_scantokey[128] = { +/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 */ 0, 27, '1', '2', '3', '4', '5', '6', // 27 - ESC +/* 10 */ '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 9 - TAB +/* 18 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', +/* 20 */ 'o', 'p', '[', ']', K_ENTER, K_CTRL, 'a', 's', +/* 28 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', +/* 30 */ '\'', '`', K_SHIFT, '\\', 'z', 'x', 'c', 'v', +/* 38 */ 'b', 'n', 'm', ',', '.', '/', K_SHIFT, K_KP_STAR, +/* 40 */ K_ALT, ' ', K_CAPSLOCK, K_F1, K_F2, K_F3, K_F4, K_F5, +/* 48 */ K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, 0, K_HOME, +/* 50 */ K_UPARROW, K_PGUP, K_KP_MINUS, K_LEFTARROW, K_KP_5, K_RIGHTARROW, K_KP_PLUS, K_END, +/* 58 */ K_DOWNARROW, K_PGDN, K_INS, K_DEL, 0, 0, '\\', K_F11, +/* 60 */ K_F12, K_HOME, K_UPARROW, K_PGUP, K_LEFTARROW, 0, K_RIGHTARROW, K_END, +/* 68 */ K_DOWNARROW, K_PGDN, K_INS, K_DEL, K_ENTER, K_CTRL, K_PAUSE, 0, +/* 70 */ '/', K_ALT, 0, 0, 0, 0, 0, 0, +/* 78 */ 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* +================= +IN_Clear_f +================= +*/ +void IN_Clear_f( const idCmdArgs &args ) { + idKeyInput::ClearStates(); +} + +/* +================= +Sys_InitInput +================= +*/ +void Sys_InitInput(void) { + int major_in_out, minor_in_out, opcode_rtrn, event_rtrn, error_rtrn; + bool ret; + + common->Printf( "\n------- Input Initialization -------\n" ); + assert( dpy ); + cmdSystem->AddCommand( "in_clear", IN_Clear_f, CMD_FL_SYSTEM, "reset the input keys" ); + major_in_out = XkbMajorVersion; + minor_in_out = XkbMinorVersion; + ret = XkbLibraryVersion( &major_in_out, &minor_in_out ); + common->Printf( "XKB extension: compile time 0x%x:0x%x, runtime 0x%x:0x%x: %s\n", XkbMajorVersion, XkbMinorVersion, major_in_out, minor_in_out, ret ? "OK" : "Not compatible" ); + if ( ret ) { + ret = XkbQueryExtension( dpy, &opcode_rtrn, &event_rtrn, &error_rtrn, &major_in_out, &minor_in_out ); + if ( ret ) { + common->Printf( "XKB extension present on server ( 0x%x:0x%x )\n", major_in_out, minor_in_out ); + have_xkb = true; + } else { + common->Printf( "XKB extension not present on server\n" ); + have_xkb = false; + } + } else { + have_xkb = false; + } + common->Printf( "------------------------------------\n" ); +} + +//#define XEVT_DBG +//#define XEVT_DBG2 + +static Cursor Sys_XCreateNullCursor( Display *display, Window root ) { + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} + +static void Sys_XInstallGrabs( void ) { + assert( dpy ); + + XWarpPointer( dpy, None, win, + 0, 0, 0, 0, + glConfig.vidWidth / 2, glConfig.vidHeight / 2 ); + + XSync( dpy, False ); + + XDefineCursor( dpy, win, Sys_XCreateNullCursor( dpy, win ) ); + + XGrabPointer( dpy, win, + False, + MOUSE_MASK, + GrabModeAsync, GrabModeAsync, + win, + None, + CurrentTime ); + + XGetPointerControl( dpy, &mouse_accel_numerator, &mouse_accel_denominator, + &mouse_threshold ); + + XChangePointerControl( dpy, True, True, 1, 1, 0 ); + + XSync( dpy, False ); + + mouse_reset_time = Sys_Milliseconds (); + + if ( in_dgamouse.GetBool() && !dga_found ) { + common->Printf("XF86DGA not available, forcing DGA mouse off\n"); + in_dgamouse.SetBool( false ); + } + + if ( in_dgamouse.GetBool() ) { +#if defined( ID_ENABLE_DGA ) + XF86DGADirectVideo( dpy, DefaultScreen( dpy ), XF86DGADirectMouse ); + XWarpPointer( dpy, None, win, 0, 0, 0, 0, 0, 0 ); +#endif + } else { + mwx = glConfig.vidWidth / 2; + mwy = glConfig.vidHeight / 2; + mx = my = 0; + } + + XGrabKeyboard( dpy, win, + False, + GrabModeAsync, GrabModeAsync, + CurrentTime ); + + XSync( dpy, False ); + + mouse_active = true; +} + +void Sys_XUninstallGrabs(void) { + assert( dpy ); + +#if defined( ID_ENABLE_DGA ) + if ( in_dgamouse.GetBool() ) { + common->DPrintf( "DGA Mouse - Disabling DGA DirectVideo\n" ); + XF86DGADirectVideo( dpy, DefaultScreen( dpy ), 0 ); + } +#endif + + XChangePointerControl( dpy, true, true, mouse_accel_numerator, + mouse_accel_denominator, mouse_threshold ); + + XUngrabPointer( dpy, CurrentTime ); + XUngrabKeyboard( dpy, CurrentTime ); + + XWarpPointer( dpy, None, win, + 0, 0, 0, 0, + glConfig.vidWidth / 2, glConfig.vidHeight / 2); + + XUndefineCursor( dpy, win ); + + mouse_active = false; +} + +void Sys_GrabMouseCursor( bool grabIt ) { + +#if defined( ID_DEDICATED ) + return; +#endif + + if ( !dpy ) { + #ifdef XEVT_DBG + common->DPrintf("Sys_GrabMouseCursor: !dpy\n"); + #endif + return; + } + + if ( glConfig.isFullscreen ) { + if ( !grabIt ) { + return; // never ungrab while fullscreen + } + if ( in_nograb.GetBool() ) { + common->DPrintf("forcing in_nograb 0 while running fullscreen\n"); + in_nograb.SetBool( false ); + } + } + + if ( in_nograb.GetBool() ) { + if ( in_dgamouse.GetBool() ) { + common->DPrintf("in_nograb 1, forcing forcing DGA mouse off\n"); + in_dgamouse.SetBool( false ); + } + if (grabIt) { + mouse_active = true; + } else { + mouse_active = false; + } + return; + } + + if ( grabIt && !mouse_active ) { + Sys_XInstallGrabs(); + } else if ( !grabIt && mouse_active ) { + Sys_XUninstallGrabs(); + } +} + +/** + * XPending() actually performs a blocking read + * if no events available. From Fakk2, by way of + * Heretic2, by way of SDL, original idea GGI project. + * The benefit of this approach over the quite + * badly behaved XAutoRepeatOn/Off is that you get + * focus handling for free, which is a major win + * with debug and windowed mode. It rests on the + * assumption that the X server will use the + * same timestamp on press/release event pairs + * for key repeats. + */ +static bool Sys_XPendingInput( void ) { + // Flush the display connection + // and look to see if events are queued + XFlush( dpy ); + if ( XEventsQueued( dpy, QueuedAlready) ) { + return true; + } + + // More drastic measures are required -- see if X is ready to talk + static struct timeval zero_time; + int x11_fd; + fd_set fdset; + + x11_fd = ConnectionNumber( dpy ); + FD_ZERO( &fdset ); + FD_SET( x11_fd, &fdset ); + if ( select( x11_fd+1, &fdset, NULL, NULL, &zero_time ) == 1 ) { + return XPending( dpy ); + } + + // Oh well, nothing is ready .. + return false; +} + +/** + * Intercept a KeyRelease-KeyPress sequence and ignore + */ +static bool Sys_XRepeatPress( XEvent *event ) { + XEvent peekevent; + bool repeated = false; + int lookupRet; + char buf[5]; + KeySym keysym; + + if ( Sys_XPendingInput() ) { + XPeekEvent( dpy, &peekevent ); + + if ((peekevent.type == KeyPress) && + (peekevent.xkey.keycode == event->xkey.keycode) && + (peekevent.xkey.time == event->xkey.time)) { + repeated = true; + XNextEvent( dpy, &peekevent ); + // emit an SE_CHAR for the repeat + lookupRet = XLookupString( (XKeyEvent*)&peekevent, buf, sizeof(buf), &keysym, NULL ); + if (lookupRet > 0) { + Posix_QueEvent( SE_CHAR, buf[ 0 ], 0, 0, NULL); + } else { + // shouldn't we be doing a release/press in this order rather? + // ( doesn't work .. but that's what I would have expected to do though ) + Posix_QueEvent( SE_KEY, s_scantokey[peekevent.xkey.keycode], true, 0, NULL); + Posix_QueEvent( SE_KEY, s_scantokey[peekevent.xkey.keycode], false, 0, NULL); + } + } + } + + return repeated; +} + +/* +========================== +Posix_PollInput +========================== +*/ +void Posix_PollInput() { + static char buf[16]; + static XEvent event; + static XKeyEvent *key_event = (XKeyEvent*)&event; + int lookupRet; + int b, dx, dy; + KeySym keysym; + + if ( !dpy ) { + return; + } + + // NOTE: Sys_GetEvent only calls when there are no events left + // but here we pump all X events that have accumulated + // pump one by one? or use threaded input? + while ( XPending( dpy ) ) { + XNextEvent( dpy, &event ); + switch (event.type) { + case KeyPress: + #ifdef XEVT_DBG + if (key_event->keycode > 0x7F) + common->DPrintf("WARNING: KeyPress keycode > 0x7F"); + #endif + key_event->keycode &= 0x7F; + #ifdef XEVT_DBG2 + printf("SE_KEY press %d\n", key_event->keycode); + #endif + Posix_QueEvent( SE_KEY, s_scantokey[key_event->keycode], true, 0, NULL); + lookupRet = XLookupString(key_event, buf, sizeof(buf), &keysym, NULL); + if (lookupRet > 0) { + char s = buf[0]; + #ifdef XEVT_DBG + if (buf[1]!=0) + common->DPrintf("WARNING: got XLookupString buffer '%s' (%d)\n", buf, strlen(buf)); + #endif + #ifdef XEVT_DBG2 + printf("SE_CHAR %s\n", buf); + #endif + Posix_QueEvent( SE_CHAR, s, 0, 0, NULL); + } + if (!Posix_AddKeyboardPollEvent( s_scantokey[key_event->keycode], true )) + return; + break; + + case KeyRelease: + if (Sys_XRepeatPress(&event)) { + #ifdef XEVT_DBG2 + printf("RepeatPress\n"); + #endif + continue; + } + #ifdef XEVT_DBG + if (key_event->keycode > 0x7F) + common->DPrintf("WARNING: KeyRelease keycode > 0x7F"); + #endif + key_event->keycode &= 0x7F; + #ifdef XEVT_DBG2 + printf("SE_KEY release %d\n", key_event->keycode); + #endif + Posix_QueEvent( SE_KEY, s_scantokey[key_event->keycode], false, 0, NULL); + if (!Posix_AddKeyboardPollEvent( s_scantokey[key_event->keycode], false )) + return; + break; + + case ButtonPress: + if (event.xbutton.button == 4) { + Posix_QueEvent( SE_KEY, K_MWHEELUP, true, 0, NULL); + if (!Posix_AddMousePollEvent( M_DELTAZ, 1 )) + return; + } else if (event.xbutton.button == 5) { + Posix_QueEvent( SE_KEY, K_MWHEELDOWN, true, 0, NULL); + if (!Posix_AddMousePollEvent( M_DELTAZ, -1 )) + return; + } else { + b = -1; + if (event.xbutton.button == 1) { + b = 0; // K_MOUSE1 + } else if (event.xbutton.button == 2) { + b = 2; // K_MOUSE3 + } else if (event.xbutton.button == 3) { + b = 1; // K_MOUSE2 + } else if (event.xbutton.button == 6) { + b = 3; // K_MOUSE4 + } else if (event.xbutton.button == 7) { + b = 4; // K_MOUSE5 + } + if (b == -1 || b > 4) { + common->DPrintf("X ButtonPress %d not supported\n", event.xbutton.button); + } else { + Posix_QueEvent( SE_KEY, K_MOUSE1 + b, true, 0, NULL); + if (!Posix_AddMousePollEvent( M_ACTION1 + b, true )) + return; + } + } + break; + + case ButtonRelease: + if (event.xbutton.button == 4) { + Posix_QueEvent( SE_KEY, K_MWHEELUP, false, 0, NULL); + } else if (event.xbutton.button == 5) { + Posix_QueEvent( SE_KEY, K_MWHEELDOWN, false, 0, NULL); + } else { + b = -1; + if (event.xbutton.button == 1) { + b = 0; + } else if (event.xbutton.button == 2) { + b = 2; + } else if (event.xbutton.button == 3) { + b = 1; + } else if (event.xbutton.button == 6) { + b = 3; // K_MOUSE4 + } else if (event.xbutton.button == 7) { + b = 4; // K_MOUSE5 + } + if (b == -1 || b > 4) { + common->DPrintf("X ButtonRelease %d not supported\n", event.xbutton.button); + } else { + Posix_QueEvent( SE_KEY, K_MOUSE1 + b, false, 0, NULL); + if (!Posix_AddMousePollEvent( M_ACTION1 + b, false )) + return; + } + } + break; + + case MotionNotify: + if (!mouse_active) + break; + if (in_dgamouse.GetBool()) { + dx = event.xmotion.x_root; + dy = event.xmotion.y_root; + + Posix_QueEvent( SE_MOUSE, dx, dy, 0, NULL); + + // if we overflow here, we'll get a warning, but the delta will be completely processed anyway + Posix_AddMousePollEvent( M_DELTAX, dx ); + if (!Posix_AddMousePollEvent( M_DELTAY, dy )) + return; + } else { + // if it's a center motion, we've just returned from our warp + // FIXME: we generate mouse delta on wrap return, but that lags us quite a bit from the initial event.. + if (event.xmotion.x == glConfig.vidWidth / 2 && + event.xmotion.y == glConfig.vidHeight / 2) { + mwx = glConfig.vidWidth / 2; + mwy = glConfig.vidHeight / 2; + + Posix_QueEvent( SE_MOUSE, mx, my, 0, NULL); + + Posix_AddMousePollEvent( M_DELTAX, mx ); + if (!Posix_AddMousePollEvent( M_DELTAY, my )) + return; + mx = my = 0; + break; + } + + dx = ((int) event.xmotion.x - mwx); + dy = ((int) event.xmotion.y - mwy); + mx += dx; + my += dy; + + mwx = event.xmotion.x; + mwy = event.xmotion.y; + XWarpPointer(dpy,None,win,0,0,0,0, (glConfig.vidWidth/2),(glConfig.vidHeight/2)); + } + break; + } + } +} + +/* +================= +Sys_ShutdownInput +================= +*/ +void Sys_ShutdownInput( void ) { } + +/* +=============== +Sys_MapCharForKey +=============== +*/ +unsigned char Sys_MapCharForKey( int _key ) { + int key; // scan key ( != doom key ) + XkbStateRec kbd_state; + XEvent event; + KeySym keysym; + int lookupRet; + char buf[5]; + + if ( !have_xkb || !dpy ) { + return (unsigned char)_key; + } + + // query the current keyboard group, must be passed as bit 13-14 in the constructed XEvent + // see X Keyboard Extension library specifications + XkbGetState( dpy, XkbUseCoreKbd, &kbd_state ); + + // lookup scancode from doom key code. unique hits + for ( key = 0; key < 128; key++ ) { + if ( _key == s_scantokey[ key ] ) { + break; + } + } + if ( key == 128 ) { + // it happens. these, we can't convert + common->DPrintf( "Sys_MapCharForKey: doom key %d -> keycode failed\n", _key ); + return (unsigned char)_key; + } + + memset( &event, 0, sizeof( XEvent ) ); + event.xkey.type = KeyPress; + event.xkey.display = dpy; + event.xkey.time = CurrentTime; + event.xkey.keycode = key; + event.xkey.state = kbd_state.group << 13; + + lookupRet = XLookupString( (XKeyEvent *)&event, buf, sizeof( buf ), &keysym, NULL ); + if ( lookupRet <= 0 ) { + Sys_Printf( "Sys_MapCharForKey: XLookupString key 0x%x failed\n", key ); + return (unsigned char)_key; + } + if ( lookupRet > 1 ) { + // only ever expecting 1 char.. + Sys_Printf( "Sys_MapCharForKey: XLookupString returned '%s'\n", buf ); + } + return buf[ 0 ]; +} diff --git a/sys/linux/libXNVCtrl/NV-CONTROL-API.txt b/sys/linux/libXNVCtrl/NV-CONTROL-API.txt new file mode 100644 index 000000000..f8f43af2d --- /dev/null +++ b/sys/linux/libXNVCtrl/NV-CONTROL-API.txt @@ -0,0 +1,385 @@ + + NV-CONTROL X Extension - API specificiation v 1.6 + + +1. INTRODUCTION + + The NV-CONTROL X extension provides a mechanism for X clients to + query and set configuration parameters of the NVIDIA X driver. + State set by the NV-CONTROL X extension is assumed to be persistent + only for the current server generation. + + Attributes are configurable on a per X screen basis, and some + attributes are also configurable on a per display device basis. + Addtionally, some attributes can only be queried, though most can + be both queried and modified. The NV-CONTROL extension provides + a mechanism to determine what values are valid for an attribute, + if an attribute is read-only, if it can be read and written, if it + requires a display device qualifier, and if the the attribute is + available on the specified X screen. + + Finally, NV-CONTROL clients may also request to be notified when an + attribute is changed by any other NV-CONTROL client. + + + +2. DISPLAY DEVICES + + A "Display Device" refers to some piece of hardware capable of + displaying an image. Display devices are separated into the three + general categories: analog CRTs, digital flatpanels, and TVs. + Note that analog flatpanels fall under the category of analog CRTs. + + The NVIDIA X driver allows multiple display devices to display + portions of the same X screen; this is configured through the + TwinView feature of the NVIDIA X driver. TwinView is described in + the Appendix on TwinView in the NVIDIA Linux driver text README file. + A consequence of TwinView is that an X screen does not necessarily + uniquely identify a display device. + + While most attributes controlled by the NV-CONTROL X extension + apply to an entire X screen, some attributes can be controlled per + display device. When querying and assigning such attributes, the + particular display device is specified via a display device mask. + + A "display device mask" is an unsigned 32 bit value that identifies + one or more display devices: the first 8 bits each identify a CRT, the + next 8 bits each identify a TV, and the next 8 each identify a DFP. + For example, 0x1 refers to CRT-0, 0x3 refers to CRT-0 and CRT-1, + 0x10001 refers to CRT-0 and DFP-0, etc. + + + +3. QUERYING THE EXTENSION + + NV-CONTROL clients can query for the existence of the NV-CONTROL X + extension with: + + Bool XNVCTRLQueryExtension (Display *dpy, + int *event_basep, int *error_basep); + + This function returns True if the extension exists, and returns False + if the extension does not. It also returns the error and event bases. + The arguments are: + + dpy - The connection to the X server. + event_basep - The returned event base. Currently, only one + extension specific event is defined. + error_basep - The returned error base. Currently, no extension + specific errors are defined. + + The version of the NV-CONTROL extension can be queried with: + + Bool XNVCTRLQueryVersion (Display *dpy, int *major, int *minor); + + This function returns True if the extension exists, and returns + False if it does not. It also returns the major and minor version + numbers of the extension. The arguments are: + + dpy - The connection to the X server. + major - The returned major version number of the extension. + minor - The returned minor version number of the extension. + + + You can determine if a particular X screen is controlled by the + NVIDIA X driver (and thus supports the NV-CONTROL X extension) with: + + Bool XNVCTRLIsNvScreen (Display *dpy, int screen); + + This function returns True if the specified screen is controlled by + the NVIDIA driver, and thus supports the NV-CONTROL X extension. + It returns False if the specified screen does not support the + NV-CONTROL X extension. The arguments are: + + dpy - The connection to the X server. + screen - the X screen to query. + + + +4. QUERYING VALID ATTRIBUTE VALUES + + NV-CONTROL clients can query the valid values for any integer + attribute with: + + Bool XNVCTRLQueryValidAttributeValues (Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec + *values); + + This function returns True if the attribute exists on the specified + X screen, or False if the attribute is not available on the specified + X screen. + + The arguments are: + + dpy - The connection to the X server. + screen - the X screen to query. + display_mask - for attributes that can be controlled on a per + display device basis, the display_mask should + uniquely identify a single display device. + This argument is ignored for attributes that + apply to the entire X screen. + attribute - the integer attribute to query + values - the returned NVCTRLAttributeValidValuesRec structure. + + The NVCTRLAttributeValidValuesRec structure is defined as: + + typedef struct _NVCTRLAttributeValidValues { + int type; + union { + struct { + int min; + int max; + } range; + struct { + unsigned int ints; + } bits; + } u; + unsigned int permissions; + } NVCTRLAttributeValidValuesRec; + + Where type can be one of: + + #define ATTRIBUTE_TYPE_UNKNOWN 0 + #define ATTRIBUTE_TYPE_INTEGER 1 + #define ATTRIBUTE_TYPE_BITMASK 2 + #define ATTRIBUTE_TYPE_BOOL 3 + #define ATTRIBUTE_TYPE_RANGE 4 + #define ATTRIBUTE_TYPE_INT_BITS 5 + + ATTRIBUTE_TYPE_INTEGER indicates that the attribute is an integer + value; any integer may be specified when setting this attribute. + + ATTRIBUTE_TYPE_BITMASK indicates that the attribute is an integer + value, interpretted as a bitmask. This is the type, for example, + of the NV_CTRL_CONNECTED_DISPLAYS attribute. + + ATTRIBUTE_TYPE_BOOL indicates that the attribute is a boolean; + valid values are 1 (on/true) and 0 (off/false). + + ATTRIBUTE_TYPE_RANGE indicates that the attribute can have any + integer value between NVCTRLAttributeValidValues.u.range.min and + NVCTRLAttributeValidValues.u.range.max (inclusive). + + ATTRIBUTE_TYPE_INT_BITS indicates that the attribute can + only have certain integer values, indicated by which bits in + NVCTRLAttributeValidValues.u.bits.ints are on (for example: if bit + 0 is on, then 0 is a valid value; if bit 5 is on, then 5 is a valid + value, etc). This is the type, for example, of NV_CTRL_FSAA_MODE. + + + The permissions field in NVCTRLAttributeValidValuesRec is a bitmask + that can contain any of: + + #define ATTRIBUTE_TYPE_READ 0x1 + #define ATTRIBUTE_TYPE_WRITE 0x2 + #define ATTRIBUTE_TYPE_DISPLAY 0x4 + + ATTRIBUTE_TYPE_READ indicates that the attribute is readable; in + general, all attributes will be readable. + + ATTRIBUTE_TYPE_WRITE indicates that the attribute is writable; + attributes may not be writable for various reasons: they represent + static system information, they can only be changed by changing an + XF86Config option, etc. + + ATTRIBUTE_TYPE_DISPLAY indicates that the attribute can be + controlled on a per display device basis, and thus + XNVCTRLQueryAttribute() and XNVCTRLSetAttribute() require that a + display device be specified. + + The XNVCTRLQueryValidAttributeValues() function can cause the + following X protocol errors: + + BadValue - The screen does not exist. + BadMatch - The NVIDIA driver is not present on that screen. + + + +5. QUERYING ATTRIBUTE VALUES + + NV-CONTROL clients can query the current value of an integer + attribute with: + + Bool XNVCTRLQueryAttribute (Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value); + + This function returns True if the attribute exists, and stores the + current attribute value in the memory pointed to by the value + argument. False is returned if the attribute does not exist on the + specified X screen. + + The arguments are: + + dpy - The connection to the X server. + screen - the X screen to query. + display_mask - if the attribute requires a display device, + then this indicates the display device to query; + this field is ignored if the attribute is not + display device specific. You can determine + if an attribute is display device specific by + querying the valid values and checking for the + ATTRIBUTE_TYPE_DISPLAY bit in the permissions + field. + attribute - the attribute to query. + value - the returned attribute value. + + This function can cause the following X protocol errors: + + BadValue - The screen does not exist. + BadMatch - The NVIDIA driver is not present on that screen. + + + NV-CONTROL clients can query the read-only string attributes with: + + Bool XNVCTRLQueryStringAttribute (Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr); + + This function returns True if the string attribute exists; + or it returns False if the string attribute does not exist. If + XNVCTRLQueryStringAttribute returns True, *ptr will point to an + allocated string containing the string attribute requested. It is + the caller's responsibility to free the string with XFree(). + + The arguments are: + + dpy - The connection to the X server. + screen - the X screen to query. + display_mask - if the attribute requires a display device, + then this indicates the display device to query; + this field is ignored if the attribute is not + display device specific. + attribute - the string attribute to query + ptr - the returned allocated string + + This function can cause the following X protocol errors: + + BadValue - The screen does not exist. + BadMatch - The NVIDIA driver is not present on that screen. + BadAlloc - Insufficient resources to fulfill the request. + + See NVCtrl.h (distributed in the src/libXNVCtrl/ directory of + the nvidia-settings source package) for a list of possible string + attributes. + + + +6. ASSIGNING ATTRIBUTE VALUES + + An integer attribute can be assigned a value with: + + void XNVCTRLSetAttribute (Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value); + + This function sets the attribute to the given value. This function + does not have a return value. Note that, because it does not + return a value, XNVCTRLSetAttribute() only queues the request in + the X command stream. The command will not actually be sent to + the server until an X command that flushes the X command stream + (such as XFlush(), or any API command that queries a value from the + server) is called. + + The arguments are: + + dpy - The connection to the X server. + screen - the X screen to query. + display_mask - if the attribute requires a display device, + then this indicates the display device to set; + this field is ignored if the attribute is not + display device specific. You can determine + if an attribute is display device specific by + querying the valid values and checking for the + ATTRIBUTE_TYPE_DISPLAY bit in the permissions + field. + attribute - the attribute to set. + value - the value the attribute should be set to. + + See NVCtrl.h (distributed in the src/libXNVCtrl/ directory of + the nvidia-settings source package) for a list of possible integer + attributes. + + This function can cause the following X protocol errors: + + BadMatch - The NVIDIA driver is not present on that screen. + BadValue - The screen does not exist, or an invalid value is + specified, or the attribute does not exist on the + specified X screen, or the attribute requires a + display device and display_mask does not uniquely + identify a display device. + + Before calling XNVCTRLSetAttribute(), an NV-CONTROL client should + use XNVCTRLQueryAttribute() or XNVCTRLQueryValidAttributeValues() + to determine if the attribute exists on the specified X screen; + if the attribute does not exist and XNVCTRLSetAttribute() + is called for that attribute, then a BadValue X protocol error will + be triggered. + + + +7. SELECTING EVENT NOTIFICATION + + NV-CONTROL clients can enable NV-CONTROL events with: + + Bool XNVCtrlSelectNotify (Display *dpy, + int screen, + int type, + Bool onoff); + + This function returns True if the extension exists, or False if the + extension does not exist. The arguments are: + + dpy - The connection to the X server. + screen - the X screen on which to enable events. + type - the type of event to enable; currently, the only NV-CONTROL + event type is ATTRIBUTE_CHANGED_EVENT. + onoff - whether to enable (True) or disable (False) receiving + this event type. + + This function can cause the following X protocol errors: + + BadValue - The screen does not exist. + BadMatch - The NVIDIA driver is not present on that screen. + + When an NV-CONTROL client changes an integer attribute value, all + other NV-CONTROL clients with ATTRIBUTE_CHANGED_EVENT notificaion + enabled will receive an XEvent where XEvent.type is equal to: + + event_base + ATTRIBUTE_CHANGED_EVENT + + where event_base is the event base returned by + XNVCTRLQueryExtension(). The XEvent can then be cast as an + XNVCtrlAttributeChangedEvent structure: + + typedef struct { + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int screen; + unsigned int display_mask; + unsigned int attribute; + int value; + } XNVCtrlAttributeChangedEvent; + + The screen, display_mask, attribute, and value fields correspond to + the arguments passed to XNVCTRLSetAttribute(). + + + +8. NV-CONTROL EXTENSION HISTORY + + 1.0 - 1.5 NVIDIA Internal development versions + 1.6 Initial public version + diff --git a/sys/linux/libXNVCtrl/NVCtrl.c b/sys/linux/libXNVCtrl/NVCtrl.c new file mode 100644 index 000000000..68b97f437 --- /dev/null +++ b/sys/linux/libXNVCtrl/NVCtrl.c @@ -0,0 +1,339 @@ +#define NEED_EVENTS +#define NEED_REPLIES +#include +#include +#include +#include "extutil.h" +#include "NVCtrlLib.h" +#include "nv_control.h" + +#if !defined(XTRHEADS) +#warning XTRHEADS not defined -- this libXNVCtrl.a will not be thread safe! +#endif + +static XExtensionInfo _nvctrl_ext_info_data; +static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; +static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME; + +#define XNVCTRLCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, nvctrl_extension_name, val) +#define XNVCTRLSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) + +static int close_display(); +static Bool wire_to_event(); +static /* const */ XExtensionHooks nvctrl_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, + nvctrl_extension_name, + &nvctrl_extension_hooks, + NV_CONTROL_EVENTS, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + if (event_basep) *event_basep = info->codes->first_event; + if (error_basep) *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryExtensionReply rep; + xnvCtrlQueryExtensionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryExtension, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryExtension; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (major) *major = rep.major; + if (minor) *minor = rep.minor; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlIsNvReply rep; + xnvCtrlIsNvReq *req; + Bool isnv; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlIsNv, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlIsNv; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + isnv = rep.isnv; + UnlockDisplay (dpy); + SyncHandle (); + return isnv; +} + + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetAttributeReq *req; + + XNVCTRLSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq (nvCtrlSetAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + req->value = value; + UnlockDisplay (dpy); + SyncHandle (); +} + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryAttributeReply rep; + xnvCtrlQueryAttributeReq *req; + Bool exists; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (value) *value = rep.value; + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryStringAttributeReply rep; + xnvCtrlQueryStringAttributeReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryStringAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + *ptr = (char *) Xmalloc(numbytes); + if (! *ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryValidAttributeValuesReply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + Bool exists; + + if (!values) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidAttributeValues; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + exists = rep.flags; + values->type = rep.attr_type; + if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { + values->u.range.min = rep.min; + values->u.range.max = rep.max; + } + if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { + values->u.bits.ints = rep.bits; + } + values->permissions = rep.perms; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSelectNotifyReq *req; + + if(!XextHasExtension (info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSelectNotify, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSelectNotify; + req->screen = screen; + req->notifyType = type; + req->onoff = onoff; + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + +static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = find_display (dpy); + XNVCtrlEvent *re = (XNVCtrlEvent *) host; + xnvctrlEvent *event = (xnvctrlEvent *) wire; + + XNVCTRLCheckExtension (dpy, info, False); + + switch ((event->u.u.type & 0x7F) - info->codes->first_event) { + case ATTRIBUTE_CHANGED_EVENT: + re->attribute_changed.type = event->u.u.type & 0x7F; + re->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) event); + re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0); + re->attribute_changed.display = dpy; + re->attribute_changed.time = event->u.attribute_changed.time; + re->attribute_changed.screen = event->u.attribute_changed.screen; + re->attribute_changed.display_mask = + event->u.attribute_changed.display_mask; + re->attribute_changed.attribute = event->u.attribute_changed.attribute; + re->attribute_changed.value = event->u.attribute_changed.value; + break; + default: + return False; + } + + return True; +} + diff --git a/sys/linux/libXNVCtrl/NVCtrl.h b/sys/linux/libXNVCtrl/NVCtrl.h new file mode 100644 index 000000000..eb2dce45f --- /dev/null +++ b/sys/linux/libXNVCtrl/NVCtrl.h @@ -0,0 +1,786 @@ +#ifndef __NVCTRL_H +#define __NVCTRL_H + +/**************************************************************************/ +/* + * Integer attributes; these are settable/gettable via + * XNVCTRLSetAttribute() and XNVCTRLQueryAttribute, respectively. + * Some attributes may only be read; some may require a display_mask + * argument. This information is encoded in the "permission" comment + * after each attribute #define, and can be queried at run time with + * XNVCTRLQueryValidAttributeValues(). + * + * Key to Integer Attribute "Permissions": + * + * R: The attribute is readable (in general, all attributes will be + * readable) + * + * W: The attribute is writable (attributes may not be writable for + * various reasons: they represent static system information, they + * can only be changed by changing an XF86Config option, etc). + * + * D: The attribute requires the display mask argument. The + * attributes NV_CTRL_CONNECTED_DISPLAYS and NV_CTRL_ENABLED_DISPLAYS + * will be a bitmask of what display devices are connected and what + * display devices are enabled for use in X, respectively. Each bit + * in the bitmask represents a display device; it is these bits which + * should be used as the display_mask when dealing with attributes + * designated with "D" below. For attributes that do not require the + * display mask, the argument is ignored. + */ + + +/**************************************************************************/ + + +/* + * NV_CTRL_FLATPANEL_SCALING - the current flatpanel scaling state; + * possible values are: + * + * 0: default (the driver will use whatever state is current) + * 1: native (the driver will use the panel's scaler, if possible) + * 2: scaled (the driver will use the GPU's scaler, if possible) + * 3: centered (the driver will center the image) + * 4: aspect scaled (scale with the GPU's scaler, but keep the aspect + * ratio correct) + */ + +#define NV_CTRL_FLATPANEL_SCALING 2 /* RWD */ +#define NV_CTRL_FLATPANEL_SCALING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_SCALING_NATIVE 1 +#define NV_CTRL_FLATPANEL_SCALING_SCALED 2 +#define NV_CTRL_FLATPANEL_SCALING_CENTERED 3 +#define NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED 4 + + +/* + * NV_CTRL_FLATPANEL_DITHERING - the current flatpanel dithering + * state; possible values are: + * + * 0: default (the driver will decide when to dither) + * 1: enabled (the driver will always dither when possible) + * 2: disabled (the driver will never dither) + */ + +#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWD */ +#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1 +#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2 + + +/* + * NV_CTRL_DIGITAL_VIBRANCE - sets the digital vibrance level for the + * specified display device. + */ + +#define NV_CTRL_DIGITAL_VIBRANCE 4 /* RWD */ + + +/* + * NV_CTRL_BUS_TYPE - returns the Bus type through which the GPU + * driving the specified X screen is connected to the computer. + */ + +#define NV_CTRL_BUS_TYPE 5 /* R-- */ +#define NV_CTRL_BUS_TYPE_AGP 0 +#define NV_CTRL_BUS_TYPE_PCI 1 +#define NV_CTRL_BUS_TYPE_PCI_EXPRESS 2 + + +/* + * NV_CTRL_VIDEO_RAM - returns the amount of video ram on the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_VIDEO_RAM 6 /* R-- */ + + +/* + * NV_CTRL_IRQ - returns the interrupt request line used by the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_IRQ 7 /* R-- */ + + +/* + * NV_CTRL_OPERATING_SYSTEM - returns the operating system on which + * the X server is running. + */ + +#define NV_CTRL_OPERATING_SYSTEM 8 /* R-- */ +#define NV_CTRL_OPERATING_SYSTEM_LINUX 0 +#define NV_CTRL_OPERATING_SYSTEM_FREEBSD 1 + + +/* + * NV_CTRL_SYNC_TO_VBLANK - enables sync to vblank for OpenGL clients. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_SYNC_TO_VBLANK 9 /* RW- */ +#define NV_CTRL_SYNC_TO_VBLANK_OFF 0 +#define NV_CTRL_SYNC_TO_VBLANK_ON 1 + + +/* + * NV_CTRL_LOG_ANISO - enables anisotropic filtering for OpenGL + * clients; on some NVIDIA hardware, this can only be enabled or + * disabled; on other hardware different levels of anisotropic + * filtering can be specified. This setting is only applied to OpenGL + * clients that are started after this setting is applied. + */ + +#define NV_CTRL_LOG_ANISO 10 /* RW- */ + + +/* + * NV_CTRL_FSAA_MODE - the FSAA setting for OpenGL clients; possible + * FSAA modes: + * + * NV_CTRL_FSAA_MODE_2x "2x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_2x_5t "2x Quincunx Multisampling" + * NV_CTRL_FSAA_MODE_15x15 "1.5 x 1.5 Supersampling" + * NV_CTRL_FSAA_MODE_2x2 "2 x 2 Supersampling" + * NV_CTRL_FSAA_MODE_4x "4x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_4x_9t "4x Gaussian Multisampling" + * NV_CTRL_FSAA_MODE_8x "2x Bilinear Multisampling by 4x Supersampling" + * NV_CTRL_FSAA_MODE_16x "4x Bilinear Multisampling by 4x Supersampling" + * + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FSAA_MODE 11 /* RW- */ +#define NV_CTRL_FSAA_MODE_NONE 0 +#define NV_CTRL_FSAA_MODE_2x 1 +#define NV_CTRL_FSAA_MODE_2x_5t 2 +#define NV_CTRL_FSAA_MODE_15x15 3 +#define NV_CTRL_FSAA_MODE_2x2 4 +#define NV_CTRL_FSAA_MODE_4x 5 +#define NV_CTRL_FSAA_MODE_4x_9t 6 +#define NV_CTRL_FSAA_MODE_8x 7 +#define NV_CTRL_FSAA_MODE_16x 8 + + +/* + * NV_CTRL_TEXTURE_SHARPEN - enables texture sharpening for OpenGL + * clients. This setting is only applied to OpenGL clients that are + * started after this setting is applied. + */ + +#define NV_CTRL_TEXTURE_SHARPEN 12 /* RW- */ +#define NV_CTRL_TEXTURE_SHARPEN_OFF 0 +#define NV_CTRL_TEXTURE_SHARPEN_ON 1 + + +/* + * NV_CTRL_UBB - returns whether UBB is enabled for the specified X + * screen. + */ + +#define NV_CTRL_UBB 13 /* R-- */ +#define NV_CTRL_UBB_OFF 0 +#define NV_CTRL_UBB_ON 1 + + +/* + * NV_CTRL_OVERLAY - returns whether the RGB overlay is enabled for + * the specified X screen. + */ + +#define NV_CTRL_OVERLAY 14 /* R-- */ +#define NV_CTRL_OVERLAY_OFF 0 +#define NV_CTRL_OVERLAY_ON 1 + + +/* + * NV_CTRL_STEREO - returns whether stereo (and what type) is enabled + * for the specified X screen. + */ + +#define NV_CTRL_STEREO 16 /* R-- */ +#define NV_CTRL_STEREO_OFF 0 +#define NV_CTRL_STEREO_DDC 1 +#define NV_CTRL_STEREO_BLUELINE 2 +#define NV_CTRL_STEREO_DIN 3 +#define NV_CTRL_STEREO_TWINVIEW 4 + + +/* + * NV_CTRL_EMULATE - controls OpenGL software emulation of future + * NVIDIA GPUs. + */ + +#define NV_CTRL_EMULATE 17 /* RW- */ +#define NV_CTRL_EMULATE_NONE 0 + + +/* + * NV_CTRL_TWINVIEW - returns whether TwinView is enabled for the + * specified X screen. + */ + +#define NV_CTRL_TWINVIEW 18 /* R-- */ +#define NV_CTRL_TWINVIEW_NOT_ENABLED 0 +#define NV_CTRL_TWINVIEW_ENABLED 1 + + +/* + * NV_CTRL_CONNECTED_DISPLAYS - returns a display mask indicating what + * display devices are connected to the GPU driving the specified X + * screen. + */ + +#define NV_CTRL_CONNECTED_DISPLAYS 19 /* R-- */ + + +/* + * NV_CTRL_ENABLED_DISPLAYS - returns a display mask indicating what + * display devices are enabled for use on the specified X screen. + */ + +#define NV_CTRL_ENABLED_DISPLAYS 20 /* R-- */ + +/**************************************************************************/ +/* + * Integer attributes specific to configuring FrameLock on boards that + * support it. + */ + + +/* + * NV_CTRL_FRAMELOCK - returns whether this X screen supports + * FrameLock. All of the other FrameLock attributes are only + * applicable if NV_CTRL_FRAMELOCK is _SUPPORTED. + */ + +#define NV_CTRL_FRAMELOCK 21 /* R-- */ +#define NV_CTRL_FRAMELOCK_NOT_SUPPORTED 0 +#define NV_CTRL_FRAMELOCK_SUPPORTED 1 + + +/* + * NV_CTRL_FRAMELOCK_MASTER - get/set whether this X screen is the + * FrameLock master for the entire sync group. Note that only one + * node in the sync group should be configured as the master. + */ + +#define NV_CTRL_FRAMELOCK_MASTER 22 /* RW- */ +#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 +#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_POLARITY - sync either to the rising edge of the + * framelock pulse, or both the rising and falling edges of the + * framelock pulse. + */ + +#define NV_CTRL_FRAMELOCK_POLARITY 23 /* RW- */ +#define NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE 0x1 +#define NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES 0x3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_DELAY - delay between the framelock pulse + * and the GPU sync. This is an 11 bit value which is multipled by + * 7.81 to determine the sync delay in microseconds. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_DELAY 24 /* RW- */ +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 + +/* + * NV_CTRL_FRAMELOCK_SYNC_INTERVAL - how many house sync pulses + * between the FrameLock sync generation (0 == sync every house sync); + * this only applies to the master when receiving house sync. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_INTERVAL 25 /* RW- */ + + +/* + * NV_CTRL_FRAMELOCK_PORT0_STATUS - status of the rj45 port0. + */ + +#define NV_CTRL_FRAMELOCK_PORT0_STATUS 26 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_PORT1_STATUS - status of the rj45 port1. + */ + +#define NV_CTRL_FRAMELOCK_PORT1_STATUS 27 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_HOUSE_STATUS - status of the house input (the BNC + * connector). + */ + +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS 28 /* R-- */ +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_NOT_DETECTED 0 +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_DETECTED 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC - enable/disable the syncing of the + * specified display devices to the FrameLock pulse. + */ + +#define NV_CTRL_FRAMELOCK_SYNC 29 /* RWD */ +#define NV_CTRL_FRAMELOCK_SYNC_DISABLE 0 +#define NV_CTRL_FRAMELOCK_SYNC_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_READY - reports whether a slave FrameLock + * board is receiving sync (regardless of whether or not any display + * devices are using the sync). + */ + +#define NV_CTRL_FRAMELOCK_SYNC_READY 30 /* R-- */ +#define NV_CTRL_FRAMELOCK_SYNC_READY_FALSE 0 +#define NV_CTRL_FRAMELOCK_SYNC_READY_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_STEREO_SYNC - this indicates that the GPU stereo + * signal is in sync with the framelock stereo signal. + */ + +#define NV_CTRL_FRAMELOCK_STEREO_SYNC 31 /* R-- */ +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_FALSE 0 +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_TEST_SIGNAL - to test the connections in the sync + * group, tell the master to enable a test signal, then query port[01] + * status and sync_ready on all slaves. When done, tell the master to + * disable the test signal. Test signal should only be manipulated + * while NV_CTRL_FRAMELOCK_SYNC is enabled. + * + * The TEST_SIGNAL is also used to reset the Universal Frame Count (as + * returned by the glXQueryFrameCountNV() function in the + * GLX_NV_swap_group extension). Note: for best accuracy of the + * Universal Frame Count, it is recommended to toggle the TEST_SIGNAL + * on and off after enabling FrameLock. + */ + +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL 32 /* RW- */ +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE 0 +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED - The FrameLock boards are + * cabled together using regular cat5 cable, connecting to rj45 ports + * on the backplane of the card. There is some concern that users may + * think these are ethernet ports and connect them to a + * router/hub/etc. The hardware can detect this and will shut off to + * prevent damage (either to itself or to the router). + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED may be called to find out if + * ethernet is connected to one of the rj45 ports. An appropriate + * error message should then be displayed. The _PORT0 and PORT1 + * values may be or'ed together. + */ + +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED 33 /* R-- */ +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_NONE 0 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT0 0x1 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT1 0x2 + + +/* + * NV_CTRL_FRAMELOCK_VIDEO_MODE - get/set the video mode of the house + * input. + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE 34 /* RW- */ +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NTSCPALSECAM 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV 3 + +/* + * During FRAMELOCK bring-up, the above values were redefined to + * these: + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL 3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_RATE - this is the refresh rate that the + * framelock board is sending to the GPU, in milliHz. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_RATE 35 /* R-- */ + + + +/**************************************************************************/ + +/* + * NV_CTRL_FORCE_GENERIC_CPU - inhibit the use of CPU specific + * features such as MMX, SSE, or 3DNOW! for OpenGL clients; this + * option may result in performance loss, but may be useful in + * conjunction with software such as the Valgrind memory debugger. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FORCE_GENERIC_CPU 37 /* RW- */ +#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0 +#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1 + + +/* + * NV_CTRL_OPENGL_AA_LINE_GAMMA - for OpenGL clients, allow + * Gamma-corrected antialiased lines to consider variances in the + * color display capabilities of output devices when rendering smooth + * lines. Only available on recent Quadro GPUs. This setting is only + * applied to OpenGL clients that are started after this setting is + * applied. + */ + +#define NV_CTRL_OPENGL_AA_LINE_GAMMA 38 /* RW- */ +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_DISABLE 0 +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_TIMING - this is TRUE when the framelock board is + * receiving timing input. + */ + +#define NV_CTRL_FRAMELOCK_TIMING 39 /* RW- */ +#define NV_CTRL_FRAMELOCK_TIMING_FALSE 0 +#define NV_CTRL_FRAMELOCK_TIMING_TRUE 1 + +/* + * NV_CTRL_FLIPPING_ALLOWED - when TRUE, OpenGL will swap by flipping + * when possible; when FALSE, OpenGL will alway swap by blitting. XXX + * can this be enabled dynamically? + */ + +#define NV_CTRL_FLIPPING_ALLOWED 40 /* RW- */ +#define NV_CTRL_FLIPPING_ALLOWED_FALSE 0 +#define NV_CTRL_FLIPPING_ALLOWED_TRUE 1 + +/* + * NV_CTRL_ARCHITECTURE - returns the architecture on which the X server is + * running. + */ + +#define NV_CTRL_ARCHITECTURE 41 /* R-- */ +#define NV_CTRL_ARCHITECTURE_X86 0 +#define NV_CTRL_ARCHITECTURE_X86_64 1 +#define NV_CTRL_ARCHITECTURE_IA64 2 + + +/* + * NV_CTRL_TEXTURE_CLAMPING - texture clamping mode in OpenGL. By + * default, NVIDIA's OpenGL implementation uses CLAMP_TO_EDGE, which + * is not strictly conformant, but some applications rely on the + * non-conformant behavior, and not all GPUs support conformant + * texture clamping in hardware. _SPEC forces OpenGL texture clamping + * to be conformant, but may introduce slower performance on older + * GPUS, or incorrect texture clamping in certain applications. + */ + +#define NV_CTRL_TEXTURE_CLAMPING 42 /* RW- */ +#define NV_CTRL_TEXTURE_CLAMPING_EDGE 0 +#define NV_CTRL_TEXTURE_CLAMPING_SPEC 1 + + + +#define NV_CTRL_CURSOR_SHADOW 43 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_DISABLE 0 +#define NV_CTRL_CURSOR_SHADOW_ENABLE 1 + +#define NV_CTRL_CURSOR_SHADOW_ALPHA 44 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_RED 45 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_GREEN 46 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_BLUE 47 /* RW- */ + +#define NV_CTRL_CURSOR_SHADOW_X_OFFSET 48 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_Y_OFFSET 49 /* RW- */ + + + +/* + * When Application Control for FSAA is enabled, then what the + * application requests is used, and NV_CTRL_FSAA_MODE is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_FSAA_MODE + */ + +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED 50 /* RW- */ +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * When Application Control for LogAniso is enabled, then what the + * application requests is used, and NV_CTRL_LOG_ANISO is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_LOG_ANISO + */ + +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED 51 /* RW- */ +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * IMAGE_SHARPENING adjusts the sharpness of the display's image + * quality by amplifying high frequency content. Valid values will + * normally be in the range [0,32). Only available on GeForceFX or + * newer. + */ + +#define NV_CTRL_IMAGE_SHARPENING 52 /* RWD */ + + +/* + * NV_CTRL_TV_OVERSCAN adjusts the amount of overscan on the specified + * display device. + */ + +#define NV_CTRL_TV_OVERSCAN 53 /* RWD */ + + +/* + * NV_CTRL_TV_FLICKER_FILTER adjusts the amount of flicker filter on + * the specified display device. + */ + +#define NV_CTRL_TV_FLICKER_FILTER 54 /* RWD */ + + +/* + * NV_CTRL_TV_BRIGHTNESS adjusts the amount of brightness on the + * specified display device. + */ + +#define NV_CTRL_TV_BRIGHTNESS 55 /* RWD */ + + +/* + * NV_CTRL_TV_HUE adjusts the amount of hue on the specified display + * device. + */ + +#define NV_CTRL_TV_HUE 56 /* RWD */ + + +/* + * NV_CTRL_TV_CONTRAST adjusts the amount of contrast on the specified + * display device. + */ + +#define NV_CTRL_TV_CONTRAST 57 /* RWD */ + + +/* + * NV_CTRL_TV_SATURATION adjusts the amount of saturation on the + * specified display device. + */ + +#define NV_CTRL_TV_SATURATION 58 /* RWD */ + + +/* + * NV_CTRL_TV_RESET_SETTINGS - this write-only attribute can be used + * to request that all TV Settings be reset to their default values; + * typical usage would be that this attribute be sent, and then all + * the TV attributes be queried to retrieve their new values. + */ + +#define NV_CTRL_TV_RESET_SETTINGS 59 /* -WD */ + + +/* + * NV_CTRL_GPU_CORE_TEMPERATURE reports the current core temperature + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_CORE_TEMPERATURE 60 /* R-- */ + + +/* + * NV_CTRL_GPU_CORE_THRESHOLD reports the current GPU core slowdown + * threshold temperature, NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD and + * NV_CTRL_GPU_MAX_CORE_THRESHOLD report the default and MAX core + * slowdown threshold temperatures. + * + * NV_CTRL_GPU_CORE_THRESHOLD reflects the temperature at which the + * GPU is throttled to prevent overheating. + */ + +#define NV_CTRL_GPU_CORE_THRESHOLD 61 /* R-- */ +#define NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD 62 /* R-- */ +#define NV_CTRL_GPU_MAX_CORE_THRESHOLD 63 /* R-- */ + + +/* + * NV_CTRL_AMBIENT_TEMPERATURE reports the current temperature in the + * immediate neighbourhood of the GPU driving the X screen. + */ + +#define NV_CTRL_AMBIENT_TEMPERATURE 64 /* R-- */ + + +/* + * NV_CTRL_PBUFFER_SCANOUT_SUPPORTED - returns whether this X screen + * supports scanout of FP pbuffers; + * + * if this screen does not support PBUFFER_SCANOUT, then all other + * PBUFFER_SCANOUT attributes are unavailable. + */ + +#define NV_CTRL_PBUFFER_SCANOUT_SUPPORTED 65 /* R-- */ +#define NV_CTRL_PBUFFER_SCANOUT_FALSE 0 +#define NV_CTRL_PBUFFER_SCANOUT_TRUE 1 + +/* + * NV_CTRL_PBUFFER_SCANOUT_XID indicates the XID of the pbuffer used for + * scanout. + */ +#define NV_CTRL_PBUFFER_SCANOUT_XID 66 /* RW- */ + +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_PBUFFER_SCANOUT_XID + +/**************************************************************************/ + +/* + * String Attributes: + */ + + +/* + * NV_CTRL_STRING_PRODUCT_NAME - the GPU product name on which the + * specified X screen is running. + */ + +#define NV_CTRL_STRING_PRODUCT_NAME 0 /* R-- */ + + +/* + * NV_CTRL_STRING_VBIOS_VERSION - the video bios version on the GPU on + * which the specified X screen is running. + */ + +#define NV_CTRL_STRING_VBIOS_VERSION 1 /* R-- */ + + +/* + * NV_CTRL_STRING_NVIDIA_DRIVER_VERSION - string representation of the + * NVIDIA driver version number for the NVIDIA X driver in use. + */ + +#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R-- */ + + +/* + * NV_CTRL_STRING_DISPLAY_DEVICE_NAME - name of the display device + * specified in the display_mask argument. + */ + +#define NV_CTRL_STRING_DISPLAY_DEVICE_NAME 4 /* R-D */ + + +/* + * NV_CTRL_STRING_TV_ENCODER_NAME - name of the TV encoder used by the + * specified display device; only valid if the display device is a TV. + */ + +#define NV_CTRL_STRING_TV_ENCODER_NAME 5 /* R-D */ + +#define NV_CTRL_STRING_LAST_ATTRIBUTE NV_CTRL_STRING_TV_ENCODER_NAME + + + +/**************************************************************************/ +/* + * CTRLAttributeValidValuesRec - + * + * structure and related defines used by + * XNVCTRLQueryValidAttributeValues() to describe the valid values of + * a particular attribute. The type field will be one of: + * + * ATTRIBUTE_TYPE_INTEGER : the attribute is an integer value; there + * is no fixed range of valid values. + * + * ATTRIBUTE_TYPE_BITMASK : the attribute is an integer value, + * interpretted as a bitmask. + * + * ATTRIBUTE_TYPE_BOOL : the attribute is a boolean, valid values are + * either 1 (on/true) or 0 (off/false). + * + * ATTRIBUTE_TYPE_RANGE : the attribute can have any integer value + * between NVCTRLAttributeValidValues.u.range.min and + * NVCTRLAttributeValidValues.u.range.max (inclusive). + * + * ATTRIBUTE_TYPE_INT_BITS : the attribute can only have certain + * integer values, indicated by which bits in + * NVCTRLAttributeValidValues.u.bits.ints are on (for example: if bit + * 0 is on, then 0 is a valid value; if bit 5 is on, then 5 is a valid + * value, etc). This is useful for attributes like NV_CTRL_FSAA_MODE, + * which can only have certain values, depending on GPU. + * + * + * The permissions field of NVCTRLAttributeValidValuesRec is a bitmask + * that may contain: + * + * ATTRIBUTE_TYPE_READ + * ATTRIBUTE_TYPE_WRITE + * ATTRIBUTE_TYPE_DISPLAY + * + * See 'Key to Integer Attribute "Permissions"' at the top of this + * file for a description of what these three permission bits mean. + */ + +#define ATTRIBUTE_TYPE_UNKNOWN 0 +#define ATTRIBUTE_TYPE_INTEGER 1 +#define ATTRIBUTE_TYPE_BITMASK 2 +#define ATTRIBUTE_TYPE_BOOL 3 +#define ATTRIBUTE_TYPE_RANGE 4 +#define ATTRIBUTE_TYPE_INT_BITS 5 + +#define ATTRIBUTE_TYPE_READ 0x1 +#define ATTRIBUTE_TYPE_WRITE 0x2 +#define ATTRIBUTE_TYPE_DISPLAY 0x4 + +typedef struct _NVCTRLAttributeValidValues { + int type; + union { + struct { + int min; + int max; + } range; + struct { + unsigned int ints; + } bits; + } u; + unsigned int permissions; +} NVCTRLAttributeValidValuesRec; + + + +#define ATTRIBUTE_CHANGED_EVENT 0 + + +#endif /* __NVCTRL_H */ diff --git a/sys/linux/libXNVCtrl/NVCtrlLib.h b/sys/linux/libXNVCtrl/NVCtrlLib.h new file mode 100644 index 000000000..ee8810f03 --- /dev/null +++ b/sys/linux/libXNVCtrl/NVCtrlLib.h @@ -0,0 +1,177 @@ +#ifndef __NVCTRLLIB_H +#define __NVCTRLLIB_H + +#include "NVCtrl.h" + +/* + * XNVCTRLQueryExtension - + * + * Returns True if the extension exists, returns False otherwise. + * event_basep and error_basep are the extension event and error + * bases. Currently, no extension specific errors or events are + * defined. + */ + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +); + +/* + * XNVCTRLQueryVersion - + * + * Returns True if the extension exists, returns False otherwise. + * major and minor are the extension's major and minor version + * numbers. + */ + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +); + + +/* + * XNVCTRLIsNvScreen + * + * Returns True is the specified screen is controlled by the NVIDIA + * driver. Returns False otherwise. + */ + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +); + +/* + * XNVCTRLSetAttribute - + * + * Sets the attribute to the given value. The attributes and their + * possible values are listed in NVCtrl.h. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen or attribute doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +); + +/* + * XNVCTRLQueryAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +); + +/* + * XNVCTRLQueryStringAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryStringAttribute returns True, *ptr will point to an + * allocated string containing the string attribute requested. It is + * the caller's responsibility to free the string when done. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +); + +/* + * XNVCTRLQueryValidAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidAttributeValues returns True, values will indicate + * the valid values for the specified attribute; see the description + * of NVCTRLAttributeValidValues in NVCtrl.h. + */ + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +); + +/* + * XNVCtrlSelectNotify - + * + * This enables/disables receiving of NV-CONTROL events. The type + * specifies the type of event to enable (currently, the only type is + * ATTRIBUTE_CHANGED_EVENT); onoff controls whether receiving this + * type of event should be enabled (True) or disabled (False). + * + * Returns True if successful, or False if the screen is not + * controlled by the NVIDIA driver. + */ + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +); + + + +/* + * XNVCtrlEvent structure + */ + +typedef struct { + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int screen; + unsigned int display_mask; + unsigned int attribute; + int value; +} XNVCtrlAttributeChangedEvent; + +typedef union { + int type; + XNVCtrlAttributeChangedEvent attribute_changed; + long pad[24]; +} XNVCtrlEvent; + + +#endif /* __NVCTRLLIB_H */ diff --git a/sys/linux/libXNVCtrl/extutil.h b/sys/linux/libXNVCtrl/extutil.h new file mode 100644 index 000000000..cb3592770 --- /dev/null +++ b/sys/linux/libXNVCtrl/extutil.h @@ -0,0 +1,224 @@ +/* + * $Xorg: extutil.h,v 1.4 2001/02/09 02:03:24 xorgcvs Exp $ + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the 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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT The Open Group + * + * Xlib Extension-Writing Utilities + * + * This package contains utilities for writing the client API for various + * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND + * ARE SUBJECT TO CHANGE! + */ +/* $XFree86: xc/include/extensions/extutil.h,v 1.9 2001/12/14 19:53:28 dawes Exp $ */ + +#ifndef _EXTUTIL_H_ +#define _EXTUTIL_H_ + +#include + +/* + * We need to keep a list of open displays since the Xlib display list isn't + * public. We also have to per-display info in a separate block since it isn't + * stored directly in the Display structure. + */ +typedef struct _XExtDisplayInfo { + struct _XExtDisplayInfo *next; /* keep a linked list */ + Display *display; /* which display this is */ + XExtCodes *codes; /* the extension protocol codes */ + XPointer data; /* extra data for extension to use */ +} XExtDisplayInfo; + +typedef struct _XExtensionInfo { + XExtDisplayInfo *head; /* start of list */ + XExtDisplayInfo *cur; /* most recently used */ + int ndisplays; /* number of displays */ +} XExtensionInfo; + +typedef struct _XExtensionHooks { + int (*create_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*copy_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*flush_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*free_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*create_font)( +#if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + int (*free_font)( +#if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + int (*close_display)( +#if NeedNestedPrototypes + Display* /* display */, + XExtCodes* /* codes */ +#endif +); + Bool (*wire_to_event)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + Status (*event_to_wire)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + int (*error)( +#if NeedNestedPrototypes + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ +#endif +); + char *(*error_string)( +#if NeedNestedPrototypes + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ +#endif +); +} XExtensionHooks; + +extern XExtensionInfo *XextCreateExtension( +#if NeedFunctionPrototypes + void +#endif +); +extern void XextDestroyExtension( +#if NeedFunctionPrototypes + XExtensionInfo* /* info */ +#endif +); +extern XExtDisplayInfo *XextAddDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */, + char* /* ext_name */, + XExtensionHooks* /* hooks */, + int /* nevents */, + XPointer /* data */ +#endif +); +extern int XextRemoveDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */ +#endif +); +extern XExtDisplayInfo *XextFindDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */ +#endif +); + +#define XextHasExtension(i) ((i) && ((i)->codes)) +#define XextCheckExtension(dpy,i,name,val) \ + if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; } +#define XextSimpleCheckExtension(dpy,i,name) \ + if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; } + + +/* + * helper macros to generate code that is common to all extensions; caller + * should prefix it with static if extension source is in one file; this + * could be a utility function, but have to stack 6 unused arguments for + * something that is called many, many times would be bad. + */ +#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \ +XExtDisplayInfo *proc (Display *dpy) \ +{ \ + XExtDisplayInfo *dpyinfo; \ + if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \ + if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \ + dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \ + return dpyinfo; \ +} + +#define XEXT_FIND_DISPLAY_PROTO(proc) \ + XExtDisplayInfo *proc(Display *dpy) + +#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \ +int proc (Display *dpy, XExtCodes *codes) \ +{ \ + return XextRemoveDisplay (extinfo, dpy); \ +} + +#define XEXT_CLOSE_DISPLAY_PROTO(proc) \ + int proc(Display *dpy, XExtCodes *codes) + +#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \ +char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \ +{ \ + code -= codes->first_error; \ + if (code >= 0 && code < nerr) { \ + char tmp[256]; \ + sprintf (tmp, "%s.%d", extname, code); \ + XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \ + return buf; \ + } \ + return (char *)0; \ +} + +#define XEXT_ERROR_STRING_PROTO(proc) \ + char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n) +#endif diff --git a/sys/linux/libXNVCtrl/nv_control.h b/sys/linux/libXNVCtrl/nv_control.h new file mode 100644 index 000000000..fcd26cfb7 --- /dev/null +++ b/sys/linux/libXNVCtrl/nv_control.h @@ -0,0 +1,184 @@ +#ifndef __NVCONTROL_H +#define __NVCONTROL_H + +#define NV_CONTROL_ERRORS 0 +#define NV_CONTROL_EVENTS 1 +#define NV_CONTROL_NAME "NV-CONTROL" + +#define NV_CONTROL_MAJOR 1 +#define NV_CONTROL_MINOR 6 + +#define X_nvCtrlQueryExtension 0 +#define X_nvCtrlIsNv 1 +#define X_nvCtrlQueryAttribute 2 +#define X_nvCtrlSetAttribute 3 +#define X_nvCtrlQueryStringAttribute 4 +#define X_nvCtrlQueryValidAttributeValues 5 +#define X_nvCtrlSelectNotify 6 +#define X_nvCtrlLastRequest (X_nvCtrlSelectNotify + 1) + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; +} xnvCtrlQueryExtensionReq; +#define sz_xnvCtrlQueryExtensionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 major B16; + CARD16 minor B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryExtensionReply; +#define sz_xnvCtrlQueryExtensionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlIsNvReq; +#define sz_xnvCtrlIsNvReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isnv B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlIsNvReply; +#define sz_xnvCtrlIsNvReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryAttributeReq; +#define sz_xnvCtrlQueryAttributeReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 value B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryAttributeReply; +#define sz_xnvCtrlQueryAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + INT32 value B32; +} xnvCtrlSetAttributeReq; +#define sz_xnvCtrlSetAttributeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryStringAttributeReq; +#define sz_xnvCtrlQueryStringAttributeReq 16 + +/* + * CtrlQueryStringAttribute reply struct + * n indicates the length of the string. + */ +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryStringAttributeReply; +#define sz_xnvCtrlQueryStringAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryValidAttributeValuesReq; +#define sz_xnvCtrlQueryValidAttributeValuesReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + INT32 min B32; + INT32 max B32; + CARD32 bits B32; + CARD32 perms B32; +} xnvCtrlQueryValidAttributeValuesReply; +#define sz_xnvCtrlQueryValidAttributeValuesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 notifyType B16; + CARD16 onoff B16; +} xnvCtrlSelectNotifyReq; +#define sz_xnvCtrlSelectNotifyReq 12 + +typedef struct { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + Time time B32; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + } attribute_changed; + } u; +} xnvctrlEvent; + + +#endif /* __NVCONTROL_H */ diff --git a/sys/linux/local.h b/sys/linux/local.h new file mode 100644 index 000000000..c82fed01d --- /dev/null +++ b/sys/linux/local.h @@ -0,0 +1,54 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __LINUX_LOCAL_H__ +#define __LINUX_LOCAL_H__ + +extern glconfig_t glConfig; + +// glimp.cpp + +//#define ID_ENABLE_DGA + +#if defined( ID_ENABLE_DGA ) +#include +#endif +#include +#include + +extern Display *dpy; +extern Window win; + +// input.cpp +extern bool dga_found; +void Sys_XEvents(); +void Sys_XUninstallGrabs(); + +#define KEY_MASK (KeyPressMask | KeyReleaseMask) +#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask ) +#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask ) + +#ifndef ID_GL_HARDLINK +bool GLimp_dlopen(); +void GLimp_dlclose(); + +void GLimp_BindLogging(); +void GLimp_BindNative(); +#endif + +#endif diff --git a/sys/linux/main.cpp b/sys/linux/main.cpp new file mode 100644 index 000000000..0a5f34a48 --- /dev/null +++ b/sys/linux/main.cpp @@ -0,0 +1,556 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../posix/posix_public.h" +#include "../sys_local.h" +#include "local.h" + +#include +#include +#include +#include +#include +#include + +#ifdef ID_MCHECK +#include +#endif + +static idStr basepath; +static idStr savepath; + +/* +=========== +Sys_InitScanTable +=========== +*/ +void Sys_InitScanTable( void ) { + common->DPrintf( "TODO: Sys_InitScanTable\n" ); +} + +/* +================= +Sys_AsyncThread +================= +*/ +void Sys_AsyncThread( void ) { + int now; + int next; + int want_sleep; + + // multi tick compensate for poor schedulers (Linux 2.4) + int ticked, to_ticked; + now = Sys_Milliseconds(); + ticked = now >> 4; + while (1) { + // sleep + now = Sys_Milliseconds(); + next = ( now & 0xFFFFFFF0 ) + 0x10; + want_sleep = ( next-now-1 ) * 1000; + if ( want_sleep > 0 ) { + usleep( want_sleep ); // sleep 1ms less than true target + } + + // compensate if we slept too long + now = Sys_Milliseconds(); + to_ticked = now >> 4; + + // show ticking statistics - every 100 ticks, print a summary + #if 0 + #define STAT_BUF 100 + static int stats[STAT_BUF]; + static int counter = 0; + // how many ticks to play + stats[counter] = to_ticked - ticked; + counter++; + if (counter == STAT_BUF) { + Sys_DebugPrintf("\n"); + for( int i = 0; i < STAT_BUF; i++) { + if ( ! (i & 0xf) ) { + Sys_DebugPrintf("\n"); + } + Sys_DebugPrintf( "%d ", stats[i] ); + } + Sys_DebugPrintf("\n"); + counter = 0; + } + #endif + + while ( ticked < to_ticked ) { + common->Async(); + ticked++; + Sys_TriggerEvent( TRIGGER_EVENT_ONE ); + } + // thread exit + pthread_testcancel(); + } +} + +/* + ============== + Sys_DefaultSavePath + ============== + */ +const char *Sys_DefaultSavePath(void) { +#if defined( ID_DEMO_BUILD ) + sprintf( savepath, "%s/.doom3-demo", getenv( "HOME" ) ); +#else + sprintf( savepath, "%s/.doom3", getenv( "HOME" ) ); +#endif + return savepath.c_str(); +} +/* +============== +Sys_EXEPath +============== +*/ +const char *Sys_EXEPath( void ) { + static char buf[ 1024 ]; + idStr linkpath; + int len; + + buf[ 0 ] = '\0'; + sprintf( linkpath, "/proc/%d/exe", getpid() ); + len = readlink( linkpath.c_str(), buf, sizeof( buf ) ); + if ( len == -1 ) { + Sys_Printf("couldn't stat exe path link %s\n", linkpath.c_str()); + buf[ len ] = '\0'; + } + return buf; +} + +/* +================ +Sys_DefaultBasePath + +Get the default base path +- binary image path +- current directory +- hardcoded +Try to be intelligent: if there is no BASE_GAMEDIR, try the next path +================ +*/ +const char *Sys_DefaultBasePath(void) { + struct stat st; + idStr testbase; + basepath = Sys_EXEPath(); + if ( basepath.Length() ) { + basepath.StripFilename(); + testbase = basepath; testbase += "/"; testbase += BASE_GAMEDIR; + if ( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) ) { + return basepath.c_str(); + } else { + common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() ); + } + } + if ( basepath != Posix_Cwd() ) { + basepath = Posix_Cwd(); + testbase = basepath; testbase += "/"; testbase += BASE_GAMEDIR; + if ( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) ) { + return basepath.c_str(); + } else { + common->Printf("no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, basepath.c_str()); + } + } + common->Printf( "WARNING: using hardcoded default base path\n" ); + return LINUX_DEFAULT_PATH; +} + +/* +=============== +Sys_GetConsoleKey +=============== +*/ +unsigned char Sys_GetConsoleKey( bool shifted ) { + return shifted ? '~' : '`'; +} + +/* +=============== +Sys_Shutdown +=============== +*/ +void Sys_Shutdown( void ) { + basepath.Clear(); + savepath.Clear(); + Posix_Shutdown(); +} + +/* +=============== +Sys_GetProcessorId +=============== +*/ +cpuid_t Sys_GetProcessorId( void ) { + return CPUID_GENERIC; +} + +/* +=============== +Sys_GetProcessorString +=============== +*/ +const char *Sys_GetProcessorString( void ) { + return "generic"; +} + +/* +=============== +Sys_FPU_EnableExceptions +=============== +*/ +void Sys_FPU_EnableExceptions( int exceptions ) { +} + +/* +=============== +Sys_FPE_handler +=============== +*/ +void Sys_FPE_handler( int signum, siginfo_t *info, void *context ) { + assert( signum == SIGFPE ); + Sys_Printf( "FPE\n" ); +} + +/* +=============== +Sys_GetClockticks +=============== +*/ +double Sys_GetClockTicks( void ) { +#if defined( __i386__ ) + unsigned long lo, hi; + + __asm__ __volatile__ ( + "push %%ebx\n" \ + "xor %%eax,%%eax\n" \ + "cpuid\n" \ + "rdtsc\n" \ + "mov %%eax,%0\n" \ + "mov %%edx,%1\n" \ + "pop %%ebx\n" + : "=r" (lo), "=r" (hi) ); + return (double) lo + (double) 0xFFFFFFFF * hi; +#else +#error unsupported CPU +#endif +} + +/* +=============== +MeasureClockTicks +=============== +*/ +double MeasureClockTicks( void ) { + double t0, t1; + + t0 = Sys_GetClockTicks( ); + Sys_Sleep( 1000 ); + t1 = Sys_GetClockTicks( ); + return t1 - t0; +} + +/* +=============== +Sys_ClockTicksPerSecond +=============== +*/ +double Sys_ClockTicksPerSecond(void) { + static bool init = false; + static double ret; + + int fd, len, pos, end; + char buf[ 4096 ]; + + if ( init ) { + return ret; + } + + fd = open( "/proc/cpuinfo", O_RDONLY ); + if ( fd == -1 ) { + common->Printf( "couldn't read /proc/cpuinfo\n" ); + ret = MeasureClockTicks(); + init = true; + common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 ); + return ret; + } + len = read( fd, buf, 4096 ); + close( fd ); + pos = 0; + while ( pos < len ) { + if ( !idStr::Cmpn( buf + pos, "cpu MHz", 7 ) ) { + pos = strchr( buf + pos, ':' ) - buf + 2; + end = strchr( buf + pos, '\n' ) - buf; + if ( pos < len && end < len ) { + buf[end] = '\0'; + ret = atof( buf + pos ); + } else { + common->Printf( "failed parsing /proc/cpuinfo\n" ); + ret = MeasureClockTicks(); + init = true; + common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 ); + return ret; + } + common->Printf( "/proc/cpuinfo CPU frequency: %g MHz\n", ret ); + ret *= 1000000; + init = true; + return ret; + } + pos = strchr( buf + pos, '\n' ) - buf + 1; + } + common->Printf( "failed parsing /proc/cpuinfo\n" ); + ret = MeasureClockTicks(); + init = true; + common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 ); + return ret; +} + +/* +================ +Sys_GetSystemRam +returns in megabytes +================ +*/ +int Sys_GetSystemRam( void ) { + long count, page_size; + int mb; + + count = sysconf( _SC_PHYS_PAGES ); + if ( count == -1 ) { + common->Printf( "GetSystemRam: sysconf _SC_PHYS_PAGES failed\n" ); + return 512; + } + page_size = sysconf( _SC_PAGE_SIZE ); + if ( page_size == -1 ) { + common->Printf( "GetSystemRam: sysconf _SC_PAGE_SIZE failed\n" ); + return 512; + } + mb= (int)( (double)count * (double)page_size / ( 1024 * 1024 ) ); + // round to the nearest 16Mb + mb = ( mb + 8 ) & ~15; + return mb; +} + +/* +================== +Sys_DoStartProcess +if we don't fork, this function never returns +the no-fork lets you keep the terminal when you're about to spawn an installer + +if the command contains spaces, system() is used. Otherwise the more straightforward execl ( system() blows though ) +================== +*/ +void Sys_DoStartProcess( const char *exeName, bool dofork ) { + bool use_system = false; + if ( strchr( exeName, ' ' ) ) { + use_system = true; + } else { + // set exec rights when it's about a single file to execute + struct stat buf; + if ( stat( exeName, &buf ) == -1 ) { + printf( "stat %s failed: %s\n", exeName, strerror( errno ) ); + } else { + if ( chmod( exeName, buf.st_mode | S_IXUSR ) == -1 ) { + printf( "cmod +x %s failed: %s\n", exeName, strerror( errno ) ); + } + } + } + if ( dofork ) { + switch ( fork() ) { + case -1: + // main thread + break; + case 0: + if ( use_system ) { + printf( "system %s\n", exeName ); + system( exeName ); + _exit( 0 ); + } else { + printf( "execl %s\n", exeName ); + execl( exeName, exeName, NULL ); + printf( "execl failed: %s\n", strerror( errno ) ); + _exit( -1 ); + } + break; + } + } else { + if ( use_system ) { + printf( "system %s\n", exeName ); + system( exeName ); + sleep( 1 ); // on some systems I've seen that starting the new process and exiting this one should not be too close + } else { + printf( "execl %s\n", exeName ); + execl( exeName, exeName, NULL ); + printf( "execl failed: %s\n", strerror( errno ) ); + } + // terminate + _exit( 0 ); + } +} + +/* +================= +Sys_OpenURL +================= +*/ +void idSysLocal::OpenURL( const char *url, bool quit ) { + const char *script_path; + idFile *script_file; + char cmdline[ 1024 ]; + + static bool quit_spamguard = false; + + if ( quit_spamguard ) { + common->DPrintf( "Sys_OpenURL: already in a doexit sequence, ignoring %s\n", url ); + return; + } + + common->Printf( "Open URL: %s\n", url ); + // opening an URL on *nix can mean a lot of things .. + // just spawn a script instead of deciding for the user :-) + + // look in the savepath first, then in the basepath + script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_savepath" ), "", "openurl.sh" ); + script_file = fileSystem->OpenExplicitFileRead( script_path ); + if ( !script_file ) { + script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_basepath" ), "", "openurl.sh" ); + script_file = fileSystem->OpenExplicitFileRead( script_path ); + } + if ( !script_file ) { + common->Printf( "Can't find URL script 'openurl.sh' in either savepath or basepath\n" ); + common->Printf( "OpenURL '%s' failed\n", url ); + return; + } + fileSystem->CloseFile( script_file ); + + // if we are going to quit, only accept a single URL before quitting and spawning the script + if ( quit ) { + quit_spamguard = true; + } + + common->Printf( "URL script: %s\n", script_path ); + + // StartProcess is going to execute a system() call with that - hence the & + idStr::snPrintf( cmdline, 1024, "%s '%s' &", script_path, url ); + sys->StartProcess( cmdline, quit ); +} + +/* + ================== + Sys_DoPreferences + ================== + */ +void Sys_DoPreferences( void ) { } + +/* +================ +Sys_FPU_SetDAZ +================ +*/ +void Sys_FPU_SetDAZ( bool enable ) { + /* + DWORD dwData; + + _asm { + movzx ecx, byte ptr enable + and ecx, 1 + shl ecx, 6 + STMXCSR dword ptr dwData + mov eax, dwData + and eax, ~(1<<6) // clear DAX bit + or eax, ecx // set the DAZ bit + mov dwData, eax + LDMXCSR dword ptr dwData + } + */ +} + +/* +================ +Sys_FPU_SetFTZ +================ +*/ +void Sys_FPU_SetFTZ( bool enable ) { + /* + DWORD dwData; + + _asm { + movzx ecx, byte ptr enable + and ecx, 1 + shl ecx, 15 + STMXCSR dword ptr dwData + mov eax, dwData + and eax, ~(1<<15) // clear FTZ bit + or eax, ecx // set the FTZ bit + mov dwData, eax + LDMXCSR dword ptr dwData + } + */ +} + +/* +=============== +mem consistency stuff +=============== +*/ + +#ifdef ID_MCHECK + +const char *mcheckstrings[] = { + "MCHECK_DISABLED", + "MCHECK_OK", + "MCHECK_FREE", // block freed twice + "MCHECK_HEAD", // memory before the block was clobbered + "MCHECK_TAIL" // memory after the block was clobbered +}; + +void abrt_func( mcheck_status status ) { + Sys_Printf( "memory consistency failure: %s\n", mcheckstrings[ status + 1 ] ); + Posix_SetExit( EXIT_FAILURE ); + common->Quit(); +} + +#endif + +/* +=============== +main +=============== +*/ +int main(int argc, const char **argv) { +#ifdef ID_MCHECK + // must have -lmcheck linkage + mcheck( abrt_func ); + Sys_Printf( "memory consistency checking enabled\n" ); +#endif + + Posix_EarlyInit( ); + + if ( argc > 1 ) { + common->Init( argc-1, &argv[1], NULL ); + } else { + common->Init( 0, NULL, NULL ); + } + + Posix_LateInit( ); + + while (1) { + common->Frame(); + } +} diff --git a/sys/linux/oss/include/audio_core.h b/sys/linux/oss/include/audio_core.h new file mode 100644 index 000000000..5f701a86c --- /dev/null +++ b/sys/linux/oss/include/audio_core.h @@ -0,0 +1,310 @@ +#ifndef AUDIO_CORE_H +#define AUDIO_CORE_H +/* + * Copyright by 4Front Technologies 1993-2004 + * + * All rights reserved. + */ + +/* + * IMPORTANT NOTICE! + * + * This file contains internal structures used by Open Sound Systems. + * They will change without any notice between OSS versions. Care must be taken + * to make sure any software using this header gets properly re-compiled before + * use. + * + * 4Front Technologies (or anybody else) takes no responsibility of damages + * caused by use of this file. + */ + +/* Max number of audio channels currently supported */ +#define OSS_MAX_AUDIO_CHANNELS 8 + +struct audio_operations; + +typedef struct +{ + int fmt, speed, channels; + int convert; +} +sample_parms; + +typedef struct audio_operations audio_operations, adev_t, *adev_p; +typedef struct dma_buffparms dma_buffparms, *dmap_p; +typedef int (*cnv_func_t) (adev_p adev, dmap_p dmap, void **srcp, int *srcl, + void **tgtp, sample_parms * source, + sample_parms * target); + +struct dma_buffparms +{ +/* + * Static fields (not to be cleared during open) + */ +#ifndef CONFIGURE_C + oss_mutex mutex; +#endif + sound_os_info *osp; + char *raw_buf; + oss_native_ulong raw_buf_phys; + int buffsize; + unsigned char *tmpbuf1, *tmpbuf2; + int dma; /* DMA channel */ + void *driver_use_ptr; + long driver_use_value; + /* Interrupt callback stuff */ + void (*audio_callback) (int dev, int parm); + int callback_parm; + +#ifdef OS_DMA_PARMS + OS_DMA_PARMS +#endif +/* + * Dynamic fields (will be zeroed during open) + * Don't add anything before flags. + */ + void *srcstate[OSS_MAX_AUDIO_CHANNELS]; + oss_native_ulong flags; +#define DMAP_NOTIMEOUT 0x00000001 +#define DMAP_POST 0x00000002 +#define DMAP_PREPARED 0x00000004 +#define DMAP_FRAGFIXED 0x00000008 /* Fragment size fixed */ +#define DMAP_STARTED 0x00000010 +#define DMAP_COOKED 0x00000020 +#define DMAP_ACTIVE 0x00000040 /* ISA DMA is running */ + int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */ +#define DMODE_NONE 0 +#define DMODE_OUTPUT PCM_ENABLE_OUTPUT +#define DMODE_INPUT PCM_ENABLE_INPUT + + /* + * Queue parameters. + */ + int nbufs; + int frag_used; + int fragment_size; + int bytes_in_use; + int data_rate; /* Bytes/second */ + int frame_size; + int fragsize_rq; + int low_water; + volatile oss_native_ulonglong byte_counter; + volatile oss_native_ulonglong user_counter; + int write_count; + int interrupt_count; + int fragment_counter; + int expand_factor; + + int mapping_flags; +#define DMA_MAP_MAPPED 0x00000001 + char neutral_byte; + +#ifdef SPARCAUDIO_EMU +#define EOFLIST_SIZE 16 + void *devaudio_sigproc; /* A pref to which send a SIGPOLL signal */ + int devaudio_sigmask; + int eof_head, eof_tail; + int eof_list[EOFLIST_SIZE], eof_counts[EOFLIST_SIZE]; +#endif + int error; + int play_underruns, rec_overruns; + int underrun_flag; + int play_error, num_play_errors; + int rec_error, num_rec_errors; + + unsigned char *leftover_buf; + int leftover_bytes; + int tmpbuf_len, tmpbuf_ptr; + cnv_func_t convert_func; + unsigned int convert_mode; + struct audio_buffer *(*user_import) (struct audio_operations * adev, + struct dma_buffparms * dmap, + sample_parms * parms, + unsigned char *cbuf, int len); + int (*user_export) (struct audio_operations * adev, + struct dma_buffparms * dmap, sample_parms * parms, + struct audio_buffer * buf, unsigned char *cbuf, + int maxbytes); + struct audio_buffer *(*device_read) (struct audio_operations * adev, + struct dma_buffparms * dmap, + sample_parms * parms, + unsigned char *cbuf, int len); + int (*device_write) (struct audio_operations * adev, + struct dma_buffparms * dmap, + void *frombuf, void *tobuf, + int maxspace, int *fromlen, int *tolen); +}; +extern int dmap_get_qlen (dma_buffparms * dmap); +extern int dmap_get_qhead (dma_buffparms * dmap); +extern int dmap_get_qtail (dma_buffparms * dmap); + +struct audio_driver +{ + int (*open) (int dev, int mode, int open_flags); + void (*close) (int dev, int mode); + void (*output_block) (int dev, oss_native_ulong buf, + int count, int fragsize, int intrflag); + void (*start_input) (int dev, oss_native_ulong buf, + int count, int fragsize, int intrflag); + int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg); + int (*prepare_for_input) (int dev, int bufsize, int nbufs); + int (*prepare_for_output) (int dev, int bufsize, int nbufs); + void (*halt_io) (int dev); + int (*local_qlen) (int dev); + int (*copy_user) (int dev, char *localbuf, int localoffs, + WR_BUF_CONST snd_rw_buf * userbuf, int useroffs, + int *len, int max_space); + void (*halt_input) (int dev); + void (*halt_output) (int dev); + void (*trigger) (int dev, int bits); + int (*set_speed) (int dev, int speed); + unsigned int (*set_bits) (int dev, unsigned int bits); + short (*set_channels) (int dev, short channels); + void (*postprocess_write) (int dev); /* Device spesific postprocessing for written data */ + void (*preprocess_read) (int dev); /* Device spesific preprocessing for read data */ + /* Timeout handlers for input and output */ + int (*check_input) (int dev); + int (*check_output) (int dev); + + int (*alloc_buffer) (int dev, struct dma_buffparms * dmap, int direction); + int (*free_buffer) (int dev, struct dma_buffparms * dmap, int direction); + void (*lock_buffer) (int dev, int direction); + void *dummy; + int (*get_buffer_pointer) (int dev, struct dma_buffparms * dmap, + int direction); + int (*calibrate_speed) (int dev, int nominal_rate, int true_rate); +#define SYNC_PREPARE 1 +#define SYNC_TRIGGER 2 + int (*sync_control) (int dev, int event, int mode); + void (*prepare_to_stop) (int dev); + int (*get_input_pointer) (int dev, struct dma_buffparms * dmap, + int direction); + int (*get_output_pointer) (int dev, struct dma_buffparms * dmap, + int direction); + int (*bind) (int dev, unsigned int cmd, ioctl_arg arg); + void (*setup_fragments) (int dev, dmap_p dmap, int direction); +}; + +struct audio_operations +{ + char name[128]; + char handle[32]; + int dev; /* Device's own index */ + int enabled; + struct audio_operations *next; /* Link to the next "shadow" device */ + int flags; + int open_flags; + int caps; + int magic; /* Secret low level driver ID */ +#define NOTHING_SPECIAL 0x00 +#define NEEDS_RESTART 0x01 +#define DMA_AUTOMODE 0x02 +#define DMA_DUPLEX 0x04 +#define DMA_COLD 0x08 +#define DMA_UNUSED1 0x10 +#define DMA_UNUSED2 0x40 +#define DMA_UNUSED3 0x80 +#define DMA_ISA 0x100 /* ISA DMA buffer placement restrictions */ +#define DMA_VIRTUAL 0x400 /* Virtual audio device */ +#define DMA_OPENED 0x800 /* Will be set when the device is open */ +#define DMA_NOCONVERT 0x1000 /* No implicit format conversions */ +#define DMA_DUALBUF 0x2000 /* Alloc separate bufs for rec and play */ +#define DMA_USEPHYSADDR 0x4000 /* Use raw_buf_phys when mmap()ing */ +#define DMA_DISABLED 0x8000 +#define DMA_NOINPUT 0x10000 +#define DMA_NOOUTPUT 0x20000 +#define DMA_FIXEDRATE 0x40000 /* Fixed sampling rate */ +#define DMA_16BITONLY 0x80000 /* Only 16 bit support */ +#define DMA_STEREOONLY 0x100000 /* Only stereo (requires 16BITONLY) */ +#define DMA_HUSHOUTPUT 0x200000 /* Do not permit use with O_WRONLY */ +#define DMA_SHADOW 0x400000 /* "shadow" device */ +#define DMA_ISABUS 0x800000 /* ISA device */ +#define DMA_NODMA 0x1000000 /* For ISA devices only */ +#define DMA_8BITONLY 0x2000000 /* Only 8 bits */ +#define DMA_32BITONLY 0x4000000 /* Only 24 or 32 bits */ +#define DMA_NOSOFTOSS 0x8000000 /* Don't install SoftOSS automatically for this device */ +#define DMA_NOSRC 0x10000000 /* Don't do any kind of SRC */ +#define DMA_SPECIAL 0x20000000 /* Multich or otherwise special dev */ +#define DMA_NOMMAP 0x40000000 /* No MMAP capability */ +#define DMA_SOFTOSS_DISABLE 0x80000000 /* Not compatible with SoftOSS */ + + + /* + * Sampling parameters + */ + + sample_parms user_parms, hw_parms; + int iformat_mask, oformat_mask; /* Bitmasks for supported audio formats */ + int min_rate, max_rate; /* Sampling rate limits */ + int min_channels, max_channels; + int xformat_mask; /* Format mask for current open mode */ + int binding; + void *devc; /* Driver specific info */ + struct audio_driver *d; + void *portc, *portc_play, *portc_record; /* Driver specific info */ + struct dma_buffparms *dmap_in, *dmap_out; + int mixer_dev; + int open_mode; + int go; + int enable_bits; + int parent_dev; /* 0 -> no parent, 1 to n -> parent=parent_dev+1 */ + int max_block; /* Maximum fragment size to be accepted */ + int min_block; /* Minimum fragment size */ + int max_intrate; /* Another form of min_block */ + int fixed_rate; + int vmix_flags; /* special flags sent to virtual mixer */ +#define VMIX_MULTIFRAG 0x00000001 /* More than 2 fragments required (causes longer latencies) */ + int src_rate; + int src_ratio; + pid_t pid; + char cmd[16]; + sound_os_info *osp; + int setfragment_warned; + int riff_warned; + int redirect_in, redirect_out; + int dmask; /* Open dmaps */ +#define DMASK_OUT 0x01 +#define DMASK_IN 0x02 + int nonblock; + int forced_nonblock; + int ossd_registered; + int sync_flags; +#define SYNC_MASTER 0x01 +#define SYNC_SLAVE 0x02 + int sync_group; + int sync_mode; + struct audio_operations *sync_next; /* Next device in sync group */ + + int rate_source; +#define MAX_SAMPLE_RATES 20 /* Cannot be changed (see soundcard.h) */ + int nrates, rates[MAX_SAMPLE_RATES]; + +#ifndef CONFIGURE_C + oss_mutex mutex; +#endif + + int card_number; + int port_number; + int real_dev; + + int cooked_enable; + int timeout_count; + + void (*outputintr) (int dev, int xx); + void (*inputintr) (int dev); +}; + +typedef struct oss_card_desc +{ + char shortname[16]; + char longname[128]; +} oss_card_desc_t, *oss_card_desc_p; + +#define UNIT_EXPAND 1024 + +extern struct audio_operations **audio_devs; +extern int num_audiodevs; +extern oss_card_desc_p *oss_cardlist; +extern const char *oss_version_string; +extern const char *oss_checksum; +#endif diff --git a/sys/linux/oss/include/midi_core.h b/sys/linux/oss/include/midi_core.h new file mode 100644 index 000000000..7037c7306 --- /dev/null +++ b/sys/linux/oss/include/midi_core.h @@ -0,0 +1,66 @@ +#ifndef MIDI_CORE_H +#define MIDI_CORE_H +/* + * Copyright by 4Front Technologies 1993-2004 + * + * All rights reserved. + */ + +/* + * IMPORTANT NOTICE! + * + * This file contains internal structures used by Open Sound Systems. + * They will change without any notice between OSS versions. Care must be taken + * to make sure any software using this header gets properly re-compiled before + * use. + * + * 4Front Technologies (or anybody else) takes no responsibility of damages + * caused by use of this file. + */ + +struct midi_input_info +{ /* MIDI input scanner variables */ +#define MI_MAX 32 + int m_busy; + unsigned char m_buf[MI_MAX]; + unsigned char m_prev_status; /* For running status */ + int m_ptr; +#define MST_INIT 0 +#define MST_DATA 1 +#define MST_SYSEX 2 + int m_state; + int m_left; +}; + +typedef struct midi_operations +{ + struct midi_info info; + struct synth_operations *converter; + struct midi_input_info in_info; + int (*open) (int dev, int mode, + void (*inputintr) (int dev, unsigned char data), + void (*outputintr) (int dev)); + void (*close) (int dev); + int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg); + int (*outputc) (int dev, unsigned char data); + int (*start_read) (int dev); + int (*end_read) (int dev); + void (*kick) (int dev); + int (*command) (int dev, unsigned char *data); + int (*buffer_status) (int dev); + int (*prefix_cmd) (int dev, unsigned char status); + void (*input_callback) (int dev, unsigned char midich); + struct coproc_operations *coproc; + void *devc; + sound_os_info *osp; + int card_number; +#ifndef CONFIGURE_C + oss_mutex mutex; +#endif + unsigned long flags; +#define MFLAG_NOSEQUENCER 0x00000001 /* Not to be used by the sequencer driver */ +} mididev_t, *mididev_p; + +extern struct midi_operations **midi_devs; +extern int num_mididevs; +#endif diff --git a/sys/linux/oss/include/mixer_core.h b/sys/linux/oss/include/mixer_core.h new file mode 100644 index 000000000..e2a48ceff --- /dev/null +++ b/sys/linux/oss/include/mixer_core.h @@ -0,0 +1,61 @@ +#ifndef MIXER_CORE_H +#define MIXER_CORE_H +/* + * Copyright by 4Front Technologies 1993-2004 + * + * All rights reserved. + */ + +/* + * IMPORTANT NOTICE! + * + * This file contains internal structures used by Open Sound Systems. + * They will change without any notice between OSS versions. Care must be taken + * to make sure any software using this header gets properly re-compiled before + * use. + * + * 4Front Technologies (or anybody else) takes no responsibility of damages + * caused by use of this file. + */ +typedef int (*mixer_ext_fn) (int dev, int ctrl, unsigned int cmd, int value); +typedef int (*mixer_ext_init_fn) (int dev); + +typedef struct +{ + oss_mixext ext; + mixer_ext_fn handler; + oss_mixer_enuminfo *enum_info; +} +oss_mixext_desc; + +struct mixer_operations +{ + char id[16]; + char name[64]; + int (*ioctl) (int dev, int audiodev, unsigned int cmd, ioctl_arg arg); + + void *devc; + void *hw_devc; + int modify_counter; + + /* Mixer extension interface */ + int nr_ext; + int max_ext; + int nr_extra_ext; + int timestamp; + oss_mixext_desc *extensions; + mixer_ext_init_fn ext_init_fn; + int ignore_mask; /* Controls ignored by mixer ext API */ + int card_number; + int enabled; +}; + +typedef struct mixer_operations mixdev_t, *mixdev_p; + +extern struct mixer_operations **mixer_devs; +extern int num_mixers; +extern void touch_mixer (int dev); +extern int oss_mixer_ext (int orig_dev, unsigned int cmd, ioctl_arg arg); +extern int mixer_ext_set_enum (oss_mixer_enuminfo * ent); + +#endif diff --git a/sys/linux/oss/include/sys/soundcard.h b/sys/linux/oss/include/sys/soundcard.h new file mode 100644 index 000000000..8d2e9cf96 --- /dev/null +++ b/sys/linux/oss/include/sys/soundcard.h @@ -0,0 +1,1725 @@ +#ifndef SOUNDCARD_H +#define SOUNDCARD_H +/* + * Copyright by Hannu Savolainen 1993-2004 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * IMPORTANT NOTICE! + * + * This header file contains many obsolete definitions (for compatibility + * purposes). Please check the OSS Programmer's guide for descriptions + * of the supported API details (http://www.opensound.com/pguide). + */ + +#if defined(__cplusplus) +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#endif /* EXTERN_C_WRAPPERS */ + +/* + * OSS interface version. With versions earlier than 3.6 this value is + * an integer with value less than 361. In versions 3.6 and later + * it's a six digit hexadecimal value. For example value + * of 0x030600 represents OSS version 3.6.0. + * Use ioctl(fd, OSS_GETVERSION, &int) to get the version number of + * the currently active driver. + */ +#define SOUND_VERSION 0x039999 +#define OPEN_SOUND_SYSTEM + +#if defined(__hpux) && !defined(_HPUX_SOURCE) +# error "-D_HPUX_SOURCE must be used when compiling OSS applications" +#endif + +#ifdef __hpux +#include +#endif + +#ifdef linux +/* In Linux we need to be prepared for cross compiling */ +#include +#else +# ifdef __FreeBSD__ +# include +# else +# include +# endif +#endif + +/* + * Supported card ID numbers (OBSOLETE. NOT USED ANY MORE) + */ + +#define SNDCARD_ADLIB 1 +#define SNDCARD_SB 2 +#define SNDCARD_PAS 3 +#define SNDCARD_GUS 4 +#define SNDCARD_MPU401 5 +#define SNDCARD_SB16 6 +#define SNDCARD_SB16MIDI 7 +#define SNDCARD_UART6850 8 +#define SNDCARD_GUS16 9 +#define SNDCARD_MSS 10 +#define SNDCARD_PSS 11 +#define SNDCARD_SSCAPE 12 +#define SNDCARD_PSS_MPU 13 +#define SNDCARD_PSS_MSS 14 +#define SNDCARD_SSCAPE_MSS 15 +#define SNDCARD_TRXPRO 16 +#define SNDCARD_TRXPRO_SB 17 +#define SNDCARD_TRXPRO_MPU 18 +#define SNDCARD_MAD16 19 +#define SNDCARD_MAD16_MPU 20 +#define SNDCARD_CS4232 21 +#define SNDCARD_CS4232_MPU 22 +#define SNDCARD_MAUI 23 +#define SNDCARD_PSEUDO_MSS 24 +#define SNDCARD_GUSPNP 25 +#define SNDCARD_UART401 26 +/* Sound card numbers 27 to N are reserved. Don't add more numbers here */ + +/*********************************** + * IOCTL Commands for /dev/sequencer + */ + +#ifndef __SIOWR +#if defined(__hpux) || (defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__INCioctlh) && !defined(__Lynx__)))) + +/* + * Use already defined ioctl defines if they exist (except with Sun and some + * others) + */ +#define SIOCPARM_MASK IOCPARM_MASK +#define SIOC_VOID IOC_VOID +#define SIOC_OUT IOC_OUT +#define SIOC_IN IOC_IN +#define SIOC_INOUT IOC_INOUT +#define __SIOC_SIZE _IOC_SIZE +#define __SIOC_DIR _IOC_DIR +#define __SIOC_NONE _IOC_NONE +#define __SIOC_READ _IOC_READ +#define __SIOC_WRITE _IOC_WRITE +#define __SIO _IO +#define __SIOR _IOR +#define __SIOW _IOW +#define __SIOWR _IOWR +#else + +/* Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 8191 bytes. + */ +/* #define SIOCTYPE (0xff<<8) */ +#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */ +#define SIOC_VOID 0x00000000 /* no parameters */ +#define SIOC_OUT 0x20000000 /* copy out parameters */ +#define SIOC_IN 0x40000000 /* copy in parameters */ +#define SIOC_INOUT (SIOC_IN|SIOC_OUT) + +/* the 0x20000000 is so we can distinguish new ioctl's from old */ +#define __SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y)) +#define __SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK) +#define __SIOC_DIR(x) (x & 0xf0000000) +#define __SIOC_NONE SIOC_VOID +#define __SIOC_READ SIOC_OUT +#define __SIOC_WRITE SIOC_IN +# endif /* _IOWR */ +#endif /* !__SIOWR */ + +#define SNDCTL_SEQ_RESET __SIO ('Q', 0) +#define SNDCTL_SEQ_SYNC __SIO ('Q', 1) +#define SNDCTL_SYNTH_INFO __SIOWR('Q', 2, struct synth_info) +#define SNDCTL_SEQ_CTRLRATE __SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ +#define SNDCTL_SEQ_GETOUTCOUNT __SIOR ('Q', 4, int) +#define SNDCTL_SEQ_GETINCOUNT __SIOR ('Q', 5, int) +#define SNDCTL_SEQ_PERCMODE __SIOW ('Q', 6, int) +#define SNDCTL_FM_LOAD_INSTR __SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */ +#define SNDCTL_SEQ_TESTMIDI __SIOW ('Q', 8, int) +#define SNDCTL_SEQ_RESETSAMPLES __SIOW ('Q', 9, int) +#define SNDCTL_SEQ_NRSYNTHS __SIOR ('Q',10, int) +#define SNDCTL_SEQ_NRMIDIS __SIOR ('Q',11, int) +#define SNDCTL_MIDI_INFO __SIOWR('Q',12, struct midi_info) +#define SNDCTL_SEQ_THRESHOLD __SIOW ('Q',13, int) +#define SNDCTL_SYNTH_MEMAVL __SIOWR('Q',14, int) /* in=dev#, out=memsize */ +#define SNDCTL_FM_4OP_ENABLE __SIOW ('Q',15, int) /* in=dev# */ +#define SNDCTL_SEQ_PANIC __SIO ('Q',17) +#define SNDCTL_SEQ_OUTOFBAND __SIOW ('Q',18, struct seq_event_rec) +#define SNDCTL_SEQ_GETTIME __SIOR ('Q',19, int) +#define SNDCTL_SYNTH_ID __SIOWR('Q',20, struct synth_info) +#define SNDCTL_SYNTH_CONTROL __SIOWR('Q',21, struct synth_control) +#define SNDCTL_SYNTH_REMOVESAMPLE __SIOWR('Q',22, struct remove_sample) /* Reserved for future use */ +#define SNDCTL_SEQ_TIMING_ENABLE __SIO ('Q', 23) /* Enable incoming MIDI timing messages */ +#define SNDCTL_SEQ_ACTSENSE_ENABLE __SIO ('Q', 24) /* Enable incoming active sensing messages */ +#define SNDCTL_SEQ_RT_ENABLE __SIO ('Q', 25) /* Enable other incoming realtime messages */ + +typedef struct synth_control +{ + int devno; /* Synthesizer # */ + char data[4000]; /* Device spesific command/data record */ +} synth_control; + +typedef struct remove_sample +{ + int devno; /* Synthesizer # */ + int bankno; /* MIDI bank # (0=General MIDI) */ + int instrno; /* MIDI instrument number */ +} remove_sample; + +typedef struct seq_event_rec +{ + unsigned char arr[8]; +} seq_event_rec; + +#define SNDCTL_TMR_TIMEBASE __SIOWR('T', 1, int) +#define SNDCTL_TMR_START __SIO ('T', 2) +#define SNDCTL_TMR_STOP __SIO ('T', 3) +#define SNDCTL_TMR_CONTINUE __SIO ('T', 4) +#define SNDCTL_TMR_TEMPO __SIOWR('T', 5, int) +#define SNDCTL_TMR_SOURCE __SIOWR('T', 6, int) +# define TMR_INTERNAL 0x00000001 +# define TMR_EXTERNAL 0x00000002 +# define TMR_MODE_MIDI 0x00000010 +# define TMR_MODE_FSK 0x00000020 +# define TMR_MODE_CLS 0x00000040 +# define TMR_MODE_SMPTE 0x00000080 +#define SNDCTL_TMR_METRONOME __SIOW ('T', 7, int) +#define SNDCTL_TMR_SELECT __SIOW ('T', 8, int) + +/* + * Some big endian/little endian handling macros (native endian and opposite + * endian formats) + */ + +#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__) + +/* Big endian machines */ +# define _PATCHKEY(id) (0xfd00|id) +# define AFMT_S16_NE AFMT_S16_BE +# define AFMT_U16_NE AFMT_U16_BE +# define AFMT_S32_NE AFMT_S32_BE +# define AFMT_S24_NE AFMT_S24_BE +# define AFMT_S16_OE AFMT_S16_LE +# define AFMT_S32_OE AFMT_S32_LE +# define AFMT_S24_OE AFMT_S24_LE +#else +# define _PATCHKEY(id) ((id<<8)|0xfd) +# define AFMT_S16_NE AFMT_S16_LE +# define AFMT_U16_NE AFMT_U16_LE +# define AFMT_S32_NE AFMT_S32_LE +# define AFMT_S24_NE AFMT_S24_LE +# define AFMT_S16_OE AFMT_S16_BE +# define AFMT_S32_OE AFMT_S32_BE +# define AFMT_S24_OE AFMT_S24_BE +#endif + +/* + * Sample loading mechanism for internal synthesizers (/dev/sequencer) + * The following patch_info structure has been designed to support + * Gravis UltraSound. It tries to be universal format for uploading + * sample based patches but is probably too limited. + */ + +struct patch_info +{ + unsigned short key; /* Use WAVE_PATCH here */ +#define WAVE_PATCH _PATCHKEY(0x04) +#define GUS_PATCH WAVE_PATCH +#define WAVEFRONT_PATCH _PATCHKEY(0x06) + + short device_no; /* Synthesizer number */ + short instr_no; /* Midi pgm# */ + + unsigned int mode; +/* + * The least significant byte has the same format than the GUS .PAT + * files + */ +#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */ +#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */ +#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */ +#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */ +#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */ +#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3) */ +#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */ +#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */ + /* (use the env_rate/env_offs fields). */ +/* Linux specific bits */ +#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */ +#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */ +#define WAVE_SCALE 0x00040000 /* The scaling info is valid */ +#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */ +/* Reserved bits */ +#define WAVE_ROM 0x40000000 /* For future use */ +#define WAVE_MULAW 0x20000000 /* For future use */ +/* Other bits must be zeroed */ + + int len; /* Size of the wave data in bytes */ + int loop_start, loop_end; /* Byte offsets from the beginning */ + +/* + * The base_freq and base_note fields are used when computing the + * playback speed for a note. The base_note defines the tone frequency + * which is heard if the sample is played using the base_freq as the + * playback speed. + * + * The low_note and high_note fields define the minimum and maximum note + * frequencies for which this sample is valid. It is possible to define + * more than one samples for an instrument number at the same time. The + * low_note and high_note fields are used to select the most suitable one. + * + * The fields base_note, high_note and low_note should contain + * the note frequency multiplied by 1000. For example value for the + * middle A is 440*1000. + */ + + unsigned int base_freq; + unsigned int base_note; + unsigned int high_note; + unsigned int low_note; + int panning; /* -128=left, 127=right */ + int detuning; + + /* New fields introduced in version 1.99.5 */ + + /* Envelope. Enabled by mode bit WAVE_ENVELOPES */ + unsigned char env_rate[6]; /* GUS HW ramping rate */ + unsigned char env_offset[6]; /* 255 == 100% */ + + /* + * The tremolo, vibrato and scale info are not supported yet. + * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or + * WAVE_SCALE + */ + + unsigned char tremolo_sweep; + unsigned char tremolo_rate; + unsigned char tremolo_depth; + + unsigned char vibrato_sweep; + unsigned char vibrato_rate; + unsigned char vibrato_depth; + + int scale_frequency; + unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ + + int volume; + int fractions; + int reserved1; + int spare[2]; + char data[1]; /* The waveform data starts here */ +}; + +struct sysex_info +{ + short key; /* Use SYSEX_PATCH or MAUI_PATCH here */ +#define SYSEX_PATCH _PATCHKEY(0x05) +#define MAUI_PATCH _PATCHKEY(0x06) + short device_no; /* Synthesizer number */ + int len; /* Size of the sysex data in bytes */ + unsigned char data[1]; /* Sysex data starts here */ +}; + +/* + * /dev/sequencer input events. + * + * The data written to the /dev/sequencer is a stream of events. Events + * are records of 4 or 8 bytes. The first byte defines the size. + * Any number of events can be written with a write call. There + * is a set of macros for sending these events. Use these macros if you + * want to maximize portability of your program. + * + * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events. + * (All input events are currently 4 bytes long. Be prepared to support + * 8 byte events also. If you receive any event having first byte >= 128, + * it's a 8 byte event. + * + * The events are documented at the end of this file. + * + * Normal events (4 bytes) + * There is also a 8 byte version of most of the 4 byte events. The + * 8 byte one is recommended. + * + * NOTE! All 4 byte events are now obsolete. Applications should not write + * them. However 4 byte events are still used as inputs from + * /dev/sequencer (/dev/music uses only 8 byte ones). + */ +#define SEQ_NOTEOFF 0 +#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */ +#define SEQ_NOTEON 1 +#define SEQ_FMNOTEON SEQ_NOTEON +#define SEQ_WAIT TMR_WAIT_ABS +#define SEQ_PGMCHANGE 3 +#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE +#define SEQ_SYNCTIMER TMR_START +#define SEQ_MIDIPUTC 5 +#define SEQ_DRUMON 6 /*** OBSOLETE ***/ +#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/ +#define SEQ_ECHO TMR_ECHO /* For synching programs with output */ +#define SEQ_AFTERTOUCH 9 +#define SEQ_CONTROLLER 10 +#define SEQ_BALANCE 11 +#define SEQ_VOLMODE 12 + +/************************************ + * Midi controller numbers * + ************************************/ +/* + * Controllers 0 to 31 (0x00 to 0x1f) and + * 32 to 63 (0x20 to 0x3f) are continuous + * controllers. + * In the MIDI 1.0 these controllers are sent using + * two messages. Controller numbers 0 to 31 are used + * to send the MSB and the controller numbers 32 to 63 + * are for the LSB. Note that just 7 bits are used in MIDI bytes. + */ + +#define CTL_BANK_SELECT 0x00 +#define CTL_MODWHEEL 0x01 +#define CTL_BREATH 0x02 +/* undefined 0x03 */ +#define CTL_FOOT 0x04 +#define CTL_PORTAMENTO_TIME 0x05 +#define CTL_DATA_ENTRY 0x06 +#define CTL_MAIN_VOLUME 0x07 +#define CTL_BALANCE 0x08 +/* undefined 0x09 */ +#define CTL_PAN 0x0a +#define CTL_EXPRESSION 0x0b +/* undefined 0x0c */ +/* undefined 0x0d */ +/* undefined 0x0e */ +/* undefined 0x0f */ +#define CTL_GENERAL_PURPOSE1 0x10 +#define CTL_GENERAL_PURPOSE2 0x11 +#define CTL_GENERAL_PURPOSE3 0x12 +#define CTL_GENERAL_PURPOSE4 0x13 +/* undefined 0x14 - 0x1f */ + +/* undefined 0x20 */ +/* The controller numbers 0x21 to 0x3f are reserved for the */ +/* least significant bytes of the controllers 0x00 to 0x1f. */ +/* These controllers are not recognised by the driver. */ + +/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */ +/* 0=OFF and 127=ON (intermediate values are possible) */ +#define CTL_DAMPER_PEDAL 0x40 +#define CTL_SUSTAIN 0x40 /* Alias */ +#define CTL_HOLD 0x40 /* Alias */ +#define CTL_PORTAMENTO 0x41 +#define CTL_SOSTENUTO 0x42 +#define CTL_SOFT_PEDAL 0x43 +/* undefined 0x44 */ +#define CTL_HOLD2 0x45 +/* undefined 0x46 - 0x4f */ + +#define CTL_GENERAL_PURPOSE5 0x50 +#define CTL_GENERAL_PURPOSE6 0x51 +#define CTL_GENERAL_PURPOSE7 0x52 +#define CTL_GENERAL_PURPOSE8 0x53 +/* undefined 0x54 - 0x5a */ +#define CTL_EXT_EFF_DEPTH 0x5b +#define CTL_TREMOLO_DEPTH 0x5c +#define CTL_CHORUS_DEPTH 0x5d +#define CTL_DETUNE_DEPTH 0x5e +#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */ +#define CTL_PHASER_DEPTH 0x5f +#define CTL_DATA_INCREMENT 0x60 +#define CTL_DATA_DECREMENT 0x61 +#define CTL_NONREG_PARM_NUM_LSB 0x62 +#define CTL_NONREG_PARM_NUM_MSB 0x63 +#define CTL_REGIST_PARM_NUM_LSB 0x64 +#define CTL_REGIST_PARM_NUM_MSB 0x65 +/* undefined 0x66 - 0x78 */ +/* reserved 0x79 - 0x7f */ + +/* Pseudo controllers (not midi compatible) */ +#define CTRL_PITCH_BENDER 255 +#define CTRL_PITCH_BENDER_RANGE 254 +#define CTRL_EXPRESSION 253 /* Obsolete */ +#define CTRL_MAIN_VOLUME 252 /* Obsolete */ + +/* + * Volume mode defines how volumes are used + */ + +#define VOL_METHOD_ADAGIO 1 +#define VOL_METHOD_LINEAR 2 + +/* + * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as + * input events. + */ + +/* + * Event codes 0xf0 to 0xfc are reserved for future extensions. + */ + +#define SEQ_FULLSIZE 0xfd /* Long events */ +/* + * SEQ_FULLSIZE events are used for loading patches/samples to the + * synthesizer devices. These events are passed directly to the driver + * of the associated synthesizer device. There is no limit to the size + * of the extended events. These events are not queued but executed + * immediately when the write() is called (execution can take several + * seconds of time). + * + * When a SEQ_FULLSIZE message is written to the device, it must + * be written using exactly one write() call. Other events cannot + * be mixed to the same write. + * + * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the + * /dev/sequencer. Don't write other data together with the instrument structure + * Set the key field of the structure to FM_PATCH. The device field is used to + * route the patch to the corresponding device. + * + * For wave table use struct patch_info. Initialize the key field + * to WAVE_PATCH. + */ +#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */ +#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */ + +/* + * Record for FM patches + */ + +typedef unsigned char sbi_instr_data[32]; + +struct sbi_instrument +{ + unsigned short key; /* FM_PATCH or OPL3_PATCH */ +#define FM_PATCH _PATCHKEY(0x01) +#define OPL3_PATCH _PATCHKEY(0x03) + short device; /* Synth# (0-4) */ + int channel; /* Program# to be initialized */ + sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */ +}; + +struct synth_info +{ /* Read only */ + char name[30]; + int device; /* 0-N. INITIALIZE BEFORE CALLING */ + int synth_type; +#define SYNTH_TYPE_FM 0 +#define SYNTH_TYPE_SAMPLE 1 +#define SYNTH_TYPE_MIDI 2 /* Midi interface */ + + int synth_subtype; +#define FM_TYPE_ADLIB 0x00 +#define FM_TYPE_OPL3 0x01 +#define MIDI_TYPE_MPU401 0x401 + +#define SAMPLE_TYPE_BASIC 0x10 +#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC +#define SAMPLE_TYPE_WAVEFRONT 0x11 + + int perc_mode; /* No longer supported */ + int nr_voices; + int nr_drums; /* Obsolete field */ + int instr_bank_size; + unsigned int capabilities; +#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */ +#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */ +#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */ + int dummies[19]; /* Reserve space */ +}; + +struct sound_timer_info +{ + char name[32]; + int caps; +}; + +#define MIDI_CAP_MPU401 1 /* MPU-401 intelligent mode */ + +struct midi_info +{ + char name[30]; + int device; /* 0-N. INITIALIZE BEFORE CALLING */ + unsigned int capabilities; /* To be defined later */ + int dev_type; + int dummies[18]; /* Reserve space */ +}; + +/*************************************** + * ioctl commands for the /dev/midi## * + ***************************************/ +typedef struct +{ + unsigned char cmd; + char nr_args, nr_returns; + unsigned char data[30]; +} mpu_command_rec; + +#define SNDCTL_MIDI_PRETIME __SIOWR('m', 0, int) +#define SNDCTL_MIDI_MPUMODE __SIOWR('m', 1, int) +#define SNDCTL_MIDI_MPUCMD __SIOWR('m', 2, mpu_command_rec) + +/********************************************** + * IOCTL commands for /dev/dsp and /dev/audio * + **********************************************/ + +#define SNDCTL_DSP_RESET __SIO ('P', 0) +#define SNDCTL_DSP_SYNC __SIO ('P', 1) +#define SNDCTL_DSP_SPEED __SIOWR('P', 2, int) +#define SNDCTL_DSP_STEREO __SIOWR('P', 3, int) +#define SNDCTL_DSP_GETBLKSIZE __SIOWR('P', 4, int) +#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT +#define SNDCTL_DSP_CHANNELS __SIOWR('P', 6, int) +#define SNDCTL_DSP_POST __SIO ('P', 8) +#define SNDCTL_DSP_SUBDIVIDE __SIOWR('P', 9, int) +#define SNDCTL_DSP_SETFRAGMENT __SIOWR('P',10, int) + +/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ +#define SNDCTL_DSP_GETFMTS __SIOR ('P',11, int) /* Returns a mask */ +#define SNDCTL_DSP_SETFMT __SIOWR('P',5, int) /* Selects ONE fmt */ +# define AFMT_QUERY 0x00000000 /* Return current fmt */ +# define AFMT_MU_LAW 0x00000001 +# define AFMT_A_LAW 0x00000002 +# define AFMT_IMA_ADPCM 0x00000004 +# define AFMT_U8 0x00000008 +# define AFMT_S16_LE 0x00000010 /* Little endian signed 16 */ +# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */ +# define AFMT_S8 0x00000040 +# define AFMT_U16_LE 0x00000080 /* Little endian U16 */ +# define AFMT_U16_BE 0x00000100 /* Big endian U16 */ +# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ + +/* AC3 _compressed_ bitstreams (See Programmer's Guide for details). */ +# define AFMT_AC3 0x00000400 +/* Ogg Vorbis _compressed_ bit streams */ +# define AFMT_VORBIS 0x00000800 + +/* 32 bit formats (MSB aligned) formats */ +# define AFMT_S32_LE 0x00001000 +# define AFMT_S32_BE 0x00002000 + +/* Reserved for _native_ endian double precision IEEE floating point */ +# define AFMT_FLOAT 0x00004000 + +/* 24 bit formats (LSB aligned in 32 bit word) formats */ +# define AFMT_S24_LE 0x00008000 +# define AFMT_S24_BE 0x00010000 + +/* + * S/PDIF raw format. In this format the S/PDIF frames (including all + * control and user bits) are included in the data stream. Each sample + * is stored in a 32 bit frame (see IEC-958 for more info). This format + * is supported by very few devices and it's only usable for purposes + * where full access to the control/user bits is required (real time control). + */ +# define AFMT_SPDIF_RAW 0x00020000 + +/* 24 bit packed (3 byte) little endian format (USB compatibility) */ +# define AFMT_S24_PACKED 0x00040000 + +/* + * Buffer status queries. + */ +typedef struct audio_buf_info +{ + int fragments; /* # of available fragments (partially usend ones not counted) */ + int fragstotal; /* Total # of fragments allocated */ + int fragsize; /* Size of a fragment in bytes */ + int bytes; /* Available space in bytes (includes partially used fragments) */ + /* Note! 'bytes' could be more than fragments*fragsize */ +} audio_buf_info; + +#define SNDCTL_DSP_GETOSPACE __SIOR ('P',12, audio_buf_info) +#define SNDCTL_DSP_GETISPACE __SIOR ('P',13, audio_buf_info) +#define SNDCTL_DSP_NONBLOCK __SIO ('P',14) /* Obsolete. Not supported */ +#define SNDCTL_DSP_GETCAPS __SIOR ('P',15, int) +# define DSP_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */ +# define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */ +# define DSP_CAP_REALTIME 0x00000200 /* Not in use */ +# define DSP_CAP_BATCH 0x00000400 /* Device has some kind of */ + /* internal buffers which may */ + /* cause some delays and */ + /* decrease precision of timing */ +# define DSP_CAP_COPROC 0x00000800 /* Has a coprocessor */ + /* Sometimes it's a DSP */ + /* but usually not */ +# define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ +# define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */ +# define DSP_CAP_MULTI 0x00004000 /* Supports multiple open */ +# define DSP_CAP_BIND 0x00008000 /* Supports binding to front/rear/center/lfe */ +# define DSP_CAP_INPUT 0x00010000 /* Supports recording */ +# define DSP_CAP_OUTPUT 0x00020000 /* Supports playback */ +# define DSP_CAP_VIRTUAL 0x00040000 /* Virtuial device */ +/* 0x00040000 and 0x00080000 reserved for future use */ + +/* Analog/digital control capabilities */ +# define DSP_CAP_ANALOGOUT 0x00100000 +# define DSP_CAP_ANALOGIN 0x00200000 +# define DSP_CAP_DIGITALOUT 0x00400000 +# define DSP_CAP_DIGITALIN 0x00800000 +# define DSP_CAP_ADMASK 0x00f00000 +/* + * NOTE! (capabilities & DSP_CAP_ADMASK)==0 means just that the + * digital/analog interface control features are not supported by the + * device/driver. However the device still supports analog, digital or + * both inputs/outputs (depending on the device). See the OSS Programmer's + * Guide for full details. + */ +# define DSP_CAP_SHADOW 0x01000000 /* "Shadow" device */ + +/* + * Preferred channel usage. These bits can be used to + * give recommendations to the application. Used by few drivers. + * For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that + * the device works best in mono mode. However it doesn't necessarily mean + * that the device cannot be used in stereo. These bits should only be used + * special applications such as multi track hard disk recorders to find out + * the initial setup. However the user should be able to override this + * selection. + * + * To find out which modes are actually supported the application should + * try to select them using SNDCTL_DSP_CHANNELS. + */ +# define DSP_CH_MASK 0x06000000 /* Mask */ +# define DSP_CH_ANY 0x00000000 /* No preferred mode */ +# define DSP_CH_MONO 0x02000000 +# define DSP_CH_STEREO 0x04000000 +# define DSP_CH_MULTI 0x06000000 /* More than two channels */ + +# define DSP_CAP_SLAVE 0x08000000 /* "Slave" device */ +# define DSP_CAP_FREERATE 0x10000000 + +#define SNDCTL_DSP_GETTRIGGER __SIOR ('P',16, int) +#define SNDCTL_DSP_SETTRIGGER __SIOW ('P',16, int) +# define PCM_ENABLE_INPUT 0x00000001 +# define PCM_ENABLE_OUTPUT 0x00000002 + +typedef struct count_info +{ + unsigned int bytes; /* Total # of bytes processed */ + int blocks; /* # of fragment transitions since last time */ + int ptr; /* Current DMA pointer value */ +} count_info; + +#define SNDCTL_DSP_GETIPTR __SIOR ('P',17, count_info) +#define SNDCTL_DSP_GETOPTR __SIOR ('P',18, count_info) + +typedef struct buffmem_desc +{ + unsigned *buffer; + int size; +} buffmem_desc; +#define SNDCTL_DSP_MAPINBUF __SIOR ('P', 19, buffmem_desc) +#define SNDCTL_DSP_MAPOUTBUF __SIOR ('P', 20, buffmem_desc) +#define SNDCTL_DSP_SETSYNCRO __SIO ('P', 21) +#define SNDCTL_DSP_SETDUPLEX __SIO ('P', 22) + +/* + * Application's profile defines the way how playback underrun situations + * should be handled. + * + * APF_NORMAL (the default) and APF_NETWORK make the driver to cleanup the + * playback buffer whenever an underrun occurs. This consumes some time + * prevents looping the existing buffer. + * APF_CPUINTENS is intended to be set by CPU intensive applications which + * are likely to run out of time occasionally. In this mode the buffer cleanup + * is disabled which saves CPU time but also let's the previous buffer content + * to be played during the "pause" after the underrun. + */ +#define SNDCTL_DSP_PROFILE __SIOW ('P', 23, int) +#define APF_NORMAL 0 /* Normal applications */ +#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */ +#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */ + +#define SNDCTL_DSP_GETODELAY __SIOR ('P', 23, int) +#define SNDCTL_DSP_GETOUTVOL __SIOR ('P', 24, int) +#define SNDCTL_DSP_SETOUTVOL __SIOWR('P', 24, int) + +typedef struct audio_errinfo +{ + int play_underruns; + int rec_overruns; + unsigned int play_ptradjust; + unsigned int rec_ptradjust; + int play_errorcount; + int rec_errorcount; + int play_lasterror; + int rec_lasterror; + long play_errorparm; + long rec_errorparm; + int filler[16]; +} audio_errinfo; + +#define SNDCTL_DSP_GETERROR __SIOR ('P', 25, audio_errinfo) + +typedef struct oss_digital_control +{ + unsigned int caps; +#define DIG_CBITIN_NONE 0x00000000 +#define DIG_CBITIN_LIMITED 0x00000001 +#define DIG_CBITIN_DATA 0x00000002 +#define DIG_CBITIN_BYTE0 0x00000004 +#define DIG_CBITIN_FULL 0x00000008 +#define DIG_CBITIN_MASK 0x0000000f +#define DIG_CBITOUT_NONE 0x00000000 +#define DIG_CBITOUT_LIMITED 0x00000010 +#define DIG_CBITOUT_BYTE0 0x00000020 +#define DIG_CBITOUT_FULL 0x00000040 +#define DIG_CBITOUT_DATA 0x00000080 +#define DIG_CBITOUT_MASK 0x000000f0 +#define DIG_UBITIN 0x00000100 +#define DIG_UBITOUT 0x00000200 +#define DIG_VBITOUT 0x00000400 +#define DIG_OUTRATE 0x00000800 +#define DIG_INRATE 0x00001000 +#define DIG_INBITS 0x00002000 +#define DIG_OUTBITS 0x00004000 +#define DIG_EXACT 0x00010000 +#define DIG_PRO 0x00020000 +#define DIG_CONSUMER 0x00040000 +#define DIG_PASSTHROUGH 0x00080000 +#define DIG_OUTSEL 0x00100000 + + unsigned int valid; +#define VAL_CBITIN 0x00000001 +#define VAL_UBITIN 0x00000002 +#define VAL_CBITOUT 0x00000004 +#define VAL_UBITOUT 0x00000008 +#define VAL_ISTATUS 0x00000010 +#define VAL_IRATE 0x00000020 +#define VAL_ORATE 0x00000040 +#define VAL_INBITS 0x00000080 +#define VAL_OUTBITS 0x00000100 +#define VAL_REQUEST 0x00000200 +#define VAL_OUTSEL 0x00000400 + +#define VAL_OUTMASK (VAL_CBITOUT|VAL_UBITOUT|VAL_ORATE|VAL_OUTBITS|VAL_OUTSEL) + + unsigned int request, param; +#define SPD_RQ_PASSTHROUGH 1 + + unsigned char cbitin[24]; + unsigned char ubitin[24]; + unsigned char cbitout[24]; + unsigned char ubitout[24]; + + unsigned int outsel; +#define OUTSEL_DIGITAL 1 +#define OUTSEL_ANALOG 2 +#define OUTSEL_BOTH (OUTSEL_DIGITAL|OUTSEL_ANALOG) + + int in_data; /* Audio/data if autodetectable by the receiver */ +#define IND_UNKNOWN 0 +#define IND_AUDIO 1 +#define IND_DATA 2 + + int in_locked; /* Receiver locked */ +#define LOCK_NOT_INDICATED 0 +#define LOCK_UNLOCKED 1 +#define LOCK_LOCKED 2 + + int in_quality; /* Input signal quality */ +#define IN_QUAL_NOT_INDICATED 0 +#define IN_QUAL_POOR 1 +#define IN_QUAL_GOOD 2 + + int in_vbit, out_vbit; /* V bits */ +#define VBIT_NOT_INDICATED 0 +#define VBIT_OFF 1 +#define VBIT_ON 2 + + unsigned int in_errors; /* Various input errro conditions */ +#define INERR_CRC 0x0001 +#define INERR_QCODE_CRC 0x0002 +#define INERR_PARITY 0x0004 +#define INERR_BIPHASE 0x0008 + + int srate_in, srate_out; + int bits_in, bits_out; + + int filler[32]; +} oss_digital_control; + +#define SNDCTL_DSP_READCTL __SIOWR('P', 26, oss_digital_control) +#define SNDCTL_DSP_WRITECTL __SIOWR('P', 27, oss_digital_control) + +typedef struct oss_syncgroup +{ + int id; + int mode; + int filler[16]; +} oss_syncgroup; + +#define SNDCTL_DSP_SYNCGROUP __SIOWR('P', 28, oss_syncgroup) +#define SNDCTL_DSP_SYNCSTART __SIOW ('P', 29, int) + +/* + * "cooked" mode enables software based conversions for sample rate, sample + * format (bits) and number of channels (mono/stereo). These conversions are + * required with some devices that support only one sample rate or just stereo + * to let the applications to use other formats. The cooked mode is enabled by + * default. However it's necessary to disable this mode when mmap() is used or + * when very deterministic timing is required. SNDCTL_DSP_COOKEDMODE is an + * optional call introduced in OSS 3.9.6f. It's _error return must be ignored_ + * since normally this call will return erno=EINVAL. + * + * SNDCTL_DSP_COOKEDMODE must be called immediately after open before doing + * anything else. Otherwise the call will not have any effect. + */ +#define SNDCTL_DSP_COOKEDMODE __SIOW ('P', 30, int) + +/* + * SNDCTL_DSP_SILENCE and SNDCTL_DSP_SKIP are new calls in OSS 3.99.0 + * that can be used to implement pause/continue during playback (no effect + * on recording). + */ +#define SNDCTL_DSP_SILENCE __SIO ('P', 31) +#define SNDCTL_DSP_SKIP __SIO ('P', 32) +#define SNDCTL_DSP_RESET_INPUT __SIO ('P', 33) +#define SNDCTL_DSP_RESET_OUTPUT __SIO ('P', 34) +#define SNDCTL_DSP_LOW_WATER __SIOW ('P', 34, int) + +#ifndef OSS_NO_LONG_LONG +typedef struct +{ + long long samples; + int fifo_samples; + int filler[32]; /* For future use */ +} oss_count_t; + +#define SNDCTL_DSP_CURRENT_IPTR __SIOR ('P', 35, oss_count_t) +#define SNDCTL_DSP_CURRENT_OPTR __SIOR ('P', 36, oss_count_t) +#endif + +#define SNDCTL_DSP_GET_RECSRC_NAMES __SIOR ('P', 37, oss_mixer_enuminfo) +#define SNDCTL_DSP_GET_RECSRC __SIOR ('P', 38, int) +#define SNDCTL_DSP_SET_RECSRC __SIOWR('P', 38, int) + +#define SNDCTL_DSP_GET_PLAYTGT_NAMES __SIOR ('P', 39, oss_mixer_enuminfo) +#define SNDCTL_DSP_GET_PLAYTGT __SIOR ('P', 40, int) +#define SNDCTL_DSP_SET_PLAYTGT __SIOWR('P', 40, int) + +#define SNDCTL_DSP_GETCHANNELMASK __SIOWR('P', 64, int) +#define SNDCTL_DSP_BIND_CHANNEL __SIOWR('P', 65, int) +# define DSP_BIND_QUERY 0x00000000 +# define DSP_BIND_FRONT 0x00000001 +# define DSP_BIND_SURR 0x00000002 +# define DSP_BIND_CENTER_LFE 0x00000004 +# define DSP_BIND_HANDSET 0x00000008 +# define DSP_BIND_MIC 0x00000010 +# define DSP_BIND_MODEM1 0x00000020 +# define DSP_BIND_MODEM2 0x00000040 +# define DSP_BIND_I2S 0x00000080 +# define DSP_BIND_SPDIF 0x00000100 +# define DSP_BIND_REAR 0x00000200 + +/********************************** + * IOCTL commands for /dev/mixer * + **********************************/ + +/* + * Mixer devices + * + * There can be up to 20 different analog mixer channels. The + * SOUND_MIXER_NRDEVICES gives the currently supported maximum. + * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells + * the devices supported by the particular mixer. + */ + +#define SOUND_MIXER_NRDEVICES 28 +#define SOUND_MIXER_VOLUME 0 +#define SOUND_MIXER_BASS 1 +#define SOUND_MIXER_TREBLE 2 +#define SOUND_MIXER_SYNTH 3 +#define SOUND_MIXER_PCM 4 +#define SOUND_MIXER_SPEAKER 5 +#define SOUND_MIXER_LINE 6 +#define SOUND_MIXER_MIC 7 +#define SOUND_MIXER_CD 8 +#define SOUND_MIXER_IMIX 9 /* Recording monitor */ +#define SOUND_MIXER_ALTPCM 10 +#define SOUND_MIXER_RECLEV 11 /* Recording level */ +#define SOUND_MIXER_IGAIN 12 /* Input gain */ +#define SOUND_MIXER_OGAIN 13 /* Output gain */ +/* + * Some soundcards have three line level inputs (line, aux1 and aux2). + * Since each card manufacturer has assigned different meanings to + * these inputs, it's impractical to assign specific meanings + * (eg line, cd, synth etc.) to them. + */ +#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */ +#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */ +#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */ +#define SOUND_MIXER_DIGITAL1 17 /* Digital I/O 1 */ +#define SOUND_MIXER_DIGITAL2 18 /* Digital I/O 2 */ +#define SOUND_MIXER_DIGITAL3 19 /* Digital I/O 3 */ +#define SOUND_MIXER_PHONE 20 /* Phone */ +#define SOUND_MIXER_MONO 21 /* Mono Output */ +#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */ +#define SOUND_MIXER_RADIO 23 /* Radio in */ +#define SOUND_MIXER_DEPTH 24 /* Surround depth */ +#define SOUND_MIXER_REARVOL 25 /* Rear/Surround speaker vol */ +#define SOUND_MIXER_CENTERVOL 26 /* Center/LFE speaker vol */ +#define SOUND_MIXER_SURRVOL 27 /* Mid-Surround (8speaker) vol */ + +/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */ +/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */ +#define SOUND_ONOFF_MIN 28 +#define SOUND_ONOFF_MAX 30 + +/* Note! Number 31 cannot be used since the sign bit is reserved */ +#define SOUND_MIXER_NONE 31 + +/* + * The following unsupported macros are no longer functional. + * Use SOUND_MIXER_PRIVATE# macros in future. + */ +#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE +#define SOUND_MIXER_MUTE SOUND_MIXER_NONE +#define SOUND_MIXER_LOUD SOUND_MIXER_NONE + +#define SOUND_DEVICE_LABELS \ + {"Vol ", "Bass ", "Treble", "Synth", "Pcm ", "Speaker ", "Line ", \ + "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \ + "Aux1", "Aux2", "Aux3", "Digital1", "Digital2", "Digital3", \ + "Phone", "Mono", "Video", "Radio", "Depth", \ + "Rear", "Center", "Surround"} + +#define SOUND_DEVICE_NAMES \ + {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \ + "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \ + "aux1", "aux2", "aux3", "dig1", "dig2", "dig3", \ + "phone", "mono", "video", "radio", "depth", \ + "rear", "center", "surround"} + +/* Device bitmask identifiers */ + +#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */ +#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */ +#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */ +#define SOUND_MIXER_CAPS 0xfc +# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ +# define SOUND_CAP_LAYOUT_B 0x00000002 /* For internal use only */ +# define SOUND_CAP_NOLEGACY 0x00000004 /* For internal use only */ +# define SOUND_CAP_NORECSRC 0x00000008 +#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */ + +/* OSS/Free ONLY */ +#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */ +#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */ +/* OSS/Free ONLY */ + +/* Device mask bits */ + +#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME) +#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS) +#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE) +#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH) +#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM) +#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER) +#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE) +#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC) +#define SOUND_MASK_CD (1 << SOUND_MIXER_CD) +#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX) +#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM) +#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV) +#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN) +#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN) +#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1) +#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2) +#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3) +#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1) +#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2) +#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3) +#define SOUND_MASK_MONO (1 << SOUND_MIXER_MONO) +#define SOUND_MASK_PHONE (1 << SOUND_MIXER_PHONE) +#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO) +#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO) +#define SOUND_MASK_DEPTH (1 << SOUND_MIXER_DEPTH) +#define SOUND_MASK_MONITOR (1 << SOUND_MIXER_MONITOR) +#define SOUND_MASK_REARVOL (1 << SOUND_MIXER_REARVOL) +#define SOUND_MASK_CENTERVOL (1 << SOUND_MIXER_CENTERVOL) +#define SOUND_MASK_SURRVOL (1 << SOUND_MIXER_SURRVOL) + +/* Obsolete macros */ +#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE) +#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE) +#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD) + +#define MIXER_READ(dev) __SIOR('M', dev, int) +#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME) +#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS) +#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE) +#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH) +#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM) +#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER) +#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE) +#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC) +#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD) +#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX) +#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM) +#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1) +#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2) +#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3) + +/* Obsolete macros */ +#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE) +#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE) +#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD) + +#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC) +#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK) +#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK) +#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS) +#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS) + +#define MIXER_WRITE(dev) __SIOWR('M', dev, int) +#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME) +#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS) +#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE) +#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH) +#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM) +#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER) +#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE) +#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC) +#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD) +#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX) +#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM) +#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1) +#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2) +#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3) + +/* Obsolete macros */ +#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE) +#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE) +#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD) + +#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC) + +typedef struct mixer_info +{ + char id[16]; + char name[32]; + int modify_counter; + int fillers[10]; +} mixer_info; + +typedef struct _old_mixer_info +{ /* Obsolete */ + char id[16]; + char name[32]; +} _old_mixer_info; + +#define SOUND_MIXER_INFO __SIOR ('M', 101, mixer_info) +#define SOUND_OLD_MIXER_INFO __SIOR ('M', 101, _old_mixer_info) + +/* + * A mechanism for accessing "proprietary" mixer features. This method + * permits passing 128 bytes of arbitrary data between a mixer application + * and the mixer driver. Interpretation of the record is defined by + * the particular mixer driver. + */ +typedef unsigned char mixer_record[128]; + +#define SOUND_MIXER_ACCESS __SIOWR('M', 102, mixer_record) + +/* + * Two ioctls for special souncard function (OSS/Free only) + */ +#define SOUND_MIXER_AGC _SIOWR('M', 103, int) +#define SOUND_MIXER_3DSE _SIOWR('M', 104, int) +/* + * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers. + * These features can be used when accessing device specific features. + */ +#define SOUND_MIXER_PRIVATE1 __SIOWR('M', 111, int) +#define SOUND_MIXER_PRIVATE2 __SIOWR('M', 112, int) +#define SOUND_MIXER_PRIVATE3 __SIOWR('M', 113, int) +#define SOUND_MIXER_PRIVATE4 __SIOWR('M', 114, int) +#define SOUND_MIXER_PRIVATE5 __SIOWR('M', 115, int) + +/* + * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used + * for querying current mixer settings from the driver and for loading + * default volume settings _prior_ activating the mixer (loading + * doesn't affect current state of the mixer hardware). These calls + * are for internal use by the driver software only. + */ + +typedef struct mixer_vol_table +{ + int num; /* Index to volume table */ + char name[32]; + int levels[32]; +} mixer_vol_table; + +#define SOUND_MIXER_GETLEVELS __SIOWR('M', 116, mixer_vol_table) +#define SOUND_MIXER_SETLEVELS __SIOWR('M', 117, mixer_vol_table) + +/* + * An ioctl for identifying the driver version. It will return value + * of the SOUND_VERSION macro used when compiling the driver. + * This call was introduced in OSS version 3.6 and it will not work + * with earlier versions (returns EINVAL). + */ +#define OSS_GETVERSION __SIOR ('M', 118, int) +/* + * Calls to set/get the recording gain for the currently active + * recording source. These calls automatically map to the right control. + * Note that these calls are not supported by all drivers. In this case + * the call will return -1 with errno set to EINVAL + * + * The _MONGAIN work in similar way but set/get the monitoring gain for + * the currently selected recording source. + */ +#define SOUND_MIXER_READ_RECGAIN __SIOR ('M', 119, int) +#define SOUND_MIXER_WRITE_RECGAIN __SIOWR('M', 119, int) +#define SOUND_MIXER_READ_MONGAIN __SIOR ('M', 120, int) +#define SOUND_MIXER_WRITE_MONGAIN __SIOWR('M', 120, int) + +/* The following call is for driver development time purposes. It's not + * present in any released drivers. + */ +typedef unsigned char oss_reserved_t[512]; +#define SOUND_MIXER_RESERVED __SIOWR('M', 121, oss_reserved_t) + +/**************************************************** + * Extended mixer interface (OSS 3.99.0 and later) * + ****************************************************/ +#define SYSINFO_FILL_SIZE 256 + +typedef struct oss_sysinfo +{ + char product[32]; /* For example OSS/Free, OSS/Linux or OSS/Solaris */ + char version[32]; /* For example 4.0a */ + int versionnum; /* See OSS_GETVERSION */ + char options[128]; /* Reserved */ + + int numaudios; /* # of audio/dsp devices */ + int openedaudio[8]; /* Bit mask telling which audio devices are busy */ + + int numsynths; /* # of availavle synth devices */ + int nummidis; /* # of available MIDI ports */ + int numtimers; /* # of available timer devices */ + int nummixers; /* # of mixer devices */ + + int filler[SYSINFO_FILL_SIZE]; /* For future expansion (set to -1) */ +} oss_sysinfo; + +typedef struct oss_mixext +{ + int dev; /* Mixer device number */ + int ctrl; /* Controller number */ + int type; /* Entry type */ +# define MIXT_DEVROOT 0 /* Device root entry */ +# define MIXT_GROUP 1 /* Controller group */ +# define MIXT_ONOFF 2 /* OFF (0) or ON (1) */ +# define MIXT_ENUM 3 /* Enumerated (0 to maxvalue) */ +# define MIXT_MONOSLIDER 4 /* Mono slider (0 to 100) */ +# define MIXT_STEREOSLIDER 5 /* Stereo slider (dual 0 to 100) */ +# define MIXT_MESSAGE 6 /* (Readable) textual message */ +# define MIXT_MONOVU 7 /* VU meter value (mono) */ +# define MIXT_STEREOVU 8 /* VU meter value (stereo) */ +# define MIXT_MONOPEAK 9 /* VU meter peak value (mono) */ +# define MIXT_STEREOPEAK 10 /* VU meter peak value (stereo) */ +# define MIXT_RADIOGROUP 11 /* Radio button group */ +# define MIXT_MARKER 12 /* Separator between normal and extension entries */ +# define MIXT_VALUE 13 /* Decimal value entry */ +# define MIXT_HEXVALUE 14 /* Hexadecimal value entry */ +# define MIXT_MONODB 15 /* Mono atten. slider (0 to -144) */ +# define MIXT_STEREODB 16 /* Stereo atten. slider (dual 0 to -144) */ +# define MIXT_SLIDER 17 /* Slider (mono) with full integer range */ +# define MIXT_3D 18 + + /* Possible value range (minvalue to maxvalue) */ + /* Note that maxvalue may also be smaller than minvalue */ + int maxvalue; + int minvalue; + + int flags; +# define MIXF_READABLE 0x00000001 /* Has readable value */ +# define MIXF_WRITEABLE 0x00000002 /* Has writeable value */ +# define MIXF_POLL 0x00000004 /* May change itself */ +# define MIXF_HZ 0x00000008 /* Herz scale */ +# define MIXF_STRING 0x00000010 /* Use dynamic extensions for value */ +# define MIXF_DYNAMIC 0x00000010 /* Supports dynamic extensions */ + char id[16]; /* Mnemonic ID (mainly for internal use) */ + int parent; /* Entry# of parent (group) node (-1 if root) */ + + int dummy; /* Internal use */ + + int timestamp; + + char data[64]; /* Misc data (entry type dependent) */ + unsigned char enum_present[32]; /* Mask of allowed enum values */ + int control_no; /* SOUND_MIXER_VOLUME..SOUND_MIXER_MIDI */ + /* (-1 means not indicated) */ + int desc; /* Descriptive code. For future use. */ + char extname[32]; + int filler[8]; +} oss_mixext; + +typedef struct oss_mixext_root +{ + char id[16]; + char name[48]; +} oss_mixext_root; + +typedef struct oss_mixer_value +{ + int dev; + int ctrl; + int value; + int flags; /* Reserved for future use. Initialize to 0 */ + int timestamp; /* Must be set to oss_mixext.timestamp */ + int filler[8]; /* Reserved for future use. Initialize to 0 */ +} oss_mixer_value; + +#define OSS_ENUM_MAXVALUE 255 +typedef struct oss_mixer_enuminfo +{ + int dev; + int ctrl; + int nvalues; + short strindex[OSS_ENUM_MAXVALUE]; + char strings[3000]; +} oss_mixer_enuminfo; + +#define OPEN_READ PCM_ENABLE_INPUT +#define OPEN_WRITE PCM_ENABLE_OUTPUT +#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) + +typedef struct oss_audioinfo +{ + int dev; /* Audio device number */ + char name[64]; + int busy; /* 0, OPEN_READ, OPEN_WRITE or OPEN_READWRITE */ + int pid; + int caps; /* DSP_CAP_INPUT, DSP_CAP_OUTPUT */ + int iformats, oformats; + int magic; /* Reserved for internal use */ + char cmd[64]; /* Command using the device */ + int card_number; + int port_number; + int mixer_dev; + int real_device; /* This is the right /dev/dsp# device to open */ + int enabled; /* 1=enabled, 0=device not ready at this moment */ + int flags; /* For internal use only - no practical meaning */ + int min_rate, max_rate; /* Sample rate limits */ + int min_channels, max_channels; /* Number of channels supported */ + int binding; /* DSP_BIND_FRONT, etc. 0 means undefined */ + int rate_source; + char handle[32]; + int nrates, rates[20]; /* Please read the manual before using these */ + int filler[215]; +} oss_audioinfo; + +#define OSS_SYSINFO __SIOR ('X', 1, oss_sysinfo) + +#define SNDCTL_MIX_NRMIX __SIOR ('X', 2, int) +#define SNDCTL_MIX_NREXT __SIOWR('X', 3, int) +#define SNDCTL_MIX_EXTINFO __SIOWR('X', 4, oss_mixext) +#define SNDCTL_MIX_READ __SIOWR('X', 5, oss_mixer_value) +#define SNDCTL_MIX_WRITE __SIOWR('X', 6, oss_mixer_value) + +#define SNDCTL_AUDIOINFO __SIOWR('X', 7, oss_audioinfo) +#define SNDCTL_MIX_ENUMINFO __SIOWR('X', 8, oss_mixer_enuminfo) + +/* ioctl codes 'X', 200-255 are reserved for internal use */ + +/* + * Level 2 event types for /dev/sequencer + */ + +/* + * The 4 most significant bits of byte 0 specify the class of + * the event: + * + * 0x8X = system level events, + * 0x9X = device/port specific events, event[1] = device/port, + * The last 4 bits give the subtype: + * 0x02 = Channel event (event[3] = chn). + * 0x01 = note event (event[4] = note). + * (0x01 is not used alone but always with bit 0x02). + * event[2] = MIDI message code (0x80=note off etc.) + * + */ + +#define EV_SEQ_LOCAL 0x80 +#define EV_TIMING 0x81 +#define EV_CHN_COMMON 0x92 +#define EV_CHN_VOICE 0x93 +#define EV_SYSEX 0x94 +#define EV_SYSTEM 0x95 /* MIDI system and real time messages (input only) */ +/* + * Event types 200 to 220 are reserved for application use. + * These numbers will not be used by the driver. + */ + +/* + * Events for event type EV_CHN_VOICE + */ + +#define MIDI_NOTEOFF 0x80 +#define MIDI_NOTEON 0x90 +#define MIDI_KEY_PRESSURE 0xA0 + +/* + * Events for event type EV_CHN_COMMON + */ + +#define MIDI_CTL_CHANGE 0xB0 +#define MIDI_PGM_CHANGE 0xC0 +#define MIDI_CHN_PRESSURE 0xD0 +#define MIDI_PITCH_BEND 0xE0 + +#define MIDI_SYSTEM_PREFIX 0xF0 + +/* + * Timer event types + */ +#define TMR_WAIT_REL 1 /* Time relative to the prev time */ +#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */ +#define TMR_STOP 3 +#define TMR_START 4 +#define TMR_CONTINUE 5 +#define TMR_TEMPO 6 +#define TMR_ECHO 8 +#define TMR_CLOCK 9 /* MIDI clock */ +#define TMR_SPP 10 /* Song position pointer */ +#define TMR_TIMESIG 11 /* Time signature */ + +/* + * Local event types + */ +#define LOCL_STARTAUDIO 1 +#define LOCL_STARTAUDIO2 2 +#define LOCL_STARTAUDIO3 3 +#define LOCL_STARTAUDIO4 4 + +#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) +/* + * Some convenience macros to simplify programming of the + * /dev/sequencer interface + * + * These macros define the API which should be used when possible. + */ +#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() + +void seqbuf_dump (void); /* This function must be provided by programs */ + +EXTERNC int OSS_init (int seqfd, int buflen); +EXTERNC void OSS_seqbuf_dump (int fd, unsigned char *buf, int buflen); +EXTERNC void OSS_seq_advbuf (int len, int fd, unsigned char *buf, int buflen); +EXTERNC void OSS_seq_needbuf (int len, int fd, unsigned char *buf, + int buflen); +EXTERNC void OSS_patch_caching (int dev, int chn, int patch, int fd, + unsigned char *buf, int buflen); +EXTERNC void OSS_drum_caching (int dev, int chn, int patch, int fd, + unsigned char *buf, int buflen); +EXTERNC void OSS_write_patch (int fd, unsigned char *buf, int len); +EXTERNC int OSS_write_patch2 (int fd, unsigned char *buf, int len); + +#define SEQ_PM_DEFINES int __foo_bar___ +#ifdef OSSLIB +# define SEQ_USE_EXTBUF() \ + EXTERNC unsigned char *_seqbuf; \ + EXTERNC int _seqbuflen;EXTERNC int _seqbufptr +# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len +# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) +# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) +# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) + +# define SEQ_LOAD_GMINSTR(dev, instr) \ + OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) +# define SEQ_LOAD_GMDRUM(dev, drum) \ + OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) +#else /* !OSSLIB */ + +# define SEQ_LOAD_GMINSTR(dev, instr) +# define SEQ_LOAD_GMDRUM(dev, drum) + +# define SEQ_USE_EXTBUF() \ + EXTERNC unsigned char _seqbuf[]; \ + EXTERNC int _seqbuflen;EXTERNC int _seqbufptr + +#ifndef USE_SIMPLE_MACROS +/* Sample seqbuf_dump() implementation: + * + * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes + * + * int seqfd; -- The file descriptor for /dev/sequencer. + * + * void + * seqbuf_dump () + * { + * if (_seqbufptr) + * if (write (seqfd, _seqbuf, _seqbufptr) == -1) + * { + * perror ("write /dev/sequencer"); + * exit (-1); + * } + * _seqbufptr = 0; + * } + */ + +#define SEQ_DEFINEBUF(len) \ + unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0 +#define _SEQ_NEEDBUF(len) \ + if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump() +#define _SEQ_ADVBUF(len) _seqbufptr += len +#define SEQ_DUMPBUF seqbuf_dump +#else +/* + * This variation of the sequencer macros is used just to format one event + * using fixed buffer. + * + * The program using the macro library must define the following macros before + * using this library. + * + * #define _seqbuf name of the buffer (unsigned char[]) + * #define _SEQ_ADVBUF(len) If the applic needs to know the exact + * size of the event, this macro can be used. + * Otherwise this must be defined as empty. + * #define _seqbufptr Define the name of index variable or 0 if + * not required. + */ +#define _SEQ_NEEDBUF(len) /* empty */ +#endif +#endif /* !OSSLIB */ + +#define SEQ_VOLUME_MODE(dev, mode) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ + _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ + _seqbuf[_seqbufptr+2] = (dev);\ + _seqbuf[_seqbufptr+3] = (mode);\ + _seqbuf[_seqbufptr+4] = 0;\ + _seqbuf[_seqbufptr+5] = 0;\ + _seqbuf[_seqbufptr+6] = 0;\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} + +/* + * Midi voice messages + */ + +#define _CHN_VOICE(dev, event, chn, note, parm) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_CHN_VOICE;\ + _seqbuf[_seqbufptr+1] = (dev);\ + _seqbuf[_seqbufptr+2] = (event);\ + _seqbuf[_seqbufptr+3] = (chn);\ + _seqbuf[_seqbufptr+4] = (note);\ + _seqbuf[_seqbufptr+5] = (parm);\ + _seqbuf[_seqbufptr+6] = (0);\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} + +#define SEQ_START_NOTE(dev, chn, note, vol) \ + _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol) + +#define SEQ_STOP_NOTE(dev, chn, note, vol) \ + _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol) + +#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \ + _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure) + +/* + * Midi channel messages + */ + +#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_CHN_COMMON;\ + _seqbuf[_seqbufptr+1] = (dev);\ + _seqbuf[_seqbufptr+2] = (event);\ + _seqbuf[_seqbufptr+3] = (chn);\ + _seqbuf[_seqbufptr+4] = (p1);\ + _seqbuf[_seqbufptr+5] = (p2);\ + *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ + _SEQ_ADVBUF(8);} +/* + * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits + * sending any MIDI bytes but it's absolutely not possible. Trying to do + * so _will_ cause problems with MPU401 intelligent mode). + * + * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be + * sent by calling SEQ_SYSEX() several times (there must be no other events + * between them). First sysex fragment must have 0xf0 in the first byte + * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte + * between these sysex start and end markers cannot be larger than 0x7f. Also + * lengths of each fragments (except the last one) must be 6. + * + * Breaking the above rules may work with some MIDI ports but is likely to + * cause fatal problems with some other devices (such as MPU401). + */ +#define SEQ_SYSEX(dev, buf, len) \ + {int ii, ll=(len); \ + unsigned char *bufp=buf;\ + if (ll>6)ll=6;\ + _SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_SYSEX;\ + _seqbuf[_seqbufptr+1] = (dev);\ + for(ii=0;ii>8)&0xff);\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} +/* + * The following 5 macros are incorrectly implemented and obsolete. + * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead. + */ +#define SEQ_PITCHBEND(dev, voice, value) \ + SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value) +#define SEQ_BENDER_RANGE(dev, voice, value) \ + SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value) +#define SEQ_EXPRESSION(dev, voice, value) \ + SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128) +#define SEQ_MAIN_VOLUME(dev, voice, value) \ + SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100) +#define SEQ_PANNING(dev, voice, pos) \ + SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) + +/* + * Timing and syncronization macros + */ + +#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr+0] = EV_TIMING; \ + _seqbuf[_seqbufptr+1] = (ev); \ + _seqbuf[_seqbufptr+2] = 0;\ + _seqbuf[_seqbufptr+3] = 0;\ + *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ + _SEQ_ADVBUF(8);} + +#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0) +#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0) +#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0) +#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks) +#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks) +#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key) +#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value) +#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos) +#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig) + +/* + * Local control events + */ + +#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ + _seqbuf[_seqbufptr+1] = (ev); \ + _seqbuf[_seqbufptr+2] = 0;\ + _seqbuf[_seqbufptr+3] = 0;\ + *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ + _SEQ_ADVBUF(8);} + +#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask) +#define SEQ_PLAYAUDIO2(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO2, devmask) +#define SEQ_PLAYAUDIO3(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO3, devmask) +#define SEQ_PLAYAUDIO4(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO4, devmask) +/* + * Events for the level 1 interface only + */ + +#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\ + _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\ + _seqbuf[_seqbufptr+1] = (byte);\ + _seqbuf[_seqbufptr+2] = (device);\ + _seqbuf[_seqbufptr+3] = 0;\ + _SEQ_ADVBUF(4);} + +/* + * Patch loading. + */ +#ifdef OSSLIB +# define SEQ_WRPATCH(patchx, len) \ + OSS_write_patch(seqfd, (char*)(patchx), len) +# define SEQ_WRPATCH2(patchx, len) \ + OSS_write_patch2(seqfd, (char*)(patchx), len) +#else +# define SEQ_WRPATCH(patchx, len) \ + {if (_seqbufptr) SEQ_DUMPBUF();\ + if (write(seqfd, (char*)(patchx), len)==-1) \ + perror("Write patch: /dev/sequencer");} +# define SEQ_WRPATCH2(patchx, len) \ + (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) +#endif + +#endif + +#ifdef OSSLIB +extern int osslib_open (const char *path, int flags, int dummy); +extern void ossclose (int fd); +extern int osslib_write (int fd, const void *buf, int count); +extern int osslib_read (int fd, void *buf, int count); +extern int osslib_ioctl (int fd, unsigned int request, void *arg); +#else +# define osslib_open open +# define osslib_close close +# define osslib_write write +# define osslib_read read +# define osslib_ioctl ioctl +#endif + +#endif diff --git a/sys/linux/oss/include/sys/ultrasound.h b/sys/linux/oss/include/sys/ultrasound.h new file mode 100644 index 000000000..d42c6c632 --- /dev/null +++ b/sys/linux/oss/include/sys/ultrasound.h @@ -0,0 +1,96 @@ +#ifndef _ULTRASOUND_H_ +#define _ULTRASOUND_H_ +/* + * ultrasound.h - Macros for programming the Gravis Ultrasound + * These macros are extremely device dependent + * and not portable. + */ +#define COPYING2 Copyright (C) Hannu Savolainen and Dev Mazumdar 1997. All rights reserved. + +/* + * Private events for Gravis Ultrasound (GUS) + * + * Format: + * byte 0 - SEQ_PRIVATE (0xfe) + * byte 1 - Synthesizer device number (0-N) + * byte 2 - Command (see below) + * byte 3 - Voice number (0-31) + * bytes 4 and 5 - parameter P1 (unsigned short) + * bytes 6 and 7 - parameter P2 (unsigned short) + * + * Commands: + * Each command affects one voice defined in byte 3. + * Unused parameters (P1 and/or P2 *MUST* be initialized to zero). + * _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16) + * _GUS_VOICESAMPLE- ************ OBSOLETE ************* + * _GUS_VOICEON - Starts voice (P1=voice mode) + * _GUS_VOICEOFF - Stops voice (no parameters) + * _GUS_VOICEFADE - Stops the voice smoothly. + * _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode) + * _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7) + * _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz) + * _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) + * _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) + * (Like GUS_VOICEVOL but doesn't change the hw + * volume. It just updates volume in the voice table). + * + * _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume) + * _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate) + * _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode) + * _GUS_RAMPON - Starts volume ramping (no parameters) + * _GUS_RAMPOFF - Stops volume ramping (no parameters) + * _GUS_VOLUME_SCALE - Changes the volume calculation constants + * for all voices. + */ + +#define _GUS_NUMVOICES 0x00 +#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */ +#define _GUS_VOICEON 0x02 +#define _GUS_VOICEOFF 0x03 +#define _GUS_VOICEMODE 0x04 +#define _GUS_VOICEBALA 0x05 +#define _GUS_VOICEFREQ 0x06 +#define _GUS_VOICEVOL 0x07 +#define _GUS_RAMPRANGE 0x08 +#define _GUS_RAMPRATE 0x09 +#define _GUS_RAMPMODE 0x0a +#define _GUS_RAMPON 0x0b +#define _GUS_RAMPOFF 0x0c +#define _GUS_VOICEFADE 0x0d +#define _GUS_VOLUME_SCALE 0x0e +#define _GUS_VOICEVOL2 0x0f +#define _GUS_VOICE_POS 0x10 + +/* + * GUS API macros + */ + +#define _GUS_CMD(chn, voice, cmd, p1, p2) \ + {_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\ + _seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\ + _seqbuf[_seqbufptr+3] = voice;\ + *(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\ + *(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\ + _SEQ_ADVBUF(8);} + +#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0) +#define GUS_VOICESAMPLE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */ +#define GUS_VOICEON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0) +#define GUS_VOICEOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0) +#define GUS_VOICEFADE(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0) +#define GUS_VOICEMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0) +#define GUS_VOICEBALA(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0) +#define GUS_VOICEFREQ(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICEFREQ, \ + (p) & 0xffff, ((p) >> 16) & 0xffff) +#define GUS_VOICEVOL(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0) +#define GUS_VOICEVOL2(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0) +#define GUS_RAMPRANGE(chn, voice, low, high) _GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high)) +#define GUS_RAMPRATE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2)) +#define GUS_RAMPMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0) +#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0) +#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0) +#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2)) +#define GUS_VOICE_POS(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICE_POS, \ + (p) & 0xffff, ((p) >> 16) & 0xffff) + +#endif diff --git a/sys/linux/pk4/id_utils.py b/sys/linux/pk4/id_utils.py new file mode 100644 index 000000000..53f978bb6 --- /dev/null +++ b/sys/linux/pk4/id_utils.py @@ -0,0 +1,241 @@ +# a collection of utility functions to manipulate pak files + +import os, zipfile, md5, pdb + +# sorts in reverse alphabetical order like doom does for searching +def list_paks( path ): + files = os.listdir( path ) + for i in files: + if ( i[-4:] != '.pk4' ): + files.remove( i ) + files.sort() + files.reverse() + return files + +def list_files_in_pak( pak ): + files = [] + zippy = zipfile.ZipFile( pak ) + files += zippy.namelist() + files.sort() + return files + +# no sorting, blunt list of everything +def list_files_in_paks( path ): + files = [] + zippies = list_paks( path ) + for fname in zippies: + print fname + zippy = zipfile.ZipFile( os.path.join( path, fname ) ) + files += zippy.namelist() + # sort and remove dupes + dico = {} + for f in files: + dico[ f ] = 1 + files = dico.keys() + files.sort() + return files + +# build a dictionary of names -> ( pak name, md5 ) from a path of pk4s +def md5_in_paks( path ): + ret = {} + zippies = list_paks( path ) + for fname in zippies: + print fname + zippy = zipfile.ZipFile( os.path.join( path, fname ) ) + for file in zippy.namelist(): + if ( ret.has_key( file ) ): + continue + data = zippy.read( file ) + m = md5.new() + m.update( data ) + ret[ file ] = ( fname, m.hexdigest() ) + return ret + +# find which files need to be updated in a set of paks from an expanded list +# returns ( updated, not_found, {} ) +# ignores directories +# by default, no case match is done +# if case match is set, return ( updated, not_found, { zip case -> FS case } ) +# updated will contain the zip case name +def list_updated_files( pak_path, base_path, case_match = False ): + not_found = [] + updated = [] + case_table = {} + pak_md5 = md5_in_paks( pak_path ) + for file in pak_md5.keys(): + if ( file[-1] == '/' ): + continue + path = os.path.join( base_path, file ) + if ( case_match ): + ret = ifind( base_path, file ) + if ( not ret[ 0 ] ): + not_found.append( file ) + continue + else: + case_table[ path ] = ret[ 1 ] + path = os.path.join( base_path, ret[ 1 ] ) + try: + f = open( path ) + data = f.read() + f.close() + except: + if ( case_match ): + raise "internal error: ifind success but later read failed" + not_found.append( file ) + else: + m = md5.new() + m.update( data ) + if ( m.hexdigest() != pak_md5[ file ][ 1 ] ): + print file + updated.append( file ) + return ( updated, not_found, case_table ) + +# find which files are missing in the expanded path, and extract the directories +# returns ( files, dirs, missing ) +def status_files_for_path( path, infiles ): + files = [] + dirs = [] + missing = [] + for i in infiles: + test_path = os.path.join( path, i ) + if ( os.path.isfile( test_path ) ): + files.append( i ) + elif ( os.path.isdir( test_path ) ): + dirs.append( i ) + else: + missing.append( i ) + return ( files, dirs, missing ) + +# build a pak from a base path and a list of files +def build_pak( pak, path, files ): + zippy = zipfile.ZipFile( pak, 'w', zipfile.ZIP_DEFLATED ) + for i in files: + source_path = os.path.join( path, i ) + print source_path + zippy.write( source_path, i ) + zippy.close() + +# process the list of files after a run to update media +# dds/ -> verify all the .dds are present in zip ( case insensitive ) +# .wav -> verify that all .wav have a .ogg version in zip ( case insensitive ) +# .tga not in dds/ -> try to find a .dds for them +# work from a list of files, and a path to the base pak files +# files: text files with files line by line +# pak_path: the path to the pak files to compare against +# returns: ( [ missing ], [ bad ] ) +# bad are files the function didn't know what to do about ( bug ) +# missing are lowercased of all the files that where not matched in build +# the dds/ ones are all forced to .dds extension +# missing .wav are returned in the missing list both as .wav and .ogg +# ( that's handy when you need to fetch next ) +def check_files_against_build( files, pak_path ): + pak_list = list_files_in_paks( pak_path ) + # make it lowercase + tmp = [] + for i in pak_list: + tmp.append( i.lower() ) + pak_list = tmp + # read the files and make them lowercase + f = open( files ) + check_files = f.readlines() + f.close() + tmp = [] + for i in check_files: + s = i.lower() + s = s.replace( '\n', '' ) + s = s.replace( '\r', '' ) + tmp.append( s ) + check_files = tmp + # start processing + bad = [] + missing = [] + for i in check_files: + if ( i[ :4 ] == 'dds/' ): + if ( i[ len(i)-4: ] == '.tga' ): + i = i[ :-4 ] + '.dds' + elif ( i[ len(i)-4: ] != '.dds' ): + print 'File not understood: ' + i + bad.append( i ) + continue + try: + pak_list.index( i ) + except: + print 'Not found: ' + i + missing.append( i ) + elif ( i[ len(i)-4: ] == '.wav' ): + i = i[ :-4 ] + '.ogg' + try: + pak_list.index( i ) + except: + print 'Not found: ' + i + missing.append( i ) + missing.append( i[ :-4 ] + '.wav' ) + elif ( i[ len(i)-4: ] == '.tga' ): + # tga, not from dds/ + try: + pak_list.index( i ) + except: + print 'Not found: ' + i + missing.append( i ) + i = 'dds/' + i[ :-4 ] + '.dds' + print 'Add dds : ' + i + missing.append( i ) + else: + try: + pak_list.index( i ) + except: + print 'Not found: ' + i + missing.append( i ) + return ( missing, bad ) + +# match a path to a file in a case insensitive way +# return ( True/False, 'walked up to' ) +def ifind( base, path ): + refpath = path + path = os.path.normpath( path ) + path = os.path.normcase( path ) + # early out just in case + if ( os.path.exists( path ) ): + return ( True, path ) + head = path + components = [] + while ( len( head ) ): + ( head, chunk ) = os.path.split( head ) + components.append( chunk ) + #print 'head: %s - components: %s' % ( head, repr( components ) ) + components.reverse() + level = 0 + for root, dirs, files in os.walk( base, topdown = True ): + if ( level < len( components ) - 1 ): + #print 'filter dirs: %s' % repr( dirs ) + dirs_del = [] + for i in dirs: + if ( not i.lower() == components[ level ].lower() ): + dirs_del.append( i ) + for i in dirs_del: + dirs.remove( i ) + level += 1 + # we assume there is never going to be 2 dirs with only case difference + if ( len( dirs ) != 1 ): + #print '%s: ifind failed dirs matching at %s - dirs: %s' % ( refpath, root, repr( dirs ) ) + return ( False, root[ len( base ) + 1: ] ) + else: + # must find the file here + for i in files: + if ( i.lower() == components[-1].lower() ): + return ( True, os.path.join( root, i )[ len( base ) + 1: ] ) + return ( False, root[ len( base ) + 1: ] ) + +# do case insensitive FS search on files list +# return [ cased files, not found (unmodified ) ] +def ifind_list( base, files ): + cased = [] + notfound = [] + for i in files: + ret = ifind( base, i ) + if ( ret[ 0 ] ): + cased.append( ret[ 1 ] ) + else: + notfound.append( i ) + return [ cased, notfound ] + diff --git a/sys/linux/pk4/packup-nocase.sh b/sys/linux/pk4/packup-nocase.sh new file mode 100644 index 000000000..278a288d9 --- /dev/null +++ b/sys/linux/pk4/packup-nocase.sh @@ -0,0 +1,7 @@ +#!/bin/sh +rm $1 +flip -u $2 +mkdir -p `dirname $1` +cd /var/local/Doom/base +cat $2 | zip $1 -@ + diff --git a/sys/linux/pk4/packup.sh b/sys/linux/pk4/packup.sh new file mode 100644 index 000000000..362a17ed6 --- /dev/null +++ b/sys/linux/pk4/packup.sh @@ -0,0 +1,7 @@ +#!/bin/sh +rm $1 +flip -u $2 +mkdir -p `dirname $1` +cd /var/local/Doom/base +cat $2 | while read i ; do find . -ipath "./$i" ; done | cut -b 3- | tee /home/timo/cased.log | zip $1 -@ + diff --git a/sys/linux/pk4/syncfromlist.sh b/sys/linux/pk4/syncfromlist.sh new file mode 100644 index 000000000..2a2906221 --- /dev/null +++ b/sys/linux/pk4/syncfromlist.sh @@ -0,0 +1,42 @@ +#!/bin/sh +base=/home/doom-grp/Doom/base +host=timo@idnet.ua-corp.com +srvscript=/var/local/builds/misc/packup.sh + +maindir=$(pwd) +cd $(dirname $1) +source=$(pwd)/$(basename $1) +outdir=$(pwd) +cd $maindir + +echo "list of files : $source" +echo "base : $base" +echo "host : $host" +echo "server script : $srvscript" +echo "press enter" +read + +flip -u $source + +( +cd $base +cat $source | while read i ; do find . -ipath "./$i" | cut -b 3- ; done | tee $outdir/matched.cased.log +) + +# find the no match, not even case sensitive +diff -ui $source $outdir/matched.cased.log | grep ^- | cut -b 2- | tee $outdir/missing.log + +scp $outdir/missing.log $host:/home/timo/missing.log +ssh $host $srvscript /home/timo/dl.zip /home/timo/missing.log +rm $outdir/dl.zip +scp $host:/home/timo/dl.zip $outdir +scp $host:/home/timo/cased.log $outdir/missing.cased.log +( +cd $base +unzip $outdir/dl.zip + +# merge both lists into a single thing +rm $outdir/dl.zip +cat $outdir/missing.cased.log | zip $outdir/dl.zip -@ +cat $outdir/matched.cased.log | zip $outdir/dl.zip -@ +) diff --git a/sys/linux/pk4/updatepaks.sh b/sys/linux/pk4/updatepaks.sh new file mode 100644 index 000000000..ad2cd8df4 --- /dev/null +++ b/sys/linux/pk4/updatepaks.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +echo "current pak files: $1" +echo "expanded updated source: $2" +echo "new pak file: $3" +echo "press a key" +read + +TMPDIR=`mktemp -d -t` + +ls "$1/"*.pk4 | while read i ; do unzip -l $i | cut -b 29- | tee $TMPDIR/`basename $i`.log ; done + +ls $TMPDIR/*.log | while read i ; do lines=`cat $i | wc -l` ; tail +4 $i | head -$(( $lines - 5 )) | tee $TMPDIR/`basename $i`.2 ; done + +# check cutting off +#ls $TMPDIR/*.log | while read i ; do diff $i $i.2 ; done + +cat $TMPDIR/*.log.2 | sort -u | tee $TMPDIR/sorted-unique.log + +# now the magical zip command +cd $2 +rm $3 +cat $TMPDIR/sorted-unique.log | zip -b $TMPDIR $3 -@ 1>/dev/null + +md5sum $3 +echo "done." + diff --git a/sys/linux/process.py b/sys/linux/process.py new file mode 100644 index 000000000..9a897564b --- /dev/null +++ b/sys/linux/process.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# process stdin into an M4 macro definition file +# recognize three keyword qgl qwgl qglX +# +# output +# global macros keep track of the three intervals for function types: +# gl_start gl_end wgl_start wgl_end glX_start glX_end +# NOTE: will we need similar thing for extensions? +# +# each function: +# f_ret: return type +# f_name: function name +# f_params: complete params +# +# ex: +# define(`f1_ret', `void') +# define(`f1_name', `Accum') +# define(`f1_params', ``GLenum op, GLfloat value'') +# + +import sys, string +from read import read_gl + +(gl, wgl, glX) = read_gl(sys.stdin) + +sys.stdout.write('define(`gl_start\', `0\')\n') +sys.stdout.write('define(`gl_end\', `%d\')\n' % int(len(gl)-1)) +sys.stdout.write('define(`wgl_start\', `%d\')\n' % int(len(gl))) +sys.stdout.write('define(`wgl_end\', `%d\')\n' % int(len(gl)+len(wgl)-1)) +sys.stdout.write('define(`glX_start\', `%d\')\n' % int(len(gl)+len(wgl))) +sys.stdout.write('define(`glX_end\', `%d\')\n' % int(len(gl)+len(wgl)+len(glX)-1)) + +i = 0 +for l in (gl, wgl, glX): + for t in l: + # process ret type to strip trailing spaces + t[0] = string.strip(t[0]) + sys.stdout.write('define(`f%d_ret\', `%s\')\n' % (i, t[0])) + sys.stdout.write('define(`f%d_name\', `%s\')\n' % (i, t[2])) + sys.stdout.write('define(`f%d_params\', ``%s\'\')\n' % (i, t[3])) + i += 1 diff --git a/sys/linux/process_undef.pl b/sys/linux/process_undef.pl new file mode 100644 index 000000000..9a5ee7fa8 --- /dev/null +++ b/sys/linux/process_undef.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +# send linker output to stdin +# make 2>&1 | process_undef.pl + +my %symbols; +open($list, "cat $ARGV[0] " . '| grep \'undefined reference\' | grep -v \'more undefined\' | sed -e \'s/.*undefined reference to `\(.*\)./\1/\' |'); +my $line = <$list>; +do +{ + chop($line); + $symbols{$line}++; +} until (!($line = <$list>)); + +@sorted = sort { $symbols{$b} <=> $symbols{$a} } keys %symbols; + +foreach (@sorted) +{ + print "$symbols{$_} : $_\n"; +}; + diff --git a/sys/linux/qgl_enforce.h b/sys/linux/qgl_enforce.h index efe9843a3..c93837d1c 100644 --- a/sys/linux/qgl_enforce.h +++ b/sys/linux/qgl_enforce.h @@ -1,11 +1,1126 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #define glAccum use_qglAccum #define glAlphaFunc use_qglAlphaFunc diff --git a/sys/linux/qgl_enforce.h.m4 b/sys/linux/qgl_enforce.h.m4 new file mode 100644 index 000000000..2fb2029d7 --- /dev/null +++ b/sys/linux/qgl_enforce.h.m4 @@ -0,0 +1,24 @@ +dnl ===================================================== +dnl utils +dnl ===================================================== + +define(`forloop', + `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') +define(`_forloop', + `$4`'ifelse($1, `$3', , + `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') + +dnl ===================================================== +dnl the gl wgl glX definitions +dnl ===================================================== +include(../gllog/gl_def.m4) + +dnl ===================================================== +dnl issue the defines to lock out gl usage +dnl ===================================================== +define(`define_out', `#define gl$1 use_qgl$1') +forloop(`i', gl_start, gl_end, `define_out(indir(`f'i`_name')) +') +forloop(`i', glX_start, glX_end, `define_out(indir(`f'i`_name')) +') + diff --git a/sys/linux/runner/runner.tac b/sys/linux/runner/runner.tac new file mode 100644 index 000000000..c4e892f76 --- /dev/null +++ b/sys/linux/runner/runner.tac @@ -0,0 +1,25 @@ +# -*- mode: python -*- +import string + +from twisted.application import service, internet + +from runner_lib import doomService + +maps_file = open( 'maps.list.full' ) +multiplayer = 0 + +# maps_file = open( 'maps.list.mp' ) +# multiplayer = 1 + +# maps_file = open( 'maps.list.game' ) +# multiplayer = 0 + +blank_run = 1 + +maps = maps_file.readlines() +maps_file.close() +for i in range( 0, len(maps) ): + maps[i] = string.strip( maps[i], '\n' ) + +application = service.Application( "doomRunner" ) +doomService( '/home/timo/runner/doom.x86', '+set r_fullscreen 0 +set in_nograb 1 +set si_pure 0 +set com_makingBuild 1 +set s_forceWav 1 +set s_maxSoundsPerShader 0 +set s_constantAmplitude 1 +set fs_devpath /home/timo/Id/DoomPure +set fs_basepath /home/timo/Id/DoomBase +set fs_cdpath /home/timo/Id/DoomBase.smbfs +set fs_copyfiles 3', maps, sort = 1, multiplayer = multiplayer, blank_run = blank_run ).setServiceParent( application ) diff --git a/sys/linux/runner/runner_lib.py b/sys/linux/runner/runner_lib.py new file mode 100644 index 000000000..9e2588345 --- /dev/null +++ b/sys/linux/runner/runner_lib.py @@ -0,0 +1,209 @@ +# run doom process on a series of maps +# can be used for regression testing, or to fetch media +# keeps a log of each run ( see getLogfile ) + +# currently uses a basic stdout activity timeout to decide when to move on +# using a periodic check of /proc//status SleepAVG +# when the sleep average is reaching 0, issue a 'quit' to stdout + +# keeps serialized run status in runner.pickle +# NOTE: can be used to initiate runs on failed maps only for instance etc. + +# TODO: use the serialized and not the logs to sort the run order + +# TODO: better logging. Use idLogger? + +# TODO: configurable event when the process is found interactive +# instead of emitting a quit, perform some warning action? + +import sys, os, commands, string, time, traceback, pickle + +from twisted.application import internet, service +from twisted.internet import protocol, reactor, utils, defer +from twisted.internet.task import LoopingCall + +class doomClientProtocol( protocol.ProcessProtocol ): + + # ProcessProtocol API + + def connectionMade( self ): + self.logfile.write( 'connectionMade\n' ) + + def outReceived( self, data ): + print data + self.logfile.write( data ) + + def errReceived( self, data ): + print 'stderr: ' + data + self.logfile.write( 'stderr: ' + data ) + + def inConnectionLost( self ): + self.logfile.write( 'inConnectionLost\n' ) + + def outConnectionLost( self ): + self.logfile.write( 'outConnectionLost\n' ) + + def errConnectionLost( self ): + self.logfile.write( 'errConnectionLost\n' ) + + def processEnded( self, status_object ): + self.logfile.write( 'processEnded %s\n' % repr( status_object ) ) + self.logfile.write( time.strftime( '%H:%M:%S', time.localtime( time.time() ) ) + '\n' ) + self.logfile.close() + self.deferred.callback( None ) + + # mac management + def __init__( self, logfilename, deferred ): + self.logfilename = logfilename + self.logfile = open( logfilename, 'a' ) + self.logfile.write( time.strftime( '%H:%M:%S', time.localtime( time.time() ) ) + '\n' ) + self.deferred = deferred + +class doomService( service.Service ): + + # current monitoring state + # 0: nothing running + # 1: we have a process running, we're monitoring it's CPU usage + # 2: we issued a 'quit' to the process's stdin + # either going to get a processEnded, or a timeout + # 3: we forced a kill because of error, timeout etc. + state = 0 + + # load check period + check_period = 10 + + # pickled status file + pickle_file = 'runner.pickle' + + # stores status indexed by filename + # { 'mapname' : ( state, last_update ), .. } + status = {} + + # start the maps as multiplayer server + multiplayer = 0 + + def __init__( self, bin, cmdline, maps, sort = 0, multiplayer = 0, blank_run = 0 ): + self.p_transport = None + self.multiplayer = multiplayer + self.blank_run = blank_run + if ( self.multiplayer ): + print 'Operate in multiplayer mode' + self.bin = os.path.abspath( bin ) + if ( type( cmdline ) is type( '' ) ): + self.cmdline = string.split( cmdline, ' ' ) + else: + self.cmdline = cmdline + self.maps = maps + if ( os.path.exists( self.pickle_file ) ): + print 'Loading pickled status %s' % self.pickle_file + handle = open( self.pickle_file, 'r' ) + self.status = pickle.load( handle ) + handle.close() + if ( sort ): + print 'Sorting maps oldest runs first' + maps_sorted = [ ] + for i in self.maps: + i_log = self.getLogfile( i ) + if ( os.path.exists( i_log ) ): + maps_sorted.append( ( i, os.path.getmtime( i_log ) ) ) + else: + maps_sorted.append( ( i, 0 ) ) + maps_sorted.sort( lambda x,y : cmp( x[1], y[1] ) ) + self.maps = [ ] + if ( blank_run ): + self.maps.append( 'blankrun' ) + for i in maps_sorted: + self.maps.append( i[ 0 ] ) + print 'Sorted as: %s\n' % repr( self.maps ) + + def getLogfile( self, name ): + return 'logs/' + string.translate( name, string.maketrans( '/', '-' ) ) + '.log' + + # deferred call when child process dies + def processEnded( self, val ): + print 'child has died - state %d' % self.state + self.status[ self.maps[ self.i_map ] ] = ( self.state, time.time() ) + self.i_map += 1 + if ( self.i_map >= len( self.maps ) ): + reactor.stop() + else: + self.nextMap() + + def processTimeout( self ): + self.p_transport.signalProcess( "KILL" ) + + def sleepAVGReply( self, val ): + try: + s = val[10:][:-2] + print 'sleepAVGReply %s%%' % s + if ( s == '0' ): + # need twice in a row + if ( self.state == 2 ): + print 'child process is interactive' + self.p_transport.write( 'quit\n' ) + else: + self.state = 2 + else: + self.state = 1 +# else: +# reactor.callLater( self.check_period, self.checkCPU ) + except: + print traceback.format_tb( sys.exc_info()[2] ) + print sys.exc_info()[0] + print 'exception raised in sleepAVGReply - killing process' + self.state = 3 + self.p_transport.signalProcess( 'KILL' ) + + def sleepAVGTimeout( self ): + print 'sleepAVGTimeout - killing process' + self.state = 3 + self.p_transport.signalProcess( 'KILL' ) + + # called at regular intervals to monitor the sleep average of the child process + # when sleep reaches 0, it means the map is loaded and interactive + def checkCPU( self ): + if ( self.state == 0 or self.p_transport is None or self.p_transport.pid is None ): + print 'checkCPU: no child process atm' + return + defer = utils.getProcessOutput( '/bin/bash', [ '-c', 'cat /proc/%d/status | grep SleepAVG' % self.p_transport.pid ] ) + defer.addCallback( self.sleepAVGReply ) + defer.setTimeout( 2, self.sleepAVGTimeout ) + + def nextMap( self ): + self.state = 0 + name = self.maps[ self.i_map ] + print 'Starting map: ' + name + logfile = self.getLogfile( name ) + print 'Logging to: ' + logfile + if ( self.multiplayer ): + cmdline = [ self.bin ] + self.cmdline + [ '+set', 'si_map', name ] + if ( name != 'blankrun' ): + cmdline.append( '+spawnServer' ) + else: + cmdline = [ self.bin ] + self.cmdline + if ( name != 'blankrun' ): + cmdline += [ '+devmap', name ] + print 'Command line: ' + repr( cmdline ) + self.deferred = defer.Deferred() + self.deferred.addCallback( self.processEnded ) + self.p_transport = reactor.spawnProcess( doomClientProtocol( logfile, self.deferred ), self.bin, cmdline , path = os.path.dirname( self.bin ), env = os.environ ) + self.state = 1 +# # setup the CPU usage loop +# reactor.callLater( self.check_period, self.checkCPU ) + + def startService( self ): + print 'doomService startService' + loop = LoopingCall( self.checkCPU ) + loop.start( self.check_period ) + self.i_map = 0 + self.nextMap() + + def stopService( self ): + print 'doomService stopService' + if ( not self.p_transport.pid is None ): + self.p_transport.signalProcess( 'KILL' ) + # serialize + print 'saving status to %s' % self.pickle_file + handle = open( self.pickle_file, 'w+' ) + pickle.dump( self.status, handle ) + handle.close() diff --git a/sys/linux/setup/binary.conf b/sys/linux/setup/binary.conf new file mode 100644 index 000000000..0cfbf0888 --- /dev/null +++ b/sys/linux/setup/binary.conf @@ -0,0 +1 @@ +2 diff --git a/sys/linux/setup/brandelf.c b/sys/linux/setup/brandelf.c new file mode 100644 index 000000000..941a54ad8 --- /dev/null +++ b/sys/linux/setup/brandelf.c @@ -0,0 +1,224 @@ +/*- + * Copyright (c) 1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/usr.bin/brandelf/brandelf.c,v 1.16 2000/07/02 03:34:08 imp Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* These are defined on FreeBSD, but not on Linux */ +#ifndef ELFOSABI_SYSV +#define ELFOSABI_SYSV 0 +#endif +#ifndef ELFOSABI_LINUX +#define ELFOSABI_LINUX 3 +#endif +#ifndef ELFOSABI_HURD +#define ELFOSABI_HURD 4 +#endif +#ifndef ELFOSABI_SOLARIS +#define ELFOSABI_SOLARIS 6 +#endif +#ifndef ELFOSABI_FREEBSD +#define ELFOSABI_FREEBSD 9 +#endif + + +static int elftype(const char *); +static const char *iselftype(int); +static void printelftypes(void); +static void usage __P((void)); + +struct ELFtypes { + const char *str; + int value; +}; +/* XXX - any more types? */ +static struct ELFtypes elftypes[] = { + { "FreeBSD", ELFOSABI_FREEBSD }, + { "Linux", ELFOSABI_LINUX }, + { "Solaris", ELFOSABI_SOLARIS }, + { "SVR4", ELFOSABI_SYSV } +}; + +int +main(int argc, char **argv) +{ + + const char *strtype = "FreeBSD"; + int type = ELFOSABI_FREEBSD; + int retval = 0; + int ch, change = 0, verbose = 0, force = 0, listed = 0; + + while ((ch = getopt(argc, argv, "f:lt:v")) != -1) + switch (ch) { + case 'f': + if (change) + errx(1, "f option incompatable with t option"); + force = 1; + type = atoi(optarg); + if (errno == ERANGE || type < 0 || type > 255) { + warnx("invalid argument to option f: %s", + optarg); + usage(); + } + break; + case 'l': + printelftypes(); + listed = 1; + break; + case 'v': + verbose = 1; + break; + case 't': + if (force) + errx(1, "t option incompatable with f option"); + change = 1; + strtype = optarg; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + if (!argc) { + if (listed) + exit(0); + else { + warnx("no file(s) specified"); + usage(); + } + } + + if (!force && (type = elftype(strtype)) == -1) { + warnx("invalid ELF type '%s'", strtype); + printelftypes(); + usage(); + } + + while (argc) { + int fd; + char buffer[EI_NIDENT]; + + if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { + warn("error opening file %s", argv[0]); + retval = 1; + goto fail; + } + if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { + warnx("file '%s' too short", argv[0]); + retval = 1; + goto fail; + } + if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || + buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { + warnx("file '%s' is not ELF format", argv[0]); + retval = 1; + goto fail; + } + if (!change && !force) { + fprintf(stdout, + "File '%s' is of brand '%s' (%u).\n", + argv[0], iselftype(buffer[EI_OSABI]), + buffer[EI_OSABI]); + if (!iselftype(type)) { + warnx("ELF ABI Brand '%u' is unknown", + type); + printelftypes(); + } + } + else { + buffer[EI_OSABI] = type; + lseek(fd, 0, SEEK_SET); + if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { + warn("error writing %s %d", argv[0], fd); + retval = 1; + goto fail; + } + } +fail: + close(fd); + argc--; + argv++; + } + + return retval; +} + +static void +usage() +{ +fprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n"); + exit(1); +} + +static const char * +iselftype(int elftype) +{ + int elfwalk; + + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + if (elftype == elftypes[elfwalk].value) + return elftypes[elfwalk].str; + return 0; +} + +static int +elftype(const char *elfstrtype) +{ + int elfwalk; + + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0) + return elftypes[elfwalk].value; + return -1; +} + +static void +printelftypes() +{ + int elfwalk; + + fprintf(stderr, "known ELF types are: "); + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str, + elftypes[elfwalk].value); + fprintf(stderr, "\n"); +} diff --git a/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/setup.gtk b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/setup.gtk new file mode 100644 index 000000000..65cb3c3c2 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/setup.gtk differ diff --git a/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/xsu b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/xsu new file mode 100644 index 000000000..70b0618de Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/glibc-2.1/xsu differ diff --git a/sys/linux/setup/image-base/setup.data/bin/Linux/x86/setup b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/setup new file mode 100644 index 000000000..229467d27 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/bin/Linux/x86/setup differ diff --git a/sys/linux/setup/image-base/setup.data/config.sh b/sys/linux/setup/image-base/setup.data/config.sh new file mode 100644 index 000000000..828503f3d --- /dev/null +++ b/sys/linux/setup/image-base/setup.data/config.sh @@ -0,0 +1,30 @@ +# +# Use this script to customize the installer bootstrap script +# + +# override some defaults + +# try to get root prior to running setup? +# 0: no +# 1: prompt, but run anyway if fails +# 2: require, abort if root fails +# 3: print SU_MESSAGE if not root, don't attempt any privilege upgrade +GET_ROOT=1 + +FATAL_ERROR="Error running installer. See http://zerowing.idsoftware.com/linux/doom/ for troubleshooting" + +#XSU_ICON="-i icon.xpm" + +SU_MESSAGE="The recommended install location (/usr/local/games) requires root permissions.\nPlease enter the root password or hit enter to continue install as current user." +XSU_MESSAGE="The recommended install location (/usr/local/games) requires root permissions.^Please enter the root password or hit cancel to continue install as current user." + +rm -f /usr/local/games/tmp.$$ > /dev/null 2>&1 +touch /usr/local/games/tmp.$$ > /dev/null 2>&1 +status="$?" +if [ "$status" -eq 0 ] +then + rm -f /usr/local/games/tmp.$$ + GET_ROOT=0 +else + GET_ROOT=1 +fi diff --git a/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..4b66e6a9d Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..13b8846b6 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/de/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..c05cdc1f1 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..ca6445a06 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/en_UK/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..f4a98668e Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..e427511f2 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/es/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..03610c31b Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..b60c7d19f Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/fr/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..2d1c567cd Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..016073e50 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/it/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..2723bd82a Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..4a7bd0d24 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/nl/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..5964a86d0 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..23778c195 Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/ru/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/loki-uninstall.mo b/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/loki-uninstall.mo new file mode 100644 index 000000000..c835fccda Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/loki-uninstall.mo differ diff --git a/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/setup.mo b/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/setup.mo new file mode 100644 index 000000000..eaf351b8f Binary files /dev/null and b/sys/linux/setup/image-base/setup.data/locale/sv/LC_MESSAGES/setup.mo differ diff --git a/sys/linux/setup/image-base/setup.data/setup.glade b/sys/linux/setup/image-base/setup.data/setup.glade new file mode 100644 index 000000000..5a6f8e251 --- /dev/null +++ b/sys/linux/setup/image-base/setup.data/setup.glade @@ -0,0 +1,2096 @@ + + + + + Setup + setup + + src + pixmaps + C + False + True + False + True + setup.txt + + + + GtkWindow + setup_window + False + + delete_event + setup_button_cancel_slot + Wed, 15 Sep 1999 01:24:58 GMT + + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + + + GtkHBox + hbox1 + False + 0 + + + GtkFrame + image_frame + 5 + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkLabel + label30 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + GtkNotebook + setup_notebook + 5 + False + True + GTK_POS_TOP + False + 2 + 2 + False + + 0 + True + True + + + + GtkVBox + class_continue + True + 0 + + + GtkLabel + label69 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkRadioButton + recommended_but + 9 + This will install the product with the default options and paths + True + + True + True + install_class + + 0 + False + False + + + + + GtkRadioButton + expert_but + 10 + This will allow you to pick the installation paths and options to be installed + True + + False + True + install_class + + 0 + False + False + + + + + GtkHBox + hbox4 + True + 0 + + 0 + True + False + GTK_PACK_END + + + + GtkButton + class_cancel + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_exit_slot + Thu, 13 Sep 2001 23:46:19 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + class_readme + True + True + + 0 + GDK_F1 + clicked + + + clicked + setup_button_view_readme_slot + Thu, 13 Sep 2001 23:23:42 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + class_continue + True + True + True + + 0 + GDK_Return + clicked + + + clicked + on_class_continue_clicked + Thu, 13 Sep 2001 23:39:48 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + + + GtkLabel + Notebook:tab + setup_class + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table11 + 4 + 1 + False + 0 + 0 + + + GtkFrame + global_frame + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + + GtkTable + table12 + 5 + 3 + 2 + False + 5 + 5 + + + GtkLabel + label23 + + GTK_JUSTIFY_CENTER + False + 1 + 0.5 + 0 + 0 + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCombo + install_path + False + True + False + True + False + + + 1 + 2 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + install_entry + True + + focus_out_event + setup_entry_installpath_slot + Wed, 15 Sep 1999 01:04:39 GMT + + True + True + 0 + + + + + + GtkLabel + binary_label + + GTK_JUSTIFY_RIGHT + False + 1 + 0.5 + 0 + 0 + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCombo + binary_path + False + True + False + True + False + + + 1 + 2 + 2 + 3 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + binary_entry + Symbolic links to installed binaries are placed here + True + + focus_out_event + setup_entry_binarypath_slot + Wed, 15 Sep 1999 01:06:14 GMT + + True + True + 0 + + + + + + GtkCheckButton + symlink_checkbox + True + True + True + + toggled + on_use_binary_toggled + Thu, 03 Aug 2000 09:53:24 GMT + + + True + True + + 0 + 2 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + + + GtkFrame + frame10 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 1 + 2 + 0 + 0 + False + True + False + False + True + True + + + + GtkTable + table13 + 5 + 4 + 4 + False + 5 + 5 + + + GtkLabel + label_free_space + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label_install_size + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 3 + 4 + 2 + 3 + 0 + 0 + False + False + False + False + False + False + + + + + GtkVBox + option_vbox + False + 0 + + 0 + 4 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + + GtkLabel + label31 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + GtkLabel + free_space_label + + GTK_JUSTIFY_CENTER + False + 1 + 0.5 + 0 + 0 + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkLabel + estim_size_label + + GTK_JUSTIFY_CENTER + False + 1 + 0.5 + 0 + 0 + + 2 + 3 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + setup_menuitems_checkbox + True + + toggled + setup_checkbox_menuitems_slot + Thu, 16 Sep 1999 01:16:33 GMT + + + True + True + + 0 + 4 + 3 + 4 + 0 + 0 + False + False + False + False + True + False + + + + + GtkHSeparator + install_separator + + 0 + 4 + 1 + 2 + 0 + 0 + False + False + False + False + True + True + + + + + + + GtkHButtonBox + hbuttonbox3 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 60 + 27 + 7 + 0 + + 0 + 1 + 3 + 4 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button_cancel + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_exit_slot + Tue, 14 Sep 1999 22:58:10 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button_readme + True + True + + 0 + GDK_F1 + clicked + + + clicked + setup_button_view_readme_slot + Wed, 15 Sep 1999 01:10:59 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button_install + True + True + + clicked + setup_button_install_slot + Tue, 14 Sep 1999 22:36:50 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkLabel + options_status + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + + GtkLabel + Notebook:tab + setup_options + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table14 + 2 + 1 + False + 5 + 5 + + + GtkFrame + frame13 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + + GtkVBox + vbox10 + 5 + False + 0 + + + GtkLabel + label39 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkVBox + vbox11 + False + 0 + + 0 + True + True + + + + GtkLabel + current_option_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label50 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + current_file_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkProgressBar + current_file_progress + 0 + 0 + 100 + GTK_PROGRESS_CONTINUOUS + GTK_PROGRESS_LEFT_TO_RIGHT + False + False + %P %% + 0.5 + 0.5 + + 0 + False + False + + + + + + GtkVBox + vbox12 + False + 0 + + 0 + True + True + + + + GtkLabel + label41 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkProgressBar + total_file_progress + 0 + 0 + 100 + GTK_PROGRESS_CONTINUOUS + GTK_PROGRESS_LEFT_TO_RIGHT + False + False + %P %% + 0.5 + 0.5 + + 0 + False + False + + + + + + + + GtkHButtonBox + hbuttonbox4 + GTK_BUTTONBOX_START + 5 + 60 + 27 + 7 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + True + + + + GtkButton + button12 + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_cancel_slot + Tue, 14 Sep 1999 19:53:47 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + view_readme_progress_button + True + True + + 0 + GDK_F1 + clicked + + + clicked + setup_button_view_readme_slot + Wed, 15 Sep 1999 01:11:10 GMT + + + GTK_RELIEF_NORMAL + + + + + + GtkLabel + Notebook:tab + setup_install + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table15 + 2 + 1 + False + 5 + 5 + + + GtkHButtonBox + hbuttonbox5 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 60 + 27 + 7 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + True + + + + GtkButton + button15 + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_exit_slot + Tue, 14 Sep 1999 22:58:23 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + view_readme_end_button + True + True + + 0 + GDK_F1 + clicked + + + clicked + setup_button_view_readme_slot + Wed, 15 Sep 1999 01:11:23 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + play_game_button + True + True + + 0 + GDK_Return + clicked + + + 0 + GDK_space + enter + + + clicked + setup_button_play_slot + Tue, 14 Sep 1999 22:35:17 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkFrame + frame14 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + + GtkVBox + vbox15 + 5 + False + 0 + + + GtkLabel + label45 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + setup_complete_label + + GTK_JUSTIFY_CENTER + True + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label54 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label55 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + install_directory_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label57 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + play_game_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + + + GtkLabel + Notebook:tab + setup_complete + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table16 + 2 + 1 + False + 5 + 5 + + + GtkHButtonBox + hbuttonbox6 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 120 + 27 + 7 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + True + + + + GtkButton + button18 + True + True + + 0 + GDK_Return + clicked + + + 0 + GDK_Escape + clicked + + + clicked + setup_button_abort_slot + Wed, 06 Feb 2002 01:32:49 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkFrame + frame15 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + + GtkVBox + vbox16 + 5 + False + 0 + + + GtkLabel + label48 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label49 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + + + GtkLabel + Notebook:tab + setup_abort + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table17 + 2 + 1 + False + 5 + 5 + + + GtkHButtonBox + hbuttonbox7 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 60 + 27 + 7 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + True + + + + GtkButton + button21 + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_warning_cancel_slot + Wed, 29 Sep 1999 21:51:04 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button22 + True + True + True + + 0 + GDK_Return + clicked + + + clicked + setup_button_warning_continue_slot + Wed, 29 Sep 1999 21:50:51 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkFrame + frame16 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + + GtkVBox + vbox17 + 5 + False + 0 + + + GtkLabel + warning_label + + GTK_JUSTIFY_LEFT + False + 0 + 0.5 + 5 + 0 + + 0 + False + False + + + + + + + + GtkLabel + Notebook:tab + setup_warning + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table18 + 2 + 1 + False + 5 + 5 + + + GtkHButtonBox + hbuttonbox10 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 60 + 27 + 7 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + True + + + + GtkButton + button30 + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_exit_slot + Tue, 14 Sep 1999 22:58:23 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button31 + True + True + + 0 + GDK_F1 + clicked + + + clicked + setup_button_view_readme_slot + Wed, 15 Sep 1999 01:11:23 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button32 + True + True + True + + clicked + setup_button_complete_slot + Sat, 11 Dec 1999 04:16:26 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkFrame + frame17 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + + GtkVBox + vbox20 + 5 + False + 0 + + + GtkLabel + label60 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkHBox + hbox3 + False + 0 + + 0 + False + False + + + + GtkLabel + label67 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + website_product_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + GtkLabel + website_text_label + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label63 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label65 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + auto_url_yes + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkHButtonBox + auto_url_no + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + button33 + True + True + + clicked + setup_button_browser_slot + Sat, 11 Dec 1999 04:35:32 GMT + + + GTK_RELIEF_NORMAL + + + + + + + + GtkLabel + Notebook:tab + setup_website + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + + GtkDialog + readme_dialog + 480 + 360 + False + + destroy + setup_destroy_view_readme_slot + + Readme File + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + True + False + + + GtkVBox + Dialog:vbox + dialog-vbox1 + False + 0 + + + GtkHBox + Dialog:action_area + dialog-action_area1 + 10 + True + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button20 + True + True + + 0 + GDK_Return + clicked + + + 0 + GDK_Escape + clicked + + + clicked + setup_close_view_readme_slot + Wed, 15 Sep 1999 01:10:31 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + True + + + + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkText + readme_area + True + False + + + + + + + + GtkDialog + license_dialog + 480 + 360 + False + + destroy + setup_destroy_license_slot + + License Agreement + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_CENTER + True + True + True + False + + + GtkVBox + Dialog:vbox + vbox19 + False + 0 + + + GtkHBox + Dialog:action_area + hbox2 + 10 + True + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkHButtonBox + hbuttonbox9 + GTK_BUTTONBOX_DEFAULT_STYLE + 5 + 60 + 27 + 7 + 0 + + 0 + False + True + + + + GtkButton + button28 + True + True + + 0 + GDK_Escape + clicked + + + clicked + setup_button_exit_slot + Tue, 14 Sep 1999 22:58:10 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button29 + True + True + + 0 + GDK_Y + clicked + + + 0 + GDK_y + clicked + + + 0 + GDK_Return + clicked + + + clicked + setup_button_license_agree_slot + Tue, 30 Nov 1999 01:28:20 GMT + + + GTK_RELIEF_NORMAL + + + + + + GtkScrolledWindow + scrolledwindow3 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkText + license_area + True + False + + + + + + + diff --git a/sys/linux/setup/image-base/setup.sh b/sys/linux/setup/image-base/setup.sh new file mode 100644 index 000000000..8e92ae778 --- /dev/null +++ b/sys/linux/setup/image-base/setup.sh @@ -0,0 +1,290 @@ +#! /bin/sh +# +# Product setup script +# +# Go to the proper setup directory (if not already there) +cd `dirname $0` + +# defaults +FATAL_ERROR="Fatal error, no tech support email configured in this setup" +# try to get root prior to running setup? +# 0: no +# 1: prompt, but run anyway if fails +# 2: require, abort if root fails +GET_ROOT=0 +XSU_ICON="" +# You may want to set USE_XHOST to 1 if you want an X11 application to +# be launched with root privileges right after installation +USE_XHOST=0 +# this is the message for su call, printf +SU_MESSAGE="You need to run this installation as the super user.\nPlease enter the root password." + +NULL=/dev/null +# See if we have the XPG4 utilities (Solaris) +if test -d /usr/xpg4/bin; then + PATH=/usr/xpg4/bin:$PATH +fi + +# Return the appropriate architecture string +DetectARCH() +{ + status=1 + case `uname -m` in + amd64 | x86_64) + echo "amd64" + status=0;; + i?86 | i86*) + echo "x86" + status=0;; + 90*/*) + echo "hppa" + status=0;; + *) + case `uname -s` in + IRIX*) + echo "mips" + status=0;; + AIX*) + echo "ppc" + status=0;; + *) + arch=`uname -p 2> /dev/null || uname -m` + if test "$arch" = powerpc; then + echo "ppc" + else + echo $arch + fi + status=0;; + esac + esac + return $status +} + +# Return the appropriate version string +DetectLIBC() +{ + status=1 + if [ `uname -s` != Linux ]; then + echo "glibc-2.1" + return $status + fi + if [ -f `echo /lib/libc.so.6* | tail -n 1` ]; then + # I'm not using glibc-specific binaries + # this step even fails on amd64 gentoo, only has GLIBC_2.2 2.3 in it's strings + echo "glibc-2.1" + status=0 +# if [ fgrep GLIBC_2.1 /lib/libc.so.6* 2> $NULL >> $NULL ]; then +# echo "glibc-2.1" +# status=0 +# else +# echo "glibc-2.0" +# status=0 +# fi + elif [ -f /lib/libc.so.5 ]; then + echo "libc5" + status=0 + else + echo "unknown" + fi + return $status +} + +DetectOS() +{ + os=`uname -s` + if test "$os" = "OpenUNIX"; then + echo SCO_SV + else + echo $os + fi + return 0 +} + +# Detect the environment +arch=`DetectARCH` +libc=`DetectLIBC` +os=`DetectOS` + +args="" + +# Import preferences from a secondary script +if [ -f setup.data/config.sh ]; then + . setup.data/config.sh +elif [ -f SETUP.DAT/CONFIG.SH\;1 ]; then + # HP-UX and other systems unable to get LFN correctly + . SETUP.DAT/CONFIG.SH\;1 +fi + +# Add some standard paths for compatibility +PATH=$PATH:/usr/ucb + +# call setup with -auth when ran through su/xsu +auth=0 +if [ "$1" = "-auth" ] +then + auth=1 + shift +fi + +# Find the installation program +# try_run [-absolute] [-fatal] INSTALLER_NAME [PARAMETERS_PASSED] +# -absolute option: if what you are trying to execute has an absolute path +# NOTE: maybe try_run_absolute would be easier +# -fatal option: if you want verbose messages in case +# - the script could not be found +# - it's execution would fail +# INSTALLER_NAME: setup.gtk or setup +# PARAMETERS_PASSED: additional arguments passed to the setup script +try_run() +{ + absolute=0 + if [ "$1" = "-absolute" ]; then + absolute=1 + shift + fi + + fatal=0 + # older bash < 2.* don't like == operator, using = + if [ "$1" = "-fatal" ]; then + # got fatal + fatal=1 + shift + fi + + setup=$1 + shift + + # First find the binary we want to run + failed=0 + if [ "$absolute" -eq 0 ] + then + setup_bin="setup.data/bin/$os/$arch/$libc/$setup" + # trying $setup_bin + if [ ! -f "$setup_bin" ]; then + setup_bin="setup.data/bin/$os/$arch/$setup" + # libc dependant version failed, trying again + if [ ! -f "$setup_bin" ]; then + failed=1 + fi + fi + if [ "$failed" -eq 1 ]; then + if [ "$fatal" -eq 1 ]; then + cat <<__EOF__ +This installation doesn't support $libc on $os / $arch +(tried to run $setup) +$FATAL_ERROR +__EOF__ + fi + return $failed + fi + + # Try to run the binary ($setup_bin) + # The executable is here but we can't execute it from CD + # NOTE TTimo: this is dangerous, we also use $setup to store the name of the try_run + setup="$HOME/.setup$$" + rm -f "$setup" + cp "$setup_bin" "$setup" + chmod 700 "$setup" + trap "rm -f $setup" 1 2 3 15 + fi + # echo Running "$setup" "$@" + if [ "$fatal" -eq 0 ]; then + "$setup" "$@" + failed="$?" + else + "$setup" "$@" 2>> $NULL + failed="$?" + fi + if [ "$absolute" -eq 0 ] + then + # don't attempt removal when we are passed an absolute path + # no, I don't want to imagine a faulty try_run as root on /bin/su + rm -f "$setup" + fi + return "$failed" +} + +if [ "$GET_ROOT" -eq 3 ] +then + GOT_ROOT=`id -u` + if [ "$GOT_ROOT" != "0" ] + then + printf "$SU_MESSAGE\n" + echo "Press Enter to continue or Ctrl-C to abort" + read + fi + GET_ROOT=0 +fi + +# if we have not been through the auth yet, and if we need to get root, then prompt +if [ "$auth" -eq 0 ] && [ "$GET_ROOT" -ne 0 ] +then + GOT_ROOT=`id -u` + if [ "$GOT_ROOT" != "0" ] + then + if [ "$USE_XHOST" -eq 1 ]; then + xhost +127.0.0.1 2> $NULL > $NULL + fi + if [ "$GET_ROOT" -eq 1 ] + then + try_run xsu -e -a -u root -c "sh `pwd`/setup.sh -auth" $XSU_ICON -m "$XSU_MESSAGE" + else + try_run xsu -e -a -u root -c "sh `pwd`/setup.sh -auth" $XSU_ICON + fi + status="$?" + # echo "got $status" + # if try_run successfully executed xsu, it will return xsu's exit code + # xsu returns 2 if ran and cancelled (i.e. the user 'doesn't want' to auth) + # it will return 0 if the command was executed correctly + # summing up, if we get 1, something failed + if [ "$status" -eq 0 ] + then + # the auth command was properly executed + exit 0 + elif [ "$status" -eq 1 ] + then + # xsu wasn't found, or failed to run + # if xsu actually ran and the auth was cancelled, $status is > 1 + # try with su + # su will return 1 if auth failed + # we need to distinguish between su auth failed and su working, and still get setup.sh return code + printf "$SU_MESSAGE\n" + try_run -absolute /bin/su root -c "export DISPLAY=$DISPLAY;sh `pwd`/setup.sh -auth" + status="$?" + if [ "$status" -eq 1 ] && [ "$GET_ROOT" -eq 1 ] + then + echo "Running setup as user" + else + exit $status + fi + elif [ "$status" -eq 3 ] + then + if [ "$GET_ROOT" -eq 1 ] + then + echo "Running setup as user" + else + # the auth failed or was canceled + # we don't want to even start the setup if not root + echo "Please run this installation as the super user" + exit 1 + fi + fi + # continue running as is + fi +fi + +# run the setup program (setup.gtk first, then setup) +# except when trying setup.gtk first then console setup, always exit with 0 +# if the setup was cancelled, it is not our problem +try_run setup.gtk $args $* +status="$?" +if [ "$status" -ne 0 ] && [ "$status" -ne 3 ]; then # setup.gtk couldn't connect to X11 server - ignore +try_run setup $args $* + status="$?" + if [ "$auth" -eq 1 ] && [ "$status" -ne 0 ] + then + # distinguish between failed su and failed su'ed setup.sh + exit 2 + fi + exit $status +fi diff --git a/sys/linux/setup/image-demo/License.txt b/sys/linux/setup/image-demo/License.txt new file mode 100644 index 000000000..aa296f6d5 --- /dev/null +++ b/sys/linux/setup/image-demo/License.txt @@ -0,0 +1,86 @@ +DOOM 3 LIMITED USE SOFTWARE LICENSE AGREEMENT + +This DOOM 3 Limited Use Software License Agreement (this "Agreement") is a legal agreement among you, the end-user, and Id Software, Inc. ("Id Software"), and Activision Publishing, Inc. ("Activision"). BY CONTINUING THE INSTALLATION OF THE FULL VERSION GAME PROGRAM ENTITLED DOOM 3 (THE "SOFTWARE"), BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM OR OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS AGREEMENT. + +1. Grant of License. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software only in executable or object code form. The term "Software" includes all elements of the Software, including, without limitation, data files and screen displays. You are not receiving any ownership or proprietary right, title, or interest in or to the Software or the copyrights, trademarks, or other rights related thereto. For purposes of the first sentence of this section, "use" means loading the Software into RAM and/or onto computer hard drive, as well as installation of the Software on a hard disk or other storage device, and means the uses permitted in sections 2 and 4 hereinbelow. You agree that the Software will not be downloaded, shipped, transferred, exported or re exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the Software in any other manner in violation of any applicable law. The Software shall not be downloaded or otherwise exported or re exported into (or to a national or resident of) any country to which the United States has embargoed goods, or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. In exercising your limited rights hereunder, you shall comply, at all times, with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement, including, without limitation, all rights to Id Software's trademarks. + +2. Permitted New Creations. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to create for the Software (except any Software code) your own modifications (the "New Creations") that shall operate only with the Software (but not any demo, test, or other version of the Software). You may include within the New Creations certain textures and other images (the "Software Images") from the Software. You shall not create any New Creations that infringe against any third-party right or that are libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. You agree that the New Creations will not be downloaded, shipped, transferred, exported, or re exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the New Creations in any other manner in violation of any applicable law. The New Creations shall not be downloaded or otherwise exported or re exported into (or to a national or resident of) any country to which the United States has embargoed goods or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. You shall not rent, sell, lease, lend, offer on a pay-per-play basis, or otherwise commercially exploit or commercially distribute the New Creations. You are permitted to distribute, without any cost or charge, the New Creations only to other end-users so long as such distribution is not infringing against any third-party right and otherwise is not illegal or unlawful. As noted below, in the event you commit any breach of this Agreement, your license and this Agreement automatically shall terminate, without notice. + +3. Prohibitions with Regard to the Software. You, whether directly or indirectly, shall not do any of the following acts: + +a. rent the Software; + +b. sell the Software; + +c. lease or lend the Software; + +d. offer the Software on a pay-per-play basis; + +e. distribute the Software by any means, including, but not limited to, Internet or other electronic distribution, direct mail, retail, mail order, or other means; + +f. in any other manner and through any medium whatsoever commercially exploit the Software or use the Software for any commercial purpose; + +g. disassemble, reverse engineer, decompile, modify (except as permitted by section 2 hereinabove) or alter the Software; + +h. translate the Software; + +i. reproduce or copy the Software (except as permitted by section 4 hereinbelow); + +j. publicly display the Software; + +k. prepare or develop derivative works based upon the Software; + +l. remove or alter any notices or other markings or legends, such as trademark or copyright notices, affixed on or within the Software or the Printed Materials (as defined in section 5 hereinbelow); or + +m. remove, alter, modify, disable, or reduce any of the anti-piracy measures contained in the Software, including, without limitation, measures relating to multiplayer play. + +4. Prohibition against Cheat Programs. Any attempt by you, either directly or indirectly, to circumvent or bypass any element of the Software to gain any advantage in multiplayer play of the Software is a material breach of this Agreement. It is a material breach of this Agreement for you, whether directly or indirectly, to create, develop, copy, reproduce, distribute, or otherwise make any use of any software program or any modification to the Software ("Cheat Program") itself that enables or allows the user thereof to obtain an advantage or otherwise exploit another Software player or user when playing the Software against other players or users on a local area network, any other network, or on the Internet. Hacking into the executable of the Software, modification of the Software, or any other use of the Software in connection with the creation, development, or use of any such unauthorized Cheat Program is a material breach of this Agreement. Cheat Programs include, but are not limited to, programs that allow Software players or users to see through walls or other level geometry; programs that allow Software players or users to change their rate of speed outside the allowable limits of the Software; programs that crash either and/or other Software players, users, PC clients, or network servers; programs that automatically target other Software players or users (commonly referred to as "aimbots") that automatically simulate Software player or user input for the purpose of gaining an advantage over other Software players or users; or any other program or modification that functions in a similar capacity or allows any prohibited conduct. + +In the event you breach this section or otherwise breach this Agreement, your license and this Agreement automatically shall terminate, without notice, and you shall have no right to play the Software against other players or make any other use of the Software. + +5. Permitted Copying. You may make only the following copies of the Software: (i) you may copy the Software from the CD ROM that you purchase onto your computer hard drive; (ii) you may copy the Software from your computer hard drive into your computer RAM; and (iii) you may make one (1) "back up" or archival copy of the Software on one (1) hard disk. + +6. Intellectual Property Rights. Certain printed materials (the "Printed Materials") accompany the Software. The Software, the Printed Materials, and all copyrights, trademarks, and all other conceivable intellectual property rights related to the Software and the Printed Materials are owned by Id Software and are protected by United States copyright laws, international treaty provisions, and all applicable law, such as the Lanham Act. You must treat the Software and the Printed Materials like any other copyrighted material, as required by 17 U.S.C. § 101 et seq. and other applicable law. You agree to use your best efforts to see that any user of the Software licensed hereunder, the Printed Materials or the New Creations complies with this Agreement. You agree that you are receiving a copy of the Software and the Printed Materials by limited license only and not by sale and that the "first sale" doctrine of 17 U.S.C. § 109 does not apply to your receipt or use of the Software or the Printed Materials. This section shall survive the cancellation or termination of this Agreement. + +7. NO ID SOFTWARE WARRANTIES. ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTY OF NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE PRINTED MATERIALS, THE SOFTWARE IMAGES, AND OTHERWISE. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ID SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD NOT BE RELIED UPON. This section shall survive the cancellation or termination of this Agreement. + +8. Limited Activision Warranty. Activision warrants to the original consumer purchaser of the Software that the recording medium on which the Software is recorded will be free from defects in material and workmanship for ninety (90) days from the date of purchase. If the recording medium is found defective within ninety (90) days of original purchase, Activision agrees to replace, free of charge, any Software discovered to be defective within such period upon its receipt of the Software, postage paid, with the proof of the date of purchase, as long as the Software still is being manufactured by Activision. In the event that the Software no longer is available, Activision retains the right to substitute a similar game program of equal or greater value. This warranty is limited to the recording medium containing the Software as originally provided by Activision and is not applicable to normal wear and tear. This warranty shall not be applicable and shall be void if the defect has arisen through abuse, mistreatment, or neglect. + +EXCEPT AS SET FORTH ABOVE, THIS WARRANTY IS IN LIEU OF ALL OTHER WARRANTIES, WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, AND NO OTHER REPRESENTATIONS OR CLAIMS OF ANY KIND SHALL BE BINDING ON OR OBLIGATE ACTIVISION. + +When returning the Software for warranty replacement, the original Software disks must be sent only in protective packaging and include: (1) photocopy of your dated sales receipt; (2) your name and return address typed or clearly printed; (3) a brief note describing the defect, the problem(s) you are encountering, and the system on which you are running the Software; and (4) if you are returning the Software after the ninety (90) day warranty period, but within one (1) year after the date of purchase, please include check or money order for $10.00 U.S. (A$19 for Australia, or £10.00 for Europe) currency per CD or floppy disk replacement. Note: Certified mail recommended. + +In the United States, send to: + +Warranty Replacements +Activision, Inc. +P.O. Box 67713 +Los Angeles, California 90067 + +In Europe, send to: + +Warranty Replacements +Activision +Parliament House +St. Laurence Way +Slough, Berkshire SL1 2BW +United Kingdom + +In Australia and Asia Pacific territories, send to: + +Warranty Replacements +Activision +Level 5, 51 Rawson street +Epping, NSW 2121 +Australia + +9. Governing Law, Venue, Indemnity, and Liability Limitation. This Agreement shall be construed in accordance with and governed by the applicable laws of the State of Texas (but excluding conflicts of laws principles) and applicable United States federal law. Except as set forth below, exclusive venue for all litigation regarding this Agreement shall be in Dallas County, Texas, and you agree to submit to the jurisdiction of the federal and state courts in Dallas County, Texas, for any such litigation. Exclusive venue for all litigation involving Activision, but not involving Id Software, with regard to this Agreement shall be in Los Angeles County, California, and you agree to submit to the jurisdiction of the courts in Los Angeles, California, for any such litigation. You hereby agree to indemnify, defend and hold harmless Id Software and Activision and Id Software's and Activision's respective officers, employees, directors, agents, licensees (excluding you), sub-licensees (excluding you), successors, and assigns from and against all losses, lawsuits, damages, causes of action, and claims relating to and/or arising from the New Creations or the distribution or other use of the New Creations or relating to and/or arising from your breach of this Agreement. You agree that your unauthorized use of the Software Images, the Printed Materials, or the Software, or any part thereof, immediately and irreparably may damage Id Software such that Id Software could not be adequately compensated solely by a monetary award, and in such event, at Id Software's option, that Id Software shall be entitled to an injunctive order, in addition to all other available remedies, including a monetary award, to prohibit such unauthorized use without the necessity of Id Software posting bond or other security. IN ANY CASE, ID SOFTWARE, ACTIVISION, AND ID SOFTWARE AND ACTIVISION'S RESPECTIVE OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB-LICENSEES (EXCLUDING YOU), SUCCESSORS, AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR PUNITIVE DAMAGES, OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE, ACTIVISION, OR THEIR RESPECTIVE AGENT(S) HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you. This section shall survive the cancellation or termination of this Agreement. + +10. United States Government Restricted Rights. To the extent applicable, the United States Government shall have only those rights to use the Software and the Printed Materials as expressly stated and expressly limited and restricted in this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204, inclusive. + +11. General Provisions. Neither this Agreement nor any part or portion hereof shall be assigned or sublicensed by you. Id Software and Activision each may assign its respective rights under this Agreement in the assigning party's sole discretion. Should any provision of this Agreement be held to be void, invalid, unenforceable, or illegal by a court of competent jurisdiction, the validity and enforceability of the other provisions shall not be affected thereby. If any provision is determined to be unenforceable by a court of competent jurisdiction, you agree to a modification of such provision to provide for enforcement of the provision's intent, to the extent permitted by applicable law. Failure of Id Software or Activision to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH, OR YOUR BREACH OF ANY TERM OR PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT AUTOMATICALLY SHALL TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE AND ACTIVISION MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU THAT ARE AVAILABLE UNDER APPLICABLE LAW AND/OR THIS AGREEMENT. Immediately upon termination of this Agreement, any and all rights you are granted hereunder shall terminate, you shall have no right to use the Software, the Printed Materials, or the New Creations, in any manner, you immediately shall destroy all copies of the Software, the Printed Materials, and the New Creations in your possession, custody, or control, and all rights granted hereunder shall revert, without notice, to and be vested in Id Software. + +YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE OR RAM, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS, IF ANY, AMONG ID SOFTWARE, ACTIVISION, AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO, RELATING TO THE SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, AMONG ID SOFTWARE, ACTIVISION, AND YOU RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT. + + + diff --git a/sys/linux/setup/image-demo/README b/sys/linux/setup/image-demo/README new file mode 100644 index 000000000..1e8420d67 --- /dev/null +++ b/sys/linux/setup/image-demo/README @@ -0,0 +1,31 @@ +DOOM III Linux Demo +=================== + +Minimum system requirements: +---------------------------- + +GNU/Linux system, +Pentium III, 1Ghz +256Mb RAM +Kernel 2.4, 2.6 is recommended +glibc 2.2.4 and up + +3D card: + NV10 or R200 minimum hardware + OpenGL hardware acceleration + 64 MB VRAM + +sound card, OSS or Alsa, stereo sound and 5.1 are supported with both APIs +Alsa version 1.0.6 or above is required + +Installation instructions: +-------------------------- + +By default, the setup will install the files to +/usr/local/games/doom3-demo + +Start the demo with the command: doom3-demo + +For troubleshooting and help, see: +http://zerowing.idsoftware.com/linux/ + diff --git a/sys/linux/setup/image-demo/bin/Linux/x86/doom3-demo b/sys/linux/setup/image-demo/bin/Linux/x86/doom3-demo new file mode 100644 index 000000000..930f0a4b2 --- /dev/null +++ b/sys/linux/setup/image-demo/bin/Linux/x86/doom3-demo @@ -0,0 +1,3 @@ +#!/bin/sh +echo "If you read this, then something failed during the setup" +echo "See http://zerowing.idsoftware.com/linux/ for troubleshooting" diff --git a/sys/linux/setup/image-demo/setup.data/postinstall.sh b/sys/linux/setup/image-demo/setup.data/postinstall.sh new file mode 100644 index 000000000..5bd60066c --- /dev/null +++ b/sys/linux/setup/image-demo/setup.data/postinstall.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# create the wrapper + +create_link() +{ + +echo "#!/bin/sh +# Needed to make symlinks/shortcuts work. +# the binaries must run with correct working directory +cd \"$1\" +export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:. +exec ./$BINARY \"\$@\" +" > "$1/$TARGET" + + chmod a+x "$1/$TARGET" + + # and then we must symlink to this + # can't be done from setup.xml because it would symlink the binary + if [ -n "$SETUP_SYMLINKSPATH" ] && [ -d "$SETUP_SYMLINKSPATH" ] + then + # the symlink might already exists, in case we will remove it + if [ -h "$SETUP_SYMLINKSPATH/$TARGET" ] + then + echo "Removing existing $TARGET symlink" + rm "$SETUP_SYMLINKSPATH/$TARGET" + fi + echo "Installing symlink $SETUP_SYMLINKSPATH/$TARGET -> $1/$TARGET" + ln -s "$1/$TARGET" "$SETUP_SYMLINKSPATH/$TARGET" + fi +} + +BINARY=doom.x86 +TARGET=doom3-demo +create_link "$1" diff --git a/sys/linux/setup/image-demo/setup.data/setup.xml.in b/sys/linux/setup/image-demo/setup.data/setup.xml.in new file mode 100644 index 000000000..f1b83c614 --- /dev/null +++ b/sys/linux/setup/image-demo/setup.data/setup.xml.in @@ -0,0 +1,24 @@ + + + + License.txt + + + README + + M4_PRODUCT + + diff --git a/sys/linux/setup/image-sdk/License.SDK.txt b/sys/linux/setup/image-sdk/License.SDK.txt new file mode 100644 index 000000000..70726b6e8 --- /dev/null +++ b/sys/linux/setup/image-sdk/License.SDK.txt @@ -0,0 +1,55 @@ +DOOM 3 SOFTWARE DEVELOPMENT KIT +LIMITED USE LICENSE AGREEMENT + +This DOOM 3 Software Development Kit Limited Use License Agreement (this "Agreement") is a legal agreement among you, the end-user, and Id Software, Inc. ("Id Software"). BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THIS SOFTWARE DEVELOPMENT KIT (THE "SOFTWARE") FOR THE GAME PROGRAM ENTITLED DOOM 3, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU ACKNOWLEDGE AND UNDERSTAND THAT IN ORDER TO OPERATE THE SOFTWARE, YOU MUST HAVE THE FULL VERSION OF THE ID SOFTWARE GAME ENTITLED DOOM 3 INSTALLED ON YOUR COMPUTER. + +1. Grant of License. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software only in executable or object code form. The term "Software" includes all elements of the Software, including, without limitation, data files and screen displays. You are not receiving any ownership or proprietary right, title, or interest in or to the Software or the copyrights, trademarks, or other rights related thereto. For purposes of the first sentence of this Section, "use" means loading the Software into RAM and/or onto computer hard drive, as well as installation of the Software on a hard disk or other storage device, and means the uses permitted in Sections 2 and 5 hereinbelow. You agree that the Software will not be downloaded, shipped, transferred, exported or re-exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the Software in any other manner in violation of any applicable law. The Software shall not be downloaded or otherwise exported or re-exported into (or to a national or resident of) any country to which the United States has embargoed goods, or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. In exercising your limited rights hereunder, you shall comply, at all times, with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement, including, without limitation, all rights to Id Software's trademarks. + +2. Permitted New Creations. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software to create for the software game DOOM 3 your own modifications (the "New Creations") that shall operate only with DOOM 3 (but not any demo, test, or other version of DOOM 3). You may include within the New Creations certain textures and other images (the "Software Images") from the Software. You shall not create any New Creations that infringe against any third-party right or that are libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. You agree that the New Creations will not be downloaded, shipped, transferred, exported, or re-exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the New Creations in any other manner in violation of any applicable law. The New Creations shall not be downloaded or otherwise exported or re-exported into (or to a national or resident of) any country to which the United States has embargoed goods or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. You shall not rent, sell, lease, lend, offer on a pay-per-play basis, or otherwise commercially exploit or commercially distribute the New Creations. You are permitted to distribute, without any cost or charge, the New Creations only to other end-users so long as such distribution is not infringing against any third-party right and otherwise is not illegal or unlawful. As noted below, in the event you commit any breach of this Agreement, your license and this Agreement automatically shall terminate, without notice. + +3. Prohibitions with Regard to the Software. You, whether directly or indirectly, shall not do any of the following acts: + +a. rent the Software; + +b. sell the Software; + +c. lease or lend the Software; + +d. offer the Software on a pay-per-play basis; + +e. distribute the Software (except as permitted under Section 5 hereinbelow); + +f. in any other manner and through any medium whatsoever commercially exploit the Software or use the Software for any commercial purpose; + +g. disassemble, reverse engineer, decompile, modify (except as permitted under Section 2 hereinabove) or alter the Software; + +h. translate the Software; + +i. reproduce or copy the Software (except as permitted under Section 5 hereinbelow); + +j. publicly display the Software; + +k. prepare or develop derivative works based upon the Software; + +l. remove or alter any notices or other markings or legends, such as trademark or copyright notices, affixed on or within the Software; or + +m. remove, alter, modify, disable, or reduce any of the anti-piracy measures contained in the Software or in DOOM 3, including, without limitation, measures relating to multiplayer play. + +4. Prohibition against Cheat Programs. Any attempt by you, either directly or indirectly, to circumvent or bypass any element of the Software to gain any advantage in multiplayer play of the Software is a material breach of this Agreement. It is a material breach of this Agreement for you, whether directly or indirectly, to create, develop, copy, reproduce, distribute, or otherwise make any use of any software program or any modification to the Software ("Cheat Program") itself that enables or allows the user thereof to obtain an advantage or otherwise exploit another Software player or user when playing the Software against other players or users on a local area network, any other network, or on the Internet. Hacking into the executable of the Software, modification of the Software, or any other use of the Software in connection with the creation, development, or use of any such unauthorized Cheat Program is a material breach of this Agreement. Cheat Programs include, but are not limited to, programs that allow Software players or users to see through walls or other level geometry; programs that allow Software players or users to change their rate of speed outside the allowable limits of the Software; programs that crash either and/or other Software players, users, PC clients, or network servers; programs that automatically target other Software players or users (commonly referred to as "aimbots") that automatically simulate Software player or user input for the purpose of gaining an advantage over other Software players or users; or any other program or modification that functions in a similar capacity or allows any prohibited conduct. + +In the event you breach this Section or otherwise breach this Agreement, your license and this Agreement automatically shall terminate, without notice, and you shall have no right to play the Software against other players or make any other use of the Software. + +5. Permitted Distribution and Copying. So long as this Agreement accompanies each copy you make of the Software, and so long as you comply fully at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to copy the Software and to distribute such copies of the Software free of charge for non-commercial purposes that shall include the free-of-charge distribution of copies of the Software as mounted on the covers of magazines; provided, however, you shall not copy or distribute the Software in any infringing manner or in any manner that violates any law or third-party right, and you shall not distribute the Software together with any material that infringes against any third-party right or that is libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. Subject to the terms and conditions of this Agreement, you also may: (i) download one (1) copy of the Software or copy the Software from the CD ROM on which you received your copy of the Software onto your computer RAM; (ii) copy the Software from your computer RAM onto your computer hard drive; and (iii) make one (1) "backup" or archival copy of the Software on one (1) hard disk. In exercising your limited rights hereunder, you shall comply at all times with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement. You shall not distribute the Software commercially unless you first enter into a separate contract with Id Software, on terms and conditions determined in Id Software's sole discretion, and only upon your receipt of a written agreement executed by an authorized officer of Id Software. + +6. Intellectual Property Rights. The Software and all copyrights, trademarks, and all other conceivable intellectual property rights related to the Software are owned by Id Software and are protected by United States copyright laws, international treaty provisions, and all applicable law, such as the Lanham Act. You must treat the Software like any other copyrighted material, as required by 17 U.S.C. § 101 et seq. and other applicable law. You agree to use your best efforts to see that any user of the Software licensed hereunder or the New Creations complies with this Agreement. You agree that you are receiving a copy of the Software by limited license only and not by sale and that the "first sale" doctrine of 17 U.S.C. § 109 does not apply to your receipt or use of the Software. This Section shall survive the cancellation or termination of this Agreement. + +7. NO ID SOFTWARE WARRANTIES. ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTY OF NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE SOFTWARE IMAGES, AND OTHERWISE. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ID SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD NOT BE RELIED UPON. This Section shall survive the cancellation or termination of this Agreement. + +8. Governing Law, Venue, Indemnity, and Liability Limitation. This Agreement shall be construed in accordance with and governed by the applicable laws of the State of Texas (but excluding conflicts of laws principles) and applicable United States federal law. Except as set forth below, exclusive venue for all litigation regarding this Agreement shall be in Dallas County, Texas, and you agree to submit to the jurisdiction of the federal and state courts in Dallas County, Texas, for any such litigation. You hereby agree to indemnify, defend and hold harmless Id Software and Id Software's officers, employees, directors, agents, licensees (excluding you), sub-licensees (excluding you), successors, and assigns from and against all losses, lawsuits, damages, causes of action, and claims relating to and/or arising from the New Creations or the distribution or other use of the New Creations or relating to and/or arising from your breach of this Agreement. You agree that your unauthorized use of the Software Images or the Software, or any part thereof, immediately and irreparably may damage Id Software such that Id Software could not be adequately compensated solely by a monetary award, and in such event, at Id Software's option, that Id Software shall be entitled to an injunctive order, in addition to all other available remedies, including a monetary award, to prohibit such unauthorized use without the necessity of Id Software posting bond or other security. IN ANY CASE, ID SOFTWARE AND ID SOFTWARE'S OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB-LICENSEES (EXCLUDING YOU), SUCCESSORS, AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR PUNITIVE DAMAGES, OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE OR ITS RESPECTIVE AGENT(S) HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you. This Section shall survive the cancellation or termination of this Agreement. + +9. United States Government Restricted Rights. To the extent applicable, the United States Government shall have only those rights to use the Software as expressly stated and expressly limited and restricted in this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204, inclusive. + +10. General Provisions. Neither this Agreement nor any part or portion hereof shall be assigned or sublicensed by you. Id Software may assign its rights under this Agreement in its sole discretion. Should any provision of this Agreement be held to be void, invalid, unenforceable, or illegal by a court of competent jurisdiction, the validity and enforceability of the other provisions shall not be affected thereby. If any provision is determined to be unenforceable by a court of competent jurisdiction, you agree to a modification of such provision to provide for enforcement of the provision's intent, to the extent permitted by applicable law. Failure of Id Software to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH, OR YOUR BREACH OF ANY TERM OR PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT AUTOMATICALLY SHALL TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU THAT ARE AVAILABLE UNDER APPLICABLE LAW AND/OR THIS AGREEMENT. Immediately upon termination of this Agreement, any and all rights you are granted hereunder shall terminate, you shall have no right to use the Software or the New Creations, in any manner, you immediately shall destroy all copies of the Software and the New Creations in your possession, custody, or control, and all rights granted hereunder shall revert, without notice, to and be vested in Id Software. + +YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS AGREEMENT, AND YOU UNDERSTAND THAT, BY CONTINUING THE DOWNLOAD OR INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM, OR OTHER STORAGE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN, SEPARATE AGREEMENTS, IF ANY, BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO RELATING TO THE SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT. + diff --git a/sys/linux/setup/image-sdk/README.SDK.txt b/sys/linux/setup/image-sdk/README.SDK.txt new file mode 100644 index 000000000..7a733ec1f --- /dev/null +++ b/sys/linux/setup/image-sdk/README.SDK.txt @@ -0,0 +1,21 @@ +DOOM III Linux SDK +================== + +The DOOM build system is based on scons ( a make replacement ) +http://www.scons.org/ +packages are available for most recent distributions + +To build, invoke scons from the src/ directory +use 'scons -h' for build configuration options +scons 0.96 or newer is required for build + +Release 1.3.1 is compiled with gcc 4.0. Note that you can specify the compiler by setting CC and CXX on the command line. If you use a different gcc release line than 4.x, you may run into ABI issues. + +Links +----- + +Doom III Linux FAQ: +http://zerowing.idsoftware.com/linux/doom/ + +Doom III mod developement resources: +http://www.iddevnet.com/ diff --git a/sys/linux/setup/image-sdk/setup.data/config.sh b/sys/linux/setup/image-sdk/setup.data/config.sh new file mode 100644 index 000000000..ec3db42ea --- /dev/null +++ b/sys/linux/setup/image-sdk/setup.data/config.sh @@ -0,0 +1,17 @@ +# +# Use this script to customize the installer bootstrap script +# + +# override some defaults + +# try to get root prior to running setup? +# 0: no +# 1: prompt, but run anyway if fails +# 2: require, abort if root fails +GET_ROOT=0 + +FATAL_ERROR="Error running installer. See http://zerowing.idsoftware.com/linux/ for troubleshooting" + +#XSU_ICON="-i icon.xpm" + +#SU_MESSAGE="It is recommended to run this installation as root.\nPlease enter the root password, or hit return to continue as user" diff --git a/sys/linux/setup/image-sdk/setup.data/setup.xml.in b/sys/linux/setup/image-sdk/setup.data/setup.xml.in new file mode 100644 index 000000000..ea15cae80 --- /dev/null +++ b/sys/linux/setup/image-sdk/setup.data/setup.xml.in @@ -0,0 +1,19 @@ + + + + License.SDK.txt + + + README.SDK.txt + + doom3-sdk + + diff --git a/sys/linux/setup/image/License.txt b/sys/linux/setup/image/License.txt new file mode 100644 index 000000000..aa296f6d5 --- /dev/null +++ b/sys/linux/setup/image/License.txt @@ -0,0 +1,86 @@ +DOOM 3 LIMITED USE SOFTWARE LICENSE AGREEMENT + +This DOOM 3 Limited Use Software License Agreement (this "Agreement") is a legal agreement among you, the end-user, and Id Software, Inc. ("Id Software"), and Activision Publishing, Inc. ("Activision"). BY CONTINUING THE INSTALLATION OF THE FULL VERSION GAME PROGRAM ENTITLED DOOM 3 (THE "SOFTWARE"), BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM OR OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS AGREEMENT. + +1. Grant of License. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to use the Software only in executable or object code form. The term "Software" includes all elements of the Software, including, without limitation, data files and screen displays. You are not receiving any ownership or proprietary right, title, or interest in or to the Software or the copyrights, trademarks, or other rights related thereto. For purposes of the first sentence of this section, "use" means loading the Software into RAM and/or onto computer hard drive, as well as installation of the Software on a hard disk or other storage device, and means the uses permitted in sections 2 and 4 hereinbelow. You agree that the Software will not be downloaded, shipped, transferred, exported or re exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the Software in any other manner in violation of any applicable law. The Software shall not be downloaded or otherwise exported or re exported into (or to a national or resident of) any country to which the United States has embargoed goods, or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. In exercising your limited rights hereunder, you shall comply, at all times, with all applicable laws, regulations, ordinances, and statutes. Id Software reserves all rights not granted in this Agreement, including, without limitation, all rights to Id Software's trademarks. + +2. Permitted New Creations. Subject to the terms and provisions of this Agreement and so long as you fully comply at all times with this Agreement, Id Software grants to you the non-exclusive and limited right to create for the Software (except any Software code) your own modifications (the "New Creations") that shall operate only with the Software (but not any demo, test, or other version of the Software). You may include within the New Creations certain textures and other images (the "Software Images") from the Software. You shall not create any New Creations that infringe against any third-party right or that are libelous, defamatory, obscene, false, misleading, or otherwise illegal or unlawful. You agree that the New Creations will not be downloaded, shipped, transferred, exported, or re exported into any country in violation of the United States Export Administration Act (or any other law governing such matters) by you or anyone at your direction, and that you will not utilize and will not authorize anyone to utilize the New Creations in any other manner in violation of any applicable law. The New Creations shall not be downloaded or otherwise exported or re exported into (or to a national or resident of) any country to which the United States has embargoed goods or to anyone or into any country who/that are prohibited, by applicable law, from receiving such property. You shall not rent, sell, lease, lend, offer on a pay-per-play basis, or otherwise commercially exploit or commercially distribute the New Creations. You are permitted to distribute, without any cost or charge, the New Creations only to other end-users so long as such distribution is not infringing against any third-party right and otherwise is not illegal or unlawful. As noted below, in the event you commit any breach of this Agreement, your license and this Agreement automatically shall terminate, without notice. + +3. Prohibitions with Regard to the Software. You, whether directly or indirectly, shall not do any of the following acts: + +a. rent the Software; + +b. sell the Software; + +c. lease or lend the Software; + +d. offer the Software on a pay-per-play basis; + +e. distribute the Software by any means, including, but not limited to, Internet or other electronic distribution, direct mail, retail, mail order, or other means; + +f. in any other manner and through any medium whatsoever commercially exploit the Software or use the Software for any commercial purpose; + +g. disassemble, reverse engineer, decompile, modify (except as permitted by section 2 hereinabove) or alter the Software; + +h. translate the Software; + +i. reproduce or copy the Software (except as permitted by section 4 hereinbelow); + +j. publicly display the Software; + +k. prepare or develop derivative works based upon the Software; + +l. remove or alter any notices or other markings or legends, such as trademark or copyright notices, affixed on or within the Software or the Printed Materials (as defined in section 5 hereinbelow); or + +m. remove, alter, modify, disable, or reduce any of the anti-piracy measures contained in the Software, including, without limitation, measures relating to multiplayer play. + +4. Prohibition against Cheat Programs. Any attempt by you, either directly or indirectly, to circumvent or bypass any element of the Software to gain any advantage in multiplayer play of the Software is a material breach of this Agreement. It is a material breach of this Agreement for you, whether directly or indirectly, to create, develop, copy, reproduce, distribute, or otherwise make any use of any software program or any modification to the Software ("Cheat Program") itself that enables or allows the user thereof to obtain an advantage or otherwise exploit another Software player or user when playing the Software against other players or users on a local area network, any other network, or on the Internet. Hacking into the executable of the Software, modification of the Software, or any other use of the Software in connection with the creation, development, or use of any such unauthorized Cheat Program is a material breach of this Agreement. Cheat Programs include, but are not limited to, programs that allow Software players or users to see through walls or other level geometry; programs that allow Software players or users to change their rate of speed outside the allowable limits of the Software; programs that crash either and/or other Software players, users, PC clients, or network servers; programs that automatically target other Software players or users (commonly referred to as "aimbots") that automatically simulate Software player or user input for the purpose of gaining an advantage over other Software players or users; or any other program or modification that functions in a similar capacity or allows any prohibited conduct. + +In the event you breach this section or otherwise breach this Agreement, your license and this Agreement automatically shall terminate, without notice, and you shall have no right to play the Software against other players or make any other use of the Software. + +5. Permitted Copying. You may make only the following copies of the Software: (i) you may copy the Software from the CD ROM that you purchase onto your computer hard drive; (ii) you may copy the Software from your computer hard drive into your computer RAM; and (iii) you may make one (1) "back up" or archival copy of the Software on one (1) hard disk. + +6. Intellectual Property Rights. Certain printed materials (the "Printed Materials") accompany the Software. The Software, the Printed Materials, and all copyrights, trademarks, and all other conceivable intellectual property rights related to the Software and the Printed Materials are owned by Id Software and are protected by United States copyright laws, international treaty provisions, and all applicable law, such as the Lanham Act. You must treat the Software and the Printed Materials like any other copyrighted material, as required by 17 U.S.C. § 101 et seq. and other applicable law. You agree to use your best efforts to see that any user of the Software licensed hereunder, the Printed Materials or the New Creations complies with this Agreement. You agree that you are receiving a copy of the Software and the Printed Materials by limited license only and not by sale and that the "first sale" doctrine of 17 U.S.C. § 109 does not apply to your receipt or use of the Software or the Printed Materials. This section shall survive the cancellation or termination of this Agreement. + +7. NO ID SOFTWARE WARRANTIES. ID SOFTWARE DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTY OF NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE, THE PRINTED MATERIALS, THE SOFTWARE IMAGES, AND OTHERWISE. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ID SOFTWARE DOES NOT WARRANT THAT THE SOFTWARE OR THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC OR SPECIAL REQUIREMENTS. ADDITIONAL STATEMENTS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID SOFTWARE AND SHOULD NOT BE RELIED UPON. This section shall survive the cancellation or termination of this Agreement. + +8. Limited Activision Warranty. Activision warrants to the original consumer purchaser of the Software that the recording medium on which the Software is recorded will be free from defects in material and workmanship for ninety (90) days from the date of purchase. If the recording medium is found defective within ninety (90) days of original purchase, Activision agrees to replace, free of charge, any Software discovered to be defective within such period upon its receipt of the Software, postage paid, with the proof of the date of purchase, as long as the Software still is being manufactured by Activision. In the event that the Software no longer is available, Activision retains the right to substitute a similar game program of equal or greater value. This warranty is limited to the recording medium containing the Software as originally provided by Activision and is not applicable to normal wear and tear. This warranty shall not be applicable and shall be void if the defect has arisen through abuse, mistreatment, or neglect. + +EXCEPT AS SET FORTH ABOVE, THIS WARRANTY IS IN LIEU OF ALL OTHER WARRANTIES, WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, AND NO OTHER REPRESENTATIONS OR CLAIMS OF ANY KIND SHALL BE BINDING ON OR OBLIGATE ACTIVISION. + +When returning the Software for warranty replacement, the original Software disks must be sent only in protective packaging and include: (1) photocopy of your dated sales receipt; (2) your name and return address typed or clearly printed; (3) a brief note describing the defect, the problem(s) you are encountering, and the system on which you are running the Software; and (4) if you are returning the Software after the ninety (90) day warranty period, but within one (1) year after the date of purchase, please include check or money order for $10.00 U.S. (A$19 for Australia, or £10.00 for Europe) currency per CD or floppy disk replacement. Note: Certified mail recommended. + +In the United States, send to: + +Warranty Replacements +Activision, Inc. +P.O. Box 67713 +Los Angeles, California 90067 + +In Europe, send to: + +Warranty Replacements +Activision +Parliament House +St. Laurence Way +Slough, Berkshire SL1 2BW +United Kingdom + +In Australia and Asia Pacific territories, send to: + +Warranty Replacements +Activision +Level 5, 51 Rawson street +Epping, NSW 2121 +Australia + +9. Governing Law, Venue, Indemnity, and Liability Limitation. This Agreement shall be construed in accordance with and governed by the applicable laws of the State of Texas (but excluding conflicts of laws principles) and applicable United States federal law. Except as set forth below, exclusive venue for all litigation regarding this Agreement shall be in Dallas County, Texas, and you agree to submit to the jurisdiction of the federal and state courts in Dallas County, Texas, for any such litigation. Exclusive venue for all litigation involving Activision, but not involving Id Software, with regard to this Agreement shall be in Los Angeles County, California, and you agree to submit to the jurisdiction of the courts in Los Angeles, California, for any such litigation. You hereby agree to indemnify, defend and hold harmless Id Software and Activision and Id Software's and Activision's respective officers, employees, directors, agents, licensees (excluding you), sub-licensees (excluding you), successors, and assigns from and against all losses, lawsuits, damages, causes of action, and claims relating to and/or arising from the New Creations or the distribution or other use of the New Creations or relating to and/or arising from your breach of this Agreement. You agree that your unauthorized use of the Software Images, the Printed Materials, or the Software, or any part thereof, immediately and irreparably may damage Id Software such that Id Software could not be adequately compensated solely by a monetary award, and in such event, at Id Software's option, that Id Software shall be entitled to an injunctive order, in addition to all other available remedies, including a monetary award, to prohibit such unauthorized use without the necessity of Id Software posting bond or other security. IN ANY CASE, ID SOFTWARE, ACTIVISION, AND ID SOFTWARE AND ACTIVISION'S RESPECTIVE OFFICERS, EMPLOYEES, DIRECTORS, SHAREHOLDERS, REPRESENTATIVES, AGENTS, LICENSEES (EXCLUDING YOU), SUB-LICENSEES (EXCLUDING YOU), SUCCESSORS, AND ASSIGNS SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR PUNITIVE DAMAGES, OR ANY OTHER DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL THEORY EVEN IF ID SOFTWARE, ACTIVISION, OR THEIR RESPECTIVE AGENT(S) HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH DAMAGES, OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you. This section shall survive the cancellation or termination of this Agreement. + +10. United States Government Restricted Rights. To the extent applicable, the United States Government shall have only those rights to use the Software and the Printed Materials as expressly stated and expressly limited and restricted in this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204, inclusive. + +11. General Provisions. Neither this Agreement nor any part or portion hereof shall be assigned or sublicensed by you. Id Software and Activision each may assign its respective rights under this Agreement in the assigning party's sole discretion. Should any provision of this Agreement be held to be void, invalid, unenforceable, or illegal by a court of competent jurisdiction, the validity and enforceability of the other provisions shall not be affected thereby. If any provision is determined to be unenforceable by a court of competent jurisdiction, you agree to a modification of such provision to provide for enforcement of the provision's intent, to the extent permitted by applicable law. Failure of Id Software or Activision to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. IMMEDIATELY UPON YOUR FAILURE TO COMPLY WITH, OR YOUR BREACH OF ANY TERM OR PROVISION OF THIS AGREEMENT, YOUR LICENSE GRANTED HEREIN AND THIS AGREEMENT AUTOMATICALLY SHALL TERMINATE, WITHOUT NOTICE, AND ID SOFTWARE AND ACTIVISION MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU THAT ARE AVAILABLE UNDER APPLICABLE LAW AND/OR THIS AGREEMENT. Immediately upon termination of this Agreement, any and all rights you are granted hereunder shall terminate, you shall have no right to use the Software, the Printed Materials, or the New Creations, in any manner, you immediately shall destroy all copies of the Software, the Printed Materials, and the New Creations in your possession, custody, or control, and all rights granted hereunder shall revert, without notice, to and be vested in Id Software. + +YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE OR RAM, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS, IF ANY, AMONG ID SOFTWARE, ACTIVISION, AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES HERETO, RELATING TO THE SUBJECT MATTER HEREOF. THIS AGREEMENT SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS, OR UNDERSTANDINGS, AND ANY OTHER COMMUNICATIONS, IF ANY, AMONG ID SOFTWARE, ACTIVISION, AND YOU RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT. + + + diff --git a/sys/linux/setup/image/README b/sys/linux/setup/image/README new file mode 100644 index 000000000..c0a84633e --- /dev/null +++ b/sys/linux/setup/image/README @@ -0,0 +1,53 @@ +DOOM III Linux +============== + +Minimum system requirements: +---------------------------- + +GNU/Linux system, +Pentium III, 1Ghz +256Mb RAM +Kernel 2.4, 2.6 is recommended +glibc 2.2.4 and up + +3D card: + NV10 or R200 minimum hardware + OpenGL hardware acceleration + 64 MB VRAM + +sound card, OSS or Alsa, stereo sound and 5.1 are supported with both APIs +Alsa version 1.0.6 or above is required + +A licensed copy of Doom III retail for Windows +In order to play the additional Resurrection of Evil Expansion Pack, a licensed copy of the Expansion Pack for Windows + +Installation instructions: +-------------------------- + +The following files need to be copied from the win32 install CDs +to your base/ directory ( md5 sums provided below as reference ) +by default, /usr/local/games/doom3/base + +71b8d37b2444d3d86a36fd61783844fe base/pak000.pk4 +4bc4f3ba04ec2b4f4837be40e840a3c1 base/pak001.pk4 +fa84069e9642ad9aa4b49624150cc345 base/pak002.pk4 +f22d8464997924e4913e467e7d62d5fe base/pak003.pk4 +38561a3c73f93f2e6fd31abf1d4e9102 base/pak004.pk4 + +If you are also installing the Resurrection of Evil Expansion Pack, +you need to copy the following file to your d3xp/ directory +by default, /usr/local/games/doom3/d3xp + +a883fef0fd10aadeb73d34c462ff865d d3xp/pak000.pk4 + +Localization is not supported on Linux ( only english ), you should not copy over any of the zpak files. + +Start the game with the command: doom3 +Start the dedicated server with the command: doom3-dedicated + +If installed, you can start the Expansion Pack directly from the command line with the command: doom3 +set fs_game d3xp +Or you can select it in the mods menu of the base game. + +For troubleshooting and help, see: +http://zerowing.idsoftware.com/linux/ + diff --git a/sys/linux/setup/image/bin/Linux/x86/doom3 b/sys/linux/setup/image/bin/Linux/x86/doom3 new file mode 100644 index 000000000..930f0a4b2 --- /dev/null +++ b/sys/linux/setup/image/bin/Linux/x86/doom3 @@ -0,0 +1,3 @@ +#!/bin/sh +echo "If you read this, then something failed during the setup" +echo "See http://zerowing.idsoftware.com/linux/ for troubleshooting" diff --git a/sys/linux/setup/image/bin/Linux/x86/doom3-dedicated b/sys/linux/setup/image/bin/Linux/x86/doom3-dedicated new file mode 100644 index 000000000..930f0a4b2 --- /dev/null +++ b/sys/linux/setup/image/bin/Linux/x86/doom3-dedicated @@ -0,0 +1,3 @@ +#!/bin/sh +echo "If you read this, then something failed during the setup" +echo "See http://zerowing.idsoftware.com/linux/ for troubleshooting" diff --git a/sys/linux/setup/image/doom3.png b/sys/linux/setup/image/doom3.png new file mode 100644 index 000000000..769e9fa9a Binary files /dev/null and b/sys/linux/setup/image/doom3.png differ diff --git a/sys/linux/setup/image/openurl.sh b/sys/linux/setup/image/openurl.sh new file mode 100644 index 000000000..5c177c1cb --- /dev/null +++ b/sys/linux/setup/image/openurl.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# opening URLs into your favorite web browser +# feel free to tweak this to your needs + +if [ x`which firefox` != x ] +then + firefox "$1" +elif [ x`which mozilla` != x ] +then + mozilla "$1" +elif [ x`which opera` != x ] +then + opera "$1" +else + xterm -e lynx "$1" +fi + diff --git a/sys/linux/setup/image/setup.data/postinstall.sh b/sys/linux/setup/image/setup.data/postinstall.sh new file mode 100644 index 000000000..cfe31f89b --- /dev/null +++ b/sys/linux/setup/image/setup.data/postinstall.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# create the wrapper + +create_link() +{ + +echo "#!/bin/sh +# Needed to make symlinks/shortcuts work. +# the binaries must run with correct working directory +cd \"$1\" +export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:. +exec ./$BINARY \"\$@\" +" > "$1/$TARGET" + + chmod a+x "$1/$TARGET" + + # and then we must symlink to this + # can't be done from setup.xml because it would symlink the binary + if [ -n "$SETUP_SYMLINKSPATH" ] && [ -d "$SETUP_SYMLINKSPATH" ] + then + # the symlink might already exists, in case we will remove it + if [ -h "$SETUP_SYMLINKSPATH/$TARGET" ] + then + echo "Removing existing $TARGET symlink" + rm "$SETUP_SYMLINKSPATH/$TARGET" + fi + echo "Installing symlink $SETUP_SYMLINKSPATH/$TARGET -> $1/$TARGET" + ln -s "$1/$TARGET" "$SETUP_SYMLINKSPATH/$TARGET" + fi +} + +BINARY=doom.x86 +TARGET=doom3 +create_link "$1" +BINARY=doomded.x86 +TARGET=doom3-dedicated +create_link "$1" + +chmod +x "$1/openurl.sh" diff --git a/sys/linux/setup/image/setup.data/setup.xml.in b/sys/linux/setup/image/setup.data/setup.xml.in new file mode 100644 index 000000000..70d101667 --- /dev/null +++ b/sys/linux/setup/image/setup.data/setup.xml.in @@ -0,0 +1,42 @@ + + + + License.txt + + + README + + M4_PRODUCT + + + diff --git a/sys/linux/setup/loki_setup.patch b/sys/linux/setup/loki_setup.patch new file mode 100644 index 000000000..efa74b1fd --- /dev/null +++ b/sys/linux/setup/loki_setup.patch @@ -0,0 +1,36 @@ +? install +? to +? image/setup.data/bin +Index: Makefile.in +=================================================================== +RCS file: /cvs/cvsroot/loki_setup/Makefile.in,v +retrieving revision 1.32 +diff -u -r1.32 Makefile.in +--- Makefile.in 4 Aug 2004 03:12:34 -0000 1.32 ++++ Makefile.in 9 Aug 2004 10:16:22 -0000 +@@ -65,7 +65,8 @@ + CARBON_LIBS = $(COMMON_LIBS) @LIBS@ @CARBON_LIBS@ + CONSOLE_LIBS = $(LIBS) @CONSOLE_LIBS@ + +-all: do-plugins @DO_DIALOG@ setup setup.gtk uninstall xsu ++#all: do-plugins @DO_DIALOG@ setup setup.gtk uninstall xsu ++all: do-plugins @DO_DIALOG@ setup + + testxml: testxml.o + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) +@@ -139,6 +140,7 @@ + ifeq ($(DYN_PLUGINS),true) + $(MAKE) -C plugins install + endif ++ mkdir -p install to image/setup.data/bin/$(os)/$(arch)/$(libc) + @if [ -d image/setup.data/bin/$(os)/$(arch)/$(libc) ]; then \ + cp setup image/setup.data/bin/$(os)/$(arch); \ + strip image/setup.data/bin/$(os)/$(arch)/setup; \ +@@ -155,6 +157,7 @@ + else \ + echo No directory to copy the binary files to.; \ + fi ++ echo installed to image/setup.data/bin/$(os)/$(arch)/$(libc) + + install-image: all + ifeq ($(DYN_PLUGINS),true) diff --git a/sys/linux/setup/lokisetup/loki_setup.tgz b/sys/linux/setup/lokisetup/loki_setup.tgz new file mode 100644 index 000000000..7c28d2440 Binary files /dev/null and b/sys/linux/setup/lokisetup/loki_setup.tgz differ diff --git a/sys/linux/setup/lokisetup/loki_setupdb.tgz b/sys/linux/setup/lokisetup/loki_setupdb.tgz new file mode 100644 index 000000000..5527f5a14 Binary files /dev/null and b/sys/linux/setup/lokisetup/loki_setupdb.tgz differ diff --git a/sys/linux/setup/lokisetup/xsu.diff b/sys/linux/setup/lokisetup/xsu.diff new file mode 100644 index 000000000..ba830bb65 --- /dev/null +++ b/sys/linux/setup/lokisetup/xsu.diff @@ -0,0 +1,170 @@ +--- loki_setup/CHANGES 2004-11-20 07:43:42.000000000 -0600 ++++ loki_setup.zinx/CHANGES 2005-03-16 16:56:46.400205504 -0600 +@@ -1,4 +1,6 @@ + Current: ++Christopher Lais (Id Software) - Wed Mar 16 08:09:59 CST 2005 ++ * Fix handling of invalid password in xsu + Ryan C. Gordon (icculus.org) - Sat Nov 20 08:42:16 EST 2004 + * Minor carbon_ui tweaks and corrections to update function. + Ludwig Nussel - Wed Nov 10 14:21:21 PST 2004 +--- loki_setup/xsu.c 2003-07-02 14:40:39.000000000 -0500 ++++ loki_setup.zinx/xsu.c 2005-03-16 16:36:17.752988272 -0600 +@@ -37,6 +37,7 @@ + #include "xsu.h" + + static int term = -1; ++static int term_status = 0; + + static gint + exec_su_failed (gpointer user_data) +@@ -79,22 +80,25 @@ + if ( sig == SIGCHLD && term > 0 ) { + int status; + pid_t pid = wait(&status); ++ ++ close(term); term = -1; ++ term_status = status; ++ + if ( WIFEXITED(status) ) { + #ifdef DEBUG + fprintf(stderr,"Child %d returned\n", pid); + #endif +- gtk_exit(WEXITSTATUS(status)); ++ /* This is handled at the end of xsu_process */ ++ return; + } else if ( WIFSIGNALED(status) ) { + #ifdef DEBUG + fprintf(stderr,"Xsu: subprocess %d has died from signal %d\n", pid, WTERMSIG(status)); + #endif + gtk_exit(EXIT_ERROR); ++ } else { ++ fprintf(stderr, "Xsu: got SIGCHLD from %d for unknown reason (%08x)\n", pid, status); ++ gtk_exit(EXIT_ERROR); + } +- close(term); term = -1; +- +- while (gtk_events_pending ()) +- gtk_main_iteration (); +- gtk_main_quit (); + } + } + +@@ -135,22 +139,27 @@ + gchar *buffer; + char *argv[6], c; + fd_set fds; +- struct timeval delay = { 0, 10*1000 }; /* 10 ms wait */ ++ struct timeval delay; + + #ifdef DEBUG + printf("void xsu_perform()\n"); + #endif + ++ gtk_widget_hide (gtk_xsu_window); ++ ++ if (password == NULL) ++ return; ++ + /* 0.2.1 * + Minor security fix. Password would remain in memory if we don't + clean the password textbox. + */ +- gtk_entry_set_text(GTK_ENTRY(gtk_password_textbox),""); +- gtk_widget_hide (gtk_xsu_window); +- +- if (password == NULL) +- return; ++ password_return = g_strdup_printf ("%s\n", password); + ++ /* Technically, we aren't supposed to modify this, but it should ++ usually be OK because we're explicitly clearing it afterwards. */ ++ memset (password, 0, strlen (password)); ++ gtk_entry_set_text(GTK_ENTRY(gtk_password_textbox),""); + + /* xsu 0.2.1 * + Option to set the DISPLAY environment +@@ -177,6 +186,9 @@ + argv[2] = "-c"; + argv[3] = buffer; + argv[4] = NULL; ++#ifdef DEBUG ++ fprintf(stderr, "%s %s -c %s\n", su_command, username, buffer); ++#endif + term = exec_program(su_command, argv); + /* We are not a gnome-application anymore but under control of su */ + +@@ -231,33 +243,65 @@ + fprintf(stderr, "Got it!\n"); + #endif + +- /* Discard any remaining characters on stdin */ +- for(;;) { ++ /* Slurp up any extra characters immediately after the password prompt, ++ because su might clear the buffer after we send the password if we ++ don't. */ ++ for (;;) { + FD_ZERO(&fds); + FD_SET(term, &fds); +- if ( select(term+1, &fds, NULL, NULL, &delay) ) { +- if ( read(term, &c, 1) <= 0 ) +- break; ++ ++ delay.tv_sec = 0; ++ delay.tv_usec = 10*1000; /* 10 ms wait */ ++ ++ if (select(term+1, &fds, NULL, NULL, &delay) > 0) { ++ if (read(term, &c, 1) < 0) ++ break; + } else + break; + } + +- password_return = g_strdup_printf ("%s\n", password); + #ifdef DEBUG + fprintf(stderr,"Sending password\n"); + #endif + /* 0.2.2 * + Minor security fix, clear the password from memory + */ +- memset (password, 0, strlen (password)); + if ( write(term, password_return, strlen(password_return)) < 0 ) { + perror("write"); + } ++ + memset (password_return, 0, strlen (password_return)); + g_free (password_return); password_return = NULL; +- g_free (password); password = NULL; + +- //gtk_main(); ++ /* Eat up any output, and wait for a SIGCHLD saying su exited */ ++ while (term >= 0) { ++ FD_ZERO(&fds); ++ FD_SET(term, &fds); ++ ++ delay.tv_sec = 0; ++ delay.tv_usec = 10*1000; /* 10 ms wait */ ++ ++ if ( select(term+1, &fds, NULL, NULL, &delay) > 0 ) { ++ read(term, &c, 1); ++#ifdef DEBUG ++ fprintf(stderr, "read from pty: %02x\n", c); ++#endif ++ } ++ ++ while (gtk_events_pending ()) ++ gtk_main_iteration (); ++ } ++ ++ if (WIFEXITED(term_status) && WEXITSTATUS(term_status)) { ++ /* su failed, so ask for the password again */ ++#ifdef DEBUG ++ fprintf(stderr, "returning control to gtk\n"); ++#endif ++ gtk_widget_show (gtk_xsu_window); ++ } else { ++ /* Exit normally */ ++ gtk_main_quit(); ++ } + } + + diff --git a/sys/linux/setup/makeself/COPYING b/sys/linux/setup/makeself/COPYING new file mode 100644 index 000000000..a52b16e40 --- /dev/null +++ b/sys/linux/setup/makeself/COPYING @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/sys/linux/setup/makeself/README b/sys/linux/setup/makeself/README new file mode 100644 index 000000000..30e2c12bc --- /dev/null +++ b/sys/linux/setup/makeself/README @@ -0,0 +1,307 @@ +The following was generated from http://www.megastep.org/makeself/ +----------------------- + + + makeself - Make self-extractable archives on Unix + + [1]makeself.sh is a small shell script that generates a + self-extractable tar.gz archive from a directory. The resulting file + appears as a shell script (many of those have a .run suffix), and can + be launched as is. The archive will then uncompress itself to a + temporary directory and an optional arbitrary command will be executed + (for example an installation script). This is pretty similar to + archives generated with WinZip Self-Extractor in the Windows world. + Makeself archives also include checksums for integrity self-validation + (CRC and/or MD5 checksums). + + The makeself.sh script itself is used only to create the archives from + a directory of files. The resultant archive is actually a compressed + (using gzip, bzip2, or compress) TAR archive, with a small shell + script stub at the beginning. This small stub performs all the steps + of extracting the files, running the embedded command, and removing + the temporary files when it's all over. All what the user has to do to + install the software contained in such an archive is to "run" the + archive, i.e sh nice-software.run. I recommend using the "run" (which + was introduced by some Makeself archives released by Loki Software) or + "sh" suffix for such archives not to confuse the users, since they + know it's actually shell scripts (with quite a lot of binary data + attached to it though!). + + I am trying to keep the code of this script as portable as possible, + i.e it's not relying on any bash-specific features and only calls + commands that are installed on any functioning UNIX-compatible system. + This script as well as the archives it generates should run on any + Unix flavor, with any compatible Bourne shell, provided of course that + the compression programs are available. + + As of version 2.1, Makeself has been rewritten and tested on the + following platforms : + * Linux (all distributions) + * Sun Solaris (8 tested) + * HP-UX (tested on 11.0 and 11i on HPPA RISC) + * SCO OpenUnix and OpenServer + * IBM AIX 5.1L + * MacOS X (Darwin) + * SGI IRIX 6.5 + * FreeBSD + * UnicOS / Cray + + If you successfully run Makeself and/or archives created with it on + another system, then [2]let me know! + + Examples of publicly available archives made using makeself are : + * Game patches and installers for [3]Id Software games like Quake 3 + for Linux or Return To Castle Wolfenstien ; + * All game patches released by [4]Loki Software for the Linux + version of popular games ; + * The [5]nVidia drivers for Linux + * The [6]Makeself distribution itself ;-) + * and countless others... + + Important note for Apache users: By default, most Web servers will + think that Makeself archives are regular text files and thus they may + show up as text in a Web browser. The correct way to prevent this is + to add a MIME type for this file format, like so (in httpd.conf) : + AddType application/x-makeself .run + + Important note for recent GNU/Linux distributions: Archives created + with Makeself prior to v2.1.2 were using an old syntax for the head + and tail Unix commands that is being progressively obsoleted in their + GNU forms. Therefore you may have problems uncompressing some of these + archives. A workaround for this is to set the environment variable + $_POSIX2_VERSION to enable the old syntax, i.e. : + export _POSIX2_VERSION=199209 + +Usage + + The syntax of makeself is the following: + + makeself.sh [args] archive_dir file_name label startup_script + [script_args] + * args are optional options for Makeself. The available ones are : + + --version : Prints the version number on stdout, then exits + immediately + + --gzip : Use gzip for compression (is the default on + platforms on which gzip is commonly available, like Linux) + + --bzip2 : Use bzip2 instead of gzip for better compression. + The bzip2 command must be available in the command path. I + recommend that you set the prefix to something like + '.bz2.run' for the archive, so that potential users know that + they'll need bzip2 to extract it. + + --compress : Use the UNIX "compress" command to compress the + data. This should be the default on all platforms that don't + have gzip available. + + --nocomp : Do not use any compression for the archive, which + will then be an uncompressed TAR. + + --notemp : The generated archive will not extract the files + to a temporary directory, but in a new directory created in + the current directory. This is better to distribute software + packages that may extract and compile by themselves (i.e. + launch the compilation through the embedded script). + + --current : Files will be extracted to the current directory, + instead of in a subdirectory. This option implies --notemp + above. + + --follow : Follow the symbolic links inside of the archive + directory, i.e. store the files that are being pointed to + instead of the links themselves. + + --append (new in 2.1.x): Append data to an existing archive, + instead of creating a new one. In this mode, the settings + from the original archive are reused (compression type, + label, embedded script), and thus don't need to be specified + again on the command line. + + --header : Makeself 2.0 uses a separate file to store the + header stub, called "makeself-header.sh". By default, it is + assumed that it is stored in the same location as + makeself.sh. This option can be used to specify its actual + location if it is stored someplace else. + + --copy : Upon extraction, the archive will first extract + itself to a temporary directory. The main application of this + is to allow self-contained installers stored in a Makeself + archive on a CD, when the installer program will later need + to unmount the CD and allow a new one to be inserted. This + prevents "Filesystem busy" errors for installers that span + multiple CDs. + + --nox11 : Disable the automatic spawning of a new terminal in + X11. + + --nowait : When executed from a new X11 terminal, disable the + user prompt at the end of the script execution. + + --nomd5 and --nocrc : Disable the creation of a MD5 / CRC + checksum for the archive. This speeds up the extraction + process if integrity checking is not necessary. + + --lsm file : Provide and LSM file to makeself, that will be + embedded in the generated archive. LSM files are describing a + software package in a way that is easily parseable. The LSM + entry can then be later retrieved using the '-lsm' argument + to the archive. An exemple of a LSM file is provided with + Makeself. + * archive_dir is the name of the directory that contains the files + to be archived + * file_name is the name of the archive to be created + * label is an arbitrary text string describing the package. It will + be displayed while extracting the files. + * startup_script is the command to be executed from within the + directory of extracted files. Thus, if you wish to execute a + program contain in this directory, you must prefix your command + with "./". For example, ./program will be fine. The script_args + are additionnal arguments for this command. + + Here is an example, assuming the user has a package image stored in a + /home/joe/mysoft, and he wants to generate a self-extracting package + named mysoft.sh, which will launch the "setup" script initially stored + in /home/joe/mysoft : + + makeself.sh /home/joe/mysoft mysoft.sh "Joe's Nice Software Package" + ./setup + Here is also how I created the [7]makeself.run archive which contains + the Makeself distribution : + + makeself.sh --notemp makeself makeself.run "Makeself by Stephane + Peter" echo "Makeself has extracted itself" + + Archives generated with Makeself 2.1 can be passed the following + arguments: + + * --keep : Prevent the files to be extracted in a temporary + directory that will be removed after the embedded script's + execution. The files will then be extracted in the current working + directory and will stay here until you remove them. + * --verbose : Will prompt the user before executing the embedded + command + * --target dir : Allows to extract the archive in an arbitrary + place. + * --nox11 : Do not spawn a X11 terminal. + * --confirm : Prompt the user for confirmation before running the + embedded command. + * --info : Print out general information about the archive (does not + extract). + * --lsm : Print out the LSM entry, if it is present. + * --list : List the files in the archive. + * --check : Check the archive for integrity using the embedded + checksums. Does not extract the archive. + * --nochown : By default, a "chown -R" command is run on the target + directory after extraction, so that all files belong to the + current user. This is mostly needed if you are running as root, as + tar will then try to recreate the initial user ownerships. You may + disable this behavior with this flag. + * --tar : Run the tar command on the contents of the archive, using + the following arguments as parameter for the command. + * --noexec : Do not run the embedded script after extraction. + + Any subsequent arguments to the archive will be passed as additional + arguments to the embedded command. You should explicitly use the -- + special command-line construct before any such options to make sure + that Makeself will not try to interpret them. + +License + + Makeself is covered by the [8]GNU General Public License (GPL) version + 2 and above. Archives generated by Makeself don't have to be placed + under this license (although I encourage it ;-)), since the archive + itself is merely data for Makeself. + +Download + + Get the latest official distribution [9]here (version 2.1.3). + + The latest development version can be grabbed from the Loki Setup CVS + module, at [10]cvs.icculus.org. + +Version history + + * v1.0: Initial public release + * v1.1: The archive can be passed parameters that will be passed on + to the embedded script, thanks to John C. Quillan + * v1.2: Cosmetic updates, support for bzip2 compression and + non-temporary archives. Many ideas thanks to Francois Petitjean. + * v1.3: More patches from Bjarni R. Einarsson and Francois + Petitjean: Support for no compression (--nocomp), script is no + longer mandatory, automatic launch in an xterm, optional verbose + output, and -target archive option to indicate where to extract + the files. + * v1.4: Many patches from Francois Petitjean: improved UNIX + compatibility, automatic integrity checking, support of LSM files + to get info on the package at run time.. + * v1.5.x: A lot of bugfixes, and many other patches, including + automatic verification through the usage of checksums. Version + 1.5.5 was the stable release for a long time, even though the Web + page didn't get updated ;-). Makeself was also officially made a + part of the [11]Loki Setup installer, and its source is being + maintained as part of this package. + * v2.0: Complete internal rewrite of Makeself. The command-line + parsing was vastly improved, the overall maintenance of the + package was greatly improved by separating the stub from + makeself.sh. Also Makeself was ported and tested to a variety of + Unix platforms. + * v2.0.1: First public release of the new 2.0 branch. Prior versions + are officially obsoleted. This release introduced the '--copy' + argument that was introduced in response to a need for the + [12]UT2K3 Linux installer. + * v2.1.0: Big change : Makeself can now support multiple embedded + tarballs, each stored separately with their own checksums. An + existing archive can be updated with the --append flag. Checksums + are also better managed, and the --nochown option for archives + appeared. + * v2.1.1: Fixes related to the Unix compression (compress command). + Some Linux distributions made the insane choice to make it + unavailable, even though gzip is capable of uncompressing these + files, plus some more bugfixes in the extraction and checksum + code. + * v2.1.2: Some bug fixes. Use head -n to avoid problems with POSIX + conformance. + * v2.1.3: Bug fixes with the command line when spawning terminals. + Added --tar, --noexec for archives. Added --nomd5 and --nomd5 to + avoid creating checksums in archives. The embedded script is now + run through "eval". The --info output now includes the command + used to create the archive. A man page was contributed by Bartosz + Fenski. + +Links + + * Check out the [13]"Loki setup" installer, used to install many + Linux games and other applications, and of which I am the + co-author. Since the demise of Loki, I am now the official + maintainer of the project, and it is now being hosted on + [14]icculus.org, as well as a bunch of other ex-Loki projects (and + a lot of other good stuff!). + * Bjarni R. Einarsson also wrote the setup.sh installer script, + inspired by Makeself. [15]Check it out ! + +Contact + + This script was written by [16]Stéphane Peter (megastep at + megastep.org) I welcome any enhancements and suggestions. + + Contributions were included from John C. Quillan, Bjarni R. Einarsson, + Francois Petitjean, and Ryan C. Gordon, thanks to them! If you think I + forgot your name, don't hesitate to contact me. + + icculus.org also has a [17]Bugzilla server available that allows bug + reports to be submitted for Loki setup, and since Makeself is a part + of Loki setup, you can submit bug reports from there! + _________________________________________________________________ + + + [18]Stéphane Peter + + Last modified: Sun May 2 00:08:49 PDT 2004 + +References + + 1. http://www.megastep.org/makeself/makeself.run + 2. mailto:megastep@REMOVEME.megastep.org + 3. http://www.idsoftware.com/ + 4. http://www.lokigames.com/products/myth2/updates.php3 + 5. http://www.nvidia.com/ + 6. http://www.megastep.org/makeself/makeself.run + 7. http://www.megastep.org/makeself/makeself.run + 8. http://www.gnu.org/copyleft/gpl.html + 9. http://www.megastep.org/makeself/makeself-2.1.3.run + 10. http://cvs.icculus.org/ + 11. http://www.icculus.org/loki_setup/ + 12. http://www.unrealtournament2003.com/ + 13. http://www.icculus.org/loki_setup/ + 14. http://www.icculus.org/ + 15. http://www.mmedia.is/~bre/programs/setup.sh/ + 16. mailto:megastep@@megastep.org + 17. https://bugzilla.icculus.org/ + 18. mailto:megastep@@megastep.org diff --git a/sys/linux/setup/makeself/TODO b/sys/linux/setup/makeself/TODO new file mode 100644 index 000000000..8bf501b7b --- /dev/null +++ b/sys/linux/setup/makeself/TODO @@ -0,0 +1,6 @@ +What needs to be done next : + +- Generic compression code (thru a user-defined command) +- Collect names of directories potentially containing md5 program. GUESS_MD5_PATH + +Stéphane Peter diff --git a/sys/linux/setup/makeself/makeself-header.sh b/sys/linux/setup/makeself/makeself-header.sh new file mode 100644 index 000000000..5519e3646 --- /dev/null +++ b/sys/linux/setup/makeself/makeself-header.sh @@ -0,0 +1,373 @@ +cat << EOF > "$archname" +#!/bin/sh +# This script was generated using Makeself $MS_VERSION + +CRCsum="$CRCsum" +MD5="$MD5sum" +TMPROOT=\${TMPDIR:=/tmp} + +label="$LABEL" +script="$SCRIPT" +scriptargs="$SCRIPTARGS" +targetdir="$archdirname" +filesizes="$filesizes" +keep=$KEEP + +print_cmd_arg="" +if type printf > /dev/null; then + print_cmd="printf" +elif test -x /usr/ucb/echo; then + print_cmd="/usr/ucb/echo" +else + print_cmd="echo" +fi + +MS_Printf() +{ + \$print_cmd \$print_cmd_arg "\$1" +} + +MS_Progress() +{ + while read a; do + MS_Printf . + done +} + +MS_dd() +{ + blocks=\`expr \$3 / 1024\` + bytes=\`expr \$3 % 1024\` + dd if="\$1" ibs=\$2 skip=1 obs=1024 conv=sync 2> /dev/null | \\ + { test \$blocks -gt 0 && dd ibs=1024 obs=1024 count=\$blocks ; \\ + test \$bytes -gt 0 && dd ibs=1 obs=1024 count=\$bytes ; } 2> /dev/null +} + +MS_Help() +{ + cat << EOH >&2 +Makeself version $MS_VERSION + 1) Getting help or info about \$0 : + \$0 --help Print this message + \$0 --info Print embedded info : title, default target directory, embedded script ... + \$0 --lsm Print embedded lsm entry (or no LSM) + \$0 --list Print the list of files in the archive + \$0 --check Checks integrity of the archive + + 2) Running \$0 : + \$0 [options] [--] [additional arguments to embedded script] + with following options (in that order) + --confirm Ask before running embedded script + --noexec Do not run embedded script + --keep Do not erase target directory after running + the embedded script + --nox11 Do not spawn an xterm + --nochown Do not give the extracted files to the current user + --target NewDirectory Extract in NewDirectory + --tar arg1 [arg2 ...] Access the contents of the archive through the tar command + -- Following arguments will be passed to the embedded script +EOH +} + +MS_Check() +{ + OLD_PATH=\$PATH + PATH=\${GUESS_MD5_PATH:-"\$OLD_PATH:/bin:/usr/bin:/sbin:/usr/local/ssl/bin:/usr/local/bin:/opt/openssl/bin"} + MD5_PATH=\`exec 2>&-; which md5sum || type md5sum\` + MD5_PATH=\${MD5_PATH:-\`exec 2>&-; which md5 || type md5\`} + PATH=\$OLD_PATH + MS_Printf "Verifying archive integrity..." + offset=\`head -n $SKIP "\$1" | wc -c | tr -d " "\` + verb=\$2 + i=1 + for s in \$filesizes + do + crc=\`echo \$CRCsum | cut -d" " -f\$i\` + if test -x "\$MD5_PATH"; then + md5=\`echo \$MD5 | cut -d" " -f\$i\` + if test \$md5 = "00000000000000000000000000000000"; then + test x\$verb = xy && echo " \$1 does not contain an embedded MD5 checksum." >&2 + else + md5sum=\`MS_dd "\$1" \$offset \$s | "\$MD5_PATH" | cut -b-32\`; + if test "\$md5sum" != "\$md5"; then + echo "Error in MD5 checksums: \$md5sum is different from \$md5" >&2 + exit 2 + else + test x\$verb = xy && MS_Printf " MD5 checksums are OK." >&2 + fi + crc="0000000000"; verb=n + fi + fi + if test \$crc = "0000000000"; then + test x\$verb = xy && echo " \$1 does not contain a CRC checksum." >&2 + else + sum1=\`MS_dd "\$1" \$offset \$s | CMD_ENV=xpg4 cksum | awk '{print \$1}'\` + if test "\$sum1" = "\$crc"; then + test x\$verb = xy && MS_Printf " CRC checksums are OK." >&2 + else + echo "Error in checksums: \$sum1 is different from \$crc" + exit 2; + fi + fi + i=\`expr \$i + 1\` + offset=\`expr \$offset + \$s\` + done + echo " All good." +} + +UnTAR() +{ + tar \$1vf - 2>&1 || { echo Extraction failed. > /dev/tty; kill -15 \$$; } +} + +finish=true +xterm_loop= +nox11=$NOX11 +copy=$COPY +ownership=y +verbose=n + +initargs="\$@" + +while true +do + case "\$1" in + -h | --help) + MS_Help + exit 0 + ;; + --info) + echo Identification: "\$label" + echo Target directory: "\$targetdir" + echo Uncompressed size: $USIZE KB + echo Compression: $COMPRESS + echo Date of packaging: $DATE + echo Built with Makeself version $MS_VERSION on $OSTYPE + echo Build command was: "$MS_COMMAND" + if test x\$script != x; then + echo Script run after extraction: + echo " " \$script \$scriptargs + fi + if test x"$copy" = xcopy; then + echo "Archive will copy itself to a temporary location" + fi + if test x"$KEEP" = xy; then + echo "directory \$targetdir is permanent" + else + echo "\$targetdir will be removed after extraction" + fi + exit 0 + ;; + --dumpconf) + echo LABEL=\"\$label\" + echo SCRIPT=\"\$script\" + echo SCRIPTARGS=\"\$scriptargs\" + echo archdirname=\"$archdirname\" + echo KEEP=$KEEP + echo COMPRESS=$COMPRESS + echo filesizes=\"\$filesizes\" + echo CRCsum=\"\$CRCsum\" + echo MD5sum=\"\$MD5\" + echo OLDUSIZE=$USIZE + echo OLDSKIP=`expr $SKIP + 1` + exit 0 + ;; + --lsm) +cat << EOLSM +EOF +eval "$LSM_CMD" +cat << EOF >> "$archname" +EOLSM + exit 0 + ;; + --list) + echo Target directory: \$targetdir + offset=\`head -n $SKIP "\$0" | wc -c | tr -d " "\` + for s in \$filesizes + do + MS_dd "\$0" \$offset \$s | eval "$GUNZIP_CMD" | UnTAR t + offset=\`expr \$offset + \$s\` + done + exit 0 + ;; + --tar) + offset=\`head -n $SKIP "\$0" | wc -c | tr -d " "\` + arg1="\$2" + shift 2 + for s in \$filesizes + do + MS_dd "\$0" \$offset \$s | eval "$GUNZIP_CMD" | tar "\$arg1" - \$* + offset=\`expr \$offset + \$s\` + done + exit 0 + ;; + --check) + MS_Check "\$0" y + exit 0 + ;; + --confirm) + verbose=y + shift + ;; + --noexec) + script="" + shift + ;; + --keep) + keep=y + shift + ;; + --target) + keep=y + targetdir=\${2:-.} + shift 2 + ;; + --nox11) + nox11=y + shift + ;; + --nochown) + ownership=n + shift + ;; + --xwin) + finish="echo Press Return to close this window...; read junk" + xterm_loop=1 + shift + ;; + --phase2) + copy=phase2 + shift + ;; + --) + shift + break ;; + -*) + echo Unrecognized flag : "\$1" >&2 + MS_Help + exit 1 + ;; + *) + break ;; + esac +done + +case "\$copy" in +copy) + tmpdir=\$TMPROOT/makeself.\$RANDOM.\`date +"%y%m%d%H%M%S"\`.\$\$ + mkdir "\$tmpdir" || { + echo "Could not create temporary directory \$tmpdir" >&2 + exit 1 + } + SCRIPT_COPY="\$tmpdir/makeself" + echo "Copying to a temporary location..." >&2 + cp "\$0" "\$SCRIPT_COPY" + chmod +x "\$SCRIPT_COPY" + cd "\$TMPROOT" + exec "\$SCRIPT_COPY" --phase2 + ;; +phase2) + finish="\$finish ; rm -rf \`dirname \$0\`" + ;; +esac + +if test "\$nox11" = "n"; then + if tty -s; then # Do we have a terminal? + : + else + if test x"\$DISPLAY" != x -a x"\$xterm_loop" = x; then # No, but do we have X? + if xset q > /dev/null 2>&1; then # Check for valid DISPLAY variable + GUESS_XTERMS="xterm rxvt dtterm eterm Eterm kvt konsole aterm" + for a in \$GUESS_XTERMS; do + if type \$a >/dev/null 2>&1; then + XTERM=\$a + break + fi + done + chmod a+x \$0 || echo Please add execution rights on \$0 + if test \`echo "\$0" | cut -c1\` = "/"; then # Spawn a terminal! + exec \$XTERM -title "\$label" -e "\$0" --xwin "\$initargs" + else + exec \$XTERM -title "\$label" -e "./\$0" --xwin "\$initargs" + fi + fi + fi + fi +fi + +if test "\$targetdir" = "."; then + tmpdir="." +else + if test "\$keep" = y; then + echo "Creating directory \$targetdir" >&2 + tmpdir="\$targetdir" + dashp="-p" + else + tmpdir="\$TMPROOT/selfgz\$\$\$RANDOM" + dashp="" + fi + mkdir \$dashp \$tmpdir || { + echo 'Cannot create target directory' \$tmpdir >&2 + echo 'You should try option --target OtherDirectory' >&2 + eval \$finish + exit 1 + } +fi + +location="\`pwd\`" +if test x\$SETUP_NOCHECK != x1; then + MS_Check "\$0" +fi +offset=\`head -n $SKIP "\$0" | wc -c | tr -d " "\` + +if test x"\$verbose" = xy; then + MS_Printf "About to extract $USIZE KB in \$tmpdir ... Proceed ? [Y/n] " + read yn + if test x"\$yn" = xn; then + eval \$finish; exit 1 + fi +fi + +MS_Printf "Uncompressing \$label" +res=3 +if test "\$keep" = n; then + trap 'echo Signal caught, cleaning up >&2; cd \$TMPROOT; /bin/rm -rf \$tmpdir; eval \$finish; exit 15' 1 2 3 15 +fi + +for s in \$filesizes +do + if MS_dd "\$0" \$offset \$s | eval "$GUNZIP_CMD" | ( cd "\$tmpdir"; UnTAR x ) | MS_Progress; then + if test x"\$ownership" = xy; then + (PATH=/usr/xpg4/bin:\$PATH; cd "\$tmpdir"; chown -R \`id -u\` .; chgrp -R \`id -g\` .) + fi + else + echo + echo "Unable to decompress \$0" >&2 + eval \$finish; exit 1 + fi + offset=\`expr \$offset + \$s\` +done +echo + +cd "\$tmpdir" +res=0 +if test x"\$script" != x; then + if test x"\$verbose" = xy; then + MS_Printf "OK to execute: \$script \$scriptargs \$* ? [Y/n] " + read yn + if test x"\$yn" = x -o x"\$yn" = xy -o x"\$yn" = xY; then + eval \$script \$scriptargs \$*; res=\$?; + fi + else + eval \$script \$scriptargs \$*; res=\$? + fi + if test \$res -ne 0; then + test x"\$verbose" = xy && echo "The program '\$script' returned an error code (\$res)" >&2 + fi +fi +if test "\$keep" = n; then + cd \$TMPROOT + /bin/rm -rf \$tmpdir +fi +eval \$finish; exit \$res +EOF diff --git a/sys/linux/setup/makeself/makeself.1 b/sys/linux/setup/makeself/makeself.1 new file mode 100644 index 000000000..15c59dc82 --- /dev/null +++ b/sys/linux/setup/makeself/makeself.1 @@ -0,0 +1,76 @@ +.TH "makeself" "1" "2.1.3" +.SH "NAME" +makeself \- An utility to generate self-extractable archives. +.SH "SYNTAX" +.LP +.B makeself [\fIoptions\fP] archive_dir file_name label +.B [\fIstartup_script\fP] [\fIargs\fP] +.SH "DESCRIPTION" +.LP +This program is a free (GPL) utility designed to create self-extractable +archives from a directory. +.br +.SH "OPTIONS" +.LP +The following options are supported. +.LP +.TP 15 +.B -v, --version +Prints out the makeself version number and exits. +.TP +.B -h, --help +Print out help information. +.TP +.B --gzip +Compress using gzip (default if detected). +.TP +.B --bzip2 +Compress using bzip2. +.TP +.B --compress +Compress using the UNIX 'compress' command. +.TP +.B --nocomp +Do not compress the data. +.TP +.B --notemp +The archive will create archive_dir in the current directory and +uncompress in ./archive_dir. +.TP +.B --copy +Upon extraction, the archive will first copy itself to a temporary directory. +.TP +.B --append +Append more files to an existing makeself archive. +The label and startup scripts will then be ignored. +.TP +.B --current +Files will be extracted to the current directory. Implies --notemp. +.TP +.B --header file +Specify location of the header script. +.TP +.B --follow +Follow the symlinks in the archive. +.TP +.B --nox11 +Disable automatic spawn of an xterm if running in X11. +.TP +.B --nowait +Do not wait for user input after executing embedded program from an xterm. +.TP +.B --nomd5 +Do not create a MD5 checksum for the archive. +.TP +.B --nocrc +Do not create a CRC32 checksum for the archive. +.TP +.B --lsm file +LSM file describing the package. +.PD +.SH "AUTHORS" +.LP +Makeself has been written by Stéphane Peter . +.BR +This man page was originally written by Bartosz Fenski for the +Debian GNU/Linux distribution (but it may be used by others). diff --git a/sys/linux/setup/makeself/makeself.lsm b/sys/linux/setup/makeself/makeself.lsm new file mode 100644 index 000000000..1d28ba5d8 --- /dev/null +++ b/sys/linux/setup/makeself/makeself.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: makeself.sh +Version: 2.1 +Description: makeself.sh is a shell script that generates a self-extractable + tar.gz archive from a directory. The resulting file appears as a shell + script, and can be launched as is. The archive will then uncompress + itself to a temporary directory and an arbitrary command will be + executed (for example an installation script). This is pretty similar + to archives generated with WinZip Self-Extractor in the Windows world. +Keywords: Installation archive tar winzip +Author: Stéphane Peter (megastep@megastep.org) +Maintained-by: Stéphane Peter (megastep@megastep.org) +Original-site: http://www.megastep.org/makeself/ +Platform: Unix +Copying-policy: GPL +End diff --git a/sys/linux/setup/makeself/makeself.sh b/sys/linux/setup/makeself/makeself.sh new file mode 100644 index 000000000..1d903f58b --- /dev/null +++ b/sys/linux/setup/makeself/makeself.sh @@ -0,0 +1,374 @@ +#!/bin/sh +# +# Makeself version 2.1.x +# by Stephane Peter +# +# $Id: makeself.sh,v 1.51 2004/09/07 22:16:53 megastep Exp $ +# +# Utility to create self-extracting tar.gz archives. +# The resulting archive is a file holding the tar.gz archive with +# a small Shell script stub that uncompresses the archive to a temporary +# directory and then executes a given script from withing that directory. +# +# Makeself home page: http://www.megastep.org/makeself/ +# +# Version 2.0 is a rewrite of version 1.0 to make the code easier to read and maintain. +# +# Version history : +# - 1.0 : Initial public release +# - 1.1 : The archive can be passed parameters that will be passed on to +# the embedded script, thanks to John C. Quillan +# - 1.2 : Package distribution, bzip2 compression, more command line options, +# support for non-temporary archives. Ideas thanks to Francois Petitjean +# - 1.3 : More patches from Bjarni R. Einarsson and Francois Petitjean: +# Support for no compression (--nocomp), script is no longer mandatory, +# automatic launch in an xterm, optional verbose output, and -target +# archive option to indicate where to extract the files. +# - 1.4 : Improved UNIX compatibility (Francois Petitjean) +# Automatic integrity checking, support of LSM files (Francois Petitjean) +# - 1.5 : Many bugfixes. Optionally disable xterm spawning. +# - 1.5.1 : More bugfixes, added archive options -list and -check. +# - 1.5.2 : Cosmetic changes to inform the user of what's going on with big +# archives (Quake III demo) +# - 1.5.3 : Check for validity of the DISPLAY variable before launching an xterm. +# More verbosity in xterms and check for embedded command's return value. +# Bugfix for Debian 2.0 systems that have a different "print" command. +# - 1.5.4 : Many bugfixes. Print out a message if the extraction failed. +# - 1.5.5 : More bugfixes. Added support for SETUP_NOCHECK environment variable to +# bypass checksum verification of archives. +# - 1.6.0 : Compute MD5 checksums with the md5sum command (patch from Ryan Gordon) +# - 2.0 : Brand new rewrite, cleaner architecture, separated header and UNIX ports. +# - 2.0.1 : Added --copy +# - 2.1.0 : Allow multiple tarballs to be stored in one archive, and incremental updates. +# Added --nochown for archives +# Stopped doing redundant checksums when not necesary +# - 2.1.1 : Work around insane behavior from certain Linux distros with no 'uncompress' command +# Cleaned up the code to handle error codes from compress. Simplified the extraction code. +# - 2.1.2 : Some bug fixes. Use head -n to avoid problems. +# - 2.1.3 : Bug fixes with command line when spawning terminals. +# Added --tar for archives, allowing to give arbitrary arguments to tar on the contents of the archive. +# Added --noexec to prevent execution of embedded scripts. +# Added --nomd5 and --nocrc to avoid creating checksums in archives. +# Added command used to create the archive in --info output. +# Run the embedded script through eval. +# - 2.1.4 : Fixed --info output. +# Generate random directory name when extracting files to . to avoid problems. (Jason Trent) +# Better handling of errors with wrong permissions for the directory containing the files. (Jason Trent) +# Avoid some race conditions (Ludwig Nussel) +# +# (C) 1998-2004 by Stéphane Peter +# +# This software is released under the terms of the GNU GPL version 2 and above +# Please read the license at http://www.gnu.org/copyleft/gpl.html +# + +MS_VERSION=2.1.4 +MS_COMMAND="$0" + +for f in "${1+"$@"}"; do + MS_COMMAND="$MS_COMMAND \\\\ + \\\"$f\\\"" +done + +# Procedures + +MS_Usage() +{ + echo "Usage: $0 [params] archive_dir file_name label [startup_script] [args]" + echo "params can be one or more of the following :" + echo " --version | -v : Print out Makeself version number and exit" + echo " --help | -h : Print out this help message" + echo " --gzip : Compress using gzip (default if detected)" + echo " --bzip2 : Compress using bzip2 instead of gzip" + echo " --compress : Compress using the UNIX 'compress' command" + echo " --nocomp : Do not compress the data" + echo " --notemp : The archive will create archive_dir in the" + echo " current directory and uncompress in ./archive_dir" + echo " --copy : Upon extraction, the archive will first copy itself to" + echo " a temporary directory" + echo " --append : Append more files to an existing Makeself archive" + echo " The label and startup scripts will then be ignored" + echo " --current : Files will be extracted to the current directory." + echo " Implies --notemp." + echo " --nomd5 : Don't calculate an MD5 for archive" + echo " --nocrc : Don't calculate a CRC for archive" + echo " --header file : Specify location of the header script" + echo " --follow : Follow the symlinks in the archive" + echo " --nox11 : Disable automatic spawn of a xterm" + echo " --nowait : Do not wait for user input after executing embedded" + echo " program from an xterm" + echo " --lsm file : LSM file describing the package" + echo + echo "Do not forget to give a fully qualified startup script name" + echo "(i.e. with a ./ prefix if inside the archive)." + exit 1 +} + +# Default settings +if type gzip 2>&1 > /dev/null; then + COMPRESS=gzip +else + COMPRESS=Unix +fi +KEEP=n +CURRENT=n +NOX11=n +APPEND=n +COPY=none +TAR_ARGS=cvf +HEADER=`dirname $0`/makeself-header.sh + +# LSM file stuff +LSM_CMD="echo No LSM. >> \"\$archname\"" + +while true +do + case "$1" in + --version | -v) + echo Makeself version $MS_VERSION + exit 0 + ;; + --bzip2) + COMPRESS=bzip2 + shift + ;; + --gzip) + COMPRESS=gzip + shift + ;; + --compress) + COMPRESS=Unix + shift + ;; + --nocomp) + COMPRESS=none + shift + ;; + --notemp) + KEEP=y + shift + ;; + --copy) + COPY=copy + shift + ;; + --current) + CURRENT=y + KEEP=y + shift + ;; + --header) + HEADER="$2" + shift 2 + ;; + --follow) + TAR_ARGS=cvfh + shift + ;; + --nox11) + NOX11=y + shift + ;; + --nowait) + shift + ;; + --nomd5) + NOMD5=y + shift + ;; + --nocrc) + NOCRC=y + shift + ;; + --append) + APPEND=y + shift + ;; + --lsm) + LSM_CMD="cat \"$2\" >> \"\$archname\"" + shift 2 + ;; + -h | --help) + MS_Usage + ;; + -*) + echo Unrecognized flag : "$1" + MS_Usage + ;; + *) + break + ;; + esac +done + +archdir="$1" +archname="$2" + +if test "$APPEND" = y; then + if test $# -lt 2; then + MS_Usage + fi + + # Gather the info from the original archive + OLDENV=`sh "$archname" --dumpconf` + if test $? -ne 0; then + echo "Unable to update archive: $archname" >&2 + exit 1 + else + eval "$OLDENV" + fi +else + if test "$KEEP" = n -a $# = 3; then + echo "ERROR: Making a temporary archive with no embedded command does not make sense!" >&2 + echo + MS_Usage + fi + # We don't really want to create an absolute directory... + if test "$CURRENT" = y; then + archdirname="." + else + archdirname=`basename "$1"` + fi + + if test $# -lt 3; then + MS_Usage + fi + + LABEL="$3" + SCRIPT="$4" + test x$SCRIPT = x || shift 1 + shift 3 + SCRIPTARGS="$*" +fi + +if test "$KEEP" = n -a "$CURRENT" = y; then + echo "ERROR: It is A VERY DANGEROUS IDEA to try to combine --notemp and --current." >&2 + exit 1 +fi + +case $COMPRESS in +gzip) + GZIP_CMD="gzip -c9" + GUNZIP_CMD="gzip -cd" + ;; +bzip2) + GZIP_CMD="bzip2 -9" + GUNZIP_CMD="bzip2 -d" + ;; +Unix) + GZIP_CMD="compress -cf" + GUNZIP_CMD="exec 2>&-; uncompress -c || test \\\$? -eq 2 || gzip -cd" + ;; +none) + GZIP_CMD="cat" + GUNZIP_CMD="cat" + ;; +esac + +tmpfile="${TMPDIR:=/tmp}/mkself$$" + +if test -f $HEADER; then + oldarchname="$archname" + archname="$tmpfile" + # Generate a fake header to count its lines + SKIP=0 + . $HEADER + SKIP=`cat "$tmpfile" |wc -l` + # Get rid of any spaces + SKIP=`expr $SKIP` + rm -f "$tmpfile" + echo Header is $SKIP lines long >&2 + + archname="$oldarchname" +else + echo "Unable to open header file: $HEADER" >&2 + exit 1 +fi + +echo + +if test "$APPEND" = n; then + if test -f "$archname"; then + echo "WARNING: Overwriting existing file: $archname" >&2 + fi +fi + +USIZE=`du -ks $archdir | cut -f1` +DATE=`LC_ALL=C date` + +if test "." = "$archdirname"; then + if test "$KEEP" = n; then + archdirname="makeself-$$-`date +%Y%m%d%H%M%S`" + fi +fi + +echo About to compress $USIZE KB of data... +echo Adding files to archive named \"$archname\"... +(cd "$archdir" && ( tar $TAR_ARGS - * | eval "$GZIP_CMD" ) >> "$tmpfile") || { echo Aborting: Archive directory not found or temporary file: "$tmpfile" could not be created.; rm -f "$tmpfile"; exit 1; } +echo >> "$tmpfile" >&- # try to close the archive + +fsize=`cat "$tmpfile" | wc -c | tr -d " "` + +# Compute the checksums + +md5sum=00000000000000000000000000000000 +crcsum=0000000000 + +if test "$NOCRC" = y; then + echo "skipping crc at user request" +else + crcsum=`cat "$tmpfile" | CMD_ENV=xpg4 cksum | sed -e 's/ /Z/' -e 's/ /Z/' | cut -dZ -f1` + echo "CRC: $crcsum" +fi + +# Try to locate a MD5 binary +OLD_PATH=$PATH +PATH=${GUESS_MD5_PATH:-"$OLD_PATH:/bin:/usr/bin:/sbin:/usr/local/ssl/bin:/usr/local/bin:/opt/openssl/bin"} +MD5_PATH=`type -p md5sum` +MD5_PATH=${MD5_PATH:-`type -p md5`} +PATH=$OLD_PATH + +if test "$NOMD5" = y; then + echo "skipping md5sum at user request" +else + if test -x "$MD5_PATH"; then + md5sum=`cat "$tmpfile" | "$MD5_PATH" | cut -b-32`; + echo "MD5: $md5sum" + else + echo "MD5: none, md5sum binary not found" + fi +fi + +if test "$APPEND" = y; then + mv "$archname" "$archname".bak || exit + + # Prepare entry for new archive + filesizes="$filesizes $fsize" + CRCsum="$CRCsum $crcsum" + MD5sum="$MD5sum $md5sum" + USIZE=`expr $USIZE + $OLDUSIZE` + # Generate the header + . $HEADER + # Append the original data + tail -n +$OLDSKIP "$archname".bak >> "$archname" + # Append the new data + cat "$tmpfile" >> "$archname" + + chmod +x "$archname" + rm -f "$archname".bak + echo Self-extractible archive \"$archname\" successfully updated. +else + filesizes="$fsize" + CRCsum="$crcsum" + MD5sum="$md5sum" + + # Generate the header + . $HEADER + + # Append the compressed tar data after the stub + echo + cat "$tmpfile" >> "$archname" + chmod +x "$archname" + echo Self-extractible archive \"$archname\" successfully created. +fi +rm -f "$tmpfile" diff --git a/sys/linux/setup/makeself/update-readme b/sys/linux/setup/makeself/update-readme new file mode 100644 index 000000000..5c918e6dd --- /dev/null +++ b/sys/linux/setup/makeself/update-readme @@ -0,0 +1,7 @@ +#!/bin/sh +# Grab the Makeself web page + +echo The following was generated from http://www.megastep.org/makeself/ > README +echo ----------------------- >> README +echo >> README +lynx -dump http://www.megastep.org/makeself/ >> README diff --git a/sys/linux/sound.cpp b/sys/linux/sound.cpp new file mode 100644 index 000000000..9fa607658 --- /dev/null +++ b/sys/linux/sound.cpp @@ -0,0 +1,390 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +// OSS sound interface +// http://www.opensound.com/ +#include + +#include "../../idlib/precompiled.h" +#include "../../sound/snd_local.h" +#include "../posix/posix_public.h" +#include "sound.h" + +const char *s_driverArgs[] = { "best", "oss", "alsa", NULL }; + +#ifndef NO_ALSA +static idCVar s_driver( "s_driver", s_driverArgs[0], CVAR_SYSTEM | CVAR_ARCHIVE, "sound driver. 'best' will attempt to use alsa and fallback to OSS if not available", s_driverArgs, idCmdSystem::ArgCompletion_String ); +#else +static idCVar s_driver( "s_driver", "oss", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_ROM, "sound driver. only OSS is supported in this build" ); +#endif + +idAudioHardware *idAudioHardware::Alloc() { +#ifndef NO_ALSA + if ( !strcmp( s_driver.GetString(), "best" ) ) { + idAudioHardwareALSA *test = new idAudioHardwareALSA; + if ( test->DLOpen() ) { + common->Printf( "Alsa is available\n" ); + return test; + } + common->Printf( "Alsa is not available\n" ); + delete test; + return new idAudioHardwareOSS; + } + if ( !strcmp( s_driver.GetString(), "alsa" ) ) { + return new idAudioHardwareALSA; + } +#endif + return new idAudioHardwareOSS; +} + +// OSS sound ---------------------------------------------------- + +/* +=============== +idAudioHardware::~idAudioHardware +=============== +*/ +idAudioHardware::~idAudioHardware() { } + +/* +================= +idAudioHardwareOSS::~idAudioHardwareOSS +================= +*/ +idAudioHardwareOSS::~idAudioHardwareOSS() { + Release(); +} + +/* +================= +idAudioHardwareOSS::Release +================= +*/ +void idAudioHardwareOSS::Release( bool bSilent ) { + if (m_audio_fd) { + if (!bSilent) { + common->Printf("------ OSS Sound Shutdown ------\n"); + } + if (m_buffer) { + free( m_buffer ); + m_buffer = NULL; + m_buffer_size = 0; + } + common->Printf("close sound device\n"); + if (close(m_audio_fd) == -1) { + common->Warning( "failed to close sound device: %s", strerror(errno) ); + } + m_audio_fd = 0; + if (!bSilent) { + common->Printf("--------------------------------\n"); + } + } +} + +/* +================= +idAudioHardwareOSS::InitFailed +================= +*/ +void idAudioHardwareOSS::InitFailed() { + Release( true ); + cvarSystem->SetCVarBool( "s_noSound", true ); + common->Warning( "sound subsystem disabled" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +================= +idAudioHardwareOSS::ExtractOSSVersion +================= +*/ +void idAudioHardwareOSS::ExtractOSSVersion( int version, idStr &str ) const { + sprintf( str, "%d.%d.%d", ( version & 0xFF0000 ) >> 16, ( version & 0xFF00 ) >> 8, version & 0xFF ); +} + +/* +================= +idAudioHardwareOSS::Initialize + +http://www.4front-tech.com/pguide/index.html +though OSS API docs (1.1) advertise AFMT_S32_LE, AFMT_S16_LE is the only output format I've found in kernel emu10k1 headers + +BSD NOTE: With the GNU library, you can use free to free the blocks that memalign, posix_memalign, and valloc return. +That does not work in BSD, however--BSD does not provide any way to free such blocks. +================= +*/ +idCVar s_device( "s_dsp", "/dev/dsp", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); + +bool idAudioHardwareOSS::Initialize( ) { + common->Printf("------ OSS Sound Initialization ------\n"); + + int requested_sample_format, caps, oss_version; + idStr s_compiled_oss_version, s_oss_version; + struct audio_buf_info info; + + memset( &info, 0, sizeof( info ) ); + + if (m_audio_fd) { + Release(); + } + + // open device ------------------------------------------------ + if ((m_audio_fd = open( s_device.GetString(), O_WRONLY | O_NONBLOCK, 0)) == -1) { + m_audio_fd = 0; + common->Warning( "failed to open sound device '%s': %s", s_device.GetString(), strerror(errno) ); + InitFailed(); + return false; + } + // make it blocking - so write overruns don't fail with 'Resource temporarily unavailable' + int flags; + if ( ( flags = fcntl( m_audio_fd, F_GETFL ) ) == -1 ) { + common->Warning( "failed fcntl F_GETFL on sound device '%s': %s", s_device.GetString(), strerror( errno ) ); + InitFailed(); + return false; + } + flags &= ~O_NONBLOCK; + if ( fcntl( m_audio_fd, F_SETFL, flags ) == -1 ) { + common->Warning( "failed to clear O_NONBLOCK on sound device '%s': %s", s_device.GetString(), strerror( errno ) ); + InitFailed(); + return false; + } + + common->Printf("opened sound device '%s'\n", s_device.GetString()); + + // verify capabilities ----------------------------------------- + + // may only be available starting with OSS API v4.0 + // http://www.fi.opensound.com/developer/SNDCTL_SYSINFO.html + // NOTE: at OSS API 4.0 headers, replace OSS_SYSINFO with SNDCTL_SYSINFO + oss_sysinfo si; + if ( ioctl( m_audio_fd, OSS_SYSINFO, &si ) == -1 ) { + common->Printf( "ioctl SNDCTL_SYSINFO failed: %s\nthis ioctl is only available in OSS/Linux implementation. If you run OSS/Free, don't bother.", strerror( errno ) ); + } else { + common->Printf( "%s: %s %s\n", s_device.GetString(), si.product, si.version ); + } + + if ( ioctl( m_audio_fd, SNDCTL_DSP_GETCAPS, &caps ) == -1 ) { + common->Warning( "ioctl SNDCTL_DSP_GETCAPS failed - driver too old?" ); + InitFailed(); + return false; + } + common->DPrintf("driver rev %d - capabilities %d\n", caps & DSP_CAP_REVISION, caps); + if (ioctl( m_audio_fd, OSS_GETVERSION, &oss_version ) == -1) { + common->Warning( "ioctl OSS_GETVERSION failed" ); + InitFailed(); + return false; + } + ExtractOSSVersion( oss_version, s_oss_version ); + ExtractOSSVersion( SOUND_VERSION, s_compiled_oss_version ); + common->DPrintf( "OSS interface version %s - compile time %s\n", s_oss_version.c_str(), s_compiled_oss_version.c_str() ); + if (!(caps & DSP_CAP_MMAP)) { + common->Warning( "driver doesn't have DSP_CAP_MMAP capability" ); + InitFailed(); + return false; + } + if (!(caps & DSP_CAP_TRIGGER)) { + common->Warning( "driver doesn't have DSP_CAP_TRIGGER capability" ); + InitFailed(); + return false; + } + + // sample format ----------------------------------------------- + requested_sample_format = AFMT_S16_LE; + m_sample_format = requested_sample_format; + if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &m_sample_format) == -1) { + common->Warning( "ioctl SNDCTL_DSP_SETFMT %d failed: %s", requested_sample_format, strerror(errno) ); + InitFailed(); + return false; + } + if ( m_sample_format != requested_sample_format ) { + common->Warning( "ioctl SNDCTL_DSP_SETFMT failed to get the requested sample format %d, got %d", requested_sample_format, m_sample_format ); + InitFailed(); + return false; + } + + // channels ---------------------------------------------------- + + // sanity over number of speakers + if ( idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 6 && idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) { + common->Warning( "invalid value for s_numberOfSpeakers. Use either 2 or 6" ); + idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 ); + } + + m_channels = idSoundSystemLocal::s_numberOfSpeakers.GetInteger(); + if ( ioctl( m_audio_fd, SNDCTL_DSP_CHANNELS, &m_channels ) == -1 ) { + common->Warning( "ioctl SNDCTL_DSP_CHANNELS %d failed: %s", idSoundSystemLocal::s_numberOfSpeakers.GetInteger(), strerror(errno) ); + InitFailed(); + return false; + } + if ( m_channels != (unsigned int)idSoundSystemLocal::s_numberOfSpeakers.GetInteger() ) { + common->Warning( "ioctl SNDCTL_DSP_CHANNELS failed to get the %d requested channels, got %d", idSoundSystemLocal::s_numberOfSpeakers.GetInteger(), m_channels ); + if ( m_channels != 2 && idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) { + // we didn't request 2 channels, some drivers reply 1 channel on error but may still let us still get 2 if properly asked + m_channels = 2; + if ( ioctl( m_audio_fd, SNDCTL_DSP_CHANNELS, &m_channels ) == -1 ) { + common->Warning( "ioctl SNDCTL_DSP_CHANNELS fallback to 2 failed: %s", strerror(errno) ); + InitFailed(); + return false; + } + } + if ( m_channels == 2 ) { + // tell the system to mix 2 channels + common->Warning( "falling back to stereo" ); + idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 ); + } else { + // disable sound + InitFailed(); + return false; + } + } + assert( (int)m_channels == idSoundSystemLocal::s_numberOfSpeakers.GetInteger() ); + + // sampling rate ------------------------------------------------ + m_speed = PRIMARYFREQ; + if ( ioctl( m_audio_fd, SNDCTL_DSP_SPEED, &m_speed ) == -1 ) { + common->Warning( "ioctl SNDCTL_DSP_SPEED %d failed: %s", PRIMARYFREQ, strerror(errno) ); + InitFailed(); + return false; + } + // instead of an exact match, do a very close to + // there is some horrible Ensonic ES1371 which replies 44101 for a 44100 request + if ( abs( m_speed - PRIMARYFREQ ) > 5 ) { + common->Warning( "ioctl SNDCTL_DSP_SPEED failed to get the requested frequency %d, got %d", PRIMARYFREQ, m_speed ); + InitFailed(); + return false; + } + common->Printf("%s - bit rate: %d, channels: %d, frequency: %d\n", s_device.GetString(), m_sample_format, m_channels, m_speed); + + // output buffer ------------------------------------------------ + // allocate a final buffer target, the sound engine locks, writes, and we write back to the device + // we want m_buffer_size ( will have to rename those ) + // ROOM_SLICES_IN_BUFFER is fixed ( system default, 10 ) + // MIXBUFFER_SAMPLES is the number of samples found in a slice + // each sample is m_channels * sizeof( float ) bytes + // in AsyncUpdate we only write one block at a time, so we'd only need to have a final mix buffer sized of a single block + m_buffer_size = MIXBUFFER_SAMPLES * m_channels * 2; + m_buffer = malloc( m_buffer_size ); + common->Printf( "allocated a mix buffer of %d bytes\n", m_buffer_size ); + + // toggle sound ------------------------------------------------- + + // toggle off before toggling on. that's what OSS source code samples recommends + int flag = 0; + if (ioctl(m_audio_fd, SNDCTL_DSP_SETTRIGGER, &flag) == -1) { + common->Warning( "ioctl SNDCTL_DSP_SETTRIGGER 0 failed: %s", strerror(errno) ); + } + flag = PCM_ENABLE_OUTPUT; + if (ioctl(m_audio_fd, SNDCTL_DSP_SETTRIGGER, &flag) == -1) { + common->Warning( "ioctl SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed: %s", strerror(errno) ); + } + + common->Printf("--------------------------------------\n"); + return true; +} + +/* +=============== +idAudioHardwareOSS::Flush +=============== +*/ +bool idAudioHardwareOSS::Flush( void ) { + audio_buf_info ospace; + if ( ioctl( m_audio_fd, SNDCTL_DSP_GETOSPACE, &ospace ) == -1 ) { + Sys_Printf( "ioctl SNDCTL_DSP_GETOSPACE failed: %s\n", strerror( errno ) ); + return false; + } + // how many chunks can we write to the audio device right now + m_freeWriteChunks = ( ospace.bytes * MIXBUFFER_CHUNKS ) / ( MIXBUFFER_SAMPLES * m_channels * 2 ); + if ( m_writeChunks ) { + // flush out any remaining chunks we could now + Write( true ); + } + return ( m_freeWriteChunks > 0 ); +} + +/* +================= +idAudioHardwareOSS::GetMixBufferSize +================= +*/ +int idAudioHardwareOSS::GetMixBufferSize() { + // return MIXBUFFER_SAMPLES * 2 * m_channels; + return m_buffer_size; +} + +/* +================= +idAudioHardwareOSS::GetMixBuffer +================= +*/ +short* idAudioHardwareOSS::GetMixBuffer() { + return (short *)m_buffer; +} + +/* +=============== +idAudioHardwareOSS::Write +rely on m_freeWriteChunks which has been set in Flush() before engine did the mixing for this MIXBUFFER_SAMPLE +=============== +*/ +void idAudioHardwareOSS::Write( bool flushing ) { + assert( m_audio_fd ); + int ret; + if ( !flushing && m_writeChunks ) { + // if we write after a new mixing loop, we should have m_writeChunk == 0 + // otherwise that last remaining chunk that was never flushed out to the audio device has just been overwritten + Sys_Printf( "idAudioHardwareOSS::Write: %d samples were overflowed and dropped\n", m_writeChunks * MIXBUFFER_SAMPLES / MIXBUFFER_CHUNKS ); + } + if ( !flushing ) { + // if running after the mix loop, then we have a full buffer to write out + m_writeChunks = MIXBUFFER_CHUNKS; + } + if ( m_freeWriteChunks == 0 ) { + return; + } + // what to write and how much + int pos = (int)m_buffer + ( MIXBUFFER_CHUNKS - m_writeChunks ) * m_channels * 2 * MIXBUFFER_SAMPLES / MIXBUFFER_CHUNKS; + int len = Min( m_writeChunks, m_freeWriteChunks ) * m_channels * 2 * MIXBUFFER_SAMPLES / MIXBUFFER_CHUNKS; + assert( len > 0 ); + if ( ( ret = write( m_audio_fd, (void*)pos, len ) ) == -1 ) { + Sys_Printf( "write to audio fd failed: %s\n", strerror( errno ) ); + return; + } + if ( len != ret ) { + Sys_Printf( "short write to audio fd: wrote %d out of %d\n", ret, m_buffer_size ); + return; + } + m_writeChunks -= Min( m_writeChunks, m_freeWriteChunks ); +} + +/* + =============== + Sys_LoadOpenAL + -=============== + */ +bool Sys_LoadOpenAL( void ) { + return false; +} + diff --git a/sys/linux/sound.h b/sys/linux/sound.h new file mode 100644 index 000000000..ab7bd50bf --- /dev/null +++ b/sys/linux/sound.h @@ -0,0 +1,178 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef ID_SND_BACKENDS +#define ID_SND_BACKENDS + +class idAudioHardwareOSS : public idAudioHardware { + // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS + static const int MIXBUFFER_CHUNKS = 4; + + int m_audio_fd; + int m_sample_format; + unsigned int m_channels; + unsigned int m_speed; + void *m_buffer; + int m_buffer_size; + + // counting the loops through the dma buffer + int m_loops; + + // how many chunks we have left to write in cases where we need to split + int m_writeChunks; + // how many chunks we can write to the audio device without blocking + int m_freeWriteChunks; + +public: + idAudioHardwareOSS() { + m_audio_fd = 0; + m_sample_format = 0; + m_channels = 0; + m_speed = 0; + m_buffer = NULL; + m_buffer_size = 0; + m_loops = 0; + m_writeChunks = 0; + m_freeWriteChunks = 0; + } + virtual ~idAudioHardwareOSS(); + + bool Initialize( void ); + + // Linux driver doesn't support memory map API + bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; } + bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; } + bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; } + + bool Flush(); + void Write( bool flushing ); + + int GetNumberOfSpeakers() { return m_channels; } + int GetMixBufferSize(); + short* GetMixBuffer(); + +private: + void Release( bool bSilent = false ); + void InitFailed(); + void ExtractOSSVersion( int version, idStr &str ) const; +}; + +#ifndef NO_ALSA + +// libasound2-dev +// the new/old API may be a problem if we are going to dynamically load the asound lib? +#define ALSA_PCM_NEW_HW_PARAMS_API +#define ALSA_PCM_NEW_SW_PARAMS_API +#include + +#define id_snd_pcm_hw_params_alloca(ptr) do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(id_snd_pcm_hw_params_sizeof()); memset(*ptr, 0, id_snd_pcm_hw_params_sizeof()); } while (0) + +typedef const char * ( *pfn_snd_asoundlib_version )( void ); +typedef snd_pcm_sframes_t ( *pfn_snd_pcm_avail_update )( snd_pcm_t *pcm ); +typedef int ( *pfn_snd_pcm_close )( snd_pcm_t *pcm ); +typedef const char * ( *pfn_snd_strerror )( int errnum ); +typedef int ( *pfn_snd_pcm_hw_params )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params ); +typedef int ( *pfn_snd_pcm_hw_params_any )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params ); +typedef int ( *pfn_snd_pcm_hw_params_get_buffer_size )( const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val ); +typedef int ( *pfn_snd_pcm_hw_params_set_access )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access ); +typedef int ( *pfn_snd_pcm_hw_params_set_buffer_size_min )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val ); +typedef int ( *pfn_snd_pcm_hw_params_set_channels )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val ); +typedef int ( *pfn_snd_pcm_hw_params_set_format )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format ); +typedef int ( *pfn_snd_pcm_hw_params_set_rate )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir ); +typedef size_t ( *pfn_snd_pcm_hw_params_sizeof )( void ); +typedef int ( *pfn_snd_pcm_open )( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode ); +typedef int ( *pfn_snd_pcm_prepare )( snd_pcm_t *pcm ); +typedef snd_pcm_state_t ( *pfn_snd_pcm_state )( snd_pcm_t *pcm ); +typedef snd_pcm_sframes_t ( *pfn_snd_pcm_writei )( snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size ); + +#define ALSA_DLSYM(SYM) id_##SYM = ( pfn_##SYM )dlvsym( m_handle, #SYM, "ALSA_0.9" ); if ( !id_##SYM ) { common->Printf( "dlsym "#SYM" failed: %s\n", dlerror() ); Release(); return false; } + +class idAudioHardwareALSA : public idAudioHardware { +private: + // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS + static const int MIXBUFFER_CHUNKS = 4; + + snd_pcm_t *m_pcm_handle; + unsigned int m_channels; + void *m_buffer; + int m_buffer_size; + + // how many frames remaining to be written to the device + int m_remainingFrames; + + void *m_handle; + +public: + idAudioHardwareALSA() { + m_pcm_handle = NULL; + m_channels = 0; + m_buffer = NULL; + m_buffer_size = 0; + m_remainingFrames = 0; + m_handle = NULL; + } + virtual ~idAudioHardwareALSA(); + + // dlopen the lib ( check minimum version ) + bool DLOpen(); + + bool Initialize( void ); + + + // Linux driver doesn't support memory map API + bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; } + bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; } + bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; } + + bool Flush(); + void Write( bool flushing ); + + int GetNumberOfSpeakers( void ) { return m_channels; } + int GetMixBufferSize( void ); + short* GetMixBuffer( void ); + +private: + void Release(); + void InitFailed(); + void PlayTestPattern(); + + // may be NULL, outdated alsa versions are missing it and we just ignore + pfn_snd_asoundlib_version id_snd_asoundlib_version; + + pfn_snd_pcm_avail_update id_snd_pcm_avail_update; + pfn_snd_pcm_close id_snd_pcm_close; + pfn_snd_strerror id_snd_strerror; + pfn_snd_pcm_hw_params id_snd_pcm_hw_params; + pfn_snd_pcm_hw_params_any id_snd_pcm_hw_params_any; + pfn_snd_pcm_hw_params_get_buffer_size id_snd_pcm_hw_params_get_buffer_size; + pfn_snd_pcm_hw_params_set_access id_snd_pcm_hw_params_set_access; + pfn_snd_pcm_hw_params_set_buffer_size_min id_snd_pcm_hw_params_set_buffer_size_min; + pfn_snd_pcm_hw_params_set_channels id_snd_pcm_hw_params_set_channels; + pfn_snd_pcm_hw_params_set_format id_snd_pcm_hw_params_set_format; + pfn_snd_pcm_hw_params_set_rate id_snd_pcm_hw_params_set_rate; + pfn_snd_pcm_hw_params_sizeof id_snd_pcm_hw_params_sizeof; + pfn_snd_pcm_open id_snd_pcm_open; + pfn_snd_pcm_prepare id_snd_pcm_prepare; + pfn_snd_pcm_state id_snd_pcm_state; + pfn_snd_pcm_writei id_snd_pcm_writei; + +}; + +#endif // NO_ALSA + +#endif diff --git a/sys/linux/sound_alsa.cpp b/sys/linux/sound_alsa.cpp new file mode 100644 index 000000000..8a499c4c2 --- /dev/null +++ b/sys/linux/sound_alsa.cpp @@ -0,0 +1,307 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../../sound/snd_local.h" +#include "../posix/posix_public.h" +#include "sound.h" + +#include + +static idCVar s_alsa_pcm( "s_alsa_pcm", "default", CVAR_SYSTEM | CVAR_ARCHIVE, "which alsa pcm device to use. default, hwplug, hw.. see alsa docs" ); +static idCVar s_alsa_lib( "s_alsa_lib", "libasound.so.2", CVAR_SYSTEM | CVAR_ARCHIVE, "alsa client sound library" ); + +/* +=============== +idAudioHardwareALSA::DLOpen +=============== +*/ +bool idAudioHardwareALSA::DLOpen( void ) { + const char *version; + + if ( m_handle ) { + return true; + } + common->Printf( "dlopen(%s)\n", s_alsa_lib.GetString() ); + if ( !( m_handle = dlopen( s_alsa_lib.GetString(), RTLD_NOW | RTLD_GLOBAL ) ) ) { + common->Printf( "dlopen(%s) failed: %s\n", s_alsa_lib.GetString(), dlerror() ); + return false; + } + // print the version if available + id_snd_asoundlib_version = ( pfn_snd_asoundlib_version )dlsym( m_handle, "snd_asoundlib_version" ); + if ( !id_snd_asoundlib_version ) { + common->Printf( "dlsym(\"snd_asoundlib_version\") failed: %s\n", dlerror() ); + common->Warning( "please consider upgrading alsa to a more recent version." ); + } else { + version = id_snd_asoundlib_version(); + common->Printf( "asoundlib version: %s\n", version ); + } + // dlsym the symbols + ALSA_DLSYM(snd_pcm_avail_update); + ALSA_DLSYM(snd_pcm_close); + ALSA_DLSYM(snd_pcm_hw_params); + ALSA_DLSYM(snd_pcm_hw_params_any); + ALSA_DLSYM(snd_pcm_hw_params_get_buffer_size); + ALSA_DLSYM(snd_pcm_hw_params_set_access); + ALSA_DLSYM(snd_pcm_hw_params_set_buffer_size_min); + ALSA_DLSYM(snd_pcm_hw_params_set_channels); + ALSA_DLSYM(snd_pcm_hw_params_set_format); + ALSA_DLSYM(snd_pcm_hw_params_set_rate); + ALSA_DLSYM(snd_pcm_hw_params_sizeof); + ALSA_DLSYM(snd_pcm_open); + ALSA_DLSYM(snd_pcm_prepare); + ALSA_DLSYM(snd_pcm_state); + ALSA_DLSYM(snd_pcm_writei); + ALSA_DLSYM(snd_strerror); + return true; +} + +/* +=============== +idAudioHardwareALSA::Release +=============== +*/ +void idAudioHardwareALSA::Release() { + if ( m_pcm_handle ) { + common->Printf( "close pcm\n" ); + id_snd_pcm_close( m_pcm_handle ); + m_pcm_handle = NULL; + } + if ( m_buffer ) { + free( m_buffer ); + m_buffer = NULL; + } + if ( m_handle ) { + common->Printf( "dlclose\n" ); + dlclose( m_handle ); + m_handle = NULL; + } +} + +/* +================= +idAudioHardwareALSA::InitFailed +================= +*/ +void idAudioHardwareALSA::InitFailed() { + Release(); + cvarSystem->SetCVarBool( "s_noSound", true ); + common->Warning( "sound subsystem disabled\n" ); + common->Printf( "--------------------------------------\n" ); +} + +/* +===================== +idAudioHardwareALSA::Initialize +===================== +*/ +bool idAudioHardwareALSA::Initialize( void ) { + int err; + + common->Printf( "------ Alsa Sound Initialization -----\n" ); + if ( !DLOpen() ) { + InitFailed(); + return false; + } + if ( ( err = id_snd_pcm_open( &m_pcm_handle, s_alsa_pcm.GetString(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) < 0 ) { + common->Printf( "snd_pcm_open SND_PCM_STREAM_PLAYBACK '%s' failed: %s\n", s_alsa_pcm.GetString(), id_snd_strerror( err ) ); + InitFailed(); + return false; + } + common->Printf( "opened Alsa PCM device %s for playback\n", s_alsa_pcm.GetString() ); + + // set hardware parameters ---------------------------------------------------------------------- + + // init hwparams with the full configuration space + snd_pcm_hw_params_t *hwparams; + // this one is a define + id_snd_pcm_hw_params_alloca( &hwparams ); + if ( ( err = id_snd_pcm_hw_params_any( m_pcm_handle, hwparams ) ) < 0 ) { + common->Printf( "cannot configure the PCM device: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + if ( ( err = id_snd_pcm_hw_params_set_access( m_pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 ) { + common->Printf( "SND_PCM_ACCESS_RW_INTERLEAVED failed: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + if ( ( err = id_snd_pcm_hw_params_set_format( m_pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE ) ) < 0 ) { + common->Printf( "SND_PCM_FORMAT_S16_LE failed: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + // channels + + // sanity over number of speakers + if ( idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 6 && idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) { + common->Warning( "invalid value for s_numberOfSpeakers. Use either 2 or 6" ); + idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 ); + } + + m_channels = idSoundSystemLocal::s_numberOfSpeakers.GetInteger(); + if ( ( err = id_snd_pcm_hw_params_set_channels( m_pcm_handle, hwparams, m_channels ) ) < 0 ) { + common->Printf( "error setting %d channels: %s\n", m_channels, id_snd_strerror( err ) ); + if ( idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) { + // fallback to stereo if that works + m_channels = 2; + if ( ( err = id_snd_pcm_hw_params_set_channels( m_pcm_handle, hwparams, m_channels ) ) < 0 ) { + common->Printf( "fallback to stereo failed: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } else { + common->Printf( "fallback to stereo\n" ); + idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 ); + } + } else { + InitFailed(); + return false; + } + } + + // set sample rate (frequency) + if ( ( err = id_snd_pcm_hw_params_set_rate( m_pcm_handle, hwparams, PRIMARYFREQ, 0 ) ) < 0 ) { + common->Printf( "failed to set 44.1KHz rate: %s - try ( +set s_alsa_pcm plughw:0 ? )\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + // have enough space in the input buffer for our MIXBUFFER_SAMPLE feedings and async ticks + snd_pcm_uframes_t frames; + frames = MIXBUFFER_SAMPLES + MIXBUFFER_SAMPLES / 3; + if ( ( err = id_snd_pcm_hw_params_set_buffer_size_min( m_pcm_handle, hwparams, &frames ) ) < 0 ) { + common->Printf( "buffer size select failed: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + // apply parameters + if ( ( err = id_snd_pcm_hw_params( m_pcm_handle, hwparams ) ) < 0 ) { + common->Printf( "snd_pcm_hw_params failed: %s\n", id_snd_strerror( err ) ); + InitFailed(); + return false; + } + + // check the buffer size + if ( ( err = id_snd_pcm_hw_params_get_buffer_size( hwparams, &frames ) ) < 0 ) { + common->Printf( "snd_pcm_hw_params_get_buffer_size failed: %s\n", id_snd_strerror( err ) ); + } else { + common->Printf( "device buffer size: %lu frames ( %lu bytes )\n", ( long unsigned int )frames, frames * m_channels * 2 ); + } + + // TODO: can use swparams to setup the device so it doesn't underrun but rather loops over + // snd_pcm_sw_params_set_stop_threshold + // To get alsa to just loop on underruns. set the swparam stop_threshold to equal buffer size. The sound buffer will just loop and never throw an xrun. + + // allocate the final mix buffer + m_buffer_size = MIXBUFFER_SAMPLES * m_channels * 2; + m_buffer = malloc( m_buffer_size ); + common->Printf( "allocated a mix buffer of %d bytes\n", m_buffer_size ); + +#ifdef _DEBUG + // verbose the state + snd_pcm_state_t curstate = id_snd_pcm_state( m_pcm_handle ); + assert( curstate == SND_PCM_STATE_PREPARED ); +#endif + + common->Printf( "--------------------------------------\n" ); + return true; +} + +/* +=============== +idAudioHardwareALSA::~idAudioHardwareALSA +=============== +*/ +idAudioHardwareALSA::~idAudioHardwareALSA() { + common->Printf( "----------- Alsa Shutdown ------------\n" ); + Release(); + common->Printf( "--------------------------------------\n" ); +} + +/* +================= +idAudioHardwareALSA::GetMixBufferSize +================= +*/ +int idAudioHardwareALSA::GetMixBufferSize() { + return m_buffer_size; +} + +/* +================= +idAudioHardwareALSA::GetMixBuffer +================= +*/ +short* idAudioHardwareALSA::GetMixBuffer() { + return (short *)m_buffer; +} + +/* +=============== +idAudioHardwareALSA::Flush +=============== +*/ +bool idAudioHardwareALSA::Flush( void ) { + int ret; + snd_pcm_state_t state; + state = id_snd_pcm_state( m_pcm_handle ); + if ( state != SND_PCM_STATE_RUNNING && state != SND_PCM_STATE_PREPARED ) { + if ( ( ret = id_snd_pcm_prepare( m_pcm_handle ) ) < 0 ) { + Sys_Printf( "failed to recover from SND_PCM_STATE_XRUN: %s\n", id_snd_strerror( ret ) ); + cvarSystem->SetCVarBool( "s_noSound", true ); + return false; + } + Sys_Printf( "preparing audio device for output\n" ); + } + Write( true ); +} + +/* +=============== +idAudioHardwareALSA::Write +rely on m_freeWriteChunks which has been set in Flush() before engine did the mixing for this MIXBUFFER_SAMPLE +=============== +*/ +void idAudioHardwareALSA::Write( bool flushing ) { + if ( !flushing && m_remainingFrames ) { + // if we write after a new mixing loop, we should have m_writeChunk == 0 + // otherwise that last remaining chunk that was never flushed out to the audio device has just been overwritten + Sys_Printf( "idAudioHardwareALSA::Write: %d frames overflowed and dropped\n", m_remainingFrames ); + } + if ( !flushing ) { + // if running after the mix loop, then we have a full buffer to write out + m_remainingFrames = MIXBUFFER_SAMPLES; + } + if ( m_remainingFrames == 0 ) { + return; + } + // write the max frames you can in one shot - we need to write it all out in Flush() calls before the next Write() happens + int pos = (int)m_buffer + ( MIXBUFFER_SAMPLES - m_remainingFrames ) * m_channels * 2; + snd_pcm_sframes_t frames = id_snd_pcm_writei( m_pcm_handle, (void*)pos, m_remainingFrames ); + if ( frames < 0 ) { + if ( frames != -EAGAIN ) { + Sys_Printf( "snd_pcm_writei %d frames failed: %s\n", m_remainingFrames, id_snd_strerror( frames ) ); + } + return; + } + m_remainingFrames -= frames; +} diff --git a/sys/linux/stack.cpp b/sys/linux/stack.cpp new file mode 100644 index 000000000..21e694886 --- /dev/null +++ b/sys/linux/stack.cpp @@ -0,0 +1,128 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" + +/* +================== +Sys_ShutdownSymbols +================== +*/ +void Sys_ShutdownSymbols( void ) { +} + +#ifdef ID_BT_STUB + +/* +================== +Sys_GetCallStack +================== +*/ +void Sys_GetCallStack( address_t *callStack, const int callStackSize ) { + for ( int i = 0; i < callStackSize; i++ ) { + callStack[i] = 0; + } +} + +/* +================== +Sys_GetCallStackStr +================== +*/ +const char * Sys_GetCallStackStr( const address_t *callStack, const int callStackSize ) { + return ""; +} + +/* +================== +Sys_GetCallStackStr +================== +*/ +const char * Sys_GetCallStackCurStr( int depth ) { + return ""; +} + +/* +================== +Sys_GetCallStackCurAddressStr +================== +*/ +const char * Sys_GetCallStackCurAddressStr( int depth ) { + return ""; +} + +#else + +#include + +/* +================== +Sys_GetCallStack +================== +*/ +void Sys_GetCallStack( address_t *callStack, const int callStackSize ) { + int i; + i = backtrace( (void **)callStack, callStackSize ); + while( i < callStackSize ) { + callStack[i++] = 0; + } +} + +/* +================== +Sys_GetCallStackStr +================== +*/ +const char * Sys_GetCallStackStr( const address_t *callStack, int callStackSize ) { + static char string[MAX_STRING_CHARS*2]; + char **strings; + int i; + + strings = backtrace_symbols( (void **)callStack, callStackSize ); + string[ 0 ] = '\0'; + for ( i = 0; i < callStackSize; i++ ) { + idStr::snPrintf( string + strlen( string ), MAX_STRING_CHARS*2 - strlen( string ) - 1, "%s\n", strings[ i ] ); + } + free( strings ); + return string; +} + + +/* +================== +Sys_GetCallStackStr +================== +*/ +const char * Sys_GetCallStackCurStr( int depth ) { + address_t array[ 32 ]; + size_t size; + + size = backtrace( (void **)array, Min( 32, depth ) ); + return Sys_GetCallStackStr( array, (int)size ); +} + +/* +================== +Sys_GetCallStackCurAddressStr +================== +*/ +const char * Sys_GetCallStackCurAddressStr( int depth ) { + return Sys_GetCallStackCurStr( depth ); +} + +#endif diff --git a/sys/linux/test_scheduler.c b/sys/linux/test_scheduler.c new file mode 100644 index 000000000..b8bcebc7e --- /dev/null +++ b/sys/linux/test_scheduler.c @@ -0,0 +1,105 @@ +/* +=========================================================================== + +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. + +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). + +Doom 3 Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 Source Code. If not, see . + +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include +#include +#include +#include + +/* +================ +Sys_Milliseconds +================ +*/ +/* base time in seconds, that's our origin + timeval:tv_sec is an int: + assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038 + using unsigned long data type to work right with Sys_XTimeToSysTime */ +unsigned long sys_timeBase = 0; +/* current time in ms, using sys_timeBase as origin + NOTE: sys_timeBase*1000 + curtime -> ms since the Epoch + 0x7fffffff ms - ~24 days + or is it 48 days? the specs say int, but maybe it's casted from unsigned int? +*/ +int Sys_Milliseconds(void) +{ + int curtime; + struct timeval tp; + + gettimeofday(&tp, NULL); + + if (!sys_timeBase) { + sys_timeBase = tp.tv_sec; + return tp.tv_usec / 1000; + } + + curtime = (tp.tv_sec - sys_timeBase) * 1000 + tp.tv_usec / 1000; + + return curtime; +} + +#define STAT_BUF 100 + +int main(int argc, void *argv[]) { + int start = 30; // start waiting with 30 ms + int dec = 2; // decrement by 2 ms + int min = 4; // min wait test + int i, j, now, next; + int stats[STAT_BUF]; + + struct sched_param parm; + + Sys_Milliseconds(); // init + + // set schedule policy to see if that affects usleep + // (root rights required for that) + parm.sched_priority = 99; + if ( sched_setscheduler(0, SCHED_RR, &parm) != 0 ) { + printf("sched_setscheduler SCHED_RR failed: %s\n", strerror(errno) ); + } else { + printf("sched_setscheduler SCHED_RR ok\n"); + } + + // now run the test + for( i = start ; i >= min ; i -= dec ) { + printf( "sleep %d ms", i ); + for( j = 0 ; j < STAT_BUF ; j++ ) { + now = Sys_Milliseconds(); + usleep(i*1000); + stats[j] = Sys_Milliseconds() - now; + } + for( j = 0; j < STAT_BUF; j++) { + if ( ! (j & 0xf) ) { + printf("\n"); + } + printf( "%d ", stats[j] ); + } + printf("\n"); + } + return 0; +} diff --git a/sys/msvc/properties/_Common.props b/sys/msvc/properties/_Common.props new file mode 100644 index 000000000..379aceba7 --- /dev/null +++ b/sys/msvc/properties/_Common.props @@ -0,0 +1,22 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Common Project Properties + $(SolutionDir)\build\$(PlatformName)\$(Configuration)\ + $(SolutionDir)\build\$(PlatformName)\$(Configuration)\intermediate\$(ProjectName)\ + + + + WIN32;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;%(PreprocessorDefinitions) + Level4 + + + /MP %(AdditionalOptions) + $(SolutionDir)/include;$(SolutionDir)/win32/devil;%(AdditionalIncludeDirectories) + + + $(SolutionDir)/win32/lib + + + \ No newline at end of file diff --git a/sys/msvc/properties/_Curl.props b/sys/msvc/properties/_Curl.props new file mode 100644 index 000000000..526cb4e92 --- /dev/null +++ b/sys/msvc/properties/_Curl.props @@ -0,0 +1,13 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Curl Library + + + + Level3 + USRDLL;CURLLIB_EXPORTS;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/sys/msvc/properties/_Debug.props b/sys/msvc/properties/_Debug.props new file mode 100644 index 000000000..315fa2167 --- /dev/null +++ b/sys/msvc/properties/_Debug.props @@ -0,0 +1,24 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Debug + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + EnableFastChecks + false + MultiThreadedDebug + true + ProgramDatabase + + + nafxcwd.lib;libcmtd.lib;%(AdditionalDependencies) + nafxcwd.lib;libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + true + true + + + \ No newline at end of file diff --git a/sys/msvc/properties/_Dedicated.props b/sys/msvc/properties/_Dedicated.props new file mode 100644 index 000000000..cea663fd9 --- /dev/null +++ b/sys/msvc/properties/_Dedicated.props @@ -0,0 +1,12 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Dedicated + + + + ID_DEDICATED;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/sys/msvc/properties/_DoomDLL.props b/sys/msvc/properties/_DoomDLL.props new file mode 100644 index 000000000..9ed892fda --- /dev/null +++ b/sys/msvc/properties/_DoomDLL.props @@ -0,0 +1,27 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Doom III Executable + + + + sound/vorbis/include;%(AdditionalIncludeDirectories) + __DOOM__;__DOOM_DLL__;CURL_STATICLIB;%(PreprocessorDefinitions) + + + Level3 + + + libcurl.lib;dbghelp.lib;dinput8.lib;dsound.lib;dxguid.lib;DxErr.lib;eaxguid.lib;glu32.lib;iphlpapi.lib;odbc32.lib;odbccp32.lib;opengl32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies) + C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86;openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories) + $(OutDir)DOOM3.exe + %(AdditionalManifestDependencies) + Windows + 16777216 + 16777216 + true + LIBCMT.lib + + + \ No newline at end of file diff --git a/sys/msvc/properties/_Game.props b/sys/msvc/properties/_Game.props new file mode 100644 index 000000000..70b03bdac --- /dev/null +++ b/sys/msvc/properties/_Game.props @@ -0,0 +1,26 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Game Library + + + + __DOOM__;GAME_DLL;IL_STATIC_LIB;CURL_STATICLIB;%(PreprocessorDefinitions) + + + $(SolutionDir)/include/zlib;$(SolutionDir)/include/devil;%(AdditionalIncludeDirectories) + + + $(OutDir)gamex86.dll + .\game\game.def + ZipLoader.lib;libcurl.lib;DevIL.lib;libpng.lib;libjpeg.lib;%(AdditionalDependencies) + $(SolutionDir)/win32/devil/lib;$(SolutionDir)/win32/libjpeg/lib;$(SolutionDir)/win32/libpng/lib;%(AdditionalLibraryDirectories) + LIBCMT.lib + + + + + + + \ No newline at end of file diff --git a/sys/msvc/properties/_MayaImport.props b/sys/msvc/properties/_MayaImport.props new file mode 100644 index 000000000..711467ca5 --- /dev/null +++ b/sys/msvc/properties/_MayaImport.props @@ -0,0 +1,19 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>MayaImport Library + + + + mssdk/include;MayaImport/Maya5.0;%(AdditionalIncludeDirectories) + _USRDLL;MAYAIMPORT_EXPORTS;MAYA_IMPORT;REQUIRE_IOSTREAM;%(PreprocessorDefinitions) + Use + Level3 + + + Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies) + MayaImport/maya5.0/libs;%(AdditionalLibraryDirectories) + + + \ No newline at end of file diff --git a/sys/msvc/properties/_Release.props b/sys/msvc/properties/_Release.props new file mode 100644 index 000000000..1ce062728 --- /dev/null +++ b/sys/msvc/properties/_Release.props @@ -0,0 +1,30 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>Release + + + + MaxSpeed + AnySuitable + true + true + NDEBUG;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + ProgramDatabase + + + nafxcw.lib;libcmt.lib;%(AdditionalDependencies) + nafxcw.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + false + false + true + true + + + \ No newline at end of file diff --git a/sys/msvc/properties/_TypeInfo.props b/sys/msvc/properties/_TypeInfo.props new file mode 100644 index 000000000..464ead969 --- /dev/null +++ b/sys/msvc/properties/_TypeInfo.props @@ -0,0 +1,16 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>TypeInfo + + + + ID_ENABLE_CURL=0;ID_TYPEINFO;__DOOM_DLL__;%(PreprocessorDefinitions) + Use + + + Console + + + \ No newline at end of file diff --git a/sys/msvc/properties/_WithInlines.props b/sys/msvc/properties/_WithInlines.props new file mode 100644 index 000000000..ac88a6a65 --- /dev/null +++ b/sys/msvc/properties/_WithInlines.props @@ -0,0 +1,13 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>With Inlines + + + + OnlyExplicitInline + _INLINEDEBUG;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/sys/msvc/properties/_WithMemoryLog.props b/sys/msvc/properties/_WithMemoryLog.props new file mode 100644 index 000000000..79867b555 --- /dev/null +++ b/sys/msvc/properties/_WithMemoryLog.props @@ -0,0 +1,12 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>With Memory Log + + + + ID_REDIRECT_NEWDELETE;ID_DEBUG_MEMORY;ID_DEBUG_UNINITIALIZED_MEMORY;%(PreprocessorDefinitions) + + + \ No newline at end of file diff --git a/sys/msvc/properties/_idlib.props b/sys/msvc/properties/_idlib.props new file mode 100644 index 000000000..3d7dc2f9b --- /dev/null +++ b/sys/msvc/properties/_idlib.props @@ -0,0 +1,13 @@ + + + + <_ProjectFileVersion>10.0.40219.1 + <_PropertySheetDisplayName>idlib + + + + __IDLIB__;%(PreprocessorDefinitions) + Use + + + \ No newline at end of file diff --git a/sys/osx/DLL.OSX.txt b/sys/osx/DLL.OSX.txt new file mode 100644 index 000000000..2ffca308f --- /dev/null +++ b/sys/osx/DLL.OSX.txt @@ -0,0 +1,34 @@ +short: + +dlopen/dlclose, then dlopen a dynamic library again won't go through C++ static initialization again + +long: + +first dlopen: +set a break in idTypeInfo constructor ( class typeinfo is static ) +nothing happens on dlopen, statics are initialized when resolving symbols ( as they need to be before any C++ code runs ) +#0 0x900429ac in kill () +#1 0x1ee95074 in idClass::ProcessEventArgPtr(idEventDef const*, int*) () at /Users/timo/SVN/Doom/neo/framework/CmdSystem.h:130 +#2 0x1ee94ff4 in idClass::ProcessEventArgPtr(idEventDef const*, int*) () at /Users/timo/SVN/Doom/neo/framework/CmdSystem.h:130 +#3 0x1f138d30 in __static_initialization_and_destruction_0(int, int) (__initialize_p=521892804, __priority=520821908) at /Users/timo/SVN/Doom/neo/game/Actor.cpp:339 +#4 0x1f138d94 in _GLOBAL__I__ZN11idAnimStateC2Ev () at /Users/timo/SVN/Doom/neo/game/Actor.cpp:106 +#5 0x8fe17728 in __dyld_call_module_initializers_for_library () +#6 0x8fe174a0 in __dyld_call_module_initializers () +#7 0x8fe11704 in __dyld_link_in_need_modules () +#8 0x8fe14f50 in __dyld__dyld_NSLookupSymbolInImage () +#9 0x900f81f0 in dlsymIntern () +#10 0x900f8b1c in dlsym () +#11 0x001e71c8 in Sys_DLL_GetProcAddress(int, char const*) (handle=392873136, sym=0x3a0b20 "GetGameAPI") at /Users/timo/SVN/Doom/neo/sys/posix/posix_main.cpp:376 +#12 0x0008c968 in idCommonLocal::LoadGameDLL() (this=0x78a85c) at /Users/timo/SVN/Doom/neo/framework/Common.cpp:2589 + +then do reloadEngine, the DLL will be dlclose, then dlopen again +this time no initialization happens ( even though there is another dlsym call, and a call to GetGameAPI ) +things in that case pretty much behave like the monolithic build does + +searched online and found a bunch of people complaining about this problem here and there, but no obvious fix around +http://lists.apple.com/archives/darwin-development/2003/Sep/msg00109.html + +from the dlopen man page and various things online, I think that on top of dlclose, one should also remove +the library from the address space to force a fresh start + +maybe using NSModule ( man 3 NSModule ) would fix those issues? diff --git a/sys/osx/DOOMController.h b/sys/osx/DOOMController.h new file mode 100644 index 000000000..b43c72e1e --- /dev/null +++ b/sys/osx/DOOMController.h @@ -0,0 +1,15 @@ +// $Header: /Network/CIFS/Limbo/Limbo/CVS/id/missionpack/code/macosx/Client/DOOMController.h,v 1.2 2000/11/14 04:38:34 zaphod Exp $ + +#import + +@interface DOOMController : NSObject +{ + // IBOutlet NSPanel *bannerPanel; +} + +//- (IBAction)paste:(id)sender; +//- (IBAction)requestTerminate:(id)sender; + +//- (void) showBanner; + +@end diff --git a/sys/osx/DOOMController.mm b/sys/osx/DOOMController.mm new file mode 100644 index 000000000..01e47a950 --- /dev/null +++ b/sys/osx/DOOMController.mm @@ -0,0 +1,1056 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +// -*- mode: objc -*- +//#define __DARWIN_UNIX03 0 // greebo: We need the struct __darwin_mcontext to contain fs, no underscores +#import "../../idlib/precompiled.h" +#import "DOOMController.h" + +#import +#import + +#import +#import +#import +#import + +#import "macosx_common.h" +#import "macosx_local.h" +#import "macosx_sys.h" + +#import +#import +#import + +#define MAX_KEYS 256 + +static idStr savepath; + +extern bool key_overstrikeMode; + +#define TEST_FPU_EXCEPTIONS \ +FPU_EXCEPTION_INVALID_OPERATION | \ +FPU_EXCEPTION_DENORMALIZED_OPERAND | \ +FPU_EXCEPTION_DIVIDE_BY_ZERO | \ +/* FPU_EXCEPTION_NUMERIC_OVERFLOW | */ \ +/* FPU_EXCEPTION_NUMERIC_UNDERFLOW | */ \ +/* FPU_EXCEPTION_INEXACT_RESULT | */ \ +0 + +#define kRegKey @"RegCode" + +static const ControlID kRegCode1EditText = { 'RegC', 1 }; + +struct RegCodeInfo +{ + char prefRegCode1[256]; + bool okPressed; + WindowRef window; + ControlRef regCode1EditText; +}; + +static OSErr DoRegCodeDialog( char* ioRegCode1 ); + + +@interface DOOMController (Private) +- (void)quakeMain; +- (BOOL)checkRegCodes; +- (BOOL)checkOS; +@end + +@implementation DOOMController + +/* ++ (void)initialize; +{ + static bool initialized = NO; + + [super initialize]; + if ( initialized ) { + return; + } + initialized = YES; +} +*/ + +#define MAX_ARGC 1024 + +- (void)applicationDidFinishLaunching:(NSNotification *)notification; +{ + NS_DURING { + NSAssert(sizeof(bool) == 1, @"sizeof(bool) should equal 1 byte"); + [self quakeMain]; + } NS_HANDLER { + Sys_Error( (const char *)[ [ localException reason ] cString ] ); + } NS_ENDHANDLER; + Sys_Quit(); +} + +- (void)applicationWillHide:(NSNotification *)notification; +{ + Sys_ShutdownInput(); +} + +- (void)applicationWillUnhide:(NSNotification *)notification; +{ + Sys_InitInput(); +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + common->Quit(); + return NSTerminateLater; // we never reach this +} + +#if 0 +// Actions + +- (IBAction)paste:(id)sender; +{ + int shiftWasDown, insertWasDown; + unsigned int currentTime; + + currentTime = Sys_Milliseconds(); + // Save the original keyboard state + shiftWasDown = keys[K_SHIFT].down; + insertWasDown = keys[K_INS].down; + // Fake a Shift-Insert keyboard event + keys[K_SHIFT].down = true; + Posix_QueEvent(currentTime, SE_KEY, K_INS, true, 0, NULL); + Posix_QueEvent(currentTime, SE_KEY, K_INS, false, 0, NULL); + // Restore the original keyboard state + keys[K_SHIFT].down = shiftWasDown; + keys[K_INS].down = insertWasDown; +} + +extern void CL_Quit_f(void); +//extern void SetProgramPath(const char *path); + + +- (IBAction)requestTerminate:(id)sender; +{ + //osxQuit(); + common->Quit(); +} + +- (void)showBanner; +{ + static bool hasShownBanner = NO; + + if (!hasShownBanner) { + //cvar_t *showBanner; + + hasShownBanner = YES; + //showBanner = Cvar_Get("cl_showBanner", "1", 0); + //if ( showBanner->integer != 0 ) { + if ( true ) { + NSPanel *splashPanel; + NSImage *bannerImage; + NSRect bannerRect; + NSImageView *bannerImageView; + + bannerImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"banner.jpg"]]; + bannerRect = NSMakeRect(0.0, 0.0, [bannerImage size].width, [bannerImage size].height); + + splashPanel = [[NSPanel alloc] initWithContentRect:bannerRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; + + bannerImageView = [[NSImageView alloc] initWithFrame:bannerRect]; + [bannerImageView setImage:bannerImage]; + [splashPanel setContentView:bannerImageView]; + [bannerImageView release]; + + [splashPanel center]; + [splashPanel setHasShadow:YES]; + [splashPanel orderFront: nil]; + [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.5]]; + [splashPanel close]; + + [bannerImage release]; + } + } +} + +// Services + +- (void)connectToServer:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error; +{ + NSArray *pasteboardTypes; + + pasteboardTypes = [pasteboard types]; + if ([pasteboardTypes containsObject:NSStringPboardType]) { + NSString *requestedServer; + + requestedServer = [pasteboard stringForType:NSStringPboardType]; + if (requestedServer) { + Cbuf_AddText( va( "connect %s\n", [requestedServer cString])); + return; + } + } + *error = @"Unable to connect to server: could not find string on pasteboard"; +} + +- (void)performCommand:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error; +{ + NSArray *pasteboardTypes; + + pasteboardTypes = [pasteboard types]; + if ([pasteboardTypes containsObject:NSStringPboardType]) { + NSString *requestedCommand; + + requestedCommand = [pasteboard stringForType:NSStringPboardType]; + if (requestedCommand) { + Cbuf_AddText(va("%s\n", [requestedCommand cString])); + return; + } + } + *error = @"Unable to perform command: could not find string on pasteboard"; +} + +#endif // commented out all the banners and actions + +@end + +@implementation DOOMController (Private) + +- (void)quakeMain +{ + NSAutoreleasePool *pool; + int argc = 0; + const char *argv[MAX_ARGC]; + NSProcessInfo *processInfo; + NSArray *arguments; + unsigned int argumentIndex, argumentCount; + //const char *cddir; + //NSFileManager *defaultManager; + //bool tryAgain; + + pool = [[NSAutoreleasePool alloc] init]; + + [NSApp setServicesProvider:self]; + + processInfo = [NSProcessInfo processInfo]; + arguments = [processInfo arguments]; + argumentCount = [arguments count]; + for (argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) { + argv[argc++] = strdup([[arguments objectAtIndex:argumentIndex] cString]); + } + if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] resourcePath]]) { + Sys_Error("Could not access application resources"); + } + //cddir = macosx_scanForLibraryDirectory(); + /* + do { + tryAgain = NO; + defaultManager = [NSFileManager defaultManager]; + if (![defaultManager fileExistsAtPath:@"./base/default.cfg"] && (!cddir || *cddir == '\0' || ![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s/baseq3/pak0.pk3", cddir]])) { + NSString *message; + + if (!cddir || *cddir == '\0') { + message = [NSString stringWithFormat:@"Could not find DOOM levels."]; + } else if (![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s", cddir]]) { + message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' does not exist.", cddir]; + } else { + message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' is not a complete DOOM installation.", cddir]; + } + switch (NSRunAlertPanel(@"DOOM", @"%@", @"Quit", @"Find...", nil, message)) { + case NSAlertDefaultReturn: + default: + Sys_Quit(); + break; + case NSAlertAlternateReturn: + tryAgain = YES; + break; + } + if (tryAgain) { + NSOpenPanel *openPanel; + int result; + + openPanel = [NSOpenPanel openPanel]; + [openPanel setAllowsMultipleSelection:NO]; + [openPanel setCanChooseDirectories:YES]; + [openPanel setCanChooseFiles:NO]; + result = [openPanel runModalForDirectory:nil file:nil]; + if (result == NSOKButton) { + NSArray *filenames; + + filenames = [openPanel filenames]; + if ([filenames count] == 1) { + NSString *cdPath; + + cdPath = [filenames objectAtIndex:0]; + [[NSUserDefaults standardUserDefaults] setObject:cdPath forKey:@"CDPath"]; + cddir = strdup([cdPath cString]); + } + } + } + } + } while (tryAgain); + */ +/* + if (cddir && *cddir != '\0') { + SetProgramPath([[[NSString stringWithCString:cddir] stringByAppendingPathComponent:@"/x"] cString]); + } +*/ + + //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS ); + + Posix_EarlyInit( ); + +#ifndef _DEBUG + if ( [self checkOS] == FALSE) { + common->Quit(); + } + + if ( [self checkDVD] == FALSE) { + common->Quit(); + } +#endif + + // need strncmp, can't use idlib before init +#undef strncmp + // Finder passes the process serial number as only argument after the program path + // nuke it if we see it + if ( argc > 1 && strncmp( argv[ 1 ], "-psn", 4 ) ) { + common->Init( argc-1, &argv[1], NULL ); + } else { + common->Init( 0, NULL, NULL ); + } + + Posix_LateInit( ); + + [NSApp activateIgnoringOtherApps:YES]; + + while (1) { +#ifdef OMNI_TIMER + OTPeriodicTimerReset(); + OTNodeStart(RootNode); +#endif + + // maintain exceptions in case system calls are turning them off (is that needed) + //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS ); + + common->Frame(); + + // We should think about doing this less frequently than every frame + [pool release]; + pool = [[NSAutoreleasePool alloc] init]; +#ifdef OMNI_TIMER + OTNodeStop(RootNode); +#endif + } + + [pool release]; +} + +- (BOOL)checkRegCodes +{ + BOOL retval; + NSString *cdKey; + NSUserDefaults *userDefaults; + + userDefaults = [NSUserDefaults standardUserDefaults]; + cdKey = [userDefaults stringForKey:kRegKey]; + + retval = TRUE; + if ( cdKey == nil || [cdKey length] == 0 ) { + char regCode[256]; + if ( DoRegCodeDialog( regCode ) != noErr ) { + retval = FALSE; + } + else { + [userDefaults setObject:[NSString stringWithCString: regCode] forKey:kRegKey]; + [userDefaults synchronize]; + } + } + return retval; +} + +- (BOOL)checkOS +{ + OSErr err; + long gestaltOSVersion; + err = Gestalt(gestaltSystemVersion, &gestaltOSVersion); + if ( err || gestaltOSVersion < 0x1038 ) { + NSBundle *thisBundle = [ NSBundle mainBundle ]; + NSString *messsage = [ thisBundle localizedStringForKey:@"InsufficientOS" value:@"No translation" table:nil ]; + NSRunAlertPanel(@GAME_NAME, messsage, nil, nil, nil); + return FALSE; + } + return TRUE; +} + +- (BOOL)checkDVD +{ + return TRUE; +} + +@end + +/* +============== +Sys_EXEPath +============== +*/ +const char *Sys_EXEPath( void ) { + static char exepath[ 1024 ]; + strncpy( exepath, [ [ [ NSBundle mainBundle ] bundlePath ] cString ], 1024 ); + return exepath; +} + +/* + ========== + Sys_DefaultSavePath + ========== + */ +const char *Sys_DefaultSavePath(void) { +#if defined( ID_DEMO_BUILD ) + sprintf( savepath, "%s/Library/Application Support/Doom 3 Demo", [NSHomeDirectory() cString] ); +#else + sprintf( savepath, "%s/Library/Application Support/Doom 3", [NSHomeDirectory() cString] ); +#endif + return savepath.c_str(); +} + +/* +========== +Sys_DefaultBasePath +========== +*/ +const char *Sys_DefaultBasePath(void) { + static char basepath[ 1024 ]; + strncpy( basepath, [ [ [ NSBundle mainBundle ] bundlePath ] cString ], 1024 ); + char *snap = strrchr( basepath, '/' ); + if ( snap ) { + *snap = '\0'; + } + return basepath; +} + +/* +=============== +Sys_Shutdown +=============== +*/ +void Sys_Shutdown( void ) { + savepath.Clear(); + Posix_Shutdown(); +} + + +/* +=============== +Sys_GetProcessorId +=============== +*/ +cpuid_t Sys_GetProcessorId( void ) { + cpuid_t cpuid = CPUID_GENERIC; +#if defined(__ppc__) + cpuid |= CPUID_ALTIVEC; +#elif defined(__i386__) + cpuid |= CPUID_INTEL | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_SSE3 | CPUID_HTT | CPUID_CMOV | CPUID_FTZ | CPUID_DAZ; +#endif + return cpuid; +} + +/* +=============== +Sys_GetProcessorString +=============== +*/ +const char *Sys_GetProcessorString( void ) { +#if defined(__ppc__) + return "ppc CPU with AltiVec extensions"; +#elif defined(__i386__) + return "x86 CPU with MMX/SSE/SSE2/SSE3 extensions"; +#else + #error + return NULL; +#endif +} + +/* +=============== +Sys_FPU_EnableExceptions +http://developer.apple.com/documentation/mac/PPCNumerics/PPCNumerics-154.html +http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf +=============== +*/ + +#define fegetenvd(x) asm volatile( "mffs %0" : "=f" (x) ); +#define fesetenvd(x) asm volatile( "mtfsf 255,%0" : : "f" (x) ); +enum { + FE_ENABLE_INEXACT = 0x8, + FE_ENABLE_DIVBYZERO = 0x10, + FE_ENABLE_UNDERFLOW = 0x20, + FE_ENABLE_OVERFLOW = 0x40, + FE_ENABLE_INVALID = 0x80, + FE_ENABLE_ALL_EXCEPT = 0xF8 +}; + +typedef union { + struct { + unsigned long hi; + unsigned long lo; + } i; + double d; +} hexdouble; + +static int exception_mask = 0; + +void Sys_FPU_EnableExceptions( int exceptions ) { +#if 0 + if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) { + // clear the flag before enabling the exception + asm( "mtfsb0 2" ); + asm( "mtfsb0 7" ); + asm( "mtfsb0 8" ); + asm( "mtfsb0 9" ); + asm( "mtfsb0 10" ); + asm( "mtfsb0 11" ); + asm( "mtfsb0 12" ); + asm( "mtfsb0 21" ); + asm( "mtfsb0 22" ); + asm( "mtfsb0 23" ); + // enable + asm( "mtfsb1 24" ); + } else { + asm( "mtfsb0 24" ); + } + if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) { + asm( "mtfsb0 5" ); + asm( "mtfsb1 27" ); + } else { + asm( "mtfsb0 27" ); + } + if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) { + asm( "mtfsb0 3" ); + asm( "mtfsb1 25" ); + } else { + asm( "mtfsb0 25" ); + } + if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) { + asm( "mtfsb0 4" ); + asm( "mtfsb1 26" ); + } else { + asm( "mtfsb0 26" ); + } + if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) { + asm( "mtfsb0 6" ); + asm( "mtfsb0 13" ); + asm( "mtfsb0 14" ); + asm( "mtfsb1 28" ); + } else { + asm( "mtfsb0 28" ); + } +#elif defined(__ppc__) + hexdouble t; + exception_mask = 0; + if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) { + exception_mask |= FE_ENABLE_INVALID; + } + if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) { + exception_mask |= FE_ENABLE_DIVBYZERO; + } + if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) { + exception_mask |= FE_ENABLE_OVERFLOW; + } + if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) { + exception_mask |= FE_ENABLE_UNDERFLOW; + } + if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) { + exception_mask |= FE_ENABLE_INVALID; + } + Sys_Printf( "Sys_FPUEnableExceptions: 0x%x\n", exception_mask ); + // clear the exception flags + feclearexcept( FE_ALL_EXCEPT ); + // set the enable flags on the exceptions we want + fegetenvd( t.d ); + t.i.lo &= ~FE_ENABLE_ALL_EXCEPT; + t.i.lo |= exception_mask; + fesetenvd( t.d ); + Sys_Printf( "done\n" ); +#endif +} + +/* +=============== +Sys_FPE_handler +=============== +*/ +void Sys_FPE_handler( int signum, siginfo_t *info, void *context ) { +#if defined(__ppc__) + int ret; + ppc_float_state_t *fs; + ppc_thread_state_t *ss; + +#if __DARWIN_UNIX03 // greebo: DARWIN_UNIX03 means all struct members have leading double underscores + fs = &( (_STRUCT_UCONTEXT *)context )->uc_mcontext->__fs; + ss = &( (_STRUCT_UCONTEXT *)context )->uc_mcontext->__ss; +#else + fs = &( (_STRUCT_UCONTEXT *)context )->uc_mcontext->fs; + ss = &( (_STRUCT_UCONTEXT *)context )->uc_mcontext->ss; +#endif + + Sys_Printf( "FPE at 0x%x:\n", info->si_addr ); + + ret = fetestexcept( FE_ALL_EXCEPT ); + if ( ret & FE_INEXACT ) { + Sys_Printf( "FE_INEXACT " ); + } + if ( ret & FE_DIVBYZERO ) { + Sys_Printf( "FE_DIVBYZERO " ); + } + if ( ret & FE_UNDERFLOW ) { + Sys_Printf( "FE_UNDERFLOW " ); + } + if ( ret & FE_OVERFLOW ) { + Sys_Printf( "FE_OVERFLOW " ); + } + if ( ret & FE_INVALID ) { + Sys_Printf( "FE_INVALID " ); + } + Sys_Printf( "\n" ); + // clear the exception flags + feclearexcept( FE_ALL_EXCEPT ); + // re-arm +#if __DARWIN_UNIX03 // greebo: DARWIN_UNIX03 means all struct members have leading double underscores + fs->__fpscr &= exception_mask; + ss->__srr0 += 4; +#else + fs->fpscr &= exception_mask; + ss->srr0 += 4; +#endif +#endif +} + +/* +=============== +Sys_GetClockTicks +=============== +*/ +double Sys_GetClockTicks( void ) { + // NOTE that this only affects idTimer atm, which is only used for performance timing during developement +#warning FIXME: implement Sys_GetClockTicks + return 0.0; +} + +/* +=============== +Sys_ClockTicksPerSecond +=============== +*/ +double Sys_ClockTicksPerSecond(void) { + // Our strategy is to query both Gestalt & IOKit and then take the larger of the two values. + + long gestaltSpeed, ioKitSpeed = -1; + + // GESTALT + + // gestaltProcClkSpeedMHz available in 10.3 needs to be used because CPU speeds have now + // exceeded the signed long that Gestalt returns. + long osVers; + OSErr err; + Gestalt(gestaltSystemVersion, &osVers); + if (osVers >= 0x1030) + err = Gestalt(gestaltProcClkSpeedMHz, &gestaltSpeed); + else + { + err = Gestalt(gestaltProcClkSpeed, &gestaltSpeed); + if (err == noErr) + gestaltSpeed = gestaltSpeed / 1000000; + } + + // IO KIT + + mach_port_t masterPort; + CFMutableDictionaryRef matchDict = nil; + io_iterator_t itThis; + io_service_t service = nil; + + if (IOMasterPort(MACH_PORT_NULL, &masterPort)) + goto bail; + + matchDict = IOServiceNameMatching("cpus"); + if (IOServiceGetMatchingServices(masterPort, matchDict, &itThis)) + goto bail; + + service = IOIteratorNext(itThis); + while(service) + { + io_service_t ioCpu = NULL; + if (IORegistryEntryGetChildEntry(service, kIODeviceTreePlane, &ioCpu)) + goto bail; + + if (ioCpu) + { + CFDataRef data = (CFDataRef)IORegistryEntryCreateCFProperty(ioCpu, CFSTR("clock-frequency"),kCFAllocatorDefault,0); + if (data) + ioKitSpeed = *((unsigned long*)CFDataGetBytePtr(data)) / 1000000; + } + service = IOIteratorNext(itThis); + } + + // Return the larger value + +bail: + return ( ioKitSpeed > gestaltSpeed ? ioKitSpeed : gestaltSpeed ) * 1000000.f; +} + +/* +================ +Sys_GetSystemRam +returns in megabytes +================ +*/ +int Sys_GetSystemRam( void ) { + long ramSize; + + if ( Gestalt( gestaltPhysicalRAMSize, &ramSize ) == noErr ) { + return ramSize / (1024*1024); + } + else + return 1024; +} + +/* +================ +Sys_GetVideoRam +returns in megabytes +================ +*/ +int Sys_GetVideoRam( void ) { + unsigned int i; + CFTypeRef typeCode; + long vramStorage = 64; + const short MAXDISPLAYS = 8; + CGDisplayCount displayCount; + io_service_t dspPorts[MAXDISPLAYS]; + CGDirectDisplayID displays[MAXDISPLAYS]; + + CGGetOnlineDisplayList( MAXDISPLAYS, displays, &displayCount ); + + for ( i = 0; i < displayCount; i++ ) { + if ( Sys_DisplayToUse() == displays[i] ) { + dspPorts[i] = CGDisplayIOServicePort(displays[i]); + typeCode = IORegistryEntryCreateCFProperty( dspPorts[i], CFSTR("IOFBMemorySize"), kCFAllocatorDefault, kNilOptions ); + if( typeCode && CFGetTypeID( typeCode ) == CFNumberGetTypeID() ) { + CFNumberGetValue( ( CFNumberRef )typeCode, kCFNumberSInt32Type, &vramStorage ); + vramStorage /= (1024*1024); + } + } + } + + return vramStorage; +} + +bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture ) +{ + long cpu; + Gestalt(gestaltNativeCPUtype, &cpu); + + cpuId = cpu; + oldArchitecture = cpuId < gestaltCPU970; + return true; +} + +void OSX_GetVideoCard( int& outVendorId, int& outDeviceId ) +{ + kern_return_t err; + mach_port_t masterPort; + io_iterator_t itThis; + io_service_t service; + + outVendorId = -1; + outDeviceId = -1; + + // Get a mach port for us and check for errors + err = IOMasterPort(MACH_PORT_NULL, &masterPort); + if(err) + return; + // Grab all the PCI devices out of the registry + err = IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOPCIDevice"), &itThis); + if(err) + return; + + // Yank everything out of the iterator + // We could walk through all devices and try to determine the best card. But for now, + // we'll just look at the first card. + while(1) + { + service = IOIteratorNext(itThis); + io_name_t dName; + + // Make sure we have a valid service + if(service) + { + // Get the classcode so we know what we're looking at + CFDataRef classCode = (CFDataRef)IORegistryEntryCreateCFProperty(service,CFSTR("class-code"),kCFAllocatorDefault,0); + // Only accept devices that are + // PCI Spec - 0x00030000 is a display device + if((*(UInt32*)CFDataGetBytePtr(classCode) & 0x00ff0000) == 0x00030000) + { + // Get the name of the service (hw) + IORegistryEntryGetName(service, dName); + + CFDataRef vendorID, deviceID; + + // Get the information for the device we've selected from the list + vendorID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("vendor-id"),kCFAllocatorDefault,0); + deviceID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("device-id"),kCFAllocatorDefault,0); + + outVendorId = *((long*)CFDataGetBytePtr(vendorID)); + outDeviceId = *((long*)CFDataGetBytePtr(deviceID)); + + CFRelease(vendorID); + CFRelease(deviceID); + } + CFRelease(classCode); + + // Stop after finding the first device + if (outVendorId != -1) + break; + } + else + break; + } +} + +/* +=============== +main +=============== +*/ +int main( int argc, const char *argv[] ) { + return NSApplicationMain( argc, argv ); +} + + +#pragma mark - + + +bool FormatRegCode(const char* inRegCode, char* outRegCode) +{ + // Clean up the reg code. Remove spaces. Accept only numbers/letters. + char* dst = outRegCode; + const char* src = inRegCode; + while (*src) + { + if (isalnum(*src)) + *dst++ = *src; + else if (*src != ' ') + return false; + src++; + } + *dst = 0; + + // Reg codes are 18 characters in length + return strlen(outRegCode) == 18; +} + +/* + =============== + RegCodeHandler + =============== + */ +static pascal OSStatus RegCodeHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* inUserData ) +{ +#pragma unused( inHandler ) +#if 1 + // FIXME: the CD key API has changed for startup check support and expansion pack key support + return noErr; +#else + HICommand cmd; + OSStatus result = eventNotHandledErr; + RegCodeInfo* regCodeInfo = (RegCodeInfo*)inUserData; + + GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( cmd ), NULL, &cmd ); + + switch ( cmd.commandID ) { + case kHICommandOK: + bool fValid; + Size actualSize; + char cntrl[256]; + char doomKey[256]; + char strippedKey[256]; + + fValid = false; + strippedKey[0] = doomKey[0] = NULL; + GetControlData ( regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextTextTag, 256, cntrl, &actualSize ); + cntrl[actualSize] = NULL; + if ( FormatRegCode( cntrl, strippedKey ) ) { + strncat( doomKey, strippedKey, 16 ); + strcat( doomKey, " " ); + strncat( doomKey, strippedKey + 16, 2 ); + fValid = session->CheckKey( doomKey ); + } + if ( fValid ) { + strcpy( regCodeInfo->prefRegCode1, doomKey ); + session->SetCDKey( doomKey ); + } + else { + unsigned char theError[512]; + unsigned char theExplanation[512]; + CFStringRef theErrorStr = CFCopyLocalizedString( CFSTR("DVD_KEY_ERROR"), "" ); + CFStringRef theExplanationStr = CFCopyLocalizedString( CFSTR("DVD_KEY_EXPLANATION"), "" ); + c2pstrcpy( theError, CFStringGetCStringPtr( theErrorStr, kCFStringEncodingMacRoman ) ); + c2pstrcpy( theExplanation, CFStringGetCStringPtr( theExplanationStr, kCFStringEncodingMacRoman ) ); + + StandardAlert(kAlertStopAlert, theError, theExplanation, NULL, NULL); + + // Highlight the invalid reg code + ClearKeyboardFocus(regCodeInfo->window); + SetKeyboardFocus( regCodeInfo->window, regCodeInfo->regCode1EditText, kControlEditTextPart ); + ControlEditTextSelectionRec sel = {0, 32000}; + SetControlData (regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel); + break; + } + + regCodeInfo->okPressed = true; + QuitAppModalLoopForWindow( regCodeInfo->window ); + result = noErr; + + break; + + case kHICommandCancel: + regCodeInfo->okPressed = false; + QuitAppModalLoopForWindow( regCodeInfo->window ); + result = noErr; + break; + + } + return result; +#endif +} + +/* + =============== + DoRegCodeDialog + =============== + */ +static OSErr DoRegCodeDialog( char* ioRegCode1 ) +{ + OSErr err; + RegCodeInfo regCodeInfo; + memset(®CodeInfo, 0, sizeof(regCodeInfo)); + + IBNibRef aslNib; + CFBundleRef theBundle = CFBundleGetMainBundle(); + err = CreateNibReferenceWithCFBundle( theBundle, CFSTR("ASLCore"), &aslNib ); + err = ::CreateWindowFromNib( aslNib, CFSTR("Reg Code Sheet"), ®CodeInfo.window ); + if (err != noErr) + return err; + + GetControlByID( regCodeInfo.window, &kRegCode1EditText, ®CodeInfo.regCode1EditText ); + assert( regCodeInfo.regCode1EditText ); + SetKeyboardFocus( regCodeInfo.window, regCodeInfo.regCode1EditText, kControlEditTextPart ); + ControlEditTextSelectionRec sel = {0, 32000}; + SetControlData (regCodeInfo.regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel); + + EventTypeSpec cmdEvent = { kEventClassCommand, kEventCommandProcess }; + EventHandlerUPP handler = NewEventHandlerUPP( RegCodeHandler ); + InstallWindowEventHandler( regCodeInfo.window, handler, 1, &cmdEvent, ®CodeInfo, NULL ); + + RepositionWindow( regCodeInfo.window, NULL, kWindowAlertPositionOnMainScreen ); + ShowWindow( regCodeInfo.window ); + + RunAppModalLoopForWindow( regCodeInfo.window ); + + DisposeWindow( regCodeInfo.window ); + + if (regCodeInfo.okPressed) { + strcpy(ioRegCode1, regCodeInfo.prefRegCode1); + } + + return regCodeInfo.okPressed ? (OSErr)noErr : (OSErr)userCanceledErr; +} + +/* +================= +Sys_AsyncThread +================= +*/ +void Sys_AsyncThread( void ) { + while ( 1 ) { + usleep( 16666 ); + common->Async(); + Sys_TriggerEvent( TRIGGER_EVENT_ONE ); + pthread_testcancel(); + } +} + + +#if defined(__ppc__) + +/* + ================ + Sys_FPU_SetDAZ + ================ + */ +void Sys_FPU_SetDAZ( bool enable ) { +} + +/* + ================ + Sys_FPU_SetFTZ + ================ + */ +void Sys_FPU_SetFTZ( bool enable ) { +} + + +#elif defined(__i386__) + +#include + +/* + ================ + Sys_FPU_SetDAZ + ================ + */ +void Sys_FPU_SetDAZ( bool enable ) { + uint32_t dwData; + uint32_t enable_l = (uint32_t) enable; + + enable_l = enable_l & 1; + enable_l = enable_l << 6; + dwData = _mm_getcsr(); // store MXCSR to dwData + dwData = dwData & 0xffbf; + dwData = dwData | enable_l; + _mm_setcsr(dwData); // load MXCSR with dwData +} + +/* + ================ + Sys_FPU_SetFTZ + ================ + */ +void Sys_FPU_SetFTZ( bool enable ) { + + uint32_t dwData; + uint32_t enable_l = (uint32_t) enable; + + enable_l = enable_l & 1; + enable_l = enable_l << 15; + dwData = _mm_getcsr(); // store MXCSR to dwData + dwData = dwData & 0x7fff; + dwData = dwData | enable_l; + _mm_setcsr(dwData); // load MXCSR with dwData +} + +#endif diff --git a/sys/osx/Doom 3.rsrc b/sys/osx/Doom 3.rsrc new file mode 100644 index 000000000..14327b9d7 Binary files /dev/null and b/sys/osx/Doom 3.rsrc differ diff --git a/sys/osx/Doom3.icns b/sys/osx/Doom3.icns new file mode 100644 index 000000000..28f5295e9 Binary files /dev/null and b/sys/osx/Doom3.icns differ diff --git a/sys/osx/Doom3.xcodeproj/project.pbxproj b/sys/osx/Doom3.xcodeproj/project.pbxproj new file mode 100644 index 000000000..b90e3f1a1 --- /dev/null +++ b/sys/osx/Doom3.xcodeproj/project.pbxproj @@ -0,0 +1,1911 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3A176D3314936ACC0077AB23 /* libdevil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A176D3214936ACC0077AB23 /* libdevil.a */; }; + 812258110912BC79005D34B9 /* snd_efxfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122565F0912BC78005D34B9 /* snd_efxfile.cpp */; }; + 812258120912BC79005D34B9 /* GEWindowWrapper_stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256620912BC78005D34B9 /* GEWindowWrapper_stub.cpp */; }; + 812258130912BC79005D34B9 /* edit_stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256630912BC79005D34B9 /* edit_stub.cpp */; }; + 812258140912BC79005D34B9 /* renderbump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256660912BC79005D34B9 /* renderbump.cpp */; }; + 812258150912BC79005D34B9 /* codec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256680912BC79005D34B9 /* codec.cpp */; }; + 812258160912BC79005D34B9 /* NSBitmapImageRep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122566B0912BC79005D34B9 /* NSBitmapImageRep.cpp */; }; + 812258170912BC79005D34B9 /* roq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122566D0912BC79005D34B9 /* roq.cpp */; }; + 812258180912BC79005D34B9 /* roqParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122566F0912BC79005D34B9 /* roqParam.cpp */; }; + 812258190912BC79005D34B9 /* AASBuild_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256720912BC79005D34B9 /* AASBuild_file.cpp */; }; + 8122581A0912BC79005D34B9 /* AASBuild_gravity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256730912BC79005D34B9 /* AASBuild_gravity.cpp */; }; + 8122581B0912BC79005D34B9 /* AASBuild_ledge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256740912BC79005D34B9 /* AASBuild_ledge.cpp */; }; + 8122581C0912BC79005D34B9 /* AASBuild_merge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256760912BC79005D34B9 /* AASBuild_merge.cpp */; }; + 8122581D0912BC79005D34B9 /* AASBuild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256770912BC79005D34B9 /* AASBuild.cpp */; }; + 8122581E0912BC79005D34B9 /* AASCluster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256780912BC79005D34B9 /* AASCluster.cpp */; }; + 8122581F0912BC79005D34B9 /* AASFile_optimize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122567B0912BC79005D34B9 /* AASFile_optimize.cpp */; }; + 812258200912BC79005D34B9 /* AASFile_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122567C0912BC79005D34B9 /* AASFile_sample.cpp */; }; + 812258210912BC79005D34B9 /* AASFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122567D0912BC79005D34B9 /* AASFile.cpp */; }; + 812258220912BC79005D34B9 /* AASFileManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122567F0912BC79005D34B9 /* AASFileManager.cpp */; }; + 812258230912BC79005D34B9 /* AASReach.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256810912BC79005D34B9 /* AASReach.cpp */; }; + 812258240912BC79005D34B9 /* Brush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256830912BC79005D34B9 /* Brush.cpp */; }; + 812258250912BC79005D34B9 /* BrushBSP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256850912BC79005D34B9 /* BrushBSP.cpp */; }; + 812258260912BC79005D34B9 /* dmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256880912BC79005D34B9 /* dmap.cpp */; }; + 812258270912BC79005D34B9 /* facebsp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568A0912BC79005D34B9 /* facebsp.cpp */; }; + 812258280912BC79005D34B9 /* gldraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568B0912BC79005D34B9 /* gldraw.cpp */; }; + 812258290912BC79005D34B9 /* glfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568C0912BC79005D34B9 /* glfile.cpp */; }; + 8122582A0912BC79005D34B9 /* leakfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568D0912BC79005D34B9 /* leakfile.cpp */; }; + 8122582B0912BC79005D34B9 /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568E0912BC79005D34B9 /* map.cpp */; }; + 8122582C0912BC79005D34B9 /* optimize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122568F0912BC79005D34B9 /* optimize.cpp */; }; + 8122582D0912BC79005D34B9 /* output.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256900912BC79005D34B9 /* output.cpp */; }; + 8122582E0912BC79005D34B9 /* portals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256910912BC79005D34B9 /* portals.cpp */; }; + 8122582F0912BC79005D34B9 /* shadowopt3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256920912BC79005D34B9 /* shadowopt3.cpp */; }; + 812258300912BC79005D34B9 /* tritjunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256930912BC79005D34B9 /* tritjunction.cpp */; }; + 812258310912BC79005D34B9 /* tritools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256940912BC79005D34B9 /* tritools.cpp */; }; + 812258320912BC79005D34B9 /* ubrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256950912BC79005D34B9 /* ubrush.cpp */; }; + 812258330912BC79005D34B9 /* usurface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256960912BC79005D34B9 /* usurface.cpp */; }; + 812258340912BC79005D34B9 /* stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256990912BC79005D34B9 /* stack.cpp */; }; + 812258350912BC79005D34B9 /* util_stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122569B0912BC79005D34B9 /* util_stub.cpp */; }; + 812258360912BC79005D34B9 /* macosx_guids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122569D0912BC79005D34B9 /* macosx_guids.cpp */; }; + 812258380912BC79005D34B9 /* macosx_misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 812256A00912BC79005D34B9 /* macosx_misc.mm */; }; + 812258390912BC79005D34B9 /* PickMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256A10912BC79005D34B9 /* PickMonitor.cpp */; }; + 8122583A0912BC79005D34B9 /* PreferencesDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256A20912BC79005D34B9 /* PreferencesDialog.cpp */; }; + 8122583B0912BC79005D34B9 /* macosx_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256A50912BC79005D34B9 /* macosx_sound.cpp */; }; + 8122583C0912BC79005D34B9 /* macosx_event.mm in Sources */ = {isa = PBXBuildFile; fileRef = 812256A60912BC79005D34B9 /* macosx_event.mm */; }; + 8122583D0912BC79005D34B9 /* macosx_glimp.mm in Sources */ = {isa = PBXBuildFile; fileRef = 812256A80912BC79005D34B9 /* macosx_glimp.mm */; }; + 8122583E0912BC79005D34B9 /* DOOMController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 812256AB0912BC79005D34B9 /* DOOMController.mm */; }; + 8122583F0912BC79005D34B9 /* posix_threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256AD0912BC79005D34B9 /* posix_threads.cpp */; }; + 812258400912BC79005D34B9 /* posix_input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256AE0912BC79005D34B9 /* posix_input.cpp */; }; + 812258410912BC79005D34B9 /* posix_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256AF0912BC79005D34B9 /* posix_main.cpp */; }; + 812258420912BC79005D34B9 /* posix_net.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256B00912BC79005D34B9 /* posix_net.cpp */; }; + 812258430912BC79005D34B9 /* posix_signal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256B20912BC79005D34B9 /* posix_signal.cpp */; }; + 812258440912BC79005D34B9 /* sys_local.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256B30912BC79005D34B9 /* sys_local.cpp */; }; + 812258620912BC79005D34B9 /* snd_cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256FD0912BC79005D34B9 /* snd_cache.cpp */; }; + 812258630912BC79005D34B9 /* snd_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256FE0912BC79005D34B9 /* snd_decoder.cpp */; }; + 812258640912BC79005D34B9 /* snd_emitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812256FF0912BC79005D34B9 /* snd_emitter.cpp */; }; + 812258650912BC79005D34B9 /* snd_shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257010912BC79005D34B9 /* snd_shader.cpp */; }; + 812258660912BC79005D34B9 /* snd_system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257020912BC79005D34B9 /* snd_system.cpp */; }; + 812258670912BC79005D34B9 /* snd_wavefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257030912BC79005D34B9 /* snd_wavefile.cpp */; }; + 812258680912BC79005D34B9 /* snd_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257040912BC79005D34B9 /* snd_world.cpp */; }; + 812258690912BC79005D34B9 /* Model_ma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257070912BC79005D34B9 /* Model_ma.cpp */; }; + 8122586A0912BC79005D34B9 /* Model_sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257080912BC79005D34B9 /* Model_sprite.cpp */; }; + 8122586B0912BC79005D34B9 /* cg_explicit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257090912BC79005D34B9 /* cg_explicit.cpp */; }; + 8122586C0912BC79005D34B9 /* Cinematic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122570B0912BC79005D34B9 /* Cinematic.cpp */; }; + 8122586D0912BC79005D34B9 /* draw_arb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122570D0912BC79005D34B9 /* draw_arb.cpp */; }; + 8122586E0912BC79005D34B9 /* draw_arb2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122570E0912BC79005D34B9 /* draw_arb2.cpp */; }; + 8122586F0912BC79005D34B9 /* draw_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122570F0912BC79005D34B9 /* draw_common.cpp */; }; + 812258710912BC79005D34B9 /* draw_exp_stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257110912BC79005D34B9 /* draw_exp_stub.cpp */; }; + 812258720912BC79005D34B9 /* draw_nv10.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257120912BC79005D34B9 /* draw_nv10.cpp */; }; + 812258730912BC79005D34B9 /* draw_nv20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257130912BC79005D34B9 /* draw_nv20.cpp */; }; + 812258740912BC79005D34B9 /* draw_r200.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257140912BC79005D34B9 /* draw_r200.cpp */; }; + 812258750912BC79005D34B9 /* GuiModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257160912BC79005D34B9 /* GuiModel.cpp */; }; + 812258760912BC79005D34B9 /* Image_files.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257190912BC79005D34B9 /* Image_files.cpp */; }; + 812258770912BC79005D34B9 /* Image_init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122571A0912BC79005D34B9 /* Image_init.cpp */; }; + 812258780912BC79005D34B9 /* Image_load.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122571B0912BC79005D34B9 /* Image_load.cpp */; }; + 812258790912BC79005D34B9 /* Image_process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122571C0912BC79005D34B9 /* Image_process.cpp */; }; + 8122587A0912BC79005D34B9 /* Image_program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122571D0912BC79005D34B9 /* Image_program.cpp */; }; + 8122587B0912BC79005D34B9 /* Interaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122571E0912BC79005D34B9 /* Interaction.cpp */; }; + 8122587C0912BC79005D34B9 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257210912BC79005D34B9 /* jcapimin.c */; }; + 8122587D0912BC79005D34B9 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257220912BC79005D34B9 /* jcapistd.c */; }; + 8122587E0912BC79005D34B9 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257230912BC79005D34B9 /* jccoefct.c */; }; + 8122587F0912BC79005D34B9 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257240912BC79005D34B9 /* jccolor.c */; }; + 812258800912BC79005D34B9 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257250912BC79005D34B9 /* jcdctmgr.c */; }; + 812258810912BC79005D34B9 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257260912BC79005D34B9 /* jchuff.c */; }; + 812258820912BC79005D34B9 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257280912BC79005D34B9 /* jcinit.c */; }; + 812258830912BC79005D34B9 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257290912BC79005D34B9 /* jcmainct.c */; }; + 812258840912BC79005D34B9 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122572A0912BC79005D34B9 /* jcmarker.c */; }; + 812258850912BC79005D34B9 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122572B0912BC79005D34B9 /* jcmaster.c */; }; + 812258860912BC79005D34B9 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122572C0912BC79005D34B9 /* jcomapi.c */; }; + 812258870912BC79005D34B9 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122572E0912BC79005D34B9 /* jcparam.c */; }; + 812258880912BC79005D34B9 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122572F0912BC79005D34B9 /* jcphuff.c */; }; + 812258890912BC79005D34B9 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257300912BC79005D34B9 /* jcprepct.c */; }; + 8122588A0912BC79005D34B9 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257310912BC79005D34B9 /* jcsample.c */; }; + 8122588B0912BC79005D34B9 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257320912BC79005D34B9 /* jctrans.c */; }; + 8122588C0912BC79005D34B9 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257330912BC79005D34B9 /* jdapimin.c */; }; + 8122588D0912BC79005D34B9 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257340912BC79005D34B9 /* jdapistd.c */; }; + 8122588E0912BC79005D34B9 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257350912BC79005D34B9 /* jdatadst.c */; }; + 8122588F0912BC79005D34B9 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257360912BC79005D34B9 /* jdatasrc.c */; }; + 812258900912BC79005D34B9 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257370912BC79005D34B9 /* jdcoefct.c */; }; + 812258910912BC79005D34B9 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257380912BC79005D34B9 /* jdcolor.c */; }; + 812258920912BC79005D34B9 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122573A0912BC79005D34B9 /* jddctmgr.c */; }; + 812258930912BC79005D34B9 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122573B0912BC79005D34B9 /* jdhuff.c */; }; + 812258940912BC79005D34B9 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122573D0912BC79005D34B9 /* jdinput.c */; }; + 812258950912BC79005D34B9 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122573E0912BC79005D34B9 /* jdmainct.c */; }; + 812258960912BC79005D34B9 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122573F0912BC79005D34B9 /* jdmarker.c */; }; + 812258970912BC79005D34B9 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257400912BC79005D34B9 /* jdmaster.c */; }; + 812258980912BC79005D34B9 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257410912BC79005D34B9 /* jdmerge.c */; }; + 812258990912BC79005D34B9 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257420912BC79005D34B9 /* jdphuff.c */; }; + 8122589A0912BC79005D34B9 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257430912BC79005D34B9 /* jdpostct.c */; }; + 8122589B0912BC79005D34B9 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257440912BC79005D34B9 /* jdsample.c */; }; + 8122589C0912BC79005D34B9 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257450912BC79005D34B9 /* jdtrans.c */; }; + 8122589D0912BC79005D34B9 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257460912BC79005D34B9 /* jerror.c */; }; + 8122589E0912BC79005D34B9 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257480912BC79005D34B9 /* jfdctflt.c */; }; + 8122589F0912BC79005D34B9 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257490912BC79005D34B9 /* jfdctfst.c */; }; + 812258A00912BC79005D34B9 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122574A0912BC79005D34B9 /* jfdctint.c */; }; + 812258A10912BC79005D34B9 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122574B0912BC79005D34B9 /* jidctflt.c */; }; + 812258A20912BC79005D34B9 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122574C0912BC79005D34B9 /* jidctfst.c */; }; + 812258A30912BC79005D34B9 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122574D0912BC79005D34B9 /* jidctint.c */; }; + 812258A40912BC79005D34B9 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122574E0912BC79005D34B9 /* jidctred.c */; }; + 812258A80912BC79005D34B9 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257530912BC79005D34B9 /* jmemmgr.c */; }; + 812258AA0912BC79005D34B9 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 812257550912BC79005D34B9 /* jmemnobs.c */; }; + 812258AC0912BC79005D34B9 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122575B0912BC79005D34B9 /* jquant1.c */; }; + 812258AD0912BC79005D34B9 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122575C0912BC79005D34B9 /* jquant2.c */; }; + 812258AE0912BC79005D34B9 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8122575D0912BC79005D34B9 /* jutils.c */; }; + 812258AF0912BC79005D34B9 /* Material.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122575F0912BC79005D34B9 /* Material.cpp */; }; + 812258B00912BC79005D34B9 /* MegaTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257610912BC79005D34B9 /* MegaTexture.cpp */; }; + 812258B10912BC79005D34B9 /* Model.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257630912BC79005D34B9 /* Model.cpp */; }; + 812258B20912BC79005D34B9 /* Model_ase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257650912BC79005D34B9 /* Model_ase.cpp */; }; + 812258B30912BC79005D34B9 /* Model_beam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257670912BC79005D34B9 /* Model_beam.cpp */; }; + 812258B40912BC79005D34B9 /* Model_liquid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257680912BC79005D34B9 /* Model_liquid.cpp */; }; + 812258B50912BC79005D34B9 /* Model_lwo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122576A0912BC79005D34B9 /* Model_lwo.cpp */; }; + 812258B60912BC79005D34B9 /* Model_md3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122576C0912BC79005D34B9 /* Model_md3.cpp */; }; + 812258B70912BC79005D34B9 /* Model_md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122576E0912BC79005D34B9 /* Model_md5.cpp */; }; + 812258B80912BC79005D34B9 /* Model_prt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122576F0912BC79005D34B9 /* Model_prt.cpp */; }; + 812258B90912BC79005D34B9 /* ModelDecal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257700912BC79005D34B9 /* ModelDecal.cpp */; }; + 812258BA0912BC79005D34B9 /* ModelManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257720912BC79005D34B9 /* ModelManager.cpp */; }; + 812258BB0912BC79005D34B9 /* ModelOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257740912BC79005D34B9 /* ModelOverlay.cpp */; }; + 812258BC0912BC79005D34B9 /* RenderEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257780912BC79005D34B9 /* RenderEntity.cpp */; }; + 812258BD0912BC79005D34B9 /* RenderSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257790912BC79005D34B9 /* RenderSystem.cpp */; }; + 812258BE0912BC79005D34B9 /* RenderSystem_init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122577B0912BC79005D34B9 /* RenderSystem_init.cpp */; }; + 812258BF0912BC79005D34B9 /* RenderWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122577C0912BC79005D34B9 /* RenderWorld.cpp */; }; + 812258C00912BC79005D34B9 /* RenderWorld_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122577E0912BC79005D34B9 /* RenderWorld_demo.cpp */; }; + 812258C10912BC79005D34B9 /* RenderWorld_load.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122577F0912BC79005D34B9 /* RenderWorld_load.cpp */; }; + 812258C20912BC79005D34B9 /* RenderWorld_portals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257810912BC79005D34B9 /* RenderWorld_portals.cpp */; }; + 812258C30912BC79005D34B9 /* tr_backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257830912BC79005D34B9 /* tr_backend.cpp */; }; + 812258C40912BC79005D34B9 /* tr_deform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257840912BC79005D34B9 /* tr_deform.cpp */; }; + 812258C50912BC79005D34B9 /* tr_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257850912BC79005D34B9 /* tr_font.cpp */; }; + 812258C60912BC79005D34B9 /* tr_guisurf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257860912BC79005D34B9 /* tr_guisurf.cpp */; }; + 812258C70912BC79005D34B9 /* tr_light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257870912BC79005D34B9 /* tr_light.cpp */; }; + 812258C80912BC79005D34B9 /* tr_lightrun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257880912BC79005D34B9 /* tr_lightrun.cpp */; }; + 812258C90912BC79005D34B9 /* tr_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578A0912BC79005D34B9 /* tr_main.cpp */; }; + 812258CA0912BC79005D34B9 /* tr_orderIndexes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578B0912BC79005D34B9 /* tr_orderIndexes.cpp */; }; + 812258CB0912BC79005D34B9 /* tr_polytope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578C0912BC79005D34B9 /* tr_polytope.cpp */; }; + 812258CC0912BC79005D34B9 /* tr_render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578D0912BC79005D34B9 /* tr_render.cpp */; }; + 812258CD0912BC79005D34B9 /* tr_rendertools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578E0912BC79005D34B9 /* tr_rendertools.cpp */; }; + 812258CE0912BC79005D34B9 /* tr_shadowbounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122578F0912BC79005D34B9 /* tr_shadowbounds.cpp */; }; + 812258CF0912BC79005D34B9 /* tr_stencilshadow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257900912BC79005D34B9 /* tr_stencilshadow.cpp */; }; + 812258D00912BC79005D34B9 /* tr_subview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257910912BC79005D34B9 /* tr_subview.cpp */; }; + 812258D10912BC79005D34B9 /* tr_trace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257920912BC79005D34B9 /* tr_trace.cpp */; }; + 812258D20912BC79005D34B9 /* tr_trisurf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257930912BC79005D34B9 /* tr_trisurf.cpp */; }; + 812258D30912BC79005D34B9 /* tr_turboshadow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257940912BC79005D34B9 /* tr_turboshadow.cpp */; }; + 812258D40912BC79005D34B9 /* VertexCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257950912BC79005D34B9 /* VertexCache.cpp */; }; + 812258D50912BC79005D34B9 /* AsyncClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122579A0912BC79005D34B9 /* AsyncClient.cpp */; }; + 812258D60912BC79005D34B9 /* AsyncNetwork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122579C0912BC79005D34B9 /* AsyncNetwork.cpp */; }; + 812258D70912BC79005D34B9 /* AsyncServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122579E0912BC79005D34B9 /* AsyncServer.cpp */; }; + 812258D80912BC79005D34B9 /* MsgChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257A00912BC79005D34B9 /* MsgChannel.cpp */; }; + 812258D90912BC79005D34B9 /* NetworkSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257A20912BC79005D34B9 /* NetworkSystem.cpp */; }; + 812258DA0912BC79005D34B9 /* ServerScan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257A40912BC79005D34B9 /* ServerScan.cpp */; }; + 812258DB0912BC79005D34B9 /* CmdSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257A80912BC79005D34B9 /* CmdSystem.cpp */; }; + 812258DC0912BC79005D34B9 /* Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AA0912BC79005D34B9 /* Common.cpp */; }; + 812258DD0912BC79005D34B9 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AC0912BC79005D34B9 /* Compressor.cpp */; }; + 812258DE0912BC79005D34B9 /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AE0912BC79005D34B9 /* Console.cpp */; }; + 812258DF0912BC79005D34B9 /* CVarSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B00912BC79005D34B9 /* CVarSystem.cpp */; }; + 812258E00912BC79005D34B9 /* DeclAF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B20912BC79005D34B9 /* DeclAF.cpp */; }; + 812258E10912BC79005D34B9 /* DeclEntityDef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B40912BC79005D34B9 /* DeclEntityDef.cpp */; }; + 812258E20912BC79005D34B9 /* DeclFX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B60912BC79005D34B9 /* DeclFX.cpp */; }; + 812258E30912BC79005D34B9 /* DeclManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B80912BC79005D34B9 /* DeclManager.cpp */; }; + 812258E40912BC79005D34B9 /* DeclParticle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257BA0912BC79005D34B9 /* DeclParticle.cpp */; }; + 812258E50912BC79005D34B9 /* DeclPDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257BC0912BC79005D34B9 /* DeclPDA.cpp */; }; + 812258E60912BC79005D34B9 /* DeclSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257BE0912BC79005D34B9 /* DeclSkin.cpp */; }; + 812258E70912BC79005D34B9 /* DeclTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257C00912BC79005D34B9 /* DeclTable.cpp */; }; + 812258E80912BC79005D34B9 /* DemoFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257C20912BC79005D34B9 /* DemoFile.cpp */; }; + 812258E90912BC79005D34B9 /* EditField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257C40912BC79005D34B9 /* EditField.cpp */; }; + 812258EA0912BC79005D34B9 /* EventLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257C60912BC79005D34B9 /* EventLoop.cpp */; }; + 812258EB0912BC79005D34B9 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257C80912BC79005D34B9 /* File.cpp */; }; + 812258EC0912BC79005D34B9 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257CA0912BC79005D34B9 /* FileSystem.cpp */; }; + 812258ED0912BC79005D34B9 /* KeyInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257CC0912BC79005D34B9 /* KeyInput.cpp */; }; + 812258EE0912BC79005D34B9 /* Session.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257CF0912BC79005D34B9 /* Session.cpp */; }; + 812258EF0912BC79005D34B9 /* Session_menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257D20912BC79005D34B9 /* Session_menu.cpp */; }; + 812258F00912BC79005D34B9 /* Unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257D30912BC79005D34B9 /* Unzip.cpp */; }; + 812258F10912BC79005D34B9 /* UsercmdGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257D50912BC79005D34B9 /* UsercmdGen.cpp */; }; + 812258F20912BC79005D34B9 /* GameBearShootWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257D80912BC79005D34B9 /* GameBearShootWindow.cpp */; }; + 812258F30912BC79005D34B9 /* GameBustOutWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257DA0912BC79005D34B9 /* GameBustOutWindow.cpp */; }; + 812258F40912BC79005D34B9 /* GameSSDWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257DC0912BC79005D34B9 /* GameSSDWindow.cpp */; }; + 812258F50912BC79005D34B9 /* ListGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257DE0912BC79005D34B9 /* ListGUI.cpp */; }; + 812258F60912BC79005D34B9 /* BindWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257E10912BC79005D34B9 /* BindWindow.cpp */; }; + 812258F70912BC79005D34B9 /* ChoiceWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257E30912BC79005D34B9 /* ChoiceWindow.cpp */; }; + 812258F80912BC79005D34B9 /* DeviceContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257E50912BC79005D34B9 /* DeviceContext.cpp */; }; + 812258F90912BC79005D34B9 /* EditWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257E70912BC79005D34B9 /* EditWindow.cpp */; }; + 812258FA0912BC79005D34B9 /* FieldWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257E90912BC79005D34B9 /* FieldWindow.cpp */; }; + 812258FB0912BC79005D34B9 /* GuiScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257EB0912BC79005D34B9 /* GuiScript.cpp */; }; + 812258FC0912BC79005D34B9 /* ListWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257ED0912BC79005D34B9 /* ListWindow.cpp */; }; + 812258FD0912BC79005D34B9 /* MarkerWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257EF0912BC79005D34B9 /* MarkerWindow.cpp */; }; + 812258FE0912BC79005D34B9 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257F20912BC79005D34B9 /* RegExp.cpp */; }; + 812258FF0912BC79005D34B9 /* RenderWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257F50912BC79005D34B9 /* RenderWindow.cpp */; }; + 812259000912BC79005D34B9 /* SimpleWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257F70912BC79005D34B9 /* SimpleWindow.cpp */; }; + 812259010912BC79005D34B9 /* SliderWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257F90912BC79005D34B9 /* SliderWindow.cpp */; }; + 812259020912BC79005D34B9 /* UserInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257FB0912BC79005D34B9 /* UserInterface.cpp */; }; + 812259030912BC79005D34B9 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257FE0912BC79005D34B9 /* Window.cpp */; }; + 812259040912BC79005D34B9 /* Winvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258000912BC79005D34B9 /* Winvar.cpp */; }; + 812259050912BC79005D34B9 /* CollisionModel_contacts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258040912BC79005D34B9 /* CollisionModel_contacts.cpp */; }; + 812259060912BC79005D34B9 /* CollisionModel_contents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258050912BC79005D34B9 /* CollisionModel_contents.cpp */; }; + 812259070912BC79005D34B9 /* CollisionModel_debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258060912BC79005D34B9 /* CollisionModel_debug.cpp */; }; + 812259080912BC79005D34B9 /* CollisionModel_files.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258070912BC79005D34B9 /* CollisionModel_files.cpp */; }; + 812259090912BC79005D34B9 /* CollisionModel_load.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812258080912BC79005D34B9 /* CollisionModel_load.cpp */; }; + 8122590A0912BC79005D34B9 /* CollisionModel_rotate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122580A0912BC79005D34B9 /* CollisionModel_rotate.cpp */; }; + 8122590B0912BC79005D34B9 /* CollisionModel_trace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122580B0912BC79005D34B9 /* CollisionModel_trace.cpp */; }; + 8122590C0912BC79005D34B9 /* CollisionModel_translate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8122580C0912BC79005D34B9 /* CollisionModel_translate.cpp */; }; + 812259930912BF7F005D34B9 /* libidlib_nopic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 812259820912BF1D005D34B9 /* libidlib_nopic.a */; }; + 812259940912BF87005D34B9 /* liboggVorbis_nopic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8122598F0912BF38005D34B9 /* liboggVorbis_nopic.a */; }; + 812259B00912BFDC005D34B9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812259A30912BFDC005D34B9 /* Carbon.framework */; }; + 812259B10912BFDC005D34B9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812259A40912BFDC005D34B9 /* IOKit.framework */; }; + 812259B30912BFDC005D34B9 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812259A60912BFDC005D34B9 /* OpenGL.framework */; }; + 812259B70912C056005D34B9 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812259B40912C056005D34B9 /* CoreAudio.framework */; }; + 812259FF0912C27D005D34B9 /* Doom 3.rsrc in Resources */ = {isa = PBXBuildFile; fileRef = 812259FD0912C27C005D34B9 /* Doom 3.rsrc */; }; + 81225A000912C27D005D34B9 /* Doom3.icns in Resources */ = {isa = PBXBuildFile; fileRef = 812259FE0912C27C005D34B9 /* Doom3.icns */; }; + 81225A0D0912C2D3005D34B9 /* ASLCore.nib in Resources */ = {isa = PBXBuildFile; fileRef = 81225A0B0912C2D3005D34B9 /* ASLCore.nib */; }; + 81225A100912C2E9005D34B9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 81225A0E0912C2E9005D34B9 /* Localizable.strings */; }; + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3A1768DA149354D60077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A1768D3149354D60077AB23 /* devil.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A17681B149350DE0077AB23 /* liblibdevil.a.a */; + remoteInfo = devil; + }; + 3A176967149355C20077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A1768D3149354D60077AB23 /* devil.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A17681A149350DE0077AB23 /* devil */; + remoteInfo = devil; + }; + 8122597F0912BF1D005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 812259790912BF1D005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = idlib_pic; + }; + 812259810912BF1D005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 812259790912BF1D005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 81C858490912AD370095BC33; + remoteInfo = idlib_nopic; + }; + 812259830912BF2B005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 812259790912BF1D005D34B9 /* idlib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 81C858480912AD370095BC33; + remoteInfo = idlib_nopic; + }; + 8122598E0912BF38005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 812259890912BF38005D34B9 /* oggVorbis.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = oggVorbis_nopic; + }; + 812259900912BF43005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 812259890912BF38005D34B9 /* oggVorbis.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC045055464E500DB518D; + remoteInfo = oggVorbis_nopic; + }; + 81225B8A0912C731005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225B840912C731005D34B9 /* game.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC0630554660B00DB518D; + remoteInfo = game; + }; + 81225B8C0912C73C005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225B840912C731005D34B9 /* game.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC0620554660B00DB518D; + remoteInfo = game; + }; + 81326DC6099C162D003C4788 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81326DC1099C162D003C4788 /* curl.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = curl; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 3A1768D3149354D60077AB23 /* devil.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = devil.xcodeproj; sourceTree = ""; }; + 3A176D3214936ACC0077AB23 /* libdevil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdevil.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libdevil.a; sourceTree = ""; }; + 3A176DDB1494CAA00077AB23 /* libidlib_pic.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libidlib_pic.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libidlib_pic.a; sourceTree = ""; }; + 8122565F0912BC78005D34B9 /* snd_efxfile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = snd_efxfile.cpp; path = ../../sound/snd_efxfile.cpp; sourceTree = SOURCE_ROOT; }; + 812256620912BC78005D34B9 /* GEWindowWrapper_stub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = GEWindowWrapper_stub.cpp; path = ../../tools/guied/GEWindowWrapper_stub.cpp; sourceTree = SOURCE_ROOT; }; + 812256630912BC79005D34B9 /* edit_stub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = edit_stub.cpp; path = ../../tools/edit_stub.cpp; sourceTree = SOURCE_ROOT; }; + 812256660912BC79005D34B9 /* renderbump.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = renderbump.cpp; path = ../../tools/compilers/renderbump/renderbump.cpp; sourceTree = SOURCE_ROOT; }; + 812256680912BC79005D34B9 /* codec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = codec.cpp; path = ../../tools/compilers/roqvq/codec.cpp; sourceTree = SOURCE_ROOT; }; + 812256690912BC79005D34B9 /* codec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = codec.h; path = ../../tools/compilers/roqvq/codec.h; sourceTree = SOURCE_ROOT; }; + 8122566A0912BC79005D34B9 /* gdefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gdefs.h; path = ../../tools/compilers/roqvq/gdefs.h; sourceTree = SOURCE_ROOT; }; + 8122566B0912BC79005D34B9 /* NSBitmapImageRep.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NSBitmapImageRep.cpp; path = ../../tools/compilers/roqvq/NSBitmapImageRep.cpp; sourceTree = SOURCE_ROOT; }; + 8122566C0912BC79005D34B9 /* quaddefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = quaddefs.h; path = ../../tools/compilers/roqvq/quaddefs.h; sourceTree = SOURCE_ROOT; }; + 8122566D0912BC79005D34B9 /* roq.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = roq.cpp; path = ../../tools/compilers/roqvq/roq.cpp; sourceTree = SOURCE_ROOT; }; + 8122566E0912BC79005D34B9 /* roq.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = roq.h; path = ../../tools/compilers/roqvq/roq.h; sourceTree = SOURCE_ROOT; }; + 8122566F0912BC79005D34B9 /* roqParam.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = roqParam.cpp; path = ../../tools/compilers/roqvq/roqParam.cpp; sourceTree = SOURCE_ROOT; }; + 812256700912BC79005D34B9 /* roqParam.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = roqParam.h; path = ../../tools/compilers/roqvq/roqParam.h; sourceTree = SOURCE_ROOT; }; + 812256720912BC79005D34B9 /* AASBuild_file.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASBuild_file.cpp; path = ../../tools/compilers/aas/AASBuild_file.cpp; sourceTree = SOURCE_ROOT; }; + 812256730912BC79005D34B9 /* AASBuild_gravity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASBuild_gravity.cpp; path = ../../tools/compilers/aas/AASBuild_gravity.cpp; sourceTree = SOURCE_ROOT; }; + 812256740912BC79005D34B9 /* AASBuild_ledge.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASBuild_ledge.cpp; path = ../../tools/compilers/aas/AASBuild_ledge.cpp; sourceTree = SOURCE_ROOT; }; + 812256750912BC79005D34B9 /* AASBuild_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASBuild_local.h; path = ../../tools/compilers/aas/AASBuild_local.h; sourceTree = SOURCE_ROOT; }; + 812256760912BC79005D34B9 /* AASBuild_merge.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASBuild_merge.cpp; path = ../../tools/compilers/aas/AASBuild_merge.cpp; sourceTree = SOURCE_ROOT; }; + 812256770912BC79005D34B9 /* AASBuild.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASBuild.cpp; path = ../../tools/compilers/aas/AASBuild.cpp; sourceTree = SOURCE_ROOT; }; + 812256780912BC79005D34B9 /* AASCluster.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASCluster.cpp; path = ../../tools/compilers/aas/AASCluster.cpp; sourceTree = SOURCE_ROOT; }; + 812256790912BC79005D34B9 /* AASCluster.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASCluster.h; path = ../../tools/compilers/aas/AASCluster.h; sourceTree = SOURCE_ROOT; }; + 8122567A0912BC79005D34B9 /* AASFile_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASFile_local.h; path = ../../tools/compilers/aas/AASFile_local.h; sourceTree = SOURCE_ROOT; }; + 8122567B0912BC79005D34B9 /* AASFile_optimize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASFile_optimize.cpp; path = ../../tools/compilers/aas/AASFile_optimize.cpp; sourceTree = SOURCE_ROOT; }; + 8122567C0912BC79005D34B9 /* AASFile_sample.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASFile_sample.cpp; path = ../../tools/compilers/aas/AASFile_sample.cpp; sourceTree = SOURCE_ROOT; }; + 8122567D0912BC79005D34B9 /* AASFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASFile.cpp; path = ../../tools/compilers/aas/AASFile.cpp; sourceTree = SOURCE_ROOT; }; + 8122567E0912BC79005D34B9 /* AASFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASFile.h; path = ../../tools/compilers/aas/AASFile.h; sourceTree = SOURCE_ROOT; }; + 8122567F0912BC79005D34B9 /* AASFileManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASFileManager.cpp; path = ../../tools/compilers/aas/AASFileManager.cpp; sourceTree = SOURCE_ROOT; }; + 812256800912BC79005D34B9 /* AASFileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASFileManager.h; path = ../../tools/compilers/aas/AASFileManager.h; sourceTree = SOURCE_ROOT; }; + 812256810912BC79005D34B9 /* AASReach.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AASReach.cpp; path = ../../tools/compilers/aas/AASReach.cpp; sourceTree = SOURCE_ROOT; }; + 812256820912BC79005D34B9 /* AASReach.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AASReach.h; path = ../../tools/compilers/aas/AASReach.h; sourceTree = SOURCE_ROOT; }; + 812256830912BC79005D34B9 /* Brush.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Brush.cpp; path = ../../tools/compilers/aas/Brush.cpp; sourceTree = SOURCE_ROOT; }; + 812256840912BC79005D34B9 /* Brush.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Brush.h; path = ../../tools/compilers/aas/Brush.h; sourceTree = SOURCE_ROOT; }; + 812256850912BC79005D34B9 /* BrushBSP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BrushBSP.cpp; path = ../../tools/compilers/aas/BrushBSP.cpp; sourceTree = SOURCE_ROOT; }; + 812256860912BC79005D34B9 /* BrushBSP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = BrushBSP.h; path = ../../tools/compilers/aas/BrushBSP.h; sourceTree = SOURCE_ROOT; }; + 812256880912BC79005D34B9 /* dmap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = dmap.cpp; path = ../../tools/compilers/dmap/dmap.cpp; sourceTree = SOURCE_ROOT; }; + 812256890912BC79005D34B9 /* dmap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dmap.h; path = ../../tools/compilers/dmap/dmap.h; sourceTree = SOURCE_ROOT; }; + 8122568A0912BC79005D34B9 /* facebsp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = facebsp.cpp; path = ../../tools/compilers/dmap/facebsp.cpp; sourceTree = SOURCE_ROOT; }; + 8122568B0912BC79005D34B9 /* gldraw.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gldraw.cpp; path = ../../tools/compilers/dmap/gldraw.cpp; sourceTree = SOURCE_ROOT; }; + 8122568C0912BC79005D34B9 /* glfile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = glfile.cpp; path = ../../tools/compilers/dmap/glfile.cpp; sourceTree = SOURCE_ROOT; }; + 8122568D0912BC79005D34B9 /* leakfile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = leakfile.cpp; path = ../../tools/compilers/dmap/leakfile.cpp; sourceTree = SOURCE_ROOT; }; + 8122568E0912BC79005D34B9 /* map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = map.cpp; path = ../../tools/compilers/dmap/map.cpp; sourceTree = SOURCE_ROOT; }; + 8122568F0912BC79005D34B9 /* optimize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = optimize.cpp; path = ../../tools/compilers/dmap/optimize.cpp; sourceTree = SOURCE_ROOT; }; + 812256900912BC79005D34B9 /* output.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = output.cpp; path = ../../tools/compilers/dmap/output.cpp; sourceTree = SOURCE_ROOT; }; + 812256910912BC79005D34B9 /* portals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = portals.cpp; path = ../../tools/compilers/dmap/portals.cpp; sourceTree = SOURCE_ROOT; }; + 812256920912BC79005D34B9 /* shadowopt3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = shadowopt3.cpp; path = ../../tools/compilers/dmap/shadowopt3.cpp; sourceTree = SOURCE_ROOT; }; + 812256930912BC79005D34B9 /* tritjunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = tritjunction.cpp; path = ../../tools/compilers/dmap/tritjunction.cpp; sourceTree = SOURCE_ROOT; }; + 812256940912BC79005D34B9 /* tritools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = tritools.cpp; path = ../../tools/compilers/dmap/tritools.cpp; sourceTree = SOURCE_ROOT; }; + 812256950912BC79005D34B9 /* ubrush.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ubrush.cpp; path = ../../tools/compilers/dmap/ubrush.cpp; sourceTree = SOURCE_ROOT; }; + 812256960912BC79005D34B9 /* usurface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = usurface.cpp; path = ../../tools/compilers/dmap/usurface.cpp; sourceTree = SOURCE_ROOT; }; + 812256990912BC79005D34B9 /* stack.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stack.cpp; path = ../linux/stack.cpp; sourceTree = SOURCE_ROOT; }; + 8122569B0912BC79005D34B9 /* util_stub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = util_stub.cpp; path = ../stub/util_stub.cpp; sourceTree = SOURCE_ROOT; }; + 8122569D0912BC79005D34B9 /* macosx_guids.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = macosx_guids.cpp; sourceTree = ""; }; + 812256A00912BC79005D34B9 /* macosx_misc.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = macosx_misc.mm; sourceTree = ""; }; + 812256A10912BC79005D34B9 /* PickMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PickMonitor.cpp; sourceTree = ""; }; + 812256A20912BC79005D34B9 /* PreferencesDialog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PreferencesDialog.cpp; sourceTree = ""; }; + 812256A30912BC79005D34B9 /* PickMonitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PickMonitor.h; sourceTree = ""; }; + 812256A40912BC79005D34B9 /* PreferencesDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PreferencesDialog.h; sourceTree = ""; }; + 812256A50912BC79005D34B9 /* macosx_sound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = macosx_sound.cpp; sourceTree = ""; }; + 812256A60912BC79005D34B9 /* macosx_event.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = macosx_event.mm; sourceTree = ""; }; + 812256A70912BC79005D34B9 /* macosx_glimp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = macosx_glimp.h; sourceTree = ""; }; + 812256A80912BC79005D34B9 /* macosx_glimp.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = macosx_glimp.mm; sourceTree = ""; }; + 812256A90912BC79005D34B9 /* macosx_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = macosx_local.h; sourceTree = ""; }; + 812256AA0912BC79005D34B9 /* DOOMController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOOMController.h; sourceTree = ""; }; + 812256AB0912BC79005D34B9 /* DOOMController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOOMController.mm; sourceTree = ""; }; + 812256AD0912BC79005D34B9 /* posix_threads.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = posix_threads.cpp; path = ../posix/posix_threads.cpp; sourceTree = SOURCE_ROOT; }; + 812256AE0912BC79005D34B9 /* posix_input.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = posix_input.cpp; path = ../posix/posix_input.cpp; sourceTree = SOURCE_ROOT; }; + 812256AF0912BC79005D34B9 /* posix_main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = posix_main.cpp; path = ../posix/posix_main.cpp; sourceTree = SOURCE_ROOT; }; + 812256B00912BC79005D34B9 /* posix_net.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = posix_net.cpp; path = ../posix/posix_net.cpp; sourceTree = SOURCE_ROOT; }; + 812256B10912BC79005D34B9 /* posix_public.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = posix_public.h; path = ../posix/posix_public.h; sourceTree = SOURCE_ROOT; }; + 812256B20912BC79005D34B9 /* posix_signal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = posix_signal.cpp; path = ../posix/posix_signal.cpp; sourceTree = SOURCE_ROOT; }; + 812256B30912BC79005D34B9 /* sys_local.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sys_local.cpp; path = ../sys_local.cpp; sourceTree = SOURCE_ROOT; }; + 812256FD0912BC79005D34B9 /* snd_cache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_cache.cpp; sourceTree = ""; }; + 812256FE0912BC79005D34B9 /* snd_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_decoder.cpp; sourceTree = ""; }; + 812256FF0912BC79005D34B9 /* snd_emitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_emitter.cpp; sourceTree = ""; }; + 812257000912BC79005D34B9 /* snd_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = snd_local.h; sourceTree = ""; }; + 812257010912BC79005D34B9 /* snd_shader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_shader.cpp; sourceTree = ""; }; + 812257020912BC79005D34B9 /* snd_system.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_system.cpp; sourceTree = ""; }; + 812257030912BC79005D34B9 /* snd_wavefile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_wavefile.cpp; sourceTree = ""; }; + 812257040912BC79005D34B9 /* snd_world.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = snd_world.cpp; sourceTree = ""; }; + 812257050912BC79005D34B9 /* sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = ""; }; + 812257070912BC79005D34B9 /* Model_ma.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_ma.cpp; sourceTree = ""; }; + 812257080912BC79005D34B9 /* Model_sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_sprite.cpp; sourceTree = ""; }; + 812257090912BC79005D34B9 /* cg_explicit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cg_explicit.cpp; sourceTree = ""; }; + 8122570A0912BC79005D34B9 /* cg_explicit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cg_explicit.h; sourceTree = ""; }; + 8122570B0912BC79005D34B9 /* Cinematic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Cinematic.cpp; sourceTree = ""; }; + 8122570C0912BC79005D34B9 /* Cinematic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Cinematic.h; sourceTree = ""; }; + 8122570D0912BC79005D34B9 /* draw_arb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_arb.cpp; sourceTree = ""; }; + 8122570E0912BC79005D34B9 /* draw_arb2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_arb2.cpp; sourceTree = ""; }; + 8122570F0912BC79005D34B9 /* draw_common.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_common.cpp; sourceTree = ""; }; + 812257100912BC79005D34B9 /* draw_exp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_exp.cpp; sourceTree = ""; }; + 812257110912BC79005D34B9 /* draw_exp_stub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_exp_stub.cpp; sourceTree = ""; }; + 812257120912BC79005D34B9 /* draw_nv10.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_nv10.cpp; sourceTree = ""; }; + 812257130912BC79005D34B9 /* draw_nv20.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_nv20.cpp; sourceTree = ""; }; + 812257140912BC79005D34B9 /* draw_r200.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = draw_r200.cpp; sourceTree = ""; }; + 812257150912BC79005D34B9 /* glext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = glext.h; sourceTree = ""; }; + 812257160912BC79005D34B9 /* GuiModel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GuiModel.cpp; sourceTree = ""; }; + 812257170912BC79005D34B9 /* GuiModel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GuiModel.h; sourceTree = ""; }; + 812257180912BC79005D34B9 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; + 812257190912BC79005D34B9 /* Image_files.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image_files.cpp; sourceTree = ""; }; + 8122571A0912BC79005D34B9 /* Image_init.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image_init.cpp; sourceTree = ""; }; + 8122571B0912BC79005D34B9 /* Image_load.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image_load.cpp; sourceTree = ""; }; + 8122571C0912BC79005D34B9 /* Image_process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image_process.cpp; sourceTree = ""; }; + 8122571D0912BC79005D34B9 /* Image_program.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image_program.cpp; sourceTree = ""; }; + 8122571E0912BC79005D34B9 /* Interaction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Interaction.cpp; sourceTree = ""; }; + 8122571F0912BC79005D34B9 /* Interaction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Interaction.h; sourceTree = ""; }; + 812257210912BC79005D34B9 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapimin.c; sourceTree = ""; }; + 812257220912BC79005D34B9 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapistd.c; sourceTree = ""; }; + 812257230912BC79005D34B9 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccoefct.c; sourceTree = ""; }; + 812257240912BC79005D34B9 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccolor.c; sourceTree = ""; }; + 812257250912BC79005D34B9 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcdctmgr.c; sourceTree = ""; }; + 812257260912BC79005D34B9 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jchuff.c; sourceTree = ""; }; + 812257270912BC79005D34B9 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jchuff.h; sourceTree = ""; }; + 812257280912BC79005D34B9 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcinit.c; sourceTree = ""; }; + 812257290912BC79005D34B9 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmainct.c; sourceTree = ""; }; + 8122572A0912BC79005D34B9 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmarker.c; sourceTree = ""; }; + 8122572B0912BC79005D34B9 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmaster.c; sourceTree = ""; }; + 8122572C0912BC79005D34B9 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcomapi.c; sourceTree = ""; }; + 8122572D0912BC79005D34B9 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jconfig.h; sourceTree = ""; }; + 8122572E0912BC79005D34B9 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcparam.c; sourceTree = ""; }; + 8122572F0912BC79005D34B9 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcphuff.c; sourceTree = ""; }; + 812257300912BC79005D34B9 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcprepct.c; sourceTree = ""; }; + 812257310912BC79005D34B9 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcsample.c; sourceTree = ""; }; + 812257320912BC79005D34B9 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jctrans.c; sourceTree = ""; }; + 812257330912BC79005D34B9 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapimin.c; sourceTree = ""; }; + 812257340912BC79005D34B9 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapistd.c; sourceTree = ""; }; + 812257350912BC79005D34B9 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatadst.c; sourceTree = ""; }; + 812257360912BC79005D34B9 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatasrc.c; sourceTree = ""; }; + 812257370912BC79005D34B9 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcoefct.c; sourceTree = ""; }; + 812257380912BC79005D34B9 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcolor.c; sourceTree = ""; }; + 812257390912BC79005D34B9 /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jdct.h; sourceTree = ""; }; + 8122573A0912BC79005D34B9 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jddctmgr.c; sourceTree = ""; }; + 8122573B0912BC79005D34B9 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdhuff.c; sourceTree = ""; }; + 8122573C0912BC79005D34B9 /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jdhuff.h; sourceTree = ""; }; + 8122573D0912BC79005D34B9 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdinput.c; sourceTree = ""; }; + 8122573E0912BC79005D34B9 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmainct.c; sourceTree = ""; }; + 8122573F0912BC79005D34B9 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmarker.c; sourceTree = ""; }; + 812257400912BC79005D34B9 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmaster.c; sourceTree = ""; }; + 812257410912BC79005D34B9 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmerge.c; sourceTree = ""; }; + 812257420912BC79005D34B9 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdphuff.c; sourceTree = ""; }; + 812257430912BC79005D34B9 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdpostct.c; sourceTree = ""; }; + 812257440912BC79005D34B9 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdsample.c; sourceTree = ""; }; + 812257450912BC79005D34B9 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdtrans.c; sourceTree = ""; }; + 812257460912BC79005D34B9 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jerror.c; sourceTree = ""; }; + 812257470912BC79005D34B9 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jerror.h; sourceTree = ""; }; + 812257480912BC79005D34B9 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctflt.c; sourceTree = ""; }; + 812257490912BC79005D34B9 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctfst.c; sourceTree = ""; }; + 8122574A0912BC79005D34B9 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctint.c; sourceTree = ""; }; + 8122574B0912BC79005D34B9 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctflt.c; sourceTree = ""; }; + 8122574C0912BC79005D34B9 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctfst.c; sourceTree = ""; }; + 8122574D0912BC79005D34B9 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctint.c; sourceTree = ""; }; + 8122574E0912BC79005D34B9 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctred.c; sourceTree = ""; }; + 8122574F0912BC79005D34B9 /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jinclude.h; sourceTree = ""; }; + 812257500912BC79005D34B9 /* jload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jload.c; sourceTree = ""; }; + 812257510912BC79005D34B9 /* jmemansi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemansi.c; sourceTree = ""; }; + 812257520912BC79005D34B9 /* jmemdos.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemdos.c; sourceTree = ""; }; + 812257530912BC79005D34B9 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemmgr.c; sourceTree = ""; }; + 812257540912BC79005D34B9 /* jmemname.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemname.c; sourceTree = ""; }; + 812257550912BC79005D34B9 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemnobs.c; sourceTree = ""; }; + 812257560912BC79005D34B9 /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jmemsys.h; sourceTree = ""; }; + 812257570912BC79005D34B9 /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jmorecfg.h; sourceTree = ""; }; + 812257580912BC79005D34B9 /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jpegint.h; sourceTree = ""; }; + 812257590912BC79005D34B9 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jpeglib.h; sourceTree = ""; }; + 8122575A0912BC79005D34B9 /* jpegtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jpegtran.c; sourceTree = ""; }; + 8122575B0912BC79005D34B9 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant1.c; sourceTree = ""; }; + 8122575C0912BC79005D34B9 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant2.c; sourceTree = ""; }; + 8122575D0912BC79005D34B9 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jutils.c; sourceTree = ""; }; + 8122575E0912BC79005D34B9 /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = jversion.h; sourceTree = ""; }; + 8122575F0912BC79005D34B9 /* Material.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Material.cpp; sourceTree = ""; }; + 812257600912BC79005D34B9 /* Material.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Material.h; sourceTree = ""; }; + 812257610912BC79005D34B9 /* MegaTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MegaTexture.cpp; sourceTree = ""; }; + 812257620912BC79005D34B9 /* MegaTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MegaTexture.h; sourceTree = ""; }; + 812257630912BC79005D34B9 /* Model.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model.cpp; sourceTree = ""; }; + 812257640912BC79005D34B9 /* Model.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Model.h; sourceTree = ""; }; + 812257650912BC79005D34B9 /* Model_ase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_ase.cpp; sourceTree = ""; }; + 812257660912BC79005D34B9 /* Model_ase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Model_ase.h; sourceTree = ""; }; + 812257670912BC79005D34B9 /* Model_beam.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_beam.cpp; sourceTree = ""; }; + 812257680912BC79005D34B9 /* Model_liquid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_liquid.cpp; sourceTree = ""; }; + 812257690912BC79005D34B9 /* Model_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Model_local.h; sourceTree = ""; }; + 8122576A0912BC79005D34B9 /* Model_lwo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_lwo.cpp; sourceTree = ""; }; + 8122576B0912BC79005D34B9 /* Model_lwo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Model_lwo.h; sourceTree = ""; }; + 8122576C0912BC79005D34B9 /* Model_md3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_md3.cpp; sourceTree = ""; }; + 8122576D0912BC79005D34B9 /* Model_md3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Model_md3.h; sourceTree = ""; }; + 8122576E0912BC79005D34B9 /* Model_md5.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_md5.cpp; sourceTree = ""; }; + 8122576F0912BC79005D34B9 /* Model_prt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Model_prt.cpp; sourceTree = ""; }; + 812257700912BC79005D34B9 /* ModelDecal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ModelDecal.cpp; sourceTree = ""; }; + 812257710912BC79005D34B9 /* ModelDecal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ModelDecal.h; sourceTree = ""; }; + 812257720912BC79005D34B9 /* ModelManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ModelManager.cpp; sourceTree = ""; }; + 812257730912BC79005D34B9 /* ModelManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ModelManager.h; sourceTree = ""; }; + 812257740912BC79005D34B9 /* ModelOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ModelOverlay.cpp; sourceTree = ""; }; + 812257750912BC79005D34B9 /* ModelOverlay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ModelOverlay.h; sourceTree = ""; }; + 812257760912BC79005D34B9 /* qgl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = qgl.h; sourceTree = ""; }; + 812257770912BC79005D34B9 /* qgl_linked.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = qgl_linked.h; sourceTree = ""; }; + 812257780912BC79005D34B9 /* RenderEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderEntity.cpp; sourceTree = ""; }; + 812257790912BC79005D34B9 /* RenderSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSystem.cpp; sourceTree = ""; }; + 8122577A0912BC79005D34B9 /* RenderSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderSystem.h; sourceTree = ""; }; + 8122577B0912BC79005D34B9 /* RenderSystem_init.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSystem_init.cpp; sourceTree = ""; }; + 8122577C0912BC79005D34B9 /* RenderWorld.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWorld.cpp; sourceTree = ""; }; + 8122577D0912BC79005D34B9 /* RenderWorld.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWorld.h; sourceTree = ""; }; + 8122577E0912BC79005D34B9 /* RenderWorld_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWorld_demo.cpp; sourceTree = ""; }; + 8122577F0912BC79005D34B9 /* RenderWorld_load.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWorld_load.cpp; sourceTree = ""; }; + 812257800912BC79005D34B9 /* RenderWorld_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWorld_local.h; sourceTree = ""; }; + 812257810912BC79005D34B9 /* RenderWorld_portals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWorld_portals.cpp; sourceTree = ""; }; + 812257820912BC79005D34B9 /* simplex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = simplex.h; sourceTree = ""; }; + 812257830912BC79005D34B9 /* tr_backend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_backend.cpp; sourceTree = ""; }; + 812257840912BC79005D34B9 /* tr_deform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_deform.cpp; sourceTree = ""; }; + 812257850912BC79005D34B9 /* tr_font.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_font.cpp; sourceTree = ""; }; + 812257860912BC79005D34B9 /* tr_guisurf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_guisurf.cpp; sourceTree = ""; }; + 812257870912BC79005D34B9 /* tr_light.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_light.cpp; sourceTree = ""; }; + 812257880912BC79005D34B9 /* tr_lightrun.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_lightrun.cpp; sourceTree = ""; }; + 812257890912BC79005D34B9 /* tr_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tr_local.h; sourceTree = ""; }; + 8122578A0912BC79005D34B9 /* tr_main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_main.cpp; sourceTree = ""; }; + 8122578B0912BC79005D34B9 /* tr_orderIndexes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_orderIndexes.cpp; sourceTree = ""; }; + 8122578C0912BC79005D34B9 /* tr_polytope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_polytope.cpp; sourceTree = ""; }; + 8122578D0912BC79005D34B9 /* tr_render.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_render.cpp; sourceTree = ""; }; + 8122578E0912BC79005D34B9 /* tr_rendertools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_rendertools.cpp; sourceTree = ""; }; + 8122578F0912BC79005D34B9 /* tr_shadowbounds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_shadowbounds.cpp; sourceTree = ""; }; + 812257900912BC79005D34B9 /* tr_stencilshadow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_stencilshadow.cpp; sourceTree = ""; }; + 812257910912BC79005D34B9 /* tr_subview.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_subview.cpp; sourceTree = ""; }; + 812257920912BC79005D34B9 /* tr_trace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_trace.cpp; sourceTree = ""; }; + 812257930912BC79005D34B9 /* tr_trisurf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_trisurf.cpp; sourceTree = ""; }; + 812257940912BC79005D34B9 /* tr_turboshadow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_turboshadow.cpp; sourceTree = ""; }; + 812257950912BC79005D34B9 /* VertexCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = VertexCache.cpp; sourceTree = ""; }; + 812257960912BC79005D34B9 /* VertexCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VertexCache.h; sourceTree = ""; }; + 812257970912BC79005D34B9 /* wglext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = wglext.h; sourceTree = ""; }; + 8122579A0912BC79005D34B9 /* AsyncClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncClient.cpp; sourceTree = ""; }; + 8122579B0912BC79005D34B9 /* AsyncClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsyncClient.h; sourceTree = ""; }; + 8122579C0912BC79005D34B9 /* AsyncNetwork.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncNetwork.cpp; sourceTree = ""; }; + 8122579D0912BC79005D34B9 /* AsyncNetwork.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsyncNetwork.h; sourceTree = ""; }; + 8122579E0912BC79005D34B9 /* AsyncServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncServer.cpp; sourceTree = ""; }; + 8122579F0912BC79005D34B9 /* AsyncServer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsyncServer.h; sourceTree = ""; }; + 812257A00912BC79005D34B9 /* MsgChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MsgChannel.cpp; sourceTree = ""; }; + 812257A10912BC79005D34B9 /* MsgChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MsgChannel.h; sourceTree = ""; }; + 812257A20912BC79005D34B9 /* NetworkSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkSystem.cpp; sourceTree = ""; }; + 812257A30912BC79005D34B9 /* NetworkSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NetworkSystem.h; sourceTree = ""; }; + 812257A40912BC79005D34B9 /* ServerScan.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ServerScan.cpp; sourceTree = ""; }; + 812257A50912BC79005D34B9 /* ServerScan.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ServerScan.h; sourceTree = ""; }; + 812257A60912BC79005D34B9 /* BuildDefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BuildDefines.h; sourceTree = ""; }; + 812257A70912BC79005D34B9 /* BuildVersion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BuildVersion.h; sourceTree = ""; }; + 812257A80912BC79005D34B9 /* CmdSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CmdSystem.cpp; sourceTree = ""; }; + 812257A90912BC79005D34B9 /* CmdSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CmdSystem.h; sourceTree = ""; }; + 812257AA0912BC79005D34B9 /* Common.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Common.cpp; sourceTree = ""; }; + 812257AB0912BC79005D34B9 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = ""; }; + 812257AC0912BC79005D34B9 /* Compressor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Compressor.cpp; sourceTree = ""; }; + 812257AD0912BC79005D34B9 /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = ""; }; + 812257AE0912BC79005D34B9 /* Console.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Console.cpp; sourceTree = ""; }; + 812257AF0912BC79005D34B9 /* Console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Console.h; sourceTree = ""; }; + 812257B00912BC79005D34B9 /* CVarSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVarSystem.cpp; sourceTree = ""; }; + 812257B10912BC79005D34B9 /* CVarSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVarSystem.h; sourceTree = ""; }; + 812257B20912BC79005D34B9 /* DeclAF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclAF.cpp; sourceTree = ""; }; + 812257B30912BC79005D34B9 /* DeclAF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclAF.h; sourceTree = ""; }; + 812257B40912BC79005D34B9 /* DeclEntityDef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclEntityDef.cpp; sourceTree = ""; }; + 812257B50912BC79005D34B9 /* DeclEntityDef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclEntityDef.h; sourceTree = ""; }; + 812257B60912BC79005D34B9 /* DeclFX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclFX.cpp; sourceTree = ""; }; + 812257B70912BC79005D34B9 /* DeclFX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclFX.h; sourceTree = ""; }; + 812257B80912BC79005D34B9 /* DeclManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclManager.cpp; sourceTree = ""; }; + 812257B90912BC79005D34B9 /* DeclManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclManager.h; sourceTree = ""; }; + 812257BA0912BC79005D34B9 /* DeclParticle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclParticle.cpp; sourceTree = ""; }; + 812257BB0912BC79005D34B9 /* DeclParticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclParticle.h; sourceTree = ""; }; + 812257BC0912BC79005D34B9 /* DeclPDA.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclPDA.cpp; sourceTree = ""; }; + 812257BD0912BC79005D34B9 /* DeclPDA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclPDA.h; sourceTree = ""; }; + 812257BE0912BC79005D34B9 /* DeclSkin.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclSkin.cpp; sourceTree = ""; }; + 812257BF0912BC79005D34B9 /* DeclSkin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclSkin.h; sourceTree = ""; }; + 812257C00912BC79005D34B9 /* DeclTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclTable.cpp; sourceTree = ""; }; + 812257C10912BC79005D34B9 /* DeclTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeclTable.h; sourceTree = ""; }; + 812257C20912BC79005D34B9 /* DemoFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DemoFile.cpp; sourceTree = ""; }; + 812257C30912BC79005D34B9 /* DemoFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DemoFile.h; sourceTree = ""; }; + 812257C40912BC79005D34B9 /* EditField.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EditField.cpp; sourceTree = ""; }; + 812257C50912BC79005D34B9 /* EditField.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EditField.h; sourceTree = ""; }; + 812257C60912BC79005D34B9 /* EventLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EventLoop.cpp; sourceTree = ""; }; + 812257C70912BC79005D34B9 /* EventLoop.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EventLoop.h; sourceTree = ""; }; + 812257C80912BC79005D34B9 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = ""; }; + 812257C90912BC79005D34B9 /* File.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = ""; }; + 812257CA0912BC79005D34B9 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystem.cpp; sourceTree = ""; }; + 812257CB0912BC79005D34B9 /* FileSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileSystem.h; sourceTree = ""; }; + 812257CC0912BC79005D34B9 /* KeyInput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = KeyInput.cpp; sourceTree = ""; }; + 812257CD0912BC79005D34B9 /* KeyInput.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = KeyInput.h; sourceTree = ""; }; + 812257CE0912BC79005D34B9 /* Licensee.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Licensee.h; sourceTree = ""; }; + 812257CF0912BC79005D34B9 /* Session.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Session.cpp; sourceTree = ""; }; + 812257D00912BC79005D34B9 /* Session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Session.h; sourceTree = ""; }; + 812257D10912BC79005D34B9 /* Session_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Session_local.h; sourceTree = ""; }; + 812257D20912BC79005D34B9 /* Session_menu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Session_menu.cpp; sourceTree = ""; }; + 812257D30912BC79005D34B9 /* Unzip.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Unzip.cpp; sourceTree = ""; }; + 812257D40912BC79005D34B9 /* Unzip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Unzip.h; sourceTree = ""; }; + 812257D50912BC79005D34B9 /* UsercmdGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = UsercmdGen.cpp; sourceTree = ""; }; + 812257D60912BC79005D34B9 /* UsercmdGen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = UsercmdGen.h; sourceTree = ""; }; + 812257D80912BC79005D34B9 /* GameBearShootWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GameBearShootWindow.cpp; sourceTree = ""; }; + 812257D90912BC79005D34B9 /* GameBearShootWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GameBearShootWindow.h; sourceTree = ""; }; + 812257DA0912BC79005D34B9 /* GameBustOutWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GameBustOutWindow.cpp; sourceTree = ""; }; + 812257DB0912BC79005D34B9 /* GameBustOutWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GameBustOutWindow.h; sourceTree = ""; }; + 812257DC0912BC79005D34B9 /* GameSSDWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GameSSDWindow.cpp; sourceTree = ""; }; + 812257DD0912BC79005D34B9 /* GameSSDWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GameSSDWindow.h; sourceTree = ""; }; + 812257DE0912BC79005D34B9 /* ListGUI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ListGUI.cpp; sourceTree = ""; }; + 812257DF0912BC79005D34B9 /* ListGUI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListGUI.h; sourceTree = ""; }; + 812257E00912BC79005D34B9 /* ListGUILocal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListGUILocal.h; sourceTree = ""; }; + 812257E10912BC79005D34B9 /* BindWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BindWindow.cpp; sourceTree = ""; }; + 812257E20912BC79005D34B9 /* BindWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BindWindow.h; sourceTree = ""; }; + 812257E30912BC79005D34B9 /* ChoiceWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ChoiceWindow.cpp; sourceTree = ""; }; + 812257E40912BC79005D34B9 /* ChoiceWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ChoiceWindow.h; sourceTree = ""; }; + 812257E50912BC79005D34B9 /* DeviceContext.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceContext.cpp; sourceTree = ""; }; + 812257E60912BC79005D34B9 /* DeviceContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeviceContext.h; sourceTree = ""; }; + 812257E70912BC79005D34B9 /* EditWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EditWindow.cpp; sourceTree = ""; }; + 812257E80912BC79005D34B9 /* EditWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EditWindow.h; sourceTree = ""; }; + 812257E90912BC79005D34B9 /* FieldWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FieldWindow.cpp; sourceTree = ""; }; + 812257EA0912BC79005D34B9 /* FieldWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FieldWindow.h; sourceTree = ""; }; + 812257EB0912BC79005D34B9 /* GuiScript.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GuiScript.cpp; sourceTree = ""; }; + 812257EC0912BC79005D34B9 /* GuiScript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GuiScript.h; sourceTree = ""; }; + 812257ED0912BC79005D34B9 /* ListWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ListWindow.cpp; sourceTree = ""; }; + 812257EE0912BC79005D34B9 /* ListWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListWindow.h; sourceTree = ""; }; + 812257EF0912BC79005D34B9 /* MarkerWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MarkerWindow.cpp; sourceTree = ""; }; + 812257F00912BC79005D34B9 /* MarkerWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MarkerWindow.h; sourceTree = ""; }; + 812257F10912BC79005D34B9 /* Rectangle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Rectangle.h; sourceTree = ""; }; + 812257F20912BC79005D34B9 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = ""; }; + 812257F30912BC79005D34B9 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = ""; }; + 812257F40912BC79005D34B9 /* RegExp_old.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RegExp_old.h; sourceTree = ""; }; + 812257F50912BC79005D34B9 /* RenderWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWindow.cpp; sourceTree = ""; }; + 812257F60912BC79005D34B9 /* RenderWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWindow.h; sourceTree = ""; }; + 812257F70912BC79005D34B9 /* SimpleWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleWindow.cpp; sourceTree = ""; }; + 812257F80912BC79005D34B9 /* SimpleWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SimpleWindow.h; sourceTree = ""; }; + 812257F90912BC79005D34B9 /* SliderWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SliderWindow.cpp; sourceTree = ""; }; + 812257FA0912BC79005D34B9 /* SliderWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SliderWindow.h; sourceTree = ""; }; + 812257FB0912BC79005D34B9 /* UserInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = UserInterface.cpp; sourceTree = ""; }; + 812257FC0912BC79005D34B9 /* UserInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = UserInterface.h; sourceTree = ""; }; + 812257FD0912BC79005D34B9 /* UserInterfaceLocal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = UserInterfaceLocal.h; sourceTree = ""; }; + 812257FE0912BC79005D34B9 /* Window.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Window.cpp; sourceTree = ""; }; + 812257FF0912BC79005D34B9 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; + 812258000912BC79005D34B9 /* Winvar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Winvar.cpp; sourceTree = ""; }; + 812258010912BC79005D34B9 /* Winvar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Winvar.h; sourceTree = ""; }; + 812258030912BC79005D34B9 /* CollisionModel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CollisionModel.h; sourceTree = ""; }; + 812258040912BC79005D34B9 /* CollisionModel_contacts.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_contacts.cpp; sourceTree = ""; }; + 812258050912BC79005D34B9 /* CollisionModel_contents.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_contents.cpp; sourceTree = ""; }; + 812258060912BC79005D34B9 /* CollisionModel_debug.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_debug.cpp; sourceTree = ""; }; + 812258070912BC79005D34B9 /* CollisionModel_files.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_files.cpp; sourceTree = ""; }; + 812258080912BC79005D34B9 /* CollisionModel_load.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_load.cpp; sourceTree = ""; }; + 812258090912BC79005D34B9 /* CollisionModel_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CollisionModel_local.h; sourceTree = ""; }; + 8122580A0912BC79005D34B9 /* CollisionModel_rotate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_rotate.cpp; sourceTree = ""; }; + 8122580B0912BC79005D34B9 /* CollisionModel_trace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_trace.cpp; sourceTree = ""; }; + 8122580C0912BC79005D34B9 /* CollisionModel_translate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CollisionModel_translate.cpp; sourceTree = ""; }; + 812259790912BF1D005D34B9 /* idlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = idlib.xcodeproj; sourceTree = ""; }; + 812259890912BF38005D34B9 /* oggVorbis.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = oggVorbis.xcodeproj; sourceTree = ""; }; + 812259A30912BFDC005D34B9 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 812259A40912BFDC005D34B9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 812259A60912BFDC005D34B9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 812259B40912C056005D34B9 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 812259FD0912C27C005D34B9 /* Doom 3.rsrc */ = {isa = PBXFileReference; lastKnownFileType = archive.rsrc; path = "Doom 3.rsrc"; sourceTree = ""; }; + 812259FE0912C27C005D34B9 /* Doom3.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Doom3.icns; sourceTree = ""; }; + 81225A0C0912C2D3005D34B9 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/ASLCore.nib; sourceTree = ""; }; + 81225A0F0912C2E9005D34B9 /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; + 81225A110912C300005D34B9 /* French */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = French; path = French.lproj/ASLCore.nib; sourceTree = ""; }; + 81225A120912C310005D34B9 /* French */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = French; path = French.lproj/MainMenu.nib; sourceTree = ""; }; + 81225A130912C323005D34B9 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/InfoPlist.strings; sourceTree = ""; }; + 81225A140912C323005D34B9 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; sourceTree = ""; }; + 81225B840912C731005D34B9 /* game.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = game.xcodeproj; sourceTree = ""; }; + 81326DC1099C162D003C4788 /* curl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = curl.xcodeproj; path = SubProjects/curl.xcodeproj; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* Doom 3.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Doom 3.app"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 812259940912BF87005D34B9 /* liboggVorbis_nopic.a in Frameworks */, + 812259930912BF7F005D34B9 /* libidlib_nopic.a in Frameworks */, + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + 812259B00912BFDC005D34B9 /* Carbon.framework in Frameworks */, + 812259B10912BFDC005D34B9 /* IOKit.framework in Frameworks */, + 812259B30912BFDC005D34B9 /* OpenGL.framework in Frameworks */, + 812259B70912C056005D34B9 /* CoreAudio.framework in Frameworks */, + 3A176D3314936ACC0077AB23 /* libdevil.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* Doom 3.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Doom3 */ = { + isa = PBXGroup; + children = ( + 3A1768D3149354D60077AB23 /* devil.xcodeproj */, + 812256420912BC26005D34B9 /* Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 81326DC1099C162D003C4788 /* curl.xcodeproj */, + 812259790912BF1D005D34B9 /* idlib.xcodeproj */, + 812259890912BF38005D34B9 /* oggVorbis.xcodeproj */, + 81225B840912C731005D34B9 /* game.xcodeproj */, + 3A176D3214936ACC0077AB23 /* libdevil.a */, + 3A176DDB1494CAA00077AB23 /* libidlib_pic.a */, + ); + name = Doom3; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 812259FD0912C27C005D34B9 /* Doom 3.rsrc */, + 812259FE0912C27C005D34B9 /* Doom3.icns */, + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 81225A0E0912C2E9005D34B9 /* Localizable.strings */, + 81225A0B0912C2D3005D34B9 /* ASLCore.nib */, + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 812259B40912C056005D34B9 /* CoreAudio.framework */, + 812259A30912BFDC005D34B9 /* Carbon.framework */, + 812259A40912BFDC005D34B9 /* IOKit.framework */, + 812259A60912BFDC005D34B9 /* OpenGL.framework */, + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 3A1768D4149354D60077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A1768DB149354D60077AB23 /* liblibdevil.a.a */, + ); + name = Products; + sourceTree = ""; + }; + 812256420912BC26005D34B9 /* Sources */ = { + isa = PBXGroup; + children = ( + 812256970912BC79005D34B9 /* sys */, + 812256B40912BC79005D34B9 /* sound */, + 812257060912BC79005D34B9 /* renderer */, + 812257980912BC79005D34B9 /* framework */, + 812257D70912BC79005D34B9 /* ui */, + 812258020912BC79005D34B9 /* cm */, + 812256600912BC78005D34B9 /* tools */, + 8122565E0912BC78005D34B9 /* openal */, + ); + name = Sources; + sourceTree = ""; + }; + 8122565E0912BC78005D34B9 /* openal */ = { + isa = PBXGroup; + children = ( + 8122565F0912BC78005D34B9 /* snd_efxfile.cpp */, + ); + name = openal; + sourceTree = ""; + }; + 812256600912BC78005D34B9 /* tools */ = { + isa = PBXGroup; + children = ( + 812256640912BC79005D34B9 /* compilers */, + 812256630912BC79005D34B9 /* edit_stub.cpp */, + 812256610912BC78005D34B9 /* guied */, + ); + name = tools; + sourceTree = ""; + }; + 812256610912BC78005D34B9 /* guied */ = { + isa = PBXGroup; + children = ( + 812256620912BC78005D34B9 /* GEWindowWrapper_stub.cpp */, + ); + name = guied; + sourceTree = ""; + }; + 812256640912BC79005D34B9 /* compilers */ = { + isa = PBXGroup; + children = ( + 812256870912BC79005D34B9 /* dmap */, + 812256710912BC79005D34B9 /* aas */, + 812256670912BC79005D34B9 /* roqvq */, + 812256650912BC79005D34B9 /* renderbump */, + ); + name = compilers; + sourceTree = ""; + }; + 812256650912BC79005D34B9 /* renderbump */ = { + isa = PBXGroup; + children = ( + 812256660912BC79005D34B9 /* renderbump.cpp */, + ); + name = renderbump; + sourceTree = ""; + }; + 812256670912BC79005D34B9 /* roqvq */ = { + isa = PBXGroup; + children = ( + 812256680912BC79005D34B9 /* codec.cpp */, + 812256690912BC79005D34B9 /* codec.h */, + 8122566A0912BC79005D34B9 /* gdefs.h */, + 8122566B0912BC79005D34B9 /* NSBitmapImageRep.cpp */, + 8122566C0912BC79005D34B9 /* quaddefs.h */, + 8122566D0912BC79005D34B9 /* roq.cpp */, + 8122566E0912BC79005D34B9 /* roq.h */, + 8122566F0912BC79005D34B9 /* roqParam.cpp */, + 812256700912BC79005D34B9 /* roqParam.h */, + ); + name = roqvq; + sourceTree = ""; + }; + 812256710912BC79005D34B9 /* aas */ = { + isa = PBXGroup; + children = ( + 812256720912BC79005D34B9 /* AASBuild_file.cpp */, + 812256730912BC79005D34B9 /* AASBuild_gravity.cpp */, + 812256740912BC79005D34B9 /* AASBuild_ledge.cpp */, + 812256750912BC79005D34B9 /* AASBuild_local.h */, + 812256760912BC79005D34B9 /* AASBuild_merge.cpp */, + 812256770912BC79005D34B9 /* AASBuild.cpp */, + 812256780912BC79005D34B9 /* AASCluster.cpp */, + 812256790912BC79005D34B9 /* AASCluster.h */, + 8122567A0912BC79005D34B9 /* AASFile_local.h */, + 8122567B0912BC79005D34B9 /* AASFile_optimize.cpp */, + 8122567C0912BC79005D34B9 /* AASFile_sample.cpp */, + 8122567D0912BC79005D34B9 /* AASFile.cpp */, + 8122567E0912BC79005D34B9 /* AASFile.h */, + 8122567F0912BC79005D34B9 /* AASFileManager.cpp */, + 812256800912BC79005D34B9 /* AASFileManager.h */, + 812256810912BC79005D34B9 /* AASReach.cpp */, + 812256820912BC79005D34B9 /* AASReach.h */, + 812256830912BC79005D34B9 /* Brush.cpp */, + 812256840912BC79005D34B9 /* Brush.h */, + 812256850912BC79005D34B9 /* BrushBSP.cpp */, + 812256860912BC79005D34B9 /* BrushBSP.h */, + ); + name = aas; + sourceTree = ""; + }; + 812256870912BC79005D34B9 /* dmap */ = { + isa = PBXGroup; + children = ( + 812256880912BC79005D34B9 /* dmap.cpp */, + 812256890912BC79005D34B9 /* dmap.h */, + 8122568A0912BC79005D34B9 /* facebsp.cpp */, + 8122568B0912BC79005D34B9 /* gldraw.cpp */, + 8122568C0912BC79005D34B9 /* glfile.cpp */, + 8122568D0912BC79005D34B9 /* leakfile.cpp */, + 8122568E0912BC79005D34B9 /* map.cpp */, + 8122568F0912BC79005D34B9 /* optimize.cpp */, + 812256900912BC79005D34B9 /* output.cpp */, + 812256910912BC79005D34B9 /* portals.cpp */, + 812256920912BC79005D34B9 /* shadowopt3.cpp */, + 812256930912BC79005D34B9 /* tritjunction.cpp */, + 812256940912BC79005D34B9 /* tritools.cpp */, + 812256950912BC79005D34B9 /* ubrush.cpp */, + 812256960912BC79005D34B9 /* usurface.cpp */, + ); + name = dmap; + sourceTree = ""; + }; + 812256970912BC79005D34B9 /* sys */ = { + isa = PBXGroup; + children = ( + 812256B30912BC79005D34B9 /* sys_local.cpp */, + 812256AC0912BC79005D34B9 /* posix */, + 8122569C0912BC79005D34B9 /* osx */, + 8122569A0912BC79005D34B9 /* stub */, + 812256980912BC79005D34B9 /* linux */, + ); + name = sys; + sourceTree = ""; + }; + 812256980912BC79005D34B9 /* linux */ = { + isa = PBXGroup; + children = ( + 812256990912BC79005D34B9 /* stack.cpp */, + ); + name = linux; + sourceTree = ""; + }; + 8122569A0912BC79005D34B9 /* stub */ = { + isa = PBXGroup; + children = ( + 8122569B0912BC79005D34B9 /* util_stub.cpp */, + ); + name = stub; + sourceTree = ""; + }; + 8122569C0912BC79005D34B9 /* osx */ = { + isa = PBXGroup; + children = ( + 8122569D0912BC79005D34B9 /* macosx_guids.cpp */, + 812256A00912BC79005D34B9 /* macosx_misc.mm */, + 812256A10912BC79005D34B9 /* PickMonitor.cpp */, + 812256A20912BC79005D34B9 /* PreferencesDialog.cpp */, + 812256A30912BC79005D34B9 /* PickMonitor.h */, + 812256A40912BC79005D34B9 /* PreferencesDialog.h */, + 812256A50912BC79005D34B9 /* macosx_sound.cpp */, + 812256A60912BC79005D34B9 /* macosx_event.mm */, + 812256A70912BC79005D34B9 /* macosx_glimp.h */, + 812256A80912BC79005D34B9 /* macosx_glimp.mm */, + 812256A90912BC79005D34B9 /* macosx_local.h */, + 812256AA0912BC79005D34B9 /* DOOMController.h */, + 812256AB0912BC79005D34B9 /* DOOMController.mm */, + ); + name = osx; + sourceTree = ""; + }; + 812256AC0912BC79005D34B9 /* posix */ = { + isa = PBXGroup; + children = ( + 812256AD0912BC79005D34B9 /* posix_threads.cpp */, + 812256AE0912BC79005D34B9 /* posix_input.cpp */, + 812256AF0912BC79005D34B9 /* posix_main.cpp */, + 812256B00912BC79005D34B9 /* posix_net.cpp */, + 812256B10912BC79005D34B9 /* posix_public.h */, + 812256B20912BC79005D34B9 /* posix_signal.cpp */, + ); + name = posix; + sourceTree = ""; + }; + 812256B40912BC79005D34B9 /* sound */ = { + isa = PBXGroup; + children = ( + 812256FD0912BC79005D34B9 /* snd_cache.cpp */, + 812256FE0912BC79005D34B9 /* snd_decoder.cpp */, + 812256FF0912BC79005D34B9 /* snd_emitter.cpp */, + 812257000912BC79005D34B9 /* snd_local.h */, + 812257010912BC79005D34B9 /* snd_shader.cpp */, + 812257020912BC79005D34B9 /* snd_system.cpp */, + 812257030912BC79005D34B9 /* snd_wavefile.cpp */, + 812257040912BC79005D34B9 /* snd_world.cpp */, + 812257050912BC79005D34B9 /* sound.h */, + ); + name = sound; + path = ../../sound; + sourceTree = SOURCE_ROOT; + }; + 812257060912BC79005D34B9 /* renderer */ = { + isa = PBXGroup; + children = ( + 812257070912BC79005D34B9 /* Model_ma.cpp */, + 812257080912BC79005D34B9 /* Model_sprite.cpp */, + 812257090912BC79005D34B9 /* cg_explicit.cpp */, + 8122570A0912BC79005D34B9 /* cg_explicit.h */, + 8122570B0912BC79005D34B9 /* Cinematic.cpp */, + 8122570C0912BC79005D34B9 /* Cinematic.h */, + 8122570D0912BC79005D34B9 /* draw_arb.cpp */, + 8122570E0912BC79005D34B9 /* draw_arb2.cpp */, + 8122570F0912BC79005D34B9 /* draw_common.cpp */, + 812257100912BC79005D34B9 /* draw_exp.cpp */, + 812257110912BC79005D34B9 /* draw_exp_stub.cpp */, + 812257120912BC79005D34B9 /* draw_nv10.cpp */, + 812257130912BC79005D34B9 /* draw_nv20.cpp */, + 812257140912BC79005D34B9 /* draw_r200.cpp */, + 812257150912BC79005D34B9 /* glext.h */, + 812257160912BC79005D34B9 /* GuiModel.cpp */, + 812257170912BC79005D34B9 /* GuiModel.h */, + 812257180912BC79005D34B9 /* Image.h */, + 812257190912BC79005D34B9 /* Image_files.cpp */, + 8122571A0912BC79005D34B9 /* Image_init.cpp */, + 8122571B0912BC79005D34B9 /* Image_load.cpp */, + 8122571C0912BC79005D34B9 /* Image_process.cpp */, + 8122571D0912BC79005D34B9 /* Image_program.cpp */, + 8122571E0912BC79005D34B9 /* Interaction.cpp */, + 8122571F0912BC79005D34B9 /* Interaction.h */, + 812257200912BC79005D34B9 /* jpeg-6 */, + 8122575F0912BC79005D34B9 /* Material.cpp */, + 812257600912BC79005D34B9 /* Material.h */, + 812257610912BC79005D34B9 /* MegaTexture.cpp */, + 812257620912BC79005D34B9 /* MegaTexture.h */, + 812257630912BC79005D34B9 /* Model.cpp */, + 812257640912BC79005D34B9 /* Model.h */, + 812257650912BC79005D34B9 /* Model_ase.cpp */, + 812257660912BC79005D34B9 /* Model_ase.h */, + 812257670912BC79005D34B9 /* Model_beam.cpp */, + 812257680912BC79005D34B9 /* Model_liquid.cpp */, + 812257690912BC79005D34B9 /* Model_local.h */, + 8122576A0912BC79005D34B9 /* Model_lwo.cpp */, + 8122576B0912BC79005D34B9 /* Model_lwo.h */, + 8122576C0912BC79005D34B9 /* Model_md3.cpp */, + 8122576D0912BC79005D34B9 /* Model_md3.h */, + 8122576E0912BC79005D34B9 /* Model_md5.cpp */, + 8122576F0912BC79005D34B9 /* Model_prt.cpp */, + 812257700912BC79005D34B9 /* ModelDecal.cpp */, + 812257710912BC79005D34B9 /* ModelDecal.h */, + 812257720912BC79005D34B9 /* ModelManager.cpp */, + 812257730912BC79005D34B9 /* ModelManager.h */, + 812257740912BC79005D34B9 /* ModelOverlay.cpp */, + 812257750912BC79005D34B9 /* ModelOverlay.h */, + 812257760912BC79005D34B9 /* qgl.h */, + 812257770912BC79005D34B9 /* qgl_linked.h */, + 812257780912BC79005D34B9 /* RenderEntity.cpp */, + 812257790912BC79005D34B9 /* RenderSystem.cpp */, + 8122577A0912BC79005D34B9 /* RenderSystem.h */, + 8122577B0912BC79005D34B9 /* RenderSystem_init.cpp */, + 8122577C0912BC79005D34B9 /* RenderWorld.cpp */, + 8122577D0912BC79005D34B9 /* RenderWorld.h */, + 8122577E0912BC79005D34B9 /* RenderWorld_demo.cpp */, + 8122577F0912BC79005D34B9 /* RenderWorld_load.cpp */, + 812257800912BC79005D34B9 /* RenderWorld_local.h */, + 812257810912BC79005D34B9 /* RenderWorld_portals.cpp */, + 812257820912BC79005D34B9 /* simplex.h */, + 812257830912BC79005D34B9 /* tr_backend.cpp */, + 812257840912BC79005D34B9 /* tr_deform.cpp */, + 812257850912BC79005D34B9 /* tr_font.cpp */, + 812257860912BC79005D34B9 /* tr_guisurf.cpp */, + 812257870912BC79005D34B9 /* tr_light.cpp */, + 812257880912BC79005D34B9 /* tr_lightrun.cpp */, + 812257890912BC79005D34B9 /* tr_local.h */, + 8122578A0912BC79005D34B9 /* tr_main.cpp */, + 8122578B0912BC79005D34B9 /* tr_orderIndexes.cpp */, + 8122578C0912BC79005D34B9 /* tr_polytope.cpp */, + 8122578D0912BC79005D34B9 /* tr_render.cpp */, + 8122578E0912BC79005D34B9 /* tr_rendertools.cpp */, + 8122578F0912BC79005D34B9 /* tr_shadowbounds.cpp */, + 812257900912BC79005D34B9 /* tr_stencilshadow.cpp */, + 812257910912BC79005D34B9 /* tr_subview.cpp */, + 812257920912BC79005D34B9 /* tr_trace.cpp */, + 812257930912BC79005D34B9 /* tr_trisurf.cpp */, + 812257940912BC79005D34B9 /* tr_turboshadow.cpp */, + 812257950912BC79005D34B9 /* VertexCache.cpp */, + 812257960912BC79005D34B9 /* VertexCache.h */, + 812257970912BC79005D34B9 /* wglext.h */, + ); + name = renderer; + path = ../../renderer; + sourceTree = SOURCE_ROOT; + }; + 812257200912BC79005D34B9 /* jpeg-6 */ = { + isa = PBXGroup; + children = ( + 812257210912BC79005D34B9 /* jcapimin.c */, + 812257220912BC79005D34B9 /* jcapistd.c */, + 812257230912BC79005D34B9 /* jccoefct.c */, + 812257240912BC79005D34B9 /* jccolor.c */, + 812257250912BC79005D34B9 /* jcdctmgr.c */, + 812257260912BC79005D34B9 /* jchuff.c */, + 812257270912BC79005D34B9 /* jchuff.h */, + 812257280912BC79005D34B9 /* jcinit.c */, + 812257290912BC79005D34B9 /* jcmainct.c */, + 8122572A0912BC79005D34B9 /* jcmarker.c */, + 8122572B0912BC79005D34B9 /* jcmaster.c */, + 8122572C0912BC79005D34B9 /* jcomapi.c */, + 8122572D0912BC79005D34B9 /* jconfig.h */, + 8122572E0912BC79005D34B9 /* jcparam.c */, + 8122572F0912BC79005D34B9 /* jcphuff.c */, + 812257300912BC79005D34B9 /* jcprepct.c */, + 812257310912BC79005D34B9 /* jcsample.c */, + 812257320912BC79005D34B9 /* jctrans.c */, + 812257330912BC79005D34B9 /* jdapimin.c */, + 812257340912BC79005D34B9 /* jdapistd.c */, + 812257350912BC79005D34B9 /* jdatadst.c */, + 812257360912BC79005D34B9 /* jdatasrc.c */, + 812257370912BC79005D34B9 /* jdcoefct.c */, + 812257380912BC79005D34B9 /* jdcolor.c */, + 812257390912BC79005D34B9 /* jdct.h */, + 8122573A0912BC79005D34B9 /* jddctmgr.c */, + 8122573B0912BC79005D34B9 /* jdhuff.c */, + 8122573C0912BC79005D34B9 /* jdhuff.h */, + 8122573D0912BC79005D34B9 /* jdinput.c */, + 8122573E0912BC79005D34B9 /* jdmainct.c */, + 8122573F0912BC79005D34B9 /* jdmarker.c */, + 812257400912BC79005D34B9 /* jdmaster.c */, + 812257410912BC79005D34B9 /* jdmerge.c */, + 812257420912BC79005D34B9 /* jdphuff.c */, + 812257430912BC79005D34B9 /* jdpostct.c */, + 812257440912BC79005D34B9 /* jdsample.c */, + 812257450912BC79005D34B9 /* jdtrans.c */, + 812257460912BC79005D34B9 /* jerror.c */, + 812257470912BC79005D34B9 /* jerror.h */, + 812257480912BC79005D34B9 /* jfdctflt.c */, + 812257490912BC79005D34B9 /* jfdctfst.c */, + 8122574A0912BC79005D34B9 /* jfdctint.c */, + 8122574B0912BC79005D34B9 /* jidctflt.c */, + 8122574C0912BC79005D34B9 /* jidctfst.c */, + 8122574D0912BC79005D34B9 /* jidctint.c */, + 8122574E0912BC79005D34B9 /* jidctred.c */, + 8122574F0912BC79005D34B9 /* jinclude.h */, + 812257500912BC79005D34B9 /* jload.c */, + 812257510912BC79005D34B9 /* jmemansi.c */, + 812257520912BC79005D34B9 /* jmemdos.c */, + 812257530912BC79005D34B9 /* jmemmgr.c */, + 812257540912BC79005D34B9 /* jmemname.c */, + 812257550912BC79005D34B9 /* jmemnobs.c */, + 812257560912BC79005D34B9 /* jmemsys.h */, + 812257570912BC79005D34B9 /* jmorecfg.h */, + 812257580912BC79005D34B9 /* jpegint.h */, + 812257590912BC79005D34B9 /* jpeglib.h */, + 8122575A0912BC79005D34B9 /* jpegtran.c */, + 8122575B0912BC79005D34B9 /* jquant1.c */, + 8122575C0912BC79005D34B9 /* jquant2.c */, + 8122575D0912BC79005D34B9 /* jutils.c */, + 8122575E0912BC79005D34B9 /* jversion.h */, + ); + path = "jpeg-6"; + sourceTree = ""; + }; + 812257980912BC79005D34B9 /* framework */ = { + isa = PBXGroup; + children = ( + 812257990912BC79005D34B9 /* async */, + 812257A60912BC79005D34B9 /* BuildDefines.h */, + 812257A70912BC79005D34B9 /* BuildVersion.h */, + 812257A80912BC79005D34B9 /* CmdSystem.cpp */, + 812257A90912BC79005D34B9 /* CmdSystem.h */, + 812257AA0912BC79005D34B9 /* Common.cpp */, + 812257AB0912BC79005D34B9 /* Common.h */, + 812257AC0912BC79005D34B9 /* Compressor.cpp */, + 812257AD0912BC79005D34B9 /* Compressor.h */, + 812257AE0912BC79005D34B9 /* Console.cpp */, + 812257AF0912BC79005D34B9 /* Console.h */, + 812257B00912BC79005D34B9 /* CVarSystem.cpp */, + 812257B10912BC79005D34B9 /* CVarSystem.h */, + 812257B20912BC79005D34B9 /* DeclAF.cpp */, + 812257B30912BC79005D34B9 /* DeclAF.h */, + 812257B40912BC79005D34B9 /* DeclEntityDef.cpp */, + 812257B50912BC79005D34B9 /* DeclEntityDef.h */, + 812257B60912BC79005D34B9 /* DeclFX.cpp */, + 812257B70912BC79005D34B9 /* DeclFX.h */, + 812257B80912BC79005D34B9 /* DeclManager.cpp */, + 812257B90912BC79005D34B9 /* DeclManager.h */, + 812257BA0912BC79005D34B9 /* DeclParticle.cpp */, + 812257BB0912BC79005D34B9 /* DeclParticle.h */, + 812257BC0912BC79005D34B9 /* DeclPDA.cpp */, + 812257BD0912BC79005D34B9 /* DeclPDA.h */, + 812257BE0912BC79005D34B9 /* DeclSkin.cpp */, + 812257BF0912BC79005D34B9 /* DeclSkin.h */, + 812257C00912BC79005D34B9 /* DeclTable.cpp */, + 812257C10912BC79005D34B9 /* DeclTable.h */, + 812257C20912BC79005D34B9 /* DemoFile.cpp */, + 812257C30912BC79005D34B9 /* DemoFile.h */, + 812257C40912BC79005D34B9 /* EditField.cpp */, + 812257C50912BC79005D34B9 /* EditField.h */, + 812257C60912BC79005D34B9 /* EventLoop.cpp */, + 812257C70912BC79005D34B9 /* EventLoop.h */, + 812257C80912BC79005D34B9 /* File.cpp */, + 812257C90912BC79005D34B9 /* File.h */, + 812257CA0912BC79005D34B9 /* FileSystem.cpp */, + 812257CB0912BC79005D34B9 /* FileSystem.h */, + 812257CC0912BC79005D34B9 /* KeyInput.cpp */, + 812257CD0912BC79005D34B9 /* KeyInput.h */, + 812257CE0912BC79005D34B9 /* Licensee.h */, + 812257CF0912BC79005D34B9 /* Session.cpp */, + 812257D00912BC79005D34B9 /* Session.h */, + 812257D10912BC79005D34B9 /* Session_local.h */, + 812257D20912BC79005D34B9 /* Session_menu.cpp */, + 812257D30912BC79005D34B9 /* Unzip.cpp */, + 812257D40912BC79005D34B9 /* Unzip.h */, + 812257D50912BC79005D34B9 /* UsercmdGen.cpp */, + 812257D60912BC79005D34B9 /* UsercmdGen.h */, + ); + name = framework; + path = ../../framework; + sourceTree = SOURCE_ROOT; + }; + 812257990912BC79005D34B9 /* async */ = { + isa = PBXGroup; + children = ( + 8122579A0912BC79005D34B9 /* AsyncClient.cpp */, + 8122579B0912BC79005D34B9 /* AsyncClient.h */, + 8122579C0912BC79005D34B9 /* AsyncNetwork.cpp */, + 8122579D0912BC79005D34B9 /* AsyncNetwork.h */, + 8122579E0912BC79005D34B9 /* AsyncServer.cpp */, + 8122579F0912BC79005D34B9 /* AsyncServer.h */, + 812257A00912BC79005D34B9 /* MsgChannel.cpp */, + 812257A10912BC79005D34B9 /* MsgChannel.h */, + 812257A20912BC79005D34B9 /* NetworkSystem.cpp */, + 812257A30912BC79005D34B9 /* NetworkSystem.h */, + 812257A40912BC79005D34B9 /* ServerScan.cpp */, + 812257A50912BC79005D34B9 /* ServerScan.h */, + ); + path = async; + sourceTree = ""; + }; + 812257D70912BC79005D34B9 /* ui */ = { + isa = PBXGroup; + children = ( + 812257D80912BC79005D34B9 /* GameBearShootWindow.cpp */, + 812257D90912BC79005D34B9 /* GameBearShootWindow.h */, + 812257DA0912BC79005D34B9 /* GameBustOutWindow.cpp */, + 812257DB0912BC79005D34B9 /* GameBustOutWindow.h */, + 812257DC0912BC79005D34B9 /* GameSSDWindow.cpp */, + 812257DD0912BC79005D34B9 /* GameSSDWindow.h */, + 812257DE0912BC79005D34B9 /* ListGUI.cpp */, + 812257DF0912BC79005D34B9 /* ListGUI.h */, + 812257E00912BC79005D34B9 /* ListGUILocal.h */, + 812257E10912BC79005D34B9 /* BindWindow.cpp */, + 812257E20912BC79005D34B9 /* BindWindow.h */, + 812257E30912BC79005D34B9 /* ChoiceWindow.cpp */, + 812257E40912BC79005D34B9 /* ChoiceWindow.h */, + 812257E50912BC79005D34B9 /* DeviceContext.cpp */, + 812257E60912BC79005D34B9 /* DeviceContext.h */, + 812257E70912BC79005D34B9 /* EditWindow.cpp */, + 812257E80912BC79005D34B9 /* EditWindow.h */, + 812257E90912BC79005D34B9 /* FieldWindow.cpp */, + 812257EA0912BC79005D34B9 /* FieldWindow.h */, + 812257EB0912BC79005D34B9 /* GuiScript.cpp */, + 812257EC0912BC79005D34B9 /* GuiScript.h */, + 812257ED0912BC79005D34B9 /* ListWindow.cpp */, + 812257EE0912BC79005D34B9 /* ListWindow.h */, + 812257EF0912BC79005D34B9 /* MarkerWindow.cpp */, + 812257F00912BC79005D34B9 /* MarkerWindow.h */, + 812257F10912BC79005D34B9 /* Rectangle.h */, + 812257F20912BC79005D34B9 /* RegExp.cpp */, + 812257F30912BC79005D34B9 /* RegExp.h */, + 812257F40912BC79005D34B9 /* RegExp_old.h */, + 812257F50912BC79005D34B9 /* RenderWindow.cpp */, + 812257F60912BC79005D34B9 /* RenderWindow.h */, + 812257F70912BC79005D34B9 /* SimpleWindow.cpp */, + 812257F80912BC79005D34B9 /* SimpleWindow.h */, + 812257F90912BC79005D34B9 /* SliderWindow.cpp */, + 812257FA0912BC79005D34B9 /* SliderWindow.h */, + 812257FB0912BC79005D34B9 /* UserInterface.cpp */, + 812257FC0912BC79005D34B9 /* UserInterface.h */, + 812257FD0912BC79005D34B9 /* UserInterfaceLocal.h */, + 812257FE0912BC79005D34B9 /* Window.cpp */, + 812257FF0912BC79005D34B9 /* Window.h */, + 812258000912BC79005D34B9 /* Winvar.cpp */, + 812258010912BC79005D34B9 /* Winvar.h */, + ); + name = ui; + path = ../../ui; + sourceTree = SOURCE_ROOT; + }; + 812258020912BC79005D34B9 /* cm */ = { + isa = PBXGroup; + children = ( + 812258030912BC79005D34B9 /* CollisionModel.h */, + 812258040912BC79005D34B9 /* CollisionModel_contacts.cpp */, + 812258050912BC79005D34B9 /* CollisionModel_contents.cpp */, + 812258060912BC79005D34B9 /* CollisionModel_debug.cpp */, + 812258070912BC79005D34B9 /* CollisionModel_files.cpp */, + 812258080912BC79005D34B9 /* CollisionModel_load.cpp */, + 812258090912BC79005D34B9 /* CollisionModel_local.h */, + 8122580A0912BC79005D34B9 /* CollisionModel_rotate.cpp */, + 8122580B0912BC79005D34B9 /* CollisionModel_trace.cpp */, + 8122580C0912BC79005D34B9 /* CollisionModel_translate.cpp */, + ); + name = cm; + path = ../../cm; + sourceTree = SOURCE_ROOT; + }; + 8122597A0912BF1D005D34B9 /* Products */ = { + isa = PBXGroup; + children = ( + 812259800912BF1D005D34B9 /* libidlib_pic.a */, + 812259820912BF1D005D34B9 /* libidlib_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 8122598A0912BF38005D34B9 /* Products */ = { + isa = PBXGroup; + children = ( + 8122598F0912BF38005D34B9 /* liboggVorbis_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 81225B850912C731005D34B9 /* Products */ = { + isa = PBXGroup; + children = ( + 81225B8B0912C731005D34B9 /* game.dylib */, + ); + name = Products; + sourceTree = ""; + }; + 81326DC2099C162D003C4788 /* Products */ = { + isa = PBXGroup; + children = ( + 81326DC7099C162D003C4788 /* libcurl_static.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* Doom 3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8191F1600912BBCD006AB5A4 /* Build configuration list for PBXNativeTarget "Doom 3" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 812259840912BF2B005D34B9 /* PBXTargetDependency */, + 812259910912BF43005D34B9 /* PBXTargetDependency */, + 81225B8D0912C73C005D34B9 /* PBXTargetDependency */, + 3A176968149355C20077AB23 /* PBXTargetDependency */, + ); + name = "Doom 3"; + productInstallPath = "$(HOME)/Applications"; + productName = Doom3; + productReference = 8D1107320486CEB800E47090 /* Doom 3.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + ORGANIZATIONNAME = "id Software LLC"; + }; + buildConfigurationList = 8191F1640912BBCD006AB5A4 /* Build configuration list for PBXProject "Doom3" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* Doom3 */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 81326DC2099C162D003C4788 /* Products */; + ProjectRef = 81326DC1099C162D003C4788 /* curl.xcodeproj */; + }, + { + ProductGroup = 3A1768D4149354D60077AB23 /* Products */; + ProjectRef = 3A1768D3149354D60077AB23 /* devil.xcodeproj */; + }, + { + ProductGroup = 81225B850912C731005D34B9 /* Products */; + ProjectRef = 81225B840912C731005D34B9 /* game.xcodeproj */; + }, + { + ProductGroup = 8122597A0912BF1D005D34B9 /* Products */; + ProjectRef = 812259790912BF1D005D34B9 /* idlib.xcodeproj */; + }, + { + ProductGroup = 8122598A0912BF38005D34B9 /* Products */; + ProjectRef = 812259890912BF38005D34B9 /* oggVorbis.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 8D1107260486CEB800E47090 /* Doom 3 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 3A1768DB149354D60077AB23 /* liblibdevil.a.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = liblibdevil.a.a; + remoteRef = 3A1768DA149354D60077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 812259800912BF1D005D34B9 /* libidlib_pic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_pic.a; + remoteRef = 8122597F0912BF1D005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 812259820912BF1D005D34B9 /* libidlib_nopic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_nopic.a; + remoteRef = 812259810912BF1D005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8122598F0912BF38005D34B9 /* liboggVorbis_nopic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = liboggVorbis_nopic.a; + remoteRef = 8122598E0912BF38005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 81225B8B0912C731005D34B9 /* game.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = game.dylib; + remoteRef = 81225B8A0912C731005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 81326DC7099C162D003C4788 /* libcurl_static.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libcurl_static.a; + remoteRef = 81326DC6099C162D003C4788 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + 812259FF0912C27D005D34B9 /* Doom 3.rsrc in Resources */, + 81225A000912C27D005D34B9 /* Doom3.icns in Resources */, + 81225A0D0912C2D3005D34B9 /* ASLCore.nib in Resources */, + 81225A100912C2E9005D34B9 /* Localizable.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 812258110912BC79005D34B9 /* snd_efxfile.cpp in Sources */, + 812258120912BC79005D34B9 /* GEWindowWrapper_stub.cpp in Sources */, + 812258130912BC79005D34B9 /* edit_stub.cpp in Sources */, + 812258140912BC79005D34B9 /* renderbump.cpp in Sources */, + 812258150912BC79005D34B9 /* codec.cpp in Sources */, + 812258160912BC79005D34B9 /* NSBitmapImageRep.cpp in Sources */, + 812258170912BC79005D34B9 /* roq.cpp in Sources */, + 812258180912BC79005D34B9 /* roqParam.cpp in Sources */, + 812258190912BC79005D34B9 /* AASBuild_file.cpp in Sources */, + 8122581A0912BC79005D34B9 /* AASBuild_gravity.cpp in Sources */, + 8122581B0912BC79005D34B9 /* AASBuild_ledge.cpp in Sources */, + 8122581C0912BC79005D34B9 /* AASBuild_merge.cpp in Sources */, + 8122581D0912BC79005D34B9 /* AASBuild.cpp in Sources */, + 8122581E0912BC79005D34B9 /* AASCluster.cpp in Sources */, + 8122581F0912BC79005D34B9 /* AASFile_optimize.cpp in Sources */, + 812258200912BC79005D34B9 /* AASFile_sample.cpp in Sources */, + 812258210912BC79005D34B9 /* AASFile.cpp in Sources */, + 812258220912BC79005D34B9 /* AASFileManager.cpp in Sources */, + 812258230912BC79005D34B9 /* AASReach.cpp in Sources */, + 812258240912BC79005D34B9 /* Brush.cpp in Sources */, + 812258250912BC79005D34B9 /* BrushBSP.cpp in Sources */, + 812258260912BC79005D34B9 /* dmap.cpp in Sources */, + 812258270912BC79005D34B9 /* facebsp.cpp in Sources */, + 812258280912BC79005D34B9 /* gldraw.cpp in Sources */, + 812258290912BC79005D34B9 /* glfile.cpp in Sources */, + 8122582A0912BC79005D34B9 /* leakfile.cpp in Sources */, + 8122582B0912BC79005D34B9 /* map.cpp in Sources */, + 8122582C0912BC79005D34B9 /* optimize.cpp in Sources */, + 8122582D0912BC79005D34B9 /* output.cpp in Sources */, + 8122582E0912BC79005D34B9 /* portals.cpp in Sources */, + 8122582F0912BC79005D34B9 /* shadowopt3.cpp in Sources */, + 812258300912BC79005D34B9 /* tritjunction.cpp in Sources */, + 812258310912BC79005D34B9 /* tritools.cpp in Sources */, + 812258320912BC79005D34B9 /* ubrush.cpp in Sources */, + 812258330912BC79005D34B9 /* usurface.cpp in Sources */, + 812258340912BC79005D34B9 /* stack.cpp in Sources */, + 812258350912BC79005D34B9 /* util_stub.cpp in Sources */, + 812258360912BC79005D34B9 /* macosx_guids.cpp in Sources */, + 812258380912BC79005D34B9 /* macosx_misc.mm in Sources */, + 812258390912BC79005D34B9 /* PickMonitor.cpp in Sources */, + 8122583A0912BC79005D34B9 /* PreferencesDialog.cpp in Sources */, + 8122583B0912BC79005D34B9 /* macosx_sound.cpp in Sources */, + 8122583C0912BC79005D34B9 /* macosx_event.mm in Sources */, + 8122583D0912BC79005D34B9 /* macosx_glimp.mm in Sources */, + 8122583E0912BC79005D34B9 /* DOOMController.mm in Sources */, + 8122583F0912BC79005D34B9 /* posix_threads.cpp in Sources */, + 812258400912BC79005D34B9 /* posix_input.cpp in Sources */, + 812258410912BC79005D34B9 /* posix_main.cpp in Sources */, + 812258420912BC79005D34B9 /* posix_net.cpp in Sources */, + 812258430912BC79005D34B9 /* posix_signal.cpp in Sources */, + 812258440912BC79005D34B9 /* sys_local.cpp in Sources */, + 812258620912BC79005D34B9 /* snd_cache.cpp in Sources */, + 812258630912BC79005D34B9 /* snd_decoder.cpp in Sources */, + 812258640912BC79005D34B9 /* snd_emitter.cpp in Sources */, + 812258650912BC79005D34B9 /* snd_shader.cpp in Sources */, + 812258660912BC79005D34B9 /* snd_system.cpp in Sources */, + 812258670912BC79005D34B9 /* snd_wavefile.cpp in Sources */, + 812258680912BC79005D34B9 /* snd_world.cpp in Sources */, + 812258690912BC79005D34B9 /* Model_ma.cpp in Sources */, + 8122586A0912BC79005D34B9 /* Model_sprite.cpp in Sources */, + 8122586B0912BC79005D34B9 /* cg_explicit.cpp in Sources */, + 8122586C0912BC79005D34B9 /* Cinematic.cpp in Sources */, + 8122586D0912BC79005D34B9 /* draw_arb.cpp in Sources */, + 8122586E0912BC79005D34B9 /* draw_arb2.cpp in Sources */, + 8122586F0912BC79005D34B9 /* draw_common.cpp in Sources */, + 812258710912BC79005D34B9 /* draw_exp_stub.cpp in Sources */, + 812258720912BC79005D34B9 /* draw_nv10.cpp in Sources */, + 812258730912BC79005D34B9 /* draw_nv20.cpp in Sources */, + 812258740912BC79005D34B9 /* draw_r200.cpp in Sources */, + 812258750912BC79005D34B9 /* GuiModel.cpp in Sources */, + 812258760912BC79005D34B9 /* Image_files.cpp in Sources */, + 812258770912BC79005D34B9 /* Image_init.cpp in Sources */, + 812258780912BC79005D34B9 /* Image_load.cpp in Sources */, + 812258790912BC79005D34B9 /* Image_process.cpp in Sources */, + 8122587A0912BC79005D34B9 /* Image_program.cpp in Sources */, + 8122587B0912BC79005D34B9 /* Interaction.cpp in Sources */, + 8122587C0912BC79005D34B9 /* jcapimin.c in Sources */, + 8122587D0912BC79005D34B9 /* jcapistd.c in Sources */, + 8122587E0912BC79005D34B9 /* jccoefct.c in Sources */, + 8122587F0912BC79005D34B9 /* jccolor.c in Sources */, + 812258800912BC79005D34B9 /* jcdctmgr.c in Sources */, + 812258810912BC79005D34B9 /* jchuff.c in Sources */, + 812258820912BC79005D34B9 /* jcinit.c in Sources */, + 812258830912BC79005D34B9 /* jcmainct.c in Sources */, + 812258840912BC79005D34B9 /* jcmarker.c in Sources */, + 812258850912BC79005D34B9 /* jcmaster.c in Sources */, + 812258860912BC79005D34B9 /* jcomapi.c in Sources */, + 812258870912BC79005D34B9 /* jcparam.c in Sources */, + 812258880912BC79005D34B9 /* jcphuff.c in Sources */, + 812258890912BC79005D34B9 /* jcprepct.c in Sources */, + 8122588A0912BC79005D34B9 /* jcsample.c in Sources */, + 8122588B0912BC79005D34B9 /* jctrans.c in Sources */, + 8122588C0912BC79005D34B9 /* jdapimin.c in Sources */, + 8122588D0912BC79005D34B9 /* jdapistd.c in Sources */, + 8122588E0912BC79005D34B9 /* jdatadst.c in Sources */, + 8122588F0912BC79005D34B9 /* jdatasrc.c in Sources */, + 812258900912BC79005D34B9 /* jdcoefct.c in Sources */, + 812258910912BC79005D34B9 /* jdcolor.c in Sources */, + 812258920912BC79005D34B9 /* jddctmgr.c in Sources */, + 812258930912BC79005D34B9 /* jdhuff.c in Sources */, + 812258940912BC79005D34B9 /* jdinput.c in Sources */, + 812258950912BC79005D34B9 /* jdmainct.c in Sources */, + 812258960912BC79005D34B9 /* jdmarker.c in Sources */, + 812258970912BC79005D34B9 /* jdmaster.c in Sources */, + 812258980912BC79005D34B9 /* jdmerge.c in Sources */, + 812258990912BC79005D34B9 /* jdphuff.c in Sources */, + 8122589A0912BC79005D34B9 /* jdpostct.c in Sources */, + 8122589B0912BC79005D34B9 /* jdsample.c in Sources */, + 8122589C0912BC79005D34B9 /* jdtrans.c in Sources */, + 8122589D0912BC79005D34B9 /* jerror.c in Sources */, + 8122589E0912BC79005D34B9 /* jfdctflt.c in Sources */, + 8122589F0912BC79005D34B9 /* jfdctfst.c in Sources */, + 812258A00912BC79005D34B9 /* jfdctint.c in Sources */, + 812258A10912BC79005D34B9 /* jidctflt.c in Sources */, + 812258A20912BC79005D34B9 /* jidctfst.c in Sources */, + 812258A30912BC79005D34B9 /* jidctint.c in Sources */, + 812258A40912BC79005D34B9 /* jidctred.c in Sources */, + 812258A80912BC79005D34B9 /* jmemmgr.c in Sources */, + 812258AA0912BC79005D34B9 /* jmemnobs.c in Sources */, + 812258AC0912BC79005D34B9 /* jquant1.c in Sources */, + 812258AD0912BC79005D34B9 /* jquant2.c in Sources */, + 812258AE0912BC79005D34B9 /* jutils.c in Sources */, + 812258AF0912BC79005D34B9 /* Material.cpp in Sources */, + 812258B00912BC79005D34B9 /* MegaTexture.cpp in Sources */, + 812258B10912BC79005D34B9 /* Model.cpp in Sources */, + 812258B20912BC79005D34B9 /* Model_ase.cpp in Sources */, + 812258B30912BC79005D34B9 /* Model_beam.cpp in Sources */, + 812258B40912BC79005D34B9 /* Model_liquid.cpp in Sources */, + 812258B50912BC79005D34B9 /* Model_lwo.cpp in Sources */, + 812258B60912BC79005D34B9 /* Model_md3.cpp in Sources */, + 812258B70912BC79005D34B9 /* Model_md5.cpp in Sources */, + 812258B80912BC79005D34B9 /* Model_prt.cpp in Sources */, + 812258B90912BC79005D34B9 /* ModelDecal.cpp in Sources */, + 812258BA0912BC79005D34B9 /* ModelManager.cpp in Sources */, + 812258BB0912BC79005D34B9 /* ModelOverlay.cpp in Sources */, + 812258BC0912BC79005D34B9 /* RenderEntity.cpp in Sources */, + 812258BD0912BC79005D34B9 /* RenderSystem.cpp in Sources */, + 812258BE0912BC79005D34B9 /* RenderSystem_init.cpp in Sources */, + 812258BF0912BC79005D34B9 /* RenderWorld.cpp in Sources */, + 812258C00912BC79005D34B9 /* RenderWorld_demo.cpp in Sources */, + 812258C10912BC79005D34B9 /* RenderWorld_load.cpp in Sources */, + 812258C20912BC79005D34B9 /* RenderWorld_portals.cpp in Sources */, + 812258C30912BC79005D34B9 /* tr_backend.cpp in Sources */, + 812258C40912BC79005D34B9 /* tr_deform.cpp in Sources */, + 812258C50912BC79005D34B9 /* tr_font.cpp in Sources */, + 812258C60912BC79005D34B9 /* tr_guisurf.cpp in Sources */, + 812258C70912BC79005D34B9 /* tr_light.cpp in Sources */, + 812258C80912BC79005D34B9 /* tr_lightrun.cpp in Sources */, + 812258C90912BC79005D34B9 /* tr_main.cpp in Sources */, + 812258CA0912BC79005D34B9 /* tr_orderIndexes.cpp in Sources */, + 812258CB0912BC79005D34B9 /* tr_polytope.cpp in Sources */, + 812258CC0912BC79005D34B9 /* tr_render.cpp in Sources */, + 812258CD0912BC79005D34B9 /* tr_rendertools.cpp in Sources */, + 812258CE0912BC79005D34B9 /* tr_shadowbounds.cpp in Sources */, + 812258CF0912BC79005D34B9 /* tr_stencilshadow.cpp in Sources */, + 812258D00912BC79005D34B9 /* tr_subview.cpp in Sources */, + 812258D10912BC79005D34B9 /* tr_trace.cpp in Sources */, + 812258D20912BC79005D34B9 /* tr_trisurf.cpp in Sources */, + 812258D30912BC79005D34B9 /* tr_turboshadow.cpp in Sources */, + 812258D40912BC79005D34B9 /* VertexCache.cpp in Sources */, + 812258D50912BC79005D34B9 /* AsyncClient.cpp in Sources */, + 812258D60912BC79005D34B9 /* AsyncNetwork.cpp in Sources */, + 812258D70912BC79005D34B9 /* AsyncServer.cpp in Sources */, + 812258D80912BC79005D34B9 /* MsgChannel.cpp in Sources */, + 812258D90912BC79005D34B9 /* NetworkSystem.cpp in Sources */, + 812258DA0912BC79005D34B9 /* ServerScan.cpp in Sources */, + 812258DB0912BC79005D34B9 /* CmdSystem.cpp in Sources */, + 812258DC0912BC79005D34B9 /* Common.cpp in Sources */, + 812258DD0912BC79005D34B9 /* Compressor.cpp in Sources */, + 812258DE0912BC79005D34B9 /* Console.cpp in Sources */, + 812258DF0912BC79005D34B9 /* CVarSystem.cpp in Sources */, + 812258E00912BC79005D34B9 /* DeclAF.cpp in Sources */, + 812258E10912BC79005D34B9 /* DeclEntityDef.cpp in Sources */, + 812258E20912BC79005D34B9 /* DeclFX.cpp in Sources */, + 812258E30912BC79005D34B9 /* DeclManager.cpp in Sources */, + 812258E40912BC79005D34B9 /* DeclParticle.cpp in Sources */, + 812258E50912BC79005D34B9 /* DeclPDA.cpp in Sources */, + 812258E60912BC79005D34B9 /* DeclSkin.cpp in Sources */, + 812258E70912BC79005D34B9 /* DeclTable.cpp in Sources */, + 812258E80912BC79005D34B9 /* DemoFile.cpp in Sources */, + 812258E90912BC79005D34B9 /* EditField.cpp in Sources */, + 812258EA0912BC79005D34B9 /* EventLoop.cpp in Sources */, + 812258EB0912BC79005D34B9 /* File.cpp in Sources */, + 812258EC0912BC79005D34B9 /* FileSystem.cpp in Sources */, + 812258ED0912BC79005D34B9 /* KeyInput.cpp in Sources */, + 812258EE0912BC79005D34B9 /* Session.cpp in Sources */, + 812258EF0912BC79005D34B9 /* Session_menu.cpp in Sources */, + 812258F00912BC79005D34B9 /* Unzip.cpp in Sources */, + 812258F10912BC79005D34B9 /* UsercmdGen.cpp in Sources */, + 812258F20912BC79005D34B9 /* GameBearShootWindow.cpp in Sources */, + 812258F30912BC79005D34B9 /* GameBustOutWindow.cpp in Sources */, + 812258F40912BC79005D34B9 /* GameSSDWindow.cpp in Sources */, + 812258F50912BC79005D34B9 /* ListGUI.cpp in Sources */, + 812258F60912BC79005D34B9 /* BindWindow.cpp in Sources */, + 812258F70912BC79005D34B9 /* ChoiceWindow.cpp in Sources */, + 812258F80912BC79005D34B9 /* DeviceContext.cpp in Sources */, + 812258F90912BC79005D34B9 /* EditWindow.cpp in Sources */, + 812258FA0912BC79005D34B9 /* FieldWindow.cpp in Sources */, + 812258FB0912BC79005D34B9 /* GuiScript.cpp in Sources */, + 812258FC0912BC79005D34B9 /* ListWindow.cpp in Sources */, + 812258FD0912BC79005D34B9 /* MarkerWindow.cpp in Sources */, + 812258FE0912BC79005D34B9 /* RegExp.cpp in Sources */, + 812258FF0912BC79005D34B9 /* RenderWindow.cpp in Sources */, + 812259000912BC79005D34B9 /* SimpleWindow.cpp in Sources */, + 812259010912BC79005D34B9 /* SliderWindow.cpp in Sources */, + 812259020912BC79005D34B9 /* UserInterface.cpp in Sources */, + 812259030912BC79005D34B9 /* Window.cpp in Sources */, + 812259040912BC79005D34B9 /* Winvar.cpp in Sources */, + 812259050912BC79005D34B9 /* CollisionModel_contacts.cpp in Sources */, + 812259060912BC79005D34B9 /* CollisionModel_contents.cpp in Sources */, + 812259070912BC79005D34B9 /* CollisionModel_debug.cpp in Sources */, + 812259080912BC79005D34B9 /* CollisionModel_files.cpp in Sources */, + 812259090912BC79005D34B9 /* CollisionModel_load.cpp in Sources */, + 8122590A0912BC79005D34B9 /* CollisionModel_rotate.cpp in Sources */, + 8122590B0912BC79005D34B9 /* CollisionModel_trace.cpp in Sources */, + 8122590C0912BC79005D34B9 /* CollisionModel_translate.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3A176968149355C20077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = devil; + targetProxy = 3A176967149355C20077AB23 /* PBXContainerItemProxy */; + }; + 812259840912BF2B005D34B9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = idlib_nopic; + targetProxy = 812259830912BF2B005D34B9 /* PBXContainerItemProxy */; + }; + 812259910912BF43005D34B9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = oggVorbis_nopic; + targetProxy = 812259900912BF43005D34B9 /* PBXContainerItemProxy */; + }; + 81225B8D0912C73C005D34B9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = game; + targetProxy = 81225B8C0912C73C005D34B9 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + 81225A130912C323005D34B9 /* French */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 29B97319FDCFA39411CA2CEA /* English */, + 81225A120912C310005D34B9 /* French */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; + 81225A0B0912C2D3005D34B9 /* ASLCore.nib */ = { + isa = PBXVariantGroup; + children = ( + 81225A0C0912C2D3005D34B9 /* English */, + 81225A110912C300005D34B9 /* French */, + ); + name = ASLCore.nib; + sourceTree = ""; + }; + 81225A0E0912C2E9005D34B9 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 81225A0F0912C2E9005D34B9 /* English */, + 81225A140912C323005D34B9 /* French */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8191F1610912BBCD006AB5A4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 1; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + __DOOM_DLL__, + "ID_ENABLE_CURL=1", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "\"$(SRCROOT)/../../macosx/libcurl\"", + "\"$(SRCROOT)/build/devil.build/Release/devil.build/Objects-normal/i386\"", + "\"$(SRCROOT)/build/Release\"", + ); + OTHER_LDFLAGS = ( + "-weak_framework", + OpenAL, + "-lcurl", + ); + PREBINDING = NO; + PRODUCT_NAME = "Doom 3"; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Debug; + }; + 8191F1620912BBCD006AB5A4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + __DOOM_DLL__, + "ID_ENABLE_CURL=1", + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "\"$(SRCROOT)/../../macosx/libcurl\"", + "\"$(SRCROOT)/build/devil.build/Release/devil.build/Objects-normal/i386\"", + "\"$(SRCROOT)/build/Release\"", + ); + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + OTHER_LDFLAGS = ( + "-weak_framework", + OpenAL, + "-lcurl", + ); + PREBINDING = NO; + PRODUCT_NAME = "Doom 3"; + SYMROOT = build; + USER_HEADER_SEARCH_PATHS = /Users/Shared/darkmod_src/include; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 8191F1650912BBCD006AB5A4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 1; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + ); + HEADER_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.5; + MAIN_CPP_DEFINES = _DEBUG; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = ""; + VALID_ARCHS = "i386 ppc"; + }; + name = Debug; + }; + 8191F1660912BBCD006AB5A4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + ); + HEADER_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.5; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + "-fomit-frame-pointer", + "-fno-common", + ); + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = /Users/Shared/darkmod_src/include/; + VALID_ARCHS = "ppc i386"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8191F1600912BBCD006AB5A4 /* Build configuration list for PBXNativeTarget "Doom 3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8191F1610912BBCD006AB5A4 /* Debug */, + 8191F1620912BBCD006AB5A4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 8191F1640912BBCD006AB5A4 /* Build configuration list for PBXProject "Doom3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8191F1650912BBCD006AB5A4 /* Debug */, + 8191F1660912BBCD006AB5A4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/sys/osx/English.lproj/ASLCore.nib/classes.nib b/sys/osx/English.lproj/ASLCore.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/sys/osx/English.lproj/ASLCore.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/sys/osx/English.lproj/ASLCore.nib/info.nib b/sys/osx/English.lproj/ASLCore.nib/info.nib new file mode 100644 index 000000000..cc78cd36c --- /dev/null +++ b/sys/osx/English.lproj/ASLCore.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 644 134 374 387 0 0 1280 1002 + IBEditorPositions + + 29 + 130 495 95 44 0 0 1600 1002 + + IBFramework Version + 364.0 + IBOldestOS + 3 + IBSystem Version + 7W98 + targetFramework + IBCarbonFramework + + diff --git a/sys/osx/English.lproj/ASLCore.nib/objects.xib b/sys/osx/English.lproj/ASLCore.nib/objects.xib new file mode 100644 index 000000000..4c4e8d5a6 --- /dev/null +++ b/sys/osx/English.lproj/ASLCore.nib/objects.xib @@ -0,0 +1,710 @@ + + + IBCarbonFramework + + NSApplication + + + + SimpleHello + + + ASL Game + + ASL Game + + + About <<<kGameName>>>... + 0 + abou + + + TRUE + + + TRUE + Preferences... + , + pref + + + TRUE + TRUE + + + TRUE + Toggle Full Screen + + Togg + + + TRUE + TRUE + + + _NSAppleMenu + + + + _NSMainMenu + + + + + + + + + + + 640 261 881 829 + Doom 3 Preferences + + 0 0 241 568 + 0 0 568 241 + + + 6 20 221 272 + 20 6 252 215 + + + 36 50 102 126 + 30 30 76 66 + PREF + 1 + Fullscreen + Full + 256 + 3 + 1000 + 3 + + + 36 166 102 242 + 146 30 76 66 + PREF + 2 + In a Window + Wind + 256 + 3 + 1001 + 3 + + + 116 36 136 256 + 16 110 220 20 + PREF + 3 + Resolution: + Reso + -2 + + Popup: + + + TRUE + TRUE + 800 x 600 + + + TRUE + 1024 x 768 + + + TRUE + 1280 x 1024 + + + + + + 148 36 168 256 + 16 142 220 20 + PREF + 4 + Refresh Rate: + Refr + -2 + + Popup: + + + TRUE + TRUE + Automatic + + + TRUE + TRUE + + + + + + 189 36 205 161 + 16 183 125 16 + Multiple Monitors: + -2 + + + 188 169 208 256 + 149 182 87 20 + PREF + 5 + Choose... + Moni + + + Monitor Options + + + 48 317 104 548 + 317 48 231 56 + TRUE + 1 + This dialog will always be displayed if the command key is held down when the game starts. + + + 201 396 221 466 + 396 201 70 20 + Cancel + not! + 2 + + + 201 478 221 548 + 478 201 70 20 + OK + ok + 1 + + + 20 296 40 548 + 296 20 252 20 + PREF + 6 + Always display this dialog at startup + + + 112 296 132 548 + 296 112 252 20 + PREF + 7 + Use OpenAL + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + + + + + + + + + + + + + 256 318 276 388 + 318 256 70 20 + OK + ok + 1 + + + 366 175 662 583 + <<<kGameName>>> + + 0 0 296 408 + 0 0 408 296 + + + 6 20 236 388 + 20 6 368 230 + + + 36 36 220 372 + 16 30 336 184 + MONI + 1 + 32 + + + Select a Monitor + + + 256 236 276 306 + 236 256 70 20 + Cancel + not! + 2 + + + + + FALSE + FALSE + TRUE + TRUE + 11 + 7 + + + + + + + 88 303 108 373 + 303 88 70 20 + Quit + not! + 2 + + + 648 341 776 734 + Doom 3 + + 0 0 128 393 + 0 0 393 128 + + + + 20 84 68 373 + 84 20 289 48 + CD__ + 1 + Please insert the disc "Doom 3" or press Quit. + + + 20 20 68 68 + 20 20 48 48 + 1667523698 + 132 + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + 140 447 160 517 + 447 140 70 20 + OK + ok + 1 + + + 140 365 160 435 + 365 140 70 20 + Cancel + not! + 2 + + + 61 130 81 517 + 130 61 387 20 + CMDL + 2 + Always display this dialog at startup + + + 290 42 470 579 + <<<kGameName>>> + + 0 0 180 537 + 0 0 537 180 + + + 88 151 120 517 + 151 88 366 32 + TRUE + 1 + This dialog will always be displayed if the shift key is held down when the game starts. + + + + + 20 20 36 122 + 20 20 102 16 + Command Line: + + + 21 133 37 432 + 133 21 299 16 + CMDL + 1 + TRUE + TRUE + + + + 19 447 39 517 + 447 19 70 20 + CMDL + 3 + Revert + rvrt + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + 51 417 71 517 + 417 51 100 20 + WARN + 2 + Ignore This + IThs + Ignore all warnings and assertions in the future + Ignore all warnings and assertions in the future. This warning dialog wll no longer be displayed. + 2 + + + 0 0 187 537 + 0 0 537 187 + + + + 19 417 39 517 + 417 19 100 20 + WARN + 1 + Continue + Cont + Continue running the application + Continue running the application. If this same condition occurs again, you will be notified. + 1 + + + 20 20 84 84 + 20 20 64 64 + 0 + 0 + + + 20 92 140 409 + 92 20 317 120 + WARN + 6 + Message + + + 83 417 103 517 + 417 83 100 20 + WARN + 3 + Ignore All + IAll + Ignore all future warnings and assertions everywhere + Ignore all future warnings and assertions everywhere they occur. If this same condition occurs again, you will not be notified. + 2 + + + 115 417 135 517 + 417 115 100 20 + WARN + 4 + Debug + Debu + Drop into the debugger + 2 + + + 147 417 167 517 + 417 147 100 20 + WARN + 5 + Quit + Quit + Force Quit the applicatiion + 2 + + + 151 92 167 409 + 92 151 317 16 + WARN + 7 + TRUE + 1 + File and Line Number + + + + + 495 67 682 604 + <<<kGameName>>> Warning + + FALSE + FALSE + TRUE + TRUE + 2 + 7 + + + + + + + + + + + 0 0 380 600 + 0 0 600 380 + + + 44 20 320 580 + 20 44 560 276 + EULA + 1 + + 1 + 1 + 2 + 2 + + 2 + + + 340 496 360 580 + 496 340 84 20 + Agree + ok + + 2 + 2 + + 1 + + + 340 400 360 484 + 400 340 84 20 + Disagree + not! + + 2 + 2 + + 2 + + + 20 20 36 580 + 20 20 560 16 + EULA + 2 + 4 + End User License Agreement + + 1 + 2 + + + + + + + + 207 152 587 752 + License Agreement + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + 20 20 36 461 + 20 20 441 16 + TRUE + 1 + Doom 3 Registration Code: + + + 118 309 138 379 + 309 118 70 20 + Cancel + not! + 2 + + + 47 23 63 458 + 23 47 435 16 + RegC + 1 + TRUE + TRUE + + + 0 0 158 481 + 0 0 481 158 + + + + 74 20 102 461 + 20 74 441 28 + TRUE + 1 + Registration code is located on the back of your DVD case. The registration code will be of the form 'XXXXXXXXXXXXXXXX XX'. + + + + 118 391 138 461 + 391 118 70 20 + OK + ok + 1 + + + + + + + 449 235 607 716 + Doom 3 Registration + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Command Line + + Developer Alert + + EULA + + Files Owner + + Insert CD + + MenuBar + + Pick Monitor + + Preferences + + Reg Code Sheet + + + 378 + diff --git a/sys/osx/English.lproj/InfoPlist.strings b/sys/osx/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..ce8e78665 Binary files /dev/null and b/sys/osx/English.lproj/InfoPlist.strings differ diff --git a/sys/osx/English.lproj/Localizable.strings b/sys/osx/English.lproj/Localizable.strings new file mode 100644 index 000000000..c896f2821 Binary files /dev/null and b/sys/osx/English.lproj/Localizable.strings differ diff --git a/sys/osx/English.lproj/MainMenu.nib/classes.nib b/sys/osx/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 000000000..02a3fc42e --- /dev/null +++ b/sys/osx/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,7 @@ +{ + IBClasses = ( + {CLASS = DOOMController; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/sys/osx/English.lproj/MainMenu.nib/info.nib b/sys/osx/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 000000000..7243cee03 --- /dev/null +++ b/sys/osx/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 122 224 668 368 0 0 1280 1002 + IBEditorPositions + + 29 + 403 875 119 44 0 0 1280 1002 + + IBFramework Version + 364.0 + IBOpenObjects + + 29 + + IBSystem Version + 7M34 + + diff --git a/sys/osx/English.lproj/MainMenu.nib/objects.nib b/sys/osx/English.lproj/MainMenu.nib/objects.nib new file mode 100644 index 000000000..c9cadce09 Binary files /dev/null and b/sys/osx/English.lproj/MainMenu.nib/objects.nib differ diff --git a/sys/osx/English.lproj/locversion.plist b/sys/osx/English.lproj/locversion.plist new file mode 100644 index 000000000..d36912c55 --- /dev/null +++ b/sys/osx/English.lproj/locversion.plist @@ -0,0 +1,14 @@ + + + + + LprojCompatibleVersion + 116.2 + LprojLocale + en + LprojRevisionLevel + 1 + LprojVersion + 116.2 + + diff --git a/sys/osx/French.lproj/ASLCore.nib/classes.nib b/sys/osx/French.lproj/ASLCore.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/sys/osx/French.lproj/ASLCore.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/sys/osx/French.lproj/ASLCore.nib/info.nib b/sys/osx/French.lproj/ASLCore.nib/info.nib new file mode 100644 index 000000000..5e84c770c --- /dev/null +++ b/sys/osx/French.lproj/ASLCore.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 929 140 374 387 0 0 1680 1028 + IBEditorPositions + + 29 + 249 423 95 44 0 0 1680 1028 + + IBFramework Version + 364.0 + IBOldestOS + 3 + IBSystem Version + 7U16 + targetFramework + IBCarbonFramework + + diff --git a/sys/osx/French.lproj/ASLCore.nib/objects.xib b/sys/osx/French.lproj/ASLCore.nib/objects.xib new file mode 100644 index 000000000..64f0e89ec --- /dev/null +++ b/sys/osx/French.lproj/ASLCore.nib/objects.xib @@ -0,0 +1,701 @@ + + + IBCarbonFramework + + NSApplication + + + + SimpleHello + + + ASL Game + + ASL Game + + + À propos de <<<kGameName>>>... + 0 + abou + + + TRUE + + + TRUE + Préferences... + , + pref + + + TRUE + TRUE + + + TRUE + Mode plein écran + + Togg + + + TRUE + TRUE + + + _NSAppleMenu + + + + _NSMainMenu + + + + + + + + + + + 640 261 881 829 + Préférences de Doom 3 + + 0 0 241 568 + 0 0 568 241 + + + 6 20 221 272 + 20 6 252 215 + + + 36 50 102 126 + 30 30 76 66 + PREF + 1 + Fullscreen + Full + 256 + 3 + 1000 + 3 + + + 36 166 102 242 + 146 30 76 66 + PREF + 2 + In a Window + Wind + 256 + 3 + 1001 + 3 + + + 116 36 136 256 + 16 110 220 20 + PREF + 3 + Résolution : + Reso + -2 + + Popup: + + + TRUE + TRUE + 800 x 600 + + + TRUE + 1024 x 768 + + + TRUE + 1280 x 1024 + + + + + + 148 36 168 256 + 16 142 220 20 + PREF + 4 + Tx de rafraî. : + Refr + -2 + + Popup: + + + TRUE + TRUE + Automatique + + + TRUE + TRUE + + + + + + 189 36 205 161 + 16 183 125 16 + Écrans multiples : + -2 + + + 188 169 208 256 + 149 182 87 20 + PREF + 5 + Choisir... + Moni + + + Options de moniteur + + + 59 317 115 548 + 317 59 231 56 + TRUE + 1 + Ce dialogue apparaitra lorsque la touche Majuscule sera maintenue enfoncée lors du démarrage du jeu. + + + 201 396 221 466 + 396 201 70 20 + Annuler + not! + 2 + + + 201 478 221 548 + 478 201 70 20 + OK + ok + 1 + + + 20 296 51 548 + 296 20 252 31 + PREF + 6 + Toujours afficher ce dialogue au démarrage. + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + + + + + + + + + + + + + 256 318 276 388 + 318 256 70 20 + OK + ok + 1 + + + 366 175 662 583 + <<<kGameName>>> + + 0 0 296 408 + 0 0 408 296 + + + 6 20 236 388 + 20 6 368 230 + + + 36 36 220 372 + 16 30 336 184 + MONI + 1 + 32 + + + Choisissez un moniteur + + + 256 236 276 306 + 236 256 70 20 + Annuler + not! + 2 + + + + + FALSE + FALSE + TRUE + TRUE + 11 + 7 + + + + + + + 88 303 108 373 + 303 88 70 20 + Quitter + not! + 2 + + + 648 341 776 734 + Doom 3 + + 0 0 128 393 + 0 0 393 128 + + + + 20 84 68 373 + 84 20 289 48 + CD__ + 1 + Veuillez insérer le disque "DOOM 3" ou cliquez sur "Quitter". + + + 20 20 68 68 + 20 20 48 48 + 1667523698 + 132 + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + 140 447 160 517 + 447 140 70 20 + OK + ok + 1 + + + 140 365 160 435 + 365 140 70 20 + Annuler + not! + 2 + + + 61 130 81 517 + 130 61 387 20 + CMDL + 2 + Toujours afficher ce dialogue au démarrage + + + 290 42 470 579 + <<<kGameName>>> + + 0 0 180 537 + 0 0 537 180 + + + 88 151 120 517 + 151 88 366 32 + TRUE + 1 + Ce dialogue apparaitra lorsque la touche Majuscule sera maintenue enfoncée lors du démarrage du jeu. + + + + + 11 32 47 116 + 32 11 84 36 + Ligne de commande : + + + 21 133 37 432 + 133 21 299 16 + CMDL + 1 + TRUE + TRUE + + + + 19 447 39 517 + 447 19 70 20 + CMDL + 3 + Revenir + rvrt + + + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + 51 417 71 517 + 417 51 100 20 + WARN + 2 + Ignorer + IThs + Ignore all warnings and assertions in the future + Ignore all warnings and assertions in the future. This warning dialog wll no longer be displayed. + 2 + + + 0 0 187 537 + 0 0 537 187 + + + + 19 417 39 517 + 417 19 100 20 + WARN + 1 + Continuer + Cont + Continue running the application + Continue running the application. If this same condition occurs again, you will be notified. + 1 + + + 20 20 84 84 + 20 20 64 64 + 0 + 0 + + + 20 92 140 409 + 92 20 317 120 + WARN + 6 + Message + + + 83 417 103 517 + 417 83 100 20 + WARN + 3 + Tout ignorer + IAll + Ignore all future warnings and assertions everywhere + Ignore all future warnings and assertions everywhere they occur. If this same condition occurs again, you will not be notified. + 2 + + + 115 417 135 517 + 417 115 100 20 + WARN + 4 + Debogue + Debu + Drop into the debugger + 2 + + + 147 417 167 517 + 417 147 100 20 + WARN + 5 + Quitter + Quit + Force Quit the applicatiion + 2 + + + 151 92 167 409 + 92 151 317 16 + WARN + 7 + TRUE + 1 + Fichier et numéro de ligne + + + + + 495 67 682 604 + Alerte de <<<kGameName>>> + + FALSE + FALSE + TRUE + TRUE + 2 + 7 + + + + + + + + + + + 0 0 380 600 + 0 0 600 380 + + + 44 20 320 580 + 20 44 560 276 + EULA + 1 + + 1 + 1 + 2 + 2 + + 2 + + + 340 496 360 580 + 496 340 84 20 + Accepter + ok + + 2 + 2 + + 1 + + + 340 355 360 484 + 355 340 129 20 + Ne pas accepter + not! + + 2 + 2 + + 2 + + + 20 20 36 580 + 20 20 560 16 + EULA + 2 + 4 + Contrat de licence pour l'utilisateur final + + 1 + 2 + + + + + + + + 207 152 587 752 + License Agreement + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + 20 20 36 461 + 20 20 441 16 + TRUE + 1 + Code d'enregistrement de DOOM 3 : + + + 118 309 138 379 + 309 118 70 20 + Annuler + not! + 2 + + + 47 23 63 458 + 23 47 435 16 + RegC + 1 + TRUE + TRUE + + + 0 0 158 481 + 0 0 481 158 + + + + 74 20 102 461 + 20 74 441 28 + TRUE + 1 + Le code d'enregistrement est situé à l'arrière de la boîte du DVD. Le code d'enregistrement est de la forme 'XXXXXXXXXXXXXXXX XX'. + + + + 118 391 138 461 + 391 118 70 20 + OK + ok + 1 + + + + + + + 449 235 607 716 + Enregistrement de DOOM 3 + + FALSE + FALSE + TRUE + TRUE + 4 + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Command Line + + Developer Alert + + EULA + + Files Owner + + Insert CD + + MenuBar + + Pick Monitor + + Preferences + + Reg Code Sheet + + + 377 + diff --git a/sys/osx/French.lproj/InfoPlist.strings b/sys/osx/French.lproj/InfoPlist.strings new file mode 100644 index 000000000..0162d71c9 --- /dev/null +++ b/sys/osx/French.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Localized versions of Info.plist keys */ + +CFBundleName = "Doom 3"; +CFBundleShortVersionString = "1.1 b2847"; +CFBundleGetInfoString = "Doom 3 version 1.1 b2847, Copyright 2006 Id Software"; +NSHumanReadableCopyright = "Copyright 2006 Id Software"; diff --git a/sys/osx/French.lproj/Localizable.strings b/sys/osx/French.lproj/Localizable.strings new file mode 100644 index 000000000..c5555950d Binary files /dev/null and b/sys/osx/French.lproj/Localizable.strings differ diff --git a/sys/osx/French.lproj/MainMenu.nib/classes.nib b/sys/osx/French.lproj/MainMenu.nib/classes.nib new file mode 100644 index 000000000..02a3fc42e --- /dev/null +++ b/sys/osx/French.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,7 @@ +{ + IBClasses = ( + {CLASS = DOOMController; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/sys/osx/French.lproj/MainMenu.nib/info.nib b/sys/osx/French.lproj/MainMenu.nib/info.nib new file mode 100644 index 000000000..4b1066524 --- /dev/null +++ b/sys/osx/French.lproj/MainMenu.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 122 224 668 368 0 0 1280 1002 + IBEditorPositions + + 29 + 540 899 103 44 0 0 1680 1028 + + IBFramework Version + 364.0 + IBOpenObjects + + 29 + + IBSystem Version + 7W98 + + diff --git a/sys/osx/French.lproj/MainMenu.nib/objects.nib b/sys/osx/French.lproj/MainMenu.nib/objects.nib new file mode 100644 index 000000000..7d208f3e5 Binary files /dev/null and b/sys/osx/French.lproj/MainMenu.nib/objects.nib differ diff --git a/sys/osx/Info.plist b/sys/osx/Info.plist new file mode 100644 index 000000000..8260b7780 --- /dev/null +++ b/sys/osx/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Doom 3 + CFBundleIconFile + Doom3.icns + CFBundleIdentifier + com.idsoftware.doom3 + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + DOM3 + CFBundleVersion + 3000 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/sys/osx/PickMonitor.cpp b/sys/osx/PickMonitor.cpp new file mode 100644 index 000000000..e788ea6f8 --- /dev/null +++ b/sys/osx/PickMonitor.cpp @@ -0,0 +1,531 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#include +#include "PickMonitor.h" + +//==================================================================================== +// CONSTANTS +//==================================================================================== + +#define kMaxMonitors 16 + +//==================================================================================== +// TYPES +//==================================================================================== + +typedef struct +{ + GDHandle device; + Rect origRect; + Rect scaledRect; + int isMain; +} +Monitor; + + +//==================================================================================== +// GLOBALS +//==================================================================================== +static GDHandle sSelectedDevice; +static int sNumMonitors; +static Monitor sMonitors[kMaxMonitors]; + +static RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 }; +static RGBColor rgbWhite = { 0xffff, 0xffff, 0xffff }; +static RGBColor rgbGray = { 0x5252, 0x8A8A, 0xCCCC }; // this is the blue used in the Displays control panel + +//==================================================================================== +// MACROS +//==================================================================================== + +#undef PtInRect +#undef OffsetRect +#undef InsetRect +#undef EraseRect +#undef MoveTo +#undef LineTo + + +//==================================================================================== +// IMPLEMENTATION +//==================================================================================== + +//----------------------------------------------------------------------------- +// SetupUserPaneProcs +//----------------------------------------------------------------------------- +// Call this to initialize the specified user pane control before displaying +// the dialog window. Pass NULL for any user pane procs you don't need to install. + +OSErr SetupUserPaneProcs( ControlRef inUserPane, + ControlUserPaneDrawProcPtr inDrawProc, + ControlUserPaneHitTestProcPtr inHitTestProc, + ControlUserPaneTrackingProcPtr inTrackingProc) +{ + OSErr err = noErr; + ControlUserPaneDrawUPP drawUPP; + ControlUserPaneHitTestUPP hitTestUPP; + ControlUserPaneTrackingUPP trackingUPP; + + if (0 == inUserPane) return paramErr; + + if (inDrawProc && noErr == err) + { + drawUPP = NewControlUserPaneDrawUPP(inDrawProc); + + if (0 == drawUPP) + err = memFullErr; + else + err = SetControlData( inUserPane, + kControlEntireControl, + kControlUserPaneDrawProcTag, + sizeof(ControlUserPaneDrawUPP), + (Ptr)&drawUPP); + } + if (inHitTestProc && noErr == err) + { + hitTestUPP = NewControlUserPaneHitTestUPP(inHitTestProc); + + if (0 == hitTestUPP) + err = memFullErr; + else + err = SetControlData( inUserPane, + kControlEntireControl, + kControlUserPaneHitTestProcTag, + sizeof(ControlUserPaneHitTestUPP), + (Ptr)&hitTestUPP); + } + if (inTrackingProc && noErr == err) + { + trackingUPP = NewControlUserPaneTrackingUPP(inTrackingProc); + + if (0 == trackingUPP) + err = memFullErr; + else + err = SetControlData( inUserPane, + kControlEntireControl, + kControlUserPaneTrackingProcTag, + sizeof(ControlUserPaneTrackingUPP), + (Ptr)&trackingUPP); + } + + return err; +} + + +//----------------------------------------------------------------------------- +// DisposeUserPaneProcs +//----------------------------------------------------------------------------- +// Call this to clean up when you're done with the specified user pane control. + +OSErr DisposeUserPaneProcs(ControlRef inUserPane) +{ + ControlUserPaneDrawUPP drawUPP; + ControlUserPaneHitTestUPP hitTestUPP; + ControlUserPaneTrackingUPP trackingUPP; + Size actualSize; + OSErr err; + + err = GetControlData(inUserPane, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(ControlUserPaneDrawUPP), (Ptr)&drawUPP, &actualSize); + if (err == noErr) DisposeControlUserPaneDrawUPP(drawUPP); + + err = GetControlData(inUserPane, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(ControlUserPaneHitTestUPP), (Ptr)&hitTestUPP, &actualSize); + if (err == noErr) DisposeControlUserPaneHitTestUPP(hitTestUPP); + + err = GetControlData(inUserPane, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(ControlUserPaneTrackingUPP), (Ptr)&trackingUPP, &actualSize); + if (err == noErr) DisposeControlUserPaneTrackingUPP(trackingUPP); + + return noErr; +} + +#pragma mark - + +//----------------------------------------------------------------------------- +// drawProc +//----------------------------------------------------------------------------- +// Custom drawProc for our UserPane control. + +static pascal void drawProc(ControlRef inControl, SInt16 inPart) +{ + #pragma unused(inControl, inPart) + + int i; + RGBColor saveForeColor; + RGBColor saveBackColor; + PenState savePenState; + + GetForeColor(&saveForeColor); + GetBackColor(&saveBackColor); + GetPenState(&savePenState); + + RGBForeColor(&rgbBlack); + RGBBackColor(&rgbWhite); + PenNormal(); + + for (i = 0; i < sNumMonitors; i++) + { + RGBForeColor(&rgbGray); + PaintRect(&sMonitors[i].scaledRect); + if (sMonitors[i].isMain) + { + Rect r = sMonitors[i].scaledRect; + InsetRect(&r, 1, 1); + r.bottom = r.top + 6; + RGBForeColor(&rgbWhite); + PaintRect(&r); + RGBForeColor(&rgbBlack); + PenSize(1,1); + MoveTo(r.left, r.bottom); + LineTo(r.right, r.bottom); + } + if (sMonitors[i].device == sSelectedDevice) + { + PenSize(3,3); + RGBForeColor(&rgbBlack); + FrameRect(&sMonitors[i].scaledRect); + } + else + { + PenSize(1,1); + RGBForeColor(&rgbBlack); + FrameRect(&sMonitors[i].scaledRect); + } + } + + // restore the original pen state and colors + RGBForeColor(&saveForeColor); + RGBBackColor(&saveBackColor); + SetPenState(&savePenState); +} + + +//----------------------------------------------------------------------------- +// hitTestProc +//----------------------------------------------------------------------------- +// Custom hitTestProc for our UserPane control. +// This allows FindControlUnderMouse() to locate our control, which allows +// ModalDialog() to call TrackControl() or HandleControlClick() for our control. + +static pascal ControlPartCode hitTestProc(ControlRef inControl, Point inWhere) +{ + // return a valid part code so HandleControlClick() will be called + return kControlButtonPart; +} + + +//----------------------------------------------------------------------------- +// trackingProc +//----------------------------------------------------------------------------- +// Custom trackingProc for our UserPane control. +// This won't be called for our control unless the kControlHandlesTracking feature +// bit is specified when the userPane is created. + +static pascal ControlPartCode trackingProc ( + ControlRef inControl, + Point inStartPt, + ControlActionUPP inActionProc) +{ + #pragma unused (inControl, inStartPt, inActionProc) + int i; + + for (i = 0; i < sNumMonitors; i++) + { + if (PtInRect(inStartPt, &sMonitors[i].scaledRect)) + { + if (sMonitors[i].device != sSelectedDevice) + { + sSelectedDevice = sMonitors[i].device; + DrawOneControl(inControl); + } + break; + } + } + + return kControlNoPart; +} + + +#pragma mark - + + +//----------------------------------------------------------------------------- +// SetupPickMonitorPane +//----------------------------------------------------------------------------- +// Call this to initialize the user pane control that is the Pick Monitor +// control. Pass the ControlRef of the user pane control and a display ID +// for the monitor you want selected by default (pass 0 for the main monitor). +// Call this function before displaying the dialog window. + +OSErr SetupPickMonitorPane(ControlRef inPane, DisplayIDType inDefaultMonitor) +{ + GDHandle dev = GetDeviceList(); + OSErr err = noErr; + + // make the default monitor the selected device + if (inDefaultMonitor) + DMGetGDeviceByDisplayID(inDefaultMonitor, &sSelectedDevice, true); + else + sSelectedDevice = GetMainDevice(); + + // build the list of monitors + sNumMonitors = 0; + while (dev && sNumMonitors < kMaxMonitors) + { + if (TestDeviceAttribute(dev, screenDevice) && TestDeviceAttribute(dev, screenActive)) + { + sMonitors[sNumMonitors].device = dev; + sMonitors[sNumMonitors].origRect = (**dev).gdRect; + sMonitors[sNumMonitors].isMain = (dev == GetMainDevice()); + sNumMonitors++; + } + dev = GetNextDevice(dev); + } + + // calculate scaled rects + if (sNumMonitors) + { + Rect origPaneRect, paneRect; + Rect origGrayRect, grayRect, scaledGrayRect; + float srcAspect, dstAspect, scale; + int i; + + GetControlBounds(inPane, &origPaneRect); + paneRect = origPaneRect; + OffsetRect(&paneRect, -paneRect.left, -paneRect.top); + + GetRegionBounds(GetGrayRgn(), &origGrayRect); + grayRect = origGrayRect; + OffsetRect(&grayRect, -grayRect.left, -grayRect.top); + + srcAspect = (float)grayRect.right / (float)grayRect.bottom; + dstAspect = (float)paneRect.right / (float)paneRect.bottom; + + scaledGrayRect = paneRect; + + if (srcAspect < dstAspect) + { + scaledGrayRect.right = (float)paneRect.bottom * srcAspect; + scale = (float)scaledGrayRect.right / grayRect.right; + } + else + { + scaledGrayRect.bottom = (float)paneRect.right / srcAspect; + scale = (float)scaledGrayRect.bottom / grayRect.bottom; + } + + for (i = 0; i < sNumMonitors; i++) + { + Rect r = sMonitors[i].origRect; + Rect r2 = r; + + // normalize rect and scale + OffsetRect(&r, -r.left, -r.top); + r.bottom = (float)r.bottom * scale; + r.right = (float)r.right * scale; + + // offset rect wrt gray region + OffsetRect(&r, (float)(r2.left - origGrayRect.left) * scale, + (float)(r2.top - origGrayRect.top) * scale); + + sMonitors[i].scaledRect = r; + } + + // center scaledGrayRect in the pane + OffsetRect(&scaledGrayRect, (paneRect.right - scaledGrayRect.right) / 2, + (paneRect.bottom - scaledGrayRect.bottom) / 2); + + // offset monitors to match + for (i = 0; i < sNumMonitors; i++) + OffsetRect(&sMonitors[i].scaledRect, scaledGrayRect.left, scaledGrayRect.top); + } + else + return paramErr; + + // setup the procs for the pick monitor user pane + err = SetupUserPaneProcs(inPane, drawProc, hitTestProc, trackingProc); + return err; +} + + +//----------------------------------------------------------------------------- +// TearDownPickMonitorPane +//----------------------------------------------------------------------------- +// Disposes of everything associated with the Pick Monitor pane. You should +// call this when disposing the dialog. + +OSErr TearDownPickMonitorPane(ControlRef inPane) +{ + OSErr err; + err = DisposeUserPaneProcs(inPane); + sNumMonitors = 0; + return err; +} + +#pragma mark - + +//------------------------------------------------------------------------------------ +// ¥ PickMonitorHandler +//------------------------------------------------------------------------------------ +// Our command handler for the PickMonitor dialog. + +static pascal OSStatus PickMonitorHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* inUserData ) +{ + #pragma unused( inHandler ) + + HICommand cmd; + OSStatus result = eventNotHandledErr; + WindowRef theWindow = (WindowRef)inUserData; + + // The direct object for a 'process commmand' event is the HICommand. + // Extract it here and switch off the command ID. + + GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( cmd ), NULL, &cmd ); + + switch ( cmd.commandID ) + { + case kHICommandOK: + QuitAppModalLoopForWindow( theWindow ); + result = noErr; + break; + + case kHICommandCancel: + // Setting sSelectedDevice to zero will signal that the user cancelled. + sSelectedDevice = 0; + QuitAppModalLoopForWindow( theWindow ); + result = noErr; + break; + + } + return result; +} + + +#pragma mark - + +//----------------------------------------------------------------------------- +// CanUserPickMonitor +//----------------------------------------------------------------------------- +// Returns true if more than one monitor is available to choose from. + +Boolean CanUserPickMonitor (void) +{ + GDHandle dev = GetDeviceList(); + OSErr err = noErr; + int numMonitors; + + // build the list of monitors + numMonitors = 0; + while (dev && numMonitors < kMaxMonitors) + { + if (TestDeviceAttribute(dev, screenDevice) && TestDeviceAttribute(dev, screenActive)) + { + numMonitors++; + } + dev = GetNextDevice(dev); + } + + if (numMonitors > 1) return true; + else return false; +} + +//----------------------------------------------------------------------------- +// PickMonitor +//----------------------------------------------------------------------------- +// Prompts for a monitor. Returns userCanceledErr if the user cancelled. + +OSStatus PickMonitor (DisplayIDType *inOutDisplayID, WindowRef parentWindow) +{ + WindowRef theWindow; + OSStatus status = noErr; + static const ControlID kUserPane = { 'MONI', 1 }; + + // Fetch the dialog + + IBNibRef aslNib; + CFBundleRef theBundle = CFBundleGetMainBundle(); + status = CreateNibReferenceWithCFBundle(theBundle, CFSTR("ASLCore"), &aslNib); + status = ::CreateWindowFromNib(aslNib, CFSTR( "Pick Monitor" ), &theWindow ); + if (status != noErr) + { + assert(false); + return userCanceledErr; + } + +#if 0 + // Put game name in window title. By default the title includes the token <<>>. + + Str255 windowTitle; + GetWTitle(theWindow, windowTitle); + FormatPStringWithGameName(windowTitle); + SetWTitle(theWindow, windowTitle); +#endif + + // Set up the controls + + ControlRef monitorPane; + GetControlByID( theWindow, &kUserPane, &monitorPane ); + assert(monitorPane); + + SetupPickMonitorPane(monitorPane, *inOutDisplayID); + + // Create our UPP and install the handler. + + EventTypeSpec cmdEvent = { kEventClassCommand, kEventCommandProcess }; + EventHandlerUPP handler = NewEventHandlerUPP( PickMonitorHandler ); + InstallWindowEventHandler( theWindow, handler, 1, &cmdEvent, theWindow, NULL ); + + // Show the window + + if (parentWindow) + ShowSheetWindow( theWindow, parentWindow ); + else + ShowWindow( theWindow ); + + // Now we run modally. We will remain here until the PrefHandler + // calls QuitAppModalLoopForWindow if the user clicks OK or + // Cancel. + + RunAppModalLoopForWindow( theWindow ); + + // OK, we're done. Dispose of our window and our UPP. + // We do the UPP last because DisposeWindow can send out + // CarbonEvents, and we haven't explicitly removed our + // handler. If we disposed the UPP, the Toolbox might try + // to call it. That would be bad. + + TearDownPickMonitorPane(monitorPane); + if (parentWindow) + HideSheetWindow( theWindow ); + DisposeWindow( theWindow ); + DisposeEventHandlerUPP( handler ); + + // Return settings to caller + + if (sSelectedDevice != 0) + { + // Read back the controls + DMGetDisplayIDByGDevice (sSelectedDevice, &*inOutDisplayID, true); + return noErr; + } + else + return userCanceledErr; + +} + diff --git a/sys/osx/PickMonitor.h b/sys/osx/PickMonitor.h new file mode 100644 index 000000000..234774250 --- /dev/null +++ b/sys/osx/PickMonitor.h @@ -0,0 +1,26 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef PICKMONITOR_H +#define PICKMONITOR_H + +OSStatus PickMonitor (DisplayIDType *inOutDisplayID, WindowRef parentWindow); +Boolean CanUserPickMonitor (void); + +#endif // PICKMONITOR_H diff --git a/sys/osx/PreferencesDialog.cpp b/sys/osx/PreferencesDialog.cpp new file mode 100644 index 000000000..b27022ac1 --- /dev/null +++ b/sys/osx/PreferencesDialog.cpp @@ -0,0 +1,835 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#include +#include "PreferencesDialog.h" +#include "PickMonitor.h" +#include +#include + +static idCVar r_stretched( "r_stretched", "0", CVAR_ARCHIVE | CVAR_BOOL, "Used stretched resolution" ); + +#define kPref_PrefsDialogAlways CFSTR("PrefsDialogAlways") +#define kPref_PrefsDialogOpenAL CFSTR("UseOpenAL") + +#ifndef kAppCreator +#define kAppCreator 'DOM3' // Creator type +#endif + +const UInt32 kRes_Stretched = (1 << 0); // set if the resolution is a stretched mode (kCGDisplayModeIsStretched) +const UInt32 kRes_Safe = (1 << 1); // ¥¥¥Ê(currently unused) set if the resolution is safe (kCGDisplayModeIsSafeForHardware) + +// Data to be presented and edited in the prefs dialog +struct PrefInfo +{ + // prefs values + GameDisplayMode prefGameDisplayMode; + CGDirectDisplayID prefDisplayID; + int prefWidth; + int prefHeight; + int prefDepth; + Fixed prefFrequency; + UInt32 prefResFlags; + Boolean prefAlways; + Boolean prefOpenAL; + + bool okPressed; // Set to true if the user pressed the OK button + + // The following are private data passed from GameDisplayPreferencesDialog() to it's command handler. + WindowRef window; + ControlRef fullscreenBtn; + ControlRef inAWindowBtn; + ControlRef resolutionPopup; + ControlRef refreshRatePopup; + ControlRef chooseMonitorsBtn; + ControlRef alwaysBtn; + ControlRef openALBtn; + + ValidModeCallbackProc callback; // To validate display modes + + bool multiMonitor; // Does user have multiple monitors + std::list refreshRates; // List of refresh rates available for the selected monitor + SInt32 freqMenuIndex; +}; + + +#pragma mark - + +bool R_GetModeInfo( int *width, int *height, int mode ); + +static int GetScreenIndexForDisplayID( CGDirectDisplayID inDisplayID ) { + unsigned int i; + OSErr err; + int r_screen = -1; + CGDisplayCount count; + + err = CGGetActiveDisplayList(0, NULL, &count); + if (noErr == err) { + CGDirectDisplayID displays[count]; + err = CGGetActiveDisplayList(count, displays, &count); + if (noErr == err) { + for ( i = 0; i < count; i++) + if (displays[i] == inDisplayID) + r_screen = i; + } + } + return r_screen; +} + +static CGDirectDisplayID GetDisplayIDForScreenIndex( int inScreenIndex ) { + OSErr err; + int r_screen = -1; + CGDisplayCount count; + + err = CGGetActiveDisplayList(0, NULL, &count); + if (noErr == err) { + CGDirectDisplayID displays[count]; + err = CGGetActiveDisplayList(count, displays, &count); + if (noErr == err) { + if ( inScreenIndex >= 0 && inScreenIndex <= count ) + return displays[inScreenIndex]; + } + } + return (CGDirectDisplayID)r_screen; +} + + + +void Sys_DoPreferences( void ) { + + // An NSKeyDown event is not fired if the user holds down Cmd during startup. + // Cmd is treated purely as a modifier. To capture the user + // holding down Cmd, you would need to override NSApplication's + // keydown handler. That's overkill for a single check at + // startup, use the Carbon GetKeys approach. + unsigned char km[16]; + const int kMacKeyCodeCommand = 0x37; + KeyMap *keymap = (KeyMap*)&km; + GetKeys(*keymap); + + Boolean prefAways, keyFound, useOpenAL; + prefAways = CFPreferencesGetAppBooleanValue ( kPref_PrefsDialogAlways, kCFPreferencesCurrentApplication, &keyFound ); + bool fAlways = prefAways && keyFound; + + if ( fAlways || ( km[kMacKeyCodeCommand>>3] >> ( kMacKeyCodeCommand & 7 ) ) & 1 ) { + GameDisplayInfo info; + info.mode = cvarSystem->GetCVarBool( "r_fullscreen" ) ? kFullScreen : kWindow; + info.displayID = GetDisplayIDForScreenIndex( cvarSystem->GetCVarInteger( "r_screen" ) ); + + int w = 800, h = 600; + R_GetModeInfo( &w, &h, cvarSystem->GetCVarInteger( "r_mode" ) ); + info.width = w; + info.height = h; + info.depth = 32; + info.frequency = cvarSystem->GetCVarInteger( "r_maxDisplayRefresh" ); + info.windowLoc.x = 0; + info.windowLoc.y = 0; + info.flags = 0; + info.resFlags = 0; + if ( r_stretched.GetBool() ) + info.resFlags |= kRes_Stretched; + + WindowRef prefWindow; + if ( CreateGameDisplayPreferencesDialog( &info, &prefWindow ) == noErr ) { + if ( RunGameDisplayPreferencesDialog( &info, prefWindow ) == noErr ) { + cvarSystem->SetCVarBool( "r_fullscreen", info.mode == kFullScreen ); + + int i = 0; + int r_mode = -1; + while ( r_mode == -1 && R_GetModeInfo( &w, &h, i ) ) { + if ( w == info.width && h == info.height ) + r_mode = i; + i++; + } + cvarSystem->SetCVarInteger( "r_mode", r_mode ); + if ( r_mode == -1 ) { + cvarSystem->SetCVarInteger( "r_customWidth", info.width ); + cvarSystem->SetCVarInteger( "r_customHeight", info.height ); + } + + float r = (float) info.width / (float) info.height; + if ( r > 1.7f ) + cvarSystem->SetCVarInteger( "r_aspectRatio", 1 ); // 16:9 + else if ( r > 1.55f ) + cvarSystem->SetCVarInteger( "r_aspectRatio", 2 ); // 16:10 + else + cvarSystem->SetCVarInteger( "r_aspectRatio", 0 ); // 4:3 + + r_stretched.SetBool( info.resFlags & kRes_Stretched ); + cvarSystem->SetCVarInteger( "r_screen", GetScreenIndexForDisplayID( info.displayID ) ); + cvarSystem->SetCVarInteger( "r_minDisplayRefresh", (int)FixedToFloat( info.frequency ) ); + cvarSystem->SetCVarInteger( "r_maxDisplayRefresh", (int)FixedToFloat( info.frequency ) ); + } + else { + Sys_Quit(); + } + } + } + useOpenAL = CFPreferencesGetAppBooleanValue (kPref_PrefsDialogOpenAL, kCFPreferencesCurrentApplication, &keyFound); + if ( keyFound && useOpenAL ) { + cvarSystem->SetCVarInteger( "com_asyncSound", 1 ); + cvarSystem->SetCVarInteger( "s_useOpenAL", 1 ); + } + else { + cvarSystem->SetCVarInteger( "com_asyncSound", 2 ); + cvarSystem->SetCVarInteger( "s_useOpenAL", 0 ); + } +} + + +#pragma mark - + +#define EnablePopupMenuItem(inControl,inMenuItem) EnableMenuItem(GetControlPopupMenuRef(inControl),inMenuItem) +#define DisablePopupMenuItem(inControl,inMenuItem) DisableMenuItem(GetControlPopupMenuRef(inControl),inMenuItem) +#define IsPopupMenuItemEnabled(inControl,inMenuItem) IsMenuItemEnabled(GetControlPopupMenuRef(inControl),inMenuItem) + +// Command IDs used in the NIB file +enum +{ + kCmdFullscreen = 'Full', + kCmdInAWindow = 'Wind', + kCmdResolution = 'Reso', + kCmdRefreshRate = 'Refr', + kCmdChooseMonitors = 'Moni', +}; + +// Control IDs used in the NIB file +static const ControlID kFullscreenBtn = { 'PREF', 1 }; +static const ControlID kInAWindowBtn = { 'PREF', 2 }; +static const ControlID kResolutionPopup = { 'PREF', 3 }; +static const ControlID kRefreshRatePopup = { 'PREF', 4 }; +static const ControlID kChooseMonitorsBtn = { 'PREF', 5 }; +static const ControlID kAlwaysBtn = { 'PREF', 6 }; +static const ControlID kOpenALBtn = { 'PREF', 7 }; + +struct Res +{ + int width; + int height; + int depth; + UInt32 resFlags; +}; + +static bool operator< (const Res& a, const Res& b) +{ + if (a.width == b.width) + { + if (a.height == b.height) + { + if (a.resFlags == b.resFlags) + { + return (a.depth < b.depth); + } + return (a.resFlags < b.resFlags); + } + return (a.height < b.height); + } + return (a.width < b.width); +} + +inline Res MakeRes(int width, int height, int depth) +{ + Res temp = { width, height, depth, 0 }; + return temp; +} + +inline Res MakeRes(int width, int height, int depth, UInt32 resFlags) +{ + Res temp = { width, height, depth, resFlags }; + return temp; +} + +static bool ValidDisplayID (CGDirectDisplayID inDisplayID) +{ + unsigned int i; + CGDisplayErr err; + CGDisplayCount count; + + err = CGGetActiveDisplayList(0, NULL, &count); + if (noErr == err) + { + CGDirectDisplayID displays[count]; + err = CGGetActiveDisplayList(count, displays, &count); + if (noErr == err) + { + for ( i = 0; i < count; i++) + if (displays[i] == inDisplayID) + return true; + } + } + return false; +} + +static int BuildResolutionList(CGDirectDisplayID inDisplayID, Res *ioList, ValidModeCallbackProc inCallback) +{ + std::set modes; + int i, total = 0; + + if (inDisplayID == (CGDirectDisplayID)-1) // special case, not associated with any display + { + Res stdModes[] = { { 640, 480 }, { 800, 600 }, { 1024, 768 }, { 1152, 768 }, + { 1280, 854 }, { 1280, 960 }, { 1280, 1024 }, { 1440, 900 } }; + total = sizeof(stdModes) / sizeof(Res); + for (i = 0; i < total; i++) + { + if (inCallback == NULL || inCallback(inDisplayID, stdModes[i].width, stdModes[i].height, 32, 0)) + modes.insert( MakeRes(stdModes[i].width, stdModes[i].height, 32) ); + } + } + else + { + CGDirectDisplayID displayID = inDisplayID ? inDisplayID : kCGDirectMainDisplay; + CFArrayRef modeArrayRef = CGDisplayAvailableModes(displayID); + CFIndex numModes = CFArrayGetCount(modeArrayRef); + + for (i = 0; i < numModes; i++) + { + CFDictionaryRef modeRef = (CFDictionaryRef)CFArrayGetValueAtIndex(modeArrayRef, i); + + long value = 0; + CFNumberRef valueRef; + Boolean success; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayBitsPerPixel); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int depth = value; + if (depth != 32) continue; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayWidth); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int width = value; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayHeight); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int height = value; + + UInt32 resFlags = 0; + CFBooleanRef boolRef; + if (CFDictionaryGetValueIfPresent (modeRef, kCGDisplayModeIsStretched, (const void **)&boolRef)) + if (CFBooleanGetValue (boolRef)) + resFlags |= kRes_Stretched; + + + if (inCallback) + success = inCallback(displayID, width, height, depth, 0); + else + success = true; + + if (success) + modes.insert(MakeRes(width, height, depth, resFlags)); + } + } + + total = modes.size(); + + if (ioList) + { + std::set::iterator it = modes.begin(); + for (i = 0; it != modes.end(); i++) + ioList[i] = *it++; + } + + return total; +} + + + + +static void BuildRefreshRates(CGDirectDisplayID inDisplayID, int inWidth, int inHeight, std::list* inList, ValidModeCallbackProc inCallback) +{ + CGDirectDisplayID displayID = inDisplayID ? inDisplayID : kCGDirectMainDisplay; + + CFArrayRef modeArrayRef = CGDisplayAvailableModes(displayID); + CFIndex numModes = CFArrayGetCount(modeArrayRef); + + inList->clear(); + + for (int i = 0; i < numModes; i++) + { + CFDictionaryRef modeRef = (CFDictionaryRef)CFArrayGetValueAtIndex(modeArrayRef, i); + + long value = 0; + CFNumberRef valueRef; + Boolean success; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayBitsPerPixel); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int depth = value; + if (depth != 32) continue; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayWidth); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int width = value; + + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayHeight); + success = CFNumberGetValue(valueRef, kCFNumberLongType, &value); + int height = value; + + if (width == inWidth && height == inHeight) + { + double freqDouble; + valueRef = (CFNumberRef)CFDictionaryGetValue(modeRef, kCGDisplayRefreshRate); + success = CFNumberGetValue(valueRef, kCFNumberDoubleType, &freqDouble); + Fixed freq = FloatToFixed(freqDouble); + if (inCallback) + success = inCallback(displayID, width, height, depth, freq); + else + success = true; + if (success) + inList->push_back(freq); + } + } + + // Disallow 0, which we reserve to mean "automatic" + inList->remove(0); + + inList->sort(); + + // Remove duplicates - yes they can occur. + inList->unique(); +} + +static void BuildRefreshPopupButton(ControlRef inControl, std::list* inList) +{ + MenuRef menu = GetControlPopupMenuRef(inControl); + assert(menu); + if (!menu) return; + + // The menu has two permanent items - "Auto" & a divider line. Delete everything else. + DeleteMenuItems(menu, 3, CountMenuItems(menu)-2); + + for (std::list::const_iterator iter = inList->begin(); iter != inList->end(); ++iter) + { + float value = FixedToFloat(*iter); + CFStringRef menuString = CFStringCreateWithFormat (kCFAllocatorDefault, 0, CFSTR("%g Hz"), value); + InsertMenuItemTextWithCFString(menu, menuString, CountMenuItems(menu), 0, 0); + } + + SetControlMaximum(inControl, CountMenuItems(menu)); +} + +static SInt32 FindRefreshPopupMenuItem(std::list* inList, Fixed inFrequency) +{ + SInt32 index = 3; // skip over the "Auto" and divider ine + for (std::list::const_iterator iter = inList->begin(); iter != inList->end(); ++iter) + { + if (*iter == inFrequency) + return index; + index++; + } + return 1; // Return the "Automatic" item if we didn't find a match +} + +static void BuildResolutionPopupButton(ControlRef inControl, CGDirectDisplayID inDisplayID, ValidModeCallbackProc inCallback) +{ + // Get the list of valid resolutions + int count = BuildResolutionList(inDisplayID, NULL, inCallback); + Res resList[count]; + BuildResolutionList(inDisplayID, resList, inCallback); + + // Clear the menu + MenuRef menu = GetControlPopupMenuRef(inControl); + assert(menu); + if (!menu) return; + DeleteMenuItems(menu, 1, CountMenuItems(menu)); + + OSStatus err; + + while (count--) + { + CFStringRef menuString = CFStringCreateWithFormat (kCFAllocatorDefault, 0, CFSTR("%d x %d %@"), + resList[count].width, resList[count].height, (resList[count].resFlags & kRes_Stretched) ? CFSTR("(Stretched)") : CFSTR("")); + InsertMenuItemTextWithCFString (menu, menuString, 0, 0, 0); + err = SetMenuItemProperty (menu, 1, kAppCreator, 'Res ', sizeof(resList[count]), &resList[count]); + } + + SetControlMaximum(inControl, CountMenuItems(menu)); +} + +static void GetResolutionFromPopupMenuItem(ControlRef inControl, MenuItemIndex inItem, int *outX, int *outY, int *outDepth, UInt32 *outResFlags) +{ + MenuRef menu = GetControlPopupMenuRef(inControl); + Res res; + OSStatus err; + + err = GetMenuItemProperty (menu, inItem, kAppCreator, 'Res ', sizeof(res), NULL, &res); + if (!err) + { + *outX = res.width; + *outY = res.height; + *outResFlags = res.resFlags; + *outDepth = 32; + } +} + +static void AdjustResolutionPopupMenu(ControlRef inControl, CGDirectDisplayID inDisplayID, bool isFullscreen, int& screenwidth, int& screenheight, int& screendepth, UInt32& screenResFlags) +{ + int screenX = INT_MAX, screenY = INT_MAX; + + // In windowed mode, you have to disable resolutions that are larger than the current screen size + if (!isFullscreen) + { + screenX = (int)CGDisplayPixelsWide(inDisplayID); + screenY = (int)CGDisplayPixelsHigh(inDisplayID); + } + + MenuRef menu = GetControlPopupMenuRef(inControl); + int resX, resY, depth; + UInt32 resFlags; + int count = CountMenuItems(menu); + int item; + + for( item = 1; item <= count; item++) + { + GetResolutionFromPopupMenuItem(inControl, item, &resX, &resY, &depth, &resFlags); + + if (screenX < resX || screenY < resY) + DisablePopupMenuItem(inControl, item); + else + EnablePopupMenuItem(inControl, item); + + if (resX == screenwidth && resY == screenheight && depth == screendepth && resFlags == screenResFlags) + SetControlValue(inControl, item); + } + + // If we just disabled the current item, then choose something else. + if (!IsPopupMenuItemEnabled(inControl, GetControlValue (inControl))) + { + for(item = 1; item <= count; item++) + { + if (IsPopupMenuItemEnabled(inControl, item)) + { + SetControlValue(inControl, item); + GetResolutionFromPopupMenuItem(inControl, item, &screenwidth, &screenheight, &screendepth, &screenResFlags); + break; + } + } + } +} + +static void AdjustDisplayControls(PrefInfo *prefInfo) +{ + // Build new resolution popup and select appropriate resolution + if ((prefInfo->prefGameDisplayMode != kFullScreen)) + { + BuildResolutionPopupButton(prefInfo->resolutionPopup, (CGDirectDisplayID)-1, prefInfo->callback); + if (prefInfo->multiMonitor) + EnableControl(prefInfo->chooseMonitorsBtn); + } + else + { + BuildResolutionPopupButton(prefInfo->resolutionPopup, prefInfo->prefDisplayID, prefInfo->callback); + if (prefInfo->multiMonitor) + EnableControl(prefInfo->chooseMonitorsBtn); + } + AdjustResolutionPopupMenu(prefInfo->resolutionPopup, prefInfo->prefDisplayID, + prefInfo->prefGameDisplayMode == kFullScreen, + prefInfo->prefWidth, prefInfo->prefHeight, prefInfo->prefDepth, prefInfo->prefResFlags); + + // Build new refresh popup and select appropriate rate + BuildRefreshRates(prefInfo->prefDisplayID, prefInfo->prefWidth, prefInfo->prefHeight, + &prefInfo->refreshRates, prefInfo->callback); + BuildRefreshPopupButton(prefInfo->refreshRatePopup, &prefInfo->refreshRates); + + if (prefInfo->refreshRates.size() == 0) + { // No refresh rates, so pick Auto + prefInfo->freqMenuIndex = 1; + prefInfo->prefFrequency = 0; + } + else + { + prefInfo->freqMenuIndex = FindRefreshPopupMenuItem(&prefInfo->refreshRates, prefInfo->prefFrequency); + if (prefInfo->freqMenuIndex == 1) + prefInfo->prefFrequency = 0; // just in case FindRefreshPopupMenuItem didn't find prefInfo->prefFrequency + } + SetControlValue (prefInfo->refreshRatePopup, prefInfo->freqMenuIndex); + + // Disable refresh rate if NOT fullscreen + if ((prefInfo->prefGameDisplayMode != kFullScreen) || (prefInfo->refreshRates.size() == 0)) + DisableControl (prefInfo->refreshRatePopup); + else + EnableControl (prefInfo->refreshRatePopup); +} + +#pragma mark - + +static pascal OSStatus PrefHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* inUserData ) +{ + #pragma unused( inHandler ) + + HICommand cmd; + OSStatus result = eventNotHandledErr; + PrefInfo* prefInfo = (PrefInfo*)inUserData; + + // The direct object for a 'process commmand' event is the HICommand. + // Extract it here and switch off the command ID. + + GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( cmd ), NULL, &cmd ); + + switch ( cmd.commandID ) + { + case kHICommandOK: + + prefInfo->okPressed = true; + + prefInfo->prefAlways = GetControlValue (prefInfo->alwaysBtn); + prefInfo->prefOpenAL = GetControlValue (prefInfo->openALBtn); + + CFPreferencesSetAppValue (kPref_PrefsDialogAlways, + prefInfo->prefAlways ? kCFBooleanTrue : kCFBooleanFalse, + kCFPreferencesCurrentApplication); + + CFPreferencesSetAppValue (kPref_PrefsDialogOpenAL, + prefInfo->prefOpenAL ? kCFBooleanTrue : kCFBooleanFalse, + kCFPreferencesCurrentApplication); + + CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication); + + QuitAppModalLoopForWindow( prefInfo->window ); + result = noErr; + break; + + case kHICommandCancel: + + prefInfo->okPressed = false; + + QuitAppModalLoopForWindow( prefInfo->window ); + result = noErr; + break; + + case kCmdFullscreen: + case kCmdInAWindow: + if (cmd.commandID == kCmdFullscreen) + prefInfo->prefGameDisplayMode = kFullScreen; + else + prefInfo->prefGameDisplayMode = kWindow; + SetControlValue (prefInfo->fullscreenBtn, prefInfo->prefGameDisplayMode == kFullScreen); + SetControlValue (prefInfo->inAWindowBtn, 1 - (prefInfo->prefGameDisplayMode == kFullScreen)); + if (prefInfo->prefGameDisplayMode == kFullScreen) + EnableControl (prefInfo->refreshRatePopup); + else + DisableControl (prefInfo->refreshRatePopup); + if (prefInfo->multiMonitor) + EnableControl (prefInfo->chooseMonitorsBtn); + else + DisableControl (prefInfo->chooseMonitorsBtn); + + // Adjust resolutions, refresh rates + AdjustDisplayControls(prefInfo); + result = noErr; + break; + + + case kCmdChooseMonitors: + { + PickMonitor((DisplayIDType*)&prefInfo->prefDisplayID, prefInfo->window); + // Adjust resolutions, refresh rates for potentially new display ID + AdjustDisplayControls(prefInfo); + break; + } + + case kCmdResolution: + { + // Pick a new resolution + int item = GetControlValue(prefInfo->resolutionPopup); + GetResolutionFromPopupMenuItem(prefInfo->resolutionPopup, item, &prefInfo->prefWidth, &prefInfo->prefHeight, &prefInfo->prefDepth, &prefInfo->prefResFlags); + + // Adjust refresh menu + BuildRefreshRates(prefInfo->prefDisplayID, prefInfo->prefWidth, prefInfo->prefHeight, &prefInfo->refreshRates, prefInfo->callback); + BuildRefreshPopupButton(prefInfo->refreshRatePopup, &prefInfo->refreshRates); + prefInfo->freqMenuIndex = FindRefreshPopupMenuItem(&prefInfo->refreshRates, prefInfo->prefFrequency); + if (prefInfo->freqMenuIndex == 1) + prefInfo->prefFrequency = 0; // just in case FindRefreshPopupMenuItem didn't find prefInfo->prefFrequency + SetControlValue (prefInfo->refreshRatePopup, prefInfo->freqMenuIndex); + + // Disable refresh rate if NOT fullscreen + if ((prefInfo->prefGameDisplayMode != kFullScreen) || (prefInfo->refreshRates.size() == 0)) + DisableControl (prefInfo->refreshRatePopup); + else + EnableControl (prefInfo->refreshRatePopup); + + break; + } + + case kCmdRefreshRate: + { + // Keep prefInfo->prefFrequency updated for the other controls to reference + prefInfo->freqMenuIndex = GetControlValue (prefInfo->refreshRatePopup); + if (prefInfo->freqMenuIndex == 1) + prefInfo->prefFrequency = 0; + else + { + std::list::const_iterator iter = prefInfo->refreshRates.begin(); + for (int i = 0; i < prefInfo->freqMenuIndex-3; i++) + iter++; + prefInfo->prefFrequency = *iter; + } + break; + } + + + } + return result; +} + +#pragma mark - + +static DEFINE_ONE_SHOT_HANDLER_GETTER(PrefHandler) + +OSStatus CreateGameDisplayPreferencesDialog(const GameDisplayInfo *inGDInfo, + WindowRef *outWindow, ValidModeCallbackProc inCallback) +{ + OSStatus err = noErr; + + // Build up a structure to pass to the window handler we are about + // to install. We store the window itself, as well as the original + // states of our settings. We use this to revert if the user clicks + // the cancel button. + + static PrefInfo prefInfo; + + prefInfo.prefGameDisplayMode = inGDInfo->mode; + prefInfo.prefDisplayID = inGDInfo->displayID; + prefInfo.prefWidth = inGDInfo->width; + prefInfo.prefHeight = inGDInfo->height; + prefInfo.prefDepth = inGDInfo->depth; + prefInfo.prefFrequency = inGDInfo->frequency; + prefInfo.prefResFlags = inGDInfo->resFlags; + prefInfo.window = NULL; + prefInfo.okPressed = false; + + Boolean result; + Boolean keyFound; + result = CFPreferencesGetAppBooleanValue (kPref_PrefsDialogAlways, kCFPreferencesCurrentApplication, &keyFound); + prefInfo.prefAlways = result && keyFound; + result = CFPreferencesGetAppBooleanValue (kPref_PrefsDialogOpenAL, kCFPreferencesCurrentApplication, &keyFound); + prefInfo.prefOpenAL = result && keyFound; + + prefInfo.callback = inCallback; + + // If DoPreferences is called at the start of the game, prefInfo.prefDisplayID needs to be checked + // to see if it is still a valid display ID. + + if (!ValidDisplayID(prefInfo.prefDisplayID)) + prefInfo.prefDisplayID = kCGDirectMainDisplay; // revert to main + + // Fetch the dialog + + IBNibRef aslNib; + CFBundleRef theBundle = CFBundleGetMainBundle(); + err = CreateNibReferenceWithCFBundle(theBundle, CFSTR("ASLCore"), &aslNib); + err = ::CreateWindowFromNib(aslNib, CFSTR( "Preferences" ), &prefInfo.window ); + if (err != noErr) + return err; + SetWRefCon(prefInfo.window, (long)&prefInfo); + + // Locate all the controls + + GetControlByID( prefInfo.window, &kFullscreenBtn, &prefInfo.fullscreenBtn ); assert(prefInfo.fullscreenBtn); + GetControlByID( prefInfo.window, &kInAWindowBtn, &prefInfo.inAWindowBtn ); assert(prefInfo.inAWindowBtn); + GetControlByID( prefInfo.window, &kResolutionPopup, &prefInfo.resolutionPopup ); assert(prefInfo.resolutionPopup); + GetControlByID( prefInfo.window, &kRefreshRatePopup, &prefInfo.refreshRatePopup ); assert(prefInfo.refreshRatePopup); + GetControlByID( prefInfo.window, &kChooseMonitorsBtn, &prefInfo.chooseMonitorsBtn ); assert(prefInfo.chooseMonitorsBtn); + GetControlByID( prefInfo.window, &kAlwaysBtn, &prefInfo.alwaysBtn ); assert(prefInfo.alwaysBtn); + GetControlByID( prefInfo.window, &kOpenALBtn, &prefInfo.openALBtn ); assert(prefInfo.openALBtn); + + + + // Disable the "choose monitor" button if we've only got one to pick from + + prefInfo.multiMonitor = CanUserPickMonitor(); + + if (!prefInfo.multiMonitor) + { + DisableControl (prefInfo.chooseMonitorsBtn); + prefInfo.prefDisplayID = 0; + } + + // Prepare the resolutions and refresh rates popup menus + AdjustDisplayControls(&prefInfo); + + // Set up the controls + + SetControlValue (prefInfo.refreshRatePopup, prefInfo.freqMenuIndex); + SetControlValue (prefInfo.fullscreenBtn, prefInfo.prefGameDisplayMode == kFullScreen); + SetControlValue (prefInfo.inAWindowBtn, prefInfo.prefGameDisplayMode == kWindow); + SetControlValue (prefInfo.alwaysBtn, prefInfo.prefAlways); + SetControlValue (prefInfo.openALBtn, prefInfo.prefOpenAL); + + + // Create our UPP and install the handler. + + EventTypeSpec cmdEvent = { kEventClassCommand, kEventCommandProcess }; + EventHandlerUPP handler = GetPrefHandlerUPP(); + InstallWindowEventHandler( prefInfo.window, handler, 1, &cmdEvent, &prefInfo, NULL ); + + // Position and show the window + RepositionWindow( prefInfo.window, NULL, kWindowAlertPositionOnMainScreen ); + + if (outWindow) + *outWindow = prefInfo.window; + + return err; +} + + +//------------------------------------------------------------------------------------ +// ¥ RunGameDisplayPreferencesDialog +//------------------------------------------------------------------------------------ +// Runs the Mac-specific preferences dialog. + +OSStatus RunGameDisplayPreferencesDialog(GameDisplayInfo *outGDInfo, WindowRef inWindow) +{ + PrefInfo *prefInfo = (PrefInfo*)GetWRefCon(inWindow); + + ShowWindow( inWindow ); + + // Now we run modally. We will remain here until the PrefHandler + // calls QuitAppModalLoopForWindow if the user clicks OK or + // Cancel. + + RunAppModalLoopForWindow( inWindow ); + + // OK, we're done. Dispose of our window. + // TODO: Are we supposed to uninstall event handlers? + DisposeWindow( inWindow ); + + // Return settings to caller + + if (prefInfo->okPressed) + { + outGDInfo->mode = prefInfo->prefGameDisplayMode; + outGDInfo->width = prefInfo->prefWidth; + outGDInfo->height = prefInfo->prefHeight; + outGDInfo->depth = prefInfo->prefDepth; + outGDInfo->frequency = prefInfo->prefFrequency; + outGDInfo->resFlags = prefInfo->prefResFlags; + outGDInfo->displayID = prefInfo->prefDisplayID; + } + + return prefInfo->okPressed ? noErr : userCanceledErr; +} + + + + + + + diff --git a/sys/osx/PreferencesDialog.h b/sys/osx/PreferencesDialog.h new file mode 100644 index 000000000..2d8f5bd80 --- /dev/null +++ b/sys/osx/PreferencesDialog.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef PREFERENCESDIALOG_H +#define PREFERENCESDIALOG_H + +enum GameDisplayMode +{ + kInactive, + kFullScreen, + kWindow +}; + +typedef long LONG; + +typedef struct tagPOINT +{ + LONG x; + LONG y; +} POINT; + +typedef struct +{ + GameDisplayMode mode; // Indicates if the game is in full screen mode or window mode. + CGDirectDisplayID displayID; // Display used for the full screen mode. + short width; // Width of screen and/or window. + short height; // Height of screen and/or window. + short depth; // Screen bit depth used for full screen mode. + Fixed frequency; // Screen refresh rate in MHz for full screen mode. If zero, then a default will be used. + POINT windowLoc; // Device-local coordinate of top left corner for window mode. Expressed as a Win32 POINT. Coordiantes may be CW_USEDEFAULT indicating no location has yet been established. + unsigned long flags; // kBlankingWindow, kDontRepositionWindow, etc. + UInt32 resFlags; // boolean bits to mark special modes for each resolution, e.g. stretched +} GameDisplayInfo; + +typedef bool(*ValidModeCallbackProc)(CGDirectDisplayID displayID, int width, int height, int depth, Fixed freq); + +OSStatus CreateGameDisplayPreferencesDialog( + const GameDisplayInfo *inGDInfo, + WindowRef *outWindow, + ValidModeCallbackProc inCallback = NULL); + +OSStatus RunGameDisplayPreferencesDialog( + GameDisplayInfo *outGDInfo, + WindowRef inWindow); + + +#endif // PREFERENCESDIALOG_H diff --git a/sys/osx/SubProjects/curl.xcodeproj/project.pbxproj b/sys/osx/SubProjects/curl.xcodeproj/project.pbxproj new file mode 100644 index 000000000..9ab96bb94 --- /dev/null +++ b/sys/osx/SubProjects/curl.xcodeproj/project.pbxproj @@ -0,0 +1,418 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 81326DE0099C16B6003C4788 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = 81326DDF099C16B5003C4788 /* getdate.c */; }; + 81990C280981932900A439CA /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990B920981932900A439CA /* base64.c */; }; + 81990C310981932900A439CA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990B9E0981932900A439CA /* connect.c */; }; + 81990C350981932900A439CA /* cookie.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BA20981932900A439CA /* cookie.c */; }; + 81990C380981932900A439CA /* dict.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BA80981932900A439CA /* dict.c */; }; + 81990C3A0981932900A439CA /* easy.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BAA0981932900A439CA /* easy.c */; }; + 81990C3C0981932900A439CA /* escape.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BAC0981932900A439CA /* escape.c */; }; + 81990C3E0981932900A439CA /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BAE0981932900A439CA /* file.c */; }; + 81990C400981932900A439CA /* formdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BB00981932900A439CA /* formdata.c */; }; + 81990C420981932900A439CA /* ftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BB20981932900A439CA /* ftp.c */; }; + 81990C440981932900A439CA /* getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BB40981932900A439CA /* getenv.c */; }; + 81990C450981932900A439CA /* getinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BB50981932900A439CA /* getinfo.c */; }; + 81990C490981932900A439CA /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BB90981932900A439CA /* hash.c */; }; + 81990C4D0981932900A439CA /* hostip.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BBD0981932900A439CA /* hostip.c */; }; + 81990C530981932900A439CA /* http_chunks.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BC30981932900A439CA /* http_chunks.c */; }; + 81990C550981932900A439CA /* http_digest.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BC50981932900A439CA /* http_digest.c */; }; + 81990C570981932900A439CA /* http_negotiate.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BC70981932900A439CA /* http_negotiate.c */; }; + 81990C590981932900A439CA /* http_ntlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BC90981932900A439CA /* http_ntlm.c */; }; + 81990C5B0981932900A439CA /* http.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BCB0981932900A439CA /* http.c */; }; + 81990C5D0981932900A439CA /* if2ip.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BCD0981932900A439CA /* if2ip.c */; }; + 81990C620981932900A439CA /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BD20981932900A439CA /* inet_pton.c */; }; + 81990C640981932900A439CA /* krb4.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BD40981932900A439CA /* krb4.c */; }; + 81990C660981932900A439CA /* ldap.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BD60981932900A439CA /* ldap.c */; }; + 81990C690981932900A439CA /* llist.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BDD0981932900A439CA /* llist.c */; }; + 81990C6D0981932900A439CA /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BEB0981932900A439CA /* md5.c */; }; + 81990C6F0981932900A439CA /* memdebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BED0981932900A439CA /* memdebug.c */; }; + 81990C720981932900A439CA /* mprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BF00981932900A439CA /* mprintf.c */; }; + 81990C730981932900A439CA /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BF30981932900A439CA /* multi.c */; }; + 81990C750981932900A439CA /* netrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BF50981932900A439CA /* netrc.c */; }; + 81990C7A0981932900A439CA /* progress.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BFA0981932900A439CA /* progress.c */; }; + 81990C7C0981932900A439CA /* security.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C020981932900A439CA /* security.c */; }; + 81990C7F0981932900A439CA /* sendf.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C050981932900A439CA /* sendf.c */; }; + 81990C820981932900A439CA /* share.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C080981932900A439CA /* share.c */; }; + 81990C840981932900A439CA /* speedcheck.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C0A0981932900A439CA /* speedcheck.c */; }; + 81990C880981932900A439CA /* ssluse.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C0E0981932900A439CA /* ssluse.c */; }; + 81990C8A0981932900A439CA /* strequal.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C110981932900A439CA /* strequal.c */; }; + 81990C8E0981932900A439CA /* strtok.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C150981932900A439CA /* strtok.c */; }; + 81990C900981932900A439CA /* strtoofft.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C170981932900A439CA /* strtoofft.c */; }; + 81990C920981932900A439CA /* telnet.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C190981932900A439CA /* telnet.c */; }; + 81990C960981932900A439CA /* timeval.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C1D0981932900A439CA /* timeval.c */; }; + 81990C980981932900A439CA /* transfer.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C1F0981932900A439CA /* transfer.c */; }; + 81990C9A0981932900A439CA /* url.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C210981932900A439CA /* url.c */; }; + 81990C9D0981932900A439CA /* version.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990C240981932900A439CA /* version.c */; }; + 81990D430981A46E00A439CA /* content_encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = 81990BA00981932900A439CA /* content_encoding.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 81326DDF099C16B5003C4788 /* getdate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = getdate.c; path = ../../../curl/lib/getdate.c; sourceTree = SOURCE_ROOT; }; + 81990B920981932900A439CA /* base64.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = base64.c; path = ../../../curl/lib/base64.c; sourceTree = SOURCE_ROOT; }; + 81990B9E0981932900A439CA /* connect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = connect.c; path = ../../../curl/lib/connect.c; sourceTree = SOURCE_ROOT; }; + 81990BA00981932900A439CA /* content_encoding.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = content_encoding.c; path = ../../../curl/lib/content_encoding.c; sourceTree = SOURCE_ROOT; }; + 81990BA20981932900A439CA /* cookie.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cookie.c; path = ../../../curl/lib/cookie.c; sourceTree = SOURCE_ROOT; }; + 81990BA80981932900A439CA /* dict.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dict.c; path = ../../../curl/lib/dict.c; sourceTree = SOURCE_ROOT; }; + 81990BAA0981932900A439CA /* easy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = easy.c; path = ../../../curl/lib/easy.c; sourceTree = SOURCE_ROOT; }; + 81990BAC0981932900A439CA /* escape.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = escape.c; path = ../../../curl/lib/escape.c; sourceTree = SOURCE_ROOT; }; + 81990BAE0981932900A439CA /* file.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = file.c; path = ../../../curl/lib/file.c; sourceTree = SOURCE_ROOT; }; + 81990BB00981932900A439CA /* formdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = formdata.c; path = ../../../curl/lib/formdata.c; sourceTree = SOURCE_ROOT; }; + 81990BB20981932900A439CA /* ftp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ftp.c; path = ../../../curl/lib/ftp.c; sourceTree = SOURCE_ROOT; }; + 81990BB40981932900A439CA /* getenv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = getenv.c; path = ../../../curl/lib/getenv.c; sourceTree = SOURCE_ROOT; }; + 81990BB50981932900A439CA /* getinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = getinfo.c; path = ../../../curl/lib/getinfo.c; sourceTree = SOURCE_ROOT; }; + 81990BB90981932900A439CA /* hash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../../curl/lib/hash.c; sourceTree = SOURCE_ROOT; }; + 81990BBD0981932900A439CA /* hostip.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hostip.c; path = ../../../curl/lib/hostip.c; sourceTree = SOURCE_ROOT; }; + 81990BC30981932900A439CA /* http_chunks.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = http_chunks.c; path = ../../../curl/lib/http_chunks.c; sourceTree = SOURCE_ROOT; }; + 81990BC50981932900A439CA /* http_digest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = http_digest.c; path = ../../../curl/lib/http_digest.c; sourceTree = SOURCE_ROOT; }; + 81990BC70981932900A439CA /* http_negotiate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = http_negotiate.c; path = ../../../curl/lib/http_negotiate.c; sourceTree = SOURCE_ROOT; }; + 81990BC90981932900A439CA /* http_ntlm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = http_ntlm.c; path = ../../../curl/lib/http_ntlm.c; sourceTree = SOURCE_ROOT; }; + 81990BCB0981932900A439CA /* http.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = http.c; path = ../../../curl/lib/http.c; sourceTree = SOURCE_ROOT; }; + 81990BCD0981932900A439CA /* if2ip.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = if2ip.c; path = ../../../curl/lib/if2ip.c; sourceTree = SOURCE_ROOT; }; + 81990BD20981932900A439CA /* inet_pton.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inet_pton.c; path = ../../../curl/lib/inet_pton.c; sourceTree = SOURCE_ROOT; }; + 81990BD40981932900A439CA /* krb4.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = krb4.c; path = ../../../curl/lib/krb4.c; sourceTree = SOURCE_ROOT; }; + 81990BD60981932900A439CA /* ldap.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ldap.c; path = ../../../curl/lib/ldap.c; sourceTree = SOURCE_ROOT; }; + 81990BDD0981932900A439CA /* llist.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = llist.c; path = ../../../curl/lib/llist.c; sourceTree = SOURCE_ROOT; }; + 81990BEB0981932900A439CA /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../../curl/lib/md5.c; sourceTree = SOURCE_ROOT; }; + 81990BED0981932900A439CA /* memdebug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = memdebug.c; path = ../../../curl/lib/memdebug.c; sourceTree = SOURCE_ROOT; }; + 81990BF00981932900A439CA /* mprintf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mprintf.c; path = ../../../curl/lib/mprintf.c; sourceTree = SOURCE_ROOT; }; + 81990BF30981932900A439CA /* multi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = multi.c; path = ../../../curl/lib/multi.c; sourceTree = SOURCE_ROOT; }; + 81990BF50981932900A439CA /* netrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = netrc.c; path = ../../../curl/lib/netrc.c; sourceTree = SOURCE_ROOT; }; + 81990BFA0981932900A439CA /* progress.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = progress.c; path = ../../../curl/lib/progress.c; sourceTree = SOURCE_ROOT; }; + 81990C020981932900A439CA /* security.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = security.c; path = ../../../curl/lib/security.c; sourceTree = SOURCE_ROOT; }; + 81990C050981932900A439CA /* sendf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sendf.c; path = ../../../curl/lib/sendf.c; sourceTree = SOURCE_ROOT; }; + 81990C080981932900A439CA /* share.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = share.c; path = ../../../curl/lib/share.c; sourceTree = SOURCE_ROOT; }; + 81990C0A0981932900A439CA /* speedcheck.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = speedcheck.c; path = ../../../curl/lib/speedcheck.c; sourceTree = SOURCE_ROOT; }; + 81990C0E0981932900A439CA /* ssluse.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ssluse.c; path = ../../../curl/lib/ssluse.c; sourceTree = SOURCE_ROOT; }; + 81990C110981932900A439CA /* strequal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = strequal.c; path = ../../../curl/lib/strequal.c; sourceTree = SOURCE_ROOT; }; + 81990C150981932900A439CA /* strtok.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = strtok.c; path = ../../../curl/lib/strtok.c; sourceTree = SOURCE_ROOT; }; + 81990C170981932900A439CA /* strtoofft.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = strtoofft.c; path = ../../../curl/lib/strtoofft.c; sourceTree = SOURCE_ROOT; }; + 81990C190981932900A439CA /* telnet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = telnet.c; path = ../../../curl/lib/telnet.c; sourceTree = SOURCE_ROOT; }; + 81990C1D0981932900A439CA /* timeval.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = timeval.c; path = ../../../curl/lib/timeval.c; sourceTree = SOURCE_ROOT; }; + 81990C1F0981932900A439CA /* transfer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = transfer.c; path = ../../../curl/lib/transfer.c; sourceTree = SOURCE_ROOT; }; + 81990C210981932900A439CA /* url.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = url.c; path = ../../../curl/lib/url.c; sourceTree = SOURCE_ROOT; }; + 81990C240981932900A439CA /* version.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = version.c; path = ../../../curl/lib/version.c; sourceTree = SOURCE_ROOT; }; + D2AAC046055464E500DB518D /* libcurl_static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcurl_static.a; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D289987405E68DCB004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* curl */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + C6A0FF2B0290797F04C91782 /* Documentation */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + name = curl; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 81326DDF099C16B5003C4788 /* getdate.c */, + 81990B920981932900A439CA /* base64.c */, + 81990B9E0981932900A439CA /* connect.c */, + 81990BA00981932900A439CA /* content_encoding.c */, + 81990BA20981932900A439CA /* cookie.c */, + 81990BA80981932900A439CA /* dict.c */, + 81990BAA0981932900A439CA /* easy.c */, + 81990BAC0981932900A439CA /* escape.c */, + 81990BAE0981932900A439CA /* file.c */, + 81990BB00981932900A439CA /* formdata.c */, + 81990BB20981932900A439CA /* ftp.c */, + 81990BB40981932900A439CA /* getenv.c */, + 81990BB50981932900A439CA /* getinfo.c */, + 81990BB90981932900A439CA /* hash.c */, + 81990BBD0981932900A439CA /* hostip.c */, + 81990BC30981932900A439CA /* http_chunks.c */, + 81990BC50981932900A439CA /* http_digest.c */, + 81990BC70981932900A439CA /* http_negotiate.c */, + 81990BC90981932900A439CA /* http_ntlm.c */, + 81990BCB0981932900A439CA /* http.c */, + 81990BCD0981932900A439CA /* if2ip.c */, + 81990BD20981932900A439CA /* inet_pton.c */, + 81990BD40981932900A439CA /* krb4.c */, + 81990BD60981932900A439CA /* ldap.c */, + 81990BDD0981932900A439CA /* llist.c */, + 81990BEB0981932900A439CA /* md5.c */, + 81990BED0981932900A439CA /* memdebug.c */, + 81990BF00981932900A439CA /* mprintf.c */, + 81990BF30981932900A439CA /* multi.c */, + 81990BF50981932900A439CA /* netrc.c */, + 81990BFA0981932900A439CA /* progress.c */, + 81990C020981932900A439CA /* security.c */, + 81990C050981932900A439CA /* sendf.c */, + 81990C080981932900A439CA /* share.c */, + 81990C0A0981932900A439CA /* speedcheck.c */, + 81990C0E0981932900A439CA /* ssluse.c */, + 81990C110981932900A439CA /* strequal.c */, + 81990C150981932900A439CA /* strtok.c */, + 81990C170981932900A439CA /* strtoofft.c */, + 81990C190981932900A439CA /* telnet.c */, + 81990C1D0981932900A439CA /* timeval.c */, + 81990C1F0981932900A439CA /* transfer.c */, + 81990C210981932900A439CA /* url.c */, + 81990C240981932900A439CA /* version.c */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC046055464E500DB518D /* libcurl_static.a */, + ); + name = Products; + sourceTree = ""; + }; + C6A0FF2B0290797F04C91782 /* Documentation */ = { + isa = PBXGroup; + children = ( + ); + name = Documentation; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC043055464E500DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC045055464E500DB518D /* curl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "curl" */; + buildPhases = ( + 81990CCC09819CB700A439CA /* ShellScript */, + D2AAC043055464E500DB518D /* Headers */, + D2AAC044055464E500DB518D /* Sources */, + D289987405E68DCB004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = curl; + productName = curl; + productReference = D2AAC046055464E500DB518D /* libcurl_static.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + ORGANIZATIONNAME = "id Software LLC"; + }; + buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "curl" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* curl */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC045055464E500DB518D /* curl */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + 81990CCC09819CB700A439CA /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd ../../../curl\n\n./configure --enable-shared=no --enable-static=yes --enable-http --without-zlib --enable-ftp --disable-gopher --enable-file --disable-ldap --disable-dict --disable-telnet --disable-manual --enable-libgcc --disable-ipv6 --without-ssl\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC044055464E500DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81990C280981932900A439CA /* base64.c in Sources */, + 81990C310981932900A439CA /* connect.c in Sources */, + 81990C350981932900A439CA /* cookie.c in Sources */, + 81990C380981932900A439CA /* dict.c in Sources */, + 81990C3A0981932900A439CA /* easy.c in Sources */, + 81990C3C0981932900A439CA /* escape.c in Sources */, + 81990C3E0981932900A439CA /* file.c in Sources */, + 81990C400981932900A439CA /* formdata.c in Sources */, + 81990C420981932900A439CA /* ftp.c in Sources */, + 81990C440981932900A439CA /* getenv.c in Sources */, + 81990C450981932900A439CA /* getinfo.c in Sources */, + 81990C490981932900A439CA /* hash.c in Sources */, + 81990C4D0981932900A439CA /* hostip.c in Sources */, + 81990C530981932900A439CA /* http_chunks.c in Sources */, + 81990C550981932900A439CA /* http_digest.c in Sources */, + 81990C570981932900A439CA /* http_negotiate.c in Sources */, + 81990C590981932900A439CA /* http_ntlm.c in Sources */, + 81990C5B0981932900A439CA /* http.c in Sources */, + 81990C5D0981932900A439CA /* if2ip.c in Sources */, + 81990C620981932900A439CA /* inet_pton.c in Sources */, + 81990C640981932900A439CA /* krb4.c in Sources */, + 81990C660981932900A439CA /* ldap.c in Sources */, + 81990C690981932900A439CA /* llist.c in Sources */, + 81990C6D0981932900A439CA /* md5.c in Sources */, + 81990C6F0981932900A439CA /* memdebug.c in Sources */, + 81990C720981932900A439CA /* mprintf.c in Sources */, + 81990C730981932900A439CA /* multi.c in Sources */, + 81990C750981932900A439CA /* netrc.c in Sources */, + 81990C7A0981932900A439CA /* progress.c in Sources */, + 81990C7C0981932900A439CA /* security.c in Sources */, + 81990C7F0981932900A439CA /* sendf.c in Sources */, + 81990C820981932900A439CA /* share.c in Sources */, + 81990C840981932900A439CA /* speedcheck.c in Sources */, + 81990C880981932900A439CA /* ssluse.c in Sources */, + 81990C8A0981932900A439CA /* strequal.c in Sources */, + 81990C8E0981932900A439CA /* strtok.c in Sources */, + 81990C900981932900A439CA /* strtoofft.c in Sources */, + 81990C920981932900A439CA /* telnet.c in Sources */, + 81990C960981932900A439CA /* timeval.c in Sources */, + 81990C980981932900A439CA /* transfer.c in Sources */, + 81990C9A0981932900A439CA /* url.c in Sources */, + 81990C9D0981932900A439CA /* version.c in Sources */, + 81990D430981A46E00A439CA /* content_encoding.c in Sources */, + 81326DE0099C16B6003C4788 /* getdate.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB91EC08733DB70010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../curl/include"; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(LIBRARY_SEARCH_PATHS)", + "$(SRCROOT)/../../../curl/lib", + ); + OTHER_CFLAGS = "-DHAVE_CONFIG_H"; + PRODUCT_NAME = curl_static; + SYMROOT = ../Build; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DEB91ED08733DB70010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../curl/include"; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(LIBRARY_SEARCH_PATHS)", + "$(SRCROOT)/../../../curl/lib", + ); + OTHER_CFLAGS = "-DHAVE_CONFIG_H"; + PRODUCT_NAME = curl_static; + SYMROOT = ../Build; + }; + name = Release; + }; + 1DEB91F008733DB70010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_MODEL_TUNING = ""; + GCC_OPTIMIZATION_LEVEL = 1; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Debug; + }; + 1DEB91F108733DB70010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_MODEL_TUNING = ""; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "curl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB91EC08733DB70010E9CD /* Debug */, + 1DEB91ED08733DB70010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "curl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB91F008733DB70010E9CD /* Debug */, + 1DEB91F108733DB70010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/sys/osx/d3xp.xcodeproj/project.pbxproj b/sys/osx/d3xp.xcodeproj/project.pbxproj new file mode 100644 index 000000000..8e28acf92 --- /dev/null +++ b/sys/osx/d3xp.xcodeproj/project.pbxproj @@ -0,0 +1,938 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 25ACE0660B31FDED00A159B2 /* Grabber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25ACE0650B31FDED00A159B2 /* Grabber.cpp */; }; + 25ACE0680B31FDFE00A159B2 /* Force_Grab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25ACE0670B31FDFE00A159B2 /* Force_Grab.cpp */; }; + 81225A3A0912C3DB005D34B9 /* libidlib_pic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 81225A210912C3A4005D34B9 /* libidlib_pic.a */; }; + 81225AC40912C42F005D34B9 /* PlayerIcon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */; }; + 81225AC50912C42F005D34B9 /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3C0912C42F005D34B9 /* Actor.cpp */; }; + 81225AC60912C42F005D34B9 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A3D0912C42F005D34B9 /* Actor.h */; }; + 81225AC70912C42F005D34B9 /* AF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3E0912C42F005D34B9 /* AF.cpp */; }; + 81225AC80912C42F005D34B9 /* AF.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A3F0912C42F005D34B9 /* AF.h */; }; + 81225AC90912C42F005D34B9 /* AFEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A400912C42F005D34B9 /* AFEntity.cpp */; }; + 81225ACA0912C42F005D34B9 /* AFEntity.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A410912C42F005D34B9 /* AFEntity.h */; }; + 81225ACB0912C42F005D34B9 /* AAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A430912C42F005D34B9 /* AAS.cpp */; }; + 81225ACC0912C42F005D34B9 /* AAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A440912C42F005D34B9 /* AAS.h */; }; + 81225ACD0912C42F005D34B9 /* AAS_debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A450912C42F005D34B9 /* AAS_debug.cpp */; }; + 81225ACE0912C42F005D34B9 /* AAS_local.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A460912C42F005D34B9 /* AAS_local.h */; }; + 81225ACF0912C42F005D34B9 /* AAS_pathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A470912C42F005D34B9 /* AAS_pathing.cpp */; }; + 81225AD00912C42F005D34B9 /* AAS_routing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A480912C42F005D34B9 /* AAS_routing.cpp */; }; + 81225AD10912C42F005D34B9 /* AI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A490912C42F005D34B9 /* AI.cpp */; }; + 81225AD20912C42F005D34B9 /* AI.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A4A0912C42F005D34B9 /* AI.h */; }; + 81225AD30912C42F005D34B9 /* AI_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4B0912C42F005D34B9 /* AI_events.cpp */; }; + 81225AD40912C42F005D34B9 /* AI_pathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */; }; + 81225AD50912C42F005D34B9 /* AI_Vagary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4D0912C42F005D34B9 /* AI_Vagary.cpp */; }; + 81225AD60912C42F005D34B9 /* Anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4F0912C42F005D34B9 /* Anim.cpp */; }; + 81225AD70912C42F005D34B9 /* Anim.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A500912C42F005D34B9 /* Anim.h */; }; + 81225AD80912C42F005D34B9 /* Anim_Blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A510912C42F005D34B9 /* Anim_Blend.cpp */; }; + 81225AD90912C42F005D34B9 /* Anim_Import.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A520912C42F005D34B9 /* Anim_Import.cpp */; }; + 81225ADA0912C42F005D34B9 /* Anim_Testmodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */; }; + 81225ADB0912C42F005D34B9 /* Anim_Testmodel.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A540912C42F005D34B9 /* Anim_Testmodel.h */; }; + 81225ADC0912C42F005D34B9 /* BrittleFracture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A550912C42F005D34B9 /* BrittleFracture.cpp */; }; + 81225ADD0912C42F005D34B9 /* BrittleFracture.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A560912C42F005D34B9 /* BrittleFracture.h */; }; + 81225ADE0912C42F005D34B9 /* Camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A570912C42F005D34B9 /* Camera.cpp */; }; + 81225ADF0912C42F005D34B9 /* Camera.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A580912C42F005D34B9 /* Camera.h */; }; + 81225AE00912C42F005D34B9 /* Entity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A590912C42F005D34B9 /* Entity.cpp */; }; + 81225AE10912C42F005D34B9 /* Entity.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A5A0912C42F005D34B9 /* Entity.h */; }; + 81225AE20912C42F005D34B9 /* Fx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A5B0912C42F005D34B9 /* Fx.cpp */; }; + 81225AE30912C42F005D34B9 /* Fx.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A5C0912C42F005D34B9 /* Fx.h */; }; + 81225AE40912C42F005D34B9 /* Game.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A5E0912C42F005D34B9 /* Game.h */; }; + 81225AE50912C42F005D34B9 /* Game_local.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A5F0912C42F005D34B9 /* Game_local.cpp */; }; + 81225AE60912C42F005D34B9 /* Game_local.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A600912C42F005D34B9 /* Game_local.h */; }; + 81225AE70912C42F005D34B9 /* Game_network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A610912C42F005D34B9 /* Game_network.cpp */; }; + 81225AE80912C42F005D34B9 /* GameEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A620912C42F005D34B9 /* GameEdit.cpp */; }; + 81225AE90912C42F005D34B9 /* GameEdit.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A630912C42F005D34B9 /* GameEdit.h */; }; + 81225AEA0912C42F005D34B9 /* Class.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A650912C42F005D34B9 /* Class.cpp */; }; + 81225AEB0912C42F005D34B9 /* Class.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A660912C42F005D34B9 /* Class.h */; }; + 81225AEC0912C42F005D34B9 /* DebugGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A670912C42F005D34B9 /* DebugGraph.cpp */; }; + 81225AED0912C42F005D34B9 /* DebugGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A680912C42F005D34B9 /* DebugGraph.h */; }; + 81225AEE0912C42F005D34B9 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A690912C42F005D34B9 /* Event.cpp */; }; + 81225AEF0912C42F005D34B9 /* Event.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6A0912C42F005D34B9 /* Event.h */; }; + 81225AF00912C42F005D34B9 /* NoGameTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */; }; + 81225AF10912C42F005D34B9 /* SaveGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A6C0912C42F005D34B9 /* SaveGame.cpp */; }; + 81225AF20912C42F005D34B9 /* SaveGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6D0912C42F005D34B9 /* SaveGame.h */; }; + 81225AF30912C42F005D34B9 /* SysCmds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A6E0912C42F005D34B9 /* SysCmds.cpp */; }; + 81225AF40912C42F005D34B9 /* SysCmds.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6F0912C42F005D34B9 /* SysCmds.h */; }; + 81225AF50912C42F005D34B9 /* SysCvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A700912C42F005D34B9 /* SysCvar.cpp */; }; + 81225AF60912C42F005D34B9 /* SysCvar.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A710912C42F005D34B9 /* SysCvar.h */; }; + 81225AF70912C42F005D34B9 /* TypeInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A720912C42F005D34B9 /* TypeInfo.cpp */; }; + 81225AF80912C42F005D34B9 /* TypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A730912C42F005D34B9 /* TypeInfo.h */; }; + 81225AF90912C42F005D34B9 /* IK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A740912C42F005D34B9 /* IK.cpp */; }; + 81225AFA0912C42F005D34B9 /* IK.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A750912C42F005D34B9 /* IK.h */; }; + 81225AFB0912C42F005D34B9 /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A760912C42F005D34B9 /* Item.cpp */; }; + 81225AFC0912C42F005D34B9 /* Item.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A770912C42F005D34B9 /* Item.h */; }; + 81225AFD0912C42F005D34B9 /* Light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A780912C42F005D34B9 /* Light.cpp */; }; + 81225AFE0912C42F005D34B9 /* Light.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A790912C42F005D34B9 /* Light.h */; }; + 81225AFF0912C42F005D34B9 /* Misc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7A0912C42F005D34B9 /* Misc.cpp */; }; + 81225B000912C42F005D34B9 /* Misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7B0912C42F005D34B9 /* Misc.h */; }; + 81225B010912C42F005D34B9 /* Moveable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7C0912C42F005D34B9 /* Moveable.cpp */; }; + 81225B020912C42F005D34B9 /* Moveable.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7D0912C42F005D34B9 /* Moveable.h */; }; + 81225B030912C42F005D34B9 /* Mover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7E0912C42F005D34B9 /* Mover.cpp */; }; + 81225B040912C42F005D34B9 /* Mover.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7F0912C42F005D34B9 /* Mover.h */; }; + 81225B050912C42F005D34B9 /* MultiplayerGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */; }; + 81225B060912C42F005D34B9 /* MultiplayerGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A810912C42F005D34B9 /* MultiplayerGame.h */; }; + 81225B070912C42F005D34B9 /* Clip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A830912C42F005D34B9 /* Clip.cpp */; }; + 81225B080912C42F005D34B9 /* Clip.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A840912C42F005D34B9 /* Clip.h */; }; + 81225B090912C42F005D34B9 /* Force.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A850912C42F005D34B9 /* Force.cpp */; }; + 81225B0A0912C42F005D34B9 /* Force.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A860912C42F005D34B9 /* Force.h */; }; + 81225B0B0912C42F005D34B9 /* Force_Constant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A870912C42F005D34B9 /* Force_Constant.cpp */; }; + 81225B0C0912C42F005D34B9 /* Force_Constant.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A880912C42F005D34B9 /* Force_Constant.h */; }; + 81225B0D0912C42F005D34B9 /* Force_Drag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A890912C42F005D34B9 /* Force_Drag.cpp */; }; + 81225B0E0912C42F005D34B9 /* Force_Drag.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8A0912C42F005D34B9 /* Force_Drag.h */; }; + 81225B0F0912C42F005D34B9 /* Force_Field.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8B0912C42F005D34B9 /* Force_Field.cpp */; }; + 81225B100912C42F005D34B9 /* Force_Field.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8C0912C42F005D34B9 /* Force_Field.h */; }; + 81225B110912C42F005D34B9 /* Force_Spring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */; }; + 81225B120912C42F005D34B9 /* Force_Spring.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8E0912C42F005D34B9 /* Force_Spring.h */; }; + 81225B130912C42F005D34B9 /* Physics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8F0912C42F005D34B9 /* Physics.cpp */; }; + 81225B140912C42F005D34B9 /* Physics.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A900912C42F005D34B9 /* Physics.h */; }; + 81225B150912C42F005D34B9 /* Physics_Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A910912C42F005D34B9 /* Physics_Actor.cpp */; }; + 81225B160912C42F005D34B9 /* Physics_Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A920912C42F005D34B9 /* Physics_Actor.h */; }; + 81225B170912C42F005D34B9 /* Physics_AF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A930912C42F005D34B9 /* Physics_AF.cpp */; }; + 81225B180912C42F005D34B9 /* Physics_AF.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A940912C42F005D34B9 /* Physics_AF.h */; }; + 81225B190912C42F005D34B9 /* Physics_Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A950912C42F005D34B9 /* Physics_Base.cpp */; }; + 81225B1A0912C42F005D34B9 /* Physics_Base.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A960912C42F005D34B9 /* Physics_Base.h */; }; + 81225B1B0912C42F005D34B9 /* Physics_Monster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A970912C42F005D34B9 /* Physics_Monster.cpp */; }; + 81225B1C0912C42F005D34B9 /* Physics_Monster.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A980912C42F005D34B9 /* Physics_Monster.h */; }; + 81225B1D0912C42F005D34B9 /* Physics_Parametric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */; }; + 81225B1E0912C42F005D34B9 /* Physics_Parametric.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */; }; + 81225B1F0912C42F005D34B9 /* Physics_Player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */; }; + 81225B200912C42F005D34B9 /* Physics_Player.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9C0912C42F005D34B9 /* Physics_Player.h */; }; + 81225B210912C42F005D34B9 /* Physics_RigidBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */; }; + 81225B220912C42F005D34B9 /* Physics_RigidBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */; }; + 81225B230912C42F005D34B9 /* Physics_Static.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */; }; + 81225B240912C42F005D34B9 /* Physics_Static.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA00912C42F005D34B9 /* Physics_Static.h */; }; + 81225B250912C42F005D34B9 /* Physics_StaticMulti.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */; }; + 81225B260912C42F005D34B9 /* Physics_StaticMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */; }; + 81225B270912C42F005D34B9 /* Push.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA30912C42F005D34B9 /* Push.cpp */; }; + 81225B280912C42F005D34B9 /* Push.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA40912C42F005D34B9 /* Push.h */; }; + 81225B290912C42F005D34B9 /* Player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA50912C42F005D34B9 /* Player.cpp */; }; + 81225B2A0912C42F005D34B9 /* Player.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA60912C42F005D34B9 /* Player.h */; }; + 81225B2B0912C42F005D34B9 /* PlayerView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA70912C42F005D34B9 /* PlayerView.cpp */; }; + 81225B2C0912C42F005D34B9 /* PlayerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA80912C42F005D34B9 /* PlayerView.h */; }; + 81225B2D0912C42F005D34B9 /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA90912C42F005D34B9 /* Projectile.cpp */; }; + 81225B2E0912C42F005D34B9 /* Projectile.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAA0912C42F005D34B9 /* Projectile.h */; }; + 81225B2F0912C42F005D34B9 /* Pvs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AAB0912C42F005D34B9 /* Pvs.cpp */; }; + 81225B300912C42F005D34B9 /* Pvs.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAC0912C42F005D34B9 /* Pvs.h */; }; + 81225B310912C42F005D34B9 /* Script_Compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */; }; + 81225B320912C42F005D34B9 /* Script_Compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAF0912C42F005D34B9 /* Script_Compiler.h */; }; + 81225B330912C42F005D34B9 /* Script_Interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */; }; + 81225B340912C42F005D34B9 /* Script_Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB10912C42F005D34B9 /* Script_Interpreter.h */; }; + 81225B350912C42F005D34B9 /* Script_Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB20912C42F005D34B9 /* Script_Program.cpp */; }; + 81225B360912C42F005D34B9 /* Script_Program.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB30912C42F005D34B9 /* Script_Program.h */; }; + 81225B370912C42F005D34B9 /* Script_Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB40912C42F005D34B9 /* Script_Thread.cpp */; }; + 81225B380912C42F005D34B9 /* Script_Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB50912C42F005D34B9 /* Script_Thread.h */; }; + 81225B390912C42F005D34B9 /* SecurityCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */; }; + 81225B3A0912C42F005D34B9 /* SecurityCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB70912C42F005D34B9 /* SecurityCamera.h */; }; + 81225B3B0912C42F005D34B9 /* SmokeParticles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */; }; + 81225B3C0912C42F005D34B9 /* SmokeParticles.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB90912C42F005D34B9 /* SmokeParticles.h */; }; + 81225B3D0912C42F005D34B9 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABA0912C42F005D34B9 /* Sound.cpp */; }; + 81225B3E0912C42F005D34B9 /* Sound.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABB0912C42F005D34B9 /* Sound.h */; }; + 81225B3F0912C42F005D34B9 /* Target.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABC0912C42F005D34B9 /* Target.cpp */; }; + 81225B400912C42F005D34B9 /* Target.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABD0912C42F005D34B9 /* Target.h */; }; + 81225B410912C42F005D34B9 /* Trigger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABE0912C42F005D34B9 /* Trigger.cpp */; }; + 81225B420912C42F005D34B9 /* Trigger.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABF0912C42F005D34B9 /* Trigger.h */; }; + 81225B430912C42F005D34B9 /* Weapon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AC00912C42F005D34B9 /* Weapon.cpp */; }; + 81225B440912C42F005D34B9 /* Weapon.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AC10912C42F005D34B9 /* Weapon.h */; }; + 81225B450912C42F005D34B9 /* WorldSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */; }; + 81225B460912C42F005D34B9 /* WorldSpawn.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AC30912C42F005D34B9 /* WorldSpawn.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 81225A200912C3A4005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = idlib_pic; + }; + 81225A220912C3A4005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 81C858490912AD370095BC33; + remoteInfo = idlib_nopic; + }; + 81225A380912C3C8005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC045055464E500DB518D; + remoteInfo = idlib_pic; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 25ACE0650B31FDED00A159B2 /* Grabber.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Grabber.cpp; path = ../../d3xp/Grabber.cpp; sourceTree = SOURCE_ROOT; }; + 25ACE0670B31FDFE00A159B2 /* Force_Grab.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Grab.cpp; sourceTree = ""; }; + 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = idlib.xcodeproj; sourceTree = ""; }; + 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PlayerIcon.cpp; path = ../../d3xp/PlayerIcon.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3C0912C42F005D34B9 /* Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Actor.cpp; path = ../../d3xp/Actor.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3D0912C42F005D34B9 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../d3xp/Actor.h; sourceTree = SOURCE_ROOT; }; + 81225A3E0912C42F005D34B9 /* AF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AF.cpp; path = ../../d3xp/AF.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3F0912C42F005D34B9 /* AF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AF.h; path = ../../d3xp/AF.h; sourceTree = SOURCE_ROOT; }; + 81225A400912C42F005D34B9 /* AFEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AFEntity.cpp; path = ../../d3xp/AFEntity.cpp; sourceTree = SOURCE_ROOT; }; + 81225A410912C42F005D34B9 /* AFEntity.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AFEntity.h; path = ../../d3xp/AFEntity.h; sourceTree = SOURCE_ROOT; }; + 81225A430912C42F005D34B9 /* AAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS.cpp; sourceTree = ""; }; + 81225A440912C42F005D34B9 /* AAS.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AAS.h; sourceTree = ""; }; + 81225A450912C42F005D34B9 /* AAS_debug.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_debug.cpp; sourceTree = ""; }; + 81225A460912C42F005D34B9 /* AAS_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AAS_local.h; sourceTree = ""; }; + 81225A470912C42F005D34B9 /* AAS_pathing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_pathing.cpp; sourceTree = ""; }; + 81225A480912C42F005D34B9 /* AAS_routing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_routing.cpp; sourceTree = ""; }; + 81225A490912C42F005D34B9 /* AI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI.cpp; sourceTree = ""; }; + 81225A4A0912C42F005D34B9 /* AI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AI.h; sourceTree = ""; }; + 81225A4B0912C42F005D34B9 /* AI_events.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI_events.cpp; sourceTree = ""; }; + 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI_pathing.cpp; sourceTree = ""; }; + 81225A4D0912C42F005D34B9 /* AI_Vagary.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI_Vagary.cpp; sourceTree = ""; }; + 81225A4F0912C42F005D34B9 /* Anim.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim.cpp; sourceTree = ""; }; + 81225A500912C42F005D34B9 /* Anim.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Anim.h; sourceTree = ""; }; + 81225A510912C42F005D34B9 /* Anim_Blend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Blend.cpp; sourceTree = ""; }; + 81225A520912C42F005D34B9 /* Anim_Import.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Import.cpp; sourceTree = ""; }; + 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Testmodel.cpp; sourceTree = ""; }; + 81225A540912C42F005D34B9 /* Anim_Testmodel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Anim_Testmodel.h; sourceTree = ""; }; + 81225A550912C42F005D34B9 /* BrittleFracture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BrittleFracture.cpp; path = ../../d3xp/BrittleFracture.cpp; sourceTree = SOURCE_ROOT; }; + 81225A560912C42F005D34B9 /* BrittleFracture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = BrittleFracture.h; path = ../../d3xp/BrittleFracture.h; sourceTree = SOURCE_ROOT; }; + 81225A570912C42F005D34B9 /* Camera.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Camera.cpp; path = ../../d3xp/Camera.cpp; sourceTree = SOURCE_ROOT; }; + 81225A580912C42F005D34B9 /* Camera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Camera.h; path = ../../d3xp/Camera.h; sourceTree = SOURCE_ROOT; }; + 81225A590912C42F005D34B9 /* Entity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Entity.cpp; path = ../../d3xp/Entity.cpp; sourceTree = SOURCE_ROOT; }; + 81225A5A0912C42F005D34B9 /* Entity.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Entity.h; path = ../../d3xp/Entity.h; sourceTree = SOURCE_ROOT; }; + 81225A5B0912C42F005D34B9 /* Fx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Fx.cpp; path = ../../d3xp/Fx.cpp; sourceTree = SOURCE_ROOT; }; + 81225A5C0912C42F005D34B9 /* Fx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Fx.h; path = ../../d3xp/Fx.h; sourceTree = SOURCE_ROOT; }; + 81225A5D0912C42F005D34B9 /* Game.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Game.def; path = ../../d3xp/Game.def; sourceTree = SOURCE_ROOT; }; + 81225A5E0912C42F005D34B9 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Game.h; path = ../../d3xp/Game.h; sourceTree = SOURCE_ROOT; }; + 81225A5F0912C42F005D34B9 /* Game_local.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Game_local.cpp; path = ../../d3xp/Game_local.cpp; sourceTree = SOURCE_ROOT; }; + 81225A600912C42F005D34B9 /* Game_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Game_local.h; path = ../../d3xp/Game_local.h; sourceTree = SOURCE_ROOT; }; + 81225A610912C42F005D34B9 /* Game_network.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Game_network.cpp; path = ../../d3xp/Game_network.cpp; sourceTree = SOURCE_ROOT; }; + 81225A620912C42F005D34B9 /* GameEdit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = GameEdit.cpp; path = ../../d3xp/GameEdit.cpp; sourceTree = SOURCE_ROOT; }; + 81225A630912C42F005D34B9 /* GameEdit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GameEdit.h; path = ../../d3xp/GameEdit.h; sourceTree = SOURCE_ROOT; }; + 81225A650912C42F005D34B9 /* Class.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Class.cpp; sourceTree = ""; }; + 81225A660912C42F005D34B9 /* Class.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Class.h; sourceTree = ""; }; + 81225A670912C42F005D34B9 /* DebugGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DebugGraph.cpp; sourceTree = ""; }; + 81225A680912C42F005D34B9 /* DebugGraph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DebugGraph.h; sourceTree = ""; }; + 81225A690912C42F005D34B9 /* Event.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = ""; }; + 81225A6A0912C42F005D34B9 /* Event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; + 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NoGameTypeInfo.h; sourceTree = ""; }; + 81225A6C0912C42F005D34B9 /* SaveGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGame.cpp; sourceTree = ""; }; + 81225A6D0912C42F005D34B9 /* SaveGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SaveGame.h; sourceTree = ""; }; + 81225A6E0912C42F005D34B9 /* SysCmds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysCmds.cpp; sourceTree = ""; }; + 81225A6F0912C42F005D34B9 /* SysCmds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysCmds.h; sourceTree = ""; }; + 81225A700912C42F005D34B9 /* SysCvar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysCvar.cpp; sourceTree = ""; }; + 81225A710912C42F005D34B9 /* SysCvar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysCvar.h; sourceTree = ""; }; + 81225A720912C42F005D34B9 /* TypeInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TypeInfo.cpp; sourceTree = ""; }; + 81225A730912C42F005D34B9 /* TypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TypeInfo.h; sourceTree = ""; }; + 81225A740912C42F005D34B9 /* IK.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = IK.cpp; path = ../../d3xp/IK.cpp; sourceTree = SOURCE_ROOT; }; + 81225A750912C42F005D34B9 /* IK.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IK.h; path = ../../d3xp/IK.h; sourceTree = SOURCE_ROOT; }; + 81225A760912C42F005D34B9 /* Item.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Item.cpp; path = ../../d3xp/Item.cpp; sourceTree = SOURCE_ROOT; }; + 81225A770912C42F005D34B9 /* Item.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Item.h; path = ../../d3xp/Item.h; sourceTree = SOURCE_ROOT; }; + 81225A780912C42F005D34B9 /* Light.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Light.cpp; path = ../../d3xp/Light.cpp; sourceTree = SOURCE_ROOT; }; + 81225A790912C42F005D34B9 /* Light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Light.h; path = ../../d3xp/Light.h; sourceTree = SOURCE_ROOT; }; + 81225A7A0912C42F005D34B9 /* Misc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Misc.cpp; path = ../../d3xp/Misc.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7B0912C42F005D34B9 /* Misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Misc.h; path = ../../d3xp/Misc.h; sourceTree = SOURCE_ROOT; }; + 81225A7C0912C42F005D34B9 /* Moveable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Moveable.cpp; path = ../../d3xp/Moveable.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7D0912C42F005D34B9 /* Moveable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Moveable.h; path = ../../d3xp/Moveable.h; sourceTree = SOURCE_ROOT; }; + 81225A7E0912C42F005D34B9 /* Mover.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Mover.cpp; path = ../../d3xp/Mover.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7F0912C42F005D34B9 /* Mover.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Mover.h; path = ../../d3xp/Mover.h; sourceTree = SOURCE_ROOT; }; + 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultiplayerGame.cpp; path = ../../d3xp/MultiplayerGame.cpp; sourceTree = SOURCE_ROOT; }; + 81225A810912C42F005D34B9 /* MultiplayerGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MultiplayerGame.h; path = ../../d3xp/MultiplayerGame.h; sourceTree = SOURCE_ROOT; }; + 81225A830912C42F005D34B9 /* Clip.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Clip.cpp; sourceTree = ""; }; + 81225A840912C42F005D34B9 /* Clip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Clip.h; sourceTree = ""; }; + 81225A850912C42F005D34B9 /* Force.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force.cpp; sourceTree = ""; }; + 81225A860912C42F005D34B9 /* Force.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force.h; sourceTree = ""; }; + 81225A870912C42F005D34B9 /* Force_Constant.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Constant.cpp; sourceTree = ""; }; + 81225A880912C42F005D34B9 /* Force_Constant.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Constant.h; sourceTree = ""; }; + 81225A890912C42F005D34B9 /* Force_Drag.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Drag.cpp; sourceTree = ""; }; + 81225A8A0912C42F005D34B9 /* Force_Drag.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Drag.h; sourceTree = ""; }; + 81225A8B0912C42F005D34B9 /* Force_Field.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Field.cpp; sourceTree = ""; }; + 81225A8C0912C42F005D34B9 /* Force_Field.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Field.h; sourceTree = ""; }; + 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Spring.cpp; sourceTree = ""; }; + 81225A8E0912C42F005D34B9 /* Force_Spring.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Spring.h; sourceTree = ""; }; + 81225A8F0912C42F005D34B9 /* Physics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics.cpp; sourceTree = ""; }; + 81225A900912C42F005D34B9 /* Physics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics.h; sourceTree = ""; }; + 81225A910912C42F005D34B9 /* Physics_Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Actor.cpp; sourceTree = ""; }; + 81225A920912C42F005D34B9 /* Physics_Actor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Actor.h; sourceTree = ""; }; + 81225A930912C42F005D34B9 /* Physics_AF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_AF.cpp; sourceTree = ""; }; + 81225A940912C42F005D34B9 /* Physics_AF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_AF.h; sourceTree = ""; }; + 81225A950912C42F005D34B9 /* Physics_Base.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Base.cpp; sourceTree = ""; }; + 81225A960912C42F005D34B9 /* Physics_Base.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Base.h; sourceTree = ""; }; + 81225A970912C42F005D34B9 /* Physics_Monster.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Monster.cpp; sourceTree = ""; }; + 81225A980912C42F005D34B9 /* Physics_Monster.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Monster.h; sourceTree = ""; }; + 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Parametric.cpp; sourceTree = ""; }; + 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Parametric.h; sourceTree = ""; }; + 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Player.cpp; sourceTree = ""; }; + 81225A9C0912C42F005D34B9 /* Physics_Player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Player.h; sourceTree = ""; }; + 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_RigidBody.cpp; sourceTree = ""; }; + 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_RigidBody.h; sourceTree = ""; }; + 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Static.cpp; sourceTree = ""; }; + 81225AA00912C42F005D34B9 /* Physics_Static.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Static.h; sourceTree = ""; }; + 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_StaticMulti.cpp; sourceTree = ""; }; + 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_StaticMulti.h; sourceTree = ""; }; + 81225AA30912C42F005D34B9 /* Push.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Push.cpp; sourceTree = ""; }; + 81225AA40912C42F005D34B9 /* Push.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Push.h; sourceTree = ""; }; + 81225AA50912C42F005D34B9 /* Player.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Player.cpp; path = ../../d3xp/Player.cpp; sourceTree = SOURCE_ROOT; }; + 81225AA60912C42F005D34B9 /* Player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Player.h; path = ../../d3xp/Player.h; sourceTree = SOURCE_ROOT; }; + 81225AA70912C42F005D34B9 /* PlayerView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PlayerView.cpp; path = ../../d3xp/PlayerView.cpp; sourceTree = SOURCE_ROOT; }; + 81225AA80912C42F005D34B9 /* PlayerView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PlayerView.h; path = ../../d3xp/PlayerView.h; sourceTree = SOURCE_ROOT; }; + 81225AA90912C42F005D34B9 /* Projectile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Projectile.cpp; path = ../../d3xp/Projectile.cpp; sourceTree = SOURCE_ROOT; }; + 81225AAA0912C42F005D34B9 /* Projectile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Projectile.h; path = ../../d3xp/Projectile.h; sourceTree = SOURCE_ROOT; }; + 81225AAB0912C42F005D34B9 /* Pvs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pvs.cpp; path = ../../d3xp/Pvs.cpp; sourceTree = SOURCE_ROOT; }; + 81225AAC0912C42F005D34B9 /* Pvs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Pvs.h; path = ../../d3xp/Pvs.h; sourceTree = SOURCE_ROOT; }; + 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Compiler.cpp; sourceTree = ""; }; + 81225AAF0912C42F005D34B9 /* Script_Compiler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Compiler.h; sourceTree = ""; }; + 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Interpreter.cpp; sourceTree = ""; }; + 81225AB10912C42F005D34B9 /* Script_Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Interpreter.h; sourceTree = ""; }; + 81225AB20912C42F005D34B9 /* Script_Program.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Program.cpp; sourceTree = ""; }; + 81225AB30912C42F005D34B9 /* Script_Program.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Program.h; sourceTree = ""; }; + 81225AB40912C42F005D34B9 /* Script_Thread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Thread.cpp; sourceTree = ""; }; + 81225AB50912C42F005D34B9 /* Script_Thread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Thread.h; sourceTree = ""; }; + 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SecurityCamera.cpp; path = ../../d3xp/SecurityCamera.cpp; sourceTree = SOURCE_ROOT; }; + 81225AB70912C42F005D34B9 /* SecurityCamera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SecurityCamera.h; path = ../../d3xp/SecurityCamera.h; sourceTree = SOURCE_ROOT; }; + 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SmokeParticles.cpp; path = ../../d3xp/SmokeParticles.cpp; sourceTree = SOURCE_ROOT; }; + 81225AB90912C42F005D34B9 /* SmokeParticles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SmokeParticles.h; path = ../../d3xp/SmokeParticles.h; sourceTree = SOURCE_ROOT; }; + 81225ABA0912C42F005D34B9 /* Sound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Sound.cpp; path = ../../d3xp/Sound.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABB0912C42F005D34B9 /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sound.h; path = ../../d3xp/Sound.h; sourceTree = SOURCE_ROOT; }; + 81225ABC0912C42F005D34B9 /* Target.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Target.cpp; path = ../../d3xp/Target.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABD0912C42F005D34B9 /* Target.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Target.h; path = ../../d3xp/Target.h; sourceTree = SOURCE_ROOT; }; + 81225ABE0912C42F005D34B9 /* Trigger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Trigger.cpp; path = ../../d3xp/Trigger.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABF0912C42F005D34B9 /* Trigger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Trigger.h; path = ../../d3xp/Trigger.h; sourceTree = SOURCE_ROOT; }; + 81225AC00912C42F005D34B9 /* Weapon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Weapon.cpp; path = ../../d3xp/Weapon.cpp; sourceTree = SOURCE_ROOT; }; + 81225AC10912C42F005D34B9 /* Weapon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Weapon.h; path = ../../d3xp/Weapon.h; sourceTree = SOURCE_ROOT; }; + 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = WorldSpawn.cpp; path = ../../d3xp/WorldSpawn.cpp; sourceTree = SOURCE_ROOT; }; + 81225AC30912C42F005D34B9 /* WorldSpawn.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = WorldSpawn.h; path = ../../d3xp/WorldSpawn.h; sourceTree = SOURCE_ROOT; }; + D2AAC0630554660B00DB518D /* game-d3xp.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "game-d3xp.dylib"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D289988505E68E00004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225A3A0912C3DB005D34B9 /* libidlib_pic.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* game */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */, + ); + name = game; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 25ACE0650B31FDED00A159B2 /* Grabber.cpp */, + 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */, + 81225A3C0912C42F005D34B9 /* Actor.cpp */, + 81225A3D0912C42F005D34B9 /* Actor.h */, + 81225A3E0912C42F005D34B9 /* AF.cpp */, + 81225A3F0912C42F005D34B9 /* AF.h */, + 81225A400912C42F005D34B9 /* AFEntity.cpp */, + 81225A410912C42F005D34B9 /* AFEntity.h */, + 81225A420912C42F005D34B9 /* ai */, + 81225A4E0912C42F005D34B9 /* anim */, + 81225A550912C42F005D34B9 /* BrittleFracture.cpp */, + 81225A560912C42F005D34B9 /* BrittleFracture.h */, + 81225A570912C42F005D34B9 /* Camera.cpp */, + 81225A580912C42F005D34B9 /* Camera.h */, + 81225A590912C42F005D34B9 /* Entity.cpp */, + 81225A5A0912C42F005D34B9 /* Entity.h */, + 81225A5B0912C42F005D34B9 /* Fx.cpp */, + 81225A5C0912C42F005D34B9 /* Fx.h */, + 81225A5D0912C42F005D34B9 /* Game.def */, + 81225A5E0912C42F005D34B9 /* Game.h */, + 81225A5F0912C42F005D34B9 /* Game_local.cpp */, + 81225A600912C42F005D34B9 /* Game_local.h */, + 81225A610912C42F005D34B9 /* Game_network.cpp */, + 81225A620912C42F005D34B9 /* GameEdit.cpp */, + 81225A630912C42F005D34B9 /* GameEdit.h */, + 81225A640912C42F005D34B9 /* gamesys */, + 81225A740912C42F005D34B9 /* IK.cpp */, + 81225A750912C42F005D34B9 /* IK.h */, + 81225A760912C42F005D34B9 /* Item.cpp */, + 81225A770912C42F005D34B9 /* Item.h */, + 81225A780912C42F005D34B9 /* Light.cpp */, + 81225A790912C42F005D34B9 /* Light.h */, + 81225A7A0912C42F005D34B9 /* Misc.cpp */, + 81225A7B0912C42F005D34B9 /* Misc.h */, + 81225A7C0912C42F005D34B9 /* Moveable.cpp */, + 81225A7D0912C42F005D34B9 /* Moveable.h */, + 81225A7E0912C42F005D34B9 /* Mover.cpp */, + 81225A7F0912C42F005D34B9 /* Mover.h */, + 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */, + 81225A810912C42F005D34B9 /* MultiplayerGame.h */, + 81225A820912C42F005D34B9 /* physics */, + 81225AA50912C42F005D34B9 /* Player.cpp */, + 81225AA60912C42F005D34B9 /* Player.h */, + 81225AA70912C42F005D34B9 /* PlayerView.cpp */, + 81225AA80912C42F005D34B9 /* PlayerView.h */, + 81225AA90912C42F005D34B9 /* Projectile.cpp */, + 81225AAA0912C42F005D34B9 /* Projectile.h */, + 81225AAB0912C42F005D34B9 /* Pvs.cpp */, + 81225AAC0912C42F005D34B9 /* Pvs.h */, + 81225AAD0912C42F005D34B9 /* script */, + 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */, + 81225AB70912C42F005D34B9 /* SecurityCamera.h */, + 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */, + 81225AB90912C42F005D34B9 /* SmokeParticles.h */, + 81225ABA0912C42F005D34B9 /* Sound.cpp */, + 81225ABB0912C42F005D34B9 /* Sound.h */, + 81225ABC0912C42F005D34B9 /* Target.cpp */, + 81225ABD0912C42F005D34B9 /* Target.h */, + 81225ABE0912C42F005D34B9 /* Trigger.cpp */, + 81225ABF0912C42F005D34B9 /* Trigger.h */, + 81225AC00912C42F005D34B9 /* Weapon.cpp */, + 81225AC10912C42F005D34B9 /* Weapon.h */, + 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */, + 81225AC30912C42F005D34B9 /* WorldSpawn.h */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC0630554660B00DB518D /* game-d3xp.dylib */, + ); + name = Products; + sourceTree = ""; + }; + 81225A1C0912C3A4005D34B9 /* Products */ = { + isa = PBXGroup; + children = ( + 81225A210912C3A4005D34B9 /* libidlib_pic.a */, + 81225A230912C3A4005D34B9 /* libidlib_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 81225A420912C42F005D34B9 /* ai */ = { + isa = PBXGroup; + children = ( + 81225A430912C42F005D34B9 /* AAS.cpp */, + 81225A440912C42F005D34B9 /* AAS.h */, + 81225A450912C42F005D34B9 /* AAS_debug.cpp */, + 81225A460912C42F005D34B9 /* AAS_local.h */, + 81225A470912C42F005D34B9 /* AAS_pathing.cpp */, + 81225A480912C42F005D34B9 /* AAS_routing.cpp */, + 81225A490912C42F005D34B9 /* AI.cpp */, + 81225A4A0912C42F005D34B9 /* AI.h */, + 81225A4B0912C42F005D34B9 /* AI_events.cpp */, + 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */, + 81225A4D0912C42F005D34B9 /* AI_Vagary.cpp */, + ); + name = ai; + path = ../../d3xp/ai; + sourceTree = SOURCE_ROOT; + }; + 81225A4E0912C42F005D34B9 /* anim */ = { + isa = PBXGroup; + children = ( + 81225A4F0912C42F005D34B9 /* Anim.cpp */, + 81225A500912C42F005D34B9 /* Anim.h */, + 81225A510912C42F005D34B9 /* Anim_Blend.cpp */, + 81225A520912C42F005D34B9 /* Anim_Import.cpp */, + 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */, + 81225A540912C42F005D34B9 /* Anim_Testmodel.h */, + ); + name = anim; + path = ../../d3xp/anim; + sourceTree = SOURCE_ROOT; + }; + 81225A640912C42F005D34B9 /* gamesys */ = { + isa = PBXGroup; + children = ( + 81225A650912C42F005D34B9 /* Class.cpp */, + 81225A660912C42F005D34B9 /* Class.h */, + 81225A670912C42F005D34B9 /* DebugGraph.cpp */, + 81225A680912C42F005D34B9 /* DebugGraph.h */, + 81225A690912C42F005D34B9 /* Event.cpp */, + 81225A6A0912C42F005D34B9 /* Event.h */, + 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */, + 81225A6C0912C42F005D34B9 /* SaveGame.cpp */, + 81225A6D0912C42F005D34B9 /* SaveGame.h */, + 81225A6E0912C42F005D34B9 /* SysCmds.cpp */, + 81225A6F0912C42F005D34B9 /* SysCmds.h */, + 81225A700912C42F005D34B9 /* SysCvar.cpp */, + 81225A710912C42F005D34B9 /* SysCvar.h */, + 81225A720912C42F005D34B9 /* TypeInfo.cpp */, + 81225A730912C42F005D34B9 /* TypeInfo.h */, + ); + name = gamesys; + path = ../../d3xp/gamesys; + sourceTree = SOURCE_ROOT; + }; + 81225A820912C42F005D34B9 /* physics */ = { + isa = PBXGroup; + children = ( + 25ACE0670B31FDFE00A159B2 /* Force_Grab.cpp */, + 81225A830912C42F005D34B9 /* Clip.cpp */, + 81225A840912C42F005D34B9 /* Clip.h */, + 81225A850912C42F005D34B9 /* Force.cpp */, + 81225A860912C42F005D34B9 /* Force.h */, + 81225A870912C42F005D34B9 /* Force_Constant.cpp */, + 81225A880912C42F005D34B9 /* Force_Constant.h */, + 81225A890912C42F005D34B9 /* Force_Drag.cpp */, + 81225A8A0912C42F005D34B9 /* Force_Drag.h */, + 81225A8B0912C42F005D34B9 /* Force_Field.cpp */, + 81225A8C0912C42F005D34B9 /* Force_Field.h */, + 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */, + 81225A8E0912C42F005D34B9 /* Force_Spring.h */, + 81225A8F0912C42F005D34B9 /* Physics.cpp */, + 81225A900912C42F005D34B9 /* Physics.h */, + 81225A910912C42F005D34B9 /* Physics_Actor.cpp */, + 81225A920912C42F005D34B9 /* Physics_Actor.h */, + 81225A930912C42F005D34B9 /* Physics_AF.cpp */, + 81225A940912C42F005D34B9 /* Physics_AF.h */, + 81225A950912C42F005D34B9 /* Physics_Base.cpp */, + 81225A960912C42F005D34B9 /* Physics_Base.h */, + 81225A970912C42F005D34B9 /* Physics_Monster.cpp */, + 81225A980912C42F005D34B9 /* Physics_Monster.h */, + 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */, + 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */, + 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */, + 81225A9C0912C42F005D34B9 /* Physics_Player.h */, + 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */, + 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */, + 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */, + 81225AA00912C42F005D34B9 /* Physics_Static.h */, + 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */, + 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */, + 81225AA30912C42F005D34B9 /* Push.cpp */, + 81225AA40912C42F005D34B9 /* Push.h */, + ); + name = physics; + path = ../../d3xp/physics; + sourceTree = SOURCE_ROOT; + }; + 81225AAD0912C42F005D34B9 /* script */ = { + isa = PBXGroup; + children = ( + 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */, + 81225AAF0912C42F005D34B9 /* Script_Compiler.h */, + 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */, + 81225AB10912C42F005D34B9 /* Script_Interpreter.h */, + 81225AB20912C42F005D34B9 /* Script_Program.cpp */, + 81225AB30912C42F005D34B9 /* Script_Program.h */, + 81225AB40912C42F005D34B9 /* Script_Thread.cpp */, + 81225AB50912C42F005D34B9 /* Script_Thread.h */, + ); + name = script; + path = ../../d3xp/script; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC0600554660B00DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225AC60912C42F005D34B9 /* Actor.h in Headers */, + 81225AC80912C42F005D34B9 /* AF.h in Headers */, + 81225ACA0912C42F005D34B9 /* AFEntity.h in Headers */, + 81225ACC0912C42F005D34B9 /* AAS.h in Headers */, + 81225ACE0912C42F005D34B9 /* AAS_local.h in Headers */, + 81225AD20912C42F005D34B9 /* AI.h in Headers */, + 81225AD70912C42F005D34B9 /* Anim.h in Headers */, + 81225ADB0912C42F005D34B9 /* Anim_Testmodel.h in Headers */, + 81225ADD0912C42F005D34B9 /* BrittleFracture.h in Headers */, + 81225ADF0912C42F005D34B9 /* Camera.h in Headers */, + 81225AE10912C42F005D34B9 /* Entity.h in Headers */, + 81225AE30912C42F005D34B9 /* Fx.h in Headers */, + 81225AE40912C42F005D34B9 /* Game.h in Headers */, + 81225AE60912C42F005D34B9 /* Game_local.h in Headers */, + 81225AE90912C42F005D34B9 /* GameEdit.h in Headers */, + 81225AEB0912C42F005D34B9 /* Class.h in Headers */, + 81225AED0912C42F005D34B9 /* DebugGraph.h in Headers */, + 81225AEF0912C42F005D34B9 /* Event.h in Headers */, + 81225AF00912C42F005D34B9 /* NoGameTypeInfo.h in Headers */, + 81225AF20912C42F005D34B9 /* SaveGame.h in Headers */, + 81225AF40912C42F005D34B9 /* SysCmds.h in Headers */, + 81225AF60912C42F005D34B9 /* SysCvar.h in Headers */, + 81225AF80912C42F005D34B9 /* TypeInfo.h in Headers */, + 81225AFA0912C42F005D34B9 /* IK.h in Headers */, + 81225AFC0912C42F005D34B9 /* Item.h in Headers */, + 81225AFE0912C42F005D34B9 /* Light.h in Headers */, + 81225B000912C42F005D34B9 /* Misc.h in Headers */, + 81225B020912C42F005D34B9 /* Moveable.h in Headers */, + 81225B040912C42F005D34B9 /* Mover.h in Headers */, + 81225B060912C42F005D34B9 /* MultiplayerGame.h in Headers */, + 81225B080912C42F005D34B9 /* Clip.h in Headers */, + 81225B0A0912C42F005D34B9 /* Force.h in Headers */, + 81225B0C0912C42F005D34B9 /* Force_Constant.h in Headers */, + 81225B0E0912C42F005D34B9 /* Force_Drag.h in Headers */, + 81225B100912C42F005D34B9 /* Force_Field.h in Headers */, + 81225B120912C42F005D34B9 /* Force_Spring.h in Headers */, + 81225B140912C42F005D34B9 /* Physics.h in Headers */, + 81225B160912C42F005D34B9 /* Physics_Actor.h in Headers */, + 81225B180912C42F005D34B9 /* Physics_AF.h in Headers */, + 81225B1A0912C42F005D34B9 /* Physics_Base.h in Headers */, + 81225B1C0912C42F005D34B9 /* Physics_Monster.h in Headers */, + 81225B1E0912C42F005D34B9 /* Physics_Parametric.h in Headers */, + 81225B200912C42F005D34B9 /* Physics_Player.h in Headers */, + 81225B220912C42F005D34B9 /* Physics_RigidBody.h in Headers */, + 81225B240912C42F005D34B9 /* Physics_Static.h in Headers */, + 81225B260912C42F005D34B9 /* Physics_StaticMulti.h in Headers */, + 81225B280912C42F005D34B9 /* Push.h in Headers */, + 81225B2A0912C42F005D34B9 /* Player.h in Headers */, + 81225B2C0912C42F005D34B9 /* PlayerView.h in Headers */, + 81225B2E0912C42F005D34B9 /* Projectile.h in Headers */, + 81225B300912C42F005D34B9 /* Pvs.h in Headers */, + 81225B320912C42F005D34B9 /* Script_Compiler.h in Headers */, + 81225B340912C42F005D34B9 /* Script_Interpreter.h in Headers */, + 81225B360912C42F005D34B9 /* Script_Program.h in Headers */, + 81225B380912C42F005D34B9 /* Script_Thread.h in Headers */, + 81225B3A0912C42F005D34B9 /* SecurityCamera.h in Headers */, + 81225B3C0912C42F005D34B9 /* SmokeParticles.h in Headers */, + 81225B3E0912C42F005D34B9 /* Sound.h in Headers */, + 81225B400912C42F005D34B9 /* Target.h in Headers */, + 81225B420912C42F005D34B9 /* Trigger.h in Headers */, + 81225B440912C42F005D34B9 /* Weapon.h in Headers */, + 81225B460912C42F005D34B9 /* WorldSpawn.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC0620554660B00DB518D /* game-d3xp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81225A240912C3A4005D34B9 /* Build configuration list for PBXNativeTarget "game-d3xp" */; + buildPhases = ( + D2AAC0600554660B00DB518D /* Headers */, + D2AAC0610554660B00DB518D /* Sources */, + D289988505E68E00004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 81225A390912C3C8005D34B9 /* PBXTargetDependency */, + ); + name = "game-d3xp"; + productName = game; + productReference = D2AAC0630554660B00DB518D /* game-d3xp.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 81225A280912C3A4005D34B9 /* Build configuration list for PBXProject "d3xp" */; + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* game */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 81225A1C0912C3A4005D34B9 /* Products */; + ProjectRef = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + }, + ); + targets = ( + D2AAC0620554660B00DB518D /* game-d3xp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 81225A210912C3A4005D34B9 /* libidlib_pic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_pic.a; + remoteRef = 81225A200912C3A4005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 81225A230912C3A4005D34B9 /* libidlib_nopic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_nopic.a; + remoteRef = 81225A220912C3A4005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC0610554660B00DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225AC40912C42F005D34B9 /* PlayerIcon.cpp in Sources */, + 81225AC50912C42F005D34B9 /* Actor.cpp in Sources */, + 81225AC70912C42F005D34B9 /* AF.cpp in Sources */, + 81225AC90912C42F005D34B9 /* AFEntity.cpp in Sources */, + 81225ACB0912C42F005D34B9 /* AAS.cpp in Sources */, + 81225ACD0912C42F005D34B9 /* AAS_debug.cpp in Sources */, + 81225ACF0912C42F005D34B9 /* AAS_pathing.cpp in Sources */, + 81225AD00912C42F005D34B9 /* AAS_routing.cpp in Sources */, + 81225AD10912C42F005D34B9 /* AI.cpp in Sources */, + 81225AD30912C42F005D34B9 /* AI_events.cpp in Sources */, + 81225AD40912C42F005D34B9 /* AI_pathing.cpp in Sources */, + 81225AD50912C42F005D34B9 /* AI_Vagary.cpp in Sources */, + 81225AD60912C42F005D34B9 /* Anim.cpp in Sources */, + 81225AD80912C42F005D34B9 /* Anim_Blend.cpp in Sources */, + 81225AD90912C42F005D34B9 /* Anim_Import.cpp in Sources */, + 81225ADA0912C42F005D34B9 /* Anim_Testmodel.cpp in Sources */, + 81225ADC0912C42F005D34B9 /* BrittleFracture.cpp in Sources */, + 81225ADE0912C42F005D34B9 /* Camera.cpp in Sources */, + 81225AE00912C42F005D34B9 /* Entity.cpp in Sources */, + 81225AE20912C42F005D34B9 /* Fx.cpp in Sources */, + 81225AE50912C42F005D34B9 /* Game_local.cpp in Sources */, + 81225AE70912C42F005D34B9 /* Game_network.cpp in Sources */, + 81225AE80912C42F005D34B9 /* GameEdit.cpp in Sources */, + 81225AEA0912C42F005D34B9 /* Class.cpp in Sources */, + 81225AEC0912C42F005D34B9 /* DebugGraph.cpp in Sources */, + 81225AEE0912C42F005D34B9 /* Event.cpp in Sources */, + 81225AF10912C42F005D34B9 /* SaveGame.cpp in Sources */, + 81225AF30912C42F005D34B9 /* SysCmds.cpp in Sources */, + 81225AF50912C42F005D34B9 /* SysCvar.cpp in Sources */, + 81225AF70912C42F005D34B9 /* TypeInfo.cpp in Sources */, + 81225AF90912C42F005D34B9 /* IK.cpp in Sources */, + 81225AFB0912C42F005D34B9 /* Item.cpp in Sources */, + 81225AFD0912C42F005D34B9 /* Light.cpp in Sources */, + 81225AFF0912C42F005D34B9 /* Misc.cpp in Sources */, + 81225B010912C42F005D34B9 /* Moveable.cpp in Sources */, + 81225B030912C42F005D34B9 /* Mover.cpp in Sources */, + 81225B050912C42F005D34B9 /* MultiplayerGame.cpp in Sources */, + 81225B070912C42F005D34B9 /* Clip.cpp in Sources */, + 81225B090912C42F005D34B9 /* Force.cpp in Sources */, + 81225B0B0912C42F005D34B9 /* Force_Constant.cpp in Sources */, + 81225B0D0912C42F005D34B9 /* Force_Drag.cpp in Sources */, + 81225B0F0912C42F005D34B9 /* Force_Field.cpp in Sources */, + 81225B110912C42F005D34B9 /* Force_Spring.cpp in Sources */, + 81225B130912C42F005D34B9 /* Physics.cpp in Sources */, + 81225B150912C42F005D34B9 /* Physics_Actor.cpp in Sources */, + 81225B170912C42F005D34B9 /* Physics_AF.cpp in Sources */, + 81225B190912C42F005D34B9 /* Physics_Base.cpp in Sources */, + 81225B1B0912C42F005D34B9 /* Physics_Monster.cpp in Sources */, + 81225B1D0912C42F005D34B9 /* Physics_Parametric.cpp in Sources */, + 81225B1F0912C42F005D34B9 /* Physics_Player.cpp in Sources */, + 81225B210912C42F005D34B9 /* Physics_RigidBody.cpp in Sources */, + 81225B230912C42F005D34B9 /* Physics_Static.cpp in Sources */, + 81225B250912C42F005D34B9 /* Physics_StaticMulti.cpp in Sources */, + 81225B270912C42F005D34B9 /* Push.cpp in Sources */, + 81225B290912C42F005D34B9 /* Player.cpp in Sources */, + 81225B2B0912C42F005D34B9 /* PlayerView.cpp in Sources */, + 81225B2D0912C42F005D34B9 /* Projectile.cpp in Sources */, + 81225B2F0912C42F005D34B9 /* Pvs.cpp in Sources */, + 81225B310912C42F005D34B9 /* Script_Compiler.cpp in Sources */, + 81225B330912C42F005D34B9 /* Script_Interpreter.cpp in Sources */, + 81225B350912C42F005D34B9 /* Script_Program.cpp in Sources */, + 81225B370912C42F005D34B9 /* Script_Thread.cpp in Sources */, + 81225B390912C42F005D34B9 /* SecurityCamera.cpp in Sources */, + 81225B3B0912C42F005D34B9 /* SmokeParticles.cpp in Sources */, + 81225B3D0912C42F005D34B9 /* Sound.cpp in Sources */, + 81225B3F0912C42F005D34B9 /* Target.cpp in Sources */, + 81225B410912C42F005D34B9 /* Trigger.cpp in Sources */, + 81225B430912C42F005D34B9 /* Weapon.cpp in Sources */, + 81225B450912C42F005D34B9 /* WorldSpawn.cpp in Sources */, + 25ACE0660B31FDED00A159B2 /* Grabber.cpp in Sources */, + 25ACE0680B31FDFE00A159B2 /* Force_Grab.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 81225A390912C3C8005D34B9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = idlib_pic; + targetProxy = 81225A380912C3C8005D34B9 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 81225A250912C3A4005D34B9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MAIN_CPP_DEFINES = _DEBUG; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = game; + ZERO_LINK = YES; + }; + name = Debug; + }; + 81225A260912C3A4005D34B9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = "game-d3xp"; + SYMROOT = build; + ZERO_LINK = NO; + }; + name = Release; + }; + 81225A270912C3A4005D34B9 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_ONE_BYTE_BOOL = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + GAME_DLL, + __WITH_PB__, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = game; + }; + name = Default; + }; + 81225A290912C3A4005D34B9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_ONE_BYTE_BOOL = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + _D3XP, + CTF, + _DEBUG, + MACOS_X, + GAME_DLL, + __WITH_PB__, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 81225A2A0912C3A4005D34B9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + _D3XP, + CTF, + MACOS_X, + GAME_DLL, + __WITH_PB__, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + "-fomit-frame-pointer", + "-fno-common", + ); + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; + 81225A2B0912C3A4005D34B9 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_ONE_BYTE_BOOL = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + _D3XP, + CTF, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 81225A240912C3A4005D34B9 /* Build configuration list for PBXNativeTarget "game-d3xp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81225A250912C3A4005D34B9 /* Debug */, + 81225A260912C3A4005D34B9 /* Release */, + 81225A270912C3A4005D34B9 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 81225A280912C3A4005D34B9 /* Build configuration list for PBXProject "d3xp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81225A290912C3A4005D34B9 /* Debug */, + 81225A2A0912C3A4005D34B9 /* Release */, + 81225A2B0912C3A4005D34B9 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/sys/osx/devil.xcodeproj/project.pbxproj b/sys/osx/devil.xcodeproj/project.pbxproj new file mode 100644 index 000000000..b0c7d9a2d --- /dev/null +++ b/sys/osx/devil.xcodeproj/project.pbxproj @@ -0,0 +1,492 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3A176919149354EB0077AB23 /* altivec_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E1149354EB0077AB23 /* altivec_common.c */; }; + 3A17691A149354EB0077AB23 /* altivec_typeconversion.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E2149354EB0077AB23 /* altivec_typeconversion.c */; }; + 3A17691B149354EB0077AB23 /* il_alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E3149354EB0077AB23 /* il_alloc.c */; }; + 3A17691C149354EB0077AB23 /* il_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E4149354EB0077AB23 /* il_bits.c */; }; + 3A17691D149354EB0077AB23 /* il_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E5149354EB0077AB23 /* il_bmp.c */; }; + 3A17691E149354EB0077AB23 /* il_convbuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E6149354EB0077AB23 /* il_convbuff.c */; }; + 3A17691F149354EB0077AB23 /* il_convert.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E7149354EB0077AB23 /* il_convert.c */; }; + 3A176920149354EB0077AB23 /* il_cut.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E8149354EB0077AB23 /* il_cut.c */; }; + 3A176921149354EB0077AB23 /* il_dcx.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768E9149354EB0077AB23 /* il_dcx.c */; }; + 3A176922149354EB0077AB23 /* il_dds-save.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768EA149354EB0077AB23 /* il_dds-save.c */; }; + 3A176923149354EB0077AB23 /* il_dds.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768EB149354EB0077AB23 /* il_dds.c */; }; + 3A176924149354EB0077AB23 /* il_devil.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768EC149354EB0077AB23 /* il_devil.c */; }; + 3A176925149354EB0077AB23 /* il_doom.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768ED149354EB0077AB23 /* il_doom.c */; }; + 3A176926149354EB0077AB23 /* il_endian.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768EE149354EB0077AB23 /* il_endian.c */; }; + 3A176927149354EB0077AB23 /* il_error.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768EF149354EB0077AB23 /* il_error.c */; }; + 3A176928149354EB0077AB23 /* il_fastconv.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F0149354EB0077AB23 /* il_fastconv.c */; }; + 3A176929149354EB0077AB23 /* il_files.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F1149354EB0077AB23 /* il_files.c */; }; + 3A17692A149354EB0077AB23 /* il_gif.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F2149354EB0077AB23 /* il_gif.c */; }; + 3A17692B149354EB0077AB23 /* il_hdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F3149354EB0077AB23 /* il_hdr.c */; }; + 3A17692C149354EB0077AB23 /* il_header.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F4149354EB0077AB23 /* il_header.c */; }; + 3A17692D149354EB0077AB23 /* il_icns.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F5149354EB0077AB23 /* il_icns.c */; }; + 3A17692E149354EB0077AB23 /* il_icon.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F6149354EB0077AB23 /* il_icon.c */; }; + 3A17692F149354EB0077AB23 /* il_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F7149354EB0077AB23 /* il_internal.c */; }; + 3A176930149354EB0077AB23 /* il_io.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F8149354EB0077AB23 /* il_io.c */; }; + 3A176931149354EB0077AB23 /* il_jp2.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768F9149354EB0077AB23 /* il_jp2.c */; }; + 3A176932149354EB0077AB23 /* il_jpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FA149354EB0077AB23 /* il_jpeg.c */; }; + 3A176933149354EB0077AB23 /* il_lif.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FB149354EB0077AB23 /* il_lif.c */; }; + 3A176934149354EB0077AB23 /* il_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FC149354EB0077AB23 /* il_main.c */; }; + 3A176935149354EB0077AB23 /* il_manip.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FD149354EB0077AB23 /* il_manip.c */; }; + 3A176936149354EB0077AB23 /* il_mdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FE149354EB0077AB23 /* il_mdl.c */; }; + 3A176937149354EB0077AB23 /* il_mng.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A1768FF149354EB0077AB23 /* il_mng.c */; }; + 3A176938149354EB0077AB23 /* il_neuquant.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176900149354EB0077AB23 /* il_neuquant.c */; }; + 3A176939149354EB0077AB23 /* il_pal.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176901149354EB0077AB23 /* il_pal.c */; }; + 3A17693A149354EB0077AB23 /* il_pcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176902149354EB0077AB23 /* il_pcd.c */; }; + 3A17693B149354EB0077AB23 /* il_pcx.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176903149354EB0077AB23 /* il_pcx.c */; }; + 3A17693C149354EB0077AB23 /* il_pic.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176904149354EB0077AB23 /* il_pic.c */; }; + 3A17693D149354EB0077AB23 /* il_pix.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176905149354EB0077AB23 /* il_pix.c */; }; + 3A17693E149354EB0077AB23 /* il_png.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176906149354EB0077AB23 /* il_png.c */; }; + 3A17693F149354EB0077AB23 /* il_pnm.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176907149354EB0077AB23 /* il_pnm.c */; }; + 3A176940149354EB0077AB23 /* il_profiles.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176908149354EB0077AB23 /* il_profiles.c */; }; + 3A176941149354EB0077AB23 /* il_psd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176909149354EB0077AB23 /* il_psd.c */; }; + 3A176942149354EB0077AB23 /* il_psp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690A149354EB0077AB23 /* il_psp.c */; }; + 3A176943149354EB0077AB23 /* il_pxr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690B149354EB0077AB23 /* il_pxr.c */; }; + 3A176944149354EB0077AB23 /* il_quantizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690C149354EB0077AB23 /* il_quantizer.c */; }; + 3A176945149354EB0077AB23 /* il_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690D149354EB0077AB23 /* il_raw.c */; }; + 3A176946149354EB0077AB23 /* il_rawdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690E149354EB0077AB23 /* il_rawdata.c */; }; + 3A176947149354EB0077AB23 /* il_register.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A17690F149354EB0077AB23 /* il_register.c */; }; + 3A176948149354EB0077AB23 /* il_rle.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176910149354EB0077AB23 /* il_rle.c */; }; + 3A176949149354EB0077AB23 /* il_sgi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176911149354EB0077AB23 /* il_sgi.c */; }; + 3A17694A149354EB0077AB23 /* il_stack.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176912149354EB0077AB23 /* il_stack.c */; }; + 3A17694B149354EB0077AB23 /* il_states.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176913149354EB0077AB23 /* il_states.c */; }; + 3A17694C149354EB0077AB23 /* il_targa.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176914149354EB0077AB23 /* il_targa.c */; }; + 3A17694D149354EB0077AB23 /* il_tiff.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176915149354EB0077AB23 /* il_tiff.c */; }; + 3A17694E149354EB0077AB23 /* il_utility.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176916149354EB0077AB23 /* il_utility.c */; }; + 3A17694F149354EB0077AB23 /* il_wal.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176917149354EB0077AB23 /* il_wal.c */; }; + 3A176950149354EB0077AB23 /* il_xpm.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176918149354EB0077AB23 /* il_xpm.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3A176D6714936F6C0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D6314936F6C0077AB23 /* jpeg.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A176B561493626B0077AB23 /* libjpeg.a */; + remoteInfo = jpeg; + }; + 3A176D6D14936F720077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D6914936F720077AB23 /* png.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A176C98149365AD0077AB23 /* libpng.a */; + remoteInfo = png; + }; + 3A176D7114936F7C0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D6914936F720077AB23 /* png.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A176C97149365AD0077AB23 /* png */; + remoteInfo = png; + }; + 3A176D7314936F7E0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D6314936F6C0077AB23 /* jpeg.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A176B551493626B0077AB23 /* jpeg */; + remoteInfo = jpeg; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3A17681B149350DE0077AB23 /* libdevil.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdevil.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A1768E1149354EB0077AB23 /* altivec_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = altivec_common.c; path = ../../lib/devil/altivec_common.c; sourceTree = SOURCE_ROOT; }; + 3A1768E2149354EB0077AB23 /* altivec_typeconversion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = altivec_typeconversion.c; path = ../../lib/devil/altivec_typeconversion.c; sourceTree = SOURCE_ROOT; }; + 3A1768E3149354EB0077AB23 /* il_alloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_alloc.c; path = ../../lib/devil/il_alloc.c; sourceTree = SOURCE_ROOT; }; + 3A1768E4149354EB0077AB23 /* il_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_bits.c; path = ../../lib/devil/il_bits.c; sourceTree = SOURCE_ROOT; }; + 3A1768E5149354EB0077AB23 /* il_bmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_bmp.c; path = ../../lib/devil/il_bmp.c; sourceTree = SOURCE_ROOT; }; + 3A1768E6149354EB0077AB23 /* il_convbuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_convbuff.c; path = ../../lib/devil/il_convbuff.c; sourceTree = SOURCE_ROOT; }; + 3A1768E7149354EB0077AB23 /* il_convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_convert.c; path = ../../lib/devil/il_convert.c; sourceTree = SOURCE_ROOT; }; + 3A1768E8149354EB0077AB23 /* il_cut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_cut.c; path = ../../lib/devil/il_cut.c; sourceTree = SOURCE_ROOT; }; + 3A1768E9149354EB0077AB23 /* il_dcx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_dcx.c; path = ../../lib/devil/il_dcx.c; sourceTree = SOURCE_ROOT; }; + 3A1768EA149354EB0077AB23 /* il_dds-save.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "il_dds-save.c"; path = "../../lib/devil/il_dds-save.c"; sourceTree = SOURCE_ROOT; }; + 3A1768EB149354EB0077AB23 /* il_dds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_dds.c; path = ../../lib/devil/il_dds.c; sourceTree = SOURCE_ROOT; }; + 3A1768EC149354EB0077AB23 /* il_devil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_devil.c; path = ../../lib/devil/il_devil.c; sourceTree = SOURCE_ROOT; }; + 3A1768ED149354EB0077AB23 /* il_doom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_doom.c; path = ../../lib/devil/il_doom.c; sourceTree = SOURCE_ROOT; }; + 3A1768EE149354EB0077AB23 /* il_endian.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_endian.c; path = ../../lib/devil/il_endian.c; sourceTree = SOURCE_ROOT; }; + 3A1768EF149354EB0077AB23 /* il_error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_error.c; path = ../../lib/devil/il_error.c; sourceTree = SOURCE_ROOT; }; + 3A1768F0149354EB0077AB23 /* il_fastconv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_fastconv.c; path = ../../lib/devil/il_fastconv.c; sourceTree = SOURCE_ROOT; }; + 3A1768F1149354EB0077AB23 /* il_files.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_files.c; path = ../../lib/devil/il_files.c; sourceTree = SOURCE_ROOT; }; + 3A1768F2149354EB0077AB23 /* il_gif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_gif.c; path = ../../lib/devil/il_gif.c; sourceTree = SOURCE_ROOT; }; + 3A1768F3149354EB0077AB23 /* il_hdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_hdr.c; path = ../../lib/devil/il_hdr.c; sourceTree = SOURCE_ROOT; }; + 3A1768F4149354EB0077AB23 /* il_header.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_header.c; path = ../../lib/devil/il_header.c; sourceTree = SOURCE_ROOT; }; + 3A1768F5149354EB0077AB23 /* il_icns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_icns.c; path = ../../lib/devil/il_icns.c; sourceTree = SOURCE_ROOT; }; + 3A1768F6149354EB0077AB23 /* il_icon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_icon.c; path = ../../lib/devil/il_icon.c; sourceTree = SOURCE_ROOT; }; + 3A1768F7149354EB0077AB23 /* il_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_internal.c; path = ../../lib/devil/il_internal.c; sourceTree = SOURCE_ROOT; }; + 3A1768F8149354EB0077AB23 /* il_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_io.c; path = ../../lib/devil/il_io.c; sourceTree = SOURCE_ROOT; }; + 3A1768F9149354EB0077AB23 /* il_jp2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_jp2.c; path = ../../lib/devil/il_jp2.c; sourceTree = SOURCE_ROOT; }; + 3A1768FA149354EB0077AB23 /* il_jpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_jpeg.c; path = ../../lib/devil/il_jpeg.c; sourceTree = SOURCE_ROOT; }; + 3A1768FB149354EB0077AB23 /* il_lif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_lif.c; path = ../../lib/devil/il_lif.c; sourceTree = SOURCE_ROOT; }; + 3A1768FC149354EB0077AB23 /* il_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_main.c; path = ../../lib/devil/il_main.c; sourceTree = SOURCE_ROOT; }; + 3A1768FD149354EB0077AB23 /* il_manip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_manip.c; path = ../../lib/devil/il_manip.c; sourceTree = SOURCE_ROOT; }; + 3A1768FE149354EB0077AB23 /* il_mdl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_mdl.c; path = ../../lib/devil/il_mdl.c; sourceTree = SOURCE_ROOT; }; + 3A1768FF149354EB0077AB23 /* il_mng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_mng.c; path = ../../lib/devil/il_mng.c; sourceTree = SOURCE_ROOT; }; + 3A176900149354EB0077AB23 /* il_neuquant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_neuquant.c; path = ../../lib/devil/il_neuquant.c; sourceTree = SOURCE_ROOT; }; + 3A176901149354EB0077AB23 /* il_pal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pal.c; path = ../../lib/devil/il_pal.c; sourceTree = SOURCE_ROOT; }; + 3A176902149354EB0077AB23 /* il_pcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pcd.c; path = ../../lib/devil/il_pcd.c; sourceTree = SOURCE_ROOT; }; + 3A176903149354EB0077AB23 /* il_pcx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pcx.c; path = ../../lib/devil/il_pcx.c; sourceTree = SOURCE_ROOT; }; + 3A176904149354EB0077AB23 /* il_pic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pic.c; path = ../../lib/devil/il_pic.c; sourceTree = SOURCE_ROOT; }; + 3A176905149354EB0077AB23 /* il_pix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pix.c; path = ../../lib/devil/il_pix.c; sourceTree = SOURCE_ROOT; }; + 3A176906149354EB0077AB23 /* il_png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_png.c; path = ../../lib/devil/il_png.c; sourceTree = SOURCE_ROOT; }; + 3A176907149354EB0077AB23 /* il_pnm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pnm.c; path = ../../lib/devil/il_pnm.c; sourceTree = SOURCE_ROOT; }; + 3A176908149354EB0077AB23 /* il_profiles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_profiles.c; path = ../../lib/devil/il_profiles.c; sourceTree = SOURCE_ROOT; }; + 3A176909149354EB0077AB23 /* il_psd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_psd.c; path = ../../lib/devil/il_psd.c; sourceTree = SOURCE_ROOT; }; + 3A17690A149354EB0077AB23 /* il_psp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_psp.c; path = ../../lib/devil/il_psp.c; sourceTree = SOURCE_ROOT; }; + 3A17690B149354EB0077AB23 /* il_pxr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_pxr.c; path = ../../lib/devil/il_pxr.c; sourceTree = SOURCE_ROOT; }; + 3A17690C149354EB0077AB23 /* il_quantizer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_quantizer.c; path = ../../lib/devil/il_quantizer.c; sourceTree = SOURCE_ROOT; }; + 3A17690D149354EB0077AB23 /* il_raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_raw.c; path = ../../lib/devil/il_raw.c; sourceTree = SOURCE_ROOT; }; + 3A17690E149354EB0077AB23 /* il_rawdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_rawdata.c; path = ../../lib/devil/il_rawdata.c; sourceTree = SOURCE_ROOT; }; + 3A17690F149354EB0077AB23 /* il_register.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_register.c; path = ../../lib/devil/il_register.c; sourceTree = SOURCE_ROOT; }; + 3A176910149354EB0077AB23 /* il_rle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_rle.c; path = ../../lib/devil/il_rle.c; sourceTree = SOURCE_ROOT; }; + 3A176911149354EB0077AB23 /* il_sgi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_sgi.c; path = ../../lib/devil/il_sgi.c; sourceTree = SOURCE_ROOT; }; + 3A176912149354EB0077AB23 /* il_stack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_stack.c; path = ../../lib/devil/il_stack.c; sourceTree = SOURCE_ROOT; }; + 3A176913149354EB0077AB23 /* il_states.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_states.c; path = ../../lib/devil/il_states.c; sourceTree = SOURCE_ROOT; }; + 3A176914149354EB0077AB23 /* il_targa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_targa.c; path = ../../lib/devil/il_targa.c; sourceTree = SOURCE_ROOT; }; + 3A176915149354EB0077AB23 /* il_tiff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_tiff.c; path = ../../lib/devil/il_tiff.c; sourceTree = SOURCE_ROOT; }; + 3A176916149354EB0077AB23 /* il_utility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_utility.c; path = ../../lib/devil/il_utility.c; sourceTree = SOURCE_ROOT; }; + 3A176917149354EB0077AB23 /* il_wal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_wal.c; path = ../../lib/devil/il_wal.c; sourceTree = SOURCE_ROOT; }; + 3A176918149354EB0077AB23 /* il_xpm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = il_xpm.c; path = ../../lib/devil/il_xpm.c; sourceTree = SOURCE_ROOT; }; + 3A176D6314936F6C0077AB23 /* jpeg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = jpeg.xcodeproj; sourceTree = ""; }; + 3A176D6914936F720077AB23 /* png.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = png.xcodeproj; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3A176819149350DE0077AB23 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3A176801149350650077AB23 = { + isa = PBXGroup; + children = ( + 3A176D6914936F720077AB23 /* png.xcodeproj */, + 3A176D6314936F6C0077AB23 /* jpeg.xcodeproj */, + 3A1768E1149354EB0077AB23 /* altivec_common.c */, + 3A1768E2149354EB0077AB23 /* altivec_typeconversion.c */, + 3A1768E3149354EB0077AB23 /* il_alloc.c */, + 3A1768E4149354EB0077AB23 /* il_bits.c */, + 3A1768E5149354EB0077AB23 /* il_bmp.c */, + 3A1768E6149354EB0077AB23 /* il_convbuff.c */, + 3A1768E7149354EB0077AB23 /* il_convert.c */, + 3A1768E8149354EB0077AB23 /* il_cut.c */, + 3A1768E9149354EB0077AB23 /* il_dcx.c */, + 3A1768EA149354EB0077AB23 /* il_dds-save.c */, + 3A1768EB149354EB0077AB23 /* il_dds.c */, + 3A1768EC149354EB0077AB23 /* il_devil.c */, + 3A1768ED149354EB0077AB23 /* il_doom.c */, + 3A1768EE149354EB0077AB23 /* il_endian.c */, + 3A1768EF149354EB0077AB23 /* il_error.c */, + 3A1768F0149354EB0077AB23 /* il_fastconv.c */, + 3A1768F1149354EB0077AB23 /* il_files.c */, + 3A1768F2149354EB0077AB23 /* il_gif.c */, + 3A1768F3149354EB0077AB23 /* il_hdr.c */, + 3A1768F4149354EB0077AB23 /* il_header.c */, + 3A1768F5149354EB0077AB23 /* il_icns.c */, + 3A1768F6149354EB0077AB23 /* il_icon.c */, + 3A1768F7149354EB0077AB23 /* il_internal.c */, + 3A1768F8149354EB0077AB23 /* il_io.c */, + 3A1768F9149354EB0077AB23 /* il_jp2.c */, + 3A1768FA149354EB0077AB23 /* il_jpeg.c */, + 3A1768FB149354EB0077AB23 /* il_lif.c */, + 3A1768FC149354EB0077AB23 /* il_main.c */, + 3A1768FD149354EB0077AB23 /* il_manip.c */, + 3A1768FE149354EB0077AB23 /* il_mdl.c */, + 3A1768FF149354EB0077AB23 /* il_mng.c */, + 3A176900149354EB0077AB23 /* il_neuquant.c */, + 3A176901149354EB0077AB23 /* il_pal.c */, + 3A176902149354EB0077AB23 /* il_pcd.c */, + 3A176903149354EB0077AB23 /* il_pcx.c */, + 3A176904149354EB0077AB23 /* il_pic.c */, + 3A176905149354EB0077AB23 /* il_pix.c */, + 3A176906149354EB0077AB23 /* il_png.c */, + 3A176907149354EB0077AB23 /* il_pnm.c */, + 3A176908149354EB0077AB23 /* il_profiles.c */, + 3A176909149354EB0077AB23 /* il_psd.c */, + 3A17690A149354EB0077AB23 /* il_psp.c */, + 3A17690B149354EB0077AB23 /* il_pxr.c */, + 3A17690C149354EB0077AB23 /* il_quantizer.c */, + 3A17690D149354EB0077AB23 /* il_raw.c */, + 3A17690E149354EB0077AB23 /* il_rawdata.c */, + 3A17690F149354EB0077AB23 /* il_register.c */, + 3A176910149354EB0077AB23 /* il_rle.c */, + 3A176911149354EB0077AB23 /* il_sgi.c */, + 3A176912149354EB0077AB23 /* il_stack.c */, + 3A176913149354EB0077AB23 /* il_states.c */, + 3A176914149354EB0077AB23 /* il_targa.c */, + 3A176915149354EB0077AB23 /* il_tiff.c */, + 3A176916149354EB0077AB23 /* il_utility.c */, + 3A176917149354EB0077AB23 /* il_wal.c */, + 3A176918149354EB0077AB23 /* il_xpm.c */, + 3A17681C149350DE0077AB23 /* Products */, + ); + sourceTree = ""; + }; + 3A17681C149350DE0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A17681B149350DE0077AB23 /* libdevil.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176D6414936F6C0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176D6814936F6C0077AB23 /* libjpeg.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176D6A14936F720077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176D6E14936F720077AB23 /* libpng.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3A176817149350DE0077AB23 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3A17681A149350DE0077AB23 /* devil */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3A17681F149350DF0077AB23 /* Build configuration list for PBXNativeTarget "devil" */; + buildPhases = ( + 3A176817149350DE0077AB23 /* Headers */, + 3A176818149350DE0077AB23 /* Sources */, + 3A176819149350DE0077AB23 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3A176D7214936F7C0077AB23 /* PBXTargetDependency */, + 3A176D7414936F7E0077AB23 /* PBXTargetDependency */, + ); + name = devil; + productName = libdevil.a; + productReference = 3A17681B149350DE0077AB23 /* libdevil.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3A176803149350650077AB23 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 3A176806149350650077AB23 /* Build configuration list for PBXProject "devil" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 0; + mainGroup = 3A176801149350650077AB23; + productRefGroup = 3A17681C149350DE0077AB23 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 3A176D6414936F6C0077AB23 /* Products */; + ProjectRef = 3A176D6314936F6C0077AB23 /* jpeg.xcodeproj */; + }, + { + ProductGroup = 3A176D6A14936F720077AB23 /* Products */; + ProjectRef = 3A176D6914936F720077AB23 /* png.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 3A17681A149350DE0077AB23 /* devil */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 3A176D6814936F6C0077AB23 /* libjpeg.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libjpeg.a; + remoteRef = 3A176D6714936F6C0077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3A176D6E14936F720077AB23 /* libpng.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libpng.a; + remoteRef = 3A176D6D14936F720077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + 3A176818149350DE0077AB23 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A176919149354EB0077AB23 /* altivec_common.c in Sources */, + 3A17691A149354EB0077AB23 /* altivec_typeconversion.c in Sources */, + 3A17691B149354EB0077AB23 /* il_alloc.c in Sources */, + 3A17691C149354EB0077AB23 /* il_bits.c in Sources */, + 3A17691D149354EB0077AB23 /* il_bmp.c in Sources */, + 3A17691E149354EB0077AB23 /* il_convbuff.c in Sources */, + 3A17691F149354EB0077AB23 /* il_convert.c in Sources */, + 3A176920149354EB0077AB23 /* il_cut.c in Sources */, + 3A176921149354EB0077AB23 /* il_dcx.c in Sources */, + 3A176922149354EB0077AB23 /* il_dds-save.c in Sources */, + 3A176923149354EB0077AB23 /* il_dds.c in Sources */, + 3A176924149354EB0077AB23 /* il_devil.c in Sources */, + 3A176925149354EB0077AB23 /* il_doom.c in Sources */, + 3A176926149354EB0077AB23 /* il_endian.c in Sources */, + 3A176927149354EB0077AB23 /* il_error.c in Sources */, + 3A176928149354EB0077AB23 /* il_fastconv.c in Sources */, + 3A176929149354EB0077AB23 /* il_files.c in Sources */, + 3A17692A149354EB0077AB23 /* il_gif.c in Sources */, + 3A17692B149354EB0077AB23 /* il_hdr.c in Sources */, + 3A17692C149354EB0077AB23 /* il_header.c in Sources */, + 3A17692D149354EB0077AB23 /* il_icns.c in Sources */, + 3A17692E149354EB0077AB23 /* il_icon.c in Sources */, + 3A17692F149354EB0077AB23 /* il_internal.c in Sources */, + 3A176930149354EB0077AB23 /* il_io.c in Sources */, + 3A176931149354EB0077AB23 /* il_jp2.c in Sources */, + 3A176932149354EB0077AB23 /* il_jpeg.c in Sources */, + 3A176933149354EB0077AB23 /* il_lif.c in Sources */, + 3A176934149354EB0077AB23 /* il_main.c in Sources */, + 3A176935149354EB0077AB23 /* il_manip.c in Sources */, + 3A176936149354EB0077AB23 /* il_mdl.c in Sources */, + 3A176937149354EB0077AB23 /* il_mng.c in Sources */, + 3A176938149354EB0077AB23 /* il_neuquant.c in Sources */, + 3A176939149354EB0077AB23 /* il_pal.c in Sources */, + 3A17693A149354EB0077AB23 /* il_pcd.c in Sources */, + 3A17693B149354EB0077AB23 /* il_pcx.c in Sources */, + 3A17693C149354EB0077AB23 /* il_pic.c in Sources */, + 3A17693D149354EB0077AB23 /* il_pix.c in Sources */, + 3A17693E149354EB0077AB23 /* il_png.c in Sources */, + 3A17693F149354EB0077AB23 /* il_pnm.c in Sources */, + 3A176940149354EB0077AB23 /* il_profiles.c in Sources */, + 3A176941149354EB0077AB23 /* il_psd.c in Sources */, + 3A176942149354EB0077AB23 /* il_psp.c in Sources */, + 3A176943149354EB0077AB23 /* il_pxr.c in Sources */, + 3A176944149354EB0077AB23 /* il_quantizer.c in Sources */, + 3A176945149354EB0077AB23 /* il_raw.c in Sources */, + 3A176946149354EB0077AB23 /* il_rawdata.c in Sources */, + 3A176947149354EB0077AB23 /* il_register.c in Sources */, + 3A176948149354EB0077AB23 /* il_rle.c in Sources */, + 3A176949149354EB0077AB23 /* il_sgi.c in Sources */, + 3A17694A149354EB0077AB23 /* il_stack.c in Sources */, + 3A17694B149354EB0077AB23 /* il_states.c in Sources */, + 3A17694C149354EB0077AB23 /* il_targa.c in Sources */, + 3A17694D149354EB0077AB23 /* il_tiff.c in Sources */, + 3A17694E149354EB0077AB23 /* il_utility.c in Sources */, + 3A17694F149354EB0077AB23 /* il_wal.c in Sources */, + 3A176950149354EB0077AB23 /* il_xpm.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3A176D7214936F7C0077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = png; + targetProxy = 3A176D7114936F7C0077AB23 /* PBXContainerItemProxy */; + }; + 3A176D7414936F7E0077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = jpeg; + targetProxy = 3A176D7314936F7E0077AB23 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3A176804149350650077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + name = Debug; + }; + 3A176805149350650077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + name = Release; + }; + 3A17681D149350DF0077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = devil; + }; + name = Debug; + }; + 3A17681E149350DF0077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H; + HEADER_SEARCH_PATHS = ""; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = devil; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/libjpeg/\" \"$(SRCROOT)/../../include/libpng/\" \"$(SRCROOT)/../../include/devil/\" \"$(SRCROOT)/../../include/devil/IL/\""; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3A176806149350650077AB23 /* Build configuration list for PBXProject "devil" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A176804149350650077AB23 /* Debug */, + 3A176805149350650077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3A17681F149350DF0077AB23 /* Build configuration list for PBXNativeTarget "devil" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A17681D149350DF0077AB23 /* Debug */, + 3A17681E149350DF0077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3A176803149350650077AB23 /* Project object */; +} diff --git a/sys/osx/game.xcodeproj/project.pbxproj b/sys/osx/game.xcodeproj/project.pbxproj new file mode 100644 index 000000000..36073496c --- /dev/null +++ b/sys/osx/game.xcodeproj/project.pbxproj @@ -0,0 +1,2737 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3A176BEF149363220077AB23 /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A176BEE149363220077AB23 /* libjpeg.a */; }; + 3A176BF11493632A0077AB23 /* libdevil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A176BF01493632A0077AB23 /* libdevil.a */; }; + 3A176BF3149363310077AB23 /* libziploader.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A176BF2149363310077AB23 /* libziploader.a */; }; + 3A176D091493668A0077AB23 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A176D081493668A0077AB23 /* libpng.a */; }; + 3A537695148E80FA006DC4CE /* BoolParseNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537685148E80FA006DC4CE /* BoolParseNode.h */; }; + 3A537696148E80FA006DC4CE /* CampaignStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537686148E80FA006DC4CE /* CampaignStatistics.cpp */; }; + 3A537697148E80FA006DC4CE /* CampaignStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537687148E80FA006DC4CE /* CampaignStatistics.h */; }; + 3A537698148E80FA006DC4CE /* EMissionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537688148E80FA006DC4CE /* EMissionResult.h */; }; + 3A537699148E80FA006DC4CE /* MissionData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537689148E80FA006DC4CE /* MissionData.cpp */; }; + 3A53769A148E80FA006DC4CE /* MissionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53768A148E80FA006DC4CE /* MissionData.h */; }; + 3A53769B148E80FA006DC4CE /* MissionStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53768B148E80FA006DC4CE /* MissionStatistics.cpp */; }; + 3A53769C148E80FA006DC4CE /* MissionStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53768C148E80FA006DC4CE /* MissionStatistics.h */; }; + 3A53769D148E80FA006DC4CE /* Objective.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53768D148E80FA006DC4CE /* Objective.cpp */; }; + 3A53769E148E80FA006DC4CE /* Objective.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53768E148E80FA006DC4CE /* Objective.h */; }; + 3A53769F148E80FA006DC4CE /* ObjectiveComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53768F148E80FA006DC4CE /* ObjectiveComponent.cpp */; }; + 3A5376A0148E80FA006DC4CE /* ObjectiveComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537690148E80FA006DC4CE /* ObjectiveComponent.h */; }; + 3A5376A1148E80FA006DC4CE /* ObjectiveCondition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537691148E80FA006DC4CE /* ObjectiveCondition.cpp */; }; + 3A5376A2148E80FA006DC4CE /* ObjectiveCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537692148E80FA006DC4CE /* ObjectiveCondition.h */; }; + 3A5376A3148E80FA006DC4CE /* ObjectiveLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537693148E80FA006DC4CE /* ObjectiveLocation.cpp */; }; + 3A5376A4148E80FA006DC4CE /* ObjectiveLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537694148E80FA006DC4CE /* ObjectiveLocation.h */; }; + 3A5376A9148E8114006DC4CE /* AbsenceMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376A7148E8114006DC4CE /* AbsenceMarker.cpp */; }; + 3A5376AA148E8114006DC4CE /* AbsenceMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376A8148E8114006DC4CE /* AbsenceMarker.h */; }; + 3A5376AF148E8121006DC4CE /* AIComm_Message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376AB148E8121006DC4CE /* AIComm_Message.cpp */; }; + 3A5376B0148E8121006DC4CE /* AIComm_Message.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376AC148E8121006DC4CE /* AIComm_Message.h */; }; + 3A5376B1148E8121006DC4CE /* AIVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376AD148E8121006DC4CE /* AIVehicle.cpp */; }; + 3A5376B2148E8121006DC4CE /* AIVehicle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376AE148E8121006DC4CE /* AIVehicle.h */; }; + 3A5376E7148E813B006DC4CE /* BinaryFrobMover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376B3148E813B006DC4CE /* BinaryFrobMover.cpp */; }; + 3A5376E8148E813B006DC4CE /* BinaryFrobMover.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376B4148E813B006DC4CE /* BinaryFrobMover.h */; }; + 3A5376E9148E813B006DC4CE /* BloodMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376B5148E813B006DC4CE /* BloodMarker.cpp */; }; + 3A5376EA148E813B006DC4CE /* BloodMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376B6148E813B006DC4CE /* BloodMarker.h */; }; + 3A5376EB148E813B006DC4CE /* ButtonStateTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376B7148E813B006DC4CE /* ButtonStateTracker.cpp */; }; + 3A5376EC148E813B006DC4CE /* ButtonStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376B8148E813B006DC4CE /* ButtonStateTracker.h */; }; + 3A5376ED148E813B006DC4CE /* CImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376B9148E813B006DC4CE /* CImage.cpp */; }; + 3A5376EE148E813B006DC4CE /* CImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376BA148E813B006DC4CE /* CImage.h */; }; + 3A5376EF148E813B006DC4CE /* DarkmodAASHidingSpotFinder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376BB148E813B006DC4CE /* DarkmodAASHidingSpotFinder.cpp */; }; + 3A5376F0148E813B006DC4CE /* DarkmodAASHidingSpotFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376BC148E813B006DC4CE /* DarkmodAASHidingSpotFinder.h */; }; + 3A5376F1148E813B006DC4CE /* DarkModGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376BD148E813B006DC4CE /* DarkModGlobals.cpp */; }; + 3A5376F2148E813B006DC4CE /* DarkModGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376BE148E813B006DC4CE /* DarkModGlobals.h */; }; + 3A5376F3148E813B006DC4CE /* darkmodHidingSpotTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376BF148E813B006DC4CE /* darkmodHidingSpotTree.cpp */; }; + 3A5376F4148E813B006DC4CE /* darkmodHidingSpotTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376C0148E813B006DC4CE /* darkmodHidingSpotTree.h */; }; + 3A5376F5148E813B006DC4CE /* darkModLAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376C1148E813B006DC4CE /* darkModLAS.cpp */; }; + 3A5376F6148E813B006DC4CE /* darkModLAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376C2148E813B006DC4CE /* darkModLAS.h */; }; + 3A5376F7148E813B006DC4CE /* decltdm_matinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376C3148E813B006DC4CE /* decltdm_matinfo.cpp */; }; + 3A5376F8148E813B006DC4CE /* decltdm_matinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376C4148E813B006DC4CE /* decltdm_matinfo.h */; }; + 3A5376F9148E813B006DC4CE /* declxdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376C5148E813B006DC4CE /* declxdata.cpp */; }; + 3A5376FA148E813B006DC4CE /* declxdata.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376C6148E813B006DC4CE /* declxdata.h */; }; + 3A5376FB148E813B006DC4CE /* DifficultyManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376C7148E813B006DC4CE /* DifficultyManager.cpp */; }; + 3A5376FC148E813B006DC4CE /* DifficultyManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376C8148E813B006DC4CE /* DifficultyManager.h */; }; + 3A5376FD148E813B006DC4CE /* DifficultySettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376C9148E813B006DC4CE /* DifficultySettings.cpp */; }; + 3A5376FE148E813B006DC4CE /* DifficultySettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376CA148E813B006DC4CE /* DifficultySettings.h */; }; + 3A5376FF148E813B006DC4CE /* DownloadMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376CB148E813B006DC4CE /* DownloadMenu.cpp */; }; + 3A537700148E813B006DC4CE /* DownloadMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376CC148E813B006DC4CE /* DownloadMenu.h */; }; + 3A537701148E813B006DC4CE /* Emitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376CD148E813B006DC4CE /* Emitter.cpp */; }; + 3A537702148E813B006DC4CE /* Emitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376CE148E813B006DC4CE /* Emitter.h */; }; + 3A537703148E813B006DC4CE /* EscapePointEvaluator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376CF148E813B006DC4CE /* EscapePointEvaluator.cpp */; }; + 3A537704148E813B006DC4CE /* EscapePointEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376D0148E813B006DC4CE /* EscapePointEvaluator.h */; }; + 3A537705148E813B006DC4CE /* EscapePointManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376D1148E813B006DC4CE /* EscapePointManager.cpp */; }; + 3A537706148E813B006DC4CE /* EscapePointManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376D2148E813B006DC4CE /* EscapePointManager.h */; }; + 3A537707148E813B006DC4CE /* Force_Grab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376D3148E813B006DC4CE /* Force_Grab.cpp */; }; + 3A537708148E813B006DC4CE /* Force_Grab.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376D4148E813B006DC4CE /* Force_Grab.h */; }; + 3A537709148E813B006DC4CE /* FrobButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376D5148E813B006DC4CE /* FrobButton.cpp */; }; + 3A53770A148E813B006DC4CE /* FrobButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376D6148E813B006DC4CE /* FrobButton.h */; }; + 3A53770B148E813B006DC4CE /* FrobDoor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376D7148E813B006DC4CE /* FrobDoor.cpp */; }; + 3A53770C148E813B006DC4CE /* FrobDoor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376D8148E813B006DC4CE /* FrobDoor.h */; }; + 3A53770D148E813B006DC4CE /* FrobDoorHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376D9148E813B006DC4CE /* FrobDoorHandle.cpp */; }; + 3A53770E148E813B006DC4CE /* FrobDoorHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376DA148E813B006DC4CE /* FrobDoorHandle.h */; }; + 3A53770F148E813B006DC4CE /* FrobHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376DB148E813B006DC4CE /* FrobHandle.cpp */; }; + 3A537710148E813B006DC4CE /* FrobHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376DC148E813B006DC4CE /* FrobHandle.h */; }; + 3A537711148E813B006DC4CE /* FrobLever.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376DD148E813B006DC4CE /* FrobLever.cpp */; }; + 3A537712148E813B006DC4CE /* FrobLever.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376DE148E813B006DC4CE /* FrobLever.h */; }; + 3A537713148E813B006DC4CE /* FrobLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376DF148E813B006DC4CE /* FrobLock.cpp */; }; + 3A537714148E813B006DC4CE /* FrobLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376E0148E813B006DC4CE /* FrobLock.h */; }; + 3A537715148E813B006DC4CE /* FrobLockHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376E1148E813B006DC4CE /* FrobLockHandle.cpp */; }; + 3A537716148E813B006DC4CE /* FrobLockHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376E2148E813B006DC4CE /* FrobLockHandle.h */; }; + 3A537717148E813B006DC4CE /* Func_Shooter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376E3148E813B006DC4CE /* Func_Shooter.cpp */; }; + 3A537718148E813B006DC4CE /* Func_Shooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376E4148E813B006DC4CE /* Func_Shooter.h */; }; + 3A537719148E813B006DC4CE /* FX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5376E5148E813B006DC4CE /* FX.cpp */; }; + 3A53771A148E813B006DC4CE /* FX.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5376E6148E813B006DC4CE /* FX.h */; }; + 3A53771C148E816A006DC4CE /* GamePlayTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53771B148E816A006DC4CE /* GamePlayTimer.h */; }; + 3A537728148E817F006DC4CE /* Grabber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53771D148E817F006DC4CE /* Grabber.cpp */; }; + 3A537729148E817F006DC4CE /* Grabber.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53771E148E817F006DC4CE /* Grabber.h */; }; + 3A53772A148E817F006DC4CE /* HidingSpotSearchCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53771F148E817F006DC4CE /* HidingSpotSearchCollection.cpp */; }; + 3A53772B148E817F006DC4CE /* HidingSpotSearchCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537720148E817F006DC4CE /* HidingSpotSearchCollection.h */; }; + 3A53772C148E817F006DC4CE /* HttpConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537722148E817F006DC4CE /* HttpConnection.cpp */; }; + 3A53772D148E817F006DC4CE /* HttpConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537723148E817F006DC4CE /* HttpConnection.h */; }; + 3A53772E148E817F006DC4CE /* HttpRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537724148E817F006DC4CE /* HttpRequest.cpp */; }; + 3A53772F148E817F006DC4CE /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537725148E817F006DC4CE /* HttpRequest.h */; }; + 3A537730148E817F006DC4CE /* I18N.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537726148E817F006DC4CE /* I18N.cpp */; }; + 3A537731148E817F006DC4CE /* I18N.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537727148E817F006DC4CE /* I18N.h */; }; + 3A537766148E8193006DC4CE /* ImageMapManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537732148E8193006DC4CE /* ImageMapManager.cpp */; }; + 3A537767148E8193006DC4CE /* ImageMapManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537733148E8193006DC4CE /* ImageMapManager.h */; }; + 3A537768148E8193006DC4CE /* IniFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537734148E8193006DC4CE /* IniFile.cpp */; }; + 3A537769148E8193006DC4CE /* IniFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537735148E8193006DC4CE /* IniFile.h */; }; + 3A53776A148E8193006DC4CE /* Intersection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537736148E8193006DC4CE /* Intersection.cpp */; }; + 3A53776B148E8193006DC4CE /* Intersection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537737148E8193006DC4CE /* Intersection.h */; }; + 3A53776C148E8193006DC4CE /* Category.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537739148E8193006DC4CE /* Category.cpp */; }; + 3A53776D148E8193006DC4CE /* Category.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53773A148E8193006DC4CE /* Category.h */; }; + 3A53776E148E8193006DC4CE /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53773B148E8193006DC4CE /* Cursor.cpp */; }; + 3A53776F148E8193006DC4CE /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53773C148E8193006DC4CE /* Cursor.h */; }; + 3A537770148E8193006DC4CE /* Inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53773D148E8193006DC4CE /* Inventory.cpp */; }; + 3A537771148E8193006DC4CE /* Inventory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53773E148E8193006DC4CE /* Inventory.h */; }; + 3A537772148E8193006DC4CE /* InventoryItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53773F148E8193006DC4CE /* InventoryItem.cpp */; }; + 3A537773148E8193006DC4CE /* InventoryItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537740148E8193006DC4CE /* InventoryItem.h */; }; + 3A537774148E8193006DC4CE /* LootType.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537741148E8193006DC4CE /* LootType.h */; }; + 3A537775148E8193006DC4CE /* WeaponItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537742148E8193006DC4CE /* WeaponItem.cpp */; }; + 3A537776148E8193006DC4CE /* WeaponItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537743148E8193006DC4CE /* WeaponItem.h */; }; + 3A537777148E8193006DC4CE /* LightController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537744148E8193006DC4CE /* LightController.cpp */; }; + 3A537778148E8193006DC4CE /* LightController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537745148E8193006DC4CE /* LightController.h */; }; + 3A537779148E8193006DC4CE /* LightGem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537746148E8193006DC4CE /* LightGem.cpp */; }; + 3A53777A148E8193006DC4CE /* LightGem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537747148E8193006DC4CE /* LightGem.h */; }; + 3A53777B148E8193006DC4CE /* Liquid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537748148E8193006DC4CE /* Liquid.cpp */; }; + 3A53777C148E8193006DC4CE /* Liquid.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537749148E8193006DC4CE /* Liquid.h */; }; + 3A53777D148E8193006DC4CE /* MaterialConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53774A148E8193006DC4CE /* MaterialConverter.cpp */; }; + 3A53777E148E8193006DC4CE /* MaterialConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53774B148E8193006DC4CE /* MaterialConverter.h */; }; + 3A53777F148E8193006DC4CE /* MatrixSq.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53774C148E8193006DC4CE /* MatrixSq.h */; }; + 3A537780148E8193006DC4CE /* MeleeWeapon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53774D148E8193006DC4CE /* MeleeWeapon.cpp */; }; + 3A537781148E8193006DC4CE /* MeleeWeapon.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53774E148E8193006DC4CE /* MeleeWeapon.h */; }; + 3A537782148E8193006DC4CE /* Download.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537750148E8193006DC4CE /* Download.cpp */; }; + 3A537783148E8193006DC4CE /* Download.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537751148E8193006DC4CE /* Download.h */; }; + 3A537784148E8193006DC4CE /* DownloadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537752148E8193006DC4CE /* DownloadManager.cpp */; }; + 3A537785148E8193006DC4CE /* DownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537753148E8193006DC4CE /* DownloadManager.h */; }; + 3A537786148E8193006DC4CE /* MissionDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537754148E8193006DC4CE /* MissionDB.cpp */; }; + 3A537787148E8193006DC4CE /* MissionDB.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537755148E8193006DC4CE /* MissionDB.h */; }; + 3A537788148E8193006DC4CE /* MissionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537756148E8193006DC4CE /* MissionManager.cpp */; }; + 3A537789148E8193006DC4CE /* MissionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537757148E8193006DC4CE /* MissionManager.h */; }; + 3A53778A148E8193006DC4CE /* ModInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537758148E8193006DC4CE /* ModInfo.cpp */; }; + 3A53778B148E8193006DC4CE /* ModInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537759148E8193006DC4CE /* ModInfo.h */; }; + 3A53778C148E8193006DC4CE /* ModInfoDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53775A148E8193006DC4CE /* ModInfoDecl.cpp */; }; + 3A53778D148E8193006DC4CE /* ModInfoDecl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53775B148E8193006DC4CE /* ModInfoDecl.h */; }; + 3A53778E148E8193006DC4CE /* ModelGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53775C148E8193006DC4CE /* ModelGenerator.cpp */; }; + 3A53778F148E8193006DC4CE /* ModelGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53775D148E8193006DC4CE /* ModelGenerator.h */; }; + 3A537790148E8193006DC4CE /* ModMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53775E148E8193006DC4CE /* ModMenu.cpp */; }; + 3A537791148E8193006DC4CE /* ModMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53775F148E8193006DC4CE /* ModMenu.h */; }; + 3A537792148E8193006DC4CE /* MultiStateMover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537760148E8193006DC4CE /* MultiStateMover.cpp */; }; + 3A537793148E8193006DC4CE /* MultiStateMover.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537761148E8193006DC4CE /* MultiStateMover.h */; }; + 3A537794148E8193006DC4CE /* MultiStateMoverButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537762148E8193006DC4CE /* MultiStateMoverButton.cpp */; }; + 3A537795148E8193006DC4CE /* MultiStateMoverButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537763148E8193006DC4CE /* MultiStateMoverButton.h */; }; + 3A537796148E8193006DC4CE /* MultiStateMoverPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537764148E8193006DC4CE /* MultiStateMoverPosition.cpp */; }; + 3A537797148E8193006DC4CE /* MultiStateMoverPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537765148E8193006DC4CE /* MultiStateMoverPosition.h */; }; + 3A53779A148E81A1006DC4CE /* OverlaySys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537798148E81A1006DC4CE /* OverlaySys.cpp */; }; + 3A53779B148E81A1006DC4CE /* OverlaySys.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537799148E81A1006DC4CE /* OverlaySys.h */; }; + 3A5377BC148E81C3006DC4CE /* PickableLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53779C148E81C3006DC4CE /* PickableLock.cpp */; }; + 3A5377BD148E81C3006DC4CE /* PickableLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53779D148E81C3006DC4CE /* PickableLock.h */; }; + 3A5377BE148E81C3006DC4CE /* PlayerIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53779E148E81C3006DC4CE /* PlayerIcon.h */; }; + 3A5377BF148E81C3006DC4CE /* PositionWithinRangeFinder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53779F148E81C3006DC4CE /* PositionWithinRangeFinder.cpp */; }; + 3A5377C0148E81C3006DC4CE /* PositionWithinRangeFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377A0148E81C3006DC4CE /* PositionWithinRangeFinder.h */; }; + 3A5377C1148E81C3006DC4CE /* ProjectileResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377A1148E81C3006DC4CE /* ProjectileResult.cpp */; }; + 3A5377C2148E81C3006DC4CE /* ProjectileResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377A2148E81C3006DC4CE /* ProjectileResult.h */; }; + 3A5377C3148E81C3006DC4CE /* pugiconfig.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377A4148E81C3006DC4CE /* pugiconfig.hpp */; }; + 3A5377C4148E81C3006DC4CE /* pugixml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377A5148E81C3006DC4CE /* pugixml.cpp */; }; + 3A5377C5148E81C3006DC4CE /* pugixml.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377A6148E81C3006DC4CE /* pugixml.hpp */; }; + 3A5377C6148E81C3006DC4CE /* pugixpath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377A7148E81C3006DC4CE /* pugixpath.cpp */; }; + 3A5377C7148E81C3006DC4CE /* PVSToAASMapping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377A8148E81C3006DC4CE /* PVSToAASMapping.cpp */; }; + 3A5377C8148E81C3006DC4CE /* PVSToAASMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377A9148E81C3006DC4CE /* PVSToAASMapping.h */; }; + 3A5377C9148E81C3006DC4CE /* _lrotl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377AB148E81C3006DC4CE /* _lrotl.h */; }; + 3A5377CB148E81C3006DC4CE /* mersenne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377AE148E81C3006DC4CE /* mersenne.cpp */; }; + 3A5377CC148E81C3006DC4CE /* mother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377AF148E81C3006DC4CE /* mother.cpp */; }; + 3A5377CD148E81C3006DC4CE /* rancombi.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377B0148E81C3006DC4CE /* rancombi.h */; }; + 3A5377CE148E81C3006DC4CE /* randomc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377B1148E81C3006DC4CE /* randomc.h */; }; + 3A5377CF148E81C3006DC4CE /* ranrotb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377B3148E81C3006DC4CE /* ranrotb.cpp */; }; + 3A5377D0148E81C3006DC4CE /* ranrotw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377B4148E81C3006DC4CE /* ranrotw.cpp */; }; + 3A5377D1148E81C3006DC4CE /* userintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377B5148E81C3006DC4CE /* userintf.cpp */; }; + 3A5377D2148E81C3006DC4CE /* RawVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377B6148E81C3006DC4CE /* RawVector.cpp */; }; + 3A5377D3148E81C3006DC4CE /* RawVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377B7148E81C3006DC4CE /* RawVector.h */; }; + 3A5377D4148E81C3006DC4CE /* Relations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377B8148E81C3006DC4CE /* Relations.cpp */; }; + 3A5377D5148E81C3006DC4CE /* Relations.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377B9148E81C3006DC4CE /* Relations.h */; }; + 3A5377D6148E81C3006DC4CE /* RevisionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377BA148E81C3006DC4CE /* RevisionTracker.cpp */; }; + 3A5377D7148E81C3006DC4CE /* RevisionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377BB148E81C3006DC4CE /* RevisionTracker.h */; }; + 3A537808148E81D7006DC4CE /* SEED.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377D8148E81D7006DC4CE /* SEED.cpp */; }; + 3A537809148E81D7006DC4CE /* SEED.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377D9148E81D7006DC4CE /* SEED.h */; }; + 3A53780A148E81D7006DC4CE /* LootRuleSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377DB148E81D7006DC4CE /* LootRuleSet.cpp */; }; + 3A53780B148E81D7006DC4CE /* LootRuleSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377DC148E81D7006DC4CE /* LootRuleSet.h */; }; + 3A53780C148E81D7006DC4CE /* Shop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377DD148E81D7006DC4CE /* Shop.cpp */; }; + 3A53780D148E81D7006DC4CE /* Shop.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377DE148E81D7006DC4CE /* Shop.h */; }; + 3A53780E148E81D7006DC4CE /* ShopItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377DF148E81D7006DC4CE /* ShopItem.cpp */; }; + 3A53780F148E81D7006DC4CE /* ShopItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E0148E81D7006DC4CE /* ShopItem.h */; }; + 3A537810148E81D7006DC4CE /* SndProp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377E1148E81D7006DC4CE /* SndProp.cpp */; }; + 3A537811148E81D7006DC4CE /* SndProp.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E2148E81D7006DC4CE /* SndProp.h */; }; + 3A537812148E81D7006DC4CE /* SndPropLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377E3148E81D7006DC4CE /* SndPropLoader.cpp */; }; + 3A537813148E81D7006DC4CE /* SndPropLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E4148E81D7006DC4CE /* SndPropLoader.h */; }; + 3A537814148E81D7006DC4CE /* FastDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E6148E81D7006DC4CE /* FastDelegate.h */; }; + 3A537815148E81D7006DC4CE /* sh_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E7148E81D7006DC4CE /* sh_list.h */; }; + 3A537816148E81D7006DC4CE /* sh_memfuncinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E8148E81D7006DC4CE /* sh_memfuncinfo.h */; }; + 3A537817148E81D7006DC4CE /* sh_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377E9148E81D7006DC4CE /* sh_memory.h */; }; + 3A537818148E81D7006DC4CE /* sh_stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377EA148E81D7006DC4CE /* sh_stack.h */; }; + 3A537819148E81D7006DC4CE /* sh_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377EB148E81D7006DC4CE /* sh_string.h */; }; + 3A53781A148E81D7006DC4CE /* sh_tinyhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377EC148E81D7006DC4CE /* sh_tinyhash.h */; }; + 3A53781B148E81D7006DC4CE /* sh_vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377ED148E81D7006DC4CE /* sh_vector.h */; }; + 3A53781C148E81D7006DC4CE /* sourcehook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377EE148E81D7006DC4CE /* sourcehook.cpp */; }; + 3A53781D148E81D7006DC4CE /* sourcehook.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377EF148E81D7006DC4CE /* sourcehook.h */; }; + 3A53781E148E81D7006DC4CE /* sourcehook_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377F0148E81D7006DC4CE /* sourcehook_impl.h */; }; + 3A53781F148E81D7006DC4CE /* StaticMulti.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377F1148E81D7006DC4CE /* StaticMulti.cpp */; }; + 3A537820148E81D7006DC4CE /* StaticMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377F2148E81D7006DC4CE /* StaticMulti.h */; }; + 3A537821148E81D7006DC4CE /* Response.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377F4148E81D7006DC4CE /* Response.cpp */; }; + 3A537822148E81D7006DC4CE /* Response.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377F5148E81D7006DC4CE /* Response.h */; }; + 3A537823148E81D7006DC4CE /* ResponseEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377F6148E81D7006DC4CE /* ResponseEffect.cpp */; }; + 3A537824148E81D7006DC4CE /* ResponseEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377F7148E81D7006DC4CE /* ResponseEffect.h */; }; + 3A537825148E81D7006DC4CE /* Stim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377F8148E81D7006DC4CE /* Stim.cpp */; }; + 3A537826148E81D7006DC4CE /* Stim.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377F9148E81D7006DC4CE /* Stim.h */; }; + 3A537827148E81D7006DC4CE /* StimResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377FA148E81D7006DC4CE /* StimResponse.cpp */; }; + 3A537828148E81D7006DC4CE /* StimResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377FB148E81D7006DC4CE /* StimResponse.h */; }; + 3A537829148E81D7006DC4CE /* StimResponseCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377FC148E81D7006DC4CE /* StimResponseCollection.cpp */; }; + 3A53782A148E81D7006DC4CE /* StimResponseCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377FD148E81D7006DC4CE /* StimResponseCollection.h */; }; + 3A53782B148E81D7006DC4CE /* StimResponseTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5377FE148E81D7006DC4CE /* StimResponseTimer.cpp */; }; + 3A53782C148E81D7006DC4CE /* StimResponseTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5377FF148E81D7006DC4CE /* StimResponseTimer.h */; }; + 3A53782D148E81D7006DC4CE /* StimType.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537800148E81D7006DC4CE /* StimType.h */; }; + 3A53782E148E81D7006DC4CE /* TimerManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537801148E81D7006DC4CE /* TimerManager.cpp */; }; + 3A53782F148E81D7006DC4CE /* TimerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537802148E81D7006DC4CE /* TimerManager.h */; }; + 3A537830148E81D7006DC4CE /* UserManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537803148E81D7006DC4CE /* UserManager.cpp */; }; + 3A537831148E81D7006DC4CE /* UserManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537804148E81D7006DC4CE /* UserManager.h */; }; + 3A537832148E81D7006DC4CE /* ZipLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537806148E81D7006DC4CE /* ZipLoader.cpp */; }; + 3A537833148E81D7006DC4CE /* ZipLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537807148E81D7006DC4CE /* ZipLoader.h */; }; + 3A5378DF148E81F1006DC4CE /* AreaManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537834148E81F1006DC4CE /* AreaManager.cpp */; }; + 3A5378E0148E81F1006DC4CE /* AreaManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537835148E81F1006DC4CE /* AreaManager.h */; }; + 3A5378E1148E81F1006DC4CE /* CommunicationSubsystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537836148E81F1006DC4CE /* CommunicationSubsystem.cpp */; }; + 3A5378E2148E81F1006DC4CE /* CommunicationSubsystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537837148E81F1006DC4CE /* CommunicationSubsystem.h */; }; + 3A5378E3148E81F1006DC4CE /* Conversation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537839148E81F1006DC4CE /* Conversation.cpp */; }; + 3A5378E4148E81F1006DC4CE /* Conversation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53783A148E81F1006DC4CE /* Conversation.h */; }; + 3A5378E5148E81F1006DC4CE /* ConversationCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53783B148E81F1006DC4CE /* ConversationCommand.cpp */; }; + 3A5378E6148E81F1006DC4CE /* ConversationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53783C148E81F1006DC4CE /* ConversationCommand.h */; }; + 3A5378E7148E81F1006DC4CE /* ConversationSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53783D148E81F1006DC4CE /* ConversationSystem.cpp */; }; + 3A5378E8148E81F1006DC4CE /* ConversationSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53783E148E81F1006DC4CE /* ConversationSystem.h */; }; + 3A5378E9148E81F1006DC4CE /* DoorInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53783F148E81F1006DC4CE /* DoorInfo.cpp */; }; + 3A5378EA148E81F1006DC4CE /* DoorInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537840148E81F1006DC4CE /* DoorInfo.h */; }; + 3A5378EB148E81F1006DC4CE /* ClusterInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537842148E81F1006DC4CE /* ClusterInfo.h */; }; + 3A5378EC148E81F1006DC4CE /* EAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537843148E81F1006DC4CE /* EAS.cpp */; }; + 3A5378ED148E81F1006DC4CE /* EAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537844148E81F1006DC4CE /* EAS.h */; }; + 3A5378EE148E81F1006DC4CE /* ElevatorStationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537845148E81F1006DC4CE /* ElevatorStationInfo.h */; }; + 3A5378EF148E81F1006DC4CE /* RouteInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537846148E81F1006DC4CE /* RouteInfo.cpp */; }; + 3A5378F0148E81F1006DC4CE /* RouteInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537847148E81F1006DC4CE /* RouteInfo.h */; }; + 3A5378F1148E81F1006DC4CE /* RouteNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537848148E81F1006DC4CE /* RouteNode.cpp */; }; + 3A5378F2148E81F1006DC4CE /* RouteNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537849148E81F1006DC4CE /* RouteNode.h */; }; + 3A5378F3148E81F1006DC4CE /* Library.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53784A148E81F1006DC4CE /* Library.h */; }; + 3A5378F4148E81F1006DC4CE /* Memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53784B148E81F1006DC4CE /* Memory.cpp */; }; + 3A5378F5148E81F1006DC4CE /* Memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53784C148E81F1006DC4CE /* Memory.h */; }; + 3A5378F6148E81F1006DC4CE /* Mind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53784D148E81F1006DC4CE /* Mind.cpp */; }; + 3A5378F7148E81F1006DC4CE /* Mind.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53784E148E81F1006DC4CE /* Mind.h */; }; + 3A5378F8148E81F1006DC4CE /* MovementSubsystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53784F148E81F1006DC4CE /* MovementSubsystem.cpp */; }; + 3A5378F9148E81F1006DC4CE /* MovementSubsystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537850148E81F1006DC4CE /* MovementSubsystem.h */; }; + 3A5378FA148E81F1006DC4CE /* MoveState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537851148E81F1006DC4CE /* MoveState.cpp */; }; + 3A5378FB148E81F1006DC4CE /* MoveState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537852148E81F1006DC4CE /* MoveState.h */; }; + 3A5378FC148E81F1006DC4CE /* Queue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537853148E81F1006DC4CE /* Queue.h */; }; + 3A5378FD148E81F1006DC4CE /* AgitatedSearchingState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537855148E81F1006DC4CE /* AgitatedSearchingState.cpp */; }; + 3A5378FE148E81F1006DC4CE /* AgitatedSearchingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537856148E81F1006DC4CE /* AgitatedSearchingState.h */; }; + 3A5378FF148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537857148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.cpp */; }; + 3A537900148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537858148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.h */; }; + 3A537901148E81F1006DC4CE /* AlertIdleState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537859148E81F1006DC4CE /* AlertIdleState.cpp */; }; + 3A537902148E81F1006DC4CE /* AlertIdleState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53785A148E81F1006DC4CE /* AlertIdleState.h */; }; + 3A537903148E81F1006DC4CE /* BlindedState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53785B148E81F1006DC4CE /* BlindedState.cpp */; }; + 3A537904148E81F1006DC4CE /* BlindedState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53785C148E81F1006DC4CE /* BlindedState.h */; }; + 3A537905148E81F1006DC4CE /* CombatState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53785D148E81F1006DC4CE /* CombatState.cpp */; }; + 3A537906148E81F1006DC4CE /* CombatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53785E148E81F1006DC4CE /* CombatState.h */; }; + 3A537907148E81F1006DC4CE /* ConversationState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53785F148E81F1006DC4CE /* ConversationState.cpp */; }; + 3A537908148E81F1006DC4CE /* ConversationState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537860148E81F1006DC4CE /* ConversationState.h */; }; + 3A537909148E81F1006DC4CE /* DeadState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537861148E81F1006DC4CE /* DeadState.cpp */; }; + 3A53790A148E81F1006DC4CE /* DeadState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537862148E81F1006DC4CE /* DeadState.h */; }; + 3A53790B148E81F1006DC4CE /* EmergeFromCoverState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537863148E81F1006DC4CE /* EmergeFromCoverState.cpp */; }; + 3A53790C148E81F1006DC4CE /* EmergeFromCoverState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537864148E81F1006DC4CE /* EmergeFromCoverState.h */; }; + 3A53790D148E81F1006DC4CE /* ExamineRopeState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537865148E81F1006DC4CE /* ExamineRopeState.cpp */; }; + 3A53790E148E81F1006DC4CE /* ExamineRopeState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537866148E81F1006DC4CE /* ExamineRopeState.h */; }; + 3A53790F148E81F1006DC4CE /* FailedKnockoutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537867148E81F1006DC4CE /* FailedKnockoutState.cpp */; }; + 3A537910148E81F1006DC4CE /* FailedKnockoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537868148E81F1006DC4CE /* FailedKnockoutState.h */; }; + 3A537911148E81F1006DC4CE /* FleeDoneState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537869148E81F1006DC4CE /* FleeDoneState.cpp */; }; + 3A537912148E81F1006DC4CE /* FleeDoneState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53786A148E81F1006DC4CE /* FleeDoneState.h */; }; + 3A537913148E81F1006DC4CE /* FleeState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53786B148E81F1006DC4CE /* FleeState.cpp */; }; + 3A537914148E81F1006DC4CE /* FleeState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53786C148E81F1006DC4CE /* FleeState.h */; }; + 3A537915148E81F1006DC4CE /* IdleSleepState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53786D148E81F1006DC4CE /* IdleSleepState.cpp */; }; + 3A537916148E81F1006DC4CE /* IdleSleepState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53786E148E81F1006DC4CE /* IdleSleepState.h */; }; + 3A537917148E81F1006DC4CE /* IdleState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53786F148E81F1006DC4CE /* IdleState.cpp */; }; + 3A537918148E81F1006DC4CE /* IdleState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537870148E81F1006DC4CE /* IdleState.h */; }; + 3A537919148E81F1006DC4CE /* KnockedOutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537871148E81F1006DC4CE /* KnockedOutState.cpp */; }; + 3A53791A148E81F1006DC4CE /* KnockedOutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537872148E81F1006DC4CE /* KnockedOutState.h */; }; + 3A53791B148E81F1006DC4CE /* LostTrackOfEnemyState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537873148E81F1006DC4CE /* LostTrackOfEnemyState.cpp */; }; + 3A53791C148E81F1006DC4CE /* LostTrackOfEnemyState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537874148E81F1006DC4CE /* LostTrackOfEnemyState.h */; }; + 3A53791D148E81F1006DC4CE /* ObservantState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537875148E81F1006DC4CE /* ObservantState.cpp */; }; + 3A53791E148E81F1006DC4CE /* ObservantState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537876148E81F1006DC4CE /* ObservantState.h */; }; + 3A53791F148E81F1006DC4CE /* PainState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537877148E81F1006DC4CE /* PainState.cpp */; }; + 3A537920148E81F1006DC4CE /* PainState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537878148E81F1006DC4CE /* PainState.h */; }; + 3A537921148E81F1006DC4CE /* SearchingState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537879148E81F1006DC4CE /* SearchingState.cpp */; }; + 3A537922148E81F1006DC4CE /* SearchingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53787A148E81F1006DC4CE /* SearchingState.h */; }; + 3A537923148E81F1006DC4CE /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53787B148E81F1006DC4CE /* State.cpp */; }; + 3A537924148E81F1006DC4CE /* State.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53787C148E81F1006DC4CE /* State.h */; }; + 3A537925148E81F1006DC4CE /* StayInCoverState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53787D148E81F1006DC4CE /* StayInCoverState.cpp */; }; + 3A537926148E81F1006DC4CE /* StayInCoverState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53787E148E81F1006DC4CE /* StayInCoverState.h */; }; + 3A537927148E81F1006DC4CE /* SuspiciousState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53787F148E81F1006DC4CE /* SuspiciousState.cpp */; }; + 3A537928148E81F1006DC4CE /* SuspiciousState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537880148E81F1006DC4CE /* SuspiciousState.h */; }; + 3A537929148E81F1006DC4CE /* SwitchOnLightState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537881148E81F1006DC4CE /* SwitchOnLightState.cpp */; }; + 3A53792A148E81F1006DC4CE /* SwitchOnLightState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537882148E81F1006DC4CE /* SwitchOnLightState.h */; }; + 3A53792B148E81F1006DC4CE /* TakeCoverState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537883148E81F1006DC4CE /* TakeCoverState.cpp */; }; + 3A53792C148E81F1006DC4CE /* TakeCoverState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537884148E81F1006DC4CE /* TakeCoverState.h */; }; + 3A53792D148E81F1006DC4CE /* UnreachableTargetState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537885148E81F1006DC4CE /* UnreachableTargetState.cpp */; }; + 3A53792E148E81F1006DC4CE /* UnreachableTargetState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537886148E81F1006DC4CE /* UnreachableTargetState.h */; }; + 3A53792F148E81F1006DC4CE /* Subsystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537887148E81F1006DC4CE /* Subsystem.cpp */; }; + 3A537930148E81F1006DC4CE /* Subsystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537888148E81F1006DC4CE /* Subsystem.h */; }; + 3A537931148E81F1006DC4CE /* AnimalPatrolTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53788A148E81F1006DC4CE /* AnimalPatrolTask.cpp */; }; + 3A537932148E81F1006DC4CE /* AnimalPatrolTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53788B148E81F1006DC4CE /* AnimalPatrolTask.h */; }; + 3A537933148E81F1006DC4CE /* ChaseEnemyRangedTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53788C148E81F1006DC4CE /* ChaseEnemyRangedTask.cpp */; }; + 3A537934148E81F1006DC4CE /* ChaseEnemyRangedTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53788D148E81F1006DC4CE /* ChaseEnemyRangedTask.h */; }; + 3A537935148E81F1006DC4CE /* ChaseEnemyTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53788E148E81F1006DC4CE /* ChaseEnemyTask.cpp */; }; + 3A537936148E81F1006DC4CE /* ChaseEnemyTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53788F148E81F1006DC4CE /* ChaseEnemyTask.h */; }; + 3A537937148E81F1006DC4CE /* CombatTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537890148E81F1006DC4CE /* CombatTask.cpp */; }; + 3A537938148E81F1006DC4CE /* CombatTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537891148E81F1006DC4CE /* CombatTask.h */; }; + 3A537939148E81F1006DC4CE /* CommunicationTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537892148E81F1006DC4CE /* CommunicationTask.cpp */; }; + 3A53793A148E81F1006DC4CE /* CommunicationTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537893148E81F1006DC4CE /* CommunicationTask.h */; }; + 3A53793B148E81F1006DC4CE /* CommWaitTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537894148E81F1006DC4CE /* CommWaitTask.cpp */; }; + 3A53793C148E81F1006DC4CE /* CommWaitTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537895148E81F1006DC4CE /* CommWaitTask.h */; }; + 3A53793D148E81F1006DC4CE /* FleeTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537896148E81F1006DC4CE /* FleeTask.cpp */; }; + 3A53793E148E81F1006DC4CE /* FleeTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537897148E81F1006DC4CE /* FleeTask.h */; }; + 3A53793F148E81F1006DC4CE /* FollowActorTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537898148E81F1006DC4CE /* FollowActorTask.cpp */; }; + 3A537940148E81F1006DC4CE /* FollowActorTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537899148E81F1006DC4CE /* FollowActorTask.h */; }; + 3A537941148E81F1006DC4CE /* GreetingBarkTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53789A148E81F1006DC4CE /* GreetingBarkTask.cpp */; }; + 3A537942148E81F1006DC4CE /* GreetingBarkTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53789B148E81F1006DC4CE /* GreetingBarkTask.h */; }; + 3A537943148E81F1006DC4CE /* HandleDoorTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53789C148E81F1006DC4CE /* HandleDoorTask.cpp */; }; + 3A537944148E81F1006DC4CE /* HandleDoorTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53789D148E81F1006DC4CE /* HandleDoorTask.h */; }; + 3A537945148E81F1006DC4CE /* HandleElevatorTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A53789E148E81F1006DC4CE /* HandleElevatorTask.cpp */; }; + 3A537946148E81F1006DC4CE /* HandleElevatorTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A53789F148E81F1006DC4CE /* HandleElevatorTask.h */; }; + 3A537947148E81F1006DC4CE /* IdleAnimationTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378A0148E81F1006DC4CE /* IdleAnimationTask.cpp */; }; + 3A537948148E81F1006DC4CE /* IdleAnimationTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378A1148E81F1006DC4CE /* IdleAnimationTask.h */; }; + 3A537949148E81F1006DC4CE /* InteractionTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378A2148E81F1006DC4CE /* InteractionTask.cpp */; }; + 3A53794A148E81F1006DC4CE /* InteractionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378A3148E81F1006DC4CE /* InteractionTask.h */; }; + 3A53794B148E81F1006DC4CE /* InvestigateSpotTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378A4148E81F1006DC4CE /* InvestigateSpotTask.cpp */; }; + 3A53794C148E81F1006DC4CE /* InvestigateSpotTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378A5148E81F1006DC4CE /* InvestigateSpotTask.h */; }; + 3A53794D148E81F1006DC4CE /* MeleeCombatTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378A6148E81F1006DC4CE /* MeleeCombatTask.cpp */; }; + 3A53794E148E81F1006DC4CE /* MeleeCombatTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378A7148E81F1006DC4CE /* MeleeCombatTask.h */; }; + 3A53794F148E81F1006DC4CE /* MoveToCoverTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378A8148E81F1006DC4CE /* MoveToCoverTask.cpp */; }; + 3A537950148E81F1006DC4CE /* MoveToCoverTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378A9148E81F1006DC4CE /* MoveToCoverTask.h */; }; + 3A537951148E81F1006DC4CE /* MoveToPositionTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378AA148E81F1006DC4CE /* MoveToPositionTask.cpp */; }; + 3A537952148E81F1006DC4CE /* MoveToPositionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378AB148E81F1006DC4CE /* MoveToPositionTask.h */; }; + 3A537953148E81F1006DC4CE /* PathAnimTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378AC148E81F1006DC4CE /* PathAnimTask.cpp */; }; + 3A537954148E81F1006DC4CE /* PathAnimTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378AD148E81F1006DC4CE /* PathAnimTask.h */; }; + 3A537955148E81F1006DC4CE /* PathCornerTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378AE148E81F1006DC4CE /* PathCornerTask.cpp */; }; + 3A537956148E81F1006DC4CE /* PathCornerTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378AF148E81F1006DC4CE /* PathCornerTask.h */; }; + 3A537957148E81F1006DC4CE /* PathCycleAnimTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378B0148E81F1006DC4CE /* PathCycleAnimTask.cpp */; }; + 3A537958148E81F1006DC4CE /* PathCycleAnimTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378B1148E81F1006DC4CE /* PathCycleAnimTask.h */; }; + 3A537959148E81F1006DC4CE /* PathHideTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378B2148E81F1006DC4CE /* PathHideTask.cpp */; }; + 3A53795A148E81F1006DC4CE /* PathHideTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378B3148E81F1006DC4CE /* PathHideTask.h */; }; + 3A53795B148E81F1006DC4CE /* PathInteractTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378B4148E81F1006DC4CE /* PathInteractTask.cpp */; }; + 3A53795C148E81F1006DC4CE /* PathInteractTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378B5148E81F1006DC4CE /* PathInteractTask.h */; }; + 3A53795D148E81F1006DC4CE /* PathLookatTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378B6148E81F1006DC4CE /* PathLookatTask.cpp */; }; + 3A53795E148E81F1006DC4CE /* PathLookatTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378B7148E81F1006DC4CE /* PathLookatTask.h */; }; + 3A53795F148E81F1006DC4CE /* PathShowTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378B8148E81F1006DC4CE /* PathShowTask.cpp */; }; + 3A537960148E81F1006DC4CE /* PathShowTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378B9148E81F1006DC4CE /* PathShowTask.h */; }; + 3A537961148E81F1006DC4CE /* PathSitTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378BA148E81F1006DC4CE /* PathSitTask.cpp */; }; + 3A537962148E81F1006DC4CE /* PathSitTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378BB148E81F1006DC4CE /* PathSitTask.h */; }; + 3A537963148E81F1006DC4CE /* PathSleepTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378BC148E81F1006DC4CE /* PathSleepTask.cpp */; }; + 3A537964148E81F1006DC4CE /* PathSleepTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378BD148E81F1006DC4CE /* PathSleepTask.h */; }; + 3A537965148E81F1006DC4CE /* PathTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378BE148E81F1006DC4CE /* PathTask.cpp */; }; + 3A537966148E81F1006DC4CE /* PathTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378BF148E81F1006DC4CE /* PathTask.h */; }; + 3A537967148E81F1006DC4CE /* PathTurnTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378C0148E81F1006DC4CE /* PathTurnTask.cpp */; }; + 3A537968148E81F1006DC4CE /* PathTurnTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378C1148E81F1006DC4CE /* PathTurnTask.h */; }; + 3A537969148E81F1006DC4CE /* PathWaitForTriggerTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378C2148E81F1006DC4CE /* PathWaitForTriggerTask.cpp */; }; + 3A53796A148E81F1006DC4CE /* PathWaitForTriggerTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378C3148E81F1006DC4CE /* PathWaitForTriggerTask.h */; }; + 3A53796B148E81F1006DC4CE /* PathWaitTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378C4148E81F1006DC4CE /* PathWaitTask.cpp */; }; + 3A53796C148E81F1006DC4CE /* PathWaitTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378C5148E81F1006DC4CE /* PathWaitTask.h */; }; + 3A53796D148E81F1006DC4CE /* PlayAnimationTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378C6148E81F1006DC4CE /* PlayAnimationTask.cpp */; }; + 3A53796E148E81F1006DC4CE /* PlayAnimationTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378C7148E81F1006DC4CE /* PlayAnimationTask.h */; }; + 3A53796F148E81F1006DC4CE /* RandomHeadturnTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378C8148E81F1006DC4CE /* RandomHeadturnTask.cpp */; }; + 3A537970148E81F1006DC4CE /* RandomHeadturnTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378C9148E81F1006DC4CE /* RandomHeadturnTask.h */; }; + 3A537971148E81F1006DC4CE /* RandomTurningTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378CA148E81F1006DC4CE /* RandomTurningTask.cpp */; }; + 3A537972148E81F1006DC4CE /* RandomTurningTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378CB148E81F1006DC4CE /* RandomTurningTask.h */; }; + 3A537973148E81F1006DC4CE /* RangedCombatTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378CC148E81F1006DC4CE /* RangedCombatTask.cpp */; }; + 3A537974148E81F1006DC4CE /* RangedCombatTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378CD148E81F1006DC4CE /* RangedCombatTask.h */; }; + 3A537975148E81F1006DC4CE /* RepeatedBarkTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378CE148E81F1006DC4CE /* RepeatedBarkTask.cpp */; }; + 3A537976148E81F1006DC4CE /* RepeatedBarkTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378CF148E81F1006DC4CE /* RepeatedBarkTask.h */; }; + 3A537977148E81F1006DC4CE /* ResolveMovementBlockTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378D0148E81F1006DC4CE /* ResolveMovementBlockTask.cpp */; }; + 3A537978148E81F1006DC4CE /* ResolveMovementBlockTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378D1148E81F1006DC4CE /* ResolveMovementBlockTask.h */; }; + 3A537979148E81F1006DC4CE /* ScriptTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378D2148E81F1006DC4CE /* ScriptTask.cpp */; }; + 3A53797A148E81F1006DC4CE /* ScriptTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378D3148E81F1006DC4CE /* ScriptTask.h */; }; + 3A53797B148E81F1006DC4CE /* SingleBarkTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378D4148E81F1006DC4CE /* SingleBarkTask.cpp */; }; + 3A53797C148E81F1006DC4CE /* SingleBarkTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378D5148E81F1006DC4CE /* SingleBarkTask.h */; }; + 3A53797D148E81F1006DC4CE /* Task.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378D6148E81F1006DC4CE /* Task.h */; }; + 3A53797E148E81F1006DC4CE /* ThrowObjectTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378D7148E81F1006DC4CE /* ThrowObjectTask.cpp */; }; + 3A53797F148E81F1006DC4CE /* ThrowObjectTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378D8148E81F1006DC4CE /* ThrowObjectTask.h */; }; + 3A537980148E81F1006DC4CE /* WaitTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378D9148E81F1006DC4CE /* WaitTask.cpp */; }; + 3A537981148E81F1006DC4CE /* WaitTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378DA148E81F1006DC4CE /* WaitTask.h */; }; + 3A537982148E81F1006DC4CE /* WanderInLocationTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378DB148E81F1006DC4CE /* WanderInLocationTask.cpp */; }; + 3A537983148E81F1006DC4CE /* WanderInLocationTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378DC148E81F1006DC4CE /* WanderInLocationTask.h */; }; + 3A537984148E81F1006DC4CE /* tdmAASFindEscape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A5378DD148E81F1006DC4CE /* tdmAASFindEscape.cpp */; }; + 3A537985148E81F1006DC4CE /* tdmAASFindEscape.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A5378DE148E81F1006DC4CE /* tdmAASFindEscape.h */; }; + 3A537988148E8200006DC4CE /* Force_Push.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537986148E8200006DC4CE /* Force_Push.cpp */; }; + 3A537989148E8200006DC4CE /* Force_Push.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537987148E8200006DC4CE /* Force_Push.h */; }; + 3A537A58148E9F62006DC4CE /* Physics_Liquid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A537A56148E9F62006DC4CE /* Physics_Liquid.cpp */; }; + 3A537A59148E9F62006DC4CE /* Physics_Liquid.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A537A57148E9F62006DC4CE /* Physics_Liquid.h */; }; + 81225A3A0912C3DB005D34B9 /* libidlib_pic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 81225A210912C3A4005D34B9 /* libidlib_pic.a */; }; + 81225AC40912C42F005D34B9 /* PlayerIcon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */; }; + 81225AC50912C42F005D34B9 /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3C0912C42F005D34B9 /* Actor.cpp */; }; + 81225AC60912C42F005D34B9 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A3D0912C42F005D34B9 /* Actor.h */; }; + 81225AC70912C42F005D34B9 /* AF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A3E0912C42F005D34B9 /* AF.cpp */; }; + 81225AC80912C42F005D34B9 /* AF.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A3F0912C42F005D34B9 /* AF.h */; }; + 81225AC90912C42F005D34B9 /* AFEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A400912C42F005D34B9 /* AFEntity.cpp */; }; + 81225ACA0912C42F005D34B9 /* AFEntity.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A410912C42F005D34B9 /* AFEntity.h */; }; + 81225ACB0912C42F005D34B9 /* AAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A430912C42F005D34B9 /* AAS.cpp */; }; + 81225ACC0912C42F005D34B9 /* AAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A440912C42F005D34B9 /* AAS.h */; }; + 81225ACD0912C42F005D34B9 /* AAS_debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A450912C42F005D34B9 /* AAS_debug.cpp */; }; + 81225ACE0912C42F005D34B9 /* AAS_local.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A460912C42F005D34B9 /* AAS_local.h */; }; + 81225ACF0912C42F005D34B9 /* AAS_pathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A470912C42F005D34B9 /* AAS_pathing.cpp */; }; + 81225AD00912C42F005D34B9 /* AAS_routing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A480912C42F005D34B9 /* AAS_routing.cpp */; }; + 81225AD10912C42F005D34B9 /* AI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A490912C42F005D34B9 /* AI.cpp */; }; + 81225AD20912C42F005D34B9 /* AI.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A4A0912C42F005D34B9 /* AI.h */; }; + 81225AD30912C42F005D34B9 /* AI_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4B0912C42F005D34B9 /* AI_events.cpp */; }; + 81225AD40912C42F005D34B9 /* AI_pathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */; }; + 81225AD60912C42F005D34B9 /* Anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A4F0912C42F005D34B9 /* Anim.cpp */; }; + 81225AD70912C42F005D34B9 /* Anim.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A500912C42F005D34B9 /* Anim.h */; }; + 81225AD80912C42F005D34B9 /* Anim_Blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A510912C42F005D34B9 /* Anim_Blend.cpp */; }; + 81225AD90912C42F005D34B9 /* Anim_Import.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A520912C42F005D34B9 /* Anim_Import.cpp */; }; + 81225ADA0912C42F005D34B9 /* Anim_Testmodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */; }; + 81225ADB0912C42F005D34B9 /* Anim_Testmodel.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A540912C42F005D34B9 /* Anim_Testmodel.h */; }; + 81225ADC0912C42F005D34B9 /* BrittleFracture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A550912C42F005D34B9 /* BrittleFracture.cpp */; }; + 81225ADD0912C42F005D34B9 /* BrittleFracture.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A560912C42F005D34B9 /* BrittleFracture.h */; }; + 81225ADE0912C42F005D34B9 /* Camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A570912C42F005D34B9 /* Camera.cpp */; }; + 81225ADF0912C42F005D34B9 /* Camera.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A580912C42F005D34B9 /* Camera.h */; }; + 81225AE00912C42F005D34B9 /* Entity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A590912C42F005D34B9 /* Entity.cpp */; }; + 81225AE10912C42F005D34B9 /* Entity.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A5A0912C42F005D34B9 /* Entity.h */; }; + 81225AE40912C42F005D34B9 /* Game.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A5E0912C42F005D34B9 /* Game.h */; }; + 81225AE50912C42F005D34B9 /* Game_local.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A5F0912C42F005D34B9 /* Game_local.cpp */; }; + 81225AE60912C42F005D34B9 /* Game_local.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A600912C42F005D34B9 /* Game_local.h */; }; + 81225AE70912C42F005D34B9 /* Game_network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A610912C42F005D34B9 /* Game_network.cpp */; }; + 81225AE80912C42F005D34B9 /* GameEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A620912C42F005D34B9 /* GameEdit.cpp */; }; + 81225AE90912C42F005D34B9 /* GameEdit.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A630912C42F005D34B9 /* GameEdit.h */; }; + 81225AEA0912C42F005D34B9 /* Class.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A650912C42F005D34B9 /* Class.cpp */; }; + 81225AEB0912C42F005D34B9 /* Class.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A660912C42F005D34B9 /* Class.h */; }; + 81225AEC0912C42F005D34B9 /* DebugGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A670912C42F005D34B9 /* DebugGraph.cpp */; }; + 81225AED0912C42F005D34B9 /* DebugGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A680912C42F005D34B9 /* DebugGraph.h */; }; + 81225AEE0912C42F005D34B9 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A690912C42F005D34B9 /* Event.cpp */; }; + 81225AEF0912C42F005D34B9 /* Event.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6A0912C42F005D34B9 /* Event.h */; }; + 81225AF00912C42F005D34B9 /* NoGameTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */; }; + 81225AF10912C42F005D34B9 /* SaveGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A6C0912C42F005D34B9 /* SaveGame.cpp */; }; + 81225AF20912C42F005D34B9 /* SaveGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6D0912C42F005D34B9 /* SaveGame.h */; }; + 81225AF30912C42F005D34B9 /* SysCmds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A6E0912C42F005D34B9 /* SysCmds.cpp */; }; + 81225AF40912C42F005D34B9 /* SysCmds.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A6F0912C42F005D34B9 /* SysCmds.h */; }; + 81225AF50912C42F005D34B9 /* SysCvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A700912C42F005D34B9 /* SysCvar.cpp */; }; + 81225AF60912C42F005D34B9 /* SysCvar.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A710912C42F005D34B9 /* SysCvar.h */; }; + 81225AF70912C42F005D34B9 /* TypeInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A720912C42F005D34B9 /* TypeInfo.cpp */; }; + 81225AF80912C42F005D34B9 /* TypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A730912C42F005D34B9 /* TypeInfo.h */; }; + 81225AF90912C42F005D34B9 /* IK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A740912C42F005D34B9 /* IK.cpp */; }; + 81225AFA0912C42F005D34B9 /* IK.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A750912C42F005D34B9 /* IK.h */; }; + 81225AFB0912C42F005D34B9 /* Item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A760912C42F005D34B9 /* Item.cpp */; }; + 81225AFC0912C42F005D34B9 /* Item.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A770912C42F005D34B9 /* Item.h */; }; + 81225AFD0912C42F005D34B9 /* Light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A780912C42F005D34B9 /* Light.cpp */; }; + 81225AFE0912C42F005D34B9 /* Light.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A790912C42F005D34B9 /* Light.h */; }; + 81225AFF0912C42F005D34B9 /* Misc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7A0912C42F005D34B9 /* Misc.cpp */; }; + 81225B000912C42F005D34B9 /* Misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7B0912C42F005D34B9 /* Misc.h */; }; + 81225B010912C42F005D34B9 /* Moveable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7C0912C42F005D34B9 /* Moveable.cpp */; }; + 81225B020912C42F005D34B9 /* Moveable.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7D0912C42F005D34B9 /* Moveable.h */; }; + 81225B030912C42F005D34B9 /* Mover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A7E0912C42F005D34B9 /* Mover.cpp */; }; + 81225B040912C42F005D34B9 /* Mover.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A7F0912C42F005D34B9 /* Mover.h */; }; + 81225B050912C42F005D34B9 /* MultiplayerGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */; }; + 81225B060912C42F005D34B9 /* MultiplayerGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A810912C42F005D34B9 /* MultiplayerGame.h */; }; + 81225B070912C42F005D34B9 /* Clip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A830912C42F005D34B9 /* Clip.cpp */; }; + 81225B080912C42F005D34B9 /* Clip.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A840912C42F005D34B9 /* Clip.h */; }; + 81225B090912C42F005D34B9 /* Force.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A850912C42F005D34B9 /* Force.cpp */; }; + 81225B0A0912C42F005D34B9 /* Force.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A860912C42F005D34B9 /* Force.h */; }; + 81225B0B0912C42F005D34B9 /* Force_Constant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A870912C42F005D34B9 /* Force_Constant.cpp */; }; + 81225B0C0912C42F005D34B9 /* Force_Constant.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A880912C42F005D34B9 /* Force_Constant.h */; }; + 81225B0D0912C42F005D34B9 /* Force_Drag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A890912C42F005D34B9 /* Force_Drag.cpp */; }; + 81225B0E0912C42F005D34B9 /* Force_Drag.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8A0912C42F005D34B9 /* Force_Drag.h */; }; + 81225B0F0912C42F005D34B9 /* Force_Field.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8B0912C42F005D34B9 /* Force_Field.cpp */; }; + 81225B100912C42F005D34B9 /* Force_Field.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8C0912C42F005D34B9 /* Force_Field.h */; }; + 81225B110912C42F005D34B9 /* Force_Spring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */; }; + 81225B120912C42F005D34B9 /* Force_Spring.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A8E0912C42F005D34B9 /* Force_Spring.h */; }; + 81225B130912C42F005D34B9 /* Physics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A8F0912C42F005D34B9 /* Physics.cpp */; }; + 81225B140912C42F005D34B9 /* Physics.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A900912C42F005D34B9 /* Physics.h */; }; + 81225B150912C42F005D34B9 /* Physics_Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A910912C42F005D34B9 /* Physics_Actor.cpp */; }; + 81225B160912C42F005D34B9 /* Physics_Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A920912C42F005D34B9 /* Physics_Actor.h */; }; + 81225B170912C42F005D34B9 /* Physics_AF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A930912C42F005D34B9 /* Physics_AF.cpp */; }; + 81225B180912C42F005D34B9 /* Physics_AF.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A940912C42F005D34B9 /* Physics_AF.h */; }; + 81225B190912C42F005D34B9 /* Physics_Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A950912C42F005D34B9 /* Physics_Base.cpp */; }; + 81225B1A0912C42F005D34B9 /* Physics_Base.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A960912C42F005D34B9 /* Physics_Base.h */; }; + 81225B1B0912C42F005D34B9 /* Physics_Monster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A970912C42F005D34B9 /* Physics_Monster.cpp */; }; + 81225B1C0912C42F005D34B9 /* Physics_Monster.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A980912C42F005D34B9 /* Physics_Monster.h */; }; + 81225B1D0912C42F005D34B9 /* Physics_Parametric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */; }; + 81225B1E0912C42F005D34B9 /* Physics_Parametric.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */; }; + 81225B1F0912C42F005D34B9 /* Physics_Player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */; }; + 81225B200912C42F005D34B9 /* Physics_Player.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9C0912C42F005D34B9 /* Physics_Player.h */; }; + 81225B210912C42F005D34B9 /* Physics_RigidBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */; }; + 81225B220912C42F005D34B9 /* Physics_RigidBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */; }; + 81225B230912C42F005D34B9 /* Physics_Static.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */; }; + 81225B240912C42F005D34B9 /* Physics_Static.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA00912C42F005D34B9 /* Physics_Static.h */; }; + 81225B250912C42F005D34B9 /* Physics_StaticMulti.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */; }; + 81225B260912C42F005D34B9 /* Physics_StaticMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */; }; + 81225B270912C42F005D34B9 /* Push.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA30912C42F005D34B9 /* Push.cpp */; }; + 81225B280912C42F005D34B9 /* Push.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA40912C42F005D34B9 /* Push.h */; }; + 81225B290912C42F005D34B9 /* Player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA50912C42F005D34B9 /* Player.cpp */; }; + 81225B2A0912C42F005D34B9 /* Player.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA60912C42F005D34B9 /* Player.h */; }; + 81225B2B0912C42F005D34B9 /* PlayerView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA70912C42F005D34B9 /* PlayerView.cpp */; }; + 81225B2C0912C42F005D34B9 /* PlayerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AA80912C42F005D34B9 /* PlayerView.h */; }; + 81225B2D0912C42F005D34B9 /* Projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AA90912C42F005D34B9 /* Projectile.cpp */; }; + 81225B2E0912C42F005D34B9 /* Projectile.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAA0912C42F005D34B9 /* Projectile.h */; }; + 81225B2F0912C42F005D34B9 /* Pvs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AAB0912C42F005D34B9 /* Pvs.cpp */; }; + 81225B300912C42F005D34B9 /* Pvs.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAC0912C42F005D34B9 /* Pvs.h */; }; + 81225B310912C42F005D34B9 /* Script_Compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */; }; + 81225B320912C42F005D34B9 /* Script_Compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AAF0912C42F005D34B9 /* Script_Compiler.h */; }; + 81225B330912C42F005D34B9 /* Script_Interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */; }; + 81225B340912C42F005D34B9 /* Script_Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB10912C42F005D34B9 /* Script_Interpreter.h */; }; + 81225B350912C42F005D34B9 /* Script_Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB20912C42F005D34B9 /* Script_Program.cpp */; }; + 81225B360912C42F005D34B9 /* Script_Program.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB30912C42F005D34B9 /* Script_Program.h */; }; + 81225B370912C42F005D34B9 /* Script_Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB40912C42F005D34B9 /* Script_Thread.cpp */; }; + 81225B380912C42F005D34B9 /* Script_Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB50912C42F005D34B9 /* Script_Thread.h */; }; + 81225B390912C42F005D34B9 /* SecurityCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */; }; + 81225B3A0912C42F005D34B9 /* SecurityCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB70912C42F005D34B9 /* SecurityCamera.h */; }; + 81225B3B0912C42F005D34B9 /* SmokeParticles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */; }; + 81225B3C0912C42F005D34B9 /* SmokeParticles.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AB90912C42F005D34B9 /* SmokeParticles.h */; }; + 81225B3D0912C42F005D34B9 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABA0912C42F005D34B9 /* Sound.cpp */; }; + 81225B3E0912C42F005D34B9 /* Sound.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABB0912C42F005D34B9 /* Sound.h */; }; + 81225B3F0912C42F005D34B9 /* Target.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABC0912C42F005D34B9 /* Target.cpp */; }; + 81225B400912C42F005D34B9 /* Target.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABD0912C42F005D34B9 /* Target.h */; }; + 81225B410912C42F005D34B9 /* Trigger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225ABE0912C42F005D34B9 /* Trigger.cpp */; }; + 81225B420912C42F005D34B9 /* Trigger.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225ABF0912C42F005D34B9 /* Trigger.h */; }; + 81225B430912C42F005D34B9 /* Weapon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AC00912C42F005D34B9 /* Weapon.cpp */; }; + 81225B440912C42F005D34B9 /* Weapon.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AC10912C42F005D34B9 /* Weapon.h */; }; + 81225B450912C42F005D34B9 /* WorldSpawn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */; }; + 81225B460912C42F005D34B9 /* WorldSpawn.h in Headers */ = {isa = PBXBuildFile; fileRef = 81225AC30912C42F005D34B9 /* WorldSpawn.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3A176A17149359330077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176A10149359330077AB23 /* ziploader.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A1769AD1493584D0077AB23 /* libziploader.a */; + remoteInfo = ziploader; + }; + 3A176BEA149363140077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176BE6149363140077AB23 /* jpeg.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A176B561493626B0077AB23 /* libjpeg.a */; + remoteInfo = jpeg; + }; + 3A176CD7149366330077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176CD0149366330077AB23 /* png.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A176C98149365AD0077AB23 /* libpng.a */; + remoteInfo = png; + }; + 3A176D1A1493675B0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D161493675B0077AB23 /* devil.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A17681B149350DE0077AB23 /* libdevil.a */; + remoteInfo = devil; + }; + 3A176D5714936F5A0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176CD0149366330077AB23 /* png.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A176C97149365AD0077AB23 /* png */; + remoteInfo = png; + }; + 3A176D5914936F5D0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176A10149359330077AB23 /* ziploader.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A1769AC1493584D0077AB23 /* ziploader */; + remoteInfo = ziploader; + }; + 3A176D5B14936F5F0077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176BE6149363140077AB23 /* jpeg.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A176B551493626B0077AB23 /* jpeg */; + remoteInfo = jpeg; + }; + 3A176D5D14936F610077AB23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3A176D161493675B0077AB23 /* devil.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3A17681A149350DE0077AB23 /* devil */; + remoteInfo = devil; + }; + 81225A200912C3A4005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = idlib_pic; + }; + 81225A220912C3A4005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 81C858490912AD370095BC33; + remoteInfo = idlib_nopic; + }; + 81225A380912C3C8005D34B9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC045055464E500DB518D; + remoteInfo = idlib_pic; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3A176A10149359330077AB23 /* ziploader.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ziploader.xcodeproj; sourceTree = ""; }; + 3A176A6A149359C70077AB23 /* libziploader.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libziploader.a; path = "/Users/Shared/darkmod_src/sys/osx/build/ziploader.build/Release/ziploader.build/Objects-normal/i386/libziploader.a"; sourceTree = ""; }; + 3A176BE6149363140077AB23 /* jpeg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = jpeg.xcodeproj; sourceTree = ""; }; + 3A176BEE149363220077AB23 /* libjpeg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjpeg.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libjpeg.a; sourceTree = ""; }; + 3A176BF01493632A0077AB23 /* libdevil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdevil.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libdevil.a; sourceTree = ""; }; + 3A176BF2149363310077AB23 /* libziploader.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libziploader.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libziploader.a; sourceTree = ""; }; + 3A176CD0149366330077AB23 /* png.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = png.xcodeproj; sourceTree = ""; }; + 3A176D081493668A0077AB23 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = /Users/Shared/darkmod_src/sys/osx/build/Release/libpng.a; sourceTree = ""; }; + 3A176D161493675B0077AB23 /* devil.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = devil.xcodeproj; sourceTree = ""; }; + 3A537685148E80FA006DC4CE /* BoolParseNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoolParseNode.h; path = ../../game/Objectives/BoolParseNode.h; sourceTree = SOURCE_ROOT; }; + 3A537686148E80FA006DC4CE /* CampaignStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CampaignStatistics.cpp; path = ../../game/Objectives/CampaignStatistics.cpp; sourceTree = SOURCE_ROOT; }; + 3A537687148E80FA006DC4CE /* CampaignStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CampaignStatistics.h; path = ../../game/Objectives/CampaignStatistics.h; sourceTree = SOURCE_ROOT; }; + 3A537688148E80FA006DC4CE /* EMissionResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EMissionResult.h; path = ../../game/Objectives/EMissionResult.h; sourceTree = SOURCE_ROOT; }; + 3A537689148E80FA006DC4CE /* MissionData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MissionData.cpp; path = ../../game/Objectives/MissionData.cpp; sourceTree = SOURCE_ROOT; }; + 3A53768A148E80FA006DC4CE /* MissionData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MissionData.h; path = ../../game/Objectives/MissionData.h; sourceTree = SOURCE_ROOT; }; + 3A53768B148E80FA006DC4CE /* MissionStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MissionStatistics.cpp; path = ../../game/Objectives/MissionStatistics.cpp; sourceTree = SOURCE_ROOT; }; + 3A53768C148E80FA006DC4CE /* MissionStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MissionStatistics.h; path = ../../game/Objectives/MissionStatistics.h; sourceTree = SOURCE_ROOT; }; + 3A53768D148E80FA006DC4CE /* Objective.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Objective.cpp; path = ../../game/Objectives/Objective.cpp; sourceTree = SOURCE_ROOT; }; + 3A53768E148E80FA006DC4CE /* Objective.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Objective.h; path = ../../game/Objectives/Objective.h; sourceTree = SOURCE_ROOT; }; + 3A53768F148E80FA006DC4CE /* ObjectiveComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectiveComponent.cpp; path = ../../game/Objectives/ObjectiveComponent.cpp; sourceTree = SOURCE_ROOT; }; + 3A537690148E80FA006DC4CE /* ObjectiveComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectiveComponent.h; path = ../../game/Objectives/ObjectiveComponent.h; sourceTree = SOURCE_ROOT; }; + 3A537691148E80FA006DC4CE /* ObjectiveCondition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectiveCondition.cpp; path = ../../game/Objectives/ObjectiveCondition.cpp; sourceTree = SOURCE_ROOT; }; + 3A537692148E80FA006DC4CE /* ObjectiveCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectiveCondition.h; path = ../../game/Objectives/ObjectiveCondition.h; sourceTree = SOURCE_ROOT; }; + 3A537693148E80FA006DC4CE /* ObjectiveLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectiveLocation.cpp; path = ../../game/Objectives/ObjectiveLocation.cpp; sourceTree = SOURCE_ROOT; }; + 3A537694148E80FA006DC4CE /* ObjectiveLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectiveLocation.h; path = ../../game/Objectives/ObjectiveLocation.h; sourceTree = SOURCE_ROOT; }; + 3A5376A7148E8114006DC4CE /* AbsenceMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AbsenceMarker.cpp; path = ../../game/AbsenceMarker.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376A8148E8114006DC4CE /* AbsenceMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AbsenceMarker.h; path = ../../game/AbsenceMarker.h; sourceTree = SOURCE_ROOT; }; + 3A5376AB148E8121006DC4CE /* AIComm_Message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIComm_Message.cpp; path = ../../game/AIComm_Message.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376AC148E8121006DC4CE /* AIComm_Message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIComm_Message.h; path = ../../game/AIComm_Message.h; sourceTree = SOURCE_ROOT; }; + 3A5376AD148E8121006DC4CE /* AIVehicle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIVehicle.cpp; path = ../../game/AIVehicle.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376AE148E8121006DC4CE /* AIVehicle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIVehicle.h; path = ../../game/AIVehicle.h; sourceTree = SOURCE_ROOT; }; + 3A5376B3148E813B006DC4CE /* BinaryFrobMover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryFrobMover.cpp; path = ../../game/BinaryFrobMover.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376B4148E813B006DC4CE /* BinaryFrobMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BinaryFrobMover.h; path = ../../game/BinaryFrobMover.h; sourceTree = SOURCE_ROOT; }; + 3A5376B5148E813B006DC4CE /* BloodMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BloodMarker.cpp; path = ../../game/BloodMarker.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376B6148E813B006DC4CE /* BloodMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BloodMarker.h; path = ../../game/BloodMarker.h; sourceTree = SOURCE_ROOT; }; + 3A5376B7148E813B006DC4CE /* ButtonStateTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ButtonStateTracker.cpp; path = ../../game/ButtonStateTracker.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376B8148E813B006DC4CE /* ButtonStateTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ButtonStateTracker.h; path = ../../game/ButtonStateTracker.h; sourceTree = SOURCE_ROOT; }; + 3A5376B9148E813B006DC4CE /* CImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CImage.cpp; path = ../../game/CImage.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376BA148E813B006DC4CE /* CImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CImage.h; path = ../../game/CImage.h; sourceTree = SOURCE_ROOT; }; + 3A5376BB148E813B006DC4CE /* DarkmodAASHidingSpotFinder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DarkmodAASHidingSpotFinder.cpp; path = ../../game/DarkmodAASHidingSpotFinder.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376BC148E813B006DC4CE /* DarkmodAASHidingSpotFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DarkmodAASHidingSpotFinder.h; path = ../../game/DarkmodAASHidingSpotFinder.h; sourceTree = SOURCE_ROOT; }; + 3A5376BD148E813B006DC4CE /* DarkModGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DarkModGlobals.cpp; path = ../../game/DarkModGlobals.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376BE148E813B006DC4CE /* DarkModGlobals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DarkModGlobals.h; path = ../../game/DarkModGlobals.h; sourceTree = SOURCE_ROOT; }; + 3A5376BF148E813B006DC4CE /* darkmodHidingSpotTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = darkmodHidingSpotTree.cpp; path = ../../game/darkmodHidingSpotTree.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376C0148E813B006DC4CE /* darkmodHidingSpotTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = darkmodHidingSpotTree.h; path = ../../game/darkmodHidingSpotTree.h; sourceTree = SOURCE_ROOT; }; + 3A5376C1148E813B006DC4CE /* darkModLAS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = darkModLAS.cpp; path = ../../game/darkModLAS.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376C2148E813B006DC4CE /* darkModLAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = darkModLAS.h; path = ../../game/darkModLAS.h; sourceTree = SOURCE_ROOT; }; + 3A5376C3148E813B006DC4CE /* decltdm_matinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = decltdm_matinfo.cpp; path = ../../game/decltdm_matinfo.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376C4148E813B006DC4CE /* decltdm_matinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = decltdm_matinfo.h; path = ../../game/decltdm_matinfo.h; sourceTree = SOURCE_ROOT; }; + 3A5376C5148E813B006DC4CE /* declxdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = declxdata.cpp; path = ../../game/declxdata.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376C6148E813B006DC4CE /* declxdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = declxdata.h; path = ../../game/declxdata.h; sourceTree = SOURCE_ROOT; }; + 3A5376C7148E813B006DC4CE /* DifficultyManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DifficultyManager.cpp; path = ../../game/DifficultyManager.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376C8148E813B006DC4CE /* DifficultyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DifficultyManager.h; path = ../../game/DifficultyManager.h; sourceTree = SOURCE_ROOT; }; + 3A5376C9148E813B006DC4CE /* DifficultySettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DifficultySettings.cpp; path = ../../game/DifficultySettings.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376CA148E813B006DC4CE /* DifficultySettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DifficultySettings.h; path = ../../game/DifficultySettings.h; sourceTree = SOURCE_ROOT; }; + 3A5376CB148E813B006DC4CE /* DownloadMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DownloadMenu.cpp; path = ../../game/DownloadMenu.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376CC148E813B006DC4CE /* DownloadMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DownloadMenu.h; path = ../../game/DownloadMenu.h; sourceTree = SOURCE_ROOT; }; + 3A5376CD148E813B006DC4CE /* Emitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Emitter.cpp; path = ../../game/Emitter.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376CE148E813B006DC4CE /* Emitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Emitter.h; path = ../../game/Emitter.h; sourceTree = SOURCE_ROOT; }; + 3A5376CF148E813B006DC4CE /* EscapePointEvaluator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EscapePointEvaluator.cpp; path = ../../game/EscapePointEvaluator.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376D0148E813B006DC4CE /* EscapePointEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EscapePointEvaluator.h; path = ../../game/EscapePointEvaluator.h; sourceTree = SOURCE_ROOT; }; + 3A5376D1148E813B006DC4CE /* EscapePointManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EscapePointManager.cpp; path = ../../game/EscapePointManager.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376D2148E813B006DC4CE /* EscapePointManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EscapePointManager.h; path = ../../game/EscapePointManager.h; sourceTree = SOURCE_ROOT; }; + 3A5376D3148E813B006DC4CE /* Force_Grab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Force_Grab.cpp; path = ../../game/Force_Grab.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376D4148E813B006DC4CE /* Force_Grab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Force_Grab.h; path = ../../game/Force_Grab.h; sourceTree = SOURCE_ROOT; }; + 3A5376D5148E813B006DC4CE /* FrobButton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobButton.cpp; path = ../../game/FrobButton.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376D6148E813B006DC4CE /* FrobButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobButton.h; path = ../../game/FrobButton.h; sourceTree = SOURCE_ROOT; }; + 3A5376D7148E813B006DC4CE /* FrobDoor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobDoor.cpp; path = ../../game/FrobDoor.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376D8148E813B006DC4CE /* FrobDoor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobDoor.h; path = ../../game/FrobDoor.h; sourceTree = SOURCE_ROOT; }; + 3A5376D9148E813B006DC4CE /* FrobDoorHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobDoorHandle.cpp; path = ../../game/FrobDoorHandle.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376DA148E813B006DC4CE /* FrobDoorHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobDoorHandle.h; path = ../../game/FrobDoorHandle.h; sourceTree = SOURCE_ROOT; }; + 3A5376DB148E813B006DC4CE /* FrobHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobHandle.cpp; path = ../../game/FrobHandle.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376DC148E813B006DC4CE /* FrobHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobHandle.h; path = ../../game/FrobHandle.h; sourceTree = SOURCE_ROOT; }; + 3A5376DD148E813B006DC4CE /* FrobLever.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobLever.cpp; path = ../../game/FrobLever.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376DE148E813B006DC4CE /* FrobLever.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobLever.h; path = ../../game/FrobLever.h; sourceTree = SOURCE_ROOT; }; + 3A5376DF148E813B006DC4CE /* FrobLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobLock.cpp; path = ../../game/FrobLock.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376E0148E813B006DC4CE /* FrobLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobLock.h; path = ../../game/FrobLock.h; sourceTree = SOURCE_ROOT; }; + 3A5376E1148E813B006DC4CE /* FrobLockHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrobLockHandle.cpp; path = ../../game/FrobLockHandle.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376E2148E813B006DC4CE /* FrobLockHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrobLockHandle.h; path = ../../game/FrobLockHandle.h; sourceTree = SOURCE_ROOT; }; + 3A5376E3148E813B006DC4CE /* Func_Shooter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Func_Shooter.cpp; path = ../../game/Func_Shooter.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376E4148E813B006DC4CE /* Func_Shooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Func_Shooter.h; path = ../../game/Func_Shooter.h; sourceTree = SOURCE_ROOT; }; + 3A5376E5148E813B006DC4CE /* FX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FX.cpp; path = ../../game/FX.cpp; sourceTree = SOURCE_ROOT; }; + 3A5376E6148E813B006DC4CE /* FX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FX.h; path = ../../game/FX.h; sourceTree = SOURCE_ROOT; }; + 3A53771B148E816A006DC4CE /* GamePlayTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GamePlayTimer.h; path = ../../game/GamePlayTimer.h; sourceTree = SOURCE_ROOT; }; + 3A53771D148E817F006DC4CE /* Grabber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Grabber.cpp; path = ../../game/Grabber.cpp; sourceTree = SOURCE_ROOT; }; + 3A53771E148E817F006DC4CE /* Grabber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Grabber.h; path = ../../game/Grabber.h; sourceTree = SOURCE_ROOT; }; + 3A53771F148E817F006DC4CE /* HidingSpotSearchCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HidingSpotSearchCollection.cpp; path = ../../game/HidingSpotSearchCollection.cpp; sourceTree = SOURCE_ROOT; }; + 3A537720148E817F006DC4CE /* HidingSpotSearchCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HidingSpotSearchCollection.h; path = ../../game/HidingSpotSearchCollection.h; sourceTree = SOURCE_ROOT; }; + 3A537722148E817F006DC4CE /* HttpConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpConnection.cpp; sourceTree = ""; }; + 3A537723148E817F006DC4CE /* HttpConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpConnection.h; sourceTree = ""; }; + 3A537724148E817F006DC4CE /* HttpRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpRequest.cpp; sourceTree = ""; }; + 3A537725148E817F006DC4CE /* HttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpRequest.h; sourceTree = ""; }; + 3A537726148E817F006DC4CE /* I18N.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = I18N.cpp; path = ../../game/I18N.cpp; sourceTree = SOURCE_ROOT; }; + 3A537727148E817F006DC4CE /* I18N.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = I18N.h; path = ../../game/I18N.h; sourceTree = SOURCE_ROOT; }; + 3A537732148E8193006DC4CE /* ImageMapManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ImageMapManager.cpp; path = ../../game/ImageMapManager.cpp; sourceTree = SOURCE_ROOT; }; + 3A537733148E8193006DC4CE /* ImageMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ImageMapManager.h; path = ../../game/ImageMapManager.h; sourceTree = SOURCE_ROOT; }; + 3A537734148E8193006DC4CE /* IniFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IniFile.cpp; path = ../../game/IniFile.cpp; sourceTree = SOURCE_ROOT; }; + 3A537735148E8193006DC4CE /* IniFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IniFile.h; path = ../../game/IniFile.h; sourceTree = SOURCE_ROOT; }; + 3A537736148E8193006DC4CE /* Intersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Intersection.cpp; path = ../../game/Intersection.cpp; sourceTree = SOURCE_ROOT; }; + 3A537737148E8193006DC4CE /* Intersection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Intersection.h; path = ../../game/Intersection.h; sourceTree = SOURCE_ROOT; }; + 3A537739148E8193006DC4CE /* Category.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Category.cpp; sourceTree = ""; }; + 3A53773A148E8193006DC4CE /* Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Category.h; sourceTree = ""; }; + 3A53773B148E8193006DC4CE /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = ""; }; + 3A53773C148E8193006DC4CE /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = ""; }; + 3A53773D148E8193006DC4CE /* Inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inventory.cpp; sourceTree = ""; }; + 3A53773E148E8193006DC4CE /* Inventory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Inventory.h; sourceTree = ""; }; + 3A53773F148E8193006DC4CE /* InventoryItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InventoryItem.cpp; sourceTree = ""; }; + 3A537740148E8193006DC4CE /* InventoryItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InventoryItem.h; sourceTree = ""; }; + 3A537741148E8193006DC4CE /* LootType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LootType.h; sourceTree = ""; }; + 3A537742148E8193006DC4CE /* WeaponItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeaponItem.cpp; sourceTree = ""; }; + 3A537743148E8193006DC4CE /* WeaponItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeaponItem.h; sourceTree = ""; }; + 3A537744148E8193006DC4CE /* LightController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LightController.cpp; path = ../../game/LightController.cpp; sourceTree = SOURCE_ROOT; }; + 3A537745148E8193006DC4CE /* LightController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LightController.h; path = ../../game/LightController.h; sourceTree = SOURCE_ROOT; }; + 3A537746148E8193006DC4CE /* LightGem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LightGem.cpp; path = ../../game/LightGem.cpp; sourceTree = SOURCE_ROOT; }; + 3A537747148E8193006DC4CE /* LightGem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LightGem.h; path = ../../game/LightGem.h; sourceTree = SOURCE_ROOT; }; + 3A537748148E8193006DC4CE /* Liquid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Liquid.cpp; path = ../../game/Liquid.cpp; sourceTree = SOURCE_ROOT; }; + 3A537749148E8193006DC4CE /* Liquid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Liquid.h; path = ../../game/Liquid.h; sourceTree = SOURCE_ROOT; }; + 3A53774A148E8193006DC4CE /* MaterialConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MaterialConverter.cpp; path = ../../game/MaterialConverter.cpp; sourceTree = SOURCE_ROOT; }; + 3A53774B148E8193006DC4CE /* MaterialConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MaterialConverter.h; path = ../../game/MaterialConverter.h; sourceTree = SOURCE_ROOT; }; + 3A53774C148E8193006DC4CE /* MatrixSq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MatrixSq.h; path = ../../game/MatrixSq.h; sourceTree = SOURCE_ROOT; }; + 3A53774D148E8193006DC4CE /* MeleeWeapon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeleeWeapon.cpp; path = ../../game/MeleeWeapon.cpp; sourceTree = SOURCE_ROOT; }; + 3A53774E148E8193006DC4CE /* MeleeWeapon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeleeWeapon.h; path = ../../game/MeleeWeapon.h; sourceTree = SOURCE_ROOT; }; + 3A537750148E8193006DC4CE /* Download.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Download.cpp; sourceTree = ""; }; + 3A537751148E8193006DC4CE /* Download.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Download.h; sourceTree = ""; }; + 3A537752148E8193006DC4CE /* DownloadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DownloadManager.cpp; sourceTree = ""; }; + 3A537753148E8193006DC4CE /* DownloadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadManager.h; sourceTree = ""; }; + 3A537754148E8193006DC4CE /* MissionDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MissionDB.cpp; sourceTree = ""; }; + 3A537755148E8193006DC4CE /* MissionDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MissionDB.h; sourceTree = ""; }; + 3A537756148E8193006DC4CE /* MissionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MissionManager.cpp; sourceTree = ""; }; + 3A537757148E8193006DC4CE /* MissionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MissionManager.h; sourceTree = ""; }; + 3A537758148E8193006DC4CE /* ModInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModInfo.cpp; sourceTree = ""; }; + 3A537759148E8193006DC4CE /* ModInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModInfo.h; sourceTree = ""; }; + 3A53775A148E8193006DC4CE /* ModInfoDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModInfoDecl.cpp; sourceTree = ""; }; + 3A53775B148E8193006DC4CE /* ModInfoDecl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModInfoDecl.h; sourceTree = ""; }; + 3A53775C148E8193006DC4CE /* ModelGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModelGenerator.cpp; path = ../../game/ModelGenerator.cpp; sourceTree = SOURCE_ROOT; }; + 3A53775D148E8193006DC4CE /* ModelGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModelGenerator.h; path = ../../game/ModelGenerator.h; sourceTree = SOURCE_ROOT; }; + 3A53775E148E8193006DC4CE /* ModMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModMenu.cpp; path = ../../game/ModMenu.cpp; sourceTree = SOURCE_ROOT; }; + 3A53775F148E8193006DC4CE /* ModMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModMenu.h; path = ../../game/ModMenu.h; sourceTree = SOURCE_ROOT; }; + 3A537760148E8193006DC4CE /* MultiStateMover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MultiStateMover.cpp; path = ../../game/MultiStateMover.cpp; sourceTree = SOURCE_ROOT; }; + 3A537761148E8193006DC4CE /* MultiStateMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultiStateMover.h; path = ../../game/MultiStateMover.h; sourceTree = SOURCE_ROOT; }; + 3A537762148E8193006DC4CE /* MultiStateMoverButton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MultiStateMoverButton.cpp; path = ../../game/MultiStateMoverButton.cpp; sourceTree = SOURCE_ROOT; }; + 3A537763148E8193006DC4CE /* MultiStateMoverButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultiStateMoverButton.h; path = ../../game/MultiStateMoverButton.h; sourceTree = SOURCE_ROOT; }; + 3A537764148E8193006DC4CE /* MultiStateMoverPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MultiStateMoverPosition.cpp; path = ../../game/MultiStateMoverPosition.cpp; sourceTree = SOURCE_ROOT; }; + 3A537765148E8193006DC4CE /* MultiStateMoverPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultiStateMoverPosition.h; path = ../../game/MultiStateMoverPosition.h; sourceTree = SOURCE_ROOT; }; + 3A537798148E81A1006DC4CE /* OverlaySys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OverlaySys.cpp; path = ../../game/OverlaySys.cpp; sourceTree = SOURCE_ROOT; }; + 3A537799148E81A1006DC4CE /* OverlaySys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OverlaySys.h; path = ../../game/OverlaySys.h; sourceTree = SOURCE_ROOT; }; + 3A53779C148E81C3006DC4CE /* PickableLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PickableLock.cpp; path = ../../game/PickableLock.cpp; sourceTree = SOURCE_ROOT; }; + 3A53779D148E81C3006DC4CE /* PickableLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PickableLock.h; path = ../../game/PickableLock.h; sourceTree = SOURCE_ROOT; }; + 3A53779E148E81C3006DC4CE /* PlayerIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlayerIcon.h; path = ../../game/PlayerIcon.h; sourceTree = SOURCE_ROOT; }; + 3A53779F148E81C3006DC4CE /* PositionWithinRangeFinder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PositionWithinRangeFinder.cpp; path = ../../game/PositionWithinRangeFinder.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377A0148E81C3006DC4CE /* PositionWithinRangeFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PositionWithinRangeFinder.h; path = ../../game/PositionWithinRangeFinder.h; sourceTree = SOURCE_ROOT; }; + 3A5377A1148E81C3006DC4CE /* ProjectileResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProjectileResult.cpp; path = ../../game/ProjectileResult.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377A2148E81C3006DC4CE /* ProjectileResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProjectileResult.h; path = ../../game/ProjectileResult.h; sourceTree = SOURCE_ROOT; }; + 3A5377A4148E81C3006DC4CE /* pugiconfig.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = pugiconfig.hpp; sourceTree = ""; }; + 3A5377A5148E81C3006DC4CE /* pugixml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pugixml.cpp; sourceTree = ""; }; + 3A5377A6148E81C3006DC4CE /* pugixml.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = pugixml.hpp; sourceTree = ""; }; + 3A5377A7148E81C3006DC4CE /* pugixpath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pugixpath.cpp; sourceTree = ""; }; + 3A5377A8148E81C3006DC4CE /* PVSToAASMapping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PVSToAASMapping.cpp; path = ../../game/PVSToAASMapping.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377A9148E81C3006DC4CE /* PVSToAASMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PVSToAASMapping.h; path = ../../game/PVSToAASMapping.h; sourceTree = SOURCE_ROOT; }; + 3A5377AB148E81C3006DC4CE /* _lrotl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _lrotl.h; sourceTree = ""; }; + 3A5377AD148E81C3006DC4CE /* licence.htm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = licence.htm; sourceTree = ""; }; + 3A5377AE148E81C3006DC4CE /* mersenne.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mersenne.cpp; sourceTree = ""; }; + 3A5377AF148E81C3006DC4CE /* mother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mother.cpp; sourceTree = ""; }; + 3A5377B0148E81C3006DC4CE /* rancombi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rancombi.h; sourceTree = ""; }; + 3A5377B1148E81C3006DC4CE /* randomc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = randomc.h; sourceTree = ""; }; + 3A5377B2148E81C3006DC4CE /* randomc.htm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = randomc.htm; sourceTree = ""; }; + 3A5377B3148E81C3006DC4CE /* ranrotb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ranrotb.cpp; sourceTree = ""; }; + 3A5377B4148E81C3006DC4CE /* ranrotw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ranrotw.cpp; sourceTree = ""; }; + 3A5377B5148E81C3006DC4CE /* userintf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = userintf.cpp; sourceTree = ""; }; + 3A5377B6148E81C3006DC4CE /* RawVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RawVector.cpp; path = ../../game/RawVector.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377B7148E81C3006DC4CE /* RawVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RawVector.h; path = ../../game/RawVector.h; sourceTree = SOURCE_ROOT; }; + 3A5377B8148E81C3006DC4CE /* Relations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Relations.cpp; path = ../../game/Relations.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377B9148E81C3006DC4CE /* Relations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Relations.h; path = ../../game/Relations.h; sourceTree = SOURCE_ROOT; }; + 3A5377BA148E81C3006DC4CE /* RevisionTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RevisionTracker.cpp; path = ../../game/RevisionTracker.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377BB148E81C3006DC4CE /* RevisionTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RevisionTracker.h; path = ../../game/RevisionTracker.h; sourceTree = SOURCE_ROOT; }; + 3A5377D8148E81D7006DC4CE /* SEED.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SEED.cpp; path = ../../game/SEED.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377D9148E81D7006DC4CE /* SEED.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SEED.h; path = ../../game/SEED.h; sourceTree = SOURCE_ROOT; }; + 3A5377DB148E81D7006DC4CE /* LootRuleSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LootRuleSet.cpp; sourceTree = ""; }; + 3A5377DC148E81D7006DC4CE /* LootRuleSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LootRuleSet.h; sourceTree = ""; }; + 3A5377DD148E81D7006DC4CE /* Shop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shop.cpp; sourceTree = ""; }; + 3A5377DE148E81D7006DC4CE /* Shop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shop.h; sourceTree = ""; }; + 3A5377DF148E81D7006DC4CE /* ShopItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShopItem.cpp; sourceTree = ""; }; + 3A5377E0148E81D7006DC4CE /* ShopItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShopItem.h; sourceTree = ""; }; + 3A5377E1148E81D7006DC4CE /* SndProp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SndProp.cpp; path = ../../game/SndProp.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377E2148E81D7006DC4CE /* SndProp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SndProp.h; path = ../../game/SndProp.h; sourceTree = SOURCE_ROOT; }; + 3A5377E3148E81D7006DC4CE /* SndPropLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SndPropLoader.cpp; path = ../../game/SndPropLoader.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377E4148E81D7006DC4CE /* SndPropLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SndPropLoader.h; path = ../../game/SndPropLoader.h; sourceTree = SOURCE_ROOT; }; + 3A5377E6148E81D7006DC4CE /* FastDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastDelegate.h; sourceTree = ""; }; + 3A5377E7148E81D7006DC4CE /* sh_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_list.h; sourceTree = ""; }; + 3A5377E8148E81D7006DC4CE /* sh_memfuncinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_memfuncinfo.h; sourceTree = ""; }; + 3A5377E9148E81D7006DC4CE /* sh_memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_memory.h; sourceTree = ""; }; + 3A5377EA148E81D7006DC4CE /* sh_stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_stack.h; sourceTree = ""; }; + 3A5377EB148E81D7006DC4CE /* sh_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_string.h; sourceTree = ""; }; + 3A5377EC148E81D7006DC4CE /* sh_tinyhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_tinyhash.h; sourceTree = ""; }; + 3A5377ED148E81D7006DC4CE /* sh_vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sh_vector.h; sourceTree = ""; }; + 3A5377EE148E81D7006DC4CE /* sourcehook.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sourcehook.cpp; sourceTree = ""; }; + 3A5377EF148E81D7006DC4CE /* sourcehook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sourcehook.h; sourceTree = ""; }; + 3A5377F0148E81D7006DC4CE /* sourcehook_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sourcehook_impl.h; sourceTree = ""; }; + 3A5377F1148E81D7006DC4CE /* StaticMulti.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StaticMulti.cpp; path = ../../game/StaticMulti.cpp; sourceTree = SOURCE_ROOT; }; + 3A5377F2148E81D7006DC4CE /* StaticMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StaticMulti.h; path = ../../game/StaticMulti.h; sourceTree = SOURCE_ROOT; }; + 3A5377F4148E81D7006DC4CE /* Response.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Response.cpp; sourceTree = ""; }; + 3A5377F5148E81D7006DC4CE /* Response.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Response.h; sourceTree = ""; }; + 3A5377F6148E81D7006DC4CE /* ResponseEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResponseEffect.cpp; sourceTree = ""; }; + 3A5377F7148E81D7006DC4CE /* ResponseEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResponseEffect.h; sourceTree = ""; }; + 3A5377F8148E81D7006DC4CE /* Stim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stim.cpp; sourceTree = ""; }; + 3A5377F9148E81D7006DC4CE /* Stim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stim.h; sourceTree = ""; }; + 3A5377FA148E81D7006DC4CE /* StimResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StimResponse.cpp; sourceTree = ""; }; + 3A5377FB148E81D7006DC4CE /* StimResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StimResponse.h; sourceTree = ""; }; + 3A5377FC148E81D7006DC4CE /* StimResponseCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StimResponseCollection.cpp; sourceTree = ""; }; + 3A5377FD148E81D7006DC4CE /* StimResponseCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StimResponseCollection.h; sourceTree = ""; }; + 3A5377FE148E81D7006DC4CE /* StimResponseTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StimResponseTimer.cpp; sourceTree = ""; }; + 3A5377FF148E81D7006DC4CE /* StimResponseTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StimResponseTimer.h; sourceTree = ""; }; + 3A537800148E81D7006DC4CE /* StimType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StimType.h; sourceTree = ""; }; + 3A537801148E81D7006DC4CE /* TimerManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TimerManager.cpp; path = ../../game/TimerManager.cpp; sourceTree = SOURCE_ROOT; }; + 3A537802148E81D7006DC4CE /* TimerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimerManager.h; path = ../../game/TimerManager.h; sourceTree = SOURCE_ROOT; }; + 3A537803148E81D7006DC4CE /* UserManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserManager.cpp; path = ../../game/UserManager.cpp; sourceTree = SOURCE_ROOT; }; + 3A537804148E81D7006DC4CE /* UserManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserManager.h; path = ../../game/UserManager.h; sourceTree = SOURCE_ROOT; }; + 3A537806148E81D7006DC4CE /* ZipLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipLoader.cpp; sourceTree = ""; }; + 3A537807148E81D7006DC4CE /* ZipLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipLoader.h; sourceTree = ""; }; + 3A537834148E81F1006DC4CE /* AreaManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AreaManager.cpp; sourceTree = ""; }; + 3A537835148E81F1006DC4CE /* AreaManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AreaManager.h; sourceTree = ""; }; + 3A537836148E81F1006DC4CE /* CommunicationSubsystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommunicationSubsystem.cpp; sourceTree = ""; }; + 3A537837148E81F1006DC4CE /* CommunicationSubsystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommunicationSubsystem.h; sourceTree = ""; }; + 3A537839148E81F1006DC4CE /* Conversation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Conversation.cpp; sourceTree = ""; }; + 3A53783A148E81F1006DC4CE /* Conversation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Conversation.h; sourceTree = ""; }; + 3A53783B148E81F1006DC4CE /* ConversationCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConversationCommand.cpp; sourceTree = ""; }; + 3A53783C148E81F1006DC4CE /* ConversationCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationCommand.h; sourceTree = ""; }; + 3A53783D148E81F1006DC4CE /* ConversationSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConversationSystem.cpp; sourceTree = ""; }; + 3A53783E148E81F1006DC4CE /* ConversationSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationSystem.h; sourceTree = ""; }; + 3A53783F148E81F1006DC4CE /* DoorInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DoorInfo.cpp; sourceTree = ""; }; + 3A537840148E81F1006DC4CE /* DoorInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DoorInfo.h; sourceTree = ""; }; + 3A537842148E81F1006DC4CE /* ClusterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClusterInfo.h; sourceTree = ""; }; + 3A537843148E81F1006DC4CE /* EAS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EAS.cpp; sourceTree = ""; }; + 3A537844148E81F1006DC4CE /* EAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAS.h; sourceTree = ""; }; + 3A537845148E81F1006DC4CE /* ElevatorStationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElevatorStationInfo.h; sourceTree = ""; }; + 3A537846148E81F1006DC4CE /* RouteInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RouteInfo.cpp; sourceTree = ""; }; + 3A537847148E81F1006DC4CE /* RouteInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RouteInfo.h; sourceTree = ""; }; + 3A537848148E81F1006DC4CE /* RouteNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RouteNode.cpp; sourceTree = ""; }; + 3A537849148E81F1006DC4CE /* RouteNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RouteNode.h; sourceTree = ""; }; + 3A53784A148E81F1006DC4CE /* Library.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Library.h; sourceTree = ""; }; + 3A53784B148E81F1006DC4CE /* Memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Memory.cpp; sourceTree = ""; }; + 3A53784C148E81F1006DC4CE /* Memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Memory.h; sourceTree = ""; }; + 3A53784D148E81F1006DC4CE /* Mind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mind.cpp; sourceTree = ""; }; + 3A53784E148E81F1006DC4CE /* Mind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mind.h; sourceTree = ""; }; + 3A53784F148E81F1006DC4CE /* MovementSubsystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MovementSubsystem.cpp; sourceTree = ""; }; + 3A537850148E81F1006DC4CE /* MovementSubsystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MovementSubsystem.h; sourceTree = ""; }; + 3A537851148E81F1006DC4CE /* MoveState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoveState.cpp; sourceTree = ""; }; + 3A537852148E81F1006DC4CE /* MoveState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveState.h; sourceTree = ""; }; + 3A537853148E81F1006DC4CE /* Queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Queue.h; sourceTree = ""; }; + 3A537855148E81F1006DC4CE /* AgitatedSearchingState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AgitatedSearchingState.cpp; sourceTree = ""; }; + 3A537856148E81F1006DC4CE /* AgitatedSearchingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AgitatedSearchingState.h; sourceTree = ""; }; + 3A537857148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AgitatedSearchingStateLanternBot.cpp; sourceTree = ""; }; + 3A537858148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AgitatedSearchingStateLanternBot.h; sourceTree = ""; }; + 3A537859148E81F1006DC4CE /* AlertIdleState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlertIdleState.cpp; sourceTree = ""; }; + 3A53785A148E81F1006DC4CE /* AlertIdleState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlertIdleState.h; sourceTree = ""; }; + 3A53785B148E81F1006DC4CE /* BlindedState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlindedState.cpp; sourceTree = ""; }; + 3A53785C148E81F1006DC4CE /* BlindedState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlindedState.h; sourceTree = ""; }; + 3A53785D148E81F1006DC4CE /* CombatState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CombatState.cpp; sourceTree = ""; }; + 3A53785E148E81F1006DC4CE /* CombatState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CombatState.h; sourceTree = ""; }; + 3A53785F148E81F1006DC4CE /* ConversationState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConversationState.cpp; sourceTree = ""; }; + 3A537860148E81F1006DC4CE /* ConversationState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationState.h; sourceTree = ""; }; + 3A537861148E81F1006DC4CE /* DeadState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeadState.cpp; sourceTree = ""; }; + 3A537862148E81F1006DC4CE /* DeadState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeadState.h; sourceTree = ""; }; + 3A537863148E81F1006DC4CE /* EmergeFromCoverState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmergeFromCoverState.cpp; sourceTree = ""; }; + 3A537864148E81F1006DC4CE /* EmergeFromCoverState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmergeFromCoverState.h; sourceTree = ""; }; + 3A537865148E81F1006DC4CE /* ExamineRopeState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExamineRopeState.cpp; sourceTree = ""; }; + 3A537866148E81F1006DC4CE /* ExamineRopeState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExamineRopeState.h; sourceTree = ""; }; + 3A537867148E81F1006DC4CE /* FailedKnockoutState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FailedKnockoutState.cpp; sourceTree = ""; }; + 3A537868148E81F1006DC4CE /* FailedKnockoutState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FailedKnockoutState.h; sourceTree = ""; }; + 3A537869148E81F1006DC4CE /* FleeDoneState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FleeDoneState.cpp; sourceTree = ""; }; + 3A53786A148E81F1006DC4CE /* FleeDoneState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FleeDoneState.h; sourceTree = ""; }; + 3A53786B148E81F1006DC4CE /* FleeState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FleeState.cpp; sourceTree = ""; }; + 3A53786C148E81F1006DC4CE /* FleeState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FleeState.h; sourceTree = ""; }; + 3A53786D148E81F1006DC4CE /* IdleSleepState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdleSleepState.cpp; sourceTree = ""; }; + 3A53786E148E81F1006DC4CE /* IdleSleepState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdleSleepState.h; sourceTree = ""; }; + 3A53786F148E81F1006DC4CE /* IdleState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdleState.cpp; sourceTree = ""; }; + 3A537870148E81F1006DC4CE /* IdleState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdleState.h; sourceTree = ""; }; + 3A537871148E81F1006DC4CE /* KnockedOutState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KnockedOutState.cpp; sourceTree = ""; }; + 3A537872148E81F1006DC4CE /* KnockedOutState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KnockedOutState.h; sourceTree = ""; }; + 3A537873148E81F1006DC4CE /* LostTrackOfEnemyState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LostTrackOfEnemyState.cpp; sourceTree = ""; }; + 3A537874148E81F1006DC4CE /* LostTrackOfEnemyState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LostTrackOfEnemyState.h; sourceTree = ""; }; + 3A537875148E81F1006DC4CE /* ObservantState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObservantState.cpp; sourceTree = ""; }; + 3A537876148E81F1006DC4CE /* ObservantState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObservantState.h; sourceTree = ""; }; + 3A537877148E81F1006DC4CE /* PainState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PainState.cpp; sourceTree = ""; }; + 3A537878148E81F1006DC4CE /* PainState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PainState.h; sourceTree = ""; }; + 3A537879148E81F1006DC4CE /* SearchingState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SearchingState.cpp; sourceTree = ""; }; + 3A53787A148E81F1006DC4CE /* SearchingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchingState.h; sourceTree = ""; }; + 3A53787B148E81F1006DC4CE /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = State.cpp; sourceTree = ""; }; + 3A53787C148E81F1006DC4CE /* State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = State.h; sourceTree = ""; }; + 3A53787D148E81F1006DC4CE /* StayInCoverState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StayInCoverState.cpp; sourceTree = ""; }; + 3A53787E148E81F1006DC4CE /* StayInCoverState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StayInCoverState.h; sourceTree = ""; }; + 3A53787F148E81F1006DC4CE /* SuspiciousState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuspiciousState.cpp; sourceTree = ""; }; + 3A537880148E81F1006DC4CE /* SuspiciousState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuspiciousState.h; sourceTree = ""; }; + 3A537881148E81F1006DC4CE /* SwitchOnLightState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SwitchOnLightState.cpp; sourceTree = ""; }; + 3A537882148E81F1006DC4CE /* SwitchOnLightState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwitchOnLightState.h; sourceTree = ""; }; + 3A537883148E81F1006DC4CE /* TakeCoverState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TakeCoverState.cpp; sourceTree = ""; }; + 3A537884148E81F1006DC4CE /* TakeCoverState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TakeCoverState.h; sourceTree = ""; }; + 3A537885148E81F1006DC4CE /* UnreachableTargetState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnreachableTargetState.cpp; sourceTree = ""; }; + 3A537886148E81F1006DC4CE /* UnreachableTargetState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnreachableTargetState.h; sourceTree = ""; }; + 3A537887148E81F1006DC4CE /* Subsystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Subsystem.cpp; sourceTree = ""; }; + 3A537888148E81F1006DC4CE /* Subsystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Subsystem.h; sourceTree = ""; }; + 3A53788A148E81F1006DC4CE /* AnimalPatrolTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimalPatrolTask.cpp; sourceTree = ""; }; + 3A53788B148E81F1006DC4CE /* AnimalPatrolTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimalPatrolTask.h; sourceTree = ""; }; + 3A53788C148E81F1006DC4CE /* ChaseEnemyRangedTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChaseEnemyRangedTask.cpp; sourceTree = ""; }; + 3A53788D148E81F1006DC4CE /* ChaseEnemyRangedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChaseEnemyRangedTask.h; sourceTree = ""; }; + 3A53788E148E81F1006DC4CE /* ChaseEnemyTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChaseEnemyTask.cpp; sourceTree = ""; }; + 3A53788F148E81F1006DC4CE /* ChaseEnemyTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChaseEnemyTask.h; sourceTree = ""; }; + 3A537890148E81F1006DC4CE /* CombatTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CombatTask.cpp; sourceTree = ""; }; + 3A537891148E81F1006DC4CE /* CombatTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CombatTask.h; sourceTree = ""; }; + 3A537892148E81F1006DC4CE /* CommunicationTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommunicationTask.cpp; sourceTree = ""; }; + 3A537893148E81F1006DC4CE /* CommunicationTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommunicationTask.h; sourceTree = ""; }; + 3A537894148E81F1006DC4CE /* CommWaitTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommWaitTask.cpp; sourceTree = ""; }; + 3A537895148E81F1006DC4CE /* CommWaitTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommWaitTask.h; sourceTree = ""; }; + 3A537896148E81F1006DC4CE /* FleeTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FleeTask.cpp; sourceTree = ""; }; + 3A537897148E81F1006DC4CE /* FleeTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FleeTask.h; sourceTree = ""; }; + 3A537898148E81F1006DC4CE /* FollowActorTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FollowActorTask.cpp; sourceTree = ""; }; + 3A537899148E81F1006DC4CE /* FollowActorTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FollowActorTask.h; sourceTree = ""; }; + 3A53789A148E81F1006DC4CE /* GreetingBarkTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GreetingBarkTask.cpp; sourceTree = ""; }; + 3A53789B148E81F1006DC4CE /* GreetingBarkTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GreetingBarkTask.h; sourceTree = ""; }; + 3A53789C148E81F1006DC4CE /* HandleDoorTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HandleDoorTask.cpp; sourceTree = ""; }; + 3A53789D148E81F1006DC4CE /* HandleDoorTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandleDoorTask.h; sourceTree = ""; }; + 3A53789E148E81F1006DC4CE /* HandleElevatorTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HandleElevatorTask.cpp; sourceTree = ""; }; + 3A53789F148E81F1006DC4CE /* HandleElevatorTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandleElevatorTask.h; sourceTree = ""; }; + 3A5378A0148E81F1006DC4CE /* IdleAnimationTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdleAnimationTask.cpp; sourceTree = ""; }; + 3A5378A1148E81F1006DC4CE /* IdleAnimationTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdleAnimationTask.h; sourceTree = ""; }; + 3A5378A2148E81F1006DC4CE /* InteractionTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InteractionTask.cpp; sourceTree = ""; }; + 3A5378A3148E81F1006DC4CE /* InteractionTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteractionTask.h; sourceTree = ""; }; + 3A5378A4148E81F1006DC4CE /* InvestigateSpotTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InvestigateSpotTask.cpp; sourceTree = ""; }; + 3A5378A5148E81F1006DC4CE /* InvestigateSpotTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InvestigateSpotTask.h; sourceTree = ""; }; + 3A5378A6148E81F1006DC4CE /* MeleeCombatTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MeleeCombatTask.cpp; sourceTree = ""; }; + 3A5378A7148E81F1006DC4CE /* MeleeCombatTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeleeCombatTask.h; sourceTree = ""; }; + 3A5378A8148E81F1006DC4CE /* MoveToCoverTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoveToCoverTask.cpp; sourceTree = ""; }; + 3A5378A9148E81F1006DC4CE /* MoveToCoverTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveToCoverTask.h; sourceTree = ""; }; + 3A5378AA148E81F1006DC4CE /* MoveToPositionTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoveToPositionTask.cpp; sourceTree = ""; }; + 3A5378AB148E81F1006DC4CE /* MoveToPositionTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveToPositionTask.h; sourceTree = ""; }; + 3A5378AC148E81F1006DC4CE /* PathAnimTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathAnimTask.cpp; sourceTree = ""; }; + 3A5378AD148E81F1006DC4CE /* PathAnimTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathAnimTask.h; sourceTree = ""; }; + 3A5378AE148E81F1006DC4CE /* PathCornerTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathCornerTask.cpp; sourceTree = ""; }; + 3A5378AF148E81F1006DC4CE /* PathCornerTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathCornerTask.h; sourceTree = ""; }; + 3A5378B0148E81F1006DC4CE /* PathCycleAnimTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathCycleAnimTask.cpp; sourceTree = ""; }; + 3A5378B1148E81F1006DC4CE /* PathCycleAnimTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathCycleAnimTask.h; sourceTree = ""; }; + 3A5378B2148E81F1006DC4CE /* PathHideTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathHideTask.cpp; sourceTree = ""; }; + 3A5378B3148E81F1006DC4CE /* PathHideTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathHideTask.h; sourceTree = ""; }; + 3A5378B4148E81F1006DC4CE /* PathInteractTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathInteractTask.cpp; sourceTree = ""; }; + 3A5378B5148E81F1006DC4CE /* PathInteractTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathInteractTask.h; sourceTree = ""; }; + 3A5378B6148E81F1006DC4CE /* PathLookatTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathLookatTask.cpp; sourceTree = ""; }; + 3A5378B7148E81F1006DC4CE /* PathLookatTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathLookatTask.h; sourceTree = ""; }; + 3A5378B8148E81F1006DC4CE /* PathShowTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathShowTask.cpp; sourceTree = ""; }; + 3A5378B9148E81F1006DC4CE /* PathShowTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathShowTask.h; sourceTree = ""; }; + 3A5378BA148E81F1006DC4CE /* PathSitTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathSitTask.cpp; sourceTree = ""; }; + 3A5378BB148E81F1006DC4CE /* PathSitTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathSitTask.h; sourceTree = ""; }; + 3A5378BC148E81F1006DC4CE /* PathSleepTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathSleepTask.cpp; sourceTree = ""; }; + 3A5378BD148E81F1006DC4CE /* PathSleepTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathSleepTask.h; sourceTree = ""; }; + 3A5378BE148E81F1006DC4CE /* PathTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathTask.cpp; sourceTree = ""; }; + 3A5378BF148E81F1006DC4CE /* PathTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathTask.h; sourceTree = ""; }; + 3A5378C0148E81F1006DC4CE /* PathTurnTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathTurnTask.cpp; sourceTree = ""; }; + 3A5378C1148E81F1006DC4CE /* PathTurnTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathTurnTask.h; sourceTree = ""; }; + 3A5378C2148E81F1006DC4CE /* PathWaitForTriggerTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathWaitForTriggerTask.cpp; sourceTree = ""; }; + 3A5378C3148E81F1006DC4CE /* PathWaitForTriggerTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathWaitForTriggerTask.h; sourceTree = ""; }; + 3A5378C4148E81F1006DC4CE /* PathWaitTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathWaitTask.cpp; sourceTree = ""; }; + 3A5378C5148E81F1006DC4CE /* PathWaitTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathWaitTask.h; sourceTree = ""; }; + 3A5378C6148E81F1006DC4CE /* PlayAnimationTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlayAnimationTask.cpp; sourceTree = ""; }; + 3A5378C7148E81F1006DC4CE /* PlayAnimationTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayAnimationTask.h; sourceTree = ""; }; + 3A5378C8148E81F1006DC4CE /* RandomHeadturnTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomHeadturnTask.cpp; sourceTree = ""; }; + 3A5378C9148E81F1006DC4CE /* RandomHeadturnTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomHeadturnTask.h; sourceTree = ""; }; + 3A5378CA148E81F1006DC4CE /* RandomTurningTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomTurningTask.cpp; sourceTree = ""; }; + 3A5378CB148E81F1006DC4CE /* RandomTurningTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomTurningTask.h; sourceTree = ""; }; + 3A5378CC148E81F1006DC4CE /* RangedCombatTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RangedCombatTask.cpp; sourceTree = ""; }; + 3A5378CD148E81F1006DC4CE /* RangedCombatTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RangedCombatTask.h; sourceTree = ""; }; + 3A5378CE148E81F1006DC4CE /* RepeatedBarkTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RepeatedBarkTask.cpp; sourceTree = ""; }; + 3A5378CF148E81F1006DC4CE /* RepeatedBarkTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RepeatedBarkTask.h; sourceTree = ""; }; + 3A5378D0148E81F1006DC4CE /* ResolveMovementBlockTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResolveMovementBlockTask.cpp; sourceTree = ""; }; + 3A5378D1148E81F1006DC4CE /* ResolveMovementBlockTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolveMovementBlockTask.h; sourceTree = ""; }; + 3A5378D2148E81F1006DC4CE /* ScriptTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptTask.cpp; sourceTree = ""; }; + 3A5378D3148E81F1006DC4CE /* ScriptTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptTask.h; sourceTree = ""; }; + 3A5378D4148E81F1006DC4CE /* SingleBarkTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SingleBarkTask.cpp; sourceTree = ""; }; + 3A5378D5148E81F1006DC4CE /* SingleBarkTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleBarkTask.h; sourceTree = ""; }; + 3A5378D6148E81F1006DC4CE /* Task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Task.h; sourceTree = ""; }; + 3A5378D7148E81F1006DC4CE /* ThrowObjectTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThrowObjectTask.cpp; sourceTree = ""; }; + 3A5378D8148E81F1006DC4CE /* ThrowObjectTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThrowObjectTask.h; sourceTree = ""; }; + 3A5378D9148E81F1006DC4CE /* WaitTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaitTask.cpp; sourceTree = ""; }; + 3A5378DA148E81F1006DC4CE /* WaitTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaitTask.h; sourceTree = ""; }; + 3A5378DB148E81F1006DC4CE /* WanderInLocationTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WanderInLocationTask.cpp; sourceTree = ""; }; + 3A5378DC148E81F1006DC4CE /* WanderInLocationTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WanderInLocationTask.h; sourceTree = ""; }; + 3A5378DD148E81F1006DC4CE /* tdmAASFindEscape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tdmAASFindEscape.cpp; sourceTree = ""; }; + 3A5378DE148E81F1006DC4CE /* tdmAASFindEscape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tdmAASFindEscape.h; sourceTree = ""; }; + 3A537986148E8200006DC4CE /* Force_Push.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Push.cpp; sourceTree = ""; }; + 3A537987148E8200006DC4CE /* Force_Push.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Force_Push.h; sourceTree = ""; }; + 3A537A56148E9F62006DC4CE /* Physics_Liquid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Liquid.cpp; sourceTree = ""; }; + 3A537A57148E9F62006DC4CE /* Physics_Liquid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Physics_Liquid.h; sourceTree = ""; }; + 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = idlib.xcodeproj; sourceTree = ""; }; + 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PlayerIcon.cpp; path = ../../game/PlayerIcon.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3C0912C42F005D34B9 /* Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Actor.cpp; path = ../../game/Actor.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3D0912C42F005D34B9 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../game/Actor.h; sourceTree = SOURCE_ROOT; }; + 81225A3E0912C42F005D34B9 /* AF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AF.cpp; path = ../../game/AF.cpp; sourceTree = SOURCE_ROOT; }; + 81225A3F0912C42F005D34B9 /* AF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AF.h; path = ../../game/AF.h; sourceTree = SOURCE_ROOT; }; + 81225A400912C42F005D34B9 /* AFEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AFEntity.cpp; path = ../../game/AFEntity.cpp; sourceTree = SOURCE_ROOT; }; + 81225A410912C42F005D34B9 /* AFEntity.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AFEntity.h; path = ../../game/AFEntity.h; sourceTree = SOURCE_ROOT; }; + 81225A430912C42F005D34B9 /* AAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS.cpp; sourceTree = ""; }; + 81225A440912C42F005D34B9 /* AAS.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AAS.h; sourceTree = ""; }; + 81225A450912C42F005D34B9 /* AAS_debug.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_debug.cpp; sourceTree = ""; }; + 81225A460912C42F005D34B9 /* AAS_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AAS_local.h; sourceTree = ""; }; + 81225A470912C42F005D34B9 /* AAS_pathing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_pathing.cpp; sourceTree = ""; }; + 81225A480912C42F005D34B9 /* AAS_routing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AAS_routing.cpp; sourceTree = ""; }; + 81225A490912C42F005D34B9 /* AI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI.cpp; sourceTree = ""; }; + 81225A4A0912C42F005D34B9 /* AI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AI.h; sourceTree = ""; }; + 81225A4B0912C42F005D34B9 /* AI_events.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI_events.cpp; sourceTree = ""; }; + 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AI_pathing.cpp; sourceTree = ""; }; + 81225A4F0912C42F005D34B9 /* Anim.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim.cpp; sourceTree = ""; }; + 81225A500912C42F005D34B9 /* Anim.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Anim.h; sourceTree = ""; }; + 81225A510912C42F005D34B9 /* Anim_Blend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Blend.cpp; sourceTree = ""; }; + 81225A520912C42F005D34B9 /* Anim_Import.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Import.cpp; sourceTree = ""; }; + 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Anim_Testmodel.cpp; sourceTree = ""; }; + 81225A540912C42F005D34B9 /* Anim_Testmodel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Anim_Testmodel.h; sourceTree = ""; }; + 81225A550912C42F005D34B9 /* BrittleFracture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BrittleFracture.cpp; path = ../../game/BrittleFracture.cpp; sourceTree = SOURCE_ROOT; }; + 81225A560912C42F005D34B9 /* BrittleFracture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = BrittleFracture.h; path = ../../game/BrittleFracture.h; sourceTree = SOURCE_ROOT; }; + 81225A570912C42F005D34B9 /* Camera.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Camera.cpp; path = ../../game/Camera.cpp; sourceTree = SOURCE_ROOT; }; + 81225A580912C42F005D34B9 /* Camera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Camera.h; path = ../../game/Camera.h; sourceTree = SOURCE_ROOT; }; + 81225A590912C42F005D34B9 /* Entity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Entity.cpp; path = ../../game/Entity.cpp; sourceTree = SOURCE_ROOT; }; + 81225A5A0912C42F005D34B9 /* Entity.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Entity.h; path = ../../game/Entity.h; sourceTree = SOURCE_ROOT; }; + 81225A5D0912C42F005D34B9 /* Game.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Game.def; path = ../../game/Game.def; sourceTree = SOURCE_ROOT; }; + 81225A5E0912C42F005D34B9 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Game.h; path = ../../game/Game.h; sourceTree = SOURCE_ROOT; }; + 81225A5F0912C42F005D34B9 /* Game_local.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Game_local.cpp; path = ../../game/Game_local.cpp; sourceTree = SOURCE_ROOT; }; + 81225A600912C42F005D34B9 /* Game_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Game_local.h; path = ../../game/Game_local.h; sourceTree = SOURCE_ROOT; }; + 81225A610912C42F005D34B9 /* Game_network.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Game_network.cpp; path = ../../game/Game_network.cpp; sourceTree = SOURCE_ROOT; }; + 81225A620912C42F005D34B9 /* GameEdit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = GameEdit.cpp; path = ../../game/GameEdit.cpp; sourceTree = SOURCE_ROOT; }; + 81225A630912C42F005D34B9 /* GameEdit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GameEdit.h; path = ../../game/GameEdit.h; sourceTree = SOURCE_ROOT; }; + 81225A650912C42F005D34B9 /* Class.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Class.cpp; sourceTree = ""; }; + 81225A660912C42F005D34B9 /* Class.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Class.h; sourceTree = ""; }; + 81225A670912C42F005D34B9 /* DebugGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DebugGraph.cpp; sourceTree = ""; }; + 81225A680912C42F005D34B9 /* DebugGraph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DebugGraph.h; sourceTree = ""; }; + 81225A690912C42F005D34B9 /* Event.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = ""; }; + 81225A6A0912C42F005D34B9 /* Event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; + 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NoGameTypeInfo.h; sourceTree = ""; }; + 81225A6C0912C42F005D34B9 /* SaveGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SaveGame.cpp; sourceTree = ""; }; + 81225A6D0912C42F005D34B9 /* SaveGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SaveGame.h; sourceTree = ""; }; + 81225A6E0912C42F005D34B9 /* SysCmds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysCmds.cpp; sourceTree = ""; }; + 81225A6F0912C42F005D34B9 /* SysCmds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysCmds.h; sourceTree = ""; }; + 81225A700912C42F005D34B9 /* SysCvar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysCvar.cpp; sourceTree = ""; }; + 81225A710912C42F005D34B9 /* SysCvar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysCvar.h; sourceTree = ""; }; + 81225A720912C42F005D34B9 /* TypeInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TypeInfo.cpp; sourceTree = ""; }; + 81225A730912C42F005D34B9 /* TypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TypeInfo.h; sourceTree = ""; }; + 81225A740912C42F005D34B9 /* IK.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = IK.cpp; path = ../../game/IK.cpp; sourceTree = SOURCE_ROOT; }; + 81225A750912C42F005D34B9 /* IK.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IK.h; path = ../../game/IK.h; sourceTree = SOURCE_ROOT; }; + 81225A760912C42F005D34B9 /* Item.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Item.cpp; path = ../../game/Item.cpp; sourceTree = SOURCE_ROOT; }; + 81225A770912C42F005D34B9 /* Item.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Item.h; path = ../../game/Item.h; sourceTree = SOURCE_ROOT; }; + 81225A780912C42F005D34B9 /* Light.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Light.cpp; path = ../../game/Light.cpp; sourceTree = SOURCE_ROOT; }; + 81225A790912C42F005D34B9 /* Light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Light.h; path = ../../game/Light.h; sourceTree = SOURCE_ROOT; }; + 81225A7A0912C42F005D34B9 /* Misc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Misc.cpp; path = ../../game/Misc.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7B0912C42F005D34B9 /* Misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Misc.h; path = ../../game/Misc.h; sourceTree = SOURCE_ROOT; }; + 81225A7C0912C42F005D34B9 /* Moveable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Moveable.cpp; path = ../../game/Moveable.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7D0912C42F005D34B9 /* Moveable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Moveable.h; path = ../../game/Moveable.h; sourceTree = SOURCE_ROOT; }; + 81225A7E0912C42F005D34B9 /* Mover.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Mover.cpp; path = ../../game/Mover.cpp; sourceTree = SOURCE_ROOT; }; + 81225A7F0912C42F005D34B9 /* Mover.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Mover.h; path = ../../game/Mover.h; sourceTree = SOURCE_ROOT; }; + 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultiplayerGame.cpp; path = ../../game/MultiplayerGame.cpp; sourceTree = SOURCE_ROOT; }; + 81225A810912C42F005D34B9 /* MultiplayerGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MultiplayerGame.h; path = ../../game/MultiplayerGame.h; sourceTree = SOURCE_ROOT; }; + 81225A830912C42F005D34B9 /* Clip.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Clip.cpp; sourceTree = ""; }; + 81225A840912C42F005D34B9 /* Clip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Clip.h; sourceTree = ""; }; + 81225A850912C42F005D34B9 /* Force.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force.cpp; sourceTree = ""; }; + 81225A860912C42F005D34B9 /* Force.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force.h; sourceTree = ""; }; + 81225A870912C42F005D34B9 /* Force_Constant.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Constant.cpp; sourceTree = ""; }; + 81225A880912C42F005D34B9 /* Force_Constant.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Constant.h; sourceTree = ""; }; + 81225A890912C42F005D34B9 /* Force_Drag.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Drag.cpp; sourceTree = ""; }; + 81225A8A0912C42F005D34B9 /* Force_Drag.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Drag.h; sourceTree = ""; }; + 81225A8B0912C42F005D34B9 /* Force_Field.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Field.cpp; sourceTree = ""; }; + 81225A8C0912C42F005D34B9 /* Force_Field.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Field.h; sourceTree = ""; }; + 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Force_Spring.cpp; sourceTree = ""; }; + 81225A8E0912C42F005D34B9 /* Force_Spring.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Force_Spring.h; sourceTree = ""; }; + 81225A8F0912C42F005D34B9 /* Physics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics.cpp; sourceTree = ""; }; + 81225A900912C42F005D34B9 /* Physics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics.h; sourceTree = ""; }; + 81225A910912C42F005D34B9 /* Physics_Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Actor.cpp; sourceTree = ""; }; + 81225A920912C42F005D34B9 /* Physics_Actor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Actor.h; sourceTree = ""; }; + 81225A930912C42F005D34B9 /* Physics_AF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_AF.cpp; sourceTree = ""; }; + 81225A940912C42F005D34B9 /* Physics_AF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_AF.h; sourceTree = ""; }; + 81225A950912C42F005D34B9 /* Physics_Base.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Base.cpp; sourceTree = ""; }; + 81225A960912C42F005D34B9 /* Physics_Base.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Base.h; sourceTree = ""; }; + 81225A970912C42F005D34B9 /* Physics_Monster.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Monster.cpp; sourceTree = ""; }; + 81225A980912C42F005D34B9 /* Physics_Monster.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Monster.h; sourceTree = ""; }; + 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Parametric.cpp; sourceTree = ""; }; + 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Parametric.h; sourceTree = ""; }; + 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Player.cpp; sourceTree = ""; }; + 81225A9C0912C42F005D34B9 /* Physics_Player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Player.h; sourceTree = ""; }; + 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_RigidBody.cpp; sourceTree = ""; }; + 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_RigidBody.h; sourceTree = ""; }; + 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_Static.cpp; sourceTree = ""; }; + 81225AA00912C42F005D34B9 /* Physics_Static.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_Static.h; sourceTree = ""; }; + 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Physics_StaticMulti.cpp; sourceTree = ""; }; + 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Physics_StaticMulti.h; sourceTree = ""; }; + 81225AA30912C42F005D34B9 /* Push.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Push.cpp; sourceTree = ""; }; + 81225AA40912C42F005D34B9 /* Push.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Push.h; sourceTree = ""; }; + 81225AA50912C42F005D34B9 /* Player.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Player.cpp; path = ../../game/Player.cpp; sourceTree = SOURCE_ROOT; }; + 81225AA60912C42F005D34B9 /* Player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Player.h; path = ../../game/Player.h; sourceTree = SOURCE_ROOT; }; + 81225AA70912C42F005D34B9 /* PlayerView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PlayerView.cpp; path = ../../game/PlayerView.cpp; sourceTree = SOURCE_ROOT; }; + 81225AA80912C42F005D34B9 /* PlayerView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PlayerView.h; path = ../../game/PlayerView.h; sourceTree = SOURCE_ROOT; }; + 81225AA90912C42F005D34B9 /* Projectile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Projectile.cpp; path = ../../game/Projectile.cpp; sourceTree = SOURCE_ROOT; }; + 81225AAA0912C42F005D34B9 /* Projectile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Projectile.h; path = ../../game/Projectile.h; sourceTree = SOURCE_ROOT; }; + 81225AAB0912C42F005D34B9 /* Pvs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pvs.cpp; path = ../../game/Pvs.cpp; sourceTree = SOURCE_ROOT; }; + 81225AAC0912C42F005D34B9 /* Pvs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Pvs.h; path = ../../game/Pvs.h; sourceTree = SOURCE_ROOT; }; + 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Compiler.cpp; sourceTree = ""; }; + 81225AAF0912C42F005D34B9 /* Script_Compiler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Compiler.h; sourceTree = ""; }; + 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Interpreter.cpp; sourceTree = ""; }; + 81225AB10912C42F005D34B9 /* Script_Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Interpreter.h; sourceTree = ""; }; + 81225AB20912C42F005D34B9 /* Script_Program.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Program.cpp; sourceTree = ""; }; + 81225AB30912C42F005D34B9 /* Script_Program.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Program.h; sourceTree = ""; }; + 81225AB40912C42F005D34B9 /* Script_Thread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Script_Thread.cpp; sourceTree = ""; }; + 81225AB50912C42F005D34B9 /* Script_Thread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Script_Thread.h; sourceTree = ""; }; + 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SecurityCamera.cpp; path = ../../game/SecurityCamera.cpp; sourceTree = SOURCE_ROOT; }; + 81225AB70912C42F005D34B9 /* SecurityCamera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SecurityCamera.h; path = ../../game/SecurityCamera.h; sourceTree = SOURCE_ROOT; }; + 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SmokeParticles.cpp; path = ../../game/SmokeParticles.cpp; sourceTree = SOURCE_ROOT; }; + 81225AB90912C42F005D34B9 /* SmokeParticles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SmokeParticles.h; path = ../../game/SmokeParticles.h; sourceTree = SOURCE_ROOT; }; + 81225ABA0912C42F005D34B9 /* Sound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Sound.cpp; path = ../../game/Sound.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABB0912C42F005D34B9 /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sound.h; path = ../../game/Sound.h; sourceTree = SOURCE_ROOT; }; + 81225ABC0912C42F005D34B9 /* Target.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Target.cpp; path = ../../game/Target.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABD0912C42F005D34B9 /* Target.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Target.h; path = ../../game/Target.h; sourceTree = SOURCE_ROOT; }; + 81225ABE0912C42F005D34B9 /* Trigger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Trigger.cpp; path = ../../game/Trigger.cpp; sourceTree = SOURCE_ROOT; }; + 81225ABF0912C42F005D34B9 /* Trigger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Trigger.h; path = ../../game/Trigger.h; sourceTree = SOURCE_ROOT; }; + 81225AC00912C42F005D34B9 /* Weapon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Weapon.cpp; path = ../../game/Weapon.cpp; sourceTree = SOURCE_ROOT; }; + 81225AC10912C42F005D34B9 /* Weapon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Weapon.h; path = ../../game/Weapon.h; sourceTree = SOURCE_ROOT; }; + 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = WorldSpawn.cpp; path = ../../game/WorldSpawn.cpp; sourceTree = SOURCE_ROOT; }; + 81225AC30912C42F005D34B9 /* WorldSpawn.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = WorldSpawn.h; path = ../../game/WorldSpawn.h; sourceTree = SOURCE_ROOT; }; + D2AAC0630554660B00DB518D /* game.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = game.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D289988505E68E00004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225A3A0912C3DB005D34B9 /* libidlib_pic.a in Frameworks */, + 3A176BEF149363220077AB23 /* libjpeg.a in Frameworks */, + 3A176BF11493632A0077AB23 /* libdevil.a in Frameworks */, + 3A176BF3149363310077AB23 /* libziploader.a in Frameworks */, + 3A176D091493668A0077AB23 /* libpng.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* game */ = { + isa = PBXGroup; + children = ( + 3A176D161493675B0077AB23 /* devil.xcodeproj */, + 3A176CD0149366330077AB23 /* png.xcodeproj */, + 3A176BE6149363140077AB23 /* jpeg.xcodeproj */, + 3A176A10149359330077AB23 /* ziploader.xcodeproj */, + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */, + 3A176A6A149359C70077AB23 /* libziploader.a */, + 3A176BEE149363220077AB23 /* libjpeg.a */, + 3A176BF01493632A0077AB23 /* libdevil.a */, + 3A176BF2149363310077AB23 /* libziploader.a */, + 3A176D081493668A0077AB23 /* libpng.a */, + ); + name = game; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 3A5376A7148E8114006DC4CE /* AbsenceMarker.cpp */, + 3A5376A8148E8114006DC4CE /* AbsenceMarker.h */, + 81225A3C0912C42F005D34B9 /* Actor.cpp */, + 81225A3D0912C42F005D34B9 /* Actor.h */, + 81225A3E0912C42F005D34B9 /* AF.cpp */, + 81225A3F0912C42F005D34B9 /* AF.h */, + 81225A400912C42F005D34B9 /* AFEntity.cpp */, + 81225A410912C42F005D34B9 /* AFEntity.h */, + 81225A420912C42F005D34B9 /* ai */, + 3A5376AB148E8121006DC4CE /* AIComm_Message.cpp */, + 3A5376AC148E8121006DC4CE /* AIComm_Message.h */, + 3A5376AD148E8121006DC4CE /* AIVehicle.cpp */, + 3A5376AE148E8121006DC4CE /* AIVehicle.h */, + 81225A4E0912C42F005D34B9 /* anim */, + 3A5376B3148E813B006DC4CE /* BinaryFrobMover.cpp */, + 3A5376B4148E813B006DC4CE /* BinaryFrobMover.h */, + 3A5376B5148E813B006DC4CE /* BloodMarker.cpp */, + 3A5376B6148E813B006DC4CE /* BloodMarker.h */, + 81225A550912C42F005D34B9 /* BrittleFracture.cpp */, + 81225A560912C42F005D34B9 /* BrittleFracture.h */, + 3A5376B7148E813B006DC4CE /* ButtonStateTracker.cpp */, + 3A5376B8148E813B006DC4CE /* ButtonStateTracker.h */, + 81225A570912C42F005D34B9 /* Camera.cpp */, + 81225A580912C42F005D34B9 /* Camera.h */, + 3A5376B9148E813B006DC4CE /* CImage.cpp */, + 3A5376BA148E813B006DC4CE /* CImage.h */, + 3A5376BB148E813B006DC4CE /* DarkmodAASHidingSpotFinder.cpp */, + 3A5376BC148E813B006DC4CE /* DarkmodAASHidingSpotFinder.h */, + 3A5376BD148E813B006DC4CE /* DarkModGlobals.cpp */, + 3A5376BE148E813B006DC4CE /* DarkModGlobals.h */, + 3A5376BF148E813B006DC4CE /* darkmodHidingSpotTree.cpp */, + 3A5376C0148E813B006DC4CE /* darkmodHidingSpotTree.h */, + 3A5376C1148E813B006DC4CE /* darkModLAS.cpp */, + 3A5376C2148E813B006DC4CE /* darkModLAS.h */, + 3A5376C3148E813B006DC4CE /* decltdm_matinfo.cpp */, + 3A5376C4148E813B006DC4CE /* decltdm_matinfo.h */, + 3A5376C5148E813B006DC4CE /* declxdata.cpp */, + 3A5376C6148E813B006DC4CE /* declxdata.h */, + 3A5376C7148E813B006DC4CE /* DifficultyManager.cpp */, + 3A5376C8148E813B006DC4CE /* DifficultyManager.h */, + 3A5376C9148E813B006DC4CE /* DifficultySettings.cpp */, + 3A5376CA148E813B006DC4CE /* DifficultySettings.h */, + 3A5376CB148E813B006DC4CE /* DownloadMenu.cpp */, + 3A5376CC148E813B006DC4CE /* DownloadMenu.h */, + 3A5376CD148E813B006DC4CE /* Emitter.cpp */, + 3A5376CE148E813B006DC4CE /* Emitter.h */, + 81225A590912C42F005D34B9 /* Entity.cpp */, + 81225A5A0912C42F005D34B9 /* Entity.h */, + 3A5376CF148E813B006DC4CE /* EscapePointEvaluator.cpp */, + 3A5376D0148E813B006DC4CE /* EscapePointEvaluator.h */, + 3A5376D1148E813B006DC4CE /* EscapePointManager.cpp */, + 3A5376D2148E813B006DC4CE /* EscapePointManager.h */, + 3A5376D3148E813B006DC4CE /* Force_Grab.cpp */, + 3A5376D4148E813B006DC4CE /* Force_Grab.h */, + 3A5376D5148E813B006DC4CE /* FrobButton.cpp */, + 3A5376D6148E813B006DC4CE /* FrobButton.h */, + 3A5376D7148E813B006DC4CE /* FrobDoor.cpp */, + 3A5376D8148E813B006DC4CE /* FrobDoor.h */, + 3A5376D9148E813B006DC4CE /* FrobDoorHandle.cpp */, + 3A5376DA148E813B006DC4CE /* FrobDoorHandle.h */, + 3A5376DB148E813B006DC4CE /* FrobHandle.cpp */, + 3A5376DC148E813B006DC4CE /* FrobHandle.h */, + 3A5376DD148E813B006DC4CE /* FrobLever.cpp */, + 3A5376DE148E813B006DC4CE /* FrobLever.h */, + 3A5376DF148E813B006DC4CE /* FrobLock.cpp */, + 3A5376E0148E813B006DC4CE /* FrobLock.h */, + 3A5376E1148E813B006DC4CE /* FrobLockHandle.cpp */, + 3A5376E2148E813B006DC4CE /* FrobLockHandle.h */, + 3A5376E3148E813B006DC4CE /* Func_Shooter.cpp */, + 3A5376E4148E813B006DC4CE /* Func_Shooter.h */, + 3A5376E5148E813B006DC4CE /* FX.cpp */, + 3A5376E6148E813B006DC4CE /* FX.h */, + 81225A5D0912C42F005D34B9 /* Game.def */, + 81225A5E0912C42F005D34B9 /* Game.h */, + 81225A5F0912C42F005D34B9 /* Game_local.cpp */, + 81225A600912C42F005D34B9 /* Game_local.h */, + 81225A610912C42F005D34B9 /* Game_network.cpp */, + 81225A620912C42F005D34B9 /* GameEdit.cpp */, + 81225A630912C42F005D34B9 /* GameEdit.h */, + 3A53771B148E816A006DC4CE /* GamePlayTimer.h */, + 81225A640912C42F005D34B9 /* gamesys */, + 3A53771D148E817F006DC4CE /* Grabber.cpp */, + 3A53771E148E817F006DC4CE /* Grabber.h */, + 3A53771F148E817F006DC4CE /* HidingSpotSearchCollection.cpp */, + 3A537720148E817F006DC4CE /* HidingSpotSearchCollection.h */, + 3A537721148E817F006DC4CE /* Http */, + 3A537726148E817F006DC4CE /* I18N.cpp */, + 3A537727148E817F006DC4CE /* I18N.h */, + 81225A740912C42F005D34B9 /* IK.cpp */, + 81225A750912C42F005D34B9 /* IK.h */, + 3A537732148E8193006DC4CE /* ImageMapManager.cpp */, + 3A537733148E8193006DC4CE /* ImageMapManager.h */, + 3A537734148E8193006DC4CE /* IniFile.cpp */, + 3A537735148E8193006DC4CE /* IniFile.h */, + 3A537736148E8193006DC4CE /* Intersection.cpp */, + 3A537737148E8193006DC4CE /* Intersection.h */, + 3A537738148E8193006DC4CE /* Inventory */, + 81225A760912C42F005D34B9 /* Item.cpp */, + 81225A770912C42F005D34B9 /* Item.h */, + 81225A780912C42F005D34B9 /* Light.cpp */, + 81225A790912C42F005D34B9 /* Light.h */, + 3A537744148E8193006DC4CE /* LightController.cpp */, + 3A537745148E8193006DC4CE /* LightController.h */, + 3A537746148E8193006DC4CE /* LightGem.cpp */, + 3A537747148E8193006DC4CE /* LightGem.h */, + 3A537748148E8193006DC4CE /* Liquid.cpp */, + 3A537749148E8193006DC4CE /* Liquid.h */, + 3A53774A148E8193006DC4CE /* MaterialConverter.cpp */, + 3A53774B148E8193006DC4CE /* MaterialConverter.h */, + 3A53774C148E8193006DC4CE /* MatrixSq.h */, + 3A53774D148E8193006DC4CE /* MeleeWeapon.cpp */, + 3A53774E148E8193006DC4CE /* MeleeWeapon.h */, + 81225A7A0912C42F005D34B9 /* Misc.cpp */, + 81225A7B0912C42F005D34B9 /* Misc.h */, + 3A53774F148E8193006DC4CE /* Missions */, + 3A53775C148E8193006DC4CE /* ModelGenerator.cpp */, + 3A53775D148E8193006DC4CE /* ModelGenerator.h */, + 3A53775E148E8193006DC4CE /* ModMenu.cpp */, + 3A53775F148E8193006DC4CE /* ModMenu.h */, + 81225A7C0912C42F005D34B9 /* Moveable.cpp */, + 81225A7D0912C42F005D34B9 /* Moveable.h */, + 81225A7E0912C42F005D34B9 /* Mover.cpp */, + 81225A7F0912C42F005D34B9 /* Mover.h */, + 81225A800912C42F005D34B9 /* MultiplayerGame.cpp */, + 81225A810912C42F005D34B9 /* MultiplayerGame.h */, + 3A537760148E8193006DC4CE /* MultiStateMover.cpp */, + 3A537761148E8193006DC4CE /* MultiStateMover.h */, + 3A537762148E8193006DC4CE /* MultiStateMoverButton.cpp */, + 3A537763148E8193006DC4CE /* MultiStateMoverButton.h */, + 3A537764148E8193006DC4CE /* MultiStateMoverPosition.cpp */, + 3A537765148E8193006DC4CE /* MultiStateMoverPosition.h */, + 3A537684148E80D7006DC4CE /* Objectives */, + 3A537798148E81A1006DC4CE /* OverlaySys.cpp */, + 3A537799148E81A1006DC4CE /* OverlaySys.h */, + 81225A820912C42F005D34B9 /* physics */, + 3A53779C148E81C3006DC4CE /* PickableLock.cpp */, + 3A53779D148E81C3006DC4CE /* PickableLock.h */, + 81225AA50912C42F005D34B9 /* Player.cpp */, + 81225AA60912C42F005D34B9 /* Player.h */, + 81225A3B0912C42F005D34B9 /* PlayerIcon.cpp */, + 3A53779E148E81C3006DC4CE /* PlayerIcon.h */, + 81225AA70912C42F005D34B9 /* PlayerView.cpp */, + 81225AA80912C42F005D34B9 /* PlayerView.h */, + 3A53779F148E81C3006DC4CE /* PositionWithinRangeFinder.cpp */, + 3A5377A0148E81C3006DC4CE /* PositionWithinRangeFinder.h */, + 81225AA90912C42F005D34B9 /* Projectile.cpp */, + 81225AAA0912C42F005D34B9 /* Projectile.h */, + 3A5377A1148E81C3006DC4CE /* ProjectileResult.cpp */, + 3A5377A2148E81C3006DC4CE /* ProjectileResult.h */, + 3A5377A3148E81C3006DC4CE /* pugixml */, + 81225AAB0912C42F005D34B9 /* Pvs.cpp */, + 81225AAC0912C42F005D34B9 /* Pvs.h */, + 3A5377A8148E81C3006DC4CE /* PVSToAASMapping.cpp */, + 3A5377A9148E81C3006DC4CE /* PVSToAASMapping.h */, + 3A5377AA148E81C3006DC4CE /* randomizer */, + 3A5377B6148E81C3006DC4CE /* RawVector.cpp */, + 3A5377B7148E81C3006DC4CE /* RawVector.h */, + 3A5377B8148E81C3006DC4CE /* Relations.cpp */, + 3A5377B9148E81C3006DC4CE /* Relations.h */, + 3A5377BA148E81C3006DC4CE /* RevisionTracker.cpp */, + 3A5377BB148E81C3006DC4CE /* RevisionTracker.h */, + 81225AAD0912C42F005D34B9 /* script */, + 81225AB60912C42F005D34B9 /* SecurityCamera.cpp */, + 81225AB70912C42F005D34B9 /* SecurityCamera.h */, + 3A5377D8148E81D7006DC4CE /* SEED.cpp */, + 3A5377D9148E81D7006DC4CE /* SEED.h */, + 3A5377DA148E81D7006DC4CE /* Shop */, + 81225AB80912C42F005D34B9 /* SmokeParticles.cpp */, + 81225AB90912C42F005D34B9 /* SmokeParticles.h */, + 3A5377E1148E81D7006DC4CE /* SndProp.cpp */, + 3A5377E2148E81D7006DC4CE /* SndProp.h */, + 3A5377E3148E81D7006DC4CE /* SndPropLoader.cpp */, + 3A5377E4148E81D7006DC4CE /* SndPropLoader.h */, + 81225ABA0912C42F005D34B9 /* Sound.cpp */, + 81225ABB0912C42F005D34B9 /* Sound.h */, + 3A5377E5148E81D7006DC4CE /* sourcehook */, + 3A5377F1148E81D7006DC4CE /* StaticMulti.cpp */, + 3A5377F2148E81D7006DC4CE /* StaticMulti.h */, + 3A5377F3148E81D7006DC4CE /* StimResponse */, + 81225ABC0912C42F005D34B9 /* Target.cpp */, + 81225ABD0912C42F005D34B9 /* Target.h */, + 3A537801148E81D7006DC4CE /* TimerManager.cpp */, + 3A537802148E81D7006DC4CE /* TimerManager.h */, + 81225ABE0912C42F005D34B9 /* Trigger.cpp */, + 81225ABF0912C42F005D34B9 /* Trigger.h */, + 3A537803148E81D7006DC4CE /* UserManager.cpp */, + 3A537804148E81D7006DC4CE /* UserManager.h */, + 81225AC00912C42F005D34B9 /* Weapon.cpp */, + 81225AC10912C42F005D34B9 /* Weapon.h */, + 81225AC20912C42F005D34B9 /* WorldSpawn.cpp */, + 81225AC30912C42F005D34B9 /* WorldSpawn.h */, + 3A537805148E81D7006DC4CE /* ZipLoader */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC0630554660B00DB518D /* game.dylib */, + ); + name = Products; + sourceTree = ""; + }; + 3A176A11149359330077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176A18149359330077AB23 /* libziploader.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176BE7149363140077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176BEB149363140077AB23 /* libjpeg.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176CD1149366330077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176CD8149366330077AB23 /* libpng.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176D171493675B0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176D1B1493675B0077AB23 /* libdevil.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A537684148E80D7006DC4CE /* Objectives */ = { + isa = PBXGroup; + children = ( + 3A537685148E80FA006DC4CE /* BoolParseNode.h */, + 3A537686148E80FA006DC4CE /* CampaignStatistics.cpp */, + 3A537687148E80FA006DC4CE /* CampaignStatistics.h */, + 3A537688148E80FA006DC4CE /* EMissionResult.h */, + 3A537689148E80FA006DC4CE /* MissionData.cpp */, + 3A53768A148E80FA006DC4CE /* MissionData.h */, + 3A53768B148E80FA006DC4CE /* MissionStatistics.cpp */, + 3A53768C148E80FA006DC4CE /* MissionStatistics.h */, + 3A53768D148E80FA006DC4CE /* Objective.cpp */, + 3A53768E148E80FA006DC4CE /* Objective.h */, + 3A53768F148E80FA006DC4CE /* ObjectiveComponent.cpp */, + 3A537690148E80FA006DC4CE /* ObjectiveComponent.h */, + 3A537691148E80FA006DC4CE /* ObjectiveCondition.cpp */, + 3A537692148E80FA006DC4CE /* ObjectiveCondition.h */, + 3A537693148E80FA006DC4CE /* ObjectiveLocation.cpp */, + 3A537694148E80FA006DC4CE /* ObjectiveLocation.h */, + ); + name = Objectives; + sourceTree = ""; + }; + 3A537721148E817F006DC4CE /* Http */ = { + isa = PBXGroup; + children = ( + 3A537722148E817F006DC4CE /* HttpConnection.cpp */, + 3A537723148E817F006DC4CE /* HttpConnection.h */, + 3A537724148E817F006DC4CE /* HttpRequest.cpp */, + 3A537725148E817F006DC4CE /* HttpRequest.h */, + ); + name = Http; + path = ../../game/Http; + sourceTree = SOURCE_ROOT; + }; + 3A537738148E8193006DC4CE /* Inventory */ = { + isa = PBXGroup; + children = ( + 3A537739148E8193006DC4CE /* Category.cpp */, + 3A53773A148E8193006DC4CE /* Category.h */, + 3A53773B148E8193006DC4CE /* Cursor.cpp */, + 3A53773C148E8193006DC4CE /* Cursor.h */, + 3A53773D148E8193006DC4CE /* Inventory.cpp */, + 3A53773E148E8193006DC4CE /* Inventory.h */, + 3A53773F148E8193006DC4CE /* InventoryItem.cpp */, + 3A537740148E8193006DC4CE /* InventoryItem.h */, + 3A537741148E8193006DC4CE /* LootType.h */, + 3A537742148E8193006DC4CE /* WeaponItem.cpp */, + 3A537743148E8193006DC4CE /* WeaponItem.h */, + ); + name = Inventory; + path = ../../game/Inventory; + sourceTree = SOURCE_ROOT; + }; + 3A53774F148E8193006DC4CE /* Missions */ = { + isa = PBXGroup; + children = ( + 3A537750148E8193006DC4CE /* Download.cpp */, + 3A537751148E8193006DC4CE /* Download.h */, + 3A537752148E8193006DC4CE /* DownloadManager.cpp */, + 3A537753148E8193006DC4CE /* DownloadManager.h */, + 3A537754148E8193006DC4CE /* MissionDB.cpp */, + 3A537755148E8193006DC4CE /* MissionDB.h */, + 3A537756148E8193006DC4CE /* MissionManager.cpp */, + 3A537757148E8193006DC4CE /* MissionManager.h */, + 3A537758148E8193006DC4CE /* ModInfo.cpp */, + 3A537759148E8193006DC4CE /* ModInfo.h */, + 3A53775A148E8193006DC4CE /* ModInfoDecl.cpp */, + 3A53775B148E8193006DC4CE /* ModInfoDecl.h */, + ); + name = Missions; + path = ../../game/Missions; + sourceTree = SOURCE_ROOT; + }; + 3A5377A3148E81C3006DC4CE /* pugixml */ = { + isa = PBXGroup; + children = ( + 3A5377A4148E81C3006DC4CE /* pugiconfig.hpp */, + 3A5377A5148E81C3006DC4CE /* pugixml.cpp */, + 3A5377A6148E81C3006DC4CE /* pugixml.hpp */, + 3A5377A7148E81C3006DC4CE /* pugixpath.cpp */, + ); + name = pugixml; + path = ../../game/pugixml; + sourceTree = SOURCE_ROOT; + }; + 3A5377AA148E81C3006DC4CE /* randomizer */ = { + isa = PBXGroup; + children = ( + 3A5377AB148E81C3006DC4CE /* _lrotl.h */, + 3A5377AD148E81C3006DC4CE /* licence.htm */, + 3A5377AE148E81C3006DC4CE /* mersenne.cpp */, + 3A5377AF148E81C3006DC4CE /* mother.cpp */, + 3A5377B0148E81C3006DC4CE /* rancombi.h */, + 3A5377B1148E81C3006DC4CE /* randomc.h */, + 3A5377B2148E81C3006DC4CE /* randomc.htm */, + 3A5377B3148E81C3006DC4CE /* ranrotb.cpp */, + 3A5377B4148E81C3006DC4CE /* ranrotw.cpp */, + 3A5377B5148E81C3006DC4CE /* userintf.cpp */, + ); + name = randomizer; + path = ../../game/randomizer; + sourceTree = SOURCE_ROOT; + }; + 3A5377DA148E81D7006DC4CE /* Shop */ = { + isa = PBXGroup; + children = ( + 3A5377DB148E81D7006DC4CE /* LootRuleSet.cpp */, + 3A5377DC148E81D7006DC4CE /* LootRuleSet.h */, + 3A5377DD148E81D7006DC4CE /* Shop.cpp */, + 3A5377DE148E81D7006DC4CE /* Shop.h */, + 3A5377DF148E81D7006DC4CE /* ShopItem.cpp */, + 3A5377E0148E81D7006DC4CE /* ShopItem.h */, + ); + name = Shop; + path = ../../game/Shop; + sourceTree = SOURCE_ROOT; + }; + 3A5377E5148E81D7006DC4CE /* sourcehook */ = { + isa = PBXGroup; + children = ( + 3A5377E6148E81D7006DC4CE /* FastDelegate.h */, + 3A5377E7148E81D7006DC4CE /* sh_list.h */, + 3A5377E8148E81D7006DC4CE /* sh_memfuncinfo.h */, + 3A5377E9148E81D7006DC4CE /* sh_memory.h */, + 3A5377EA148E81D7006DC4CE /* sh_stack.h */, + 3A5377EB148E81D7006DC4CE /* sh_string.h */, + 3A5377EC148E81D7006DC4CE /* sh_tinyhash.h */, + 3A5377ED148E81D7006DC4CE /* sh_vector.h */, + 3A5377EE148E81D7006DC4CE /* sourcehook.cpp */, + 3A5377EF148E81D7006DC4CE /* sourcehook.h */, + 3A5377F0148E81D7006DC4CE /* sourcehook_impl.h */, + ); + name = sourcehook; + path = ../../game/sourcehook; + sourceTree = SOURCE_ROOT; + }; + 3A5377F3148E81D7006DC4CE /* StimResponse */ = { + isa = PBXGroup; + children = ( + 3A5377F4148E81D7006DC4CE /* Response.cpp */, + 3A5377F5148E81D7006DC4CE /* Response.h */, + 3A5377F6148E81D7006DC4CE /* ResponseEffect.cpp */, + 3A5377F7148E81D7006DC4CE /* ResponseEffect.h */, + 3A5377F8148E81D7006DC4CE /* Stim.cpp */, + 3A5377F9148E81D7006DC4CE /* Stim.h */, + 3A5377FA148E81D7006DC4CE /* StimResponse.cpp */, + 3A5377FB148E81D7006DC4CE /* StimResponse.h */, + 3A5377FC148E81D7006DC4CE /* StimResponseCollection.cpp */, + 3A5377FD148E81D7006DC4CE /* StimResponseCollection.h */, + 3A5377FE148E81D7006DC4CE /* StimResponseTimer.cpp */, + 3A5377FF148E81D7006DC4CE /* StimResponseTimer.h */, + 3A537800148E81D7006DC4CE /* StimType.h */, + ); + name = StimResponse; + path = ../../game/StimResponse; + sourceTree = SOURCE_ROOT; + }; + 3A537805148E81D7006DC4CE /* ZipLoader */ = { + isa = PBXGroup; + children = ( + 3A537806148E81D7006DC4CE /* ZipLoader.cpp */, + 3A537807148E81D7006DC4CE /* ZipLoader.h */, + ); + name = ZipLoader; + path = ../../game/ZipLoader; + sourceTree = SOURCE_ROOT; + }; + 3A537838148E81F1006DC4CE /* Conversation */ = { + isa = PBXGroup; + children = ( + 3A537839148E81F1006DC4CE /* Conversation.cpp */, + 3A53783A148E81F1006DC4CE /* Conversation.h */, + 3A53783B148E81F1006DC4CE /* ConversationCommand.cpp */, + 3A53783C148E81F1006DC4CE /* ConversationCommand.h */, + 3A53783D148E81F1006DC4CE /* ConversationSystem.cpp */, + 3A53783E148E81F1006DC4CE /* ConversationSystem.h */, + ); + path = Conversation; + sourceTree = ""; + }; + 3A537841148E81F1006DC4CE /* EAS */ = { + isa = PBXGroup; + children = ( + 3A537842148E81F1006DC4CE /* ClusterInfo.h */, + 3A537843148E81F1006DC4CE /* EAS.cpp */, + 3A537844148E81F1006DC4CE /* EAS.h */, + 3A537845148E81F1006DC4CE /* ElevatorStationInfo.h */, + 3A537846148E81F1006DC4CE /* RouteInfo.cpp */, + 3A537847148E81F1006DC4CE /* RouteInfo.h */, + 3A537848148E81F1006DC4CE /* RouteNode.cpp */, + 3A537849148E81F1006DC4CE /* RouteNode.h */, + ); + path = EAS; + sourceTree = ""; + }; + 3A537854148E81F1006DC4CE /* States */ = { + isa = PBXGroup; + children = ( + 3A537855148E81F1006DC4CE /* AgitatedSearchingState.cpp */, + 3A537856148E81F1006DC4CE /* AgitatedSearchingState.h */, + 3A537857148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.cpp */, + 3A537858148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.h */, + 3A537859148E81F1006DC4CE /* AlertIdleState.cpp */, + 3A53785A148E81F1006DC4CE /* AlertIdleState.h */, + 3A53785B148E81F1006DC4CE /* BlindedState.cpp */, + 3A53785C148E81F1006DC4CE /* BlindedState.h */, + 3A53785D148E81F1006DC4CE /* CombatState.cpp */, + 3A53785E148E81F1006DC4CE /* CombatState.h */, + 3A53785F148E81F1006DC4CE /* ConversationState.cpp */, + 3A537860148E81F1006DC4CE /* ConversationState.h */, + 3A537861148E81F1006DC4CE /* DeadState.cpp */, + 3A537862148E81F1006DC4CE /* DeadState.h */, + 3A537863148E81F1006DC4CE /* EmergeFromCoverState.cpp */, + 3A537864148E81F1006DC4CE /* EmergeFromCoverState.h */, + 3A537865148E81F1006DC4CE /* ExamineRopeState.cpp */, + 3A537866148E81F1006DC4CE /* ExamineRopeState.h */, + 3A537867148E81F1006DC4CE /* FailedKnockoutState.cpp */, + 3A537868148E81F1006DC4CE /* FailedKnockoutState.h */, + 3A537869148E81F1006DC4CE /* FleeDoneState.cpp */, + 3A53786A148E81F1006DC4CE /* FleeDoneState.h */, + 3A53786B148E81F1006DC4CE /* FleeState.cpp */, + 3A53786C148E81F1006DC4CE /* FleeState.h */, + 3A53786D148E81F1006DC4CE /* IdleSleepState.cpp */, + 3A53786E148E81F1006DC4CE /* IdleSleepState.h */, + 3A53786F148E81F1006DC4CE /* IdleState.cpp */, + 3A537870148E81F1006DC4CE /* IdleState.h */, + 3A537871148E81F1006DC4CE /* KnockedOutState.cpp */, + 3A537872148E81F1006DC4CE /* KnockedOutState.h */, + 3A537873148E81F1006DC4CE /* LostTrackOfEnemyState.cpp */, + 3A537874148E81F1006DC4CE /* LostTrackOfEnemyState.h */, + 3A537875148E81F1006DC4CE /* ObservantState.cpp */, + 3A537876148E81F1006DC4CE /* ObservantState.h */, + 3A537877148E81F1006DC4CE /* PainState.cpp */, + 3A537878148E81F1006DC4CE /* PainState.h */, + 3A537879148E81F1006DC4CE /* SearchingState.cpp */, + 3A53787A148E81F1006DC4CE /* SearchingState.h */, + 3A53787B148E81F1006DC4CE /* State.cpp */, + 3A53787C148E81F1006DC4CE /* State.h */, + 3A53787D148E81F1006DC4CE /* StayInCoverState.cpp */, + 3A53787E148E81F1006DC4CE /* StayInCoverState.h */, + 3A53787F148E81F1006DC4CE /* SuspiciousState.cpp */, + 3A537880148E81F1006DC4CE /* SuspiciousState.h */, + 3A537881148E81F1006DC4CE /* SwitchOnLightState.cpp */, + 3A537882148E81F1006DC4CE /* SwitchOnLightState.h */, + 3A537883148E81F1006DC4CE /* TakeCoverState.cpp */, + 3A537884148E81F1006DC4CE /* TakeCoverState.h */, + 3A537885148E81F1006DC4CE /* UnreachableTargetState.cpp */, + 3A537886148E81F1006DC4CE /* UnreachableTargetState.h */, + ); + path = States; + sourceTree = ""; + }; + 3A537889148E81F1006DC4CE /* Tasks */ = { + isa = PBXGroup; + children = ( + 3A53788A148E81F1006DC4CE /* AnimalPatrolTask.cpp */, + 3A53788B148E81F1006DC4CE /* AnimalPatrolTask.h */, + 3A53788C148E81F1006DC4CE /* ChaseEnemyRangedTask.cpp */, + 3A53788D148E81F1006DC4CE /* ChaseEnemyRangedTask.h */, + 3A53788E148E81F1006DC4CE /* ChaseEnemyTask.cpp */, + 3A53788F148E81F1006DC4CE /* ChaseEnemyTask.h */, + 3A537890148E81F1006DC4CE /* CombatTask.cpp */, + 3A537891148E81F1006DC4CE /* CombatTask.h */, + 3A537892148E81F1006DC4CE /* CommunicationTask.cpp */, + 3A537893148E81F1006DC4CE /* CommunicationTask.h */, + 3A537894148E81F1006DC4CE /* CommWaitTask.cpp */, + 3A537895148E81F1006DC4CE /* CommWaitTask.h */, + 3A537896148E81F1006DC4CE /* FleeTask.cpp */, + 3A537897148E81F1006DC4CE /* FleeTask.h */, + 3A537898148E81F1006DC4CE /* FollowActorTask.cpp */, + 3A537899148E81F1006DC4CE /* FollowActorTask.h */, + 3A53789A148E81F1006DC4CE /* GreetingBarkTask.cpp */, + 3A53789B148E81F1006DC4CE /* GreetingBarkTask.h */, + 3A53789C148E81F1006DC4CE /* HandleDoorTask.cpp */, + 3A53789D148E81F1006DC4CE /* HandleDoorTask.h */, + 3A53789E148E81F1006DC4CE /* HandleElevatorTask.cpp */, + 3A53789F148E81F1006DC4CE /* HandleElevatorTask.h */, + 3A5378A0148E81F1006DC4CE /* IdleAnimationTask.cpp */, + 3A5378A1148E81F1006DC4CE /* IdleAnimationTask.h */, + 3A5378A2148E81F1006DC4CE /* InteractionTask.cpp */, + 3A5378A3148E81F1006DC4CE /* InteractionTask.h */, + 3A5378A4148E81F1006DC4CE /* InvestigateSpotTask.cpp */, + 3A5378A5148E81F1006DC4CE /* InvestigateSpotTask.h */, + 3A5378A6148E81F1006DC4CE /* MeleeCombatTask.cpp */, + 3A5378A7148E81F1006DC4CE /* MeleeCombatTask.h */, + 3A5378A8148E81F1006DC4CE /* MoveToCoverTask.cpp */, + 3A5378A9148E81F1006DC4CE /* MoveToCoverTask.h */, + 3A5378AA148E81F1006DC4CE /* MoveToPositionTask.cpp */, + 3A5378AB148E81F1006DC4CE /* MoveToPositionTask.h */, + 3A5378AC148E81F1006DC4CE /* PathAnimTask.cpp */, + 3A5378AD148E81F1006DC4CE /* PathAnimTask.h */, + 3A5378AE148E81F1006DC4CE /* PathCornerTask.cpp */, + 3A5378AF148E81F1006DC4CE /* PathCornerTask.h */, + 3A5378B0148E81F1006DC4CE /* PathCycleAnimTask.cpp */, + 3A5378B1148E81F1006DC4CE /* PathCycleAnimTask.h */, + 3A5378B2148E81F1006DC4CE /* PathHideTask.cpp */, + 3A5378B3148E81F1006DC4CE /* PathHideTask.h */, + 3A5378B4148E81F1006DC4CE /* PathInteractTask.cpp */, + 3A5378B5148E81F1006DC4CE /* PathInteractTask.h */, + 3A5378B6148E81F1006DC4CE /* PathLookatTask.cpp */, + 3A5378B7148E81F1006DC4CE /* PathLookatTask.h */, + 3A5378B8148E81F1006DC4CE /* PathShowTask.cpp */, + 3A5378B9148E81F1006DC4CE /* PathShowTask.h */, + 3A5378BA148E81F1006DC4CE /* PathSitTask.cpp */, + 3A5378BB148E81F1006DC4CE /* PathSitTask.h */, + 3A5378BC148E81F1006DC4CE /* PathSleepTask.cpp */, + 3A5378BD148E81F1006DC4CE /* PathSleepTask.h */, + 3A5378BE148E81F1006DC4CE /* PathTask.cpp */, + 3A5378BF148E81F1006DC4CE /* PathTask.h */, + 3A5378C0148E81F1006DC4CE /* PathTurnTask.cpp */, + 3A5378C1148E81F1006DC4CE /* PathTurnTask.h */, + 3A5378C2148E81F1006DC4CE /* PathWaitForTriggerTask.cpp */, + 3A5378C3148E81F1006DC4CE /* PathWaitForTriggerTask.h */, + 3A5378C4148E81F1006DC4CE /* PathWaitTask.cpp */, + 3A5378C5148E81F1006DC4CE /* PathWaitTask.h */, + 3A5378C6148E81F1006DC4CE /* PlayAnimationTask.cpp */, + 3A5378C7148E81F1006DC4CE /* PlayAnimationTask.h */, + 3A5378C8148E81F1006DC4CE /* RandomHeadturnTask.cpp */, + 3A5378C9148E81F1006DC4CE /* RandomHeadturnTask.h */, + 3A5378CA148E81F1006DC4CE /* RandomTurningTask.cpp */, + 3A5378CB148E81F1006DC4CE /* RandomTurningTask.h */, + 3A5378CC148E81F1006DC4CE /* RangedCombatTask.cpp */, + 3A5378CD148E81F1006DC4CE /* RangedCombatTask.h */, + 3A5378CE148E81F1006DC4CE /* RepeatedBarkTask.cpp */, + 3A5378CF148E81F1006DC4CE /* RepeatedBarkTask.h */, + 3A5378D0148E81F1006DC4CE /* ResolveMovementBlockTask.cpp */, + 3A5378D1148E81F1006DC4CE /* ResolveMovementBlockTask.h */, + 3A5378D2148E81F1006DC4CE /* ScriptTask.cpp */, + 3A5378D3148E81F1006DC4CE /* ScriptTask.h */, + 3A5378D4148E81F1006DC4CE /* SingleBarkTask.cpp */, + 3A5378D5148E81F1006DC4CE /* SingleBarkTask.h */, + 3A5378D6148E81F1006DC4CE /* Task.h */, + 3A5378D7148E81F1006DC4CE /* ThrowObjectTask.cpp */, + 3A5378D8148E81F1006DC4CE /* ThrowObjectTask.h */, + 3A5378D9148E81F1006DC4CE /* WaitTask.cpp */, + 3A5378DA148E81F1006DC4CE /* WaitTask.h */, + 3A5378DB148E81F1006DC4CE /* WanderInLocationTask.cpp */, + 3A5378DC148E81F1006DC4CE /* WanderInLocationTask.h */, + ); + path = Tasks; + sourceTree = ""; + }; + 81225A1C0912C3A4005D34B9 /* Products */ = { + isa = PBXGroup; + children = ( + 81225A210912C3A4005D34B9 /* libidlib_pic.a */, + 81225A230912C3A4005D34B9 /* libidlib_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 81225A420912C42F005D34B9 /* ai */ = { + isa = PBXGroup; + children = ( + 3A537834148E81F1006DC4CE /* AreaManager.cpp */, + 3A537835148E81F1006DC4CE /* AreaManager.h */, + 3A537836148E81F1006DC4CE /* CommunicationSubsystem.cpp */, + 3A537837148E81F1006DC4CE /* CommunicationSubsystem.h */, + 3A537838148E81F1006DC4CE /* Conversation */, + 3A53783F148E81F1006DC4CE /* DoorInfo.cpp */, + 3A537840148E81F1006DC4CE /* DoorInfo.h */, + 3A537841148E81F1006DC4CE /* EAS */, + 3A53784A148E81F1006DC4CE /* Library.h */, + 3A53784B148E81F1006DC4CE /* Memory.cpp */, + 3A53784C148E81F1006DC4CE /* Memory.h */, + 3A53784D148E81F1006DC4CE /* Mind.cpp */, + 3A53784E148E81F1006DC4CE /* Mind.h */, + 3A53784F148E81F1006DC4CE /* MovementSubsystem.cpp */, + 3A537850148E81F1006DC4CE /* MovementSubsystem.h */, + 3A537851148E81F1006DC4CE /* MoveState.cpp */, + 3A537852148E81F1006DC4CE /* MoveState.h */, + 3A537853148E81F1006DC4CE /* Queue.h */, + 3A537854148E81F1006DC4CE /* States */, + 3A537887148E81F1006DC4CE /* Subsystem.cpp */, + 3A537888148E81F1006DC4CE /* Subsystem.h */, + 3A537889148E81F1006DC4CE /* Tasks */, + 3A5378DD148E81F1006DC4CE /* tdmAASFindEscape.cpp */, + 3A5378DE148E81F1006DC4CE /* tdmAASFindEscape.h */, + 81225A430912C42F005D34B9 /* AAS.cpp */, + 81225A440912C42F005D34B9 /* AAS.h */, + 81225A450912C42F005D34B9 /* AAS_debug.cpp */, + 81225A460912C42F005D34B9 /* AAS_local.h */, + 81225A470912C42F005D34B9 /* AAS_pathing.cpp */, + 81225A480912C42F005D34B9 /* AAS_routing.cpp */, + 81225A490912C42F005D34B9 /* AI.cpp */, + 81225A4A0912C42F005D34B9 /* AI.h */, + 81225A4B0912C42F005D34B9 /* AI_events.cpp */, + 81225A4C0912C42F005D34B9 /* AI_pathing.cpp */, + ); + name = ai; + path = ../../game/ai; + sourceTree = SOURCE_ROOT; + }; + 81225A4E0912C42F005D34B9 /* anim */ = { + isa = PBXGroup; + children = ( + 81225A4F0912C42F005D34B9 /* Anim.cpp */, + 81225A500912C42F005D34B9 /* Anim.h */, + 81225A510912C42F005D34B9 /* Anim_Blend.cpp */, + 81225A520912C42F005D34B9 /* Anim_Import.cpp */, + 81225A530912C42F005D34B9 /* Anim_Testmodel.cpp */, + 81225A540912C42F005D34B9 /* Anim_Testmodel.h */, + ); + name = anim; + path = ../../game/anim; + sourceTree = SOURCE_ROOT; + }; + 81225A640912C42F005D34B9 /* gamesys */ = { + isa = PBXGroup; + children = ( + 81225A650912C42F005D34B9 /* Class.cpp */, + 81225A660912C42F005D34B9 /* Class.h */, + 81225A670912C42F005D34B9 /* DebugGraph.cpp */, + 81225A680912C42F005D34B9 /* DebugGraph.h */, + 81225A690912C42F005D34B9 /* Event.cpp */, + 81225A6A0912C42F005D34B9 /* Event.h */, + 81225A6B0912C42F005D34B9 /* NoGameTypeInfo.h */, + 81225A6C0912C42F005D34B9 /* SaveGame.cpp */, + 81225A6D0912C42F005D34B9 /* SaveGame.h */, + 81225A6E0912C42F005D34B9 /* SysCmds.cpp */, + 81225A6F0912C42F005D34B9 /* SysCmds.h */, + 81225A700912C42F005D34B9 /* SysCvar.cpp */, + 81225A710912C42F005D34B9 /* SysCvar.h */, + 81225A720912C42F005D34B9 /* TypeInfo.cpp */, + 81225A730912C42F005D34B9 /* TypeInfo.h */, + ); + name = gamesys; + path = ../../game/gamesys; + sourceTree = SOURCE_ROOT; + }; + 81225A820912C42F005D34B9 /* physics */ = { + isa = PBXGroup; + children = ( + 3A537A56148E9F62006DC4CE /* Physics_Liquid.cpp */, + 3A537A57148E9F62006DC4CE /* Physics_Liquid.h */, + 3A537986148E8200006DC4CE /* Force_Push.cpp */, + 3A537987148E8200006DC4CE /* Force_Push.h */, + 81225A830912C42F005D34B9 /* Clip.cpp */, + 81225A840912C42F005D34B9 /* Clip.h */, + 81225A850912C42F005D34B9 /* Force.cpp */, + 81225A860912C42F005D34B9 /* Force.h */, + 81225A870912C42F005D34B9 /* Force_Constant.cpp */, + 81225A880912C42F005D34B9 /* Force_Constant.h */, + 81225A890912C42F005D34B9 /* Force_Drag.cpp */, + 81225A8A0912C42F005D34B9 /* Force_Drag.h */, + 81225A8B0912C42F005D34B9 /* Force_Field.cpp */, + 81225A8C0912C42F005D34B9 /* Force_Field.h */, + 81225A8D0912C42F005D34B9 /* Force_Spring.cpp */, + 81225A8E0912C42F005D34B9 /* Force_Spring.h */, + 81225A8F0912C42F005D34B9 /* Physics.cpp */, + 81225A900912C42F005D34B9 /* Physics.h */, + 81225A910912C42F005D34B9 /* Physics_Actor.cpp */, + 81225A920912C42F005D34B9 /* Physics_Actor.h */, + 81225A930912C42F005D34B9 /* Physics_AF.cpp */, + 81225A940912C42F005D34B9 /* Physics_AF.h */, + 81225A950912C42F005D34B9 /* Physics_Base.cpp */, + 81225A960912C42F005D34B9 /* Physics_Base.h */, + 81225A970912C42F005D34B9 /* Physics_Monster.cpp */, + 81225A980912C42F005D34B9 /* Physics_Monster.h */, + 81225A990912C42F005D34B9 /* Physics_Parametric.cpp */, + 81225A9A0912C42F005D34B9 /* Physics_Parametric.h */, + 81225A9B0912C42F005D34B9 /* Physics_Player.cpp */, + 81225A9C0912C42F005D34B9 /* Physics_Player.h */, + 81225A9D0912C42F005D34B9 /* Physics_RigidBody.cpp */, + 81225A9E0912C42F005D34B9 /* Physics_RigidBody.h */, + 81225A9F0912C42F005D34B9 /* Physics_Static.cpp */, + 81225AA00912C42F005D34B9 /* Physics_Static.h */, + 81225AA10912C42F005D34B9 /* Physics_StaticMulti.cpp */, + 81225AA20912C42F005D34B9 /* Physics_StaticMulti.h */, + 81225AA30912C42F005D34B9 /* Push.cpp */, + 81225AA40912C42F005D34B9 /* Push.h */, + ); + name = physics; + path = ../../game/physics; + sourceTree = SOURCE_ROOT; + }; + 81225AAD0912C42F005D34B9 /* script */ = { + isa = PBXGroup; + children = ( + 81225AAE0912C42F005D34B9 /* Script_Compiler.cpp */, + 81225AAF0912C42F005D34B9 /* Script_Compiler.h */, + 81225AB00912C42F005D34B9 /* Script_Interpreter.cpp */, + 81225AB10912C42F005D34B9 /* Script_Interpreter.h */, + 81225AB20912C42F005D34B9 /* Script_Program.cpp */, + 81225AB30912C42F005D34B9 /* Script_Program.h */, + 81225AB40912C42F005D34B9 /* Script_Thread.cpp */, + 81225AB50912C42F005D34B9 /* Script_Thread.h */, + ); + name = script; + path = ../../game/script; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC0600554660B00DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225AC60912C42F005D34B9 /* Actor.h in Headers */, + 81225AC80912C42F005D34B9 /* AF.h in Headers */, + 81225ACA0912C42F005D34B9 /* AFEntity.h in Headers */, + 81225ACC0912C42F005D34B9 /* AAS.h in Headers */, + 81225ACE0912C42F005D34B9 /* AAS_local.h in Headers */, + 81225AD20912C42F005D34B9 /* AI.h in Headers */, + 81225AD70912C42F005D34B9 /* Anim.h in Headers */, + 81225ADB0912C42F005D34B9 /* Anim_Testmodel.h in Headers */, + 81225ADD0912C42F005D34B9 /* BrittleFracture.h in Headers */, + 81225ADF0912C42F005D34B9 /* Camera.h in Headers */, + 81225AE10912C42F005D34B9 /* Entity.h in Headers */, + 81225AE40912C42F005D34B9 /* Game.h in Headers */, + 81225AE60912C42F005D34B9 /* Game_local.h in Headers */, + 81225AE90912C42F005D34B9 /* GameEdit.h in Headers */, + 81225AEB0912C42F005D34B9 /* Class.h in Headers */, + 81225AED0912C42F005D34B9 /* DebugGraph.h in Headers */, + 81225AEF0912C42F005D34B9 /* Event.h in Headers */, + 81225AF00912C42F005D34B9 /* NoGameTypeInfo.h in Headers */, + 81225AF20912C42F005D34B9 /* SaveGame.h in Headers */, + 81225AF40912C42F005D34B9 /* SysCmds.h in Headers */, + 81225AF60912C42F005D34B9 /* SysCvar.h in Headers */, + 81225AF80912C42F005D34B9 /* TypeInfo.h in Headers */, + 81225AFA0912C42F005D34B9 /* IK.h in Headers */, + 81225AFC0912C42F005D34B9 /* Item.h in Headers */, + 81225AFE0912C42F005D34B9 /* Light.h in Headers */, + 81225B000912C42F005D34B9 /* Misc.h in Headers */, + 81225B020912C42F005D34B9 /* Moveable.h in Headers */, + 81225B040912C42F005D34B9 /* Mover.h in Headers */, + 81225B060912C42F005D34B9 /* MultiplayerGame.h in Headers */, + 81225B080912C42F005D34B9 /* Clip.h in Headers */, + 81225B0A0912C42F005D34B9 /* Force.h in Headers */, + 81225B0C0912C42F005D34B9 /* Force_Constant.h in Headers */, + 81225B0E0912C42F005D34B9 /* Force_Drag.h in Headers */, + 81225B100912C42F005D34B9 /* Force_Field.h in Headers */, + 81225B120912C42F005D34B9 /* Force_Spring.h in Headers */, + 81225B140912C42F005D34B9 /* Physics.h in Headers */, + 81225B160912C42F005D34B9 /* Physics_Actor.h in Headers */, + 81225B180912C42F005D34B9 /* Physics_AF.h in Headers */, + 81225B1A0912C42F005D34B9 /* Physics_Base.h in Headers */, + 81225B1C0912C42F005D34B9 /* Physics_Monster.h in Headers */, + 81225B1E0912C42F005D34B9 /* Physics_Parametric.h in Headers */, + 81225B200912C42F005D34B9 /* Physics_Player.h in Headers */, + 81225B220912C42F005D34B9 /* Physics_RigidBody.h in Headers */, + 81225B240912C42F005D34B9 /* Physics_Static.h in Headers */, + 81225B260912C42F005D34B9 /* Physics_StaticMulti.h in Headers */, + 81225B280912C42F005D34B9 /* Push.h in Headers */, + 81225B2A0912C42F005D34B9 /* Player.h in Headers */, + 81225B2C0912C42F005D34B9 /* PlayerView.h in Headers */, + 81225B2E0912C42F005D34B9 /* Projectile.h in Headers */, + 81225B300912C42F005D34B9 /* Pvs.h in Headers */, + 81225B320912C42F005D34B9 /* Script_Compiler.h in Headers */, + 81225B340912C42F005D34B9 /* Script_Interpreter.h in Headers */, + 81225B360912C42F005D34B9 /* Script_Program.h in Headers */, + 81225B380912C42F005D34B9 /* Script_Thread.h in Headers */, + 81225B3A0912C42F005D34B9 /* SecurityCamera.h in Headers */, + 81225B3C0912C42F005D34B9 /* SmokeParticles.h in Headers */, + 81225B3E0912C42F005D34B9 /* Sound.h in Headers */, + 81225B400912C42F005D34B9 /* Target.h in Headers */, + 81225B420912C42F005D34B9 /* Trigger.h in Headers */, + 81225B440912C42F005D34B9 /* Weapon.h in Headers */, + 81225B460912C42F005D34B9 /* WorldSpawn.h in Headers */, + 3A537695148E80FA006DC4CE /* BoolParseNode.h in Headers */, + 3A537697148E80FA006DC4CE /* CampaignStatistics.h in Headers */, + 3A537698148E80FA006DC4CE /* EMissionResult.h in Headers */, + 3A53769A148E80FA006DC4CE /* MissionData.h in Headers */, + 3A53769C148E80FA006DC4CE /* MissionStatistics.h in Headers */, + 3A53769E148E80FA006DC4CE /* Objective.h in Headers */, + 3A5376A0148E80FA006DC4CE /* ObjectiveComponent.h in Headers */, + 3A5376A2148E80FA006DC4CE /* ObjectiveCondition.h in Headers */, + 3A5376A4148E80FA006DC4CE /* ObjectiveLocation.h in Headers */, + 3A5376AA148E8114006DC4CE /* AbsenceMarker.h in Headers */, + 3A5376B0148E8121006DC4CE /* AIComm_Message.h in Headers */, + 3A5376B2148E8121006DC4CE /* AIVehicle.h in Headers */, + 3A5376E8148E813B006DC4CE /* BinaryFrobMover.h in Headers */, + 3A5376EA148E813B006DC4CE /* BloodMarker.h in Headers */, + 3A5376EC148E813B006DC4CE /* ButtonStateTracker.h in Headers */, + 3A5376EE148E813B006DC4CE /* CImage.h in Headers */, + 3A5376F0148E813B006DC4CE /* DarkmodAASHidingSpotFinder.h in Headers */, + 3A5376F2148E813B006DC4CE /* DarkModGlobals.h in Headers */, + 3A5376F4148E813B006DC4CE /* darkmodHidingSpotTree.h in Headers */, + 3A5376F6148E813B006DC4CE /* darkModLAS.h in Headers */, + 3A5376F8148E813B006DC4CE /* decltdm_matinfo.h in Headers */, + 3A5376FA148E813B006DC4CE /* declxdata.h in Headers */, + 3A5376FC148E813B006DC4CE /* DifficultyManager.h in Headers */, + 3A5376FE148E813B006DC4CE /* DifficultySettings.h in Headers */, + 3A537700148E813B006DC4CE /* DownloadMenu.h in Headers */, + 3A537702148E813B006DC4CE /* Emitter.h in Headers */, + 3A537704148E813B006DC4CE /* EscapePointEvaluator.h in Headers */, + 3A537706148E813B006DC4CE /* EscapePointManager.h in Headers */, + 3A537708148E813B006DC4CE /* Force_Grab.h in Headers */, + 3A53770A148E813B006DC4CE /* FrobButton.h in Headers */, + 3A53770C148E813B006DC4CE /* FrobDoor.h in Headers */, + 3A53770E148E813B006DC4CE /* FrobDoorHandle.h in Headers */, + 3A537710148E813B006DC4CE /* FrobHandle.h in Headers */, + 3A537712148E813B006DC4CE /* FrobLever.h in Headers */, + 3A537714148E813B006DC4CE /* FrobLock.h in Headers */, + 3A537716148E813B006DC4CE /* FrobLockHandle.h in Headers */, + 3A537718148E813B006DC4CE /* Func_Shooter.h in Headers */, + 3A53771A148E813B006DC4CE /* FX.h in Headers */, + 3A53771C148E816A006DC4CE /* GamePlayTimer.h in Headers */, + 3A537729148E817F006DC4CE /* Grabber.h in Headers */, + 3A53772B148E817F006DC4CE /* HidingSpotSearchCollection.h in Headers */, + 3A53772D148E817F006DC4CE /* HttpConnection.h in Headers */, + 3A53772F148E817F006DC4CE /* HttpRequest.h in Headers */, + 3A537731148E817F006DC4CE /* I18N.h in Headers */, + 3A537767148E8193006DC4CE /* ImageMapManager.h in Headers */, + 3A537769148E8193006DC4CE /* IniFile.h in Headers */, + 3A53776B148E8193006DC4CE /* Intersection.h in Headers */, + 3A53776D148E8193006DC4CE /* Category.h in Headers */, + 3A53776F148E8193006DC4CE /* Cursor.h in Headers */, + 3A537771148E8193006DC4CE /* Inventory.h in Headers */, + 3A537773148E8193006DC4CE /* InventoryItem.h in Headers */, + 3A537774148E8193006DC4CE /* LootType.h in Headers */, + 3A537776148E8193006DC4CE /* WeaponItem.h in Headers */, + 3A537778148E8193006DC4CE /* LightController.h in Headers */, + 3A53777A148E8193006DC4CE /* LightGem.h in Headers */, + 3A53777C148E8193006DC4CE /* Liquid.h in Headers */, + 3A53777E148E8193006DC4CE /* MaterialConverter.h in Headers */, + 3A53777F148E8193006DC4CE /* MatrixSq.h in Headers */, + 3A537781148E8193006DC4CE /* MeleeWeapon.h in Headers */, + 3A537783148E8193006DC4CE /* Download.h in Headers */, + 3A537785148E8193006DC4CE /* DownloadManager.h in Headers */, + 3A537787148E8193006DC4CE /* MissionDB.h in Headers */, + 3A537789148E8193006DC4CE /* MissionManager.h in Headers */, + 3A53778B148E8193006DC4CE /* ModInfo.h in Headers */, + 3A53778D148E8193006DC4CE /* ModInfoDecl.h in Headers */, + 3A53778F148E8193006DC4CE /* ModelGenerator.h in Headers */, + 3A537791148E8193006DC4CE /* ModMenu.h in Headers */, + 3A537793148E8193006DC4CE /* MultiStateMover.h in Headers */, + 3A537795148E8193006DC4CE /* MultiStateMoverButton.h in Headers */, + 3A537797148E8193006DC4CE /* MultiStateMoverPosition.h in Headers */, + 3A53779B148E81A1006DC4CE /* OverlaySys.h in Headers */, + 3A5377BD148E81C3006DC4CE /* PickableLock.h in Headers */, + 3A5377BE148E81C3006DC4CE /* PlayerIcon.h in Headers */, + 3A5377C0148E81C3006DC4CE /* PositionWithinRangeFinder.h in Headers */, + 3A5377C2148E81C3006DC4CE /* ProjectileResult.h in Headers */, + 3A5377C3148E81C3006DC4CE /* pugiconfig.hpp in Headers */, + 3A5377C5148E81C3006DC4CE /* pugixml.hpp in Headers */, + 3A5377C8148E81C3006DC4CE /* PVSToAASMapping.h in Headers */, + 3A5377C9148E81C3006DC4CE /* _lrotl.h in Headers */, + 3A5377CD148E81C3006DC4CE /* rancombi.h in Headers */, + 3A5377CE148E81C3006DC4CE /* randomc.h in Headers */, + 3A5377D3148E81C3006DC4CE /* RawVector.h in Headers */, + 3A5377D5148E81C3006DC4CE /* Relations.h in Headers */, + 3A5377D7148E81C3006DC4CE /* RevisionTracker.h in Headers */, + 3A537809148E81D7006DC4CE /* SEED.h in Headers */, + 3A53780B148E81D7006DC4CE /* LootRuleSet.h in Headers */, + 3A53780D148E81D7006DC4CE /* Shop.h in Headers */, + 3A53780F148E81D7006DC4CE /* ShopItem.h in Headers */, + 3A537811148E81D7006DC4CE /* SndProp.h in Headers */, + 3A537813148E81D7006DC4CE /* SndPropLoader.h in Headers */, + 3A537814148E81D7006DC4CE /* FastDelegate.h in Headers */, + 3A537815148E81D7006DC4CE /* sh_list.h in Headers */, + 3A537816148E81D7006DC4CE /* sh_memfuncinfo.h in Headers */, + 3A537817148E81D7006DC4CE /* sh_memory.h in Headers */, + 3A537818148E81D7006DC4CE /* sh_stack.h in Headers */, + 3A537819148E81D7006DC4CE /* sh_string.h in Headers */, + 3A53781A148E81D7006DC4CE /* sh_tinyhash.h in Headers */, + 3A53781B148E81D7006DC4CE /* sh_vector.h in Headers */, + 3A53781D148E81D7006DC4CE /* sourcehook.h in Headers */, + 3A53781E148E81D7006DC4CE /* sourcehook_impl.h in Headers */, + 3A537820148E81D7006DC4CE /* StaticMulti.h in Headers */, + 3A537822148E81D7006DC4CE /* Response.h in Headers */, + 3A537824148E81D7006DC4CE /* ResponseEffect.h in Headers */, + 3A537826148E81D7006DC4CE /* Stim.h in Headers */, + 3A537828148E81D7006DC4CE /* StimResponse.h in Headers */, + 3A53782A148E81D7006DC4CE /* StimResponseCollection.h in Headers */, + 3A53782C148E81D7006DC4CE /* StimResponseTimer.h in Headers */, + 3A53782D148E81D7006DC4CE /* StimType.h in Headers */, + 3A53782F148E81D7006DC4CE /* TimerManager.h in Headers */, + 3A537831148E81D7006DC4CE /* UserManager.h in Headers */, + 3A537833148E81D7006DC4CE /* ZipLoader.h in Headers */, + 3A5378E0148E81F1006DC4CE /* AreaManager.h in Headers */, + 3A5378E2148E81F1006DC4CE /* CommunicationSubsystem.h in Headers */, + 3A5378E4148E81F1006DC4CE /* Conversation.h in Headers */, + 3A5378E6148E81F1006DC4CE /* ConversationCommand.h in Headers */, + 3A5378E8148E81F1006DC4CE /* ConversationSystem.h in Headers */, + 3A5378EA148E81F1006DC4CE /* DoorInfo.h in Headers */, + 3A5378EB148E81F1006DC4CE /* ClusterInfo.h in Headers */, + 3A5378ED148E81F1006DC4CE /* EAS.h in Headers */, + 3A5378EE148E81F1006DC4CE /* ElevatorStationInfo.h in Headers */, + 3A5378F0148E81F1006DC4CE /* RouteInfo.h in Headers */, + 3A5378F2148E81F1006DC4CE /* RouteNode.h in Headers */, + 3A5378F3148E81F1006DC4CE /* Library.h in Headers */, + 3A5378F5148E81F1006DC4CE /* Memory.h in Headers */, + 3A5378F7148E81F1006DC4CE /* Mind.h in Headers */, + 3A5378F9148E81F1006DC4CE /* MovementSubsystem.h in Headers */, + 3A5378FB148E81F1006DC4CE /* MoveState.h in Headers */, + 3A5378FC148E81F1006DC4CE /* Queue.h in Headers */, + 3A5378FE148E81F1006DC4CE /* AgitatedSearchingState.h in Headers */, + 3A537900148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.h in Headers */, + 3A537902148E81F1006DC4CE /* AlertIdleState.h in Headers */, + 3A537904148E81F1006DC4CE /* BlindedState.h in Headers */, + 3A537906148E81F1006DC4CE /* CombatState.h in Headers */, + 3A537908148E81F1006DC4CE /* ConversationState.h in Headers */, + 3A53790A148E81F1006DC4CE /* DeadState.h in Headers */, + 3A53790C148E81F1006DC4CE /* EmergeFromCoverState.h in Headers */, + 3A53790E148E81F1006DC4CE /* ExamineRopeState.h in Headers */, + 3A537910148E81F1006DC4CE /* FailedKnockoutState.h in Headers */, + 3A537912148E81F1006DC4CE /* FleeDoneState.h in Headers */, + 3A537914148E81F1006DC4CE /* FleeState.h in Headers */, + 3A537916148E81F1006DC4CE /* IdleSleepState.h in Headers */, + 3A537918148E81F1006DC4CE /* IdleState.h in Headers */, + 3A53791A148E81F1006DC4CE /* KnockedOutState.h in Headers */, + 3A53791C148E81F1006DC4CE /* LostTrackOfEnemyState.h in Headers */, + 3A53791E148E81F1006DC4CE /* ObservantState.h in Headers */, + 3A537920148E81F1006DC4CE /* PainState.h in Headers */, + 3A537922148E81F1006DC4CE /* SearchingState.h in Headers */, + 3A537924148E81F1006DC4CE /* State.h in Headers */, + 3A537926148E81F1006DC4CE /* StayInCoverState.h in Headers */, + 3A537928148E81F1006DC4CE /* SuspiciousState.h in Headers */, + 3A53792A148E81F1006DC4CE /* SwitchOnLightState.h in Headers */, + 3A53792C148E81F1006DC4CE /* TakeCoverState.h in Headers */, + 3A53792E148E81F1006DC4CE /* UnreachableTargetState.h in Headers */, + 3A537930148E81F1006DC4CE /* Subsystem.h in Headers */, + 3A537932148E81F1006DC4CE /* AnimalPatrolTask.h in Headers */, + 3A537934148E81F1006DC4CE /* ChaseEnemyRangedTask.h in Headers */, + 3A537936148E81F1006DC4CE /* ChaseEnemyTask.h in Headers */, + 3A537938148E81F1006DC4CE /* CombatTask.h in Headers */, + 3A53793A148E81F1006DC4CE /* CommunicationTask.h in Headers */, + 3A53793C148E81F1006DC4CE /* CommWaitTask.h in Headers */, + 3A53793E148E81F1006DC4CE /* FleeTask.h in Headers */, + 3A537940148E81F1006DC4CE /* FollowActorTask.h in Headers */, + 3A537942148E81F1006DC4CE /* GreetingBarkTask.h in Headers */, + 3A537944148E81F1006DC4CE /* HandleDoorTask.h in Headers */, + 3A537946148E81F1006DC4CE /* HandleElevatorTask.h in Headers */, + 3A537948148E81F1006DC4CE /* IdleAnimationTask.h in Headers */, + 3A53794A148E81F1006DC4CE /* InteractionTask.h in Headers */, + 3A53794C148E81F1006DC4CE /* InvestigateSpotTask.h in Headers */, + 3A53794E148E81F1006DC4CE /* MeleeCombatTask.h in Headers */, + 3A537950148E81F1006DC4CE /* MoveToCoverTask.h in Headers */, + 3A537952148E81F1006DC4CE /* MoveToPositionTask.h in Headers */, + 3A537954148E81F1006DC4CE /* PathAnimTask.h in Headers */, + 3A537956148E81F1006DC4CE /* PathCornerTask.h in Headers */, + 3A537958148E81F1006DC4CE /* PathCycleAnimTask.h in Headers */, + 3A53795A148E81F1006DC4CE /* PathHideTask.h in Headers */, + 3A53795C148E81F1006DC4CE /* PathInteractTask.h in Headers */, + 3A53795E148E81F1006DC4CE /* PathLookatTask.h in Headers */, + 3A537960148E81F1006DC4CE /* PathShowTask.h in Headers */, + 3A537962148E81F1006DC4CE /* PathSitTask.h in Headers */, + 3A537964148E81F1006DC4CE /* PathSleepTask.h in Headers */, + 3A537966148E81F1006DC4CE /* PathTask.h in Headers */, + 3A537968148E81F1006DC4CE /* PathTurnTask.h in Headers */, + 3A53796A148E81F1006DC4CE /* PathWaitForTriggerTask.h in Headers */, + 3A53796C148E81F1006DC4CE /* PathWaitTask.h in Headers */, + 3A53796E148E81F1006DC4CE /* PlayAnimationTask.h in Headers */, + 3A537970148E81F1006DC4CE /* RandomHeadturnTask.h in Headers */, + 3A537972148E81F1006DC4CE /* RandomTurningTask.h in Headers */, + 3A537974148E81F1006DC4CE /* RangedCombatTask.h in Headers */, + 3A537976148E81F1006DC4CE /* RepeatedBarkTask.h in Headers */, + 3A537978148E81F1006DC4CE /* ResolveMovementBlockTask.h in Headers */, + 3A53797A148E81F1006DC4CE /* ScriptTask.h in Headers */, + 3A53797C148E81F1006DC4CE /* SingleBarkTask.h in Headers */, + 3A53797D148E81F1006DC4CE /* Task.h in Headers */, + 3A53797F148E81F1006DC4CE /* ThrowObjectTask.h in Headers */, + 3A537981148E81F1006DC4CE /* WaitTask.h in Headers */, + 3A537983148E81F1006DC4CE /* WanderInLocationTask.h in Headers */, + 3A537985148E81F1006DC4CE /* tdmAASFindEscape.h in Headers */, + 3A537989148E8200006DC4CE /* Force_Push.h in Headers */, + 3A537A59148E9F62006DC4CE /* Physics_Liquid.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC0620554660B00DB518D /* game */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81225A240912C3A4005D34B9 /* Build configuration list for PBXNativeTarget "game" */; + buildPhases = ( + D2AAC0600554660B00DB518D /* Headers */, + D2AAC0610554660B00DB518D /* Sources */, + D289988505E68E00004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3A176D5814936F5A0077AB23 /* PBXTargetDependency */, + 3A176D5A14936F5D0077AB23 /* PBXTargetDependency */, + 3A176D5C14936F5F0077AB23 /* PBXTargetDependency */, + 3A176D5E14936F610077AB23 /* PBXTargetDependency */, + 81225A390912C3C8005D34B9 /* PBXTargetDependency */, + ); + name = game; + productName = game; + productReference = D2AAC0630554660B00DB518D /* game.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + ORGANIZATIONNAME = "id Software LLC"; + }; + buildConfigurationList = 81225A280912C3A4005D34B9 /* Build configuration list for PBXProject "game" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* game */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 3A176D171493675B0077AB23 /* Products */; + ProjectRef = 3A176D161493675B0077AB23 /* devil.xcodeproj */; + }, + { + ProductGroup = 81225A1C0912C3A4005D34B9 /* Products */; + ProjectRef = 81225A1B0912C3A4005D34B9 /* idlib.xcodeproj */; + }, + { + ProductGroup = 3A176BE7149363140077AB23 /* Products */; + ProjectRef = 3A176BE6149363140077AB23 /* jpeg.xcodeproj */; + }, + { + ProductGroup = 3A176CD1149366330077AB23 /* Products */; + ProjectRef = 3A176CD0149366330077AB23 /* png.xcodeproj */; + }, + { + ProductGroup = 3A176A11149359330077AB23 /* Products */; + ProjectRef = 3A176A10149359330077AB23 /* ziploader.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + D2AAC0620554660B00DB518D /* game */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 3A176A18149359330077AB23 /* libziploader.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libziploader.a; + remoteRef = 3A176A17149359330077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3A176BEB149363140077AB23 /* libjpeg.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libjpeg.a; + remoteRef = 3A176BEA149363140077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3A176CD8149366330077AB23 /* libpng.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libpng.a; + remoteRef = 3A176CD7149366330077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3A176D1B1493675B0077AB23 /* libdevil.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libdevil.a; + remoteRef = 3A176D1A1493675B0077AB23 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 81225A210912C3A4005D34B9 /* libidlib_pic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_pic.a; + remoteRef = 81225A200912C3A4005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 81225A230912C3A4005D34B9 /* libidlib_nopic.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libidlib_nopic.a; + remoteRef = 81225A220912C3A4005D34B9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC0610554660B00DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81225AC40912C42F005D34B9 /* PlayerIcon.cpp in Sources */, + 81225AC50912C42F005D34B9 /* Actor.cpp in Sources */, + 81225AC70912C42F005D34B9 /* AF.cpp in Sources */, + 81225AC90912C42F005D34B9 /* AFEntity.cpp in Sources */, + 81225ACB0912C42F005D34B9 /* AAS.cpp in Sources */, + 81225ACD0912C42F005D34B9 /* AAS_debug.cpp in Sources */, + 81225ACF0912C42F005D34B9 /* AAS_pathing.cpp in Sources */, + 81225AD00912C42F005D34B9 /* AAS_routing.cpp in Sources */, + 81225AD10912C42F005D34B9 /* AI.cpp in Sources */, + 81225AD30912C42F005D34B9 /* AI_events.cpp in Sources */, + 81225AD40912C42F005D34B9 /* AI_pathing.cpp in Sources */, + 81225AD60912C42F005D34B9 /* Anim.cpp in Sources */, + 81225AD80912C42F005D34B9 /* Anim_Blend.cpp in Sources */, + 81225AD90912C42F005D34B9 /* Anim_Import.cpp in Sources */, + 81225ADA0912C42F005D34B9 /* Anim_Testmodel.cpp in Sources */, + 81225ADC0912C42F005D34B9 /* BrittleFracture.cpp in Sources */, + 81225ADE0912C42F005D34B9 /* Camera.cpp in Sources */, + 81225AE00912C42F005D34B9 /* Entity.cpp in Sources */, + 81225AE50912C42F005D34B9 /* Game_local.cpp in Sources */, + 81225AE70912C42F005D34B9 /* Game_network.cpp in Sources */, + 81225AE80912C42F005D34B9 /* GameEdit.cpp in Sources */, + 81225AEA0912C42F005D34B9 /* Class.cpp in Sources */, + 81225AEC0912C42F005D34B9 /* DebugGraph.cpp in Sources */, + 81225AEE0912C42F005D34B9 /* Event.cpp in Sources */, + 81225AF10912C42F005D34B9 /* SaveGame.cpp in Sources */, + 81225AF30912C42F005D34B9 /* SysCmds.cpp in Sources */, + 81225AF50912C42F005D34B9 /* SysCvar.cpp in Sources */, + 81225AF70912C42F005D34B9 /* TypeInfo.cpp in Sources */, + 81225AF90912C42F005D34B9 /* IK.cpp in Sources */, + 81225AFB0912C42F005D34B9 /* Item.cpp in Sources */, + 81225AFD0912C42F005D34B9 /* Light.cpp in Sources */, + 81225AFF0912C42F005D34B9 /* Misc.cpp in Sources */, + 81225B010912C42F005D34B9 /* Moveable.cpp in Sources */, + 81225B030912C42F005D34B9 /* Mover.cpp in Sources */, + 81225B050912C42F005D34B9 /* MultiplayerGame.cpp in Sources */, + 81225B070912C42F005D34B9 /* Clip.cpp in Sources */, + 81225B090912C42F005D34B9 /* Force.cpp in Sources */, + 81225B0B0912C42F005D34B9 /* Force_Constant.cpp in Sources */, + 81225B0D0912C42F005D34B9 /* Force_Drag.cpp in Sources */, + 81225B0F0912C42F005D34B9 /* Force_Field.cpp in Sources */, + 81225B110912C42F005D34B9 /* Force_Spring.cpp in Sources */, + 81225B130912C42F005D34B9 /* Physics.cpp in Sources */, + 81225B150912C42F005D34B9 /* Physics_Actor.cpp in Sources */, + 81225B170912C42F005D34B9 /* Physics_AF.cpp in Sources */, + 81225B190912C42F005D34B9 /* Physics_Base.cpp in Sources */, + 81225B1B0912C42F005D34B9 /* Physics_Monster.cpp in Sources */, + 81225B1D0912C42F005D34B9 /* Physics_Parametric.cpp in Sources */, + 81225B1F0912C42F005D34B9 /* Physics_Player.cpp in Sources */, + 81225B210912C42F005D34B9 /* Physics_RigidBody.cpp in Sources */, + 81225B230912C42F005D34B9 /* Physics_Static.cpp in Sources */, + 81225B250912C42F005D34B9 /* Physics_StaticMulti.cpp in Sources */, + 81225B270912C42F005D34B9 /* Push.cpp in Sources */, + 81225B290912C42F005D34B9 /* Player.cpp in Sources */, + 81225B2B0912C42F005D34B9 /* PlayerView.cpp in Sources */, + 81225B2D0912C42F005D34B9 /* Projectile.cpp in Sources */, + 81225B2F0912C42F005D34B9 /* Pvs.cpp in Sources */, + 81225B310912C42F005D34B9 /* Script_Compiler.cpp in Sources */, + 81225B330912C42F005D34B9 /* Script_Interpreter.cpp in Sources */, + 81225B350912C42F005D34B9 /* Script_Program.cpp in Sources */, + 81225B370912C42F005D34B9 /* Script_Thread.cpp in Sources */, + 81225B390912C42F005D34B9 /* SecurityCamera.cpp in Sources */, + 81225B3B0912C42F005D34B9 /* SmokeParticles.cpp in Sources */, + 81225B3D0912C42F005D34B9 /* Sound.cpp in Sources */, + 81225B3F0912C42F005D34B9 /* Target.cpp in Sources */, + 81225B410912C42F005D34B9 /* Trigger.cpp in Sources */, + 81225B430912C42F005D34B9 /* Weapon.cpp in Sources */, + 81225B450912C42F005D34B9 /* WorldSpawn.cpp in Sources */, + 3A537696148E80FA006DC4CE /* CampaignStatistics.cpp in Sources */, + 3A537699148E80FA006DC4CE /* MissionData.cpp in Sources */, + 3A53769B148E80FA006DC4CE /* MissionStatistics.cpp in Sources */, + 3A53769D148E80FA006DC4CE /* Objective.cpp in Sources */, + 3A53769F148E80FA006DC4CE /* ObjectiveComponent.cpp in Sources */, + 3A5376A1148E80FA006DC4CE /* ObjectiveCondition.cpp in Sources */, + 3A5376A3148E80FA006DC4CE /* ObjectiveLocation.cpp in Sources */, + 3A5376A9148E8114006DC4CE /* AbsenceMarker.cpp in Sources */, + 3A5376AF148E8121006DC4CE /* AIComm_Message.cpp in Sources */, + 3A5376B1148E8121006DC4CE /* AIVehicle.cpp in Sources */, + 3A5376E7148E813B006DC4CE /* BinaryFrobMover.cpp in Sources */, + 3A5376E9148E813B006DC4CE /* BloodMarker.cpp in Sources */, + 3A5376EB148E813B006DC4CE /* ButtonStateTracker.cpp in Sources */, + 3A5376ED148E813B006DC4CE /* CImage.cpp in Sources */, + 3A5376EF148E813B006DC4CE /* DarkmodAASHidingSpotFinder.cpp in Sources */, + 3A5376F1148E813B006DC4CE /* DarkModGlobals.cpp in Sources */, + 3A5376F3148E813B006DC4CE /* darkmodHidingSpotTree.cpp in Sources */, + 3A5376F5148E813B006DC4CE /* darkModLAS.cpp in Sources */, + 3A5376F7148E813B006DC4CE /* decltdm_matinfo.cpp in Sources */, + 3A5376F9148E813B006DC4CE /* declxdata.cpp in Sources */, + 3A5376FB148E813B006DC4CE /* DifficultyManager.cpp in Sources */, + 3A5376FD148E813B006DC4CE /* DifficultySettings.cpp in Sources */, + 3A5376FF148E813B006DC4CE /* DownloadMenu.cpp in Sources */, + 3A537701148E813B006DC4CE /* Emitter.cpp in Sources */, + 3A537703148E813B006DC4CE /* EscapePointEvaluator.cpp in Sources */, + 3A537705148E813B006DC4CE /* EscapePointManager.cpp in Sources */, + 3A537707148E813B006DC4CE /* Force_Grab.cpp in Sources */, + 3A537709148E813B006DC4CE /* FrobButton.cpp in Sources */, + 3A53770B148E813B006DC4CE /* FrobDoor.cpp in Sources */, + 3A53770D148E813B006DC4CE /* FrobDoorHandle.cpp in Sources */, + 3A53770F148E813B006DC4CE /* FrobHandle.cpp in Sources */, + 3A537711148E813B006DC4CE /* FrobLever.cpp in Sources */, + 3A537713148E813B006DC4CE /* FrobLock.cpp in Sources */, + 3A537715148E813B006DC4CE /* FrobLockHandle.cpp in Sources */, + 3A537717148E813B006DC4CE /* Func_Shooter.cpp in Sources */, + 3A537719148E813B006DC4CE /* FX.cpp in Sources */, + 3A537728148E817F006DC4CE /* Grabber.cpp in Sources */, + 3A53772A148E817F006DC4CE /* HidingSpotSearchCollection.cpp in Sources */, + 3A53772C148E817F006DC4CE /* HttpConnection.cpp in Sources */, + 3A53772E148E817F006DC4CE /* HttpRequest.cpp in Sources */, + 3A537730148E817F006DC4CE /* I18N.cpp in Sources */, + 3A537766148E8193006DC4CE /* ImageMapManager.cpp in Sources */, + 3A537768148E8193006DC4CE /* IniFile.cpp in Sources */, + 3A53776A148E8193006DC4CE /* Intersection.cpp in Sources */, + 3A53776C148E8193006DC4CE /* Category.cpp in Sources */, + 3A53776E148E8193006DC4CE /* Cursor.cpp in Sources */, + 3A537770148E8193006DC4CE /* Inventory.cpp in Sources */, + 3A537772148E8193006DC4CE /* InventoryItem.cpp in Sources */, + 3A537775148E8193006DC4CE /* WeaponItem.cpp in Sources */, + 3A537777148E8193006DC4CE /* LightController.cpp in Sources */, + 3A537779148E8193006DC4CE /* LightGem.cpp in Sources */, + 3A53777B148E8193006DC4CE /* Liquid.cpp in Sources */, + 3A53777D148E8193006DC4CE /* MaterialConverter.cpp in Sources */, + 3A537780148E8193006DC4CE /* MeleeWeapon.cpp in Sources */, + 3A537782148E8193006DC4CE /* Download.cpp in Sources */, + 3A537784148E8193006DC4CE /* DownloadManager.cpp in Sources */, + 3A537786148E8193006DC4CE /* MissionDB.cpp in Sources */, + 3A537788148E8193006DC4CE /* MissionManager.cpp in Sources */, + 3A53778A148E8193006DC4CE /* ModInfo.cpp in Sources */, + 3A53778C148E8193006DC4CE /* ModInfoDecl.cpp in Sources */, + 3A53778E148E8193006DC4CE /* ModelGenerator.cpp in Sources */, + 3A537790148E8193006DC4CE /* ModMenu.cpp in Sources */, + 3A537792148E8193006DC4CE /* MultiStateMover.cpp in Sources */, + 3A537794148E8193006DC4CE /* MultiStateMoverButton.cpp in Sources */, + 3A537796148E8193006DC4CE /* MultiStateMoverPosition.cpp in Sources */, + 3A53779A148E81A1006DC4CE /* OverlaySys.cpp in Sources */, + 3A5377BC148E81C3006DC4CE /* PickableLock.cpp in Sources */, + 3A5377BF148E81C3006DC4CE /* PositionWithinRangeFinder.cpp in Sources */, + 3A5377C1148E81C3006DC4CE /* ProjectileResult.cpp in Sources */, + 3A5377C4148E81C3006DC4CE /* pugixml.cpp in Sources */, + 3A5377C6148E81C3006DC4CE /* pugixpath.cpp in Sources */, + 3A5377C7148E81C3006DC4CE /* PVSToAASMapping.cpp in Sources */, + 3A5377CB148E81C3006DC4CE /* mersenne.cpp in Sources */, + 3A5377CC148E81C3006DC4CE /* mother.cpp in Sources */, + 3A5377CF148E81C3006DC4CE /* ranrotb.cpp in Sources */, + 3A5377D0148E81C3006DC4CE /* ranrotw.cpp in Sources */, + 3A5377D1148E81C3006DC4CE /* userintf.cpp in Sources */, + 3A5377D2148E81C3006DC4CE /* RawVector.cpp in Sources */, + 3A5377D4148E81C3006DC4CE /* Relations.cpp in Sources */, + 3A5377D6148E81C3006DC4CE /* RevisionTracker.cpp in Sources */, + 3A537808148E81D7006DC4CE /* SEED.cpp in Sources */, + 3A53780A148E81D7006DC4CE /* LootRuleSet.cpp in Sources */, + 3A53780C148E81D7006DC4CE /* Shop.cpp in Sources */, + 3A53780E148E81D7006DC4CE /* ShopItem.cpp in Sources */, + 3A537810148E81D7006DC4CE /* SndProp.cpp in Sources */, + 3A537812148E81D7006DC4CE /* SndPropLoader.cpp in Sources */, + 3A53781C148E81D7006DC4CE /* sourcehook.cpp in Sources */, + 3A53781F148E81D7006DC4CE /* StaticMulti.cpp in Sources */, + 3A537821148E81D7006DC4CE /* Response.cpp in Sources */, + 3A537823148E81D7006DC4CE /* ResponseEffect.cpp in Sources */, + 3A537825148E81D7006DC4CE /* Stim.cpp in Sources */, + 3A537827148E81D7006DC4CE /* StimResponse.cpp in Sources */, + 3A537829148E81D7006DC4CE /* StimResponseCollection.cpp in Sources */, + 3A53782B148E81D7006DC4CE /* StimResponseTimer.cpp in Sources */, + 3A53782E148E81D7006DC4CE /* TimerManager.cpp in Sources */, + 3A537830148E81D7006DC4CE /* UserManager.cpp in Sources */, + 3A537832148E81D7006DC4CE /* ZipLoader.cpp in Sources */, + 3A5378DF148E81F1006DC4CE /* AreaManager.cpp in Sources */, + 3A5378E1148E81F1006DC4CE /* CommunicationSubsystem.cpp in Sources */, + 3A5378E3148E81F1006DC4CE /* Conversation.cpp in Sources */, + 3A5378E5148E81F1006DC4CE /* ConversationCommand.cpp in Sources */, + 3A5378E7148E81F1006DC4CE /* ConversationSystem.cpp in Sources */, + 3A5378E9148E81F1006DC4CE /* DoorInfo.cpp in Sources */, + 3A5378EC148E81F1006DC4CE /* EAS.cpp in Sources */, + 3A5378EF148E81F1006DC4CE /* RouteInfo.cpp in Sources */, + 3A5378F1148E81F1006DC4CE /* RouteNode.cpp in Sources */, + 3A5378F4148E81F1006DC4CE /* Memory.cpp in Sources */, + 3A5378F6148E81F1006DC4CE /* Mind.cpp in Sources */, + 3A5378F8148E81F1006DC4CE /* MovementSubsystem.cpp in Sources */, + 3A5378FA148E81F1006DC4CE /* MoveState.cpp in Sources */, + 3A5378FD148E81F1006DC4CE /* AgitatedSearchingState.cpp in Sources */, + 3A5378FF148E81F1006DC4CE /* AgitatedSearchingStateLanternBot.cpp in Sources */, + 3A537901148E81F1006DC4CE /* AlertIdleState.cpp in Sources */, + 3A537903148E81F1006DC4CE /* BlindedState.cpp in Sources */, + 3A537905148E81F1006DC4CE /* CombatState.cpp in Sources */, + 3A537907148E81F1006DC4CE /* ConversationState.cpp in Sources */, + 3A537909148E81F1006DC4CE /* DeadState.cpp in Sources */, + 3A53790B148E81F1006DC4CE /* EmergeFromCoverState.cpp in Sources */, + 3A53790D148E81F1006DC4CE /* ExamineRopeState.cpp in Sources */, + 3A53790F148E81F1006DC4CE /* FailedKnockoutState.cpp in Sources */, + 3A537911148E81F1006DC4CE /* FleeDoneState.cpp in Sources */, + 3A537913148E81F1006DC4CE /* FleeState.cpp in Sources */, + 3A537915148E81F1006DC4CE /* IdleSleepState.cpp in Sources */, + 3A537917148E81F1006DC4CE /* IdleState.cpp in Sources */, + 3A537919148E81F1006DC4CE /* KnockedOutState.cpp in Sources */, + 3A53791B148E81F1006DC4CE /* LostTrackOfEnemyState.cpp in Sources */, + 3A53791D148E81F1006DC4CE /* ObservantState.cpp in Sources */, + 3A53791F148E81F1006DC4CE /* PainState.cpp in Sources */, + 3A537921148E81F1006DC4CE /* SearchingState.cpp in Sources */, + 3A537923148E81F1006DC4CE /* State.cpp in Sources */, + 3A537925148E81F1006DC4CE /* StayInCoverState.cpp in Sources */, + 3A537927148E81F1006DC4CE /* SuspiciousState.cpp in Sources */, + 3A537929148E81F1006DC4CE /* SwitchOnLightState.cpp in Sources */, + 3A53792B148E81F1006DC4CE /* TakeCoverState.cpp in Sources */, + 3A53792D148E81F1006DC4CE /* UnreachableTargetState.cpp in Sources */, + 3A53792F148E81F1006DC4CE /* Subsystem.cpp in Sources */, + 3A537931148E81F1006DC4CE /* AnimalPatrolTask.cpp in Sources */, + 3A537933148E81F1006DC4CE /* ChaseEnemyRangedTask.cpp in Sources */, + 3A537935148E81F1006DC4CE /* ChaseEnemyTask.cpp in Sources */, + 3A537937148E81F1006DC4CE /* CombatTask.cpp in Sources */, + 3A537939148E81F1006DC4CE /* CommunicationTask.cpp in Sources */, + 3A53793B148E81F1006DC4CE /* CommWaitTask.cpp in Sources */, + 3A53793D148E81F1006DC4CE /* FleeTask.cpp in Sources */, + 3A53793F148E81F1006DC4CE /* FollowActorTask.cpp in Sources */, + 3A537941148E81F1006DC4CE /* GreetingBarkTask.cpp in Sources */, + 3A537943148E81F1006DC4CE /* HandleDoorTask.cpp in Sources */, + 3A537945148E81F1006DC4CE /* HandleElevatorTask.cpp in Sources */, + 3A537947148E81F1006DC4CE /* IdleAnimationTask.cpp in Sources */, + 3A537949148E81F1006DC4CE /* InteractionTask.cpp in Sources */, + 3A53794B148E81F1006DC4CE /* InvestigateSpotTask.cpp in Sources */, + 3A53794D148E81F1006DC4CE /* MeleeCombatTask.cpp in Sources */, + 3A53794F148E81F1006DC4CE /* MoveToCoverTask.cpp in Sources */, + 3A537951148E81F1006DC4CE /* MoveToPositionTask.cpp in Sources */, + 3A537953148E81F1006DC4CE /* PathAnimTask.cpp in Sources */, + 3A537955148E81F1006DC4CE /* PathCornerTask.cpp in Sources */, + 3A537957148E81F1006DC4CE /* PathCycleAnimTask.cpp in Sources */, + 3A537959148E81F1006DC4CE /* PathHideTask.cpp in Sources */, + 3A53795B148E81F1006DC4CE /* PathInteractTask.cpp in Sources */, + 3A53795D148E81F1006DC4CE /* PathLookatTask.cpp in Sources */, + 3A53795F148E81F1006DC4CE /* PathShowTask.cpp in Sources */, + 3A537961148E81F1006DC4CE /* PathSitTask.cpp in Sources */, + 3A537963148E81F1006DC4CE /* PathSleepTask.cpp in Sources */, + 3A537965148E81F1006DC4CE /* PathTask.cpp in Sources */, + 3A537967148E81F1006DC4CE /* PathTurnTask.cpp in Sources */, + 3A537969148E81F1006DC4CE /* PathWaitForTriggerTask.cpp in Sources */, + 3A53796B148E81F1006DC4CE /* PathWaitTask.cpp in Sources */, + 3A53796D148E81F1006DC4CE /* PlayAnimationTask.cpp in Sources */, + 3A53796F148E81F1006DC4CE /* RandomHeadturnTask.cpp in Sources */, + 3A537971148E81F1006DC4CE /* RandomTurningTask.cpp in Sources */, + 3A537973148E81F1006DC4CE /* RangedCombatTask.cpp in Sources */, + 3A537975148E81F1006DC4CE /* RepeatedBarkTask.cpp in Sources */, + 3A537977148E81F1006DC4CE /* ResolveMovementBlockTask.cpp in Sources */, + 3A537979148E81F1006DC4CE /* ScriptTask.cpp in Sources */, + 3A53797B148E81F1006DC4CE /* SingleBarkTask.cpp in Sources */, + 3A53797E148E81F1006DC4CE /* ThrowObjectTask.cpp in Sources */, + 3A537980148E81F1006DC4CE /* WaitTask.cpp in Sources */, + 3A537982148E81F1006DC4CE /* WanderInLocationTask.cpp in Sources */, + 3A537984148E81F1006DC4CE /* tdmAASFindEscape.cpp in Sources */, + 3A537988148E8200006DC4CE /* Force_Push.cpp in Sources */, + 3A537A58148E9F62006DC4CE /* Physics_Liquid.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3A176D5814936F5A0077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = png; + targetProxy = 3A176D5714936F5A0077AB23 /* PBXContainerItemProxy */; + }; + 3A176D5A14936F5D0077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ziploader; + targetProxy = 3A176D5914936F5D0077AB23 /* PBXContainerItemProxy */; + }; + 3A176D5C14936F5F0077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = jpeg; + targetProxy = 3A176D5B14936F5F0077AB23 /* PBXContainerItemProxy */; + }; + 3A176D5E14936F610077AB23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = devil; + targetProxy = 3A176D5D14936F610077AB23 /* PBXContainerItemProxy */; + }; + 81225A390912C3C8005D34B9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = idlib_pic; + targetProxy = 81225A380912C3C8005D34B9 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 81225A250912C3A4005D34B9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + GAME_DLL, + __WITH_PB__, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "\"$(SRCROOT)/../../macosx/boost/lib/\"", + "\"$(SRCROOT)/../../macosx/libcurl/\"", + "\"$(SRCROOT)/build/Release\"", + ); + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MAIN_CPP_DEFINES = _DEBUG; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + OTHER_LDFLAGS = ( + "-lboost_filesystem", + "-lboost_thread", + "-lboost_system", + "-lcurl", + ); + PREBINDING = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = game; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/minizip/\" \"$(SRCROOT)/../../include/\" \"$(SRCROOT)/../../include/devil/\""; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = YES; + }; + name = Debug; + }; + 81225A260912C3A4005D34B9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + GAME_DLL, + __WITH_PB__, + ); + LIBRARY_SEARCH_PATHS = ( + "\"$(SRCROOT)/../../macosx/boost/lib/\"", + "\"$(SRCROOT)/../../macosx/libcurl/\"", + "\"$(SRCROOT)/build/Release\"", + ); + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + OTHER_LDFLAGS = ( + "-lboost_filesystem", + "-lboost_thread", + "-lboost_system", + "-lcurl", + ); + PREBINDING = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = game; + SYMROOT = build; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/minizip/\" \"$(SRCROOT)/../../include/\" \"$(SRCROOT)/../../include/devil/\""; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = NO; + }; + name = Release; + }; + 81225A290912C3A4005D34B9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 1; + GCC_PREPROCESSOR_DEFINITIONS = ( + _DEBUG, + MACOS_X, + GAME_DLL, + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Debug; + }; + 81225A2A0912C3A4005D34B9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + MACOS_X, + GAME_DLL, + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + "-fomit-frame-pointer", + "-fno-common", + ); + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 81225A240912C3A4005D34B9 /* Build configuration list for PBXNativeTarget "game" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81225A250912C3A4005D34B9 /* Debug */, + 81225A260912C3A4005D34B9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 81225A280912C3A4005D34B9 /* Build configuration list for PBXProject "game" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81225A290912C3A4005D34B9 /* Debug */, + 81225A2A0912C3A4005D34B9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/sys/osx/idlib.xcodeproj/project.pbxproj b/sys/osx/idlib.xcodeproj/project.pbxproj new file mode 100644 index 000000000..98df176bc --- /dev/null +++ b/sys/osx/idlib.xcodeproj/project.pbxproj @@ -0,0 +1,1104 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3A1767C7149346E90077AB23 /* Frustum_gcc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3A1767C6149346E90077AB23 /* Frustum_gcc.cpp */; }; + 81C857480912AD020095BC33 /* BitMsg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857470912AD020095BC33 /* BitMsg.cpp */; }; + 81C857C90912AD0D0095BC33 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8574A0912AD0D0095BC33 /* Base64.cpp */; }; + 81C857CA0912AD0D0095BC33 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574B0912AD0D0095BC33 /* Base64.h */; }; + 81C857CB0912AD0D0095BC33 /* BitMsg.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574C0912AD0D0095BC33 /* BitMsg.h */; }; + 81C857CC0912AD0D0095BC33 /* Bounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8574E0912AD0D0095BC33 /* Bounds.cpp */; }; + 81C857CD0912AD0D0095BC33 /* Bounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574F0912AD0D0095BC33 /* Bounds.h */; }; + 81C857CE0912AD0D0095BC33 /* Box.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857500912AD0D0095BC33 /* Box.cpp */; }; + 81C857CF0912AD0D0095BC33 /* Box.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857510912AD0D0095BC33 /* Box.h */; }; + 81C857D00912AD0D0095BC33 /* Frustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857520912AD0D0095BC33 /* Frustum.cpp */; }; + 81C857D10912AD0D0095BC33 /* Frustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857530912AD0D0095BC33 /* Frustum.h */; }; + 81C857D20912AD0D0095BC33 /* Sphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857540912AD0D0095BC33 /* Sphere.cpp */; }; + 81C857D30912AD0D0095BC33 /* Sphere.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857550912AD0D0095BC33 /* Sphere.h */; }; + 81C857D40912AD0D0095BC33 /* CmdArgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857560912AD0D0095BC33 /* CmdArgs.cpp */; }; + 81C857D50912AD0D0095BC33 /* CmdArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857570912AD0D0095BC33 /* CmdArgs.h */; }; + 81C857D60912AD0D0095BC33 /* BinSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857590912AD0D0095BC33 /* BinSearch.h */; }; + 81C857D70912AD0D0095BC33 /* BTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575A0912AD0D0095BC33 /* BTree.h */; }; + 81C857D80912AD0D0095BC33 /* HashIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8575B0912AD0D0095BC33 /* HashIndex.cpp */; }; + 81C857D90912AD0D0095BC33 /* HashIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575C0912AD0D0095BC33 /* HashIndex.h */; }; + 81C857DA0912AD0D0095BC33 /* HashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575D0912AD0D0095BC33 /* HashTable.h */; }; + 81C857DB0912AD0D0095BC33 /* Hierarchy.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575E0912AD0D0095BC33 /* Hierarchy.h */; }; + 81C857DC0912AD0D0095BC33 /* LinkList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575F0912AD0D0095BC33 /* LinkList.h */; }; + 81C857DD0912AD0D0095BC33 /* List.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857600912AD0D0095BC33 /* List.h */; }; + 81C857DE0912AD0D0095BC33 /* PlaneSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857610912AD0D0095BC33 /* PlaneSet.h */; }; + 81C857DF0912AD0D0095BC33 /* Queue.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857620912AD0D0095BC33 /* Queue.h */; }; + 81C857E00912AD0D0095BC33 /* Stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857630912AD0D0095BC33 /* Stack.h */; }; + 81C857E10912AD0D0095BC33 /* StaticList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857640912AD0D0095BC33 /* StaticList.h */; }; + 81C857E20912AD0D0095BC33 /* StrList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857650912AD0D0095BC33 /* StrList.h */; }; + 81C857E30912AD0D0095BC33 /* StrPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857660912AD0D0095BC33 /* StrPool.h */; }; + 81C857E40912AD0D0095BC33 /* VectorSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857670912AD0D0095BC33 /* VectorSet.h */; }; + 81C857E50912AD0D0095BC33 /* Dict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857680912AD0D0095BC33 /* Dict.cpp */; }; + 81C857E60912AD0D0095BC33 /* Dict.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857690912AD0D0095BC33 /* Dict.h */; }; + 81C857E70912AD0D0095BC33 /* DrawVert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576B0912AD0D0095BC33 /* DrawVert.cpp */; }; + 81C857E80912AD0D0095BC33 /* DrawVert.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8576C0912AD0D0095BC33 /* DrawVert.h */; }; + 81C857E90912AD0D0095BC33 /* JointTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576D0912AD0D0095BC33 /* JointTransform.cpp */; }; + 81C857EA0912AD0D0095BC33 /* JointTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8576E0912AD0D0095BC33 /* JointTransform.h */; }; + 81C857EB0912AD0D0095BC33 /* Surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576F0912AD0D0095BC33 /* Surface.cpp */; }; + 81C857EC0912AD0D0095BC33 /* Surface.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857700912AD0D0095BC33 /* Surface.h */; }; + 81C857ED0912AD0D0095BC33 /* Surface_Patch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857710912AD0D0095BC33 /* Surface_Patch.cpp */; }; + 81C857EE0912AD0D0095BC33 /* Surface_Patch.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857720912AD0D0095BC33 /* Surface_Patch.h */; }; + 81C857EF0912AD0D0095BC33 /* Surface_Polytope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857730912AD0D0095BC33 /* Surface_Polytope.cpp */; }; + 81C857F00912AD0D0095BC33 /* Surface_Polytope.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857740912AD0D0095BC33 /* Surface_Polytope.h */; }; + 81C857F10912AD0D0095BC33 /* Surface_SweptSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857750912AD0D0095BC33 /* Surface_SweptSpline.cpp */; }; + 81C857F20912AD0D0095BC33 /* Surface_SweptSpline.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857760912AD0D0095BC33 /* Surface_SweptSpline.h */; }; + 81C857F30912AD0D0095BC33 /* TraceModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857770912AD0D0095BC33 /* TraceModel.cpp */; }; + 81C857F40912AD0D0095BC33 /* TraceModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857780912AD0D0095BC33 /* TraceModel.h */; }; + 81C857F50912AD0D0095BC33 /* Winding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857790912AD0D0095BC33 /* Winding.cpp */; }; + 81C857F60912AD0D0095BC33 /* Winding.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8577A0912AD0D0095BC33 /* Winding.h */; }; + 81C857F70912AD0D0095BC33 /* Winding2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8577B0912AD0D0095BC33 /* Winding2D.cpp */; }; + 81C857F80912AD0D0095BC33 /* Winding2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8577C0912AD0D0095BC33 /* Winding2D.h */; }; + 81C857FB0912AD0D0095BC33 /* CRC32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857800912AD0D0095BC33 /* CRC32.cpp */; }; + 81C857FC0912AD0D0095BC33 /* CRC32.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857810912AD0D0095BC33 /* CRC32.h */; }; + 81C858010912AD0D0095BC33 /* MD4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857860912AD0D0095BC33 /* MD4.cpp */; }; + 81C858020912AD0D0095BC33 /* MD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857870912AD0D0095BC33 /* MD4.h */; }; + 81C858030912AD0D0095BC33 /* MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857880912AD0D0095BC33 /* MD5.cpp */; }; + 81C858040912AD0D0095BC33 /* MD5.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857890912AD0D0095BC33 /* MD5.h */; }; + 81C858050912AD0D0095BC33 /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578A0912AD0D0095BC33 /* Heap.cpp */; }; + 81C858060912AD0D0095BC33 /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578B0912AD0D0095BC33 /* Heap.h */; }; + 81C858070912AD0D0095BC33 /* LangDict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578C0912AD0D0095BC33 /* LangDict.cpp */; }; + 81C858080912AD0D0095BC33 /* LangDict.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578D0912AD0D0095BC33 /* LangDict.h */; }; + 81C858090912AD0D0095BC33 /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578E0912AD0D0095BC33 /* Lexer.cpp */; }; + 81C8580A0912AD0D0095BC33 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578F0912AD0D0095BC33 /* Lexer.h */; }; + 81C8580B0912AD0D0095BC33 /* Lib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857900912AD0D0095BC33 /* Lib.cpp */; }; + 81C8580C0912AD0D0095BC33 /* Lib.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857910912AD0D0095BC33 /* Lib.h */; }; + 81C8580D0912AD0D0095BC33 /* MapFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857920912AD0D0095BC33 /* MapFile.cpp */; }; + 81C8580E0912AD0D0095BC33 /* MapFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857930912AD0D0095BC33 /* MapFile.h */; }; + 81C8580F0912AD0D0095BC33 /* Angles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857950912AD0D0095BC33 /* Angles.cpp */; }; + 81C858100912AD0D0095BC33 /* Polynomial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857960912AD0D0095BC33 /* Polynomial.cpp */; }; + 81C858110912AD0D0095BC33 /* Polynomial.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857970912AD0D0095BC33 /* Polynomial.h */; }; + 81C858120912AD0D0095BC33 /* Angles.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857980912AD0D0095BC33 /* Angles.h */; }; + 81C858130912AD0D0095BC33 /* Complex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857990912AD0D0095BC33 /* Complex.cpp */; }; + 81C858140912AD0D0095BC33 /* Complex.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579A0912AD0D0095BC33 /* Complex.h */; }; + 81C858150912AD0D0095BC33 /* Curve.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579B0912AD0D0095BC33 /* Curve.h */; }; + 81C858160912AD0D0095BC33 /* Extrapolate.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579C0912AD0D0095BC33 /* Extrapolate.h */; }; + 81C858170912AD0D0095BC33 /* Interpolate.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579D0912AD0D0095BC33 /* Interpolate.h */; }; + 81C858180912AD0D0095BC33 /* Lcp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8579E0912AD0D0095BC33 /* Lcp.cpp */; }; + 81C858190912AD0D0095BC33 /* Lcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579F0912AD0D0095BC33 /* Lcp.h */; }; + 81C8581A0912AD0D0095BC33 /* Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A00912AD0D0095BC33 /* Math.cpp */; }; + 81C8581B0912AD0D0095BC33 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A10912AD0D0095BC33 /* Matrix.cpp */; }; + 81C8581C0912AD0D0095BC33 /* Matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A20912AD0D0095BC33 /* Matrix.h */; }; + 81C8581D0912AD0D0095BC33 /* Ode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A30912AD0D0095BC33 /* Ode.cpp */; }; + 81C8581E0912AD0D0095BC33 /* Ode.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A40912AD0D0095BC33 /* Ode.h */; }; + 81C8581F0912AD0D0095BC33 /* Plane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A50912AD0D0095BC33 /* Plane.cpp */; }; + 81C858200912AD0D0095BC33 /* Plane.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A60912AD0D0095BC33 /* Plane.h */; }; + 81C858210912AD0D0095BC33 /* Pluecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A70912AD0D0095BC33 /* Pluecker.cpp */; }; + 81C858220912AD0D0095BC33 /* Pluecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A80912AD0D0095BC33 /* Pluecker.h */; }; + 81C858230912AD0D0095BC33 /* Quat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A90912AD0D0095BC33 /* Quat.cpp */; }; + 81C858240912AD0D0095BC33 /* Quat.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AA0912AD0D0095BC33 /* Quat.h */; }; + 81C858250912AD0D0095BC33 /* Random.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AB0912AD0D0095BC33 /* Random.h */; }; + 81C858260912AD0D0095BC33 /* Rotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857AC0912AD0D0095BC33 /* Rotation.cpp */; }; + 81C858270912AD0D0095BC33 /* Rotation.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AD0912AD0D0095BC33 /* Rotation.h */; }; + 81C858280912AD0D0095BC33 /* Simd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857AE0912AD0D0095BC33 /* Simd.cpp */; }; + 81C858290912AD0D0095BC33 /* Simd.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AF0912AD0D0095BC33 /* Simd.h */; }; + 81C8582A0912AD0D0095BC33 /* Simd_3DNow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B00912AD0D0095BC33 /* Simd_3DNow.cpp */; }; + 81C8582B0912AD0D0095BC33 /* Simd_3DNow.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B10912AD0D0095BC33 /* Simd_3DNow.h */; }; + 81C8582C0912AD0D0095BC33 /* Simd_AltiVec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B20912AD0D0095BC33 /* Simd_AltiVec.cpp */; }; + 81C8582D0912AD0D0095BC33 /* Simd_AltiVec.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B30912AD0D0095BC33 /* Simd_AltiVec.h */; }; + 81C8582E0912AD0D0095BC33 /* Simd_Generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B40912AD0D0095BC33 /* Simd_Generic.cpp */; }; + 81C8582F0912AD0D0095BC33 /* Simd_Generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B50912AD0D0095BC33 /* Simd_Generic.h */; }; + 81C858300912AD0D0095BC33 /* Simd_MMX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B60912AD0D0095BC33 /* Simd_MMX.cpp */; }; + 81C858310912AD0D0095BC33 /* Simd_MMX.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B70912AD0D0095BC33 /* Simd_MMX.h */; }; + 81C858320912AD0D0095BC33 /* Simd_SSE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B80912AD0D0095BC33 /* Simd_SSE.cpp */; }; + 81C858330912AD0D0095BC33 /* Simd_SSE.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B90912AD0D0095BC33 /* Simd_SSE.h */; }; + 81C858340912AD0D0095BC33 /* Simd_SSE2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BA0912AD0D0095BC33 /* Simd_SSE2.cpp */; }; + 81C858350912AD0D0095BC33 /* Simd_SSE2.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BB0912AD0D0095BC33 /* Simd_SSE2.h */; }; + 81C858360912AD0D0095BC33 /* Simd_SSE3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BC0912AD0D0095BC33 /* Simd_SSE3.cpp */; }; + 81C858370912AD0D0095BC33 /* Simd_SSE3.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BD0912AD0D0095BC33 /* Simd_SSE3.h */; }; + 81C858380912AD0D0095BC33 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BE0912AD0D0095BC33 /* Vector.cpp */; }; + 81C858390912AD0D0095BC33 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BF0912AD0D0095BC33 /* Vector.h */; }; + 81C8583A0912AD0D0095BC33 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C00912AD0D0095BC33 /* Parser.cpp */; }; + 81C8583B0912AD0D0095BC33 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C10912AD0D0095BC33 /* Parser.h */; }; + 81C8583C0912AD0D0095BC33 /* precompiled.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C20912AD0D0095BC33 /* precompiled.h */; }; + 81C8583D0912AD0D0095BC33 /* Str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C30912AD0D0095BC33 /* Str.cpp */; }; + 81C8583E0912AD0D0095BC33 /* Str.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C40912AD0D0095BC33 /* Str.h */; }; + 81C8583F0912AD0D0095BC33 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C50912AD0D0095BC33 /* Timer.cpp */; }; + 81C858400912AD0D0095BC33 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C60912AD0D0095BC33 /* Timer.h */; }; + 81C858410912AD0D0095BC33 /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C70912AD0D0095BC33 /* Token.cpp */; }; + 81C858420912AD0D0095BC33 /* Token.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C80912AD0D0095BC33 /* Token.h */; }; + 81C8584A0912AD510095BC33 /* BitMsg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857470912AD020095BC33 /* BitMsg.cpp */; }; + 81C8584B0912AD510095BC33 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8574A0912AD0D0095BC33 /* Base64.cpp */; }; + 81C8584C0912AD510095BC33 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574B0912AD0D0095BC33 /* Base64.h */; }; + 81C8584D0912AD510095BC33 /* BitMsg.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574C0912AD0D0095BC33 /* BitMsg.h */; }; + 81C8584E0912AD510095BC33 /* Bounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8574E0912AD0D0095BC33 /* Bounds.cpp */; }; + 81C8584F0912AD510095BC33 /* Bounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8574F0912AD0D0095BC33 /* Bounds.h */; }; + 81C858500912AD510095BC33 /* Box.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857500912AD0D0095BC33 /* Box.cpp */; }; + 81C858510912AD510095BC33 /* Box.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857510912AD0D0095BC33 /* Box.h */; }; + 81C858520912AD510095BC33 /* Frustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857520912AD0D0095BC33 /* Frustum.cpp */; }; + 81C858530912AD510095BC33 /* Frustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857530912AD0D0095BC33 /* Frustum.h */; }; + 81C858540912AD510095BC33 /* Sphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857540912AD0D0095BC33 /* Sphere.cpp */; }; + 81C858550912AD510095BC33 /* Sphere.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857550912AD0D0095BC33 /* Sphere.h */; }; + 81C858560912AD510095BC33 /* CmdArgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857560912AD0D0095BC33 /* CmdArgs.cpp */; }; + 81C858570912AD510095BC33 /* CmdArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857570912AD0D0095BC33 /* CmdArgs.h */; }; + 81C858580912AD510095BC33 /* BinSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857590912AD0D0095BC33 /* BinSearch.h */; }; + 81C858590912AD510095BC33 /* BTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575A0912AD0D0095BC33 /* BTree.h */; }; + 81C8585A0912AD510095BC33 /* HashIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8575B0912AD0D0095BC33 /* HashIndex.cpp */; }; + 81C8585B0912AD510095BC33 /* HashIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575C0912AD0D0095BC33 /* HashIndex.h */; }; + 81C8585C0912AD510095BC33 /* HashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575D0912AD0D0095BC33 /* HashTable.h */; }; + 81C8585D0912AD510095BC33 /* Hierarchy.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575E0912AD0D0095BC33 /* Hierarchy.h */; }; + 81C8585E0912AD510095BC33 /* LinkList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8575F0912AD0D0095BC33 /* LinkList.h */; }; + 81C8585F0912AD510095BC33 /* List.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857600912AD0D0095BC33 /* List.h */; }; + 81C858600912AD510095BC33 /* PlaneSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857610912AD0D0095BC33 /* PlaneSet.h */; }; + 81C858610912AD510095BC33 /* Queue.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857620912AD0D0095BC33 /* Queue.h */; }; + 81C858620912AD510095BC33 /* Stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857630912AD0D0095BC33 /* Stack.h */; }; + 81C858630912AD510095BC33 /* StaticList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857640912AD0D0095BC33 /* StaticList.h */; }; + 81C858640912AD510095BC33 /* StrList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857650912AD0D0095BC33 /* StrList.h */; }; + 81C858650912AD510095BC33 /* StrPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857660912AD0D0095BC33 /* StrPool.h */; }; + 81C858660912AD510095BC33 /* VectorSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857670912AD0D0095BC33 /* VectorSet.h */; }; + 81C858670912AD510095BC33 /* Dict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857680912AD0D0095BC33 /* Dict.cpp */; }; + 81C858680912AD510095BC33 /* Dict.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857690912AD0D0095BC33 /* Dict.h */; }; + 81C858690912AD510095BC33 /* DrawVert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576B0912AD0D0095BC33 /* DrawVert.cpp */; }; + 81C8586A0912AD510095BC33 /* DrawVert.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8576C0912AD0D0095BC33 /* DrawVert.h */; }; + 81C8586B0912AD510095BC33 /* JointTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576D0912AD0D0095BC33 /* JointTransform.cpp */; }; + 81C8586C0912AD510095BC33 /* JointTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8576E0912AD0D0095BC33 /* JointTransform.h */; }; + 81C8586D0912AD510095BC33 /* Surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8576F0912AD0D0095BC33 /* Surface.cpp */; }; + 81C8586E0912AD510095BC33 /* Surface.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857700912AD0D0095BC33 /* Surface.h */; }; + 81C8586F0912AD510095BC33 /* Surface_Patch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857710912AD0D0095BC33 /* Surface_Patch.cpp */; }; + 81C858700912AD510095BC33 /* Surface_Patch.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857720912AD0D0095BC33 /* Surface_Patch.h */; }; + 81C858710912AD510095BC33 /* Surface_Polytope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857730912AD0D0095BC33 /* Surface_Polytope.cpp */; }; + 81C858720912AD510095BC33 /* Surface_Polytope.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857740912AD0D0095BC33 /* Surface_Polytope.h */; }; + 81C858730912AD510095BC33 /* Surface_SweptSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857750912AD0D0095BC33 /* Surface_SweptSpline.cpp */; }; + 81C858740912AD510095BC33 /* Surface_SweptSpline.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857760912AD0D0095BC33 /* Surface_SweptSpline.h */; }; + 81C858750912AD510095BC33 /* TraceModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857770912AD0D0095BC33 /* TraceModel.cpp */; }; + 81C858760912AD510095BC33 /* TraceModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857780912AD0D0095BC33 /* TraceModel.h */; }; + 81C858770912AD510095BC33 /* Winding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857790912AD0D0095BC33 /* Winding.cpp */; }; + 81C858780912AD510095BC33 /* Winding.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8577A0912AD0D0095BC33 /* Winding.h */; }; + 81C858790912AD510095BC33 /* Winding2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8577B0912AD0D0095BC33 /* Winding2D.cpp */; }; + 81C8587A0912AD510095BC33 /* Winding2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8577C0912AD0D0095BC33 /* Winding2D.h */; }; + 81C8587D0912AD510095BC33 /* CRC32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857800912AD0D0095BC33 /* CRC32.cpp */; }; + 81C8587E0912AD510095BC33 /* CRC32.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857810912AD0D0095BC33 /* CRC32.h */; }; + 81C858830912AD510095BC33 /* MD4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857860912AD0D0095BC33 /* MD4.cpp */; }; + 81C858840912AD510095BC33 /* MD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857870912AD0D0095BC33 /* MD4.h */; }; + 81C858850912AD510095BC33 /* MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857880912AD0D0095BC33 /* MD5.cpp */; }; + 81C858860912AD510095BC33 /* MD5.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857890912AD0D0095BC33 /* MD5.h */; }; + 81C858870912AD510095BC33 /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578A0912AD0D0095BC33 /* Heap.cpp */; }; + 81C858880912AD510095BC33 /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578B0912AD0D0095BC33 /* Heap.h */; }; + 81C858890912AD510095BC33 /* LangDict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578C0912AD0D0095BC33 /* LangDict.cpp */; }; + 81C8588A0912AD510095BC33 /* LangDict.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578D0912AD0D0095BC33 /* LangDict.h */; }; + 81C8588B0912AD510095BC33 /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8578E0912AD0D0095BC33 /* Lexer.cpp */; }; + 81C8588C0912AD510095BC33 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8578F0912AD0D0095BC33 /* Lexer.h */; }; + 81C8588D0912AD510095BC33 /* Lib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857900912AD0D0095BC33 /* Lib.cpp */; }; + 81C8588E0912AD510095BC33 /* Lib.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857910912AD0D0095BC33 /* Lib.h */; }; + 81C8588F0912AD510095BC33 /* MapFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857920912AD0D0095BC33 /* MapFile.cpp */; }; + 81C858900912AD510095BC33 /* MapFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857930912AD0D0095BC33 /* MapFile.h */; }; + 81C858910912AD510095BC33 /* Angles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857950912AD0D0095BC33 /* Angles.cpp */; }; + 81C858920912AD510095BC33 /* Polynomial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857960912AD0D0095BC33 /* Polynomial.cpp */; }; + 81C858930912AD510095BC33 /* Polynomial.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857970912AD0D0095BC33 /* Polynomial.h */; }; + 81C858940912AD510095BC33 /* Angles.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857980912AD0D0095BC33 /* Angles.h */; }; + 81C858950912AD510095BC33 /* Complex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857990912AD0D0095BC33 /* Complex.cpp */; }; + 81C858960912AD510095BC33 /* Complex.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579A0912AD0D0095BC33 /* Complex.h */; }; + 81C858970912AD510095BC33 /* Curve.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579B0912AD0D0095BC33 /* Curve.h */; }; + 81C858980912AD510095BC33 /* Extrapolate.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579C0912AD0D0095BC33 /* Extrapolate.h */; }; + 81C858990912AD510095BC33 /* Interpolate.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579D0912AD0D0095BC33 /* Interpolate.h */; }; + 81C8589A0912AD510095BC33 /* Lcp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C8579E0912AD0D0095BC33 /* Lcp.cpp */; }; + 81C8589B0912AD510095BC33 /* Lcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8579F0912AD0D0095BC33 /* Lcp.h */; }; + 81C8589C0912AD510095BC33 /* Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A00912AD0D0095BC33 /* Math.cpp */; }; + 81C8589D0912AD510095BC33 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A10912AD0D0095BC33 /* Matrix.cpp */; }; + 81C8589E0912AD510095BC33 /* Matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A20912AD0D0095BC33 /* Matrix.h */; }; + 81C8589F0912AD510095BC33 /* Ode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A30912AD0D0095BC33 /* Ode.cpp */; }; + 81C858A00912AD510095BC33 /* Ode.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A40912AD0D0095BC33 /* Ode.h */; }; + 81C858A10912AD510095BC33 /* Plane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A50912AD0D0095BC33 /* Plane.cpp */; }; + 81C858A20912AD510095BC33 /* Plane.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A60912AD0D0095BC33 /* Plane.h */; }; + 81C858A30912AD510095BC33 /* Pluecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A70912AD0D0095BC33 /* Pluecker.cpp */; }; + 81C858A40912AD510095BC33 /* Pluecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857A80912AD0D0095BC33 /* Pluecker.h */; }; + 81C858A50912AD510095BC33 /* Quat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857A90912AD0D0095BC33 /* Quat.cpp */; }; + 81C858A60912AD510095BC33 /* Quat.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AA0912AD0D0095BC33 /* Quat.h */; }; + 81C858A70912AD510095BC33 /* Random.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AB0912AD0D0095BC33 /* Random.h */; }; + 81C858A80912AD510095BC33 /* Rotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857AC0912AD0D0095BC33 /* Rotation.cpp */; }; + 81C858A90912AD510095BC33 /* Rotation.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AD0912AD0D0095BC33 /* Rotation.h */; }; + 81C858AA0912AD510095BC33 /* Simd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857AE0912AD0D0095BC33 /* Simd.cpp */; }; + 81C858AB0912AD510095BC33 /* Simd.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857AF0912AD0D0095BC33 /* Simd.h */; }; + 81C858AC0912AD510095BC33 /* Simd_3DNow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B00912AD0D0095BC33 /* Simd_3DNow.cpp */; }; + 81C858AD0912AD510095BC33 /* Simd_3DNow.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B10912AD0D0095BC33 /* Simd_3DNow.h */; }; + 81C858AE0912AD510095BC33 /* Simd_AltiVec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B20912AD0D0095BC33 /* Simd_AltiVec.cpp */; }; + 81C858AF0912AD510095BC33 /* Simd_AltiVec.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B30912AD0D0095BC33 /* Simd_AltiVec.h */; }; + 81C858B00912AD510095BC33 /* Simd_Generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B40912AD0D0095BC33 /* Simd_Generic.cpp */; }; + 81C858B10912AD510095BC33 /* Simd_Generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B50912AD0D0095BC33 /* Simd_Generic.h */; }; + 81C858B20912AD510095BC33 /* Simd_MMX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B60912AD0D0095BC33 /* Simd_MMX.cpp */; }; + 81C858B30912AD510095BC33 /* Simd_MMX.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B70912AD0D0095BC33 /* Simd_MMX.h */; }; + 81C858B40912AD510095BC33 /* Simd_SSE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857B80912AD0D0095BC33 /* Simd_SSE.cpp */; }; + 81C858B50912AD510095BC33 /* Simd_SSE.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857B90912AD0D0095BC33 /* Simd_SSE.h */; }; + 81C858B60912AD510095BC33 /* Simd_SSE2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BA0912AD0D0095BC33 /* Simd_SSE2.cpp */; }; + 81C858B70912AD510095BC33 /* Simd_SSE2.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BB0912AD0D0095BC33 /* Simd_SSE2.h */; }; + 81C858B80912AD510095BC33 /* Simd_SSE3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BC0912AD0D0095BC33 /* Simd_SSE3.cpp */; }; + 81C858B90912AD510095BC33 /* Simd_SSE3.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BD0912AD0D0095BC33 /* Simd_SSE3.h */; }; + 81C858BA0912AD510095BC33 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857BE0912AD0D0095BC33 /* Vector.cpp */; }; + 81C858BB0912AD510095BC33 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857BF0912AD0D0095BC33 /* Vector.h */; }; + 81C858BC0912AD510095BC33 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C00912AD0D0095BC33 /* Parser.cpp */; }; + 81C858BD0912AD510095BC33 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C10912AD0D0095BC33 /* Parser.h */; }; + 81C858BE0912AD510095BC33 /* precompiled.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C20912AD0D0095BC33 /* precompiled.h */; }; + 81C858BF0912AD510095BC33 /* Str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C30912AD0D0095BC33 /* Str.cpp */; }; + 81C858C00912AD510095BC33 /* Str.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C40912AD0D0095BC33 /* Str.h */; }; + 81C858C10912AD510095BC33 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C50912AD0D0095BC33 /* Timer.cpp */; }; + 81C858C20912AD510095BC33 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C60912AD0D0095BC33 /* Timer.h */; }; + 81C858C30912AD510095BC33 /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81C857C70912AD0D0095BC33 /* Token.cpp */; }; + 81C858C40912AD510095BC33 /* Token.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C857C80912AD0D0095BC33 /* Token.h */; }; + 81C858D90912ADD80095BC33 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C858D80912ADD80095BC33 /* OpenGL.framework */; }; + 81C858DA0912ADD80095BC33 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C858D80912ADD80095BC33 /* OpenGL.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3A1767C6149346E90077AB23 /* Frustum_gcc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Frustum_gcc.cpp; sourceTree = ""; }; + 81C857470912AD020095BC33 /* BitMsg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BitMsg.cpp; path = ../../idlib/BitMsg.cpp; sourceTree = SOURCE_ROOT; }; + 81C8574A0912AD0D0095BC33 /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Base64.cpp; path = ../../idlib/Base64.cpp; sourceTree = SOURCE_ROOT; }; + 81C8574B0912AD0D0095BC33 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Base64.h; path = ../../idlib/Base64.h; sourceTree = SOURCE_ROOT; }; + 81C8574C0912AD0D0095BC33 /* BitMsg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = BitMsg.h; path = ../../idlib/BitMsg.h; sourceTree = SOURCE_ROOT; }; + 81C8574E0912AD0D0095BC33 /* Bounds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Bounds.cpp; sourceTree = ""; }; + 81C8574F0912AD0D0095BC33 /* Bounds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Bounds.h; sourceTree = ""; }; + 81C857500912AD0D0095BC33 /* Box.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Box.cpp; sourceTree = ""; }; + 81C857510912AD0D0095BC33 /* Box.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Box.h; sourceTree = ""; }; + 81C857520912AD0D0095BC33 /* Frustum.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Frustum.cpp; sourceTree = ""; }; + 81C857530912AD0D0095BC33 /* Frustum.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Frustum.h; sourceTree = ""; }; + 81C857540912AD0D0095BC33 /* Sphere.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Sphere.cpp; sourceTree = ""; }; + 81C857550912AD0D0095BC33 /* Sphere.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Sphere.h; sourceTree = ""; }; + 81C857560912AD0D0095BC33 /* CmdArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CmdArgs.cpp; path = ../../idlib/CmdArgs.cpp; sourceTree = SOURCE_ROOT; }; + 81C857570912AD0D0095BC33 /* CmdArgs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CmdArgs.h; path = ../../idlib/CmdArgs.h; sourceTree = SOURCE_ROOT; }; + 81C857590912AD0D0095BC33 /* BinSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BinSearch.h; sourceTree = ""; }; + 81C8575A0912AD0D0095BC33 /* BTree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BTree.h; sourceTree = ""; }; + 81C8575B0912AD0D0095BC33 /* HashIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HashIndex.cpp; sourceTree = ""; }; + 81C8575C0912AD0D0095BC33 /* HashIndex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HashIndex.h; sourceTree = ""; }; + 81C8575D0912AD0D0095BC33 /* HashTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HashTable.h; sourceTree = ""; }; + 81C8575E0912AD0D0095BC33 /* Hierarchy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Hierarchy.h; sourceTree = ""; }; + 81C8575F0912AD0D0095BC33 /* LinkList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LinkList.h; sourceTree = ""; }; + 81C857600912AD0D0095BC33 /* List.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = List.h; sourceTree = ""; }; + 81C857610912AD0D0095BC33 /* PlaneSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlaneSet.h; sourceTree = ""; }; + 81C857620912AD0D0095BC33 /* Queue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Queue.h; sourceTree = ""; }; + 81C857630912AD0D0095BC33 /* Stack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Stack.h; sourceTree = ""; }; + 81C857640912AD0D0095BC33 /* StaticList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StaticList.h; sourceTree = ""; }; + 81C857650912AD0D0095BC33 /* StrList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StrList.h; sourceTree = ""; }; + 81C857660912AD0D0095BC33 /* StrPool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StrPool.h; sourceTree = ""; }; + 81C857670912AD0D0095BC33 /* VectorSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VectorSet.h; sourceTree = ""; }; + 81C857680912AD0D0095BC33 /* Dict.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Dict.cpp; path = ../../idlib/Dict.cpp; sourceTree = SOURCE_ROOT; }; + 81C857690912AD0D0095BC33 /* Dict.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Dict.h; path = ../../idlib/Dict.h; sourceTree = SOURCE_ROOT; }; + 81C8576B0912AD0D0095BC33 /* DrawVert.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DrawVert.cpp; sourceTree = ""; }; + 81C8576C0912AD0D0095BC33 /* DrawVert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DrawVert.h; sourceTree = ""; }; + 81C8576D0912AD0D0095BC33 /* JointTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JointTransform.cpp; sourceTree = ""; }; + 81C8576E0912AD0D0095BC33 /* JointTransform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JointTransform.h; sourceTree = ""; }; + 81C8576F0912AD0D0095BC33 /* Surface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Surface.cpp; sourceTree = ""; }; + 81C857700912AD0D0095BC33 /* Surface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Surface.h; sourceTree = ""; }; + 81C857710912AD0D0095BC33 /* Surface_Patch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Surface_Patch.cpp; sourceTree = ""; }; + 81C857720912AD0D0095BC33 /* Surface_Patch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Surface_Patch.h; sourceTree = ""; }; + 81C857730912AD0D0095BC33 /* Surface_Polytope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Surface_Polytope.cpp; sourceTree = ""; }; + 81C857740912AD0D0095BC33 /* Surface_Polytope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Surface_Polytope.h; sourceTree = ""; }; + 81C857750912AD0D0095BC33 /* Surface_SweptSpline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Surface_SweptSpline.cpp; sourceTree = ""; }; + 81C857760912AD0D0095BC33 /* Surface_SweptSpline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Surface_SweptSpline.h; sourceTree = ""; }; + 81C857770912AD0D0095BC33 /* TraceModel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TraceModel.cpp; sourceTree = ""; }; + 81C857780912AD0D0095BC33 /* TraceModel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TraceModel.h; sourceTree = ""; }; + 81C857790912AD0D0095BC33 /* Winding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Winding.cpp; sourceTree = ""; }; + 81C8577A0912AD0D0095BC33 /* Winding.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Winding.h; sourceTree = ""; }; + 81C8577B0912AD0D0095BC33 /* Winding2D.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Winding2D.cpp; sourceTree = ""; }; + 81C8577C0912AD0D0095BC33 /* Winding2D.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Winding2D.h; sourceTree = ""; }; + 81C857800912AD0D0095BC33 /* CRC32.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CRC32.cpp; sourceTree = ""; }; + 81C857810912AD0D0095BC33 /* CRC32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CRC32.h; sourceTree = ""; }; + 81C857860912AD0D0095BC33 /* MD4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MD4.cpp; sourceTree = ""; }; + 81C857870912AD0D0095BC33 /* MD4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MD4.h; sourceTree = ""; }; + 81C857880912AD0D0095BC33 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MD5.cpp; sourceTree = ""; }; + 81C857890912AD0D0095BC33 /* MD5.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MD5.h; sourceTree = ""; }; + 81C8578A0912AD0D0095BC33 /* Heap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Heap.cpp; path = ../../idlib/Heap.cpp; sourceTree = SOURCE_ROOT; }; + 81C8578B0912AD0D0095BC33 /* Heap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Heap.h; path = ../../idlib/Heap.h; sourceTree = SOURCE_ROOT; }; + 81C8578C0912AD0D0095BC33 /* LangDict.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LangDict.cpp; path = ../../idlib/LangDict.cpp; sourceTree = SOURCE_ROOT; }; + 81C8578D0912AD0D0095BC33 /* LangDict.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LangDict.h; path = ../../idlib/LangDict.h; sourceTree = SOURCE_ROOT; }; + 81C8578E0912AD0D0095BC33 /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Lexer.cpp; path = ../../idlib/Lexer.cpp; sourceTree = SOURCE_ROOT; }; + 81C8578F0912AD0D0095BC33 /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Lexer.h; path = ../../idlib/Lexer.h; sourceTree = SOURCE_ROOT; }; + 81C857900912AD0D0095BC33 /* Lib.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Lib.cpp; path = ../../idlib/Lib.cpp; sourceTree = SOURCE_ROOT; }; + 81C857910912AD0D0095BC33 /* Lib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Lib.h; path = ../../idlib/Lib.h; sourceTree = SOURCE_ROOT; }; + 81C857920912AD0D0095BC33 /* MapFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MapFile.cpp; path = ../../idlib/MapFile.cpp; sourceTree = SOURCE_ROOT; }; + 81C857930912AD0D0095BC33 /* MapFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MapFile.h; path = ../../idlib/MapFile.h; sourceTree = SOURCE_ROOT; }; + 81C857950912AD0D0095BC33 /* Angles.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Angles.cpp; sourceTree = ""; }; + 81C857960912AD0D0095BC33 /* Polynomial.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Polynomial.cpp; sourceTree = ""; }; + 81C857970912AD0D0095BC33 /* Polynomial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Polynomial.h; sourceTree = ""; }; + 81C857980912AD0D0095BC33 /* Angles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Angles.h; sourceTree = ""; }; + 81C857990912AD0D0095BC33 /* Complex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Complex.cpp; sourceTree = ""; }; + 81C8579A0912AD0D0095BC33 /* Complex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Complex.h; sourceTree = ""; }; + 81C8579B0912AD0D0095BC33 /* Curve.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Curve.h; sourceTree = ""; }; + 81C8579C0912AD0D0095BC33 /* Extrapolate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Extrapolate.h; sourceTree = ""; }; + 81C8579D0912AD0D0095BC33 /* Interpolate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Interpolate.h; sourceTree = ""; }; + 81C8579E0912AD0D0095BC33 /* Lcp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Lcp.cpp; sourceTree = ""; }; + 81C8579F0912AD0D0095BC33 /* Lcp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Lcp.h; sourceTree = ""; }; + 81C857A00912AD0D0095BC33 /* Math.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Math.cpp; sourceTree = ""; }; + 81C857A10912AD0D0095BC33 /* Matrix.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Matrix.cpp; sourceTree = ""; }; + 81C857A20912AD0D0095BC33 /* Matrix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Matrix.h; sourceTree = ""; }; + 81C857A30912AD0D0095BC33 /* Ode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Ode.cpp; sourceTree = ""; }; + 81C857A40912AD0D0095BC33 /* Ode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Ode.h; sourceTree = ""; }; + 81C857A50912AD0D0095BC33 /* Plane.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Plane.cpp; sourceTree = ""; }; + 81C857A60912AD0D0095BC33 /* Plane.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plane.h; sourceTree = ""; }; + 81C857A70912AD0D0095BC33 /* Pluecker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Pluecker.cpp; sourceTree = ""; }; + 81C857A80912AD0D0095BC33 /* Pluecker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Pluecker.h; sourceTree = ""; }; + 81C857A90912AD0D0095BC33 /* Quat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Quat.cpp; sourceTree = ""; }; + 81C857AA0912AD0D0095BC33 /* Quat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Quat.h; sourceTree = ""; }; + 81C857AB0912AD0D0095BC33 /* Random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Random.h; sourceTree = ""; }; + 81C857AC0912AD0D0095BC33 /* Rotation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Rotation.cpp; sourceTree = ""; }; + 81C857AD0912AD0D0095BC33 /* Rotation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Rotation.h; sourceTree = ""; }; + 81C857AE0912AD0D0095BC33 /* Simd.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd.cpp; sourceTree = ""; }; + 81C857AF0912AD0D0095BC33 /* Simd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd.h; sourceTree = ""; }; + 81C857B00912AD0D0095BC33 /* Simd_3DNow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_3DNow.cpp; sourceTree = ""; }; + 81C857B10912AD0D0095BC33 /* Simd_3DNow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_3DNow.h; sourceTree = ""; }; + 81C857B20912AD0D0095BC33 /* Simd_AltiVec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_AltiVec.cpp; sourceTree = ""; }; + 81C857B30912AD0D0095BC33 /* Simd_AltiVec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_AltiVec.h; sourceTree = ""; }; + 81C857B40912AD0D0095BC33 /* Simd_Generic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_Generic.cpp; sourceTree = ""; }; + 81C857B50912AD0D0095BC33 /* Simd_Generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_Generic.h; sourceTree = ""; }; + 81C857B60912AD0D0095BC33 /* Simd_MMX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_MMX.cpp; sourceTree = ""; }; + 81C857B70912AD0D0095BC33 /* Simd_MMX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_MMX.h; sourceTree = ""; }; + 81C857B80912AD0D0095BC33 /* Simd_SSE.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_SSE.cpp; sourceTree = ""; }; + 81C857B90912AD0D0095BC33 /* Simd_SSE.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_SSE.h; sourceTree = ""; }; + 81C857BA0912AD0D0095BC33 /* Simd_SSE2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_SSE2.cpp; sourceTree = ""; }; + 81C857BB0912AD0D0095BC33 /* Simd_SSE2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_SSE2.h; sourceTree = ""; }; + 81C857BC0912AD0D0095BC33 /* Simd_SSE3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Simd_SSE3.cpp; sourceTree = ""; }; + 81C857BD0912AD0D0095BC33 /* Simd_SSE3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Simd_SSE3.h; sourceTree = ""; }; + 81C857BE0912AD0D0095BC33 /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = ""; }; + 81C857BF0912AD0D0095BC33 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; + 81C857C00912AD0D0095BC33 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = ../../idlib/Parser.cpp; sourceTree = SOURCE_ROOT; }; + 81C857C10912AD0D0095BC33 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = ../../idlib/Parser.h; sourceTree = SOURCE_ROOT; }; + 81C857C20912AD0D0095BC33 /* precompiled.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = precompiled.h; path = ../../idlib/precompiled.h; sourceTree = SOURCE_ROOT; }; + 81C857C30912AD0D0095BC33 /* Str.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Str.cpp; path = ../../idlib/Str.cpp; sourceTree = SOURCE_ROOT; }; + 81C857C40912AD0D0095BC33 /* Str.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Str.h; path = ../../idlib/Str.h; sourceTree = SOURCE_ROOT; }; + 81C857C50912AD0D0095BC33 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cpp; path = ../../idlib/Timer.cpp; sourceTree = SOURCE_ROOT; }; + 81C857C60912AD0D0095BC33 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Timer.h; path = ../../idlib/Timer.h; sourceTree = SOURCE_ROOT; }; + 81C857C70912AD0D0095BC33 /* Token.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Token.cpp; path = ../../idlib/Token.cpp; sourceTree = SOURCE_ROOT; }; + 81C857C80912AD0D0095BC33 /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Token.h; path = ../../idlib/Token.h; sourceTree = SOURCE_ROOT; }; + 81C858490912AD370095BC33 /* libidlib_nopic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libidlib_nopic.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 81C858D80912ADD80095BC33 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + D2AAC046055464E500DB518D /* libidlib_pic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libidlib_pic.a; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 81C858470912AD370095BC33 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C858DA0912ADD80095BC33 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D289987405E68DCB004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C858D90912ADD80095BC33 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* idlib */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + 81C858D80912ADD80095BC33 /* OpenGL.framework */, + ); + name = idlib; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 81C857470912AD020095BC33 /* BitMsg.cpp */, + 81C8574A0912AD0D0095BC33 /* Base64.cpp */, + 81C8574B0912AD0D0095BC33 /* Base64.h */, + 81C8574C0912AD0D0095BC33 /* BitMsg.h */, + 81C8574D0912AD0D0095BC33 /* bv */, + 81C857560912AD0D0095BC33 /* CmdArgs.cpp */, + 81C857570912AD0D0095BC33 /* CmdArgs.h */, + 81C857580912AD0D0095BC33 /* containers */, + 81C857680912AD0D0095BC33 /* Dict.cpp */, + 81C857690912AD0D0095BC33 /* Dict.h */, + 81C8576A0912AD0D0095BC33 /* geometry */, + 81C8577D0912AD0D0095BC33 /* hashing */, + 81C8578A0912AD0D0095BC33 /* Heap.cpp */, + 81C8578B0912AD0D0095BC33 /* Heap.h */, + 81C8578C0912AD0D0095BC33 /* LangDict.cpp */, + 81C8578D0912AD0D0095BC33 /* LangDict.h */, + 81C8578E0912AD0D0095BC33 /* Lexer.cpp */, + 81C8578F0912AD0D0095BC33 /* Lexer.h */, + 81C857900912AD0D0095BC33 /* Lib.cpp */, + 81C857910912AD0D0095BC33 /* Lib.h */, + 81C857920912AD0D0095BC33 /* MapFile.cpp */, + 81C857930912AD0D0095BC33 /* MapFile.h */, + 81C857940912AD0D0095BC33 /* math */, + 81C857C00912AD0D0095BC33 /* Parser.cpp */, + 81C857C10912AD0D0095BC33 /* Parser.h */, + 81C857C20912AD0D0095BC33 /* precompiled.h */, + 81C857C30912AD0D0095BC33 /* Str.cpp */, + 81C857C40912AD0D0095BC33 /* Str.h */, + 81C857C50912AD0D0095BC33 /* Timer.cpp */, + 81C857C60912AD0D0095BC33 /* Timer.h */, + 81C857C70912AD0D0095BC33 /* Token.cpp */, + 81C857C80912AD0D0095BC33 /* Token.h */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC046055464E500DB518D /* libidlib_pic.a */, + 81C858490912AD370095BC33 /* libidlib_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 81C8574D0912AD0D0095BC33 /* bv */ = { + isa = PBXGroup; + children = ( + 3A1767C6149346E90077AB23 /* Frustum_gcc.cpp */, + 81C8574E0912AD0D0095BC33 /* Bounds.cpp */, + 81C8574F0912AD0D0095BC33 /* Bounds.h */, + 81C857500912AD0D0095BC33 /* Box.cpp */, + 81C857510912AD0D0095BC33 /* Box.h */, + 81C857520912AD0D0095BC33 /* Frustum.cpp */, + 81C857530912AD0D0095BC33 /* Frustum.h */, + 81C857540912AD0D0095BC33 /* Sphere.cpp */, + 81C857550912AD0D0095BC33 /* Sphere.h */, + ); + name = bv; + path = ../../idlib/bv; + sourceTree = SOURCE_ROOT; + }; + 81C857580912AD0D0095BC33 /* containers */ = { + isa = PBXGroup; + children = ( + 81C857590912AD0D0095BC33 /* BinSearch.h */, + 81C8575A0912AD0D0095BC33 /* BTree.h */, + 81C8575B0912AD0D0095BC33 /* HashIndex.cpp */, + 81C8575C0912AD0D0095BC33 /* HashIndex.h */, + 81C8575D0912AD0D0095BC33 /* HashTable.h */, + 81C8575E0912AD0D0095BC33 /* Hierarchy.h */, + 81C8575F0912AD0D0095BC33 /* LinkList.h */, + 81C857600912AD0D0095BC33 /* List.h */, + 81C857610912AD0D0095BC33 /* PlaneSet.h */, + 81C857620912AD0D0095BC33 /* Queue.h */, + 81C857630912AD0D0095BC33 /* Stack.h */, + 81C857640912AD0D0095BC33 /* StaticList.h */, + 81C857650912AD0D0095BC33 /* StrList.h */, + 81C857660912AD0D0095BC33 /* StrPool.h */, + 81C857670912AD0D0095BC33 /* VectorSet.h */, + ); + name = containers; + path = ../../idlib/containers; + sourceTree = SOURCE_ROOT; + }; + 81C8576A0912AD0D0095BC33 /* geometry */ = { + isa = PBXGroup; + children = ( + 81C8576B0912AD0D0095BC33 /* DrawVert.cpp */, + 81C8576C0912AD0D0095BC33 /* DrawVert.h */, + 81C8576D0912AD0D0095BC33 /* JointTransform.cpp */, + 81C8576E0912AD0D0095BC33 /* JointTransform.h */, + 81C8576F0912AD0D0095BC33 /* Surface.cpp */, + 81C857700912AD0D0095BC33 /* Surface.h */, + 81C857710912AD0D0095BC33 /* Surface_Patch.cpp */, + 81C857720912AD0D0095BC33 /* Surface_Patch.h */, + 81C857730912AD0D0095BC33 /* Surface_Polytope.cpp */, + 81C857740912AD0D0095BC33 /* Surface_Polytope.h */, + 81C857750912AD0D0095BC33 /* Surface_SweptSpline.cpp */, + 81C857760912AD0D0095BC33 /* Surface_SweptSpline.h */, + 81C857770912AD0D0095BC33 /* TraceModel.cpp */, + 81C857780912AD0D0095BC33 /* TraceModel.h */, + 81C857790912AD0D0095BC33 /* Winding.cpp */, + 81C8577A0912AD0D0095BC33 /* Winding.h */, + 81C8577B0912AD0D0095BC33 /* Winding2D.cpp */, + 81C8577C0912AD0D0095BC33 /* Winding2D.h */, + ); + name = geometry; + path = ../../idlib/geometry; + sourceTree = SOURCE_ROOT; + }; + 81C8577D0912AD0D0095BC33 /* hashing */ = { + isa = PBXGroup; + children = ( + 81C857800912AD0D0095BC33 /* CRC32.cpp */, + 81C857810912AD0D0095BC33 /* CRC32.h */, + 81C857860912AD0D0095BC33 /* MD4.cpp */, + 81C857870912AD0D0095BC33 /* MD4.h */, + 81C857880912AD0D0095BC33 /* MD5.cpp */, + 81C857890912AD0D0095BC33 /* MD5.h */, + ); + name = hashing; + path = ../../idlib/hashing; + sourceTree = SOURCE_ROOT; + }; + 81C857940912AD0D0095BC33 /* math */ = { + isa = PBXGroup; + children = ( + 81C857950912AD0D0095BC33 /* Angles.cpp */, + 81C857960912AD0D0095BC33 /* Polynomial.cpp */, + 81C857970912AD0D0095BC33 /* Polynomial.h */, + 81C857980912AD0D0095BC33 /* Angles.h */, + 81C857990912AD0D0095BC33 /* Complex.cpp */, + 81C8579A0912AD0D0095BC33 /* Complex.h */, + 81C8579B0912AD0D0095BC33 /* Curve.h */, + 81C8579C0912AD0D0095BC33 /* Extrapolate.h */, + 81C8579D0912AD0D0095BC33 /* Interpolate.h */, + 81C8579E0912AD0D0095BC33 /* Lcp.cpp */, + 81C8579F0912AD0D0095BC33 /* Lcp.h */, + 81C857A00912AD0D0095BC33 /* Math.cpp */, + 81C857A10912AD0D0095BC33 /* Matrix.cpp */, + 81C857A20912AD0D0095BC33 /* Matrix.h */, + 81C857A30912AD0D0095BC33 /* Ode.cpp */, + 81C857A40912AD0D0095BC33 /* Ode.h */, + 81C857A50912AD0D0095BC33 /* Plane.cpp */, + 81C857A60912AD0D0095BC33 /* Plane.h */, + 81C857A70912AD0D0095BC33 /* Pluecker.cpp */, + 81C857A80912AD0D0095BC33 /* Pluecker.h */, + 81C857A90912AD0D0095BC33 /* Quat.cpp */, + 81C857AA0912AD0D0095BC33 /* Quat.h */, + 81C857AB0912AD0D0095BC33 /* Random.h */, + 81C857AC0912AD0D0095BC33 /* Rotation.cpp */, + 81C857AD0912AD0D0095BC33 /* Rotation.h */, + 81C857AE0912AD0D0095BC33 /* Simd.cpp */, + 81C857AF0912AD0D0095BC33 /* Simd.h */, + 81C857B00912AD0D0095BC33 /* Simd_3DNow.cpp */, + 81C857B10912AD0D0095BC33 /* Simd_3DNow.h */, + 81C857B20912AD0D0095BC33 /* Simd_AltiVec.cpp */, + 81C857B30912AD0D0095BC33 /* Simd_AltiVec.h */, + 81C857B40912AD0D0095BC33 /* Simd_Generic.cpp */, + 81C857B50912AD0D0095BC33 /* Simd_Generic.h */, + 81C857B60912AD0D0095BC33 /* Simd_MMX.cpp */, + 81C857B70912AD0D0095BC33 /* Simd_MMX.h */, + 81C857B80912AD0D0095BC33 /* Simd_SSE.cpp */, + 81C857B90912AD0D0095BC33 /* Simd_SSE.h */, + 81C857BA0912AD0D0095BC33 /* Simd_SSE2.cpp */, + 81C857BB0912AD0D0095BC33 /* Simd_SSE2.h */, + 81C857BC0912AD0D0095BC33 /* Simd_SSE3.cpp */, + 81C857BD0912AD0D0095BC33 /* Simd_SSE3.h */, + 81C857BE0912AD0D0095BC33 /* Vector.cpp */, + 81C857BF0912AD0D0095BC33 /* Vector.h */, + ); + name = math; + path = ../../idlib/math; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 81C858450912AD370095BC33 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C8584C0912AD510095BC33 /* Base64.h in Headers */, + 81C8584D0912AD510095BC33 /* BitMsg.h in Headers */, + 81C8584F0912AD510095BC33 /* Bounds.h in Headers */, + 81C858510912AD510095BC33 /* Box.h in Headers */, + 81C858530912AD510095BC33 /* Frustum.h in Headers */, + 81C858550912AD510095BC33 /* Sphere.h in Headers */, + 81C858570912AD510095BC33 /* CmdArgs.h in Headers */, + 81C858580912AD510095BC33 /* BinSearch.h in Headers */, + 81C858590912AD510095BC33 /* BTree.h in Headers */, + 81C8585B0912AD510095BC33 /* HashIndex.h in Headers */, + 81C8585C0912AD510095BC33 /* HashTable.h in Headers */, + 81C8585D0912AD510095BC33 /* Hierarchy.h in Headers */, + 81C8585E0912AD510095BC33 /* LinkList.h in Headers */, + 81C8585F0912AD510095BC33 /* List.h in Headers */, + 81C858600912AD510095BC33 /* PlaneSet.h in Headers */, + 81C858610912AD510095BC33 /* Queue.h in Headers */, + 81C858620912AD510095BC33 /* Stack.h in Headers */, + 81C858630912AD510095BC33 /* StaticList.h in Headers */, + 81C858640912AD510095BC33 /* StrList.h in Headers */, + 81C858650912AD510095BC33 /* StrPool.h in Headers */, + 81C858660912AD510095BC33 /* VectorSet.h in Headers */, + 81C858680912AD510095BC33 /* Dict.h in Headers */, + 81C8586A0912AD510095BC33 /* DrawVert.h in Headers */, + 81C8586C0912AD510095BC33 /* JointTransform.h in Headers */, + 81C8586E0912AD510095BC33 /* Surface.h in Headers */, + 81C858700912AD510095BC33 /* Surface_Patch.h in Headers */, + 81C858720912AD510095BC33 /* Surface_Polytope.h in Headers */, + 81C858740912AD510095BC33 /* Surface_SweptSpline.h in Headers */, + 81C858760912AD510095BC33 /* TraceModel.h in Headers */, + 81C858780912AD510095BC33 /* Winding.h in Headers */, + 81C8587A0912AD510095BC33 /* Winding2D.h in Headers */, + 81C8587E0912AD510095BC33 /* CRC32.h in Headers */, + 81C858840912AD510095BC33 /* MD4.h in Headers */, + 81C858860912AD510095BC33 /* MD5.h in Headers */, + 81C858880912AD510095BC33 /* Heap.h in Headers */, + 81C8588A0912AD510095BC33 /* LangDict.h in Headers */, + 81C8588C0912AD510095BC33 /* Lexer.h in Headers */, + 81C8588E0912AD510095BC33 /* Lib.h in Headers */, + 81C858900912AD510095BC33 /* MapFile.h in Headers */, + 81C858930912AD510095BC33 /* Polynomial.h in Headers */, + 81C858940912AD510095BC33 /* Angles.h in Headers */, + 81C858960912AD510095BC33 /* Complex.h in Headers */, + 81C858970912AD510095BC33 /* Curve.h in Headers */, + 81C858980912AD510095BC33 /* Extrapolate.h in Headers */, + 81C858990912AD510095BC33 /* Interpolate.h in Headers */, + 81C8589B0912AD510095BC33 /* Lcp.h in Headers */, + 81C8589E0912AD510095BC33 /* Matrix.h in Headers */, + 81C858A00912AD510095BC33 /* Ode.h in Headers */, + 81C858A20912AD510095BC33 /* Plane.h in Headers */, + 81C858A40912AD510095BC33 /* Pluecker.h in Headers */, + 81C858A60912AD510095BC33 /* Quat.h in Headers */, + 81C858A70912AD510095BC33 /* Random.h in Headers */, + 81C858A90912AD510095BC33 /* Rotation.h in Headers */, + 81C858AB0912AD510095BC33 /* Simd.h in Headers */, + 81C858AD0912AD510095BC33 /* Simd_3DNow.h in Headers */, + 81C858AF0912AD510095BC33 /* Simd_AltiVec.h in Headers */, + 81C858B10912AD510095BC33 /* Simd_Generic.h in Headers */, + 81C858B30912AD510095BC33 /* Simd_MMX.h in Headers */, + 81C858B50912AD510095BC33 /* Simd_SSE.h in Headers */, + 81C858B70912AD510095BC33 /* Simd_SSE2.h in Headers */, + 81C858B90912AD510095BC33 /* Simd_SSE3.h in Headers */, + 81C858BB0912AD510095BC33 /* Vector.h in Headers */, + 81C858BD0912AD510095BC33 /* Parser.h in Headers */, + 81C858BE0912AD510095BC33 /* precompiled.h in Headers */, + 81C858C00912AD510095BC33 /* Str.h in Headers */, + 81C858C20912AD510095BC33 /* Timer.h in Headers */, + 81C858C40912AD510095BC33 /* Token.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC043055464E500DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C857CA0912AD0D0095BC33 /* Base64.h in Headers */, + 81C857CB0912AD0D0095BC33 /* BitMsg.h in Headers */, + 81C857CD0912AD0D0095BC33 /* Bounds.h in Headers */, + 81C857CF0912AD0D0095BC33 /* Box.h in Headers */, + 81C857D10912AD0D0095BC33 /* Frustum.h in Headers */, + 81C857D30912AD0D0095BC33 /* Sphere.h in Headers */, + 81C857D50912AD0D0095BC33 /* CmdArgs.h in Headers */, + 81C857D60912AD0D0095BC33 /* BinSearch.h in Headers */, + 81C857D70912AD0D0095BC33 /* BTree.h in Headers */, + 81C857D90912AD0D0095BC33 /* HashIndex.h in Headers */, + 81C857DA0912AD0D0095BC33 /* HashTable.h in Headers */, + 81C857DB0912AD0D0095BC33 /* Hierarchy.h in Headers */, + 81C857DC0912AD0D0095BC33 /* LinkList.h in Headers */, + 81C857DD0912AD0D0095BC33 /* List.h in Headers */, + 81C857DE0912AD0D0095BC33 /* PlaneSet.h in Headers */, + 81C857DF0912AD0D0095BC33 /* Queue.h in Headers */, + 81C857E00912AD0D0095BC33 /* Stack.h in Headers */, + 81C857E10912AD0D0095BC33 /* StaticList.h in Headers */, + 81C857E20912AD0D0095BC33 /* StrList.h in Headers */, + 81C857E30912AD0D0095BC33 /* StrPool.h in Headers */, + 81C857E40912AD0D0095BC33 /* VectorSet.h in Headers */, + 81C857E60912AD0D0095BC33 /* Dict.h in Headers */, + 81C857E80912AD0D0095BC33 /* DrawVert.h in Headers */, + 81C857EA0912AD0D0095BC33 /* JointTransform.h in Headers */, + 81C857EC0912AD0D0095BC33 /* Surface.h in Headers */, + 81C857EE0912AD0D0095BC33 /* Surface_Patch.h in Headers */, + 81C857F00912AD0D0095BC33 /* Surface_Polytope.h in Headers */, + 81C857F20912AD0D0095BC33 /* Surface_SweptSpline.h in Headers */, + 81C857F40912AD0D0095BC33 /* TraceModel.h in Headers */, + 81C857F60912AD0D0095BC33 /* Winding.h in Headers */, + 81C857F80912AD0D0095BC33 /* Winding2D.h in Headers */, + 81C857FC0912AD0D0095BC33 /* CRC32.h in Headers */, + 81C858020912AD0D0095BC33 /* MD4.h in Headers */, + 81C858040912AD0D0095BC33 /* MD5.h in Headers */, + 81C858060912AD0D0095BC33 /* Heap.h in Headers */, + 81C858080912AD0D0095BC33 /* LangDict.h in Headers */, + 81C8580A0912AD0D0095BC33 /* Lexer.h in Headers */, + 81C8580C0912AD0D0095BC33 /* Lib.h in Headers */, + 81C8580E0912AD0D0095BC33 /* MapFile.h in Headers */, + 81C858110912AD0D0095BC33 /* Polynomial.h in Headers */, + 81C858120912AD0D0095BC33 /* Angles.h in Headers */, + 81C858140912AD0D0095BC33 /* Complex.h in Headers */, + 81C858150912AD0D0095BC33 /* Curve.h in Headers */, + 81C858160912AD0D0095BC33 /* Extrapolate.h in Headers */, + 81C858170912AD0D0095BC33 /* Interpolate.h in Headers */, + 81C858190912AD0D0095BC33 /* Lcp.h in Headers */, + 81C8581C0912AD0D0095BC33 /* Matrix.h in Headers */, + 81C8581E0912AD0D0095BC33 /* Ode.h in Headers */, + 81C858200912AD0D0095BC33 /* Plane.h in Headers */, + 81C858220912AD0D0095BC33 /* Pluecker.h in Headers */, + 81C858240912AD0D0095BC33 /* Quat.h in Headers */, + 81C858250912AD0D0095BC33 /* Random.h in Headers */, + 81C858270912AD0D0095BC33 /* Rotation.h in Headers */, + 81C858290912AD0D0095BC33 /* Simd.h in Headers */, + 81C8582B0912AD0D0095BC33 /* Simd_3DNow.h in Headers */, + 81C8582D0912AD0D0095BC33 /* Simd_AltiVec.h in Headers */, + 81C8582F0912AD0D0095BC33 /* Simd_Generic.h in Headers */, + 81C858310912AD0D0095BC33 /* Simd_MMX.h in Headers */, + 81C858330912AD0D0095BC33 /* Simd_SSE.h in Headers */, + 81C858350912AD0D0095BC33 /* Simd_SSE2.h in Headers */, + 81C858370912AD0D0095BC33 /* Simd_SSE3.h in Headers */, + 81C858390912AD0D0095BC33 /* Vector.h in Headers */, + 81C8583B0912AD0D0095BC33 /* Parser.h in Headers */, + 81C8583C0912AD0D0095BC33 /* precompiled.h in Headers */, + 81C8583E0912AD0D0095BC33 /* Str.h in Headers */, + 81C858400912AD0D0095BC33 /* Timer.h in Headers */, + 81C858420912AD0D0095BC33 /* Token.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 81C858480912AD370095BC33 /* idlib_nopic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81C858C60912AD610095BC33 /* Build configuration list for PBXNativeTarget "idlib_nopic" */; + buildPhases = ( + 81C858450912AD370095BC33 /* Headers */, + 81C858460912AD370095BC33 /* Sources */, + 81C858470912AD370095BC33 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = idlib_nopic; + productName = idlib_nopic; + productReference = 81C858490912AD370095BC33 /* libidlib_nopic.a */; + productType = "com.apple.product-type.library.static"; + }; + D2AAC045055464E500DB518D /* idlib_pic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81C857230912ACE80095BC33 /* Build configuration list for PBXNativeTarget "idlib_pic" */; + buildPhases = ( + D2AAC043055464E500DB518D /* Headers */, + D2AAC044055464E500DB518D /* Sources */, + D289987405E68DCB004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = idlib_pic; + productName = idlib; + productReference = D2AAC046055464E500DB518D /* libidlib_pic.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + ORGANIZATIONNAME = "id Software LLC"; + }; + buildConfigurationList = 81C857270912ACE80095BC33 /* Build configuration list for PBXProject "idlib" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* idlib */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC045055464E500DB518D /* idlib_pic */, + 81C858480912AD370095BC33 /* idlib_nopic */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 81C858460912AD370095BC33 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C8584A0912AD510095BC33 /* BitMsg.cpp in Sources */, + 81C8584B0912AD510095BC33 /* Base64.cpp in Sources */, + 81C8584E0912AD510095BC33 /* Bounds.cpp in Sources */, + 81C858500912AD510095BC33 /* Box.cpp in Sources */, + 81C858520912AD510095BC33 /* Frustum.cpp in Sources */, + 81C858540912AD510095BC33 /* Sphere.cpp in Sources */, + 81C858560912AD510095BC33 /* CmdArgs.cpp in Sources */, + 81C8585A0912AD510095BC33 /* HashIndex.cpp in Sources */, + 81C858670912AD510095BC33 /* Dict.cpp in Sources */, + 81C858690912AD510095BC33 /* DrawVert.cpp in Sources */, + 81C8586B0912AD510095BC33 /* JointTransform.cpp in Sources */, + 81C8586D0912AD510095BC33 /* Surface.cpp in Sources */, + 81C8586F0912AD510095BC33 /* Surface_Patch.cpp in Sources */, + 81C858710912AD510095BC33 /* Surface_Polytope.cpp in Sources */, + 81C858730912AD510095BC33 /* Surface_SweptSpline.cpp in Sources */, + 81C858750912AD510095BC33 /* TraceModel.cpp in Sources */, + 81C858770912AD510095BC33 /* Winding.cpp in Sources */, + 81C858790912AD510095BC33 /* Winding2D.cpp in Sources */, + 81C8587D0912AD510095BC33 /* CRC32.cpp in Sources */, + 81C858830912AD510095BC33 /* MD4.cpp in Sources */, + 81C858850912AD510095BC33 /* MD5.cpp in Sources */, + 81C858870912AD510095BC33 /* Heap.cpp in Sources */, + 81C858890912AD510095BC33 /* LangDict.cpp in Sources */, + 81C8588B0912AD510095BC33 /* Lexer.cpp in Sources */, + 81C8588D0912AD510095BC33 /* Lib.cpp in Sources */, + 81C8588F0912AD510095BC33 /* MapFile.cpp in Sources */, + 81C858910912AD510095BC33 /* Angles.cpp in Sources */, + 81C858920912AD510095BC33 /* Polynomial.cpp in Sources */, + 81C858950912AD510095BC33 /* Complex.cpp in Sources */, + 81C8589A0912AD510095BC33 /* Lcp.cpp in Sources */, + 81C8589C0912AD510095BC33 /* Math.cpp in Sources */, + 81C8589D0912AD510095BC33 /* Matrix.cpp in Sources */, + 81C8589F0912AD510095BC33 /* Ode.cpp in Sources */, + 81C858A10912AD510095BC33 /* Plane.cpp in Sources */, + 81C858A30912AD510095BC33 /* Pluecker.cpp in Sources */, + 81C858A50912AD510095BC33 /* Quat.cpp in Sources */, + 81C858A80912AD510095BC33 /* Rotation.cpp in Sources */, + 81C858AA0912AD510095BC33 /* Simd.cpp in Sources */, + 81C858AC0912AD510095BC33 /* Simd_3DNow.cpp in Sources */, + 81C858AE0912AD510095BC33 /* Simd_AltiVec.cpp in Sources */, + 81C858B00912AD510095BC33 /* Simd_Generic.cpp in Sources */, + 81C858B20912AD510095BC33 /* Simd_MMX.cpp in Sources */, + 81C858B40912AD510095BC33 /* Simd_SSE.cpp in Sources */, + 81C858B60912AD510095BC33 /* Simd_SSE2.cpp in Sources */, + 81C858B80912AD510095BC33 /* Simd_SSE3.cpp in Sources */, + 81C858BA0912AD510095BC33 /* Vector.cpp in Sources */, + 81C858BC0912AD510095BC33 /* Parser.cpp in Sources */, + 81C858BF0912AD510095BC33 /* Str.cpp in Sources */, + 81C858C10912AD510095BC33 /* Timer.cpp in Sources */, + 81C858C30912AD510095BC33 /* Token.cpp in Sources */, + 3A1767C7149346E90077AB23 /* Frustum_gcc.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC044055464E500DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81C857480912AD020095BC33 /* BitMsg.cpp in Sources */, + 81C857C90912AD0D0095BC33 /* Base64.cpp in Sources */, + 81C857CC0912AD0D0095BC33 /* Bounds.cpp in Sources */, + 81C857CE0912AD0D0095BC33 /* Box.cpp in Sources */, + 81C857D00912AD0D0095BC33 /* Frustum.cpp in Sources */, + 81C857D20912AD0D0095BC33 /* Sphere.cpp in Sources */, + 81C857D40912AD0D0095BC33 /* CmdArgs.cpp in Sources */, + 81C857D80912AD0D0095BC33 /* HashIndex.cpp in Sources */, + 81C857E50912AD0D0095BC33 /* Dict.cpp in Sources */, + 81C857E70912AD0D0095BC33 /* DrawVert.cpp in Sources */, + 81C857E90912AD0D0095BC33 /* JointTransform.cpp in Sources */, + 81C857EB0912AD0D0095BC33 /* Surface.cpp in Sources */, + 81C857ED0912AD0D0095BC33 /* Surface_Patch.cpp in Sources */, + 81C857EF0912AD0D0095BC33 /* Surface_Polytope.cpp in Sources */, + 81C857F10912AD0D0095BC33 /* Surface_SweptSpline.cpp in Sources */, + 81C857F30912AD0D0095BC33 /* TraceModel.cpp in Sources */, + 81C857F50912AD0D0095BC33 /* Winding.cpp in Sources */, + 81C857F70912AD0D0095BC33 /* Winding2D.cpp in Sources */, + 81C857FB0912AD0D0095BC33 /* CRC32.cpp in Sources */, + 81C858010912AD0D0095BC33 /* MD4.cpp in Sources */, + 81C858030912AD0D0095BC33 /* MD5.cpp in Sources */, + 81C858050912AD0D0095BC33 /* Heap.cpp in Sources */, + 81C858070912AD0D0095BC33 /* LangDict.cpp in Sources */, + 81C858090912AD0D0095BC33 /* Lexer.cpp in Sources */, + 81C8580B0912AD0D0095BC33 /* Lib.cpp in Sources */, + 81C8580D0912AD0D0095BC33 /* MapFile.cpp in Sources */, + 81C8580F0912AD0D0095BC33 /* Angles.cpp in Sources */, + 81C858100912AD0D0095BC33 /* Polynomial.cpp in Sources */, + 81C858130912AD0D0095BC33 /* Complex.cpp in Sources */, + 81C858180912AD0D0095BC33 /* Lcp.cpp in Sources */, + 81C8581A0912AD0D0095BC33 /* Math.cpp in Sources */, + 81C8581B0912AD0D0095BC33 /* Matrix.cpp in Sources */, + 81C8581D0912AD0D0095BC33 /* Ode.cpp in Sources */, + 81C8581F0912AD0D0095BC33 /* Plane.cpp in Sources */, + 81C858210912AD0D0095BC33 /* Pluecker.cpp in Sources */, + 81C858230912AD0D0095BC33 /* Quat.cpp in Sources */, + 81C858260912AD0D0095BC33 /* Rotation.cpp in Sources */, + 81C858280912AD0D0095BC33 /* Simd.cpp in Sources */, + 81C8582A0912AD0D0095BC33 /* Simd_3DNow.cpp in Sources */, + 81C8582C0912AD0D0095BC33 /* Simd_AltiVec.cpp in Sources */, + 81C8582E0912AD0D0095BC33 /* Simd_Generic.cpp in Sources */, + 81C858300912AD0D0095BC33 /* Simd_MMX.cpp in Sources */, + 81C858320912AD0D0095BC33 /* Simd_SSE.cpp in Sources */, + 81C858340912AD0D0095BC33 /* Simd_SSE2.cpp in Sources */, + 81C858360912AD0D0095BC33 /* Simd_SSE3.cpp in Sources */, + 81C858380912AD0D0095BC33 /* Vector.cpp in Sources */, + 81C8583A0912AD0D0095BC33 /* Parser.cpp in Sources */, + 81C8583D0912AD0D0095BC33 /* Str.cpp in Sources */, + 81C8583F0912AD0D0095BC33 /* Timer.cpp in Sources */, + 81C858410912AD0D0095BC33 /* Token.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 81C857240912ACE80095BC33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + PREBINDING = NO; + PRODUCT_NAME = idlib_pic; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = YES; + }; + name = Debug; + }; + 81C857250912ACE80095BC33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 3; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = idlib_pic; + SYMROOT = build; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = NO; + }; + name = Release; + }; + 81C857280912ACE80095BC33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_ALTIVEC_EXTENSIONS = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 1; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + MAIN_CPP_DEFINES = _DEBUG; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + SDKROOT = macosx10.5; + USE_SEPARATE_HEADERMAPS = YES; + VALID_ARCHS = i386; + }; + name = Debug; + }; + 81C857290912ACE80095BC33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_ALTIVEC_EXTENSIONS = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(MAIN_CPP_DEFINES)", + MACOS_X, + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + SDKROOT = macosx10.5; + USE_SEPARATE_HEADERMAPS = YES; + VALID_ARCHS = i386; + }; + name = Release; + }; + 81C858C70912AD610095BC33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = "$(HOME)/lib"; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = idlib_nopic; + SECTORDER_FLAGS = ""; + VALID_ARCHS = "ppc i386"; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Debug; + }; + 81C858C80912AD610095BC33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 3; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = idlib_nopic; + SYMROOT = build; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 81C857230912ACE80095BC33 /* Build configuration list for PBXNativeTarget "idlib_pic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81C857240912ACE80095BC33 /* Debug */, + 81C857250912ACE80095BC33 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 81C857270912ACE80095BC33 /* Build configuration list for PBXProject "idlib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81C857280912ACE80095BC33 /* Debug */, + 81C857290912ACE80095BC33 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 81C858C60912AD610095BC33 /* Build configuration list for PBXNativeTarget "idlib_nopic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81C858C70912AD610095BC33 /* Debug */, + 81C858C80912AD610095BC33 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/sys/osx/jpeg.xcodeproj/project.pbxproj b/sys/osx/jpeg.xcodeproj/project.pbxproj new file mode 100644 index 000000000..997833389 --- /dev/null +++ b/sys/osx/jpeg.xcodeproj/project.pbxproj @@ -0,0 +1,385 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3A176C441493657B0077AB23 /* ansi2knr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C0C1493657A0077AB23 /* ansi2knr.c */; }; + 3A176C471493657B0077AB23 /* ckconfig.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C0F1493657A0077AB23 /* ckconfig.c */; }; + 3A176C4A1493657B0077AB23 /* jaricom.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C121493657A0077AB23 /* jaricom.c */; }; + 3A176C4B1493657B0077AB23 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C131493657A0077AB23 /* jcapimin.c */; }; + 3A176C4C1493657B0077AB23 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C141493657A0077AB23 /* jcapistd.c */; }; + 3A176C4D1493657B0077AB23 /* jcarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C151493657A0077AB23 /* jcarith.c */; }; + 3A176C4E1493657B0077AB23 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C161493657A0077AB23 /* jccoefct.c */; }; + 3A176C4F1493657B0077AB23 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C171493657A0077AB23 /* jccolor.c */; }; + 3A176C501493657B0077AB23 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C181493657A0077AB23 /* jcdctmgr.c */; }; + 3A176C511493657B0077AB23 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C191493657A0077AB23 /* jchuff.c */; }; + 3A176C521493657B0077AB23 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1A1493657A0077AB23 /* jcinit.c */; }; + 3A176C531493657B0077AB23 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1B1493657A0077AB23 /* jcmainct.c */; }; + 3A176C541493657B0077AB23 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1C1493657A0077AB23 /* jcmarker.c */; }; + 3A176C551493657B0077AB23 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1D1493657A0077AB23 /* jcmaster.c */; }; + 3A176C561493657B0077AB23 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1E1493657A0077AB23 /* jcomapi.c */; }; + 3A176C571493657B0077AB23 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C1F1493657A0077AB23 /* jcparam.c */; }; + 3A176C581493657B0077AB23 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C201493657A0077AB23 /* jcprepct.c */; }; + 3A176C591493657B0077AB23 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C211493657A0077AB23 /* jcsample.c */; }; + 3A176C5A1493657B0077AB23 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C221493657A0077AB23 /* jctrans.c */; }; + 3A176C5B1493657B0077AB23 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C231493657A0077AB23 /* jdapimin.c */; }; + 3A176C5C1493657B0077AB23 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C241493657A0077AB23 /* jdapistd.c */; }; + 3A176C5D1493657B0077AB23 /* jdarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C251493657A0077AB23 /* jdarith.c */; }; + 3A176C5E1493657B0077AB23 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C261493657A0077AB23 /* jdatadst.c */; }; + 3A176C5F1493657B0077AB23 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C271493657A0077AB23 /* jdatasrc.c */; }; + 3A176C601493657B0077AB23 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C281493657A0077AB23 /* jdcoefct.c */; }; + 3A176C611493657B0077AB23 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C291493657A0077AB23 /* jdcolor.c */; }; + 3A176C621493657B0077AB23 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2A1493657A0077AB23 /* jddctmgr.c */; }; + 3A176C631493657B0077AB23 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2B1493657A0077AB23 /* jdhuff.c */; }; + 3A176C641493657B0077AB23 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2C1493657A0077AB23 /* jdinput.c */; }; + 3A176C651493657B0077AB23 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2D1493657A0077AB23 /* jdmainct.c */; }; + 3A176C661493657B0077AB23 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2E1493657A0077AB23 /* jdmarker.c */; }; + 3A176C671493657B0077AB23 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C2F1493657B0077AB23 /* jdmaster.c */; }; + 3A176C681493657B0077AB23 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C301493657B0077AB23 /* jdmerge.c */; }; + 3A176C691493657B0077AB23 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C311493657B0077AB23 /* jdpostct.c */; }; + 3A176C6A1493657B0077AB23 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C321493657B0077AB23 /* jdsample.c */; }; + 3A176C6B1493657B0077AB23 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C331493657B0077AB23 /* jdtrans.c */; }; + 3A176C6C1493657B0077AB23 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C341493657B0077AB23 /* jerror.c */; }; + 3A176C6D1493657B0077AB23 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C351493657B0077AB23 /* jfdctflt.c */; }; + 3A176C6E1493657B0077AB23 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C361493657B0077AB23 /* jfdctfst.c */; }; + 3A176C6F1493657B0077AB23 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C371493657B0077AB23 /* jfdctint.c */; }; + 3A176C701493657B0077AB23 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C381493657B0077AB23 /* jidctflt.c */; }; + 3A176C711493657B0077AB23 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C391493657B0077AB23 /* jidctfst.c */; }; + 3A176C721493657B0077AB23 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3A1493657B0077AB23 /* jidctint.c */; }; + 3A176C731493657B0077AB23 /* jmemansi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3B1493657B0077AB23 /* jmemansi.c */; }; + 3A176C741493657B0077AB23 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3C1493657B0077AB23 /* jmemmgr.c */; }; + 3A176C751493657B0077AB23 /* jmemname.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3D1493657B0077AB23 /* jmemname.c */; }; + 3A176C761493657B0077AB23 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3E1493657B0077AB23 /* jmemnobs.c */; }; + 3A176C771493657B0077AB23 /* jpegtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C3F1493657B0077AB23 /* jpegtran.c */; }; + 3A176C781493657B0077AB23 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C401493657B0077AB23 /* jquant1.c */; }; + 3A176C791493657B0077AB23 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C411493657B0077AB23 /* jquant2.c */; }; + 3A176C7A1493657B0077AB23 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C421493657B0077AB23 /* jutils.c */; }; + 3A176C7B1493657B0077AB23 /* transupp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176C431493657B0077AB23 /* transupp.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3A176B561493626B0077AB23 /* libjpeg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjpeg.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A176C0C1493657A0077AB23 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ansi2knr.c; path = ../../lib/libjpeg/ansi2knr.c; sourceTree = SOURCE_ROOT; }; + 3A176C0F1493657A0077AB23 /* ckconfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ckconfig.c; path = ../../lib/libjpeg/ckconfig.c; sourceTree = SOURCE_ROOT; }; + 3A176C121493657A0077AB23 /* jaricom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jaricom.c; path = ../../lib/libjpeg/jaricom.c; sourceTree = SOURCE_ROOT; }; + 3A176C131493657A0077AB23 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../../lib/libjpeg/jcapimin.c; sourceTree = SOURCE_ROOT; }; + 3A176C141493657A0077AB23 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../../lib/libjpeg/jcapistd.c; sourceTree = SOURCE_ROOT; }; + 3A176C151493657A0077AB23 /* jcarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcarith.c; path = ../../lib/libjpeg/jcarith.c; sourceTree = SOURCE_ROOT; }; + 3A176C161493657A0077AB23 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../../lib/libjpeg/jccoefct.c; sourceTree = SOURCE_ROOT; }; + 3A176C171493657A0077AB23 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../../lib/libjpeg/jccolor.c; sourceTree = SOURCE_ROOT; }; + 3A176C181493657A0077AB23 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../../lib/libjpeg/jcdctmgr.c; sourceTree = SOURCE_ROOT; }; + 3A176C191493657A0077AB23 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../../lib/libjpeg/jchuff.c; sourceTree = SOURCE_ROOT; }; + 3A176C1A1493657A0077AB23 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../../lib/libjpeg/jcinit.c; sourceTree = SOURCE_ROOT; }; + 3A176C1B1493657A0077AB23 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../../lib/libjpeg/jcmainct.c; sourceTree = SOURCE_ROOT; }; + 3A176C1C1493657A0077AB23 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../../lib/libjpeg/jcmarker.c; sourceTree = SOURCE_ROOT; }; + 3A176C1D1493657A0077AB23 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../../lib/libjpeg/jcmaster.c; sourceTree = SOURCE_ROOT; }; + 3A176C1E1493657A0077AB23 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../../lib/libjpeg/jcomapi.c; sourceTree = SOURCE_ROOT; }; + 3A176C1F1493657A0077AB23 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../../lib/libjpeg/jcparam.c; sourceTree = SOURCE_ROOT; }; + 3A176C201493657A0077AB23 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../../lib/libjpeg/jcprepct.c; sourceTree = SOURCE_ROOT; }; + 3A176C211493657A0077AB23 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../../lib/libjpeg/jcsample.c; sourceTree = SOURCE_ROOT; }; + 3A176C221493657A0077AB23 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../../lib/libjpeg/jctrans.c; sourceTree = SOURCE_ROOT; }; + 3A176C231493657A0077AB23 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../../lib/libjpeg/jdapimin.c; sourceTree = SOURCE_ROOT; }; + 3A176C241493657A0077AB23 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../../lib/libjpeg/jdapistd.c; sourceTree = SOURCE_ROOT; }; + 3A176C251493657A0077AB23 /* jdarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdarith.c; path = ../../lib/libjpeg/jdarith.c; sourceTree = SOURCE_ROOT; }; + 3A176C261493657A0077AB23 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../../lib/libjpeg/jdatadst.c; sourceTree = SOURCE_ROOT; }; + 3A176C271493657A0077AB23 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../../lib/libjpeg/jdatasrc.c; sourceTree = SOURCE_ROOT; }; + 3A176C281493657A0077AB23 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../../lib/libjpeg/jdcoefct.c; sourceTree = SOURCE_ROOT; }; + 3A176C291493657A0077AB23 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../../lib/libjpeg/jdcolor.c; sourceTree = SOURCE_ROOT; }; + 3A176C2A1493657A0077AB23 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../../lib/libjpeg/jddctmgr.c; sourceTree = SOURCE_ROOT; }; + 3A176C2B1493657A0077AB23 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../../lib/libjpeg/jdhuff.c; sourceTree = SOURCE_ROOT; }; + 3A176C2C1493657A0077AB23 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../../lib/libjpeg/jdinput.c; sourceTree = SOURCE_ROOT; }; + 3A176C2D1493657A0077AB23 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../../lib/libjpeg/jdmainct.c; sourceTree = SOURCE_ROOT; }; + 3A176C2E1493657A0077AB23 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../../lib/libjpeg/jdmarker.c; sourceTree = SOURCE_ROOT; }; + 3A176C2F1493657B0077AB23 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../../lib/libjpeg/jdmaster.c; sourceTree = SOURCE_ROOT; }; + 3A176C301493657B0077AB23 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../../lib/libjpeg/jdmerge.c; sourceTree = SOURCE_ROOT; }; + 3A176C311493657B0077AB23 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../../lib/libjpeg/jdpostct.c; sourceTree = SOURCE_ROOT; }; + 3A176C321493657B0077AB23 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../../lib/libjpeg/jdsample.c; sourceTree = SOURCE_ROOT; }; + 3A176C331493657B0077AB23 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../../lib/libjpeg/jdtrans.c; sourceTree = SOURCE_ROOT; }; + 3A176C341493657B0077AB23 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../../lib/libjpeg/jerror.c; sourceTree = SOURCE_ROOT; }; + 3A176C351493657B0077AB23 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../../lib/libjpeg/jfdctflt.c; sourceTree = SOURCE_ROOT; }; + 3A176C361493657B0077AB23 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../../lib/libjpeg/jfdctfst.c; sourceTree = SOURCE_ROOT; }; + 3A176C371493657B0077AB23 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../../lib/libjpeg/jfdctint.c; sourceTree = SOURCE_ROOT; }; + 3A176C381493657B0077AB23 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../../lib/libjpeg/jidctflt.c; sourceTree = SOURCE_ROOT; }; + 3A176C391493657B0077AB23 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../../lib/libjpeg/jidctfst.c; sourceTree = SOURCE_ROOT; }; + 3A176C3A1493657B0077AB23 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../../lib/libjpeg/jidctint.c; sourceTree = SOURCE_ROOT; }; + 3A176C3B1493657B0077AB23 /* jmemansi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemansi.c; path = ../../lib/libjpeg/jmemansi.c; sourceTree = SOURCE_ROOT; }; + 3A176C3C1493657B0077AB23 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../../lib/libjpeg/jmemmgr.c; sourceTree = SOURCE_ROOT; }; + 3A176C3D1493657B0077AB23 /* jmemname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemname.c; path = ../../lib/libjpeg/jmemname.c; sourceTree = SOURCE_ROOT; }; + 3A176C3E1493657B0077AB23 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../../lib/libjpeg/jmemnobs.c; sourceTree = SOURCE_ROOT; }; + 3A176C3F1493657B0077AB23 /* jpegtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jpegtran.c; path = ../../lib/libjpeg/jpegtran.c; sourceTree = SOURCE_ROOT; }; + 3A176C401493657B0077AB23 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../../lib/libjpeg/jquant1.c; sourceTree = SOURCE_ROOT; }; + 3A176C411493657B0077AB23 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../../lib/libjpeg/jquant2.c; sourceTree = SOURCE_ROOT; }; + 3A176C421493657B0077AB23 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../lib/libjpeg/jutils.c; sourceTree = SOURCE_ROOT; }; + 3A176C431493657B0077AB23 /* transupp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = transupp.c; path = ../../lib/libjpeg/transupp.c; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3A176B541493626B0077AB23 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3A176B471493625D0077AB23 = { + isa = PBXGroup; + children = ( + 3A176C0C1493657A0077AB23 /* ansi2knr.c */, + 3A176C0F1493657A0077AB23 /* ckconfig.c */, + 3A176C121493657A0077AB23 /* jaricom.c */, + 3A176C131493657A0077AB23 /* jcapimin.c */, + 3A176C141493657A0077AB23 /* jcapistd.c */, + 3A176C151493657A0077AB23 /* jcarith.c */, + 3A176C161493657A0077AB23 /* jccoefct.c */, + 3A176C171493657A0077AB23 /* jccolor.c */, + 3A176C181493657A0077AB23 /* jcdctmgr.c */, + 3A176C191493657A0077AB23 /* jchuff.c */, + 3A176C1A1493657A0077AB23 /* jcinit.c */, + 3A176C1B1493657A0077AB23 /* jcmainct.c */, + 3A176C1C1493657A0077AB23 /* jcmarker.c */, + 3A176C1D1493657A0077AB23 /* jcmaster.c */, + 3A176C1E1493657A0077AB23 /* jcomapi.c */, + 3A176C1F1493657A0077AB23 /* jcparam.c */, + 3A176C201493657A0077AB23 /* jcprepct.c */, + 3A176C211493657A0077AB23 /* jcsample.c */, + 3A176C221493657A0077AB23 /* jctrans.c */, + 3A176C231493657A0077AB23 /* jdapimin.c */, + 3A176C241493657A0077AB23 /* jdapistd.c */, + 3A176C251493657A0077AB23 /* jdarith.c */, + 3A176C261493657A0077AB23 /* jdatadst.c */, + 3A176C271493657A0077AB23 /* jdatasrc.c */, + 3A176C281493657A0077AB23 /* jdcoefct.c */, + 3A176C291493657A0077AB23 /* jdcolor.c */, + 3A176C2A1493657A0077AB23 /* jddctmgr.c */, + 3A176C2B1493657A0077AB23 /* jdhuff.c */, + 3A176C2C1493657A0077AB23 /* jdinput.c */, + 3A176C2D1493657A0077AB23 /* jdmainct.c */, + 3A176C2E1493657A0077AB23 /* jdmarker.c */, + 3A176C2F1493657B0077AB23 /* jdmaster.c */, + 3A176C301493657B0077AB23 /* jdmerge.c */, + 3A176C311493657B0077AB23 /* jdpostct.c */, + 3A176C321493657B0077AB23 /* jdsample.c */, + 3A176C331493657B0077AB23 /* jdtrans.c */, + 3A176C341493657B0077AB23 /* jerror.c */, + 3A176C351493657B0077AB23 /* jfdctflt.c */, + 3A176C361493657B0077AB23 /* jfdctfst.c */, + 3A176C371493657B0077AB23 /* jfdctint.c */, + 3A176C381493657B0077AB23 /* jidctflt.c */, + 3A176C391493657B0077AB23 /* jidctfst.c */, + 3A176C3A1493657B0077AB23 /* jidctint.c */, + 3A176C3B1493657B0077AB23 /* jmemansi.c */, + 3A176C3C1493657B0077AB23 /* jmemmgr.c */, + 3A176C3D1493657B0077AB23 /* jmemname.c */, + 3A176C3E1493657B0077AB23 /* jmemnobs.c */, + 3A176C3F1493657B0077AB23 /* jpegtran.c */, + 3A176C401493657B0077AB23 /* jquant1.c */, + 3A176C411493657B0077AB23 /* jquant2.c */, + 3A176C421493657B0077AB23 /* jutils.c */, + 3A176C431493657B0077AB23 /* transupp.c */, + 3A176B571493626B0077AB23 /* Products */, + ); + sourceTree = ""; + }; + 3A176B571493626B0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176B561493626B0077AB23 /* libjpeg.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3A176B521493626B0077AB23 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3A176B551493626B0077AB23 /* jpeg */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3A176B5A1493626B0077AB23 /* Build configuration list for PBXNativeTarget "jpeg" */; + buildPhases = ( + 3A176B521493626B0077AB23 /* Headers */, + 3A176B531493626B0077AB23 /* Sources */, + 3A176B541493626B0077AB23 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = jpeg; + productName = jpeg; + productReference = 3A176B561493626B0077AB23 /* libjpeg.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3A176B491493625D0077AB23 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 3A176B4C1493625D0077AB23 /* Build configuration list for PBXProject "jpeg" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 0; + mainGroup = 3A176B471493625D0077AB23; + productRefGroup = 3A176B571493626B0077AB23 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3A176B551493626B0077AB23 /* jpeg */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 3A176B531493626B0077AB23 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A176C441493657B0077AB23 /* ansi2knr.c in Sources */, + 3A176C471493657B0077AB23 /* ckconfig.c in Sources */, + 3A176C4A1493657B0077AB23 /* jaricom.c in Sources */, + 3A176C4B1493657B0077AB23 /* jcapimin.c in Sources */, + 3A176C4C1493657B0077AB23 /* jcapistd.c in Sources */, + 3A176C4D1493657B0077AB23 /* jcarith.c in Sources */, + 3A176C4E1493657B0077AB23 /* jccoefct.c in Sources */, + 3A176C4F1493657B0077AB23 /* jccolor.c in Sources */, + 3A176C501493657B0077AB23 /* jcdctmgr.c in Sources */, + 3A176C511493657B0077AB23 /* jchuff.c in Sources */, + 3A176C521493657B0077AB23 /* jcinit.c in Sources */, + 3A176C531493657B0077AB23 /* jcmainct.c in Sources */, + 3A176C541493657B0077AB23 /* jcmarker.c in Sources */, + 3A176C551493657B0077AB23 /* jcmaster.c in Sources */, + 3A176C561493657B0077AB23 /* jcomapi.c in Sources */, + 3A176C571493657B0077AB23 /* jcparam.c in Sources */, + 3A176C581493657B0077AB23 /* jcprepct.c in Sources */, + 3A176C591493657B0077AB23 /* jcsample.c in Sources */, + 3A176C5A1493657B0077AB23 /* jctrans.c in Sources */, + 3A176C5B1493657B0077AB23 /* jdapimin.c in Sources */, + 3A176C5C1493657B0077AB23 /* jdapistd.c in Sources */, + 3A176C5D1493657B0077AB23 /* jdarith.c in Sources */, + 3A176C5E1493657B0077AB23 /* jdatadst.c in Sources */, + 3A176C5F1493657B0077AB23 /* jdatasrc.c in Sources */, + 3A176C601493657B0077AB23 /* jdcoefct.c in Sources */, + 3A176C611493657B0077AB23 /* jdcolor.c in Sources */, + 3A176C621493657B0077AB23 /* jddctmgr.c in Sources */, + 3A176C631493657B0077AB23 /* jdhuff.c in Sources */, + 3A176C641493657B0077AB23 /* jdinput.c in Sources */, + 3A176C651493657B0077AB23 /* jdmainct.c in Sources */, + 3A176C661493657B0077AB23 /* jdmarker.c in Sources */, + 3A176C671493657B0077AB23 /* jdmaster.c in Sources */, + 3A176C681493657B0077AB23 /* jdmerge.c in Sources */, + 3A176C691493657B0077AB23 /* jdpostct.c in Sources */, + 3A176C6A1493657B0077AB23 /* jdsample.c in Sources */, + 3A176C6B1493657B0077AB23 /* jdtrans.c in Sources */, + 3A176C6C1493657B0077AB23 /* jerror.c in Sources */, + 3A176C6D1493657B0077AB23 /* jfdctflt.c in Sources */, + 3A176C6E1493657B0077AB23 /* jfdctfst.c in Sources */, + 3A176C6F1493657B0077AB23 /* jfdctint.c in Sources */, + 3A176C701493657B0077AB23 /* jidctflt.c in Sources */, + 3A176C711493657B0077AB23 /* jidctfst.c in Sources */, + 3A176C721493657B0077AB23 /* jidctint.c in Sources */, + 3A176C731493657B0077AB23 /* jmemansi.c in Sources */, + 3A176C741493657B0077AB23 /* jmemmgr.c in Sources */, + 3A176C751493657B0077AB23 /* jmemname.c in Sources */, + 3A176C761493657B0077AB23 /* jmemnobs.c in Sources */, + 3A176C771493657B0077AB23 /* jpegtran.c in Sources */, + 3A176C781493657B0077AB23 /* jquant1.c in Sources */, + 3A176C791493657B0077AB23 /* jquant2.c in Sources */, + 3A176C7A1493657B0077AB23 /* jutils.c in Sources */, + 3A176C7B1493657B0077AB23 /* transupp.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3A176B4A1493625D0077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + name = Debug; + }; + 3A176B4B1493625D0077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + name = Release; + }; + 3A176B581493626B0077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = jpeg; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/libjpeg/\""; + }; + name = Debug; + }; + 3A176B591493626B0077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = jpeg; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/libjpeg/\""; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3A176B4C1493625D0077AB23 /* Build configuration list for PBXProject "jpeg" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A176B4A1493625D0077AB23 /* Debug */, + 3A176B4B1493625D0077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3A176B5A1493626B0077AB23 /* Build configuration list for PBXNativeTarget "jpeg" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A176B581493626B0077AB23 /* Debug */, + 3A176B591493626B0077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3A176B491493625D0077AB23 /* Project object */; +} diff --git a/sys/osx/macosx_common.h b/sys/osx/macosx_common.h new file mode 100644 index 000000000..1cf65990c --- /dev/null +++ b/sys/osx/macosx_common.h @@ -0,0 +1,2 @@ +const char *macosx_scanForLibraryDirectory(void); + diff --git a/sys/osx/macosx_display.h b/sys/osx/macosx_display.h new file mode 100644 index 000000000..b5424cf30 --- /dev/null +++ b/sys/osx/macosx_display.h @@ -0,0 +1,16 @@ +#include "macosx_local.h" + +@class NSDictionary; + +extern NSDictionary *Sys_GetMatchingDisplayMode( glimpParms_t parms ); + +extern void Sys_StoreGammaTables(); +extern void Sys_GetGammaTable(glwgamma_t *table); +extern void Sys_SetScreenFade(glwgamma_t *table, float fraction); + +extern void Sys_FadeScreens(); +extern void Sys_FadeScreen(CGDirectDisplayID display); +extern void Sys_UnfadeScreens(); +extern void Sys_UnfadeScreen(CGDirectDisplayID display, glwgamma_t *table); +extern void Sys_ReleaseAllDisplays(); + diff --git a/sys/osx/macosx_event.mm b/sys/osx/macosx_event.mm new file mode 100644 index 000000000..efa4417f7 --- /dev/null +++ b/sys/osx/macosx_event.mm @@ -0,0 +1,533 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +// -*- mode: objc -*- +#import "../../idlib/precompiled.h" + +#import "macosx_local.h" +#import "macosx_sys.h" + +#import +#import +#import +#import +#import +#import + +#import +#import +#import +#import + +#import + +#import +#import +#import +#include + +static NSDate *distantPast = NULL; +static bool inputActive = false; +static bool mouseActive = false; +static bool inputRectValid = NO; +static CGRect inputRect; +static const void *sKLuchrData = NULL; +static const void *sKLKCHRData = NULL; + +int vkeyToDoom3Key[256] = { + /*0x00*/ 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', + /*0x08*/ 'c', 'v', '?', 'b', 'q', 'w', 'e', 'r', + /*0x10*/ 'y', 't', '1', '2', '3', '4', '6', '5', + /*0x18*/ '=', '9', '7', '-', '8', '0', ']', 'o', + /*0x20*/ 'u', '[', 'i', 'p', K_ENTER, 'l', 'j', '\'', + /*0x28*/ 'k', ';', '\\', ',', '/', 'n', 'm', '.', + /*0x30*/ K_TAB, K_SPACE, '`', K_BACKSPACE, '?', K_ESCAPE, '?', K_COMMAND, + /*0x38*/ K_SHIFT, K_CAPSLOCK, K_ALT, K_CTRL, '?', '?', '?', '?', + /*0x40*/ '?', K_KP_DEL, '?', K_KP_STAR, '?', K_KP_PLUS, '?', K_KP_NUMLOCK, + /*0x48*/ '?', '?', '?', K_KP_SLASH, K_KP_ENTER, '?', K_KP_MINUS, '?', + /*0x50*/ '?', K_KP_EQUALS, K_KP_INS, K_KP_END, K_KP_DOWNARROW, K_KP_PGDN, K_KP_LEFTARROW, K_KP_5, + /*0x58*/ K_KP_RIGHTARROW, K_KP_HOME, '?', K_KP_UPARROW, K_KP_PGUP, '?', '?', '?', + /*0x60*/ K_F5, K_F6, K_F7, K_F3, K_F8, K_F9, '?', K_F11, + /*0x68*/ '?', K_PRINT_SCR, '?', K_F14, '?', K_F10, '?', K_F12, + /*0x70*/ '?', K_F15, K_INS, K_HOME, K_PGUP, K_DEL, K_F4, K_END, + /*0x78*/ K_F2, K_PGDN, K_F1, K_LEFTARROW, K_RIGHTARROW, K_DOWNARROW, K_UPARROW, K_POWER +}; + +int vkeyToDoom3Key_French[256] = { + /*0x00*/ 'q', 's', 'd', 'f', 'h', 'g', 'w', 'x', + /*0x08*/ 'c', 'v', '?', 'b', 'a', 'z', 'e', 'r', + /*0x10*/ 'y', 't', '1', '2', '3', '4', '6', '5', + /*0x18*/ '-', '9', '7', ')', '8', '0', '$', 'o', + /*0x20*/ 'u', '^', 'i', 'p', K_ENTER, 'l', 'j', 'ù', + /*0x28*/ 'k', 'm', 0x60, ';', '=', 'n', ',', ':', + /*0x30*/ K_TAB, K_SPACE, '<', K_BACKSPACE, '?', K_ESCAPE, '?', K_COMMAND, + /*0x38*/ K_SHIFT, K_CAPSLOCK, K_ALT, K_CTRL, '?', '?', '?', '?', + /*0x40*/ '?', K_KP_DEL, '?', K_KP_STAR, '?', K_KP_PLUS, '?', K_KP_NUMLOCK, + /*0x48*/ '?', '?', '?', K_KP_SLASH, K_KP_ENTER, '?', K_KP_MINUS, '?', + /*0x50*/ '?', K_KP_EQUALS, K_KP_INS, K_KP_END, K_KP_DOWNARROW, K_KP_PGDN, K_KP_LEFTARROW, K_KP_5, + /*0x58*/ K_KP_RIGHTARROW, K_KP_HOME, '?', K_KP_UPARROW, K_KP_PGUP, '?', '?', '?', + /*0x60*/ K_F5, K_F6, K_F7, K_F3, K_F8, K_F9, '?', K_F11, + /*0x68*/ '?', K_PRINT_SCR, '?', K_F14, '?', K_F10, '?', K_F12, + /*0x70*/ '?', K_F15, K_INS, K_HOME, K_PGUP, K_DEL, K_F4, K_END, + /*0x78*/ K_F2, K_PGDN, K_F1, K_LEFTARROW, K_RIGHTARROW, K_DOWNARROW, K_UPARROW, K_POWER +}; + +int vkeyToDoom3Key_German[256] = { + /*0x00*/ 'a', 's', 'd', 'f', 'h', 'g', 'y', 'x', + /*0x08*/ 'c', 'v', '?', 'b', 'q', 'w', 'e', 'r', + /*0x10*/ 'z', 't', '1', '2', '3', '4', '6', '5', + /*0x18*/ '«', '9', '7', '-', '8', '0', '+', 'o', + /*0x20*/ 'u', '[', 'i', 'p', K_ENTER, 'l', 'j', '\'', + /*0x28*/ 'k', ';', '#', ',', '-', 'n', 'm', '.', + /*0x30*/ K_TAB, K_SPACE, '`', K_BACKSPACE, '?', K_ESCAPE, '?', K_COMMAND, + /*0x38*/ K_SHIFT, K_CAPSLOCK, K_ALT, K_CTRL, '?', '?', '?', '?', + /*0x40*/ '?', K_KP_DEL, '?', K_KP_STAR, '?', K_KP_PLUS, '?', K_KP_NUMLOCK, + /*0x48*/ '?', '?', '?', K_KP_SLASH, K_KP_ENTER, '?', K_KP_MINUS, '?', + /*0x50*/ '?', K_KP_EQUALS, K_KP_INS, K_KP_END, K_KP_DOWNARROW, K_KP_PGDN, K_KP_LEFTARROW, K_KP_5, + /*0x58*/ K_KP_RIGHTARROW, K_KP_HOME, '?', K_KP_UPARROW, K_KP_PGUP, '?', '?', '?', + /*0x60*/ K_F5, K_F6, K_F7, K_F3, K_F8, K_F9, '?', K_F11, + /*0x68*/ '?', K_PRINT_SCR, '?', K_F14, '?', K_F10, '?', K_F12, + /*0x70*/ '?', K_F15, K_INS, K_HOME, K_PGUP, K_DEL, K_F4, K_END, + /*0x78*/ K_F2, K_PGDN, K_F1, K_LEFTARROW, K_RIGHTARROW, K_DOWNARROW, K_UPARROW, K_POWER +}; + +static const int *vkeyTable = vkeyToDoom3Key; + +/* + =========== + Sys_InitScanTable + =========== + */ +void Sys_InitScanTable( void ) { + KeyboardLayoutRef kbLayout; + + idStr lang = cvarSystem->GetCVarString( "sys_lang" ); + if ( lang.Length() == 0 ) { + lang = "english"; + } + + if ( lang.Icmp( "english" ) == 0 ) { + vkeyTable = vkeyToDoom3Key; + } else if ( lang.Icmp( "french" ) == 0 ) { + vkeyTable = vkeyToDoom3Key_French; + } else if ( lang.Icmp( "german" ) == 0 ) { + vkeyTable = vkeyToDoom3Key_German; + } + + if ( KLGetCurrentKeyboardLayout( &kbLayout ) == 0 ) { + if ( KLGetKeyboardLayoutProperty( kbLayout, kKLuchrData, &sKLuchrData ) ) { + common->Warning("KLGetKeyboardLayoutProperty failed"); + } + if ( !sKLuchrData ) { + if ( KLGetKeyboardLayoutProperty( kbLayout, kKLKCHRData, &sKLKCHRData ) ) { + common->Warning("KLGetKeyboardLayoutProperty failed"); + } + } + } + if ( !sKLuchrData && !sKLKCHRData ) { + common->Warning("Keyboard input initialziation failed"); + } +} + +void Sys_InitInput( void ) { + common->Printf( "------- Input Initialization -------\n" ); + + if ( !distantPast ) { + distantPast = [ [ NSDate distantPast ] retain ]; + } + + IN_ActivateMouse(); + + inputActive = true; +} + +void Sys_ShutdownInput( void ) { + common->Printf( "------- Input Shutdown -------\n" ); + + if ( !inputActive ) { + return; + } + inputActive = false; + if ( mouseActive ) { + IN_DeactivateMouse(); + } + + common->Printf( "------------------------------\n" ); +} + +void processMouseMovedEvent( NSEvent *mouseMovedEvent ) { + CGMouseDelta dx, dy; + + if ( !mouseActive ) { + return; + } + +#if 0 + +#define ACT_LIKE_WINDOWS +#ifdef ACT_LIKE_WINDOWS + cvar_t *in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "3.5", CVAR_ARCHIVE); + if (in_mouseLowEndSlope->value < 1) { + Cvar_Set("in_mouseLowEndSlope", "1"); + } +#else + cvar_t *in_mouseLowEndSlope = Cvar_Get("in_mouseLowEndSlope", "1", CVAR_ARCHIVE); + if (in_mouseLowEndSlope->value < 1) { + Cvar_Set("in_mouseLowEndSlope", "1"); + } +#endif + + cvar_t *in_mouseHighEndCutoff = Cvar_Get("in_mouseHighEndCutoff", "20", CVAR_ARCHIVE); + if (in_mouseLowEndSlope->value < 1) { + Cvar_Set("in_mouseHighEndCutoff", "1"); + } + +#endif + + CGGetLastMouseDelta(&dx, &dy); + + if ( dx || dy ) { + #if 0 // this is be handled by the mouse driver clean me out later + CGMouseDelta distSqr; + float m0, N; + + distSqr = dx * dx + dy * dy; + //Com_Printf("distSqr = %d\n", distSqr); + + /* This code is here to help people that like the feel of the Logitech USB Gaming Mouse with the Win98 drivers. By empirical testing, the Windows drivers seem to be more heavily accelerated at the low end of the curve. */ + //N = in_mouseHighEndCutoff->value; + N = 1; + + if (distSqr < N*N) { + float dist, accel, scale; + + //m0 = in_mouseLowEndSlope->value; + m0 = 1; + dist = sqrt(distSqr); + accel = (((m0 - 1.0)/(N*N) * dist + (2.0 - 2.0*m0)/N) * dist + m0) * dist; + + scale = accel / dist; + //Com_Printf("dx = %d, dy = %d, dist = %f, accel = %f, scale = %f\n", dx, dy, dist, accel, scale); + + dx *= scale; + dy *= scale; + } +#endif + Posix_QueEvent( SE_MOUSE, dx, dy, 0, NULL ); + Posix_AddMousePollEvent( M_DELTAX, dx ); + Posix_AddMousePollEvent( M_DELTAY, dy ); + } +} + +inline bool OSX_LookupCharacter(unsigned short vkey, unsigned int modifiers, bool keyDownFlag, unsigned char *outChar) +{ + UInt32 translated; + UInt32 deadKeyState = 0; + UniChar unicodeString[16]; + UniCharCount actualStringLength = 0; + static UInt32 keyTranslateState = 0; + + // Only want character if Translate() returns a single character + if ( sKLuchrData ) { + UCKeyTranslate( (UCKeyboardLayout*)sKLuchrData, vkey, keyDownFlag ? kUCKeyActionDown : kUCKeyActionUp, modifiers, + LMGetKbdType(), 0, &deadKeyState, 16, &actualStringLength, unicodeString ); + + if ( actualStringLength == 1 ) { + *outChar = (unsigned char)unicodeString[0]; + return true; + } + } + else if ( sKLKCHRData ) { + translated = KeyTranslate( sKLKCHRData, vkey, &keyTranslateState ); + if ( ( translated & 0x00ff0000 ) == 0 ) { + *outChar = translated & 0xff; + return true; + } + } + return false; +} + +void OSX_ProcessKeyEvent( NSEvent *keyEvent, bool keyDownFlag ) { + unsigned char character; + unsigned int modifiers = 0; + unsigned short vkey = [ keyEvent keyCode ]; + + if ( [ keyEvent modifierFlags ] & NSAlphaShiftKeyMask ) + modifiers |= alphaLock; + if ( [ keyEvent modifierFlags ] & NSShiftKeyMask ) + modifiers |= shiftKey; + if ( [ keyEvent modifierFlags ] & NSControlKeyMask ) + modifiers |= controlKey; + if ( [ keyEvent modifierFlags ] & NSAlternateKeyMask ) + modifiers |= optionKey; + if ( [ keyEvent modifierFlags ] & NSCommandKeyMask ) + modifiers |= cmdKey; + modifiers >>= 8; + + int doomKey = (unsigned char)vkeyTable[vkey]; + Posix_QueEvent( SE_KEY, doomKey, keyDownFlag, 0, NULL ); + if ( keyDownFlag ) { + if ( OSX_LookupCharacter(vkey, modifiers, keyDownFlag, &character ) && + character != Sys_GetConsoleKey( false ) && character != Sys_GetConsoleKey( true ) ) { + Posix_QueEvent( SE_CHAR, character, 0, 0, NULL); + } + } + Posix_AddKeyboardPollEvent( doomKey, keyDownFlag ); + + return; +} + +void sendEventForMaskChangeInFlags( int quakeKey, unsigned int modifierMask, unsigned int oldModifierFlags, unsigned int newModifierFlags ) { + bool oldHadModifier, newHasModifier; + + oldHadModifier = (oldModifierFlags & modifierMask) != 0; + newHasModifier = (newModifierFlags & modifierMask) != 0; + if (oldHadModifier != newHasModifier) { + //NSLog(@"Key %d posted for modifier mask modifierMask", quakeKey); + Posix_QueEvent( SE_KEY, quakeKey, newHasModifier, 0, NULL); + Posix_AddKeyboardPollEvent( quakeKey, newHasModifier ); + } +} + +void processFlagsChangedEvent( NSEvent *flagsChangedEvent ) { + static int oldModifierFlags; + int newModifierFlags; + + newModifierFlags = [flagsChangedEvent modifierFlags]; + sendEventForMaskChangeInFlags( K_ALT, NSAlternateKeyMask, oldModifierFlags, newModifierFlags ); + sendEventForMaskChangeInFlags( K_CTRL, NSControlKeyMask, oldModifierFlags, newModifierFlags ); + sendEventForMaskChangeInFlags( K_SHIFT, NSShiftKeyMask, oldModifierFlags, newModifierFlags ); + oldModifierFlags = newModifierFlags; +} + +void processSystemDefinedEvent( NSEvent *systemDefinedEvent ) { + static int oldButtons = 0; + int buttonsDelta; + int buttons; + int isDown; + + if ( [systemDefinedEvent subtype] == 7 ) { + + if ( !mouseActive ) { + return; + } + + buttons = [systemDefinedEvent data2]; + buttonsDelta = oldButtons ^ buttons; + + //common->Printf( "uberbuttons: %08lx %08lx\n", buttonsDelta, buttons ); + + if (buttonsDelta & 1) { + isDown = buttons & 1; + Posix_QueEvent( SE_KEY, K_MOUSE1, isDown, 0, NULL); + Posix_AddMousePollEvent( M_ACTION1, isDown ); + } + + if (buttonsDelta & 2) { + isDown = buttons & 2; + Posix_QueEvent( SE_KEY, K_MOUSE2, isDown, 0, NULL); + Posix_AddMousePollEvent( M_ACTION2, isDown ); + } + + if (buttonsDelta & 4) { + isDown = buttons & 4; + Posix_QueEvent( SE_KEY, K_MOUSE3, isDown, 0, NULL); + Posix_AddMousePollEvent( M_ACTION3, isDown ); + } + + if (buttonsDelta & 8) { + isDown = buttons & 8; + Posix_QueEvent( SE_KEY, K_MOUSE4, isDown, 0, NULL); + Posix_AddMousePollEvent( M_ACTION4, isDown ); + } + + if (buttonsDelta & 16) { + isDown = buttons & 16; + Posix_QueEvent( SE_KEY, K_MOUSE5, isDown, 0, NULL); + Posix_AddMousePollEvent( M_ACTION5, isDown ); + } + + oldButtons = buttons; + } +} + +void processEvent( NSEvent *event ) { + NSEventType eventType; + + if ( !inputActive ) { + return; + } + + eventType = [ event type ]; + + switch ( eventType ) { + // These four event types are ignored since we do all of our mouse down/up process via the uber-mouse system defined event. We have to accept these events however since they get enqueued and the queue will fill up if we don't. + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSRightMouseDown: + case NSRightMouseUp: + //NSLog( @"ignore simple mouse event %@", event ); + return; + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + processMouseMovedEvent( event ); + return; + case NSKeyDown: + // Send ALL command key-ups to Quake, but not command key-downs, otherwise if the user hits a key, presses command, and lets up on the key, the key-up won't register. + if ( [ event modifierFlags ] & NSCommandKeyMask ) { + NSLog( @"command key up ignored: %@", event ); + break; + } + case NSKeyUp: + OSX_ProcessKeyEvent( event, eventType == NSKeyDown ); + return; + case NSFlagsChanged: + processFlagsChangedEvent( event ); + return; + case NSSystemDefined: + processSystemDefinedEvent( event ); + return; + case NSScrollWheel: + if ([event deltaY] < 0.0) { + Posix_QueEvent( SE_KEY, K_MWHEELDOWN, true, 0, NULL ); + Posix_QueEvent( SE_KEY, K_MWHEELDOWN, false, 0, NULL ); + Posix_AddMousePollEvent( M_DELTAZ, -1 ); + } else { + Posix_QueEvent( SE_KEY, K_MWHEELUP, true, 0, NULL ); + Posix_QueEvent( SE_KEY, K_MWHEELUP, false, 0, NULL ); + Posix_AddMousePollEvent( M_DELTAZ, 1 ); + } + return; + default: + //NSLog( @"handle event %@", event ); + break; + } + [NSApp sendEvent:event]; +} + +void Posix_PollInput( void ) { + NSEvent *event; + unsigned int eventMask; + + eventMask = NSAnyEventMask; + + while ( ( event = [ NSApp nextEventMatchingMask: eventMask + untilDate: distantPast + inMode: NSDefaultRunLoopMode + dequeue:YES ] ) ) { + processEvent( event ); + } +} + +void Sys_PreventMouseMovement( CGPoint point ) { + CGEventErr err; + + //common->Printf( "**** Calling CGAssociateMouseAndMouseCursorPosition(false)\n" ); + err = CGAssociateMouseAndMouseCursorPosition( false ); + if ( err != CGEventNoErr ) { + common->Error( "Could not disable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err ); + } + + // Put the mouse in the position we want to leave it at + err = CGWarpMouseCursorPosition( point ); + if ( err != CGEventNoErr ) { + common->Error( "Could not disable mouse movement, CGWarpMouseCursorPosition returned %d\n", err ); + } +} + +void Sys_ReenableMouseMovement() { + CGEventErr err; + + //common->Printf( "**** Calling CGAssociateMouseAndMouseCursorPosition(true)\n" ); + err = CGAssociateMouseAndMouseCursorPosition( true ); + if ( err != CGEventNoErr ) { + common->Error( "Could not reenable mouse movement, CGAssociateMouseAndMouseCursorPosition returned %d\n", err ); + } + + // Leave the mouse where it was -- don't warp here. +} + +void Sys_LockMouseInInputRect(CGRect rect) { + CGPoint center; + + center.x = rect.origin.x + rect.size.width / 2.0; + center.y = rect.origin.y + rect.size.height / 2.0; + + // Now, put the mouse in the middle of the input rect (anywhere over it would do) + // and don't allow it to move. This means that the user won't be able to accidentally + // select another application. + Sys_PreventMouseMovement(center); +} + +void Sys_SetMouseInputRect(CGRect newRect) { + inputRectValid = YES; + inputRect = newRect; + + if ( mouseActive ) { + Sys_LockMouseInInputRect( inputRect ); + } +} + +void IN_ActivateMouse( void ) { + if ( mouseActive ) { + return; + } + if ( inputRectValid ) { + // Make sure that if window moved we don't hose the user... + Sys_UpdateWindowMouseInputRect(); + } + Sys_LockMouseInInputRect( inputRect ); + CGDisplayHideCursor( Sys_DisplayToUse() ); + mouseActive = true; +} + +void IN_DeactivateMouse( void ) { + if ( !mouseActive ) { + return; + } + Sys_ReenableMouseMovement(); + CGDisplayShowCursor( Sys_DisplayToUse() ); + mouseActive = false; +} + +/* +=============== +Sys_MapCharForKey +=============== +*/ +unsigned char Sys_MapCharForKey( int key ) { + return (unsigned char)key; +} + +/* + =============== + Sys_GetConsoleKey + =============== + */ +unsigned char Sys_GetConsoleKey( bool shifted ) { + if ( vkeyTable == vkeyToDoom3Key_French ) { + return shifted ? '>' : '<'; + } + else { + return shifted ? '~' : '`'; + } + +} + diff --git a/sys/osx/macosx_glimp.h b/sys/osx/macosx_glimp.h new file mode 100644 index 000000000..a55db4265 --- /dev/null +++ b/sys/osx/macosx_glimp.h @@ -0,0 +1,17 @@ +#include +#include +#include +#ifndef GL_EXT_abgr +#include +#endif + +// This can be defined to use the CGLMacro.h support which avoids looking up +// the current context. +//#define USE_CGLMACROS + +#ifdef USE_CGLMACROS +#include "macosx_local.h" +#define cgl_ctx glw_state._cgl_ctx +#include +#endif + diff --git a/sys/osx/macosx_glimp.mm b/sys/osx/macosx_glimp.mm new file mode 100644 index 000000000..1e395be0c --- /dev/null +++ b/sys/osx/macosx_glimp.mm @@ -0,0 +1,1856 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +// -*- mode: objc -*- +#import "../../idlib/precompiled.h" + +#import "../../renderer/tr_local.h" + +#import "macosx_glimp.h" + +#import "macosx_local.h" +#import "macosx_sys.h" +#import "macosx_display.h" + +#import +#import + +#import +#import +#import + +static idCVar r_minDisplayRefresh( "r_minDisplayRefresh", "0", CVAR_ARCHIVE | CVAR_INTEGER, "" ); +static idCVar r_maxDisplayRefresh( "r_maxDisplayRefresh", "0", CVAR_ARCHIVE | CVAR_INTEGER, "" ); +static idCVar r_screen( "r_screen", "-1", CVAR_ARCHIVE | CVAR_INTEGER, "which display to use" ); + +static void GLW_InitExtensions( void ); +static bool CreateGameWindow( glimpParms_t parms ); +static unsigned long Sys_QueryVideoMemory(); +CGDisplayErr Sys_CaptureActiveDisplays(void); + +glwstate_t glw_state; +static bool isHidden = false; + +@interface NSOpenGLContext (CGLContextAccess) +- (CGLContextObj) cglContext; +@end + +@implementation NSOpenGLContext (CGLContextAccess) +- (CGLContextObj) cglContext; +{ + return _contextAuxiliary; +} +@end + +/* +============ +CheckErrors +============ +*/ +void CheckErrors( void ) { + GLenum err; + + err = qglGetError(); + if ( err != GL_NO_ERROR ) { + common->Error( "glGetError: %s\n", qglGetString( err ) ); + } +} + +#if !defined(NDEBUG) && defined(QGL_CHECK_GL_ERRORS) + +unsigned int QGLBeginStarted = 0; + +void QGLErrorBreak(void) { } + +void QGLCheckError( const char *message ) { + GLenum error; + static unsigned int errorCount = 0; + + error = _glGetError(); + if (error != GL_NO_ERROR) { + if (errorCount == 100) { + common->Printf("100 GL errors printed ... disabling further error reporting.\n"); + } else if (errorCount < 100) { + if (errorCount == 0) { + common->Warning("BREAK ON QGLErrorBreak to stop at the GL errors\n"); + } + common->Warning("OpenGL Error(%s): 0x%04x -- %s\n", message, (int)error, gluErrorString(error)); + QGLErrorBreak(); + } + errorCount++; + } +} +#endif + +/* +** GLimp_SetMode +*/ + +bool GLimp_SetMode( glimpParms_t parms ) { + if ( !CreateGameWindow( parms ) ) { + common->Printf( "GLimp_SetMode: window could not be created!\n" ); + return false; + } + + glConfig.vidWidth = parms.width; + glConfig.vidHeight = parms.height; + glConfig.isFullscreen = parms.fullScreen; + + // draw something to show that GL is alive + qglClearColor( 0.5, 0.5, 0.7, 0 ); + qglClear( GL_COLOR_BUFFER_BIT ); + GLimp_SwapBuffers(); + + qglClearColor( 0.5, 0.5, 0.7, 0 ); + qglClear( GL_COLOR_BUFFER_BIT ); + GLimp_SwapBuffers(); + + Sys_UnfadeScreen( Sys_DisplayToUse(), NULL ); + + CheckErrors(); + + return true; +} + +/* +================= +GetPixelAttributes +================= +*/ + +#define ADD_ATTR(x) \ + do { \ + if (attributeIndex >= attributeSize) { \ + attributeSize *= 2; \ + pixelAttributes = (NSOpenGLPixelFormatAttribute *)NSZoneRealloc(NULL, pixelAttributes, sizeof(*pixelAttributes) * attributeSize); \ + } \ + pixelAttributes[attributeIndex] = (NSOpenGLPixelFormatAttribute)x; \ + attributeIndex++; \ + if ( verbose ) { \ + common->Printf( "Adding pixel attribute: %d (%s)\n", x, #x); \ + } \ + } while(0) + +static NSOpenGLPixelFormatAttribute *GetPixelAttributes( unsigned int multisamples ) { + NSOpenGLPixelFormatAttribute *pixelAttributes; + unsigned int attributeIndex = 0; + unsigned int attributeSize = 128; + int verbose; + unsigned int colorDepth; + unsigned int desktopColorDepth; + unsigned int depthBits; + unsigned int stencilBits; + unsigned int buffers; + + verbose = 0; + + pixelAttributes = (NSOpenGLPixelFormatAttribute *)NSZoneMalloc(NULL, sizeof(*pixelAttributes) * attributeSize); + + // only greater or equal attributes will be selected + ADD_ATTR( NSOpenGLPFAMinimumPolicy ); + ADD_ATTR( 1 ); + + if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + ADD_ATTR(NSOpenGLPFAFullScreen); + } + + ADD_ATTR(NSOpenGLPFAScreenMask); + ADD_ATTR(CGDisplayIDToOpenGLDisplayMask(Sys_DisplayToUse())); + + // Require hardware acceleration + ADD_ATTR(NSOpenGLPFAAccelerated); + + // Require double-buffer + ADD_ATTR(NSOpenGLPFADoubleBuffer); + + // color bits + ADD_ATTR(NSOpenGLPFAColorSize); + colorDepth = 32; + if ( !cvarSystem->GetCVarBool( "r_fullscreen" ) ) { + desktopColorDepth = [[glw_state.desktopMode objectForKey: (id)kCGDisplayBitsPerPixel] intValue]; + if ( desktopColorDepth != 32 ) { + common->Warning( "Desktop display colors should be 32 bits for window rendering" ); + } + } + ADD_ATTR(colorDepth); + + // Specify the number of depth bits + ADD_ATTR( NSOpenGLPFADepthSize ); + depthBits = 24; + ADD_ATTR( depthBits ); + + // Specify the number of stencil bits + stencilBits = 8; + ADD_ATTR( NSOpenGLPFAStencilSize ); + ADD_ATTR( stencilBits ); + + // Specify destination alpha + ADD_ATTR( NSOpenGLPFAAlphaSize ); + ADD_ATTR( 8 ); + + if ( multisamples ) { + buffers = 1; + ADD_ATTR( NSOpenGLPFASampleBuffers ); + ADD_ATTR( buffers ); + ADD_ATTR( NSOpenGLPFASamples ); + ADD_ATTR( multisamples ); + } + + // Terminate the list + ADD_ATTR(0); + + return pixelAttributes; +} + +void Sys_UpdateWindowMouseInputRect(void) { + NSRect windowRect, screenRect; + NSScreen *screen; + + /* + + // TTimo - I guess glw_state.window is bogus .. getting crappy data out of this + + // It appears we need to flip the coordinate system here. This means we need + // to know the size of the screen. + screen = [glw_state.window screen]; + screenRect = [screen frame]; + windowRect = [glw_state.window frame]; + windowRect.origin.y = screenRect.size.height - (windowRect.origin.y + windowRect.size.height); + + Sys_SetMouseInputRect( CGRectMake( windowRect.origin.x, windowRect.origin.y, windowRect.size.width, windowRect.size.height ) ); + */ + + Sys_SetMouseInputRect( CGDisplayBounds( glw_state.display ) ); +} + +// This is needed since CGReleaseAllDisplays() restores the gamma on the displays and we want to fade it up rather than just flickering all the displays +static void ReleaseAllDisplays() { + CGDisplayCount displayIndex; + + common->Printf("Releasing displays\n"); + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + CGDisplayRelease(glw_state.originalDisplayGammaTables[displayIndex].display); + } +} + +/* +================= +CreateGameWindow +================= +*/ +static bool CreateGameWindow( glimpParms_t parms ) { + const char *windowed[] = { "Windowed", "Fullscreen" }; + NSOpenGLPixelFormatAttribute *pixelAttributes; + NSOpenGLPixelFormat *pixelFormat; + CGDisplayErr err; + unsigned int multisamples; + const long swap_limit = false; + int nsOpenGLCPSwapLimit = 203; + + glw_state.display = Sys_DisplayToUse(); + glw_state.desktopMode = (NSDictionary *)CGDisplayCurrentMode( glw_state.display ); + if ( !glw_state.desktopMode ) { + common->Error( "Could not get current graphics mode for display 0x%08x\n", glw_state.display ); + } + + common->Printf( " %d %d %s\n", parms.width, parms.height, windowed[ parms.fullScreen ] ); + + if (parms.fullScreen) { + + // We'll set up the screen resolution first in case that effects the list of pixel + // formats that are available (for example, a smaller frame buffer might mean more + // bits for depth/stencil buffers). Allow stretched video modes if we are in fallback mode. + glw_state.gameMode = Sys_GetMatchingDisplayMode(parms); + if (!glw_state.gameMode) { + common->Printf( "Unable to find requested display mode.\n"); + return false; + } + + // Fade all screens to black + // Sys_FadeScreens(); + + err = Sys_CaptureActiveDisplays(); + if ( err != CGDisplayNoErr ) { + CGDisplayRestoreColorSyncSettings(); + common->Printf( " Unable to capture displays err = %d\n", err ); + return false; + } + + err = CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.gameMode); + if ( err != CGDisplayNoErr ) { + CGDisplayRestoreColorSyncSettings(); + ReleaseAllDisplays(); + common->Printf( " Unable to set display mode, err = %d\n", err ); + return false; + } + } else { + glw_state.gameMode = glw_state.desktopMode; + } + + // Get the GL pixel format + pixelFormat = nil; + multisamples = cvarSystem->GetCVarInteger( "r_multiSamples" ); + while ( !pixelFormat ) { + pixelAttributes = GetPixelAttributes( multisamples ); + pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: pixelAttributes] autorelease]; + NSZoneFree(NULL, pixelAttributes); + if ( pixelFormat || multisamples == 0 ) + break; + multisamples >>= 1; + } + cvarSystem->SetCVarInteger( "r_multiSamples", multisamples ); + + if (!pixelFormat) { + CGDisplayRestoreColorSyncSettings(); + CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.desktopMode); + ReleaseAllDisplays(); + common->Printf( " No pixel format found\n"); + return false; + } + + // Create a context with the desired pixel attributes + OSX_SetGLContext([[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: nil]); + if ( !OSX_GetNSGLContext() ) { + CGDisplayRestoreColorSyncSettings(); + CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.desktopMode); + ReleaseAllDisplays(); + common->Printf( "... +[NSOpenGLContext createWithFormat:share:] failed.\n" ); + return false; + } +#ifdef __ppc__ + long system_version = 0; + Gestalt( gestaltSystemVersion, &system_version ); + if ( parms.width <= 1024 && parms.height <= 768 && system_version <= 0x1045 ) { + [ OSX_GetNSGLContext() setValues: &swap_limit forParameter: (NSOpenGLContextParameter)nsOpenGLCPSwapLimit ]; + } +#endif + + if ( !parms.fullScreen ) { + NSScreen* screen; + NSRect windowRect; + int displayIndex; + int displayCount; + + displayIndex = r_screen.GetInteger(); + displayCount = [[NSScreen screens] count]; + if ( displayIndex < 0 || displayIndex >= displayCount ) { + screen = [NSScreen mainScreen]; + } else { + screen = [[NSScreen screens] objectAtIndex:displayIndex]; + } + + NSRect r = [screen frame]; + windowRect.origin.x = ((short)r.size.width - parms.width) / 2; + windowRect.origin.y = ((short)r.size.height - parms.height) / 2; + windowRect.size.width = parms.width; + windowRect.size.height = parms.height; + + glw_state.window = [NSWindow alloc]; + [glw_state.window initWithContentRect:windowRect styleMask:NSTitledWindowMask backing:NSBackingStoreRetained defer:NO screen:screen]; + + [glw_state.window setTitle: @GAME_NAME]; + + [glw_state.window orderFront: nil]; + + // Always get mouse moved events (if mouse support is turned off (rare) + // the event system will filter them out. + [glw_state.window setAcceptsMouseMovedEvents: YES]; + + // Direct the context to draw in this window + [OSX_GetNSGLContext() setView: [glw_state.window contentView]]; + + // Sync input rect with where the window actually is... + Sys_UpdateWindowMouseInputRect(); + } else { + CGLError err; + + glw_state.window = NULL; + + err = CGLSetFullScreen(OSX_GetCGLContext()); + if (err) { + CGDisplayRestoreColorSyncSettings(); + CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.desktopMode); + ReleaseAllDisplays(); + common->Printf("CGLSetFullScreen -> %d (%s)\n", err, CGLErrorString(err)); + return false; + } + + Sys_SetMouseInputRect( CGDisplayBounds( glw_state.display ) ); + } + +#ifndef USE_CGLMACROS + // Make this the current context + OSX_GLContextSetCurrent(); +#endif + + // Store off the pixel format attributes that we actually got + [pixelFormat getValues: (long *) &glConfig.colorBits forAttribute: NSOpenGLPFAColorSize forVirtualScreen: 0]; + [pixelFormat getValues: (long *) &glConfig.depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0]; + [pixelFormat getValues: (long *) &glConfig.stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0]; + + glConfig.displayFrequency = [[glw_state.gameMode objectForKey: (id)kCGDisplayRefreshRate] intValue]; + + common->Printf( "ok\n" ); + + return true; +} + +// This can be used to temporarily disassociate the GL context from the screen so that CoreGraphics can be used to draw to the screen. +void Sys_PauseGL () { + if (!glw_state.glPauseCount) { + qglFinish (); // must do this to ensure the queue is complete + + // Have to call both to actually deallocate kernel resources and free the NSSurface + CGLClearDrawable(OSX_GetCGLContext()); + [OSX_GetNSGLContext() clearDrawable]; + } + glw_state.glPauseCount++; +} + +// This can be used to reverse the pausing caused by Sys_PauseGL() +void Sys_ResumeGL () { + if (glw_state.glPauseCount) { + glw_state.glPauseCount--; + if (!glw_state.glPauseCount) { + if (!glConfig.isFullscreen) { + [OSX_GetNSGLContext() setView: [glw_state.window contentView]]; + } else { + CGLError err; + + err = CGLSetFullScreen(OSX_GetCGLContext()); + if (err) + common->Printf("CGLSetFullScreen -> %d (%s)\n", err, CGLErrorString(err)); + } + } + } +} + +/* +=================== +GLimp_Init + +Don't return unless OpenGL has been properly initialized +=================== +*/ + +#ifdef OMNI_TIMER +static void GLImp_Dump_Stamp_List_f(void) { + OTStampListDumpToFile(glThreadStampList, "/tmp/gl_stamps"); +} +#endif + +bool GLimp_Init( glimpParms_t parms ) { + char *buf; + + common->Printf( "Initializing OpenGL subsystem\n" ); + common->Printf( " fullscreen: %s\n", cvarSystem->GetCVarBool( "r_fullscreen" ) ? "yes" : "no" ); + + Sys_StoreGammaTables(); + + if ( !Sys_QueryVideoMemory() ) { + common->Error( "Could not initialize OpenGL. There does not appear to be an OpenGL-supported video card in your system.\n" ); + } + + if ( !GLimp_SetMode( parms ) ) { + common->Warning( "Could not initialize OpenGL\n" ); + return false; + } + + common->Printf( "------------------\n" ); + + // get our config strings + glConfig.vendor_string = (const char *)qglGetString( GL_VENDOR ); + glConfig.renderer_string = (const char *)qglGetString( GL_RENDERER ); + glConfig.version_string = (const char *)qglGetString( GL_VERSION ); + glConfig.extensions_string = (const char *)qglGetString( GL_EXTENSIONS ); + + // + // chipset specific configuration + // + buf = (char *)malloc(strlen(glConfig.renderer_string) + 1); + strcpy( buf, glConfig.renderer_string ); + + // Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string ); + free(buf); + + GLW_InitExtensions(); + + /* +#ifndef USE_CGLMACROS + if (!r_enablerender->integer) + OSX_GLContextClearCurrent(); +#endif + */ + return true; +} + + +/* +** GLimp_SwapBuffers +** +** Responsible for doing a swapbuffers and possibly for other stuff +** as yet to be determined. Probably better not to make this a GLimp +** function and instead do a call to GLimp_SwapBuffers. +*/ +void GLimp_SwapBuffers( void ) { + if ( r_swapInterval.IsModified() ) { + r_swapInterval.ClearModified(); + } + +#if !defined(NDEBUG) && defined(QGL_CHECK_GL_ERRORS) + QGLCheckError("GLimp_EndFrame"); +#endif + + if (!glw_state.glPauseCount && !isHidden) { + glw_state.bufferSwapCount++; + [OSX_GetNSGLContext() flushBuffer]; + } + + /* + // Enable turning off GL at any point for performance testing + if (OSX_GLContextIsCurrent() != r_enablerender->integer) { + if (r_enablerender->integer) { + common->Printf("--- Enabling Renderer ---\n"); + OSX_GLContextSetCurrent(); + } else { + common->Printf("--- Disabling Renderer ---\n"); + OSX_GLContextClearCurrent(); + } + } + */ +} + +/* +** GLimp_Shutdown +** +** This routine does all OS specific shutdown procedures for the OpenGL +** subsystem. Under OpenGL this means NULLing out the current DC and +** HGLRC, deleting the rendering context, and releasing the DC acquired +** for the window. The state structure is also nulled out. +** +*/ + +static void _GLimp_RestoreOriginalVideoSettings() { + CGDisplayErr err; + + // CGDisplayCurrentMode lies because we've captured the display and thus we won't + // get any notifications about what the current display mode really is. For now, + // we just always force it back to what mode we remember the desktop being in. + if (glConfig.isFullscreen) { + err = CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.desktopMode); + if ( err != CGDisplayNoErr ) + common->Printf( " Unable to restore display mode!\n" ); + + ReleaseAllDisplays(); + } +} + +void GLimp_Shutdown( void ) { + CGDisplayCount displayIndex; + + common->Printf("----- Shutting down GL -----\n"); + + Sys_FadeScreen(Sys_DisplayToUse()); + + if (OSX_GetNSGLContext()) { +#ifndef USE_CGLMACROS + OSX_GLContextClearCurrent(); +#endif + // Have to call both to actually deallocate kernel resources and free the NSSurface + CGLClearDrawable(OSX_GetCGLContext()); + [OSX_GetNSGLContext() clearDrawable]; + + [OSX_GetNSGLContext() release]; + OSX_SetGLContext((id)nil); + } + + _GLimp_RestoreOriginalVideoSettings(); + + Sys_UnfadeScreens(); + + // Restore the original gamma if needed. + // if (glConfig.deviceSupportsGamma) { + // common->Printf("Restoring ColorSync settings\n"); + // CGDisplayRestoreColorSyncSettings(); + // } + + if (glw_state.window) { + [glw_state.window release]; + glw_state.window = nil; + } + + if (glw_state.log_fp) { + fclose(glw_state.log_fp); + glw_state.log_fp = 0; + } + + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + free(glw_state.originalDisplayGammaTables[displayIndex].red); + free(glw_state.originalDisplayGammaTables[displayIndex].blue); + free(glw_state.originalDisplayGammaTables[displayIndex].green); + } + free(glw_state.originalDisplayGammaTables); + if (glw_state.tempTable.red) { + free(glw_state.tempTable.red); + free(glw_state.tempTable.blue); + free(glw_state.tempTable.green); + } + if (glw_state.inGameTable.red) { + free(glw_state.inGameTable.red); + free(glw_state.inGameTable.blue); + free(glw_state.inGameTable.green); + } + + memset(&glConfig, 0, sizeof(glConfig)); + // memset(&glState, 0, sizeof(glState)); + memset(&glw_state, 0, sizeof(glw_state)); + + common->Printf("----- Done shutting down GL -----\n"); +} + +/* +=============== +GLimp_LogComment +=============== +*/ +void GLimp_LogComment( char *comment ) { } + +/* +=============== +GLimp_SetGamma +=============== +*/ +void GLimp_SetGamma(unsigned short red[256], + unsigned short green[256], + unsigned short blue[256]) { + CGGammaValue redGamma[256], greenGamma[256], blueGamma[256]; + CGTableCount i; + CGDisplayErr err; + + for (i = 0; i < 256; i++) { + redGamma[i] = red[i] / 65535.0; + greenGamma[i] = green[i] / 65535.0; + blueGamma[i] = blue[i] / 65535.0; + } + + err = CGSetDisplayTransferByTable(glw_state.display, 256, redGamma, greenGamma, blueGamma); + if (err != CGDisplayNoErr) { + common->Printf("GLimp_SetGamma: CGSetDisplayTransferByByteTable returned %d.\n", err); + } + + // Store the gamma table that we ended up using so we can reapply it later when unhiding or to work around the bug where if you leave the game sitting and the monitor sleeps, when it wakes, the gamma isn't reset. + glw_state.inGameTable.display = glw_state.display; + Sys_GetGammaTable(&glw_state.inGameTable); +} + +/*****************************************************************************/ + +#pragma mark - +#pragma mark ¥ ATI_fragment_shader + +static GLuint sGeneratingProgram = 0; +static int sCurrentPass; +static char sConstString[4096]; +static char sPassString[2][4096]; +static int sOpUsed; +static int sConstUsed; +static int sConst[8]; +static GLfloat sConstVal[8][4]; + +static void _endPass (void) { + if (!sOpUsed) return; + sOpUsed = 0; + sCurrentPass ++; +} + +GLuint glGenFragmentShadersATI (GLuint ID) { + qglGenProgramsARB(1, &ID); + return ID; +} + +void glBindFragmentShaderATI (GLuint ID) { + qglBindProgramARB(GL_TEXT_FRAGMENT_SHADER_ATI, ID); +} + +void glDeleteFragmentShaderATI (GLuint ID) { +// qglDeleteProgramsARB(1, &ID); +} + +void glBeginFragmentShaderATI (void) { + int i; + + sConstString[0] = 0; + for (i = 0; i < 8; i ++) + sConst[i] = 0; + + sOpUsed = 0; + sPassString[0][0] = 0; + sPassString[1][0] = 0; + + sCurrentPass = 0; + sGeneratingProgram = 1; +} + +void glEndFragmentShaderATI (void) { + GLint errPos; + int i; + char fragString[4096]; + + sGeneratingProgram = 0; + + // header + strcpy(fragString, "!!ATIfs1.0\n"); + + // constants + if (sConstString[0] || sConstUsed) { + strcat (fragString, "StartConstants;\n"); + if (sConstUsed) { + for (i = 0; i < 8; i ++) { + if (sConst[i] == 1) { + char str[128]; + sprintf (str, " CONSTANT c%d = program.env[%d];\n", i, i); + strcat (fragString, str); + } + } + } + if (sConstString[0]) { + strcat (fragString, sConstString); + } + strcat (fragString, "EndConstants;\n\n"); + } + + if (sCurrentPass == 0) { + strcat(fragString, "StartOutputPass;\n"); + strcat(fragString, sPassString[0]); + strcat(fragString, "EndPass;\n"); + } else { + strcat(fragString, "StartPrelimPass;\n"); + strcat(fragString, sPassString[0]); + strcat(fragString, "EndPass;\n\n"); + + strcat(fragString, "StartOutputPass;\n"); + strcat(fragString, sPassString[1]); + strcat(fragString, "EndPass;\n"); + } + + qglProgramStringARB(GL_TEXT_FRAGMENT_SHADER_ATI, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragString), fragString); + qglGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); + if(errPos != -1) { + const GLubyte *errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + common->Warning("WARNING: glError at %d:%s when compiling atiFragmentShader %s", errPos, errString, fragString); + } +} + + +void glSetFragmentShaderConstantATI (GLuint num, const GLfloat *val) { + int constNum = num-GL_CON_0_ATI; + if (sGeneratingProgram) { + char str[128]; + sprintf (str, " CONSTANT c%d = { %f, %f, %f, %f };\n", constNum, val[0], val[1], val[2], val[3]); + strcat (sConstString, str); + sConst[constNum] = 2; + } + else { + // According to Duane, frequent setting of fragment shader constants, even if they contain + // the same value, will cause a performance hit. + // According to Chris Bentley at ATI, this performance hit appears if you are using + // many different fragment shaders in each scene. + // So, we cache those values and only set the constants if they are different. + if (memcmp (val, sConstVal[constNum], sizeof(GLfloat)*8*4) != 0) + { + qglProgramEnvParameter4fvARB (GL_TEXT_FRAGMENT_SHADER_ATI, num-GL_CON_0_ATI, val); + memcpy (sConstVal[constNum], val, sizeof(GLfloat)*8*4); + } + } +} + +char *makeArgStr(GLuint arg) { + // Since we return "str", it needs to be static to ensure that it retains + // its value outside this routine. + static char str[128]; + + strcpy (str, ""); + + if ( arg >= GL_REG_0_ATI && arg <= GL_REG_5_ATI ) { + sprintf(str, "r%d", arg - GL_REG_0_ATI); + } else if(arg >= GL_CON_0_ATI && arg <= GL_CON_7_ATI) { + if(!sConst[arg - GL_CON_0_ATI]) { + sConstUsed = 1; + sConst[arg - GL_CON_0_ATI] = 1; + } + sprintf(str, "c%d", arg - GL_CON_0_ATI); + } else if( arg >= GL_TEXTURE0_ARB && arg <= GL_TEXTURE31_ARB ) { + sprintf(str, "t%d", arg - GL_TEXTURE0_ARB); + } else if( arg == GL_PRIMARY_COLOR_ARB ) { + strcpy(str, "color0"); + } else if(arg == GL_SECONDARY_INTERPOLATOR_ATI) { + strcpy(str, "color1"); + } else if (arg == GL_ZERO) { + strcpy(str, "0"); + } else if (arg == GL_ONE) { + strcpy(str, "1"); + } else { + common->Warning("makeArgStr: bad arg value\n"); + } + return str; +} + +void glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle) { + char str[128] = "\0"; + _endPass(); + + switch(swizzle) { + case GL_SWIZZLE_STR_ATI: + sprintf(str, " PassTexCoord r%d, %s.str;\n", dst - GL_REG_0_ATI, makeArgStr(coord)); + break; + case GL_SWIZZLE_STQ_ATI: + sprintf(str, " PassTexCoord r%d, %s.stq;\n", dst - GL_REG_0_ATI, makeArgStr(coord)); + break; + case GL_SWIZZLE_STR_DR_ATI: + sprintf(str, " PassTexCoord r%d, %s.str_dr;\n", dst - GL_REG_0_ATI, makeArgStr(coord)); + break; + case GL_SWIZZLE_STQ_DQ_ATI: + sprintf(str, " PassTexCoord r%d, %s.stq_dq;\n", dst - GL_REG_0_ATI, makeArgStr(coord)); + break; + default: + common->Warning("glPassTexCoordATI invalid swizzle;"); + break; + } + strcat(sPassString[sCurrentPass], str); +} + +void glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle) { + char str[128] = "\0"; + _endPass(); + + switch(swizzle) { + case GL_SWIZZLE_STR_ATI: + sprintf(str, " SampleMap r%d, %s.str;\n", dst - GL_REG_0_ATI, makeArgStr(interp)); + break; + case GL_SWIZZLE_STQ_ATI: + sprintf(str, " SampleMap r%d, %s.stq;\n", dst - GL_REG_0_ATI, makeArgStr(interp)); + break; + case GL_SWIZZLE_STR_DR_ATI: + sprintf(str, " SampleMap r%d, %s.str_dr;\n", dst - GL_REG_0_ATI, makeArgStr(interp)); + break; + case GL_SWIZZLE_STQ_DQ_ATI: + sprintf(str, " SampleMap r%d, %s.stq_dq;\n", dst - GL_REG_0_ATI, makeArgStr(interp)); + break; + default: + common->Warning("glSampleMapATI invalid swizzle;"); + break; + } + strcat(sPassString[sCurrentPass], str); +} + +char *makeMaskStr(GLuint mask) { + // Since we return "str", it needs to be static to ensure that it retains + // its value outside this routine. + static char str[128]; + + strcpy (str, ""); + + switch (mask) { + case GL_NONE: + str[0] = '\0'; + break; + case GL_RGBA: + strcpy(str, ".rgba"); + break; + case GL_RGB: + strcpy(str, ".rgb"); + break; + case GL_RED: + strcpy(str, ".r"); + break; + case GL_GREEN: + strcpy(str, ".g"); + break; + case GL_BLUE: + strcpy(str, ".b"); + break; + case GL_ALPHA: + strcpy(str, ".a"); + break; + default: + strcpy(str, "."); + if( mask & GL_RED_BIT_ATI ) + strcat(str, "r"); + if( mask & GL_GREEN_BIT_ATI ) + strcat(str, "g"); + if( mask & GL_BLUE_BIT_ATI ) + strcat(str, "b"); + break; + } + + return str; +} + +char *makeDstModStr(GLuint mod) { + // Since we return "str", it needs to be static to ensure that it retains + // its value outside this routine. + static char str[128]; + + strcpy (str, ""); + + if( mod == GL_NONE) { + str[0] = '\0'; + return str; + } + if( mod & GL_2X_BIT_ATI) { + strcat(str, ".2x"); + } + + if( mod & GL_4X_BIT_ATI) { + strcat(str, ".4x"); + } + + if( mod & GL_8X_BIT_ATI) { + strcat(str, ".8x"); + } + + if( mod & GL_SATURATE_BIT_ATI) { + strcat(str, ".sat"); + } + + if( mod & GL_HALF_BIT_ATI) { + strcat(str, ".half"); + } + + if( mod & GL_QUARTER_BIT_ATI) { + strcat(str, ".quarter"); + } + + if( mod & GL_EIGHTH_BIT_ATI) { + strcat(str, ".eighth"); + } + + return str; +} + +char *makeArgModStr(GLuint mod) { + // Since we return "str", it needs to be static to ensure that it retains + // its value outside this routine. + static char str[128]; + + strcpy (str, ""); + + if( mod == GL_NONE) { + str[0] = '\0'; + return str; + } + if( mod & GL_NEGATE_BIT_ATI) { + strcat(str, ".neg"); + } + + if( mod & GL_2X_BIT_ATI) { + strcat(str, ".2x"); + } + + if( mod & GL_BIAS_BIT_ATI) { + strcat(str, ".bias"); + } + + if( mod & GL_COMP_BIT_ATI) { + strcat(str, ".comp"); + } + + return str; +} + +void glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) { + char str[128] = "\0"; + + sOpUsed = 1; + + switch(op) { + // Unary operators + case GL_MOV_ATI: + sprintf(str, " MOV r%d", dst - GL_REG_0_ATI); + break; + default: + common->Warning("glColorFragmentOp1ATI invalid op;\n"); + break; + } + if(dstMask != GL_NONE) { + strcat(str, makeMaskStr(dstMask)); + } + else { + strcat(str, ".rgb" ); + } + + if(dstMod != GL_NONE) { + strcat(str, makeDstModStr(dstMod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg1)); + if(arg1Rep != GL_NONE) { + strcat(str, makeMaskStr(arg1Rep)); + } + if(arg1Mod != GL_NONE) { + strcat(str, makeArgModStr(arg1Mod)); + } + strcat(str, ";\n"); + + strcat(sPassString[sCurrentPass], str); +} + +void glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) { + char str[128] = "\0"; + + if (!sOpUsed) + sprintf(str,"\n"); + sOpUsed = 1; + + switch(op) { + // Unary operators - fall back to Op1 routine. + case GL_MOV_ATI: + glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod); + return; + + // Binary operators + case GL_ADD_ATI: + sprintf(str, " ADD r%d", dst - GL_REG_0_ATI); + break; + case GL_MUL_ATI: + sprintf(str, " MUL r%d", dst - GL_REG_0_ATI); + break; + case GL_SUB_ATI: + sprintf(str, " SUB r%d", dst - GL_REG_0_ATI); + break; + case GL_DOT3_ATI: + sprintf(str, " DOT3 r%d", dst - GL_REG_0_ATI); + break; + case GL_DOT4_ATI: + sprintf(str, " DOT4 r%d", dst - GL_REG_0_ATI); + break; + default: + common->Warning("glColorFragmentOp2ATI invalid op;"); + break; + } + if(dstMask != GL_NONE) { + strcat(str, makeMaskStr(dstMask)); + } + else { + strcat(str, ".rgb" ); + } + if(dstMod != GL_NONE) { + strcat(str, makeDstModStr(dstMod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg1)); +// if(arg1Rep != GL_NONE) + strcat(str, makeMaskStr(arg1Rep)); + if(arg1Mod != GL_NONE) { + strcat(str, makeArgModStr(arg1Mod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg2)); +// if(arg2Rep != GL_NONE) + strcat(str, makeMaskStr(arg2Rep)); + if(arg2Mod != GL_NONE) { + strcat(str, makeArgModStr(arg2Mod)); + } + strcat(str, ";\n"); + + strcat(sPassString[sCurrentPass], str); +} + +void glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) { + char str[128] = "\0"; + + sOpUsed = 1; + + switch(op) { + // Unary operators - fall back to Op1 routine. + case GL_MOV_ATI: + glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod); + return; + + // Binary operators - fall back to Op2 routine. + case GL_ADD_ATI: + case GL_MUL_ATI: + case GL_SUB_ATI: + case GL_DOT3_ATI: + case GL_DOT4_ATI: + glColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod); + break; + + // Ternary operators + case GL_MAD_ATI: + sprintf(str, " MAD r%d", dst - GL_REG_0_ATI); + break; + case GL_LERP_ATI: + sprintf(str, " LERP r%d", dst - GL_REG_0_ATI); + break; + case GL_CND_ATI: + sprintf(str, " CND r%d", dst - GL_REG_0_ATI); + break; + case GL_CND0_ATI: + sprintf(str, " CND0 r%d", dst - GL_REG_0_ATI); + break; + case GL_DOT2_ADD_ATI: + sprintf(str, " DOT2ADD r%d", dst - GL_REG_0_ATI); + break; + default: + common->Warning("glColorFragmentOp3ATI invalid op;"); + break; + } + + if(dstMask != GL_NONE) { + strcat(str, makeMaskStr(dstMask)); + } + else { + strcat(str, ".rgb" ); + } + if(dstMod != GL_NONE) { + strcat(str, makeDstModStr(dstMod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg1)); + if(arg1Rep != GL_NONE) { + strcat(str, makeMaskStr(arg1Rep)); + } + if(arg1Mod != GL_NONE) { + strcat(str, makeArgModStr(arg1Mod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg2)); + if(arg2Rep != GL_NONE) { + strcat(str, makeMaskStr(arg2Rep)); + } + if(arg2Mod != GL_NONE) { + strcat(str, makeArgModStr(arg2Mod)); + } + strcat(str, ", "); + + strcat(str, makeArgStr(arg3)); + if(arg3Rep != GL_NONE) { + strcat(str, makeMaskStr(arg3Rep)); + } + if(arg3Mod != GL_NONE) { + strcat(str, makeArgModStr(arg3Mod)); + } + strcat(str, ";\n"); + + strcat(sPassString[sCurrentPass], str); +} + +void glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) { + glColorFragmentOp1ATI ( op, dst, GL_ALPHA, dstMod, arg1, arg1Rep, arg1Mod); +} + +void glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) { + glColorFragmentOp2ATI ( op, dst, GL_ALPHA, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod); +} + +void glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) { + glColorFragmentOp3ATI ( op, dst, GL_ALPHA, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod); +} +#pragma mark - + +GLExtension_t GLimp_ExtensionPointer(const char *name) { + NSSymbol symbol; + char *symbolName; + + // special case for ATI_fragment_shader calls to map to ATI_text_fragment_shader routines + if (!strcmp(name, "glGenFragmentShadersATI")) { + return (GLExtension_t)glGenFragmentShadersATI; + } + if (!strcmp(name, "glBindFragmentShaderATI")) { + return (GLExtension_t)glBindFragmentShaderATI; + } + if (!strcmp(name, "glDeleteFragmentShaderATI")) { + return (GLExtension_t)glDeleteFragmentShaderATI; + } + if (!strcmp(name, "glBeginFragmentShaderATI")) { + return (GLExtension_t)glBeginFragmentShaderATI; + } + if (!strcmp(name, "glEndFragmentShaderATI")) { + return (GLExtension_t)glEndFragmentShaderATI; + } + if (!strcmp(name, "glPassTexCoordATI")) { + return (GLExtension_t)glPassTexCoordATI; + } + if (!strcmp(name, "glSampleMapATI")) { + return (GLExtension_t)glSampleMapATI; + } + if (!strcmp(name, "glColorFragmentOp1ATI")) { + return (GLExtension_t)glColorFragmentOp1ATI; + } + if (!strcmp(name, "glColorFragmentOp2ATI")) { + return (GLExtension_t)glColorFragmentOp2ATI; + } + if (!strcmp(name, "glColorFragmentOp3ATI")) { + return (GLExtension_t)glColorFragmentOp3ATI; + } + if (!strcmp(name, "glAlphaFragmentOp1ATI")) { + return (GLExtension_t)glAlphaFragmentOp1ATI; + } + if (!strcmp(name, "glAlphaFragmentOp2ATI")) { + return (GLExtension_t)glAlphaFragmentOp2ATI; + } + if (!strcmp(name, "glAlphaFragmentOp3ATI")) { + return (GLExtension_t)glAlphaFragmentOp3ATI; + } + if (!strcmp(name, "glSetFragmentShaderConstantATI")) { + return (GLExtension_t)glSetFragmentShaderConstantATI; + } + + // Prepend a '_' for the Unix C symbol mangling convention + symbolName = (char *)alloca(strlen(name) + 2); + strcpy(symbolName + 1, name); + symbolName[0] = '_'; + + if ( !NSIsSymbolNameDefined( symbolName ) ) { + return NULL; + } + + symbol = NSLookupAndBindSymbol(symbolName); + if ( !symbol ) { + // shouldn't happen ... + return NULL; + } + + return (GLExtension_t)(NSAddressOfSymbol(symbol)); +} + +void * wglGetProcAddress(const char *name) { + return (void *)GLimp_ExtensionPointer( name ); +} + + +/* +** GLW_InitExtensions +*/ +void GLW_InitExtensions( void ) { } + +#define MAX_RENDERER_INFO_COUNT 128 + +// Returns zero if there are no hardware renderers. Otherwise, returns the max memory across all renderers (on the presumption that the screen that we'll use has the most memory). +unsigned long Sys_QueryVideoMemory() { + CGLError err; + CGLRendererInfoObj rendererInfo, rendererInfos[MAX_RENDERER_INFO_COUNT]; + long rendererInfoIndex, rendererInfoCount = MAX_RENDERER_INFO_COUNT; + long rendererIndex, rendererCount; + long maxVRAM = 0, vram = 0; + long accelerated; + long rendererID; + long totalRenderers = 0; + + err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(Sys_DisplayToUse()), rendererInfos, &rendererInfoCount); + if (err) { + common->Printf("CGLQueryRendererInfo -> %d\n", err); + return vram; + } + + //common->Printf("rendererInfoCount = %d\n", rendererInfoCount); + for (rendererInfoIndex = 0; rendererInfoIndex < rendererInfoCount && totalRenderers < rendererInfoCount; rendererInfoIndex++) { + rendererInfo = rendererInfos[rendererInfoIndex]; + //common->Printf("rendererInfo: 0x%08x\n", rendererInfo); + + + err = CGLDescribeRenderer(rendererInfo, 0, kCGLRPRendererCount, &rendererCount); + if (err) { + common->Printf("CGLDescribeRenderer(kCGLRPRendererID) -> %d\n", err); + continue; + } + //common->Printf(" rendererCount: %d\n", rendererCount); + + for (rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { + totalRenderers++; + //common->Printf(" rendererIndex: %d\n", rendererIndex); + + rendererID = 0xffffffff; + err = CGLDescribeRenderer(rendererInfo, rendererIndex, kCGLRPRendererID, &rendererID); + if (err) { + common->Printf("CGLDescribeRenderer(kCGLRPRendererID) -> %d\n", err); + continue; + } + //common->Printf(" rendererID: 0x%08x\n", rendererID); + + accelerated = 0; + err = CGLDescribeRenderer(rendererInfo, rendererIndex, kCGLRPAccelerated, &accelerated); + if (err) { + common->Printf("CGLDescribeRenderer(kCGLRPAccelerated) -> %d\n", err); + continue; + } + //common->Printf(" accelerated: %d\n", accelerated); + if (!accelerated) + continue; + + vram = 0; + err = CGLDescribeRenderer(rendererInfo, rendererIndex, kCGLRPVideoMemory, &vram); + if (err) { + common->Printf("CGLDescribeRenderer -> %d\n", err); + continue; + } + //common->Printf(" vram: 0x%08x\n", vram); + + // presumably we'll be running on the best card, so we'll take the max of the vrams + if (vram > maxVRAM) + maxVRAM = vram; + } + +#if 0 + err = CGLDestroyRendererInfo(rendererInfo); + if (err) { + common->Printf("CGLDestroyRendererInfo -> %d\n", err); + } +#endif + } + + return maxVRAM; +} + + +// We will set the Sys_IsHidden global to cause input to be handle differently (we'll just let NSApp handle events in this case). We also will unbind the GL context and restore the video mode. +bool Sys_Hide() { + if ( isHidden ) { + // Eh? + return false; + } + + if ( !r_fullscreen.GetBool() ) { + // We only support hiding in fullscreen mode right now + return false; + } + + isHidden = true; + + // Don't need to store the current gamma since we always keep it around in glw_state.inGameTable. + + Sys_FadeScreen(Sys_DisplayToUse()); + + // Disassociate the GL context from the screen + // Have to call both to actually deallocate kernel resources and free the NSSurface + CGLClearDrawable(OSX_GetCGLContext()); + [OSX_GetNSGLContext() clearDrawable]; + + // Restore the original video mode + _GLimp_RestoreOriginalVideoSettings(); + + // Restore the original gamma if needed. + // if (glConfig.deviceSupportsGamma) { + // CGDisplayRestoreColorSyncSettings(); + // } + + // Release the screen(s) + ReleaseAllDisplays(); + + Sys_UnfadeScreens(); + + // Shut down the input system so the mouse and keyboard settings are restore to normal + Sys_ShutdownInput(); + + // Hide the application so that when the user clicks on our app icon, we'll get an unhide notification + [NSApp hide: nil]; + + return true; +} + +CGDisplayErr Sys_CaptureActiveDisplays(void) { + CGDisplayErr err; + CGDisplayCount displayIndex; + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + const glwgamma_t *table; + table = &glw_state.originalDisplayGammaTables[displayIndex]; + err = CGDisplayCapture(table->display); + if (err != CGDisplayNoErr) + return err; + } + return CGDisplayNoErr; +} + +bool Sys_Unhide() { + CGDisplayErr err; + CGLError glErr; + + if ( !isHidden) { + // Eh? + return false; + } + + Sys_FadeScreens(); + + // Capture the screen(s) + err = Sys_CaptureActiveDisplays(); + if (err != CGDisplayNoErr) { + Sys_UnfadeScreens(); + common->Printf( "Unhide failed -- cannot capture the display again.\n" ); + return false; + } + + // Restore the game mode + err = CGDisplaySwitchToMode(glw_state.display, (CFDictionaryRef)glw_state.gameMode); + if ( err != CGDisplayNoErr ) { + ReleaseAllDisplays(); + Sys_UnfadeScreens(); + common->Printf( "Unhide failed -- Unable to set display mode\n" ); + return false; + } + + // Reassociate the GL context and the screen + glErr = CGLSetFullScreen(OSX_GetCGLContext()); + if (glErr) { + ReleaseAllDisplays(); + Sys_UnfadeScreens(); + common->Printf( "Unhide failed: CGLSetFullScreen -> %d (%s)\n", err, CGLErrorString(glErr)); + return false; + } + + // Restore the current context + [OSX_GetNSGLContext() makeCurrentContext]; + + // Restore the gamma that the game had set + Sys_UnfadeScreen(Sys_DisplayToUse(), &glw_state.inGameTable); + + // Restore the input system (last so if something goes wrong we don't eat the mouse) + Sys_InitInput(); + + isHidden = false; + return true; +} + +bool GLimp_SpawnRenderThread( void (*function)( void ) ) { + return false; +} + +void *GLimp_RendererSleep(void) { + return NULL; +} + +void GLimp_FrontEndSleep(void) { } + +void GLimp_WakeRenderer( void *data ) { } + +void *GLimp_BackEndSleep( void ) { + return NULL; +} + +void GLimp_WakeBackEnd( void *data ) { +} + +// enable / disable context is just for the r_skipRenderContext debug option +void GLimp_DeactivateContext( void ) { + [NSOpenGLContext clearCurrentContext]; +} + +void GLimp_ActivateContext( void ) { + [OSX_GetNSGLContext() makeCurrentContext]; +} + +void GLimp_EnableLogging(bool stat) { } + +NSDictionary *Sys_GetMatchingDisplayMode( glimpParms_t parms ) { + NSArray *displayModes; + NSDictionary *mode; + unsigned int modeIndex, modeCount, bestModeIndex; + int verbose; + // cvar_t *cMinFreq, *cMaxFreq; + int minFreq, maxFreq; + unsigned int colorDepth; + + verbose = 0; + + colorDepth = 32; + + minFreq = r_minDisplayRefresh.GetInteger(); + maxFreq = r_maxDisplayRefresh.GetInteger(); + if ( minFreq > maxFreq ) { + common->Error( "r_minDisplayRefresh must be less than or equal to r_maxDisplayRefresh" ); + } + + displayModes = (NSArray *)CGDisplayAvailableModes(glw_state.display); + if (!displayModes) { + common->Error( "CGDisplayAvailableModes returned NULL -- 0x%0x is an invalid display", glw_state.display); + } + + modeCount = [displayModes count]; + if (verbose) { + common->Printf( "%d modes avaliable\n", modeCount); + common->Printf( "Current mode is %s\n", [[(id)CGDisplayCurrentMode(glw_state.display) description] cString]); + } + + // Default to the current desktop mode + bestModeIndex = 0xFFFFFFFF; + + for ( modeIndex = 0; modeIndex < modeCount; ++modeIndex ) { + id object; + int refresh; + + mode = [displayModes objectAtIndex: modeIndex]; + if (verbose) { + common->Printf( " mode %d -- %s\n", modeIndex, [[mode description] cString]); + } + + // Make sure we get the right size + if ([[mode objectForKey: (id)kCGDisplayWidth] intValue] != parms.width || + [[mode objectForKey: (id)kCGDisplayHeight] intValue] != parms.height) { + if (verbose) + common->Printf( " -- bad size\n"); + continue; + } + + // Make sure that our frequency restrictions are observed + refresh = [[mode objectForKey: (id)kCGDisplayRefreshRate] intValue]; + if (minFreq && refresh < minFreq) { + if (verbose) + common->Printf( " -- refresh too low\n"); + continue; + } + + if (maxFreq && refresh > maxFreq) { + if (verbose) + common->Printf( " -- refresh too high\n"); + continue; + } + + if ([[mode objectForKey: (id)kCGDisplayBitsPerPixel] intValue] != colorDepth) { + if (verbose) + common->Printf( " -- bad depth\n"); + continue; + } + + object = [mode objectForKey: (id)kCGDisplayModeIsStretched]; + if ( object ) { + if ( [object boolValue] != cvarSystem->GetCVarBool( "r_stretched" ) ) { + if (verbose) + common->Printf( " -- bad stretch setting\n"); + continue; + } + } + else { + if ( cvarSystem->GetCVarBool( "r_stretched" ) ) { + if (verbose) + common->Printf( " -- stretch requested, stretch property not available\n"); + continue; + } + } + + bestModeIndex = modeIndex; + if (verbose) + common->Printf( " -- OK\n", bestModeIndex); + } + + if (verbose) + common->Printf( " bestModeIndex = %d\n", bestModeIndex); + + if (bestModeIndex == 0xFFFFFFFF) { + common->Printf( "No suitable display mode available.\n"); + return nil; + } + + return [displayModes objectAtIndex: bestModeIndex]; +} + + +#define MAX_DISPLAYS 128 + +void Sys_GetGammaTable(glwgamma_t *table) { + CGTableCount tableSize = 512; + CGDisplayErr err; + + table->tableSize = tableSize; + if (table->red) + free(table->red); + table->red = (float *)malloc(tableSize * sizeof(*table->red)); + if (table->green) + free(table->green); + table->green = (float *)malloc(tableSize * sizeof(*table->green)); + if (table->blue) + free(table->blue); + table->blue = (float *)malloc(tableSize * sizeof(*table->blue)); + + // TJW: We _could_ loop here if we get back the same size as our table, increasing the table size. + err = CGGetDisplayTransferByTable(table->display, tableSize, table->red, table->green, table->blue, + &table->tableSize); + if (err != CGDisplayNoErr) { + common->Printf("GLimp_Init: CGGetDisplayTransferByTable returned %d.\n", err); + table->tableSize = 0; + } +} + +void Sys_SetGammaTable(glwgamma_t *table) { } + +void Sys_StoreGammaTables() { + // Store the original gamma for all monitors so that we can fade and unfade them all + CGDirectDisplayID displays[MAX_DISPLAYS]; + CGDisplayCount displayIndex; + CGDisplayErr err; + + err = CGGetActiveDisplayList(MAX_DISPLAYS, displays, &glw_state.displayCount); + if (err != CGDisplayNoErr) + Sys_Error("Cannot get display list -- CGGetActiveDisplayList returned %d.\n", err); + + glw_state.originalDisplayGammaTables = (glwgamma_t *)calloc(glw_state.displayCount, sizeof(*glw_state.originalDisplayGammaTables)); + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + glwgamma_t *table; + + table = &glw_state.originalDisplayGammaTables[displayIndex]; + table->display = displays[displayIndex]; + Sys_GetGammaTable(table); + } +} + + +// This isn't a mathematically correct fade, but we don't care that much. +void Sys_SetScreenFade(glwgamma_t *table, float fraction) { + CGTableCount tableSize; + CGGammaValue *red, *blue, *green; + CGTableCount gammaIndex; + + // if (!glConfig.deviceSupportsGamma) + // return; + + if (!(tableSize = table->tableSize)) + // we couldn't get the table for this display for some reason + return; + + // common->Printf("0x%08x %f\n", table->display, fraction); + + red = glw_state.tempTable.red; + green = glw_state.tempTable.green; + blue = glw_state.tempTable.blue; + if (glw_state.tempTable.tableSize < tableSize) { + glw_state.tempTable.tableSize = tableSize; + red = (float *)realloc(red, sizeof(*red) * tableSize); + green = (float *)realloc(green, sizeof(*green) * tableSize); + blue = (float *)realloc(blue, sizeof(*blue) * tableSize); + glw_state.tempTable.red = red; + glw_state.tempTable.green = green; + glw_state.tempTable.blue = blue; + } + + for (gammaIndex = 0; gammaIndex < table->tableSize; gammaIndex++) { + red[gammaIndex] = table->red[gammaIndex] * fraction; + blue[gammaIndex] = table->blue[gammaIndex] * fraction; + green[gammaIndex] = table->green[gammaIndex] * fraction; + } + + CGSetDisplayTransferByTable(table->display, table->tableSize, red, green, blue); +} + +// Fades all the active displays at the same time. + +#define FADE_DURATION 0.5 +void Sys_FadeScreens() { + CGDisplayCount displayIndex; + int stepIndex; + glwgamma_t *table; + NSTimeInterval start, current; + float time; + + // if (!glConfig.deviceSupportsGamma) + // return; + + common->Printf("Fading all displays\n"); + + start = [NSDate timeIntervalSinceReferenceDate]; + time = 0.0; + while (time != FADE_DURATION) { + current = [NSDate timeIntervalSinceReferenceDate]; + time = current - start; + if (time > FADE_DURATION) + time = FADE_DURATION; + + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + table = &glw_state.originalDisplayGammaTables[displayIndex]; + Sys_SetScreenFade(table, 1.0 - time / FADE_DURATION); + } + } +} + +void Sys_FadeScreen(CGDirectDisplayID display) { + CGDisplayCount displayIndex; + glwgamma_t *table; + int stepIndex; + + common->Printf( "FIXME: Sys_FadeScreen\n" ); + + return; + + // if (!glConfig.deviceSupportsGamma) + // return; + + common->Printf("Fading display 0x%08x\n", display); + + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + if (display == glw_state.originalDisplayGammaTables[displayIndex].display) { + NSTimeInterval start, current; + float time; + + start = [NSDate timeIntervalSinceReferenceDate]; + time = 0.0; + + table = &glw_state.originalDisplayGammaTables[displayIndex]; + while (time != FADE_DURATION) { + current = [NSDate timeIntervalSinceReferenceDate]; + time = current - start; + if (time > FADE_DURATION) + time = FADE_DURATION; + + Sys_SetScreenFade(table, 1.0 - time / FADE_DURATION); + } + return; + } + } + + common->Printf("Unable to find display to fade it\n"); +} + +void Sys_UnfadeScreens() { + CGDisplayCount displayIndex; + int stepIndex; + glwgamma_t *table; + NSTimeInterval start, current; + float time; + + common->Printf( "FIXME: Sys_UnfadeScreens\n" ); + + return; + + // if (!glConfig.deviceSupportsGamma) + // return; + + common->Printf("Unfading all displays\n"); + + start = [NSDate timeIntervalSinceReferenceDate]; + time = 0.0; + while (time != FADE_DURATION) { + current = [NSDate timeIntervalSinceReferenceDate]; + time = current - start; + if (time > FADE_DURATION) + time = FADE_DURATION; + + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + table = &glw_state.originalDisplayGammaTables[displayIndex]; + Sys_SetScreenFade(table, time / FADE_DURATION); + } + } +} + +void Sys_UnfadeScreen(CGDirectDisplayID display, glwgamma_t *table) { + CGDisplayCount displayIndex; + int stepIndex; + + common->Printf( "FIXME: Sys_UnfadeScreen\n" ); + + return; + // if (!glConfig.deviceSupportsGamma) + // return; + + common->Printf("Unfading display 0x%08x\n", display); + + if (table) { + CGTableCount i; + + common->Printf("Given table:\n"); + for (i = 0; i < table->tableSize; i++) { + common->Printf(" %f %f %f\n", table->red[i], table->blue[i], table->green[i]); + } + } + + // Search for the original gamma table for the display + if (!table) { + for (displayIndex = 0; displayIndex < glw_state.displayCount; displayIndex++) { + if (display == glw_state.originalDisplayGammaTables[displayIndex].display) { + table = &glw_state.originalDisplayGammaTables[displayIndex]; + break; + } + } + } + + if (table) { + NSTimeInterval start, current; + float time; + + start = [NSDate timeIntervalSinceReferenceDate]; + time = 0.0; + + while (time != FADE_DURATION) { + current = [NSDate timeIntervalSinceReferenceDate]; + time = current - start; + if (time > FADE_DURATION) + time = FADE_DURATION; + Sys_SetScreenFade(table, time / FADE_DURATION); + } + return; + } + + common->Printf("Unable to find display to unfade it\n"); +} + +#define MAX_DISPLAYS 128 + +CGDirectDisplayID Sys_DisplayToUse(void) { + static bool gotDisplay = NO; + static CGDirectDisplayID displayToUse; + + CGDisplayErr err; + CGDirectDisplayID displays[MAX_DISPLAYS]; + CGDisplayCount displayCount; + int displayIndex; + + if ( gotDisplay ) { + return displayToUse; + } + gotDisplay = YES; + + err = CGGetActiveDisplayList( MAX_DISPLAYS, displays, &displayCount ); + if ( err != CGDisplayNoErr ) { + common->Error("Cannot get display list -- CGGetActiveDisplayList returned %d.\n", err ); + } + + // -1, the default, means to use the main screen + displayIndex = r_screen.GetInteger(); + + if ( displayIndex < 0 || displayIndex >= displayCount ) { + // This is documented (in CGDirectDisplay.h) to be the main display. We want to + // return this instead of kCGDirectMainDisplay since this will allow us to compare + // display IDs. + displayToUse = displays[ 0 ]; + } else { + displayToUse = displays[ displayIndex ]; + } + + return displayToUse; +} + +/* +=================== +GLimp_SetScreenParms +=================== +*/ +bool GLimp_SetScreenParms( glimpParms_t parms ) { + return true; +} + +/* +=================== +Sys_GrabMouseCursor +=================== +*/ +void Sys_GrabMouseCursor( bool grabIt ) { } + diff --git a/sys/osx/macosx_guids.cpp b/sys/osx/macosx_guids.cpp new file mode 100644 index 000000000..793042607 --- /dev/null +++ b/sys/osx/macosx_guids.cpp @@ -0,0 +1,6 @@ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#define INITGUID + +#include "../../sound/snd_local.h" diff --git a/sys/osx/macosx_local.h b/sys/osx/macosx_local.h new file mode 100644 index 000000000..9422d83e6 --- /dev/null +++ b/sys/osx/macosx_local.h @@ -0,0 +1,22 @@ + +#include + +#include "../sys_public.h" + +void OutputDebugString( const char *text ); + +// input +void Sys_InitInput( void ); +void Sys_ShutdownInput( void ); + +void IN_DeactivateMouse( void); +void IN_ActivateMouse( void); + +void IN_Activate (bool active); +void IN_Frame (void); + +void * wglGetProcAddress(const char *name); + +void Sleep( const int time ); + +void Sys_UpdateWindowMouseInputRect( void ); diff --git a/sys/osx/macosx_misc.mm b/sys/osx/macosx_misc.mm new file mode 100644 index 000000000..490454c70 --- /dev/null +++ b/sys/osx/macosx_misc.mm @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +#define GL_GLEXT_LEGACY // AppKit.h include pulls in gl.h already +#import +#import +#include "../../idlib/precompiled.h" +#include "../sys_local.h" + +/* +================== +idSysLocal::OpenURL +================== +*/ +void idSysLocal::OpenURL( const char *url, bool doexit ) { + static bool quit_spamguard = false; + + if ( quit_spamguard ) { + common->DPrintf( "Sys_OpenURL: already in a doexit sequence, ignoring %s\n", url ); + return; + } + + common->Printf("Open URL: %s\n", url); + + + [[ NSWorkspace sharedWorkspace] openURL: [ NSURL URLWithString: + [ NSString stringWithCString: url ] ] ]; + + if ( doexit ) { + quit_spamguard = true; + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + } +} + +/* +================== +Sys_DoStartProcess +================== +*/ +void Sys_DoStartProcess( const char *exeName, bool dofork = true ) { + common->Printf( "TODO: Sys_DoStartProcess %s\n", exeName ); +} + +/* +================== +OSX_GetLocalizedString +================== +*/ +const char* OSX_GetLocalizedString( const char* key ) +{ + NSString *string = [ [ NSBundle mainBundle ] localizedStringForKey:[ NSString stringWithCString: key ] + value:@"No translation" table:nil]; + return [string cString]; +} diff --git a/sys/osx/macosx_sound.cpp b/sys/osx/macosx_sound.cpp new file mode 100644 index 000000000..8502d0c27 --- /dev/null +++ b/sys/osx/macosx_sound.cpp @@ -0,0 +1,439 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#include "../../sound/snd_local.h" + +#include +#include + +idCVar s_device( "s_device", "-1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "Sound device to use. -1 for default device" ); + +class idAudioHardwareOSX : public idAudioHardware { +public: + idAudioHardwareOSX(); + ~idAudioHardwareOSX(); + + bool Initialize( ); + + // OSX driver doesn't support memory map API + bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; } + bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; } + bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; } + int GetMixBufferSize( void ) { return 0; } + + int GetNumberOfSpeakers( void ); + + // OSX driver doesn't support write API + bool Flush( void ) { return false; } + void Write( bool ) { } + short* GetMixBuffer( void ) { return NULL; } + +private: + AudioDeviceID selectedDevice; + bool activeIOProc; + + void Reset( void ); + void InitFailed( void ); + const char* ExtractStatus( OSStatus status ); + void GetAvailableNominalSampleRates( void ); + + // AudioDevicePropertyListenerProc + static OSStatus DeviceListener( AudioDeviceID inDevice, + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData ); + + // AudioDeviceIOProc + static OSStatus DeviceIOProc( AudioDeviceID inDevice, + const AudioTimeStamp* inNow, + const AudioBufferList* inInputData, + const AudioTimeStamp* inInputTime, + AudioBufferList* outOutputData, + const AudioTimeStamp* inOutputTime, + void* inClientData ); +}; + +/* +========== +iAudioHardware::Alloc +========== +*/ +idAudioHardware *idAudioHardware::Alloc() { return new idAudioHardwareOSX; } + +/* +========== +idAudioHardware::~idAudioHardware +========== +*/ +idAudioHardware::~idAudioHardware() { } + +/* +========== +idAudioHardwareOSX::idAudioHardwareOSX +========== +*/ +idAudioHardwareOSX::idAudioHardwareOSX() { + selectedDevice = kAudioDeviceUnknown; + activeIOProc = false; +} + +/* +========== +idAudioHardwareOSX::~idAudioHardwareOSX +========== +*/ +idAudioHardwareOSX::~idAudioHardwareOSX() { + Reset(); +} + +/* +========== +idAudioHardwareOSX::Reset +========== +*/ +void idAudioHardwareOSX::Reset() { + OSStatus status; + + if ( activeIOProc ) { + status = AudioDeviceStop( selectedDevice, DeviceIOProc ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "idAudioHardwareOSX::Reset: AudioDeviceStop failed. status: %s", ExtractStatus( status ) ); + } + status = AudioDeviceRemoveIOProc( selectedDevice, DeviceIOProc ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "idAudioHardwareOSX::Reset: AudioDeviceRemoveIOProc failed. status %s\n", ExtractStatus( status ) ); + } + activeIOProc = false; + } + selectedDevice = kAudioDeviceUnknown; + AudioHardwareUnload(); +} + +/* +================= +idAudioHardwareOSX::InitFailed +================= +*/ +void idAudioHardwareOSX::InitFailed() { + Reset(); + cvarSystem->SetCVarBool( "s_noSound", true ); + common->Warning( "sound subsystem disabled" ); + common->Printf( "------------------------------------------------\n" ); +} + +/* +========== +idAudioHardwareOSX::DeviceListener +========== +*/ +OSStatus idAudioHardwareOSX::DeviceListener( AudioDeviceID inDevice, + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) { + common->Printf( "DeviceListener\n" ); + return kAudioHardwareNoError; +} + +/* +========== +idAudioHardwareOSX::DeviceIOProc +========== +*/ +OSStatus idAudioHardwareOSX::DeviceIOProc( AudioDeviceID inDevice, + const AudioTimeStamp* inNow, + const AudioBufferList* inInputData, + const AudioTimeStamp* inInputTime, + AudioBufferList* outOutputData, + const AudioTimeStamp* inOutputTime, + void* inClientData ) { + + // setup similar to async thread + Sys_EnterCriticalSection(); + soundSystem->AsyncMix( (int)inOutputTime->mSampleTime, (float*)outOutputData->mBuffers[ 0 ].mData ); + Sys_LeaveCriticalSection(); + + // doom mixes sound to -32768.0f 32768.0f range, scale down to -1.0f 1.0f + SIMDProcessor->Mul( (Float32*)outOutputData->mBuffers[ 0 ].mData, 1.0f / 32768.0f, (Float32*)outOutputData->mBuffers[ 0 ].mData, MIXBUFFER_SAMPLES * 2 ); + + return kAudioHardwareNoError; +} + +/* +========== +idAudioHardwareOSX::ExtractStatus +========== +*/ +const char* idAudioHardwareOSX::ExtractStatus( OSStatus status ) { + static char buf[ sizeof( OSStatus ) + 1 ]; + strncpy( buf, (const char *)&status, sizeof( OSStatus ) ); + buf[ sizeof( OSStatus ) ] = '\0'; + return buf; +} + +/* +========== +idAudioHardwareOSX::Initialize +========== +*/ +bool idAudioHardwareOSX::Initialize( ) { + + UInt32 size; + OSStatus status; + int i, deviceCount; + AudioDeviceID *deviceList; + char buf[ 1024 ]; + + status = AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &size, NULL ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioHardwareGetPropertyInfo kAudioHardwarePropertyDevices failed. status: %s", ExtractStatus( status ) ); + InitFailed(); + return false; + } + + deviceCount = size / sizeof( AudioDeviceID ); + if ( !deviceCount ) { + common->Printf( "No sound device found\n" ); + InitFailed(); + return false; + } + + deviceList = (AudioDeviceID*)malloc( size ); + status = AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &size, deviceList ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioHardwareGetProperty kAudioHardwarePropertyDevices failed. status: %s", ExtractStatus( status ) ); + free( deviceList ); + InitFailed(); + return false; + } + + common->Printf( "%d sound device(s)\n", deviceCount ); + for( i = 0; i < deviceCount; i++ ) { + size = 1024; + status = AudioDeviceGetProperty( deviceList[ i ], 0, false, kAudioDevicePropertyDeviceName, &size, buf ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty kAudioDevicePropertyDeviceName %d failed. status: %s", i, ExtractStatus( status ) ); + free( deviceList ); + InitFailed(); + return false; + } + common->Printf( " %d: ID %d, %s - ", i, deviceList[ i ], buf ); + size = 1024; + status = AudioDeviceGetProperty( deviceList[ i ], 0, false, kAudioDevicePropertyDeviceManufacturer, &size, buf ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty kAudioDevicePropertyDeviceManufacturer %d failed. status: %s", i, ExtractStatus( status ) ); + free( deviceList ); + InitFailed(); + return false; + } + common->Printf( "%s\n", buf ); + } + + if ( s_device.GetInteger() != -1 && s_device.GetInteger() < deviceCount ) { + selectedDevice = deviceList[ s_device.GetInteger() ]; + common->Printf( "s_device: device ID %d\n", selectedDevice ); + } else { + size = sizeof( selectedDevice ); + status = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &size, &selectedDevice ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioHardwareGetProperty kAudioHardwarePropertyDefaultOutputDevice failed. status: %s", ExtractStatus( status ) ); + + free( deviceList ); + InitFailed(); + return false; + } + common->Printf( "select default device, ID %d\n", selectedDevice ); + } + + free( deviceList ); + deviceList = NULL; + + /* + // setup a listener to watch for changes to properties + status = AudioDeviceAddPropertyListener( selectedDevice, 0, false, kAudioDeviceProcessorOverload, DeviceListener, this ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceAddPropertyListener kAudioDeviceProcessorOverload failed. status: %s", ExtractStatus( status ) ); + InitFailed(); + return; + } + */ + + Float64 sampleRate; + size = sizeof( sampleRate ); + status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyNominalSampleRate, &size, &sampleRate ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyNominalSampleRate failed. status: %s", selectedDevice, ExtractStatus( status ) ); + InitFailed(); + return false; + } + common->Printf( "current nominal rate: %g\n", sampleRate ); + + if ( sampleRate != PRIMARYFREQ ) { + + GetAvailableNominalSampleRates(); + + sampleRate = PRIMARYFREQ; + common->Printf( "setting rate to: %g\n", sampleRate ); + status = AudioDeviceSetProperty( selectedDevice, NULL, 0, false, kAudioDevicePropertyNominalSampleRate, size, &sampleRate ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceSetProperty %d kAudioDevicePropertyNominalSampleRate %g failed. status: %s", selectedDevice, sampleRate, ExtractStatus( status ) ); + InitFailed(); + return false; + } + } + + UInt32 frameSize; + size = sizeof( UInt32 ); + status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyBufferFrameSize, &size, &frameSize ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyBufferFrameSize failed.status: %s", selectedDevice, ExtractStatus( status ) ); + InitFailed(); + return false; + } + common->Printf( "current frame size: %d\n", frameSize ); + + // get the allowed frame size range + AudioValueRange frameSizeRange; + size = sizeof( AudioValueRange ); + status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &frameSizeRange ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyBufferFrameSizeRange failed. status: %s", selectedDevice, ExtractStatus( status ) ); + InitFailed(); + return false; + } + common->Printf( "frame size allowed range: %g %g\n", frameSizeRange.mMinimum, frameSizeRange.mMaximum ); + + if ( frameSizeRange.mMaximum < MIXBUFFER_SAMPLES ) { + common->Warning( "can't obtain the required frame size of %d bits", MIXBUFFER_SAMPLES ); + InitFailed(); + return false; + } + + if ( frameSize != (unsigned int)MIXBUFFER_SAMPLES ) { + frameSize = MIXBUFFER_SAMPLES; + common->Printf( "setting frame size to: %d\n", frameSize ); + size = sizeof( frameSize ); + status = AudioDeviceSetProperty( selectedDevice, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, size, &frameSize ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceSetProperty %d kAudioDevicePropertyBufferFrameSize failed. status: %s", selectedDevice, ExtractStatus( status ) ); + InitFailed(); + return false; + } + } + + if ( idSoundSystemLocal::s_numberOfSpeakers.GetInteger() != 2 ) { + common->Warning( "only stereo sound currently supported" ); + idSoundSystemLocal::s_numberOfSpeakers.SetInteger( 2 ); + } + UInt32 channels[ 2 ]; + size = 2 * sizeof( UInt32 ); + status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size, &channels ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyPreferredChannelsForStereo failed. status: %s", selectedDevice, ExtractStatus( status ) ); + InitFailed(); + return false; + } + common->Printf( "using stereo channel IDs %d %d\n", channels[ 0 ], channels[ 1 ] ); + + status = AudioDeviceAddIOProc( selectedDevice, DeviceIOProc, NULL ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceAddIOProc failed. status: %s", ExtractStatus( status ) ); + InitFailed(); + return false; + } + activeIOProc = true; + + status = AudioDeviceStart( selectedDevice, DeviceIOProc ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceStart failed. status: %s", ExtractStatus( status ) ); + InitFailed(); + return false; + } + + /* + // allocate the mix buffer + // it has the space for ROOM_SLICES_IN_BUFFER DeviceIOProc loops + mixBufferSize = dwSpeakers * dwSampleSize * dwPrimaryBitRate * ROOM_SLICES_IN_BUFFER / 8; + mixBuffer = malloc( mixBufferSize ); + memset( mixBuffer, 0, mixBufferSize ); + */ + + return true; +} + +/* +========== +idAudioHardwareOSX::GetAvailableNominalSampleRates +========== +*/ +void idAudioHardwareOSX::GetAvailableNominalSampleRates( void ) { + UInt32 size; + OSStatus status; + int i, rangeCount; + AudioValueRange *rangeArray; + + status = AudioDeviceGetPropertyInfo( selectedDevice, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, NULL ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetPropertyInfo %d kAudioDevicePropertyAvailableNominalSampleRates failed. status: %s", selectedDevice, ExtractStatus( status ) ); + return; + } + rangeCount = size / sizeof( AudioValueRange ); + rangeArray = (AudioValueRange *)malloc( size ); + + common->Printf( "%d possible rate(s)\n", rangeCount ); + + status = AudioDeviceGetProperty( selectedDevice, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, rangeArray ); + if ( status != kAudioHardwareNoError ) { + common->Warning( "AudioDeviceGetProperty %d kAudioDevicePropertyAvailableNominalSampleRates failed. status: %s", selectedDevice, ExtractStatus( status ) ); + free( rangeArray ); + return; + } + + for( i = 0; i < rangeCount; i++ ) { + common->Printf( " %d: min %g max %g\n", i, rangeArray[ i ].mMinimum, rangeArray[ i ].mMaximum ); + } + + free( rangeArray ); +} + +/* +========== +idAudioHardwareOSX::GetNumberOfSpeakers +========== +*/ +int idAudioHardwareOSX::GetNumberOfSpeakers() { + return idSoundSystemLocal::s_numberOfSpeakers.GetInteger(); +} + +/* + =============== + Sys_LoadOpenAL + =============== + */ +bool Sys_LoadOpenAL( void ) { + OSErr err; + long gestaltOSVersion; + err = Gestalt(gestaltSystemVersion, &gestaltOSVersion); + if ( err || gestaltOSVersion < 0x1040 ) { + return false; + } + return true; +} diff --git a/sys/osx/macosx_sys.h b/sys/osx/macosx_sys.h new file mode 100644 index 000000000..7dcf08bb2 --- /dev/null +++ b/sys/osx/macosx_sys.h @@ -0,0 +1,84 @@ +#import "../posix/posix_public.h" + +#import +@class NSEvent, NSOpenGLContext, NSWindow; + +#import +#import + +// sys + +const char *macosx_scanForLibraryDirectory(void); + +// In macosx_input.m +void Sys_InitInput(void); +void Sys_ShutdownInput(void); +CGDirectDisplayID Sys_DisplayToUse(void); +//extern void osxQuit(); +void SetProgramPath(char *path); +void Sys_SetMouseInputRect(CGRect newRect); + +void Sys_AnnoyingBanner(); + +// In macosx_glimp.m +bool Sys_Hide(); +bool Sys_Unhide(); + +typedef struct { + CGDirectDisplayID display; + CGTableCount tableSize; + CGGammaValue *red; + CGGammaValue *blue; + CGGammaValue *green; +} glwgamma_t; + +typedef struct +{ + CGDirectDisplayID display; + NSDictionary *desktopMode; + NSDictionary *gameMode; + + CGDisplayCount displayCount; + glwgamma_t *originalDisplayGammaTables; + glwgamma_t inGameTable; + glwgamma_t tempTable; + + NSOpenGLContext *_ctx; + CGLContextObj _cgl_ctx; + bool _ctx_is_current; + NSWindow *window; + + FILE *log_fp; + + unsigned int bufferSwapCount; + unsigned int glPauseCount; +} glwstate_t; + +extern glwstate_t glw_state; + +#define OSX_SetGLContext(context) \ +do { \ + NSOpenGLContext *_context = (context); \ + glw_state._ctx = _context; \ + glw_state._cgl_ctx = [_context cglContext]; \ +} while (0) + +#define OSX_GetNSGLContext() glw_state._ctx +#define OSX_GetCGLContext() glw_state._cgl_ctx + +#define OSX_GLContextIsCurrent() glw_state._ctx_is_current +#define OSX_GLContextSetCurrent() \ +do { \ + [glw_state._ctx makeCurrentContext]; \ + glw_state._ctx_is_current = (glw_state._ctx != nil); \ +} while (0) + +#define OSX_GLContextClearCurrent() \ +do { \ + [NSOpenGLContext clearCurrentContext]; \ + glw_state._ctx_is_current = NO; \ +} while (0) + + +void Sys_PauseGL(); +void Sys_ResumeGL(); diff --git a/sys/osx/macosx_sys.mm b/sys/osx/macosx_sys.mm new file mode 100644 index 000000000..4c37e9c29 --- /dev/null +++ b/sys/osx/macosx_sys.mm @@ -0,0 +1,251 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +// -*- mode: objc -*- +#import "../../idlib/precompiled.h" + +#import "macosx_local.h" +#import "macosx_sys.h" + +#import "macosx_common.h" +#import "dlfcn.h" + +#import + +#import +#import +#import +#import +#import + +#ifdef OMNI_TIMER +#import "macosx_timers.h" +#endif + +void Sys_Init (void); + +char *Sys_GetCurrentUser( void ); + +void Sys_Error( const char *error, ...); +void Sys_Quit (void); +char *Sys_GetClipboardData( void ); // note that this isn't journaled... + +void Sys_Print( const char *msg ); +//=========================================================================== + +int main(int argc, const char *argv[]) { + return NSApplicationMain(argc, argv); +} + +//=========================================================================== + +void Sys_Sleep( const int time ) { + sleep( time ); +} + +void EditorPrintConsole( const char *test ) { +} + +/* +================= +Sys_UnloadDll + +================= +*/ +void Sys_UnloadDll( void *dllHandle ) { +} + +/* +================= +Sys_LoadDll + +Used to load a development dll instead of a virtual machine +================= +*/ +extern char *FS_BuildOSPath( const char *base, const char *game, const char *qpath ); + +void *Sys_LoadDll( const char *name, int (**entryPoint)(int, ...), + int (*systemcalls)(int, ...) ) +{ + return NULL; +} + +//=========================================================================== + +char *Sys_GetClipboardData(void) // FIXME +{ + NSPasteboard *pasteboard; + NSArray *pasteboardTypes; + + pasteboard = [NSPasteboard generalPasteboard]; + pasteboardTypes = [pasteboard types]; + if ([pasteboardTypes containsObject:NSStringPboardType]) { + NSString *clipboardString; + + clipboardString = [pasteboard stringForType:NSStringPboardType]; + if (clipboardString && [clipboardString length] > 0) { + return strdup([clipboardString cString]); + } + } + return NULL; +} + +//=========================================================================== + +void Sys_BeginProfiling(void) +{ +} + +void Sys_EndProfiling(void) +{ +} + +//=========================================================================== + +/* +================ +Sys_Init + +The cvar and file system has been setup, so configurations are loaded +================ +*/ +void Sys_Init(void) +{ +// Sys_InitNetwork(); + Sys_InitInput(); +} + +/* +================= +Sys_Shutdown +================= +*/ +void Sys_Shutdown(void) +{ + common->Printf( "----- Sys_Shutdown -----\n" ); + Sys_EndProfiling(); + Sys_ShutdownInput(); + common->Printf( "------------------------\n" ); +} + +void Sys_Error(const char *error, ...) +{ + va_list argptr; + NSString *formattedString; + + Sys_Shutdown(); + + va_start(argptr,error); + formattedString = [[NSString alloc] initWithFormat:[NSString stringWithCString:error] arguments:argptr]; + va_end(argptr); + + NSLog(@"Sys_Error: %@", formattedString); + NSRunAlertPanel(@"DOOM Error", formattedString, nil, nil, nil); + + Sys_Quit(); +} + +void Sys_Quit(void) +{ + Sys_Shutdown(); + [NSApp terminate:nil]; +} + +/* +================ +Sys_Print + +This is called for all console output, even if the game is running +full screen and the dedicated console window is hidden. +================ +*/ + +char *ansiColors[8] = + { "\033[30m" , /* ANSI Black */ + "\033[31m" , /* ANSI Red */ + "\033[32m" , /* ANSI Green */ + "\033[33m" , /* ANSI Yellow */ + "\033[34m" , /* ANSI Blue */ + "\033[36m" , /* ANSI Cyan */ + "\033[35m" , /* ANSI Magenta */ + "\033[37m" }; /* ANSI White */ + +void Sys_Print(const char *text) +{ +#if 0 + /* Okay, this is a stupid hack, but what the hell, I was bored. ;) */ + char *scan = text; + char code; + int index; + + /* Make sure terminal mode is reset at the start of the line... */ + fputs("\033[0m", stdout); + + while(*scan) { + /* See if we have a color control code. If so, snarf the character, + print what we have so far, print the ANSI Terminal color code, + skip over the color control code and continue */ + if(Q_IsColorString(scan)) { + index = ColorIndex(scan[1]); + + /* Flush current message */ + if(scan != text) { + fwrite(text, scan - text, 1, stdout); + } + + /* Write ANSI color code */ + fputs(ansiColors[index], stdout); + + /* Reset search */ + text = scan+2; + scan = text; + continue; + } + scan++; + } + + /* Flush whatever's left */ + fputs(text, stdout); + + /* Make sure terminal mode is reset at the end of the line too... */ + fputs("\033[0m", stdout); + +#else + fputs(text, stdout); +#endif +} + +void OutputDebugString( const char *text ) { + Sys_Print( text ); +} + +void Sys_OutputDebugString( const char *text ) { + OutputDebugString( text ); +} + +/* +================ +Sys_CheckCD + +Return true if the proper CD is in the drive +================ +*/ +bool Sys_CheckCD( void ) { + return macosx_scanForLibraryDirectory() != NULL; +} diff --git a/sys/osx/macosx_timers.h b/sys/osx/macosx_timers.h new file mode 100644 index 000000000..02e8e747c --- /dev/null +++ b/sys/osx/macosx_timers.h @@ -0,0 +1,17 @@ +#ifdef OMNI_TIMER + +#import + +extern OTTimerNode *RootNode; +extern OTTimerNode *FrameNode; +extern OTTimerNode *UpdateScreenNode; +extern OTTimerNode *SurfaceMeshNode; +extern OTTimerNode *LerpMeshVertexesNode; +extern OTTimerNode *LerpMeshVertexesNode1; +extern OTTimerNode *LerpMeshVertexesNode2; +extern OTTimerNode *VectorArrayNormalizeNode; + +extern void InitializeTimers(); +extern void PrintTimers(); + +#endif // OMNI_TIMER diff --git a/sys/osx/macosx_utils.mm b/sys/osx/macosx_utils.mm new file mode 100644 index 000000000..73e1e8712 --- /dev/null +++ b/sys/osx/macosx_utils.mm @@ -0,0 +1,159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision: 916 $ (Revision of last commit) + $Date: 2007-04-20 22:48:14 +0200 (Fr, 20 Apr 2007) $ (Date of last commit) + $Author: greebo $ (Author of last commit) + +******************************************************************************/ + +// -*- mode: objc -*- +#import "../../idlib/precompiled.h" + +#import +#import +#import + + +#define CD_MOUNT_NAME "DOOM" + +#include "macosx_local.h" +#include "macosx_sys.h" + +//extern "C" void *vm_allocate(unsigned, unsigned*, unsigned, int); +//extern "C" void vm_deallocate(unsigned, unsigned*, unsigned); + +const char *macosx_scanForLibraryDirectory(void) +{ + return "/Library/DOOM"; +} + +// EEEK! +static long size_save; + +void *osxAllocateMemoryNV(long size, float readFrequency, float writeFrequency, float priority) +{ + kern_return_t kr; + vm_address_t buffer; + + kr = vm_allocate(mach_task_self(), + (vm_address_t *)&buffer, + size, + VM_FLAGS_ANYWHERE); + if(kr == 0) { + size_save = size; + return buffer; + } + else + { + size_save = 0; + return NULL; + } + +} + +void osxFreeMemoryNV(void *pointer) +{ + if(size_save) { + vm_deallocate(mach_task_self(), + (vm_address_t)pointer, + size_save); + size_save = 0; + } +} + +void *osxAllocateMemory(long size) +{ + kern_return_t kr; + vm_address_t buffer; + + size += sizeof( int ); + kr = vm_allocate(mach_task_self(), + (vm_address_t *)&buffer, + size, + VM_FLAGS_ANYWHERE); + if(kr == 0) { + int *ptr = buffer; + *ptr = size; + ptr = ptr + 1; + return ptr; + } + else + { + return NULL; + } + +} + +void osxFreeMemory(void *pointer) +{ + int size; + int *ptr = pointer; + ptr = ptr - 1; + size = *ptr; + vm_deallocate(mach_task_self(), (vm_address_t)ptr, size); +} + +static inline void __eieio(void) +{ + __asm__ ("eieio"); +} + +static inline void __sync(void) +{ + __asm__ ("sync"); +} + +static inline void __isync(void) +{ + __asm__ ("isync"); +} + +static inline void __dcbf(void *base, unsigned long offset) +{ + __asm__ ("dcbf %0, %1" + : + : "r" (base), "r" (offset) + : "r0"); +} + +static inline void __dcbst(void *base, unsigned long offset) +{ + __asm__ ("dcbst %0, %1" + : + : "r" (base), "r" (offset) + : "r0"); +} + +static inline void __dcbz(void *base, unsigned long offset) +{ + __asm__ ("dcbz %0, %1" + : + : "r" (base), "r" (offset) + : "r0"); +} + +void Sys_FlushCacheMemory( void *base, int bytes ) { + unsigned long i; + + for(i = 0; i < bytes; i+= 32) { + __dcbf(base,i); + } + __sync(); + __isync(); + __dcbf(base, i); + __sync(); + __isync(); + *(volatile unsigned long *)(base + i); + __isync(); +} diff --git a/sys/osx/misc/ftoi.patch b/sys/osx/misc/ftoi.patch new file mode 100644 index 000000000..180236332 --- /dev/null +++ b/sys/osx/misc/ftoi.patch @@ -0,0 +1,145 @@ +Index: neo/idlib/math/Math.h +=================================================================== +--- neo/idlib/math/Math.h (revision 1760) ++++ neo/idlib/math/Math.h (working copy) +@@ -776,6 +776,21 @@ + m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); + shift = e - IEEE_FLT_MANTISSA_BITS; + return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; ++//#elif defined( MACOS_X ) ++#elif 0 ++ double ret = __fctiw( f ); ++ return *( reinterpret_cast( &ret ) + 1 ); ++//#elif defined( MACOS_X ) ++#elif 0 ++ float c; ++ // c = __fsels( f, -0x1.0p+52, 0x1.0p+52 ); ++ __asm__ ("fsel %0,%1,%2,%3" ++ /* outputs: */ : "=f" (c) ++ /* inputs: */ : "f" (f), "f" (-0x1.0p+52), "f" (0x1.0p+52)); ++ float result = (f - c) + c; ++ if( f < result ) result -= 1.0; ++ int i = *reinterpret_cast( &f ); ++ return ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ); + #else + return (int) f; + #endif +Index: neo/idlib/precompiled.h +=================================================================== +--- neo/idlib/precompiled.h (revision 1760) ++++ neo/idlib/precompiled.h (working copy) +@@ -47,6 +47,10 @@ + + #endif /* _WIN32 */ + ++#if defined( MACOS_X ) ++#include ++#endif ++ + //----------------------------------------------------- + + #if !defined( _DEBUG ) && !defined( NDEBUG ) +Index: neo/TestSIMD/math/Math.h +=================================================================== +--- neo/TestSIMD/math/Math.h (revision 1760) ++++ neo/TestSIMD/math/Math.h (working copy) +@@ -143,6 +143,7 @@ + static float Rint( float f ); // returns the nearest integer + static int Ftoi( float f ); // float to int conversion + static int FtoiFast( float f ); // fast float to int conversion but rounds to nearest ++ static unsigned int FtouiFast( float f ); // fast float to unsigned int conversion + static unsigned long Ftol( float f ); // float to long conversion + static unsigned long FtolFast( float ); // fast float to long conversion but rounds to nearest + +@@ -673,11 +674,31 @@ + __asm fld f + __asm fistp i + return i; ++//#elif defined( MACOS_X ) ++#elif 0 ++ int i, s, e, m, shift; ++ i = *reinterpret_cast( &f ); ++ s = i >> IEEE_FLT_SIGN_BIT; ++ e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; ++ m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); ++ shift = e - IEEE_FLT_MANTISSA_BITS; ++ return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s; + #else + return (int) f; + #endif + } + ++ID_INLINE unsigned int idMath::FtouiFast( float f ) { ++#ifdef _WIN32 ++ int i; ++ __asm fld f ++ __asm fistp i ++ return i; ++#else ++ return (unsigned int) f; ++#endif ++} ++ + ID_INLINE unsigned long idMath::Ftol( float f ) { + return (unsigned long) f; + } +Index: neo/TestSIMD/math/Simd.cpp +=================================================================== +--- neo/TestSIMD/math/Simd.cpp (revision 1760) ++++ neo/TestSIMD/math/Simd.cpp (working copy) +@@ -3886,6 +3886,35 @@ + GetBest( start, end, bestClocks ); + } + PrintClocks( " idAngles::ToMat3()", 1, bestClocks ); ++ ++ int j; ++ int tmp; ++ ++ bestClocks = 0; ++ tst = rnd.CRandomFloat() * 5000.0f; ++ for ( i = 0; i < NUMTESTS; i++ ) { ++ StartRecordTime( start ); ++ for ( j = 0; j < NUMTESTS; j++ ) { ++ tmp = idMath::FtoiFast( tst ); ++ } ++ StopRecordTime( end ); ++ GetBest( start, end, bestClocks ); ++ tst = rnd.CRandomFloat() * 5000.0f; ++ } ++ PrintClocks( " idMath::FtoiFast()", NUMTESTS, bestClocks ); ++ ++ bestClocks = 0; ++ tst = rnd.CRandomFloat() * 5000.0f + 5000.0f; ++ for ( i = 0; i < NUMTESTS; i++ ) { ++ StartRecordTime( start ); ++ for ( j = 0; j < NUMTESTS; j++ ) { ++ tmp = idMath::FtouiFast( tst ); ++ } ++ StopRecordTime( end ); ++ GetBest( start, end, bestClocks ); ++ tst = rnd.CRandomFloat() * 5000.0f + 5000.0f; ++ } ++ PrintClocks( " idMath::FtouiFast()", NUMTESTS, bestClocks ); + } + + /* +@@ -3903,7 +3932,7 @@ + p_generic = generic; + + +-#if 0 ++#if 1 + //patrick : running timing test + TIME_TYPE s1,s2, best; + best = 0; +@@ -3967,8 +3996,9 @@ + idLib::common->Printf( "using %s for SIMD processing\n", p_simd->GetName() ); + + GetBaseClocks(); +-#if 1 + TestMath(); ++#if 0 ++ TestMath(); + TestAdd(); + TestSub(); + TestMul(); diff --git a/sys/osx/oggVorbis.xcodeproj/project.pbxproj b/sys/osx/oggVorbis.xcodeproj/project.pbxproj new file mode 100644 index 000000000..de5805e0c --- /dev/null +++ b/sys/osx/oggVorbis.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 8125B8820912BA6000492E1F /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B83F0912BA6000492E1F /* ogg.h */; }; + 8125B8830912BA6000492E1F /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8400912BA6000492E1F /* os_types.h */; }; + 8125B8840912BA6000492E1F /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8430912BA6000492E1F /* framing.c */; }; + 8125B8850912BA6000492E1F /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8440912BA6000492E1F /* bitwise.c */; }; + 8125B8860912BA6000492E1F /* floor_all.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8470912BA6000492E1F /* floor_all.h */; }; + 8125B8870912BA6000492E1F /* psych_11.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8480912BA6000492E1F /* psych_11.h */; }; + 8125B8880912BA6000492E1F /* psych_16.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8490912BA6000492E1F /* psych_16.h */; }; + 8125B8890912BA6000492E1F /* psych_44.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84A0912BA6000492E1F /* psych_44.h */; }; + 8125B88A0912BA6000492E1F /* psych_8.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84B0912BA6000492E1F /* psych_8.h */; }; + 8125B88B0912BA6000492E1F /* residue_16.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84C0912BA6000492E1F /* residue_16.h */; }; + 8125B88C0912BA6000492E1F /* residue_44.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84D0912BA6000492E1F /* residue_44.h */; }; + 8125B88D0912BA6000492E1F /* residue_44u.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84E0912BA6000492E1F /* residue_44u.h */; }; + 8125B88E0912BA6000492E1F /* residue_8.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B84F0912BA6000492E1F /* residue_8.h */; }; + 8125B88F0912BA6000492E1F /* setup_11.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8500912BA6000492E1F /* setup_11.h */; }; + 8125B8900912BA6000492E1F /* setup_16.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8510912BA6000492E1F /* setup_16.h */; }; + 8125B8910912BA6000492E1F /* setup_22.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8520912BA6000492E1F /* setup_22.h */; }; + 8125B8920912BA6000492E1F /* setup_32.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8530912BA6000492E1F /* setup_32.h */; }; + 8125B8930912BA6000492E1F /* setup_44.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8540912BA6000492E1F /* setup_44.h */; }; + 8125B8940912BA6000492E1F /* setup_44u.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8550912BA6000492E1F /* setup_44u.h */; }; + 8125B8950912BA6000492E1F /* setup_8.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8560912BA6000492E1F /* setup_8.h */; }; + 8125B8960912BA6000492E1F /* setup_X.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8570912BA6000492E1F /* setup_X.h */; }; + 8125B8970912BA6000492E1F /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8580912BA6000492E1F /* analysis.c */; }; + 8125B8980912BA6000492E1F /* backends.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8590912BA6000492E1F /* backends.h */; }; + 8125B8990912BA6000492E1F /* bitrate.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B85A0912BA6000492E1F /* bitrate.c */; }; + 8125B89A0912BA6000492E1F /* bitrate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B85B0912BA6000492E1F /* bitrate.h */; }; + 8125B89B0912BA6000492E1F /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B85C0912BA6000492E1F /* block.c */; }; + 8125B89C0912BA6000492E1F /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B85D0912BA6000492E1F /* codebook.c */; }; + 8125B89D0912BA6000492E1F /* codebook.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B85E0912BA6000492E1F /* codebook.h */; }; + 8125B89E0912BA6000492E1F /* codec_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B85F0912BA6000492E1F /* codec_internal.h */; }; + 8125B89F0912BA6000492E1F /* envelope.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8600912BA6000492E1F /* envelope.c */; }; + 8125B8A00912BA6000492E1F /* envelope.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8610912BA6000492E1F /* envelope.h */; }; + 8125B8A10912BA6000492E1F /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8620912BA6000492E1F /* floor0.c */; }; + 8125B8A20912BA6000492E1F /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8630912BA6000492E1F /* floor1.c */; }; + 8125B8A30912BA6000492E1F /* highlevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8640912BA6000492E1F /* highlevel.h */; }; + 8125B8A40912BA6000492E1F /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8650912BA6000492E1F /* info.c */; }; + 8125B8A50912BA6000492E1F /* lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8660912BA6000492E1F /* lookup.c */; }; + 8125B8A60912BA6000492E1F /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8670912BA6000492E1F /* lookup.h */; }; + 8125B8A70912BA6000492E1F /* lookup_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8680912BA6000492E1F /* lookup_data.h */; }; + 8125B8A80912BA6000492E1F /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B86A0912BA6000492E1F /* lpc.c */; }; + 8125B8A90912BA6000492E1F /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B86B0912BA6000492E1F /* lpc.h */; }; + 8125B8AA0912BA6000492E1F /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B86C0912BA6000492E1F /* lsp.c */; }; + 8125B8AB0912BA6000492E1F /* lsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B86D0912BA6000492E1F /* lsp.h */; }; + 8125B8AC0912BA6000492E1F /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B86E0912BA6000492E1F /* mapping0.c */; }; + 8125B8AD0912BA6000492E1F /* masking.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B86F0912BA6000492E1F /* masking.h */; }; + 8125B8AE0912BA6000492E1F /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8700912BA6000492E1F /* mdct.c */; }; + 8125B8AF0912BA6000492E1F /* mdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8710912BA6000492E1F /* mdct.h */; }; + 8125B8B00912BA6000492E1F /* misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8720912BA6000492E1F /* misc.h */; }; + 8125B8B10912BA6000492E1F /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8730912BA6000492E1F /* os.h */; }; + 8125B8B20912BA6000492E1F /* psy.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8740912BA6000492E1F /* psy.c */; }; + 8125B8B30912BA6000492E1F /* psy.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8750912BA6000492E1F /* psy.h */; }; + 8125B8B40912BA6000492E1F /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8760912BA6000492E1F /* registry.c */; }; + 8125B8B50912BA6000492E1F /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8770912BA6000492E1F /* registry.h */; }; + 8125B8B60912BA6000492E1F /* res0.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8780912BA6000492E1F /* res0.c */; }; + 8125B8B70912BA6000492E1F /* scales.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8790912BA6000492E1F /* scales.h */; }; + 8125B8B80912BA6000492E1F /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B87A0912BA6000492E1F /* sharedbook.c */; }; + 8125B8B90912BA6000492E1F /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B87B0912BA6000492E1F /* smallft.c */; }; + 8125B8BA0912BA6000492E1F /* smallft.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B87C0912BA6000492E1F /* smallft.h */; }; + 8125B8BB0912BA6000492E1F /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B87D0912BA6000492E1F /* synthesis.c */; }; + 8125B8BC0912BA6000492E1F /* vorbisenc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B87E0912BA6000492E1F /* vorbisenc.c */; }; + 8125B8BD0912BA6000492E1F /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B87F0912BA6000492E1F /* vorbisfile.c */; }; + 8125B8BE0912BA6000492E1F /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = 8125B8800912BA6000492E1F /* window.h */; }; + 8125B8BF0912BA6000492E1F /* windowvb.c in Sources */ = {isa = PBXBuildFile; fileRef = 8125B8810912BA6000492E1F /* windowvb.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 8125B83C0912BA6000492E1F /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = AUTHORS; sourceTree = ""; }; + 8125B83D0912BA6000492E1F /* config_types.h.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = config_types.h.in; sourceTree = ""; }; + 8125B83E0912BA6000492E1F /* COPYING */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = COPYING; sourceTree = ""; }; + 8125B83F0912BA6000492E1F /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ogg.h; sourceTree = ""; }; + 8125B8400912BA6000492E1F /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = os_types.h; sourceTree = ""; }; + 8125B8410912BA6000492E1F /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = ""; }; + 8125B8430912BA6000492E1F /* framing.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = framing.c; sourceTree = ""; }; + 8125B8440912BA6000492E1F /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = bitwise.c; sourceTree = ""; }; + 8125B8470912BA6000492E1F /* floor_all.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = floor_all.h; sourceTree = ""; }; + 8125B8480912BA6000492E1F /* psych_11.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = psych_11.h; sourceTree = ""; }; + 8125B8490912BA6000492E1F /* psych_16.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = psych_16.h; sourceTree = ""; }; + 8125B84A0912BA6000492E1F /* psych_44.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = psych_44.h; sourceTree = ""; }; + 8125B84B0912BA6000492E1F /* psych_8.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = psych_8.h; sourceTree = ""; }; + 8125B84C0912BA6000492E1F /* residue_16.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = residue_16.h; sourceTree = ""; }; + 8125B84D0912BA6000492E1F /* residue_44.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = residue_44.h; sourceTree = ""; }; + 8125B84E0912BA6000492E1F /* residue_44u.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = residue_44u.h; sourceTree = ""; }; + 8125B84F0912BA6000492E1F /* residue_8.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = residue_8.h; sourceTree = ""; }; + 8125B8500912BA6000492E1F /* setup_11.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_11.h; sourceTree = ""; }; + 8125B8510912BA6000492E1F /* setup_16.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_16.h; sourceTree = ""; }; + 8125B8520912BA6000492E1F /* setup_22.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_22.h; sourceTree = ""; }; + 8125B8530912BA6000492E1F /* setup_32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_32.h; sourceTree = ""; }; + 8125B8540912BA6000492E1F /* setup_44.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_44.h; sourceTree = ""; }; + 8125B8550912BA6000492E1F /* setup_44u.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_44u.h; sourceTree = ""; }; + 8125B8560912BA6000492E1F /* setup_8.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_8.h; sourceTree = ""; }; + 8125B8570912BA6000492E1F /* setup_X.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = setup_X.h; sourceTree = ""; }; + 8125B8580912BA6000492E1F /* analysis.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = analysis.c; sourceTree = ""; }; + 8125B8590912BA6000492E1F /* backends.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = backends.h; sourceTree = ""; }; + 8125B85A0912BA6000492E1F /* bitrate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = bitrate.c; sourceTree = ""; }; + 8125B85B0912BA6000492E1F /* bitrate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = bitrate.h; sourceTree = ""; }; + 8125B85C0912BA6000492E1F /* block.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = block.c; sourceTree = ""; }; + 8125B85D0912BA6000492E1F /* codebook.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = codebook.c; sourceTree = ""; }; + 8125B85E0912BA6000492E1F /* codebook.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codebook.h; sourceTree = ""; }; + 8125B85F0912BA6000492E1F /* codec_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codec_internal.h; sourceTree = ""; }; + 8125B8600912BA6000492E1F /* envelope.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = envelope.c; sourceTree = ""; }; + 8125B8610912BA6000492E1F /* envelope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = envelope.h; sourceTree = ""; }; + 8125B8620912BA6000492E1F /* floor0.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = floor0.c; sourceTree = ""; }; + 8125B8630912BA6000492E1F /* floor1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = floor1.c; sourceTree = ""; }; + 8125B8640912BA6000492E1F /* highlevel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = highlevel.h; sourceTree = ""; }; + 8125B8650912BA6000492E1F /* info.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = info.c; sourceTree = ""; }; + 8125B8660912BA6000492E1F /* lookup.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = lookup.c; sourceTree = ""; }; + 8125B8670912BA6000492E1F /* lookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = ""; }; + 8125B8680912BA6000492E1F /* lookup_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lookup_data.h; sourceTree = ""; }; + 8125B8690912BA6000492E1F /* lookups.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = lookups.pl; sourceTree = ""; }; + 8125B86A0912BA6000492E1F /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = ""; }; + 8125B86B0912BA6000492E1F /* lpc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lpc.h; sourceTree = ""; }; + 8125B86C0912BA6000492E1F /* lsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = lsp.c; sourceTree = ""; }; + 8125B86D0912BA6000492E1F /* lsp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lsp.h; sourceTree = ""; }; + 8125B86E0912BA6000492E1F /* mapping0.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mapping0.c; sourceTree = ""; }; + 8125B86F0912BA6000492E1F /* masking.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = masking.h; sourceTree = ""; }; + 8125B8700912BA6000492E1F /* mdct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mdct.c; sourceTree = ""; }; + 8125B8710912BA6000492E1F /* mdct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mdct.h; sourceTree = ""; }; + 8125B8720912BA6000492E1F /* misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = ""; }; + 8125B8730912BA6000492E1F /* os.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = os.h; sourceTree = ""; }; + 8125B8740912BA6000492E1F /* psy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = psy.c; sourceTree = ""; }; + 8125B8750912BA6000492E1F /* psy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = psy.h; sourceTree = ""; }; + 8125B8760912BA6000492E1F /* registry.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = registry.c; sourceTree = ""; }; + 8125B8770912BA6000492E1F /* registry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = registry.h; sourceTree = ""; }; + 8125B8780912BA6000492E1F /* res0.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = res0.c; sourceTree = ""; }; + 8125B8790912BA6000492E1F /* scales.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = scales.h; sourceTree = ""; }; + 8125B87A0912BA6000492E1F /* sharedbook.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = sharedbook.c; sourceTree = ""; }; + 8125B87B0912BA6000492E1F /* smallft.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = smallft.c; sourceTree = ""; }; + 8125B87C0912BA6000492E1F /* smallft.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = smallft.h; sourceTree = ""; }; + 8125B87D0912BA6000492E1F /* synthesis.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = synthesis.c; sourceTree = ""; }; + 8125B87E0912BA6000492E1F /* vorbisenc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = vorbisenc.c; sourceTree = ""; }; + 8125B87F0912BA6000492E1F /* vorbisfile.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = vorbisfile.c; sourceTree = ""; }; + 8125B8800912BA6000492E1F /* window.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = ""; }; + 8125B8810912BA6000492E1F /* windowvb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = windowvb.c; sourceTree = ""; }; + D2AAC046055464E500DB518D /* liboggVorbis_nopic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liboggVorbis_nopic.a; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D289987405E68DCB004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* oggVorbis */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + name = oggVorbis; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 8125B83B0912BA6000492E1F /* ogg */, + 8125B8420912BA6000492E1F /* oggsrc */, + 8125B8450912BA6000492E1F /* vorbissrc */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC046055464E500DB518D /* liboggVorbis_nopic.a */, + ); + name = Products; + sourceTree = ""; + }; + 8125B83B0912BA6000492E1F /* ogg */ = { + isa = PBXGroup; + children = ( + 8125B83C0912BA6000492E1F /* AUTHORS */, + 8125B83D0912BA6000492E1F /* config_types.h.in */, + 8125B83E0912BA6000492E1F /* COPYING */, + 8125B83F0912BA6000492E1F /* ogg.h */, + 8125B8400912BA6000492E1F /* os_types.h */, + 8125B8410912BA6000492E1F /* README */, + ); + name = ogg; + path = ../../sound/OggVorbis/ogg; + sourceTree = SOURCE_ROOT; + }; + 8125B8420912BA6000492E1F /* oggsrc */ = { + isa = PBXGroup; + children = ( + 8125B8430912BA6000492E1F /* framing.c */, + 8125B8440912BA6000492E1F /* bitwise.c */, + ); + name = oggsrc; + path = ../../sound/OggVorbis/oggsrc; + sourceTree = SOURCE_ROOT; + }; + 8125B8450912BA6000492E1F /* vorbissrc */ = { + isa = PBXGroup; + children = ( + 8125B8460912BA6000492E1F /* modes */, + 8125B8580912BA6000492E1F /* analysis.c */, + 8125B8590912BA6000492E1F /* backends.h */, + 8125B85A0912BA6000492E1F /* bitrate.c */, + 8125B85B0912BA6000492E1F /* bitrate.h */, + 8125B85C0912BA6000492E1F /* block.c */, + 8125B85D0912BA6000492E1F /* codebook.c */, + 8125B85E0912BA6000492E1F /* codebook.h */, + 8125B85F0912BA6000492E1F /* codec_internal.h */, + 8125B8600912BA6000492E1F /* envelope.c */, + 8125B8610912BA6000492E1F /* envelope.h */, + 8125B8620912BA6000492E1F /* floor0.c */, + 8125B8630912BA6000492E1F /* floor1.c */, + 8125B8640912BA6000492E1F /* highlevel.h */, + 8125B8650912BA6000492E1F /* info.c */, + 8125B8660912BA6000492E1F /* lookup.c */, + 8125B8670912BA6000492E1F /* lookup.h */, + 8125B8680912BA6000492E1F /* lookup_data.h */, + 8125B8690912BA6000492E1F /* lookups.pl */, + 8125B86A0912BA6000492E1F /* lpc.c */, + 8125B86B0912BA6000492E1F /* lpc.h */, + 8125B86C0912BA6000492E1F /* lsp.c */, + 8125B86D0912BA6000492E1F /* lsp.h */, + 8125B86E0912BA6000492E1F /* mapping0.c */, + 8125B86F0912BA6000492E1F /* masking.h */, + 8125B8700912BA6000492E1F /* mdct.c */, + 8125B8710912BA6000492E1F /* mdct.h */, + 8125B8720912BA6000492E1F /* misc.h */, + 8125B8730912BA6000492E1F /* os.h */, + 8125B8740912BA6000492E1F /* psy.c */, + 8125B8750912BA6000492E1F /* psy.h */, + 8125B8760912BA6000492E1F /* registry.c */, + 8125B8770912BA6000492E1F /* registry.h */, + 8125B8780912BA6000492E1F /* res0.c */, + 8125B8790912BA6000492E1F /* scales.h */, + 8125B87A0912BA6000492E1F /* sharedbook.c */, + 8125B87B0912BA6000492E1F /* smallft.c */, + 8125B87C0912BA6000492E1F /* smallft.h */, + 8125B87D0912BA6000492E1F /* synthesis.c */, + 8125B87E0912BA6000492E1F /* vorbisenc.c */, + 8125B87F0912BA6000492E1F /* vorbisfile.c */, + 8125B8800912BA6000492E1F /* window.h */, + 8125B8810912BA6000492E1F /* windowvb.c */, + ); + name = vorbissrc; + path = ../../sound/OggVorbis/vorbissrc; + sourceTree = SOURCE_ROOT; + }; + 8125B8460912BA6000492E1F /* modes */ = { + isa = PBXGroup; + children = ( + 8125B8470912BA6000492E1F /* floor_all.h */, + 8125B8480912BA6000492E1F /* psych_11.h */, + 8125B8490912BA6000492E1F /* psych_16.h */, + 8125B84A0912BA6000492E1F /* psych_44.h */, + 8125B84B0912BA6000492E1F /* psych_8.h */, + 8125B84C0912BA6000492E1F /* residue_16.h */, + 8125B84D0912BA6000492E1F /* residue_44.h */, + 8125B84E0912BA6000492E1F /* residue_44u.h */, + 8125B84F0912BA6000492E1F /* residue_8.h */, + 8125B8500912BA6000492E1F /* setup_11.h */, + 8125B8510912BA6000492E1F /* setup_16.h */, + 8125B8520912BA6000492E1F /* setup_22.h */, + 8125B8530912BA6000492E1F /* setup_32.h */, + 8125B8540912BA6000492E1F /* setup_44.h */, + 8125B8550912BA6000492E1F /* setup_44u.h */, + 8125B8560912BA6000492E1F /* setup_8.h */, + 8125B8570912BA6000492E1F /* setup_X.h */, + ); + path = modes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC043055464E500DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8125B8820912BA6000492E1F /* ogg.h in Headers */, + 8125B8830912BA6000492E1F /* os_types.h in Headers */, + 8125B8860912BA6000492E1F /* floor_all.h in Headers */, + 8125B8870912BA6000492E1F /* psych_11.h in Headers */, + 8125B8880912BA6000492E1F /* psych_16.h in Headers */, + 8125B8890912BA6000492E1F /* psych_44.h in Headers */, + 8125B88A0912BA6000492E1F /* psych_8.h in Headers */, + 8125B88B0912BA6000492E1F /* residue_16.h in Headers */, + 8125B88C0912BA6000492E1F /* residue_44.h in Headers */, + 8125B88D0912BA6000492E1F /* residue_44u.h in Headers */, + 8125B88E0912BA6000492E1F /* residue_8.h in Headers */, + 8125B88F0912BA6000492E1F /* setup_11.h in Headers */, + 8125B8900912BA6000492E1F /* setup_16.h in Headers */, + 8125B8910912BA6000492E1F /* setup_22.h in Headers */, + 8125B8920912BA6000492E1F /* setup_32.h in Headers */, + 8125B8930912BA6000492E1F /* setup_44.h in Headers */, + 8125B8940912BA6000492E1F /* setup_44u.h in Headers */, + 8125B8950912BA6000492E1F /* setup_8.h in Headers */, + 8125B8960912BA6000492E1F /* setup_X.h in Headers */, + 8125B8980912BA6000492E1F /* backends.h in Headers */, + 8125B89A0912BA6000492E1F /* bitrate.h in Headers */, + 8125B89D0912BA6000492E1F /* codebook.h in Headers */, + 8125B89E0912BA6000492E1F /* codec_internal.h in Headers */, + 8125B8A00912BA6000492E1F /* envelope.h in Headers */, + 8125B8A30912BA6000492E1F /* highlevel.h in Headers */, + 8125B8A60912BA6000492E1F /* lookup.h in Headers */, + 8125B8A70912BA6000492E1F /* lookup_data.h in Headers */, + 8125B8A90912BA6000492E1F /* lpc.h in Headers */, + 8125B8AB0912BA6000492E1F /* lsp.h in Headers */, + 8125B8AD0912BA6000492E1F /* masking.h in Headers */, + 8125B8AF0912BA6000492E1F /* mdct.h in Headers */, + 8125B8B00912BA6000492E1F /* misc.h in Headers */, + 8125B8B10912BA6000492E1F /* os.h in Headers */, + 8125B8B30912BA6000492E1F /* psy.h in Headers */, + 8125B8B50912BA6000492E1F /* registry.h in Headers */, + 8125B8B70912BA6000492E1F /* scales.h in Headers */, + 8125B8BA0912BA6000492E1F /* smallft.h in Headers */, + 8125B8BE0912BA6000492E1F /* window.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC045055464E500DB518D /* oggVorbis_nopic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8125B8310912BA3100492E1F /* Build configuration list for PBXNativeTarget "oggVorbis_nopic" */; + buildPhases = ( + D2AAC043055464E500DB518D /* Headers */, + D2AAC044055464E500DB518D /* Sources */, + D289987405E68DCB004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = oggVorbis_nopic; + productName = oggVorbis; + productReference = D2AAC046055464E500DB518D /* liboggVorbis_nopic.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + ORGANIZATIONNAME = "id Software LLC"; + }; + buildConfigurationList = 8125B8350912BA3100492E1F /* Build configuration list for PBXProject "oggVorbis" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* oggVorbis */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC045055464E500DB518D /* oggVorbis_nopic */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC044055464E500DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8125B8840912BA6000492E1F /* framing.c in Sources */, + 8125B8850912BA6000492E1F /* bitwise.c in Sources */, + 8125B8970912BA6000492E1F /* analysis.c in Sources */, + 8125B8990912BA6000492E1F /* bitrate.c in Sources */, + 8125B89B0912BA6000492E1F /* block.c in Sources */, + 8125B89C0912BA6000492E1F /* codebook.c in Sources */, + 8125B89F0912BA6000492E1F /* envelope.c in Sources */, + 8125B8A10912BA6000492E1F /* floor0.c in Sources */, + 8125B8A20912BA6000492E1F /* floor1.c in Sources */, + 8125B8A40912BA6000492E1F /* info.c in Sources */, + 8125B8A50912BA6000492E1F /* lookup.c in Sources */, + 8125B8A80912BA6000492E1F /* lpc.c in Sources */, + 8125B8AA0912BA6000492E1F /* lsp.c in Sources */, + 8125B8AC0912BA6000492E1F /* mapping0.c in Sources */, + 8125B8AE0912BA6000492E1F /* mdct.c in Sources */, + 8125B8B20912BA6000492E1F /* psy.c in Sources */, + 8125B8B40912BA6000492E1F /* registry.c in Sources */, + 8125B8B60912BA6000492E1F /* res0.c in Sources */, + 8125B8B80912BA6000492E1F /* sharedbook.c in Sources */, + 8125B8B90912BA6000492E1F /* smallft.c in Sources */, + 8125B8BB0912BA6000492E1F /* synthesis.c in Sources */, + 8125B8BC0912BA6000492E1F /* vorbisenc.c in Sources */, + 8125B8BD0912BA6000492E1F /* vorbisfile.c in Sources */, + 8125B8BF0912BA6000492E1F /* windowvb.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 8125B8320912BA3100492E1F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + PREBINDING = NO; + PRODUCT_NAME = oggVorbis_nopic; + VALID_ARCHS = "ppc i386"; + ZERO_LINK = YES; + }; + name = Debug; + }; + 8125B8330912BA3100492E1F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + "-fomit-frame-pointer", + "-fno-common", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + ); + PREBINDING = NO; + PRODUCT_NAME = oggVorbis_nopic; + SYMROOT = build; + VALID_ARCHS = "i386 ppc"; + ZERO_LINK = NO; + }; + name = Release; + }; + 8125B8360912BA3100492E1F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 1; + HEADER_SEARCH_PATHS = ../../sound/OggVorbis/vorbissrc/; + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Debug; + }; + 8125B8370912BA3100492E1F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_MODEL_TUNING = ""; + GCC_ONE_BYTE_BOOL = YES; + GCC_OPTIMIZATION_LEVEL = 3; + HEADER_SEARCH_PATHS = ../../sound/OggVorbis/vorbissrc/; + MACOSX_DEPLOYMENT_TARGET = 10.5; + OTHER_CFLAGS = ( + "-finline", + "-finline-limit=1000", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fpermissive", + "-fomit-frame-pointer", + "-fno-common", + ); + SDKROOT = macosx10.5; + VALID_ARCHS = i386; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8125B8310912BA3100492E1F /* Build configuration list for PBXNativeTarget "oggVorbis_nopic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8125B8320912BA3100492E1F /* Debug */, + 8125B8330912BA3100492E1F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 8125B8350912BA3100492E1F /* Build configuration list for PBXProject "oggVorbis" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8125B8360912BA3100492E1F /* Debug */, + 8125B8370912BA3100492E1F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/sys/osx/png.xcodeproj/project.pbxproj b/sys/osx/png.xcodeproj/project.pbxproj new file mode 100644 index 000000000..11cc4bb7d --- /dev/null +++ b/sys/osx/png.xcodeproj/project.pbxproj @@ -0,0 +1,241 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3A176CEE149366470077AB23 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CDE149366470077AB23 /* png.c */; }; + 3A176CEF149366470077AB23 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CDF149366470077AB23 /* pngerror.c */; }; + 3A176CF0149366470077AB23 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE0149366470077AB23 /* pngget.c */; }; + 3A176CF1149366470077AB23 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE1149366470077AB23 /* pngmem.c */; }; + 3A176CF2149366470077AB23 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE2149366470077AB23 /* pngpread.c */; }; + 3A176CF3149366470077AB23 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE3149366470077AB23 /* pngread.c */; }; + 3A176CF4149366470077AB23 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE4149366470077AB23 /* pngrio.c */; }; + 3A176CF5149366470077AB23 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE5149366470077AB23 /* pngrtran.c */; }; + 3A176CF6149366470077AB23 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE6149366470077AB23 /* pngrutil.c */; }; + 3A176CF7149366470077AB23 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE7149366470077AB23 /* pngset.c */; }; + 3A176CF8149366470077AB23 /* pngtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE8149366470077AB23 /* pngtest.c */; }; + 3A176CF9149366470077AB23 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CE9149366470077AB23 /* pngtrans.c */; }; + 3A176CFA149366470077AB23 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CEA149366470077AB23 /* pngwio.c */; }; + 3A176CFB149366470077AB23 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CEB149366470077AB23 /* pngwrite.c */; }; + 3A176CFC149366470077AB23 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CEC149366470077AB23 /* pngwtran.c */; }; + 3A176CFD149366470077AB23 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176CED149366470077AB23 /* pngwutil.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3A176C98149365AD0077AB23 /* libpng.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpng.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A176CDE149366470077AB23 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../../lib/libpng/png.c; sourceTree = SOURCE_ROOT; }; + 3A176CDF149366470077AB23 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../../lib/libpng/pngerror.c; sourceTree = SOURCE_ROOT; }; + 3A176CE0149366470077AB23 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../../lib/libpng/pngget.c; sourceTree = SOURCE_ROOT; }; + 3A176CE1149366470077AB23 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../../lib/libpng/pngmem.c; sourceTree = SOURCE_ROOT; }; + 3A176CE2149366470077AB23 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../../lib/libpng/pngpread.c; sourceTree = SOURCE_ROOT; }; + 3A176CE3149366470077AB23 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../../lib/libpng/pngread.c; sourceTree = SOURCE_ROOT; }; + 3A176CE4149366470077AB23 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../../lib/libpng/pngrio.c; sourceTree = SOURCE_ROOT; }; + 3A176CE5149366470077AB23 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../../lib/libpng/pngrtran.c; sourceTree = SOURCE_ROOT; }; + 3A176CE6149366470077AB23 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../../lib/libpng/pngrutil.c; sourceTree = SOURCE_ROOT; }; + 3A176CE7149366470077AB23 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../../lib/libpng/pngset.c; sourceTree = SOURCE_ROOT; }; + 3A176CE8149366470077AB23 /* pngtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtest.c; path = ../../lib/libpng/pngtest.c; sourceTree = SOURCE_ROOT; }; + 3A176CE9149366470077AB23 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../../lib/libpng/pngtrans.c; sourceTree = SOURCE_ROOT; }; + 3A176CEA149366470077AB23 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../../lib/libpng/pngwio.c; sourceTree = SOURCE_ROOT; }; + 3A176CEB149366470077AB23 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = ../../lib/libpng/pngwrite.c; sourceTree = SOURCE_ROOT; }; + 3A176CEC149366470077AB23 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../../lib/libpng/pngwtran.c; sourceTree = SOURCE_ROOT; }; + 3A176CED149366470077AB23 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../../lib/libpng/pngwutil.c; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3A176C96149365AD0077AB23 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3A176C89149365A60077AB23 = { + isa = PBXGroup; + children = ( + 3A176CDE149366470077AB23 /* png.c */, + 3A176CDF149366470077AB23 /* pngerror.c */, + 3A176CE0149366470077AB23 /* pngget.c */, + 3A176CE1149366470077AB23 /* pngmem.c */, + 3A176CE2149366470077AB23 /* pngpread.c */, + 3A176CE3149366470077AB23 /* pngread.c */, + 3A176CE4149366470077AB23 /* pngrio.c */, + 3A176CE5149366470077AB23 /* pngrtran.c */, + 3A176CE6149366470077AB23 /* pngrutil.c */, + 3A176CE7149366470077AB23 /* pngset.c */, + 3A176CE8149366470077AB23 /* pngtest.c */, + 3A176CE9149366470077AB23 /* pngtrans.c */, + 3A176CEA149366470077AB23 /* pngwio.c */, + 3A176CEB149366470077AB23 /* pngwrite.c */, + 3A176CEC149366470077AB23 /* pngwtran.c */, + 3A176CED149366470077AB23 /* pngwutil.c */, + 3A176C99149365AD0077AB23 /* Products */, + ); + sourceTree = ""; + }; + 3A176C99149365AD0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A176C98149365AD0077AB23 /* libpng.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3A176C94149365AD0077AB23 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3A176C97149365AD0077AB23 /* png */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3A176C9C149365AD0077AB23 /* Build configuration list for PBXNativeTarget "png" */; + buildPhases = ( + 3A176C94149365AD0077AB23 /* Headers */, + 3A176C95149365AD0077AB23 /* Sources */, + 3A176C96149365AD0077AB23 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = png; + productName = png; + productReference = 3A176C98149365AD0077AB23 /* libpng.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3A176C8B149365A60077AB23 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 3A176C8E149365A60077AB23 /* Build configuration list for PBXProject "png" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 0; + mainGroup = 3A176C89149365A60077AB23; + productRefGroup = 3A176C99149365AD0077AB23 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3A176C97149365AD0077AB23 /* png */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 3A176C95149365AD0077AB23 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A176CEE149366470077AB23 /* png.c in Sources */, + 3A176CEF149366470077AB23 /* pngerror.c in Sources */, + 3A176CF0149366470077AB23 /* pngget.c in Sources */, + 3A176CF1149366470077AB23 /* pngmem.c in Sources */, + 3A176CF2149366470077AB23 /* pngpread.c in Sources */, + 3A176CF3149366470077AB23 /* pngread.c in Sources */, + 3A176CF4149366470077AB23 /* pngrio.c in Sources */, + 3A176CF5149366470077AB23 /* pngrtran.c in Sources */, + 3A176CF6149366470077AB23 /* pngrutil.c in Sources */, + 3A176CF7149366470077AB23 /* pngset.c in Sources */, + 3A176CF8149366470077AB23 /* pngtest.c in Sources */, + 3A176CF9149366470077AB23 /* pngtrans.c in Sources */, + 3A176CFA149366470077AB23 /* pngwio.c in Sources */, + 3A176CFB149366470077AB23 /* pngwrite.c in Sources */, + 3A176CFC149366470077AB23 /* pngwtran.c in Sources */, + 3A176CFD149366470077AB23 /* pngwutil.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3A176C8C149365A60077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + name = Debug; + }; + 3A176C8D149365A60077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + name = Release; + }; + 3A176C9A149365AD0077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = png; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/libpng\""; + }; + name = Debug; + }; + 3A176C9B149365AD0077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = png; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/libpng\""; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3A176C8E149365A60077AB23 /* Build configuration list for PBXProject "png" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A176C8C149365A60077AB23 /* Debug */, + 3A176C8D149365A60077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3A176C9C149365AD0077AB23 /* Build configuration list for PBXNativeTarget "png" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A176C9A149365AD0077AB23 /* Debug */, + 3A176C9B149365AD0077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3A176C8B149365A60077AB23 /* Project object */; +} diff --git a/sys/osx/showcursor b/sys/osx/showcursor new file mode 100644 index 000000000..551754552 Binary files /dev/null and b/sys/osx/showcursor differ diff --git a/sys/osx/showcursor.c b/sys/osx/showcursor.c new file mode 100644 index 000000000..cb889102b --- /dev/null +++ b/sys/osx/showcursor.c @@ -0,0 +1,54 @@ +/* + cc -o showcursor showcursor.c -framework IOKit +*/ + +#include +#include +#include + +mach_port_t masterPort; + +io_connect_t OpenEventDriver( void ) +{ + register kern_return_t kr; + mach_port_t ev, service, iter; + + kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( kIOHIDSystemClass ), &iter); + assert( KERN_SUCCESS == kr); + + service = IOIteratorNext( iter ); + assert(service); + + kr = IOServiceOpen( service, mach_task_self(), kIOHIDParamConnectType, &ev); + assert( KERN_SUCCESS == kr ); + + IOObjectRelease( service ); + IOObjectRelease( iter ); + + return( ev ); +} + + +void TestParams( io_connect_t ev, boolean_t show ) +{ + kern_return_t kr; + + kr = IOHIDSetCursorEnable( ev, show ); + assert(KERN_SUCCESS == kr); +} + +int main(int argc, char **argv) +{ + kern_return_t kr; + boolean_t show; + + if (argc != 2) + show = 1; + else + show = (atoi(argv[0]) != 0); + + assert( KERN_SUCCESS == ( kr = IOMasterPort( bootstrap_port, &masterPort) )); + TestParams( OpenEventDriver(), show); + + return( 0 ); +} diff --git a/sys/osx/version.plist b/sys/osx/version.plist new file mode 100644 index 000000000..6f3c68caa --- /dev/null +++ b/sys/osx/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 1 + CFBundleShortVersionString + 0.1 + CFBundleVersion + 0.1 + ProjectName + NibPBTemplates + SourceVersion + 1160200 + + diff --git a/sys/osx/ziploader.xcodeproj/project.pbxproj b/sys/osx/ziploader.xcodeproj/project.pbxproj new file mode 100644 index 000000000..0cc4445fb --- /dev/null +++ b/sys/osx/ziploader.xcodeproj/project.pbxproj @@ -0,0 +1,288 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3A176A38149359410077AB23 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A1F149359410077AB23 /* ioapi.c */; }; + 3A176A3A149359410077AB23 /* miniunz.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A21149359410077AB23 /* miniunz.c */; }; + 3A176A3B149359410077AB23 /* minizip.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A22149359410077AB23 /* minizip.c */; }; + 3A176A3C149359410077AB23 /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A23149359410077AB23 /* mztools.c */; }; + 3A176A3D149359410077AB23 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A24149359410077AB23 /* unzip.c */; }; + 3A176A3E149359410077AB23 /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A25149359410077AB23 /* zip.c */; }; + 3A176A3F149359410077AB23 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A27149359410077AB23 /* adler32.c */; }; + 3A176A40149359410077AB23 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A28149359410077AB23 /* compress.c */; }; + 3A176A41149359410077AB23 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A29149359410077AB23 /* crc32.c */; }; + 3A176A42149359410077AB23 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2A149359410077AB23 /* deflate.c */; }; + 3A176A43149359410077AB23 /* gzclose.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2B149359410077AB23 /* gzclose.c */; }; + 3A176A44149359410077AB23 /* gzlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2C149359410077AB23 /* gzlib.c */; }; + 3A176A45149359410077AB23 /* gzread.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2D149359410077AB23 /* gzread.c */; }; + 3A176A46149359410077AB23 /* gzwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2E149359410077AB23 /* gzwrite.c */; }; + 3A176A47149359410077AB23 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A2F149359410077AB23 /* infback.c */; }; + 3A176A48149359410077AB23 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A30149359410077AB23 /* inffast.c */; }; + 3A176A49149359410077AB23 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A31149359410077AB23 /* inflate.c */; }; + 3A176A4A149359410077AB23 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A32149359410077AB23 /* inftrees.c */; }; + 3A176A4B149359410077AB23 /* minigzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A33149359410077AB23 /* minigzip.c */; }; + 3A176A4C149359410077AB23 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A34149359410077AB23 /* trees.c */; }; + 3A176A4D149359410077AB23 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A35149359410077AB23 /* uncompr.c */; }; + 3A176A4E149359410077AB23 /* zconf.in.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A176A36149359410077AB23 /* zconf.in.h */; }; + 3A176A4F149359410077AB23 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A176A37149359410077AB23 /* zutil.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3A1769AD1493584D0077AB23 /* libziploader.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libziploader.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A176A1F149359410077AB23 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = ""; }; + 3A176A21149359410077AB23 /* miniunz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = miniunz.c; sourceTree = ""; }; + 3A176A22149359410077AB23 /* minizip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = minizip.c; sourceTree = ""; }; + 3A176A23149359410077AB23 /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mztools.c; sourceTree = ""; }; + 3A176A24149359410077AB23 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = ""; }; + 3A176A25149359410077AB23 /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = ""; }; + 3A176A27149359410077AB23 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adler32.c; sourceTree = ""; }; + 3A176A28149359410077AB23 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = ""; }; + 3A176A29149359410077AB23 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crc32.c; sourceTree = ""; }; + 3A176A2A149359410077AB23 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = deflate.c; sourceTree = ""; }; + 3A176A2B149359410077AB23 /* gzclose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gzclose.c; sourceTree = ""; }; + 3A176A2C149359410077AB23 /* gzlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gzlib.c; sourceTree = ""; }; + 3A176A2D149359410077AB23 /* gzread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gzread.c; sourceTree = ""; }; + 3A176A2E149359410077AB23 /* gzwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gzwrite.c; sourceTree = ""; }; + 3A176A2F149359410077AB23 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = infback.c; sourceTree = ""; }; + 3A176A30149359410077AB23 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inffast.c; sourceTree = ""; }; + 3A176A31149359410077AB23 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inflate.c; sourceTree = ""; }; + 3A176A32149359410077AB23 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inftrees.c; sourceTree = ""; }; + 3A176A33149359410077AB23 /* minigzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = minigzip.c; sourceTree = ""; }; + 3A176A34149359410077AB23 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = trees.c; sourceTree = ""; }; + 3A176A35149359410077AB23 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uncompr.c; sourceTree = ""; }; + 3A176A36149359410077AB23 /* zconf.in.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zconf.in.h; sourceTree = ""; }; + 3A176A37149359410077AB23 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zutil.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3A1769AB1493584D0077AB23 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3A17699E149358400077AB23 = { + isa = PBXGroup; + children = ( + 3A176A1E149359410077AB23 /* minizip */, + 3A176A26149359410077AB23 /* zlib */, + 3A1769AE1493584D0077AB23 /* Products */, + ); + sourceTree = ""; + }; + 3A1769AE1493584D0077AB23 /* Products */ = { + isa = PBXGroup; + children = ( + 3A1769AD1493584D0077AB23 /* libziploader.a */, + ); + name = Products; + sourceTree = ""; + }; + 3A176A1E149359410077AB23 /* minizip */ = { + isa = PBXGroup; + children = ( + 3A176A1F149359410077AB23 /* ioapi.c */, + 3A176A21149359410077AB23 /* miniunz.c */, + 3A176A22149359410077AB23 /* minizip.c */, + 3A176A23149359410077AB23 /* mztools.c */, + 3A176A24149359410077AB23 /* unzip.c */, + 3A176A25149359410077AB23 /* zip.c */, + ); + name = minizip; + path = ../../lib/minizip; + sourceTree = SOURCE_ROOT; + }; + 3A176A26149359410077AB23 /* zlib */ = { + isa = PBXGroup; + children = ( + 3A176A27149359410077AB23 /* adler32.c */, + 3A176A28149359410077AB23 /* compress.c */, + 3A176A29149359410077AB23 /* crc32.c */, + 3A176A2A149359410077AB23 /* deflate.c */, + 3A176A2B149359410077AB23 /* gzclose.c */, + 3A176A2C149359410077AB23 /* gzlib.c */, + 3A176A2D149359410077AB23 /* gzread.c */, + 3A176A2E149359410077AB23 /* gzwrite.c */, + 3A176A2F149359410077AB23 /* infback.c */, + 3A176A30149359410077AB23 /* inffast.c */, + 3A176A31149359410077AB23 /* inflate.c */, + 3A176A32149359410077AB23 /* inftrees.c */, + 3A176A33149359410077AB23 /* minigzip.c */, + 3A176A34149359410077AB23 /* trees.c */, + 3A176A35149359410077AB23 /* uncompr.c */, + 3A176A36149359410077AB23 /* zconf.in.h */, + 3A176A37149359410077AB23 /* zutil.c */, + ); + name = zlib; + path = ../../lib/zlib; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3A1769A91493584D0077AB23 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A176A4E149359410077AB23 /* zconf.in.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3A1769AC1493584D0077AB23 /* ziploader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3A1769B11493584E0077AB23 /* Build configuration list for PBXNativeTarget "ziploader" */; + buildPhases = ( + 3A1769A91493584D0077AB23 /* Headers */, + 3A1769AA1493584D0077AB23 /* Sources */, + 3A1769AB1493584D0077AB23 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ziploader; + productName = ziploader; + productReference = 3A1769AD1493584D0077AB23 /* libziploader.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3A1769A0149358400077AB23 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 3A1769A3149358400077AB23 /* Build configuration list for PBXProject "ziploader" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 0; + mainGroup = 3A17699E149358400077AB23; + productRefGroup = 3A1769AE1493584D0077AB23 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3A1769AC1493584D0077AB23 /* ziploader */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 3A1769AA1493584D0077AB23 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3A176A38149359410077AB23 /* ioapi.c in Sources */, + 3A176A3A149359410077AB23 /* miniunz.c in Sources */, + 3A176A3B149359410077AB23 /* minizip.c in Sources */, + 3A176A3C149359410077AB23 /* mztools.c in Sources */, + 3A176A3D149359410077AB23 /* unzip.c in Sources */, + 3A176A3E149359410077AB23 /* zip.c in Sources */, + 3A176A3F149359410077AB23 /* adler32.c in Sources */, + 3A176A40149359410077AB23 /* compress.c in Sources */, + 3A176A41149359410077AB23 /* crc32.c in Sources */, + 3A176A42149359410077AB23 /* deflate.c in Sources */, + 3A176A43149359410077AB23 /* gzclose.c in Sources */, + 3A176A44149359410077AB23 /* gzlib.c in Sources */, + 3A176A45149359410077AB23 /* gzread.c in Sources */, + 3A176A46149359410077AB23 /* gzwrite.c in Sources */, + 3A176A47149359410077AB23 /* infback.c in Sources */, + 3A176A48149359410077AB23 /* inffast.c in Sources */, + 3A176A49149359410077AB23 /* inflate.c in Sources */, + 3A176A4A149359410077AB23 /* inftrees.c in Sources */, + 3A176A4B149359410077AB23 /* minigzip.c in Sources */, + 3A176A4C149359410077AB23 /* trees.c in Sources */, + 3A176A4D149359410077AB23 /* uncompr.c in Sources */, + 3A176A4F149359410077AB23 /* zutil.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3A1769A1149358400077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + name = Debug; + }; + 3A1769A2149358400077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + name = Release; + }; + 3A1769AF1493584E0077AB23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = ziploader; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/minizip/\" \"$(SRCROOT)/../../include/zlib/\""; + }; + name = Debug; + }; + 3A1769B01493584E0077AB23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = unix; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = ziploader; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../include/minizip/\" \"$(SRCROOT)/../../include/zlib/\""; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3A1769A3149358400077AB23 /* Build configuration list for PBXProject "ziploader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A1769A1149358400077AB23 /* Debug */, + 3A1769A2149358400077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3A1769B11493584E0077AB23 /* Build configuration list for PBXNativeTarget "ziploader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A1769AF1493584E0077AB23 /* Debug */, + 3A1769B01493584E0077AB23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3A1769A0149358400077AB23 /* Project object */; +} diff --git a/sys/posix/posix_input.cpp b/sys/posix/posix_input.cpp new file mode 100644 index 000000000..7af89e2b5 --- /dev/null +++ b/sys/posix/posix_input.cpp @@ -0,0 +1,127 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "posix_public.h" + +typedef struct poll_keyboard_event_s +{ + int key; + bool state; +} poll_keyboard_event_t; + +typedef struct poll_mouse_event_s +{ + int action; + int value; +} poll_mouse_event_t; + +#define MAX_POLL_EVENTS 50 +#define POLL_EVENTS_HEADROOM 2 // some situations require to add several events +static poll_keyboard_event_t poll_events_keyboard[MAX_POLL_EVENTS + POLL_EVENTS_HEADROOM]; +static int poll_keyboard_event_count; +static poll_mouse_event_t poll_events_mouse[MAX_POLL_EVENTS + POLL_EVENTS_HEADROOM]; +static int poll_mouse_event_count; + +/* +========== +Posix_AddKeyboardPollEvent +========== +*/ +bool Posix_AddKeyboardPollEvent(int key, bool state) { + if (poll_keyboard_event_count >= MAX_POLL_EVENTS + POLL_EVENTS_HEADROOM) + common->FatalError( "poll_keyboard_event_count exceeded MAX_POLL_EVENT + POLL_EVENTS_HEADROOM\n"); + poll_events_keyboard[poll_keyboard_event_count].key = key; + poll_events_keyboard[poll_keyboard_event_count++].state = state; + if (poll_keyboard_event_count >= MAX_POLL_EVENTS) { + common->DPrintf("WARNING: reached MAX_POLL_EVENT poll_keyboard_event_count\n"); + return false; + } + return true; +} + +/* +========== +Posix_AddMousePollEvent +========== +*/ +bool Posix_AddMousePollEvent(int action, int value) { + if (poll_mouse_event_count >= MAX_POLL_EVENTS + POLL_EVENTS_HEADROOM) + common->FatalError( "poll_mouse_event_count exceeded MAX_POLL_EVENT + POLL_EVENTS_HEADROOM\n"); + poll_events_mouse[poll_mouse_event_count].action = action; + poll_events_mouse[poll_mouse_event_count++].value = value; + if (poll_mouse_event_count >= MAX_POLL_EVENTS) { + common->DPrintf("WARNING: reached MAX_POLL_EVENT poll_mouse_event_count\n"); + return false; + } + return true; +} + +/* +=========================================================================== +polled from GetDirectUsercmd +async input polling is obsolete +we have a single entry point for both mouse and keyboard +the mouse/keyboard seperation is API legacy +=========================================================================== +*/ + +int Sys_PollKeyboardInputEvents( void ) { + return poll_keyboard_event_count; +} + +int Sys_ReturnKeyboardInputEvent( const int n, int &key, bool &state ) { + if ( n >= poll_keyboard_event_count ) { + return 0; + } + key = poll_events_keyboard[n].key; + state = poll_events_keyboard[n].state; + return 1; +} + +void Sys_EndKeyboardInputEvents( void ) { + //isn't this were it's supposed to be, was missing some key strokes with it set below + poll_keyboard_event_count = 0; + } + +int Sys_PollMouseInputEvents( void ) { +#if 0 //moved to the Sys_End functions + poll_keyboard_event_count = 0; + poll_mouse_event_count = 0; +#endif + + // that's OS specific, implemented in osx/ and linux/ + Posix_PollInput( ); + + return poll_mouse_event_count; +} + +int Sys_ReturnMouseInputEvent( const int n, int &action, int &value ) +{ + if ( n>=poll_mouse_event_count ) { + return 0; + } + action = poll_events_mouse[ n ].action; + value = poll_events_mouse[ n ].value; + return 1; +} + +void Sys_EndMouseInputEvents( void ) { + // moved out of the Sys_PollMouseInputEvents + poll_mouse_event_count = 0; +} diff --git a/sys/posix/posix_main.cpp b/sys/posix/posix_main.cpp new file mode 100644 index 000000000..c1128b694 --- /dev/null +++ b/sys/posix/posix_main.cpp @@ -0,0 +1,1044 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "../sys_local.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "posix_public.h" + +#define MAX_OSPATH 256 +#define COMMAND_HISTORY 64 + +static int input_hide = 0; + +idEditField input_field; +static char input_ret[256]; + +static idStr history[ COMMAND_HISTORY ]; // cycle buffer +static int history_count = 0; // buffer fill up +static int history_start = 0; // current history start +static int history_current = 0; // goes back in history +idEditField history_backup; // the base edit line + +// terminal support +idCVar in_tty( "in_tty", "1", CVAR_BOOL | CVAR_INIT | CVAR_SYSTEM, "terminal tab-completion and history" ); + +static bool tty_enabled = false; +static struct termios tty_tc; + +// pid - useful when you attach to gdb.. +idCVar com_pid( "com_pid", "0", CVAR_INTEGER | CVAR_INIT | CVAR_SYSTEM, "process id" ); + +// exit - quit - error -------------------------------------------------------- + +static int set_exit = 0; +static char exit_spawn[ 1024 ]; + +/* +================ +Posix_Exit +================ +*/ +void Posix_Exit(int ret) { + if ( tty_enabled ) { + Sys_Printf( "shutdown terminal support\n" ); + if ( tcsetattr( 0, TCSADRAIN, &tty_tc ) == -1 ) { + Sys_Printf( "tcsetattr failed: %s\n", strerror( errno ) ); + } + } + // at this point, too late to catch signals + Posix_ClearSigs(); + if ( asyncThread.threadHandle ) { + Sys_DestroyThread( asyncThread ); + } + // process spawning. it's best when it happens after everything has shut down + if ( exit_spawn[0] ) { + Sys_DoStartProcess( exit_spawn, false ); + } + // in case of signal, handler tries a common->Quit + // we use set_exit to maintain a correct exit code + if ( set_exit ) { + exit( set_exit ); + } + exit( ret ); +} + +/* +================ +Posix_SetExit +================ +*/ +void Posix_SetExit(int ret) { + set_exit = 0; +} + +/* +=============== +Posix_SetExitSpawn +set the process to be spawned when we quit +=============== +*/ +void Posix_SetExitSpawn( const char *exeName ) { + idStr::Copynz( exit_spawn, exeName, 1024 ); +} + +/* +================== +idSysLocal::StartProcess +if !quit, start the process asap +otherwise, push it for execution at exit +(i.e. let complete shutdown of the game and freeing of resources happen) +NOTE: might even want to add a small delay? +================== +*/ +void idSysLocal::StartProcess( const char *exeName, bool quit ) { + if ( quit ) { + common->DPrintf( "Sys_StartProcess %s (delaying until final exit)\n", exeName ); + Posix_SetExitSpawn( exeName ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + return; + } + + common->DPrintf( "Sys_StartProcess %s\n", exeName ); + Sys_DoStartProcess( exeName ); +} + +/* +================ +Sys_Quit +================ +*/ +void Sys_Quit(void) { + Posix_Exit( EXIT_SUCCESS ); +} + +/* +================ +Sys_Milliseconds +================ +*/ +/* base time in seconds, that's our origin + timeval:tv_sec is an int: + assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038 + using unsigned long data type to work right with Sys_XTimeToSysTime */ +unsigned long sys_timeBase = 0; +/* current time in ms, using sys_timeBase as origin + NOTE: sys_timeBase*1000 + curtime -> ms since the Epoch + 0x7fffffff ms - ~24 days + or is it 48 days? the specs say int, but maybe it's casted from unsigned int? +*/ +int Sys_Milliseconds( void ) { + int curtime; + struct timeval tp; + + gettimeofday(&tp, NULL); + + if (!sys_timeBase) { + sys_timeBase = tp.tv_sec; + return tp.tv_usec / 1000; + } + + curtime = (tp.tv_sec - sys_timeBase) * 1000 + tp.tv_usec / 1000; + + return curtime; +} + +/* +================ +Sys_Mkdir +================ +*/ +void Sys_Mkdir( const char *path ) { + mkdir(path, 0777); +} + +/* +================ +Sys_ListFiles +================ +*/ +int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { + struct dirent *d; + DIR *fdir; + bool dironly = false; + char search[MAX_OSPATH]; + struct stat st; + bool debug; + + list.Clear(); + + debug = cvarSystem->GetCVarBool( "fs_debug" ); + + if (!extension) + extension = ""; + + // passing a slash as extension will find directories + if (extension[0] == '/' && extension[1] == 0) { + extension = ""; + dironly = true; + } + + // search + // NOTE: case sensitivity of directory path can screw us up here + if ((fdir = opendir(directory)) == NULL) { + if (debug) { + common->Printf("Sys_ListFiles: opendir %s failed\n", directory); + } + return -1; + } + + while ((d = readdir(fdir)) != NULL) { + idStr::snPrintf(search, sizeof(search), "%s/%s", directory, d->d_name); + if (stat(search, &st) == -1) + continue; + if (!dironly) { + idStr look(search); + idStr ext; + look.ExtractFileExtension(ext); + if (extension[0] != '\0' && ext.Icmp(&extension[1]) != 0) { + continue; + } + } + if ((dironly && !(st.st_mode & S_IFDIR)) || + (!dironly && (st.st_mode & S_IFDIR))) + continue; + + list.Append(d->d_name); + } + + closedir(fdir); + + if ( debug ) { + common->Printf( "Sys_ListFiles: %d entries in %s\n", list.Num(), directory ); + } + + return list.Num(); +} + +/* +============================================================================ +EVENT LOOP +============================================================================ +*/ + +#define MAX_QUED_EVENTS 256 +#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 ) + +static sysEvent_t eventQue[MAX_QUED_EVENTS]; +static int eventHead, eventTail; + +/* +================ +Posix_QueEvent + +ptr should either be null, or point to a block of data that can be freed later +================ +*/ +void Posix_QueEvent( sysEventType_t type, int value, int value2, + int ptrLength, void *ptr ) { + sysEvent_t *ev; + + ev = &eventQue[eventHead & MASK_QUED_EVENTS]; + if (eventHead - eventTail >= MAX_QUED_EVENTS) { + common->Printf( "Posix_QueEvent: overflow\n" ); + // we are discarding an event, but don't leak memory + // TTimo: verbose dropped event types? + if (ev->evPtr) { + Mem_Free(ev->evPtr); + ev->evPtr = NULL; + } + eventTail++; + } + + eventHead++; + + ev->evType = type; + ev->evValue = value; + ev->evValue2 = value2; + ev->evPtrLength = ptrLength; + ev->evPtr = ptr; + +#if 0 + common->Printf( "Event %d: %d %d\n", ev->evType, ev->evValue, ev->evValue2 ); +#endif +} + +/* +================ +Sys_GetEvent +================ +*/ +sysEvent_t Sys_GetEvent(void) { + static sysEvent_t ev; + + // return if we have data + if (eventHead > eventTail) { + eventTail++; + return eventQue[(eventTail - 1) & MASK_QUED_EVENTS]; + } + // return the empty event with the current time + memset(&ev, 0, sizeof(ev)); + + return ev; +} + +/* +================ +Sys_ClearEvents +================ +*/ +void Sys_ClearEvents( void ) { + eventHead = eventTail = 0; +} + +/* +================ +Posix_Cwd +================ +*/ +const char *Posix_Cwd( void ) { + static char cwd[MAX_OSPATH]; + + getcwd( cwd, sizeof( cwd ) - 1 ); + cwd[MAX_OSPATH-1] = 0; + + return cwd; +} + +/* +================= +Sys_GetMemoryStatus +================= +*/ +void Sys_GetMemoryStatus( sysMemoryStats_t &stats ) { + common->Printf( "FIXME: Sys_GetMemoryStatus stub\n" ); +} + +void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats ) { + common->Printf( "FIXME: Sys_GetCurrentMemoryStatus\n" ); +} + +void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t &stats ) { + common->Printf( "FIXME: Sys_GetExeLaunchMemoryStatus\n" ); +} + +/* +================= +Sys_Init +Posix_EarlyInit/Posix_LateInit is better +================= +*/ +void Sys_Init( void ) { } + +/* +================= +Posix_Shutdown +================= +*/ +void Posix_Shutdown( void ) { + for ( int i = 0; i < COMMAND_HISTORY; i++ ) { + history[ i ].Clear(); + } +} + +/* +================= +Sys_DLL_Load +TODO: OSX - use the native API instead? NSModule +================= +*/ +int Sys_DLL_Load( const char *path ) { + void *handle = dlopen( path, RTLD_NOW ); + if ( !handle ) { + Sys_Printf( "dlopen '%s' failed: %s\n", path, dlerror() ); + } + return (int)handle; +} + +/* +================= +Sys_DLL_GetProcAddress +================= +*/ +void* Sys_DLL_GetProcAddress( int handle, const char *sym ) { + const char *error; + void *ret = dlsym( (void *)handle, sym ); + if ((error = dlerror()) != NULL) { + Sys_Printf( "dlsym '%s' failed: %s\n", sym, error ); + } + return ret; +} + +/* +================= +Sys_DLL_Unload +================= +*/ +void Sys_DLL_Unload( int handle ) { + dlclose( (void *)handle ); +} + +/* +================ +Sys_ShowConsole +================ +*/ +void Sys_ShowConsole( int visLevel, bool quitOnClose ) { } + +// --------------------------------------------------------------------------- + +// only relevant when specified on command line +const char *Sys_DefaultCDPath( void ) { + return ""; +} + +long Sys_FileTimeStamp(FILE * fp) { + struct stat st; + fstat(fileno(fp), &st); + return st.st_mtime; +} + +void Sys_Sleep(int msec) { + if ( msec < 20 ) { + static int last = 0; + int now = Sys_Milliseconds(); + if ( now - last > 1000 ) { + Sys_Printf("WARNING: Sys_Sleep - %d < 20 msec is not portable\n", msec); + last = now; + } + // ignore that sleep call, keep going + return; + } + // use nanosleep? keep sleeping if signal interrupt? + if (usleep(msec * 1000) == -1) + Sys_Printf("usleep: %s\n", strerror(errno)); +} + +char *Sys_GetClipboardData(void) { + Sys_Printf( "TODO: Sys_GetClipboardData\n" ); + return NULL; +} + +void Sys_SetClipboardData( const char *string ) { + Sys_Printf( "TODO: Sys_SetClipboardData\n" ); +} + + +// stub pretty much everywhere - heavy calling +void Sys_FlushCacheMemory(void *base, int bytes) +{ +// Sys_Printf("Sys_FlushCacheMemory stub\n"); +} + +bool Sys_FPU_StackIsEmpty( void ) { + return true; +} + +void Sys_FPU_ClearStack( void ) { +} + +const char *Sys_FPU_GetState( void ) { + return ""; +} + +void Sys_FPU_SetPrecision( int precision ) { +} + +/* +================ +Sys_LockMemory +================ +*/ +bool Sys_LockMemory( void *ptr, int bytes ) { + return true; +} + +/* +================ +Sys_UnlockMemory +================ +*/ +bool Sys_UnlockMemory( void *ptr, int bytes ) { + return true; +} + +/* +================ +Sys_SetPhysicalWorkMemory +================ +*/ +void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes ) { + common->DPrintf( "TODO: Sys_SetPhysicalWorkMemory\n" ); +} + +/* +=========== +Sys_GetDriveFreeSpace +return in MegaBytes +=========== +*/ +int Sys_GetDriveFreeSpace( const char *path ) { + common->DPrintf( "TODO: Sys_GetDriveFreeSpace\n" ); + return 1000 * 1024; +} + +/* +================ +Sys_AlreadyRunning +return true if there is a copy of D3 running already +================ +*/ +bool Sys_AlreadyRunning( void ) { + return false; +} + +/* +=============== +Posix_EarlyInit +=============== +*/ +void Posix_EarlyInit( void ) { + memset( &asyncThread, 0, sizeof( asyncThread ) ); + exit_spawn[0] = '\0'; + Posix_InitSigs(); + // set the base time + Sys_Milliseconds(); + Posix_InitPThreads(); +} + +/* +=============== +Posix_LateInit +=============== +*/ +void Posix_LateInit( void ) { + Posix_InitConsoleInput(); + com_pid.SetInteger( getpid() ); + common->Printf( "pid: %d\n", com_pid.GetInteger() ); + common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() ); +#ifndef ID_DEDICATED + common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() ); +#endif + Posix_StartAsyncThread( ); +} + +/* +=============== +Posix_InitConsoleInput +=============== +*/ +void Posix_InitConsoleInput( void ) { + struct termios tc; + + if ( in_tty.GetBool() ) { + if ( isatty( STDIN_FILENO ) != 1 ) { + Sys_Printf( "terminal support disabled: stdin is not a tty\n" ); + in_tty.SetBool( false ); + return; + } + if ( tcgetattr( 0, &tty_tc ) == -1 ) { + Sys_Printf( "tcgetattr failed. disabling terminal support: %s\n", strerror( errno ) ); + in_tty.SetBool( false ); + return; + } + // make the input non blocking + if ( fcntl( STDIN_FILENO, F_SETFL, fcntl( STDIN_FILENO, F_GETFL, 0 ) | O_NONBLOCK ) == -1 ) { + Sys_Printf( "fcntl STDIN non blocking failed. disabling terminal support: %s\n", strerror( errno ) ); + in_tty.SetBool( false ); + return; + } + tc = tty_tc; + /* + ECHO: don't echo input characters + ICANON: enable canonical mode. This enables the special + characters EOF, EOL, EOL2, ERASE, KILL, REPRINT, + STATUS, and WERASE, and buffers by lines. + ISIG: when any of the characters INTR, QUIT, SUSP, or + DSUSP are received, generate the corresponding signal + */ + tc.c_lflag &= ~(ECHO | ICANON); + /* + ISTRIP strip off bit 8 + INPCK enable input parity checking + */ + tc.c_iflag &= ~(ISTRIP | INPCK); + tc.c_cc[VMIN] = 1; + tc.c_cc[VTIME] = 0; + if ( tcsetattr( 0, TCSADRAIN, &tc ) == -1 ) { + Sys_Printf( "tcsetattr failed: %s\n", strerror( errno ) ); + Sys_Printf( "terminal support may not work correctly. Use +set in_tty 0 to disable it\n" ); + } +#if 0 + // make the output non blocking + if ( fcntl( STDOUT_FILENO, F_SETFL, fcntl( STDOUT_FILENO, F_GETFL, 0 ) | O_NONBLOCK ) == -1 ) { + Sys_Printf( "fcntl STDOUT non blocking failed: %s\n", strerror( errno ) ); + } +#endif + tty_enabled = true; + // check the terminal type for the supported ones + char *term = getenv( "TERM" ); + if ( term ) { + if ( strcmp( term, "linux" ) && strcmp( term, "xterm" ) && strcmp( term, "xterm-color" ) && strcmp( term, "screen" ) ) { + Sys_Printf( "WARNING: terminal type '%s' is unknown. terminal support may not work correctly\n", term ); + } + } + Sys_Printf( "terminal support enabled ( use +set in_tty 0 to disabled )\n" ); + } else { + Sys_Printf( "terminal support disabled\n" ); + } +} + +/* +================ +terminal support utilities +================ +*/ + +void tty_Del() { + char key; + key = '\b'; + write( STDOUT_FILENO, &key, 1 ); + key = ' '; + write( STDOUT_FILENO, &key, 1 ); + key = '\b'; + write( STDOUT_FILENO, &key, 1 ); +} + +void tty_Left() { + char key = '\b'; + write( STDOUT_FILENO, &key, 1 ); +} + +void tty_Right() { + char key = 27; + write( STDOUT_FILENO, &key, 1 ); + write( STDOUT_FILENO, "[C", 2 ); +} + +// clear the display of the line currently edited +// bring cursor back to beginning of line +void tty_Hide() { + int len, buf_len; + if ( !tty_enabled ) { + return; + } + if ( input_hide ) { + input_hide++; + return; + } + // clear after cursor + len = strlen( input_field.GetBuffer() ) - input_field.GetCursor(); + while ( len > 0 ) { + tty_Right(); + len--; + } + buf_len = strlen( input_field.GetBuffer() ); + while ( buf_len > 0 ) { + tty_Del(); + buf_len--; + } + input_hide++; +} + +// show the current line +void tty_Show() { + // int i; + if ( !tty_enabled ) { + return; + } + assert( input_hide > 0 ); + input_hide--; + if ( input_hide == 0 ) { + char *buf = input_field.GetBuffer(); + if ( buf[0] ) { + write( STDOUT_FILENO, buf, strlen( buf ) ); + int back = strlen( buf ) - input_field.GetCursor(); + while ( back > 0 ) { + tty_Left(); + back--; + } + } + } +} + +void tty_FlushIn() { + char key; + while ( read(0, &key, 1) != -1 ) { + Sys_Printf( "'%d' ", key ); + } + Sys_Printf( "\n" ); +} + +/* +================ +Posix_ConsoleInput +Checks for a complete line of text typed in at the console. +Return NULL if a complete line is not ready. +================ +*/ +char *Posix_ConsoleInput( void ) { + if ( tty_enabled ) { + int ret; + char key; + bool hidden = false; + while ( ( ret = read( STDIN_FILENO, &key, 1 ) ) > 0 ) { + if ( !hidden ) { + tty_Hide(); + hidden = true; + } + switch ( key ) { + case 1: + input_field.SetCursor( 0 ); + break; + case 5: + input_field.SetCursor( strlen( input_field.GetBuffer() ) ); + break; + case 127: + case 8: + input_field.CharEvent( K_BACKSPACE ); + break; + case '\n': + idStr::Copynz( input_ret, input_field.GetBuffer(), sizeof( input_ret ) ); + assert( hidden ); + tty_Show(); + write( STDOUT_FILENO, &key, 1 ); + input_field.Clear(); + if ( history_count < COMMAND_HISTORY ) { + history[ history_count ] = input_ret; + history_count++; + } else { + history[ history_start ] = input_ret; + history_start++; + history_start %= COMMAND_HISTORY; + } + history_current = 0; + return input_ret; + case '\t': + input_field.AutoComplete(); + break; + case 27: { + // enter escape sequence mode + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 ) { + Sys_Printf( "dropping sequence: '27' " ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + switch ( key ) { + case 79: + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 ) { + Sys_Printf( "dropping sequence: '27' '79' " ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + switch ( key ) { + case 72: + // xterm only + input_field.SetCursor( 0 ); + break; + case 70: + // xterm only + input_field.SetCursor( strlen( input_field.GetBuffer() ) ); + break; + default: + Sys_Printf( "dropping sequence: '27' '79' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + break; + case 91: { + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 ) { + Sys_Printf( "dropping sequence: '27' '91' " ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + switch ( key ) { + case 49: { + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 || key != 126 ) { + Sys_Printf( "dropping sequence: '27' '91' '49' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + // only screen and linux terms + input_field.SetCursor( 0 ); + break; + } + case 50: { + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 || key != 126 ) { + Sys_Printf( "dropping sequence: '27' '91' '50' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + // all terms + input_field.KeyDownEvent( K_INS ); + break; + } + case 52: { + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 || key != 126 ) { + Sys_Printf( "dropping sequence: '27' '91' '52' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + // only screen and linux terms + input_field.SetCursor( strlen( input_field.GetBuffer() ) ); + break; + } + case 51: { + ret = read( STDIN_FILENO, &key, 1 ); + if ( ret <= 0 ) { + Sys_Printf( "dropping sequence: '27' '91' '51' " ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + if ( key == 126 ) { + input_field.KeyDownEvent( K_DEL ); + break; + } + Sys_Printf( "dropping sequence: '27' '91' '51' '%d'", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + case 65: + case 66: { + // history + if ( history_current == 0 ) { + history_backup = input_field; + } + if ( key == 65 ) { + // up + history_current++; + } else { + // down + history_current--; + } + // history_current cycle: + // 0: current edit + // 1 .. Min( COMMAND_HISTORY, history_count ): back in history + if ( history_current < 0 ) { + history_current = Min( COMMAND_HISTORY, history_count ); + } else { + history_current %= Min( COMMAND_HISTORY, history_count ) + 1; + } + int index = -1; + if ( history_current == 0 ) { + input_field = history_backup; + } else { + index = history_start + Min( COMMAND_HISTORY, history_count ) - history_current; + index %= COMMAND_HISTORY; + assert( index >= 0 && index < COMMAND_HISTORY ); + input_field.SetBuffer( history[ index ] ); + } + assert( hidden ); + tty_Show(); + return NULL; + } + case 67: + input_field.KeyDownEvent( K_RIGHTARROW ); + break; + case 68: + input_field.KeyDownEvent( K_LEFTARROW ); + break; + default: + Sys_Printf( "dropping sequence: '27' '91' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + break; + } + default: + Sys_Printf( "dropping sequence: '27' '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + break; + } + default: + if ( key >= ' ' ) { + input_field.CharEvent( key ); + break; + } + Sys_Printf( "dropping sequence: '%d' ", key ); + tty_FlushIn(); + assert( hidden ); + tty_Show(); + return NULL; + } + } + if ( hidden ) { + tty_Show(); + } + return NULL; + } else { + // disabled on OSX. works fine from a terminal, but launching from Finder is causing trouble + // I'm pretty sure it could be re-enabled if needed, and just handling the Finder failure case right (TTimo) +#ifndef MACOS_X + // no terminal support - read only complete lines + int len; + fd_set fdset; + struct timeval timeout; + + FD_ZERO( &fdset ); + FD_SET( STDIN_FILENO, &fdset ); + timeout.tv_sec = 0; + timeout.tv_usec = 0; + if ( select( 1, &fdset, NULL, NULL, &timeout ) == -1 || !FD_ISSET( 0, &fdset ) ) { + return NULL; + } + + len = read( 0, input_ret, sizeof( input_ret ) ); + if ( len == 0 ) { + // EOF + return NULL; + } + + if ( len < 1 ) { + Sys_Printf( "read failed: %s\n", strerror( errno ) ); // something bad happened, cancel this line and print an error + return NULL; + } + + if ( len == sizeof( input_ret ) ) { + Sys_Printf( "read overflow\n" ); // things are likely to break, as input will be cut into pieces + } + + input_ret[ len-1 ] = '\0'; // rip off the \n and terminate + return input_ret; +#endif + } + return NULL; +} + +/* +called during frame loops, pacifier updates etc. +this is only for console input polling and misc mouse grab tasks +the actual mouse and keyboard input is in the Sys_Poll logic +*/ +void Sys_GenerateEvents( void ) { + char *s; + if ( ( s = Posix_ConsoleInput() ) ) { + char *b; + int len; + + len = strlen( s ) + 1; + b = (char *)Mem_Alloc( len ); + strcpy( b, s ); + Posix_QueEvent( SE_CONSOLE, 0, 0, len, b ); + } +} + +/* +=============== +low level output +=============== +*/ + +void Sys_DebugPrintf( const char *fmt, ... ) { + va_list argptr; + + tty_Hide(); + va_start( argptr, fmt ); + vprintf( fmt, argptr ); + va_end( argptr ); + tty_Show(); +} + +void Sys_DebugVPrintf( const char *fmt, va_list arg ) { + tty_Hide(); + vprintf( fmt, arg ); + tty_Show(); +} + +void Sys_Printf(const char *msg, ...) { + va_list argptr; + + tty_Hide(); + va_start( argptr, msg ); + vprintf( msg, argptr ); + va_end( argptr ); + tty_Show(); +} + +void Sys_VPrintf(const char *msg, va_list arg) { + tty_Hide(); + vprintf(msg, arg); + tty_Show(); +} + +/* +================ +Sys_Error +================ +*/ +void Sys_Error(const char *error, ...) { + va_list argptr; + + Sys_Printf( "Sys_Error: " ); + va_start( argptr, error ); + Sys_DebugVPrintf( error, argptr ); + va_end( argptr ); + Sys_Printf( "\n" ); + + Posix_Exit( EXIT_FAILURE ); +} + +/* +=============== +Sys_FreeOpenAL +=============== +*/ +void Sys_FreeOpenAL( void ) { } diff --git a/sys/posix/posix_net.cpp b/sys/posix/posix_net.cpp new file mode 100644 index 000000000..dd6546f26 --- /dev/null +++ b/sys/posix/posix_net.cpp @@ -0,0 +1,775 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if MACOS_X +#include +#endif + +#include "../../idlib/precompiled.h" + +idPort clientPort, serverPort; + +idCVar net_ip( "net_ip", "localhost", CVAR_SYSTEM, "local IP address" ); +idCVar net_port( "net_port", "", CVAR_SYSTEM | CVAR_INTEGER, "local IP port number" ); + +typedef struct { + unsigned long ip; + unsigned long mask; +} net_interface; + +#define MAX_INTERFACES 32 +int num_interfaces = 0; +net_interface netint[MAX_INTERFACES]; + +/* +============= +NetadrToSockadr +============= +*/ +static void NetadrToSockadr( const netadr_t * a, struct sockaddr_in *s ) { + memset(s, 0, sizeof(*s)); + + if ( a->type == NA_BROADCAST ) { + s->sin_family = AF_INET; + + s->sin_port = htons( (short)a->port ); + *(int *) &s->sin_addr = -1; + } else if ( a->type == NA_IP || a->type == NA_LOOPBACK ) { + s->sin_family = AF_INET; + + *(int *) &s->sin_addr = *(int *) &a->ip; + s->sin_port = htons( (short)a->port ); + } +} + +/* +============= +SockadrToNetadr +============= +*/ +static void SockadrToNetadr(struct sockaddr_in *s, netadr_t * a) { + unsigned int ip = *(int *)&s->sin_addr; + *(int *)&a->ip = ip; + a->port = ntohs( s->sin_port ); + // we store in network order, that loopback test is host order.. + ip = ntohl( ip ); + if ( ip == INADDR_LOOPBACK ) { + a->type = NA_LOOPBACK; + } else { + a->type = NA_IP; + } +} + +/* +============= +ExtractPort +============= +*/ +static bool ExtractPort( const char *src, char *buf, int bufsize, int *port ) { + char *p; + strncpy( buf, src, bufsize ); + p = buf; p += Min( bufsize - 1, (int)strlen( src ) ); *p = '\0'; + p = strchr( buf, ':' ); + if ( !p ) { + return false; + } + *p = '\0'; + *port = strtol( p+1, NULL, 10 ); + if ( ( *port == 0 && errno == EINVAL ) || + ( ( *port == LONG_MIN || *port == LONG_MAX ) && errno == ERANGE ) ) { + return false; + } + return true; +} + +/* +============= +StringToSockaddr +============= +*/ +static bool StringToSockaddr( const char *s, struct sockaddr_in *sadr, bool doDNSResolve ) { + struct hostent *h; + char buf[256]; + int port; + + memset( sadr, 0, sizeof( *sadr ) ); + sadr->sin_family = AF_INET; + + sadr->sin_port = 0; + + if (s[0] >= '0' && s[0] <= '9') { + if ( !inet_aton( s, &sadr->sin_addr ) ) { + // check for port + if ( !ExtractPort( s, buf, sizeof( buf ), &port ) ) { + return false; + } + if ( !inet_aton( buf, &sadr->sin_addr ) ) { + return false; + } + sadr->sin_port = htons( port ); + } + } else if ( doDNSResolve ) { + // try to remove the port first, otherwise the DNS gets confused into multiple timeouts + // failed or not failed, buf is expected to contain the appropriate host to resolve + if ( ExtractPort( s, buf, sizeof( buf ), &port ) ) { + sadr->sin_port = htons( port ); + } + if ( !( h = gethostbyname( buf ) ) ) { + return false; + } + *(int *) &sadr->sin_addr = + *(int *) h->h_addr_list[0]; + } + + return true; +} + +/* +============= +Sys_StringToAdr +============= +*/ +bool Sys_StringToNetAdr( const char *s, netadr_t * a, bool doDNSResolve ) { + struct sockaddr_in sadr; + + if ( !StringToSockaddr( s, &sadr, doDNSResolve ) ) { + return false; + } + + SockadrToNetadr( &sadr, a ); + return true; +} + +/* +============= +Sys_NetAdrToString +============= +*/ +const char *Sys_NetAdrToString( const netadr_t a ) { + static char s[64]; + + if ( a.type == NA_LOOPBACK ) { + if ( a.port ) { + idStr::snPrintf( s, sizeof(s), "localhost:%i", a.port ); + } else { + idStr::snPrintf( s, sizeof(s), "localhost" ); + } + } else if ( a.type == NA_IP ) { + idStr::snPrintf( s, sizeof(s), "%i.%i.%i.%i:%i", + a.ip[0], a.ip[1], a.ip[2], a.ip[3], a.port ); + } + return s; +} + +/* +================== +Sys_IsLANAddress +================== +*/ +bool Sys_IsLANAddress( const netadr_t adr ) { + int i; + unsigned long *p_ip; + unsigned long ip; + +#if ID_NOLANADDRESS + common->Printf( "Sys_IsLANAddress: ID_NOLANADDRESS\n" ); + return false; +#endif + + if ( adr.type == NA_LOOPBACK ) { + return true; + } + + if ( adr.type != NA_IP ) { + return false; + } + + if ( !num_interfaces ) { + return false; // well, if there's no networking, there are no LAN addresses, right + } + + for ( i = 0; i < num_interfaces; i++ ) { + p_ip = (unsigned long *)&adr.ip[0]; + ip = ntohl( *p_ip ); + if( ( netint[i].ip & netint[i].mask ) == ( ip & netint[i].mask ) ) { + return true; + } + } + + return false; +} + +/* +=================== +Sys_CompareNetAdrBase + +Compares without the port +=================== +*/ +bool Sys_CompareNetAdrBase( const netadr_t a, const netadr_t b ) { + if ( a.type != b.type ) { + return false; + } + + if ( a.type == NA_LOOPBACK ) { + return true; + } + + if ( a.type == NA_IP ) { + if ( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] ) { + return true; + } + return false; + } + + common->Printf( "Sys_CompareNetAdrBase: bad address type\n" ); + return false; +} + +/* +==================== +NET_InitNetworking +==================== +*/ +void Sys_InitNetworking(void) +{ + // haven't been able to clearly pinpoint which standards or RFCs define SIOCGIFCONF, SIOCGIFADDR, SIOCGIFNETMASK ioctls + // it seems fairly widespread, in Linux kernel ioctl, and in BSD .. so let's assume it's always available on our targets + +#if MACOS_X + unsigned int ip, mask; + struct ifaddrs *ifap, *ifp; + + num_interfaces = 0; + + if( getifaddrs( &ifap ) < 0 ) { + common->FatalError( "InitNetworking: SIOCGIFCONF error - %s\n", strerror( errno ) ); + return; + } + + for( ifp = ifap; ifp; ifp = ifp->ifa_next ) { + if ( ifp->ifa_addr->sa_family != AF_INET ) + continue; + + if ( !( ifp->ifa_flags & IFF_UP ) ) + continue; + + if ( !ifp->ifa_addr ) + continue; + + if ( !ifp->ifa_netmask ) + continue; + + ip = ntohl( *( unsigned long *)&ifp->ifa_addr->sa_data[2] ); + mask = ntohl( *( unsigned long *)&ifp->ifa_netmask->sa_data[2] ); + + if ( ip == INADDR_LOOPBACK ) { + common->Printf( "loopback\n" ); + } else { + common->Printf( "IP: %d.%d.%d.%d\n", + (unsigned char)ifp->ifa_addr->sa_data[2], + (unsigned char)ifp->ifa_addr->sa_data[3], + (unsigned char)ifp->ifa_addr->sa_data[4], + (unsigned char)ifp->ifa_addr->sa_data[5] ); + common->Printf( "NetMask: %d.%d.%d.%d\n", + (unsigned char)ifp->ifa_netmask->sa_data[2], + (unsigned char)ifp->ifa_netmask->sa_data[3], + (unsigned char)ifp->ifa_netmask->sa_data[4], + (unsigned char)ifp->ifa_netmask->sa_data[5] ); + } + netint[ num_interfaces ].ip = ip; + netint[ num_interfaces ].mask = mask; + num_interfaces++; + } +#else + int s; + char buf[ MAX_INTERFACES*sizeof( ifreq ) ]; + ifconf ifc; + ifreq *ifr; + int ifindex; + unsigned int ip, mask; + + num_interfaces = 0; + + s = socket( AF_INET, SOCK_DGRAM, 0 ); + ifc.ifc_len = MAX_INTERFACES*sizeof( ifreq ); + ifc.ifc_buf = buf; + if ( ioctl( s, SIOCGIFCONF, &ifc ) < 0 ) { + common->FatalError( "InitNetworking: SIOCGIFCONF error - %s\n", strerror( errno ) ); + return; + } + ifindex = 0; + while ( ifindex < ifc.ifc_len ) { + common->Printf( "found interface %s - ", ifc.ifc_buf + ifindex ); + // find the type - ignore interfaces for which we can find we can't get IP and mask ( not configured ) + ifr = (ifreq*)( ifc.ifc_buf + ifindex ); + if ( ioctl( s, SIOCGIFADDR, ifr ) < 0 ) { + common->Printf( "SIOCGIFADDR failed: %s\n", strerror( errno ) ); + } else { + if ( ifr->ifr_addr.sa_family != AF_INET ) { + common->Printf( "not AF_INET\n" ); + } else { + ip = ntohl( *( unsigned long *)&ifr->ifr_addr.sa_data[2] ); + if ( ip == INADDR_LOOPBACK ) { + common->Printf( "loopback\n" ); + } else { + common->Printf( "%d.%d.%d.%d", + (unsigned char)ifr->ifr_addr.sa_data[2], + (unsigned char)ifr->ifr_addr.sa_data[3], + (unsigned char)ifr->ifr_addr.sa_data[4], + (unsigned char)ifr->ifr_addr.sa_data[5] ); + } + if ( ioctl( s, SIOCGIFNETMASK, ifr ) < 0 ) { + common->Printf( " SIOCGIFNETMASK failed: %s\n", strerror( errno ) ); + } else { + mask = ntohl( *( unsigned long *)&ifr->ifr_addr.sa_data[2] ); + if ( ip != INADDR_LOOPBACK ) { + common->Printf( "/%d.%d.%d.%d\n", + (unsigned char)ifr->ifr_addr.sa_data[2], + (unsigned char)ifr->ifr_addr.sa_data[3], + (unsigned char)ifr->ifr_addr.sa_data[4], + (unsigned char)ifr->ifr_addr.sa_data[5] ); + } + netint[ num_interfaces ].ip = ip; + netint[ num_interfaces ].mask = mask; + num_interfaces++; + } + } + } + ifindex += sizeof( ifreq ); + } +#endif +} + +/* +==================== +IPSocket +==================== +*/ +static int IPSocket( const char *net_interface, int port, netadr_t *bound_to = NULL ) { + int newsocket; + struct sockaddr_in address; + int i = 1; + + if ( net_interface ) { + common->Printf( "Opening IP socket: %s:%i\n", net_interface, port ); + } else { + common->Printf( "Opening IP socket: localhost:%i\n", port ); + } + + if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == -1 ) { + common->Printf( "ERROR: IPSocket: socket: %s", strerror( errno ) ); + return 0; + } + // make it non-blocking + int on = 1; + if ( ioctl( newsocket, FIONBIO, &on ) == -1 ) { + common->Printf( "ERROR: IPSocket: ioctl FIONBIO:%s\n", + strerror( errno ) ); + return 0; + } + // make it broadcast capable + if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i) ) == -1 ) { + common->Printf( "ERROR: IPSocket: setsockopt SO_BROADCAST:%s\n", strerror( errno ) ); + return 0; + } + + if ( !net_interface || !net_interface[ 0 ] + || !idStr::Icmp( net_interface, "localhost" ) ) { + address.sin_addr.s_addr = INADDR_ANY; + } else { + StringToSockaddr( net_interface, &address, true ); + } + + if ( port == PORT_ANY ) { + address.sin_port = 0; + } else { + address.sin_port = htons((short) port); + } + + address.sin_family = AF_INET; + + if ( bind( newsocket, (const struct sockaddr *)&address, sizeof( address ) ) == -1 ) { + common->Printf( "ERROR: IPSocket: bind: %s\n", strerror( errno ) ); + close( newsocket ); + return 0; + } + + if ( bound_to ) { + unsigned int len = sizeof( address ); + if ( (unsigned int)(getsockname( newsocket, (struct sockaddr *)&address, (socklen_t*)&len )) == -1 ) { + common->Printf( "ERROR: IPSocket: getsockname: %s\n", strerror( errno ) ); + close( newsocket ); + return 0; + } + SockadrToNetadr( &address, bound_to ); + } + + return newsocket; +} + +/* +================== +idPort::idPort +================== +*/ +idPort::idPort() { + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); +} + +/* +================== +idPort::~idPort +================== +*/ +idPort::~idPort() { + Close(); +} + +/* +================== +idPort::Close +================== +*/ +void idPort::Close() { + if ( netSocket ) { + close(netSocket); + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); + } +} + +/* +================== +idPort::GetPacket +================== +*/ +bool idPort::GetPacket( netadr_t &net_from, void *data, int &size, int maxSize ) { + int ret; + struct sockaddr_in from; + int fromlen; + + if ( !netSocket ) { + return false; + } + + fromlen = sizeof( from ); + ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *) &from, (socklen_t *) &fromlen ); + + if ( ret == -1 ) { + if (errno == EWOULDBLOCK || errno == ECONNREFUSED) { + // those commonly happen, don't verbose + return false; + } + common->DPrintf( "idPort::GetPacket recvfrom(): %s\n", strerror( errno ) ); + return false; + } + + assert( ret < maxSize ); + + SockadrToNetadr( &from, &net_from ); + size = ret; + return true; +} + +/* +================== +idPort::GetPacketBlocking +================== +*/ +bool idPort::GetPacketBlocking( netadr_t &net_from, void *data, int &size, int maxSize, int timeout ) { + fd_set set; + struct timeval tv; + int ret; + + if ( !netSocket ) { + return false; + } + + if ( timeout < 0 ) { + return GetPacket( net_from, data, size, maxSize ); + } + + FD_ZERO( &set ); + FD_SET( netSocket, &set ); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = ( timeout % 1000 ) * 1000; + ret = select( netSocket+1, &set, NULL, NULL, &tv ); + if ( ret == -1 ) { + if ( errno == EINTR ) { + common->DPrintf( "idPort::GetPacketBlocking: select EINTR\n" ); + return false; + } else { + common->Error( "idPort::GetPacketBlocking: select failed: %s\n", strerror( errno ) ); + } + } + + if ( ret == 0 ) { + // timed out + return false; + } + struct sockaddr_in from; + int fromlen; + fromlen = sizeof( from ); + ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen ); + if ( ret == -1 ) { + // there should be no blocking errors once select declares things are good + common->DPrintf( "idPort::GetPacketBlocking: %s\n", strerror( errno ) ); + return false; + } + assert( ret < maxSize ); + SockadrToNetadr( &from, &net_from ); + size = ret; + return true; +} + +/* +================== +idPort::SendPacket +================== +*/ +void idPort::SendPacket( const netadr_t to, const void *data, int size ) { + int ret; + struct sockaddr_in addr; + + if ( to.type == NA_BAD ) { + common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" ); + return; + } + + if ( !netSocket ) { + return; + } + + NetadrToSockadr( &to, &addr ); + + ret = sendto( netSocket, data, size, 0, (struct sockaddr *) &addr, sizeof(addr) ); + if ( ret == -1 ) { + common->Printf( "idPort::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) ); + } +} + +/* +================== +idPort::InitForPort +================== +*/ +bool idPort::InitForPort( int portNumber ) { + netSocket = IPSocket( net_ip.GetString(), portNumber, &bound_to ); + if ( netSocket <= 0 ) { + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); + return false; + } + return true; +} + +//============================================================================= + +/* +================== +idTCP::idTCP +================== +*/ +idTCP::idTCP() { + fd = 0; + memset(&address, 0, sizeof(address)); +} + +/* +================== +idTCP::~idTCP +================== +*/ +idTCP::~idTCP() { + Close(); +} + +/* +================== +idTCP::Init +================== +*/ +bool idTCP::Init( const char *host, short port ) { + struct sockaddr_in sadr; + if ( !Sys_StringToNetAdr( host, &address, true ) ) { + common->Printf( "Couldn't resolve server name \"%s\"\n", host ); + return false; + } + address.type = NA_IP; + if (!address.port) { + address.port = port; + } + common->Printf( "\"%s\" resolved to %i.%i.%i.%i:%i\n", host, + address.ip[0], address.ip[1], address.ip[2], address.ip[3], address.port ); + NetadrToSockadr(&address, &sadr); + + if (fd) { + common->Warning("idTCP::Init: already initialized?\n"); + } + + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + fd = 0; + common->Printf("ERROR: idTCP::Init: socket: %s\n", strerror(errno)); + return false; + } + + if ( connect( fd, (const sockaddr *)&sadr, sizeof( sadr ) ) == -1 ) { + common->Printf( "ERROR: idTCP::Init: connect: %s\n", strerror( errno ) ); + close( fd ); + fd = 0; + return false; + } + + int status; + if ((status = fcntl(fd, F_GETFL, 0)) != -1) { + status |= O_NONBLOCK; /* POSIX */ + status = fcntl(fd, F_SETFL, status); + } + if (status == -1) { + common->Printf("ERROR: idTCP::Init: fcntl / O_NONBLOCK: %s\n", strerror(errno)); + close(fd); + fd = 0; + return false; + } + + common->DPrintf("Opened TCP connection\n"); + return true; +} + +/* +================== +idTCP::Close +================== +*/ +void idTCP::Close() { + if (fd) { + close(fd); + } + fd = 0; +} + +/* +================== +idTCP::Read +================== +*/ +int idTCP::Read(void *data, int size) { + int nbytes; + + if (!fd) { + common->Printf("idTCP::Read: not initialized\n"); + return -1; + } + +#if defined(_GNU_SOURCE) + // handle EINTR interrupted system call with TEMP_FAILURE_RETRY - this is probably GNU libc specific + if ( ( nbytes = TEMP_FAILURE_RETRY( read( fd, data, size ) ) ) == -1 ) { +#else + do { + nbytes = read( fd, data, size ); + } while ( nbytes == -1 && errno == EINTR ); + if ( nbytes == -1 ) { +#endif + if (errno == EAGAIN) { + return 0; + } + common->Printf("ERROR: idTCP::Read: %s\n", strerror(errno)); + Close(); + return -1; + } + + // a successful read of 0 bytes indicates remote has closed the connection + if ( nbytes == 0 ) { + common->DPrintf( "idTCP::Read: read 0 bytes - assume connection closed\n" ); + return -1; + } + + return nbytes; +} + +/* +================== +idTCP::Write +================== +*/ + +static void got_SIGPIPE( int signum ) { + common->Printf( "idTCP: SIGPIPE\n" ); +} + +int idTCP::Write(void *data, int size) { + int nbytes; + + if ( !fd ) { + common->Printf( "idTCP::Write: not initialized\n"); + return -1; + } + + struct sigaction bak_action; + struct sigaction action; + + action.sa_handler = got_SIGPIPE; + sigemptyset( &action.sa_mask ); + action.sa_flags = 0; + + if ( sigaction( SIGPIPE, &action, &bak_action ) != 0 ) { + common->Printf( "ERROR: idTCP::Write: failed to set temporary SIGPIPE handler\n" ); + Close(); + return -1; + } + +#if defined(_GNU_SOURCE) + // handle EINTR interrupted system call with TEMP_FAILURE_RETRY - this is probably GNU libc specific + if ( ( nbytes = TEMP_FAILURE_RETRY ( write( fd, data, size ) ) ) == -1 ) { +#else + do { + nbytes = write( fd, data, size ); + } while ( nbytes == -1 && errno == EINTR ); + if ( nbytes == -1 ) { +#endif + common->Printf( "ERROR: idTCP::Write: %s\n", strerror( errno ) ); + Close(); + return -1; + } + + if ( sigaction( SIGPIPE, &bak_action, NULL ) != 0 ) { + common->Printf( "ERROR: idTCP::Write: failed to reset SIGPIPE handler\n" ); + Close(); + return -1; + } + + return nbytes; +} diff --git a/sys/posix/posix_public.h b/sys/posix/posix_public.h new file mode 100644 index 000000000..05156ca68 --- /dev/null +++ b/sys/posix/posix_public.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SYS_POSIX__ +#define __SYS_POSIX__ + +#include + +void Posix_QueEvent( sysEventType_t type, int value, int value2, int ptrLength, void *ptr ); +const char* Posix_Cwd( void ); + +// called first thing. does InitSigs and various things +void Posix_EarlyInit( ); +// called after common has been initialized +void Posix_LateInit( ); + +void Posix_InitPThreads( ); +void Posix_InitSigs( ); +void Posix_ClearSigs( ); + +void Posix_Exit( int ret ); +void Posix_SetExit(int ret); // override the exit code +void Posix_SetExitSpawn( const char *exeName ); // set the process to be spawned when we quit + +void Posix_StartAsyncThread( void ); +extern xthreadInfo asyncThread; + +bool Posix_AddKeyboardPollEvent( int key, bool state ); +bool Posix_AddMousePollEvent( int action, int value ); + +void Posix_PollInput( void ); +void Posix_InitConsoleInput( void ); +void Posix_Shutdown( void ); + +void Sys_FPE_handler( int signum, siginfo_t *info, void *context ); +void Sys_DoStartProcess( const char *exeName, bool dofork = true ); // if not forking, current process gets replaced + +void Sys_AsyncThread( void ); + +#endif + diff --git a/sys/posix/posix_signal.cpp b/sys/posix/posix_signal.cpp new file mode 100644 index 000000000..a0bbf0247 --- /dev/null +++ b/sys/posix/posix_signal.cpp @@ -0,0 +1,157 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#include "posix_public.h" + +#include +#include + +const int siglist[] = { + SIGHUP, + SIGQUIT, + SIGILL, + SIGTRAP, + SIGIOT, + SIGBUS, + SIGFPE, + SIGSEGV, + SIGPIPE, + SIGABRT, + // SIGTTIN, + // SIGTTOU, + -1 + }; + +const char *signames[] = { + "SIGHUP", + "SIGQUIT", + "SIGILL", + "SIGTRAP", + "SIGIOT", + "SIGBUS", + "SIGFPE", + "SIGSEGV", + "SIGPIPE", + "SIGABRT", + // "SIGTTIN", + // "SIGTTOUT" +}; + +static char fatalError[ 1024 ]; + +/* +================ +Posix_ClearSigs +================ +*/ +void Posix_ClearSigs( ) { + struct sigaction action; + int i; + + /* Set up the structure */ + action.sa_handler = SIG_DFL; + sigemptyset( &action.sa_mask ); + action.sa_flags = 0; + + i = 0; + while ( siglist[ i ] != -1 ) { + if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) { + Sys_Printf( "Failed to reset %s handler: %s\n", signames[ i ], strerror( errno ) ); + } + i++; + } +} + +/* +================ +sig_handler +================ +*/ +static void sig_handler( int signum, siginfo_t *info, void *context ) { + static bool double_fault = false; + + if ( double_fault ) { + Sys_Printf( "double fault %s, bailing out\n", strsignal( signum ) ); + Posix_Exit( signum ); + } + + double_fault = true; + + // NOTE: see sigaction man page, could verbose the whole siginfo_t and print human readable si_code + Sys_Printf( "signal caught: %s\nsi_code %d\n", strsignal( signum ), info->si_code ); + +#ifndef ID_BT_STUB + Sys_Printf( "callstack:\n%s", Sys_GetCallStackCurStr( 30 ) ); +#endif + + if ( fatalError[ 0 ] ) { + Sys_Printf( "Was in fatal error shutdown: %s\n", fatalError ); + } + + Sys_Printf( "Trying to exit gracefully..\n" ); + + Posix_SetExit( signum ); + + common->Quit(); +} + +/* +================ +Posix_InitSigs +================ +*/ +void Posix_InitSigs( ) { + struct sigaction action; + int i; + + fatalError[0] = '\0'; + + /* Set up the structure */ + action.sa_sigaction = sig_handler; + sigemptyset( &action.sa_mask ); + action.sa_flags = SA_SIGINFO | SA_NODEFER; + + i = 0; + while ( siglist[ i ] != -1 ) { + if ( siglist[ i ] == SIGFPE ) { + action.sa_sigaction = Sys_FPE_handler; + if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) { + Sys_Printf( "Failed to set SIGFPE handler: %s\n", strerror( errno ) ); + } + action.sa_sigaction = sig_handler; + } else if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) { + Sys_Printf( "Failed to set %s handler: %s\n", signames[ i ], strerror( errno ) ); + } + i++; + } + + // if the process is backgrounded (running non interactively) + // then SIGTTIN or SIGTOU could be emitted, if not caught, turns into a SIGSTP + signal( SIGTTIN, SIG_IGN ); + signal( SIGTTOU, SIG_IGN ); +} + +/* +================== +Sys_SetFatalError +================== +*/ +void Sys_SetFatalError( const char *error ) { + strncpy( fatalError, error, sizeof( fatalError ) ); +} diff --git a/sys/posix/posix_threads.cpp b/sys/posix/posix_threads.cpp new file mode 100644 index 000000000..54d3a0ebb --- /dev/null +++ b/sys/posix/posix_threads.cpp @@ -0,0 +1,283 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../idlib/precompiled.h" +#include "posix_public.h" + +#if defined(_DEBUG) +// #define ID_VERBOSE_PTHREADS +#endif + +/* +====================================================== +locks +====================================================== +*/ + +// we use an extra lock for the local stuff +const int MAX_LOCAL_CRITICAL_SECTIONS = MAX_CRITICAL_SECTIONS + 1; +static pthread_mutex_t global_lock[ MAX_LOCAL_CRITICAL_SECTIONS ]; + +/* +================== +Sys_EnterCriticalSection +================== +*/ +void Sys_EnterCriticalSection( int index ) { + assert( index >= 0 && index < MAX_LOCAL_CRITICAL_SECTIONS ); +#ifdef ID_VERBOSE_PTHREADS + if ( pthread_mutex_trylock( &global_lock[index] ) == EBUSY ) { + Sys_Printf( "busy lock %d in thread '%s'\n", index, Sys_GetThreadName() ); + if ( pthread_mutex_lock( &global_lock[index] ) == EDEADLK ) { + Sys_Printf( "FATAL: DEADLOCK %d, in thread '%s'\n", index, Sys_GetThreadName() ); + } + } +#else + pthread_mutex_lock( &global_lock[index] ); +#endif +} + +/* +================== +Sys_LeaveCriticalSection +================== +*/ +void Sys_LeaveCriticalSection( int index ) { + assert( index >= 0 && index < MAX_LOCAL_CRITICAL_SECTIONS ); +#ifdef ID_VERBOSE_PTHREADS + if ( pthread_mutex_unlock( &global_lock[index] ) == EPERM ) { + Sys_Printf( "FATAL: NOT LOCKED %d, in thread '%s'\n", index, Sys_GetThreadName() ); + } +#else + pthread_mutex_unlock( &global_lock[index] ); +#endif +} + +/* +====================================================== +wait and trigger events +we use a single lock to manipulate the conditions, MAX_LOCAL_CRITICAL_SECTIONS-1 + +the semantics match the win32 version. signals raised while no one is waiting stay raised until a wait happens (which then does a simple pass-through) + +NOTE: we use the same mutex for all the events. I don't think this would become much of a problem +cond_wait unlocks atomically with setting the wait condition, and locks it back before exiting the function +the potential for time wasting lock waits is very low +====================================================== +*/ + +pthread_cond_t event_cond[ MAX_TRIGGER_EVENTS ]; +bool signaled[ MAX_TRIGGER_EVENTS ]; +bool waiting[ MAX_TRIGGER_EVENTS ]; + +/* +================== +Sys_WaitForEvent +================== +*/ +void Sys_WaitForEvent( int index ) { + assert( index >= 0 && index < MAX_TRIGGER_EVENTS ); + Sys_EnterCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 ); + assert( !waiting[ index ] ); // WaitForEvent from multiple threads? that wouldn't be good + if ( signaled[ index ] ) { + // emulate windows behaviour: signal has been raised already. clear and keep going + signaled[ index ] = false; + } else { + waiting[ index ] = true; + pthread_cond_wait( &event_cond[ index ], &global_lock[ MAX_LOCAL_CRITICAL_SECTIONS - 1 ] ); + waiting[ index ] = false; + } + Sys_LeaveCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 ); +} + +/* +================== +Sys_TriggerEvent +================== +*/ +void Sys_TriggerEvent( int index ) { + assert( index >= 0 && index < MAX_TRIGGER_EVENTS ); + Sys_EnterCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 ); + if ( waiting[ index ] ) { + pthread_cond_signal( &event_cond[ index ] ); + } else { + // emulate windows behaviour: if no thread is waiting, leave the signal on so next wait keeps going + signaled[ index ] = true; + } + Sys_LeaveCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 ); +} + +/* +====================================================== +thread create and destroy +====================================================== +*/ + +// not a hard limit, just what we keep track of for debugging +#define MAX_THREADS 10 +xthreadInfo *g_threads[MAX_THREADS]; + +int g_thread_count = 0; + +typedef void *(*pthread_function_t) (void *); + +/* +================== +Sys_CreateThread +================== +*/ +void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo& info, const char *name, xthreadInfo **threads, int *thread_count ) { + Sys_EnterCriticalSection( ); + pthread_attr_t attr; + pthread_attr_init( &attr ); + if ( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ) != 0 ) { + common->Error( "ERROR: pthread_attr_setdetachstate %s failed\n", name ); + } + if ( pthread_create( ( pthread_t* )&info.threadHandle, &attr, ( pthread_function_t )function, parms ) != 0 ) { + common->Error( "ERROR: pthread_create %s failed\n", name ); + } + pthread_attr_destroy( &attr ); + info.name = name; + if ( *thread_count < MAX_THREADS ) { + threads[ ( *thread_count )++ ] = &info; + } else { + common->DPrintf( "WARNING: MAX_THREADS reached\n" ); + } + Sys_LeaveCriticalSection( ); +} + +/* +================== +Sys_DestroyThread +================== +*/ +void Sys_DestroyThread( xthreadInfo& info ) { + // the target thread must have a cancelation point, otherwise pthread_cancel is useless + assert( info.threadHandle ); + if ( pthread_cancel( ( pthread_t )info.threadHandle ) != 0 ) { + common->Error( "ERROR: pthread_cancel %s failed\n", info.name ); + } + if ( pthread_join( ( pthread_t )info.threadHandle, NULL ) != 0 ) { + common->Error( "ERROR: pthread_join %s failed\n", info.name ); + } + info.threadHandle = 0; + Sys_EnterCriticalSection( ); + for( int i = 0 ; i < g_thread_count ; i++ ) { + if ( &info == g_threads[ i ] ) { + g_threads[ i ] = NULL; + int j; + for( j = i+1 ; j < g_thread_count ; j++ ) { + g_threads[ j-1 ] = g_threads[ j ]; + } + g_threads[ j-1 ] = NULL; + g_thread_count--; + Sys_LeaveCriticalSection( ); + return; + } + } + Sys_LeaveCriticalSection( ); +} + +/* +================== +Sys_GetThreadName +find the name of the calling thread +================== +*/ +const char* Sys_GetThreadName( int *index ) { + Sys_EnterCriticalSection( ); + pthread_t thread = pthread_self(); + for( int i = 0 ; i < g_thread_count ; i++ ) { + if ( thread == (pthread_t)g_threads[ i ]->threadHandle ) { + if ( index ) { + *index = i; + } + Sys_LeaveCriticalSection( ); + return g_threads[ i ]->name; + } + } + if ( index ) { + *index = -1; + } + Sys_LeaveCriticalSection( ); + return "main"; +} + +/* +========================================================= +Async Thread +========================================================= +*/ + +xthreadInfo asyncThread; + +/* +================= +Posix_StartAsyncThread +================= +*/ +void Posix_StartAsyncThread() { + if ( asyncThread.threadHandle == 0 ) { + Sys_CreateThread( (xthread_t)Sys_AsyncThread, NULL, THREAD_NORMAL, asyncThread, "Async", g_threads, &g_thread_count ); + } else { + common->Printf( "Async thread already running\n" ); + } + common->Printf( "Async thread started\n" ); +} + +/* +================== +Posix_InitPThreads +================== +*/ +void Posix_InitPThreads( ) { + int i; + pthread_mutexattr_t attr; + + // init critical sections + for ( i = 0; i < MAX_LOCAL_CRITICAL_SECTIONS; i++ ) { + pthread_mutexattr_init( &attr ); + pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK ); + pthread_mutex_init( &global_lock[i], &attr ); + pthread_mutexattr_destroy( &attr ); + } + + // init event sleep/triggers + for ( i = 0; i < MAX_TRIGGER_EVENTS; i++ ) { + pthread_cond_init( &event_cond[ i ], NULL ); + signaled[i] = false; + waiting[i] = false; + } + + // init threads table + for ( i = 0; i < MAX_THREADS; i++ ) { + g_threads[ i ] = NULL; + } +} + diff --git a/sys/scons/SConscript.core b/sys/scons/SConscript.core new file mode 100644 index 000000000..ce51269f7 --- /dev/null +++ b/sys/scons/SConscript.core @@ -0,0 +1,359 @@ +# -*- mode: python -*- +# DOOM build script +# TTimo +# http://scons.sourceforge.net + +import sys, os +import scons_utils + +Import( 'GLOBALS' ) +Import( GLOBALS ) + +jpeg_string = ' \ + jcapimin.c \ + jccoefct.c \ + jccolor.c \ + jcdctmgr.c \ + jchuff.c \ + jcinit.c \ + jcmainct.c \ + jcmarker.c \ + jcmaster.c \ + jcomapi.c \ + jcparam.c \ + jcphuff.c \ + jcprepct.c \ + jcsample.c \ + jdapimin.c \ + jdapistd.c \ + jdatadst.c \ + jdatasrc.c \ + jdcoefct.c \ + jdcolor.c \ + jddctmgr.c \ + jdhuff.c \ + jdinput.c \ + jdmainct.c \ + jdmarker.c \ + jdmaster.c \ + jdmerge.c \ + jdphuff.c \ + jdpostct.c \ + jdsample.c \ + jdtrans.c \ + jerror.c \ + jfdctflt.c \ + jfdctfst.c \ + jfdctint.c \ + jidctflt.c \ + jidctfst.c \ + jidctint.c \ + jidctred.c \ + jmemmgr.c \ + jmemnobs.c \ + jquant1.c \ + jquant2.c \ + jutils.c' + +jpeg_list = scons_utils.BuildList( 'renderer/jpeg-6', jpeg_string ) + +ogg_string = ' \ + oggsrc/bitwise.c \ + oggsrc/framing.c \ + vorbissrc/analysis.c \ + vorbissrc/bitrate.c \ + vorbissrc/block.c \ + vorbissrc/codebook.c \ + vorbissrc/envelope.c \ + vorbissrc/floor0.c \ + vorbissrc/floor1.c \ + vorbissrc/info.c \ + vorbissrc/lookup.c \ + vorbissrc/lpc.c \ + vorbissrc/lsp.c \ + vorbissrc/mapping0.c \ + vorbissrc/mdct.c \ + vorbissrc/psy.c \ + vorbissrc/registry.c \ + vorbissrc/res0.c \ + vorbissrc/sharedbook.c \ + vorbissrc/smallft.c \ + vorbissrc/synthesis.c \ + vorbissrc/vorbisenc.c \ + vorbissrc/vorbisfile.c \ + vorbissrc/windowvb.c' + +ogg_list = scons_utils.BuildList( 'sound/OggVorbis', ogg_string ) + +renderer_string = ' \ + Cinematic.cpp \ + GuiModel.cpp \ + Image_files.cpp \ + Image_init.cpp \ + Image_load.cpp \ + Image_process.cpp \ + Image_program.cpp \ + Interaction.cpp \ + Material.cpp \ + MegaTexture.cpp \ + Model.cpp \ + ModelDecal.cpp \ + ModelManager.cpp \ + ModelOverlay.cpp \ + Model_beam.cpp \ + Model_ase.cpp \ + Model_liquid.cpp \ + Model_lwo.cpp \ + Model_ma.cpp \ + Model_md3.cpp \ + Model_md5.cpp \ + Model_prt.cpp \ + Model_sprite.cpp \ + RenderEntity.cpp \ + RenderSystem.cpp \ + RenderSystem_init.cpp \ + RenderWorld.cpp \ + RenderWorld_demo.cpp \ + RenderWorld_load.cpp \ + RenderWorld_portals.cpp \ + VertexCache.cpp \ + cg_explicit.cpp \ + draw_arb.cpp \ + draw_arb2.cpp \ + draw_common.cpp \ + draw_exp_stub.cpp \ + draw_nv10.cpp \ + draw_nv20.cpp \ + draw_r200.cpp \ + tr_backend.cpp \ + tr_deform.cpp \ + tr_font.cpp \ + tr_guisurf.cpp \ + tr_light.cpp \ + tr_lightrun.cpp \ + tr_main.cpp \ + tr_orderIndexes.cpp \ + tr_polytope.cpp \ + tr_render.cpp \ + tr_rendertools.cpp \ + tr_shadowbounds.cpp \ + tr_stencilshadow.cpp \ + tr_subview.cpp \ + tr_trace.cpp \ + tr_trisurf.cpp \ + tr_turboshadow.cpp' + +renderer_list = scons_utils.BuildList( 'renderer', renderer_string ) + +framework_string = ' \ + CVarSystem.cpp \ + CmdSystem.cpp \ + Common.cpp \ + Compressor.cpp \ + Console.cpp \ + DemoFile.cpp \ + DeclAF.cpp \ + DeclEntityDef.cpp \ + DeclFX.cpp \ + DeclManager.cpp \ + DeclParticle.cpp \ + DeclPDA.cpp \ + DeclSkin.cpp \ + DeclTable.cpp \ + EditField.cpp \ + EventLoop.cpp \ + File.cpp \ + FileSystem.cpp \ + KeyInput.cpp \ + Unzip.cpp \ + UsercmdGen.cpp \ + Session_menu.cpp \ + Session.cpp \ + async/AsyncClient.cpp \ + async/AsyncNetwork.cpp \ + async/AsyncServer.cpp \ + async/MsgChannel.cpp \ + async/NetworkSystem.cpp \ + async/ServerScan.cpp' + +framework_list = scons_utils.BuildList( 'framework', framework_string ) + +cm_string = ' \ + CollisionModel_contacts.cpp \ + CollisionModel_contents.cpp \ + CollisionModel_debug.cpp \ + CollisionModel_files.cpp \ + CollisionModel_load.cpp \ + CollisionModel_rotate.cpp \ + CollisionModel_trace.cpp \ + CollisionModel_translate.cpp' +cm_list = scons_utils.BuildList( 'cm', cm_string ) + +dmap_string = ' \ + dmap.cpp \ + facebsp.cpp \ + gldraw.cpp \ + glfile.cpp \ + leakfile.cpp \ + map.cpp \ + optimize.cpp \ + output.cpp \ + portals.cpp \ + shadowopt3.cpp \ + tritjunction.cpp \ + tritools.cpp \ + ubrush.cpp \ + usurface.cpp' + +dmap_list = scons_utils.BuildList( 'tools/compilers/dmap', dmap_string ) + +aas_string = ' \ + AASBuild.cpp \ + AASBuild_file.cpp \ + AASBuild_gravity.cpp \ + AASBuild_ledge.cpp \ + AASBuild_merge.cpp \ + AASCluster.cpp \ + AASFile.cpp \ + AASFile_optimize.cpp \ + AASFile_sample.cpp \ + AASReach.cpp \ + AASFileManager.cpp \ + Brush.cpp \ + BrushBSP.cpp' + +aas_list = scons_utils.BuildList( 'tools/compilers/aas', aas_string ) + +roq_string = ' \ + NSBitmapImageRep.cpp \ + codec.cpp \ + roq.cpp \ + roqParam.cpp' + +roq_list = scons_utils.BuildList( 'tools/compilers/roqvq', roq_string ) + +renderbump_list = [ 'tools/compilers/renderbump/renderbump.cpp' ] + +snd_string = ' \ + snd_cache.cpp \ + snd_decoder.cpp \ + snd_efxfile.cpp \ + snd_emitter.cpp \ + snd_shader.cpp \ + snd_system.cpp \ + snd_wavefile.cpp \ + snd_world.cpp' + +snd_list = scons_utils.BuildList( 'sound', snd_string ) + +ui_string = ' \ + BindWindow.cpp \ + ChoiceWindow.cpp \ + DeviceContext.cpp \ + EditWindow.cpp \ + FieldWindow.cpp \ + GameBearShootWindow.cpp \ + GameBustOutWindow.cpp \ + GameSSDWindow.cpp \ + GuiScript.cpp \ + ListGUI.cpp \ + ListWindow.cpp \ + MarkerWindow.cpp \ + RegExp.cpp \ + RenderWindow.cpp \ + SimpleWindow.cpp \ + SliderWindow.cpp \ + UserInterface.cpp \ + Window.cpp \ + Winvar.cpp' + +ui_list = scons_utils.BuildList( 'ui', ui_string ) + +sys_string = ' \ + sys_local.cpp \ + posix/posix_net.cpp \ + posix/posix_main.cpp \ + posix/posix_signal.cpp \ + posix/posix_threads.cpp \ + linux/stack.cpp \ + linux/main.cpp \ + stub/util_stub.cpp' + +if ( local_dedicated == 0 ): + sys_string += ' \ + linux/glimp.cpp \ + posix/posix_input.cpp \ + linux/input.cpp \ + linux/libXNVCtrl/NVCtrl.c' +else: + sys_string += ' linux/dedicated.cpp' + +sys_list = scons_utils.BuildList( 'sys', sys_string ) + +tools_string = ' \ + guied/GEWindowWrapper_stub.cpp' + +tools_list = scons_utils.BuildList( 'tools', tools_string ) + +core_list = framework_list + jpeg_list + renderer_list + ui_list \ + + cm_list + dmap_list + renderbump_list + aas_list + roq_list \ + + snd_list + sys_list + tools_list + [ 'TypeInfo/TypeInfoGen.cpp' ] + +for i in range( len( core_list ) ): + core_list[ i ] = '../../' + core_list[ i ] + +for i in range( len( ogg_list ) ): + ogg_list[ i ] = '../../' + ogg_list[ i ] + +local_env = g_env.Clone() + +if ( local_dedicated == 1 ): + local_env.Append( CPPDEFINES = [ 'ID_DEDICATED', 'ID_GL_HARDLINK' ] ) + # don't enable alsa for a dedicated server binary + ALSA = '0' + +if ( local_gamedll == 1 ): + local_env.Append( CPPDEFINES = [ '__DOOM_DLL__' ] ) + +if ( local_demo == 1 ): + local_env.Append( CPPDEFINES = [ 'ID_DEMO_BUILD' ] ) + +if ( local_curl == 0 ): + local_env.Append( CPPDEFINES = [ 'ID_ENABLE_CURL=0' ] ) + +ogg_env = local_env.Clone() +ogg_env.Append( CPPPATH = '#sound/OggVorbis/vorbissrc' ) +libogg = ogg_env.StaticLibrary( 'ogg', ogg_list ) + +sound_env = local_env.Clone() +sound_env.Append( CPPPATH = '/usr/local/lib/oss/include' ) +# store a local copy of the include headers as well for holy build +sound_env.Append( CPPPATH = '../linux/oss/include' ) +sound_list = [ '../linux/sound.cpp' ] +if ( ALSA != '0' ): + sound_list.append( '../../sys/linux/sound_alsa.cpp' ) +else: + sound_env.Append( CPPDEFINES = 'NO_ALSA' ) +sound_lib = sound_env.StaticLibrary( 'sound', sound_list ) + +local_env.Append( LIBS = [ 'pthread', 'dl', 'rt' ] ) # greebo: Added librt +if ( local_dedicated == 0 ): + local_env.Append( LIBS = [ 'X11', 'Xext', 'Xxf86vm' ] ) # 'Xxf86dga', + local_env.Append( LIBPATH = [ '/usr/X11R6/lib' ] ) +# local_env.Append( LIBS = [ 'openal' ] ) + +source_list = core_list +source_list += idlib_objects +source_list += [ '../../glimp/sys/scons/libglimp.a' ] +source_list += libogg +source_list += curl_lib +source_list += sound_lib +source_list += [ '../../openal/stubs.cpp' ] + +source_list += g_env_noopt.StaticObject( '../../tools/compilers/dmap/optimize_gcc.cpp' ) + +if ( local_gamedll == 0 ): + source_list += game_objects + +d3wm = local_env.Program( target = 'doom', source = source_list ) +Return( 'd3wm' ) diff --git a/sys/scons/SConscript.curl b/sys/scons/SConscript.curl new file mode 100644 index 000000000..54eb1e55f --- /dev/null +++ b/sys/scons/SConscript.curl @@ -0,0 +1,43 @@ +# -*- mode: python -*- +# DOOM build script +# TTimo +# http://scons.sourceforge.net + +import os + +import scons_utils + +Import( 'GLOBALS' ) +Import( GLOBALS ) + +class idBuildCurl( scons_utils.idSetupBase ): + + def Compile( self, target = None, source = None, env = None ): + self.TrySimpleCommand( 'cd curl ; make clean' ) + cmd = 'cd curl ; CC=\'' + env['CC'] + '\' ./configure --enable-shared=no --enable-static=yes --enable-http --enable-ftp --disable-gopher --enable-file --disable-ldap --disable-dict --disable-telnet --disable-manual --enable-libgcc --disable-ipv6 --without-ssl ' + if ( self.debug ): + cmd += '--enable-debug' + else: + cmd += '--disable-debug' + os.system( cmd ) + os.system( 'cd curl ; make' ) + if ( self.debug ): + os.system( 'cd curl ; mv ./lib/.libs/libcurl.a ./lib/.libs/libcurl-debug.a' ) + else: + os.system( 'cd curl ; mv ./lib/.libs/libcurl.a ./lib/.libs/libcurl-release.a' ) + return 0 + +#build = idBuildCurl() +#if ( local_curl == 1 ): +# build.debug = 1 +# target_name = '#curl/lib/.libs/libcurl-debug.a' +#else: +# build.debug = 0 +# target_name = '#curl/lib/.libs/libcurl-release.a' + +target_name = '#linux/libcurl/libcurl.a' + +#g_env.Command( target_name, None, Action( build.Compile ) ) + +curl_libs = [ target_name, '/usr/lib/libz.a' ] +Return( 'curl_libs' ) diff --git a/sys/scons/SConscript.devil b/sys/scons/SConscript.devil index 542714344..baf7af05f 100644 --- a/sys/scons/SConscript.devil +++ b/sys/scons/SConscript.devil @@ -1,20 +1,21 @@ -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision: 4379 $ -#* $Date: 2010-12-22 15:49:40 +0100 (Mi, 22 Dez 2010) $ -#* $Author: greebo $ -#* -#* $Log$ -#* Revision 1.3 2005/11/11 22:50:09 sparhawk -#* SDK 1.3 Merge -#* -#* Revision 1.2 2004/11/28 19:23:11 sparhawk -#* Added header and Id Copyright. -#* -#* -#*************************************************************************** +#***************************************************************************** +# The Dark Mod GPL Source Code +# +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. +# +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** import scons_utils diff --git a/sys/scons/SConscript.game b/sys/scons/SConscript.game index fdb64ebb7..6313220eb 100644 --- a/sys/scons/SConscript.game +++ b/sys/scons/SConscript.game @@ -5,23 +5,24 @@ # TTimo # http://scons.sourceforge.net -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#* $Log$ -#* Revision 1.3 2005/11/11 22:50:09 sparhawk -#* SDK 1.3 Merge -#* -#* Revision 1.2 2004/11/28 19:23:11 sparhawk -#* Added header and Id Copyright. -#* -#* -#*************************************************************************** +#***************************************************************************** +# The Dark Mod GPL Source Code +# +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. +# +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** import sys, os import scons_utils @@ -31,79 +32,80 @@ Import( GLOBALS ) # Master list of source files to compile game_string = ' \ - af.cpp \ - afentity.cpp \ - actor.cpp \ - camera.cpp \ - entity.cpp \ - emitter.cpp \ - brittlefracture.cpp \ - fx.cpp \ - gameedit.cpp \ - game_local.cpp \ - game_network.cpp \ - item.cpp \ - ik.cpp \ - light.cpp \ - misc.cpp \ - mover.cpp \ - moveable.cpp \ - multiplayergame.cpp \ - player.cpp \ - playericon.cpp \ - playerview.cpp \ - projectile.cpp \ - pvs.cpp \ - securitycamera.cpp \ - smokeparticles.cpp \ - sound.cpp \ - target.cpp \ - trigger.cpp \ - weapon.cpp \ - worldspawn.cpp \ - ai/aas.cpp \ - ai/aas_debug.cpp \ - ai/aas_pathing.cpp \ - ai/aas_routing.cpp \ - ai/ai.cpp \ - ai/ai_events.cpp \ - ai/ai_pathing.cpp \ + Actor.cpp \ + AF.cpp \ + AFEntity.cpp \ + BrittleFracture.cpp \ + Camera.cpp \ + Entity.cpp \ + Emitter.cpp \ + FX.cpp \ + Game_local.cpp \ + Game_network.cpp \ + GameEdit.cpp \ + IK.cpp \ + Item.cpp \ + Light.cpp \ + Misc.cpp \ + Moveable.cpp \ + Mover.cpp \ + MultiplayerGame.cpp \ + Player.cpp \ + PlayerIcon.cpp \ + PlayerView.cpp \ + Projectile.cpp \ + Pvs.cpp \ + SecurityCamera.cpp \ + SmokeParticles.cpp \ + Sound.cpp \ + Target.cpp \ + Trigger.cpp \ + Weapon.cpp \ + WorldSpawn.cpp \ + ai/AAS.cpp \ + ai/AAS_debug.cpp \ + ai/AAS_pathing.cpp \ + ai/AAS_routing.cpp \ + ai/AI.cpp \ + ai/AI_events.cpp \ + ai/AI_pathing.cpp \ ai/MoveState.cpp \ ai/tdmAASFindEscape.cpp \ - gamesys/debuggraph.cpp \ - gamesys/class.cpp \ - gamesys/event.cpp \ - gamesys/savegame.cpp \ - gamesys/syscmds.cpp \ - gamesys/syscvar.cpp \ - gamesys/typeinfo.cpp \ - anim/anim.cpp \ - anim/anim_blend.cpp \ - anim/anim_import.cpp \ - anim/anim_testmodel.cpp \ - script/script_compiler.cpp \ - script/script_interpreter.cpp \ - script/script_program.cpp \ - script/script_thread.cpp \ - physics/clip.cpp \ - physics/force.cpp \ - physics/force_constant.cpp \ - physics/force_drag.cpp \ - physics/force_push.cpp \ - physics/force_field.cpp \ - physics/force_spring.cpp \ - physics/physics.cpp \ - physics/physics_af.cpp \ - physics/physics_actor.cpp \ - physics/physics_base.cpp \ - physics/physics_monster.cpp \ - physics/physics_liquid.cpp \ - physics/physics_parametric.cpp \ - physics/physics_player.cpp \ - physics/physics_rigidbody.cpp \ - physics/physics_static.cpp \ - physics/physics_staticmulti.cpp \ - physics/push.cpp' + anim/Anim.cpp \ + anim/Anim_Blend.cpp \ + anim/Anim_Import.cpp \ + anim/Anim_Testmodel.cpp \ + gamesys/Class.cpp \ + gamesys/DebugGraph.cpp \ + gamesys/Event.cpp \ + gamesys/SaveGame.cpp \ + gamesys/SysCmds.cpp \ + gamesys/SysCvar.cpp \ + gamesys/TypeInfo.cpp \ + physics/Clip.cpp \ + physics/Force.cpp \ + physics/Force_Constant.cpp \ + physics/Force_Drag.cpp \ + physics/Force_Field.cpp \ + physics/Force_Push.cpp \ + physics/Force_Spring.cpp \ + physics/Physics.cpp \ + physics/Physics_Actor.cpp \ + physics/Physics_AF.cpp \ + physics/Physics_Base.cpp \ + physics/Physics_Liquid.cpp \ + physics/Physics_Monster.cpp \ + physics/Physics_Parametric.cpp \ + physics/Physics_Player.cpp \ + physics/Physics_RigidBody.cpp \ + physics/Physics_Static.cpp \ + physics/Physics_StaticMulti.cpp \ + physics/Push.cpp \ + script/Script_Compiler.cpp \ + script/Script_Interpreter.cpp \ + script/Script_Program.cpp \ + script/Script_Thread.cpp' + game_list = scons_utils.BuildList( 'game', game_string ) @@ -130,8 +132,8 @@ DifficultySettings.cpp \ DownloadMenu.cpp \ EscapePointEvaluator.cpp \ EscapePointManager.cpp \ -force_grab.cpp \ -func_shooter.cpp \ +Force_Grab.cpp \ +Func_Shooter.cpp \ FrobDoor.cpp \ FrobButton.cpp \ FrobDoorHandle.cpp \ @@ -144,29 +146,29 @@ HidingSpotSearchCollection.cpp \ AbsenceMarker.cpp \ Intersection.cpp \ IniFile.cpp \ -lightgem.cpp \ -liquid.cpp \ +LightGem.cpp \ +Liquid.cpp \ MaterialConverter.cpp \ MeleeWeapon.cpp \ ModMenu.cpp \ MultiStateMover.cpp \ MultiStateMoverButton.cpp \ MultiStateMoverPosition.cpp \ -overlaysys.cpp \ +OverlaySys.cpp \ PositionWithinRangeFinder.cpp \ ProjectileResult.cpp \ PVSToAASMapping.cpp \ PickableLock.cpp \ Relations.cpp \ RevisionTracker.cpp \ -sndProp.cpp \ -sndPropLoader.cpp \ +SndProp.cpp \ +SndPropLoader.cpp \ TimerManager.cpp \ UserManager.cpp \ Inventory/Category.cpp \ Inventory/Cursor.cpp \ Inventory/Inventory.cpp \ -Inventory/Item.cpp \ +Inventory/InventoryItem.cpp \ Inventory/WeaponItem.cpp \ Missions/Download.cpp \ Missions/DownloadManager.cpp \ @@ -200,85 +202,85 @@ StimResponse/Stim.cpp \ StimResponse/StimResponse.cpp \ StimResponse/StimResponseCollection.cpp \ StimResponse/StimResponseTimer.cpp \ -AI/AreaManager.cpp \ -AI/CommunicationSubsystem.cpp \ -AI/DoorInfo.cpp \ -AI/Mind.cpp \ -AI/Memory.cpp \ -AI/MovementSubsystem.cpp \ -AI/Subsystem.cpp \ -AI/Conversation/ConversationSystem.cpp \ -AI/Conversation/Conversation.cpp \ -AI/Conversation/ConversationCommand.cpp \ -AI/EAS/EAS.cpp \ -AI/EAS/RouteInfo.cpp \ -AI/EAS/RouteNode.cpp \ -AI/States/AgitatedSearchingState.cpp \ -AI/States/AlertIdleState.cpp \ -AI/States/BlindedState.cpp \ -AI/States/CombatState.cpp \ -AI/States/AgitatedSearchingStateLanternBot.cpp \ -AI/States/ConversationState.cpp \ -AI/States/DeadState.cpp \ -AI/States/EmergeFromCoverState.cpp \ -AI/States/FailedKnockoutState.cpp \ -AI/States/FleeState.cpp \ -AI/States/FleeDoneState.cpp \ -AI/States/IdleSleepState.cpp \ -AI/States/IdleState.cpp \ -AI/States/KnockedOutState.cpp \ -AI/States/LostTrackOfEnemyState.cpp \ -AI/States/ObservantState.cpp \ -AI/States/PainState.cpp \ -AI/States/SearchingState.cpp \ -AI/States/State.cpp \ -AI/States/StayInCoverState.cpp \ -AI/States/SuspiciousState.cpp \ -AI/States/SwitchOnLightState.cpp \ -AI/States/ExamineRopeState.cpp \ -AI/States/TakeCoverState.cpp \ -AI/States/UnreachableTargetState.cpp \ -AI/Tasks/ChaseEnemyRangedTask.cpp \ -AI/Tasks/ChaseEnemyTask.cpp \ -AI/Tasks/CombatTask.cpp \ -AI/Tasks/CommunicationTask.cpp \ -AI/Tasks/CommWaitTask.cpp \ -AI/Tasks/FleeTask.cpp \ -AI/Tasks/FollowActorTask.cpp \ -AI/Tasks/GreetingBarkTask.cpp \ -AI/Tasks/HandleDoorTask.cpp \ -AI/Tasks/HandleElevatorTask.cpp \ -AI/Tasks/IdleAnimationTask.cpp \ -AI/Tasks/InteractionTask.cpp \ -AI/Tasks/InvestigateSpotTask.cpp \ -AI/Tasks/MeleeCombatTask.cpp \ -AI/Tasks/MoveToCoverTask.cpp \ -AI/Tasks/MoveToPositionTask.cpp \ -AI/Tasks/PathAnimTask.cpp \ -AI/Tasks/PathCornerTask.cpp \ -AI/Tasks/PathCycleAnimTask.cpp \ -AI/Tasks/PathHideTask.cpp \ -AI/Tasks/PathInteractTask.cpp \ -AI/Tasks/PathLookatTask.cpp \ -AI/Tasks/PathShowTask.cpp \ -AI/Tasks/PathSitTask.cpp \ -AI/Tasks/PathSleepTask.cpp \ -AI/Tasks/PathTask.cpp \ -AI/Tasks/PathTurnTask.cpp \ -AI/Tasks/PathWaitForTriggerTask.cpp \ -AI/Tasks/PathWaitTask.cpp \ -AI/Tasks/PlayAnimationTask.cpp \ -AI/Tasks/AnimalPatrolTask.cpp \ -AI/Tasks/RandomHeadturnTask.cpp \ -AI/Tasks/RandomTurningTask.cpp \ -AI/Tasks/RangedCombatTask.cpp \ -AI/Tasks/RepeatedBarkTask.cpp \ -AI/Tasks/ResolveMovementBlockTask.cpp \ -AI/Tasks/SingleBarkTask.cpp \ -AI/Tasks/ScriptTask.cpp \ -AI/Tasks/ThrowObjectTask.cpp \ -AI/Tasks/WaitTask.cpp \ -AI/Tasks/WanderInLocationTask.cpp \ +ai/AreaManager.cpp \ +ai/CommunicationSubsystem.cpp \ +ai/DoorInfo.cpp \ +ai/Mind.cpp \ +ai/Memory.cpp \ +ai/MovementSubsystem.cpp \ +ai/Subsystem.cpp \ +ai/Conversation/ConversationSystem.cpp \ +ai/Conversation/Conversation.cpp \ +ai/Conversation/ConversationCommand.cpp \ +ai/EAS/EAS.cpp \ +ai/EAS/RouteInfo.cpp \ +ai/EAS/RouteNode.cpp \ +ai/States/AgitatedSearchingState.cpp \ +ai/States/AlertIdleState.cpp \ +ai/States/BlindedState.cpp \ +ai/States/CombatState.cpp \ +ai/States/AgitatedSearchingStateLanternBot.cpp \ +ai/States/ConversationState.cpp \ +ai/States/DeadState.cpp \ +ai/States/EmergeFromCoverState.cpp \ +ai/States/FailedKnockoutState.cpp \ +ai/States/FleeState.cpp \ +ai/States/FleeDoneState.cpp \ +ai/States/IdleSleepState.cpp \ +ai/States/IdleState.cpp \ +ai/States/KnockedOutState.cpp \ +ai/States/LostTrackOfEnemyState.cpp \ +ai/States/ObservantState.cpp \ +ai/States/PainState.cpp \ +ai/States/SearchingState.cpp \ +ai/States/State.cpp \ +ai/States/StayInCoverState.cpp \ +ai/States/SuspiciousState.cpp \ +ai/States/SwitchOnLightState.cpp \ +ai/States/ExamineRopeState.cpp \ +ai/States/TakeCoverState.cpp \ +ai/States/UnreachableTargetState.cpp \ +ai/Tasks/ChaseEnemyRangedTask.cpp \ +ai/Tasks/ChaseEnemyTask.cpp \ +ai/Tasks/CombatTask.cpp \ +ai/Tasks/CommunicationTask.cpp \ +ai/Tasks/CommWaitTask.cpp \ +ai/Tasks/FleeTask.cpp \ +ai/Tasks/FollowActorTask.cpp \ +ai/Tasks/GreetingBarkTask.cpp \ +ai/Tasks/HandleDoorTask.cpp \ +ai/Tasks/HandleElevatorTask.cpp \ +ai/Tasks/IdleAnimationTask.cpp \ +ai/Tasks/InteractionTask.cpp \ +ai/Tasks/InvestigateSpotTask.cpp \ +ai/Tasks/MeleeCombatTask.cpp \ +ai/Tasks/MoveToCoverTask.cpp \ +ai/Tasks/MoveToPositionTask.cpp \ +ai/Tasks/PathAnimTask.cpp \ +ai/Tasks/PathCornerTask.cpp \ +ai/Tasks/PathCycleAnimTask.cpp \ +ai/Tasks/PathHideTask.cpp \ +ai/Tasks/PathInteractTask.cpp \ +ai/Tasks/PathLookatTask.cpp \ +ai/Tasks/PathShowTask.cpp \ +ai/Tasks/PathSitTask.cpp \ +ai/Tasks/PathSleepTask.cpp \ +ai/Tasks/PathTask.cpp \ +ai/Tasks/PathTurnTask.cpp \ +ai/Tasks/PathWaitForTriggerTask.cpp \ +ai/Tasks/PathWaitTask.cpp \ +ai/Tasks/PlayAnimationTask.cpp \ +ai/Tasks/AnimalPatrolTask.cpp \ +ai/Tasks/RandomHeadturnTask.cpp \ +ai/Tasks/RandomTurningTask.cpp \ +ai/Tasks/RangedCombatTask.cpp \ +ai/Tasks/RepeatedBarkTask.cpp \ +ai/Tasks/ResolveMovementBlockTask.cpp \ +ai/Tasks/SingleBarkTask.cpp \ +ai/Tasks/ScriptTask.cpp \ +ai/Tasks/ThrowObjectTask.cpp \ +ai/Tasks/WaitTask.cpp \ +ai/Tasks/WanderInLocationTask.cpp \ SEED.cpp \ ModelGenerator.cpp \ ImageMapManager.cpp \ @@ -288,7 +290,7 @@ RawVector.cpp \ I18N.cpp \ sourcehook/sourcehook.cpp' -darkModList = scons_utils.BuildList('../../DarkMod', darkModSrc) +darkModList = scons_utils.BuildList('../../game/', darkModSrc) ziploader_list = SConscript( '../../sys/scons/SConscript.ziploader' ) @@ -297,31 +299,18 @@ local_env = g_game_env.Clone() local_env.Append( CPPDEFINES = [ 'GAME_DLL' ] ) local_env.Append( CPPFLAGS = [ '-Wno-unused', '-Wno-deprecated' ] ) -if g_os == 'MacOSX': - local_env.Append(LIBS = [ - File('#/macosx/libcurl/libcurl.a'), - - File('#/macosx/libpng/libpng12.a'), - File('#/macosx/libjpeg/libjpeg.a'), - File('#/macosx/boost/lib/libboost_filesystem.a'), - File('#/macosx/boost/lib/libboost_system.a'), - File('#/macosx/boost/lib/libboost_thread.a') - ]) -else: - # Linux - - # Link the runtime statically, link statically against libjpeg.a and libpng.a - # the corresponding packages libpng12-dev and libjpeg-dev must be available on the system - local_env.Append( LINKFLAGS = [ '-lrt', '-ljpeg', '-lpng' ] ) +# Link the runtime statically, link statically against libjpeg.a and libpng.a +# the corresponding packages libpng12-dev and libjpeg-dev must be available on the system +local_env.Append( LINKFLAGS = [ '-lrt', '-ljpeg', '-lpng' ] ) - local_env.Append(LIBS = [ - File('#/linux/libcurl/libcurl.a'), - File('#/linux/boost/lib/libboost_filesystem.a'), - File('#/linux/boost/lib/libboost_system.a'), - File('#/linux/boost/lib/libboost_thread.a') - ]) +local_env.Append(LIBS = [ + File('#/linux/libcurl/libcurl.a'), + File('#/linux/boost/lib/libboost_filesystem.a'), + File('#/linux/boost/lib/libboost_system.a'), + File('#/linux/boost/lib/libboost_thread.a') +]) -# greebo: Use custom compiled devIL in Linux and Mac OS X +# greebo: Use custom compiled devIL in Linux devil_list = SConscript( '../../sys/scons/SConscript.devil' ) full_list = game_list + darkModList + idlib_objects + ziploader_list + devil_list diff --git a/sys/scons/SConscript.gl b/sys/scons/SConscript.gl new file mode 100644 index 000000000..a7053a196 --- /dev/null +++ b/sys/scons/SConscript.gl @@ -0,0 +1,101 @@ +# -*- mode: python -*- +# DOOM build script +# TTimo +# http://scons.sourceforge.net + +# various GL-related code: +# GL logging functions (used on all platforms) +# GLimp code (Linux only) +# The C code is generated using M4 macros from a description of the GL API +# on win32, the logging functions are generated ones and kept in the source +# on other platforms, scons generates on the fly at build time + +import time +Import('GLOBALS') +Import(GLOBALS) + +# NOTE: make sure the .api files are in LF line endings, CRLF isn't working so well +def build_logfuncs(env, target, source): + import os, sys + # search for the module - source repository might make things harder + gllog_path = 'sys/gllog' + if ( not os.path.exists( gllog_path + '/logfunc.py' ) ): + gllog_path = '/var/local/Doom/neo/sys/gllog' + sys.path.append( gllog_path ) + from logfunc import do_logfunc + f_out = open('%s' % target[0], 'w') + f_out.write('// generated file, do not modify!\n') + f_out.write('// ' + time.asctime() + '\n') + f_out.write('// see SConscript.gl and sys/gllog/\n\n') + + f_in = open( gllog_path + '/gl.api', 'r') + do_logfunc(f_in, f_out) + f_in.close() + + f_out.write('\n#ifdef __linux__\n\n') + f_in = open( gllog_path + '/glX.api', 'r') + do_logfunc(f_in, f_out) + f_in.close() + f_out.write('\n#endif\n\n') + + f_out.write('\n#ifdef WIN32\n\n') + f_in = open( gllog_path + '/wgl.api', 'r') + do_logfunc(f_in, f_out) + f_in.close() + f_out.write('\n#endif\n\n') + + f_out.close() + + print 'Generated %s' % target[0] + +gl_env = g_env.Clone() +gl_env.Append( CPPPATH = '#' ) +gl_env.Append( CPPFLAGS = '-DGLIMP' ) + +if ( local_dedicated == 1 ): + gl_env.Append( CPPFLAGS = '-DID_DEDICATED' ) + +# general M4 builder setup +# files we are going to generate from their M4 counterparts + +m4_list = ( + '../gllog/gl_extensions.cpp', + '../linux/glimp_dlopen.cpp', + '../linux/glimp_logging.cpp', + '../linux/glimp_stub.cpp', + '../linux/glimp_local.h' ) + +for i_m4 in m4_list: + gl_env.M4( i_m4, i_m4 + '.m4' ) + gl_env.Depends( i_m4, '../gllog/gl_def.m4' ) + +# enable if you need to generate again +# FIXME: conflicts when several environements are used. move that to seperate script +#enforce = gl_env.M4( '#sys/linux/qgl_enforce.h', '../linux/qgl_enforce.h.m4' ) +#gl_env.Depends( enforce, '../gllog/gl_def.m4' ) + +# logging functions, python generated ( that's beyond my m4-fu ) + +gl_env.Depends( '../linux/glimp_logging.cpp', '../linux/glimp_logfuncs.cpp' ) + +logfuncs = gl_env.Command( '../linux/glimp_logfuncs.cpp', '../gllog/logfunc.py', build_logfuncs ) +gl_env.Depends( logfuncs, '../gllog/gl_def.m4' ) + +sources = [] +sources.append( '../gllog/gl_extensions.cpp' ) + +if ( local_dedicated == 1 ): + sources.append( '../linux/glimp_stub.cpp' ) +else: + sources.append( '../linux/glimp_dlopen.cpp' ) + sources.append( '../linux/glimp_logging.cpp' ) + +#if ( DEDICATED != '0' ): +# sources.append( '../linux/glimp_stub.cpp' ) +# +#if ( GL_HARDLINK == '0' ): +# sources.append( '../linux/glimp_dlopen.cpp' ) +# sources.append( '../linux/glimp_logging.cpp' ) + +lib = gl_env.StaticLibrary( 'glimp', sources ) +#gl_env.Install( '../..', lib ) diff --git a/sys/scons/SConscript.idlib b/sys/scons/SConscript.idlib index c4e1e14bd..6a0a04e49 100644 --- a/sys/scons/SConscript.idlib +++ b/sys/scons/SConscript.idlib @@ -1,86 +1,56 @@ # -*- mode: python -*- -# coding=utf-8 - # DOOM build script # TTimo # http://scons.sourceforge.net -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#* $Log$ -#* Revision 1.3 2005/11/11 22:50:09 sparhawk -#* SDK 1.3 Merge -#* -#* Revision 1.2 2004/11/28 19:23:11 sparhawk -#* Added header and Id Copyright. -#* -#* -#*************************************************************************** - import scons_utils Import( 'GLOBALS' ) Import( GLOBALS ) idlib_string = ' \ - bv/bounds.cpp \ - bv/frustum.cpp \ - bv/sphere.cpp \ - bv/box.cpp \ - geometry/drawvert.cpp \ - geometry/winding2d.cpp \ - geometry/surface_sweptspline.cpp \ - geometry/winding.cpp \ - geometry/surface.cpp \ - geometry/surface_patch.cpp \ - geometry/tracemodel.cpp \ - geometry/jointtransform.cpp \ - hashing/crc32.cpp \ - hashing/crc16.cpp \ - hashing/honeyman.cpp \ - hashing/md4.cpp \ - hashing/md5.cpp \ - math/angles.cpp \ - math/lcp.cpp \ - math/math.cpp \ - math/matrix.cpp \ - math/ode.cpp \ - math/plane.cpp \ - math/pluecker.cpp \ - math/polynomial.cpp \ - math/quat.cpp \ - math/rotation.cpp \ - math/simd.cpp \ - math/simd_generic.cpp \ - math/simd_mmx.cpp \ - math/simd_sse.cpp \ - math/simd_sse2.cpp \ - math/simd_sse3.cpp \ - math/vector.cpp \ - bitmsg.cpp \ - langdict.cpp \ - lexer.cpp \ - lib.cpp \ - containers/hashindex.cpp \ - dict.cpp \ - str.cpp \ - parser.cpp \ - mapfile.cpp \ - cmdargs.cpp \ - token.cpp \ - base64.cpp \ - timer.cpp \ - heap.cpp' - -# greebo: Compile the altivec file in MacOSX only -if g_os == 'MacOSX': - idlib_string += ' math/simd_altivec.cpp ' + bv/Bounds.cpp \ + bv/Frustum.cpp \ + bv/Sphere.cpp \ + bv/Box.cpp \ + geometry/DrawVert.cpp \ + geometry/Winding2D.cpp \ + geometry/Surface_SweptSpline.cpp \ + geometry/Winding.cpp \ + geometry/Surface.cpp \ + geometry/Surface_Patch.cpp \ + geometry/TraceModel.cpp \ + geometry/JointTransform.cpp \ + hashing/CRC32.cpp \ + hashing/MD4.cpp \ + hashing/MD5.cpp \ + math/Angles.cpp \ + math/Lcp.cpp \ + math/Math.cpp \ + math/Matrix.cpp \ + math/Ode.cpp \ + math/Plane.cpp \ + math/Pluecker.cpp \ + math/Polynomial.cpp \ + math/Quat.cpp \ + math/Rotation.cpp \ + math/Simd.cpp \ + math/Simd_Generic.cpp \ + math/Vector.cpp \ + BitMsg.cpp \ + LangDict.cpp \ + Lexer.cpp \ + Lib.cpp \ + containers/HashIndex.cpp \ + Dict.cpp \ + Str.cpp \ + Parser.cpp \ + MapFile.cpp \ + CmdArgs.cpp \ + Token.cpp \ + Base64.cpp \ + Timer.cpp \ + Heap.cpp' idlib_list = scons_utils.BuildList( 'idlib', idlib_string ) @@ -99,21 +69,13 @@ except: pass local_env_noopt.Append( CPPFLAGS = flags ) -# greebo: Need SSE2 instruction set to compile simd_sse2.cpp -local_env.Append(CPPFLAGS = '-msse2') - -if g_os == 'MacOSX': - local_env.Append(CPPFLAGS = '-faltivec') - ret_list = [] - if ( local_idlibpic == 0 ): for f in idlib_list: ret_list += local_env.StaticObject( source = f ) - ret_list += local_env_noopt.StaticObject( source = [ '../../idlib/bv/frustum_gcc.cpp' ] ) + ret_list += local_env_noopt.StaticObject( source = [ '../../idlib/bv/Frustum_gcc.cpp' ] ) else: for f in idlib_list: ret_list += local_env.SharedObject( source = f ) - ret_list += local_env_noopt.SharedObject( source = [ '../../idlib/bv/frustum_gcc.cpp' ] ) - + ret_list += local_env_noopt.SharedObject( source = [ '../../idlib/bv/Frustum_gcc.cpp' ] ) Return( 'ret_list' ) diff --git a/sys/scons/SConscript.ziploader b/sys/scons/SConscript.ziploader index 059e5f52c..2f860230d 100644 --- a/sys/scons/SConscript.ziploader +++ b/sys/scons/SConscript.ziploader @@ -1,20 +1,21 @@ -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#* $Log$ -#* Revision 1.3 2005/11/11 22:50:09 sparhawk -#* SDK 1.3 Merge -#* -#* Revision 1.2 2004/11/28 19:23:11 sparhawk -#* Added header and Id Copyright. -#* -#* -#*************************************************************************** +#***************************************************************************** +# The Dark Mod GPL Source Code +# +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. +# +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** import scons_utils diff --git a/sys/scons/SDK.py b/sys/scons/SDK.py new file mode 100644 index 000000000..05bef26b4 --- /dev/null +++ b/sys/scons/SDK.py @@ -0,0 +1,89 @@ +import os, sys + +import scons_utils + +class idSDK( scons_utils.idSetupBase ): + + def PreBuildSDK( self, build_path ): + self.build_path = build_path + print 'PreBuildSDK: ' + repr( build_path ) + for p in build_path: + self.SimpleCommand( 'rm -rf ' + p ) + + def Visit( self, arg, dirname, names ): + #print 'visit: %s %s' % ( dirname, repr( names ) ) + for i in names: + if ( i[len(i)-2:] == '.h' or i[len(i)-4:] == '.cpp' ): + self.file_list.append( os.path.join( dirname, i ) ) + + def BuildSDK( self, target = None, source = None, env = None ): + print 'Building SDK release' + # extract the file list + self.file_list = [] + for p in self.build_path: + os.path.walk( p, self.Visit, None ) + main_version = self.ExtractEngineVersion() + version = self.ExtractBuildVersion() + sdk_dirname = 'doom3-linux-%s.%s-sdk' % ( main_version, version ) + sdk_srcdir = os.path.join( sdk_dirname, 'src' ) + if ( os.path.exists( sdk_dirname ) ): + self.SimpleCommand( 'rm -rf ' + sdk_dirname ) + self.SimpleCommand( 'mkdir -p ' + sdk_srcdir ) + for i in self.file_list: + # NOTE: same len on all paths game/d3xp. probably breaks for anything else + short = i[ len( self.build_path[0] ) + 1: ] + target = os.path.join( sdk_srcdir, short ) + dir = os.path.dirname( target ) + if ( not os.path.exists( dir ) ): + self.SimpleCommand( 'mkdir -p ' + dir ) + self.SimpleCommand( 'cp ' + i + ' ' + target ) + # remove a bunch of files from hardcoded list + delete = [ 'framework/Compressor.h', 'framework/Console.h', 'framework/DemoChecksum.h', 'framework/DemoFile.h', + 'framework/EditField.h', 'framework/EventLoop.h', 'framework/KeyInput.h', 'framework/Session.h', + 'framework/async/AsyncClient.h', 'framework/async/AsyncNetwork.h', 'framework/async/AsyncServer.h', + 'framework/async/MsgChannel.h', 'framework/async/ServerScan.h', + 'mssdk', 'punkbuster', 'sys/osx', + 'tools/comafx/StdAfx.h', 'tools/compilers/compiler_public.h', 'tools/edit_public.h' ] + for i in delete: + target = os.path.join( sdk_srcdir, i ) + self.SimpleCommand( 'rm -rf ' + target ) + # copy files from a hardcoded list + force_copy = [ 'SConstruct', 'sys/scons/SConscript.game', 'sys/scons/SConscript.idlib', 'sys/scons/scons_utils.py', + 'game/Game.def', 'd3xp/Game.def', + 'idlib/geometry/Surface_Polytope.cpp', 'idlib/hashing/CRC8.cpp', 'idlib/math/Complex.cpp', + 'idlib/math/Simd_3DNow.cpp', 'idlib/math/Simd_AltiVec.cpp', 'idlib/math/Simd_MMX.cpp', 'idlib/math/Simd_SSE.cpp', + 'idlib/math/Simd_SSE2.cpp', 'idlib/math/Simd_SSE3.cpp', + 'MayaImport/exporter.h', 'MayaImport/maya_main.cpp', 'MayaImport/maya_main.h', + 'MayaImport/mayaimport.def', 'MayaImport/Maya4.5/maya.h', 'MayaImport/maya5.0/maya.h', + 'MayaImport/Maya6.0/maya.h', + 'd3xp/EndLevel.cpp', 'd3xp/EndLevel.h' + ] + for i in force_copy: + target = os.path.join( sdk_srcdir, i ) + dir = os.path.dirname( target ) + if ( not os.path.exists( dir ) ): + self.SimpleCommand( 'mkdir -p ' + dir ) + self.SimpleCommand( 'cp ' + i + ' ' + target ) + # copy sdk media + if ( not os.path.exists( 'sys/linux/setup/media-sdk' ) ): + print 'sdk media is missing (sys/linux/setup/media-sdk)' + sys.exit( 1 ) + self.SimpleCommand( 'cp -R sys/linux/setup/media-sdk/* ' + sdk_dirname ) + # .zip files are auto-expanded by lokisetup, and there's no disable feature + # zip up the maya toplevel stuff + self.SimpleCommand( 'cd ' + sdk_dirname + ' && zip MayaSetupStuff.zip MayaImportx86* && rm MayaImportx86*' ) + # put the setup in + self.SimpleCommand( 'cp -R -f sys/linux/setup/image-base/* ' + sdk_dirname ) + self.SimpleCommand( 'cp -R -f sys/linux/setup/image-sdk/* ' + sdk_dirname ) + # M4 + m4_dict = { 'M4_VERSION' : main_version } + self.M4Processing( sdk_dirname + '/setup.data/setup.xml.in', m4_dict ) + # create the FreeBSD symlinks + self.SimpleCommand( 'cd ' + sdk_dirname + '/setup.data/bin ; ln -s Linux FreeBSD' ) + # create amd64 symlinks + self.SimpleCommand( 'cd ' + sdk_dirname + '/setup.data/bin/Linux ; ln -s x86 amd64' ) + # remove .svn entries + self.SimpleCommand( 'find ' + sdk_dirname + ' -name \'.svn\' -type d | xargs rm -rf' ) + # put it together + self.SimpleCommand( 'sys/linux/setup/makeself/makeself.sh ' + sdk_dirname + ' ' + sdk_dirname + '.x86.run \'DOOM III SDK\' ./setup.sh' ) + print 'TODO: do a build check in SDK directory' diff --git a/sys/scons/Setup.py b/sys/scons/Setup.py new file mode 100644 index 000000000..42750a76c --- /dev/null +++ b/sys/scons/Setup.py @@ -0,0 +1,160 @@ +import sys, os, string, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, tempfile + +import scons_utils + +class idSetup( scons_utils.idSetupBase ): + + # do not alter the sources, specially with strip and brandelfing + def BuildSetup( self, target = None, source = None, env = None ): + brandelf_path = source[0].abspath + if ( target[0].path == 'setup-demo' ): + print 'Building demo setup' + demo_build = True + core_path = source[1].abspath + game_path = source[2].abspath + else: + print 'Building setup' + demo_build = False + core_path = source[1].abspath + ded_path = source[2].abspath + game_path = source[3].abspath + d3xp_path = source[4].abspath + # identify dynamic dependencies that we bundle with the binary + ldd_deps = [] + ldd_output = self.SimpleCommand( 'ldd -r ' + core_path ) + pat = re.compile( '.*lib(stdc\+\+|gcc_s).* => (.*) \(.*\)' ) + for i in string.split( ldd_output, '\n' ): + if ( pat.match( i ) ): + ldd_deps.append( pat.split( i )[ 2 ] ) + # prep the binaries and update the paths + temp_dir = tempfile.mkdtemp( prefix = 'doomsetup' ) + if ( demo_build ): + self.SimpleCommand( 'cp %s %s/doom.x86' % ( core_path, temp_dir ) ) + core_path = '%s/doom.x86' % temp_dir + self.SimpleCommand( 'cp %s %s/gamex86.so' % ( game_path, temp_dir ) ) + game_path = '%s/gamex86.so' % temp_dir + self.SimpleCommand( 'strip ' + core_path ) + self.SimpleCommand( 'strip ' + game_path ) + self.SimpleCommand( brandelf_path + ' -t Linux ' + core_path ) + else: + self.SimpleCommand( 'cp %s %s/doom.x86' % ( core_path, temp_dir ) ) + core_path = '%s/doom.x86' % temp_dir + self.SimpleCommand( 'cp %s %s/doomded.x86' % ( ded_path, temp_dir ) ) + ded_path = '%s/doomded.x86' % temp_dir + self.SimpleCommand( 'cp %s %s/gamex86-base.so' % ( game_path, temp_dir ) ) + game_path = '%s/gamex86-base.so' % temp_dir + self.SimpleCommand( 'cp %s %s/gamex86-d3xp.so' % ( d3xp_path, temp_dir ) ) + d3xp_path = '%s/gamex86-d3xp.so' % temp_dir + self.SimpleCommand( 'strip ' + core_path ) + self.SimpleCommand( 'strip ' + ded_path ) + self.SimpleCommand( 'strip ' + game_path ) + self.SimpleCommand( 'strip ' + d3xp_path ) + self.SimpleCommand( brandelf_path + ' -t Linux ' + core_path ) + self.SimpleCommand( brandelf_path + ' -t Linux ' + ded_path ) + # main version tag - ENGINE_VERSION in Licensee.h + main_version = self.ExtractEngineVersion( ) + # build number + version = self.ExtractBuildVersion( ) + if ( demo_build ): + base_dirname = 'doom3-linux-%s.%s-demo' % ( main_version, version ) + else: + base_dirname = 'doom3-linux-%s.%s' % ( main_version, version ) + if ( os.path.exists( base_dirname ) ): + self.SimpleCommand( 'rm -rf %s' % base_dirname ) + self.SimpleCommand( 'mkdir %s' % base_dirname ) + self.SimpleCommand( 'cp -R sys/linux/setup/image-base/* ' + base_dirname ) + if ( demo_build ): + self.SimpleCommand( 'cp -R -f sys/linux/setup/image-demo/* ' + base_dirname ) + else: + self.SimpleCommand( 'cp -R -f sys/linux/setup/image/* ' + base_dirname ) + # process M4 stuff + if ( demo_build ): + m4_dict = { 'M4_PRODUCT' : 'doom3-demo', 'M4_DESC' : 'DOOM III demo', 'M4_VERSION' : '%s.%s' % ( main_version, version ) } + else: + m4_dict = { 'M4_PRODUCT' : 'doom3', 'M4_DESC' : 'DOOM III', 'M4_VERSION' : '%s.%s' % ( main_version, version ) } + M4_LDD = '' + for i in ldd_deps: + if ( len( M4_LDD ) ): + M4_LDD += '\n' + M4_LDD += os.path.basename( i ) + m4_dict[ 'M4_LDD' ] = M4_LDD + self.M4Processing( base_dirname + '/setup.data/setup.xml.in', m4_dict ) + # build the game pak + if ( demo_build ): + # the demo doesn't use a game pak + self.SimpleCommand( 'cp ' + game_path + ' ' + base_dirname ) + else: + # comment out this part to stick to game paks already provided in the media tree +# print 'zipping together base game01.pk4' +# game_zip = zipfile.ZipFile( 'sys/linux/setup/media/base/game01.pk4', 'w', zipfile.ZIP_DEFLATED ) +# game_zip.write( game_path, 'gamex86.so' ) +# game_zip.write( 'sys/linux/setup/binary.conf', 'binary.conf' ) +# game_zip.printdir() +# game_zip.close() +# print 'zipping together d3xp game01.pk4' +# game_zip = zipfile.ZipFile( 'sys/linux/setup/media/d3xp/game01.pk4', 'w', zipfile.ZIP_DEFLATED ) +# game_zip.write( d3xp_path, 'gamex86.so' ) +# game_zip.write( 'sys/linux/setup/binary.conf', 'binary.conf' ) +# game_zip.printdir() +# game_zip.close() + pass + # copy media + if ( demo_build ): + # we use a different repository path for large binary data + # extract or symlink from media-demo + if ( not os.path.exists( 'sys/linux/setup/media-demo' ) ): + print 'demo media is missing (sys/linux/setup/media-demo)' + sys.exit( 1 ) + # check the md5 of the demo pack to be sure + md5sum = self.SimpleCommand( 'md5sum sys/linux/setup/media-demo/demo/demo00.pk4' ) + if ( md5sum != '70c2c63ef1190158f1ebd6c255b22d8e sys/linux/setup/media-demo/demo/demo00.pk4' ): + print 'demo media has invalid checksum' + sys.exit( 1 ) + self.SimpleCommand( 'cp -R sys/linux/setup/media-demo/* ' + base_dirname ) + else: + if ( not os.path.exists( 'sys/linux/setup/media' ) ): + print 'media is missing (sys/linux/setup/media)' + sys.exit( 1 ) + # copy the CHANGES file + self.SimpleCommand( 'cp -v sys/linux/setup/media/CHANGES ' + base_dirname ) + # copy out the pk4 files from the main media tree + self.SimpleCommand( 'mkdir ' + base_dirname + '/base' ) + self.SimpleCommand( 'mkdir ' + base_dirname + '/d3xp' ) + self.SimpleCommand( 'find sys/linux/setup/media/ -name "*.pk4" | grep -v zpak | cut -b 23- | while read i ; do cp -v sys/linux/setup/media/$i ' + base_dirname + '/$i ; done' ) + # copy + self.SimpleCommand( 'cp ' + core_path + ' ' + base_dirname + '/bin/Linux/x86' ) + if ( not demo_build ): + self.SimpleCommand( 'cp ' + ded_path + ' ' + base_dirname + '/bin/Linux/x86' ) + for i in ldd_deps: + self.SimpleCommand( 'cp ' + i + ' ' + base_dirname + '/' + os.path.basename( i ) ) + # punkbuster + if ( not demo_build ): + self.SimpleCommand( 'cp -R punkbuster/setup/pb ' + base_dirname ) + self.SimpleCommand( 'cp -Rf punkbuster/setup/linux/pb ' + base_dirname ) + self.SimpleCommand( 'cp sys/linux/setup/media/PB_EULA.txt ' + base_dirname + '/pb' ) + # put a version tag, xqf request + f = open( base_dirname + '/version.info', 'w' ) + f.write( main_version + '\n' ) + f.write( self.ExtractProtocolVersion() + '\n' ) + f.close() + # create the FreeBSD symlinks + self.SimpleCommand( 'cd ' + base_dirname + '/bin ; ln -s Linux FreeBSD' ) + self.SimpleCommand( 'cd ' + base_dirname + '/setup.data/bin ; ln -s Linux FreeBSD' ) + # create amd64 symlinks + self.SimpleCommand( 'cd ' + base_dirname + '/bin/Linux ; ln -s x86 amd64' ) + self.SimpleCommand( 'cd ' + base_dirname + '/setup.data/bin/Linux ; ln -s x86 amd64' ) + # remove .svn entries + self.SimpleCommand( 'find ' + base_dirname + ' -name \'.svn\' -type d | xargs rm -rf' ) + # remove D3XP related stuff until final release + #self.SimpleCommand( 'rm -rf ' + base_dirname + '/d3xp/*' ) + # package it + target_setup = base_dirname + '.x86.run' + if ( demo_build ): + self.SimpleCommand( 'sys/linux/setup/makeself/makeself.sh ' + base_dirname + ' ' + target_setup + ' \'DOOM III demo\' ./setup.sh' ) + else: + self.SimpleCommand( 'sys/linux/setup/makeself/makeself.sh ' + base_dirname + ' ' + target_setup + ' \'DOOM III\' ./setup.sh' ) + # take out the temp dir + self.SimpleCommand( 'rm -rf %s' % temp_dir ) + # success + return None + diff --git a/sys/scons/scons_utils.py b/sys/scons/scons_utils.py index e258575df..d8ef92225 100644 --- a/sys/scons/scons_utils.py +++ b/sys/scons/scons_utils.py @@ -1,29 +1,10 @@ # -*- mode: python -*- -# coding=utf-8 - -#*************************************************************************** -#* -#* PROJECT: The Dark Mod -#* $Source$ -#* $Revision$ -#* $Date$ -#* $Author$ -#* -#* $Log$ -#* Revision 1.3 2005/11/11 22:50:09 sparhawk -#* SDK 1.3 Merge -#* -#* Revision 1.2 2004/11/28 19:23:10 sparhawk -#* Added header and Id Copyright. -#* -#* -#*************************************************************************** - -import sys, os, string, time, commands, re, pickle, StringIO, commands, pdb, zipfile, tempfile +import sys, os, string, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, tempfile import SCons # need an Environment and a matching buffered_spawn API .. encapsulate class idBuffering: + silent = False def buffered_spawn( self, sh, escape, cmd, args, env ): stderr = StringIO.StringIO() @@ -41,8 +22,9 @@ def buffered_spawn( self, sh, escape, cmd, args, env ): print 'OSError ignored on command: %s' % command_string retval = 0 print command_string - sys.stdout.write( stdout.getvalue() ) - sys.stderr.write( stderr.getvalue() ) + if ( retval != 0 or not self.silent ): + sys.stdout.write( stdout.getvalue() ) + sys.stderr.write( stderr.getvalue() ) return retval class idSetupBase: @@ -140,6 +122,7 @@ def checkLDD( target, source, env ): if ( have_undef ): print output print "ERROR: undefined symbols" + os.system('rm %s' % target[0]) sys.exit(1) def SharedLibrarySafe( env, target, source ): @@ -158,31 +141,19 @@ class idGamePaks( idSetupBase ): def BuildGamePak( self, target = None, source = None, env = None ): # NOTE: ew should have done with zipfile module temp_dir = tempfile.mkdtemp( prefix = 'gamepak' ) - - if sys.platform == 'darwin': - # Mac OS X has OS number 1 - os_id = '1' - target_game_file_name = 'game.dylib' - else: - # Linux has OS number 2 - os_id = '2' - target_game_file_name = 'gamex86.so' - - self.SimpleCommand( 'cp %s %s' % ( source[0].abspath, os.path.join( temp_dir, target_game_file_name ) ) ) - # Removed by Crispy: don't strip the .so; debugging symbols are useful - #self.SimpleCommand( 'strip %s' % os.path.join( temp_dir, target_game_file_name ) ) - - self.SimpleCommand( 'echo %s > %s' % ( os_id, os.path.join( temp_dir, 'binary.conf' ) ) ) - - self.SimpleCommand( 'cd %s ; zip %s %s binary.conf' % ( temp_dir, os.path.join( temp_dir, target[0].abspath ), target_game_file_name ) ) + self.SimpleCommand( 'cp %s %s' % ( source[0].abspath, os.path.join( temp_dir, 'gamex86.so' ) ) ) + self.SimpleCommand( 'strip %s' % os.path.join( temp_dir, 'gamex86.so' ) ) + self.SimpleCommand( 'echo 2 > %s' % ( os.path.join( temp_dir, 'binary.conf' ) ) ) + self.SimpleCommand( 'cd %s ; zip %s gamex86.so binary.conf' % ( temp_dir, os.path.join( temp_dir, target[0].abspath ) ) ) self.SimpleCommand( 'rm -r %s' % temp_dir ) return None # -------------------------------------------------------------------- # get a clean error output when running multiple jobs -def SetupBufferedOutput( env ): +def SetupBufferedOutput( env, silent ): buf = idBuffering() + buf.silent = silent buf.env = env env['SPAWN'] = buf.buffered_spawn diff --git a/sys/stub/stub_gl.cpp b/sys/stub/stub_gl.cpp new file mode 100644 index 000000000..ba382c29c --- /dev/null +++ b/sys/stub/stub_gl.cpp @@ -0,0 +1,386 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../renderer/tr_local.h" + +void glAccum(GLenum op, GLfloat value){}; +void glAlphaFunc(GLenum func, GLclampf ref){}; +GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences){}; +void glArrayElement(GLint i){}; +void glBegin(GLenum mode){}; +void glBindTexture(GLenum target, GLuint texture){}; +void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap){}; +void glBlendFunc(GLenum sfactor, GLenum dfactor){}; +void glCallList(GLuint list){}; +void glCallLists(GLsizei n, GLenum type, const GLvoid *lists){}; +void glClear(GLbitfield mask){}; +void glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha){}; +void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){}; +void glClearDepth(GLclampd depth){}; +void glClearIndex(GLfloat c){}; +void glClearStencil(GLint s){}; +void glClipPlane(GLenum plane, const GLdouble *equation){}; +void glColor3b(GLbyte red, GLbyte green, GLbyte blue){}; +void glColor3bv(const GLbyte *v){}; +void glColor3d(GLdouble red, GLdouble green, GLdouble blue){}; +void glColor3dv(const GLdouble *v){}; +void glColor3f(GLfloat red, GLfloat green, GLfloat blue){}; +void glColor3fv(const GLfloat *v){}; +void glColor3i(GLint red, GLint green, GLint blue){}; +void glColor3iv(const GLint *v){}; +void glColor3s(GLshort red, GLshort green, GLshort blue){}; +void glColor3sv(const GLshort *v){}; +void glColor3ub(GLubyte red, GLubyte green, GLubyte blue){}; +void glColor3ubv(const GLubyte *v){}; +void glColor3ui(GLuint red, GLuint green, GLuint blue){}; +void glColor3uiv(const GLuint *v){}; +void glColor3us(GLushort red, GLushort green, GLushort blue){}; +void glColor3usv(const GLushort *v){}; +void glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha){}; +void glColor4bv(const GLbyte *v){}; +void glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha){}; +void glColor4dv(const GLdouble *v){}; +void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha){}; +void glColor4fv(const GLfloat *v){}; +void glColor4i(GLint red, GLint green, GLint blue, GLint alpha){}; +void glColor4iv(const GLint *v){}; +void glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha){}; +void glColor4sv(const GLshort *v){}; +void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha){}; +void glColor4ubv(const GLubyte *v){}; +void glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha){}; +void glColor4uiv(const GLuint *v){}; +void glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha){}; +void glColor4usv(const GLushort *v){}; +void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha){}; +void glColorMaterial(GLenum face, GLenum mode){}; +void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer){}; +void glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type){}; +void glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border){}; +void glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border){}; +void glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width){}; +void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height){}; +void glCullFace(GLenum mode){}; +void glDeleteLists(GLuint list, GLsizei range){}; +void glDeleteTextures(GLsizei n, const GLuint *textures){}; +void glDepthFunc(GLenum func){}; +void glDepthMask(GLboolean flag){}; +void glDepthRange(GLclampd zNear, GLclampd zFar){}; +void glDisable(GLenum cap){}; +void glDisableClientState(GLenum array){}; +void glDrawArrays(GLenum mode, GLint first, GLsizei count){}; +void glDrawBuffer(GLenum mode){}; +void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices){}; +void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels){}; +void glEdgeFlag(GLboolean flag){}; +void glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer){}; +void glEdgeFlagv(const GLboolean *flag){}; +void glEnable(GLenum cap){}; +void glEnableClientState(GLenum array){}; +void glEnd(void){}; +void glEndList(void){}; +void glEvalCoord1d(GLdouble u){}; +void glEvalCoord1dv(const GLdouble *u){}; +void glEvalCoord1f(GLfloat u){}; +void glEvalCoord1fv(const GLfloat *u){}; +void glEvalCoord2d(GLdouble u, GLdouble v){}; +void glEvalCoord2dv(const GLdouble *u){}; +void glEvalCoord2f(GLfloat u, GLfloat v){}; +void glEvalCoord2fv(const GLfloat *u){}; +void glEvalMesh1(GLenum mode, GLint i1, GLint i2){}; +void glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2){}; +void glEvalPoint1(GLint i){}; +void glEvalPoint2(GLint i, GLint j){}; +void glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer){}; +void glFinish(void){}; +void glFlush(void){}; +void glFogf(GLenum pname, GLfloat param){}; +void glFogfv(GLenum pname, const GLfloat *params){}; +void glFogi(GLenum pname, GLint param){}; +void glFogiv(GLenum pname, const GLint *params){}; +void glFrontFace(GLenum mode){}; +void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar){}; +GLuint glGenLists(GLsizei range){return 0;}; +void glGenTextures(GLsizei n, GLuint *textures){}; +void glGetBooleanv(GLenum pname, GLboolean *params){}; +void glGetClipPlane(GLenum plane, GLdouble *equation){}; +void glGetDoublev(GLenum pname, GLdouble *params){}; +GLenum glGetError(void){return 0;}; +void glGetFloatv(GLenum pname, GLfloat *params){}; +void glGetIntegerv(GLenum pname, GLint *params){ + switch( pname ) { + case GL_MAX_TEXTURE_SIZE: *params = 1024; break; + case GL_MAX_TEXTURE_UNITS_ARB: *params = 2; break; + default: *params = 0; break; + } +}; +void glGetLightfv(GLenum light, GLenum pname, GLfloat *params){}; +void glGetLightiv(GLenum light, GLenum pname, GLint *params){}; +void glGetMapdv(GLenum target, GLenum query, GLdouble *v){}; +void glGetMapfv(GLenum target, GLenum query, GLfloat *v){}; +void glGetMapiv(GLenum target, GLenum query, GLint *v){}; +void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params){}; +void glGetMaterialiv(GLenum face, GLenum pname, GLint *params){}; +void glGetPixelMapfv(GLenum map, GLfloat *values){}; +void glGetPixelMapuiv(GLenum map, GLuint *values){}; +void glGetPixelMapusv(GLenum map, GLushort *values){}; +void glGetPointerv(GLenum pname, GLvoid* *params){}; +void glGetPolygonStipple(GLubyte *mask){}; +const GLubyte * glGetString(GLenum name){ + switch( name ) { + case GL_EXTENSIONS: return (GLubyte *)"GL_ARB_multitexture GL_ARB_texture_env_combine GL_ARB_texture_cube_map GL_ARB_texture_env_dot3"; + } + return (const GLubyte *)""; +}; +void glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params){}; +void glGetTexEnviv(GLenum target, GLenum pname, GLint *params){}; +void glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params){}; +void glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params){}; +void glGetTexGeniv(GLenum coord, GLenum pname, GLint *params){}; +void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels){}; +void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params){}; +void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params){}; +void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params){}; +void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params){}; +void glHint(GLenum target, GLenum mode){}; +void glIndexMask(GLuint mask){}; +void glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer){}; +void glIndexd(GLdouble c){}; +void glIndexdv(const GLdouble *c){}; +void glIndexf(GLfloat c){}; +void glIndexfv(const GLfloat *c){}; +void glIndexi(GLint c){}; +void glIndexiv(const GLint *c){}; +void glIndexs(GLshort c){}; +void glIndexsv(const GLshort *c){}; +void glIndexub(GLubyte c){}; +void glIndexubv(const GLubyte *c){}; +void glInitNames(void){}; +void glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer){}; +GLboolean glIsEnabled(GLenum cap){}; +GLboolean glIsList(GLuint list){}; +GLboolean glIsTexture(GLuint texture){}; +void glLightModelf(GLenum pname, GLfloat param){}; +void glLightModelfv(GLenum pname, const GLfloat *params){}; +void glLightModeli(GLenum pname, GLint param){}; +void glLightModeliv(GLenum pname, const GLint *params){}; +void glLightf(GLenum light, GLenum pname, GLfloat param){}; +void glLightfv(GLenum light, GLenum pname, const GLfloat *params){}; +void glLighti(GLenum light, GLenum pname, GLint param){}; +void glLightiv(GLenum light, GLenum pname, const GLint *params){}; +void glLineStipple(GLint factor, GLushort pattern){}; +void glLineWidth(GLfloat width){}; +void glListBase(GLuint base){}; +void glLoadIdentity(void){}; +void glLoadMatrixd(const GLdouble *m){}; +void glLoadMatrixf(const GLfloat *m){}; +void glLoadName(GLuint name){}; +void glLogicOp(GLenum opcode){}; +void glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points){}; +void glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points){}; +void glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points){}; +void glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points){}; +void glMapGrid1d(GLint un, GLdouble u1, GLdouble u2){}; +void glMapGrid1f(GLint un, GLfloat u1, GLfloat u2){}; +void glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2){}; +void glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2){}; +void glMaterialf(GLenum face, GLenum pname, GLfloat param){}; +void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params){}; +void glMateriali(GLenum face, GLenum pname, GLint param){}; +void glMaterialiv(GLenum face, GLenum pname, const GLint *params){}; +void glMatrixMode(GLenum mode){}; +void glMultMatrixd(const GLdouble *m){}; +void glMultMatrixf(const GLfloat *m){}; +void glNewList(GLuint list, GLenum mode){}; +void glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz){}; +void glNormal3bv(const GLbyte *v){}; +void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz){}; +void glNormal3dv(const GLdouble *v){}; +void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz){}; +void glNormal3fv(const GLfloat *v){}; +void glNormal3i(GLint nx, GLint ny, GLint nz){}; +void glNormal3iv(const GLint *v){}; +void glNormal3s(GLshort nx, GLshort ny, GLshort nz){}; +void glNormal3sv(const GLshort *v){}; +void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer){}; +void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar){}; +void glPassThrough(GLfloat token){}; +void glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values){}; +void glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values){}; +void glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values){}; +void glPixelStoref(GLenum pname, GLfloat param){}; +void glPixelStorei(GLenum pname, GLint param){}; +void glPixelTransferf(GLenum pname, GLfloat param){}; +void glPixelTransferi(GLenum pname, GLint param){}; +void glPixelZoom(GLfloat xfactor, GLfloat yfactor){}; +void glPointSize(GLfloat size){}; +void glPolygonMode(GLenum face, GLenum mode){}; +void glPolygonOffset(GLfloat factor, GLfloat units){}; +void glPolygonStipple(const GLubyte *mask){}; +void glPopAttrib(void){}; +void glPopClientAttrib(void){}; +void glPopMatrix(void){}; +void glPopName(void){}; +void glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities){}; +void glPushAttrib(GLbitfield mask){}; +void glPushClientAttrib(GLbitfield mask){}; +void glPushMatrix(void){}; +void glPushName(GLuint name){}; +void glRasterPos2d(GLdouble x, GLdouble y){}; +void glRasterPos2dv(const GLdouble *v){}; +void glRasterPos2f(GLfloat x, GLfloat y){}; +void glRasterPos2fv(const GLfloat *v){}; +void glRasterPos2i(GLint x, GLint y){}; +void glRasterPos2iv(const GLint *v){}; +void glRasterPos2s(GLshort x, GLshort y){}; +void glRasterPos2sv(const GLshort *v){}; +void glRasterPos3d(GLdouble x, GLdouble y, GLdouble z){}; +void glRasterPos3dv(const GLdouble *v){}; +void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z){}; +void glRasterPos3fv(const GLfloat *v){}; +void glRasterPos3i(GLint x, GLint y, GLint z){}; +void glRasterPos3iv(const GLint *v){}; +void glRasterPos3s(GLshort x, GLshort y, GLshort z){}; +void glRasterPos3sv(const GLshort *v){}; +void glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w){}; +void glRasterPos4dv(const GLdouble *v){}; +void glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w){}; +void glRasterPos4fv(const GLfloat *v){}; +void glRasterPos4i(GLint x, GLint y, GLint z, GLint w){}; +void glRasterPos4iv(const GLint *v){}; +void glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w){}; +void glRasterPos4sv(const GLshort *v){}; +void glReadBuffer(GLenum mode){}; +void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels){}; +void glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2){}; +void glRectdv(const GLdouble *v1, const GLdouble *v2){}; +void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2){}; +void glRectfv(const GLfloat *v1, const GLfloat *v2){}; +void glRecti(GLint x1, GLint y1, GLint x2, GLint y2){}; +void glRectiv(const GLint *v1, const GLint *v2){}; +void glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2){}; +void glRectsv(const GLshort *v1, const GLshort *v2){}; +GLint glRenderMode(GLenum mode){}; +void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z){}; +void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z){}; +void glScaled(GLdouble x, GLdouble y, GLdouble z){}; +void glScalef(GLfloat x, GLfloat y, GLfloat z){}; +void glScissor(GLint x, GLint y, GLsizei width, GLsizei height){}; +void glSelectBuffer(GLsizei size, GLuint *buffer){}; +void glShadeModel(GLenum mode){}; +void glStencilFunc(GLenum func, GLint ref, GLuint mask){}; +void glStencilMask(GLuint mask){}; +void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass){}; +void glTexCoord1d(GLdouble s){}; +void glTexCoord1dv(const GLdouble *v){}; +void glTexCoord1f(GLfloat s){}; +void glTexCoord1fv(const GLfloat *v){}; +void glTexCoord1i(GLint s){}; +void glTexCoord1iv(const GLint *v){}; +void glTexCoord1s(GLshort s){}; +void glTexCoord1sv(const GLshort *v){}; +void glTexCoord2d(GLdouble s, GLdouble t){}; +void glTexCoord2dv(const GLdouble *v){}; +void glTexCoord2f(GLfloat s, GLfloat t){}; +void glTexCoord2fv(const GLfloat *v){}; +void glTexCoord2i(GLint s, GLint t){}; +void glTexCoord2iv(const GLint *v){}; +void glTexCoord2s(GLshort s, GLshort t){}; +void glTexCoord2sv(const GLshort *v){}; +void glTexCoord3d(GLdouble s, GLdouble t, GLdouble r){}; +void glTexCoord3dv(const GLdouble *v){}; +void glTexCoord3f(GLfloat s, GLfloat t, GLfloat r){}; +void glTexCoord3fv(const GLfloat *v){}; +void glTexCoord3i(GLint s, GLint t, GLint r){}; +void glTexCoord3iv(const GLint *v){}; +void glTexCoord3s(GLshort s, GLshort t, GLshort r){}; +void glTexCoord3sv(const GLshort *v){}; +void glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q){}; +void glTexCoord4dv(const GLdouble *v){}; +void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q){}; +void glTexCoord4fv(const GLfloat *v){}; +void glTexCoord4i(GLint s, GLint t, GLint r, GLint q){}; +void glTexCoord4iv(const GLint *v){}; +void glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q){}; +void glTexCoord4sv(const GLshort *v){}; +void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer){}; +void glTexEnvf(GLenum target, GLenum pname, GLfloat param){}; +void glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params){}; +void glTexEnvi(GLenum target, GLenum pname, GLint param){}; +void glTexEnviv(GLenum target, GLenum pname, const GLint *params){}; +void glTexGend(GLenum coord, GLenum pname, GLdouble param){}; +void glTexGendv(GLenum coord, GLenum pname, const GLdouble *params){}; +void glTexGenf(GLenum coord, GLenum pname, GLfloat param){}; +void glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params){}; +void glTexGeni(GLenum coord, GLenum pname, GLint param){}; +void glTexGeniv(GLenum coord, GLenum pname, const GLint *params){}; +void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels){}; +void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {}; +void glTexParameterf(GLenum target, GLenum pname, GLfloat param){}; +void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params){}; +void glTexParameteri(GLenum target, GLenum pname, GLint param){}; +void glTexParameteriv(GLenum target, GLenum pname, const GLint *params){}; +void glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels){}; +void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels){}; +void glTranslated(GLdouble x, GLdouble y, GLdouble z){}; +void glTranslatef(GLfloat x, GLfloat y, GLfloat z){}; +void glVertex2d(GLdouble x, GLdouble y){}; +void glVertex2dv(const GLdouble *v){}; +void glVertex2f(GLfloat x, GLfloat y){}; +void glVertex2fv(const GLfloat *v){}; +void glVertex2i(GLint x, GLint y){}; +void glVertex2iv(const GLint *v){}; +void glVertex2s(GLshort x, GLshort y){}; +void glVertex2sv(const GLshort *v){}; +void glVertex3d(GLdouble x, GLdouble y, GLdouble z){}; +void glVertex3dv(const GLdouble *v){}; +void glVertex3f(GLfloat x, GLfloat y, GLfloat z){}; +void glVertex3fv(const GLfloat *v){}; +void glVertex3i(GLint x, GLint y, GLint z){}; +void glVertex3iv(const GLint *v){}; +void glVertex3s(GLshort x, GLshort y, GLshort z){}; +void glVertex3sv(const GLshort *v){}; +void glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w){}; +void glVertex4dv(const GLdouble *v){}; +void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w){}; +void glVertex4fv(const GLfloat *v){}; +void glVertex4i(GLint x, GLint y, GLint z, GLint w){}; +void glVertex4iv(const GLint *v){}; +void glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w){}; +void glVertex4sv(const GLshort *v){}; +void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer){}; +void glViewport(GLint x, GLint y, GLsizei width, GLsizei height){}; + +void GLimp_WakeBackEnd(void*a) {}; +void GLimp_EnableLogging(bool) {}; +void GLimp_FrontEndSleep() {}; +void GLimp_ActivateContext() {}; +void GLimp_DeactivateContext() {}; +bool GLimp_SpawnRenderThread(void (*a)()) {return false;}; + +static void StubFunction( void ) {}; +GLExtension_t GLimp_ExtensionPointer( const char *a) { return StubFunction; }; + +bool GLimp_Init(glimpParms_t a) {return true;}; +void GLimp_SetGamma(unsigned short*a, unsigned short*b, unsigned short*c) {}; +void GLimp_Shutdown() {}; +void GLimp_SwapBuffers() {}; +void *GLimp_BackEndSleep() {return 0;}; diff --git a/sys/stub/sys_stub.cpp b/sys/stub/sys_stub.cpp new file mode 100644 index 000000000..94c897d29 --- /dev/null +++ b/sys/stub/sys_stub.cpp @@ -0,0 +1,225 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_OSPATH 256 + +static int frameNum; + +int Sys_Milliseconds( void ) { + return frameNum * 16; +} + +double Sys_GetClockTicks( void ) { + return frameNum * 16.0; +} + +double Sys_ClockTicksPerSecond( void ) { + return 1000.0; +} + +void Sys_Sleep( int msec ) { +} + +void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo& info ) { +} + +void Sys_DestroyThread( xthreadInfo& info ) { +} + +void Sys_FlushCacheMemory( void *base, int bytes ) { +} + +void Sys_Error( const char *error, ... ) { + va_list argptr; + char text[4096]; + + va_start (argptr, error); + vprintf (error, argptr); + va_end (argptr); + printf( "\n" ); + + exit( 1 ); +} + +void Sys_Quit( void ) { + exit( 0 ); +} + +char *Sys_GetClipboardData( void ) { + return NULL; +} + +void Sys_GenerateEvents( void ) { +} + +void Sys_Init( void ) { +} + +//========================================================== + +idPort clientPort, serverPort; + +void Sys_InitNetworking( void ) { +} + +bool idPort::GetPacket( netadr_t &net_from, void *data int &size, int maxSize ) { + return false; +} +void idPort::SendPacket( const netadr_t to, const void *data, int size ) { +} + +//========================================================== + +double idTimer::base; + +void idTimer::InitBaseClockTicks( void ) const { +} + +//========================================================== + +void _glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { +} + + +void Sys_InitInput( void ) { +} + +void Sys_ShutdownInput( void ) { +} + +sysEvent_t Sys_GetEvent( void ) { + sysEvent_t ev; + + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_NONE; + ev.evTime = Sys_Milliseconds(); + return ev; +} + +void Sys_Mkdir( const char *path ) { +} + +const char *Sys_DefaultCDPath(void) { + return ""; +} + +const char *Sys_DefaultBasePath(void) { + return ""; +} + +int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) +{ + struct dirent *d; + DIR *fdir; + bool dironly = false; + char search[MAX_OSPATH]; + int i; + struct stat st; + + list.Clear(); + + if ( !extension) + extension = ""; + + if ( extension[0] == '/' && extension[1] == 0 ) { + extension = ""; + dironly = true; + } + + // search + if ((fdir = opendir(directory)) == NULL) { + return 0; + } + + while ((d = readdir(fdir)) != NULL) { + idStr::snprintf( search, sizeof(search), "%s/%s", directory, d->d_name ); + if (stat(search, &st) == -1) + continue; + if (!dironly) { + idStr look(search); + idStr ext; + look.ExtractFileExtension( ext ); + if ( extension && extension[0] && ext.Icmp( &extension[1] ) != 0 ) { + continue; + } + } + if ((dironly && !(st.st_mode & S_IFDIR)) || + (!dironly && (st.st_mode & S_IFDIR))) + continue; + + list.Append( d->d_name ); + } + + closedir(fdir); + + return list.Num(); +} + +void Sys_GrabMouseCursor( bool grabIt ) { +} + +bool Sys_StringToNetAdr( const char *s, netadr_t *a ) { + return false; +} + +const char *Sys_NetAdrToString( const netadr_t a ) { + static char s[64]; + + if ( a.type == NA_LOOPBACK ) { + idStr::snPrintf( s, sizeof(s), "localhost" ); + } else if ( a.type == NA_IP ) { + idStr::snPrintf( s, sizeof(s), "%i.%i.%i.%i:%i", + a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port) ); + } + return s; +} + +void Sys_DoPreferences( void ) { +} + +int main( int argc, char **argv ) { + // combine the args into a windows-style command line + char cmdline[4096]; + cmdline[0] = 0; + for ( int i = 1 ; i < argc ; i++ ) { + strcat( cmdline, argv[i] ); + if ( i < argc - 1 ) { + strcat( cmdline, " " ); + } + } + common->Init( cmdline ); + + while( 1 ) { + common->Async(); + common->Frame(); + frameNum++; + } +} diff --git a/sys/stub/util_stub.cpp b/sys/stub/util_stub.cpp new file mode 100644 index 000000000..dd49fbb31 --- /dev/null +++ b/sys/stub/util_stub.cpp @@ -0,0 +1,24 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +void EditorPrintConsole(const char *msg) { +} diff --git a/sys/sys_local.cpp b/sys/sys_local.cpp new file mode 100644 index 000000000..16e981bb5 --- /dev/null +++ b/sys/sys_local.cpp @@ -0,0 +1,201 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop +#include "sys_local.h" + +const char * sysLanguageNames[] = { + "english", "spanish", "italian", "german", "french", "russian", + "polish", "korean", "japanese", "chinese", NULL +}; + +idCVar sys_lang( "sys_lang", "english", CVAR_SYSTEM | CVAR_ARCHIVE, "", sysLanguageNames, idCmdSystem::ArgCompletion_String ); + +idSysLocal sysLocal; +idSys * sys = &sysLocal; + +void idSysLocal::DebugPrintf( const char *fmt, ... ) { + va_list argptr; + + va_start( argptr, fmt ); + Sys_DebugVPrintf( fmt, argptr ); + va_end( argptr ); +} + +void idSysLocal::DebugVPrintf( const char *fmt, va_list arg ) { + Sys_DebugVPrintf( fmt, arg ); +} + +double idSysLocal::GetClockTicks( void ) { + return Sys_GetClockTicks(); +} + +double idSysLocal::ClockTicksPerSecond( void ) { + return Sys_ClockTicksPerSecond(); +} + +cpuid_t idSysLocal::GetProcessorId( void ) { + return Sys_GetProcessorId(); +} + +const char *idSysLocal::GetProcessorString( void ) { + return Sys_GetProcessorString(); +} + +const char *idSysLocal::FPU_GetState( void ) { + return Sys_FPU_GetState(); +} + +bool idSysLocal::FPU_StackIsEmpty( void ) { + return Sys_FPU_StackIsEmpty(); +} + +void idSysLocal::FPU_SetFTZ( bool enable ) { + Sys_FPU_SetFTZ( enable ); +} + +void idSysLocal::FPU_SetDAZ( bool enable ) { + Sys_FPU_SetDAZ( enable ); +} + +bool idSysLocal::LockMemory( void *ptr, int bytes ) { + return Sys_LockMemory( ptr, bytes ); +} + +bool idSysLocal::UnlockMemory( void *ptr, int bytes ) { + return Sys_UnlockMemory( ptr, bytes ); +} + +void idSysLocal::GetCallStack( address_t *callStack, const int callStackSize ) { + Sys_GetCallStack( callStack, callStackSize ); +} + +const char * idSysLocal::GetCallStackStr( const address_t *callStack, const int callStackSize ) { + return Sys_GetCallStackStr( callStack, callStackSize ); +} + +const char * idSysLocal::GetCallStackCurStr( int depth ) { + return Sys_GetCallStackCurStr( depth ); +} + +void idSysLocal::ShutdownSymbols( void ) { + Sys_ShutdownSymbols(); +} + +int idSysLocal::DLL_Load( const char *dllName ) { + return Sys_DLL_Load( dllName ); +} + +void *idSysLocal::DLL_GetProcAddress( int dllHandle, const char *procName ) { + return Sys_DLL_GetProcAddress( dllHandle, procName ); +} + +void idSysLocal::DLL_Unload( int dllHandle ) { + Sys_DLL_Unload( dllHandle ); +} + +void idSysLocal::DLL_GetFileName( const char *baseName, char *dllName, int maxLength ) { +#ifdef _WIN32 + idStr::snPrintf( dllName, maxLength, "%s" CPUSTRING ".dll", baseName ); +#elif defined( __linux__ ) + idStr::snPrintf( dllName, maxLength, "%s" CPUSTRING ".so", baseName ); +#elif defined( MACOS_X ) + idStr::snPrintf( dllName, maxLength, "%s" ".dylib", baseName ); +#else +#error OS define is required +#endif +} + +sysEvent_t idSysLocal::GenerateMouseButtonEvent( int button, bool down ) { + sysEvent_t ev; + ev.evType = SE_KEY; + ev.evValue = K_MOUSE1 + button - 1; + ev.evValue2 = down; + ev.evPtrLength = 0; + ev.evPtr = NULL; + return ev; +} + +sysEvent_t idSysLocal::GenerateMouseMoveEvent( int deltax, int deltay ) { + sysEvent_t ev; + ev.evType = SE_MOUSE; + ev.evValue = deltax; + ev.evValue2 = deltay; + ev.evPtrLength = 0; + ev.evPtr = NULL; + return ev; +} + +void idSysLocal::FPU_EnableExceptions( int exceptions ) { + Sys_FPU_EnableExceptions( exceptions ); +} + +/* +================= +Sys_TimeStampToStr +================= +*/ +const char *Sys_TimeStampToStr( ID_TIME_T timeStamp ) { + static char timeString[MAX_STRING_CHARS]; + timeString[0] = '\0'; + + tm* time = localtime( &timeStamp ); + idStr out; + + idStr lang = cvarSystem->GetCVarString( "sys_lang" ); + if ( lang.Icmp( "english" ) == 0 ) { + // english gets "month/day/year hour:min" + "am" or "pm" + out = va( "%02d", time->tm_mon + 1 ); + out += "/"; + out += va( "%02d", time->tm_mday ); + out += "/"; + out += va( "%d", time->tm_year + 1900 ); + out += "\t"; + if ( time->tm_hour > 12 ) { + out += va( "%02d", time->tm_hour - 12 ); + } else if ( time->tm_hour == 0 ) { + out += "12"; + } else { + out += va( "%02d", time->tm_hour ); + } + out += ":"; + out +=va( "%02d", time->tm_min ); + if ( time->tm_hour >= 12 ) { + out += "pm"; + } else { + out += "am"; + } + } else { + // europeans get "day/month/year 24hour:min" + out = va( "%02d", time->tm_mday ); + out += "/"; + out += va( "%02d", time->tm_mon + 1 ); + out += "/"; + out += va( "%d", time->tm_year + 1900 ); + out += "\t"; + out += va( "%02d", time->tm_hour ); + out += ":"; + out += va( "%02d", time->tm_min ); + } + idStr::Copynz( timeString, out, sizeof( timeString ) ); + + return timeString; +} + diff --git a/sys/sys_local.h b/sys/sys_local.h new file mode 100644 index 000000000..63722ffdd --- /dev/null +++ b/sys/sys_local.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SYS_LOCAL__ +#define __SYS_LOCAL__ + +/* +============================================================== + + idSysLocal + +============================================================== +*/ + +class idSysLocal : public idSys { +public: + virtual void DebugPrintf( const char *fmt, ... )id_attribute((format(printf,2,3))); + virtual void DebugVPrintf( const char *fmt, va_list arg ); + + virtual double GetClockTicks( void ); + virtual double ClockTicksPerSecond( void ); + virtual cpuid_t GetProcessorId( void ); + virtual const char * GetProcessorString( void ); + virtual const char * FPU_GetState( void ); + virtual bool FPU_StackIsEmpty( void ); + virtual void FPU_SetFTZ( bool enable ); + virtual void FPU_SetDAZ( bool enable ); + + virtual void FPU_EnableExceptions( int exceptions ); + + virtual void GetCallStack( address_t *callStack, const int callStackSize ); + virtual const char * GetCallStackStr( const address_t *callStack, const int callStackSize ); + virtual const char * GetCallStackCurStr( int depth ); + virtual void ShutdownSymbols( void ); + + virtual bool LockMemory( void *ptr, int bytes ); + virtual bool UnlockMemory( void *ptr, int bytes ); + + virtual int DLL_Load( const char *dllName ); + virtual void * DLL_GetProcAddress( int dllHandle, const char *procName ); + virtual void DLL_Unload( int dllHandle ); + virtual void DLL_GetFileName( const char *baseName, char *dllName, int maxLength ); + + virtual sysEvent_t GenerateMouseButtonEvent( int button, bool down ); + virtual sysEvent_t GenerateMouseMoveEvent( int deltax, int deltay ); + + virtual void OpenURL( const char *url, bool quit ); + virtual void StartProcess( const char *exeName, bool quit ); +}; + +#endif /* !__SYS_LOCAL__ */ diff --git a/sys/sys_public.h b/sys/sys_public.h index 6f7ff362a..615054f89 100644 --- a/sys/sys_public.h +++ b/sys/sys_public.h @@ -1,14 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef __SYS_PUBLIC__ #define __SYS_PUBLIC__ @@ -87,10 +94,6 @@ // Linux #ifdef __linux__ -#include -#include -#include - #ifdef __i386__ #define BUILD_STRING "linux-x86" #define BUILD_OS_ID 2 @@ -356,9 +359,9 @@ void Sys_ShowConsole( int visLevel, bool quitOnClose ); void Sys_Mkdir( const char *path ); -long Sys_FileTimeStamp( FILE *fp ); +ID_TIME_T Sys_FileTimeStamp( FILE *fp ); // NOTE: do we need to guarantee the same output on all platforms? -const char * Sys_TimeStampToStr( long timeStamp ); +const char * Sys_TimeStampToStr( ID_TIME_T timeStamp ); const char * Sys_DefaultCDPath( void ); const char * Sys_DefaultBasePath( void ); const char * Sys_DefaultSavePath( void ); diff --git a/sys/win32/eax.h b/sys/win32/eax.h new file mode 100644 index 000000000..8e420b053 --- /dev/null +++ b/sys/win32/eax.h @@ -0,0 +1,533 @@ +/****************************************************************** +* +* EAX.H - Environmental Audio Extensions version 3.0 +* for OpenAL and DirectSound3D +* Updated May 22, 2001 by Jean-Marc Jot, Sam Dicker (version 1.0). +* +******************************************************************* +*/ + +#ifndef EAX_H_INCLUDED +#define EAX_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef OPENAL + #include + + /* + * EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5} + */ + DEFINE_GUID(CLSID_EAXDirectSound, + 0x4ff53b81, + 0x1ce0, + 0x11d3, + 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5); + + /* + * EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C} + */ + DEFINE_GUID(CLSID_EAXDirectSound8, + 0xca503b60, + 0xb176, + 0x11d4, + 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc); + + + +#ifdef DIRECTSOUND_VERSION +#if DIRECTSOUND_VERSION == 0x0800 + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); +#endif +#endif + + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); + +#else // OPENAL + #include "..\Sdk\OpenAL\Include\al.h" + + #ifndef GUID_DEFINED + #define GUID_DEFINED + typedef struct _GUID + { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + } GUID; + #endif // !GUID_DEFINED + + #ifndef DEFINE_GUID + #ifndef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID FAR name + #else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + #endif // INITGUID + #endif // DEFINE_GUID + + + /* + * EAX OpenAL Extension + */ + typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); +#endif + +#pragma pack(push, 4) + +/* + * EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87} + */ +DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties, + 0xa8fa6882, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties + +typedef enum +{ + DSPROPERTY_EAXLISTENER_NONE, + DSPROPERTY_EAXLISTENER_ALLPARAMETERS, + DSPROPERTY_EAXLISTENER_ENVIRONMENT, + DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, + DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION, + DSPROPERTY_EAXLISTENER_ROOM, + DSPROPERTY_EAXLISTENER_ROOMHF, + DSPROPERTY_EAXLISTENER_ROOMLF, + DSPROPERTY_EAXLISTENER_DECAYTIME, + DSPROPERTY_EAXLISTENER_DECAYHFRATIO, + DSPROPERTY_EAXLISTENER_DECAYLFRATIO, + DSPROPERTY_EAXLISTENER_REFLECTIONS, + DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY, + DSPROPERTY_EAXLISTENER_REFLECTIONSPAN, + DSPROPERTY_EAXLISTENER_REVERB, + DSPROPERTY_EAXLISTENER_REVERBDELAY, + DSPROPERTY_EAXLISTENER_REVERBPAN, + DSPROPERTY_EAXLISTENER_ECHOTIME, + DSPROPERTY_EAXLISTENER_ECHODEPTH, + DSPROPERTY_EAXLISTENER_MODULATIONTIME, + DSPROPERTY_EAXLISTENER_MODULATIONDEPTH, + DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF, + DSPROPERTY_EAXLISTENER_HFREFERENCE, + DSPROPERTY_EAXLISTENER_LFREFERENCE, + DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXLISTENER_FLAGS +} DSPROPERTY_EAX_LISTENERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \ + DSPROPERTY_EAXLISTENER_IMMEDIATE) + +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; + +// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all times and delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myListener.lRoom = -1000; +// myListener.lRoomHF = -100; +// ... +// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ; +// instead of: +// myListener = { -1000, -100, ... , 0x00000009 }; +// If you want to save and load presets in binary form, you +// should define your own structure to insure future compatibility. +// +typedef struct _EAXLISTENERPROPERTIES +{ + unsigned long ulEnvironment; // sets all listener properties + float flEnvironmentSize; // environment size in meters + float flEnvironmentDiffusion; // environment diffusion + long lRoom; // room effect level (at mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lRoomLF; // relative room effect level at low frequencies + float flDecayTime; // reverberation decay time at mid frequencies + float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio + float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio + long lReflections; // early reflections level relative to room effect + float flReflectionsDelay; // initial reflection delay time + EAXVECTOR vReflectionsPan; // early reflections panning vector + long lReverb; // late reverberation level relative to room effect + float flReverbDelay; // late reverberation delay time relative to initial reflection + EAXVECTOR vReverbPan; // late reverberation panning vector + float flEchoTime; // echo time + float flEchoDepth; // echo depth + float flModulationTime; // modulation time + float flModulationDepth; // modulation depth + float flAirAbsorptionHF; // change in level per meter at high frequencies + float flHFReference; // reference high frequency + float flLFReference; // reference low frequency + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + unsigned long ulFlags; // modifies the behavior of properties +} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES; + +// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_UNDEFINED, + + EAX_ENVIRONMENT_COUNT +}; + +// Used by DSPROPERTY_EAXLISTENER_FLAGS +// +// Note: The number and order of flags may change in future EAX versions. +// It is recommended to use the flag defines as follows: +// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE; +// instead of: +// myFlags = 0x00000009; +// +// These flags determine what properties are affected by environment size. +#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time +#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level +#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time +#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level +#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time +#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time +#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time + +// This flag limits high-frequency decay time according to air absorption. +#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020 + +#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use + +// Property ranges and defaults: + +#define EAXLISTENER_MINENVIRONMENT 0 +#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1) +#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC + +#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f +#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f +#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f + +#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f +#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f +#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f + +#define EAXLISTENER_MINROOM (-10000) +#define EAXLISTENER_MAXROOM 0 +#define EAXLISTENER_DEFAULTROOM (-1000) + +#define EAXLISTENER_MINROOMHF (-10000) +#define EAXLISTENER_MAXROOMHF 0 +#define EAXLISTENER_DEFAULTROOMHF (-100) + +#define EAXLISTENER_MINROOMLF (-10000) +#define EAXLISTENER_MAXROOMLF 0 +#define EAXLISTENER_DEFAULTROOMLF 0 + +#define EAXLISTENER_MINDECAYTIME 0.1f +#define EAXLISTENER_MAXDECAYTIME 20.0f +#define EAXLISTENER_DEFAULTDECAYTIME 1.49f + +#define EAXLISTENER_MINDECAYHFRATIO 0.1f +#define EAXLISTENER_MAXDECAYHFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f + +#define EAXLISTENER_MINDECAYLFRATIO 0.1f +#define EAXLISTENER_MAXDECAYLFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f + +#define EAXLISTENER_MINREFLECTIONS (-10000) +#define EAXLISTENER_MAXREFLECTIONS 1000 +#define EAXLISTENER_DEFAULTREFLECTIONS (-2602) + +#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f +#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f +#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f + +#define EAXLISTENER_MINREVERB (-10000) +#define EAXLISTENER_MAXREVERB 2000 +#define EAXLISTENER_DEFAULTREVERB 200 + +#define EAXLISTENER_MINREVERBDELAY 0.0f +#define EAXLISTENER_MAXREVERBDELAY 0.1f +#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f + +#define EAXLISTENER_MINECHOTIME 0.075f +#define EAXLISTENER_MAXECHOTIME 0.25f +#define EAXLISTENER_DEFAULTECHOTIME 0.25f + +#define EAXLISTENER_MINECHODEPTH 0.0f +#define EAXLISTENER_MAXECHODEPTH 1.0f +#define EAXLISTENER_DEFAULTECHODEPTH 0.0f + +#define EAXLISTENER_MINMODULATIONTIME 0.04f +#define EAXLISTENER_MAXMODULATIONTIME 4.0f +#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f + +#define EAXLISTENER_MINMODULATIONDEPTH 0.0f +#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f +#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f + +#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f) +#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f +#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXLISTENER_MINHFREFERENCE 1000.0f +#define EAXLISTENER_MAXHFREFERENCE 20000.0f +#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f + +#define EAXLISTENER_MINLFREFERENCE 20.0f +#define EAXLISTENER_MAXLFREFERENCE 1000.0f +#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f + +#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f +#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f +#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \ + EAXLISTENERFLAGS_REFLECTIONSSCALE | \ + EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \ + EAXLISTENERFLAGS_REVERBSCALE | \ + EAXLISTENERFLAGS_REVERBDELAYSCALE | \ + EAXLISTENERFLAGS_DECAYHFLIMIT) + + + +/* +* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87} +*/ +DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties, + 0xa8fa6881, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties +#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties + +typedef enum +{ + DSPROPERTY_EAXBUFFER_NONE, + DSPROPERTY_EAXBUFFER_ALLPARAMETERS, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS, + DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_DIRECT, + DSPROPERTY_EAXBUFFER_DIRECTHF, + DSPROPERTY_EAXBUFFER_ROOM, + DSPROPERTY_EAXBUFFER_ROOMHF, + DSPROPERTY_EAXBUFFER_OBSTRUCTION, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSION, + DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO, + DSPROPERTY_EAXBUFFER_EXCLUSION, + DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF, + DSPROPERTY_EAXBUFFER_DOPPLERFACTOR, + DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR, + DSPROPERTY_EAXBUFFER_FLAGS +} DSPROPERTY_EAX_BUFFERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \ + DSPROPERTY_EAXBUFFER_IMMEDIATE) + +// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +typedef struct _EAXBUFFERPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lObstruction; // main obstruction control (attenuation at high frequencies) + float flObstructionLFRatio; // obstruction low-frequency level re. main control + long lOcclusion; // main occlusion control (attenuation at high frequencies) + float flOcclusionLFRatio; // occlusion low-frequency level re. main control + float flOcclusionRoomRatio; // relative occlusion control for room effect + float flOcclusionDirectRatio; // relative occlusion control for direct path + long lExclusion; // main exlusion control (attenuation at high frequencies) + float flExclusionLFRatio; // exclusion low-frequency level re. main control + long lOutsideVolumeHF; // outside sound cone level at high frequencies + float flDopplerFactor; // like DS3D flDopplerFactor but per source + float flRolloffFactor; // like DS3D flRolloffFactor but per source + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF + unsigned long ulFlags; // modifies the behavior of properties +} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION, +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; + +// Used by DSPROPERTY_EAXBUFFER_FLAGS +// TRUE: value is computed automatically - property is an offset +// FALSE: value is used directly +// +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO; +// instead of: +// myFlags = 0x00000003; +// +#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF +#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM +#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF + +#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use + +// Property ranges and defaults: + +#define EAXBUFFER_MINDIRECT (-10000) +#define EAXBUFFER_MAXDIRECT 1000 +#define EAXBUFFER_DEFAULTDIRECT 0 + +#define EAXBUFFER_MINDIRECTHF (-10000) +#define EAXBUFFER_MAXDIRECTHF 0 +#define EAXBUFFER_DEFAULTDIRECTHF 0 + +#define EAXBUFFER_MINROOM (-10000) +#define EAXBUFFER_MAXROOM 1000 +#define EAXBUFFER_DEFAULTROOM 0 + +#define EAXBUFFER_MINROOMHF (-10000) +#define EAXBUFFER_MAXROOMHF 0 +#define EAXBUFFER_DEFAULTROOMHF 0 + +#define EAXBUFFER_MINOBSTRUCTION (-10000) +#define EAXBUFFER_MAXOBSTRUCTION 0 +#define EAXBUFFER_DEFAULTOBSTRUCTION 0 + +#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f +#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f + +#define EAXBUFFER_MINOCCLUSION (-10000) +#define EAXBUFFER_MAXOCCLUSION 0 +#define EAXBUFFER_DEFAULTOCCLUSION 0 + +#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f + +#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f + +#define EAXBUFFER_MINEXCLUSION (-10000) +#define EAXBUFFER_MAXEXCLUSION 0 +#define EAXBUFFER_DEFAULTEXCLUSION 0 + +#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f + +#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000) +#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0 +#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0 + +#define EAXBUFFER_MINDOPPLERFACTOR 0.0f +#define EAXBUFFER_MAXDOPPLERFACTOR 10.f +#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f + +#define EAXBUFFER_MINROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f +#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f +#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f + +#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \ + EAXBUFFERFLAGS_ROOMAUTO | \ + EAXBUFFERFLAGS_ROOMHFAUTO ) + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif diff --git a/sys/win32/eaxguid.lib b/sys/win32/eaxguid.lib new file mode 100644 index 000000000..5247dd7ed Binary files /dev/null and b/sys/win32/eaxguid.lib differ diff --git a/sys/win32/gl_logfuncs.cpp b/sys/win32/gl_logfuncs.cpp new file mode 100644 index 000000000..7c1544a4d --- /dev/null +++ b/sys/win32/gl_logfuncs.cpp @@ -0,0 +1,1914 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +static void APIENTRY logAccum(GLenum op, GLfloat value) { + fprintf( tr.logFile, "glAccum %s %g\n", EnumString(op), value ); + dllAccum(op, value); +} + +static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref) { + fprintf( tr.logFile, "glAlphaFunc %s %g\n", EnumString(func), ref ); + dllAlphaFunc(func, ref); +} + +static GLboolean APIENTRY logAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) { +// unknown type: "const GLuint *" name: "textures" +// unknown type: "GLboolean *" name: "residences" + fprintf( tr.logFile, "glAreTexturesResident %d 'const GLuint * textures' 'GLboolean * residences'\n", n ); + return dllAreTexturesResident(n, textures, residences); +} + +static void APIENTRY logArrayElement(GLint i) { + fprintf( tr.logFile, "glArrayElement %d\n", i ); + dllArrayElement(i); +} + +static void APIENTRY logBegin(GLenum mode) { + fprintf( tr.logFile, "glBegin %s\n", EnumString(mode) ); + dllBegin(mode); +} + +static void APIENTRY logBindTexture(GLenum target, GLuint texture) { + fprintf( tr.logFile, "glBindTexture %s %d\n", EnumString(target), texture ); + dllBindTexture(target, texture); +} + +static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { +// unknown type: "const GLubyte *" name: "bitmap" + fprintf( tr.logFile, "glBitmap %d %d %g %g %g %g 'const GLubyte * bitmap'\n", width, height, xorig, yorig, xmove, ymove ); + dllBitmap(width, height, xorig, yorig, xmove, ymove, bitmap); +} + +static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor) { + fprintf( tr.logFile, "glBlendFunc %s %s\n", EnumString(sfactor), EnumString(dfactor) ); + dllBlendFunc(sfactor, dfactor); +} + +static void APIENTRY logCallList(GLuint list) { + fprintf( tr.logFile, "glCallList %d\n", list ); + dllCallList(list); +} + +static void APIENTRY logCallLists(GLsizei n, GLenum type, const GLvoid *lists) { +// unknown type: "const GLvoid *" name: "lists" + fprintf( tr.logFile, "glCallLists %d %s 'const GLvoid * lists'\n", n, EnumString(type) ); + dllCallLists(n, type, lists); +} + +static void APIENTRY logClear(GLbitfield mask) { +// unknown type: "GLbitfield" name: "mask" + fprintf( tr.logFile, "glClear 'GLbitfield mask'\n" ); + dllClear(mask); +} + +static void APIENTRY logClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + fprintf( tr.logFile, "glClearAccum %g %g %g %g\n", red, green, blue, alpha ); + dllClearAccum(red, green, blue, alpha); +} + +static void APIENTRY logClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + fprintf( tr.logFile, "glClearColor %g %g %g %g\n", red, green, blue, alpha ); + dllClearColor(red, green, blue, alpha); +} + +static void APIENTRY logClearDepth(GLclampd depth) { +// unknown type: "GLclampd" name: "depth" + fprintf( tr.logFile, "glClearDepth 'GLclampd depth'\n" ); + dllClearDepth(depth); +} + +static void APIENTRY logClearIndex(GLfloat c) { + fprintf( tr.logFile, "glClearIndex %g\n", c ); + dllClearIndex(c); +} + +static void APIENTRY logClearStencil(GLint s) { + fprintf( tr.logFile, "glClearStencil %d\n", s ); + dllClearStencil(s); +} + +static void APIENTRY logClipPlane(GLenum plane, const GLdouble *equation) { +// unknown type: "const GLdouble *" name: "equation" + fprintf( tr.logFile, "glClipPlane %s 'const GLdouble * equation'\n", EnumString(plane) ); + dllClipPlane(plane, equation); +} + +static void APIENTRY logColor3b(GLbyte red, GLbyte green, GLbyte blue) { + fprintf( tr.logFile, "glColor3b %d %d %d\n", red, green, blue ); + dllColor3b(red, green, blue); +} + +static void APIENTRY logColor3bv(const GLbyte *v) { +// unknown type: "const GLbyte *" name: "v" + fprintf( tr.logFile, "glColor3bv 'const GLbyte * v'\n" ); + dllColor3bv(v); +} + +static void APIENTRY logColor3d(GLdouble red, GLdouble green, GLdouble blue) { + fprintf( tr.logFile, "glColor3d %g %g %g\n", red, green, blue ); + dllColor3d(red, green, blue); +} + +static void APIENTRY logColor3dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glColor3dv 'const GLdouble * v'\n" ); + dllColor3dv(v); +} + +static void APIENTRY logColor3f(GLfloat red, GLfloat green, GLfloat blue) { + fprintf( tr.logFile, "glColor3f %g %g %g\n", red, green, blue ); + dllColor3f(red, green, blue); +} + +static void APIENTRY logColor3fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glColor3fv 'const GLfloat * v'\n" ); + dllColor3fv(v); +} + +static void APIENTRY logColor3i(GLint red, GLint green, GLint blue) { + fprintf( tr.logFile, "glColor3i %d %d %d\n", red, green, blue ); + dllColor3i(red, green, blue); +} + +static void APIENTRY logColor3iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glColor3iv 'const GLint * v'\n" ); + dllColor3iv(v); +} + +static void APIENTRY logColor3s(GLshort red, GLshort green, GLshort blue) { + fprintf( tr.logFile, "glColor3s %d %d %d\n", red, green, blue ); + dllColor3s(red, green, blue); +} + +static void APIENTRY logColor3sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glColor3sv 'const GLshort * v'\n" ); + dllColor3sv(v); +} + +static void APIENTRY logColor3ub(GLubyte red, GLubyte green, GLubyte blue) { + fprintf( tr.logFile, "glColor3ub %d %d %d\n", red, green, blue ); + dllColor3ub(red, green, blue); +} + +static void APIENTRY logColor3ubv(const GLubyte *v) { +// unknown type: "const GLubyte *" name: "v" + fprintf( tr.logFile, "glColor3ubv 'const GLubyte * v'\n" ); + dllColor3ubv(v); +} + +static void APIENTRY logColor3ui(GLuint red, GLuint green, GLuint blue) { + fprintf( tr.logFile, "glColor3ui %d %d %d\n", red, green, blue ); + dllColor3ui(red, green, blue); +} + +static void APIENTRY logColor3uiv(const GLuint *v) { +// unknown type: "const GLuint *" name: "v" + fprintf( tr.logFile, "glColor3uiv 'const GLuint * v'\n" ); + dllColor3uiv(v); +} + +static void APIENTRY logColor3us(GLushort red, GLushort green, GLushort blue) { + fprintf( tr.logFile, "glColor3us %d %d %d\n", red, green, blue ); + dllColor3us(red, green, blue); +} + +static void APIENTRY logColor3usv(const GLushort *v) { +// unknown type: "const GLushort *" name: "v" + fprintf( tr.logFile, "glColor3usv 'const GLushort * v'\n" ); + dllColor3usv(v); +} + +static void APIENTRY logColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { + fprintf( tr.logFile, "glColor4b %d %d %d %d\n", red, green, blue, alpha ); + dllColor4b(red, green, blue, alpha); +} + +static void APIENTRY logColor4bv(const GLbyte *v) { +// unknown type: "const GLbyte *" name: "v" + fprintf( tr.logFile, "glColor4bv 'const GLbyte * v'\n" ); + dllColor4bv(v); +} + +static void APIENTRY logColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { + fprintf( tr.logFile, "glColor4d %g %g %g %g\n", red, green, blue, alpha ); + dllColor4d(red, green, blue, alpha); +} + +static void APIENTRY logColor4dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glColor4dv 'const GLdouble * v'\n" ); + dllColor4dv(v); +} + +static void APIENTRY logColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + fprintf( tr.logFile, "glColor4f %g %g %g %g\n", red, green, blue, alpha ); + dllColor4f(red, green, blue, alpha); +} + +static void APIENTRY logColor4fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glColor4fv 'const GLfloat * v'\n" ); + dllColor4fv(v); +} + +static void APIENTRY logColor4i(GLint red, GLint green, GLint blue, GLint alpha) { + fprintf( tr.logFile, "glColor4i %d %d %d %d\n", red, green, blue, alpha ); + dllColor4i(red, green, blue, alpha); +} + +static void APIENTRY logColor4iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glColor4iv 'const GLint * v'\n" ); + dllColor4iv(v); +} + +static void APIENTRY logColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) { + fprintf( tr.logFile, "glColor4s %d %d %d %d\n", red, green, blue, alpha ); + dllColor4s(red, green, blue, alpha); +} + +static void APIENTRY logColor4sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glColor4sv 'const GLshort * v'\n" ); + dllColor4sv(v); +} + +static void APIENTRY logColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { + fprintf( tr.logFile, "glColor4ub %d %d %d %d\n", red, green, blue, alpha ); + dllColor4ub(red, green, blue, alpha); +} + +static void APIENTRY logColor4ubv(const GLubyte *v) { +// unknown type: "const GLubyte *" name: "v" + fprintf( tr.logFile, "glColor4ubv 'const GLubyte * v'\n" ); + dllColor4ubv(v); +} + +static void APIENTRY logColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) { + fprintf( tr.logFile, "glColor4ui %d %d %d %d\n", red, green, blue, alpha ); + dllColor4ui(red, green, blue, alpha); +} + +static void APIENTRY logColor4uiv(const GLuint *v) { +// unknown type: "const GLuint *" name: "v" + fprintf( tr.logFile, "glColor4uiv 'const GLuint * v'\n" ); + dllColor4uiv(v); +} + +static void APIENTRY logColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) { + fprintf( tr.logFile, "glColor4us %d %d %d %d\n", red, green, blue, alpha ); + dllColor4us(red, green, blue, alpha); +} + +static void APIENTRY logColor4usv(const GLushort *v) { +// unknown type: "const GLushort *" name: "v" + fprintf( tr.logFile, "glColor4usv 'const GLushort * v'\n" ); + dllColor4usv(v); +} + +static void APIENTRY logColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + fprintf( tr.logFile, "glColorMask %s %s %s %s\n", red ? "Y" : "N", green ? "Y" : "N", blue ? "Y" : "N", alpha ? "Y" : "N" ); + dllColorMask(red, green, blue, alpha); +} + +static void APIENTRY logColorMaterial(GLenum face, GLenum mode) { + fprintf( tr.logFile, "glColorMaterial %s %s\n", EnumString(face), EnumString(mode) ); + dllColorMaterial(face, mode); +} + +static void APIENTRY logColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glColorPointer %d %s %d 'const GLvoid * pointer'\n", size, EnumString(type), stride ); + dllColorPointer(size, type, stride, pointer); +} + +static void APIENTRY logCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { + fprintf( tr.logFile, "glCopyPixels %d %d %d %d %s\n", x, y, width, height, EnumString(type) ); + dllCopyPixels(x, y, width, height, type); +} + +static void APIENTRY logCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) { + fprintf( tr.logFile, "glCopyTexImage1D %s %d %s %d %d %d %d\n", EnumString(target), level, EnumString(internalFormat), x, y, width, border ); + dllCopyTexImage1D(target, level, internalFormat, x, y, width, border); +} + +static void APIENTRY logCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + fprintf( tr.logFile, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n", EnumString(target), level, EnumString(internalFormat), x, y, width, height, border ); + dllCopyTexImage2D(target, level, internalFormat, x, y, width, height, border); +} + +static void APIENTRY logCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { + fprintf( tr.logFile, "glCopyTexSubImage1D %s %d %d %d %d %d\n", EnumString(target), level, xoffset, x, y, width ); + dllCopyTexSubImage1D(target, level, xoffset, x, y, width); +} + +static void APIENTRY logCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + fprintf( tr.logFile, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n", EnumString(target), level, xoffset, yoffset, x, y, width, height ); + dllCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +} + +static void APIENTRY logCullFace(GLenum mode) { + fprintf( tr.logFile, "glCullFace %s\n", EnumString(mode) ); + dllCullFace(mode); +} + +static void APIENTRY logDeleteLists(GLuint list, GLsizei range) { + fprintf( tr.logFile, "glDeleteLists %d %d\n", list, range ); + dllDeleteLists(list, range); +} + +static void APIENTRY logDeleteTextures(GLsizei n, const GLuint *textures) { +// unknown type: "const GLuint *" name: "textures" + fprintf( tr.logFile, "glDeleteTextures %d 'const GLuint * textures'\n", n ); + dllDeleteTextures(n, textures); +} + +static void APIENTRY logDepthFunc(GLenum func) { + fprintf( tr.logFile, "glDepthFunc %s\n", EnumString(func) ); + dllDepthFunc(func); +} + +static void APIENTRY logDepthMask(GLboolean flag) { + fprintf( tr.logFile, "glDepthMask %s\n", flag ? "Y" : "N" ); + dllDepthMask(flag); +} + +static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar) { +// unknown type: "GLclampd" name: "zNear" +// unknown type: "GLclampd" name: "zFar" + fprintf( tr.logFile, "glDepthRange 'GLclampd zNear' 'GLclampd zFar'\n" ); + dllDepthRange(zNear, zFar); +} + +static void APIENTRY logDisable(GLenum cap) { + fprintf( tr.logFile, "glDisable %s\n", EnumString(cap) ); + dllDisable(cap); +} + +static void APIENTRY logDisableClientState(GLenum array) { + fprintf( tr.logFile, "glDisableClientState %s\n", EnumString(array) ); + dllDisableClientState(array); +} + +static void APIENTRY logDrawArrays(GLenum mode, GLint first, GLsizei count) { + fprintf( tr.logFile, "glDrawArrays %s %d %d\n", EnumString(mode), first, count ); + dllDrawArrays(mode, first, count); +} + +static void APIENTRY logDrawBuffer(GLenum mode) { + fprintf( tr.logFile, "glDrawBuffer %s\n", EnumString(mode) ); + dllDrawBuffer(mode); +} + +static void APIENTRY logDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { +// unknown type: "const GLvoid *" name: "indices" + fprintf( tr.logFile, "glDrawElements %s %d %s 'const GLvoid * indices'\n", EnumString(mode), count, EnumString(type) ); + dllDrawElements(mode, count, type, indices); +} + +static void APIENTRY logDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { +// unknown type: "const GLvoid *" name: "pixels" + fprintf( tr.logFile, "glDrawPixels %d %d %s %s 'const GLvoid * pixels'\n", width, height, EnumString(format), EnumString(type) ); + dllDrawPixels(width, height, format, type, pixels); +} + +static void APIENTRY logEdgeFlag(GLboolean flag) { + fprintf( tr.logFile, "glEdgeFlag %s\n", flag ? "Y" : "N" ); + dllEdgeFlag(flag); +} + +static void APIENTRY logEdgeFlagPointer(GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glEdgeFlagPointer %d 'const GLvoid * pointer'\n", stride ); + dllEdgeFlagPointer(stride, pointer); +} + +static void APIENTRY logEdgeFlagv(const GLboolean *flag) { +// unknown type: "const GLboolean *" name: "flag" + fprintf( tr.logFile, "glEdgeFlagv 'const GLboolean * flag'\n" ); + dllEdgeFlagv(flag); +} + +static void APIENTRY logEnable(GLenum cap) { + fprintf( tr.logFile, "glEnable %s\n", EnumString(cap) ); + dllEnable(cap); +} + +static void APIENTRY logEnableClientState(GLenum array) { + fprintf( tr.logFile, "glEnableClientState %s\n", EnumString(array) ); + dllEnableClientState(array); +} + +static void APIENTRY logEnd(void) { + fprintf( tr.logFile, "glEnd\n" ); + dllEnd(); +} + +static void APIENTRY logEndList(void) { + fprintf( tr.logFile, "glEndList\n" ); + dllEndList(); +} + +static void APIENTRY logEvalCoord1d(GLdouble u) { + fprintf( tr.logFile, "glEvalCoord1d %g\n", u ); + dllEvalCoord1d(u); +} + +static void APIENTRY logEvalCoord1dv(const GLdouble *u) { +// unknown type: "const GLdouble *" name: "u" + fprintf( tr.logFile, "glEvalCoord1dv 'const GLdouble * u'\n" ); + dllEvalCoord1dv(u); +} + +static void APIENTRY logEvalCoord1f(GLfloat u) { + fprintf( tr.logFile, "glEvalCoord1f %g\n", u ); + dllEvalCoord1f(u); +} + +static void APIENTRY logEvalCoord1fv(const GLfloat *u) { +// unknown type: "const GLfloat *" name: "u" + fprintf( tr.logFile, "glEvalCoord1fv 'const GLfloat * u'\n" ); + dllEvalCoord1fv(u); +} + +static void APIENTRY logEvalCoord2d(GLdouble u, GLdouble v) { + fprintf( tr.logFile, "glEvalCoord2d %g %g\n", u, v ); + dllEvalCoord2d(u, v); +} + +static void APIENTRY logEvalCoord2dv(const GLdouble *u) { +// unknown type: "const GLdouble *" name: "u" + fprintf( tr.logFile, "glEvalCoord2dv 'const GLdouble * u'\n" ); + dllEvalCoord2dv(u); +} + +static void APIENTRY logEvalCoord2f(GLfloat u, GLfloat v) { + fprintf( tr.logFile, "glEvalCoord2f %g %g\n", u, v ); + dllEvalCoord2f(u, v); +} + +static void APIENTRY logEvalCoord2fv(const GLfloat *u) { +// unknown type: "const GLfloat *" name: "u" + fprintf( tr.logFile, "glEvalCoord2fv 'const GLfloat * u'\n" ); + dllEvalCoord2fv(u); +} + +static void APIENTRY logEvalMesh1(GLenum mode, GLint i1, GLint i2) { + fprintf( tr.logFile, "glEvalMesh1 %s %d %d\n", EnumString(mode), i1, i2 ); + dllEvalMesh1(mode, i1, i2); +} + +static void APIENTRY logEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { + fprintf( tr.logFile, "glEvalMesh2 %s %d %d %d %d\n", EnumString(mode), i1, i2, j1, j2 ); + dllEvalMesh2(mode, i1, i2, j1, j2); +} + +static void APIENTRY logEvalPoint1(GLint i) { + fprintf( tr.logFile, "glEvalPoint1 %d\n", i ); + dllEvalPoint1(i); +} + +static void APIENTRY logEvalPoint2(GLint i, GLint j) { + fprintf( tr.logFile, "glEvalPoint2 %d %d\n", i, j ); + dllEvalPoint2(i, j); +} + +static void APIENTRY logFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) { +// unknown type: "GLfloat *" name: "buffer" + fprintf( tr.logFile, "glFeedbackBuffer %d %s 'GLfloat * buffer'\n", size, EnumString(type) ); + dllFeedbackBuffer(size, type, buffer); +} + +static void APIENTRY logFinish(void) { + fprintf( tr.logFile, "glFinish\n" ); + dllFinish(); +} + +static void APIENTRY logFlush(void) { + fprintf( tr.logFile, "glFlush\n" ); + dllFlush(); +} + +static void APIENTRY logFogf(GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glFogf %s %g\n", EnumString(pname), param ); + dllFogf(pname, param); +} + +static void APIENTRY logFogfv(GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glFogfv %s 'const GLfloat * params'\n", EnumString(pname) ); + dllFogfv(pname, params); +} + +static void APIENTRY logFogi(GLenum pname, GLint param) { + fprintf( tr.logFile, "glFogi %s %d\n", EnumString(pname), param ); + dllFogi(pname, param); +} + +static void APIENTRY logFogiv(GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glFogiv %s 'const GLint * params'\n", EnumString(pname) ); + dllFogiv(pname, params); +} + +static void APIENTRY logFrontFace(GLenum mode) { + fprintf( tr.logFile, "glFrontFace %s\n", EnumString(mode) ); + dllFrontFace(mode); +} + +static void APIENTRY logFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { + fprintf( tr.logFile, "glFrustum %g %g %g %g %g %g\n", left, right, bottom, top, zNear, zFar ); + dllFrustum(left, right, bottom, top, zNear, zFar); +} + +static GLuint APIENTRY logGenLists(GLsizei range) { + fprintf( tr.logFile, "glGenLists %d\n", range ); + return dllGenLists(range); +} + +static void APIENTRY logGenTextures(GLsizei n, GLuint *textures) { +// unknown type: "GLuint *" name: "textures" + fprintf( tr.logFile, "glGenTextures %d 'GLuint * textures'\n", n ); + dllGenTextures(n, textures); +} + +static void APIENTRY logGetBooleanv(GLenum pname, GLboolean *params) { +// unknown type: "GLboolean *" name: "params" + fprintf( tr.logFile, "glGetBooleanv %s 'GLboolean * params'\n", EnumString(pname) ); + dllGetBooleanv(pname, params); +} + +static void APIENTRY logGetClipPlane(GLenum plane, GLdouble *equation) { +// unknown type: "GLdouble *" name: "equation" + fprintf( tr.logFile, "glGetClipPlane %s 'GLdouble * equation'\n", EnumString(plane) ); + dllGetClipPlane(plane, equation); +} + +static void APIENTRY logGetDoublev(GLenum pname, GLdouble *params) { +// unknown type: "GLdouble *" name: "params" + fprintf( tr.logFile, "glGetDoublev %s 'GLdouble * params'\n", EnumString(pname) ); + dllGetDoublev(pname, params); +} + +static GLenum APIENTRY logGetError(void) { + fprintf( tr.logFile, "glGetError\n" ); + return dllGetError(); +} + +static void APIENTRY logGetFloatv(GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetFloatv %s 'GLfloat * params'\n", EnumString(pname) ); + dllGetFloatv(pname, params); +} + +static void APIENTRY logGetIntegerv(GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetIntegerv %s 'GLint * params'\n", EnumString(pname) ); + dllGetIntegerv(pname, params); +} + +static void APIENTRY logGetLightfv(GLenum light, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetLightfv %s %s 'GLfloat * params'\n", EnumString(light), EnumString(pname) ); + dllGetLightfv(light, pname, params); +} + +static void APIENTRY logGetLightiv(GLenum light, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetLightiv %s %s 'GLint * params'\n", EnumString(light), EnumString(pname) ); + dllGetLightiv(light, pname, params); +} + +static void APIENTRY logGetMapdv(GLenum target, GLenum query, GLdouble *v) { +// unknown type: "GLdouble *" name: "v" + fprintf( tr.logFile, "glGetMapdv %s %s 'GLdouble * v'\n", EnumString(target), EnumString(query) ); + dllGetMapdv(target, query, v); +} + +static void APIENTRY logGetMapfv(GLenum target, GLenum query, GLfloat *v) { +// unknown type: "GLfloat *" name: "v" + fprintf( tr.logFile, "glGetMapfv %s %s 'GLfloat * v'\n", EnumString(target), EnumString(query) ); + dllGetMapfv(target, query, v); +} + +static void APIENTRY logGetMapiv(GLenum target, GLenum query, GLint *v) { +// unknown type: "GLint *" name: "v" + fprintf( tr.logFile, "glGetMapiv %s %s 'GLint * v'\n", EnumString(target), EnumString(query) ); + dllGetMapiv(target, query, v); +} + +static void APIENTRY logGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetMaterialfv %s %s 'GLfloat * params'\n", EnumString(face), EnumString(pname) ); + dllGetMaterialfv(face, pname, params); +} + +static void APIENTRY logGetMaterialiv(GLenum face, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetMaterialiv %s %s 'GLint * params'\n", EnumString(face), EnumString(pname) ); + dllGetMaterialiv(face, pname, params); +} + +static void APIENTRY logGetPixelMapfv(GLenum map, GLfloat *values) { +// unknown type: "GLfloat *" name: "values" + fprintf( tr.logFile, "glGetPixelMapfv %s 'GLfloat * values'\n", EnumString(map) ); + dllGetPixelMapfv(map, values); +} + +static void APIENTRY logGetPixelMapuiv(GLenum map, GLuint *values) { +// unknown type: "GLuint *" name: "values" + fprintf( tr.logFile, "glGetPixelMapuiv %s 'GLuint * values'\n", EnumString(map) ); + dllGetPixelMapuiv(map, values); +} + +static void APIENTRY logGetPixelMapusv(GLenum map, GLushort *values) { +// unknown type: "GLushort *" name: "values" + fprintf( tr.logFile, "glGetPixelMapusv %s 'GLushort * values'\n", EnumString(map) ); + dllGetPixelMapusv(map, values); +} + +static void APIENTRY logGetPointerv(GLenum pname, GLvoid* *params) { +// unknown type: "GLvoid* *" name: "params" + fprintf( tr.logFile, "glGetPointerv %s 'GLvoid* * params'\n", EnumString(pname) ); + dllGetPointerv(pname, params); +} + +static void APIENTRY logGetPolygonStipple(GLubyte *mask) { +// unknown type: "GLubyte *" name: "mask" + fprintf( tr.logFile, "glGetPolygonStipple 'GLubyte * mask'\n" ); + dllGetPolygonStipple(mask); +} + +static const GLubyte * APIENTRY logGetString(GLenum name) { + fprintf( tr.logFile, "glGetString %s\n", EnumString(name) ); + return dllGetString(name); +} + +static void APIENTRY logGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetTexEnvfv %s %s 'GLfloat * params'\n", EnumString(target), EnumString(pname) ); + dllGetTexEnvfv(target, pname, params); +} + +static void APIENTRY logGetTexEnviv(GLenum target, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetTexEnviv %s %s 'GLint * params'\n", EnumString(target), EnumString(pname) ); + dllGetTexEnviv(target, pname, params); +} + +static void APIENTRY logGetTexGendv(GLenum coord, GLenum pname, GLdouble *params) { +// unknown type: "GLdouble *" name: "params" + fprintf( tr.logFile, "glGetTexGendv %s %s 'GLdouble * params'\n", EnumString(coord), EnumString(pname) ); + dllGetTexGendv(coord, pname, params); +} + +static void APIENTRY logGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetTexGenfv %s %s 'GLfloat * params'\n", EnumString(coord), EnumString(pname) ); + dllGetTexGenfv(coord, pname, params); +} + +static void APIENTRY logGetTexGeniv(GLenum coord, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetTexGeniv %s %s 'GLint * params'\n", EnumString(coord), EnumString(pname) ); + dllGetTexGeniv(coord, pname, params); +} + +static void APIENTRY logGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) { +// unknown type: "GLvoid *" name: "pixels" + fprintf( tr.logFile, "glGetTexImage %s %d %s %s 'GLvoid * pixels'\n", EnumString(target), level, EnumString(format), EnumString(type) ); + dllGetTexImage(target, level, format, type, pixels); +} + +static void APIENTRY logGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetTexLevelParameterfv %s %d %s 'GLfloat * params'\n", EnumString(target), level, EnumString(pname) ); + dllGetTexLevelParameterfv(target, level, pname, params); +} + +static void APIENTRY logGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetTexLevelParameteriv %s %d %s 'GLint * params'\n", EnumString(target), level, EnumString(pname) ); + dllGetTexLevelParameteriv(target, level, pname, params); +} + +static void APIENTRY logGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { +// unknown type: "GLfloat *" name: "params" + fprintf( tr.logFile, "glGetTexParameterfv %s %s 'GLfloat * params'\n", EnumString(target), EnumString(pname) ); + dllGetTexParameterfv(target, pname, params); +} + +static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { +// unknown type: "GLint *" name: "params" + fprintf( tr.logFile, "glGetTexParameteriv %s %s 'GLint * params'\n", EnumString(target), EnumString(pname) ); + dllGetTexParameteriv(target, pname, params); +} + +static void APIENTRY logHint(GLenum target, GLenum mode) { + fprintf( tr.logFile, "glHint %s %s\n", EnumString(target), EnumString(mode) ); + dllHint(target, mode); +} + +static void APIENTRY logIndexMask(GLuint mask) { + fprintf( tr.logFile, "glIndexMask %d\n", mask ); + dllIndexMask(mask); +} + +static void APIENTRY logIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glIndexPointer %s %d 'const GLvoid * pointer'\n", EnumString(type), stride ); + dllIndexPointer(type, stride, pointer); +} + +static void APIENTRY logIndexd(GLdouble c) { + fprintf( tr.logFile, "glIndexd %g\n", c ); + dllIndexd(c); +} + +static void APIENTRY logIndexdv(const GLdouble *c) { +// unknown type: "const GLdouble *" name: "c" + fprintf( tr.logFile, "glIndexdv 'const GLdouble * c'\n" ); + dllIndexdv(c); +} + +static void APIENTRY logIndexf(GLfloat c) { + fprintf( tr.logFile, "glIndexf %g\n", c ); + dllIndexf(c); +} + +static void APIENTRY logIndexfv(const GLfloat *c) { +// unknown type: "const GLfloat *" name: "c" + fprintf( tr.logFile, "glIndexfv 'const GLfloat * c'\n" ); + dllIndexfv(c); +} + +static void APIENTRY logIndexi(GLint c) { + fprintf( tr.logFile, "glIndexi %d\n", c ); + dllIndexi(c); +} + +static void APIENTRY logIndexiv(const GLint *c) { +// unknown type: "const GLint *" name: "c" + fprintf( tr.logFile, "glIndexiv 'const GLint * c'\n" ); + dllIndexiv(c); +} + +static void APIENTRY logIndexs(GLshort c) { + fprintf( tr.logFile, "glIndexs %d\n", c ); + dllIndexs(c); +} + +static void APIENTRY logIndexsv(const GLshort *c) { +// unknown type: "const GLshort *" name: "c" + fprintf( tr.logFile, "glIndexsv 'const GLshort * c'\n" ); + dllIndexsv(c); +} + +static void APIENTRY logIndexub(GLubyte c) { + fprintf( tr.logFile, "glIndexub %d\n", c ); + dllIndexub(c); +} + +static void APIENTRY logIndexubv(const GLubyte *c) { +// unknown type: "const GLubyte *" name: "c" + fprintf( tr.logFile, "glIndexubv 'const GLubyte * c'\n" ); + dllIndexubv(c); +} + +static void APIENTRY logInitNames(void) { + fprintf( tr.logFile, "glInitNames\n" ); + dllInitNames(); +} + +static void APIENTRY logInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glInterleavedArrays %s %d 'const GLvoid * pointer'\n", EnumString(format), stride ); + dllInterleavedArrays(format, stride, pointer); +} + +static GLboolean APIENTRY logIsEnabled(GLenum cap) { + fprintf( tr.logFile, "glIsEnabled %s\n", EnumString(cap) ); + return dllIsEnabled(cap); +} + +static GLboolean APIENTRY logIsList(GLuint list) { + fprintf( tr.logFile, "glIsList %d\n", list ); + return dllIsList(list); +} + +static GLboolean APIENTRY logIsTexture(GLuint texture) { + fprintf( tr.logFile, "glIsTexture %d\n", texture ); + return dllIsTexture(texture); +} + +static void APIENTRY logLightModelf(GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glLightModelf %s %g\n", EnumString(pname), param ); + dllLightModelf(pname, param); +} + +static void APIENTRY logLightModelfv(GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glLightModelfv %s 'const GLfloat * params'\n", EnumString(pname) ); + dllLightModelfv(pname, params); +} + +static void APIENTRY logLightModeli(GLenum pname, GLint param) { + fprintf( tr.logFile, "glLightModeli %s %d\n", EnumString(pname), param ); + dllLightModeli(pname, param); +} + +static void APIENTRY logLightModeliv(GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glLightModeliv %s 'const GLint * params'\n", EnumString(pname) ); + dllLightModeliv(pname, params); +} + +static void APIENTRY logLightf(GLenum light, GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glLightf %s %s %g\n", EnumString(light), EnumString(pname), param ); + dllLightf(light, pname, param); +} + +static void APIENTRY logLightfv(GLenum light, GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glLightfv %s %s 'const GLfloat * params'\n", EnumString(light), EnumString(pname) ); + dllLightfv(light, pname, params); +} + +static void APIENTRY logLighti(GLenum light, GLenum pname, GLint param) { + fprintf( tr.logFile, "glLighti %s %s %d\n", EnumString(light), EnumString(pname), param ); + dllLighti(light, pname, param); +} + +static void APIENTRY logLightiv(GLenum light, GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glLightiv %s %s 'const GLint * params'\n", EnumString(light), EnumString(pname) ); + dllLightiv(light, pname, params); +} + +static void APIENTRY logLineStipple(GLint factor, GLushort pattern) { + fprintf( tr.logFile, "glLineStipple %d %d\n", factor, pattern ); + dllLineStipple(factor, pattern); +} + +static void APIENTRY logLineWidth(GLfloat width) { + fprintf( tr.logFile, "glLineWidth %g\n", width ); + dllLineWidth(width); +} + +static void APIENTRY logListBase(GLuint base) { + fprintf( tr.logFile, "glListBase %d\n", base ); + dllListBase(base); +} + +static void APIENTRY logLoadIdentity(void) { + fprintf( tr.logFile, "glLoadIdentity\n" ); + dllLoadIdentity(); +} + +static void APIENTRY logLoadMatrixd(const GLdouble *m) { +// unknown type: "const GLdouble *" name: "m" + fprintf( tr.logFile, "glLoadMatrixd 'const GLdouble * m'\n" ); + dllLoadMatrixd(m); +} + +static void APIENTRY logLoadMatrixf(const GLfloat *m) { +// unknown type: "const GLfloat *" name: "m" + fprintf( tr.logFile, "glLoadMatrixf 'const GLfloat * m'\n" ); + dllLoadMatrixf(m); +} + +static void APIENTRY logLoadName(GLuint name) { + fprintf( tr.logFile, "glLoadName %d\n", name ); + dllLoadName(name); +} + +static void APIENTRY logLogicOp(GLenum opcode) { + fprintf( tr.logFile, "glLogicOp %s\n", EnumString(opcode) ); + dllLogicOp(opcode); +} + +static void APIENTRY logMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) { +// unknown type: "const GLdouble *" name: "points" + fprintf( tr.logFile, "glMap1d %s %g %g %d %d 'const GLdouble * points'\n", EnumString(target), u1, u2, stride, order ); + dllMap1d(target, u1, u2, stride, order, points); +} + +static void APIENTRY logMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) { +// unknown type: "const GLfloat *" name: "points" + fprintf( tr.logFile, "glMap1f %s %g %g %d %d 'const GLfloat * points'\n", EnumString(target), u1, u2, stride, order ); + dllMap1f(target, u1, u2, stride, order, points); +} + +static void APIENTRY logMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) { +// unknown type: "const GLdouble *" name: "points" + fprintf( tr.logFile, "glMap2d %s %g %g %d %d %g %g %d %d 'const GLdouble * points'\n", EnumString(target), u1, u2, ustride, uorder, v1, v2, vstride, vorder ); + dllMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); +} + +static void APIENTRY logMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) { +// unknown type: "const GLfloat *" name: "points" + fprintf( tr.logFile, "glMap2f %s %g %g %d %d %g %g %d %d 'const GLfloat * points'\n", EnumString(target), u1, u2, ustride, uorder, v1, v2, vstride, vorder ); + dllMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); +} + +static void APIENTRY logMapGrid1d(GLint un, GLdouble u1, GLdouble u2) { + fprintf( tr.logFile, "glMapGrid1d %d %g %g\n", un, u1, u2 ); + dllMapGrid1d(un, u1, u2); +} + +static void APIENTRY logMapGrid1f(GLint un, GLfloat u1, GLfloat u2) { + fprintf( tr.logFile, "glMapGrid1f %d %g %g\n", un, u1, u2 ); + dllMapGrid1f(un, u1, u2); +} + +static void APIENTRY logMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) { + fprintf( tr.logFile, "glMapGrid2d %d %g %g %d %g %g\n", un, u1, u2, vn, v1, v2 ); + dllMapGrid2d(un, u1, u2, vn, v1, v2); +} + +static void APIENTRY logMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { + fprintf( tr.logFile, "glMapGrid2f %d %g %g %d %g %g\n", un, u1, u2, vn, v1, v2 ); + dllMapGrid2f(un, u1, u2, vn, v1, v2); +} + +static void APIENTRY logMaterialf(GLenum face, GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glMaterialf %s %s %g\n", EnumString(face), EnumString(pname), param ); + dllMaterialf(face, pname, param); +} + +static void APIENTRY logMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glMaterialfv %s %s 'const GLfloat * params'\n", EnumString(face), EnumString(pname) ); + dllMaterialfv(face, pname, params); +} + +static void APIENTRY logMateriali(GLenum face, GLenum pname, GLint param) { + fprintf( tr.logFile, "glMateriali %s %s %d\n", EnumString(face), EnumString(pname), param ); + dllMateriali(face, pname, param); +} + +static void APIENTRY logMaterialiv(GLenum face, GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glMaterialiv %s %s 'const GLint * params'\n", EnumString(face), EnumString(pname) ); + dllMaterialiv(face, pname, params); +} + +static void APIENTRY logMatrixMode(GLenum mode) { + fprintf( tr.logFile, "glMatrixMode %s\n", EnumString(mode) ); + dllMatrixMode(mode); +} + +static void APIENTRY logMultMatrixd(const GLdouble *m) { +// unknown type: "const GLdouble *" name: "m" + fprintf( tr.logFile, "glMultMatrixd 'const GLdouble * m'\n" ); + dllMultMatrixd(m); +} + +static void APIENTRY logMultMatrixf(const GLfloat *m) { +// unknown type: "const GLfloat *" name: "m" + fprintf( tr.logFile, "glMultMatrixf 'const GLfloat * m'\n" ); + dllMultMatrixf(m); +} + +static void APIENTRY logNewList(GLuint list, GLenum mode) { + fprintf( tr.logFile, "glNewList %d %s\n", list, EnumString(mode) ); + dllNewList(list, mode); +} + +static void APIENTRY logNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) { + fprintf( tr.logFile, "glNormal3b %d %d %d\n", nx, ny, nz ); + dllNormal3b(nx, ny, nz); +} + +static void APIENTRY logNormal3bv(const GLbyte *v) { +// unknown type: "const GLbyte *" name: "v" + fprintf( tr.logFile, "glNormal3bv 'const GLbyte * v'\n" ); + dllNormal3bv(v); +} + +static void APIENTRY logNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) { + fprintf( tr.logFile, "glNormal3d %g %g %g\n", nx, ny, nz ); + dllNormal3d(nx, ny, nz); +} + +static void APIENTRY logNormal3dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glNormal3dv 'const GLdouble * v'\n" ); + dllNormal3dv(v); +} + +static void APIENTRY logNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { + fprintf( tr.logFile, "glNormal3f %g %g %g\n", nx, ny, nz ); + dllNormal3f(nx, ny, nz); +} + +static void APIENTRY logNormal3fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glNormal3fv 'const GLfloat * v'\n" ); + dllNormal3fv(v); +} + +static void APIENTRY logNormal3i(GLint nx, GLint ny, GLint nz) { + fprintf( tr.logFile, "glNormal3i %d %d %d\n", nx, ny, nz ); + dllNormal3i(nx, ny, nz); +} + +static void APIENTRY logNormal3iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glNormal3iv 'const GLint * v'\n" ); + dllNormal3iv(v); +} + +static void APIENTRY logNormal3s(GLshort nx, GLshort ny, GLshort nz) { + fprintf( tr.logFile, "glNormal3s %d %d %d\n", nx, ny, nz ); + dllNormal3s(nx, ny, nz); +} + +static void APIENTRY logNormal3sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glNormal3sv 'const GLshort * v'\n" ); + dllNormal3sv(v); +} + +static void APIENTRY logNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glNormalPointer %s %d 'const GLvoid * pointer'\n", EnumString(type), stride ); + dllNormalPointer(type, stride, pointer); +} + +static void APIENTRY logOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { + fprintf( tr.logFile, "glOrtho %g %g %g %g %g %g\n", left, right, bottom, top, zNear, zFar ); + dllOrtho(left, right, bottom, top, zNear, zFar); +} + +static void APIENTRY logPassThrough(GLfloat token) { + fprintf( tr.logFile, "glPassThrough %g\n", token ); + dllPassThrough(token); +} + +static void APIENTRY logPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values) { +// unknown type: "const GLfloat *" name: "values" + fprintf( tr.logFile, "glPixelMapfv %s %d 'const GLfloat * values'\n", EnumString(map), mapsize ); + dllPixelMapfv(map, mapsize, values); +} + +static void APIENTRY logPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values) { +// unknown type: "const GLuint *" name: "values" + fprintf( tr.logFile, "glPixelMapuiv %s %d 'const GLuint * values'\n", EnumString(map), mapsize ); + dllPixelMapuiv(map, mapsize, values); +} + +static void APIENTRY logPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values) { +// unknown type: "const GLushort *" name: "values" + fprintf( tr.logFile, "glPixelMapusv %s %d 'const GLushort * values'\n", EnumString(map), mapsize ); + dllPixelMapusv(map, mapsize, values); +} + +static void APIENTRY logPixelStoref(GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glPixelStoref %s %g\n", EnumString(pname), param ); + dllPixelStoref(pname, param); +} + +static void APIENTRY logPixelStorei(GLenum pname, GLint param) { + fprintf( tr.logFile, "glPixelStorei %s %d\n", EnumString(pname), param ); + dllPixelStorei(pname, param); +} + +static void APIENTRY logPixelTransferf(GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glPixelTransferf %s %g\n", EnumString(pname), param ); + dllPixelTransferf(pname, param); +} + +static void APIENTRY logPixelTransferi(GLenum pname, GLint param) { + fprintf( tr.logFile, "glPixelTransferi %s %d\n", EnumString(pname), param ); + dllPixelTransferi(pname, param); +} + +static void APIENTRY logPixelZoom(GLfloat xfactor, GLfloat yfactor) { + fprintf( tr.logFile, "glPixelZoom %g %g\n", xfactor, yfactor ); + dllPixelZoom(xfactor, yfactor); +} + +static void APIENTRY logPointSize(GLfloat size) { + fprintf( tr.logFile, "glPointSize %g\n", size ); + dllPointSize(size); +} + +static void APIENTRY logPolygonMode(GLenum face, GLenum mode) { + fprintf( tr.logFile, "glPolygonMode %s %s\n", EnumString(face), EnumString(mode) ); + dllPolygonMode(face, mode); +} + +static void APIENTRY logPolygonOffset(GLfloat factor, GLfloat units) { + fprintf( tr.logFile, "glPolygonOffset %g %g\n", factor, units ); + dllPolygonOffset(factor, units); +} + +static void APIENTRY logPolygonStipple(const GLubyte *mask) { +// unknown type: "const GLubyte *" name: "mask" + fprintf( tr.logFile, "glPolygonStipple 'const GLubyte * mask'\n" ); + dllPolygonStipple(mask); +} + +static void APIENTRY logPopAttrib(void) { + fprintf( tr.logFile, "glPopAttrib\n" ); + dllPopAttrib(); +} + +static void APIENTRY logPopClientAttrib(void) { + fprintf( tr.logFile, "glPopClientAttrib\n" ); + dllPopClientAttrib(); +} + +static void APIENTRY logPopMatrix(void) { + fprintf( tr.logFile, "glPopMatrix\n" ); + dllPopMatrix(); +} + +static void APIENTRY logPopName(void) { + fprintf( tr.logFile, "glPopName\n" ); + dllPopName(); +} + +static void APIENTRY logPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities) { +// unknown type: "const GLuint *" name: "textures" +// unknown type: "const GLclampf *" name: "priorities" + fprintf( tr.logFile, "glPrioritizeTextures %d 'const GLuint * textures' 'const GLclampf * priorities'\n", n ); + dllPrioritizeTextures(n, textures, priorities); +} + +static void APIENTRY logPushAttrib(GLbitfield mask) { +// unknown type: "GLbitfield" name: "mask" + fprintf( tr.logFile, "glPushAttrib 'GLbitfield mask'\n" ); + dllPushAttrib(mask); +} + +static void APIENTRY logPushClientAttrib(GLbitfield mask) { +// unknown type: "GLbitfield" name: "mask" + fprintf( tr.logFile, "glPushClientAttrib 'GLbitfield mask'\n" ); + dllPushClientAttrib(mask); +} + +static void APIENTRY logPushMatrix(void) { + fprintf( tr.logFile, "glPushMatrix\n" ); + dllPushMatrix(); +} + +static void APIENTRY logPushName(GLuint name) { + fprintf( tr.logFile, "glPushName %d\n", name ); + dllPushName(name); +} + +static void APIENTRY logRasterPos2d(GLdouble x, GLdouble y) { + fprintf( tr.logFile, "glRasterPos2d %g %g\n", x, y ); + dllRasterPos2d(x, y); +} + +static void APIENTRY logRasterPos2dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glRasterPos2dv 'const GLdouble * v'\n" ); + dllRasterPos2dv(v); +} + +static void APIENTRY logRasterPos2f(GLfloat x, GLfloat y) { + fprintf( tr.logFile, "glRasterPos2f %g %g\n", x, y ); + dllRasterPos2f(x, y); +} + +static void APIENTRY logRasterPos2fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glRasterPos2fv 'const GLfloat * v'\n" ); + dllRasterPos2fv(v); +} + +static void APIENTRY logRasterPos2i(GLint x, GLint y) { + fprintf( tr.logFile, "glRasterPos2i %d %d\n", x, y ); + dllRasterPos2i(x, y); +} + +static void APIENTRY logRasterPos2iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glRasterPos2iv 'const GLint * v'\n" ); + dllRasterPos2iv(v); +} + +static void APIENTRY logRasterPos2s(GLshort x, GLshort y) { + fprintf( tr.logFile, "glRasterPos2s %d %d\n", x, y ); + dllRasterPos2s(x, y); +} + +static void APIENTRY logRasterPos2sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glRasterPos2sv 'const GLshort * v'\n" ); + dllRasterPos2sv(v); +} + +static void APIENTRY logRasterPos3d(GLdouble x, GLdouble y, GLdouble z) { + fprintf( tr.logFile, "glRasterPos3d %g %g %g\n", x, y, z ); + dllRasterPos3d(x, y, z); +} + +static void APIENTRY logRasterPos3dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glRasterPos3dv 'const GLdouble * v'\n" ); + dllRasterPos3dv(v); +} + +static void APIENTRY logRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { + fprintf( tr.logFile, "glRasterPos3f %g %g %g\n", x, y, z ); + dllRasterPos3f(x, y, z); +} + +static void APIENTRY logRasterPos3fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glRasterPos3fv 'const GLfloat * v'\n" ); + dllRasterPos3fv(v); +} + +static void APIENTRY logRasterPos3i(GLint x, GLint y, GLint z) { + fprintf( tr.logFile, "glRasterPos3i %d %d %d\n", x, y, z ); + dllRasterPos3i(x, y, z); +} + +static void APIENTRY logRasterPos3iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glRasterPos3iv 'const GLint * v'\n" ); + dllRasterPos3iv(v); +} + +static void APIENTRY logRasterPos3s(GLshort x, GLshort y, GLshort z) { + fprintf( tr.logFile, "glRasterPos3s %d %d %d\n", x, y, z ); + dllRasterPos3s(x, y, z); +} + +static void APIENTRY logRasterPos3sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glRasterPos3sv 'const GLshort * v'\n" ); + dllRasterPos3sv(v); +} + +static void APIENTRY logRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { + fprintf( tr.logFile, "glRasterPos4d %g %g %g %g\n", x, y, z, w ); + dllRasterPos4d(x, y, z, w); +} + +static void APIENTRY logRasterPos4dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glRasterPos4dv 'const GLdouble * v'\n" ); + dllRasterPos4dv(v); +} + +static void APIENTRY logRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + fprintf( tr.logFile, "glRasterPos4f %g %g %g %g\n", x, y, z, w ); + dllRasterPos4f(x, y, z, w); +} + +static void APIENTRY logRasterPos4fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glRasterPos4fv 'const GLfloat * v'\n" ); + dllRasterPos4fv(v); +} + +static void APIENTRY logRasterPos4i(GLint x, GLint y, GLint z, GLint w) { + fprintf( tr.logFile, "glRasterPos4i %d %d %d %d\n", x, y, z, w ); + dllRasterPos4i(x, y, z, w); +} + +static void APIENTRY logRasterPos4iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glRasterPos4iv 'const GLint * v'\n" ); + dllRasterPos4iv(v); +} + +static void APIENTRY logRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) { + fprintf( tr.logFile, "glRasterPos4s %d %d %d %d\n", x, y, z, w ); + dllRasterPos4s(x, y, z, w); +} + +static void APIENTRY logRasterPos4sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glRasterPos4sv 'const GLshort * v'\n" ); + dllRasterPos4sv(v); +} + +static void APIENTRY logReadBuffer(GLenum mode) { + fprintf( tr.logFile, "glReadBuffer %s\n", EnumString(mode) ); + dllReadBuffer(mode); +} + +static void APIENTRY logReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { +// unknown type: "GLvoid *" name: "pixels" + fprintf( tr.logFile, "glReadPixels %d %d %d %d %s %s 'GLvoid * pixels'\n", x, y, width, height, EnumString(format), EnumString(type) ); + dllReadPixels(x, y, width, height, format, type, pixels); +} + +static void APIENTRY logRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { + fprintf( tr.logFile, "glRectd %g %g %g %g\n", x1, y1, x2, y2 ); + dllRectd(x1, y1, x2, y2); +} + +static void APIENTRY logRectdv(const GLdouble *v1, const GLdouble *v2) { +// unknown type: "const GLdouble *" name: "v1" +// unknown type: "const GLdouble *" name: "v2" + fprintf( tr.logFile, "glRectdv 'const GLdouble * v1' 'const GLdouble * v2'\n" ); + dllRectdv(v1, v2); +} + +static void APIENTRY logRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { + fprintf( tr.logFile, "glRectf %g %g %g %g\n", x1, y1, x2, y2 ); + dllRectf(x1, y1, x2, y2); +} + +static void APIENTRY logRectfv(const GLfloat *v1, const GLfloat *v2) { +// unknown type: "const GLfloat *" name: "v1" +// unknown type: "const GLfloat *" name: "v2" + fprintf( tr.logFile, "glRectfv 'const GLfloat * v1' 'const GLfloat * v2'\n" ); + dllRectfv(v1, v2); +} + +static void APIENTRY logRecti(GLint x1, GLint y1, GLint x2, GLint y2) { + fprintf( tr.logFile, "glRecti %d %d %d %d\n", x1, y1, x2, y2 ); + dllRecti(x1, y1, x2, y2); +} + +static void APIENTRY logRectiv(const GLint *v1, const GLint *v2) { +// unknown type: "const GLint *" name: "v1" +// unknown type: "const GLint *" name: "v2" + fprintf( tr.logFile, "glRectiv 'const GLint * v1' 'const GLint * v2'\n" ); + dllRectiv(v1, v2); +} + +static void APIENTRY logRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) { + fprintf( tr.logFile, "glRects %d %d %d %d\n", x1, y1, x2, y2 ); + dllRects(x1, y1, x2, y2); +} + +static void APIENTRY logRectsv(const GLshort *v1, const GLshort *v2) { +// unknown type: "const GLshort *" name: "v1" +// unknown type: "const GLshort *" name: "v2" + fprintf( tr.logFile, "glRectsv 'const GLshort * v1' 'const GLshort * v2'\n" ); + dllRectsv(v1, v2); +} + +static GLint APIENTRY logRenderMode(GLenum mode) { + fprintf( tr.logFile, "glRenderMode %s\n", EnumString(mode) ); + return dllRenderMode(mode); +} + +static void APIENTRY logRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { + fprintf( tr.logFile, "glRotated %g %g %g %g\n", angle, x, y, z ); + dllRotated(angle, x, y, z); +} + +static void APIENTRY logRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + fprintf( tr.logFile, "glRotatef %g %g %g %g\n", angle, x, y, z ); + dllRotatef(angle, x, y, z); +} + +static void APIENTRY logScaled(GLdouble x, GLdouble y, GLdouble z) { + fprintf( tr.logFile, "glScaled %g %g %g\n", x, y, z ); + dllScaled(x, y, z); +} + +static void APIENTRY logScalef(GLfloat x, GLfloat y, GLfloat z) { + fprintf( tr.logFile, "glScalef %g %g %g\n", x, y, z ); + dllScalef(x, y, z); +} + +static void APIENTRY logScissor(GLint x, GLint y, GLsizei width, GLsizei height) { + fprintf( tr.logFile, "glScissor %d %d %d %d\n", x, y, width, height ); + dllScissor(x, y, width, height); +} + +static void APIENTRY logSelectBuffer(GLsizei size, GLuint *buffer) { +// unknown type: "GLuint *" name: "buffer" + fprintf( tr.logFile, "glSelectBuffer %d 'GLuint * buffer'\n", size ); + dllSelectBuffer(size, buffer); +} + +static void APIENTRY logShadeModel(GLenum mode) { + fprintf( tr.logFile, "glShadeModel %s\n", EnumString(mode) ); + dllShadeModel(mode); +} + +static void APIENTRY logStencilFunc(GLenum func, GLint ref, GLuint mask) { + fprintf( tr.logFile, "glStencilFunc %s %d %d\n", EnumString(func), ref, mask ); + dllStencilFunc(func, ref, mask); +} + +static void APIENTRY logStencilMask(GLuint mask) { + fprintf( tr.logFile, "glStencilMask %d\n", mask ); + dllStencilMask(mask); +} + +static void APIENTRY logStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { + fprintf( tr.logFile, "glStencilOp %s %s %s\n", EnumString(fail), EnumString(zfail), EnumString(zpass) ); + dllStencilOp(fail, zfail, zpass); +} + +static void APIENTRY logTexCoord1d(GLdouble s) { + fprintf( tr.logFile, "glTexCoord1d %g\n", s ); + dllTexCoord1d(s); +} + +static void APIENTRY logTexCoord1dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glTexCoord1dv 'const GLdouble * v'\n" ); + dllTexCoord1dv(v); +} + +static void APIENTRY logTexCoord1f(GLfloat s) { + fprintf( tr.logFile, "glTexCoord1f %g\n", s ); + dllTexCoord1f(s); +} + +static void APIENTRY logTexCoord1fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glTexCoord1fv 'const GLfloat * v'\n" ); + dllTexCoord1fv(v); +} + +static void APIENTRY logTexCoord1i(GLint s) { + fprintf( tr.logFile, "glTexCoord1i %d\n", s ); + dllTexCoord1i(s); +} + +static void APIENTRY logTexCoord1iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glTexCoord1iv 'const GLint * v'\n" ); + dllTexCoord1iv(v); +} + +static void APIENTRY logTexCoord1s(GLshort s) { + fprintf( tr.logFile, "glTexCoord1s %d\n", s ); + dllTexCoord1s(s); +} + +static void APIENTRY logTexCoord1sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glTexCoord1sv 'const GLshort * v'\n" ); + dllTexCoord1sv(v); +} + +static void APIENTRY logTexCoord2d(GLdouble s, GLdouble t) { + fprintf( tr.logFile, "glTexCoord2d %g %g\n", s, t ); + dllTexCoord2d(s, t); +} + +static void APIENTRY logTexCoord2dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glTexCoord2dv 'const GLdouble * v'\n" ); + dllTexCoord2dv(v); +} + +static void APIENTRY logTexCoord2f(GLfloat s, GLfloat t) { + fprintf( tr.logFile, "glTexCoord2f %g %g\n", s, t ); + dllTexCoord2f(s, t); +} + +static void APIENTRY logTexCoord2fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glTexCoord2fv 'const GLfloat * v'\n" ); + dllTexCoord2fv(v); +} + +static void APIENTRY logTexCoord2i(GLint s, GLint t) { + fprintf( tr.logFile, "glTexCoord2i %d %d\n", s, t ); + dllTexCoord2i(s, t); +} + +static void APIENTRY logTexCoord2iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glTexCoord2iv 'const GLint * v'\n" ); + dllTexCoord2iv(v); +} + +static void APIENTRY logTexCoord2s(GLshort s, GLshort t) { + fprintf( tr.logFile, "glTexCoord2s %d %d\n", s, t ); + dllTexCoord2s(s, t); +} + +static void APIENTRY logTexCoord2sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glTexCoord2sv 'const GLshort * v'\n" ); + dllTexCoord2sv(v); +} + +static void APIENTRY logTexCoord3d(GLdouble s, GLdouble t, GLdouble r) { + fprintf( tr.logFile, "glTexCoord3d %g %g %g\n", s, t, r ); + dllTexCoord3d(s, t, r); +} + +static void APIENTRY logTexCoord3dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glTexCoord3dv 'const GLdouble * v'\n" ); + dllTexCoord3dv(v); +} + +static void APIENTRY logTexCoord3f(GLfloat s, GLfloat t, GLfloat r) { + fprintf( tr.logFile, "glTexCoord3f %g %g %g\n", s, t, r ); + dllTexCoord3f(s, t, r); +} + +static void APIENTRY logTexCoord3fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glTexCoord3fv 'const GLfloat * v'\n" ); + dllTexCoord3fv(v); +} + +static void APIENTRY logTexCoord3i(GLint s, GLint t, GLint r) { + fprintf( tr.logFile, "glTexCoord3i %d %d %d\n", s, t, r ); + dllTexCoord3i(s, t, r); +} + +static void APIENTRY logTexCoord3iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glTexCoord3iv 'const GLint * v'\n" ); + dllTexCoord3iv(v); +} + +static void APIENTRY logTexCoord3s(GLshort s, GLshort t, GLshort r) { + fprintf( tr.logFile, "glTexCoord3s %d %d %d\n", s, t, r ); + dllTexCoord3s(s, t, r); +} + +static void APIENTRY logTexCoord3sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glTexCoord3sv 'const GLshort * v'\n" ); + dllTexCoord3sv(v); +} + +static void APIENTRY logTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { + fprintf( tr.logFile, "glTexCoord4d %g %g %g %g\n", s, t, r, q ); + dllTexCoord4d(s, t, r, q); +} + +static void APIENTRY logTexCoord4dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glTexCoord4dv 'const GLdouble * v'\n" ); + dllTexCoord4dv(v); +} + +static void APIENTRY logTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + fprintf( tr.logFile, "glTexCoord4f %g %g %g %g\n", s, t, r, q ); + dllTexCoord4f(s, t, r, q); +} + +static void APIENTRY logTexCoord4fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glTexCoord4fv 'const GLfloat * v'\n" ); + dllTexCoord4fv(v); +} + +static void APIENTRY logTexCoord4i(GLint s, GLint t, GLint r, GLint q) { + fprintf( tr.logFile, "glTexCoord4i %d %d %d %d\n", s, t, r, q ); + dllTexCoord4i(s, t, r, q); +} + +static void APIENTRY logTexCoord4iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glTexCoord4iv 'const GLint * v'\n" ); + dllTexCoord4iv(v); +} + +static void APIENTRY logTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) { + fprintf( tr.logFile, "glTexCoord4s %d %d %d %d\n", s, t, r, q ); + dllTexCoord4s(s, t, r, q); +} + +static void APIENTRY logTexCoord4sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glTexCoord4sv 'const GLshort * v'\n" ); + dllTexCoord4sv(v); +} + +static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glTexCoordPointer %d %s %d 'const GLvoid * pointer'\n", size, EnumString(type), stride ); + dllTexCoordPointer(size, type, stride, pointer); +} + +static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glTexEnvf %s %s %g\n", EnumString(target), EnumString(pname), param ); + dllTexEnvf(target, pname, param); +} + +static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glTexEnvfv %s %s 'const GLfloat * params'\n", EnumString(target), EnumString(pname) ); + dllTexEnvfv(target, pname, params); +} + +static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param) { + fprintf( tr.logFile, "glTexEnvi %s %s %d\n", EnumString(target), EnumString(pname), param ); + dllTexEnvi(target, pname, param); +} + +static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glTexEnviv %s %s 'const GLint * params'\n", EnumString(target), EnumString(pname) ); + dllTexEnviv(target, pname, params); +} + +static void APIENTRY logTexGend(GLenum coord, GLenum pname, GLdouble param) { + fprintf( tr.logFile, "glTexGend %s %s %g\n", EnumString(coord), EnumString(pname), param ); + dllTexGend(coord, pname, param); +} + +static void APIENTRY logTexGendv(GLenum coord, GLenum pname, const GLdouble *params) { +// unknown type: "const GLdouble *" name: "params" + fprintf( tr.logFile, "glTexGendv %s %s 'const GLdouble * params'\n", EnumString(coord), EnumString(pname) ); + dllTexGendv(coord, pname, params); +} + +static void APIENTRY logTexGenf(GLenum coord, GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glTexGenf %s %s %g\n", EnumString(coord), EnumString(pname), param ); + dllTexGenf(coord, pname, param); +} + +static void APIENTRY logTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glTexGenfv %s %s 'const GLfloat * params'\n", EnumString(coord), EnumString(pname) ); + dllTexGenfv(coord, pname, params); +} + +static void APIENTRY logTexGeni(GLenum coord, GLenum pname, GLint param) { + fprintf( tr.logFile, "glTexGeni %s %s %d\n", EnumString(coord), EnumString(pname), param ); + dllTexGeni(coord, pname, param); +} + +static void APIENTRY logTexGeniv(GLenum coord, GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glTexGeniv %s %s 'const GLint * params'\n", EnumString(coord), EnumString(pname) ); + dllTexGeniv(coord, pname, params); +} + +static void APIENTRY logTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { +// unknown type: "const GLvoid *" name: "pixels" + fprintf( tr.logFile, "glTexImage1D %s %d %d %d %d %s %s 'const GLvoid * pixels'\n", EnumString(target), level, internalformat, width, border, EnumString(format), EnumString(type) ); + dllTexImage1D(target, level, internalformat, width, border, format, type, pixels); +} + +static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { +// unknown type: "const GLvoid *" name: "pixels" + fprintf( tr.logFile, "glTexImage2D %s %d %d %d %d %d %s %s 'const GLvoid * pixels'\n", EnumString(target), level, internalformat, width, height, border, EnumString(format), EnumString(type) ); + dllTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param) { + fprintf( tr.logFile, "glTexParameterf %s %s %g\n", EnumString(target), EnumString(pname), param ); + dllTexParameterf(target, pname, param); +} + +static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { +// unknown type: "const GLfloat *" name: "params" + fprintf( tr.logFile, "glTexParameterfv %s %s 'const GLfloat * params'\n", EnumString(target), EnumString(pname) ); + dllTexParameterfv(target, pname, params); +} + +static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param) { + fprintf( tr.logFile, "glTexParameteri %s %s %d\n", EnumString(target), EnumString(pname), param ); + dllTexParameteri(target, pname, param); +} + +static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params) { +// unknown type: "const GLint *" name: "params" + fprintf( tr.logFile, "glTexParameteriv %s %s 'const GLint * params'\n", EnumString(target), EnumString(pname) ); + dllTexParameteriv(target, pname, params); +} + +static void APIENTRY logTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { +// unknown type: "const GLvoid *" name: "pixels" + fprintf( tr.logFile, "glTexSubImage1D %s %d %d %d %s %s 'const GLvoid * pixels'\n", EnumString(target), level, xoffset, width, EnumString(format), EnumString(type) ); + dllTexSubImage1D(target, level, xoffset, width, format, type, pixels); +} + +static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { +// unknown type: "const GLvoid *" name: "pixels" + fprintf( tr.logFile, "glTexSubImage2D %s %d %d %d %d %d %s %s 'const GLvoid * pixels'\n", EnumString(target), level, xoffset, yoffset, width, height, EnumString(format), EnumString(type) ); + dllTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +static void APIENTRY logTranslated(GLdouble x, GLdouble y, GLdouble z) { + fprintf( tr.logFile, "glTranslated %g %g %g\n", x, y, z ); + dllTranslated(x, y, z); +} + +static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z) { + fprintf( tr.logFile, "glTranslatef %g %g %g\n", x, y, z ); + dllTranslatef(x, y, z); +} + +static void APIENTRY logVertex2d(GLdouble x, GLdouble y) { + fprintf( tr.logFile, "glVertex2d %g %g\n", x, y ); + dllVertex2d(x, y); +} + +static void APIENTRY logVertex2dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glVertex2dv 'const GLdouble * v'\n" ); + dllVertex2dv(v); +} + +static void APIENTRY logVertex2f(GLfloat x, GLfloat y) { + fprintf( tr.logFile, "glVertex2f %g %g\n", x, y ); + dllVertex2f(x, y); +} + +static void APIENTRY logVertex2fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glVertex2fv 'const GLfloat * v'\n" ); + dllVertex2fv(v); +} + +static void APIENTRY logVertex2i(GLint x, GLint y) { + fprintf( tr.logFile, "glVertex2i %d %d\n", x, y ); + dllVertex2i(x, y); +} + +static void APIENTRY logVertex2iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glVertex2iv 'const GLint * v'\n" ); + dllVertex2iv(v); +} + +static void APIENTRY logVertex2s(GLshort x, GLshort y) { + fprintf( tr.logFile, "glVertex2s %d %d\n", x, y ); + dllVertex2s(x, y); +} + +static void APIENTRY logVertex2sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glVertex2sv 'const GLshort * v'\n" ); + dllVertex2sv(v); +} + +static void APIENTRY logVertex3d(GLdouble x, GLdouble y, GLdouble z) { + fprintf( tr.logFile, "glVertex3d %g %g %g\n", x, y, z ); + dllVertex3d(x, y, z); +} + +static void APIENTRY logVertex3dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glVertex3dv 'const GLdouble * v'\n" ); + dllVertex3dv(v); +} + +static void APIENTRY logVertex3f(GLfloat x, GLfloat y, GLfloat z) { + fprintf( tr.logFile, "glVertex3f %g %g %g\n", x, y, z ); + dllVertex3f(x, y, z); +} + +static void APIENTRY logVertex3fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glVertex3fv 'const GLfloat * v'\n" ); + dllVertex3fv(v); +} + +static void APIENTRY logVertex3i(GLint x, GLint y, GLint z) { + fprintf( tr.logFile, "glVertex3i %d %d %d\n", x, y, z ); + dllVertex3i(x, y, z); +} + +static void APIENTRY logVertex3iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glVertex3iv 'const GLint * v'\n" ); + dllVertex3iv(v); +} + +static void APIENTRY logVertex3s(GLshort x, GLshort y, GLshort z) { + fprintf( tr.logFile, "glVertex3s %d %d %d\n", x, y, z ); + dllVertex3s(x, y, z); +} + +static void APIENTRY logVertex3sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glVertex3sv 'const GLshort * v'\n" ); + dllVertex3sv(v); +} + +static void APIENTRY logVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { + fprintf( tr.logFile, "glVertex4d %g %g %g %g\n", x, y, z, w ); + dllVertex4d(x, y, z, w); +} + +static void APIENTRY logVertex4dv(const GLdouble *v) { +// unknown type: "const GLdouble *" name: "v" + fprintf( tr.logFile, "glVertex4dv 'const GLdouble * v'\n" ); + dllVertex4dv(v); +} + +static void APIENTRY logVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + fprintf( tr.logFile, "glVertex4f %g %g %g %g\n", x, y, z, w ); + dllVertex4f(x, y, z, w); +} + +static void APIENTRY logVertex4fv(const GLfloat *v) { +// unknown type: "const GLfloat *" name: "v" + fprintf( tr.logFile, "glVertex4fv 'const GLfloat * v'\n" ); + dllVertex4fv(v); +} + +static void APIENTRY logVertex4i(GLint x, GLint y, GLint z, GLint w) { + fprintf( tr.logFile, "glVertex4i %d %d %d %d\n", x, y, z, w ); + dllVertex4i(x, y, z, w); +} + +static void APIENTRY logVertex4iv(const GLint *v) { +// unknown type: "const GLint *" name: "v" + fprintf( tr.logFile, "glVertex4iv 'const GLint * v'\n" ); + dllVertex4iv(v); +} + +static void APIENTRY logVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { + fprintf( tr.logFile, "glVertex4s %d %d %d %d\n", x, y, z, w ); + dllVertex4s(x, y, z, w); +} + +static void APIENTRY logVertex4sv(const GLshort *v) { +// unknown type: "const GLshort *" name: "v" + fprintf( tr.logFile, "glVertex4sv 'const GLshort * v'\n" ); + dllVertex4sv(v); +} + +static void APIENTRY logVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { +// unknown type: "const GLvoid *" name: "pointer" + fprintf( tr.logFile, "glVertexPointer %d %s %d 'const GLvoid * pointer'\n", size, EnumString(type), stride ); + dllVertexPointer(size, type, stride, pointer); +} + +static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + fprintf( tr.logFile, "glViewport %d %d %d %d\n", x, y, width, height ); + dllViewport(x, y, width, height); +} + + +#ifdef __linux__ + +static XVisualInfo * APIENTRY logChooseVisual(Display *dpy, int screen, int *attribList) { +// unknown type: "Display *" name: "dpy" +// unknown type: "int" name: "screen" +// unknown type: "int *" name: "attribList" + fprintf( tr.logFile, "glXChooseVisual 'Display * dpy' 'int screen' 'int * attribList'\n" ); + return dllChooseVisual(dpy, screen, attribList); +} + +static GLXContext APIENTRY logCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) { +// unknown type: "Display *" name: "dpy" +// unknown type: "XVisualInfo *" name: "vis" +// unknown type: "GLXContext" name: "shareList" +// unknown type: "Bool" name: "direct" + fprintf( tr.logFile, "glXCreateContext 'Display * dpy' 'XVisualInfo * vis' 'GLXContext shareList' 'Bool direct'\n" ); + return dllCreateContext(dpy, vis, shareList, direct); +} + +static void APIENTRY logDestroyContext(Display *dpy, GLXContext ctx) { +// unknown type: "Display *" name: "dpy" +// unknown type: "GLXContext" name: "ctx" + fprintf( tr.logFile, "glXDestroyContext 'Display * dpy' 'GLXContext ctx'\n" ); + dllDestroyContext(dpy, ctx); +} + +static Bool APIENTRY logMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) { +// unknown type: "Display *" name: "dpy" +// unknown type: "GLXDrawable" name: "drawable" +// unknown type: "GLXContext" name: "ctx" + fprintf( tr.logFile, "glXMakeCurrent 'Display * dpy' 'GLXDrawable drawable' 'GLXContext ctx'\n" ); + return dllMakeCurrent(dpy, drawable, ctx); +} + +static void APIENTRY logSwapBuffers(Display *dpy, GLXDrawable drawable) { +// unknown type: "Display *" name: "dpy" +// unknown type: "GLXDrawable" name: "drawable" + fprintf( tr.logFile, "glXSwapBuffers 'Display * dpy' 'GLXDrawable drawable'\n" ); + dllSwapBuffers(dpy, drawable); +} + + +#endif + + +#ifdef WIN32 + + +#endif + diff --git a/sys/win32/rc/AFEditor.rc b/sys/win32/rc/AFEditor.rc new file mode 100644 index 000000000..29d14b786 --- /dev/null +++ b/sys/win32/rc/AFEditor.rc @@ -0,0 +1,893 @@ +// Microsoft Visual C++ generated resource script. +// +#include "afeditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "afeditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_AF_VIEW DIALOGEX 0, 0, 254, 272 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Articulated Figure",IDC_AF_VIEW_AF,6,6,246,96,0, + WS_EX_TRANSPARENT + CONTROL "bodies",IDC_CHECK_VIEW_BODIES,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,24,46,10 + CONTROL "body names",IDC_CHECK_VIEW_BODYNAMES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,36,55,10 + CONTROL "body mass",IDC_CHECK_VIEW_BODYMASS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,48,46,10 + CONTROL "inertia tensor",IDC_CHECK_VIEW_INERTIATENSOR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,72,61,10 + CONTROL "velocity",IDC_CHECK_VIEW_VELOCITY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,84,66,10 + CONTROL "constraints",IDC_CHECK_VIEW_CONSTRAINTS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,24,53,10 + CONTROL "constraint names",IDC_CHECK_VIEW_CONSTRAINTNAMES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,36,71,10 + CONTROL "primary only",IDC_CHECK_VIEW_PRIMARYONLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,48,53,10 + CONTROL "limits",IDC_CHECK_VIEW_LIMITS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,132,60,36,10 + CONTROL "trees",IDC_CHECK_VIEW_TREES,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,132,84,36,10 + GROUPBOX "MD5",IDC_AF_VIEW_MD5,6,108,246,36,0,WS_EX_TRANSPARENT + CONTROL "skeleton",IDC_CHECK_MD5_SKELETON,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,126,43,10 + CONTROL "skeleton only",IDC_CHECK_MD5_SKELETONONLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,126,58,10 + GROUPBOX "Lines",IDC_AF_VIEW_LINES,6,150,246,36,0, + WS_EX_TRANSPARENT + CONTROL "depth test",IDC_CHECK_LINES_DEPTHTEST,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,169,49,10 + CONTROL "use arrows",IDC_CHECK_LINES_USEARROWS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,169,51,10 + GROUPBOX "Physics",IDC_AF_VIEW_PHYSICS,6,193,246,72,0, + WS_EX_TRANSPARENT + CONTROL "no friction",IDC_CHECK_PHYSICS_NOFRICTION,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,210,48,10 + CONTROL "no gravity",IDC_CHECK_PHYSICS_NOGRAVITY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,222,48,10 + CONTROL "no limits",IDC_CHECK_PHYSICS_NOLIMITS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,234,41,10 + CONTROL "drag entities",IDC_CHECK_PHYSICS_DRAG_ENTITIES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,210,56,10 + CONTROL "show drag selection", + IDC_CHECK_PHYSICS_SHOW_DRAG_SELECTION,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,222,79,10 + CONTROL "timings",IDC_CHECK_PHYSICS_TIMING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,132,234,38,10 + CONTROL "no self collision",IDC_CHECK_PHYSICS_NOSELFCOLLISION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,246,66,10 + CONTROL "constrained bodies",IDC_CHECK_VIEW_CONSTRAINEDBODIES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,132,72,78,10 + CONTROL "total mass",IDC_CHECK_VIEW_TOTALMASS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,60,46,10 +END + +IDD_DIALOG_AF_PROPERTIES DIALOGEX 0, 0, 254, 320 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "MD5",IDC_STATIC_MD5,6,6,246,49 + LTEXT "model:",IDC_STATIC_MODEL,18,20,22,8 + EDITTEXT IDC_EDIT_MODEL,42,18,183,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + PUSHBUTTON "...",IDC_BUTTON_BROWSE_MODEL,228,18,18,12 + GROUPBOX "Default Collision Detection", + IDC_STATIC_COLLISIONDETECTION,6,60,246,42 + CONTROL "Self Collision",IDC_CHECK_SELFCOLLISION,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,18,78,72,10 + LTEXT "Contents",IDC_STATIC_CONTENTS,108,72,30,8 + EDITTEXT IDC_EDIT_CONTENTS,150,70,96,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Clip Mask",IDC_STATIC_CLIPMASK,108,85,30,8 + EDITTEXT IDC_EDIT_CLIPMASK,150,86,96,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + GROUPBOX "Default Friction",IDC_STATIC_FRICTION,6,106,246,48 + LTEXT "Linear",IDC_STATIC_LINEARFRICTION,12,118,20,8 + EDITTEXT IDC_EDIT_LINEARFRICTION,36,118,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_LINEARFRICTION,"msctls_updown32", + UDS_ARROWKEYS,66,118,12,12 + LTEXT "Angular",IDC_STATIC_ANGULARFRICTION,90,118,31,8 + EDITTEXT IDC_EDIT_ANGULARFRICTION,120,118,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANGULARFRICTION,"msctls_updown32", + UDS_ARROWKEYS,150,118,12,12 + LTEXT "Contact",IDC_STATIC_CONTACTFRICTION,174,118,31,8 + EDITTEXT IDC_EDIT_CONTACTFRICTION,204,118,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CONTACTFRICTION,"msctls_updown32", + UDS_ARROWKEYS,234,118,12,12 + GROUPBOX "Mass",IDC_STATIC_MASS,6,158,246,30 + LTEXT "Total Mass",IDC_STATIC_TOTALMASS,12,170,35,8 + EDITTEXT IDC_EDIT_TOTALMASS,54,170,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_TOTALMASS,"msctls_updown32",UDS_ARROWKEYS,84, + 170,11,13 + GROUPBOX "Suspend Speed",IDC_STATIC_SUSPENDSPEED,6,193,246,42 + LTEXT "Linear Velocity",IDC_STATIC_LINEARVELOCITY,12,206,47,8 + EDITTEXT IDC_EDIT_LINEARVELOCITY,67,204,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Linear Acceleration",IDC_STATIC_LINEARACCELERATION,126, + 206,62,8 + EDITTEXT IDC_EDIT_LINEARACCELERATION,198,204,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Angular Velocity",IDC_STATIC_ANGULARVELOCITY,12,220,52, + 8 + EDITTEXT IDC_EDIT_ANGULARVELOCITY,67,217,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Angular Acceleration",IDC_STATIC_ANGULARACCELERATION, + 126,220,67,8 + EDITTEXT IDC_EDIT_ANGULARACCELERATION,198,217,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + GROUPBOX "Suspend Movement",IDC_STATIC_SUSPENDMOVEMENT,6,240,246, + 54 + LTEXT "No Move Time",IDC_STATIC_NO_MOVE_TIME,12,253,46,8 + EDITTEXT IDC_EDIT_NO_MOVE_TIME,74,250,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Maximum Move Time",IDC_STATIC_MAXIMUM_MOVE_TIME,129,267, + 66,8 + EDITTEXT IDC_EDIT_MAXIMUM_MOVE_TIME,198,264,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Linear Tolerance",IDC_STATIC_LINEAR_TOLERANCE,12,267,54, + 8 + EDITTEXT IDC_EDIT_LINEAR_TOLERANCE,74,264,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Angular Tolerance",IDC_STATIC_ANGULAR_TOLERANCE,11,282, + 59,8 + EDITTEXT IDC_EDIT_ANGULAR_TOLERANCE,74,278,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Constraint",IDC_STATIC_CONSTRAINT,166,136,34,8 + EDITTEXT IDC_EDIT_CONSTRAINTFRICTION,204,136,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CONSTRAINTFRICTION,"msctls_updown32", + UDS_ARROWKEYS,234,136,11,12 + LTEXT "skin:",IDC_STATIC_SKIN,18,37,16,8 + EDITTEXT IDC_EDIT_SKIN,42,35,183,12,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_WANTRETURN + PUSHBUTTON "...",IDC_BUTTON_BROWSE_SKIN,228,35,18,12 + EDITTEXT IDC_EDIT_MINIMUM_MOVE_TIME,198,250,49,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Minimum Move Time",IDC_STATIC_MINIMUM_MOVE_TIME,129,253, + 64,8 +END + +IDD_DIALOG_AF_NAME DIALOGEX 0, 0, 186, 53 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Name" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,18,30,50,14 + PUSHBUTTON "Cancel",IDCANCEL,114,30,50,14 + EDITTEXT IDC_EDIT_AF_NAME,36,6,138,13,ES_AUTOHSCROLL + LTEXT "Name:",IDC_STATIC_AF_NAME,12,6,22,8 +END + +IDD_DIALOG_AF_CONSTRAINT_UNIVERSAL DIALOGEX 0, 0, 254, 260 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Anchor",IDC_STATIC_ANCHOR,6,0,246,48 + CONTROL "joint",IDC_RADIO_ANCHOR_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,12,30,10 + COMBOBOX IDC_COMBO_ANCHOR_JOINT,78,12,168,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "coordinates",IDC_RADIO_ANCHOR_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,30,53,10 + EDITTEXT IDC_EDIT_ANCHOR_X,78,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_X,"msctls_updown32",UDS_ARROWKEYS,114, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Y,138,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Y,"msctls_updown32",UDS_ARROWKEYS,174, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Z,198,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Z,"msctls_updown32",UDS_ARROWKEYS,234, + 30,11,12 + GROUPBOX "Shaft 1",IDC_STATIC_UNIVERSAL_SHAFT1,6,48,246,48 + CONTROL "bone",IDC_RADIO_UNIVERSAL_BONE_SHAFT1,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,60,32,10 + COMBOBOX IDC_COMBO_UNIVERSAL_JOINT1_SHAFT1,60,60,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_UNIVERSAL_JOINT2_SHAFT1,156,60,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,78,37,10 + EDITTEXT IDC_EDIT_UNIVERSAL_PITCH_SHAFT1,60,78,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_PITCH_SHAFT1,"msctls_updown32", + UDS_ARROWKEYS,138,78,11,12 + EDITTEXT IDC_EDIT_UNIVERSAL_YAW_SHAFT1,156,78,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_YAW_SHAFT1,"msctls_updown32", + UDS_ARROWKEYS,234,78,11,12 + GROUPBOX "Shaft 2",IDC_STATIC_UNIVERSAL_SHAFT2,6,96,246,48 + CONTROL "bone",IDC_RADIO_UNIVERSAL_BONE_SHAFT2,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,108,32,10 + COMBOBOX IDC_COMBO_UNIVERSAL_JOINT1_SHAFT2,60,108,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_UNIVERSAL_JOINT2_SHAFT2,156,108,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,126,37,10 + EDITTEXT IDC_EDIT_UNIVERSAL_PITCH_SHAFT2,60,126,78,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_PITCH_SHAFT2,"msctls_updown32", + UDS_ARROWKEYS,138,126,11,12 + EDITTEXT IDC_EDIT_UNIVERSAL_YAW_SHAFT2,156,126,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_YAW_SHAFT2,"msctls_updown32", + UDS_ARROWKEYS,234,126,11,12 + GROUPBOX "Limit Type",IDC_STATIC_UNIVERSAL_LIMIT_TYPE,6,144,246, + 66 + CONTROL "none",IDC_RADIO_UNIVERSAL_LIMIT_NONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,156,32,10 + CONTROL "cone",IDC_RADIO_UNIVERSAL_LIMIT_CONE,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,174,31,10 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE,60,174,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_CONE_ANGLE,"msctls_updown32", + UDS_ARROWKEYS,102,174,11,12 + CONTROL "pyramid",IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,193,41,10 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1,60,192,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE1, + "msctls_updown32",UDS_ARROWKEYS,102,192,11,12 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2,126,192,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE2, + "msctls_updown32",UDS_ARROWKEYS,168,192,11,12 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_ROLL,192,192,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_ROLL,"msctls_updown32", + UDS_ARROWKEYS,234,192,11,12 + GROUPBOX "Limit Orientation", + IDC_STATIC_UNIVERSAL_LIMIT_ORIENTATION,6,210,246,48 + CONTROL "bone",IDC_RADIO_UNIVERSAL_LIMIT_BONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,222,32,10 + COMBOBOX IDC_COMBO_UNIVERSAL_LIMIT_JOINT1,60,222,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_UNIVERSAL_LIMIT_JOINT2,156,222,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_UNIVERSAL_LIMIT_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,240,37,10 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_PITCH,60,240,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_PITCH,"msctls_updown32", + UDS_ARROWKEYS,138,240,11,12 + EDITTEXT IDC_EDIT_UNIVERSAL_LIMIT_YAW,156,240,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_UNIVERSAL_LIMIT_YAW,"msctls_updown32", + UDS_ARROWKEYS,234,240,11,12 +END + +IDD_DIALOG_AF_CONSTRAINT_SPRING DIALOGEX 0, 0, 254, 201 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Anchor 1",IDC_STATIC_ANCHOR,6,0,246,48 + CONTROL "joint",IDC_RADIO_ANCHOR_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,12,30,10 + COMBOBOX IDC_COMBO_ANCHOR_JOINT,78,12,168,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "coordinates",IDC_RADIO_ANCHOR_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,30,53,10 + EDITTEXT IDC_EDIT_ANCHOR_X,78,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_X,"msctls_updown32",UDS_ARROWKEYS,114, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Y,138,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Y,"msctls_updown32",UDS_ARROWKEYS,174, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Z,198,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Z,"msctls_updown32",UDS_ARROWKEYS,234, + 30,11,12 + GROUPBOX "Anchor 2",IDC_STATIC_ANCHOR2,6,48,246,48 + CONTROL "joint",IDC_RADIO_ANCHOR2_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,61,30,10 + COMBOBOX IDC_COMBO_ANCHOR2_JOINT,78,61,168,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "coordinates",IDC_RADIO_ANCHOR2_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,78,53,10 + EDITTEXT IDC_EDIT_ANCHOR2_X,78,78,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR2_X,"msctls_updown32",UDS_ARROWKEYS, + 114,78,11,12 + EDITTEXT IDC_EDIT_ANCHOR2_Y,138,78,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR2_Y,"msctls_updown32",UDS_ARROWKEYS, + 174,78,11,12 + EDITTEXT IDC_EDIT_ANCHOR2_Z,198,78,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR2_Z,"msctls_updown32",UDS_ARROWKEYS, + 234,78,11,12 + GROUPBOX "Spring settings",IDC_STATIC_SPRING_SETTINGS,6,96,246,48 + LTEXT "stretch",IDC_STATIC_SPRING_STRETCH,46,108,24,8 + EDITTEXT IDC_EDIT_SPRING_STRETCH,78,106,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_STRETCH,"msctls_updown32", + UDS_ARROWKEYS,113,106,11,12 + LTEXT "compress",IDC_STATIC_SPRING_COMPRESS,157,107,30,8 + EDITTEXT IDC_EDIT_SPRING_COMPRESS,198,106,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_COMPRESS,"msctls_updown32", + UDS_ARROWKEYS,234,106,11,12 + LTEXT "damping",IDC_STATIC_SPRING_DAMPING,46,127,26,8 + EDITTEXT IDC_EDIT_SPRING_DAMPING,78,125,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_DAMPING,"msctls_updown32", + UDS_ARROWKEYS,113,125,11,12 + LTEXT "rest length",IDC_STATIC_SPRING_REST_LENGTH,157,127,36,8 + EDITTEXT IDC_EDIT_SPRING_REST_LENGTH,198,125,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_REST_LENGTH,"msctls_updown32", + UDS_ARROWKEYS,234,125,11,12 + GROUPBOX "Limit",IDC_STATIC_SPRING_LIMIT,6,144,246,48 + CONTROL "no min length",IDC_RADIO_SPRING_NO_MIN_LENGTH,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,156,59,10 + CONTROL "min length",IDC_RADIO_SPRING_MIN_LENGTH,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,174,44,10 + EDITTEXT IDC_EDIT_SPRING_MIN_LENGTH,78,174,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_MIN_LENGTH,"msctls_updown32", + UDS_ARROWKEYS,114,174,11,12 + CONTROL "no max length",IDC_RADIO_SPRING_NO_MAX_LENGTH,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,144,156,61,10 + CONTROL "max length",IDC_RADIO_SPRING_MAX_LENGTH,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,144,174,51,10 + EDITTEXT IDC_EDIT_SPRING_MAX_LENGTH,199,174,35,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SPRING_MAX_LENGTH,"msctls_updown32", + UDS_ARROWKEYS,234,174,11,12 +END + +IDD_DIALOG_AF_CONSTRAINT_SLIDER DIALOGEX 0, 0, 254, 146 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Axis",IDC_STATIC_SLIDER_AXIS,6,0,246,48 + CONTROL "bone",IDC_RADIO_SLIDER_AXIS_BONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,12,32,10 + COMBOBOX IDC_COMBO_SLIDER_AXIS_JOINT1,60,13,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_SLIDER_AXIS_JOINT2,156,13,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_SLIDER_AXIS_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,30,37,10 + EDITTEXT IDC_EDIT_SLIDER_AXIS_PITCH,60,30,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SLIDER_AXIS_PITCH,"msctls_updown32", + UDS_ARROWKEYS,138,30,11,12 + EDITTEXT IDC_EDIT_SLIDER_AXIS_YAW,156,30,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_SLIDER_AXIS_YAW,"msctls_updown32", + UDS_ARROWKEYS,234,30,11,12 +END + +IDD_DIALOG_AF_CONSTRAINT_HINGE DIALOGEX 0, 0, 254, 146 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Anchor",IDC_STATIC_ANCHOR,6,0,246,48 + CONTROL "joint",IDC_RADIO_ANCHOR_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,12,30,10 + COMBOBOX IDC_COMBO_ANCHOR_JOINT,78,12,168,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "coordinates",IDC_RADIO_ANCHOR_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,30,53,10 + EDITTEXT IDC_EDIT_ANCHOR_X,78,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_X,"msctls_updown32",UDS_ARROWKEYS,114, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Y,138,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Y,"msctls_updown32",UDS_ARROWKEYS,174, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Z,198,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Z,"msctls_updown32",UDS_ARROWKEYS,234, + 30,11,12 + GROUPBOX "Axis",IDC_STATIC_HINGE_AXIS,6,48,246,48 + CONTROL "bone",IDC_RADIO_HINGE_AXIS_BONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,60,32,10 + COMBOBOX IDC_COMBO_HINGE_AXIS_JOINT1,60,60,90,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_HINGE_AXIS_JOINT2,156,60,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_HINGE_AXIS_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,78,37,10 + EDITTEXT IDC_EDIT_HINGE_AXIS_PITCH,60,78,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_HINGE_AXIS_PITCH,"msctls_updown32", + UDS_ARROWKEYS,138,78,11,12 + EDITTEXT IDC_EDIT_HINGE_AXIS_YAW,156,78,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_HINGE_AXIS_YAW,"msctls_updown32", + UDS_ARROWKEYS,234,78,11,12 + GROUPBOX "Limit",IDC_STATIC_HINGE_LIMIT,6,96,246,48 + CONTROL "none",IDC_RADIO_HINGE_LIMIT_NONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,108,32,10 + CONTROL "angles",IDC_RADIO_HINGE_LIMIT_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,126,37,10 + EDITTEXT IDC_EDIT_HINGE_LIMIT_ANGLE1,60,126,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_HINGE_LIMIT_ANGLE1,"msctls_updown32", + UDS_ARROWKEYS,102,126,11,12 + EDITTEXT IDC_EDIT_HINGE_LIMIT_ANGLE2,126,126,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_HINGE_LIMIT_ANGLE2,"msctls_updown32", + UDS_ARROWKEYS,168,126,11,12 + EDITTEXT IDC_EDIT_HINGE_LIMIT_ANGLE3,192,126,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_HINGE_LIMIT_ANGLE3,"msctls_updown32", + UDS_ARROWKEYS,234,126,11,12 +END + +IDD_DIALOG_AF_CONSTRAINT_FIXED DIALOGEX 0, 0, 254, 56 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN +END + +IDD_DIALOG_AF_CONSTRAINT_BALLANDSOCKET DIALOGEX 0, 0, 254, 212 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Anchor",IDC_STATIC_ANCHOR,6,0,246,48 + CONTROL "joint",IDC_RADIO_ANCHOR_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,12,30,10 + COMBOBOX IDC_COMBO_ANCHOR_JOINT,78,12,168,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "coordinates",IDC_RADIO_ANCHOR_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,30,53,10 + EDITTEXT IDC_EDIT_ANCHOR_X,78,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_X,"msctls_updown32",UDS_ARROWKEYS,114, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Y,138,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Y,"msctls_updown32",UDS_ARROWKEYS,174, + 30,11,12 + EDITTEXT IDC_EDIT_ANCHOR_Z,198,30,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANCHOR_Z,"msctls_updown32",UDS_ARROWKEYS,234, + 30,11,12 + GROUPBOX "Limit Type",IDC_STATIC_BAS_LIMIT_TYPE,6,48,246,66 + CONTROL "none",IDC_RADIO_BAS_LIMIT_NONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,60,32,10 + CONTROL "cone",IDC_RADIO_BAS_LIMIT_CONE,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,78,31,10 + EDITTEXT IDC_EDIT_BAS_LIMIT_CONE_ANGLE,60,78,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_CONE_ANGLE,"msctls_updown32", + UDS_ARROWKEYS,102,78,11,12 + CONTROL "pyramid",IDC_RADIO_BAS_LIMIT_PYRAMID,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,97,41,10 + EDITTEXT IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1,60,96,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE1,"msctls_updown32", + UDS_ARROWKEYS,102,96,11,12 + EDITTEXT IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2,126,96,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE2,"msctls_updown32", + UDS_ARROWKEYS,168,96,11,12 + EDITTEXT IDC_EDIT_BAS_LIMIT_ROLL,192,96,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_ROLL,"msctls_updown32", + UDS_ARROWKEYS,234,96,11,12 + GROUPBOX "Limit Orientation",IDC_STATIC_BAS_LIMIT_ORIENTATION,6, + 114,246,48 + CONTROL "bone",IDC_RADIO_BAS_LIMIT_BONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,126,32,10 + COMBOBOX IDC_COMBO_BAS_LIMIT_JOINT1,60,126,90,60,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_BAS_LIMIT_JOINT2,156,126,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_BAS_LIMIT_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,144,37,10 + EDITTEXT IDC_EDIT_BAS_LIMIT_PITCH,60,144,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_PITCH,"msctls_updown32", + UDS_ARROWKEYS,138,144,11,12 + EDITTEXT IDC_EDIT_BAS_LIMIT_YAW,156,144,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_YAW,"msctls_updown32", + UDS_ARROWKEYS,234,144,11,12 + GROUPBOX "Limit Axis",IDC_STATIC_BAS_LIMIT_AXIS,6,162,246,48 + CONTROL "bone",IDC_RADIO_BAS_LIMIT_AXIS_BONE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,18,174,32,10 + COMBOBOX IDC_COMBO_BAS_LIMIT_AXIS_JOINT1,60,174,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_BAS_LIMIT_AXIS_JOINT2,156,174,90,60, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "angles",IDC_RADIO_BAS_LIMIT_AXIS_ANGLES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,18,192,37,10 + EDITTEXT IDC_EDIT_BAS_LIMIT_AXIS_PITCH,60,192,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_AXIS_PITCH,"msctls_updown32", + UDS_ARROWKEYS,138,192,11,12 + EDITTEXT IDC_EDIT_BAS_LIMIT_AXIS_YAW,156,192,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_BAS_LIMIT_AXIS_YAW,"msctls_updown32", + UDS_ARROWKEYS,234,192,11,12 +END + +IDD_DIALOG_AF_CONSTRAINT DIALOGEX 0, 0, 254, 332 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_COMBO_CONSTRAINTS,6,4,138,114,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "New",IDC_BUTTON_NEWCONSTRAINT,150,4,30,12 + PUSHBUTTON "Rename",IDC_BUTTON_RENAMECONSTRAINT,186,4,30,12 + PUSHBUTTON "Delete",IDC_BUTTON_DELETECONSTRAINT,222,4,30,12 + GROUPBOX "General",IDC_STATIC_CONSTRAINT_GENERAL,6,22,246,48 + LTEXT "type",IDC_STATIC_CONSTRAINT_TYPE,12,34,16,8 + COMBOBOX IDC_COMBO_CONSTRAINT_TYPE,36,34,90,66,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "friction",IDC_STATIC_CONSTRAINT_FRICTION,132,34,23,8 + EDITTEXT IDC_EDIT_CONSTRAINT_FRICTION,156,34,78,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CONSTRAINT_FRICTION,"msctls_updown32", + UDS_ARROWKEYS,234,34,11,12 + LTEXT "body1",IDC_STATIC_BODY1,12,52,21,8 + COMBOBOX IDC_COMBO_CONSTRAINT_BODY1,36,52,90,66,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "body2",IDC_STATIC_BODY2,132,52,21,8 + COMBOBOX IDC_COMBO_CONSTRAINT_BODY2,156,52,90,72,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP +END + +IDD_DIALOG_AF_BODY DIALOGEX 0, 0, 254, 344 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_COMBO_BODIES,6,4,138,114,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "New",IDC_BUTTON_NEWBODY,150,4,30,12 + PUSHBUTTON "Rename",IDC_BUTTON_RENAMEBODY,186,4,30,12 + PUSHBUTTON "Delete",IDC_BUTTON_DELETEBODY,222,4,30,12 + GROUPBOX "Collision Model",IDC_BODY_COLLISIONMODEL,6,22,246,84 + LTEXT "Type",IDC_STATIC_CM_TYPE,12,34,17,8 + COMBOBOX IDC_COMBO_CM_TYPE,42,34,84,66,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_BUTTON_CM_BROWSE,132,34,18,12,WS_DISABLED + EDITTEXT IDC_EDIT_CM_NAME,162,34,84,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_DISABLED + LTEXT "Length",IDC_STATIC_CM_LENGTH,12,52,23,8 + EDITTEXT IDC_EDIT_CM_LENGTH,42,52,72,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CM_LENGTH,"msctls_updown32",UDS_ARROWKEYS, + 114,52,11,12 + LTEXT "Height",IDC_STATIC_CM_HEIGHT,132,52,22,8 + EDITTEXT IDC_EDIT_CM_HEIGHT,162,52,72,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CM_HEIGHT,"msctls_updown32",UDS_ARROWKEYS, + 234,52,11,12 + LTEXT "Width",IDC_STATIC_CM_WIDTH,12,70,20,8 + EDITTEXT IDC_EDIT_CM_WIDTH,42,70,72,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CM_WIDTH,"msctls_updown32",UDS_ARROWKEYS,114, + 70,11,12 + LTEXT "Sides",IDC_STATIC_CM_NUMSIDES,132,70,18,8 + EDITTEXT IDC_EDIT_CM_NUMSIDES,162,70,72,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + ES_NUMBER + CONTROL "",IDC_SPIN_CM_NUMSIDES,"msctls_updown32",UDS_ARROWKEYS, + 234,70,11,12 + LTEXT "Density",IDC_STATIC_CM_DENSITY,12,88,25,8 + EDITTEXT IDC_EDIT_CM_DENSITY,42,88,72,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CM_DENSITY,"msctls_updown32",UDS_ARROWKEYS, + 114,88,11,12 + LTEXT "Inertia Scale",IDC_STATIC_CM_INERTIASCALE,132,82,24,18 + EDITTEXT IDC_EDIT_CM_INERTIASCALE,162,88,84,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + GROUPBOX "Position",IDC_STATIC_BODY_ORIGIN_AND_ANGLES,6,106,246, + 83 + CONTROL "coordinates",IDC_RADIO_ORIGIN_COORDINATES,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,12,118,53,10 + EDITTEXT IDC_EDIT_AF_VECTOR_X,66,118,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_AF_VECTOR_X,"msctls_updown32",UDS_ARROWKEYS, + 102,118,11,12 + EDITTEXT IDC_EDIT_AF_VECTOR_Y,132,118,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_AF_VECTOR_Y,"msctls_updown32",UDS_ARROWKEYS, + 168,118,11,12 + EDITTEXT IDC_EDIT_AF_VECTOR_Z,198,118,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_AF_VECTOR_Z,"msctls_updown32",UDS_ARROWKEYS, + 234,118,11,12 + CONTROL "bone center",IDC_RADIO_ORIGIN_BONECENTER,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,12,136,54,10 + COMBOBOX IDC_COMBO_ORIGIN_BONECENTER_JOINT1,66,136,90,48, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_ORIGIN_BONECENTER_JOINT2,162,136,84,49, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "joint",IDC_RADIO_ORIGIN_JOINT,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,12,154,30,10 + COMBOBOX IDC_COMBO_ORIGIN_JOINT,66,154,180,48,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "pitch",IDC_STATIC_ANGLES_PITCH,42,172,16,8 + EDITTEXT IDC_EDIT_ANGLES_PITCH,66,172,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANGLES_PITCH,"msctls_updown32",UDS_ARROWKEYS, + 102,172,11,12 + LTEXT " yaw",IDC_STATIC_ANGLES_YAW,114,172,16,8 + EDITTEXT IDC_EDIT_ANGLES_YAW,132,172,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANGLES_YAW,"msctls_updown32",UDS_ARROWKEYS, + 168,172,11,12 + LTEXT "roll",IDC_STATIC_ANGLES_ROLL,186,172,10,8 + EDITTEXT IDC_EDIT_ANGLES_ROLL,198,172,36,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANGLES_ROLL,"msctls_updown32",UDS_ARROWKEYS, + 234,172,11,12 + GROUPBOX "Collision Detection",IDC_STATIC_COLLISIONDETECTION,6, + 190,246,42 + CONTROL "Self Collision",IDC_CHECK_SELFCOLLISION,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,18,208,54,10 + LTEXT "Contents",IDC_STATIC_CONTENTS,108,202,30,8 + EDITTEXT IDC_EDIT_CONTENTS,150,200,96,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Clip Mask",IDC_STATIC_CLIPMASK,108,215,30,8 + EDITTEXT IDC_EDIT_CLIPMASK,150,216,96,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + GROUPBOX "Friction",IDC_STATIC_FRICTION,6,232,246,48 + LTEXT "Linear",IDC_STATIC_LINEARFRICTION,12,244,20,8 + EDITTEXT IDC_EDIT_LINEARFRICTION,36,244,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_LINEARFRICTION,"msctls_updown32", + UDS_ARROWKEYS,66,244,12,12 + LTEXT "Angular",IDC_STATIC_ANGULARFRICTION,90,244,24,8 + EDITTEXT IDC_EDIT_ANGULARFRICTION,120,244,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_ANGULARFRICTION,"msctls_updown32", + UDS_ARROWKEYS,150,244,12,12 + LTEXT "Contact",IDC_STATIC_CONTACTFRICTION,174,244,24,8 + EDITTEXT IDC_EDIT_CONTACTFRICTION,204,244,30,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "",IDC_SPIN_CONTACTFRICTION,"msctls_updown32", + UDS_ARROWKEYS,234,244,12,12 + LTEXT "Friction Direction",IDC_STATIC_FRICTIONDIRECTION,12,262, + 54,8 + EDITTEXT IDC_EDIT_FRICTIONDIRECTION,78,262,42,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + LTEXT "Motor Direction",IDC_STATIC_CONTACTMOTORDIRECTION,150, + 262,50,8 + EDITTEXT IDC_EDIT_CONTACTMOTORDIRECTION,204,262,42,12, + ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | + ES_WANTRETURN + GROUPBOX "Joints",IDC_STATIC_JOINTS,6,280,246,62 + LTEXT "Modified Joint",IDC_STATIC_MODIFIEDJOINT,12,293,45,8 + COMBOBOX IDC_COMBO_MODIFIEDJOINT,72,293,174,59,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Contained Joints",IDC_STATIC_CONTAINEDJOINTS,12,325,54, + 8 + EDITTEXT IDC_EDIT_CONTAINEDJOINTS,72,325,174,12,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + COMBOBOX IDC_COMBO_BONE_JOINT1,42,52,84,59,CBS_DROPDOWNLIST | + CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_BONE_JOINT2,162,52,84,59,CBS_DROPDOWNLIST | + CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + LTEXT "Modify",IDC_STATIC_MODIFY,12,310,22,8 + CONTROL "orientation",IDC_RADIO_MODIFY_ORIENTATION,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,72,310,51,10 + CONTROL "position",IDC_RADIO_MODIFY_POSITION,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,134,310,41,10 + CONTROL "both",IDC_RADIO_MODIFY_BOTH,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,195,310,31,10 +END + +IDD_DIALOG_AF DIALOGEX 0, 0, 277, 404 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Articulated Figure Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_COMBO_AF,6,6,180,204,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "New",IDC_BUTTON_AF_NEW,192,6,36,12 + PUSHBUTTON "Delete",IDC_BUTTON_AF_DELETE,234,6,36,12 + CONTROL "",IDC_DIALOG_AF_TAB_MODE,"SysTabControl32",WS_TABSTOP,7, + 23,264,361 + PUSHBUTTON "Spawn",IDC_BUTTON_AF_SPAWN,6,388,42,12 + PUSHBUTTON "T-pose",IDC_BUTTON_AF_TPOSE,54,388,42,12 + PUSHBUTTON "Kill",IDC_BUTTON_AF_KILL,102,388,42,12 + PUSHBUTTON "Save",IDC_BUTTON_AF_SAVE,180,388,42,12 + PUSHBUTTON "Cancel",IDCANCEL,228,388,42,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_AF_VIEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 247 + TOPMARGIN, 7 + BOTTOMMARGIN, 265 + END + + IDD_DIALOG_AF_PROPERTIES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 247 + TOPMARGIN, 7 + BOTTOMMARGIN, 313 + END + + IDD_DIALOG_AF_NAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 46 + END + + IDD_DIALOG_AF_CONSTRAINT_UNIVERSAL, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 258 + END + + IDD_DIALOG_AF_CONSTRAINT_SPRING, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + VERTGUIDE, 78 + VERTGUIDE, 124 + VERTGUIDE, 198 + VERTGUIDE, 234 + VERTGUIDE, 245 + BOTTOMMARGIN, 199 + END + + IDD_DIALOG_AF_CONSTRAINT_SLIDER, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 144 + END + + IDD_DIALOG_AF_CONSTRAINT_HINGE, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 144 + END + + IDD_DIALOG_AF_CONSTRAINT_FIXED, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 54 + END + + IDD_DIALOG_AF_CONSTRAINT_BALLANDSOCKET, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 252 + BOTTOMMARGIN, 210 + END + + IDD_DIALOG_AF_CONSTRAINT, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 247 + TOPMARGIN, 7 + BOTTOMMARGIN, 325 + END + + IDD_DIALOG_AF_BODY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 247 + TOPMARGIN, 7 + BOTTOMMARGIN, 325 + END + + IDD_DIALOG_AF, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 270 + TOPMARGIN, 7 + BOTTOMMARGIN, 395 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON2 ICON "res\\doom.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/AFEditor_resource.h b/sys/win32/rc/AFEditor_resource.h new file mode 100644 index 000000000..06acd5427 --- /dev/null +++ b/sys/win32/rc/AFEditor_resource.h @@ -0,0 +1,360 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_AF 100 +#define IDD_DIALOG_AF_NAME 101 +#define IDD_DIALOG_AF_VIEW 102 +#define IDD_DIALOG_AF_PROPERTIES 103 +#define IDD_DIALOG_AF_BODY 104 +#define IDD_DIALOG_AF_CONSTRAINT 105 +#define IDD_DIALOG_AF_CONSTRAINT_FIXED 106 +#define IDD_DIALOG_AF_CONSTRAINT_BALLANDSOCKET 107 +#define IDD_DIALOG_AF_CONSTRAINT_UNIVERSAL 108 +#define IDD_DIALOG_AF_CONSTRAINT_HINGE 109 +#define IDD_DIALOG_AF_CONSTRAINT_SLIDER 110 +#define IDD_DIALOG_AF_CONSTRAINT_SPRING 111 +#define IDI_ICON2 112 + +#define IDC_DIALOG_AF_TAB_MODE 200 +#define IDC_DIALOG_AF_START 201 +#define IDC_COMBO_AF 202 +#define IDC_BUTTON_AF_NEW 203 +#define IDC_BUTTON_AF_DELETE 204 +#define IDC_BUTTON_AF_SPAWN 205 +#define IDC_BUTTON_AF_TPOSE 206 +#define IDC_BUTTON_AF_KILL 207 +#define IDC_BUTTON_AF_SAVE 208 +#define IDC_EDIT_AF_NAME 209 +#define IDC_STATIC_AF_NAME 210 +#define IDC_DIALOG_AF_VIEW_START 211 +#define IDC_AF_VIEW_AF 212 +#define IDC_AF_VIEW_MD5 213 +#define IDC_AF_VIEW_LINES 214 +#define IDC_AF_VIEW_PHYSICS 215 +#define IDC_CHECK_VIEW_BODIES 216 +#define IDC_CHECK_VIEW_BODYNAMES 217 +#define IDC_CHECK_VIEW_BODYMASS 218 +#define IDC_CHECK_VIEW_TOTALMASS 219 +#define IDC_CHECK_VIEW_INERTIATENSOR 220 +#define IDC_CHECK_VIEW_VELOCITY 221 +#define IDC_CHECK_VIEW_CONSTRAINTNAMES 222 +#define IDC_CHECK_VIEW_CONSTRAINTS 223 +#define IDC_CHECK_VIEW_PRIMARYONLY 224 +#define IDC_CHECK_VIEW_LIMITS 225 +#define IDC_CHECK_VIEW_CONSTRAINEDBODIES 226 +#define IDC_CHECK_VIEW_TREES 227 +#define IDC_CHECK_MD5_SKELETON 228 +#define IDC_CHECK_MD5_SKELETONONLY 229 +#define IDC_CHECK_LINES_DEPTHTEST 230 +#define IDC_CHECK_LINES_USEARROWS 231 +#define IDC_CHECK_PHYSICS_NOFRICTION 232 +#define IDC_CHECK_PHYSICS_NOLIMITS 233 +#define IDC_CHECK_PHYSICS_NOGRAVITY 234 +#define IDC_CHECK_PHYSICS_NOSELFCOLLISION 235 +#define IDC_CHECK_PHYSICS_TIMING 236 +#define IDC_CHECK_PHYSICS_DRAG_ENTITIES 237 +#define IDC_CHECK_PHYSICS_SHOW_DRAG_SELECTION 238 +#define IDC_DIALOG_AF_PROPERTIES_START 239 +#define IDC_STATIC_MD5 240 +#define IDC_STATIC_MODEL 241 +#define IDC_EDIT_MODEL 242 +#define IDC_BUTTON_BROWSE_MODEL 243 +#define IDC_STATIC_SKIN 244 +#define IDC_EDIT_SKIN 245 +#define IDC_BUTTON_BROWSE_SKIN 246 +#define IDC_STATIC_FRICTION 247 +#define IDC_STATIC_LINEARFRICTION 248 +#define IDC_EDIT_LINEARFRICTION 249 +#define IDC_SPIN_LINEARFRICTION 250 +#define IDC_STATIC_ANGULARFRICTION 251 +#define IDC_EDIT_ANGULARFRICTION 252 +#define IDC_SPIN_ANGULARFRICTION 253 +#define IDC_STATIC_CONTACTFRICTION 254 +#define IDC_EDIT_CONTACTFRICTION 255 +#define IDC_SPIN_CONTACTFRICTION 256 +#define IDC_STATIC_CONSTRAINT 257 +#define IDC_EDIT_CONSTRAINTFRICTION 258 +#define IDC_SPIN_CONSTRAINTFRICTION 259 +#define IDC_STATIC_SUSPENDSPEED 260 +#define IDC_STATIC_COLLISIONDETECTION 261 +#define IDC_CHECK_SELFCOLLISION 262 +#define IDC_STATIC_CONTENTS 263 +#define IDC_EDIT_CONTENTS 264 +#define IDC_STATIC_CLIPMASK 265 +#define IDC_EDIT_CLIPMASK 266 +#define IDC_STATIC_LINEARVELOCITY 267 +#define IDC_EDIT_LINEARVELOCITY 268 +#define IDC_STATIC_ANGULARVELOCITY 269 +#define IDC_EDIT_ANGULARVELOCITY 270 +#define IDC_STATIC_LINEARACCELERATION 271 +#define IDC_EDIT_LINEARACCELERATION 272 +#define IDC_STATIC_ANGULARACCELERATION 273 +#define IDC_EDIT_ANGULARACCELERATION 274 +#define IDC_STATIC_MASS 275 +#define IDC_STATIC_TOTALMASS 276 +#define IDC_EDIT_TOTALMASS 277 +#define IDC_SPIN_TOTALMASS 278 +#define IDC_STATIC_SUSPENDMOVEMENT 279 +#define IDC_STATIC_LINEAR_TOLERANCE 280 +#define IDC_EDIT_LINEAR_TOLERANCE 281 +#define IDC_STATIC_ANGULAR_TOLERANCE 282 +#define IDC_EDIT_ANGULAR_TOLERANCE 283 +#define IDC_STATIC_NO_MOVE_TIME 284 +#define IDC_EDIT_NO_MOVE_TIME 285 +#define IDC_STATIC_MAXIMUM_MOVE_TIME 286 +#define IDC_EDIT_MAXIMUM_MOVE_TIME 287 +#define IDC_STATIC_MINIMUM_MOVE_TIME 288 +#define IDC_EDIT_MINIMUM_MOVE_TIME 289 +#define IDC_DIALOG_AF_BODY_START 290 +#define IDC_COMBO_BODIES 291 +#define IDC_BUTTON_NEWBODY 292 +#define IDC_BUTTON_RENAMEBODY 293 +#define IDC_BUTTON_DELETEBODY 294 +#define IDC_BODY_COLLISIONMODEL 295 +#define IDC_STATIC_CM_TYPE 296 +#define IDC_COMBO_CM_TYPE 297 +#define IDC_EDIT_CM_NAME 298 +#define IDC_BUTTON_CM_BROWSE 299 +#define IDC_COMBO_BONE_JOINT1 300 +#define IDC_COMBO_BONE_JOINT2 301 +#define IDC_STATIC_CM_HEIGHT 302 +#define IDC_EDIT_CM_HEIGHT 303 +#define IDC_SPIN_CM_HEIGHT 304 +#define IDC_STATIC_CM_WIDTH 305 +#define IDC_EDIT_CM_WIDTH 306 +#define IDC_SPIN_CM_WIDTH 307 +#define IDC_STATIC_CM_LENGTH 308 +#define IDC_EDIT_CM_LENGTH 309 +#define IDC_SPIN_CM_LENGTH 310 +#define IDC_STATIC_CM_NUMSIDES 311 +#define IDC_EDIT_CM_NUMSIDES 312 +#define IDC_SPIN_CM_NUMSIDES 313 +#define IDC_STATIC_CM_DENSITY 314 +#define IDC_EDIT_CM_DENSITY 315 +#define IDC_SPIN_CM_DENSITY 316 +#define IDC_STATIC_CM_INERTIASCALE 317 +#define IDC_EDIT_CM_INERTIASCALE 318 +#define IDC_STATIC_BODY_ORIGIN_AND_ANGLES 319 +#define IDC_RADIO_ORIGIN_COORDINATES 320 +#define IDC_RADIO_ORIGIN_BONECENTER 321 +#define IDC_RADIO_ORIGIN_JOINT 322 +#define IDC_EDIT_AF_VECTOR_X 323 +#define IDC_EDIT_AF_VECTOR_Y 324 +#define IDC_EDIT_AF_VECTOR_Z 325 +#define IDC_SPIN_AF_VECTOR_X 326 +#define IDC_SPIN_AF_VECTOR_Y 327 +#define IDC_SPIN_AF_VECTOR_Z 328 +#define IDC_COMBO_ORIGIN_BONECENTER_JOINT1 329 +#define IDC_COMBO_ORIGIN_BONECENTER_JOINT2 330 +#define IDC_COMBO_ORIGIN_JOINT 331 +#define IDC_STATIC_CM_ANGLES 332 +#define IDC_STATIC_ANGLES_PITCH 333 +#define IDC_STATIC_ANGLES_YAW 334 +#define IDC_STATIC_ANGLES_ROLL 335 +#define IDC_EDIT_ANGLES_PITCH 336 +#define IDC_SPIN_ANGLES_PITCH 337 +#define IDC_EDIT_ANGLES_YAW 338 +#define IDC_SPIN_ANGLES_YAW 339 +#define IDC_EDIT_ANGLES_ROLL 340 +#define IDC_SPIN_ANGLES_ROLL 341 +#define IDC_STATIC_FRICTIONDIRECTION 342 +#define IDC_EDIT_FRICTIONDIRECTION 343 +#define IDC_STATIC_CONTACTMOTORDIRECTION 344 +#define IDC_EDIT_CONTACTMOTORDIRECTION 345 +#define IDC_STATIC_JOINTS 346 +#define IDC_STATIC_MODIFIEDJOINT 347 +#define IDC_COMBO_MODIFIEDJOINT 348 +#define IDC_STATIC_MODIFY 349 +#define IDC_RADIO_MODIFY_ORIENTATION 350 +#define IDC_RADIO_MODIFY_POSITION 351 +#define IDC_RADIO_MODIFY_BOTH 352 +#define IDC_STATIC_CONTAINEDJOINTS 353 +#define IDC_EDIT_CONTAINEDJOINTS 354 +#define IDC_DIALOG_AF_CONSTRAINT_START 355 +#define IDC_COMBO_CONSTRAINTS 356 +#define IDC_BUTTON_NEWCONSTRAINT 357 +#define IDC_BUTTON_RENAMECONSTRAINT 358 +#define IDC_BUTTON_DELETECONSTRAINT 359 +#define IDC_STATIC_CONSTRAINT_GENERAL 360 +#define IDC_STATIC_CONSTRAINT_TYPE 361 +#define IDC_COMBO_CONSTRAINT_TYPE 362 +#define IDC_STATIC_BODY1 363 +#define IDC_STATIC_BODY2 364 +#define IDC_COMBO_CONSTRAINT_BODY1 365 +#define IDC_COMBO_CONSTRAINT_BODY2 366 +#define IDC_STATIC_CONSTRAINT_FRICTION 367 +#define IDC_EDIT_CONSTRAINT_FRICTION 368 +#define IDC_SPIN_CONSTRAINT_FRICTION 369 +#define IDC_DIALOG_AF_CONSTRAINT_UNIVERSAL_START 370 +#define IDC_STATIC_ANCHOR 371 +#define IDC_RADIO_ANCHOR_JOINT 372 +#define IDC_COMBO_ANCHOR_JOINT 373 +#define IDC_RADIO_ANCHOR_COORDINATES 374 +#define IDC_EDIT_ANCHOR_X 375 +#define IDC_SPIN_ANCHOR_X 376 +#define IDC_EDIT_ANCHOR_Y 377 +#define IDC_SPIN_ANCHOR_Y 378 +#define IDC_EDIT_ANCHOR_Z 379 +#define IDC_SPIN_ANCHOR_Z 380 +#define IDC_STATIC_UNIVERSAL_SHAFT1 381 +#define IDC_RADIO_UNIVERSAL_BONE_SHAFT1 382 +#define IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1 383 +#define IDC_COMBO_UNIVERSAL_JOINT1_SHAFT1 384 +#define IDC_COMBO_UNIVERSAL_JOINT2_SHAFT1 385 +#define IDC_EDIT_UNIVERSAL_PITCH_SHAFT1 386 +#define IDC_SPIN_UNIVERSAL_PITCH_SHAFT1 387 +#define IDC_EDIT_UNIVERSAL_YAW_SHAFT1 388 +#define IDC_SPIN_UNIVERSAL_YAW_SHAFT1 389 +#define IDC_STATIC_UNIVERSAL_SHAFT2 390 +#define IDC_RADIO_UNIVERSAL_BONE_SHAFT2 391 +#define IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2 392 +#define IDC_COMBO_UNIVERSAL_JOINT1_SHAFT2 393 +#define IDC_COMBO_UNIVERSAL_JOINT2_SHAFT2 394 +#define IDC_EDIT_UNIVERSAL_PITCH_SHAFT2 395 +#define IDC_SPIN_UNIVERSAL_PITCH_SHAFT2 396 +#define IDC_EDIT_UNIVERSAL_YAW_SHAFT2 397 +#define IDC_SPIN_UNIVERSAL_YAW_SHAFT2 398 +#define IDC_STATIC_UNIVERSAL_LIMIT_TYPE 399 +#define IDC_RADIO_UNIVERSAL_LIMIT_NONE 400 +#define IDC_RADIO_UNIVERSAL_LIMIT_CONE 401 +#define IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID 402 +#define IDC_STATIC_UNIVERSAL_LIMIT_ORIENTATION 403 +#define IDC_RADIO_UNIVERSAL_LIMIT_BONE 404 +#define IDC_RADIO_UNIVERSAL_LIMIT_ANGLES 405 +#define IDC_COMBO_UNIVERSAL_LIMIT_JOINT1 406 +#define IDC_COMBO_UNIVERSAL_LIMIT_JOINT2 407 +#define IDC_EDIT_UNIVERSAL_LIMIT_YAW 408 +#define IDC_SPIN_UNIVERSAL_LIMIT_YAW 409 +#define IDC_EDIT_UNIVERSAL_LIMIT_PITCH 410 +#define IDC_SPIN_UNIVERSAL_LIMIT_PITCH 411 +#define IDC_EDIT_UNIVERSAL_LIMIT_ROLL 412 +#define IDC_SPIN_UNIVERSAL_LIMIT_ROLL 413 +#define IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE 414 +#define IDC_SPIN_UNIVERSAL_LIMIT_CONE_ANGLE 415 +#define IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1 416 +#define IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE1 417 +#define IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2 418 +#define IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE2 419 +#define IDC_DIALOG_AF_CONSTRAINT_HINGE_START 420 +#define IDC_STATIC_HINGE_AXIS 421 +#define IDC_RADIO_HINGE_AXIS_BONE 422 +#define IDC_RADIO_HINGE_AXIS_ANGLES 423 +#define IDC_COMBO_HINGE_AXIS_JOINT1 424 +#define IDC_COMBO_HINGE_AXIS_JOINT2 425 +#define IDC_EDIT_HINGE_AXIS_PITCH 426 +#define IDC_SPIN_HINGE_AXIS_PITCH 427 +#define IDC_EDIT_HINGE_AXIS_YAW 428 +#define IDC_SPIN_HINGE_AXIS_YAW 429 +#define IDC_STATIC_HINGE_LIMIT 430 +#define IDC_RADIO_HINGE_LIMIT_NONE 431 +#define IDC_STATIC_HINGE_LIMIT2 432 +#define IDC_RADIO_HINGE_LIMIT_ANGLES 433 +#define IDC_SPIN_HINGE_LIMIT_ANGLE1 434 +#define IDC_EDIT_HINGE_LIMIT_ANGLE1 435 +#define IDC_SPIN_HINGE_LIMIT_ANGLE2 436 +#define IDC_EDIT_HINGE_LIMIT_ANGLE2 437 +#define IDC_EDIT_HINGE_LIMIT_ANGLE3 438 +#define IDC_SPIN_HINGE_LIMIT_ANGLE3 439 +#define IDC_DIALOG_AF_CONSTRAINT_BAS_START 440 +#define IDC_STATIC_BAS_LIMIT_TYPE 441 +#define IDC_RADIO_BAS_LIMIT_NONE 442 +#define IDC_RADIO_BAS_LIMIT_CONE 443 +#define IDC_RADIO_BAS_LIMIT_PYRAMID 444 +#define IDC_EDIT_BAS_LIMIT_CONE_ANGLE 445 +#define IDC_SPIN_BAS_LIMIT_CONE_ANGLE 446 +#define IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1 447 +#define IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE1 448 +#define IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2 449 +#define IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE2 450 +#define IDC_EDIT_BAS_LIMIT_ROLL 451 +#define IDC_SPIN_BAS_LIMIT_ROLL 452 +#define IDC_STATIC_BAS_LIMIT_ORIENTATION 453 +#define IDC_RADIO_BAS_LIMIT_BONE 454 +#define IDC_RADIO_BAS_LIMIT_ANGLES 455 +#define IDC_COMBO_BAS_LIMIT_JOINT1 456 +#define IDC_COMBO_BAS_LIMIT_JOINT2 457 +#define IDC_EDIT_BAS_LIMIT_PITCH 458 +#define IDC_SPIN_BAS_LIMIT_PITCH 459 +#define IDC_EDIT_BAS_LIMIT_YAW 460 +#define IDC_SPIN_BAS_LIMIT_YAW 461 +#define IDC_STATIC_BAS_LIMIT_AXIS 462 +#define IDC_RADIO_BAS_LIMIT_AXIS_BONE 463 +#define IDC_COMBO_BAS_LIMIT_AXIS_JOINT1 464 +#define IDC_COMBO_BAS_LIMIT_AXIS_JOINT2 465 +#define IDC_RADIO_BAS_LIMIT_AXIS_ANGLES 466 +#define IDC_EDIT_BAS_LIMIT_AXIS_PITCH 467 +#define IDC_SPIN_BAS_LIMIT_AXIS_PITCH 468 +#define IDC_EDIT_BAS_LIMIT_AXIS_YAW 469 +#define IDC_SPIN_BAS_LIMIT_AXIS_YAW 470 +#define IDC_DIALOG_AF_CONSTRAINT_SLIDER_START 471 +#define IDC_RADIO_SLIDER_AXIS_BONE 472 +#define IDC_COMBO_SLIDER_AXIS_JOINT1 473 +#define IDC_COMBO_SLIDER_AXIS_JOINT2 474 +#define IDC_RADIO_SLIDER_AXIS_ANGLES 475 +#define IDC_EDIT_SLIDER_AXIS_PITCH 476 +#define IDC_SPIN_SLIDER_AXIS_PITCH 477 +#define IDC_EDIT_SLIDER_AXIS_YAW 478 +#define IDC_SPIN_SLIDER_AXIS_YAW 479 +#define IDC_STATIC_SLIDER_AXIS 480 +#define IDC_DIALOG_AF_CONSTRAINT_SPRING_START 481 +#define IDC_STATIC_ANCHOR2 482 +#define IDC_RADIO_ANCHOR2_JOINT 483 +#define IDC_COMBO_ANCHOR2_JOINT 484 +#define IDC_RADIO_ANCHOR2_COORDINATES 485 +#define IDC_EDIT_ANCHOR2_X 486 +#define IDC_SPIN_ANCHOR2_X 487 +#define IDC_EDIT_ANCHOR2_Y 488 +#define IDC_SPIN_ANCHOR2_Y 489 +#define IDC_EDIT_ANCHOR2_Z 490 +#define IDC_SPIN_ANCHOR2_Z 491 +#define IDC_STATIC_SPRING_SETTINGS 492 +#define IDC_STATIC_SPRING_STRETCH 493 +#define IDC_STATIC_SPRING_COMPRESS 494 +#define IDC_STATIC_SPRING_DAMPING 495 +#define IDC_STATIC_SPRING_REST_LENGTH 496 +#define IDC_EDIT_SPRING_STRETCH 497 +#define IDC_SPIN_SPRING_STRETCH 498 +#define IDC_EDIT_SPRING_COMPRESS 499 +#define IDC_SPIN_SPRING_COMPRESS 500 +#define IDC_EDIT_SPRING_DAMPING 501 +#define IDC_SPIN_SPRING_DAMPING 502 +#define IDC_EDIT_SPRING_REST_LENGTH 503 +#define IDC_SPIN_SPRING_REST_LENGTH 504 +#define IDC_STATIC_SPRING_LIMIT 505 +#define IDC_RADIO_SPRING_NO_MIN_LENGTH 506 +#define IDC_RADIO_SPRING_MIN_LENGTH 507 +#define IDC_EDIT_SPRING_MIN_LENGTH 508 +#define IDC_SPIN_SPRING_MIN_LENGTH 509 +#define IDC_RADIO_SPRING_NO_MAX_LENGTH 510 +#define IDC_RADIO_SPRING_MAX_LENGTH 511 +#define IDC_EDIT_SPRING_MAX_LENGTH 512 +#define IDC_SPIN_SPRING_MAX_LENGTH 513 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 20000 +#define _APS_NEXT_CONTROL_VALUE 514 +#define _APS_NEXT_SYMED_VALUE 113 +#endif +#endif diff --git a/sys/win32/rc/Common.rc b/sys/win32/rc/Common.rc new file mode 100644 index 000000000..235d7f908 --- /dev/null +++ b/sys/win32/rc/Common.rc @@ -0,0 +1,170 @@ +// Microsoft Visual C++ generated resource script. +// +#include "common_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "common_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TOOLS_OPEN DIALOGEX 0, 0, 308, 217 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Open" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "File &name:",IDC_STATIC,13,181,34,8 + EDITTEXT IDC_TOOLS_FILENAME,51,179,187,13,ES_AUTOHSCROLL + LTEXT "Look In:",IDC_STATIC,7,9,27,8 + CONTROL "",IDC_TOOLS_LOOKIN,"ComboBoxEx32",CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP,35,7,195,118 + PUSHBUTTON "",IDC_TOOLS_BACK,241,7,14,13,BS_BITMAP + CONTROL "",IDC_TOOLS_FILELIST,"SysListView32",LVS_LIST | + LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7, + 24,294,149 + DEFPUSHBUTTON "&Open",IDOK,251,179,50,14 + PUSHBUTTON "Cancel",IDCANCEL,251,197,50,14 +END + +IDD_RENDERBUMPFLAT DIALOGEX 0, 0, 186, 73 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Render Bump Flat" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_RBF_WIDTH,36,6,40,14,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_RBF_HEIGHT,36,30,40,14,ES_AUTOHSCROLL | ES_NUMBER + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + LTEXT "Width:",IDC_STATIC,6,6,22,8 + LTEXT "Height:",IDC_STATIC,6,30,24,8 + LTEXT "File:",IDC_STATIC,6,54,14,8 + LTEXT "",IDC_RBF_FILENAME,24,54,156,8 +END + +IDD_NEWNAME DIALOG 0, 0, 186, 46 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_TOOLS_EDITNAME,31,10,106,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,143,7,36,14 + PUSHBUTTON "Cancel",IDCANCEL,143,24,36,14 + LTEXT "Name:",IDC_STATIC,7,12,22,8 +END + +IDD_DIALOG_GOTOLINE DIALOGEX 0, 0, 166, 54 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Go To Line" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,55,33,50,14 + PUSHBUTTON "Cancel",IDCANCEL,108,33,50,14 + LTEXT "&Line number (0 - 0):",IDC_GOTOLINE_STATIC,7,4,152,8 + EDITTEXT IDC_GOTOLINE_EDIT,7,15,152,14,ES_AUTOHSCROLL | ES_NUMBER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TOOLS_OPEN BITMAP "res\\dbg_open.bmp" +IDB_TOOLS_BACK BITMAP "res\\dbg_back.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_RENDERBUMPFLAT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 66 + END + + IDD_NEWNAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 39 + END + + IDD_DIALOG_GOTOLINE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 159 + TOPMARGIN, 3 + BOTTOMMARGIN, 47 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/Common_resource.h b/sys/win32/rc/Common_resource.h new file mode 100644 index 000000000..1de94023f --- /dev/null +++ b/sys/win32/rc/Common_resource.h @@ -0,0 +1,49 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_NEWNAME 1000 +#define IDD_RENDERBUMPFLAT 1001 +#define IDD_TOOLS_OPEN 1002 +#define IDD_DIALOG_GOTOLINE 1003 +#define IDB_TOOLS_OPEN 1004 +#define IDB_TOOLS_BACK 1005 + +#define IDC_TOOLS_EDITNAME 1200 +#define IDC_TOOLS_BACK 1201 +#define IDC_TOOLS_LOOKIN 1202 +#define IDC_TOOLS_FILENAME 1203 +#define IDC_TOOLS_FILELIST 1204 +#define IDC_RBF_WIDTH 1205 +#define IDC_RBF_HEIGHT 1206 +#define IDC_RBF_FILENAME 1207 +#define IDC_GOTOLINE_STATIC 1208 +#define IDC_GOTOLINE_EDIT 1209 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 1006 +#define _APS_NEXT_COMMAND_VALUE 21000 +#define _APS_NEXT_CONTROL_VALUE 1210 +#define _APS_NEXT_SYMED_VALUE 1006 +#endif +#endif diff --git a/sys/win32/rc/CreateResourceIDs.cpp b/sys/win32/rc/CreateResourceIDs.cpp new file mode 100644 index 000000000..e7d28a665 --- /dev/null +++ b/sys/win32/rc/CreateResourceIDs.cpp @@ -0,0 +1,180 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + + +/* +================ +CreateResourceIDs_f +================ +*/ +void CreateResourceIDs_f( const idCmdArgs &args ) { + int i, j; + idStr path, fileName; + idStrList resourceFiles; + idLexer src; + idToken token; + idStrList dialogs; + idStrList resources; + idStrList bitmaps; + idStrList icons; + idStrList strings; + idStrList controls; + idStrList commands; + + if ( args.Argc() > 1 ) { + path = args.Argv(1); + } else { + path = SOURCE_CODE_BASE_FOLDER"/"; + path.Append( __FILE__ ); + path.StripFilename(); + path.BackSlashesToSlashes(); + } + + common->Printf( "%s\n", path.c_str() ); + Sys_ListFiles( path, "_resource.h", resourceFiles ); + + for ( i = 0; i < resourceFiles.Num(); i++ ) { + + fileName = path + "/" + resourceFiles[i]; + + common->Printf( "creating IDs for %s...\n", fileName.c_str() ); + + if ( !src.LoadFile( fileName, true ) ) { + common->Warning( "couldn't load %s", fileName.c_str() ); + continue; + } + + dialogs.Clear(); + resources.Clear(); + bitmaps.Clear(); + icons.Clear(); + strings.Clear(); + controls.Clear(); + commands.Clear(); + + while( src.ReadToken( &token ) ) { + if ( token == "#" ) { + src.ExpectAnyToken( &token ); + if ( token == "ifdef" || token == "ifndef" ) { + src.SkipRestOfLine(); + } else if ( token == "define" ) { + src.ExpectTokenType( TT_NAME, 0, &token ); + + if ( token.Icmpn( "_APS_", 5 ) == 0 ) { + continue; + } + + if ( token.Icmpn( "IDD_", 4 ) == 0 ) { + dialogs.AddUnique( token ); + } else if ( token.Icmpn( "IDR_", 4 ) == 0 ) { + resources.AddUnique( token ); + } else if ( token.Icmpn( "IDB_", 4 ) == 0 ) { + bitmaps.AddUnique( token ); + } else if ( token.Icmpn( "IDI_", 4 ) == 0 ) { + icons.AddUnique( token ); + } else if ( token.Icmpn( "IDS_", 4 ) == 0 || + token.Icmpn( "IDP_", 4 ) == 0 ) { + strings.AddUnique( token ); + } else if ( token.Icmpn( "IDC_", 4 ) == 0 ) { + controls.AddUnique( token ); + } else { + commands.AddUnique( token ); + } + } + } + } + + src.FreeSource(); + + idFile *f; + int curResource, curControl, curCommand; + + curResource = i ? i * 1000 : 100; + curCommand = 20000 + i * 1000; + curControl = i * 1000 + 200; + + f = fileSystem->OpenExplicitFileWrite( fileName ); + if ( !f ) { + common->Warning( "couldn't write %s", fileName.c_str() ); + continue; + } + + f->WriteFloatString( "//{{NO_DEPENDENCIES}}\n" + "// Microsoft Visual C++ generated include file.\n" + "// Used by .rc\n" + "//\n\n" ); + + for ( j = 0; j < dialogs.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", dialogs[j].c_str(), curResource++ ); + } + for ( j = 0; j < resources.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", resources[j].c_str(), curResource++ ); + } + for ( j = 0; j < bitmaps.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", bitmaps[j].c_str(), curResource++ ); + } + for ( j = 0; j < icons.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", icons[j].c_str(), curResource++ ); + } + for ( j = 0; j < strings.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", strings[j].c_str(), curResource++ ); + } + + f->WriteFloatString( "\n" ); + + for ( j = 0; j < controls.Num(); j++ ) { + f->WriteFloatString( "#define %-40s %d\n", controls[j].c_str(), curControl++ ); + } + + f->WriteFloatString( "\n" ); + + for ( j = 0; j < commands.Num(); j++ ) { + + // NOTE: special hack for Radiant + if ( commands[j].Cmp( "ID_ENTITY_START" ) == 0 ) { + f->WriteFloatString( "#define %-40s %d\n", commands[j].c_str(), 40000 ); + continue; + } + if ( commands[j].Cmp( "ID_ENTITY_END" ) == 0 ) { + f->WriteFloatString( "#define %-40s %d\n", commands[j].c_str(), 45000 ); + continue; + } + + f->WriteFloatString( "#define %-40s %d\n", commands[j].c_str(), curCommand++ ); + } + + + f->WriteFloatString( "\n// Next default values for new objects\n" + "// \n" + "#ifdef APSTUDIO_INVOKED\n" + "#ifndef APSTUDIO_READONLY_SYMBOLS\n" + "#define _APS_3D_CONTROLS 1\n" + "#define _APS_NEXT_RESOURCE_VALUE %d\n" + "#define _APS_NEXT_COMMAND_VALUE %d\n" + "#define _APS_NEXT_CONTROL_VALUE %d\n" + "#define _APS_NEXT_SYMED_VALUE %d\n" + "#endif\n" + "#endif\n", curResource, curCommand, curControl, curResource ); + + fileSystem->CloseFile( f ); + } +} diff --git a/sys/win32/rc/CreateResourceIDs.h b/sys/win32/rc/CreateResourceIDs.h new file mode 100644 index 000000000..d9e58d5f8 --- /dev/null +++ b/sys/win32/rc/CreateResourceIDs.h @@ -0,0 +1,33 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CREATERESOURCEIDS__ +#define __CREATERESOURCEIDS__ + +/* +=============================================================================== + + Create resource IDs without conflicts. + +=============================================================================== +*/ + +void CreateResourceIDs_f( const idCmdArgs &args ); + +#endif /* !__CREATERESOURCEIDS__ */ diff --git a/sys/win32/rc/Debugger.rc b/sys/win32/rc/Debugger.rc new file mode 100644 index 000000000..bee22e2fa --- /dev/null +++ b/sys/win32/rc/Debugger.rc @@ -0,0 +1,250 @@ +// Microsoft Visual C++ generated resource script. +// +#include "debugger_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "debugger_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_DBG_MAIN MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open...\tCtrl-O", ID_DBG_FILE_OPEN + MENUITEM "&Close", ID_DBG_FILE_CLOSE + MENUITEM "MRU1", ID_DBG_FILE_MRU + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_DBG_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "Cu&t", ID_DBG_EDIT_CUT, GRAYED + MENUITEM "&Copy", ID_DBG_EDIT_COPY, GRAYED + MENUITEM "&Paste", ID_DBG_EDIT_PASTE, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Find...", ID_DBG_EDIT_FIND + END + POPUP "&Debug" + BEGIN + MENUITEM "&Run\tF5", ID_DBG_DEBUG_RUN + MENUITEM "&Break", ID_DBG_DEBUG_BREAK + MENUITEM SEPARATOR + MENUITEM "&Quick Watch...\tShift+F9", 125 + MENUITEM SEPARATOR + MENUITEM "Step &Over\tF10", ID_DBG_DEBUG_STEPOVER + MENUITEM "Step &Into\tF11", ID_DBG_DEBUG_STEPINTO + MENUITEM "Step O&ut\tShift+F11", ID_DBG_DEBUG_STEPOUT + MENUITEM SEPARATOR + MENUITEM "Toggle &Breakpoint\tF9", ID_DBG_DEBUG_TOGGLEBREAKPOINT + + END + POPUP "&Window" + BEGIN + MENUITEM "&Close All", ID_DBG_WINDOW_CLOSEALL + END + POPUP "&Help" + BEGIN + MENUITEM "&About...", ID_DBG_HELP_ABOUT + END +END + +IDR_DBG_SCRIPT_POPUP MENU +BEGIN + POPUP "script" + BEGIN + MENUITEM "Toggle &Breakpoint\tF9", 111 + MENUITEM SEPARATOR + MENUITEM "&Show Next Statement", ID_DBG_DEBUG_SHOWNEXTSTATEMENT + + MENUITEM "&Run To Cursor", ID_DBG_DEBUG_RUNTOCURSOR + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_DBG_BREAKPOINT ICON "res\\dbg_breakpoint.ico" +IDI_DBG_CURRENTLINE ICON "res\\dbg_currentline.ico" +IDI_DBG_CURRENT ICON "res\\dbg_current.ico" +IDI_DBG_EMPTY ICON "res\\dbg_empty.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_DBG_ACCELERATORS ACCELERATORS +BEGIN + VK_F9, ID_DBG_DEBUG_QUICKWATCH, VIRTKEY, SHIFT, NOINVERT + VK_F5, ID_DBG_DEBUG_RUN, VIRTKEY, NOINVERT + VK_F11, ID_DBG_DEBUG_STEPINTO, VIRTKEY, NOINVERT + VK_F10, ID_DBG_DEBUG_STEPOVER, VIRTKEY, NOINVERT + VK_F9, ID_DBG_DEBUG_TOGGLEBREAKPOINT, VIRTKEY, NOINVERT + VK_F3, ID_DBG_EDIT_FINDNEXT, VIRTKEY, NOINVERT + VK_F3, ID_DBG_EDIT_FINDPREV, VIRTKEY, SHIFT, NOINVERT + VK_F3, ID_DBG_EDIT_FINDSELECTED, VIRTKEY, CONTROL, NOINVERT + VK_F3, ID_DBG_EDIT_FINDSELECTED, VIRTKEY, CONTROL, NOINVERT + VK_F3, ID_DBG_EDIT_FINDSELECTEDPREV, VIRTKEY, SHIFT, CONTROL, + NOINVERT + VK_F4, ID_DBG_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT + VK_TAB, ID_DBG_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT + "O", ID_DBG_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "F", ID_DBG_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DBG_ABOUT DIALOGEX 0, 0, 222, 71 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "About Script Debugger" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Script Debugger",IDC_STATIC,35,7,81,8 + LTEXT "Version 0.01",IDC_STATIC,35,17,41,8 + LTEXT "Original version by Raven",IDC_STATIC,35, + 28,134,8 + DEFPUSHBUTTON "OK",IDOK,165,50,50,14 + ICON 5098,IDC_STATIC,7,7,20,20 +END + +IDD_DBG_QUICKWATCH DIALOGEX 0, 0, 306, 174 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +CAPTION "Quick Watch" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Variable:",IDC_STATIC,7,7,29,8 + EDITTEXT IDC_DBG_VARIABLE,7,17,230,12,ES_AUTOHSCROLL + LTEXT "C&urrent value:",IDC_DBG_CURVALUE_STATIC,7,34,48,8 + CONTROL "",IDC_DBG_CURVALUE,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,46,230,121 + DEFPUSHBUTTON "&Recalculate",IDC_DBG_RECALC,250,7,49,14 + PUSHBUTTON "&Add Watch",IDC_DBG_ADDWATCH,250,24,49,14 + PUSHBUTTON "&Close",IDC_DBG_CLOSE,250,41,49,14 +END + +IDD_DBG_FIND DIALOGEX 0, 0, 232, 52 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Find" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Fi&nd what:",IDC_STATIC,7,9,35,8 + EDITTEXT IDC_DBG_FIND,45,8,122,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "&Find",IDOK,175,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,175,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DBG_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_DBG_QUICKWATCH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 299 + TOPMARGIN, 7 + BOTTOMMARGIN, 167 + END + + IDD_DBG_FIND, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 225 + TOPMARGIN, 7 + BOTTOMMARGIN, 45 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_DBG_TOOLBAR BITMAP "res\\dbg_toolbar.bmp" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/Debugger_resource.h b/sys/win32/rc/Debugger_resource.h new file mode 100644 index 000000000..688736d34 --- /dev/null +++ b/sys/win32/rc/Debugger_resource.h @@ -0,0 +1,81 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DBG_FIND 2000 +#define IDD_DBG_QUICKWATCH 2001 +#define IDD_DBG_ABOUT 2002 +#define IDR_DBG_MAIN 2003 +#define IDR_DBG_ACCELERATORS 2004 +#define IDR_DBG_SCRIPT_POPUP 2005 +#define IDB_DBG_TOOLBAR 2006 +#define IDI_DBG_BREAKPOINT 2007 +#define IDI_DBG_CURRENTLINE 2008 +#define IDI_DBG_CURRENT 2009 +#define IDI_DBG_EMPTY 2010 + +#define IDC_DBG_CLOSE 2200 +#define IDC_DBG_FILELIST 2201 +#define IDC_DBG_NAME 2202 +#define IDC_DBG_PATH 2203 +#define IDC_DBG_BACK 2204 +#define IDC_DBG_LOOKIN 2205 +#define IDC_DBG_RECALC 2206 +#define IDC_DBG_ADDWATCH 2207 +#define IDC_DBG_VARIABLE 2208 +#define IDC_DBG_CURVALUE 2209 +#define IDC_DBG_CURVALUE_STATIC 2210 +#define IDC_DBG_FIND 2211 + +#define ID_DBG_FILE_MRU 22000 +#define ID_DBG_FILE_OPEN 22001 +#define ID_DBG_FILE_OPENSCRIPT 22002 +#define ID_DBG_FILE_EXIT 22003 +#define ID_DBG_WINDOW_CLOSEALL 22004 +#define ID_DBG_DEBUG_TOGGLEBREAKPOINT 22005 +#define ID_DBG_DEBUG_RUN 22006 +#define ID_DBG_DEBUG_BREAK 22007 +#define ID_DBG_FILE_NEXT 22008 +#define ID_DBG_DEBUG_STEPOVER 22009 +#define ID_DBG_FILE_CLOSE 22010 +#define ID_DBG_DEBUG_STEPINTO 22011 +#define ID_DBG_DEBUG_STEPOUT 22012 +#define ID_DBG_DEBUG_QUICKWATCH 22013 +#define ID_DBG_DEBUG_RUNTOCURSOR 22014 +#define ID_DBG_DEBUG_SHOWNEXTSTATEMENT 22015 +#define ID_DBG_EDIT_COPY 22016 +#define ID_DBG_EDIT_CUT 22017 +#define ID_DBG_EDIT_PASTE 22018 +#define ID_DBG_EDIT_FIND 22019 +#define ID_DBG_EDIT_FINDSELECTED 22020 +#define ID_DBG_EDIT_FINDNEXT 22021 +#define ID_DBG_EDIT_FINDPREV 22022 +#define ID_DBG_EDIT_FINDSELECTEDPREV 22023 +#define ID_DBG_HELP_ABOUT 22024 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 2011 +#define _APS_NEXT_COMMAND_VALUE 22025 +#define _APS_NEXT_CONTROL_VALUE 2212 +#define _APS_NEXT_SYMED_VALUE 2011 +#endif +#endif diff --git a/sys/win32/rc/DeclEditor.rc b/sys/win32/rc/DeclEditor.rc new file mode 100644 index 000000000..1d09f02e3 --- /dev/null +++ b/sys/win32/rc/DeclEditor.rc @@ -0,0 +1,179 @@ +// Microsoft Visual C++ generated resource script. +// +#include "DeclEditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "DeclEditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_DECLBROWSER DIALOGEX 0, 0, 271, 313 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | + WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Declaration Browser" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_DECLBROWSER_TREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, + 2,2,268,247,WS_EX_CLIENTEDGE + CONTROL "",IDC_DECLBROWSER_BASE_TREE,"SysTreeView32", + TVS_NOSCROLL | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP, + 166,281,20,17 + EDITTEXT IDC_DECLBROWSER_EDIT_SEARCH_NAMES,53,252,215,12, + ES_AUTOHSCROLL + EDITTEXT IDC_DECLBROWSER_EDIT_SEARCH_TEXT,53,267,215,12, + ES_AUTOHSCROLL + LTEXT "Search names:",IDC_DECLBROWSER_STATIC_SEARCH_NAMES,2, + 254,48,9 + LTEXT "Search text:",IDC_DECLBROWSER_STATIC_SEARCH_TEXT,2,267, + 48,9 + DEFPUSHBUTTON "Find",IDC_DECLBROWSER_BUTTON_FIND,3,284,38,14 + PUSHBUTTON "Edit",IDC_DECLBROWSER_BUTTON_EDIT,44,284,38,14 + PUSHBUTTON "New",IDC_DECLBROWSER_BUTTON_NEW,85,284,38,14 + PUSHBUTTON "Reload",IDC_DECLBROWSER_BUTTON_RELOAD,126,284,38,14 + PUSHBUTTON "Close",IDCANCEL,230,284,38,14 +END + +IDD_DIALOG_DECLEDITOR DIALOGEX 0, 0, 350, 246 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | + WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Declaration Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Save",IDOK,260,216,42,14 + PUSHBUTTON "Cancel",IDCANCEL,306,216,42,14 + CONTROL "",IDC_DECLEDITOR_EDIT_TEXT,"RichEdit20A",ES_MULTILINE | + ES_AUTOHSCROLL | ES_WANTRETURN | WS_BORDER | WS_VSCROLL | + WS_HSCROLL | WS_TABSTOP,2,4,346,208 + PUSHBUTTON "Test",IDC_DECLEDITOR_BUTTON_TEST,2,216,42,14 +END + +IDD_DIALOG_DECLNEW DIALOGEX 0, 0, 244, 87 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "New Declaration" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,133,65,50,14 + PUSHBUTTON "Cancel",IDCANCEL,187,65,50,14 + LTEXT "Type:",IDC_DECLNEW_STATIC_NEW_TYPE,7,9,20,8 + EDITTEXT IDC_DECLNEW_EDIT_NEW_FILE,34,45,176,13,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_DECLNEW_BUTTON_NEW_FILE,217,44,20,14 + LTEXT "File:",IDC_DECLNEW_STATIC_NEW_FILE,7,47,14,8 + EDITTEXT IDC_DECLNEW_EDIT_NEW_NAME,34,26,203,13,ES_AUTOHSCROLL + LTEXT "Name:",IDC_DECLNEW_STATIC_NEW_NAME,7,28,22,8 + COMBOBOX IDC_DECLNEW_COMBO_NEW_TYPE,34,7,203,75,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_DECLBROWSER, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 225 + BOTTOMMARGIN, 298 + END + + IDD_DIALOG_DECLEDITOR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 343 + TOPMARGIN, 7 + BOTTOMMARGIN, 239 + END + + IDD_DIALOG_DECLNEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 237 + TOPMARGIN, 7 + BOTTOMMARGIN, 80 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR_DECLEDITOR ACCELERATORS +BEGIN + VK_F3, ID_DECLEDITOR_FIND_NEXT, VIRTKEY, NOINVERT + "G", ID_DECLEDITOR_GOTOLINE, VIRTKEY, CONTROL, NOINVERT + "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT + "R", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT + "H", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT + "S", IDOK, VIRTKEY, CONTROL, NOINVERT +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/DeclEditor_resource.h b/sys/win32/rc/DeclEditor_resource.h new file mode 100644 index 000000000..093449915 --- /dev/null +++ b/sys/win32/rc/DeclEditor_resource.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_DECLBROWSER 3000 +#define IDD_DIALOG_DECLEDITOR 3001 +#define IDD_DIALOG_DECLNEW 3002 +#define IDR_ACCELERATOR_DECLEDITOR 3003 + +#define IDC_DECLBROWSER_BASE_TREE 3200 +#define IDC_DECLBROWSER_TREE 3201 +#define IDC_DECLBROWSER_STATIC_SEARCH_NAMES 3202 +#define IDC_DECLBROWSER_STATIC_SEARCH_TEXT 3203 +#define IDC_DECLBROWSER_EDIT_SEARCH_NAMES 3204 +#define IDC_DECLBROWSER_EDIT_SEARCH_TEXT 3205 +#define IDC_DECLBROWSER_BUTTON_FIND 3206 +#define IDC_DECLBROWSER_BUTTON_EDIT 3207 +#define IDC_DECLBROWSER_BUTTON_NEW 3208 +#define IDC_DECLBROWSER_BUTTON_RELOAD 3209 +#define IDC_DECLNEW_STATIC_NEW_TYPE 3210 +#define IDC_DECLNEW_STATIC_NEW_NAME 3211 +#define IDC_DECLNEW_STATIC_NEW_FILE 3212 +#define IDC_DECLNEW_COMBO_NEW_TYPE 3213 +#define IDC_DECLNEW_EDIT_NEW_NAME 3214 +#define IDC_DECLNEW_EDIT_NEW_FILE 3215 +#define IDC_DECLNEW_BUTTON_NEW_FILE 3216 +#define IDC_DECLEDITOR_EDIT_TEXT 3217 +#define IDC_DECLEDITOR_BUTTON_TEST 3218 + +#define ID_DECLEDITOR_FIND_NEXT 23000 +#define ID_DECLEDITOR_GOTOLINE 23001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 3004 +#define _APS_NEXT_COMMAND_VALUE 23002 +#define _APS_NEXT_CONTROL_VALUE 3219 +#define _APS_NEXT_SYMED_VALUE 3004 +#endif +#endif diff --git a/sys/win32/rc/GuiEd.rc b/sys/win32/rc/GuiEd.rc new file mode 100644 index 000000000..6de83dc71 --- /dev/null +++ b/sys/win32/rc/GuiEd.rc @@ -0,0 +1,736 @@ +// Microsoft Visual C++ generated resource script. +// +#include "guied_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "guied_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_GUIED_MAIN MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New\tCtrl+N", ID_GUIED_FILE_NEW + MENUITEM "&Open...\tCtrl+O", ID_GUIED_FILE_OPEN + MENUITEM "&Close", ID_GUIED_FILE_CLOSE + MENUITEM SEPARATOR + MENUITEM "&Save\tCtrl+S", ID_GUIED_FILE_SAVE + MENUITEM "Save &As...", ID_GUIED_FILE_SAVEAS + MENUITEM SEPARATOR + POPUP "So&urce Control" + BEGIN + MENUITEM "&Get Latest Version", ID_GUIED_SOURCECONTROL_GETLATESTVERSION + + MENUITEM "Check &Out", ID_GUIED_SOURCECONTROL_CHECKOUT + + MENUITEM "Check &In", ID_GUIED_SOURCECONTROL_CHECKIN + + MENUITEM "&Undo Checkout", ID_GUIED_SOURCECONTROL_UNDOCHECKOUT + + END + MENUITEM "MRU1", ID_GUIED_FILE_MRU + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_GUIED_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl+Z", ID_GUIED_EDIT_UNDO + MENUITEM "&Redo\tCtrl+Y", ID_GUIED_EDIT_REDO + MENUITEM SEPARATOR + MENUITEM "&Copy\tCtrl+C", ID_GUIED_EDIT_COPY, GRAYED + MENUITEM "&Paste\tCtrl+V", ID_GUIED_EDIT_PASTE, GRAYED + MENUITEM "&Delete\tDel", ID_GUIED_EDIT_DELETE + END + POPUP "&View" + BEGIN + MENUITEM "Zoom &In\tCtrl++", ID_GUIED_VIEW_ZOOMIN + MENUITEM "Zoom &Out\tCtrl+-", ID_GUIED_VIEW_ZOOMOUT + MENUITEM SEPARATOR + POPUP "&Hide/Show" + BEGIN + MENUITEM "&Hide Selected\tH", ID_GUIED_VIEW_HIDESELECTED + + MENUITEM "&Unhide Selected\tU", ID_GUIED_VIEW_UNHIDESELECTED + + MENUITEM "&Show Hidden\tShift+H", ID_GUIED_VIEW_SHOWHIDDEN + END + MENUITEM SEPARATOR + MENUITEM "Show &Grid\tCtrl+""", ID_GUIED_VIEW_SHOWGRID + MENUITEM "S&nap To Grid\tShift+Ctrl+""", ID_GUIED_VIEW_SNAPTOGRID + MENUITEM SEPARATOR + MENUITEM "Show &Status Bar", ID_GUIED_VIEW_STATUSBAR + MENUITEM SEPARATOR + MENUITEM "O&ptions...", ID_GUIED_VIEW_OPTIONS + END + POPUP "&Item" + BEGIN + POPUP "&New" + BEGIN + MENUITEM "&windowDef", ID_GUIED_ITEM_NEWWINDOWDEF + + MENUITEM "&editDef", ID_GUIED_ITEM_NEWEDITDEF + MENUITEM "&htmlDef", ID_GUIED_ITEM_NEWHTMLDEF + MENUITEM "&choiceDef", 5114 + MENUITEM "&sliderDef", 0 + MENUITEM "&bindDef", 5115 + MENUITEM "&listDef", 5116 + MENUITEM "&renderDef", 5118 + END + MENUITEM SEPARATOR + POPUP "&Arrange" + BEGIN + MENUITEM "Bring to &Front\tCtrl+Shift+]", + ID_GUIED_ITEM_ARRANGEBRINGTOFRONT + + MENUITEM "Bring F&orward\tCtrl+]", ID_GUIED_ITEM_ARRANGEBRINGFORWARD + + MENUITEM "Send to &Back\tCtrl+Shift+[", ID_GUIED_ITEM_ARRANGESENDTOBACK + + MENUITEM "Send B&ackward\tCtrl+[", ID_GUIED_ITEM_ARRANGESENDBACKWARD + + MENUITEM SEPARATOR + MENUITEM "&Make Child", 5093 + END + POPUP "A&lign" + BEGIN + MENUITEM "&Lefts\tCtrl+Left Arrow", ID_GUIED_ITEM_ALIGNLEFTS + MENUITEM "&Centers", ID_GUIED_ITEM_ALIGNCENTERS + + MENUITEM "&Rights\tCtrl+Right Arrow", ID_GUIED_ITEM_ALIGNRIGHTS + + MENUITEM SEPARATOR + MENUITEM "&Tops\tCtrl+Up Arrow", ID_GUIED_ITEM_ALIGNTOPS + MENUITEM "&Middles", ID_GUIED_ITEM_ALIGNMIDDLES + + MENUITEM "&Bottoms\tCtrl+Down Arrow", ID_GUIED_ITEM_ALIGNBOTTOMS + + END + POPUP "&Make Same Size" + BEGIN + MENUITEM "&Width", ID_GUIED_ITEM_MAKESAMESIZEWIDTH + + MENUITEM "&Height", ID_GUIED_ITEM_MAKESAMESIZEHEIGHT + + MENUITEM "&Both", ID_GUIED_ITEM_MAKESAMESIZEBOTH + + END + MENUITEM SEPARATOR + MENUITEM "&Scripts...\tCtrl+Enter", 5090 + MENUITEM "&Properties...\tAlt+Enter", ID_GUIED_ITEM_PROPERTIES + END + POPUP "&Tools" + BEGIN + MENUITEM "&Viewer\tCtrl+t", ID_GUIED_TOOLS_VIEWER + MENUITEM "Reload &Materials\tCtrl+m", ID_GUIED_TOOLS_RELOADMATERIALS + + END + POPUP "&Window" + BEGIN + MENUITEM "&Cascade", ID_GUIED_WINDOW_CASCADE + MENUITEM "&Tile", ID_GUIED_WINDOW_TILE + MENUITEM "Close &All", ID_GUIED_WINDOW_CLOSEALL + , GRAYED + MENUITEM SEPARATOR + MENUITEM "Show &Navigator", ID_GUIED_WINDOW_SHOWNAVIGATOR + + MENUITEM "Show &Transformer", ID_GUIED_WINDOW_SHOWTRANSFORMER + + MENUITEM "Show &Properties", ID_GUIED_WINDOW_SHOWPROPERTIES + + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_GUIED_HELP_ABOUT + END +END + +IDR_GUIED_ITEM_POPUP MENU +BEGIN + POPUP "NULL" + BEGIN + POPUP "&New" + BEGIN + MENUITEM "&windowDef", ID_GUIED_ITEM_NEWWINDOWDEF + + MENUITEM "&editDef", ID_GUIED_ITEM_NEWEDITDEF + MENUITEM "&htmlDef", 5112 + MENUITEM "&choiceDef", ID_GUIED_ITEM_NEWCHOICEDEF + + MENUITEM "&sliderDef", ID_GUIED_ITEM_NEWSLIDERDEF + + MENUITEM "&bindDef", ID_GUIED_ITEM_NEWBINDDEF + MENUITEM "&listDef", ID_GUIED_ITEM_NEWLISTDEF + MENUITEM "&renderDef", ID_GUIED_ITEM_NEWRENDERDEF + + END + MENUITEM SEPARATOR + POPUP "&Arrange" + BEGIN + MENUITEM "Bring to &Front\tCtrl+Shift+]", + ID_GUIED_ITEM_ARRANGEBRINGTOFRONT + + MENUITEM "Bring F&orward\tCtrl+]", ID_GUIED_ITEM_ARRANGEBRINGFORWARD + + MENUITEM "Send to &Back\tCtrl+Shift+[", ID_GUIED_ITEM_ARRANGESENDTOBACK + + MENUITEM "Send B&ackward\tCtrl+[", ID_GUIED_ITEM_ARRANGESENDBACKWARD + + MENUITEM SEPARATOR + MENUITEM "&Make Child", ID_GUIED_ITEM_ARRANGEMAKECHILD + + END + POPUP "A&lign" + BEGIN + MENUITEM "&Lefts\tCtrl+Left Arrow", ID_GUIED_ITEM_ALIGNLEFTS + MENUITEM "&Centers", ID_GUIED_ITEM_ALIGNCENTERS + + MENUITEM "&Rights\tCtrl+Right Arrow", ID_GUIED_ITEM_ALIGNRIGHTS + + MENUITEM SEPARATOR + MENUITEM "&Tops\tCtrl+Up Arrow", ID_GUIED_ITEM_ALIGNTOPS + MENUITEM "&Middles", ID_GUIED_ITEM_ALIGNMIDDLES + + MENUITEM "&Bottoms\tCtrl+Down Arrow", ID_GUIED_ITEM_ALIGNBOTTOMS + + END + POPUP "&Make Same Size" + BEGIN + MENUITEM "&Width", ID_GUIED_ITEM_MAKESAMESIZEWIDTH + + MENUITEM "&Height", ID_GUIED_ITEM_MAKESAMESIZEHEIGHT + + MENUITEM "&Both", ID_GUIED_ITEM_MAKESAMESIZEBOTH + + END + MENUITEM SEPARATOR + MENUITEM "&Scripts...\tCtrl+Enter", ID_GUIED_ITEM_SCRIPTS + MENUITEM "&Properties...\tAlt+Enter", ID_GUIED_ITEM_PROPERTIES + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_GUIED_ABOUT DIALOGEX 0, 0, 222, 71 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "About GUI Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "GUI Editor",IDC_STATIC,35,7,62,8 + LTEXT "Version 0.15",IDC_STATIC,35,17,41,8 + LTEXT "Original version by Raven",IDC_STATIC,35, + 28,134,8 + DEFPUSHBUTTON "OK",IDOK,165,50,50,14 + ICON IDI_GUIED,IDC_STATIC,7,7,20,20 +END + +IDD_GUIED_OPTIONS_GRID DIALOGEX 0, 0, 221, 119 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_NOFAILCREATE | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Color:",IDC_STATIC,147,41,46,8 + CONTROL "Button1",IDC_GUIED_GRIDCOLOR,"Button",BS_OWNERDRAW | + WS_TABSTOP,145,51,50,14 + GROUPBOX "Spacing",IDC_STATIC,7,41,128,53 + LTEXT "&Width:",IDC_STATIC,15,57,27,8 + LTEXT "&Height:",IDC_STATIC,15,74,29,8 + EDITTEXT IDC_GUIED_SPACINGWIDTH,44,54,38,14,ES_AUTOHSCROLL | + ES_NUMBER + EDITTEXT IDC_GUIED_SPACINGHEIGHT,44,73,38,14,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "&Show Grid",IDC_GUIED_GRIDVISIBLE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,7,106,10 + CONTROL "S&nap To Grid",IDC_GUIED_GRIDSNAP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,21,106,10 +END + +IDD_GUIED_ITEMPROPS_GENERAL DIALOGEX 0, 0, 243, 217 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Name:",IDC_STATIC,7,7,22,8 + EDITTEXT IDC_GUIED_ITEMNAME,7,17,107,13,ES_AUTOHSCROLL | WS_GROUP + CONTROL "&Visible",IDC_GUIED_ITEMVISIBLE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,21,55,41,10 + CONTROL "No &Events",IDC_GUIED_ITEMNOEVENTS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,21,70,49,10 + CONTROL "No &Time",IDC_GUIED_ITEMNOTIME,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,92,55,41,10 + CONTROL "No &Clip",IDC_GUIED_ITEMNOCLIP,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,92,69,38,10 + GROUPBOX "States",IDC_STATIC,7,39,229,53 + CONTROL "No C&ursor",IDC_GUIED_ITEMNOCURSOR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,157,55,48,10 + LTEXT "T&ype:",IDC_STATIC,126,7,20,8 + EDITTEXT IDC_GUIED_TYPE,125,17,107,13,ES_AUTOHSCROLL | + ES_READONLY | WS_GROUP | NOT WS_TABSTOP +END + +IDD_GUIED_OPTIONS_GENERAL DIALOGEX 0, 0, 230, 137 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Button1",IDC_GUIED_SELECTIONCOLOR,"Button",BS_OWNERDRAW | + WS_TABSTOP,7,17,50,14 + LTEXT "&Selection Color:",IDC_STATIC,7,7,51,8 + CONTROL "&Ignore Desktop Select",IDC_GUIED_IGNOREDESKTOP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,41,147,10 +END + +IDD_GUIED_ITEMKEY DIALOGEX 0, 0, 266, 49 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Modify Item Key" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Key:",IDC_STATIC,7,10,16,8 + EDITTEXT IDC_GUIED_ITEMKEY,29,7,169,14,ES_AUTOHSCROLL + LTEXT "&Value:",IDC_STATIC,7,31,21,8 + EDITTEXT IDC_GUIED_ITEMVALUE,29,28,170,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,209,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,209,24,50,14 +END + +IDD_GUIED_ALPHA DIALOGEX 0, 0, 160, 17 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_GUIED_ALPHA,129,2,28,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE + CONTROL "Custom1",IDC_GUIED_ALPHASLIDER,"GUIED_ALPHASLIDER", + WS_TABSTOP,2,2,125,13 +END + +IDD_GUIED_SCRIPTS DIALOGEX 0, 0, 448, 215 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +CAPTION "Item Scripts" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_GUIED_SCRIPT,"RichEdit20A",ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,7,7,434, + 201 +END + +IDD_GUIED_ITEMPROPS_KEYS DIALOGEX 0, 0, 240, 212 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_GUIED_ITEMKEYS,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | + WS_BORDER | WS_TABSTOP,7,25,226,180 + PUSHBUTTON "&Add",IDC_GUIED_ADDKEY,103,7,40,14 + PUSHBUTTON "&Edit",IDC_GUIED_EDITKEY,148,7,40,14 + PUSHBUTTON "&Delete",IDC_GUIED_DELETEKEY,193,7,40,14 +END + +IDD_GUIED_ITEM_VARIABLES DIALOGEX 0, 0, 240, 209 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Item Variables" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_GUIED_ITEMVARIABLES,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | + WS_BORDER | WS_TABSTOP,7,7,181,193 + PUSHBUTTON "&Add",IDC_GUIED_ADDVARIABLE,193,7,40,14 + PUSHBUTTON "&Edit",IDC_GUIED_EDITVARIABLE,193,26,40,14 + PUSHBUTTON "&Delete",IDC_GUIED_DELETEVARIABLE,193,45,40,14 + PUSHBUTTON "OK",IDOK,193,163,40,14 +END + +IDD_GUIED_ITEMPROPS_TEXT DIALOGEX 0, 0, 238, 217 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "&Text:",IDC_GUIED_USETEXT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,7,33,10 + EDITTEXT IDC_GUIED_ITEMTEXT,7,19,224,32,ES_AUTOHSCROLL + LTEXT "&Font:",IDC_GUIED_STATIC_FONT,8,58,18,8 + COMBOBOX IDC_GUIED_ITEMTEXTFONT,7,69,105,71,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "&Scale:",IDC_GUIED_STATIC_SCALE,126,58,20,8 + EDITTEXT IDC_GUIED_ITEMTEXTSCALE,124,69,38,12,ES_AUTOHSCROLL + CONTROL "",IDC_GUIED_ITEMTEXTSCALE_SPIN,"msctls_updown32", + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,155,69,11, + 14 + LTEXT "&Color:",IDC_GUIED_STATIC_COLOR,180,58,20,8 + CONTROL "Button1",IDC_GUIED_ITEMFORECOLOR,"Button",BS_OWNERDRAW | + WS_GROUP | WS_TABSTOP,178,69,32,14 + CONTROL "Button1",IDC_GUIED_ITEMFORECOLORALPHA,"Button", + BS_OWNERDRAW | WS_TABSTOP,211,69,19,14 + LTEXT "&Alignment:",IDC_GUIED_STATIC_ALIGNMENT,8,98,35,8 + COMBOBOX IDC_GUIED_ITEMTEXTALIGN,47,95,58,71,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "&X:",IDC_GUIED_STATIC_X,113,98,8,8 + EDITTEXT IDC_GUIED_ITEMTEXTALIGNX,121,95,45,12,ES_AUTOHSCROLL + LTEXT "&Y:",IDC_GUIED_STATIC_Y,178,98,8,8 + EDITTEXT IDC_GUIED_ITEMTEXTALIGNY,186,95,45,12,ES_AUTOHSCROLL + CONTROL "&No Wrap",IDC_GUIED_ITEMTEXTNOWRAP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,121,44,10 +END + +IDD_GUIED_ITEMPROPS_IMAGE DIALOGEX 0, 0, 243, 233 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Background",IDC_STATIC,7,7,229,93 + CONTROL "&Backcolor:",IDC_GUIED_USEBACKCOLOR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,19,22,49,10 + CONTROL "Button1",IDC_GUIED_ITEMBACKCOLOR,"Button",BS_OWNERDRAW | + WS_TABSTOP,68,20,32,14 + CONTROL "Button1",IDC_GUIED_ITEMBACKCOLORALPHA,"Button", + BS_OWNERDRAW | WS_TABSTOP,100,20,19,14 + CONTROL "&Material:",IDC_GUIED_USEMATERIAL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,19,44,44,10 + EDITTEXT IDC_GUIED_ITEMBACKGROUND,77,42,152,14,ES_AUTOHSCROLL + LTEXT "&X Scale:",IDC_GUIED_XSCALE_STATIC,78,62,26,8 + EDITTEXT IDC_GUIED_ITEMMATSCALEX,105,60,42,13,ES_AUTOHSCROLL + LTEXT "&Y Scale:",IDC_GUIED_YSCALE_STATIC,160,62,26,8 + EDITTEXT IDC_GUIED_ITEMMATSCALEY,187,60,42,13,ES_AUTOHSCROLL + CONTROL "&Disable Cache",IDC_GUIED_ITEMVARIABLEBACKGROUND,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,77,79,61,10 + GROUPBOX "Border",IDC_STATIC,7,105,229,78 + LTEXT "&Size:",IDC_STATIC,19,119,16,8 + EDITTEXT IDC_GUIED_ITEMBORDERSIZE,38,118,39,13,ES_AUTOHSCROLL + CONTROL "&Color:",IDC_GUIED_USEBORDERCOLOR,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,19,143,35,10 + CONTROL "Button1",IDC_GUIED_ITEMBORDERCOLOR,"Button", + BS_OWNERDRAW | WS_GROUP | WS_TABSTOP,68,140,32,14 + CONTROL "Button1",IDC_GUIED_ITEMBORDERCOLORALPHA,"Button", + BS_OWNERDRAW | WS_TABSTOP,100,140,19,14 + CONTROL "&Material",IDC_GUIED_USEBORDERMATERIAL,"Button", + BS_AUTORADIOBUTTON,19,163,41,10 + EDITTEXT IDC_GUIED_ITEMBORDERMATERIAL,77,161,151,14, + ES_AUTOHSCROLL + GROUPBOX "General",IDC_STATIC,7,189,229,37 + LTEXT "Ma&tcolor:",IDC_GUIED_ITEMMATCOLORSTATIC,19,205,31,8 + CONTROL "Button1",IDC_GUIED_ITEMMATCOLOR,"Button",BS_OWNERDRAW | + WS_TABSTOP,55,202,32,14 + CONTROL "Button1",IDC_GUIED_ITEMMATCOLORALPHA,"Button", + BS_OWNERDRAW | WS_TABSTOP,87,202,19,14 +END + +IDD_GUIED_TRANSFORMER DIALOGEX 0, 0, 124, 32 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "X:",IDC_STATIC,6,3,8,8 + EDITTEXT IDC_GUIED_ITEMRECTX,14,2,43,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE + LTEXT "Y:",IDC_STATIC,6,19,8,8 + EDITTEXT IDC_GUIED_ITEMRECTY,14,17,43,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE + LTEXT "W:",IDC_STATIC,64,3,10,8 + EDITTEXT IDC_GUIED_ITEMRECTW,73,2,43,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE + LTEXT "H:",IDC_STATIC,65,19,8,8 + EDITTEXT IDC_GUIED_ITEMRECTH,73,17,43,12,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_STATICEDGE +END + +IDD_GUIED_CHECKIN DIALOGEX 0, 0, 250, 137 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Check In" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Filename:",IDC_STATIC,7,7,33,8 + EDITTEXT IDC_GUIED_FILENAME,7,16,236,14,ES_AUTOHSCROLL | + ES_READONLY | NOT WS_TABSTOP + LTEXT "&Comment:",IDC_STATIC,7,37,33,8 + EDITTEXT IDC_GUIED_COMMENT,7,46,236,60,ES_MULTILINE | + ES_AUTOHSCROLL | ES_WANTRETURN + DEFPUSHBUTTON "OK",IDOK,129,116,50,14 + PUSHBUTTON "Cancel",IDCANCEL,193,116,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_GUIED_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_GUIED_OPTIONS_GRID, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 214 + TOPMARGIN, 7 + BOTTOMMARGIN, 112 + END + + IDD_GUIED_ITEMPROPS_GENERAL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 236 + TOPMARGIN, 7 + BOTTOMMARGIN, 210 + END + + IDD_GUIED_OPTIONS_GENERAL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 223 + TOPMARGIN, 7 + BOTTOMMARGIN, 130 + END + + IDD_GUIED_ITEMKEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 259 + TOPMARGIN, 7 + BOTTOMMARGIN, 42 + END + + IDD_GUIED_ALPHA, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 157 + TOPMARGIN, 2 + BOTTOMMARGIN, 15 + END + + IDD_GUIED_SCRIPTS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 441 + TOPMARGIN, 7 + BOTTOMMARGIN, 208 + END + + IDD_GUIED_ITEMPROPS_KEYS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 233 + TOPMARGIN, 7 + BOTTOMMARGIN, 205 + END + + IDD_GUIED_ITEM_VARIABLES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 233 + TOPMARGIN, 7 + BOTTOMMARGIN, 201 + END + + IDD_GUIED_ITEMPROPS_TEXT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 231 + TOPMARGIN, 7 + BOTTOMMARGIN, 210 + END + + IDD_GUIED_ITEMPROPS_IMAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 236 + TOPMARGIN, 7 + BOTTOMMARGIN, 226 + END + + IDD_GUIED_TRANSFORMER, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 120 + TOPMARGIN, 2 + BOTTOMMARGIN, 29 + END + + IDD_GUIED_CHECKIN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 130 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_GUIED_ACCELERATORS ACCELERATORS +BEGIN + "C", ID_GUIED_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_GUIED_EDIT_DELETE, VIRTKEY, NOINVERT + "V", ID_GUIED_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + "Y", ID_GUIED_EDIT_REDO, VIRTKEY, CONTROL, NOINVERT + "Z", ID_GUIED_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT + "N", ID_GUIED_FILE_NEW, VIRTKEY, CONTROL, NOINVERT + "O", ID_GUIED_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "S", ID_GUIED_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, ID_GUIED_ITEM_ALIGNBOTTOMS, VIRTKEY, CONTROL, NOINVERT + VK_LEFT, ID_GUIED_ITEM_ALIGNLEFTS, VIRTKEY, CONTROL, NOINVERT + VK_RIGHT, ID_GUIED_ITEM_ALIGNRIGHTS, VIRTKEY, CONTROL, NOINVERT + VK_UP, ID_GUIED_ITEM_ALIGNTOPS, VIRTKEY, CONTROL, NOINVERT + VK_OEM_6, ID_GUIED_ITEM_ARRANGEBRINGFORWARD, VIRTKEY, CONTROL, + NOINVERT + VK_OEM_6, ID_GUIED_ITEM_ARRANGEBRINGTOFRONT, VIRTKEY, SHIFT, + CONTROL, NOINVERT + VK_OEM_4, ID_GUIED_ITEM_ARRANGESENDBACKWARD, VIRTKEY, CONTROL, + NOINVERT + VK_OEM_4, ID_GUIED_ITEM_ARRANGESENDTOBACK, VIRTKEY, SHIFT, CONTROL, + NOINVERT + VK_RETURN, ID_GUIED_ITEM_PROPERTIES, VIRTKEY, ALT, NOINVERT + VK_RETURN, ID_GUIED_ITEM_SCRIPTS, VIRTKEY, CONTROL, NOINVERT + "T", ID_GUIED_TOOLS_VIEWER, VIRTKEY, CONTROL, NOINVERT + "H", ID_GUIED_VIEW_HIDESELECTED, VIRTKEY, NOINVERT + VK_OEM_7, ID_GUIED_VIEW_SHOWGRID, VIRTKEY, CONTROL, NOINVERT + "H", ID_GUIED_VIEW_SHOWHIDDEN, VIRTKEY, SHIFT, NOINVERT + VK_OEM_7, ID_GUIED_VIEW_SNAPTOGRID, VIRTKEY, SHIFT, CONTROL, + NOINVERT + "U", ID_GUIED_VIEW_UNHIDESELECTED, VIRTKEY, NOINVERT + VK_OEM_PLUS, ID_GUIED_VIEW_ZOOMIN, VIRTKEY, CONTROL, NOINVERT + VK_OEM_MINUS, ID_GUIED_VIEW_ZOOMOUT, VIRTKEY, CONTROL, NOINVERT + "M", ID_GUIED_TOOLS_RELOADMATERIALS, VIRTKEY, CONTROL, + NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_GUIED_NAV_VISIBLE ICON "res\\guied_nav_visible.ico" +IDI_GUIED_NAV_SCRIPTS ICON "res\\guied_scripts.ico" +IDI_GUIED ICON "res\\guied.ico" +IDI_GUIED_NAV_VISIBLEDISABLED ICON "res\\guied_nav_visibledisabled.ico" +IDI_GUIED_NAV_SCRIPTSHI ICON "res\\guied_scripts_white.ico" +IDI_GUIED_NAV_COLLAPSE ICON "res\\guied_collapse.ico" +IDI_GUIED_NAV_EXPAND ICON "res\\guied_expand.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_GUIED_ITEMPROPS_TEXT DLGINIT +BEGIN + IDC_GUIED_ITEMTEXTFONT, 0x403, 10, 0 +0x643c, 0x6665, 0x7561, 0x746c, 0x003e, + IDC_GUIED_ITEMTEXTFONT, 0x403, 7, 0 +0x7473, 0x6f72, 0x6767, "\000" + IDC_GUIED_ITEMTEXTFONT, 0x403, 6, 0 +0x6863, 0x6961, 0x006e, + IDC_GUIED_ITEMTEXTALIGN, 0x403, 5, 0 +0x654c, 0x7466, "\000" + IDC_GUIED_ITEMTEXTALIGN, 0x403, 7, 0 +0x6543, 0x746e, 0x7265, "\000" + IDC_GUIED_ITEMTEXTALIGN, 0x403, 6, 0 +0x6952, 0x6867, 0x0074, + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_GUIED_VIEWERTOOLBAR TOOLBAR 16, 15 +BEGIN + BUTTON ID_GUIED_VIEWER_PLAY + BUTTON ID_GUIED_VIEWER_PAUSE + BUTTON ID_GUIED_VIEWER_START +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_GUIED_VIEWERTOOLBAR BITMAP "res\\guied_viewer_toolbar.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_GUIED_HAND CURSOR "res\\guied_hand.cur" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/GuiEd_resource.h b/sys/win32/rc/GuiEd_resource.h new file mode 100644 index 000000000..2b3c6b92c --- /dev/null +++ b/sys/win32/rc/GuiEd_resource.h @@ -0,0 +1,198 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_GUIED_ABOUT 5000 +#define IDD_GUIED_OPTIONS_GRID 5001 +#define IDD_GUIED_OPTIONS_GENERAL 5002 +#define IDD_GUIED_ITEMPROPS_GENERAL 5003 +#define IDD_GUIED_ITEMPROPS_ADVANCED 5004 +#define IDD_GUIED_ITEMKEY 5005 +#define IDD_GUIED_ALPHA 5006 +#define IDD_GUIED_SCRIPTS 5007 +#define IDD_GUIED_ITEMPROPS_KEYS 5008 +#define IDD_GUIED_ITEM_VARIABLES 5009 +#define IDD_GUIED_ITEMPROPS_TEXT 5010 +#define IDD_GUIED_ITEMPROPS_IMAGE 5011 +#define IDD_GUIED_TRANSFORMER 5012 +#define IDD_GUIED_CHECKIN 5013 +#define IDR_GUIED_MAIN 5014 +#define IDR_GUIED_ACCELERATORS 5015 +#define IDR_GUIED_ITEM_POPUP 5016 +#define IDR_GUIED_VIEWERTOOLBAR 5017 +#define IDI_GUIED 5018 +#define IDI_GUIED_NAV_VISIBLE 5019 +#define IDI_GUIED_NAV_SCRIPTS 5020 +#define IDI_GUIED_NAV_VISIBLEDISABLED 5021 +#define IDI_GUIED_NAV_SCRIPTSHI 5022 +#define IDI_GUIED_NAV_COLLAPSE 5023 +#define IDI_GUIED_NAV_EXPAND 5024 + +#define IDC_GUIED_OPTIONSTAB 5200 +#define IDC_GUIED_GRIDCOLOR 5201 +#define IDC_GUIED_SPACINGWIDTH 5202 +#define IDC_GUIED_SPACINGHEIGHT 5203 +#define IDC_GUIED_GRIDVISIBLE 5204 +#define IDC_GUIED_GRIDSNAP 5205 +#define IDC_GUIED_WINDOWTREE 5206 +#define IDC_GUIED_ITEMNAME 5207 +#define IDC_GUIED_ITEMBACKGROUND 5208 +#define IDC_GUIED_TYPE 5209 +#define IDC_GUIED_USEMATERIAL 5210 +#define IDC_GUIED_ITEMBORDERMATERIAL 5211 +#define IDC_GUIED_ITEMBACKCOLOR 5212 +#define IDC_GUIED_ITEMMATCOLOR 5213 +#define IDC_GUIED_ITEMFORECOLOR 5214 +#define IDC_GUIED_ITEMBORDERCOLOR 5215 +#define IDC_GUIED_ITEMBACKCOLORALPHA 5216 +#define IDC_GUIED_ITEMTEXT 5217 +#define IDC_GUIED_ITEMBORDERCOLORALPHA 5218 +#define IDC_GUIED_ITEMTEXTSCALE 5219 +#define IDC_GUIED_ITEMBORDERSIZE 5220 +#define IDC_GUIED_ITEMMATCOLORALPHA 5221 +#define IDC_GUIED_ITEMTEXTALIGNX 5222 +#define IDC_GUIED_ITEMTEXTALIGNY 5223 +#define IDC_GUIED_ITEMMATSCALEX 5224 +#define IDC_GUIED_ITEMMATSCALEY 5225 +#define IDC_GUIED_USEBACKCOLOR 5226 +#define IDC_GUIED_ITEMMATCOLORSTATIC 5227 +#define IDC_GUIED_ITEMKEYS 5228 +#define IDC_GUIED_ADDKEY 5229 +#define IDC_GUIED_EDITKEY 5230 +#define IDC_GUIED_DELETEKEY 5231 +#define IDC_GUIED_ITEMKEY 5232 +#define IDC_GUIED_ITEMVALUE 5233 +#define IDC_GUIED_ITEMVISIBLE 5234 +#define IDC_GUIED_SELECTIONCOLOR 5235 +#define IDC_GUIED_ALPHA 5236 +#define IDC_GUIED_ALPHASLIDER 5237 +#define IDC_GUIED_SCRIPT 5238 +#define IDC_GUIED_ADDVARIABLE 5239 +#define IDC_GUIED_EDITVARIABLE 5240 +#define IDC_GUIED_DELETEVARIABLE 5241 +#define IDC_GUIED_ITEMVARIABLES 5242 +#define IDC_GUIED_USETEXT 5243 +#define IDC_GUIED_ITEMTEXTALIGN 5244 +#define IDC_GUIED_STATIC_ALIGNMENT 5245 +#define IDC_GUIED_STATIC_X 5246 +#define IDC_GUIED_STATIC_Y 5247 +#define IDC_GUIED_ITEMFORECOLORALPHA 5248 +#define IDC_GUIED_STATIC_SCALE 5249 +#define IDC_GUIED_STATIC_COLOR 5250 +#define IDC_GUIED_USEBORDERCOLOR 5251 +#define IDC_GUIED_STATIC_FONT 5252 +#define IDC_GUIED_USEBORDERMATERIAL 5253 +#define IDC_GUIED_ITEMTEXTFONT 5254 +#define IDC_GUIED_STATIC_FONTSIZE 5255 +#define IDC_GUIED_ITEMVARIABLEBACKGROUND 5256 +#define IDC_GUIED_ITEMTEXTFONTSIZE 5257 +#define IDC_GUIED_XSCALE_STATIC 5258 +#define IDC_GUIED_YSCALE_STATIC 5259 +#define IDC_GUIED_ITEMNOEVENTS 5260 +#define IDC_GUIED_ITEMNOCLIP 5261 +#define IDC_GUIED_ITEMNOCLIP2 5262 +#define IDC_GUIED_ITEMNOCURSOR 5263 +#define IDC_GUIED_ITEMNOTIME 5264 +#define IDC_GUIED_ITEMRECTX 5265 +#define IDC_GUIED_ITEMRECTW 5266 +#define IDC_GUIED_IGNOREDESKTOP 5267 +#define IDC_GUIED_ITEMRECTH 5268 +#define IDC_GUIED_ITEMTEXTNOWRAP 5269 +#define IDC_GUIED_ITEMRECTY 5270 +#define IDC_GUIED_FILENAME 5271 +#define IDC_GUIED_COMMENT 5272 +#define IDC_GUIED_ITEMTEXTSCALE_SPIN 5273 +#define IDC_GUIED_HAND 5274 + +#define ID_GUIED_NEW_HTMLDEF 25000 +#define ID_GUIED_ITEM_NEWSLIDERDEF 25001 +#define ID_GUIED_FILE_EXIT 25002 +#define ID_GUIED_HELP_ABOUT 25003 +#define ID_GUIED_WINDOW_CLOSEALL 25004 +#define ID_GUIED_FILE_NEW 25005 +#define ID_GUIED_FILE_OPEN 25006 +#define ID_GUIED_FILE_CLOSE 25007 +#define ID_GUIED_VIEW_ZOOMIN 25008 +#define ID_GUIED_VIEW_ZOOMOUT 25009 +#define ID_GUIED_FILE_SAVE 25010 +#define ID_GUIED_FILE_SAVEAS 25011 +#define ID_GUIED_VIEW_SHOWGRID 25012 +#define ID_GUIED_VIEW_SNAPTOGRID 25013 +#define ID_GUIED_VIEW_GRIDSETTINGS 25014 +#define ID_GUIED_EDIT_CUT 25015 +#define ID_GUIED_EDIT_COPY 25016 +#define ID_GUIED_EDIT_PASTE 25017 +#define ID_GUIED_VIEW_OPTIONS 25018 +#define ID_GUIED_EDIT_REDO 25019 +#define ID_GUIED_VIEW_HIDESELECTED 25020 +#define ID_GUIED_VIEW_SHOWHIDDEN 25021 +#define ID_GUIED_EDIT_UNDO 25022 +#define ID_GUIED_EDIT_DELETE 25023 +#define ID_GUIED_WINDOW_TILE 25024 +#define ID_GUIED_WINDOW_SHOWNAVIGATOR 25025 +#define ID_GUIED_FILE_MRU 25026 +#define ID_GUIED_ITEM_NEWEDITDEF 25027 +#define ID_GUIED_ITEM_NEWSCRIPTDEF 25028 +#define ID_GUIED_ITEM_PROPERTIES 25029 +#define ID_GUIED_ITEM_ARRANGEBRINGFORWARD 25030 +#define ID_GUIED_ITEM_ARRANGESENDTOBACK 25031 +#define ID_GUIED_ITEM_ARRANGESENDBACKWARD 25032 +#define ID_GUIED_ITEM_ARRANGEBRINGTOFRONT 25033 +#define ID_GUIED_ITEM_ALIGNLEFTS 25034 +#define ID_GUIED_ITEM_ALIGNCENTERS 25035 +#define ID_GUIED_ITEM_ALIGNRIGHTS 25036 +#define ID_GUIED_ITEM_ALIGNTOPS 25037 +#define ID_GUIED_ITEM_ALIGNMIDDLES 25038 +#define ID_GUIED_ITEM_ALIGNBOTTOMS 25039 +#define ID_GUIED_ITEM_MAKESAMESIZEWIDTH 25040 +#define ID_GUIED_ITEM_MAKESAMESIZEHEIGHT 25041 +#define ID_GUIED_ITEM_MAKESAMESIZEBOTH 25042 +#define ID_GUIED_ITEM_SCRIPTS 25043 +#define ID_GUIED_ITEM_ARRANGEMAKECHILD 25044 +#define ID_GUIED_TOOLS_VIEWER 25045 +#define ID_GUIED_WINDOW_CASCADE 25046 +#define ID_GUIED_ITEM_NEWWINDOWDEF 25047 +#define ID_GUIED_VIEW_UNHIDESELECTED 25048 +#define ID_GUIED_WINDOW_SHOWTRANSFORMER 25049 +#define ID_GUIED_TOOLS_RELOADMATERIALS 25050 +#define ID_GUIED_SOURCECONTROL_CHECKIN 25051 +#define ID_GUIED_SOURCECONTROL_CHECKOUT 25052 +#define ID_GUIED_SOURCECONTROL_UNDOCHECKOUT 25053 +#define ID_GUIED_SOURCECONTROL_GETLATESTVERSION 25054 +#define ID_GUIED_ITEM_NEWHTMLDEF 25055 +#define ID_GUIED_VIEW_STATUSBAR 25056 +#define ID_GUIED_ITEM_NEWCHOICEDEF 25057 +#define ID_GUIED_ITEM_NEWBINDDEF 25058 +#define ID_GUIED_ITEM_NEWLISTDEF 25059 +#define ID_GUIED_WINDOW_SHOWPROPERTIES 25060 +#define ID_GUIED_ITEM_NEWRENDERDEF 25061 +#define ID_GUIED_VIEWER_PAUSE 25062 +#define ID_GUIED_VIEWER_PLAY 25063 +#define ID_GUIED_VIEWER_START 25064 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 5025 +#define _APS_NEXT_COMMAND_VALUE 25065 +#define _APS_NEXT_CONTROL_VALUE 5275 +#define _APS_NEXT_SYMED_VALUE 5025 +#endif +#endif diff --git a/sys/win32/rc/MaterialEditor.rc b/sys/win32/rc/MaterialEditor.rc new file mode 100644 index 000000000..13434049d --- /dev/null +++ b/sys/win32/rc/MaterialEditor.rc @@ -0,0 +1,387 @@ +// Microsoft Visual C++ generated resource script. +// +#include "MaterialEditor_Resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "MaterialEditor_Resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ME_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END + + IDD_CONSOLE_FORM, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 428 + TOPMARGIN, 7 + BOTTOMMARGIN, 267 + END + + IDD_FIND, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 243 + TOPMARGIN, 7 + BOTTOMMARGIN, 75 + END + + IDD_MATERIALEDIT_FORM, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 172 + TOPMARGIN, 7 + BOTTOMMARGIN, 82 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ME_ABOUTBOX DIALOGEX 0, 0, 186, 95 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + +IDD_CONSOLE_FORM DIALOGEX 0, 0, 435, 274 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_CONSOLE_OUTPUT,7,7,421,242,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VSCROLL + EDITTEXT IDC_CONSOLE_EDIT,7,250,421,17,ES_AUTOHSCROLL +END + +IDD_FIND DIALOGEX 0, 0, 250, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Find" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Find What:",IDC_STATIC,12,6,52,18,SS_CENTERIMAGE + EDITTEXT IDC_EDIT_FINDTEXT,52,7,122,15,ES_AUTOHSCROLL + GROUPBOX "Search",IDC_STATIC,12,30,162,42 + CONTROL "Current File",IDC_RADIO_SEARCHFILE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,24,42,53,10 + CONTROL "All Files",IDC_RADIO_SEARCHALL,"Button", + BS_AUTORADIOBUTTON,24,54,39,10 + CONTROL "Search Name Only",IDC_CHECK_NAME_ONLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,90,42,75,9 + DEFPUSHBUTTON "Find Next",ID_FIND_NEXT,193,7,50,14 + PUSHBUTTON "Close",IDCANCEL,193,25,50,14 +END + +IDD_MATERIALEDIT_FORM DIALOGEX 0, 0, 179, 89 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_MATERIALEDITOR_EDIT_TEXT,"RichEdit20A", + ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,7,7,57, + 36 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_ME_MAINFRAME ICON "res\\MaterialEditor.ico" +IDI_ME_ON_ICON ICON "res\\me_on_icon.ico" +IDI_ME_OFF_ICON ICON "res\\me_off_icon.ico" +IDI_ME_DISABLED_ICON ICON "res\\me_disabled_icon.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_ME_MAINFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "Save &Material", ID_ME_FILE_SAVEMATERIAL + MENUITEM "Save &File\tCtrl-S", ID_ME_FILE_SAVEFILE + MENUITEM "&Save All", ID_ME_FILE_SAVE + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_ME_FILE_EXIT + END + POPUP "Edit" + BEGIN + MENUITEM "Undo\tCtrl-Z", ID_ME_EDIT_UNDO + MENUITEM "Redo\tCtrl-Y", ID_ME_EDIT_REDO + MENUITEM SEPARATOR + MENUITEM "Cut\tCtrl-x", ID_ME_EDIT_CUT + MENUITEM "Copy\tCtrl-C", ID_ME_EDIT_COPY + MENUITEM "Paste\tCtrl-V", ID_ME_EDIT_PASTE + MENUITEM "Delete\tDel", ID_ME_EDIT_DELETE + MENUITEM "Rename\tF2", ID_ME_EDIT_RENAME + MENUITEM SEPARATOR + MENUITEM "Find\tCtrl-F", ID_ME_EDIT_FIND + END + POPUP "&Material View" + BEGIN + MENUITEM "&Include Filename", ID_VIEW_INCLUDEFILENAME + , CHECKED + END + POPUP "&Preview" + BEGIN + MENUITEM "Apply Material\tCtrl-A", ID_ME_PREVIEW_APPLYCHANGES + MENUITEM "Apply File", ID_ME_PREVIEW_APPLYFILE + MENUITEM "Apply All", ID_ME_PREVIEW_APPLYALL + MENUITEM SEPARATOR + MENUITEM "&Reload ARB Programs\tCtrl-R", + ID_PREVIEW_RELOADARBPROGRAMS + MENUITEM "Reload Images\tCtrl-I", ID_PREVIEW_RELOADIMAGES + END +END + +IDR_ME_MATERIALTREE_POPUP MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "Apply Material", ID_POPUP_APPLYMATERIAL + MENUITEM "Apply File", ID_POPUP_APPLYFILE + MENUITEM "Apply All", ID_POPUP_APPLYALL + MENUITEM SEPARATOR + MENUITEM "Save Material", ID_POPUP_SAVEMATERIAL + MENUITEM "Save File", ID_POPUP_SAVEFILE + MENUITEM "Save All", ID_POPUP_SAVEALL + MENUITEM SEPARATOR + MENUITEM "Cut", ID_POPUP_CUT + MENUITEM "Copy", ID_POPUP_COPY + MENUITEM "Paste", ID_POPUP_PASTE + MENUITEM "Delete", ID_POPUP_DELETEMATERIAL + MENUITEM SEPARATOR + MENUITEM "Add Material", ID_POPUP_ADDMATERIAL + MENUITEM "Add Folder", ID_POPUP_ADDFOLDER + MENUITEM "Rename", ID_POPUP_RENAMEMATERIAL + MENUITEM SEPARATOR + MENUITEM "Reload File", ID_POPUP_RELOADFILE + END + POPUP "Popup2" + BEGIN + MENUITEM "Apply File", ID_POPUP_APPLYFILE + MENUITEM "Apply All", ID_POPUP_APPLYALL + MENUITEM SEPARATOR + MENUITEM "Save File", ID_POPUP_SAVEFILE + MENUITEM "Save All", ID_POPUP_SAVEALL + END + POPUP "Popup3" + BEGIN + MENUITEM "Apply All", ID_POPUP_APPLYALL + MENUITEM SEPARATOR + MENUITEM "Save All", ID_POPUP_SAVEALL + END +END + +IDR_ME_STAGELIST_POPUP MENU +BEGIN + POPUP "Stage Popup" + BEGIN + MENUITEM "Rename", ID_STAGEPOPUP_RENAMESTAGE + MENUITEM "Add", ID_STAGEPOPUP_ADDSTAGE + MENUITEM "Add Bumpmap Stage", ID_STAGEPOPUP_ADDBUMPMAP + MENUITEM "Add Diffuse Stage", ID_STAGEPOPUP_ADDDIFFUSEMAP + MENUITEM "Add Specular Stage", ID_STAGEPOPUP_ADDSPECULAR + MENUITEM SEPARATOR + MENUITEM "Copy", ID_STAGEPOPUP_COPY + MENUITEM "Paste", ID_STAGEPOPUP_PASTE + MENUITEM "Delete", ID_STAGEPOPUP_DELETESTAGE + MENUITEM "Delete All Stages", ID_STAGEPOPUP_DELETEALLSTAGES + + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_ME_MAINFRAME TOOLBAR 16, 15 +BEGIN + BUTTON ID_ME_FILE_SAVEMATERIAL + BUTTON ID_ME_FILE_SAVEFILE + BUTTON ID_ME_FILE_SAVE + SEPARATOR + BUTTON ID_ME_EDIT_UNDO + BUTTON ID_ME_EDIT_REDO + SEPARATOR + BUTTON ID_ME_EDIT_CUT + BUTTON ID_ME_EDIT_COPY + BUTTON ID_ME_EDIT_PASTE + BUTTON ID_ME_EDIT_DELETE + BUTTON ID_ME_EDIT_RENAME + BUTTON ID_ME_EDIT_FIND + BUTTON ID_ME_EDIT_FIND_NEXT + SEPARATOR + BUTTON ID_ME_PREVIEW_APPLYCHANGES + BUTTON ID_ME_PREVIEW_APPLYFILE + BUTTON ID_ME_PREVIEW_APPLYALL + SEPARATOR + BUTTON ID_PREVIEW_RELOADARBPROGRAMS + BUTTON ID_PREVIEW_RELOADIMAGES +END + +IDR_ME_FILETOOLBAR TOOLBAR 16, 15 +BEGIN + BUTTON ID_ME_FILE_SAVEMATERIAL + BUTTON ID_ME_FILE_SAVEFILE + BUTTON ID_ME_FILE_SAVE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_ME_MAINFRAME BITMAP "res\\MEtoolbar.bmp" +IDB_ME_TREEBITMAP BITMAP "res\\matedtree.bmp" +IDR_ME_FILETOOLBAR BITMAP "res\\MEFileToolbar.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ME_MAINFRAME ACCELERATORS +BEGIN + "F", ID_ME_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT + VK_F3, ID_ME_EDIT_FIND_NEXT, VIRTKEY, NOINVERT + "Y", ID_ME_EDIT_REDO, VIRTKEY, CONTROL, NOINVERT + "Z", ID_ME_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT + "S", ID_ME_FILE_SAVEFILE, VIRTKEY, CONTROL, NOINVERT + "A", ID_ME_PREVIEW_APPLYCHANGES, VIRTKEY, CONTROL, NOINVERT + "R", ID_PREVIEW_RELOADARBPROGRAMS, VIRTKEY, CONTROL, NOINVERT + "I", ID_PREVIEW_RELOADIMAGES, VIRTKEY, CONTROL, NOINVERT + VK_F2, ID_ME_EDIT_RENAME, VIRTKEY, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_ME_MAINFRAME "Material Editor" +END + +STRINGTABLE +BEGIN + ID_ME_FILE_EXIT "Exit" + ID_ME_FILE_SAVE "Save All\nSave All" + ID_VIEW_INCLUDEFILENAME "Include Filename" + ID_PREVIEW_RELOADARBPROGRAMS "Reload ARB Programs\nReload ARB Programs" + ID_ME_PREVIEW_APPLYCHANGES "Apply Material\nApply Material" + ID_ME_PREVIEW_APPLYALL "Apply All\nApply All" + ID_ME_FILE_SAVEMATERIAL "Save Material\nSave Material" + ID_ME_FILE_SAVEFILE "Save File\nSave File" +END + +STRINGTABLE +BEGIN + ID_ME_PREVIEW_APPLYFILE "Apply File\nApply File" + ID_PREVIEW_RELOADIMAGES "Reload Images\nReload Images" +END + +STRINGTABLE +BEGIN + ID_ME_EDIT_UNDO "Undo\nUndo" + ID_ME_EDIT_REDO "Redo\nRedo" + ID_ME_EDIT_CUT "Cut\nCut" + ID_ME_EDIT_COPY "Copy\nCopy" + ID_ME_EDIT_PASTE "Paste\nPaste" + ID_ME_EDIT_DELETE "Delete\nDelete" +END + +STRINGTABLE +BEGIN + ID_ME_EDIT_FIND "Find\nFind" + ID_ME_EDIT_RENAME "Rename\nRename" + ID_ME_EDIT_FIND_NEXT "Find Next\nFind Next" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/MaterialEditor_Resource.h b/sys/win32/rc/MaterialEditor_Resource.h new file mode 100644 index 000000000..ac5d3b078 --- /dev/null +++ b/sys/win32/rc/MaterialEditor_Resource.h @@ -0,0 +1,121 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#define IDD_ME_ABOUTBOX 6000 +#define IDD_TEST_DIALOG 6001 +#define IDD_CONSOLE_FORM 6002 +#define IDD_FIND 6003 +#define IDD_MATERIALEDIT_FORM 6004 +#define IDR_ME_MAINFRAME 6005 +#define IDR_ME_MATERIALTREE_POPUP 6006 +#define IDR_ME_FILETOOLBAR 6007 +#define IDR_ME_STAGELIST_POPUP 6008 +#define IDB_ME_TREEBITMAP 6009 +#define IDI_ME_ON_ICON 6010 +#define IDI_ME_OFF_ICON 6011 +#define IDI_ME_DISABLED_ICON 6012 +#define IDS_STRING7002 6013 +#define ID_EDITMENU_INSERTFILE 6015 +#define IDC_MATERIALEDITOR_EDIT_TEXT 6200 +#define IDC_TAB1 6201 +#define IDC_TAB2 6202 +#define IDC_CONSOLE_OUTPUT 6203 +#define IDC_EDIT_FINDTEXT 6204 +#define IDC_EDIT2 6205 +#define IDC_CONSOLE_EDIT 6206 +#define IDC_CHECK_MATCH_CASE 6207 +#define IDC_CHECK_NAME_ONLY 6208 +#define IDC_CHECK_MATCH_WORD 6209 +#define IDC_RADIO_SEARCHFILE 6210 +#define IDC_RADIO_SEARCHSCOPE 6211 +#define IDC_RADIO_SEARCHALL 6212 +#define IDC_MATERIAL_NAME 6213 +#define ID_ME_FILE_EXIT 26000 +#define ID_ME_FILE_OPEN 26001 +#define ID_ME_FILE_SAVE 26002 +#define ID_ME_FILE_NEW 26003 +#define ID_ME_FILE_SAVEAS 26004 +#define ID_VIEW_INCLUDEFILENAME 26005 +#define ID_PREVIEW_RELOADARBPROGRAMS 26006 +#define ID_ME_PREVIEW_APPLYCHANGES 26007 +#define ID_ME_PREVIEW_APPLYALL 26008 +#define ID_POPUP_APPLYCHANGES 26009 +#define ID_ME_FILE_SAVEMATERIAL 26010 +#define ID_ME_FILE_SAVEFILE 26011 +#define ID_POPUP_SAVEMATERIAL 26012 +#define ID_POPUP_SAVEFILE 26013 +#define ID_POPUP_SAVEALL 26014 +#define ID_POPUP_APPLYFILE 26015 +#define ID_POPUP2_SAVEFILE 26016 +#define ID_POPUP2_SAVEALL 26017 +#define ID_POPUP_APPLYALL 26018 +#define ID_POPUP3_SAVEALL 26019 +#define ID_POPUP_APPLYMATERIAL 26020 +#define ID_ME_PREVIEW_APPLYFILE 26021 +#define ID_STAGEPOPUP_ADDSTAGE 26022 +#define ID_STAGEPOPUP_ADDBUMPMAP 26023 +#define ID_STAGEPOPUP_ADDDIFFUSEMAP 26024 +#define ID_STAGEPOPUP_ADDSPECULAR 26025 +#define ID_STAGEPOPUP_DELETESTAGE 26026 +#define ID_Menu7052 26027 +#define ID_STAGEPOPUP_RENAMESTAGE 26028 +#define ID_STAGEPOPUP_DELETEALLSTAGES 26029 +#define ID_PREVIEW_RELOADIMAGES 26030 +#define ID_POPUP_ADDMATERIAL 26031 +#define ID_POPUP_DELETEMATERIAL 26032 +#define ID_POPUP_RENAMEMATERIAL 26033 +#define ID_POPUP_ADDFOLDER 26034 +#define ID_ME_EDIT_UNDO 26035 +#define ID_ME_EDIT_REDO 26036 +#define ID_ME_EDIT_CUT 26037 +#define ID_Menu7063 26038 +#define ID_ME_EDIT_COPY 26039 +#define ID_ME_EDIT_PASTE 26040 +#define ID_ME_EDIT_DELETE 26041 +#define ID_POPUP_CUT 26042 +#define ID_POPUP_COPY 26043 +#define ID_POPUP_PASTE 26044 +#define ID_STAGEPOPUP_CUT 26045 +#define ID_STAGEPOPUP_COPY 26046 +#define ID_STAGEPOPUP_PASTE 26047 +#define ID_STAGEPOPUP_ADD 26048 +#define ID_ME_EDIT_FIND 26049 +#define ID_ME_EDIT_RENAME 26050 +#define ID_POPUP_RELOADFILE 26051 +#define ID_FIND_NEXT 26052 +#define ID_BUTTON40001 26053 +#define ID_BUTTON40002 26054 +#define ID_BUTTON40003 26055 +#define ID_BUTTON40004 26056 +#define ID_BUTTON40005 26057 +#define ID_BUTTON40006 26058 +#define ID_BUTTON40007 26059 +#define ID_ME_FILE_SAVE_ACEL 26060 +#define ID_ME_EDIT_FIND_NEXT 26061 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 6016 +#define _APS_NEXT_COMMAND_VALUE 26062 +#define _APS_NEXT_CONTROL_VALUE 6214 +#define _APS_NEXT_SYMED_VALUE 6014 +#endif +#endif diff --git a/sys/win32/rc/PDAEditor.rc b/sys/win32/rc/PDAEditor.rc new file mode 100644 index 000000000..4aa3bbf52 --- /dev/null +++ b/sys/win32/rc/PDAEditor.rc @@ -0,0 +1,192 @@ +// Microsoft Visual C++ generated resource script. +// +#include "PDAEditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "PDAEditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_PDA_EDITOR DIALOGEX 0, 0, 396, 238 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "PDA Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "PDAs:",IDC_STATIC,7,7,20,8 + LISTBOX IDC_LIST_PDAS,7,20,92,189,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Full Name:",IDC_STATIC,110,23,34,8 + EDITTEXT IDC_EDIT_FULLNAME,162,20,79,14,ES_AUTOHSCROLL + LTEXT "Short Name:",IDC_STATIC,110,40,41,8 + EDITTEXT IDC_EDIT_SHORTNAME,162,37,79,14,ES_AUTOHSCROLL + LTEXT "Title:",IDC_STATIC,109,58,17,8 + EDITTEXT IDC_EDIT_TITLE,162,54,79,14,ES_AUTOHSCROLL + LTEXT "Post (Location):",IDC_STATIC,110,74,52,8 + EDITTEXT IDC_EDIT_POST,162,71,79,14,ES_AUTOHSCROLL + LTEXT "Security Level:",IDC_STATIC,110,91,48,8 + EDITTEXT IDC_EDIT_SECURITY,162,88,79,14,ES_AUTOHSCROLL + LTEXT "ID Number:",IDC_STATIC,110,108,41,8 + EDITTEXT IDC_EDIT_IDNUM,162,105,51,14,ES_AUTOHSCROLL + PUSHBUTTON "Rand",IDC_BUTTON_RANDOMID,216,105,25,14 + GROUPBOX "Email",IDC_STATIC,254,20,133,99 + LISTBOX IDC_LIST_EMAIL,261,32,117,65,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add...",IDC_BUTTON_EMAIL_ADD,262,98,38,14 + PUSHBUTTON "Edit...",IDC_BUTTON_EMAIL_EDIT,302,98,38,14 + PUSHBUTTON "Delete...",IDC_BUTTON_EMAIL_DELETE,342,98,38,14 + GROUPBOX "Audio Logs",IDC_STATIC,110,128,132,81 + LISTBOX IDC_LIST_AUDIO,117,140,117,49,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add...",IDC_BUTTON_AUDIO_ADD,118,190,38,14 + PUSHBUTTON "Edit...",IDC_BUTTON_AUDIO_EDIT,157,190,38,14 + PUSHBUTTON "Delete...",IDC_BUTTON_AUDIO_DELETE,196,190,38,14 + GROUPBOX "Videos",IDC_STATIC,254,128,134,81 + LISTBOX IDC_LIST_VIDEO,262,140,117,49,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add...",IDC_BUTTON_VIDEO_ADD,262,190,38,14 + PUSHBUTTON "Edit...",IDC_BUTTON_VIDEO_EDIT,302,190,38,14 + PUSHBUTTON "Delete...",IDC_BUTTON_VIDEO_DELETE,342,190,38,14 + PUSHBUTTON "Save",IDC_BUTTON_SAVE,284,217,50,14 + PUSHBUTTON "Close",IDCANCEL,338,217,50,14 + RTEXT "This mostly works. You can't delete anything, or edit audio logs/videos", + IDC_STATIC,146,7,242,8 + PUSHBUTTON "Add",IDC_BUTTON_PDA_ADD,7,209,26,14 + PUSHBUTTON "Del",IDC_BUTTON_PDA_DEL,37,209,25,14 +END + +IDD_DIALOG_PDA_EDIT_EMAIL DIALOGEX 0, 0, 262, 186 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "EMail Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "To:",IDC_STATIC,7,10,12,8 + EDITTEXT IDC_EDIT_TO,43,7,212,14,ES_AUTOHSCROLL + LTEXT "From:",IDC_STATIC,7,25,20,8 + EDITTEXT IDC_EDIT_FROM,43,22,212,14,ES_AUTOHSCROLL + LTEXT "Date:",IDC_STATIC,7,40,19,8 + EDITTEXT IDC_EDIT_DATE,43,37,212,14,ES_AUTOHSCROLL + LTEXT "Subject:",IDC_STATIC,7,55,28,8 + EDITTEXT IDC_EDIT_SUBJECT,43,52,212,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_BODY,7,70,248,91,ES_MULTILINE | ES_AUTOVSCROLL | + ES_WANTRETURN | WS_VSCROLL + DEFPUSHBUTTON "OK",IDOK,154,165,50,14 + PUSHBUTTON "Cancel",IDCANCEL,205,165,50,14 +END + +IDD_DIALOG_PDA_ADD DIALOGEX 0, 0, 186, 70 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "New PDA" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "New PDA Name:",IDC_STATIC,7,15,53,8 + EDITTEXT IDC_EDIT1,66,12,113,14,ES_AUTOHSCROLL + LTEXT "(mapname_lastname)",IDC_STATIC,66,32,70,8 + DEFPUSHBUTTON "OK",IDOK,41,49,50,14 + PUSHBUTTON "Cancel",IDCANCEL,97,49,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_PDA_EDITOR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 388 + TOPMARGIN, 7 + BOTTOMMARGIN, 231 + END + + IDD_DIALOG_PDA_EDIT_EMAIL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 255 + VERTGUIDE, 43 + TOPMARGIN, 7 + BOTTOMMARGIN, 179 + HORZGUIDE, 14 + HORZGUIDE, 29 + HORZGUIDE, 44 + HORZGUIDE, 59 + END + + IDD_DIALOG_PDA_ADD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + VERTGUIDE, 66 + TOPMARGIN, 7 + BOTTOMMARGIN, 63 + HORZGUIDE, 19 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/PDAEditor_resource.h b/sys/win32/rc/PDAEditor_resource.h new file mode 100644 index 000000000..4168fdea5 --- /dev/null +++ b/sys/win32/rc/PDAEditor_resource.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_PDA_EDITOR 8000 +#define IDD_DIALOG_PDA_EDIT_EMAIL 8001 +#define IDD_DIALOG_PDA_ADD 8002 + +#define IDC_LIST_PDAS 8200 +#define IDC_EDIT_FULLNAME 8201 +#define IDC_EDIT_SHORTNAME 8202 +#define IDC_EDIT_POST 8203 +#define IDC_EDIT_TITLE 8204 +#define IDC_EDIT_SECURITY 8205 +#define IDC_EDIT_IDNUM 8206 +#define IDC_BUTTON_RANDOMID 8207 +#define IDC_LIST_EMAILS 8208 +#define IDC_LIST_VIDEO 8209 +#define IDC_BUTTON_VIDEO_DELETE 8210 +#define IDC_BUTTON_VIDEO_EDIT 8211 +#define IDC_BUTTON_VIDEO_ADD 8212 +#define IDC_LIST_AUDIO 8213 +#define IDC_BUTTON_AUDIO_DELETE 8214 +#define IDC_BUTTON_AUDIO_EDIT 8215 +#define IDC_BUTTON_AUDIO_ADD 8216 +#define IDC_LIST_EMAIL 8217 +#define IDC_BUTTON_EMAIL_DELETE 8218 +#define IDC_BUTTON_EMAIL_EDIT 8219 +#define IDC_BUTTON_EMAIL_ADD 8220 +#define IDC_EDIT_SUBJECT 8221 +#define IDC_EDIT_TO 8222 +#define IDC_EDIT_FROM 8223 +#define IDC_EDIT_DATE 8224 +#define IDC_EDIT_BODY 8225 +#define IDC_BUTTON_SAVE 8226 +#define IDC_BUTTON_PDA_ADD 8227 +#define IDC_BUTTON_PDA_ 8228 +#define IDC_BUTTON_PDA_DEL 8229 +#define IDC_EDIT1 8230 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 8003 +#define _APS_NEXT_COMMAND_VALUE 28000 +#define _APS_NEXT_CONTROL_VALUE 8231 +#define _APS_NEXT_SYMED_VALUE 8003 +#endif +#endif diff --git a/sys/win32/rc/ParticleEditor.rc b/sys/win32/rc/ParticleEditor.rc new file mode 100644 index 000000000..a9e8c7864 --- /dev/null +++ b/sys/win32/rc/ParticleEditor.rc @@ -0,0 +1,324 @@ +// Microsoft Visual C++ generated resource script. +// +#include "ParticleEditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "ParticleEditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_PARTICLE_EDITOR DIALOGEX 0, 0, 312, 505 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Particle Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_COMBO_PARTICLES,35,5,149,200,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "New...",IDC_BUTTON_NEW,187,5,59,13 + PUSHBUTTON "Save",IDC_BUTTON_SAVE_PARTICLE,250,5,59,13 + EDITTEXT IDC_EDIT_DEPTHHACK,185,21,40,12,ES_AUTOHSCROLL + PUSHBUTTON "Save as...",IDC_BUTTON_SAVE_PARTICLE_AS,250,21,59,13 + PUSHBUTTON "+",IDC_BUTTON_ADDSTAGE,16,42,10,9 + PUSHBUTTON "-",IDC_BUTTON_REMOVESTAGE,29,42,10,9 + PUSHBUTTON "H",IDC_BUTTON_HIDESTAGE,42,42,10,9 + PUSHBUTTON "S",IDC_BUTTON_SHOWSTAGE,55,42,10,9 + LISTBOX IDC_LIST_STAGES,15,53,78,111,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_MATERIAL,120,50,164,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON_BROWSEMATERIAL,285,50,14,12 + EDITTEXT IDC_EDIT_ANIMFRAMES,158,67,31,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ANIMRATE,236,67,31,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_COLOR,141,82,101,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON_BROWSECOLOR,244,82,14,12 + EDITTEXT IDC_EDIT_FADECOLOR,141,99,101,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON_BROWSEFADECOLOR,244,99,14,12 + EDITTEXT IDC_EDIT_FADEIN,141,116,39,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_FADEIN,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,184,116,112,12 + EDITTEXT IDC_EDIT_FADEOUT,141,130,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_FADEOUT,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,184,130,112,12 + EDITTEXT IDC_EDIT_BUNCHING,141,159,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_BUNCHING,"msctls_trackbar32",TBS_AUTOTICKS | + TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,184,158,112,13 + EDITTEXT IDC_EDIT_COUNT,43,172,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_COUNT,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,88,173,209,12 + EDITTEXT IDC_EDIT_TIME,43,187,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_TIME,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,88,187,209,12 + EDITTEXT IDC_EDIT_CYCLES,43,201,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_TIMEOFFSET,139,201,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_DEADTIME,225,201,40,12,ES_AUTOHSCROLL + CONTROL "World Gravity",IDC_CHECK_WORLDGRAVITY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,9,221,58,10 + EDITTEXT IDC_EDIT_GRAVITY,68,220,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_GRAVITY,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,111,220,185,12 + CONTROL "Rect",IDC_RADIO_RECT,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,14,246,31,10 + CONTROL "Cylinder",IDC_RADIO_CYLINDER,"Button", + BS_AUTORADIOBUTTON,14,257,42,10 + CONTROL "Sphere",IDC_RADIO_SPHERE,"Button",BS_AUTORADIOBUTTON,14, + 268,39,10 + EDITTEXT IDC_EDIT_OFFSET,11,291,47,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_XSIZE,83,242,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_YSIZE,83,257,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ZSIZE,83,272,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RINGOFFSET,83,288,40,12,ES_AUTOHSCROLL + CONTROL "Cone",IDC_RADIO_CONE,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,137,244,33,10 + CONTROL "Outward",IDC_RADIO_OUTWARD,"Button",BS_AUTORADIOBUTTON, + 137,255,44,10 + EDITTEXT IDC_EDIT_DIRECTIONPARM,137,280,40,12,ES_AUTOHSCROLL + CONTROL "View",IDC_RADIO_VIEW,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,202,244,31,10 + CONTROL "Aimed",IDC_RADIO_AIMED,"Button",BS_AUTORADIOBUTTON,202, + 255,35,10 + CONTROL "X",IDC_RADIO_X,"Button",BS_AUTORADIOBUTTON,202,266,20, + 10 + CONTROL "Y",IDC_RADIO_Y,"Button",BS_AUTORADIOBUTTON,202,277,20, + 10 + CONTROL "Z",IDC_RADIO_Z,"Button",BS_AUTORADIOBUTTON,202,288,20, + 10 + EDITTEXT IDC_EDIT_ORIENTATIONPARM1,249,272,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ORIENTATIONPARM2,249,288,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_SPEEDFROM,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,31,325,106,12 + EDITTEXT IDC_EDIT_SPEEDFROM,35,337,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_SPEEDTO,92,337,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_SPEEDTO,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,31,349,106,12 + CONTROL "",IDC_SLIDER_ROTATIONFROM,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,165,325,106,12 + EDITTEXT IDC_EDIT_ROTATIONFROM,169,337,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ROTATIONTO,226,337,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_ROTATIONTO,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,165,349,106,12 + CONTROL "",IDC_SLIDER_SIZEFROM,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,31,366,106,12 + EDITTEXT IDC_EDIT_SIZEFROM,35,379,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_SIZETO,92,379,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_SIZETO,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,31,391,106,12 + CONTROL "",IDC_SLIDER_ASPECTFROM,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,165,366,106,12 + EDITTEXT IDC_EDIT_ASPECTFROM,169,378,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ASPECTTO,226,378,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_ASPECTTO,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,165,391,106,12 + COMBOBOX IDC_COMBO_CUSTOMPATH,57,424,75,110,CBS_DROPDOWN | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Apply",IDC_BUTTON_UPDATE,253,422,50,14 + CONTROL "Edit Mode",IDC_CHECK_EDITPARTICLEMODE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,98,459,47,10 + PUSHBUTTON "Save .MAP",IDC_BUTTON_SAVE_PARTICLEENTITIES,257,480,47, + 13 + LTEXT "Particle",IDC_STATIC,8,7,27,8 + LTEXT "Depth hack",IDC_STATIC,146,23,37,8 + LTEXT "Material",IDC_STATIC,119,41,26,8 + GROUPBOX "Stages",IDC_STATIC,3,32,305,412 + LTEXT "Count",IDC_STATIC,20,174,20,8 + LTEXT "Time",IDC_STATIC,24,189,16,8 + LTEXT "Time offset",IDC_STATIC,99,203,37,8 + LTEXT "Bunching",IDC_STATIC,109,160,30,8 + LTEXT "Dead time",IDC_STATIC,189,203,33,8 + GROUPBOX "Distribution",IDC_STATIC,7,235,120,87 + LTEXT "XSize",IDC_STATIC,62,245,18,8 + LTEXT "YSize",IDC_STATIC,63,259,18,8 + LTEXT "ZSize",IDC_STATIC,63,274,18,8 + LTEXT "Ring",IDC_STATIC,64,290,15,8 + GROUPBOX "Direction / Orientation",IDC_STATIC,132,235,165,87 + LTEXT "Static",IDC_STATIC_DIRPARM,140,270,52,8 + LTEXT "Custom Path",IDC_STATIC,11,426,42,8 + LTEXT "Speed",IDC_STATIC,11,339,21,8 + LTEXT "to",IDC_STATIC,80,339,8,8 + LTEXT "Rotation",IDC_STATIC,139,339,28,8 + LTEXT "to",IDC_STATIC,213,339,8,8 + LTEXT "Size",IDC_STATIC,11,381,14,8 + LTEXT "to",IDC_STATIC,80,381,8,8 + LTEXT "Aspect",IDC_STATIC,140,380,23,8 + LTEXT "to",IDC_STATIC,213,380,8,8 + LTEXT "Color",IDC_STATIC,122,84,18,8 + RTEXT "Fade Color",IDC_STATIC,104,101,36,8 + LTEXT "Fade in %",IDC_STATIC,107,118,34,8 + LTEXT "Fade out %",IDC_STATIC,101,132,39,8 + LTEXT "Anim Frames",IDC_STATIC,113,70,42,8 + LTEXT "Anim Rate",IDC_STATIC,196,70,34,8 + LTEXT "Offset",IDC_STATIC,13,281,22,8 + GROUPBOX "DOOM Stuff",IDC_STATIC,5,448,84,48,WS_TABSTOP + LTEXT "Trails",IDC_STATIC,227,274,18,8 + LTEXT "Time",IDC_STATIC,228,289,16,8 + LTEXT "In file: ",IDC_STATIC_INFILE,10,23,119,8 + LTEXT "Cycles",IDC_STATIC,18,203,22,8 + PUSHBUTTON "T",IDC_BUTTON_TESTMODEL,12,462,11,12 + PUSHBUTTON "I",IDC_BUTTON_IMPACT,28,462,11,12 + PUSHBUTTON "M",IDC_BUTTON_MUZZLE,43,462,11,12 + PUSHBUTTON "F",IDC_BUTTON_FLIGHT,58,462,11,12 + PUSHBUTTON "S",IDC_BUTTON_SELECTED,73,462,11,12 + PUSHBUTTON "Switch to DOOM",IDC_BUTTON_DOOM,12,480,63,12 + PUSHBUTTON "x-",IDC_BUTTON_XDN,152,467,13,11 + PUSHBUTTON "x+",IDC_BUTTON_XUP,177,467,13,11 + PUSHBUTTON "y+",IDC_BUTTON_YUP,165,455,13,11 + PUSHBUTTON "y-",IDC_BUTTON_YDN,165,480,13,11 + PUSHBUTTON "z+",IDC_BUTTON_ZUP,194,461,13,11 + PUSHBUTTON "z-",IDC_BUTTON_ZDN,194,475,13,11 + PUSHBUTTON "Drop",IDC_BUTTON_DROPEMITTER,98,470,44,12 + GROUPBOX "Entity Editing",IDC_STATIC,92,448,216,48,WS_TABSTOP + CONTROL "Vector",IDC_BUTTON_VECTOR,"Button",BS_OWNERDRAW | + WS_TABSTOP,213,462,35,27 + EDITTEXT IDC_EDIT_CUSTOMPARMS,159,424,73,12,ES_AUTOHSCROLL + LTEXT "Parms",IDC_STATIC,137,426,20,8 + EDITTEXT IDC_EDIT_FADEFRACTION,141,144,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SLIDER_FADEFRACTION,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,184,144,112,12 + LTEXT "Fade Frac",IDC_STATIC,104,146,33,8 + EDITTEXT IDC_EDIT_BOUNDSEXPANSION,75,406,40,12,ES_AUTOHSCROLL + LTEXT "Bounds Expansion",IDC_STATIC,11,407,59,8 + LTEXT "Desc:",IDC_STATIC,138,405,19,8 + LTEXT "Desc:",IDC_STATIC_DESC,163,405,69,16 + EDITTEXT IDC_EDIT_INITIALANGLE,182,305,40,12,ES_AUTOHSCROLL + LTEXT "Initial Angle:",IDC_STATIC,137,307,41,8 + CONTROL "Random Distribution",IDC_CHECK_RANDOMDISTRIBUTION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,307,91,10 + PUSHBUTTON "...",IDC_BUTTON_BROWSECOLOR_ENTITY,283,459,14,12 + LTEXT "Color",IDC_STATIC,262,461,16,8 + CONTROL "Entity Color",IDC_CHECK_ENTITYCOLOR,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,263,85,40,25 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_DIALOG_PARTICLE_EDITOR DLGINIT +BEGIN + IDC_COMBO_CUSTOMPATH, 0x403, 9, 0 +0x7453, 0x6e61, 0x6164, 0x6472, "\000" + IDC_COMBO_CUSTOMPATH, 0x403, 6, 0 +0x6548, 0x696c, 0x0078, + IDC_COMBO_CUSTOMPATH, 0x403, 6, 0 +0x6c46, 0x6569, 0x0073, + IDC_COMBO_CUSTOMPATH, 0x403, 10, 0 +0x7053, 0x6568, 0x6972, 0x6163, 0x006c, + IDC_COMBO_CUSTOMPATH, 0x403, 5, 0 +0x7244, 0x7069, "\000" + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_PARTICLE_EDITOR, DIALOG + BEGIN + BOTTOMMARGIN, 501 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDC_BUTTON_UPDATE "apply any typed in changes to the current system ( this does not save it )" + IDC_BUTTON_SAVE_PARTICLE "save the current particle system" + IDC_COMBO_PARTICLES "select a particle system to edit" + IDC_BUTTON_NEW "create a new particle system" + IDC_BUTTON_ADDSTAGE "add a new generic stage" + IDC_BUTTON_REMOVESTAGE "remove the selected stage" +END + +STRINGTABLE +BEGIN + IDC_BUTTON_HIDESTAGE "hide the selected stage" + IDC_BUTTON_SAVE_PARTICLE_AS "save the current particle as a new particle" + IDC_BUTTON_SAVE_ONENTITY + "save the current particle uniquely on the selected entity" + IDC_BUTTON_SHOWSTAGE "show the selected stage" + IDC_BUTTON_SAVE_PARTICLEENTITIES + "save the current map with any updated particle emitter entities" +END + +STRINGTABLE +BEGIN + IDC_BUTTON_TESTMODEL "show the selected particle as a testmodel" + IDC_BUTTON_IMPACT "show the selected particle on projectile impact" + IDC_BUTTON_MUZZLE "show the selected particle as muzzle smoke" + IDC_BUTTON_FLIGHT "show the selected particle as projectile flight smoke" + IDC_BUTTON_SELECTED "show the selected particle on the selected entity" + IDC_BUTTON_DOOM "force focus to DOOM" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/ParticleEditor_resource.h b/sys/win32/rc/ParticleEditor_resource.h new file mode 100644 index 000000000..dcc1e303a --- /dev/null +++ b/sys/win32/rc/ParticleEditor_resource.h @@ -0,0 +1,142 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_PARTICLE_EDITOR 7000 + +#define IDC_BUTTON_UPDATE 7200 +#define IDC_BUTTON_SAVE_PARTICLE 7201 +#define IDC_COMBO_PARTICLES 7202 +#define IDC_BUTTON_NEW 7203 +#define IDC_LIST_STAGES 7204 +#define IDC_BUTTON_ADDSTAGE 7205 +#define IDC_BUTTON_REMOVESTAGE 7206 +#define IDC_EDIT_MATERIAL 7207 +#define IDC_BUTTON_BROWSEMATERIAL 7208 +#define IDC_EDIT_DEPTHHACK 7209 +#define IDC_CHECK_ONESHOT 7210 +#define IDC_EDIT_COUNT 7211 +#define IDC_SLIDER_COUNT 7212 +#define IDC_CHECK_WORLDGRAVITY 7213 +#define IDC_EDIT_TIME 7214 +#define IDC_SLIDER_TIME 7215 +#define IDC_EDIT_TIMEOFFSET 7216 +#define IDC_EDIT_BUNCHING 7217 +#define IDC_EDIT_DEADTIME 7218 +#define IDC_RADIO_RECT 7219 +#define IDC_RADIO_SPHERE 7220 +#define IDC_RADIO_CYLINDER 7221 +#define IDC_RADIO_SPHERE2 7222 +#define IDC_CHECK_WORLDGRAVITY2 7223 +#define IDC_CHECK_ENTITYCOLOR 7224 +#define IDC_EDIT_XSIZE 7225 +#define IDC_EDIT_ZSIZE 7226 +#define IDC_EDIT_YSIZE 7227 +#define IDC_EDIT_RINGOFFSET 7228 +#define IDC_RADIO_CONE 7229 +#define IDC_RADIO_OUTWARD 7230 +#define IDC_EDIT_DIRECTIONPARM 7231 +#define IDC_RADIO_VIEW 7232 +#define IDC_RADIO_AIMED 7233 +#define IDC_RADIO_X 7234 +#define IDC_RADIO_Y 7235 +#define IDC_RADIO_Z 7236 +#define IDC_EDIT_CUSTOMPATH 7237 +#define IDC_CHECK_RANDOMANGLE2 7238 +#define IDC_CHECK_RANDOMDISTRIBUTION 7239 +#define IDC_EDIT_CYCLES 7240 +#define IDC_EDIT_COLOR 7241 +#define IDC_BUTTON_BROWSECOLOR 7242 +#define IDC_EDIT_SPEEDFROM 7243 +#define IDC_EDIT_SPEEDTO 7244 +#define IDC_EDIT_ROTATIONFROM 7245 +#define IDC_EDIT_ROTATIONTO 7246 +#define IDC_EDIT_SIZEFROM 7247 +#define IDC_EDIT_SIZETO 7248 +#define IDC_EDIT_ASPECTFROM 7249 +#define IDC_EDIT_ASPECTTO 7250 +#define IDC_EDIT_FADECOLOR 7251 +#define IDC_BUTTON_BROWSEFADECOLOR 7252 +#define IDC_EDIT_FADEIN 7253 +#define IDC_EDIT_FADEOUT 7254 +#define IDC_EDIT_ANIMFRAMES 7255 +#define IDC_EDIT_ANIMRATE 7256 +#define IDC_EDIT_GRAVITY 7257 +#define IDC_EDIT_OFFSET 7258 +#define IDC_STATIC_DIRPARM 7259 +#define IDC_BUTTON_HIDESTAGE 7260 +#define IDC_RADIO_VIEWORIGIN 7261 +#define IDC_EDIT_CUSTOMPARMS 7262 +#define IDC_CHECK_EDITPARTICLEMODE 7263 +#define IDC_RADIO_VIEWPROJECTILE 7264 +#define IDC_EDIT_FADEFRACTION 7265 +#define IDC_BUTTON_SAVE_PARTICLE_AS 7266 +#define IDC_RADIO_VIEWIMPACT 7267 +#define IDC_BUTTON_BROWSECOLOR_ENTITY 7268 +#define IDC_BUTTON_SAVE_ONENTITY 7269 +#define IDC_BUTTON_SHOWSTAGE 7270 +#define IDC_RADIO_VIEWEXPLOSION 7271 +#define IDC_BUTTON_SAVE_PARTICLEENTITIES 7272 +#define IDC_EDIT_ORIENTATIONPARM1 7273 +#define IDC_EDIT_ORIENTATIONPARM2 7274 +#define IDC_SLIDER_BUNCHING 7275 +#define IDC_SLIDER_SPEEDFROM 7276 +#define IDC_SLIDER_SPEEDTO 7277 +#define IDC_SLIDER_SIZEFROM 7278 +#define IDC_SLIDER_SIZETO 7279 +#define IDC_SLIDER_ROTATIONFROM 7280 +#define IDC_SLIDER_ROTATIONTO 7281 +#define IDC_SLIDER_ASPECTFROM 7282 +#define IDC_SLIDER_ASPECTTO 7283 +#define IDC_SLIDER_GRAVITY 7284 +#define IDC_SLIDER_FADEIN 7285 +#define IDC_SLIDER_FADEOUT 7286 +#define IDC_COMBO_CUSTOMPATH 7287 +#define IDC_STATIC_INFILE 7288 +#define IDC_BUTTON_TESTMODEL 7289 +#define IDC_BUTTON_IMPACT 7290 +#define IDC_BUTTON_MUZZLE 7291 +#define IDC_BUTTON_FLIGHT 7292 +#define IDC_BUTTON_SELECTED 7293 +#define IDC_BUTTON_DOOM 7294 +#define IDC_BUTTON_DROPEMITTER 7295 +#define IDC_BUTTON1 7296 +#define IDC_BUTTON_VECTOR 7297 +#define IDC_SLIDER_FADEFRACTION 7298 +#define IDC_EDIT_BOUNDSEXPANSION 7299 +#define IDC_STATIC_DESC 7300 +#define IDC_EDIT_INITIALANGLE 7301 +#define IDC_BUTTON_XDN 7302 +#define IDC_BUTTON_XUP 7303 +#define IDC_BUTTON_YUP 7304 +#define IDC_BUTTON_YDN 7305 +#define IDC_BUTTON_ZUP 7306 +#define IDC_BUTTON_ZDN 7307 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 7001 +#define _APS_NEXT_COMMAND_VALUE 27000 +#define _APS_NEXT_CONTROL_VALUE 7308 +#define _APS_NEXT_SYMED_VALUE 7001 +#endif +#endif diff --git a/sys/win32/rc/PropTree.rc b/sys/win32/rc/PropTree.rc new file mode 100644 index 000000000..1e045e9da --- /dev/null +++ b/sys/win32/rc/PropTree.rc @@ -0,0 +1,132 @@ +// Microsoft Visual C++ generated resource script. +// +#include "proptree_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "proptree_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\PropTree.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_FPOINT CURSOR "res\\fpoint.cur" +IDC_SPLITTER CURSOR "res\\spliter.cur" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_ME_EDIT_MENU MENU +BEGIN + POPUP "EditMenu" + BEGIN + MENUITEM "Insert File", ID_EDITMENU_INSERTFILE + MENUITEM SEPARATOR + MENUITEM "Undo", 57643 + MENUITEM SEPARATOR + MENUITEM "Cut", 57635 + MENUITEM "Copy", 57634 + MENUITEM "Paste", 57637 + MENUITEM "Delete", ID_EDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "Select All", ID_EDIT_SELECTALL + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_TRUE "True" + IDS_FALSE "False" + IDS_NOITEMSEL "No Item Selected" + IDS_SELFORINFO "Select an item to see its description" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\PropTree.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/PropTree_resource.h b/sys/win32/rc/PropTree_resource.h new file mode 100644 index 000000000..5f12b4580 --- /dev/null +++ b/sys/win32/rc/PropTree_resource.h @@ -0,0 +1,44 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#define IDR_ME_EDIT_MENU 6014 +#define ID_EDITMENU_INSERTFILE 6015 +#define IDS_TRUE 9000 +#define IDS_FALSE 9001 +#define IDS_NOITEMSEL 9002 +#define IDS_SELFORINFO 9003 +#define ID_UNDO 9005 +#define ID_CUT 9006 +#define ID_COPY 9007 +#define ID_PASTE 9008 +#define ID_EDIT_DELETE 9009 +#define ID_EDIT_SELECTALL 9010 +#define IDC_SPLITTER 9200 +#define IDC_FPOINT 9201 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 9011 +#define _APS_NEXT_COMMAND_VALUE 29000 +#define _APS_NEXT_CONTROL_VALUE 9202 +#define _APS_NEXT_SYMED_VALUE 9004 +#endif +#endif diff --git a/sys/win32/rc/Radiant.rc b/sys/win32/rc/Radiant.rc new file mode 100644 index 000000000..56699f9e6 --- /dev/null +++ b/sys/win32/rc/Radiant.rc @@ -0,0 +1,2825 @@ +// Microsoft Visual C++ generated resource script. +// +#include "Radiant_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "Radiant_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\doom.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_SHADERFRAME BITMAP "res\\Toolbar.bmp" +IDR_TOOLBAR1 BITMAP "res\\toolbar1.bmp" +IDB_VIEWDEFAULT BITMAP "res\\bitmap2.bmp" +IDB_VIEWQE4 BITMAP "res\\viewdefa.bmp" +IDB_VIEW4WAY BITMAP "res\\viewoppo.bmp" +IDB_VIEWDEFAULT_Z BITMAP "res\\bmp00001.bmp" +IDR_TOOLBAR_SCALELOCK BITMAP "res\\toolbar2.bmp" +IDR_TOOLBAR_ADVANCED BITMAP "res\\bmp00002.bmp" +IDB_IENDCAP BITMAP "res\\iendcap.bmp" +IDB_ENDCAP BITMAP "res\\endcap.bmp" +IDB_BEVEL BITMAP "res\\bevel.bmp" +IDB_IBEVEL BITMAP "res\\ibevel.bmp" +IDB_BITMAP_GROUPS BITMAP "res\\bmp00003.bmp" +IDB_BITMAP_MATERIAL BITMAP "res\\bmp00004.bmp" +IDB_BITMAP_HSB BITMAP "res\\cchsb.bmp" +IDB_BITMAP_RGB BITMAP "res\\ccrgb.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_SHADERFRAME TOOLBAR 16, 15 +BEGIN + BUTTON ID_FILE_OPEN + BUTTON ID_FILE_SAVE + SEPARATOR + BUTTON ID_EDIT_CUT + BUTTON ID_EDIT_COPY + BUTTON ID_EDIT_PASTE +END + +IDR_TOOLBAR1 TOOLBAR 16, 15 +BEGIN + BUTTON ID_FILE_OPEN + BUTTON ID_FILE_SAVE + SEPARATOR + BUTTON ID_BRUSH_FLIPX + BUTTON ID_BRUSH_ROTATEX + BUTTON ID_BRUSH_FLIPY + BUTTON ID_BRUSH_ROTATEY + BUTTON ID_BRUSH_FLIPZ + BUTTON ID_BRUSH_ROTATEZ + SEPARATOR + BUTTON ID_POPUP_SELECTION + SEPARATOR + BUTTON ID_SELECTION_CSGSUBTRACT + BUTTON ID_SELECTION_MAKEHOLLOW + SEPARATOR + BUTTON ID_VIEW_CHANGE + SEPARATOR + BUTTON ID_TEXTURES_POPUP + SEPARATOR + BUTTON ID_VIEW_CAMERATOGGLE + BUTTON ID_VIEW_CAMERAUPDATE + BUTTON ID_VIEW_CUBICCLIPPING + SEPARATOR + BUTTON ID_VIEW_ENTITY + SEPARATOR + BUTTON ID_VIEW_CLIPPER + SEPARATOR + BUTTON ID_SELECT_MOUSEROTATE + SEPARATOR + BUTTON ID_SELECT_COMPLETE_ENTITY + BUTTON ID_SCALELOCKX + BUTTON ID_SCALELOCKY + BUTTON ID_SCALELOCKZ +END + +IDR_TOOLBAR_SCALELOCK TOOLBAR 16, 15 +BEGIN + BUTTON ID_SCALELOCKX + BUTTON ID_SCALELOCKY + BUTTON ID_SCALELOCKZ +END + +IDR_TOOLBAR_ADVANCED TOOLBAR 16, 17 +BEGIN + BUTTON ID_FILE_OPEN + BUTTON ID_FILE_SAVE + SEPARATOR + BUTTON ID_BRUSH_FLIPX + BUTTON ID_BRUSH_ROTATEX + BUTTON ID_BRUSH_FLIPY + BUTTON ID_BRUSH_ROTATEY + BUTTON ID_BRUSH_FLIPZ + BUTTON ID_BRUSH_ROTATEZ + SEPARATOR + BUTTON ID_SELECTION_SELECTCOMPLETETALL + BUTTON ID_SELECTION_SELECTTOUCHING + BUTTON ID_SELECTION_SELECTPARTIALTALL + BUTTON ID_SELECTION_SELECTINSIDE + SEPARATOR + BUTTON ID_SELECTION_CSGSUBTRACT + BUTTON ID_SELECTION_CSGMERGE + BUTTON ID_SELECTION_MAKEHOLLOW + BUTTON ID_VIEW_CLIPPER + SEPARATOR + BUTTON ID_VIEW_CHANGE + BUTTON ID_TEXTURES_POPUP + BUTTON ID_VIEW_CUBICCLIPPING + SEPARATOR + BUTTON ID_SELECT_MOUSEROTATE + SEPARATOR + BUTTON ID_SELECT_MOUSESCALE + SEPARATOR + BUTTON ID_SCALELOCKX + BUTTON ID_SCALELOCKY + BUTTON ID_SCALELOCKZ + SEPARATOR + BUTTON ID_SELECTION_MOVEONLY + SEPARATOR + BUTTON ID_SELECT_BRUSHESONLY + BUTTON ID_SELECT_NOMODELS + BUTTON ID_SELECT_BYBOUNDINGBRUSH + BUTTON ID_PATCH_SHOWBOUNDINGBOX + SEPARATOR + BUTTON ID_SHOW_ENTITIES + SEPARATOR + BUTTON ID_PATCH_WIREFRAME + BUTTON ID_PATCH_BEND + BUTTON ID_PATCH_INSDEL + BUTTON ID_CURVE_CAP + BUTTON ID_PATCH_WELD + BUTTON ID_PATCH_DRILLDOWN + SEPARATOR + BUTTON ID_SHOW_LIGHTVOLUMES + BUTTON ID_SHOW_LIGHTTEXTURES + SEPARATOR + BUTTON ID_SPLINES_POPUP + BUTTON ID_SPLINES_EDITPOINTS + BUTTON ID_SPLINES_ADDPOINTS + BUTTON ID_SPLINES_INSERTPOINTS + BUTTON ID_SPLINES_DELETEPOINTS + SEPARATOR + BUTTON ID_SOUND_SHOWSOUNDVOLUMES + BUTTON ID_SOUND_SHOWSELECTEDSOUNDVOLUMES + SEPARATOR + BUTTON ID_SHOW_DOOM +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_SHADERFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New\tCtrl+N", ID_FILE_NEW + MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN + MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE + MENUITEM "Save &As...", ID_FILE_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Close", ID_FILE_CLOSE + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT + MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY + MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE + MENUITEM "Delete\tDel", ID_EDIT_CLEAR + MENUITEM SEPARATOR + MENUITEM "&Find...", ID_EDIT_FIND + MENUITEM "Find &Next\tF3", ID_EDIT_REPEAT + MENUITEM "&Replace...", ID_EDIT_REPLACE + MENUITEM SEPARATOR + MENUITEM "Select &All", ID_EDIT_SELECT_ALL + END +END + +IDR_MAINFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New\tCtrl+N", ID_FILE_NEW + MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&View" + BEGIN + MENUITEM "&Toolbar", ID_VIEW_TOOLBAR + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Help" + BEGIN + MENUITEM "&About Radiant...", ID_APP_ABOUT + END +END + +IDR_RADIANTYPE MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New\tCtrl+N", ID_FILE_NEW + MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN + MENUITEM "&Close", ID_FILE_CLOSE + MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE + MENUITEM "Save &As...", ID_FILE_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT + MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW + MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT + MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY + MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE + END + POPUP "&View" + BEGIN + MENUITEM "&Toolbar", ID_VIEW_TOOLBAR + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Window" + BEGIN + MENUITEM "&New Window", ID_WINDOW_NEW + MENUITEM "&Cascade", ID_WINDOW_CASCADE + MENUITEM "&Tile", ID_WINDOW_TILE_HORZ + MENUITEM "&Arrange Icons", ID_WINDOW_ARRANGE + END + POPUP "&Help" + BEGIN + MENUITEM "&About Radiant...", ID_APP_ABOUT + END +END + +IDR_MENU_QUAKE3 MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New map", ID_FILE_NEW + MENUITEM SEPARATOR + MENUITEM "&Open...", ID_FILE_OPEN + MENUITEM "&Load...", ID_FILE_IMPORTMAP + MENUITEM "&Save", ID_FILE_SAVE + MENUITEM "Save &as...", ID_FILE_SAVEAS + MENUITEM "Save s&elected...", ID_FILE_EXPORTMAP + MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM "Save re&gion...", ID_FILE_SAVEREGION + MENUITEM SEPARATOR + MENUITEM "New p&roject...", ID_FILE_NEWPROJECT, GRAYED + MENUITEM "Load &project...", ID_FILE_LOADPROJECT + MENUITEM "Pro&ject settings...", ID_FILE_PROJECTSETTINGS + MENUITEM SEPARATOR + MENUITEM "&Pointfile...", ID_FILE_POINTFILE + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl-Z", ID_EDIT_UNDO + MENUITEM "&Redo\tShift-Ctrl-Z", ID_EDIT_REDO + MENUITEM SEPARATOR + MENUITEM "&Copy\tCtrl-C", ID_EDIT_COPYBRUSH + MENUITEM "&Paste\tCtrl-V", ID_EDIT_PASTEBRUSH + MENUITEM "&Delete\tBackspace", ID_SELECTION_DELETE + MENUITEM SEPARATOR + MENUITEM "Map Info...", ID_EDIT_MAPINFO + MENUITEM "Entity Info...", ID_EDIT_ENTITYINFO + MENUITEM SEPARATOR + MENUITEM "Brush Scripts...", ID_BRUSH_SCRIPTS + MENUITEM SEPARATOR + MENUITEM "Load Pre&fab...", ID_EDIT_LOADPREFAB + MENUITEM "Save Selection as Prefab...", ID_EDIT_SAVEPREFAB + MENUITEM SEPARATOR + MENUITEM "Preferences...", ID_PREFS + END + POPUP "&View" + BEGIN + POPUP "Toggle" + BEGIN + MENUITEM "Camera View", ID_TOGGLECAMERA + MENUITEM "Console View", ID_TOGGLECONSOLE + MENUITEM "Entity View", ID_VIEW_ENTITY + MENUITEM "Groups View", ID_VIEW_GROUPS + MENUITEM "XY (Top)", ID_TOGGLEVIEW + MENUITEM "YZ (Side)", ID_TOGGLEVIEW_YZ + MENUITEM "XZ (Front)", ID_TOGGLEVIEW_XZ + MENUITEM "Z View", ID_TOGGLEZ + END + MENUITEM SEPARATOR + MENUITEM "&Center\tEnd", ID_VIEW_CENTER + MENUITEM "&Up Floor\tPage Up", ID_VIEW_UPFLOOR + MENUITEM "&Down Floor\tPage Down", ID_VIEW_DOWNFLOOR + MENUITEM SEPARATOR + MENUITEM "&Next (XY, YZ, XY)\tCtrl-TAB", ID_VIEW_NEXTVIEW + POPUP "Layout" + BEGIN + MENUITEM "XY (Top)", ID_VIEW_XY + MENUITEM "YZ", ID_VIEW_SIDE + MENUITEM "XZ", ID_VIEW_FRONT + END + POPUP "Zoom" + BEGIN + MENUITEM "&XY 100%", ID_VIEW_100 + MENUITEM "XY Zoom &In\tDelete", ID_VIEW_ZOOMIN + MENUITEM "XY Zoom &Out\tInsert", ID_VIEW_ZOOMOUT + MENUITEM SEPARATOR + MENUITEM "&Z 100%", ID_VIEW_Z100 + MENUITEM "Z Zoo&m In\tctrl-Delete", ID_VIEW_ZZOOMIN + MENUITEM "Z Zoom O&ut\tctrl-Insert", ID_VIEW_ZZOOMOUT + MENUITEM SEPARATOR + MENUITEM "Cubic Clip Zoom In\tctrl-]", ID_VIEW_CUBEIN + MENUITEM "Cubic Clip Zoom Out\tctrl-[", ID_VIEW_CUBEOUT + END + MENUITEM SEPARATOR + POPUP "Show" + BEGIN + MENUITEM "Show &Names", ID_VIEW_SHOWNAMES + , CHECKED + MENUITEM "Show Blocks", ID_VIEW_SHOWBLOCKS + , CHECKED + MENUITEM "Show C&oordinates", ID_VIEW_SHOWCOORDINATES + , CHECKED + MENUITEM "Show &Entities", ID_VIEW_SHOWENT, CHECKED + MENUITEM "Show &Path", ID_VIEW_SHOWPATH + , CHECKED + MENUITEM "Show &Lights", ID_VIEW_SHOWLIGHTS + , CHECKED + MENUITEM "Show Dynamics", ID_VIEW_SHOWWATER + , CHECKED + MENUITEM "Show Clip &Brush", ID_VIEW_SHOWCLIP + , CHECKED + MENUITEM "Show &Hint Brush", ID_VIEW_SHOWHINT + , CHECKED + MENUITEM "Show Wor&ld", ID_VIEW_SHOWWORLD + , CHECKED + MENUITEM "Show Detail\tctrl-D", ID_VIEW_SHOWDETAIL + , CHECKED + MENUITEM "Show Curves", ID_VIEW_SHOWCURVES + , CHECKED + MENUITEM "Show Caulk", ID_VIEW_SHOWCAULK + , CHECKED + MENUITEM "Show Angles", ID_VIEW_SHOWANGLES + , CHECKED + MENUITEM "Show Vis Portals", ID_VIEW_SHOW_SHOWVISPORTALS + , CHECKED + MENUITEM "Show No Draw", ID_VIEW_SHOW_NODRAW + , CHECKED + MENUITEM "Show Combat Nodes", ID_VIEW_SHOWCOMBATNODES + , CHECKED + MENUITEM "Show Triggers", ID_VIEW_SHOWTRIGGERS + , CHECKED + END + POPUP "Hide/Show" + BEGIN + MENUITEM "Hide Selected", ID_VIEW_HIDESHOW_HIDESELECTED + + MENUITEM "Hide Not Selected", ID_VIEW_HIDESHOW_HIDENOTSELECTED + + MENUITEM "Show Hidden", ID_VIEW_HIDESHOW_SHOWHIDDEN + + END + MENUITEM "Cycle Precision Cursor", ID_PRECISION_CURSOR_CYCLE + MENUITEM SEPARATOR + POPUP "Entities as" + BEGIN + MENUITEM "Bounding box", ID_VIEW_ENTITIESAS_BOUNDINGBOX + + MENUITEM "Wireframe", ID_VIEW_ENTITIESAS_WIREFRAME + + MENUITEM "Selected Wireframe", ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME + + MENUITEM "Selected Skinned", ID_VIEW_ENTITIESAS_SELECTEDSKINNED + + MENUITEM "Skinned", ID_VIEW_ENTITIESAS_SKINNED + + MENUITEM "Skinned and Boxed", ID_VIEW_ENTITIESAS_SKINNEDANDBOXED + + END + MENUITEM SEPARATOR + MENUITEM "Cubic Clipping", ID_VIEW_CUBICCLIPPING + , CHECKED + MENUITEM SEPARATOR + MENUITEM "Render Mode", ID_VIEW_RENDERMODE + MENUITEM "Realtime Rebuild", ID_VIEW_REALTIMEREBUILD + MENUITEM "Render Light Outlines", ID_VIEW_RENDERENTITYOUTLINES + MENUITEM "Material Animation", ID_VIEW_MATERIALANIMATION + MENUITEM "Rebuild Render Data", ID_VIEW_REBUILDRENDERDATA + MENUITEM "Render Selection", ID_VIEW_RENDERSELECTION + MENUITEM "Render Sound", ID_VIEW_RENDERSOUND + END + POPUP "&Selection" + BEGIN + POPUP "Drag" + BEGIN + MENUITEM "Drag &Edges", ID_SELECTION_DRAGEDGES + MENUITEM "Drag &Vertices", ID_SELECTION_DRAGVERTECIES + + END + MENUITEM SEPARATOR + MENUITEM "&Clone", ID_SELECTION_CLONE + MENUITEM "Deselect\tEsc", ID_SELECTION_DESELECT + MENUITEM SEPARATOR + POPUP "Flip" + BEGIN + MENUITEM "Flip &X", ID_BRUSH_FLIPX + MENUITEM "Flip &Y", ID_BRUSH_FLIPY + MENUITEM "Flip &Z", ID_BRUSH_FLIPZ + END + MENUITEM SEPARATOR + POPUP "Rotate" + BEGIN + MENUITEM "Rotate X", ID_BRUSH_ROTATEX + MENUITEM "Rotate Y", ID_BRUSH_ROTATEY + MENUITEM "Rotate Z", ID_BRUSH_ROTATEZ + MENUITEM "Arbitrary rotation...", ID_SELECTION_ARBITRARYROTATION + + END + MENUITEM SEPARATOR + MENUITEM "Scale...", ID_SELECT_SCALE + POPUP "CSG" + BEGIN + MENUITEM "&Hollow", ID_SELECTION_MAKEHOLLOW + MENUITEM "&Subtract", ID_SELECTION_CSGSUBTRACT + MENUITEM "&Merge", ID_SELECTION_CSGMERGE + END + MENUITEM SEPARATOR + POPUP "Select" + BEGIN + MENUITEM "Select Complete &Tall", ID_SELECTION_SELECTCOMPLETETALL + + MENUITEM "Select T&ouching", ID_SELECTION_SELECTTOUCHING + + MENUITEM "Select &Partial Tall", ID_SELECTION_SELECTPARTIALTALL + + MENUITEM "Select &Inside", ID_SELECTION_SELECTINSIDE + + MENUITEM "All Targets", ID_SELECT_ALLTARGETS + MENUITEM "Complete Entity", 32866 + END + MENUITEM SEPARATOR + POPUP "Clipper" + BEGIN + MENUITEM "Toggle Clipper", ID_VIEW_CLIPPER + MENUITEM SEPARATOR + MENUITEM "Clip selection", ID_CLIP_SELECTED + MENUITEM "Split selectedion", ID_SPLIT_SELECTED + MENUITEM "Flip Clip orientation", ID_FLIP_CLIP + END + MENUITEM SEPARATOR + MENUITEM "Connect entities", ID_SELECTION_CONNECT + MENUITEM "Ungroup entity", ID_SELECTION_UNGROUPENTITY + MENUITEM SEPARATOR + MENUITEM "Make detail", ID_SELECTION_MAKE_DETAIL + MENUITEM "Make structural", ID_SELECTION_MAKE_STRUCTURAL + MENUITEM SEPARATOR + MENUITEM "Combine", ID_SELECTION_COMBINE + MENUITEM SEPARATOR + POPUP "Export" + BEGIN + MENUITEM "To OBJ", ID_SELECTION_EXPORT_TOOBJ + + MENUITEM "To CM", ID_SELECTION_EXPORT_TOCM + END + END + POPUP "&Bsp" + BEGIN + MENUITEM SEPARATOR + END + POPUP "&Grid" + BEGIN + MENUITEM "Grid 0.125 \t&Shift + 1", ID_GRID_POINT125 + MENUITEM "Grid 0.25 \t&Shift + 2", ID_GRID_POINT25 + MENUITEM "Grid 0.5 \t&Shift + 3", ID_GRID_POINT5 + MENUITEM "Grid1\t&1", ID_GRID_1 + MENUITEM "Grid2\t&2", ID_GRID_2 + MENUITEM "Grid4\t&3", ID_GRID_4 + MENUITEM "Grid8\t&4", ID_GRID_8, CHECKED + MENUITEM "Grid16\t&5", ID_GRID_16 + MENUITEM "Grid32\t&6", ID_GRID_32 + MENUITEM "Grid64\t&7", ID_GRID_64 + MENUITEM SEPARATOR + MENUITEM "Snap to grid", ID_VIEW_SHOWTRIGGERS + , CHECKED + END + POPUP "Ma&terials" + BEGIN + MENUITEM "Show In &Use\tU", ID_TEXTURES_SHOWINUSE + MENUITEM "Show &All\tCtrl-A", ID_TEXTURES_SHOWALL + MENUITEM "&Hide All", ID_TEXTURES_HIDEALL + MENUITEM SEPARATOR + MENUITEM "&Surface Inspector\tS", ID_TEXTURES_INSPECTOR + MENUITEM SEPARATOR + MENUITEM "Find / Replace...", ID_TEXTURE_REPLACEALL + MENUITEM SEPARATOR + POPUP "Texture Lock" + BEGIN + MENUITEM "Moves", ID_TOGGLE_LOCK, CHECKED + MENUITEM "Rotations", ID_TOGGLE_ROTATELOCK + , CHECKED + END + MENUITEM SEPARATOR + MENUITEM "Reload", ID_TEXTURES_RELOADSHADERS + MENUITEM SEPARATOR + POPUP "Texture Window Scale" + BEGIN + MENUITEM "200%", ID_TEXTURES_TEXTUREWINDOWSCALE_200 + + MENUITEM "100%", ID_TEXTURES_TEXTUREWINDOWSCALE_100 + + MENUITEM "50%", ID_TEXTURES_TEXTUREWINDOWSCALE_50 + + MENUITEM "25%", ID_TEXTURES_TEXTUREWINDOWSCALE_25 + + MENUITEM "10%", ID_TEXTURES_TEXTUREWINDOWSCALE_10 + + END + MENUITEM SEPARATOR + MENUITEM "Generate Material List", ID_MATERIALS_GENERATEMATERIALSLIST + + END + POPUP "&Misc" + BEGIN + MENUITEM "&Benchmark", ID_MISC_BENCHMARK + POPUP "&Colors" + BEGIN + POPUP "Themes" + BEGIN + MENUITEM "QE4 Original", ID_COLOR_SETORIGINAL + MENUITEM "Q3Radiant Original", ID_COLOR_SETQER + MENUITEM "Black and Green", ID_COLOR_SETBLACK + MENUITEM "Max/Maya/Lightwave", ID_THEMES_MAX + MENUITEM "Super Mal", ID_COLOR_SUPERMAL + END + MENUITEM SEPARATOR + MENUITEM "&Texture Background...", ID_TEXTUREBK + MENUITEM "Grid Background...", ID_COLORS_XYBK + MENUITEM "Grid Major...", ID_COLORS_MAJOR + MENUITEM "Grid Minor...", ID_COLORS_MINOR + MENUITEM "Grid Text...", ID_COLORS_GRIDTEXT + MENUITEM "Grid Block...", ID_COLORS_GRIDBLOCK + MENUITEM "Default Brush...", ID_COLORS_BRUSH + MENUITEM "Selected Brush...", ID_COLORS_SELECTEDBRUSH + MENUITEM "Clipper...", ID_COLORS_CLIPPER + MENUITEM "Active View name...", ID_COLORS_VIEWNAME + END + MENUITEM "&Gamma...", ID_MISC_GAMMA + MENUITEM "Find brush...", ID_MISC_FINDBRUSH + MENUITEM "Next leak spot\tctrl-l", ID_MISC_NEXTLEAKSPOT + MENUITEM "Previous leak spot\tctrl-p", ID_MISC_PREVIOUSLEAKSPOT + MENUITEM "&Print XY View", ID_MISC_PRINTXY + MENUITEM "&Select Entity Color...\tK", ID_MISC_SELECTENTITYCOLOR + MENUITEM "Find or Replace Entity", ID_MISC_FINDORREPLACEENTITY + MENUITEM "SetViewPos", ID_MISC_SETVIEWPOS + END + POPUP "&Region" + BEGIN + MENUITEM "&Off", ID_REGION_OFF + MENUITEM "&Set XY", ID_REGION_SETXY + MENUITEM "Set &Tall Brush", ID_REGION_SETTALLBRUSH + MENUITEM "Set &Brush", ID_REGION_SETBRUSH + MENUITEM "Set Se&lected Brushes", ID_REGION_SETSELECTION + END + POPUP "&Brush" + BEGIN + MENUITEM "3 sided\tctrl-3", ID_BRUSH_3SIDED + MENUITEM "4 sided\tctrl-4", ID_BRUSH_4SIDED + MENUITEM "5 sided\tctrl-5", ID_BRUSH_5SIDED + MENUITEM "6 sided\tctrl-6", ID_BRUSH_6SIDED + MENUITEM "7 sided\tctrl-7", ID_BRUSH_7SIDED + MENUITEM "8 sided\tctrl-8", ID_BRUSH_8SIDED + MENUITEM "9 sided\tctrl-9", ID_BRUSH_9SIDED + MENUITEM SEPARATOR + MENUITEM "Arbitrary sided...", ID_BRUSH_ARBITRARYSIDED + MENUITEM SEPARATOR + POPUP "Primitives" + BEGIN + MENUITEM "Cone...", ID_BRUSH_MAKECONE + MENUITEM "Sphere...", ID_BRUSH_PRIMITIVES_SPHERE + + END + END + POPUP "&Patch" + BEGIN + MENUITEM "Cylinder", ID_CURVE_PATCHTUBE + POPUP "More Cylinders" + BEGIN + MENUITEM "Dense Cylinder", ID_CURVE_PATCHDENSETUBE + MENUITEM "Very Dense Cylinder", ID_CURVE_PATCHVERYDENSETUBE + + MENUITEM "Square Cylinder", ID_CURVE_PATCHSQUARE + END + MENUITEM SEPARATOR + MENUITEM "End cap", ID_CURVE_PATCHENDCAP + MENUITEM "Bevel", ID_CURVE_PATCHBEVEL + POPUP "More End caps, Bevels" + BEGIN + MENUITEM "Square Endcap", ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL + + MENUITEM "Square Bevel", ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP + + END + MENUITEM SEPARATOR + MENUITEM "Cone", ID_CURVE_PATCHCONE + MENUITEM "Sphere", ID_CURVE_PRIMITIVES_SPHERE + , GRAYED + MENUITEM SEPARATOR + MENUITEM "Simple Patch Mesh...", ID_CURVE_SIMPLEPATCHMESH + MENUITEM SEPARATOR + POPUP "Insert" + BEGIN + MENUITEM "Insert (2) Columns", ID_CURVE_INSERT_INSERTCOLUMN + + MENUITEM "Add (2) Columns", ID_CURVE_INSERT_ADDCOLUMN + + MENUITEM SEPARATOR + MENUITEM "Insert (2) Rows", ID_CURVE_INSERT_INSERTROW + + MENUITEM "Add (2) Rows", ID_CURVE_INSERT_ADDROW + END + POPUP "Delete" + BEGIN + MENUITEM "First (2) Columns", ID_CURVE_DELETE_FIRSTCOLUMN + + MENUITEM "Last (2) Columns", ID_CURVE_DELETE_LASTCOLUMN + + MENUITEM SEPARATOR + MENUITEM "First (2) Rows", ID_CURVE_DELETE_FIRSTROW + MENUITEM "Last (2) Rows", ID_CURVE_DELETE_LASTROW + END + MENUITEM SEPARATOR + POPUP "Matrix" + BEGIN + MENUITEM "Invert", ID_CURVE_NEGATIVE + POPUP "Re-disperse" + BEGIN + MENUITEM "Cols", ID_CURVE_REDISPERSE_COLS + + MENUITEM "Rows", ID_CURVE_REDISPERSE_ROWS + + END + MENUITEM "Transpose", ID_CURVE_MATRIX_TRANSPOSE + + END + MENUITEM SEPARATOR + POPUP "Cap" + BEGIN + MENUITEM "Normal", ID_CURVE_CAP + MENUITEM "Inverted Bevel", ID_CURVE_CAP_INVERTEDBEVEL + + MENUITEM "Inverted Endcap", ID_CURVE_CAP_INVERTEDENDCAP + + MENUITEM SEPARATOR + MENUITEM "Cycle Cap Texture", ID_CURVE_CYCLECAP + END + MENUITEM SEPARATOR + POPUP "Overlay" + BEGIN + MENUITEM "Set", ID_CURVE_OVERLAY_SET + MENUITEM "Clear", ID_CURVE_OVERLAY_CLEAR + END + MENUITEM SEPARATOR + MENUITEM "Thicken...", ID_CURVE_THICKEN + MENUITEM "Combine", ID_PATCH_COMBINE + MENUITEM SEPARATOR + MENUITEM "Nurb Editor", ID_PATCH_NURBEDITOR + END + POPUP "P&lugins" + BEGIN + MENUITEM "Refresh", ID_PLUGINS_REFRESH + MENUITEM SEPARATOR + END + POPUP "&Help" + BEGIN + MENUITEM "Help\tF1", ID_HELP + MENUITEM SEPARATOR + MENUITEM "Command list...", ID_HELP_COMMANDLIST + MENUITEM SEPARATOR + MENUITEM "&About...", ID_HELP_ABOUT + END +END + +IDR_POPUP_TEXTURE MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "&Wireframe", ID_TEXTURES_WIREFRAME + MENUITEM "&Flat shade", ID_TEXTURES_FLATSHADE + MENUITEM "&Nearest", ID_VIEW_NEAREST + MENUITEM "Nearest &Mipmap", ID_VIEW_NEARESTMIPMAP + MENUITEM "&Linear", ID_VIEW_LINEAR + MENUITEM "&Bilinear", ID_VIEW_BILINEAR + MENUITEM "B&ilinear Mipmap", ID_VIEW_BILINEARMIPMAP + MENUITEM "T&rilinear", ID_VIEW_TRILINEAR + END +END + +IDR_POPUP_SELECTION MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "Select Complete &Tall", ID_SELECTION_SELECTCOMPLETETALL + + MENUITEM "Select T&ouching", ID_SELECTION_SELECTTOUCHING + MENUITEM "Select &Partial Tall", ID_SELECTION_SELECTPARTIALTALL + + MENUITEM "Select &Inside", ID_SELECTION_SELECTINSIDE + END +END + +IDR_POPUP_VIEW MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "XY (Top)", ID_VIEW_XY + MENUITEM "XZ", ID_VIEW_SIDE + MENUITEM "YZ", ID_VIEW_FRONT + END +END + +IDR_MENU_DROP MENU +BEGIN + POPUP "Select" + BEGIN + MENUITEM "Select Complete &Tall", ID_SELECTION_SELECTCOMPLETETALL + + MENUITEM "Select T&ouching", ID_SELECTION_SELECTTOUCHING + MENUITEM "Select &Partial Tall", ID_SELECTION_SELECTPARTIALTALL + + MENUITEM "Select &Inside", ID_SELECTION_SELECTINSIDE + END + POPUP "Force Visibility" + BEGIN + MENUITEM "On", 27395 + MENUITEM "Off", 27396 + END + MENUITEM "Ungroup entity", ID_SELECTION_UNGROUPENTITY + MENUITEM "New Model...", ID_DROP_NEWMODEL + MENUITEM SEPARATOR +END + +IDR_MENU_EV MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open...", 4 + MENUITEM "&Save", 1236 + MENUITEM "E&xit", 1 + END +END + +IDR_POPUP_ENTITY MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "Wireframe", ID_VIEW_ENTITIESAS_WIREFRAME + MENUITEM "Skinned", ID_VIEW_ENTITIESAS_SKINNED + END +END + +IDR_POPUP_GROUP MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "XY (Top)", ID_VIEW_XY + MENUITEM "XZ", ID_VIEW_SIDE + MENUITEM "YZ", ID_VIEW_FRONT + END +END + +IDR_POPUP_SPLINE MENU +BEGIN + POPUP "Popup" + BEGIN + POPUP "New Camera" + BEGIN + MENUITEM "Fixed", ID_POPUP_NEWCAMERA_FIXED + MENUITEM "Interpolated", ID_POPUP_NEWCAMERA_INTERPOLATED + + MENUITEM "Spline", ID_POPUP_NEWCAMERA_SPLINE + + END + MENUITEM "Camera Inspector...", ID_MATERIAL_INFO + MENUITEM SEPARATOR + MENUITEM "Test Camera", ID_SPLINE_TEST + END +END + +IDR_POPUP_MATERIAL MENU +BEGIN + POPUP "Popup" + BEGIN + MENUITEM "Edit...", ID_MATERIAL_EDIT + MENUITEM "Info...", ID_MATERIAL_INFO + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS +BEGIN + "3", ID_BRUSH_3SIDED, VIRTKEY, CONTROL, NOINVERT + "4", ID_BRUSH_4SIDED, VIRTKEY, CONTROL, NOINVERT + "5", ID_BRUSH_5SIDED, VIRTKEY, CONTROL, NOINVERT + "6", ID_BRUSH_6SIDED, VIRTKEY, CONTROL, NOINVERT + "7", ID_BRUSH_7SIDED, VIRTKEY, CONTROL, NOINVERT + "8", ID_BRUSH_8SIDED, VIRTKEY, CONTROL, NOINVERT + "9", ID_BRUSH_9SIDED, VIRTKEY, CONTROL, NOINVERT + "D", ID_VIEW_SHOWDETAIL, VIRTKEY, CONTROL, NOINVERT + "K", ID_SELECTION_CONNECT, VIRTKEY, CONTROL, NOINVERT + "L", ID_MISC_NEXTLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "M", ID_SELECTION_MAKE_DETAIL, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", ID_MISC_PREVIOUSLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_VIEW_ZZOOMIN, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, ID_VIEW_ZZOOMOUT, VIRTKEY, CONTROL, NOINVERT + "X", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT +END + +IDR_MAINFRAME ACCELERATORS +BEGIN + "7", ID_BRUSH_7SIDED, VIRTKEY, CONTROL, NOINVERT + "8", ID_BRUSH_8SIDED, VIRTKEY, CONTROL, NOINVERT + "9", ID_BRUSH_9SIDED, VIRTKEY, CONTROL, NOINVERT + "D", ID_VIEW_SHOWDETAIL, VIRTKEY, CONTROL, NOINVERT + "K", ID_SELECTION_CONNECT, VIRTKEY, CONTROL, NOINVERT + "L", ID_MISC_NEXTLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "M", ID_SELECTION_MAKE_DETAIL, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", ID_MISC_PREVIOUSLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_VIEW_ZZOOMIN, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, ID_SELECTION_SELECT_NUDGEDOWN, VIRTKEY, ALT, NOINVERT + VK_INSERT, ID_VIEW_ZZOOMOUT, VIRTKEY, CONTROL, NOINVERT + "X", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT +END + +IDR_ACCEL_SURFACE ACCELERATORS +BEGIN + VK_ESCAPE, ID_BYEBYE, VIRTKEY, NOINVERT +END + +IDR_MINIACCEL ACCELERATORS +BEGIN + VK_DOWN, ID_SELECTION_SELECT_NUDGEDOWN, VIRTKEY, ALT, NOINVERT + VK_LEFT, ID_SELECTION_SELECT_NUDGELEFT, VIRTKEY, ALT, NOINVERT + VK_RIGHT, ID_SELECTION_SELECT_NUDGERIGHT, VIRTKEY, ALT, NOINVERT + VK_UP, ID_SELECTION_SELECT_NUDGEUP, VIRTKEY, ALT, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FINDTEXTURE DIALOG 0, 0, 129, 53 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Find Texture" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,10,30,50,14 + PUSHBUTTON "Cancel",IDCANCEL,70,30,50,14 + EDITTEXT IDC_EDIT1,10,10,110,14,ES_AUTOHSCROLL +END + +IDD_ENTITY DIALOGEX 0, 0, 234, 354 +STYLE DS_SETFONT | DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | + WS_CLIPSIBLINGS | WS_CAPTION | WS_THICKFRAME +EXSTYLE WS_EX_OVERLAPPEDWINDOW | WS_EX_TOOLWINDOW +CAPTION "Entity" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + LISTBOX IDC_E_LIST,5,5,180,94,LBS_SORT | LBS_NOINTEGRALHEIGHT | + LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP, + WS_EX_CLIENTEDGE + EDITTEXT IDC_E_COMMENT,5,102,180,45,ES_MULTILINE | ES_READONLY | + WS_VSCROLL,WS_EX_CLIENTEDGE + PUSHBUTTON "135",IDC_E_135,5,276,15,15 + PUSHBUTTON "180",IDC_E_180,5,292,15,15 + PUSHBUTTON "225",IDC_E_225,5,306,15,15 + PUSHBUTTON "270",IDC_E_270,21,306,15,15 + PUSHBUTTON "90",IDC_E_90,21,276,15,15 + PUSHBUTTON "45",IDC_E_45,35,276,15,15 + PUSHBUTTON "360",IDC_E_0,35,292,15,15 + PUSHBUTTON "315",IDC_E_315,35,306,15,15 + PUSHBUTTON "Up",IDC_E_UP,60,281,15,15 + PUSHBUTTON "Dn",IDC_E_DOWN,60,297,15,15 + LISTBOX IDC_E_PROPS,5,151,180,91,LBS_SORT | LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT | + WS_VSCROLL | WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "Del Key/Pair",IDC_E_DELPROP,105,281,45,15 + EDITTEXT IDC_E_STATUS,83,298,95,30,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL + LTEXT "Key",IDC_STATIC_KEY,5,246,25,10 + LTEXT "Value",IDC_STATIC_VALUE,5,262,25,10 + EDITTEXT IDC_E_KEY_FIELD,40,245,145,12,ES_AUTOHSCROLL + EDITTEXT IDC_E_VALUE_FIELD,40,261,145,12,ES_AUTOHSCROLL + PUSHBUTTON "Hide",IDC_BTN_HIDE,190,328,7,6 + PUSHBUTTON "Sound...",IDC_BTN_ASSIGNSOUND,198,247,36,11 + PUSHBUTTON "Model...",IDC_BTN_ASSIGNMODEL,198,264,36,11 + CONTROL "Tab1",IDC_TAB_MODE,"SysTabControl32",TCS_BOTTOM | + WS_BORDER,3,338,223,14 +END + +IDD_GAMMA DIALOGEX 0, 0, 135, 94 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Gamma" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_G_EDIT,5,8,46,13,ES_AUTOHSCROLL,WS_EX_CLIENTEDGE + DEFPUSHBUTTON "OK",IDOK,91,5,39,14 + PUSHBUTTON "Cancel",IDCANCEL,91,23,39,14 + LTEXT "0.0 is brightest\n1.0 is darkest\n\nYou must restart for the settings to take effect", + IDC_STATIC,7,25,61,55 +END + +IDD_FINDBRUSH DIALOGEX 0, 0, 127, 76 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Find brush" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,5,55,50,14 + PUSHBUTTON "Cancel",IDCANCEL,65,55,50,14 + EDITTEXT IDC_FIND_ENTITY,80,15,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + EDITTEXT IDC_FIND_BRUSH,80,30,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + LTEXT "Entity number",IDC_STATIC,10,15,60,8 + LTEXT "Brush number",IDC_STATIC,10,30,65,8 +END + +IDD_ROTATE DIALOGEX 0, 0, 128, 91 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrary rotation" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_ROTX,23,3,29,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,52,3,11,14 + EDITTEXT IDC_ROTY,23,21,29,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN2,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,53,21,11,14 + EDITTEXT IDC_ROTZ,23,39,29,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN3,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,53,39,11,14 + DEFPUSHBUTTON "OK",IDOK,82,3,39,14 + PUSHBUTTON "Cancel",IDCANCEL,82,19,39,14 + PUSHBUTTON "Apply",IDC_APPLY,82,39,39,14 + RTEXT "X",IDC_STATIC,8,6,8,8 + RTEXT "Y",IDC_STATIC,8,24,8,8 + RTEXT "Z",IDC_STATIC,8,42,8,8 + CONTROL "Flat Center Rotation",IDC_CHK_FLAT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,11,60,79,10 +END + +IDD_SIDES DIALOGEX 0, 0, 130, 47 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrrary sides" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_SIDES,27,6,40,14,ES_AUTOHSCROLL,WS_EX_CLIENTEDGE + DEFPUSHBUTTON "OK",IDOK,85,4,41,14 + PUSHBUTTON "Cancel",IDCANCEL,85,22,41,14 + LTEXT "Sides:",IDC_STATIC,6,8,20,8 +END + +IDD_ABOUT DIALOG 0, 0, 275, 223 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About DOOM Radiant" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,236,7,35,14 + CONTROL 127,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | + SS_REALSIZEIMAGE | SS_SUNKEN | WS_BORDER,7,7,87,80 + GROUPBOX "OpenGL Properties",IDC_STATIC,5,93,265,56 + LTEXT "Vendor:\t\tWHOEVER",IDC_ABOUT_GLVENDOR,10,101,253,10 + LTEXT "Version:\t\t1.1",IDC_ABOUT_GLVERSION,10,111,249,10 + LTEXT "Renderer:\tWHATEVER",IDC_ABOUT_GLRENDERER,10,121,253,24 + GROUPBOX "OpenGL Extensions",IDC_STATIC,5,152,265,65 + CONTROL "DOOM Radiant 1.0 build 199\nCopyright ©1999, 2003 Id Software, Inc.\n\n", + IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,99,7, + 132,78 + EDITTEXT IDC_ABOUT_GLEXTENSIONS,10,162,256,53,ES_MULTILINE | + ES_AUTOVSCROLL | ES_READONLY | WS_DISABLED | NOT + WS_BORDER +END + +IDD_SURFACE DIALOGEX 400, 100, 449, 249 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Surface inspector" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_HSHIFT,121,22,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_HSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,155,23,11,14 + EDITTEXT IDC_VSHIFT,121,38,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_VSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,155,39,11,14 + EDITTEXT IDC_ROTATE,121,58,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_ROTATE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,155,61,11,14 + EDITTEXT IDC_HSCALE,121,87,43,12,ES_AUTOHSCROLL | ES_WANTRETURN + EDITTEXT IDC_VSCALE,121,103,44,12,ES_AUTOHSCROLL | ES_WANTRETURN + EDITTEXT IDC_EDIT_WIDTH,53,141,30,12,ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "Spin1",IDC_SPIN_WIDTH,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,77,139,11,18 + EDITTEXT IDC_EDIT_HEIGHT,91,141,30,12,ES_AUTOHSCROLL | + ES_WANTRETURN + CONTROL "Spin1",IDC_SPIN_HEIGHT,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,113,138,11,18 + EDITTEXT IDC_TEXTURE,33,6,133,12,ES_AUTOHSCROLL + PUSHBUTTON "CAP",IDC_BTN_PATCHDETAILS,11,158,34,12 + PUSHBUTTON "Ok",IDOK,412,233,34,12 + PUSHBUTTON "Cancel",IDCANCEL,377,233,34,12 + RTEXT "Shift vertically",IDC_STATIC,51,40,65,8 + RTEXT "Scale horizontally",IDC_STATIC,51,89,65,8 + RTEXT "Scale vertically",IDC_STATIC,51,105,65,8 + RTEXT "Rotate",IDC_STATIC,95,60,22,8 + RTEXT "Material",IDC_STATIC,3,8,28,8 + RTEXT "Shift horizontally",IDC_STATIC,51,24,65,8 + GROUPBOX "Texturing",IDC_STATIC,3,125,168,51 + PUSHBUTTON "Natural",IDC_BTN_PATCHNATURAL,50,158,34,12 + PUSHBUTTON "Fit",IDC_BTN_FACEFIT,11,141,34,12 + LTEXT "Width",IDC_STATIC,54,132,20,8 + LTEXT "Height",IDC_STATIC,91,132,22,8 + EDITTEXT IDC_EDIT_HORZ,138,195,21,12,ES_AUTOHSCROLL + GROUPBOX "Texture Tool Goes here",IDC_STATIC,179,7,262,207 + CONTROL "Subdivide Patch",IDC_CHECK_SUBDIVIDE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,3,181,66,11 + CONTROL "Slider1",IDC_SLIDER_HORZ,"msctls_trackbar32", + TBS_AUTOTICKS | WS_TABSTOP,36,193,99,17 + LTEXT "Horizontal",IDC_STATIC,3,196,34,10 + EDITTEXT IDC_EDIT_VERT,137,217,21,12,ES_AUTOHSCROLL + CONTROL "Slider1",IDC_SLIDER_VERT,"msctls_trackbar32", + TBS_AUTOTICKS | WS_TABSTOP,35,215,99,17 + LTEXT "Vertical",IDC_STATIC,3,218,34,10 + PUSHBUTTON "Flip X",IDC_BTN_FLIPX,89,158,34,12 + PUSHBUTTON "Flip Y",IDC_BTN_FLIPY,128,158,34,12 + CONTROL "Absolute",IDC_CHECK_ABSOLUTE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,8,86,41,10 + GROUPBOX "",IDC_STATIC,2,76,168,44 +END + +IDD_DLG_PREFS DIALOGEX 0, 0, 386, 263 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Q3Radiant Preferences" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "",IDC_RADIO_VIEWTYPE,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED | WS_GROUP,18,35,10,10 + CONTROL "",IDC_RADIO_VIEWTYPE2,"Button",BS_AUTORADIOBUTTON,45,35, + 11,10 + CONTROL "",IDC_RADIO_VIEWTYPE3,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED,73,35,11,10 + CONTROL "",IDC_RADIO_VIEWTYPE4,"Button",BS_AUTORADIOBUTTON | + WS_DISABLED,99,35,11,10 + CONTROL "OpenGL display lists",IDC_CHECK_DISPLAYLISTS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,47,79,10 + CONTROL "Solid selection boxes",IDC_CHECK_NOSTIPPLE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,60,82,10 + CONTROL "Slider1",IDC_SLIDER_CAMSPEED,"msctls_trackbar32", + WS_TABSTOP,128,23,92,11 + CONTROL "Update XY views during\nmouse drags", + IDC_CHECK_CAMXYUPDATE,"Button",BS_AUTOCHECKBOX | + BS_MULTILINE | WS_TABSTOP,130,48,91,18 + CONTROL "QE4 update model",IDC_CHECK_QE4PAINTING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,68,75,10 + CONTROL "Slider1",IDC_SLIDER_TEXTUREQUALITY,"msctls_trackbar32", + TBS_AUTOTICKS | WS_TABSTOP,237,34,127,11 + CONTROL "Texture toolbar",IDC_CHECK_TEXTURETOOLBAR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,236,60,63,10 + CONTROL "Texture scrollbar",IDC_CHECK_TEXTURESCROLLBAR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,236,71,68,10 + CONTROL "Texture subset",IDC_CHECK_TEXTUREWINDOW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,308,60,63,10 + CONTROL "Right click to drop entities",IDC_CHECK_RIGHTCLICK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,103,95,10 + CONTROL "Face selection",IDC_CHECK_FACE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,13,115,62,10 + EDITTEXT IDC_EDIT_ROTATION,58,127,24,12,ES_AUTOHSCROLL + CONTROL "ALT + multi-drag",IDC_CHECK_ALTDRAG,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,114,103,68,10 + CONTROL "Snap T to Grid",IDC_CHECK_SNAPT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,114,115,62,10 + CONTROL "Mouse chaser",IDC_CHECK_MOUSECHASE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,114,126,68,10 + CONTROL "Patch Toolbar",IDC_CHECK_WIDETOOLBAR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,193,103,61,10 + CONTROL "Light drawing",IDC_CHECK_LIGHTDRAW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,193,115,58,10 + CONTROL "Paint sizing info",IDC_CHECK_SIZEPAINT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,193,126,65,10 + CONTROL "Hi Color Textures",IDC_CHECK_HICOLOR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,281,103,70,10 + LTEXT "Startup Shaders:",IDC_STATIC,281,116,54,8 + COMBOBOX IDC_COMBO_SHADERS,281,126,82,54,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "Don't clamp plane points",IDC_CHECK_NOCLAMP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,157,93,10 + CONTROL "Snapshots",IDC_CHECK_SNAPSHOTS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,13,168,49,10 + CONTROL "Use +setgame for run",IDC_CHECK_SETGAME,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,181,83,10 + CONTROL "Run game after QBSP3...",IDC_CHECK_RUNQUAKE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,118,157,96,10 + CONTROL "Load last project on open",IDC_CHECK_LOADLAST,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,118,169,96,10 + CONTROL "Load last map on open",IDC_CHECK_LOADLASTMAP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,118,181,88,10 + CONTROL "Auto save every ",IDC_CHECK_AUTOSAVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,118,193,66,10 + EDITTEXT IDC_EDIT_AUTOSAVE,185,193,27,12,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "Spin1",IDC_SPIN_AUTOSAVE,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,209,191,9,14 + LTEXT "Status point size:",IDC_STATIC,256,157,54,8 + EDITTEXT IDC_EDIT_STATUSPOINTSIZE,313,155,29,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_POINTSIZE,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,342,154,9,14 + LTEXT "Undo Levels:",IDC_STATIC,256,170,43,8 + EDITTEXT IDC_EDIT_UNDOLEVELS,313,168,29,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_UNDO,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,342,168,9,14 + DEFPUSHBUTTON "OK",IDOK,341,236,38,14 + PUSHBUTTON "Cancel",IDCANCEL,299,236,38,14 + LTEXT "minutes",IDC_STATIC,213,194,25,8 + GROUPBOX "Views / Rendering",IDC_STATIC,7,4,372,86 + GROUPBOX "Tool settings / Stuff that wouldn't fit anywhere else", + IDC_STATIC,7,145,372,83 + CONTROL 147,IDB_VIEWDEFAULT,"Static",SS_BITMAP,13,14,21,19 + CONTROL 148,IDB_VIEWDEFAULT2,"Static",SS_BITMAP,40,14,21,19 + CONTROL 149,IDB_VIEWDEFAULT3,"Static",SS_BITMAP,67,14,21,19 + GROUPBOX "New functionality:",IDC_STATIC,7,92,372,52 + CONTROL 150,IDB_VIEWDEFAULT_Z,"Static",SS_BITMAP,93,14,21,19 + LTEXT "slow",IDC_STATIC,131,35,15,8 + LTEXT "fast",IDC_STATIC,204,35,12,8 + GROUPBOX "Camera ",IDC_STATIC,126,13,100,72 + LTEXT "Rotation inc:",IDC_STATIC,15,129,41,8 + GROUPBOX "Texturing",IDC_STATIC,231,13,141,72 + LTEXT "Quality",IDC_STATIC,237,23,22,8 + LTEXT "Low",IDC_STATIC,239,47,14,8 + LTEXT "High",IDC_STATIC,347,48,16,8 + LTEXT "Map Path:",IDC_STATIC,13,215,34,8 + EDITTEXT IDC_EDIT_MAPS,49,212,90,12,ES_AUTOHSCROLL + CONTROL "Use new map format",IDC_CHECK_NEWMAPFORMAT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,194,81,10 +END + +IDD_DLG_MAPINFO DIALOG 0, 0, 181, 183 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Map Info" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Close",IDOK,138,7,36,14 + LTEXT "Total Brushes",IDC_STATIC,7,14,50,8 + EDITTEXT IDC_EDIT_TOTALBRUSHES,66,12,40,12,ES_RIGHT | + ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Total Entities",IDC_STATIC,7,30,50,8 + EDITTEXT IDC_EDIT_TOTALENTITIES,66,28,40,12,ES_RIGHT | + ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Net brush count\n(non entity)",IDC_STATIC,7,49,57,17 + EDITTEXT IDC_EDIT_NET,66,47,40,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + LISTBOX IDC_LIST_ENTITIES,7,81,167,95,LBS_SORT | LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LTEXT "Entity breakdown",IDC_STATIC,7,71,56,8 +END + +IDD_DLG_ENTITYLIST DIALOGEX 0, 0, 492, 244 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Entities" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "Close",IDOK,446,223,39,14 + DEFPUSHBUTTON "Select",IDC_SELECT,401,223,39,14 + CONTROL "List2",IDC_LIST_ENTITY,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_EDITLABELS | LVS_NOSORTHEADER | + WS_BORDER | WS_TABSTOP,178,7,307,208 + LISTBOX IDC_LIST_ENTITIES,7,7,165,230,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + +IDD_DLG_SCRIPTS DIALOG 0, 0, 212, 215 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Available Scripts" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "New...",IDC_NEW,166,74,39,14,WS_DISABLED + PUSHBUTTON "Close",IDOK,168,194,37,14 + LISTBOX IDC_LIST_SCRIPTS,7,56,146,152,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Edit...",IDC_EDIT,166,90,39,14,WS_DISABLED + DEFPUSHBUTTON "Run",IDC_RUN,166,56,39,14 + LTEXT "WARNING: BrushScripting is in a highly experimental state and is far from complete. If you attempt to use them it is VERY LIKELY that Q3Radiant will crash. Save your work before attempting to make use of any scripting features.", + IDC_STATIC,7,7,198,38 +END + +IDD_DLG_NEWPROJECT DIALOG 0, 0, 246, 74 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New project" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_EDIT_NAME,57,28,116,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,189,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,189,24,50,14 + LTEXT "This will create a new directory beneath your Quake2 path based on the project name you give.", + IDC_STATIC,7,7,165,19 + LTEXT "Project name:",IDC_STATIC,7,30,44,8 + CONTROL "Include game dll files",IDC_CHECK1,"Button", + BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,49,81,10 +END + +IDD_DLG_COMMANDLIST DIALOG 0, 0, 283, 223 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Mapped Commands" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Close",IDOK,241,202,35,14 + LISTBOX IDC_LIST_COMMANDS,7,7,221,209,LBS_SORT | LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + +IDD_DIALOG_SCALE DIALOG 0, 0, 122, 74 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Scale" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,79,7,36,14 + PUSHBUTTON "Cancel",IDCANCEL,79,23,36,14 + LTEXT "X:",IDC_STATIC,7,15,8,8 + LTEXT "Y:",IDC_STATIC,7,32,8,8 + LTEXT "Z:",IDC_STATIC,7,49,8,8 + EDITTEXT IDC_EDIT_X,22,13,32,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_Y,22,30,32,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_Z,22,47,32,12,ES_AUTOHSCROLL +END + +IDD_DIALOG_FINDREPLACE DIALOGEX 0, 0, 222, 98 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Find replace texture(s)" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_FIND,27,16,132,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_REPLACE,45,31,114,12,ES_AUTOHSCROLL + CONTROL "Replace within selected brushes only", + IDC_CHECK_SELECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 7,51,133,10 + CONTROL "Force replacement (ignore current texture name)", + IDC_CHECK_FORCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7, + 63,167,10 + DEFPUSHBUTTON "OK",IDOK,175,7,40,14 + PUSHBUTTON "Close",IDCANCEL,175,77,40,14 + LTEXT "Find:",IDC_STATIC,7,18,16,8 + LTEXT "Replace:",IDC_STATIC,7,33,30,8 + DEFPUSHBUTTON "Apply",IDC_BTN_APPLY,175,25,40,14 + CONTROL "Live updates from Texture/Camera Windows", + IDC_CHECK_LIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7, + 79,157,10 +END + +IDD_DIALOG_STAIRS DIALOG 0, 0, 196, 143 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Stairs" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,147,7,42,14 + PUSHBUTTON "Cancel",IDCANCEL,136,24,42,14 + LTEXT "This creates a set of stairs using the selected brush as a template. You may optionally specify a rotation angle to be applied to each new step", + IDC_STATIC,7,7,120,37 + LTEXT "After pressing OK, left click to select a ""height"" point for the stairs. Enough stairs will be created to consume the hieght (Z) between the selected brush and the point you specify", + IDC_STATIC,7,46,116,53 + LTEXT "Rotation per step:",IDC_STATIC,7,104,57,8 + EDITTEXT IDC_EDIT_ROTATION,69,102,40,12,ES_AUTOHSCROLL +END + +IDD_DIALOG_INPUT DIALOG 0, 0, 171, 173 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "BrushScript Input" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,127,7,37,14 + PUSHBUTTON "Cancel",IDCANCEL,127,24,37,14 + LTEXT "Field1:",IDC_STATIC_FIELD1,7,13,96,8 + EDITTEXT IDC_EDIT_FIELD1,7,23,47,14,ES_AUTOHSCROLL + LTEXT "Field1:",IDC_STATIC_FIELD2,7,41,105,8 + EDITTEXT IDC_EDIT_FIELD2,7,51,47,14,ES_AUTOHSCROLL + LTEXT "Field1:",IDC_STATIC_FIELD3,7,71,115,8 + EDITTEXT IDC_EDIT_FIELD3,7,81,47,14,ES_AUTOHSCROLL + LTEXT "Field1:",IDC_STATIC_FIELD4,7,103,129,8 + EDITTEXT IDC_EDIT_FIELD4,7,113,47,14,ES_AUTOHSCROLL + LTEXT "Field1:",IDC_STATIC_FIELD5,7,133,135,8 + EDITTEXT IDC_EDIT_FIELD5,7,142,47,14,ES_AUTOHSCROLL +END + +IDD_DLG_INFORMATION DIALOGEX 0, 0, 186, 95 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Information" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_EDIT1,7,7,172,81,ES_MULTILINE | WS_DISABLED | + WS_VSCROLL +END + +IDD_PROJECT DIALOGEX 250, 100, 341, 335 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Project Settings" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_PRJBASEPATH,75,20,205,12,ES_AUTOHSCROLL + EDITTEXT IDC_PRJMAPSPATH,75,40,205,12,ES_AUTOHSCROLL + EDITTEXT IDC_PRJRSHCMD,75,60,205,12,ES_AUTOHSCROLL + EDITTEXT IDC_PRJREMOTEBASE,75,80,205,12,ES_AUTOHSCROLL + EDITTEXT IDC_PRJENTITYPATH,75,100,205,12,ES_AUTOHSCROLL + EDITTEXT IDC_PRJTEXPATH,75,120,205,12,ES_AUTOHSCROLL + LISTBOX IDC_CMD_LIST,10,157,270,90,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP, + WS_EX_CLIENTEDGE + PUSHBUTTON "Add...",IDC_ADDCMD,290,150,45,13 + PUSHBUTTON "Change...",IDC_EDITCMD,290,167,45,13 + PUSHBUTTON "Remove",IDC_REMCMD,290,184,45,13 + CONTROL "Use brush primitives in MAP files",IDC_CHECK_BPRIMIT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,270,136,9 + DEFPUSHBUTTON "OK",IDOK,290,10,45,13 + PUSHBUTTON "Cancel",IDCANCEL,290,26,45,13 + GROUPBOX "Project settings",IDC_STATIC,5,7,280,133 + LTEXT "basepath",IDC_STATIC,42,22,30,8 + LTEXT "rshcmd",IDC_STATIC,48,62,24,8 + LTEXT "remotebasepath",IDC_STATIC,20,82,52,8 + LTEXT "entitypath",IDC_STATIC,40,102,32,8 + LTEXT "texturepath",IDC_STATIC,36,122,36,8 + GROUPBOX "Menu commands",IDC_STATIC,5,146,280,105 + LTEXT "mapspath",IDC_STATIC,40,42,32,8 + GROUPBOX "Misc settings",IDC_STATIC,5,258,280,73 +END + +IDD_ADDCMD DIALOG 300, 200, 312, 65 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add command" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,116,44,37,13 + PUSHBUTTON "Cancel",IDCANCEL,159,44,37,13 + EDITTEXT IDC_CMDMENUTEXT,44,8,254,12,ES_AUTOHSCROLL + EDITTEXT IDC_CMDCOMMAND,44,26,254,12,ES_AUTOHSCROLL + LTEXT "Menu text",IDC_STATIC,5,10,32,8 + LTEXT "Command",IDC_STATIC,5,28,32,8 +END + +IDD_TEXTUREBAR DIALOG 0, 0, 313, 19 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_HSHIFT,33,4,32,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_HSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,56,3,10,14 + EDITTEXT IDC_VSHIFT,76,4,32,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_VSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,97,3,11,14 + EDITTEXT IDC_HSCALE,143,4,32,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_HSCALE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,164,3,11,14 + EDITTEXT IDC_VSCALE,188,4,32,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_VSCALE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,210,3,11,14 + EDITTEXT IDC_ROTATE,252,4,32,12,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_ROTATE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,272,3,11,14 + LTEXT "Shift H",IDC_STATIC,7,6,22,8 + LTEXT "V",IDC_STATIC,68,6,8,8 + LTEXT "Scale H",IDC_STATIC,112,6,26,8 + LTEXT "V",IDC_STATIC,180,6,8,8 + LTEXT "Rotate",IDC_STATIC,226,6,22,8 + DEFPUSHBUTTON "Button1",IDC_BTN_APPLYTEXTURESTUFF,278,2,11,8,NOT + WS_VISIBLE | NOT WS_TABSTOP + EDITTEXT IDC_EDIT_ROTATEAMT,287,4,20,12,ES_AUTOHSCROLL +END + +IDD_DIALOG_TEXTURELIST DIALOGEX 0, 0, 314, 318 +STYLE DS_SETFONT | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "&Load",IDC_LOAD,7,7,35,12,WS_DISABLED + CONTROL "Tree1",IDC_TREE_TEXTURES,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | WS_BORDER | + WS_TABSTOP,7,24,300,137 + DEFPUSHBUTTON "&Reload",IDC_REFRESH,45,7,35,12 + CONTROL "",IDC_PREVIEW,"Static",SS_BLACKFRAME | SS_NOTIFY | + SS_SUNKEN,7,166,300,145 + CONTROL "Hide root entries",IDC_CHECK_HIDEROOT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,163,7,67,10 +END + +IDD_DIALOG_NEWPATCH DIALOG 0, 0, 129, 58 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Patch density" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,90,7,32,14 + PUSHBUTTON "Cancel",IDCANCEL,90,24,32,14 + LTEXT "Width:",IDC_STATIC,9,9,22,8 + LTEXT "Height:",IDC_STATIC,7,27,24,8 + COMBOBOX IDC_COMBO_WIDTH,38,7,33,51,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + COMBOBOX IDC_COMBO_HEIGHT,38,25,33,51,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP +END + +IDD_DIALOG_TEXTURELAYOUT DIALOG 0, 0, 186, 95 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Patch texture layout" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,141,7,38,14 + PUSHBUTTON "Cancel",IDCANCEL,141,24,38,14 + LTEXT "Texture will be fit across the patch based on the x and y values given. Values of 1x1 will ""fit"" the texture. 2x2 will repeat it twice, etc.", + IDC_STATIC,7,7,122,36 + LTEXT "Texture x:",IDC_STATIC,7,48,32,8 + EDITTEXT IDC_EDIT_X,42,46,30,12,ES_AUTOHSCROLL + LTEXT "Texture y:",IDC_STATIC,7,64,32,8 + EDITTEXT IDC_EDIT_Y,42,62,30,12,ES_AUTOHSCROLL +END + +IDD_DIALOG_CAP DIALOG 0, 0, 171, 84 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Cap" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,123,7,41,14 + PUSHBUTTON "Cancel",IDCANCEL,123,25,41,14 + CONTROL "Bevel",IDC_RADIO_CAP,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,31,10,50,10 + CONTROL "Endcap",IDC_RADIO_CAP2,"Button",BS_AUTORADIOBUTTON,31, + 28,50,10 + CONTROL "Inverted Bevel",IDC_RADIO_CAP3,"Button", + BS_AUTORADIOBUTTON,31,47,68,10 + CONTROL "Inverted Endcap",IDC_RADIO_CAP4,"Button", + BS_AUTORADIOBUTTON,31,65,75,10 + CONTROL 177,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE | + SS_SUNKEN,7,7,18,15 + CONTROL 178,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE | + SS_SUNKEN,7,44,18,15 + CONTROL 176,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE | + SS_SUNKEN,7,26,18,15 + CONTROL 175,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE | + SS_SUNKEN,7,63,17,14 +END + +IDD_DIALOG_THICKEN DIALOG 0, 0, 204, 63 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Thicken Patch" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,158,7,39,14 + PUSHBUTTON "Cancel",IDCANCEL,158,24,39,14 + LTEXT "This produces a func_grouped set of patches that contains the original patch along with the 'thick' patch and an optional set of seam patches. ", + IDC_STATIC,7,7,145,33 + EDITTEXT IDC_EDIT_AMOUNT,38,42,26,12,ES_AUTOHSCROLL + LTEXT "Amount:",IDC_STATIC,7,44,27,8 + CONTROL "Seams",IDC_CHECK_SEAMS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,74,43,37,10 +END + +IDD_DIALOG_PATCH DIALOG 0, 0, 272, 178 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Patch Properties" +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_COMBO_ROW,15,29,34,79,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_COL,54,29,34,84,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_X,34,49,54,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_Y,33,64,55,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_Z,33,81,55,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_S,33,98,55,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_T,33,115,55,12,ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_TYPE,33,134,55,79,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_NAME,106,29,144,12,ES_AUTOHSCROLL + EDITTEXT IDC_HSHIFT,107,48,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_HSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,141,48,11,14 + EDITTEXT IDC_VSHIFT,107,64,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_VSHIFT,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,141,64,11,14 + EDITTEXT IDC_HSCALE,107,81,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_HSCALE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,141,81,11,14 + EDITTEXT IDC_VSCALE,107,98,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_VSCALE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,141,98,11,14 + EDITTEXT IDC_ROTATE,107,115,45,12,ES_AUTOHSCROLL + CONTROL "Spin2",IDC_SPIN_ROTATE,"msctls_updown32",UDS_ALIGNRIGHT | + UDS_AUTOBUDDY | UDS_ARROWKEYS,141,114,11,14 + PUSHBUTTON "CAP",IDC_BTN_PATCHDETAILS,109,134,32,13 + PUSHBUTTON "Set...",IDC_BTN_PATCHRESET,148,134,32,13 + PUSHBUTTON "Natural",IDC_BTN_PATCHNATURAL,185,134,32,13 + PUSHBUTTON "Fit",IDC_BTN_PATCHFIT,225,134,32,13 + PUSHBUTTON "Apply",IDC_APPLY,184,159,38,12 + DEFPUSHBUTTON "Done",IDOK,227,159,38,12 + LTEXT "Row:",IDC_STATIC,15,17,18,8 + LTEXT "Column:",IDC_STATIC,54,17,26,8 + LTEXT "X:",IDC_STATIC,21,51,8,8 + LTEXT "Y:",IDC_STATIC,21,66,8,8 + LTEXT "Z:",IDC_STATIC,21,83,8,8 + LTEXT "S:",IDC_STATIC,21,100,8,8 + LTEXT "T:",IDC_STATIC,21,117,8,8 + LTEXT "Name:",IDC_STATIC,106,17,22,8 + LTEXT "Vertical shift",IDC_STATIC,157,66,65,8 + LTEXT "Horizontal stretch",IDC_STATIC,157,83,65,8 + LTEXT "Vertical stretch",IDC_STATIC,157,100,65,8 + LTEXT "Rotate",IDC_STATIC,157,117,30,8 + LTEXT "Horizontal shift",IDC_STATIC,157,51,65,8 + GROUPBOX "Texturing",IDC_STATIC,99,7,166,148 + GROUPBOX "Details",IDC_STATIC,7,7,87,148 + LTEXT "Type:",IDC_STATIC,13,136,19,8 +END + +IDD_PLAYWAVE DIALOG 0, 0, 33, 15 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "Play",IDC_BTN_PLAY,0,0,33,15 +END + +IDD_TEXLIST DIALOG 0, 0, 251, 273 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Load multiple texture paths" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Load",IDOK,194,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,194,24,50,14 + LISTBOX IDC_LIST_TEXTURES,7,7,179,259,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + +IDD_DLG_GROUP DIALOG 0, 0, 224, 241 +STYLE DS_SETFONT | DS_CONTROL | WS_CHILD | WS_BORDER +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Tree1",IDC_TREE_GROUP,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | + TVS_SHOWSELALWAYS | TVS_CHECKBOXES | TVS_TRACKSELECT | + WS_BORDER | WS_TABSTOP,7,7,210,209 + PUSHBUTTON "Add...",IDC_BTN_ADD,7,221,33,12 + PUSHBUTTON "Delete",IDC_BTN_DEL,83,221,33,12 + PUSHBUTTON "Edit...",IDC_BTN_EDIT,44,221,33,12 + PUSHBUTTON "Hide All",IDC_BTN_HIDEALL,135,221,33,12 + PUSHBUTTON "Show All",IDC_BTN_SHOWALL,174,221,33,12 +END + +IDD_DIALOG_LIGHT DIALOGEX 0, 0, 311, 287 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Light Inspector" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Equilateral Radius",IDC_CHECK_EQUALRADIUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,22,73,10 + EDITTEXT IDC_EDIT_RADIUSX,39,41,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RADIUSY,63,41,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RADIUSZ,86,41,19,12,ES_AUTOHSCROLL + CONTROL "0.0",IDC_RADIO_FALLOFF,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,11,67,26,10 + CONTROL "0.5",IDC_RADIO_FALLOFF2,"Button",BS_AUTORADIOBUTTON,38, + 67,26,10 + CONTROL "1.0",IDC_RADIO_FALLOFF3,"Button",BS_AUTORADIOBUTTON,66, + 67,26,10 + EDITTEXT IDC_EDIT_TARGETX,37,152,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_TARGETY,61,152,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_TARGETZ,84,152,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RIGHTX,37,167,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RIGHTY,61,167,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_RIGHTZ,84,167,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_UPX,37,181,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_UPY,61,181,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_UPZ,84,181,19,12,ES_AUTOHSCROLL + CONTROL "Explicit start/end points",IDC_CHECK_EXPLICITFALLOFF, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,197,89,10 + EDITTEXT IDC_EDIT_STARTX,37,209,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_STARTY,61,209,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_STARTZ,84,209,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ENDX,37,223,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ENDY,61,223,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_ENDZ,83,223,19,12,ES_AUTOHSCROLL + PUSHBUTTON "",IDC_BTN_COLOR,163,38,22,10,BS_BITMAP + CONTROL "Cast Shadows",IDC_CHECK_SHADOWS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,135,17,59,10 + CONTROL "Cast Diffuse",IDC_CHECK_DIFFUSE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,198,18,51,8 + CONTROL "Cast Specular",IDC_CHECK_SPECULAR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,252,18,58,8 + DEFPUSHBUTTON "OK",IDOK,7,270,40,14 + PUSHBUTTON "Apply",IDC_APPLY,102,270,40,14 + PUSHBUTTON "Cancel",IDCANCEL,54,270,40,14 + GROUPBOX "",IDC_STATIC,7,13,123,106 + GROUPBOX "",IDC_STATIC,7,134,123,133 + LTEXT "Fall-off",IDC_STATIC,9,57,22,8 + LTEXT "Color",IDC_STATIC,141,39,17,8 + LTEXT "Texture",IDC_STATIC,135,68,25,8 + LTEXT "Radius",IDC_STATIC,15,43,23,8 + LTEXT "X",IDC_STATIC,46,33,8,8 + LTEXT "Y",IDC_STATIC,70,33,8,8 + LTEXT "Z",IDC_STATIC,93,33,8,8 + RTEXT "Target",IDC_STATIC,11,154,22,8 + LTEXT "X",IDC_STATIC,44,144,8,8 + LTEXT "Y",IDC_STATIC,68,144,8,8 + LTEXT "Z",IDC_STATIC,91,144,8,8 + RTEXT "Right",IDC_STATIC,15,169,18,8 + RTEXT "Up",IDC_STATIC,23,182,10,8 + RTEXT "Start",IDC_STATIC,17,211,16,8 + RTEXT "End",IDC_STATIC,19,225,14,8 + COMBOBOX IDC_COMBO_TEXTURE,163,67,141,116,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + CONTROL "Point Light",IDC_CHECK_POINT,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,7,7,48,10 + CONTROL "Projected Light",IDC_CHECK_PROJECTED,"Button", + BS_AUTORADIOBUTTON,7,123,63,12 + CONTROL "Center",IDC_CHECK_CENTER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,11,105,37,10 + EDITTEXT IDC_EDIT_CENTERX,49,104,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_CENTERY,73,104,19,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_CENTERZ,96,104,19,12,ES_AUTOHSCROLL + LTEXT "X",IDC_STATIC,56,96,8,8 + LTEXT "Y",IDC_STATIC,80,96,8,8 + LTEXT "Z",IDC_STATIC,103,96,8,8 + CONTROL "Parallel",IDC_CHECK_PARALLEL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,11,90,39,10 + CONTROL "Slider1",IDC_SLIDER_BRIGHTNESS,"msctls_trackbar32", + WS_TABSTOP,228,36,76,15 + LTEXT "Brightness",IDC_STATIC,195,39,34,8 + CONTROL "",IDC_LIGHTPREVIEW,"Static",SS_BLACKFRAME | SS_NOTIFY | + SS_SUNKEN,137,91,173,175 + PUSHBUTTON "Apply Different",IDC_APPLY_DIFFERENT,150,270,60,14 +END + +IDD_DLG_CAMERA DIALOGEX 0, 0, 277, 295 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Camera Inspector" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "Close",IDOK,220,274,50,14 + LTEXT "Name",IDC_STATIC,7,14,24,8 + EDITTEXT IDC_EDIT_CAM_NAME,32,12,154,12,ES_AUTOHSCROLL + LTEXT "Edit >",IDC_STATIC,11,70,20,8 + COMBOBOX IDC_COMBO_SPLINES,33,68,154,81,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add Target...",IDC_BTN_ADDTARGET,34,54,53,11 + SCROLLBAR IDC_SCROLLBAR_SEGMENT,14,168,165,10 + LTEXT "Length ( seconds )",IDC_STATIC,14,140,60,8 + EDITTEXT IDC_EDIT_LENGTH,75,138,30,12,ES_AUTOHSCROLL + LTEXT "Current Time:",IDC_STATIC,14,156,43,8 + LISTBOX IDC_LIST_EVENTS,14,207,152,65,LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Time",IDC_STATIC,7,129,200,159 + EDITTEXT IDC_EDIT_SEGMENT,61,154,40,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_READONLY + LTEXT "Events",IDC_STATIC,14,195,23,8 + PUSHBUTTON "Add...",IDC_BTN_ADDEVENT,171,207,32,11 + PUSHBUTTON "Del",IDC_BTN_DELEVENT,171,221,32,11 + DEFPUSHBUTTON "Apply",IDC_APPLY,220,91,50,14 + DEFPUSHBUTTON "Load...",ID_FILE_OPEN,220,26,50,14 + DEFPUSHBUTTON "Save...",ID_FILE_SAVE,220,42,50,14 + DEFPUSHBUTTON "New",ID_FILE_NEW,220,7,50,14 + DEFPUSHBUTTON "Preview",IDC_TESTCAMERA,220,109,50,14 + CONTROL "Track Camera",IDC_CHECK_TRACKCAMERA,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,14,180,61,10 + LTEXT "of",IDC_STATIC,109,155,11,9 + EDITTEXT IDC_EDIT_TOTALSEGMENTS,122,154,35,12,ES_RIGHT | + ES_AUTOHSCROLL | ES_READONLY + GROUPBOX "Path and Target editing",IDC_STATIC,7,43,201,83 + CONTROL "Edit Points",IDC_RADIO_EDITPOINTS,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,13,86,52,9 + CONTROL "Add Points",IDC_RADIO_EDITPOINTS2,"Button", + BS_AUTORADIOBUTTON,13,97,52,9 + PUSHBUTTON "Delete Selected",IDC_BTN_DELETEPOINTS,13,109,61,11 + LTEXT "Type:",IDC_STATIC,7,30,20,9 + EDITTEXT IDC_EDIT_TYPE,32,28,48,12,ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "Select All",IDC_BTN_SELECTALL,78,109,61,11 +END + +IDD_DLG_CAMERAEVENT DIALOG 0, 0, 166, 188 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Camera Event" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Wait",IDC_RADIO_EVENT,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,15,18,31,10 + CONTROL "Target wait",IDC_RADIO9,"Button",BS_AUTORADIOBUTTON,15, + 28,51,10 + CONTROL "Speed",IDC_RADIO10,"Button",BS_AUTORADIOBUTTON,15,38,37, + 10 + CONTROL "Change target",IDC_RADIO5,"Button",BS_AUTORADIOBUTTON, + 15,48,61,10 + CONTROL "Snap target",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON,15, + 58,53,10 + CONTROL "FOV",IDC_RADIO7,"Button",BS_AUTORADIOBUTTON,15,68,30,10 + CONTROL "Cmd",IDC_RADIO8,"Button",BS_AUTORADIOBUTTON,15,78,30,10 + CONTROL "Trigger",IDC_RADIO11,"Button",BS_AUTORADIOBUTTON,15,88, + 38,10 + CONTROL "Stop",IDC_RADIO12,"Button",BS_AUTORADIOBUTTON,15,98,31, + 10 + CONTROL "Switch Cameras",IDC_RADIO13,"Button",BS_AUTORADIOBUTTON, + 15,108,67,10 + CONTROL "Fade Out",IDC_RADIO14,"Button",BS_AUTORADIOBUTTON,15, + 118,45,10 + CONTROL "Fade In",IDC_RADIO15,"Button",BS_AUTORADIOBUTTON,15,128, + 40,10 + CONTROL "Feather",IDC_RADIO16,"Button",BS_AUTORADIOBUTTON,15,139, + 40,10 + EDITTEXT IDC_EDIT_PARAM,7,169,124,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,124,7,35,14 + PUSHBUTTON "Cancel",IDCANCEL,123,24,35,14 + GROUPBOX "Type",IDC_STATIC,7,7,81,147 + LTEXT "Paremeter:",IDC_STATIC,7,159,35,8 +END + +IDD_DLG_CAMERATARGET DIALOG 0, 0, 194, 93 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Camera Target" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Fixed",IDC_RADIO_FIXED,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,15,38,37,10 + CONTROL "Interpolated",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,15, + 49,60,11 + CONTROL "Spline",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,15,61,60, + 11 + DEFPUSHBUTTON "OK",IDOK,146,7,41,11 + PUSHBUTTON "Cancel",IDCANCEL,146,21,41,11 + LTEXT "Name:",IDC_STATIC,7,7,23,10 + EDITTEXT IDC_EDIT_NAME,32,7,105,12,ES_AUTOHSCROLL + GROUPBOX "Type",IDC_STATIC,7,26,130,53 +END + +IDD_DLG_WAIT DIALOGEX 0, 0, 186, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Please wait..." +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_WAITSTR,7,7,172,38,ES_CENTER | ES_MULTILINE | + WS_DISABLED | NOT WS_BORDER + PUSHBUTTON "Cancel",IDCANCEL,68,51,50,14 +END + +IDD_DIALOG_ENTITY DIALOGEX 0, 0, 262, 292 +STYLE DS_SETFONT | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IDC_COMBO_CLASS,7,17,212,134,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Gui...",IDC_BUTTON_GUI,213,265,42,14 + PUSHBUTTON "Sound...",IDC_BUTTON_SOUND,213,250,42,14 + PUSHBUTTON "Model...",IDC_BUTTON_MODEL,213,234,42,14 + PUSHBUTTON "Dn",IDC_E_DOWN,58,261,15,15 + PUSHBUTTON "Up",IDC_E_UP,58,245,15,15 + PUSHBUTTON "315",IDC_E_315,37,270,15,15 + PUSHBUTTON "270",IDC_E_270,23,270,15,15 + PUSHBUTTON "225",IDC_E_225,7,270,15,15 + PUSHBUTTON "360",IDC_E_0,37,256,15,15 + PUSHBUTTON "180",IDC_E_180,7,256,15,15 + PUSHBUTTON "45",IDC_E_45,37,240,15,15 + PUSHBUTTON "90",IDC_E_90,23,240,15,15 + PUSHBUTTON "135",IDC_E_135,7,240,15,15 + PUSHBUTTON "X",IDC_BUTTON_BROWSE,244,217,11,11 + EDITTEXT IDC_EDIT_VAL,23,218,217,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_KEY,23,203,217,12,ES_AUTOHSCROLL + LISTBOX IDC_LIST_KEYVAL,7,111,248,85,LBS_OWNERDRAWVARIABLE | + LBS_HASSTRINGS | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Create",IDC_BUTTON_CREATE,221,18,34,11 + LTEXT "Entity Class",IDC_STATIC_TITLE,7,7,37,8 + LTEXT "Key",IDC_STATIC_KEY,7,205,13,8 + LTEXT "Val",IDC_STATIC_VAL,7,220,11,8 + LISTBOX IDC_LIST_VARS,7,35,248,73,LBS_OWNERDRAWVARIABLE | + LBS_HASSTRINGS | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Particle...",IDC_BUTTON_PARTICLE,168,265,42,14 + COMBOBOX IDC_ENTITY_ANIMATIONS,74,234,79,101,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_ANIMATION_SLIDER,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,75,249,100,15 + PUSHBUTTON "Play",IDC_ENTITY_PLAY_ANIM,157,234,19,14 + DEFPUSHBUTTON "Stop",IDC_ENTITY_STOP_ANIM,180,234,20,14 + LTEXT "Static",IDC_ENTITY_CURRENT_ANIM,189,253,19,8 + PUSHBUTTON "Skin...",IDC_BUTTON_SKIN,119,265,42,14 + PUSHBUTTON "Curve...",IDC_BUTTON_CURVE,73,264,42,14 +END + +IDD_DIALOG_COLORS DIALOG 0, 0, 383, 206 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Color Picker" +FONT 8, "Tahoma" +BEGIN + GROUPBOX "RGB",IDC_STATIC_RGB_RECT,7,3,138,157 + GROUPBOX "HSBO",IDC_STATIC_HSB_RECT,150,3,180,157 + EDITTEXT IDC_EDIT_RED,13,181,32,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_RED,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,37,179,11, + 14 + EDITTEXT IDC_EDIT_GREEN,51,182,33,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_GREEN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,77,180,11, + 14 + EDITTEXT IDC_EDIT_BLUE,91,182,33,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_BLUE,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,117,180, + 11,14 + EDITTEXT IDC_EDIT_HUE,156,182,33,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_HUE,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,181,180, + 11,14 + EDITTEXT IDC_EDIT_SAT,195,182,33,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_SAT,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,221,180, + 11,14 + EDITTEXT IDC_EDIT_VAL,235,182,31,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_VAL,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,259,180, + 11,14 + PUSHBUTTON "Old Color...",IDC_BTN_OLDCOLOR,332,188,47,14 + DEFPUSHBUTTON "OK",IDOK,339,7,38,14 + PUSHBUTTON "Cancel",IDCANCEL,339,24,38,14 + LTEXT "Saturation",IDC_STATIC,196,173,33,8 + GROUPBOX "RGB Values",IDC_STATIC,7,163,137,39 + LTEXT "Red",IDC_STATIC,15,172,14,8 + LTEXT "Green",IDC_STATIC,51,173,20,8 + LTEXT "Blue",IDC_STATIC,91,173,15,8 + GROUPBOX "HSBO Values",IDC_STATIC,152,163,169,39 + LTEXT "Hue",IDC_STATIC,158,174,14,8 + LTEXT "Brightness",IDC_STATIC,236,173,34,8 + PUSHBUTTON "1",IDC_BUTTON_COLOR1,335,70,14,13 + PUSHBUTTON "2",IDC_BUTTON_COLOR2,359,70,14,13 + EDITTEXT IDC_EDIT_OVERBRIGHT,277,182,31,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_OVERBRIGHT,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,301,180,11,14 + LTEXT "Overbright",IDC_STATIC,278,173,36,8 + LTEXT "Static",IDC_STATIC_NEWCOLOR,343,156,22,18,WS_BORDER + LTEXT "Presets, click to assign",IDC_STATIC,333,44,44,18 +END + +IDD_DIALOG_INSPECTORS DIALOGEX 0, 0, 330, 327 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_THICKFRAME +CAPTION "Inspectors" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_TAB_INSPECTOR,"SysTabControl32",TCS_BOTTOM | + TCS_HOTTRACK | TCS_MULTILINE | TCS_TOOLTIPS | + TCS_FOCUSNEVER,7,307,316,13 +END + +IDD_DIALOG_TEXTURE DIALOGEX 0, 0, 274, 335 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_POPUP | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Custom1",IDC_CUSTOM1,"",WS_TABSTOP,7,7,260,321 +END + +IDD_DIALOG_GETSTRING DIALOGEX 0, 0, 207, 114 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Input needed..." +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,32,93,50,14 + PUSHBUTTON "Cancel",IDCANCEL,121,93,50,14 + LTEXT "Static",IDC_PROMPT,7,7,193,47 + EDITTEXT IDC_EDIT1,11,66,185,15,ES_AUTOHSCROLL +END + +IDD_ENTFINDREPLACE DIALOGEX 0, 0, 425, 129 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Entity key Find / Replace (F3 = find next)" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,164,108,87,14 + PUSHBUTTON "Find",IDC_FIND,33,108,121,14 + PUSHBUTTON "Replace",IDC_REPLACE,259,108,121,14 + GROUPBOX "FIND",IDC_STATIC,7,10,177,84,BS_CENTER + EDITTEXT IDC_EDIT_FIND_KEY,39,22,121,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_FIND_VALUE,39,45,121,14,ES_AUTOHSCROLL + RTEXT "Key",IDC_STATIC,23,25,13,8 + RTEXT "Value",IDC_STATIC,7,46,29,8 + GROUPBOX "FIND",IDC_STATIC,226,10,177,84,BS_CENTER + EDITTEXT IDC_EDIT_REPLACE_KEY,258,23,121,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_REPLACE_VALUE,258,45,121,14,ES_AUTOHSCROLL + RTEXT "Key",IDC_STATIC,242,26,13,8 + RTEXT "Value",IDC_STATIC,234,47,21,8 + PUSHBUTTON "->",IDC_KEYCOPY,190,22,31,14 + PUSHBUTTON "->",IDC_VALUECOPY,190,46,31,14 + CONTROL "Whole-string match only", + IDC_CHECK_FIND_WHOLESTRINGMATCHONLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,41,64,93,10 + CONTROL "Select all matching ents at once", + IDC_CHECK_SELECTALLMATCHING,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,41,77,117,10 +END + +IDD_DIALOG_PREVIEW DIALOGEX 0, 0, 328, 322 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | + WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOPMOST +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,285,301,36,14 + PUSHBUTTON "Cancel",IDCANCEL,246,301,36,14 + CONTROL "",IDC_TREE_MEDIA,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | WS_BORDER | + WS_TABSTOP,7,7,314,165 + CONTROL "",IDC_PREVIEW,"Static",SS_BLACKFRAME | SS_NOTIFY | + SS_SUNKEN,7,175,173,140 + EDITTEXT IDC_EDIT_INFO,185,175,136,118,ES_MULTILINE | + ES_AUTOVSCROLL | ES_READONLY + PUSHBUTTON "Reload",IDC_BUTTON_RELOAD,185,301,36,14 + PUSHBUTTON "Play",IDC_BUTTON_PLAY,7,175,36,14 +END + +IDD_DIALOG_CONSOLE DIALOGEX 0, 0, 295, 292 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_CONSOLE,7,7,281,261,ES_MULTILINE | WS_VSCROLL | + NOT WS_TABSTOP + EDITTEXT IDC_EDIT_INPUT,7,273,281,12,ES_AUTOHSCROLL | + ES_WANTRETURN +END + +IDD_DIALOG_COMMENTS DIALOGEX 0, 0, 225, 115 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Commented Item" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,177,7,41,14 + PUSHBUTTON "Cancel",IDCANCEL,177,25,41,14 + LTEXT "Name:",IDC_STATIC,7,9,22,8 + EDITTEXT IDC_EDIT_NAME,33,7,135,12,ES_AUTOHSCROLL + LTEXT "Path:",IDC_STATIC,7,23,18,8 + EDITTEXT IDC_EDIT_PATH,33,21,135,12,ES_AUTOHSCROLL + LTEXT "Comments:",IDC_STATIC,7,38,37,8 + EDITTEXT IDC_EDIT_COMMENTS,48,37,122,71,ES_MULTILINE | + ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL +END + +IDD_DIALOG_EDITVIEW DIALOGEX 0, 0, 546, 367 +STYLE DS_SETFONT | DS_NOIDLEMSG | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_WINDOWEDGE +CAPTION "Media Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Close",IDOK,503,7,36,14 + EDITTEXT IDC_EDIT_INFO,7,25,532,313,ES_MULTILINE | ES_AUTOVSCROLL | + ES_NOHIDESEL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL + PUSHBUTTON "Save",IDC_BUTTON_SAVE,46,7,36,14 + PUSHBUTTON "Open...",IDC_BUTTON_OPEN,7,7,36,14 + LTEXT "Current Line:",IDC_STATIC_LINE,105,348,43,8 + DEFPUSHBUTTON "Goto",IDC_BUTTON_GOTO,7,346,36,14 + EDITTEXT IDC_EDIT_GOTO,45,347,40,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_LINE,152,348,40,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER +END + +IDD_DIALOG_EDITPREVIEW DIALOGEX 0, 0, 328, 322 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION | WS_THICKFRAME +EXSTYLE WS_EX_OVERLAPPEDWINDOW +CAPTION "Media Preview" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_PREVIEW,"Static",SS_BLACKFRAME | SS_NOTIFY | + SS_SUNKEN,7,7,314,308 +END + +IDD_DIALOG_NEWCURVE DIALOGEX 0, 0, 186, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Edit Curve Type" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + COMBOBOX IDC_COMBO_CURVES,8,7,114,200,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "id Software" + VALUE "FileDescription", "DOOM 3" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "DOOM 3" + VALUE "LegalCopyright", "Copyright (C) 2004 id Software" + VALUE "OriginalFilename", "Doom.EXE" + VALUE "ProductName", "DOOM 3" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_GAMMA, DIALOG + BEGIN + RIGHTMARGIN, 127 + BOTTOMMARGIN, 76 + END + + IDD_ROTATE, DIALOG + BEGIN + BOTTOMMARGIN, 65 + END + + IDD_SIDES, DIALOG + BEGIN + RIGHTMARGIN, 126 + BOTTOMMARGIN, 45 + END + + IDD_SURFACE, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 446 + BOTTOMMARGIN, 234 + END + + IDD_DLG_PREFS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 379 + TOPMARGIN, 4 + BOTTOMMARGIN, 256 + END + + IDD_DLG_MAPINFO, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 174 + TOPMARGIN, 7 + BOTTOMMARGIN, 176 + END + + IDD_DLG_ENTITYLIST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 485 + TOPMARGIN, 7 + BOTTOMMARGIN, 237 + END + + IDD_DLG_SCRIPTS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 205 + TOPMARGIN, 7 + BOTTOMMARGIN, 208 + END + + IDD_DLG_NEWPROJECT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 239 + TOPMARGIN, 7 + BOTTOMMARGIN, 67 + END + + IDD_DLG_COMMANDLIST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 276 + TOPMARGIN, 7 + BOTTOMMARGIN, 216 + END + + IDD_DIALOG_SCALE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 115 + TOPMARGIN, 7 + BOTTOMMARGIN, 67 + END + + IDD_DIALOG_FINDREPLACE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 80 + END + + IDD_DIALOG_STAIRS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 189 + TOPMARGIN, 7 + BOTTOMMARGIN, 136 + END + + IDD_DIALOG_INPUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 164 + TOPMARGIN, 7 + BOTTOMMARGIN, 166 + END + + IDD_DLG_INFORMATION, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END + + IDD_ADDCMD, DIALOG + BEGIN + BOTTOMMARGIN, 60 + END + + IDD_DIALOG_TEXTURELIST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 307 + TOPMARGIN, 7 + BOTTOMMARGIN, 311 + END + + IDD_DIALOG_NEWPATCH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 122 + TOPMARGIN, 7 + BOTTOMMARGIN, 51 + END + + IDD_DIALOG_TEXTURELAYOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END + + IDD_DIALOG_CAP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 164 + TOPMARGIN, 7 + BOTTOMMARGIN, 77 + END + + IDD_DIALOG_THICKEN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 197 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + + IDD_DIALOG_PATCH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 265 + TOPMARGIN, 7 + BOTTOMMARGIN, 171 + END + + IDD_TEXLIST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 244 + TOPMARGIN, 7 + BOTTOMMARGIN, 266 + END + + IDD_DLG_GROUP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 217 + TOPMARGIN, 7 + BOTTOMMARGIN, 233 + END + + IDD_DIALOG_LIGHT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 304 + TOPMARGIN, 7 + BOTTOMMARGIN, 284 + END + + IDD_DLG_CAMERA, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 270 + TOPMARGIN, 7 + BOTTOMMARGIN, 288 + END + + IDD_DLG_CAMERAEVENT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 159 + TOPMARGIN, 7 + BOTTOMMARGIN, 181 + END + + IDD_DLG_CAMERATARGET, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 187 + TOPMARGIN, 7 + BOTTOMMARGIN, 86 + END + + IDD_DLG_WAIT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IDD_DIALOG_ENTITY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 255 + TOPMARGIN, 7 + BOTTOMMARGIN, 285 + END + + IDD_DIALOG_INSPECTORS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 323 + TOPMARGIN, 7 + BOTTOMMARGIN, 320 + END + + IDD_DIALOG_TEXTURE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 267 + TOPMARGIN, 7 + BOTTOMMARGIN, 328 + END + + IDD_DIALOG_PREVIEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 321 + TOPMARGIN, 7 + BOTTOMMARGIN, 315 + END + + IDD_DIALOG_CONSOLE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 288 + TOPMARGIN, 7 + BOTTOMMARGIN, 285 + END + + IDD_DIALOG_COMMENTS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 218 + TOPMARGIN, 7 + BOTTOMMARGIN, 108 + END + + IDD_DIALOG_EDITVIEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 539 + TOPMARGIN, 7 + BOTTOMMARGIN, 360 + END + + IDD_DIALOG_EDITPREVIEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 321 + TOPMARGIN, 7 + BOTTOMMARGIN, 315 + END + + IDD_DIALOG_NEWCURVE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_DIALOG_NEWCURVE DLGINIT +BEGIN + IDC_COMBO_CURVES, 0x403, 17, 0 +0x6143, 0x6d74, 0x6c75, 0x526c, 0x6d6f, 0x7053, 0x696c, 0x656e, "\000" + IDC_COMBO_CURVES, 0x403, 6, 0 +0x754e, 0x6272, 0x0073, + 0 +END + +IDD_DIALOG_NEWPATCH DLGINIT +BEGIN + IDC_COMBO_WIDTH, 0x403, 2, 0 +0x0033, + IDC_COMBO_WIDTH, 0x403, 2, 0 +0x0035, + IDC_COMBO_WIDTH, 0x403, 2, 0 +0x0037, + IDC_COMBO_WIDTH, 0x403, 2, 0 +0x0039, + IDC_COMBO_WIDTH, 0x403, 3, 0 +0x3131, "\000" + IDC_COMBO_WIDTH, 0x403, 3, 0 +0x3331, "\000" + IDC_COMBO_WIDTH, 0x403, 3, 0 +0x3531, "\000" + IDC_COMBO_HEIGHT, 0x403, 2, 0 +0x0033, + IDC_COMBO_HEIGHT, 0x403, 2, 0 +0x0035, + IDC_COMBO_HEIGHT, 0x403, 2, 0 +0x0037, + IDC_COMBO_HEIGHT, 0x403, 2, 0 +0x0039, + IDC_COMBO_HEIGHT, 0x403, 3, 0 +0x3131, "\000" + IDC_COMBO_HEIGHT, 0x403, 3, 0 +0x3331, "\000" + IDC_COMBO_HEIGHT, 0x403, 3, 0 +0x3531, "\000" + 0 +END + +IDD_DLG_PREFS DLGINIT +BEGIN + IDC_COMBO_SHADERS, 0x403, 5, 0 +0x6f4e, 0x656e, "\000" + IDC_COMBO_SHADERS, 0x403, 7, 0 +0x6f43, 0x6d6d, 0x6e6f, "\000" + IDC_COMBO_SHADERS, 0x403, 4, 0 +0x6c41, 0x006c, + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_MAINFRAME "Doom 3" + IDR_RADIANTYPE "\nRadian\nRadian\n\n\nRadiant.Document\nRadian Document" + IDR_SHADERTYPE "\nUntitled\nSHADER Document\nShader Files (*.shader)\n.shader\nShaderFileType\nSHADER File Type\nSHADER\nShader Files\n" +END + +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE "DOOM" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE +BEGIN + ID_FILE_NEW "Create a new document\nNew" + ID_FILE_OPEN "Open an existing map\nOpen" + ID_FILE_CLOSE "Close the active document\nClose" + ID_FILE_SAVE "Save the active map\nSave" + ID_FILE_SAVE_AS "Save the active document with a new name\nSave As" + ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup" + ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup" + ID_FILE_PRINT "Print the active document\nPrint" + ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview" +END + +STRINGTABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright\nAbout" + ID_APP_EXIT "Quit the application; prompts to save documents\nExit" +END + +STRINGTABLE +BEGIN + ID_FILE_MRU_FILE1 "Open this document" + ID_FILE_MRU_FILE2 "Open this document" + ID_FILE_MRU_FILE3 "Open this document" + ID_FILE_MRU_FILE4 "Open this document" + ID_FILE_MRU_FILE5 "Open this document" + ID_FILE_MRU_FILE6 "Open this document" + ID_FILE_MRU_FILE7 "Open this document" + ID_FILE_MRU_FILE8 "Open this document" + ID_FILE_MRU_FILE9 "Open this document" + ID_FILE_MRU_FILE10 "Open this document" + ID_FILE_MRU_FILE11 "Open this document" + ID_FILE_MRU_FILE12 "Open this document" + ID_FILE_MRU_FILE13 "Open this document" + ID_FILE_MRU_FILE14 "Open this document" + ID_FILE_MRU_FILE15 "Open this document" + ID_FILE_MRU_FILE16 "Open this document" +END + +STRINGTABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane\nNext Pane" + ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane" +END + +STRINGTABLE +BEGIN + ID_WINDOW_NEW "Open another window for the active document\nNew Window" + ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons" + ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows" + ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows" + ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows" + ID_WINDOW_SPLIT "Split the active window into panes\nSplit" +END + +STRINGTABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection\nErase" + ID_EDIT_CLEAR_ALL "Erase everything\nErase All" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut" + ID_EDIT_FIND "Find the specified text\nFind" + ID_EDIT_PASTE "Insert Clipboard contents\nPaste" + ID_EDIT_REPEAT "Repeat the last action\nRepeat" + ID_EDIT_REPLACE "Replace specific text with different text\nReplace" + ID_EDIT_SELECT_ALL "Select the entire document\nSelect All" + ID_EDIT_UNDO "Undo the last action\nUndo" + ID_EDIT_REDO "Redo the previously undone action\nRedo" +END + +STRINGTABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar" + ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" + AFX_IDS_MDICHILD "Activate this window" +END + +STRINGTABLE +BEGIN + AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview" +END + +STRINGTABLE +BEGIN + ID_VIEW_XY "View original layout (Top)" + ID_VIEW_SIDE "Side view" + ID_VIEW_FRONT "Front view" + ID_VIEW_CAMERATOGGLE "Toggle full time camera preview\nCamera preview" + ID_TEXTURES_POPUP "Texture view mode\nTexture view mode" + ID_POPUP_SELECTION "Selection\nSelection" + ID_VIEW_CHANGE "Change views\nChange views" + ID_VIEW_CAMERAUPDATE "Update Camera\nUpdate Camera" + ID_VIEW_CLIPPER "Set clipper mode\nClipper" + ID_PREFS "Preferences\nPreferences" + ID_EDIT_MAPINFO "Entity Information\nEntity list" + ID_BRUSH_SCRIPTS "Define and run BrushScripts\nBrushScripts" +END + +STRINGTABLE +BEGIN + ID_HELP_COMMANDLIST "Provides a list of the currently bound commands" +END + +STRINGTABLE +BEGIN + ID_SELECTION_SELECTINSIDE "Select Inside\nSelect Inside" +END + +STRINGTABLE +BEGIN + ID_VIEW_ENTITY "Toggle entity inspector\nEntity inspector" +END + +STRINGTABLE +BEGIN + ID_SELECT_BRUSHESONLY "Brushes are your friend, only select them\nOnly select brushes." + ID_SELECT_BYBOUNDINGBRUSH + "Select primitives by bounding brush\nSelect primitives by bounding brush" + ID_VIEW_RENDERMODE "Camera view shows render data\nCamera view shows render data" + ID_VIEW_REBUILDRENDERDATA + "Rebuild render data now\nRebuild render data now" + ID_VIEW_REALTIMEREBUILD "Rebuild render data in realtime\nRebuild render data in realtime" + ID_VIEW_RENDERENTITYOUTLINES + "Render light entities in render mode\nRender light entities in render mode" + ID_VIEW_MATERIALANIMATION + "Render material (shader) animation\nRender material (shader) animation" +END + +STRINGTABLE +BEGIN + ID_SELECT_NOMODELS "Don't select models\nDon't select models" + ID_VIEW_RENDERSOUND "Render sound\nRender sound" + ID_SOUND_POPUP "Show sound volumes when selected\nShow sound volumes when selected" + ID_SOUND_SHOWSOUNDVOLUMES + "Always show sound volumes\nAlways show sound volumes" + ID_SPLINES_EDITPOINTS "Edit Curve Points\nEdit Curve Points" + ID_SPLINES_ADDPOINTS "Add Curve Points\nAdd Curve Points" + ID_SPLINES_INSERTPOINTS "Insert Curve Point\nInsert Curve Point" + ID_SPLINES_DELETEPOINTS "Delete Curve Point\nDelete Curve Point" +END + +STRINGTABLE +BEGIN + ID_BRUSH_FLIPX "Flip selected brushes along x-axis\nx-axis Flip" + ID_BRUSH_FLIPY "Flip selected brushes along y-axis\ny-axis Flip" + ID_BRUSH_FLIPZ "Flip selected brushes along z-axis\nz-axis Flip" + ID_BRUSH_ROTATEX "Rotate selected brushes along x-axis\nx-axis Rotate" + ID_BRUSH_ROTATEY "Rotate selected brushes along y-axis\ny-axis Rotate" + ID_BRUSH_ROTATEZ "Rotate selected brushes along z-axis\nz-axis Rotate" +END + +STRINGTABLE +BEGIN + ID_SELECTION_MAKEHOLLOW "Hollow Selection\nHollow" + ID_SELECTION_SELECTPARTIALTALL "Select Partial Tall\nSelect Partial Tall" +END + +STRINGTABLE +BEGIN + ID_SELECTION_SELECTCOMPLETETALL "Complete Tall\nComplete Tall" + ID_SELECTION_CSGSUBTRACT "CSG Subtract\nCSG Subtract" + ID_SELECTION_SELECTTOUCHING "Select Touching\nSelect Touching" +END + +STRINGTABLE +BEGIN + ID_SELECT_MOUSEROTATE "Free rotation\nFree Rotation" + ID_TEXTURE_REPLACESELECTED + "Find and replace texture names in selected brushes/faces" + ID_TEXTURE_REPLACEALL "Find and replace texture names in all brushes/faces" + ID_SELECT_COMPLETE_ENTITY + "Select the entire entity from the currently selected brushes." + ID_SCALELOCKX "Scale X\nScale X" + ID_SCALELOCKY "Scale Y\nScale Y" + ID_SCALELOCKZ "Scale Z\nScale Z" + ID_VIEW_CUBICCLIPPING "Cubic clip the camera view\nCubic clip the camera view" + ID_FILE_PROJECTSETTINGS "View and edit project attributes" + ID_VIEW_CUBEOUT "Zoom cubic clip out" + ID_VIEW_CUBEIN "Zoom cubic clip in" +END + +STRINGTABLE +BEGIN + ID_FILE_SAVEREGION "Save defined region" + ID_FILE_LOADREGION "Load saved region" + ID_TOOLBAR_MAIN "Standard toolbar" + ID_TOOLBAR_TEXTURE "Texture control toolbar" + ID_TEXTURES_LOAD "Load from a specific directory" + ID_CURVE_CYLINDER "Create a cylinder" +END + +STRINGTABLE +BEGIN + ID_FILE_IMPORTMAP "Load map, leaving current map intact" + ID_FILE_EXPORTMAP "Save selection into map file" + ID_EDIT_LOADPREFAB "Load .map from prefab path" + ID_VIEW_SHOWCURVES "Show Curved brushes" + ID_TEXTURES_LOADLIST "Loads from material list" + ID_DONTSELECTCURVE "Select all primitives with bounding brushes\nSelect all primitives with bounding brushes" +END + +STRINGTABLE +BEGIN + ID_CONVERTCURVES "Turns selected brush into a new test curve" + ID_PATCH_SHOWBOUNDINGBOX + "Show primitive bounding box\nShow primitive bounding box" + ID_CURVE_SIMPLEPATCHMESH "Builds a flat patch mesh, you specify the size" + ID_PATCH_WIREFRAME "Show patches as wireframes\nShow patches as wireframes" + ID_PATCH_WELD "Welds equal patch points during moves\nWelds equal patch points during moves" + ID_CURVE_PATCHTUBE "Create a cylinder" + ID_CURVE_PATCHENDCAP "Create an endcap" + ID_CURVE_PATCHBEVEL "Create a bevel" + ID_PATCH_DRILLDOWN "Selects drill down rows and columns\nSelects drill down rows and columns" + ID_CURVE_LOADPATCHFILE "Load corresponding .patch file\nLoad corresponding .patch file" + ID_CURVE_INSERTROW "Inserts a row in the selected patch(s)\nInserts a row in the selected patch(s)" + ID_CURVE_INSERTCOLUMN "Inserts a column in the selected patch(s)\nInserts a column in the selected patch(s)" +END + +STRINGTABLE +BEGIN + ID_CURVE_DELETEROW "Deletes a row in the current patch(s)\nDeletes a row in the current patch(s)" + ID_CURVE_DELETECOLUMN "Deletes a column in the current Patch(s)\nDeletes a column in the current Patch(s)" + ID_PATCH_INSDEL "Redisperse patch points\nRedisperse patch points" + ID_CURVE_INSERT_ADDCOLUMN + "Add a column to the end of the patch\nAdd a column to the end of the patch" + ID_CURVE_INSERT_INSERTCOLUMN + "Insert a column at the beginning of the patch\nInsert a column at the beginning of the patch" + ID_CURVE_INSERT_ADDROW "Add a row at the end of the patch\nAdd a row at the end of the patch" + ID_CURVE_INSERT_INSERTROW + "Insert a row at the beginning of the patch\nInsert a row at the beginning of the patch" + ID_CURVE_DELETE_FIRSTCOLUMN + "Delete the first (2) columns\nDelete the first (2) columns" + ID_CURVE_DELETE_LASTCOLUMN + "Delete the last (2) columns\nDelete the last (2) columns" + ID_CURVE_DELETE_FIRSTROW + "Delete the first (2) rows\nDelete the first (2) rows" + ID_CURVE_DELETE_LASTROW "Delete the last (2) rows\nDelete the last (2) rows" + ID_CURVE_NEGATIVE "Toggle negative flag\nToggle negative flag" + ID_PATCH_BEND "Patch Bend mode\nPatch Bend mode" + ID_CURVE_PATCHDENSETUBE "Create a dense tube" + ID_CURVE_PATCHVERYDENSETUBE "Create a very dense cylinder" + ID_CURVE_CAP "Put caps on the current patch\nPut caps on the current patch" +END + +STRINGTABLE +BEGIN + ID_CURVE_REDISPERSE_ROWS + "Re-disperse rows across the dimensions of the patch" + ID_CURVE_REDISPERSE_COLS + "Re-disperse columns across the dimensions of the patch" + ID_CURVE_PATCHSQUARE "Create a very square cylinder" + ID_TEXTURES_FLUSH "Flush texture palette" +END + +STRINGTABLE +BEGIN + ID_TEXTURES_RELOADSHADERS + "Reload Shaders and apply visual changes to current map" + ID_SHOW_ENTITIES "Show models as\nShow Models as" +END + +STRINGTABLE +BEGIN + ID_VIEW_OPENGLLIGHTING "Toggle OpenGL Lighting" + ID_SELECTION_CSGMERGE "CSG Merge\nCSG Merge" +END + +STRINGTABLE +BEGIN + ID_SHOW_LIGHTVOLUMES "Show Light Volumes\nShow Light Volumes" + ID_SHOW_DOOM "Enable DOOM\n" + ID_SELECTION_MOVEONLY "Move selection only ( No size )\nMove selection only ( No size )" +END + +STRINGTABLE +BEGIN + ID_SPLINES_POPUP "Spline options\nSpline options" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/Radiant_resource.h b/sys/win32/rc/Radiant_resource.h new file mode 100644 index 000000000..f5ff947d1 --- /dev/null +++ b/sys/win32/rc/Radiant_resource.h @@ -0,0 +1,879 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_FINDTEXTURE 10000 +#define IDD_ENTITY 10001 +#define IDD_GAMMA 10002 +#define IDD_FINDBRUSH 10003 +#define IDD_ROTATE 10004 +#define IDD_SIDES 10005 +#define IDD_ABOUT 10006 +#define IDD_SURFACE 10007 +#define IDD_PROJECT 10008 +#define IDD_TEXTUREBAR 10009 +#define IDD_ADDCMD 10010 +#define IDD_PLAYWAVE 10011 +#define IDD_TEXLIST 10012 +#define IDD_DLG_PREFS 10013 +#define IDD_DLG_MAPINFO 10014 +#define IDD_DLG_ENTITYLIST 10015 +#define IDD_DLG_SCRIPTS 10016 +#define IDD_DLG_NEWPROJECT 10017 +#define IDD_DLG_COMMANDLIST 10018 +#define IDD_DLG_INFORMATION 10019 +#define IDD_DLG_GROUP 10020 +#define IDD_DLG_CAMERA 10021 +#define IDD_DLG_CAMERAEVENT 10022 +#define IDD_DLG_CAMERATARGET 10023 +#define IDD_DLG_WAIT 10024 +#define IDD_DIALOG_SCALE 10025 +#define IDD_DIALOG_FINDREPLACE 10026 +#define IDD_DIALOG_STAIRS 10027 +#define IDD_DIALOG_INPUT 10028 +#define IDD_DIALOG_TEXTURELIST 10029 +#define IDD_DIALOG_NEWPATCH 10030 +#define IDD_DIALOG_TEXTURELAYOUT 10031 +#define IDD_DIALOG_CAP 10032 +#define IDD_DIALOG_THICKEN 10033 +#define IDD_DIALOG_PATCH 10034 +#define IDD_DIALOG_LIGHT 10035 +#define IDD_DIALOG_ENTITY 10036 +#define IDD_DIALOG_COLORS 10037 +#define IDD_DIALOG_INSPECTORS 10038 +#define IDD_DIALOG_TEXTURE 10039 +#define IDD_DIALOG_PREVIEW 10040 +#define IDD_DIALOG_CONSOLE 10041 +#define IDD_DIALOG_COMMENTS 10042 +#define IDD_DIALOG_EDITVIEW 10043 +#define IDD_DIALOG_EDITPREVIEW 10044 +#define IDD_DIALOG_NEW_INSPECTORS 10045 +#define IDD_DIALOG_NEWCURVE 10046 +#define IDD_DIALOG_GETSTRING 10047 +#define IDD_ENTFINDREPLACE 10048 +#define IDR_ACCELERATOR1 10049 +#define IDR_ACCEL_SURFACE 10050 +#define IDR_MINIACCEL 10051 +#define IDR_MAINFRAME 10052 +#define IDR_RADIANTYPE 10053 +#define IDR_SHADERFRAME 10054 +#define IDR_SHADERTYPE 10055 +#define IDR_TOOLBAR1 10056 +#define IDR_TOOLBAR_SCALELOCK 10057 +#define IDR_TOOLBAR_ADVANCED 10058 +#define IDR_MENU_DROP 10059 +#define IDR_MENU_QUAKE3 10060 +#define IDR_MENU_EV 10061 +#define IDR_POPUP_TEXTURE 10062 +#define IDR_POPUP_SELECTION 10063 +#define IDR_POPUP_VIEW 10064 +#define IDR_POPUP_GROUP 10065 +#define IDR_POPUP_SPLINE 10066 +#define IDR_POPUP_MATERIAL 10067 +#define IDR_POPUP_ENTITY 10068 +#define IDB_IENDCAP 10069 +#define IDB_ENDCAP 10070 +#define IDB_BEVEL 10071 +#define IDB_IBEVEL 10072 +#define IDB_VIEWQE4 10073 +#define IDB_VIEW4WAY 10074 +#define IDB_VIEWDEFAULT 10075 +#define IDB_VIEWDEFAULT2 10076 +#define IDB_VIEWDEFAULT3 10077 +#define IDB_VIEWDEFAULT_Z 10078 +#define IDB_BITMAP_GROUPS 10079 +#define IDB_BITMAP_MATERIAL 10080 +#define IDB_BITMAP_HSB 10081 +#define IDB_BITMAP_RGB 10082 + +#define IDC_VIEWDEFAULT 10200 +#define IDC_VIEWDEFAULT_Z 10201 +#define IDC_SELECT 10202 +#define IDC_APPLY 10203 +#define IDC_REFRESH 10204 +#define IDC_BUTTON_RELOAD 10205 +#define IDC_BUTTON_ADD 10206 +#define IDC_BUTTON_OPEN 10207 +#define IDC_APPLY2 10208 +#define IDC_APPLY_DIFFERENT 10209 +#define IDC_BUTTON_PLAY 10210 +#define IDC_CHECK1 10211 +#define IDC_TESTCAMERA 10212 +#define IDC_CHECK_LIVE 10213 +#define IDC_BTN_HIDE 10214 +#define IDC_SPIN1 10215 +#define IDC_SPIN2 10216 +#define IDC_SPIN3 10217 +#define IDC_RADIO2 10218 +#define IDC_RADIO3 10219 +#define IDC_RADIO_VIEWTYPE 10220 +#define IDC_RADIO_FALLOFF2 10221 +#define IDC_RADIO_VIEWTYPE2 10222 +#define IDC_RADIO_FALLOFF3 10223 +#define IDC_RADIO_VIEWTYPE3 10224 +#define IDC_LIST_ENTITIES 10225 +#define IDC_RADIO_VIEWTYPE4 10226 +#define IDC_EDIT_TOTALBRUSHES 10227 +#define IDC_CHECK_LOADLAST 10228 +#define IDC_CHECK_AUTOSAVE 10229 +#define IDC_CHECK_LOADLASTMAP 10230 +#define IDC_LIST_ENTITY 10231 +#define IDC_LIST_SCRIPTS 10232 +#define IDC_NEW 10233 +#define IDC_EDIT 10234 +#define IDC_EDIT_NAME 10235 +#define IDC_RUN 10236 +#define IDC_LIST_COMMANDS 10237 +#define IDC_CHECK_FACE 10238 +#define IDC_CHECK_RIGHTCLICK 10239 +#define IDC_CHECK_TEXTUREWINDOW 10240 +#define IDC_CHECK_TEXTURETOOLBAR 10241 +#define IDC_CHECK_LIGHTDRAW 10242 +#define IDC_CHECK_SNAPT 10243 +#define IDC_CHECK_TEXTURESCROLLBAR 10244 +#define IDC_CHECK_RUNQUAKE 10245 +#define IDC_CHECK_SETGAME 10246 +#define IDC_CHECK_DISPLAYLISTS 10247 +#define IDC_EDIT_AUTOSAVE 10248 +#define IDC_CHK_FLAT 10249 +#define IDC_CHECK_NEWMAPFORMAT 10250 +#define IDC_BTN_APPLYTEXTURESTUFF 10251 +#define IDC_CHECK_QE4PAINTING 10252 +#define IDC_BTN_PLAY 10253 +#define IDC_BTN_ADD 10254 +#define IDC_BTN_TEXTURE 10255 +#define IDC_BTN_PREVIEW 10256 +#define IDC_BTN_ADDTARGET 10257 +#define IDC_BTN_SET 10258 +#define IDC_BTN_OLDCOLOR 10259 +#define IDC_BUTTON_MODEL 10260 +#define IDC_SPIN_AUTOSAVE 10261 +#define IDC_BTN_DEL 10262 +#define IDC_BUTTON_SOUND 10263 +#define IDC_CHECK_SIZEPAINT 10264 +#define IDC_BTN_EDIT 10265 +#define IDC_BUTTON_GUI 10266 +#define IDC_EDIT_X 10267 +#define IDC_SPIN_UNDO 10268 +#define IDC_BTN_HIDEALL 10269 +#define IDC_BUTTON_PARTICLE 10270 +#define IDC_CHECK_SNAPSHOTS 10271 +#define IDC_BTN_SHOWALL 10272 +#define IDC_BUTTON_SKIN 10273 +#define IDC_EDIT_FIND 10274 +#define IDC_SPIN_POINTSIZE 10275 +#define IDC_BUTTON_CURVE 10276 +#define IDC_EDIT_REPLACE 10277 +#define IDC_EDIT_S 10278 +#define IDC_CHECK_SELECTED 10279 +#define IDC_EDIT_T 10280 +#define IDC_CHECK_FORCE 10281 +#define IDC_EDIT1 10282 +#define IDC_ROTATE_BOX 10283 +#define IDC_ROTZ 10284 +#define IDC_EDIT_TOTALENTITIES 10285 +#define IDC_EDIT_Y 10286 +#define IDC_EDIT_KEY 10287 +#define IDC_EDIT_INPUT 10288 +#define IDC_EDIT_PATH 10289 +#define IDC_PARTICLE_EDIT2 10290 +#define IDC_ROTY 10291 +#define IDC_EDIT_NET 10292 +#define IDC_EDIT_Z 10293 +#define IDC_EDIT_COMMENTS 10294 +#define IDC_E_VALUE_FIELD 10295 +#define IDC_E_LIST 10296 +#define IDC_E_COMMENT 10297 +#define IDC_E_PROPS 10298 +#define IDC_E_135 10299 +#define IDC_E_180 10300 +#define IDC_E_225 10301 +#define IDC_E_270 10302 +#define IDC_E_90 10303 +#define IDC_E_45 10304 +#define IDC_E_0 10305 +#define IDC_E_315 10306 +#define IDC_E_UP 10307 +#define IDC_E_DOWN 10308 +#define IDC_E_ADDPROP 10309 +#define IDC_E_DELPROP 10310 +#define IDC_E_CREATE 10311 +#define IDC_E_STATUS 10312 +#define IDC_SHIFT_BOX 10313 +#define IDC_HSHIFT 10314 +#define IDC_VSHIFT 10315 +#define IDC_ROTATEV 10316 +#define IDC_HSTRETCH 10317 +#define IDC_SCALEV 10318 +#define IDC_EDIT_STATUSPOINTSIZE 10319 +#define IDC_SCALEH 10320 +#define IDC_EDIT_ROTATION 10321 +#define IDC_STATIC_FIELD1 10322 +#define IDC_EDIT_UNDOLEVELS 10323 +#define IDC_HSCALE 10324 +#define IDC_VSCALE 10325 +#define IDC_EDIT_FIELD1 10326 +#define IDC_STATIC_FIELD2 10327 +#define IDC_ROTATE 10328 +#define IDC_EDIT_FIELD2 10329 +#define IDC_SLIDER_CAMSPEED 10330 +#define IDC_G_EDIT 10331 +#define IDC_STATIC_FIELD3 10332 +#define IDC_CHECK_CAMXYUPDATE 10333 +#define IDC_STATIC_KEY 10334 +#define IDC_FIND_BRUSH 10335 +#define IDC_EDIT_FIELD3 10336 +#define IDC_STATIC_VALUE 10337 +#define IDC_STATIC_FIELD4 10338 +#define IDC_E_KEY_FIELD 10339 +#define IDC_EDIT_FIELD4 10340 +#define IDC_FIND_ENTITY 10341 +#define IDC_STATIC_FIELD5 10342 +#define IDC_SIDES 10343 +#define IDC_EDIT_FIELD5 10344 +#define IDC_COMBO_WHATGAME 10345 +#define IDC_ROTX 10346 +#define IDC_BTN_COLOR 10347 +#define IDC_STATIC_COLOR 10348 +#define IDC_E_COLOR 10349 +#define IDC_ABOUT_GLVENDOR 10350 +#define IDC_ABOUT_GLVERSION 10351 +#define IDC_BTN_THECOLOR 10352 +#define IDC_ABOUT_GLRENDERER 10353 +#define IDC_STATIC_STUFF 10354 +#define IDC_TEXTURE 10355 +#define IDC_CHECK_ALTDRAG 10356 +#define IDC_PRJRSHCMD 10357 +#define IDC_SPIN_HSHIFT 10358 +#define IDC_CHECK_MOUSECHASE 10359 +#define IDC_PRJREMOTEBASE 10360 +#define IDC_SPIN_VSHIFT 10361 +#define IDC_CHECK_FACECOLOR 10362 +#define IDC_PRJENTITYPATH 10363 +#define IDC_SPIN_VSCALE 10364 +#define IDC_CHECK_NOCLAMP 10365 +#define IDC_PRJTEXPATH 10366 +#define IDC_SPIN_HSCALE 10367 +#define IDC_PRJAUTOSAVE 10368 +#define IDC_SPIN_ROTATE 10369 +#define IDC_ADDCMD 10370 +#define IDC_EDIT_ROTATEAMT 10371 +#define IDC_CMD_LIST 10372 +#define IDC_CHECK_DLLENTITIES 10373 +#define IDC_PRJBASEPATH 10374 +#define IDC_CHECK_WIDETOOLBAR 10375 +#define IDC_CMDCOMMAND 10376 +#define IDC_CHECK_BUGGYICD 10377 +#define IDC_CMDMENUTEXT 10378 +#define IDC_CHECK_SGIOPENGL 10379 +#define IDC_REMCMD 10380 +#define IDC_PRJINTERVAL 10381 +#define IDC_CHECK_HICOLOR 10382 +#define IDC_PRJMAPSPATH 10383 +#define IDC_CHECK_SHADERTEST 10384 +#define IDC_EDITCMD 10385 +#define IDC_CHECK_SHOWSHADERS 10386 +#define IDC_ABOUT_GLEXTENSIONS 10387 +#define IDC_LIST_TEXTURES 10388 +#define IDC_COMBO_WIDTH 10389 +#define IDC_COMBO_HEIGHT 10390 +#define IDC_BTN_PATCHDETAILS 10391 +#define IDC_BTN_PATCHRESET 10392 +#define IDC_BTN_PATCHNATURAL 10393 +#define IDC_RADIO_CAP 10394 +#define IDC_BTN_PATCHFIT 10395 +#define IDC_RADIO_CAP2 10396 +#define IDC_CHECK_SEAMS 10397 +#define IDC_BTN_FLIPX 10398 +#define IDC_RADIO_CAP3 10399 +#define IDC_EDIT_AMOUNT 10400 +#define IDC_BTN_FLIPY 10401 +#define IDC_RADIO_CAP4 10402 +#define IDC_BTN_ASSIGNSOUND 10403 +#define IDC_BTN_AXIAL 10404 +#define IDC_BTN_ASSIGNMODEL 10405 +#define IDC_BTN_FACEFIT 10406 +#define IDC_SLIDER_TEXTUREQUALITY 10407 +#define IDC_LIST1 10408 +#define IDC_BTN_BRUSHFIT 10409 +#define IDC_LIST_EVENTS 10410 +#define IDC_LIST_WAV 10411 +#define IDC_PARTICLE_LIST1 10412 +#define IDC_LIST_VARS 10413 +#define IDC_TREE1 10414 +#define IDC_TREE_TEXTURES 10415 +#define IDC_COMBO_ROW 10416 +#define IDC_COMBO_COL 10417 +#define IDC_COMBO_TYPE 10418 +#define IDC_EDIT_WIDTH 10419 +#define IDC_CHECK_BPRIMIT 10420 +#define IDC_EDIT_HEIGHT 10421 +#define IDC_SPIN_WIDTH 10422 +#define IDC_SPIN_HEIGHT 10423 +#define IDC_COMBO_SHADERS 10424 +#define IDC_TREE_GROUP 10425 +#define IDC_CHECK_NOSTIPPLE 10426 +#define IDC_TAB_MODE 10427 +#define IDC_CHECK_POINT 10428 +#define IDC_CHECK_EQUALRADIUS 10429 +#define IDC_RADIO_FALLOFF 10430 +#define IDC_CHECK_PROJECTED 10431 +#define IDC_CHECK_EXPLICITFALLOFF 10432 +#define IDC_CHECK_CENTER 10433 +#define IDC_SLIDER_BRIGHTNESS 10434 +#define IDC_CHECK_PARALLEL 10435 +#define IDC_CHECK_SHADOWS 10436 +#define IDC_CHECK_DIFFUSE 10437 +#define IDC_CHECK_SPECULAR 10438 +#define IDC_EDIT_RADIUSY 10439 +#define IDC_EDIT_RADIUSZ 10440 +#define IDC_EDIT_RADIUSX 10441 +#define IDC_EDIT_TARGETX 10442 +#define IDC_EDIT_TARGETY 10443 +#define IDC_EDIT_TARGETZ 10444 +#define IDC_EDIT_RIGHTX 10445 +#define IDC_EDIT_RIGHTY 10446 +#define IDC_EDIT_RIGHTZ 10447 +#define IDC_EDIT_UPX 10448 +#define IDC_EDIT_UPY 10449 +#define IDC_EDIT_UPZ 10450 +#define IDC_EDIT_STARTX 10451 +#define IDC_EDIT_STARTY 10452 +#define IDC_EDIT_STARTZ 10453 +#define IDC_EDIT_ENDX 10454 +#define IDC_EDIT_ENDY 10455 +#define IDC_EDIT_ENDZ 10456 +#define IDC_EDIT_CENTERX 10457 +#define IDC_COMBO_TEXTURE 10458 +#define IDC_EDIT_CENTERY 10459 +#define IDC_EDIT_MAPS 10460 +#define IDC_EDIT_CENTERZ 10461 +#define IDC_EDIT_CAM_NAME 10462 +#define IDC_COMBO_SPLINES 10463 +#define IDC_SCROLLBAR_SEGMENT 10464 +#define IDC_EDIT_LENGTH 10465 +#define IDC_EDIT_SEGMENT 10466 +#define IDC_BTN_ADDEVENT 10467 +#define IDC_BTN_DELEVENT 10468 +#define IDC_CHECK_TRACKCAMERA 10469 +#define IDC_RADIO_EVENT 10470 +#define IDC_EDIT_TOTALSEGMENTS 10471 +#define IDC_RADIO5 10472 +#define IDC_RADIO6 10473 +#define IDC_RADIO7 10474 +#define IDC_RADIO8 10475 +#define IDC_EDIT_PARAM 10476 +#define IDC_RADIO9 10477 +#define IDC_RADIO_FIXED 10478 +#define IDC_RADIO10 10479 +#define IDC_RADIO11 10480 +#define IDC_RADIO_EDITPOINTS 10481 +#define IDC_RADIO12 10482 +#define IDC_RADIO_EDITPOINTS2 10483 +#define IDC_BTN_DELETEPOINTS 10484 +#define IDC_RADIO13 10485 +#define IDC_EDIT_TYPE 10486 +#define IDC_RADIO14 10487 +#define IDC_BTN_SELECTALL 10488 +#define IDC_RADIO15 10489 +#define IDC_CHECK_SUBDIVIDE 10490 +#define IDC_RADIO16 10491 +#define IDC_SLIDER_HORZ 10492 +#define IDC_SLIDER_VERT 10493 +#define IDC_EDIT_HORZ 10494 +#define IDC_EDIT_VERT 10495 +#define IDC_LOAD 10496 +#define IDC_PREVIEW 10497 +#define IDC_CHECK_HIDEROOT 10498 +#define IDC_CHECK_ABSOLUTE 10499 +#define IDC_LIGHTPREVIEW 10500 +#define IDC_BUTTON_COLOR1 10501 +#define IDC_STATIC_RGB_RECT 10502 +#define IDC_STATIC_HSB_RECT 10503 +#define IDC_EDIT_RED 10504 +#define IDC_SPIN_RED 10505 +#define IDC_EDIT_GREEN 10506 +#define IDC_SPIN_GREEN 10507 +#define IDC_EDIT_BLUE 10508 +#define IDC_SPIN_BLUE 10509 +#define IDC_BUTTON_COLOR2 10510 +#define IDC_STATIC_NEWCOLOR 10511 +#define IDC_EDIT_HUE 10512 +#define IDC_SPIN_HUE 10513 +#define IDC_ANIMATION_SLIDER 10514 +#define IDC_EDIT_SAT 10515 +#define IDC_SPIN_SAT 10516 +#define IDC_BTN_APPLY 10517 +#define IDC_EDIT_VAL 10518 +#define IDC_SPIN_VAL 10519 +#define IDC_EDIT_OVERBRIGHT 10520 +#define IDC_SPIN_OVERBRIGHT 10521 +#define IDC_WAITSTR 10522 +#define IDC_COMBO_CLASS 10523 +#define IDC_EDIT_INFO 10524 +#define IDC_LIST_KEYVAL 10525 +#define IDC_BUTTON_BROWSE 10526 +#define IDC_BUTTON_CREATE 10527 +#define IDC_CUSTOM1 10528 +#define IDC_TAB_INSPECTOR 10529 +#define IDC_STATIC_TITLE 10530 +#define IDC_STATIC_VAL 10531 +#define IDC_TREE_MEDIA 10532 +#define IDC_EDIT_CONSOLE 10533 +#define IDC_BUTTON_SAVE 10534 +#define IDC_STATIC_LINE 10535 +#define IDC_BUTTON_GOTO 10536 +#define IDC_EDIT_GOTO 10537 +#define IDC_EDIT_LINE 10538 +#define IDC_ENTITY_PLAY_ANIM 10539 +#define IDC_ENTITY_ANIMATIONS 10540 +#define IDC_ENTITY_STOP_ANIM 10541 +#define IDC_ENTITY_CURRENT_ANIM 10542 +#define IDC_COMBO_CURVES 10543 +#define IDC_EDIT_FIND_KEY 10544 +#define IDC_EDIT_FIND_VALUE 10545 +#define IDC_EDIT_REPLACE_KEY 10546 +#define IDC_EDIT_REPLACE_VALUE 10547 +#define IDC_KEYCOPY 10548 +#define IDC_VALUECOPY 10549 +#define IDC_CHECK_FIND_WHOLESTRINGMATCHONLY 10550 +#define IDC_REPLACE 10551 +#define IDC_FIND 10552 +#define IDC_PROMPT 10553 +#define IDC_CHECK_SELECTALLMATCHING 10554 + +#define ID_COLOR_SUPERMAL 30000 +#define ID_Menu 30001 +#define ID_DROP_VIEWOPTIONS 30002 +#define ID_VIEWOPTIONS_WIREFRAME 30003 +#define ID_WIREFRAME_ON 30004 +#define ID_WIREFRAME_OFF 30005 +#define ID_VIEWOPTIONS_FORCEVISIBILITY 30006 +#define ID_FORCEVISIBILITY_ON 30007 +#define ID_FORCEVISIBILITY_OFF 30008 +#define ID_SELECT_COMPLETEENTITY 30009 +#define ID_PATCH_NURBEDITOR 30010 +#define ID_PRECISION_CURSOR_CYCLE 30011 +#define ID_THEMES_MAX 30012 +#define ID_MATERIALS_GENERATEMATERIALSLIST 30013 +#define ID_MATERIAL_EDIT 30014 +#define ID_SELECT_ALLTARGETS 30015 +#define ID_VIEW_SHOWCOMBATNODES 30016 +#define ID_FILE_IMPORT 30017 +#define ID_VIEW_XY 30018 +#define ID_VIEW_SIDE 30019 +#define ID_VIEW_FRONT 30020 +#define ID_CAMERATOGGLE 30021 +#define ID_VIEW_CAMERATOGGLE 30022 +#define ID_TEXTURES_POPUP 30023 +#define ID_POPUP_SELECTION 30024 +#define ID_VIEW_CHANGE 30025 +#define ID_VIEW_CAMERAUPDATE 30026 +#define ID_VIEW_CLIPPER 30027 +#define ID_PREFS 30028 +#define ID_TOGGLE_LOCK 30029 +#define ID_EDIT_MAPINFO 30030 +#define ID_EDIT_ENTITYINFO 30031 +#define ID_BRUSH_SCRIPTS 30032 +#define ID_VIEW_NEXTVIEW 30033 +#define ID_HELP_COMMANDLIST 30034 +#define ID_FILE_NEWPROJECT 30035 +#define ID_SNAPTOGRID 30036 +#define ID_SPLIT_SELECTED 30037 +#define ID_CLIP_SELECTED 30038 +#define ID_FLIP_CLIP 30039 +#define ID_TOGGLEVIEW_YZ 30040 +#define ID_TOGGLEVIEW_XZ 30041 +#define ID_COLORS_GRIDTEXT 30042 +#define ID_COLORS_BRUSH 30043 +#define ID_COLORS_SELECTEDBRUSH 30044 +#define ID_COLORS_CLIPPER 30045 +#define ID_COLORS_GRIDBLOCK 30046 +#define ID_COLORS_VIEWNAME 30047 +#define ID_COLOR_SETORIGINAL 30048 +#define ID_COLOR_SETQER 30049 +#define ID_COLOR_SETBLACK 30050 +#define ID_BYEBYE 30051 +#define ID_SELECT_SCALE 30052 +#define ID_SELECT_MOUSEROTATE 30053 +#define ID_TEXTURE_REPLACESELECTED 30054 +#define ID_TEXTURE_REPLACEALL 30055 +#define ID_SELECT_COMPLETE_ENTITY 30056 +#define ID_SCALELOCKX 30057 +#define ID_SCALELOCKY 30058 +#define ID_SCALELOCKZ 30059 +#define ID_VIEW_CUBICCLIPPING 30060 +#define ID_FILE_PROJECTSETTINGS 30061 +#define ID_VIEW_CUBEOUT 30062 +#define ID_VIEW_CUBEIN 30063 +#define ID_NODES_LOADNODES 30064 +#define ID_NODES_SHOWNODES 30065 +#define ID_NODES_SHOWLINKS 30066 +#define ID_NODES_REMOVEALLNODES 30067 +#define ID_NODES_COUNTNODES 30068 +#define ID_NODES_GIVEMONEYTONELNO 30069 +#define ID_FILE_SAVEREGION 30070 +#define ID_FILE_LOADREGION 30071 +#define ID_SELECTION_MOVEDOWN 30072 +#define ID_TOOLBAR_MAIN 30073 +#define ID_SELECTION_MOVEUP 30074 +#define ID_TOOLBAR_TEXTURE 30075 +#define ID_BRUSH_MAKECONE 30076 +#define ID_TEXTURES_LOAD 30077 +#define ID_TOGGLE_ROTATELOCK 30078 +#define ID_CURVE_CYLINDER 30079 +#define ID_CURVE_ENDCAP 30080 +#define ID_CURVE_BEVEL 30081 +#define ID_CURVE_SPHERE 30082 +#define ID_CURVE_HEMISPHERE 30083 +#define ID_CURVE_QUARTER 30084 +#define ID_CURVE_EIGHTHSPHERE 30085 +#define ID_CURVE_INVERTCURVE 30086 +#define ID_FILE_IMPORTMAP 30087 +#define ID_FILE_EXPORTMAP 30088 +#define ID_EDIT_LOADPREFAB 30089 +#define ID_VIEW_SHOWCURVES 30090 +#define ID_SELECTION_SELECT_NUDGELEFT 30091 +#define ID_SELECTION_SELECT_NUDGERIGHT 30092 +#define ID_SELECTION_SELECT_NUDGEUP 30093 +#define ID_SELECTION_SELECT_NUDGEDOWN 30094 +#define ID_TEXTURES_LOADLIST 30095 +#define ID_DONTSELECTCURVE 30096 +#define ID_CONVERTCURVES 30097 +#define ID_DYNAMIC_LIGHTING 30098 +#define ID_PATCH_SHOWBOUNDINGBOX 30099 +#define ID_CURVE_SIMPLEPATCHMESH 30100 +#define ID_PATCH_WIREFRAME 30101 +#define ID_PATCH_WELD 30102 +#define ID_CURVE_PATCHTUBE 30103 +#define ID_CURVE_PATCHCONE 30104 +#define ID_CURVE_PATCHENDCAP 30105 +#define ID_CURVE_PATCHBEVEL 30106 +#define ID_CURVE_PATCHINVERTEDENDCAP 30107 +#define ID_CURVE_PATCHINVERTEDBEVEL 30108 +#define ID_PATCH_DRILLDOWN 30109 +#define ID_CURVE_LOADPATCHFILE 30110 +#define ID_CURVE_INSERTROW 30111 +#define ID_CURVE_INSERTCOLUMN 30112 +#define ID_CURVE_DELETEROW 30113 +#define ID_CURVE_DELETECOLUMN 30114 +#define ID_PATCH_INSDEL 30115 +#define ID_CURVE_INSERT_ADDCOLUMN 30116 +#define ID_CURVE_INSERT_INSERTCOLUMN 30117 +#define ID_CURVE_INSERT_ADDROW 30118 +#define ID_CURVE_INSERT_INSERTROW 30119 +#define ID_CURVE_DELETE_FIRSTCOLUMN 30120 +#define ID_CURVE_DELETE_LASTCOLUMN 30121 +#define ID_CURVE_DELETE_FIRSTROW 30122 +#define ID_CURVE_DELETE_LASTROW 30123 +#define ID_CURVE_NEGATIVE 30124 +#define ID_PATCH_BEND 30125 +#define ID_CURVE_PATCHDENSETUBE 30126 +#define ID_CURVE_PATCHVERYDENSETUBE 30127 +#define ID_CURVE_CAP 30128 +#define ID_CURVE_CAP_INVERTEDBEVEL 30129 +#define ID_CURVE_CAP_INVERTEDENDCAP 30130 +#define ID_CURVE_REDISPERSE_ROWS 30131 +#define ID_CURVE_REDISPERSE_COLS 30132 +#define ID_PATCH_NATURALIZE 30133 +#define ID_CURVE_PATCHSQUARE 30134 +#define ID_BRUSH_PRIMITIVES_SPHERE 30135 +#define ID_BRUSH_PRIMITIVES_TORUS 30136 +#define ID_TEXTURES_TEXTUREWINDOWSCALE_200 30137 +#define ID_TEXTURES_TEXTUREWINDOWSCALE_100 30138 +#define ID_TEXTURES_TEXTUREWINDOWSCALE_50 30139 +#define ID_TEXTURES_TEXTUREWINDOWSCALE_25 30140 +#define ID_TEXTURES_TEXTUREWINDOWSCALE_10 30141 +#define ID_CURVE_NEGATIVETEXTUREX 30142 +#define ID_TEXTURES_FLUSH 30143 +#define ID_CURVE_OVERLAY_SET 30144 +#define ID_CURVE_OVERLAY_CLEAR 30145 +#define ID_CURVE_NEGATIVETEXTUREY 30146 +#define ID_CURVE_THICKEN 30147 +#define ID_CURVE_CYCLECAP 30148 +#define ID_CURVE_CYCLECAPALT 30149 +#define ID_CURVE_MATRIX_TRANSPOSE 30150 +#define ID_PLUGINS_REFRESH 30151 +#define ID_TEXTURES_RELOADSHADERS 30152 +#define ID_VIEW_ENTITIESAS_BOUNDINGBOX 30153 +#define ID_VIEW_ENTITIESAS_WRITEFRAME 30154 +#define ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME 30155 +#define ID_VIEW_ENTITIESAS_SELECTEDSKINNED 30156 +#define ID_VIEW_ENTITIESAS_SKINNED 30157 +#define ID_VIEW_ENTITIESAS_SKINNEDANDBOXED 30158 +#define ID_SHOW_ENTITIES 30159 +#define ID_VIEW_ENTITIESAS_WIREFRAME 30160 +#define ID_VIEW_SHOWHINT 30161 +#define ID_VIEW_OPENGLLIGHTING 30162 +#define ID_VIEW_SHOWCAULK 30163 +#define ID_VIEW_SHOWANGLES 30164 +#define ID_EDIT_SAVEPREFAB 30165 +#define ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP 30166 +#define ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL 30167 +#define ID_CURVE_PRIMITIVES_SPHERE 30168 +#define ID_VIEW_HIDESHOW_HIDESELECTED 30169 +#define ID_VIEW_HIDESHOW_SHOWHIDDEN 30170 +#define ID_TEXTURES_SHADERS_SHOW 30171 +#define ID_SELECTION_CSGADD 30172 +#define ID_VIEW_HIDESHOW_HIDENOTSELECTED 30173 +#define ID_SELECTION_CSGMERGE 30174 +#define ID_TEXTURES_FLUSH_UNUSED 30175 +#define ID_DROP_GROUP_REMOVE 30176 +#define ID_DROP_GROUP_ADDTO_WORLD 30177 +#define ID_DROP_GROUP_NEWGROUP 30178 +#define ID_DROP_GROUP_NAME 30179 +#define ID_DROP_GROUP_ADDTO 30180 +#define ID_SHOW_LIGHTVOLUMES 30181 +#define ID_SHOW_LIGHTTEXTURES 30182 +#define ID_SHOW_DOOM 30183 +#define ID_SPLINES_MODE 30184 +#define ID_SPLINES_LOAD 30185 +#define ID_SPLINES_SAVE 30186 +#define ID_MATERIAL_INFO 30187 +#define ID_SPLINE_TEST 30188 +#define ID_POPUP_NEWCAMERA_INTERPOLATED 30189 +#define ID_POPUP_NEWCAMERA_SPLINE 30190 +#define ID_POPUP_NEWCAMERA_FIXED 30191 +#define ID_SELECTION_MOVEONLY 30192 +#define ID_SELECT_BRUSHESONLY 30193 +#define ID_SELECT_BYBOUNDINGBRUSH 30194 +#define ID_TEXTURES_HIDEALL 30195 +#define ID_SELECTION_COMBINE 30196 +#define ID_PATCH_COMBINE 30197 +#define ID_VIEW_RENDERMODE 30198 +#define ID_VIEW_REBUILDRENDERDATA 30199 +#define ID_VIEW_REALTIMEREBUILD 30200 +#define ID_VIEW_RENDERENTITYOUTLINES 30201 +#define ID_VIEW_MATERIALANIMATION 30202 +#define ID_DROP_NEWMODEL 30203 +#define ID_SELECT_AXIALTEXTURE_BYWIDTH 30204 +#define ID_SELECT_AXIALTEXTURE_BYHEIGHT 30205 +#define ID_SELECT_AXIALTEXTURE_ARBITRARY 30206 +#define ID_SELECTION_EXPORT_TOOBJ 30207 +#define ID_VIEW_RENDERSELECTION 30208 +#define ID_VIEW_SHOW_SHOWVISPORTALS 30209 +#define ID_SELECT_NOMODELS 30210 +#define ID_VIEW_RENDERSOUND 30211 +#define ID_SOUND_POPUP 30212 +#define ID_SOUND_SHOWSOUNDVOLUMES 30213 +#define ID_SOUND_SHOWSELECTEDSOUNDVOLUMES 30214 +#define ID_VIEW_SHOW_NODRAW 30215 +#define ID_SELECT_MOUSESCALE 30216 +#define ID_SELECTION_EXPORT_TOCM 30217 +#define ID_SPLINES_EDITPOINTS 30218 +#define ID_SPLINES_ADDPOINTS 30219 +#define ID_SPLINES_INSERTPOINTS 30220 +#define ID_SPLINES_DELETEPOINTS 30221 +#define ID_PLUGIN_START 30222 +#define ID_PLUGIN_END 30223 +#define ID_FILE_EXIT 30224 +#define ID_FILE_SAVEAS 30225 +#define ID_VIEW_CENTER 30226 +#define ID_VIEW_UPFLOOR 30227 +#define ID_VIEW_DOWNFLOOR 30228 +#define ID_BRUSH_FLIPX 30229 +#define ID_BRUSH_FLIPY 30230 +#define ID_BRUSH_FLIPZ 30231 +#define ID_BRUSH_ROTATEX 30232 +#define ID_BRUSH_ROTATEY 30233 +#define ID_BRUSH_ROTATEZ 30234 +#define ID_BSP_FULLVIS 30235 +#define ID_BSP_FASTVIS 30236 +#define ID_BSP_NOVIS 30237 +#define ID_BSP_RELIGHT 30238 +#define ID_BSP_ENTITIES 30239 +#define ID_FILE_POINTFILE 30240 +#define ID_VIEW_100 30241 +#define ID_VIEW_75 30242 +#define ID_VIEW_50 30243 +#define ID_VIEW_25 30244 +#define ID_VIEW_12 30245 +#define ID_TEXTURES_SHOWALL 30246 +#define ID_TEXTURES_SHOWINUSE 30247 +#define ID_TEXTURES_TOGGLEVIEW 30248 +#define ID_SELECTION_CREATEENTITY 30249 +#define ID_SELECTION_EDITENTITY 30250 +#define ID_MISC_BENCHMARK 30251 +#define ID_REGION_OFF 30252 +#define ID_REGION_SETXY 30253 +#define ID_REGION_SETBRUSH 30254 +#define ID_SELECTION_MAKEHOLLOW 30255 +#define ID_SELECTION_SELECTPARTIALTALL 30256 +#define ID_SELECTION_SELECTCOMPLETETALL 30257 +#define ID_SELECTION_CSGSUBTRACT 30258 +#define ID_SELECTION_SELECTTOUCHING 30259 +#define ID_VIEW_NEAREST 30260 +#define ID_VIEW_NEARESTMIPMAP 30261 +#define ID_VIEW_LINEAR 30262 +#define ID_VIEW_BILINEAR 30263 +#define ID_VIEW_BILINEARMIPMAP 30264 +#define ID_VIEW_TRILINEAR 30265 +#define ID_TEXTURES_WIREFRAME 30266 +#define ID_TEXTURES_FLATSHADE 30267 +#define ID_VIEW_SHOWNAMES 30268 +#define ID_VIEW_ZOOMIN 30269 +#define ID_VIEW_ZOOMOUT 30270 +#define ID_VIEW_SHOWCOORDINATES 30271 +#define ID_VIEW_Z100 30272 +#define ID_VIEW_ZZOOMIN 30273 +#define ID_VIEW_ZZOOMOUT 30274 +#define ID_SELECTION_CLONE 30275 +#define ID_SELECTION_DESELECT 30276 +#define ID_SELECTION_DELETE 30277 +#define ID_SELECTION_DRAGVERTECIES 30278 +#define ID_SELECTION_DRAGEDGES 30279 +#define ID_REGION_SETTALLBRUSH 30280 +#define ID_SELECTION_SELECTINSIDE 30281 +#define ID_PROJECT_RELEAD 30282 +#define ID_PROJECT_CHANGE 30283 +#define ID_MISC_GAMMA 30284 +#define ID_VIEW_SHOWENT 30285 +#define ID_VIEW_SHOWPATH 30286 +#define ID_VIEW_SHOWLIGHTS 30287 +#define ID_VIEW_SHOWCLIP 30288 +#define ID_VIEW_SHOWWATER 30289 +#define ID_VIEW_SHOWWORLD 30290 +#define ID_MISC_TEXTUREBACKGROUN 30291 +#define ID_TEXTUREBK 30292 +#define ID_COLORS_XYBK 30293 +#define ID_FILE_ABOUT 30294 +#define ID_VIEW_CONSOLE 30295 +#define ID_VIEW_ENTITY 30296 +#define ID_VIEW_TEXTURE 30297 +#define ID_COLORS_MAJOR 30298 +#define ID_COLORS_MINOR 30299 +#define ID_SELECTION_CONNECT 30300 +#define ID_FILE_LOADPROJECT 30301 +#define ID_MISC_FINDBRUSH 30302 +#define ID_MISC_NEXTLEAKSPOT 30303 +#define ID_MISC_PREVIOUSLEAKSPOT 30304 +#define ID_BRUSH_3SIDED 30305 +#define ID_BRUSH_4SIDED 30306 +#define ID_BRUSH_5SIDED 30307 +#define ID_BRUSH_6SIDED 30308 +#define ID_BRUSH_7SIDED 30309 +#define ID_BRUSH_8SIDED 30310 +#define ID_BRUSH_9SIDED 30311 +#define ID_SELECTION_ARBITRARYROTATION 30312 +#define ID_BRUSH_ARBITRARYSIDED 30313 +#define ID_SELECTION_UNGROUPENTITY 30314 +#define ID_MISC_SELECTENTITYCOLOR 30315 +#define ID_MISC_PRINTXY 30316 +#define ID_HELP_ABOUT 30317 +#define ID_EDIT_COPYBRUSH 30318 +#define ID_EDIT_PASTEBRUSH 30319 +#define ID_TEXTURES_INSPECTOR 30320 +#define ID_VIEW_SHOWDETAIL 30321 +#define ID_SELECTION_MAKE_DETAIL 30322 +#define ID_SELECTION_MAKE_STRUCTURAL 30323 +#define ID_REGION_SETSELECTION 30324 +#define ID_VIEW_SHOWBLOCKS 30325 +#define ID_CAMERA_UP 30326 +#define ID_CAMERA_DOWN 30327 +#define ID_CAMERA_LEFT 30328 +#define ID_CAMERA_RIGHT 30329 +#define ID_CAMERA_FORWARD 30330 +#define ID_CAMERA_BACK 30331 +#define ID_CAMERA_ANGLEUP 30332 +#define ID_CAMERA_ANGLEDOWN 30333 +#define ID_CAMERA_STRAFELEFT 30334 +#define ID_CAMERA_STRAFERIGHT 30335 +#define ID_GRID_TOGGLE 30336 +#define ID_ENTITYLIST 30337 +#define ID_MAPINFO 30338 +#define ID_TOGGLECONSOLE 30339 +#define ID_TOGGLECAMERA 30340 +#define ID_TOGGLEZ 30341 +#define ID_TOGGLEVIEW 30342 +#define ID_SELECTION_TEXTURE_DEC 30343 +#define ID_SELECTION_TEXTURE_INC 30344 +#define ID_SELECTION_TEXTURE_FIT 30345 +#define ID_SELECTION_TEXTURE_ROTATECLOCK 30346 +#define ID_SELECTION_TEXTURE_ROTATECOUNTER 30347 +#define ID_SELECTION_TEXTURE_SCALEUP 30348 +#define ID_SELECTION_TEXTURE_SCALEDOWN 30349 +#define ID_SELECTION_TEXTURE_SHIFTLEFT 30350 +#define ID_SELECTION_TEXTURE_SHIFTRIGHT 30351 +#define ID_SELECTION_TEXTURE_SHIFTUP 30352 +#define ID_SELECTION_TEXTURE_SHIFTDOWN 30353 +#define ID_GRID_NEXT 30354 +#define ID_GRID_PREV 30355 +#define ID_SELECTION_TEXTURE_SCALELEFT 30356 +#define ID_SELECTION_TEXTURE_SCALERIGHT 30357 +#define ID_SELECTION_PRINT 30358 +#define ID_SELECTION_TOGGLESIZEPAINT 30359 +#define ID_PATCH_TAB 30360 +#define ID_PATCH_ENTER 30361 +#define ID_SELECT_SNAPTOGRID 30362 +#define ID_PATCH_INSPECTOR 30363 +#define ID_SELECT_ALL 30364 +#define ID_CURVE_FREEZE 30365 +#define ID_CURVE_UNFREEZE 30366 +#define ID_CURVE_UNFREEZEALL 30367 +#define ID_SELECT_RESELECT 30368 +#define ID_FITBRUSH 30369 +#define ID_FITFACE 30370 +#define ID_VIEW_CROSSHAIR 30371 +#define ID_SELECTION_INVERT 30372 +#define ID_VIEW_GROUPS 30373 +#define ID_PROJECTED_LIGHT 30374 +#define ID_SPLINES_POPUP 30375 +#define ID_SELECTION_CENTER_ORIGIN 30376 +#define ID_CURVE_INCREASE_VERT 30377 +#define ID_CURVE_DECREASE_VERT 30378 +#define ID_CURVE_INCREASE_HORZ 30379 +#define ID_CURVE_DECREASE_HORZ 30380 +#define ID_GRID_START 30381 +#define ID_GRID_POINT0625 30382 +#define ID_GRID_POINT125 30383 +#define ID_GRID_POINT25 30384 +#define ID_GRID_POINT5 30385 +#define ID_GRID_1 30386 +#define ID_GRID_2 30387 +#define ID_GRID_4 30388 +#define ID_GRID_8 30389 +#define ID_GRID_16 30390 +#define ID_GRID_32 30391 +#define ID_GRID_64 30392 +#define ID_GRID_END 30393 +#define ID_VIEW_MEDIABROWSER 30394 +#define ID_VIEW_GAME 30395 +#define ID_PATCH_NATURALIZEALT 30396 +#define ID_VIEW_SHOWTRIGGERS 30397 +#define ID_AUTOCAULK 30398 +#define ID_MISC_FINDORREPLACEENTITY 30399 +#define ID_MISC_SETVIEWPOS 30400 +#define ID_MISC_FINDNEXTENT 30401 +#define ID_SELECTION_VIEW_WIREFRAMEON 30402 +#define ID_SELECTION_VIEW_WIREFRAMEOFF 30403 +#define ID_SELECTION_VIEW_VISIBLEON 30404 +#define ID_SELECTION_VIEW_VISIBLEOFF 30405 +#define ID_ENTITY_START 40000 +#define ID_ENTITY_END 45000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 10083 +#define _APS_NEXT_COMMAND_VALUE 30406 +#define _APS_NEXT_CONTROL_VALUE 10555 +#define _APS_NEXT_SYMED_VALUE 10083 +#endif +#endif diff --git a/sys/win32/rc/ScriptEditor.rc b/sys/win32/rc/ScriptEditor.rc new file mode 100644 index 000000000..e94ffed63 --- /dev/null +++ b/sys/win32/rc/ScriptEditor.rc @@ -0,0 +1,99 @@ +// Microsoft Visual C++ generated resource script. +// +#include "ScriptEditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "ScriptEditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_SCRIPTEDITOR DIALOGEX 0, 0, 350, 246 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | + WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Declaration Editor" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Save",IDOK,260,216,42,14 + PUSHBUTTON "Cancel",IDCANCEL,306,216,42,14 + CONTROL "",IDC_SCRIPTEDITOR_EDIT_TEXT,"RichEdit20A",ES_MULTILINE | + ES_AUTOHSCROLL | ES_WANTRETURN | WS_BORDER | WS_VSCROLL | + WS_HSCROLL | WS_TABSTOP,2,4,346,208,WS_EX_CLIENTEDGE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR_SCRIPTEDITOR ACCELERATORS +BEGIN + VK_F3, ID_SCRIPTEDITOR_FIND_NEXT, VIRTKEY, NOINVERT + "G", ID_SCRIPTEDITOR_GOTOLINE, VIRTKEY, CONTROL, NOINVERT + "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT + "R", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT + "H", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT + "S", IDOK, VIRTKEY, CONTROL, NOINVERT +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/ScriptEditor_resource.h b/sys/win32/rc/ScriptEditor_resource.h new file mode 100644 index 000000000..46c21521b --- /dev/null +++ b/sys/win32/rc/ScriptEditor_resource.h @@ -0,0 +1,38 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_SCRIPTEDITOR 11000 +#define IDR_ACCELERATOR_SCRIPTEDITOR 11001 + +#define IDC_SCRIPTEDITOR_EDIT_TEXT 11200 + +#define ID_SCRIPTEDITOR_FIND_NEXT 31000 +#define ID_SCRIPTEDITOR_GOTOLINE 31001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 11002 +#define _APS_NEXT_COMMAND_VALUE 31002 +#define _APS_NEXT_CONTROL_VALUE 11201 +#define _APS_NEXT_SYMED_VALUE 11002 +#endif +#endif diff --git a/sys/win32/rc/SoundEditor.rc b/sys/win32/rc/SoundEditor.rc new file mode 100644 index 000000000..a4408fac4 --- /dev/null +++ b/sys/win32/rc/SoundEditor.rc @@ -0,0 +1,188 @@ +// Microsoft Visual C++ generated resource script. +// +#include "SoundEditor_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "SoundEditor_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_SOUND DIALOGEX 0, 0, 332, 451 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT +CAPTION "Sound Editor" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + GROUPBOX "",IDC_STATIC,7,3,318,38 + LTEXT "Speakers",IDC_STATIC,11,12,31,8 + CONTROL "Show Group Only",IDC_CHECK_GROUPONLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,50,12,71,10 + LTEXT "Select Group",IDC_STATIC,171,12,42,8 + COMBOBOX IDC_COMBO_SPEAKERS,9,24,154,234,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_GROUPS,169,24,154,30,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Entity name:",IDC_STATIC,7,46,43,8 + EDITTEXT IDC_EDIT_SOUND_NAME,52,44,208,12,ES_AUTOHSCROLL + LTEXT "Group name:",IDC_STATIC,8,62,42,8 + EDITTEXT IDC_EDIT_GROUP,51,60,210,12,ES_AUTOHSCROLL + PUSHBUTTON "x-",IDC_BTN_XDN,261,90,13,11 + PUSHBUTTON "x+",IDC_BTN_XUP,285,90,13,11 + PUSHBUTTON "y+",IDC_BTN_YUP,273,78,13,11 + PUSHBUTTON "y-",IDC_BTN_YDN,274,103,13,11 + PUSHBUTTON "z+",IDC_BTN_ZUP,303,83,13,11 + PUSHBUTTON "z-",IDC_BTN_ZDN,303,97,13,11 + LTEXT "Volume:",IDC_STATIC,18,79,26,8 + EDITTEXT IDC_EDIT_VOLUME,51,77,22,12,ES_AUTOHSCROLL + PUSHBUTTON "<",IDC_BTN_DOWN,76,78,9,10 + PUSHBUTTON ">",IDC_BTN_UP,87,78,9,10 + LTEXT "Min Dist:",IDC_STATIC,103,79,28,8 + EDITTEXT IDC_EDIT_MINDIST,134,77,30,12,ES_AUTOHSCROLL + LTEXT "Max Dist:",IDC_STATIC,171,79,30,8 + EDITTEXT IDC_EDIT_MAXDIST,206,77,30,12,ES_AUTOHSCROLL + CONTROL "Occlusion",IDC_CHECK_OCCLUSION,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,85,111,47,10 + CONTROL "Omnidirectional",IDC_CHECK_OMNI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,145,111,64,10 + LTEXT "Lead through:",IDC_STATIC,159,96,45,8 + EDITTEXT IDC_EDIT_LEADTHROUGH,206,94,30,12,ES_AUTOHSCROLL + CONTROL "Plain",IDC_CHECK_PLAIN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,85,122,31,10 + CONTROL "Triggered",IDC_CHECKP_TRIGGERED,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,145,122,46,10 + GROUPBOX "",IDC_STATIC,7,147,318,240 + LTEXT "Sound shader:",IDC_STATIC,16,156,47,8 + EDITTEXT IDC_EDIT_SHADER,65,154,195,12,ES_AUTOHSCROLL + PUSHBUTTON "Edit...",IDC_BTN_EDIT_SOUND,267,154,50,12 + CONTROL "Tree1",IDC_TREE_SOUNDS,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,15,169,301, + 195 + PUSHBUTTON "&Play",IDC_BTN_PLAYSOUND,15,368,25,14 + CONTROL "Play on single click",IDC_CHECK_PLAY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,47,370,76,10 + PUSHBUTTON "Refresh Wave Path",IDC_BTN_REFRESHWAVE,161,368,83,14 + PUSHBUTTON "&Refresh",IDC_BTN_REFRESH,248,368,67,14 + GROUPBOX "",IDC_STATIC,7,391,318,35 + PUSHBUTTON "Drop Speaker...",IDC_BTN_DROP,22,402,65,14 + PUSHBUTTON "Delete Speaker...",IDC_BTN_GROUP,96,402,65,14 + PUSHBUTTON "Sa&ve .MAP",IDC_BTN_SAVEMAP,170,402,65,14 + PUSHBUTTON "Sa&ve .MAP As...",IDC_BTN_SAVEMAPAS,244,402,65,14 + PUSHBUTTON "&Switch To Game",IDC_BTN_SWITCHTOGAME,7,430,66,14 + PUSHBUTTON "Refresh Speaker List",IDC_BTN_REFRESHSPEAKERS,78,430,79, + 14 + DEFPUSHBUTTON "Apply",IDC_BTN_APPLY_SOUND,275,430,50,14 + LTEXT "Wave file size: ",IDC_STATIC,19,135,49,8 + LTEXT "Static",IDC_STATIC_WAVESIZE,71,135,242,8 + LTEXT "Wait:",IDC_STATIC,28,96,18,8 + EDITTEXT IDC_EDIT_WAIT,50,94,30,12,ES_AUTOHSCROLL + LTEXT "Random:",IDC_STATIC,89,96,30,8 + EDITTEXT IDC_EDIT_RANDOM,119,94,30,12,ES_AUTOHSCROLL + PUSHBUTTON "Trigger",IDC_BTN_TRIGGER,271,57,37,14 + CONTROL "Looping",IDC_CHECK_LOOPING,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,216,111,41,10 + CONTROL "Unclamped",IDC_CHECK_UNCLAMPED,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,216,122,52,10 + LTEXT "Shakes:",IDC_STATIC,20,111,27,8 + EDITTEXT IDC_EDIT_SHAKES,49,109,30,12,ES_AUTOHSCROLL +END + +IDD_DIALOG_SOUNDGROUP DIALOG 0, 0, 186, 180 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Select Sound Group" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + LISTBOX IDC_LIST_GROUPS,7,7,116,166,LBS_SORT | LBS_MULTIPLESEL | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_SOUND, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 325 + TOPMARGIN, 7 + BOTTOMMARGIN, 444 + HORZGUIDE, 7 + END + + IDD_DIALOG_SOUNDGROUP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 173 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/SoundEditor_resource.h b/sys/win32/rc/SoundEditor_resource.h new file mode 100644 index 000000000..b91ebb2bc --- /dev/null +++ b/sys/win32/rc/SoundEditor_resource.h @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDD_DIALOG_SOUND 12000 +#define IDD_DIALOG_SOUNDGROUP 12001 + +#define IDC_EDIT_SOUND_NAME 12200 +#define IDC_EDIT_VOLUME 12201 +#define IDC_EDIT_MINDIST 12202 +#define IDC_EDIT_MAXDIST 12203 +#define IDC_EDIT_LEADTHROUGH 12204 +#define IDC_BTN_SAVEMAP 12205 +#define IDC_BTN_SAVEMAPAS 12206 +#define IDC_BTN_EDIT_SOUND 12207 +#define IDC_LIST_GROUPS 12208 +#define IDC_EDIT_WAIT 12209 +#define IDC_TREE_SOUNDS 12210 +#define IDC_BTN_SWITCHTOGAME 12211 +#define IDC_BTN_APPLY_SOUND 12212 +#define IDC_BTN_REFRESHSPEAKERS 12213 +#define IDC_BTN_REFRESH 12214 +#define IDC_BTN_PLAYSOUND 12215 +#define IDC_EDIT_SHADER 12216 +#define IDC_CHECK_PLAY 12217 +#define IDC_CHECK_OMNI 12218 +#define IDC_CHECKP_TRIGGERED 12219 +#define IDC_CHECK_OCCLUSION 12220 +#define IDC_EDIT_GROUP 12221 +#define IDC_BTN_DROP 12222 +#define IDC_BTN_GROUP 12223 +#define IDC_CHECK_PLAIN 12224 +#define IDC_BTN_REFRESHWAVE 12225 +#define IDC_BTN_XDN 12226 +#define IDC_BTN_XUP 12227 +#define IDC_BTN_YUP 12228 +#define IDC_BTN_YDN 12229 +#define IDC_BTN_ZUP 12230 +#define IDC_BTN_ZDN 12231 +#define IDC_COMBO_SPEAKERS 12232 +#define IDC_CHECK_GROUPONLY 12233 +#define IDC_COMBO_GROUPS 12234 +#define IDC_BTN_UP 12235 +#define IDC_BTN_DOWN 12236 +#define IDC_STATIC_WAVESIZE 12237 +#define IDC_EDIT_RANDOM 12238 +#define IDC_BTN_TRIGGER 12239 +#define IDC_CHECK_LOOPING 12240 +#define IDC_CHECK_UNCLAMPED 12241 +#define IDC_EDIT_WAIT2 12242 +#define IDC_EDIT_SHAKES 12243 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 12002 +#define _APS_NEXT_COMMAND_VALUE 32000 +#define _APS_NEXT_CONTROL_VALUE 12244 +#define _APS_NEXT_SYMED_VALUE 12002 +#endif +#endif diff --git a/sys/win32/rc/doom.rc b/sys/win32/rc/doom.rc new file mode 100644 index 000000000..b63d20405 --- /dev/null +++ b/sys/win32/rc/doom.rc @@ -0,0 +1,122 @@ +// Microsoft Visual C++ generated resource script. +// +#include "doom_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif +#include "Common.rc" +#include "Radiant.rc" +#include "AFEditor.rc" +#include "SoundEditor.rc" +#include "ParticleEditor.rc" +#include "DeclEditor.rc" + +#include "ScriptEditor.rc" + +#include "GuiEd.rc" +#include "Debugger.rc" +#include "MaterialEditor.rc" +#include "PropTree.rc" +#include "afxres.rc" // Standard components +#include "afxprint.rc" // printing/print preview resources +#endif +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "doom_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif\r\n" + "#include ""Common.rc""\r\n" + "#include ""Radiant.rc""\r\n" + "#include ""AFEditor.rc""\r\n" + "#include ""SoundEditor.rc""\r\n" + "#include ""ParticleEditor.rc""\r\n" + "#include ""DeclEditor.rc""\n" + "\n" + "#include ""ScriptEditor.rc""\n" + "\n" + "#include ""GuiEd.rc""\r\n" + "#include ""Debugger.rc""\r\n" + "#include ""MaterialEditor.rc""\r\n" + "#include ""PropTree.rc""\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#include ""afxprint.rc"" // printing/print preview resources\r\n" + "#endif\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "res\\doom.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sys/win32/rc/doom_resource.h b/sys/win32/rc/doom_resource.h new file mode 100644 index 000000000..9f82185e9 --- /dev/null +++ b/sys/win32/rc/doom_resource.h @@ -0,0 +1,35 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define IDB_BITMAP_LOGO 4000 +#define IDI_ICON1 4001 + + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 4002 +#define _APS_NEXT_COMMAND_VALUE 24000 +#define _APS_NEXT_CONTROL_VALUE 4200 +#define _APS_NEXT_SYMED_VALUE 4002 +#endif +#endif diff --git a/sys/win32/rc/res/BEVEL.BMP b/sys/win32/rc/res/BEVEL.BMP new file mode 100644 index 000000000..5c2dcd691 Binary files /dev/null and b/sys/win32/rc/res/BEVEL.BMP differ diff --git a/sys/win32/rc/res/BITMAP2.BMP b/sys/win32/rc/res/BITMAP2.BMP new file mode 100644 index 000000000..7982fa294 Binary files /dev/null and b/sys/win32/rc/res/BITMAP2.BMP differ diff --git a/sys/win32/rc/res/BMP00001.BMP b/sys/win32/rc/res/BMP00001.BMP new file mode 100644 index 000000000..bc656dfa2 Binary files /dev/null and b/sys/win32/rc/res/BMP00001.BMP differ diff --git a/sys/win32/rc/res/BMP0002.BMP b/sys/win32/rc/res/BMP0002.BMP new file mode 100644 index 000000000..50ab1918b Binary files /dev/null and b/sys/win32/rc/res/BMP0002.BMP differ diff --git a/sys/win32/rc/res/DEFTEX.WAL b/sys/win32/rc/res/DEFTEX.WAL new file mode 100644 index 000000000..498b56a9b Binary files /dev/null and b/sys/win32/rc/res/DEFTEX.WAL differ diff --git a/sys/win32/rc/res/ENDCAP.BMP b/sys/win32/rc/res/ENDCAP.BMP new file mode 100644 index 000000000..cb25691e3 Binary files /dev/null and b/sys/win32/rc/res/ENDCAP.BMP differ diff --git a/sys/win32/rc/res/GetString.htm b/sys/win32/rc/res/GetString.htm new file mode 100644 index 000000000..fd2b1b147 --- /dev/null +++ b/sys/win32/rc/res/GetString.htm @@ -0,0 +1,19 @@ + + + + + + + + + + +
+
+ +
+TODO: Place controls here. +
+ + + \ No newline at end of file diff --git a/sys/win32/rc/res/IBEVEL.BMP b/sys/win32/rc/res/IBEVEL.BMP new file mode 100644 index 000000000..4624f5d36 Binary files /dev/null and b/sys/win32/rc/res/IBEVEL.BMP differ diff --git a/sys/win32/rc/res/IENDCAP.BMP b/sys/win32/rc/res/IENDCAP.BMP new file mode 100644 index 000000000..892bbde45 Binary files /dev/null and b/sys/win32/rc/res/IENDCAP.BMP differ diff --git a/sys/win32/rc/res/MEFileToolbar.bmp b/sys/win32/rc/res/MEFileToolbar.bmp new file mode 100644 index 000000000..42d18e753 Binary files /dev/null and b/sys/win32/rc/res/MEFileToolbar.bmp differ diff --git a/sys/win32/rc/res/MEtoolbar.bmp b/sys/win32/rc/res/MEtoolbar.bmp new file mode 100644 index 000000000..a49be78ad Binary files /dev/null and b/sys/win32/rc/res/MEtoolbar.bmp differ diff --git a/sys/win32/rc/res/MaterialEditor.ico b/sys/win32/rc/res/MaterialEditor.ico new file mode 100644 index 000000000..be1cee6a5 Binary files /dev/null and b/sys/win32/rc/res/MaterialEditor.ico differ diff --git a/sys/win32/rc/res/PropTree.rc2 b/sys/win32/rc/res/PropTree.rc2 new file mode 100644 index 000000000..83f74ca93 --- /dev/null +++ b/sys/win32/rc/res/PropTree.rc2 @@ -0,0 +1,13 @@ +// +// PROPTREE.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/sys/win32/rc/res/Q.BMP b/sys/win32/rc/res/Q.BMP new file mode 100644 index 000000000..4894e0b08 Binary files /dev/null and b/sys/win32/rc/res/Q.BMP differ diff --git a/sys/win32/rc/res/RADIANT3.GIF b/sys/win32/rc/res/RADIANT3.GIF new file mode 100644 index 000000000..adbe1f5d3 Binary files /dev/null and b/sys/win32/rc/res/RADIANT3.GIF differ diff --git a/sys/win32/rc/res/Radiant.ico b/sys/win32/rc/res/Radiant.ico new file mode 100644 index 000000000..f644e9a73 Binary files /dev/null and b/sys/win32/rc/res/Radiant.ico differ diff --git a/sys/win32/rc/res/RadiantDoc.ico b/sys/win32/rc/res/RadiantDoc.ico new file mode 100644 index 000000000..3288c6f5c Binary files /dev/null and b/sys/win32/rc/res/RadiantDoc.ico differ diff --git a/sys/win32/rc/res/TOOLBAR1.BMP b/sys/win32/rc/res/TOOLBAR1.BMP new file mode 100644 index 000000000..55e05ecd8 Binary files /dev/null and b/sys/win32/rc/res/TOOLBAR1.BMP differ diff --git a/sys/win32/rc/res/TOOLBAR2.BMP b/sys/win32/rc/res/TOOLBAR2.BMP new file mode 100644 index 000000000..dfa5dd17a Binary files /dev/null and b/sys/win32/rc/res/TOOLBAR2.BMP differ diff --git a/sys/win32/rc/res/Toolbar.bmp b/sys/win32/rc/res/Toolbar.bmp new file mode 100644 index 000000000..1956dd57f Binary files /dev/null and b/sys/win32/rc/res/Toolbar.bmp differ diff --git a/sys/win32/rc/res/VIEWDEFA.BMP b/sys/win32/rc/res/VIEWDEFA.BMP new file mode 100644 index 000000000..30233a879 Binary files /dev/null and b/sys/win32/rc/res/VIEWDEFA.BMP differ diff --git a/sys/win32/rc/res/VIEWOPPO.BMP b/sys/win32/rc/res/VIEWOPPO.BMP new file mode 100644 index 000000000..afa427058 Binary files /dev/null and b/sys/win32/rc/res/VIEWOPPO.BMP differ diff --git a/sys/win32/rc/res/bmp00002.bmp b/sys/win32/rc/res/bmp00002.bmp new file mode 100644 index 000000000..6d77432de Binary files /dev/null and b/sys/win32/rc/res/bmp00002.bmp differ diff --git a/sys/win32/rc/res/bmp00003.bmp b/sys/win32/rc/res/bmp00003.bmp new file mode 100644 index 000000000..c7270fdd5 Binary files /dev/null and b/sys/win32/rc/res/bmp00003.bmp differ diff --git a/sys/win32/rc/res/bmp00004.bmp b/sys/win32/rc/res/bmp00004.bmp new file mode 100644 index 000000000..7aca914ee Binary files /dev/null and b/sys/win32/rc/res/bmp00004.bmp differ diff --git a/sys/win32/rc/res/bmp00005.bmp b/sys/win32/rc/res/bmp00005.bmp new file mode 100644 index 000000000..6e8e84062 Binary files /dev/null and b/sys/win32/rc/res/bmp00005.bmp differ diff --git a/sys/win32/rc/res/cchsb.bmp b/sys/win32/rc/res/cchsb.bmp new file mode 100644 index 000000000..4b8c94a7e Binary files /dev/null and b/sys/win32/rc/res/cchsb.bmp differ diff --git a/sys/win32/rc/res/ccrgb.bmp b/sys/win32/rc/res/ccrgb.bmp new file mode 100644 index 000000000..5d25db18c Binary files /dev/null and b/sys/win32/rc/res/ccrgb.bmp differ diff --git a/sys/win32/rc/res/dbg_back.bmp b/sys/win32/rc/res/dbg_back.bmp new file mode 100644 index 000000000..b8e14707d Binary files /dev/null and b/sys/win32/rc/res/dbg_back.bmp differ diff --git a/sys/win32/rc/res/dbg_breakpoint.ico b/sys/win32/rc/res/dbg_breakpoint.ico new file mode 100644 index 000000000..db5d0ed42 Binary files /dev/null and b/sys/win32/rc/res/dbg_breakpoint.ico differ diff --git a/sys/win32/rc/res/dbg_current.ico b/sys/win32/rc/res/dbg_current.ico new file mode 100644 index 000000000..9392c0690 Binary files /dev/null and b/sys/win32/rc/res/dbg_current.ico differ diff --git a/sys/win32/rc/res/dbg_currentline.ico b/sys/win32/rc/res/dbg_currentline.ico new file mode 100644 index 000000000..6d3435e7f Binary files /dev/null and b/sys/win32/rc/res/dbg_currentline.ico differ diff --git a/sys/win32/rc/res/dbg_empty.ico b/sys/win32/rc/res/dbg_empty.ico new file mode 100644 index 000000000..2bd471732 Binary files /dev/null and b/sys/win32/rc/res/dbg_empty.ico differ diff --git a/sys/win32/rc/res/dbg_open.bmp b/sys/win32/rc/res/dbg_open.bmp new file mode 100644 index 000000000..bb8613c27 Binary files /dev/null and b/sys/win32/rc/res/dbg_open.bmp differ diff --git a/sys/win32/rc/res/dbg_toolbar.bmp b/sys/win32/rc/res/dbg_toolbar.bmp new file mode 100644 index 000000000..12a4afa56 Binary files /dev/null and b/sys/win32/rc/res/dbg_toolbar.bmp differ diff --git a/sys/win32/rc/res/doom.ico b/sys/win32/rc/res/doom.ico new file mode 100644 index 000000000..2a6b79ac0 Binary files /dev/null and b/sys/win32/rc/res/doom.ico differ diff --git a/sys/win32/rc/res/fpoint.cur b/sys/win32/rc/res/fpoint.cur new file mode 100644 index 000000000..ca13f10f1 Binary files /dev/null and b/sys/win32/rc/res/fpoint.cur differ diff --git a/sys/win32/rc/res/fxed_link.ico b/sys/win32/rc/res/fxed_link.ico new file mode 100644 index 000000000..cb9cc2386 Binary files /dev/null and b/sys/win32/rc/res/fxed_link.ico differ diff --git a/sys/win32/rc/res/fxed_toolbar.bmp b/sys/win32/rc/res/fxed_toolbar.bmp new file mode 100644 index 000000000..645bbe5a9 Binary files /dev/null and b/sys/win32/rc/res/fxed_toolbar.bmp differ diff --git a/sys/win32/rc/res/fxeditor.ico b/sys/win32/rc/res/fxeditor.ico new file mode 100644 index 000000000..19f10e3b8 Binary files /dev/null and b/sys/win32/rc/res/fxeditor.ico differ diff --git a/sys/win32/rc/res/guied.ico b/sys/win32/rc/res/guied.ico new file mode 100644 index 000000000..79127de85 Binary files /dev/null and b/sys/win32/rc/res/guied.ico differ diff --git a/sys/win32/rc/res/guied_collapse.ico b/sys/win32/rc/res/guied_collapse.ico new file mode 100644 index 000000000..86b0ac889 Binary files /dev/null and b/sys/win32/rc/res/guied_collapse.ico differ diff --git a/sys/win32/rc/res/guied_expand.ico b/sys/win32/rc/res/guied_expand.ico new file mode 100644 index 000000000..c02206c7e Binary files /dev/null and b/sys/win32/rc/res/guied_expand.ico differ diff --git a/sys/win32/rc/res/guied_hand.cur b/sys/win32/rc/res/guied_hand.cur new file mode 100644 index 000000000..72ef9db7f Binary files /dev/null and b/sys/win32/rc/res/guied_hand.cur differ diff --git a/sys/win32/rc/res/guied_nav_visible.ico b/sys/win32/rc/res/guied_nav_visible.ico new file mode 100644 index 000000000..f3e58b4ee Binary files /dev/null and b/sys/win32/rc/res/guied_nav_visible.ico differ diff --git a/sys/win32/rc/res/guied_nav_visibledisabled.ico b/sys/win32/rc/res/guied_nav_visibledisabled.ico new file mode 100644 index 000000000..290eaedd5 Binary files /dev/null and b/sys/win32/rc/res/guied_nav_visibledisabled.ico differ diff --git a/sys/win32/rc/res/guied_scripts.ico b/sys/win32/rc/res/guied_scripts.ico new file mode 100644 index 000000000..6eec8c8af Binary files /dev/null and b/sys/win32/rc/res/guied_scripts.ico differ diff --git a/sys/win32/rc/res/guied_scripts_white.ico b/sys/win32/rc/res/guied_scripts_white.ico new file mode 100644 index 000000000..91f09f2d3 Binary files /dev/null and b/sys/win32/rc/res/guied_scripts_white.ico differ diff --git a/sys/win32/rc/res/guied_viewer_toolbar.bmp b/sys/win32/rc/res/guied_viewer_toolbar.bmp new file mode 100644 index 000000000..01385af58 Binary files /dev/null and b/sys/win32/rc/res/guied_viewer_toolbar.bmp differ diff --git a/sys/win32/rc/res/icon2.ico b/sys/win32/rc/res/icon2.ico new file mode 100644 index 000000000..b59992feb Binary files /dev/null and b/sys/win32/rc/res/icon2.ico differ diff --git a/sys/win32/rc/res/logo_sm3dfx.bmp b/sys/win32/rc/res/logo_sm3dfx.bmp new file mode 100644 index 000000000..9a1e106a3 Binary files /dev/null and b/sys/win32/rc/res/logo_sm3dfx.bmp differ diff --git a/sys/win32/rc/res/matedtree.bmp b/sys/win32/rc/res/matedtree.bmp new file mode 100644 index 000000000..0ee91b3de Binary files /dev/null and b/sys/win32/rc/res/matedtree.bmp differ diff --git a/sys/win32/rc/res/me_disabled_icon.ico b/sys/win32/rc/res/me_disabled_icon.ico new file mode 100644 index 000000000..290eaedd5 Binary files /dev/null and b/sys/win32/rc/res/me_disabled_icon.ico differ diff --git a/sys/win32/rc/res/me_enabled.ico b/sys/win32/rc/res/me_enabled.ico new file mode 100644 index 000000000..8e47a281e Binary files /dev/null and b/sys/win32/rc/res/me_enabled.ico differ diff --git a/sys/win32/rc/res/me_off_icon.ico b/sys/win32/rc/res/me_off_icon.ico new file mode 100644 index 000000000..9077bbcb2 Binary files /dev/null and b/sys/win32/rc/res/me_off_icon.ico differ diff --git a/sys/win32/rc/res/me_on_icon.ico b/sys/win32/rc/res/me_on_icon.ico new file mode 100644 index 000000000..f3e58b4ee Binary files /dev/null and b/sys/win32/rc/res/me_on_icon.ico differ diff --git a/sys/win32/rc/res/qe3.ico b/sys/win32/rc/res/qe3.ico new file mode 100644 index 000000000..d83f67732 Binary files /dev/null and b/sys/win32/rc/res/qe3.ico differ diff --git a/sys/win32/rc/res/shaderbar.bmp b/sys/win32/rc/res/shaderbar.bmp new file mode 100644 index 000000000..913de51d2 Binary files /dev/null and b/sys/win32/rc/res/shaderbar.bmp differ diff --git a/sys/win32/rc/res/shaderdoc.ico b/sys/win32/rc/res/shaderdoc.ico new file mode 100644 index 000000000..3288c6f5c Binary files /dev/null and b/sys/win32/rc/res/shaderdoc.ico differ diff --git a/sys/win32/rc/res/shaderframe.ico b/sys/win32/rc/res/shaderframe.ico new file mode 100644 index 000000000..f644e9a73 Binary files /dev/null and b/sys/win32/rc/res/shaderframe.ico differ diff --git a/sys/win32/rc/res/spliter.cur b/sys/win32/rc/res/spliter.cur new file mode 100644 index 000000000..1a4fff643 Binary files /dev/null and b/sys/win32/rc/res/spliter.cur differ diff --git a/sys/win32/sdk/D3SDK.nsi b/sys/win32/sdk/D3SDK.nsi new file mode 100644 index 000000000..feee493a0 --- /dev/null +++ b/sys/win32/sdk/D3SDK.nsi @@ -0,0 +1,42 @@ +SetCompressor lzma + +; HM NIS Edit Wizard helper defines +!define PRODUCT_NAME "Doom 3 SDK" +!define PRODUCT_VERSION "1.3.1" +!define PRODUCT_PUBLISHER "id Software" +!define PRODUCT_WEB_SITE "http://www.iddevnet.com" + +; MUI 1.67 compatible ------ +!include "MUI.nsh" + +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" + +; MUI Pages +!insertmacro MUI_PAGE_WELCOME +!define MUI_LICENSEPAGE_RADIOBUTTONS +!insertmacro MUI_PAGE_LICENSE "Doom3_SDK\EULA.Development Kit.rtf" +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +; Language files +!insertmacro MUI_LANGUAGE "English" + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "D3_${PRODUCT_VERSION}_SDK.exe" +InstallDir "C:\Doom3_SDK\" +ShowInstDetails show + +Section "MainSection" SEC01 + SetOutPath "$INSTDIR" + SetOverwrite ifnewer + File /R "Doom3_SDK\*.*" +SectionEnd + +Section -Post +SectionEnd + diff --git a/sys/win32/sdk/prepare.py b/sys/win32/sdk/prepare.py new file mode 100644 index 000000000..60de91f5b --- /dev/null +++ b/sys/win32/sdk/prepare.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# prepare content for SDK + +import shutil, os, stat + +media = '../../../../../media-sdk' +media = os.path.abspath( media ) + +try: + shutil.rmtree( 'Doom3_SDK' ) +except: + print 'Could not remove Doom3_SDK' + pass + +# copy source from list +f = open( 'source.list' ) +l = [ s[:-1] for s in f.readlines() ] +f.close() +for p in l: + sp = os.path.join( '../../..', p ) + dp = os.path.join( 'Doom3_SDK/src', p ) + try: + os.makedirs( os.path.dirname( dp ) ) + except: + pass + print 'cp ' + sp + ' -> ' + dp + shutil.copy( sp, dp ) + +# copy explicit media content over +for root, dirs, files in os.walk( media ): + if '.svn' in dirs: + dirs.remove( '.svn' ) + for f in files: + sp = os.path.join( root, f ) + dp = os.path.join( 'Doom3_SDK', sp[ len( media ) + 1: ] ) + try: + os.makedirs( os.path.dirname( dp ) ) + except: + pass + print 'cp ' + sp + ' -> ' + dp + shutil.copy( sp, dp ) + +def makewritable( path ): + for root, dirs, files in os.walk( path ): + for f in files: + os.chmod( os.path.join( root, f ), stat.S_IWRITE ) + +# cleanup '.svn' +for root, dirs, files in os.walk( 'Doom3_SDK' ): + if '.svn' in dirs: + print 'remove ' + os.path.join( root, '.svn' ) + # SVN sets readonly on some files, which causes rmtree failure on win32 + makewritable( os.path.join( root, '.svn' ) ) + shutil.rmtree( os.path.join( root, '.svn' ) ) + dirs.remove( '.svn' ) diff --git a/sys/win32/sdk/source.list b/sys/win32/sdk/source.list new file mode 100644 index 000000000..04393a7b4 --- /dev/null +++ b/sys/win32/sdk/source.list @@ -0,0 +1,446 @@ +MayaImport/Maya4.5/maya.h +MayaImport/Maya6.0/maya.h +MayaImport/exporter.h +MayaImport/maya5.0/maya.h +MayaImport/maya_main.cpp +MayaImport/maya_main.h +MayaImport/maya_main.h +MayaImport/mayaimport.def +SConstruct +cm/CollisionModel.h +framework/BuildDefines.h +framework/BuildVersion.h +framework/CVarSystem.h +framework/CmdSystem.h +framework/Common.h +framework/DeclAF.h +framework/DeclEntityDef.h +framework/DeclFX.h +framework/DeclManager.h +framework/DeclPDA.h +framework/DeclParticle.h +framework/DeclSkin.h +framework/DeclTable.h +framework/File.h +framework/FileSystem.h +framework/Licensee.h +framework/UsercmdGen.h +framework/async/NetworkSystem.h +game/AF.cpp +game/AF.h +game/AFEntity.cpp +game/AFEntity.h +game/Actor.cpp +game/Actor.h +game/BrittleFracture.cpp +game/BrittleFracture.h +game/Camera.cpp +game/Camera.h +game/Entity.cpp +game/Entity.h +game/Fx.cpp +game/Fx.h +game/Game.def +game/Game.h +game/GameEdit.cpp +game/GameEdit.h +game/Game_local.cpp +game/Game_local.h +game/Game_network.cpp +game/IK.cpp +game/IK.h +game/Item.cpp +game/Item.h +game/Light.cpp +game/Light.h +game/Misc.cpp +game/Misc.h +game/Moveable.cpp +game/Moveable.h +game/Mover.cpp +game/Mover.h +game/MultiplayerGame.cpp +game/MultiplayerGame.h +game/Player.cpp +game/Player.h +game/PlayerIcon.cpp +game/PlayerIcon.h +game/PlayerView.cpp +game/PlayerView.h +game/Projectile.cpp +game/Projectile.h +game/Pvs.cpp +game/Pvs.h +game/SecurityCamera.cpp +game/SecurityCamera.h +game/SmokeParticles.cpp +game/SmokeParticles.h +game/Sound.cpp +game/Sound.h +game/Target.cpp +game/Target.h +game/Trigger.cpp +game/Trigger.h +game/Weapon.cpp +game/Weapon.h +game/WorldSpawn.cpp +game/WorldSpawn.h +game/ai/AAS.cpp +game/ai/AAS.h +game/ai/AAS_debug.cpp +game/ai/AAS_local.h +game/ai/AAS_pathing.cpp +game/ai/AAS_routing.cpp +game/ai/AI.cpp +game/ai/AI.h +game/ai/AI_Vagary.cpp +game/ai/AI_events.cpp +game/ai/AI_pathing.cpp +game/anim/Anim.cpp +game/anim/Anim.h +game/anim/Anim_Blend.cpp +game/anim/Anim_Import.cpp +game/anim/Anim_Testmodel.cpp +game/anim/Anim_Testmodel.h +game/gamesys/Callbacks.cpp +game/gamesys/Class.cpp +game/gamesys/Class.h +game/gamesys/DebugGraph.cpp +game/gamesys/DebugGraph.h +game/gamesys/Event.cpp +game/gamesys/Event.h +game/gamesys/NoGameTypeInfo.h +game/gamesys/SaveGame.cpp +game/gamesys/SaveGame.h +game/gamesys/SysCmds.cpp +game/gamesys/SysCmds.h +game/gamesys/SysCvar.cpp +game/gamesys/SysCvar.h +game/gamesys/TypeInfo.cpp +game/gamesys/TypeInfo.h +game/physics/Clip.cpp +game/physics/Clip.h +game/physics/Force.cpp +game/physics/Force.h +game/physics/Force_Constant.cpp +game/physics/Force_Constant.h +game/physics/Force_Drag.cpp +game/physics/Force_Drag.h +game/physics/Force_Field.cpp +game/physics/Force_Field.h +game/physics/Force_Spring.cpp +game/physics/Force_Spring.h +game/physics/Physics.cpp +game/physics/Physics.h +game/physics/Physics_AF.cpp +game/physics/Physics_AF.h +game/physics/Physics_Actor.cpp +game/physics/Physics_Actor.h +game/physics/Physics_Base.cpp +game/physics/Physics_Base.h +game/physics/Physics_Monster.cpp +game/physics/Physics_Monster.h +game/physics/Physics_Parametric.cpp +game/physics/Physics_Parametric.h +game/physics/Physics_Player.cpp +game/physics/Physics_Player.h +game/physics/Physics_RigidBody.cpp +game/physics/Physics_RigidBody.h +game/physics/Physics_Static.cpp +game/physics/Physics_Static.h +game/physics/Physics_StaticMulti.cpp +game/physics/Physics_StaticMulti.h +game/physics/Push.cpp +game/physics/Push.h +game/script/Script_Compiler.cpp +game/script/Script_Compiler.h +game/script/Script_Interpreter.cpp +game/script/Script_Interpreter.h +game/script/Script_Program.cpp +game/script/Script_Program.h +game/script/Script_Thread.cpp +game/script/Script_Thread.h +idlib/Base64.cpp +idlib/Base64.h +idlib/BitMsg.cpp +idlib/BitMsg.h +idlib/CmdArgs.cpp +idlib/CmdArgs.h +idlib/Dict.cpp +idlib/Dict.h +idlib/Heap.cpp +idlib/Heap.h +idlib/LangDict.cpp +idlib/LangDict.h +idlib/Lexer.cpp +idlib/Lexer.h +idlib/Lib.cpp +idlib/Lib.h +idlib/MapFile.cpp +idlib/MapFile.h +idlib/Parser.cpp +idlib/Parser.h +idlib/Str.cpp +idlib/Str.h +idlib/Timer.cpp +idlib/Timer.h +idlib/Token.cpp +idlib/Token.h +idlib/bv/Bounds.cpp +idlib/bv/Bounds.h +idlib/bv/Box.cpp +idlib/bv/Box.h +idlib/bv/Frustum.cpp +idlib/bv/Frustum_gcc.cpp +idlib/bv/Frustum.h +idlib/bv/Sphere.cpp +idlib/bv/Sphere.h +idlib/containers/BTree.h +idlib/containers/BinSearch.h +idlib/containers/HashIndex.cpp +idlib/containers/HashIndex.h +idlib/containers/HashTable.h +idlib/containers/Hierarchy.h +idlib/containers/LinkList.h +idlib/containers/List.h +idlib/containers/PlaneSet.h +idlib/containers/Queue.h +idlib/containers/Stack.h +idlib/containers/StaticList.h +idlib/containers/StrList.h +idlib/containers/StrPool.h +idlib/containers/VectorSet.h +idlib/geometry/DrawVert.cpp +idlib/geometry/DrawVert.h +idlib/geometry/JointTransform.cpp +idlib/geometry/JointTransform.h +idlib/geometry/Surface.cpp +idlib/geometry/Surface.h +idlib/geometry/Surface_Patch.cpp +idlib/geometry/Surface_Patch.h +idlib/geometry/Surface_Polytope.cpp +idlib/geometry/Surface_Polytope.h +idlib/geometry/Surface_SweptSpline.cpp +idlib/geometry/Surface_SweptSpline.h +idlib/geometry/TraceModel.cpp +idlib/geometry/TraceModel.h +idlib/geometry/Winding.cpp +idlib/geometry/Winding.h +idlib/geometry/Winding2D.cpp +idlib/geometry/Winding2D.h +idlib/hashing/CRC16.cpp +idlib/hashing/CRC16.h +idlib/hashing/CRC32.cpp +idlib/hashing/CRC32.h +idlib/hashing/CRC8.cpp +idlib/hashing/CRC8.h +idlib/hashing/Honeyman.cpp +idlib/hashing/Honeyman.h +idlib/hashing/MD4.cpp +idlib/hashing/MD4.h +idlib/hashing/MD5.cpp +idlib/hashing/MD5.h +idlib/math/Angles.cpp +idlib/math/Angles.h +idlib/math/Complex.cpp +idlib/math/Complex.h +idlib/math/Curve.h +idlib/math/Extrapolate.h +idlib/math/Interpolate.h +idlib/math/Lcp.cpp +idlib/math/Lcp.h +idlib/math/Math.cpp +idlib/math/Math.h +idlib/math/Matrix.cpp +idlib/math/Matrix.h +idlib/math/Ode.cpp +idlib/math/Ode.h +idlib/math/Plane.cpp +idlib/math/Plane.h +idlib/math/Pluecker.cpp +idlib/math/Pluecker.h +idlib/math/Polynomial.cpp +idlib/math/Polynomial.h +idlib/math/Quat.cpp +idlib/math/Quat.h +idlib/math/Random.h +idlib/math/Rotation.cpp +idlib/math/Rotation.h +idlib/math/Simd.cpp +idlib/math/Simd.h +idlib/math/Simd_3DNow.cpp +idlib/math/Simd_3DNow.h +idlib/math/Simd_AltiVec.cpp +idlib/math/Simd_AltiVec.h +idlib/math/Simd_Generic.cpp +idlib/math/Simd_Generic.h +idlib/math/Simd_MMX.cpp +idlib/math/Simd_MMX.h +idlib/math/Simd_SSE.cpp +idlib/math/Simd_SSE.h +idlib/math/Simd_SSE2.cpp +idlib/math/Simd_SSE2.h +idlib/math/Simd_SSE3.cpp +idlib/math/Simd_SSE3.h +idlib/math/Vector.cpp +idlib/math/Vector.h +idlib/precompiled.h +renderer/Cinematic.h +renderer/Material.h +renderer/Model.h +renderer/ModelManager.h +renderer/RenderSystem.h +renderer/RenderWorld.h +renderer/glext.h +renderer/qgl.h +renderer/qgl_linked.h +sound/sound.h +sys/linux/qgl_enforce.h +sys/scons/SConscript.game +sys/scons/SConscript.idlib +sys/scons/scons_utils.py +sys/sys_public.h +tools/compilers/aas/AASFile.h +tools/compilers/aas/AASFileManager.h +ui/ListGUI.h +ui/UserInterface.h +d3xp/Actor.cpp +d3xp/Actor.h +d3xp/AF.cpp +d3xp/AF.h +d3xp/AFEntity.cpp +d3xp/AFEntity.h +d3xp/ai/AAS.cpp +d3xp/ai/AAS.h +d3xp/ai/AAS_debug.cpp +d3xp/ai/AAS_local.h +d3xp/ai/AAS_pathing.cpp +d3xp/ai/AAS_routing.cpp +d3xp/ai/AI.cpp +d3xp/ai/AI.h +d3xp/ai/AI_events.cpp +d3xp/ai/AI_pathing.cpp +d3xp/ai/AI_Vagary.cpp +d3xp/anim/Anim.cpp +d3xp/anim/Anim.h +d3xp/anim/Anim_Blend.cpp +d3xp/anim/Anim_Import.cpp +d3xp/anim/Anim_Testmodel.cpp +d3xp/anim/Anim_Testmodel.h +d3xp/BrittleFracture.cpp +d3xp/BrittleFracture.h +d3xp/Camera.cpp +d3xp/Camera.h +d3xp/EndLevel.cpp +d3xp/EndLevel.h +d3xp/Entity.cpp +d3xp/Entity.h +d3xp/Fx.cpp +d3xp/Fx.h +d3xp/Game.def +d3xp/Game.h +d3xp/GameEdit.cpp +d3xp/GameEdit.h +d3xp/gamesys/Callbacks.cpp +d3xp/gamesys/Class.cpp +d3xp/gamesys/Class.h +d3xp/gamesys/DebugGraph.cpp +d3xp/gamesys/DebugGraph.h +d3xp/gamesys/Event.cpp +d3xp/gamesys/Event.h +d3xp/gamesys/NoGameTypeInfo.h +d3xp/gamesys/SaveGame.cpp +d3xp/gamesys/SaveGame.h +d3xp/gamesys/SysCmds.cpp +d3xp/gamesys/SysCmds.h +d3xp/gamesys/SysCvar.cpp +d3xp/gamesys/SysCvar.h +d3xp/gamesys/TypeInfo.cpp +d3xp/gamesys/TypeInfo.h +d3xp/Game_local.cpp +d3xp/Game_local.h +d3xp/Game_network.cpp +d3xp/Grabber.cpp +d3xp/Grabber.h +d3xp/IK.cpp +d3xp/IK.h +d3xp/Item.cpp +d3xp/Item.h +d3xp/Light.cpp +d3xp/Light.h +d3xp/Misc.cpp +d3xp/Misc.h +d3xp/Moveable.cpp +d3xp/Moveable.h +d3xp/Mover.cpp +d3xp/Mover.h +d3xp/MultiplayerGame.cpp +d3xp/MultiplayerGame.h +d3xp/physics/Clip.cpp +d3xp/physics/Clip.h +d3xp/physics/Force.cpp +d3xp/physics/Force.h +d3xp/physics/Force_Constant.cpp +d3xp/physics/Force_Constant.h +d3xp/physics/Force_Drag.cpp +d3xp/physics/Force_Drag.h +d3xp/physics/Force_Field.cpp +d3xp/physics/Force_Field.h +d3xp/physics/Force_Grab.cpp +d3xp/physics/Force_Grab.h +d3xp/physics/Force_Spring.cpp +d3xp/physics/Force_Spring.h +d3xp/physics/Physics.cpp +d3xp/physics/Physics.h +d3xp/physics/Physics_Actor.cpp +d3xp/physics/Physics_Actor.h +d3xp/physics/Physics_AF.cpp +d3xp/physics/Physics_AF.h +d3xp/physics/Physics_Base.cpp +d3xp/physics/Physics_Base.h +d3xp/physics/Physics_Monster.cpp +d3xp/physics/Physics_Monster.h +d3xp/physics/Physics_Parametric.cpp +d3xp/physics/Physics_Parametric.h +d3xp/physics/Physics_Player.cpp +d3xp/physics/Physics_Player.h +d3xp/physics/Physics_RigidBody.cpp +d3xp/physics/Physics_RigidBody.h +d3xp/physics/Physics_Static.cpp +d3xp/physics/Physics_Static.h +d3xp/physics/Physics_StaticMulti.cpp +d3xp/physics/Physics_StaticMulti.h +d3xp/physics/Push.cpp +d3xp/physics/Push.h +d3xp/Player.cpp +d3xp/Player.h +d3xp/PlayerIcon.cpp +d3xp/PlayerIcon.h +d3xp/PlayerView.cpp +d3xp/PlayerView.h +d3xp/Projectile.cpp +d3xp/Projectile.h +d3xp/Pvs.cpp +d3xp/Pvs.h +d3xp/script/Script_Compiler.cpp +d3xp/script/Script_Compiler.h +d3xp/script/Script_Interpreter.cpp +d3xp/script/Script_Interpreter.h +d3xp/script/Script_Program.cpp +d3xp/script/Script_Program.h +d3xp/script/Script_Thread.cpp +d3xp/script/Script_Thread.h +d3xp/SecurityCamera.cpp +d3xp/SecurityCamera.h +d3xp/SmokeParticles.cpp +d3xp/SmokeParticles.h +d3xp/Sound.cpp +d3xp/Sound.h +d3xp/Target.cpp +d3xp/Target.h +d3xp/Trigger.cpp +d3xp/Trigger.h +d3xp/Weapon.cpp +d3xp/Weapon.h +d3xp/WorldSpawn.cpp +d3xp/WorldSpawn.h diff --git a/sys/win32/win_cpu.cpp b/sys/win32/win_cpu.cpp new file mode 100644 index 000000000..12badf658 --- /dev/null +++ b/sys/win32/win_cpu.cpp @@ -0,0 +1,921 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "win_local.h" + + +/* +============================================================== + + Clock ticks + +============================================================== +*/ + +/* +================ +Sys_GetClockTicks +================ +*/ +double Sys_GetClockTicks( void ) { +#if 0 + + LARGE_INTEGER li; + + QueryPerformanceCounter( &li ); + return = (double ) li.LowPart + (double) 0xFFFFFFFF * li.HighPart; + +#else + + unsigned long lo, hi; + + __asm { + push ebx + xor eax, eax + cpuid + rdtsc + mov lo, eax + mov hi, edx + pop ebx + } + return (double ) lo + (double) 0xFFFFFFFF * hi; + +#endif +} + +/* +================ +Sys_ClockTicksPerSecond +================ +*/ +double Sys_ClockTicksPerSecond( void ) { + static double ticks = 0; +#if 0 + + if ( !ticks ) { + LARGE_INTEGER li; + QueryPerformanceFrequency( &li ); + ticks = li.QuadPart; + } + +#else + + if ( !ticks ) { + HKEY hKey; + LPBYTE ProcSpeed; + DWORD buflen, ret; + + if ( !RegOpenKeyEx( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey ) ) { + ProcSpeed = 0; + buflen = sizeof( ProcSpeed ); + ret = RegQueryValueEx( hKey, "~MHz", NULL, NULL, (LPBYTE) &ProcSpeed, &buflen ); + // If we don't succeed, try some other spellings. + if ( ret != ERROR_SUCCESS ) { + ret = RegQueryValueEx( hKey, "~Mhz", NULL, NULL, (LPBYTE) &ProcSpeed, &buflen ); + } + if ( ret != ERROR_SUCCESS ) { + ret = RegQueryValueEx( hKey, "~mhz", NULL, NULL, (LPBYTE) &ProcSpeed, &buflen ); + } + RegCloseKey( hKey ); + if ( ret == ERROR_SUCCESS ) { + ticks = (double) ((unsigned long)ProcSpeed) * 1000000; + } + } + } + +#endif + return ticks; +} + + +/* +============================================================== + + CPU + +============================================================== +*/ + +/* +================ +HasCPUID +================ +*/ +static bool HasCPUID( void ) { + __asm + { + pushfd // save eflags + pop eax + test eax, 0x00200000 // check ID bit + jz set21 // bit 21 is not set, so jump to set_21 + and eax, 0xffdfffff // clear bit 21 + push eax // save new value in register + popfd // store new value in flags + pushfd + pop eax + test eax, 0x00200000 // check ID bit + jz good + jmp err // cpuid not supported +set21: + or eax, 0x00200000 // set ID bit + push eax // store new value + popfd // store new value in EFLAGS + pushfd + pop eax + test eax, 0x00200000 // if bit 21 is on + jnz good + jmp err + } + +err: + return false; +good: + return true; +} + +#define _REG_EAX 0 +#define _REG_EBX 1 +#define _REG_ECX 2 +#define _REG_EDX 3 + +/* +================ +CPUID +================ +*/ +static void CPUID( int func, unsigned regs[4] ) { + unsigned regEAX, regEBX, regECX, regEDX; + + __asm pusha + __asm mov eax, func + __asm __emit 00fh + __asm __emit 0a2h + __asm mov regEAX, eax + __asm mov regEBX, ebx + __asm mov regECX, ecx + __asm mov regEDX, edx + __asm popa + + regs[_REG_EAX] = regEAX; + regs[_REG_EBX] = regEBX; + regs[_REG_ECX] = regECX; + regs[_REG_EDX] = regEDX; +} + + +/* +================ +IsAMD +================ +*/ +static bool IsAMD( void ) { + char pstring[16]; + char processorString[13]; + + // get name of processor + CPUID( 0, ( unsigned int * ) pstring ); + processorString[0] = pstring[4]; + processorString[1] = pstring[5]; + processorString[2] = pstring[6]; + processorString[3] = pstring[7]; + processorString[4] = pstring[12]; + processorString[5] = pstring[13]; + processorString[6] = pstring[14]; + processorString[7] = pstring[15]; + processorString[8] = pstring[8]; + processorString[9] = pstring[9]; + processorString[10] = pstring[10]; + processorString[11] = pstring[11]; + processorString[12] = 0; + + if ( strcmp( processorString, "AuthenticAMD" ) == 0 ) { + return true; + } + return false; +} + +/* +================ +HasCMOV +================ +*/ +static bool HasCMOV( void ) { + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 15 of EDX denotes CMOV existence + if ( regs[_REG_EDX] & ( 1 << 15 ) ) { + return true; + } + return false; +} + +/* +================ +Has3DNow +================ +*/ +static bool Has3DNow( void ) { + unsigned regs[4]; + + // check AMD-specific functions + CPUID( 0x80000000, regs ); + if ( regs[_REG_EAX] < 0x80000000 ) { + return false; + } + + // bit 31 of EDX denotes 3DNow! support + CPUID( 0x80000001, regs ); + if ( regs[_REG_EDX] & ( 1 << 31 ) ) { + return true; + } + + return false; +} + +/* +================ +HasMMX +================ +*/ +static bool HasMMX( void ) { + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 23 of EDX denotes MMX existence + if ( regs[_REG_EDX] & ( 1 << 23 ) ) { + return true; + } + return false; +} + +/* +================ +HasSSE +================ +*/ +static bool HasSSE( void ) { + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 25 of EDX denotes SSE existence + if ( regs[_REG_EDX] & ( 1 << 25 ) ) { + return true; + } + return false; +} + +/* +================ +HasSSE2 +================ +*/ +static bool HasSSE2( void ) { + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 26 of EDX denotes SSE2 existence + if ( regs[_REG_EDX] & ( 1 << 26 ) ) { + return true; + } + return false; +} + +/* +================ +HasSSE3 +================ +*/ +static bool HasSSE3( void ) { + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 0 of ECX denotes SSE3 existence + if ( regs[_REG_ECX] & ( 1 << 0 ) ) { + return true; + } + return false; +} + +/* +================ +LogicalProcPerPhysicalProc +================ +*/ +#define NUM_LOGICAL_BITS 0x00FF0000 // EBX[23:16] Bit 16-23 in ebx contains the number of logical + // processors per physical processor when execute cpuid with + // eax set to 1 +static unsigned char LogicalProcPerPhysicalProc( void ) { + unsigned int regebx = 0; + __asm { + mov eax, 1 + cpuid + mov regebx, ebx + } + return (unsigned char) ((regebx & NUM_LOGICAL_BITS) >> 16); +} + +/* +================ +GetAPIC_ID +================ +*/ +#define INITIAL_APIC_ID_BITS 0xFF000000 // EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique + // initial APIC ID for the processor this code is running on. + // Default value = 0xff if HT is not supported +static unsigned char GetAPIC_ID( void ) { + unsigned int regebx = 0; + __asm { + mov eax, 1 + cpuid + mov regebx, ebx + } + return (unsigned char) ((regebx & INITIAL_APIC_ID_BITS) >> 24); +} + +/* +================ +CPUCount + + logicalNum is the number of logical CPU per physical CPU + physicalNum is the total number of physical processor + returns one of the HT_* flags +================ +*/ +#define HT_NOT_CAPABLE 0 +#define HT_ENABLED 1 +#define HT_DISABLED 2 +#define HT_SUPPORTED_NOT_ENABLED 3 +#define HT_CANNOT_DETECT 4 + +int CPUCount( int &logicalNum, int &physicalNum ) { + int statusFlag; + SYSTEM_INFO info; + + physicalNum = 1; + logicalNum = 1; + statusFlag = HT_NOT_CAPABLE; + + info.dwNumberOfProcessors = 0; + GetSystemInfo (&info); + + // Number of physical processors in a non-Intel system + // or in a 32-bit Intel system with Hyper-Threading technology disabled + physicalNum = info.dwNumberOfProcessors; + + unsigned char HT_Enabled = 0; + + logicalNum = LogicalProcPerPhysicalProc(); + + if ( logicalNum >= 1 ) { // > 1 doesn't mean HT is enabled in the BIOS + HANDLE hCurrentProcessHandle; + DWORD dwProcessAffinity; + DWORD dwSystemAffinity; + DWORD dwAffinityMask; + + // Calculate the appropriate shifts and mask based on the + // number of logical processors. + + unsigned char i = 1, PHY_ID_MASK = 0xFF, PHY_ID_SHIFT = 0; + + while( i < logicalNum ) { + i *= 2; + PHY_ID_MASK <<= 1; + PHY_ID_SHIFT++; + } + + hCurrentProcessHandle = GetCurrentProcess(); + GetProcessAffinityMask( hCurrentProcessHandle, &dwProcessAffinity, &dwSystemAffinity ); + + // Check if available process affinity mask is equal to the + // available system affinity mask + if ( dwProcessAffinity != dwSystemAffinity ) { + statusFlag = HT_CANNOT_DETECT; + physicalNum = -1; + return statusFlag; + } + + dwAffinityMask = 1; + while ( dwAffinityMask != 0 && dwAffinityMask <= dwProcessAffinity ) { + // Check if this CPU is available + if ( dwAffinityMask & dwProcessAffinity ) { + if ( SetProcessAffinityMask( hCurrentProcessHandle, dwAffinityMask ) ) { + unsigned char APIC_ID, LOG_ID, PHY_ID; + + Sleep( 0 ); // Give OS time to switch CPU + + APIC_ID = GetAPIC_ID(); + LOG_ID = APIC_ID & ~PHY_ID_MASK; + PHY_ID = APIC_ID >> PHY_ID_SHIFT; + + if ( LOG_ID != 0 ) { + HT_Enabled = 1; + } + } + } + dwAffinityMask = dwAffinityMask << 1; + } + + // Reset the processor affinity + SetProcessAffinityMask( hCurrentProcessHandle, dwProcessAffinity ); + + if ( logicalNum == 1 ) { // Normal P4 : HT is disabled in hardware + statusFlag = HT_DISABLED; + } else { + if ( HT_Enabled ) { + // Total physical processors in a Hyper-Threading enabled system. + physicalNum /= logicalNum; + statusFlag = HT_ENABLED; + } else { + statusFlag = HT_SUPPORTED_NOT_ENABLED; + } + } + } + return statusFlag; +} + +/* +================ +HasHTT +================ +*/ +static bool HasHTT( void ) { + unsigned regs[4]; + int logicalNum, physicalNum, HTStatusFlag; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 28 of EDX denotes HTT existence + if ( !( regs[_REG_EDX] & ( 1 << 28 ) ) ) { + return false; + } + + HTStatusFlag = CPUCount( logicalNum, physicalNum ); + if ( HTStatusFlag != HT_ENABLED ) { + return false; + } + return true; +} + +/* +================ +HasHTT +================ +*/ +static bool HasDAZ( void ) { + __declspec(align(16)) unsigned char FXSaveArea[512]; + unsigned char *FXArea = FXSaveArea; + DWORD dwMask = 0; + unsigned regs[4]; + + // get CPU feature bits + CPUID( 1, regs ); + + // bit 24 of EDX denotes support for FXSAVE + if ( !( regs[_REG_EDX] & ( 1 << 24 ) ) ) { + return false; + } + + memset( FXArea, 0, sizeof( FXSaveArea ) ); + + __asm { + mov eax, FXArea + FXSAVE [eax] + } + + dwMask = *(DWORD *)&FXArea[28]; // Read the MXCSR Mask + return ( ( dwMask & ( 1 << 6 ) ) == ( 1 << 6 ) ); // Return if the DAZ bit is set +} + +/* +================ +Sys_GetCPUId +================ +*/ +cpuid_t Sys_GetCPUId( void ) { + int flags; + + // verify we're at least a Pentium or 486 with CPUID support + if ( !HasCPUID() ) { + return CPUID_UNSUPPORTED; + } + + // check for an AMD + if ( IsAMD() ) { + flags = CPUID_AMD; + } else { + flags = CPUID_INTEL; + } + + // check for Multi Media Extensions + if ( HasMMX() ) { + flags |= CPUID_MMX; + } + + // check for 3DNow! + if ( Has3DNow() ) { + flags |= CPUID_3DNOW; + } + + // check for Streaming SIMD Extensions + if ( HasSSE() ) { + flags |= CPUID_SSE | CPUID_FTZ; + } + + // check for Streaming SIMD Extensions 2 + if ( HasSSE2() ) { + flags |= CPUID_SSE2; + } + + // check for Streaming SIMD Extensions 3 aka Prescott's New Instructions + if ( HasSSE3() ) { + flags |= CPUID_SSE3; + } + + // check for Hyper-Threading Technology + if ( HasHTT() ) { + flags |= CPUID_HTT; + } + + // check for Conditional Move (CMOV) and fast floating point comparison (FCOMI) instructions + if ( HasCMOV() ) { + flags |= CPUID_CMOV; + } + + // check for Denormals-Are-Zero mode + if ( HasDAZ() ) { + flags |= CPUID_DAZ; + } + + return (cpuid_t)flags; +} + + +/* +=============================================================================== + + FPU + +=============================================================================== +*/ + +typedef struct bitFlag_s { + char * name; + int bit; +} bitFlag_t; + +static byte fpuState[128], *statePtr = fpuState; +static char fpuString[2048]; +static bitFlag_t controlWordFlags[] = { + { "Invalid operation", 0 }, + { "Denormalized operand", 1 }, + { "Divide-by-zero", 2 }, + { "Numeric overflow", 3 }, + { "Numeric underflow", 4 }, + { "Inexact result (precision)", 5 }, + { "Infinity control", 12 }, + { "", 0 } +}; +static char *precisionControlField[] = { + "Single Precision (24-bits)", + "Reserved", + "Double Precision (53-bits)", + "Double Extended Precision (64-bits)" +}; +static char *roundingControlField[] = { + "Round to nearest", + "Round down", + "Round up", + "Round toward zero" +}; +static bitFlag_t statusWordFlags[] = { + { "Invalid operation", 0 }, + { "Denormalized operand", 1 }, + { "Divide-by-zero", 2 }, + { "Numeric overflow", 3 }, + { "Numeric underflow", 4 }, + { "Inexact result (precision)", 5 }, + { "Stack fault", 6 }, + { "Error summary status", 7 }, + { "FPU busy", 15 }, + { "", 0 } +}; + +/* +=============== +Sys_FPU_PrintStateFlags +=============== +*/ +int Sys_FPU_PrintStateFlags( char *ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ) { + int i, length = 0; + + length += sprintf( ptr+length, "CTRL = %08x\n" + "STAT = %08x\n" + "TAGS = %08x\n" + "INOF = %08x\n" + "INSE = %08x\n" + "OPOF = %08x\n" + "OPSE = %08x\n" + "\n", + ctrl, stat, tags, inof, inse, opof, opse ); + + length += sprintf( ptr+length, "Control Word:\n" ); + for ( i = 0; controlWordFlags[i].name[0]; i++ ) { + length += sprintf( ptr+length, " %-30s = %s\n", controlWordFlags[i].name, ( ctrl & ( 1 << controlWordFlags[i].bit ) ) ? "true" : "false" ); + } + length += sprintf( ptr+length, " %-30s = %s\n", "Precision control", precisionControlField[(ctrl>>8)&3] ); + length += sprintf( ptr+length, " %-30s = %s\n", "Rounding control", roundingControlField[(ctrl>>10)&3] ); + + length += sprintf( ptr+length, "Status Word:\n" ); + for ( i = 0; statusWordFlags[i].name[0]; i++ ) { + ptr += sprintf( ptr+length, " %-30s = %s\n", statusWordFlags[i].name, ( stat & ( 1 << statusWordFlags[i].bit ) ) ? "true" : "false" ); + } + length += sprintf( ptr+length, " %-30s = %d%d%d%d\n", "Condition code", (stat>>8)&1, (stat>>9)&1, (stat>>10)&1, (stat>>14)&1 ); + length += sprintf( ptr+length, " %-30s = %d\n", "Top of stack pointer", (stat>>11)&7 ); + + return length; +} + +/* +=============== +Sys_FPU_StackIsEmpty +=============== +*/ +bool Sys_FPU_StackIsEmpty( void ) { + __asm { + mov eax, statePtr + fnstenv [eax] + mov eax, [eax+8] + xor eax, 0xFFFFFFFF + and eax, 0x0000FFFF + jz empty + } + return false; +empty: + return true; +} + +/* +=============== +Sys_FPU_ClearStack +=============== +*/ +void Sys_FPU_ClearStack( void ) { + __asm { + mov eax, statePtr + fnstenv [eax] + mov eax, [eax+8] + xor eax, 0xFFFFFFFF + mov edx, (3<<14) + emptyStack: + mov ecx, eax + and ecx, edx + jz done + fstp st + shr edx, 2 + jmp emptyStack + done: + } +} + +/* +=============== +Sys_FPU_GetState + + gets the FPU state without changing the state +=============== +*/ +const char *Sys_FPU_GetState( void ) { + double fpuStack[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + double *fpuStackPtr = fpuStack; + int i, numValues; + char *ptr; + + __asm { + mov esi, statePtr + mov edi, fpuStackPtr + fnstenv [esi] + mov esi, [esi+8] + xor esi, 0xFFFFFFFF + mov edx, (3<<14) + xor eax, eax + mov ecx, esi + and ecx, edx + jz done + fst qword ptr [edi+0] + inc eax + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(1) + fst qword ptr [edi+8] + inc eax + fxch st(1) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(2) + fst qword ptr [edi+16] + inc eax + fxch st(2) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(3) + fst qword ptr [edi+24] + inc eax + fxch st(3) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(4) + fst qword ptr [edi+32] + inc eax + fxch st(4) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(5) + fst qword ptr [edi+40] + inc eax + fxch st(5) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(6) + fst qword ptr [edi+48] + inc eax + fxch st(6) + shr edx, 2 + mov ecx, esi + and ecx, edx + jz done + fxch st(7) + fst qword ptr [edi+56] + inc eax + fxch st(7) + done: + mov numValues, eax + } + + int ctrl = *(int *)&fpuState[0]; + int stat = *(int *)&fpuState[4]; + int tags = *(int *)&fpuState[8]; + int inof = *(int *)&fpuState[12]; + int inse = *(int *)&fpuState[16]; + int opof = *(int *)&fpuState[20]; + int opse = *(int *)&fpuState[24]; + + ptr = fpuString; + ptr += sprintf( ptr,"FPU State:\n" + "num values on stack = %d\n", numValues ); + for ( i = 0; i < 8; i++ ) { + ptr += sprintf( ptr, "ST%d = %1.10e\n", i, fpuStack[i] ); + } + + Sys_FPU_PrintStateFlags( ptr, ctrl, stat, tags, inof, inse, opof, opse ); + + return fpuString; +} + +/* +=============== +Sys_FPU_EnableExceptions +=============== +*/ +void Sys_FPU_EnableExceptions( int exceptions ) { + __asm { + mov eax, statePtr + mov ecx, exceptions + and cx, 63 + not cx + fnstcw word ptr [eax] + mov bx, word ptr [eax] + or bx, 63 + and bx, cx + mov word ptr [eax], bx + fldcw word ptr [eax] + } +} + +/* +=============== +Sys_FPU_SetPrecision +=============== +*/ +void Sys_FPU_SetPrecision( int precision ) { + short precisionBitTable[4] = { 0, 1, 3, 0 }; + short precisionBits = precisionBitTable[precision & 3] << 8; + short precisionMask = ~( ( 1 << 9 ) | ( 1 << 8 ) ); + + __asm { + mov eax, statePtr + mov cx, precisionBits + fnstcw word ptr [eax] + mov bx, word ptr [eax] + and bx, precisionMask + or bx, cx + mov word ptr [eax], bx + fldcw word ptr [eax] + } +} + +/* +================ +Sys_FPU_SetRounding +================ +*/ +void Sys_FPU_SetRounding( int rounding ) { + short roundingBitTable[4] = { 0, 1, 2, 3 }; + short roundingBits = roundingBitTable[rounding & 3] << 10; + short roundingMask = ~( ( 1 << 11 ) | ( 1 << 10 ) ); + + __asm { + mov eax, statePtr + mov cx, roundingBits + fnstcw word ptr [eax] + mov bx, word ptr [eax] + and bx, roundingMask + or bx, cx + mov word ptr [eax], bx + fldcw word ptr [eax] + } +} + +/* +================ +Sys_FPU_SetDAZ +================ +*/ +void Sys_FPU_SetDAZ( bool enable ) { + DWORD dwData; + + _asm { + movzx ecx, byte ptr enable + and ecx, 1 + shl ecx, 6 + STMXCSR dword ptr dwData + mov eax, dwData + and eax, ~(1<<6) // clear DAX bit + or eax, ecx // set the DAZ bit + mov dwData, eax + LDMXCSR dword ptr dwData + } +} + +/* +================ +Sys_FPU_SetFTZ +================ +*/ +void Sys_FPU_SetFTZ( bool enable ) { + DWORD dwData; + + _asm { + movzx ecx, byte ptr enable + and ecx, 1 + shl ecx, 15 + STMXCSR dword ptr dwData + mov eax, dwData + and eax, ~(1<<15) // clear FTZ bit + or eax, ecx // set the FTZ bit + mov dwData, eax + LDMXCSR dword ptr dwData + } +} diff --git a/sys/win32/win_gamma.cpp b/sys/win32/win_gamma.cpp new file mode 100644 index 000000000..9eec4e442 --- /dev/null +++ b/sys/win32/win_gamma.cpp @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/* +** WIN_GAMMA.C +*/ +#include +#include "win_local.h" +#include "../../renderer/tr_local.h" + +static unsigned short s_oldHardwareGamma[3][256]; + +/* +** WG_GetOldGammaRamp +** +*/ +void WG_GetOldGammaRamp( void ) +{ + HDC hDC; + + hDC = GetDC( GetDesktopWindow() ); + GetDeviceGammaRamp( hDC, s_oldHardwareGamma ); + ReleaseDC( GetDesktopWindow(), hDC ); + + +/* +** GLimp_SetGamma +** +*/ +void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) +{ + unsigned short table[3][256]; + int i; + + if ( !glw_state.hDC ) + { + return; + } + + for ( i = 0; i < 256; i++ ) + { + table[0][i] = ( ( ( unsigned short ) red[i] ) << 8 ) | red[i]; + table[1][i] = ( ( ( unsigned short ) green[i] ) << 8 ) | green[i]; + table[2][i] = ( ( ( unsigned short ) blue[i] ) << 8 ) | blue[i]; + } + + if ( !SetDeviceGammaRamp( glw_state.hDC, table ) ) { + common->Printf( "WARNING: SetDeviceGammaRamp failed.\n" ); + } +} + +/* +** WG_RestoreGamma +*/ +void WG_RestoreGamma( void ) +{ + HDC hDC; + + // if we never read in a reasonable looking + // table, don't write it out + if ( s_oldHardwareGamma[0][255] == 0 ) { + return; + } + + hDC = GetDC( GetDesktopWindow() ); + SetDeviceGammaRamp( hDC, s_oldHardwareGamma ); + ReleaseDC( GetDesktopWindow(), hDC ); +} + diff --git a/sys/win32/win_glimp.cpp b/sys/win32/win_glimp.cpp new file mode 100644 index 000000000..34c210954 --- /dev/null +++ b/sys/win32/win_glimp.cpp @@ -0,0 +1,1232 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/* +** WIN_GLIMP.C +** +** This file contains ALL Win32 specific stuff having to do with the +** OpenGL refresh. When a port is being made the following functions +** must be implemented by the port: +** +** GLimp_SwapBuffers +** GLimp_Init +** GLimp_Shutdown +** GLimp_SetGamma +** +** Note that the GLW_xxx functions are Windows specific GL-subsystem +** related functions that are relevant ONLY to win_glimp.c +*/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "win_local.h" +#include "rc/AFEditor_resource.h" +#include "rc/doom_resource.h" +#include "../../renderer/tr_local.h" + +static void GLW_InitExtensions( void ); + + +// WGL_ARB_extensions_string +PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; + +// WGL_EXT_swap_interval +PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + +// WGL_ARB_pixel_format +PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB; +PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB; +PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; + +// WGL_ARB_pbuffer +PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB; +PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB; +PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB; +PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB; +PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB; + +// WGL_ARB_render_texture +PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB; +PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB; +PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB; + + + +/* ARB_pixel_format */ +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +/* ARB_multisample */ +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + + + +// +// function declaration +// +bool QGL_Init( const char *dllname ); +void QGL_Shutdown( void ); + + + +/* +======================== +GLimp_GetOldGammaRamp +======================== +*/ +static void GLimp_SaveGamma( void ) { + HDC hDC; + BOOL success; + + hDC = GetDC( GetDesktopWindow() ); + success = GetDeviceGammaRamp( hDC, win32.oldHardwareGamma ); + common->DPrintf( "...getting default gamma ramp: %s\n", success ? "success" : "failed" ); + ReleaseDC( GetDesktopWindow(), hDC ); +} + +/* +======================== +GLimp_RestoreGamma +======================== +*/ +static void GLimp_RestoreGamma( void ) { + HDC hDC; + BOOL success; + + // if we never read in a reasonable looking + // table, don't write it out + if ( win32.oldHardwareGamma[0][255] == 0 ) { + return; + } + + hDC = GetDC( GetDesktopWindow() ); + success = SetDeviceGammaRamp( hDC, win32.oldHardwareGamma ); + common->DPrintf ( "...restoring hardware gamma: %s\n", success ? "success" : "failed" ); + ReleaseDC( GetDesktopWindow(), hDC ); +} + + +/* +======================== +GLimp_SetGamma + +The renderer calls this when the user adjusts r_gamma or r_brightness +======================== +*/ +void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigned short blue[256] ) { + unsigned short table[3][256]; + int i; + + if ( !win32.hDC ) { + return; + } + + for ( i = 0; i < 256; i++ ) { + table[0][i] = red[i]; + table[1][i] = green[i]; + table[2][i] = blue[i]; + } + + if ( !SetDeviceGammaRamp( win32.hDC, table ) ) { + common->Printf( "WARNING: SetDeviceGammaRamp failed.\n" ); + } +} + +/* +============================================================================= + +WglExtension Grabbing + +This is gross -- creating a window just to get a context to get the wgl extensions + +============================================================================= +*/ + +/* +==================== +FakeWndProc + +Only used to get wglExtensions +==================== +*/ +LONG WINAPI FakeWndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + + if ( uMsg == WM_DESTROY ) { + PostQuitMessage(0); + } + + if ( uMsg != WM_CREATE ) { + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + + const static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, + 0, 0, 0, 0, 0, 0, + 8, 0, + 0, 0, 0, 0, + 24, 8, + 0, + PFD_MAIN_PLANE, + 0, + 0, + 0, + 0, + }; + int pixelFormat; + HDC hDC; + HGLRC hGLRC; + + hDC = GetDC(hWnd); + + // Set up OpenGL + pixelFormat = ChoosePixelFormat(hDC, &pfd); + SetPixelFormat(hDC, pixelFormat, &pfd); + hGLRC = qwglCreateContext(hDC); + qwglMakeCurrent(hDC, hGLRC); + + // free things + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hGLRC); + ReleaseDC(hWnd, hDC); + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +/* +================== +GLW_GetWGLExtensionsWithFakeWindow +================== +*/ +void GLW_CheckWGLExtensions( HDC hDC ) { + wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) + GLimp_ExtensionPointer("wglGetExtensionsStringARB"); + if ( wglGetExtensionsStringARB ) { + glConfig.wgl_extensions_string = (const char *) wglGetExtensionsStringARB(hDC); + } else { + glConfig.wgl_extensions_string = ""; + } + + // WGL_EXT_swap_control + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GLimp_ExtensionPointer( "wglSwapIntervalEXT" ); + r_swapInterval.SetModified(); // force a set next frame + + // WGL_ARB_pixel_format + wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)GLimp_ExtensionPointer("wglGetPixelFormatAttribivARB"); + wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)GLimp_ExtensionPointer("wglGetPixelFormatAttribfvARB"); + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)GLimp_ExtensionPointer("wglChoosePixelFormatARB"); + + // WGL_ARB_pbuffer + wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)GLimp_ExtensionPointer("wglCreatePbufferARB"); + wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)GLimp_ExtensionPointer("wglGetPbufferDCARB"); + wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)GLimp_ExtensionPointer("wglReleasePbufferDCARB"); + wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)GLimp_ExtensionPointer("wglDestroyPbufferARB"); + wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)GLimp_ExtensionPointer("wglQueryPbufferARB"); + + // WGL_ARB_render_texture + wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)GLimp_ExtensionPointer("wglBindTexImageARB"); + wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)GLimp_ExtensionPointer("wglReleaseTexImageARB"); + wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)GLimp_ExtensionPointer("wglSetPbufferAttribARB"); +} + +/* +================== +GLW_GetWGLExtensionsWithFakeWindow +================== +*/ +static void GLW_GetWGLExtensionsWithFakeWindow( void ) { + HWND hWnd; + MSG msg; + + // Create a window for the sole purpose of getting + // a valid context to get the wglextensions + hWnd = CreateWindow(WIN32_FAKE_WINDOW_CLASS_NAME, GAME_NAME, + WS_OVERLAPPEDWINDOW, + 40, 40, + 640, + 480, + NULL, NULL, win32.hInstance, NULL ); + if ( !hWnd ) { + common->FatalError( "GLW_GetWGLExtensionsWithFakeWindow: Couldn't create fake window" ); + } + + HDC hDC = GetDC( hWnd ); + HGLRC gRC = wglCreateContext( hDC ); + wglMakeCurrent( hDC, gRC ); + GLW_CheckWGLExtensions( hDC ); + wglDeleteContext( gRC ); + ReleaseDC( hWnd, hDC ); + + DestroyWindow( hWnd ); + while ( GetMessage( &msg, NULL, 0, 0 ) ) { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } +} + +//============================================================================= + +/* +==================== +GLW_WM_CREATE +==================== +*/ +void GLW_WM_CREATE( HWND hWnd ) { +} + + + +/* +==================== +GLW_InitDriver + +Set the pixelformat for the window before it is +shown, and create the rendering context +==================== +*/ +static bool GLW_InitDriver( glimpParms_t parms ) { + PIXELFORMATDESCRIPTOR src = + { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 32, // 32-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 8, // 8 bit destination alpha + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 24, // 24-bit z-buffer + 8, // 8-bit stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + + common->Printf( "Initializing OpenGL driver\n" ); + + // + // get a DC for our window if we don't already have one allocated + // + if ( win32.hDC == NULL ) { + common->Printf( "...getting DC: " ); + + if ( ( win32.hDC = GetDC( win32.hWnd ) ) == NULL ) { + common->Printf( "^3failed^0\n" ); + return false; + } + common->Printf( "succeeded\n" ); + } + + // the multisample path uses the wgl + if ( wglChoosePixelFormatARB && parms.multiSamples > 1 ) { + int iAttributes[20]; + FLOAT fAttributes[] = {0, 0}; + UINT numFormats; + + // FIXME: specify all the other stuff + iAttributes[0] = WGL_SAMPLE_BUFFERS_ARB; + iAttributes[1] = 1; + iAttributes[2] = WGL_SAMPLES_ARB; + iAttributes[3] = parms.multiSamples; + iAttributes[4] = WGL_DOUBLE_BUFFER_ARB; + iAttributes[5] = TRUE; + iAttributes[6] = WGL_STENCIL_BITS_ARB; + iAttributes[7] = 8; + iAttributes[8] = WGL_DEPTH_BITS_ARB; + iAttributes[9] = 24; + iAttributes[10] = WGL_RED_BITS_ARB; + iAttributes[11] = 8; + iAttributes[12] = WGL_BLUE_BITS_ARB; + iAttributes[13] = 8; + iAttributes[14] = WGL_GREEN_BITS_ARB; + iAttributes[15] = 8; + iAttributes[16] = WGL_ALPHA_BITS_ARB; + iAttributes[17] = 8; + iAttributes[18] = 0; + iAttributes[19] = 0; + + wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes, 1, &win32.pixelformat, &numFormats ); + } else { + // this is the "classic" choose pixel format path + + // eventually we may need to have more fallbacks, but for + // now, ask for everything + if ( parms.stereo ) { + common->Printf( "...attempting to use stereo\n" ); + src.dwFlags |= PFD_STEREO; + } + + // + // choose, set, and describe our desired pixel format. If we're + // using a minidriver then we need to bypass the GDI functions, + // otherwise use the GDI functions. + // + if ( ( win32.pixelformat = ChoosePixelFormat( win32.hDC, &src ) ) == 0 ) { + common->Printf( "...^3GLW_ChoosePFD failed^0\n"); + return false; + } + common->Printf( "...PIXELFORMAT %d selected\n", win32.pixelformat ); + } + + // get the full info + DescribePixelFormat( win32.hDC, win32.pixelformat, sizeof( win32.pfd ), &win32.pfd ); + glConfig.colorBits = win32.pfd.cColorBits; + glConfig.depthBits = win32.pfd.cDepthBits; + glConfig.stencilBits = win32.pfd.cStencilBits; + + // XP seems to set this incorrectly + if ( !glConfig.stencilBits ) { + glConfig.stencilBits = 8; + } + + // the same SetPixelFormat is used either way + if ( SetPixelFormat( win32.hDC, win32.pixelformat, &win32.pfd ) == FALSE ) { + common->Printf( "...^3SetPixelFormat failed^0\n", win32.hDC ); + return false; + } + + // + // startup the OpenGL subsystem by creating a context and making it current + // + common->Printf( "...creating GL context: " ); + if ( ( win32.hGLRC = qwglCreateContext( win32.hDC ) ) == 0 ) { + common->Printf( "^3failed^0\n" ); + return false; + } + common->Printf( "succeeded\n" ); + + common->Printf( "...making context current: " ); + if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) { + qwglDeleteContext( win32.hGLRC ); + win32.hGLRC = NULL; + common->Printf( "^3failed^0\n" ); + return false; + } + common->Printf( "succeeded\n" ); + + return true; +} + +/* +==================== +GLW_CreateWindowClasses +==================== +*/ +static void GLW_CreateWindowClasses( void ) { + WNDCLASS wc; + + // + // register the window class if necessary + // + if ( win32.windowClassRegistered ) { + return; + } + + memset( &wc, 0, sizeof( wc ) ); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = win32.hInstance; + wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1)); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (struct HBRUSH__ *)COLOR_GRAYTEXT; + wc.lpszMenuName = 0; + wc.lpszClassName = WIN32_WINDOW_CLASS_NAME; + + if ( !RegisterClass( &wc ) ) { + common->FatalError( "GLW_CreateWindow: could not register window class" ); + } + common->Printf( "...registered window class\n" ); + + // now register the fake window class that is only used + // to get wgl extensions + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) FakeWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = win32.hInstance; + wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1)); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (struct HBRUSH__ *)COLOR_GRAYTEXT; + wc.lpszMenuName = 0; + wc.lpszClassName = WIN32_FAKE_WINDOW_CLASS_NAME; + + if ( !RegisterClass( &wc ) ) { + common->FatalError( "GLW_CreateWindow: could not register window class" ); + } + common->Printf( "...registered fake window class\n" ); + + win32.windowClassRegistered = true; +} + +/* +======================= +GLW_CreateWindow + +Responsible for creating the Win32 window. +If cdsFullscreen is true, it won't have a border +======================= +*/ +static bool GLW_CreateWindow( glimpParms_t parms ) { + int stylebits; + int x, y, w, h; + int exstyle; + + // + // compute width and height + // + if ( parms.fullScreen ) { + exstyle = WS_EX_TOPMOST; + stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU; + + x = 0; + y = 0; + w = parms.width; + h = parms.height; + } else { + RECT r; + + // adjust width and height for window border + r.bottom = parms.height; + r.left = 0; + r.top = 0; + r.right = parms.width; + + exstyle = 0; + stylebits = WINDOW_STYLE|WS_SYSMENU; + AdjustWindowRect (&r, stylebits, FALSE); + + w = r.right - r.left; + h = r.bottom - r.top; + + x = win32.win_xpos.GetInteger(); + y = win32.win_ypos.GetInteger(); + + // adjust window coordinates if necessary + // so that the window is completely on screen + if ( x + w > win32.desktopWidth ) { + x = ( win32.desktopWidth - w ); + } + if ( y + h > win32.desktopHeight ) { + y = ( win32.desktopHeight - h ); + } + if ( x < 0 ) { + x = 0; + } + if ( y < 0 ) { + y = 0; + } + } + + win32.hWnd = CreateWindowEx ( + exstyle, + WIN32_WINDOW_CLASS_NAME, + GAME_NAME, + stylebits, + x, y, w, h, + NULL, + NULL, + win32.hInstance, + NULL); + + if ( !win32.hWnd ) { + common->Printf( "^3GLW_CreateWindow() - Couldn't create window^0\n" ); + return false; + } + + ::SetTimer( win32.hWnd, 0, 100, NULL ); + + ShowWindow( win32.hWnd, SW_SHOW ); + UpdateWindow( win32.hWnd ); + common->Printf( "...created window @ %d,%d (%dx%d)\n", x, y, w, h ); + + if ( !GLW_InitDriver( parms ) ) { + ShowWindow( win32.hWnd, SW_HIDE ); + DestroyWindow( win32.hWnd ); + win32.hWnd = NULL; + return false; + } + + SetForegroundWindow( win32.hWnd ); + SetFocus( win32.hWnd ); + + glConfig.isFullscreen = parms.fullScreen; + + return true; +} + + + +static void PrintCDSError( int value ) { + switch ( value ) { + case DISP_CHANGE_RESTART: + common->Printf( "restart required\n" ); + break; + case DISP_CHANGE_BADPARAM: + common->Printf( "bad param\n" ); + break; + case DISP_CHANGE_BADFLAGS: + common->Printf( "bad flags\n" ); + break; + case DISP_CHANGE_FAILED: + common->Printf( "DISP_CHANGE_FAILED\n" ); + break; + case DISP_CHANGE_BADMODE: + common->Printf( "bad mode\n" ); + break; + case DISP_CHANGE_NOTUPDATED: + common->Printf( "not updated\n" ); + break; + default: + common->Printf( "unknown error %d\n", value ); + break; + } +} + + +/* +=================== +GLW_SetFullScreen +=================== +*/ +static bool GLW_SetFullScreen( glimpParms_t parms ) { +#if 0 + // for some reason, bounds checker claims that windows is + // writing past the bounds of dm in the get display frequency call + union { + DEVMODE dm; + byte filler[1024]; + } hack; +#endif + DEVMODE dm; + int cdsRet; + + DEVMODE devmode; + int modeNum; + bool matched; + + // first make sure the user is not trying to select a mode that his card/monitor can't handle + matched = false; + for ( modeNum = 0 ; ; modeNum++ ) { + if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) { + if ( matched ) { + // we got a resolution match, but not a frequency match + // so disable the frequency requirement + common->Printf( "...^3%dhz is unsupported at %dx%d^0\n", parms.displayHz, parms.width, parms.height ); + parms.displayHz = 0; + break; + } + common->Printf( "...^3%dx%d is unsupported in 32 bit^0\n", parms.width, parms.height ); + return false; + } + if ( (int)devmode.dmPelsWidth >= parms.width + && (int)devmode.dmPelsHeight >= parms.height + && devmode.dmBitsPerPel == 32 ) { + + matched = true; + + if ( parms.displayHz == 0 || devmode.dmDisplayFrequency == parms.displayHz ) { + break; + } + } + } + + memset( &dm, 0, sizeof( dm ) ); + dm.dmSize = sizeof( dm ); + + dm.dmPelsWidth = parms.width; + dm.dmPelsHeight = parms.height; + dm.dmBitsPerPel = 32; + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + + if ( parms.displayHz != 0 ) { + dm.dmDisplayFrequency = parms.displayHz; + dm.dmFields |= DM_DISPLAYFREQUENCY; + } + + common->Printf( "...calling CDS: " ); + + // try setting the exact mode requested, because some drivers don't report + // the low res modes in EnumDisplaySettings, but still work + if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) { + common->Printf( "ok\n" ); + win32.cdsFullscreen = true; + return true; + } + + // + // the exact mode failed, so scan EnumDisplaySettings for the next largest mode + // + common->Printf( "^3failed^0, " ); + + PrintCDSError( cdsRet ); + + common->Printf( "...trying next higher resolution:" ); + + // we could do a better matching job here... + for ( modeNum = 0 ; ; modeNum++ ) { + if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) { + break; + } + if ( (int)devmode.dmPelsWidth >= parms.width + && (int)devmode.dmPelsHeight >= parms.height + && devmode.dmBitsPerPel == 32 ) { + + if ( ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) { + common->Printf( "ok\n" ); + win32.cdsFullscreen = true; + + return true; + } + break; + } + } + + common->Printf( "\n...^3no high res mode found^0\n" ); + return false; +} + + + +/* +=================== +GLimp_Init + +This is the platform specific OpenGL initialization function. It +is responsible for loading OpenGL, initializing it, +creating a window of the appropriate size, doing +fullscreen manipulations, etc. Its overall responsibility is +to make sure that a functional OpenGL subsystem is operating +when it returns to the ref. + +If there is any failure, the renderer will revert back to safe +parameters and try again. +=================== +*/ +bool GLimp_Init( glimpParms_t parms ) { + const char *driverName; + HDC hDC; + + common->Printf( "Initializing OpenGL subsystem\n" ); + + // check our desktop attributes + hDC = GetDC( GetDesktopWindow() ); + win32.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL ); + win32.desktopWidth = GetDeviceCaps( hDC, HORZRES ); + win32.desktopHeight = GetDeviceCaps( hDC, VERTRES ); + ReleaseDC( GetDesktopWindow(), hDC ); + + // we can't run in a window unless it is 32 bpp + if ( win32.desktopBitsPixel < 32 && !parms.fullScreen ) { + common->Printf("^3Windowed mode requires 32 bit desktop depth^0\n"); + return false; + } + + // save the hardware gamma so it can be + // restored on exit + GLimp_SaveGamma(); + + // create our window classes if we haven't already + GLW_CreateWindowClasses(); + + // this will load the dll and set all our qgl* function pointers, + // but doesn't create a window + + // r_glDriver is only intended for using instrumented OpenGL + // dlls. Normal users should never have to use it, and it is + // not archived. + driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "opengl32"; + if ( !QGL_Init( driverName ) ) { + common->Printf( "^3GLimp_Init() could not load r_glDriver \"%s\"^0\n", driverName ); + return false; + } + + // getting the wgl extensions involves creating a fake window to get a context, + // which is pretty disgusting, and seems to mess with the AGP VAR allocation + GLW_GetWGLExtensionsWithFakeWindow(); + + // try to change to fullscreen + if ( parms.fullScreen ) { + if ( !GLW_SetFullScreen( parms ) ) { + GLimp_Shutdown(); + return false; + } + } + + // try to create a window with the correct pixel format + // and init the renderer context + if ( !GLW_CreateWindow( parms ) ) { + GLimp_Shutdown(); + return false; + } + + // wglSwapinterval, etc + GLW_CheckWGLExtensions( win32.hDC ); + + // check logging + GLimp_EnableLogging( ( r_logFile.GetInteger() != 0 ) ); + + return true; +} + + +/* +=================== +GLimp_SetScreenParms + +Sets up the screen based on passed parms.. +=================== +*/ +bool GLimp_SetScreenParms( glimpParms_t parms ) { + int exstyle; + int stylebits; + int x, y, w, h; + DEVMODE dm; + + memset( &dm, 0, sizeof( dm ) ); + dm.dmSize = sizeof( dm ); + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + if ( parms.displayHz != 0 ) { + dm.dmDisplayFrequency = parms.displayHz; + dm.dmFields |= DM_DISPLAYFREQUENCY; + } + + win32.cdsFullscreen = parms.fullScreen; + glConfig.isFullscreen = parms.fullScreen; + + if ( parms.fullScreen ) { + exstyle = WS_EX_TOPMOST; + stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU; + SetWindowLong( win32.hWnd, GWL_STYLE, stylebits ); + SetWindowLong( win32.hWnd, GWL_EXSTYLE, exstyle ); + dm.dmPelsWidth = parms.width; + dm.dmPelsHeight = parms.height; + dm.dmBitsPerPel = 32; + x = y = w = h = 0; + } else { + RECT r; + + // adjust width and height for window border + r.bottom = parms.height; + r.left = 0; + r.top = 0; + r.right = parms.width; + + w = r.right - r.left; + h = r.bottom - r.top; + + x = win32.win_xpos.GetInteger(); + y = win32.win_ypos.GetInteger(); + + // adjust window coordinates if necessary + // so that the window is completely on screen + if ( x + w > win32.desktopWidth ) { + x = ( win32.desktopWidth - w ); + } + if ( y + h > win32.desktopHeight ) { + y = ( win32.desktopHeight - h ); + } + if ( x < 0 ) { + x = 0; + } + if ( y < 0 ) { + y = 0; + } + dm.dmPelsWidth = win32.desktopWidth; + dm.dmPelsHeight = win32.desktopHeight; + dm.dmBitsPerPel = win32.desktopBitsPixel; + exstyle = 0; + stylebits = WINDOW_STYLE|WS_SYSMENU; + AdjustWindowRect (&r, stylebits, FALSE); + SetWindowLong( win32.hWnd, GWL_STYLE, stylebits ); + SetWindowLong( win32.hWnd, GWL_EXSTYLE, exstyle ); + common->Printf( "%i %i %i %i\n", x, y, w, h ); + } + bool ret = ( ChangeDisplaySettings( &dm, parms.fullScreen ? CDS_FULLSCREEN : 0 ) == DISP_CHANGE_SUCCESSFUL ); + SetWindowPos( win32.hWnd, parms.fullScreen ? HWND_TOPMOST : HWND_NOTOPMOST, x, y, w, h, parms.fullScreen ? SWP_NOSIZE | SWP_NOMOVE : SWP_SHOWWINDOW ); + return ret; +} + +/* +=================== +GLimp_Shutdown + +This routine does all OS specific shutdown procedures for the OpenGL +subsystem. +=================== +*/ +void GLimp_Shutdown( void ) { + const char *success[] = { "failed", "success" }; + int retVal; + + common->Printf( "Shutting down OpenGL subsystem\n" ); + + // set current context to NULL + if ( qwglMakeCurrent ) { + retVal = qwglMakeCurrent( NULL, NULL ) != 0; + common->Printf( "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] ); + } + + // delete HGLRC + if ( win32.hGLRC ) { + retVal = qwglDeleteContext( win32.hGLRC ) != 0; + common->Printf( "...deleting GL context: %s\n", success[retVal] ); + win32.hGLRC = NULL; + } + + // release DC + if ( win32.hDC ) { + retVal = ReleaseDC( win32.hWnd, win32.hDC ) != 0; + common->Printf( "...releasing DC: %s\n", success[retVal] ); + win32.hDC = NULL; + } + + // destroy window + if ( win32.hWnd ) { + common->Printf( "...destroying window\n" ); + ShowWindow( win32.hWnd, SW_HIDE ); + DestroyWindow( win32.hWnd ); + win32.hWnd = NULL; + } + + // reset display settings + if ( win32.cdsFullscreen ) { + common->Printf( "...resetting display\n" ); + ChangeDisplaySettings( 0, 0 ); + win32.cdsFullscreen = false; + } + + // close the thread so the handle doesn't dangle + if ( win32.renderThreadHandle ) { + common->Printf( "...closing smp thread\n" ); + CloseHandle( win32.renderThreadHandle ); + win32.renderThreadHandle = NULL; + } + + // restore gamma + GLimp_RestoreGamma(); + + // shutdown QGL subsystem + QGL_Shutdown(); +} + + +/* +===================== +GLimp_SwapBuffers +===================== +*/ +void GLimp_SwapBuffers( void ) { + // + // wglSwapinterval is a windows-private extension, + // so we must check for it here instead of portably + // + if ( r_swapInterval.IsModified() ) { + r_swapInterval.ClearModified(); + + if ( wglSwapIntervalEXT ) { + wglSwapIntervalEXT( r_swapInterval.GetInteger() ); + } + } + + qwglSwapBuffers( win32.hDC ); + +//Sys_DebugPrintf( "*** SwapBuffers() ***\n" ); +} + +/* +=========================================================== + +SMP acceleration + +=========================================================== +*/ + +//#define REALLOC_DC + +/* +=================== +GLimp_ActivateContext + +=================== +*/ +void GLimp_ActivateContext( void ) { + if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) { + win32.wglErrors++; + } +} + +/* +=================== +GLimp_DeactivateContext + +=================== +*/ +void GLimp_DeactivateContext( void ) { + qglFinish(); + if ( !qwglMakeCurrent( win32.hDC, NULL ) ) { + win32.wglErrors++; + } +#ifdef REALLOC_DC + // makeCurrent NULL frees the DC, so get another + if ( ( win32.hDC = GetDC( win32.hWnd ) ) == NULL ) { + win32.wglErrors++; + } +#endif + +} + +/* +=================== +GLimp_RenderThreadWrapper + +=================== +*/ +static void GLimp_RenderThreadWrapper( void ) { + win32.glimpRenderThread(); + + // unbind the context before we die + qwglMakeCurrent( win32.hDC, NULL ); +} + +/* +======================= +GLimp_SpawnRenderThread + +Returns false if the system only has a single processor +======================= +*/ +bool GLimp_SpawnRenderThread( void (*function)( void ) ) { + SYSTEM_INFO info; + + // check number of processors + GetSystemInfo( &info ); + if ( info.dwNumberOfProcessors < 2 ) { + return false; + } + + // create the IPC elements + win32.renderCommandsEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + win32.renderCompletedEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + win32.renderActiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + + win32.glimpRenderThread = function; + + win32.renderThreadHandle = CreateThread( + NULL, // LPSECURITY_ATTRIBUTES lpsa, + 0, // DWORD cbStack, + (LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper, // LPTHREAD_START_ROUTINE lpStartAddr, + 0, // LPVOID lpvThreadParm, + 0, // DWORD fdwCreate, + &win32.renderThreadId ); + + if ( !win32.renderThreadHandle ) { + common->Error( "GLimp_SpawnRenderThread: failed" ); + } + + SetThreadPriority( win32.renderThreadHandle, THREAD_PRIORITY_ABOVE_NORMAL ); +#if 0 + // make sure they always run on different processors + SetThreadAffinityMask( GetCurrentThread, 1 ); + SetThreadAffinityMask( win32.renderThreadHandle, 2 ); +#endif + + return true; +} + + +//#define DEBUG_PRINTS + +/* +=================== +GLimp_BackEndSleep + +=================== +*/ +void *GLimp_BackEndSleep( void ) { + void *data; + +#ifdef DEBUG_PRINTS +OutputDebugString( "-->GLimp_BackEndSleep\n" ); +#endif + ResetEvent( win32.renderActiveEvent ); + + // after this, the front end can exit GLimp_FrontEndSleep + SetEvent( win32.renderCompletedEvent ); + + WaitForSingleObject( win32.renderCommandsEvent, INFINITE ); + + ResetEvent( win32.renderCompletedEvent ); + ResetEvent( win32.renderCommandsEvent ); + + data = win32.smpData; + + // after this, the main thread can exit GLimp_WakeRenderer + SetEvent( win32.renderActiveEvent ); + +#ifdef DEBUG_PRINTS +OutputDebugString( "<--GLimp_BackEndSleep\n" ); +#endif + return data; +} + +/* +=================== +GLimp_FrontEndSleep + +=================== +*/ +void GLimp_FrontEndSleep( void ) { +#ifdef DEBUG_PRINTS +OutputDebugString( "-->GLimp_FrontEndSleep\n" ); +#endif + WaitForSingleObject( win32.renderCompletedEvent, INFINITE ); + +#ifdef DEBUG_PRINTS +OutputDebugString( "<--GLimp_FrontEndSleep\n" ); +#endif +} + +volatile bool renderThreadActive; + +/* +=================== +GLimp_WakeBackEnd + +=================== +*/ +void GLimp_WakeBackEnd( void *data ) { + int r; + +#ifdef DEBUG_PRINTS +OutputDebugString( "-->GLimp_WakeBackEnd\n" ); +#endif + win32.smpData = data; + + if ( renderThreadActive ) { + common->FatalError( "GLimp_WakeBackEnd: already active" ); + } + + r = WaitForSingleObject( win32.renderActiveEvent, 0 ); + if ( r == WAIT_OBJECT_0 ) { + common->FatalError( "GLimp_WakeBackEnd: already signaled" ); + } + + r = WaitForSingleObject( win32.renderCommandsEvent, 0 ); + if ( r == WAIT_OBJECT_0 ) { + common->FatalError( "GLimp_WakeBackEnd: commands already signaled" ); + } + + // after this, the renderer can continue through GLimp_RendererSleep + SetEvent( win32.renderCommandsEvent ); + + r = WaitForSingleObject( win32.renderActiveEvent, 5000 ); + + if ( r == WAIT_TIMEOUT ) { + common->FatalError( "GLimp_WakeBackEnd: WAIT_TIMEOUT" ); + } + +#ifdef DEBUG_PRINTS +OutputDebugString( "<--GLimp_WakeBackEnd\n" ); +#endif +} + +//=================================================================== + +/* +=================== +GLimp_ExtensionPointer + +Returns a function pointer for an OpenGL extension entry point +=================== +*/ +GLExtension_t GLimp_ExtensionPointer( const char *name ) { + void (*proc)(void); + + proc = (GLExtension_t)qwglGetProcAddress( name ); + + if ( !proc ) { + common->Printf( "Couldn't find proc address for: %s\n", name ); + } + + return proc; +} + diff --git a/sys/win32/win_input.cpp b/sys/win32/win_input.cpp new file mode 100644 index 000000000..a0baae497 --- /dev/null +++ b/sys/win32/win_input.cpp @@ -0,0 +1,1038 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "win_local.h" + + +#define DINPUT_BUFFERSIZE 256 + +#define CHAR_FIRSTREPEAT 200 +#define CHAR_REPEAT 100 + +typedef struct MYDATA { + LONG lX; // X axis goes here + LONG lY; // Y axis goes here + LONG lZ; // Z axis goes here + BYTE bButtonA; // One button goes here + BYTE bButtonB; // Another button goes here + BYTE bButtonC; // Another button goes here + BYTE bButtonD; // Another button goes here +} MYDATA; + +static DIOBJECTDATAFORMAT rgodf[] = { + { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +}; + +//========================================================================== + +static const unsigned char s_scantokey[256] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', K_SHIFT, '\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 7 +// shifted + 0, 27, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '~', K_SHIFT, '\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +static const unsigned char s_scantokey_german[256] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '?', '\'', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', + 'o', 'p', '=', '+', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', + ']', '`', K_SHIFT, '#', 'y', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 7 +// shifted + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '?', '\'', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', + 'o', 'p', '=', '+', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', + ']', '`', K_SHIFT, '#', 'y', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +static const unsigned char s_scantokey_french[256] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', ')', '=', K_BACKSPACE, 9, // 0 + 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '^', '$', K_ENTER,K_CTRL, 'q', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', + 'ù', '`', K_SHIFT, '*', 'w', 'x', 'c', 'v', // 2 + 'b', 'n', ',', ';', ':', '!', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 7 +// shifted + 0, 27, '&', 'é', '\"', '\'', '(', '-', + 'è', '_', 'ç', 'à', '°', '+', K_BACKSPACE, 9, // 0 + 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '^', '$', K_ENTER,K_CTRL, 'q', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', + 'ù', 0, K_SHIFT, '*', 'w', 'x', 'c', 'v', // 2 + 'b', 'n', ',', ';', ':', '!', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +static const unsigned char s_scantokey_spanish[256] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '\'', '¡', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '`', '+', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ñ', + '´', 'º', K_SHIFT, 'ç', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 7 +// shifted + 0, 27, '!', '\"', '·', '$', '%', '&', + '/', '(', ')', '=', '?', '¿', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '^', '*', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'Ñ', + '¨', 'ª', K_SHIFT, 'Ç', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +static const unsigned char s_scantokey_italian[256] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '\'', 'ì', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', 'è', '+', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ò', + 'à', '\\', K_SHIFT, 'ù', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 7 +// shifted + 0, 27, '!', '\"', '£', '$', '%', '&', + '/', '(', ')', '=', '?', '^', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', 'é', '*', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ç', + '°', '|', K_SHIFT, '§', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '-', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, '<', K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 + + +}; + +static const unsigned char *keyScanTable = s_scantokey; + +// this should be part of the scantables and the scan tables should be 512 bytes +// (256 scan codes, shifted and unshifted). Changing everything to use 512 byte +// scan tables now might introduce bugs in tested code. Since we only need to fix +// the right-alt case for non-US keyboards, we're just using a special-case table +// for it. Eventually, the tables above should be fixed to handle all possible +// scan codes instead of just the first 128. +static unsigned char rightAltKey = K_ALT; + +#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0])) + +static DIDATAFORMAT df = { + sizeof(DIDATAFORMAT), // this structure + sizeof(DIOBJECTDATAFORMAT), // size of object data format + DIDF_RELAXIS, // absolute axis coordinates + sizeof(MYDATA), // device data size + NUM_OBJECTS, // number of objects + rgodf, // and here they are +}; + +/* +============================================================ + +DIRECT INPUT KEYBOARD CONTROL + +============================================================ +*/ + +bool IN_StartupKeyboard( void ) { + HRESULT hr; + bool bExclusive; + bool bForeground; + bool bImmediate; + bool bDisableWindowsKey; + DWORD dwCoopFlags; + + if (!win32.g_pdi) { + common->Printf("keyboard: DirectInput has not been started\n"); + return false; + } + + if (win32.g_pKeyboard) { + win32.g_pKeyboard->Release(); + win32.g_pKeyboard = NULL; + } + + // Detrimine where the buffer would like to be allocated + bExclusive = false; + bForeground = true; + bImmediate = false; + bDisableWindowsKey = true; + + if( bExclusive ) + dwCoopFlags = DISCL_EXCLUSIVE; + else + dwCoopFlags = DISCL_NONEXCLUSIVE; + + if( bForeground ) + dwCoopFlags |= DISCL_FOREGROUND; + else + dwCoopFlags |= DISCL_BACKGROUND; + + // Disabling the windows key is only allowed only if we are in foreground nonexclusive + if( bDisableWindowsKey && !bExclusive && bForeground ) + dwCoopFlags |= DISCL_NOWINKEY; + + // Obtain an interface to the system keyboard device. + if( FAILED( hr = win32.g_pdi->CreateDevice( GUID_SysKeyboard, &win32.g_pKeyboard, NULL ) ) ) { + common->Printf("keyboard: couldn't find a keyboard device\n"); + return false; + } + + // Set the data format to "keyboard format" - a predefined data format + // + // A data format specifies which controls on a device we + // are interested in, and how they should be reported. + // + // This tells DirectInput that we will be passing an array + // of 256 bytes to IDirectInputDevice::GetDeviceState. + if( FAILED( hr = win32.g_pKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) ) + return false; + + // Set the cooperativity level to let DirectInput know how + // this device should interact with the system and with other + // DirectInput applications. + hr = win32.g_pKeyboard->SetCooperativeLevel( win32.hWnd, dwCoopFlags ); + if( hr == DIERR_UNSUPPORTED && !bForeground && bExclusive ) { + common->Printf("keyboard: SetCooperativeLevel() returned DIERR_UNSUPPORTED.\nFor security reasons, background exclusive keyboard access is not allowed.\n"); + return false; + } + + if( FAILED(hr) ) { + return false; + } + + if( !bImmediate ) { + // IMPORTANT STEP TO USE BUFFERED DEVICE DATA! + // + // DirectInput uses unbuffered I/O (buffer size = 0) by default. + // If you want to read buffered data, you need to set a nonzero + // buffer size. + // + // Set the buffer size to DINPUT_BUFFERSIZE (defined above) elements. + // + // The buffer size is a DWORD property associated with the device. + DIPROPDWORD dipdw; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DINPUT_BUFFERSIZE; // Arbitary buffer size + + if( FAILED( hr = win32.g_pKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) ) + return false; + } + + // Acquire the newly created device + win32.g_pKeyboard->Acquire(); + + common->Printf( "keyboard: DirectInput initialized.\n"); + return true; +} + +/* +======= +MapKey + +Map from windows to quake keynums + +FIXME: scan code tables should include the upper 128 scan codes instead + of having to special-case them here. The current code makes it difficult + to special-case conversions for non-US keyboards. Currently the only + special-case is for right alt. +======= +*/ +int IN_DIMapKey (int key) { + if ( key>=128 ) { + switch ( key ) { + case DIK_HOME: + return K_HOME; + case DIK_UPARROW: + return K_UPARROW; + case DIK_PGUP: + return K_PGUP; + case DIK_LEFTARROW: + return K_LEFTARROW; + case DIK_RIGHTARROW: + return K_RIGHTARROW; + case DIK_END: + return K_END; + case DIK_DOWNARROW: + return K_DOWNARROW; + case DIK_PGDN: + return K_PGDN; + case DIK_INSERT: + return K_INS; + case DIK_DELETE: + return K_DEL; + case DIK_RMENU: + return rightAltKey; + case DIK_RCONTROL: + return K_CTRL; + case DIK_NUMPADENTER: + return K_KP_ENTER; + case DIK_NUMPADEQUALS: + return K_KP_EQUALS; + case DIK_PAUSE: + return K_PAUSE; + case DIK_DIVIDE: + return K_KP_SLASH; + case DIK_LWIN: + return K_LWIN; + case DIK_RWIN: + return K_RWIN; + case DIK_APPS: + return K_MENU; + case DIK_SYSRQ: + return K_PRINT_SCR; + default: + return 0; + } + } else { + switch (key) { + case DIK_NUMPAD7: + return K_KP_HOME; + case DIK_NUMPAD8: + return K_KP_UPARROW; + case DIK_NUMPAD9: + return K_KP_PGUP; + case DIK_NUMPAD4: + return K_KP_LEFTARROW; + case DIK_NUMPAD5: + return K_KP_5; + case DIK_NUMPAD6: + return K_KP_RIGHTARROW; + case DIK_NUMPAD1: + return K_KP_END; + case DIK_NUMPAD2: + return K_KP_DOWNARROW; + case DIK_NUMPAD3: + return K_KP_PGDN; + case DIK_NUMPAD0: + return K_KP_INS; + case DIK_DECIMAL: + return K_KP_DEL; + case DIK_SUBTRACT: + return K_KP_MINUS; + case DIK_ADD: + return K_KP_PLUS; + case DIK_NUMLOCK: + return K_KP_NUMLOCK; + case DIK_MULTIPLY: + return K_KP_STAR; + default: + return keyScanTable[key]; + } + } +} + + +/* +========================== +IN_DeactivateKeyboard +========================== +*/ +void IN_DeactivateKeyboard( void ) { + if (!win32.g_pKeyboard) { + return; + } + win32.g_pKeyboard->Unacquire( ); +} + +/* +============================================================ + +DIRECT INPUT MOUSE CONTROL + +============================================================ +*/ + +/* +======================== +IN_InitDirectInput +======================== +*/ + +void IN_InitDirectInput( void ) { + HRESULT hr; + + common->Printf( "Initializing DirectInput...\n" ); + + if ( win32.g_pdi != NULL ) { + win32.g_pdi->Release(); // if the previous window was destroyed we need to do this + win32.g_pdi = NULL; + } + + // Register with the DirectInput subsystem and get a pointer + // to a IDirectInput interface we can use. + // Create the base DirectInput object + if ( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&win32.g_pdi, NULL ) ) ) { + common->Printf ("DirectInputCreate failed\n"); + } +} + +/* +======================== +IN_InitDIMouse +======================== +*/ +bool IN_InitDIMouse( void ) { + HRESULT hr; + + if ( win32.g_pdi == NULL) { + return false; + } + + // obtain an interface to the system mouse device. + hr = win32.g_pdi->CreateDevice( GUID_SysMouse, &win32.g_pMouse, NULL); + + if (FAILED(hr)) { + common->Printf ("mouse: Couldn't open DI mouse device\n"); + return false; + } + + // Set the data format to "mouse format" - a predefined data format + // + // A data format specifies which controls on a device we + // are interested in, and how they should be reported. + // + // This tells DirectInput that we will be passing a + // DIMOUSESTATE2 structure to IDirectInputDevice::GetDeviceState. + if( FAILED( hr = win32.g_pMouse->SetDataFormat( &c_dfDIMouse2 ) ) ) { + common->Printf ("mouse: Couldn't set DI mouse format\n"); + return false; + } + + // set the cooperativity level. + hr = win32.g_pMouse->SetCooperativeLevel( win32.hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); + + if (FAILED(hr)) { + common->Printf ("mouse: Couldn't set DI coop level\n"); + return false; + } + + + // IMPORTANT STEP TO USE BUFFERED DEVICE DATA! + // + // DirectInput uses unbuffered I/O (buffer size = 0) by default. + // If you want to read buffered data, you need to set a nonzero + // buffer size. + // + // Set the buffer size to SAMPLE_BUFFER_SIZE (defined above) elements. + // + // The buffer size is a DWORD property associated with the device. + DIPROPDWORD dipdw; + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DINPUT_BUFFERSIZE; // Arbitary buffer size + + if( FAILED( hr = win32.g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) ) { + common->Printf ("mouse: Couldn't set DI buffersize\n"); + return false; + } + + IN_ActivateMouse(); + + // clear any pending samples + Sys_PollMouseInputEvents(); + + common->Printf( "mouse: DirectInput initialized.\n"); + return true; +} + + +/* +========================== +IN_ActivateMouse +========================== +*/ +void IN_ActivateMouse( void ) { + int i; + HRESULT hr; + + if ( !win32.in_mouse.GetBool() || win32.mouseGrabbed || !win32.g_pMouse ) { + return; + } + + win32.mouseGrabbed = true; + for ( i = 0; i < 10; i++ ) { + if ( ::ShowCursor( false ) < 0 ) { + break; + } + } + + // we may fail to reacquire if the window has been recreated + hr = win32.g_pMouse->Acquire(); + if (FAILED(hr)) { + return; + } + + // set the cooperativity level. + hr = win32.g_pMouse->SetCooperativeLevel( win32.hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); +} + +/* +========================== +IN_DeactivateMouse +========================== +*/ +void IN_DeactivateMouse( void ) { + int i; + + if (!win32.g_pMouse || !win32.mouseGrabbed ) { + return; + } + + win32.g_pMouse->Unacquire(); + + for ( i = 0; i < 10; i++ ) { + if ( ::ShowCursor( true ) >= 0 ) { + break; + } + } + win32.mouseGrabbed = false; +} + +/* +========================== +IN_DeactivateMouseIfWindowed +========================== +*/ +void IN_DeactivateMouseIfWindowed( void ) { + if ( !win32.cdsFullscreen ) { + IN_DeactivateMouse(); + } +} + +/* +============================================================ + + MOUSE CONTROL + +============================================================ +*/ + + +/* +=========== +Sys_ShutdownInput +=========== +*/ +void Sys_ShutdownInput( void ) { + IN_DeactivateMouse(); + IN_DeactivateKeyboard(); + if ( win32.g_pKeyboard ) { + win32.g_pKeyboard->Release(); + win32.g_pKeyboard = NULL; + } + + if ( win32.g_pMouse ) { + win32.g_pMouse->Release(); + win32.g_pMouse = NULL; + } + + if ( win32.g_pdi ) { + win32.g_pdi->Release(); + win32.g_pdi = NULL; + } +} + +/* +=========== +Sys_InitInput +=========== +*/ +void Sys_InitInput( void ) { + common->Printf ("\n------- Input Initialization -------\n"); + IN_InitDirectInput(); + if ( win32.in_mouse.GetBool() ) { + IN_InitDIMouse(); + // don't grab the mouse on initialization + Sys_GrabMouseCursor( false ); + } else { + common->Printf ("Mouse control not active.\n"); + } + IN_StartupKeyboard(); + common->Printf ("------------------------------------\n"); + win32.in_mouse.ClearModified(); +} + +/* +=========== +Sys_InitScanTable +=========== +*/ +void Sys_InitScanTable( void ) { + idStr lang = cvarSystem->GetCVarString( "sys_lang" ); + if ( lang.Length() == 0 ) { + lang = "english"; + } + if ( lang.Icmp( "english" ) == 0 ) { + keyScanTable = s_scantokey; + // the only reason that english right alt binds as K_ALT is so that + // users who were using right-alt before the patch don't suddenly find + // that only left-alt is working. + rightAltKey = K_ALT; + } else if ( lang.Icmp( "spanish" ) == 0 ) { + keyScanTable = s_scantokey_spanish; + rightAltKey = K_RIGHT_ALT; + } else if ( lang.Icmp( "french" ) == 0 ) { + keyScanTable = s_scantokey_french; + rightAltKey = K_RIGHT_ALT; + } else if ( lang.Icmp( "german" ) == 0 ) { + keyScanTable = s_scantokey_german; + rightAltKey = K_RIGHT_ALT; + } else if ( lang.Icmp( "italian" ) == 0 ) { + keyScanTable = s_scantokey_italian; + rightAltKey = K_RIGHT_ALT; + } +} + +/* +================== +Sys_GetScanTable +================== +*/ +const unsigned char *Sys_GetScanTable( void ) { + return keyScanTable; +} + +/* +=============== +Sys_GetConsoleKey +=============== +*/ +unsigned char Sys_GetConsoleKey( bool shifted ) { + return keyScanTable[41 + ( shifted ? 128 : 0 )]; +} + +/* +================== +IN_Frame + +Called every frame, even if not generating commands +================== +*/ +void IN_Frame( void ) { + bool shouldGrab = true; + + if ( !win32.in_mouse.GetBool() ) { + shouldGrab = false; + } + // if fullscreen, we always want the mouse + if ( !win32.cdsFullscreen ) { + if ( win32.mouseReleased ) { + shouldGrab = false; + } + if ( win32.movingWindow ) { + shouldGrab = false; + } + if ( !win32.activeApp ) { + shouldGrab = false; + } + } + + if ( shouldGrab != win32.mouseGrabbed ) { + if ( win32.mouseGrabbed ) { + IN_DeactivateMouse(); + } else { + IN_ActivateMouse(); + +#if 0 // if we can't reacquire, try reinitializing + if ( !IN_InitDIMouse() ) { + win32.in_mouse.SetBool( false ); + return; + } +#endif + } + } +} + + +void Sys_GrabMouseCursor( bool grabIt ) { +#ifndef ID_DEDICATED + win32.mouseReleased = !grabIt; + if ( !grabIt ) { + // release it right now + IN_Frame(); + } +#endif +} + +//===================================================================================== + +static DIDEVICEOBJECTDATA polled_didod[ DINPUT_BUFFERSIZE ]; // Receives buffered data + +static int diFetch; +static byte toggleFetch[2][ 256 ]; + + +#if 1 +// I tried doing the full-state get to address a keyboard problem on one system, +// but it didn't make any difference + +/* +==================== +Sys_PollKeyboardInputEvents +==================== +*/ +int Sys_PollKeyboardInputEvents( void ) { + DWORD dwElements; + HRESULT hr; + + if( win32.g_pKeyboard == NULL ) { + return 0; + } + + dwElements = DINPUT_BUFFERSIZE; + hr = win32.g_pKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), + polled_didod, &dwElements, 0 ); + if( hr != DI_OK ) + { + // We got an error or we got DI_BUFFEROVERFLOW. + // + // Either way, it means that continuous contact with the + // device has been lost, either due to an external + // interruption, or because the buffer overflowed + // and some events were lost. + hr = win32.g_pKeyboard->Acquire(); + + + + // nuke the garbage + if (!FAILED(hr)) { + //Bug 951: The following command really clears the garbage input. + //The original will still process keys in the buffer and was causing + //some problems. + win32.g_pKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), NULL, &dwElements, 0 ); + dwElements = 0; + } + // hr may be DIERR_OTHERAPPHASPRIO or other errors. This + // may occur when the app is minimized or in the process of + // switching, so just try again later + } + + if( FAILED(hr) ) { + return 0; + } + + return dwElements; +} + +#else + +/* +==================== +Sys_PollKeyboardInputEvents + +Fake events by getting the entire device state +and checking transitions +==================== +*/ +int Sys_PollKeyboardInputEvents( void ) { + HRESULT hr; + + if( win32.g_pKeyboard == NULL ) { + return 0; + } + + hr = win32.g_pKeyboard->GetDeviceState( sizeof( toggleFetch[ diFetch ] ), toggleFetch[ diFetch ] ); + if( hr != DI_OK ) + { + // We got an error or we got DI_BUFFEROVERFLOW. + // + // Either way, it means that continuous contact with the + // device has been lost, either due to an external + // interruption, or because the buffer overflowed + // and some events were lost. + hr = win32.g_pKeyboard->Acquire(); + + // nuke the garbage + if (!FAILED(hr)) { + hr = win32.g_pKeyboard->GetDeviceState( sizeof( toggleFetch[ diFetch ] ), toggleFetch[ diFetch ] ); + } + // hr may be DIERR_OTHERAPPHASPRIO or other errors. This + // may occur when the app is minimized or in the process of + // switching, so just try again later + } + + if( FAILED(hr) ) { + return 0; + } + + // build faked events + int numChanges = 0; + + for ( int i = 0 ; i < 256 ; i++ ) { + if ( toggleFetch[0][i] != toggleFetch[1][i] ) { + polled_didod[ numChanges ].dwOfs = i; + polled_didod[ numChanges ].dwData = toggleFetch[ diFetch ][i] ? 0x80 : 0; + numChanges++; + } + } + + diFetch ^= 1; + + return numChanges; +} + +#endif + +/* +==================== +Sys_PollKeyboardInputEvents +==================== +*/ +int Sys_ReturnKeyboardInputEvent( const int n, int &ch, bool &state ) { + ch = IN_DIMapKey( polled_didod[ n ].dwOfs ); + state = (polled_didod[ n ].dwData & 0x80) == 0x80; + if ( ch == K_PRINT_SCR || ch == K_CTRL || ch == K_ALT || ch == K_RIGHT_ALT ) { + // for windows, add a keydown event for print screen here, since + // windows doesn't send keydown events to the WndProc for this key. + // ctrl and alt are handled here to get around windows sending ctrl and + // alt messages when the right-alt is pressed on non-US 102 keyboards. + Sys_QueEvent( GetTickCount(), SE_KEY, ch, state, 0, NULL ); + } + return ch; +} + + +void Sys_EndKeyboardInputEvents( void ) { +} + +void Sys_QueMouseEvents( int dwElements ) { + int i, value; + + for( i = 0; i < dwElements; i++ ) { + if ( polled_didod[i].dwOfs >= DIMOFS_BUTTON0 && polled_didod[i].dwOfs <= DIMOFS_BUTTON7 ) { + value = (polled_didod[i].dwData & 0x80) == 0x80; + Sys_QueEvent( polled_didod[i].dwTimeStamp, SE_KEY, K_MOUSE1 + ( polled_didod[i].dwOfs - DIMOFS_BUTTON0 ), value, 0, NULL ); + } else { + switch (polled_didod[i].dwOfs) { + case DIMOFS_X: + value = polled_didod[i].dwData; + Sys_QueEvent( polled_didod[i].dwTimeStamp, SE_MOUSE, value, 0, 0, NULL ); + break; + case DIMOFS_Y: + value = polled_didod[i].dwData; + Sys_QueEvent( polled_didod[i].dwTimeStamp, SE_MOUSE, 0, value, 0, NULL ); + break; + case DIMOFS_Z: + value = ( (int) polled_didod[i].dwData ) / WHEEL_DELTA; + int key = value < 0 ? K_MWHEELDOWN : K_MWHEELUP; + value = abs( value ); + while( value-- > 0 ) { + Sys_QueEvent( polled_didod[i].dwTimeStamp, SE_KEY, key, true, 0, NULL ); + Sys_QueEvent( polled_didod[i].dwTimeStamp, SE_KEY, key, false, 0, NULL ); + } + break; + } + } + } +} + +//===================================================================================== + +int Sys_PollMouseInputEvents( void ) { + DWORD dwElements; + HRESULT hr; + + if ( !win32.g_pMouse || !win32.mouseGrabbed ) { + return 0; + } + + dwElements = DINPUT_BUFFERSIZE; + hr = win32.g_pMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), polled_didod, &dwElements, 0 ); + + if( hr != DI_OK ) { + hr = win32.g_pMouse->Acquire(); + // clear the garbage + if (!FAILED(hr)) { + win32.g_pMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), polled_didod, &dwElements, 0 ); + } + } + + if( FAILED(hr) ) { + return 0; + } + + Sys_QueMouseEvents( dwElements ); + + return dwElements; +} + +int Sys_ReturnMouseInputEvent( const int n, int &action, int &value ) { + int diaction = polled_didod[n].dwOfs; + + if ( diaction >= DIMOFS_BUTTON0 && diaction <= DIMOFS_BUTTON7 ) { + value = (polled_didod[n].dwData & 0x80) == 0x80; + action = M_ACTION1 + ( diaction - DIMOFS_BUTTON0 ); + return 1; + } + + switch( diaction ) { + case DIMOFS_X: + value = polled_didod[n].dwData; + action = M_DELTAX; + return 1; + case DIMOFS_Y: + value = polled_didod[n].dwData; + action = M_DELTAY; + return 1; + case DIMOFS_Z: + // mouse wheel actions are impulses, without a specific up / down + value = ( (int) polled_didod[n].dwData ) / WHEEL_DELTA; + action = M_DELTAZ; + // a value of zero here should never happen + if ( value == 0 ) { + return 0; + } + return 1; + } + return 0; +} + +void Sys_EndMouseInputEvents( void ) { } + +unsigned char Sys_MapCharForKey( int key ) { + return (unsigned char)key; +} diff --git a/sys/win32/win_local.h b/sys/win32/win_local.h new file mode 100644 index 000000000..7049a04ea --- /dev/null +++ b/sys/win32/win_local.h @@ -0,0 +1,166 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __WIN_LOCAL_H__ +#define __WIN_LOCAL_H__ + +#include +#include "../../renderer/wglext.h" // windows OpenGL extensions + +// WGL_ARB_extensions_string +extern PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; + +// WGL_EXT_swap_interval +extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + +// WGL_ARB_pixel_format +extern PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB; +extern PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB; +extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; + +// WGL_ARB_pbuffer +extern PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB; +extern PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB; +extern PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB; +extern PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB; +extern PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB; + +// WGL_ARB_render_texture +extern PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB; +extern PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB; +extern PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB; + + +#define MAX_OSPATH 256 + +#define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE | WS_THICKFRAME) + +void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ); + +void Sys_CreateConsole( void ); +void Sys_DestroyConsole( void ); + +char *Sys_ConsoleInput (void); +char *Sys_GetCurrentUser( void ); + +void Win_SetErrorText( const char *text ); + +cpuid_t Sys_GetCPUId( void ); + +int MapKey (int key); + + +// Input subsystem + +void IN_Init (void); +void IN_Shutdown (void); +// add additional non keyboard / non mouse movement on top of the keyboard move cmd + +void IN_DeactivateMouseIfWindowed( void ); +void IN_DeactivateMouse( void ); +void IN_ActivateMouse( void ); + +void IN_Frame( void ); + +int IN_DIMapKey( int key ); + +void DisableTaskKeys( BOOL bDisable, BOOL bBeep, BOOL bTaskMgr ); + + +// window procedure +LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +void Conbuf_AppendText( const char *msg ); + +typedef struct { + HWND hWnd; + HINSTANCE hInstance; + + bool activeApp; // changed with WM_ACTIVATE messages + bool mouseReleased; // when the game has the console down or is doing a long operation + bool movingWindow; // inhibit mouse grab when dragging the window + bool mouseGrabbed; // current state of grab and hide + + OSVERSIONINFOEX osversion; + + cpuid_t cpuid; + + // when we get a windows message, we store the time off so keyboard processing + // can know the exact time of an event (not really needed now that we use async direct input) + int sysMsgTime; + + bool windowClassRegistered; + + WNDPROC wndproc; + + HDC hDC; // handle to device context + HGLRC hGLRC; // handle to GL rendering context + PIXELFORMATDESCRIPTOR pfd; + int pixelformat; + + HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library + + int desktopBitsPixel; + int desktopWidth, desktopHeight; + + bool cdsFullscreen; + + FILE *log_fp; + + unsigned short oldHardwareGamma[3][256]; + // desktop gamma is saved here for restoration at exit + + static idCVar sys_arch; + static idCVar sys_cpustring; + static idCVar in_mouse; + static idCVar win_allowAltTab; + static idCVar win_notaskkeys; + static idCVar win_username; + static idCVar win_xpos; // archived X coordinate of window position + static idCVar win_ypos; // archived Y coordinate of window position + static idCVar win_outputDebugString; + static idCVar win_outputEditString; + static idCVar win_viewlog; + static idCVar win_timerUpdate; + static idCVar win_allowMultipleInstances; + + CRITICAL_SECTION criticalSections[MAX_CRITICAL_SECTIONS]; + HANDLE backgroundDownloadSemaphore; + + HINSTANCE hInstDI; // direct input + + LPDIRECTINPUT8 g_pdi; + LPDIRECTINPUTDEVICE8 g_pMouse; + LPDIRECTINPUTDEVICE8 g_pKeyboard; + + HANDLE renderCommandsEvent; + HANDLE renderCompletedEvent; + HANDLE renderActiveEvent; + HANDLE renderThreadHandle; + unsigned long renderThreadId; + void (*glimpRenderThread)( void ); + void *smpData; + int wglErrors; + // SMP acceleration vars + +} Win32Vars_t; + +extern Win32Vars_t win32; + +#endif /* !__WIN_LOCAL_H__ */ diff --git a/sys/win32/win_main.cpp b/sys/win32/win_main.cpp new file mode 100644 index 000000000..de1281833 --- /dev/null +++ b/sys/win32/win_main.cpp @@ -0,0 +1,1606 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __MRC__ +#include +#include +#endif + +#include "../sys_local.h" +#include "win_local.h" +#include "rc/CreateResourceIDs.h" +#include "../../renderer/tr_local.h" + +idCVar Win32Vars_t::sys_arch( "sys_arch", "", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar Win32Vars_t::sys_cpustring( "sys_cpustring", "detect", CVAR_SYSTEM | CVAR_INIT, "" ); +idCVar Win32Vars_t::in_mouse( "in_mouse", "1", CVAR_SYSTEM | CVAR_BOOL, "enable mouse input" ); +idCVar Win32Vars_t::win_allowAltTab( "win_allowAltTab", "0", CVAR_SYSTEM | CVAR_BOOL, "allow Alt-Tab when fullscreen" ); +idCVar Win32Vars_t::win_notaskkeys( "win_notaskkeys", "0", CVAR_SYSTEM | CVAR_INTEGER, "disable windows task keys" ); +idCVar Win32Vars_t::win_username( "win_username", "", CVAR_SYSTEM | CVAR_INIT, "windows user name" ); +idCVar Win32Vars_t::win_xpos( "win_xpos", "3", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "horizontal position of window" ); +idCVar Win32Vars_t::win_ypos( "win_ypos", "22", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "vertical position of window" ); +idCVar Win32Vars_t::win_outputDebugString( "win_outputDebugString", "0", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar Win32Vars_t::win_outputEditString( "win_outputEditString", "1", CVAR_SYSTEM | CVAR_BOOL, "" ); +idCVar Win32Vars_t::win_viewlog( "win_viewlog", "0", CVAR_SYSTEM | CVAR_INTEGER, "" ); +idCVar Win32Vars_t::win_timerUpdate( "win_timerUpdate", "0", CVAR_SYSTEM | CVAR_BOOL, "allows the game to be updated while dragging the window" ); +idCVar Win32Vars_t::win_allowMultipleInstances( "win_allowMultipleInstances", "0", CVAR_SYSTEM | CVAR_BOOL, "allow multiple instances running concurrently" ); + +Win32Vars_t win32; + +static char sys_cmdline[MAX_STRING_CHARS]; + +// not a hard limit, just what we keep track of for debugging +xthreadInfo *g_threads[MAX_THREADS]; + +int g_thread_count = 0; + +static sysMemoryStats_t exeLaunchMemoryStats; + +static xthreadInfo threadInfo; +static HANDLE hTimer; + +/* +================ +Sys_GetExeLaunchMemoryStatus +================ +*/ +void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t &stats ) { + stats = exeLaunchMemoryStats; +} + +/* +================== +Sys_Createthread +================== +*/ +void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo &info, const char *name, xthreadInfo *threads[MAX_THREADS], int *thread_count ) { + HANDLE temp = CreateThread( NULL, // LPSECURITY_ATTRIBUTES lpsa, + 0, // DWORD cbStack, + (LPTHREAD_START_ROUTINE)function, // LPTHREAD_START_ROUTINE lpStartAddr, + parms, // LPVOID lpvThreadParm, + 0, // DWORD fdwCreate, + &info.threadId); + info.threadHandle = (int) temp; + if (priority == THREAD_HIGHEST) { + SetThreadPriority( (HANDLE)info.threadHandle, THREAD_PRIORITY_HIGHEST ); // we better sleep enough to do this + } else if (priority == THREAD_ABOVE_NORMAL ) { + SetThreadPriority( (HANDLE)info.threadHandle, THREAD_PRIORITY_ABOVE_NORMAL ); + } + info.name = name; + if ( *thread_count < MAX_THREADS ) { + threads[(*thread_count)++] = &info; + } else { + common->DPrintf("WARNING: MAX_THREADS reached\n"); + } +} + +/* +================== +Sys_DestroyThread +================== +*/ +void Sys_DestroyThread( xthreadInfo& info ) { + WaitForSingleObject( (HANDLE)info.threadHandle, INFINITE); + CloseHandle( (HANDLE)info.threadHandle ); + info.threadHandle = 0; +} + +/* +================== +Sys_Sentry +================== +*/ +void Sys_Sentry() { + int j = 0; +} + +/* +================== +Sys_GetThreadName +================== +*/ +const char* Sys_GetThreadName(int *index) { + int id = GetCurrentThreadId(); + for( int i = 0; i < g_thread_count; i++ ) { + if ( id == g_threads[i]->threadId ) { + if ( index ) { + *index = i; + } + return g_threads[i]->name; + } + } + if ( index ) { + *index = -1; + } + return "main"; +} + + +/* +================== +Sys_EnterCriticalSection +================== +*/ +void Sys_EnterCriticalSection( int index ) { + assert( index >= 0 && index < MAX_CRITICAL_SECTIONS ); + if ( TryEnterCriticalSection( &win32.criticalSections[index] ) == 0 ) { + EnterCriticalSection( &win32.criticalSections[index] ); +// Sys_DebugPrintf( "busy lock '%s' in thread '%s'\n", lock->name, Sys_GetThreadName() ); + } +} + +/* +================== +Sys_LeaveCriticalSection +================== +*/ +void Sys_LeaveCriticalSection( int index ) { + assert( index >= 0 && index < MAX_CRITICAL_SECTIONS ); + LeaveCriticalSection( &win32.criticalSections[index] ); +} + +/* +================== +Sys_WaitForEvent +================== +*/ +void Sys_WaitForEvent( int index ) { + assert( index == 0 ); + if ( !win32.backgroundDownloadSemaphore ) { + win32.backgroundDownloadSemaphore = CreateEvent( NULL, TRUE, FALSE, NULL ); + } + WaitForSingleObject( win32.backgroundDownloadSemaphore, INFINITE ); + ResetEvent( win32.backgroundDownloadSemaphore ); +} + +/* +================== +Sys_TriggerEvent +================== +*/ +void Sys_TriggerEvent( int index ) { + assert( index == 0 ); + SetEvent( win32.backgroundDownloadSemaphore ); +} + + + +#pragma optimize( "", on ) + +#ifdef DEBUG + + +static unsigned int debug_total_alloc = 0; +static unsigned int debug_total_alloc_count = 0; +static unsigned int debug_current_alloc = 0; +static unsigned int debug_current_alloc_count = 0; +static unsigned int debug_frame_alloc = 0; +static unsigned int debug_frame_alloc_count = 0; + +idCVar sys_showMallocs( "sys_showMallocs", "0", CVAR_SYSTEM, "" ); + +// _HOOK_ALLOC, _HOOK_REALLOC, _HOOK_FREE + +typedef struct CrtMemBlockHeader +{ + struct _CrtMemBlockHeader *pBlockHeaderNext; // Pointer to the block allocated just before this one: + struct _CrtMemBlockHeader *pBlockHeaderPrev; // Pointer to the block allocated just after this one + char *szFileName; // File name + int nLine; // Line number + size_t nDataSize; // Size of user block + int nBlockUse; // Type of block + long lRequest; // Allocation number + byte gap[4]; // Buffer just before (lower than) the user's memory: +} CrtMemBlockHeader; + +#include + +/* +================== +Sys_AllocHook + + called for every malloc/new/free/delete +================== +*/ +int Sys_AllocHook( int nAllocType, void *pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char * szFileName, int nLine ) +{ + CrtMemBlockHeader *pHead; + byte *temp; + + if ( nBlockUse == _CRT_BLOCK ) + { + return( TRUE ); + } + + // get a pointer to memory block header + temp = ( byte * )pvData; + temp -= 32; + pHead = ( CrtMemBlockHeader * )temp; + + switch( nAllocType ) { + case _HOOK_ALLOC: + debug_total_alloc += nSize; + debug_current_alloc += nSize; + debug_frame_alloc += nSize; + debug_total_alloc_count++; + debug_current_alloc_count++; + debug_frame_alloc_count++; + break; + + case _HOOK_FREE: + assert( pHead->gap[0] == 0xfd && pHead->gap[1] == 0xfd && pHead->gap[2] == 0xfd && pHead->gap[3] == 0xfd ); + + debug_current_alloc -= pHead->nDataSize; + debug_current_alloc_count--; + debug_total_alloc_count++; + debug_frame_alloc_count++; + break; + + case _HOOK_REALLOC: + assert( pHead->gap[0] == 0xfd && pHead->gap[1] == 0xfd && pHead->gap[2] == 0xfd && pHead->gap[3] == 0xfd ); + + debug_current_alloc -= pHead->nDataSize; + debug_total_alloc += nSize; + debug_current_alloc += nSize; + debug_frame_alloc += nSize; + debug_total_alloc_count++; + debug_current_alloc_count--; + debug_frame_alloc_count++; + break; + } + return( TRUE ); +} + +/* +================== +Sys_DebugMemory_f +================== +*/ +void Sys_DebugMemory_f( void ) { + common->Printf( "Total allocation %8dk in %d blocks\n", debug_total_alloc / 1024, debug_total_alloc_count ); + common->Printf( "Current allocation %8dk in %d blocks\n", debug_current_alloc / 1024, debug_current_alloc_count ); +} + +/* +================== +Sys_MemFrame +================== +*/ +void Sys_MemFrame( void ) { + if( sys_showMallocs.GetInteger() ) { + common->Printf("Frame: %8dk in %5d blocks\n", debug_frame_alloc / 1024, debug_frame_alloc_count ); + } + + debug_frame_alloc = 0; + debug_frame_alloc_count = 0; +} + +#endif + +/* +================== +Sys_FlushCacheMemory + +On windows, the vertex buffers are write combined, so they +don't need to be flushed from the cache +================== +*/ +void Sys_FlushCacheMemory( void *base, int bytes ) { +} + +/* +============= +Sys_Error + +Show the early console as an error dialog +============= +*/ +void Sys_Error( const char *error, ... ) { + va_list argptr; + char text[4096]; + MSG msg; + + va_start( argptr, error ); + vsprintf( text, error, argptr ); + va_end( argptr); + + Conbuf_AppendText( text ); + Conbuf_AppendText( "\n" ); + + Win_SetErrorText( text ); + Sys_ShowConsole( 1, true ); + + timeEndPeriod( 1 ); + + Sys_ShutdownInput(); + + GLimp_Shutdown(); + + // wait for the user to quit + while ( 1 ) { + if ( !GetMessage( &msg, NULL, 0, 0 ) ) { + common->Quit(); + } + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + Sys_DestroyConsole(); + + exit (1); +} + +/* +============== +Sys_Quit +============== +*/ +void Sys_Quit( void ) { + timeEndPeriod( 1 ); + Sys_ShutdownInput(); + Sys_DestroyConsole(); + ExitProcess( 0 ); +} + + +/* +============== +Sys_Printf +============== +*/ +#define MAXPRINTMSG 4096 +void Sys_Printf( const char *fmt, ... ) { + char msg[MAXPRINTMSG]; + + va_list argptr; + va_start(argptr, fmt); + idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, argptr ); + va_end(argptr); + msg[sizeof(msg)-1] = '\0'; + + if ( win32.win_outputDebugString.GetBool() ) { + OutputDebugString( msg ); + } + if ( win32.win_outputEditString.GetBool() ) { + Conbuf_AppendText( msg ); + } +} + +/* +============== +Sys_DebugPrintf +============== +*/ +#define MAXPRINTMSG 4096 +void Sys_DebugPrintf( const char *fmt, ... ) { + char msg[MAXPRINTMSG]; + + va_list argptr; + va_start( argptr, fmt ); + idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, argptr ); + msg[ sizeof(msg)-1 ] = '\0'; + va_end( argptr ); + + OutputDebugString( msg ); +} + +/* +============== +Sys_DebugVPrintf +============== +*/ +void Sys_DebugVPrintf( const char *fmt, va_list arg ) { + char msg[MAXPRINTMSG]; + + idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, arg ); + msg[ sizeof(msg)-1 ] = '\0'; + + OutputDebugString( msg ); +} + +/* +============== +Sys_Sleep +============== +*/ +void Sys_Sleep( int msec ) { + Sleep( msec ); +} + +/* +============== +Sys_ShowWindow +============== +*/ +void Sys_ShowWindow( bool show ) { + ::ShowWindow( win32.hWnd, show ? SW_SHOW : SW_HIDE ); +} + +/* +============== +Sys_IsWindowVisible +============== +*/ +bool Sys_IsWindowVisible( void ) { + return ( ::IsWindowVisible( win32.hWnd ) != 0 ); +} + +/* +============== +Sys_Mkdir +============== +*/ +void Sys_Mkdir( const char *path ) { + _mkdir (path); +} + +/* +================= +Sys_FileTimeStamp +================= +*/ +ID_TIME_T Sys_FileTimeStamp( FILE *fp ) { + struct _stat st; + _fstat( _fileno( fp ), &st ); + return (long) st.st_mtime; +} + +/* +============== +Sys_Cwd +============== +*/ +const char *Sys_Cwd( void ) { + static char cwd[MAX_OSPATH]; + + _getcwd( cwd, sizeof( cwd ) - 1 ); + cwd[MAX_OSPATH-1] = 0; + + return cwd; +} + +/* +============== +Sys_DefaultCDPath +============== +*/ +const char *Sys_DefaultCDPath( void ) { + return ""; +} + +/* +============== +Sys_DefaultBasePath +============== +*/ +const char *Sys_DefaultBasePath( void ) { + return Sys_Cwd(); +} + +/* +============== +Sys_DefaultSavePath +============== +*/ +const char *Sys_DefaultSavePath( void ) { + return cvarSystem->GetCVarString( "fs_basepath" ); +} + +/* +============== +Sys_EXEPath +============== +*/ +const char *Sys_EXEPath( void ) { + static char exe[ MAX_OSPATH ]; + GetModuleFileName( NULL, exe, sizeof( exe ) - 1 ); + return exe; +} + +/* +============== +Sys_ListFiles +============== +*/ +int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { + idStr search; + struct _finddata_t findinfo; + int findhandle; + int flag; + + if ( !extension) { + extension = ""; + } + + // passing a slash as extension will find directories + if ( extension[0] == '/' && extension[1] == 0 ) { + extension = ""; + flag = 0; + } else { + flag = _A_SUBDIR; + } + + sprintf( search, "%s\\*%s", directory, extension ); + + // search + list.Clear(); + + findhandle = _findfirst( search, &findinfo ); + if ( findhandle == -1 ) { + return -1; + } + + do { + if ( flag ^ ( findinfo.attrib & _A_SUBDIR ) ) { + list.Append( findinfo.name ); + } + } while ( _findnext( findhandle, &findinfo ) != -1 ); + + _findclose( findhandle ); + + return list.Num(); +} + + +/* +================ +Sys_GetClipboardData +================ +*/ +char *Sys_GetClipboardData( void ) { + char *data = NULL; + char *cliptext; + + if ( OpenClipboard( NULL ) != 0 ) { + HANDLE hClipboardData; + + if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) { + if ( ( cliptext = (char *)GlobalLock( hClipboardData ) ) != 0 ) { + data = (char *)Mem_Alloc( GlobalSize( hClipboardData ) + 1 ); + strcpy( data, cliptext ); + GlobalUnlock( hClipboardData ); + + strtok( data, "\n\r\b" ); + } + } + CloseClipboard(); + } + return data; +} + +/* +================ +Sys_SetClipboardData +================ +*/ +void Sys_SetClipboardData( const char *string ) { + HGLOBAL HMem; + char *PMem; + + // allocate memory block + HMem = (char *)::GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, strlen( string ) + 1 ); + if ( HMem == NULL ) { + return; + } + // lock allocated memory and obtain a pointer + PMem = (char *)::GlobalLock( HMem ); + if ( PMem == NULL ) { + return; + } + // copy text into allocated memory block + lstrcpy( PMem, string ); + // unlock allocated memory + ::GlobalUnlock( HMem ); + // open Clipboard + if ( !OpenClipboard( 0 ) ) { + ::GlobalFree( HMem ); + return; + } + // remove current Clipboard contents + EmptyClipboard(); + // supply the memory handle to the Clipboard + SetClipboardData( CF_TEXT, HMem ); + HMem = 0; + // close Clipboard + CloseClipboard(); +} + +/* +======================================================================== + +DLL Loading + +======================================================================== +*/ + +/* +===================== +Sys_DLL_Load +===================== +*/ +int Sys_DLL_Load( const char *dllName ) { + HINSTANCE libHandle; + libHandle = LoadLibrary( dllName ); + if ( libHandle ) { + // since we can't have LoadLibrary load only from the specified path, check it did the right thing + char loadedPath[ MAX_OSPATH ]; + GetModuleFileName( libHandle, loadedPath, sizeof( loadedPath ) - 1 ); + if ( idStr::IcmpPath( dllName, loadedPath ) ) { + Sys_Printf( "ERROR: LoadLibrary '%s' wants to load '%s'\n", dllName, loadedPath ); + Sys_DLL_Unload( (int)libHandle ); + return 0; + } + } + return (int)libHandle; +} + +/* +===================== +Sys_DLL_GetProcAddress +===================== +*/ +void *Sys_DLL_GetProcAddress( int dllHandle, const char *procName ) { + return GetProcAddress( (HINSTANCE)dllHandle, procName ); +} + +/* +===================== +Sys_DLL_Unload +===================== +*/ +void Sys_DLL_Unload( int dllHandle ) { + if ( !dllHandle ) { + return; + } + if ( FreeLibrary( (HINSTANCE)dllHandle ) == 0 ) { + int lastError = GetLastError(); + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + lastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + Sys_Error( "Sys_DLL_Unload: FreeLibrary failed - %s (%d)", lpMsgBuf, lastError ); + } +} + +/* +======================================================================== + +EVENT LOOP + +======================================================================== +*/ + +#define MAX_QUED_EVENTS 256 +#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 ) + +sysEvent_t eventQue[MAX_QUED_EVENTS]; +int eventHead = 0; +int eventTail = 0; + +/* +================ +Sys_QueEvent + +Ptr should either be null, or point to a block of data that can +be freed by the game later. +================ +*/ +void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) { + sysEvent_t *ev; + + ev = &eventQue[ eventHead & MASK_QUED_EVENTS ]; + + if ( eventHead - eventTail >= MAX_QUED_EVENTS ) { + common->Printf("Sys_QueEvent: overflow\n"); + // we are discarding an event, but don't leak memory + if ( ev->evPtr ) { + Mem_Free( ev->evPtr ); + } + eventTail++; + } + + eventHead++; + + ev->evType = type; + ev->evValue = value; + ev->evValue2 = value2; + ev->evPtrLength = ptrLength; + ev->evPtr = ptr; +} + +/* +============= +Sys_PumpEvents + +This allows windows to be moved during renderbump +============= +*/ +void Sys_PumpEvents( void ) { + MSG msg; + + // pump the message loop + while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) { + if ( !GetMessage( &msg, NULL, 0, 0 ) ) { + common->Quit(); + } + + // save the msg time, because wndprocs don't have access to the timestamp + if ( win32.sysMsgTime && win32.sysMsgTime > (int)msg.time ) { + // don't ever let the event times run backwards +// common->Printf( "Sys_PumpEvents: win32.sysMsgTime (%i) > msg.time (%i)\n", win32.sysMsgTime, msg.time ); + } else { + win32.sysMsgTime = msg.time; + } + +#ifdef ID_ALLOW_TOOLS + if ( GUIEditorHandleMessage ( &msg ) ) { + continue; + } +#endif + + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} + +/* +================ +Sys_GenerateEvents +================ +*/ +void Sys_GenerateEvents( void ) { + static int entered = false; + char *s; + + if ( entered ) { + return; + } + entered = true; + + // pump the message loop + Sys_PumpEvents(); + + // make sure mouse and joystick are only called once a frame + IN_Frame(); + + // check for console commands + s = Sys_ConsoleInput(); + if ( s ) { + char *b; + int len; + + len = strlen( s ) + 1; + b = (char *)Mem_Alloc( len ); + strcpy( b, s ); + Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b ); + } + + entered = false; +} + +/* +================ +Sys_ClearEvents +================ +*/ +void Sys_ClearEvents( void ) { + eventHead = eventTail = 0; +} + +/* +================ +Sys_GetEvent +================ +*/ +sysEvent_t Sys_GetEvent( void ) { + sysEvent_t ev; + + // return if we have data + if ( eventHead > eventTail ) { + eventTail++; + return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ]; + } + + // return the empty event + memset( &ev, 0, sizeof( ev ) ); + + return ev; +} + +//================================================================ + +/* +================= +Sys_In_Restart_f + +Restart the input subsystem +================= +*/ +void Sys_In_Restart_f( const idCmdArgs &args ) { + Sys_ShutdownInput(); + Sys_InitInput(); +} + + +/* +================== +Sys_AsyncThread +================== +*/ +static void Sys_AsyncThread( void *parm ) { + int wakeNumber; + int startTime; + + startTime = Sys_Milliseconds(); + wakeNumber = 0; + + while ( 1 ) { +#ifdef WIN32 + // this will trigger 60 times a second + int r = WaitForSingleObject( hTimer, 100 ); + if ( r != WAIT_OBJECT_0 ) { + OutputDebugString( "idPacketServer::PacketServerInterrupt: bad wait return" ); + } +#endif + +#if 0 + wakeNumber++; + int msec = Sys_Milliseconds(); + int deltaTime = msec - startTime; + startTime = msec; + + char str[1024]; + sprintf( str, "%i ", deltaTime ); + OutputDebugString( str ); +#endif + + + common->Async(); + } +} + +/* +============== +Sys_StartAsyncThread + +Start the thread that will call idCommon::Async() +============== +*/ +void Sys_StartAsyncThread( void ) { + // create an auto-reset event that happens 60 times a second + hTimer = CreateWaitableTimer( NULL, false, NULL ); + if ( !hTimer ) { + common->Error( "idPacketServer::Spawn: CreateWaitableTimer failed" ); + } + + LARGE_INTEGER t; + t.HighPart = t.LowPart = 0; + SetWaitableTimer( hTimer, &t, USERCMD_MSEC, NULL, NULL, TRUE ); + + Sys_CreateThread( (xthread_t)Sys_AsyncThread, NULL, THREAD_ABOVE_NORMAL, threadInfo, "Async", g_threads, &g_thread_count ); + +#ifdef SET_THREAD_AFFINITY + // give the async thread an affinity for the second cpu + SetThreadAffinityMask( (HANDLE)threadInfo.threadHandle, 2 ); +#endif + + if ( !threadInfo.threadHandle ) { + common->Error( "Sys_StartAsyncThread: failed" ); + } +} + +/* +================ +Sys_AlreadyRunning + +returns true if there is a copy of D3 running already +================ +*/ +bool Sys_AlreadyRunning( void ) { +#ifndef DEBUG + if ( !win32.win_allowMultipleInstances.GetBool() ) { + HANDLE hMutexOneInstance = ::CreateMutex( NULL, FALSE, "DOOM3" ); + if ( ::GetLastError() == ERROR_ALREADY_EXISTS || ::GetLastError() == ERROR_ACCESS_DENIED ) { + return true; + } + } +#endif + return false; +} + +/* +================ +Sys_Init + +The cvar system must already be setup +================ +*/ +#define OSR2_BUILD_NUMBER 1111 +#define WIN98_BUILD_NUMBER 1998 + +void Sys_Init( void ) { + + CoInitialize( NULL ); + + // make sure the timer is high precision, otherwise + // NT gets 18ms resolution + timeBeginPeriod( 1 ); + + // get WM_TIMER messages pumped every millisecond +// SetTimer( NULL, 0, 100, NULL ); + + cmdSystem->AddCommand( "in_restart", Sys_In_Restart_f, CMD_FL_SYSTEM, "restarts the input system" ); +#ifdef DEBUG + cmdSystem->AddCommand( "createResourceIDs", CreateResourceIDs_f, CMD_FL_TOOL, "assigns resource IDs in _resouce.h files" ); +#endif +#if 0 + cmdSystem->AddCommand( "setAsyncSound", Sys_SetAsyncSound_f, CMD_FL_SYSTEM, "set the async sound option" ); +#endif + + // + // Windows user name + // + win32.win_username.SetString( Sys_GetCurrentUser() ); + + // + // Windows version + // + win32.osversion.dwOSVersionInfoSize = sizeof( win32.osversion ); + + if ( !GetVersionEx( (LPOSVERSIONINFO)&win32.osversion ) ) + Sys_Error( "Couldn't get OS info" ); + + if ( win32.osversion.dwMajorVersion < 4 ) { + Sys_Error( GAME_NAME " requires Windows version 4 (NT) or greater" ); + } + if ( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32s ) { + Sys_Error( GAME_NAME " doesn't run on Win32s" ); + } + + if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) { + if( win32.osversion.dwMajorVersion <= 4 ) { + win32.sys_arch.SetString( "WinNT (NT)" ); + } else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 0 ) { + win32.sys_arch.SetString( "Win2K (NT)" ); + } else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 1 ) { + win32.sys_arch.SetString( "WinXP (NT)" ); + } else if ( win32.osversion.dwMajorVersion == 6 ) { + win32.sys_arch.SetString( "Vista" ); + } else { + win32.sys_arch.SetString( "Unknown NT variant" ); + } + } else if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { + if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 0 ) { + // Win95 + if( win32.osversion.szCSDVersion[1] == 'C' ) { + win32.sys_arch.SetString( "Win95 OSR2 (95)" ); + } else { + win32.sys_arch.SetString( "Win95 (95)" ); + } + } else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 10 ) { + // Win98 + if( win32.osversion.szCSDVersion[1] == 'A' ) { + win32.sys_arch.SetString( "Win98SE (95)" ); + } else { + win32.sys_arch.SetString( "Win98 (95)" ); + } + } else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 90 ) { + // WinMe + win32.sys_arch.SetString( "WinMe (95)" ); + } else { + win32.sys_arch.SetString( "Unknown 95 variant" ); + } + } else { + win32.sys_arch.SetString( "unknown Windows variant" ); + } + + // + // CPU type + // + if ( !idStr::Icmp( win32.sys_cpustring.GetString(), "detect" ) ) { + idStr string; + + common->Printf( "%1.0f MHz ", Sys_ClockTicksPerSecond() / 1000000.0f ); + + win32.cpuid = Sys_GetCPUId(); + + string.Clear(); + + if ( win32.cpuid & CPUID_AMD ) { + string += "AMD CPU"; + } else if ( win32.cpuid & CPUID_INTEL ) { + string += "Intel CPU"; + } else if ( win32.cpuid & CPUID_UNSUPPORTED ) { + string += "unsupported CPU"; + } else { + string += "generic CPU"; + } + + string += " with "; + if ( win32.cpuid & CPUID_MMX ) { + string += "MMX & "; + } + if ( win32.cpuid & CPUID_3DNOW ) { + string += "3DNow! & "; + } + if ( win32.cpuid & CPUID_SSE ) { + string += "SSE & "; + } + if ( win32.cpuid & CPUID_SSE2 ) { + string += "SSE2 & "; + } + if ( win32.cpuid & CPUID_SSE3 ) { + string += "SSE3 & "; + } + if ( win32.cpuid & CPUID_HTT ) { + string += "HTT & "; + } + string.StripTrailing( " & " ); + string.StripTrailing( " with " ); + win32.sys_cpustring.SetString( string ); + } else { + common->Printf( "forcing CPU type to " ); + idLexer src( win32.sys_cpustring.GetString(), idStr::Length( win32.sys_cpustring.GetString() ), "sys_cpustring" ); + idToken token; + + int id = CPUID_NONE; + while( src.ReadToken( &token ) ) { + if ( token.Icmp( "generic" ) == 0 ) { + id |= CPUID_GENERIC; + } else if ( token.Icmp( "intel" ) == 0 ) { + id |= CPUID_INTEL; + } else if ( token.Icmp( "amd" ) == 0 ) { + id |= CPUID_AMD; + } else if ( token.Icmp( "mmx" ) == 0 ) { + id |= CPUID_MMX; + } else if ( token.Icmp( "3dnow" ) == 0 ) { + id |= CPUID_3DNOW; + } else if ( token.Icmp( "sse" ) == 0 ) { + id |= CPUID_SSE; + } else if ( token.Icmp( "sse2" ) == 0 ) { + id |= CPUID_SSE2; + } else if ( token.Icmp( "sse3" ) == 0 ) { + id |= CPUID_SSE3; + } else if ( token.Icmp( "htt" ) == 0 ) { + id |= CPUID_HTT; + } + } + if ( id == CPUID_NONE ) { + common->Printf( "WARNING: unknown sys_cpustring '%s'\n", win32.sys_cpustring.GetString() ); + id = CPUID_GENERIC; + } + win32.cpuid = (cpuid_t) id; + } + + common->Printf( "%s\n", win32.sys_cpustring.GetString() ); + common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() ); + common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() ); +} + +/* +================ +Sys_Shutdown +================ +*/ +void Sys_Shutdown( void ) { + CoUninitialize(); +} + +/* +================ +Sys_GetProcessorId +================ +*/ +cpuid_t Sys_GetProcessorId( void ) { + return win32.cpuid; +} + +/* +================ +Sys_GetProcessorString +================ +*/ +const char *Sys_GetProcessorString( void ) { + return win32.sys_cpustring.GetString(); +} + +//======================================================================= + +//#define SET_THREAD_AFFINITY + + +/* +==================== +Win_Frame +==================== +*/ +void Win_Frame( void ) { + // if "viewlog" has been modified, show or hide the log console + if ( win32.win_viewlog.IsModified() ) { + if ( !com_skipRenderer.GetBool() && idAsyncNetwork::serverDedicated.GetInteger() != 1 ) { + Sys_ShowConsole( win32.win_viewlog.GetInteger(), false ); + } + win32.win_viewlog.ClearModified(); + } +} + +extern "C" { void _chkstk( int size ); }; +void clrstk( void ); + +/* +==================== +TestChkStk +==================== +*/ +void TestChkStk( void ) { + int buffer[0x1000]; + + buffer[0] = 1; +} + +/* +==================== +HackChkStk +==================== +*/ +void HackChkStk( void ) { + DWORD old; + VirtualProtect( _chkstk, 6, PAGE_EXECUTE_READWRITE, &old ); + *(byte *)_chkstk = 0xe9; + *(int *)((int)_chkstk+1) = (int)clrstk - (int)_chkstk - 5; + + TestChkStk(); +} + +/* +==================== +GetExceptionCodeInfo +==================== +*/ +const char *GetExceptionCodeInfo( UINT code ) { + switch( code ) { + case EXCEPTION_ACCESS_VIOLATION: return "The thread tried to read from or write to a virtual address for which it does not have the appropriate access."; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."; + case EXCEPTION_BREAKPOINT: return "A breakpoint was encountered."; + case EXCEPTION_DATATYPE_MISALIGNMENT: return "The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on."; + case EXCEPTION_FLT_DENORMAL_OPERAND: return "One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value."; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "The thread tried to divide a floating-point value by a floating-point divisor of zero."; + case EXCEPTION_FLT_INEXACT_RESULT: return "The result of a floating-point operation cannot be represented exactly as a decimal fraction."; + case EXCEPTION_FLT_INVALID_OPERATION: return "This exception represents any floating-point exception not included in this list."; + case EXCEPTION_FLT_OVERFLOW: return "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."; + case EXCEPTION_FLT_STACK_CHECK: return "The stack overflowed or underflowed as the result of a floating-point operation."; + case EXCEPTION_FLT_UNDERFLOW: return "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."; + case EXCEPTION_ILLEGAL_INSTRUCTION: return "The thread tried to execute an invalid instruction."; + case EXCEPTION_IN_PAGE_ERROR: return "The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network."; + case EXCEPTION_INT_DIVIDE_BY_ZERO: return "The thread tried to divide an integer value by an integer divisor of zero."; + case EXCEPTION_INT_OVERFLOW: return "The result of an integer operation caused a carry out of the most significant bit of the result."; + case EXCEPTION_INVALID_DISPOSITION: return "An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception."; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "The thread tried to continue execution after a noncontinuable exception occurred."; + case EXCEPTION_PRIV_INSTRUCTION: return "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."; + case EXCEPTION_SINGLE_STEP: return "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."; + case EXCEPTION_STACK_OVERFLOW: return "The thread used up its stack."; + default: return "Unknown exception"; + } +} + +/* +==================== +EmailCrashReport + + emailer originally from Raven/Quake 4 +==================== +*/ +void EmailCrashReport( LPSTR messageText ) { + LPMAPISENDMAIL MAPISendMail; + MapiMessage message; + static int lastEmailTime = 0; + + if ( Sys_Milliseconds() < lastEmailTime + 10000 ) { + return; + } + + lastEmailTime = Sys_Milliseconds(); + + HINSTANCE mapi = LoadLibrary( "MAPI32.DLL" ); + if( mapi ) { + MAPISendMail = ( LPMAPISENDMAIL )GetProcAddress( mapi, "MAPISendMail" ); + if( MAPISendMail ) { + MapiRecipDesc toProgrammers = + { + 0, // ulReserved + MAPI_TO, // ulRecipClass + "DOOM 3 Crash", // lpszName + "SMTP:programmers@idsoftware.com", // lpszAddress + 0, // ulEIDSize + 0 // lpEntry + }; + + memset( &message, 0, sizeof( message ) ); + message.lpszSubject = "DOOM 3 Fatal Error"; + message.lpszNoteText = messageText; + message.nRecipCount = 1; + message.lpRecips = &toProgrammers; + + MAPISendMail( + 0, // LHANDLE lhSession + 0, // ULONG ulUIParam + &message, // lpMapiMessage lpMessage + MAPI_DIALOG, // FLAGS flFlags + 0 // ULONG ulReserved + ); + } + FreeLibrary( mapi ); + } +} + +int Sys_FPU_PrintStateFlags( char *ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ); + +/* +==================== +_except_handler +==================== +*/ +EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, + struct _CONTEXT *ContextRecord, void * DispatcherContext ) { + + static char msg[ 8192 ]; + char FPUFlags[2048]; + + Sys_FPU_PrintStateFlags( FPUFlags, ContextRecord->FloatSave.ControlWord, + ContextRecord->FloatSave.StatusWord, + ContextRecord->FloatSave.TagWord, + ContextRecord->FloatSave.ErrorOffset, + ContextRecord->FloatSave.ErrorSelector, + ContextRecord->FloatSave.DataOffset, + ContextRecord->FloatSave.DataSelector ); + + + sprintf( msg, + "Please describe what you were doing when DOOM 3 crashed!\n" + "If this text did not pop into your email client please copy and email it to programmers@idsoftware.com\n" + "\n" + "-= FATAL EXCEPTION =-\n" + "\n" + "%s\n" + "\n" + "0x%x at address 0x%08x\n" + "\n" + "%s\n" + "\n" + "EAX = 0x%08x EBX = 0x%08x\n" + "ECX = 0x%08x EDX = 0x%08x\n" + "ESI = 0x%08x EDI = 0x%08x\n" + "EIP = 0x%08x ESP = 0x%08x\n" + "EBP = 0x%08x EFL = 0x%08x\n" + "\n" + "CS = 0x%04x\n" + "SS = 0x%04x\n" + "DS = 0x%04x\n" + "ES = 0x%04x\n" + "FS = 0x%04x\n" + "GS = 0x%04x\n" + "\n" + "%s\n", + com_version.GetString(), + ExceptionRecord->ExceptionCode, + ExceptionRecord->ExceptionAddress, + GetExceptionCodeInfo( ExceptionRecord->ExceptionCode ), + ContextRecord->Eax, ContextRecord->Ebx, + ContextRecord->Ecx, ContextRecord->Edx, + ContextRecord->Esi, ContextRecord->Edi, + ContextRecord->Eip, ContextRecord->Esp, + ContextRecord->Ebp, ContextRecord->EFlags, + ContextRecord->SegCs, + ContextRecord->SegSs, + ContextRecord->SegDs, + ContextRecord->SegEs, + ContextRecord->SegFs, + ContextRecord->SegGs, + FPUFlags + ); + + EmailCrashReport( msg ); + common->FatalError( msg ); + + // Tell the OS to restart the faulting instruction + return ExceptionContinueExecution; +} + +#define TEST_FPU_EXCEPTIONS /* FPU_EXCEPTION_INVALID_OPERATION | */ \ + /* FPU_EXCEPTION_DENORMALIZED_OPERAND | */ \ + /* FPU_EXCEPTION_DIVIDE_BY_ZERO | */ \ + /* FPU_EXCEPTION_NUMERIC_OVERFLOW | */ \ + /* FPU_EXCEPTION_NUMERIC_UNDERFLOW | */ \ + /* FPU_EXCEPTION_INEXACT_RESULT | */ \ + 0 + +/* +================== +WinMain +================== +*/ +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { + + const HCURSOR hcurSave = ::SetCursor( LoadCursor( 0, IDC_WAIT ) ); + + Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 ); + + Sys_GetCurrentMemoryStatus( exeLaunchMemoryStats ); + +#if 0 + DWORD handler = (DWORD)_except_handler; + __asm + { // Build EXCEPTION_REGISTRATION record: + push handler // Address of handler function + push FS:[0] // Address of previous handler + mov FS:[0],ESP // Install new EXECEPTION_REGISTRATION + } +#endif + + win32.hInstance = hInstance; + idStr::Copynz( sys_cmdline, lpCmdLine, sizeof( sys_cmdline ) ); + + // done before Com/Sys_Init since we need this for error output + Sys_CreateConsole(); + + // no abort/retry/fail errors + SetErrorMode( SEM_FAILCRITICALERRORS ); + + for ( int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) { + InitializeCriticalSection( &win32.criticalSections[i] ); + } + + // get the initial time base + Sys_Milliseconds(); + +#ifdef DEBUG + // disable the painfully slow MS heap check every 1024 allocs + _CrtSetDbgFlag( 0 ); +#endif + +// Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS ); + Sys_FPU_SetPrecision( FPU_PRECISION_DOUBLE_EXTENDED ); + + common->Init( 0, NULL, lpCmdLine ); + +#if TEST_FPU_EXCEPTIONS != 0 + common->Printf( Sys_FPU_GetState() ); +#endif + +#ifndef ID_DEDICATED + if ( win32.win_notaskkeys.GetInteger() ) { + DisableTaskKeys( TRUE, FALSE, /*( win32.win_notaskkeys.GetInteger() == 2 )*/ FALSE ); + } +#endif + + Sys_StartAsyncThread(); + + // hide or show the early console as necessary + if ( win32.win_viewlog.GetInteger() || com_skipRenderer.GetBool() || idAsyncNetwork::serverDedicated.GetInteger() ) { + Sys_ShowConsole( 1, true ); + } else { + Sys_ShowConsole( 0, false ); + } + +#ifdef SET_THREAD_AFFINITY + // give the main thread an affinity for the first cpu + SetThreadAffinityMask( GetCurrentThread(), 1 ); +#endif + + ::SetCursor( hcurSave ); + + // Launch the script debugger + if ( strstr( lpCmdLine, "+debugger" ) ) { + // DebuggerClientInit( lpCmdLine ); + return 0; + } + + ::SetFocus( win32.hWnd ); + + // main game loop + while( 1 ) { + + Win_Frame(); + +#ifdef DEBUG + Sys_MemFrame(); +#endif + + // set exceptions, even if some crappy syscall changes them! + Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS ); + +#ifdef ID_ALLOW_TOOLS + if ( com_editors ) { + if ( com_editors & EDITOR_GUI ) { + // GUI editor + GUIEditorRun(); + } else if ( com_editors & EDITOR_RADIANT ) { + // Level Editor + RadiantRun(); + } + else if (com_editors & EDITOR_MATERIAL ) { + //BSM Nerve: Add support for the material editor + MaterialEditorRun(); + } + else { + if ( com_editors & EDITOR_LIGHT ) { + // in-game Light Editor + LightEditorRun(); + } + if ( com_editors & EDITOR_SOUND ) { + // in-game Sound Editor + SoundEditorRun(); + } + if ( com_editors & EDITOR_DECL ) { + // in-game Declaration Browser + DeclBrowserRun(); + } + if ( com_editors & EDITOR_AF ) { + // in-game Articulated Figure Editor + AFEditorRun(); + } + if ( com_editors & EDITOR_PARTICLE ) { + // in-game Particle Editor + ParticleEditorRun(); + } + if ( com_editors & EDITOR_SCRIPT ) { + // in-game Script Editor + ScriptEditorRun(); + } + if ( com_editors & EDITOR_PDA ) { + // in-game PDA Editor + PDAEditorRun(); + } + } + } +#endif + // run the game + common->Frame(); + } + + // never gets here + return 0; +} + +/* +==================== +clrstk + +I tried to get the run time to call this at every function entry, but +==================== +*/ +static int parmBytes; +__declspec( naked ) void clrstk( void ) { + // eax = bytes to add to stack + __asm { + mov [parmBytes],eax + neg eax ; compute new stack pointer in eax + add eax,esp + add eax,4 + xchg eax,esp + mov eax,dword ptr [eax] ; copy the return address + push eax + + ; clear to zero + push edi + push ecx + mov edi,esp + add edi,12 + mov ecx,[parmBytes] + shr ecx,2 + xor eax,eax + cld + rep stosd + pop ecx + pop edi + + ret + } +} + +/* +================== +idSysLocal::OpenURL +================== +*/ +void idSysLocal::OpenURL( const char *url, bool doexit ) { + static bool doexit_spamguard = false; + HWND wnd; + + if (doexit_spamguard) { + common->DPrintf( "OpenURL: already in an exit sequence, ignoring %s\n", url ); + return; + } + + common->Printf("Open URL: %s\n", url); + + if ( !ShellExecute( NULL, "open", url, NULL, NULL, SW_RESTORE ) ) { + common->Error( "Could not open url: '%s' ", url ); + return; + } + + wnd = GetForegroundWindow(); + if ( wnd ) { + ShowWindow( wnd, SW_MAXIMIZE ); + } + + if ( doexit ) { + doexit_spamguard = true; + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + } +} + +/* +================== +idSysLocal::StartProcess +================== +*/ +void idSysLocal::StartProcess( const char *exePath, bool doexit ) { + TCHAR szPathOrig[_MAX_PATH]; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + + strncpy( szPathOrig, exePath, _MAX_PATH ); + + if( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) { + common->Error( "Could not start process: '%s' ", szPathOrig ); + return; + } + + if ( doexit ) { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); + } +} + +/* +================== +Sys_SetFatalError +================== +*/ +void Sys_SetFatalError( const char *error ) { +} + +/* +================== +Sys_DoPreferences +================== +*/ +void Sys_DoPreferences( void ) { +} diff --git a/sys/win32/win_net.cpp b/sys/win32/win_net.cpp new file mode 100644 index 000000000..7bb1a04c8 --- /dev/null +++ b/sys/win32/win_net.cpp @@ -0,0 +1,1191 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include + +#include "win_local.h" + +static WSADATA winsockdata; +static bool winsockInitialized = false; +static bool usingSocks = false; + +idCVar net_ip( "net_ip", "localhost", CVAR_SYSTEM, "local IP address" ); +idCVar net_port( "net_port", "0", CVAR_SYSTEM | CVAR_INTEGER, "local IP port number" ); +idCVar net_forceLatency( "net_forceLatency", "0", CVAR_SYSTEM | CVAR_INTEGER, "milliseconds latency" ); +idCVar net_forceDrop( "net_forceDrop", "0", CVAR_SYSTEM | CVAR_INTEGER, "percentage packet loss" ); + +idCVar net_socksEnabled( "net_socksEnabled", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "" ); +idCVar net_socksServer( "net_socksServer", "", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); +idCVar net_socksPort( "net_socksPort", "1080", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "" ); +idCVar net_socksUsername( "net_socksUsername", "", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); +idCVar net_socksPassword( "net_socksPassword", "", CVAR_SYSTEM | CVAR_ARCHIVE, "" ); + + +static struct sockaddr socksRelayAddr; + +static SOCKET ip_socket; +static SOCKET socks_socket; +static char socksBuf[4096]; + +typedef struct { + unsigned long ip; + unsigned long mask; +} net_interface; + +#define MAX_INTERFACES 32 +int num_interfaces = 0; +net_interface netint[MAX_INTERFACES]; + +//============================================================================= + + +/* +==================== +NET_ErrorString +==================== +*/ +char *NET_ErrorString( void ) { + int code; + + code = WSAGetLastError(); + switch( code ) { + case WSAEINTR: return "WSAEINTR"; + case WSAEBADF: return "WSAEBADF"; + case WSAEACCES: return "WSAEACCES"; + case WSAEDISCON: return "WSAEDISCON"; + case WSAEFAULT: return "WSAEFAULT"; + case WSAEINVAL: return "WSAEINVAL"; + case WSAEMFILE: return "WSAEMFILE"; + case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK"; + case WSAEINPROGRESS: return "WSAEINPROGRESS"; + case WSAEALREADY: return "WSAEALREADY"; + case WSAENOTSOCK: return "WSAENOTSOCK"; + case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ"; + case WSAEMSGSIZE: return "WSAEMSGSIZE"; + case WSAEPROTOTYPE: return "WSAEPROTOTYPE"; + case WSAENOPROTOOPT: return "WSAENOPROTOOPT"; + case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT"; + case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT"; + case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP"; + case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT"; + case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT"; + case WSAEADDRINUSE: return "WSAEADDRINUSE"; + case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL"; + case WSAENETDOWN: return "WSAENETDOWN"; + case WSAENETUNREACH: return "WSAENETUNREACH"; + case WSAENETRESET: return "WSAENETRESET"; + case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR"; + case WSAECONNRESET: return "WSAECONNRESET"; + case WSAENOBUFS: return "WSAENOBUFS"; + case WSAEISCONN: return "WSAEISCONN"; + case WSAENOTCONN: return "WSAENOTCONN"; + case WSAESHUTDOWN: return "WSAESHUTDOWN"; + case WSAETOOMANYREFS: return "WSAETOOMANYREFS"; + case WSAETIMEDOUT: return "WSAETIMEDOUT"; + case WSAECONNREFUSED: return "WSAECONNREFUSED"; + case WSAELOOP: return "WSAELOOP"; + case WSAENAMETOOLONG: return "WSAENAMETOOLONG"; + case WSAEHOSTDOWN: return "WSAEHOSTDOWN"; + case WSASYSNOTREADY: return "WSASYSNOTREADY"; + case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED"; + case WSANOTINITIALISED: return "WSANOTINITIALISED"; + case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND"; + case WSATRY_AGAIN: return "WSATRY_AGAIN"; + case WSANO_RECOVERY: return "WSANO_RECOVERY"; + case WSANO_DATA: return "WSANO_DATA"; + default: return "NO ERROR"; + } +} + +/* +==================== +Net_NetadrToSockadr +==================== +*/ +void Net_NetadrToSockadr( const netadr_t *a, struct sockaddr *s ) { + memset( s, 0, sizeof(*s) ); + + if( a->type == NA_BROADCAST ) { + ((struct sockaddr_in *)s)->sin_family = AF_INET; + ((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST; + } + else if( a->type == NA_IP || a->type == NA_LOOPBACK ) { + ((struct sockaddr_in *)s)->sin_family = AF_INET; + ((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip; + } + + ((struct sockaddr_in *)s)->sin_port = htons( (short)a->port ); +} + + +/* +==================== +Net_SockadrToNetadr +==================== +*/ +void Net_SockadrToNetadr( struct sockaddr *s, netadr_t *a ) { + unsigned int ip; + if (s->sa_family == AF_INET) { + ip = ((struct sockaddr_in *)s)->sin_addr.s_addr; + *(unsigned int *)&a->ip = ip; + a->port = htons( ((struct sockaddr_in *)s)->sin_port ); + // we store in network order, that loopback test is host order.. + ip = ntohl( ip ); + if ( ip == INADDR_LOOPBACK ) { + a->type = NA_LOOPBACK; + } else { + a->type = NA_IP; + } + } +} + +/* +============= +Net_ExtractPort +============= +*/ +static bool Net_ExtractPort( const char *src, char *buf, int bufsize, int *port ) { + char *p; + strncpy( buf, src, bufsize ); + p = buf; p += Min( bufsize - 1, (int)strlen( src ) ); *p = '\0'; + p = strchr( buf, ':' ); + if ( !p ) { + return false; + } + *p = '\0'; + *port = strtol( p+1, NULL, 10 ); + if ( errno == ERANGE ) { + return false; + } + return true; +} + +/* +============= +Net_StringToSockaddr +============= +*/ +static bool Net_StringToSockaddr( const char *s, struct sockaddr *sadr, bool doDNSResolve ) { + struct hostent *h; + char buf[256]; + int port; + + memset( sadr, 0, sizeof( *sadr ) ); + + ((struct sockaddr_in *)sadr)->sin_family = AF_INET; + ((struct sockaddr_in *)sadr)->sin_port = 0; + + if( s[0] >= '0' && s[0] <= '9' ) { + unsigned long ret = inet_addr(s); + if ( ret != INADDR_NONE ) { + *(int *)&((struct sockaddr_in *)sadr)->sin_addr = ret; + } else { + // check for port + if ( !Net_ExtractPort( s, buf, sizeof( buf ), &port ) ) { + return false; + } + ret = inet_addr( buf ); + if ( ret == INADDR_NONE ) { + return false; + } + *(int *)&((struct sockaddr_in *)sadr)->sin_addr = ret; + ((struct sockaddr_in *)sadr)->sin_port = htons( port ); + } + } else if ( doDNSResolve ) { + // try to remove the port first, otherwise the DNS gets confused into multiple timeouts + // failed or not failed, buf is expected to contain the appropriate host to resolve + if ( Net_ExtractPort( s, buf, sizeof( buf ), &port ) ) { + ((struct sockaddr_in *)sadr)->sin_port = htons( port ); + } + h = gethostbyname( buf ); + if ( h == 0 ) { + return false; + } + *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; + } + + return true; +} + +/* +==================== +NET_IPSocket +==================== +*/ +int NET_IPSocket( const char *net_interface, int port, netadr_t *bound_to ) { + SOCKET newsocket; + struct sockaddr_in address; + unsigned long _true = 1; + int i = 1; + int err; + + if( net_interface ) { + common->DPrintf( "Opening IP socket: %s:%i\n", net_interface, port ); + } else { + common->DPrintf( "Opening IP socket: localhost:%i\n", port ); + } + + if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) { + err = WSAGetLastError(); + if( err != WSAEAFNOSUPPORT ) { + common->Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() ); + } + return 0; + } + + // make it non-blocking + if( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) { + common->Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() ); + return 0; + } + + // make it broadcast capable + if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i) ) == SOCKET_ERROR ) { + common->Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() ); + return 0; + } + + if( !net_interface || !net_interface[0] || !idStr::Icmp( net_interface, "localhost" ) ) { + address.sin_addr.s_addr = INADDR_ANY; + } + else { + Net_StringToSockaddr( net_interface, (struct sockaddr *)&address, true ); + } + + if( port == PORT_ANY ) { + address.sin_port = 0; + } + else { + address.sin_port = htons( (short)port ); + } + + address.sin_family = AF_INET; + + if( bind( newsocket, (const struct sockaddr *)&address, sizeof(address) ) == SOCKET_ERROR ) { + common->Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() ); + closesocket( newsocket ); + return 0; + } + + // if the port was PORT_ANY, we need to query again to know the real port we got bound to + // ( this used to be in idPort::InitForPort ) + if ( bound_to ) { + int len = sizeof( address ); + getsockname( newsocket, (sockaddr *)&address, &len ); + Net_SockadrToNetadr( (sockaddr *)&address, bound_to ); + } + + return newsocket; +} + +/* +==================== +NET_OpenSocks +==================== +*/ +void NET_OpenSocks( int port ) { + struct sockaddr_in address; + int err; + struct hostent *h; + int len; + bool rfc1929; + unsigned char buf[64]; + + usingSocks = false; + + common->Printf( "Opening connection to SOCKS server.\n" ); + + if ( ( socks_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == INVALID_SOCKET ) { + err = WSAGetLastError(); + common->Printf( "WARNING: NET_OpenSocks: socket: %s\n", NET_ErrorString() ); + return; + } + + h = gethostbyname( net_socksServer.GetString() ); + if ( h == NULL ) { + err = WSAGetLastError(); + common->Printf( "WARNING: NET_OpenSocks: gethostbyname: %s\n", NET_ErrorString() ); + return; + } + if ( h->h_addrtype != AF_INET ) { + common->Printf( "WARNING: NET_OpenSocks: gethostbyname: address type was not AF_INET\n" ); + return; + } + address.sin_family = AF_INET; + address.sin_addr.s_addr = *(int *)h->h_addr_list[0]; + address.sin_port = htons( (short)net_socksPort.GetInteger() ); + + if ( connect( socks_socket, (struct sockaddr *)&address, sizeof( address ) ) == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: connect: %s\n", NET_ErrorString() ); + return; + } + + // send socks authentication handshake + if ( *net_socksUsername.GetString() || *net_socksPassword.GetString() ) { + rfc1929 = true; + } + else { + rfc1929 = false; + } + + buf[0] = 5; // SOCKS version + // method count + if ( rfc1929 ) { + buf[1] = 2; + len = 4; + } + else { + buf[1] = 1; + len = 3; + } + buf[2] = 0; // method #1 - method id #00: no authentication + if ( rfc1929 ) { + buf[2] = 2; // method #2 - method id #02: username/password + } + if ( send( socks_socket, (const char *)buf, len, 0 ) == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); + return; + } + + // get the response + len = recv( socks_socket, (char *)buf, 64, 0 ); + if ( len == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); + return; + } + if ( len != 2 || buf[0] != 5 ) { + common->Printf( "NET_OpenSocks: bad response\n" ); + return; + } + switch( buf[1] ) { + case 0: // no authentication + break; + case 2: // username/password authentication + break; + default: + common->Printf( "NET_OpenSocks: request denied\n" ); + return; + } + + // do username/password authentication if needed + if ( buf[1] == 2 ) { + int ulen; + int plen; + + // build the request + ulen = strlen( net_socksUsername.GetString() ); + plen = strlen( net_socksPassword.GetString() ); + + buf[0] = 1; // username/password authentication version + buf[1] = ulen; + if ( ulen ) { + memcpy( &buf[2], net_socksUsername.GetString(), ulen ); + } + buf[2 + ulen] = plen; + if ( plen ) { + memcpy( &buf[3 + ulen], net_socksPassword.GetString(), plen ); + } + + // send it + if ( send( socks_socket, (const char *)buf, 3 + ulen + plen, 0 ) == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); + return; + } + + // get the response + len = recv( socks_socket, (char *)buf, 64, 0 ); + if ( len == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); + return; + } + if ( len != 2 || buf[0] != 1 ) { + common->Printf( "NET_OpenSocks: bad response\n" ); + return; + } + if ( buf[1] != 0 ) { + common->Printf( "NET_OpenSocks: authentication failed\n" ); + return; + } + } + + // send the UDP associate request + buf[0] = 5; // SOCKS version + buf[1] = 3; // command: UDP associate + buf[2] = 0; // reserved + buf[3] = 1; // address type: IPV4 + *(int *)&buf[4] = INADDR_ANY; + *(short *)&buf[8] = htons( (short)port ); // port + if ( send( socks_socket, (const char *)buf, 10, 0 ) == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); + return; + } + + // get the response + len = recv( socks_socket, (char *)buf, 64, 0 ); + if( len == SOCKET_ERROR ) { + err = WSAGetLastError(); + common->Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); + return; + } + if( len < 2 || buf[0] != 5 ) { + common->Printf( "NET_OpenSocks: bad response\n" ); + return; + } + // check completion code + if( buf[1] != 0 ) { + common->Printf( "NET_OpenSocks: request denied: %i\n", buf[1] ); + return; + } + if( buf[3] != 1 ) { + common->Printf( "NET_OpenSocks: relay address is not IPV4: %i\n", buf[3] ); + return; + } + ((struct sockaddr_in *)&socksRelayAddr)->sin_family = AF_INET; + ((struct sockaddr_in *)&socksRelayAddr)->sin_addr.s_addr = *(int *)&buf[4]; + ((struct sockaddr_in *)&socksRelayAddr)->sin_port = *(short *)&buf[8]; + memset( ((struct sockaddr_in *)&socksRelayAddr)->sin_zero, 0, 8 ); + + usingSocks = true; +} + +/* +================== +Net_WaitForUDPPacket +================== +*/ +bool Net_WaitForUDPPacket( int netSocket, int timeout ) { + int ret; + fd_set set; + struct timeval tv; + + if ( !netSocket ) { + return false; + } + + if ( timeout <= 0 ) { + return true; + } + + FD_ZERO( &set ); + FD_SET( netSocket, &set ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + + ret = select( netSocket + 1, &set, NULL, NULL, &tv ); + + if ( ret == -1 ) { + common->DPrintf( "Net_WaitForUPDPacket select(): %s\n", strerror( errno ) ); + return false; + } + + // timeout with no data + if ( ret == 0 ) { + return false; + } + + return true; +} + +/* +================== +Net_GetUDPPacket +================== +*/ +bool Net_GetUDPPacket( int netSocket, netadr_t &net_from, char *data, int &size, int maxSize ) { + int ret; + struct sockaddr from; + int fromlen; + int err; + + if( !netSocket ) { + return false; + } + + fromlen = sizeof(from); + ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *)&from, &fromlen ); + if ( ret == SOCKET_ERROR ) { + err = WSAGetLastError(); + + if( err == WSAEWOULDBLOCK || err == WSAECONNRESET ) { + return false; + } + char buf[1024]; + sprintf( buf, "Net_GetUDPPacket: %s\n", NET_ErrorString() ); + OutputDebugString( buf ); + return false; + } + + if ( netSocket == ip_socket ) { + memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 ); + } + + if ( usingSocks && netSocket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) { + if ( ret < 10 || data[0] != 0 || data[1] != 0 || data[2] != 0 || data[3] != 1 ) { + return false; + } + net_from.type = NA_IP; + net_from.ip[0] = data[4]; + net_from.ip[1] = data[5]; + net_from.ip[2] = data[6]; + net_from.ip[3] = data[7]; + net_from.port = *(short *)&data[8]; + memmove( data, &data[10], ret - 10 ); + } else { + Net_SockadrToNetadr( &from, &net_from ); + } + + if( ret == maxSize ) { + char buf[1024]; + sprintf( buf, "Net_GetUDPPacket: oversize packet from %s\n", Sys_NetAdrToString( net_from ) ); + OutputDebugString( buf ); + return false; + } + + size = ret; + + return true; +} + +/* +================== +Net_SendUDPPacket +================== +*/ +void Net_SendUDPPacket( int netSocket, int length, const void *data, const netadr_t to ) { + int ret; + struct sockaddr addr; + + if( !netSocket ) { + return; + } + + Net_NetadrToSockadr( &to, &addr ); + + if( usingSocks && to.type == NA_IP ) { + socksBuf[0] = 0; // reserved + socksBuf[1] = 0; + socksBuf[2] = 0; // fragment (not fragmented) + socksBuf[3] = 1; // address type: IPV4 + *(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr; + *(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port; + memcpy( &socksBuf[10], data, length ); + ret = sendto( netSocket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) ); + } else { + ret = sendto( netSocket, (const char *)data, length, 0, &addr, sizeof(addr) ); + } + if( ret == SOCKET_ERROR ) { + int err = WSAGetLastError(); + + // wouldblock is silent + if( err == WSAEWOULDBLOCK ) { + return; + } + + // some PPP links do not allow broadcasts and return an error + if( ( err == WSAEADDRNOTAVAIL ) && ( to.type == NA_BROADCAST ) ) { + return; + } + + char buf[1024]; + sprintf( buf, "Net_SendUDPPacket: %s\n", NET_ErrorString() ); + OutputDebugString( buf ); + } +} + +/* +==================== +Sys_InitNetworking +==================== +*/ +void Sys_InitNetworking( void ) { + int r; + + r = WSAStartup( MAKEWORD( 1, 1 ), &winsockdata ); + if( r ) { + common->Printf( "WARNING: Winsock initialization failed, returned %d\n", r ); + return; + } + + winsockInitialized = true; + common->Printf( "Winsock Initialized\n" ); + + PIP_ADAPTER_INFO pAdapterInfo; + PIP_ADAPTER_INFO pAdapter = NULL; + DWORD dwRetVal = 0; + PIP_ADDR_STRING pIPAddrString; + ULONG ulOutBufLen; + bool foundloopback; + + num_interfaces = 0; + foundloopback = false; + + pAdapterInfo = (IP_ADAPTER_INFO *)malloc( sizeof( IP_ADAPTER_INFO ) ); + if( !pAdapterInfo ) { + common->FatalError( "Sys_InitNetworking: Couldn't malloc( %d )", sizeof( IP_ADAPTER_INFO ) ); + } + ulOutBufLen = sizeof( IP_ADAPTER_INFO ); + + // Make an initial call to GetAdaptersInfo to get + // the necessary size into the ulOutBufLen variable + if( GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) == ERROR_BUFFER_OVERFLOW ) { + free( pAdapterInfo ); + pAdapterInfo = (IP_ADAPTER_INFO *)malloc( ulOutBufLen ); + if( !pAdapterInfo ) { + common->FatalError( "Sys_InitNetworking: Couldn't malloc( %ld )", ulOutBufLen ); + } + } + + if( ( dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) ) != NO_ERROR ) { + // happens if you have no network connection + common->Printf( "Sys_InitNetworking: GetAdaptersInfo failed (%ld).\n", dwRetVal ); + } else { + pAdapter = pAdapterInfo; + while( pAdapter ) { + common->Printf( "Found interface: %s %s - ", pAdapter->AdapterName, pAdapter->Description ); + pIPAddrString = &pAdapter->IpAddressList; + while( pIPAddrString ) { + unsigned long ip_a, ip_m; + if( !idStr::Icmp( "127.0.0.1", pIPAddrString->IpAddress.String ) ) { + foundloopback = true; + } + ip_a = ntohl( inet_addr( pIPAddrString->IpAddress.String ) ); + ip_m = ntohl( inet_addr( pIPAddrString->IpMask.String ) ); + //skip null netmasks + if( !ip_m ) { + common->Printf( "%s NULL netmask - skipped\n", pIPAddrString->IpAddress.String ); + pIPAddrString = pIPAddrString->Next; + continue; + } + common->Printf( "%s/%s\n", pIPAddrString->IpAddress.String, pIPAddrString->IpMask.String ); + netint[num_interfaces].ip = ip_a; + netint[num_interfaces].mask = ip_m; + num_interfaces++; + if( num_interfaces >= MAX_INTERFACES ) { + common->Printf( "Sys_InitNetworking: MAX_INTERFACES(%d) hit.\n", MAX_INTERFACES ); + free( pAdapterInfo ); + return; + } + pIPAddrString = pIPAddrString->Next; + } + pAdapter = pAdapter->Next; + } + } + // for some retarded reason, win32 doesn't count loopback as an adapter... + if( !foundloopback && num_interfaces < MAX_INTERFACES ) { + common->Printf( "Sys_InitNetworking: adding loopback interface\n" ); + netint[num_interfaces].ip = ntohl( inet_addr( "127.0.0.1" ) ); + netint[num_interfaces].mask = ntohl( inet_addr( "255.0.0.0" ) ); + num_interfaces++; + } + free( pAdapterInfo ); +} + + +/* +==================== +Sys_ShutdownNetworking +==================== +*/ +void Sys_ShutdownNetworking( void ) { + if ( !winsockInitialized ) { + return; + } + WSACleanup(); + winsockInitialized = false; +} + +/* +============= +Sys_StringToNetAdr +============= +*/ +bool Sys_StringToNetAdr( const char *s, netadr_t *a, bool doDNSResolve ) { + struct sockaddr sadr; + + if ( !Net_StringToSockaddr( s, &sadr, doDNSResolve ) ) { + return false; + } + + Net_SockadrToNetadr( &sadr, a ); + return true; +} + +/* +============= +Sys_NetAdrToString +============= +*/ +const char *Sys_NetAdrToString( const netadr_t a ) { + static int index = 0; + static char buf[ 4 ][ 64 ]; // flip/flop + char *s; + + s = buf[index]; + index = (index + 1) & 3; + + if ( a.type == NA_LOOPBACK ) { + if ( a.port ) { + idStr::snPrintf( s, 64, "localhost:%i", a.port ); + } else { + idStr::snPrintf( s, 64, "localhost" ); + } + } else if ( a.type == NA_IP ) { + idStr::snPrintf( s, 64, "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], a.port ); + } + return s; +} + +/* +================== +Sys_IsLANAddress +================== +*/ +bool Sys_IsLANAddress( const netadr_t adr ) { +#if ID_NOLANADDRESS + common->Printf( "Sys_IsLANAddress: ID_NOLANADDRESS\n" ); + return false; +#endif + if( adr.type == NA_LOOPBACK ) { + return true; + } + + if( adr.type != NA_IP ) { + return false; + } + + if( num_interfaces ) { + int i; + unsigned long *p_ip; + unsigned long ip; + p_ip = (unsigned long *)&adr.ip[0]; + ip = ntohl( *p_ip ); + + for( i=0; i < num_interfaces; i++ ) { + if( ( netint[i].ip & netint[i].mask ) == ( ip & netint[i].mask ) ) { + return true; + } + } + } + return false; +} + +/* +=================== +Sys_CompareNetAdrBase + +Compares without the port +=================== +*/ +bool Sys_CompareNetAdrBase( const netadr_t a, const netadr_t b ) { + if ( a.type != b.type ) { + return false; + } + + if ( a.type == NA_LOOPBACK ) { + return true; + } + + if ( a.type == NA_IP ) { + if ( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] ) { + return true; + } + return false; + } + + common->Printf( "Sys_CompareNetAdrBase: bad address type\n" ); + return false; +} + +//============================================================================= + + +#define MAX_UDP_MSG_SIZE 1400 + +typedef struct udpMsg_s { + byte data[MAX_UDP_MSG_SIZE]; + netadr_t address; + int size; + int time; + struct udpMsg_s * next; +} udpMsg_t; + +class idUDPLag { +public: + idUDPLag( void ); + ~idUDPLag( void ); + + udpMsg_t * sendFirst; + udpMsg_t * sendLast; + udpMsg_t * recieveFirst; + udpMsg_t * recieveLast; + idBlockAlloc udpMsgAllocator; +}; + +idUDPLag::idUDPLag( void ) { + sendFirst = sendLast = recieveFirst = recieveLast = NULL; +} + +idUDPLag::~idUDPLag( void ) { + udpMsgAllocator.Shutdown(); +} + +idUDPLag *udpPorts[65536]; + +/* +================== +idPort::idPort +================== +*/ +idPort::idPort() { + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); +} + +/* +================== +idPort::~idPort +================== +*/ +idPort::~idPort() { + Close(); +} + +/* +================== +InitForPort +================== +*/ +bool idPort::InitForPort( int portNumber ) { + int len = sizeof( struct sockaddr_in ); + + netSocket = NET_IPSocket( net_ip.GetString(), portNumber, &bound_to ); + if ( netSocket <= 0 ) { + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); + return false; + } + +#if 0 + if ( net_socksEnabled.GetBool() ) { + NET_OpenSocks( portNumber ); + } +#endif + + udpPorts[ bound_to.port ] = new idUDPLag; + + return true; +} + +/* +================== +idPort::Close +================== +*/ +void idPort::Close() { + if ( netSocket ) { + if ( udpPorts[ bound_to.port ] ) { + delete udpPorts[ bound_to.port ]; + udpPorts[ bound_to.port ] = NULL; + } + closesocket( netSocket ); + netSocket = 0; + memset( &bound_to, 0, sizeof( bound_to ) ); + } +} + +/* +================== +idPort::GetPacket +================== +*/ +bool idPort::GetPacket( netadr_t &from, void *data, int &size, int maxSize ) { + udpMsg_t *msg; + bool ret; + + while( 1 ) { + + ret = Net_GetUDPPacket( netSocket, from, (char *)data, size, maxSize ); + if ( !ret ) { + break; + } + + if ( net_forceDrop.GetInteger() > 0 ) { + if ( rand() < net_forceDrop.GetInteger() * RAND_MAX / 100 ) { + continue; + } + } + + packetsRead++; + bytesRead += size; + + if ( net_forceLatency.GetInteger() > 0 ) { + + assert( size <= MAX_UDP_MSG_SIZE ); + msg = udpPorts[ bound_to.port ]->udpMsgAllocator.Alloc(); + memcpy( msg->data, data, size ); + msg->size = size; + msg->address = from; + msg->time = Sys_Milliseconds(); + msg->next = NULL; + if ( udpPorts[ bound_to.port ]->recieveLast ) { + udpPorts[ bound_to.port ]->recieveLast->next = msg; + } else { + udpPorts[ bound_to.port ]->recieveFirst = msg; + } + udpPorts[ bound_to.port ]->recieveLast = msg; + } else { + break; + } + } + + if ( net_forceLatency.GetInteger() > 0 || ( udpPorts[ bound_to.port] && udpPorts[ bound_to.port ]->recieveFirst ) ) { + + msg = udpPorts[ bound_to.port ]->recieveFirst; + if ( msg && msg->time <= Sys_Milliseconds() - net_forceLatency.GetInteger() ) { + memcpy( data, msg->data, msg->size ); + size = msg->size; + from = msg->address; + udpPorts[ bound_to.port ]->recieveFirst = udpPorts[ bound_to.port ]->recieveFirst->next; + if ( !udpPorts[ bound_to.port ]->recieveFirst ) { + udpPorts[ bound_to.port ]->recieveLast = NULL; + } + udpPorts[ bound_to.port ]->udpMsgAllocator.Free( msg ); + return true; + } + return false; + + } else { + return ret; + } +} + +/* +================== +idPort::GetPacketBlocking +================== +*/ +bool idPort::GetPacketBlocking( netadr_t &from, void *data, int &size, int maxSize, int timeout ) { + + Net_WaitForUDPPacket( netSocket, timeout ); + + if ( GetPacket( from, data, size, maxSize ) ) { + return true; + } + + return false; +} + +/* +================== +idPort::SendPacket +================== +*/ +void idPort::SendPacket( const netadr_t to, const void *data, int size ) { + udpMsg_t *msg; + + if ( to.type == NA_BAD ) { + common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" ); + return; + } + + packetsWritten++; + bytesWritten += size; + + if ( net_forceDrop.GetInteger() > 0 ) { + if ( rand() < net_forceDrop.GetInteger() * RAND_MAX / 100 ) { + return; + } + } + + if ( net_forceLatency.GetInteger() > 0 || ( udpPorts[ bound_to.port ] && udpPorts[ bound_to.port ]->sendFirst ) ) { + + assert( size <= MAX_UDP_MSG_SIZE ); + msg = udpPorts[ bound_to.port ]->udpMsgAllocator.Alloc(); + memcpy( msg->data, data, size ); + msg->size = size; + msg->address = to; + msg->time = Sys_Milliseconds(); + msg->next = NULL; + if ( udpPorts[ bound_to.port ]->sendLast ) { + udpPorts[ bound_to.port ]->sendLast->next = msg; + } else { + udpPorts[ bound_to.port ]->sendFirst = msg; + } + udpPorts[ bound_to.port ]->sendLast = msg; + + for ( msg = udpPorts[ bound_to.port ]->sendFirst; msg && msg->time <= Sys_Milliseconds() - net_forceLatency.GetInteger(); msg = udpPorts[ bound_to.port ]->sendFirst ) { + Net_SendUDPPacket( netSocket, msg->size, msg->data, msg->address ); + udpPorts[ bound_to.port ]->sendFirst = udpPorts[ bound_to.port ]->sendFirst->next; + if ( !udpPorts[ bound_to.port ]->sendFirst ) { + udpPorts[ bound_to.port ]->sendLast = NULL; + } + udpPorts[ bound_to.port ]->udpMsgAllocator.Free( msg ); + } + + } else { + Net_SendUDPPacket( netSocket, size, data, to ); + } +} + + +//============================================================================= + +/* +================== +idTCP::idTCP +================== +*/ +idTCP::idTCP() { + fd = 0; + memset( &address, 0, sizeof( address ) ); +} + +/* +================== +idTCP::~idTCP +================== +*/ +idTCP::~idTCP() { + Close(); +} + +/* +================== +idTCP::Init +================== +*/ +bool idTCP::Init( const char *host, short port ) { + unsigned long _true = 1; + struct sockaddr sadr; + + if ( !Sys_StringToNetAdr( host, &address, true ) ) { + common->Printf( "Couldn't resolve server name \"%s\"\n", host ); + return false; + } + address.type = NA_IP; + if ( !address.port ) { + address.port = port; + } + common->Printf( "\"%s\" resolved to %i.%i.%i.%i:%i\n", host, + address.ip[0], address.ip[1], address.ip[2], address.ip[3], address.port ); + Net_NetadrToSockadr( &address, &sadr ); + + if ( fd ) { + common->Warning( "idTCP::Init: already initialized?" ); + } + + if ( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET ) { + fd = 0; + common->Printf( "ERROR: idTCP::Init: socket: %s\n", NET_ErrorString() ); + return false; + } + + if ( connect( fd, &sadr, sizeof(sadr)) == SOCKET_ERROR ) { + common->Printf( "ERROR: idTCP::Init: connect: %s\n", NET_ErrorString() ); + closesocket( fd ); + fd = 0; + return false; + } + + // make it non-blocking + if( ioctlsocket( fd, FIONBIO, &_true ) == SOCKET_ERROR ) { + common->Printf( "ERROR: idTCP::Init: ioctl FIONBIO: %s\n", NET_ErrorString() ); + closesocket( fd ); + fd = 0; + return false; + } + + common->DPrintf( "Opened TCP connection\n" ); + return true; +} + +/* +================== +idTCP::Close +================== +*/ +void idTCP::Close() { + if ( fd ) { + closesocket( fd ); + } + fd = 0; +} + +/* +================== +idTCP::Read +================== +*/ +int idTCP::Read( void *data, int size ) { + int nbytes; + + if ( !fd ) { + common->Printf("idTCP::Read: not initialized\n"); + return -1; + } + + if ( ( nbytes = recv( fd, (char *)data, size, 0 ) ) == SOCKET_ERROR ) { + if ( WSAGetLastError() == WSAEWOULDBLOCK ) { + return 0; + } + common->Printf( "ERROR: idTCP::Read: %s\n", NET_ErrorString() ); + Close(); + return -1; + } + + // a successful read of 0 bytes indicates remote has closed the connection + if ( nbytes == 0 ) { + common->DPrintf( "idTCP::Read: read 0 bytes - assume connection closed\n" ); + return -1; + } + + return nbytes; +} + +/* +================== +idTCP::Write +================== +*/ +int idTCP::Write( void *data, int size ) { + int nbytes; + + if ( !fd ) { + common->Printf("idTCP::Write: not initialized\n"); + return -1; + } + + if ( ( nbytes = send( fd, (char *)data, size, 0 ) ) == SOCKET_ERROR ) { + common->Printf( "ERROR: idTCP::Write: %s\n", NET_ErrorString() ); + Close(); + return -1; + } + + return nbytes; +} diff --git a/sys/win32/win_qgl.cpp b/sys/win32/win_qgl.cpp new file mode 100644 index 000000000..43dda3e54 --- /dev/null +++ b/sys/win32/win_qgl.cpp @@ -0,0 +1,2802 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/* +** QGL_WIN.C +** +** This file implements the operating system binding of GL to QGL function +** pointers. When doing a port of Doom you must implement the following +** two functions: +** +** QGL_Init() - loads libraries, assigns function pointers, etc. +** QGL_Shutdown() - unloads libraries, NULLs function pointers +*/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include "win_local.h" +#include "../../renderer/tr_local.h" + + +int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); +int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); +int ( WINAPI * qwglGetPixelFormat)(HDC); +BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); +BOOL ( WINAPI * qwglSwapBuffers)(HDC); + +BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); +HGLRC ( WINAPI * qwglCreateContext)(HDC); +HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int); +BOOL ( WINAPI * qwglDeleteContext)(HGLRC); +HGLRC ( WINAPI * qwglGetCurrentContext)(VOID); +HDC ( WINAPI * qwglGetCurrentDC)(VOID); +PROC ( WINAPI * qwglGetProcAddress)(LPCSTR); +BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC); +BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC); +BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD); + +BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, + FLOAT, int, LPGLYPHMETRICSFLOAT); + +BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, + LPLAYERPLANEDESCRIPTOR); +int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, + CONST COLORREF *); +int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, + COLORREF *); +BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL); +BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); + +void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); +void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); +GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); +void ( APIENTRY * qglArrayElement )(GLint i); +void ( APIENTRY * qglBegin )(GLenum mode); +void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); +void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); +void ( APIENTRY * qglCallList )(GLuint list); +void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); +void ( APIENTRY * qglClear )(GLbitfield mask); +void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +void ( APIENTRY * qglClearDepth )(GLclampd depth); +void ( APIENTRY * qglClearIndex )(GLfloat c); +void ( APIENTRY * qglClearStencil )(GLint s); +void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); +void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); +void ( APIENTRY * qglColor3bv )(const GLbyte *v); +void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); +void ( APIENTRY * qglColor3dv )(const GLdouble *v); +void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); +void ( APIENTRY * qglColor3fv )(const GLfloat *v); +void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); +void ( APIENTRY * qglColor3iv )(const GLint *v); +void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); +void ( APIENTRY * qglColor3sv )(const GLshort *v); +void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); +void ( APIENTRY * qglColor3ubv )(const GLubyte *v); +void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); +void ( APIENTRY * qglColor3uiv )(const GLuint *v); +void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); +void ( APIENTRY * qglColor3usv )(const GLushort *v); +void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +void ( APIENTRY * qglColor4bv )(const GLbyte *v); +void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +void ( APIENTRY * qglColor4dv )(const GLdouble *v); +void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +void ( APIENTRY * qglColor4fv )(const GLfloat *v); +void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); +void ( APIENTRY * qglColor4iv )(const GLint *v); +void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); +void ( APIENTRY * qglColor4sv )(const GLshort *v); +void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +void ( APIENTRY * qglColor4ubv )(const GLubyte *v); +void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); +void ( APIENTRY * qglColor4uiv )(const GLuint *v); +void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); +void ( APIENTRY * qglColor4usv )(const GLushort *v); +void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); +void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +void ( APIENTRY * qglCullFace )(GLenum mode); +void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); +void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); +void ( APIENTRY * qglDepthFunc )(GLenum func); +void ( APIENTRY * qglDepthMask )(GLboolean flag); +void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); +void ( APIENTRY * qglDisable )(GLenum cap); +void ( APIENTRY * qglDisableClientState )(GLenum array); +void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); +void ( APIENTRY * qglDrawBuffer )(GLenum mode); +void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglEdgeFlag )(GLboolean flag); +void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); +void ( APIENTRY * qglEnable )(GLenum cap); +void ( APIENTRY * qglEnableClientState )(GLenum array); +void ( APIENTRY * qglEnd )(void); +void ( APIENTRY * qglEndList )(void); +void ( APIENTRY * qglEvalCoord1d )(GLdouble u); +void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); +void ( APIENTRY * qglEvalCoord1f )(GLfloat u); +void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); +void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); +void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); +void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); +void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); +void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); +void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +void ( APIENTRY * qglEvalPoint1 )(GLint i); +void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); +void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); +void ( APIENTRY * qglFinish )(void); +void ( APIENTRY * qglFlush )(void); +void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); +void ( APIENTRY * qglFogi )(GLenum pname, GLint param); +void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); +void ( APIENTRY * qglFrontFace )(GLenum mode); +void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLuint ( APIENTRY * qglGenLists )(GLsizei range); +void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); +void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); +void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); +void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); +GLenum ( APIENTRY * qglGetError )(void); +void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); +void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); +void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); +void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); +void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); +void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); +void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); +void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); +void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); +void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); +void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); +const GLubyte * ( APIENTRY * qglGetString )(GLenum name); +void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); +void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); +void ( APIENTRY * qglHint )(GLenum target, GLenum mode); +void ( APIENTRY * qglIndexMask )(GLuint mask); +void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglIndexd )(GLdouble c); +void ( APIENTRY * qglIndexdv )(const GLdouble *c); +void ( APIENTRY * qglIndexf )(GLfloat c); +void ( APIENTRY * qglIndexfv )(const GLfloat *c); +void ( APIENTRY * qglIndexi )(GLint c); +void ( APIENTRY * qglIndexiv )(const GLint *c); +void ( APIENTRY * qglIndexs )(GLshort c); +void ( APIENTRY * qglIndexsv )(const GLshort *c); +void ( APIENTRY * qglIndexub )(GLubyte c); +void ( APIENTRY * qglIndexubv )(const GLubyte *c); +void ( APIENTRY * qglInitNames )(void); +void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); +GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); +GLboolean ( APIENTRY * qglIsList )(GLuint list); +GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); +void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); +void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); +void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); +void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); +void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); +void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); +void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); +void ( APIENTRY * qglLineWidth )(GLfloat width); +void ( APIENTRY * qglListBase )(GLuint base); +void ( APIENTRY * qglLoadIdentity )(void); +void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); +void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); +void ( APIENTRY * qglLoadName )(GLuint name); +void ( APIENTRY * qglLogicOp )(GLenum opcode); +void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); +void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); +void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); +void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); +void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); +void ( APIENTRY * qglMatrixMode )(GLenum mode); +void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); +void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); +void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); +void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); +void ( APIENTRY * qglNormal3bv )(const GLbyte *v); +void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); +void ( APIENTRY * qglNormal3dv )(const GLdouble *v); +void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); +void ( APIENTRY * qglNormal3fv )(const GLfloat *v); +void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); +void ( APIENTRY * qglNormal3iv )(const GLint *v); +void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); +void ( APIENTRY * qglNormal3sv )(const GLshort *v); +void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +void ( APIENTRY * qglPassThrough )(GLfloat token); +void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); +void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); +void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); +void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); +void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); +void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); +void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); +void ( APIENTRY * qglPointSize )(GLfloat size); +void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); +void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); +void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); +void ( APIENTRY * qglPopAttrib )(void); +void ( APIENTRY * qglPopClientAttrib )(void); +void ( APIENTRY * qglPopMatrix )(void); +void ( APIENTRY * qglPopName )(void); +void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); +void ( APIENTRY * qglPushAttrib )(GLbitfield mask); +void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); +void ( APIENTRY * qglPushMatrix )(void); +void ( APIENTRY * qglPushName )(GLuint name); +void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); +void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); +void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); +void ( APIENTRY * qglRasterPos2iv )(const GLint *v); +void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); +void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); +void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); +void ( APIENTRY * qglRasterPos3iv )(const GLint *v); +void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); +void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); +void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); +void ( APIENTRY * qglRasterPos4iv )(const GLint *v); +void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); +void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); +void ( APIENTRY * qglReadBuffer )(GLenum mode); +void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); +void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); +void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); +void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); +void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); +GLint ( APIENTRY * qglRenderMode )(GLenum mode); +void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); +void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); +void ( APIENTRY * qglShadeModel )(GLenum mode); +void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); +void ( APIENTRY * qglStencilMask )(GLuint mask); +void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); +void ( APIENTRY * qglTexCoord1d )(GLdouble s); +void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord1f )(GLfloat s); +void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord1i )(GLint s); +void ( APIENTRY * qglTexCoord1iv )(const GLint *v); +void ( APIENTRY * qglTexCoord1s )(GLshort s); +void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); +void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); +void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); +void ( APIENTRY * qglTexCoord2iv )(const GLint *v); +void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); +void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); +void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); +void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); +void ( APIENTRY * qglTexCoord3iv )(const GLint *v); +void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); +void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); +void ( APIENTRY * qglTexCoord4iv )(const GLint *v); +void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); +void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); +void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); +void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); +void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); +void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); +void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param); +void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y); +void ( APIENTRY * qglVertex2dv )(const GLdouble *v); +void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y); +void ( APIENTRY * qglVertex2fv )(const GLfloat *v); +void ( APIENTRY * qglVertex2i )(GLint x, GLint y); +void ( APIENTRY * qglVertex2iv )(const GLint *v); +void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y); +void ( APIENTRY * qglVertex2sv )(const GLshort *v); +void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglVertex3dv )(const GLdouble *v); +void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglVertex3fv )(const GLfloat *v); +void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z); +void ( APIENTRY * qglVertex3iv )(const GLint *v); +void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z); +void ( APIENTRY * qglVertex3sv )(const GLshort *v); +void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +void ( APIENTRY * qglVertex4dv )(const GLdouble *v); +void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +void ( APIENTRY * qglVertex4fv )(const GLfloat *v); +void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w); +void ( APIENTRY * qglVertex4iv )(const GLint *v); +void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); +void ( APIENTRY * qglVertex4sv )(const GLshort *v); +void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); + + + +static void ( APIENTRY * dllAccum )(GLenum op, GLfloat value); +static void ( APIENTRY * dllAlphaFunc )(GLenum func, GLclampf ref); +GLboolean ( APIENTRY * dllAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); +static void ( APIENTRY * dllArrayElement )(GLint i); +static void ( APIENTRY * dllBegin )(GLenum mode); +static void ( APIENTRY * dllBindTexture )(GLenum target, GLuint texture); +static void ( APIENTRY * dllBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +static void ( APIENTRY * dllBlendFunc )(GLenum sfactor, GLenum dfactor); +static void ( APIENTRY * dllCallList )(GLuint list); +static void ( APIENTRY * dllCallLists )(GLsizei n, GLenum type, const GLvoid *lists); +static void ( APIENTRY * dllClear )(GLbitfield mask); +static void ( APIENTRY * dllClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +static void ( APIENTRY * dllClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +static void ( APIENTRY * dllClearDepth )(GLclampd depth); +static void ( APIENTRY * dllClearIndex )(GLfloat c); +static void ( APIENTRY * dllClearStencil )(GLint s); +static void ( APIENTRY * dllClipPlane )(GLenum plane, const GLdouble *equation); +static void ( APIENTRY * dllColor3b )(GLbyte red, GLbyte green, GLbyte blue); +static void ( APIENTRY * dllColor3bv )(const GLbyte *v); +static void ( APIENTRY * dllColor3d )(GLdouble red, GLdouble green, GLdouble blue); +static void ( APIENTRY * dllColor3dv )(const GLdouble *v); +static void ( APIENTRY * dllColor3f )(GLfloat red, GLfloat green, GLfloat blue); +static void ( APIENTRY * dllColor3fv )(const GLfloat *v); +static void ( APIENTRY * dllColor3i )(GLint red, GLint green, GLint blue); +static void ( APIENTRY * dllColor3iv )(const GLint *v); +static void ( APIENTRY * dllColor3s )(GLshort red, GLshort green, GLshort blue); +static void ( APIENTRY * dllColor3sv )(const GLshort *v); +static void ( APIENTRY * dllColor3ub )(GLubyte red, GLubyte green, GLubyte blue); +static void ( APIENTRY * dllColor3ubv )(const GLubyte *v); +static void ( APIENTRY * dllColor3ui )(GLuint red, GLuint green, GLuint blue); +static void ( APIENTRY * dllColor3uiv )(const GLuint *v); +static void ( APIENTRY * dllColor3us )(GLushort red, GLushort green, GLushort blue); +static void ( APIENTRY * dllColor3usv )(const GLushort *v); +static void ( APIENTRY * dllColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +static void ( APIENTRY * dllColor4bv )(const GLbyte *v); +static void ( APIENTRY * dllColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +static void ( APIENTRY * dllColor4dv )(const GLdouble *v); +static void ( APIENTRY * dllColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +static void ( APIENTRY * dllColor4fv )(const GLfloat *v); +static void ( APIENTRY * dllColor4i )(GLint red, GLint green, GLint blue, GLint alpha); +static void ( APIENTRY * dllColor4iv )(const GLint *v); +static void ( APIENTRY * dllColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); +static void ( APIENTRY * dllColor4sv )(const GLshort *v); +static void ( APIENTRY * dllColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +static void ( APIENTRY * dllColor4ubv )(const GLubyte *v); +static void ( APIENTRY * dllColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); +static void ( APIENTRY * dllColor4uiv )(const GLuint *v); +static void ( APIENTRY * dllColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); +static void ( APIENTRY * dllColor4usv )(const GLushort *v); +static void ( APIENTRY * dllColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +static void ( APIENTRY * dllColorMaterial )(GLenum face, GLenum mode); +static void ( APIENTRY * dllColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +static void ( APIENTRY * dllCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +static void ( APIENTRY * dllCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +static void ( APIENTRY * dllCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +static void ( APIENTRY * dllCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +static void ( APIENTRY * dllCullFace )(GLenum mode); +static void ( APIENTRY * dllDeleteLists )(GLuint list, GLsizei range); +static void ( APIENTRY * dllDeleteTextures )(GLsizei n, const GLuint *textures); +static void ( APIENTRY * dllDepthFunc )(GLenum func); +static void ( APIENTRY * dllDepthMask )(GLboolean flag); +static void ( APIENTRY * dllDepthRange )(GLclampd zNear, GLclampd zFar); +static void ( APIENTRY * dllDisable )(GLenum cap); +static void ( APIENTRY * dllDisableClientState )(GLenum array); +static void ( APIENTRY * dllDrawArrays )(GLenum mode, GLint first, GLsizei count); +static void ( APIENTRY * dllDrawBuffer )(GLenum mode); +static void ( APIENTRY * dllDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +static void ( APIENTRY * dllDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllEdgeFlag )(GLboolean flag); +static void ( APIENTRY * dllEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllEdgeFlagv )(const GLboolean *flag); +static void ( APIENTRY * dllEnable )(GLenum cap); +static void ( APIENTRY * dllEnableClientState )(GLenum array); +static void ( APIENTRY * dllEnd )(void); +static void ( APIENTRY * dllEndList )(void); +static void ( APIENTRY * dllEvalCoord1d )(GLdouble u); +static void ( APIENTRY * dllEvalCoord1dv )(const GLdouble *u); +static void ( APIENTRY * dllEvalCoord1f )(GLfloat u); +static void ( APIENTRY * dllEvalCoord1fv )(const GLfloat *u); +static void ( APIENTRY * dllEvalCoord2d )(GLdouble u, GLdouble v); +static void ( APIENTRY * dllEvalCoord2dv )(const GLdouble *u); +static void ( APIENTRY * dllEvalCoord2f )(GLfloat u, GLfloat v); +static void ( APIENTRY * dllEvalCoord2fv )(const GLfloat *u); +static void ( APIENTRY * dllEvalMesh1 )(GLenum mode, GLint i1, GLint i2); +static void ( APIENTRY * dllEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +static void ( APIENTRY * dllEvalPoint1 )(GLint i); +static void ( APIENTRY * dllEvalPoint2 )(GLint i, GLint j); +static void ( APIENTRY * dllFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); +static void ( APIENTRY * dllFinish )(void); +static void ( APIENTRY * dllFlush )(void); +static void ( APIENTRY * dllFogf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllFogfv )(GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllFogi )(GLenum pname, GLint param); +static void ( APIENTRY * dllFogiv )(GLenum pname, const GLint *params); +static void ( APIENTRY * dllFrontFace )(GLenum mode); +static void ( APIENTRY * dllFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLuint ( APIENTRY * dllGenLists )(GLsizei range); +static void ( APIENTRY * dllGenTextures )(GLsizei n, GLuint *textures); +static void ( APIENTRY * dllGetBooleanv )(GLenum pname, GLboolean *params); +static void ( APIENTRY * dllGetClipPlane )(GLenum plane, GLdouble *equation); +static void ( APIENTRY * dllGetDoublev )(GLenum pname, GLdouble *params); +GLenum ( APIENTRY * dllGetError )(void); +static void ( APIENTRY * dllGetFloatv )(GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetIntegerv )(GLenum pname, GLint *params); +static void ( APIENTRY * dllGetLightfv )(GLenum light, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetLightiv )(GLenum light, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetMapdv )(GLenum target, GLenum query, GLdouble *v); +static void ( APIENTRY * dllGetMapfv )(GLenum target, GLenum query, GLfloat *v); +static void ( APIENTRY * dllGetMapiv )(GLenum target, GLenum query, GLint *v); +static void ( APIENTRY * dllGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetMaterialiv )(GLenum face, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetPixelMapfv )(GLenum map, GLfloat *values); +static void ( APIENTRY * dllGetPixelMapuiv )(GLenum map, GLuint *values); +static void ( APIENTRY * dllGetPixelMapusv )(GLenum map, GLushort *values); +static void ( APIENTRY * dllGetPointerv )(GLenum pname, GLvoid* *params); +static void ( APIENTRY * dllGetPolygonStipple )(GLubyte *mask); +const GLubyte * ( APIENTRY * dllGetString )(GLenum name); +static void ( APIENTRY * dllGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexEnviv )(GLenum target, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); +static void ( APIENTRY * dllGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +static void ( APIENTRY * dllGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); +static void ( APIENTRY * dllHint )(GLenum target, GLenum mode); +static void ( APIENTRY * dllIndexMask )(GLuint mask); +static void ( APIENTRY * dllIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllIndexd )(GLdouble c); +static void ( APIENTRY * dllIndexdv )(const GLdouble *c); +static void ( APIENTRY * dllIndexf )(GLfloat c); +static void ( APIENTRY * dllIndexfv )(const GLfloat *c); +static void ( APIENTRY * dllIndexi )(GLint c); +static void ( APIENTRY * dllIndexiv )(const GLint *c); +static void ( APIENTRY * dllIndexs )(GLshort c); +static void ( APIENTRY * dllIndexsv )(const GLshort *c); +static void ( APIENTRY * dllIndexub )(GLubyte c); +static void ( APIENTRY * dllIndexubv )(const GLubyte *c); +static void ( APIENTRY * dllInitNames )(void); +static void ( APIENTRY * dllInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); +GLboolean ( APIENTRY * dllIsEnabled )(GLenum cap); +GLboolean ( APIENTRY * dllIsList )(GLuint list); +GLboolean ( APIENTRY * dllIsTexture )(GLuint texture); +static void ( APIENTRY * dllLightModelf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllLightModelfv )(GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllLightModeli )(GLenum pname, GLint param); +static void ( APIENTRY * dllLightModeliv )(GLenum pname, const GLint *params); +static void ( APIENTRY * dllLightf )(GLenum light, GLenum pname, GLfloat param); +static void ( APIENTRY * dllLightfv )(GLenum light, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllLighti )(GLenum light, GLenum pname, GLint param); +static void ( APIENTRY * dllLightiv )(GLenum light, GLenum pname, const GLint *params); +static void ( APIENTRY * dllLineStipple )(GLint factor, GLushort pattern); +static void ( APIENTRY * dllLineWidth )(GLfloat width); +static void ( APIENTRY * dllListBase )(GLuint base); +static void ( APIENTRY * dllLoadIdentity )(void); +static void ( APIENTRY * dllLoadMatrixd )(const GLdouble *m); +static void ( APIENTRY * dllLoadMatrixf )(const GLfloat *m); +static void ( APIENTRY * dllLoadName )(GLuint name); +static void ( APIENTRY * dllLogicOp )(GLenum opcode); +static void ( APIENTRY * dllMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +static void ( APIENTRY * dllMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +static void ( APIENTRY * dllMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +static void ( APIENTRY * dllMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +static void ( APIENTRY * dllMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); +static void ( APIENTRY * dllMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); +static void ( APIENTRY * dllMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +static void ( APIENTRY * dllMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +static void ( APIENTRY * dllMaterialf )(GLenum face, GLenum pname, GLfloat param); +static void ( APIENTRY * dllMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllMateriali )(GLenum face, GLenum pname, GLint param); +static void ( APIENTRY * dllMaterialiv )(GLenum face, GLenum pname, const GLint *params); +static void ( APIENTRY * dllMatrixMode )(GLenum mode); +static void ( APIENTRY * dllMultMatrixd )(const GLdouble *m); +static void ( APIENTRY * dllMultMatrixf )(const GLfloat *m); +static void ( APIENTRY * dllNewList )(GLuint list, GLenum mode); +static void ( APIENTRY * dllNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); +static void ( APIENTRY * dllNormal3bv )(const GLbyte *v); +static void ( APIENTRY * dllNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); +static void ( APIENTRY * dllNormal3dv )(const GLdouble *v); +static void ( APIENTRY * dllNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); +static void ( APIENTRY * dllNormal3fv )(const GLfloat *v); +static void ( APIENTRY * dllNormal3i )(GLint nx, GLint ny, GLint nz); +static void ( APIENTRY * dllNormal3iv )(const GLint *v); +static void ( APIENTRY * dllNormal3s )(GLshort nx, GLshort ny, GLshort nz); +static void ( APIENTRY * dllNormal3sv )(const GLshort *v); +static void ( APIENTRY * dllNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +static void ( APIENTRY * dllPassThrough )(GLfloat token); +static void ( APIENTRY * dllPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); +static void ( APIENTRY * dllPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); +static void ( APIENTRY * dllPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); +static void ( APIENTRY * dllPixelStoref )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllPixelStorei )(GLenum pname, GLint param); +static void ( APIENTRY * dllPixelTransferf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllPixelTransferi )(GLenum pname, GLint param); +static void ( APIENTRY * dllPixelZoom )(GLfloat xfactor, GLfloat yfactor); +static void ( APIENTRY * dllPointSize )(GLfloat size); +static void ( APIENTRY * dllPolygonMode )(GLenum face, GLenum mode); +static void ( APIENTRY * dllPolygonOffset )(GLfloat factor, GLfloat units); +static void ( APIENTRY * dllPolygonStipple )(const GLubyte *mask); +static void ( APIENTRY * dllPopAttrib )(void); +static void ( APIENTRY * dllPopClientAttrib )(void); +static void ( APIENTRY * dllPopMatrix )(void); +static void ( APIENTRY * dllPopName )(void); +static void ( APIENTRY * dllPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); +static void ( APIENTRY * dllPushAttrib )(GLbitfield mask); +static void ( APIENTRY * dllPushClientAttrib )(GLbitfield mask); +static void ( APIENTRY * dllPushMatrix )(void); +static void ( APIENTRY * dllPushName )(GLuint name); +static void ( APIENTRY * dllRasterPos2d )(GLdouble x, GLdouble y); +static void ( APIENTRY * dllRasterPos2dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos2f )(GLfloat x, GLfloat y); +static void ( APIENTRY * dllRasterPos2fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos2i )(GLint x, GLint y); +static void ( APIENTRY * dllRasterPos2iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos2s )(GLshort x, GLshort y); +static void ( APIENTRY * dllRasterPos2sv )(const GLshort *v); +static void ( APIENTRY * dllRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllRasterPos3dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllRasterPos3fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos3i )(GLint x, GLint y, GLint z); +static void ( APIENTRY * dllRasterPos3iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos3s )(GLshort x, GLshort y, GLshort z); +static void ( APIENTRY * dllRasterPos3sv )(const GLshort *v); +static void ( APIENTRY * dllRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +static void ( APIENTRY * dllRasterPos4dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +static void ( APIENTRY * dllRasterPos4fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos4i )(GLint x, GLint y, GLint z, GLint w); +static void ( APIENTRY * dllRasterPos4iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); +static void ( APIENTRY * dllRasterPos4sv )(const GLshort *v); +static void ( APIENTRY * dllReadBuffer )(GLenum mode); +static void ( APIENTRY * dllReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +static void ( APIENTRY * dllRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +static void ( APIENTRY * dllRectdv )(const GLdouble *v1, const GLdouble *v2); +static void ( APIENTRY * dllRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +static void ( APIENTRY * dllRectfv )(const GLfloat *v1, const GLfloat *v2); +static void ( APIENTRY * dllRecti )(GLint x1, GLint y1, GLint x2, GLint y2); +static void ( APIENTRY * dllRectiv )(const GLint *v1, const GLint *v2); +static void ( APIENTRY * dllRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +static void ( APIENTRY * dllRectsv )(const GLshort *v1, const GLshort *v2); +GLint ( APIENTRY * dllRenderMode )(GLenum mode); +static void ( APIENTRY * dllRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllScaled )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllScalef )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllScissor )(GLint x, GLint y, GLsizei width, GLsizei height); +static void ( APIENTRY * dllSelectBuffer )(GLsizei size, GLuint *buffer); +static void ( APIENTRY * dllShadeModel )(GLenum mode); +static void ( APIENTRY * dllStencilFunc )(GLenum func, GLint ref, GLuint mask); +static void ( APIENTRY * dllStencilMask )(GLuint mask); +static void ( APIENTRY * dllStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); +static void ( APIENTRY * dllTexCoord1d )(GLdouble s); +static void ( APIENTRY * dllTexCoord1dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord1f )(GLfloat s); +static void ( APIENTRY * dllTexCoord1fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord1i )(GLint s); +static void ( APIENTRY * dllTexCoord1iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord1s )(GLshort s); +static void ( APIENTRY * dllTexCoord1sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord2d )(GLdouble s, GLdouble t); +static void ( APIENTRY * dllTexCoord2dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord2f )(GLfloat s, GLfloat t); +static void ( APIENTRY * dllTexCoord2fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord2i )(GLint s, GLint t); +static void ( APIENTRY * dllTexCoord2iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord2s )(GLshort s, GLshort t); +static void ( APIENTRY * dllTexCoord2sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); +static void ( APIENTRY * dllTexCoord3dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); +static void ( APIENTRY * dllTexCoord3fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord3i )(GLint s, GLint t, GLint r); +static void ( APIENTRY * dllTexCoord3iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord3s )(GLshort s, GLshort t, GLshort r); +static void ( APIENTRY * dllTexCoord3sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +static void ( APIENTRY * dllTexCoord4dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +static void ( APIENTRY * dllTexCoord4fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord4i )(GLint s, GLint t, GLint r, GLint q); +static void ( APIENTRY * dllTexCoord4iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); +static void ( APIENTRY * dllTexCoord4sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllTexEnvf )(GLenum target, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexEnvi )(GLenum target, GLenum pname, GLint param); +static void ( APIENTRY * dllTexEnviv )(GLenum target, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexGend )(GLenum coord, GLenum pname, GLdouble param); +static void ( APIENTRY * dllTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); +static void ( APIENTRY * dllTexGenf )(GLenum coord, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexGeni )(GLenum coord, GLenum pname, GLint param); +static void ( APIENTRY * dllTexGeniv )(GLenum coord, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexParameteri )(GLenum target, GLenum pname, GLint param); +static void ( APIENTRY * dllTexParameteriv )(GLenum target, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTranslated )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllVertex2d )(GLdouble x, GLdouble y); +static void ( APIENTRY * dllVertex2dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y); +static void ( APIENTRY * dllVertex2fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex2i )(GLint x, GLint y); +static void ( APIENTRY * dllVertex2iv )(const GLint *v); +static void ( APIENTRY * dllVertex2s )(GLshort x, GLshort y); +static void ( APIENTRY * dllVertex2sv )(const GLshort *v); +static void ( APIENTRY * dllVertex3d )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllVertex3dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllVertex3fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex3i )(GLint x, GLint y, GLint z); +static void ( APIENTRY * dllVertex3iv )(const GLint *v); +static void ( APIENTRY * dllVertex3s )(GLshort x, GLshort y, GLshort z); +static void ( APIENTRY * dllVertex3sv )(const GLshort *v); +static void ( APIENTRY * dllVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +static void ( APIENTRY * dllVertex4dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +static void ( APIENTRY * dllVertex4fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex4i )(GLint x, GLint y, GLint z, GLint w); +static void ( APIENTRY * dllVertex4iv )(const GLint *v); +static void ( APIENTRY * dllVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); +static void ( APIENTRY * dllVertex4sv )(const GLshort *v); +static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height); + +typedef struct { + GLenum e; + const char *name; +} glEnumName_t; + +#define DEF(x) { x, #x }, + +glEnumName_t glEnumNames[] = { +DEF(GL_FALSE) +DEF(GL_TRUE) + + { GL_BYTE, "GL_BYTE" }, + { GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE" }, + { GL_SHORT, "GL_SHORT" }, + { GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT" }, + { GL_INT, "GL_INT" }, + { GL_UNSIGNED_INT, "GL_UNSIGNED_INT" }, + { GL_FLOAT, "GL_FLOAT" }, + { GL_DOUBLE, "GL_DOUBLE" }, + + { GL_TEXTURE_CUBE_MAP_EXT, "GL_TEXTURE_CUBE_MAP_EXT" }, + { GL_TEXTURE_3D, "GL_TEXTURE_3D" }, + { GL_TEXTURE_2D, "GL_TEXTURE_2D" }, + { GL_BLEND, "GL_BLEND" }, + { GL_DEPTH_TEST, "GL_DEPTH_TEST" }, + { GL_CULL_FACE, "GL_CULL_FACE" }, + { GL_CLIP_PLANE0, "GL_CLIP_PLANE0" }, + { GL_COLOR_ARRAY, "GL_COLOR_ARRAY" }, + { GL_TEXTURE_COORD_ARRAY, "GL_TEXTURE_COORD_ARRAY" }, + { GL_VERTEX_ARRAY, "GL_VERTEX_ARRAY" }, + { GL_ALPHA_TEST, "GL_ALPHA_TEST" }, + { GL_TEXTURE_GEN_S, "GL_TEXTURE_GEN_S" }, + { GL_TEXTURE_GEN_T, "GL_TEXTURE_GEN_T" }, + { GL_TEXTURE_GEN_R, "GL_TEXTURE_GEN_R" }, + { GL_TEXTURE_GEN_Q, "GL_TEXTURE_GEN_Q" }, + { GL_STENCIL_TEST, "GL_STENCIL_TEST" }, + { GL_POLYGON_OFFSET_FILL, "GL_POLYGON_OFFSET_FILL" }, + + { GL_TRIANGLES, "GL_TRIANGLES" }, + { GL_TRIANGLE_STRIP, "GL_TRIANGLE_STRIP" }, + { GL_TRIANGLE_FAN, "GL_TRIANGLE_FAN" }, + { GL_QUADS, "GL_QUADS" }, + { GL_QUAD_STRIP, "GL_QUAD_STRIP" }, + { GL_POLYGON, "GL_POLYGON" }, + { GL_POINTS, "GL_POINTS" }, + { GL_LINES, "GL_LINES" }, + { GL_LINE_STRIP, "GL_LINE_STRIP" }, + { GL_LINE_LOOP, "GL_LINE_LOOP" }, + + { GL_ALWAYS, "GL_ALWAYS" }, + { GL_NEVER, "GL_NEVER" }, + { GL_LEQUAL, "GL_LEQUAL" }, + { GL_LESS, "GL_LESS" }, + { GL_EQUAL, "GL_EQUAL" }, + { GL_GREATER, "GL_GREATER" }, + { GL_GEQUAL, "GL_GEQUAL" }, + { GL_NOTEQUAL, "GL_NOTEQUAL" }, + + { GL_ONE, "GL_ONE" }, + { GL_ZERO, "GL_ZERO" }, + { GL_SRC_ALPHA, "GL_SRC_ALPHA" }, + { GL_ONE_MINUS_SRC_ALPHA, "GL_ONE_MINUS_SRC_ALPHA" }, + { GL_DST_COLOR, "GL_DST_COLOR" }, + { GL_ONE_MINUS_DST_COLOR, "GL_ONE_MINUS_DST_COLOR" }, + { GL_DST_ALPHA, "GL_DST_ALPHA" }, + + { GL_MODELVIEW, "GL_MODELVIEW" }, + { GL_PROJECTION, "GL_PROJECTION" }, + { GL_TEXTURE, "GL_TEXTURE" }, + +/* DrawBufferMode */ +DEF(GL_NONE) +DEF(GL_FRONT_LEFT) +DEF(GL_FRONT_RIGHT) +DEF(GL_BACK_LEFT) +DEF(GL_BACK_RIGHT) +DEF(GL_FRONT) +DEF(GL_BACK) +DEF(GL_LEFT) +DEF(GL_RIGHT) +DEF(GL_FRONT_AND_BACK) +DEF(GL_AUX0) +DEF(GL_AUX1) +DEF(GL_AUX2) +DEF(GL_AUX3) + +/* GetTarget */ +DEF(GL_CURRENT_COLOR) +DEF(GL_CURRENT_INDEX) +DEF(GL_CURRENT_NORMAL) +DEF(GL_CURRENT_TEXTURE_COORDS) +DEF(GL_CURRENT_RASTER_COLOR) +DEF(GL_CURRENT_RASTER_INDEX) +DEF(GL_CURRENT_RASTER_TEXTURE_COORDS) +DEF(GL_CURRENT_RASTER_POSITION) +DEF(GL_CURRENT_RASTER_POSITION_VALID) +DEF(GL_CURRENT_RASTER_DISTANCE) +DEF(GL_POINT_SMOOTH) +DEF(GL_POINT_SIZE) +DEF(GL_POINT_SIZE_RANGE) +DEF(GL_POINT_SIZE_GRANULARITY) +DEF(GL_LINE_SMOOTH) +DEF(GL_LINE_WIDTH) +DEF(GL_LINE_WIDTH_RANGE) +DEF(GL_LINE_WIDTH_GRANULARITY) +DEF(GL_LINE_STIPPLE) +DEF(GL_LINE_STIPPLE_PATTERN) +DEF(GL_LINE_STIPPLE_REPEAT) +DEF(GL_LIST_MODE) +DEF(GL_MAX_LIST_NESTING) +DEF(GL_LIST_BASE) +DEF(GL_LIST_INDEX) +DEF(GL_POLYGON_MODE) +DEF(GL_POLYGON_SMOOTH) +DEF(GL_POLYGON_STIPPLE) +DEF(GL_EDGE_FLAG) +DEF(GL_CULL_FACE) +DEF(GL_CULL_FACE_MODE) +DEF(GL_FRONT_FACE) +DEF(GL_LIGHTING) +DEF(GL_LIGHT_MODEL_LOCAL_VIEWER) +DEF(GL_LIGHT_MODEL_TWO_SIDE) +DEF(GL_LIGHT_MODEL_AMBIENT) +DEF(GL_SHADE_MODEL) +DEF(GL_COLOR_MATERIAL_FACE) +DEF(GL_COLOR_MATERIAL_PARAMETER) +DEF(GL_COLOR_MATERIAL) +DEF(GL_FOG) +DEF(GL_FOG_INDEX) +DEF(GL_FOG_DENSITY) +DEF(GL_FOG_START) +DEF(GL_FOG_END) +DEF(GL_FOG_MODE) +DEF(GL_FOG_COLOR) +DEF(GL_DEPTH_RANGE) +DEF(GL_DEPTH_TEST) +DEF(GL_DEPTH_WRITEMASK) +DEF(GL_DEPTH_CLEAR_VALUE) +DEF(GL_DEPTH_FUNC) +DEF(GL_ACCUM_CLEAR_VALUE) +DEF(GL_STENCIL_TEST) +DEF(GL_STENCIL_CLEAR_VALUE) +DEF(GL_STENCIL_FUNC) +DEF(GL_STENCIL_VALUE_MASK) +DEF(GL_STENCIL_FAIL) +DEF(GL_STENCIL_PASS_DEPTH_FAIL) +DEF(GL_STENCIL_PASS_DEPTH_PASS) +DEF(GL_STENCIL_REF) +DEF(GL_STENCIL_WRITEMASK) +DEF(GL_MATRIX_MODE) +DEF(GL_NORMALIZE) +DEF(GL_VIEWPORT) +DEF(GL_MODELVIEW_STACK_DEPTH) +DEF(GL_PROJECTION_STACK_DEPTH) +DEF(GL_TEXTURE_STACK_DEPTH) +DEF(GL_MODELVIEW_MATRIX) +DEF(GL_PROJECTION_MATRIX) +DEF(GL_TEXTURE_MATRIX) +DEF(GL_ATTRIB_STACK_DEPTH) +DEF(GL_CLIENT_ATTRIB_STACK_DEPTH) +DEF(GL_ALPHA_TEST) +DEF(GL_ALPHA_TEST_FUNC) +DEF(GL_ALPHA_TEST_REF) +DEF(GL_DITHER) +DEF(GL_BLEND_DST) +DEF(GL_BLEND_SRC) +DEF(GL_BLEND) +DEF(GL_LOGIC_OP_MODE) +DEF(GL_INDEX_LOGIC_OP) +DEF(GL_COLOR_LOGIC_OP) +DEF(GL_AUX_BUFFERS) +DEF(GL_DRAW_BUFFER) +DEF(GL_READ_BUFFER) +DEF(GL_SCISSOR_BOX) +DEF(GL_SCISSOR_TEST) +DEF(GL_INDEX_CLEAR_VALUE) +DEF(GL_INDEX_WRITEMASK) +DEF(GL_COLOR_CLEAR_VALUE) +DEF(GL_COLOR_WRITEMASK) +DEF(GL_INDEX_MODE) +DEF(GL_RGBA_MODE) +DEF(GL_DOUBLEBUFFER) +DEF(GL_STEREO) +DEF(GL_RENDER_MODE) +DEF(GL_PERSPECTIVE_CORRECTION_HINT) +DEF(GL_POINT_SMOOTH_HINT) +DEF(GL_LINE_SMOOTH_HINT) +DEF(GL_POLYGON_SMOOTH_HINT) +DEF(GL_FOG_HINT) +DEF(GL_TEXTURE_GEN_S) +DEF(GL_TEXTURE_GEN_T) +DEF(GL_TEXTURE_GEN_R) +DEF(GL_TEXTURE_GEN_Q) +DEF(GL_PIXEL_MAP_I_TO_I) +DEF(GL_PIXEL_MAP_S_TO_S) +DEF(GL_PIXEL_MAP_I_TO_R) +DEF(GL_PIXEL_MAP_I_TO_G) +DEF(GL_PIXEL_MAP_I_TO_B) +DEF(GL_PIXEL_MAP_I_TO_A) +DEF(GL_PIXEL_MAP_R_TO_R) +DEF(GL_PIXEL_MAP_G_TO_G) +DEF(GL_PIXEL_MAP_B_TO_B) +DEF(GL_PIXEL_MAP_A_TO_A) +DEF(GL_PIXEL_MAP_I_TO_I_SIZE) +DEF(GL_PIXEL_MAP_S_TO_S_SIZE) +DEF(GL_PIXEL_MAP_I_TO_R_SIZE) +DEF(GL_PIXEL_MAP_I_TO_G_SIZE) +DEF(GL_PIXEL_MAP_I_TO_B_SIZE) +DEF(GL_PIXEL_MAP_I_TO_A_SIZE) +DEF(GL_PIXEL_MAP_R_TO_R_SIZE) +DEF(GL_PIXEL_MAP_G_TO_G_SIZE) +DEF(GL_PIXEL_MAP_B_TO_B_SIZE) +DEF(GL_PIXEL_MAP_A_TO_A_SIZE) +DEF(GL_UNPACK_SWAP_BYTES) +DEF(GL_UNPACK_LSB_FIRST) +DEF(GL_UNPACK_ROW_LENGTH) +DEF(GL_UNPACK_SKIP_ROWS) +DEF(GL_UNPACK_SKIP_PIXELS) +DEF(GL_UNPACK_ALIGNMENT) +DEF(GL_PACK_SWAP_BYTES) +DEF(GL_PACK_LSB_FIRST) +DEF(GL_PACK_ROW_LENGTH) +DEF(GL_PACK_SKIP_ROWS) +DEF(GL_PACK_SKIP_PIXELS) +DEF(GL_PACK_ALIGNMENT) +DEF(GL_MAP_COLOR) +DEF(GL_MAP_STENCIL) +DEF(GL_INDEX_SHIFT) +DEF(GL_INDEX_OFFSET) +DEF(GL_RED_SCALE) +DEF(GL_RED_BIAS) +DEF(GL_ZOOM_X) +DEF(GL_ZOOM_Y) +DEF(GL_GREEN_SCALE) +DEF(GL_GREEN_BIAS) +DEF(GL_BLUE_SCALE) +DEF(GL_BLUE_BIAS) +DEF(GL_ALPHA_SCALE) +DEF(GL_ALPHA_BIAS) +DEF(GL_DEPTH_SCALE) +DEF(GL_DEPTH_BIAS) +DEF(GL_MAX_EVAL_ORDER) +DEF(GL_MAX_LIGHTS) +DEF(GL_MAX_CLIP_PLANES) +DEF(GL_MAX_TEXTURE_SIZE) +DEF(GL_MAX_PIXEL_MAP_TABLE) +DEF(GL_MAX_ATTRIB_STACK_DEPTH) +DEF(GL_MAX_MODELVIEW_STACK_DEPTH) +DEF(GL_MAX_NAME_STACK_DEPTH) +DEF(GL_MAX_PROJECTION_STACK_DEPTH) +DEF(GL_MAX_TEXTURE_STACK_DEPTH) +DEF(GL_MAX_VIEWPORT_DIMS) +DEF(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH) +DEF(GL_SUBPIXEL_BITS) +DEF(GL_INDEX_BITS) +DEF(GL_RED_BITS) +DEF(GL_GREEN_BITS) +DEF(GL_BLUE_BITS) +DEF(GL_ALPHA_BITS) +DEF(GL_DEPTH_BITS) +DEF(GL_STENCIL_BITS) +DEF(GL_ACCUM_RED_BITS) +DEF(GL_ACCUM_GREEN_BITS) +DEF(GL_ACCUM_BLUE_BITS) +DEF(GL_ACCUM_ALPHA_BITS) +DEF(GL_NAME_STACK_DEPTH) +DEF(GL_AUTO_NORMAL) +DEF(GL_MAP1_COLOR_4) +DEF(GL_MAP1_INDEX) +DEF(GL_MAP1_NORMAL) +DEF(GL_MAP1_TEXTURE_COORD_1) +DEF(GL_MAP1_TEXTURE_COORD_2) +DEF(GL_MAP1_TEXTURE_COORD_3) +DEF(GL_MAP1_TEXTURE_COORD_4) +DEF(GL_MAP1_VERTEX_3) +DEF(GL_MAP1_VERTEX_4) +DEF(GL_MAP2_COLOR_4) +DEF(GL_MAP2_INDEX) +DEF(GL_MAP2_NORMAL) +DEF(GL_MAP2_TEXTURE_COORD_1) +DEF(GL_MAP2_TEXTURE_COORD_2) +DEF(GL_MAP2_TEXTURE_COORD_3) +DEF(GL_MAP2_TEXTURE_COORD_4) +DEF(GL_MAP2_VERTEX_3) +DEF(GL_MAP2_VERTEX_4) +DEF(GL_MAP1_GRID_DOMAIN) +DEF(GL_MAP1_GRID_SEGMENTS) +DEF(GL_MAP2_GRID_DOMAIN) +DEF(GL_MAP2_GRID_SEGMENTS) +DEF(GL_TEXTURE_1D) +DEF(GL_TEXTURE_2D) +DEF(GL_FEEDBACK_BUFFER_POINTER) +DEF(GL_FEEDBACK_BUFFER_SIZE) +DEF(GL_FEEDBACK_BUFFER_TYPE) +DEF(GL_SELECTION_BUFFER_POINTER) +DEF(GL_SELECTION_BUFFER_SIZE) + +/* PixelCopyType */ +DEF(GL_COLOR) +DEF(GL_DEPTH) +DEF(GL_STENCIL) + +/* PixelFormat */ +DEF(GL_COLOR_INDEX) +DEF(GL_STENCIL_INDEX) +DEF(GL_DEPTH_COMPONENT) +DEF(GL_RED) +DEF(GL_GREEN) +DEF(GL_BLUE) +DEF(GL_ALPHA) +DEF(GL_RGB) +DEF(GL_RGBA) +DEF(GL_LUMINANCE) +DEF(GL_LUMINANCE_ALPHA) + +/* PixelMap */ +/* GL_PIXEL_MAP_I_TO_I */ +/* GL_PIXEL_MAP_S_TO_S */ +/* GL_PIXEL_MAP_I_TO_R */ +/* GL_PIXEL_MAP_I_TO_G */ +/* GL_PIXEL_MAP_I_TO_B */ +/* GL_PIXEL_MAP_I_TO_A */ +/* GL_PIXEL_MAP_R_TO_R */ +/* GL_PIXEL_MAP_G_TO_G */ +/* GL_PIXEL_MAP_B_TO_B */ +/* GL_PIXEL_MAP_A_TO_A */ + +/* PixelStore */ +/* GL_UNPACK_SWAP_BYTES */ +/* GL_UNPACK_LSB_FIRST */ +/* GL_UNPACK_ROW_LENGTH */ +/* GL_UNPACK_SKIP_ROWS */ +/* GL_UNPACK_SKIP_PIXELS */ +/* GL_UNPACK_ALIGNMENT */ +/* GL_PACK_SWAP_BYTES */ +/* GL_PACK_LSB_FIRST */ +/* GL_PACK_ROW_LENGTH */ +/* GL_PACK_SKIP_ROWS */ +/* GL_PACK_SKIP_PIXELS */ +/* GL_PACK_ALIGNMENT */ + +/* PixelTransfer */ +/* GL_MAP_COLOR */ +/* GL_MAP_STENCIL */ +/* GL_INDEX_SHIFT */ +/* GL_INDEX_OFFSET */ +/* GL_RED_SCALE */ +/* GL_RED_BIAS */ +/* GL_GREEN_SCALE */ +/* GL_GREEN_BIAS */ +/* GL_BLUE_SCALE */ +/* GL_BLUE_BIAS */ +/* GL_ALPHA_SCALE */ +/* GL_ALPHA_BIAS */ +/* GL_DEPTH_SCALE */ +/* GL_DEPTH_BIAS */ + +/* PixelType */ +DEF(GL_BITMAP) +/* GL_BYTE */ +/* GL_UNSIGNED_BYTE */ +/* GL_SHORT */ +/* GL_UNSIGNED_SHORT */ +/* GL_INT */ +/* GL_UNSIGNED_INT */ +/* GL_FLOAT */ + +/* PolygonMode */ +DEF(GL_POINT) +DEF(GL_LINE) +DEF(GL_FILL) + +/* RenderingMode */ +DEF(GL_RENDER) +DEF(GL_FEEDBACK) +DEF(GL_SELECT) + +/* ShadingModel */ +DEF(GL_FLAT) +DEF(GL_SMOOTH) + +/* StencilOp */ +/* GL_ZERO */ +DEF(GL_KEEP) +DEF(GL_REPLACE) +DEF(GL_INCR) +DEF(GL_DECR) +/* GL_INVERT */ + +/* StringName */ +DEF(GL_VENDOR) +DEF(GL_RENDERER) +DEF(GL_VERSION) +DEF(GL_EXTENSIONS) + +/* TextureCoordName */ +DEF(GL_S) +DEF(GL_T) +DEF(GL_R) +DEF(GL_Q) + +/* TexCoordPointerType */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* TextureEnvMode */ +DEF(GL_MODULATE) +DEF(GL_DECAL) +/* GL_BLEND */ +/* GL_REPLACE */ + +/* TextureEnvParameter */ +DEF(GL_TEXTURE_ENV_MODE) +DEF(GL_TEXTURE_ENV_COLOR) + +/* TextureEnvTarget */ +DEF(GL_TEXTURE_ENV) + +/* TextureGenMode */ +DEF(GL_EYE_LINEAR) +DEF(GL_OBJECT_LINEAR) +DEF(GL_SPHERE_MAP) + +/* TextureGenParameter */ +DEF(GL_TEXTURE_GEN_MODE) +DEF(GL_OBJECT_PLANE) +DEF(GL_EYE_PLANE) + +/* TextureMagFilter */ +DEF(GL_NEAREST) +DEF(GL_LINEAR) + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +DEF(GL_NEAREST_MIPMAP_NEAREST) +DEF(GL_LINEAR_MIPMAP_NEAREST) +DEF(GL_NEAREST_MIPMAP_LINEAR) +DEF(GL_LINEAR_MIPMAP_LINEAR) + +/* TextureParameterName */ +DEF(GL_TEXTURE_MAG_FILTER) +DEF(GL_TEXTURE_MIN_FILTER) +DEF(GL_TEXTURE_WRAP_S) +DEF(GL_TEXTURE_WRAP_T) +/* GL_TEXTURE_BORDER_COLOR */ +/* GL_TEXTURE_PRIORITY */ + +/* TextureTarget */ +/* GL_TEXTURE_1D */ +/* GL_TEXTURE_2D */ +/* GL_PROXY_TEXTURE_1D */ +/* GL_PROXY_TEXTURE_2D */ + +/* TextureWrapMode */ +DEF(GL_CLAMP) +DEF(GL_REPEAT) + +/* VertexPointerType */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* ClientAttribMask */ +DEF(GL_CLIENT_PIXEL_STORE_BIT) +DEF(GL_CLIENT_VERTEX_ARRAY_BIT) +DEF(GL_CLIENT_ALL_ATTRIB_BITS) + +/* polygon_offset */ +DEF(GL_POLYGON_OFFSET_FACTOR) +DEF(GL_POLYGON_OFFSET_UNITS) +DEF(GL_POLYGON_OFFSET_POINT) +DEF(GL_POLYGON_OFFSET_LINE) +DEF(GL_POLYGON_OFFSET_FILL) + + { 0, NULL } +}; + +static const char *EnumString( GLenum t ) +{ + static char buffer[8][1024]; + static int index = 0; + + for ( glEnumName_t *n = glEnumNames ; n->name ; n++ ) { + if ( t == n->e ) { + return n->name; + } + } + + int oldIndex = index; + index = ( index + 1 ) & 7; + sprintf( buffer[oldIndex], "0x%x", t ); + + return buffer[oldIndex]; +} + +static const char *FloatData( const GLfloat *v, int count ) { + static char buffer[8][1024]; + static int index = 0; + char *name; + + name = buffer[index&7]; + sprintf( name, "f%i", index ); + index++; + + fprintf( tr.logFile, "static float %s[%i] = {", name, count ); + for( int i = 0 ; i < count ; i++ ) { + if ( i < count - 1 ) { + fprintf( tr.logFile, "%f,", v[i] ); + } else { + fprintf( tr.logFile, "%f};\n", v[i] ); + } + } + + return name; +} + +#if 0 + +// TODO: support GLbitfield + +static void APIENTRY logClear(GLbitfield mask) +{ + fprintf( tr.logFile, "glClear( 0 " ); + + if ( mask & GL_COLOR_BUFFER_BIT ) + fprintf( tr.logFile, "| GL_COLOR_BUFFER_BIT " ); + if ( mask & GL_DEPTH_BUFFER_BIT ) + fprintf( tr.logFile, "| GL_DEPTH_BUFFER_BIT " ); + if ( mask & GL_STENCIL_BUFFER_BIT ) + fprintf( tr.logFile, "| GL_STENCIL_BUFFER_BIT " ); + if ( mask & GL_ACCUM_BUFFER_BIT ) + fprintf( tr.logFile, "| GL_ACCUM_BUFFER_BIT " ); + + fprintf( tr.logFile, ");\n" ); + dllClear( mask ); +} + +#endif + +#include "gl_logfuncs.cpp" + +/* +** QGL_Shutdown +** +** Unloads the specified DLL then nulls out all the proc pointers. This +** is only called during a hard shutdown of the OGL subsystem (e.g. vid_restart). +*/ +void QGL_Shutdown( void ) +{ + common->Printf( "...shutting down QGL\n" ); + + if ( win32.hinstOpenGL ) + { + common->Printf( "...unloading OpenGL DLL\n" ); + FreeLibrary( win32.hinstOpenGL ); + } + + win32.hinstOpenGL = NULL; + + qglAccum = NULL; + qglAlphaFunc = NULL; + qglAreTexturesResident = NULL; + qglArrayElement = NULL; + qglBegin = NULL; + qglBindTexture = NULL; + qglBitmap = NULL; + qglBlendFunc = NULL; + qglCallList = NULL; + qglCallLists = NULL; + qglClear = NULL; + qglClearAccum = NULL; + qglClearColor = NULL; + qglClearDepth = NULL; + qglClearIndex = NULL; + qglClearStencil = NULL; + qglClipPlane = NULL; + qglColor3b = NULL; + qglColor3bv = NULL; + qglColor3d = NULL; + qglColor3dv = NULL; + qglColor3f = NULL; + qglColor3fv = NULL; + qglColor3i = NULL; + qglColor3iv = NULL; + qglColor3s = NULL; + qglColor3sv = NULL; + qglColor3ub = NULL; + qglColor3ubv = NULL; + qglColor3ui = NULL; + qglColor3uiv = NULL; + qglColor3us = NULL; + qglColor3usv = NULL; + qglColor4b = NULL; + qglColor4bv = NULL; + qglColor4d = NULL; + qglColor4dv = NULL; + qglColor4f = NULL; + qglColor4fv = NULL; + qglColor4i = NULL; + qglColor4iv = NULL; + qglColor4s = NULL; + qglColor4sv = NULL; + qglColor4ub = NULL; + qglColor4ubv = NULL; + qglColor4ui = NULL; + qglColor4uiv = NULL; + qglColor4us = NULL; + qglColor4usv = NULL; + qglColorMask = NULL; + qglColorMaterial = NULL; + qglColorPointer = NULL; + qglCopyPixels = NULL; + qglCopyTexImage1D = NULL; + qglCopyTexImage2D = NULL; + qglCopyTexSubImage1D = NULL; + qglCopyTexSubImage2D = NULL; + qglCullFace = NULL; + qglDeleteLists = NULL; + qglDeleteTextures = NULL; + qglDepthFunc = NULL; + qglDepthMask = NULL; + qglDepthRange = NULL; + qglDisable = NULL; + qglDisableClientState = NULL; + qglDrawArrays = NULL; + qglDrawBuffer = NULL; + qglDrawElements = NULL; + qglDrawPixels = NULL; + qglEdgeFlag = NULL; + qglEdgeFlagPointer = NULL; + qglEdgeFlagv = NULL; + qglEnable = NULL; + qglEnableClientState = NULL; + qglEnd = NULL; + qglEndList = NULL; + qglEvalCoord1d = NULL; + qglEvalCoord1dv = NULL; + qglEvalCoord1f = NULL; + qglEvalCoord1fv = NULL; + qglEvalCoord2d = NULL; + qglEvalCoord2dv = NULL; + qglEvalCoord2f = NULL; + qglEvalCoord2fv = NULL; + qglEvalMesh1 = NULL; + qglEvalMesh2 = NULL; + qglEvalPoint1 = NULL; + qglEvalPoint2 = NULL; + qglFeedbackBuffer = NULL; + qglFinish = NULL; + qglFlush = NULL; + qglFogf = NULL; + qglFogfv = NULL; + qglFogi = NULL; + qglFogiv = NULL; + qglFrontFace = NULL; + qglFrustum = NULL; + qglGenLists = NULL; + qglGenTextures = NULL; + qglGetBooleanv = NULL; + qglGetClipPlane = NULL; + qglGetDoublev = NULL; + qglGetError = NULL; + qglGetFloatv = NULL; + qglGetIntegerv = NULL; + qglGetLightfv = NULL; + qglGetLightiv = NULL; + qglGetMapdv = NULL; + qglGetMapfv = NULL; + qglGetMapiv = NULL; + qglGetMaterialfv = NULL; + qglGetMaterialiv = NULL; + qglGetPixelMapfv = NULL; + qglGetPixelMapuiv = NULL; + qglGetPixelMapusv = NULL; + qglGetPointerv = NULL; + qglGetPolygonStipple = NULL; + qglGetString = NULL; + qglGetTexEnvfv = NULL; + qglGetTexEnviv = NULL; + qglGetTexGendv = NULL; + qglGetTexGenfv = NULL; + qglGetTexGeniv = NULL; + qglGetTexImage = NULL; + qglGetTexLevelParameterfv = NULL; + qglGetTexLevelParameteriv = NULL; + qglGetTexParameterfv = NULL; + qglGetTexParameteriv = NULL; + qglHint = NULL; + qglIndexMask = NULL; + qglIndexPointer = NULL; + qglIndexd = NULL; + qglIndexdv = NULL; + qglIndexf = NULL; + qglIndexfv = NULL; + qglIndexi = NULL; + qglIndexiv = NULL; + qglIndexs = NULL; + qglIndexsv = NULL; + qglIndexub = NULL; + qglIndexubv = NULL; + qglInitNames = NULL; + qglInterleavedArrays = NULL; + qglIsEnabled = NULL; + qglIsList = NULL; + qglIsTexture = NULL; + qglLightModelf = NULL; + qglLightModelfv = NULL; + qglLightModeli = NULL; + qglLightModeliv = NULL; + qglLightf = NULL; + qglLightfv = NULL; + qglLighti = NULL; + qglLightiv = NULL; + qglLineStipple = NULL; + qglLineWidth = NULL; + qglListBase = NULL; + qglLoadIdentity = NULL; + qglLoadMatrixd = NULL; + qglLoadMatrixf = NULL; + qglLoadName = NULL; + qglLogicOp = NULL; + qglMap1d = NULL; + qglMap1f = NULL; + qglMap2d = NULL; + qglMap2f = NULL; + qglMapGrid1d = NULL; + qglMapGrid1f = NULL; + qglMapGrid2d = NULL; + qglMapGrid2f = NULL; + qglMaterialf = NULL; + qglMaterialfv = NULL; + qglMateriali = NULL; + qglMaterialiv = NULL; + qglMatrixMode = NULL; + qglMultMatrixd = NULL; + qglMultMatrixf = NULL; + qglNewList = NULL; + qglNormal3b = NULL; + qglNormal3bv = NULL; + qglNormal3d = NULL; + qglNormal3dv = NULL; + qglNormal3f = NULL; + qglNormal3fv = NULL; + qglNormal3i = NULL; + qglNormal3iv = NULL; + qglNormal3s = NULL; + qglNormal3sv = NULL; + qglNormalPointer = NULL; + qglOrtho = NULL; + qglPassThrough = NULL; + qglPixelMapfv = NULL; + qglPixelMapuiv = NULL; + qglPixelMapusv = NULL; + qglPixelStoref = NULL; + qglPixelStorei = NULL; + qglPixelTransferf = NULL; + qglPixelTransferi = NULL; + qglPixelZoom = NULL; + qglPointSize = NULL; + qglPolygonMode = NULL; + qglPolygonOffset = NULL; + qglPolygonStipple = NULL; + qglPopAttrib = NULL; + qglPopClientAttrib = NULL; + qglPopMatrix = NULL; + qglPopName = NULL; + qglPrioritizeTextures = NULL; + qglPushAttrib = NULL; + qglPushClientAttrib = NULL; + qglPushMatrix = NULL; + qglPushName = NULL; + qglRasterPos2d = NULL; + qglRasterPos2dv = NULL; + qglRasterPos2f = NULL; + qglRasterPos2fv = NULL; + qglRasterPos2i = NULL; + qglRasterPos2iv = NULL; + qglRasterPos2s = NULL; + qglRasterPos2sv = NULL; + qglRasterPos3d = NULL; + qglRasterPos3dv = NULL; + qglRasterPos3f = NULL; + qglRasterPos3fv = NULL; + qglRasterPos3i = NULL; + qglRasterPos3iv = NULL; + qglRasterPos3s = NULL; + qglRasterPos3sv = NULL; + qglRasterPos4d = NULL; + qglRasterPos4dv = NULL; + qglRasterPos4f = NULL; + qglRasterPos4fv = NULL; + qglRasterPos4i = NULL; + qglRasterPos4iv = NULL; + qglRasterPos4s = NULL; + qglRasterPos4sv = NULL; + qglReadBuffer = NULL; + qglReadPixels = NULL; + qglRectd = NULL; + qglRectdv = NULL; + qglRectf = NULL; + qglRectfv = NULL; + qglRecti = NULL; + qglRectiv = NULL; + qglRects = NULL; + qglRectsv = NULL; + qglRenderMode = NULL; + qglRotated = NULL; + qglRotatef = NULL; + qglScaled = NULL; + qglScalef = NULL; + qglScissor = NULL; + qglSelectBuffer = NULL; + qglShadeModel = NULL; + qglStencilFunc = NULL; + qglStencilMask = NULL; + qglStencilOp = NULL; + qglTexCoord1d = NULL; + qglTexCoord1dv = NULL; + qglTexCoord1f = NULL; + qglTexCoord1fv = NULL; + qglTexCoord1i = NULL; + qglTexCoord1iv = NULL; + qglTexCoord1s = NULL; + qglTexCoord1sv = NULL; + qglTexCoord2d = NULL; + qglTexCoord2dv = NULL; + qglTexCoord2f = NULL; + qglTexCoord2fv = NULL; + qglTexCoord2i = NULL; + qglTexCoord2iv = NULL; + qglTexCoord2s = NULL; + qglTexCoord2sv = NULL; + qglTexCoord3d = NULL; + qglTexCoord3dv = NULL; + qglTexCoord3f = NULL; + qglTexCoord3fv = NULL; + qglTexCoord3i = NULL; + qglTexCoord3iv = NULL; + qglTexCoord3s = NULL; + qglTexCoord3sv = NULL; + qglTexCoord4d = NULL; + qglTexCoord4dv = NULL; + qglTexCoord4f = NULL; + qglTexCoord4fv = NULL; + qglTexCoord4i = NULL; + qglTexCoord4iv = NULL; + qglTexCoord4s = NULL; + qglTexCoord4sv = NULL; + qglTexCoordPointer = NULL; + qglTexEnvf = NULL; + qglTexEnvfv = NULL; + qglTexEnvi = NULL; + qglTexEnviv = NULL; + qglTexGend = NULL; + qglTexGendv = NULL; + qglTexGenf = NULL; + qglTexGenfv = NULL; + qglTexGeni = NULL; + qglTexGeniv = NULL; + qglTexImage1D = NULL; + qglTexImage2D = NULL; + qglTexParameterf = NULL; + qglTexParameterfv = NULL; + qglTexParameteri = NULL; + qglTexParameteriv = NULL; + qglTexSubImage1D = NULL; + qglTexSubImage2D = NULL; + qglTranslated = NULL; + qglTranslatef = NULL; + qglVertex2d = NULL; + qglVertex2dv = NULL; + qglVertex2f = NULL; + qglVertex2fv = NULL; + qglVertex2i = NULL; + qglVertex2iv = NULL; + qglVertex2s = NULL; + qglVertex2sv = NULL; + qglVertex3d = NULL; + qglVertex3dv = NULL; + qglVertex3f = NULL; + qglVertex3fv = NULL; + qglVertex3i = NULL; + qglVertex3iv = NULL; + qglVertex3s = NULL; + qglVertex3sv = NULL; + qglVertex4d = NULL; + qglVertex4dv = NULL; + qglVertex4f = NULL; + qglVertex4fv = NULL; + qglVertex4i = NULL; + qglVertex4iv = NULL; + qglVertex4s = NULL; + qglVertex4sv = NULL; + qglVertexPointer = NULL; + qglViewport = NULL; + + qwglCopyContext = NULL; + qwglCreateContext = NULL; + qwglCreateLayerContext = NULL; + qwglDeleteContext = NULL; + qwglDescribeLayerPlane = NULL; + qwglGetCurrentContext = NULL; + qwglGetCurrentDC = NULL; + qwglGetLayerPaletteEntries = NULL; + qwglGetProcAddress = NULL; + qwglMakeCurrent = NULL; + qwglRealizeLayerPalette = NULL; + qwglSetLayerPaletteEntries = NULL; + qwglShareLists = NULL; + qwglSwapLayerBuffers = NULL; + qwglUseFontBitmaps = NULL; + qwglUseFontOutlines = NULL; + + qwglChoosePixelFormat = NULL; + qwglDescribePixelFormat = NULL; + qwglGetPixelFormat = NULL; + qwglSetPixelFormat = NULL; + qwglSwapBuffers = NULL; +} + +#define GR_NUM_BOARDS 0x0f + + +#pragma warning (disable : 4113 4133 4047 ) +#define GPA( a ) GetProcAddress( win32.hinstOpenGL, a ) + +/* +** QGL_Init +** +** This is responsible for binding our qgl function pointers to +** the appropriate GL stuff. In Windows this means doing a +** LoadLibrary and a bunch of calls to GetProcAddress. On other +** operating systems we need to do the right thing, whatever that +** might be. +*/ +bool QGL_Init( const char *dllname ) +{ + assert( win32.hinstOpenGL == 0 ); + + common->Printf( "...initializing QGL\n" ); + + common->Printf( "...calling LoadLibrary( '%s' ): ", dllname ); + + if ( ( win32.hinstOpenGL = LoadLibrary( dllname ) ) == 0 ) + { + common->Printf( "failed\n" ); + return false; + } + common->Printf( "succeeded\n" ); + + qglAccum = dllAccum = glAccum; + qglAlphaFunc = dllAlphaFunc = glAlphaFunc; + qglAreTexturesResident = dllAreTexturesResident = glAreTexturesResident; + qglArrayElement = dllArrayElement = glArrayElement; + qglBegin = dllBegin = glBegin; + qglBindTexture = dllBindTexture = glBindTexture; + qglBitmap = dllBitmap = glBitmap; + qglBlendFunc = dllBlendFunc = glBlendFunc; + qglCallList = dllCallList = glCallList; + qglCallLists = dllCallLists = glCallLists; + qglClear = dllClear = glClear; + qglClearAccum = dllClearAccum = glClearAccum; + qglClearColor = dllClearColor = glClearColor; + qglClearDepth = dllClearDepth = glClearDepth; + qglClearIndex = dllClearIndex = glClearIndex; + qglClearStencil = dllClearStencil = glClearStencil; + qglClipPlane = dllClipPlane = glClipPlane; + qglColor3b = dllColor3b = glColor3b; + qglColor3bv = dllColor3bv = glColor3bv; + qglColor3d = dllColor3d = glColor3d; + qglColor3dv = dllColor3dv = glColor3dv; + qglColor3f = dllColor3f = glColor3f; + qglColor3fv = dllColor3fv = glColor3fv; + qglColor3i = dllColor3i = glColor3i; + qglColor3iv = dllColor3iv = glColor3iv; + qglColor3s = dllColor3s = glColor3s; + qglColor3sv = dllColor3sv = glColor3sv; + qglColor3ub = dllColor3ub = glColor3ub; + qglColor3ubv = dllColor3ubv = glColor3ubv; + qglColor3ui = dllColor3ui = glColor3ui; + qglColor3uiv = dllColor3uiv = glColor3uiv; + qglColor3us = dllColor3us = glColor3us; + qglColor3usv = dllColor3usv = glColor3usv; + qglColor4b = dllColor4b = glColor4b; + qglColor4bv = dllColor4bv = glColor4bv; + qglColor4d = dllColor4d = glColor4d; + qglColor4dv = dllColor4dv = glColor4dv; + qglColor4f = dllColor4f = glColor4f; + qglColor4fv = dllColor4fv = glColor4fv; + qglColor4i = dllColor4i = glColor4i; + qglColor4iv = dllColor4iv = glColor4iv; + qglColor4s = dllColor4s = glColor4s; + qglColor4sv = dllColor4sv = glColor4sv; + qglColor4ub = dllColor4ub = glColor4ub; + qglColor4ubv = dllColor4ubv = glColor4ubv; + qglColor4ui = dllColor4ui = glColor4ui; + qglColor4uiv = dllColor4uiv = glColor4uiv; + qglColor4us = dllColor4us = glColor4us; + qglColor4usv = dllColor4usv = glColor4usv; + qglColorMask = dllColorMask = glColorMask; + qglColorMaterial = dllColorMaterial = glColorMaterial; + qglColorPointer = dllColorPointer = glColorPointer; + qglCopyPixels = dllCopyPixels = glCopyPixels; + qglCopyTexImage1D = dllCopyTexImage1D = glCopyTexImage1D; + qglCopyTexImage2D = dllCopyTexImage2D = glCopyTexImage2D; + qglCopyTexSubImage1D = dllCopyTexSubImage1D = glCopyTexSubImage1D; + qglCopyTexSubImage2D = dllCopyTexSubImage2D = glCopyTexSubImage2D; + qglCullFace = dllCullFace = glCullFace; + qglDeleteLists = dllDeleteLists = glDeleteLists; + qglDeleteTextures = dllDeleteTextures = glDeleteTextures; + qglDepthFunc = dllDepthFunc = glDepthFunc; + qglDepthMask = dllDepthMask = glDepthMask; + qglDepthRange = dllDepthRange = glDepthRange; + qglDisable = dllDisable = glDisable; + qglDisableClientState = dllDisableClientState = glDisableClientState; + qglDrawArrays = dllDrawArrays = glDrawArrays; + qglDrawBuffer = dllDrawBuffer = glDrawBuffer; + qglDrawElements = dllDrawElements = glDrawElements; + qglDrawPixels = dllDrawPixels = glDrawPixels; + qglEdgeFlag = dllEdgeFlag = glEdgeFlag; + qglEdgeFlagPointer = dllEdgeFlagPointer = glEdgeFlagPointer; + qglEdgeFlagv = dllEdgeFlagv = glEdgeFlagv; + qglEnable = dllEnable = glEnable; + qglEnableClientState = dllEnableClientState = glEnableClientState; + qglEnd = dllEnd = glEnd; + qglEndList = dllEndList = glEndList; + qglEvalCoord1d = dllEvalCoord1d = glEvalCoord1d; + qglEvalCoord1dv = dllEvalCoord1dv = glEvalCoord1dv; + qglEvalCoord1f = dllEvalCoord1f = glEvalCoord1f; + qglEvalCoord1fv = dllEvalCoord1fv = glEvalCoord1fv; + qglEvalCoord2d = dllEvalCoord2d = glEvalCoord2d; + qglEvalCoord2dv = dllEvalCoord2dv = glEvalCoord2dv; + qglEvalCoord2f = dllEvalCoord2f = glEvalCoord2f; + qglEvalCoord2fv = dllEvalCoord2fv = glEvalCoord2fv; + qglEvalMesh1 = dllEvalMesh1 = glEvalMesh1; + qglEvalMesh2 = dllEvalMesh2 = glEvalMesh2; + qglEvalPoint1 = dllEvalPoint1 = glEvalPoint1; + qglEvalPoint2 = dllEvalPoint2 = glEvalPoint2; + qglFeedbackBuffer = dllFeedbackBuffer = glFeedbackBuffer; + qglFinish = dllFinish = glFinish; + qglFlush = dllFlush = glFlush; + qglFogf = dllFogf = glFogf; + qglFogfv = dllFogfv = glFogfv; + qglFogi = dllFogi = glFogi; + qglFogiv = dllFogiv = glFogiv; + qglFrontFace = dllFrontFace = glFrontFace; + qglFrustum = dllFrustum = glFrustum; + qglGenLists = dllGenLists = ( GLuint (__stdcall * )(int) ) glGenLists; + qglGenTextures = dllGenTextures = glGenTextures; + qglGetBooleanv = dllGetBooleanv = glGetBooleanv; + qglGetClipPlane = dllGetClipPlane = glGetClipPlane; + qglGetDoublev = dllGetDoublev = glGetDoublev; + qglGetError = dllGetError = ( GLenum (__stdcall * )(void) ) glGetError; + qglGetFloatv = dllGetFloatv = glGetFloatv; + qglGetIntegerv = dllGetIntegerv = glGetIntegerv; + qglGetLightfv = dllGetLightfv = glGetLightfv; + qglGetLightiv = dllGetLightiv = glGetLightiv; + qglGetMapdv = dllGetMapdv = glGetMapdv; + qglGetMapfv = dllGetMapfv = glGetMapfv; + qglGetMapiv = dllGetMapiv = glGetMapiv; + qglGetMaterialfv = dllGetMaterialfv = glGetMaterialfv; + qglGetMaterialiv = dllGetMaterialiv = glGetMaterialiv; + qglGetPixelMapfv = dllGetPixelMapfv = glGetPixelMapfv; + qglGetPixelMapuiv = dllGetPixelMapuiv = glGetPixelMapuiv; + qglGetPixelMapusv = dllGetPixelMapusv = glGetPixelMapusv; + qglGetPointerv = dllGetPointerv = glGetPointerv; + qglGetPolygonStipple = dllGetPolygonStipple = glGetPolygonStipple; + qglGetString = dllGetString = glGetString; + qglGetTexEnvfv = dllGetTexEnvfv = glGetTexEnvfv; + qglGetTexEnviv = dllGetTexEnviv = glGetTexEnviv; + qglGetTexGendv = dllGetTexGendv = glGetTexGendv; + qglGetTexGenfv = dllGetTexGenfv = glGetTexGenfv; + qglGetTexGeniv = dllGetTexGeniv = glGetTexGeniv; + qglGetTexImage = dllGetTexImage = glGetTexImage; + qglGetTexLevelParameterfv = dllGetTexLevelParameterfv = glGetTexLevelParameterfv; + qglGetTexLevelParameteriv = dllGetTexLevelParameteriv = glGetTexLevelParameteriv; + qglGetTexParameterfv = dllGetTexParameterfv = glGetTexParameterfv; + qglGetTexParameteriv = dllGetTexParameteriv = glGetTexParameteriv; + qglHint = dllHint = glHint; + qglIndexMask = dllIndexMask = glIndexMask; + qglIndexPointer = dllIndexPointer = glIndexPointer; + qglIndexd = dllIndexd = glIndexd; + qglIndexdv = dllIndexdv = glIndexdv; + qglIndexf = dllIndexf = glIndexf; + qglIndexfv = dllIndexfv = glIndexfv; + qglIndexi = dllIndexi = glIndexi; + qglIndexiv = dllIndexiv = glIndexiv; + qglIndexs = dllIndexs = glIndexs; + qglIndexsv = dllIndexsv = glIndexsv; + qglIndexub = dllIndexub = glIndexub; + qglIndexubv = dllIndexubv = glIndexubv; + qglInitNames = dllInitNames = glInitNames; + qglInterleavedArrays = dllInterleavedArrays = glInterleavedArrays; + qglIsEnabled = dllIsEnabled = glIsEnabled; + qglIsList = dllIsList = glIsList; + qglIsTexture = dllIsTexture = glIsTexture; + qglLightModelf = dllLightModelf = glLightModelf; + qglLightModelfv = dllLightModelfv = glLightModelfv; + qglLightModeli = dllLightModeli = glLightModeli; + qglLightModeliv = dllLightModeliv = glLightModeliv; + qglLightf = dllLightf = glLightf; + qglLightfv = dllLightfv = glLightfv; + qglLighti = dllLighti = glLighti; + qglLightiv = dllLightiv = glLightiv; + qglLineStipple = dllLineStipple = glLineStipple; + qglLineWidth = dllLineWidth = glLineWidth; + qglListBase = dllListBase = glListBase; + qglLoadIdentity = dllLoadIdentity = glLoadIdentity; + qglLoadMatrixd = dllLoadMatrixd = glLoadMatrixd; + qglLoadMatrixf = dllLoadMatrixf = glLoadMatrixf; + qglLoadName = dllLoadName = glLoadName; + qglLogicOp = dllLogicOp = glLogicOp; + qglMap1d = dllMap1d = glMap1d; + qglMap1f = dllMap1f = glMap1f; + qglMap2d = dllMap2d = glMap2d; + qglMap2f = dllMap2f = glMap2f; + qglMapGrid1d = dllMapGrid1d = glMapGrid1d; + qglMapGrid1f = dllMapGrid1f = glMapGrid1f; + qglMapGrid2d = dllMapGrid2d = glMapGrid2d; + qglMapGrid2f = dllMapGrid2f = glMapGrid2f; + qglMaterialf = dllMaterialf = glMaterialf; + qglMaterialfv = dllMaterialfv = glMaterialfv; + qglMateriali = dllMateriali = glMateriali; + qglMaterialiv = dllMaterialiv = glMaterialiv; + qglMatrixMode = dllMatrixMode = glMatrixMode; + qglMultMatrixd = dllMultMatrixd = glMultMatrixd; + qglMultMatrixf = dllMultMatrixf = glMultMatrixf; + qglNewList = dllNewList = glNewList; + qglNormal3b = dllNormal3b = glNormal3b; + qglNormal3bv = dllNormal3bv = glNormal3bv; + qglNormal3d = dllNormal3d = glNormal3d; + qglNormal3dv = dllNormal3dv = glNormal3dv; + qglNormal3f = dllNormal3f = glNormal3f; + qglNormal3fv = dllNormal3fv = glNormal3fv; + qglNormal3i = dllNormal3i = glNormal3i; + qglNormal3iv = dllNormal3iv = glNormal3iv; + qglNormal3s = dllNormal3s = glNormal3s; + qglNormal3sv = dllNormal3sv = glNormal3sv; + qglNormalPointer = dllNormalPointer = glNormalPointer; + qglOrtho = dllOrtho = glOrtho; + qglPassThrough = dllPassThrough = glPassThrough; + qglPixelMapfv = dllPixelMapfv = glPixelMapfv; + qglPixelMapuiv = dllPixelMapuiv = glPixelMapuiv; + qglPixelMapusv = dllPixelMapusv = glPixelMapusv; + qglPixelStoref = dllPixelStoref = glPixelStoref; + qglPixelStorei = dllPixelStorei = glPixelStorei; + qglPixelTransferf = dllPixelTransferf = glPixelTransferf; + qglPixelTransferi = dllPixelTransferi = glPixelTransferi; + qglPixelZoom = dllPixelZoom = glPixelZoom; + qglPointSize = dllPointSize = glPointSize; + qglPolygonMode = dllPolygonMode = glPolygonMode; + qglPolygonOffset = dllPolygonOffset = glPolygonOffset; + qglPolygonStipple = dllPolygonStipple = glPolygonStipple; + qglPopAttrib = dllPopAttrib = glPopAttrib; + qglPopClientAttrib = dllPopClientAttrib = glPopClientAttrib; + qglPopMatrix = dllPopMatrix = glPopMatrix; + qglPopName = dllPopName = glPopName; + qglPrioritizeTextures = dllPrioritizeTextures = glPrioritizeTextures; + qglPushAttrib = dllPushAttrib = glPushAttrib; + qglPushClientAttrib = dllPushClientAttrib = glPushClientAttrib; + qglPushMatrix = dllPushMatrix = glPushMatrix; + qglPushName = dllPushName = glPushName; + qglRasterPos2d = dllRasterPos2d = glRasterPos2d; + qglRasterPos2dv = dllRasterPos2dv = glRasterPos2dv; + qglRasterPos2f = dllRasterPos2f = glRasterPos2f; + qglRasterPos2fv = dllRasterPos2fv = glRasterPos2fv; + qglRasterPos2i = dllRasterPos2i = glRasterPos2i; + qglRasterPos2iv = dllRasterPos2iv = glRasterPos2iv; + qglRasterPos2s = dllRasterPos2s = glRasterPos2s; + qglRasterPos2sv = dllRasterPos2sv = glRasterPos2sv; + qglRasterPos3d = dllRasterPos3d = glRasterPos3d; + qglRasterPos3dv = dllRasterPos3dv = glRasterPos3dv; + qglRasterPos3f = dllRasterPos3f = glRasterPos3f; + qglRasterPos3fv = dllRasterPos3fv = glRasterPos3fv; + qglRasterPos3i = dllRasterPos3i = glRasterPos3i; + qglRasterPos3iv = dllRasterPos3iv = glRasterPos3iv; + qglRasterPos3s = dllRasterPos3s = glRasterPos3s; + qglRasterPos3sv = dllRasterPos3sv = glRasterPos3sv; + qglRasterPos4d = dllRasterPos4d = glRasterPos4d; + qglRasterPos4dv = dllRasterPos4dv = glRasterPos4dv; + qglRasterPos4f = dllRasterPos4f = glRasterPos4f; + qglRasterPos4fv = dllRasterPos4fv = glRasterPos4fv; + qglRasterPos4i = dllRasterPos4i = glRasterPos4i; + qglRasterPos4iv = dllRasterPos4iv = glRasterPos4iv; + qglRasterPos4s = dllRasterPos4s = glRasterPos4s; + qglRasterPos4sv = dllRasterPos4sv = glRasterPos4sv; + qglReadBuffer = dllReadBuffer = glReadBuffer; + qglReadPixels = dllReadPixels = glReadPixels; + qglRectd = dllRectd = glRectd; + qglRectdv = dllRectdv = glRectdv; + qglRectf = dllRectf = glRectf; + qglRectfv = dllRectfv = glRectfv; + qglRecti = dllRecti = glRecti; + qglRectiv = dllRectiv = glRectiv; + qglRects = dllRects = glRects; + qglRectsv = dllRectsv = glRectsv; + qglRenderMode = dllRenderMode = glRenderMode; + qglRotated = dllRotated = glRotated; + qglRotatef = dllRotatef = glRotatef; + qglScaled = dllScaled = glScaled; + qglScalef = dllScalef = glScalef; + qglScissor = dllScissor = glScissor; + qglSelectBuffer = dllSelectBuffer = glSelectBuffer; + qglShadeModel = dllShadeModel = glShadeModel; + qglStencilFunc = dllStencilFunc = glStencilFunc; + qglStencilMask = dllStencilMask = glStencilMask; + qglStencilOp = dllStencilOp = glStencilOp; + qglTexCoord1d = dllTexCoord1d = glTexCoord1d; + qglTexCoord1dv = dllTexCoord1dv = glTexCoord1dv; + qglTexCoord1f = dllTexCoord1f = glTexCoord1f; + qglTexCoord1fv = dllTexCoord1fv = glTexCoord1fv; + qglTexCoord1i = dllTexCoord1i = glTexCoord1i; + qglTexCoord1iv = dllTexCoord1iv = glTexCoord1iv; + qglTexCoord1s = dllTexCoord1s = glTexCoord1s; + qglTexCoord1sv = dllTexCoord1sv = glTexCoord1sv; + qglTexCoord2d = dllTexCoord2d = glTexCoord2d; + qglTexCoord2dv = dllTexCoord2dv = glTexCoord2dv; + qglTexCoord2f = dllTexCoord2f = glTexCoord2f; + qglTexCoord2fv = dllTexCoord2fv = glTexCoord2fv; + qglTexCoord2i = dllTexCoord2i = glTexCoord2i; + qglTexCoord2iv = dllTexCoord2iv = glTexCoord2iv; + qglTexCoord2s = dllTexCoord2s = glTexCoord2s; + qglTexCoord2sv = dllTexCoord2sv = glTexCoord2sv; + qglTexCoord3d = dllTexCoord3d = glTexCoord3d; + qglTexCoord3dv = dllTexCoord3dv = glTexCoord3dv; + qglTexCoord3f = dllTexCoord3f = glTexCoord3f; + qglTexCoord3fv = dllTexCoord3fv = glTexCoord3fv; + qglTexCoord3i = dllTexCoord3i = glTexCoord3i; + qglTexCoord3iv = dllTexCoord3iv = glTexCoord3iv; + qglTexCoord3s = dllTexCoord3s = glTexCoord3s; + qglTexCoord3sv = dllTexCoord3sv = glTexCoord3sv; + qglTexCoord4d = dllTexCoord4d = glTexCoord4d; + qglTexCoord4dv = dllTexCoord4dv = glTexCoord4dv; + qglTexCoord4f = dllTexCoord4f = glTexCoord4f; + qglTexCoord4fv = dllTexCoord4fv = glTexCoord4fv; + qglTexCoord4i = dllTexCoord4i = glTexCoord4i; + qglTexCoord4iv = dllTexCoord4iv = glTexCoord4iv; + qglTexCoord4s = dllTexCoord4s = glTexCoord4s; + qglTexCoord4sv = dllTexCoord4sv = glTexCoord4sv; + qglTexCoordPointer = dllTexCoordPointer = glTexCoordPointer; + qglTexEnvf = dllTexEnvf = glTexEnvf; + qglTexEnvfv = dllTexEnvfv = glTexEnvfv; + qglTexEnvi = dllTexEnvi = glTexEnvi; + qglTexEnviv = dllTexEnviv = glTexEnviv; + qglTexGend = dllTexGend = glTexGend; + qglTexGendv = dllTexGendv = glTexGendv; + qglTexGenf = dllTexGenf = glTexGenf; + qglTexGenfv = dllTexGenfv = glTexGenfv; + qglTexGeni = dllTexGeni = glTexGeni; + qglTexGeniv = dllTexGeniv = glTexGeniv; + qglTexImage1D = dllTexImage1D = glTexImage1D; + qglTexImage2D = dllTexImage2D = glTexImage2D; + qglTexParameterf = dllTexParameterf = glTexParameterf; + qglTexParameterfv = dllTexParameterfv = glTexParameterfv; + qglTexParameteri = dllTexParameteri = glTexParameteri; + qglTexParameteriv = dllTexParameteriv = glTexParameteriv; + qglTexSubImage1D = dllTexSubImage1D = glTexSubImage1D; + qglTexSubImage2D = dllTexSubImage2D = glTexSubImage2D; + qglTranslated = dllTranslated = glTranslated; + qglTranslatef = dllTranslatef = glTranslatef; + qglVertex2d = dllVertex2d = glVertex2d; + qglVertex2dv = dllVertex2dv = glVertex2dv; + qglVertex2f = dllVertex2f = glVertex2f; + qglVertex2fv = dllVertex2fv = glVertex2fv; + qglVertex2i = dllVertex2i = glVertex2i; + qglVertex2iv = dllVertex2iv = glVertex2iv; + qglVertex2s = dllVertex2s = glVertex2s; + qglVertex2sv = dllVertex2sv = glVertex2sv; + qglVertex3d = dllVertex3d = glVertex3d; + qglVertex3dv = dllVertex3dv = glVertex3dv; + qglVertex3f = dllVertex3f = glVertex3f; + qglVertex3fv = dllVertex3fv = glVertex3fv; + qglVertex3i = dllVertex3i = glVertex3i; + qglVertex3iv = dllVertex3iv = glVertex3iv; + qglVertex3s = dllVertex3s = glVertex3s; + qglVertex3sv = dllVertex3sv = glVertex3sv; + qglVertex4d = dllVertex4d = glVertex4d; + qglVertex4dv = dllVertex4dv = glVertex4dv; + qglVertex4f = dllVertex4f = glVertex4f; + qglVertex4fv = dllVertex4fv = glVertex4fv; + qglVertex4i = dllVertex4i = glVertex4i; + qglVertex4iv = dllVertex4iv = glVertex4iv; + qglVertex4s = dllVertex4s = glVertex4s; + qglVertex4sv = dllVertex4sv = glVertex4sv; + qglVertexPointer = dllVertexPointer = glVertexPointer; + qglViewport = dllViewport = glViewport; + + qwglCopyContext = wglCopyContext; + qwglCreateContext = wglCreateContext; + qwglCreateLayerContext = wglCreateLayerContext; + qwglDeleteContext = wglDeleteContext; + qwglDescribeLayerPlane = wglDescribeLayerPlane; + qwglGetCurrentContext = wglGetCurrentContext; + qwglGetCurrentDC = wglGetCurrentDC; + qwglGetLayerPaletteEntries = wglGetLayerPaletteEntries; + qwglGetProcAddress = wglGetProcAddress; + qwglMakeCurrent = wglMakeCurrent; + qwglRealizeLayerPalette = wglRealizeLayerPalette; + qwglSetLayerPaletteEntries = wglSetLayerPaletteEntries; + qwglShareLists = wglShareLists; + qwglSwapLayerBuffers = wglSwapLayerBuffers; + qwglUseFontBitmaps = wglUseFontBitmapsA; + qwglUseFontOutlines = wglUseFontOutlinesA; + + qwglChoosePixelFormat = ChoosePixelFormat; + qwglDescribePixelFormat = DescribePixelFormat; + qwglGetPixelFormat = GetPixelFormat; + qwglSetPixelFormat = SetPixelFormat; + qwglSwapBuffers = SwapBuffers; + + qglActiveTextureARB = 0; + qglClientActiveTextureARB = 0; + qglMultiTexCoord2fARB = 0; + + return true; +} + + +/* +================== +GLimp_EnableLogging + +================== +*/ +void GLimp_EnableLogging( bool enable ) { + static bool isEnabled; + static int initialFrames; + static char ospath[ MAX_OSPATH ]; + + // return if we're already active + if ( isEnabled && enable ) { + // decrement log counter and stop if it has reached 0 + r_logFile.SetInteger( r_logFile.GetInteger() - 1 ); + if ( r_logFile.GetInteger() ) { + return; + } + common->Printf( "closing logfile '%s' after %i frames.\n", ospath, initialFrames ); + enable = false; + + fclose( tr.logFile ); + tr.logFile = NULL; + + } + + // return if we're already disabled + if ( !enable && !isEnabled ) { + return; + } + + isEnabled = enable; + + if ( enable ) { + if ( !tr.logFile ) { + struct tm *newtime; + ID_TIME_T aclock; + idStr qpath; + int i; + const char *path; + + initialFrames = r_logFile.GetInteger(); + + // scan for an unused filename + for ( i = 0 ; i < 9999 ; i++ ) { + sprintf( qpath, "renderlog_%i.txt", i ); + if ( fileSystem->ReadFile( qpath, NULL, NULL ) == -1 ) { + break; // use this name + } + } + + path = fileSystem->RelativePathToOSPath( qpath, "fs_savepath" ); + idStr::Copynz( ospath, path, sizeof( ospath ) ); + tr.logFile = fopen( ospath, "wt" ); + + // write the time out to the top of the file + time( &aclock ); + newtime = localtime( &aclock ); + fprintf( tr.logFile, "// %s", asctime( newtime ) ); + fprintf( tr.logFile, "// %s\n\n", cvarSystem->GetCVarString( "si_version" ) ); + } + + qglAccum = logAccum; + qglAlphaFunc = logAlphaFunc; + qglAreTexturesResident = logAreTexturesResident; + qglArrayElement = logArrayElement; + qglBegin = logBegin; + qglBindTexture = logBindTexture; + qglBitmap = logBitmap; + qglBlendFunc = logBlendFunc; + qglCallList = logCallList; + qglCallLists = logCallLists; + qglClear = logClear; + qglClearAccum = logClearAccum; + qglClearColor = logClearColor; + qglClearDepth = logClearDepth; + qglClearIndex = logClearIndex; + qglClearStencil = logClearStencil; + qglClipPlane = logClipPlane; + qglColor3b = logColor3b; + qglColor3bv = logColor3bv; + qglColor3d = logColor3d; + qglColor3dv = logColor3dv; + qglColor3f = logColor3f; + qglColor3fv = logColor3fv; + qglColor3i = logColor3i; + qglColor3iv = logColor3iv; + qglColor3s = logColor3s; + qglColor3sv = logColor3sv; + qglColor3ub = logColor3ub; + qglColor3ubv = logColor3ubv; + qglColor3ui = logColor3ui; + qglColor3uiv = logColor3uiv; + qglColor3us = logColor3us; + qglColor3usv = logColor3usv; + qglColor4b = logColor4b; + qglColor4bv = logColor4bv; + qglColor4d = logColor4d; + qglColor4dv = logColor4dv; + qglColor4f = logColor4f; + qglColor4fv = logColor4fv; + qglColor4i = logColor4i; + qglColor4iv = logColor4iv; + qglColor4s = logColor4s; + qglColor4sv = logColor4sv; + qglColor4ub = logColor4ub; + qglColor4ubv = logColor4ubv; + qglColor4ui = logColor4ui; + qglColor4uiv = logColor4uiv; + qglColor4us = logColor4us; + qglColor4usv = logColor4usv; + qglColorMask = logColorMask; + qglColorMaterial = logColorMaterial; + qglColorPointer = logColorPointer; + qglCopyPixels = logCopyPixels; + qglCopyTexImage1D = logCopyTexImage1D; + qglCopyTexImage2D = logCopyTexImage2D; + qglCopyTexSubImage1D = logCopyTexSubImage1D; + qglCopyTexSubImage2D = logCopyTexSubImage2D; + qglCullFace = logCullFace; + qglDeleteLists = logDeleteLists ; + qglDeleteTextures = logDeleteTextures ; + qglDepthFunc = logDepthFunc ; + qglDepthMask = logDepthMask ; + qglDepthRange = logDepthRange ; + qglDisable = logDisable ; + qglDisableClientState = logDisableClientState ; + qglDrawArrays = logDrawArrays ; + qglDrawBuffer = logDrawBuffer ; + qglDrawElements = logDrawElements ; + qglDrawPixels = logDrawPixels ; + qglEdgeFlag = logEdgeFlag ; + qglEdgeFlagPointer = logEdgeFlagPointer ; + qglEdgeFlagv = logEdgeFlagv ; + qglEnable = logEnable ; + qglEnableClientState = logEnableClientState ; + qglEnd = logEnd ; + qglEndList = logEndList ; + qglEvalCoord1d = logEvalCoord1d ; + qglEvalCoord1dv = logEvalCoord1dv ; + qglEvalCoord1f = logEvalCoord1f ; + qglEvalCoord1fv = logEvalCoord1fv ; + qglEvalCoord2d = logEvalCoord2d ; + qglEvalCoord2dv = logEvalCoord2dv ; + qglEvalCoord2f = logEvalCoord2f ; + qglEvalCoord2fv = logEvalCoord2fv ; + qglEvalMesh1 = logEvalMesh1 ; + qglEvalMesh2 = logEvalMesh2 ; + qglEvalPoint1 = logEvalPoint1 ; + qglEvalPoint2 = logEvalPoint2 ; + qglFeedbackBuffer = logFeedbackBuffer ; + qglFinish = logFinish ; + qglFlush = logFlush ; + qglFogf = logFogf ; + qglFogfv = logFogfv ; + qglFogi = logFogi ; + qglFogiv = logFogiv ; + qglFrontFace = logFrontFace ; + qglFrustum = logFrustum ; + qglGenLists = logGenLists ; + qglGenTextures = logGenTextures ; + qglGetBooleanv = logGetBooleanv ; + qglGetClipPlane = logGetClipPlane ; + qglGetDoublev = logGetDoublev ; + qglGetError = logGetError ; + qglGetFloatv = logGetFloatv ; + qglGetIntegerv = logGetIntegerv ; + qglGetLightfv = logGetLightfv ; + qglGetLightiv = logGetLightiv ; + qglGetMapdv = logGetMapdv ; + qglGetMapfv = logGetMapfv ; + qglGetMapiv = logGetMapiv ; + qglGetMaterialfv = logGetMaterialfv ; + qglGetMaterialiv = logGetMaterialiv ; + qglGetPixelMapfv = logGetPixelMapfv ; + qglGetPixelMapuiv = logGetPixelMapuiv ; + qglGetPixelMapusv = logGetPixelMapusv ; + qglGetPointerv = logGetPointerv ; + qglGetPolygonStipple = logGetPolygonStipple ; + qglGetString = logGetString ; + qglGetTexEnvfv = logGetTexEnvfv ; + qglGetTexEnviv = logGetTexEnviv ; + qglGetTexGendv = logGetTexGendv ; + qglGetTexGenfv = logGetTexGenfv ; + qglGetTexGeniv = logGetTexGeniv ; + qglGetTexImage = logGetTexImage ; + qglGetTexLevelParameterfv = logGetTexLevelParameterfv ; + qglGetTexLevelParameteriv = logGetTexLevelParameteriv ; + qglGetTexParameterfv = logGetTexParameterfv ; + qglGetTexParameteriv = logGetTexParameteriv ; + qglHint = logHint ; + qglIndexMask = logIndexMask ; + qglIndexPointer = logIndexPointer ; + qglIndexd = logIndexd ; + qglIndexdv = logIndexdv ; + qglIndexf = logIndexf ; + qglIndexfv = logIndexfv ; + qglIndexi = logIndexi ; + qglIndexiv = logIndexiv ; + qglIndexs = logIndexs ; + qglIndexsv = logIndexsv ; + qglIndexub = logIndexub ; + qglIndexubv = logIndexubv ; + qglInitNames = logInitNames ; + qglInterleavedArrays = logInterleavedArrays ; + qglIsEnabled = logIsEnabled ; + qglIsList = logIsList ; + qglIsTexture = logIsTexture ; + qglLightModelf = logLightModelf ; + qglLightModelfv = logLightModelfv ; + qglLightModeli = logLightModeli ; + qglLightModeliv = logLightModeliv ; + qglLightf = logLightf ; + qglLightfv = logLightfv ; + qglLighti = logLighti ; + qglLightiv = logLightiv ; + qglLineStipple = logLineStipple ; + qglLineWidth = logLineWidth ; + qglListBase = logListBase ; + qglLoadIdentity = logLoadIdentity ; + qglLoadMatrixd = logLoadMatrixd ; + qglLoadMatrixf = logLoadMatrixf ; + qglLoadName = logLoadName ; + qglLogicOp = logLogicOp ; + qglMap1d = logMap1d ; + qglMap1f = logMap1f ; + qglMap2d = logMap2d ; + qglMap2f = logMap2f ; + qglMapGrid1d = logMapGrid1d ; + qglMapGrid1f = logMapGrid1f ; + qglMapGrid2d = logMapGrid2d ; + qglMapGrid2f = logMapGrid2f ; + qglMaterialf = logMaterialf ; + qglMaterialfv = logMaterialfv ; + qglMateriali = logMateriali ; + qglMaterialiv = logMaterialiv ; + qglMatrixMode = logMatrixMode ; + qglMultMatrixd = logMultMatrixd ; + qglMultMatrixf = logMultMatrixf ; + qglNewList = logNewList ; + qglNormal3b = logNormal3b ; + qglNormal3bv = logNormal3bv ; + qglNormal3d = logNormal3d ; + qglNormal3dv = logNormal3dv ; + qglNormal3f = logNormal3f ; + qglNormal3fv = logNormal3fv ; + qglNormal3i = logNormal3i ; + qglNormal3iv = logNormal3iv ; + qglNormal3s = logNormal3s ; + qglNormal3sv = logNormal3sv ; + qglNormalPointer = logNormalPointer ; + qglOrtho = logOrtho ; + qglPassThrough = logPassThrough ; + qglPixelMapfv = logPixelMapfv ; + qglPixelMapuiv = logPixelMapuiv ; + qglPixelMapusv = logPixelMapusv ; + qglPixelStoref = logPixelStoref ; + qglPixelStorei = logPixelStorei ; + qglPixelTransferf = logPixelTransferf ; + qglPixelTransferi = logPixelTransferi ; + qglPixelZoom = logPixelZoom ; + qglPointSize = logPointSize ; + qglPolygonMode = logPolygonMode ; + qglPolygonOffset = logPolygonOffset ; + qglPolygonStipple = logPolygonStipple ; + qglPopAttrib = logPopAttrib ; + qglPopClientAttrib = logPopClientAttrib ; + qglPopMatrix = logPopMatrix ; + qglPopName = logPopName ; + qglPrioritizeTextures = logPrioritizeTextures ; + qglPushAttrib = logPushAttrib ; + qglPushClientAttrib = logPushClientAttrib ; + qglPushMatrix = logPushMatrix ; + qglPushName = logPushName ; + qglRasterPos2d = logRasterPos2d ; + qglRasterPos2dv = logRasterPos2dv ; + qglRasterPos2f = logRasterPos2f ; + qglRasterPos2fv = logRasterPos2fv ; + qglRasterPos2i = logRasterPos2i ; + qglRasterPos2iv = logRasterPos2iv ; + qglRasterPos2s = logRasterPos2s ; + qglRasterPos2sv = logRasterPos2sv ; + qglRasterPos3d = logRasterPos3d ; + qglRasterPos3dv = logRasterPos3dv ; + qglRasterPos3f = logRasterPos3f ; + qglRasterPos3fv = logRasterPos3fv ; + qglRasterPos3i = logRasterPos3i ; + qglRasterPos3iv = logRasterPos3iv ; + qglRasterPos3s = logRasterPos3s ; + qglRasterPos3sv = logRasterPos3sv ; + qglRasterPos4d = logRasterPos4d ; + qglRasterPos4dv = logRasterPos4dv ; + qglRasterPos4f = logRasterPos4f ; + qglRasterPos4fv = logRasterPos4fv ; + qglRasterPos4i = logRasterPos4i ; + qglRasterPos4iv = logRasterPos4iv ; + qglRasterPos4s = logRasterPos4s ; + qglRasterPos4sv = logRasterPos4sv ; + qglReadBuffer = logReadBuffer ; + qglReadPixels = logReadPixels ; + qglRectd = logRectd ; + qglRectdv = logRectdv ; + qglRectf = logRectf ; + qglRectfv = logRectfv ; + qglRecti = logRecti ; + qglRectiv = logRectiv ; + qglRects = logRects ; + qglRectsv = logRectsv ; + qglRenderMode = logRenderMode ; + qglRotated = logRotated ; + qglRotatef = logRotatef ; + qglScaled = logScaled ; + qglScalef = logScalef ; + qglScissor = logScissor ; + qglSelectBuffer = logSelectBuffer ; + qglShadeModel = logShadeModel ; + qglStencilFunc = logStencilFunc ; + qglStencilMask = logStencilMask ; + qglStencilOp = logStencilOp ; + qglTexCoord1d = logTexCoord1d ; + qglTexCoord1dv = logTexCoord1dv ; + qglTexCoord1f = logTexCoord1f ; + qglTexCoord1fv = logTexCoord1fv ; + qglTexCoord1i = logTexCoord1i ; + qglTexCoord1iv = logTexCoord1iv ; + qglTexCoord1s = logTexCoord1s ; + qglTexCoord1sv = logTexCoord1sv ; + qglTexCoord2d = logTexCoord2d ; + qglTexCoord2dv = logTexCoord2dv ; + qglTexCoord2f = logTexCoord2f ; + qglTexCoord2fv = logTexCoord2fv ; + qglTexCoord2i = logTexCoord2i ; + qglTexCoord2iv = logTexCoord2iv ; + qglTexCoord2s = logTexCoord2s ; + qglTexCoord2sv = logTexCoord2sv ; + qglTexCoord3d = logTexCoord3d ; + qglTexCoord3dv = logTexCoord3dv ; + qglTexCoord3f = logTexCoord3f ; + qglTexCoord3fv = logTexCoord3fv ; + qglTexCoord3i = logTexCoord3i ; + qglTexCoord3iv = logTexCoord3iv ; + qglTexCoord3s = logTexCoord3s ; + qglTexCoord3sv = logTexCoord3sv ; + qglTexCoord4d = logTexCoord4d ; + qglTexCoord4dv = logTexCoord4dv ; + qglTexCoord4f = logTexCoord4f ; + qglTexCoord4fv = logTexCoord4fv ; + qglTexCoord4i = logTexCoord4i ; + qglTexCoord4iv = logTexCoord4iv ; + qglTexCoord4s = logTexCoord4s ; + qglTexCoord4sv = logTexCoord4sv ; + qglTexCoordPointer = logTexCoordPointer ; + qglTexEnvf = logTexEnvf ; + qglTexEnvfv = logTexEnvfv ; + qglTexEnvi = logTexEnvi ; + qglTexEnviv = logTexEnviv ; + qglTexGend = logTexGend ; + qglTexGendv = logTexGendv ; + qglTexGenf = logTexGenf ; + qglTexGenfv = logTexGenfv ; + qglTexGeni = logTexGeni ; + qglTexGeniv = logTexGeniv ; + qglTexImage1D = logTexImage1D ; + qglTexImage2D = logTexImage2D ; + qglTexParameterf = logTexParameterf ; + qglTexParameterfv = logTexParameterfv ; + qglTexParameteri = logTexParameteri ; + qglTexParameteriv = logTexParameteriv ; + qglTexSubImage1D = logTexSubImage1D ; + qglTexSubImage2D = logTexSubImage2D ; + qglTranslated = logTranslated ; + qglTranslatef = logTranslatef ; + qglVertex2d = logVertex2d ; + qglVertex2dv = logVertex2dv ; + qglVertex2f = logVertex2f ; + qglVertex2fv = logVertex2fv ; + qglVertex2i = logVertex2i ; + qglVertex2iv = logVertex2iv ; + qglVertex2s = logVertex2s ; + qglVertex2sv = logVertex2sv ; + qglVertex3d = logVertex3d ; + qglVertex3dv = logVertex3dv ; + qglVertex3f = logVertex3f ; + qglVertex3fv = logVertex3fv ; + qglVertex3i = logVertex3i ; + qglVertex3iv = logVertex3iv ; + qglVertex3s = logVertex3s ; + qglVertex3sv = logVertex3sv ; + qglVertex4d = logVertex4d ; + qglVertex4dv = logVertex4dv ; + qglVertex4f = logVertex4f ; + qglVertex4fv = logVertex4fv ; + qglVertex4i = logVertex4i ; + qglVertex4iv = logVertex4iv ; + qglVertex4s = logVertex4s ; + qglVertex4sv = logVertex4sv ; + qglVertexPointer = logVertexPointer ; + qglViewport = logViewport ; + } + else + { + qglAccum = dllAccum; + qglAlphaFunc = dllAlphaFunc; + qglAreTexturesResident = dllAreTexturesResident; + qglArrayElement = dllArrayElement; + qglBegin = dllBegin; + qglBindTexture = dllBindTexture; + qglBitmap = dllBitmap; + qglBlendFunc = dllBlendFunc; + qglCallList = dllCallList; + qglCallLists = dllCallLists; + qglClear = dllClear; + qglClearAccum = dllClearAccum; + qglClearColor = dllClearColor; + qglClearDepth = dllClearDepth; + qglClearIndex = dllClearIndex; + qglClearStencil = dllClearStencil; + qglClipPlane = dllClipPlane; + qglColor3b = dllColor3b; + qglColor3bv = dllColor3bv; + qglColor3d = dllColor3d; + qglColor3dv = dllColor3dv; + qglColor3f = dllColor3f; + qglColor3fv = dllColor3fv; + qglColor3i = dllColor3i; + qglColor3iv = dllColor3iv; + qglColor3s = dllColor3s; + qglColor3sv = dllColor3sv; + qglColor3ub = dllColor3ub; + qglColor3ubv = dllColor3ubv; + qglColor3ui = dllColor3ui; + qglColor3uiv = dllColor3uiv; + qglColor3us = dllColor3us; + qglColor3usv = dllColor3usv; + qglColor4b = dllColor4b; + qglColor4bv = dllColor4bv; + qglColor4d = dllColor4d; + qglColor4dv = dllColor4dv; + qglColor4f = dllColor4f; + qglColor4fv = dllColor4fv; + qglColor4i = dllColor4i; + qglColor4iv = dllColor4iv; + qglColor4s = dllColor4s; + qglColor4sv = dllColor4sv; + qglColor4ub = dllColor4ub; + qglColor4ubv = dllColor4ubv; + qglColor4ui = dllColor4ui; + qglColor4uiv = dllColor4uiv; + qglColor4us = dllColor4us; + qglColor4usv = dllColor4usv; + qglColorMask = dllColorMask; + qglColorMaterial = dllColorMaterial; + qglColorPointer = dllColorPointer; + qglCopyPixels = dllCopyPixels; + qglCopyTexImage1D = dllCopyTexImage1D; + qglCopyTexImage2D = dllCopyTexImage2D; + qglCopyTexSubImage1D = dllCopyTexSubImage1D; + qglCopyTexSubImage2D = dllCopyTexSubImage2D; + qglCullFace = dllCullFace; + qglDeleteLists = dllDeleteLists ; + qglDeleteTextures = dllDeleteTextures ; + qglDepthFunc = dllDepthFunc ; + qglDepthMask = dllDepthMask ; + qglDepthRange = dllDepthRange ; + qglDisable = dllDisable ; + qglDisableClientState = dllDisableClientState ; + qglDrawArrays = dllDrawArrays ; + qglDrawBuffer = dllDrawBuffer ; + qglDrawElements = dllDrawElements ; + qglDrawPixels = dllDrawPixels ; + qglEdgeFlag = dllEdgeFlag ; + qglEdgeFlagPointer = dllEdgeFlagPointer ; + qglEdgeFlagv = dllEdgeFlagv ; + qglEnable = dllEnable ; + qglEnableClientState = dllEnableClientState ; + qglEnd = dllEnd ; + qglEndList = dllEndList ; + qglEvalCoord1d = dllEvalCoord1d ; + qglEvalCoord1dv = dllEvalCoord1dv ; + qglEvalCoord1f = dllEvalCoord1f ; + qglEvalCoord1fv = dllEvalCoord1fv ; + qglEvalCoord2d = dllEvalCoord2d ; + qglEvalCoord2dv = dllEvalCoord2dv ; + qglEvalCoord2f = dllEvalCoord2f ; + qglEvalCoord2fv = dllEvalCoord2fv ; + qglEvalMesh1 = dllEvalMesh1 ; + qglEvalMesh2 = dllEvalMesh2 ; + qglEvalPoint1 = dllEvalPoint1 ; + qglEvalPoint2 = dllEvalPoint2 ; + qglFeedbackBuffer = dllFeedbackBuffer ; + qglFinish = dllFinish ; + qglFlush = dllFlush ; + qglFogf = dllFogf ; + qglFogfv = dllFogfv ; + qglFogi = dllFogi ; + qglFogiv = dllFogiv ; + qglFrontFace = dllFrontFace ; + qglFrustum = dllFrustum ; + qglGenLists = dllGenLists ; + qglGenTextures = dllGenTextures ; + qglGetBooleanv = dllGetBooleanv ; + qglGetClipPlane = dllGetClipPlane ; + qglGetDoublev = dllGetDoublev ; + qglGetError = dllGetError ; + qglGetFloatv = dllGetFloatv ; + qglGetIntegerv = dllGetIntegerv ; + qglGetLightfv = dllGetLightfv ; + qglGetLightiv = dllGetLightiv ; + qglGetMapdv = dllGetMapdv ; + qglGetMapfv = dllGetMapfv ; + qglGetMapiv = dllGetMapiv ; + qglGetMaterialfv = dllGetMaterialfv ; + qglGetMaterialiv = dllGetMaterialiv ; + qglGetPixelMapfv = dllGetPixelMapfv ; + qglGetPixelMapuiv = dllGetPixelMapuiv ; + qglGetPixelMapusv = dllGetPixelMapusv ; + qglGetPointerv = dllGetPointerv ; + qglGetPolygonStipple = dllGetPolygonStipple ; + qglGetString = dllGetString ; + qglGetTexEnvfv = dllGetTexEnvfv ; + qglGetTexEnviv = dllGetTexEnviv ; + qglGetTexGendv = dllGetTexGendv ; + qglGetTexGenfv = dllGetTexGenfv ; + qglGetTexGeniv = dllGetTexGeniv ; + qglGetTexImage = dllGetTexImage ; + qglGetTexLevelParameterfv = dllGetTexLevelParameterfv ; + qglGetTexLevelParameteriv = dllGetTexLevelParameteriv ; + qglGetTexParameterfv = dllGetTexParameterfv ; + qglGetTexParameteriv = dllGetTexParameteriv ; + qglHint = dllHint ; + qglIndexMask = dllIndexMask ; + qglIndexPointer = dllIndexPointer ; + qglIndexd = dllIndexd ; + qglIndexdv = dllIndexdv ; + qglIndexf = dllIndexf ; + qglIndexfv = dllIndexfv ; + qglIndexi = dllIndexi ; + qglIndexiv = dllIndexiv ; + qglIndexs = dllIndexs ; + qglIndexsv = dllIndexsv ; + qglIndexub = dllIndexub ; + qglIndexubv = dllIndexubv ; + qglInitNames = dllInitNames ; + qglInterleavedArrays = dllInterleavedArrays ; + qglIsEnabled = dllIsEnabled ; + qglIsList = dllIsList ; + qglIsTexture = dllIsTexture ; + qglLightModelf = dllLightModelf ; + qglLightModelfv = dllLightModelfv ; + qglLightModeli = dllLightModeli ; + qglLightModeliv = dllLightModeliv ; + qglLightf = dllLightf ; + qglLightfv = dllLightfv ; + qglLighti = dllLighti ; + qglLightiv = dllLightiv ; + qglLineStipple = dllLineStipple ; + qglLineWidth = dllLineWidth ; + qglListBase = dllListBase ; + qglLoadIdentity = dllLoadIdentity ; + qglLoadMatrixd = dllLoadMatrixd ; + qglLoadMatrixf = dllLoadMatrixf ; + qglLoadName = dllLoadName ; + qglLogicOp = dllLogicOp ; + qglMap1d = dllMap1d ; + qglMap1f = dllMap1f ; + qglMap2d = dllMap2d ; + qglMap2f = dllMap2f ; + qglMapGrid1d = dllMapGrid1d ; + qglMapGrid1f = dllMapGrid1f ; + qglMapGrid2d = dllMapGrid2d ; + qglMapGrid2f = dllMapGrid2f ; + qglMaterialf = dllMaterialf ; + qglMaterialfv = dllMaterialfv ; + qglMateriali = dllMateriali ; + qglMaterialiv = dllMaterialiv ; + qglMatrixMode = dllMatrixMode ; + qglMultMatrixd = dllMultMatrixd ; + qglMultMatrixf = dllMultMatrixf ; + qglNewList = dllNewList ; + qglNormal3b = dllNormal3b ; + qglNormal3bv = dllNormal3bv ; + qglNormal3d = dllNormal3d ; + qglNormal3dv = dllNormal3dv ; + qglNormal3f = dllNormal3f ; + qglNormal3fv = dllNormal3fv ; + qglNormal3i = dllNormal3i ; + qglNormal3iv = dllNormal3iv ; + qglNormal3s = dllNormal3s ; + qglNormal3sv = dllNormal3sv ; + qglNormalPointer = dllNormalPointer ; + qglOrtho = dllOrtho ; + qglPassThrough = dllPassThrough ; + qglPixelMapfv = dllPixelMapfv ; + qglPixelMapuiv = dllPixelMapuiv ; + qglPixelMapusv = dllPixelMapusv ; + qglPixelStoref = dllPixelStoref ; + qglPixelStorei = dllPixelStorei ; + qglPixelTransferf = dllPixelTransferf ; + qglPixelTransferi = dllPixelTransferi ; + qglPixelZoom = dllPixelZoom ; + qglPointSize = dllPointSize ; + qglPolygonMode = dllPolygonMode ; + qglPolygonOffset = dllPolygonOffset ; + qglPolygonStipple = dllPolygonStipple ; + qglPopAttrib = dllPopAttrib ; + qglPopClientAttrib = dllPopClientAttrib ; + qglPopMatrix = dllPopMatrix ; + qglPopName = dllPopName ; + qglPrioritizeTextures = dllPrioritizeTextures ; + qglPushAttrib = dllPushAttrib ; + qglPushClientAttrib = dllPushClientAttrib ; + qglPushMatrix = dllPushMatrix ; + qglPushName = dllPushName ; + qglRasterPos2d = dllRasterPos2d ; + qglRasterPos2dv = dllRasterPos2dv ; + qglRasterPos2f = dllRasterPos2f ; + qglRasterPos2fv = dllRasterPos2fv ; + qglRasterPos2i = dllRasterPos2i ; + qglRasterPos2iv = dllRasterPos2iv ; + qglRasterPos2s = dllRasterPos2s ; + qglRasterPos2sv = dllRasterPos2sv ; + qglRasterPos3d = dllRasterPos3d ; + qglRasterPos3dv = dllRasterPos3dv ; + qglRasterPos3f = dllRasterPos3f ; + qglRasterPos3fv = dllRasterPos3fv ; + qglRasterPos3i = dllRasterPos3i ; + qglRasterPos3iv = dllRasterPos3iv ; + qglRasterPos3s = dllRasterPos3s ; + qglRasterPos3sv = dllRasterPos3sv ; + qglRasterPos4d = dllRasterPos4d ; + qglRasterPos4dv = dllRasterPos4dv ; + qglRasterPos4f = dllRasterPos4f ; + qglRasterPos4fv = dllRasterPos4fv ; + qglRasterPos4i = dllRasterPos4i ; + qglRasterPos4iv = dllRasterPos4iv ; + qglRasterPos4s = dllRasterPos4s ; + qglRasterPos4sv = dllRasterPos4sv ; + qglReadBuffer = dllReadBuffer ; + qglReadPixels = dllReadPixels ; + qglRectd = dllRectd ; + qglRectdv = dllRectdv ; + qglRectf = dllRectf ; + qglRectfv = dllRectfv ; + qglRecti = dllRecti ; + qglRectiv = dllRectiv ; + qglRects = dllRects ; + qglRectsv = dllRectsv ; + qglRenderMode = dllRenderMode ; + qglRotated = dllRotated ; + qglRotatef = dllRotatef ; + qglScaled = dllScaled ; + qglScalef = dllScalef ; + qglScissor = dllScissor ; + qglSelectBuffer = dllSelectBuffer ; + qglShadeModel = dllShadeModel ; + qglStencilFunc = dllStencilFunc ; + qglStencilMask = dllStencilMask ; + qglStencilOp = dllStencilOp ; + qglTexCoord1d = dllTexCoord1d ; + qglTexCoord1dv = dllTexCoord1dv ; + qglTexCoord1f = dllTexCoord1f ; + qglTexCoord1fv = dllTexCoord1fv ; + qglTexCoord1i = dllTexCoord1i ; + qglTexCoord1iv = dllTexCoord1iv ; + qglTexCoord1s = dllTexCoord1s ; + qglTexCoord1sv = dllTexCoord1sv ; + qglTexCoord2d = dllTexCoord2d ; + qglTexCoord2dv = dllTexCoord2dv ; + qglTexCoord2f = dllTexCoord2f ; + qglTexCoord2fv = dllTexCoord2fv ; + qglTexCoord2i = dllTexCoord2i ; + qglTexCoord2iv = dllTexCoord2iv ; + qglTexCoord2s = dllTexCoord2s ; + qglTexCoord2sv = dllTexCoord2sv ; + qglTexCoord3d = dllTexCoord3d ; + qglTexCoord3dv = dllTexCoord3dv ; + qglTexCoord3f = dllTexCoord3f ; + qglTexCoord3fv = dllTexCoord3fv ; + qglTexCoord3i = dllTexCoord3i ; + qglTexCoord3iv = dllTexCoord3iv ; + qglTexCoord3s = dllTexCoord3s ; + qglTexCoord3sv = dllTexCoord3sv ; + qglTexCoord4d = dllTexCoord4d ; + qglTexCoord4dv = dllTexCoord4dv ; + qglTexCoord4f = dllTexCoord4f ; + qglTexCoord4fv = dllTexCoord4fv ; + qglTexCoord4i = dllTexCoord4i ; + qglTexCoord4iv = dllTexCoord4iv ; + qglTexCoord4s = dllTexCoord4s ; + qglTexCoord4sv = dllTexCoord4sv ; + qglTexCoordPointer = dllTexCoordPointer ; + qglTexEnvf = dllTexEnvf ; + qglTexEnvfv = dllTexEnvfv ; + qglTexEnvi = dllTexEnvi ; + qglTexEnviv = dllTexEnviv ; + qglTexGend = dllTexGend ; + qglTexGendv = dllTexGendv ; + qglTexGenf = dllTexGenf ; + qglTexGenfv = dllTexGenfv ; + qglTexGeni = dllTexGeni ; + qglTexGeniv = dllTexGeniv ; + qglTexImage1D = dllTexImage1D ; + qglTexImage2D = dllTexImage2D ; + qglTexParameterf = dllTexParameterf ; + qglTexParameterfv = dllTexParameterfv ; + qglTexParameteri = dllTexParameteri ; + qglTexParameteriv = dllTexParameteriv ; + qglTexSubImage1D = dllTexSubImage1D ; + qglTexSubImage2D = dllTexSubImage2D ; + qglTranslated = dllTranslated ; + qglTranslatef = dllTranslatef ; + qglVertex2d = dllVertex2d ; + qglVertex2dv = dllVertex2dv ; + qglVertex2f = dllVertex2f ; + qglVertex2fv = dllVertex2fv ; + qglVertex2i = dllVertex2i ; + qglVertex2iv = dllVertex2iv ; + qglVertex2s = dllVertex2s ; + qglVertex2sv = dllVertex2sv ; + qglVertex3d = dllVertex3d ; + qglVertex3dv = dllVertex3dv ; + qglVertex3f = dllVertex3f ; + qglVertex3fv = dllVertex3fv ; + qglVertex3i = dllVertex3i ; + qglVertex3iv = dllVertex3iv ; + qglVertex3s = dllVertex3s ; + qglVertex3sv = dllVertex3sv ; + qglVertex4d = dllVertex4d ; + qglVertex4dv = dllVertex4dv ; + qglVertex4f = dllVertex4f ; + qglVertex4fv = dllVertex4fv ; + qglVertex4i = dllVertex4i ; + qglVertex4iv = dllVertex4iv ; + qglVertex4s = dllVertex4s ; + qglVertex4sv = dllVertex4sv ; + qglVertexPointer = dllVertexPointer ; + qglViewport = dllViewport ; + } +} diff --git a/sys/win32/win_shared.cpp b/sys/win32/win_shared.cpp new file mode 100644 index 000000000..1eb9bb9dc --- /dev/null +++ b/sys/win32/win_shared.cpp @@ -0,0 +1,769 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "win_local.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ID_DEDICATED +#include +#include +#include + +#pragma comment (lib, "wbemuuid.lib") +#endif + +/* +================ +Sys_Milliseconds +================ +*/ +int Sys_Milliseconds( void ) { + int sys_curtime; + static int sys_timeBase; + static bool initialized = false; + + if ( !initialized ) { + sys_timeBase = timeGetTime(); + initialized = true; + } + sys_curtime = timeGetTime() - sys_timeBase; + + return sys_curtime; +} + +/* +================ +Sys_GetSystemRam + + returns amount of physical memory in MB +================ +*/ +int Sys_GetSystemRam( void ) { + MEMORYSTATUSEX statex; + statex.dwLength = sizeof ( statex ); + GlobalMemoryStatusEx (&statex); + int physRam = statex.ullTotalPhys / ( 1024 * 1024 ); + // HACK: For some reason, ullTotalPhys is sometimes off by a meg or two, so we round up to the nearest 16 megs + physRam = ( physRam + 8 ) & ~15; + return physRam; +} + + +/* +================ +Sys_GetDriveFreeSpace +returns in megabytes +================ +*/ +int Sys_GetDriveFreeSpace( const char *path ) { + DWORDLONG lpFreeBytesAvailable; + DWORDLONG lpTotalNumberOfBytes; + DWORDLONG lpTotalNumberOfFreeBytes; + int ret = 26; + //FIXME: see why this is failing on some machines + if ( ::GetDiskFreeSpaceEx( path, (PULARGE_INTEGER)&lpFreeBytesAvailable, (PULARGE_INTEGER)&lpTotalNumberOfBytes, (PULARGE_INTEGER)&lpTotalNumberOfFreeBytes ) ) { + ret = ( double )( lpFreeBytesAvailable ) / ( 1024.0 * 1024.0 ); + } + return ret; +} + + +/* +================ +Sys_GetVideoRam +returns in megabytes +================ +*/ +int Sys_GetVideoRam( void ) { +#ifdef ID_DEDICATED + return 0; +#else + unsigned int retSize = 64; + + CComPtr spLoc = NULL; + HRESULT hr = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, ( LPVOID * ) &spLoc ); + if ( hr != S_OK || spLoc == NULL ) { + return retSize; + } + + CComBSTR bstrNamespace( _T( "\\\\.\\root\\CIMV2" ) ); + CComPtr spServices; + + // Connect to CIM + hr = spLoc->ConnectServer( bstrNamespace, NULL, NULL, 0, NULL, 0, 0, &spServices ); + if ( hr != WBEM_S_NO_ERROR ) { + return retSize; + } + + // Switch the security level to IMPERSONATE so that provider will grant access to system-level objects. + hr = CoSetProxyBlanket( spServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); + if ( hr != S_OK ) { + return retSize; + } + + // Get the vid controller + CComPtr spEnumInst = NULL; + hr = spServices->CreateInstanceEnum( CComBSTR( "Win32_VideoController" ), WBEM_FLAG_SHALLOW, NULL, &spEnumInst ); + if ( hr != WBEM_S_NO_ERROR || spEnumInst == NULL ) { + return retSize; + } + + ULONG uNumOfInstances = 0; + CComPtr spInstance = NULL; + hr = spEnumInst->Next( 10000, 1, &spInstance, &uNumOfInstances ); + + if ( hr == S_OK && spInstance ) { + // Get properties from the object + CComVariant varSize; + hr = spInstance->Get( CComBSTR( _T( "AdapterRAM" ) ), 0, &varSize, 0, 0 ); + if ( hr == S_OK ) { + retSize = varSize.intVal / ( 1024 * 1024 ); + if ( retSize == 0 ) { + retSize = 64; + } + } + } + return retSize; +#endif +} + +/* +================ +Sys_GetCurrentMemoryStatus + + returns OS mem info + all values are in kB except the memoryload +================ +*/ +void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats ) { + MEMORYSTATUSEX statex; + unsigned __int64 work; + + memset( &statex, sizeof( statex ), 0 ); + statex.dwLength = sizeof( statex ); + GlobalMemoryStatusEx( &statex ); + + memset( &stats, 0, sizeof( stats ) ); + + stats.memoryLoad = statex.dwMemoryLoad; + + work = statex.ullTotalPhys >> 20; + stats.totalPhysical = *(int*)&work; + + work = statex.ullAvailPhys >> 20; + stats.availPhysical = *(int*)&work; + + work = statex.ullAvailPageFile >> 20; + stats.availPageFile = *(int*)&work; + + work = statex.ullTotalPageFile >> 20; + stats.totalPageFile = *(int*)&work; + + work = statex.ullTotalVirtual >> 20; + stats.totalVirtual = *(int*)&work; + + work = statex.ullAvailVirtual >> 20; + stats.availVirtual = *(int*)&work; + + work = statex.ullAvailExtendedVirtual >> 20; + stats.availExtendedVirtual = *(int*)&work; +} + +/* +================ +Sys_LockMemory +================ +*/ +bool Sys_LockMemory( void *ptr, int bytes ) { + return ( VirtualLock( ptr, (SIZE_T)bytes ) != FALSE ); +} + +/* +================ +Sys_UnlockMemory +================ +*/ +bool Sys_UnlockMemory( void *ptr, int bytes ) { + return ( VirtualUnlock( ptr, (SIZE_T)bytes ) != FALSE ); +} + +/* +================ +Sys_SetPhysicalWorkMemory +================ +*/ +void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes ) { + ::SetProcessWorkingSetSize( GetCurrentProcess(), minBytes, maxBytes ); +} + +/* +================ +Sys_GetCurrentUser +================ +*/ +char *Sys_GetCurrentUser( void ) { + static char s_userName[1024]; + unsigned long size = sizeof( s_userName ); + + + if ( !GetUserName( s_userName, &size ) ) { + strcpy( s_userName, "player" ); + } + + if ( !s_userName[0] ) { + strcpy( s_userName, "player" ); + } + + return s_userName; +} + + +/* +=============================================================================== + + Call stack + +=============================================================================== +*/ + + +#define PROLOGUE_SIGNATURE 0x00EC8B55 + +#include + +const int UNDECORATE_FLAGS = UNDNAME_NO_MS_KEYWORDS | + UNDNAME_NO_ACCESS_SPECIFIERS | + UNDNAME_NO_FUNCTION_RETURNS | + UNDNAME_NO_ALLOCATION_MODEL | + UNDNAME_NO_ALLOCATION_LANGUAGE | + UNDNAME_NO_MEMBER_TYPE; + +#if defined(_DEBUG) && 1 + +typedef struct symbol_s { + int address; + char * name; + struct symbol_s * next; +} symbol_t; + +typedef struct module_s { + int address; + char * name; + symbol_t * symbols; + struct module_s * next; +} module_t; + +module_t *modules; + +/* +================== +SkipRestOfLine +================== +*/ +void SkipRestOfLine( const char **ptr ) { + while( (**ptr) != '\0' && (**ptr) != '\n' && (**ptr) != '\r' ) { + (*ptr)++; + } + while( (**ptr) == '\n' || (**ptr) == '\r' ) { + (*ptr)++; + } +} + +/* +================== +SkipWhiteSpace +================== +*/ +void SkipWhiteSpace( const char **ptr ) { + while( (**ptr) == ' ' ) { + (*ptr)++; + } +} + +/* +================== +ParseHexNumber +================== +*/ +int ParseHexNumber( const char **ptr ) { + int n = 0; + while( (**ptr) >= '0' && (**ptr) <= '9' || (**ptr) >= 'a' && (**ptr) <= 'f' ) { + n <<= 4; + if ( **ptr >= '0' && **ptr <= '9' ) { + n |= ( (**ptr) - '0' ); + } else { + n |= 10 + ( (**ptr) - 'a' ); + } + (*ptr)++; + } + return n; +} + +/* +================== +Sym_Init +================== +*/ +void Sym_Init( long addr ) { + TCHAR moduleName[MAX_STRING_CHARS]; + MEMORY_BASIC_INFORMATION mbi; + + VirtualQuery( (void*)addr, &mbi, sizeof(mbi) ); + + GetModuleFileName( (HMODULE)mbi.AllocationBase, moduleName, sizeof( moduleName ) ); + + char *ext = moduleName + strlen( moduleName ); + while( ext > moduleName && *ext != '.' ) { + ext--; + } + if ( ext == moduleName ) { + strcat( moduleName, ".map" ); + } else { + strcpy( ext, ".map" ); + } + + module_t *module = (module_t *) malloc( sizeof( module_t ) ); + module->name = (char *) malloc( strlen( moduleName ) + 1 ); + strcpy( module->name, moduleName ); + module->address = (int)mbi.AllocationBase; + module->symbols = NULL; + module->next = modules; + modules = module; + + FILE *fp = fopen( moduleName, "rb" ); + if ( fp == NULL ) { + return; + } + + int pos = ftell( fp ); + fseek( fp, 0, SEEK_END ); + int length = ftell( fp ); + fseek( fp, pos, SEEK_SET ); + + char *text = (char *) malloc( length+1 ); + fread( text, 1, length, fp ); + text[length] = '\0'; + fclose( fp ); + + const char *ptr = text; + + // skip up to " Address" on a new line + while( *ptr != '\0' ) { + SkipWhiteSpace( &ptr ); + if ( idStr::Cmpn( ptr, "Address", 7 ) == 0 ) { + SkipRestOfLine( &ptr ); + break; + } + SkipRestOfLine( &ptr ); + } + + int symbolAddress; + int symbolLength; + char symbolName[MAX_STRING_CHARS]; + symbol_t *symbol; + + // parse symbols + while( *ptr != '\0' ) { + + SkipWhiteSpace( &ptr ); + + ParseHexNumber( &ptr ); + if ( *ptr == ':' ) { + ptr++; + } else { + break; + } + ParseHexNumber( &ptr ); + + SkipWhiteSpace( &ptr ); + + // parse symbol name + symbolLength = 0; + while( *ptr != '\0' && *ptr != ' ' ) { + symbolName[symbolLength++] = *ptr++; + if ( symbolLength >= sizeof( symbolName ) - 1 ) { + break; + } + } + symbolName[symbolLength++] = '\0'; + + SkipWhiteSpace( &ptr ); + + // parse symbol address + symbolAddress = ParseHexNumber( &ptr ); + + SkipRestOfLine( &ptr ); + + symbol = (symbol_t *) malloc( sizeof( symbol_t ) ); + symbol->name = (char *) malloc( symbolLength ); + strcpy( symbol->name, symbolName ); + symbol->address = symbolAddress; + symbol->next = module->symbols; + module->symbols = symbol; + } + + free( text ); +} + +/* +================== +Sym_Shutdown +================== +*/ +void Sym_Shutdown( void ) { + module_t *m; + symbol_t *s; + + for ( m = modules; m != NULL; m = modules ) { + modules = m->next; + for ( s = m->symbols; s != NULL; s = m->symbols ) { + m->symbols = s->next; + free( s->name ); + free( s ); + } + free( m->name ); + free( m ); + } + modules = NULL; +} + +/* +================== +Sym_GetFuncInfo +================== +*/ +void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) { + MEMORY_BASIC_INFORMATION mbi; + module_t *m; + symbol_t *s; + + VirtualQuery( (void*)addr, &mbi, sizeof(mbi) ); + + for ( m = modules; m != NULL; m = m->next ) { + if ( m->address == (int) mbi.AllocationBase ) { + break; + } + } + if ( !m ) { + Sym_Init( addr ); + m = modules; + } + + for ( s = m->symbols; s != NULL; s = s->next ) { + if ( s->address == addr ) { + + char undName[MAX_STRING_CHARS]; + if ( UnDecorateSymbolName( s->name, undName, sizeof(undName), UNDECORATE_FLAGS ) ) { + funcName = undName; + } else { + funcName = s->name; + } + for ( int i = 0; i < funcName.Length(); i++ ) { + if ( funcName[i] == '(' ) { + funcName.CapLength( i ); + break; + } + } + module = m->name; + return; + } + } + + sprintf( funcName, "0x%08x", addr ); + module = ""; +} + +#elif defined(_DEBUG) + +DWORD lastAllocationBase = -1; +HANDLE processHandle; +idStr lastModule; + +/* +================== +Sym_Init +================== +*/ +void Sym_Init( long addr ) { + TCHAR moduleName[MAX_STRING_CHARS]; + TCHAR modShortNameBuf[MAX_STRING_CHARS]; + MEMORY_BASIC_INFORMATION mbi; + + if ( lastAllocationBase != -1 ) { + Sym_Shutdown(); + } + + VirtualQuery( (void*)addr, &mbi, sizeof(mbi) ); + + GetModuleFileName( (HMODULE)mbi.AllocationBase, moduleName, sizeof( moduleName ) ); + _splitpath( moduleName, NULL, NULL, modShortNameBuf, NULL ); + lastModule = modShortNameBuf; + + processHandle = GetCurrentProcess(); + if ( !SymInitialize( processHandle, NULL, FALSE ) ) { + return; + } + if ( !SymLoadModule( processHandle, NULL, moduleName, NULL, (DWORD)mbi.AllocationBase, 0 ) ) { + SymCleanup( processHandle ); + return; + } + + SymSetOptions( SymGetOptions() & ~SYMOPT_UNDNAME ); + + lastAllocationBase = (DWORD) mbi.AllocationBase; +} + +/* +================== +Sym_Shutdown +================== +*/ +void Sym_Shutdown( void ) { + SymUnloadModule( GetCurrentProcess(), lastAllocationBase ); + SymCleanup( GetCurrentProcess() ); + lastAllocationBase = -1; +} + +/* +================== +Sym_GetFuncInfo +================== +*/ +void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) { + MEMORY_BASIC_INFORMATION mbi; + + VirtualQuery( (void*)addr, &mbi, sizeof(mbi) ); + + if ( (DWORD) mbi.AllocationBase != lastAllocationBase ) { + Sym_Init( addr ); + } + + BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + MAX_STRING_CHARS ]; + PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)&symbolBuffer[0]; + pSymbol->SizeOfStruct = sizeof(symbolBuffer); + pSymbol->MaxNameLength = 1023; + pSymbol->Address = 0; + pSymbol->Flags = 0; + pSymbol->Size =0; + + DWORD symDisplacement = 0; + if ( SymGetSymFromAddr( processHandle, addr, &symDisplacement, pSymbol ) ) { + // clean up name, throwing away decorations that don't affect uniqueness + char undName[MAX_STRING_CHARS]; + if ( UnDecorateSymbolName( pSymbol->Name, undName, sizeof(undName), UNDECORATE_FLAGS ) ) { + funcName = undName; + } else { + funcName = pSymbol->Name; + } + module = lastModule; + } + else { + LPVOID lpMsgBuf; + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + LocalFree( lpMsgBuf ); + + // Couldn't retrieve symbol (no debug info?, can't load dbghelp.dll?) + sprintf( funcName, "0x%08x", addr ); + module = ""; + } +} + +#else + +/* +================== +Sym_Init +================== +*/ +void Sym_Init( long addr ) { +} + +/* +================== +Sym_Shutdown +================== +*/ +void Sym_Shutdown( void ) { +} + +/* +================== +Sym_GetFuncInfo +================== +*/ +void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) { + module = ""; + sprintf( funcName, "0x%08x", addr ); +} + +#endif + +/* +================== +GetFuncAddr +================== +*/ +address_t GetFuncAddr( address_t midPtPtr ) { + long temp; + do { + temp = (long)(*(long*)midPtPtr); + if ( (temp&0x00FFFFFF) == PROLOGUE_SIGNATURE ) { + break; + } + midPtPtr--; + } while(true); + + return midPtPtr; +} + +/* +================== +GetCallerAddr +================== +*/ +address_t GetCallerAddr( long _ebp ) { + long midPtPtr; + long res = 0; + + __asm { + mov eax, _ebp + mov ecx, [eax] // check for end of stack frames list + test ecx, ecx // check for zero stack frame + jz label + mov eax, [eax+4] // get the ret address + test eax, eax // check for zero return address + jz label + mov midPtPtr, eax + } + res = GetFuncAddr( midPtPtr ); +label: + return res; +} + +/* +================== +Sys_GetCallStack + + use /Oy option +================== +*/ +void Sys_GetCallStack( address_t *callStack, const int callStackSize ) { +#if 1 //def _DEBUG + int i; + long m_ebp; + + __asm { + mov eax, ebp + mov m_ebp, eax + } + // skip last two functions + m_ebp = *((long*)m_ebp); + m_ebp = *((long*)m_ebp); + // list functions + for ( i = 0; i < callStackSize; i++ ) { + callStack[i] = GetCallerAddr( m_ebp ); + if ( callStack[i] == 0 ) { + break; + } + m_ebp = *((long*)m_ebp); + } +#else + int i = 0; +#endif + while( i < callStackSize ) { + callStack[i++] = 0; + } +} + +/* +================== +Sys_GetCallStackStr +================== +*/ +const char *Sys_GetCallStackStr( const address_t *callStack, const int callStackSize ) { + static char string[MAX_STRING_CHARS*2]; + int index, i; + idStr module, funcName; + + index = 0; + for ( i = callStackSize-1; i >= 0; i-- ) { + Sym_GetFuncInfo( callStack[i], module, funcName ); + index += sprintf( string+index, " -> %s", funcName.c_str() ); + } + return string; +} + +/* +================== +Sys_GetCallStackCurStr +================== +*/ +const char *Sys_GetCallStackCurStr( int depth ) { + address_t *callStack; + + callStack = (address_t *) _alloca( depth * sizeof( address_t ) ); + Sys_GetCallStack( callStack, depth ); + return Sys_GetCallStackStr( callStack, depth ); +} + +/* +================== +Sys_GetCallStackCurAddressStr +================== +*/ +const char *Sys_GetCallStackCurAddressStr( int depth ) { + static char string[MAX_STRING_CHARS*2]; + address_t *callStack; + int index, i; + + callStack = (address_t *) _alloca( depth * sizeof( address_t ) ); + Sys_GetCallStack( callStack, depth ); + + index = 0; + for ( i = depth-1; i >= 0; i-- ) { + index += sprintf( string+index, " -> 0x%08x", callStack[i] ); + } + return string; +} + +/* +================== +Sys_ShutdownSymbols +================== +*/ +void Sys_ShutdownSymbols( void ) { + Sym_Shutdown(); +} diff --git a/sys/win32/win_snd.cpp b/sys/win32/win_snd.cpp new file mode 100644 index 000000000..63aac0336 --- /dev/null +++ b/sys/win32/win_snd.cpp @@ -0,0 +1,838 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +// DirectX SDK +#include + +#include +#include +#include "../../sound/snd_local.h" +#include "win_local.h" + +#include "../../openal/idal.cpp" + +#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } +#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } + +class idAudioBufferWIN32 : public idAudioBuffer { +public: + idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile=NULL ); + ~idAudioBufferWIN32(); + + int FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger ); + + bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ); + bool Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ); + bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ); + + int Play( dword dwPriority=0, dword dwFlags=0 ); + int Stop( void ); + int Reset( void ); + bool IsSoundPlaying( void ); + void SetVolume( float x); + + idWaveFile* m_pWaveFile; +private: + LPDIRECTSOUNDBUFFER m_apDSBuffer; + dword m_dwDSBufferSize; + + int RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored ); +}; + +class idAudioHardwareWIN32 : public idAudioHardware { + +public: + idAudioHardwareWIN32(); + ~idAudioHardwareWIN32(); + + bool Initialize( ); + bool InitializeSpeakers( byte *buffer, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ); + + void SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ); + + int Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab ); + int Create( idAudioBuffer** ppSound, const char* strWaveFileName, dword dwCreationFlags = 0 ); + int CreateFromMemory( idAudioBufferWIN32** ppSound, byte* pbData, ulong ulDataSize, waveformatextensible_t *pwfx, dword dwCreationFlags = 0 ); + + bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ); + bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ); + bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ); + + int GetNumberOfSpeakers() { return numSpeakers; } + int GetMixBufferSize() { return MIXBUFFER_SAMPLES * blockAlign; } + + // WIN32 driver doesn't support write API + bool Flush( void ) { return true; } + void Write( bool ) { } + short* GetMixBuffer( void ) { return NULL; } + +private: + LPDIRECTSOUND m_pDS; + LPDIRECTSOUNDBUFFER pDSBPrimary; + idAudioBufferWIN32 *speakers; + + int numSpeakers; + int bitsPerSample; + int bufferSize; // allocate buffer handed over to DirectSound + int blockAlign; // channels * bits per sample / 8: sound frame size +}; + +idAudioHardware *idAudioHardware::Alloc() { return new idAudioHardwareWIN32; } +idAudioHardware::~idAudioHardware() {} + +/* +================ +idAudioHardwareWIN32::idAudioHardware +================ +*/ +idAudioHardwareWIN32::idAudioHardwareWIN32() { + m_pDS = NULL; + pDSBPrimary = NULL; + speakers = NULL; +} + +/* +================ +idAudioHardwareWIN32::~idAudioHardware +================ +*/ +idAudioHardwareWIN32::~idAudioHardwareWIN32() { + SAFE_DELETE( speakers ); + SAFE_RELEASE( pDSBPrimary ); + SAFE_RELEASE( m_pDS ); +} + +/* +=============== +idAudioHardwareWIN32::Initialize +=============== +*/ +bool idAudioHardwareWIN32::Initialize( void ) { + int hr; + + bufferSize = 0; + numSpeakers = 0; + blockAlign = 0; + + SAFE_RELEASE( m_pDS ); + + // Create IDirectSound using the primary sound device + if( FAILED( hr = DirectSoundCreate( NULL, &m_pDS, NULL ) )) { + return false; + } + + // Set primary buffer format + SetPrimaryBufferFormat( PRIMARYFREQ, 16, idSoundSystemLocal::s_numberOfSpeakers.GetInteger() ); + return true; +} + +/* +=============== +idAudioHardwareWIN32::InitializeSpeakers +=============== +*/ +bool idAudioHardwareWIN32::InitializeSpeakers( byte *speakerData, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) { + if ( dwSpeakers == 2 ) { + WAVEFORMATEXTENSIBLE wfx; + ZeroMemory( &wfx, sizeof(WAVEFORMATEXTENSIBLE) ); + wfx.Format.wFormatTag = WAVE_FORMAT_PCM; + wfx.Format.nChannels = 2; + wfx.Format.nSamplesPerSec = dwPrimaryFreq; + wfx.Format.wBitsPerSample = dwPrimaryBitRate; + wfx.Format.nBlockAlign = wfx.Format.wBitsPerSample / 8 * wfx.Format.nChannels; + wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; + wfx.Format.cbSize = sizeof(WAVEFORMATEX); + + CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&wfx ); + + common->Printf("sound: STEREO\n"); + } else { + WAVEFORMATEXTENSIBLE waveFormatPCMEx; + ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) ); + + waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + waveFormatPCMEx.Format.nChannels = 6; + waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq; + waveFormatPCMEx.Format.wBitsPerSample = dwPrimaryBitRate; + waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels; + waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign; + waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; + // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | + // SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | + // SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT + waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM + waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE); + waveFormatPCMEx.Samples.wValidBitsPerSample = 16; + + CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&waveFormatPCMEx ); + + common->Printf("sound: MULTICHANNEL\n"); + } + + if (!speakers) { + return false; + } + + speakers->Play(0,DSBPLAY_LOOPING); + + return true; +} + +/* +=============== +idAudioHardwareWIN32::SetPrimaryBufferFormat +Set primary buffer to a specified format +For example, to set the primary buffer format to 22kHz stereo, 16-bit +then: dwPrimaryChannels = 2 + dwPrimaryFreq = 22050, + dwPrimaryBitRate = 16 +=============== +*/ +void idAudioHardwareWIN32::SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) { + HRESULT hr; + + if( m_pDS == NULL ) { + return; + } + + ulong cfgSpeakers; + m_pDS->GetSpeakerConfig( &cfgSpeakers ); + + DSCAPS dscaps; + dscaps.dwSize = sizeof(DSCAPS); + m_pDS->GetCaps(&dscaps); + + if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { + return; + } + + // Get the primary buffer + DSBUFFERDESC dsbd; + ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + dsbd.dwBufferBytes = 0; + dsbd.lpwfxFormat = NULL; + + // Obtain write-primary cooperative level. + if( FAILED( hr = m_pDS->SetCooperativeLevel(win32.hWnd, DSSCL_PRIORITY ) ) ) { + DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr ); + return; + } + + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) { + return; + } + + if ( dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND) ) { + WAVEFORMATEXTENSIBLE waveFormatPCMEx; + ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) ); + + waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + waveFormatPCMEx.Format.nChannels = 6; + waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq; + waveFormatPCMEx.Format.wBitsPerSample = (WORD) dwPrimaryBitRate; + waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels; + waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign; + waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; + // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | + // SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | + // SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT + waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM + waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE); + waveFormatPCMEx.Samples.wValidBitsPerSample = 16; + + if( FAILED( hr = pDSBPrimary->SetFormat((WAVEFORMATEX*)&waveFormatPCMEx) ) ) { + DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr ); + return; + } + numSpeakers = 6; // force it to think 5.1 + blockAlign = waveFormatPCMEx.Format.nBlockAlign; + } else { + if (dwSpeakers == 6) { + common->Printf("sound: hardware reported unable to use multisound, defaulted to stereo\n"); + } + WAVEFORMATEX wfx; + ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 2; + wfx.nSamplesPerSec = dwPrimaryFreq; + wfx.wBitsPerSample = (WORD) dwPrimaryBitRate; + wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize = sizeof(WAVEFORMATEX); + + if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) { + return; + } + numSpeakers = 2; // force it to think stereo + blockAlign = wfx.nBlockAlign; + } + + byte *speakerData; + bufferSize = MIXBUFFER_SAMPLES * sizeof(word) * numSpeakers * ROOM_SLICES_IN_BUFFER; + speakerData = (byte *)Mem_Alloc( bufferSize ); + memset( speakerData, 0, bufferSize ); + + InitializeSpeakers( speakerData, bufferSize, dwPrimaryFreq, dwPrimaryBitRate, numSpeakers ); +} + +/* +=============== +idAudioHardwareWIN32::Create +=============== +*/ +int idAudioHardwareWIN32::Create( idAudioBuffer** ppSound, + const char* strWaveFileName, + dword dwCreationFlags ) { + int hr; + LPDIRECTSOUNDBUFFER apDSBuffer = NULL; + dword dwDSBufferSize = NULL; + idWaveFile* pWaveFile = NULL; + + if( m_pDS == NULL ) + return -1; + if( strWaveFileName == NULL || ppSound == NULL ) + return -1; + + pWaveFile = new idWaveFile(); + + pWaveFile->Open( strWaveFileName, NULL ); + + if( pWaveFile->GetOutputSize() == 0 ) { + // Wave is blank, so don't create it. + hr = E_FAIL; + goto LFail; + } + + // Make the DirectSound buffer the same size as the wav file + dwDSBufferSize = pWaveFile->GetOutputSize(); + + // Create the direct sound buffer, and only request the flags needed + // since each requires some overhead and limits if the buffer can + // be hardware accelerated + DSBUFFERDESC dsbd; + memset( &dsbd, 0, sizeof(DSBUFFERDESC) ); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = dwCreationFlags; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = GUID_NULL; + dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx; + + // DirectSound is only guarenteed to play PCM data. Other + // formats may or may not work depending the sound card driver. + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) ) + return -1; + + // Create the sound + *ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile ); + + pWaveFile->Close(); + + return 0; + +LFail: + // Cleanup + SAFE_DELETE( pWaveFile ); + return -1; +} + +/* +=============== +idAudioHardwareWIN32::Create +=============== +*/ +int idAudioHardwareWIN32::Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab ) { + int hr; + LPDIRECTSOUNDBUFFER apDSBuffer = NULL; + dword dwDSBufferSize = NULL; + + if( m_pDS == NULL ) + return -1; + + if( pWaveFile == NULL ) + return -1; + + *ppiab = NULL; + + if( pWaveFile->GetOutputSize() == 0 ) { + // Wave is blank, so don't create it. + hr = E_FAIL; + goto LFail; + } + + // Make the DirectSound buffer the same size as the wav file + dwDSBufferSize = pWaveFile->GetOutputSize(); + + // Create the direct sound buffer, and only request the flags needed + // since each requires some overhead and limits if the buffer can + // be hardware accelerated + DSBUFFERDESC dsbd; + memset( &dsbd, 0, sizeof(DSBUFFERDESC) ); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = 0; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = GUID_NULL; + dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx; + + // DirectSound is only guarenteed to play PCM data. Other + // formats may or may not work depending the sound card driver. + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) ) + return -1; + + // Create the sound + *ppiab = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile ); + + return 0; + +LFail: + // Cleanup + SAFE_DELETE( pWaveFile ); + return -1; +} + +//----------------------------------------------------------------------------- +// Name: idAudioHardwareWIN32::CreateFromMemory() +// Desc: +//----------------------------------------------------------------------------- +int idAudioHardwareWIN32::CreateFromMemory( idAudioBufferWIN32** ppSound, + byte* pbData, + ulong ulDataSize, + waveformatextensible_t* pwfx, + dword dwCreationFlags ) { + int hr; + LPDIRECTSOUNDBUFFER apDSBuffer = NULL; + dword dwDSBufferSize = NULL; + idWaveFile* pWaveFile = NULL; + + if( m_pDS == NULL ) + return -1; + if( pbData == NULL || ppSound == NULL ) + return -1; + + pWaveFile = new idWaveFile(); + + pWaveFile->OpenFromMemory( (short *)pbData, ulDataSize, (waveformatextensible_t *)pwfx); + + + // Make the DirectSound buffer the same size as the wav file + dwDSBufferSize = ulDataSize; + + // Create the direct sound buffer, and only request the flags needed + // since each requires some overhead and limits if the buffer can + // be hardware accelerated + DSBUFFERDESC dsbd; + memset( &dsbd, 0, sizeof(DSBUFFERDESC) ); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = dwCreationFlags | DSBCAPS_GETCURRENTPOSITION2; + dsbd.dwBufferBytes = dwDSBufferSize; + dsbd.guid3DAlgorithm = GUID_NULL; + dsbd.lpwfxFormat = (WAVEFORMATEX *)pwfx; + + if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) ) + return -1; + + // Create the sound + *ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile ); + + return S_OK; +} + +/* +=============== +idAudioHardwareWIN32::Lock +=============== +*/ +bool idAudioHardwareWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { + if (speakers) { + return speakers->Lock( pDSLockedBuffer, dwDSLockedBufferSize ); + } + return false; +} + +/* +=============== +idAudioHardwareWIN32::Unlock +=============== +*/ +bool idAudioHardwareWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { + if (speakers) { + return speakers->Unlock( pDSLockedBuffer, dwDSLockedBufferSize ); + } + return false; +} + +/* +=============== +idAudioHardwareWIN32::GetCurrentPosition +=============== +*/ +bool idAudioHardwareWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { + if (speakers) { + return speakers->GetCurrentPosition( pdwCurrentWriteCursor ); + } + return false; +} + +static HMODULE hOpenAL = NULL; + +/* +=============== +Sys_LoadOpenAL +=============== +*/ +bool Sys_LoadOpenAL( void ) { +#if ID_OPENAL + const char *sym; + + if ( hOpenAL ) { + return true; + } + + hOpenAL = LoadLibrary( idSoundSystemLocal::s_libOpenAL.GetString() ); + if ( !hOpenAL ) { + common->Warning( "LoadLibrary %s failed.", idSoundSystemLocal::s_libOpenAL.GetString() ); + return false; + } + if ( ( sym = InitializeIDAL( hOpenAL ) ) ) { + common->Warning( "GetProcAddress %s failed.", sym ); + FreeLibrary( hOpenAL ); + hOpenAL = NULL; + return false; + } + return true; +#else + return false; +#endif +} + +/* +=============== +Sys_FreeOpenAL +=============== +*/ +void Sys_FreeOpenAL( void ) { + if ( hOpenAL ) { + FreeLibrary( hOpenAL ); + hOpenAL = NULL; + } +} + +/* +=============== +idAudioBufferWIN32::idAudioBuffer +=============== +*/ +idAudioBufferWIN32::idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile ) { + + m_apDSBuffer = apDSBuffer; + + m_dwDSBufferSize = dwDSBufferSize; + m_pWaveFile = pWaveFile; + + if (pWaveFile) { + FillBufferWithSound( m_apDSBuffer, false ); + + m_apDSBuffer->SetCurrentPosition(0); + } +} + +/* +=============== +idAudioBufferWIN32::~idAudioBuffer +=============== +*/ +idAudioBufferWIN32::~idAudioBufferWIN32() { + SAFE_DELETE(m_pWaveFile); + SAFE_RELEASE( m_apDSBuffer ); + m_pWaveFile = NULL; + m_apDSBuffer = NULL; +} + +/* +=============== +idAudioBufferWIN32::FillBufferWithSound +=============== +*/ +int idAudioBufferWIN32::FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger ) { + int hr; + void* pDSLockedBuffer = NULL; // Pointer to locked buffer memory + ulong dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer + int dwWavDataRead = 0; // Amount of data read from the wav file + + if( pDSB == NULL ) + return -1; + + // we may not even have a wavefile + if (m_pWaveFile==NULL) { + return -1; + } + + // Make sure we have focus, and we didn't just switch in from + // an app which had a DirectSound device + if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) ) { + DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); + return -1; + } + + // Lock the buffer down + if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize, &pDSLockedBuffer, &dwDSLockedBufferSize, NULL, NULL, 0L ) ) ) { + DXTRACE_ERR( TEXT("Lock"), hr ); + return -1; + } + + // Reset the wave file to the beginning + m_pWaveFile->ResetFile(); + + if( FAILED( hr = m_pWaveFile->Read( (byte*) pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead ) ) ) { + return DXTRACE_ERR( TEXT("Read"), hr ); + } + + if( dwWavDataRead == 0 ) { + // Wav is blank, so just fill with silence + memset( pDSLockedBuffer, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize ); + } else if( dwWavDataRead < (int)dwDSLockedBufferSize ) { + // If the wav file was smaller than the DirectSound buffer, + // we need to fill the remainder of the buffer with data + if( bRepeatWavIfBufferLarger ) { + // Reset the file and fill the buffer with wav data + int dwReadSoFar = dwWavDataRead; // From previous call above. + while( dwReadSoFar < (int)dwDSLockedBufferSize ) { + // This will keep reading in until the buffer is full + // for very short files + if( FAILED( hr = m_pWaveFile->ResetFile() ) ) { + return DXTRACE_ERR( TEXT("ResetFile"), hr ); + } + + hr = m_pWaveFile->Read( (byte*)pDSLockedBuffer + dwReadSoFar, dwDSLockedBufferSize - dwReadSoFar, &dwWavDataRead ); + if( FAILED(hr) ) { + return DXTRACE_ERR( TEXT("Read"), hr ); + } + + dwReadSoFar += dwWavDataRead; + } + } else { + // Don't repeat the wav file, just fill in silence + memset( (byte*) pDSLockedBuffer + dwWavDataRead, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize - dwWavDataRead); + } + } + + // Unlock the buffer, we don't need it anymore. + pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 ); + + return S_OK; +} + +/* +=============== +idAudioBufferWIN32::RestoreBuffer +Desc: Restores the lost buffer. *pbWasRestored returns true if the buffer was + restored. It can also NULL if the information is not needed. +=============== +*/ +int idAudioBufferWIN32::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored ) { + int hr; + + if( pDSB == NULL ) { + return -1; + } + if( pbWasRestored ) { + *pbWasRestored = false; + } + + ulong dwStatus; + if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) ) { + return DXTRACE_ERR( TEXT("GetStatus"), hr ); + } + + if( dwStatus & DSBSTATUS_BUFFERLOST ) { + // Since the app could have just been activated, then + // DirectSound may not be giving us control yet, so + // the restoring the buffer may fail. + // If it does, sleep until DirectSound gives us control. + do { + hr = pDSB->Restore(); + if( hr == DSERR_BUFFERLOST ) { + Sleep( 10 ); + } + hr = pDSB->Restore(); + } while( hr ); + + if( pbWasRestored != NULL ) { + *pbWasRestored = true; + } + + return S_OK; + } else { + return S_FALSE; + } +} + +/* +=============== +idAudioBufferWIN32::Play +Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING + in the dwFlags to loop the sound +=============== +*/ +int idAudioBufferWIN32::Play( dword dwPriority, dword dwFlags ) { + int hr; + bool bRestored; + + if( m_apDSBuffer == NULL ) { + return -1; + } + + // Restore the buffer if it was lost + if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) { + common->Error( TEXT("RestoreBuffer"), hr ); + } + + if( bRestored ) { + // The buffer was restored, so we need to fill it with new data + if( FAILED( hr = FillBufferWithSound( m_apDSBuffer, false ) ) ) { + common->Error( TEXT("FillBufferWithSound"), hr ); + } + + // Make DirectSound do pre-processing on sound effects + Reset(); + } + + m_apDSBuffer->Play( 0, dwPriority, dwFlags ); + return 0; +} + +/* +=============== +idAudioBufferWIN32::Stop +Desc: Stops the sound from playing +=============== +*/ +int idAudioBufferWIN32::Stop() { + if( this == NULL || m_apDSBuffer == NULL ) { + return -1; + } + + m_apDSBuffer->Stop(); + + return 0; +} + +/* +=============== +idAudioBufferWIN32::Reset +Desc: Reset all of the sound buffers +=============== +*/ +int idAudioBufferWIN32::Reset() { + if( m_apDSBuffer == NULL ) { + return -1; + } + + m_apDSBuffer->SetCurrentPosition( 0 ); + + return 0; +} + +/* +=============== +idAudioBufferWIN32::IsSoundPlaying +Desc: Checks to see if a buffer is playing and returns true if it +=============== +*/ +bool idAudioBufferWIN32::IsSoundPlaying( ) { + if( m_apDSBuffer == NULL ) { + return false; + } + + if( m_apDSBuffer ) { + ulong dwStatus = 0; + m_apDSBuffer->GetStatus( &dwStatus ); + if ( dwStatus & DSBSTATUS_PLAYING ) { + return true; + } + } + return false; +} + +/* +=============== +idAudioBufferWIN32::Lock +=============== +*/ +bool idAudioBufferWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { + int hr; + // Restore the buffer if it was lost + bool bRestored; + if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) { + return false; + } + + // Lock the DirectSound buffer + if( FAILED( hr = m_apDSBuffer->Lock( 0, m_dwDSBufferSize, pDSLockedBuffer, dwDSLockedBufferSize, NULL, NULL, 0 ) ) ) { + return false; + } + return true; +} + +/* +=============== +idAudioBufferWIN32::Unlock +=============== +*/ +bool idAudioBufferWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { + // Unlock the DirectSound buffer + m_apDSBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 ); + return true; +} + +/* +=============== +idAudioBufferWIN32::GetCurrentPosition +=============== +*/ +bool idAudioBufferWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { + int hr; + + // Make sure we have focus, and we didn't just switch in from + // an app which had a DirectSound device + if( FAILED( hr = RestoreBuffer( m_apDSBuffer, NULL ) ) ) { + DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); + return false; + } + + if( FAILED( hr = m_apDSBuffer->GetCurrentPosition( NULL, pdwCurrentWriteCursor ) ) ) { + return false; + } + return true; +} + +/* +=============== +idAudioBufferWIN32::SetVolume +=============== +*/ +void idAudioBufferWIN32::SetVolume( float x) { + if (m_apDSBuffer) { + m_apDSBuffer->SetVolume(x); + } +} diff --git a/sys/win32/win_syscon.cpp b/sys/win32/win_syscon.cpp new file mode 100644 index 000000000..3f41ff000 --- /dev/null +++ b/sys/win32/win_syscon.cpp @@ -0,0 +1,548 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include +#include +#include +#include +#include +#include + +#include "win_local.h" +#include "rc/AFEditor_resource.h" +#include "rc/doom_resource.h" + +#define COPY_ID 1 +#define QUIT_ID 2 +#define CLEAR_ID 3 + +#define ERRORBOX_ID 10 +#define ERRORTEXT_ID 11 + +#define EDIT_ID 100 +#define INPUT_ID 101 + +#define COMMAND_HISTORY 64 + +typedef struct { + HWND hWnd; + HWND hwndBuffer; + + HWND hwndButtonClear; + HWND hwndButtonCopy; + HWND hwndButtonQuit; + + HWND hwndErrorBox; + HWND hwndErrorText; + + HBITMAP hbmLogo; + HBITMAP hbmClearBitmap; + + HBRUSH hbrEditBackground; + HBRUSH hbrErrorBackground; + + HFONT hfBufferFont; + HFONT hfButtonFont; + + HWND hwndInputLine; + + char errorString[80]; + + char consoleText[512], returnedText[512]; + bool quitOnClose; + int windowWidth, windowHeight; + + WNDPROC SysInputLineWndProc; + + idEditField historyEditLines[COMMAND_HISTORY]; + + int nextHistoryLine;// the last line in the history buffer, not masked + int historyLine; // the line being displayed from history buffer + // will be <= nextHistoryLine + + idEditField consoleField; + +} WinConData; + +static WinConData s_wcd; + +static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + char *cmdString; + static bool s_timePolarity; + + switch (uMsg) { + case WM_ACTIVATE: + if ( LOWORD( wParam ) != WA_INACTIVE ) { + SetFocus( s_wcd.hwndInputLine ); + } + break; + case WM_CLOSE: + if ( cvarSystem->IsInitialized() && com_skipRenderer.GetBool() ) { + cmdString = Mem_CopyString( "quit" ); + Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); + } else if ( s_wcd.quitOnClose ) { + PostQuitMessage( 0 ); + } else { + Sys_ShowConsole( 0, false ); + win32.win_viewlog.SetBool( false ); + } + return 0; + case WM_CTLCOLORSTATIC: + if ( ( HWND ) lParam == s_wcd.hwndBuffer ) { + SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0x80 ) ); + SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) ); + return ( long ) s_wcd.hbrEditBackground; + } else if ( ( HWND ) lParam == s_wcd.hwndErrorBox ) { + if ( s_timePolarity & 1 ) { + SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) ); + SetTextColor( ( HDC ) wParam, RGB( 0xff, 0x0, 0x00 ) ); + } else { + SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) ); + SetTextColor( ( HDC ) wParam, RGB( 0x00, 0x0, 0x00 ) ); + } + return ( long ) s_wcd.hbrErrorBackground; + } + break; + case WM_SYSCOMMAND: + if ( wParam == SC_CLOSE ) { + PostQuitMessage( 0 ); + } + break; + case WM_COMMAND: + if ( wParam == COPY_ID ) { + SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); + SendMessage( s_wcd.hwndBuffer, WM_COPY, 0, 0 ); + } else if ( wParam == QUIT_ID ) { + if ( s_wcd.quitOnClose ) { + PostQuitMessage( 0 ); + } else { + cmdString = Mem_CopyString( "quit" ); + Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); + } + } else if ( wParam == CLEAR_ID ) { + SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); + SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, ( LPARAM ) "" ); + UpdateWindow( s_wcd.hwndBuffer ); + } + break; + case WM_CREATE: + s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0x80 ) ); + s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) ); + SetTimer( hWnd, 1, 1000, NULL ); + break; +/* + case WM_ERASEBKGND: + HGDIOBJ oldObject; + HDC hdcScaled; + hdcScaled = CreateCompatibleDC( ( HDC ) wParam ); + assert( hdcScaled != 0 ); + if ( hdcScaled ) { + oldObject = SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo ); + assert( oldObject != 0 ); + if ( oldObject ) + { + StretchBlt( ( HDC ) wParam, 0, 0, s_wcd.windowWidth, s_wcd.windowHeight, + hdcScaled, 0, 0, 512, 384, + SRCCOPY ); + } + DeleteDC( hdcScaled ); + hdcScaled = 0; + } + return 1; +*/ + case WM_TIMER: + if ( wParam == 1 ) { + s_timePolarity = (bool)!s_timePolarity; + if ( s_wcd.hwndErrorBox ) { + InvalidateRect( s_wcd.hwndErrorBox, NULL, FALSE ); + } + } + break; + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + +LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + int key, cursor; + switch ( uMsg ) { + case WM_KILLFOCUS: + if ( ( HWND ) wParam == s_wcd.hWnd || ( HWND ) wParam == s_wcd.hwndErrorBox ) { + SetFocus( hWnd ); + return 0; + } + break; + + case WM_KEYDOWN: + key = MapKey( lParam ); + + // command history + if ( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ) { + if ( s_wcd.nextHistoryLine - s_wcd.historyLine < COMMAND_HISTORY && s_wcd.historyLine > 0 ) { + s_wcd.historyLine--; + } + s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ]; + + SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() ); + SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() ); + return 0; + } + + if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ) { + if ( s_wcd.historyLine == s_wcd.nextHistoryLine ) { + return 0; + } + s_wcd.historyLine++; + s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ]; + + SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() ); + SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() ); + return 0; + } + break; + + case WM_CHAR: + key = MapKey( lParam ); + + GetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer(), MAX_EDIT_LINE ); + SendMessage( s_wcd.hwndInputLine, EM_GETSEL, (WPARAM) NULL, (LPARAM) &cursor ); + s_wcd.consoleField.SetCursor( cursor ); + + // enter the line + if ( key == K_ENTER || key == K_KP_ENTER ) { + strncat( s_wcd.consoleText, s_wcd.consoleField.GetBuffer(), sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 ); + strcat( s_wcd.consoleText, "\n" ); + SetWindowText( s_wcd.hwndInputLine, "" ); + + Sys_Printf( "]%s\n", s_wcd.consoleField.GetBuffer() ); + + // copy line to history buffer + s_wcd.historyEditLines[s_wcd.nextHistoryLine % COMMAND_HISTORY] = s_wcd.consoleField; + s_wcd.nextHistoryLine++; + s_wcd.historyLine = s_wcd.nextHistoryLine; + + s_wcd.consoleField.Clear(); + + return 0; + } + + // command completion + if ( key == K_TAB ) { + s_wcd.consoleField.AutoComplete(); + + SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() ); + //s_wcd.consoleField.SetWidthInChars( strlen( s_wcd.consoleField.GetBuffer() ) ); + SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() ); + + return 0; + } + + // clear autocompletion buffer on normal key input + if ( ( key >= K_SPACE && key <= K_BACKSPACE ) || + ( key >= K_KP_SLASH && key <= K_KP_PLUS ) || ( key >= K_KP_STAR && key <= K_KP_EQUALS ) ) { + s_wcd.consoleField.ClearAutoComplete(); + } + break; + } + + return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam ); +} + +/* +** Sys_CreateConsole +*/ +void Sys_CreateConsole( void ) { + HDC hDC; + WNDCLASS wc; + RECT rect; + const char *DEDCLASS = WIN32_CONSOLE_CLASS; + int nHeight; + int swidth, sheight; + int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX; + int i; + + memset( &wc, 0, sizeof( wc ) ); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) ConWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = win32.hInstance; + wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1)); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (struct HBRUSH__ *)COLOR_WINDOW; + wc.lpszMenuName = 0; + wc.lpszClassName = DEDCLASS; + + if ( !RegisterClass (&wc) ) { + return; + } + + rect.left = 0; + rect.right = 540; + rect.top = 0; + rect.bottom = 450; + AdjustWindowRect( &rect, DEDSTYLE, FALSE ); + + hDC = GetDC( GetDesktopWindow() ); + swidth = GetDeviceCaps( hDC, HORZRES ); + sheight = GetDeviceCaps( hDC, VERTRES ); + ReleaseDC( GetDesktopWindow(), hDC ); + + s_wcd.windowWidth = rect.right - rect.left + 1; + s_wcd.windowHeight = rect.bottom - rect.top + 1; + + //s_wcd.hbmLogo = LoadBitmap( win32.hInstance, MAKEINTRESOURCE( IDB_BITMAP_LOGO) ); + + s_wcd.hWnd = CreateWindowEx( 0, + DEDCLASS, + GAME_NAME, + DEDSTYLE, + ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, + NULL, + NULL, + win32.hInstance, + NULL ); + + if ( s_wcd.hWnd == NULL ) { + return; + } + + // + // create fonts + // + hDC = GetDC( s_wcd.hWnd ); + nHeight = -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY ), 72 ); + + s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH, "Courier New" ); + + ReleaseDC( s_wcd.hWnd, hDC ); + + // + // create the input line + // + s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | + ES_LEFT | ES_AUTOHSCROLL, + 6, 400, 528, 20, + s_wcd.hWnd, + ( HMENU ) INPUT_ID, // child window ID + win32.hInstance, NULL ); + + // + // create the buttons + // + s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 5, 425, 72, 24, + s_wcd.hWnd, + ( HMENU ) COPY_ID, // child window ID + win32.hInstance, NULL ); + SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" ); + + s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 82, 425, 72, 24, + s_wcd.hWnd, + ( HMENU ) CLEAR_ID, // child window ID + win32.hInstance, NULL ); + SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" ); + + s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 462, 425, 72, 24, + s_wcd.hWnd, + ( HMENU ) QUIT_ID, // child window ID + win32.hInstance, NULL ); + SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" ); + + + // + // create the scrollbuffer + // + s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | + ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY, + 6, 40, 526, 354, + s_wcd.hWnd, + ( HMENU ) EDIT_ID, // child window ID + win32.hInstance, NULL ); + SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + + s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc ); + SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + +// don't show it now that we have a splash screen up + if ( win32.win_viewlog.GetBool() ) { + ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT); + UpdateWindow( s_wcd.hWnd ); + SetForegroundWindow( s_wcd.hWnd ); + SetFocus( s_wcd.hwndInputLine ); + } + + + + s_wcd.consoleField.Clear(); + + for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) { + s_wcd.historyEditLines[i].Clear(); + } +} + +/* +** Sys_DestroyConsole +*/ +void Sys_DestroyConsole( void ) { + if ( s_wcd.hWnd ) { + ShowWindow( s_wcd.hWnd, SW_HIDE ); + CloseWindow( s_wcd.hWnd ); + DestroyWindow( s_wcd.hWnd ); + s_wcd.hWnd = 0; + } +} + +/* +** Sys_ShowConsole +*/ +void Sys_ShowConsole( int visLevel, bool quitOnClose ) { + + s_wcd.quitOnClose = quitOnClose; + + if ( !s_wcd.hWnd ) { + return; + } + + switch ( visLevel ) { + case 0: + ShowWindow( s_wcd.hWnd, SW_HIDE ); + break; + case 1: + ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL ); + SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); + break; + case 2: + ShowWindow( s_wcd.hWnd, SW_MINIMIZE ); + break; + default: + Sys_Error( "Invalid visLevel %d sent to Sys_ShowConsole\n", visLevel ); + break; + } +} + +/* +** Sys_ConsoleInput +*/ +char *Sys_ConsoleInput( void ) { + + if ( s_wcd.consoleText[0] == 0 ) { + return NULL; + } + + strcpy( s_wcd.returnedText, s_wcd.consoleText ); + s_wcd.consoleText[0] = 0; + + return s_wcd.returnedText; +} + +/* +** Conbuf_AppendText +*/ +void Conbuf_AppendText( const char *pMsg ) +{ +#define CONSOLE_BUFFER_SIZE 16384 + + char buffer[CONSOLE_BUFFER_SIZE*2]; + char *b = buffer; + const char *msg; + int bufLen; + int i = 0; + static unsigned long s_totalChars; + + // + // if the message is REALLY long, use just the last portion of it + // + if ( strlen( pMsg ) > CONSOLE_BUFFER_SIZE - 1 ) { + msg = pMsg + strlen( pMsg ) - CONSOLE_BUFFER_SIZE + 1; + } else { + msg = pMsg; + } + + // + // copy into an intermediate buffer + // + while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) ) { + if ( msg[i] == '\n' && msg[i+1] == '\r' ) { + b[0] = '\r'; + b[1] = '\n'; + b += 2; + i++; + } else if ( msg[i] == '\r' ) { + b[0] = '\r'; + b[1] = '\n'; + b += 2; + } else if ( msg[i] == '\n' ) { + b[0] = '\r'; + b[1] = '\n'; + b += 2; + } else if ( idStr::IsColor( &msg[i] ) ) { + i++; + } else { + *b= msg[i]; + b++; + } + i++; + } + *b = 0; + bufLen = b - buffer; + + s_totalChars += bufLen; + + // + // replace selection instead of appending if we're overflowing + // + if ( s_totalChars > 0x7000 ) { + SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); + s_totalChars = bufLen; + } + + // + // put this text into the windows console + // + SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); + SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 ); + SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer ); +} + +/* +** Win_SetErrorText +*/ +void Win_SetErrorText( const char *buf ) { + idStr::Copynz( s_wcd.errorString, buf, sizeof( s_wcd.errorString ) ); + if ( !s_wcd.hwndErrorBox ) { + s_wcd.hwndErrorBox = CreateWindow( "static", NULL, WS_CHILD | WS_VISIBLE | SS_SUNKEN, + 6, 5, 526, 30, + s_wcd.hWnd, + ( HMENU ) ERRORBOX_ID, // child window ID + win32.hInstance, NULL ); + SendMessage( s_wcd.hwndErrorBox, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + SetWindowText( s_wcd.hwndErrorBox, s_wcd.errorString ); + + DestroyWindow( s_wcd.hwndInputLine ); + s_wcd.hwndInputLine = NULL; + } +} diff --git a/sys/win32/win_taskkeyhook.cpp b/sys/win32/win_taskkeyhook.cpp new file mode 100644 index 000000000..c85dcaa13 --- /dev/null +++ b/sys/win32/win_taskkeyhook.cpp @@ -0,0 +1,136 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +// +// This file implements the low-level keyboard hook that traps the task keys. +// + +//#define _WIN32_WINNT 0x0500 // for KBDLLHOOKSTRUCT +#include // MFC core and standard components +#include "win_local.h" + +#define DLLEXPORT __declspec(dllexport) + +// Magic registry key/value for "Remove Task Manager" policy. +LPCTSTR KEY_DisableTaskMgr = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; +LPCTSTR VAL_DisableTaskMgr = "DisableTaskMgr"; + +// The section is SHARED among all instances of this DLL. +// A low-level keyboard hook is always a system-wide hook. +#pragma data_seg (".mydata") +HHOOK g_hHookKbdLL = NULL; // hook handle +BOOL g_bBeep = FALSE; // beep on illegal key +#pragma data_seg () +#pragma comment(linker, "/SECTION:.mydata,RWS") // tell linker: make it shared + +/* +================ +MyTaskKeyHookLL + + Low-level keyboard hook: + Trap task-switching keys by returning without passing along. +================ +*/ +LRESULT CALLBACK MyTaskKeyHookLL( int nCode, WPARAM wp, LPARAM lp ) { + KBDLLHOOKSTRUCT *pkh = (KBDLLHOOKSTRUCT *) lp; + + if ( nCode == HC_ACTION ) { + BOOL bCtrlKeyDown = GetAsyncKeyState( VK_CONTROL)>>((sizeof(SHORT) * 8) - 1 ); + + if ( ( pkh->vkCode == VK_ESCAPE && bCtrlKeyDown ) // Ctrl+Esc + || ( pkh->vkCode == VK_TAB && pkh->flags & LLKHF_ALTDOWN ) // Alt+TAB + || ( pkh->vkCode == VK_ESCAPE && pkh->flags & LLKHF_ALTDOWN ) // Alt+Esc + || ( pkh->vkCode == VK_LWIN || pkh->vkCode == VK_RWIN ) // Start Menu + ) { + + if ( g_bBeep && ( wp == WM_SYSKEYDOWN || wp == WM_KEYDOWN ) ) { + MessageBeep( 0 ); // beep on downstroke if requested + } + return 1; // return without processing the key strokes + } + } + return CallNextHookEx( g_hHookKbdLL, nCode, wp, lp ); +} + +/* +================ +AreTaskKeysDisabled + + Are task keys disabled--ie, is hook installed? + Note: This assumes there's no other hook that does the same thing! +================ +*/ +BOOL AreTaskKeysDisabled() { + return g_hHookKbdLL != NULL; +} + +/* +================ +IsTaskMgrDisabled +================ +*/ +BOOL IsTaskMgrDisabled() { + HKEY hk; + + if ( RegOpenKey( HKEY_CURRENT_USER, KEY_DisableTaskMgr, &hk ) != ERROR_SUCCESS ) { + return FALSE; // no key ==> not disabled + } + + DWORD val = 0; + DWORD len = 4; + return RegQueryValueEx( hk, VAL_DisableTaskMgr, NULL, NULL, (BYTE*)&val, &len ) == ERROR_SUCCESS && val == 1; +} + +/* +================ +DisableTaskKeys +================ +*/ +void DisableTaskKeys( BOOL bDisable, BOOL bBeep, BOOL bTaskMgr ) { + + // task keys (Ctrl+Esc, Alt-Tab, etc.) + if ( bDisable ) { + if ( !g_hHookKbdLL ) { + g_hHookKbdLL = SetWindowsHookEx( WH_KEYBOARD_LL, MyTaskKeyHookLL, win32.hInstance, 0 ); + } + } else if ( g_hHookKbdLL != NULL ) { + UnhookWindowsHookEx( g_hHookKbdLL ); + g_hHookKbdLL = NULL; + } + g_bBeep = bBeep; + + // task manager (Ctrl+Alt+Del) + if ( bTaskMgr ) { + HKEY hk; + if ( RegOpenKey( HKEY_CURRENT_USER, KEY_DisableTaskMgr, &hk ) != ERROR_SUCCESS ) { + RegCreateKey( HKEY_CURRENT_USER, KEY_DisableTaskMgr, &hk ); + } + if ( bDisable ) { + // disable TM: set policy = 1 + DWORD val = 1; + RegSetValueEx( hk, VAL_DisableTaskMgr, NULL, REG_DWORD, (BYTE*)&val, sizeof(val) ); + } else { + // enable TM: remove policy + RegDeleteValue( hk,VAL_DisableTaskMgr ); + } + } +} diff --git a/sys/win32/win_wndproc.cpp b/sys/win32/win_wndproc.cpp new file mode 100644 index 000000000..b76a61cc7 --- /dev/null +++ b/sys/win32/win_wndproc.cpp @@ -0,0 +1,447 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "win_local.h" +#include "../../renderer/tr_local.h" + +LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +static bool s_alttab_disabled; + +static void WIN_DisableAltTab( void ) { + if ( s_alttab_disabled || win32.win_allowAltTab.GetBool() ) { + return; + } + if ( !idStr::Icmp( cvarSystem->GetCVarString( "sys_arch" ), "winnt" ) ) { + RegisterHotKey( 0, 0, MOD_ALT, VK_TAB ); + } else { + BOOL old; + + SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 ); + } + s_alttab_disabled = true; +} + +static void WIN_EnableAltTab( void ) { + if ( !s_alttab_disabled || win32.win_allowAltTab.GetBool() ) { + return; + } + if ( !idStr::Icmp( cvarSystem->GetCVarString( "sys_arch" ), "winnt" ) ) { + UnregisterHotKey( 0, 0 ); + } else { + BOOL old; + + SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 ); + } + + s_alttab_disabled = false; +} + +void WIN_Sizing(WORD side, RECT *rect) +{ + if ( !glConfig.isInitialized || glConfig.vidHeight <= 0 || glConfig.vidWidth <= 0 ) { + return; + } + + if ( idKeyInput::IsDown( K_CTRL ) ) { + return; + } + + int width = rect->right - rect->left; + int height = rect->bottom - rect->top; + + // Adjust width/height for window decoration + RECT decoRect = { 0, 0, 0, 0 }; + AdjustWindowRect( &decoRect, WINDOW_STYLE|WS_SYSMENU, FALSE ); + int decoWidth = decoRect.right - decoRect.left; + int decoHeight = decoRect.bottom - decoRect.top; + + width -= decoWidth; + height -= decoHeight; + + // Clamp to a minimum size + int minWidth = 160; + int minHeight = minWidth * SCREEN_HEIGHT / SCREEN_WIDTH; + + if ( width < minWidth ) { + width = minWidth; + } + if ( height < minHeight ) { + height = minHeight; + } + + // Set the new size + switch ( side ) { + case WMSZ_LEFT: + rect->left = rect->right - width - decoWidth; + rect->bottom = rect->top + ( width * SCREEN_HEIGHT / SCREEN_WIDTH ) + decoHeight; + break; + case WMSZ_RIGHT: + rect->right = rect->left + width + decoWidth; + rect->bottom = rect->top + ( width * SCREEN_HEIGHT / SCREEN_WIDTH ) + decoHeight; + break; + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + rect->bottom = rect->top + height + decoHeight; + rect->right = rect->left + ( height * SCREEN_WIDTH / SCREEN_HEIGHT ) + decoWidth; + break; + case WMSZ_TOP: + case WMSZ_TOPRIGHT: + rect->top = rect->bottom - height - decoHeight; + rect->right = rect->left + ( height * SCREEN_WIDTH / SCREEN_HEIGHT ) + decoWidth; + break; + case WMSZ_BOTTOMLEFT: + rect->bottom = rect->top + height + decoHeight; + rect->left = rect->right - ( height * SCREEN_WIDTH / SCREEN_HEIGHT ) - decoWidth; + break; + case WMSZ_TOPLEFT: + rect->top = rect->bottom - height - decoHeight; + rect->left = rect->right - ( height * SCREEN_WIDTH / SCREEN_HEIGHT ) - decoWidth; + break; + } +} + +//========================================================================== + +// Keep this in sync with the one in win_input.cpp +// This one is used in the menu, the other one is used in game + +static byte s_scantokey[128] = +{ +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', K_ENTER,K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', K_SHIFT, '\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +static byte s_scantoshift[128] = +{ +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', K_ENTER,K_CTRL, 'A', 'S', // 1 + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '|' , '~', K_SHIFT, '\\', 'Z', 'X', 'C', 'V', // 2 + 'B', 'N', 'M', '<', '>', '?', K_SHIFT, K_KP_STAR, + K_ALT, ' ', K_CAPSLOCK,K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, K_SCROLL, K_HOME, + K_UPARROW, K_PGUP, K_KP_MINUS,K_LEFTARROW,K_KP_5, K_RIGHTARROW,K_KP_PLUS,K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, + K_F12, 0, 0, K_LWIN, K_RWIN, K_MENU, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + + +/* +======= +MapKey + +Map from windows to Doom keynums +======= +*/ +int MapKey (int key) +{ + int result; + int modified; + bool is_extended; + + modified = ( key >> 16 ) & 255; + + if ( modified > 127 ) + return 0; + + if ( key & ( 1 << 24 ) ) { + is_extended = true; + } + else { + is_extended = false; + } + + //Check for certain extended character codes. + //The specific case we are testing is the numpad / is not being translated + //properly for localized builds. + if(is_extended) { + switch(modified) { + case 0x35: //Numpad / + return K_KP_SLASH; + } + } + + const unsigned char *scanToKey = Sys_GetScanTable(); + result = scanToKey[modified]; + + // common->Printf( "Key: 0x%08x Modified: 0x%02x Extended: %s Result: 0x%02x\n", key, modified, (is_extended?"Y":"N"), result); + + if ( is_extended ) { + switch ( result ) + { + case K_PAUSE: + return K_KP_NUMLOCK; + case 0x0D: + return K_KP_ENTER; + case 0x2F: + return K_KP_SLASH; + case 0xAF: + return K_KP_PLUS; + case K_KP_STAR: + return K_PRINT_SCR; + case K_ALT: + return K_RIGHT_ALT; + } + } + else { + switch ( result ) + { + case K_HOME: + return K_KP_HOME; + case K_UPARROW: + return K_KP_UPARROW; + case K_PGUP: + return K_KP_PGUP; + case K_LEFTARROW: + return K_KP_LEFTARROW; + case K_RIGHTARROW: + return K_KP_RIGHTARROW; + case K_END: + return K_KP_END; + case K_DOWNARROW: + return K_KP_DOWNARROW; + case K_PGDN: + return K_KP_PGDN; + case K_INS: + return K_KP_INS; + case K_DEL: + return K_KP_DEL; + } + } + + return result; +} + + +/* +==================== +MainWndProc + +main window procedure +==================== +*/ +LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { + int key; + switch( uMsg ) { + case WM_WINDOWPOSCHANGED: + if (glConfig.isInitialized) { + RECT rect; + if (::GetClientRect(win32.hWnd, &rect)) { + glConfig.vidWidth = rect.right - rect.left; + glConfig.vidHeight = rect.bottom - rect.top; + } + } + break; + + case WM_CREATE: + + win32.hWnd = hWnd; + + if ( win32.cdsFullscreen ) { + WIN_DisableAltTab(); + } else { + WIN_EnableAltTab(); + } + + // do the OpenGL setup + void GLW_WM_CREATE( HWND hWnd ); + GLW_WM_CREATE( hWnd ); + + break; + + case WM_DESTROY: + // let sound and input know about this? + win32.hWnd = NULL; + if ( win32.cdsFullscreen ) { + WIN_EnableAltTab(); + } + break; + + case WM_CLOSE: + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit" ); + break; + + case WM_ACTIVATE: + // if we got here because of an alt-tab or maximize, + // we should activate immediately. If we are here because + // the mouse was clicked on a title bar or drag control, + // don't activate until the mouse button is released + { + int fActive, fMinimized; + + fActive = LOWORD(wParam); + fMinimized = (BOOL) HIWORD(wParam); + + win32.activeApp = (fActive != WA_INACTIVE); + if ( win32.activeApp ) { + idKeyInput::ClearStates(); + com_editorActive = false; + Sys_GrabMouseCursor( true ); + } + + if ( fActive == WA_INACTIVE ) { + win32.movingWindow = false; + } + + // start playing the game sound world + session->SetPlayingSoundWorld(); + + // we do not actually grab or release the mouse here, + // that will be done next time through the main loop + } + break; + + case WM_MOVE: { + int xPos, yPos; + RECT r; + int style; + + if (!win32.cdsFullscreen ) + { + xPos = (short) LOWORD(lParam); // horizontal position + yPos = (short) HIWORD(lParam); // vertical position + + r.left = 0; + r.top = 0; + r.right = 1; + r.bottom = 1; + + style = GetWindowLong( hWnd, GWL_STYLE ); + AdjustWindowRect( &r, style, FALSE ); + + win32.win_xpos.SetInteger( xPos + r.left ); + win32.win_ypos.SetInteger( yPos + r.top ); + win32.win_xpos.ClearModified(); + win32.win_ypos.ClearModified(); + } + break; + } + case WM_TIMER: { + if ( win32.win_timerUpdate.GetBool() ) { + common->Frame(); + } + break; + } + case WM_SYSCOMMAND: + if ( wParam == SC_SCREENSAVE || wParam == SC_KEYMENU ) { + return 0; + } + break; + + case WM_SYSKEYDOWN: + if ( wParam == 13 ) { // alt-enter toggles full-screen + cvarSystem->SetCVarBool( "r_fullscreen", !renderSystem->IsFullScreen() ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" ); + return 0; + } + // fall through for other keys + case WM_KEYDOWN: + key = MapKey( lParam ); + if ( key == K_CTRL || key == K_ALT || key == K_RIGHT_ALT ) { + // let direct-input handle this because windows sends Alt-Gr + // as two events (ctrl then alt) + break; + } + Sys_QueEvent( win32.sysMsgTime, SE_KEY, key, true, 0, NULL ); + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + key = MapKey( lParam ); + if ( key == K_PRINT_SCR ) { + // don't queue printscreen keys. Since windows doesn't send us key + // down events for this, we handle queueing them with DirectInput + break; + } else if ( key == K_CTRL || key == K_ALT || key == K_RIGHT_ALT ) { + // let direct-input handle this because windows sends Alt-Gr + // as two events (ctrl then alt) + break; + } + Sys_QueEvent( win32.sysMsgTime, SE_KEY, key, false, 0, NULL ); + break; + + case WM_CHAR: + Sys_QueEvent( win32.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL ); + break; + + case WM_NCLBUTTONDOWN: +// win32.movingWindow = true; + break; + + case WM_ENTERSIZEMOVE: + win32.movingWindow = true; + break; + + case WM_EXITSIZEMOVE: + win32.movingWindow = false; + break; + + case WM_SIZING: + WIN_Sizing(wParam, (RECT *)lParam); + break; + + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEMOVE: { + break; + } + case WM_MOUSEWHEEL: { + int delta = GET_WHEEL_DELTA_WPARAM( wParam ) / WHEEL_DELTA; + int key = delta < 0 ? K_MWHEELDOWN : K_MWHEELUP; + delta = abs( delta ); + while( delta-- > 0 ) { + Sys_QueEvent( win32.sysMsgTime, SE_KEY, key, true, 0, NULL ); + Sys_QueEvent( win32.sysMsgTime, SE_KEY, key, false, 0, NULL ); + } + break; + } + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} diff --git a/tdm_update/ConsoleUpdater.cpp b/tdm_update/ConsoleUpdater.cpp index 0409cf101..4bf51e820 100644 --- a/tdm_update/ConsoleUpdater.cpp +++ b/tdm_update/ConsoleUpdater.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "ConsoleUpdater.h" diff --git a/tdm_update/ConsoleUpdater.h b/tdm_update/ConsoleUpdater.h index 1b5364112..6c1f9b404 100644 --- a/tdm_update/ConsoleUpdater.h +++ b/tdm_update/ConsoleUpdater.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/LogWriters.h b/tdm_update/LogWriters.h index fdcd815ce..6156775f3 100644 --- a/tdm_update/LogWriters.h +++ b/tdm_update/LogWriters.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/SConscript.libtdm_update b/tdm_update/SConscript.libtdm_update index d64b6a25c..065da5818 100644 --- a/tdm_update/SConscript.libtdm_update +++ b/tdm_update/SConscript.libtdm_update @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Updater -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Updater (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** import string diff --git a/tdm_update/SConscript.minizip b/tdm_update/SConscript.minizip index 0c5012a83..e0d8a8d5f 100644 --- a/tdm_update/SConscript.minizip +++ b/tdm_update/SConscript.minizip @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Updater -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Updater (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** import string diff --git a/tdm_update/SConscript.tdm_update b/tdm_update/SConscript.tdm_update index 72a9ed6ba..3d135b38c 100644 --- a/tdm_update/SConscript.tdm_update +++ b/tdm_update/SConscript.tdm_update @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Updater -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Updater (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** # The Dark Mod Updater build script # Adapted from id's game sconscript diff --git a/tdm_update/SConstruct b/tdm_update/SConstruct index 841ac7534..3b3706481 100644 --- a/tdm_update/SConstruct +++ b/tdm_update/SConstruct @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Updater -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Updater (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** # The Dark Mod Updater build script for Linux # Based on id's game sconscript diff --git a/tdm_update/libtdm_update/CRC.h b/tdm_update/libtdm_update/CRC.h index 8d15f0054..dfb796f92 100644 --- a/tdm_update/libtdm_update/CRC.h +++ b/tdm_update/libtdm_update/CRC.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #ifndef _TDM_CRC_H_ #define _TDM_CRC_H_ diff --git a/tdm_update/libtdm_update/Constants.h b/tdm_update/libtdm_update/Constants.h index e00430a2d..14e615581 100644 --- a/tdm_update/libtdm_update/Constants.h +++ b/tdm_update/libtdm_update/Constants.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/ExceptionSafeThread.h b/tdm_update/libtdm_update/ExceptionSafeThread.h index 40dd3e299..33a22c4f3 100644 --- a/tdm_update/libtdm_update/ExceptionSafeThread.h +++ b/tdm_update/libtdm_update/ExceptionSafeThread.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/File.cpp b/tdm_update/libtdm_update/File.cpp index 86b445522..fcf621a20 100644 --- a/tdm_update/libtdm_update/File.cpp +++ b/tdm_update/libtdm_update/File.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "File.h" diff --git a/tdm_update/libtdm_update/File.h b/tdm_update/libtdm_update/File.h index 44ab2e094..6d6ad1bb2 100644 --- a/tdm_update/libtdm_update/File.h +++ b/tdm_update/libtdm_update/File.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/Download.cpp b/tdm_update/libtdm_update/Http/Download.cpp index b8787649d..49ec9b3a3 100644 --- a/tdm_update/libtdm_update/Http/Download.cpp +++ b/tdm_update/libtdm_update/Http/Download.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Download.h" #include "../Http/HttpConnection.h" diff --git a/tdm_update/libtdm_update/Http/Download.h b/tdm_update/libtdm_update/Http/Download.h index 4a3dacf1c..3e3a66607 100644 --- a/tdm_update/libtdm_update/Http/Download.h +++ b/tdm_update/libtdm_update/Http/Download.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/DownloadManager.cpp b/tdm_update/libtdm_update/Http/DownloadManager.cpp index 01effa1ce..7167ff1bc 100644 --- a/tdm_update/libtdm_update/Http/DownloadManager.cpp +++ b/tdm_update/libtdm_update/Http/DownloadManager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "DownloadManager.h" diff --git a/tdm_update/libtdm_update/Http/DownloadManager.h b/tdm_update/libtdm_update/Http/DownloadManager.h index 88fc501fe..197394da8 100644 --- a/tdm_update/libtdm_update/Http/DownloadManager.h +++ b/tdm_update/libtdm_update/Http/DownloadManager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/HttpConnection.cpp b/tdm_update/libtdm_update/Http/HttpConnection.cpp index 48c457bfa..1ed2c9c41 100644 --- a/tdm_update/libtdm_update/Http/HttpConnection.cpp +++ b/tdm_update/libtdm_update/Http/HttpConnection.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "HttpConnection.h" #include "HttpRequest.h" diff --git a/tdm_update/libtdm_update/Http/HttpConnection.h b/tdm_update/libtdm_update/Http/HttpConnection.h index ad23d40e0..c6af74ab0 100644 --- a/tdm_update/libtdm_update/Http/HttpConnection.h +++ b/tdm_update/libtdm_update/Http/HttpConnection.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/HttpRequest.cpp b/tdm_update/libtdm_update/Http/HttpRequest.cpp index bcac58019..0b55ac73a 100644 --- a/tdm_update/libtdm_update/Http/HttpRequest.cpp +++ b/tdm_update/libtdm_update/Http/HttpRequest.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "HttpRequest.h" #include "HttpConnection.h" diff --git a/tdm_update/libtdm_update/Http/HttpRequest.h b/tdm_update/libtdm_update/Http/HttpRequest.h index d5e36f5f1..d558cf52e 100644 --- a/tdm_update/libtdm_update/Http/HttpRequest.h +++ b/tdm_update/libtdm_update/Http/HttpRequest.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/MirrorDownload.cpp b/tdm_update/libtdm_update/Http/MirrorDownload.cpp index 454107c0d..ebd30f329 100644 --- a/tdm_update/libtdm_update/Http/MirrorDownload.cpp +++ b/tdm_update/libtdm_update/Http/MirrorDownload.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "MirrorDownload.h" diff --git a/tdm_update/libtdm_update/Http/MirrorDownload.h b/tdm_update/libtdm_update/Http/MirrorDownload.h index f9d5a2188..97baf085c 100644 --- a/tdm_update/libtdm_update/Http/MirrorDownload.h +++ b/tdm_update/libtdm_update/Http/MirrorDownload.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Http/MirrorList.h b/tdm_update/libtdm_update/Http/MirrorList.h index 812c1dc8b..c8ddb8fdd 100644 --- a/tdm_update/libtdm_update/Http/MirrorList.h +++ b/tdm_update/libtdm_update/Http/MirrorList.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/IniFile.cpp b/tdm_update/libtdm_update/IniFile.cpp index 8bf0a2fdd..8b18cfc68 100644 --- a/tdm_update/libtdm_update/IniFile.cpp +++ b/tdm_update/libtdm_update/IniFile.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "IniFile.h" diff --git a/tdm_update/libtdm_update/IniFile.h b/tdm_update/libtdm_update/IniFile.h index 0c84cd088..e3fded0d4 100644 --- a/tdm_update/libtdm_update/IniFile.h +++ b/tdm_update/libtdm_update/IniFile.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/PackageInstructions.h b/tdm_update/libtdm_update/PackageInstructions.h index 825394836..699d8b8bd 100644 --- a/tdm_update/libtdm_update/PackageInstructions.h +++ b/tdm_update/libtdm_update/PackageInstructions.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Packager/Packager.cpp b/tdm_update/libtdm_update/Packager/Packager.cpp index 1fb6ef0ee..452b0112a 100644 --- a/tdm_update/libtdm_update/Packager/Packager.cpp +++ b/tdm_update/libtdm_update/Packager/Packager.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Packager.h" diff --git a/tdm_update/libtdm_update/Packager/Packager.h b/tdm_update/libtdm_update/Packager/Packager.h index 29cb578ac..b85b4f355 100644 --- a/tdm_update/libtdm_update/Packager/Packager.h +++ b/tdm_update/libtdm_update/Packager/Packager.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Packager/PackagerOptions.h b/tdm_update/libtdm_update/Packager/PackagerOptions.h index ba76668f0..c4ac75c71 100644 --- a/tdm_update/libtdm_update/Packager/PackagerOptions.h +++ b/tdm_update/libtdm_update/Packager/PackagerOptions.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Pk4Mappings.h b/tdm_update/libtdm_update/Pk4Mappings.h index 40a598399..3ad19b5d8 100644 --- a/tdm_update/libtdm_update/Pk4Mappings.h +++ b/tdm_update/libtdm_update/Pk4Mappings.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/ProgramOptions.h b/tdm_update/libtdm_update/ProgramOptions.h index f07e690d0..f179adf68 100644 --- a/tdm_update/libtdm_update/ProgramOptions.h +++ b/tdm_update/libtdm_update/ProgramOptions.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/ReleaseFileset.h b/tdm_update/libtdm_update/ReleaseFileset.h index 5babb9fea..e0c441558 100644 --- a/tdm_update/libtdm_update/ReleaseFileset.h +++ b/tdm_update/libtdm_update/ReleaseFileset.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/ReleaseManifest.h b/tdm_update/libtdm_update/ReleaseManifest.h index 63035a856..b0caf7825 100644 --- a/tdm_update/libtdm_update/ReleaseManifest.h +++ b/tdm_update/libtdm_update/ReleaseManifest.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/ReleaseVersions.h b/tdm_update/libtdm_update/ReleaseVersions.h index 80a542ce4..fd721f464 100644 --- a/tdm_update/libtdm_update/ReleaseVersions.h +++ b/tdm_update/libtdm_update/ReleaseVersions.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/SvnClient.cpp b/tdm_update/libtdm_update/SvnClient.cpp index d95ab0d4b..99c4d3f47 100644 --- a/tdm_update/libtdm_update/SvnClient.cpp +++ b/tdm_update/libtdm_update/SvnClient.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "SvnClient.h" diff --git a/tdm_update/libtdm_update/SvnClient.h b/tdm_update/libtdm_update/SvnClient.h index ba2e988fe..c52e00992 100644 --- a/tdm_update/libtdm_update/SvnClient.h +++ b/tdm_update/libtdm_update/SvnClient.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/SvnClientImpl.cpp b/tdm_update/libtdm_update/SvnClientImpl.cpp index 113125ec2..532019d30 100644 --- a/tdm_update/libtdm_update/SvnClientImpl.cpp +++ b/tdm_update/libtdm_update/SvnClientImpl.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "SvnClientImpl.h" diff --git a/tdm_update/libtdm_update/SvnClientImpl.h b/tdm_update/libtdm_update/SvnClientImpl.h index f75745d83..1d8218aa5 100644 --- a/tdm_update/libtdm_update/SvnClientImpl.h +++ b/tdm_update/libtdm_update/SvnClientImpl.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/TraceLog.cpp b/tdm_update/libtdm_update/TraceLog.cpp index 0f33f4ca1..69456b135 100644 --- a/tdm_update/libtdm_update/TraceLog.cpp +++ b/tdm_update/libtdm_update/TraceLog.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "TraceLog.h" diff --git a/tdm_update/libtdm_update/TraceLog.h b/tdm_update/libtdm_update/TraceLog.h index d874d69f4..4f0a8c82f 100644 --- a/tdm_update/libtdm_update/TraceLog.h +++ b/tdm_update/libtdm_update/TraceLog.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/UpdatePackage.h b/tdm_update/libtdm_update/UpdatePackage.h index ee94d3890..26463f544 100644 --- a/tdm_update/libtdm_update/UpdatePackage.h +++ b/tdm_update/libtdm_update/UpdatePackage.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/UpdatePackageInfo.h b/tdm_update/libtdm_update/UpdatePackageInfo.h index 0ebc9921f..d1fd44aed 100644 --- a/tdm_update/libtdm_update/UpdatePackageInfo.h +++ b/tdm_update/libtdm_update/UpdatePackageInfo.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/DifferentialUpdateInfo.h b/tdm_update/libtdm_update/Updater/DifferentialUpdateInfo.h index 40e20f1b0..04398ba84 100644 --- a/tdm_update/libtdm_update/Updater/DifferentialUpdateInfo.h +++ b/tdm_update/libtdm_update/Updater/DifferentialUpdateInfo.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/ProgressHandler.h b/tdm_update/libtdm_update/Updater/ProgressHandler.h index 6ada17ad9..290bb1008 100644 --- a/tdm_update/libtdm_update/Updater/ProgressHandler.h +++ b/tdm_update/libtdm_update/Updater/ProgressHandler.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/UpdateController.cpp b/tdm_update/libtdm_update/Updater/UpdateController.cpp index 5ea07baf4..5c286d0d3 100644 --- a/tdm_update/libtdm_update/Updater/UpdateController.cpp +++ b/tdm_update/libtdm_update/Updater/UpdateController.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "UpdateController.h" diff --git a/tdm_update/libtdm_update/Updater/UpdateController.h b/tdm_update/libtdm_update/Updater/UpdateController.h index a2e15a29a..b74504ee9 100644 --- a/tdm_update/libtdm_update/Updater/UpdateController.h +++ b/tdm_update/libtdm_update/Updater/UpdateController.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/UpdateStep.h b/tdm_update/libtdm_update/Updater/UpdateStep.h index a12b07bc5..3a6b2aa02 100644 --- a/tdm_update/libtdm_update/Updater/UpdateStep.h +++ b/tdm_update/libtdm_update/Updater/UpdateStep.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/UpdateView.h b/tdm_update/libtdm_update/Updater/UpdateView.h index 5e0a1e02c..4db534102 100644 --- a/tdm_update/libtdm_update/Updater/UpdateView.h +++ b/tdm_update/libtdm_update/Updater/UpdateView.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/Updater.cpp b/tdm_update/libtdm_update/Updater/Updater.cpp index 1096bdc16..159ab09be 100644 --- a/tdm_update/libtdm_update/Updater/Updater.cpp +++ b/tdm_update/libtdm_update/Updater/Updater.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Updater.h" diff --git a/tdm_update/libtdm_update/Updater/Updater.h b/tdm_update/libtdm_update/Updater/Updater.h index e54493d04..c8135a11e 100644 --- a/tdm_update/libtdm_update/Updater/Updater.h +++ b/tdm_update/libtdm_update/Updater/Updater.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Updater/UpdaterOptions.h b/tdm_update/libtdm_update/Updater/UpdaterOptions.h index c9609abed..9c681a67a 100644 --- a/tdm_update/libtdm_update/Updater/UpdaterOptions.h +++ b/tdm_update/libtdm_update/Updater/UpdaterOptions.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Util.cpp b/tdm_update/libtdm_update/Util.cpp index 4ec8de37f..734a7a2b4 100644 --- a/tdm_update/libtdm_update/Util.cpp +++ b/tdm_update/libtdm_update/Util.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Util.h" diff --git a/tdm_update/libtdm_update/Util.h b/tdm_update/libtdm_update/Util.h index b9509c312..78c2abd8f 100644 --- a/tdm_update/libtdm_update/Util.h +++ b/tdm_update/libtdm_update/Util.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/Zip/Zip.cpp b/tdm_update/libtdm_update/Zip/Zip.cpp index c1e4c9807..0b107cc7c 100644 --- a/tdm_update/libtdm_update/Zip/Zip.cpp +++ b/tdm_update/libtdm_update/Zip/Zip.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include "Zip.h" diff --git a/tdm_update/libtdm_update/Zip/Zip.h b/tdm_update/libtdm_update/Zip/Zip.h index d118661de..51f35a2a4 100644 --- a/tdm_update/libtdm_update/Zip/Zip.h +++ b/tdm_update/libtdm_update/Zip/Zip.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/libtdm_update/libtdm_update.vcproj b/tdm_update/libtdm_update/libtdm_update.vcproj deleted file mode 100644 index 298045370..000000000 --- a/tdm_update/libtdm_update/libtdm_update.vcproj +++ /dev/null @@ -1,362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tdm_update/libtdm_update/libtdm_update.vcxproj b/tdm_update/libtdm_update/libtdm_update.vcxproj new file mode 100644 index 000000000..f83d9a89a --- /dev/null +++ b/tdm_update/libtdm_update/libtdm_update.vcxproj @@ -0,0 +1,139 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} + libtdm_update + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)/Build/lib/$(Configuration)\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + $(SolutionDir)/Build/lib/$(Configuration)\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/../win32/subversion/include;$(SolutionDir)/../win32/subversion/include/apr;%(AdditionalIncludeDirectories) + DEBUG;WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;USE_LIBSVN;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Level3 + EditAndContinue + 4355;4996;%(DisableSpecificWarnings) + + + %(AdditionalLibraryDirectories) + + + + + /MP %(AdditionalOptions) + MaxSpeed + true + false + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/../win32/subversion/include;$(SolutionDir)/../win32/subversion/include/apr;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;USE_LIBSVN;%(PreprocessorDefinitions) + MultiThreaded + true + Level3 + ProgramDatabase + 4355;4996;%(DisableSpecificWarnings) + + + %(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tdm_update/libtdm_update/libtdm_update.vcxproj.filters b/tdm_update/libtdm_update/libtdm_update.vcxproj.filters new file mode 100644 index 000000000..ef2e60f20 --- /dev/null +++ b/tdm_update/libtdm_update/libtdm_update.vcxproj.filters @@ -0,0 +1,119 @@ + + + + + {5c8a1119-fea7-417c-9b44-66d5ab9df59c} + + + {847ab4fe-ace0-4cb9-83d5-b57df7b99fc1} + + + {a265ae68-6dfc-4cc5-a9eb-13f5a52ac0b7} + + + {9ffd21da-5f63-47c3-9f90-89781d64e5d8} + + + + + Http + + + Http + + + Http + + + Http + + + Http + + + Zip + + + Updater + + + Updater + + + Packager + + + + + + + + + + + Http + + + Http + + + Http + + + Http + + + Http + + + Http + + + Zip + + + Updater + + + Updater + + + Updater + + + Updater + + + Updater + + + Updater + + + Updater + + + Packager + + + Packager + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tdm_update/tdm_package/LogWriters.h b/tdm_update/tdm_package/LogWriters.h index a85f6d61c..6b8451fb3 100644 --- a/tdm_update/tdm_package/LogWriters.h +++ b/tdm_update/tdm_package/LogWriters.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Packager - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_package/SConscript.tdm_package b/tdm_update/tdm_package/SConscript.tdm_package index 97f5b0196..260e55a84 100644 --- a/tdm_update/tdm_package/SConscript.tdm_package +++ b/tdm_update/tdm_package/SConscript.tdm_package @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Packager -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Packager (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** # The Dark Mod Packager build script # Adapted from id's game sconscript diff --git a/tdm_update/tdm_package/SConstruct b/tdm_update/tdm_package/SConstruct index 22daa040b..91eaa8fa8 100644 --- a/tdm_update/tdm_package/SConstruct +++ b/tdm_update/tdm_package/SConstruct @@ -1,14 +1,24 @@ # -*- mode: python -*- # coding=utf-8 -############################################################################# +#***************************************************************************** +# The Dark Mod GPL Source Code # -# PROJECT: The Dark Mod - Updater -# $Revision$ -# $Date$ -# $Author$ +# This file is part of the The Dark Mod Source Code, originally based +# on the Doom 3 GPL Source Code as published in 2011. # -############################################################################## +# The Dark Mod Source Code is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. For details, see LICENSE.TXT. +# +# Project: The Dark Mod Packager (http://www.thedarkmod.com/) +# +# $Revision$ (Revision of last commit) +# $Date$ (Date of last commit) +# $Author$ (Author of last commit) +# +#***************************************************************************** # The Dark Mod Packager build script for Linux # Based on id's game sconscript diff --git a/tdm_update/tdm_package/tdm_package.cpp b/tdm_update/tdm_package/tdm_package.cpp index 355fb4904..54f400c67 100644 --- a/tdm_update/tdm_package/tdm_package.cpp +++ b/tdm_update/tdm_package/tdm_package.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Packager - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include #include diff --git a/tdm_update/tdm_package/tdm_package.vcproj b/tdm_update/tdm_package/tdm_package.vcproj deleted file mode 100644 index c02810a05..000000000 --- a/tdm_update/tdm_package/tdm_package.vcproj +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tdm_update/tdm_package/tdm_package.vcxproj b/tdm_update/tdm_package/tdm_package.vcxproj new file mode 100644 index 000000000..98d4d6ab0 --- /dev/null +++ b/tdm_update/tdm_package/tdm_package.vcxproj @@ -0,0 +1,139 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A181019F-4348-4574-B88C-DEAAA2B5CB7D} + tdm_package + Win32Proj + + + + Application + MultiByte + true + + + Application + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)bin\ + $(SolutionDir)Build/$(ProjectName)/$(Configuration)\ + true + $(SolutionDir)bin\ + $(SolutionDir)Build/$(ProjectName)/$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;$(SolutionDir)/../win32/subversion/include;$(SolutionDir)/../win32/subversion/include/apr;%(AdditionalIncludeDirectories) + DEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;TDM_USE_OLD_CRC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + 4355;4996;%(DisableSpecificWarnings) + + + libtdm_update.lib;ZipLoader.lib;WS2_32.lib;libsvn_client-1.lib;libapr-1.lib;libsvn_subr-1.lib;libsvn_fs_fs-1.lib;libsvn_fs_base-1.lib;libsvn_fs-1.lib;libsvn_wc-1.lib;%(AdditionalDependencies) + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;$(SolutionDir)/../win32/subversion/lib;$(SolutionDir)/../win32/subversion/lib/apr;$(SolutionDir)/../win32/subversion/lib/apr-util;$(SolutionDir)/../win32/subversion/lib/serf;$(SolutionDir)/../win32/subversion/lib/neon;$(SolutionDir)/../win32/subversion/lib/sasl;%(AdditionalLibraryDirectories) + LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) + true + Console + mainCRTStartup + + + MachineX86 + + + Copying Subversion binaries to bin/ + echo copy $(SolutionDir)..\win32\subversion\bin\*.dll $(OutDir). +copy $(SolutionDir)..\win32\subversion\bin\*.dll $(OutDir) + + + + + + /MP %(AdditionalOptions) + MaxSpeed + true + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;$(SolutionDir)/../win32/subversion/include;$(SolutionDir)/../win32/subversion/include/apr;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + 4355;4996;%(DisableSpecificWarnings) + + + libtdm_update.lib;ZipLoader.lib;WS2_32.lib;libsvn_client-1.lib;libapr-1.lib;libsvn_subr-1.lib;libsvn_fs_fs-1.lib;libsvn_fs_base-1.lib;libsvn_fs-1.lib;libsvn_wc-1.lib;%(AdditionalDependencies) + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;$(SolutionDir)/../win32/subversion/lib;$(SolutionDir)/../win32/subversion/lib/apr;$(SolutionDir)/../win32/subversion/lib/apr-util;$(SolutionDir)/../win32/subversion/lib/serf;$(SolutionDir)/../win32/subversion/lib/neon;$(SolutionDir)/../win32/subversion/lib/sasl;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + true + Console + true + true + mainCRTStartup + false + + + MachineX86 + + + Copying Subversion binaries to bin/ + echo copy $(SolutionDir)..\win32\subversion\bin\*.dll $(OutDir). +copy $(SolutionDir)..\win32\subversion\bin\*.dll $(OutDir) + + + + + + + + + + + + + + + {46cc0f23-49e6-4fab-a1a0-bd87c4792319} + false + + + + + + \ No newline at end of file diff --git a/tdm_update/tdm_package/tdm_package.vcxproj.filters b/tdm_update/tdm_package/tdm_package.vcxproj.filters new file mode 100644 index 000000000..61d15ab4c --- /dev/null +++ b/tdm_update/tdm_package/tdm_package.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tdm_update/tdm_update.cpp b/tdm_update/tdm_update.cpp index 9979e6684..338b7bc24 100644 --- a/tdm_update/tdm_update.cpp +++ b/tdm_update/tdm_update.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #include #include diff --git a/tdm_update/tdm_update.sln b/tdm_update/tdm_update.sln index 883c273d8..c86afe18b 100644 --- a/tdm_update/tdm_update.sln +++ b/tdm_update/tdm_update.sln @@ -1,21 +1,12 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_update", "tdm_update.vcproj", "{7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}" - ProjectSection(ProjectDependencies) = postProject - {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} = {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} - EndProjectSection +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_update", "tdm_update.vcxproj", "{7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtdm_update", "libtdm_update\libtdm_update.vcproj", "{46CC0F23-49E6-4FAB-A1A0-BD87C4792319}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtdm_update", "libtdm_update\libtdm_update.vcxproj", "{46CC0F23-49E6-4FAB-A1A0-BD87C4792319}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_package", "tdm_package\tdm_package.vcproj", "{A181019F-4348-4574-B88C-DEAAA2B5CB7D}" - ProjectSection(ProjectDependencies) = postProject - {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} = {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} - EndProjectSection +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_package", "tdm_package\tdm_package.vcxproj", "{A181019F-4348-4574-B88C-DEAAA2B5CB7D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_update_mfc", "tdm_update_mfc\tdm_update_mfc.vcproj", "{D1A70E0F-90AF-443F-B512-8A25E99FE568}" - ProjectSection(ProjectDependencies) = postProject - {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} = {46CC0F23-49E6-4FAB-A1A0-BD87C4792319} - EndProjectSection +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tdm_update_mfc", "tdm_update_mfc\tdm_update_mfc.vcxproj", "{D1A70E0F-90AF-443F-B512-8A25E99FE568}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/tdm_update/tdm_update.vcproj b/tdm_update/tdm_update.vcproj deleted file mode 100644 index 3c387a5a7..000000000 --- a/tdm_update/tdm_update.vcproj +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tdm_update/tdm_update.vcxproj b/tdm_update/tdm_update.vcxproj new file mode 100644 index 000000000..8ec7648db --- /dev/null +++ b/tdm_update/tdm_update.vcxproj @@ -0,0 +1,133 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7DFE38AC-1418-4B91-A7CD-E6F18FB44F4D} + tdm_update + Win32Proj + + + + Application + false + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)/bin\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + true + false + $(SolutionDir)/bin\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + false + true + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;%(AdditionalIncludeDirectories) + DEBUG;WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;TDM_USE_OLD_CRC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + 4355;4996;%(DisableSpecificWarnings) + + + libtdm_update.lib;libcurl.lib;ZipLoader.lib;WS2_32.lib;psapi.lib;%(AdditionalDependencies) + $(OutDir)ConsoleUpdater/tdm_update.exe + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;%(AdditionalLibraryDirectories) + LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) + true + Console + mainCRTStartup + false + + + MachineX86 + + + + + /MP %(AdditionalOptions) + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + 4355;4996;%(DisableSpecificWarnings) + + + libtdm_update.lib;libcurl.lib;ZipLoader.lib;WS2_32.lib;psapi.lib;%(AdditionalDependencies) + $(OutDir)ConsoleUpdater/tdm_update.exe + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + false + Console + true + true + mainCRTStartup + false + + + MachineX86 + + + + + + + + + + + + + + + + {46cc0f23-49e6-4fab-a1a0-bd87c4792319} + false + + + + + + \ No newline at end of file diff --git a/tdm_update/tdm_update.vcxproj.filters b/tdm_update/tdm_update.vcxproj.filters new file mode 100644 index 000000000..0d7056f92 --- /dev/null +++ b/tdm_update/tdm_update.vcxproj.filters @@ -0,0 +1,34 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.cpp b/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.cpp index ffb69d852..cd0eb03b3 100644 --- a/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.cpp +++ b/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // AdvancedOptionsDialog.cpp : implementation file // diff --git a/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.h b/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.h index d8a0f00b4..9c92c8e9e 100644 --- a/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.h +++ b/tdm_update/tdm_update_mfc/AdvancedOptionsDialog.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/CommandLineInfo.h b/tdm_update/tdm_update_mfc/CommandLineInfo.h index 3cafd1b4a..1c3a81e65 100644 --- a/tdm_update/tdm_update_mfc/CommandLineInfo.h +++ b/tdm_update/tdm_update_mfc/CommandLineInfo.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/DownloadProgressHandler.h b/tdm_update/tdm_update_mfc/DownloadProgressHandler.h index dd1b57619..cbc600a96 100644 --- a/tdm_update/tdm_update_mfc/DownloadProgressHandler.h +++ b/tdm_update/tdm_update_mfc/DownloadProgressHandler.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/FileProgressHandler.h b/tdm_update/tdm_update_mfc/FileProgressHandler.h index 26c5cc44f..9ed653dd2 100644 --- a/tdm_update/tdm_update_mfc/FileProgressHandler.h +++ b/tdm_update/tdm_update_mfc/FileProgressHandler.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/LogViewer.cpp b/tdm_update/tdm_update_mfc/LogViewer.cpp index 529bf6b44..cb8dc2896 100644 --- a/tdm_update/tdm_update_mfc/LogViewer.cpp +++ b/tdm_update/tdm_update_mfc/LogViewer.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // LogViewer.cpp : implementation file // diff --git a/tdm_update/tdm_update_mfc/LogViewer.h b/tdm_update/tdm_update_mfc/LogViewer.h index e7cf52a7e..ba213aa70 100644 --- a/tdm_update/tdm_update_mfc/LogViewer.h +++ b/tdm_update/tdm_update_mfc/LogViewer.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/LogWriters.h b/tdm_update/tdm_update_mfc/LogWriters.h index 81a042fcd..105300b31 100644 --- a/tdm_update/tdm_update_mfc/LogWriters.h +++ b/tdm_update/tdm_update_mfc/LogWriters.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/UpdaterDialog.cpp b/tdm_update/tdm_update_mfc/UpdaterDialog.cpp index b43746bcb..b88686d76 100644 --- a/tdm_update/tdm_update_mfc/UpdaterDialog.cpp +++ b/tdm_update/tdm_update_mfc/UpdaterDialog.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // UpdaterDialog.cpp : implementation file diff --git a/tdm_update/tdm_update_mfc/UpdaterDialog.h b/tdm_update/tdm_update_mfc/UpdaterDialog.h index 3118c1adc..e05a9d26d 100644 --- a/tdm_update/tdm_update_mfc/UpdaterDialog.h +++ b/tdm_update/tdm_update_mfc/UpdaterDialog.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ #pragma once diff --git a/tdm_update/tdm_update_mfc/Win7Decls.h b/tdm_update/tdm_update_mfc/Win7Decls.h index 099cfe444..51323ddf6 100644 --- a/tdm_update/tdm_update_mfc/Win7Decls.h +++ b/tdm_update/tdm_update_mfc/Win7Decls.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ /** * greebo: I copied the main part of this auxiliary header diff --git a/tdm_update/tdm_update_mfc/stdafx.cpp b/tdm_update/tdm_update_mfc/stdafx.cpp index 7fce602da..23e333712 100644 --- a/tdm_update/tdm_update_mfc/stdafx.cpp +++ b/tdm_update/tdm_update_mfc/stdafx.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // stdafx.cpp : source file that includes just the standard includes diff --git a/tdm_update/tdm_update_mfc/stdafx.h b/tdm_update/tdm_update_mfc/stdafx.h index e7a8d2771..1200fb9aa 100644 --- a/tdm_update/tdm_update_mfc/stdafx.h +++ b/tdm_update/tdm_update_mfc/stdafx.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, diff --git a/tdm_update/tdm_update_mfc/tdm_update_mfc.cpp b/tdm_update/tdm_update_mfc/tdm_update_mfc.cpp index 196d093e4..3905cf214 100644 --- a/tdm_update/tdm_update_mfc/tdm_update_mfc.cpp +++ b/tdm_update/tdm_update_mfc/tdm_update_mfc.cpp @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // tdm_update_mfc.cpp : Defines the class behaviors for the application. diff --git a/tdm_update/tdm_update_mfc/tdm_update_mfc.h b/tdm_update/tdm_update_mfc/tdm_update_mfc.h index fab26381f..0549132d8 100644 --- a/tdm_update/tdm_update_mfc/tdm_update_mfc.h +++ b/tdm_update/tdm_update_mfc/tdm_update_mfc.h @@ -1,11 +1,21 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - Updater - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod Updater (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ // tdm_update_mfc.h : main header file for the PROJECT_NAME application diff --git a/tdm_update/tdm_update_mfc/tdm_update_mfc.vcproj b/tdm_update/tdm_update_mfc/tdm_update_mfc.vcproj deleted file mode 100644 index 045f56bb8..000000000 --- a/tdm_update/tdm_update_mfc/tdm_update_mfc.vcproj +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj b/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj new file mode 100644 index 000000000..95deb8c4b --- /dev/null +++ b/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Template + Win32 + + + + {D1A70E0F-90AF-443F-B512-8A25E99FE568} + tdm_update_mfc + MFCProj + + + + Application + Static + Unicode + true + + + Application + Static + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)/bin\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + true + $(SolutionDir)/bin\ + $(SolutionDir)/Build/$(ProjectName)/$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + _DEBUG;%(PreprocessorDefinitions) + false + true + + + Disabled + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + + + libtdm_update.lib;libcurl.lib;ZipLoader.lib;WS2_32.lib;psapi.lib;%(AdditionalDependencies) + $(OutDir)GuiUpdater/tdm_update.exe + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;%(AdditionalLibraryDirectories) + LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) + true + Windows + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + false + true + + + /MP %(AdditionalOptions) + MaxSpeed + true + $(SolutionDir)/../include;$(SolutionDir)/../include/zlib;$(SolutionDir)/../win32/include;$(SolutionDir)/libtdm_update;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + MultiThreaded + true + Use + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + + + libtdm_update.lib;libcurl.lib;ZipLoader.lib;WS2_32.lib;psapi.lib;%(AdditionalDependencies) + $(OutDir)GuiUpdater/tdm_update.exe + $(SolutionDir)/Build/lib/$(Configuration);$(SolutionDir)/../win32/lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {46cc0f23-49e6-4fab-a1a0-bd87c4792319} + false + + + + + + + + + + + \ No newline at end of file diff --git a/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj.filters b/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj.filters new file mode 100644 index 000000000..fb948d7d6 --- /dev/null +++ b/tdm_update/tdm_update_mfc/tdm_update_mfc.vcxproj.filters @@ -0,0 +1,88 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tools/Help/MT_help.htm b/tools/Help/MT_help.htm new file mode 100644 index 000000000..38fffb6a2 --- /dev/null +++ b/tools/Help/MT_help.htm @@ -0,0 +1,213 @@ + + + + + Material Types + + + +
+

Material Types

+

 

+

Version 1.00 – Friday + 13th June 2003 – John J Scott

+

 

+

Materials are defined by .mtt files in the base/materials/ + folder. The name of the file is the name of the material (eg. + “materials/sand.mtt” is called “sand”).

+

 

+

A .mtt file looks like this –

+

 

+

materialType

+

{

+

            +description        “A phrase that describes +this material type”

+

            +rgb                   +r,g,b

+

}

+

 

+

The r, g and b components are defined as 0 to 255. (eg. + 255,0,0 would be bright red)

+

 

+

The material type can be defined in the material in 2 ways –

+
    +
  1. + The keyword “materialType”
  2. +
+

 

+

The following material would have the material type of + “concrete”

+

 

+

textures/wall/texture

+

{

+

qer_editorimage            textures/wall/texture_d

+

 

+

            materialType              concrete

+

 

+

bumpmap                     addnormals +( textures/wall/texture_local, heightmap ( textures/wall/texture_h, 1 ) )

+

diffusemap                    textures/wall/texture_d

+

specularmap                 textures/wall/texture_s

+

}

+

 

+
    +
  1. + The keyword “materialImage” can be used to specify an image to indirect into. + The rgb values in the material image are compared with the rgb values defined + in the .mtt files to define the material type. Eg. A window frame would have + material type wood wherever the frame was, and material type glass wherever the + glass was. +
  2. +
+

 

+

The following material will use +the hit image map “textures/wall/texture_hit” to work out the material type, +but return metal should the hit image not yield a valid material.

+

 

+

textures/wall/texture

+

{

+

qer_editorimage            textures/wall/texture_d

+

 

+

            materialType              metal

+

            materialImage            textures/wall/texture_hit

+

 

+

bumpmap                     addnormals +( textures/wall/texture_local, heightmap ( textures/wall/texture_h, 1 ) )

+

diffusemap                    textures/wall/texture_d

+

specularmap                 textures/wall/texture_s

+

}

+

 

+

The currently defined materials +are –

+

 

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Material Type

+
+

RGB Value

+
+

 

+
+

 

+
+

None

+
+

0,0,0

+
+

Solidmetal

+
+

178,178,178

+
+

HollowMetal

+
+

102,102,102

+
+

Sand

+
+

255,255,0

+
+

Flesh

+
+

204,102,102

+
+
+

 

+

 

+

Notes -

+
    +
  1. + There are no limits to the dimensions of the material type image. However, + using half the width and height would be a good balance of accuracy vs. memory. + If more accuracy is required, go up to the same size. There is no gain (and + hence no point) in going larger than the material the hit image will be applied + to.
  2. +
  3. + If the exact rgb values are used, loading up the hit images will be quick. It + will check for the nearest match, but this takes a little longer.
  4. +
  5. + Generally, use a realistic colour for the material type. This way, the diffuse + map will work naturally as a quick and dirty starting point. For example, flesh + is pink so that any pink found on a hit material image will return a material + type of flesh.
  6. +
  7. + Try to keep a good separation of material type rgb values. Having two very + close together makes the hit images harder to edit.
  8. +
+

 

+

 

+

 

+

 

+

 

+

 

+
+ + diff --git a/tools/Help/MVH_Controls.htm b/tools/Help/MVH_Controls.htm new file mode 100644 index 000000000..3e3eeb850 --- /dev/null +++ b/tools/Help/MVH_Controls.htm @@ -0,0 +1,239 @@ + + + + Controls + + + + + + + + + +
+

Toolbar +Buttons + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Button

+
+

Description

+
+

+

+
+

Opens a mesh file. The supported formats are MD5MESH, + LWO and ASE. This acts the same as the Open Mesh command in the File menu.

+
+

+

+
+

Opens an animation file. The supported format is + MD5ANIM. This acts the same as the Open + Anim + command in the File Menu.

+
+

+

+
+

Go to the first animation in the sequence.

+
+

+

+
+

Go to the previous animation in the sequence

+
+

+

+
+

Play the current sequence from the start.

+
+

+

+
+

Stop the current sequence and retain the current + frame.

+
+

+

+
+

Go to the next animation in the sequence.

+
+

+

+
+

Go to the last animation in the sequence.

+
+

+

+
+

Loop the sequence of animations. This defaults to on.

+
+

+

+
+

Remove the movement embedded into the animation. This + stops the models “walking” off the map, but can also make + animations where there is subtle movement look wrong.

+
+

+

+
+

Toggle diffuse lighting on and off. This defaults to + on.

+
+

+

+
+

Toggle + specular + lighting on and off. This defaults to on.

+
+

+

+
+

Display the window containing the list of surfaces + that make up the model. This window can be used to turn selected surfaces on + and off, and to show the triangles that make up each surface.

+
+

+

+
+

Display the window containing the tree view of the + bones that make up the skeleton. In conjunction with the show skeleton option, + this allows the user to see which bones are where and at which orientation.

+
+

+

+
+

Cycles through the various show skeleton options. + Pressed once, it will show the skeleton and the mesh. Pressed again, it will + show the skeleton without the mesh. The bone window can be used to reduce the + data to a more manageable level.

+
+

+

+
+

Toggles primitive view on and off. Only surfaces + selected in the surface window will show their primitives. When this button is + first pressed, all surfaces are selected.

+
+

+

+
Toggles the show overdraw mode. This can + be used to check for models being textured multiple times.
+

+

+
+

Cycles through the various show normal and show + tangent options.

+
+

+

+
+

Resets the camera to its initial viewing position.

+
+

+

+
+

Reloads any changed textures. Does not reload any + material files.

+
+

 

+
+ + diff --git a/tools/Help/MVH_Issues.htm b/tools/Help/MVH_Issues.htm new file mode 100644 index 000000000..f091fb92c --- /dev/null +++ b/tools/Help/MVH_Issues.htm @@ -0,0 +1,23 @@ + + + + + + + + +

Known issues

+

* The animations always start from the first animation when the play + button is hit.

+

* The bounding box will still deform as if the model is animating while the + animation is stopped.

+

* Player cocking weapon sound on startup

+

* Player assets load on startup. This makes the startup longer than it should + be.

+

* Unchecking or deleting an animation in the sequence will continue to play that + animation until it finishes.

+

* Animations do not blend together

+

 

+

 

+ + diff --git a/tools/Help/MVH_Misc.htm b/tools/Help/MVH_Misc.htm new file mode 100644 index 000000000..0400468be --- /dev/null +++ b/tools/Help/MVH_Misc.htm @@ -0,0 +1,56 @@ + + + + + + + + +

Miscellaneous Controls

+

Spawn Class Drop Down

+

Collates the entity types by spawn class for easier navigation of ModView. + Whenever a new spawn class is selected, the entity type drop down box is + populated with all the entity types that have the just selected spawn class. A + loaded mesh will have the spawn class of "<file>".

+

Entity Type Drop Down

+

A list of entity types with the above selected spawn class. Whenever an entity + type is selected, the associated mesh is loaded and displayed. The def file is + parsed and the relevant animations are added to the "Animations Available" list + view box. A loaded mesh will have the entity type of it's filename within + chevrons. eg. "<models/md5/meshes/player.md5mesh>".

+

Animations Available List

+

This lists the animations found in the def file. You can select one or many and + move them to the current animation sequence with the ">>" button to the + right of this list. If an animation will not go to the sequence window, then it + was not found or there was some other problem with it. Loaded animations will + go here as their filename, and also to the "Animations Loaded" list. These + loaded animations will be remembered as associated to this spawn class/entity + type combination as long as ModView is running.

+

Animations Loaded List

+

This is the list of animations that have been successfully loaded and can be + played or stepped through using the toolbar controls. Unchecking a particular + animation in the list will temporarily disable the playback of this animation + in the sequence. Selecting one or more animations and pressing the delete key + will remove them from the list permenantly; that is, until you re add them from + the "Animations Available" list.

+

Animation Frame Slider & Text

+

The slider displays the current frame of animation in the current sequence of + animations and takes into account deleted and disabled animations. Hitting + either end of the slider acts the same as pressing the stop toolbar control but + steps one frame at a time in the desired direction. Hitting the slider bar + either side of the button advances the animation ten frames in the desired + direction. The slider button can be dragged to a specific frame. The text + above this slider shows the exact frame number out of how many frames, and the + current playing animation in brackets.

+

Timescale Slider

+

The slider sets the global speed of the animation playback. It defaults to 1.0 + and can go from the minimum of 0.02 to the maximum of 2.0 (double the playback + speed).

+

Light Intensity Sliders

+

There are six lights surrounding the model and these sliders adjust their + brightness. The range is from 0 (completely black) to 255 (bright white). The + starting default is 128 (medium grey). There are no current options for + multicoloured lights.

+

 

+ + diff --git a/tools/Help/MVH_Mouse.htm b/tools/Help/MVH_Mouse.htm new file mode 100644 index 000000000..1a496a2a8 --- /dev/null +++ b/tools/Help/MVH_Mouse.htm @@ -0,0 +1,194 @@ + + + + + + + + Mouse controls + + + + +
+

Mouse controls

+

All these operations are performed while the mouse cursor is within the bounds + of the viewing window. The controls are based on the Maya scheme of control + with a few additions and changes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Mouse + button

+
+

Shift

+
+

Description

+
+

Left

+
+

No

+
+

Rotates the camera around the object in all three + dimensions.

+
+

Middle

+
+

No

+
+

Pans the camera around the object. Both the camera + and camera target move left, right, up and down relative to the model.

+
+

Right

+
+

No

+
+

Moving left and right alter the field of view from + the default value of 60. Moving up and down alter the distance between the + camera and the camera target.

+
+

Left

+
+

Yes

+
+

Pans the camera and model in the world. The camera, + camera target and model move left, right, up and down in the + worild.

+
+

Middle

+
+

Yes

+
+

Modifies the pitch and yaw of the model. This rotates + the model while leaving everything else in place.

+
+

Right

+
+

Yes

+
+

Pans the camera target in the world.

+
+

 

+
+ + diff --git a/tools/Help/MVH_Overview.htm b/tools/Help/MVH_Overview.htm new file mode 100644 index 000000000..90b887591 --- /dev/null +++ b/tools/Help/MVH_Overview.htm @@ -0,0 +1,84 @@ + + + + + + + + Overview + + + + +
+

Overview

+

  +

+

ModView + is a tool to view Doom3/Quake4 models and animations. It supports any format + that the Doom3 engine can import.

+

 

+

There are two main ways to view models in this tool.

+

 

+

1. Directly from files.

+

Use the open mesh toolbar button to load up an MD5MESH, LWO or + ASE file. The model will be displayed in the view window with all the assets + the game can find.

+

Use the open animation toolbar button to load up an MD5ANIM + file. Hit the play toolbar button to see the model with that animation. If the + model has no bones, or the animation was not defined for that mesh, then + unpredictable results will happen.

+

 

+

2. + Via + def files

+

Use the “Spawn Class” drop down list to pick a spawn + class, + this will populate the “Entity Type” drop down list with every entity type that + has that spawn class. Select your desired entity type from that list and the + mesh will be loaded up for that entity type. The animations in the def file for + that entity type will appear in the “Animations Available” list view box. Add + these to the animation sequence using the >> button. Hit play to view + them.

+

 

+

Loaded files have the spawn class of <file> and the + entity type of <mesh name>. Within sessions, any loaded animations for a + particular mesh will be remembered.

+

 

+

Sounds based on frame commands will play when loading a model + through the def file system. + Directly loaded files will +not as they do not have the def file information. + However, this means a def file is not required to load up and view a model.

+

 

+

 

+
+ + diff --git a/tools/Help/Tools.hhc b/tools/Help/Tools.hhc new file mode 100644 index 000000000..2a3af5ecc --- /dev/null +++ b/tools/Help/Tools.hhc @@ -0,0 +1,56 @@ + + + + + + + + + + +
    +
  • + + +
      +
    • + + + +
    • + + +
        +
      • + + + +
      +
    • + + +
        +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      +
    +
+ diff --git a/tools/Help/Tools.hhk b/tools/Help/Tools.hhk new file mode 100644 index 000000000..c0ba08a9a --- /dev/null +++ b/tools/Help/Tools.hhk @@ -0,0 +1,9 @@ + + + + + + +
    +
+ diff --git a/tools/Help/Tools.hhp b/tools/Help/Tools.hhp new file mode 100644 index 000000000..1675c316d --- /dev/null +++ b/tools/Help/Tools.hhp @@ -0,0 +1,13 @@ +[OPTIONS] +Compatibility=1.1 or later +Compiled file=Tools.chm +Contents file=Tools.hhc +Default topic=default.htm +Display compile progress=No +Index file=Tools.hhk +Language=0x409 English (United States) +Title=Quake 4 Tools Help File + + +[INFOTYPES] + diff --git a/tools/Help/default.htm b/tools/Help/default.htm new file mode 100644 index 000000000..4aea5db68 --- /dev/null +++ b/tools/Help/default.htm @@ -0,0 +1,10 @@ + + + + + + +

Quake 4 tools table of contents

+

 

+ + diff --git a/tools/Help/images/FirstAnim.png b/tools/Help/images/FirstAnim.png new file mode 100644 index 000000000..23aad500c Binary files /dev/null and b/tools/Help/images/FirstAnim.png differ diff --git a/tools/Help/images/OpenAnim.png b/tools/Help/images/OpenAnim.png new file mode 100644 index 000000000..5dc6ccc56 Binary files /dev/null and b/tools/Help/images/OpenAnim.png differ diff --git a/tools/Help/images/OpenMesh.png b/tools/Help/images/OpenMesh.png new file mode 100644 index 000000000..37277071a Binary files /dev/null and b/tools/Help/images/OpenMesh.png differ diff --git a/tools/Help/images/Play.png b/tools/Help/images/Play.png new file mode 100644 index 000000000..1b05e81c8 Binary files /dev/null and b/tools/Help/images/Play.png differ diff --git a/tools/Help/images/PrevAnim.png b/tools/Help/images/PrevAnim.png new file mode 100644 index 000000000..7c7a870b3 Binary files /dev/null and b/tools/Help/images/PrevAnim.png differ diff --git a/tools/Help/images/animloop.png b/tools/Help/images/animloop.png new file mode 100644 index 000000000..2165969c5 Binary files /dev/null and b/tools/Help/images/animloop.png differ diff --git a/tools/Help/images/diffuse.png b/tools/Help/images/diffuse.png new file mode 100644 index 000000000..934465278 Binary files /dev/null and b/tools/Help/images/diffuse.png differ diff --git a/tools/Help/images/lastanim.png b/tools/Help/images/lastanim.png new file mode 100644 index 000000000..72e69282a Binary files /dev/null and b/tools/Help/images/lastanim.png differ diff --git a/tools/Help/images/nextanim.png b/tools/Help/images/nextanim.png new file mode 100644 index 000000000..59f18facb Binary files /dev/null and b/tools/Help/images/nextanim.png differ diff --git a/tools/Help/images/orgoff.png b/tools/Help/images/orgoff.png new file mode 100644 index 000000000..f3b2e67e7 Binary files /dev/null and b/tools/Help/images/orgoff.png differ diff --git a/tools/Help/images/reloadtex.png b/tools/Help/images/reloadtex.png new file mode 100644 index 000000000..07a32ccea Binary files /dev/null and b/tools/Help/images/reloadtex.png differ diff --git a/tools/Help/images/resetcam.png b/tools/Help/images/resetcam.png new file mode 100644 index 000000000..9fad058dc Binary files /dev/null and b/tools/Help/images/resetcam.png differ diff --git a/tools/Help/images/showbones.png b/tools/Help/images/showbones.png new file mode 100644 index 000000000..2929dff80 Binary files /dev/null and b/tools/Help/images/showbones.png differ diff --git a/tools/Help/images/shownorms.png b/tools/Help/images/shownorms.png new file mode 100644 index 000000000..7883fb68c Binary files /dev/null and b/tools/Help/images/shownorms.png differ diff --git a/tools/Help/images/showoverdraw.png b/tools/Help/images/showoverdraw.png new file mode 100644 index 000000000..517eb13ee Binary files /dev/null and b/tools/Help/images/showoverdraw.png differ diff --git a/tools/Help/images/showskel.png b/tools/Help/images/showskel.png new file mode 100644 index 000000000..912364f0b Binary files /dev/null and b/tools/Help/images/showskel.png differ diff --git a/tools/Help/images/showsurf.png b/tools/Help/images/showsurf.png new file mode 100644 index 000000000..104eb6b18 Binary files /dev/null and b/tools/Help/images/showsurf.png differ diff --git a/tools/Help/images/showtris.png b/tools/Help/images/showtris.png new file mode 100644 index 000000000..5d7dcbd5a Binary files /dev/null and b/tools/Help/images/showtris.png differ diff --git a/tools/Help/images/specular.png b/tools/Help/images/specular.png new file mode 100644 index 000000000..23818d936 Binary files /dev/null and b/tools/Help/images/specular.png differ diff --git a/tools/Help/images/stop.png b/tools/Help/images/stop.png new file mode 100644 index 000000000..58e0a719b Binary files /dev/null and b/tools/Help/images/stop.png differ diff --git a/tools/af/DialogAF.cpp b/tools/af/DialogAF.cpp new file mode 100644 index 000000000..866ebaaec --- /dev/null +++ b/tools/af/DialogAF.cpp @@ -0,0 +1,619 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFName.h" +#include "DialogAFView.h" +#include "DialogAFProperties.h" +#include "DialogAFBody.h" +#include "DialogAFConstraint.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +// DialogAF + +#define AFTAB_VIEW 0x01 +#define AFTAB_PROPERTIES 0x02 +#define AFTAB_BODIES 0x03 +#define AFTAB_CONSTRAINTS 0x04 + +toolTip_t DialogAF::toolTips[] = { + { IDC_COMBO_AF, "select an articulated figure for editing" }, + { IDC_BUTTON_AF_NEW, "create a new articulated figure" }, + { IDC_BUTTON_AF_DELETE, "delete the selected articulated figure" }, + { IDC_BUTTON_AF_SPAWN, "spawn ingame entity using the selected articulated figure" }, + { IDC_BUTTON_AF_TPOSE, "set ingame entity using the selected articulated figure back into T-Pose" }, + { IDC_BUTTON_AF_KILL, "kill ingame entity using the selected articulated figure" }, + { IDC_BUTTON_AF_SAVE, "save the selected articulated figure" }, + { IDCANCEL, "cancel all changes to all articulated figures" }, + { 0, NULL } +}; + + +DialogAF *g_AFDialog = NULL; + + +IMPLEMENT_DYNAMIC(DialogAF, CDialog) + +/* +================ +DialogAF::DialogAF +================ +*/ +DialogAF::DialogAF( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogAF::IDD, pParent) + , file(NULL) +{ + wndTabs = NULL; + wndTabDisplay = NULL; +} + +/* +================ +DialogAF::~DialogAF +================ +*/ +DialogAF::~DialogAF() { +} + +/* +================ +DialogAF::DoDataExchange +================ +*/ +void DialogAF::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAF) + DDX_Control(pDX, IDC_COMBO_AF, AFList); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAF::LoadFile +================ +*/ +void DialogAF::LoadFile( idDeclAF *af ) { + file = af; + propertiesDlg->LoadFile( af ); + bodyDlg->LoadFile( af ); + constraintDlg->LoadFile( af ); + + if ( file ) { + // select file in AFList + int i = AFList.FindString( -1, file->GetName() ); + if ( i != AFList.GetCurSel() ) { + AFList.SetCurSel( i ); + } + GetDlgItem( IDC_BUTTON_AF_SAVE )->EnableWindow( file->modified ); + GetDlgItem( IDC_BUTTON_AF_DELETE )->EnableWindow( true ); + } + else { + AFList.SetCurSel( -1 ); + GetDlgItem( IDC_BUTTON_AF_SAVE )->EnableWindow( false ); + GetDlgItem( IDC_BUTTON_AF_DELETE )->EnableWindow( false ); + } +} + +/* +================ +DialogAF::LoadFile +================ +*/ +void DialogAF::SaveFile( void ) { + if ( !file ) { + return; + } + propertiesDlg->SaveFile(); + bodyDlg->SaveFile(); + constraintDlg->SaveFile(); + gameEdit->AF_UpdateEntities( file->GetName() ); +} + +/* +================ +DialogAF::SetFileModified +================ +*/ +void DialogAF::SetFileModified( void ) { + if ( file ) { + file->modified = true; + GetDlgItem( IDC_BUTTON_AF_SAVE )->EnableWindow( true ); + } +} + +/* +================ +DialogAF::ReloadFile +================ +*/ +void DialogAF::ReloadFile( void ) { + LoadFile( file ); +} + +/* +================ +DialogAF::InitAFList +================ +*/ +void DialogAF::InitAFList( void ) { + int i, c; + + AFList.ResetContent(); + c = declManager->GetNumDecls( DECL_AF ); + for ( i = 0; i < c; i++ ) { + AFList.AddString( static_cast( declManager->DeclByIndex( DECL_AF, i, false ) )->GetName() ); + } +} + +/* +================ +DialogAF::AddTabItem +================ +*/ +void DialogAF::AddTabItem( int id, const char *name ) { + TCITEM item; + item.mask = TCIF_PARAM; + item.lParam = id; + int tab = wndTabs->InsertItem( wndTabs->GetItemCount(), name ); + wndTabs->SetItem( tab, &item ); +} + +/* +================ +DialogAF::SetTab +================ +*/ +void DialogAF::SetTab( int id ) { + int c = wndTabs->GetItemCount(); + for ( int i = 0; i < c; i++ ) { + TCITEM item; + item.mask = TCIF_PARAM; + wndTabs->GetItem( i, &item ); + if ( item.lParam == id ) { + wndTabs->SetCurSel(i); + return; + } + } + wndTabs->SetCurSel(0); +} + +/* +================ +DialogAF::SetTabChildPos + + position the child dialog box +================ +*/ +void DialogAF::SetTabChildPos( void ) { + if ( wndTabDisplay ) { + wndTabDisplay->ShowWindow( SW_SHOW ); + wndTabDisplay->SetWindowPos( wndTabs, 12, 60, 0, 0, SWP_NOSIZE ); + } +} + +/* +================ +DialogAF::OnInitDialog +================ +*/ +BOOL DialogAF::OnInitDialog() { + CDialog::OnInitDialog(); + + com_editors |= EDITOR_AF; + + // initialize list with articulated figure files + InitAFList(); + + // initialize tabs + wndTabs = (CTabCtrl *) GetDlgItem( IDC_DIALOG_AF_TAB_MODE ); + AddTabItem( AFTAB_VIEW, "View" ); + AddTabItem( AFTAB_PROPERTIES, "Properties" ); + AddTabItem( AFTAB_BODIES, "Bodies" ); + AddTabItem( AFTAB_CONSTRAINTS, "Constraints" ); + SetTab( AFTAB_VIEW ); + + // create child dialog windows + viewDlg = new DialogAFView( this ); + propertiesDlg = new DialogAFProperties( this ); + bodyDlg = new DialogAFBody( this ); + constraintDlg = new DialogAFConstraint( this ); + + // the body dialog may force the constraint dialog to reload the file + bodyDlg->constraintDlg = constraintDlg; + + // the properties dialog may force the body or constraint dialog to reload the file + propertiesDlg->bodyDlg = bodyDlg; + propertiesDlg->constraintDlg = constraintDlg; + + // set active child dialog + wndTabDisplay = viewDlg; + SetTabChildPos(); + + EnableToolTips( TRUE ); + + GetDlgItem( IDC_BUTTON_AF_DELETE )->EnableWindow( false ); + GetDlgItem( IDC_BUTTON_AF_SAVE )->EnableWindow( false ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +BEGIN_MESSAGE_MAP(DialogAF, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY(TCN_SELCHANGE, IDC_DIALOG_AF_TAB_MODE, OnTcnSelchangeTabMode) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_MOVE() + ON_WM_SETFOCUS() + ON_CBN_SELCHANGE(IDC_COMBO_AF, OnCbnSelchangeComboAf) + ON_BN_CLICKED(IDC_BUTTON_AF_NEW, OnBnClickedButtonAfNew) + ON_BN_CLICKED(IDC_BUTTON_AF_DELETE, OnBnClickedButtonAfDelete) + ON_BN_CLICKED(IDC_BUTTON_AF_SAVE, OnBnClickedButtonAfSave) + ON_BN_CLICKED(IDC_BUTTON_AF_SPAWN, OnBnClickedButtonAfSpawn) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) + ON_BN_CLICKED(IDC_BUTTON_AF_KILL, OnBnClickedButtonAfKill) + ON_BN_CLICKED(IDC_BUTTON_AF_TPOSE, OnBnClickedButtonAfTpose) +END_MESSAGE_MAP() + + +/* +================ +AFEditorInit +================ +*/ +void AFEditorInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the articulated figure editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_AFDialog == NULL ) { + InitAfx(); + g_AFDialog = new DialogAF(); + } + + if ( g_AFDialog->GetSafeHwnd() == NULL) { + g_AFDialog->Create( IDD_DIALOG_AF ); +/* + // FIXME: restore position + CRect rct; + g_AFDialog->SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE ); +*/ + } + + idKeyInput::ClearStates(); + + g_AFDialog->ShowWindow( SW_SHOW ); + g_AFDialog->SetFocus(); + + if ( spawnArgs ) { + // select AF based on spawn args + const char *name = spawnArgs->GetString( "articulatedFigure" ); + if ( name[0] == '\0' ) { + name = spawnArgs->GetString( "ragdoll" ); + } + idDeclAF *decl = static_cast( const_cast( declManager->FindType( DECL_AF, name ) ) ); + if ( decl ) { + g_AFDialog->LoadFile( decl ); + } + } +} + +/* +================ +AFEditorRun +================ +*/ +void AFEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +/* +================ +AFEditorShutdown +================ +*/ +void AFEditorShutdown( void ) { + delete g_AFDialog; + g_AFDialog = NULL; +} + + +// DialogAF message handlers + +/* +================ +DialogAF::OnActivate +================ +*/ +void DialogAF::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogAF::OnToolTipNotify +================ +*/ +BOOL DialogAF::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogAF::OnSetFocus +================ +*/ +void DialogAF::OnSetFocus( CWnd *pOldWnd ) { + //SetActiveWindow(); + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogAF::OnDestroy +================ +*/ +void DialogAF::OnDestroy() { + + com_editors &= ~EDITOR_AF; + + return CDialog::OnDestroy(); +} + +/* +================ +DialogAF::OnMove +================ +*/ +void DialogAF::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +/* +================ +DialogAF::OnTcnSelchangeTabMode + + tab control notification handler +================ +*/ +void DialogAF::OnTcnSelchangeTabMode( NMHDR *pNMHDR, LRESULT *pResult ) { + *pResult = 0; + + // hide the current tab child dialog box, if any. + if ( wndTabDisplay != NULL ) { + wndTabDisplay->ShowWindow( SW_HIDE ); + } + + TCITEM item; + item.mask = TCIF_PARAM; + wndTabs->GetItem( wndTabs->GetCurSel(), &item ); + + // show the new tab child dialog box. + switch ( item.lParam ) { + case AFTAB_VIEW: + wndTabDisplay = viewDlg; + break; + case AFTAB_PROPERTIES: + wndTabDisplay = propertiesDlg; + break; + case AFTAB_BODIES: + wndTabDisplay = bodyDlg; + break; + case AFTAB_CONSTRAINTS: + wndTabDisplay = constraintDlg; + break; + } + + SetTabChildPos(); +} + +/* +================ +DialogAF::OnCbnSelchangeComboAf +================ +*/ +void DialogAF::OnCbnSelchangeComboAf() { + int index = AFList.GetCurSel(); + if ( index < 0 || index >= declManager->GetNumDecls( DECL_AF ) ) { + InitAFList(); + return; + } + if ( index != CB_ERR ) { + CString str; + AFList.GetLBText( index, str ); + LoadFile( static_cast( const_cast( declManager->FindType( DECL_AF, str ) ) ) ); + } +} + +/* +================ +DialogAF::OnBnClickedButtonAfNew +================ +*/ +void DialogAF::OnBnClickedButtonAfNew() { + DialogAFName nameDlg; + CString name; + idStr fileName; + + nameDlg.SetComboBox( &AFList ); + if ( nameDlg.DoModal() != IDOK ) { + return; + } + nameDlg.GetName( name ); + + CFileDialog dlgSave( FALSE, "map", NULL, OFN_OVERWRITEPROMPT, "AF Files (*.af)|*.af|All Files (*.*)|*.*||", AfxGetMainWnd() ); + if ( dlgSave.DoModal() != IDOK ) { + return; + } + fileName = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile ); + + // create a new .af file + AFList.AddString( name ); + AFList.SetCurSel( AFList.FindString( -1, name ) ); + idDeclAF *decl = static_cast( declManager->CreateNewDecl( DECL_AF, name, fileName ) ); + LoadFile( decl ); + AFDialogSetFileModified(); +} + +/* +================ +DialogAF::OnBnClickedButtonAfDelete +================ +*/ +void DialogAF::OnBnClickedButtonAfDelete() { + int i; + + i = AFList.GetCurSel(); + if ( i != CB_ERR ) { + if ( MessageBox( "Are you sure you want to delete the articulated figure file ?", "Delete Articulated Figure", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + // FIXME: delete the currently selected .af file + } + } +} + +/* +================ +DialogAF::OnBnClickedButtonAfSpawn +================ +*/ +void DialogAF::OnBnClickedButtonAfSpawn() { + int index = AFList.GetCurSel(); + if ( index != CB_ERR ) { + CString str; + AFList.GetLBText( index, str ); + gameEdit->AF_SpawnEntity( str ); + } +} + +/* +================ +DialogAF::OnBnClickedButtonAfTpose +================ +*/ +void DialogAF::OnBnClickedButtonAfTpose() { + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAF::OnBnClickedButtonAfKill +================ +*/ +void DialogAF::OnBnClickedButtonAfKill() { + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "deleteSelected\n" ); +} + +/* +================ +DialogAF::OnBnClickedButtonAfSave +================ +*/ +void DialogAF::OnBnClickedButtonAfSave() { + // save the selected .af file + if ( file ) { + if ( file->Save() ) { + GetDlgItem( IDC_BUTTON_AF_SAVE )->EnableWindow( false ); + } + else { + MessageBox( "Saving the file failed. Make sure the file is not read-only.", "Delete Articulated Figure", MB_OK ); + } + } +} + +/* +================ +DialogAF::OnBnClickedCancel +================ +*/ +void DialogAF::OnBnClickedCancel() { + int i, c; + + // check if there are modified .af files and come up with a warning if so + c = declManager->GetNumDecls( DECL_AF ); + for ( i = 0; i < c; i++ ) { + if ( static_cast( declManager->DeclByIndex( DECL_AF, i ) )->modified ) { + if ( MessageBox( "Some articulated figures have been modified.\nCancel all changes ?", "Cancel", MB_YESNO | MB_ICONQUESTION ) != IDYES ) { + return; + } + break; + } + } + // reload all modified .af files + LoadFile( NULL ); + gameEdit->AF_UndoChanges(); + InitAFList(); + OnCancel(); +} + + +// General convenience routines + +/* +================ +AFDialogSetFileModified +================ +*/ +void AFDialogSetFileModified( void ) { + if ( g_AFDialog ) { + g_AFDialog->SetFileModified(); + } +} + +/* +================ +AFDialogReloadFile +================ +*/ +void AFDialogReloadFile( void ) { + if ( g_AFDialog ) { + g_AFDialog->ReloadFile(); + } +} diff --git a/tools/af/DialogAF.h b/tools/af/DialogAF.h new file mode 100644 index 000000000..4faa4a357 --- /dev/null +++ b/tools/af/DialogAF.h @@ -0,0 +1,89 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +class idDeclAF; + +class DialogAFView; +class DialogAFProperties; +class DialogAFBody; +class DialogAFConstraint; + + +// DialogAF dialog + +class DialogAF : public CDialog { + + DECLARE_DYNAMIC(DialogAF) + +public: + DialogAF( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogAF(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void ReloadFile( void ); + void SetFileModified( void ); + + enum { IDD = IDD_DIALOG_AF }; + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnMove( int x, int y ); + afx_msg void OnTcnSelchangeTabMode( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnCbnSelchangeComboAf(); + afx_msg void OnBnClickedButtonAfNew(); + afx_msg void OnBnClickedButtonAfDelete(); + afx_msg void OnBnClickedButtonAfSpawn(); + afx_msg void OnBnClickedButtonAfTpose(); + afx_msg void OnBnClickedButtonAfKill(); + afx_msg void OnBnClickedButtonAfSave(); + afx_msg void OnBnClickedCancel(); + + DECLARE_MESSAGE_MAP() + +private: + CTabCtrl * wndTabs; + CWnd * wndTabDisplay; + DialogAFView * viewDlg; + DialogAFProperties *propertiesDlg; + DialogAFBody * bodyDlg; + DialogAFConstraint *constraintDlg; + + idDeclAF * file; // file being edited + + //{{AFX_DATA(DialogAF) + CComboBox AFList; // list with .af files + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitAFList( void ); + void AddTabItem( int id, const char *name ); + void SetTab( int id ); + void SetTabChildPos( void ); +}; + +void AFDialogSetFileModified( void ); +void AFDialogReloadFile( void ); diff --git a/tools/af/DialogAFBody.cpp b/tools/af/DialogAFBody.cpp new file mode 100644 index 000000000..de0d7940c --- /dev/null +++ b/tools/af/DialogAFBody.cpp @@ -0,0 +1,1346 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFName.h" +#include "DialogAFConstraint.h" +#include "DialogAFBody.h" + +typedef struct { + traceModel_t type; + const char *name; +} cm_type_t; + +cm_type_t modelTypes[] = { + { TRM_INVALID, "invalid" }, + { TRM_BOX, "box" }, + { TRM_OCTAHEDRON, "octahedron" }, + { TRM_DODECAHEDRON, "dodecahedron" }, + { TRM_CYLINDER, "cylinder" }, + { TRM_CONE, "cone" }, + { TRM_BONE, "bone" }, + { TRM_CUSTOM, "custom" }, + { TRM_INVALID, NULL } +}; + +const char *ModelTypeToString( int type ) { + for ( int i = 0; modelTypes[i].name; i++ ) { + if ( modelTypes[i].type == type ) { + return modelTypes[i].name; + } + } + return ""; +} + +traceModel_t StringToModelType( const char *str ) { + for ( int i = 0; modelTypes[i].name; i++ ) { + if ( idStr::Icmp( modelTypes[i].name, str ) == 0 ) { + return modelTypes[i].type; + } + } + return TRM_INVALID; +} + +// DialogAFBody dialog + +toolTip_t DialogAFBody::toolTips[] = { + { IDC_COMBO_BODIES, "select body for editing" }, + { IDC_BUTTON_NEWBODY, "create a new body" }, + { IDC_BUTTON_RENAMEBODY, "rename the selected body" }, + { IDC_BUTTON_DELETEBODY, "delete the selected body" }, + { IDC_COMBO_CM_TYPE, "collision model type" }, + { IDC_EDIT_CM_NAME, "custom collision model" }, + { IDC_BUTTON_CM_BROWSE, "browse custom collision model" }, + { IDC_COMBO_BONE_JOINT1, "first joint of bone collision model" }, + { IDC_COMBO_BONE_JOINT2, "second joint of bone collision model" }, + { IDC_EDIT_CM_HEIGHT, "hieght of the collision model" }, + { IDC_EDIT_CM_WIDTH, "width of the collision model" }, + { IDC_EDIT_CM_LENGTH, "length of the collision model" }, + { IDC_EDIT_CM_NUMSIDES, "number of sides of the collision model" }, + { IDC_EDIT_CM_DENSITY, "collision model density" }, + { IDC_EDIT_CM_INERTIASCALE, "inertia tensor scale" }, + { IDC_RADIO_ORIGIN_COORDINATES, "use absolute coordinates for the body origin" }, + { IDC_RADIO_ORIGIN_BONECENTER, "use the center of a bone for the body origin" }, + { IDC_RADIO_ORIGIN_JOINT, "use the position of a joint for the body origin" }, + { IDC_EDIT_AF_VECTOR_X, "x-coordinate" }, + { IDC_EDIT_AF_VECTOR_Y, "y-coordinate" }, + { IDC_EDIT_AF_VECTOR_Z, "z-coordinate" }, + { IDC_COMBO_ORIGIN_BONECENTER_JOINT1, "bone start joint" }, + { IDC_COMBO_ORIGIN_BONECENTER_JOINT2, "bone end joint" }, + { IDC_COMBO_ORIGIN_JOINT, "joint name" }, + { IDC_EDIT_ANGLES_PITCH, "pitch angle of body" }, + { IDC_EDIT_ANGLES_YAW, "yaw angle of body" }, + { IDC_EDIT_ANGLES_ROLL, "roll angle of body" }, + { IDC_EDIT_LINEARFRICTION, "translational friction" }, + { IDC_EDIT_ANGULARFRICTION, "rotational friction" }, + { IDC_EDIT_CONTACTFRICTION, "friction with contact surfaces" }, + { IDC_CHECK_SELFCOLLISION, "collide with other bodies of this articulated figure" }, + { IDC_EDIT_CONTENTS, "content of body" }, + { IDC_EDIT_CLIPMASK, "collide with these content types" }, + { IDC_EDIT_FRICTIONDIRECTION, "single friction direction relative to body" }, + { IDC_EDIT_CONTACTMOTORDIRECTION, "contact motor direction" }, + { IDC_COMBO_MODIFIEDJOINT, "the joint modified by the relative rotation of the body" }, + { IDC_RADIO_MODIFY_ORIENTATION, "modify the joint orientation" }, + { IDC_RADIO_MODIFY_POSITION, "modify the joint position" }, + { IDC_RADIO_MODIFY_BOTH, "modify the joint orientation and position" }, + { IDC_EDIT_CONTAINEDJOINTS, "all the joints contained by this body" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFBody, CDialog) + +/* +================ +DialogAFBody::DialogAFBody +================ +*/ +DialogAFBody::DialogAFBody( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogAFBody::IDD, pParent) + , constraintDlg(NULL) + , numJoints(0) + , cm_length(0) + , cm_height(0) + , cm_width(0) + , cm_density(0) + , cm_numSides(3) + , cm_origin_x(0) + , cm_origin_y(0) + , cm_origin_z(0) + , cm_angles_pitch(0) + , cm_angles_yaw(0) + , cm_angles_roll(0) + , m_selfCollision(false) + , m_linearFriction(0) + , m_angularFriction(0) + , m_contactFriction(0) + , file(NULL) + , body(NULL) +{ + Create( IDD_DIALOG_AF_BODY, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFBody::~DialogAFBody +================ +*/ +DialogAFBody::~DialogAFBody() { +} + +/* +================ +DialogAFBody::DoDataExchange +================ +*/ +void DialogAFBody::DoDataExchange( CDataExchange* pDX ) { + CDialog::DoDataExchange( pDX ); + //{{AFX_DATA_MAP(DialogAFBody) + DDX_Control(pDX, IDC_COMBO_BODIES, bodyList); + DDX_Control(pDX, IDC_COMBO_CM_TYPE, cm_comboType); + DDX_Text(pDX, IDC_EDIT_CM_LENGTH, cm_length); + DDX_Text(pDX, IDC_EDIT_CM_HEIGHT, cm_height); + DDX_Text(pDX, IDC_EDIT_CM_WIDTH, cm_width); + DDX_Text(pDX, IDC_EDIT_CM_NUMSIDES, cm_numSides); + DDX_Control(pDX, IDC_COMBO_BONE_JOINT1, cm_comboBoneJoint1 ); + DDX_Control(pDX, IDC_COMBO_BONE_JOINT2, cm_comboBoneJoint2 ); + DDX_Text(pDX, IDC_EDIT_CM_DENSITY, cm_density); + DDX_Control(pDX, IDC_EDIT_CM_INERTIASCALE, cm_inertiaScale); + DDX_Text(pDX, IDC_EDIT_AF_VECTOR_X, cm_origin_x); + DDX_Text(pDX, IDC_EDIT_AF_VECTOR_Y, cm_origin_y); + DDX_Text(pDX, IDC_EDIT_AF_VECTOR_Z, cm_origin_z); + DDX_Control(pDX, IDC_COMBO_ORIGIN_BONECENTER_JOINT1, cm_originBoneCenterJoint1); + DDX_Control(pDX, IDC_COMBO_ORIGIN_BONECENTER_JOINT2, cm_originBoneCenterJoint2); + DDX_Control(pDX, IDC_COMBO_ORIGIN_JOINT, cm_originJoint); + DDX_Text(pDX, IDC_EDIT_ANGLES_PITCH, cm_angles_pitch); + DDX_Text(pDX, IDC_EDIT_ANGLES_YAW, cm_angles_yaw); + DDX_Text(pDX, IDC_EDIT_ANGLES_ROLL, cm_angles_roll); + DDX_Check(pDX, IDC_CHECK_SELFCOLLISION, m_selfCollision); + DDX_Control(pDX, IDC_EDIT_CONTENTS, m_editContents); + DDX_Control(pDX, IDC_EDIT_CLIPMASK, m_editClipMask); + DDX_Text(pDX, IDC_EDIT_LINEARFRICTION, m_linearFriction); + DDX_Text(pDX, IDC_EDIT_ANGULARFRICTION, m_angularFriction); + DDX_Text(pDX, IDC_EDIT_CONTACTFRICTION, m_contactFriction); + DDX_Control(pDX, IDC_EDIT_FRICTIONDIRECTION, m_frictionDirection); + DDX_Control(pDX, IDC_EDIT_CONTACTMOTORDIRECTION, m_contactMotorDirection); + DDX_Control(pDX, IDC_COMBO_MODIFIEDJOINT, m_comboModifiedJoint); + DDX_Control(pDX, IDC_EDIT_CONTAINEDJOINTS, m_editContainedJoints); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFBody::InitBodyList +================ +*/ +void DialogAFBody::InitBodyList( void ) { + CString str; + + bodyList.ResetContent(); + if ( !file ) { + return; + } + for ( int i = 0; i < file->bodies.Num(); i++ ) { + bodyList.AddString( file->bodies[i]->name.c_str() ); + } + if ( bodyList.GetCount() != 0 ) { + bodyList.SetCurSel( 0 ); + bodyList.GetLBText( 0, str ); + LoadBody( str ); + } +} + +/* +================ +DialogAFBody::InitJointLists + + initialize the joint lists for bone collision models +================ +*/ +void DialogAFBody::InitJointLists( void ) { + idStrList joints; + + cm_comboBoneJoint1.ResetContent(); + cm_comboBoneJoint2.ResetContent(); + cm_originBoneCenterJoint1.ResetContent(); + cm_originBoneCenterJoint2.ResetContent(); + cm_originJoint.ResetContent(); + numJoints = 0; + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + cm_comboBoneJoint1.AddString( jointName ); + cm_comboBoneJoint2.AddString( jointName ); + cm_originBoneCenterJoint1.AddString( jointName ); + cm_originBoneCenterJoint2.AddString( jointName ); + cm_originJoint.AddString( jointName ); + } +} + +/* +================ +DialogAFBody::InitCollisionModelType +================ +*/ +void DialogAFBody::InitCollisionModelType( void ) { + int showBone, showOther; + bool enableOther; + CString str; + + UpdateData( TRUE ); + cm_comboType.GetLBText( cm_comboType.GetCurSel(), str ); + traceModel_t type = StringToModelType( str ); + if ( type == TRM_BONE ) { + showBone = SW_SHOW; + showOther = SW_HIDE; + enableOther = false; + GetDlgItem( IDC_STATIC_CM_LENGTH )->SetWindowText( "Joint 1" ); + GetDlgItem( IDC_STATIC_CM_HEIGHT )->SetWindowText( "Joint 2" ); + CheckRadioButton( IDC_RADIO_ORIGIN_COORDINATES, + IDC_RADIO_ORIGIN_JOINT, + IDC_RADIO_ORIGIN_BONECENTER ); + } + else { + showBone = SW_HIDE; + showOther = SW_SHOW; + enableOther = true; + GetDlgItem( IDC_STATIC_CM_LENGTH )->SetWindowText( "Length" ); + GetDlgItem( IDC_STATIC_CM_HEIGHT )->SetWindowText( "Height" ); + } + GetDlgItem( IDC_COMBO_BONE_JOINT1 )->ShowWindow( showBone ); + GetDlgItem( IDC_COMBO_BONE_JOINT2 )->ShowWindow( showBone ); + GetDlgItem( IDC_EDIT_CM_LENGTH )->ShowWindow( showOther ); + GetDlgItem( IDC_SPIN_CM_LENGTH )->ShowWindow( showOther ); + GetDlgItem( IDC_EDIT_CM_HEIGHT )->ShowWindow( showOther ); + GetDlgItem( IDC_SPIN_CM_HEIGHT )->ShowWindow( showOther ); + + // enable/disable origin controls + GetDlgItem( IDC_EDIT_AF_VECTOR_X )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_AF_VECTOR_X )->EnableWindow( enableOther ); + GetDlgItem( IDC_EDIT_AF_VECTOR_Y )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_AF_VECTOR_Y )->EnableWindow( enableOther ); + GetDlgItem( IDC_EDIT_AF_VECTOR_Z )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_AF_VECTOR_Z )->EnableWindow( enableOther ); + + // enable/disable joint controls + GetDlgItem( IDC_COMBO_ORIGIN_BONECENTER_JOINT1 )->EnableWindow( enableOther ); + GetDlgItem( IDC_COMBO_ORIGIN_BONECENTER_JOINT2 )->EnableWindow( enableOther ); + GetDlgItem( IDC_COMBO_ORIGIN_JOINT )->EnableWindow( enableOther ); + + // enable/disable angles controls + GetDlgItem( IDC_STATIC_ANGLES_PITCH )->EnableWindow( enableOther ); + GetDlgItem( IDC_EDIT_ANGLES_PITCH )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_ANGLES_PITCH )->EnableWindow( enableOther ); + GetDlgItem( IDC_STATIC_ANGLES_YAW )->EnableWindow( enableOther ); + GetDlgItem( IDC_EDIT_ANGLES_YAW )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_ANGLES_YAW )->EnableWindow( enableOther ); + GetDlgItem( IDC_STATIC_ANGLES_ROLL )->EnableWindow( enableOther ); + GetDlgItem( IDC_EDIT_ANGLES_ROLL )->EnableWindow( enableOther ); + GetDlgItem( IDC_SPIN_ANGLES_ROLL )->EnableWindow( enableOther ); + + GetDlgItem( IDC_RADIO_ORIGIN_COORDINATES )->EnableWindow( enableOther ); + GetDlgItem( IDC_RADIO_ORIGIN_BONECENTER )->EnableWindow( enableOther ); + GetDlgItem( IDC_RADIO_ORIGIN_JOINT )->EnableWindow( enableOther ); + + if ( type == TRM_CONE || type == TRM_CYLINDER ) { + GetDlgItem( IDC_EDIT_CM_NUMSIDES )->EnableWindow( true ); + GetDlgItem( IDC_SPIN_CM_NUMSIDES )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_EDIT_CM_NUMSIDES )->EnableWindow( false ); + GetDlgItem( IDC_SPIN_CM_NUMSIDES )->EnableWindow( false ); + } +} + +/* +================ +DialogAFBody::InitModifiedJointList +================ +*/ +void DialogAFBody::InitModifiedJointList( void ) { + int i, j, numJoints; + CString str; + + m_comboModifiedJoint.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + numJoints = model->NumJoints(); + for ( i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + for ( j = 0; j < file->bodies.Num(); j++ ) { + if ( file->bodies[j] == body ) { + continue; + } + if ( file->bodies[j]->jointName.Icmp( jointName ) == 0 ) { + break; + } + } + if ( j < file->bodies.Num() ) { + continue; + } + m_comboModifiedJoint.AddString( jointName ); + } + + if ( body ) { + if ( body->jointName.Length() == 0 ) { + m_comboModifiedJoint.GetLBText( 0, str ); + body->jointName = str; + } + SetSafeComboBoxSelection( &m_comboModifiedJoint, body->jointName, -1 ); + // cannot change the body which modifies the origin joint + if ( body->jointName.Icmp( "origin" ) == 0 ) { + // check if there is another body which modifies the "origin" joint + for ( i = 0; i < file->bodies.Num(); i++ ) { + if ( file->bodies[i] == body ) { + continue; + } + if ( file->bodies[i]->jointName.Icmp( "origin" ) == 0 ) { + break; + } + } + // if there is another body which modifies the "origin" joint + if ( i < file->bodies.Num() ) { + GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( false ); + } + } + else { + GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( true ); + } + } +} + +/* +================ +DialogAFBody::InitNewRenameDeleteButtons +================ +*/ +void DialogAFBody::InitNewRenameDeleteButtons( void ) { + if ( file && numJoints > file->bodies.Num() ) { + GetDlgItem( IDC_BUTTON_NEWBODY )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_BUTTON_NEWBODY )->EnableWindow( false ); + } + + if ( file && bodyList.GetCount() >= 1 ) { + GetDlgItem( IDC_BUTTON_RENAMEBODY )->EnableWindow( true ); + GetDlgItem( IDC_BUTTON_DELETEBODY )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_BUTTON_RENAMEBODY )->EnableWindow( false ); + GetDlgItem( IDC_BUTTON_DELETEBODY )->EnableWindow( false ); + } +} + +/* +================ +DialogAFBody::LoadFile +================ +*/ +void DialogAFBody::LoadFile( idDeclAF *af ) { + file = af; + body = NULL; + InitJointLists(); + InitBodyList(); + InitNewRenameDeleteButtons(); +} + +/* +================ +DialogAFBody::SaveFile +================ +*/ +void DialogAFBody::SaveFile( void ) { + SaveBody(); +} + +/* +================ +DialogAFBody::LoadBody +================ +*/ +void DialogAFBody::LoadBody( const char *name ) { + int i, s1, s2; + idStr str; + + if ( !file ) { + return; + } + for ( i = 0; i < file->bodies.Num(); i++ ) { + if ( file->bodies[i]->name.Icmp( name ) == 0 ) { + break; + } + } + if ( i >= file->bodies.Num() ) { + return; + } + body = file->bodies[i]; + + // load collision model from the current idDeclAF_Body + SetSafeComboBoxSelection( &cm_comboType, ModelTypeToString( body->modelType ), -1 ); + if ( body->modelType == TRM_BONE ) { + s1 = SetSafeComboBoxSelection( &cm_comboBoneJoint1, body->v1.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &cm_comboBoneJoint2, body->v2.joint1.c_str(), s1 ); + cm_width = body->width; + cm_length = cm_height = 20.0f; + s1 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint1, body->v1.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint2, body->v2.joint1.c_str(), s1 ); + } + else { + cm_length = body->v2.ToVec3().x - body->v1.ToVec3().x; + cm_height = body->v2.ToVec3().z - body->v1.ToVec3().z; + cm_width = body->v2.ToVec3().y - body->v1.ToVec3().y; + cm_origin_x = body->origin.ToVec3().x; + cm_origin_y = body->origin.ToVec3().y; + cm_origin_z = body->origin.ToVec3().z; + s1 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint1, body->origin.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint2, body->origin.joint2.c_str(), s1 ); + s1 = SetSafeComboBoxSelection( &cm_originJoint, body->origin.joint1.c_str(), -1 ); + cm_angles_pitch = body->angles.pitch; + cm_angles_yaw = body->angles.yaw; + cm_angles_roll = body->angles.roll; + if ( body->origin.type == idAFVector::VEC_BONECENTER ) { + i = IDC_RADIO_ORIGIN_BONECENTER; + } + else if ( body->origin.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ORIGIN_JOINT; + } + else { + i = IDC_RADIO_ORIGIN_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ORIGIN_COORDINATES, IDC_RADIO_ORIGIN_JOINT, i ); + } + cm_numSides = body->numSides; + cm_density = body->density; + if ( body->inertiaScale == mat3_identity ) { + cm_inertiaScale.SetWindowText( "none" ); + } + else { + cm_inertiaScale.SetWindowText( body->inertiaScale.ToString( 1 ) ); + } + + // load collision detection settings from the current idDeclAF_Body + m_selfCollision = body->selfCollision; + idDeclAF::ContentsToString( body->contents, str ); + m_editContents.SetWindowText( str ); + idDeclAF::ContentsToString( body->clipMask, str ); + m_editClipMask.SetWindowText( str ); + + // load friction settings from the current idDeclAF_Body + m_linearFriction = body->linearFriction; + m_angularFriction = body->angularFriction; + m_contactFriction = body->contactFriction; + + // friction direction and contact motor direction + if ( body->frictionDirection.ToVec3() != vec3_origin ) { + idFile_Memory file( "frictionDirection" ); + file.WriteFloatString( "%f %f %f", body->frictionDirection.ToVec3().x, body->frictionDirection.ToVec3().y, body->frictionDirection.ToVec3().z ); + m_frictionDirection.SetWindowText( file.GetDataPtr() ); + } else { + m_frictionDirection.SetWindowText( "" ); + } + if ( body->contactMotorDirection.ToVec3() != vec3_origin ) { + idFile_Memory file( "contactMotorDirection" ); + file.WriteFloatString( "%f %f %f", body->contactMotorDirection.ToVec3().x, body->contactMotorDirection.ToVec3().y, body->contactMotorDirection.ToVec3().z ); + m_contactMotorDirection.SetWindowText( file.GetDataPtr() ); + } else { + m_contactMotorDirection.SetWindowText( "" ); + } + + // load joint settings from the current idDeclAF_Body + InitModifiedJointList(); + if ( body->jointMod == DECLAF_JOINTMOD_AXIS ) { + i = IDC_RADIO_MODIFY_ORIENTATION; + } else if ( body->jointMod == DECLAF_JOINTMOD_ORIGIN ) { + i = IDC_RADIO_MODIFY_POSITION; + } else if ( body->jointMod == DECLAF_JOINTMOD_BOTH ) { + i = IDC_RADIO_MODIFY_BOTH; + } else { + i = IDC_RADIO_MODIFY_ORIENTATION; + } + CheckRadioButton( IDC_RADIO_MODIFY_ORIENTATION, IDC_RADIO_MODIFY_BOTH, i ); + m_editContainedJoints.SetWindowText( body->containedJoints.c_str() ); + + // update displayed values + UpdateData( FALSE ); + + InitCollisionModelType(); // CComboBox::SetCurSel doesn't call this + + if ( GetStyle() & WS_VISIBLE ) { + // highlight the current body ingame + cvarSystem->SetCVarString( "af_highlightBody", name ); + } +} + +/* +================ +DialogAFBody::SaveBody +================ +*/ +void DialogAFBody::SaveBody( void ) { + int s1, s2; + CString str; + + if ( !file || !body ) { + return; + } + UpdateData( TRUE ); + + // save the collision model to the current idDeclAF_Body + cm_comboType.GetLBText( cm_comboType.GetCurSel(), str ); + body->modelType = StringToModelType( str ); + if ( body->modelType == TRM_BONE ) { + body->origin.type = idAFVector::VEC_BONECENTER; + s1 = GetSafeComboBoxSelection( &cm_comboBoneJoint1, str, -1 ); + body->v1.type = idAFVector::VEC_JOINT; + body->v1.joint1 = str; + body->origin.joint1 = str; + s2 = GetSafeComboBoxSelection( &cm_comboBoneJoint2, str, s1 ); + body->v2.type = idAFVector::VEC_JOINT; + body->v2.joint1 = str; + body->origin.joint2 = str; + body->width = cm_width; + body->angles.Zero(); + } else { + body->v1.type = idAFVector::VEC_COORDS; + body->v1.ToVec3().x = -0.5f * cm_length; + body->v1.ToVec3().y = -0.5f * cm_width; + body->v1.ToVec3().z = -0.5f * cm_height; + body->v2.type = idAFVector::VEC_COORDS; + body->v2.ToVec3().x = 0.5f * cm_length; + body->v2.ToVec3().y = 0.5f * cm_width; + body->v2.ToVec3().z = 0.5f * cm_height; + body->origin.ToVec3().x = cm_origin_x; + body->origin.ToVec3().y = cm_origin_y; + body->origin.ToVec3().z = cm_origin_z; + body->angles.pitch = cm_angles_pitch; + body->angles.yaw = cm_angles_yaw; + body->angles.roll = cm_angles_roll; + if ( body->origin.type == idAFVector::VEC_JOINT ) { + s1 = GetSafeComboBoxSelection( &cm_originJoint, str, -1 ); + body->origin.joint1 = str; + } + else { + s1 = GetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str, -1 ); + body->origin.joint1 = str; + } + s2 = GetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str, s1 ); + body->origin.joint2 = str; + } + body->numSides = cm_numSides; + body->density = cm_density; + cm_inertiaScale.GetWindowText( str ); + if ( idStr::Icmp( str, "none" ) == 0 ) { + body->inertiaScale.Identity(); + } else { + idLexer src( str, str.GetLength(), "inertiaScale" ); + src.SetFlags( LEXFL_NOERRORS | LEXFL_NOWARNINGS ); + for ( int i = 0; i < 3; i++ ) { + for ( int j = 0; j < 3; j++ ) { + body->inertiaScale[i][j] = src.ParseFloat(); + } + } + } + + // save the collision detection settings to the current idDeclAF_Body + body->selfCollision = ( m_selfCollision != FALSE ); + m_editContents.GetWindowText( str ); + body->contents = idDeclAF::ContentsFromString( str ); + m_editClipMask.GetWindowText( str ); + body->clipMask = idDeclAF::ContentsFromString( str ); + + // save friction settings to the current idDeclAF_Body + body->linearFriction = m_linearFriction; + body->angularFriction = m_angularFriction; + body->contactFriction = m_contactFriction; + + // friction direction and contact motor direction + m_frictionDirection.GetWindowText( str ); + if ( str.GetLength() != 0 ) { + body->frictionDirection.ToVec3().Zero(); + sscanf( str, "%f %f %f", &body->frictionDirection.ToVec3().x, &body->frictionDirection.ToVec3().y, &body->frictionDirection.ToVec3().z ); + } + m_contactMotorDirection.GetWindowText( str ); + if ( str.GetLength() != 0 ) { + body->contactMotorDirection.ToVec3().Zero(); + sscanf( str, "%f %f %f", &body->contactMotorDirection.ToVec3().x, &body->contactMotorDirection.ToVec3().y, &body->contactMotorDirection.ToVec3().z ); + } + + // save joint settings to the current idDeclAF_Body + GetSafeComboBoxSelection( &m_comboModifiedJoint, str, -1 ); + body->jointName = str; + m_editContainedJoints.GetWindowText( str ); + body->containedJoints = str; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFBody::UpdateFile +================ +*/ +void DialogAFBody::UpdateFile( void ) { + SaveBody(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFBody::OnInitDialog +================ +*/ +BOOL DialogAFBody::OnInitDialog() { + + CDialog::OnInitDialog(); + + // initialize the collision model types + cm_comboType.ResetContent(); + for ( int i = 0; modelTypes[i].name; i++ ) { + if ( modelTypes[i].type == TRM_INVALID || modelTypes[i].type == TRM_CUSTOM ) { + continue; + } + cm_comboType.AddString( modelTypes[i].name ); + } + + InitNewRenameDeleteButtons(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +/* +================ +DialogAFBody::OnToolHitTest +================ +*/ +int DialogAFBody::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + +BEGIN_MESSAGE_MAP(DialogAFBody, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_SHOWWINDOW() + ON_CBN_SELCHANGE(IDC_COMBO_BODIES, OnCbnSelchangeComboBodies) + ON_BN_CLICKED(IDC_BUTTON_NEWBODY, OnBnClickedButtonNewbody) + ON_BN_CLICKED(IDC_BUTTON_RENAMEBODY, OnBnClickedButtonRenamebody) + ON_BN_CLICKED(IDC_BUTTON_DELETEBODY, OnBnClickedButtonDeletebody) + ON_CBN_SELCHANGE(IDC_COMBO_CM_TYPE, OnCbnSelchangeComboCmType) + ON_EN_CHANGE(IDC_EDIT_CM_LENGTH, OnEnChangeEditCmLength) + ON_EN_CHANGE(IDC_EDIT_CM_HEIGHT, OnEnChangeEditCmHeight) + ON_EN_CHANGE(IDC_EDIT_CM_WIDTH, OnEnChangeEditCmWidth) + ON_EN_CHANGE(IDC_EDIT_CM_NUMSIDES, OnEnChangeEditCmNumsides) + ON_CBN_SELCHANGE(IDC_COMBO_BONE_JOINT1, OnCbnSelchangeComboBoneJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_BONE_JOINT2, OnCbnSelchangeComboBoneJoint2) + ON_EN_CHANGE(IDC_EDIT_CM_DENSITY, OnEnChangeEditCmDensity) + ON_EN_CHANGE(IDC_EDIT_CM_INERTIASCALE, OnEnChangeEditCmInertiascale) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_LENGTH, OnDeltaposSpinCmLength) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_HEIGHT, OnDeltaposSpinCmHeight) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_WIDTH, OnDeltaposSpinCmWidth) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_NUMSIDES, OnDeltaposSpinCmNumsides) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_DENSITY, OnDeltaposSpinCmDensity) + ON_BN_CLICKED(IDC_RADIO_ORIGIN_COORDINATES, OnBnClickedRadioOriginCoordinates) + ON_BN_CLICKED(IDC_RADIO_ORIGIN_BONECENTER, OnBnClickedRadioOriginBonecenter) + ON_BN_CLICKED(IDC_RADIO_ORIGIN_JOINT, OnBnClickedRadioOriginJoint) + ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_X, OnEnChangeEditAfVectorX) + ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_Y, OnEnChangeEditAfVectorY) + ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_Z, OnEnChangeEditAfVectorZ) + ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_BONECENTER_JOINT1, OnOnCbnSelchangeComboOriginBoneCenterJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_BONECENTER_JOINT2, OnOnCbnSelchangeComboOriginBoneCenterJoint2) + ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_JOINT, OnOnCbnSelchangeComboOriginJoint) + ON_EN_CHANGE(IDC_EDIT_ANGLES_PITCH, OnEnChangeEditAnglesPitch) + ON_EN_CHANGE(IDC_EDIT_ANGLES_YAW, OnEnChangeEditAnglesYaw) + ON_EN_CHANGE(IDC_EDIT_ANGLES_ROLL, OnEnChangeEditAnglesRoll) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_X, OnDeltaposSpinAfVectorX) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_Y, OnDeltaposSpinAfVectorY) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_Z, OnDeltaposSpinAfVectorZ) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_PITCH, OnDeltaposSpinAnglesPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_YAW, OnDeltaposSpinAnglesYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_ROLL, OnDeltaposSpinAnglesRoll) + ON_BN_CLICKED(IDC_CHECK_SELFCOLLISION, OnBnClickedCheckSelfcollision) + ON_EN_CHANGE(IDC_EDIT_CONTENTS, OnEnChangeEditContents) + ON_EN_CHANGE(IDC_EDIT_CLIPMASK, OnEnChangeEditClipmask) + ON_EN_CHANGE(IDC_EDIT_LINEARFRICTION, OnEnChangeEditLinearfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_LINEARFRICTION, OnDeltaposSpinLinearfriction) + ON_EN_CHANGE(IDC_EDIT_ANGULARFRICTION, OnEnChangeEditAngularfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGULARFRICTION, OnDeltaposSpinAngularfriction) + ON_EN_CHANGE(IDC_EDIT_CONTACTFRICTION, OnEnChangeEditContactfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CONTACTFRICTION, OnDeltaposSpinContactfriction) + ON_EN_CHANGE(IDC_EDIT_FRICTIONDIRECTION, OnEnChangeEditFrictionDirection) + ON_EN_CHANGE(IDC_EDIT_CONTACTMOTORDIRECTION, OnEnChangeEditContactMotorDirection) + ON_CBN_SELCHANGE(IDC_COMBO_MODIFIEDJOINT, OnCbnSelchangeComboModifiedjoint) + ON_BN_CLICKED(IDC_RADIO_MODIFY_ORIENTATION, OnBnClickedRadioModifyOrientation) + ON_BN_CLICKED(IDC_RADIO_MODIFY_POSITION, OnBnClickedRadioModifyPosition) + ON_BN_CLICKED(IDC_RADIO_MODIFY_BOTH, OnBnClickedRadioModifyBoth) + ON_EN_CHANGE(IDC_EDIT_CONTAINEDJOINTS, OnEnChangeEditContainedjoints) +END_MESSAGE_MAP() + + +// DialogAFBody message handlers + +BOOL DialogAFBody::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFBody::OnShowWindow( BOOL bShow, UINT nStatus ) { + if ( bShow && body ) { + cvarSystem->SetCVarString( "af_highlightBody", body->name.c_str() ); + } else { + cvarSystem->SetCVarString( "af_highlightBody", "" ); + } + CDialog::OnShowWindow( bShow, nStatus ); +} + +void DialogAFBody::OnCbnSelchangeComboBodies() { + CString str; + + GetSafeComboBoxSelection( &bodyList, str, -1 ); + LoadBody( str ); +} + +void DialogAFBody::OnBnClickedButtonNewbody() { + DialogAFName nameDlg; + CString str; + INT_PTR res; + + // the names 'origin' and 'world' are reserved for constraints bound to the world + bodyList.AddString( "origin" ); + bodyList.AddString( "world" ); + + nameDlg.SetComboBox( &bodyList ); + res = nameDlg.DoModal(); + + bodyList.DeleteString( bodyList.FindString( -1, "origin" ) ); + bodyList.DeleteString( bodyList.FindString( -1, "world" ) ); + + if ( res == IDOK ) { + nameDlg.GetName( str ); + // create new body + file->NewBody( str ); + bodyList.SetCurSel( bodyList.AddString( str ) ); + LoadBody( str ); + constraintDlg->LoadFile( file ); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + InitNewRenameDeleteButtons(); +} + +void DialogAFBody::OnBnClickedButtonRenamebody() { + int i; + CString name, newName; + DialogAFName nameDlg; + + if ( !file || !body ) { + return; + } + + i = bodyList.GetCurSel(); + if ( i != CB_ERR ) { + bodyList.GetLBText( i, name ); + nameDlg.SetName( name ); + nameDlg.SetComboBox( &bodyList ); + if ( nameDlg.DoModal() == IDOK ) { + nameDlg.GetName( newName ); + // rename body + file->RenameBody( name, newName ); + bodyList.DeleteString( i ); + bodyList.SetCurSel( bodyList.AddString( newName ) ); + LoadBody( newName ); + constraintDlg->LoadFile( file ); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + } +} + +void DialogAFBody::OnBnClickedButtonDeletebody() { + int i; + CString str; + + if ( !file || !body ) { + return; + } + + i = bodyList.GetCurSel(); + if ( i != CB_ERR ) { + if ( MessageBox( "Are you sure you want to delete this body and all attached constraints ?", "Delete Body", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + bodyList.GetLBText( i, str ); + // delete currently selected body + file->DeleteBody( str ); + bodyList.DeleteString( i ); + body = NULL; + OnCbnSelchangeComboBodies(); + constraintDlg->LoadFile( file ); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + } + InitNewRenameDeleteButtons(); +} + +void DialogAFBody::OnCbnSelchangeComboCmType() { + InitCollisionModelType(); + UpdateFile(); +} + +void DialogAFBody::ValidateCollisionModelLength( bool update ) { + if ( cm_length < 1.0f ) { + cm_length = 1.0f; + update = true; + } + if ( update ) { + UpdateData( FALSE ); + } +} + +void DialogAFBody::OnEnChangeEditCmLength() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_LENGTH ) ) ) { + ValidateCollisionModelLength( false ); + UpdateFile(); + } + else { + cm_length = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_LENGTH ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinCmLength(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_length += 1.0f; + } + else if ( cm_length >= 2.0f ) { + cm_length -= 1.0f; + } + ValidateCollisionModelLength( true ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::ValidateCollisionModelHeight( bool update ) { + if ( cm_height < 1.0f ) { + cm_height = 1.0f; + update = true; + } + if ( update ) { + UpdateData( FALSE ); + } +} + +void DialogAFBody::OnEnChangeEditCmHeight() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_HEIGHT ) ) ) { + ValidateCollisionModelHeight( false ); + UpdateFile(); + } + else { + cm_height = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_HEIGHT ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinCmHeight(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_height += 1.0f; + } + else if ( cm_height >= 2.0f ) { + cm_height -= 1.0f; + } + ValidateCollisionModelHeight( true ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::ValidateCollisionModelWidth( bool update ) { + if ( cm_width < 1.0f ) { + cm_width = 1.0f; + update = true; + } + if ( update ) { + UpdateData( FALSE ); + } +} + +void DialogAFBody::OnEnChangeEditCmWidth() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_WIDTH ) ) ) { + ValidateCollisionModelWidth( false ); + UpdateFile(); + } + else { + cm_width = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_WIDTH ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinCmWidth(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_width += 1.0f; + } + else if ( cm_width >= 2.0f ) { + cm_width -= 1.0f; + } + ValidateCollisionModelWidth( true ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::ValidateCollisionModelNumSides( bool update ) { + cm_numSides = (int) cm_numSides; + if ( cm_numSides < 3 ) { + cm_numSides = 3; + update = true; + } + else if ( cm_numSides > 10 ) { + cm_numSides = 10; + update = true; + } + if ( update ) { + UpdateData( FALSE ); + } +} + +void DialogAFBody::OnEnChangeEditCmNumsides() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_NUMSIDES ) ) ) { + ValidateCollisionModelNumSides( false ); + UpdateFile(); + } +} + +void DialogAFBody::OnDeltaposSpinCmNumsides(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_numSides += 1; + } + else if ( cm_numSides > 3 ) { + cm_numSides -= 1; + } + ValidateCollisionModelNumSides( true ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnCbnSelchangeComboBoneJoint1() { + CString str; + GetSafeComboBoxSelection( &cm_comboBoneJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &cm_comboBoneJoint2, str ); + UpdateFile(); +} + +void DialogAFBody::OnCbnSelchangeComboBoneJoint2() { + CString str; + GetSafeComboBoxSelection( &cm_comboBoneJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &cm_comboBoneJoint1, str ); + UpdateFile(); +} + +void DialogAFBody::ValidateCollisionModelDensity( bool update ) { + if ( cm_density < 1e-6f ) { + cm_density = 1e-6f; + update = true; + } + if ( update ) { + UpdateData( FALSE ); + } +} + +void DialogAFBody::OnEnChangeEditCmDensity() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_DENSITY ) ) ) { + ValidateCollisionModelDensity( false ); + UpdateFile(); + } + else { + cm_density = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_DENSITY ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinCmDensity(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + cm_density = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CM_DENSITY ), pNMUpDown->iDelta < 0 ); + ValidateCollisionModelDensity( false ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditCmInertiascale() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_INERTIASCALE ) ) ) { + UpdateFile(); + } +} + +void DialogAFBody::OnBnClickedRadioOriginCoordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_COORDINATES ) ) { + if ( body ) { + body->origin.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFBody::OnBnClickedRadioOriginBonecenter() { + if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_BONECENTER ) ) { + if ( body ) { + body->origin.type = idAFVector::VEC_BONECENTER; + UpdateFile(); + } + } +} + +void DialogAFBody::OnBnClickedRadioOriginJoint() { + if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_JOINT ) ) { + if ( body ) { + body->origin.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFBody::OnEnChangeEditAfVectorX() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_X ) ) ) { + UpdateFile(); + } + else { + cm_origin_x = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_X ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAfVectorX(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_origin_x += 1; + } + else { + cm_origin_x -= 1; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditAfVectorY() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Y ) ) ) { + UpdateFile(); + } + else { + cm_origin_y = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Y ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAfVectorY(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_origin_y += 1; + } + else { + cm_origin_y -= 1; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditAfVectorZ() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Z ) ) ) { + UpdateFile(); + } + else { + cm_origin_z = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Z ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAfVectorZ(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_origin_z += 1; + } + else { + cm_origin_z -= 1; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnOnCbnSelchangeComboOriginBoneCenterJoint1() { + CString str; + GetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str ); + UpdateFile(); +} + +void DialogAFBody::OnOnCbnSelchangeComboOriginBoneCenterJoint2() { + CString str; + GetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str ); + UpdateFile(); +} + +void DialogAFBody::OnOnCbnSelchangeComboOriginJoint() { + UpdateFile(); +} + +void DialogAFBody::OnEnChangeEditAnglesPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_PITCH ) ) ) { + UpdateFile(); + } + else { + cm_angles_pitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_PITCH ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAnglesPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_angles_pitch += 1; + } + else { + cm_angles_pitch -= 1; + } + cm_angles_pitch = idMath::AngleNormalize360( cm_angles_pitch ); + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditAnglesYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_YAW ) ) ) { + UpdateFile(); + } + else { + cm_angles_yaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_YAW ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAnglesYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_angles_yaw += 1; + } + else { + cm_angles_yaw -= 1; + } + cm_angles_yaw = idMath::AngleNormalize360( cm_angles_yaw ); + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditAnglesRoll() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_ROLL ) ) ) { + UpdateFile(); + } + else { + cm_angles_roll = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_ROLL ) ); + } +} + +void DialogAFBody::OnDeltaposSpinAnglesRoll(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + cm_angles_roll += 1; + } + else { + cm_angles_roll -= 1; + } + cm_angles_roll = idMath::AngleNormalize360( cm_angles_roll ); + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnBnClickedCheckSelfcollision() { + UpdateFile(); +} + +void DialogAFBody::OnEnChangeEditContents() { + if ( EditControlEnterHit( &m_editContents ) ) { + UpdateFile(); + } +} + +void DialogAFBody::OnEnChangeEditClipmask() { + if ( EditControlEnterHit( &m_editClipMask ) ) { + UpdateFile(); + } +} + +void DialogAFBody::OnEnChangeEditLinearfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ) ) ) { + UpdateFile(); + } + else { + m_linearFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinLinearfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_linearFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_LINEARFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditAngularfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ) ) ) { + UpdateFile(); + } + else { + m_angularFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinAngularfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_angularFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_ANGULARFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditContactfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ) ) ) { + UpdateFile(); + } + else { + m_contactFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ), false ); + } +} + +void DialogAFBody::OnDeltaposSpinContactfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_contactFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CONTACTFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFBody::OnEnChangeEditFrictionDirection() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_FRICTIONDIRECTION ) ) ) { + UpdateFile(); + } +} + +void DialogAFBody::OnEnChangeEditContactMotorDirection() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTMOTORDIRECTION ) ) ) { + UpdateFile(); + } +} + +void DialogAFBody::OnCbnSelchangeComboModifiedjoint() { + UpdateFile(); +} + +void DialogAFBody::OnBnClickedRadioModifyOrientation() { + if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_ORIENTATION ) ) { + if ( body ) { + body->jointMod = DECLAF_JOINTMOD_AXIS; + UpdateFile(); + } + } +} + +void DialogAFBody::OnBnClickedRadioModifyPosition() { + if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_POSITION ) ) { + if ( body ) { + body->jointMod = DECLAF_JOINTMOD_ORIGIN; + UpdateFile(); + } + } +} + +void DialogAFBody::OnBnClickedRadioModifyBoth() { + if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_BOTH ) ) { + if ( body ) { + body->jointMod = DECLAF_JOINTMOD_BOTH; + UpdateFile(); + } + } +} + +void DialogAFBody::OnEnChangeEditContainedjoints() { + if ( EditControlEnterHit( &m_editContainedJoints ) ) { + UpdateFile(); + } +} diff --git a/tools/af/DialogAFBody.h b/tools/af/DialogAFBody.h new file mode 100644 index 000000000..3353e54ea --- /dev/null +++ b/tools/af/DialogAFBody.h @@ -0,0 +1,151 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFBody dialog + +class DialogAFBody : public CDialog { + + DECLARE_DYNAMIC(DialogAFBody) + +public: + DialogAFBody( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogAFBody(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadBody( const char *name ); + void SaveBody( void ); + void UpdateFile( void ); + + DialogAFConstraint *constraintDlg; + + enum { IDD = IDD_DIALOG_AF_BODY }; + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnShowWindow( BOOL bShow, UINT nStatus ); + afx_msg void OnCbnSelchangeComboBodies(); + afx_msg void OnBnClickedButtonNewbody(); + afx_msg void OnBnClickedButtonRenamebody(); + afx_msg void OnBnClickedButtonDeletebody(); + afx_msg void OnCbnSelchangeComboCmType(); + afx_msg void OnEnChangeEditCmLength(); + afx_msg void OnDeltaposSpinCmLength(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditCmHeight(); + afx_msg void OnDeltaposSpinCmHeight(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditCmWidth(); + afx_msg void OnDeltaposSpinCmWidth(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditCmNumsides(); + afx_msg void OnDeltaposSpinCmNumsides(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnCbnSelchangeComboBoneJoint1(); + afx_msg void OnCbnSelchangeComboBoneJoint2(); + afx_msg void OnEnChangeEditCmDensity(); + afx_msg void OnDeltaposSpinCmDensity(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditCmInertiascale(); + afx_msg void OnBnClickedRadioOriginCoordinates(); + afx_msg void OnBnClickedRadioOriginBonecenter(); + afx_msg void OnBnClickedRadioOriginJoint(); + afx_msg void OnEnChangeEditAfVectorX(); + afx_msg void OnDeltaposSpinAfVectorX(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAfVectorY(); + afx_msg void OnDeltaposSpinAfVectorY(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAfVectorZ(); + afx_msg void OnDeltaposSpinAfVectorZ(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnOnCbnSelchangeComboOriginBoneCenterJoint1(); + afx_msg void OnOnCbnSelchangeComboOriginBoneCenterJoint2(); + afx_msg void OnOnCbnSelchangeComboOriginJoint(); + afx_msg void OnEnChangeEditAnglesPitch(); + afx_msg void OnDeltaposSpinAnglesPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAnglesYaw(); + afx_msg void OnDeltaposSpinAnglesYaw(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAnglesRoll(); + afx_msg void OnDeltaposSpinAnglesRoll(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedCheckSelfcollision(); + afx_msg void OnEnChangeEditContents(); + afx_msg void OnEnChangeEditClipmask(); + afx_msg void OnEnChangeEditLinearfriction(); + afx_msg void OnDeltaposSpinLinearfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAngularfriction(); + afx_msg void OnDeltaposSpinAngularfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditContactfriction(); + afx_msg void OnDeltaposSpinContactfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditFrictionDirection(); + afx_msg void OnEnChangeEditContactMotorDirection(); + afx_msg void OnCbnSelchangeComboModifiedjoint(); + afx_msg void OnBnClickedRadioModifyOrientation(); + afx_msg void OnBnClickedRadioModifyPosition(); + afx_msg void OnBnClickedRadioModifyBoth(); + afx_msg void OnEnChangeEditContainedjoints(); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Body * body; + int numJoints; + + //{{AFX_DATA(DialogAFBody) + CComboBox bodyList; // list with bodies + CComboBox cm_comboType; + float cm_length; + float cm_height; + float cm_width; + CComboBox cm_comboBoneJoint1; + CComboBox cm_comboBoneJoint2; + float cm_numSides; + float cm_density; + CEdit cm_inertiaScale; + float cm_origin_x; + float cm_origin_y; + float cm_origin_z; + CComboBox cm_originBoneCenterJoint1; + CComboBox cm_originBoneCenterJoint2; + CComboBox cm_originJoint; + float cm_angles_pitch; + float cm_angles_yaw; + float cm_angles_roll; + BOOL m_selfCollision; + CEdit m_editContents; + CEdit m_editClipMask; + float m_linearFriction; + float m_angularFriction; + float m_contactFriction; + CEdit m_frictionDirection; + CEdit m_contactMotorDirection; + CComboBox m_comboModifiedJoint; + CEdit m_editContainedJoints; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitBodyList( void ); + void InitJointLists( void ); + void InitCollisionModelType( void ); + void InitModifiedJointList( void ); + void InitNewRenameDeleteButtons( void ); + void ValidateCollisionModelLength( bool update ); + void ValidateCollisionModelHeight( bool update ); + void ValidateCollisionModelWidth( bool update ); + void ValidateCollisionModelNumSides( bool update ); + void ValidateCollisionModelDensity( bool update ); +}; diff --git a/tools/af/DialogAFConstraint.cpp b/tools/af/DialogAFConstraint.cpp new file mode 100644 index 000000000..fb21ee575 --- /dev/null +++ b/tools/af/DialogAFConstraint.cpp @@ -0,0 +1,552 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFName.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintFixed.h" +#include "DialogAFConstraintBallAndSocket.h" +#include "DialogAFConstraintUniversal.h" +#include "DialogAFConstraintHinge.h" +#include "DialogAFConstraintSlider.h" +#include "DialogAFConstraintSpring.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +typedef struct { + declAFConstraintType_t type; + const char *name; +} c_type_t; + +c_type_t constraintTypes[] = { + { DECLAF_CONSTRAINT_FIXED, "fixed" }, + { DECLAF_CONSTRAINT_BALLANDSOCKETJOINT, "ball and socket" }, + { DECLAF_CONSTRAINT_UNIVERSALJOINT, "universal" }, + { DECLAF_CONSTRAINT_HINGE, "hinge" }, + { DECLAF_CONSTRAINT_SLIDER, "slider" }, + { DECLAF_CONSTRAINT_SPRING, "spring" }, + { DECLAF_CONSTRAINT_INVALID, NULL } +}; + + +const char *ConstraintTypeToString( declAFConstraintType_t type ) { + for ( int i = 0; constraintTypes[i].name; i++ ) { + if ( constraintTypes[i].type == type ) { + return constraintTypes[i].name; + } + } + return ""; +} + +declAFConstraintType_t StringToConstraintType( const char *str ) { + for ( int i = 0; constraintTypes[i].name; i++ ) { + if ( idStr::Icmp( constraintTypes[i].name, str ) == 0 ) { + return constraintTypes[i].type; + } + } + return DECLAF_CONSTRAINT_INVALID; +} + + +// DialogAFConstraint dialog + +toolTip_t DialogAFConstraint::toolTips[] = { + { IDC_COMBO_CONSTRAINTS, "select contraint for editing" }, + { IDC_BUTTON_NEWCONSTRAINT, "create a new constraint" }, + { IDC_BUTTON_RENAMECONSTRAINT, "rename the selected constraint" }, + { IDC_BUTTON_DELETECONSTRAINT, "delete the selected constraint" }, + { IDC_COMBO_CONSTRAINT_TYPE, "constraint type" }, + { IDC_COMBO_CONSTRAINT_BODY1, "first constrained body" }, + { IDC_COMBO_CONSTRAINT_BODY2, "second constrained body" }, + { IDC_EDIT_CONSTRAINT_FRICTION, "constraint friction" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraint, CDialog) + +/* +================ +DialogAFConstraint::DialogAFConstraint +================ +*/ +DialogAFConstraint::DialogAFConstraint( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogAFConstraint::IDD, pParent) + , m_friction(0) + , constraint(NULL) + , file(NULL) + , constraintDlg(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraint::~DialogAFConstraint +================ +*/ +DialogAFConstraint::~DialogAFConstraint() { +} + +/* +================ +DialogAFConstraint::DoDataExchange +================ +*/ +void DialogAFConstraint::DoDataExchange( CDataExchange* pDX ) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraint) + DDX_Control(pDX, IDC_COMBO_CONSTRAINTS, m_comboConstraintList); + DDX_Control(pDX, IDC_COMBO_CONSTRAINT_TYPE, m_comboConstraintType); + DDX_Control(pDX, IDC_COMBO_CONSTRAINT_BODY1, m_comboBody1List); + DDX_Control(pDX, IDC_COMBO_CONSTRAINT_BODY2, m_comboBody2List); + DDX_Text(pDX, IDC_EDIT_CONSTRAINT_FRICTION, m_friction); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraint::InitConstraintList +================ +*/ +void DialogAFConstraint::InitConstraintList( void ) { + CString str; + + m_comboConstraintList.ResetContent(); + if ( !file ) { + return; + } + for ( int i = 0; i < file->constraints.Num(); i++ ) { + m_comboConstraintList.AddString( file->constraints[i]->name.c_str() ); + } + if ( m_comboConstraintList.GetCount() != 0 ) { + m_comboConstraintList.SetCurSel( 0 ); + m_comboConstraintList.GetLBText( 0, str ); + LoadConstraint( str ); + } +} + +/* +================ +DialogAFConstraint::InitConstraintTypeDlg +================ +*/ +void DialogAFConstraint::InitConstraintTypeDlg( void ) { + CString str; + RECT rect; + + if ( !file || !constraint ) { + return; + } + + UpdateData( TRUE ); + + if ( constraintDlg ) { + constraintDlg->ShowWindow( SW_HIDE ); + } + + GetSafeComboBoxSelection( &m_comboConstraintType, str, -1 ); + switch( StringToConstraintType( str ) ) { + case DECLAF_CONSTRAINT_FIXED: + fixedDlg->LoadConstraint( constraint ); + constraintDlg = fixedDlg; + break; + case DECLAF_CONSTRAINT_BALLANDSOCKETJOINT: + ballAndSocketDlg->LoadConstraint( constraint ); + constraintDlg = ballAndSocketDlg; + break; + case DECLAF_CONSTRAINT_UNIVERSALJOINT: + universalDlg->LoadConstraint( constraint ); + constraintDlg = universalDlg; + break; + case DECLAF_CONSTRAINT_HINGE: + hingeDlg->LoadConstraint( constraint ); + constraintDlg = hingeDlg; + break; + case DECLAF_CONSTRAINT_SLIDER: + sliderDlg->LoadConstraint( constraint ); + constraintDlg = sliderDlg; + break; + case DECLAF_CONSTRAINT_SPRING: + springDlg->LoadConstraint( constraint ); + constraintDlg = springDlg; + break; + } + + if ( constraintDlg ) { + constraintDlg->ShowWindow( SW_SHOW ); + constraintDlg->GetWindowRect( &rect ); + constraintDlg->MoveWindow( 0, 117, rect.right - rect.left, rect.bottom - rect.top ); + } +} + +/* +================ +DialogAFConstraint::InitBodyLists +================ +*/ +void DialogAFConstraint::InitBodyLists( void ) { + m_comboBody1List.ResetContent(); + m_comboBody2List.ResetContent(); + if ( !file ) { + return; + } + for ( int i = 0; i < file->bodies.Num(); i++ ) { + m_comboBody1List.AddString( file->bodies[i]->name ); + m_comboBody2List.AddString( file->bodies[i]->name ); + } + // the second body may also be the world + m_comboBody2List.AddString( "world" ); // FIXME: we currently assume this is the last body in the list +} + +/* +================ +DialogAFConstraint::InitNewRenameDeleteButtons +================ +*/ +void DialogAFConstraint::InitNewRenameDeleteButtons( void ) { + if ( file && file->bodies.Num() >= 1 ) { + GetDlgItem( IDC_BUTTON_NEWCONSTRAINT )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_BUTTON_NEWCONSTRAINT )->EnableWindow( false ); + } + + if ( file && m_comboConstraintList.GetCount() >= 1 ) { + GetDlgItem( IDC_BUTTON_RENAMECONSTRAINT )->EnableWindow( true ); + GetDlgItem( IDC_BUTTON_DELETECONSTRAINT )->EnableWindow( true ); + } + else { + GetDlgItem( IDC_BUTTON_RENAMECONSTRAINT )->EnableWindow( false ); + GetDlgItem( IDC_BUTTON_DELETECONSTRAINT )->EnableWindow( false ); + } +} + +/* +================ +DialogAFConstraint::LoadFile +================ +*/ +void DialogAFConstraint::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + ballAndSocketDlg->LoadFile( af ); + universalDlg->LoadFile( af ); + hingeDlg->LoadFile( af ); + sliderDlg->LoadFile( af ); + springDlg->LoadFile( af ); + InitBodyLists(); + InitConstraintList(); + InitNewRenameDeleteButtons(); +} + +/* +================ +DialogAFConstraint::SaveFile +================ +*/ +void DialogAFConstraint::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraint::LoadConstraint +================ +*/ +void DialogAFConstraint::LoadConstraint( const char *name ) { + int i, s1, s2; + + if ( !file ) { + return; + } + for ( i = 0; i < file->constraints.Num(); i++ ) { + if ( file->constraints[i]->name.Icmp( name ) == 0 ) { + break; + } + } + if ( i >= file->constraints.Num() ) { + return; + } + constraint = file->constraints[i]; + + // load the constraint type from the current idDeclAF_Constraint + SetSafeComboBoxSelection( &m_comboConstraintType, ConstraintTypeToString( constraint->type ), -1 ); + + // load constrained bodies from the current idDeclAF_Constraint + s1 = SetSafeComboBoxSelection( &m_comboBody1List, constraint->body1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboBody2List, constraint->body2.c_str(), s1 ); + + // load friction from the current idDeclAF_Constraint + m_friction = constraint->friction; + + // update displayed values + UpdateData( FALSE ); + + InitConstraintTypeDlg(); + + if ( GetStyle() & WS_VISIBLE ) { + // highlight the current constraint ingame + cvarSystem->SetCVarString( "af_highlightConstraint", name ); + } +} + +/* +================ +DialogAFConstraint::SaveConstraint +================ +*/ +void DialogAFConstraint::SaveConstraint( void ) { + int s1, s2; + CString str; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // save constraint type to the current idDeclAF_Constraint + GetSafeComboBoxSelection( &m_comboConstraintType, str, -1 ); + constraint->type = StringToConstraintType( str ); + + // save constrained bodies to the current idDeclAF_Constraint + s1 = GetSafeComboBoxSelection( &m_comboBody1List, str, -1 ); + constraint->body1 = str; + s2 = GetSafeComboBoxSelection( &m_comboBody2List, str, s1 ); + constraint->body2 = str; + + // save friction to the current idDeclAF_Constraint + constraint->friction = m_friction; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraint::UpdateFile +================ +*/ +void DialogAFConstraint::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraint::OnInitDialog +================ +*/ +BOOL DialogAFConstraint::OnInitDialog() { + + CDialog::OnInitDialog(); + + // initialize the constraint types + m_comboConstraintType.ResetContent(); + for ( int i = 0; constraintTypes[i].name; i++ ) { + m_comboConstraintType.AddString( constraintTypes[i].name ); + } + + fixedDlg = new DialogAFConstraintFixed( this ); + fixedDlg->ShowWindow( SW_HIDE ); + + ballAndSocketDlg = new DialogAFConstraintBallAndSocket( this ); + ballAndSocketDlg->ShowWindow( SW_HIDE ); + + universalDlg = new DialogAFConstraintUniversal( this ); + universalDlg->ShowWindow( SW_HIDE ); + + hingeDlg = new DialogAFConstraintHinge( this ); + hingeDlg->ShowWindow( SW_HIDE ); + + sliderDlg = new DialogAFConstraintSlider( this ); + sliderDlg->ShowWindow( SW_HIDE ); + + springDlg = new DialogAFConstraintSpring( this ); + springDlg->ShowWindow( SW_HIDE ); + + constraintDlg = NULL; + + InitNewRenameDeleteButtons(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +/* +================ +DialogAFConstraint::OnToolHitTest +================ +*/ +int DialogAFConstraint::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + +BEGIN_MESSAGE_MAP(DialogAFConstraint, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_SHOWWINDOW() + ON_CBN_SELCHANGE(IDC_COMBO_CONSTRAINTS, OnCbnSelchangeComboConstraints) + ON_CBN_SELCHANGE(IDC_COMBO_CONSTRAINT_TYPE, OnCbnSelchangeComboConstraintType) + ON_CBN_SELCHANGE(IDC_COMBO_CONSTRAINT_BODY1, OnCbnSelchangeComboConstraintBody1) + ON_CBN_SELCHANGE(IDC_COMBO_CONSTRAINT_BODY2, OnCbnSelchangeComboConstraintBody2) + ON_EN_CHANGE(IDC_EDIT_CONSTRAINT_FRICTION, OnEnChangeEditConstraintFriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CONSTRAINT_FRICTION, OnDeltaposSpinConstraintFriction) + ON_BN_CLICKED(IDC_BUTTON_NEWCONSTRAINT, OnBnClickedButtonNewconstraint) + ON_BN_CLICKED(IDC_BUTTON_RENAMECONSTRAINT, OnBnClickedButtonRenameconstraint) + ON_BN_CLICKED(IDC_BUTTON_DELETECONSTRAINT, OnBnClickedButtonDeleteconstraint) +END_MESSAGE_MAP() + + +// DialogAFConstraint message handlers + +BOOL DialogAFConstraint::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraint::OnShowWindow( BOOL bShow, UINT nStatus ) { + if ( bShow && constraint ) { + cvarSystem->SetCVarString( "af_highlightConstraint", constraint->name.c_str() ); + } else { + cvarSystem->SetCVarString( "af_highlightConstraint", "" ); + } + CDialog::OnShowWindow( bShow, nStatus ); +} + +void DialogAFConstraint::OnCbnSelchangeComboConstraints() { + CString str; + + GetSafeComboBoxSelection( &m_comboConstraintList, str, -1 ); + LoadConstraint( str ); +} + +void DialogAFConstraint::OnBnClickedButtonNewconstraint() { + DialogAFName nameDlg; + CString str; + + nameDlg.SetComboBox( &m_comboConstraintList ); + if ( nameDlg.DoModal() == IDOK ) { + nameDlg.GetName( str ); + // create new constraint + file->NewConstraint( str ); + m_comboConstraintList.SetCurSel( m_comboConstraintList.AddString( str ) ); + LoadConstraint( str ); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + InitNewRenameDeleteButtons(); +} + +void DialogAFConstraint::OnBnClickedButtonRenameconstraint() { + int i; + CString name, newName; + DialogAFName nameDlg; + + if ( !file || !constraint ) { + return; + } + + i = m_comboConstraintList.GetCurSel(); + if ( i != CB_ERR ) { + m_comboConstraintList.GetLBText( i, name ); + nameDlg.SetName( name ); + nameDlg.SetComboBox( &m_comboConstraintList ); + if ( nameDlg.DoModal() == IDOK ) { + nameDlg.GetName( newName ); + // rename constraint; + file->RenameConstraint( name, newName ); + m_comboConstraintList.DeleteString( i ); + m_comboConstraintList.SetCurSel( m_comboConstraintList.AddString( newName ) ); + LoadConstraint( newName ); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + } +} + +void DialogAFConstraint::OnBnClickedButtonDeleteconstraint() { + int i; + CString str; + + if ( !file || !constraint ) { + return; + } + + i = m_comboConstraintList.GetCurSel(); + if ( i != CB_ERR ) { + if ( MessageBox( "Are you sure you want to delete this constraint ?", "Delete Constraint", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + m_comboConstraintList.GetLBText( i, str ); + // delete current constraint + file->DeleteConstraint( str ); + constraint = NULL; + m_comboConstraintList.DeleteString( i ); + OnCbnSelchangeComboConstraints(); + gameEdit->AF_UpdateEntities( file->GetName() ); + AFDialogSetFileModified(); + } + } + InitNewRenameDeleteButtons(); +} + +void DialogAFConstraint::OnCbnSelchangeComboConstraintType() { + InitConstraintTypeDlg(); + UpdateFile(); +} + +void DialogAFConstraint::OnCbnSelchangeComboConstraintBody1() { + CString str; + GetSafeComboBoxSelection( &m_comboBody1List, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboBody2List, str ); + UpdateFile(); +} + +void DialogAFConstraint::OnCbnSelchangeComboConstraintBody2() { + CString str; + GetSafeComboBoxSelection( &m_comboBody2List, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboBody1List, str ); + UpdateFile(); +} + +void DialogAFConstraint::OnEnChangeEditConstraintFriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONSTRAINT_FRICTION ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CONSTRAINT_FRICTION ), false ); + } +} + +void DialogAFConstraint::OnDeltaposSpinConstraintFriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_friction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CONSTRAINT_FRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraint.h b/tools/af/DialogAFConstraint.h new file mode 100644 index 000000000..24bd0e7fa --- /dev/null +++ b/tools/af/DialogAFConstraint.h @@ -0,0 +1,89 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +class DialogAFConstraintFixed; +class DialogAFConstraintBallAndSocket; +class DialogAFConstraintUniversal; +class DialogAFConstraintHinge; +class DialogAFConstraintSlider; +class DialogAFConstraintSpring; + +// DialogAFConstraint dialog + +class DialogAFConstraint : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraint) + +public: + DialogAFConstraint( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogAFConstraint(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( const char *name ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT }; + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnShowWindow( BOOL bShow, UINT nStatus ); + afx_msg void OnCbnSelchangeComboConstraints(); + afx_msg void OnBnClickedButtonNewconstraint(); + afx_msg void OnBnClickedButtonRenameconstraint(); + afx_msg void OnBnClickedButtonDeleteconstraint(); + afx_msg void OnCbnSelchangeComboConstraintType(); + afx_msg void OnCbnSelchangeComboConstraintBody1(); + afx_msg void OnCbnSelchangeComboConstraintBody2(); + afx_msg void OnEnChangeEditConstraintFriction(); + afx_msg void OnDeltaposSpinConstraintFriction(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + CDialog * constraintDlg; + DialogAFConstraintFixed *fixedDlg; + DialogAFConstraintBallAndSocket *ballAndSocketDlg; + DialogAFConstraintUniversal *universalDlg; + DialogAFConstraintHinge *hingeDlg; + DialogAFConstraintSlider *sliderDlg; + DialogAFConstraintSpring *springDlg; + + //{{AFX_DATA(DialogAFConstraint) + CComboBox m_comboConstraintList; // list with constraints + CComboBox m_comboConstraintType; + CComboBox m_comboBody1List; + CComboBox m_comboBody2List; + float m_friction; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitConstraintList( void ); + void InitConstraintTypeDlg( void ); + void InitBodyLists( void ); + void InitNewRenameDeleteButtons( void ); +}; diff --git a/tools/af/DialogAFConstraintBallAndSocket.cpp b/tools/af/DialogAFConstraintBallAndSocket.cpp new file mode 100644 index 000000000..6b67c16f9 --- /dev/null +++ b/tools/af/DialogAFConstraintBallAndSocket.cpp @@ -0,0 +1,726 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintBallAndSocket.h" + + +// DialogAFConstraintBallAndSocket dialog + +toolTip_t DialogAFConstraintBallAndSocket::toolTips[] = { + { IDC_RADIO_ANCHOR_JOINT, "use the position of a joint for the anchor" }, + { IDC_COMBO_ANCHOR_JOINT, "anchor joint name" }, + { IDC_RADIO_ANCHOR_COORDINATES, "use absolute coordinates for the anchor" }, + { IDC_EDIT_ANCHOR_X, "anchor x-coordinate" }, + { IDC_EDIT_ANCHOR_Y, "anchor y-coordinate" }, + { IDC_EDIT_ANCHOR_Z, "anchor z-coordinate" }, + { IDC_RADIO_BAS_LIMIT_NONE, "no joint limit" }, + { IDC_RADIO_BAS_LIMIT_CONE, "cone shaped joint limit" }, + { IDC_RADIO_BAS_LIMIT_PYRAMID, "pyramid shaped joint limit" }, + { IDC_EDIT_BAS_LIMIT_CONE_ANGLE, "cone angle" }, + { IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1, "first pyramid angle" }, + { IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2, "second pyramid angle" }, + { IDC_EDIT_BAS_LIMIT_ROLL, "roll angle" }, + { IDC_RADIO_BAS_LIMIT_BONE, "use a bone for the orientation of the limit" }, + { IDC_RADIO_BAS_LIMIT_ANGLES, "use angles to set the orientation of the limit" }, + { IDC_COMBO_BAS_LIMIT_JOINT1, "bone start joint" }, + { IDC_COMBO_BAS_LIMIT_JOINT2, "bone end joint" }, + { IDC_EDIT_BAS_LIMIT_PITCH, "pitch angle" }, + { IDC_EDIT_BAS_LIMIT_YAW, "yaw angle" }, + { IDC_RADIO_BAS_LIMIT_AXIS_BONE, "use a bone for the limit axis" }, + { IDC_RADIO_BAS_LIMIT_AXIS_ANGLES, "use angles to set the orientation of the limit axis" }, + { IDC_COMBO_BAS_LIMIT_AXIS_JOINT1, "bone start joint" }, + { IDC_COMBO_BAS_LIMIT_AXIS_JOINT2, "bone end joint" }, + { IDC_EDIT_BAS_LIMIT_AXIS_PITCH, "pitch angle" }, + { IDC_EDIT_BAS_LIMIT_AXIS_YAW, "yaw angle" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintBallAndSocket, CDialog) + +/* +================ +DialogAFConstraintBallAndSocket::DialogAFConstraintBallAndSocket +================ +*/ +DialogAFConstraintBallAndSocket::DialogAFConstraintBallAndSocket(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintBallAndSocket::IDD, pParent) + , m_anchor_x(0) + , m_anchor_y(0) + , m_anchor_z(0) + , m_coneAngle(30.0f) + , m_pyramidAngle1(30.0f) + , m_pyramidAngle2(30.0f) + , m_limitPitch(0) + , m_limitYaw(0) + , m_limitRoll(0) + , m_limitAxisPitch(0) + , m_limitAxisYaw(0) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_BALLANDSOCKET, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintBallAndSocket::~DialogAFConstraintBallAndSocket +================ +*/ +DialogAFConstraintBallAndSocket::~DialogAFConstraintBallAndSocket() { +} + +/* +================ +DialogAFConstraintBallAndSocket::DoDataExchange +================ +*/ +void DialogAFConstraintBallAndSocket::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintBallAndSocket) + DDX_Control(pDX, IDC_COMBO_ANCHOR_JOINT, m_comboAnchorJoint); + DDX_Text(pDX, IDC_EDIT_ANCHOR_X, m_anchor_x); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Y, m_anchor_y); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Z, m_anchor_z); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_CONE_ANGLE, m_coneAngle); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1, m_pyramidAngle1); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2, m_pyramidAngle2); + DDX_Control(pDX, IDC_COMBO_BAS_LIMIT_JOINT1, m_comboLimitJoint1); + DDX_Control(pDX, IDC_COMBO_BAS_LIMIT_JOINT2, m_comboLimitJoint2); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_PITCH, m_limitPitch); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_YAW, m_limitYaw); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_ROLL, m_limitRoll); + DDX_Control(pDX, IDC_COMBO_BAS_LIMIT_AXIS_JOINT1, m_comboLimitAxisJoint1); + DDX_Control(pDX, IDC_COMBO_BAS_LIMIT_AXIS_JOINT2, m_comboLimitAxisJoint2); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_AXIS_PITCH, m_limitAxisPitch); + DDX_Text(pDX, IDC_EDIT_BAS_LIMIT_AXIS_YAW, m_limitAxisYaw); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintBallAndSocket::InitJointLists +================ +*/ +void DialogAFConstraintBallAndSocket::InitJointLists( void ) { + m_comboAnchorJoint.ResetContent(); + m_comboLimitJoint1.ResetContent(); + m_comboLimitJoint2.ResetContent(); + m_comboLimitAxisJoint1.ResetContent(); + m_comboLimitAxisJoint2.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + int numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + m_comboAnchorJoint.AddString( jointName ); + m_comboLimitJoint1.AddString( jointName ); + m_comboLimitJoint2.AddString( jointName ); + m_comboLimitAxisJoint1.AddString( jointName ); + m_comboLimitAxisJoint2.AddString( jointName ); + } +} + +/* +================ +DialogAFConstraintBallAndSocket::LoadFile +================ +*/ +void DialogAFConstraintBallAndSocket::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintBallAndSocket::SaveFile +================ +*/ +void DialogAFConstraintBallAndSocket::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintBallAndSocket::LoadConstraint +================ +*/ +void DialogAFConstraintBallAndSocket::LoadConstraint( idDeclAF_Constraint *c ) { + int i, s1, s2; + idAngles angles; + + constraint = c; + + // anchor + SetSafeComboBoxSelection( &m_comboAnchorJoint, constraint->anchor.joint1.c_str(), -1 ); + m_anchor_x = constraint->anchor.ToVec3().x; + m_anchor_y = constraint->anchor.ToVec3().y; + m_anchor_z = constraint->anchor.ToVec3().z; + if ( constraint->anchor.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ANCHOR_JOINT; + } + else { + i = IDC_RADIO_ANCHOR_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ANCHOR_JOINT, IDC_RADIO_ANCHOR_COORDINATES, i ); + + // limit + if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) { + i = IDC_RADIO_BAS_LIMIT_CONE; + } + else if ( constraint->limit == idDeclAF_Constraint::LIMIT_PYRAMID ) { + i = IDC_RADIO_BAS_LIMIT_PYRAMID; + } + else { + i = IDC_RADIO_BAS_LIMIT_NONE; + } + CheckRadioButton( IDC_RADIO_BAS_LIMIT_NONE, IDC_RADIO_BAS_LIMIT_PYRAMID, i ); + + m_coneAngle = constraint->limitAngles[0]; + m_pyramidAngle1 = constraint->limitAngles[0]; + m_pyramidAngle2 = constraint->limitAngles[1]; + m_limitRoll = constraint->limitAngles[2]; + angles = constraint->limitAxis.ToVec3().ToAngles(); + m_limitPitch = angles.pitch; + m_limitYaw = angles.yaw; + + if ( constraint->limitAxis.type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_BAS_LIMIT_BONE; + } + else { + i = IDC_RADIO_BAS_LIMIT_ANGLES; + } + CheckRadioButton( IDC_RADIO_BAS_LIMIT_BONE, IDC_RADIO_BAS_LIMIT_ANGLES, i ); + s1 = SetSafeComboBoxSelection( &m_comboLimitJoint1, constraint->limitAxis.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboLimitJoint2, constraint->limitAxis.joint2.c_str(), s1 ); + + // limit axis + s1 = SetSafeComboBoxSelection( &m_comboLimitAxisJoint1, constraint->shaft[0].joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboLimitAxisJoint2, constraint->shaft[0].joint2.c_str(), s1 ); + angles = constraint->shaft[0].ToVec3().ToAngles(); + m_limitAxisPitch = angles.pitch; + m_limitAxisYaw = angles.yaw; + if ( constraint->shaft[0].type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_BAS_LIMIT_AXIS_BONE; + } + else { + i = IDC_RADIO_BAS_LIMIT_AXIS_ANGLES; + constraint->shaft[0].type = idAFVector::VEC_COORDS; + } + CheckRadioButton( IDC_RADIO_BAS_LIMIT_AXIS_BONE, IDC_RADIO_BAS_LIMIT_AXIS_ANGLES, i ); + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintBallAndSocket::SaveConstraint +================ +*/ +void DialogAFConstraintBallAndSocket::SaveConstraint( void ) { + int s1, s2; + CString str; + idAngles angles; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // anchor + GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 ); + constraint->anchor.joint1 = str; + constraint->anchor.ToVec3().x = m_anchor_x; + constraint->anchor.ToVec3().y = m_anchor_y; + constraint->anchor.ToVec3().z = m_anchor_z; + + // limit + if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) { + constraint->limitAngles[0] = m_coneAngle; + } + else { + constraint->limitAngles[0] = m_pyramidAngle1; + } + constraint->limitAngles[1] = m_pyramidAngle2; + constraint->limitAngles[2] = m_limitRoll; + angles.pitch = m_limitPitch; + angles.yaw = m_limitYaw; + angles.roll = 0.0f; + constraint->limitAxis.ToVec3() = angles.ToForward(); + s1 = GetSafeComboBoxSelection( &m_comboLimitJoint1, str, -1 ); + constraint->limitAxis.joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboLimitJoint2, str, s1 ); + constraint->limitAxis.joint2 = str; + + // limit axis + if ( constraint->shaft[0].type == idAFVector::VEC_BONEDIR ) { + s1 = GetSafeComboBoxSelection( &m_comboLimitAxisJoint1, str, -1 ); + constraint->shaft[0].joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboLimitAxisJoint2, str, s1 ); + constraint->shaft[0].joint2 = str; + } + else { + constraint->shaft[0].ToVec3() = idAngles( m_limitAxisPitch, m_limitAxisYaw, 0.0f ).ToForward(); + } + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintBallAndSocket::UpdateFile +================ +*/ +void DialogAFConstraintBallAndSocket::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintBallAndSocket::OnToolHitTest +================ +*/ +int DialogAFConstraintBallAndSocket::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintBallAndSocket, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_JOINT, OnBnClickedRadioAnchorJoint) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_COORDINATES, OnBnClickedRadioAnchorCoordinates) + ON_CBN_SELCHANGE(IDC_COMBO_ANCHOR_JOINT, OnCbnSelchangeComboAnchorJoint) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_X, OnEnChangeEditAnchorX) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Y, OnEnChangeEditAnchorY) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Z, OnEnChangeEditAnchorZ) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_X, OnDeltaposSpinAnchorX) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Y, OnDeltaposSpinAnchorY) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Z, OnDeltaposSpinAnchorZ) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_NONE, OnBnClickedRadioBasLimitNone) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_CONE, OnBnClickedRadioBasLimitCone) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_PYRAMID, OnBnClickedRadioBasLimitPyramid) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_CONE_ANGLE, OnEnChangeEditBasLimitConeAngle) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_CONE_ANGLE, OnDeltaposSpinBasLimitConeAngle) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1, OnEnChangeEditBasLimitPyramidAngle1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE1, OnDeltaposSpinBasLimitPyramidAngle1) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2, OnEnChangeEditBasLimitPyramidAngle2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_PYRAMID_ANGLE2, OnDeltaposSpinBasLimitPyramidAngle2) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_ROLL, OnEnChangeEditBasLimitRoll) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_ROLL, OnDeltaposSpinBasLimitRoll) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_BONE, OnBnClickedRadioBasLimitBone) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_ANGLES, OnBnClickedRadioBasLimitAngles) + ON_CBN_SELCHANGE(IDC_COMBO_BAS_LIMIT_JOINT1, OnCbnSelchangeComboBasLimitJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_BAS_LIMIT_JOINT2, OnCbnSelchangeComboBasLimitJoint2) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_PITCH, OnEnChangeEditBasLimitPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_PITCH, OnDeltaposSpinBasLimitPitch) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_YAW, OnEnChangeEditBasLimitYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_YAW, OnDeltaposSpinBasLimitYaw) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_AXIS_BONE, OnBnClickedRadioBasLimitAxisBone) + ON_BN_CLICKED(IDC_RADIO_BAS_LIMIT_AXIS_ANGLES, OnBnClickedRadioBasLimitAxisAngles) + ON_CBN_SELCHANGE(IDC_COMBO_BAS_LIMIT_AXIS_JOINT1, OnCbnSelchangeComboBasLimitAxisJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_BAS_LIMIT_AXIS_JOINT2, OnCbnSelchangeComboBasLimitAxisJoint2) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_AXIS_PITCH, OnEnChangeEditBasLimitAxisPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_AXIS_PITCH, OnDeltaposSpinBasLimitAxisPitch) + ON_EN_CHANGE(IDC_EDIT_BAS_LIMIT_AXIS_YAW, OnEnChangeEditBasLimitAxisYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BAS_LIMIT_AXIS_YAW, OnDeltaposSpinBasLimitAxisYaw) +END_MESSAGE_MAP() + + +// DialogAFConstraintBallAndSocket message handlers + +BOOL DialogAFConstraintBallAndSocket::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioAnchorJoint() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_JOINT ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioAnchorCoordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_COORDINATES ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnCbnSelchangeComboAnchorJoint() { + UpdateFile(); +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditAnchorX() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ) ) { + UpdateFile(); + } + else { + m_anchor_x = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditAnchorY() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ) ) { + UpdateFile(); + } + else { + m_anchor_y = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditAnchorZ() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ) ) { + UpdateFile(); + } + else { + m_anchor_z = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_x += 1.0f; + } + else { + m_anchor_x -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_y += 1.0f; + } + else { + m_anchor_y -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_z += 1.0f; + } + else { + m_anchor_z -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitNone() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_NONE ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitCone() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_CONE ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitPyramid() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_PYRAMID ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_PYRAMID; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitConeAngle() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_CONE_ANGLE ) ) ) { + UpdateFile(); + } + else { + m_coneAngle = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_CONE_ANGLE ), false ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitConeAngle(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_coneAngle += 1.0f; + } + else if ( m_coneAngle > 0.0f ) { + m_coneAngle -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitPyramidAngle1() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1 ) ) ) { + UpdateFile(); + } + else { + m_pyramidAngle1 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE1 ), false ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitPyramidAngle1(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pyramidAngle1 += 1.0f; + } + else if ( m_pyramidAngle1 > 0.0f ) { + m_pyramidAngle1 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitPyramidAngle2() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2 ) ) ) { + UpdateFile(); + } + else { + m_pyramidAngle2 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PYRAMID_ANGLE2 ), false ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitPyramidAngle2(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pyramidAngle2 += 1.0f; + } + else if ( m_pyramidAngle2 > 0.0f ) { + m_pyramidAngle2 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitRoll() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_ROLL ) ) ) { + UpdateFile(); + } + else { + m_limitRoll = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_ROLL ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitRoll(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitRoll += 1.0f; + } + else { + m_limitRoll -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitBone() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_BONE ) ) { + if ( constraint ) { + constraint->limitAxis.type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_ANGLES ) ) { + if ( constraint ) { + constraint->limitAxis.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnCbnSelchangeComboBasLimitJoint1() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitJoint2, str ); + UpdateFile(); +} + +void DialogAFConstraintBallAndSocket::OnCbnSelchangeComboBasLimitJoint2() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitJoint1, str ); + UpdateFile(); +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PITCH ) ) ) { + UpdateFile(); + } + else { + m_limitPitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_PITCH ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitPitch += 1.0f; + } + else { + m_limitPitch -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_YAW ) ) ) { + UpdateFile(); + } + else { + m_limitYaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_YAW ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitYaw += 1.0f; + } + else { + m_limitYaw -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitAxisBone() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_AXIS_BONE ) ) { + if ( constraint ) { + constraint->shaft[0].type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnBnClickedRadioBasLimitAxisAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_BAS_LIMIT_AXIS_ANGLES ) ) { + if ( constraint ) { + constraint->shaft[0].type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintBallAndSocket::OnCbnSelchangeComboBasLimitAxisJoint1() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitAxisJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitAxisJoint2, str ); + UpdateFile(); +} + +void DialogAFConstraintBallAndSocket::OnCbnSelchangeComboBasLimitAxisJoint2() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitAxisJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitAxisJoint1, str ); + UpdateFile(); +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitAxisPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_AXIS_PITCH ) ) ) { + UpdateFile(); + } + else { + m_limitAxisPitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_AXIS_PITCH ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitAxisPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitAxisPitch += 1.0f; + } + else { + m_limitAxisPitch -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintBallAndSocket::OnEnChangeEditBasLimitAxisYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_AXIS_YAW ) ) ) { + UpdateFile(); + } + else { + m_limitAxisYaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_BAS_LIMIT_AXIS_YAW ) ); + } +} + +void DialogAFConstraintBallAndSocket::OnDeltaposSpinBasLimitAxisYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitAxisYaw += 1.0f; + } + else { + m_limitAxisYaw -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraintBallAndSocket.h b/tools/af/DialogAFConstraintBallAndSocket.h new file mode 100644 index 000000000..18ab1bd37 --- /dev/null +++ b/tools/af/DialogAFConstraintBallAndSocket.h @@ -0,0 +1,108 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintBallAndSocket dialog + +class DialogAFConstraintBallAndSocket : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintBallAndSocket) + +public: + DialogAFConstraintBallAndSocket(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintBallAndSocket(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_BALLANDSOCKET }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedRadioAnchorJoint(); + afx_msg void OnBnClickedRadioAnchorCoordinates(); + afx_msg void OnCbnSelchangeComboAnchorJoint(); + afx_msg void OnEnChangeEditAnchorX(); + afx_msg void OnEnChangeEditAnchorY(); + afx_msg void OnEnChangeEditAnchorZ(); + afx_msg void OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioBasLimitNone(); + afx_msg void OnBnClickedRadioBasLimitCone(); + afx_msg void OnBnClickedRadioBasLimitPyramid(); + afx_msg void OnEnChangeEditBasLimitConeAngle(); + afx_msg void OnDeltaposSpinBasLimitConeAngle(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditBasLimitPyramidAngle1(); + afx_msg void OnDeltaposSpinBasLimitPyramidAngle1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditBasLimitPyramidAngle2(); + afx_msg void OnDeltaposSpinBasLimitPyramidAngle2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditBasLimitRoll(); + afx_msg void OnDeltaposSpinBasLimitRoll(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioBasLimitBone(); + afx_msg void OnBnClickedRadioBasLimitAngles(); + afx_msg void OnCbnSelchangeComboBasLimitJoint1(); + afx_msg void OnCbnSelchangeComboBasLimitJoint2(); + afx_msg void OnEnChangeEditBasLimitPitch(); + afx_msg void OnDeltaposSpinBasLimitPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditBasLimitYaw(); + afx_msg void OnDeltaposSpinBasLimitYaw(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioBasLimitAxisBone(); + afx_msg void OnBnClickedRadioBasLimitAxisAngles(); + afx_msg void OnCbnSelchangeComboBasLimitAxisJoint1(); + afx_msg void OnCbnSelchangeComboBasLimitAxisJoint2(); + afx_msg void OnEnChangeEditBasLimitAxisPitch(); + afx_msg void OnDeltaposSpinBasLimitAxisPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditBasLimitAxisYaw(); + afx_msg void OnDeltaposSpinBasLimitAxisYaw(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintBallAndSocket) + CComboBox m_comboAnchorJoint; + float m_anchor_x; + float m_anchor_y; + float m_anchor_z; + float m_coneAngle; + float m_pyramidAngle1; + float m_pyramidAngle2; + CComboBox m_comboLimitJoint1; + CComboBox m_comboLimitJoint2; + float m_limitPitch; + float m_limitYaw; + float m_limitRoll; + CComboBox m_comboLimitAxisJoint1; + CComboBox m_comboLimitAxisJoint2; + float m_limitAxisPitch; + float m_limitAxisYaw; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFConstraintFixed.cpp b/tools/af/DialogAFConstraintFixed.cpp new file mode 100644 index 000000000..bc939ad8f --- /dev/null +++ b/tools/af/DialogAFConstraintFixed.cpp @@ -0,0 +1,160 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintFixed.h" + + +// DialogAFConstraintFixed dialog + +toolTip_t DialogAFConstraintFixed::toolTips[] = { + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintFixed, CDialog) + +/* +================ +DialogAFConstraintFixed::DialogAFConstraintFixed +================ +*/ +DialogAFConstraintFixed::DialogAFConstraintFixed(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintFixed::IDD, pParent) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_FIXED, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintFixed::~DialogAFConstraintFixed +================ +*/ +DialogAFConstraintFixed::~DialogAFConstraintFixed() { +} + +/* +================ +DialogAFConstraintFixed::DoDataExchange +================ +*/ +void DialogAFConstraintFixed::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintHinge) + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintFixed::InitJointLists +================ +*/ +void DialogAFConstraintFixed::InitJointLists( void ) { +} + +/* +================ +DialogAFConstraintFixed::LoadFile +================ +*/ +void DialogAFConstraintFixed::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintFixed::SaveFile +================ +*/ +void DialogAFConstraintFixed::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintFixed::LoadConstraint +================ +*/ +void DialogAFConstraintFixed::LoadConstraint( idDeclAF_Constraint *c ) { + + constraint = c; + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintFixed::SaveConstraint +================ +*/ +void DialogAFConstraintFixed::SaveConstraint( void ) { + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintFixed::UpdateFile +================ +*/ +void DialogAFConstraintFixed::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintFixed::OnToolHitTest +================ +*/ +int DialogAFConstraintFixed::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintFixed, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) +END_MESSAGE_MAP() + + +// DialogAFConstraintFixed message handlers + +BOOL DialogAFConstraintFixed::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} diff --git a/tools/af/DialogAFConstraintFixed.h b/tools/af/DialogAFConstraintFixed.h new file mode 100644 index 000000000..2bdc008b5 --- /dev/null +++ b/tools/af/DialogAFConstraintFixed.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintFixed dialog + +class DialogAFConstraintFixed : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintFixed) + +public: + DialogAFConstraintFixed(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintFixed(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_FIXED }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintHinge) + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFConstraintHinge.cpp b/tools/af/DialogAFConstraintHinge.cpp new file mode 100644 index 000000000..ad0838ac0 --- /dev/null +++ b/tools/af/DialogAFConstraintHinge.cpp @@ -0,0 +1,556 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintHinge.h" + + +// DialogAFConstraintHinge dialog + +toolTip_t DialogAFConstraintHinge::toolTips[] = { + { IDC_RADIO_ANCHOR_JOINT, "use the position of a joint for the anchor" }, + { IDC_COMBO_ANCHOR_JOINT, "anchor joint name" }, + { IDC_RADIO_ANCHOR_COORDINATES, "use absolute coordinates for the anchor" }, + { IDC_EDIT_ANCHOR_X, "anchor x-coordinate" }, + { IDC_EDIT_ANCHOR_Y, "anchor y-coordinate" }, + { IDC_EDIT_ANCHOR_Z, "anchor z-coordinate" }, + { IDC_RADIO_HINGE_AXIS_BONE, "use a bone for the hinge axis" }, + { IDC_RADIO_HINGE_AXIS_ANGLES, "use angles to set the orientation of the hinge axis" }, + { IDC_COMBO_HINGE_AXIS_JOINT1, "bone start joint" }, + { IDC_COMBO_HINGE_AXIS_JOINT2, "bone end joint" }, + { IDC_EDIT_HINGE_AXIS_PITCH, "pitch angle" }, + { IDC_EDIT_HINGE_AXIS_YAW, "yaw angle" }, + { IDC_RADIO_HINGE_LIMIT_NONE, "no limit" }, + { IDC_RADIO_HINGE_LIMIT_ANGLES, "angle limit" }, + { IDC_EDIT_HINGE_LIMIT_ANGLE1, "limit orientation" }, + { IDC_EDIT_HINGE_LIMIT_ANGLE2, "limit width" }, + { IDC_EDIT_HINGE_LIMIT_ANGLE3, "limit angle" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintHinge, CDialog) + +/* +================ +DialogAFConstraintHinge::DialogAFConstraintHinge +================ +*/ +DialogAFConstraintHinge::DialogAFConstraintHinge(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintHinge::IDD, pParent) + , m_anchor_x(0) + , m_anchor_y(0) + , m_anchor_z(0) + , m_axisPitch(0) + , m_axisYaw(0) + , m_limitAngle1(0) + , m_limitAngle2(30.0f) + , m_limitAngle3(0) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_HINGE, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintHinge::~DialogAFConstraintHinge +================ +*/ +DialogAFConstraintHinge::~DialogAFConstraintHinge() { +} + +/* +================ +DialogAFConstraintHinge::DoDataExchange +================ +*/ +void DialogAFConstraintHinge::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintHinge) + DDX_Control(pDX, IDC_COMBO_ANCHOR_JOINT, m_comboAnchorJoint); + DDX_Text(pDX, IDC_EDIT_ANCHOR_X, m_anchor_x); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Y, m_anchor_y); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Z, m_anchor_z); + DDX_Control(pDX, IDC_COMBO_HINGE_AXIS_JOINT1, m_comboAxisJoint1); + DDX_Control(pDX, IDC_COMBO_HINGE_AXIS_JOINT2, m_comboAxisJoint2); + DDX_Text(pDX, IDC_EDIT_HINGE_AXIS_PITCH, m_axisPitch); + DDX_Text(pDX, IDC_EDIT_HINGE_AXIS_YAW, m_axisYaw); + DDX_Text(pDX, IDC_EDIT_HINGE_LIMIT_ANGLE1, m_limitAngle1); + DDX_Text(pDX, IDC_EDIT_HINGE_LIMIT_ANGLE2, m_limitAngle2); + DDX_Text(pDX, IDC_EDIT_HINGE_LIMIT_ANGLE3, m_limitAngle3); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintHinge::InitJointLists +================ +*/ +void DialogAFConstraintHinge::InitJointLists( void ) { + m_comboAnchorJoint.ResetContent(); + m_comboAxisJoint1.ResetContent(); + m_comboAxisJoint2.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + int numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + m_comboAnchorJoint.AddString( jointName ); + m_comboAxisJoint1.AddString( jointName ); + m_comboAxisJoint2.AddString( jointName ); + } +} + +/* +================ +DialogAFConstraintHinge::LoadFile +================ +*/ +void DialogAFConstraintHinge::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintHinge::SaveFile +================ +*/ +void DialogAFConstraintHinge::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintHinge::LoadConstraint +================ +*/ +void DialogAFConstraintHinge::LoadConstraint( idDeclAF_Constraint *c ) { + int i, s1, s2; + idAngles angles; + + constraint = c; + + // load anchor from the current idDeclAF_Constraint + SetSafeComboBoxSelection( &m_comboAnchorJoint, constraint->anchor.joint1.c_str(), -1 ); + m_anchor_x = constraint->anchor.ToVec3().x; + m_anchor_y = constraint->anchor.ToVec3().y; + m_anchor_z = constraint->anchor.ToVec3().z; + if ( constraint->anchor.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ANCHOR_JOINT; + } + else { + i = IDC_RADIO_ANCHOR_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ANCHOR_JOINT, IDC_RADIO_ANCHOR_COORDINATES, i ); + + // hinge axis + s1 = SetSafeComboBoxSelection( &m_comboAxisJoint1, constraint->axis.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboAxisJoint2, constraint->axis.joint2.c_str(), s1 ); + angles = constraint->axis.ToVec3().ToAngles(); + m_axisPitch = angles.pitch; + m_axisYaw = angles.yaw; + if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_HINGE_AXIS_BONE; + } + else { + i = IDC_RADIO_HINGE_AXIS_ANGLES; + constraint->axis.type = idAFVector::VEC_COORDS; + } + CheckRadioButton( IDC_RADIO_HINGE_AXIS_BONE, IDC_RADIO_HINGE_AXIS_ANGLES, i ); + + // hinge limit + if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) { + i = IDC_RADIO_HINGE_LIMIT_ANGLES; + } + else { + i = IDC_RADIO_HINGE_LIMIT_NONE; + } + CheckRadioButton( IDC_RADIO_HINGE_LIMIT_NONE, IDC_RADIO_HINGE_LIMIT_ANGLES, i ); + m_limitAngle1 = constraint->limitAngles[0]; + m_limitAngle2 = constraint->limitAngles[1]; + m_limitAngle3 = constraint->limitAngles[2]; + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintHinge::SaveConstraint +================ +*/ +void DialogAFConstraintHinge::SaveConstraint( void ) { + int s1, s2; + CString str; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // save anchor to the current idDeclAF_Constraint + GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 ); + constraint->anchor.joint1 = str; + constraint->anchor.ToVec3().x = m_anchor_x; + constraint->anchor.ToVec3().y = m_anchor_y; + constraint->anchor.ToVec3().z = m_anchor_z; + + // hinge axis + if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) { + s1 = GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 ); + constraint->axis.joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboAxisJoint2, str, s1 ); + constraint->axis.joint2 = str; + } + else { + constraint->axis.ToVec3() = idAngles( m_axisPitch, m_axisYaw, 0.0f ).ToForward(); + } + + // hinge limit + constraint->limitAngles[0] = m_limitAngle1; + constraint->limitAngles[1] = m_limitAngle2; + constraint->limitAngles[2] = m_limitAngle3; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintHinge::UpdateFile +================ +*/ +void DialogAFConstraintHinge::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintHinge::OnToolHitTest +================ +*/ +int DialogAFConstraintHinge::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintHinge, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_JOINT, OnBnClickedRadioAnchorJoint) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_COORDINATES, OnBnClickedRadioAnchorCoordinates) + ON_CBN_SELCHANGE(IDC_COMBO_ANCHOR_JOINT, OnCbnSelchangeComboAnchorJoint) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_X, OnEnChangeEditAnchorX) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Y, OnEnChangeEditAnchorY) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Z, OnEnChangeEditAnchorZ) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_X, OnDeltaposSpinAnchorX) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Y, OnDeltaposSpinAnchorY) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Z, OnDeltaposSpinAnchorZ) + ON_BN_CLICKED(IDC_RADIO_HINGE_AXIS_BONE, OnBnClickedRadioHingeAxisBone) + ON_BN_CLICKED(IDC_RADIO_HINGE_AXIS_ANGLES, OnBnClickedRadioHingeAxisAngles) + ON_CBN_SELCHANGE(IDC_COMBO_HINGE_AXIS_JOINT1, OnCbnSelchangeComboHingeAxisJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_HINGE_AXIS_JOINT2, OnCbnSelchangeComboHingeAxisJoint2) + ON_EN_CHANGE(IDC_EDIT_HINGE_AXIS_PITCH, OnEnChangeEditHingeAxisPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HINGE_AXIS_PITCH, OnDeltaposSpinHingeAxisPitch) + ON_EN_CHANGE(IDC_EDIT_HINGE_AXIS_YAW, OnEnChangeEditHingeAxisYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HINGE_AXIS_YAW, OnDeltaposSpinHingeAxisYaw) + ON_BN_CLICKED(IDC_RADIO_HINGE_LIMIT_NONE, OnBnClickedRadioHingeLimitNone) + ON_BN_CLICKED(IDC_RADIO_HINGE_LIMIT_ANGLES, OnBnClickedRadioHingeLimitAngles) + ON_EN_CHANGE(IDC_EDIT_HINGE_LIMIT_ANGLE1, OnEnChangeEditHingeLimitAngle1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HINGE_LIMIT_ANGLE1, OnDeltaposSpinHingeLimitAngle1) + ON_EN_CHANGE(IDC_EDIT_HINGE_LIMIT_ANGLE2, OnEnChangeEditHingeLimitAngle2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HINGE_LIMIT_ANGLE2, OnDeltaposSpinHingeLimitAngle2) + ON_EN_CHANGE(IDC_EDIT_HINGE_LIMIT_ANGLE3, OnEnChangeEditHingeLimitAngle3) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HINGE_LIMIT_ANGLE3, OnDeltaposSpinHingeLimitAngle3) +END_MESSAGE_MAP() + + +// DialogAFConstraintHinge message handlers + +BOOL DialogAFConstraintHinge::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraintHinge::OnBnClickedRadioAnchorJoint() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_JOINT ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnBnClickedRadioAnchorCoordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_COORDINATES ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnCbnSelchangeComboAnchorJoint() { + UpdateFile(); +} + +void DialogAFConstraintHinge::OnEnChangeEditAnchorX() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ) ) { + UpdateFile(); + } + else { + m_anchor_x = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ); + } +} + +void DialogAFConstraintHinge::OnEnChangeEditAnchorY() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ) ) { + UpdateFile(); + } + else { + m_anchor_y = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ); + } +} + +void DialogAFConstraintHinge::OnEnChangeEditAnchorZ() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ) ) { + UpdateFile(); + } + else { + m_anchor_z = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_x += 1.0f; + } + else { + m_anchor_x -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_y += 1.0f; + } + else { + m_anchor_y -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_z += 1.0f; + } + else { + m_anchor_z -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnBnClickedRadioHingeAxisBone() { + if ( IsDlgButtonChecked( IDC_RADIO_HINGE_AXIS_BONE ) ) { + if ( constraint ) { + constraint->axis.type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnBnClickedRadioHingeAxisAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_HINGE_AXIS_ANGLES ) ) { + if ( constraint ) { + constraint->axis.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnCbnSelchangeComboHingeAxisJoint1() { + CString str; + GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboAxisJoint2, str ); + UpdateFile(); +} + +void DialogAFConstraintHinge::OnCbnSelchangeComboHingeAxisJoint2() { + CString str; + GetSafeComboBoxSelection( &m_comboAxisJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboAxisJoint1, str ); + UpdateFile(); +} + +void DialogAFConstraintHinge::OnEnChangeEditHingeAxisPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_AXIS_PITCH ) ) ) { + UpdateFile(); + } + else { + m_axisPitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_AXIS_PITCH ) ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinHingeAxisPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_axisPitch += 1.0f; + } + else { + m_axisPitch -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnEnChangeEditHingeAxisYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_AXIS_YAW ) ) ) { + UpdateFile(); + } + else { + m_axisYaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_AXIS_YAW ) ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinHingeAxisYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_axisYaw += 1.0f; + } + else { + m_axisYaw -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnBnClickedRadioHingeLimitNone() { + if ( IsDlgButtonChecked( IDC_RADIO_HINGE_LIMIT_NONE ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnBnClickedRadioHingeLimitAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_HINGE_LIMIT_ANGLES ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintHinge::OnEnChangeEditHingeLimitAngle1() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE1 ) ) ) { + UpdateFile(); + } + else { + m_limitAngle1 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE1 ) ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinHingeLimitAngle1(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitAngle1 += 1.0f; + } + else { + m_limitAngle1 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnEnChangeEditHingeLimitAngle2() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE2 ) ) ) { + UpdateFile(); + } + else { + m_limitAngle2 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE2 ), false ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinHingeLimitAngle2(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitAngle2 += 1.0f; + } + else if ( m_limitAngle2 > 0.0f ) { + m_limitAngle2 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintHinge::OnEnChangeEditHingeLimitAngle3() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE3 ) ) ) { + UpdateFile(); + } + else { + m_limitAngle3 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_HINGE_LIMIT_ANGLE3 ) ); + } +} + +void DialogAFConstraintHinge::OnDeltaposSpinHingeLimitAngle3(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitAngle3 += 1.0f; + } + else { + m_limitAngle3 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraintHinge.h b/tools/af/DialogAFConstraintHinge.h new file mode 100644 index 000000000..474b06d82 --- /dev/null +++ b/tools/af/DialogAFConstraintHinge.h @@ -0,0 +1,92 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintHinge dialog + +class DialogAFConstraintHinge : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintHinge) + +public: + DialogAFConstraintHinge(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintHinge(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_HINGE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedRadioAnchorJoint(); + afx_msg void OnBnClickedRadioAnchorCoordinates(); + afx_msg void OnCbnSelchangeComboAnchorJoint(); + afx_msg void OnEnChangeEditAnchorX(); + afx_msg void OnEnChangeEditAnchorY(); + afx_msg void OnEnChangeEditAnchorZ(); + afx_msg void OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioHingeAxisBone(); + afx_msg void OnBnClickedRadioHingeAxisAngles(); + afx_msg void OnCbnSelchangeComboHingeAxisJoint1(); + afx_msg void OnCbnSelchangeComboHingeAxisJoint2(); + afx_msg void OnEnChangeEditHingeAxisPitch(); + afx_msg void OnDeltaposSpinHingeAxisPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditHingeAxisYaw(); + afx_msg void OnDeltaposSpinHingeAxisYaw(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioHingeLimitNone(); + afx_msg void OnBnClickedRadioHingeLimitAngles(); + afx_msg void OnEnChangeEditHingeLimitAngle1(); + afx_msg void OnDeltaposSpinHingeLimitAngle1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditHingeLimitAngle2(); + afx_msg void OnDeltaposSpinHingeLimitAngle2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditHingeLimitAngle3(); + afx_msg void OnDeltaposSpinHingeLimitAngle3(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintHinge) + CComboBox m_comboAnchorJoint; + float m_anchor_x; + float m_anchor_y; + float m_anchor_z; + CComboBox m_comboAxisJoint1; + CComboBox m_comboAxisJoint2; + float m_axisPitch; + float m_axisYaw; + float m_limitAngle1; + float m_limitAngle2; + float m_limitAngle3; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFConstraintSlider.cpp b/tools/af/DialogAFConstraintSlider.cpp new file mode 100644 index 000000000..77bf01ec7 --- /dev/null +++ b/tools/af/DialogAFConstraintSlider.cpp @@ -0,0 +1,304 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintSlider.h" + + +// DialogAFConstraintSlider dialog + +toolTip_t DialogAFConstraintSlider::toolTips[] = { + { IDC_RADIO_SLIDER_AXIS_BONE, "use a bone for the slider axis" }, + { IDC_RADIO_SLIDER_AXIS_ANGLES, "use angles to set the orientation of the slider axis" }, + { IDC_COMBO_SLIDER_AXIS_JOINT1, "bone start joint" }, + { IDC_COMBO_SLIDER_AXIS_JOINT2, "bone end joint" }, + { IDC_EDIT_SLIDER_AXIS_PITCH, "pitch angle" }, + { IDC_EDIT_SLIDER_AXIS_YAW, "yaw angle" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintSlider, CDialog) + +/* +================ +DialogAFConstraintSlider::DialogAFConstraintSlider +================ +*/ +DialogAFConstraintSlider::DialogAFConstraintSlider(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintSlider::IDD, pParent) + , m_axisPitch(0) + , m_axisYaw(0) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_SLIDER, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintSlider::~DialogAFConstraintSlider +================ +*/ +DialogAFConstraintSlider::~DialogAFConstraintSlider() { +} + +/* +================ +DialogAFConstraintSlider::DoDataExchange +================ +*/ +void DialogAFConstraintSlider::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintSlider) + DDX_Control(pDX, IDC_COMBO_SLIDER_AXIS_JOINT1, m_comboAxisJoint1); + DDX_Control(pDX, IDC_COMBO_SLIDER_AXIS_JOINT2, m_comboAxisJoint2); + DDX_Text(pDX, IDC_EDIT_SLIDER_AXIS_PITCH, m_axisPitch); + DDX_Text(pDX, IDC_EDIT_SLIDER_AXIS_YAW, m_axisYaw); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintSlider::InitJointLists +================ +*/ +void DialogAFConstraintSlider::InitJointLists( void ) { + m_comboAxisJoint1.ResetContent(); + m_comboAxisJoint2.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + int numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + m_comboAxisJoint1.AddString( jointName ); + m_comboAxisJoint2.AddString( jointName ); + } +} + +/* +================ +DialogAFConstraintSlider::LoadFile +================ +*/ +void DialogAFConstraintSlider::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintSlider::SaveFile +================ +*/ +void DialogAFConstraintSlider::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintSlider::LoadConstraint +================ +*/ +void DialogAFConstraintSlider::LoadConstraint( idDeclAF_Constraint *c ) { + int i, s1, s2; + idAngles angles; + + constraint = c; + + // slider axis + s1 = SetSafeComboBoxSelection( &m_comboAxisJoint1, constraint->axis.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboAxisJoint2, constraint->axis.joint2.c_str(), s1 ); + angles = constraint->axis.ToVec3().ToAngles(); + m_axisPitch = angles.pitch; + m_axisYaw = angles.yaw; + if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_SLIDER_AXIS_BONE; + } + else { + i = IDC_RADIO_SLIDER_AXIS_ANGLES; + constraint->axis.type = idAFVector::VEC_COORDS; + } + CheckRadioButton( IDC_RADIO_SLIDER_AXIS_BONE, IDC_RADIO_SLIDER_AXIS_ANGLES, i ); + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintSlider::SaveConstraint +================ +*/ +void DialogAFConstraintSlider::SaveConstraint( void ) { + int s1, s2; + CString str; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // slider axis + if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) { + s1 = GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 ); + constraint->axis.joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboAxisJoint2, str, s1 ); + constraint->axis.joint2 = str; + } + else { + constraint->axis.ToVec3() = idAngles( m_axisPitch, m_axisYaw, 0.0f ).ToForward(); + } + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintSlider::UpdateFile +================ +*/ +void DialogAFConstraintSlider::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintSlider::OnToolHitTest +================ +*/ +int DialogAFConstraintSlider::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintSlider, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_RADIO_SLIDER_AXIS_BONE, OnBnClickedRadioSliderAxisBone) + ON_BN_CLICKED(IDC_RADIO_SLIDER_AXIS_ANGLES, OnBnClickedRadioSliderAxisAngles) + ON_CBN_SELCHANGE(IDC_COMBO_SLIDER_AXIS_JOINT1, OnCbnSelchangeComboSliderAxisJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_SLIDER_AXIS_JOINT2, OnCbnSelchangeComboSliderAxisJoint2) + ON_EN_CHANGE(IDC_EDIT_SLIDER_AXIS_PITCH, OnEnChangeEditSliderAxisPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SLIDER_AXIS_PITCH, OnDeltaposSpinSliderAxisPitch) + ON_EN_CHANGE(IDC_EDIT_SLIDER_AXIS_YAW, OnEnChangeEditSliderAxisYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SLIDER_AXIS_YAW, OnDeltaposSpinSliderAxisYaw) +END_MESSAGE_MAP() + + +// DialogAFConstraintSlider message handlers + +BOOL DialogAFConstraintSlider::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraintSlider::OnBnClickedRadioSliderAxisBone() { + if ( IsDlgButtonChecked( IDC_RADIO_SLIDER_AXIS_BONE ) ) { + if ( constraint ) { + constraint->axis.type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintSlider::OnBnClickedRadioSliderAxisAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_SLIDER_AXIS_ANGLES ) ) { + if ( constraint ) { + constraint->axis.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintSlider::OnCbnSelchangeComboSliderAxisJoint1() { + CString str; + GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboAxisJoint2, str ); + UpdateFile(); +} + +void DialogAFConstraintSlider::OnCbnSelchangeComboSliderAxisJoint2() { + CString str; + GetSafeComboBoxSelection( &m_comboAxisJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboAxisJoint1, str ); + UpdateFile(); +} + +void DialogAFConstraintSlider::OnEnChangeEditSliderAxisPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SLIDER_AXIS_PITCH ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SLIDER_AXIS_PITCH ) ); + } +} + +void DialogAFConstraintSlider::OnDeltaposSpinSliderAxisPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_axisPitch += 1.0f; + } + else { + m_axisPitch -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSlider::OnEnChangeEditSliderAxisYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SLIDER_AXIS_YAW ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SLIDER_AXIS_YAW ) ); + } +} + +void DialogAFConstraintSlider::OnDeltaposSpinSliderAxisYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_axisYaw += 1.0f; + } + else { + m_axisYaw -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraintSlider.h b/tools/af/DialogAFConstraintSlider.h new file mode 100644 index 000000000..0448ab23a --- /dev/null +++ b/tools/af/DialogAFConstraintSlider.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintSlider dialog + +class DialogAFConstraintSlider : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintSlider) + +public: + DialogAFConstraintSlider(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintSlider(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_HINGE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedRadioSliderAxisBone(); + afx_msg void OnBnClickedRadioSliderAxisAngles(); + afx_msg void OnCbnSelchangeComboSliderAxisJoint1(); + afx_msg void OnCbnSelchangeComboSliderAxisJoint2(); + afx_msg void OnEnChangeEditSliderAxisPitch(); + afx_msg void OnDeltaposSpinSliderAxisPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditSliderAxisYaw(); + afx_msg void OnDeltaposSpinSliderAxisYaw(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintSlider) + CComboBox m_comboAxisJoint1; + CComboBox m_comboAxisJoint2; + float m_axisPitch; + float m_axisYaw; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFConstraintSpring.cpp b/tools/af/DialogAFConstraintSpring.cpp new file mode 100644 index 000000000..07599f0d0 --- /dev/null +++ b/tools/af/DialogAFConstraintSpring.cpp @@ -0,0 +1,653 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintSpring.h" + + +// DialogAFConstraintSpring dialog + +toolTip_t DialogAFConstraintSpring::toolTips[] = { + { IDC_RADIO_ANCHOR_JOINT, "use the position of a joint for the first anchor" }, + { IDC_COMBO_ANCHOR_JOINT, "first anchor joint name" }, + { IDC_RADIO_ANCHOR_COORDINATES, "use absolute coordinates for the first anchor" }, + { IDC_EDIT_ANCHOR_X, "first anchor x-coordinate" }, + { IDC_EDIT_ANCHOR_Y, "first anchor y-coordinate" }, + { IDC_EDIT_ANCHOR_Z, "first anchor z-coordinate" }, + { IDC_RADIO_ANCHOR2_JOINT, "use the position of a joint for the second anchor" }, + { IDC_COMBO_ANCHOR2_JOINT, "second anchor joint name" }, + { IDC_RADIO_ANCHOR2_COORDINATES, "use absolute coordinates for the second anchor" }, + { IDC_EDIT_ANCHOR2_X, "second anchor x-coordinate" }, + { IDC_EDIT_ANCHOR2_Y, "second anchor y-coordinate" }, + { IDC_EDIT_ANCHOR2_Z, "second anchor z-coordinate" }, + { IDC_EDIT_SPRING_STRETCH, "spring constant when stretched" }, + { IDC_EDIT_SPRING_COMPRESS, "spring constant when compressed" }, + { IDC_EDIT_SPRING_DAMPING, "spring damping" }, + { IDC_EDIT_SPRING_REST_LENGTH, "rest length" }, + { IDC_RADIO_SPRING_NO_MIN_LENGTH, "no minimum length" }, + { IDC_RADIO_SPRING_MIN_LENGTH, "minimum length" }, + { IDC_EDIT_SPRING_MIN_LENGTH, "minimum length" }, + { IDC_RADIO_SPRING_NO_MAX_LENGTH, "no maximum length" }, + { IDC_RADIO_SPRING_MAX_LENGTH, "maximum length" }, + { IDC_EDIT_SPRING_MAX_LENGTH, "maximum length" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintSpring, CDialog) + +/* +================ +DialogAFConstraintSpring::DialogAFConstraintSpring +================ +*/ +DialogAFConstraintSpring::DialogAFConstraintSpring(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintSpring::IDD, pParent) + , m_anchor_x(0) + , m_anchor_y(0) + , m_anchor_z(0) + , m_anchor2_x(0) + , m_anchor2_y(0) + , m_anchor2_z(0) + , m_stretch(0) + , m_compress(0) + , m_damping(0) + , m_restLength(0) + , m_minLength(0) + , m_maxLength(0) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_SPRING, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintSpring::~DialogAFConstraintSpring +================ +*/ +DialogAFConstraintSpring::~DialogAFConstraintSpring() { +} + +/* +================ +DialogAFConstraintSpring::DoDataExchange +================ +*/ +void DialogAFConstraintSpring::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintSpring) + DDX_Control(pDX, IDC_COMBO_ANCHOR_JOINT, m_comboAnchorJoint); + DDX_Control(pDX, IDC_COMBO_ANCHOR2_JOINT, m_comboAnchor2Joint); + DDX_Text(pDX, IDC_EDIT_ANCHOR_X, m_anchor_x); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Y, m_anchor_y); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Z, m_anchor_z); + DDX_Text(pDX, IDC_EDIT_ANCHOR2_X, m_anchor2_x); + DDX_Text(pDX, IDC_EDIT_ANCHOR2_Y, m_anchor2_y); + DDX_Text(pDX, IDC_EDIT_ANCHOR2_Z, m_anchor2_z); + DDX_Text(pDX, IDC_EDIT_SPRING_STRETCH, m_stretch); + DDX_Text(pDX, IDC_EDIT_SPRING_COMPRESS, m_compress); + DDX_Text(pDX, IDC_EDIT_SPRING_DAMPING, m_damping); + DDX_Text(pDX, IDC_EDIT_SPRING_REST_LENGTH, m_restLength); + DDX_Text(pDX, IDC_EDIT_SPRING_MIN_LENGTH, m_minLength); + DDX_Text(pDX, IDC_EDIT_SPRING_MAX_LENGTH, m_maxLength); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintSpring::InitJointLists +================ +*/ +void DialogAFConstraintSpring::InitJointLists( void ) { + m_comboAnchorJoint.ResetContent(); + m_comboAnchor2Joint.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + int numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + m_comboAnchorJoint.AddString( jointName ); + m_comboAnchor2Joint.AddString( jointName ); + } +} + +/* +================ +DialogAFConstraintSpring::LoadFile +================ +*/ +void DialogAFConstraintSpring::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintSpring::SaveFile +================ +*/ +void DialogAFConstraintSpring::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintSpring::LoadConstraint +================ +*/ +void DialogAFConstraintSpring::LoadConstraint( idDeclAF_Constraint *c ) { + int i; + + constraint = c; + + // load first anchor from the current idDeclAF_Constraint + SetSafeComboBoxSelection( &m_comboAnchorJoint, constraint->anchor.joint1.c_str(), -1 ); + m_anchor_x = constraint->anchor.ToVec3().x; + m_anchor_y = constraint->anchor.ToVec3().y; + m_anchor_z = constraint->anchor.ToVec3().z; + if ( constraint->anchor.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ANCHOR_JOINT; + } + else { + i = IDC_RADIO_ANCHOR_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ANCHOR_JOINT, IDC_RADIO_ANCHOR_COORDINATES, i ); + + // load second anchor from the current idDeclAF_Constraint + SetSafeComboBoxSelection( &m_comboAnchor2Joint, constraint->anchor2.joint1.c_str(), -1 ); + m_anchor2_x = constraint->anchor2.ToVec3().x; + m_anchor2_y = constraint->anchor2.ToVec3().y; + m_anchor2_z = constraint->anchor2.ToVec3().z; + if ( constraint->anchor2.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ANCHOR2_JOINT; + } + else { + i = IDC_RADIO_ANCHOR2_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ANCHOR2_JOINT, IDC_RADIO_ANCHOR2_COORDINATES, i ); + + // spring settings + m_stretch = constraint->stretch; + m_compress = constraint->compress; + m_damping = constraint->damping; + m_restLength = constraint->restLength; + + // spring limits + if ( constraint->minLength > 0.0f ) { + i = IDC_RADIO_SPRING_MIN_LENGTH; + } + else { + i = IDC_RADIO_SPRING_NO_MIN_LENGTH; + } + CheckRadioButton( IDC_RADIO_SPRING_NO_MIN_LENGTH, IDC_RADIO_SPRING_MIN_LENGTH, i ); + m_minLength = constraint->minLength; + + if ( constraint->maxLength > 0.0f ) { + i = IDC_RADIO_SPRING_MAX_LENGTH; + } + else { + i = IDC_RADIO_SPRING_NO_MAX_LENGTH; + } + CheckRadioButton( IDC_RADIO_SPRING_NO_MAX_LENGTH, IDC_RADIO_SPRING_MAX_LENGTH, i ); + m_maxLength = constraint->maxLength; + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintSpring::SaveConstraint +================ +*/ +void DialogAFConstraintSpring::SaveConstraint( void ) { + CString str; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // save first anchor to the current idDeclAF_Constraint + GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 ); + constraint->anchor.joint1 = str; + constraint->anchor.ToVec3().x = m_anchor_x; + constraint->anchor.ToVec3().y = m_anchor_y; + constraint->anchor.ToVec3().z = m_anchor_z; + + // save second anchor to the current idDeclAF_Constraint + GetSafeComboBoxSelection( &m_comboAnchor2Joint, str, -1 ); + constraint->anchor2.joint1 = str; + constraint->anchor2.ToVec3().x = m_anchor2_x; + constraint->anchor2.ToVec3().y = m_anchor2_y; + constraint->anchor2.ToVec3().z = m_anchor2_z; + + // spring settings + constraint->stretch = m_stretch; + constraint->compress = m_compress; + constraint->damping = m_damping; + constraint->restLength = m_restLength; + + // spring limits + constraint->minLength = m_minLength; + constraint->maxLength = m_maxLength; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintSpring::UpdateFile +================ +*/ +void DialogAFConstraintSpring::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintSpring::OnToolHitTest +================ +*/ +int DialogAFConstraintSpring::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintSpring, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_JOINT, OnBnClickedRadioAnchorJoint) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_COORDINATES, OnBnClickedRadioAnchorCoordinates) + ON_CBN_SELCHANGE(IDC_COMBO_ANCHOR_JOINT, OnCbnSelchangeComboAnchorJoint) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_X, OnEnChangeEditAnchorX) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Y, OnEnChangeEditAnchorY) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Z, OnEnChangeEditAnchorZ) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_X, OnDeltaposSpinAnchorX) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Y, OnDeltaposSpinAnchorY) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Z, OnDeltaposSpinAnchorZ) + ON_BN_CLICKED(IDC_RADIO_ANCHOR2_JOINT, OnBnClickedRadioAnchor2Joint) + ON_BN_CLICKED(IDC_RADIO_ANCHOR2_COORDINATES, OnBnClickedRadioAnchor2Coordinates) + ON_CBN_SELCHANGE(IDC_COMBO_ANCHOR2_JOINT, OnCbnSelchangeComboAnchor2Joint) + ON_EN_CHANGE(IDC_EDIT_ANCHOR2_X, OnEnChangeEditAnchor2X) + ON_EN_CHANGE(IDC_EDIT_ANCHOR2_Y, OnEnChangeEditAnchor2Y) + ON_EN_CHANGE(IDC_EDIT_ANCHOR2_Z, OnEnChangeEditAnchor2Z) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR2_X, OnDeltaposSpinAnchor2X) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR2_Y, OnDeltaposSpinAnchor2Y) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR2_Z, OnDeltaposSpinAnchor2Z) + ON_EN_CHANGE(IDC_EDIT_SPRING_STRETCH, OnEnChangeEditSpringStretch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_STRETCH, OnDeltaposSpinSpringStretch) + ON_EN_CHANGE(IDC_EDIT_SPRING_COMPRESS, OnEnChangeEditSpringCompress) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_COMPRESS, OnDeltaposSpinSpringCompress) + ON_EN_CHANGE(IDC_EDIT_SPRING_DAMPING, OnEnChangeEditSpringDamping) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_DAMPING, OnDeltaposSpinSpringDamping) + ON_EN_CHANGE(IDC_EDIT_SPRING_REST_LENGTH, OnEnChangeEditSpringRestLength) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_REST_LENGTH, OnDeltaposSpinSpringRestLength) + ON_BN_CLICKED(IDC_RADIO_SPRING_NO_MIN_LENGTH, OnBnClickedRadioLimitNoMinLength) + ON_BN_CLICKED(IDC_RADIO_SPRING_MIN_LENGTH, OnBnClickedRadioLimitMinLength) + ON_EN_CHANGE(IDC_EDIT_SPRING_MIN_LENGTH, OnEnChangeEditLimitMinLength) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_MIN_LENGTH, OnDeltaposSpinLimitMinLength) + ON_BN_CLICKED(IDC_RADIO_SPRING_NO_MAX_LENGTH, OnBnClickedRadioLimitNoMaxLength) + ON_BN_CLICKED(IDC_RADIO_SPRING_MAX_LENGTH, OnBnClickedRadioLimitMaxLength) + ON_EN_CHANGE(IDC_EDIT_SPRING_MAX_LENGTH, OnEnChangeEditLimitMaxLength) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPRING_MAX_LENGTH, OnDeltaposSpinLimitMaxLength) +END_MESSAGE_MAP() + + +// DialogAFConstraintSpring message handlers + +BOOL DialogAFConstraintSpring::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraintSpring::OnBnClickedRadioAnchorJoint() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_JOINT ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnBnClickedRadioAnchorCoordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_COORDINATES ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnCbnSelchangeComboAnchorJoint() { + UpdateFile(); +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchorX() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ); + } +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchorY() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ); + } +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchorZ() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_x += 1.0f; + } + else { + m_anchor_x -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_y += 1.0f; + } + else { + m_anchor_y -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_z += 1.0f; + } + else { + m_anchor_z -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnBnClickedRadioAnchor2Joint() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR2_JOINT ) ) { + if ( constraint ) { + constraint->anchor2.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnBnClickedRadioAnchor2Coordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR2_COORDINATES ) ) { + if ( constraint ) { + constraint->anchor2.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnCbnSelchangeComboAnchor2Joint() { + UpdateFile(); +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchor2X() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_X ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_X ) ); + } +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchor2Y() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_Y ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_Y ) ); + } +} + +void DialogAFConstraintSpring::OnEnChangeEditAnchor2Z() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_Z ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR2_Z ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchor2X(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor2_x += 1.0f; + } + else { + m_anchor2_x -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchor2Y(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor2_y += 1.0f; + } + else { + m_anchor2_y -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnDeltaposSpinAnchor2Z(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor2_z += 1.0f; + } + else { + m_anchor2_z -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnEnChangeEditSpringStretch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_STRETCH ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_STRETCH ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinSpringStretch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_stretch = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_SPRING_STRETCH ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnEnChangeEditSpringCompress() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_COMPRESS ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_COMPRESS ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinSpringCompress(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_compress = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_SPRING_COMPRESS ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnEnChangeEditSpringDamping() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_DAMPING ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_DAMPING ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinSpringDamping(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_damping = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_SPRING_DAMPING ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnEnChangeEditSpringRestLength() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_REST_LENGTH ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_REST_LENGTH ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinSpringRestLength(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_restLength += 1.0f; + } + else { + m_restLength -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnBnClickedRadioLimitNoMinLength() { + if ( IsDlgButtonChecked( IDC_RADIO_SPRING_NO_MIN_LENGTH ) ) { + if ( constraint ) { + constraint->minLength = 0.0f; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnBnClickedRadioLimitMinLength() { + // do nothing +} + +void DialogAFConstraintSpring::OnEnChangeEditLimitMinLength() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_MIN_LENGTH ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_MIN_LENGTH ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinLimitMinLength(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_minLength += 1.0f; + } + else { + m_minLength -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintSpring::OnBnClickedRadioLimitNoMaxLength() { + if ( IsDlgButtonChecked( IDC_RADIO_SPRING_NO_MAX_LENGTH ) ) { + if ( constraint ) { + constraint->maxLength = 0.0f; + UpdateFile(); + } + } +} + +void DialogAFConstraintSpring::OnBnClickedRadioLimitMaxLength() { + // do nothing +} + +void DialogAFConstraintSpring::OnEnChangeEditLimitMaxLength() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_MAX_LENGTH ) ) ) { + UpdateFile(); + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_SPRING_MAX_LENGTH ) ); + } +} + +void DialogAFConstraintSpring::OnDeltaposSpinLimitMaxLength(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_maxLength += 1.0f; + } + else { + m_maxLength -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraintSpring.h b/tools/af/DialogAFConstraintSpring.h new file mode 100644 index 000000000..68da83527 --- /dev/null +++ b/tools/af/DialogAFConstraintSpring.h @@ -0,0 +1,104 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintSpring dialog + +class DialogAFConstraintSpring : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintSpring) + +public: + DialogAFConstraintSpring(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintSpring(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_HINGE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedRadioAnchorJoint(); + afx_msg void OnBnClickedRadioAnchorCoordinates(); + afx_msg void OnCbnSelchangeComboAnchorJoint(); + afx_msg void OnEnChangeEditAnchorX(); + afx_msg void OnEnChangeEditAnchorY(); + afx_msg void OnEnChangeEditAnchorZ(); + afx_msg void OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioAnchor2Joint(); + afx_msg void OnBnClickedRadioAnchor2Coordinates(); + afx_msg void OnCbnSelchangeComboAnchor2Joint(); + afx_msg void OnEnChangeEditAnchor2X(); + afx_msg void OnEnChangeEditAnchor2Y(); + afx_msg void OnEnChangeEditAnchor2Z(); + afx_msg void OnDeltaposSpinAnchor2X(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchor2Y(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchor2Z(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditSpringStretch(); + afx_msg void OnDeltaposSpinSpringStretch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditSpringCompress(); + afx_msg void OnDeltaposSpinSpringCompress(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditSpringDamping(); + afx_msg void OnDeltaposSpinSpringDamping(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditSpringRestLength(); + afx_msg void OnDeltaposSpinSpringRestLength(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioLimitNoMinLength(); + afx_msg void OnBnClickedRadioLimitMinLength(); + afx_msg void OnEnChangeEditLimitMinLength(); + afx_msg void OnDeltaposSpinLimitMinLength(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioLimitNoMaxLength(); + afx_msg void OnBnClickedRadioLimitMaxLength(); + afx_msg void OnEnChangeEditLimitMaxLength(); + afx_msg void OnDeltaposSpinLimitMaxLength(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintSpring) + CComboBox m_comboAnchorJoint; + float m_anchor_x; + float m_anchor_y; + float m_anchor_z; + CComboBox m_comboAnchor2Joint; + float m_anchor2_x; + float m_anchor2_y; + float m_anchor2_z; + float m_stretch; + float m_compress; + float m_damping; + float m_restLength; + float m_minLength; + float m_maxLength; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFConstraintUniversal.cpp b/tools/af/DialogAFConstraintUniversal.cpp new file mode 100644 index 000000000..eb456049d --- /dev/null +++ b/tools/af/DialogAFConstraintUniversal.cpp @@ -0,0 +1,854 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFConstraint.h" +#include "DialogAFConstraintUniversal.h" + + +// DialogAFConstraintUniversal dialog + +toolTip_t DialogAFConstraintUniversal::toolTips[] = { + { IDC_RADIO_ANCHOR_JOINT, "use the position of a joint for the anchor" }, + { IDC_COMBO_ANCHOR_JOINT, "anchor joint name" }, + { IDC_RADIO_ANCHOR_COORDINATES, "use absolute coordinates for the anchor" }, + { IDC_EDIT_ANCHOR_X, "anchor x-coordinate" }, + { IDC_EDIT_ANCHOR_Y, "anchor y-coordinate" }, + { IDC_EDIT_ANCHOR_Z, "anchor z-coordinate" }, + { IDC_RADIO_UNIVERSAL_BONE_SHAFT1, "use a bone for the first shaft" }, + { IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1, "use angles to set the orientation of the first shaft" }, + { IDC_COMBO_UNIVERSAL_JOINT1_SHAFT1, "bone start joint" }, + { IDC_COMBO_UNIVERSAL_JOINT2_SHAFT1, "bone end joint" }, + { IDC_EDIT_UNIVERSAL_PITCH_SHAFT1, "pitch angle" }, + { IDC_EDIT_UNIVERSAL_YAW_SHAFT1, "yaw angle" }, + { IDC_RADIO_UNIVERSAL_BONE_SHAFT2, "use a bone for the second shaft" }, + { IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2, "use angles to set the orientation of the second shaft" }, + { IDC_COMBO_UNIVERSAL_JOINT1_SHAFT2, "bone start joint" }, + { IDC_COMBO_UNIVERSAL_JOINT2_SHAFT2, "bone end joint" }, + { IDC_EDIT_UNIVERSAL_PITCH_SHAFT2, "pitch angle" }, + { IDC_EDIT_UNIVERSAL_YAW_SHAFT2, "yaw angle" }, + { IDC_RADIO_UNIVERSAL_LIMIT_NONE, "no joint limit" }, + { IDC_RADIO_UNIVERSAL_LIMIT_CONE, "cone shaped joint limit" }, + { IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID, "pyramid shaped joint limit" }, + { IDC_RADIO_UNIVERSAL_LIMIT_BONE, "use a bone for the limit orientation" }, + { IDC_RADIO_UNIVERSAL_LIMIT_ANGLES, "use angles for the limit orientation" }, + { IDC_COMBO_UNIVERSAL_LIMIT_JOINT1, "bone start joint" }, + { IDC_COMBO_UNIVERSAL_LIMIT_JOINT2, "bone end joint" }, + { IDC_EDIT_UNIVERSAL_LIMIT_PITCH, "pitch angle" }, + { IDC_EDIT_UNIVERSAL_LIMIT_YAW, "yaw angle" }, + { IDC_EDIT_UNIVERSAL_LIMIT_ROLL, "roll angle" }, + { IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE, "cone angle" }, + { IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1, "first pyramid angle" }, + { IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2, "second pyramid angle" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFConstraintUniversal, CDialog) + +/* +================ +DialogAFConstraintUniversal::DialogAFConstraintUniversal +================ +*/ +DialogAFConstraintUniversal::DialogAFConstraintUniversal(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFConstraintUniversal::IDD, pParent) + , m_anchor_x(0) + , m_anchor_y(0) + , m_anchor_z(0) + , m_pitchShaft1(0) + , m_yawShaft1(0) + , m_pitchShaft2(0) + , m_yawShaft2(0) + , m_coneAngle(30.0f) + , m_pyramidAngle1(30.0f) + , m_pyramidAngle2(30.0f) + , m_limitPitch(0) + , m_limitYaw(0) + , m_limitRoll(0) + , constraint(NULL) + , file(NULL) +{ + Create( IDD_DIALOG_AF_CONSTRAINT_UNIVERSAL, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFConstraintUniversal::~DialogAFConstraintUniversal +================ +*/ +DialogAFConstraintUniversal::~DialogAFConstraintUniversal() { +} + +/* +================ +DialogAFConstraintUniversal::DoDataExchange +================ +*/ +void DialogAFConstraintUniversal::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFConstraintUniversal) + DDX_Control(pDX, IDC_COMBO_ANCHOR_JOINT, m_comboAnchorJoint); + DDX_Text(pDX, IDC_EDIT_ANCHOR_X, m_anchor_x); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Y, m_anchor_y); + DDX_Text(pDX, IDC_EDIT_ANCHOR_Z, m_anchor_z); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_JOINT1_SHAFT1, m_comboJoint1Shaft1); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_JOINT2_SHAFT1, m_comboJoint2Shaft1); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_PITCH_SHAFT1, m_pitchShaft1); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_YAW_SHAFT1, m_yawShaft1); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_JOINT1_SHAFT2, m_comboJoint1Shaft2); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_JOINT2_SHAFT2, m_comboJoint2Shaft2); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_PITCH_SHAFT2, m_pitchShaft2); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_YAW_SHAFT2, m_yawShaft2); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE, m_coneAngle); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1, m_pyramidAngle1); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2, m_pyramidAngle2); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_LIMIT_JOINT1, m_comboLimitJoint1); + DDX_Control(pDX, IDC_COMBO_UNIVERSAL_LIMIT_JOINT2, m_comboLimitJoint2); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_PITCH, m_limitPitch); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_YAW, m_limitYaw); + DDX_Text(pDX, IDC_EDIT_UNIVERSAL_LIMIT_ROLL, m_limitRoll); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFConstraintUniversal::InitJointLists +================ +*/ +void DialogAFConstraintUniversal::InitJointLists( void ) { + m_comboAnchorJoint.ResetContent(); + m_comboJoint1Shaft1.ResetContent(); + m_comboJoint2Shaft1.ResetContent(); + m_comboJoint1Shaft2.ResetContent(); + m_comboJoint2Shaft2.ResetContent(); + m_comboLimitJoint1.ResetContent(); + m_comboLimitJoint2.ResetContent(); + + if ( !file ) { + return; + } + + const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model ); + if ( !model ) { + return; + } + + int numJoints = model->NumJoints(); + for ( int i = 0; i < numJoints; i++ ) { + const char *jointName = model->GetJointName( (jointHandle_t) i ); + m_comboAnchorJoint.AddString( jointName ); + m_comboJoint1Shaft1.AddString( jointName ); + m_comboJoint2Shaft1.AddString( jointName ); + m_comboJoint1Shaft2.AddString( jointName ); + m_comboJoint2Shaft2.AddString( jointName ); + m_comboLimitJoint1.AddString( jointName ); + m_comboLimitJoint2.AddString( jointName ); + } +} + +/* +================ +DialogAFConstraintUniversal::LoadFile +================ +*/ +void DialogAFConstraintUniversal::LoadFile( idDeclAF *af ) { + file = af; + constraint = NULL; + InitJointLists(); +} + +/* +================ +DialogAFConstraintUniversal::SaveFile +================ +*/ +void DialogAFConstraintUniversal::SaveFile( void ) { + SaveConstraint(); +} + +/* +================ +DialogAFConstraintUniversal::LoadConstraint +================ +*/ +void DialogAFConstraintUniversal::LoadConstraint( idDeclAF_Constraint *c ) { + int i, s1, s2; + idAngles angles; + idMat3 mat; + + constraint = c; + + // anchor + SetSafeComboBoxSelection( &m_comboAnchorJoint, constraint->anchor.joint1.c_str(), -1 ); + m_anchor_x = constraint->anchor.ToVec3().x; + m_anchor_y = constraint->anchor.ToVec3().y; + m_anchor_z = constraint->anchor.ToVec3().z; + if ( constraint->anchor.type == idAFVector::VEC_JOINT ) { + i = IDC_RADIO_ANCHOR_JOINT; + } + else { + i = IDC_RADIO_ANCHOR_COORDINATES; + } + CheckRadioButton( IDC_RADIO_ANCHOR_JOINT, IDC_RADIO_ANCHOR_COORDINATES, i ); + + // shaft 1 + s1 = SetSafeComboBoxSelection( &m_comboJoint1Shaft1, constraint->shaft[0].joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboJoint2Shaft1, constraint->shaft[0].joint2.c_str(), s1 ); + angles = constraint->shaft[0].ToVec3().ToAngles(); + m_pitchShaft1 = angles.pitch; + m_yawShaft1 = angles.yaw; + if ( constraint->shaft[0].type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_UNIVERSAL_BONE_SHAFT1; + } + else { + i = IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1; + constraint->shaft[0].type = idAFVector::VEC_COORDS; + } + CheckRadioButton( IDC_RADIO_UNIVERSAL_BONE_SHAFT1, IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1, i ); + + // shaft 2 + s1 = SetSafeComboBoxSelection( &m_comboJoint1Shaft2, constraint->shaft[1].joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboJoint2Shaft2, constraint->shaft[1].joint2.c_str(), s1 ); + angles = constraint->shaft[1].ToVec3().ToAngles(); + m_pitchShaft2 = angles.pitch; + m_yawShaft2 = angles.yaw; + if ( constraint->shaft[1].type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_UNIVERSAL_BONE_SHAFT2; + } + else { + i = IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2; + constraint->shaft[1].type = idAFVector::VEC_COORDS; + } + CheckRadioButton( IDC_RADIO_UNIVERSAL_BONE_SHAFT2, IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2, i ); + + // limit + if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) { + i = IDC_RADIO_UNIVERSAL_LIMIT_CONE; + } + else if ( constraint->limit == idDeclAF_Constraint::LIMIT_PYRAMID ) { + i = IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID; + } + else { + i = IDC_RADIO_UNIVERSAL_LIMIT_NONE; + } + CheckRadioButton( IDC_RADIO_UNIVERSAL_LIMIT_NONE, IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID, i ); + + m_coneAngle = constraint->limitAngles[0]; + m_pyramidAngle1 = constraint->limitAngles[0]; + m_pyramidAngle2 = constraint->limitAngles[1]; + m_limitRoll = constraint->limitAngles[2]; + angles = constraint->limitAxis.ToVec3().ToAngles(); + m_limitPitch = angles.pitch; + m_limitYaw = angles.yaw; + + if ( constraint->limitAxis.type == idAFVector::VEC_BONEDIR ) { + i = IDC_RADIO_UNIVERSAL_LIMIT_BONE; + } + else { + i = IDC_RADIO_UNIVERSAL_LIMIT_ANGLES; + } + CheckRadioButton( IDC_RADIO_UNIVERSAL_LIMIT_BONE, IDC_RADIO_UNIVERSAL_LIMIT_ANGLES, i ); + s1 = SetSafeComboBoxSelection( &m_comboLimitJoint1, constraint->limitAxis.joint1.c_str(), -1 ); + s2 = SetSafeComboBoxSelection( &m_comboLimitJoint2, constraint->limitAxis.joint2.c_str(), s1 ); + + // update displayed values + UpdateData( FALSE ); +} + +/* +================ +DialogAFConstraintUniversal::SaveConstraint +================ +*/ +void DialogAFConstraintUniversal::SaveConstraint( void ) { + int s1, s2; + CString str; + idAngles angles; + idMat3 mat; + + if ( !file || !constraint ) { + return; + } + UpdateData( TRUE ); + + // anchor + GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 ); + constraint->anchor.joint1 = str; + constraint->anchor.ToVec3().x = m_anchor_x; + constraint->anchor.ToVec3().y = m_anchor_y; + constraint->anchor.ToVec3().z = m_anchor_z; + + // shaft 1 + if ( constraint->shaft[0].type == idAFVector::VEC_BONEDIR ) { + s1 = GetSafeComboBoxSelection( &m_comboJoint1Shaft1, str, -1 ); + constraint->shaft[0].joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboJoint2Shaft1, str, s1 ); + constraint->shaft[0].joint2 = str; + } + else { + constraint->shaft[0].ToVec3() = idAngles( m_pitchShaft1, m_yawShaft1, 0.0f ).ToForward(); + } + + // shaft 2 + if ( constraint->shaft[1].type == idAFVector::VEC_BONEDIR ) { + s1 = GetSafeComboBoxSelection( &m_comboJoint1Shaft2, str, -1 ); + constraint->shaft[1].joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboJoint2Shaft2, str, s1 ); + constraint->shaft[1].joint2 = str; + } + else { + constraint->shaft[1].ToVec3() = idAngles( m_pitchShaft2, m_yawShaft2, 0.0f ).ToForward(); + } + + // limit + if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) { + constraint->limitAngles[0] = m_coneAngle; + } + else { + constraint->limitAngles[0] = m_pyramidAngle1; + } + constraint->limitAngles[1] = m_pyramidAngle2; + constraint->limitAngles[2] = m_limitRoll; + angles.pitch = m_limitPitch; + angles.yaw = m_limitYaw; + angles.roll = 0.0f; + constraint->limitAxis.ToVec3() = angles.ToForward(); + s1 = GetSafeComboBoxSelection( &m_comboLimitJoint1, str, -1 ); + constraint->limitAxis.joint1 = str; + s2 = GetSafeComboBoxSelection( &m_comboLimitJoint2, str, s1 ); + constraint->limitAxis.joint2 = str; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFConstraintUniversal::UpdateFile +================ +*/ +void DialogAFConstraintUniversal::UpdateFile( void ) { + SaveConstraint(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFConstraintUniversal::OnToolHitTest +================ +*/ +int DialogAFConstraintUniversal::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + + +BEGIN_MESSAGE_MAP(DialogAFConstraintUniversal, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_JOINT, OnBnClickedRadioAnchorJoint) + ON_BN_CLICKED(IDC_RADIO_ANCHOR_COORDINATES, OnBnClickedRadioAnchorCoordinates) + ON_CBN_SELCHANGE(IDC_COMBO_ANCHOR_JOINT, OnCbnSelchangeComboAnchorJoint) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_X, OnEnChangeEditAnchorX) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Y, OnEnChangeEditAnchorY) + ON_EN_CHANGE(IDC_EDIT_ANCHOR_Z, OnEnChangeEditAnchorZ) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_X, OnDeltaposSpinAnchorX) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Y, OnDeltaposSpinAnchorY) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANCHOR_Z, OnDeltaposSpinAnchorZ) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_BONE_SHAFT1, OnBnClickedRadioUniversalBoneShaft1) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1, OnBnClickedRadioUniversalAnglesShaft1) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_JOINT1_SHAFT1, OnCbnSelchangeComboUniversalJoint1Shaft1) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_JOINT2_SHAFT1, OnCbnSelchangeComboUniversalJoint2Shaft1) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_PITCH_SHAFT1, OnEnChangeEditUniversalPitchShaft1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_PITCH_SHAFT1, OnDeltaposSpinUniversalPitchShaft1) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_YAW_SHAFT1, OnEnChangeEditUniversalYawShaft1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_YAW_SHAFT1, OnDeltaposSpinUniversalYawShaft1) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_BONE_SHAFT2, OnBnClickedRadioUniversalBoneShaft2) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2, OnBnClickedRadioUniversalAnglesShaft2) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_JOINT1_SHAFT2, OnCbnSelchangeComboUniversalJoint1Shaft2) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_JOINT2_SHAFT2, OnCbnSelchangeComboUniversalJoint2Shaft2) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_PITCH_SHAFT2, OnEnChangeEditUniversalPitchShaft2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_PITCH_SHAFT2, OnDeltaposSpinUniversalPitchShaft2) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_YAW_SHAFT2, OnEnChangeEditUniversalYawShaft2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_YAW_SHAFT2, OnDeltaposSpinUniversalYawShaft2) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_LIMIT_NONE, OnBnClickedRadioUniversalLimitNone) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_LIMIT_CONE, OnBnClickedRadioUniversalLimitCone) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID, OnBnClickedRadioUniversalLimitPyramid) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE, OnEnChangeEditUniversalLimitConeAngle) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_CONE_ANGLE, OnDeltaposSpinUniversalLimitConeAngle) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1, OnEnChangeEditUniversalLimitPyramidAngle1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE1, OnDeltaposSpinUniversalLimitPyramidAngle1) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2, OnEnChangeEditUniversalLimitPyramidAngle2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_PYRAMID_ANGLE2, OnDeltaposSpinUniversalLimitPyramidAngle2) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_ROLL, OnEnChangeEditUniversalLimitRoll) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_ROLL, OnDeltaposSpinUniversalLimitRoll) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_LIMIT_BONE, OnBnClickedRadioUniversalLimitBone) + ON_BN_CLICKED(IDC_RADIO_UNIVERSAL_LIMIT_ANGLES, OnBnClickedRadioUniversalLimitAngles) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_LIMIT_JOINT1, OnCbnSelchangeComboUniversalLimitJoint1) + ON_CBN_SELCHANGE(IDC_COMBO_UNIVERSAL_LIMIT_JOINT2, OnCbnSelchangeComboUniversalLimitJoint2) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_PITCH, OnEnChangeEditUniversalLimitPitch) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_PITCH, OnDeltaposSpinUniversalLimitPitch) + ON_EN_CHANGE(IDC_EDIT_UNIVERSAL_LIMIT_YAW, OnEnChangeEditUniversalLimitYaw) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_UNIVERSAL_LIMIT_YAW, OnDeltaposSpinUniversalLimitYaw) +END_MESSAGE_MAP() + + +// DialogAFConstraintUniversal message handlers + +BOOL DialogAFConstraintUniversal::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFConstraintUniversal::OnBnClickedRadioAnchorJoint() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_JOINT ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_JOINT; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioAnchorCoordinates() { + if ( IsDlgButtonChecked( IDC_RADIO_ANCHOR_COORDINATES ) ) { + if ( constraint ) { + constraint->anchor.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboAnchorJoint() { + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnEnChangeEditAnchorX() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ) ) { + UpdateFile(); + } + else { + m_anchor_x = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_X ) ); + } +} + +void DialogAFConstraintUniversal::OnEnChangeEditAnchorY() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ) ) { + UpdateFile(); + } + else { + m_anchor_y = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Y ) ); + } +} + +void DialogAFConstraintUniversal::OnEnChangeEditAnchorZ() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ) ) { + UpdateFile(); + } + else { + m_anchor_z = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANCHOR_Z ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_x += 1.0f; + } + else { + m_anchor_x -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_y += 1.0f; + } + else { + m_anchor_y -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_anchor_z += 1.0f; + } + else { + m_anchor_z -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalBoneShaft1() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_BONE_SHAFT1 ) ) { + if ( constraint ) { + constraint->shaft[0].type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalAnglesShaft1() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_ANGLES_SHAFT1 ) ) { + if ( constraint ) { + constraint->shaft[0].type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalJoint1Shaft1() { + CString str; + GetSafeComboBoxSelection( &m_comboJoint1Shaft1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboJoint2Shaft1, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalJoint2Shaft1() { + CString str; + GetSafeComboBoxSelection( &m_comboJoint2Shaft1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboJoint1Shaft1, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalPitchShaft1() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_PITCH_SHAFT1 ) ) ) { + UpdateFile(); + } + else { + m_pitchShaft1 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_PITCH_SHAFT1 ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalPitchShaft1(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pitchShaft1 += 1.0f; + } + else { + m_pitchShaft1 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalYawShaft1() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_YAW_SHAFT1 ) ) ) { + UpdateFile(); + } + else { + m_yawShaft1 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_YAW_SHAFT1 ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalYawShaft1(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_yawShaft1 += 1.0f; + } + else { + m_yawShaft1 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalBoneShaft2() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_BONE_SHAFT2 ) ) { + if ( constraint ) { + constraint->shaft[1].type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalAnglesShaft2() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_ANGLES_SHAFT2 ) ) { + if ( constraint ) { + constraint->shaft[1].type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalJoint1Shaft2() { + CString str; + GetSafeComboBoxSelection( &m_comboJoint1Shaft2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboJoint2Shaft2, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalJoint2Shaft2() { + CString str; + GetSafeComboBoxSelection( &m_comboJoint2Shaft2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboJoint1Shaft2, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalPitchShaft2() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_PITCH_SHAFT2 ) ) ) { + UpdateFile(); + } + else { + m_pitchShaft2 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_PITCH_SHAFT2 ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalPitchShaft2(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pitchShaft2 += 1.0f; + } + else { + m_pitchShaft2 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalYawShaft2() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_YAW_SHAFT2 ) ) ) { + UpdateFile(); + } + else { + m_yawShaft2 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_YAW_SHAFT2 ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalYawShaft2(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_yawShaft2 += 1.0f; + } + else { + m_yawShaft2 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalLimitNone() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_LIMIT_NONE ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_NONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalLimitCone() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_LIMIT_CONE ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_CONE; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalLimitPyramid() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_LIMIT_PYRAMID ) ) { + if ( constraint ) { + constraint->limit = idDeclAF_Constraint::LIMIT_PYRAMID; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitConeAngle() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE ) ) ) { + UpdateFile(); + } + else { + m_coneAngle = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_CONE_ANGLE ), false ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitConeAngle(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_coneAngle += 1.0f; + } + else if ( m_coneAngle > 0.0f ) { + m_coneAngle -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitPyramidAngle1() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1 ) ) ) { + UpdateFile(); + } + else { + m_pyramidAngle1 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE1 ), false ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitPyramidAngle1(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pyramidAngle1 += 1.0f; + } + else if ( m_pyramidAngle1 > 0.0f ) { + m_pyramidAngle1 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitPyramidAngle2() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2 ) ) ) { + UpdateFile(); + } + else { + m_pyramidAngle2 = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PYRAMID_ANGLE2 ), false ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitPyramidAngle2(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_pyramidAngle2 += 1.0f; + } + else if ( m_pyramidAngle2 > 0.0f ) { + m_pyramidAngle2 -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitRoll() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_ROLL ) ) ) { + UpdateFile(); + } + else { + m_limitRoll = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_ROLL ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitRoll(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitRoll += 1.0f; + } + else { + m_limitRoll -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalLimitBone() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_LIMIT_BONE ) ) { + if ( constraint ) { + constraint->limitAxis.type = idAFVector::VEC_BONEDIR; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnBnClickedRadioUniversalLimitAngles() { + if ( IsDlgButtonChecked( IDC_RADIO_UNIVERSAL_LIMIT_ANGLES ) ) { + if ( constraint ) { + constraint->limitAxis.type = idAFVector::VEC_COORDS; + UpdateFile(); + } + } +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalLimitJoint1() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitJoint1, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitJoint2, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnCbnSelchangeComboUniversalLimitJoint2() { + CString str; + GetSafeComboBoxSelection( &m_comboLimitJoint2, str, -1 ); + UnsetSafeComboBoxSelection( &m_comboLimitJoint1, str ); + UpdateFile(); +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitPitch() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PITCH ) ) ) { + UpdateFile(); + } + else { + m_limitPitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_PITCH ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitPitch(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitPitch += 1.0f; + } + else { + m_limitPitch -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFConstraintUniversal::OnEnChangeEditUniversalLimitYaw() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_YAW ) ) ) { + UpdateFile(); + } + else { + m_limitYaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_UNIVERSAL_LIMIT_YAW ) ); + } +} + +void DialogAFConstraintUniversal::OnDeltaposSpinUniversalLimitYaw(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + if ( pNMUpDown->iDelta < 0 ) { + m_limitYaw += 1.0f; + } + else { + m_limitYaw -= 1.0f; + } + UpdateData( FALSE ); + UpdateFile(); + *pResult = 0; +} diff --git a/tools/af/DialogAFConstraintUniversal.h b/tools/af/DialogAFConstraintUniversal.h new file mode 100644 index 000000000..e6bec4b63 --- /dev/null +++ b/tools/af/DialogAFConstraintUniversal.h @@ -0,0 +1,120 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFConstraintUniversal dialog + +class DialogAFConstraintUniversal : public CDialog { + + DECLARE_DYNAMIC(DialogAFConstraintUniversal) + +public: + DialogAFConstraintUniversal(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFConstraintUniversal(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + void LoadConstraint( idDeclAF_Constraint *c ); + void SaveConstraint( void ); + void UpdateFile( void ); + + enum { IDD = IDD_DIALOG_AF_CONSTRAINT_UNIVERSAL }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedRadioAnchorJoint(); + afx_msg void OnBnClickedRadioAnchorCoordinates(); + afx_msg void OnCbnSelchangeComboAnchorJoint(); + afx_msg void OnEnChangeEditAnchorX(); + afx_msg void OnEnChangeEditAnchorY(); + afx_msg void OnEnChangeEditAnchorZ(); + afx_msg void OnDeltaposSpinAnchorX(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorY(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnDeltaposSpinAnchorZ(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioUniversalBoneShaft1(); + afx_msg void OnBnClickedRadioUniversalAnglesShaft1(); + afx_msg void OnCbnSelchangeComboUniversalJoint1Shaft1(); + afx_msg void OnCbnSelchangeComboUniversalJoint2Shaft1(); + afx_msg void OnEnChangeEditUniversalPitchShaft1(); + afx_msg void OnDeltaposSpinUniversalPitchShaft1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalYawShaft1(); + afx_msg void OnDeltaposSpinUniversalYawShaft1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioUniversalBoneShaft2(); + afx_msg void OnBnClickedRadioUniversalAnglesShaft2(); + afx_msg void OnCbnSelchangeComboUniversalJoint1Shaft2(); + afx_msg void OnCbnSelchangeComboUniversalJoint2Shaft2(); + afx_msg void OnEnChangeEditUniversalPitchShaft2(); + afx_msg void OnDeltaposSpinUniversalPitchShaft2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalYawShaft2(); + afx_msg void OnDeltaposSpinUniversalYawShaft2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioUniversalLimitNone(); + afx_msg void OnBnClickedRadioUniversalLimitCone(); + afx_msg void OnBnClickedRadioUniversalLimitPyramid(); + afx_msg void OnEnChangeEditUniversalLimitConeAngle(); + afx_msg void OnDeltaposSpinUniversalLimitConeAngle(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalLimitPyramidAngle1(); + afx_msg void OnDeltaposSpinUniversalLimitPyramidAngle1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalLimitPyramidAngle2(); + afx_msg void OnDeltaposSpinUniversalLimitPyramidAngle2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalLimitRoll(); + afx_msg void OnDeltaposSpinUniversalLimitRoll(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedRadioUniversalLimitBone(); + afx_msg void OnBnClickedRadioUniversalLimitAngles(); + afx_msg void OnCbnSelchangeComboUniversalLimitJoint1(); + afx_msg void OnCbnSelchangeComboUniversalLimitJoint2(); + afx_msg void OnEnChangeEditUniversalLimitPitch(); + afx_msg void OnDeltaposSpinUniversalLimitPitch(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditUniversalLimitYaw(); + afx_msg void OnDeltaposSpinUniversalLimitYaw(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + idDeclAF_Constraint*constraint; + + //{{AFX_DATA(DialogAFConstraintUniversal) + CComboBox m_comboAnchorJoint; + float m_anchor_x; + float m_anchor_y; + float m_anchor_z; + CComboBox m_comboJoint1Shaft1; + CComboBox m_comboJoint2Shaft1; + float m_pitchShaft1; + float m_yawShaft1; + CComboBox m_comboJoint1Shaft2; + CComboBox m_comboJoint2Shaft2; + float m_pitchShaft2; + float m_yawShaft2; + float m_coneAngle; + float m_pyramidAngle1; + float m_pyramidAngle2; + CComboBox m_comboLimitJoint1; + CComboBox m_comboLimitJoint2; + float m_limitPitch; + float m_limitYaw; + float m_limitRoll; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void InitJointLists( void ); +}; diff --git a/tools/af/DialogAFName.cpp b/tools/af/DialogAFName.cpp new file mode 100644 index 000000000..e8da4052b --- /dev/null +++ b/tools/af/DialogAFName.cpp @@ -0,0 +1,159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFName.h" + +// DialogAFName dialog + +IMPLEMENT_DYNAMIC(DialogAFName, CDialog) + +/* +================ +DialogAFName::DialogAFName +================ +*/ +DialogAFName::DialogAFName(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFName::IDD, pParent) + , m_combo(NULL) +{ +} + +/* +================ +DialogAFName::~DialogAFName +================ +*/ +DialogAFName::~DialogAFName() { +} + +/* +================ +DialogAFName::DoDataExchange +================ +*/ +void DialogAFName::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_EDIT_AF_NAME, m_editName); +} + +/* +================ +DialogAFName::SetName +================ +*/ +void DialogAFName::SetName( CString &str ) { + m_editName = str; +} + +/* +================ +DialogAFName::GetName +================ +*/ +void DialogAFName::GetName( CString &str ) { + str = m_editName; +} + +/* +================ +DialogAFName::SetComboBox +================ +*/ +void DialogAFName::SetComboBox( CComboBox *combo ) { + m_combo = combo; +} + +/* +================ +DialogAFName::OnInitDialog +================ +*/ +BOOL DialogAFName::OnInitDialog() { + CEdit *edit; + CString str; + + CDialog::OnInitDialog(); + + edit = (CEdit *)GetDlgItem( IDC_EDIT_AF_NAME ); + edit->SetFocus(); + edit->GetWindowText( str ); + edit->SetSel( 0, str.GetLength() ); + + return FALSE; +} + +/* +================ +EditVerifyName +================ +*/ +void EditVerifyName( CEdit *edit ) { + CString strIn, strOut; + int start, end; + static bool entered = false; + + if ( entered ) { + return; + } + entered = true; + + edit->GetSel( start, end ); + edit->GetWindowText( strIn ); + for ( int i = 0; i < strIn.GetLength(); i++ ) { + if ( ( strIn[i] >= 'a' && strIn[i] <= 'z' ) || + ( strIn[i] >= 'A' && strIn[i] <= 'Z' ) || + ( strIn[i] == '_' ) || ( strIn[i] >= '0' && strIn[i] <= '9' ) ) { + strOut.AppendChar( strIn[i] ); + } + } + edit->SetWindowText( strOut ); + edit->SetSel( start, end ); + + entered = false; +} + + +BEGIN_MESSAGE_MAP(DialogAFName, CDialog) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_EN_CHANGE(IDC_EDIT_AF_NAME, OnEnChangeEditAfName) +END_MESSAGE_MAP() + + +// DialogAFName message handlers + +void DialogAFName::OnBnClickedOk() { + + UpdateData( TRUE ); + if ( m_combo && m_combo->FindStringExact( -1, m_editName ) != -1 ) { + MessageBox( va( "The name %s is already used.", m_editName.GetBuffer() ), "Name", MB_OK ); + } + else { + OnOK(); + } +} + +void DialogAFName::OnEnChangeEditAfName() { + EditVerifyName( (CEdit *) GetDlgItem( IDC_EDIT_AF_NAME ) ); +} diff --git a/tools/af/DialogAFName.h b/tools/af/DialogAFName.h new file mode 100644 index 000000000..8342787f1 --- /dev/null +++ b/tools/af/DialogAFName.h @@ -0,0 +1,47 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFName dialog + +class DialogAFName : public CDialog { + + DECLARE_DYNAMIC(DialogAFName) + +public: + DialogAFName(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFName(); + void SetName( CString &str ); + void GetName( CString &str ); + void SetComboBox( CComboBox *combo ); + + enum { IDD = IDD_DIALOG_AF_NAME }; + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + afx_msg void OnBnClickedOk(); + afx_msg void OnEnChangeEditAfName(); + + DECLARE_MESSAGE_MAP() + +private: + CString m_editName; + CComboBox * m_combo; +}; diff --git a/tools/af/DialogAFProperties.cpp b/tools/af/DialogAFProperties.cpp new file mode 100644 index 000000000..204c21b6d --- /dev/null +++ b/tools/af/DialogAFProperties.cpp @@ -0,0 +1,503 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFProperties.h" +#include "DialogAFBody.h" +#include "DialogAFConstraint.h" + + +// DialogAFProperties dialog + +toolTip_t DialogAFProperties::toolTips[] = { + { IDC_EDIT_MODEL, "model def" }, + { IDC_BUTTON_BROWSE_MODEL, "browse model def" }, + { IDC_EDIT_SKIN, "skin" }, + { IDC_BUTTON_BROWSE_SKIN, "browse skin" }, + { IDC_EDIT_LINEARFRICTION, "translational friction" }, + { IDC_EDIT_ANGULARFRICTION, "rotational friction" }, + { IDC_EDIT_CONTACTFRICTION, "friction with contact surfaces" }, + { IDC_EDIT_CONSTRAINTFRICTION, "constraint friction" }, + { IDC_CHECK_SELFCOLLISION, "allow bodies to collide with other bodies of this articulated figure" }, + { IDC_EDIT_CONTENTS, "content of bodies" }, + { IDC_EDIT_CLIPMASK, "collide with these content types" }, + { IDC_EDIT_TOTALMASS, "scale the mass of each body to get this total mass" }, + { IDC_EDIT_LINEARVELOCITY, "do not suspend simulation if the linear velocity is higher than this value" }, + { IDC_EDIT_ANGULARVELOCITY, "do not suspend simulation if the angular velocity is higher than this value" }, + { IDC_EDIT_LINEARACCELERATION, "do not suspend simulation if the linear acceleration is higher than this value" }, + { IDC_EDIT_ANGULARACCELERATION, "do not suspend simulation if the angular acceleration is higher than this value" }, + { IDC_EDIT_NO_MOVE_TIME, "suspend simulation if hardly any movement for this many seconds" }, + { IDC_EDIT_MAXIMUM_MOVE_TIME, "always suspend simulation after running for this many seconds" }, + { IDC_EDIT_LINEAR_TOLERANCE, "maximum translation considered no movement" }, + { IDC_EDIT_ANGULAR_TOLERANCE, "maximum rotation considered no movement" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFProperties, CDialog) + +/* +================ +DialogAFProperties::DialogAFProperties +================ +*/ +DialogAFProperties::DialogAFProperties(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFProperties::IDD, pParent) + , m_selfCollision(false) + , m_linearFriction(0) + , m_angularFriction(0) + , m_contactFriction(0) + , m_constraintFriction(0) + , m_totalMass(0) + , m_suspendLinearVelocity(0) + , m_suspendAngularVelocity(0) + , m_suspendLinearAcceleration(0) + , m_suspendAngularAcceleration(0) + , m_noMoveTime(0) + , m_minMoveTime(0) + , m_maxMoveTime(0) + , m_linearTolerance(0) + , m_angularTolerance(0) + , file(NULL) +{ + Create( IDD_DIALOG_AF_PROPERTIES, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFProperties::~DialogAFProperties +================ +*/ +DialogAFProperties::~DialogAFProperties() { +} + +/* +================ +DialogAFProperties::DoDataExchange +================ +*/ +void DialogAFProperties::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFProperties) + DDX_Control(pDX, IDC_EDIT_MODEL, m_editModel); + DDX_Control(pDX, IDC_EDIT_SKIN, m_editSkin); + DDX_Check(pDX, IDC_CHECK_SELFCOLLISION, m_selfCollision); + DDX_Control(pDX, IDC_EDIT_CONTENTS, m_editContents); + DDX_Control(pDX, IDC_EDIT_CLIPMASK, m_editClipMask); + DDX_Text(pDX, IDC_EDIT_LINEARFRICTION, m_linearFriction); + DDX_Text(pDX, IDC_EDIT_ANGULARFRICTION, m_angularFriction); + DDX_Text(pDX, IDC_EDIT_CONTACTFRICTION, m_contactFriction); + DDX_Text(pDX, IDC_EDIT_CONSTRAINTFRICTION, m_constraintFriction); + DDX_Text(pDX, IDC_EDIT_TOTALMASS, m_totalMass); + DDX_Text(pDX, IDC_EDIT_LINEARVELOCITY, m_suspendLinearVelocity); + DDX_Text(pDX, IDC_EDIT_ANGULARVELOCITY, m_suspendAngularVelocity); + DDX_Text(pDX, IDC_EDIT_LINEARACCELERATION, m_suspendLinearAcceleration); + DDX_Text(pDX, IDC_EDIT_ANGULARACCELERATION, m_suspendAngularAcceleration); + DDX_Text(pDX, IDC_EDIT_NO_MOVE_TIME, m_noMoveTime); + DDX_Text(pDX, IDC_EDIT_MINIMUM_MOVE_TIME, m_minMoveTime); + DDX_Text(pDX, IDC_EDIT_MAXIMUM_MOVE_TIME, m_maxMoveTime); + DDX_Text(pDX, IDC_EDIT_LINEAR_TOLERANCE, m_linearTolerance); + DDX_Text(pDX, IDC_EDIT_ANGULAR_TOLERANCE, m_angularTolerance); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFProperties::LoadFile +================ +*/ +void DialogAFProperties::LoadFile( idDeclAF *af ) { + idStr str; + + file = af; + + if ( !file ) { + ClearFile(); + return; + } + m_editModel.SetWindowText( file->model.c_str() ); + m_editSkin.SetWindowText( file->skin.c_str() ); + m_selfCollision = file->selfCollision; + idDeclAF::ContentsToString( file->contents, str ); + m_editContents.SetWindowText( str ); + idDeclAF::ContentsToString( file->clipMask, str ); + m_editClipMask.SetWindowText( str ); + m_linearFriction = file->defaultLinearFriction; + m_angularFriction = file->defaultAngularFriction; + m_contactFriction = file->defaultContactFriction; + m_constraintFriction = file->defaultConstraintFriction; + m_totalMass = file->totalMass; + m_suspendLinearVelocity = file->suspendVelocity[0]; + m_suspendAngularVelocity = file->suspendVelocity[1]; + m_suspendLinearAcceleration = file->suspendAcceleration[0]; + m_suspendAngularAcceleration = file->suspendAcceleration[1]; + m_noMoveTime = file->noMoveTime; + m_minMoveTime = file->minMoveTime; + m_maxMoveTime = file->maxMoveTime; + m_linearTolerance = file->noMoveTranslation; + m_angularTolerance = file->noMoveRotation; + UpdateData( FALSE ); +} + +/* +================ +DialogAFProperties::SetFile +================ +*/ +void DialogAFProperties::SaveFile( void ) { + CString str; + + if ( !file ) { + return; + } + UpdateData( TRUE ); + m_editModel.GetWindowText( str ); + file->model = str; + m_editSkin.GetWindowText( str ); + file->skin = str; + file->selfCollision = ( m_selfCollision != FALSE ); + m_editContents.GetWindowText( str ); + file->contents = idDeclAF::ContentsFromString( str ); + m_editClipMask.GetWindowText( str ); + file->clipMask = idDeclAF::ContentsFromString( str ); + file->defaultLinearFriction = m_linearFriction; + file->defaultAngularFriction = m_angularFriction; + file->defaultContactFriction = m_contactFriction; + file->defaultConstraintFriction = m_constraintFriction; + file->totalMass = m_totalMass; + file->suspendVelocity[0] = m_suspendLinearVelocity; + file->suspendVelocity[1] = m_suspendAngularVelocity; + file->suspendAcceleration[0] = m_suspendLinearAcceleration; + file->suspendAcceleration[1] = m_suspendAngularAcceleration; + file->noMoveTime = m_noMoveTime; + file->minMoveTime = m_minMoveTime; + file->maxMoveTime = m_maxMoveTime; + file->noMoveTranslation = m_linearTolerance; + file->noMoveRotation = m_angularTolerance; + + AFDialogSetFileModified(); +} + +/* +================ +DialogAFProperties::UpdateFile +================ +*/ +void DialogAFProperties::UpdateFile( void ) { + SaveFile(); + if ( file ) { + gameEdit->AF_UpdateEntities( file->GetName() ); + } +} + +/* +================ +DialogAFProperties::ClearFile +================ +*/ +void DialogAFProperties::ClearFile( void ) { + m_editModel.SetWindowText( "" ); + m_editSkin.SetWindowText( "" ); + m_selfCollision = false; + m_editContents.SetWindowText( "" ); + m_editClipMask.SetWindowText( "" ); + m_linearFriction = 0.0f; + m_angularFriction = 0.0f; + m_contactFriction = 0.0f; + m_constraintFriction = 0.0f; + m_totalMass = -1.0f; + m_suspendLinearVelocity = 0.0f; + m_suspendAngularVelocity = 0.0f; + m_suspendLinearAcceleration = 0.0f; + m_suspendAngularAcceleration = 0.0f; + m_noMoveTime = 0.0f; + m_minMoveTime = 0.0f; + m_maxMoveTime = 0.0f; + m_linearTolerance = 0.0f; + m_angularTolerance = 0.0f; + UpdateData( FALSE ); +} + +/* +================ +DialogAFProperties::OnToolHitTest +================ +*/ +int DialogAFProperties::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + +BEGIN_MESSAGE_MAP(DialogAFProperties, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_EN_CHANGE(IDC_EDIT_MODEL, OnEnChangeEditModel) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_MODEL, OnBnClickedButtonBrowseModel) + ON_EN_CHANGE(IDC_EDIT_SKIN, OnEnChangeEditSkin) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_SKIN, OnBnClickedButtonBrowseSkin) + ON_EN_CHANGE(IDC_EDIT_LINEARFRICTION, OnEnChangeEditLinearfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_LINEARFRICTION, OnDeltaposSpinLinearfriction) + ON_EN_CHANGE(IDC_EDIT_ANGULARFRICTION, OnEnChangeEditAngularfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGULARFRICTION, OnDeltaposSpinAngularfriction) + ON_EN_CHANGE(IDC_EDIT_CONTACTFRICTION, OnEnChangeEditContactfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CONTACTFRICTION, OnDeltaposSpinContactfriction) + ON_EN_CHANGE(IDC_EDIT_CONSTRAINTFRICTION, OnEnChangeEditConstraintfriction) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CONSTRAINTFRICTION, OnDeltaposSpinConstraintfriction) + ON_BN_CLICKED(IDC_CHECK_SELFCOLLISION, OnBnClickedCheckSelfcollision) + ON_EN_CHANGE(IDC_EDIT_CONTENTS, OnEnChangeEditContents) + ON_EN_CHANGE(IDC_EDIT_CLIPMASK, OnEnChangeEditClipmask) + ON_EN_CHANGE(IDC_EDIT_TOTALMASS, OnEnChangeEditTotalmass) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_TOTALMASS, OnDeltaposSpinTotalmass) + ON_EN_CHANGE(IDC_EDIT_LINEARVELOCITY, OnEnChangeEditLinearvelocity) + ON_EN_CHANGE(IDC_EDIT_ANGULARVELOCITY, OnEnChangeEditAngularvelocity) + ON_EN_CHANGE(IDC_EDIT_LINEARACCELERATION, OnEnChangeEditLinearacceleration) + ON_EN_CHANGE(IDC_EDIT_ANGULARACCELERATION, OnEnChangeEditAngularacceleration) + ON_EN_CHANGE(IDC_EDIT_NO_MOVE_TIME, OnEnChangeEditNomovetime) + ON_EN_CHANGE(IDC_EDIT_MINIMUM_MOVE_TIME, OnEnChangeEditMinimummovetime) + ON_EN_CHANGE(IDC_EDIT_MAXIMUM_MOVE_TIME, OnEnChangeEditMaximummovetime) + ON_EN_CHANGE(IDC_EDIT_LINEAR_TOLERANCE, OnEnChangeEditLineartolerance) + ON_EN_CHANGE(IDC_EDIT_ANGULAR_TOLERANCE, OnEnChangeEditAngulartolerance) +END_MESSAGE_MAP() + + +// DialogAFProperties message handlers + +BOOL DialogAFProperties::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFProperties::OnEnChangeEditModel() { + if ( EditControlEnterHit( &m_editModel ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditSkin() { + if ( EditControlEnterHit( &m_editSkin ) ) { + UpdateFile(); + // reload the .af file + AFDialogReloadFile(); + } +} + +void DialogAFProperties::OnBnClickedCheckSelfcollision() { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Self Collision", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->selfCollision = file->selfCollision; + } + bodyDlg->LoadFile( file ); + } +} + +void DialogAFProperties::OnEnChangeEditContents() { + if ( EditControlEnterHit( &m_editContents ) ) { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Contents", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->contents = file->contents; + } + bodyDlg->LoadFile( file ); + } + } +} + +void DialogAFProperties::OnEnChangeEditClipmask() { + if ( EditControlEnterHit( &m_editClipMask ) ) { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Clip Mask", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->clipMask = file->clipMask; + } + bodyDlg->LoadFile( file ); + } + } +} + +void DialogAFProperties::OnEnChangeEditLinearfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ) ) ) { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Linear Friction", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->linearFriction = file->defaultLinearFriction; + } + bodyDlg->LoadFile( file ); + } + } + else { + m_linearFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ), false ); + } +} + +void DialogAFProperties::OnDeltaposSpinLinearfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_linearFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_LINEARFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFProperties::OnEnChangeEditAngularfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ) ) ) { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Angular Friction", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->angularFriction = file->defaultAngularFriction; + } + bodyDlg->LoadFile( file ); + } + } + else { + m_angularFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ), false ); + } +} + +void DialogAFProperties::OnDeltaposSpinAngularfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_angularFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_ANGULARFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFProperties::OnEnChangeEditContactfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ) ) ) { + UpdateFile(); + if ( file && file->bodies.Num() && MessageBox( "Apply to all bodies ?", "Contact Friction", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->bodies.Num(); i++ ) { + file->bodies[i]->contactFriction = file->defaultContactFriction; + } + bodyDlg->LoadFile( file ); + } + } + else { + m_contactFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ), false ); + } +} + +void DialogAFProperties::OnDeltaposSpinContactfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_contactFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CONTACTFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFProperties::OnEnChangeEditConstraintfriction() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONSTRAINTFRICTION ) ) ) { + UpdateFile(); + if ( file && file->constraints.Num() && MessageBox( "Apply to all constraints ?", "Constraint Friction", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + for ( int i = 0; i < file->constraints.Num(); i++ ) { + file->constraints[i]->friction = file->defaultConstraintFriction; + } + constraintDlg->LoadFile( file ); + } + } + else { + EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CONSTRAINTFRICTION ), false ); + } +} + +void DialogAFProperties::OnDeltaposSpinConstraintfriction(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_constraintFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CONSTRAINTFRICTION ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFProperties::OnEnChangeEditTotalmass() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_TOTALMASS ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnDeltaposSpinTotalmass(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); + m_totalMass = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_TOTALMASS ), pNMUpDown->iDelta < 0 ); + UpdateFile(); + *pResult = 0; +} + +void DialogAFProperties::OnEnChangeEditLinearvelocity() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEARVELOCITY ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditAngularvelocity() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARVELOCITY ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditLinearacceleration() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEARACCELERATION ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditAngularacceleration() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARACCELERATION ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditNomovetime() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_NO_MOVE_TIME ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditMinimummovetime() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_MINIMUM_MOVE_TIME ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditMaximummovetime() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_MAXIMUM_MOVE_TIME ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditLineartolerance() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEAR_TOLERANCE ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnEnChangeEditAngulartolerance() { + if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULAR_TOLERANCE ) ) ) { + UpdateFile(); + } +} + +void DialogAFProperties::OnBnClickedButtonBrowseModel() { +// m_editModel.SetWindowText( str ); +// UpdateFile(); +} + +void DialogAFProperties::OnBnClickedButtonBrowseSkin() { +// m_editSkin.SetWindowText( str ); +// UpdateFile(); + // reload the .af file +// AFDialogReloadFile(); +} diff --git a/tools/af/DialogAFProperties.h b/tools/af/DialogAFProperties.h new file mode 100644 index 000000000..ab56a9e7d --- /dev/null +++ b/tools/af/DialogAFProperties.h @@ -0,0 +1,101 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFProperties dialog + +class DialogAFProperties : public CDialog { + + DECLARE_DYNAMIC(DialogAFProperties) + +public: + DialogAFProperties( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogAFProperties(); + void LoadFile( idDeclAF *af ); + void SaveFile( void ); + + DialogAFBody * bodyDlg; + DialogAFConstraint *constraintDlg; + + enum { IDD = IDD_DIALOG_AF_PROPERTIES }; + +protected: + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnEnChangeEditModel(); + afx_msg void OnEnChangeEditSkin(); + afx_msg void OnBnClickedButtonBrowseModel(); + afx_msg void OnBnClickedButtonBrowseSkin(); + afx_msg void OnBnClickedCheckSelfcollision(); + afx_msg void OnEnChangeEditContents(); + afx_msg void OnEnChangeEditClipmask(); + afx_msg void OnEnChangeEditLinearfriction(); + afx_msg void OnDeltaposSpinLinearfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditAngularfriction(); + afx_msg void OnDeltaposSpinAngularfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditContactfriction(); + afx_msg void OnDeltaposSpinContactfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditConstraintfriction(); + afx_msg void OnDeltaposSpinConstraintfriction(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditTotalmass(); + afx_msg void OnDeltaposSpinTotalmass(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditLinearvelocity(); + afx_msg void OnEnChangeEditAngularvelocity(); + afx_msg void OnEnChangeEditLinearacceleration(); + afx_msg void OnEnChangeEditAngularacceleration(); + afx_msg void OnEnChangeEditNomovetime(); + afx_msg void OnEnChangeEditMinimummovetime(); + afx_msg void OnEnChangeEditMaximummovetime(); + afx_msg void OnEnChangeEditLineartolerance(); + afx_msg void OnEnChangeEditAngulartolerance(); + + DECLARE_MESSAGE_MAP() + +private: + idDeclAF * file; + + //{{AFX_DATA(DialogAFProperties) + CEdit m_editModel; + CEdit m_editSkin; + BOOL m_selfCollision; + CEdit m_editContents; + CEdit m_editClipMask; + float m_linearFriction; + float m_angularFriction; + float m_contactFriction; + float m_constraintFriction; + float m_totalMass; + float m_suspendLinearVelocity; + float m_suspendAngularVelocity; + float m_suspendLinearAcceleration; + float m_suspendAngularAcceleration; + float m_noMoveTime; + float m_minMoveTime; + float m_maxMoveTime; + float m_linearTolerance; + float m_angularTolerance; + //}}AFX_DATA + + static toolTip_t toolTips[]; + +private: + void UpdateFile( void ); + void ClearFile( void ); +}; diff --git a/tools/af/DialogAFView.cpp b/tools/af/DialogAFView.cpp new file mode 100644 index 000000000..0ee861400 --- /dev/null +++ b/tools/af/DialogAFView.cpp @@ -0,0 +1,315 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/AFEditor_resource.h" + +#include "DialogAF.h" +#include "DialogAFView.h" + +// DialogAFView dialog + +toolTip_t DialogAFView::toolTips[] = { + { IDC_CHECK_VIEW_BODIES, "show bodies" }, + { IDC_CHECK_VIEW_BODYNAMES, "show body names" }, + { IDC_CHECK_VIEW_BODYMASS, "show body mass" }, + { IDC_CHECK_VIEW_TOTALMASS, "show total mass" }, + { IDC_CHECK_VIEW_INERTIATENSOR, "show body inertia tensor" }, + { IDC_CHECK_VIEW_VELOCITY, "show body velocity" }, + { IDC_CHECK_VIEW_CONSTRAINTNAMES, "show constraint names" }, + { IDC_CHECK_VIEW_CONSTRAINTS, "show constraints" }, + { IDC_CHECK_VIEW_PRIMARYONLY, "show only primary constraints" }, + { IDC_CHECK_VIEW_LIMITS, "show constraint limits" }, + { IDC_CHECK_VIEW_CONSTRAINEDBODIES, "show bodies constrained by current constraint (body1 = cyan, body2 = blue)" }, + { IDC_CHECK_VIEW_TREES, "show tree structures" }, + { IDC_CHECK_MD5_SKELETON, "show md5 with skeleton" }, + { IDC_CHECK_MD5_SKELETONONLY, "show only the md5 skeleton" }, + { IDC_CHECK_LINES_DEPTHTEST, "zbuffer lines" }, + { IDC_CHECK_LINES_USEARROWS, "use arrows" }, + { IDC_CHECK_PHYSICS_NOFRICTION, "disable all friction" }, + { IDC_CHECK_PHYSICS_NOLIMITS, "disable all joint limits" }, + { IDC_CHECK_PHYSICS_NOGRAVITY, "disable gravity" }, + { IDC_CHECK_PHYSICS_NOSELFCOLLISION, "disable self collision detection" }, + { IDC_CHECK_PHYSICS_TIMING, "show performance timings" }, + { IDC_CHECK_PHYSICS_DRAG_ENTITIES, "drag entities" }, + { IDC_CHECK_PHYSICS_SHOW_DRAG_SELECTION, "show selection box around the entity selected for dragging" }, + { 0, NULL } +}; + +IMPLEMENT_DYNAMIC(DialogAFView, CDialog) + +/* +================ +DialogAFView::DialogAFView +================ +*/ +DialogAFView::DialogAFView(CWnd* pParent /*=NULL*/) + : CDialog(DialogAFView::IDD, pParent) + +{ + m_showBodies = cvarSystem->GetCVarBool( "af_showBodies" ); + m_showBodyNames = cvarSystem->GetCVarBool( "af_showBodyNames" ); + m_showMass = cvarSystem->GetCVarBool( "af_showMass" ); + m_showTotalMass = cvarSystem->GetCVarBool( "af_showTotalMass" ); + m_showInertia = cvarSystem->GetCVarBool( "af_showInertia" ); + m_showVelocity = cvarSystem->GetCVarBool( "af_showVelocity" ); + m_showConstraints = cvarSystem->GetCVarBool( "af_showConstraints" ); + m_showConstraintNames = cvarSystem->GetCVarBool( "af_showConstraintNames" ); + m_showPrimaryOnly = cvarSystem->GetCVarBool( "af_showPrimaryOnly" ); + m_showLimits = cvarSystem->GetCVarBool( "af_showLimits" ); + m_showConstrainedBodies = cvarSystem->GetCVarBool( "af_showConstrainedBodies" ); + m_showTrees = cvarSystem->GetCVarBool( "af_showTrees" ); + m_showSkeleton = cvarSystem->GetCVarInteger( "af_showSkel" ) == 1; + m_showSkeletonOnly = cvarSystem->GetCVarInteger( "af_showSkel" ) == 2; + m_debugLineDepthTest = cvarSystem->GetCVarBool( "r_debugLineDepthTest" ); + m_debugLineUseArrows = cvarSystem->GetCVarInteger( "r_debugArrowStep" ) != 0; + m_noFriction = cvarSystem->GetCVarBool( "af_skipFriction" ); + m_noLimits = cvarSystem->GetCVarBool( "af_skipLimits" ); + m_gravity = cvarSystem->GetCVarFloat( "g_gravity" ); + m_noGravity = ( m_gravity == 0.0f ); + m_noSelfCollision = cvarSystem->GetCVarBool( "af_skipSelfCollision" ); + m_showTimings = cvarSystem->GetCVarBool( "af_showTimings" ); + m_dragEntity = cvarSystem->GetCVarBool( "g_dragEntity" ); + m_dragShowSelection = cvarSystem->GetCVarBool( "g_dragShowSelection" ); + + Create( IDD_DIALOG_AF_VIEW, pParent ); + EnableToolTips( TRUE ); +} + +/* +================ +DialogAFView::~DialogAFView +================ +*/ +DialogAFView::~DialogAFView() { +} + +/* +================ +DialogAFView::DoDataExchange +================ +*/ +void DialogAFView::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogAFView) + DDX_Check(pDX, IDC_CHECK_VIEW_BODIES, m_showBodies); + DDX_Check(pDX, IDC_CHECK_VIEW_BODYNAMES, m_showBodyNames); + DDX_Check(pDX, IDC_CHECK_VIEW_BODYMASS, m_showMass); + DDX_Check(pDX, IDC_CHECK_VIEW_TOTALMASS, m_showTotalMass); + DDX_Check(pDX, IDC_CHECK_VIEW_INERTIATENSOR, m_showInertia); + DDX_Check(pDX, IDC_CHECK_VIEW_VELOCITY, m_showVelocity); + DDX_Check(pDX, IDC_CHECK_VIEW_CONSTRAINTS, m_showConstraints); + DDX_Check(pDX, IDC_CHECK_VIEW_CONSTRAINTNAMES, m_showConstraintNames); + DDX_Check(pDX, IDC_CHECK_VIEW_PRIMARYONLY, m_showPrimaryOnly); + DDX_Check(pDX, IDC_CHECK_VIEW_LIMITS, m_showLimits); + DDX_Check(pDX, IDC_CHECK_VIEW_CONSTRAINEDBODIES, m_showConstrainedBodies); + DDX_Check(pDX, IDC_CHECK_VIEW_TREES, m_showTrees); + DDX_Check(pDX, IDC_CHECK_MD5_SKELETON, m_showSkeleton); + DDX_Check(pDX, IDC_CHECK_MD5_SKELETONONLY, m_showSkeletonOnly); + DDX_Check(pDX, IDC_CHECK_LINES_DEPTHTEST, m_debugLineDepthTest); + DDX_Check(pDX, IDC_CHECK_LINES_USEARROWS, m_debugLineUseArrows); + DDX_Check(pDX, IDC_CHECK_PHYSICS_NOFRICTION, m_noFriction); + DDX_Check(pDX, IDC_CHECK_PHYSICS_NOLIMITS, m_noLimits); + DDX_Check(pDX, IDC_CHECK_PHYSICS_NOGRAVITY, m_noGravity); + DDX_Check(pDX, IDC_CHECK_PHYSICS_NOSELFCOLLISION, m_noSelfCollision); + DDX_Check(pDX, IDC_CHECK_PHYSICS_TIMING, m_showTimings); + DDX_Check(pDX, IDC_CHECK_PHYSICS_DRAG_ENTITIES, m_dragEntity); + DDX_Check(pDX, IDC_CHECK_PHYSICS_SHOW_DRAG_SELECTION, m_dragShowSelection); + //}}AFX_DATA_MAP +} + +/* +================ +DialogAFView::OnToolHitTest +================ +*/ +int DialogAFView::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CDialog::OnToolHitTest( point, pTI ); + return DefaultOnToolHitTest( toolTips, this, point, pTI ); +} + +BEGIN_MESSAGE_MAP(DialogAFView, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_BN_CLICKED(IDC_CHECK_VIEW_BODIES, OnBnClickedCheckViewBodies) + ON_BN_CLICKED(IDC_CHECK_VIEW_BODYNAMES, OnBnClickedCheckViewBodynames) + ON_BN_CLICKED(IDC_CHECK_VIEW_BODYMASS, OnBnClickedCheckViewBodyMass) + ON_BN_CLICKED(IDC_CHECK_VIEW_TOTALMASS, OnBnClickedCheckViewTotalMass) + ON_BN_CLICKED(IDC_CHECK_VIEW_INERTIATENSOR, OnBnClickedCheckViewInertiatensor) + ON_BN_CLICKED(IDC_CHECK_VIEW_VELOCITY, OnBnClickedCheckViewVelocity) + ON_BN_CLICKED(IDC_CHECK_VIEW_CONSTRAINTS, OnBnClickedCheckViewConstraints) + ON_BN_CLICKED(IDC_CHECK_VIEW_CONSTRAINTNAMES, OnBnClickedCheckViewConstraintnames) + ON_BN_CLICKED(IDC_CHECK_VIEW_PRIMARYONLY, OnBnClickedCheckViewPrimaryonly) + ON_BN_CLICKED(IDC_CHECK_VIEW_LIMITS, OnBnClickedCheckViewLimits) + ON_BN_CLICKED(IDC_CHECK_VIEW_CONSTRAINEDBODIES, OnBnClickedCheckViewConstrainedBodies) + ON_BN_CLICKED(IDC_CHECK_VIEW_TREES, OnBnClickedCheckViewTrees) + ON_BN_CLICKED(IDC_CHECK_MD5_SKELETON, OnBnClickedCheckMd5Skeleton) + ON_BN_CLICKED(IDC_CHECK_MD5_SKELETONONLY, OnBnClickedCheckMd5Skeletononly) + ON_BN_CLICKED(IDC_CHECK_LINES_DEPTHTEST, OnBnClickedCheckLinesDepthtest) + ON_BN_CLICKED(IDC_CHECK_LINES_USEARROWS, OnBnClickedCheckLinesUsearrows) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_NOFRICTION, OnBnClickedCheckPhysicsNofriction) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_NOLIMITS, OnBnClickedCheckPhysicsNolimits) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_NOGRAVITY, OnBnClickedCheckPhysicsNogravity) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_NOSELFCOLLISION, OnBnClickedCheckPhysicsNoselfcollision) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_TIMING, OnBnClickedCheckPhysicsTiming) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_DRAG_ENTITIES, OnBnClickedCheckPhysicsDragEntities) + ON_BN_CLICKED(IDC_CHECK_PHYSICS_SHOW_DRAG_SELECTION, OnBnClickedCheckPhysicsShowDragSelection) +END_MESSAGE_MAP() + + +// DialogAFView message handlers + +BOOL DialogAFView::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +void DialogAFView::OnBnClickedCheckViewBodies() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showBodies", m_showBodies != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewBodynames() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showBodyNames", m_showBodyNames != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewBodyMass() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showMass", m_showMass != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewTotalMass() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showTotalMass", m_showTotalMass != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewInertiatensor() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showInertia", m_showInertia != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewVelocity() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showVelocity", m_showVelocity != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewConstraints() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showConstraints", m_showConstraints != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewConstraintnames() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showConstraintNames", m_showConstraintNames != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewPrimaryonly() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showPrimaryOnly", m_showPrimaryOnly != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewLimits() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showLimits", m_showLimits != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewConstrainedBodies() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showConstrainedBodies", m_showConstrainedBodies != FALSE ); +} + +void DialogAFView::OnBnClickedCheckViewTrees() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showTrees", m_showTrees != FALSE ); +} + +void DialogAFView::OnBnClickedCheckMd5Skeleton() { + UpdateData(TRUE); + if ( !m_showSkeletonOnly ) { + if ( m_showSkeleton ) { + cvarSystem->SetCVarInteger( "r_showSkel", 1 ); + } else { + cvarSystem->SetCVarInteger( "r_showSkel", 0 ); + } + } +} + +void DialogAFView::OnBnClickedCheckMd5Skeletononly() { + UpdateData(TRUE); + if ( m_showSkeletonOnly ) { + cvarSystem->SetCVarInteger( "r_showSkel", 2 ); + } else { + if ( m_showSkeleton ) { + cvarSystem->SetCVarInteger( "r_showSkel", 1 ); + } else { + cvarSystem->SetCVarInteger( "r_showSkel", 0 ); + } + } +} + +void DialogAFView::OnBnClickedCheckLinesDepthtest() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "r_debugLineDepthTest", m_debugLineDepthTest != FALSE ); +} + +void DialogAFView::OnBnClickedCheckLinesUsearrows() { + UpdateData(TRUE); + if ( m_debugLineUseArrows ) { + cvarSystem->SetCVarInteger( "r_debugArrowStep", 120 ); + } else { + cvarSystem->SetCVarInteger( "r_debugArrowStep", 0 ); + } +} + +void DialogAFView::OnBnClickedCheckPhysicsNofriction() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_skipFriction", m_noFriction != FALSE ); +} + +void DialogAFView::OnBnClickedCheckPhysicsNolimits() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_skipLimits", m_noLimits != FALSE ); +} + +void DialogAFView::OnBnClickedCheckPhysicsNogravity() { + UpdateData(TRUE); + cvarSystem->SetCVarFloat( "g_gravity", m_noGravity ? 0.0f : m_gravity ); +} + +void DialogAFView::OnBnClickedCheckPhysicsNoselfcollision() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_skipSelfCollision", m_noSelfCollision != FALSE ); +} + +void DialogAFView::OnBnClickedCheckPhysicsTiming() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "af_showTimings", m_showTimings != FALSE ); +} + +void DialogAFView::OnBnClickedCheckPhysicsDragEntities() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "g_dragEntity", m_dragEntity != FALSE ); +} + +void DialogAFView::OnBnClickedCheckPhysicsShowDragSelection() { + UpdateData(TRUE); + cvarSystem->SetCVarBool( "g_dragShowSelection", m_dragShowSelection != FALSE ); +} diff --git a/tools/af/DialogAFView.h b/tools/af/DialogAFView.h new file mode 100644 index 000000000..043d15696 --- /dev/null +++ b/tools/af/DialogAFView.h @@ -0,0 +1,93 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// DialogAFView dialog + +class DialogAFView : public CDialog { + + DECLARE_DYNAMIC(DialogAFView) + +public: + DialogAFView(CWnd* pParent = NULL); // standard constructor + virtual ~DialogAFView(); + + enum { IDD = IDD_DIALOG_AF_VIEW }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedCheckViewBodies(); + afx_msg void OnBnClickedCheckViewBodynames(); + afx_msg void OnBnClickedCheckViewBodyMass(); + afx_msg void OnBnClickedCheckViewTotalMass(); + afx_msg void OnBnClickedCheckViewInertiatensor(); + afx_msg void OnBnClickedCheckViewVelocity(); + afx_msg void OnBnClickedCheckViewConstraints(); + afx_msg void OnBnClickedCheckViewConstraintnames(); + afx_msg void OnBnClickedCheckViewPrimaryonly(); + afx_msg void OnBnClickedCheckViewLimits(); + afx_msg void OnBnClickedCheckViewConstrainedBodies(); + afx_msg void OnBnClickedCheckViewTrees(); + afx_msg void OnBnClickedCheckMd5Skeleton(); + afx_msg void OnBnClickedCheckMd5Skeletononly(); + afx_msg void OnBnClickedCheckLinesDepthtest(); + afx_msg void OnBnClickedCheckLinesUsearrows(); + afx_msg void OnBnClickedCheckPhysicsNofriction(); + afx_msg void OnBnClickedCheckPhysicsNolimits(); + afx_msg void OnBnClickedCheckPhysicsNogravity(); + afx_msg void OnBnClickedCheckPhysicsNoselfcollision(); + afx_msg void OnBnClickedCheckPhysicsTiming(); + afx_msg void OnBnClickedCheckPhysicsDragEntities(); + afx_msg void OnBnClickedCheckPhysicsShowDragSelection(); + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(DialogAFView) + BOOL m_showBodies; + BOOL m_showBodyNames; + BOOL m_showMass; + BOOL m_showTotalMass; + BOOL m_showInertia; + BOOL m_showVelocity; + BOOL m_showConstraints; + BOOL m_showConstraintNames; + BOOL m_showPrimaryOnly; + BOOL m_showLimits; + BOOL m_showConstrainedBodies; + BOOL m_showTrees; + BOOL m_showSkeleton; + BOOL m_showSkeletonOnly; + BOOL m_debugLineDepthTest; + BOOL m_debugLineUseArrows; + BOOL m_noFriction; + BOOL m_noLimits; + BOOL m_noGravity; + BOOL m_noSelfCollision; + BOOL m_showTimings; + BOOL m_dragEntity; + BOOL m_dragShowSelection; + //}}AFX_DATA + + float m_gravity; + + static toolTip_t toolTips[]; +}; diff --git a/tools/autoexp/autoexp.dat.change b/tools/autoexp/autoexp.dat.change deleted file mode 100644 index 14905760c..000000000 --- a/tools/autoexp/autoexp.dat.change +++ /dev/null @@ -1,148 +0,0 @@ -;------------------------------------------------------------------------------ -; ID Doom3 (idLib) types -;------------------------------------------------------------------------------ - -idStr{ - preview ( - #if ($c.data == 0) - ( - "[null_ptr]" - ) - #else - ( - [$c.data,s] - ) - ) -} - -idList<*>{ - children - ( - #( - [actual members]: [$c,!], - #if ($c.list == 0) - ( - $c.list - ) - #else - ( - #array - ( - expr: ($c.list)[$i], - size: $c.num - ) - ) - ) - ) - preview - ( - #if ($c.list == 0) - ( - "[null_ptr]" - ) - #else - ( - #( - "[", - $c.num, - "](", - #array - ( - expr: ($c.list)[$i], - size: $c.num - ), - ")" - ) - ) - ) -} - -idStaticList<*,*>{ - children - ( - #( - [actual members]: [$c,!], - #array - ( - expr: ($c.list)[$i], - size: $c.num - ) - ) - ) - preview - ( - #( - "[", - $c.num, - "](", - #array - ( - expr: ($c.list)[$i], - size: $c.num - ), - ")" - ) - ) -} - -idHashIndex{ - children - ( - #( - [actual members]: [$c,!], - #if ( $c.hash != $c.INVALID_INDEX ) - ( - #( - [hash]: (_idHashIndex_showarray_helper*)(&($c.hashSize)), - [index]: (_idHashIndex_showarray_helper*)(&($c.indexSize)) - ) - ) - ) - ) -} -_idHashIndex_showarray_helper{ - children - ( - #array - ( - expr: $c.ptr[$i], - size: $c.size - ) - ) -} - - -idKeyValue{ - children ( - #( - [actual members]: [$c,!], - key: (idStr*)($c.key), - value: (idStr*)($c.value) - ) - ) - preview ( - #( - "{key=", - (idStr*)($c.key), - " value=", - (idStr*)($c.value), - "}" - ) - ) -} - -idDict{ - children ( - #( - [actual members]: [$c,!], - [elements]: $c.args - ) - ) - preview ( - $c.args - ) -} - -;------------------------------------------------------------------------------ -; end of custom templates -;------------------------------------------------------------------------------ diff --git a/tools/autoexp/readme.txt b/tools/autoexp/readme.txt deleted file mode 100644 index 4c6abf2a6..000000000 --- a/tools/autoexp/readme.txt +++ /dev/null @@ -1,11 +0,0 @@ -To install the TDM autoexp tamplates follow the steps: - -1. Find the "autoexp.dat" file in your MSVS. -It is usually located in somewhere like: -"C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\autoexp.dat" - -2. In the "autoexp.dat" file find the line with: -"[Visualizer]" - -3. Copy the contents of "autoexp.dat.change" file -into your "autoexp.dat" file AFTER that line. diff --git a/tools/comafx/CDIB.cpp b/tools/comafx/CDIB.cpp new file mode 100644 index 000000000..687d041ad --- /dev/null +++ b/tools/comafx/CDIB.cpp @@ -0,0 +1,1013 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#ifdef ID_DEBUG_MEMORY +#undef new +#endif + +#include "math.h" +#include "CDIB.h" + +// Original ColorPicker/DIB source by Rajiv Ramachandran +// included with Permission from the author + +#define BIG_DISTANCE 10000000L + +#define DIST(r1,g1,b1,r2,g2,b2) \ + (long) (3L*(long)((r1)-(r2))*(long)((r1)-(r2)) + \ + 4L*(long)((g1)-(g2))*(long)((g1)-(g2)) + \ + 2L*(long)((b1)-(b2))*(long)((b1)-(b2))) + + +static unsigned char masktable[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; + + + +CDIB::CDIB(HANDLE hDib,int nBits) +{ + m_pVoid = NULL; + m_pLinePtr = NULL; + m_bUseGamma=FALSE; + width=height=0; + if(hDib) + { + CreateFromHandle(hDib,nBits); + } +} + +CDIB::~CDIB() +{ + DestroyDIB(); +} + +void CDIB::DestroyDIB() +{ + if(m_pVoid) free(m_pVoid); + m_pVoid = NULL; + if(m_pLinePtr) free(m_pLinePtr); + m_pLinePtr = NULL; +} + + +BOOL CDIB::Create(int width,int height,int bits) +{ + /* + Free existing image + */ + DestroyDIB(); +// ASSERT(bits == 24 || bits == 8); + +BITMAPINFOHEADER bmInfo; + + memset(&bmInfo,0,sizeof(BITMAPINFOHEADER)); + bmInfo.biSize = sizeof(BITMAPINFOHEADER); + bmInfo.biWidth = width; + bmInfo.biHeight = height; + bmInfo.biPlanes = 1; + bmInfo.biBitCount = bits; + bmInfo.biCompression = BI_RGB; + return Create(bmInfo); +} + +BOOL CDIB::Create(BITMAPINFOHEADER& bmInfo) +{ + bytes = (bmInfo.biBitCount*bmInfo.biWidth)>>3; + height = bmInfo.biHeight; + width = bmInfo.biWidth; +// bmInfo.biHeight *= -1; + while(bytes%4) bytes++; + + int size; + size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(bmInfo) + bytes*height; + m_pVoid = (void *)malloc(size); + if(!m_pVoid) return FALSE; + + m_pInfo = (PBITMAPINFO )m_pVoid; + memcpy((void *)&m_pInfo->bmiHeader,(void *)&bmInfo,sizeof(BITMAPINFOHEADER)); + m_pRGB = (RGBQUAD *)((unsigned char *)m_pVoid + sizeof(BITMAPINFOHEADER)) ; + m_pBits = (unsigned char *)(m_pVoid) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(); + +int i; +BYTE **ptr; + m_pLinePtr = (BYTE **)malloc(sizeof(BYTE *)*height); + if(!m_pLinePtr) return FALSE; + for(i=0,ptr=m_pLinePtr; i < height; i++,ptr++) + { + //*ptr = (int)(m_pBits)+(i*bytes); + //*ptr = (int)GetLinePtr(i); + *ptr = m_pBits + (height-i-1)*bytes; + } + m_nFlags = 0; + return TRUE; +} + +void CDIB::SetPalette(unsigned char *palette) +{ +int i,size; +RGBQUAD *rgb; + if(!palette) return; + size = GetPaletteSize(); + for(i=0,rgb = m_pRGB; i < size; i++,rgb++,palette+=3) + { + if(m_bUseGamma) + { + rgb->rgbRed = Gamma[palette[0]]; + rgb->rgbGreen = Gamma[palette[1]]; + rgb->rgbBlue = Gamma[palette[2]]; + } + else + { + rgb->rgbRed = palette[0]; + rgb->rgbGreen = palette[1]; + rgb->rgbBlue = palette[2]; + } + rgb->rgbReserved = (BYTE)0; + } +} + +void CDIB::SetPalette(RGBQUAD *pRGB) +{ +int size; + if(!pRGB) return; + size = GetPaletteSize(); + memcpy(m_pRGB,pRGB,size*sizeof(RGBQUAD)); +} + + +int CDIB::GetPaletteSize() +{ + return GetPaletteSize(m_pInfo->bmiHeader); +} + + +int CDIB::GetPaletteSize(BITMAPINFOHEADER& bmInfo) +{ + switch(bmInfo.biBitCount) + { + case 1: + return 2; + case 4: + return 16; + case 8: + return 256; + default: + return 0; + } +} + + +void CDIB::SetPixel(int x,int y,COLORREF color) +{ +unsigned char *ptr; + ASSERT(x >= 0 && y >=0); + ASSERT(x < width && y < height); + +// ptr = m_pBits + (y*bytes) + x * 3; + ptr = (unsigned char *)m_pLinePtr[y]; + ptr += x*3; + *ptr++ = (unsigned char)GetBValue(color); + *ptr++ = (unsigned char)GetGValue(color); + *ptr++ = (unsigned char)GetRValue(color); +} + +void CDIB::SetPixel8(int x,int y,unsigned char color) +{ +unsigned char *ptr,*aptr; + ASSERT(x >= 0 && y >=0); + ASSERT(x < width && y < height); + +// ptr = m_pBits + (y*bytes) + x ; +// ptr = (unsigned char *)m_pLinePtr[y] ; + ptr = GetLinePtr(y); + aptr = ptr; + ptr += x; + *ptr = color; +} + + +COLORREF CDIB::GetPixel(int x,int y) +{ +unsigned char *ptr; +COLORREF color; + ASSERT(x >= 0 && y >=0); + ASSERT(x < width && y < height); + +// ptr = m_pBits + (y*bytes) + x * 3; + ptr = GetLinePtr(y); + ptr += (x*3); + color = RGB(*(ptr+2),*(ptr+1),*ptr); + return color; +} + +CBitmap *CDIB::GetTempBitmap(CDC& dc) +{ +HBITMAP hBitmap; +CBitmap *temp; + ASSERT(m_pVoid != NULL); + hBitmap = CreateDIBitmap(dc.m_hDC, + (PBITMAPINFOHEADER)m_pInfo, + CBM_INIT, + (const void *)m_pBits, + m_pInfo, + DIB_RGB_COLORS); + + if(hBitmap == NULL) return NULL; + temp = CBitmap::FromHandle(hBitmap); + return temp; +} + +CBitmap *CDIB::GetBitmap(CDC& dc) +{ +HBITMAP hBitmap; +CBitmap *temp; + ASSERT(m_pVoid != NULL); + hBitmap = CreateDIBitmap(dc.m_hDC, + (PBITMAPINFOHEADER)m_pInfo, + CBM_INIT, + (const void *)m_pBits, + m_pInfo, + DIB_RGB_COLORS); + + if(hBitmap == NULL) return NULL; + temp = CBitmap::FromHandle(hBitmap); + if(temp) + { + BITMAP bmp; + LPVOID lpVoid; + temp->GetBitmap(&bmp); + lpVoid = malloc(bmp.bmWidthBytes*bmp.bmHeight); + if(!lpVoid) return NULL; + temp->GetBitmapBits(bmp.bmWidthBytes*bmp.bmHeight,lpVoid); + CBitmap *newBmp = new CBitmap; + newBmp->CreateBitmapIndirect(&bmp); + newBmp->SetBitmapBits(bmp.bmWidthBytes*bmp.bmHeight,lpVoid); + free(lpVoid); + return newBmp; + } + else return NULL; + +} + +void CDIB::CopyLine(int source,int dest) +{ +unsigned char *src,*dst; + ASSERT(source <= height && source >= 0); + ASSERT(dest <= height && dest >= 0); + if(source == dest) return; + src = GetLinePtr(source); + dst = GetLinePtr(dest); + memcpy(dst,src,bytes); +} + +void CDIB::InitDIB(COLORREF color) +{ +int i,j; +unsigned char *ptr; + + if(m_pInfo->bmiHeader.biBitCount == 24) + { + unsigned char col[3]; + col[0]=GetBValue(color); + col[1]=GetGValue(color); + col[2]=GetRValue(color); + for(i=0,ptr = m_pBits; i < height; i++) + { + ptr = m_pBits + i*bytes; + for(j=0; j < width ; j++,ptr+=3) + { + memcpy(ptr,col,3); + } + } + } + else + { + for(i=0,ptr = m_pBits; i < height; i++,ptr+=bytes) + { + memset(ptr,(BYTE)color,bytes); + } + } +} + + +void CDIB::BitBlt(HDC hDest,int nXDest,int nYDest,int nWidth,int nHeight,int xSrc,int ySrc) +{ + SetDIBitsToDevice(hDest,nXDest,nYDest,nWidth,nHeight,xSrc,Height()-ySrc-nHeight,0,Height(),m_pBits,m_pInfo,DIB_RGB_COLORS); +} + +void CDIB::StretchBlt(HDC hDest,int nXDest,int nYDest,int nDWidth,int nDHeight,int xSrc,int ySrc,int nSWidth,int nSHeight) +{ + int err; + err = StretchDIBits(hDest,nXDest,nYDest,nDWidth,nDHeight,xSrc,ySrc,nSWidth,nSHeight,m_pBits,(CONST BITMAPINFO * )&m_pInfo->bmiHeader,DIB_RGB_COLORS,SRCCOPY); +} + +void CDIB::ExpandBlt(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight) +{ + SetPalette(dibSrc.m_pRGB); + + nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth; + nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight; + + Expand(nXDest,nYDest,xRatio,yRatio,dibSrc,xSrc,ySrc,nSWidth,nSHeight); +} + +void CDIB::Expand(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight) +{ +int xNum,yNum,xErr,yErr; +int nDWidth,nDHeight; + + nDWidth = nSWidth*xRatio; + nDHeight = nSHeight*yRatio; + + nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ; + nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight; + + xNum = nDWidth/xRatio; + yNum = nDHeight/yRatio; + xErr = nDWidth%xRatio; + yErr = nDHeight%yRatio; + +unsigned char *buffer,*srcPtr,*destPtr,*ptr; +int i,j,k; + + buffer = (unsigned char *)malloc(nDWidth+20); + if(!buffer) return; + + for(i=0; i < yNum; i++,ySrc++) + { + srcPtr = dibSrc.GetLinePtr(ySrc) + xSrc; + ptr = buffer; + for(j=0; j < xNum; j++,ptr+=xRatio) + { + memset(ptr,*(srcPtr+j),xRatio); + k=*(srcPtr+j); + } + memset(ptr,(unsigned char)k,xErr); + for(j=0; j < yRatio ; j++,nYDest++) + { + destPtr = GetLinePtr(nYDest) + nXDest; + memcpy(destPtr,buffer,nDWidth); + } + } + for(j=0; j < yErr; j++,nYDest++) + { + destPtr = GetLinePtr(nYDest) + nXDest; + memcpy(destPtr,buffer,nDWidth); + } + free(buffer); +} + +void CDIB::StretchBlt(int nXDest,int nYDest,int nDWidth,int nDHeight,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight) +{ + SetPalette(dibSrc.m_pRGB); + nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ; + nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight; + + nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth; + nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight; + +int xDiv,yDiv; +int xMod,yMod; + + xDiv = nDWidth/nSWidth; + xMod = nDWidth%nSWidth; + + yDiv = nDHeight/nSHeight; + yMod = nDHeight%nSHeight; + + if(!xMod && !yMod && xDiv > 0 && yDiv > 0) + { + ExpandBlt(nXDest,nYDest,xDiv,yDiv,dibSrc,xSrc,ySrc,nSWidth,nSHeight); + return; + } + +unsigned char *tempPtr,*srcPix,*destPix,*q; + tempPtr = (unsigned char *)malloc(nDWidth+20); +int i,j,k,l,x,y,m; +int xErr,yErr; + for(i=yErr=m=0; i < nSHeight; i++) + { + srcPix = dibSrc.GetLinePtr(i+ySrc) + xSrc; + q = tempPtr; + for(j=l=xErr=0; j < nSWidth; j++,srcPix++) + { + k = xDiv; + xErr += xMod; + if(xErr >= nSWidth) + { + k++; + xErr%=nSWidth; + } + x=0; + while(l < nDWidth && x < k) + { + *q++ = *srcPix; + l++; + x++; + } + } + while(l < nDWidth) + { + *q++=*srcPix; + l++; + } + k= yDiv; + yErr += yMod; + if(yErr >= nSHeight) + { + k++; + yErr%=nSHeight; + } + y=0; + while(m < nDHeight && y < k) + { + destPix = GetLinePtr(m+nYDest) + nXDest; + memcpy(destPix,tempPtr,nDWidth); + m++; + y++; + } + } + while(m < nDHeight ) + { + destPix = GetLinePtr(m+nYDest) + nXDest; + memcpy(destPix,tempPtr,nDWidth); + m++; + } + free(tempPtr); +} + +void CDIB::BitBlt(int nXDest,int nYDest,int nWidth,int nHeight,CDIB& dibSrc,int nSrcX,int nSrcY,BYTE *colors) +{ + SetPalette(dibSrc.m_pRGB); + if(nXDest < 0) + { + nSrcX -= nXDest; + nWidth += nXDest; + nXDest=0; + } + if(nYDest < 0) + { + nSrcY -= nYDest; + nHeight += nYDest; + nYDest=0; + } + if(nSrcX < 0) + { + nXDest -= nSrcX; + nWidth += nSrcX; + nSrcX=0; + } + if(nSrcY < 0) + { + nYDest -= nSrcY; + nHeight += nSrcY; + nSrcY=0; + } + nWidth = nXDest+nWidth > width ? width-nXDest : nWidth ; + nHeight = nYDest+nHeight > height ? height-nYDest : nHeight; + + nWidth = nSrcX+nWidth > dibSrc.width ? dibSrc.width-nSrcX : nWidth; + nHeight = nSrcY+nHeight > dibSrc.height? dibSrc.height-nSrcY : nHeight; + + nWidth = __max(0,nWidth); + nHeight = __max(0,nHeight); +int i,k,l,j; +unsigned char *srcPtr,*destPtr; + if(!colors) + { + for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++) + { + if(k < 0 || l < 0) + { + continue; + } + else + { + srcPtr = dibSrc.GetLinePtr(k); + destPtr = GetLinePtr(l); + memcpy(destPtr+nXDest,srcPtr+nSrcX,nWidth); + } + } + } + else + { + for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++) + { + if(k < 0 || l < 0) + { + continue; + } + else + { + srcPtr = dibSrc.GetLinePtr(k)+nXDest; + destPtr = GetLinePtr(l)+nSrcX; + for(j=0; j < nWidth; j++,srcPtr++,destPtr++) + { + if(colors[*srcPtr]) *destPtr=*srcPtr; + } + } + } + } +} + +unsigned char *CDIB::GetLinePtr(int line) +{ +/*unsigned char *ptr; + ptr = m_pBits + (height-line-1)*bytes; + return ptr;*/ + return m_pLinePtr[line]; +} + +BOOL CDIB::CopyDIB(CDIB& dib) +{ + if(Create(dib.m_pInfo->bmiHeader)) + { + SetPalette(dib.m_pRGB); + memcpy(m_pBits,dib.m_pBits,height*bytes); + return TRUE; + } + return FALSE; +} + +void CDIB::ReplaceColor(unsigned char oldColor,unsigned char newColor) +{ +int i,j; +unsigned char *ptr; + for(i=0; i < height; i++) + { + ptr = GetLinePtr(i); + for(j=0; j < width; j++) + { + if(ptr[j] == oldColor) ptr[j] = newColor; + } + } +} + + +CDIB& CDIB::operator=(CDIB& dib) +{ + CopyDIB(dib); + return *this; +} + +HANDLE CDIB::GetDIBits(int nStartX,int nStartY,int nCx,int nCy) +{ + if(nStartX == -1) + { + nStartX = nStartY=0; + nCx = width; + nCy = height; + CDIB dib; + dib.Create(nCx,nCy,8); + dib.BitBlt(0,0,nCx,nCy,*this,0,0); + dib.SetPalette(m_pRGB); + return dib.DIBHandle(); + } + return DIBHandle(); +} + +DWORD CDIB::GetDIBSize() +{ + return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize() + bytes*height; +} + +HANDLE CDIB::DIBHandle() +{ +int nSize; +HANDLE hMem; + nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize() + bytes*height; + hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,nSize); + if(hMem == NULL) return NULL; +UCHAR *lpVoid,*pBits; +LPBITMAPINFOHEADER pHead; +RGBQUAD *pRgb; + lpVoid = (UCHAR *)GlobalLock(hMem); + pHead = (LPBITMAPINFOHEADER )lpVoid; + memcpy(pHead,&m_pInfo->bmiHeader,sizeof(BITMAPINFOHEADER)); + pRgb = (RGBQUAD *)(lpVoid + sizeof(BITMAPINFOHEADER) ); + memcpy(pRgb,m_pRGB,sizeof(RGBQUAD)*GetPaletteSize()); + pBits = lpVoid + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(); + memcpy(pBits,m_pBits,height*bytes); + GlobalUnlock(lpVoid); + return hMem; +} + +BOOL CDIB::CreateFromHandle(HANDLE hMem,int bits) +{ + DestroyDIB(); +UCHAR *lpVoid,*pBits; +LPBITMAPINFOHEADER pHead; +RGBQUAD *pRgb; + lpVoid = (UCHAR *)GlobalLock(hMem); + pHead = (LPBITMAPINFOHEADER )lpVoid; + width = pHead->biWidth; + height = pHead->biHeight; + m_nBits = pHead->biBitCount; + if(pHead->biCompression != BI_RGB) + { + GlobalUnlock(lpVoid); + return FALSE; + } + if(pHead->biBitCount >= 15) + { + if(pHead->biBitCount != 24) + { + GlobalUnlock(lpVoid); + return FALSE; + } + } + if(!Create(*pHead)) + { + GlobalUnlock(lpVoid); + return FALSE; + } + pRgb = (RGBQUAD *)(lpVoid + sizeof(BITMAPINFOHEADER) ); + memcpy(m_pRGB,pRgb,sizeof(RGBQUAD)*GetPaletteSize()); + pBits = lpVoid + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(); + memcpy(m_pBits,pBits,height*bytes); + GlobalUnlock(lpVoid); + return TRUE; +} + +void CDIB::UseGamma(float fg,BOOL bUse) +{ + m_bUseGamma = bUse; + m_fOldGamma = m_fGamma; + m_fGamma = fg; + CreateGammaCurve(); +} + + +void CDIB::CreateGammaCurve() +{ +int i; + for(i=0;i<256;++i) + { + Gamma[i]=(int)(255 * powf((double)i/255,m_fGamma) + (double)0.5); + } +} + + + +void CDIB::GetPixel(UINT x,UINT y,int& pixel) +{ + ASSERT(x < (UINT)Width()); + ASSERT(y < (UINT)Height()); + if(x >= (UINT)Width()) return; + if(y >= (UINT)Height()) return; + pixel=(GetLinePtr(y))[x]; +} + +BOOL CDIB::Make8Bit(CDIB& dib) +{ +int nBits; + ASSERT(Width() == dib.Width()); + ASSERT(Height() == dib.Height()); + nBits = dib.GetBitCount(); + switch(nBits) + { + case 1: + return SwitchFromOne(dib); + break; + case 4: + return SwitchFromFour(dib); + break; + case 8: + return SwitchPalette(dib); + break; + case 24: + return SwitchFrom24(dib); + break; + default: + return FALSE; + } + return FALSE; +} + +/* +BOOL CDIB::SwitchFrom24(CDIB& dib) +{ +int i,j,w,h; +unsigned char *sPtr,*dPtr; + w = Width(); + h = Height(); + memset(CachePtr,0,sizeof(CachePtr)); + for(i=0; i < h; i++) + { + dPtr = GetLinePtr(i); + sPtr = dib.GetLinePtr(i); + for(j=0 ; j < w; j++,dPtr++,sPtr+=3) + { + *dPtr = ClosestColor((RGBQUAD *)sPtr); + } + } + return TRUE; +} +*/ + + +BOOL CDIB::SwitchFromOne(CDIB& dib) +{ +int i,j,w,h; +unsigned char *sPtr,*dPtr; +unsigned char cols[2]; + w = Width(); + h = Height(); + memset(CachePtr,0,sizeof(CachePtr)); + cols[0]=ClosestColor(dib.m_pRGB); + cols[1]=ClosestColor(dib.m_pRGB+1); + for(i=0; i < h; i++) + { + dPtr = GetLinePtr(i); + sPtr = dib.GetLinePtr(i); + for(j=0 ; j < w; j++,dPtr++) + { + if(!(sPtr[j>>3] & masktable[j&7])) *dPtr = cols[0]; + else *dPtr = cols[1]; + } + } + return TRUE; +} + +BOOL CDIB::SwitchFromFour(CDIB& dib) +{ +int i,n,j,w,h; +unsigned char *sPtr,*dPtr; +unsigned char cols[16]; + w = Width(); + h = Height(); + memset(CachePtr,0,sizeof(CachePtr)); + for(i=0; i < 16; i++) + { + cols[i]=ClosestColor(dib.m_pRGB+i); + } + for(i=0; i < h; i++) + { + dPtr = GetLinePtr(i); + sPtr = dib.GetLinePtr(i); + for(j=0 ; j < w; j++,dPtr++) + { + if(!(j&1)) n = (*sPtr & 0xf0)>>4; + else + { + n = *sPtr & 0x0f; + sPtr++; + } + *dPtr = cols[n]; + } + } + return TRUE; +} + +BOOL CDIB::SwitchPalette(CDIB& dib) +{ +int i,j,w,h; +unsigned char *sPtr,*dPtr; +unsigned char cols[256]; + w = Width(); + h = Height(); + memset(CachePtr,0,sizeof(CachePtr)); + for(i=0; i < 256; i++) + { + cols[i]=ClosestColor(dib.m_pRGB+i); + } + for(i=0; i < h; i++) + { + dPtr = GetLinePtr(i); + sPtr = dib.GetLinePtr(i); + for(j=0 ; j < w; j++,sPtr++,dPtr++) + { + *dPtr = cols[*sPtr]; + } + } + return TRUE; +} + + +int CDIB::ClosestColor(RGBQUAD *pRgb) +{ +unsigned int dist=BIG_DISTANCE,i,d,c; +RGBQUAD *pQuad=m_pRGB; +unsigned int pSize=GetPaletteSize(); + for(i=0; i < pSize;i++) + { + if(CachePtr[i]) + { + if(!memcmp((void *)&CacheQuad[i],(void *)pRgb,3)) + { + return i; + } + } + } + for(i=0; i < pSize; i++,pQuad++) + { + d = Distance(*pRgb,*pQuad); + if(!d) + { + CacheQuad[i]=*pRgb; + CachePtr[i]=1; + return i; + } + if(dist > d) + { + c = i; + dist = d; + } + } + CacheQuad[c]=*pRgb; + CachePtr[c]=1; + return c; +} + +unsigned int CDIB::Distance(RGBQUAD& rgb1,RGBQUAD& rgb2) +{ +unsigned int d; + d = 3*(unsigned)((rgb1.rgbRed)-(rgb2.rgbRed))*(unsigned)((rgb1.rgbRed)-(rgb2.rgbRed)); + d += 4*(unsigned)((rgb1.rgbGreen)-(rgb2.rgbGreen))*(unsigned)((rgb1.rgbGreen)-(rgb2.rgbGreen)) ; + d += 2*(unsigned)((rgb1.rgbBlue)-(rgb2.rgbBlue))*(unsigned)((rgb1.rgbBlue)-(rgb2.rgbBlue)); + return d; +} + +BOOL CDIB::OpenDIB(CString& csFileName) +{ +CFile file; + if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary)) + { + return FALSE; + } + file.Close(); + if(OpenBMP(csFileName)) return TRUE; + return FALSE; +} + + + +BOOL CDIB::SaveDIB(CString& csFileName,BitmapType type) +{ +CFile file; + if(!file.Open(csFileName,CFile::modeCreate | CFile::typeBinary)) + { + return FALSE; + } + file.Close(); + switch(type) + { + case BMP: + return SaveBMP(csFileName); + default: + return FALSE; + } + return FALSE; +} + +BOOL CDIB::SaveBMP(CString& csFileName) +{ +BITMAPFILEHEADER bFile; +CFile file; + if(!file.Open(csFileName,CFile::modeWrite | CFile::typeBinary)) + { + return FALSE; + } + ::ZeroMemory(&bFile,sizeof(bFile)); + memcpy((void *)&bFile.bfType,"BM",2); + bFile.bfSize = GetDIBSize() + sizeof(bFile); + bFile.bfOffBits = sizeof(BITMAPINFOHEADER) + GetPaletteSize()*sizeof(RGBQUAD) + sizeof(BITMAPFILEHEADER); + file.Write(&bFile,sizeof(bFile)); + file.Write(m_pVoid,GetDIBSize()); + file.Close(); + return TRUE; + +} + +BOOL CDIB::OpenBMP(CString& csFileName) +{ +BITMAPFILEHEADER bFile; +BITMAPINFOHEADER head; +CFile file; + if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary)) + { + return FALSE; + } + file.Read(&bFile,sizeof(bFile)); + if(memcmp((void *)&bFile.bfType,"BM",2)) + { + file.Close(); + return FALSE; + } + file.Read(&head,sizeof(head)); + if(!Create(head)) + { + file.Close(); + return FALSE; + } + file.Read(m_pRGB,sizeof(RGBQUAD)*GetPaletteSize()); + file.Seek(bFile.bfOffBits,CFile::begin); + file.Read(m_pBits,height*bytes); + file.Close(); + return TRUE; + +} + + +int CDIB::CountColors() +{ + ASSERT(GetBitCount()==8); +BYTE colors[256],*ptr; +int nNum=0,i,j,w,d; + w = Width(); + d = Height(); + memset(colors,0,256); + for(i=0; i < d; i++) + { + ptr = GetLinePtr(i); + for(j=0; j < w; j++,ptr++) + { + if(!colors[*ptr]) + { + colors[*ptr]=1; + nNum++; + } + } + } + return nNum; +} + +int CDIB::EnumColors(BYTE *array) +{ + ASSERT(GetBitCount()==8); +BYTE *ptr; +int nNum=0,i,j,w,d; + w = Width(); + d = Height(); + memset(array,0,256); + for(i=0; i < d; i++) + { + ptr = GetLinePtr(i); + for(j=0; j < w; j++,ptr++) + { + if(!array[*ptr]) + { + array[*ptr]=1; + nNum++; + } + } + } + return nNum; +} + +COLORREF CDIB::PaletteColor(int nIndex) +{ + ASSERT(nIndex < 256); +RGBQUAD *pRGB= m_pRGB+nIndex; + return RGB(pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue); +} + +BOOL CDIB::SwitchFrom24(CDIB& dib) +{ +int i,j,w,h,c; +unsigned char *sPtr,*dPtr; +BYTE *index_ptr=NULL; +RGBQUAD rgb; + w = Width(); + h = Height(); + index_ptr = (BYTE *)malloc(0x7FFF+1); + if(!index_ptr) return FALSE; + memset(CachePtr,0,sizeof(CachePtr)); + for(i=0; i <= 0x7FFF; i++) + { + rgb.rgbRed = (((i & 0x7C00)>>10) << 3) | 0x07; + rgb.rgbGreen = (((i & 0x3e0)>>5) << 3) | 0x07; + rgb.rgbBlue = ((i & 0x1F)<<3) | 0x07; + index_ptr[i] = ClosestColor(&rgb); + } + for(i=0; i < h; i++) + { + dPtr = GetLinePtr(i); + sPtr = dib.GetLinePtr(i); + for(j=0 ; j < w; j++,dPtr++,sPtr+=3) + { + c = (*sPtr >> 3) | ((*(sPtr+1) >> 3) << 5) | ((*(sPtr+2) >> 3) << 10); + *dPtr = index_ptr[c]; + } + } + free(index_ptr); + return TRUE; +} diff --git a/tools/comafx/CDIB.h b/tools/comafx/CDIB.h new file mode 100644 index 000000000..db54e5796 --- /dev/null +++ b/tools/comafx/CDIB.h @@ -0,0 +1,112 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CDIB__ +#define __CDIB__ + +// Original ColorPicker/DIB source by Rajiv Ramachandran +// included with permission from the author + +class CDIB { +public: + enum BitmapType { + BMP, + GIF, + TIFF + }; + CDIB( HANDLE hDib = NULL,int nBits = 8 ); + virtual ~CDIB(); + + CDIB & operator=( CDIB& dib ); + BOOL IsValid() { return ( m_pVoid && Width() && Height() ); } + void UseGamma( float fg, BOOL bUse = TRUE ); + BOOL CreateFromHandle( HANDLE hDib, int nBits ); + BOOL Create( int width, int height, int bits = 24 ); + BOOL Create( BITMAPINFOHEADER& bmInfo ); + BOOL CopyDIB( CDIB& dib ); + BOOL OpenDIB( CString &fileName ); + BOOL SaveDIB( CString &fileName, BitmapType type ); + void ReplaceColor(unsigned char oldColor,unsigned char newColor); + HANDLE GetDIBits(int nStartX=-1,int nStartY=-1,int nCx=-1,int nCy=-1); + CBitmap * GetBitmap(CDC& dc); + CBitmap * GetTempBitmap(CDC& dc); + DWORD GetDIBSize(); + int GetPaletteSize(BITMAPINFOHEADER& bmInfo); + int GetPaletteSize(); + int CountColors(); + int EnumColors(BYTE *colors); + void InitDIB(COLORREF color); + void CopyLine(int source,int dest); + void DestroyDIB(); + void SetPalette(unsigned char *palette); + void SetPalette(RGBQUAD *pRGB); + COLORREF PaletteColor(int index); + void SetPixel(int x,int y,COLORREF color); + void SetPixel8(int x,int y,unsigned char color); + COLORREF GetPixel(int x,int y); + void GetPixel(UINT x,UINT y,int& pixel); + void BitBlt(HDC hDest,int nXDest,int nYDest,int nWidth,int nHeight,int xSrc,int ySrc); + void BitBlt(int nXDest,int nYDest,int nWidth,int nHeight,CDIB& dibSrc,int nSrcX,int nSrcY,BYTE *colors=NULL); + void StretchBlt(HDC hDest,int nXDest,int nYDest,int nDWidth,int nDHeight,int xSrc,int ySrc,int nSWidth,int nSHeight); + void StretchBlt(int nXDest,int nYDest,int nDWidth,int nDHeight,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight); + void ExpandBlt(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight); + void SetFlags(int flag) { m_nFlags = flag; } + int Height() { return height ; } + int Width() { return width ; } + unsigned char *GetLinePtr(int line); + inline int GetBitCount() { return m_pInfo->bmiHeader.biBitCount; } + BOOL Make8Bit( CDIB &dib ); + BOOL SwitchFromOne( CDIB &dib ); + BOOL SwitchFromFour( CDIB &dib ); + BOOL SwitchFrom24( CDIB &dib ); + BOOL SwitchPalette( CDIB &dib ); + int ClosestColor(RGBQUAD *pRgb ); + LPBITMAPINFO GetBitmapInfo() { return m_pInfo; } + static unsigned int Distance( RGBQUAD& rgb1, RGBQUAD& rgb2 ); + +protected: + HANDLE DIBHandle(); + BOOL OpenBMP( CString &csFileName ); + BOOL OpenGIF( CString &csFileName ); + BOOL OpenTIFF( CString &csFileName ); + BOOL SaveBMP( CString &csFileName ); + BOOL SaveGIF( CString &csFileName ); + BOOL SaveTIFF( CString &csFileName ); + void CreateGammaCurve(); + void Expand( int nXDest, int nYDest, int xRatio, int yRatio, CDIB &dibSrc, int xSrc, int ySrc, int nSWidth, int nSHeight ); + + unsigned char * m_pBits; + PBITMAPINFO m_pInfo; + RGBQUAD * m_pRGB; + void * m_pVoid; + BYTE ** m_pLinePtr; + int height; + int bytes; + int width; + int m_nBits; + int m_nFlags; + BOOL m_bUseGamma; + float m_fGamma; + float m_fOldGamma; + unsigned char Gamma[256]; + RGBQUAD CacheQuad[256]; + char CachePtr[256]; +}; + +#endif /* !__CDIB__ */ diff --git a/tools/comafx/CPathTreeCtrl.cpp b/tools/comafx/CPathTreeCtrl.cpp new file mode 100644 index 000000000..1ea816f6f --- /dev/null +++ b/tools/comafx/CPathTreeCtrl.cpp @@ -0,0 +1,296 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "CPathTreeCtrl.h" + + +/* +================ +CPathTreeCtrl::CPathTreeCtrl +================ +*/ +CPathTreeCtrl::CPathTreeCtrl() { +} + +/* +================ +CPathTreeCtrl::~CPathTreeCtrl +================ +*/ +CPathTreeCtrl::~CPathTreeCtrl() { +} + +/* +================ +CPathTreeCtrl::PreSubclassWindow +================ +*/ +void CPathTreeCtrl::PreSubclassWindow() { + CTreeCtrl::PreSubclassWindow(); + EnableToolTips( TRUE ); +} + +/* +================ +CPathTreeCtrl::FindItem + +Find the given path in the tree. +================ +*/ +HTREEITEM CPathTreeCtrl::FindItem( const idStr &pathName ) { + int lastSlash; + idStr path, tmpPath, itemName; + HTREEITEM item, parentItem; + + parentItem = NULL; + item = GetRootItem(); + + lastSlash = pathName.Last( '/' ); + + while( item && lastSlash > path.Length() ) { + itemName = GetItemText( item ); + tmpPath = path + itemName; + if ( pathName.Icmpn( tmpPath, tmpPath.Length() ) == 0 ) { + parentItem = item; + item = GetChildItem( item ); + path = tmpPath + "/"; + } else { + item = GetNextSiblingItem( item ); + } + } + + for ( item = GetChildItem( parentItem ); item; item = GetNextSiblingItem( item ) ) { + itemName = GetItemText( item ); + if ( pathName.Icmp( path + itemName ) == 0 ) { + return item; + } + } + + return NULL; +} + +/* +================ +CPathTreeCtrl::InsertPathIntoTree + +Inserts a new item going from the root down the tree only creating paths where necessary. +This is slow and should only be used to insert single items. +================ +*/ +HTREEITEM CPathTreeCtrl::InsertPathIntoTree( const idStr &pathName, const int id ) { + int lastSlash; + idStr path, tmpPath, itemName; + HTREEITEM item, parentItem; + + parentItem = NULL; + item = GetRootItem(); + + lastSlash = pathName.Last( '/' ); + + while( item && lastSlash > path.Length() ) { + itemName = GetItemText( item ); + tmpPath = path + itemName; + if ( pathName.Icmpn( tmpPath, tmpPath.Length() ) == 0 ) { + parentItem = item; + item = GetChildItem( item ); + path = tmpPath + "/"; + } else { + item = GetNextSiblingItem( item ); + } + } + + while( lastSlash > path.Length() ) { + pathName.Mid( path.Length(), pathName.Length(), tmpPath ); + tmpPath.Left( tmpPath.Find( '/' ), itemName ); + parentItem = InsertItem( itemName, parentItem ); + path += itemName + "/"; + } + + pathName.Mid( path.Length(), pathName.Length(), itemName ); + item = InsertItem( itemName, parentItem, TVI_SORT ); + SetItemData( item, id ); + + return item; +} + +/* +================ +CPathTreeCtrl::AddPathToTree + +Adds a new item to the tree. +Assumes new paths after the current stack path do not yet exist. +================ +*/ +HTREEITEM CPathTreeCtrl::AddPathToTree( const idStr &pathName, const int id, idPathTreeStack &stack ) { + int lastSlash; + idStr itemName, tmpPath; + HTREEITEM item; + + lastSlash = pathName.Last( '/' ); + + while( stack.Num() > 1 ) { + if ( pathName.Icmpn( stack.TopName(), stack.TopNameLength() ) == 0 ) { + break; + } + stack.Pop(); + } + + while( lastSlash > stack.TopNameLength() ) { + pathName.Mid( stack.TopNameLength(), pathName.Length(), tmpPath ); + tmpPath.Left( tmpPath.Find( '/' ), itemName ); + item = InsertItem( itemName, stack.TopItem() ); + stack.Push( item, itemName ); + } + + pathName.Mid( stack.TopNameLength(), pathName.Length(), itemName ); + item = InsertItem( itemName, stack.TopItem() ); + SetItemData( item, id ); + + return item; +} + +/* +================ +CPathTreeCtrl::SearchTree + +Search the three using the search string. +Adds the matched tree items to the result tree. +Returns the number of items added to the result tree. +================ +*/ +int CPathTreeCtrl::SearchTree( treeItemCompare_t compare, void *data, CPathTreeCtrl &result ) { + idPathTreeStack stack, searchStack; + HTREEITEM item, child; + idStr name; + int id, numItems; + + numItems = 0; + result.DeleteAllItems(); + stack.PushRoot( NULL ); + + item = GetRootItem(); + searchStack.PushRoot( item ); + id = 0; + + while( searchStack.Num() > 0 ) { + + for ( child = GetChildItem( item ); child; child = GetChildItem( child ) ) { + searchStack.Push( item, GetItemText( item ) ); + item = child; + } + + name = searchStack.TopName(); + name += GetItemText( item ); + id = GetItemData( item ); + + if ( compare( data, item, name ) ) { + result.AddPathToTree( name, id, stack ); + numItems++; + } + + for ( item = GetNextSiblingItem( item ); item == NULL; ) { + item = GetNextSiblingItem( searchStack.TopItem() ); + searchStack.Pop(); + if ( searchStack.Num() <= 0 ) { + return numItems; + } + } + } + + return numItems; +} + +BEGIN_MESSAGE_MAP(CPathTreeCtrl,CTreeCtrl) + //{{AFX_MSG_MAP(CPathTreeCtrl) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) + ON_WM_MOUSEMOVE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +/* +================ +CPathTreeCtrl::OnToolHitTest +================ +*/ +int CPathTreeCtrl::OnToolHitTest( CPoint point, TOOLINFO * pTI ) const { + RECT rect; + + UINT nFlags; + HTREEITEM hitem = HitTest( point, &nFlags ); + if( nFlags & TVHT_ONITEM ) { + GetItemRect( hitem, &rect, TRUE ); + pTI->hwnd = m_hWnd; + pTI->uId = (UINT)hitem; + pTI->lpszText = LPSTR_TEXTCALLBACK; + pTI->rect = rect; + return pTI->uId; + } + return -1; +} + +/* +================ +CPathTreeCtrl::OnToolTipText +================ +*/ +BOOL CPathTreeCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { + // need to handle both ANSI and UNICODE versions of the message + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + + UINT nID = pNMHDR->idFrom; + + *pResult = 0; + + // Do not process the message from built in tooltip + if( nID == (UINT)m_hWnd && + (( pNMHDR->code == TTN_NEEDTEXTA && pTTTA->uFlags & TTF_IDISHWND ) || + ( pNMHDR->code == TTN_NEEDTEXTW && pTTTW->uFlags & TTF_IDISHWND ) ) ) { + return FALSE; + } + + CString toolTip = "?"; + + // Get the mouse position + const MSG* pMessage; + CPoint pt; + pMessage = GetCurrentMessage(); + ASSERT ( pMessage ); + pt = pMessage->pt; + ScreenToClient( &pt ); + + // get the tree item + UINT nFlags; + HTREEITEM hitem = HitTest( pt, &nFlags ); + + if( nFlags & TVHT_ONITEM ) { + // relay message to parent + pTTTA->hdr.hwndFrom = GetSafeHwnd(); + pTTTA->hdr.idFrom = (UINT) hitem; + if ( GetParent()->SendMessage( WM_NOTIFY, ( TTN_NEEDTEXT << 16 ) | GetDlgCtrlID(), (LPARAM)pTTTA ) == FALSE ) { + return FALSE; + } + } + + return TRUE; // message was handled +} diff --git a/tools/comafx/CPathTreeCtrl.h b/tools/comafx/CPathTreeCtrl.h new file mode 100644 index 000000000..08dee2963 --- /dev/null +++ b/tools/comafx/CPathTreeCtrl.h @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CPATHTREECTR_H__ +#define __CPATHTREECTR_H__ + +/* +=============================================================================== + + Tree Control for path names. + +=============================================================================== +*/ + +class idPathTreeStack { +public: + idPathTreeStack( void ) { size = 0; } + + void PushRoot( HTREEITEM root ); + void Push( HTREEITEM item, const char *name ); + void Pop( void ) { size--; } + HTREEITEM TopItem( void ) const { return stackItem[size-1]; } + const char * TopName( void ) const { return stackName[size-1]; } + int TopNameLength( void ) const { return stackName[size-1].Length(); } + int Num( void ) const { return size; } + +private: + int size; + HTREEITEM stackItem[128]; + idStr stackName[128]; +}; + +ID_INLINE void idPathTreeStack::PushRoot( HTREEITEM root ) { + assert( size == 0 ); + stackItem[size] = root; + stackName[size] = ""; + size++; +} + +ID_INLINE void idPathTreeStack::Push( HTREEITEM item, const char *name ) { + assert( size < 127 ); + stackItem[size] = item; + stackName[size] = stackName[size-1] + name + "/"; + size++; +} + +typedef bool (*treeItemCompare_t)( void *data, HTREEITEM item, const char *name ); + + +class CPathTreeCtrl : public CTreeCtrl { +public: + CPathTreeCtrl(); + ~CPathTreeCtrl(); + + HTREEITEM FindItem( const idStr &pathName ); + HTREEITEM InsertPathIntoTree( const idStr &pathName, const int id ); + HTREEITEM AddPathToTree( const idStr &pathName, const int id, idPathTreeStack &stack ); + int SearchTree( treeItemCompare_t compare, void *data, CPathTreeCtrl &result ); + +protected: + virtual void PreSubclassWindow(); + virtual int OnToolHitTest( CPoint point, TOOLINFO * pTI ) const; + afx_msg BOOL OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ); + + DECLARE_MESSAGE_MAP() +}; + +#endif /* !__CPATHTREECTR_H__ */ diff --git a/tools/comafx/CSyntaxRichEditCtrl.cpp b/tools/comafx/CSyntaxRichEditCtrl.cpp new file mode 100644 index 000000000..ede6c13d8 --- /dev/null +++ b/tools/comafx/CSyntaxRichEditCtrl.cpp @@ -0,0 +1,1894 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "CSyntaxRichEditCtrl.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +// NOTE: known bug, if you directly jump to a not yet highligted page with the first line starting +// inside a multi-line comment then the multi-line comment is not picked up and highlighted + +const int AUTOCOMPLETE_WIDTH = 200; +const int AUTOCOMPLETE_HEIGHT = 180; +const int AUTOCOMPLETE_OFFSET = 16; + +const int FUNCPARMTOOLTIP_WIDTH = 16; +const int FUNCPARMTOOLTIP_HEIGHT = 20; +const int FUNCPARMTOOLTIP_OFFSET = 16; + +const COLORREF DEFAULT_BACK_COLOR = SRE_COLOR_WHITE; +const COLORREF INVALID_BACK_COLOR = SRE_COLOR_WHITE - 2; +const COLORREF MULTILINE_COMMENT_BACK_COLOR = SRE_COLOR_WHITE - 1; + +#define IDC_LISTBOX_AUTOCOMPLETE 700 +#define IDC_EDITBOX_FUNCPARMS 701 + +static keyWord_t defaultKeyWords[] = { + { NULL, SRE_COLOR_BLACK, "" } +}; + +BEGIN_MESSAGE_MAP(CSyntaxRichEditCtrl, CRichEditCtrl) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_GETDLGCODE() + ON_WM_KEYDOWN() + ON_WM_CHAR() + ON_WM_LBUTTONDOWN() + ON_WM_MOUSEWHEEL() + ON_WM_MOUSEMOVE() + ON_WM_VSCROLL() + ON_WM_SIZE() + ON_NOTIFY_REFLECT(EN_PROTECTED, OnProtected) + ON_CONTROL_REFLECT(EN_CHANGE, OnChange) + ON_LBN_SELCANCEL(IDC_LISTBOX_AUTOCOMPLETE, OnAutoCompleteListBoxChange) + ON_LBN_SELCHANGE(IDC_LISTBOX_AUTOCOMPLETE, OnAutoCompleteListBoxChange) + ON_LBN_DBLCLK(IDC_LISTBOX_AUTOCOMPLETE, OnAutoCompleteListBoxDblClk) +END_MESSAGE_MAP() + + +/* +================ +CSyntaxRichEditCtrl::CSyntaxRichEditCtrl +================ +*/ +CSyntaxRichEditCtrl::CSyntaxRichEditCtrl( void ) { + m_TextDoc = NULL; + keyWords = defaultKeyWords; + keyWordColors = NULL; + keyWordLengths = NULL; + caseSensitive = false; + allowPathNames = true; + keyWordAutoCompletion = true; + updateRange.cpMin = 0; + updateRange.cpMax = 0; + updateSyntaxHighlighting = true; + stringColorIndex = 0; + stringColorLine = -1; + autoCompleteStart = -1; + funcParmToolTipStart = -1; + bracedSection[0] = -1; + bracedSection[1] = -1; + GetObjectMembers = NULL; + GetFunctionParms = NULL; + GetToolTip = NULL; + mousePoint.x = 0; + mousePoint.y = 0; + keyWordToolTip = NULL; + m_pchTip = NULL; + m_pwchTip = NULL; +} + +/* +================ +CSyntaxRichEditCtrl::~CSyntaxRichEditCtrl +================ +*/ +CSyntaxRichEditCtrl::~CSyntaxRichEditCtrl( void ) { + FreeKeyWordsFromFile(); + delete m_pchTip; + delete m_pwchTip; + m_DefaultFont->Release(); +} + +/* +================ +CSyntaxRichEditCtrl::InitFont +================ +*/ +void CSyntaxRichEditCtrl::InitFont( void ) { + LOGFONT lf; + CFont font; + PARAFORMAT pf; + int logx, tabSize; + + // set the font + memset( &lf, 0, sizeof( lf ) ); + lf.lfHeight = FONT_HEIGHT * 10; + lf.lfWidth = FONT_WIDTH * 10; + lf.lfCharSet = ANSI_CHARSET; + lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN; + strcpy( lf.lfFaceName, FONT_NAME ); + font.CreatePointFontIndirect( &lf ); + + SetFont( &font ); + + // get the tab size in twips + logx = ::GetDeviceCaps( GetDC()->GetSafeHdc(), LOGPIXELSX ); + tabSize = TAB_SIZE * FONT_WIDTH * 1440 / logx; + + // set the tabs + memset( &pf, 0, sizeof( PARAFORMAT ) ); + pf.cbSize = sizeof( PARAFORMAT ); + pf.dwMask = PFM_TABSTOPS; + for ( pf.cTabCount = 0; pf.cTabCount < MAX_TAB_STOPS; pf.cTabCount++ ) { + pf.rgxTabs[pf.cTabCount] = pf.cTabCount * tabSize; + } + + SetParaFormat( pf ); + + memset( &defaultCharFormat, 0, sizeof( defaultCharFormat ) ); + defaultCharFormat.dwMask = CFM_CHARSET | CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_COLOR | CFM_PROTECTED | CFM_BACKCOLOR; + defaultCharFormat.yHeight = FONT_HEIGHT * 20; + defaultCharFormat.bCharSet = ANSI_CHARSET; + defaultCharFormat.bPitchAndFamily = FIXED_PITCH | FF_MODERN; + defaultCharFormat.crTextColor = SRE_COLOR_BLACK; + defaultCharFormat.crBackColor = DEFAULT_BACK_COLOR; + defaultCharFormat.dwEffects = CFE_PROTECTED; + strcpy( defaultCharFormat.szFaceName, FONT_NAME ); + defaultCharFormat.cbSize = sizeof( defaultCharFormat ); + + SetDefaultCharFormat( defaultCharFormat ); + + defaultColor = SRE_COLOR_BLACK; + singleLineCommentColor = SRE_COLOR_DARK_GREEN; + multiLineCommentColor = SRE_COLOR_DARK_GREEN; + stringColor[0] = stringColor[1] = SRE_COLOR_DARK_CYAN; + literalColor = SRE_COLOR_GREY; + braceHighlightColor = SRE_COLOR_RED; + + // get the default tom::ITextFont + tom::ITextRange *irange; + tom::ITextFont *ifont; + + m_TextDoc->Range( 0, 0, &irange ); + irange->get_Font( &ifont ); + + ifont->get_Duplicate( &m_DefaultFont ); + + ifont->Release(); + irange->Release(); +} + +/* +================ +CSyntaxRichEditCtrl::SetCharType +================ +*/ +void CSyntaxRichEditCtrl::SetCharType( int first, int last, int type ) { + for ( int i = first; i <= last; i++ ) { + charType[i] = type; + } +} + +/* +================ +CSyntaxRichEditCtrl::InitSyntaxHighlighting +================ +*/ +void CSyntaxRichEditCtrl::InitSyntaxHighlighting( void ) { + SetCharType( 0x00, 0xFF, CT_PUNCTUATION ); + SetCharType( '\0', ' ', CT_WHITESPACE ); + SetCharType( '/', '/', CT_COMMENT ); + SetCharType( '\"', '\"', CT_STRING ); + SetCharType( '\'', '\'', CT_LITERAL ); + SetCharType( 'a', 'z', CT_NAME ); + SetCharType( 'A', 'Z', CT_NAME ); + SetCharType( '_', '_', CT_NAME ); + SetCharType( '#', '#', CT_NAME ); + SetCharType( '0', '9', CT_NUMBER ); +} + +/* +================ +CSyntaxRichEditCtrl::Init +================ +*/ +void CSyntaxRichEditCtrl::Init( void ) { + + // get the Rich Edit ITextDocument to use the wonky TOM interface + IRichEditOle *ire = GetIRichEditOle(); + IUnknown *iu = (IUnknown *)ire; + if ( iu == NULL || iu->QueryInterface( tom::IID_ITextDocument, (void**) &m_TextDoc ) != S_OK ) { + m_TextDoc = NULL; + } + + InitFont(); + + InitSyntaxHighlighting(); + + SetEventMask( GetEventMask() | ENM_CHANGE | ENM_KEYEVENTS | ENM_MOUSEEVENTS | ENM_PROTECTED ); // ENM_SCROLLEVENTS + + EnableToolTips( TRUE ); + + // create auto complete list box + CRect rect( 0, 0, AUTOCOMPLETE_WIDTH, AUTOCOMPLETE_HEIGHT ); + autoCompleteListBox.Create( WS_DLGFRAME | WS_VISIBLE | WS_VSCROLL | LBS_SORT | LBS_NOTIFY, rect, this, IDC_LISTBOX_AUTOCOMPLETE ); + autoCompleteListBox.SetFont( GetParent()->GetFont() ); + autoCompleteListBox.ShowWindow( FALSE ); + + // create function parameter tool tip + funcParmToolTip.Create( WS_VISIBLE | WS_BORDER, rect, this, IDC_EDITBOX_FUNCPARMS ); + funcParmToolTip.SetFont( GetParent()->GetFont() ); + funcParmToolTip.ShowWindow( FALSE ); +} + +/* +================ +CSyntaxRichEditCtrl::FindKeyWord +================ +*/ +ID_INLINE int CSyntaxRichEditCtrl::FindKeyWord( const char *keyWord, int length ) const { + int i, hash; + + if ( caseSensitive ) { + hash = idStr::Hash( keyWord, length ); + } else { + hash = idStr::IHash( keyWord, length ); + } + for ( i = keyWordHash.First( hash ); i != -1; i = keyWordHash.Next( i ) ) { + if ( length != keyWordLengths[i] ) { + continue; + } + if ( caseSensitive ) { + if ( idStr::Cmpn( keyWords[i].keyWord, keyWord, length ) != 0 ) { + continue; + } + } else { + if ( idStr::Icmpn( keyWords[i].keyWord, keyWord, length ) != 0 ) { + continue; + } + } + return i; + } + return -1; +} + +/* +================ +CSyntaxRichEditCtrl::SetKeyWords +================ +*/ +void CSyntaxRichEditCtrl::SetKeyWords( const keyWord_t kws[] ) { + int i, numKeyWords, hash; + + keyWords = kws; + + for ( numKeyWords = 0; keyWords[numKeyWords].keyWord; numKeyWords++ ) { + } + + delete keyWordColors; + keyWordColors = new COLORREF[numKeyWords]; + + for ( i = 0; i < numKeyWords; i++ ) { + keyWordColors[i] = keyWords[i].color; + } + + delete keyWordLengths; + keyWordLengths = new int[numKeyWords]; + + for ( i = 0; i < numKeyWords; i++ ) { + keyWordLengths[i] = idStr::Length( keyWords[i].keyWord ); + } + + keyWordHash.Clear( 1024, 1024 ); + for ( i = 0; i < numKeyWords; i++ ) { + if ( caseSensitive ) { + hash = idStr::Hash( keyWords[i].keyWord, keyWordLengths[i] ); + } else { + hash = idStr::IHash( keyWords[i].keyWord, keyWordLengths[i] ); + } + keyWordHash.Add( hash, i ); + } +} + +/* +================ +CSyntaxRichEditCtrl::LoadKeyWordsFromFile +================ +*/ +bool CSyntaxRichEditCtrl::LoadKeyWordsFromFile( const char *fileName ) { + idParser src; + idToken token, name, description; + byte red, green, blue; + keyWord_t keyword; + + if ( !src.LoadFile( fileName ) ) { + return false; + } + + FreeKeyWordsFromFile(); + + while( src.ReadToken( &token ) ) { + if ( token.Icmp( "keywords" ) == 0 ) { + src.ExpectTokenString( "{" ); + while( src.ReadToken( &token ) ) { + if ( token == "}" ) { + break; + } + if ( token == "{" ) { + + // parse name + src.ExpectTokenType( TT_STRING, 0, &name ); + src.ExpectTokenString( "," ); + + // parse color + src.ExpectTokenString( "(" ); + src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); + red = token.GetIntValue(); + src.ExpectTokenString( "," ); + src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); + green = token.GetIntValue(); + src.ExpectTokenString( "," ); + src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ); + blue = token.GetIntValue(); + src.ExpectTokenString( ")" ); + src.ExpectTokenString( "," ); + + // parse description + src.ExpectTokenType( TT_STRING, 0, &description ); + src.ExpectTokenString( "}" ); + + keyword.keyWord = Mem_CopyString( name ); + keyword.color = RGB( red, green, blue ); + keyword.description = Mem_CopyString( description ); + + keyWordsFromFile.Append( keyword ); + } + } + } else { + src.SkipBracedSection(); + } + } + + keyword.keyWord = NULL; + keyword.color = RGB( 255, 255, 255 ); + keyword.description = NULL; + keyWordsFromFile.Append( keyword ); + + SetKeyWords( keyWordsFromFile.Ptr() ); + + return true; +} + +/* +================ +CSyntaxRichEditCtrl::FreeKeyWordsFromFile +================ +*/ +void CSyntaxRichEditCtrl::FreeKeyWordsFromFile( void ) { + for ( int i = 0; i < keyWordsFromFile.Num(); i++ ) { + Mem_Free( const_cast( keyWordsFromFile[i].keyWord ) ); + Mem_Free( const_cast( keyWordsFromFile[i].description ) ); + } + keyWordsFromFile.Clear(); +} + +/* +================ +CSyntaxRichEditCtrl::SetDefaultColor +================ +*/ +void CSyntaxRichEditCtrl::SetDefaultColor( const COLORREF color ) { + defaultColor = color; +} + +/* +================ +CSyntaxRichEditCtrl::SetCommentColor +================ +*/ +void CSyntaxRichEditCtrl::SetCommentColor( const COLORREF color ) { + singleLineCommentColor = color; + multiLineCommentColor = color; +} + +/* +================ +CSyntaxRichEditCtrl::SetStringColor +================ +*/ +void CSyntaxRichEditCtrl::SetStringColor( const COLORREF color, const COLORREF altColor ) { + stringColor[0] = color; + if ( altColor == -1 ) { + stringColor[1] = color; + } else { + stringColor[1] = altColor; + } +} + +/* +================ +CSyntaxRichEditCtrl::SetLiteralColor +================ +*/ +void CSyntaxRichEditCtrl::SetLiteralColor( const COLORREF color ) { + literalColor = color; +} + +/* +================ +CSyntaxRichEditCtrl::SetObjectMemberCallback +================ +*/ +void CSyntaxRichEditCtrl::SetObjectMemberCallback( objectMemberCallback_t callback ) { + GetObjectMembers = callback; +} + +/* +================ +CSyntaxRichEditCtrl::SetFunctionParmCallback +================ +*/ +void CSyntaxRichEditCtrl::SetFunctionParmCallback( toolTipCallback_t callback ) { + GetFunctionParms = callback; +} + +/* +================ +CSyntaxRichEditCtrl::SetToolTipCallback +================ +*/ +void CSyntaxRichEditCtrl::SetToolTipCallback( toolTipCallback_t callback ) { + GetToolTip = callback; +} + +/* +================ +CSyntaxRichEditCtrl::SetCaseSensitive +================ +*/ +void CSyntaxRichEditCtrl::SetCaseSensitive( bool caseSensitive ) { + this->caseSensitive = caseSensitive; +} + +/* +================ +CSyntaxRichEditCtrl::AllowPathNames +================ +*/ +void CSyntaxRichEditCtrl::AllowPathNames( bool allow ) { + allowPathNames = allow; +} + +/* +================ +CSyntaxRichEditCtrl::EnableKeyWordAutoCompletion +================ +*/ +void CSyntaxRichEditCtrl::EnableKeyWordAutoCompletion( bool enable ) { + keyWordAutoCompletion = enable; +} + +/* +================ +CSyntaxRichEditCtrl::GetVisibleRange +================ +*/ +CHARRANGE CSyntaxRichEditCtrl::GetVisibleRange( void ) const { + RECT rectArea; + int firstLine, lastLine; + CHARRANGE range; + + firstLine = GetFirstVisibleLine(); + GetClientRect( &rectArea ); + lastLine = firstLine + ( rectArea.bottom / ( defaultCharFormat.yHeight / 20 ) ); + + if ( lastLine >= GetLineCount() ) { + lastLine = GetLineCount() - 1; + } + range.cpMin = LineIndex( firstLine ); + if ( range.cpMin < 0 ) { + range.cpMin = 0; + } + range.cpMax = LineIndex( lastLine ); + if ( range.cpMax == -1 ) { + range.cpMax = range.cpMin + LineLength( range.cpMin ); + } else { + range.cpMax += LineLength( range.cpMax ); + } + if ( range.cpMax >= GetTextLength() ) { + range.cpMax = GetTextLength() - 1; + } + return range; +} + +/* +================ +CSyntaxRichEditCtrl::SetDefaultFont +================ +*/ +void CSyntaxRichEditCtrl::SetDefaultFont( int startCharIndex, int endCharIndex ) { + tom::ITextRange *range; + + updateSyntaxHighlighting = false; + + m_TextDoc->Range( startCharIndex, endCharIndex, &range ); + + m_TextDoc->Undo( tom::tomSuspend, NULL ); + range->put_Font( m_DefaultFont ); + m_TextDoc->Undo( tom::tomResume, NULL ); + + range->Release(); + + updateSyntaxHighlighting = true; +} + +/* +================ +CSyntaxRichEditCtrl::SetColor +================ +*/ +void CSyntaxRichEditCtrl::SetColor( int startCharIndex, int endCharIndex, COLORREF foreColor, COLORREF backColor, bool bold ) { + tom::ITextRange *range; + tom::ITextFont *font; + long prop; + + updateSyntaxHighlighting = false; + + m_TextDoc->Range( startCharIndex, endCharIndex, &range ); + range->get_Font( &font ); + + m_TextDoc->Undo( tom::tomSuspend, &prop ); + font->put_ForeColor( foreColor ); + m_TextDoc->Undo( tom::tomResume, &prop ); + + m_TextDoc->Undo( tom::tomSuspend, &prop ); + font->put_BackColor( backColor ); + m_TextDoc->Undo( tom::tomResume, &prop ); + + m_TextDoc->Undo( tom::tomSuspend, &prop ); + font->put_Bold( bold ? tom::tomTrue : tom::tomFalse ); + m_TextDoc->Undo( tom::tomResume, &prop ); + + font->Release(); + range->Release(); + + updateSyntaxHighlighting = true; +} + +/* +================ +CSyntaxRichEditCtrl::GetForeColor +================ +*/ +COLORREF CSyntaxRichEditCtrl::GetForeColor( int charIndex ) const { + tom::ITextRange *range; + tom::ITextFont *font; + long foreColor; + + m_TextDoc->Range( charIndex, charIndex, &range ); + range->get_Font( &font ); + + font->get_BackColor( &foreColor ); + + font->Release(); + range->Release(); + + return foreColor; +} + +/* +================ +CSyntaxRichEditCtrl::GetBackColor +================ +*/ +COLORREF CSyntaxRichEditCtrl::GetBackColor( int charIndex ) const { + tom::ITextRange *range; + tom::ITextFont *font; + long backColor; + + m_TextDoc->Range( charIndex, charIndex, &range ); + range->get_Font( &font ); + + font->get_BackColor( &backColor ); + + font->Release(); + range->Release(); + + return backColor; +} + +/* +================ +CSyntaxRichEditCtrl::HighlightSyntax + + Update the syntax highlighting for the given character range. +================ +*/ +void CSyntaxRichEditCtrl::HighlightSyntax( int startCharIndex, int endCharIndex ) { + int c, t, line, charIndex, textLength, syntaxStart, keyWordLength, keyWordIndex; + const char *keyWord; + CHARRANGE visRange; + CString text; + + // get text length + GetTextRange( 0, GetTextLength(), text ); + textLength = text.GetLength(); + + // make sure the indexes are within bounds + if ( startCharIndex < 0 ) { + startCharIndex = 0; + } + if ( endCharIndex < 0 ) { + endCharIndex = textLength - 1; + } else if ( endCharIndex >= textLength ) { + endCharIndex = textLength - 1; + } + + // move the start index to the beginning of the line + for ( ; startCharIndex > 0; startCharIndex-- ) { + if ( idStr::CharIsNewLine( text[startCharIndex-1] ) ) { + break; + } + } + + // move the end index to the end of the line + for ( ; endCharIndex < textLength - 1; endCharIndex++ ) { + if ( idStr::CharIsNewLine( text[endCharIndex+1] ) ) { + break; + } + } + + // get the visible char range + visRange = GetVisibleRange(); + + // never update beyond the visible range + if ( startCharIndex < visRange.cpMin ) { + SetColor( startCharIndex, visRange.cpMin - 1, SRE_COLOR_BLACK, INVALID_BACK_COLOR, false ); + startCharIndex = visRange.cpMin; + } + if ( visRange.cpMax < endCharIndex ) { + SetColor( visRange.cpMax, endCharIndex, SRE_COLOR_BLACK, INVALID_BACK_COLOR, false ); + endCharIndex = visRange.cpMax; + if ( endCharIndex >= textLength ) { + endCharIndex = textLength - 1; + } + } + + // test if the start index is inside a multi-line comment + if ( startCharIndex > 0 ) { + // multi-line comments have a slightly different background color + if ( GetBackColor( startCharIndex-1 ) == MULTILINE_COMMENT_BACK_COLOR ) { + for( ; startCharIndex > 0; startCharIndex-- ) { + if ( text[startCharIndex] == '/' && text[startCharIndex+1] == '*' ) { + break; + } + } + } + } + + // test if the end index is inside a multi-line comment + if ( endCharIndex < textLength - 1 ) { + // multi-line comments have a slightly different background color + if ( GetBackColor( endCharIndex+1 ) == MULTILINE_COMMENT_BACK_COLOR ) { + for( endCharIndex++; endCharIndex < textLength - 1; endCharIndex++ ) { + if ( text[endCharIndex-1] == '*' && text[endCharIndex] == '/' ) { + break; + } + } + } + } + + line = 0; + stringColorLine = -1; + stringColorIndex = 0; + + // set the default color + SetDefaultFont( startCharIndex, endCharIndex + 1 ); + + // syntax based colors + for( charIndex = startCharIndex; charIndex <= endCharIndex; charIndex++ ) { + + t = charType[text[charIndex]]; + switch( t ) { + case CT_WHITESPACE: { + if ( idStr::CharIsNewLine( text[charIndex] ) ) { + line++; + } + break; + } + case CT_COMMENT: { + c = text[charIndex+1]; + if ( c == '/' ) { + // single line comment + syntaxStart = charIndex; + for ( charIndex += 2; charIndex < textLength; charIndex++ ) { + if ( idStr::CharIsNewLine( text[charIndex] ) ) { + break; + } + } + SetColor( syntaxStart, charIndex + 1, singleLineCommentColor, DEFAULT_BACK_COLOR, false ); + } else if ( c == '*' ) { + // multi-line comment + syntaxStart = charIndex; + for ( charIndex += 2; charIndex < textLength; charIndex++ ) { + if ( text[charIndex] == '*' && text[charIndex+1] == '/' ) { + break; + } + } + charIndex++; + SetColor( syntaxStart, charIndex + 1, multiLineCommentColor, MULTILINE_COMMENT_BACK_COLOR, false ); + } + break; + } + case CT_STRING: { + if ( line != stringColorLine ) { + stringColorLine = line; + stringColorIndex = 0; + } + syntaxStart = charIndex; + for ( charIndex++; charIndex < textLength; charIndex++ ) { + c = text[charIndex]; + if ( charType[c] == CT_STRING && text[charIndex-1] != '\\' ) { + break; + } + if ( idStr::CharIsNewLine( c ) ) { + line++; + break; + } + } + SetColor( syntaxStart, charIndex + 1, stringColor[stringColorIndex], DEFAULT_BACK_COLOR, false ); + stringColorIndex ^= 1; + break; + } + case CT_LITERAL: { + syntaxStart = charIndex; + for ( charIndex++; charIndex < textLength; charIndex++ ) { + c = text[charIndex]; + if ( charType[c] == CT_LITERAL && text[charIndex-1] != '\\' ) { + break; + } + if ( idStr::CharIsNewLine( c ) ) { + line++; + break; + } + } + SetColor( syntaxStart, charIndex + 1, literalColor, DEFAULT_BACK_COLOR, false ); + break; + } + case CT_NUMBER: { + break; + } + case CT_NAME: { + syntaxStart = charIndex; + keyWord = ((const char *)text) + charIndex; + for ( charIndex++; charIndex < textLength; charIndex++ ) { + c = text[charIndex]; + t = charType[c]; + if ( t != CT_NAME && t != CT_NUMBER ) { + // allow path names + if ( !allowPathNames || ( c != '/' && c != '\\' && c != '.' ) ) { + break; + } + } + } + keyWordLength = charIndex - syntaxStart; + keyWordIndex = FindKeyWord( keyWord, keyWordLength ); + if ( keyWordIndex != -1 ) { + SetColor( syntaxStart, syntaxStart + keyWordLength, keyWordColors[keyWordIndex], DEFAULT_BACK_COLOR, false ); + } + break; + } + case CT_PUNCTUATION: { + break; + } + } + } + + // show braced section + BracedSectionShow(); +} + +/* +================ +CSyntaxRichEditCtrl::UpdateVisibleRange + + Updates the visible character range if it is not yet properly highlighted. +================ +*/ +void CSyntaxRichEditCtrl::UpdateVisibleRange( void ) { + CHARRANGE visRange; + tom::ITextRange *range; + tom::ITextFont *font; + long backColor; + bool update = false; + + if ( !updateSyntaxHighlighting ) { + return; + } + + visRange = GetVisibleRange(); + + m_TextDoc->Range( visRange.cpMin, visRange.cpMax, &range ); + range->get_End( &visRange.cpMax ); + + range->get_Font( &font ); + + range->SetRange( visRange.cpMin, visRange.cpMin ); + while( 1 ) { + range->get_Start( &visRange.cpMin ); + if ( visRange.cpMin >= visRange.cpMax ) { + break; + } + font->get_BackColor( &backColor ); + if ( backColor == INVALID_BACK_COLOR ) { + update = true; + break; + } + if ( range->Move( tom::tomCharFormat, 1, NULL ) != S_OK ) { + break; + } + } + + font->Release(); + range->Release(); + + if ( update ) { + HighlightSyntax( visRange.cpMin, visRange.cpMax - 1 ); + } +} + +/* +================ +CSyntaxRichEditCtrl::GetCursorPos +================ +*/ +void CSyntaxRichEditCtrl::GetCursorPos( int &line, int &column, int &character ) const { + long start, end; + char buffer[MAX_STRING_CHARS]; + + GetSel( start, end ); + line = LineFromChar( start ); + start -= LineIndex( line ); + GetLine( line, buffer, sizeof( buffer ) ); + for ( column = 1, character = 0; character < start; character++ ) { + if ( idStr::CharIsTab( buffer[character] ) ) { + column += TAB_SIZE; + column -= column % TAB_SIZE; + } else { + column++; + } + } + character++; +} + +/* +================ +CSyntaxRichEditCtrl::GetText +================ +*/ +void CSyntaxRichEditCtrl::GetText( idStr &text ) const { + GetText( text, 0, GetTextLength() ); +} + +/* +================ +CSyntaxRichEditCtrl::GetText +================ +*/ +void CSyntaxRichEditCtrl::GetText( idStr &text, int startCharIndex, int endCharIndex ) const { + tom::ITextRange *range; + BSTR bstr; + USES_CONVERSION; + + m_TextDoc->Range( startCharIndex, endCharIndex, &range ); + range->get_Text( &bstr ); + text = W2A( bstr ); + range->Release(); + text.StripTrailingOnce( "\r" ); // remove last carriage return which is always added to a tom::ITextRange +} + +/* +================ +CSyntaxRichEditCtrl::SetText +================ +*/ +void CSyntaxRichEditCtrl::SetText( const char *text ) { + SetSel( 0, -1 ); + ReplaceSel( text, FALSE ); + SetSel( 0, 0 ); +} + +/* +================ +CSyntaxRichEditCtrl::FindNext +================ +*/ +bool CSyntaxRichEditCtrl::FindNext( const char *find, bool matchCase, bool matchWholeWords, bool searchForward ) { + long selStart, selEnd, flags, search, length, start; + tom::ITextRange *range; + + if ( find[0] == '\0' ) { + return false; + } + + GetSel( selStart, selEnd ); + + flags = 0; + flags |= matchCase ? tom::tomMatchCase : 0; + flags |= matchWholeWords ? tom::tomMatchWord : 0; + + if ( searchForward ) { + m_TextDoc->Range( selEnd, GetTextLength(), &range ); + search = GetTextLength() - selEnd; + } else { + m_TextDoc->Range( 0, selStart, &range ); + search = -selStart; + } + + if ( range->FindShit( A2BSTR(find), search, flags, &length ) == S_OK ) { + + m_TextDoc->Freeze( NULL ); + + range->get_Start( &start ); + range->Release(); + + SetSel( start, start + length ); + + int line = Max( (int) LineFromChar( start ) - 5, 0 ); + LineScroll( line - GetFirstVisibleLine(), 0 ); + + UpdateVisibleRange(); + + m_TextDoc->Unfreeze( NULL ); + return true; + } else { + range->Release(); + return false; + } +} + +/* +================ +CSyntaxRichEditCtrl::ReplaceAll +================ +*/ +int CSyntaxRichEditCtrl::ReplaceAll( const char *find, const char *replace, bool matchCase, bool matchWholeWords ) { + long selStart, selEnd, flags, search, length, start; + int numReplaced; + tom::ITextRange *range; + CComBSTR bstr( find ); + + if ( find[0] == '\0' ) { + return 0; + } + + m_TextDoc->Freeze( NULL ); + + GetSel( selStart, selEnd ); + + flags = 0; + flags |= matchCase ? tom::tomMatchCase : 0; + flags |= matchWholeWords ? tom::tomMatchWord : 0; + + m_TextDoc->Range( 0, GetTextLength(), &range ); + search = GetTextLength(); + + numReplaced = 0; + while( range->FindShit( bstr, search, flags, &length ) == S_OK ) { + range->get_Start( &start ); + ReplaceText( start, start + length, replace ); + numReplaced++; + } + + range->Release(); + + m_TextDoc->Unfreeze( NULL ); + + return numReplaced; +} + +/* +================ +CSyntaxRichEditCtrl::ReplaceText +================ +*/ +void CSyntaxRichEditCtrl::ReplaceText( int startCharIndex, int endCharIndex, const char *replace ) { + tom::ITextRange *range; + CComBSTR bstr( replace ); + + m_TextDoc->Range( startCharIndex, endCharIndex, &range ); + range->put_Text( bstr ); + range->Release(); +} + +/* +================ +CSyntaxRichEditCtrl::AutoCompleteInsertText +================ +*/ +void CSyntaxRichEditCtrl::AutoCompleteInsertText( void ) { + long selStart, selEnd; + int index; + + index = autoCompleteListBox.GetCurSel(); + if ( index >= 0 ) { + CString text; + autoCompleteListBox.GetText( index, text ); + GetSel( selStart, selEnd ); + selStart = autoCompleteStart; + SetSel( selStart, selEnd ); + ReplaceSel( text, TRUE ); + } +} + +/* +================ +CSyntaxRichEditCtrl::AutoCompleteUpdate +================ +*/ +void CSyntaxRichEditCtrl::AutoCompleteUpdate( void ) { + long selStart, selEnd; + int index; + idStr text; + + GetSel( selStart, selEnd ); + GetText( text, autoCompleteStart, selStart ); + index = autoCompleteListBox.FindString( -1, text ); + if ( index >= 0 && index < autoCompleteListBox.GetCount() ) { + autoCompleteListBox.SetCurSel( index ); + } +} + +/* +================ +CSyntaxRichEditCtrl::AutoCompleteShow +================ +*/ +void CSyntaxRichEditCtrl::AutoCompleteShow( int charIndex ) { + CPoint point; + CRect rect; + + autoCompleteStart = charIndex; + point = PosFromChar( charIndex ); + GetClientRect( rect ); + if ( point.y < rect.bottom - AUTOCOMPLETE_OFFSET - AUTOCOMPLETE_HEIGHT ) { + rect.top = point.y + AUTOCOMPLETE_OFFSET; + rect.bottom = point.y + AUTOCOMPLETE_OFFSET + AUTOCOMPLETE_HEIGHT; + } else { + rect.top = point.y - AUTOCOMPLETE_HEIGHT; + rect.bottom = point.y; + } + rect.left = point.x; + rect.right = point.x + AUTOCOMPLETE_WIDTH; + autoCompleteListBox.MoveWindow( &rect ); + autoCompleteListBox.ShowWindow( TRUE ); + AutoCompleteUpdate(); +} + +/* +================ +CSyntaxRichEditCtrl::AutoCompleteHide +================ +*/ +void CSyntaxRichEditCtrl::AutoCompleteHide( void ) { + autoCompleteStart = -1; + autoCompleteListBox.ShowWindow( FALSE ); +} + +/* +================ +CSyntaxRichEditCtrl::ToolTipShow +================ +*/ +void CSyntaxRichEditCtrl::ToolTipShow( int charIndex, const char *string ) { + CPoint point, p1, p2; + CRect rect; + + funcParmToolTipStart = charIndex; + funcParmToolTip.SetWindowText( string ); + p1 = funcParmToolTip.PosFromChar( 0 ); + p2 = funcParmToolTip.PosFromChar( strlen( string ) - 1 ); + point = PosFromChar( charIndex ); + GetClientRect( rect ); + if ( point.y < rect.bottom - FUNCPARMTOOLTIP_OFFSET - FUNCPARMTOOLTIP_HEIGHT ) { + rect.top = point.y + FUNCPARMTOOLTIP_OFFSET; + rect.bottom = point.y + FUNCPARMTOOLTIP_OFFSET + FUNCPARMTOOLTIP_HEIGHT; + } else { + rect.top = point.y - FUNCPARMTOOLTIP_HEIGHT; + rect.bottom = point.y; + } + rect.left = point.x; + rect.right = point.x + FUNCPARMTOOLTIP_WIDTH + p2.x - p1.x; + funcParmToolTip.MoveWindow( &rect ); + funcParmToolTip.ShowWindow( TRUE ); +} + +/* +================ +CSyntaxRichEditCtrl::ToolTipHide +================ +*/ +void CSyntaxRichEditCtrl::ToolTipHide( void ) { + funcParmToolTipStart = -1; + funcParmToolTip.ShowWindow( FALSE ); +} + +/* +================ +CSyntaxRichEditCtrl::BracedSectionStart +================ +*/ +bool CSyntaxRichEditCtrl::BracedSectionStart( char braceStartChar, char braceEndChar ) { + long selStart, selEnd; + int brace, i; + idStr text; + + GetSel( selStart, selEnd ); + GetText( text, 0, GetTextLength() ); + + for ( brace = 1, i = selStart; i < text.Length(); i++ ) { + if ( text[i] == braceStartChar ) { + brace++; + } else if ( text[i] == braceEndChar ) { + brace--; + if ( brace == 0 ) { + break; + } + } + } + if ( brace == 0 ) { + bracedSection[0] = selStart - 1; + bracedSection[1] = i; + BracedSectionShow(); + } + + return ( brace == 0 ); +} + +/* +================ +CSyntaxRichEditCtrl::BracedSectionEnd +================ +*/ +bool CSyntaxRichEditCtrl::BracedSectionEnd( char braceStartChar, char braceEndChar ) { + long selStart, selEnd; + int brace, i; + idStr text; + + GetSel( selStart, selEnd ); + GetText( text, 0, GetTextLength() ); + + for ( brace = 1, i = Min( selStart-2, (long)text.Length()-1 ); i >= 0; i-- ) { + if ( text[i] == braceStartChar ) { + brace--; + if ( brace == 0 ) { + break; + } + } else if ( text[i] == braceEndChar ) { + brace++; + } + } + + if ( brace == 0 ) { + bracedSection[0] = i; + bracedSection[1] = selStart - 1; + BracedSectionAdjustEndTabs(); + BracedSectionShow(); + } + + return ( brace == 0 ); +} + +/* +================ +CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs +================ +*/ +void CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs( void ) { + int line, lineIndex, length, column, numTabs, i; + char buffer[1024]; + idStr text; + + line = LineFromChar( bracedSection[0] ); + length = GetLine( line, buffer, sizeof( buffer ) ); + for ( numTabs = 0; numTabs < length; numTabs++ ) { + if ( !idStr::CharIsTab( buffer[numTabs] ) ) { + break; + } + text.Append( '\t' ); + } + + line = LineFromChar( bracedSection[1] ); + lineIndex = LineIndex( line ); + length = GetLine( line, buffer, sizeof( buffer ) ); + column = bracedSection[1] - lineIndex; + for ( i = 0; i < column; i++ ) { + if ( charType[buffer[i]] != CT_WHITESPACE ) { + return; + } + } + + ReplaceText( lineIndex, lineIndex + column, text ); + + bracedSection[1] += numTabs - column; + SetSel( bracedSection[1]+1, bracedSection[1]+1 ); +} + +/* +================ +CSyntaxRichEditCtrl::BracedSectionShow +================ +*/ +void CSyntaxRichEditCtrl::BracedSectionShow( void ) { + for ( int i = 0; i < 2; i++ ) { + if ( bracedSection[i] >= 0 ) { + SetColor( bracedSection[i], bracedSection[i] + 1, braceHighlightColor, DEFAULT_BACK_COLOR, true ); + } + } +} + +/* +================ +CSyntaxRichEditCtrl::BracedSectionHide +================ +*/ +void CSyntaxRichEditCtrl::BracedSectionHide( void ) { + for ( int i = 0; i < 2; i++ ) { + if ( bracedSection[i] >= 0 ) { + SetColor( bracedSection[i], bracedSection[i] + 1, defaultColor, DEFAULT_BACK_COLOR, false ); + bracedSection[i] = -1; + } + } +} + +/* +================ +CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection +================ +*/ +bool CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection( CString &name, int &charIndex ) const { + long selStart, selEnd; + int line, column, length; + char buffer[1024]; + + GetSel( selStart, selEnd ); + charIndex = selStart; + line = LineFromChar( selStart ); + length = GetLine( line, buffer, sizeof( buffer ) ); + column = selStart - LineIndex( line ) - 1; + do { + buffer[column--] = '\0'; + } while( charType[buffer[column]] == CT_WHITESPACE ); + for ( length = 0; length < column; length++ ) { + if ( charType[buffer[column-length-1]] != CT_NAME ) { + break; + } + } + if ( length > 0 ) { + name = buffer + column - length; + return true; + } + return false; +} + +/* +================ +CSyntaxRichEditCtrl::GetNameForMousePosition +================ +*/ +bool CSyntaxRichEditCtrl::GetNameForMousePosition( idStr &name ) const { + int charIndex, startCharIndex, endCharIndex, type; + idStr text; + + charIndex = CharFromPos( mousePoint ); + + for ( startCharIndex = charIndex; startCharIndex > 0; startCharIndex-- ) { + GetText( text, startCharIndex - 1, startCharIndex ); + type = charType[text[0]]; + if ( type != CT_NAME && type != CT_NUMBER ) { + break; + } + } + + for ( endCharIndex = charIndex; endCharIndex < GetTextLength(); endCharIndex++ ) { + GetText( text, endCharIndex, endCharIndex + 1 ); + type = charType[text[0]]; + if ( type != CT_NAME && type != CT_NUMBER ) { + break; + } + } + + GetText( name, startCharIndex, endCharIndex ); + + return ( endCharIndex > startCharIndex ); +} + +/* +================ +CSyntaxRichEditCtrl::GoToLine +================ +*/ +void CSyntaxRichEditCtrl::GoToLine( int line ) { + + int index = LineIndex( line ); + + m_TextDoc->Freeze( NULL ); + + SetSel( index, index ); + + m_TextDoc->Unfreeze( NULL ); + + UpdateVisibleRange(); + + RedrawWindow(); +} + +/* +================ +CSyntaxRichEditCtrl::OnToolHitTest +================ +*/ +int CSyntaxRichEditCtrl::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { + CRichEditCtrl::OnToolHitTest( point, pTI ); + + pTI->hwnd = GetSafeHwnd(); + pTI->uId = (UINT_PTR)GetSafeHwnd(); + pTI->uFlags |= TTF_IDISHWND; + pTI->lpszText = LPSTR_TEXTCALLBACK; + pTI->rect = CRect( point, point ); + pTI->rect.right += 100; + pTI->rect.bottom += 20; + return pTI->uId; +} + +/* +================ +CSyntaxRichEditCtrl::OnToolTipNotify +================ +*/ +BOOL CSyntaxRichEditCtrl::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + + *pResult = 0; + + idStr name; + + if ( GetNameForMousePosition( name ) ) { + CString toolTip; + + if ( GetToolTip == NULL || !GetToolTip( name, toolTip ) ) { + + int keyWordIndex = FindKeyWord( name, name.Length() ); + + if ( keyWordIndex != -1 && keyWords[keyWordIndex].description[0] != '\0' ) { + toolTip = keyWords[keyWordIndex].description; + } else { + toolTip = name.c_str(); + } + } + + AFX_MODULE_THREAD_STATE *state = AfxGetModuleThreadState(); + + // set max tool tip width to enable multi-line tool tips using "\r\n" for line breaks + state->m_pToolTip->SetMaxTipWidth( 500 ); + + // set the number of milliseconds after which the tool tip automatically disappears + state->m_pToolTip->SetDelayTime( TTDT_AUTOPOP, 5000 + toolTip.GetLength() * 50 ); + +#ifndef _UNICODE + if( pNMHDR->code == TTN_NEEDTEXTA ) { + delete m_pchTip; + m_pchTip = new TCHAR[toolTip.GetLength() + 2]; + lstrcpyn( m_pchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTW->lpszText = (WCHAR*)m_pchTip; + } else { + delete m_pwchTip; + m_pwchTip = new WCHAR[toolTip.GetLength() + 2]; + _mbstowcsz( m_pwchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTW->lpszText = (WCHAR*)m_pwchTip; + } +#else + if( pNMHDR->code == TTN_NEEDTEXTA ) { + delete m_pchTip; + m_pchTip = new TCHAR[toolTip.GetLength() + 2]; + _wcstombsz( m_pchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTA->lpszText = (LPTSTR)m_pchTip; + } else { + delete m_pwchTip; + m_pwchTip = new WCHAR[toolTip.GetLength() + 2]; + lstrcpyn( m_pwchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTA->lpszText = (LPTSTR) m_pwchTip; + } +#endif + + return TRUE; + } + return FALSE; +} + +/* +================ +CSyntaxRichEditCtrl::OnGetDlgCode +================ +*/ +UINT CSyntaxRichEditCtrl::OnGetDlgCode() { + // get all keys, including tabs + return DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTMESSAGE | DLGC_WANTTAB; +} + +/* +================ +CSyntaxRichEditCtrl::OnKeyDown +================ +*/ +void CSyntaxRichEditCtrl::OnKeyDown( UINT nKey, UINT nRepCnt, UINT nFlags ) { + + if ( m_TextDoc == NULL ) { + return; + } + + if ( autoCompleteStart >= 0 ) { + int sel; + + switch( nKey ) { + case VK_UP: { // up arrow + sel = Max( 0, autoCompleteListBox.GetCurSel() - 1 ); + autoCompleteListBox.SetCurSel( sel ); + return; + } + case VK_DOWN: { // down arrow + sel = Min( autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 1 ); + autoCompleteListBox.SetCurSel( sel ); + return; + } + case VK_PRIOR: { // page up key + sel = Max( 0, autoCompleteListBox.GetCurSel() - 10 ); + autoCompleteListBox.SetCurSel( sel ); + return; + } + case VK_NEXT: { // page down key + sel = Min( autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 10 ); + autoCompleteListBox.SetCurSel( sel ); + return; + } + case VK_HOME: { // home key + autoCompleteListBox.SetCurSel( 0 ); + return; + } + case VK_END: { + autoCompleteListBox.SetCurSel( autoCompleteListBox.GetCount() - 1 ); + return; + } + case VK_RETURN: // enter key + case VK_TAB: { // tab key + AutoCompleteInsertText(); + AutoCompleteHide(); + return; + } + case VK_LEFT: // left arrow + case VK_RIGHT: // right arrow + case VK_INSERT: // insert key + case VK_DELETE: { // delete key + return; + } + } + } + + BracedSectionHide(); + + switch( nKey ) { + case VK_TAB: { // multi-line tabs + long selStart, selEnd; + + GetSel( selStart, selEnd ); + + // if multiple lines are selected add tabs to, or remove tabs from all of them + if ( selEnd > selStart ) { + CString text; + + text = GetSelText(); + + if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) { + if ( idStr::CharIsTab( text[0] ) ) { + text.Delete( 0, 1 ); + } + for ( int i = 0; i < text.GetLength() - 2; i++ ) { + if ( idStr::CharIsNewLine( text[i] ) ) { + do { + i++; + } while( idStr::CharIsNewLine( text[i] ) ); + if ( idStr::CharIsTab( text[i] ) ) { + text.Delete( i, 1 ); + } + } + } + } else { + text.Insert( 0, '\t' ); + for ( int i = 0; i < text.GetLength() - 1; i++ ) { + if ( idStr::CharIsNewLine( text[i] ) ) { + do { + i++; + } while( idStr::CharIsNewLine( text[i] ) ); + text.Insert( i, '\t' ); + } + } + } + + ReplaceSel( text, TRUE ); + SetSel( selStart, selStart + text.GetLength() ); + } else { + ReplaceSel( "\t", TRUE ); + } + return; + } + case VK_RETURN: { // auto-indentation + long selStart, selEnd; + int line, length, numTabs, i; + char buffer[1024]; + idStr text; + + GetSel( selStart, selEnd ); + line = LineFromChar( selStart ); + length = GetLine( line, buffer, sizeof( buffer ) ); + for ( numTabs = 0; numTabs < length; numTabs++ ) { + if ( !idStr::CharIsTab( buffer[numTabs] ) ) { + break; + } + } + bool first = true; + for ( i = numTabs; i < length; i++ ) { + if ( buffer[i] == '{' ) { + numTabs++; + first = false; + } else if ( buffer[i] == '}' && !first ) { + numTabs--; + } + } + text = "\r\n"; + for ( i = 0; i < numTabs; i++ ) { + text.Append( '\t' ); + } + ReplaceSel( text, TRUE ); + return; + } + } + + m_TextDoc->Freeze( NULL ); + + CRichEditCtrl::OnKeyDown( nKey, nRepCnt, nFlags ); + + UpdateVisibleRange(); + + m_TextDoc->Unfreeze( NULL ); +} + +/* +================ +CSyntaxRichEditCtrl::OnChar +================ +*/ +void CSyntaxRichEditCtrl::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ) { + + if ( nChar == VK_TAB ) { + return; // tab is handle in OnKeyDown + } + + CRichEditCtrl::OnChar( nChar, nRepCnt, nFlags ); + + // if the auto-complete list box is up + if ( autoCompleteStart >= 0 ) { + long selStart, selEnd; + + if ( charType[nChar] == CT_NAME ) { + AutoCompleteUpdate(); + return; + } else if ( nChar == VK_BACK ) { + GetSel( selStart, selEnd ); + if ( selStart > autoCompleteStart ) { + AutoCompleteUpdate(); + } else { + AutoCompleteHide(); + } + return; + } else { + AutoCompleteHide(); + } + } + + // if the function parameter tool tip is up + if ( funcParmToolTipStart >= 0 ) { + long selStart, selEnd; + + if ( nChar == ')' || nChar == VK_ESCAPE ) { + ToolTipHide(); + } else if ( nChar == VK_BACK ) { + GetSel( selStart, selEnd ); + if ( selStart < funcParmToolTipStart ) { + ToolTipHide(); + } + } + } + + // show keyword auto-completion + if ( keyWordAutoCompletion && charType[nChar] == CT_NAME && funcParmToolTipStart < 0 ) { + long selStart, selEnd; + int line, column, length, i; + char buffer[1024]; + + GetSel( selStart, selEnd ); + line = LineFromChar( selStart ); + length = GetLine( line, buffer, sizeof( buffer ) ); + column = selStart - LineIndex( line ); + if ( column <= 1 || charType[buffer[column-2]] == CT_WHITESPACE ) { + if ( column >= length-1 || charType[buffer[column]] == CT_WHITESPACE ) { + + autoCompleteListBox.ResetContent(); + for ( i = 0; keyWords[i].keyWord; i++ ) { + autoCompleteListBox.AddString( keyWords[i].keyWord ); + } + AutoCompleteShow( selStart - 1 ); + } + } + return; + } + + // highlight braced sections + if ( nChar == '{' ) { + BracedSectionStart( '{', '}' ); + } else if ( nChar == '}' ) { + BracedSectionEnd( '{', '}' ); + } else if ( nChar == '(' ) { + BracedSectionStart( '(', ')' ); + } else if ( nChar == ')' ) { + BracedSectionEnd( '(', ')' ); + } else if ( nChar == '[' ) { + BracedSectionStart( '[', ']' ); + } else if ( nChar == ']' ) { + BracedSectionEnd( '[', ']' ); + } else if ( nChar == '<' ) { + BracedSectionStart( '<', '>' ); + } else if ( nChar == '>' ) { + BracedSectionEnd( '<', '>' ); + } + + // show object member auto-completion + if ( nChar == '.' && GetObjectMembers && funcParmToolTipStart < 0 ) { + int charIndex; + CString name; + + if ( GetNameBeforeCurrentSelection( name, charIndex ) ) { + autoCompleteListBox.ResetContent(); + if ( GetObjectMembers( name, autoCompleteListBox ) ) { + AutoCompleteShow( charIndex ); + } + } + return; + } + + // show function parameter tool tip + if ( nChar == '(' && GetFunctionParms ) { + int charIndex; + CString name; + + if ( GetNameBeforeCurrentSelection( name, charIndex ) ) { + CString parmString; + if ( GetFunctionParms( name, parmString ) ) { + ToolTipShow( charIndex, parmString ); + } + } + return; + } +} + +/* +================ +CSyntaxRichEditCtrl::OnLButtonDown +================ +*/ +void CSyntaxRichEditCtrl::OnLButtonDown( UINT nFlags, CPoint point ) { + + if ( autoCompleteStart >= 0 ) { + AutoCompleteHide(); + } + + BracedSectionHide(); + + CRichEditCtrl::OnLButtonDown( nFlags, point ); +} + +/* +================ +CSyntaxRichEditCtrl::OnMouseWheel +================ +*/ +BOOL CSyntaxRichEditCtrl::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ) { + if ( autoCompleteStart >= 0 ) { + int sel; + + if ( zDelta > 0 ) { + sel = Max( 0, autoCompleteListBox.GetCurSel() - ( zDelta / WHEEL_DELTA ) ); + } else { + sel = Min( autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() - ( zDelta / WHEEL_DELTA ) ); + } + autoCompleteListBox.SetCurSel( sel ); + return TRUE; + } + + m_TextDoc->Freeze( NULL ); + + LineScroll( -3 * ( (int) zDelta ) / WHEEL_DELTA, 0 ); + + UpdateVisibleRange(); + + m_TextDoc->Unfreeze( NULL ); + + return TRUE; +} + +/* +================ +CSyntaxRichEditCtrl::OnMouseMove +================ +*/ +void CSyntaxRichEditCtrl::OnMouseMove( UINT nFlags, CPoint point ) { + CRichEditCtrl::OnMouseMove( nFlags, point ); + + if ( point != mousePoint ) { + mousePoint = point; + + // remove tool tip and activate the tool tip control, otherwise + // tool tips stop working until the mouse moves over another window first + AFX_MODULE_THREAD_STATE *state = AfxGetModuleThreadState(); + state->m_pToolTip->Pop(); + state->m_pToolTip->Activate( TRUE ); + } +} + +/* +================ +CSyntaxRichEditCtrl::OnSize +================ +*/ +void CSyntaxRichEditCtrl::OnSize( UINT nType, int cx, int cy ) { + m_TextDoc->Freeze( NULL ); + + CRichEditCtrl::OnSize( nType, cx, cy ); + + m_TextDoc->Unfreeze( NULL ); + + UpdateVisibleRange(); +} + +/* +================ +CSyntaxRichEditCtrl::OnVScroll +================ +*/ +void CSyntaxRichEditCtrl::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { + m_TextDoc->Freeze( NULL ); + + CRichEditCtrl::OnVScroll( nSBCode, nPos, pScrollBar ); + + SetFocus(); + + UpdateVisibleRange(); + + m_TextDoc->Unfreeze( NULL ); +} + +/* +================ +CSyntaxRichEditCtrl::OnProtected +================ +*/ +void CSyntaxRichEditCtrl::OnProtected( NMHDR *pNMHDR, LRESULT *pResult ) { + ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR; + + *pResult = 0; + + updateRange = pEP->chrg; + + switch( pEP->msg ) { + case WM_MOUSEMOVE: { + break; + } + case WM_SETTEXT: { + updateRange.cpMin = pEP->chrg.cpMin; + updateRange.cpMax = pEP->chrg.cpMin + strlen( (LPCTSTR) pEP->lParam ); + break; + } + case WM_CUT: { + break; + } + case WM_COPY: { + break; + } + case WM_PASTE: { + break; + } + case WM_CLEAR: { + break; + } + case WM_UNDO: { + break; + } + default: { + break; + } + } +} + +/* +================ +CSyntaxRichEditCtrl::OnChange +================ +*/ +void CSyntaxRichEditCtrl::OnChange() { + long selStart, selEnd; + + if ( !updateSyntaxHighlighting ) { + return; + } + + GetSel( selStart, selEnd ); + selStart = Min( selStart, updateRange.cpMin ); + selEnd = Max( selEnd, updateRange.cpMax ); + + HighlightSyntax( selStart, selEnd ); + + // send EN_CHANGE notification to parent window + NMHDR pNMHDR; + pNMHDR.hwndFrom = GetSafeHwnd(); + pNMHDR.idFrom = GetDlgCtrlID(); + pNMHDR.code = EN_CHANGE; + GetParent()->SendMessage( WM_NOTIFY, ( EN_CHANGE << 16 ) | GetDlgCtrlID(), (LPARAM)&pNMHDR ); +} + +/* +================ +CSyntaxRichEditCtrl::OnAutoCompleteListBoxChange +================ +*/ +void CSyntaxRichEditCtrl::OnAutoCompleteListBoxChange() { + // steal focus back from the auto-complete list box + SetFocus(); +} + +/* +================ +CSyntaxRichEditCtrl::OnAutoCompleteListBoxDblClk +================ +*/ +void CSyntaxRichEditCtrl::OnAutoCompleteListBoxDblClk() { + // steal focus back from the auto-complete list box + SetFocus(); + + // insert current auto-complete selection + AutoCompleteInsertText(); + AutoCompleteHide(); +} diff --git a/tools/comafx/CSyntaxRichEditCtrl.h b/tools/comafx/CSyntaxRichEditCtrl.h new file mode 100644 index 000000000..4051fa91c --- /dev/null +++ b/tools/comafx/CSyntaxRichEditCtrl.h @@ -0,0 +1,227 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CSYNTAXRICHEDITCTR_H__ +#define __CSYNTAXRICHEDITCTR_H__ + +/* +=============================================================================== + + Rich Edit Control with: + + - syntax highlighting + - braced section highlighting + - braced section auto-indentation + - multi-line tabs + - keyword auto-completion + - object member auto-completion + - keyword tool tip + - function parameter tool tip + +=============================================================================== +*/ + +// use #import on Vista to generate .tlh header to copy from intermediate compile directory to local directory for subsequent builds +// rename: avoids warning C4278: 'FindText': identifier in type library 'riched20.dll' is already a macro; use the 'rename' qualifier +// no_auto_exclude: avoids warnings +// no_namespace: no longer using this option, which avoids variable redifinition compile errors on Vista +//#define GENERATE_TLH +#ifdef GENERATE_TLH +# import "riched20.dll" raw_interfaces_only, raw_native_types, named_guids, no_auto_exclude, no_implementation, rename( "FindText", "FindShit" ) +#else +# include "riched20.tlh" +#endif + +static const char * FONT_NAME = "Courier"; +static const int FONT_HEIGHT = 10; +static const int FONT_WIDTH = 8; +static const int TAB_SIZE = 4; + +static const COLORREF SRE_COLOR_BLACK = RGB( 0, 0, 0 ); +static const COLORREF SRE_COLOR_WHITE = RGB( 255, 255, 255 ); +static const COLORREF SRE_COLOR_RED = RGB( 255, 0, 0 ); +static const COLORREF SRE_COLOR_GREEN = RGB( 0, 255, 0 ); +static const COLORREF SRE_COLOR_BLUE = RGB( 0, 0, 255 ); +static const COLORREF SRE_COLOR_YELLOW = RGB( 255, 255, 0 ); +static const COLORREF SRE_COLOR_MAGENTA = RGB( 255, 0, 255 ); +static const COLORREF SRE_COLOR_CYAN = RGB( 0, 255, 255 ); +static const COLORREF SRE_COLOR_ORANGE = RGB( 255, 128, 0 ); +static const COLORREF SRE_COLOR_PURPLE = RGB( 150, 0, 150 ); +static const COLORREF SRE_COLOR_PINK = RGB( 186, 102, 123 ); +static const COLORREF SRE_COLOR_GREY = RGB( 85, 85, 85 ); +static const COLORREF SRE_COLOR_BROWN = RGB( 100, 90, 20 ); +static const COLORREF SRE_COLOR_LIGHT_GREY = RGB( 170, 170, 170 ); +static const COLORREF SRE_COLOR_LIGHT_BROWN = RGB( 170, 150, 20 ); +static const COLORREF SRE_COLOR_DARK_GREEN = RGB( 0, 128, 0 ); +static const COLORREF SRE_COLOR_DARK_CYAN = RGB( 0, 150, 150 ); +static const COLORREF SRE_COLOR_DARK_YELLOW = RGB( 220, 200, 20 ); + +typedef struct { + const char * keyWord; + COLORREF color; + const char * description; +} keyWord_t; + +typedef bool (*objectMemberCallback_t)( const char *objectName, CListBox &listBox ); +typedef bool (*toolTipCallback_t)( const char *name, CString &string ); + + +class CSyntaxRichEditCtrl : public CRichEditCtrl { +public: + CSyntaxRichEditCtrl( void ); + ~CSyntaxRichEditCtrl( void ); + + void Init( void ); + + void SetCaseSensitive( bool caseSensitive ); + void AllowPathNames( bool allow ); + void EnableKeyWordAutoCompletion( bool enable ); + void SetKeyWords( const keyWord_t kws[] ); + bool LoadKeyWordsFromFile( const char *fileName ); + void SetObjectMemberCallback( objectMemberCallback_t callback ); + void SetFunctionParmCallback( toolTipCallback_t callback ); + void SetToolTipCallback( toolTipCallback_t callback ); + + void SetDefaultColor( const COLORREF color ); + void SetCommentColor( const COLORREF color ); + void SetStringColor( const COLORREF color, const COLORREF altColor = -1 ); + void SetLiteralColor( const COLORREF color ); + + COLORREF GetForeColor( int charIndex ) const; + COLORREF GetBackColor( int charIndex ) const; + + void GetCursorPos( int &line, int &column, int &character ) const; + CHARRANGE GetVisibleRange( void ) const; + + void GetText( idStr &text ) const; + void GetText( idStr &text, int startCharIndex, int endCharIndex ) const; + void SetText( const char *text ); + + void GoToLine( int line ); + bool FindNext( const char *find, bool matchCase, bool matchWholeWords, bool searchForward ); + int ReplaceAll( const char *find, const char *replace, bool matchCase, bool matchWholeWords ); + void ReplaceText( int startCharIndex, int endCharIndex, const char *replace ); + +protected: + virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const; + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg UINT OnGetDlgCode(); + afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnKeyDown( UINT nKey, UINT nRepCnt, UINT nFlags ); + afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); + afx_msg BOOL OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ); + afx_msg void OnMouseMove( UINT nFlags, CPoint point ); + afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ); + afx_msg void OnSize( UINT nType, int cx, int cy ); + afx_msg void OnProtected( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnChange(); + afx_msg void OnAutoCompleteListBoxChange(); + afx_msg void OnAutoCompleteListBoxDblClk(); + + DECLARE_MESSAGE_MAP() + + // settings + CHARFORMAT2 defaultCharFormat; + COLORREF defaultColor; + COLORREF singleLineCommentColor; + COLORREF multiLineCommentColor; + COLORREF stringColor[2]; + COLORREF literalColor; + COLORREF braceHighlightColor; + + typedef enum { + CT_WHITESPACE, + CT_COMMENT, + CT_STRING, + CT_LITERAL, + CT_NUMBER, + CT_NAME, + CT_PUNCTUATION + } charType_t; + + int charType[256]; + + idList keyWordsFromFile; + const keyWord_t * keyWords; + int * keyWordLengths; + COLORREF * keyWordColors; + idHashIndex keyWordHash; + + bool caseSensitive; + bool allowPathNames; + bool keyWordAutoCompletion; + + objectMemberCallback_t GetObjectMembers; + toolTipCallback_t GetFunctionParms; + toolTipCallback_t GetToolTip; + + // run-time variables + tom::ITextDocument * m_TextDoc; + tom::ITextFont * m_DefaultFont; + + CHARRANGE updateRange; + bool updateSyntaxHighlighting; + int stringColorIndex; + int stringColorLine; + + int autoCompleteStart; + CListBox autoCompleteListBox; + + int funcParmToolTipStart; + CEdit funcParmToolTip; + + int bracedSection[2]; + + CPoint mousePoint; + CToolTipCtrl * keyWordToolTip; + TCHAR * m_pchTip; + WCHAR * m_pwchTip; + +protected: + void InitFont( void ); + void InitSyntaxHighlighting( void ); + void SetCharType( int first, int last, int type ); + void SetDefaultFont( int startCharIndex, int endCharIndex ); + void SetColor( int startCharIndex, int endCharIndex, COLORREF foreColor, COLORREF backColor, bool bold ); + + void FreeKeyWordsFromFile( void ); + int FindKeyWord( const char *keyWord, int length ) const; + + void HighlightSyntax( int startCharIndex, int endCharIndex ); + void UpdateVisibleRange( void ); + + bool GetNameBeforeCurrentSelection( CString &name, int &charIndex ) const; + bool GetNameForMousePosition( idStr &name ) const; + + void AutoCompleteInsertText( void ); + void AutoCompleteUpdate( void ); + void AutoCompleteShow( int charIndex ); + void AutoCompleteHide( void ); + + void ToolTipShow( int charIndex, const char *string ); + void ToolTipHide( void ); + + bool BracedSectionStart( char braceStartChar, char braceEndChar ); + bool BracedSectionEnd( char braceStartChar, char braceEndChar ); + void BracedSectionAdjustEndTabs( void ); + void BracedSectionShow( void ); + void BracedSectionHide( void ); +}; + +#endif /* !__CSYNTAXRICHEDITCTR_H__ */ diff --git a/tools/comafx/DialogColorPicker.cpp b/tools/comafx/DialogColorPicker.cpp new file mode 100644 index 000000000..7b08d08b5 --- /dev/null +++ b/tools/comafx/DialogColorPicker.cpp @@ -0,0 +1,1305 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/Radiant_resource.h" +#include "DialogColorPicker.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +// Old color picker + +class CMyColorDialog : public CColorDialog +{ + DECLARE_DYNCREATE(CMyColorDialog); + // Construction +public: + CMyColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd *pParentWnd = NULL ); + virtual int DoModal(); + +protected: + enum { NCUSTCOLORS = 16 }; + static COLORREF c_CustColors[NCUSTCOLORS]; + static COLORREF c_LastCustColors[NCUSTCOLORS]; + static bool c_NeedToInitCustColors; + static void InitCustColors(); + static void SaveCustColors(); + + // Dialog Data + //{{AFX_DATA(CMyColorDialog) + //}}AFX_DATA + +protected: + // ClassWizard generate virtual function overrides + //{{AFX_VIRTUAL(CMyColorDialog) + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + // Generated message map functions + //{{AFX_MSG(CMyColorDialog) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +IMPLEMENT_DYNCREATE( CMyColorDialog, CColorDialog ) + +bool CMyColorDialog::c_NeedToInitCustColors = true; +COLORREF CMyColorDialog::c_CustColors[]; +COLORREF CMyColorDialog::c_LastCustColors[]; + +#define SECTION _T("Custom Colors") + +void CMyColorDialog::InitCustColors() { + for ( int i = 0; i < NCUSTCOLORS; i++) { + CString entry; + entry.Format( "tool_color%d", i); + idCVar *cvar = cvarSystem->Find( entry ); + if ( cvar ) { + c_LastCustColors[i] = c_CustColors[i] = cvar->GetInteger(); + } else { + c_LastCustColors[i] = c_CustColors[i] = RGB( 255, 255, 255 ); + } + } + c_NeedToInitCustColors= false; +} + +void CMyColorDialog::SaveCustColors() { + for (int i = 0; i < NCUSTCOLORS; i++) { + if ( c_LastCustColors[i] != c_CustColors[i] ) { + CString entry; + entry.Format( "tool_color%d", i ); + if ( c_CustColors[i] == RGB( 255, 255, 255 ) ) { + cvarSystem->SetCVarString( entry, "" ); + } else { + cvarSystem->SetCVarString( entry, va( "%d", c_CustColors[i] ), CVAR_TOOL ); + } + c_LastCustColors[i] = c_CustColors[i]; + } + } +} + +CMyColorDialog::CMyColorDialog( COLORREF clrInit, DWORD dwFlags, + CWnd* pParentWnd) : CColorDialog(clrInit,dwFlags,pParentWnd) +{ + //{{AFX_DATA_INIT(CMyColorDialog) + //}}AFX_DATA_INIT + if (c_NeedToInitCustColors) { + InitCustColors(); + } + m_cc.lpCustColors = c_CustColors; +} + +int CMyColorDialog::DoModal() { + int code = CColorDialog::DoModal(); + SaveCustColors(); + return code; +} + +void CMyColorDialog::DoDataExchange(CDataExchange* pDX) { + // overridden (calls this base class) + CColorDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CMyColorDialog) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CMyColorDialog, CColorDialog) +//{{AFX_MSG_MAP(CMyColorDialog) +//}}AFX_MSG_MAP +END_MESSAGE_MAP() + +COLORREF DoOldColor(COLORREF cr) { + CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT | CC_ANYCOLOR); + if (dlg.DoModal() == IDOK) { + return dlg.GetColor(); + } + return cr; +} + +// New color picker + +// Original ColorPicker/DIB source by Rajiv Ramachandran +// included with Permission from the author + +#define RADUIS 100 + +#define IN_NOTHING 0 +#define IN_CIRCLE 1 +#define IN_BRIGHT 2 +#define IN_OVERBRIGHT 3 + +int Distance(CPoint pt1,CPoint pt2); + + +double Slope( CPoint pt1,CPoint pt2 ) { + double x,y; + + y = pt2.y - pt1.y; + x = pt2.x - pt1.x; + if( x ) { + return y/x; + } else { + return BAD_SLOPE; + } +} + +CPoint Intersection(LineDesc l1,LineDesc l2) +{ + CPoint pt; + double x,y; + + if(l1.slope == l2.slope) + { + // Parallel lines, no intersection + return CPoint(0,0); + } + else + if(l1.slope == BAD_SLOPE ) + { + // First Line is vertical, eqn is x=0 + // Put x = 0 in second line eqn to get y; + x = l1.x; + y = l2.slope * x + l2.c; + } + else + if(l2.slope == BAD_SLOPE) + { + // second line is vertical Equation of line is x=0; + // Put x = 0 in first line eqn to get y; + x = l2.x; + y = l1.slope * l2.x + l1.c; + } + else + { + y = ((l1.c * l2.slope) - (l2.c * l1.slope))/(l2.slope - l1.slope); + x = (y - l1.c)/l1.slope; + } + + return CPoint((int)x,(int)y); +} + +double FindC(LineDesc& l) +{ + double c; + + if(l.slope == BAD_SLOPE) + { + c = l.y; + } + else + { + c = l.y - l.slope * l.x; + } + return c; +} + +CPoint PointOnLine(CPoint pt1,CPoint pt2,int len,int maxlen ) +{ + double x,y,m,a,c,C,A; + double a2,c2,m2,B; + CPoint opt = pt1; + CPoint pt; + + pt1.y *= -1; + pt2.y *= -1; + + a = (double)len; + + if(pt2.x != pt1.x) + { + m = (double)(pt2.y - pt1.y)/(pt2.x - pt1.x); + m2 = m*m; + a2 = a*a; + c = (double)pt1.y - m * (double)pt1.x; + c2 = c*c; + + + A = 1.0; + + x = pt1.x; + + B = 2.0 * pt1.x; + + x *= x; + C = x - a2/(m2 + 1); + + x = (B + idMath::Sqrt(B*B - (4.0*A*C)))/(2.0*A); + y = m*x + c; + pt = CPoint((int)x,(int)y); + if(Distance(pt,pt1) > maxlen || Distance(pt,pt2) > maxlen) + { + x = (B - idMath::Sqrt(B*B - (4.0*A*C)))/(2.0 * A); + y = m*x + c; + pt = CPoint((int)x,(int)y); + } + } + else + { + a2 = a*a; + y = idMath::Sqrt(a2); + x = 0; + pt = CPoint((int)x,(int)y); + pt += pt1; + if(Distance(pt,pt1) > maxlen || Distance(pt,pt2) > maxlen) + { + y = -1.0 *y; + pt = CPoint((int)x,(int)y); + pt+=pt1; + } + } + pt.y *= -1; + return pt; +} + + +int Distance(CPoint pt1,CPoint pt2) +{ + double a; + int x,y; + + y = (pt1.y - pt2.y); + y *= y; + + x = (pt1.x - pt2.x); + x *= x; + + a = (double)x + (double)y ; + a = idMath::Sqrt(a); + return (int)a; +} + +double AngleFromPoint(CPoint pt,CPoint center) +{ + double x,y; + + y = -1 * (pt.y - center.y); + x = pt.x - center.x; + if(x == 0 && y == 0) + { + return 0.0; + } + else + { + return atan2(y,x); + } +} + +CPoint PtFromAngle(double angle,double sat,CPoint center) +{ + angle = DEG2RAD(angle); + sat = TOSCALE(sat); + + double x,y; + + x = sat * cos(angle); + y = sat * sin(angle); + + CPoint pt; + + pt = CPoint((int)x,(int)y); + pt.y *= -1; + pt += center; + return pt; +} + +RGBType HSVType::toRGB() +{ + RGBType rgb; + + if(!h && !s) + { + rgb.r = rgb.g = rgb.b = v; + } + + double min,max,delta,hue; + + max = v; + delta = (max * s)/255.0; + min = max - delta; + + hue = h; + if(h > 300 || h <= 60) + { + rgb.r = (int)max; + if(h > 300) + { + rgb.g = (int)min; + hue = (hue - 360.0)/60.0; + rgb.b = (int)((hue * delta - min) * -1); + } + else + { + rgb.b = (int)min; + hue = hue / 60.0; + rgb.g = (int)(hue * delta + min); + } + } + else if(h > 60 && h < 180) + { + rgb.g = (int)max; + if(h < 120) + { + rgb.b = (int)min; + hue = (hue/60.0 - 2.0 ) * delta; + rgb.r = (int)(min - hue); + } + else + { + rgb.r = (int)min; + hue = (hue/60 - 2.0) * delta; + rgb.b = (int)(min + hue); + } + } + else + { + rgb.b = (int)max; + if(h < 240) + { + rgb.r = (int)min; + hue = (hue/60.0 - 4.0 ) * delta; + rgb.g = (int)(min - hue); + } + else + { + rgb.g = (int)min; + hue = (hue/60 - 4.0) * delta; + rgb.r = (int)(min + hue); + } + } + return rgb; +} + + +HSVType RGBType::toHSV() +{ + HSVType hsv; + + double min,max,delta,temp; + + min = __min(r,__min(g,b)); + max = __max(r,__max(g,b)); + delta = max - min; + + hsv.v = (int)max; + if(!delta) + { + hsv.h = hsv.s = 0; + } + else + { + temp = delta/max; + hsv.s = (int)(temp*255); + + if(r == (int)max) + { + temp = (double)(g-b)/delta; + } + else + if(g == (int)max) + { + temp = 2.0 + ((double)(b-r)/delta); + } + else + { + temp = 4.0 + ((double)(r-g)/delta); + } + temp *= 60; + if(temp < 0) + { + temp+=360; + } + if(temp == 360) + { + temp = 0; + } + hsv.h = (int)temp; + } + return hsv; + +} +///////////////////////////////////////////////////////////////////////////// +// CDialogColorPicker dialog + + +CDialogColorPicker::CDialogColorPicker( COLORREF c, CWnd* pParent /*=NULL*/) + : CDialog(CDialogColorPicker::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogColorPicker) + m_overBright = 0.0f; + //}}AFX_DATA_INIT + + Vertex = CPoint(102,108); + Top = CPoint(102,9); + Left = CPoint(23,147); + Right = CPoint(181,147); + + color.r = GetRValue(c); + color.g = GetGValue(c); + color.b = GetBValue(c); + + m_OldColor = color; + hsvColor = color.toHSV(); + m_bInMouse = FALSE; + m_bInitOver = FALSE; + m_bInDrawAll = FALSE; + overBright = 1.0f; + UpdateParent = NULL; +} + +CDialogColorPicker::~CDialogColorPicker() +{ + if(m_RgbBitmap.GetSafeHandle()) + { + m_RgbBitmap.DeleteObject(); + } + if(m_HsbBitmap.GetSafeHandle()) + { + m_HsbBitmap.DeleteObject(); + } +} + + +BEGIN_MESSAGE_MAP(CDialogColorPicker, CDialog) + //{{AFX_MSG_MAP(CDialogColorPicker) + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_SYSCOLORCHANGE() + ON_WM_PAINT() + ON_EN_CHANGE(IDC_EDIT_BLUE, OnChangeEditBlue) + ON_EN_CHANGE(IDC_EDIT_GREEN, OnChangeEditGreen) + ON_EN_CHANGE(IDC_EDIT_HUE, OnChangeEditHue) + ON_EN_CHANGE(IDC_EDIT_RED, OnChangeEditRed) + ON_EN_CHANGE(IDC_EDIT_SAT, OnChangeEditSat) + ON_EN_CHANGE(IDC_EDIT_VAL, OnChangeEditVal) + ON_EN_CHANGE(IDC_EDIT_OVERBRIGHT, OnChangeEditOverbright) + ON_BN_CLICKED(IDC_BTN_OLDCOLOR, OnBtnColor) + ON_WM_TIMER() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogColorPicker message handlers + +void CDialogColorPicker::OnLButtonDown(UINT nFlags, CPoint point) { + if(hsbRect.PtInRect(point)) { + m_bInMouse = FALSE; + if(InCircle(point)) { + m_nMouseIn = IN_CIRCLE; + } else if (InBright(point)) { + m_nMouseIn = IN_BRIGHT; + } else if (InOverBright(point)) { + m_nMouseIn = IN_OVERBRIGHT; + } else { + m_nMouseIn = IN_NOTHING; + } + + if(m_nMouseIn) { + SetCapture(); + TrackPoint(point); + } + } + else if (rgbRect.PtInRect(point)) { + m_nMouseIn = IN_NOTHING; + if(rects[RED].PtInRect(point)) { + SetCapture(); + m_bInMouse = TRUE; + nIndex = RED; + } else if (rects[GREEN].PtInRect(point)) { + SetCapture(); + m_bInMouse = TRUE; + nIndex = GREEN; + } else if (rects[BLUE].PtInRect(point)) { + SetCapture(); + m_bInMouse = TRUE; + nIndex = BLUE; + } + } + + CDialog::OnLButtonDown(nFlags, point); +} + +void CDialogColorPicker::OnLButtonUp(UINT nFlags, CPoint point) +{ + if(GetCapture() == this) + { + ReleaseCapture(); + m_bInMouse = FALSE; + } + CDialog::OnLButtonUp(nFlags, point); +} + +void CDialogColorPicker::OnMouseMove(UINT nFlags, CPoint point) +{ + if(GetCapture() == this && m_nMouseIn) + { + TrackPoint(point); + } + else if(GetCapture() == this && m_bInMouse) + { + double val; + BOOL bChange = FALSE; + + if(nIndex == RED) + { + if(point.y > Vertex.y) + { + point.y = Vertex.y; + } + point.x = Vertex.x; + val = Distance(point,Vertex); + if(val > RedLen) + { + val = RedLen; + } + CClientDC dc(this); + DrawLines(&dc); + val = (val/RedLen)*255; + color.r = (int)val; + CPoint pt; + pt = PointOnLine(Vertex,Top,(color.r*RedLen)/255,RedLen); + rects[RED] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH ); + CalcCuboid(); + DrawLines(&dc); + bChange = TRUE; + } + else if(nIndex == GREEN) + { + if(point.x > Vertex.x) + { + point.x = Vertex.x; + } + point.y = rects[GREEN].top + RECT_WIDTH; + val = Distance(point,Vertex); + if(val > GreenLen) + { + val = GreenLen; + } + CClientDC dc(this); + DrawLines(&dc); + val = (val/GreenLen)*255; + color.g = (int)val; + CPoint pt; + pt = PointOnLine(Vertex,Left,(color.g*GreenLen)/255,GreenLen); + rects[GREEN] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH ); + CalcCuboid(); + DrawLines(&dc); + bChange = TRUE; + } + else if(nIndex == BLUE) + { + if(point.x < Vertex.x) + { + point.x = Vertex.x; + } + point.y = rects[BLUE].top + RECT_WIDTH; + val = Distance(point,Vertex); + if(val > BlueLen) + { + val = BlueLen; + } + CClientDC dc(this); + DrawLines(&dc); + val = (val/BlueLen)*255; + color.b = (int)val; + CPoint pt; + pt = PointOnLine(Vertex,Right,(color.b*GreenLen)/255,BlueLen); + rects[BLUE] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH ); + CalcCuboid(); + DrawLines(&dc); + bChange = TRUE; + } + if(bChange) + { + hsvColor = color.toHSV(); + SetEditVals(); + CClientDC dc(this); + DrawMarkers(&dc); + CalcRects(); + SetDIBPalette(); + + InvalidateRect(&brightRect,FALSE); + DrawHSB(&dc); + } + } + CDialog::OnMouseMove(nFlags, point); +} + +void CDialogColorPicker::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + DrawHSB(&dc); + DrawRGB(&dc); +} + +BOOL CDialogColorPicker::OnInitDialog() +{ + CDialog::OnInitDialog(); + + GetDlgItem(IDC_STATIC_RGB_RECT)->GetWindowRect(&rgbRect); + GetDlgItem(IDC_STATIC_HSB_RECT)->GetWindowRect(&hsbRect); + ScreenToClient(&rgbRect); + ScreenToClient(&hsbRect); + + GetDlgItem(IDC_STATIC_NEWCOLOR)->GetWindowRect(&NewColorRect); + ScreenToClient(&NewColorRect); + + + CWindowDC dc(NULL); + CSize bmSize; + + // Set Up HSB + + memDC.CreateCompatibleDC(&dc); + + LoadMappedBitmap(m_HsbBitmap,IDB_BITMAP_HSB,bmSize); + hsbWidth = bmSize.cx; + hsbHeight = bmSize.cy; + + hsbRect.InflateRect(-5,-5); + hsbRect.top += 20; + hsbRect.left += 10; + + m_Centre = CPoint(RADIUS,RADIUS); + m_Centre += CPoint(hsbRect.left,hsbRect.top); + + brightRect = CRect(hsbRect.left+hsbWidth+20,hsbRect.top,hsbRect.left+hsbWidth+20+20,hsbRect.top + hsbHeight); + overBrightRect = brightRect; + overBrightRect.OffsetRect(brightRect.Width() + 5, 0); + + CreateBrightDIB(); + CalcRects(); + SetDIBPalette(); + + + // Set Up RGB + + LoadMappedBitmap(m_RgbBitmap,IDB_BITMAP_RGB,bmSize); + rgbWidth = bmSize.cx; + rgbHeight = bmSize.cy; + + rgbRect.InflateRect(-5,-5); + rgbRect.top+=10; + rgbRect.left-=3; + + CPoint pt = CPoint(rgbRect.left,rgbRect.top); + + Top += pt; + Left += pt; + Right += pt; + Vertex += pt; + // TODO: Add your specialized code here and/or call the base class + + RedLen = Distance(Vertex,Top); + GreenLen = Distance(Vertex,Left); + BlueLen = Distance(Vertex,Right); + + CalcSlopes(); + CalcCuboid(); + + SetSpinVals(); + SetEditVals(); + + m_bInitOver = TRUE; + + SetTimer(0, 50, NULL); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CDialogColorPicker::DrawMarkers(CDC *pDC) +{ + if(m_CurrentRect.Width()) + { + CPen *oldPen; + CBrush *oldBrush; + int oldMode; + CRect cr = m_CurrentRect; + + oldPen = (CPen *)pDC->SelectStockObject(WHITE_PEN); + oldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH); + + oldMode = pDC->SetROP2(R2_XORPEN); + + pDC->Rectangle(&cr); + CPen pen; + pen.CreatePen(PS_SOLID,2,RGB(255,255,255)); + pDC->SelectObject(&pen); + pDC->Rectangle(&brightMark); + + pDC->SelectObject(oldPen); + pDC->SelectObject(oldBrush); + pDC->SetROP2(oldMode); + pen.DeleteObject(); + } +} + +BOOL CDialogColorPicker::InCircle(CPoint pt) +{ + return Distance(pt,m_Centre) <= RADIUS; +} + +BOOL CDialogColorPicker::InBright(CPoint pt) +{ + return brightRect.PtInRect(pt); +} + +BOOL CDialogColorPicker::InOverBright(CPoint pt) +{ + return overBrightRect.PtInRect(pt); +} + +void CDialogColorPicker::TrackPoint(CPoint pt) +{ + if(m_nMouseIn == IN_CIRCLE) + { + CClientDC dc(this); + + DrawMarkers(&dc); + + hsvColor.h = (int)RAD2DEG(AngleFromPoint(pt,m_Centre)); + if(hsvColor.h < 0) + { + hsvColor.h += 360; + } + hsvColor.s = (int)SCALETOMAX(Distance(pt,m_Centre)); + if(hsvColor.s > 255) hsvColor.s = 255; + + SetDIBPalette(); + CalcRects(); + + + InvalidateRect(&brightRect,FALSE); + + DrawMarkers(&dc); + + color = hsvColor.toRGB(); + SetEditVals(); + DrawLines(&dc); + CalcCuboid(); + DrawRGB(&dc); + + } + else if(m_nMouseIn == IN_BRIGHT) + { + double d; + d = brightRect.bottom - pt.y; + d *= 255; + d /= brightRect.Height(); + if(d < 0 ) d = 0; + if(d > 255) d = 255; + CClientDC dc(this); + DrawMarkers(&dc); + hsvColor.v = (int)d; + CalcRects(); + DrawMarkers(&dc); + + color = hsvColor.toRGB(); + SetEditVals(); + DrawLines(&dc); + CalcCuboid(); + DrawRGB(&dc); + } +} + +void CDialogColorPicker::CreateBrightDIB() +{ + CDIB& d = m_BrightDIB; + + d.Create(brightRect.Width(),brightRect.Height(),8); + for(int i=0; i < d.Height(); i++) + { + memset(d.GetLinePtr(i),i,d.Width()); + } +} + +void CDialogColorPicker::SetDIBPalette() +{ + BYTE palette[768],*p; + HSVType h = hsvColor; + double d; + + d = 255.0/brightRect.Height(); + p = palette; + for(int i=brightRect.Height()-1; i >= 0 ;i--,p+=3) + { + h.v = (int)((double)i * d); + RGBType rgb = h.toRGB(); + p[0] = rgb.r; + p[1] = rgb.g; + p[2] = rgb.b; + } + m_BrightDIB.SetPalette(palette); +} + +void CDialogColorPicker::CalcRects() +{ + CPoint pt; + + pt = PtFromAngle(hsvColor.h,hsvColor.s,m_Centre); + m_CurrentRect = CRect(pt.x - RECT_WIDTH,pt.y - RECT_WIDTH,pt.x+RECT_WIDTH,pt.y + RECT_WIDTH); + + int y; + + y = (int)(((double)hsvColor.v/255)*brightRect.Height()); + y = brightRect.bottom - y; + brightMark = CRect(brightRect.left - 2, y - 4, brightRect.right+2,y+4); +} + + +void CDialogColorPicker::DrawHSB(CDC *pDC) +{ + if(m_HsbBitmap.GetSafeHandle()) + { + CBitmap *pOldBitmap ; + pOldBitmap = (CBitmap *)memDC.SelectObject(&m_HsbBitmap); + pDC->BitBlt(hsbRect.left,hsbRect.top,hsbWidth,hsbHeight,&memDC,0,0,SRCCOPY); + m_BrightDIB.BitBlt(pDC->m_hDC,brightRect.left,brightRect.top,brightRect.Width(),brightRect.Height(),0,0); + DrawMarkers(pDC); + memDC.SelectObject(pOldBitmap); + } +} + +void CDialogColorPicker::DrawRGB(CDC *pDC) +{ + if(m_RgbBitmap.GetSafeHandle()) + { + CBitmap *pOldBitmap ; + pOldBitmap = (CBitmap *)memDC.SelectObject(&m_RgbBitmap); + pDC->BitBlt(rgbRect.left,rgbRect.top,rgbWidth,rgbHeight,&memDC,0,0,SRCCOPY); + DrawLines(pDC); + memDC.SelectObject(pOldBitmap); + } +} + +void CDialogColorPicker::DrawLines(CDC *pDC) +{ + CPoint pt[3]; + + pt[0] = PointOnLine(Vertex,Top,(color.r*RedLen)/255,RedLen); + pt[1] = PointOnLine(Vertex,Left,(color.g*GreenLen)/255,GreenLen); + pt[2] = PointOnLine(Vertex,Right,(color.b*BlueLen)/255,BlueLen); + + COLORREF col = RGB(255,255,255); + CRect cr; + + for(int i = 0; i < 3; i++ ) { + cr = CRect(pt[i].x - RECT_WIDTH ,pt[i].y-RECT_WIDTH ,pt[i].x+RECT_WIDTH ,pt[i].y+RECT_WIDTH ); + rects[i] = cr; + DrawXorRect(pDC,cr); + } + + CPen *oldPen; + int oldMode; + + oldPen = (CPen *)pDC->SelectStockObject(WHITE_PEN); + oldMode = pDC->SetROP2(R2_XORPEN); + + /* + Draw the following lines : + + 1 -2 + 2 -3 + 3 - 4 + 4- 5 + 5 -2 + 5 - 6 + 6-7 + 7-4 + */ + pDC->MoveTo(m_Cuboid[1]); + pDC->LineTo(m_Cuboid[2]); + pDC->LineTo(m_Cuboid[3]); + pDC->LineTo(m_Cuboid[4]); + pDC->LineTo(m_Cuboid[5]); + pDC->LineTo(m_Cuboid[2]); + + pDC->MoveTo(m_Cuboid[5]); + pDC->LineTo(m_Cuboid[6]); + pDC->LineTo(m_Cuboid[7]); + pDC->LineTo(m_Cuboid[4]); + + pDC->MoveTo(m_Cuboid[1]); + pDC->LineTo(m_Cuboid[6]); + + pDC->SelectObject(oldPen); + pDC->SetROP2(oldMode); + + DrawFilledColor(pDC,NewColorRect,color.color()); +} + +void CDialogColorPicker::DrawXorRect(CDC *pDC,CRect& cr) +{ + CPen pen,*oldPen; + CBrush *oldBrush; + int oldMode; + + pen.CreatePen(PS_SOLID,1,RGB(255,255,255)); + oldPen = (CPen *)pDC->SelectObject(&pen); + oldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH); + oldMode =pDC->SetROP2(R2_XORPEN); + pDC->Rectangle(&cr); + pDC->SetROP2(oldMode); + pDC->SelectObject(oldPen); + pDC->SelectObject(oldBrush); + pen.DeleteObject(); + +} + +void CDialogColorPicker::CalcSlopes() +{ + lines[RED].slope = Slope(Top,Vertex); + lines[GREEN].slope = Slope(Left,Vertex); + lines[BLUE].slope = Slope(Right,Vertex); + + int i; + + for( i = 0; i < 3; i++ ) { + lines[i].x = Vertex.x; + lines[i].y = Vertex.y; + lines[i].c = FindC(lines[i]); + } +} + +/* + + Cuboid points + 0 = vertex + 1 = Red Axis + 2 = Red Green Intersection + 3 = Green Axis + 4 = Blue Green Intersection + 5 = Blue Green Red Intersection + 6 = Red Blue Intersection + 7 = Blue Axis + + Draw the following lines : + + 1 -2 + 2 -3 + 3 - 4 + 4- 5 + 5 -2 + 5 - 6 + 6-7 + 7-4 +*/ + +void CDialogColorPicker::CalcCuboid() +{ + double rLen,gLen,bLen; + + rLen = (double)(color.r*RedLen)/255; + gLen = (double)(color.g*GreenLen)/255; + bLen = (double)(color.b*BlueLen)/255; + + LineDesc l[12]; + + m_Cuboid[0] = Vertex; + m_Cuboid[1] = PointOnLine(Vertex,Top,(int)rLen,RedLen); + m_Cuboid[3] = PointOnLine(Vertex,Left,(int)gLen,GreenLen); + m_Cuboid[7] = PointOnLine(Vertex,Right,(int)bLen,BlueLen); + + l[0] = lines[RED]; + l[1] = lines[GREEN]; + l[2] = lines[BLUE]; + + l[3].slope = lines[GREEN].slope; + l[3].x = m_Cuboid[1].x; + l[3].y = m_Cuboid[1].y; + l[3].c = FindC(l[3]); + + l[4].slope = lines[RED].slope; + l[4].x = m_Cuboid[3].x; + l[4].y = m_Cuboid[3].y; + l[4].c = FindC(l[4]); + + l[5].slope = lines[BLUE].slope; + l[5].x = m_Cuboid[3].x; + l[5].y = m_Cuboid[3].y; + l[5].c = FindC(l[5]); + + l[6].slope = lines[GREEN].slope; + l[6].x = m_Cuboid[7].x; + l[6].y = m_Cuboid[7].y; + l[6].c = FindC(l[6]); + + l[10].slope = lines[BLUE].slope; + l[10].x = m_Cuboid[1].x; + l[10].y = m_Cuboid[1].y; + l[10].c = FindC(l[10]); + + l[11].slope = lines[RED].slope; + l[11].x = m_Cuboid[7].x; + l[11].y = m_Cuboid[7].y; + l[11].c = FindC(l[11]); + + m_Cuboid[2] = Intersection(l[3],l[4]); + m_Cuboid[4] = Intersection(l[5],l[6]); + m_Cuboid[6] = Intersection(l[10],l[11]); + + l[7].slope = lines[RED].slope; + l[7].x = m_Cuboid[4].x; + l[7].y = m_Cuboid[4].y; + l[7].c = FindC(l[7]); + + l[8].slope = lines[BLUE].slope; + l[8].x = m_Cuboid[2].x; + l[8].y = m_Cuboid[2].y; + l[8].c = FindC(l[8]); + + m_Cuboid[5] = Intersection(l[7],l[8]); + +} + +void CDialogColorPicker::SetSpinVals() +{ + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_RED))->SetRange(0,255); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_GREEN))->SetRange(0,255); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_BLUE))->SetRange(0,255); + + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HUE))->SetRange(0,360); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_SAT))->SetRange(0,255); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VAL))->SetRange(0,255); + + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_OVERBRIGHT))->SetRange(0,1023); + +} + +void CDialogColorPicker::SetEditVals() +{ + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_RED))->SetPos(color.r); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_GREEN))->SetPos(color.g); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_BLUE))->SetPos(color.b); + + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HUE))->SetPos(hsvColor.h); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_SAT))->SetPos(hsvColor.s); + ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VAL))->SetPos(hsvColor.v); + +} + +void CDialogColorPicker::OnChangeEditBlue() +{ + int b; + + b = GetDlgItemInt(IDC_EDIT_BLUE); + if( b != color.b && m_bInitOver) + { + color.b = b; + if(color.b < 0) color.b = 0; + if(color.b > 255) color.b = 255; + hsvColor = color.toHSV(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditGreen() +{ + int g; + + g = GetDlgItemInt(IDC_EDIT_GREEN); + if(g != color.g && m_bInitOver) + { + color.g = g; + if(color.g < 0) color.g = 0; + if(color.g > 255) color.g = 255; + hsvColor = color.toHSV(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditRed() +{ + int r; + + r = GetDlgItemInt(IDC_EDIT_RED); + if(r != color.r && m_bInitOver) + { + color.r = r; + if(color.r < 0) color.r = 0; + if(color.r > 255) color.r = 255; + hsvColor = color.toHSV(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditHue() +{ + int h; + + h = GetDlgItemInt(IDC_EDIT_HUE); + if(h != hsvColor.h && m_bInitOver) + { + hsvColor.h = h; + if(hsvColor.h < 0) hsvColor.h = 0; + if(hsvColor.h > 359) hsvColor.h = 359; + color = hsvColor.toRGB(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditSat() +{ + int s; + + s = GetDlgItemInt(IDC_EDIT_SAT); + if(s != hsvColor.s && m_bInitOver) + { + hsvColor.s = s; + if(hsvColor.s < 0) hsvColor.s = 0; + if(hsvColor.s > 255) hsvColor.s = 255; + color = hsvColor.toRGB(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditVal() +{ + int v; + + v = GetDlgItemInt(IDC_EDIT_VAL); + if(v != hsvColor.v && m_bInitOver) + { + hsvColor.v = v; + if(hsvColor.v < 0) hsvColor.v = 0; + if(hsvColor.v > 255) hsvColor.v = 255; + color = hsvColor.toRGB(); + DrawAll(); + } +} + +void CDialogColorPicker::OnChangeEditOverbright() { + CString str; + GetDlgItemText(IDC_EDIT_OVERBRIGHT, str); + if(m_bInitOver) { + overBright = atof(str); + } +} + +void CDialogColorPicker::DrawAll() +{ + if(m_bInitOver && !m_bInDrawAll) + { + CClientDC dc(this); + + DrawMarkers(&dc); + DrawLines(&dc); + m_bInDrawAll = TRUE; + CalcCuboid(); + CalcRects(); + SetDIBPalette(); + DrawRGB(&dc); + DrawHSB(&dc); + SetEditVals(); + m_bInDrawAll = FALSE; + } +} + +void CDialogColorPicker::DrawFilledColor(CDC *pDC,CRect cr,COLORREF c) +{ + pDC->FillSolidRect(&cr,c); + pDC->Draw3dRect(&cr,RGB(0,0,0),RGB(0,0,0)); + cr.InflateRect(-1,-1); + pDC->Draw3dRect(&cr,RGB(192,192,192),RGB(128,128,128)); +} + +void CDialogColorPicker::LoadMappedBitmap(CBitmap& bitmap,UINT nIdResource,CSize& size) +{ + CBitmap *pOldBitmap; + + if(bitmap.GetSafeHandle()) bitmap.DeleteObject(); + + if(bitmap.LoadBitmap(nIdResource)) + { + + int width,height; + BITMAP bmInfo; + + ::GetObject(bitmap.m_hObject,sizeof(bmInfo),&bmInfo); + width = bmInfo.bmWidth; + height = bmInfo.bmHeight; + + COLORREF colorWindow = ::GetSysColor(COLOR_3DFACE); + COLORREF sourceColor = RGB(192,192,192); + + pOldBitmap = (CBitmap *)memDC.SelectObject(&bitmap); + + int i,j; + + for(i=0; i < height; i++) + { + for(j=0; j < width; j++) + { + if(memDC.GetPixel(j,i) == sourceColor) + { + memDC.SetPixel(j,i,colorWindow); + } + } + } + + memDC.SelectObject(&pOldBitmap); + size = CSize(width,height); + } +} + +void CDialogColorPicker::OnSysColorChange() +{ + CSize size; + LoadMappedBitmap(m_HsbBitmap,IDB_BITMAP_HSB,size); + LoadMappedBitmap(m_RgbBitmap,IDB_BITMAP_RGB,size); +} + +void CDialogColorPicker::OnTimer(UINT nIDEvent) { + if ( UpdateParent ) { + UpdateParent( color.r, color.g, color.b, 1.0f ); + } +} + +void CDialogColorPicker::OnBtnColor() { + COLORREF cr = DoOldColor(GetColor()); + color.r = GetRValue(cr); + color.g = GetGValue(cr); + color.b = GetBValue(cr); + hsvColor = color.toHSV(); + DrawAll(); +} + +bool DoNewColor( int* i1, int* i2, int* i3, float *overBright, void (*Update)( float, float, float, float ) ) { + COLORREF cr = (*i1) + ((*i2) <<8) + ((*i3) <<16); + CDialogColorPicker dlg( cr ); + //CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT | CC_ANYCOLOR); + + dlg.UpdateParent = Update; + + if ( dlg.DoModal() == IDOK ) { + *i1 = (dlg.GetColor() & 255); + *i2 = ((dlg.GetColor() >> 8) & 255); + *i3 = ((dlg.GetColor() >> 16) & 255); + *overBright = dlg.GetOverBright(); + return true; + } + return false; +} diff --git a/tools/comafx/DialogColorPicker.h b/tools/comafx/DialogColorPicker.h new file mode 100644 index 000000000..7fb563a5a --- /dev/null +++ b/tools/comafx/DialogColorPicker.h @@ -0,0 +1,184 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGCOLORPICKER__ +#define __DIALOGCOLORPICKER__ + +// Original ColorPicker/DIB source by Rajiv Ramachandran +// included with permission from the author + +#include "CDib.h" + +#define RADIUS 100 +#define PI 3.14159265358 + +#define RECT_WIDTH 5 + +#define TOSCALE(x) (((x)*RADIUS)/255.0) +#define SCALETOMAX(x) (((x)*255.0)/RADIUS) + + +#define RED 0 +#define GREEN 1 +#define BLUE 2 + +#define BAD_SLOPE 1000000.0 + + +struct HSVType; + +struct RGBType { + COLORREF color() { return RGB( r, g, b ); } + HSVType toHSV(); + int r, g, b; +}; + +struct HSVType { + RGBType toRGB(); + int h, s, v; +}; + +struct LineDesc { + double x, y; + double slope; + double c; +}; + + +class CDialogColorPicker : public CDialog +{ +// Construction +public: + CDialogColorPicker(COLORREF c,CWnd* pParent = NULL); // standard constructor + ~CDialogColorPicker(); + + COLORREF GetColor() { return color.color();}; + float GetOverBright() { return overBright; }; + + + // Dialog Data + //{{AFX_DATA(CDialogColorPicker) + enum { IDD = IDD_DIALOG_COLORS }; + float m_overBright; + //}}AFX_DATA + + void (*UpdateParent)( float r, float g, float b, float a ); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDialogColorPicker) + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDialogColorPicker) + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnSysColorChange(); + afx_msg void OnPaint(); + virtual BOOL OnInitDialog(); + afx_msg void OnChangeEditBlue(); + afx_msg void OnChangeEditGreen(); + afx_msg void OnChangeEditHue(); + afx_msg void OnChangeEditRed(); + afx_msg void OnChangeEditSat(); + afx_msg void OnChangeEditVal(); + afx_msg void OnChangeEditOverbright(); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnBtnColor(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + void DrawFilledColor(CDC *pDC,CRect cr,COLORREF c); + void DrawLines(CDC *pDC); + void DrawXorRect(CDC *pDC,CRect& cr); + void CalcSlopes(); + void CalcCuboid(); + + void CreateBrightDIB(); + void SetDIBPalette(); + void DrawMarkers(CDC *pDC); + void TrackPoint(CPoint pt); + void CalcRects(); + + BOOL InCircle(CPoint pt); + BOOL InBright(CPoint pt); + BOOL InOverBright(CPoint pt); + + + void SetSpinVals(); + void SetEditVals(); + void DrawAll(); + + void DrawRGB(CDC *pDC); + void DrawHSB(CDC *pDC); + + void LoadMappedBitmap(CBitmap& bitmap,UINT nIdResource,CSize& size); + + CBitmap m_RgbBitmap,m_HsbBitmap; + + CDC memDC; + CPoint m_Centre; + CDIB m_BrightDIB; + + int rgbWidth; + int rgbHeight; + int hsbWidth; + int hsbHeight; + + int m_nMouseIn; + CRect m_CurrentRect,brightMark; + CRect brightRect; + CRect overBrightRect; + + HSVType hsvColor; + + RGBType color; + RGBType m_OldColor; + CPoint Vertex; + CPoint Top; + CPoint Left; + CPoint Right; + CRect rects[3]; + CPoint m_Cuboid[8]; + BOOL m_bInMouse; + int nIndex; + int RedLen; + int GreenLen; + int BlueLen; + LineDesc lines[3]; + + + CRect rgbRect; + CRect hsbRect; + CRect OldColorRect; + CRect NewColorRect; + + BOOL m_bInitOver; + BOOL m_bInDrawAll; + + float overBright; +}; + +bool DoNewColor( int* i1, int* i2, int* i3, float *overBright, void (*Update)( float, float, float, float ) = NULL ); + +#endif /* !__DIALOGCOLORPICKER__ */ diff --git a/tools/comafx/DialogGoToLine.cpp b/tools/comafx/DialogGoToLine.cpp new file mode 100644 index 000000000..79f87e4fe --- /dev/null +++ b/tools/comafx/DialogGoToLine.cpp @@ -0,0 +1,125 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/Common_resource.h" + +#include "DialogGoToLine.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +IMPLEMENT_DYNAMIC(DialogGoToLine, CDialog) + +/* +================ +DialogGoToLine::DialogGoToLine +================ +*/ +DialogGoToLine::DialogGoToLine( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogGoToLine::IDD, pParent) + , firstLine(0) + , lastLine(0) + , line(0) +{ +} + +/* +================ +DialogGoToLine::~DialogGoToLine +================ +*/ +DialogGoToLine::~DialogGoToLine() { +} + +/* +================ +DialogGoToLine::DoDataExchange +================ +*/ +void DialogGoToLine::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogGoToLine) + DDX_Control( pDX, IDC_GOTOLINE_EDIT, numberEdit); + //}}AFX_DATA_MAP +} + +/* +================ +DialogGoToLine::SetRange +================ +*/ +void DialogGoToLine::SetRange( int firstLine, int lastLine ) { + this->firstLine = firstLine; + this->lastLine = lastLine; +} + +/* +================ +DialogGoToLine::GetLine +================ +*/ +int DialogGoToLine::GetLine( void ) const { + return line; +} + +/* +================ +DialogGoToLine::OnInitDialog +================ +*/ +BOOL DialogGoToLine::OnInitDialog() { + + CDialog::OnInitDialog(); + + GetDlgItem( IDC_GOTOLINE_STATIC )->SetWindowText( va( "&Line number (%d - %d):", firstLine, lastLine ) ); + + numberEdit.SetWindowText( va( "%d", firstLine ) ); + numberEdit.SetSel( 0, -1 ); + numberEdit.SetFocus(); + + return FALSE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +BEGIN_MESSAGE_MAP(DialogGoToLine, CDialog) + ON_BN_CLICKED(IDOK, OnBnClickedOk) +END_MESSAGE_MAP() + + +// DialogGoToLine message handlers + +/* +================ +DialogGoToLine::OnBnClickedOk +================ +*/ +void DialogGoToLine::OnBnClickedOk() { + CString text; + numberEdit.GetWindowText( text ); + line = idMath::ClampInt( firstLine, lastLine, atoi( text ) ); + OnOK(); +} diff --git a/tools/comafx/DialogGoToLine.h b/tools/comafx/DialogGoToLine.h new file mode 100644 index 000000000..4b4788a42 --- /dev/null +++ b/tools/comafx/DialogGoToLine.h @@ -0,0 +1,54 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGGOTOLINE_H__ +#define __DIALOGGOTOLINE_H__ + +// DialogGoToLine dialog + +class DialogGoToLine : public CDialog { + + DECLARE_DYNAMIC(DialogGoToLine) + +public: + + DialogGoToLine( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogGoToLine(); + + enum { IDD = IDD_DIALOG_GOTOLINE }; + + void SetRange( int firstLine, int lastLine ); + int GetLine( void ) const; + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + afx_msg void OnBnClickedOk(); + + DECLARE_MESSAGE_MAP() + +private: + + CEdit numberEdit; + int firstLine; + int lastLine; + int line; +}; + +#endif /* !__DIALOGGOTOLINE_H__ */ diff --git a/tools/comafx/DialogName.cpp b/tools/comafx/DialogName.cpp new file mode 100644 index 000000000..e1aa0353a --- /dev/null +++ b/tools/comafx/DialogName.cpp @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/common_resource.h" +#include "DialogName.h" + +///////////////////////////////////////////////////////////////////////////// +// DialogName dialog + + +DialogName::DialogName(const char *pName, CWnd* pParent /*=NULL*/) + : CDialog(DialogName::IDD, pParent) +{ + //{{AFX_DATA_INIT(DialogName) + m_strName = _T(""); + //}}AFX_DATA_INIT + m_strCaption = pName; +} + + +void DialogName::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogName) + DDX_Text(pDX, IDC_TOOLS_EDITNAME, m_strName); + //}}AFX_DATA_MAP +} + +BOOL DialogName::OnInitDialog() +{ + CDialog::OnInitDialog(); + + SetWindowText(m_strCaption); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +BEGIN_MESSAGE_MAP(DialogName, CDialog) + //{{AFX_MSG_MAP(DialogName) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DialogName message handlers + +void DialogName::OnOK() +{ + CDialog::OnOK(); +} diff --git a/tools/comafx/DialogName.h b/tools/comafx/DialogName.h new file mode 100644 index 000000000..adcce161c --- /dev/null +++ b/tools/comafx/DialogName.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGNAME_H__ +#define __DIALOGNAME_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// NameDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// DialogName dialog + +class DialogName : public CDialog +{ + CString m_strCaption; +// Construction +public: + DialogName(const char *pName, CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(DialogName) + enum { IDD = IDD_NEWNAME }; + CString m_strName; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(DialogName) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(DialogName) + virtual BOOL OnInitDialog(); + virtual void OnOK(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif /* !__DIALOGNAME_H__ */ diff --git a/tools/comafx/StdAfx.cpp b/tools/comafx/StdAfx.cpp new file mode 100644 index 000000000..6e51eea64 --- /dev/null +++ b/tools/comafx/StdAfx.cpp @@ -0,0 +1,373 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" + +// source file that includes just the standard includes +// Radiant.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +/* +=============================================================================== + + Afx initialization. + +=============================================================================== +*/ + +bool afxInitialized = false; + +/* +================ +InitAfx +================ +*/ +void InitAfx( void ) { + if ( !afxInitialized ) { + AfxWinInit( win32.hInstance, NULL, "", SW_SHOW ); + AfxInitRichEdit(); + afxInitialized = true; + } +} + + +/* +=============================================================================== + + Tool Tips. + +=============================================================================== +*/ + +/* +================ +DefaultOnToolHitTest +================ +*/ +int DefaultOnToolHitTest( const toolTip_t *toolTips, const CDialog *dialog, CPoint point, TOOLINFO* pTI ) { + CWnd *wnd; + RECT clientRect, rect; + + dialog->GetWindowRect( &clientRect ); + point.x += clientRect.left; + point.y += clientRect.top; + for ( int i = 0; toolTips[i].tip; i++ ) { + wnd = dialog->GetDlgItem( toolTips[i].id ); + if ( !( wnd->GetStyle() & WS_VISIBLE ) ) { + continue; + } + wnd->GetWindowRect( &rect ); + if ( point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom ) { + pTI->hwnd = dialog->GetSafeHwnd(); + pTI->uFlags |= TTF_IDISHWND; + pTI->uFlags &= ~TTF_CENTERTIP; + pTI->uId = (UINT_PTR) wnd->GetSafeHwnd(); + return pTI->uId; + } + } + return -1; +} + +/* +================ +DefaultOnToolTipNotify +================ +*/ +BOOL DefaultOnToolTipNotify( const toolTip_t *toolTips, UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + // need to handle both ANSI and UNICODE versions of the message + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + + *pResult = 0; + + UINT nID = pNMHDR->idFrom; + if ( pTTTA->uFlags & TTF_IDISHWND ) { + // idFrom is actually the HWND of the tool + nID = ::GetDlgCtrlID((HWND)nID); + } + + int i; + for ( i = 0; toolTips[i].tip; i++ ) { + if ( toolTips[i].id == nID ) { + break; + } + } + + if ( !toolTips[i].tip ) { + return FALSE; + } + + if ( pNMHDR->code == TTN_NEEDTEXTA ) { + lstrcpyn( pTTTA->szText, toolTips[i].tip, sizeof(pTTTA->szText) ); + } else { + _mbstowcsz( pTTTW->szText, toolTips[i].tip, sizeof(pTTTW->szText) ); + } + return TRUE; +} + + +/* +=============================================================================== + + Common control tools. + +=============================================================================== +*/ + +/* +================ +EditControlEnterHit + + returns true if [Enter] was hit in the edit box + all 'return' characters in the text are removed and a single line is maintained + the edit control must be multi-line with auto-vscroll +================ +*/ +bool EditControlEnterHit( CEdit *edit ) { + CString strIn, strOut; + if ( edit->GetLineCount() > 1 ) { + edit->GetWindowText( strIn ); + for ( int i = 0; i < strIn.GetLength(); i++ ) { + if ( strIn[i] >= ' ' ) { + strOut.AppendChar( strIn[i] ); + } + } + edit->SetWindowText( strOut ); + edit->SetSel( 0, strOut.GetLength() ); + return true; + } + return false; +} + +/* +================ +EditVerifyFloat +================ +*/ +float EditVerifyFloat( CEdit *edit, bool allowNegative ) { + + CString strIn, strOut; + bool dot = false; + int start, end; + + edit->GetSel( start, end ); + edit->GetWindowText( strIn ); + for ( int i = 0; i < strIn.GetLength(); i++ ) { + // first character may be a minus sign + if ( allowNegative && strOut.GetLength() == 0 && strIn[i] == '-' ) { + strOut.AppendChar( '-' ); + } + // the string may contain one dot + else if ( !dot && strIn[i] == '.' ) { + strOut.AppendChar( strIn[i] ); + dot = true; + } + else if ( strIn[i] >= '0' && strIn[i] <= '9' ) { + strOut.AppendChar( strIn[i] ); + } + } + edit->SetWindowText( strOut ); + edit->SetSel( start, end ); + + return atof(strOut.GetBuffer(0)); + +} + +/* +================ +SpinFloatString +================ +*/ +void SpinFloatString( CString &str, bool up ) { + int i, dotIndex = -1, digitIndex = -1; + + for ( i = 0; str[i]; i++ ) { + if ( str[i] == '.' ) { + if ( dotIndex == -1 ) { + dotIndex = i; + } + } + else if ( str[i] != '0' ) { + if ( digitIndex == -1 ) { + digitIndex = i; + } + } + } + if ( digitIndex == -1 ) { + str.SetString( "1" ); + return; + } + + if ( dotIndex != -1 ) { + str.Delete( dotIndex, 1 ); + if ( digitIndex > dotIndex ) { + digitIndex--; + } + } + else { + dotIndex = i; + } + + if ( up ) { + if ( str[digitIndex] == '9' ) { + str.SetAt( digitIndex, '0' ); + if ( digitIndex == 0 ) { + str.Insert( 0, '1' ); + dotIndex++; + } + else { + str.SetAt( digitIndex-1, '1' ); + } + } + else { + str.SetAt( digitIndex, str[digitIndex] + 1 ); + } + } + else { + if ( str[digitIndex] == '1' ) { + if ( str[digitIndex+1] == '\0' ) { + str.SetAt( digitIndex, '0' ); + str.AppendChar( '9' ); + } + else if ( str[digitIndex+1] == '0' ) { + str.SetAt( digitIndex, '0' ); + str.SetAt( digitIndex+1, '9' ); + } + else { + str.SetAt( digitIndex+1, str[digitIndex+1] - 1 ); + } + } + else { + str.SetAt( digitIndex, str[digitIndex] - 1 ); + } + } + if ( dotIndex < str.GetLength() ) { + str.Insert( dotIndex, '.' ); + // remove trailing zeros + for ( i = str.GetLength()-1; i >= 0; i-- ) { + if ( str[i] != '0' && str[i] != '.' ) { + break; + } + } + if ( i < str.GetLength() - 1 ) { + str.Delete( i+1, str.GetLength() - i ); + } + } + for ( i = 0; str[i]; i++ ) { + if ( str[i] == '.' ) { + if ( i > 1 ) { + str.Delete( 0, i-1 ); + } + break; + } + if ( str[i] != '0' ) { + if ( i > 0 ) { + str.Delete( 0, i ); + } + break; + } + } +} + +/* +================ +EditSpinFloat +================ +*/ +float EditSpinFloat( CEdit *edit, bool up ) { + CString str; + + edit->GetWindowText( str ); + SpinFloatString( str, up ); + edit->SetWindowText( str ); + return atof( str ); +} + +/* +================ +SetSafeComboBoxSelection +================ +*/ +int SetSafeComboBoxSelection( CComboBox *combo, const char *string, int skip ) { + int index; + + index = combo->FindString( -1, string ); + if ( index == -1 ) { + index = 0; + } + if ( combo->GetCount() != 0 ) { + if ( index == skip ) { + index = ( skip + 1 ) % combo->GetCount(); + } + combo->SetCurSel( index ); + } + + return index; +} + +/* +================ +GetComboBoxSelection +================ +*/ +int GetSafeComboBoxSelection( CComboBox *combo, CString &string, int skip ) { + int index; + + index = combo->GetCurSel(); + if ( index == CB_ERR ) { + index = 0; + } + if ( combo->GetCount() != 0 ) { + if ( index == skip ) { + index = ( skip + 1 ) % combo->GetCount(); + } + combo->GetLBText( index, string ); + } + else { + string = ""; + } + + return index; +} + +/* +================ +UnsetSafeComboBoxSelection +================ +*/ +int UnsetSafeComboBoxSelection( CComboBox *combo, CString &string ) { + int skip, index; + + skip = combo->FindString( -1, string ); + index = combo->GetCurSel(); + if ( index == CB_ERR ) { + index = 0; + } + if ( combo->GetCount() != 0 ) { + if ( index == skip ) { + index = ( skip + 1 ) % combo->GetCount(); + } + combo->SetCurSel( index ); + } + + return index; +} diff --git a/tools/comafx/StdAfx.h b/tools/comafx/StdAfx.h new file mode 100644 index 000000000..c3ec51264 --- /dev/null +++ b/tools/comafx/StdAfx.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AFX_STDAFX_H__ +#define __AFX_STDAFX_H__ + +// include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently + +//#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +void InitAfx( void ); + +// tool tips +typedef struct toolTip_s { + int id; + char *tip; +} toolTip_t; + +int DefaultOnToolHitTest( const toolTip_t *toolTips, const CDialog *dialog, CPoint point, TOOLINFO* pTI ); +BOOL DefaultOnToolTipNotify( const toolTip_t *toolTips, UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + +// edit control +bool EditControlEnterHit( CEdit *edit ); +float EditVerifyFloat( CEdit *edit, bool allowNegative = true ); +float EditSpinFloat( CEdit *edit, bool up ); + +// combo box +int SetSafeComboBoxSelection( CComboBox *combo, const char *string, int skip ); +int GetSafeComboBoxSelection( CComboBox *combo, CString &string, int skip ); +int UnsetSafeComboBoxSelection( CComboBox *combo, CString &string ); + +#endif /* !__AFX_STDAFX_H__ */ diff --git a/tools/comafx/VectorCtl.cpp b/tools/comafx/VectorCtl.cpp new file mode 100644 index 000000000..8eda67c5b --- /dev/null +++ b/tools/comafx/VectorCtl.cpp @@ -0,0 +1,415 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + + +#include "VectorCtl.h" +#include + +BEGIN_MESSAGE_MAP(CVectorCtl, CButton) + //{{AFX_MSG_MAP(idGLWidget) + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MOUSEMOVE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +CVectorCtl::CVectorCtl () : + m_bBmpCreated (FALSE), + m_bImageChange (TRUE), + m_bBackgroundBitmapUsed (FALSE), + m_clrDiffuse (DEFAULT_DIFFUSE), + m_clrAmbient (DEFAULT_AMBIENT), + m_clrLight (DEFAULT_LIGHT), + m_clrBackgroundStart (DEFAULT_START_BACKGROUND_COLOR), + m_clrBackgroundEnd (DEFAULT_END_BACKGROUND_COLOR), + m_dSpecularExponent (DEFAULT_SPEC_EXP), + m_bHasFocus (FALSE), + m_bSelected (FALSE), + m_bFrontVector (FALSE), + m_dSensitivity (20.0), + m_procVectorChanging (NULL), + m_procVectorChanged (NULL) +{ + double DefaultVec[3] = DEFAULT_VEC; + for (int i=0; i<3; i++) { + m_dVec[i] = DefaultVec[i]; + pCtl[i] = NULL; + } + + rotationQuat.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + lastPress.Zero(); + radius = 0.6f; +} + + +CVectorCtl::~CVectorCtl () +{ + if (m_bBmpCreated) + m_dcMem.SelectObject (m_pOldBitmap); + ClearBackgroundBitmap (); +} + +// Owner-drawn control service function: +void CVectorCtl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ) +{ + CDC *pDC = CDC::FromHandle (lpDrawItemStruct->hDC); // Get CDC to draw + + if (!m_bSelected && lpDrawItemStruct->itemState & ODS_SELECTED) { + // Just got re-selected (user starts a new mouse dragging session) + } else if (m_bSelected && // Last state was selected + !(lpDrawItemStruct->itemState & ODS_SELECTED) && // New state is NOT selected + (lpDrawItemStruct->itemState & ODS_FOCUS) && // New state is still in focus + m_procVectorChanged) // User asked for a callback + // User has left the track-ball and asked for a callback. + m_procVectorChanged ( rotationQuat ); + + m_bHasFocus = lpDrawItemStruct->itemState & ODS_FOCUS; // Update focus status + m_bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; // Update selection status + + if (!m_bBmpCreated) // 1st time + InitBitmap (lpDrawItemStruct, pDC); + if (m_bImageChange) { // Image has changes - recalc it! + if (m_procVectorChanging) // User has specified a callback + m_procVectorChanging ( rotationQuat ); // Call it! + BuildImage (lpDrawItemStruct); + m_bImageChange = FALSE; + } + pDC->BitBlt (0,0,m_iWidth, m_iHeight, &m_dcMem, 0, 0, SRCCOPY); // Update screen +} + +// Mouse was dragged +void CVectorCtl::OnMouseDrag (int ixMove, int iyMove) +{ + RotateByXandY (double(-iyMove) / m_dSensitivity, + double(ixMove) / m_dSensitivity); +} + +// Recalc ball image +void CVectorCtl::BuildImage (LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + int xf, yf; + + for (int x=0; x EPS) { + Norm = sqrt (Norm); + m_dVec[0] /= Norm; + m_dVec[1] /= Norm; + m_dVec[2] /= Norm; + return TRUE; + } else { // Reset to defualt vector + double DefaultVec[3] = DEFAULT_VEC; + for (int i=0; i<3; i++) + m_dVec[i] = DefaultVec[i]; + return FALSE; + } +} + +// Calculate lightning effect for specific pixel on ball's surface +COLORREF CVectorCtl::CalcLight (double dx, double dy, double dz) +{ + double NL = dx * m_dVec[0] + dy * m_dVec[1] + dz * m_dVec[2], + RV = 2.0 * NL, + rx = m_dVec[0] - (dx * RV), + ry = m_dVec[1] - (dy * RV), + rz = m_dVec[2] - (dz * RV); + + if (NL < 0.0) // Diffuse coefficient + NL = 0.0; + + RV = max (0.0, -rz); + RV = double(pow (RV, m_dSpecularExponent)); + + int r = int ( double(GetRValue(m_clrDiffuse)) * NL + // Diffuse + double(GetRValue(m_clrLight)) * RV + // Specular + double(GetRValue(m_clrAmbient))), // Ambient + + g = int ( double(GetGValue(m_clrDiffuse)) * NL + // Diffuse + double(GetGValue(m_clrLight)) * RV + // Specular + double(GetGValue(m_clrAmbient))), // Ambient + + b = int ( double(GetBValue(m_clrDiffuse)) * NL + // Diffuse + double(GetBValue(m_clrLight)) * RV + // Specular + double(GetBValue(m_clrAmbient))); // Ambient + + r = min (255, r); // Cutoff highlight + g = min (255, g); + b = min (255, b); + return RGB(BYTE(r),BYTE(g),BYTE(b)); +} + + +// Start memory buffer bitmap and measure it +void CVectorCtl::InitBitmap (LPDRAWITEMSTRUCT lpDrawItemStruct, CDC *pDC) +{ + m_iWidth = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left; + m_iHeight = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top; + m_bmpBuffer.CreateCompatibleBitmap (pDC, m_iWidth, m_iHeight); + m_bBmpCreated = TRUE; + m_dcMem.CreateCompatibleDC (pDC); + m_pOldBitmap = m_dcMem.SelectObject (&m_bmpBuffer); + SetRadius (max (min (m_iWidth, m_iHeight) - 2, 0) / 2); + SetCenter (m_iWidth / 2, m_iHeight / 2); + CreateBackground (); +} + +// Set new specular intensity +BOOL CVectorCtl::SetSpecularExponent (double dExp) +{ + if (dExp < 1.0 || dExp > 200.0) + return FALSE; + m_dSpecularExponent = dExp; + Redraw (); + return TRUE; +} + +// Rotate our vector around the X and Y axis +void CVectorCtl::RotateByXandY (double XRot, double YRot) +{ // Angles are in radians + + if (XRot == 0.0 && YRot == 0.0) { + return; + } + + double cx = cos(XRot), + sx = sin(XRot), + cy = cos(YRot), + sy = sin(YRot), + dx = m_dVec[0] * cy + m_dVec[1] * sx * sy + m_dVec[2] * cx * sy, + dy = m_dVec[1] * cx - m_dVec[2] * sx, + dz = -m_dVec[0] * sy + m_dVec[1] * sx * cy + m_dVec[2] * cx * cy; + + if (!m_bFrontVector || dz >= 0.0) { // Vector is bounds free + m_dVec[0] = dx; + m_dVec[1] = dy; + m_dVec[2] = dz; + } else { // Otherwise, do not allow Z to be negative (light shines from behind) + m_dVec[2] = 0.0; + m_dVec[0] = dx; + m_dVec[1] = dy; + Normalize (); + } + Redraw (); +} + + +void CVectorCtl::UpdateAxisControls () +{ + CString cs; + for (int i=0; i<3; i++) + if (pCtl[i]) { + cs.Format ("%+1.5f",m_dVec[i]); + pCtl[i]->SetWindowText (cs); + } +} + +void CVectorCtl::SetAxisControl (int nXCtl, int nYCtl, int nZCtl) +{ + pCtl[0] = GetParent()->GetDlgItem(nXCtl); + pCtl[1] = GetParent()->GetDlgItem(nYCtl); + pCtl[2] = GetParent()->GetDlgItem(nZCtl); +} + +void CVectorCtl::SetRadius (UINT uRadius) +{ + m_iRadius = uRadius; + m_iSqrRadius = m_iRadius * m_iRadius; + CreateBackground (); + Redraw (TRUE); +} + + +void CVectorCtl::SetCenter (UINT uHorizPos, UINT uVertPos) +{ + m_iXCenter = uHorizPos; + m_iYCenter = uVertPos; + CreateBackground (); + Redraw (TRUE); +} + + +void CVectorCtl::SetAxis (double d, int nAxis) +{ + if (fabs(d)>=1.0) { + m_dVec[nAxis]=d > 1.0 ? 1.0 : -1.0; + m_dVec[(nAxis+1) %3]=m_dVec[(nAxis+2) %3]=0.0; + Redraw (); + return; + } + m_dVec[nAxis] = d; + Normalize (); + Redraw (); +} + +void CVectorCtl::SetVector (double dx, double dy, double dz) +{ + m_dVec[0] = dx; + m_dVec[1] = dy; + m_dVec[2] = dz; + Normalize (); + Redraw (); +} + +void CVectorCtl::SetBackgroundColor (COLORREF clrStart, COLORREF clrEnd) +{ + ClearBackgroundBitmap (); + m_clrBackgroundStart = clrStart; + m_clrBackgroundEnd = clrEnd; + CreateBackground (); +} + + +BOOL CVectorCtl::SetBackgroundImage (UINT uBackgroundBitmapID) +{ + if (m_bBackgroundBitmapUsed) { + ClearBackgroundBitmap (); + CreateBackground (); + } + if (!m_bmpBack.LoadBitmap (uBackgroundBitmapID)) + return FALSE; + m_bBackgroundBitmapUsed = TRUE; + CreateBackground (); + return TRUE; +} + +void CVectorCtl::CreateBackground () +{ + if (!m_bBmpCreated) + return; // No image yet + if (!m_bBackgroundBitmapUsed) { // No background used - fill with gradient color + double r = GetRValue (m_clrBackgroundStart), + g = GetGValue (m_clrBackgroundStart), + b = GetBValue (m_clrBackgroundStart), + rd = double (GetRValue (m_clrBackgroundEnd) - r) / double (m_iHeight), + gd = double (GetGValue (m_clrBackgroundEnd) - g) / double (m_iHeight), + bd = double (GetBValue (m_clrBackgroundEnd) - b) / double (m_iHeight); + for (int j=0; j + +namespace tom { + +// +// Forward references and typedefs +// + +struct __declspec(uuid("8cc497c9-a1df-11ce-8098-00aa0047be5d")) +/* LIBID */ __tom; +enum __MIDL___MIDL_itf_tom_0000_0001; +struct __declspec(uuid("8cc497c0-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextDocument; +struct __declspec(uuid("8cc497c1-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextSelection; +struct __declspec(uuid("8cc497c2-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextRange; +struct __declspec(uuid("8cc497c3-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextFont; +struct __declspec(uuid("8cc497c4-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextPara; +struct __declspec(uuid("8cc497c5-a1df-11ce-8098-00aa0047be5d")) +/* dual interface */ ITextStoryRanges; +struct __declspec(uuid("01c25500-4268-11d1-883a-3c8b00c10000")) +/* dual interface */ ITextDocument2; +struct __declspec(uuid("a3787420-4267-11d1-883a-3c8b00c10000")) +/* interface */ ITextMsgFilter; +struct _RemotableHandle; +union __MIDL_IWinTypes_0009; +typedef enum __MIDL___MIDL_itf_tom_0000_0001 tomConstants; +typedef struct _RemotableHandle * wireHWND; +typedef unsigned long UINT_PTR; +typedef long LONG_PTR; + +// +// Smart pointer typedef declarations +// + +_COM_SMARTPTR_TYPEDEF(ITextFont, __uuidof(ITextFont)); +_COM_SMARTPTR_TYPEDEF(ITextPara, __uuidof(ITextPara)); +_COM_SMARTPTR_TYPEDEF(ITextRange, __uuidof(ITextRange)); +_COM_SMARTPTR_TYPEDEF(ITextSelection, __uuidof(ITextSelection)); +_COM_SMARTPTR_TYPEDEF(ITextStoryRanges, __uuidof(ITextStoryRanges)); +_COM_SMARTPTR_TYPEDEF(ITextDocument, __uuidof(ITextDocument)); +_COM_SMARTPTR_TYPEDEF(ITextDocument2, __uuidof(ITextDocument2)); +_COM_SMARTPTR_TYPEDEF(ITextMsgFilter, __uuidof(ITextMsgFilter)); + +// +// Type library items +// + +enum __MIDL___MIDL_itf_tom_0000_0001 +{ + tomFalse = 0, + tomTrue = -1, + tomUndefined = -9999999, + tomToggle = -9999998, + tomAutoColor = -9999997, + tomDefault = -9999996, + tomSuspend = -9999995, + tomResume = -9999994, + tomApplyNow = 0, + tomApplyLater = 1, + tomTrackParms = 2, + tomCacheParms = 3, + tomBackward = -1073741823, + tomForward = 1073741823, + tomMove = 0, + tomExtend = 1, + tomNoSelection = 0, + tomSelectionIP = 1, + tomSelectionNormal = 2, + tomSelectionFrame = 3, + tomSelectionColumn = 4, + tomSelectionRow = 5, + tomSelectionBlock = 6, + tomSelectionInlineShape = 7, + tomSelectionShape = 8, + tomSelStartActive = 1, + tomSelAtEOL = 2, + tomSelOvertype = 4, + tomSelActive = 8, + tomSelReplace = 16, + tomEnd = 0, + tomStart = 32, + tomCollapseEnd = 0, + tomCollapseStart = 1, + tomClientCoord = 256, + tomNone = 0, + tomSingle = 1, + tomWords = 2, + tomDouble = 3, + tomDotted = 4, + tomDash = 5, + tomDashDot = 6, + tomDashDotDot = 7, + tomWave = 8, + tomThick = 9, + tomHair = 10, + tomLineSpaceSingle = 0, + tomLineSpace1pt5 = 1, + tomLineSpaceDouble = 2, + tomLineSpaceAtLeast = 3, + tomLineSpaceExactly = 4, + tomLineSpaceMultiple = 5, + tomAlignLeft = 0, + tomAlignCenter = 1, + tomAlignRight = 2, + tomAlignJustify = 3, + tomAlignDecimal = 3, + tomAlignBar = 4, + tomAlignInterWord = 3, + tomAlignInterLetter = 4, + tomAlignScaled = 5, + tomAlignGlyphs = 6, + tomAlignSnapGrid = 7, + tomSpaces = 0, + tomDots = 1, + tomDashes = 2, + tomLines = 3, + tomThickLines = 4, + tomEquals = 5, + tomTabBack = -3, + tomTabNext = -2, + tomTabHere = -1, + tomListNone = 0, + tomListBullet = 1, + tomListNumberAsArabic = 2, + tomListNumberAsLCLetter = 3, + tomListNumberAsUCLetter = 4, + tomListNumberAsLCRoman = 5, + tomListNumberAsUCRoman = 6, + tomListNumberAsSequence = 7, + tomListParentheses = 65536, + tomListPeriod = 131072, + tomListPlain = 196608, + tomCharacter = 1, + tomWord = 2, + tomSentence = 3, + tomParagraph = 4, + tomLine = 5, + tomStory = 6, + tomScreen = 7, + tomSection = 8, + tomColumn = 9, + tomRow = 10, + tomWindow = 11, + tomCell = 12, + tomCharFormat = 13, + tomParaFormat = 14, + tomTable = 15, + tomObject = 16, + tomMatchWord = 2, + tomMatchCase = 4, + tomMatchPattern = 8, + tomUnknownStory = 0, + tomMainTextStory = 1, + tomFootnotesStory = 2, + tomEndnotesStory = 3, + tomCommentsStory = 4, + tomTextFrameStory = 5, + tomEvenPagesHeaderStory = 6, + tomPrimaryHeaderStory = 7, + tomEvenPagesFooterStory = 8, + tomPrimaryFooterStory = 9, + tomFirstPageHeaderStory = 10, + tomFirstPageFooterStory = 11, + tomNoAnimation = 0, + tomLasVegasLights = 1, + tomBlinkingBackground = 2, + tomSparkleText = 3, + tomMarchingBlackAnts = 4, + tomMarchingRedAnts = 5, + tomShimmer = 6, + tomWipeDown = 7, + tomWipeRight = 8, + tomAnimationMax = 8, + tomLowerCase = 0, + tomUpperCase = 1, + tomTitleCase = 2, + tomSentenceCase = 4, + tomToggleCase = 5, + tomReadOnly = 256, + tomShareDenyRead = 512, + tomShareDenyWrite = 1024, + tomPasteFile = 4096, + tomCreateNew = 16, + tomCreateAlways = 32, + tomOpenExisting = 48, + tomOpenAlways = 64, + tomTruncateExisting = 80, + tomRTF = 1, + tomText = 2, + tomHTML = 3, + tomWordDocument = 4, + tomBold = -2147483647, + tomItalic = -2147483646, + tomUnderline = -2147483644, + tomStrikeout = -2147483640, + tomProtected = -2147483632, + tomLink = -2147483616, + tomSmallCaps = -2147483584, + tomAllCaps = -2147483520, + tomHidden = -2147483392, + tomOutline = -2147483136, + tomShadow = -2147482624, + tomEmboss = -2147481600, + tomImprint = -2147479552, + tomDisabled = -2147475456, + tomRevised = -2147467264, + tomNormalCaret = 0, + tomKoreanBlockCaret = 1, + tomIncludeInset = 1, + tomIgnoreCurrentFont = 0, + tomMatchFontCharset = 1, + tomMatchFontSignature = 2, + tomCharset = 0x80000000, + tomRE10Mode = 1, + tomNoIME = 524288, + tomSelfIME = 262144 +}; + +struct __declspec(uuid("8cc497c3-a1df-11ce-8098-00aa0047be5d")) +ITextFont : IDispatch +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall get_Duplicate ( + /*[out,retval]*/ struct ITextFont * * ppFont ) = 0; + virtual HRESULT __stdcall put_Duplicate ( + /*[in]*/ struct ITextFont * ppFont ) = 0; + virtual HRESULT __stdcall CanChange ( + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall IsEqual ( + /*[in]*/ struct ITextFont * pFont, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall Reset ( + /*[in]*/ long Value ) = 0; + virtual HRESULT __stdcall get_Style ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Style ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_AllCaps ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_AllCaps ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Animation ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Animation ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_BackColor ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_BackColor ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Bold ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Bold ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Emboss ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Emboss ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_ForeColor ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_ForeColor ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Hidden ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Hidden ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Engrave ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Engrave ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Italic ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Italic ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Kerning ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_Kerning ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_LanguageID ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_LanguageID ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Name ( + /*[out,retval]*/ BSTR * pbstr ) = 0; + virtual HRESULT __stdcall put_Name ( + /*[in]*/ BSTR pbstr ) = 0; + virtual HRESULT __stdcall get_Outline ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Outline ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Position ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_Position ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_Protected ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Protected ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Shadow ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Shadow ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Size ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_Size ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_SmallCaps ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_SmallCaps ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Spacing ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_Spacing ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_StrikeThrough ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_StrikeThrough ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Subscript ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Subscript ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Superscript ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Superscript ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Underline ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Underline ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Weight ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Weight ( + /*[in]*/ long pValue ) = 0; +}; + +struct __declspec(uuid("8cc497c4-a1df-11ce-8098-00aa0047be5d")) +ITextPara : IDispatch +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall get_Duplicate ( + /*[out,retval]*/ struct ITextPara * * ppPara ) = 0; + virtual HRESULT __stdcall put_Duplicate ( + /*[in]*/ struct ITextPara * ppPara ) = 0; + virtual HRESULT __stdcall CanChange ( + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall IsEqual ( + /*[in]*/ struct ITextPara * pPara, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall Reset ( + /*[in]*/ long Value ) = 0; + virtual HRESULT __stdcall get_Style ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Style ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Alignment ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Alignment ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_Hyphenation ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Hyphenation ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_FirstLineIndent ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall get_KeepTogether ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_KeepTogether ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_KeepWithNext ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_KeepWithNext ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_LeftIndent ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall get_LineSpacing ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall get_LineSpacingRule ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall get_ListAlignment ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_ListAlignment ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_ListLevelIndex ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_ListLevelIndex ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_ListStart ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_ListStart ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_ListTab ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_ListTab ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_ListType ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_ListType ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_NoLineNumber ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_NoLineNumber ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_PageBreakBefore ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_PageBreakBefore ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_RightIndent ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_RightIndent ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall SetIndents ( + /*[in]*/ float StartIndent, + /*[in]*/ float LeftIndent, + /*[in]*/ float RightIndent ) = 0; + virtual HRESULT __stdcall SetLineSpacing ( + /*[in]*/ long LineSpacingRule, + /*[in]*/ float LineSpacing ) = 0; + virtual HRESULT __stdcall get_SpaceAfter ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_SpaceAfter ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_SpaceBefore ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_SpaceBefore ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall get_WidowControl ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_WidowControl ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_TabCount ( + /*[out,retval]*/ long * pCount ) = 0; + virtual HRESULT __stdcall AddTab ( + /*[in]*/ float tbPos, + /*[in]*/ long tbAlign, + /*[in]*/ long tbLeader ) = 0; + virtual HRESULT __stdcall ClearAllTabs ( ) = 0; + virtual HRESULT __stdcall DeleteTab ( + /*[in]*/ float tbPos ) = 0; + virtual HRESULT __stdcall GetTab ( + /*[in]*/ long iTab, + /*[out]*/ float * ptbPos, + /*[out]*/ long * ptbAlign, + /*[out]*/ long * ptbLeader ) = 0; +}; + +struct __declspec(uuid("8cc497c2-a1df-11ce-8098-00aa0047be5d")) +ITextRange : IDispatch +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall get_Text ( + /*[out,retval]*/ BSTR * pbstr ) = 0; + virtual HRESULT __stdcall put_Text ( + /*[in]*/ BSTR pbstr ) = 0; + virtual HRESULT __stdcall get_Char ( + /*[out,retval]*/ long * pch ) = 0; + virtual HRESULT __stdcall put_Char ( + /*[in]*/ long pch ) = 0; + virtual HRESULT __stdcall get_Duplicate ( + /*[out,retval]*/ struct ITextRange * * ppRange ) = 0; + virtual HRESULT __stdcall get_FormattedText ( + /*[out,retval]*/ struct ITextRange * * ppRange ) = 0; + virtual HRESULT __stdcall put_FormattedText ( + /*[in]*/ struct ITextRange * ppRange ) = 0; + virtual HRESULT __stdcall get_Start ( + /*[out,retval]*/ long * pcpFirst ) = 0; + virtual HRESULT __stdcall put_Start ( + /*[in]*/ long pcpFirst ) = 0; + virtual HRESULT __stdcall get_End ( + /*[out,retval]*/ long * pcpLim ) = 0; + virtual HRESULT __stdcall put_End ( + /*[in]*/ long pcpLim ) = 0; + virtual HRESULT __stdcall get_Font ( + /*[out,retval]*/ struct ITextFont * * pFont ) = 0; + virtual HRESULT __stdcall put_Font ( + /*[in]*/ struct ITextFont * pFont ) = 0; + virtual HRESULT __stdcall get_Para ( + /*[out,retval]*/ struct ITextPara * * pPara ) = 0; + virtual HRESULT __stdcall put_Para ( + /*[in]*/ struct ITextPara * pPara ) = 0; + virtual HRESULT __stdcall get_StoryLength ( + /*[out,retval]*/ long * pcch ) = 0; + virtual HRESULT __stdcall get_StoryType ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall Collapse ( + /*[in]*/ long bStart ) = 0; + virtual HRESULT __stdcall Expand ( + /*[in]*/ long Unit, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall GetIndex ( + /*[in]*/ long Unit, + /*[out,retval]*/ long * pIndex ) = 0; + virtual HRESULT __stdcall SetIndex ( + /*[in]*/ long Unit, + /*[in]*/ long Index, + /*[in]*/ long Extend ) = 0; + virtual HRESULT __stdcall SetRange ( + /*[in]*/ long cpActive, + /*[in]*/ long cpOther ) = 0; + virtual HRESULT __stdcall InRange ( + /*[in]*/ struct ITextRange * pRange, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall InStory ( + /*[in]*/ struct ITextRange * pRange, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall IsEqual ( + /*[in]*/ struct ITextRange * pRange, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall Select ( ) = 0; + virtual HRESULT __stdcall StartOf ( + /*[in]*/ long Unit, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall EndOf ( + /*[in]*/ long Unit, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall Move ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveStart ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveEnd ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveWhile ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveStartWhile ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveEndWhile ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveUntil ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveStartUntil ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveEndUntil ( + /*[in]*/ VARIANT * Cset, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall FindShit ( + /*[in]*/ BSTR bstr, + /*[in]*/ long cch, + /*[in]*/ long Flags, + /*[out,retval]*/ long * pLength ) = 0; + virtual HRESULT __stdcall FindTextStart ( + /*[in]*/ BSTR bstr, + /*[in]*/ long cch, + /*[in]*/ long Flags, + /*[out,retval]*/ long * pLength ) = 0; + virtual HRESULT __stdcall FindTextEnd ( + /*[in]*/ BSTR bstr, + /*[in]*/ long cch, + /*[in]*/ long Flags, + /*[out,retval]*/ long * pLength ) = 0; + virtual HRESULT __stdcall Delete ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall Cut ( + /*[out]*/ VARIANT * pVar ) = 0; + virtual HRESULT __stdcall Copy ( + /*[out]*/ VARIANT * pVar ) = 0; + virtual HRESULT __stdcall Paste ( + /*[in]*/ VARIANT * pVar, + /*[in]*/ long Format ) = 0; + virtual HRESULT __stdcall CanPaste ( + /*[in]*/ VARIANT * pVar, + /*[in]*/ long Format, + /*[out,retval]*/ long * pB ) = 0; + virtual HRESULT __stdcall CanEdit ( + /*[out,retval]*/ long * pbCanEdit ) = 0; + virtual HRESULT __stdcall ChangeCase ( + /*[in]*/ long Type ) = 0; + virtual HRESULT __stdcall GetPoint ( + /*[in]*/ long Type, + /*[out]*/ long * px, + /*[out]*/ long * py ) = 0; + virtual HRESULT __stdcall SetPoint ( + /*[in]*/ long x, + /*[in]*/ long y, + /*[in]*/ long Type, + /*[in]*/ long Extend ) = 0; + virtual HRESULT __stdcall ScrollIntoView ( + /*[in]*/ long Value ) = 0; + virtual HRESULT __stdcall GetEmbeddedObject ( + /*[out,retval]*/ IUnknown * * ppv ) = 0; +}; + +struct __declspec(uuid("8cc497c1-a1df-11ce-8098-00aa0047be5d")) +ITextSelection : ITextRange +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall get_Flags ( + /*[out,retval]*/ long * pFlags ) = 0; + virtual HRESULT __stdcall put_Flags ( + /*[in]*/ long pFlags ) = 0; + virtual HRESULT __stdcall get_Type ( + /*[out,retval]*/ long * pType ) = 0; + virtual HRESULT __stdcall MoveLeft ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveRight ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveUp ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall MoveDown ( + /*[in]*/ long Unit, + /*[in]*/ long Count, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall HomeKey ( + /*[in]*/ long Unit, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall EndKey ( + /*[in]*/ long Unit, + /*[in]*/ long Extend, + /*[out,retval]*/ long * pDelta ) = 0; + virtual HRESULT __stdcall TypeText ( + /*[in]*/ BSTR bstr ) = 0; +}; + +struct __declspec(uuid("8cc497c5-a1df-11ce-8098-00aa0047be5d")) +ITextStoryRanges : IDispatch +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall _NewEnum ( + /*[out,retval]*/ IUnknown * * ppunkEnum ) = 0; + virtual HRESULT __stdcall Item ( + /*[in]*/ long Index, + /*[out,retval]*/ struct ITextRange * * ppRange ) = 0; + virtual HRESULT __stdcall get_Count ( + /*[out,retval]*/ long * pCount ) = 0; +}; + +struct __declspec(uuid("8cc497c0-a1df-11ce-8098-00aa0047be5d")) +ITextDocument : IDispatch +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall get_Name ( + /*[out,retval]*/ BSTR * pName ) = 0; + virtual HRESULT __stdcall get_Selection ( + /*[out,retval]*/ struct ITextSelection * * ppSel ) = 0; + virtual HRESULT __stdcall get_StoryCount ( + /*[out,retval]*/ long * pCount ) = 0; + virtual HRESULT __stdcall get_StoryRanges ( + /*[out,retval]*/ struct ITextStoryRanges * * ppStories ) = 0; + virtual HRESULT __stdcall get_Saved ( + /*[out,retval]*/ long * pValue ) = 0; + virtual HRESULT __stdcall put_Saved ( + /*[in]*/ long pValue ) = 0; + virtual HRESULT __stdcall get_DefaultTabStop ( + /*[out,retval]*/ float * pValue ) = 0; + virtual HRESULT __stdcall put_DefaultTabStop ( + /*[in]*/ float pValue ) = 0; + virtual HRESULT __stdcall New ( ) = 0; + virtual HRESULT __stdcall Open ( + /*[in]*/ VARIANT * pVar, + /*[in]*/ long Flags, + /*[in]*/ long CodePage ) = 0; + virtual HRESULT __stdcall Save ( + /*[in]*/ VARIANT * pVar, + /*[in]*/ long Flags, + /*[in]*/ long CodePage ) = 0; + virtual HRESULT __stdcall Freeze ( + /*[out,retval]*/ long * pCount ) = 0; + virtual HRESULT __stdcall Unfreeze ( + /*[out,retval]*/ long * pCount ) = 0; + virtual HRESULT __stdcall BeginEditCollection ( ) = 0; + virtual HRESULT __stdcall EndEditCollection ( ) = 0; + virtual HRESULT __stdcall Undo ( + /*[in]*/ long Count, + /*[out,retval]*/ long * prop ) = 0; + virtual HRESULT __stdcall Redo ( + /*[in]*/ long Count, + /*[out,retval]*/ long * prop ) = 0; + virtual HRESULT __stdcall Range ( + /*[in]*/ long cp1, + /*[in]*/ long cp2, + /*[out,retval]*/ struct ITextRange * * ppRange ) = 0; + virtual HRESULT __stdcall RangeFromPoint ( + /*[in]*/ long x, + /*[in]*/ long y, + /*[out,retval]*/ struct ITextRange * * ppRange ) = 0; +}; + +struct __declspec(uuid("01c25500-4268-11d1-883a-3c8b00c10000")) +ITextDocument2 : ITextDocument +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall AttachMsgFilter ( + /*[in]*/ IUnknown * pFilter ) = 0; + virtual HRESULT __stdcall SetEffectColor ( + /*[in]*/ long Index, + /*[in]*/ unsigned long cr ) = 0; + virtual HRESULT __stdcall GetEffectColor ( + /*[in]*/ long Index, + /*[out]*/ unsigned long * pcr ) = 0; + virtual HRESULT __stdcall get_CaretType ( + /*[out,retval]*/ long * pCaretType ) = 0; + virtual HRESULT __stdcall put_CaretType ( + /*[in]*/ long pCaretType ) = 0; + virtual HRESULT __stdcall GetImmContext ( + /*[out,retval]*/ long * pContext ) = 0; + virtual HRESULT __stdcall ReleaseImmContext ( + /*[in]*/ long Context ) = 0; + virtual HRESULT __stdcall GetPreferredFont ( + /*[in]*/ long cp, + /*[in]*/ long CodePage, + /*[in]*/ long Option, + /*[in]*/ long curCodepage, + /*[in]*/ long curFontSize, + /*[out]*/ BSTR * pbstr, + /*[out]*/ long * pPitchAndFamily, + /*[out]*/ long * pNewFontSize ) = 0; + virtual HRESULT __stdcall get_NotificationMode ( + /*[out,retval]*/ long * pMode ) = 0; + virtual HRESULT __stdcall put_NotificationMode ( + /*[in]*/ long pMode ) = 0; + virtual HRESULT __stdcall GetClientRect ( + /*[in]*/ long Type, + /*[out]*/ long * pLeft, + /*[out]*/ long * pTop, + /*[out]*/ long * pRight, + /*[out]*/ long * pBottom ) = 0; + virtual HRESULT __stdcall get_SelectionEx ( + /*[out,retval]*/ struct ITextSelection * * ppSel ) = 0; + virtual HRESULT __stdcall GetWindow ( + /*[out]*/ long * phWnd ) = 0; + virtual HRESULT __stdcall GetFEFlags ( + /*[out]*/ long * pFlags ) = 0; + virtual HRESULT __stdcall UpdateWindow ( ) = 0; + virtual HRESULT __stdcall CheckTextLimit ( + long cch, + long * pcch ) = 0; + virtual HRESULT __stdcall IMEInProgress ( + long Mode ) = 0; + virtual HRESULT __stdcall SysBeep ( ) = 0; + virtual HRESULT __stdcall Update ( + /*[in]*/ long Mode ) = 0; + virtual HRESULT __stdcall Notify ( + /*[in]*/ long Notify ) = 0; +}; + +#pragma pack(push, 4) + +union __MIDL_IWinTypes_0009 +{ + long hInproc; + long hRemote; +}; + +#pragma pack(pop) + +#pragma pack(push, 4) + +struct _RemotableHandle +{ + long fContext; + union __MIDL_IWinTypes_0009 u; +}; + +#pragma pack(pop) + +struct __declspec(uuid("a3787420-4267-11d1-883a-3c8b00c10000")) +ITextMsgFilter : IUnknown +{ + // + // Raw methods provided by interface + // + + virtual HRESULT __stdcall AttachDocument ( + /*[in]*/ wireHWND hwnd, + /*[in]*/ struct ITextDocument2 * pTextDoc ) = 0; + virtual HRESULT __stdcall HandleMessage ( + /*[in,out]*/ unsigned int * pmsg, + /*[in,out]*/ UINT_PTR * pwparam, + /*[in,out]*/ LONG_PTR * plparam, + /*[out]*/ LONG_PTR * plres ) = 0; + virtual HRESULT __stdcall AttachMsgFilter ( + /*[in]*/ struct ITextMsgFilter * pMsgFilter ) = 0; +}; + +// +// Named GUID constants initializations +// + +extern "C" const GUID __declspec(selectany) LIBID_tom = + {0x8cc497c9,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextFont = + {0x8cc497c3,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextPara = + {0x8cc497c4,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextRange = + {0x8cc497c2,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextSelection = + {0x8cc497c1,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextStoryRanges = + {0x8cc497c5,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextDocument = + {0x8cc497c0,0xa1df,0x11ce,{0x80,0x98,0x00,0xaa,0x00,0x47,0xbe,0x5d}}; +extern "C" const GUID __declspec(selectany) IID_ITextDocument2 = + {0x01c25500,0x4268,0x11d1,{0x88,0x3a,0x3c,0x8b,0x00,0xc1,0x00,0x00}}; +extern "C" const GUID __declspec(selectany) IID_ITextMsgFilter = + {0xa3787420,0x4267,0x11d1,{0x88,0x3a,0x3c,0x8b,0x00,0xc1,0x00,0x00}}; + +} // namespace tom + +#pragma pack(pop) diff --git a/tools/common/AlphaPopup.cpp b/tools/common/AlphaPopup.cpp new file mode 100644 index 000000000..78ed03bc1 --- /dev/null +++ b/tools/common/AlphaPopup.cpp @@ -0,0 +1,333 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" +#include "ColorButton.h" +#include "MaskEdit.h" +#include "../../sys/win32/rc/guied_resource.h" + +static HHOOK gAlphaHook = NULL; +static HWND gAlphaDlg = NULL; + +/* +================ +AlphaSlider_DrawArrow + +Draws the arrow under alpha slider +================ +*/ +static void AlphaSlider_DrawArrow ( HDC hDC, RECT* pRect, COLORREF color ) +{ + POINT ptsArrow[3]; + + ptsArrow[0].x = pRect->left; + ptsArrow[0].y = pRect->bottom; + ptsArrow[1].x = (pRect->left + pRect->right)/2; + ptsArrow[1].y = pRect->top; + ptsArrow[2].x = pRect->right; + ptsArrow[2].y = pRect->bottom; + + HBRUSH arrowBrush = CreateSolidBrush ( color ); + HPEN arrowPen = CreatePen ( PS_SOLID, 1, color ); + + HGDIOBJ oldBrush = SelectObject ( hDC, arrowBrush ); + HGDIOBJ oldPen = SelectObject ( hDC, arrowPen ); + + SetPolyFillMode(hDC, WINDING); + Polygon(hDC, ptsArrow, 3); + + SelectObject ( hDC, oldBrush ); + SelectObject ( hDC, oldPen ); + + DeleteObject ( arrowBrush ); + DeleteObject ( arrowPen ); +} + +/* +================ +AlphaSlider_WndProc + +Window procedure for the alpha slider control +================ +*/ +LRESULT CALLBACK AlphaSlider_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_LBUTTONDOWN: + { + RECT rClient; + float v; + + GetClientRect ( hwnd, &rClient ); + v = (float)((short)LOWORD(lParam)-5) / (float)(rClient.right - rClient.left - 10); + if ( v < 0 ) v = 0; + if ( v > 1.0f ) v = 1.0f; + SetWindowLong ( hwnd, GWL_USERDATA, MAKELONG(0x8000,(unsigned short)(255.0f * v)) ); + InvalidateRect ( hwnd, NULL, FALSE ); + + SetCapture ( hwnd ); + + break; + } + + case WM_MOUSEMOVE: + if ( LOWORD(GetWindowLong ( hwnd, GWL_USERDATA ) ) & 0x8000 ) + { + RECT rClient; + float v; + + GetClientRect ( hwnd, &rClient ); + v = (float)((short)LOWORD(lParam)-5) / (float)(rClient.right - rClient.left - 10); + if ( v < 0 ) v = 0; + if ( v > 1.0f ) v = 1.0f; + SetWindowLong ( hwnd, GWL_USERDATA, MAKELONG(0x8000,(unsigned short)(255.0f * v)) ); + InvalidateRect ( hwnd, NULL, FALSE ); + } + break; + + case WM_LBUTTONUP: + if ( LOWORD(GetWindowLong ( hwnd, GWL_USERDATA ) ) & 0x8000 ) + { + RECT rClient; + float v; + + GetClientRect ( hwnd, &rClient ); + v = (float)((short)LOWORD(lParam)-5) / (float)(rClient.right - rClient.left - 10); + if ( v < 0 ) v = 0; + if ( v > 1.0f ) v = 1.0f; + SetWindowLong ( hwnd, GWL_USERDATA, MAKELONG(0x8000,(unsigned short)(255.0f * v)) ); + InvalidateRect ( hwnd, NULL, FALSE ); + ReleaseCapture ( ); + SendMessage ( GetParent ( hwnd ), WM_COMMAND, MAKELONG(GetWindowLong (hwnd,GWL_ID),0), 0 ); + } + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint ( hwnd, &ps ); + + RECT rDraw; + RECT rClient; + GetClientRect ( hwnd, &rClient ); + + // Setup the gradient rect + CopyRect ( &rDraw, &rClient ); + rDraw.left += 5; + rDraw.right -= 5; + rDraw.bottom -= 6; + + // Draw the gradient + int parts = 20; + RECT rColor; + float step = (float)(rDraw.right-rDraw.left) / (float)parts; + CopyRect ( &rColor, &rDraw ); + for ( int i = 0; i < parts; i ++ ) + { + float color = ((float)i / (float)parts) * 255.0f; + + rColor.left = rDraw.left + i * step; + rColor.right = rColor.left + step + 1; + + HBRUSH brush = CreateSolidBrush ( RGB((int)color,(int)color,(int)color) ); + FillRect ( hDC, &rColor, brush ); + DeleteObject ( brush ); + } + + // Draw a frame around the gradient + FrameRect (hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) ); + + // Make sure the area below the graident is filled in + rClient.top = rDraw.bottom; + FillRect ( hDC, &rClient, GetSysColorBrush ( COLOR_3DFACE ) ); + + // Draw the thumb + RECT rThumb; + short s = HIWORD(GetWindowLong ( hwnd, GWL_USERDATA )); + float thumb = (float)(short)s; + thumb /= 255.0f; + thumb *= (float)(rDraw.right-rDraw.left); + rThumb.left = rDraw.left - 5 + thumb; + rThumb.right = rThumb.left + 10; + rThumb.top = rDraw.bottom + 1; + rThumb.bottom = rThumb.top + 5; + AlphaSlider_DrawArrow ( hDC, &rThumb, RGB(0,0,0) ); + + EndPaint ( hwnd, &ps ); + return 0; + } + } + + return DefWindowProc ( hwnd, msg, wParam, lParam ); +} + +/* +================ +AlphaSelectDlg_GetMsgProc + +Ensures normal dialog functions work in the alpha select dialog +================ +*/ +LRESULT FAR PASCAL AlphaSelectDlg_GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LPMSG lpMsg = (LPMSG) lParam; + + if ( nCode >= 0 && PM_REMOVE == wParam ) + { + // Don't translate non-input events. + if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) ) + { + if ( IsDialogMessage( gAlphaDlg, lpMsg) ) + { + // The value returned from this hookproc is ignored, + // and it cannot be used to tell Windows the message has been handled. + // To avoid further processing, convert the message to WM_NULL + // before returning. + lpMsg->message = WM_NULL; + lpMsg->lParam = 0; + lpMsg->wParam = 0; + } + } + } + + return CallNextHookEx(gAlphaHook, nCode, wParam, lParam); +} + +/* +================ +AlphaSelectDlg_WndProc + +Window procedure for the alpha select dialog +================ +*/ +INT_PTR CALLBACK AlphaSelectDlg_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_INITDIALOG: + { + int color; + + gAlphaDlg = hwnd; + gAlphaHook = SetWindowsHookEx( WH_GETMESSAGE, AlphaSelectDlg_GetMsgProc, NULL, GetCurrentThreadId() ); + color = GetRValue(ColorButton_GetColor ((HWND)lParam)); + + // The lParam for the alpha select dialog is the window handle of the button pressed + SetWindowLong ( hwnd, GWL_USERDATA, lParam ); + + // Subclass the alpha + SetWindowLong ( GetDlgItem ( hwnd, IDC_GUIED_ALPHASLIDER ), GWL_USERDATA, MAKELONG(0,color) ); + + // Numbers only on the edit box and start it with the current alpha value. + NumberEdit_Attach ( GetDlgItem ( hwnd, IDC_GUIED_ALPHA ) ); + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_ALPHA ), va("%.3f", ((float)color / 255.0f) ) ); + break; + } + + case WM_DESTROY: + UnhookWindowsHookEx( gAlphaHook ); + ReleaseCapture ( ); + gAlphaDlg = NULL; + break; + + case WM_ACTIVATE: + if ( !LOWORD(wParam) ) + { + EndDialog ( hwnd, 0 ); + } + break; + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case IDC_GUIED_ALPHA: + { + char temp[64]; + float value; + + // Get the current text in the window and convert it to a float + GetDlgItemText ( hwnd, IDC_GUIED_ALPHA, temp, 64 ); + value = atof ( temp ); + + if ( value < 0.0f ) + { + value = 0.0f; + } + else if ( value > 1.0f ) + { + value = 1.0f; + } + + // Set the current alpha value in the slider + SetWindowLong ( GetDlgItem ( hwnd, IDC_GUIED_ALPHASLIDER ), GWL_USERDATA, MAKELONG(0,(255.0f * value)) ); + break; + } + + case IDC_GUIED_ALPHASLIDER: + case IDOK: + { + int color = (short)HIWORD(GetWindowLong ( GetDlgItem ( hwnd, IDC_GUIED_ALPHASLIDER ), GWL_USERDATA )); + ColorButton_SetColor ( (HWND)GetWindowLong ( hwnd, GWL_USERDATA ), RGB(color,color,color) ); + EndDialog ( hwnd, 0 ); + break; + } + + case IDCANCEL: + EndDialog ( hwnd, 0 ); + break; + } + break; + } + + return FALSE; +} + +/* +================ +AlphaButton_OpenPopup + +Opens the popup window under the alpha button +================ +*/ +void AlphaButton_OpenPopup ( HWND button ) +{ + RECT rWindow; + WNDCLASSEX wndClass; + HWND dlg; + + // Make sure the alpha slider window class is registered + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "GUIED_ALPHASLIDER"; + wndClass.lpfnWndProc = AlphaSlider_WndProc; + wndClass.hInstance = win32.hInstance; + RegisterClassEx ( &wndClass ); + + GetWindowRect ( button, &rWindow ); + dlg = CreateDialogParam ( win32.hInstance, MAKEINTRESOURCE(IDD_GUIED_ALPHA), GetParent(button), AlphaSelectDlg_WndProc, (LPARAM)button ); + + SetWindowPos ( dlg, NULL, rWindow.left, rWindow.bottom + 1, 0, 0, SWP_NOSIZE|SWP_NOZORDER ); + ShowWindow ( dlg, SW_SHOW ); + UpdateWindow ( dlg ); + SetFocus ( dlg ); +} diff --git a/tools/common/ColorButton.cpp b/tools/common/ColorButton.cpp new file mode 100644 index 000000000..c897caf2b --- /dev/null +++ b/tools/common/ColorButton.cpp @@ -0,0 +1,197 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "ColorButton.h" + +static const int ARROW_SIZE_CX = 4 ; +static const int ARROW_SIZE_CY = 2 ; + +/* +================ +ColorButton_SetColor + +Sets the current color button color +================ +*/ +void ColorButton_SetColor ( HWND hWnd, COLORREF color ) +{ + if ( NULL == hWnd ) + { + return; + } + SetWindowLong ( hWnd, GWL_USERDATA, color ); + InvalidateRect ( hWnd, NULL, FALSE ); +} + +void ColorButton_SetColor ( HWND hWnd, const char* color ) +{ + float red; + float green; + float blue; + float alpha; + + if ( NULL == hWnd ) + { + return; + } + + sscanf ( color, "%f,%f,%f,%f", &red, &green, &blue, &alpha ); + + ColorButton_SetColor ( hWnd, RGB(red*255.0f, green*255.0f, blue*255.0f) ); +} + +void AlphaButton_SetColor ( HWND hWnd, const char* color ) +{ + float red; + float green; + float blue; + float alpha; + + if ( NULL == hWnd ) + { + return; + } + + sscanf ( color, "%f,%f,%f,%f", &red, &green, &blue, &alpha ); + + ColorButton_SetColor ( hWnd, RGB(alpha*255.0f, alpha*255.0f, alpha*255.0f) ); +} + +/* +================ +ColorButton_GetColor + +Retrieves the current color button color +================ +*/ +COLORREF ColorButton_GetColor ( HWND hWnd ) +{ + return (COLORREF) GetWindowLong ( hWnd, GWL_USERDATA ); +} + +/* +================ +ColorButton_DrawArrow + +Draws the arrow on the color button +================ +*/ +static void ColorButton_DrawArrow ( HDC hDC, RECT* pRect, COLORREF color ) +{ + POINT ptsArrow[3]; + + ptsArrow[0].x = pRect->left; + ptsArrow[0].y = pRect->top; + ptsArrow[1].x = pRect->right; + ptsArrow[1].y = pRect->top; + ptsArrow[2].x = (pRect->left + pRect->right)/2; + ptsArrow[2].y = pRect->bottom; + + HBRUSH arrowBrush = CreateSolidBrush ( color ); + HPEN arrowPen = CreatePen ( PS_SOLID, 1, color ); + + HGDIOBJ oldBrush = SelectObject ( hDC, arrowBrush ); + HGDIOBJ oldPen = SelectObject ( hDC, arrowPen ); + + SetPolyFillMode(hDC, WINDING); + Polygon(hDC, ptsArrow, 3); + + SelectObject ( hDC, oldBrush ); + SelectObject ( hDC, oldPen ); + + DeleteObject ( arrowBrush ); + DeleteObject ( arrowPen ); +} + +/* +================ +ColorButton_DrawItem + +Draws the actual color button as as reponse to a WM_DRAWITEM message +================ +*/ +void ColorButton_DrawItem ( HWND hWnd, LPDRAWITEMSTRUCT dis ) +{ + assert ( dis ); + + HDC hDC = dis->hDC; + UINT state = dis->itemState; + RECT rDraw = dis->rcItem; + RECT rArrow; + + // Draw outter edge + UINT uFrameState = DFCS_BUTTONPUSH|DFCS_ADJUSTRECT; + + if (state & ODS_SELECTED) + { + uFrameState |= DFCS_PUSHED; + } + + if (state & ODS_DISABLED) + { + uFrameState |= DFCS_INACTIVE; + } + + DrawFrameControl ( hDC, &rDraw, DFC_BUTTON, uFrameState ); + + // Draw Focus + if (state & ODS_SELECTED) + { + OffsetRect(&rDraw, 1,1); + } + + if (state & ODS_FOCUS) + { + RECT rFocus = {rDraw.left, + rDraw.top, + rDraw.right - 1, + rDraw.bottom}; + + DrawFocusRect ( hDC, &rFocus ); + } + + InflateRect ( &rDraw, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE) ); + + // Draw the arrow + rArrow.left = rDraw.right - ARROW_SIZE_CX - GetSystemMetrics(SM_CXEDGE) /2; + rArrow.right = rArrow.left + ARROW_SIZE_CX; + rArrow.top = (rDraw.bottom + rDraw.top)/2 - ARROW_SIZE_CY / 2; + rArrow.bottom = (rDraw.bottom + rDraw.top)/2 + ARROW_SIZE_CY / 2; + + ColorButton_DrawArrow ( hDC, &rArrow, (state & ODS_DISABLED) ? ::GetSysColor(COLOR_GRAYTEXT) : RGB(0,0,0) ); + + rDraw.right = rArrow.left - GetSystemMetrics(SM_CXEDGE)/2; + + // Draw separator + DrawEdge ( hDC, &rDraw, EDGE_ETCHED, BF_RIGHT); + + rDraw.right -= (GetSystemMetrics(SM_CXEDGE) * 2) + 1 ; + + // Draw Color + if ((state & ODS_DISABLED) == 0) + { + HBRUSH color = CreateSolidBrush ( (COLORREF)GetWindowLong ( hWnd, GWL_USERDATA ) ); + FillRect ( hDC, &rDraw, color ); + FrameRect ( hDC, &rDraw, (HBRUSH)::GetStockObject(BLACK_BRUSH)); + DeleteObject( color ); + } +} diff --git a/tools/common/ColorButton.h b/tools/common/ColorButton.h new file mode 100644 index 000000000..16ddd6b7d --- /dev/null +++ b/tools/common/ColorButton.h @@ -0,0 +1,31 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef COLORBUTTON_H_ +#define COLORBUTTON_H_ + +void ColorButton_DrawItem ( HWND hWnd, LPDRAWITEMSTRUCT dis ); +void ColorButton_SetColor ( HWND hWnd, COLORREF color ); +void ColorButton_SetColor ( HWND hWnd, const char* color ); +COLORREF ColorButton_GetColor ( HWND hWnd ); + +void AlphaButton_SetColor ( HWND hWnd, const char* color ); + +void AlphaButton_OpenPopup ( HWND button ); + +#endif // COLORBUTTON_H_ \ No newline at end of file diff --git a/tools/common/DialogHelpers.h b/tools/common/DialogHelpers.h new file mode 100644 index 000000000..2de6bfc95 --- /dev/null +++ b/tools/common/DialogHelpers.h @@ -0,0 +1,119 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef DIALOGHELPERS_H_ +#define DIALOGHELPERS_H_ + +class rvDialogItem +{ +public: + + HWND mWindow; + int mID; + + rvDialogItem ( int id ) { mID = id; } + + void Cache ( HWND parent ) + { + mWindow = GetDlgItem ( parent, mID ); + } + + void Check ( bool checked ) + { + SendMessage ( mWindow, BM_SETCHECK, checked ? BST_CHECKED : BST_UNCHECKED, 0 ); + } + + void Enable ( bool enable ) + { + EnableWindow ( mWindow, enable ); + } + + bool IsChecked ( void ) + { + return SendMessage ( mWindow, BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false; + } + + void SetText ( const char* text ) + { + SetWindowText ( mWindow, text ); + } + + void GetText ( idStr& out ) + { + char text[4096]; + GetWindowText ( mWindow, text, 4095 ); + out = text; + } + + float GetFloat ( void ) + { + idStr text; + GetText ( text ); + return atof( text ); + } + + void SetFloat ( float f ) + { + SetText ( va("%g", f ) ); + } + + operator HWND( void ) const { return mWindow; } +}; + +class rvDialogItemContainer +{ +protected: + + void Cache ( HWND parent, int count ) + { + int i; + unsigned char* ptr; + + ptr = (unsigned char*)this; + for ( i = 0; i < count; i ++, ptr += sizeof(rvDialogItem) ) + { + ((rvDialogItem*)ptr)->Cache ( parent ); + } + } +}; + +#define DIALOGITEM_BEGIN(name) \ +class name : public rvDialogItemContainer \ +{ \ +public: \ + name ( void ) { } \ + name ( HWND hwnd ) { Cache ( hwnd ); } \ + void Cache ( HWND parent ) \ + { \ + rvDialogItemContainer::Cache ( parent, sizeof(*this)/sizeof(rvDialogItem) ); \ + } + + +#define DIALOGITEM(id,name) \ +class c##name : public rvDialogItem \ +{ \ +public: \ + c##name(int localid=id) : rvDialogItem ( localid ) { } \ +} name; + +#define DIALOGITEM_END() \ +}; + + +#endif // DIALOGHELPERS_H_ diff --git a/tools/common/MaskEdit.cpp b/tools/common/MaskEdit.cpp new file mode 100644 index 000000000..7563e5322 --- /dev/null +++ b/tools/common/MaskEdit.cpp @@ -0,0 +1,88 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#define MASKEDIT_MAXINVALID 1024 +typedef struct +{ + WNDPROC mProc; + char mInvalid[MASKEDIT_MAXINVALID]; +} rvGEMaskEdit; + +/* +================ +MaskEdit_WndProc + +Prevents the invalid characters from being entered +================ +*/ +LRESULT CALLBACK MaskEdit_WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGEMaskEdit* edit = (rvGEMaskEdit*)GetWindowLong ( hWnd, GWL_USERDATA ); + WNDPROC wndproc = edit->mProc; + + switch ( msg ) + { + case WM_CHAR: + if ( strchr ( edit->mInvalid, wParam ) ) + { + return 0; + } + + break; + + case WM_DESTROY: + delete edit; + SetWindowLong ( hWnd, GWL_WNDPROC, (LONG)wndproc ); + break; + } + + return CallWindowProc ( wndproc, hWnd, msg, wParam, lParam ); +} + +/* +================ +MaskEdit_Attach + +Attaches the mask edit control to a normal edit control +================ +*/ +void MaskEdit_Attach ( HWND hWnd, const char* invalid ) +{ + rvGEMaskEdit* edit = new rvGEMaskEdit; + edit->mProc = (WNDPROC)GetWindowLong ( hWnd, GWL_WNDPROC ); + strcpy ( edit->mInvalid, invalid ); + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)edit ); + SetWindowLong ( hWnd, GWL_WNDPROC, (LONG)MaskEdit_WndProc ); +} + +/* +================ +NumberEdit_Attach + +Allows editing of floating point numbers +================ +*/ +void NumberEdit_Attach ( HWND hWnd ) +{ + static const char invalid[] = "`~!@#$%^&*()_+|=\\qwertyuiop[]asdfghjkl;'zxcvbnm,/QWERTYUIOP{}ASDFGHJKL:ZXCVBNM<>"; + MaskEdit_Attach ( hWnd, invalid ); +} diff --git a/tools/common/MaskEdit.h b/tools/common/MaskEdit.h new file mode 100644 index 000000000..f718fac7a --- /dev/null +++ b/tools/common/MaskEdit.h @@ -0,0 +1,25 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef MASKEDIT_H_ +#define MASKEDIT_H_ + +void MaskEdit_Attach ( HWND hWnd, const char* invalid ); +void NumberEdit_Attach ( HWND hWnd ); + +#endif // MASKEDIT_H_ \ No newline at end of file diff --git a/tools/common/OpenFileDialog.cpp b/tools/common/OpenFileDialog.cpp new file mode 100644 index 000000000..e1482830c --- /dev/null +++ b/tools/common/OpenFileDialog.cpp @@ -0,0 +1,495 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" +#include "../../sys/win32/rc/common_resource.h" +#include "OpenFileDialog.h" + +char rvOpenFileDialog::mLookin[ MAX_OSPATH ]; + +/* +================ +rvOpenFileDialog::rvOpenFileDialog + +constructor +================ +*/ +rvOpenFileDialog::rvOpenFileDialog( void ) +{ + mWnd = NULL; + mInstance = NULL; + mBackBitmap = NULL; + mImageList = NULL; + mFlags = 0; +} + +/* +================ +rvOpenFileDialog::~rvOpenFileDialog + +destructor +================ +*/ +rvOpenFileDialog::~rvOpenFileDialog ( void ) +{ + if ( mImageList ) + { + ImageList_Destroy ( mImageList ); + } + + if ( mBackBitmap ) + { + DeleteObject ( mBackBitmap ); + } +} + +/* +================ +rvOpenFileDialog::DoModal + +Opens the dialog and returns true if a filename was found +================ +*/ +bool rvOpenFileDialog::DoModal ( HWND parent ) +{ + mInstance = win32.hInstance; + + INITCOMMONCONTROLSEX ex; + ex.dwICC = ICC_USEREX_CLASSES | ICC_LISTVIEW_CLASSES; + ex.dwSize = sizeof(INITCOMMONCONTROLSEX); + + InitCommonControlsEx ( &ex ); + + return DialogBoxParam ( mInstance, MAKEINTRESOURCE(IDD_TOOLS_OPEN), parent, DlgProc, (LPARAM)this ) ? true : false; +} + +/* +================ +rvOpenFileDialog::UpdateLookIn + +Updates the lookin combo box with the current lookin state +================ +*/ +void rvOpenFileDialog::UpdateLookIn ( void ) +{ + COMBOBOXEXITEM item; + idStr file; + idStr path; + + // Reset the combo box + SendMessage ( mWndLookin, CB_RESETCONTENT, 0, 0 ); + + // Setup the common item structure components + ZeroMemory ( &item, sizeof(item) ); + item.mask = CBEIF_TEXT | CBEIF_INDENT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + + // Add the top left folder + item.pszText = (LPSTR)"base"; + SendMessage ( mWndLookin, CBEM_INSERTITEM, 0, (LPARAM)&item ); + + // Break the lookin path up into its individual components and add them + // to the combo box + path = mLookin; + + while ( path.Length ( ) ) + { + int slash = path.Find ( "/" ); + + // Parse out the next subfolder + if ( slash != -1 ) + { + file = path.Left ( slash ); + path = path.Right ( path.Length ( ) - slash - 1 ); + } + else + { + file = path; + path.Empty ( ); + } + + // Add the sub folder + item.pszText = (LPSTR)file.c_str(); + item.iIndent++; + item.iItem = item.iIndent; + SendMessage ( mWndLookin, CBEM_INSERTITEM, 0, (LPARAM)&item ); + } + + // Set the selection to the last one since thats the deepest folder + SendMessage ( mWndLookin, CB_SETCURSEL, item.iIndent, 0 ); +} + +/* +================ +rvOpenFileDialog::UpdateFileList + +Updates the file list with the files that match the filter in the current +look in directory +================ +*/ +void rvOpenFileDialog::UpdateFileList ( void ) +{ + const char *basepath = mLookin; + idFileList *files; + HWND list = GetDlgItem ( mWnd, IDC_TOOLS_FILELIST ); + int i; + int filter; + + ListView_DeleteAllItems ( list ); + + // Add all the folders first + files = fileSystem->ListFiles ( basepath, "/", true ); + for ( i = 0; i < files->GetNumFiles(); i ++ ) + { + if ( files->GetFile( i )[0] == '.' ) + { + continue; + } + + LVITEM item; + item.mask = LVIF_TEXT; + item.iItem = ListView_GetItemCount ( list ); + item.pszText = (LPSTR)files->GetFile( i ); + item.iSubItem = 0; + ListView_InsertItem ( list, &item ); + } + fileSystem->FreeFileList( files ); + + // Add all the files in the current lookin directory that match the + // current filters. + for ( filter = 0; filter < mFilters.Num(); filter ++ ) + { + files = fileSystem->ListFiles( basepath, mFilters[filter], true ); + for ( i = 0; i < files->GetNumFiles(); i ++ ) + { + if ( files->GetFile( i )[0] == '.' ) + { + continue; + } + + LVITEM item; + item.mask = LVIF_TEXT|LVIF_IMAGE; + item.iImage = 2; + item.iItem = ListView_GetItemCount( list ); + item.pszText = (LPSTR)files->GetFile( i ); + item.iSubItem = 0; + ListView_InsertItem ( list, &item ); + } + fileSystem->FreeFileList( files ); + } +} + +/* +================ +rvOpenFileDialog::HandleCommandOK + +Handles the pressing of the OK button but either opening a selected folder +or closing the dialog with the resulting filename +================ +*/ +void rvOpenFileDialog::HandleCommandOK ( void ) +{ + char temp[256]; + LVITEM item; + + // If nothing is selected then there is nothing to open + int sel = ListView_GetNextItem ( mWndFileList, -1, LVNI_SELECTED ); + if ( sel == -1 ) + { + GetWindowText ( GetDlgItem ( mWnd, IDC_TOOLS_FILENAME ), temp, sizeof(temp)-1 ); + if ( !temp[0] ) + { + return; + } + + item.iImage = 2; + } + else + { + // Get the currently selected item + item.mask = LVIF_IMAGE|LVIF_TEXT; + item.iImage = sel; + item.iSubItem = 0; + item.pszText = temp; + item.cchTextMax = 256; + item.iItem = sel; + ListView_GetItem ( mWndFileList, &item ); + } + + // If the item is a folder then just open that folder + if ( item.iImage == 0 ) + { + if ( strlen( mLookin ) ) + { + idStr::snPrintf( mLookin, sizeof( mLookin ), "%s/%s", mLookin, temp ); + } else { + idStr::Copynz( mLookin, temp, sizeof( mLookin ) ); + } + UpdateLookIn ( ); + UpdateFileList ( ); + } + // If the item is a file then build the filename and end the dialog + else if ( item.iImage == 2 ) + { + mFilename = mLookin; + if ( mFilename.Length ( ) ) + { + mFilename.Append ( "/" ); + } + mFilename.Append ( temp ); + + // Make sure the file exists + if ( mFlags & OFD_MUSTEXIST ) + { + idFile* file; + file = fileSystem->OpenFileRead ( mFilename ); + if ( !file ) + { + MessageBox ( mWnd, va("%s\nFile not found.\nPlease verify the correct file name was given", mFilename.c_str() ), "Open", MB_ICONERROR|MB_OK ); + return; + } + fileSystem->CloseFile ( file ); + } + + EndDialog ( mWnd, 1 ); + } + + return; +} + +/* +================ +rvOpenFileDialog::HandleInitDialog + +Handles the init dialog message +================ +*/ +void rvOpenFileDialog::HandleInitDialog ( void ) +{ + // Cache the more used window handles + mWndFileList = GetDlgItem ( mWnd, IDC_TOOLS_FILELIST ); + mWndLookin = GetDlgItem ( mWnd, IDC_TOOLS_LOOKIN ); + + // Load the custom resources used by the controls + mImageList = ImageList_LoadBitmap ( mInstance, MAKEINTRESOURCE(IDB_TOOLS_OPEN),16,1,RGB(255,255,255) ); + mBackBitmap = (HBITMAP)LoadImage ( mInstance, MAKEINTRESOURCE(IDB_TOOLS_BACK), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + + // Attach the image list to the file list and lookin controls + ListView_SetImageList ( mWndFileList, mImageList, LVSIL_SMALL ); + SendMessage( mWndLookin,CBEM_SETIMAGELIST,0,(LPARAM) mImageList ); + + // Back button is a bitmap button + SendMessage( GetDlgItem ( mWnd, IDC_TOOLS_BACK ), BM_SETIMAGE, IMAGE_BITMAP, (LONG) mBackBitmap ); + + // Allow custom titles + SetWindowText ( mWnd, mTitle ); + + // Custom ok button title + if ( mOKTitle.Length ( ) ) + { + SetWindowText ( GetDlgItem ( mWnd, IDOK ), mOKTitle ); + } + + // See if there is a filename in the lookin + idStr temp; + idStr filename = mLookin; + filename.ExtractFileExtension ( temp ); + if ( temp.Length ( ) ) + { + filename.ExtractFileName ( temp ); + SetWindowText ( GetDlgItem ( mWnd, IDC_TOOLS_FILENAME ), temp ); + filename.StripFilename ( ); + idStr::snPrintf( mLookin, sizeof( mLookin ), "%s", filename.c_str() ); + } + + // Update our controls + UpdateLookIn ( ); + UpdateFileList ( ); +} + +/* +================ +rvOpenFileDialog::HandleLookInChange + +Handles a selection change within the lookin control +================ +*/ +void rvOpenFileDialog::HandleLookInChange ( void ) +{ + char temp[256]; + int sel; + int i; + idStr lookin; + + temp[0] = 0; + + sel = SendMessage ( mWndLookin, CB_GETCURSEL, 0, 0 ); + + // If something other than base is selected then walk up the list + // and build the new lookin path + if ( sel >= 1 ) + { + SendMessage ( mWndLookin, CB_GETLBTEXT, 1, (LPARAM)temp ); + idStr::snPrintf( mLookin, sizeof( mLookin ), "%s", temp ); + for ( i = 2; i <= sel; i ++ ) + { + SendMessage ( mWndLookin, CB_GETLBTEXT, i, (LPARAM)temp ); + idStr::snPrintf( mLookin, sizeof( mLookin ), "%s/%s", mLookin, temp ); + } + } + else + { + mLookin[0] = 0; + } + + // Update the controls with the new lookin path + UpdateLookIn ( ); + UpdateFileList ( ); +} + +/* +================ +rvOpenFileDialog::SetFilter + +Set the extensions available in the dialog +================ +*/ +void rvOpenFileDialog::SetFilter ( const char* s ) +{ + idStr filters = s; + idStr filter; + + while ( filters.Length ( ) ) + { + int semi = filters.Find ( ';' ); + if ( semi != -1 ) + { + filter = filters.Left ( semi ); + filters = filters.Right ( filters.Length ( ) - semi ); + } + else + { + filter = filters; + filters.Empty ( ); + } + + mFilters.Append ( filter.c_str() + (filter[0] == '*' ? 1 : 0) ); + } +} + +/* +================ +rvOpenFileDialog::DlgProc + +Dialog Procedure for the open file dialog +================ +*/ +INT_PTR rvOpenFileDialog::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + rvOpenFileDialog* dlg = (rvOpenFileDialog*) GetWindowLong ( wnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_INITDIALOG: + dlg = (rvOpenFileDialog*) lparam; + SetWindowLong ( wnd, GWL_USERDATA, lparam ); + dlg->mWnd = wnd; + dlg->HandleInitDialog ( ); + return TRUE; + + case WM_NOTIFY: + { + NMHDR* nm = (NMHDR*) lparam; + switch ( nm->idFrom ) + { + case IDC_TOOLS_FILELIST: + switch ( nm->code ) + { + case LVN_ITEMCHANGED: + { + NMLISTVIEW* nmlv = (NMLISTVIEW*)nm; + if ( nmlv->uNewState & LVIS_SELECTED ) + { + // Get the currently selected item + LVITEM item; + char temp[256]; + item.mask = LVIF_IMAGE|LVIF_TEXT; + item.iSubItem = 0; + item.pszText = temp; + item.cchTextMax = sizeof(temp)-1; + item.iItem = nmlv->iItem; + ListView_GetItem ( dlg->mWndFileList, &item ); + + if ( item.iImage == 2 ) + { + SetWindowText ( GetDlgItem ( wnd, IDC_TOOLS_FILENAME ), temp ); + } + } + break; + } + + case NM_DBLCLK: + dlg->HandleCommandOK ( ); + break; + } + break; + } + break; + } + + case WM_COMMAND: + switch ( LOWORD ( wparam ) ) + { + case IDOK: + { + dlg->HandleCommandOK ( ); + break; + } + + case IDCANCEL: + EndDialog ( wnd, 0 ); + break; + + case IDC_TOOLS_BACK: + { + int sel = SendMessage ( GetDlgItem ( wnd, IDC_TOOLS_LOOKIN ), CB_GETCURSEL, 0, 0 ); + if ( sel > 0 ) + { + sel--; + SendMessage ( GetDlgItem ( wnd, IDC_TOOLS_LOOKIN ), CB_SETCURSEL, sel, 0 ); + dlg->HandleLookInChange ( ); + } + + break; + } + + case IDC_TOOLS_LOOKIN: + if ( HIWORD ( wparam ) == CBN_SELCHANGE ) + { + dlg->HandleLookInChange ( ); + } + break; + } + break; + } + + return FALSE; +} diff --git a/tools/common/OpenFileDialog.h b/tools/common/OpenFileDialog.h new file mode 100644 index 000000000..930b7bcdb --- /dev/null +++ b/tools/common/OpenFileDialog.h @@ -0,0 +1,108 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef OPENFILEDIALOG_H_ +#define OPENFILEDIALOG_H_ + +#define OFD_MUSTEXIST 0x00000001 + +class rvOpenFileDialog +{ +public: + + rvOpenFileDialog ( void ); + ~rvOpenFileDialog ( void ); + + bool DoModal ( HWND parent ); + const char* GetFilename ( void ); + + void SetFilter ( const char* filter ); + void SetTitle ( const char* title ); + void SetOKTitle ( const char* title ); + void SetInitialPath ( const char* path ); + void SetFlags ( int flags ); + + const char* GetInitialPath ( void ); + +protected: + + void UpdateFileList ( void ); + void UpdateLookIn ( void ); + + HWND mWnd; + HWND mWndFileList; + HWND mWndLookin; + + HINSTANCE mInstance; + + HIMAGELIST mImageList; + HBITMAP mBackBitmap; + + static char mLookin[ MAX_OSPATH ]; + idStr mFilename; + idStr mTitle; + idStr mOKTitle; + idStrList mFilters; + + int mFlags; + +private: + + void HandleCommandOK ( void ); + void HandleLookInChange ( void ); + void HandleInitDialog ( void ); + + static INT_PTR CALLBACK DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); +}; + +ID_INLINE const char* rvOpenFileDialog::GetFilename ( void ) +{ + return mFilename.c_str ( ); +} + +ID_INLINE void rvOpenFileDialog::SetTitle ( const char* title ) +{ + mTitle = title; +} + +ID_INLINE void rvOpenFileDialog::SetOKTitle ( const char* title ) +{ + mOKTitle = title; +} + +ID_INLINE void rvOpenFileDialog::SetInitialPath ( const char* path ) +{ + if ( !idStr::Cmpn( mLookin, path, strlen( path ) ) ) + { + return; + } + + idStr::Copynz( mLookin, path, sizeof( mLookin ) ); +} + +ID_INLINE void rvOpenFileDialog::SetFlags ( int flags ) +{ + mFlags = flags; +} + +ID_INLINE const char* rvOpenFileDialog::GetInitialPath ( void ) +{ + return mLookin; +} + +#endif // OPENFILEDIALOG_H_ diff --git a/tools/common/PropTree/PropTree.cpp b/tools/common/PropTree/PropTree.cpp new file mode 100644 index 000000000..ca9e737b0 --- /dev/null +++ b/tools/common/PropTree/PropTree.cpp @@ -0,0 +1,923 @@ +// PropTree.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column +#define PROPTREEITEM_COLRNG 5 // width of splitter + +//static AFX_EXTENSION_MODULE PropTreeDLL = {NULL, NULL}; +static const CString strOfficeFontName = _T("Tahoma"); +static const CString strDefaultFontName = _T("MS Sans Serif"); + +HINSTANCE ghInst; + +/*extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + TRACE0("PROPTREE.DLL Initializing!\n"); + + if (!AfxInitExtensionModule(PropTreeDLL, hInstance)) + return 0; + + new CDynLinkLibrary(PropTreeDLL); + + ghInst = hInstance; + } + else if (dwReason == DLL_PROCESS_DETACH) + { + TRACE0("PROPTREE.DLL Terminating!\n"); + AfxTermExtensionModule(PropTreeDLL); + } + + return 1; +}*/ + +void InitPropTree(HINSTANCE hInstance) { + ghInst = hInstance; +} + +static int CALLBACK FontFamilyProcFonts(const LOGFONT FAR* lplf, const TEXTMETRIC FAR*, ULONG, LPARAM) +{ + ASSERT(lplf != NULL); + CString strFont = lplf->lfFaceName; + return strFont.CollateNoCase (strOfficeFontName) == 0 ? 0 : 1; +} + +///////////////////////////////////////////////////////////////////////////// +// CPropTree + +UINT CPropTree::s_nInstanceCount; +CFont* CPropTree::s_pNormalFont; +CFont* CPropTree::s_pBoldFont; +CPropTreeItem* CPropTree::s_pFound; + +CPropTree::CPropTree() : + m_bShowInfo(TRUE), + m_nInfoHeight(50), + m_pVisbleList(NULL), + m_Origin(100,0), + m_nLastUID(1), + m_pFocus(NULL), + m_bDisableInput(FALSE) +{ + m_Root.Expand(); + + // init global resources only once + if (!s_nInstanceCount) + InitGlobalResources(); + s_nInstanceCount++; +} + + +CPropTree::~CPropTree() +{ + DeleteAllItems(); + + s_nInstanceCount--; + + // free global resource when ALL CPropTrees are destroyed + if (!s_nInstanceCount) + FreeGlobalResources(); +} + + +BEGIN_MESSAGE_MAP(CPropTree, CWnd) + //{{AFX_MSG_MAP(CPropTree) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_ENABLE() + ON_WM_SYSCOLORCHANGE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CPropTree message handlers + +const POINT& CPropTree::GetOrigin() +{ + return m_Origin; +} + + +BOOL CPropTree::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) +{ + CWnd* pWnd = this; + + LPCTSTR pszCreateClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, ::LoadCursor(NULL, IDC_ARROW)); + + return pWnd->Create(pszCreateClass, _T(""), dwStyle, rect, pParentWnd, nID); +} + + +int CPropTree::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + DWORD dwStyle; + CRect rc; + + GetClientRect(rc); + + // create CPropTreeList + // + + dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL; + + if (!m_List.Create(dwStyle, rc, this, 100)) + { + TRACE0("Failed to create CPropTreeList\n"); + return -1; + } + + m_List.SetPropOwner(this); + + // create CPropTreeInfo + // + + dwStyle &= ~WS_VSCROLL; + + if (!m_Info.Create(_T(""), dwStyle, rc, this)) + { + TRACE0("Failed to create CPropTreeInfo\n"); + return -1; + } + + m_Info.SetPropOwner(this); + + return 0; +} + + +CWnd* CPropTree::GetCtrlParent() +{ + return &m_List; +} + + +void CPropTree::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + ResizeChildWindows(cx, cy); +} + + +void CPropTree::ResizeChildWindows(int cx, int cy) +{ + if (m_bShowInfo) + { + if (IsWindow(m_List.m_hWnd)) + m_List.MoveWindow(0, 0, cx, cy - m_nInfoHeight); + + if (IsWindow(m_Info.m_hWnd)) + m_Info.MoveWindow(0, cy - m_nInfoHeight, cx, m_nInfoHeight); + } + else + { + if (IsWindow(m_List.m_hWnd)) + m_List.MoveWindow(0, 0, cx, cy); + } +} + + +void CPropTree::InitGlobalResources() +{ + NONCLIENTMETRICS info; + info.cbSize = sizeof(info); + + ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + + LOGFONT lf; + memset(&lf, 0, sizeof (LOGFONT)); + + CWindowDC dc(NULL); + lf.lfCharSet = (BYTE)GetTextCharsetInfo(dc.GetSafeHdc(), NULL, 0); + + lf.lfHeight = info.lfMenuFont.lfHeight; + lf.lfWeight = info.lfMenuFont.lfWeight; + lf.lfItalic = info.lfMenuFont.lfItalic; + + // check if we should use system font + _tcscpy(lf.lfFaceName, info.lfMenuFont.lfFaceName); + + BOOL fUseSystemFont = (info.lfMenuFont.lfCharSet > SYMBOL_CHARSET); + if (!fUseSystemFont) + { + // check for "Tahoma" font existance: + if (::EnumFontFamilies(dc.GetSafeHdc(), NULL, FontFamilyProcFonts, 0)==0) + { + // Found! Use MS Office font! + _tcscpy(lf.lfFaceName, strOfficeFontName); + } + else + { + // Not found. Use default font: + _tcscpy(lf.lfFaceName, strDefaultFontName); + } + } + + s_pNormalFont = new CFont; + s_pNormalFont->CreateFontIndirect(&lf); + + lf.lfWeight = FW_BOLD; + s_pBoldFont = new CFont; + s_pBoldFont->CreateFontIndirect(&lf); +} + + +void CPropTree::FreeGlobalResources() +{ + if (s_pNormalFont) + { + delete s_pNormalFont; + s_pNormalFont = NULL; + } + + if (s_pBoldFont) + { + delete s_pBoldFont; + s_pBoldFont = NULL; + } +} + + +CFont* CPropTree::GetNormalFont() +{ + return s_pNormalFont; +} + + +CFont* CPropTree::GetBoldFont() +{ + return s_pBoldFont; +} + + +CPropTreeItem* CPropTree::GetFocusedItem() +{ + return m_pFocus; +} + + +CPropTreeItem* CPropTree::GetRootItem() +{ + return &m_Root; +} + + +void CPropTree::ClearVisibleList() +{ + m_pVisbleList = NULL; +} + + +CPropTreeItem* CPropTree::GetVisibleList() +{ + return m_pVisbleList; +} + + +void CPropTree::AddToVisibleList(CPropTreeItem* pItem) +{ + if (!pItem) + return; + + // check for an empty visible list + if (!m_pVisbleList) + m_pVisbleList = pItem; + else + { + // Add the new item to the end of the list + CPropTreeItem* pNext; + + pNext = m_pVisbleList; + while (pNext->GetNextVisible()) + pNext = pNext->GetNextVisible(); + + pNext->SetNextVisible(pItem); + } + + pItem->SetNextVisible(NULL); +} + + +BOOL CPropTree::EnumItems(CPropTreeItem* pItem, ENUMPROPITEMPROC proc, LPARAM lParam) +{ + if (!pItem || !proc) + return FALSE; + + CPropTreeItem* pNext; + + // don't count the root item in any enumerations + if (pItem!=&m_Root && !proc(this, pItem, lParam)) + return FALSE; + + // recurse thru all child items + pNext = pItem->GetChild(); + + while (pNext) + { + if (!EnumItems(pNext, proc, lParam)) + return FALSE; + + pNext = pNext->GetSibling(); + } + + return TRUE; +} + + +void CPropTree::SetOriginOffset(LONG nOffset) +{ + m_Origin.y = nOffset; +} + + +void CPropTree::UpdatedItems() +{ + if (!IsWindow(m_hWnd)) + return; + + Invalidate(); + + m_List.UpdateResize(); + m_List.Invalidate(); +} + + +void CPropTree::DeleteAllItems() +{ + Delete(NULL); + UpdatedItems(); + m_nLastUID = 1; // reset uid counter +} + + +void CPropTree::DeleteItem(CPropTreeItem* pItem) +{ + Delete(pItem); + UpdatedItems(); +} + + +LONG CPropTree::GetColumn() +{ + return m_Origin.x; +} + + +void CPropTree::SetColumn(LONG nColumn) +{ + CRect rc; + + GetClientRect(rc); + + if (rc.IsRectEmpty()) + nColumn = __max(PROPTREEITEM_EXPANDCOLUMN, nColumn); + else + nColumn = __min(__max(PROPTREEITEM_EXPANDCOLUMN, nColumn), rc.Width() - PROPTREEITEM_EXPANDCOLUMN); + + m_Origin.x = nColumn; + + Invalidate(); +} + + +void CPropTree::Delete(CPropTreeItem* pItem) +{ + if (pItem && pItem!=&m_Root && SendNotify(PTN_DELETEITEM, pItem)) + return; + + // passing in a NULL item is the same as calling DeleteAllItems + if (!pItem) + pItem = &m_Root; + + // Clear the visible list before anything gets deleted + ClearVisibleList(); + + // delete children + + CPropTreeItem* pIter; + CPropTreeItem* pNext; + + pIter = pItem->GetChild(); + while (pIter) + { + pNext = pIter->GetSibling(); + DeleteItem(pIter); + pIter = pNext; + } + + // unlink from tree + if (pItem->GetParent()) + { + if (pItem->GetParent()->GetChild()==pItem) + pItem->GetParent()->SetChild(pItem->GetSibling()); + else + { + pIter = pItem->GetParent()->GetChild(); + while (pIter->GetSibling() && pIter->GetSibling()!=pItem) + pIter = pIter->GetSibling(); + + if (pIter->GetSibling()) + pIter->SetSibling(pItem->GetSibling()); + } + } + + if (pItem!=&m_Root) + { + if (pItem==GetFocusedItem()) + SetFocusedItem(NULL); + delete pItem; + } +} + + +void CPropTree::SetFocusedItem(CPropTreeItem* pItem) +{ + m_pFocus = pItem; + EnsureVisible(m_pFocus); + + if (!IsWindow(m_hWnd)) + return; + + Invalidate(); +} + + +void CPropTree::ShowInfoText(BOOL bShow) +{ + m_bShowInfo = bShow; + + CRect rc; + + GetClientRect(rc); + ResizeChildWindows(rc.Width(), rc.Height()); +} + + +BOOL CPropTree::IsItemVisible(CPropTreeItem* pItem) +{ + if (!pItem) + return FALSE; + + for (CPropTreeItem* pNext = m_pVisbleList; pNext; pNext = pNext->GetNextVisible()) + { + if (pNext==pItem) + return TRUE; + } + + return FALSE; +} + + +void CPropTree::EnsureVisible(CPropTreeItem* pItem) +{ + if (!pItem) + return; + + // item is not scroll visible (expand all parents) + if (!IsItemVisible(pItem)) + { + CPropTreeItem* pParent; + + pParent = pItem->GetParent(); + while (pParent) + { + pParent->Expand(); + pParent = pParent->GetParent(); + } + + UpdatedItems(); + UpdateWindow(); + } + + ASSERT(IsItemVisible(pItem)); + + CRect rc; + + m_List.GetClientRect(rc); + rc.OffsetRect(0, m_Origin.y); + rc.bottom -= pItem->GetHeight(); + + CPoint pt; + + pt = pItem->GetLocation(); + + if (!rc.PtInRect(pt)) + { + LONG oy; + + if (pt.y < rc.top) + oy = pt.y; + else + oy = pt.y - rc.Height() + pItem->GetHeight(); + + m_List.OnVScroll(SB_THUMBTRACK, oy, NULL); + } +} + + +CPropTreeItem* CPropTree::InsertItem(CPropTreeItem* pItem, CPropTreeItem* pParent) +{ + if (!pItem) + return NULL; + + if (!pParent) + pParent = &m_Root; + + if (!pParent->GetChild()) + pParent->SetChild(pItem); + else + { + // add to end of the sibling list + CPropTreeItem* pNext; + + pNext = pParent->GetChild(); + while (pNext->GetSibling()) + pNext = pNext->GetSibling(); + + pNext->SetSibling(pItem); + } + + pItem->SetParent(pParent); + pItem->SetPropOwner(this); + + // auto generate a default ID + pItem->SetCtrlID(m_nLastUID++); + + SendNotify(PTN_INSERTITEM, pItem); + + UpdatedItems(); + + return pItem; +} + + + +LONG CPropTree::HitTest(const POINT& pt) +{ + POINT p = pt; + + CPropTreeItem* pItem; + + // convert screen to tree coordinates + p.y += m_Origin.y; + + if ((pItem = FindItem(pt))!=NULL) + { + if (!pItem->IsRootLevel() && pt.x >= m_Origin.x - PROPTREEITEM_COLRNG && pt.x <= m_Origin.x + PROPTREEITEM_COLRNG) + return HTCOLUMN; + + if (pItem->HitButton(p)) { + return HTBUTTON; + } + + if (pt.x > m_Origin.x + PROPTREEITEM_COLRNG) + return HTATTRIBUTE; + + if (pItem->HitExpand(p)) + return HTEXPAND; + + if (pItem->HitCheckBox(p)) + return HTCHECKBOX; + + return HTLABEL; + } + + return HTCLIENT; +} + + +CPropTreeItem* CPropTree::FindItem(const POINT& pt) +{ + CPropTreeItem* pItem; + + CPoint p = pt; + + // convert screen to tree coordinates + p.y += m_Origin.y; + + // search the visible list for the item + for (pItem = m_pVisbleList; pItem; pItem = pItem->GetNextVisible()) + { + CPoint ipt = pItem->GetLocation(); + if (p.y>=ipt.y && p.yGetHeight()) + return pItem; + } + + return NULL; +} + + +CPropTreeItem* CPropTree::FindItem(UINT nCtrlID) +{ + s_pFound = NULL; + + EnumItems(&m_Root, EnumFindItem, nCtrlID); + + return s_pFound; +} + + +BOOL CALLBACK CPropTree::EnumFindItem(CPropTree*, CPropTreeItem* pItem, LPARAM lParam) +{ + ASSERT(pItem!=NULL); + + if (pItem->GetCtrlID()==(UINT)lParam) + { + s_pFound = pItem; + return FALSE; + } + + return TRUE; +} + + +BOOL CPropTree::IsDisableInput() +{ + return m_bDisableInput; +} + + +void CPropTree::DisableInput(BOOL bDisable) +{ + m_bDisableInput = bDisable; + + CWnd* pWnd; + + if ((pWnd = GetParent())!=NULL) + pWnd->EnableWindow(!bDisable); +} + + +void CPropTree::SelectItems(CPropTreeItem* pItem, BOOL bSelect) +{ + if (!pItem) + pItem = &m_Root; + + EnumItems(pItem, EnumSelectAll, (LPARAM)bSelect); +} + + +CPropTreeItem* CPropTree::FocusFirst() +{ + CPropTreeItem *pold; + + pold = m_pFocus; + + SetFocusedItem(m_pVisbleList); + + if (m_pFocus) + { + SelectItems(NULL, FALSE); + m_pFocus->Select(); + } + + if (pold!=m_pFocus) + SendNotify(PTN_SELCHANGE, m_pFocus); + + return m_pFocus; +} + + +CPropTreeItem* CPropTree::FocusLast() +{ + CPropTreeItem* pNext; + CPropTreeItem* pChange; + + pChange = m_pFocus; + + pNext = m_pVisbleList; + + if (pNext) + { + while (pNext->GetNextVisible()) + pNext = pNext->GetNextVisible(); + + SetFocusedItem(pNext); + + if (m_pFocus) + { + SelectItems(NULL, FALSE); + m_pFocus->Select(); + } + } + + if (pChange!=m_pFocus) + SendNotify(PTN_SELCHANGE, m_pFocus); + + return pNext; +} + + +CPropTreeItem* CPropTree::FocusPrev() +{ + CPropTreeItem* pNext; + CPropTreeItem* pChange; + + pChange = m_pFocus; + + if (m_pFocus==NULL) + { + // get the last visible item + pNext = m_pVisbleList; + while (pNext && pNext->GetNextVisible()) + pNext = pNext->GetNextVisible(); + } + else + { + pNext = m_pVisbleList; + while (pNext && pNext->GetNextVisible()!=m_pFocus) + pNext = pNext->GetNextVisible(); + } + + if (pNext) + SetFocusedItem(pNext); + + if (m_pFocus) + { + SelectItems(NULL, FALSE); + m_pFocus->Select(); + } + + if (pChange!=m_pFocus) + SendNotify(PTN_SELCHANGE, m_pFocus); + + return pNext; +} + + +CPropTreeItem* CPropTree::FocusNext() +{ + CPropTreeItem* pNext; + CPropTreeItem* pChange; + + pChange = m_pFocus; + + if (m_pFocus==NULL) + pNext = m_pVisbleList; + else + if (m_pFocus->GetNextVisible()) + pNext = m_pFocus->GetNextVisible(); + else + pNext = NULL; + + if (pNext) + SetFocusedItem(pNext); + + if (m_pFocus) + { + SelectItems(NULL, FALSE); + m_pFocus->Select(); + } + + if (pChange!=m_pFocus) + SendNotify(PTN_SELCHANGE, m_pFocus); + + return pNext; +} + + +void CPropTree::UpdateMoveAllItems() +{ + EnumItems(&m_Root, EnumMoveAll); +} + + +void CPropTree::RefreshItems(CPropTreeItem* pItem) +{ + if (!pItem) + pItem = &m_Root; + + EnumItems(pItem, EnumRefreshAll); + + UpdatedItems(); +} + + +BOOL CALLBACK CPropTree::EnumSelectAll(CPropTree*, CPropTreeItem* pItem, LPARAM lParam) +{ + if (!pItem) + return FALSE; + + pItem->Select((BOOL)lParam); + + return TRUE; +} + + +BOOL CALLBACK CPropTree::EnumRefreshAll(CPropTree*, CPropTreeItem* pItem, LPARAM) +{ + if (!pItem) + return FALSE; + + pItem->OnRefresh(); + + return TRUE; +} + + +BOOL CALLBACK CPropTree::EnumMoveAll(CPropTree*, CPropTreeItem* pItem, LPARAM) +{ + if (!pItem) + return FALSE; + + pItem->OnMove(); + + return TRUE; +} + + +LRESULT CPropTree::SendNotify(UINT nNotifyCode, CPropTreeItem* pItem) +{ + if (!IsWindow(m_hWnd)) + return 0L; + + if (!(GetStyle() & PTS_NOTIFY)) + return 0L; + + NMPROPTREE nmmp; + LPNMHDR lpnm; + + lpnm = NULL; + + switch (nNotifyCode) + { + case PTN_INSERTITEM: + case PTN_DELETEITEM: + case PTN_DELETEALLITEMS: + case PTN_ITEMCHANGED: + case PTN_ITEMBUTTONCLICK: + case PTN_SELCHANGE: + case PTN_ITEMEXPANDING: + case PTN_COLUMNCLICK: + case PTN_PROPCLICK: + case PTN_CHECKCLICK: + lpnm = (LPNMHDR)&nmmp; + nmmp.pItem = pItem; + break; + } + + if (lpnm) + { + UINT id = (UINT)::GetMenu(m_hWnd); + lpnm->code = nNotifyCode; + lpnm->hwndFrom = m_hWnd; + lpnm->idFrom = id; + + return GetParent()->SendMessage(WM_NOTIFY, (WPARAM)id, (LPARAM)lpnm); + } + + return 0L; +} + + +void CPropTree::OnEnable(BOOL bEnable) +{ + CWnd::OnEnable(bEnable); + Invalidate(); +} + + +void CPropTree::OnSysColorChange() +{ + CWnd::OnSysColorChange(); + + Invalidate(); +} + + +BOOL CPropTree::IsSingleSelection() +{ + // right now only support single selection + return TRUE; +} \ No newline at end of file diff --git a/tools/common/PropTree/PropTree.h b/tools/common/PropTree/PropTree.h new file mode 100644 index 000000000..64977d7e9 --- /dev/null +++ b/tools/common/PropTree/PropTree.h @@ -0,0 +1,290 @@ +// PropTree.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#if !defined(AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_) +#define AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +/*#ifdef _PROPTREE_EXPORT +#define PROPTREE_API __declspec(dllexport) +#else +#define PROPTREE_API __declspec(dllimport) +#endif + +#ifndef _PROPTREE_DLL + #ifdef _UNICODE + #ifdef _DEBUG + #pragma comment(lib, "PropTreeDU") + #pragma message("Automatically linking with PropTreeDU.dll (Debug Unicode)") + #else + #pragma comment(lib, "PropTreeU") + #pragma message("Automatically linking with PropTreeU.dll (Release Unicode)") + #endif + #else + #ifdef _DEBUG + #pragma comment(lib, "PropTreeD") + #pragma message("Automatically linking with PropTreeD.dll (Debug)") + #else + #pragma comment(lib, "PropTree") + #pragma message("Automatically linking with PropTree.dll (Release)") + #endif + #endif // _UNICODE +#endif // _PROPTREE_DLL +*/ + +#define PROPTREE_API + +#include "PropTreeList.h" +#include "PropTreeInfo.h" + +#include "PropTreeItem.h" +#include "PropTreeItemStatic.h" +#include "PropTreeItemEdit.h" +#include "PropTreeItemCombo.h" +#include "PropTreeItemColor.h" +#include "PropTreeItemCheck.h" +#include "PropTreeItemButton.h" +#include "PropTreeItemEditButton.h" +#include "PropTreeItemFileEdit.h" + +class CPropTree; + +typedef BOOL (CALLBACK* ENUMPROPITEMPROC)(CPropTree*, CPropTreeItem*, LPARAM); + +void InitPropTree(HINSTANCE hInstance); + +// CPropTree window styles +#define PTS_NOTIFY 0x00000001 + +// CPropTree HitTest return codes +#define HTPROPFIRST 50 + +#define HTLABEL (HTPROPFIRST + 0) +#define HTCOLUMN (HTPROPFIRST + 1) +#define HTEXPAND (HTPROPFIRST + 2) +#define HTATTRIBUTE (HTPROPFIRST + 3) +#define HTCHECKBOX (HTPROPFIRST + 4) +#define HTBUTTON (HTPROPFIRST + 5) + +// CPropTree WM_NOTIFY notification structure +typedef struct _NMPROPTREE +{ + NMHDR hdr; + CPropTreeItem* pItem; +} NMPROPTREE, *PNMPROPTREE, FAR *LPNMPROPTREE; + +// CPropTree specific Notification Codes +#define PTN_FIRST (0U-1100U) + +#define PTN_INSERTITEM (PTN_FIRST-1) +#define PTN_DELETEITEM (PTN_FIRST-2) +#define PTN_DELETEALLITEMS (PTN_FIRST-3) +#define PTN_ITEMCHANGED (PTN_FIRST-5) +#define PTN_ITEMBUTTONCLICK (PTN_FIRST-6) +#define PTN_SELCHANGE (PTN_FIRST-7) +#define PTN_ITEMEXPANDING (PTN_FIRST-8) +#define PTN_COLUMNCLICK (PTN_FIRST-9) +#define PTN_PROPCLICK (PTN_FIRST-10) +#define PTN_CHECKCLICK (PTN_FIRST-12) + +///////////////////////////////////////////////////////////////////////////// +// CPropTree window + +class PROPTREE_API CPropTree : public CWnd +{ +// Construction +public: + CPropTree(); + virtual ~CPropTree(); + + BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID); + +// Attributes/Operations +public: + static CFont* GetNormalFont(); + static CFont* GetBoldFont(); + + // Returns the root item of the tree + CPropTreeItem* GetRootItem(); + + // Returns the focused item or NULL for none + CPropTreeItem* GetFocusedItem(); + + // Enumerates an item and all its child items + BOOL EnumItems(CPropTreeItem* pItem, ENUMPROPITEMPROC proc, LPARAM lParam = 0L); + + // Insert a created CPropTreeItem into the control + CPropTreeItem* InsertItem(CPropTreeItem* pItem, CPropTreeItem* pParent = NULL); + + // Delete an item and ALL its children + void DeleteItem(CPropTreeItem* pItem); + + // Delete all items from the tree + void DeleteAllItems(); + + // Return the splitter position + LONG GetColumn(); + + // Set the splitter position + void SetColumn(LONG nColumn); + + // Sets the focused item + void SetFocusedItem(CPropTreeItem* pItem); + + // Show or hide the info text + void ShowInfoText(BOOL bShow = TRUE); + + // Returns TRUE if the item is visible (its parent is expanded) + BOOL IsItemVisible(CPropTreeItem* pItem); + + // Ensures that an item is visible + void EnsureVisible(CPropTreeItem* pItem); + + // do a hit test on the control (returns a HTxxxx code) + LONG HitTest(const POINT& pt); + + // find an item by a location + CPropTreeItem* FindItem(const POINT& pt); + + // find an item by item id + CPropTreeItem* FindItem(UINT nCtrlID); + +protected: + // Actual tree control + CPropTreeList m_List; + + // Descriptive control + CPropTreeInfo m_Info; + + // TRUE to show info control + BOOL m_bShowInfo; + + // Height of the info control + LONG m_nInfoHeight; + + // Root level tree item + CPropTreeItem m_Root; + + // Linked list of visible items + CPropTreeItem* m_pVisbleList; + + // Pointer to the focused item (selected) + CPropTreeItem* m_pFocus; + + // PropTree scroll position. x = splitter position, y = vscroll position + CPoint m_Origin; + + // auto generated last created ID + UINT m_nLastUID; + + // Number of CPropTree controls in the current application + static UINT s_nInstanceCount; + + static CFont* s_pNormalFont; + static CFont* s_pBoldFont; + + BOOL m_bDisableInput; + + // Used for enumeration + static CPropTreeItem* s_pFound; + +public: + // + // functions used by CPropTreeItem (you normally dont need to call these directly) + // + + void AddToVisibleList(CPropTreeItem* pItem); + void ClearVisibleList(); + + void SetOriginOffset(LONG nOffset); + void UpdatedItems(); + void UpdateMoveAllItems(); + void RefreshItems(CPropTreeItem* pItem = NULL); + + // enable or disable tree input + void DisableInput(BOOL bDisable = TRUE); + BOOL IsDisableInput(); + + BOOL IsSingleSelection(); + + CPropTreeItem* GetVisibleList(); + CWnd* GetCtrlParent(); + + const POINT& GetOrigin(); + + void SelectItems(CPropTreeItem* pItem, BOOL bSelect = TRUE); + + // Focus on the first visible item + CPropTreeItem *FocusFirst(); + + // Focus on the last visible item + CPropTreeItem *FocusLast(); + + // Focus on the previous item + CPropTreeItem *FocusPrev(); + + // Focus on the next item + CPropTreeItem *FocusNext(); + + LRESULT SendNotify(UINT nNotifyCode, CPropTreeItem* pItem = NULL); + +protected: + // Resize the child windows to fit the exact dimensions the CPropTree control + void ResizeChildWindows(int cx, int cy); + + // Initialize global resources, brushes, fonts, etc. + void InitGlobalResources(); + + // Free global resources, brushes, fonts, etc. + void FreeGlobalResources(); + + // Recursive version of DeleteItem + void Delete(CPropTreeItem* pItem); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTree) + //}}AFX_VIRTUAL + +// Implementation +private: + static BOOL CALLBACK EnumFindItem(CPropTree* pProp, CPropTreeItem* pItem, LPARAM lParam); + static BOOL CALLBACK EnumSelectAll(CPropTree*, CPropTreeItem* pItem, LPARAM lParam); + static BOOL CALLBACK EnumMoveAll(CPropTree*, CPropTreeItem* pItem, LPARAM); + static BOOL CALLBACK EnumRefreshAll(CPropTree*, CPropTreeItem* pItem, LPARAM); + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTree) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnEnable(BOOL bEnable); + afx_msg void OnSysColorChange(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPT_H__386AA426_6FB7_4B4B_9563_C4CC045BB0C9__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeInfo.cpp b/tools/common/PropTree/PropTreeInfo.cpp new file mode 100644 index 000000000..4603a794e --- /dev/null +++ b/tools/common/PropTree/PropTreeInfo.cpp @@ -0,0 +1,110 @@ +// PropTreeInfo.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" +#include "../../../sys/win32/rc/proptree_Resource.h" +#include "PropTreeInfo.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeInfo + +CPropTreeInfo::CPropTreeInfo() : + m_pProp(NULL) +{ +} + +CPropTreeInfo::~CPropTreeInfo() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeInfo, CStatic) + //{{AFX_MSG_MAP(CPropTreeInfo) + ON_WM_PAINT() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeInfo message handlers + +void CPropTreeInfo::SetPropOwner(CPropTree* pProp) +{ + m_pProp = pProp; +} + +void CPropTreeInfo::OnPaint() +{ + CPaintDC dc(this); + CRect rc; + + GetClientRect(rc); + + dc.SelectObject(GetSysColorBrush(COLOR_BTNFACE)); + dc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY); + + dc.DrawEdge(&rc, BDR_SUNKENOUTER, BF_RECT); + rc.DeflateRect(4, 4); + + ASSERT(m_pProp!=NULL); + + CPropTreeItem* pItem = m_pProp->GetFocusedItem(); + + if (!m_pProp->IsWindowEnabled()) + dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT)); + else + dc.SetTextColor(GetSysColor(COLOR_BTNTEXT)); + + dc.SetBkMode(TRANSPARENT); + dc.SelectObject(m_pProp->GetBoldFont()); + + CString txt; + + if (!pItem) + txt.LoadString(IDS_NOITEMSEL); + else + txt = pItem->GetLabelText(); + + CRect ir; + ir = rc; + + // draw label + dc.DrawText(txt, &ir, DT_SINGLELINE|DT_CALCRECT); + dc.DrawText(txt, &ir, DT_SINGLELINE); + + ir.top = ir.bottom; + ir.bottom = rc.bottom; + ir.right = rc.right; + + if (pItem) + txt = pItem->GetInfoText(); + else + txt.LoadString(IDS_SELFORINFO); + + dc.SelectObject(m_pProp->GetNormalFont()); + dc.DrawText(txt, &ir, DT_WORDBREAK); +} diff --git a/tools/common/PropTree/PropTreeInfo.h b/tools/common/PropTree/PropTreeInfo.h new file mode 100644 index 000000000..6c4a90202 --- /dev/null +++ b/tools/common/PropTree/PropTreeInfo.h @@ -0,0 +1,71 @@ +#if !defined(AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_) +#define AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeInfo.h : header file +// +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +class CPropTree; + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeInfo window + +class PROPTREE_API CPropTreeInfo : public CStatic +{ +// Construction +public: + CPropTreeInfo(); + +// Attributes +public: + // CPropTree class that this class belongs + void SetPropOwner(CPropTree* pProp); + +protected: + CPropTree* m_pProp; + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeInfo) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CPropTreeInfo(); + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeInfo) + afx_msg void OnPaint(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPTREEINFO_H__22BD9C18_A68C_4BB8_B7FC_C4A7DA0E1EBF__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeItem.cpp b/tools/common/PropTree/PropTreeItem.cpp new file mode 100644 index 000000000..17546a5b9 --- /dev/null +++ b/tools/common/PropTree/PropTreeItem.cpp @@ -0,0 +1,590 @@ +// PropTreeItem.cpp +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" + +#include "PropTreeItem.h" + +#define PROPTREEITEM_DEFHEIGHT 21 // default heigt of an item +#define PROPTREEITEM_SPACE 5 // default horz spacing +#define PROPTREEITEM_EXPANDBOX 9 // size of the expand box +#define PROPTREEITEM_CHECKBOX 14 // size of the check box +#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column +#define PNINDENT 16 // child level indent + +#define PROPTREEITEM_EXPANDBOXHALF (PROPTREEITEM_EXPANDBOX/2) + + +///////////////////////////////////////////////////////////////////////////// +// drawing helper functions +// + +// draw a dotted horizontal line +static void _DotHLine(HDC hdc, LONG x, LONG y, LONG w) +{ + for (; w>0; w-=2, x+=2) + SetPixel(hdc, x, y, GetSysColor(COLOR_BTNSHADOW)); +} + + +// draw the plus/minus button +static void _DrawExpand(HDC hdc, LONG x, LONG y, BOOL bExpand, BOOL bFill) +{ + HPEN hPen; + HPEN oPen; + HBRUSH oBrush; + + hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); + oPen = (HPEN)SelectObject(hdc, hPen); + oBrush = (HBRUSH)SelectObject(hdc, GetStockObject(bFill ? WHITE_BRUSH : NULL_BRUSH)); + + Rectangle(hdc, x, y, x + PROPTREEITEM_EXPANDBOX, y + PROPTREEITEM_EXPANDBOX); + SelectObject(hdc, GetStockObject(BLACK_PEN)); + + if (!bExpand) + { + MoveToEx(hdc, x + PROPTREEITEM_EXPANDBOXHALF, y + 2, NULL); + LineTo(hdc, x + PROPTREEITEM_EXPANDBOXHALF, y + PROPTREEITEM_EXPANDBOX - 2); + } + + MoveToEx(hdc, x + 2, y + PROPTREEITEM_EXPANDBOXHALF, NULL); + LineTo(hdc, x + PROPTREEITEM_EXPANDBOX - 2, y + PROPTREEITEM_EXPANDBOXHALF); + + SelectObject(hdc, oPen); + SelectObject(hdc, oBrush); + DeleteObject(hPen); +} + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItem +// + +CPropTreeItem::CPropTreeItem() : + m_pProp(NULL), + m_sLabel(_T("")), + m_sInfo(_T("")), + m_loc(0,0), + m_rc(0,0,0,0), + m_lParam(0), + m_nCtrlID(0), + m_dwState(0), + m_bActivated(FALSE), + m_bCommitOnce(FALSE), + m_rcExpand(0,0,0,0), + m_rcCheckbox(0,0,0,0), + m_rcButton(0,0,0,0), + m_pParent(NULL), + m_pSibling(NULL), + m_pChild(NULL), + m_pVis(NULL) +{ +} + + +CPropTreeItem::~CPropTreeItem() +{ +} + + +BOOL CPropTreeItem::IsExpanded() +{ + return (m_dwState & TreeItemExpanded) ? TRUE : FALSE; +} + + +BOOL CPropTreeItem::IsSelected() +{ + return (m_dwState & TreeItemSelected) ? TRUE : FALSE; +} + + +BOOL CPropTreeItem::IsChecked() +{ + return (m_dwState & TreeItemChecked) ? TRUE : FALSE; +} + + +BOOL CPropTreeItem::IsReadOnly() +{ + return (m_dwState & TreeItemReadOnly) ? TRUE : FALSE; +} + + +BOOL CPropTreeItem::IsActivated() +{ + return (m_dwState & TreeItemActivated) ? TRUE : FALSE; +} + + +void CPropTreeItem::Select(BOOL bSelect) +{ + if (bSelect) + m_dwState |= TreeItemSelected; + else + m_dwState &= ~TreeItemSelected; +} + + +void CPropTreeItem::Expand(BOOL bExpand) +{ + if (bExpand) + m_dwState |= TreeItemExpanded; + else + m_dwState &= ~TreeItemExpanded; +} + + +void CPropTreeItem::Check(BOOL bCheck) +{ + if (bCheck) + m_dwState |= TreeItemChecked; + else + m_dwState &= ~TreeItemChecked; +} + + +void CPropTreeItem::ReadOnly(BOOL bReadOnly) +{ + if (bReadOnly) + m_dwState |= TreeItemReadOnly; + else + m_dwState &= ~TreeItemReadOnly; +} + + +BOOL CPropTreeItem::IsCheckBox() +{ + return (m_dwState & TreeItemCheckbox) ? TRUE : FALSE; +} + + +void CPropTreeItem::HasCheckBox(BOOL bCheckbox) +{ + if (bCheckbox) + m_dwState |= TreeItemCheckbox; + else + m_dwState &= ~TreeItemCheckbox; +} + + +BOOL CPropTreeItem::HitExpand(const POINT& pt) +{ + return m_rcExpand.PtInRect(pt); +} + + +BOOL CPropTreeItem::HitCheckBox(const POINT& pt) +{ + return m_rcCheckbox.PtInRect(pt); +} + + +BOOL CPropTreeItem::IsRootLevel() +{ + ASSERT(m_pProp!=NULL); + return GetParent() == m_pProp->GetRootItem(); +} + + +LONG CPropTreeItem::GetTotalHeight() +{ + CPropTreeItem* pItem; + LONG nHeight; + + nHeight = GetHeight(); + + if (IsExpanded()) + { + for (pItem = GetChild(); pItem; pItem = pItem->GetSibling()) + nHeight += pItem->GetTotalHeight(); + } + + return nHeight; +} + + +void CPropTreeItem::SetLabelText(LPCTSTR sLabel) +{ + m_sLabel = sLabel; +} + + +LPCTSTR CPropTreeItem::GetLabelText() +{ + return m_sLabel; +} + + +void CPropTreeItem::SetInfoText(LPCTSTR sInfo) +{ + m_sInfo = sInfo; +} + + +LPCTSTR CPropTreeItem::GetInfoText() +{ + return m_sInfo; +} + + +void CPropTreeItem::SetCtrlID(UINT nCtrlID) +{ + m_nCtrlID = nCtrlID; +} + + +UINT CPropTreeItem::GetCtrlID() +{ + return m_nCtrlID; +} + + +LONG CPropTreeItem::GetHeight() +{ + return PROPTREEITEM_DEFHEIGHT; +} + + +LPARAM CPropTreeItem::GetItemValue() +{ + // no items are assocatied with this type + return 0L; +} + + +void CPropTreeItem::SetItemValue(LPARAM) +{ + // no items are assocatied with this type +} + + +void CPropTreeItem::OnMove() +{ + // no attributes, do nothing +} + + +void CPropTreeItem::OnRefresh() +{ + // no attributes, do nothing +} + + +void CPropTreeItem::OnCommit() +{ + // no attributes, do nothing +} + + +void CPropTreeItem::Activate(int activateType, CPoint point) +{ + m_bActivated = TRUE; + m_bCommitOnce = FALSE; + + OnActivate(activateType, point); +} + + +void CPropTreeItem::CommitChanges() +{ + m_bActivated = FALSE; + + if (m_bCommitOnce) + return; + + m_bCommitOnce = TRUE; + + ASSERT(m_pProp!=NULL); + + OnCommit(); + + m_pProp->SendNotify(PTN_ITEMCHANGED, this); + m_pProp->RefreshItems(this); +} + + +void CPropTreeItem::OnActivate(int activateType, CPoint point) +{ + // no attributes, do nothing +} + + +void CPropTreeItem::SetPropOwner(CPropTree* pProp) +{ + m_pProp = pProp; +} + + +const POINT& CPropTreeItem::GetLocation() +{ + return m_loc; +} + + +CPropTreeItem* CPropTreeItem::GetParent() +{ + return m_pParent; +} + + +CPropTreeItem* CPropTreeItem::GetSibling() +{ + return m_pSibling; +} + + +CPropTreeItem* CPropTreeItem::GetChild() +{ + return m_pChild; +} + + +CPropTreeItem* CPropTreeItem::GetNextVisible() +{ + return m_pVis; +} + + +void CPropTreeItem::SetParent(CPropTreeItem* pParent) +{ + m_pParent = pParent; +} + + +void CPropTreeItem::SetSibling(CPropTreeItem* pSibling) +{ + m_pSibling = pSibling; +} + + +void CPropTreeItem::SetChild(CPropTreeItem* pChild) +{ + m_pChild = pChild; +} + + +void CPropTreeItem::SetNextVisible(CPropTreeItem* pVis) +{ + m_pVis = pVis; +} + + +LONG CPropTreeItem::DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y) +{ + CPoint pt; + LONG nTotal, nCol, ey; + CRect drc, ir; + + ASSERT(m_pProp!=NULL); + + // Add TreeItem the list of visble items + m_pProp->AddToVisibleList(this); + + // store the item's location + m_loc = CPoint(x, y); + + // store the items rectangle position + m_rc.SetRect(m_pProp->GetOrigin().x + PROPTREEITEM_SPACE, m_loc.y, rc.right, m_loc.y + GetHeight()-1); + m_rc.OffsetRect(0, -m_pProp->GetOrigin().y); + + // init temp drawing variables + nTotal = GetHeight(); + ey = (nTotal >> 1) - (PROPTREEITEM_EXPANDBOX >> 1) - 2; + + bool bCheck = false; + + // convert item coordinates to screen coordinates + pt = m_loc; + pt.y -= m_pProp->GetOrigin().y; + nCol = m_pProp->GetOrigin().x; + + if (IsRootLevel()) + drc.SetRect(pt.x + PROPTREEITEM_EXPANDCOLUMN, pt.y, rc.right, pt.y + nTotal); + else + drc.SetRect(pt.x + PROPTREEITEM_EXPANDCOLUMN, pt.y, nCol, pt.y + nTotal); + + // root level items are shaded + if (IsRootLevel()) + { + HGDIOBJ hOld = pDC->SelectObject(GetSysColorBrush(COLOR_BTNFACE)); + pDC->PatBlt(rc.left, drc.top, rc.right - rc.left + 1, drc.Height(), PATCOPY); + pDC->SelectObject(hOld); + } + + // calc/draw expand box position + if (GetChild()) + { + m_rcExpand.left = PROPTREEITEM_EXPANDCOLUMN/2 - PROPTREEITEM_EXPANDBOXHALF; + m_rcExpand.top = m_loc.y + ey; + m_rcExpand.right = m_rcExpand.left + PROPTREEITEM_EXPANDBOX - 1; + m_rcExpand.bottom = m_rcExpand.top + PROPTREEITEM_EXPANDBOX - 1; + + ir = m_rcExpand; + ir.OffsetRect(0, -m_pProp->GetOrigin().y); + _DrawExpand(pDC->m_hDC, ir.left, ir.top, IsExpanded(), !IsRootLevel()); + } + else + m_rcExpand.SetRectEmpty(); + + // calc/draw check box position + if (IsCheckBox()) + { + bCheck = true; + + ir.left = drc.left + PROPTREEITEM_SPACE; + ir.top = m_loc.y + ey; + + ir.right = ir.left + PROPTREEITEM_CHECKBOX; + ir.bottom = ir.top + PROPTREEITEM_CHECKBOX; + + m_rcCheckbox = ir; + } + else + m_rcCheckbox.SetRectEmpty(); + + HRGN hRgn = NULL; + + // create a clipping region for the label + if (!IsRootLevel()) + { + hRgn = CreateRectRgn(drc.left, drc.top, drc.right, drc.bottom); + SelectClipRgn(pDC->m_hDC, hRgn); + } + + // calc label position + ir = drc; + ir.left += PROPTREEITEM_SPACE; + + // offset the label text if item has a check box + if (bCheck) + OffsetRect(&ir, PROPTREEITEM_CHECKBOX + PROPTREEITEM_SPACE * 2, 0); + + // draw label + if (!m_sLabel.IsEmpty()) + { + if (IsRootLevel()) + pDC->SelectObject(CPropTree::GetBoldFont()); + else + pDC->SelectObject(CPropTree::GetNormalFont()); + + pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT)); + pDC->SetBkMode(TRANSPARENT); + pDC->DrawText(m_sLabel, &ir, DT_SINGLELINE|DT_VCENTER|DT_CALCRECT); + + // draw the text highlighted if selected + if (IsSelected()) + { + HGDIOBJ oPen = pDC->SelectObject(GetStockObject(NULL_PEN)); + HGDIOBJ oBrush = pDC->SelectObject(GetSysColorBrush(COLOR_HIGHLIGHT)); + + CRect dr; + dr = drc; + dr.left = PROPTREEITEM_EXPANDCOLUMN; + + pDC->Rectangle(&dr); + + pDC->SelectObject(oPen); + pDC->SelectObject(oBrush); + + pDC->SetTextColor(GetSysColor(COLOR_BTNHIGHLIGHT)); + } + + // check if we need to draw the text as disabled + if (!m_pProp->IsWindowEnabled()) + pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT)); + + pDC->DrawText(m_sLabel, &ir, DT_SINGLELINE|DT_VCENTER); + } + + // draw check box frame + if (IsCheckBox()) + { + ir = m_rcCheckbox; + ir.OffsetRect(0, -m_pProp->GetOrigin().y); + pDC->DrawFrameControl(&ir, DFC_BUTTON, DFCS_BUTTONCHECK | (IsChecked() ? DFCS_CHECKED : 0)); + } + + // remove clip region + if (hRgn) + { + SelectClipRgn(pDC->m_hDC, NULL); + DeleteObject(hRgn); + } + + // draw horzontal sep + _DotHLine(pDC->m_hDC, PROPTREEITEM_EXPANDCOLUMN, pt.y + nTotal - 1, rc.right - PROPTREEITEM_EXPANDCOLUMN + 1); + + // draw separators + if (!IsRootLevel()) + { + // column sep + CPen pn1(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); + CPen* pOld; + + pOld = pDC->SelectObject(&pn1); + pDC->MoveTo(nCol, drc.top); + pDC->LineTo(nCol, drc.bottom); + + CPen pn2(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); + pDC->SelectObject(&pn2); + pDC->MoveTo(nCol + 1, drc.top); + pDC->LineTo(nCol + 1, drc.bottom); + + pDC->SelectObject(pOld); + } + + // draw attribute + if (!IsRootLevel()) + { + // create clip region + hRgn = CreateRectRgn(m_rc.left, m_rc.top, m_rc.right, m_rc.bottom); + SelectClipRgn(pDC->m_hDC, hRgn); + + DrawAttribute(pDC, m_rc); + + SelectClipRgn(pDC->m_hDC, NULL); + DeleteObject(hRgn); + } + + // draw children + if (GetChild() && IsExpanded()) + { + y += nTotal; + + CPropTreeItem* pNext; + + for (pNext = GetChild(); pNext; pNext = pNext->GetSibling()) + { + LONG nHeight = pNext->DrawItem(pDC, rc, x + (IsRootLevel() ? 0 : PNINDENT), y); + nTotal += nHeight; + y += nHeight; + } + } + + return nTotal; +} + + +void CPropTreeItem::DrawAttribute(CDC*, const RECT&) +{ + // no attributes are assocatied with this type +} diff --git a/tools/common/PropTree/PropTreeItem.h b/tools/common/PropTree/PropTreeItem.h new file mode 100644 index 000000000..6eafdd2f1 --- /dev/null +++ b/tools/common/PropTree/PropTreeItem.h @@ -0,0 +1,203 @@ +// PropTreeItem.h +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#ifndef _PROPTREEITEM_H +#define _PROPTREEITEM_H + +class CPropTree; + +class PROPTREE_API CPropTreeItem +{ +// Construction +public: + CPropTreeItem(); + virtual ~CPropTreeItem(); + +// Attributes/Operations +public: + // TreeItem states + BOOL IsExpanded(); + BOOL IsSelected(); + BOOL IsChecked(); + BOOL IsReadOnly(); + BOOL IsActivated(); + + void Select(BOOL bSelect = TRUE); + void Expand(BOOL bExpand = TRUE); + void Check(BOOL bCheck = TRUE); + void ReadOnly(BOOL bReadOnly = TRUE); + + // Returns true if the item has a checkbox + BOOL IsCheckBox(); + + // Pass in true, for the item to have a checkbox + void HasCheckBox(BOOL bCheckbox = TRUE); + + // Returns TRUE if the point is on the expand button + BOOL HitExpand(const POINT& pt); + + // Returns TRUE if the point is on the check box + BOOL HitCheckBox(const POINT& pt); + + // Overrideable - Returns TRUE if the point is on the button + virtual BOOL HitButton(const POINT& pt) { return false;} + + // Returns TRUE if the item is on the root level. Root level items don't have attribute areas + BOOL IsRootLevel(); + + // Returns the total height of the item and all its children + LONG GetTotalHeight(); + + // Set the items label text + void SetLabelText(LPCTSTR sLabel); + + // Return the items label text + LPCTSTR GetLabelText(); + + // Set the items info (description) text + void SetInfoText(LPCTSTR sInfo); + + // Get the items info (description) text + LPCTSTR GetInfoText(); + + // Set the item's ID + void SetCtrlID(UINT nCtrlID); + + // Return the item's ID + UINT GetCtrlID(); + + // Overrideable - draw the item's non attribute area + virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y); + + // call to mark attribute changes + void CommitChanges(); + + // call to activate item attribute + enum { + ACTIVATE_TYPE_KEYBOARD, + ACTIVATE_TYPE_MOUSE + }; + void Activate(int activateType, CPoint point); + + // + // Overrideables + // + + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Return the height of the item + virtual LONG GetHeight(); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + // + // Usually only CPropTree should calls these + // + + void SetPropOwner(CPropTree* pProp); + + // Return the location of the PropItem + const POINT& GetLocation(); + + // TreeItem link pointer access + CPropTreeItem* GetParent(); + CPropTreeItem* GetSibling(); + CPropTreeItem* GetChild(); + CPropTreeItem* GetNextVisible(); + + void SetParent(CPropTreeItem* pParent); + void SetSibling(CPropTreeItem* pSibling); + void SetChild(CPropTreeItem* pChild); + void SetNextVisible(CPropTreeItem* pVis); + +protected: + // CPropTree class that this class belongs + CPropTree* m_pProp; + + // TreeItem label name + CString m_sLabel; + + // Descriptive info text + CString m_sInfo; + + // TreeItem location + CPoint m_loc; + + // TreeItem attribute size + CRect m_rc; + + // user defined LPARAM value + LPARAM m_lParam; + + // ID of control item (should be unique) + UINT m_nCtrlID; + +protected: + enum TreeItemStates + { + TreeItemSelected = 0x00000001, + TreeItemExpanded = 0x00000002, + TreeItemCheckbox = 0x00000004, + TreeItemChecked = 0x00000008, + TreeItemActivated = 0x00000010, + TreeItemReadOnly = 0x00000020, + }; + + // TreeItem state + DWORD m_dwState; + + // TRUE if item is activated + BOOL m_bActivated; + + // TRUE if item has been commited once (activation) + BOOL m_bCommitOnce; + + // Rectangle position of the expand button (if contains one) + CRect m_rcExpand; + + // Rectangle position of the check box (if contains one) + CRect m_rcCheckbox; + + // Rectangle position of the button (if contains one) + CRect m_rcButton; + + // link pointers + CPropTreeItem* m_pParent; + CPropTreeItem* m_pSibling; + CPropTreeItem* m_pChild; + CPropTreeItem* m_pVis; +}; + +#endif // _PROPTREEITEM_H diff --git a/tools/common/PropTree/PropTreeItemButton.cpp b/tools/common/PropTree/PropTreeItemButton.cpp new file mode 100644 index 000000000..fe095c97b --- /dev/null +++ b/tools/common/PropTree/PropTreeItemButton.cpp @@ -0,0 +1,103 @@ +// PropTreeItemButton.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "proptree.h" +#include "PropTreeItemButton.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define BUTTON_SIZE 17 + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemButton + +CPropTreeItemButton::CPropTreeItemButton() { + mouseDown = false; +} + +CPropTreeItemButton::~CPropTreeItemButton() { +} + + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemButton message handlers + +LONG CPropTreeItemButton::DrawItem( CDC* pDC, const RECT& rc, LONG x, LONG y ) +{ + CSize textSize; + CRect textRect; + LONG nTotal = 0; + + nTotal = CPropTreeItem::DrawItem( pDC, rc, x, y ); + + textSize = pDC->GetOutputTextExtent( buttonText ); + + buttonRect.left = m_rc.right - ( textSize.cx + 12 + 4); + buttonRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-BUTTON_SIZE/2; + buttonRect.right = buttonRect.left + textSize.cx + 12; + buttonRect.bottom = buttonRect.top + BUTTON_SIZE; + + UINT buttonStyle; + + if ( (m_dwState & TreeItemChecked) ) { + buttonStyle = DFCS_BUTTONPUSH | DFCS_PUSHED; + } else { + buttonStyle = DFCS_BUTTONPUSH; + } + pDC->DrawFrameControl(&buttonRect, DFC_BUTTON, buttonStyle ); + + textRect = buttonRect; + textRect.left += 4; + textRect.right -= 8; + pDC->DrawText( buttonText, textRect, DT_SINGLELINE|DT_VCENTER ); + + //Adjust hit test rect to acount for window scrolling + hitTestRect = buttonRect; + hitTestRect.OffsetRect(0, m_pProp->GetOrigin().y); + + return nTotal; +} + +void CPropTreeItemButton::DrawAttribute(CDC* pDC, const RECT& rc) { +} + + +LPARAM CPropTreeItemButton::GetItemValue() { + return (LPARAM)0; +} + + +void CPropTreeItemButton::SetItemValue(LPARAM lParam) { +} + + +BOOL CPropTreeItemButton::HitButton( const POINT& pt ) { + return hitTestRect.PtInRect( pt ); +} + +void CPropTreeItemButton::SetButtonText( LPCSTR text ) { + buttonText = text; +} diff --git a/tools/common/PropTree/PropTreeItemButton.h b/tools/common/PropTree/PropTreeItemButton.h new file mode 100644 index 000000000..84922cb27 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemButton.h @@ -0,0 +1,63 @@ +#pragma once + +// PropTreeItemButton.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemButton window + +class PROPTREE_API CPropTreeItemButton : public CPropTreeItem +{ +// Construction +public: + CPropTreeItemButton(); + virtual ~CPropTreeItemButton(); + +// Attributes +public: + // The non-attribute area needs drawing + virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y); + + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Overrideable - Returns TRUE if the point is on the button + virtual BOOL HitButton(const POINT& pt); + + void SetButtonText( LPCSTR text ); + +protected: + CString buttonText; + CRect buttonRect; + CRect hitTestRect; + bool mouseDown; + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. diff --git a/tools/common/PropTree/PropTreeItemCheck.cpp b/tools/common/PropTree/PropTreeItemCheck.cpp new file mode 100644 index 000000000..7189e76ed --- /dev/null +++ b/tools/common/PropTree/PropTreeItemCheck.cpp @@ -0,0 +1,161 @@ +// PropTreeItemCheck.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "proptree.h" +#include "PropTreeItemCheck.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define CHECK_BOX_SIZE 14 + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCheck + +CPropTreeItemCheck::CPropTreeItemCheck() +{ + checkState = 0; +} + +CPropTreeItemCheck::~CPropTreeItemCheck() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemCheck, CButton) + //{{AFX_MSG_MAP(CPropTreeItemCheck) + //}}AFX_MSG_MAP + ON_CONTROL_REFLECT(BN_KILLFOCUS, OnBnKillfocus) + ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCheck message handlers + +void CPropTreeItemCheck::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + // verify the window has been created + if (!IsWindow(m_hWnd)) + { + TRACE0("CPropTreeItemCombo::DrawAttribute() - The window has not been created\n"); + return; + } + + checkRect.left = m_rc.left; + checkRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-CHECK_BOX_SIZE/2; + checkRect.right = checkRect.left + CHECK_BOX_SIZE; + checkRect.bottom = checkRect.top + CHECK_BOX_SIZE; + + if(!m_bActivated) + pDC->DrawFrameControl(&checkRect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT |(checkState ? DFCS_CHECKED : 0)); +} + +void CPropTreeItemCheck::SetCheckState(BOOL state) + { + checkState = state; + + SetCheck(checkState ? BST_CHECKED : BST_UNCHECKED); + } + + +LPARAM CPropTreeItemCheck::GetItemValue() +{ + return (LPARAM)GetCheckState(); +} + + +void CPropTreeItemCheck::SetItemValue(LPARAM lParam) +{ + SetCheckState((BOOL)lParam); +} + + +void CPropTreeItemCheck::OnMove() +{ + if (IsWindow(m_hWnd)) + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE); +} + + +void CPropTreeItemCheck::OnRefresh() +{ +} + + +void CPropTreeItemCheck::OnCommit() +{ + ShowWindow(SW_HIDE); +} + + +void CPropTreeItemCheck::OnActivate(int activateType, CPoint point) +{ + if(activateType == CPropTreeItem::ACTIVATE_TYPE_MOUSE) { + //Check where the user clicked + if(point.x < m_rc.left + CHECK_BOX_SIZE) { + SetCheckState(!GetCheckState()); + CommitChanges(); + } else { + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); + } + } else { + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); + } +} + + +bool CPropTreeItemCheck::CreateCheckBox() { + ASSERT(m_pProp!=NULL); + + if (IsWindow(m_hWnd)) + DestroyWindow(); + + DWORD dwStyle = (WS_CHILD|BS_CHECKBOX|BS_NOTIFY|BS_FLAT ); + + if (!Create(NULL, dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID())) + { + TRACE0("CPropTreeItemCombo::CreateComboBox() - failed to create combo box\n"); + return FALSE; + } + + return TRUE; +} + +void CPropTreeItemCheck::OnBnKillfocus() +{ + CommitChanges(); +} + +void CPropTreeItemCheck::OnBnClicked() +{ + int state = GetCheck(); + + SetCheckState(GetCheck() == BST_CHECKED ? FALSE : TRUE); + CommitChanges(); +} diff --git a/tools/common/PropTree/PropTreeItemCheck.h b/tools/common/PropTree/PropTreeItemCheck.h new file mode 100644 index 000000000..b1e7f99f6 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemCheck.h @@ -0,0 +1,95 @@ +#pragma once + +// PropTreeItemCheck.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCheck window + +class PROPTREE_API CPropTreeItemCheck : public CButton, public CPropTreeItem +{ +// Construction +public: + CPropTreeItemCheck(); + virtual ~CPropTreeItemCheck(); + +// Attributes +public: + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + bool HitCheckBoxTest(const POINT& pt); + + bool CreateCheckBox(); + + BOOL GetCheckState() { return checkState; }; + void SetCheckState(BOOL state); + + +protected: + BOOL checkState; + CRect checkRect; + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemCheck) + //}}AFX_VIRTUAL + +// Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemCheck) + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +public: + + afx_msg void OnBnKillfocus(); + afx_msg void OnBnClicked(); +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. diff --git a/tools/common/PropTree/PropTreeItemColor.cpp b/tools/common/PropTree/PropTreeItemColor.cpp new file mode 100644 index 000000000..bf369587f --- /dev/null +++ b/tools/common/PropTree/PropTreeItemColor.cpp @@ -0,0 +1,369 @@ +// PropTreeItemColor.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" +#include "../../../sys/win32/rc/proptree_Resource.h" +#include "PropTreeItemColor.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +extern HINSTANCE ghInst; + +typedef struct _ColorTableEntry +{ + COLORREF color; + RECT rcSpot; +} ColorTableEntry; + +static ColorTableEntry _crColors[] = +{ + {RGB(0x00, 0x00, 0x00)}, + {RGB(0xA5, 0x2A, 0x00)}, + {RGB(0x00, 0x40, 0x40)}, + {RGB(0x00, 0x55, 0x00)}, + {RGB(0x00, 0x00, 0x5E)}, + {RGB(0x00, 0x00, 0x8B)}, + {RGB(0x4B, 0x00, 0x82)}, + {RGB(0x28, 0x28, 0x28)}, + + {RGB(0x8B, 0x00, 0x00)}, + {RGB(0xFF, 0x68, 0x20)}, + {RGB(0x8B, 0x8B, 0x00)}, + {RGB(0x00, 0x93, 0x00)}, + {RGB(0x38, 0x8E, 0x8E)}, + {RGB(0x00, 0x00, 0xFF)}, + {RGB(0x7B, 0x7B, 0xC0)}, + {RGB(0x66, 0x66, 0x66)}, + + {RGB(0xFF, 0x00, 0x00)}, + {RGB(0xFF, 0xAD, 0x5B)}, + {RGB(0x32, 0xCD, 0x32)}, + {RGB(0x3C, 0xB3, 0x71)}, + {RGB(0x7F, 0xFF, 0xD4)}, + {RGB(0x7D, 0x9E, 0xC0)}, + {RGB(0x80, 0x00, 0x80)}, + {RGB(0x7F, 0x7F, 0x7F)}, + + {RGB(0xFF, 0xC0, 0xCB)}, + {RGB(0xFF, 0xD7, 0x00)}, + {RGB(0xFF, 0xFF, 0x00)}, + {RGB(0x00, 0xFF, 0x00)}, + {RGB(0x40, 0xE0, 0xD0)}, + {RGB(0xC0, 0xFF, 0xFF)}, + {RGB(0x48, 0x00, 0x48)}, + {RGB(0xC0, 0xC0, 0xC0)}, + + {RGB(0xFF, 0xE4, 0xE1)}, + {RGB(0xD2, 0xB4, 0x8C)}, + {RGB(0xFF, 0xFF, 0xE0)}, + {RGB(0x98, 0xFB, 0x98)}, + {RGB(0xAF, 0xEE, 0xEE)}, + {RGB(0x68, 0x83, 0x8B)}, + {RGB(0xE6, 0xE6, 0xFA)}, + {RGB(0xFF, 0xFF, 0xFF)} +}; + +static void ColorBox(CDC* pDC, CPoint pt, COLORREF clr, BOOL bHover) +{ + CBrush br(clr); + + CBrush* obr = pDC->SelectObject(&br); + + pDC->PatBlt(pt.x, pt.y, 13, 13, PATCOPY); + pDC->SelectObject(obr); + + CRect rc; + rc.SetRect(pt.x - 2, pt.y - 2, pt.x + 15, pt.y + 15); + + pDC->DrawEdge(&rc, (bHover) ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT); +} + + + +static LONG FindSpot(CPoint point) +{ + for (LONG i=0; i<40; i++) + { + if (PtInRect(&_crColors[i].rcSpot, point)) + return i; + } + + return -1; +} + + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemColor + +COLORREF* CPropTreeItemColor::s_pColors = NULL; + +CPropTreeItemColor::CPropTreeItemColor() : + m_cColor(0), + m_cPrevColor(0), + m_nSpot(-1), + m_bButton(FALSE), + m_bInDialog(FALSE) +{ +} + +CPropTreeItemColor::~CPropTreeItemColor() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemColor, CWnd) + //{{AFX_MSG_MAP(CPropTreeItemColor) + ON_WM_KILLFOCUS() + ON_WM_PAINT() + ON_WM_CLOSE() + ON_WM_MOUSEMOVE() + ON_WM_SETCURSOR() + ON_WM_LBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemColor message handlers + +void CPropTreeItemColor::SetDefaultColorsList(COLORREF* pColors) +{ + s_pColors = pColors; +} + + +void CPropTreeItemColor::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + CRect r(rc); + + pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont()); + + if (!m_pProp->IsWindowEnabled()) + pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT)); + else + pDC->SetTextColor(RGB(0,0,0)); + + r.top += 1; + r.right = r.left + r.Height() - 1; + + CBrush br(m_cColor); + CBrush* pold = pDC->SelectObject(&br); + pDC->PatBlt(r.left, r.top, r.Width(), r.Height(), PATCOPY); + pDC->SelectObject(pold); + + pDC->DrawEdge(&r, EDGE_SUNKEN, BF_RECT); + + CString s; + + r = rc; + r.left += r.Height(); + s.Format(_T("R = %d, G = %d, B = %d"), GetRValue(m_cColor),GetGValue(m_cColor), GetBValue(m_cColor)); + pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER); +} + + +LPARAM CPropTreeItemColor::GetItemValue() +{ + return m_cColor; +} + + +void CPropTreeItemColor::SetItemValue(LPARAM lParam) +{ + m_cColor = lParam; +} + + +void CPropTreeItemColor::OnMove() +{ +} + + +void CPropTreeItemColor::OnRefresh() +{ +} + + +void CPropTreeItemColor::OnCommit() +{ + ShowWindow(SW_HIDE); +} + + +void CPropTreeItemColor::OnActivate(int activateType, CPoint point) +{ + CRect r; + + m_cPrevColor = m_cColor; + + r = m_rc; + r.right = r.left + 150; + r.bottom = r.top + 120; + + ASSERT(m_pProp!=NULL); + m_pProp->GetCtrlParent()->ClientToScreen(r); + + if (!IsWindow(m_hWnd)) + { + LPCTSTR pszClassName; + + pszClassName = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE + 1)); + + DWORD dwStyle = WS_POPUP|WS_DLGFRAME; + + CreateEx(0, pszClassName, _T(""), dwStyle, r, m_pProp->GetCtrlParent(), 0); + m_rcButton.SetRect(40, 94, 110, 114); + } + + SetWindowPos(NULL, r.left, r.top, r.Width() + 1, r.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); +} + + +void CPropTreeItemColor::OnKillFocus(CWnd* pNewWnd) +{ + CWnd::OnKillFocus(pNewWnd); + + if (!m_bInDialog) + CommitChanges(); +} + + +void CPropTreeItemColor::OnPaint() +{ + CPaintDC dc(this); + CPoint pt; + + for (LONG i=0; i<40; i++) + { + pt.x = (i & 7) * 18 + 3; + pt.y = (i >> 3) * 18 + 3; + ColorBox(&dc, pt, _crColors[i].color, m_nSpot==i); + SetRect(&_crColors[i].rcSpot, pt.x, pt.y, pt.x + 13, pt.y + 13); + } + + ASSERT(m_pProp!=NULL); + + dc.SelectObject(m_pProp->GetNormalFont()); + + CString s(_T("More Colors")); + + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(GetSysColor(COLOR_BTNTEXT)); + dc.DrawText(s, &m_rcButton, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + + dc.DrawEdge(&m_rcButton, m_bButton ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT); +} + + +void CPropTreeItemColor::OnClose() +{ + CommitChanges(); +} + + +void CPropTreeItemColor::OnMouseMove(UINT, CPoint point) +{ + BOOL bButton; + LONG nSpot; + + nSpot = FindSpot(point); + if (nSpot!=m_nSpot) + { + Invalidate(FALSE); + m_nSpot = nSpot; + } + + bButton = m_rcButton.PtInRect(point); + + if (bButton!=m_bButton) + { + m_bButton = bButton; + Invalidate(FALSE); + } +} + + +BOOL CPropTreeItemColor::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) +{ + if (nHitTest==HTCLIENT) + { + CPoint point; + + GetCursorPos(&point); + ScreenToClient(&point); + + if (FindSpot(point)!=-1 || m_rcButton.PtInRect(point)) + { + SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_FPOINT))); + return TRUE; + } + + } + + return CWnd::OnSetCursor(pWnd, nHitTest, message); +} + + +void CPropTreeItemColor::OnLButtonDown(UINT, CPoint point) +{ + if (m_nSpot!=-1) + { + m_cColor = _crColors[m_nSpot].color; + CommitChanges(); + } + else + if (m_rcButton.PtInRect(point)) + { + CHOOSECOLOR cc; + COLORREF clr[16]; + + ZeroMemory(&cc, sizeof(CHOOSECOLOR)); + cc.Flags = CC_FULLOPEN|CC_ANYCOLOR|CC_RGBINIT; + cc.lStructSize = sizeof(CHOOSECOLOR); + cc.hwndOwner = m_hWnd; + cc.rgbResult = m_cColor; + cc.lpCustColors = s_pColors ? s_pColors : clr; + + memset(clr, 0xff, sizeof(COLORREF) * 16); + clr[0] = m_cColor; + + m_bInDialog = TRUE; + + ASSERT(m_pProp!=NULL); + m_pProp->DisableInput(); + + ShowWindow(SW_HIDE); + + if (ChooseColor(&cc)) + m_cColor = cc.rgbResult; + + m_pProp->DisableInput(FALSE); + CommitChanges(); + } +} diff --git a/tools/common/PropTree/PropTreeItemColor.h b/tools/common/PropTree/PropTreeItemColor.h new file mode 100644 index 000000000..be0b1d599 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemColor.h @@ -0,0 +1,98 @@ +#if !defined(AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_) +#define AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeItemColor.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemColor window + +class PROPTREE_API CPropTreeItemColor : public CWnd, public CPropTreeItem +{ +// Construction +public: + CPropTreeItemColor(); + virtual ~CPropTreeItemColor(); + +// Attributes +public: + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + static void SetDefaultColorsList(COLORREF* pColors); + +protected: + COLORREF m_cColor; + COLORREF m_cPrevColor; + CRect m_rcButton; + LONG m_nSpot; + BOOL m_bButton; + BOOL m_bInDialog; + + static COLORREF* s_pColors; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemColor) + //}}AFX_VIRTUAL + +// Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemColor) + afx_msg void OnKillFocus(CWnd* pNewWnd); + afx_msg void OnPaint(); + afx_msg void OnClose(); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPTREEITEMCOLOR_H__50C09AC0_1F02_4150_AA6A_5151345D87A2__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeItemCombo.cpp b/tools/common/PropTree/PropTreeItemCombo.cpp new file mode 100644 index 000000000..d4444475f --- /dev/null +++ b/tools/common/PropTree/PropTreeItemCombo.cpp @@ -0,0 +1,233 @@ +// PropTreeItemCombo.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" +#include "../../../sys/win32/rc/proptree_Resource.h" + +#include "PropTreeItemCombo.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define DROPDOWN_HEIGHT 100 + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCombo + +CPropTreeItemCombo::CPropTreeItemCombo() : + m_lComboData(0), + m_nDropHeight(DROPDOWN_HEIGHT) +{ +} + +CPropTreeItemCombo::~CPropTreeItemCombo() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemCombo, CComboBox) + //{{AFX_MSG_MAP(CPropTreeItemCombo) + ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange) + ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCombo message handlers + +void CPropTreeItemCombo::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + // verify the window has been created + if (!IsWindow(m_hWnd)) + { + TRACE0("CPropTreeItemCombo::DrawAttribute() - The window has not been created\n"); + return; + } + + pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont()); + pDC->SetTextColor(RGB(0,0,0)); + pDC->SetBkMode(TRANSPARENT); + + CRect r = rc; + CString s; + LONG idx; + + if ((idx = GetCurSel())!=CB_ERR) + GetLBText(idx, s); + else + s = _T(""); + + pDC->DrawText(s, r, DT_SINGLELINE|DT_VCENTER); +} + + +LPARAM CPropTreeItemCombo::GetItemValue() +{ + return m_lComboData; +} + + +void CPropTreeItemCombo::SetItemValue(LPARAM lParam) +{ + m_lComboData = lParam; + OnRefresh(); +} + + +void CPropTreeItemCombo::OnMove() +{ + if (IsWindow(m_hWnd) && IsWindowVisible()) + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() + 1, m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); +} + + +void CPropTreeItemCombo::OnRefresh() +{ + LONG idx = FindCBData(m_lComboData); + + if (idx!=CB_ERR) + SetCurSel(idx); +} + + +void CPropTreeItemCombo::OnCommit() +{ + LONG idx; + + // store combo box item data + if ((idx = GetCurSel())==CB_ERR) + m_lComboData = 0; + else + m_lComboData = (LPARAM)GetItemData(idx); + + ShowWindow(SW_HIDE); +} + + +void CPropTreeItemCombo::OnActivate(int activateType, CPoint point) +{ + // activate the combo box + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() + 1, m_rc.Height() + m_nDropHeight, SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); + + if (GetCount()) + ShowDropDown(TRUE); +} + + +BOOL CPropTreeItemCombo::CreateComboBox(DWORD dwStyle) +{ + ASSERT(m_pProp!=NULL); + + if (IsWindow(m_hWnd)) + DestroyWindow(); + + // force as not visible child window + dwStyle = (WS_CHILD|WS_VSCROLL|dwStyle) & ~WS_VISIBLE; + + if (!Create(dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID())) + { + TRACE0("CPropTreeItemCombo::CreateComboBox() - failed to create combo box\n"); + return FALSE; + } + + SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject); + + return TRUE; +} + + +BOOL CPropTreeItemCombo::CreateComboBoxBool() +{ + ASSERT(m_pProp!=NULL); + + if (IsWindow(m_hWnd)) + DestroyWindow(); + + // force as a non-visible child window + DWORD dwStyle = WS_CHILD|WS_VSCROLL|CBS_SORT|CBS_DROPDOWNLIST; + + if (!Create(dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID())) + { + TRACE0("CPropTreeItemCombo::CreateComboBoxBool() - failed to create combo box\n"); + return FALSE; + } + + SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject); + + // file the combo box + LONG idx; + CString s; + + s.LoadString(IDS_TRUE); + idx = AddString(s); + SetItemData(idx, TRUE); + + s.LoadString(IDS_FALSE); + idx = AddString(s); + SetItemData(idx, FALSE); + + return TRUE; +} + + +LONG CPropTreeItemCombo::FindCBData(LPARAM lParam) +{ + LONG idx; + + for (idx = 0; idx < GetCount(); idx++) + { + if (GetItemData(idx)==(DWORD)lParam) + return idx; + } + + return CB_ERR; +} + + +void CPropTreeItemCombo::OnSelchange() +{ + CommitChanges(); +} + + +void CPropTreeItemCombo::OnKillfocus() +{ + CommitChanges(); +} + + +void CPropTreeItemCombo::SetDropDownHeight(LONG nDropHeight) +{ + m_nDropHeight = nDropHeight; +} + + +LONG CPropTreeItemCombo::GetDropDownHeight() +{ + return m_nDropHeight; +} diff --git a/tools/common/PropTree/PropTreeItemCombo.h b/tools/common/PropTree/PropTreeItemCombo.h new file mode 100644 index 000000000..35f192145 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemCombo.h @@ -0,0 +1,103 @@ +#if !defined(AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_) +#define AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeItemCombo.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemCombo window + +class PROPTREE_API CPropTreeItemCombo : public CComboBox, public CPropTreeItem +{ +// Construction +public: + CPropTreeItemCombo(); + virtual ~CPropTreeItemCombo(); + +// Attributes +public: + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + // Create your combo box with your specified styles + BOOL CreateComboBox(DWORD dwStyle = WS_CHILD|WS_VSCROLL|CBS_SORT|CBS_DROPDOWNLIST); + + // Create combo box with TRUE/FALSE selections + BOOL CreateComboBoxBool(); + + // Set the height for the dropdown combo box + void SetDropDownHeight(LONG nDropHeight); + + // Get the height of the dropdown combo box + LONG GetDropDownHeight(); + +protected: + LPARAM m_lComboData; + LONG m_nDropHeight; + +// Operations +protected: + LONG FindCBData(LPARAM lParam); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemCombo) + //}}AFX_VIRTUAL + +// Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemCombo) + afx_msg void OnSelchange(); + afx_msg void OnKillfocus(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPTREEITEMCOMBO_H__9916BC6F_751F_4B15_996F_3C9F6334A259__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeItemEdit.cpp b/tools/common/PropTree/PropTreeItemEdit.cpp new file mode 100644 index 000000000..87384df14 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemEdit.cpp @@ -0,0 +1,212 @@ +// PropTreeItemEdit.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "proptree.h" +#include "PropTreeItemEdit.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEdit + +CPropTreeItemEdit::CPropTreeItemEdit() : + m_sEdit(_T("")), + m_nFormat(ValueFormatText), + m_bPassword(FALSE), + m_fValue(0.0f) +{ +} + +CPropTreeItemEdit::~CPropTreeItemEdit() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemEdit, CEdit) + //{{AFX_MSG_MAP(CPropTreeItemEdit) + ON_WM_GETDLGCODE() + ON_WM_KEYDOWN() + ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEdit message handlers + +void CPropTreeItemEdit::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont()); + pDC->SetTextColor(RGB(0,0,0)); + pDC->SetBkMode(TRANSPARENT); + + CRect r = rc; + + TCHAR ch; + + // can't use GetPasswordChar(), because window may not be created yet + ch = (m_bPassword) ? '*' : '\0'; + + if (ch) + { + CString s; + + s = m_sEdit; + for (LONG i=0; iDrawText(s, r, DT_SINGLELINE|DT_VCENTER); + } + else + { + pDC->DrawText(m_sEdit, r, DT_SINGLELINE|DT_VCENTER); + } +} + + + +void CPropTreeItemEdit::SetAsPassword(BOOL bPassword) +{ + m_bPassword = bPassword; +} + + +void CPropTreeItemEdit::SetValueFormat(ValueFormat nFormat) +{ + m_nFormat = nFormat; +} + + +LPARAM CPropTreeItemEdit::GetItemValue() +{ + switch (m_nFormat) + { + case ValueFormatNumber: + return _ttoi(m_sEdit); + + case ValueFormatFloatPointer: + _stscanf(m_sEdit, _T("%f"), &m_fValue); + return (LPARAM)&m_fValue; + } + + return (LPARAM)(LPCTSTR)m_sEdit; +} + + +void CPropTreeItemEdit::SetItemValue(LPARAM lParam) +{ + switch (m_nFormat) + { + case ValueFormatNumber: + m_sEdit.Format(_T("%d"), lParam); + return; + + case ValueFormatFloatPointer: + { + TCHAR tmp[MAX_PATH]; + m_fValue = *(float*)lParam; + _stprintf(tmp, _T("%f"), m_fValue); + m_sEdit = tmp; + } + return; + } + + if (lParam==0L) + { + TRACE0("CPropTreeItemEdit::SetItemValue - Invalid lParam value\n"); + return; + } + + m_sEdit = (LPCTSTR)lParam; +} + + +void CPropTreeItemEdit::OnMove() +{ + if (IsWindow(m_hWnd)) + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE); +} + + +void CPropTreeItemEdit::OnRefresh() +{ + if (IsWindow(m_hWnd)) + SetWindowText(m_sEdit); +} + + +void CPropTreeItemEdit::OnCommit() +{ + // hide edit control + ShowWindow(SW_HIDE); + + // store edit text for GetItemValue + GetWindowText(m_sEdit); +} + + +void CPropTreeItemEdit::OnActivate(int activateType, CPoint point) +{ + // Check if the edit control needs creation + if (!IsWindow(m_hWnd)) + { + DWORD dwStyle; + + dwStyle = WS_CHILD|ES_AUTOHSCROLL; + Create(dwStyle, m_rc, m_pProp->GetCtrlParent(), GetCtrlID()); + } + + SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject); + + SetPasswordChar((TCHAR)(m_bPassword ? '*' : 0)); + SetWindowText(m_sEdit); + SetSel(0, -1); + + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); +} + + +UINT CPropTreeItemEdit::OnGetDlgCode() +{ + return CEdit::OnGetDlgCode()|DLGC_WANTALLKEYS; +} + + +void CPropTreeItemEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + if (nChar==VK_RETURN) + CommitChanges(); + + CEdit::OnKeyDown(nChar, nRepCnt, nFlags); +} + + +void CPropTreeItemEdit::OnKillfocus() +{ + CommitChanges(); +} diff --git a/tools/common/PropTree/PropTreeItemEdit.h b/tools/common/PropTree/PropTreeItemEdit.h new file mode 100644 index 000000000..610df0131 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemEdit.h @@ -0,0 +1,108 @@ +#if !defined(AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_) +#define AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeItemEdit.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEdit window + +class PROPTREE_API CPropTreeItemEdit : public CEdit, public CPropTreeItem +{ +// Construction +public: + CPropTreeItemEdit(); + virtual ~CPropTreeItemEdit(); + +// Attributes +public: + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + + enum ValueFormat + { + ValueFormatText, + ValueFormatNumber, + ValueFormatFloatPointer + }; + + // Set to specifify format of SetItemValue/GetItemValue + void SetValueFormat(ValueFormat nFormat); + + // Set to TRUE for to use a password edit control + void SetAsPassword(BOOL bPassword); + +protected: + CString m_sEdit; + float m_fValue; + + ValueFormat m_nFormat; + BOOL m_bPassword; + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemEdit) + //}}AFX_VIRTUAL + +// Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemEdit) + afx_msg UINT OnGetDlgCode(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKillfocus(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPTREEITEMEDIT_H__642536B1_1162_4F99_B09D_9B1BD2CF88B6__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeItemEditButton.cpp b/tools/common/PropTree/PropTreeItemEditButton.cpp new file mode 100644 index 000000000..977fee356 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemEditButton.cpp @@ -0,0 +1,259 @@ +// PropTreeItemEdit.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "proptree.h" +#include "PropTreeItemEditButton.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define BUTTON_SIZE 17 + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEditButton + +CPropTreeItemEditButton::CPropTreeItemEditButton() : +m_sEdit(_T("")), +m_nFormat(ValueFormatText), +m_bPassword(FALSE), +m_fValue(0.0f) +{ + mouseDown = false; +} + +CPropTreeItemEditButton::~CPropTreeItemEditButton() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemEditButton, CEdit) + //{{AFX_MSG_MAP(CPropTreeItemEditButton) + ON_WM_GETDLGCODE() + ON_WM_KEYDOWN() + ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEditButton message handlers + +LONG CPropTreeItemEditButton::DrawItem( CDC* pDC, const RECT& rc, LONG x, LONG y ) +{ + CSize textSize; + CRect textRect; + LONG nTotal = 0; + + nTotal = CPropTreeItemEdit::DrawItem( pDC, rc, x, y ); + + textSize = pDC->GetOutputTextExtent( buttonText ); + + buttonRect.left = m_rc.right - ( textSize.cx + 12 + 4); + buttonRect.top = m_rc.top + ((m_rc.bottom - m_rc.top)/2)-BUTTON_SIZE/2; + buttonRect.right = buttonRect.left + textSize.cx + 12; + buttonRect.bottom = buttonRect.top + BUTTON_SIZE; + + UINT buttonStyle; + + if ( (m_dwState & TreeItemChecked) ) { + buttonStyle = DFCS_BUTTONPUSH | DFCS_PUSHED; + } else { + buttonStyle = DFCS_BUTTONPUSH; + } + pDC->DrawFrameControl(&buttonRect, DFC_BUTTON, buttonStyle ); + + textRect = buttonRect; + textRect.left += 4; + textRect.right -= 8; + pDC->DrawText( buttonText, textRect, DT_SINGLELINE|DT_VCENTER ); + + //Adjust hit test rect to acount for window scrolling + hitTestRect = buttonRect; + hitTestRect.OffsetRect(0, m_pProp->GetOrigin().y); + + return nTotal; +} + +void CPropTreeItemEditButton::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont()); + pDC->SetTextColor(RGB(0,0,0)); + pDC->SetBkMode(TRANSPARENT); + + CRect r = rc; + r.right = buttonRect.left - 5; + + TCHAR ch; + + // can't use GetPasswordChar(), because window may not be created yet + ch = (m_bPassword) ? '*' : '\0'; + + if (ch) + { + CString s; + + s = m_sEdit; + for (LONG i=0; iDrawText(s, r, DT_SINGLELINE|DT_VCENTER); + } + else + { + pDC->DrawText(m_sEdit, r, DT_SINGLELINE|DT_VCENTER); + } +} + + + +void CPropTreeItemEditButton::SetAsPassword(BOOL bPassword) +{ + m_bPassword = bPassword; +} + + +void CPropTreeItemEditButton::SetValueFormat(ValueFormat nFormat) +{ + m_nFormat = nFormat; +} + + +LPARAM CPropTreeItemEditButton::GetItemValue() +{ + switch (m_nFormat) + { + case ValueFormatNumber: + return _ttoi(m_sEdit); + + case ValueFormatFloatPointer: + _stscanf(m_sEdit, _T("%f"), &m_fValue); + return (LPARAM)&m_fValue; + } + + return (LPARAM)(LPCTSTR)m_sEdit; +} + + +void CPropTreeItemEditButton::SetItemValue(LPARAM lParam) +{ + switch (m_nFormat) + { + case ValueFormatNumber: + m_sEdit.Format(_T("%d"), lParam); + return; + + case ValueFormatFloatPointer: + { + TCHAR tmp[MAX_PATH]; + m_fValue = *(float*)lParam; + _stprintf(tmp, _T("%f"), m_fValue); + m_sEdit = tmp; + } + return; + } + + if (lParam==0L) + { + TRACE0("CPropTreeItemEditButton::SetItemValue - Invalid lParam value\n"); + return; + } + + m_sEdit = (LPCTSTR)lParam; +} + + +void CPropTreeItemEditButton::OnMove() +{ + if (IsWindow(m_hWnd)) + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE); +} + + +void CPropTreeItemEditButton::OnRefresh() +{ + if (IsWindow(m_hWnd)) + SetWindowText(m_sEdit); +} + + +void CPropTreeItemEditButton::OnCommit() +{ + // hide edit control + ShowWindow(SW_HIDE); + + // store edit text for GetItemValue + GetWindowText(m_sEdit); +} + + +void CPropTreeItemEditButton::OnActivate(int activateType, CPoint point) +{ + // Check if the edit control needs creation + if (!IsWindow(m_hWnd)) + { + DWORD dwStyle; + + dwStyle = WS_CHILD|ES_AUTOHSCROLL; + Create(dwStyle, m_rc, m_pProp->GetCtrlParent(), GetCtrlID()); + SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject); + } + + SetPasswordChar((TCHAR)(m_bPassword ? '*' : 0)); + SetWindowText(m_sEdit); + SetSel(0, -1); + + SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() - buttonRect.Width() - 5, m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); + SetFocus(); +} + + +UINT CPropTreeItemEditButton::OnGetDlgCode() +{ + return CEdit::OnGetDlgCode()|DLGC_WANTALLKEYS; +} + + +void CPropTreeItemEditButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + if (nChar==VK_RETURN) + CommitChanges(); + + CEdit::OnKeyDown(nChar, nRepCnt, nFlags); +} + + +void CPropTreeItemEditButton::OnKillfocus() +{ + CommitChanges(); +} + +BOOL CPropTreeItemEditButton::HitButton( const POINT& pt ) { + return hitTestRect.PtInRect( pt ); +} + +void CPropTreeItemEditButton::SetButtonText( LPCSTR text ) { + buttonText = text; +} diff --git a/tools/common/PropTree/PropTreeItemEditButton.h b/tools/common/PropTree/PropTreeItemEditButton.h new file mode 100644 index 000000000..1ad26702e --- /dev/null +++ b/tools/common/PropTree/PropTreeItemEditButton.h @@ -0,0 +1,125 @@ +#ifndef __PROP_TREE_ITEM_EDIT_BUTTON_H__ +#define __PROP_TREE_ITEM_EDIT_BUTTON_H__ + + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeItemEdit.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#include "PropTreeItem.h" +//#include "PropTreeItemEdit.h" + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemEditButton window + +class PROPTREE_API CPropTreeItemEditButton : public CPropTreeItemEdit +{ + // Construction +public: + CPropTreeItemEditButton(); + virtual ~CPropTreeItemEditButton(); + + // Attributes +public: + // The non-attribute area needs drawing + virtual LONG DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y); + + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + + // Called when attribute area has changed size + virtual void OnMove(); + + // Called when the item needs to refresh its data + virtual void OnRefresh(); + + // Called when the item needs to commit its changes + virtual void OnCommit(); + + // Called to activate the item + virtual void OnActivate(int activateType, CPoint point); + + + enum ValueFormat + { + ValueFormatText, + ValueFormatNumber, + ValueFormatFloatPointer + }; + + // Set to specifify format of SetItemValue/GetItemValue + void SetValueFormat(ValueFormat nFormat); + + // Set to TRUE for to use a password edit control + void SetAsPassword(BOOL bPassword); + + // Overrideable - Returns TRUE if the point is on the button + virtual BOOL HitButton(const POINT& pt); + + void SetButtonText( LPCSTR text ); + +protected: + CString m_sEdit; + float m_fValue; + + ValueFormat m_nFormat; + BOOL m_bPassword; + + + CString buttonText; + CRect buttonRect; + CRect hitTestRect; + bool mouseDown; + + + // Operations +public: + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemEditButton) + //}}AFX_VIRTUAL + + // Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemEditButton) + afx_msg UINT OnGetDlgCode(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKillfocus(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // __PROP_TREE_ITEM_EDIT_BUTTON_H__ diff --git a/tools/common/PropTree/PropTreeItemFileEdit.cpp b/tools/common/PropTree/PropTreeItemFileEdit.cpp new file mode 100644 index 000000000..2e956508e --- /dev/null +++ b/tools/common/PropTree/PropTreeItemFileEdit.cpp @@ -0,0 +1,130 @@ +// PropTreeItemFileEdit.cpp : implementation file + + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "proptree.h" +#include "PropTreeItemFileEdit.h" + +#include "../../../sys/win32/rc/proptree_Resource.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeItemFileEdit + +CPropTreeItemFileEdit::CPropTreeItemFileEdit() { +} + +CPropTreeItemFileEdit::~CPropTreeItemFileEdit() { +} + + +BEGIN_MESSAGE_MAP(CPropTreeItemFileEdit, CPropTreeItemEdit) + //{{AFX_MSG_MAP(CPropTreeItemFileEdit) + //}}AFX_MSG_MAP + ON_WM_CONTEXTMENU() + ON_WM_CREATE() + + ON_COMMAND(ID_EDITMENU_INSERTFILE, OnInsertFile) + ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) + ON_COMMAND(ID_EDIT_CUT, OnEditCut) + ON_COMMAND(ID_EDIT_COPY, OnEditCopy) + ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) + ON_COMMAND(ID_EDIT_DELETE, OnEditDelete) + ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectAll) + +END_MESSAGE_MAP() + + +void CPropTreeItemFileEdit::OnContextMenu(CWnd* pWnd, CPoint point) { + + CMenu FloatingMenu; + VERIFY(FloatingMenu.LoadMenu(IDR_ME_EDIT_MENU)); + CMenu* pPopupMenu = FloatingMenu.GetSubMenu (0); + + if(CanUndo()) { + pPopupMenu->EnableMenuItem(ID_EDIT_UNDO, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_EDIT_UNDO, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + DWORD dwSel = GetSel(); + if(HIWORD(dwSel) != LOWORD(dwSel)) { + pPopupMenu->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_ENABLED); + pPopupMenu->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED); + pPopupMenu->EnableMenuItem(ID_EDIT_DELETE, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_EDIT_DELETE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); +} + +int CPropTreeItemFileEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CPropTreeItemEdit::OnCreate(lpCreateStruct) == -1) + return -1; + + // TODO: Add your specialized creation code here + + return 0; +} + +void CPropTreeItemFileEdit::OnInsertFile() { + CFileDialog dlg(TRUE); + dlg.m_ofn.Flags |= OFN_FILEMUSTEXIST; + + int startSel, endSel; + GetSel(startSel, endSel); + + if( dlg.DoModal()== IDOK) { + + idStr currentText = (char*)GetItemValue(); + idStr newText = currentText.Left(startSel) + currentText.Right(currentText.Length() - endSel); + + idStr filename = fileSystem->OSPathToRelativePath(dlg.m_ofn.lpstrFile); + filename.BackSlashesToSlashes(); + + + newText.Insert(filename, startSel); + + SetItemValue((LPARAM)newText.c_str()); + m_pProp->RefreshItems(this); + + m_pProp->SendNotify(PTN_ITEMCHANGED, this); + + } +} + +void CPropTreeItemFileEdit::OnEditUndo() { + Undo(); +} + +void CPropTreeItemFileEdit::OnEditCut() { + Cut(); +} + +void CPropTreeItemFileEdit::OnEditCopy() { + Copy(); +} + +void CPropTreeItemFileEdit::OnEditPaste() { + Paste(); +} + +void CPropTreeItemFileEdit::OnEditDelete() { + Clear(); +} + +void CPropTreeItemFileEdit::OnEditSelectAll() { + SetSel(0, -1); +} diff --git a/tools/common/PropTree/PropTreeItemFileEdit.h b/tools/common/PropTree/PropTreeItemFileEdit.h new file mode 100644 index 000000000..8d959d0e6 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemFileEdit.h @@ -0,0 +1,54 @@ +#ifndef __PROP_TREE_ITEM_FILE_EDIT_H__ +#define __PROP_TREE_ITEM_FILE_EDIT_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif + + +//#include "PropTreeItem.h" +//#include "PropTreeItemEdit.h" + +class PROPTREE_API CPropTreeItemFileEdit : public CPropTreeItemEdit +{ + // Construction +public: + CPropTreeItemFileEdit(); + virtual ~CPropTreeItemFileEdit(); + + // Operations +public: + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeItemFileEdit) + //}}AFX_VIRTUAL + + // Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeItemFileEdit) + //}}AFX_MSG + + afx_msg void OnInsertFile(); + afx_msg void OnEditUndo(); + afx_msg void OnEditCut(); + afx_msg void OnEditCopy(); + afx_msg void OnEditPaste(); + afx_msg void OnEditDelete(); + afx_msg void OnEditSelectAll(); + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} + + +#endif diff --git a/tools/common/PropTree/PropTreeItemStatic.cpp b/tools/common/PropTree/PropTreeItemStatic.cpp new file mode 100644 index 000000000..c87e7f435 --- /dev/null +++ b/tools/common/PropTree/PropTreeItemStatic.cpp @@ -0,0 +1,67 @@ +// PropTreeItemStatic.cpp +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" + +#include "PropTreeItemStatic.h" + + +CPropTreeItemStatic::CPropTreeItemStatic() : + m_sAttribute(_T("")) +{ +} + + +CPropTreeItemStatic::~CPropTreeItemStatic() +{ +} + + +void CPropTreeItemStatic::DrawAttribute(CDC* pDC, const RECT& rc) +{ + ASSERT(m_pProp!=NULL); + + pDC->SelectObject(m_pProp->GetNormalFont()); + pDC->SetTextColor(RGB(0,0,0)); + pDC->SetBkMode(TRANSPARENT); + + CRect r = rc; + pDC->DrawText(m_sAttribute, r, DT_SINGLELINE|DT_VCENTER); +} + + +LPARAM CPropTreeItemStatic::GetItemValue() +{ + return (LPARAM)(LPCTSTR)m_sAttribute; +} + + +void CPropTreeItemStatic::SetItemValue(LPARAM lParam) +{ + if (lParam==0L) + { + TRACE0("CPropTreeItemStatic::SetItemValue() - Invalid lParam value\n"); + return; + } + + m_sAttribute = (LPCTSTR)lParam; +} diff --git a/tools/common/PropTree/PropTreeItemStatic.h b/tools/common/PropTree/PropTreeItemStatic.h new file mode 100644 index 000000000..e39fa2dfd --- /dev/null +++ b/tools/common/PropTree/PropTreeItemStatic.h @@ -0,0 +1,45 @@ +// PropTreeItemStatic.h +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +#ifndef _PROPTREEITEMSTATIC_H +#define _PROPTREEITEMSTATIC_H + +#include "PropTreeItem.h" + +class PROPTREE_API CPropTreeItemStatic : public CPropTreeItem +{ +public: + CPropTreeItemStatic(); + virtual ~CPropTreeItemStatic(); + +public: + // The attribute area needs drawing + virtual void DrawAttribute(CDC* pDC, const RECT& rc); + + // Retrieve the item's attribute value (in this case the CString) + virtual LPARAM GetItemValue(); + + // Set the item's attribute value + virtual void SetItemValue(LPARAM lParam); + +protected: + CString m_sAttribute; +}; + + +#endif // _PROPTREEITEMSTATIC_H diff --git a/tools/common/PropTree/PropTreeList.cpp b/tools/common/PropTree/PropTreeList.cpp new file mode 100644 index 000000000..60d0e5772 --- /dev/null +++ b/tools/common/PropTree/PropTreeList.cpp @@ -0,0 +1,635 @@ +// PropTreeList.cpp : implementation file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "PropTree.h" +#include "../../../sys/win32/rc/proptree_Resource.h" +#include "PropTreeList.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define PROPTREEITEM_EXPANDCOLUMN 16 // width of the expand column +#define PROPTREEITEM_COLRNG 5 // width of splitter +#define PROPTREEITEM_DEFHEIGHT 21 // default heigt of an item + +extern HINSTANCE ghInst; + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeList + +CPropTreeList::CPropTreeList() : + m_pProp(NULL), + m_BackBufferSize(0,0), + m_bColDrag(FALSE), + m_nPrevCol(0) +{ +} + +CPropTreeList::~CPropTreeList() +{ +} + + +BEGIN_MESSAGE_MAP(CPropTreeList, CWnd) + //{{AFX_MSG_MAP(CPropTreeList) + ON_WM_SIZE() + ON_WM_PAINT() + ON_WM_SETCURSOR() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_LBUTTONDBLCLK() + ON_WM_MOUSEMOVE() + ON_WM_MOUSEWHEEL() + ON_WM_KEYDOWN() + ON_WM_GETDLGCODE() + ON_WM_VSCROLL() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeList message handlers + +void CPropTreeList::SetPropOwner(CPropTree* pProp) +{ + m_pProp = pProp; +} + + +BOOL CPropTreeList::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) +{ + CWnd* pWnd = this; + + LPCTSTR pszCreateClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW)); + + return pWnd->Create(pszCreateClass, _T(""), dwStyle, rect, pParentWnd, nID); +} + + +void CPropTreeList::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + + RecreateBackBuffer(cx, cy); + + if (m_pProp) + { + UpdateResize(); + Invalidate(); + UpdateWindow(); + + // inform all items that a resize has been made + m_pProp->UpdateMoveAllItems(); + } +} + + +void CPropTreeList::RecreateBackBuffer(int cx, int cy) +{ + if (m_BackBufferSize.cxGetRootItem()->GetTotalHeight(); + si.nPage = nHeight; + + if ((int)si.nPage>si.nMax) + m_pProp->SetOriginOffset(0); + + SetScrollInfo(SB_VERT, &si, TRUE); + + // force set column for clipping + m_pProp->SetColumn(m_pProp->GetColumn()); +} + + +void CPropTreeList::OnPaint() +{ + CPaintDC dc(this); + CDC memdc; + CBitmap* pOldBitmap; + + ASSERT(m_pProp!=NULL); + + m_pProp->ClearVisibleList(); + + memdc.CreateCompatibleDC(&dc); + pOldBitmap = memdc.SelectObject(&m_BackBuffer); + + CRect rc; + GetClientRect(rc); + + // draw control background + memdc.SelectObject(GetSysColorBrush(COLOR_BTNFACE)); + memdc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY); + + // draw control inside fill color + rc.DeflateRect(2,2); + memdc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), m_pProp->IsWindowEnabled() ? WHITENESS : PATCOPY); + rc.InflateRect(2,2); + + // draw expand column + memdc.SelectObject(GetSysColorBrush(COLOR_BTNFACE)); + memdc.PatBlt(0, 0, PROPTREEITEM_EXPANDCOLUMN, rc.Height(), PATCOPY); + + // draw edge + memdc.DrawEdge(&rc, BDR_SUNKENOUTER, BF_RECT); + + CPropTreeItem* pItem; + LONG nTotal = 0; + + ASSERT(m_pProp->GetRootItem()!=NULL); + + rc.DeflateRect(2,2); + + // create clip region + HRGN hRgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); + SelectClipRgn(memdc.m_hDC, hRgn); + + // draw all items + for (pItem = m_pProp->GetRootItem()->GetChild(); pItem; pItem = pItem->GetSibling()) + { + LONG nHeight = pItem->DrawItem(&memdc, rc, 0, nTotal); + nTotal += nHeight; + } + + // remove clip region + SelectClipRgn(memdc.m_hDC, NULL); + DeleteObject(hRgn); + + // copy back buffer to the display + dc.GetClipBox(&rc); + dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, rc.left, rc.top, SRCCOPY); + memdc.DeleteDC(); +} + + +BOOL CPropTreeList::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) +{ + if (nHitTest==HTCLIENT) + { + CPoint pt; + + ASSERT(m_pProp!=NULL); + + GetCursorPos(&pt); + ScreenToClient(&pt); + + switch (m_pProp->HitTest(pt)) + { + case HTCOLUMN: + SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_SPLITTER))); + return TRUE; + + case HTCHECKBOX: + case HTBUTTON: + case HTEXPAND: + SetCursor(LoadCursor(ghInst, MAKEINTRESOURCE(IDC_FPOINT))); + return TRUE; + } + } + + return CWnd::OnSetCursor(pWnd, nHitTest, message); +} + + +void CPropTreeList::OnLButtonDown(UINT, CPoint point) +{ + ASSERT(m_pProp!=NULL); + + if (m_pProp->IsDisableInput()) + return; + + m_pProp->SendNotify(NM_CLICK); + + if (!m_pProp->IsWindowEnabled()) + return; + + SetFocus(); + + LONG nHit = m_pProp->HitTest(point); + + CPropTreeItem* pItem; + CRect rc; + CDC* pDC; + + switch (nHit) + { + case HTCOLUMN: + if (m_pProp->SendNotify(PTN_COLUMNCLICK)) + break; + + m_bColDrag = TRUE; + SetCapture(); + + m_nPrevCol = m_pProp->GetOrigin().x; + + // paint drag line + pDC = GetDC(); + GetClientRect(rc); + pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT); + ReleaseDC(pDC); + break; + + case HTCHECKBOX: + if ((pItem = m_pProp->FindItem(point))!=NULL) + { + pItem->Check(!pItem->IsChecked()); + m_pProp->SendNotify(PTN_CHECKCLICK, pItem); + Invalidate(); + } + break; + case HTBUTTON: + if ((pItem = m_pProp->FindItem(point))!=NULL) + { + pItem->Check(); + m_pProp->SendNotify(PTN_ITEMBUTTONCLICK, pItem); + Invalidate(); + } + break; + case HTEXPAND: + if ((pItem = m_pProp->FindItem(point))!=NULL) + { + if (pItem->GetChild() && !m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem)) + { + pItem->Expand(!pItem->IsExpanded()); + + UpdateResize(); + Invalidate(); + UpdateWindow(); + CheckVisibleFocus(); + } + } + break; + + default: + if ((pItem = m_pProp->FindItem(point))!=NULL) + { + CPropTreeItem* pOldFocus = m_pProp->GetFocusedItem(); + + m_pProp->SelectItems(NULL, FALSE); + m_pProp->SetFocusedItem(pItem); + + pItem->Select(); + + Invalidate(); + + if (pItem!=pOldFocus) + m_pProp->SendNotify(PTN_SELCHANGE, pItem); + + if (nHit==HTATTRIBUTE && !pItem->IsRootLevel()) + { + if (!m_pProp->SendNotify(PTN_PROPCLICK, pItem) && !pItem->IsReadOnly()) + pItem->Activate(CPropTreeItem::ACTIVATE_TYPE_MOUSE, point); + } + } + else + { + m_pProp->SelectItems(NULL, FALSE); + m_pProp->SetFocusedItem(NULL); + m_pProp->SendNotify(PTN_SELCHANGE); + Invalidate(); + } + break; + } +} + + +void CPropTreeList::OnLButtonUp(UINT, CPoint point) +{ + if (m_bColDrag) + { + CDC* pDC = GetDC(); + CRect rc; + + GetClientRect(rc); + pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT); + ReleaseDC(pDC); + + m_bColDrag = FALSE; + ReleaseCapture(); + + m_pProp->SetColumn(point.x); + m_pProp->UpdateMoveAllItems(); + Invalidate(); + } else { + LONG nHit = m_pProp->HitTest(point); + CPropTreeItem* pItem; + + switch (nHit) + { + case HTBUTTON: + if ((pItem = m_pProp->FindItem(point))!=NULL) + { + pItem->Check( FALSE ); + Invalidate(); + } + break; + default: + break; + } + } +} + + +void CPropTreeList::OnLButtonDblClk(UINT, CPoint point) +{ + ASSERT(m_pProp!=NULL); + + m_pProp->SendNotify(NM_DBLCLK); + + CPropTreeItem* pItem; + CPropTreeItem* pOldFocus; + + if ((pItem = m_pProp->FindItem(point))!=NULL && pItem->GetChild()) + { + switch (m_pProp->HitTest(point)) + { + case HTCOLUMN: + break; + + case HTCHECKBOX: + pItem->Check(!pItem->IsChecked()); + m_pProp->SendNotify(PTN_CHECKCLICK, pItem); + Invalidate(); + break; + + case HTATTRIBUTE: + if (!pItem->IsRootLevel()) + break; + + // pass thru to default + + default: + pOldFocus = m_pProp->GetFocusedItem(); + m_pProp->SelectItems(NULL, FALSE); + m_pProp->SetFocusedItem(pItem); + pItem->Select(); + + if (pItem!=pOldFocus) + m_pProp->SendNotify(PTN_SELCHANGE, pItem); + + // pass thru to HTEXPAND + + case HTEXPAND: + if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem)) + { + pItem->Expand(!pItem->IsExpanded()); + + UpdateResize(); + Invalidate(); + UpdateWindow(); + CheckVisibleFocus(); + } + break; + } + } +} + + +void CPropTreeList::OnMouseMove(UINT, CPoint point) +{ + if (m_bColDrag) + { + CDC* pDC = GetDC(); + CRect rc; + + GetClientRect(rc); + pDC->PatBlt(m_nPrevCol - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT); + pDC->PatBlt(point.x - PROPTREEITEM_COLRNG/2, 0, PROPTREEITEM_COLRNG, rc.bottom, PATINVERT); + m_nPrevCol = point.x; + ReleaseDC(pDC); + } +} + + +BOOL CPropTreeList::OnMouseWheel(UINT, short zDelta, CPoint) +{ + SCROLLINFO si; + + ZeroMemory(&si, sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_RANGE; + + GetScrollInfo(SB_VERT, &si); + + CRect rc; + GetClientRect(rc); + + if (si.nMax - si.nMin < rc.Height()) + return TRUE; + + SetFocus(); + OnVScroll(zDelta < 0 ? SB_LINEDOWN : SB_LINEUP, 0, NULL); + + return TRUE; +} + + +void CPropTreeList::OnKeyDown(UINT nChar, UINT, UINT) +{ + + CPropTreeItem* pItem; + + ASSERT(m_pProp!=NULL); + + if (m_pProp->IsDisableInput() || !m_pProp->IsWindowEnabled()) + return; + + switch (nChar) + { + case VK_RETURN: + if ((pItem = m_pProp->GetFocusedItem())!=NULL && !pItem->IsRootLevel() && !pItem->IsReadOnly()) + { + pItem->Activate(CPropTreeItem::ACTIVATE_TYPE_KEYBOARD, CPoint(0,0)); + } + break; + + case VK_HOME: + if (m_pProp->FocusFirst()) + Invalidate(); + break; + + case VK_END: + if (m_pProp->FocusLast()) + Invalidate(); + break; + + case VK_LEFT: + if ((pItem = m_pProp->GetFocusedItem())!=NULL) + { + if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem)) + { + if (pItem->GetChild() && pItem->IsExpanded()) + { + pItem->Expand(FALSE); + UpdateResize(); + Invalidate(); + UpdateWindow(); + CheckVisibleFocus(); + break; + } + } + } + else + break; + // pass thru to next case VK_UP + case VK_UP: + if (m_pProp->FocusPrev()) + Invalidate(); + break; + + case VK_RIGHT: + if ((pItem = m_pProp->GetFocusedItem())!=NULL) + { + if (!m_pProp->SendNotify(PTN_ITEMEXPANDING, pItem)) + { + if (pItem->GetChild() && !pItem->IsExpanded()) + { + pItem->Expand(); + UpdateResize(); + Invalidate(); + UpdateWindow(); + CheckVisibleFocus(); + break; + } + } + } + else + break; + // pass thru to next case VK_DOWN + case VK_DOWN: + if (m_pProp->FocusNext()) + Invalidate(); + break; + } +} + + +UINT CPropTreeList::OnGetDlgCode() +{ + return DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_WANTALLKEYS; +} + + +void CPropTreeList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*) +{ + SCROLLINFO si; + CRect rc; + LONG nHeight; + + SetFocus(); + + GetClientRect(rc); + nHeight = rc.Height() + 1; + + ZeroMemory(&si, sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_RANGE; + + GetScrollInfo(SB_VERT, &si); + + LONG ny = m_pProp->GetOrigin().y; + + switch (nSBCode) + { + case SB_LINEDOWN: + ny += PROPTREEITEM_DEFHEIGHT; + break; + + case SB_LINEUP: + ny -= PROPTREEITEM_DEFHEIGHT; + break; + + case SB_PAGEDOWN: + ny += nHeight; + break; + + case SB_PAGEUP: + ny -= nHeight; + break; + + case SB_THUMBTRACK: + ny = nPos; + break; + } + + ny = __min(__max(ny, si.nMin), si.nMax - nHeight); + + m_pProp->SetOriginOffset(ny); + si.fMask = SIF_POS; + si.nPos = ny; + + SetScrollInfo(SB_VERT, &si, TRUE); + Invalidate(); +} + + +void CPropTreeList::CheckVisibleFocus() +{ + ASSERT(m_pProp!=NULL); + + CPropTreeItem* pItem; + + if ((pItem = m_pProp->GetFocusedItem())==NULL) + return; + + if (!m_pProp->IsItemVisible(pItem)) + { + if (m_pProp->IsSingleSelection()) + pItem->Select(FALSE); + + m_pProp->SetFocusedItem(NULL); + m_pProp->SendNotify(PTN_SELCHANGE, NULL); + + Invalidate(); + } +} diff --git a/tools/common/PropTree/PropTreeList.h b/tools/common/PropTree/PropTreeList.h new file mode 100644 index 000000000..fe25c9216 --- /dev/null +++ b/tools/common/PropTree/PropTreeList.h @@ -0,0 +1,99 @@ +#if !defined(AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_) +#define AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropTreeList.h : header file +// +// Copyright (C) 1998-2001 Scott Ramsay +// sramsay@gonavi.com +// http://www.gonavi.com +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this software for any purpose is hereby granted +// without fee, provided the above notices are retained on all copies. +// Permission to modify the code and to distribute modified code is granted, +// provided the above notices are retained, and a notice that the code was +// modified is included with the above copyright notice. +// +// If you use this code, drop me an email. I'd like to know if you find the code +// useful. + +class CPropTree; + +///////////////////////////////////////////////////////////////////////////// +// CPropTreeList window + +class PROPTREE_API CPropTreeList : public CWnd +{ +// Construction +public: + CPropTreeList(); + virtual ~CPropTreeList(); + + BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID); + +// Attributes +public: + void SetPropOwner(CPropTree* pProp); + +protected: + // CPropTree class that this class belongs + CPropTree* m_pProp; + + // bitmap back buffer for flicker free drawing + CBitmap m_BackBuffer; + + // current diminsions of the back buffer + CSize m_BackBufferSize; + + // splitter pevious position + LONG m_nPrevCol; + + // TRUE if we are dragging the splitter + BOOL m_bColDrag; + +// Operations +public: + void UpdateResize(); + +protected: + void RecreateBackBuffer(int cx, int cy); + void CheckVisibleFocus(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropTreeList) + //}}AFX_VIRTUAL + +// Implementation +public: + + // Generated message map functions +protected: + //{{AFX_MSG(CPropTreeList) + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnPaint(); + afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg UINT OnGetDlgCode(); + //}}AFX_MSG +public: + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPTREELIST_H__2E09E831_09F5_44AA_B41D_9C4BF495873C__INCLUDED_) diff --git a/tools/common/PropTree/PropTreeView.cpp b/tools/common/PropTree/PropTreeView.cpp new file mode 100644 index 000000000..1ccc9a2c9 --- /dev/null +++ b/tools/common/PropTree/PropTreeView.cpp @@ -0,0 +1,103 @@ +// CPropTreeView.cpp : implementation file +// + +//#include "stdafx.h" +#include "../../../idlib/precompiled.h" +#pragma hdrstop + + +#include "PropTreeView.h" + +// CPropTreeView + +IMPLEMENT_DYNCREATE(CPropTreeView, CFormView) + +CPropTreeView::CPropTreeView() +: CFormView((LPCTSTR) NULL) +{ +} + +CPropTreeView::~CPropTreeView() +{ +} + +BEGIN_MESSAGE_MAP(CPropTreeView, CView) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_PAINT() +END_MESSAGE_MAP() + + +// CPropTreeView drawing + +void CPropTreeView::OnDraw(CDC* pDC) +{ + CDocument* pDoc = GetDocument(); + // TODO: add draw code here +} + + +// CPropTreeView diagnostics + +#ifdef _DEBUG +void CPropTreeView::AssertValid() const +{ + CView::AssertValid(); +} + +void CPropTreeView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} +#endif //_DEBUG + + +BOOL CPropTreeView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, + DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, + UINT nID, CCreateContext* pContext) +{ + // create the view window itself + m_pCreateContext = pContext; + if (!CView::Create(lpszClassName, lpszWindowName, + dwStyle, rect, pParentWnd, nID, pContext)) + { + return FALSE; + } + + return TRUE; +} +// CPropTreeView message handlers + +int CPropTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) + return -1; + + DWORD dwStyle; + CRect rc; + + // PTS_NOTIFY - CPropTree will send notification messages to the parent window + dwStyle = WS_CHILD|WS_VISIBLE|PTS_NOTIFY; + + // Init the control's size to cover the entire client area + GetClientRect(rc); + + // Create CPropTree control + m_Tree.Create(dwStyle, rc, this, IDC_PROPERTYTREE); + + return 0; +} + +void CPropTreeView::OnSize(UINT nType, int cx, int cy) +{ + CView::OnSize(nType, cx, cy); + + if (::IsWindow(m_Tree.GetSafeHwnd())) + m_Tree.SetWindowPos(NULL, -1, -1, cx, cy, SWP_NOMOVE|SWP_NOZORDER); +} + + +void CPropTreeView::OnPaint() +{ + Default(); +} diff --git a/tools/common/PropTree/PropTreeView.h b/tools/common/PropTree/PropTreeView.h new file mode 100644 index 000000000..c3d986782 --- /dev/null +++ b/tools/common/PropTree/PropTreeView.h @@ -0,0 +1,41 @@ +#pragma once + +#include "PropTree.h" +// CPropTreeView view + +#define IDC_PROPERTYTREE 100 + +class CPropTreeView : public CFormView +{ + DECLARE_DYNCREATE(CPropTreeView) + +protected: + CPropTree m_Tree; + +protected: + CPropTreeView(); // protected constructor used by dynamic creation + virtual ~CPropTreeView(); + +public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + + CPropTree& GetPropertyTreeCtrl() { return m_Tree; }; + +protected: + DECLARE_MESSAGE_MAP() + +public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, + DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, + CCreateContext* pContext = NULL); + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnPaint(); +}; + + diff --git a/tools/common/PropertyGrid.cpp b/tools/common/PropertyGrid.cpp new file mode 100644 index 000000000..7c7f22e19 --- /dev/null +++ b/tools/common/PropertyGrid.cpp @@ -0,0 +1,665 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" +#include "PropertyGrid.h" + +class rvPropertyGridItem +{ +public: + + rvPropertyGridItem ( ) + { + } + + idStr mName; + idStr mValue; + rvPropertyGrid::EItemType mType; +}; + +/* +================ +rvPropertyGrid::rvPropertyGrid + +constructor +================ +*/ +rvPropertyGrid::rvPropertyGrid ( void ) +{ + mWindow = NULL; + mEdit = NULL; + mListWndProc = NULL; + mSplitter = 100; + mSelectedItem = -1; + mEditItem = -1; + mState = STATE_NORMAL; +} + +/* +================ +rvPropertyGrid::Create + +Create a new property grid control with the given id and parent +================ +*/ +bool rvPropertyGrid::Create ( HWND parent, int id, int style ) +{ + mStyle = style; + + // Create the List view + mWindow = CreateWindowEx ( 0, "LISTBOX", "", WS_VSCROLL|WS_CHILD|WS_VISIBLE|LBS_OWNERDRAWFIXED|LBS_NOINTEGRALHEIGHT|LBS_NOTIFY, 0, 0, 0, 0, parent, (HMENU)id, win32.hInstance, 0 ); + mListWndProc = (WNDPROC)GetWindowLong ( mWindow, GWL_WNDPROC ); + SetWindowLong ( mWindow, GWL_USERDATA, (LONG)this ); + SetWindowLong ( mWindow, GWL_WNDPROC, (LONG)WndProc ); + + LoadLibrary ( "Riched20.dll" ); + mEdit = CreateWindowEx ( 0, "RichEdit20A", "", WS_CHILD, 0, 0, 0, 0, mWindow, (HMENU) 999, win32.hInstance, NULL ); + SendMessage ( mEdit, EM_SETEVENTMASK, 0, ENM_KEYEVENTS ); + + // Set the font of the list box + HDC dc; + LOGFONT lf; + + dc = GetDC ( mWindow ); + ZeroMemory ( &lf, sizeof(lf) ); + lf.lfHeight = -MulDiv(8, GetDeviceCaps(dc, LOGPIXELSY), 72); + strcpy ( lf.lfFaceName, "MS Shell Dlg" ); + SendMessage ( mWindow, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + SendMessage ( mEdit, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + ReleaseDC ( mWindow, dc ); + + RemoveAllItems ( ); + + return true; +} + +/* +================ +rvPropertyGrid::Move + +Move the window +================ +*/ +void rvPropertyGrid::Move ( int x, int y, int w, int h, BOOL redraw ) +{ + MoveWindow ( mWindow, x, y, w, h, redraw ); +} + +/* +================ +rvPropertyGrid::StartEdit + +Start editing +================ +*/ +void rvPropertyGrid::StartEdit ( int item, bool label ) +{ + rvPropertyGridItem* gitem; + RECT rItem; + + gitem = (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, item, 0 ); + if ( NULL == gitem ) + { + return; + } + + SendMessage ( mWindow, LB_GETITEMRECT, item, (LPARAM)&rItem ); + if ( label ) + { + rItem.right = rItem.left + mSplitter - 1; + } + else + { + rItem.left = rItem.left + mSplitter + 1; + } + + mState = STATE_EDIT; + mEditItem = item; + mEditLabel = label; + + SetWindowText ( mEdit, label?gitem->mName:gitem->mValue ); + MoveWindow ( mEdit, rItem.left, rItem.top + 2, + rItem.right - rItem.left, + rItem.bottom - rItem.top - 2, TRUE ); + ShowWindow ( mEdit, SW_SHOW ); + + SetFocus ( mEdit ); +} + +/* +================ +rvPropertyGrid::FinishEdit + +Finish editing by copying the data in the edit control to the internal value +================ +*/ +void rvPropertyGrid::FinishEdit ( void ) +{ + char value[1024]; + rvPropertyGridItem* item; + bool update; + + if ( mState != STATE_EDIT ) + { + return; + } + + assert ( mEditItem >= 0 ); + + mState = STATE_FINISHEDIT; + + update = false; + item = (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, mEditItem, 0 ); + assert ( item ); + + GetWindowText ( mEdit, value, 1023 ); + + if ( !value[0] ) + { + mState = STATE_EDIT; + MessageBeep ( MB_ICONASTERISK ); + return; + } + + if ( !mEditLabel && item->mValue.Cmp ( value ) ) + { + NMPROPGRID nmpg; + nmpg.hdr.code = PGN_ITEMCHANGED; + nmpg.hdr.hwndFrom = mWindow; + nmpg.hdr.idFrom = GetWindowLong ( mWindow, GWL_ID ); + nmpg.mName = item->mName; + nmpg.mValue = value; + + if ( !SendMessage ( GetParent ( mWindow ), WM_NOTIFY, 0, (LONG)&nmpg ) ) + { + mState = STATE_EDIT; + SetFocus ( mEdit ); + return; + } + + // The item may have been destroyed and recreated in the notify call so get it again + item = (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, mEditItem, 0 ); + if ( item ) + { + item->mValue = value; + update = true; + } + } + else if ( mEditLabel && item->mName.Cmp ( value ) ) + { + int sel; + sel = AddItem ( value, "", PGIT_STRING ); + SetCurSel ( sel ); + StartEdit ( sel, false ); + return; + } + + SetCurSel ( mEditItem ); + + mState = STATE_NORMAL; + mEditItem = -1; + + ShowWindow ( mEdit, SW_HIDE ); + SetFocus ( mWindow ); +} + +/* +================ +rvPropertyGrid::CancelEdit + +Stop editing without saving the data +================ +*/ +void rvPropertyGrid::CancelEdit ( void ) +{ + if ( mState == STATE_EDIT && !mEditLabel ) + { + if ( !*GetItemValue ( mEditItem ) ) + { + RemoveItem ( mEditItem ); + } + } + + mSelectedItem = mEditItem; + mEditItem = -1; + mState = STATE_NORMAL; + ShowWindow ( mEdit, SW_HIDE ); + SetFocus ( mWindow ); + SetCurSel ( mSelectedItem ); +} + +/* +================ +rvPropertyGrid::AddItem + +Add a new item to the property grid +================ +*/ +int rvPropertyGrid::AddItem ( const char* name, const char* value, EItemType type ) +{ + rvPropertyGridItem* item; + int insert; + + // Cant add headers if headers arent enabled + if ( type == PGIT_HEADER && !(mStyle&PGS_HEADERS) ) + { + return -1; + } + + item = new rvPropertyGridItem; + item->mName = name; + item->mValue = value; + item->mType = type; + + insert = SendMessage(mWindow,LB_GETCOUNT,0,0) - ((mStyle&PGS_ALLOWINSERT)?1:0); + + return SendMessage ( mWindow, LB_INSERTSTRING, insert, (LONG)item ); +} + +/* +================ +rvPropertyGrid::RemoveItem + +Remove the item at the given index +================ +*/ +void rvPropertyGrid::RemoveItem ( int index ) +{ + if ( index < 0 || index >= SendMessage ( mWindow, LB_GETCOUNT, 0, 0 ) ) + { + return; + } + + delete (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, index, 0 ); + + SendMessage ( mWindow, LB_DELETESTRING, index, 0 ); +} + +/* +================ +rvPropertyGrid::RemoveAllItems + +Remove all items from the property grid +================ +*/ +void rvPropertyGrid::RemoveAllItems ( void ) +{ + int i; + + // free the memory for all the items + for ( i = SendMessage ( mWindow, LB_GETCOUNT, 0, 0 ); i > 0; i -- ) + { + delete (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, i - 1, 0 ); + } + + // remove all items from the listbox itself + SendMessage ( mWindow, LB_RESETCONTENT, 0, 0 ); + + if ( mStyle & PGS_ALLOWINSERT ) + { + // Add the item used to add items + rvPropertyGridItem* item; + item = new rvPropertyGridItem; + item->mName = ""; + item->mValue = ""; + SendMessage ( mWindow, LB_ADDSTRING, 0, (LONG)item ); + } +} + +/* +================ +rvPropertyGrid::GetItemName + +Return name of item at given index +================ +*/ +const char* rvPropertyGrid::GetItemName ( int index ) +{ + rvPropertyGridItem* item; + + item = (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, index, 0 ); + if ( !item ) + { + return ""; + } + + return item->mName; +} + +/* +================ +rvPropertyGrid::GetItemValue + +Return value of item at given index +================ +*/ +const char* rvPropertyGrid::GetItemValue ( int index ) +{ + rvPropertyGridItem* item; + + item = (rvPropertyGridItem*)SendMessage ( mWindow, LB_GETITEMDATA, index, 0 ); + if ( !item ) + { + return ""; + } + + return item->mValue; +} + +/* +================ +rvPropertyGrid::WndProc + +Window procedure for property grid +================ +*/ +LRESULT CALLBACK rvPropertyGrid::WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvPropertyGrid* grid = (rvPropertyGrid*) GetWindowLong ( hWnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_SETFOCUS: +// grid->mEditItem = -1; + break; + + case WM_KEYDOWN: + { + NMKEY nmkey; + nmkey.hdr.code = NM_KEYDOWN; + nmkey.hdr.hwndFrom = grid->mWindow; + nmkey.nVKey = wParam; + nmkey.uFlags = HIWORD(lParam); + nmkey.hdr.idFrom = GetWindowLong ( hWnd, GWL_ID ); + SendMessage ( GetParent ( hWnd ), WM_NOTIFY, nmkey.hdr.idFrom, (LPARAM)&nmkey ); + break; + } + + case WM_CHAR: + { + switch ( wParam ) + { + case VK_RETURN: + if ( grid->mSelectedItem >= 0 ) + { + grid->StartEdit ( grid->mSelectedItem, (*grid->GetItemName ( grid->mSelectedItem ))?false:true); + } + break; + } + break; + } + + case WM_KILLFOCUS: + grid->mSelectedItem = -1; + break; + + case WM_NOTIFY: + { + NMHDR* hdr; + hdr = (NMHDR*)lParam; + if ( hdr->idFrom == 999 ) + { + if ( hdr->code == EN_MSGFILTER ) + { + MSGFILTER* filter; + filter = (MSGFILTER*)lParam; + if ( filter->msg == WM_KEYDOWN ) + { + switch ( filter->wParam ) + { + case VK_RETURN: + case VK_TAB: + grid->FinishEdit ( ); + return 1; + + case VK_ESCAPE: + grid->CancelEdit ( ); + return 1; + } + } + + if ( filter->msg == WM_CHAR || filter->msg == WM_KEYUP ) + { + switch ( filter->wParam ) + { + case VK_RETURN: + case VK_TAB: + case VK_ESCAPE: + return 1; + } + } + } + } + break; + } + + case WM_COMMAND: + if ( lParam == (long)grid->mEdit ) + { + if ( HIWORD(wParam) == EN_KILLFOCUS ) + { + grid->FinishEdit ( ); + return true; + } + } + break; + + case WM_LBUTTONDBLCLK: + grid->mSelectedItem = SendMessage ( hWnd, LB_ITEMFROMPOINT, 0, lParam ); + + // fall through + + case WM_LBUTTONDOWN: + { + int item; + rvPropertyGridItem* gitem; + RECT rItem; + POINT pt; + + if ( grid->mState == rvPropertyGrid::STATE_EDIT ) + { + break; + } + + item = (short)LOWORD(SendMessage ( hWnd, LB_ITEMFROMPOINT, 0, lParam )); + if ( item == -1 ) + { + break; + } + + gitem = (rvPropertyGridItem*)SendMessage ( hWnd, LB_GETITEMDATA, item, 0 ); + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + + SendMessage ( hWnd, LB_GETITEMRECT, item, (LPARAM)&rItem ); + + if ( !gitem->mName.Icmp ( "" ) ) + { + rItem.right = rItem.left + grid->mSplitter - 1; + if ( PtInRect ( &rItem, pt) ) + { + grid->SetCurSel ( item ); + grid->StartEdit ( item, true ); + } + } + else if ( grid->mSelectedItem == item ) + { + rItem.left = rItem.left + grid->mSplitter + 1; + if ( PtInRect ( &rItem, pt) ) + { + grid->StartEdit ( item, false ); + } + } + + if ( grid->mState == rvPropertyGrid::STATE_EDIT ) + { + ClientToScreen ( hWnd, &pt ); + ScreenToClient ( grid->mEdit, &pt ); + SendMessage ( grid->mEdit, WM_LBUTTONDOWN, wParam, MAKELONG(pt.x,pt.y) ); + return 0; + } + + break; + } + + case WM_ERASEBKGND: + { + RECT rClient; + GetClientRect ( hWnd, &rClient ); + FillRect ( (HDC)wParam, &rClient, GetSysColorBrush ( COLOR_3DFACE ) ); + return TRUE; + } + + case WM_SETCURSOR: + { + POINT point; + GetCursorPos ( &point ); + ScreenToClient ( hWnd, &point ); + if ( point.x >= grid->mSplitter - 2 && point.x <= grid->mSplitter + 2 ) + { + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZEWE))); + return TRUE; + } + break; + } + } + + return CallWindowProc ( grid->mListWndProc, hWnd, msg, wParam, lParam ); +} + +/* +================ +rvPropertyGrid::ReflectMessage + +Handle messages sent to the parent window +================ +*/ +bool rvPropertyGrid::ReflectMessage ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_COMMAND: + { + if ( (HWND)lParam == mWindow ) + { + switch ( HIWORD(wParam) ) + { + case LBN_SELCHANGE: + mSelectedItem = SendMessage ( mWindow, LB_GETCURSEL, 0, 0 ); + break; + } + } + break; + } + + case WM_DRAWITEM: + HandleDrawItem ( wParam, lParam ); + return true; + + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT* mis = (MEASUREITEMSTRUCT*) lParam; + mis->itemHeight = 18; + return true; + } + } + + return false; +} + +/* +================ +rvPropertyGrid::HandleDrawItem + +Handle the draw item message +================ +*/ +int rvPropertyGrid::HandleDrawItem ( WPARAM wParam, LPARAM lParam ) +{ + DRAWITEMSTRUCT* dis = (DRAWITEMSTRUCT*) lParam; + rvPropertyGridItem* item = (rvPropertyGridItem*) dis->itemData; + RECT rTemp; + HBRUSH brush; + + if ( !item ) + { + return 0; + } + + rTemp = dis->rcItem; + if ( mStyle & PGS_HEADERS ) + { + brush = GetSysColorBrush ( COLOR_SCROLLBAR ); + rTemp.right = rTemp.left + 10; + FillRect ( dis->hDC, &rTemp, brush ); + rTemp.left = rTemp.right; + rTemp.right = dis->rcItem.right; + } + + if ( item->mType == PGIT_HEADER ) + { + brush = GetSysColorBrush ( COLOR_SCROLLBAR ); + } + else if ( dis->itemState & ODS_SELECTED ) + { + brush = GetSysColorBrush ( COLOR_HIGHLIGHT ); + } + else + { + brush = GetSysColorBrush ( COLOR_WINDOW ); + } + + FillRect ( dis->hDC, &rTemp, brush ); + + HPEN pen = CreatePen ( PS_SOLID, 1, GetSysColor ( COLOR_SCROLLBAR ) ); + HPEN oldpen = (HPEN)SelectObject ( dis->hDC, pen ); + MoveToEx ( dis->hDC, dis->rcItem.left, dis->rcItem.top, NULL ); + LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.top ); + MoveToEx ( dis->hDC, dis->rcItem.left, dis->rcItem.bottom, NULL ); + LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.bottom); + + if ( item->mType != PGIT_HEADER ) + { + MoveToEx ( dis->hDC, dis->rcItem.left + mSplitter, dis->rcItem.top, NULL ); + LineTo ( dis->hDC, dis->rcItem.left + mSplitter, dis->rcItem.bottom ); + } + SelectObject ( dis->hDC, oldpen ); + DeleteObject ( pen ); + + int colorIndex = ( (dis->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT ); + SetTextColor ( dis->hDC, GetSysColor ( colorIndex ) ); + SetBkMode ( dis->hDC, TRANSPARENT ); + SetBkColor ( dis->hDC, GetSysColor ( COLOR_3DFACE ) ); + + RECT rText; + rText = rTemp; + rText.right = rText.left + mSplitter; + rText.left += 2; + + DrawText ( dis->hDC, item->mName, item->mName.Length(), &rText, DT_LEFT|DT_VCENTER|DT_SINGLELINE ); + + rText.left = dis->rcItem.left + mSplitter + 2; + rText.right = dis->rcItem.right; + DrawText ( dis->hDC, item->mValue, item->mValue.Length(), &rText, DT_LEFT|DT_VCENTER|DT_SINGLELINE ); + + return 0; +} \ No newline at end of file diff --git a/tools/common/PropertyGrid.h b/tools/common/PropertyGrid.h new file mode 100644 index 000000000..808826d23 --- /dev/null +++ b/tools/common/PropertyGrid.h @@ -0,0 +1,114 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef PROPERTYGRID_H_ +#define PROPERTYGRID_H_ + +#define PGN_ITEMCHANGED 100 + +#define PGS_HEADERS 0x00000001 +#define PGS_ALLOWINSERT 0x00000002 + +typedef struct +{ + NMHDR hdr; + int mItem; + const char* mName; + const char* mValue; + +} NMPROPGRID; + +class rvPropertyGrid +{ +public: + + enum EItemType + { + PGIT_STRING, + PGIT_HEADER, + PGIT_MAX + }; + + rvPropertyGrid ( ); + + bool Create ( HWND parent, int id, int style = 0 ); + + void Move ( int x, int y, int w, int h, BOOL redraw = FALSE ); + + bool ReflectMessage ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + + int AddItem ( const char* name, const char* value, EItemType type = PGIT_STRING ); + + void RemoveItem ( int index ); + void RemoveAllItems ( void ); + + void SetCurSel ( int index ); + int GetCurSel ( void ); + + HWND GetWindow ( void ); + const char* GetItemName ( int index ); + const char* GetItemValue ( int index ); + +protected: + + enum EState + { + STATE_FINISHEDIT, + STATE_EDIT, + STATE_NORMAL, + }; + + void StartEdit ( int item, bool label ); + void FinishEdit ( void ); + void CancelEdit ( void ); + + int HandleDrawItem ( WPARAM wParam, LPARAM lParam ); + + HWND mWindow; + HWND mEdit; + int mEditItem; + bool mEditLabel; + int mSelectedItem; + WNDPROC mListWndProc; + int mSplitter; + int mStyle; + EState mState; + +private: + + static LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); +}; + +inline HWND rvPropertyGrid::GetWindow ( void ) +{ + return mWindow; +} + +inline int rvPropertyGrid::GetCurSel ( void ) +{ + return SendMessage ( mWindow, LB_GETCURSEL, 0, 0 ); +} + +inline void rvPropertyGrid::SetCurSel ( int index ) +{ + SendMessage ( mWindow, LB_SETCURSEL, index, 0 ); + mSelectedItem = index; +} + +#endif // PROPERTYGRID_H_ diff --git a/tools/common/RegistryOptions.cpp b/tools/common/RegistryOptions.cpp new file mode 100644 index 000000000..80fe79317 --- /dev/null +++ b/tools/common/RegistryOptions.cpp @@ -0,0 +1,327 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "RegistryOptions.h" + +/* +================ +rvRegistryOptions::rvRegistryOptions + +Constructor +================ +*/ +rvRegistryOptions::rvRegistryOptions( void ) { +} + +/* +================ +rvRegistryOptions::Init +================ +*/ +void rvRegistryOptions::Init( const char *key ) { + mBaseKey = key; +} + +/* +================ +rvRegistryOptions::Save + +Write the options to the registry +================ +*/ +bool rvRegistryOptions::Save ( void ) +{ + HKEY hKey; + int i; + + // Create the top level key + if ( ERROR_SUCCESS != RegCreateKeyEx ( HKEY_LOCAL_MACHINE, mBaseKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL ) ) + { + return false; + } + + // Write out the values + for ( i = 0; i < mValues.GetNumKeyVals(); i ++ ) + { + const idKeyValue* key = mValues.GetKeyVal ( i ); + assert ( key ); + RegSetValueEx ( hKey, key->GetKey().c_str(), 0, REG_SZ, (BYTE*)key->GetValue().c_str(), key->GetValue().Length() ); + } + + // Write Recent Files + for ( i = 0; i < mRecentFiles.Num(); i ++ ) + { + RegSetValueEx ( hKey, va("mru%d",i), 0, REG_SZ, (BYTE*)mRecentFiles[i].c_str(), mRecentFiles[i].Length() ); + } + + return true; +} + +/* +================ +rvRegistryOptions::Load + +Read the options from the registry +================ +*/ +bool rvRegistryOptions::Load ( void ) +{ + HKEY hKey; + char temp[MAX_PATH]; + TCHAR keyname[MAX_PATH]; + DWORD dwType; + DWORD dwSize; + int i; + + mValues.Clear ( ); + mRecentFiles.Clear ( ); + + if ( ERROR_SUCCESS != RegOpenKeyEx ( HKEY_LOCAL_MACHINE, mBaseKey, 0, KEY_READ, &hKey ) ) + { + return false; + } + + // Read in the values and recent files + keyname[0] = 0; + dwSize = MAX_PATH; + for ( i = 0; RegEnumValue ( hKey, i, keyname, &dwSize, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS; i ++ ) + { + temp[0] = '\0'; + dwSize = MAX_PATH; + + if ( ERROR_SUCCESS != RegQueryValueEx ( hKey, keyname, NULL, &dwType, (LPBYTE)temp, &dwSize ) ) + { + continue; + } + + dwSize = MAX_PATH; + + // Skip the mru values + if( !idStr(keyname).IcmpPrefix ( "mru" ) ) + { + continue; + } + + mValues.Set ( keyname, temp ); + } + + // Read Recent Files + for ( i = 0; i < MAX_MRU_SIZE; i ++ ) + { + dwSize = MAX_PATH; + if ( ERROR_SUCCESS != RegQueryValueEx ( hKey, va("mru%d", i ), NULL, &dwType, (LPBYTE)temp, &dwSize ) ) + { + continue; + } + + AddRecentFile ( temp ); + } + + return true; +} + +/* +================ +rvRegistryOptions::SetWindowPlacement + +Set a window placement in the options +================ +*/ +void rvRegistryOptions::SetWindowPlacement ( const char* name, HWND hwnd ) +{ + WINDOWPLACEMENT wp; + + wp.length = sizeof(wp); + ::GetWindowPlacement ( hwnd, &wp ); + + idStr out; + + out = va("%d %d %d %d %d %d %d %d %d %d", + wp.flags, + wp.ptMaxPosition.x, + wp.ptMaxPosition.y, + wp.ptMinPosition.x, + wp.ptMinPosition.y, + wp.rcNormalPosition.left, + wp.rcNormalPosition.top, + wp.rcNormalPosition.right, + wp.rcNormalPosition.bottom, + wp.showCmd ); + + mValues.Set ( name, out ); +} + +/* +================ +rvRegistryOptions::GetWindowPlacement + +Retrieve a window placement from the options +================ +*/ +bool rvRegistryOptions::GetWindowPlacement ( const char* name, HWND hwnd ) +{ + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + + const idKeyValue* key = mValues.FindKey ( name ); + if ( !key ) + { + return false; + } + + sscanf ( key->GetValue().c_str(), "%d %d %d %d %d %d %d %d %d %d", + &wp.flags, + &wp.ptMaxPosition.x, + &wp.ptMaxPosition.y, + &wp.ptMinPosition.x, + &wp.ptMinPosition.y, + &wp.rcNormalPosition.left, + &wp.rcNormalPosition.top, + &wp.rcNormalPosition.right, + &wp.rcNormalPosition.bottom, + &wp.showCmd ); + + ::SetWindowPlacement ( hwnd, &wp ); + + return true; +} + +/* +================ +rvRegistryOptions::AddRecentFile + +Adds the given filename to the MRU list +================ +*/ +void rvRegistryOptions::AddRecentFile ( const char* filename ) +{ + int i; + + idStr path = filename; + + // Remove duplicates first + for ( i = mRecentFiles.Num() - 1; i >= 0; i -- ) + { + if ( !mRecentFiles[i].Icmp ( filename ) ) + { + mRecentFiles.RemoveIndex ( i ); + break; + } + } + + // Alwasy trip to the max MRU size + while ( mRecentFiles.Num ( ) >= MAX_MRU_SIZE ) + { + mRecentFiles.RemoveIndex ( 0 ); + } + + mRecentFiles.Append ( path ); +} + +/* +================ +rvRegistryOptions::SetColumnWidths + +Set a group of column widths in the options +================ +*/ +void rvRegistryOptions::SetColumnWidths ( const char* name, HWND list ) +{ + LVCOLUMN col; + int index; + idStr widths; + + col.mask = LVCF_WIDTH; + + for ( index = 0; ListView_GetColumn ( list, index, &col ); index ++ ) + { + widths += va("%d ", col.cx ); + } + + mValues.Set ( name, widths ); +} + +/* +================ +rvRegistryOptions::GetColumnWidths + +Retrieve a group of column widths from the options +================ +*/ +void rvRegistryOptions::GetColumnWidths ( const char* name, HWND list ) +{ + idStr widths; + const char* parse; + const char* next; + int index; + + widths = mValues.GetString ( name ); + parse = widths; + index = 0; + + while ( NULL != (next = strchr ( parse, ' ' ) ) ) + { + int width; + + sscanf ( parse, "%d", &width ); + parse = next + 1; + + ListView_SetColumnWidth ( list, index++, width ); + } +} + +/* +================ +rvRegistryOptions::SetBinary + +Set binary data for the given key +================ +*/ +void rvRegistryOptions::SetBinary ( const char* name, const unsigned char* data, int size ) +{ + idStr binary; + for ( size --; size >= 0; size --, data++ ) + { + binary += va("%02x", *data ); + } + + mValues.Set ( name, binary ); +} + +/* +================ +rvRegistryOptions::GetBinary + +Get the binary data for a given key +================ +*/ +void rvRegistryOptions::GetBinary ( const char* name, unsigned char* data, int size ) +{ + const char* parse; + parse = mValues.GetString ( name ); + for ( size --; size >= 0 && *parse && *(parse+1); size --, parse += 2, data ++ ) + { + int value; + sscanf ( parse, "%02x", &value ); + *data = (unsigned char)value; + } +} diff --git a/tools/common/RegistryOptions.h b/tools/common/RegistryOptions.h new file mode 100644 index 000000000..d4eb42685 --- /dev/null +++ b/tools/common/RegistryOptions.h @@ -0,0 +1,135 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef REGISTRYOPTIONS_H_ +#define REGISTRYOPTIONS_H_ + +class rvRegistryOptions +{ +public: + + static const int MAX_MRU_SIZE = 4; + + rvRegistryOptions(); + + void Init( const char *key ); + + // Write the options to the registery + bool Save ( void ); + + // Read the options from the registry + bool Load ( void ); + + // Window placement routines + void SetWindowPlacement ( const char* name, HWND hwnd ); + bool GetWindowPlacement ( const char* name, HWND hwnd ); + + // List view column sizes + void SetColumnWidths ( const char* name, HWND list ); + void GetColumnWidths ( const char* name, HWND list ); + + // Set routines + void SetFloat ( const char* name, float v ); + void SetLong ( const char* name, long v ); + void SetBool ( const char* name, bool v ); + void SetString ( const char* name, const char* v ); + void SetVec4 ( const char* name, idVec4& v ); + void SetBinary ( const char* name, const unsigned char* data, int size ); + + // Get routines + float GetFloat ( const char* name ); + long GetLong ( const char* name ); + bool GetBool ( const char* name ); + const char* GetString ( const char* name ); + idVec4 GetVec4 ( const char* name ); + void GetBinary ( const char* name, unsigned char* data, int size ); + + // MRU related methods + void AddRecentFile ( const char* filename ); + const char* GetRecentFile ( int index ); + int GetRecentFileCount ( void ); + +private: + + idList mRecentFiles; + idDict mValues; + idStr mBaseKey; +}; + +ID_INLINE void rvRegistryOptions::SetFloat ( const char* name, float v ) +{ + mValues.SetFloat ( name, v ); +} + +ID_INLINE void rvRegistryOptions::SetLong ( const char* name, long v ) +{ + mValues.SetInt ( name, v ); +} + +ID_INLINE void rvRegistryOptions::SetBool ( const char* name, bool v ) +{ + mValues.SetBool ( name, v ); +} + +ID_INLINE void rvRegistryOptions::SetString ( const char* name, const char* v ) +{ + mValues.Set ( name, v ); +} + +ID_INLINE void rvRegistryOptions::SetVec4 ( const char* name, idVec4& v ) +{ + mValues.SetVec4 ( name, v ); +} + +ID_INLINE float rvRegistryOptions::GetFloat ( const char* name ) +{ + return mValues.GetFloat ( name ); +} + +ID_INLINE long rvRegistryOptions::GetLong ( const char* name ) +{ + return mValues.GetInt ( name ); +} + +ID_INLINE bool rvRegistryOptions::GetBool ( const char* name ) +{ + return mValues.GetBool ( name ); +} + +ID_INLINE const char* rvRegistryOptions::GetString ( const char* name ) +{ + return mValues.GetString ( name ); +} + +ID_INLINE idVec4 rvRegistryOptions::GetVec4 ( const char* name ) +{ + return mValues.GetVec4 ( name ); +} + +ID_INLINE int rvRegistryOptions::GetRecentFileCount ( void ) +{ + return mRecentFiles.Num ( ); +} + +ID_INLINE const char* rvRegistryOptions::GetRecentFile ( int index ) +{ + return mRecentFiles[index].c_str ( ); +} + +#endif // REGISTRYOPTIONS_H_ diff --git a/tools/common/RenderBumpFlatDialog.cpp b/tools/common/RenderBumpFlatDialog.cpp new file mode 100644 index 000000000..50994ea3b --- /dev/null +++ b/tools/common/RenderBumpFlatDialog.cpp @@ -0,0 +1,101 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/common_resource.h" + +idCVar rbfg_DefaultWidth( "rbfg_DefaultWidth", "0", 0, "" ); +idCVar rbfg_DefaultHeight( "rbfg_DefaultHeight", "0", 0, "" ); + +static idStr RBFName; + +static bool CheckPow2(int Num) +{ + while(Num) + { + if ((Num & 1) && (Num != 1)) + { + return false; + } + + Num >>= 1; + } + + return true; +} + +extern void Com_WriteConfigToFile( const char *filename ); + +static BOOL CALLBACK RBFProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + SetDlgItemInt(hwndDlg, IDC_RBF_WIDTH, rbfg_DefaultWidth.GetInteger(), FALSE); + SetDlgItemInt(hwndDlg, IDC_RBF_HEIGHT, rbfg_DefaultHeight.GetInteger(), FALSE); + SetDlgItemText(hwndDlg, IDC_RBF_FILENAME, RBFName); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + int width, height; + + width = GetDlgItemInt(hwndDlg, IDC_RBF_WIDTH, 0, FALSE); + height = GetDlgItemInt(hwndDlg, IDC_RBF_HEIGHT, 0, FALSE); + + rbfg_DefaultWidth.SetInteger( width ); + rbfg_DefaultHeight.SetInteger( height ); + + Com_WriteConfigToFile( CONFIG_FILE ); + + if (!CheckPow2(width) || !CheckPow2(height)) + { + return TRUE; + } + + DestroyWindow(hwndDlg); + + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, va("renderbumpflat -size %d %d %s\n", width, height, RBFName.c_str() ) ); + return TRUE; + } + + case IDCANCEL: + DestroyWindow(hwndDlg); + return TRUE; + } + } + + return FALSE; +} + +void DoRBFDialog(const char *FileName) +{ + RBFName = FileName; + + Sys_GrabMouseCursor( false ); + + DialogBox(0, MAKEINTRESOURCE(IDD_RENDERBUMPFLAT), 0, (DLGPROC)RBFProc); + + Sys_GrabMouseCursor( true ); +} diff --git a/tools/common/RenderBumpFlatDialog.h b/tools/common/RenderBumpFlatDialog.h new file mode 100644 index 000000000..03199f7b6 --- /dev/null +++ b/tools/common/RenderBumpFlatDialog.h @@ -0,0 +1,26 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __RENDERBUMPFLATDIALOG_H +#define __RENDERBUMPFLATDIALOG_H + +void DoRBFDialog(const char *FileName); + +#endif // __RENDERBUMPFLATDIALOG_H + diff --git a/tools/common/RollupPanel.cpp b/tools/common/RollupPanel.cpp new file mode 100644 index 000000000..8428aff4f --- /dev/null +++ b/tools/common/RollupPanel.cpp @@ -0,0 +1,1206 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" +#include "RollupPanel.h" + +// Based on original code by Johann Nadalutti + +#define RP_PGBUTTONHEIGHT 18 +#define RP_SCROLLBARWIDTH 6 +#define RP_GRPBOXINDENT 6 +#define RP_SCROLLBARCOLOR RGB(150,180,180) +#define RP_ROLLCURSOR MAKEINTRESOURCE(32649) // see IDC_HAND (WINVER >= 0x0500) + +//Popup Menu Ids +#define RP_IDM_EXPANDALL 0x100 +#define RP_IDM_COLLAPSEALL 0x101 +#define RP_IDM_STARTITEMS 0x102 + +idList rvRollupPanel::mDialogs; +HHOOK rvRollupPanel::mDialogHook = NULL; + +#define DEFERPOS + +/* +================ +rvRollupPanel::rvRollupPanel + +constructor +================ +*/ +rvRollupPanel::rvRollupPanel ( void ) +{ + mStartYPos = 0; + mItemHeight = 0; + mWindow = NULL; +} + +/* +================ +rvRollupPanel::~rvRollupPanel + +destructor +================ +*/ +rvRollupPanel::~rvRollupPanel ( void ) +{ + // destroy the items + for ( ; mItems.Num(); ) + { + _RemoveItem ( 0 ); + } +} + +/* +================ +rvRollupPanel::Create + +Create the rollup panel window +================ +*/ +bool rvRollupPanel::Create ( DWORD dwStyle, const RECT& rect, HWND parent, unsigned int id ) +{ + WNDCLASSEX wndClass; + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "ROLLUP_PANEL"; + wndClass.lpfnWndProc = WindowProc; + wndClass.hbrBackground = (HBRUSH)GetSysColorBrush ( COLOR_3DFACE ); + wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); + wndClass.lpszMenuName = NULL; + wndClass.hInstance = win32.hInstance; + wndClass.style = CS_VREDRAW | CS_HREDRAW; + RegisterClassEx ( &wndClass ); + + mWindow = CreateWindowEx ( WS_EX_TOOLWINDOW, + "ROLLUP_PANEL", + "", + dwStyle|WS_CLIPSIBLINGS, + rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, + parent, + NULL, + win32.hInstance, + this ); + + if ( !mWindow ) + { + return false; + } + + return true; +} + +/* +================ +rvRollupPanel::InsertItem + +Insert and item into the rollup panel. Return -1 if an error occured +================ +*/ +int rvRollupPanel::InsertItem ( const char* caption, HWND dialog, bool autoDestroy, int index ) +{ + assert ( caption ); + assert ( dialog ); + + // -1 means add to the end + if ( index > 0 && index >= mItems.Num() ) + { + index = -1; + } + + // Get client rect + RECT r; + GetClientRect(mWindow,&r); + + // Create the GroupBox control + HWND groupbox = CreateWindow ( "BUTTON", "", WS_CHILD|BS_GROUPBOX, + r.left, r.top, r.right-r.left, r.bottom-r.top, + mWindow, 0, win32.hInstance, NULL ); + + // Create the expand button + HWND button = CreateWindow ( "BUTTON", caption, WS_CHILD|BS_AUTOCHECKBOX|BS_PUSHLIKE|BS_FLAT, + r.left, r.top, r.right-r.left, r.bottom-r.top, + mWindow, 0, win32.hInstance, NULL ); + + // Change the button's font + SendMessage ( button, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0 ); + + // Add item to the item list + RPITEM* item = new RPITEM; + item->mExpanded = false; + item->mEnable = true; + item->mDialog = dialog; + item->mButton = button; + item->mGroupBox = groupbox; + item->mOldDlgProc = (WNDPROC) GetWindowLong ( dialog, DWL_DLGPROC ); + item->mOldButtonProc = (WNDPROC) GetWindowLong ( button, GWL_WNDPROC ); + item->mAutoDestroy = autoDestroy; + strcpy ( item->mCaption, caption ); + + if ( index < 0 ) + { + index = mItems.Append ( item ); + } + else + { + mItems.Insert ( item, index ); + } + + // Store data with the dialog window in its user data + SetWindowLong ( dialog, GWL_USERDATA, (LONG)item ); + + // Attach item to button through user data + SetWindowLong ( button, GWL_USERDATA, (LONG)item ); + SetWindowLong ( button, GWL_ID, index ); + + // Subclass dialog + SetWindowLong ( dialog, DWL_DLGPROC, (LONG)DialogProc ); + + // SubClass button + SetWindowLong ( button, GWL_WNDPROC, (LONG)ButtonProc ); + + // Update + mItemHeight += RP_PGBUTTONHEIGHT+(RP_GRPBOXINDENT/2); + RecallLayout ( ); + + // One hook for all panel dialogs + if ( !mDialogHook ) + { + mDialogHook = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId() ); + } + + mDialogs.Append ( dialog ); + + return index; +} + +/* +================ +rvRollupPanel::RemoveItem + +Remove the item at the given index from the rollup panel +================ +*/ +void rvRollupPanel::RemoveItem ( int index ) +{ + // safety check + if ( index >= mItems.Num() || index < 0 ) + { + return; + } + + // remove the item + _RemoveItem( index ); + + // update the layout + RecallLayout ( ); +} + +/* +================ +rvRollupPanel::RemoveAllItems + +Remove all items from the control +================ +*/ +void rvRollupPanel::RemoveAllItems() +{ + for ( ; mItems.Num(); ) + { + _RemoveItem ( 0 ); + } + + // update layout + RecallLayout ( ); +} + +/* +================ +rvRollupPanel::_RemoveItem + +called by RemoveItem and RemoveAllItems methods to acutally remove the item +================ +*/ +void rvRollupPanel::_RemoveItem ( int index ) +{ + RPITEM* item = mItems[index]; + + // get the item rect + RECT ir; + GetWindowRect ( item->mDialog, &ir ); + + // update item height + mItemHeight -= RP_PGBUTTONHEIGHT+(RP_GRPBOXINDENT/2); + if ( item->mExpanded ) + { + mItemHeight -= (ir.bottom-ir.top); + } + + // destroy windows + if ( item->mButton ) + { + DestroyWindow ( item->mButton ); + } + if ( item->mGroupBox ) + { + DestroyWindow ( item->mGroupBox ); + } + if ( item->mDialog && item->mAutoDestroy ) + { + DestroyWindow ( item->mDialog ); + mDialogs.Remove ( item->mDialog ); + } + + if ( mDialogs.Num () <= 0 ) + { + UnhookWindowsHookEx( mDialogHook ); + mDialogHook = NULL; + } + + // finish up + mItems.RemoveIndex ( index ); + delete item; +} + +/* +================ +rvRollupPanel::ExpandItem + +expand or collapse the item at the given index +================ +*/ +void rvRollupPanel::ExpandItem( int index, bool expand ) +{ + // safety check + if ( index >= mItems.Num() || index < 0 ) + { + return; + } + + _ExpandItem ( mItems[index], expand ); + + RecallLayout ( ); + + // scroll to this page (automatic page visibility) + if ( expand ) + { + ScrollToItem ( index, false ); + } +} + +/* +================ +rvRollupPanel::ExpandItem + +expand or collapse the item at the given index +================ +*/ +void rvRollupPanel::ExpandAllItems( bool expand ) +{ + int i; + + // expand all items + for ( i=0; i < mItems.Num(); i ++ ) + { + _ExpandItem ( mItems[i], expand ); + } + + RecallLayout(); +} + +/* +================ +rvRollupPanel::ExpandItem + +expand or collapse the item at the given index +================ +*/ +void rvRollupPanel::_ExpandItem ( RPITEM* item, bool expand ) +{ + // check if we need to change state + if ( item->mExpanded == expand || !item->mEnable ) + { + return; + } + + RECT ir; + GetWindowRect ( item->mDialog, &ir ); + + // Expand-collapse + item->mExpanded = expand; + + if ( expand ) + { + mItemHeight += (ir.bottom - ir.top); + } + else + { + mItemHeight -= (ir.bottom - ir.top); + } +} + +/* +================ +rvRollupPanel::EnableItem + +enable/disable the item at the given index +================ +*/ +void rvRollupPanel::EnableItem ( int index, bool enable ) +{ + // safety check + if ( index >= mItems.Num() || index < 0 ) + { + return; + } + + _EnableItem ( mItems[index], enable ); + RecallLayout ( ); +} + +/* +================ +rvRollupPanel::EnableAllItems + +enable/disable all items in the panel +================ +*/ +void rvRollupPanel::EnableAllItems ( bool enable ) +{ + int i; + + for ( i=0; i < mItems.Num(); i++ ) + { + _EnableItem ( mItems[i], enable ); + } + + RecallLayout ( ); +} + +/* +================ +rvRollupPanel::_EnableItem + +Called by EnableItem and EnableAllItems to do the work of enabling/disablgin +the window +================ +*/ +void rvRollupPanel::_EnableItem ( RPITEM* item, bool enable ) +{ + // check if we need to change state + if ( item->mEnable == enable ) + { + return; + } + + RECT ir; + GetWindowRect ( item->mDialog, &ir ); + + item->mEnable = enable; + + if ( item->mExpanded ) + { + mItemHeight -= (ir.bottom-ir.top); + item->mExpanded = false; + } +} + +/* +================ +rvRollupPanel::ScrollToItem + +Scroll a page at the top of the Rollup Panel if top = true or just ensure +item visibility into view if top = false +================ +*/ +void rvRollupPanel::ScrollToItem ( int index, bool top ) +{ + // safety check + if ( index >= mItems.Num() || index < 0 ) + { + return; + } + + RPITEM* item = mItems[index]; + + // get rects + RECT r; + RECT ir; + GetWindowRect ( mWindow, &r ); + GetWindowRect ( item->mDialog, &ir ); + + // check page visibility + if ( top || ((ir.bottom > r.bottom) || (ir.top < r.top))) + { + // compute new mStartYPos + GetWindowRect( item->mButton, &ir ); + mStartYPos -= (ir.top-r.top); + + RecallLayout(); + } +} + +/* +================ +rvRollupPanel::MoveItemAt + +newIndex can be equal to -1 (move at end) +return -1 if an error occurs +================ +*/ +int rvRollupPanel::MoveItemAt ( int index, int newIndex ) +{ + if ( index == newIndex || index >= mItems.Num() || index < 0 ) + { + return -1; + } + + // remove page from its old position + RPITEM* item = mItems[index]; + mItems.RemoveIndex ( index ); + + // insert at its new position + if ( newIndex < 0 ) + { + index = mItems.Append( item ); + } + else + { + mItems.Insert ( item, newIndex ); + index = newIndex; + } + + RecallLayout ( ); + + return index; +} + +/* +================ +rvRollupPanel::RecallLayout + +Update the layout of the control based on current states +================ +*/ +void rvRollupPanel::RecallLayout ( void ) +{ + int bottomPagePos; + RECT r; + int posy; + int i; + + // check StartPosY + GetClientRect ( mWindow, &r ); + bottomPagePos = mStartYPos + mItemHeight; + + if ( bottomPagePos < r.bottom-r.top ) + { + mStartYPos = (r.bottom-r.top) - mItemHeight; + } + if ( mStartYPos > 0 ) + { + mStartYPos = 0; + } + + // update layout +#ifdef DEFERPOS + HDWP hdwp; + hdwp = BeginDeferWindowPos ( mItems.Num() * 3 ); +#endif + posy = mStartYPos; + + for ( i=0; i < mItems.Num(); i++ ) + { + RPITEM* item = mItems[i]; + + // enable / disable button + SendMessage ( item->mButton, BM_SETCHECK, (item->mEnable&item->mExpanded)?BST_CHECKED:BST_UNCHECKED, 0 ); + EnableWindow ( item->mButton, item->mEnable ); + + // Expanded + if ( item->mExpanded && item->mEnable ) + { + RECT ir; + GetWindowRect ( item->mDialog, &ir ); + + // update GroupBox position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mGroupBox, 0, 2, posy, + (r.right-r.left)-3-RP_SCROLLBARWIDTH, + (ir.bottom-ir.top)+RP_PGBUTTONHEIGHT+RP_GRPBOXINDENT-4, + SWP_NOZORDER|SWP_SHOWWINDOW); + + //Update Dialog position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mDialog, 0, RP_GRPBOXINDENT, posy+RP_PGBUTTONHEIGHT, + (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2), + ir.bottom-ir.top, SWP_NOZORDER|SWP_SHOWWINDOW); + + //Update Button's position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mButton, 0, RP_GRPBOXINDENT, posy, + (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2), + RP_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW); + + posy += (ir.bottom-ir.top) + RP_PGBUTTONHEIGHT; + } + // collapsed + else + { + // update GroupBox position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mGroupBox, 0, 2, posy, + (r.right-r.left)-3-RP_SCROLLBARWIDTH, 16, SWP_NOZORDER|SWP_SHOWWINDOW); + + // update Dialog position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mDialog, 0, RP_GRPBOXINDENT, 0, 0, 0,SWP_NOZORDER|SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE); + + // update Button's position and size +#ifdef DEFERPOS + DeferWindowPos ( hdwp, +#else + SetWindowPos ( +#endif + item->mButton, 0, RP_GRPBOXINDENT, posy, + (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2), + RP_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW); + + posy += RP_PGBUTTONHEIGHT; + } + + posy += (RP_GRPBOXINDENT/2); + + } + +#ifdef DEFERPOS + EndDeferWindowPos ( hdwp ); +#endif + + // update Scroll Bar + RECT br; + SetRect ( &br, r.right-RP_SCROLLBARWIDTH,r.top,r.right,r.bottom); + InvalidateRect( mWindow, &br, FALSE ); + UpdateWindow ( mWindow ); +} + +/* +================ +rvRollupPanel::GetItemIndex + +Return -1 if no matching item was found, otherwise the index of the item +================ +*/ +int rvRollupPanel::GetItemIndex ( HWND wnd ) +{ + int i; + + //Search matching button's hwnd + for ( i=0; i < mItems.Num(); i++ ) + { + if ( wnd == mItems[i]->mButton ) + { + return i; + } + } + + return -1; +} + +int rvRollupPanel::GetItemIndex ( const char* caption ) +{ + int i; + + //Search matching button's hwnd + for ( i=0; i < mItems.Num(); i++ ) + { + if ( !idStr::Icmp ( caption, mItems[i]->mCaption ) ) + { + return i; + } + } + + return -1; +} + +/* +================ +rvRollupPanel::GetItem + +Return NULL if the index is invalid +================ +*/ +RPITEM* rvRollupPanel::GetItem ( int index ) +{ + // safety check + if ( index >= mItems.Num() || index < 0 ) + { + return NULL; + } + + return mItems[index]; +} + +/* +================ +rvRollupPanel::DialogProc + +Dialog procedure for items +================ +*/ +LRESULT CALLBACK rvRollupPanel::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + RPITEM* item = (RPITEM*)GetWindowLong ( hWnd, GWL_USERDATA ); + rvRollupPanel* _this = (rvRollupPanel*)GetWindowLong ( GetParent ( hWnd ), GWL_USERDATA ); + + RECT r; + GetClientRect ( _this->mWindow, &r ); + + if ( _this->mItemHeight > r.bottom-r.top ) + { + switch (uMsg) + { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + { + POINT pos; + GetCursorPos ( &pos ); + _this->mOldMouseYPos = pos.y; + ::SetCapture(hWnd); + return 0; + } + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + { + if ( ::GetCapture() == hWnd ) + { + ::ReleaseCapture(); + return 0; + } + break; + } + + case WM_MOUSEMOVE: + if ( (::GetCapture() == hWnd) && (wParam==MK_LBUTTON || wParam==MK_MBUTTON)) + { + POINT pos; + GetCursorPos(&pos); + _this->mStartYPos += (pos.y-_this->mOldMouseYPos); + _this->RecallLayout(); + _this->mOldMouseYPos = pos.y; + InvalidateRect ( _this->mWindow, NULL, TRUE ); + return 0; + } + + break; + + case WM_SETCURSOR: + if ( (HWND)wParam == hWnd) + { + SetCursor ( LoadCursor (NULL, RP_ROLLCURSOR) ); + return TRUE; + } + break; + } + } + + return ::CallWindowProc ( item->mOldDlgProc, hWnd, uMsg, wParam, lParam ); +} + +/* +================ +rvRollupPanel::DialogProc + +Button procedure for items +================ +*/ +LRESULT CALLBACK rvRollupPanel::ButtonProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if ( uMsg == WM_SETFOCUS ) + { + return FALSE; + } + + RPITEM* item = (RPITEM*)GetWindowLong(hWnd, GWL_USERDATA); + return ::CallWindowProc( item->mOldButtonProc, hWnd, uMsg, wParam, lParam ); +} + +/* +================ +rvRollupPanel::WindowProc + +Window procedure for rollup panel +================ +*/ +LRESULT CALLBACK rvRollupPanel::WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + rvRollupPanel* panel; + panel = (rvRollupPanel*)GetWindowLong (hWnd, GWL_USERDATA); + + switch ( uMsg ) + { + case WM_CREATE: + { + LPCREATESTRUCT cs; + + // Attach the class to the window first + cs = (LPCREATESTRUCT) lParam; + panel = (rvRollupPanel*) cs->lpCreateParams; + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)panel ); + break; + } + + case WM_COMMAND: + panel->HandleCommand ( wParam, lParam ); + break; + + case WM_PAINT: + return panel->HandlePaint ( wParam, lParam ); + + case WM_SIZE: + return panel->HandleSize ( wParam, lParam ); + + case WM_LBUTTONDOWN: + panel->HandleLButtonDown ( wParam, lParam ); + break; + + case WM_LBUTTONUP: + panel->HandleLButtonUp ( wParam, lParam ); + break; + + case WM_MOUSEMOVE: + panel->HandleMouseMove ( wParam, lParam ); + break; + + case WM_MOUSEWHEEL: + panel->HandleMouseWheel ( wParam, lParam ); + break; + + case WM_MOUSEACTIVATE: + panel->HandleMouseActivate ( wParam, lParam ); + break; + + case WM_CONTEXTMENU: + return panel->HandleContextMenu ( wParam, lParam ); + } + + return DefWindowProc ( hWnd, uMsg, wParam, lParam ); +} + +/* +================ +rvRollupPanel::HandleCommand + +Handle the WM_COMMAND message +================ +*/ +int rvRollupPanel::HandleCommand ( WPARAM wParam, LPARAM lParam ) +{ + // popup menu command to expand or collapse pages + if ( LOWORD(wParam) == RP_IDM_EXPANDALL ) + { + ExpandAllItems ( true ); + } + else if ( LOWORD(wParam) == RP_IDM_COLLAPSEALL ) + { + ExpandAllItems ( false ); + } + + // popupMenu command to expand page + else if ( LOWORD(wParam) >= RP_IDM_STARTITEMS && + LOWORD(wParam) < RP_IDM_STARTITEMS + GetItemCount ( ) ) + { + int index = LOWORD(wParam)-RP_IDM_STARTITEMS; + ExpandItem ( index, !IsItemExpanded(index) ); + } + + // button command + else if ( HIWORD(wParam) == BN_CLICKED ) + { + int index = GetItemIndex ((HWND)lParam); + if ( index != -1 ) + { + ExpandItem ( index, !IsItemExpanded ( index ) ); + return 0; + } + } + + return 0; +} + +/* +================ +rvRollupPanel::HandlePaint + +Handle the WM_PAINT message +================ +*/ +int rvRollupPanel::HandlePaint( WPARAM wParam, LPARAM lParam ) +{ + HDC dc; + PAINTSTRUCT ps; + RECT r; + RECT br; + int sbPos; + int sbSize; + int clientHeight; + + dc = BeginPaint ( mWindow, &ps ); + + // scrollbar + GetClientRect ( mWindow, &r ); + SetRect ( &br, r.right-RP_SCROLLBARWIDTH, r.top, r.right, r.bottom ); + DrawEdge ( dc, &br, EDGE_RAISED, BF_RECT ); + + sbPos = 0; + sbSize = 0; + clientHeight = (r.bottom-r.top) - 4; + + if ( mItemHeight > (r.bottom-r.top) ) + { + sbSize = clientHeight - (((mItemHeight-(r.bottom-r.top)) * clientHeight ) / mItemHeight ); + sbPos = -(mStartYPos * clientHeight) / mItemHeight; + } + else + { + sbSize = clientHeight; + } + + br.left +=2; + br.right -=1; + br.top = sbPos+2; + br.bottom = br.top+sbSize; + + HBRUSH brush; + brush = CreateSolidBrush ( RP_SCROLLBARCOLOR ); + FillRect ( dc, &br, brush ); + DeleteObject ( brush ); + + SetRect ( &r, br.left,2,br.right,br.top ); + FillRect ( dc, &r, (HBRUSH)GetStockObject ( BLACK_BRUSH ) ); + + SetRect ( &r, br.left,br.bottom,br.right,2+clientHeight ); + FillRect ( dc, &r, (HBRUSH)GetStockObject ( BLACK_BRUSH ) ); + + return 0; +} + +/* +================ +rvRollupPanel::HandleSize + +Handle the WM_SIZE message +================ +*/ +int rvRollupPanel::HandleSize ( WPARAM wParam, LPARAM lParam ) +{ + DefWindowProc ( mWindow, WM_SIZE, wParam, lParam ); + RecallLayout(); + return 0; +} + +/* +================ +rvRollupPanel::HandleLButtonDown + +Handle the WM_LBUTTONDOWN message +================ +*/ +int rvRollupPanel::HandleLButtonDown ( WPARAM wParam, LPARAM lParam ) +{ + RECT r; + RECT br; + POINT point; + + GetClientRect ( mWindow, &r ); + if ( mItemHeight <= r.bottom - r.top ) + { + return 0; + } + + point.x = LOWORD(lParam); + point.y = HIWORD(lParam); + + SetRect ( &br, r.right - RP_SCROLLBARWIDTH, r.top, r.right, r.bottom ); + + if ( (wParam & MK_LBUTTON) && PtInRect ( &br, point ) ) + { + SetCapture( mWindow ); + + int clientHeight = (r.bottom-r.top) - 4; + + int sbSize = clientHeight - (((mItemHeight - (r.bottom-r.top)) * clientHeight) / mItemHeight ); + int sbPos = -(mStartYPos * clientHeight) / mItemHeight; + + // click inside scrollbar cursor + if ( (point.y < (sbPos + sbSize)) && (point.y > sbPos )) + { + mSBOffset = sbPos - point.y + 1; + } + // click outside scrollbar cursor (2 cases => above or below cursor) + else + { + int distup = point.y - sbPos; + int distdown = (sbPos + sbSize) - point.y; + + if ( distup < distdown ) + { + //above + mSBOffset = 0; + } + else + { + //below + mSBOffset = -sbSize; + } + } + + // calc new m_nStartYPos from mouse pos + int targetPos = point.y + mSBOffset; + mStartYPos =- (targetPos * mItemHeight) / clientHeight; + + // update + RecallLayout(); + } + + return 0; +} + +/* +================ +rvRollupPanel::HandleLButtonUp + +Handle the WM_LBUTTONUP message +================ +*/ +int rvRollupPanel::HandleLButtonUp ( WPARAM wParam, LPARAM lParam ) +{ + if ( GetCapture() == mWindow ) + { + ReleaseCapture(); + } + + return 0; +} + +/* +================ +rvRollupPanel::HandleMouseMove + +Handle the WM_MOUSEMOVE message +================ +*/ +int rvRollupPanel::HandleMouseMove ( WPARAM wParam, LPARAM lParam ) +{ + RECT r; + RECT br; + POINT point; + + GetClientRect ( mWindow, &r ); + if ( mItemHeight <= r.bottom - r.top ) + { + return 0; + } + + point.x = LOWORD(lParam); + point.y = HIWORD(lParam); + + SetRect ( &br, r.right - RP_SCROLLBARWIDTH, r.top, r.right, r.bottom ); + + if ( (wParam & MK_LBUTTON) && (GetCapture() == mWindow )) + { + // calc new m_nStartYPos from mouse pos + int clientHeight = (r.bottom-r.top) - 4; + int targetPos = point.y + mSBOffset; + + mStartYPos =- (targetPos * mItemHeight) / clientHeight; + + RecallLayout ( ); + + InvalidateRect ( mWindow, NULL, FALSE ); +// UpdateWindow ( mWindow ); + } + + return 0; +} + +/* +================ +rvRollupPanel::HandleMouseWheel + +Handle the WM_MOUSEWHEEL message +================ +*/ +int rvRollupPanel::HandleMouseWheel ( WPARAM wParam, LPARAM lParam ) +{ + // calc new m_nStartYPos + mStartYPos += (HIWORD(wParam) / 4); + + RecallLayout(); + + return 0; +} + +/* +================ +rvRollupPanel::HandleMouseActivate + +Handle the WM_MOUSEACTIVATE message +================ +*/ +int rvRollupPanel::HandleMouseActivate ( WPARAM wParam, LPARAM lParam ) +{ + SetFocus ( mWindow ); + return 0; +} + +/* +================ +rvRollupPanel::HandleContextMenu + +Handle the WM_CONTEXTMENU message +================ +*/ +int rvRollupPanel::HandleContextMenu ( WPARAM wParam, LPARAM lParam ) +{ + HMENU menu; + int i; + POINT point; + + menu = CreatePopupMenu ( ); + if ( !menu ) + { + return 0; + } + + point.x = LOWORD(lParam); + point.y = HIWORD(lParam); + + AppendMenu ( menu, MF_STRING, RP_IDM_EXPANDALL, "Expand all" ); + AppendMenu ( menu, MF_STRING, RP_IDM_COLLAPSEALL, "Collapse all" ); + AppendMenu ( menu, MF_SEPARATOR, 0, "" ); + + //Add all pages with checked style for expanded ones + for ( i=0; i < mItems.Num(); i++ ) + { + char itemName[1024]; + GetWindowText ( mItems[i]->mButton, itemName, 1023 ); + AppendMenu ( menu, MF_STRING, RP_IDM_STARTITEMS + i, itemName ); + + if ( mItems[i]->mExpanded ) + { + CheckMenuItem ( menu, RP_IDM_STARTITEMS + i, MF_CHECKED); + } + + TrackPopupMenu ( menu, TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, 0, mWindow, NULL ); + } + + return 0; +} + +/* +================ +rvRollupPanel::GetMsgProc + +Ensures normal dialog functions work in the alpha select dialog +================ +*/ +LRESULT FAR PASCAL rvRollupPanel::GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam ) +{ + LPMSG lpMsg = (LPMSG) lParam; + + if ( nCode >= 0 && PM_REMOVE == wParam ) + { + // Don't translate non-input events. + if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) ) + { + int i; + for ( i = 0; i < mDialogs.Num(); i ++ ) + { + if ( IsDialogMessage( mDialogs[i], lpMsg) ) + { + // The value returned from this hookproc is ignored, + // and it cannot be used to tell Windows the message has been handled. + // To avoid further processing, convert the message to WM_NULL + // before returning. + lpMsg->message = WM_NULL; + lpMsg->lParam = 0; + lpMsg->wParam = 0; + break; + } + } + } + } + + return CallNextHookEx ( mDialogHook, nCode, wParam, lParam); +} + +/* +================ +rvRollupPanel::AutoSize + +Automatically set the width of the control based on the dialogs it contains +================ +*/ +void rvRollupPanel::AutoSize ( void ) +{ + int i; + int width = 0; + for ( i = 0; i < mItems.Num(); i ++ ) + { + RECT r; + int w; + GetWindowRect ( mItems[i]->mDialog, &r ); + w = (r.right-r.left)+RP_SCROLLBARWIDTH+(RP_GRPBOXINDENT*2); + if ( w > width ) + { + width = w; + } + } + + RECT cr; + GetWindowRect ( mWindow, &cr ); + SetWindowPos ( mWindow, NULL, 0, 0, width, cr.bottom-cr.top, SWP_NOMOVE|SWP_NOZORDER ); +} + diff --git a/tools/common/RollupPanel.h b/tools/common/RollupPanel.h new file mode 100644 index 000000000..f2b7db10f --- /dev/null +++ b/tools/common/RollupPanel.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef ROLLUPPANEL_H_ +#define ROLLUPPANEL_H_ + +#define RPITEM_MAX_NAME 64 + +struct RPITEM +{ + HWND mDialog; + HWND mButton; + HWND mGroupBox; + bool mExpanded; + bool mEnable; + bool mAutoDestroy; + WNDPROC mOldDlgProc; + WNDPROC mOldButtonProc; + char mCaption[RPITEM_MAX_NAME]; +}; + +class rvRollupPanel +{ +public: + + rvRollupPanel ( void ); + virtual ~rvRollupPanel ( void ); + + bool Create ( DWORD dwStyle, const RECT& rect, HWND parent, unsigned int id ); + + int InsertItem ( const char* caption, HWND dialog, bool autoDestroy, int index = -1); + + void RemoveItem ( int index ); + void RemoveAllItems ( void ); + + void ExpandItem ( int index, bool expand = true ); + void ExpandAllItems ( bool expand = true ); + + void EnableItem ( int index, bool enabled = true ); + void EnableAllItems ( bool enable = true ); + + int GetItemCount ( void ); + + RPITEM* GetItem ( int index ); + + int GetItemIndex ( const char* caption ); + int GetItemIndex ( HWND hwnd ); + + void ScrollToItem ( int index, bool top = true ); + int MoveItemAt ( int index, int newIndex ); + bool IsItemExpanded ( int index ); + bool IsItemEnabled ( int index ); + + HWND GetWindow ( void ); + + void AutoSize ( void ); + +protected: + + void RecallLayout ( void ); + void _RemoveItem ( int index ); + void _ExpandItem ( RPITEM* item, bool expand ); + void _EnableItem ( RPITEM* item, bool enable ); + + int HandleCommand ( WPARAM wParam, LPARAM lParam ); + int HandlePaint ( WPARAM wParam, LPARAM lParam ); + int HandleSize ( WPARAM wParam, LPARAM lParam ); + int HandleLButtonDown ( WPARAM wParam, LPARAM lParam ); + int HandleLButtonUp ( WPARAM wParam, LPARAM lParam ); + int HandleMouseMove ( WPARAM wParam, LPARAM lParam ); + int HandleMouseWheel ( WPARAM wParam, LPARAM lParam ); + int HandleMouseActivate ( WPARAM wParam, LPARAM lParam ); + int HandleContextMenu ( WPARAM wParam, LPARAM lParam ); + + // Datas + idList mItems; + int mStartYPos; + int mItemHeight; + int mOldMouseYPos; + int mSBOffset; + HWND mWindow; + + // Window proc + static LRESULT CALLBACK WindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static LRESULT CALLBACK DialogProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static LRESULT CALLBACK ButtonProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + static LRESULT FAR PASCAL GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam ); + static idList mDialogs; + static HHOOK mDialogHook; +}; + +ID_INLINE int rvRollupPanel::GetItemCount ( void ) +{ + return mItems.Num(); +} + +ID_INLINE bool rvRollupPanel::IsItemExpanded ( int index ) +{ + if ( index >= mItems.Num() || index < 0 ) + { + return false; + } + return mItems[index]->mExpanded; +} + +ID_INLINE bool rvRollupPanel::IsItemEnabled( int index ) +{ + if ( index >= mItems.Num() || index < 0 ) + { + return false; + } + return mItems[index]->mEnable; +} + +ID_INLINE HWND rvRollupPanel::GetWindow ( void ) +{ + return mWindow; +} + +#endif // ROLLUPPANEL_H_ diff --git a/tools/common/SpinButton.cpp b/tools/common/SpinButton.cpp new file mode 100644 index 000000000..3db71cadd --- /dev/null +++ b/tools/common/SpinButton.cpp @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "SpinButton.h" + +void SpinButton_SetIncrement ( HWND hWnd, float inc ) +{ + SetWindowLong ( hWnd, GWL_USERDATA, (long)(inc * 100.0f) ); +} + +void SpinButton_SetRange ( HWND hWnd, float minRange, float maxRange ) +{ + SendMessage ( hWnd, UDM_SETRANGE32, (LONG)(minRange*100.0f), (LONG)(maxRange*100.0f) ); +} + +void SpinButton_HandleNotify ( NMHDR* hdr ) +{ + // Return if incorrect data in edit box + NM_UPDOWN* udhdr= (NM_UPDOWN*)hdr; + + // Change with 0.1 on each click + char strValue[64]; + float value; + GetWindowText ( (HWND)SendMessage ( hdr->hwndFrom, UDM_GETBUDDY, 0, 0 ), strValue, 63 ); + + float inc = (float)GetWindowLong ( hdr->hwndFrom, GWL_USERDATA ); + if ( inc == 0 ) + { + inc = 100.0f; + SetWindowLong ( hdr->hwndFrom, GWL_USERDATA, 100 ); + } + inc /= 100.0f; + + if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) + { + inc *= 10.0f; + } + + value = atof(strValue); + value += (udhdr->iDelta)*(inc); + + // Avoid round-off errors + value = floor(value*1e3+0.5)/1e3; + + LONG minRange; + LONG maxRange; + SendMessage ( hdr->hwndFrom, UDM_GETRANGE32, (LONG)&minRange, (LONG)&maxRange ); + if ( minRange != 0 || maxRange != 0 ) + { + float minRangef = (float)(long)minRange / 100.0f; + float maxRangef = (float)maxRange / 100.0f; + if ( value > maxRangef ) + { + value = maxRangef; + } + if ( value < minRangef ) + { + value = minRangef; + } + } + + SetWindowText ( (HWND)SendMessage ( hdr->hwndFrom, UDM_GETBUDDY, 0, 0 ), va("%g",value) ); +} diff --git a/tools/common/SpinButton.h b/tools/common/SpinButton.h new file mode 100644 index 000000000..4678f5f4f --- /dev/null +++ b/tools/common/SpinButton.h @@ -0,0 +1,27 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef SPINBUTTON_H_ +#define SPINBUTTON_H_ + +void SpinButton_SetIncrement ( HWND hWnd, float inc ); +void SpinButton_HandleNotify ( NMHDR* hdr ); +void SpinButton_SetRange ( HWND hWnd, float min, float max ); + +#endif // SPINBUTOTN_H_ diff --git a/tools/compilers/aas/AASBuild.cpp b/tools/compilers/aas/AASBuild.cpp new file mode 100644 index 000000000..789f4c81d --- /dev/null +++ b/tools/compilers/aas/AASBuild.cpp @@ -0,0 +1,1022 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASBuild_local.h" + +#define BFL_PATCH 0x1000 + +//=============================================================== +// +// idAASBuild +// +//=============================================================== + +/* +============ +idAASBuild::idAASBuild +============ +*/ +idAASBuild::idAASBuild( void ) { + file = NULL; + procNodes = NULL; + numProcNodes = 0; + numGravitationalSubdivisions = 0; + numMergedLeafNodes = 0; + numLedgeSubdivisions = 0; + ledgeMap = NULL; +} + +/* +============ +idAASBuild::~idAASBuild +============ +*/ +idAASBuild::~idAASBuild( void ) { + Shutdown(); +} + +/* +================ +idAASBuild::Shutdown +================ +*/ +void idAASBuild::Shutdown( void ) { + aasSettings = NULL; + if ( file ) { + delete file; + file = NULL; + } + DeleteProcBSP(); + numGravitationalSubdivisions = 0; + numMergedLeafNodes = 0; + numLedgeSubdivisions = 0; + ledgeList.Clear(); + if ( ledgeMap ) { + delete ledgeMap; + ledgeMap = NULL; + } +} + +/* +================ +idAASBuild::ParseProcNodes +================ +*/ +void idAASBuild::ParseProcNodes( idLexer *src ) { + int i; + + src->ExpectTokenString( "{" ); + + idAASBuild::numProcNodes = src->ParseInt(); + if ( idAASBuild::numProcNodes < 0 ) { + src->Error( "idAASBuild::ParseProcNodes: bad numProcNodes" ); + } + idAASBuild::procNodes = (aasProcNode_t *)Mem_ClearedAlloc( idAASBuild::numProcNodes * sizeof( aasProcNode_t ) ); + + for ( i = 0; i < idAASBuild::numProcNodes; i++ ) { + aasProcNode_t *node; + + node = &(idAASBuild::procNodes[i]); + + src->Parse1DMatrix( 4, node->plane.ToFloatPtr() ); + node->children[0] = src->ParseInt(); + node->children[1] = src->ParseInt(); + } + + src->ExpectTokenString( "}" ); +} + +/* +================ +idAASBuild::LoadProcBSP +================ +*/ +bool idAASBuild::LoadProcBSP( const char *name, ID_TIME_T minFileTime ) { + idStr fileName; + idToken token; + idLexer *src; + + // load it + fileName = name; + fileName.SetFileExtension( PROC_FILE_EXT ); + src = new idLexer( fileName, LEXFL_NOSTRINGCONCAT | LEXFL_NODOLLARPRECOMPILE ); + if ( !src->IsLoaded() ) { + common->Warning("idAASBuild::LoadProcBSP: couldn't load %s", fileName.c_str() ); + delete src; + return false; + } + + // if the file is too old + if ( src->GetFileTime() < minFileTime ) { + delete src; + return false; + } + + if ( !src->ReadToken( &token ) || token.Icmp( PROC_FILE_ID ) ) { + common->Warning( "idAASBuild::LoadProcBSP: bad id '%s' instead of '%s'", token.c_str(), PROC_FILE_ID ); + delete src; + return false; + } + + // parse the file + while ( 1 ) { + if ( !src->ReadToken( &token ) ) { + break; + } + + if ( token == "model" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "shadowModel" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "interAreaPortals" ) { + src->SkipBracedSection(); + continue; + } + + if ( token == "nodes" ) { + idAASBuild::ParseProcNodes( src ); + break; + } + + src->Error( "idAASBuild::LoadProcBSP: bad token \"%s\"", token.c_str() ); + } + + delete src; + + return true; +} + +/* +============ +idAASBuild::DeleteProcBSP +============ +*/ +void idAASBuild::DeleteProcBSP( void ) { + if ( procNodes ) { + Mem_Free( procNodes ); + procNodes = NULL; + } + numProcNodes = 0; +} + +/* +============ +idAASBuild::ChoppedAwayByProcBSP +============ +*/ +bool idAASBuild::ChoppedAwayByProcBSP( int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius ) { + int res; + idFixedWinding back; + aasProcNode_t *node; + float dist; + + do { + node = idAASBuild::procNodes + nodeNum; + dist = node->plane.Normal() * origin + node->plane[3]; + if ( dist > radius ) { + res = SIDE_FRONT; + } + else if ( dist < -radius ) { + res = SIDE_BACK; + } + else { + res = w->Split( &back, node->plane, ON_EPSILON ); + } + if ( res == SIDE_FRONT ) { + nodeNum = node->children[0]; + } + else if ( res == SIDE_BACK ) { + nodeNum = node->children[1]; + } + else if ( res == SIDE_ON ) { + // continue with the side the winding faces + if ( node->plane.Normal() * normal > 0.0f ) { + nodeNum = node->children[0]; + } + else { + nodeNum = node->children[1]; + } + } + else { + // if either node is not solid + if ( node->children[0] < 0 || node->children[1] < 0 ) { + return false; + } + // only recurse if the node is not solid + if ( node->children[1] > 0 ) { + if ( !idAASBuild::ChoppedAwayByProcBSP( node->children[1], &back, normal, origin, radius ) ) { + return false; + } + } + nodeNum = node->children[0]; + } + } while ( nodeNum > 0 ); + if ( nodeNum < 0 ) { + return false; + } + return true; +} + +/* +============ +idAASBuild::ClipBrushSidesWithProcBSP +============ +*/ +void idAASBuild::ClipBrushSidesWithProcBSP( idBrushList &brushList ) { + int i, clippedSides; + idBrush *brush; + idFixedWinding neww; + idBounds bounds; + float radius; + idVec3 origin; + + // if the .proc file has no BSP tree + if ( idAASBuild::procNodes == NULL ) { + return; + } + + clippedSides = 0; + for ( brush = brushList.Head(); brush; brush = brush->Next() ) { + for ( i = 0; i < brush->GetNumSides(); i++ ) { + + if ( !brush->GetSide(i)->GetWinding() ) { + continue; + } + + // make a local copy of the winding + neww = *brush->GetSide(i)->GetWinding(); + neww.GetBounds( bounds ); + origin = (bounds[1] - bounds[0]) * 0.5f; + radius = origin.Length() + ON_EPSILON; + origin = bounds[0] + origin; + + if ( ChoppedAwayByProcBSP( 0, &neww, brush->GetSide(i)->GetPlane().Normal(), origin, radius ) ) { + brush->GetSide(i)->SetFlag( SFL_USED_SPLITTER ); + clippedSides++; + } + } + } + + common->Printf( "%6d brush sides clipped\n", clippedSides ); +} + +/* +============ +idAASBuild::ContentsForAAS +============ +*/ +int idAASBuild::ContentsForAAS( int contents ) { + int c; + + if ( contents & ( CONTENTS_SOLID|CONTENTS_AAS_SOLID|CONTENTS_MONSTERCLIP ) ) { + return AREACONTENTS_SOLID; + } + c = 0; + if ( contents & CONTENTS_WATER ) { + c |= AREACONTENTS_WATER; + } + if ( contents & CONTENTS_AREAPORTAL ) { + c |= AREACONTENTS_CLUSTERPORTAL; + } + if ( contents & CONTENTS_AAS_OBSTACLE ) { + c |= AREACONTENTS_OBSTACLE; + } + return c; +} + +/* +============ +idAASBuild::AddBrushForMapBrush +============ +*/ +idBrushList idAASBuild::AddBrushesForMapBrush( const idMapBrush *mapBrush, const idVec3 &origin, const idMat3 &axis, int entityNum, int primitiveNum, idBrushList brushList ) { + int contents, i; + idMapBrushSide *mapSide; + const idMaterial *mat; + idList sideList; + idBrush *brush; + idPlane plane; + + contents = 0; + for ( i = 0; i < mapBrush->GetNumSides(); i++ ) { + mapSide = mapBrush->GetSide(i); + mat = declManager->FindMaterial( mapSide->GetMaterial() ); + contents |= mat->GetContentFlags(); + plane = mapSide->GetPlane(); + plane.FixDegeneracies( DEGENERATE_DIST_EPSILON ); + sideList.Append( new idBrushSide( plane, -1 ) ); + } + + contents = ContentsForAAS( contents ); + if ( !contents ) { + for ( i = 0; i < sideList.Num(); i++ ) { + delete sideList[i]; + } + return brushList; + } + + brush = new idBrush(); + brush->SetContents( contents ); + + if ( !brush->FromSides( sideList ) ) { + common->Warning( "brush primitive %d on entity %d is degenerate", primitiveNum, entityNum ); + delete brush; + return brushList; + } + + brush->SetEntityNum( entityNum ); + brush->SetPrimitiveNum( primitiveNum ); + brush->Transform( origin, axis ); + brushList.AddToTail( brush ); + + return brushList; +} + +/* +============ +idAASBuild::AddBrushesForPatch +============ +*/ +idBrushList idAASBuild::AddBrushesForMapPatch( const idMapPatch *mapPatch, const idVec3 &origin, const idMat3 &axis, int entityNum, int primitiveNum, idBrushList brushList ) { + int i, j, contents, validBrushes; + float dot; + int v1, v2, v3, v4; + idFixedWinding w; + idPlane plane; + idVec3 d1, d2; + idBrush *brush; + idSurface_Patch mesh; + const idMaterial *mat; + + mat = declManager->FindMaterial( mapPatch->GetMaterial() ); + contents = ContentsForAAS( mat->GetContentFlags() ); + + if ( !contents ) { + return brushList; + } + + mesh = idSurface_Patch( *mapPatch ); + + // if the patch has an explicit number of subdivisions use it to avoid cracks + if ( mapPatch->GetExplicitlySubdivided() ) { + mesh.SubdivideExplicit( mapPatch->GetHorzSubdivisions(), mapPatch->GetVertSubdivisions(), false, true ); + } else { + mesh.Subdivide( DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_LENGTH_CD, false ); + } + + validBrushes = 0; + + for ( i = 0; i < mesh.GetWidth() - 1; i++ ) { + for ( j = 0; j < mesh.GetHeight() - 1; j++ ) { + + v1 = j * mesh.GetWidth() + i; + v2 = v1 + 1; + v3 = v1 + mesh.GetWidth() + 1; + v4 = v1 + mesh.GetWidth(); + + d1 = mesh[v2].xyz - mesh[v1].xyz; + d2 = mesh[v3].xyz - mesh[v1].xyz; + plane.SetNormal( d1.Cross(d2) ); + if ( plane.Normalize() != 0.0f ) { + plane.FitThroughPoint( mesh[v1].xyz ); + dot = plane.Distance( mesh[v4].xyz ); + // if we can turn it into a quad + if ( idMath::Fabs(dot) < 0.1f ) { + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v2].xyz; + w += mesh[v3].xyz; + w += mesh[v4].xyz; + + brush = new idBrush(); + brush->SetContents( contents ); + if ( brush->FromWinding( w, plane ) ) { + brush->SetEntityNum( entityNum ); + brush->SetPrimitiveNum( primitiveNum ); + brush->SetFlag( BFL_PATCH ); + brush->Transform( origin, axis ); + brushList.AddToTail( brush ); + validBrushes++; + } + else { + delete brush; + } + continue; + } + else { + // create one of the triangles + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v2].xyz; + w += mesh[v3].xyz; + + brush = new idBrush(); + brush->SetContents( contents ); + if ( brush->FromWinding( w, plane ) ) { + brush->SetEntityNum( entityNum ); + brush->SetPrimitiveNum( primitiveNum ); + brush->SetFlag( BFL_PATCH ); + brush->Transform( origin, axis ); + brushList.AddToTail( brush ); + validBrushes++; + } + else { + delete brush; + } + } + } + // create the other triangle + d1 = mesh[v3].xyz - mesh[v1].xyz; + d2 = mesh[v4].xyz - mesh[v1].xyz; + plane.SetNormal( d1.Cross(d2) ); + if ( plane.Normalize() != 0.0f ) { + plane.FitThroughPoint( mesh[v1].xyz ); + + w.Clear(); + w += mesh[v1].xyz; + w += mesh[v3].xyz; + w += mesh[v4].xyz; + + brush = new idBrush(); + brush->SetContents( contents ); + if ( brush->FromWinding( w, plane ) ) { + brush->SetEntityNum( entityNum ); + brush->SetPrimitiveNum( primitiveNum ); + brush->SetFlag( BFL_PATCH ); + brush->Transform( origin, axis ); + brushList.AddToTail( brush ); + validBrushes++; + } + else { + delete brush; + } + } + } + } + + if ( !validBrushes ) { + common->Warning( "patch primitive %d on entity %d is completely degenerate", primitiveNum, entityNum ); + } + + return brushList; +} + +/* +============ +idAASBuild::AddBrushesForMapEntity +============ +*/ +idBrushList idAASBuild::AddBrushesForMapEntity( const idMapEntity *mapEnt, int entityNum, idBrushList brushList ) { + int i; + idVec3 origin; + idMat3 axis; + + if ( mapEnt->GetNumPrimitives() < 1 ) { + return brushList; + } + + mapEnt->epairs.GetVector( "origin", "0 0 0", origin ); + if ( !mapEnt->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) { + float angle = mapEnt->epairs.GetFloat( "angle" ); + if ( angle != 0.0f ) { + axis = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } else { + axis.Identity(); + } + } + + for ( i = 0; i < mapEnt->GetNumPrimitives(); i++ ) { + idMapPrimitive *mapPrim; + + mapPrim = mapEnt->GetPrimitive(i); + if ( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) { + brushList = AddBrushesForMapBrush( static_cast(mapPrim), origin, axis, entityNum, i, brushList ); + continue; + } + if ( mapPrim->GetType() == idMapPrimitive::TYPE_PATCH ) { + if ( aasSettings->usePatches ) { + brushList = AddBrushesForMapPatch( static_cast(mapPrim), origin, axis, entityNum, i, brushList ); + } + continue; + } + } + + return brushList; +} + +/* +============ +idAASBuild::AddBrushesForMapFile +============ +*/ +idBrushList idAASBuild::AddBrushesForMapFile( const idMapFile * mapFile, idBrushList brushList ) { + int i; + + common->Printf( "[Brush Load]\n" ); + + brushList = AddBrushesForMapEntity( mapFile->GetEntity( 0 ), 0, brushList ); + + for ( i = 1; i < mapFile->GetNumEntities(); i++ ) { + const char *classname = mapFile->GetEntity( i )->epairs.GetString( "classname" ); + + if ( idStr::Icmp( classname, "func_aas_obstacle" ) == 0 ) { + brushList = AddBrushesForMapEntity( mapFile->GetEntity( i ), i, brushList ); + } + } + + common->Printf( "%6d brushes\n", brushList.Num() ); + + return brushList; +} + +/* +============ +idAASBuild::CheckForEntities +============ +*/ +bool idAASBuild::CheckForEntities( const idMapFile *mapFile, idStrList &entityClassNames ) const { + int i; + idStr classname; + + com_editors |= EDITOR_AAS; + + for ( i = 0; i < mapFile->GetNumEntities(); i++ ) { + if ( !mapFile->GetEntity(i)->epairs.GetString( "classname", "", classname ) ) { + continue; + } + + if ( aasSettings->ValidEntity( classname ) ) { + entityClassNames.AddUnique( classname ); + } + } + + com_editors &= ~EDITOR_AAS; + + return ( entityClassNames.Num() != 0 ); +} + +/* +============ +MergeAllowed +============ +*/ +bool MergeAllowed( idBrush *b1, idBrush *b2 ) { + return ( b1->GetContents() == b2->GetContents() && !( ( b1->GetFlags() | b2->GetFlags() ) & BFL_PATCH ) ); +} + +/* +============ +ExpandedChopAllowed +============ +*/ +bool ExpandedChopAllowed( idBrush *b1, idBrush *b2 ) { + return ( b1->GetContents() == b2->GetContents() ); +} + +/* +============ +ExpandedMergeAllowed +============ +*/ +bool ExpandedMergeAllowed( idBrush *b1, idBrush *b2 ) { + return ( b1->GetContents() == b2->GetContents() ); +} + +/* +============ +idAASBuild::ChangeMultipleBoundingBoxContents +============ +*/ +void idAASBuild::ChangeMultipleBoundingBoxContents_r( idBrushBSPNode *node, int mask ) { + while( node ) { + if ( !( node->GetContents() & mask ) ) { + node->SetContents( node->GetContents() & ~AREACONTENTS_SOLID ); + } + ChangeMultipleBoundingBoxContents_r( node->GetChild( 0 ), mask ); + node = node->GetChild( 1 ); + } +} + +/* +============ +idAASBuild::Build +============ +*/ +bool idAASBuild::Build( const idStr &fileName, const idAASSettings *settings ) { + int i, bit, mask, startTime; + idMapFile * mapFile; + idBrushList brushList; + idList expandedBrushes; + idBrush *b; + idBrushBSP bsp; + idStr name; + idAASReach reach; + idAASCluster cluster; + idStrList entityClassNames; + + startTime = Sys_Milliseconds(); + + Shutdown(); + + aasSettings = settings; + + name = fileName; + name.SetFileExtension( "map" ); + + mapFile = new idMapFile; + if ( !mapFile->Parse( name ) ) { + delete mapFile; + common->Error( "Couldn't load map file: '%s'", name.c_str() ); + return false; + } + + // check if this map has any entities that use this AAS file + if ( !CheckForEntities( mapFile, entityClassNames ) ) { + delete mapFile; + common->Printf( "no entities in map that use %s\n", settings->fileExtension.c_str() ); + return true; + } + + // load map file brushes + brushList = AddBrushesForMapFile( mapFile, brushList ); + + // if empty map + if ( brushList.Num() == 0 ) { + delete mapFile; + common->Error( "%s is empty", name.c_str() ); + return false; + } + + // merge as many brushes as possible before expansion + brushList.Merge( MergeAllowed ); + + // if there is a .proc file newer than the .map file + if ( LoadProcBSP( fileName, mapFile->GetFileTime() ) ) { + ClipBrushSidesWithProcBSP( brushList ); + DeleteProcBSP(); + } + + // make copies of the brush list + expandedBrushes.Append( &brushList ); + for ( i = 1; i < aasSettings->numBoundingBoxes; i++ ) { + expandedBrushes.Append( brushList.Copy() ); + } + + // expand brushes for the axial bounding boxes + mask = AREACONTENTS_SOLID; + for ( i = 0; i < expandedBrushes.Num(); i++ ) { + for ( b = expandedBrushes[i]->Head(); b; b = b->Next() ) { + b->ExpandForAxialBox( aasSettings->boundingBoxes[i] ); + bit = 1 << ( i + AREACONTENTS_BBOX_BIT ); + mask |= bit; + b->SetContents( b->GetContents() | bit ); + } + } + + // move all brushes back into the original list + for ( i = 1; i < aasSettings->numBoundingBoxes; i++ ) { + brushList.AddToTail( *expandedBrushes[i] ); + delete expandedBrushes[i]; + } + + if ( aasSettings->writeBrushMap ) { + bsp.WriteBrushMap( fileName, "_" + aasSettings->fileExtension, AREACONTENTS_SOLID ); + } + + // build BSP tree from brushes + bsp.Build( brushList, AREACONTENTS_SOLID, ExpandedChopAllowed, ExpandedMergeAllowed ); + + // only solid nodes with all bits set for all bounding boxes need to stay solid + ChangeMultipleBoundingBoxContents_r( bsp.GetRootNode(), mask ); + + // portalize the bsp tree + bsp.Portalize(); + + // remove subspaces not reachable by entities + if ( !bsp.RemoveOutside( mapFile, AREACONTENTS_SOLID, entityClassNames ) ) { + bsp.LeakFile( name ); + delete mapFile; + common->Printf( "%s has no outside", name.c_str() ); + return false; + } + + // gravitational subdivision + GravitationalSubdivision( bsp ); + + // merge portals where possible + bsp.MergePortals( AREACONTENTS_SOLID ); + + // melt portal windings + bsp.MeltPortals( AREACONTENTS_SOLID ); + + if ( aasSettings->writeBrushMap ) { + WriteLedgeMap( fileName, "_" + aasSettings->fileExtension + "_ledge" ); + } + + // ledge subdivisions + LedgeSubdivision( bsp ); + + // merge leaf nodes + MergeLeafNodes( bsp ); + + // merge portals where possible + bsp.MergePortals( AREACONTENTS_SOLID ); + + // melt portal windings + bsp.MeltPortals( AREACONTENTS_SOLID ); + + // store the file from the bsp tree + StoreFile( bsp ); + file->settings = *aasSettings; + + // calculate reachability + reach.Build( mapFile, file ); + + // build clusters + cluster.Build( file ); + + // optimize the file + if ( !aasSettings->noOptimize ) { + file->Optimize(); + } + + // write the file + name.SetFileExtension( aasSettings->fileExtension ); + file->Write( name, mapFile->GetGeometryCRC() ); + + // delete the map file + delete mapFile; + + common->Printf( "%6d seconds to create AAS\n", (Sys_Milliseconds() - startTime) / 1000 ); + + return true; +} + +/* +============ +idAASBuild::BuildReachability +============ +*/ +bool idAASBuild::BuildReachability( const idStr &fileName, const idAASSettings *settings ) { + int startTime; + idMapFile * mapFile; + idStr name; + idAASReach reach; + idAASCluster cluster; + + startTime = Sys_Milliseconds(); + + aasSettings = settings; + + name = fileName; + name.SetFileExtension( "map" ); + + mapFile = new idMapFile; + if ( !mapFile->Parse( name ) ) { + delete mapFile; + common->Error( "Couldn't load map file: '%s'", name.c_str() ); + return false; + } + + file = new idAASFileLocal(); + + name.SetFileExtension( aasSettings->fileExtension ); + if ( !file->Load( name, 0 ) ) { + delete mapFile; + common->Error( "Couldn't load AAS file: '%s'", name.c_str() ); + return false; + } + + file->settings = *aasSettings; + + // calculate reachability + reach.Build( mapFile, file ); + + // build clusters + cluster.Build( file ); + + // write the file + file->Write( name, mapFile->GetGeometryCRC() ); + + // delete the map file + delete mapFile; + + common->Printf( "%6d seconds to calculate reachability\n", (Sys_Milliseconds() - startTime) / 1000 ); + + return true; +} + +/* +============ +ParseOptions +============ +*/ +int ParseOptions( const idCmdArgs &args, idAASSettings &settings ) { + int i; + idStr str; + + for ( i = 1; i < args.Argc(); i++ ) { + + str = args.Argv( i ); + str.StripLeading( '-' ); + + if ( str.Icmp( "usePatches" ) == 0 ) { + settings.usePatches = true; + common->Printf( "usePatches = true\n" ); + } else if ( str.Icmp( "writeBrushMap" ) == 0 ) { + settings.writeBrushMap = true; + common->Printf( "writeBrushMap = true\n" ); + } else if ( str.Icmp( "playerFlood" ) == 0 ) { + settings.playerFlood = true; + common->Printf( "playerFlood = true\n" ); + } else if ( str.Icmp( "noOptimize" ) == 0 ) { + settings.noOptimize = true; + common->Printf( "noOptimize = true\n" ); + } + } + return args.Argc() - 1; +} + +/* +============ +RunAAS_f +============ +*/ +void RunAAS_f( const idCmdArgs &args ) { + int i; + idAASBuild aas; + idAASSettings settings; + idStr mapName; + + if ( args.Argc() <= 1 ) { + common->Printf( "runAAS [options] \n" + "options:\n" + " -usePatches = use bezier patches for collision detection.\n" + " -writeBrushMap = write a brush map with the AAS geometry.\n" + " -playerFlood = use player spawn points as valid AAS positions.\n" ); + return; + } + + common->ClearWarnings( "compiling AAS" ); + + common->SetRefreshOnPrint( true ); + + // get the aas settings definitions + const idDict *dict = gameEdit->FindEntityDefDict( "aas_types", false ); + if ( !dict ) { + common->Error( "Unable to find entityDef for 'aas_types'" ); + } + + const idKeyValue *kv = dict->MatchPrefix( "type" ); + while( kv != NULL ) { + const idDict *settingsDict = gameEdit->FindEntityDefDict( kv->GetValue(), false ); + if ( !settingsDict ) { + common->Warning( "Unable to find '%s' in def/aas.def", kv->GetValue().c_str() ); + } else { + settings.FromDict( kv->GetValue(), settingsDict ); + i = ParseOptions( args, settings ); + mapName = args.Argv(i); + mapName.BackSlashesToSlashes(); + if ( mapName.Icmpn( "maps/", 4 ) != 0 ) { + mapName = "maps/" + mapName; + } + aas.Build( mapName, &settings ); + } + + kv = dict->MatchPrefix( "type", kv ); + if ( kv ) { + common->Printf( "=======================================================\n" ); + } + } + common->SetRefreshOnPrint( false ); + common->PrintWarnings(); +} + +/* +============ +RunAASDir_f +============ +*/ +void RunAASDir_f( const idCmdArgs &args ) { + int i; + idAASBuild aas; + idAASSettings settings; + idFileList *mapFiles; + + if ( args.Argc() <= 1 ) { + common->Printf( "runAASDir \n" ); + return; + } + + common->ClearWarnings( "compiling AAS" ); + + common->SetRefreshOnPrint( true ); + + // get the aas settings definitions + const idDict *dict = gameEdit->FindEntityDefDict( "aas_types", false ); + if ( !dict ) { + common->Error( "Unable to find entityDef for 'aas_types'" ); + } + + // scan for .map files + mapFiles = fileSystem->ListFiles( idStr("maps/") + args.Argv(1), ".map" ); + + // create AAS files for all the .map files + for ( i = 0; i < mapFiles->GetNumFiles(); i++ ) { + if ( i ) { + common->Printf( "=======================================================\n" ); + } + + const idKeyValue *kv = dict->MatchPrefix( "type" ); + while( kv != NULL ) { + const idDict *settingsDict = gameEdit->FindEntityDefDict( kv->GetValue(), false ); + if ( !settingsDict ) { + common->Warning( "Unable to find '%s' in def/aas.def", kv->GetValue().c_str() ); + } else { + settings.FromDict( kv->GetValue(), settingsDict ); + aas.Build( idStr( "maps/" ) + args.Argv( 1 ) + "/" + mapFiles->GetFile( i ), &settings ); + } + + kv = dict->MatchPrefix( "type", kv ); + if ( kv ) { + common->Printf( "=======================================================\n" ); + } + } + } + + fileSystem->FreeFileList( mapFiles ); + + common->SetRefreshOnPrint( false ); + common->PrintWarnings(); +} + +/* +============ +RunReach_f +============ +*/ +void RunReach_f( const idCmdArgs &args ) { + int i; + idAASBuild aas; + idAASSettings settings; + + if ( args.Argc() <= 1 ) { + common->Printf( "runReach [options] \n" ); + return; + } + + common->ClearWarnings( "calculating AAS reachability" ); + + common->SetRefreshOnPrint( true ); + + // get the aas settings definitions + const idDict *dict = gameEdit->FindEntityDefDict( "aas_types", false ); + if ( !dict ) { + common->Error( "Unable to find entityDef for 'aas_types'" ); + } + + const idKeyValue *kv = dict->MatchPrefix( "type" ); + while( kv != NULL ) { + const idDict *settingsDict = gameEdit->FindEntityDefDict( kv->GetValue(), false ); + if ( !settingsDict ) { + common->Warning( "Unable to find '%s' in def/aas.def", kv->GetValue().c_str() ); + } else { + settings.FromDict( kv->GetValue(), settingsDict ); + i = ParseOptions( args, settings ); + aas.BuildReachability( idStr("maps/") + args.Argv(i), &settings ); + } + + kv = dict->MatchPrefix( "type", kv ); + if ( kv ) { + common->Printf( "=======================================================\n" ); + } + } + + common->SetRefreshOnPrint( false ); + common->PrintWarnings(); +} diff --git a/tools/compilers/aas/AASBuild_file.cpp b/tools/compilers/aas/AASBuild_file.cpp new file mode 100644 index 000000000..a137f950c --- /dev/null +++ b/tools/compilers/aas/AASBuild_file.cpp @@ -0,0 +1,490 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASBuild_local.h" + +#define VERTEX_HASH_BOXSIZE (1<<6) // must be power of 2 +#define VERTEX_HASH_SIZE (VERTEX_HASH_BOXSIZE*VERTEX_HASH_BOXSIZE) +#define EDGE_HASH_SIZE (1<<14) + +#define INTEGRAL_EPSILON 0.01f +#define VERTEX_EPSILON 0.1f + +#define AAS_PLANE_NORMAL_EPSILON 0.00001f +#define AAS_PLANE_DIST_EPSILON 0.01f + + +idHashIndex *aas_vertexHash; +idHashIndex *aas_edgeHash; +idBounds aas_vertexBounds; +int aas_vertexShift; + +/* +================ +idAASBuild::SetupHash +================ +*/ +void idAASBuild::SetupHash( void ) { + aas_vertexHash = new idHashIndex( VERTEX_HASH_SIZE, 1024 ); + aas_edgeHash = new idHashIndex( EDGE_HASH_SIZE, 1024 ); +} + +/* +================ +idAASBuild::ShutdownHash +================ +*/ +void idAASBuild::ShutdownHash( void ) { + delete aas_vertexHash; + delete aas_edgeHash; +} + +/* +================ +idAASBuild::ClearHash +================ +*/ +void idAASBuild::ClearHash( const idBounds &bounds ) { + int i; + float f, max; + + aas_vertexHash->Clear(); + aas_edgeHash->Clear(); + aas_vertexBounds = bounds; + + max = bounds[1].x - bounds[0].x; + f = bounds[1].y - bounds[0].y; + if ( f > max ) { + max = f; + } + aas_vertexShift = (float) max / VERTEX_HASH_BOXSIZE; + for ( i = 0; (1<> 2; + y = (((int) (vec[1] - aas_vertexBounds[0].y + 0.5)) + 2) >> 2; + return (x + y * VERTEX_HASH_BOXSIZE) & (VERTEX_HASH_SIZE-1); +} + +/* +================ +idAASBuild::GetVertex +================ +*/ +bool idAASBuild::GetVertex( const idVec3 &v, int *vertexNum ) { + int i, hashKey, vn; + aasVertex_t vert, *p; + + for (i = 0; i < 3; i++) { + if ( idMath::Fabs(v[i] - idMath::Rint(v[i])) < INTEGRAL_EPSILON ) { + vert[i] = idMath::Rint(v[i]); + } + else { + vert[i] = v[i]; + } + } + + hashKey = idAASBuild::HashVec( vert ); + + for ( vn = aas_vertexHash->First( hashKey ); vn >= 0; vn = aas_vertexHash->Next( vn ) ) { + p = &file->vertices[vn]; + // first compare z-axis because hash is based on x-y plane + if (idMath::Fabs( vert.z - p->z ) < VERTEX_EPSILON && + idMath::Fabs( vert.x - p->x ) < VERTEX_EPSILON && + idMath::Fabs( vert.y - p->y ) < VERTEX_EPSILON ) + { + *vertexNum = vn; + return true; + } + } + + *vertexNum = file->vertices.Num(); + aas_vertexHash->Add( hashKey, file->vertices.Num() ); + file->vertices.Append( vert ); + + return false; +} + +/* +================ +idAASBuild::GetEdge +================ +*/ +bool idAASBuild::GetEdge( const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num ) { + int v2num, hashKey, e; + int *vertexNum; + aasEdge_t edge; + bool found; + + if ( v1num != -1 ) { + found = true; + } + else { + found = GetVertex( v1, &v1num ); + } + found &= GetVertex( v2, &v2num ); + // if both vertexes are the same or snapped onto each other + if ( v1num == v2num ) { + *edgeNum = 0; + return true; + } + hashKey = aas_edgeHash->GenerateKey( v1num, v2num ); + // if both vertexes where already stored + if ( found ) { + for ( e = aas_edgeHash->First( hashKey ); e >= 0; e = aas_edgeHash->Next( e ) ) { + + vertexNum = file->edges[e].vertexNum; + if ( vertexNum[0] == v2num ) { + if ( vertexNum[1] == v1num ) { + // negative for a reversed edge + *edgeNum = -e; + break; + } + } + else if ( vertexNum[0] == v1num ) { + if ( vertexNum[1] == v2num ) { + *edgeNum = e; + break; + } + } + } + // if edge found in hash + if ( e >= 0 ) { + return true; + } + } + + *edgeNum = file->edges.Num(); + aas_edgeHash->Add( hashKey, file->edges.Num() ); + + edge.vertexNum[0] = v1num; + edge.vertexNum[1] = v2num; + + file->edges.Append( edge ); + + return false; +} + +/* +================ +idAASBuild::GetFaceForPortal +================ +*/ +bool idAASBuild::GetFaceForPortal( idBrushBSPPortal *portal, int side, int *faceNum ) { + int i, j, v1num; + int numFaceEdges, faceEdges[MAX_POINTS_ON_WINDING]; + idWinding *w; + aasFace_t face; + + if ( portal->GetFaceNum() > 0 ) { + if ( side ) { + *faceNum = -portal->GetFaceNum(); + } + else { + *faceNum = portal->GetFaceNum(); + } + return true; + } + + w = portal->GetWinding(); + // turn the winding into a sequence of edges + numFaceEdges = 0; + v1num = -1; // first vertex unknown + for ( i = 0; i < w->GetNumPoints(); i++ ) { + + GetEdge( (*w)[i].ToVec3(), (*w)[(i+1)%w->GetNumPoints()].ToVec3(), &faceEdges[numFaceEdges], v1num ); + + if ( faceEdges[numFaceEdges] ) { + // last vertex of this edge is the first vertex of the next edge + v1num = file->edges[ abs(faceEdges[numFaceEdges]) ].vertexNum[ INTSIGNBITNOTSET(faceEdges[numFaceEdges]) ]; + + // this edge is valid so keep it + numFaceEdges++; + } + } + + // should have at least 3 edges + if ( numFaceEdges < 3 ) { + return false; + } + + // the polygon is invalid if some edge is found twice + for ( i = 0; i < numFaceEdges; i++ ) { + for ( j = i+1; j < numFaceEdges; j++ ) { + if ( faceEdges[i] == faceEdges[j] || faceEdges[i] == -faceEdges[j] ) { + return false; + } + } + } + + portal->SetFaceNum( file->faces.Num() ); + + face.planeNum = file->planeList.FindPlane( portal->GetPlane(), AAS_PLANE_NORMAL_EPSILON, AAS_PLANE_DIST_EPSILON ); + face.flags = portal->GetFlags(); + face.areas[0] = face.areas[1] = 0; + face.firstEdge = file->edgeIndex.Num(); + face.numEdges = numFaceEdges; + for ( i = 0; i < numFaceEdges; i++ ) { + file->edgeIndex.Append( faceEdges[i] ); + } + if ( side ) { + *faceNum = -file->faces.Num(); + } + else { + *faceNum = file->faces.Num(); + } + file->faces.Append( face ); + + return true; +} + +/* +================ +idAASBuild::GetAreaForLeafNode +================ +*/ +bool idAASBuild::GetAreaForLeafNode( idBrushBSPNode *node, int *areaNum ) { + int s, faceNum; + idBrushBSPPortal *p; + aasArea_t area; + + if ( node->GetAreaNum() ) { + *areaNum = -node->GetAreaNum(); + return true; + } + + area.flags = node->GetFlags(); + area.cluster = area.clusterAreaNum = 0; + area.contents = node->GetContents(); + area.firstFace = file->faceIndex.Num(); + area.numFaces = 0; + area.reach = NULL; + area.rev_reach = NULL; + + for ( p = node->GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == node); + + if ( !GetFaceForPortal( p, s, &faceNum ) ) { + continue; + } + + file->faceIndex.Append( faceNum ); + area.numFaces++; + + if ( faceNum > 0 ) { + file->faces[abs(faceNum)].areas[0] = file->areas.Num(); + } + else { + file->faces[abs(faceNum)].areas[1] = file->areas.Num(); + } + } + + if ( !area.numFaces ) { + *areaNum = 0; + return false; + } + + *areaNum = -file->areas.Num(); + node->SetAreaNum( file->areas.Num() ); + file->areas.Append( area ); + + DisplayRealTimeString( "\r%6d", file->areas.Num() ); + + return true; +} + +/* +================ +idAASBuild::StoreTree_r +================ +*/ +int idAASBuild::StoreTree_r( idBrushBSPNode *node ) { + int areaNum, nodeNum, child0, child1; + aasNode_t aasNode; + + if ( !node ) { + return 0; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return 0; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + if ( GetAreaForLeafNode( node, &areaNum ) ) { + return areaNum; + } + return 0; + } + + aasNode.planeNum = file->planeList.FindPlane( node->GetPlane(), AAS_PLANE_NORMAL_EPSILON, AAS_PLANE_DIST_EPSILON ); + aasNode.children[0] = aasNode.children[1] = 0; + nodeNum = file->nodes.Num(); + file->nodes.Append( aasNode ); + + // !@#$%^ cause of some bug we cannot set the children directly with the StoreTree_r return value + child0 = StoreTree_r( node->GetChild(0) ); + file->nodes[nodeNum].children[0] = child0; + child1 = StoreTree_r( node->GetChild(1) ); + file->nodes[nodeNum].children[1] = child1; + + if ( !child0 && !child1 ) { + file->nodes.SetNum( file->nodes.Num()-1 ); + return 0; + } + + return nodeNum; +} + +/* +================ +idAASBuild::GetSizeEstimate_r +================ +*/ +typedef struct sizeEstimate_s { + int numEdgeIndexes; + int numFaceIndexes; + int numAreas; + int numNodes; +} sizeEstimate_t; + +void idAASBuild::GetSizeEstimate_r( idBrushBSPNode *parent, idBrushBSPNode *node, struct sizeEstimate_s &size ) { + idBrushBSPPortal *p; + int s; + + if ( !node ) { + return; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + // multiple branches of the bsp tree might point to the same leaf node + if ( node->GetParent() == parent ) { + size.numAreas++; + for ( p = node->GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == node); + size.numFaceIndexes++; + size.numEdgeIndexes += p->GetWinding()->GetNumPoints(); + } + } + } + else { + size.numNodes++; + } + + GetSizeEstimate_r( node, node->GetChild(0), size ); + GetSizeEstimate_r( node, node->GetChild(1), size ); +} + +/* +================ +idAASBuild::SetSizeEstimate +================ +*/ +void idAASBuild::SetSizeEstimate( const idBrushBSP &bsp, idAASFileLocal *file ) { + sizeEstimate_t size; + + size.numEdgeIndexes = 1; + size.numFaceIndexes = 1; + size.numAreas = 1; + size.numNodes = 1; + + GetSizeEstimate_r( NULL, bsp.GetRootNode(), size ); + + file->planeList.Resize( size.numNodes / 2, 1024 ); + file->vertices.Resize( size.numEdgeIndexes / 3, 1024 ); + file->edges.Resize( size.numEdgeIndexes / 2, 1024 ); + file->edgeIndex.Resize( size.numEdgeIndexes, 4096 ); + file->faces.Resize( size.numFaceIndexes, 1024 ); + file->faceIndex.Resize( size.numFaceIndexes, 4096 ); + file->areas.Resize( size.numAreas, 1024 ); + file->nodes.Resize( size.numNodes, 1024 ); +} + +/* +================ +idAASBuild::StoreFile +================ +*/ +bool idAASBuild::StoreFile( const idBrushBSP &bsp ) { + aasEdge_t edge; + aasFace_t face; + aasArea_t area; + aasNode_t node; + + common->Printf( "[Store AAS]\n" ); + + SetupHash(); + ClearHash( bsp.GetTreeBounds() ); + + file = new idAASFileLocal(); + + file->Clear(); + + SetSizeEstimate( bsp, file ); + + // the first edge is a dummy + memset( &edge, 0, sizeof( edge ) ); + file->edges.Append( edge ); + + // the first face is a dummy + memset( &face, 0, sizeof( face ) ); + file->faces.Append( face ); + + // the first area is a dummy + memset( &area, 0, sizeof( area ) ); + file->areas.Append( area ); + + // the first node is a dummy + memset( &node, 0, sizeof( node ) ); + file->nodes.Append( node ); + + // store the tree + StoreTree_r( bsp.GetRootNode() ); + + // calculate area bounds and a reachable point in the area + file->FinishAreas(); + + ShutdownHash(); + + common->Printf( "\r%6d areas\n", file->areas.Num() ); + + return true; +} diff --git a/tools/compilers/aas/AASBuild_gravity.cpp b/tools/compilers/aas/AASBuild_gravity.cpp new file mode 100644 index 000000000..98fa048c0 --- /dev/null +++ b/tools/compilers/aas/AASBuild_gravity.cpp @@ -0,0 +1,350 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASBuild_local.h" + + +/* +============ +idAASBuild::SetPortalFlags_r +============ +*/ +void idAASBuild::SetPortalFlags_r( idBrushBSPNode *node ) { + int s; + idBrushBSPPortal *p; + idVec3 normal; + + if ( !node ) { + return; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + for ( p = node->GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == node); + + // if solid at the other side of the portal + if ( p->GetNode(!s)->GetContents() & AREACONTENTS_SOLID ) { + if ( s ) { + normal = -p->GetPlane().Normal(); + } + else { + normal = p->GetPlane().Normal(); + } + if ( normal * aasSettings->invGravityDir > aasSettings->minFloorCos ) { + p->SetFlag( FACE_FLOOR ); + } + else { + p->SetFlag( FACE_SOLID ); + } + } + } + return; + } + + SetPortalFlags_r( node->GetChild(0) ); + SetPortalFlags_r( node->GetChild(1) ); +} + +/* +============ +idAASBuild::PortalIsGap +============ +*/ +bool idAASBuild::PortalIsGap( idBrushBSPPortal *portal, int side ) { + idVec3 normal; + + // if solid at the other side of the portal + if ( portal->GetNode(!side)->GetContents() & AREACONTENTS_SOLID ) { + return false; + } + + if ( side ) { + normal = -(portal->GetPlane().Normal()); + } + else { + normal = portal->GetPlane().Normal(); + } + if ( normal * aasSettings->invGravityDir > aasSettings->minFloorCos ) { + return true; + } + return false; +} + +/* +============ +idAASBuild::GravSubdivLeafNode +============ +*/ +#define FACE_CHECKED BIT(31) +#define GRAVSUBDIV_EPSILON 0.1f + +void idAASBuild::GravSubdivLeafNode( idBrushBSPNode *node ) { + int s1, s2, i, j, k, side1; + int numSplits, numSplitters; + idBrushBSPPortal *p1, *p2; + idWinding *w1, *w2; + idVec3 normal; + idPlane plane; + idPlaneSet planeList; + float d, min, max; + int *splitterOrder; + int *bestNumSplits; + int floor, gap, numFloorChecked; + + // if this leaf node is already classified it cannot have a combination of floor and gap portals + if ( node->GetFlags() & (AREA_FLOOR|AREA_GAP) ) { + return; + } + + floor = gap = 0; + + // check if the area has a floor + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( p1->GetFlags() & FACE_FLOOR ) { + floor++; + } + } + + // find seperating planes between gap and floor portals + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + // if the portal is a gap seen from this side + if ( PortalIsGap( p1, s1 ) ) { + gap++; + // if the area doesn't have a floor + if ( !floor ) { + break; + } + } + else { + continue; + } + + numFloorChecked = 0; + + w1 = p1->GetWinding(); + + // test all edges of the gap + for ( i = 0; i < w1->GetNumPoints(); i++ ) { + + // create a plane through the edge of the gap parallel to the direction of gravity + normal = (*w1)[(i+1)%w1->GetNumPoints()].ToVec3() - (*w1)[i].ToVec3(); + normal = normal.Cross( aasSettings->invGravityDir ); + if ( normal.Normalize() < 0.2f ) { + continue; + } + plane.SetNormal( normal ); + plane.FitThroughPoint( (*w1)[i].ToVec3() ); + + // get the side of the plane the gap is on + side1 = w1->PlaneSide( plane, GRAVSUBDIV_EPSILON ); + if ( side1 == SIDE_ON ) { + break; + } + + // test if the plane through the edge of the gap seperates the gap from a floor portal + for ( p2 = node->GetPortals(); p2; p2 = p2->Next(s2) ) { + s2 = (p2->GetNode(1) == node); + + if ( !( p2->GetFlags() & FACE_FLOOR ) ) { + continue; + } + + if ( p2->GetFlags() & FACE_CHECKED ) { + continue; + } + + w2 = p2->GetWinding(); + + min = 2.0f * GRAVSUBDIV_EPSILON; + max = GRAVSUBDIV_EPSILON; + if ( side1 == SIDE_FRONT ) { + for ( j = 0; j < w2->GetNumPoints(); j++ ) { + d = plane.Distance( (*w2)[j].ToVec3() ); + if ( d >= GRAVSUBDIV_EPSILON ) { + break; // point at the same side of the plane as the gap + } + d = idMath::Fabs( d ); + if ( d < min ) { + min = d; + } + if ( d > max ) { + max = d; + } + } + } + else { + for ( j = 0; j < w2->GetNumPoints(); j++ ) { + d = plane.Distance( (*w2)[j].ToVec3() ); + if ( d <= -GRAVSUBDIV_EPSILON ) { + break; // point at the same side of the plane as the gap + } + d = idMath::Fabs( d ); + if ( d < min ) { + min = d; + } + if ( d > max ) { + max = d; + } + } + } + + // a point of the floor portal was found to be at the same side of the plane as the gap + if ( j < w2->GetNumPoints() ) { + continue; + } + + // if the floor portal touches the plane + if ( min < GRAVSUBDIV_EPSILON && max > GRAVSUBDIV_EPSILON ) { + planeList.FindPlane( plane, 0.00001f, 0.1f ); + } + + p2->SetFlag( FACE_CHECKED ); + numFloorChecked++; + + } + if ( numFloorChecked == floor ) { + break; + } + } + + for ( p2 = node->GetPortals(); p2; p2 = p2->Next(s2) ) { + s2 = (p2->GetNode(1) == node); + p2->RemoveFlag( FACE_CHECKED ); + } + } + + // if the leaf node does not have both floor and gap portals + if ( !( gap && floor) ) { + if ( floor ) { + node->SetFlag( AREA_FLOOR ); + } + else if ( gap ) { + node->SetFlag( AREA_GAP ); + } + return; + } + + // if no valid seperators found + if ( planeList.Num() == 0 ) { + // NOTE: this should never happend, if it does the leaf node has degenerate portals + return; + } + + splitterOrder = (int *) _alloca( planeList.Num() * sizeof( int ) ); + bestNumSplits = (int *) _alloca( planeList.Num() * sizeof( int ) ); + numSplitters = 0; + + // test all possible seperators and sort them from best to worst + for ( i = 0; i < planeList.Num(); i += 2 ) { + numSplits = 0; + + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + if ( p1->GetWinding()->PlaneSide( planeList[i], 0.1f ) == SIDE_CROSS ) { + numSplits++; + } + } + + for ( j = 0; j < numSplitters; j++ ) { + if ( numSplits < bestNumSplits[j] ) { + for ( k = numSplitters; k > j; k-- ) { + bestNumSplits[k] = bestNumSplits[k-1]; + splitterOrder[k] = splitterOrder[k-1]; + } + bestNumSplits[j] = numSplits; + splitterOrder[j] = i; + numSplitters++; + break; + } + } + if ( j >= numSplitters ) { + bestNumSplits[j] = numSplits; + splitterOrder[j] = i; + numSplitters++; + } + } + + // try all seperators in order from best to worst + for ( i = 0; i < numSplitters; i++ ) { + if ( node->Split( planeList[splitterOrder[i]], -1 ) ) { + // we found a seperator that works + break; + } + } + if ( i >= numSplitters) { + return; + } + + DisplayRealTimeString( "\r%6d", ++numGravitationalSubdivisions ); + + // test children for further splits + GravSubdivLeafNode( node->GetChild(0) ); + GravSubdivLeafNode( node->GetChild(1) ); +} + +/* +============ +idAASBuild::GravSubdiv_r +============ +*/ +void idAASBuild::GravSubdiv_r( idBrushBSPNode *node ) { + + if ( !node ) { + return; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + GravSubdivLeafNode( node ); + return; + } + + GravSubdiv_r( node->GetChild(0) ); + GravSubdiv_r( node->GetChild(1) ); +} + +/* +============ +idAASBuild::GravitationalSubdivision +============ +*/ +void idAASBuild::GravitationalSubdivision( idBrushBSP &bsp ) { + numGravitationalSubdivisions = 0; + + common->Printf( "[Gravitational Subdivision]\n" ); + + SetPortalFlags_r( bsp.GetRootNode() ); + GravSubdiv_r( bsp.GetRootNode() ); + + common->Printf( "\r%6d subdivisions\n", numGravitationalSubdivisions ); +} diff --git a/tools/compilers/aas/AASBuild_ledge.cpp b/tools/compilers/aas/AASBuild_ledge.cpp new file mode 100644 index 000000000..2afc9dbac --- /dev/null +++ b/tools/compilers/aas/AASBuild_ledge.cpp @@ -0,0 +1,566 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASBuild_local.h" + +#define LEDGE_EPSILON 0.1f + +//=============================================================== +// +// idLedge +// +//=============================================================== + +/* +============ +idLedge::idLedge +============ +*/ +idLedge::idLedge( void ) { +} + +/* +============ +idLedge::idLedge +============ +*/ +idLedge::idLedge( const idVec3 &v1, const idVec3 &v2, const idVec3 &gravityDir, idBrushBSPNode *n ) { + start = v1; + end = v2; + node = n; + numPlanes = 4; + planes[0].SetNormal( (v1 - v2).Cross( gravityDir ) ); + planes[0].Normalize(); + planes[0].FitThroughPoint( v1 ); + planes[1].SetNormal( (v1 - v2).Cross( planes[0].Normal() ) ); + planes[1].Normalize(); + planes[1].FitThroughPoint( v1 ); + planes[2].SetNormal( v1 - v2 ); + planes[2].Normalize(); + planes[2].FitThroughPoint( v1 ); + planes[3].SetNormal( v2 - v1 ); + planes[3].Normalize(); + planes[3].FitThroughPoint( v2 ); +} + +/* +============ +idLedge::AddPoint +============ +*/ +void idLedge::AddPoint( const idVec3 &v ) { + if ( planes[2].Distance( v ) > 0.0f ) { + start = v; + planes[2].FitThroughPoint( start ); + } + if ( planes[3].Distance( v ) > 0.0f ) { + end = v; + planes[3].FitThroughPoint( end ); + } +} + +/* +============ +idLedge::CreateBevels + + NOTE: this assumes the gravity is vertical +============ +*/ +void idLedge::CreateBevels( const idVec3 &gravityDir ) { + int i, j; + idBounds bounds; + idVec3 size, normal; + + bounds.Clear(); + bounds.AddPoint( start ); + bounds.AddPoint( end ); + size = bounds[1] - bounds[0]; + + // plane through ledge + planes[0].SetNormal( (start - end).Cross( gravityDir ) ); + planes[0].Normalize(); + planes[0].FitThroughPoint( start ); + // axial bevels at start and end point + i = size[1] > size[0]; + normal = vec3_origin; + normal[i] = 1.0f; + j = end[i] > start[i]; + planes[1+j].SetNormal( normal ); + planes[1+!j].SetNormal( -normal ); + planes[1].FitThroughPoint( start ); + planes[2].FitThroughPoint( end ); + numExpandedPlanes = 3; + // if additional bevels are required + if ( idMath::Fabs( size[!i] ) > 0.01f ) { + normal = vec3_origin; + normal[!i] = 1.0f; + j = end[!i] > start[!i]; + planes[3+j].SetNormal( normal ); + planes[3+!j].SetNormal( -normal ); + planes[3].FitThroughPoint( start ); + planes[4].FitThroughPoint( end ); + numExpandedPlanes = 5; + } + // opposite of first + planes[numExpandedPlanes+0] = -planes[0]; + // number of planes used for splitting + numSplitPlanes = numExpandedPlanes + 1; + // top plane + planes[numSplitPlanes+0].SetNormal( (start - end).Cross( planes[0].Normal() ) ); + planes[numSplitPlanes+0].Normalize(); + planes[numSplitPlanes+0].FitThroughPoint( start ); + // bottom plane + planes[numSplitPlanes+1] = -planes[numSplitPlanes+0]; + // total number of planes + numPlanes = numSplitPlanes + 2; +} + +/* +============ +idLedge::Expand +============ +*/ +void idLedge::Expand( const idBounds &bounds, float maxStepHeight ) { + int i, j; + idVec3 v; + + for ( i = 0; i < numExpandedPlanes; i++ ) { + + for ( j = 0; j < 3; j++ ) { + if ( planes[i].Normal()[j] > 0.0f ) { + v[j] = bounds[0][j]; + } + else { + v[j] = bounds[1][j]; + } + } + + planes[i].SetDist( planes[i].Dist() + v * -planes[i].Normal() ); + } + + planes[numSplitPlanes+0].SetDist( planes[numSplitPlanes+0].Dist() + maxStepHeight ); + planes[numSplitPlanes+1].SetDist( planes[numSplitPlanes+1].Dist() + 1.0f ); +} + +/* +============ +idLedge::ChopWinding +============ +*/ +idWinding *idLedge::ChopWinding( const idWinding *winding ) const { + int i; + idWinding *w; + + w = winding->Copy(); + for ( i = 0; i < numPlanes && w; i++ ) { + w = w->Clip( -planes[i], ON_EPSILON, true ); + } + return w; +} + +/* +============ +idLedge::PointBetweenBounds +============ +*/ +bool idLedge::PointBetweenBounds( const idVec3 &v ) const { + return ( planes[2].Distance( v ) < LEDGE_EPSILON ) && ( planes[3].Distance( v ) < LEDGE_EPSILON ); +} + + +//=============================================================== +// +// idAASBuild +// +//=============================================================== + +/* +============ +idAASBuild::LedgeSubdivFlood_r +============ +*/ +void idAASBuild::LedgeSubdivFlood_r( idBrushBSPNode *node, const idLedge *ledge ) { + int s1, i; + idBrushBSPPortal *p1; + idWinding *w; + idList nodeList; + + if ( node->GetFlags() & NODE_VISITED ) { + return; + } + + // if this is not already a ledge area + if ( !( node->GetFlags() & AREA_LEDGE ) ) { + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( !(p1->GetFlags() & FACE_FLOOR) ) { + continue; + } + + // split the area if some part of the floor portal is inside the expanded ledge + w = ledge->ChopWinding( p1->GetWinding() ); + if ( !w ) { + continue; + } + delete w; + + for ( i = 0; i < ledge->numSplitPlanes; i++ ) { + if ( node->PlaneSide( ledge->planes[i], 0.1f ) != SIDE_CROSS ) { + continue; + } + if ( !node->Split( ledge->planes[i], -1 ) ) { + continue; + } + numLedgeSubdivisions++; + DisplayRealTimeString( "\r%6d", numLedgeSubdivisions ); + node->GetChild(0)->SetFlag( NODE_VISITED ); + LedgeSubdivFlood_r( node->GetChild(1), ledge ); + return; + } + + node->SetFlag( AREA_LEDGE ); + break; + } + } + + node->SetFlag( NODE_VISITED ); + + // get all nodes we might need to flood into + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( p1->GetNode( !s1 )->GetContents() & AREACONTENTS_SOLID ) { + continue; + } + + // flood through this portal if the portal is partly inside the expanded ledge + w = ledge->ChopWinding( p1->GetWinding() ); + if ( !w ) { + continue; + } + delete w; + // add to list, cannot flood directly cause portals might be split on the way + nodeList.Append( p1->GetNode( !s1 ) ); + } + + // flood into other nodes + for ( i = 0; i < nodeList.Num(); i++ ) { + LedgeSubdivLeafNodes_r( nodeList[i], ledge ); + } +} + +/* +============ +idAASBuild::LedgeSubdivLeafNodes_r + + The node the ledge was originally part of might be split by other ledges. + Here we recurse down the tree from the original node to find all the new leaf nodes the ledge might be part of. +============ +*/ +void idAASBuild::LedgeSubdivLeafNodes_r( idBrushBSPNode *node, const idLedge *ledge ) { + if ( !node ) { + return; + } + if ( !node->GetChild(0) && !node->GetChild(1) ) { + LedgeSubdivFlood_r( node, ledge ); + return; + } + LedgeSubdivLeafNodes_r( node->GetChild(0), ledge ); + LedgeSubdivLeafNodes_r( node->GetChild(1), ledge ); +} + +/* +============ +idAASBuild::LedgeSubdiv +============ +*/ +void idAASBuild::LedgeSubdiv( idBrushBSPNode *root ) { + int i, j; + idBrush *brush; + idList sideList; + + // create ledge bevels and expand ledges + for ( i = 0; i < ledgeList.Num(); i++ ) { + + ledgeList[i].CreateBevels( aasSettings->gravityDir ); + ledgeList[i].Expand( aasSettings->boundingBoxes[0], aasSettings->maxStepHeight ); + + // if we should write out a ledge map + if ( ledgeMap ) { + sideList.SetNum( 0 ); + for ( j = 0; j < ledgeList[i].numPlanes; j++ ) { + sideList.Append( new idBrushSide( ledgeList[i].planes[j], -1 ) ); + } + + brush = new idBrush(); + brush->FromSides( sideList ); + + ledgeMap->WriteBrush( brush ); + + delete brush; + } + + // flood tree from the ledge node and subdivide areas with the ledge + LedgeSubdivLeafNodes_r( ledgeList[i].node, &ledgeList[i] ); + + // remove the node visited flags + ledgeList[i].node->RemoveFlagRecurseFlood( NODE_VISITED ); + } +} + +/* +============ +idAASBuild::IsLedgeSide_r +============ +*/ +bool idAASBuild::IsLedgeSide_r( idBrushBSPNode *node, idFixedWinding *w, const idPlane &plane, const idVec3 &normal, const idVec3 &origin, const float radius ) { + int res, i; + idFixedWinding back; + float dist; + + if ( !node ) { + return false; + } + + while ( node->GetChild(0) && node->GetChild(1) ) { + dist = node->GetPlane().Distance( origin ); + if ( dist > radius ) { + res = SIDE_FRONT; + } + else if ( dist < -radius ) { + res = SIDE_BACK; + } + else { + res = w->Split( &back, node->GetPlane(), LEDGE_EPSILON ); + } + if ( res == SIDE_FRONT ) { + node = node->GetChild(0); + } + else if ( res == SIDE_BACK ) { + node = node->GetChild(1); + } + else if ( res == SIDE_ON ) { + // continue with the side the winding faces + if ( node->GetPlane().Normal() * normal > 0.0f ) { + node = node->GetChild(0); + } + else { + node = node->GetChild(1); + } + } + else { + if ( IsLedgeSide_r( node->GetChild(1), &back, plane, normal, origin, radius ) ) { + return true; + } + node = node->GetChild(0); + } + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return false; + } + + for ( i = 0; i < w->GetNumPoints(); i++ ) { + if ( plane.Distance( (*w)[i].ToVec3() ) > 0.0f ) { + return true; + } + } + + return false; +} + +/* +============ +idAASBuild::AddLedge +============ +*/ +void idAASBuild::AddLedge( const idVec3 &v1, const idVec3 &v2, idBrushBSPNode *node ) { + int i, j, merged; + + // first try to merge the ledge with existing ledges + merged = -1; + for ( i = 0; i < ledgeList.Num(); i++ ) { + + for ( j = 0; j < 2; j++ ) { + if ( idMath::Fabs( ledgeList[i].planes[j].Distance( v1 ) ) > LEDGE_EPSILON ) { + break; + } + if ( idMath::Fabs( ledgeList[i].planes[j].Distance( v2 ) ) > LEDGE_EPSILON ) { + break; + } + } + if ( j < 2 ) { + continue; + } + + if ( !ledgeList[i].PointBetweenBounds( v1 ) && + !ledgeList[i].PointBetweenBounds( v2 ) ) { + continue; + } + + if ( merged == -1 ) { + ledgeList[i].AddPoint( v1 ); + ledgeList[i].AddPoint( v2 ); + merged = i; + } + else { + ledgeList[merged].AddPoint( ledgeList[i].start ); + ledgeList[merged].AddPoint( ledgeList[i].end ); + ledgeList.RemoveIndex(i); + break; + } + } + + // if the ledge could not be merged + if ( merged == -1 ) { + ledgeList.Append( idLedge( v1, v2, aasSettings->gravityDir, node ) ); + } +} + +/* +============ +idAASBuild::FindLeafNodeLedges +============ +*/ +void idAASBuild::FindLeafNodeLedges( idBrushBSPNode *root, idBrushBSPNode *node ) { + int s1, i; + idBrushBSPPortal *p1; + idWinding *w; + idVec3 v1, v2, normal, origin; + idFixedWinding winding; + idBounds bounds; + idPlane plane; + float radius; + + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( !(p1->GetFlags() & FACE_FLOOR) ) { + continue; + } + + if ( s1 ) { + plane = p1->GetPlane(); + w = p1->GetWinding()->Reverse(); + } + else { + plane = -p1->GetPlane(); + w = p1->GetWinding(); + } + + for ( i = 0; i < w->GetNumPoints(); i++ ) { + + v1 = (*w)[i].ToVec3(); + v2 = (*w)[(i+1)%w->GetNumPoints()].ToVec3(); + normal = (v2 - v1).Cross( aasSettings->gravityDir ); + if ( normal.Normalize() < 0.5f ) { + continue; + } + + winding.Clear(); + winding += v1 + normal * LEDGE_EPSILON * 0.5f; + winding += v2 + normal * LEDGE_EPSILON * 0.5f; + winding += winding[1].ToVec3() + ( aasSettings->maxStepHeight + 1.0f ) * aasSettings->gravityDir; + winding += winding[0].ToVec3() + ( aasSettings->maxStepHeight + 1.0f ) * aasSettings->gravityDir; + + winding.GetBounds( bounds ); + origin = (bounds[1] - bounds[0]) * 0.5f; + radius = origin.Length() + LEDGE_EPSILON; + origin = bounds[0] + origin; + + plane.FitThroughPoint( v1 + aasSettings->maxStepHeight * aasSettings->gravityDir ); + + if ( !IsLedgeSide_r( root, &winding, plane, normal, origin, radius ) ) { + continue; + } + + AddLedge( v1, v2, node ); + } + + if ( w != p1->GetWinding() ) { + delete w; + } + } +} + +/* +============ +idAASBuild::FindLedges_r +============ +*/ +void idAASBuild::FindLedges_r( idBrushBSPNode *root, idBrushBSPNode *node ) { + if ( !node ) { + return; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + if ( node->GetFlags() & NODE_VISITED ) { + return; + } + FindLeafNodeLedges( root, node ); + node->SetFlag( NODE_VISITED ); + return; + } + + FindLedges_r( root, node->GetChild(0) ); + FindLedges_r( root, node->GetChild(1) ); +} + +/* +============ +idAASBuild::WriteLedgeMap +============ +*/ +void idAASBuild::WriteLedgeMap( const idStr &fileName, const idStr &ext ) { + ledgeMap = new idBrushMap( fileName, ext ); + ledgeMap->SetTexture( "textures/base_trim/bluetex4q_ed" ); +} + +/* +============ +idAASBuild::LedgeSubdivision + + NOTE: this assumes the bounding box is higher than the maximum step height + only ledges with vertical sides are considered +============ +*/ +void idAASBuild::LedgeSubdivision( idBrushBSP &bsp ) { + numLedgeSubdivisions = 0; + ledgeList.Clear(); + + common->Printf( "[Ledge Subdivision]\n" ); + + bsp.GetRootNode()->RemoveFlagRecurse( NODE_VISITED ); + FindLedges_r( bsp.GetRootNode(), bsp.GetRootNode() ); + bsp.GetRootNode()->RemoveFlagRecurse( NODE_VISITED ); + + common->Printf( "\r%6d ledges\n", ledgeList.Num() ); + + LedgeSubdiv( bsp.GetRootNode() ); + + common->Printf( "\r%6d subdivisions\n", numLedgeSubdivisions ); +} diff --git a/tools/compilers/aas/AASBuild_local.h b/tools/compilers/aas/AASBuild_local.h new file mode 100644 index 000000000..4f6b20f5e --- /dev/null +++ b/tools/compilers/aas/AASBuild_local.h @@ -0,0 +1,140 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASBUILD_LOCAL_H__ +#define __AASBUILD_LOCAL_H__ + +#include "AASFile.h" +#include "AASFile_local.h" + +#include "Brush.h" +#include "BrushBSP.h" +#include "AASReach.h" +#include "AASCluster.h" + + +//=============================================================== +// +// idAASBuild +// +//=============================================================== + +typedef struct aasProcNode_s { + idPlane plane; + int children[2]; // negative numbers are (-1 - areaNumber), 0 = solid +} aasProcNode_t; + + +class idLedge { + +public: + idVec3 start; + idVec3 end; + idBrushBSPNode * node; + int numExpandedPlanes; + int numSplitPlanes; + int numPlanes; + idPlane planes[8]; + +public: + idLedge( void ); + idLedge( const idVec3 &v1, const idVec3 &v2, const idVec3 &gravityDir, idBrushBSPNode *n ); + void AddPoint( const idVec3 &v ); + void CreateBevels( const idVec3 &gravityDir ); + void Expand( const idBounds &bounds, float maxStepHeight ); + idWinding * ChopWinding( const idWinding *winding ) const; + bool PointBetweenBounds( const idVec3 &v ) const; +}; + + +class idAASBuild { + +public: + idAASBuild( void ); + ~idAASBuild( void ); + bool Build( const idStr &fileName, const idAASSettings *settings ); + bool BuildReachability( const idStr &fileName, const idAASSettings *settings ); + void Shutdown( void ); + +private: + const idAASSettings * aasSettings; + idAASFileLocal * file; + aasProcNode_t * procNodes; + int numProcNodes; + int numGravitationalSubdivisions; + int numMergedLeafNodes; + int numLedgeSubdivisions; + idList ledgeList; + idBrushMap * ledgeMap; + +private: // map loading + void ParseProcNodes( idLexer *src ); + bool LoadProcBSP( const char *name, ID_TIME_T minFileTime ); + void DeleteProcBSP( void ); + bool ChoppedAwayByProcBSP( int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius ); + void ClipBrushSidesWithProcBSP( idBrushList &brushList ); + int ContentsForAAS( int contents ); + idBrushList AddBrushesForMapBrush( const idMapBrush *mapBrush, const idVec3 &origin, const idMat3 &axis, int entityNum, int primitiveNum, idBrushList brushList ); + idBrushList AddBrushesForMapPatch( const idMapPatch *mapPatch, const idVec3 &origin, const idMat3 &axis, int entityNum, int primitiveNum, idBrushList brushList ); + idBrushList AddBrushesForMapEntity( const idMapEntity *mapEnt, int entityNum, idBrushList brushList ); + idBrushList AddBrushesForMapFile( const idMapFile * mapFile, idBrushList brushList ); + bool CheckForEntities( const idMapFile *mapFile, idStrList &entityClassNames ) const; + void ChangeMultipleBoundingBoxContents_r( idBrushBSPNode *node, int mask ); + +private: // gravitational subdivision + void SetPortalFlags_r( idBrushBSPNode *node ); + bool PortalIsGap( idBrushBSPPortal *portal, int side ); + void GravSubdivLeafNode( idBrushBSPNode *node ); + void GravSubdiv_r( idBrushBSPNode *node ); + void GravitationalSubdivision( idBrushBSP &bsp ); + +private: // ledge subdivision + void LedgeSubdivFlood_r( idBrushBSPNode *node, const idLedge *ledge ); + void LedgeSubdivLeafNodes_r( idBrushBSPNode *node, const idLedge *ledge ); + void LedgeSubdiv( idBrushBSPNode *root ); + bool IsLedgeSide_r( idBrushBSPNode *node, idFixedWinding *w, const idPlane &plane, const idVec3 &normal, const idVec3 &origin, const float radius ); + void AddLedge( const idVec3 &v1, const idVec3 &v2, idBrushBSPNode *node ); + void FindLeafNodeLedges( idBrushBSPNode *root, idBrushBSPNode *node ); + void FindLedges_r( idBrushBSPNode *root, idBrushBSPNode *node ); + void LedgeSubdivision( idBrushBSP &bsp ); + void WriteLedgeMap( const idStr &fileName, const idStr &ext ); + +private: // merging + bool AllGapsLeadToOtherNode( idBrushBSPNode *nodeWithGaps, idBrushBSPNode *otherNode ); + bool MergeWithAdjacentLeafNodes( idBrushBSP &bsp, idBrushBSPNode *node ); + void MergeLeafNodes_r( idBrushBSP &bsp, idBrushBSPNode *node ); + void MergeLeafNodes( idBrushBSP &bsp ); + +private: // storing file + void SetupHash( void ); + void ShutdownHash( void ); + void ClearHash( const idBounds &bounds ); + int HashVec( const idVec3 &vec ); + bool GetVertex( const idVec3 &v, int *vertexNum ); + bool GetEdge( const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num ); + bool GetFaceForPortal( idBrushBSPPortal *portal, int side, int *faceNum ); + bool GetAreaForLeafNode( idBrushBSPNode *node, int *areaNum ); + int StoreTree_r( idBrushBSPNode *node ); + void GetSizeEstimate_r( idBrushBSPNode *parent, idBrushBSPNode *node, struct sizeEstimate_s &size ); + void SetSizeEstimate( const idBrushBSP &bsp, idAASFileLocal *file ); + bool StoreFile( const idBrushBSP &bsp ); + +}; + +#endif /* !__AASBUILD_LOCAL_H__ */ diff --git a/tools/compilers/aas/AASBuild_merge.cpp b/tools/compilers/aas/AASBuild_merge.cpp new file mode 100644 index 000000000..f452bc1c1 --- /dev/null +++ b/tools/compilers/aas/AASBuild_merge.cpp @@ -0,0 +1,154 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASBuild_local.h" + +/* +============ +idAASBuild::AllGapsLeadToOtherNode +============ +*/ +bool idAASBuild::AllGapsLeadToOtherNode( idBrushBSPNode *nodeWithGaps, idBrushBSPNode *otherNode ) { + int s; + idBrushBSPPortal *p; + + for ( p = nodeWithGaps->GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == nodeWithGaps); + + if ( !PortalIsGap( p, s ) ) { + continue; + } + + if ( p->GetNode(!s) != otherNode ) { + return false; + } + } + return true; +} + +/* +============ +idAASBuild::MergeWithAdjacentLeafNodes +============ +*/ +bool idAASBuild::MergeWithAdjacentLeafNodes( idBrushBSP &bsp, idBrushBSPNode *node ) { + int s, numMerges = 0, otherNodeFlags; + idBrushBSPPortal *p; + + do { + for ( p = node->GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == node); + + // both leaf nodes must have the same contents + if ( node->GetContents() != p->GetNode(!s)->GetContents() ) { + continue; + } + + // cannot merge leaf nodes if one is near a ledge and the other is not + if ( (node->GetFlags() & AREA_LEDGE) != (p->GetNode(!s)->GetFlags() & AREA_LEDGE) ) { + continue; + } + + // cannot merge leaf nodes if one has a floor portal and the other a gap portal + if ( node->GetFlags() & AREA_FLOOR ) { + if ( p->GetNode(!s)->GetFlags() & AREA_GAP ) { + if ( !AllGapsLeadToOtherNode( p->GetNode(!s), node ) ) { + continue; + } + } + } + else if ( node->GetFlags() & AREA_GAP ) { + if ( p->GetNode(!s)->GetFlags() & AREA_FLOOR ) { + if ( !AllGapsLeadToOtherNode( node, p->GetNode(!s) ) ) { + continue; + } + } + } + + otherNodeFlags = p->GetNode(!s)->GetFlags(); + + // try to merge the leaf nodes + if ( bsp.TryMergeLeafNodes( p, s ) ) { + node->SetFlag( otherNodeFlags ); + if ( node->GetFlags() & AREA_FLOOR ) { + node->RemoveFlag( AREA_GAP ); + } + numMerges++; + DisplayRealTimeString( "\r%6d", ++numMergedLeafNodes ); + break; + } + } + } while( p ); + + if ( numMerges ) { + return true; + } + return false; +} + +/* +============ +idAASBuild::MergeLeafNodes_r +============ +*/ +void idAASBuild::MergeLeafNodes_r( idBrushBSP &bsp, idBrushBSPNode *node ) { + + if ( !node ) { + return; + } + + if ( node->GetContents() & AREACONTENTS_SOLID ) { + return; + } + + if ( node->GetFlags() & NODE_DONE ) { + return; + } + + if ( !node->GetChild(0) && !node->GetChild(1) ) { + MergeWithAdjacentLeafNodes( bsp, node ); + node->SetFlag( NODE_DONE ); + return; + } + + MergeLeafNodes_r( bsp, node->GetChild(0) ); + MergeLeafNodes_r( bsp, node->GetChild(1) ); + + return; +} + +/* +============ +idAASBuild::MergeLeafNodes +============ +*/ +void idAASBuild::MergeLeafNodes( idBrushBSP &bsp ) { + numMergedLeafNodes = 0; + + common->Printf( "[Merge Leaf Nodes]\n" ); + + MergeLeafNodes_r( bsp, bsp.GetRootNode() ); + bsp.GetRootNode()->RemoveFlagRecurse( NODE_DONE ); + bsp.PruneMergedTree_r( bsp.GetRootNode() ); + + common->Printf( "\r%6d leaf nodes merged\n", numMergedLeafNodes ); +} diff --git a/tools/compilers/aas/AASCluster.cpp b/tools/compilers/aas/AASCluster.cpp new file mode 100644 index 000000000..6e9939456 --- /dev/null +++ b/tools/compilers/aas/AASCluster.cpp @@ -0,0 +1,548 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" +#include "AASCluster.h" + + +/* +================ +idAASCluster::UpdatePortal +================ +*/ +bool idAASCluster::UpdatePortal( int areaNum, int clusterNum ) { + int portalNum; + aasPortal_t *portal; + + // find the portal for this area + for ( portalNum = 1; portalNum < file->portals.Num(); portalNum++ ) { + if ( file->portals[portalNum].areaNum == areaNum ) { + break; + } + } + + if ( portalNum >= file->portals.Num() ) { + common->Error( "no portal for area %d", areaNum ); + return true; + } + + portal = &file->portals[portalNum]; + + // if the portal is already fully updated + if ( portal->clusters[0] == clusterNum ) { + return true; + } + if ( portal->clusters[1] == clusterNum ) { + return true; + } + // if the portal has no front cluster yet + if ( !portal->clusters[0] ) { + portal->clusters[0] = clusterNum; + } + // if the portal has no back cluster yet + else if ( !portal->clusters[1] ) + { + portal->clusters[1] = clusterNum; + } + else + { + // remove the cluster portal flag contents + file->areas[areaNum].contents &= ~AREACONTENTS_CLUSTERPORTAL; + return false; + } + + // set the area cluster number to the negative portal number + file->areas[areaNum].cluster = -portalNum; + + // add the portal to the cluster using the portal index + file->portalIndex.Append( portalNum ); + file->clusters[clusterNum].numPortals++; + return true; +} + +/* +================ +idAASCluster::FloodClusterAreas_r +================ +*/ +bool idAASCluster::FloodClusterAreas_r( int areaNum, int clusterNum ) { + aasArea_t *area; + aasFace_t *face; + int faceNum, i; + idReachability *reach; + + area = &file->areas[areaNum]; + + // if the area is already part of a cluster + if ( area->cluster > 0 ) { + if ( area->cluster == clusterNum ) { + return true; + } + // there's a reachability going from one cluster to another only in one direction + common->Error( "cluster %d touched cluster %d at area %d\r\n", clusterNum, file->areas[areaNum].cluster, areaNum ); + return false; + } + + // if this area is a cluster portal + if ( area->contents & AREACONTENTS_CLUSTERPORTAL ) { + return UpdatePortal( areaNum, clusterNum ); + } + + // set the area cluster number + area->cluster = clusterNum; + + if ( !noFaceFlood ) { + // use area faces to flood into adjacent areas + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = abs(file->faceIndex[area->firstFace + i]); + face = &file->faces[faceNum]; + if ( face->areas[0] == areaNum ) { + if ( face->areas[1] ) { + if ( !FloodClusterAreas_r( face->areas[1], clusterNum ) ) { + return false; + } + } + } + else { + if ( face->areas[0] ) { + if ( !FloodClusterAreas_r( face->areas[0], clusterNum ) ) { + return false; + } + } + } + } + } + + // use the reachabilities to flood into other areas + for ( reach = file->areas[areaNum].reach; reach; reach = reach->next ) { + if ( !FloodClusterAreas_r( reach->toAreaNum, clusterNum) ) { + return false; + } + } + + // use the reversed reachabilities to flood into other areas + for ( reach = file->areas[areaNum].rev_reach; reach; reach = reach->rev_next ) { + if ( !FloodClusterAreas_r( reach->fromAreaNum, clusterNum) ) { + return false; + } + } + + return true; +} + +/* +================ +idAASCluster::RemoveAreaClusterNumbers +================ +*/ +void idAASCluster::RemoveAreaClusterNumbers( void ) { + int i; + + for ( i = 1; i < file->areas.Num(); i++ ) { + file->areas[i].cluster = 0; + } +} + +/* +================ +idAASCluster::NumberClusterAreas +================ +*/ +void idAASCluster::NumberClusterAreas( int clusterNum ) { + int i, portalNum; + aasCluster_t *cluster; + aasPortal_t *portal; + + cluster = &file->clusters[clusterNum]; + cluster->numAreas = 0; + cluster->numReachableAreas = 0; + + // number all areas in this cluster WITH reachabilities + for ( i = 1; i < file->areas.Num(); i++ ) { + + if ( file->areas[i].cluster != clusterNum ) { + continue; + } + + if ( !(file->areas[i].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { + continue; + } + + file->areas[i].clusterAreaNum = cluster->numAreas++; + cluster->numReachableAreas++; + } + + // number all portals in this cluster WITH reachabilities + for ( i = 0; i < cluster->numPortals; i++ ) { + portalNum = file->portalIndex[cluster->firstPortal + i]; + portal = &file->portals[portalNum]; + + if ( !(file->areas[portal->areaNum].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { + continue; + } + + if ( portal->clusters[0] == clusterNum ) { + portal->clusterAreaNum[0] = cluster->numAreas++; + } + else { + portal->clusterAreaNum[1] = cluster->numAreas++; + } + cluster->numReachableAreas++; + } + + // number all areas in this cluster WITHOUT reachabilities + for ( i = 1; i < file->areas.Num(); i++ ) { + + if ( file->areas[i].cluster != clusterNum ) { + continue; + } + + if ( file->areas[i].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { + continue; + } + + file->areas[i].clusterAreaNum = cluster->numAreas++; + } + + // number all portals in this cluster WITHOUT reachabilities + for ( i = 0; i < cluster->numPortals; i++ ) { + portalNum = file->portalIndex[cluster->firstPortal + i]; + portal = &file->portals[portalNum]; + + if ( file->areas[portal->areaNum].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { + continue; + } + + if ( portal->clusters[0] == clusterNum ) { + portal->clusterAreaNum[0] = cluster->numAreas++; + } + else { + portal->clusterAreaNum[1] = cluster->numAreas++; + } + } +} + +/* +================ +idAASCluster::FindClusters +================ +*/ +bool idAASCluster::FindClusters( void ) { + int i, clusterNum; + aasCluster_t cluster; + + RemoveAreaClusterNumbers(); + + for ( i = 1; i < file->areas.Num(); i++ ) { + // if the area is already part of a cluster + if ( file->areas[i].cluster ) { + continue; + } + + // if not flooding through faces only use areas that have reachabilities + if ( noFaceFlood ) { + if ( !(file->areas[i].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) ) { + continue; + } + } + + // if the area is a cluster portal + if ( file->areas[i].contents & AREACONTENTS_CLUSTERPORTAL ) { + continue; + } + + cluster.numAreas = 0; + cluster.numReachableAreas = 0; + cluster.firstPortal = file->portalIndex.Num(); + cluster.numPortals = 0; + clusterNum = file->clusters.Num(); + file->clusters.Append( cluster ); + + // flood the areas in this cluster + if ( !FloodClusterAreas_r( i, clusterNum ) ) { + return false; + } + + // number the cluster areas + NumberClusterAreas( clusterNum ); + } + return true; +} + +/* +================ +idAASCluster::CreatePortals +================ +*/ +void idAASCluster::CreatePortals( void ) { + int i; + aasPortal_t portal; + + for ( i = 1; i < file->areas.Num(); i++ ) { + // if the area is a cluster portal + if ( file->areas[i].contents & AREACONTENTS_CLUSTERPORTAL ) { + portal.areaNum = i; + portal.clusters[0] = portal.clusters[1] = 0; + portal.maxAreaTravelTime = 0; + file->portals.Append( portal ); + } + } +} + +/* +================ +idAASCluster::TestPortals +================ +*/ +bool idAASCluster::TestPortals( void ) { + int i; + aasPortal_t *portal, *portal2; + aasArea_t *area, *area2; + idReachability *reach; + bool ok; + + ok = true; + for ( i = 1; i < file->portals.Num(); i++ ) { + portal = &file->portals[i]; + area = &file->areas[portal->areaNum]; + + // if this portal was already removed + if ( !( area->contents & AREACONTENTS_CLUSTERPORTAL) ) { + continue; + } + + // may not removed this portal if it has a reachability to a removed portal + for ( reach = area->reach; reach; reach = reach->next ) { + area2 = &file->areas[ reach->toAreaNum ]; + if ( area2->contents & AREACONTENTS_CLUSTERPORTAL ) { + continue; + } + if ( area2->cluster < 0 ) { + break; + } + } + if ( reach ) { + continue; + } + + // may not removed this portal if it has a reversed reachability to a removed portal + for ( reach = area->rev_reach; reach; reach = reach->rev_next ) { + area2 = &file->areas[ reach->toAreaNum ]; + if ( area2->contents & AREACONTENTS_CLUSTERPORTAL ) { + continue; + } + if ( area2->cluster < 0 ) { + break; + } + } + if ( reach ) { + continue; + } + + // portal should have two clusters set + if ( !portal->clusters[0] ) { + area->contents &= ~AREACONTENTS_CLUSTERPORTAL; + ok = false; + continue; + } + if ( !portal->clusters[1] ) { + area->contents &= ~AREACONTENTS_CLUSTERPORTAL; + ok = false; + continue; + } + + // this portal may not have reachabilities to a portal that doesn't seperate the same clusters + for ( reach = area->reach; reach; reach = reach->next ) { + area2 = &file->areas[ reach->toAreaNum ]; + + if ( !(area2->contents & AREACONTENTS_CLUSTERPORTAL) ) { + continue; + } + + if ( area2->cluster > 0 ) { + area2->contents &= ~AREACONTENTS_CLUSTERPORTAL; + ok = false; + continue; + } + + portal2 = &file->portals[ -file->areas[ reach->toAreaNum ].cluster ]; + + if ( ( portal2->clusters[0] != portal->clusters[0] && portal2->clusters[0] != portal->clusters[1] ) || + ( portal2->clusters[1] != portal->clusters[0] && portal2->clusters[1] != portal->clusters[1] ) ) { + area2->contents &= ~AREACONTENTS_CLUSTERPORTAL; + ok = false; + continue; + } + } + } + + return ok; +} + +/* +================ +idAASCluster::RemoveInvalidPortals +================ +*/ +void idAASCluster::RemoveInvalidPortals( void ) { + int i, j, k, face1Num, face2Num, otherAreaNum, numOpenAreas, numInvalidPortals; + aasFace_t *face1, *face2; + + numInvalidPortals = 0; + for ( i = 0; i < file->areas.Num(); i++ ) { + if ( !( file->areas[i].contents & AREACONTENTS_CLUSTERPORTAL ) ) { + continue; + } + + numOpenAreas = 0; + for ( j = 0; j < file->areas[i].numFaces; j++ ) { + face1Num = file->faceIndex[ file->areas[i].firstFace + j ]; + face1 = &file->faces[ abs(face1Num) ]; + otherAreaNum = face1->areas[ face1Num < 0 ]; + + if ( !otherAreaNum ) { + continue; + } + + for ( k = 0; k < j; k++ ) { + face2Num = file->faceIndex[ file->areas[i].firstFace + k ]; + face2 = &file->faces[ abs(face2Num) ]; + if ( otherAreaNum == face2->areas[ face2Num < 0 ] ) { + break; + } + } + if ( k < j ) { + continue; + } + + if ( !( file->areas[otherAreaNum].contents & AREACONTENTS_CLUSTERPORTAL ) ) { + numOpenAreas++; + } + } + + if ( numOpenAreas <= 1 ) { + file->areas[i].contents &= AREACONTENTS_CLUSTERPORTAL; + numInvalidPortals++; + } + } + + common->Printf( "\r%6d invalid portals removed\n", numInvalidPortals ); +} + +/* +================ +idAASCluster::Build +================ +*/ +bool idAASCluster::Build( idAASFileLocal *file ) { + + common->Printf( "[Clustering]\n" ); + + this->file = file; + this->noFaceFlood = true; + + RemoveInvalidPortals(); + + while( 1 ) { + + // delete all existing clusters + file->DeleteClusters(); + + // create the portals from the portal areas + CreatePortals(); + + common->Printf( "\r%6d", file->portals.Num() ); + + // find the clusters + if ( !FindClusters() ) { + continue; + } + + // test the portals + if ( !TestPortals() ) { + continue; + } + + break; + } + + common->Printf( "\r%6d portals\n", file->portals.Num() ); + common->Printf( "%6d clusters\n", file->clusters.Num() ); + + for ( int i = 0; i < file->clusters.Num(); i++ ) { + common->Printf( "%6d reachable areas in cluster %d\n", file->clusters[i].numReachableAreas, i ); + } + + file->ReportRoutingEfficiency(); + + return true; +} + +/* +================ +idAASCluster::BuildSingleCluster +================ +*/ +bool idAASCluster::BuildSingleCluster( idAASFileLocal *file ) { + int i, numAreas; + aasCluster_t cluster; + + common->Printf( "[Clustering]\n" ); + + this->file = file; + + // delete all existing clusters + file->DeleteClusters(); + + cluster.firstPortal = 0; + cluster.numPortals = 0; + cluster.numAreas = file->areas.Num(); + cluster.numReachableAreas = 0; + // give all reachable areas in the cluster a number + for ( i = 0; i < file->areas.Num(); i++ ) { + file->areas[i].cluster = file->clusters.Num(); + if ( file->areas[i].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { + file->areas[i].clusterAreaNum = cluster.numReachableAreas++; + } + } + // give the remaining areas a number within the cluster + numAreas = cluster.numReachableAreas; + for ( i = 0; i < file->areas.Num(); i++ ) { + if ( file->areas[i].flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) { + continue; + } + file->areas[i].clusterAreaNum = numAreas++; + } + file->clusters.Append( cluster ); + + common->Printf( "%6d portals\n", file->portals.Num() ); + common->Printf( "%6d clusters\n", file->clusters.Num() ); + + for ( i = 0; i < file->clusters.Num(); i++ ) { + common->Printf( "%6d reachable areas in cluster %d\n", file->clusters[i].numReachableAreas, i ); + } + + file->ReportRoutingEfficiency(); + + return true; +} diff --git a/tools/compilers/aas/AASCluster.h b/tools/compilers/aas/AASCluster.h new file mode 100644 index 000000000..caca88bcc --- /dev/null +++ b/tools/compilers/aas/AASCluster.h @@ -0,0 +1,53 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASCLUSTER_H__ +#define __AASCLUSTER_H__ + +/* +=============================================================================== + + Area Clustering + +=============================================================================== +*/ + +class idAASCluster { + +public: + bool Build( idAASFileLocal *file ); + bool BuildSingleCluster( idAASFileLocal *file ); + +private: + idAASFileLocal * file; + bool noFaceFlood; + +private: + bool UpdatePortal( int areaNum, int clusterNum ); + bool FloodClusterAreas_r( int areaNum, int clusterNum ); + void RemoveAreaClusterNumbers( void ); + void NumberClusterAreas( int clusterNum ); + bool FindClusters( void ); + void CreatePortals( void ); + bool TestPortals( void ); + void ReportEfficiency( void ); + void RemoveInvalidPortals( void ); +}; + +#endif /* !__AASCLUSTER_H__ */ diff --git a/tools/compilers/aas/AASFile.cpp b/tools/compilers/aas/AASFile.cpp new file mode 100644 index 000000000..c8c26517d --- /dev/null +++ b/tools/compilers/aas/AASFile.cpp @@ -0,0 +1,1305 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" + + +/* +=============================================================================== + + idReachability + +=============================================================================== +*/ + +/* +================ +Reachability_Write +================ +*/ +bool Reachability_Write( idFile *fp, idReachability *reach ) { + fp->WriteFloatString( "\t\t%d %d (%f %f %f) (%f %f %f) %d %d", + (int) reach->travelType, (int) reach->toAreaNum, reach->start.x, reach->start.y, reach->start.z, + reach->end.x, reach->end.y, reach->end.z, reach->edgeNum, (int) reach->travelTime ); + return true; +} + +/* +================ +Reachability_Read +================ +*/ +bool Reachability_Read( idLexer &src, idReachability *reach ) { + reach->travelType = src.ParseInt(); + reach->toAreaNum = src.ParseInt(); + src.Parse1DMatrix( 3, reach->start.ToFloatPtr() ); + src.Parse1DMatrix( 3, reach->end.ToFloatPtr() ); + reach->edgeNum = src.ParseInt(); + reach->travelTime = src.ParseInt(); + return true; +} + +/* +================ +idReachability::CopyBase +================ +*/ +void idReachability::CopyBase( idReachability &reach ) { + travelType = reach.travelType; + toAreaNum = reach.toAreaNum; + start = reach.start; + end = reach.end; + edgeNum = reach.edgeNum; + travelTime = reach.travelTime; +} + + +/* +=============================================================================== + + idReachability_Special + +=============================================================================== +*/ + +/* +================ +Reachability_Special_Write +================ +*/ +bool Reachability_Special_Write( idFile *fp, idReachability_Special *reach ) { + int i; + const idKeyValue *keyValue; + + fp->WriteFloatString( "\n\t\t{\n" ); + for ( i = 0; i < reach->dict.GetNumKeyVals(); i++ ) { + keyValue = reach->dict.GetKeyVal( i ); + fp->WriteFloatString( "\t\t\t\"%s\" \"%s\"\n", keyValue->GetKey().c_str(), keyValue->GetValue().c_str() ); + } + fp->WriteFloatString( "\t\t}\n" ); + + return true; +} + +/* +================ +Reachability_Special_Read +================ +*/ +bool Reachability_Special_Read( idLexer &src, idReachability_Special *reach ) { + idToken key, value; + + src.ExpectTokenString( "{" ); + while( src.ReadToken( &key ) ) { + if ( key == "}" ) { + return true; + } + src.ExpectTokenType( TT_STRING, 0, &value ); + reach->dict.Set( key, value ); + } + return false; +} + +/* +=============================================================================== + + idAASSettings + +=============================================================================== +*/ + +/* +============ +idAASSettings::idAASSettings +============ +*/ +idAASSettings::idAASSettings( void ) { + numBoundingBoxes = 1; + boundingBoxes[0] = idBounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 72 ) ); + usePatches = false; + writeBrushMap = false; + playerFlood = false; + noOptimize = false; + allowSwimReachabilities = false; + allowFlyReachabilities = false; + fileExtension = "aas48"; + // physics settings + gravity = idVec3( 0, 0, -1066 ); + gravityDir = gravity; + gravityValue = gravityDir.Normalize(); + invGravityDir = -gravityDir; + maxStepHeight = 14.0f; + maxBarrierHeight = 32.0f; + maxWaterJumpHeight = 20.0f; + maxFallHeight = 64.0f; + minFloorCos = 0.7f; + // fixed travel times + tt_barrierJump = 100; + tt_startCrouching = 100; + tt_waterJump = 100; + tt_startWalkOffLedge = 100; +} + +/* +============ +idAASSettings::ParseBool +============ +*/ +bool idAASSettings::ParseBool( idLexer &src, bool &b ) { + if ( !src.ExpectTokenString( "=" ) ) { + return false; + } + b = src.ParseBool(); + return true; +} + +/* +============ +idAASSettings::ParseInt +============ +*/ +bool idAASSettings::ParseInt( idLexer &src, int &i ) { + if ( !src.ExpectTokenString( "=" ) ) { + return false; + } + i = src.ParseInt(); + return true; +} + +/* +============ +idAASSettings::ParseFloat +============ +*/ +bool idAASSettings::ParseFloat( idLexer &src, float &f ) { + if ( !src.ExpectTokenString( "=" ) ) { + return false; + } + f = src.ParseFloat(); + return true; +} + +/* +============ +idAASSettings::ParseVector +============ +*/ +bool idAASSettings::ParseVector( idLexer &src, idVec3 &vec ) { + if ( !src.ExpectTokenString( "=" ) ) { + return false; + } + return ( src.Parse1DMatrix( 3, vec.ToFloatPtr() ) != 0 ); +} + +/* +============ +idAASSettings::ParseBBoxes +============ +*/ +bool idAASSettings::ParseBBoxes( idLexer &src ) { + idToken token; + idBounds bounds; + + numBoundingBoxes = 0; + + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + while( src.ReadToken( &token ) ) { + if ( token == "}" ) { + return true; + } + src.UnreadToken( &token ); + src.Parse1DMatrix( 3, bounds[0].ToFloatPtr() ); + if ( !src.ExpectTokenString( "-" ) ) { + return false; + } + src.Parse1DMatrix( 3, bounds[1].ToFloatPtr() ); + + boundingBoxes[numBoundingBoxes++] = bounds; + } + return false; +} + +/* +============ +idAASSettings::FromParser +============ +*/ +bool idAASSettings::FromParser( idLexer &src ) { + idToken token; + + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + + // parse the file + while ( 1 ) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "}" ) { + break; + } + + if ( token == "bboxes" ) { + if ( !ParseBBoxes( src ) ) { return false; } + } + else if ( token == "usePatches" ) { + if ( !ParseBool( src, usePatches ) ) { return false; } + } + else if ( token == "writeBrushMap" ) { + if ( !ParseBool( src, writeBrushMap ) ) { return false; } + } + else if ( token == "playerFlood" ) { + if ( !ParseBool( src, playerFlood ) ) { return false; } + } + else if ( token == "allowSwimReachabilities" ) { + if ( !ParseBool( src, allowSwimReachabilities ) ) { return false; } + } + else if ( token == "allowFlyReachabilities" ) { + if ( !ParseBool( src, allowFlyReachabilities ) ) { return false; } + } + else if ( token == "fileExtension" ) { + src.ExpectTokenString( "=" ); + src.ExpectTokenType( TT_STRING, 0, &token ); + fileExtension = token; + } + else if ( token == "gravity" ) { + ParseVector( src, gravity ); + gravityDir = gravity; + gravityValue = gravityDir.Normalize(); + invGravityDir = -gravityDir; + } + else if ( token == "maxStepHeight" ) { + if ( !ParseFloat( src, maxStepHeight ) ) { return false; } + } + else if ( token == "maxBarrierHeight" ) { + if ( !ParseFloat( src, maxBarrierHeight ) ) { return false; } + } + else if ( token == "maxWaterJumpHeight" ) { + if ( !ParseFloat( src, maxWaterJumpHeight ) ) { return false; } + } + else if ( token == "maxFallHeight" ) { + if ( !ParseFloat( src, maxFallHeight ) ) { return false; } + } + else if ( token == "minFloorCos" ) { + if ( !ParseFloat( src, minFloorCos ) ) { return false; } + } + else if ( token == "tt_barrierJump" ) { + if ( !ParseInt( src, tt_barrierJump ) ) { return false; } + } + else if ( token == "tt_startCrouching" ) { + if ( !ParseInt( src, tt_startCrouching ) ) { return false; } + } + else if ( token == "tt_waterJump" ) { + if ( !ParseInt( src, tt_waterJump ) ) { return false; } + } + else if ( token == "tt_startWalkOffLedge" ) { + if ( !ParseInt( src, tt_startWalkOffLedge ) ) { return false; } + } + else { + src.Error( "invalid token '%s'", token.c_str() ); + } + } + + if ( numBoundingBoxes <= 0 ) { + src.Error( "no valid bounding box" ); + } + + return true; +} + +/* +============ +idAASSettings::FromFile +============ +*/ +bool idAASSettings::FromFile( const idStr &fileName ) { + idLexer src( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT ); + idStr name; + + name = fileName; + + common->Printf( "loading %s\n", name.c_str() ); + + if ( !src.LoadFile( name ) ) { + common->Error( "WARNING: couldn't load %s\n", name.c_str() ); + return false; + } + + if ( !src.ExpectTokenString( "settings" ) ) { + common->Error( "%s is not a settings file", name.c_str() ); + return false; + } + + if ( !FromParser( src ) ) { + common->Error( "failed to parse %s", name.c_str() ); + return false; + } + + return true; +} + +/* +============ +idAASSettings::FromDict +============ +*/ +bool idAASSettings::FromDict( const char *name, const idDict *dict ) { + idBounds bounds; + + if ( !dict->GetVector( "mins", "0 0 0", bounds[ 0 ] ) ) { + common->Error( "Missing 'mins' in entityDef '%s'", name ); + } + if ( !dict->GetVector( "maxs", "0 0 0", bounds[ 1 ] ) ) { + common->Error( "Missing 'maxs' in entityDef '%s'", name ); + } + + numBoundingBoxes = 1; + boundingBoxes[0] = bounds; + + if ( !dict->GetBool( "usePatches", "0", usePatches ) ) { + common->Error( "Missing 'usePatches' in entityDef '%s'", name ); + } + + if ( !dict->GetBool( "writeBrushMap", "0", writeBrushMap ) ) { + common->Error( "Missing 'writeBrushMap' in entityDef '%s'", name ); + } + + if ( !dict->GetBool( "playerFlood", "0", playerFlood ) ) { + common->Error( "Missing 'playerFlood' in entityDef '%s'", name ); + } + + if ( !dict->GetBool( "allowSwimReachabilities", "0", allowSwimReachabilities ) ) { + common->Error( "Missing 'allowSwimReachabilities' in entityDef '%s'", name ); + } + + if ( !dict->GetBool( "allowFlyReachabilities", "0", allowFlyReachabilities ) ) { + common->Error( "Missing 'allowFlyReachabilities' in entityDef '%s'", name ); + } + + if ( !dict->GetString( "fileExtension", "", fileExtension ) ) { + common->Error( "Missing 'fileExtension' in entityDef '%s'", name ); + } + + if ( !dict->GetVector( "gravity", "0 0 -1066", gravity ) ) { + common->Error( "Missing 'gravity' in entityDef '%s'", name ); + } + gravityDir = gravity; + gravityValue = gravityDir.Normalize(); + invGravityDir = -gravityDir; + + if ( !dict->GetFloat( "maxStepHeight", "0", maxStepHeight ) ) { + common->Error( "Missing 'maxStepHeight' in entityDef '%s'", name ); + } + + if ( !dict->GetFloat( "maxBarrierHeight", "0", maxBarrierHeight ) ) { + common->Error( "Missing 'maxBarrierHeight' in entityDef '%s'", name ); + } + + if ( !dict->GetFloat( "maxWaterJumpHeight", "0", maxWaterJumpHeight ) ) { + common->Error( "Missing 'maxWaterJumpHeight' in entityDef '%s'", name ); + } + + if ( !dict->GetFloat( "maxFallHeight", "0", maxFallHeight ) ) { + common->Error( "Missing 'maxFallHeight' in entityDef '%s'", name ); + } + + if ( !dict->GetFloat( "minFloorCos", "0", minFloorCos ) ) { + common->Error( "Missing 'minFloorCos' in entityDef '%s'", name ); + } + + if ( !dict->GetInt( "tt_barrierJump", "0", tt_barrierJump ) ) { + common->Error( "Missing 'tt_barrierJump' in entityDef '%s'", name ); + } + + if ( !dict->GetInt( "tt_startCrouching", "0", tt_startCrouching ) ) { + common->Error( "Missing 'tt_startCrouching' in entityDef '%s'", name ); + } + + if ( !dict->GetInt( "tt_waterJump", "0", tt_waterJump ) ) { + common->Error( "Missing 'tt_waterJump' in entityDef '%s'", name ); + } + + if ( !dict->GetInt( "tt_startWalkOffLedge", "0", tt_startWalkOffLedge ) ) { + common->Error( "Missing 'tt_startWalkOffLedge' in entityDef '%s'", name ); + } + + return true; +} + + +/* +============ +idAASSettings::WriteToFile +============ +*/ +bool idAASSettings::WriteToFile( idFile *fp ) const { + int i; + + fp->WriteFloatString( "{\n" ); + fp->WriteFloatString( "\tbboxes\n\t{\n" ); + for ( i = 0; i < numBoundingBoxes; i++ ) { + fp->WriteFloatString( "\t\t(%f %f %f)-(%f %f %f)\n", boundingBoxes[i][0].x, boundingBoxes[i][0].y, + boundingBoxes[i][0].z, boundingBoxes[i][1].x, boundingBoxes[i][1].y, boundingBoxes[i][1].z ); + } + fp->WriteFloatString( "\t}\n" ); + fp->WriteFloatString( "\tusePatches = %d\n", usePatches ); + fp->WriteFloatString( "\twriteBrushMap = %d\n", writeBrushMap ); + fp->WriteFloatString( "\tplayerFlood = %d\n", playerFlood ); + fp->WriteFloatString( "\tallowSwimReachabilities = %d\n", allowSwimReachabilities ); + fp->WriteFloatString( "\tallowFlyReachabilities = %d\n", allowFlyReachabilities ); + fp->WriteFloatString( "\tfileExtension = \"%s\"\n", fileExtension.c_str() ); + fp->WriteFloatString( "\tgravity = (%f %f %f)\n", gravity.x, gravity.y, gravity.z ); + fp->WriteFloatString( "\tmaxStepHeight = %f\n", maxStepHeight ); + fp->WriteFloatString( "\tmaxBarrierHeight = %f\n", maxBarrierHeight ); + fp->WriteFloatString( "\tmaxWaterJumpHeight = %f\n", maxWaterJumpHeight ); + fp->WriteFloatString( "\tmaxFallHeight = %f\n", maxFallHeight ); + fp->WriteFloatString( "\tminFloorCos = %f\n", minFloorCos ); + fp->WriteFloatString( "\ttt_barrierJump = %d\n", tt_barrierJump ); + fp->WriteFloatString( "\ttt_startCrouching = %d\n", tt_startCrouching ); + fp->WriteFloatString( "\ttt_waterJump = %d\n", tt_waterJump ); + fp->WriteFloatString( "\ttt_startWalkOffLedge = %d\n", tt_startWalkOffLedge ); + fp->WriteFloatString( "}\n" ); + return true; +} + +/* +============ +idAASSettings::ValidForBounds +============ +*/ +bool idAASSettings::ValidForBounds( const idBounds &bounds ) const { + int i; + + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] < boundingBoxes[0][0][i] ) { + return false; + } + if ( bounds[1][i] > boundingBoxes[0][1][i] ) { + return false; + } + } + return true; +} + +/* +============ +idAASSettings::ValidEntity +============ +*/ +bool idAASSettings::ValidEntity( const char *classname ) const { + idStr use_aas; + idVec3 size; + idBounds bounds; + + if ( playerFlood ) { + if ( !strcmp( classname, "info_player_start" ) || !strcmp( classname , "info_player_deathmatch" ) || !strcmp( classname, "func_teleporter" ) ) { + return true; + } + } + + const idDeclEntityDef *decl = static_cast( declManager->FindType( DECL_ENTITYDEF, classname, false ) ); + if ( decl && decl->dict.GetString( "use_aas", NULL, use_aas ) && !fileExtension.Icmp( use_aas ) ) { + if ( decl->dict.GetVector( "mins", NULL, bounds[0] ) ) { + decl->dict.GetVector( "maxs", NULL, bounds[1] ); + } else if ( decl->dict.GetVector( "size", NULL, size ) ) { + bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f ); + bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z ); + } + + if ( !ValidForBounds( bounds ) ) { + common->Error( "%s cannot use %s\n", classname, fileExtension.c_str() ); + } + + return true; + } + + return false; +} + + +/* +=============================================================================== + + idAASFileLocal + +=============================================================================== +*/ + +#define AAS_LIST_GRANULARITY 1024 +#define AAS_INDEX_GRANULARITY 4096 +#define AAS_PLANE_GRANULARITY 4096 +#define AAS_VERTEX_GRANULARITY 4096 +#define AAS_EDGE_GRANULARITY 4096 + +/* +================ +idAASFileLocal::idAASFileLocal +================ +*/ +idAASFileLocal::idAASFileLocal( void ) { + planeList.SetGranularity( AAS_PLANE_GRANULARITY ); + vertices.SetGranularity( AAS_VERTEX_GRANULARITY ); + edges.SetGranularity( AAS_EDGE_GRANULARITY ); + edgeIndex.SetGranularity( AAS_INDEX_GRANULARITY ); + faces.SetGranularity( AAS_LIST_GRANULARITY ); + faceIndex.SetGranularity( AAS_INDEX_GRANULARITY ); + areas.SetGranularity( AAS_LIST_GRANULARITY ); + nodes.SetGranularity( AAS_LIST_GRANULARITY ); + portals.SetGranularity( AAS_LIST_GRANULARITY ); + portalIndex.SetGranularity( AAS_INDEX_GRANULARITY ); + clusters.SetGranularity( AAS_LIST_GRANULARITY ); +} + +/* +================ +idAASFileLocal::~idAASFileLocal +================ +*/ +idAASFileLocal::~idAASFileLocal( void ) { + int i; + idReachability *reach, *next; + + for ( i = 0; i < areas.Num(); i++ ) { + for ( reach = areas[i].reach; reach; reach = next ) { + next = reach->next; + delete reach; + } + } +} + +/* +================ +idAASFileLocal::Clear +================ +*/ +void idAASFileLocal::Clear( void ) { + planeList.Clear(); + vertices.Clear(); + edges.Clear(); + edgeIndex.Clear(); + faces.Clear(); + faceIndex.Clear(); + areas.Clear(); + nodes.Clear(); + portals.Clear(); + portalIndex.Clear(); + clusters.Clear(); +} + +/* +================ +idAASFileLocal::Write +================ +*/ +bool idAASFileLocal::Write( const idStr &fileName, unsigned int mapFileCRC ) { + int i, num; + idFile *aasFile; + idReachability *reach; + + common->Printf( "[Write AAS]\n" ); + common->Printf( "writing %s\n", fileName.c_str() ); + + name = fileName; + crc = mapFileCRC; + + aasFile = fileSystem->OpenFileWrite( fileName, "fs_devpath" ); + if ( !aasFile ) { + common->Error( "Error opening %s", fileName.c_str() ); + return false; + } + + aasFile->WriteFloatString( "%s \"%s\"\n\n", AAS_FILEID, AAS_FILEVERSION ); + aasFile->WriteFloatString( "%u\n\n", mapFileCRC ); + + // write out the settings + aasFile->WriteFloatString( "settings\n" ); + settings.WriteToFile( aasFile ); + + // write out planes + aasFile->WriteFloatString( "planes %d {\n", planeList.Num() ); + for ( i = 0; i < planeList.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %f %f %f %f )\n", i, + planeList[i].Normal().x, planeList[i].Normal().y, planeList[i].Normal().z, planeList[i].Dist() ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out vertices + aasFile->WriteFloatString( "vertices %d {\n", vertices.Num() ); + for ( i = 0; i < vertices.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %f %f %f )\n", i, vertices[i].x, vertices[i].y, vertices[i].z ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out edges + aasFile->WriteFloatString( "edges %d {\n", edges.Num() ); + for ( i = 0; i < edges.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d %d )\n", i, edges[i].vertexNum[0], edges[i].vertexNum[1] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out edgeIndex + aasFile->WriteFloatString( "edgeIndex %d {\n", edgeIndex.Num() ); + for ( i = 0; i < edgeIndex.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d )\n", i, edgeIndex[i] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out faces + aasFile->WriteFloatString( "faces %d {\n", faces.Num() ); + for ( i = 0; i < faces.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d %d )\n", i, faces[i].planeNum, faces[i].flags, + faces[i].areas[0], faces[i].areas[1], faces[i].firstEdge, faces[i].numEdges ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out faceIndex + aasFile->WriteFloatString( "faceIndex %d {\n", faceIndex.Num() ); + for ( i = 0; i < faceIndex.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d )\n", i, faceIndex[i] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out areas + aasFile->WriteFloatString( "areas %d {\n", areas.Num() ); + for ( i = 0; i < areas.Num(); i++ ) { + for ( num = 0, reach = areas[i].reach; reach; reach = reach->next ) { + num++; + } + aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d %d ) %d {\n", i, areas[i].flags, areas[i].contents, + areas[i].firstFace, areas[i].numFaces, areas[i].cluster, areas[i].clusterAreaNum, num ); + for ( reach = areas[i].reach; reach; reach = reach->next ) { + Reachability_Write( aasFile, reach ); + switch( reach->travelType ) { + case TFL_SPECIAL: + Reachability_Special_Write( aasFile, static_cast(reach) ); + break; + } + aasFile->WriteFloatString( "\n" ); + } + aasFile->WriteFloatString( "\t}\n" ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out nodes + aasFile->WriteFloatString( "nodes %d {\n", nodes.Num() ); + for ( i = 0; i < nodes.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d %d %d )\n", i, nodes[i].planeNum, nodes[i].children[0], nodes[i].children[1] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out portals + aasFile->WriteFloatString( "portals %d {\n", portals.Num() ); + for ( i = 0; i < portals.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d )\n", i, portals[i].areaNum, portals[i].clusters[0], + portals[i].clusters[1], portals[i].clusterAreaNum[0], portals[i].clusterAreaNum[1] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out portalIndex + aasFile->WriteFloatString( "portalIndex %d {\n", portalIndex.Num() ); + for ( i = 0; i < portalIndex.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d )\n", i, portalIndex[i] ); + } + aasFile->WriteFloatString( "}\n" ); + + // write out clusters + aasFile->WriteFloatString( "clusters %d {\n", clusters.Num() ); + for ( i = 0; i < clusters.Num(); i++ ) { + aasFile->WriteFloatString( "\t%d ( %d %d %d %d )\n", i, clusters[i].numAreas, clusters[i].numReachableAreas, + clusters[i].firstPortal, clusters[i].numPortals ); + } + aasFile->WriteFloatString( "}\n" ); + + // close file + fileSystem->CloseFile( aasFile ); + + common->Printf( "done.\n" ); + + return true; +} + +/* +================ +idAASFileLocal::ParseIndex +================ +*/ +bool idAASFileLocal::ParseIndex( idLexer &src, idList &indexes ) { + int numIndexes, i; + aasIndex_t index; + + numIndexes = src.ParseInt(); + indexes.Resize( numIndexes ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numIndexes; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + index = src.ParseInt(); + src.ExpectTokenString( ")" ); + indexes.Append( index ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParsePlanes +================ +*/ +bool idAASFileLocal::ParsePlanes( idLexer &src ) { + int numPlanes, i; + idPlane plane; + idVec4 vec; + + numPlanes = src.ParseInt(); + planeList.Resize( numPlanes ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numPlanes; i++ ) { + src.ParseInt(); + if ( !src.Parse1DMatrix( 4, vec.ToFloatPtr() ) ) { + return false; + } + plane.SetNormal( vec.ToVec3() ); + plane.SetDist( vec[3] ); + planeList.Append( plane ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParseVertices +================ +*/ +bool idAASFileLocal::ParseVertices( idLexer &src ) { + int numVertices, i; + idVec3 vec; + + numVertices = src.ParseInt(); + vertices.Resize( numVertices ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numVertices; i++ ) { + src.ParseInt(); + if ( !src.Parse1DMatrix( 3, vec.ToFloatPtr() ) ) { + return false; + } + vertices.Append( vec ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParseEdges +================ +*/ +bool idAASFileLocal::ParseEdges( idLexer &src ) { + int numEdges, i; + aasEdge_t edge; + + numEdges = src.ParseInt(); + edges.Resize( numEdges ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numEdges; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + edge.vertexNum[0] = src.ParseInt(); + edge.vertexNum[1] = src.ParseInt(); + src.ExpectTokenString( ")" ); + edges.Append( edge ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParseFaces +================ +*/ +bool idAASFileLocal::ParseFaces( idLexer &src ) { + int numFaces, i; + aasFace_t face; + + numFaces = src.ParseInt(); + faces.Resize( numFaces ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numFaces; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + face.planeNum = src.ParseInt(); + face.flags = src.ParseInt(); + face.areas[0] = src.ParseInt(); + face.areas[1] = src.ParseInt(); + face.firstEdge = src.ParseInt(); + face.numEdges = src.ParseInt(); + src.ExpectTokenString( ")" ); + faces.Append( face ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParseReachabilities +================ +*/ +bool idAASFileLocal::ParseReachabilities( idLexer &src, int areaNum ) { + int num, j; + aasArea_t *area; + idReachability reach, *newReach; + idReachability_Special *special; + + area = &areas[areaNum]; + + num = src.ParseInt(); + src.ExpectTokenString( "{" ); + area->reach = NULL; + area->rev_reach = NULL; + area->travelFlags = AreaContentsTravelFlags( areaNum ); + for ( j = 0; j < num; j++ ) { + Reachability_Read( src, &reach ); + switch( reach.travelType ) { + case TFL_SPECIAL: + newReach = special = new idReachability_Special(); + Reachability_Special_Read( src, special ); + break; + default: + newReach = new idReachability(); + break; + } + newReach->CopyBase( reach ); + newReach->fromAreaNum = areaNum; + newReach->next = area->reach; + area->reach = newReach; + } + src.ExpectTokenString( "}" ); + return true; +} + +/* +================ +idAASFileLocal::LinkReversedReachability +================ +*/ +void idAASFileLocal::LinkReversedReachability( void ) { + int i; + idReachability *reach; + + // link reversed reachabilities + for ( i = 0; i < areas.Num(); i++ ) { + for ( reach = areas[i].reach; reach; reach = reach->next ) { + reach->rev_next = areas[reach->toAreaNum].rev_reach; + areas[reach->toAreaNum].rev_reach = reach; + } + } +} + +/* +================ +idAASFileLocal::ParseAreas +================ +*/ +bool idAASFileLocal::ParseAreas( idLexer &src ) { + int numAreas, i; + aasArea_t area; + + numAreas = src.ParseInt(); + areas.Resize( numAreas ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numAreas; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + area.flags = src.ParseInt(); + area.contents = src.ParseInt(); + area.firstFace = src.ParseInt(); + area.numFaces = src.ParseInt(); + area.cluster = src.ParseInt(); + area.clusterAreaNum = src.ParseInt(); + src.ExpectTokenString( ")" ); + areas.Append( area ); + ParseReachabilities( src, i ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + + LinkReversedReachability(); + + return true; +} + +/* +================ +idAASFileLocal::ParseNodes +================ +*/ +bool idAASFileLocal::ParseNodes( idLexer &src ) { + int numNodes, i; + aasNode_t node; + + numNodes = src.ParseInt(); + nodes.Resize( numNodes ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numNodes; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + node.planeNum = src.ParseInt(); + node.children[0] = src.ParseInt(); + node.children[1] = src.ParseInt(); + src.ExpectTokenString( ")" ); + nodes.Append( node ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParsePortals +================ +*/ +bool idAASFileLocal::ParsePortals( idLexer &src ) { + int numPortals, i; + aasPortal_t portal; + + numPortals = src.ParseInt(); + portals.Resize( numPortals ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numPortals; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + portal.areaNum = src.ParseInt(); + portal.clusters[0] = src.ParseInt(); + portal.clusters[1] = src.ParseInt(); + portal.clusterAreaNum[0] = src.ParseInt(); + portal.clusterAreaNum[1] = src.ParseInt(); + src.ExpectTokenString( ")" ); + portals.Append( portal ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::ParseClusters +================ +*/ +bool idAASFileLocal::ParseClusters( idLexer &src ) { + int numClusters, i; + aasCluster_t cluster; + + numClusters = src.ParseInt(); + clusters.Resize( numClusters ); + if ( !src.ExpectTokenString( "{" ) ) { + return false; + } + for ( i = 0; i < numClusters; i++ ) { + src.ParseInt(); + src.ExpectTokenString( "(" ); + cluster.numAreas = src.ParseInt(); + cluster.numReachableAreas = src.ParseInt(); + cluster.firstPortal = src.ParseInt(); + cluster.numPortals = src.ParseInt(); + src.ExpectTokenString( ")" ); + clusters.Append( cluster ); + } + if ( !src.ExpectTokenString( "}" ) ) { + return false; + } + return true; +} + +/* +================ +idAASFileLocal::FinishAreas +================ +*/ +void idAASFileLocal::FinishAreas( void ) { + int i; + + for ( i = 0; i < areas.Num(); i++ ) { + areas[i].center = AreaReachableGoal( i ); + areas[i].bounds = AreaBounds( i ); + } +} + +/* +================ +idAASFileLocal::Load +================ +*/ +bool idAASFileLocal::Load( const idStr &fileName, unsigned int mapFileCRC ) { + idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES ); + idToken token; + int depth; + unsigned int c; + + name = fileName; + crc = mapFileCRC; + + common->Printf( "[Load AAS]\n" ); + common->Printf( "loading %s\n", name.c_str() ); + + if ( !src.LoadFile( name ) ) { + return false; + } + + if ( !src.ExpectTokenString( AAS_FILEID ) ) { + common->Warning( "Not an AAS file: '%s'", name.c_str() ); + return false; + } + + if ( !src.ReadToken( &token ) || token != AAS_FILEVERSION ) { + common->Warning( "AAS file '%s' has version %s instead of %s", name.c_str(), token.c_str(), AAS_FILEVERSION ); + return false; + } + + if ( !src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) { + common->Warning( "AAS file '%s' has no map file CRC", name.c_str() ); + return false; + } + + c = token.GetUnsignedLongValue(); + if ( mapFileCRC && c != mapFileCRC ) { + common->Warning( "AAS file '%s' is out of date", name.c_str() ); + return false; + } + + // clear the file in memory + Clear(); + + // parse the file + while ( 1 ) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( token == "settings" ) { + if ( !settings.FromParser( src ) ) { return false; } + } + else if ( token == "planes" ) { + if ( !ParsePlanes( src ) ) { return false; } + } + else if ( token == "vertices" ) { + if ( !ParseVertices( src ) ) { return false; } + } + else if ( token == "edges" ) { + if ( !ParseEdges( src ) ) { return false; } + } + else if ( token == "edgeIndex" ) { + if ( !ParseIndex( src, edgeIndex ) ) { return false; } + } + else if ( token == "faces" ) { + if ( !ParseFaces( src ) ) { return false; } + } + else if ( token == "faceIndex" ) { + if ( !ParseIndex( src, faceIndex ) ) { return false; } + } + else if ( token == "areas" ) { + if ( !ParseAreas( src ) ) { return false; } + } + else if ( token == "nodes" ) { + if ( !ParseNodes( src ) ) { return false; } + } + else if ( token == "portals" ) { + if ( !ParsePortals( src ) ) { return false; } + } + else if ( token == "portalIndex" ) { + if ( !ParseIndex( src, portalIndex ) ) { return false; } + } + else if ( token == "clusters" ) { + if ( !ParseClusters( src ) ) { return false; } + } + else { + src.Error( "idAASFileLocal::Load: bad token \"%s\"", token.c_str() ); + return false; + } + } + + FinishAreas(); + + depth = MaxTreeDepth(); + if ( depth > MAX_AAS_TREE_DEPTH ) { + src.Error( "idAASFileLocal::Load: tree depth = %d", depth ); + } + + common->Printf( "done.\n" ); + + return true; +} + +/* +================ +idAASFileLocal::MemorySize +================ +*/ +int idAASFileLocal::MemorySize( void ) const { + int size; + + size = planeList.Size(); + size += vertices.Size(); + size += edges.Size(); + size += edgeIndex.Size(); + size += faces.Size(); + size += faceIndex.Size(); + size += areas.Size(); + size += nodes.Size(); + size += portals.Size(); + size += portalIndex.Size(); + size += clusters.Size(); + size += sizeof( idReachability_Walk ) * NumReachabilities(); + + return size; +} + +/* +================ +idAASFileLocal::PrintInfo +================ +*/ +void idAASFileLocal::PrintInfo( void ) const { + common->Printf( "%6d KB file size\n", MemorySize() >> 10 ); + common->Printf( "%6d areas\n", areas.Num() ); + common->Printf( "%6d max tree depth\n", MaxTreeDepth() ); + ReportRoutingEfficiency(); +} + +/* +================ +idAASFileLocal::NumReachabilities +================ +*/ +int idAASFileLocal::NumReachabilities( void ) const { + int i, num; + idReachability *reach; + + num = 0; + for ( i = 0; i < areas.Num(); i++ ) { + for ( reach = areas[i].reach; reach; reach = reach->next ) { + num++; + } + } + return num; +} + +/* +================ +idAASFileLocal::ReportRoutingEfficiency +================ +*/ +void idAASFileLocal::ReportRoutingEfficiency( void ) const { + int numReachableAreas, total, i, n; + + numReachableAreas = 0; + total = 0; + for ( i = 0; i < clusters.Num(); i++ ) { + n = clusters[i].numReachableAreas; + numReachableAreas += n; + total += n * n; + } + total += numReachableAreas * portals.Num(); + + common->Printf( "%6d reachable areas\n", numReachableAreas ); + common->Printf( "%6d reachabilities\n", NumReachabilities() ); + common->Printf( "%6d KB max routing cache\n", ( total * 3 ) >> 10 ); +} + +/* +================ +idAASFileLocal::DeleteReachabilities +================ +*/ +void idAASFileLocal::DeleteReachabilities( void ) { + int i; + idReachability *reach, *nextReach; + + for ( i = 0; i < areas.Num(); i++ ) { + for ( reach = areas[i].reach; reach; reach = nextReach ) { + nextReach = reach->next; + delete reach; + } + areas[i].reach = NULL; + areas[i].rev_reach = NULL; + } +} + +/* +================ +idAASFileLocal::DeleteClusters +================ +*/ +void idAASFileLocal::DeleteClusters( void ) { + aasPortal_t portal; + aasCluster_t cluster; + + portals.Clear(); + portalIndex.Clear(); + clusters.Clear(); + + // first portal is a dummy + memset( &portal, 0, sizeof( portal ) ); + portals.Append( portal ); + + // first cluster is a dummy + memset( &cluster, 0, sizeof( portal ) ); + clusters.Append( cluster ); +} diff --git a/tools/compilers/aas/AASFile.h b/tools/compilers/aas/AASFile.h new file mode 100644 index 000000000..835be2520 --- /dev/null +++ b/tools/compilers/aas/AASFile.h @@ -0,0 +1,346 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASFILE_H__ +#define __AASFILE_H__ + +/* +=============================================================================== + + AAS File + +=============================================================================== +*/ + +#define AAS_FILEID "DewmAAS" +#define AAS_FILEVERSION "1.07" + +// travel flags +#define TFL_INVALID BIT(0) // not valid +#define TFL_WALK BIT(1) // walking +#define TFL_CROUCH BIT(2) // crouching +#define TFL_WALKOFFLEDGE BIT(3) // walking of a ledge +#define TFL_BARRIERJUMP BIT(4) // jumping onto a barrier +#define TFL_JUMP BIT(5) // jumping +#define TFL_LADDER BIT(6) // climbing a ladder +#define TFL_SWIM BIT(7) // swimming +#define TFL_WATERJUMP BIT(8) // jump out of the water +#define TFL_TELEPORT BIT(9) // teleportation +#define TFL_ELEVATOR BIT(10) // travel by elevator +#define TFL_FLY BIT(11) // fly +#define TFL_SPECIAL BIT(12) // special +#define TFL_WATER BIT(21) // travel through water +#define TFL_AIR BIT(22) // travel through air +#define TFL_DOOR BIT(23) // travel through a not-open door + +// face flags +#define FACE_SOLID BIT(0) // solid at the other side +#define FACE_LADDER BIT(1) // ladder surface +#define FACE_FLOOR BIT(2) // standing on floor when on this face +#define FACE_LIQUID BIT(3) // face seperating two areas with liquid +#define FACE_LIQUIDSURFACE BIT(4) // face seperating liquid and air + +// area flags +#define AREA_FLOOR BIT(0) // AI can stand on the floor in this area +#define AREA_GAP BIT(1) // area has a gap +#define AREA_LEDGE BIT(2) // if entered the AI bbox partly floats above a ledge +#define AREA_LADDER BIT(3) // area contains one or more ladder faces +#define AREA_LIQUID BIT(4) // area contains a liquid +#define AREA_CROUCH BIT(5) // AI cannot walk but can only crouch in this area +#define AREA_REACHABLE_WALK BIT(6) // area is reachable by walking or swimming +#define AREA_REACHABLE_FLY BIT(7) // area is reachable by flying +#define AREA_DOOR BIT(8) // area contains one ore more doors + +// area contents flags +#define AREACONTENTS_SOLID BIT(0) // solid, not a valid area +#define AREACONTENTS_WATER BIT(1) // area contains water +#define AREACONTENTS_CLUSTERPORTAL BIT(2) // area is a cluster portal +#define AREACONTENTS_OBSTACLE BIT(3) // area contains (part of) a dynamic obstacle +#define AREACONTENTS_TELEPORTER BIT(4) // area contains (part of) a teleporter trigger + +// bits for different bboxes +#define AREACONTENTS_BBOX_BIT 24 + +#define MAX_REACH_PER_AREA 256 +#define MAX_AAS_TREE_DEPTH 128 + +#define MAX_AAS_BOUNDING_BOXES 4 + +// reachability to another area +class idReachability { +public: + int travelType; // type of travel required to get to the area + short toAreaNum; // number of the reachable area + short fromAreaNum; // number of area the reachability starts + idVec3 start; // start point of inter area movement + idVec3 end; // end point of inter area movement + int edgeNum; // edge crossed by this reachability + unsigned short travelTime; // travel time of the inter area movement + byte number; // reachability number within the fromAreaNum (must be < 256) + byte disableCount; // number of times this reachability has been disabled + idReachability * next; // next reachability in list + idReachability * rev_next; // next reachability in reversed list + unsigned short * areaTravelTimes; // travel times within the fromAreaNum from reachabilities that lead towards this area +public: + void CopyBase( idReachability &reach ); +}; + +class idReachability_Walk : public idReachability { +}; + +class idReachability_BarrierJump : public idReachability { +}; + +class idReachability_WaterJump : public idReachability { +}; + +class idReachability_WalkOffLedge : public idReachability { +}; + +class idReachability_Swim : public idReachability { +}; + +class idReachability_Fly : public idReachability { +}; + +class idReachability_Special : public idReachability { +public: + idDict dict; +}; + +// index +typedef int aasIndex_t; + +// vertex +typedef idVec3 aasVertex_t; + +// edge +typedef struct aasEdge_s { + int vertexNum[2]; // numbers of the vertexes of this edge +} aasEdge_t; + +// area boundary face +typedef struct aasFace_s { + unsigned short planeNum; // number of the plane this face is on + unsigned short flags; // face flags + int numEdges; // number of edges in the boundary of the face + int firstEdge; // first edge in the edge index + short areas[2]; // area at the front and back of this face +} aasFace_t; + +// area with a boundary of faces +typedef struct aasArea_s { + int numFaces; // number of faces used for the boundary of the area + int firstFace; // first face in the face index used for the boundary of the area + idBounds bounds; // bounds of the area + idVec3 center; // center of the area an AI can move towards + unsigned short flags; // several area flags + unsigned short contents; // contents of the area + short cluster; // cluster the area belongs to, if negative it's a portal + short clusterAreaNum; // number of the area in the cluster + int travelFlags; // travel flags for traveling through this area + idReachability * reach; // reachabilities that start from this area + idReachability * rev_reach; // reachabilities that lead to this area +} aasArea_t; + +// nodes of the bsp tree +typedef struct aasNode_s { + unsigned short planeNum; // number of the plane that splits the subspace at this node + int children[2]; // child nodes, zero is solid, negative is -(area number) +} aasNode_t; + +// cluster portal +typedef struct aasPortal_s { + short areaNum; // number of the area that is the actual portal + short clusters[2]; // number of cluster at the front and back of the portal + short clusterAreaNum[2]; // number of this portal area in the front and back cluster + unsigned short maxAreaTravelTime; // maximum travel time through the portal area +} aasPortal_t; + +// cluster +typedef struct aasCluster_s { + int numAreas; // number of areas in the cluster + int numReachableAreas; // number of areas with reachabilities + int numPortals; // number of cluster portals + int firstPortal; // first cluster portal in the index +} aasCluster_t; + +// trace through the world +typedef struct aasTrace_s { + // parameters + int flags; // areas with these flags block the trace + int travelFlags; // areas with these travel flags block the trace + int maxAreas; // size of the 'areas' array + int getOutOfSolid; // trace out of solid if the trace starts in solid + // output + float fraction; // fraction of trace completed + idVec3 endpos; // end position of trace + int planeNum; // plane hit + int lastAreaNum; // number of last area the trace went through + int blockingAreaNum; // area that could not be entered + int numAreas; // number of areas the trace went through + int * areas; // array to store areas the trace went through + idVec3 * points; // points where the trace entered each new area + aasTrace_s( void ) { areas = NULL; points = NULL; getOutOfSolid = false; flags = travelFlags = maxAreas = 0; } +} aasTrace_t; + +// settings +class idAASSettings { +public: + // collision settings + int numBoundingBoxes; + idBounds boundingBoxes[MAX_AAS_BOUNDING_BOXES]; + bool usePatches; + bool writeBrushMap; + bool playerFlood; + bool noOptimize; + bool allowSwimReachabilities; + bool allowFlyReachabilities; + idStr fileExtension; + // physics settings + idVec3 gravity; + idVec3 gravityDir; + idVec3 invGravityDir; + float gravityValue; + float maxStepHeight; + float maxBarrierHeight; + float maxWaterJumpHeight; + float maxFallHeight; + float minFloorCos; + // fixed travel times + int tt_barrierJump; + int tt_startCrouching; + int tt_waterJump; + int tt_startWalkOffLedge; + +public: + idAASSettings( void ); + + bool FromFile( const idStr &fileName ); + bool FromParser( idLexer &src ); + bool FromDict( const char *name, const idDict *dict ); + bool WriteToFile( idFile *fp ) const; + bool ValidForBounds( const idBounds &bounds ) const; + bool ValidEntity( const char *classname ) const; + +private: + bool ParseBool( idLexer &src, bool &b ); + bool ParseInt( idLexer &src, int &i ); + bool ParseFloat( idLexer &src, float &f ); + bool ParseVector( idLexer &src, idVec3 &vec ); + bool ParseBBoxes( idLexer &src ); +}; + + +/* + +- when a node child is a solid leaf the node child number is zero +- two adjacent areas (sharing a plane at opposite sides) share a face + this face is a portal between the areas +- when an area uses a face from the faceindex with a positive index + then the face plane normal points into the area +- the face edges are stored counter clockwise using the edgeindex +- two adjacent convex areas (sharing a face) only share One face + this is a simple result of the areas being convex +- the areas can't have a mixture of ground and gap faces + other mixtures of faces in one area are allowed +- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have + the cluster number set to the negative portal number +- edge zero is a dummy +- face zero is a dummy +- area zero is a dummy +- node zero is a dummy +- portal zero is a dummy +- cluster zero is a dummy + +*/ + + +class idAASFile { +public: + virtual ~idAASFile( void ) {} + + const char * GetName( void ) const { return name.c_str(); } + unsigned int GetCRC( void ) const { return crc; } + + int GetNumPlanes( void ) const { return planeList.Num(); } + const idPlane & GetPlane( int index ) const { return planeList[index]; } + int GetNumVertices( void ) const { return vertices.Num(); } + const aasVertex_t & GetVertex( int index ) const { return vertices[index]; } + int GetNumEdges( void ) const { return edges.Num(); } + const aasEdge_t & GetEdge( int index ) const { return edges[index]; } + int GetNumEdgeIndexes( void ) const { return edgeIndex.Num(); } + const aasIndex_t & GetEdgeIndex( int index ) const { return edgeIndex[index]; } + int GetNumFaces( void ) const { return faces.Num(); } + const aasFace_t & GetFace( int index ) const { return faces[index]; } + int GetNumFaceIndexes( void ) const { return faceIndex.Num(); } + const aasIndex_t & GetFaceIndex( int index ) const { return faceIndex[index]; } + int GetNumAreas( void ) const { return areas.Num(); } + const aasArea_t & GetArea( int index ) { return areas[index]; } + int GetNumNodes( void ) const { return nodes.Num(); } + const aasNode_t & GetNode( int index ) const { return nodes[index]; } + int GetNumPortals( void ) const { return portals.Num(); } + const aasPortal_t & GetPortal( int index ) { return portals[index]; } + int GetNumPortalIndexes( void ) const { return portalIndex.Num(); } + const aasIndex_t & GetPortalIndex( int index ) const { return portalIndex[index]; } + int GetNumClusters( void ) const { return clusters.Num(); } + const aasCluster_t & GetCluster( int index ) const { return clusters[index]; } + + const idAASSettings & GetSettings( void ) const { return settings; } + + void SetPortalMaxTravelTime( int index, int time ) { portals[index].maxAreaTravelTime = time; } + void SetAreaTravelFlag( int index, int flag ) { areas[index].travelFlags |= flag; } + void SetAreaFlag( int index, int flag ) { areas[index].flags |= flag; } + void RemoveAreaFlag( int index, int flag ) { areas[index].flags &= ~flag; } + void RemoveAreaTravelFlag( int index, int flag ) { areas[index].travelFlags &= ~flag; } + + virtual idVec3 EdgeCenter( int edgeNum ) const = 0; + virtual idVec3 FaceCenter( int faceNum ) const = 0; + virtual idVec3 AreaCenter( int areaNum ) const = 0; + + virtual idBounds EdgeBounds( int edgeNum ) const = 0; + virtual idBounds FaceBounds( int faceNum ) const = 0; + virtual idBounds AreaBounds( int areaNum ) const = 0; + + virtual int PointAreaNum( const idVec3 &origin ) const = 0; + virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const = 0; + virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const = 0; + virtual void PushPointIntoAreaNum( int areaNum, idVec3 &point ) const = 0; + virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0; + virtual void PrintInfo( void ) const = 0; + +protected: + idStr name; + unsigned int crc; + + idPlaneSet planeList; + idList vertices; + idList edges; + idList edgeIndex; + idList faces; + idList faceIndex; + idList areas; + idList nodes; + idList portals; + idList portalIndex; + idList clusters; + idAASSettings settings; +}; + +#endif /* !__AASFILE_H__ */ diff --git a/tools/compilers/aas/AASFileManager.cpp b/tools/compilers/aas/AASFileManager.cpp new file mode 100644 index 000000000..f79bff0b2 --- /dev/null +++ b/tools/compilers/aas/AASFileManager.cpp @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" + +/* +=============================================================================== + + AAS File Manager + +=============================================================================== +*/ + +class idAASFileManagerLocal : public idAASFileManager { +public: + virtual ~idAASFileManagerLocal( void ) {} + + virtual idAASFile * LoadAAS( const char *fileName, unsigned int mapFileCRC ); + virtual void FreeAAS( idAASFile *file ); +}; + +idAASFileManagerLocal AASFileManagerLocal; +idAASFileManager * AASFileManager = &AASFileManagerLocal; + + +/* +================ +idAASFileManagerLocal::LoadAAS +================ +*/ +idAASFile *idAASFileManagerLocal::LoadAAS( const char *fileName, unsigned int mapFileCRC ) { + idAASFileLocal *file = new idAASFileLocal(); + if ( !file->Load( fileName, mapFileCRC ) ) { + delete file; + return NULL; + } + return file; +} + +/* +================ +idAASFileManagerLocal::FreeAAS +================ +*/ +void idAASFileManagerLocal::FreeAAS( idAASFile *file ) { + delete file; +} diff --git a/tools/compilers/aas/AASFileManager.h b/tools/compilers/aas/AASFileManager.h new file mode 100644 index 000000000..3328057c2 --- /dev/null +++ b/tools/compilers/aas/AASFileManager.h @@ -0,0 +1,41 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASFILEMANAGER_H__ +#define __AASFILEMANAGER_H__ + +/* +=============================================================================== + + AAS File Manager + +=============================================================================== +*/ + +class idAASFileManager { +public: + virtual ~idAASFileManager( void ) {} + + virtual idAASFile * LoadAAS( const char *fileName, unsigned int mapFileCRC ) = 0; + virtual void FreeAAS( idAASFile *file ) = 0; +}; + +extern idAASFileManager * AASFileManager; + +#endif /* !__AASFILEMANAGER_H__ */ diff --git a/tools/compilers/aas/AASFile_local.h b/tools/compilers/aas/AASFile_local.h new file mode 100644 index 000000000..188a77b33 --- /dev/null +++ b/tools/compilers/aas/AASFile_local.h @@ -0,0 +1,90 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASFILELOCAL_H__ +#define __AASFILELOCAL_H__ + +/* +=============================================================================== + + AAS File Local + +=============================================================================== +*/ + +class idAASFileLocal : public idAASFile { + friend class idAASBuild; + friend class idAASReach; + friend class idAASCluster; +public: + idAASFileLocal( void ); + virtual ~idAASFileLocal( void ); + +public: + virtual idVec3 EdgeCenter( int edgeNum ) const; + virtual idVec3 FaceCenter( int faceNum ) const; + virtual idVec3 AreaCenter( int areaNum ) const; + + virtual idBounds EdgeBounds( int edgeNum ) const; + virtual idBounds FaceBounds( int faceNum ) const; + virtual idBounds AreaBounds( int areaNum ) const; + + virtual int PointAreaNum( const idVec3 &origin ) const; + virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const; + virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const; + virtual void PushPointIntoAreaNum( int areaNum, idVec3 &point ) const; + virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const; + virtual void PrintInfo( void ) const; + +public: + bool Load( const idStr &fileName, unsigned int mapFileCRC ); + bool Write( const idStr &fileName, unsigned int mapFileCRC ); + + int MemorySize( void ) const; + void ReportRoutingEfficiency( void ) const; + void Optimize( void ); + void LinkReversedReachability( void ); + void FinishAreas( void ); + + void Clear( void ); + void DeleteReachabilities( void ); + void DeleteClusters( void ); + +private: + bool ParseIndex( idLexer &src, idList &indexes ); + bool ParsePlanes( idLexer &src ); + bool ParseVertices( idLexer &src ); + bool ParseEdges( idLexer &src ); + bool ParseFaces( idLexer &src ); + bool ParseReachabilities( idLexer &src, int areaNum ); + bool ParseAreas( idLexer &src ); + bool ParseNodes( idLexer &src ); + bool ParsePortals( idLexer &src ); + bool ParseClusters( idLexer &src ); + +private: + int BoundsReachableAreaNum_r( int nodeNum, const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const; + void MaxTreeDepth_r( int nodeNum, int &depth, int &maxDepth ) const; + int MaxTreeDepth( void ) const; + int AreaContentsTravelFlags( int areaNum ) const; + idVec3 AreaReachableGoal( int areaNum ) const; + int NumReachabilities( void ) const; +}; + +#endif /* !__AASFILELOCAL_H__ */ diff --git a/tools/compilers/aas/AASFile_optimize.cpp b/tools/compilers/aas/AASFile_optimize.cpp new file mode 100644 index 000000000..8e729442b --- /dev/null +++ b/tools/compilers/aas/AASFile_optimize.cpp @@ -0,0 +1,145 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" + + +//=============================================================== +// +// optimize file +// +//=============================================================== + +/* +================ +idAASFileLocal::Optimize +================ +*/ +void idAASFileLocal::Optimize( void ) { + int i, j, k, faceNum, edgeNum, areaFirstFace, faceFirstEdge; + aasArea_t *area; + aasFace_t *face; + aasEdge_t *edge; + idReachability *reach; + idList vertexRemap; + idList edgeRemap; + idList faceRemap; + idList newVertices; + idList newEdges; + idList newEdgeIndex; + idList newFaces; + idList newFaceIndex; + + vertexRemap.AssureSize( vertices.Num(), -1 ); + edgeRemap.AssureSize( edges.Num(), 0 ); + faceRemap.AssureSize( faces.Num(), 0 ); + + newVertices.Resize( vertices.Num() ); + newEdges.Resize( edges.Num() ); + newEdges.SetNum( 1, false ); + newEdgeIndex.Resize( edgeIndex.Num() ); + newFaces.Resize( faces.Num() ); + newFaces.SetNum( 1, false ); + newFaceIndex.Resize( faceIndex.Num() ); + + for ( i = 0; i < areas.Num(); i++ ) { + area = &areas[i]; + + areaFirstFace = newFaceIndex.Num(); + for ( j = 0; j < area->numFaces; j++ ) { + faceNum = faceIndex[area->firstFace + j]; + face = &faces[ abs(faceNum) ]; + + // store face + if ( !faceRemap[ abs(faceNum) ] ) { + faceRemap[ abs(faceNum) ] = newFaces.Num(); + newFaces.Append( *face ); + + // don't store edges for faces we don't care about + if ( !( face->flags & ( FACE_FLOOR|FACE_LADDER ) ) ) { + + newFaces[ newFaces.Num()-1 ].firstEdge = 0; + newFaces[ newFaces.Num()-1 ].numEdges = 0; + + } else { + + // store edges + faceFirstEdge = newEdgeIndex.Num(); + for ( k = 0; k < face->numEdges; k++ ) { + edgeNum = edgeIndex[ face->firstEdge + k ]; + edge = &edges[ abs(edgeNum) ]; + + if ( !edgeRemap[ abs(edgeNum) ] ) { + if ( edgeNum < 0 ) { + edgeRemap[ abs(edgeNum) ] = -newEdges.Num(); + } + else { + edgeRemap[ abs(edgeNum) ] = newEdges.Num(); + } + + // remap vertices if not yet remapped + if ( vertexRemap[ edge->vertexNum[0] ] == -1 ) { + vertexRemap[ edge->vertexNum[0] ] = newVertices.Num(); + newVertices.Append( vertices[ edge->vertexNum[0] ] ); + } + if ( vertexRemap[ edge->vertexNum[1] ] == -1 ) { + vertexRemap[ edge->vertexNum[1] ] = newVertices.Num(); + newVertices.Append( vertices[ edge->vertexNum[1] ] ); + } + + newEdges.Append( *edge ); + newEdges[ newEdges.Num()-1 ].vertexNum[0] = vertexRemap[ edge->vertexNum[0] ]; + newEdges[ newEdges.Num()-1 ].vertexNum[1] = vertexRemap[ edge->vertexNum[1] ]; + } + + newEdgeIndex.Append( edgeRemap[ abs(edgeNum) ] ); + } + + newFaces[ newFaces.Num()-1 ].firstEdge = faceFirstEdge; + newFaces[ newFaces.Num()-1 ].numEdges = newEdgeIndex.Num() - faceFirstEdge; + } + } + + if ( faceNum < 0 ) { + newFaceIndex.Append( -faceRemap[ abs(faceNum) ] ); + } else { + newFaceIndex.Append( faceRemap[ abs(faceNum) ] ); + } + } + + area->firstFace = areaFirstFace; + area->numFaces = newFaceIndex.Num() - areaFirstFace; + + // remap the reachability edges + for ( reach = area->reach; reach; reach = reach->next ) { + reach->edgeNum = abs( edgeRemap[reach->edgeNum] ); + } + } + + // store new list + vertices = newVertices; + edges = newEdges; + edgeIndex = newEdgeIndex; + faces = newFaces; + faceIndex = newFaceIndex; +} diff --git a/tools/compilers/aas/AASFile_sample.cpp b/tools/compilers/aas/AASFile_sample.cpp new file mode 100644 index 000000000..f403aafe0 --- /dev/null +++ b/tools/compilers/aas/AASFile_sample.cpp @@ -0,0 +1,599 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" + + +//=============================================================== +// +// Environment Sampling +// +//=============================================================== + +/* +================ +idAASFileLocal::EdgeCenter +================ +*/ +idVec3 idAASFileLocal::EdgeCenter( int edgeNum ) const { + const aasEdge_t *edge; + edge = &edges[edgeNum]; + return ( vertices[edge->vertexNum[0]] + vertices[edge->vertexNum[1]] ) * 0.5f; +} + +/* +================ +idAASFileLocal::FaceCenter +================ +*/ +idVec3 idAASFileLocal::FaceCenter( int faceNum ) const { + int i, edgeNum; + const aasFace_t *face; + const aasEdge_t *edge; + idVec3 center; + + center = vec3_origin; + + face = &faces[faceNum]; + if ( face->numEdges > 0 ) { + for ( i = 0; i < face->numEdges; i++ ) { + edgeNum = edgeIndex[ face->firstEdge + i ]; + edge = &edges[ abs( edgeNum ) ]; + center += vertices[ edge->vertexNum[ INTSIGNBITSET(edgeNum) ] ]; + } + center /= face->numEdges; + } + return center; +} + +/* +================ +idAASFileLocal::AreaCenter +================ +*/ +idVec3 idAASFileLocal::AreaCenter( int areaNum ) const { + int i, faceNum; + const aasArea_t *area; + idVec3 center; + + center = vec3_origin; + + area = &areas[areaNum]; + if ( area->numFaces > 0 ) { + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = faceIndex[area->firstFace + i]; + center += FaceCenter( abs(faceNum) ); + } + center /= area->numFaces; + } + return center; +} + +/* +============ +idAASFileLocal::AreaReachableGoal +============ +*/ +idVec3 idAASFileLocal::AreaReachableGoal( int areaNum ) const { + int i, faceNum, numFaces; + const aasArea_t *area; + idVec3 center; + idVec3 start, end; + aasTrace_t trace; + + area = &areas[areaNum]; + + if ( !(area->flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY)) || (area->flags & AREA_LIQUID) ) { + return AreaCenter( areaNum ); + } + + center = vec3_origin; + + numFaces = 0; + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = faceIndex[area->firstFace + i]; + if ( !(faces[abs(faceNum)].flags & FACE_FLOOR) ) { + continue; + } + center += FaceCenter( abs(faceNum) ); + numFaces++; + } + if ( numFaces > 0 ) { + center /= numFaces; + } + center[2] += 1.0f; + end = center; + end[2] -= 1024; + Trace( trace, center, end ); + + return trace.endpos; +} + +/* +================ +idAASFileLocal::EdgeBounds +================ +*/ +idBounds idAASFileLocal::EdgeBounds( int edgeNum ) const { + const aasEdge_t *edge; + idBounds bounds; + + edge = &edges[ abs( edgeNum ) ]; + bounds[0] = bounds[1] = vertices[ edge->vertexNum[0] ]; + bounds += vertices[ edge->vertexNum[1] ]; + return bounds; +} + +/* +================ +idAASFileLocal::FaceBounds +================ +*/ +idBounds idAASFileLocal::FaceBounds( int faceNum ) const { + int i, edgeNum; + const aasFace_t *face; + const aasEdge_t *edge; + idBounds bounds; + + face = &faces[faceNum]; + bounds.Clear(); + + for ( i = 0; i < face->numEdges; i++ ) { + edgeNum = edgeIndex[ face->firstEdge + i ]; + edge = &edges[ abs( edgeNum ) ]; + bounds.AddPoint( vertices[ edge->vertexNum[ INTSIGNBITSET(edgeNum) ] ] ); + } + return bounds; +} + +/* +================ +idAASFileLocal::AreaBounds +================ +*/ +idBounds idAASFileLocal::AreaBounds( int areaNum ) const { + int i, faceNum; + const aasArea_t *area; + idBounds bounds; + + area = &areas[areaNum]; + bounds.Clear(); + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = faceIndex[area->firstFace + i]; + bounds += FaceBounds( abs(faceNum) ); + } + return bounds; +} + +/* +============ +idAASFileLocal::PointAreaNum +============ +*/ +int idAASFileLocal::PointAreaNum( const idVec3 &origin ) const { + int nodeNum; + const aasNode_t *node; + + nodeNum = 1; + do { + node = &nodes[nodeNum]; + if ( planeList[node->planeNum].Side( origin ) == PLANESIDE_BACK ) { + nodeNum = node->children[1]; + } + else { + nodeNum = node->children[0]; + } + if ( nodeNum < 0 ) { + return -nodeNum; + } + } while( nodeNum ); + + return 0; +} + +/* +============ +idAASFileLocal::PointReachableAreaNum +============ +*/ +int idAASFileLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const { + int areaList[32], areaNum, i; + idVec3 start, end, pointList[32]; + aasTrace_t trace; + idBounds bounds; + float frac; + + start = origin; + + trace.areas = areaList; + trace.points = pointList; + trace.maxAreas = sizeof( areaList ) / sizeof( int ); + trace.getOutOfSolid = true; + + areaNum = PointAreaNum( start ); + if ( areaNum ) { + if ( ( areas[areaNum].flags & areaFlags ) && ( ( areas[areaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { + return areaNum; + } + } + else { + // trace up + end = start; + end[2] += 32.0f; + Trace( trace, start, end ); + if ( trace.numAreas >= 1 ) { + if ( ( areas[0].flags & areaFlags ) && ( ( areas[0].travelFlags & excludeTravelFlags ) == 0 ) ) { + return areaList[0]; + } + start = pointList[0]; + start[2] += 1.0f; + } + } + + // trace down + end = start; + end[2] -= 32.0f; + Trace( trace, start, end ); + if ( trace.lastAreaNum ) { + if ( ( areas[trace.lastAreaNum].flags & areaFlags ) && ( ( areas[trace.lastAreaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { + return trace.lastAreaNum; + } + start = trace.endpos; + } + + // expand bounds until an area is found + for ( i = 1; i <= 12; i++ ) { + frac = i * ( 1.0f / 12.0f ); + bounds[0] = origin + searchBounds[0] * frac; + bounds[1] = origin + searchBounds[1] * frac; + areaNum = BoundsReachableAreaNum( bounds, areaFlags, excludeTravelFlags ); + if ( areaNum && ( areas[areaNum].flags & areaFlags ) && ( ( areas[areaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { + return areaNum; + } + } + return 0; +} + +/* +============ +idAASFileLocal::BoundsReachableAreaNum_r +============ +*/ +int idAASFileLocal::BoundsReachableAreaNum_r( int nodeNum, const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const { + int res; + const aasNode_t *node; + + while( nodeNum ) { + if ( nodeNum < 0 ) { + if ( ( areas[-nodeNum].flags & areaFlags ) && ( ( areas[-nodeNum].travelFlags & excludeTravelFlags ) == 0 ) ) { + return -nodeNum; + } + return 0; + } + node = &nodes[nodeNum]; + res = bounds.PlaneSide( planeList[node->planeNum] ); + if ( res == PLANESIDE_BACK ) { + nodeNum = node->children[1]; + } + else if ( res == PLANESIDE_FRONT ) { + nodeNum = node->children[0]; + } + else { + nodeNum = BoundsReachableAreaNum_r( node->children[1], bounds, areaFlags, excludeTravelFlags ); + if ( nodeNum ) { + return nodeNum; + } + nodeNum = node->children[0]; + } + } + + return 0; +} + +/* +============ +idAASFileLocal::BoundsReachableAreaNum +============ +*/ +int idAASFileLocal::BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const { + + return BoundsReachableAreaNum_r( 1, bounds, areaFlags, excludeTravelFlags ); +} + +/* +============ +idAASFileLocal::PushPointIntoAreaNum +============ +*/ +void idAASFileLocal::PushPointIntoAreaNum( int areaNum, idVec3 &point ) const { + int i, faceNum; + const aasArea_t *area; + const aasFace_t *face; + + area = &areas[areaNum]; + + // push the point to the right side of all area face planes + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = faceIndex[area->firstFace + i]; + face = &faces[abs( faceNum )]; + + const idPlane &plane = planeList[face->planeNum ^ INTSIGNBITSET( faceNum )]; + float dist = plane.Distance( point ); + + // project the point onto the face plane if it is on the wrong side + if ( dist < 0.0f ) { + point -= dist * plane.Normal(); + } + } +} + +/* +============ +idAASFileLocal::Trace +============ +*/ +#define TRACEPLANE_EPSILON 0.125f + +typedef struct aasTraceStack_s +{ + idVec3 start; + idVec3 end; + int planeNum; + int nodeNum; +} aasTraceStack_t; + +bool idAASFileLocal::Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const { + int side, nodeNum, tmpPlaneNum; + double front, back, frac; + idVec3 cur_start, cur_end, cur_mid, v1, v2; + aasTraceStack_t tracestack[MAX_AAS_TREE_DEPTH]; + aasTraceStack_t *tstack_p; + const aasNode_t *node; + const idPlane *plane; + + trace.numAreas = 0; + trace.lastAreaNum = 0; + trace.blockingAreaNum = 0; + + tstack_p = tracestack; + tstack_p->start = start; + tstack_p->end = end; + tstack_p->planeNum = 0; + tstack_p->nodeNum = 1; //start with the root of the tree + tstack_p++; + + while( 1 ) { + + tstack_p--; + // if the trace stack is empty + if ( tstack_p < tracestack ) { + if ( !trace.lastAreaNum ) { + // completely in solid + trace.fraction = 0.0f; + trace.endpos = start; + } + else { + // nothing was hit + trace.fraction = 1.0f; + trace.endpos = end; + } + trace.planeNum = 0; + return false; + } + + // number of the current node to test the line against + nodeNum = tstack_p->nodeNum; + + // if it is an area + if ( nodeNum < 0) { + // if can't enter the area + if ( ( areas[-nodeNum].flags & trace.flags ) || ( areas[-nodeNum].travelFlags & trace.travelFlags ) ) { + if ( !trace.lastAreaNum ) { + trace.fraction = 0.0f; + v1 = vec3_origin; + } else { + v1 = end - start; + v2 = tstack_p->start - start; + trace.fraction = v2.Length() / v1.Length(); + } + trace.endpos = tstack_p->start; + trace.blockingAreaNum = -nodeNum; + trace.planeNum = tstack_p->planeNum; + // always take the plane with normal facing towards the trace start + plane = &planeList[trace.planeNum]; + if ( v1 * plane->Normal() > 0.0f ) { + trace.planeNum ^= 1; + } + return true; + } + trace.lastAreaNum = -nodeNum; + if ( trace.numAreas < trace.maxAreas ) { + if ( trace.areas ) { + trace.areas[trace.numAreas] = -nodeNum; + } + if ( trace.points ) { + trace.points[trace.numAreas] = tstack_p->start; + } + trace.numAreas++; + } + continue; + } + + // if it is a solid leaf + if ( !nodeNum ) { + if ( !trace.lastAreaNum ) { + trace.fraction = 0.0f; + v1 = vec3_origin; + } else { + v1 = end - start; + v2 = tstack_p->start - start; + trace.fraction = v2.Length() / v1.Length(); + } + trace.endpos = tstack_p->start; + trace.blockingAreaNum = 0; // hit solid leaf + trace.planeNum = tstack_p->planeNum; + // always take the plane with normal facing towards the trace start + plane = &planeList[trace.planeNum]; + if ( v1 * plane->Normal() > 0.0f ) { + trace.planeNum ^= 1; + } + if ( !trace.lastAreaNum && trace.getOutOfSolid ) { + continue; + } + else { + return true; + } + } + + // the node to test against + node = &nodes[nodeNum]; + // start point of current line to test against node + cur_start = tstack_p->start; + // end point of the current line to test against node + cur_end = tstack_p->end; + // the current node plane + plane = &planeList[node->planeNum]; + + front = plane->Distance( cur_start ); + back = plane->Distance( cur_end ); + + // if the whole to be traced line is totally at the front of this node + // only go down the tree with the front child + if ( front >= -ON_EPSILON && back >= -ON_EPSILON ) { + // keep the current start and end point on the stack and go down the tree with the front child + tstack_p->nodeNum = node->children[0]; + tstack_p++; + if ( tstack_p >= &tracestack[MAX_AAS_TREE_DEPTH] ) { + common->Error("idAASFileLocal::Trace: stack overflow\n" ); + return false; + } + } + // if the whole to be traced line is totally at the back of this node + // only go down the tree with the back child + else if ( front < ON_EPSILON && back < ON_EPSILON ) { + // keep the current start and end point on the stack and go down the tree with the back child + tstack_p->nodeNum = node->children[1]; + tstack_p++; + if ( tstack_p >= &tracestack[MAX_AAS_TREE_DEPTH] ) { + common->Error("idAASFileLocal::Trace: stack overflow\n" ); + return false; + } + } + // go down the tree both at the front and back of the node + else { + tmpPlaneNum = tstack_p->planeNum; + // calculate the hit point with the node plane + // put the cross point TRACEPLANE_EPSILON on the near side + if (front < 0) { + frac = (front + TRACEPLANE_EPSILON) / ( front - back ); + } + else { + frac = (front - TRACEPLANE_EPSILON) / ( front - back ); + } + + if (frac < 0) { + frac = 0.001f; //0 + } + else if (frac > 1) { + frac = 0.999f; //1 + } + + cur_mid = cur_start + ( cur_end - cur_start ) * frac; + + // side the front part of the line is on + side = front < 0; + + // first put the end part of the line on the stack (back side) + tstack_p->start = cur_mid; + tstack_p->planeNum = node->planeNum; + tstack_p->nodeNum = node->children[!side]; + tstack_p++; + if ( tstack_p >= &tracestack[MAX_AAS_TREE_DEPTH] ) { + common->Error("idAASFileLocal::Trace: stack overflow\n" ); + return false; + } + // now put the part near the start of the line on the stack so we will + // continue with that part first. + tstack_p->start = cur_start; + tstack_p->end = cur_mid; + tstack_p->planeNum = tmpPlaneNum; + tstack_p->nodeNum = node->children[side]; + tstack_p++; + if ( tstack_p >= &tracestack[MAX_AAS_TREE_DEPTH] ) { + common->Error("idAASFileLocal::Trace: stack overflow\n" ); + return false; + } + } + } + return false; +} + +/* +============ +idAASLocal::AreaContentsTravelFlags +============ +*/ +int idAASFileLocal::AreaContentsTravelFlags( int areaNum ) const { + if ( areas[areaNum].contents & AREACONTENTS_WATER ) { + return TFL_WATER; + } + return TFL_AIR; +} + +/* +============ +idAASFileLocal::MaxTreeDepth_r +============ +*/ +void idAASFileLocal::MaxTreeDepth_r( int nodeNum, int &depth, int &maxDepth ) const { + const aasNode_t *node; + + if ( nodeNum <= 0 ) { + return; + } + + depth++; + if ( depth > maxDepth ) { + maxDepth = depth; + } + + node = &nodes[nodeNum]; + MaxTreeDepth_r( node->children[0], depth, maxDepth ); + MaxTreeDepth_r( node->children[1], depth, maxDepth ); + + depth--; +} + +/* +============ +idAASFileLocal::MaxTreeDepth +============ +*/ +int idAASFileLocal::MaxTreeDepth( void ) const { + int depth, maxDepth; + + depth = maxDepth = 0; + MaxTreeDepth_r( 1, depth, maxDepth ); + return maxDepth; +} diff --git a/tools/compilers/aas/AASReach.cpp b/tools/compilers/aas/AASReach.cpp new file mode 100644 index 000000000..973dc5601 --- /dev/null +++ b/tools/compilers/aas/AASReach.cpp @@ -0,0 +1,936 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "AASFile.h" +#include "AASFile_local.h" +#include "AASReach.h" + +#define INSIDEUNITS 2.0f +#define INSIDEUNITS_WALKEND 0.5f +#define INSIDEUNITS_WALKSTART 0.1f +#define INSIDEUNITS_SWIMEND 0.5f +#define INSIDEUNITS_FLYEND 0.5f +#define INSIDEUNITS_WATERJUMP 15.0f + + +/* +================ +idAASReach::ReachabilityExists +================ +*/ +bool idAASReach::ReachabilityExists( int fromAreaNum, int toAreaNum ) { + aasArea_t *area; + idReachability *reach; + + area = &file->areas[fromAreaNum]; + for ( reach = area->reach; reach; reach = reach->next ) { + if ( reach->toAreaNum == toAreaNum ) { + return true; + } + } + return false; +} + +/* +================ +idAASReach::CanSwimInArea +================ +*/ +ID_INLINE bool idAASReach::CanSwimInArea( int areaNum ) { + return ( file->areas[areaNum].contents & AREACONTENTS_WATER ) != 0; +} + +/* +================ +idAASReach::AreaHasFloor +================ +*/ +ID_INLINE bool idAASReach::AreaHasFloor( int areaNum ) { + return ( file->areas[areaNum].flags & AREA_FLOOR ) != 0; +} + +/* +================ +idAASReach::AreaIsClusterPortal +================ +*/ +ID_INLINE bool idAASReach::AreaIsClusterPortal( int areaNum ) { + return ( file->areas[areaNum].contents & AREACONTENTS_CLUSTERPORTAL ) != 0; +} + +/* +================ +idAASReach::AddReachabilityToArea +================ +*/ +void idAASReach::AddReachabilityToArea( idReachability *reach, int areaNum ) { + aasArea_t *area; + + area = &file->areas[areaNum]; + reach->next = area->reach; + area->reach = reach; + numReachabilities++; +} + +/* +================ +idAASReach::Reachability_Fly +================ +*/ +void idAASReach::Reachability_Fly( int areaNum ) { + int i, faceNum, otherAreaNum; + aasArea_t *area; + aasFace_t *face; + idReachability_Fly *reach; + + area = &file->areas[areaNum]; + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = file->faceIndex[area->firstFace + i]; + face = &file->faces[abs(faceNum)]; + + otherAreaNum = face->areas[INTSIGNBITNOTSET(faceNum)]; + + if ( otherAreaNum == 0 ) { + continue; + } + + if ( ReachabilityExists( areaNum, otherAreaNum ) ) { + continue; + } + + // create reachability going through this face + reach = new idReachability_Fly(); + reach->travelType = TFL_FLY; + reach->toAreaNum = otherAreaNum; + reach->fromAreaNum = areaNum; + reach->edgeNum = 0; + reach->travelTime = 1; + reach->start = file->FaceCenter( abs(faceNum) ); + if ( faceNum < 0 ) { + reach->end = reach->start + file->planeList[face->planeNum].Normal() * INSIDEUNITS_FLYEND; + } else { + reach->end = reach->start - file->planeList[face->planeNum].Normal() * INSIDEUNITS_FLYEND; + } + AddReachabilityToArea( reach, areaNum ); + } +} + +/* +================ +idAASReach::Reachability_Swim +================ +*/ +void idAASReach::Reachability_Swim( int areaNum ) { + int i, faceNum, otherAreaNum; + aasArea_t *area; + aasFace_t *face; + idReachability_Swim *reach; + + if ( !CanSwimInArea( areaNum ) ) { + return; + } + + area = &file->areas[areaNum]; + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = file->faceIndex[area->firstFace + i]; + face = &file->faces[abs(faceNum)]; + + otherAreaNum = face->areas[INTSIGNBITNOTSET(faceNum)]; + + if ( otherAreaNum == 0 ) { + continue; + } + + if ( !CanSwimInArea( otherAreaNum ) ) { + continue; + } + + if ( ReachabilityExists( areaNum, otherAreaNum ) ) { + continue; + } + + // create reachability going through this face + reach = new idReachability_Swim(); + reach->travelType = TFL_SWIM; + reach->toAreaNum = otherAreaNum; + reach->fromAreaNum = areaNum; + reach->edgeNum = 0; + reach->travelTime = 1; + reach->start = file->FaceCenter( abs(faceNum) ); + if ( faceNum < 0 ) { + reach->end = reach->start + file->planeList[face->planeNum].Normal() * INSIDEUNITS_SWIMEND; + } else { + reach->end = reach->start - file->planeList[face->planeNum].Normal() * INSIDEUNITS_SWIMEND; + } + AddReachabilityToArea( reach, areaNum ); + } +} + +/* +================ +idAASReach::Reachability_EqualFloorHeight +================ +*/ +void idAASReach::Reachability_EqualFloorHeight( int areaNum ) { + int i, k, l, m, n, faceNum, face1Num, face2Num, otherAreaNum, edge1Num, edge2Num; + aasArea_t *area, *otherArea; + aasFace_t *face, *face1, *face2; + idReachability_Walk *reach; + + if ( !AreaHasFloor( areaNum ) ) { + return; + } + + area = &file->areas[areaNum]; + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = file->faceIndex[area->firstFace + i]; + face = &file->faces[abs(faceNum)]; + + otherAreaNum = face->areas[INTSIGNBITNOTSET(faceNum)]; + if ( !AreaHasFloor( otherAreaNum ) ) { + continue; + } + + otherArea = &file->areas[otherAreaNum]; + + for ( k = 0; k < area->numFaces; k++ ) { + face1Num = file->faceIndex[area->firstFace + k]; + face1 = &file->faces[abs(face1Num)]; + + if ( !( face1->flags & FACE_FLOOR ) ) { + continue; + } + for ( l = 0; l < otherArea->numFaces; l++ ) { + face2Num = file->faceIndex[otherArea->firstFace + l]; + face2 = &file->faces[abs(face2Num)]; + + if ( !( face2->flags & FACE_FLOOR ) ) { + continue; + } + + for ( m = 0; m < face1->numEdges; m++ ) { + edge1Num = abs(file->edgeIndex[face1->firstEdge + m]); + for ( n = 0; n < face2->numEdges; n++ ) { + edge2Num = abs(file->edgeIndex[face2->firstEdge + n]); + if ( edge1Num == edge2Num ) { + break; + } + } + if ( n < face2->numEdges ) { + break; + } + } + if ( m < face1->numEdges ) { + break; + } + } + if ( l < otherArea->numFaces ) { + break; + } + } + if ( k < area->numFaces ) { + // create reachability + reach = new idReachability_Walk(); + reach->travelType = TFL_WALK; + reach->toAreaNum = otherAreaNum; + reach->fromAreaNum = areaNum; + reach->edgeNum = abs( edge1Num ); + reach->travelTime = 1; + reach->start = file->EdgeCenter( edge1Num ); + if ( faceNum < 0 ) { + reach->end = reach->start + file->planeList[face->planeNum].Normal() * INSIDEUNITS_WALKEND; + } + else { + reach->end = reach->start - file->planeList[face->planeNum].Normal() * INSIDEUNITS_WALKEND; + } + AddReachabilityToArea( reach, areaNum ); + } + } +} + +/* +================ +idAASReach::Reachability_Step_Barrier_WaterJump_WalkOffLedge +================ +*/ +bool idAASReach::Reachability_Step_Barrier_WaterJump_WalkOffLedge( int area1num, int area2num ) { + int i, j, k, l, edge1Num, edge2Num, areas[10]; + int floor_bestArea1FloorEdgeNum, floor_bestArea2FloorEdgeNum, floor_foundReach; + int water_bestArea1FloorEdgeNum, water_bestArea2FloorEdgeNum, water_foundReach; + int side1, faceSide1, floorFace1Num; + float dist, dist1, dist2, diff, invGravityDot, orthogonalDot; + float x1, x2, x3, x4, y1, y2, y3, y4, tmp, y; + float length, floor_bestLength, water_bestLength, floor_bestDist, water_bestDist; + idVec3 v1, v2, v3, v4, tmpv, p1area1, p1area2, p2area1, p2area2; + idVec3 normal, orthogonal, edgeVec, start, end; + idVec3 floor_bestStart, floor_bestEnd, floor_bestNormal; + idVec3 water_bestStart, water_bestEnd, water_bestNormal; + idVec3 testPoint; + idPlane *plane; + aasArea_t *area1, *area2; + aasFace_t *floorFace1, *floorFace2, *floor_bestFace1, *water_bestFace1; + aasEdge_t *edge1, *edge2; + idReachability_Walk *walkReach; + idReachability_BarrierJump *barrierJumpReach; + idReachability_WaterJump *waterJumpReach; + idReachability_WalkOffLedge *walkOffLedgeReach; + aasTrace_t trace; + + // must be able to walk or swim in the first area + if ( !AreaHasFloor( area1num ) && !CanSwimInArea( area1num ) ) { + return false; + } + + if ( !AreaHasFloor( area2num ) && !CanSwimInArea( area2num ) ) { + return false; + } + + area1 = &file->areas[area1num]; + area2 = &file->areas[area2num]; + + // if the areas are not near anough in the x-y direction + for ( i = 0; i < 2; i++ ) { + if ( area1->bounds[0][i] > area2->bounds[1][i] + 2.0f ) { + return false; + } + if ( area1->bounds[1][i] < area2->bounds[0][i] - 2.0f ) { + return false; + } + } + + floor_foundReach = false; + floor_bestDist = 99999; + floor_bestLength = 0; + floor_bestArea2FloorEdgeNum = 0; + + water_foundReach = false; + water_bestDist = 99999; + water_bestLength = 0; + water_bestArea2FloorEdgeNum = 0; + + for ( i = 0; i < area1->numFaces; i++ ) { + floorFace1Num = file->faceIndex[area1->firstFace + i]; + faceSide1 = floorFace1Num < 0; + floorFace1 = &file->faces[abs(floorFace1Num)]; + + // if this isn't a floor face + if ( !(floorFace1->flags & FACE_FLOOR) ) { + + // if we can swim in the first area + if ( CanSwimInArea( area1num ) ) { + + // face plane must be more or less horizontal + plane = &file->planeList[ floorFace1->planeNum ^ (!faceSide1) ]; + if ( plane->Normal() * file->settings.invGravityDir < file->settings.minFloorCos ) { + continue; + } + } + else { + // if we can't swim in the area it must be a ground face + continue; + } + } + + for ( k = 0; k < floorFace1->numEdges; k++ ) { + edge1Num = file->edgeIndex[floorFace1->firstEdge + k]; + side1 = (edge1Num < 0); + // NOTE: for water faces we must take the side area 1 is on into + // account because the face is shared and doesn't have to be oriented correctly + if ( !(floorFace1->flags & FACE_FLOOR) ) { + side1 = (side1 == faceSide1); + } + edge1Num = abs(edge1Num); + edge1 = &file->edges[edge1Num]; + // vertices of the edge + v1 = file->vertices[edge1->vertexNum[!side1]]; + v2 = file->vertices[edge1->vertexNum[side1]]; + // get a vertical plane through the edge + // NOTE: normal is pointing into area 2 because the face edges are stored counter clockwise + edgeVec = v2 - v1; + normal = edgeVec.Cross( file->settings.invGravityDir ); + normal.Normalize(); + dist = normal * v1; + + // check the faces from the second area + for ( j = 0; j < area2->numFaces; j++ ) { + floorFace2 = &file->faces[abs(file->faceIndex[area2->firstFace + j])]; + // must be a ground face + if ( !(floorFace2->flags & FACE_FLOOR) ) { + continue; + } + // check the edges of this ground face + for ( l = 0; l < floorFace2->numEdges; l++ ) { + edge2Num = abs(file->edgeIndex[floorFace2->firstEdge + l]); + edge2 = &file->edges[edge2Num]; + // vertices of the edge + v3 = file->vertices[edge2->vertexNum[0]]; + v4 = file->vertices[edge2->vertexNum[1]]; + // check the distance between the two points and the vertical plane through the edge of area1 + diff = normal * v3 - dist; + if ( diff < -0.2f || diff > 0.2f ) { + continue; + } + diff = normal * v4 - dist; + if ( diff < -0.2f || diff > 0.2f ) { + continue; + } + + // project the two ground edges into the step side plane + // and calculate the shortest distance between the two + // edges if they overlap in the direction orthogonal to + // the gravity direction + orthogonal = file->settings.invGravityDir.Cross( normal ); + invGravityDot = file->settings.invGravityDir * file->settings.invGravityDir; + orthogonalDot = orthogonal * orthogonal; + // projection into the step plane + // NOTE: since gravity is vertical this is just the z coordinate + y1 = v1[2];//(v1 * file->settings.invGravity) / invGravityDot; + y2 = v2[2];//(v2 * file->settings.invGravity) / invGravityDot; + y3 = v3[2];//(v3 * file->settings.invGravity) / invGravityDot; + y4 = v4[2];//(v4 * file->settings.invGravity) / invGravityDot; + + x1 = (v1 * orthogonal) / orthogonalDot; + x2 = (v2 * orthogonal) / orthogonalDot; + x3 = (v3 * orthogonal) / orthogonalDot; + x4 = (v4 * orthogonal) / orthogonalDot; + + if ( x1 > x2 ) { + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + tmpv = v1; v1 = v2; v2 = tmpv; + } + if ( x3 > x4 ) { + tmp = x3; x3 = x4; x4 = tmp; + tmp = y3; y3 = y4; y4 = tmp; + tmpv = v3; v3 = v4; v4 = tmpv; + } + // if the two projected edge lines have no overlap + if ( x2 <= x3 || x4 <= x1 ) { + continue; + } + // if the two lines fully overlap + if ( (x1 - 0.5f < x3 && x4 < x2 + 0.5f) && (x3 - 0.5f < x1 && x2 < x4 + 0.5f) ) { + dist1 = y3 - y1; + dist2 = y4 - y2; + p1area1 = v1; + p2area1 = v2; + p1area2 = v3; + p2area2 = v4; + } + else { + // if the points are equal + if ( x1 > x3 - 0.1f && x1 < x3 + 0.1f ) { + dist1 = y3 - y1; + p1area1 = v1; + p1area2 = v3; + } + else if ( x1 < x3 ) { + y = y1 + (x3 - x1) * (y2 - y1) / (x2 - x1); + dist1 = y3 - y; + p1area1 = v3; + p1area1[2] = y; + p1area2 = v3; + } + else { + y = y3 + (x1 - x3) * (y4 - y3) / (x4 - x3); + dist1 = y - y1; + p1area1 = v1; + p1area2 = v1; + p1area2[2] = y; + } + // if the points are equal + if ( x2 > x4 - 0.1f && x2 < x4 + 0.1f ) { + dist2 = y4 - y2; + p2area1 = v2; + p2area2 = v4; + } + else if ( x2 < x4 ) { + y = y3 + (x2 - x3) * (y4 - y3) / (x4 - x3); + dist2 = y - y2; + p2area1 = v2; + p2area2 = v2; + p2area2[2] = y; + } + else { + y = y1 + (x4 - x1) * (y2 - y1) / (x2 - x1); + dist2 = y4 - y; + p2area1 = v4; + p2area1[2] = y; + p2area2 = v4; + } + } + + // if both distances are pretty much equal then we take the middle of the points + if ( dist1 > dist2 - 1.0f && dist1 < dist2 + 1.0f ) { + dist = dist1; + start = ( p1area1 + p2area1 ) * 0.5f; + end = ( p1area2 + p2area2 ) * 0.5f; + } + else if (dist1 < dist2) { + dist = dist1; + start = p1area1; + end = p1area2; + } + else { + dist = dist2; + start = p2area1; + end = p2area2; + } + + // get the length of the overlapping part of the edges of the two areas + length = (p2area2 - p1area2).Length(); + + if ( floorFace1->flags & FACE_FLOOR ) { + // if the vertical distance is smaller + if ( dist < floor_bestDist || + // or the vertical distance is pretty much the same + // but the overlapping part of the edges is longer + (dist < floor_bestDist + 1.0f && length > floor_bestLength) ) { + floor_bestDist = dist; + floor_bestLength = length; + floor_foundReach = true; + floor_bestArea1FloorEdgeNum = edge1Num; + floor_bestArea2FloorEdgeNum = edge2Num; + floor_bestFace1 = floorFace1; + floor_bestStart = start; + floor_bestNormal = normal; + floor_bestEnd = end; + } + } + else { + // if the vertical distance is smaller + if ( dist < water_bestDist || + //or the vertical distance is pretty much the same + //but the overlapping part of the edges is longer + (dist < water_bestDist + 1.0f && length > water_bestLength) ) { + water_bestDist = dist; + water_bestLength = length; + water_foundReach = true; + water_bestArea1FloorEdgeNum = edge1Num; + water_bestArea2FloorEdgeNum = edge2Num; + water_bestFace1 = floorFace1; + water_bestStart = start; // best start point in area1 + water_bestNormal = normal; // normal is pointing into area2 + water_bestEnd = end; // best point towards area2 + } + } + } + } + } + } + // + // NOTE: swim reachabilities should already be filtered out + // + // Steps + // + // --------- + // | step height -> TFL_WALK + // --------| + // + // --------- + // ~~~~~~~~| step height and low water -> TFL_WALK + // --------| + // + // ~~~~~~~~~~~~~~~~~~ + // --------- + // | step height and low water up to the step -> TFL_WALK + // --------| + // + // check for a step reachability + if ( floor_foundReach ) { + // if area2 is higher but lower than the maximum step height + // NOTE: floor_bestDist >= 0 also catches equal floor reachabilities + if ( floor_bestDist >= 0 && floor_bestDist < file->settings.maxStepHeight ) { + // create walk reachability from area1 to area2 + walkReach = new idReachability_Walk(); + walkReach->travelType = TFL_WALK; + walkReach->toAreaNum = area2num; + walkReach->fromAreaNum = area1num; + walkReach->start = floor_bestStart + INSIDEUNITS_WALKSTART * floor_bestNormal; + walkReach->end = floor_bestEnd + INSIDEUNITS_WALKEND * floor_bestNormal; + walkReach->edgeNum = abs( floor_bestArea1FloorEdgeNum ); + walkReach->travelTime = 0; + if ( area2->flags & AREA_CROUCH ) { + walkReach->travelTime += file->settings.tt_startCrouching; + } + AddReachabilityToArea( walkReach, area1num ); + return true; + } + } + // + // Water Jumps + // + // --------- + // | + // ~~~~~~~~| + // | + // | higher than step height and water up to waterjump height -> TFL_WATERJUMP + // --------| + // + // ~~~~~~~~~~~~~~~~~~ + // --------- + // | + // | + // | + // | higher than step height and low water up to the step -> TFL_WATERJUMP + // --------| + // + // check for a waterjump reachability + if ( water_foundReach ) { + // get a test point a little bit towards area1 + testPoint = water_bestEnd - INSIDEUNITS * water_bestNormal; + // go down the maximum waterjump height + testPoint[2] -= file->settings.maxWaterJumpHeight; + // if there IS water the sv_maxwaterjump height below the bestend point + if ( area1->flags & AREA_LIQUID ) { + // don't create rediculous water jump reachabilities from areas very far below the water surface + if ( water_bestDist < file->settings.maxWaterJumpHeight + 24 ) { + // water jumping from or towards a crouch only areas is not possible + if ( !(area1->flags & AREA_CROUCH) && !(area2->flags & AREA_CROUCH) ) { + // create water jump reachability from area1 to area2 + waterJumpReach = new idReachability_WaterJump(); + waterJumpReach->travelType = TFL_WATERJUMP; + waterJumpReach->toAreaNum = area2num; + waterJumpReach->fromAreaNum = area1num; + waterJumpReach->start = water_bestStart; + waterJumpReach->end = water_bestEnd + INSIDEUNITS_WATERJUMP * water_bestNormal; + waterJumpReach->edgeNum = abs( floor_bestArea1FloorEdgeNum ); + waterJumpReach->travelTime = file->settings.tt_waterJump; + AddReachabilityToArea( waterJumpReach, area1num ); + return true; + } + } + } + } + // + // Barrier Jumps + // + // --------- + // | + // | + // | + // | higher than max step height lower than max barrier height -> TFL_BARRIERJUMP + // --------| + // + // --------- + // | + // | + // | + // ~~~~~~~~| higher than max step height lower than max barrier height + // --------| and a thin layer of water in the area to jump from -> TFL_BARRIERJUMP + // + // check for a barrier jump reachability + if ( floor_foundReach ) { + //if area2 is higher but lower than the maximum barrier jump height + if ( floor_bestDist > 0 && floor_bestDist < file->settings.maxBarrierHeight ) { + //if no water in area1 or a very thin layer of water on the ground + if ( !water_foundReach || (floor_bestDist - water_bestDist < 16) ) { + // cannot perform a barrier jump towards or from a crouch area + if ( !(area1->flags & AREA_CROUCH) && !(area2->flags & AREA_CROUCH) ) { + // create barrier jump reachability from area1 to area2 + barrierJumpReach = new idReachability_BarrierJump(); + barrierJumpReach->travelType = TFL_BARRIERJUMP; + barrierJumpReach->toAreaNum = area2num; + barrierJumpReach->fromAreaNum = area1num; + barrierJumpReach->start = floor_bestStart + INSIDEUNITS_WALKSTART * floor_bestNormal; + barrierJumpReach->end = floor_bestEnd + INSIDEUNITS_WALKEND * floor_bestNormal; + barrierJumpReach->edgeNum = abs( floor_bestArea1FloorEdgeNum ); + barrierJumpReach->travelTime = file->settings.tt_barrierJump; + AddReachabilityToArea( barrierJumpReach, area1num ); + return true; + } + } + } + } + // + // Walk and Walk Off Ledge + // + // --------| + // | can walk or step back -> TFL_WALK + // --------- + // + // --------| + // | + // | + // | + // | cannot walk/step back -> TFL_WALKOFFLEDGE + // --------- + // + // --------| + // | + // |~~~~~~~~ + // | + // | cannot step back but can waterjump back -> TFL_WALKOFFLEDGE + // --------- FIXME: create TFL_WALK reach?? + // + // check for a walk or walk off ledge reachability + if ( floor_foundReach ) { + if ( floor_bestDist < 0 ) { + if ( floor_bestDist > -file->settings.maxStepHeight ) { + // create walk reachability from area1 to area2 + walkReach = new idReachability_Walk(); + walkReach->travelType = TFL_WALK; + walkReach->toAreaNum = area2num; + walkReach->fromAreaNum = area1num; + walkReach->start = floor_bestStart + INSIDEUNITS_WALKSTART * floor_bestNormal; + walkReach->end = floor_bestEnd + INSIDEUNITS_WALKEND * floor_bestNormal; + walkReach->edgeNum = abs( floor_bestArea1FloorEdgeNum ); + walkReach->travelTime = 1; + AddReachabilityToArea( walkReach, area1num ); + return true; + } + // if no maximum fall height set or less than the max + if ( !file->settings.maxFallHeight || idMath::Fabs(floor_bestDist) < file->settings.maxFallHeight ) { + // trace a bounding box vertically to check for solids + floor_bestEnd += INSIDEUNITS * floor_bestNormal; + start = floor_bestEnd; + start[2] = floor_bestStart[2]; + end = floor_bestEnd; + end[2] += 4; + trace.areas = areas; + trace.maxAreas = sizeof(areas) / sizeof(int); + file->Trace( trace, start, end ); + // if the trace didn't start in solid and nothing was hit + if ( trace.lastAreaNum && trace.fraction >= 1.0f ) { + // the trace end point must be in the goal area + if ( trace.lastAreaNum == area2num ) { + // don't create reachability if going through a cluster portal + for (i = 0; i < trace.numAreas; i++) { + if ( AreaIsClusterPortal( trace.areas[i] ) ) { + break; + } + } + if ( i >= trace.numAreas ) { + // create a walk off ledge reachability from area1 to area2 + walkOffLedgeReach = new idReachability_WalkOffLedge(); + walkOffLedgeReach->travelType = TFL_WALKOFFLEDGE; + walkOffLedgeReach->toAreaNum = area2num; + walkOffLedgeReach->fromAreaNum = area1num; + walkOffLedgeReach->start = floor_bestStart; + walkOffLedgeReach->end = floor_bestEnd; + walkOffLedgeReach->edgeNum = abs( floor_bestArea1FloorEdgeNum ); + walkOffLedgeReach->travelTime = file->settings.tt_startWalkOffLedge + idMath::Fabs(floor_bestDist) * 50 / file->settings.gravityValue; + AddReachabilityToArea( walkOffLedgeReach, area1num ); + return true; + } + } + } + } + } + } + return false; +} + +/* +================ +idAASReach::Reachability_WalkOffLedge +================ +*/ +void idAASReach::Reachability_WalkOffLedge( int areaNum ) { + int i, j, faceNum, edgeNum, side, reachAreaNum, p, areas[10]; + aasArea_t *area; + aasFace_t *face; + aasEdge_t *edge; + idPlane *plane; + idVec3 v1, v2, mid, dir, testEnd; + idReachability_WalkOffLedge *reach; + aasTrace_t trace; + + if ( !AreaHasFloor( areaNum ) || CanSwimInArea( areaNum ) ) { + return; + } + + area = &file->areas[areaNum]; + + for ( i = 0; i < area->numFaces; i++ ) { + faceNum = file->faceIndex[area->firstFace + i]; + face = &file->faces[abs(faceNum)]; + + // face must be a floor face + if ( !(face->flags & FACE_FLOOR) ) { + continue; + } + + for ( j = 0; j < face->numEdges; j++ ) { + + edgeNum = file->edgeIndex[face->firstEdge + j]; + edge = &file->edges[abs(edgeNum)]; + + //if ( !(edge->flags & EDGE_LEDGE) ) { + // continue; + //} + + side = edgeNum < 0; + + v1 = file->vertices[edge->vertexNum[side]]; + v2 = file->vertices[edge->vertexNum[!side]]; + + plane = &file->planeList[face->planeNum ^ INTSIGNBITSET(faceNum) ]; + + // get the direction into the other area + dir = plane->Normal().Cross( v2 - v1 ); + dir.Normalize(); + + mid = ( v1 + v2 ) * 0.5f; + testEnd = mid + INSIDEUNITS_WALKEND * dir; + testEnd[2] -= file->settings.maxFallHeight + 1.0f; + trace.areas = areas; + trace.maxAreas = sizeof(areas) / sizeof(int); + file->Trace( trace, mid, testEnd ); + + reachAreaNum = trace.lastAreaNum; + if ( !reachAreaNum || reachAreaNum == areaNum ) { + continue; + } + if ( idMath::Fabs( mid[2] - trace.endpos[2] ) > file->settings.maxFallHeight ) { + continue; + } + if ( !AreaHasFloor( reachAreaNum ) && !CanSwimInArea( reachAreaNum ) ) { + continue; + } + if ( ReachabilityExists( areaNum, reachAreaNum) ) { + continue; + } + // if not going through a cluster portal + for ( p = 0; p < trace.numAreas; p++ ) { + if ( AreaIsClusterPortal( trace.areas[p] ) ) { + break; + } + } + if ( p < trace.numAreas ) { + continue; + } + + reach = new idReachability_WalkOffLedge(); + reach->travelType = TFL_WALKOFFLEDGE; + reach->toAreaNum = reachAreaNum; + reach->fromAreaNum = areaNum; + reach->start = mid; + reach->end = trace.endpos; + reach->edgeNum = abs( edgeNum ); + reach->travelTime = file->settings.tt_startWalkOffLedge + idMath::Fabs(mid[2] - trace.endpos[2]) * 50 / file->settings.gravityValue; + AddReachabilityToArea( reach, areaNum ); + } + } +} + +/* +================ +idAASReach::FlagReachableAreas +================ +*/ +void idAASReach::FlagReachableAreas( idAASFileLocal *file ) { + int i, numReachableAreas; + + numReachableAreas = 0; + for ( i = 1; i < file->areas.Num(); i++ ) { + + if ( ( file->areas[i].flags & ( AREA_FLOOR | AREA_LADDER ) ) || + ( file->areas[i].contents & AREACONTENTS_WATER ) ) { + file->areas[i].flags |= AREA_REACHABLE_WALK; + } + if ( file->GetSettings().allowFlyReachabilities ) { + file->areas[i].flags |= AREA_REACHABLE_FLY; + } + numReachableAreas++; + } + + common->Printf( "%6d reachable areas\n", numReachableAreas ); +} + +/* +================ +idAASReach::Build +================ +*/ +bool idAASReach::Build( const idMapFile *mapFile, idAASFileLocal *file ) { + int i, j, lastPercent, percent; + + this->mapFile = mapFile; + this->file = file; + numReachabilities = 0; + + common->Printf( "[Reachability]\n" ); + + // delete all existing reachabilities + file->DeleteReachabilities(); + + FlagReachableAreas( file ); + + for ( i = 1; i < file->areas.Num(); i++ ) { + if ( !( file->areas[i].flags & AREA_REACHABLE_WALK ) ) { + continue; + } + if ( file->GetSettings().allowSwimReachabilities ) { + Reachability_Swim( i ); + } + Reachability_EqualFloorHeight( i ); + } + + lastPercent = -1; + for ( i = 1; i < file->areas.Num(); i++ ) { + + if ( !( file->areas[i].flags & AREA_REACHABLE_WALK ) ) { + continue; + } + + for ( j = 0; j < file->areas.Num(); j++ ) { + if ( i == j ) { + continue; + } + + if ( !( file->areas[j].flags & AREA_REACHABLE_WALK ) ) { + continue; + } + + if ( ReachabilityExists( i, j ) ) { + continue; + } + if ( Reachability_Step_Barrier_WaterJump_WalkOffLedge( i, j ) ) { + continue; + } + } + + //Reachability_WalkOffLedge( i ); + + percent = 100 * i / file->areas.Num(); + if ( percent > lastPercent ) { + common->Printf( "\r%6d%%", percent ); + lastPercent = percent; + } + } + + if ( file->GetSettings().allowFlyReachabilities ) { + for ( i = 1; i < file->areas.Num(); i++ ) { + Reachability_Fly( i ); + } + } + + file->LinkReversedReachability(); + + common->Printf( "\r%6d reachabilities\n", numReachabilities ); + + return true; +} diff --git a/tools/compilers/aas/AASReach.h b/tools/compilers/aas/AASReach.h new file mode 100644 index 000000000..20f281ff9 --- /dev/null +++ b/tools/compilers/aas/AASReach.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __AASREACH_H__ +#define __AASREACH_H__ + +/* +=============================================================================== + + Reachabilities + +=============================================================================== +*/ + +class idAASReach { + +public: + bool Build( const idMapFile *mapFile, idAASFileLocal *file ); + +private: + const idMapFile * mapFile; + idAASFileLocal * file; + int numReachabilities; + bool allowSwimReachabilities; + bool allowFlyReachabilities; + +private: // reachability + void FlagReachableAreas( idAASFileLocal *file ); + bool ReachabilityExists( int fromAreaNum, int toAreaNum ); + bool CanSwimInArea( int areaNum ); + bool AreaHasFloor( int areaNum ); + bool AreaIsClusterPortal( int areaNum ); + void AddReachabilityToArea( idReachability *reach, int areaNum ); + void Reachability_Fly( int areaNum ); + void Reachability_Swim( int areaNum ); + void Reachability_EqualFloorHeight( int areaNum ); + bool Reachability_Step_Barrier_WaterJump_WalkOffLedge( int fromAreaNum, int toAreaNum ); + void Reachability_WalkOffLedge( int areaNum ); + +}; + +#endif /* !__AASREACH_H__ */ diff --git a/tools/compilers/aas/Brush.cpp b/tools/compilers/aas/Brush.cpp new file mode 100644 index 000000000..494fbbc42 --- /dev/null +++ b/tools/compilers/aas/Brush.cpp @@ -0,0 +1,1573 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "Brush.h" + +#define BRUSH_EPSILON 0.1f +#define BRUSH_PLANE_NORMAL_EPSILON 0.00001f +#define BRUSH_PLANE_DIST_EPSILON 0.01f + +#define OUTPUT_UPDATE_TIME 500 // update every 500 msec + +//#define OUTPUT_CHOP_STATS + +/* +============ +DisplayRealTimeString +============ +*/ +void DisplayRealTimeString( char *string, ... ) { + va_list argPtr; + char buf[MAX_STRING_CHARS]; + static int lastUpdateTime; + int time; + + time = Sys_Milliseconds(); + if ( time > lastUpdateTime + OUTPUT_UPDATE_TIME ) { + va_start( argPtr, string ); + vsprintf( buf, string, argPtr ); + va_end( argPtr ); + common->Printf( buf ); + lastUpdateTime = time; + } +} + + +//=============================================================== +// +// idBrushSide +// +//=============================================================== + +/* +============ +idBrushSide::idBrushSide +============ +*/ +idBrushSide::idBrushSide( void ) { + flags = 0; + planeNum = -1; + winding = NULL; +} + +/* +============ +idBrushSide::idBrushSide +============ +*/ +idBrushSide::idBrushSide( const idPlane &plane, int planeNum ) { + this->flags = 0; + this->plane = plane; + this->planeNum = planeNum; + this->winding = NULL; +} + +/* +============ +idBrushSide::~idBrushSide +============ +*/ +idBrushSide::~idBrushSide( void ) { + if ( winding ) { + delete winding; + } +} + +/* +============ +idBrushSide::Copy +============ +*/ +idBrushSide *idBrushSide::Copy( void ) const { + idBrushSide *side; + + side = new idBrushSide( plane, planeNum ); + side->flags = flags; + if ( winding ) { + side->winding = winding->Copy(); + } + else { + side->winding = NULL; + } + return side; +} + +/* +============ +idBrushSide::Split +============ +*/ +int idBrushSide::Split( const idPlane &splitPlane, idBrushSide **front, idBrushSide **back ) const { + idWinding *frontWinding, *backWinding; + + assert( winding ); + + *front = *back = NULL; + + winding->Split( splitPlane, 0.0f, &frontWinding, &backWinding ); + + if ( frontWinding ) { + (*front) = new idBrushSide( plane, planeNum ); + (*front)->winding = frontWinding; + (*front)->flags = flags; + } + + if ( backWinding ) { + (*back) = new idBrushSide( plane, planeNum ); + (*back)->winding = backWinding; + (*back)->flags = flags; + } + + if ( frontWinding && backWinding ) { + return PLANESIDE_CROSS; + } + else if ( frontWinding ) { + return PLANESIDE_FRONT; + } + else { + return PLANESIDE_BACK; + } +} + + +//=============================================================== +// +// idBrushSide +// +//=============================================================== + +/* +============ +idBrush::idBrush +============ +*/ +idBrush::idBrush( void ) { + contents = flags = 0; + bounds.Clear(); + sides.Clear(); + windingsValid = false; +} + + +/* +============ +idBrush::~idBrush +============ +*/ +idBrush::~idBrush( void ) { + for ( int i = 0; i < sides.Num(); i++ ) { + delete sides[i]; + } +} + +/* +============ +idBrush::RemoveSidesWithoutWinding +============ +*/ +bool idBrush::RemoveSidesWithoutWinding( void ) { + int i; + + for ( i = 0; i < sides.Num(); i++ ) { + + if ( sides[i]->winding ) { + continue; + } + + sides.RemoveIndex( i ); + i--; + } + + return ( sides.Num() >= 4 ); +} + +/* +============ +idBrush::CreateWindings +============ +*/ +bool idBrush::CreateWindings( void ) { + int i, j; + idBrushSide *side; + + bounds.Clear(); + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + + if ( side->winding ) { + delete side->winding; + } + + side->winding = new idWinding( side->plane.Normal(), side->plane.Dist() ); + + for ( j = 0; j < sides.Num() && side->winding; j++ ) { + if ( i == j ) { + continue; + } + // keep the winding if on the clip plane + side->winding = side->winding->Clip( -sides[j]->plane, BRUSH_EPSILON, true ); + } + + if ( side->winding ) { + for ( j = 0; j < side->winding->GetNumPoints(); j++ ) { + bounds.AddPoint( (*side->winding)[j].ToVec3() ); + } + } + } + + if ( bounds[0][0] > bounds[1][0] ) { + return false; + } + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] < MIN_WORLD_COORD || bounds[1][i] > MAX_WORLD_COORD ) { + return false; + } + } + + windingsValid = true; + + return true; +} + +/* +============ +idBrush::BoundBrush +============ +*/ +void idBrush::BoundBrush( const idBrush *original ) { + int i, j; + idBrushSide *side; + idWinding *w; + + assert( windingsValid ); + + bounds.Clear(); + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + + w = side->winding; + + if ( !w ) { + continue; + } + + for ( j = 0; j < w->GetNumPoints(); j++ ) { + bounds.AddPoint( (*w)[j].ToVec3() ); + } + } + + if ( bounds[0][0] > bounds[1][0] ) { + if ( original ) { + idBrushMap *bm = new idBrushMap( "error_brush", "_original" ); + bm->WriteBrush( original ); + delete bm; + } + common->Error( "idBrush::BoundBrush: brush %d on entity %d without windings", primitiveNum, entityNum ); + } + + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] < MIN_WORLD_COORD || bounds[1][i] > MAX_WORLD_COORD ) { + if ( original ) { + idBrushMap *bm = new idBrushMap( "error_brush", "_original" ); + bm->WriteBrush( original ); + delete bm; + } + common->Error( "idBrush::BoundBrush: brush %d on entity %d is unbounded", primitiveNum, entityNum ); + } + } +} + +/* +============ +idBrush::FromSides +============ +*/ +bool idBrush::FromSides( idList &sideList ) { + int i; + + for ( i = 0; i < sideList.Num(); i++ ) { + sides.Append( sideList[i] ); + } + + sideList.Clear(); + + return CreateWindings(); +} + +/* +============ +idBrush::FromWinding +============ +*/ +bool idBrush::FromWinding( const idWinding &w, const idPlane &windingPlane ) { + int i, j, bestAxis; + idPlane plane; + idVec3 normal, axialNormal; + + sides.Append( new idBrushSide( windingPlane, -1 ) ); + sides.Append( new idBrushSide( -windingPlane, -1 ) ); + + bestAxis = 0; + for ( i = 1; i < 3; i++ ) { + if ( idMath::Fabs( windingPlane.Normal()[i] ) > idMath::Fabs( windingPlane.Normal()[bestAxis] ) ) { + bestAxis = i; + } + } + axialNormal = vec3_origin; + if ( windingPlane.Normal()[bestAxis] > 0.0f ) { + axialNormal[bestAxis] = 1.0f; + } + else { + axialNormal[bestAxis] = -1.0f; + } + + for ( i = 0; i < w.GetNumPoints(); i++ ) { + j = (i+1) % w.GetNumPoints(); + normal = ( w[j].ToVec3() - w[i].ToVec3() ).Cross( axialNormal ); + if ( normal.Normalize() < 0.5f ) { + continue; + } + plane.SetNormal( normal ); + plane.FitThroughPoint( w[j].ToVec3() ); + sides.Append( new idBrushSide( plane, -1 ) ); + } + + if ( sides.Num() < 4 ) { + for ( i = 0; i < sides.Num(); i++ ) { + delete sides[i]; + } + sides.Clear(); + return false; + } + + sides[0]->winding = w.Copy(); + windingsValid = true; + BoundBrush(); + + return true; +} + +/* +============ +idBrush::FromBounds +============ +*/ +bool idBrush::FromBounds( const idBounds &bounds ) { + int axis, dir; + idVec3 normal; + idPlane plane; + + for ( axis = 0; axis < 3; axis++ ) { + for ( dir = -1; dir <= 1; dir += 2 ) { + normal = vec3_origin; + normal[axis] = dir; + plane.SetNormal( normal ); + plane.SetDist( dir * bounds[(dir == 1)][axis] ); + sides.Append( new idBrushSide( plane, -1 ) ); + } + } + + return CreateWindings(); +} + +/* +============ +idBrush::Transform +============ +*/ +void idBrush::Transform( const idVec3 &origin, const idMat3 &axis ) { + int i; + bool transformed = false; + + if ( axis.IsRotated() ) { + for ( i = 0; i < sides.Num(); i++ ) { + sides[i]->plane.RotateSelf( vec3_origin, axis ); + } + transformed = true; + } + if ( origin != vec3_origin ) { + for ( i = 0; i < sides.Num(); i++ ) { + sides[i]->plane.TranslateSelf( origin ); + } + transformed = true; + } + if ( transformed ) { + CreateWindings(); + } +} + +/* +============ +idBrush::GetVolume +============ +*/ +float idBrush::GetVolume( void ) const { + int i; + idWinding *w; + idVec3 corner; + float d, area, volume; + + // grab the first valid point as a corner + w = NULL; + for ( i = 0; i < sides.Num(); i++ ) { + w = sides[i]->winding; + if ( w ) { + break; + } + } + if ( !w ) { + return 0.0f; + } + corner = (*w)[0].ToVec3(); + + // create tetrahedrons to all other sides + volume = 0.0f; + for ( ; i < sides.Num(); i++) { + w = sides[i]->winding; + if ( !w ) { + continue; + } + d = -( corner * sides[i]->plane.Normal() - sides[i]->plane.Dist() ); + area = w->GetArea(); + volume += d * area; + } + + return ( volume * ( 1.0f / 3.0f ) ); +} + +/* +============ +idBrush::Subtract +============ +*/ +bool idBrush::Subtract( const idBrush *b, idBrushList &list ) const { + int i; + idBrush *front, *back; + const idBrush *in; + + list.Clear(); + in = this; + for ( i = 0; i < b->sides.Num() && in; i++ ) { + + in->Split( b->sides[i]->plane, b->sides[i]->planeNum, &front, &back ); + + if ( in != this ) { + delete in; + } + if ( front ) { + list.AddToTail( front ); + } + in = back; + } + // if didn't really intersect + if ( !in ) { + list.Free(); + return false; + } + + delete in; + return true; +} + +/* +============ +idBrush::TryMerge +============ +*/ +bool idBrush::TryMerge( const idBrush *brush, const idPlaneSet &planeList ) { + int i, j, k, l, m, seperatingPlane; + const idBrush *brushes[2]; + const idWinding *w; + const idPlane *plane; + + // brush bounds should overlap + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] > brush->bounds[1][i] + 0.1f ) { + return false; + } + if ( bounds[1][i] < brush->bounds[0][i] - 0.1f ) { + return false; + } + } + + // the brushes should share an opposite plane + seperatingPlane = -1; + for ( i = 0; i < GetNumSides(); i++ ) { + for ( j = 0; j < brush->GetNumSides(); j++ ) { + if ( GetSide(i)->GetPlaneNum() == (brush->GetSide(j)->GetPlaneNum() ^ 1) ) { + // may only have one seperating plane + if ( seperatingPlane != -1 ) { + return false; + } + seperatingPlane = GetSide(i)->GetPlaneNum(); + break; + } + } + } + if ( seperatingPlane == -1 ) { + return false; + } + + brushes[0] = this; + brushes[1] = brush; + + for ( i = 0; i < 2; i++ ) { + + j = !i; + + for ( k = 0; k < brushes[i]->GetNumSides(); k++ ) { + + // if the brush side plane is the seprating plane + if ( !( ( brushes[i]->GetSide(k)->GetPlaneNum() ^ seperatingPlane ) >> 1 ) ) { + continue; + } + + plane = &brushes[i]->GetSide(k)->GetPlane(); + + // all the non seperating brush sides of the other brush should be at the back or on the plane + for ( l = 0; l < brushes[j]->GetNumSides(); l++ ) { + + w = brushes[j]->GetSide(l)->GetWinding(); + if ( !w ) { + continue; + } + + if ( !( ( brushes[j]->GetSide(l)->GetPlaneNum() ^ seperatingPlane ) >> 1 ) ) { + continue; + } + + for ( m = 0; m < w->GetNumPoints(); m++ ) { + if ( plane->Distance( (*w)[m].ToVec3() ) > 0.1f ) { + return false; + } + } + } + } + } + + // add any sides from the other brush to this brush + for ( i = 0; i < brush->GetNumSides(); i++ ) { + for ( j = 0; j < GetNumSides(); j++ ) { + if ( !( ( brush->GetSide(i)->GetPlaneNum() ^ GetSide(j)->GetPlaneNum() ) >> 1 ) ) { + break; + } + } + if ( j < GetNumSides() ) { + sides[j]->flags &= brush->GetSide(i)->GetFlags(); + continue; + } + sides.Append( brush->GetSide(i)->Copy() ); + } + + // remove any side from this brush that is the opposite of a side of the other brush + for ( i = 0; i < GetNumSides(); i++ ) { + for ( j = 0; j < brush->GetNumSides(); j++ ) { + if ( GetSide(i)->GetPlaneNum() == ( brush->GetSide(j)->GetPlaneNum() ^ 1 ) ) { + break; + } + } + if ( j < brush->GetNumSides() ) { + delete sides[i]; + sides.RemoveIndex(i); + i--; + continue; + } + } + + contents |= brush->contents; + + CreateWindings(); + BoundBrush(); + + return true; +} + +/* +============ +idBrush::Split +============ +*/ +int idBrush::Split( const idPlane &plane, int planeNum, idBrush **front, idBrush **back ) const { + int res, i, j; + idBrushSide *side, *frontSide, *backSide; + float dist, maxBack, maxFront, *maxBackWinding, *maxFrontWinding; + idWinding *w, *mid; + + assert( windingsValid ); + + if ( front ) { + *front = NULL; + } + if ( back ) { + *back = NULL; + } + + res = bounds.PlaneSide( plane, -BRUSH_EPSILON ); + if ( res == PLANESIDE_FRONT ) { + if ( front ) { + *front = Copy(); + } + return res; + } + if ( res == PLANESIDE_BACK ) { + if ( back ) { + *back = Copy(); + } + return res; + } + + maxBackWinding = (float *) _alloca16( sides.Num() * sizeof(float) ); + maxFrontWinding = (float *) _alloca16( sides.Num() * sizeof(float) ); + + maxFront = maxBack = 0.0f; + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + + w = side->winding; + + if ( !w ) { + continue; + } + + maxBackWinding[i] = 10.0f; + maxFrontWinding[i] = -10.0f; + + for ( j = 0; j < w->GetNumPoints(); j++ ) { + + dist = plane.Distance( (*w)[j].ToVec3() ); + if ( dist > maxFrontWinding[i] ) { + maxFrontWinding[i] = dist; + } + if ( dist < maxBackWinding[i] ) { + maxBackWinding[i] = dist; + } + } + + if ( maxFrontWinding[i] > maxFront ) { + maxFront = maxFrontWinding[i]; + } + if ( maxBackWinding[i] < maxBack ) { + maxBack = maxBackWinding[i]; + } + } + + if ( maxFront < BRUSH_EPSILON ) { + if ( back ) { + *back = Copy(); + } + return PLANESIDE_BACK; + } + + if ( maxBack > -BRUSH_EPSILON ) { + if ( front ) { + *front = Copy(); + } + return PLANESIDE_FRONT; + } + + mid = new idWinding( plane.Normal(), plane.Dist() ); + + for ( i = 0; i < sides.Num() && mid; i++ ) { + mid = mid->Clip( -sides[i]->plane, BRUSH_EPSILON, false ); + } + + if ( mid ) { + if ( mid->IsTiny() ) { + delete mid; + mid = NULL; + } + else if ( mid->IsHuge() ) { + // if the winding is huge then the brush is unbounded + common->Warning( "brush %d on entity %d is unbounded" + "( %1.2f %1.2f %1.2f )-( %1.2f %1.2f %1.2f )-( %1.2f %1.2f %1.2f )", primitiveNum, entityNum, + bounds[0][0], bounds[0][1], bounds[0][2], bounds[1][0], bounds[1][1], bounds[1][2], + bounds[1][0]-bounds[0][0], bounds[1][1]-bounds[0][1], bounds[1][2]-bounds[0][2] ); + delete mid; + mid = NULL; + } + } + + if ( !mid ) { + if ( maxFront > - maxBack ) { + if ( front ) { + *front = Copy(); + } + return PLANESIDE_FRONT; + } + else { + if ( back ) { + *back = Copy(); + } + return PLANESIDE_BACK; + } + } + + if ( !front && !back ) { + delete mid; + return PLANESIDE_CROSS; + } + + *front = new idBrush(); + (*front)->SetContents( contents ); + (*front)->SetEntityNum( entityNum ); + (*front)->SetPrimitiveNum( primitiveNum ); + *back = new idBrush(); + (*back)->SetContents( contents ); + (*back)->SetEntityNum( entityNum ); + (*back)->SetPrimitiveNum( primitiveNum ); + + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + + if ( !side->winding ) { + continue; + } + + // if completely at the front + if ( maxBackWinding[i] >= BRUSH_EPSILON ) { + (*front)->sides.Append( side->Copy() ); + } + // if completely at the back + else if ( maxFrontWinding[i] <= -BRUSH_EPSILON ) { + (*back)->sides.Append( side->Copy() ); + } + else { + // split the side + side->Split( plane, &frontSide, &backSide ); + if ( frontSide ) { + (*front)->sides.Append( frontSide ); + } + else if ( maxFrontWinding[i] > -BRUSH_EPSILON ) { + // favor an overconstrained brush + side = side->Copy(); + side->winding = side->winding->Clip( idPlane( plane.Normal(), (plane.Dist() - (BRUSH_EPSILON+0.02f)) ), 0.01f, true ); + assert( side->winding ); + (*front)->sides.Append( side ); + } + if ( backSide ) { + (*back)->sides.Append( backSide ); + } + else if ( maxBackWinding[i] < BRUSH_EPSILON ) { + // favor an overconstrained brush + side = side->Copy(); + side->winding = side->winding->Clip( idPlane( -plane.Normal(), -(plane.Dist() + (BRUSH_EPSILON+0.02f)) ), 0.01f, true ); + assert( side->winding ); + (*back)->sides.Append( side ); + } + } + } + + side = new idBrushSide( -plane, planeNum^1 ); + side->winding = mid->Reverse(); + side->flags |= SFL_SPLIT; + (*front)->sides.Append( side ); + (*front)->windingsValid = true; + (*front)->BoundBrush( this ); + + side = new idBrushSide( plane, planeNum ); + side->winding = mid; + side->flags |= SFL_SPLIT; + (*back)->sides.Append( side ); + (*back)->windingsValid = true; + (*back)->BoundBrush( this ); + + return PLANESIDE_CROSS; +} + +/* +============ +idBrush::AddBevelsForAxialBox +============ +*/ +#define BRUSH_BEVEL_EPSILON 0.1f + +void idBrush::AddBevelsForAxialBox( void ) { + int axis, dir, i, j, k, l, order; + idBrushSide *side, *newSide; + idPlane plane; + idVec3 normal, vec; + idWinding *w, *w2; + float d, minBack; + + assert( windingsValid ); + + // add the axial planes + order = 0; + for ( axis = 0; axis < 3; axis++ ) { + + for ( dir = -1; dir <= 1; dir += 2, order++ ) { + + // see if the plane is already present + for ( i = 0; i < sides.Num(); i++ ) { + if ( dir > 0 ) { + if ( sides[i]->plane.Normal()[axis] >= 0.9999f ) { + break; + } + } + else { + if ( sides[i]->plane.Normal()[axis] <= -0.9999f ) { + break; + } + } + } + + if ( i >= sides.Num() ) { + normal = vec3_origin; + normal[axis] = dir; + plane.SetNormal( normal ); + plane.SetDist( dir * bounds[(dir == 1)][axis] ); + newSide = new idBrushSide( plane, -1 ); + newSide->SetFlag( SFL_BEVEL ); + sides.Append( newSide ); + } + } + } + + // if the brush is pure axial we're done + if ( sides.Num() == 6 ) { + return; + } + + // test the non-axial plane edges + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + w = side->winding; + if ( !w ) { + continue; + } + + for ( j = 0; j < w->GetNumPoints(); j++) { + k = (j+1) % w->GetNumPoints(); + vec = (*w)[j].ToVec3() - (*w)[k].ToVec3(); + if ( vec.Normalize() < 0.5f ) { + continue; + } + for ( k = 0; k < 3; k++ ) { + if ( vec[k] == 1.0f || vec[k] == -1.0f || (vec[k] == 0.0f && vec[(k+1)%3] == 0.0f) ) { + break; // axial + } + } + if ( k < 3 ) { + continue; // only test non-axial edges + } + + // try the six possible slanted axials from this edge + for ( axis = 0; axis < 3; axis++ ) { + + for ( dir = -1; dir <= 1; dir += 2 ) { + + // construct a plane + normal = vec3_origin; + normal[axis] = dir; + normal = vec.Cross( normal ); + if ( normal.Normalize() < 0.5f ) { + continue; + } + plane.SetNormal( normal ); + plane.FitThroughPoint( (*w)[j].ToVec3() ); + + // if all the points on all the sides are + // behind this plane, it is a proper edge bevel + for ( k = 0; k < sides.Num(); k++ ) { + + // if this plane has allready been used, skip it + if ( plane.Compare( sides[k]->plane, 0.001f, 0.1f ) ) { + break; + } + + w2 = sides[k]->winding; + if ( !w2 ) { + continue; + } + minBack = 0.0f; + for ( l = 0; l < w2->GetNumPoints(); l++ ) { + d = plane.Distance( (*w2)[l].ToVec3() ); + if ( d > BRUSH_BEVEL_EPSILON ) { + break; // point at the front + } + if ( d < minBack ) { + minBack = d; + } + } + // if some point was at the front + if ( l < w2->GetNumPoints() ) { + break; + } + // if no points at the back then the winding is on the bevel plane + if ( minBack > -BRUSH_BEVEL_EPSILON ) { + break; + } + } + + if ( k < sides.Num() ) { + continue; // wasn't part of the outer hull + } + + // add this plane + newSide = new idBrushSide( plane, -1 ); + newSide->SetFlag( SFL_BEVEL ); + sides.Append( newSide ); + } + } + } + } +} + +/* +============ +idBrush::ExpandForAxialBox +============ +*/ +void idBrush::ExpandForAxialBox( const idBounds &bounds ) { + int i, j; + idBrushSide *side; + idVec3 v; + + AddBevelsForAxialBox(); + + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + + for ( j = 0; j < 3; j++ ) { + if ( side->plane.Normal()[j] > 0.0f ) { + v[j] = bounds[0][j]; + } + else { + v[j] = bounds[1][j]; + } + } + + side->plane.SetDist( side->plane.Dist() + v * -side->plane.Normal() ); + } + + if ( !CreateWindings() ) { + common->Error( "idBrush::ExpandForAxialBox: brush %d on entity %d imploded", primitiveNum, entityNum ); + } + + /* + // after expansion at least all non bevel sides should have a winding + for ( i = 0; i < sides.Num(); i++ ) { + side = sides[i]; + if ( !side->winding ) { + if ( !( side->flags & SFL_BEVEL ) ) { + int shit = 1; + } + } + } + */ +} + +/* +============ +idBrush::Copy +============ +*/ +idBrush *idBrush::Copy( void ) const { + int i; + idBrush *b; + + b = new idBrush(); + b->entityNum = entityNum; + b->primitiveNum = primitiveNum; + b->contents = contents; + b->windingsValid = windingsValid; + b->bounds = bounds; + for ( i = 0; i < sides.Num(); i++ ) { + b->sides.Append( sides[i]->Copy() ); + } + return b; +} + + +//=============================================================== +// +// idBrushList +// +//=============================================================== + +/* +============ +idBrushList::idBrushList +============ +*/ +idBrushList::idBrushList( void ) { + numBrushes = numBrushSides = 0; + head = tail = NULL; +} + +/* +============ +idBrushList::~idBrushList +============ +*/ +idBrushList::~idBrushList( void ) { +} + +/* +============ +idBrushList::GetBounds +============ +*/ +idBounds idBrushList::GetBounds( void ) const { + idBounds bounds; + idBrush *b; + + bounds.Clear(); + for ( b = Head(); b; b = b->Next() ) { + bounds += b->GetBounds(); + } + return bounds; +} + +/* +============ +idBrushList::AddToTail +============ +*/ +void idBrushList::AddToTail( idBrush *brush ) { + brush->next = NULL; + if ( tail ) { + tail->next = brush; + } + tail = brush; + if ( !head ) { + head = brush; + } + numBrushes++; + numBrushSides += brush->sides.Num(); +} + +/* +============ +idBrushList::AddToTail +============ +*/ +void idBrushList::AddToTail( idBrushList &list ) { + idBrush *brush, *next; + + for ( brush = list.head; brush; brush = next ) { + next = brush->next; + brush->next = NULL; + if ( tail ) { + tail->next = brush; + } + tail = brush; + if ( !head ) { + head = brush; + } + numBrushes++; + numBrushSides += brush->sides.Num(); + } + list.head = list.tail = NULL; + list.numBrushes = 0; +} + +/* +============ +idBrushList::AddToFront +============ +*/ +void idBrushList::AddToFront( idBrush *brush ) { + brush->next = head; + head = brush; + if ( !tail ) { + tail = brush; + } + numBrushes++; + numBrushSides += brush->sides.Num(); +} + +/* +============ +idBrushList::AddToFront +============ +*/ +void idBrushList::AddToFront( idBrushList &list ) { + idBrush *brush, *next; + + for ( brush = list.head; brush; brush = next ) { + next = brush->next; + brush->next = head; + head = brush; + if ( !tail ) { + tail = brush; + } + numBrushes++; + numBrushSides += brush->sides.Num(); + } + list.head = list.tail = NULL; + list.numBrushes = 0; +} + +/* +============ +idBrushList::Remove +============ +*/ +void idBrushList::Remove( idBrush *brush ) { + idBrush *b, *last; + + last = NULL; + for ( b = head; b; b = b->next ) { + if ( b == brush ) { + if ( last ) { + last->next = b->next; + } + else { + head = b->next; + } + if ( b == tail ) { + tail = last; + } + numBrushes--; + numBrushSides -= brush->sides.Num(); + return; + } + last = b; + } +} + +/* +============ +idBrushList::Delete +============ +*/ +void idBrushList::Delete( idBrush *brush ) { + idBrush *b, *last; + + last = NULL; + for ( b = head; b; b = b->next ) { + if ( b == brush ) { + if ( last ) { + last->next = b->next; + } + else { + head = b->next; + } + if ( b == tail ) { + tail = last; + } + numBrushes--; + numBrushSides -= b->sides.Num(); + delete b; + return; + } + last = b; + } +} + +/* +============ +idBrushList::Copy +============ +*/ +idBrushList *idBrushList::Copy( void ) const { + idBrush *brush; + idBrushList *list; + + list = new idBrushList; + + for ( brush = head; brush; brush = brush->next ) { + list->AddToTail( brush->Copy() ); + } + return list; +} + +/* +============ +idBrushList::Free +============ +*/ +void idBrushList::Free( void ) { + idBrush *brush, *next; + + for ( brush = head; brush; brush = next ) { + next = brush->next; + delete brush; + } + head = tail = NULL; + numBrushes = numBrushSides = 0; +} + +/* +============ +idBrushList::Split +============ +*/ +void idBrushList::Split( const idPlane &plane, int planeNum, idBrushList &frontList, idBrushList &backList, bool useBrushSavedPlaneSide ) { + idBrush *b, *front, *back; + + frontList.Clear(); + backList.Clear(); + + if ( !useBrushSavedPlaneSide ) { + for ( b = head; b; b = b->next ) { + b->Split( plane, planeNum, &front, &back ); + if ( front ) { + frontList.AddToTail( front ); + } + if ( back ) { + backList.AddToTail( back ); + } + } + return; + } + + for ( b = head; b; b = b->next ) { + if ( b->savedPlaneSide & BRUSH_PLANESIDE_BOTH ) { + b->Split( plane, planeNum, &front, &back ); + if ( front ) { + frontList.AddToTail( front ); + } + if ( back ) { + backList.AddToTail( back ); + } + } + else if ( b->savedPlaneSide & BRUSH_PLANESIDE_FRONT ) { + frontList.AddToTail( b->Copy() ); + } + else { + backList.AddToTail( b->Copy() ); + } + } +} + +/* +============ +idBrushList::Chop +============ +*/ +void idBrushList::Chop( bool (*ChopAllowed)( idBrush *b1, idBrush *b2 ) ) { + idBrush *b1, *b2, *next; + idBrushList sub1, sub2, keep; + int i, j, c1, c2; + idPlaneSet planeList; + +#ifdef OUTPUT_CHOP_STATS + common->Printf( "[Brush CSG]\n"); + common->Printf( "%6d original brushes\n", this->Num() ); +#endif + + CreatePlaneList( planeList ); + + for ( b1 = this->Head(); b1; b1 = this->Head() ) { + + for ( b2 = b1->next; b2; b2 = next ) { + + next = b2->next; + + for ( i = 0; i < 3; i++ ) { + if ( b1->bounds[0][i] >= b2->bounds[1][i] ) { + break; + } + if ( b1->bounds[1][i] <= b2->bounds[0][i] ) { + break; + } + } + if ( i < 3 ) { + continue; + } + + for ( i = 0; i < b1->GetNumSides(); i++ ) { + for ( j = 0; j < b2->GetNumSides(); j++ ) { + if ( b1->GetSide(i)->GetPlaneNum() == ( b2->GetSide(j)->GetPlaneNum() ^ 1 ) ) { + // opposite planes, so not touching + break; + } + } + if ( j < b2->GetNumSides() ) { + break; + } + } + if ( i < b1->GetNumSides() ) { + continue; + } + + sub1.Clear(); + sub2.Clear(); + + c1 = 999999; + c2 = 999999; + + // if b2 may chop up b1 + if ( !ChopAllowed || ChopAllowed( b2, b1 ) ) { + if ( !b1->Subtract( b2, sub1 ) ) { + // didn't really intersect + continue; + } + if ( sub1.IsEmpty() ) { + // b1 is swallowed by b2 + this->Delete( b1 ); + break; + } + c1 = sub1.Num(); + } + + // if b1 may chop up b2 + if ( !ChopAllowed || ChopAllowed( b1, b2 ) ) { + if ( !b2->Subtract( b1, sub2 ) ) { + // didn't really intersect + continue; + } + if ( sub2.IsEmpty() ) { + // b2 is swallowed by b1 + sub1.Free(); + this->Delete( b2 ); + continue; + } + c2 = sub2.Num(); + } + + if ( sub1.IsEmpty() && sub2.IsEmpty() ) { + continue; + } + + // don't allow too much fragmentation + if ( c1 > 2 && c2 > 2 ) { + sub1.Free(); + sub2.Free(); + continue; + } + + if ( c1 < c2 ) { + sub2.Free(); + this->AddToTail( sub1 ); + this->Delete( b1 ); + break; + } + else { + sub1.Free(); + this->AddToTail( sub2 ); + this->Delete( b2 ); + continue; + } + } + + if ( !b2 ) { + // b1 is no longer intersecting anything, so keep it + this->Remove( b1 ); + keep.AddToTail( b1 ); +#ifdef OUTPUT_CHOP_STATS + DisplayRealTimeString( "\r%6d", keep.numBrushes ); +#endif + } + } + + *this = keep; + +#ifdef OUTPUT_CHOP_STATS + common->Printf( "\r%6d output brushes\n", Num() ); +#endif +} + + +/* +============ +idBrushList::Merge +============ +*/ +void idBrushList::Merge( bool (*MergeAllowed)( idBrush *b1, idBrush *b2 ) ) { + idPlaneSet planeList; + idBrush *b1, *b2, *nextb2; + int numMerges; + + common->Printf( "[Brush Merge]\n"); + common->Printf( "%6d original brushes\n", Num() ); + + CreatePlaneList( planeList ); + + numMerges = 0; + for ( b1 = Head(); b1; b1 = b1->next ) { + + for ( b2 = Head(); b2; b2 = nextb2 ) { + nextb2 = b2->Next(); + + if ( b2 == b1 ) { + continue; + } + + if ( MergeAllowed && !MergeAllowed( b1, b2 ) ) { + continue; + } + + if ( b1->TryMerge( b2, planeList ) ) { + Delete( b2 ); + DisplayRealTimeString( "\r%6d", ++numMerges ); + nextb2 = Head(); + } + } + } + + common->Printf( "\r%6d brushes merged\n", numMerges ); +} + +/* +============ +idBrushList::SetFlagOnFacingBrushSides +============ +*/ +void idBrushList::SetFlagOnFacingBrushSides( const idPlane &plane, int flag ) { + int i; + idBrush *b; + const idWinding *w; + + for ( b = head; b; b = b->next ) { + if ( idMath::Fabs( b->GetBounds().PlaneDistance( plane ) ) > 0.1f ) { + continue; + } + for ( i = 0; i < b->GetNumSides(); i++ ) { + w = b->GetSide(i)->GetWinding(); + if ( !w ) { + if ( b->GetSide(i)->GetPlane().Compare( plane, BRUSH_PLANE_NORMAL_EPSILON, BRUSH_PLANE_DIST_EPSILON ) ) { + b->GetSide(i)->SetFlag( flag ); + } + continue; + } + if ( w->PlaneSide( plane ) == SIDE_ON ) { + b->GetSide(i)->SetFlag( flag ); + } + } + } +} + +/* +============ +idBrushList::CreatePlaneList +============ +*/ +void idBrushList::CreatePlaneList( idPlaneSet &planeList ) const { + int i; + idBrush *b; + idBrushSide *side; + + planeList.Resize( 512, 128 ); + for ( b = Head(); b; b = b->Next() ) { + for ( i = 0; i < b->GetNumSides(); i++ ) { + side = b->GetSide( i ); + side->SetPlaneNum( planeList.FindPlane( side->GetPlane(), BRUSH_PLANE_NORMAL_EPSILON, BRUSH_PLANE_DIST_EPSILON ) ); + } + } +} + +/* +============ +idBrushList::CreatePlaneList +============ +*/ +void idBrushList::WriteBrushMap( const idStr &fileName, const idStr &ext ) const { + idBrushMap *map; + + map = new idBrushMap( fileName, ext ); + map->WriteBrushList( *this ); + delete map; +} + + +//=============================================================== +// +// idBrushMap +// +//=============================================================== + +/* +============ +idBrushMap::idBrushMap +============ +*/ +idBrushMap::idBrushMap( const idStr &fileName, const idStr &ext ) { + idStr qpath; + + qpath = fileName; + qpath.StripFileExtension(); + qpath += ext; + qpath.SetFileExtension( "map" ); + + common->Printf( "writing %s...\n", qpath.c_str() ); + + fp = fileSystem->OpenFileWrite( qpath, "fs_devpath" ); + if ( !fp ) { + common->Error( "Couldn't open %s\n", qpath.c_str() ); + return; + } + + texture = "textures/washroom/btile01"; + + fp->WriteFloatString( "Version %1.2f\n", (float) CURRENT_MAP_VERSION ); + fp->WriteFloatString( "{\n" ); + fp->WriteFloatString( "\"classname\" \"worldspawn\"\n" ); + + brushCount = 0; +} + +/* +============ +idBrushMap::~idBrushMap +============ +*/ +idBrushMap::~idBrushMap( void ) { + if ( !fp ) { + return; + } + fp->WriteFloatString( "}\n" ); + fileSystem->CloseFile( fp ); +} + +/* +============ +idBrushMap::WriteBrush +============ +*/ +void idBrushMap::WriteBrush( const idBrush *brush ) { + int i; + idBrushSide *side; + + if ( !fp ) { + return; + } + + fp->WriteFloatString( "// primitive %d\n{\nbrushDef3\n{\n", brushCount++ ); + + for ( i = 0; i < brush->GetNumSides(); i++ ) { + side = brush->GetSide( i ); + fp->WriteFloatString( " ( %f %f %f %f ) ", side->GetPlane()[0], side->GetPlane()[1], side->GetPlane()[2], -side->GetPlane().Dist() ); + fp->WriteFloatString( "( ( 0.031250 0 0 ) ( 0 0.031250 0 ) ) %s 0 0 0\n", texture.c_str() ); + + } + fp->WriteFloatString( "}\n}\n" ); +} + +/* +============ +idBrushMap::WriteBrushList +============ +*/ +void idBrushMap::WriteBrushList( const idBrushList &brushList ) { + idBrush *b; + + if ( !fp ) { + return; + } + + for ( b = brushList.Head(); b; b = b->Next() ) { + WriteBrush( b ); + } +} diff --git a/tools/compilers/aas/Brush.h b/tools/compilers/aas/Brush.h new file mode 100644 index 000000000..7a5ce3de1 --- /dev/null +++ b/tools/compilers/aas/Brush.h @@ -0,0 +1,222 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BRUSH_H__ +#define __BRUSH_H__ + +/* +=============================================================================== + + Brushes + +=============================================================================== +*/ + + +#define BRUSH_PLANESIDE_FRONT 1 +#define BRUSH_PLANESIDE_BACK 2 +#define BRUSH_PLANESIDE_BOTH ( BRUSH_PLANESIDE_FRONT | BRUSH_PLANESIDE_BACK ) +#define BRUSH_PLANESIDE_FACING 4 + +class idBrush; +class idBrushList; + +void DisplayRealTimeString( char *string, ... ) id_attribute((format(printf,1,2))); + + +//=============================================================== +// +// idBrushSide +// +//=============================================================== + +#define SFL_SPLIT 0x0001 +#define SFL_BEVEL 0x0002 +#define SFL_USED_SPLITTER 0x0004 +#define SFL_TESTED_SPLITTER 0x0008 + +class idBrushSide { + + friend class idBrush; + +public: + idBrushSide( void ); + idBrushSide( const idPlane &plane, int planeNum ); + ~idBrushSide( void ); + + int GetFlags( void ) const { return flags; } + void SetFlag( int flag ) { flags |= flag; } + void RemoveFlag( int flag ) { flags &= ~flag; } + const idPlane & GetPlane( void ) const { return plane; } + void SetPlaneNum( int num ) { planeNum = num; } + int GetPlaneNum( void ) { return planeNum; } + const idWinding * GetWinding( void ) const { return winding; } + idBrushSide * Copy( void ) const; + int Split( const idPlane &splitPlane, idBrushSide **front, idBrushSide **back ) const; + +private: + int flags; + int planeNum; + idPlane plane; + idWinding * winding; +}; + + +//=============================================================== +// +// idBrush +// +//=============================================================== + +#define BFL_NO_VALID_SPLITTERS 0x0001 + +class idBrush { + + friend class idBrushList; + +public: + idBrush( void ); + ~idBrush( void ); + + int GetFlags( void ) const { return flags; } + void SetFlag( int flag ) { flags |= flag; } + void RemoveFlag( int flag ) { flags &= ~flag; } + void SetEntityNum( int num ) { entityNum = num; } + void SetPrimitiveNum( int num ) { primitiveNum = num; } + void SetContents( int contents ) { this->contents = contents; } + int GetContents( void ) const { return contents; } + const idBounds & GetBounds( void ) const { return bounds; } + float GetVolume( void ) const; + int GetNumSides( void ) const { return sides.Num(); } + idBrushSide * GetSide( int i ) const { return sides[i]; } + void SetPlaneSide( int s ) { planeSide = s; } + void SavePlaneSide( void ) { savedPlaneSide = planeSide; } + int GetSavedPlaneSide( void ) const { return savedPlaneSide; } + bool FromSides( idList &sideList ); + bool FromWinding( const idWinding &w, const idPlane &windingPlane ); + bool FromBounds( const idBounds &bounds ); + void Transform( const idVec3 &origin, const idMat3 &axis ); + idBrush * Copy( void ) const; + bool TryMerge( const idBrush *brush, const idPlaneSet &planeList ); + // returns true if the brushes did intersect + bool Subtract( const idBrush *b, idBrushList &list ) const; + // split the brush into a front and back brush + int Split( const idPlane &plane, int planeNum, idBrush **front, idBrush **back ) const; + // expand the brush for an axial bounding box + void ExpandForAxialBox( const idBounds &bounds ); + // next brush in list + idBrush * Next( void ) const { return next; } + +private: + mutable idBrush * next; // next brush in list + int entityNum; // entity number in editor + int primitiveNum; // primitive number in editor + int flags; // brush flags + bool windingsValid; // set when side windings are valid + int contents; // contents of brush + int planeSide; // side of a plane this brush is on + int savedPlaneSide; // saved plane side + idBounds bounds; // brush bounds + idList sides; // list with sides + +private: + bool CreateWindings( void ); + void BoundBrush( const idBrush *original = NULL ); + void AddBevelsForAxialBox( void ); + bool RemoveSidesWithoutWinding( void ); +}; + + +//=============================================================== +// +// idBrushList +// +//=============================================================== + +class idBrushList { +public: + idBrushList( void ); + ~idBrushList( void ); + + int Num( void ) const { return numBrushes; } + int NumSides( void ) const { return numBrushSides; } + idBrush * Head( void ) const { return head; } + idBrush * Tail( void ) const { return tail; } + void Clear( void ) { head = tail = NULL; numBrushes = 0; } + bool IsEmpty( void ) const { return (numBrushes == 0); } + idBounds GetBounds( void ) const; + // add brush to the tail of the list + void AddToTail( idBrush *brush ); + // add list to the tail of the list + void AddToTail( idBrushList &list ); + // add brush to the front of the list + void AddToFront( idBrush *brush ); + // add list to the front of the list + void AddToFront( idBrushList &list ); + // remove the brush from the list + void Remove( idBrush *brush ); + // remove the brush from the list and delete the brush + void Delete( idBrush *brush); + // returns a copy of the brush list + idBrushList * Copy( void ) const; + // delete all brushes in the list + void Free( void ); + // split the brushes in the list into two lists + void Split( const idPlane &plane, int planeNum, idBrushList &frontList, idBrushList &backList, bool useBrushSavedPlaneSide = false ); + // chop away all brush overlap + void Chop( bool (*ChopAllowed)( idBrush *b1, idBrush *b2 ) ); + // merge brushes + void Merge( bool (*MergeAllowed)( idBrush *b1, idBrush *b2 ) ); + // set the given flag on all brush sides facing the plane + void SetFlagOnFacingBrushSides( const idPlane &plane, int flag ); + // get a list with planes for all brushes in the list + void CreatePlaneList( idPlaneSet &planeList ) const; + // write a brush map with the brushes in the list + void WriteBrushMap( const idStr &fileName, const idStr &ext ) const; + +private: + idBrush * head; + idBrush * tail; + int numBrushes; + int numBrushSides; +}; + + +//=============================================================== +// +// idBrushMap +// +//=============================================================== + +class idBrushMap { + +public: + idBrushMap( const idStr &fileName, const idStr &ext ); + ~idBrushMap( void ); + void SetTexture( const idStr &textureName ) { texture = textureName; } + void WriteBrush( const idBrush *brush ); + void WriteBrushList( const idBrushList &brushList ); + +private: + idFile * fp; + idStr texture; + int brushCount; +}; + +#endif /* !__BRUSH_H__ */ diff --git a/tools/compilers/aas/BrushBSP.cpp b/tools/compilers/aas/BrushBSP.cpp new file mode 100644 index 000000000..6784882ee --- /dev/null +++ b/tools/compilers/aas/BrushBSP.cpp @@ -0,0 +1,2142 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "Brush.h" +#include "BrushBSP.h" + + +#define BSP_GRID_SIZE 512.0f +#define SPLITTER_EPSILON 0.1f +#define VERTEX_MELT_EPSILON 0.1f +#define VERTEX_MELT_HASH_SIZE 32 + +#define PORTAL_PLANE_NORMAL_EPSILON 0.00001f +#define PORTAL_PLANE_DIST_EPSILON 0.01f + +//#define OUPUT_BSP_STATS_PER_GRID_CELL + + +//=============================================================== +// +// idBrushBSPPortal +// +//=============================================================== + +/* +============ +idBrushBSPPortal::idBrushBSPPortal +============ +*/ +idBrushBSPPortal::idBrushBSPPortal( void ) { + planeNum = -1; + winding = NULL; + nodes[0] = nodes[1] = NULL; + next[0] = next[1] = NULL; + faceNum = 0; + flags = 0; +} + +/* +============ +idBrushBSPPortal::~idBrushBSPPortal +============ +*/ +idBrushBSPPortal::~idBrushBSPPortal( void ) { + if ( winding ) { + delete winding; + } +} + +/* +============ +idBrushBSPPortal::AddToNodes +============ +*/ +void idBrushBSPPortal::AddToNodes( idBrushBSPNode *front, idBrushBSPNode *back ) { + if ( nodes[0] || nodes[1] ) { + common->Error( "AddToNode: allready included" ); + } + + assert( front && back ); + + nodes[0] = front; + next[0] = front->portals; + front->portals = this; + + nodes[1] = back; + next[1] = back->portals; + back->portals = this; +} + +/* +============ +idBrushBSPPortal::RemoveFromNode +============ +*/ +void idBrushBSPPortal::RemoveFromNode( idBrushBSPNode *l ) { + idBrushBSPPortal **pp, *t; + + // remove reference to the current portal + pp = &l->portals; + while (1) + { + t = *pp; + if ( !t ) { + common->Error( "idBrushBSPPortal::RemoveFromNode: portal not in node" ); + } + + if ( t == this ) { + break; + } + + if ( t->nodes[0] == l ) { + pp = &t->next[0]; + } + else if ( t->nodes[1] == l ) { + pp = &t->next[1]; + } + else { + common->Error( "idBrushBSPPortal::RemoveFromNode: portal not bounding node" ); + } + } + + if ( nodes[0] == l ) { + *pp = next[0]; + nodes[0] = NULL; + } + else if ( nodes[1] == l ) { + *pp = next[1]; + nodes[1] = NULL; + } + else { + common->Error( "idBrushBSPPortal::RemoveFromNode: mislinked portal" ); + } +} + +/* +============ +idBrushBSPPortal::Flip +============ +*/ +void idBrushBSPPortal::Flip( void ) { + idBrushBSPNode *frontNode, *backNode; + + frontNode = nodes[0]; + backNode = nodes[1]; + + if ( frontNode ) { + RemoveFromNode( frontNode ); + } + if ( backNode ) { + RemoveFromNode( backNode ); + } + AddToNodes( frontNode, backNode ); + + plane = -plane; + planeNum ^= 1; + winding->ReverseSelf(); +} + +/* +============ +idBrushBSPPortal::Split +============ +*/ +int idBrushBSPPortal::Split( const idPlane &splitPlane, idBrushBSPPortal **front, idBrushBSPPortal **back ) { + idWinding *frontWinding, *backWinding; + + (*front) = (*back) = NULL; + winding->Split( splitPlane, 0.1f, &frontWinding, &backWinding ); + if ( frontWinding ) { + (*front) = new idBrushBSPPortal(); + (*front)->plane = plane; + (*front)->planeNum = planeNum; + (*front)->flags = flags; + (*front)->winding = frontWinding; + } + if ( backWinding ) { + (*back) = new idBrushBSPPortal(); + (*back)->plane = plane; + (*back)->planeNum = planeNum; + (*back)->flags = flags; + (*back)->winding = backWinding; + } + + if ( frontWinding && backWinding ) { + return PLANESIDE_CROSS; + } + else if ( frontWinding ) { + return PLANESIDE_FRONT; + } + else { + return PLANESIDE_BACK; + } +} + + +//=============================================================== +// +// idBrushBSPNode +// +//=============================================================== + +/* +============ +idBrushBSPNode::idBrushBSPNode +============ +*/ +idBrushBSPNode::idBrushBSPNode( void ) { + brushList.Clear(); + contents = 0; + flags = 0; + volume = NULL; + portals = NULL; + children[0] = children[1] = NULL; + areaNum = 0; + occupied = 0; +} + +/* +============ +idBrushBSPNode::~idBrushBSPNode +============ +*/ +idBrushBSPNode::~idBrushBSPNode( void ) { + idBrushBSPPortal *p; + + // delete brushes + brushList.Free(); + + // delete volume brush + if ( volume ) { + delete volume; + } + + // delete portals + for ( p = portals; p; p = portals ) { + p->RemoveFromNode( this ); + if ( !p->nodes[0] && !p->nodes[1] ) { + delete p; + } + } +} + +/* +============ +idBrushBSPNode::SetContentsFromBrushes +============ +*/ +void idBrushBSPNode::SetContentsFromBrushes( void ) { + idBrush *brush; + + contents = 0; + for ( brush = brushList.Head(); brush; brush = brush->Next() ) { + contents |= brush->GetContents(); + } +} + +/* +============ +idBrushBSPNode::GetPortalBounds +============ +*/ +idBounds idBrushBSPNode::GetPortalBounds( void ) { + int s, i; + idBrushBSPPortal *p; + idBounds bounds; + + bounds.Clear(); + for ( p = portals; p; p = p->next[s] ) { + s = (p->nodes[1] == this); + + for ( i = 0; i < p->winding->GetNumPoints(); i++ ) { + bounds.AddPoint( (*p->winding)[i].ToVec3() ); + } + } + return bounds; +} + +/* +============ +idBrushBSPNode::TestLeafNode +============ +*/ +bool idBrushBSPNode::TestLeafNode( void ) { + int s, n; + float d; + idBrushBSPPortal *p; + idVec3 center; + idPlane plane; + + n = 0; + center = vec3_origin; + for ( p = portals; p; p = p->next[s] ) { + s = (p->nodes[1] == this); + center += p->winding->GetCenter(); + n++; + } + + center /= n; + + for ( p = portals; p; p = p->next[s] ) { + s = (p->nodes[1] == this); + if ( s ) { + plane = -p->GetPlane(); + } + else { + plane = p->GetPlane(); + } + d = plane.Distance( center ); + if ( d < 0.0f ) { + return false; + } + } + return true; +} + +/* +============ +idBrushBSPNode::Split +============ +*/ +bool idBrushBSPNode::Split( const idPlane &splitPlane, int splitPlaneNum ) { + int s, i; + idWinding *mid; + idBrushBSPPortal *p, *midPortal, *newPortals[2]; + idBrushBSPNode *newNodes[2]; + + mid = new idWinding( splitPlane.Normal(), splitPlane.Dist() ); + + for ( p = portals; p && mid; p = p->next[s] ) { + s = (p->nodes[1] == this); + if ( s ) { + mid = mid->Clip( -p->plane, 0.1f, false ); + } + else { + mid = mid->Clip( p->plane, 0.1f, false ); + } + } + + if ( !mid ) { + return false; + } + + // allocate two new nodes + for ( i = 0; i < 2; i++ ) { + newNodes[i] = new idBrushBSPNode(); + newNodes[i]->flags = flags; + newNodes[i]->contents = contents; + newNodes[i]->parent = this; + } + + // split all portals of the node + for ( p = portals; p; p = portals ) { + s = (p->nodes[1] == this); + p->Split( splitPlane, &newPortals[0], &newPortals[1] ); + for ( i = 0; i < 2; i++ ) { + if ( newPortals[i] ) { + if ( s ) { + newPortals[i]->AddToNodes( p->nodes[0], newNodes[i] ); + } + else { + newPortals[i]->AddToNodes( newNodes[i], p->nodes[1] ); + } + } + } + p->RemoveFromNode( p->nodes[0] ); + p->RemoveFromNode( p->nodes[1] ); + delete p; + } + + // add seperating portal + midPortal = new idBrushBSPPortal(); + midPortal->plane = splitPlane; + midPortal->planeNum = splitPlaneNum; + midPortal->winding = mid; + midPortal->AddToNodes( newNodes[0], newNodes[1] ); + + // set new child nodes + children[0] = newNodes[0]; + children[1] = newNodes[1]; + plane = splitPlane; + + return true; +} + +/* +============ +idBrushBSPNode::PlaneSide +============ +*/ +int idBrushBSPNode::PlaneSide( const idPlane &plane, float epsilon ) const { + int s, side; + idBrushBSPPortal *p; + bool front, back; + + front = back = false; + for ( p = portals; p; p = p->next[s] ) { + s = (p->nodes[1] == this); + + side = p->winding->PlaneSide( plane, epsilon ); + if ( side == SIDE_CROSS || side == SIDE_ON) { + return side; + } + if ( side == SIDE_FRONT ) { + if ( back ) { + return SIDE_CROSS; + } + front = true; + } + if ( side == SIDE_BACK ) { + if ( front ) { + return SIDE_CROSS; + } + back = true; + } + } + + if ( front ) { + return SIDE_FRONT; + } + return SIDE_BACK; +} + +/* +============ +idBrushBSPNode::RemoveFlagFlood +============ +*/ +void idBrushBSPNode::RemoveFlagFlood( int flag ) { + int s; + idBrushBSPPortal *p; + + RemoveFlag( flag ); + + for ( p = GetPortals(); p; p = p->Next(s) ) { + s = (p->GetNode(1) == this); + + if ( !(p->GetNode( !s )->GetFlags() & flag ) ) { + continue; + } + + p->GetNode( !s )->RemoveFlagFlood( flag ); + } +} + +/* +============ +idBrushBSPNode::RemoveFlagRecurse +============ +*/ +void idBrushBSPNode::RemoveFlagRecurse( int flag ) { + RemoveFlag( flag ); + if ( children[0] ) { + children[0]->RemoveFlagRecurse( flag ); + } + if ( children[1] ) { + children[1]->RemoveFlagRecurse( flag ); + } +} + +/* +============ +idBrushBSPNode::RemoveFlagRecurseFlood +============ +*/ +void idBrushBSPNode::RemoveFlagRecurseFlood( int flag ) { + RemoveFlag( flag ); + if ( !children[0] && !children[1] ) { + RemoveFlagFlood( flag ); + } + else { + if ( children[0] ) { + children[0]->RemoveFlagRecurseFlood( flag ); + } + if ( children[1] ) { + children[1]->RemoveFlagRecurseFlood( flag ); + } + } +} + + +//=============================================================== +// +// idBrushBSP +// +//=============================================================== + +/* +============ +idBrushBSP::idBrushBSP +============ +*/ +idBrushBSP::idBrushBSP( void ) { + root = outside = NULL; + numSplits = numPrunedSplits = 0; + brushMapContents = 0; + brushMap = NULL; +} + +/* +============ +idBrushBSP::~idBrushBSP +============ +*/ +idBrushBSP::~idBrushBSP( void ) { + + RemoveMultipleLeafNodeReferences_r( root ); + Free_r( root ); + + if ( outside ) { + delete outside; + } +} + +/* +============ +idBrushBSP::RemoveMultipleLeafNodeReferences_r +============ +*/ +void idBrushBSP::RemoveMultipleLeafNodeReferences_r( idBrushBSPNode *node ) { + if ( !node ) { + return; + } + + if ( node->children[0] ) { + if ( node->children[0]->parent != node ) { + node->children[0] = NULL; + } + else { + RemoveMultipleLeafNodeReferences_r( node->children[0] ); + } + } + if ( node->children[1] ) { + if ( node->children[1]->parent != node ) { + node->children[1] = NULL; + } + else { + RemoveMultipleLeafNodeReferences_r( node->children[1] ); + } + } +} + +/* +============ +idBrushBSP::Free_r +============ +*/ +void idBrushBSP::Free_r( idBrushBSPNode *node ) { + if ( !node ) { + return; + } + + Free_r( node->children[0] ); + Free_r( node->children[1] ); + + delete node; +} + +/* +============ +idBrushBSP::IsValidSplitter +============ +*/ +ID_INLINE bool idBrushBSP::IsValidSplitter( const idBrushSide *side ) { + return !( side->GetFlags() & ( SFL_SPLIT | SFL_USED_SPLITTER ) ); +} + +/* +============ +idBrushBSP::BrushSplitterStats +============ +*/ +typedef struct splitterStats_s { + int numFront; // number of brushes at the front of the splitter + int numBack; // number of brushes at the back of the splitter + int numSplits; // number of brush sides split by the splitter + int numFacing; // number of brushes facing this splitter + int epsilonBrushes; // number of tiny brushes this splitter would create +} splitterStats_t; + +int idBrushBSP::BrushSplitterStats( const idBrush *brush, int planeNum, const idPlaneSet &planeList, bool *testedPlanes, struct splitterStats_s &stats ) { + int i, j, num, s, lastNumSplits; + const idPlane *plane; + const idWinding *w; + float d, d_front, d_back, brush_front, brush_back; + + plane = &planeList[planeNum]; + + // get the plane side for the brush bounds + s = brush->GetBounds().PlaneSide( *plane, SPLITTER_EPSILON ); + if ( s == PLANESIDE_FRONT ) { + stats.numFront++; + return BRUSH_PLANESIDE_FRONT; + } + if ( s == PLANESIDE_BACK ) { + stats.numBack++; + return BRUSH_PLANESIDE_BACK; + } + + // if the brush actually uses the planenum, we can tell the side for sure + for ( i = 0; i < brush->GetNumSides(); i++ ) { + num = brush->GetSide( i )->GetPlaneNum(); + + if ( !(( num ^ planeNum ) >> 1) ) { + if ( num == planeNum ) { + stats.numBack++; + stats.numFacing++; + return ( BRUSH_PLANESIDE_BACK | BRUSH_PLANESIDE_FACING ); + } + if ( num == ( planeNum ^ 1 ) ) { + stats.numFront++; + stats.numFacing++; + return ( BRUSH_PLANESIDE_FRONT | BRUSH_PLANESIDE_FACING ); + } + } + } + + lastNumSplits = stats.numSplits; + brush_front = brush_back = 0.0f; + for ( i = 0; i < brush->GetNumSides(); i++ ) { + + if ( !IsValidSplitter( brush->GetSide( i ) ) ) { + continue; + } + + j = brush->GetSide( i )->GetPlaneNum(); + if ( testedPlanes[j] || testedPlanes[j^1] ) { + continue; + } + + w = brush->GetSide(i)->GetWinding(); + if ( !w ) { + continue; + } + d_front = d_back = 0.0f; + for ( j = 0; j < w->GetNumPoints(); j++ ) { + d = plane->Distance( (*w)[j].ToVec3() ); + if ( d > d_front ) { + d_front = d; + } + else if ( d < d_back ) { + d_back = d; + } + } + if ( d_front > SPLITTER_EPSILON && d_back < -SPLITTER_EPSILON ) { + stats.numSplits++; + } + if ( d_front > brush_front ) { + brush_front = d_front; + } + else if ( d_back < brush_back ) { + brush_back = d_back; + } + } + + // if brush sides are split and the brush only pokes one unit through the plane + if ( stats.numSplits > lastNumSplits && (brush_front < 1.0f || brush_back > -1.0f) ) { + stats.epsilonBrushes++; + } + + return BRUSH_PLANESIDE_BOTH; +} + +/* +============ +idBrushBSP::FindSplitter +============ +*/ +int idBrushBSP::FindSplitter( idBrushBSPNode *node, const idPlaneSet &planeList, bool *testedPlanes, struct splitterStats_s &bestStats ) { + int i, planeNum, bestSplitter, value, bestValue, f, numBrushSides; + idBrush *brush, *b; + splitterStats_t stats; + + memset( testedPlanes, 0, planeList.Num() * sizeof( bool ) ); + + bestSplitter = -1; + bestValue = -99999999; + for ( brush = node->brushList.Head(); brush; brush = brush->Next() ) { + + if ( brush->GetFlags() & BFL_NO_VALID_SPLITTERS ) { + continue; + } + + for ( i = 0; i < brush->GetNumSides(); i++ ) { + + if ( !IsValidSplitter( brush->GetSide(i) ) ) { + continue; + } + + planeNum = brush->GetSide(i)->GetPlaneNum(); + + if ( testedPlanes[planeNum] || testedPlanes[planeNum^1] ) { + continue; + } + + testedPlanes[planeNum] = testedPlanes[planeNum^1] = true; + + if ( node->volume->Split( planeList[planeNum], planeNum, NULL, NULL ) != PLANESIDE_CROSS ) { + continue; + } + + memset( &stats, 0, sizeof( stats ) ); + + f = 15 + 5 * (brush->GetSide(i)->GetPlane().Type() < PLANETYPE_TRUEAXIAL); + numBrushSides = node->brushList.NumSides(); + + for ( b = node->brushList.Head(); b; b = b->Next() ) { + + // if the brush has no valid splitters left + if ( b->GetFlags() & BFL_NO_VALID_SPLITTERS ) { + b->SetPlaneSide( BRUSH_PLANESIDE_BOTH ); + } + else { + b->SetPlaneSide( BrushSplitterStats( b, planeNum, planeList, testedPlanes, stats ) ); + } + + numBrushSides -= b->GetNumSides(); + // best value we can get using this plane as a splitter + value = f * (stats.numFacing + numBrushSides) - 10 * stats.numSplits - stats.epsilonBrushes * 1000; + // if the best value for this plane can't get any better than the best value we have + if ( value < bestValue ) { + break; + } + } + + if ( b ) { + continue; + } + + value = f * stats.numFacing - 10 * stats.numSplits - abs(stats.numFront - stats.numBack) - stats.epsilonBrushes * 1000; + + if ( value > bestValue ) { + bestValue = value; + bestSplitter = planeNum; + bestStats = stats; + + for ( b = node->brushList.Head(); b; b = b->Next() ) { + b->SavePlaneSide(); + } + } + } + } + + return bestSplitter; +} + +/* +============ +idBrushBSP::SetSplitterUsed +============ +*/ +void idBrushBSP::SetSplitterUsed( idBrushBSPNode *node, int planeNum ) { + int i, numValidBrushSplitters; + idBrush *brush; + + for ( brush = node->brushList.Head(); brush; brush = brush->Next() ) { + if ( !( brush->GetSavedPlaneSide() & BRUSH_PLANESIDE_FACING ) ) { + continue; + } + numValidBrushSplitters = 0; + for ( i = 0; i < brush->GetNumSides(); i++ ) { + + if ( !(( brush->GetSide(i)->GetPlaneNum() ^ planeNum ) >> 1) ) { + brush->GetSide(i)->SetFlag( SFL_USED_SPLITTER ); + } + else if ( IsValidSplitter( brush->GetSide(i) ) ) { + numValidBrushSplitters++; + } + } + if ( numValidBrushSplitters == 0 ) { + brush->SetFlag( BFL_NO_VALID_SPLITTERS ); + } + } +} + +/* +============ +idBrushBSP::BuildBrushBSP_r +============ +*/ +idBrushBSPNode *idBrushBSP::BuildBrushBSP_r( idBrushBSPNode *node, const idPlaneSet &planeList, bool *testedPlanes, int skipContents ) { + int planeNum; + splitterStats_t bestStats; + + planeNum = FindSplitter( node, planeList, testedPlanes, bestStats ); + + // if no split plane found this is a leaf node + if ( planeNum == -1 ) { + + node->SetContentsFromBrushes(); + + if ( brushMap && ( node->contents & brushMapContents ) ) { + brushMap->WriteBrush( node->volume ); + } + + // free node memory + node->brushList.Free(); + delete node->volume; + node->volume = NULL; + + node->children[0] = node->children[1] = NULL; + return node; + } + + numSplits++; + numGridCellSplits++; + + // mark all brush sides on the split plane as used + SetSplitterUsed( node, planeNum ); + + // set node split plane + node->plane = planeList[planeNum]; + + // allocate children + node->children[0] = new idBrushBSPNode(); + node->children[1] = new idBrushBSPNode(); + + // split node volume and brush list for children + node->volume->Split( node->plane, -1, &node->children[0]->volume, &node->children[1]->volume ); + node->brushList.Split( node->plane, -1, node->children[0]->brushList, node->children[1]->brushList, true ); + node->children[0]->parent = node->children[1]->parent = node; + + // free node memory + node->brushList.Free(); + delete node->volume; + node->volume = NULL; + + // process children + node->children[0] = BuildBrushBSP_r( node->children[0], planeList, testedPlanes, skipContents ); + node->children[1] = BuildBrushBSP_r( node->children[1], planeList, testedPlanes, skipContents ); + + // if both children contain the skip contents + if ( node->children[0]->contents & node->children[1]->contents & skipContents ) { + node->contents = node->children[0]->contents | node->children[1]->contents; + delete node->children[0]; + delete node->children[1]; + node->children[0] = node->children[1] = NULL; + numSplits--; + numGridCellSplits--; + } + + return node; +} + +/* +============ +idBrushBSP::ProcessGridCell +============ +*/ +idBrushBSPNode *idBrushBSP::ProcessGridCell( idBrushBSPNode *node, int skipContents ) { + idPlaneSet planeList; + bool *testedPlanes; + +#ifdef OUPUT_BSP_STATS_PER_GRID_CELL + common->Printf( "[Grid Cell %d]\n", ++numGridCells ); + common->Printf( "%6d brushes\n", node->brushList.Num() ); +#endif + + numGridCellSplits = 0; + + // chop away all brush overlap + node->brushList.Chop( BrushChopAllowed ); + + // merge brushes if possible + //node->brushList.Merge( BrushMergeAllowed ); + + // create a list with planes for this grid cell + node->brushList.CreatePlaneList( planeList ); + +#ifdef OUPUT_BSP_STATS_PER_GRID_CELL + common->Printf( "[Grid Cell BSP]\n" ); +#endif + + testedPlanes = new bool[planeList.Num()]; + + BuildBrushBSP_r( node, planeList, testedPlanes, skipContents ); + + delete testedPlanes; + +#ifdef OUPUT_BSP_STATS_PER_GRID_CELL + common->Printf( "\r%6d splits\n", numGridCellSplits ); +#endif + + return node; +} + +/* +============ +idBrushBSP::BuildGrid_r +============ +*/ +void idBrushBSP::BuildGrid_r( idList &gridCells, idBrushBSPNode *node ) { + int axis; + float dist; + idBounds bounds; + idVec3 normal, halfSize; + + if ( !node->brushList.Num() ) { + delete node->volume; + node->volume = NULL; + node->children[0] = node->children[1] = NULL; + return; + } + + bounds = node->volume->GetBounds(); + halfSize = (bounds[1] - bounds[0]) * 0.5f; + for ( axis = 0; axis < 3; axis++ ) { + if ( halfSize[axis] > BSP_GRID_SIZE ) { + dist = BSP_GRID_SIZE * ( floor( (bounds[0][axis] + halfSize[axis]) / BSP_GRID_SIZE ) + 1 ); + } + else { + dist = BSP_GRID_SIZE * ( floor( bounds[0][axis] / BSP_GRID_SIZE ) + 1 ); + } + if ( dist > bounds[0][axis] + 1.0f && dist < bounds[1][axis] - 1.0f ) { + break; + } + } + if ( axis >= 3 ) { + gridCells.Append( node ); + return; + } + + numSplits++; + + normal = vec3_origin; + normal[axis] = 1.0f; + node->plane.SetNormal( normal ); + node->plane.SetDist( (int) dist ); + + // allocate children + node->children[0] = new idBrushBSPNode(); + node->children[1] = new idBrushBSPNode(); + + // split volume and brush list for children + node->volume->Split( node->plane, -1, &node->children[0]->volume, &node->children[1]->volume ); + node->brushList.Split( node->plane, -1, node->children[0]->brushList, node->children[1]->brushList ); + node->children[0]->brushList.SetFlagOnFacingBrushSides( node->plane, SFL_USED_SPLITTER ); + node->children[1]->brushList.SetFlagOnFacingBrushSides( node->plane, SFL_USED_SPLITTER ); + node->children[0]->parent = node->children[1]->parent = node; + + // free node memory + node->brushList.Free(); + delete node->volume; + node->volume = NULL; + + // process children + BuildGrid_r( gridCells, node->children[0] ); + BuildGrid_r( gridCells, node->children[1] ); +} + +/* +============ +idBrushBSP::Build +============ +*/ +void idBrushBSP::Build( idBrushList brushList, int skipContents, + bool (*ChopAllowed)( idBrush *b1, idBrush *b2 ), + bool (*MergeAllowed)( idBrush *b1, idBrush *b2 ) ) { + + int i; + idList gridCells; + + common->Printf( "[Brush BSP]\n" ); + common->Printf( "%6d brushes\n", brushList.Num() ); + + BrushChopAllowed = ChopAllowed; + BrushMergeAllowed = MergeAllowed; + + numGridCells = 0; + treeBounds = brushList.GetBounds(); + root = new idBrushBSPNode(); + root->brushList = brushList; + root->volume = new idBrush(); + root->volume->FromBounds( treeBounds ); + root->parent = NULL; + + BuildGrid_r( gridCells, root ); + + common->Printf( "\r%6d grid cells\n", gridCells.Num() ); + +#ifdef OUPUT_BSP_STATS_PER_GRID_CELL + for ( i = 0; i < gridCells.Num(); i++ ) { + ProcessGridCell( gridCells[i], skipContents ); + } +#else + common->Printf( "\r%6d %%", 0 ); + for ( i = 0; i < gridCells.Num(); i++ ) { + DisplayRealTimeString( "\r%6d", i * 100 / gridCells.Num() ); + ProcessGridCell( gridCells[i], skipContents ); + } + common->Printf( "\r%6d %%\n", 100 ); +#endif + + common->Printf( "\r%6d splits\n", numSplits ); + + if ( brushMap ) { + delete brushMap; + } +} + +/* +============ +idBrushBSP::WriteBrushMap +============ +*/ +void idBrushBSP::WriteBrushMap( const idStr &fileName, const idStr &ext, int contents ) { + brushMap = new idBrushMap( fileName, ext ); + brushMapContents = contents; +} + +/* +============ +idBrushBSP::PruneTree_r +============ +*/ +void idBrushBSP::PruneTree_r( idBrushBSPNode *node, int contents ) { + int i, s; + idBrushBSPNode *nodes[2]; + idBrushBSPPortal *p, *nextp; + + if ( !node->children[0] || !node->children[1] ) { + return; + } + + PruneTree_r( node->children[0], contents ); + PruneTree_r( node->children[1], contents ); + + if ( ( node->children[0]->contents & node->children[1]->contents & contents ) ) { + + node->contents = node->children[0]->contents | node->children[1]->contents; + // move all child portals to parent + for ( i = 0; i < 2; i++ ) { + for ( p = node->children[i]->portals; p; p = nextp ) { + s = ( p->nodes[1] == node->children[i] ); + nextp = p->next[s]; + nodes[s] = node; + nodes[!s] = p->nodes[!s]; + p->RemoveFromNode( p->nodes[0] ); + p->RemoveFromNode( p->nodes[1] ); + if ( nodes[!s] == node->children[!i] ) { + delete p; // portal seperates both children + } + else { + p->AddToNodes( nodes[0], nodes[1] ); + } + } + } + + delete node->children[0]; + delete node->children[1]; + node->children[0] = NULL; + node->children[1] = NULL; + + numPrunedSplits++; + } +} + +/* +============ +idBrushBSP::PruneTree +============ +*/ +void idBrushBSP::PruneTree( int contents ) { + numPrunedSplits = 0; + common->Printf( "[Prune BSP]\n" ); + PruneTree_r( root, contents ); + common->Printf( "%6d splits pruned\n", numPrunedSplits ); +} + +/* +============ +idBrushBSP::BaseWindingForNode +============ +*/ +#define BASE_WINDING_EPSILON 0.001f + +idWinding *idBrushBSP::BaseWindingForNode( idBrushBSPNode *node ) { + idWinding *w; + idBrushBSPNode *n; + + w = new idWinding( node->plane.Normal(), node->plane.Dist() ); + + // clip by all the parents + for ( n = node->parent; n && w; n = n->parent ) { + + if ( n->children[0] == node ) { + // take front + w = w->Clip( n->plane, BASE_WINDING_EPSILON ); + } + else { + // take back + w = w->Clip( -n->plane, BASE_WINDING_EPSILON ); + } + node = n; + } + + return w; +} + +/* +============ +idBrushBSP::MakeNodePortal + + create the new portal by taking the full plane winding for the cutting + plane and clipping it by all of parents of this node +============ +*/ +void idBrushBSP::MakeNodePortal( idBrushBSPNode *node ) { + idBrushBSPPortal *newPortal, *p; + idWinding *w; + int side; + + w = BaseWindingForNode( node ); + + // clip the portal by all the other portals in the node + for ( p = node->portals; p && w; p = p->next[side] ) { + if ( p->nodes[0] == node ) { + side = 0; + w = w->Clip( p->plane, 0.1f ); + } + else if ( p->nodes[1] == node ) { + side = 1; + w = w->Clip( -p->plane, 0.1f ); + } + else { + common->Error( "MakeNodePortal: mislinked portal" ); + } + } + + if ( !w ) { + return; + } + + if ( w->IsTiny() ) { + delete w; + return; + } + + newPortal = new idBrushBSPPortal(); + newPortal->plane = node->plane; + newPortal->winding = w; + newPortal->AddToNodes( node->children[0], node->children[1] ); +} + +/* +============ +idBrushBSP::SplitNodePortals + + Move or split the portals that bound the node so that the node's children have portals instead of node. +============ +*/ +#define SPLIT_WINDING_EPSILON 0.001f + +void idBrushBSP::SplitNodePortals( idBrushBSPNode *node ) { + int side; + idBrushBSPPortal *p, *nextPortal, *newPortal; + idBrushBSPNode *f, *b, *otherNode; + idPlane *plane; + idWinding *frontWinding, *backWinding; + + plane = &node->plane; + f = node->children[0]; + b = node->children[1]; + + for ( p = node->portals; p; p = nextPortal ) { + if (p->nodes[0] == node) { + side = 0; + } + else if (p->nodes[1] == node) { + side = 1; + } + else { + common->Error( "idBrushBSP::SplitNodePortals: mislinked portal" ); + } + nextPortal = p->next[side]; + + otherNode = p->nodes[!side]; + p->RemoveFromNode( p->nodes[0] ); + p->RemoveFromNode( p->nodes[1] ); + + // cut the portal into two portals, one on each side of the cut plane + p->winding->Split( *plane, SPLIT_WINDING_EPSILON, &frontWinding, &backWinding ); + + if ( frontWinding && frontWinding->IsTiny() ) { + delete frontWinding; + frontWinding = NULL; + //tinyportals++; + } + + if ( backWinding && backWinding->IsTiny() ) { + delete backWinding; + backWinding = NULL; + //tinyportals++; + } + + if ( !frontWinding && !backWinding ) { + // tiny windings on both sides + continue; + } + + if ( !frontWinding ) { + delete backWinding; + if ( side == 0 ) { + p->AddToNodes( b, otherNode ); + } + else { + p->AddToNodes( otherNode, b ); + } + continue; + } + if ( !backWinding ) { + delete frontWinding; + if ( side == 0 ) { + p->AddToNodes( f, otherNode ); + } + else { + p->AddToNodes( otherNode, f ); + } + continue; + } + + // the winding is split + newPortal = new idBrushBSPPortal(); + *newPortal = *p; + newPortal->winding = backWinding; + delete p->winding; + p->winding = frontWinding; + + if ( side == 0 ) { + p->AddToNodes( f, otherNode ); + newPortal->AddToNodes( b, otherNode ); + } + else { + p->AddToNodes( otherNode, f ); + newPortal->AddToNodes( otherNode, b ); + } + } + + node->portals = NULL; +} + +/* +============ +idBrushBSP::MakeTreePortals_r +============ +*/ +void idBrushBSP::MakeTreePortals_r( idBrushBSPNode *node ) { + int i; + idBounds bounds; + + numPortals++; + DisplayRealTimeString( "\r%6d", numPortals ); + + bounds = node->GetPortalBounds(); + + if ( bounds[0][0] >= bounds[1][0] ) { + //common->Warning( "node without volume" ); + } + + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] < MIN_WORLD_COORD || bounds[1][i] > MAX_WORLD_COORD ) { + common->Warning( "node with unbounded volume" ); + break; + } + } + + if ( !node->children[0] || !node->children[1] ) { + return; + } + + MakeNodePortal( node ); + SplitNodePortals( node ); + + MakeTreePortals_r( node->children[0] ); + MakeTreePortals_r( node->children[1] ); +} + +/* +============ +idBrushBSP::MakeOutsidePortals +============ +*/ +void idBrushBSP::MakeOutsidePortals( void ) { + int i, j, n; + idBounds bounds; + idBrushBSPPortal *p, *portals[6]; + idVec3 normal; + idPlane planes[6]; + + // pad with some space so there will never be null volume leaves + bounds = treeBounds.Expand( 32 ); + + for ( i = 0; i < 3; i++ ) { + if ( bounds[0][i] > bounds[1][i] ) { + common->Error( "empty BSP tree" ); + } + } + + outside = new idBrushBSPNode(); + outside->parent = NULL; + outside->children[0] = outside->children[1] = NULL; + outside->brushList.Clear(); + outside->portals = NULL; + outside->contents = 0; + + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 2; j++ ) { + + p = new idBrushBSPPortal(); + normal = vec3_origin; + normal[i] = j ? -1 : 1; + p->plane.SetNormal( normal ); + p->plane.SetDist( j ? -bounds[j][i] : bounds[j][i] ); + p->winding = new idWinding( p->plane.Normal(), p->plane.Dist() ); + p->AddToNodes( root, outside ); + + n = j * 3 + i; + portals[n] = p; + } + } + + // clip the base windings with all the other planes + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 6; j++ ) { + if (j == i) { + continue; + } + portals[i]->winding = portals[i]->winding->Clip( portals[j]->plane, ON_EPSILON ); + } + } +} + +/* +============ +idBrushBSP::Portalize +============ +*/ +void idBrushBSP::Portalize( void ) { + common->Printf( "[Portalize BSP]\n" ); + common->Printf( "%6d nodes\n", (numSplits - numPrunedSplits) * 2 + 1 ); + numPortals = 0; + MakeOutsidePortals(); + MakeTreePortals_r( root ); + common->Printf( "\r%6d nodes portalized\n", numPortals ); +} + +/* +============= +LeakFile + +Finds the shortest possible chain of portals that +leads from the outside leaf to a specific occupied leaf. +============= +*/ +void idBrushBSP::LeakFile( const idStr &fileName ) { + int count, next, s; + idVec3 mid; + idFile *lineFile; + idBrushBSPNode *node, *nextNode; + idBrushBSPPortal *p, *nextPortal; + idStr qpath, name; + + if ( !outside->occupied ) { + return; + } + + qpath = fileName; + qpath.SetFileExtension( "lin" ); + + common->Printf( "writing %s...\n", qpath.c_str() ); + + lineFile = fileSystem->OpenFileWrite( qpath, "fs_devpath" ); + if ( !lineFile ) { + common->Error( "Couldn't open %s\n", qpath.c_str() ); + return; + } + + count = 0; + node = outside; + while( node->occupied > 1 ) { + + // find the best portal exit + next = node->occupied; + for (p = node->portals; p; p = p->next[!s] ) { + s = (p->nodes[0] == node); + if ( p->nodes[s]->occupied && p->nodes[s]->occupied < next ) { + nextPortal = p; + nextNode = p->nodes[s]; + next = nextNode->occupied; + } + } + node = nextNode; + mid = nextPortal->winding->GetCenter(); + lineFile->Printf( "%f %f %f\n", mid[0], mid[1], mid[2] ); + count++; + } + + // add the origin of the entity from which the leak was found + lineFile->Printf( "%f %f %f\n", leakOrigin[0], leakOrigin[1], leakOrigin[2] ); + + fileSystem->CloseFile( lineFile ); +} + +/* +============ +idBrushBSP::FloodThroughPortals_r +============ +*/ +void idBrushBSP::FloodThroughPortals_r( idBrushBSPNode *node, int contents, int depth ) { + idBrushBSPPortal *p; + int s; + + if ( node->occupied ) { + common->Error( "FloodThroughPortals_r: node already occupied\n" ); + } + if ( !node ) { + common->Error( "FloodThroughPortals_r: NULL node\n" ); + } + + node->occupied = depth; + + for ( p = node->portals; p; p = p->next[s] ) { + s = (p->nodes[1] == node); + + // if the node at the other side of the portal is removed + if ( !p->nodes[!s] ) { + continue; + } + + // if the node at the other side of the portal is occupied already + if ( p->nodes[!s]->occupied ) { + continue; + } + + // can't flood through the portal if it has the seperating contents at the other side + if ( p->nodes[!s]->contents & contents ) { + continue; + } + + // flood recursively through the current portal + FloodThroughPortals_r( p->nodes[!s], contents, depth+1 ); + } +} + +/* +============ +idBrushBSP::FloodFromOrigin +============ +*/ +bool idBrushBSP::FloodFromOrigin( const idVec3 &origin, int contents ) { + idBrushBSPNode *node; + + //find the leaf to start in + node = root; + while( node->children[0] && node->children[1] ) { + + if ( node->plane.Side( origin ) == PLANESIDE_BACK ) { + node = node->children[1]; + } + else { + node = node->children[0]; + } + } + + if ( !node ) { + return false; + } + + // if inside the inside/outside seperating contents + if ( node->contents & contents ) { + return false; + } + + // if the node is already occupied + if ( node->occupied ) { + return false; + } + + FloodThroughPortals_r( node, contents, 1 ); + + return true; +} + +/* +============ +idBrushBSP::FloodFromEntities + + Marks all nodes that can be reached by entites. +============ +*/ +bool idBrushBSP::FloodFromEntities( const idMapFile *mapFile, int contents, const idStrList &classNames ) { + int i, j; + bool inside; + idVec3 origin; + idMapEntity *mapEnt; + idStr classname; + + inside = false; + outside->occupied = 0; + + // skip the first entity which is assumed to be the worldspawn + for ( i = 1; i < mapFile->GetNumEntities(); i++ ) { + + mapEnt = mapFile->GetEntity( i ); + + if ( !mapEnt->epairs.GetVector( "origin", "", origin ) ) { + continue; + } + + if ( !mapEnt->epairs.GetString( "classname", "", classname ) ) { + continue; + } + + for ( j = 0; j < classNames.Num(); j++ ) { + if ( classname.Icmp( classNames[j] ) == 0 ) { + break; + } + } + + if ( j >= classNames.Num() ) { + continue; + } + + origin[2] += 1; + + // nudge around a little + if ( FloodFromOrigin( origin, contents ) ) { + inside = true; + } + + if ( outside->occupied ) { + leakOrigin = origin; + break; + } + } + + if ( !inside ) { + common->Warning( "no entities inside" ); + } + else if ( outside->occupied ) { + common->Warning( "reached outside from entity %d (%s)", i, classname.c_str() ); + } + + return ( inside && !outside->occupied ); +} + +/* +============ +idBrushBSP::RemoveOutside_r +============ +*/ +void idBrushBSP::RemoveOutside_r( idBrushBSPNode *node, int contents ) { + + if ( !node ) { + return; + } + + if ( node->children[0] || node->children[1] ) { + RemoveOutside_r( node->children[0], contents ); + RemoveOutside_r( node->children[1], contents ); + return; + } + + if ( !node->occupied ) { + if ( !( node->contents & contents ) ) { + outsideLeafNodes++; + node->contents |= contents; + } + else { + solidLeafNodes++; + } + } + else { + insideLeafNodes++; + } +} + +/* +============ +idBrushBSP::RemoveOutside +============ +*/ +bool idBrushBSP::RemoveOutside( const idMapFile *mapFile, int contents, const idStrList &classNames ) { + common->Printf( "[Remove Outside]\n" ); + + solidLeafNodes = outsideLeafNodes = insideLeafNodes = 0; + + if ( !FloodFromEntities( mapFile, contents, classNames ) ) { + return false; + } + + RemoveOutside_r( root, contents ); + + common->Printf( "%6d solid leaf nodes\n", solidLeafNodes ); + common->Printf( "%6d outside leaf nodes\n", outsideLeafNodes ); + common->Printf( "%6d inside leaf nodes\n", insideLeafNodes ); + + //PruneTree( contents ); + + return true; +} + +/* +============ +idBrushBSP::SetPortalPlanes_r +============ +*/ +void idBrushBSP::SetPortalPlanes_r( idBrushBSPNode *node, idPlaneSet &planeList ) { + int s; + idBrushBSPPortal *p; + + if ( !node ) { + return; + } + + for ( p = node->portals; p; p = p->next[s] ) { + s = (p->nodes[1] == node); + if ( p->planeNum == -1 ) { + p->planeNum = planeList.FindPlane( p->plane, PORTAL_PLANE_NORMAL_EPSILON, PORTAL_PLANE_DIST_EPSILON ); + } + } + SetPortalPlanes_r( node->children[0], planeList ); + SetPortalPlanes_r( node->children[1], planeList ); +} + +/* +============ +idBrushBSP::SetPortalPlanes + + give all portals a plane number +============ +*/ +void idBrushBSP::SetPortalPlanes( void ) { + SetPortalPlanes_r( root, portalPlanes ); +} + +/* +============ +idBrushBSP::MergeLeafNodePortals +============ +*/ +void idBrushBSP::MergeLeafNodePortals( idBrushBSPNode *node, int skipContents ) { + int s1, s2; + bool foundPortal; + idBrushBSPPortal *p1, *p2, *nextp1, *nextp2; + idWinding *newWinding, *reverse; + + // pass 1: merge all portals that seperate the same leaf nodes + for ( p1 = node->GetPortals(); p1; p1 = nextp1 ) { + s1 = (p1->GetNode(1) == node); + nextp1 = p1->Next(s1); + + for ( p2 = nextp1; p2; p2 = nextp2 ) { + s2 = (p2->GetNode(1) == node); + nextp2 = p2->Next(s2); + + // if both portals seperate the same leaf nodes + if ( p1->nodes[!s1] == p2->nodes[!s2] ) { + + // add the winding of p2 to the winding of p1 + p1->winding->AddToConvexHull( p2->winding, p1->plane.Normal() ); + + // delete p2 + p2->RemoveFromNode( p2->nodes[0] ); + p2->RemoveFromNode( p2->nodes[1] ); + delete p2; + + numMergedPortals++; + + nextp1 = node->GetPortals(); + break; + } + } + } + + // pass 2: merge all portals in the same plane if they all have the skip contents at the other side + for ( p1 = node->GetPortals(); p1; p1 = nextp1 ) { + s1 = (p1->GetNode(1) == node); + nextp1 = p1->Next(s1); + + if ( !(p1->nodes[!s1]->contents & skipContents) ) { + continue; + } + + // test if all portals in this plane have the skip contents at the other side + foundPortal = false; + for ( p2 = node->GetPortals(); p2; p2 = nextp2 ) { + s2 = (p2->GetNode(1) == node); + nextp2 = p2->Next(s2); + + if ( p2 == p1 || (p2->planeNum & ~1) != (p1->planeNum & ~1) ) { + continue; + } + foundPortal = true; + if ( !(p2->nodes[!s2]->contents & skipContents) ) { + break; + } + } + + // if all portals in this plane have the skip contents at the other side + if ( !p2 && foundPortal ) { + for ( p2 = node->GetPortals(); p2; p2 = nextp2 ) { + s2 = (p2->GetNode(1) == node); + nextp2 = p2->Next(s2); + + if ( p2 == p1 || (p2->planeNum & ~1) != (p1->planeNum & ~1) ) { + continue; + } + + // add the winding of p2 to the winding of p1 + p1->winding->AddToConvexHull( p2->winding, p1->plane.Normal() ); + + // delete p2 + p2->RemoveFromNode( p2->nodes[0] ); + p2->RemoveFromNode( p2->nodes[1] ); + delete p2; + + numMergedPortals++; + } + nextp1 = node->GetPortals(); + } + } + + // pass 3: try to merge portals in the same plane that have the skip contents at the other side + for ( p1 = node->GetPortals(); p1; p1 = nextp1 ) { + s1 = (p1->GetNode(1) == node); + nextp1 = p1->Next(s1); + + if ( !(p1->nodes[!s1]->contents & skipContents) ) { + continue; + } + + for ( p2 = nextp1; p2; p2 = nextp2 ) { + s2 = (p2->GetNode(1) == node); + nextp2 = p2->Next(s2); + + if ( !(p2->nodes[!s2]->contents & skipContents) ) { + continue; + } + + if ( (p2->planeNum & ~1) != (p1->planeNum & ~1) ) { + continue; + } + + // try to merge the two portal windings + if ( p2->planeNum == p1->planeNum ) { + newWinding = p1->winding->TryMerge( *p2->winding, p1->plane.Normal() ); + } + else { + reverse = p2->winding->Reverse(); + newWinding = p1->winding->TryMerge( *reverse, p1->plane.Normal() ); + delete reverse; + } + + // if successfully merged + if ( newWinding ) { + + // replace the winding of the first portal + delete p1->winding; + p1->winding = newWinding; + + // delete p2 + p2->RemoveFromNode( p2->nodes[0] ); + p2->RemoveFromNode( p2->nodes[1] ); + delete p2; + + numMergedPortals++; + + nextp1 = node->GetPortals(); + break; + } + } + } +} + +/* +============ +idBrushBSP::MergePortals_r +============ +*/ +void idBrushBSP::MergePortals_r( idBrushBSPNode *node, int skipContents ) { + + if ( !node ) { + return; + } + + if ( node->contents & skipContents ) { + return; + } + + if ( !node->children[0] && !node->children[1] ) { + MergeLeafNodePortals( node, skipContents ); + return; + } + + MergePortals_r( node->children[0], skipContents ); + MergePortals_r( node->children[1], skipContents ); +} + +/* +============ +idBrushBSP::MergePortals +============ +*/ +void idBrushBSP::MergePortals( int skipContents ) { + numMergedPortals = 0; + common->Printf( "[Merge Portals]\n" ); + SetPortalPlanes(); + MergePortals_r( root, skipContents ); + common->Printf( "%6d portals merged\n", numMergedPortals ); +} + +/* +============ +idBrushBSP::PruneMergedTree_r +============ +*/ +void idBrushBSP::PruneMergedTree_r( idBrushBSPNode *node ) { + int i; + idBrushBSPNode *leafNode; + + if ( !node ) { + return; + } + + PruneMergedTree_r( node->children[0] ); + PruneMergedTree_r( node->children[1] ); + + for ( i = 0; i < 2; i++ ) { + if ( node->children[i] ) { + leafNode = node->children[i]->children[0]; + if ( leafNode && leafNode == node->children[i]->children[1] ) { + if ( leafNode->parent == node->children[i] ) { + leafNode->parent = node; + } + delete node->children[i]; + node->children[i] = leafNode; + } + } + } +} + +/* +============ +idBrushBSP::UpdateTreeAfterMerge_r +============ +*/ +void idBrushBSP::UpdateTreeAfterMerge_r( idBrushBSPNode *node, const idBounds &bounds, idBrushBSPNode *oldNode, idBrushBSPNode *newNode ) { + + if ( !node ) { + return; + } + + if ( !node->children[0] && !node->children[1] ) { + return; + } + + if ( node->children[0] == oldNode ) { + node->children[0] = newNode; + } + if ( node->children[1] == oldNode ) { + node->children[1] = newNode; + } + + switch( bounds.PlaneSide( node->plane, 2.0f ) ) { + case PLANESIDE_FRONT: + UpdateTreeAfterMerge_r( node->children[0], bounds, oldNode, newNode ); + break; + case PLANESIDE_BACK: + UpdateTreeAfterMerge_r( node->children[1], bounds, oldNode, newNode ); + break; + default: + UpdateTreeAfterMerge_r( node->children[0], bounds, oldNode, newNode ); + UpdateTreeAfterMerge_r( node->children[1], bounds, oldNode, newNode ); + break; + } +} + +/* +============ +idBrushBSP::TryMergeLeafNodes + + NOTE: multiple brances of the BSP tree might point to the same leaf node after merging +============ +*/ +bool idBrushBSP::TryMergeLeafNodes( idBrushBSPPortal *portal, int side ) { + int i, j, k, s1, s2, s; + idBrushBSPNode *nodes[2], *node1, *node2; + idBrushBSPPortal *p1, *p2, *p, *nextp; + idPlane plane; + idWinding *w; + idBounds bounds, b; + + nodes[0] = node1 = portal->nodes[side]; + nodes[1] = node2 = portal->nodes[!side]; + + // check if the merged node would still be convex + for ( i = 0; i < 2; i++ ) { + + j = !i; + + for ( p1 = nodes[i]->portals; p1; p1 = p1->next[s1] ) { + s1 = (p1->nodes[1] == nodes[i]); + + if ( p1->nodes[!s1] == nodes[j] ) { + continue; + } + + if ( s1 ) { + plane = -p1->plane; + } + else { + plane = p1->plane; + } + + // all the non seperating portals of the other node should be at the front or on the plane + for ( p2 = nodes[j]->portals; p2; p2 = p2->next[s2] ) { + s2 = (p2->nodes[1] == nodes[j]); + + if ( p2->nodes[!s2] == nodes[i] ) { + continue; + } + + w = p2->winding; + for ( k = 0; k < w->GetNumPoints(); k++ ) { + if ( plane.Distance( (*w)[k].ToVec3() ) < -0.1f ) { + return false; + } + } + } + } + } + + // remove all portals that seperate the two nodes + for ( p = node1->portals; p; p = nextp ) { + s = (p->nodes[1] == node1); + nextp = p->next[s]; + + if ( p->nodes[!s] == node2 ) { + p->RemoveFromNode( p->nodes[0] ); + p->RemoveFromNode( p->nodes[1] ); + delete p; + } + } + + // move all portals of node2 to node1 + for ( p = node2->portals; p; p = node2->portals ) { + s = (p->nodes[1] == node2); + + nodes[s] = node1; + nodes[!s] = p->nodes[!s]; + p->RemoveFromNode( p->nodes[0] ); + p->RemoveFromNode( p->nodes[1] ); + p->AddToNodes( nodes[0], nodes[1] ); + } + + // get bounds for the new node + bounds.Clear(); + for ( p = node1->portals; p; p = p->next[s] ) { + s = (p->nodes[1] == node1); + p->GetWinding()->GetBounds( b ); + bounds += b; + } + + // replace every reference to node2 by a reference to node1 + UpdateTreeAfterMerge_r( root, bounds, node2, node1 ); + + delete node2; + + return true; +} + +/* +============ +idBrushBSP::MeltFloor_r + + flood through portals touching the bounds to find all vertices that might be inside the bounds +============ +*/ +void idBrushBSP::MeltFlood_r( idBrushBSPNode *node, int skipContents, idBounds &bounds, idVectorSet &vertexList ) { + int s1, i; + idBrushBSPPortal *p1; + idBounds b; + const idWinding *w; + + node->SetFlag( NODE_VISITED ); + + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( p1->GetNode( !s1 )->GetFlags() & NODE_VISITED ) { + continue; + } + + w = p1->GetWinding(); + + for ( i = 0; i < w->GetNumPoints(); i++ ) { + if ( bounds.ContainsPoint( (*w)[i].ToVec3() ) ) { + vertexList.FindVector( (*w)[i].ToVec3(), VERTEX_MELT_EPSILON ); + } + } + } + + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( p1->GetNode( !s1 )->GetFlags() & NODE_VISITED ) { + continue; + } + + if ( p1->GetNode( !s1 )->GetContents() & skipContents ) { + continue; + } + + w = p1->GetWinding(); + w->GetBounds( b ); + + if ( !bounds.IntersectsBounds( b ) ) { + continue; + } + + MeltFlood_r( p1->GetNode( !s1 ), skipContents, bounds, vertexList ); + } +} + +/* +============ +idBrushBSP::MeltLeafNodePortals +============ +*/ +void idBrushBSP::MeltLeafNodePortals( idBrushBSPNode *node, int skipContents, idVectorSet &vertexList ) { + int s1, i; + idBrushBSPPortal *p1; + idBounds bounds; + + if ( node->GetFlags() & NODE_DONE ) { + return; + } + + node->SetFlag( NODE_DONE ); + + // melt things together + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + + if ( p1->GetNode( !s1 )->GetFlags() & NODE_DONE ) { + continue; + } + + p1->winding->GetBounds( bounds ); + bounds.ExpandSelf( 2 * VERTEX_MELT_HASH_SIZE * VERTEX_MELT_EPSILON ); + vertexList.Init( bounds[0], bounds[1], VERTEX_MELT_HASH_SIZE, 128 ); + + // get all vertices to be considered + MeltFlood_r( node, skipContents, bounds, vertexList ); + node->RemoveFlagFlood( NODE_VISITED ); + + for ( i = 0; i < vertexList.Num(); i++ ) { + if ( p1->winding->InsertPointIfOnEdge( vertexList[i], p1->plane, 0.1f ) ) { + numInsertedPoints++; + } + } + } + DisplayRealTimeString( "\r%6d", numInsertedPoints ); +} + +/* +============ +idBrushBSP::MeltPortals_r +============ +*/ +void idBrushBSP::MeltPortals_r( idBrushBSPNode *node, int skipContents, idVectorSet &vertexList ) { + if ( !node ) { + return; + } + + if ( node->contents & skipContents ) { + return; + } + + if ( !node->children[0] && !node->children[1] ) { + MeltLeafNodePortals( node, skipContents, vertexList ); + return; + } + + MeltPortals_r( node->children[0], skipContents, vertexList ); + MeltPortals_r( node->children[1], skipContents, vertexList ); +} + +/* +============ +idBrushBSP::RemoveLeafNodeColinearPoints +============ +*/ +void idBrushBSP::RemoveLeafNodeColinearPoints( idBrushBSPNode *node ) { + int s1; + idBrushBSPPortal *p1; + + // remove colinear points + for ( p1 = node->GetPortals(); p1; p1 = p1->Next(s1) ) { + s1 = (p1->GetNode(1) == node); + p1->winding->RemoveColinearPoints( p1->plane.Normal(), 0.1f ); + } +} + +/* +============ +idBrushBSP::RemoveColinearPoints_r +============ +*/ +void idBrushBSP::RemoveColinearPoints_r( idBrushBSPNode *node, int skipContents ) { + if ( !node ) { + return; + } + + if ( node->contents & skipContents ) { + return; + } + + if ( !node->children[0] && !node->children[1] ) { + RemoveLeafNodeColinearPoints( node ); + return; + } + + RemoveColinearPoints_r( node->children[0], skipContents ); + RemoveColinearPoints_r( node->children[1], skipContents ); +} + +/* +============ +idBrushBSP::MeltPortals +============ +*/ +void idBrushBSP::MeltPortals( int skipContents ) { + idVectorSet vertexList; + + numInsertedPoints = 0; + common->Printf( "[Melt Portals]\n" ); + RemoveColinearPoints_r( root, skipContents ); + MeltPortals_r( root, skipContents, vertexList ); + root->RemoveFlagRecurse( NODE_DONE ); + common->Printf( "\r%6d points inserted\n", numInsertedPoints ); +} diff --git a/tools/compilers/aas/BrushBSP.h b/tools/compilers/aas/BrushBSP.h new file mode 100644 index 000000000..8159759ae --- /dev/null +++ b/tools/compilers/aas/BrushBSP.h @@ -0,0 +1,224 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __BRUSHBSP_H__ +#define __BRUSHBSP_H__ + +/* +=============================================================================== + + BrushBSP + +=============================================================================== +*/ + +class idBrushBSP; +class idBrushBSPNode; +class idBrushBSPPortal; + + +//=============================================================== +// +// idBrushBSPPortal +// +//=============================================================== + +class idBrushBSPPortal { + + friend class idBrushBSP; + friend class idBrushBSPNode; + +public: + idBrushBSPPortal( void ); + ~idBrushBSPPortal( void ); + void AddToNodes( idBrushBSPNode *front, idBrushBSPNode *back ); + void RemoveFromNode( idBrushBSPNode *l ); + void Flip( void ); + int Split( const idPlane &splitPlane, idBrushBSPPortal **front, idBrushBSPPortal **back ); + idWinding * GetWinding( void ) const { return winding; } + const idPlane & GetPlane( void ) const { return plane; } + void SetFaceNum( int num ) { faceNum = num; } + int GetFaceNum( void ) const { return faceNum; } + int GetFlags( void ) const { return flags; } + void SetFlag( int flag ) { flags |= flag; } + void RemoveFlag( int flag ) { flags &= ~flag; } + idBrushBSPPortal * Next( int side ) const { return next[side]; } + idBrushBSPNode * GetNode( int side ) const { return nodes[side]; } + +private: + idPlane plane; // portal plane + int planeNum; // number of plane this portal is on + idWinding * winding; // portal winding + idBrushBSPNode * nodes[2]; // nodes this portal seperates + idBrushBSPPortal * next[2]; // next portal in list for both nodes + int flags; // portal flags + int faceNum; // number of the face created for this portal +}; + + +//=============================================================== +// +// idBrushBSPNode +// +//=============================================================== + +#define NODE_VISITED BIT(30) +#define NODE_DONE BIT(31) + +class idBrushBSPNode { + + friend class idBrushBSP; + friend class idBrushBSPPortal; + +public: + idBrushBSPNode( void ); + ~idBrushBSPNode( void ); + void SetContentsFromBrushes( void ); + idBounds GetPortalBounds( void ); + idBrushBSPNode * GetChild( int index ) const { return children[index]; } + idBrushBSPNode * GetParent( void ) const { return parent; } + void SetContents( int contents ) { this->contents = contents; } + int GetContents( void ) const { return contents; } + const idPlane & GetPlane( void ) const { return plane; } + idBrushBSPPortal * GetPortals( void ) const { return portals; } + void SetAreaNum( int num ) { areaNum = num; } + int GetAreaNum( void ) const { return areaNum; } + int GetFlags( void ) const { return flags; } + void SetFlag( int flag ) { flags |= flag; } + void RemoveFlag( int flag ) { flags &= ~flag; } + bool TestLeafNode( void ); + // remove the flag from nodes found by flooding through portals to nodes with the flag set + void RemoveFlagFlood( int flag ); + // recurse down the tree and remove the flag from all visited nodes + void RemoveFlagRecurse( int flag ); + // first recurse down the tree and flood from there + void RemoveFlagRecurseFlood( int flag ); + // returns side of the plane the node is on + int PlaneSide( const idPlane &plane, float epsilon = ON_EPSILON ) const; + // split the leaf node with a plane + bool Split( const idPlane &splitPlane, int splitPlaneNum ); + + +private: + idPlane plane; // split plane if this is not a leaf node + idBrush * volume; // node volume + int contents; // node contents + idBrushList brushList; // list with brushes for this node + idBrushBSPNode * parent; // parent of this node + idBrushBSPNode * children[2]; // both are NULL if this is a leaf node + idBrushBSPPortal * portals; // portals of this node + int flags; // node flags + int areaNum; // number of the area created for this node + int occupied; // true when portal is occupied +}; + + +//=============================================================== +// +// idBrushBSP +// +//=============================================================== + +class idBrushBSP { + +public: + idBrushBSP( void ); + ~idBrushBSP( void ); + // build a bsp tree from a set of brushes + void Build( idBrushList brushList, int skipContents, + bool (*ChopAllowed)( idBrush *b1, idBrush *b2 ), + bool (*MergeAllowed)( idBrush *b1, idBrush *b2 ) ); + // remove splits in subspaces with the given contents + void PruneTree( int contents ); + // portalize the bsp tree + void Portalize( void ); + // remove subspaces outside the map not reachable by entities + bool RemoveOutside( const idMapFile *mapFile, int contents, const idStrList &classNames ); + // write file with a trace going through a leak + void LeakFile( const idStr &fileName ); + // try to merge portals + void MergePortals( int skipContents ); + // try to merge the two leaf nodes at either side of the portal + bool TryMergeLeafNodes( idBrushBSPPortal *portal, int side ); + void PruneMergedTree_r( idBrushBSPNode *node ); + // melt portal windings + void MeltPortals( int skipContents ); + // write a map file with a brush for every leaf node that has the given contents + void WriteBrushMap( const idStr &fileName, const idStr &ext, int contents ); + // bounds for the whole tree + const idBounds & GetTreeBounds( void ) const { return treeBounds; } + // root node of the tree + idBrushBSPNode * GetRootNode( void ) const { return root; } + +private: + idBrushBSPNode * root; + idBrushBSPNode * outside; + idBounds treeBounds; + idPlaneSet portalPlanes; + int numGridCells; + int numSplits; + int numGridCellSplits; + int numPrunedSplits; + int numPortals; + int solidLeafNodes; + int outsideLeafNodes; + int insideLeafNodes; + int numMergedPortals; + int numInsertedPoints; + idVec3 leakOrigin; + int brushMapContents; + idBrushMap * brushMap; + + bool (*BrushChopAllowed)( idBrush *b1, idBrush *b2 ); + bool (*BrushMergeAllowed)( idBrush *b1, idBrush *b2 ); + +private: + void RemoveMultipleLeafNodeReferences_r( idBrushBSPNode *node ); + void Free_r( idBrushBSPNode *node ); + void IncreaseNumSplits( void ); + bool IsValidSplitter( const idBrushSide *side ); + int BrushSplitterStats( const idBrush *brush, int planeNum, const idPlaneSet &planeList, bool *testedPlanes, struct splitterStats_s &stats ); + int FindSplitter( idBrushBSPNode *node, const idPlaneSet &planeList, bool *testedPlanes, struct splitterStats_s &bestStats ); + void SetSplitterUsed( idBrushBSPNode *node, int planeNum ); + idBrushBSPNode * BuildBrushBSP_r( idBrushBSPNode *node, const idPlaneSet &planeList, bool *testedPlanes, int skipContents ); + idBrushBSPNode * ProcessGridCell( idBrushBSPNode *node, int skipContents ); + void BuildGrid_r( idList &gridCells, idBrushBSPNode *node ); + void PruneTree_r( idBrushBSPNode *node, int contents ); + void MakeOutsidePortals( void ); + idWinding * BaseWindingForNode( idBrushBSPNode *node ); + void MakeNodePortal( idBrushBSPNode *node ); + void SplitNodePortals( idBrushBSPNode *node ); + void MakeTreePortals_r( idBrushBSPNode *node ); + void FloodThroughPortals_r( idBrushBSPNode *node, int contents, int depth ); + bool FloodFromOrigin( const idVec3 &origin, int contents ); + bool FloodFromEntities( const idMapFile *mapFile, int contents, const idStrList &classNames ); + void RemoveOutside_r( idBrushBSPNode *node, int contents ); + void SetPortalPlanes_r( idBrushBSPNode *node, idPlaneSet &planeList ); + void SetPortalPlanes( void ); + void MergePortals_r( idBrushBSPNode *node, int skipContents ); + void MergeLeafNodePortals( idBrushBSPNode *node, int skipContents ); + void UpdateTreeAfterMerge_r( idBrushBSPNode *node, const idBounds &bounds, idBrushBSPNode *oldNode, idBrushBSPNode *newNode ); + void RemoveLeafNodeColinearPoints( idBrushBSPNode *node ); + void RemoveColinearPoints_r( idBrushBSPNode *node, int skipContents ); + void MeltFlood_r( idBrushBSPNode *node, int skipContents, idBounds &bounds, idVectorSet &vertexList ); + void MeltLeafNodePortals( idBrushBSPNode *node, int skipContents, idVectorSet &vertexList ); + void MeltPortals_r( idBrushBSPNode *node, int skipContents, idVectorSet &vertexList ); +}; + +#endif /* !__BRUSHBSP_H__ */ diff --git a/tools/compilers/aas/aasfile.h b/tools/compilers/aas/aasfile.h deleted file mode 100644 index 15eff6181..000000000 --- a/tools/compilers/aas/aasfile.h +++ /dev/null @@ -1,339 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __AASFILE_H__ -#define __AASFILE_H__ - -/* -=============================================================================== - - AAS File - -=============================================================================== -*/ - -#define AAS_FILEID "DewmAAS" -#define AAS_FILEVERSION "1.07" - -// travel flags -#define TFL_INVALID BIT(0) // not valid -#define TFL_WALK BIT(1) // walking -#define TFL_CROUCH BIT(2) // crouching -#define TFL_WALKOFFLEDGE BIT(3) // walking of a ledge -#define TFL_BARRIERJUMP BIT(4) // jumping onto a barrier -#define TFL_JUMP BIT(5) // jumping -#define TFL_LADDER BIT(6) // climbing a ladder -#define TFL_SWIM BIT(7) // swimming -#define TFL_WATERJUMP BIT(8) // jump out of the water -#define TFL_TELEPORT BIT(9) // teleportation -#define TFL_ELEVATOR BIT(10) // travel by elevator -#define TFL_FLY BIT(11) // fly -#define TFL_SPECIAL BIT(12) // special -#define TFL_WATER BIT(21) // travel through water -#define TFL_AIR BIT(22) // travel through air -#define TFL_DOOR BIT(23) // travel through a not-open door - -// face flags -#define FACE_SOLID BIT(0) // solid at the other side -#define FACE_LADDER BIT(1) // ladder surface -#define FACE_FLOOR BIT(2) // standing on floor when on this face -#define FACE_LIQUID BIT(3) // face seperating two areas with liquid -#define FACE_LIQUIDSURFACE BIT(4) // face seperating liquid and air - -// area flags -#define AREA_FLOOR BIT(0) // AI can stand on the floor in this area -#define AREA_GAP BIT(1) // area has a gap -#define AREA_LEDGE BIT(2) // if entered the AI bbox partly floats above a ledge -#define AREA_LADDER BIT(3) // area contains one or more ladder faces -#define AREA_LIQUID BIT(4) // area contains a liquid -#define AREA_CROUCH BIT(5) // AI cannot walk but can only crouch in this area -#define AREA_REACHABLE_WALK BIT(6) // area is reachable by walking or swimming -#define AREA_REACHABLE_FLY BIT(7) // area is reachable by flying -#define AREA_DOOR BIT(8) // area contains one ore more doors - -// area contents flags -#define AREACONTENTS_SOLID BIT(0) // solid, not a valid area -#define AREACONTENTS_WATER BIT(1) // area contains water -#define AREACONTENTS_CLUSTERPORTAL BIT(2) // area is a cluster portal -#define AREACONTENTS_OBSTACLE BIT(3) // area contains (part of) a dynamic obstacle -#define AREACONTENTS_TELEPORTER BIT(4) // area contains (part of) a teleporter trigger - -// bits for different bboxes -#define AREACONTENTS_BBOX_BIT 24 - -#define MAX_REACH_PER_AREA 256 -#define MAX_AAS_TREE_DEPTH 128 - -#define MAX_AAS_BOUNDING_BOXES 4 - -// reachability to another area -class idReachability { -public: - int travelType; // type of travel required to get to the area - short toAreaNum; // number of the reachable area - short fromAreaNum; // number of area the reachability starts - idVec3 start; // start point of inter area movement - idVec3 end; // end point of inter area movement - int edgeNum; // edge crossed by this reachability - unsigned short travelTime; // travel time of the inter area movement - byte number; // reachability number within the fromAreaNum (must be < 256) - byte disableCount; // number of times this reachability has been disabled - idReachability * next; // next reachability in list - idReachability * rev_next; // next reachability in reversed list - unsigned short * areaTravelTimes; // travel times within the fromAreaNum from reachabilities that lead towards this area -public: - void CopyBase( idReachability &reach ); -}; - -class idReachability_Walk : public idReachability { -}; - -class idReachability_BarrierJump : public idReachability { -}; - -class idReachability_WaterJump : public idReachability { -}; - -class idReachability_WalkOffLedge : public idReachability { -}; - -class idReachability_Swim : public idReachability { -}; - -class idReachability_Fly : public idReachability { -}; - -class idReachability_Special : public idReachability { -public: - idDict dict; -}; - -// index -typedef int aasIndex_t; - -// vertex -typedef idVec3 aasVertex_t; - -// edge -typedef struct aasEdge_s { - int vertexNum[2]; // numbers of the vertexes of this edge -} aasEdge_t; - -// area boundary face -typedef struct aasFace_s { - unsigned short planeNum; // number of the plane this face is on - unsigned short flags; // face flags - int numEdges; // number of edges in the boundary of the face - int firstEdge; // first edge in the edge index - short areas[2]; // area at the front and back of this face -} aasFace_t; - -// area with a boundary of faces -typedef struct aasArea_s { - int numFaces; // number of faces used for the boundary of the area - int firstFace; // first face in the face index used for the boundary of the area - idBounds bounds; // bounds of the area - idVec3 center; // center of the area an AI can move towards - unsigned short flags; // several area flags - unsigned short contents; // contents of the area - short cluster; // cluster the area belongs to, if negative it's a portal - short clusterAreaNum; // number of the area in the cluster - int travelFlags; // travel flags for traveling through this area - idReachability * reach; // reachabilities that start from this area - idReachability * rev_reach; // reachabilities that lead to this area -} aasArea_t; - -// nodes of the bsp tree -typedef struct aasNode_s { - unsigned short planeNum; // number of the plane that splits the subspace at this node - int children[2]; // child nodes, zero is solid, negative is -(area number) -} aasNode_t; - -// cluster portal -typedef struct aasPortal_s { - short areaNum; // number of the area that is the actual portal - short clusters[2]; // number of cluster at the front and back of the portal - short clusterAreaNum[2]; // number of this portal area in the front and back cluster - unsigned short maxAreaTravelTime; // maximum travel time through the portal area -} aasPortal_t; - -// cluster -typedef struct aasCluster_s { - int numAreas; // number of areas in the cluster - int numReachableAreas; // number of areas with reachabilities - int numPortals; // number of cluster portals - int firstPortal; // first cluster portal in the index -} aasCluster_t; - -// trace through the world -typedef struct aasTrace_s { - // parameters - int flags; // areas with these flags block the trace - int travelFlags; // areas with these travel flags block the trace - int maxAreas; // size of the 'areas' array - int getOutOfSolid; // trace out of solid if the trace starts in solid - // output - float fraction; // fraction of trace completed - idVec3 endpos; // end position of trace - int planeNum; // plane hit - int lastAreaNum; // number of last area the trace went through - int blockingAreaNum; // area that could not be entered - int numAreas; // number of areas the trace went through - int * areas; // array to store areas the trace went through - idVec3 * points; // points where the trace entered each new area - aasTrace_s( void ) { areas = NULL; points = NULL; getOutOfSolid = false; flags = travelFlags = maxAreas = 0; } -} aasTrace_t; - -// settings -class idAASSettings { -public: - // collision settings - int numBoundingBoxes; - idBounds boundingBoxes[MAX_AAS_BOUNDING_BOXES]; - bool usePatches; - bool writeBrushMap; - bool playerFlood; - bool noOptimize; - bool allowSwimReachabilities; - bool allowFlyReachabilities; - idStr fileExtension; - // physics settings - idVec3 gravity; - idVec3 gravityDir; - idVec3 invGravityDir; - float gravityValue; - float maxStepHeight; - float maxBarrierHeight; - float maxWaterJumpHeight; - float maxFallHeight; - float minFloorCos; - // fixed travel times - int tt_barrierJump; - int tt_startCrouching; - int tt_waterJump; - int tt_startWalkOffLedge; - -public: - idAASSettings( void ); - - bool FromFile( const idStr &fileName ); - bool FromParser( idLexer &src ); - bool FromDict( const char *name, const idDict *dict ); - bool WriteToFile( idFile *fp ) const; - bool ValidForBounds( const idBounds &bounds ) const; - bool ValidEntity( const char *classname ) const; - -private: - bool ParseBool( idLexer &src, bool &b ); - bool ParseInt( idLexer &src, int &i ); - bool ParseFloat( idLexer &src, float &f ); - bool ParseVector( idLexer &src, idVec3 &vec ); - bool ParseBBoxes( idLexer &src ); -}; - - -/* - -- when a node child is a solid leaf the node child number is zero -- two adjacent areas (sharing a plane at opposite sides) share a face - this face is a portal between the areas -- when an area uses a face from the faceindex with a positive index - then the face plane normal points into the area -- the face edges are stored counter clockwise using the edgeindex -- two adjacent convex areas (sharing a face) only share One face - this is a simple result of the areas being convex -- the areas can't have a mixture of ground and gap faces - other mixtures of faces in one area are allowed -- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have - the cluster number set to the negative portal number -- edge zero is a dummy -- face zero is a dummy -- area zero is a dummy -- node zero is a dummy -- portal zero is a dummy -- cluster zero is a dummy - -*/ - - -class idAASFile { -public: - virtual ~idAASFile( void ) {} - - const char * GetName( void ) const { return name.c_str(); } - unsigned int GetCRC( void ) const { return crc; } - - int GetNumPlanes( void ) const { return planeList.Num(); } - const idPlane & GetPlane( int index ) const { return planeList[index]; } - int GetNumVertices( void ) const { return vertices.Num(); } - const aasVertex_t & GetVertex( int index ) const { return vertices[index]; } - int GetNumEdges( void ) const { return edges.Num(); } - const aasEdge_t & GetEdge( int index ) const { return edges[index]; } - int GetNumEdgeIndexes( void ) const { return edgeIndex.Num(); } - const aasIndex_t & GetEdgeIndex( int index ) const { return edgeIndex[index]; } - int GetNumFaces( void ) const { return faces.Num(); } - const aasFace_t & GetFace( int index ) const { return faces[index]; } - int GetNumFaceIndexes( void ) const { return faceIndex.Num(); } - const aasIndex_t & GetFaceIndex( int index ) const { return faceIndex[index]; } - int GetNumAreas( void ) const { return areas.Num(); } - const aasArea_t & GetArea( int index ) { return areas[index]; } - int GetNumNodes( void ) const { return nodes.Num(); } - const aasNode_t & GetNode( int index ) const { return nodes[index]; } - int GetNumPortals( void ) const { return portals.Num(); } - const aasPortal_t & GetPortal( int index ) { return portals[index]; } - int GetNumPortalIndexes( void ) const { return portalIndex.Num(); } - const aasIndex_t & GetPortalIndex( int index ) const { return portalIndex[index]; } - int GetNumClusters( void ) const { return clusters.Num(); } - const aasCluster_t & GetCluster( int index ) const { return clusters[index]; } - - const idAASSettings & GetSettings( void ) const { return settings; } - - void SetPortalMaxTravelTime( int index, int time ) { portals[index].maxAreaTravelTime = time; } - void SetAreaTravelFlag( int index, int flag ) { areas[index].travelFlags |= flag; } - void SetAreaFlag( int index, int flag ) { areas[index].flags |= flag; } - void RemoveAreaFlag( int index, int flag ) { areas[index].flags &= ~flag; } - void RemoveAreaTravelFlag( int index, int flag ) { areas[index].travelFlags &= ~flag; } - - virtual idVec3 EdgeCenter( int edgeNum ) const = 0; - virtual idVec3 FaceCenter( int faceNum ) const = 0; - virtual idVec3 AreaCenter( int areaNum ) const = 0; - - virtual idBounds EdgeBounds( int edgeNum ) const = 0; - virtual idBounds FaceBounds( int faceNum ) const = 0; - virtual idBounds AreaBounds( int areaNum ) const = 0; - - virtual int PointAreaNum( const idVec3 &origin ) const = 0; - virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const = 0; - virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const = 0; - virtual void PushPointIntoAreaNum( int areaNum, idVec3 &point ) const = 0; - virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0; - virtual void PrintInfo( void ) const = 0; - -protected: - idStr name; - unsigned int crc; - - idPlaneSet planeList; - idList vertices; - idList edges; - idList edgeIndex; - idList faces; - idList faceIndex; - idList areas; - idList nodes; - idList portals; - idList portalIndex; - idList clusters; - idAASSettings settings; -}; - -#endif /* !__AASFILE_H__ */ diff --git a/tools/compilers/aas/aasfilemanager.h b/tools/compilers/aas/aasfilemanager.h deleted file mode 100644 index 7788a66b8..000000000 --- a/tools/compilers/aas/aasfilemanager.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __AASFILEMANAGER_H__ -#define __AASFILEMANAGER_H__ - -/* -=============================================================================== - - AAS File Manager - -=============================================================================== -*/ - -class idAASFileManager { -public: - virtual ~idAASFileManager( void ) {} - - virtual idAASFile * LoadAAS( const char *fileName, unsigned int mapFileCRC ) = 0; - virtual void FreeAAS( idAASFile *file ) = 0; -}; - -extern idAASFileManager * AASFileManager; - -#endif /* !__AASFILEMANAGER_H__ */ diff --git a/tools/compilers/compiler_public.h b/tools/compilers/compiler_public.h new file mode 100644 index 000000000..1b212e073 --- /dev/null +++ b/tools/compilers/compiler_public.h @@ -0,0 +1,46 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __COMPILER_PUBLIC_H__ +#define __COMPILER_PUBLIC_H__ + +/* +=============================================================================== + + Compilers for map, model, video etc. processing. + +=============================================================================== +*/ + +// map processing (also see SuperOptimizeOccluders in tr_local.h) +void Dmap_f( const idCmdArgs &args ); + +// bump map generation +void RenderBump_f( const idCmdArgs &args ); +void RenderBumpFlat_f( const idCmdArgs &args ); + +// AAS file compiler +void RunAAS_f( const idCmdArgs &args ); +void RunAASDir_f( const idCmdArgs &args ); +void RunReach_f( const idCmdArgs &args ); + +// video file encoding +void RoQFileEncode_f( const idCmdArgs &args ); + +#endif /* !__COMPILER_PUBLIC_H__ */ diff --git a/tools/compilers/dmap/dmap.cpp b/tools/compilers/dmap/dmap.cpp new file mode 100644 index 000000000..981d8fd8a --- /dev/null +++ b/tools/compilers/dmap/dmap.cpp @@ -0,0 +1,395 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +dmapGlobals_t dmapGlobals; + +/* +============ +ProcessModel +============ +*/ +bool ProcessModel( uEntity_t *e, bool floodFill ) { + bspface_t *faces; + + // build a bsp tree using all of the sides + // of all of the structural brushes + faces = MakeStructuralBspFaceList ( e->primitives ); + e->tree = FaceBSP( faces ); + + // create portals at every leaf intersection + // to allow flood filling + MakeTreePortals( e->tree ); + + // classify the leafs as opaque or areaportal + FilterBrushesIntoTree( e ); + + // see if the bsp is completely enclosed + if ( floodFill && !dmapGlobals.noFlood ) { + if ( FloodEntities( e->tree ) ) { + // set the outside leafs to opaque + FillOutside( e ); + } else { + common->Printf ( "**********************\n" ); + common->Warning( "******* leaked *******" ); + common->Printf ( "**********************\n" ); + LeakFile( e->tree ); + // bail out here. If someone really wants to + // process a map that leaks, they should use + // -noFlood + return false; + } + } + + // get minimum convex hulls for each visible side + // this must be done before creating area portals, + // because the visible hull is used as the portal + ClipSidesByTree( e ); + + // determine areas before clipping tris into the + // tree, so tris will never cross area boundaries + FloodAreas( e ); + + // we now have a BSP tree with solid and non-solid leafs marked with areas + // all primitives will now be clipped into this, throwing away + // fragments in the solid areas + PutPrimitivesInAreas( e ); + + // now build shadow volumes for the lights and split + // the optimize lists by the light beam trees + // so there won't be unneeded overdraw in the static + // case + Prelight( e ); + + // optimizing is a superset of fixing tjunctions + if ( !dmapGlobals.noOptimize ) { + OptimizeEntity( e ); + } else if ( !dmapGlobals.noTJunc ) { + FixEntityTjunctions( e ); + } + + // now fix t junctions across areas + FixGlobalTjunctions( e ); + + return true; +} + +/* +============ +ProcessModels +============ +*/ +bool ProcessModels( void ) { + bool oldVerbose; + uEntity_t *entity; + + oldVerbose = dmapGlobals.verbose; + + for ( dmapGlobals.entityNum = 0 ; dmapGlobals.entityNum < dmapGlobals.num_entities ; dmapGlobals.entityNum++ ) { + + entity = &dmapGlobals.uEntities[dmapGlobals.entityNum]; + if ( !entity->primitives ) { + continue; + } + + common->Printf( "############### entity %i ###############\n", dmapGlobals.entityNum ); + + // if we leaked, stop without any more processing + if ( !ProcessModel( entity, (bool)(dmapGlobals.entityNum == 0 ) ) ) { + return false; + } + + // we usually don't want to see output for submodels unless + // something strange is going on + if ( !dmapGlobals.verboseentities ) { + dmapGlobals.verbose = false; + } + } + + dmapGlobals.verbose = oldVerbose; + + return true; +} + +/* +============ +DmapHelp +============ +*/ +void DmapHelp( void ) { + common->Printf( + + "Usage: dmap [options] mapfile\n" + "Options:\n" + "noCurves = don't process curves\n" + "noCM = don't create collision map\n" + "noAAS = don't create AAS files\n" + + ); +} + +/* +============ +ResetDmapGlobals +============ +*/ +void ResetDmapGlobals( void ) { + dmapGlobals.mapFileBase[0] = '\0'; + dmapGlobals.dmapFile = NULL; + dmapGlobals.mapPlanes.Clear(); + dmapGlobals.num_entities = 0; + dmapGlobals.uEntities = NULL; + dmapGlobals.entityNum = 0; + dmapGlobals.mapLights.Clear(); + dmapGlobals.verbose = false; + dmapGlobals.glview = false; + dmapGlobals.noOptimize = false; + dmapGlobals.verboseentities = false; + dmapGlobals.noCurves = false; + dmapGlobals.fullCarve = false; + dmapGlobals.noModelBrushes = false; + dmapGlobals.noTJunc = false; + dmapGlobals.nomerge = false; + dmapGlobals.noFlood = false; + dmapGlobals.noClipSides = false; + dmapGlobals.noLightCarve = false; + dmapGlobals.noShadow = false; + dmapGlobals.shadowOptLevel = SO_NONE; + dmapGlobals.drawBounds.Clear(); + dmapGlobals.drawflag = false; + dmapGlobals.totalShadowTriangles = 0; + dmapGlobals.totalShadowVerts = 0; +} + +/* +============ +Dmap +============ +*/ +void Dmap( const idCmdArgs &args ) { + int i; + int start, end; + char path[1024]; + idStr passedName; + bool leaked = false; + bool noCM = false; + bool noAAS = false; + + ResetDmapGlobals(); + + if ( args.Argc() < 2 ) { + DmapHelp(); + return; + } + + common->Printf("---- dmap ----\n"); + + dmapGlobals.fullCarve = true; + dmapGlobals.shadowOptLevel = SO_MERGE_SURFACES; // create shadows by merging all surfaces, but no super optimization +// dmapGlobals.shadowOptLevel = SO_CLIP_OCCLUDERS; // remove occluders that are completely covered +// dmapGlobals.shadowOptLevel = SO_SIL_OPTIMIZE; +// dmapGlobals.shadowOptLevel = SO_CULL_OCCLUDED; + + dmapGlobals.noLightCarve = true; + + for ( i = 1 ; i < args.Argc() ; i++ ) { + const char *s; + + s = args.Argv(i); + if ( s[0] == '-' ) { + s++; + if ( s[0] == '\0' ) { + continue; + } + } + + if ( !idStr::Icmp( s,"glview" ) ) { + dmapGlobals.glview = true; + } else if ( !idStr::Icmp( s, "v" ) ) { + common->Printf( "verbose = true\n" ); + dmapGlobals.verbose = true; + } else if ( !idStr::Icmp( s, "draw" ) ) { + common->Printf( "drawflag = true\n" ); + dmapGlobals.drawflag = true; + } else if ( !idStr::Icmp( s, "noFlood" ) ) { + common->Printf( "noFlood = true\n" ); + dmapGlobals.noFlood = true; + } else if ( !idStr::Icmp( s, "noLightCarve" ) ) { + common->Printf( "noLightCarve = true\n" ); + dmapGlobals.noLightCarve = true; + } else if ( !idStr::Icmp( s, "lightCarve" ) ) { + common->Printf( "noLightCarve = false\n" ); + dmapGlobals.noLightCarve = false; + } else if ( !idStr::Icmp( s, "noOpt" ) ) { + common->Printf( "noOptimize = true\n" ); + dmapGlobals.noOptimize = true; + } else if ( !idStr::Icmp( s, "verboseentities" ) ) { + common->Printf( "verboseentities = true\n"); + dmapGlobals.verboseentities = true; + } else if ( !idStr::Icmp( s, "noCurves" ) ) { + common->Printf( "noCurves = true\n"); + dmapGlobals.noCurves = true; + } else if ( !idStr::Icmp( s, "noModels" ) ) { + common->Printf( "noModels = true\n" ); + dmapGlobals.noModelBrushes = true; + } else if ( !idStr::Icmp( s, "noClipSides" ) ) { + common->Printf( "noClipSides = true\n" ); + dmapGlobals.noClipSides = true; + } else if ( !idStr::Icmp( s, "noCarve" ) ) { + common->Printf( "noCarve = true\n" ); + dmapGlobals.fullCarve = false; + } else if ( !idStr::Icmp( s, "shadowOpt" ) ) { + dmapGlobals.shadowOptLevel = (shadowOptLevel_t)atoi( args.Argv( i+1 ) ); + common->Printf( "shadowOpt = %i\n",dmapGlobals.shadowOptLevel ); + i += 1; + } else if ( !idStr::Icmp( s, "noTjunc" ) ) { + // triangle optimization won't work properly without tjunction fixing + common->Printf ("noTJunc = true\n" ); + dmapGlobals.noTJunc = true; + dmapGlobals.noOptimize = true; + common->Printf ("forcing noOptimize = true\n" ); + } else if ( !idStr::Icmp( s, "noCM" ) ) { + noCM = true; + common->Printf( "noCM = true\n" ); + } else if ( !idStr::Icmp( s, "noAAS" ) ) { + noAAS = true; + common->Printf( "noAAS = true\n" ); + } else if ( !idStr::Icmp( s, "editorOutput" ) ) { +#ifdef _WIN32 + com_outputMsg = true; +#endif + } else { + break; + } + } + + if ( i >= args.Argc() ) { + common->Error( "usage: dmap [options] mapfile" ); + } + + passedName = args.Argv(i); // may have an extension + passedName.BackSlashesToSlashes(); + if ( passedName.Icmpn( "maps/", 4 ) != 0 ) { + passedName = "maps/" + passedName; + } + + idStr stripped = passedName; + stripped.StripFileExtension(); + idStr::Copynz( dmapGlobals.mapFileBase, stripped, sizeof(dmapGlobals.mapFileBase) ); + + bool region = false; + // if this isn't a regioned map, delete the last saved region map + if ( passedName.Right( 4 ) != ".reg" ) { + sprintf( path, "%s.reg", dmapGlobals.mapFileBase ); + fileSystem->RemoveFile( path ); + } else { + region = true; + } + + + passedName = stripped; + + // delete any old line leak files + sprintf( path, "%s.lin", dmapGlobals.mapFileBase ); + fileSystem->RemoveFile( path ); + + + // + // start from scratch + // + start = Sys_Milliseconds(); + + if ( !LoadDMapFile( passedName ) ) { + return; + } + + if ( ProcessModels() ) { + WriteOutputFile(); + } else { + leaked = true; + } + + FreeDMapFile(); + + common->Printf( "%i total shadow triangles\n", dmapGlobals.totalShadowTriangles ); + common->Printf( "%i total shadow verts\n", dmapGlobals.totalShadowVerts ); + + end = Sys_Milliseconds(); + common->Printf( "-----------------------\n" ); + common->Printf( "%5.0f seconds for dmap\n", ( end - start ) * 0.001f ); + + if ( !leaked ) { + + if ( !noCM ) { + + // make sure the collision model manager is not used by the game + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); + + // create the collision map + start = Sys_Milliseconds(); + + collisionModelManager->LoadMap( dmapGlobals.dmapFile ); + collisionModelManager->FreeMap(); + + end = Sys_Milliseconds(); + common->Printf( "-------------------------------------\n" ); + common->Printf( "%5.0f seconds to create collision map\n", ( end - start ) * 0.001f ); + } + + if ( !noAAS && !region ) { + // create AAS files + RunAAS_f( args ); + } + } + + // free the common .map representation + delete dmapGlobals.dmapFile; + + // clear the map plane list + dmapGlobals.mapPlanes.Clear(); + +#ifdef _WIN32 + if ( com_outputMsg && com_hwndMsg != NULL ) { + unsigned int msg = ::RegisterWindowMessage( DMAP_DONE ); + ::PostMessage( com_hwndMsg, msg, 0, 0 ); + } +#endif +} + +/* +============ +Dmap_f +============ +*/ +void Dmap_f( const idCmdArgs &args ) { + + common->ClearWarnings( "running dmap" ); + + // refresh the screen each time we print so it doesn't look + // like it is hung + common->SetRefreshOnPrint( true ); + Dmap( args ); + common->SetRefreshOnPrint( false ); + + common->PrintWarnings(); +} diff --git a/tools/compilers/dmap/dmap.h b/tools/compilers/dmap/dmap.h new file mode 100644 index 000000000..2e42f232f --- /dev/null +++ b/tools/compilers/dmap/dmap.h @@ -0,0 +1,476 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../renderer/tr_local.h" + + +typedef struct primitive_s { + struct primitive_s *next; + + // only one of these will be non-NULL + struct bspbrush_s * brush; + struct mapTri_s * tris; +} primitive_t; + + +typedef struct { + struct optimizeGroup_s *groups; + // we might want to add other fields later +} uArea_t; + +typedef struct { + idMapEntity * mapEntity; // points into mapFile_t data + + idVec3 origin; + primitive_t * primitives; + struct tree_s * tree; + + int numAreas; + uArea_t * areas; +} uEntity_t; + + +// chains of mapTri_t are the general unit of processing +typedef struct mapTri_s { + struct mapTri_s * next; + + const idMaterial * material; + void * mergeGroup; // we want to avoid merging triangles + // from different fixed groups, like guiSurfs and mirrors + int planeNum; // not set universally, just in some areas + + idDrawVert v[3]; + const struct hashVert_s *hashVert[3]; + struct optVertex_s *optVert[3]; +} mapTri_t; + + +typedef struct { + int width, height; + idDrawVert * verts; +} mesh_t; + + +#define MAX_PATCH_SIZE 32 + +#define PLANENUM_LEAF -1 + +typedef struct parseMesh_s { + struct parseMesh_s *next; + mesh_t mesh; + const idMaterial * material; +} parseMesh_t; + +typedef struct bspface_s { + struct bspface_s * next; + int planenum; + bool portal; // all portals will be selected before + // any non-portals + bool checked; // used by SelectSplitPlaneNum() + idWinding * w; +} bspface_t; + +typedef struct { + idVec4 v[2]; // the offset value will always be in the 0.0 to 1.0 range +} textureVectors_t; + +typedef struct side_s { + int planenum; + + const idMaterial * material; + textureVectors_t texVec; + + idWinding * winding; // only clipped to the other sides of the brush + idWinding * visibleHull; // also clipped to the solid parts of the world +} side_t; + + +typedef struct bspbrush_s { + struct bspbrush_s * next; + struct bspbrush_s * original; // chopped up brushes will reference the originals + + int entitynum; // editor numbering for messages + int brushnum; // editor numbering for messages + + const idMaterial * contentShader; // one face's shader will determine the volume attributes + + int contents; + bool opaque; + int outputNumber; // set when the brush is written to the file list + + idBounds bounds; + int numsides; + side_t sides[6]; // variably sized +} uBrush_t; + + +typedef struct drawSurfRef_s { + struct drawSurfRef_s * nextRef; + int outputNumber; +} drawSurfRef_t; + + +typedef struct node_s { + // both leafs and nodes + int planenum; // -1 = leaf node + struct node_s * parent; + idBounds bounds; // valid after portalization + + // nodes only + side_t * side; // the side that created the node + struct node_s * children[2]; + int nodeNumber; // set after pruning + + // leafs only + bool opaque; // view can never be inside + + uBrush_t * brushlist; // fragments of all brushes in this leaf + // needed for FindSideForPortal + + int area; // determined by flood filling up to areaportals + int occupied; // 1 or greater can reach entity + uEntity_t * occupant; // for leak file testing + + struct uPortal_s * portals; // also on nodes during construction +} node_t; + + +typedef struct uPortal_s { + idPlane plane; + node_t *onnode; // NULL = outside box + node_t *nodes[2]; // [0] = front side of plane + struct uPortal_s *next[2]; + idWinding *winding; +} uPortal_t; + +// a tree_t is created by FaceBSP() +typedef struct tree_s { + node_t *headnode; + node_t outside_node; + idBounds bounds; +} tree_t; + +#define MAX_QPATH 256 // max length of a game pathname + +typedef struct { + idRenderLightLocal def; + char name[MAX_QPATH]; // for naming the shadow volume surface and interactions + srfTriangles_t *shadowTris; +} mapLight_t; + +#define MAX_GROUP_LIGHTS 16 + +typedef struct optimizeGroup_s { + struct optimizeGroup_s *nextGroup; + + idBounds bounds; // set in CarveGroupsByLight + + // all of these must match to add a triangle to the triList + bool smoothed; // curves will never merge with brushes + int planeNum; + int areaNum; + const idMaterial * material; + int numGroupLights; + mapLight_t * groupLights[MAX_GROUP_LIGHTS]; // lights effecting this list + void * mergeGroup; // if this differs (guiSurfs, mirrors, etc), the + // groups will not be combined into model surfaces + // after optimization + textureVectors_t texVec; + + bool surfaceEmited; + + mapTri_t * triList; + mapTri_t * regeneratedTris; // after each island optimization + idVec3 axis[2]; // orthogonal to the plane, so optimization can be 2D +} optimizeGroup_t; + +// all primitives from the map are added to optimzeGroups, creating new ones as needed +// each optimizeGroup is then split into the map areas, creating groups in each area +// each optimizeGroup is then divided by each light, creating more groups +// the final list of groups is then tjunction fixed against all groups, then optimized internally +// multiple optimizeGroups will be merged together into .proc surfaces, but no further optimization +// is done on them + + +//============================================================================= + +// dmap.cpp + +typedef enum { + SO_NONE, // 0 + SO_MERGE_SURFACES, // 1 + SO_CULL_OCCLUDED, // 2 + SO_CLIP_OCCLUDERS, // 3 + SO_CLIP_SILS, // 4 + SO_SIL_OPTIMIZE // 5 +} shadowOptLevel_t; + +typedef struct { + // mapFileBase will contain the qpath without any extension: "maps/test_box" + char mapFileBase[1024]; + + idMapFile *dmapFile; + + idPlaneSet mapPlanes; + + int num_entities; + uEntity_t *uEntities; + + int entityNum; + + idList mapLights; + + bool verbose; + + bool glview; + bool noOptimize; + bool verboseentities; + bool noCurves; + bool fullCarve; + bool noModelBrushes; + bool noTJunc; + bool nomerge; + bool noFlood; + bool noClipSides; // don't cut sides by solid leafs, use the entire thing + bool noLightCarve; // extra triangle subdivision by light frustums + shadowOptLevel_t shadowOptLevel; + bool noShadow; // don't create optimized shadow volumes + + idBounds drawBounds; + bool drawflag; + + int totalShadowTriangles; + int totalShadowVerts; +} dmapGlobals_t; + +extern dmapGlobals_t dmapGlobals; + +int FindFloatPlane( const idPlane &plane, bool *fixedDegeneracies = NULL ); + + +//============================================================================= + +// brush.cpp + +#ifndef CLIP_EPSILON +#define CLIP_EPSILON 0.1f +#endif + +#define PSIDE_FRONT 1 +#define PSIDE_BACK 2 +#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK) +#define PSIDE_FACING 4 + +int CountBrushList (uBrush_t *brushes); +uBrush_t *AllocBrush (int numsides); +void FreeBrush (uBrush_t *brushes); +void FreeBrushList (uBrush_t *brushes); +uBrush_t *CopyBrush (uBrush_t *brush); +void DrawBrushList (uBrush_t *brush); +void PrintBrush (uBrush_t *brush); +bool BoundBrush (uBrush_t *brush); +bool CreateBrushWindings (uBrush_t *brush); +uBrush_t *BrushFromBounds( const idBounds &bounds ); +float BrushVolume (uBrush_t *brush); +void WriteBspBrushMap( const char *name, uBrush_t *list ); + +void FilterBrushesIntoTree( uEntity_t *e ); + +void SplitBrush( uBrush_t *brush, int planenum, uBrush_t **front, uBrush_t **back); +node_t *AllocNode( void ); + + +//============================================================================= + +// map.cpp + +bool LoadDMapFile( const char *filename ); +void FreeOptimizeGroupList( optimizeGroup_t *groups ); +void FreeDMapFile( void ); + +//============================================================================= + +// draw.cpp -- draw debug views either directly, or through glserv.exe + +void Draw_ClearWindow( void ); +void DrawWinding( const idWinding *w ); +void DrawAuxWinding( const idWinding *w ); + +void DrawLine( idVec3 v1, idVec3 v2, int color ); + +void GLS_BeginScene( void ); +void GLS_Winding( const idWinding *w, int code ); +void GLS_Triangle( const mapTri_t *tri, int code ); +void GLS_EndScene( void ); + + + +//============================================================================= + +// portals.cpp + +#define MAX_INTER_AREA_PORTALS 1024 + +typedef struct { + int area0, area1; + side_t *side; +} interAreaPortal_t; + +extern interAreaPortal_t interAreaPortals[MAX_INTER_AREA_PORTALS]; +extern int numInterAreaPortals; + +bool FloodEntities( tree_t *tree ); +void FillOutside( uEntity_t *e ); +void FloodAreas( uEntity_t *e ); +void MakeTreePortals( tree_t *tree ); +void FreePortal( uPortal_t *p ); + +//============================================================================= + +// glfile.cpp -- write a debug file to be viewd with glview.exe + +void OutputWinding( idWinding *w, idFile *glview ); +void WriteGLView( tree_t *tree, char *source ); + +//============================================================================= + +// leakfile.cpp + +void LeakFile( tree_t *tree ); + +//============================================================================= + +// facebsp.cpp + +tree_t *AllocTree( void ); + +void FreeTree( tree_t *tree ); + +void FreeTree_r( node_t *node ); +void FreeTreePortals_r( node_t *node ); + + +bspface_t *MakeStructuralBspFaceList( primitive_t *list ); +bspface_t *MakeVisibleBspFaceList( primitive_t *list ); +tree_t *FaceBSP( bspface_t *list ); + +//============================================================================= + +// surface.cpp + +mapTri_t *CullTrisInOpaqueLeafs( mapTri_t *triList, tree_t *tree ); +void ClipSidesByTree( uEntity_t *e ); +void SplitTrisToSurfaces( mapTri_t *triList, tree_t *tree ); +void PutPrimitivesInAreas( uEntity_t *e ); +void Prelight( uEntity_t *e ); + +//============================================================================= + +// tritjunction.cpp + +struct hashVert_s *GetHashVert( idVec3 &v ); +void HashTriangles( optimizeGroup_t *groupList ); +void FreeTJunctionHash( void ); +int CountGroupListTris( const optimizeGroup_t *groupList ); +void FixEntityTjunctions( uEntity_t *e ); +void FixAreaGroupsTjunctions( optimizeGroup_t *groupList ); +void FixGlobalTjunctions( uEntity_t *e ); + +//============================================================================= + +// optimize.cpp -- trianlge mesh reoptimization + +// the shadow volume optimizer call internal optimizer routines, normal triangles +// will just be done by OptimizeEntity() + + +typedef struct optVertex_s { + idDrawVert v; + idVec3 pv; // projected against planar axis, third value is 0 + struct optEdge_s *edges; + struct optVertex_s *islandLink; + bool addedToIsland; + bool emited; // when regenerating triangles +} optVertex_t; + +typedef struct optEdge_s { + optVertex_t *v1, *v2; + struct optEdge_s *islandLink; + bool addedToIsland; + bool created; // not one of the original edges + bool combined; // combined from two or more colinear edges + struct optTri_s *frontTri, *backTri; + struct optEdge_s *v1link, *v2link; +} optEdge_t; + +typedef struct optTri_s { + struct optTri_s *next; + idVec3 midpoint; + optVertex_t *v[3]; + bool filled; +} optTri_t; + +typedef struct { + optimizeGroup_t *group; + optVertex_t *verts; + optEdge_t *edges; + optTri_t *tris; +} optIsland_t; + + +void OptimizeEntity( uEntity_t *e ); +void OptimizeGroupList( optimizeGroup_t *groupList ); + +//============================================================================= + +// tritools.cpp + +mapTri_t *AllocTri( void ); +void FreeTri( mapTri_t *tri ); +int CountTriList( const mapTri_t *list ); +mapTri_t *MergeTriLists( mapTri_t *a, mapTri_t *b ); +mapTri_t *CopyTriList( const mapTri_t *a ); +void FreeTriList( mapTri_t *a ); +mapTri_t *CopyMapTri( const mapTri_t *tri ); +float MapTriArea( const mapTri_t *tri ); +mapTri_t *RemoveBadTris( const mapTri_t *tri ); +void BoundTriList( const mapTri_t *list, idBounds &b ); +void DrawTri( const mapTri_t *tri ); +void FlipTriList( mapTri_t *tris ); +void TriVertsFromOriginal( mapTri_t *tri, const mapTri_t *original ); +void PlaneForTri( const mapTri_t *tri, idPlane &plane ); +idWinding *WindingForTri( const mapTri_t *tri ); +mapTri_t *WindingToTriList( const idWinding *w, const mapTri_t *originalTri ); +void ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon, mapTri_t **front, mapTri_t **back ); + +//============================================================================= + +// output.cpp + +srfTriangles_t *ShareMapTriVerts( const mapTri_t *tris ); +void WriteOutputFile( void ); + +//============================================================================= + +// shadowopt.cpp + +srfTriangles_t *CreateLightShadow( optimizeGroup_t *shadowerGroups, const mapLight_t *light ); +void FreeBeamTree( struct beamTree_s *beamTree ); + +void CarveTriByBeamTree( const struct beamTree_s *beamTree, const mapTri_t *tri, mapTri_t **lit, mapTri_t **unLit ); diff --git a/tools/compilers/dmap/facebsp.cpp b/tools/compilers/dmap/facebsp.cpp new file mode 100644 index 000000000..93206fbb6 --- /dev/null +++ b/tools/compilers/dmap/facebsp.cpp @@ -0,0 +1,490 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +int c_faceLeafs; + + +extern int c_nodes; + +void RemovePortalFromNode( uPortal_t *portal, node_t *l ); + +node_t *NodeForPoint( node_t *node, idVec3 origin ) { + float d; + + while( node->planenum != PLANENUM_LEAF ) { + idPlane &plane = dmapGlobals.mapPlanes[node->planenum]; + d = plane.Distance( origin ); + if ( d >= 0 ) { + node = node->children[0]; + } else { + node = node->children[1]; + } + } + + return node; +} + + + +/* +============= +FreeTreePortals_r +============= +*/ +void FreeTreePortals_r (node_t *node) +{ + uPortal_t *p, *nextp; + int s; + + // free children + if (node->planenum != PLANENUM_LEAF) + { + FreeTreePortals_r (node->children[0]); + FreeTreePortals_r (node->children[1]); + } + + // free portals + for (p=node->portals ; p ; p=nextp) + { + s = (p->nodes[1] == node); + nextp = p->next[s]; + + RemovePortalFromNode (p, p->nodes[!s]); + FreePortal (p); + } + node->portals = NULL; +} + +/* +============= +FreeTree_r +============= +*/ +void FreeTree_r (node_t *node) +{ + // free children + if (node->planenum != PLANENUM_LEAF) + { + FreeTree_r (node->children[0]); + FreeTree_r (node->children[1]); + } + + // free brushes + FreeBrushList (node->brushlist); + + // free the node + c_nodes--; + Mem_Free (node); +} + + +/* +============= +FreeTree +============= +*/ +void FreeTree( tree_t *tree ) { + if ( !tree ) { + return; + } + FreeTreePortals_r (tree->headnode); + FreeTree_r (tree->headnode); + Mem_Free (tree); +} + +//=============================================================== + +void PrintTree_r (node_t *node, int depth) +{ + int i; + uBrush_t *bb; + + for (i=0 ; iPrintf(" "); + if (node->planenum == PLANENUM_LEAF) + { + if (!node->brushlist) + common->Printf("NULL\n"); + else + { + for (bb=node->brushlist ; bb ; bb=bb->next) + common->Printf("%i ", bb->original->brushnum); + common->Printf("\n"); + } + return; + } + + idPlane &plane = dmapGlobals.mapPlanes[node->planenum]; + common->Printf( "#%i (%5.2f %5.2f %5.2f %5.2f)\n", node->planenum, + plane[0], plane[1], plane[2], plane[3] ); + PrintTree_r( node->children[0], depth+1 ); + PrintTree_r( node->children[1], depth+1 ); +} + +/* +================ +AllocBspFace +================ +*/ +bspface_t *AllocBspFace( void ) { + bspface_t *f; + + f = (bspface_t *)Mem_Alloc(sizeof(*f)); + memset( f, 0, sizeof(*f) ); + + return f; +} + +/* +================ +FreeBspFace +================ +*/ +void FreeBspFace( bspface_t *f ) { + if ( f->w ) { + delete f->w; + } + Mem_Free( f ); +} + + +/* +================ +SelectSplitPlaneNum +================ +*/ +#define BLOCK_SIZE 1024 +int SelectSplitPlaneNum( node_t *node, bspface_t *list ) { + bspface_t *split; + bspface_t *check; + bspface_t *bestSplit; + int splits, facing, front, back; + int side; + idPlane *mapPlane; + int value, bestValue; + idPlane plane; + int planenum; + bool havePortals; + float dist; + idVec3 halfSize; + + // if it is crossing a 1k block boundary, force a split + // this prevents epsilon problems from extending an + // arbitrary distance across the map + + halfSize = ( node->bounds[1] - node->bounds[0] ) * 0.5f; + for ( int axis = 0; axis < 3; axis++ ) { + if ( halfSize[axis] > BLOCK_SIZE ) { + dist = BLOCK_SIZE * ( floor( ( node->bounds[0][axis] + halfSize[axis] ) / BLOCK_SIZE ) + 1.0f ); + } else { + dist = BLOCK_SIZE * ( floor( node->bounds[0][axis] / BLOCK_SIZE ) + 1.0f ); + } + if ( dist > node->bounds[0][axis] + 1.0f && dist < node->bounds[1][axis] - 1.0f ) { + plane[0] = plane[1] = plane[2] = 0.0f; + plane[axis] = 1.0f; + plane[3] = -dist; + planenum = FindFloatPlane( plane ); + return planenum; + } + } + + // pick one of the face planes + // if we have any portal faces at all, only + // select from them, otherwise select from + // all faces + bestValue = -999999; + bestSplit = list; + + havePortals = false; + for ( split = list ; split ; split = split->next ) { + split->checked = false; + if ( split->portal ) { + havePortals = true; + } + } + + for ( split = list ; split ; split = split->next ) { + if ( split->checked ) { + continue; + } + if ( havePortals != split->portal ) { + continue; + } + mapPlane = &dmapGlobals.mapPlanes[ split->planenum ]; + splits = 0; + facing = 0; + front = 0; + back = 0; + for ( check = list ; check ; check = check->next ) { + if ( check->planenum == split->planenum ) { + facing++; + check->checked = true; // won't need to test this plane again + continue; + } + side = check->w->PlaneSide( *mapPlane ); + if ( side == SIDE_CROSS ) { + splits++; + } else if ( side == SIDE_FRONT ) { + front++; + } else if ( side == SIDE_BACK ) { + back++; + } + } + value = 5*facing - 5*splits; // - abs(front-back); + if ( mapPlane->Type() < PLANETYPE_TRUEAXIAL ) { + value+=5; // axial is better + } + + if ( value > bestValue ) { + bestValue = value; + bestSplit = split; + } + } + + if ( bestValue == -999999 ) { + return -1; + } + + return bestSplit->planenum; +} + +/* +================ +BuildFaceTree_r +================ +*/ +void BuildFaceTree_r( node_t *node, bspface_t *list ) { + bspface_t *split; + bspface_t *next; + int side; + bspface_t *newFace; + bspface_t *childLists[2]; + idWinding *frontWinding, *backWinding; + int i; + int splitPlaneNum; + + splitPlaneNum = SelectSplitPlaneNum( node, list ); + // if we don't have any more faces, this is a node + if ( splitPlaneNum == -1 ) { + node->planenum = PLANENUM_LEAF; + c_faceLeafs++; + return; + } + + // partition the list + node->planenum = splitPlaneNum; + idPlane &plane = dmapGlobals.mapPlanes[ splitPlaneNum ]; + childLists[0] = NULL; + childLists[1] = NULL; + for ( split = list ; split ; split = next ) { + next = split->next; + + if ( split->planenum == node->planenum ) { + FreeBspFace( split ); + continue; + } + + side = split->w->PlaneSide( plane ); + + if ( side == SIDE_CROSS ) { + split->w->Split( plane, CLIP_EPSILON * 2, &frontWinding, &backWinding ); + if ( frontWinding ) { + newFace = AllocBspFace(); + newFace->w = frontWinding; + newFace->next = childLists[0]; + newFace->planenum = split->planenum; + childLists[0] = newFace; + } + if ( backWinding ) { + newFace = AllocBspFace(); + newFace->w = backWinding; + newFace->next = childLists[1]; + newFace->planenum = split->planenum; + childLists[1] = newFace; + } + FreeBspFace( split ); + } else if ( side == SIDE_FRONT ) { + split->next = childLists[0]; + childLists[0] = split; + } else if ( side == SIDE_BACK ) { + split->next = childLists[1]; + childLists[1] = split; + } + } + + + // recursively process children + for ( i = 0 ; i < 2 ; i++ ) { + node->children[i] = AllocNode(); + node->children[i]->parent = node; + node->children[i]->bounds = node->bounds; + } + + // split the bounds if we have a nice axial plane + for ( i = 0 ; i < 3 ; i++ ) { + if ( idMath::Fabs( plane[i] - 1.0 ) < 0.001 ) { + node->children[0]->bounds[0][i] = plane.Dist(); + node->children[1]->bounds[1][i] = plane.Dist(); + break; + } + } + + for ( i = 0 ; i < 2 ; i++ ) { + BuildFaceTree_r ( node->children[i], childLists[i]); + } +} + + +/* +================ +FaceBSP + +List will be freed before returning +================ +*/ +tree_t *FaceBSP( bspface_t *list ) { + tree_t *tree; + bspface_t *face; + int i; + int count; + int start, end; + + start = Sys_Milliseconds(); + + common->Printf( "--- FaceBSP ---\n" ); + + tree = AllocTree (); + + count = 0; + tree->bounds.Clear(); + for ( face = list ; face ; face = face->next ) { + count++; + for ( i = 0 ; i < face->w->GetNumPoints() ; i++ ) { + tree->bounds.AddPoint( (*face->w)[i].ToVec3() ); + } + } + common->Printf( "%5i faces\n", count ); + + tree->headnode = AllocNode(); + tree->headnode->bounds = tree->bounds; + c_faceLeafs = 0; + + BuildFaceTree_r ( tree->headnode, list ); + + common->Printf( "%5i leafs\n", c_faceLeafs ); + + end = Sys_Milliseconds(); + + common->Printf( "%5.1f seconds faceBsp\n", ( end - start ) / 1000.0 ); + + return tree; +} + +//========================================================================== + +/* +================= +MakeStructuralBspFaceList +================= +*/ +bspface_t *MakeStructuralBspFaceList( primitive_t *list ) { + uBrush_t *b; + int i; + side_t *s; + idWinding *w; + bspface_t *f, *flist; + + flist = NULL; + for ( ; list ; list = list->next ) { + b = list->brush; + if ( !b ) { + continue; + } + if ( !b->opaque && !( b->contents & CONTENTS_AREAPORTAL ) ) { + continue; + } + for ( i = 0 ; i < b->numsides ; i++ ) { + s = &b->sides[i]; + w = s->winding; + if ( !w ) { + continue; + } + if ( ( b->contents & CONTENTS_AREAPORTAL ) && ! ( s->material->GetContentFlags() & CONTENTS_AREAPORTAL ) ) { + continue; + } + f = AllocBspFace(); + if ( s->material->GetContentFlags() & CONTENTS_AREAPORTAL ) { + f->portal = true; + } + f->w = w->Copy(); + f->planenum = s->planenum & ~1; + f->next = flist; + flist = f; + } + } + + return flist; +} + +/* +================= +MakeVisibleBspFaceList +================= +*/ +bspface_t *MakeVisibleBspFaceList( primitive_t *list ) { + uBrush_t *b; + int i; + side_t *s; + idWinding *w; + bspface_t *f, *flist; + + flist = NULL; + for ( ; list ; list = list->next ) { + b = list->brush; + if ( !b ) { + continue; + } + if ( !b->opaque && !( b->contents & CONTENTS_AREAPORTAL ) ) { + continue; + } + for ( i = 0 ; i < b->numsides ; i++ ) { + s = &b->sides[i]; + w = s->visibleHull; + if ( !w ) { + continue; + } + f = AllocBspFace(); + if ( s->material->GetContentFlags() & CONTENTS_AREAPORTAL ) { + f->portal = true; + } + f->w = w->Copy(); + f->planenum = s->planenum & ~1; + f->next = flist; + flist = f; + } + } + + return flist; +} + diff --git a/tools/compilers/dmap/gldraw.cpp b/tools/compilers/dmap/gldraw.cpp new file mode 100644 index 000000000..866e57655 --- /dev/null +++ b/tools/compilers/dmap/gldraw.cpp @@ -0,0 +1,283 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +#ifdef WIN32 +#include +#include +#include +//#include + +#define WIN_SIZE 1024 + +void Draw_ClearWindow( void ) { + + if ( !dmapGlobals.drawflag ) { + return; + } + + glDrawBuffer( GL_FRONT ); + + RB_SetGL2D(); + + glClearColor( 0.5, 0.5, 0.5, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + +#if 0 + int w, h, g; + float mx, my; + + w = (dmapGlobals.drawBounds.b[1][0] - dmapGlobals.drawBounds.b[0][0]); + h = (dmapGlobals.drawBounds.b[1][1] - dmapGlobals.drawBounds.b[0][1]); + + mx = dmapGlobals.drawBounds.b[0][0] + w/2; + my = dmapGlobals.drawBounds.b[1][1] + h/2; + + g = w > h ? w : h; + + glLoadIdentity (); + gluPerspective (90, 1, 2, 16384); + gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0); +#else + glMatrixMode( GL_PROJECTION ); + glLoadIdentity (); + glOrtho( dmapGlobals.drawBounds[0][0], dmapGlobals.drawBounds[1][0], + dmapGlobals.drawBounds[0][1], dmapGlobals.drawBounds[1][1], + -1, 1 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +#endif + glColor3f (0,0,0); +// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glDisable (GL_DEPTH_TEST); +// glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +#if 0 +//glColor4f (1,0,0,0.5); +// glBegin( GL_LINE_LOOP ); + glBegin( GL_QUADS ); + + glVertex2f( dmapGlobals.drawBounds.b[0][0] + 20, dmapGlobals.drawBounds.b[0][1] + 20 ); + glVertex2f( dmapGlobals.drawBounds.b[1][0] - 20, dmapGlobals.drawBounds.b[0][1] + 20 ); + glVertex2f( dmapGlobals.drawBounds.b[1][0] - 20, dmapGlobals.drawBounds.b[1][1] - 20 ); + glVertex2f( dmapGlobals.drawBounds.b[0][0] + 20, dmapGlobals.drawBounds.b[1][1] - 20 ); + + glEnd (); +#endif + + glFlush (); + +} + +void Draw_SetRed (void) +{ + if (!dmapGlobals.drawflag) + return; + + glColor3f (1,0,0); +} + +void Draw_SetGrey (void) +{ + if (!dmapGlobals.drawflag) + return; + + glColor3f( 0.5f, 0.5f, 0.5f); +} + +void Draw_SetBlack (void) +{ + if (!dmapGlobals.drawflag) + return; + + glColor3f( 0.0f, 0.0f, 0.0f ); +} + +void DrawWinding ( const idWinding *w ) +{ + int i; + + if (!dmapGlobals.drawflag) + return; + + glColor3f( 0.3f, 0.0f, 0.0f ); + glBegin (GL_POLYGON); + for ( i = 0; i < w->GetNumPoints(); i++ ) + glVertex3f( (*w)[i][0], (*w)[i][1], (*w)[i][2] ); + glEnd (); + + glColor3f( 1, 0, 0 ); + glBegin (GL_LINE_LOOP); + for ( i = 0; i < w->GetNumPoints(); i++ ) + glVertex3f( (*w)[i][0], (*w)[i][1], (*w)[i][2] ); + glEnd (); + + glFlush (); +} + +void DrawAuxWinding ( const idWinding *w) +{ + int i; + + if (!dmapGlobals.drawflag) + return; + + glColor3f( 0.0f, 0.3f, 0.0f ); + glBegin (GL_POLYGON); + for ( i = 0; i < w->GetNumPoints(); i++ ) + glVertex3f( (*w)[i][0], (*w)[i][1], (*w)[i][2] ); + glEnd (); + + glColor3f( 0.0f, 1.0f, 0.0f ); + glBegin (GL_LINE_LOOP); + for ( i = 0; i < w->GetNumPoints(); i++ ) + glVertex3f( (*w)[i][0], (*w)[i][1], (*w)[i][2] ); + glEnd (); + + glFlush (); +} + +void DrawLine( idVec3 v1, idVec3 v2, int color ) { + if (!dmapGlobals.drawflag) + return; + + switch( color ) { + case 0: glColor3f( 0, 0, 0 ); break; + case 1: glColor3f( 0, 0, 1 ); break; + case 2: glColor3f( 0, 1, 0 ); break; + case 3: glColor3f( 0, 1, 1 ); break; + case 4: glColor3f( 1, 0, 0 ); break; + case 5: glColor3f( 1, 0, 1 ); break; + case 6: glColor3f( 1, 1, 0 ); break; + case 7: glColor3f( 1, 1, 1 ); break; + } + + + glBegin( GL_LINES ); + + glVertex3fv( v1.ToFloatPtr() ); + glVertex3fv( v2.ToFloatPtr() ); + + glEnd(); + glFlush(); +} + +//============================================================ + +#define GLSERV_PORT 25001 + +bool wins_init; +int draw_socket; + +void GLS_BeginScene (void) +{ + WSADATA winsockdata; + WORD wVersionRequested; + struct sockaddr_in address; + int r; + + if (!wins_init) + { + wins_init = true; + + wVersionRequested = MAKEWORD(1, 1); + + r = WSAStartup (MAKEWORD(1, 1), &winsockdata); + + if (r) + common->Error( "Winsock initialization failed."); + + } + + // connect a socket to the server + + draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (draw_socket == -1) + common->Error( "draw_socket failed"); + + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + address.sin_port = GLSERV_PORT; + r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address)); + if (r == -1) + { + closesocket (draw_socket); + draw_socket = 0; + } +} + +void GLS_Winding( const idWinding *w, int code ) +{ + byte buf[1024]; + int i, j; + + if (!draw_socket) + return; + + ((int *)buf)[0] = w->GetNumPoints(); + ((int *)buf)[1] = code; + for ( i = 0; i < w->GetNumPoints(); i++ ) + for (j=0 ; j<3 ; j++) + ((float *)buf)[2+i*3+j] = (*w)[i][j]; + + send (draw_socket, (const char *)buf, w->GetNumPoints() * 12 + 8, 0); +} + +void GLS_Triangle( const mapTri_t *tri, int code ) { + idWinding w; + + w.SetNumPoints( 3 ); + VectorCopy( tri->v[0].xyz, w[0] ); + VectorCopy( tri->v[1].xyz, w[1] ); + VectorCopy( tri->v[2].xyz, w[2] ); + GLS_Winding( &w, code ); +} + +void GLS_EndScene (void) +{ + closesocket (draw_socket); + draw_socket = 0; +} +#else +void Draw_ClearWindow( void ) { +} + +void DrawWinding( const idWinding *w) { +} + +void DrawAuxWinding ( const idWinding *w) { +} + +void GLS_Winding( const idWinding *w, int code ) { +} + +void GLS_BeginScene (void) { +} + +void GLS_EndScene (void) +{ +} + +#endif diff --git a/tools/compilers/dmap/glfile.cpp b/tools/compilers/dmap/glfile.cpp new file mode 100644 index 000000000..aad2dd906 --- /dev/null +++ b/tools/compilers/dmap/glfile.cpp @@ -0,0 +1,149 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +int c_glfaces; + +int PortalVisibleSides( uPortal_t *p ) +{ + int fcon, bcon; + + if (!p->onnode) + return 0; // outside + + fcon = p->nodes[0]->opaque; + bcon = p->nodes[1]->opaque; + + // same contents never create a face + if (fcon == bcon) + return 0; + + if (!fcon) + return 1; + if (!bcon) + return 2; + return 0; +} + +void OutputWinding( idWinding *w, idFile *glview ) +{ + static int level = 128; + float light; + int i; + + glview->WriteFloatString( "%i\n", w->GetNumPoints() ); + level += 28; + light = (level&255)/255.0; + for ( i = 0; i < w->GetNumPoints(); i++ ) { + glview->WriteFloatString( "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n", + (*w)[i][0], + (*w)[i][1], + (*w)[i][2], + light, + light, + light ); + } + glview->WriteFloatString( "\n" ); +} + +/* +============= +OutputPortal +============= +*/ +void OutputPortal( uPortal_t *p, idFile *glview ) { + idWinding *w; + int sides; + + sides = PortalVisibleSides( p ); + if ( !sides ) { + return; + } + + c_glfaces++; + + w = p->winding; + + if ( sides == 2 ) { // back side + w = w->Reverse(); + } + + OutputWinding( w, glview ); + + if ( sides == 2 ) { + delete w; + } +} + +/* +============= +WriteGLView_r +============= +*/ +void WriteGLView_r( node_t *node, idFile *glview ) +{ + uPortal_t *p, *nextp; + + if ( node->planenum != PLANENUM_LEAF ) + { + WriteGLView_r( node->children[0], glview ); + WriteGLView_r( node->children[1], glview ); + return; + } + + // write all the portals + for ( p = node->portals; p; p = nextp ) + { + if ( p->nodes[0] == node ) + { + OutputPortal( p, glview ); + nextp = p->next[0]; + } + else { + nextp = p->next[1]; + } + } +} + +/* +============= +WriteGLView +============= +*/ +void WriteGLView( tree_t *tree, char *source ) +{ + idFile *glview; + + c_glfaces = 0; + common->Printf( "Writing %s\n", source ); + + glview = fileSystem->OpenExplicitFileWrite( source ); + if ( !glview ) { + common->Error( "Couldn't open %s", source ); + } + WriteGLView_r( tree->headnode, glview ); + fileSystem->CloseFile( glview ); + + common->Printf( "%5i c_glfaces\n", c_glfaces ); +} + diff --git a/tools/compilers/dmap/leakfile.cpp b/tools/compilers/dmap/leakfile.cpp new file mode 100644 index 000000000..0673dcf8f --- /dev/null +++ b/tools/compilers/dmap/leakfile.cpp @@ -0,0 +1,103 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +/* +============================================================================== + +LEAF FILE GENERATION + +Save out name.line for qe3 to read +============================================================================== +*/ + + +/* +============= +LeakFile + +Finds the shortest possible chain of portals +that leads from the outside leaf to a specifically +occupied leaf +============= +*/ +void LeakFile (tree_t *tree) +{ + idVec3 mid; + FILE *linefile; + idStr filename; + idStr ospath; + node_t *node; + int count; + + if (!tree->outside_node.occupied) + return; + + common->Printf ("--- LeakFile ---\n"); + + // + // write the points to the file + // + sprintf( filename, "%s.lin", dmapGlobals.mapFileBase ); + ospath = fileSystem->RelativePathToOSPath( filename ); + linefile = fopen( ospath, "w" ); + if ( !linefile ) { + common->Error( "Couldn't open %s\n", filename.c_str() ); + } + + count = 0; + node = &tree->outside_node; + while (node->occupied > 1) + { + int next; + uPortal_t *p, *nextportal; + node_t *nextnode; + int s; + + // find the best portal exit + next = node->occupied; + for (p=node->portals ; p ; p = p->next[!s]) + { + s = (p->nodes[0] == node); + if (p->nodes[s]->occupied + && p->nodes[s]->occupied < next) + { + nextportal = p; + nextnode = p->nodes[s]; + next = nextnode->occupied; + } + } + node = nextnode; + mid = nextportal->winding->GetCenter(); + fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]); + count++; + } + // add the occupant center + node->occupant->mapEntity->epairs.GetVector( "origin", "", mid ); + + fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]); + common->Printf ("%5i point linefile\n", count+1); + + fclose (linefile); +} + diff --git a/tools/compilers/dmap/map.cpp b/tools/compilers/dmap/map.cpp new file mode 100644 index 000000000..955a0a6b6 --- /dev/null +++ b/tools/compilers/dmap/map.cpp @@ -0,0 +1,639 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +/* + + After parsing, there will be a list of entities that each has + a list of primitives. + + Primitives are either brushes, triangle soups, or model references. + + Curves are tesselated to triangle soups at load time, but model + references are + Brushes will have + + brushes, each of which has a side definition. + +*/ + +// +// private declarations +// + +#define MAX_BUILD_SIDES 300 + +static int entityPrimitive; // to track editor brush numbers +static int c_numMapPatches; +static int c_areaportals; + +static uEntity_t *uEntity; + +// brushes are parsed into a temporary array of sides, +// which will have duplicates removed before the final brush is allocated +static uBrush_t *buildBrush; + + +#define NORMAL_EPSILON 0.00001f +#define DIST_EPSILON 0.01f + + +/* +=========== +FindFloatPlane +=========== +*/ +int FindFloatPlane( const idPlane &plane, bool *fixedDegeneracies ) { + idPlane p = plane; + bool fixed = p.FixDegeneracies( DIST_EPSILON ); + if ( fixed && fixedDegeneracies ) { + *fixedDegeneracies = true; + } + return dmapGlobals.mapPlanes.FindPlane( p, NORMAL_EPSILON, DIST_EPSILON ); +} + +/* +=========== +SetBrushContents + +The contents on all sides of a brush should be the same +Sets contentsShader, contents, opaque +=========== +*/ +static void SetBrushContents( uBrush_t *b ) { + int contents, c2; + side_t *s; + int i; + bool mixed; + + s = &b->sides[0]; + contents = s->material->GetContentFlags(); + + b->contentShader = s->material; + mixed = false; + + // a brush is only opaque if all sides are opaque + b->opaque = true; + + for ( i=1 ; inumsides ; i++, s++ ) { + s = &b->sides[i]; + + if ( !s->material ) { + continue; + } + + c2 = s->material->GetContentFlags(); + if (c2 != contents) { + mixed = true; + contents |= c2; + } + + if ( s->material->Coverage() != MC_OPAQUE ) { + b->opaque = false; + } + } + + if ( contents & CONTENTS_AREAPORTAL ) { + c_areaportals++; + } + + b->contents = contents; +} + + +//============================================================================ + +/* +=============== +FreeBuildBrush +=============== +*/ +static void FreeBuildBrush( void ) { + int i; + + for ( i = 0 ; i < buildBrush->numsides ; i++ ) { + if ( buildBrush->sides[i].winding ) { + delete buildBrush->sides[i].winding; + } + } + buildBrush->numsides = 0; +} + +/* +=============== +FinishBrush + +Produces a final brush based on the buildBrush->sides array +and links it to the current entity +=============== +*/ +static uBrush_t *FinishBrush( void ) { + uBrush_t *b; + primitive_t *prim; + + // create windings for sides and bounds for brush + if ( !CreateBrushWindings( buildBrush ) ) { + // don't keep this brush + FreeBuildBrush(); + return NULL; + } + + if ( buildBrush->contents & CONTENTS_AREAPORTAL ) { + if (dmapGlobals.num_entities != 1) { + common->Printf("Entity %i, Brush %i: areaportals only allowed in world\n" + , dmapGlobals.num_entities - 1, entityPrimitive); + FreeBuildBrush(); + return NULL; + } + } + + // keep it + b = CopyBrush( buildBrush ); + + FreeBuildBrush(); + + b->entitynum = dmapGlobals.num_entities-1; + b->brushnum = entityPrimitive; + + b->original = b; + + prim = (primitive_t *)Mem_Alloc( sizeof( *prim ) ); + memset( prim, 0, sizeof( *prim ) ); + prim->next = uEntity->primitives; + uEntity->primitives = prim; + + prim->brush = b; + + return b; +} + +/* +================ +AdjustEntityForOrigin +================ +*/ +static void AdjustEntityForOrigin( uEntity_t *ent ) { + primitive_t *prim; + uBrush_t *b; + int i; + side_t *s; + + for ( prim = ent->primitives ; prim ; prim = prim->next ) { + b = prim->brush; + if ( !b ) { + continue; + } + for ( i = 0; i < b->numsides; i++ ) { + idPlane plane; + + s = &b->sides[i]; + + plane = dmapGlobals.mapPlanes[s->planenum]; + plane[3] += plane.Normal() * ent->origin; + + s->planenum = FindFloatPlane( plane ); + + s->texVec.v[0][3] += DotProduct( ent->origin, s->texVec.v[0] ); + s->texVec.v[1][3] += DotProduct( ent->origin, s->texVec.v[1] ); + + // remove any integral shift + s->texVec.v[0][3] -= floor( s->texVec.v[0][3] ); + s->texVec.v[1][3] -= floor( s->texVec.v[1][3] ); + } + CreateBrushWindings(b); + } +} + +/* +================= +RemoveDuplicateBrushPlanes + +Returns false if the brush has a mirrored set of planes, +meaning it encloses no volume. +Also removes planes without any normal +================= +*/ +static bool RemoveDuplicateBrushPlanes( uBrush_t * b ) { + int i, j, k; + side_t *sides; + + sides = b->sides; + + for ( i = 1 ; i < b->numsides ; i++ ) { + + // check for a degenerate plane + if ( sides[i].planenum == -1) { + common->Printf("Entity %i, Brush %i: degenerate plane\n" + , b->entitynum, b->brushnum); + // remove it + for ( k = i + 1 ; k < b->numsides ; k++ ) { + sides[k-1] = sides[k]; + } + b->numsides--; + i--; + continue; + } + + // check for duplication and mirroring + for ( j = 0 ; j < i ; j++ ) { + if ( sides[i].planenum == sides[j].planenum ) { + common->Printf("Entity %i, Brush %i: duplicate plane\n" + , b->entitynum, b->brushnum); + // remove the second duplicate + for ( k = i + 1 ; k < b->numsides ; k++ ) { + sides[k-1] = sides[k]; + } + b->numsides--; + i--; + break; + } + + if ( sides[i].planenum == (sides[j].planenum ^ 1) ) { + // mirror plane, brush is invalid + common->Printf("Entity %i, Brush %i: mirrored plane\n" + , b->entitynum, b->brushnum); + return false; + } + } + } + return true; +} + + +/* +================= +ParseBrush +================= +*/ +static void ParseBrush( const idMapBrush *mapBrush, int primitiveNum ) { + uBrush_t *b; + side_t *s; + const idMapBrushSide *ms; + int i; + bool fixedDegeneracies = false; + + buildBrush->entitynum = dmapGlobals.num_entities-1; + buildBrush->brushnum = entityPrimitive; + buildBrush->numsides = mapBrush->GetNumSides(); + for ( i = 0 ; i < mapBrush->GetNumSides() ; i++ ) { + s = &buildBrush->sides[i]; + ms = mapBrush->GetSide(i); + + memset( s, 0, sizeof( *s ) ); + s->planenum = FindFloatPlane( ms->GetPlane(), &fixedDegeneracies ); + s->material = declManager->FindMaterial( ms->GetMaterial() ); + ms->GetTextureVectors( s->texVec.v ); + // remove any integral shift, which will help with grouping + s->texVec.v[0][3] -= floor( s->texVec.v[0][3] ); + s->texVec.v[1][3] -= floor( s->texVec.v[1][3] ); + } + + // if there are mirrored planes, the entire brush is invalid + if ( !RemoveDuplicateBrushPlanes( buildBrush ) ) { + return; + } + + // get the content for the entire brush + SetBrushContents( buildBrush ); + + b = FinishBrush(); + if ( !b ) { + return; + } + + if ( fixedDegeneracies && dmapGlobals.verboseentities ) { + common->Warning( "brush %d has degenerate plane equations", primitiveNum ); + } +} + +/* +================ +ParseSurface +================ +*/ +static void ParseSurface( const idMapPatch *patch, const idSurface *surface, const idMaterial *material ) { + int i; + mapTri_t *tri; + primitive_t *prim; + + prim = (primitive_t *)Mem_Alloc( sizeof( *prim ) ); + memset( prim, 0, sizeof( *prim ) ); + prim->next = uEntity->primitives; + uEntity->primitives = prim; + + for ( i = 0; i < surface->GetNumIndexes(); i += 3 ) { + tri = AllocTri(); + tri->v[2] = (*surface)[surface->GetIndexes()[i+0]]; + tri->v[1] = (*surface)[surface->GetIndexes()[i+2]]; + tri->v[0] = (*surface)[surface->GetIndexes()[i+1]]; + tri->material = material; + tri->next = prim->tris; + prim->tris = tri; + } + + // set merge groups if needed, to prevent multiple sides from being + // merged into a single surface in the case of gui shaders, mirrors, and autosprites + if ( material->IsDiscrete() ) { + for ( tri = prim->tris ; tri ; tri = tri->next ) { + tri->mergeGroup = (void *)patch; + } + } +} + +/* +================ +ParsePatch +================ +*/ +static void ParsePatch( const idMapPatch *patch, int primitiveNum ) { + const idMaterial *mat; + + if ( dmapGlobals.noCurves ) { + return; + } + + c_numMapPatches++; + + mat = declManager->FindMaterial( patch->GetMaterial() ); + + idSurface_Patch *cp = new idSurface_Patch( *patch ); + + if ( patch->GetExplicitlySubdivided() ) { + cp->SubdivideExplicit( patch->GetHorzSubdivisions(), patch->GetVertSubdivisions(), true ); + } else { + cp->Subdivide( DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_LENGTH, true ); + } + + ParseSurface( patch, cp, mat ); + + delete cp; +} + +/* +================ +ProcessMapEntity +================ +*/ +static bool ProcessMapEntity( idMapEntity *mapEnt ) { + idMapPrimitive *prim; + + uEntity = &dmapGlobals.uEntities[dmapGlobals.num_entities]; + memset( uEntity, 0, sizeof(*uEntity) ); + uEntity->mapEntity = mapEnt; + dmapGlobals.num_entities++; + + for ( entityPrimitive = 0; entityPrimitive < mapEnt->GetNumPrimitives(); entityPrimitive++ ) { + prim = mapEnt->GetPrimitive(entityPrimitive); + + if ( prim->GetType() == idMapPrimitive::TYPE_BRUSH ) { + ParseBrush( static_cast(prim), entityPrimitive ); + } + else if ( prim->GetType() == idMapPrimitive::TYPE_PATCH ) { + ParsePatch( static_cast(prim), entityPrimitive ); + } + } + + // never put an origin on the world, even if the editor left one there + if ( dmapGlobals.num_entities != 1 ) { + uEntity->mapEntity->epairs.GetVector( "origin", "", uEntity->origin ); + } + + return true; +} + +//=================================================================== + +/* +============== +CreateMapLight + +============== +*/ +static void CreateMapLight( const idMapEntity *mapEnt ) { + mapLight_t *light; + bool dynamic; + + // designers can add the "noPrelight" flag to signal that + // the lights will move around, so we don't want + // to bother chopping up the surfaces under it or creating + // shadow volumes + mapEnt->epairs.GetBool( "noPrelight", "0", dynamic ); + if ( dynamic ) { + return; + } + + light = new mapLight_t; + light->name[0] = '\0'; + light->shadowTris = NULL; + + // parse parms exactly as the game do + // use the game's epair parsing code so + // we can use the same renderLight generation + gameEdit->ParseSpawnArgsToRenderLight( &mapEnt->epairs, &light->def.parms ); + + R_DeriveLightData( &light->def ); + + // get the name for naming the shadow surfaces + const char *name; + + mapEnt->epairs.GetString( "name", "", &name ); + + idStr::Copynz( light->name, name, sizeof( light->name ) ); + if ( !light->name[0] ) { + common->Error( "Light at (%f,%f,%f) didn't have a name", + light->def.parms.origin[0], light->def.parms.origin[1], light->def.parms.origin[2] ); + } +#if 0 + // use the renderer code to get the bounding planes for the light + // based on all the parameters + R_RenderLightFrustum( light->parms, light->frustum ); + light->lightShader = light->parms.shader; +#endif + + dmapGlobals.mapLights.Append( light ); + +} + +/* +============== +CreateMapLights + +============== +*/ +static void CreateMapLights( const idMapFile *dmapFile ) { + int i; + const idMapEntity *mapEnt; + const char *value; + + for ( i = 0 ; i < dmapFile->GetNumEntities() ; i++ ) { + mapEnt = dmapFile->GetEntity(i); + mapEnt->epairs.GetString( "classname", "", &value); + if ( !idStr::Icmp( value, "light" ) ) { + CreateMapLight( mapEnt ); + } + + } + +} + +/* +================ +LoadDMapFile +================ +*/ +bool LoadDMapFile( const char *filename ) { + primitive_t *prim; + idBounds mapBounds; + int brushes, triSurfs; + int i; + int size; + + common->Printf( "--- LoadDMapFile ---\n" ); + common->Printf( "loading %s\n", filename ); + + // load and parse the map file into canonical form + dmapGlobals.dmapFile = new idMapFile(); + if ( !dmapGlobals.dmapFile->Parse(filename) ) { + delete dmapGlobals.dmapFile; + dmapGlobals.dmapFile = NULL; + common->Warning( "Couldn't load map file: '%s'", filename ); + return false; + } + + dmapGlobals.mapPlanes.Clear(); + dmapGlobals.mapPlanes.SetGranularity( 1024 ); + + // process the canonical form into utility form + dmapGlobals.num_entities = 0; + c_numMapPatches = 0; + c_areaportals = 0; + + size = dmapGlobals.dmapFile->GetNumEntities() * sizeof( dmapGlobals.uEntities[0] ); + dmapGlobals.uEntities = (uEntity_t *)Mem_Alloc( size ); + memset( dmapGlobals.uEntities, 0, size ); + + // allocate a very large temporary brush for building + // the brushes as they are loaded + buildBrush = AllocBrush( MAX_BUILD_SIDES ); + + for ( i = 0 ; i < dmapGlobals.dmapFile->GetNumEntities() ; i++ ) { + ProcessMapEntity( dmapGlobals.dmapFile->GetEntity(i) ); + } + + CreateMapLights( dmapGlobals.dmapFile ); + + brushes = 0; + triSurfs = 0; + + mapBounds.Clear(); + for ( prim = dmapGlobals.uEntities[0].primitives ; prim ; prim = prim->next ) { + if ( prim->brush ) { + brushes++; + mapBounds.AddBounds( prim->brush->bounds ); + } else if ( prim->tris ) { + triSurfs++; + } + } + + common->Printf( "%5i total world brushes\n", brushes ); + common->Printf( "%5i total world triSurfs\n", triSurfs ); + common->Printf( "%5i patches\n", c_numMapPatches ); + common->Printf( "%5i entities\n", dmapGlobals.num_entities ); + common->Printf( "%5i planes\n", dmapGlobals.mapPlanes.Num() ); + common->Printf( "%5i areaportals\n", c_areaportals ); + common->Printf( "size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", mapBounds[0][0], mapBounds[0][1],mapBounds[0][2], + mapBounds[1][0], mapBounds[1][1], mapBounds[1][2] ); + + return true; +} + +/* +================ +FreeOptimizeGroupList +================ +*/ +void FreeOptimizeGroupList( optimizeGroup_t *groups ) { + optimizeGroup_t *next; + + for ( ; groups ; groups = next ) { + next = groups->nextGroup; + FreeTriList( groups->triList ); + Mem_Free( groups ); + } +} + +/* +================ +FreeDMapFile +================ +*/ +void FreeDMapFile( void ) { + int i, j; + + FreeBrush( buildBrush ); + buildBrush = NULL; + + // free the entities and brushes + for ( i = 0 ; i < dmapGlobals.num_entities ; i++ ) { + uEntity_t *ent; + primitive_t *prim, *nextPrim; + + ent = &dmapGlobals.uEntities[i]; + + FreeTree( ent->tree ); + + // free primitives + for ( prim = ent->primitives ; prim ; prim = nextPrim ) { + nextPrim = prim->next; + if ( prim->brush ) { + FreeBrush( prim->brush ); + } + if ( prim->tris ) { + FreeTriList( prim->tris ); + } + Mem_Free( prim ); + } + + // free area surfaces + if ( ent->areas ) { + for ( j = 0 ; j < ent->numAreas ; j++ ) { + uArea_t *area; + + area = &ent->areas[j]; + FreeOptimizeGroupList( area->groups ); + + } + Mem_Free( ent->areas ); + } + } + + Mem_Free( dmapGlobals.uEntities ); + + dmapGlobals.num_entities = 0; + + // free the map lights + for ( i = 0; i < dmapGlobals.mapLights.Num(); i++ ) { + R_FreeLightDefDerivedData( &dmapGlobals.mapLights[i]->def ); + } + dmapGlobals.mapLights.DeleteContents( true ); +} diff --git a/tools/compilers/dmap/optimize.cpp b/tools/compilers/dmap/optimize.cpp new file mode 100644 index 000000000..8fdb85689 --- /dev/null +++ b/tools/compilers/dmap/optimize.cpp @@ -0,0 +1,1981 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +//#pragma optimize( "", off ) + +#include "dmap.h" +#ifdef WIN32 +#include +#include +#endif + +/* + + New vertexes will be created where edges cross. + + optimization requires an accurate t junction fixer. + + + +*/ + +idBounds optBounds; + +#define MAX_OPT_VERTEXES 0x10000 +int numOptVerts; +optVertex_t optVerts[MAX_OPT_VERTEXES]; + +#define MAX_OPT_EDGES 0x40000 +static int numOptEdges; +static optEdge_t optEdges[MAX_OPT_EDGES]; + +static bool IsTriangleValid( const optVertex_t *v1, const optVertex_t *v2, const optVertex_t *v3 ); +static bool IsTriangleDegenerate( const optVertex_t *v1, const optVertex_t *v2, const optVertex_t *v3 ); + +static idRandom orandom; + +/* +============== +ValidateEdgeCounts +============== +*/ +static void ValidateEdgeCounts( optIsland_t *island ) { + optVertex_t *vert; + optEdge_t *e; + int c; + + for ( vert = island->verts ; vert ; vert = vert->islandLink ) { + c = 0; + for ( e = vert->edges ; e ; ) { + c++; + if ( e->v1 == vert ) { + e = e->v1link; + } else if ( e->v2 == vert ) { + e = e->v2link; + } else { + common->Error( "ValidateEdgeCounts: mislinked" ); + } + } + if ( c != 2 && c != 0 ) { + // this can still happen at diamond intersections +// common->Printf( "ValidateEdgeCounts: %i edges\n", c ); + } + } +} + + +/* +==================== +AllocEdge +==================== +*/ +static optEdge_t *AllocEdge( void ) { + optEdge_t *e; + + if ( numOptEdges == MAX_OPT_EDGES ) { + common->Error( "MAX_OPT_EDGES" ); + } + e = &optEdges[ numOptEdges ]; + numOptEdges++; + memset( e, 0, sizeof( *e ) ); + + return e; +} + +/* +==================== +RemoveEdgeFromVert +==================== +*/ +static void RemoveEdgeFromVert( optEdge_t *e1, optVertex_t *vert ) { + optEdge_t **prev; + optEdge_t *e; + + if ( !vert ) { + return; + } + prev = &vert->edges; + while ( *prev ) { + e = *prev; + if ( e == e1 ) { + if ( e1->v1 == vert ) { + *prev = e1->v1link; + } else if ( e1->v2 == vert ) { + *prev = e1->v2link; + } else { + common->Error( "RemoveEdgeFromVert: vert not found" ); + } + return; + } + + if ( e->v1 == vert ) { + prev = &e->v1link; + } else if ( e->v2 == vert ) { + prev = &e->v2link; + } else { + common->Error( "RemoveEdgeFromVert: vert not found" ); + } + } +} + +/* +==================== +UnlinkEdge +==================== +*/ +static void UnlinkEdge( optEdge_t *e, optIsland_t *island ) { + optEdge_t **prev; + + RemoveEdgeFromVert( e, e->v1 ); + RemoveEdgeFromVert( e, e->v2 ); + + for ( prev = &island->edges ; *prev ; prev = &(*prev)->islandLink ) { + if ( *prev == e ) { + *prev = e->islandLink; + return; + } + } + + common->Error( "RemoveEdgeFromIsland: couldn't free edge" ); +} + + +/* +==================== +LinkEdge +==================== +*/ +static void LinkEdge( optEdge_t *e ) { + e->v1link = e->v1->edges; + e->v1->edges = e; + + e->v2link = e->v2->edges; + e->v2->edges = e; +} + +#ifdef __linux__ + +optVertex_t *FindOptVertex( idDrawVert *v, optimizeGroup_t *opt ); + +#else + +/* +================ +FindOptVertex +================ +*/ +static optVertex_t *FindOptVertex( idDrawVert *v, optimizeGroup_t *opt ) { + int i; + float x, y; + optVertex_t *vert; + + // deal with everything strictly as 2D + x = v->xyz * opt->axis[0]; + y = v->xyz * opt->axis[1]; + + // should we match based on the t-junction fixing hash verts? + for ( i = 0 ; i < numOptVerts ; i++ ) { + if ( optVerts[i].pv[0] == x && optVerts[i].pv[1] == y ) { + return &optVerts[i]; + } + } + + if ( numOptVerts >= MAX_OPT_VERTEXES ) { + common->Error( "MAX_OPT_VERTEXES" ); + return NULL; + } + + numOptVerts++; + + vert = &optVerts[i]; + memset( vert, 0, sizeof( *vert ) ); + vert->v = *v; + vert->pv[0] = x; + vert->pv[1] = y; + vert->pv[2] = 0; + + optBounds.AddPoint( vert->pv ); + + return vert; +} + +#endif + +/* +================ +DrawAllEdges +================ +*/ +static void DrawAllEdges( void ) { + int i; + + if ( !dmapGlobals.drawflag ) { + return; + } + + Draw_ClearWindow(); + + qglBegin( GL_LINES ); + for ( i = 0 ; i < numOptEdges ; i++ ) { + if ( optEdges[i].v1 == NULL ) { + continue; + } + qglColor3f( 1, 0, 0 ); + qglVertex3fv( optEdges[i].v1->pv.ToFloatPtr() ); + qglColor3f( 0, 0, 0 ); + qglVertex3fv( optEdges[i].v2->pv.ToFloatPtr() ); + } + qglEnd(); + qglFlush(); + +// GLimp_SwapBuffers(); +} + +/* +================ +DrawVerts +================ +*/ +static void DrawVerts( optIsland_t *island ) { + optVertex_t *vert; + + if ( !dmapGlobals.drawflag ) { + return; + } + + qglEnable( GL_BLEND ); + qglBlendFunc( GL_ONE, GL_ONE ); + qglColor3f( 0.3f, 0.3f, 0.3f ); + qglPointSize( 3 ); + qglBegin( GL_POINTS ); + for ( vert = island->verts ; vert ; vert = vert->islandLink ) { + qglVertex3fv( vert->pv.ToFloatPtr() ); + } + qglEnd(); + qglDisable( GL_BLEND ); + qglFlush(); +} + +/* +================ +DrawEdges +================ +*/ +static void DrawEdges( optIsland_t *island ) { + optEdge_t *edge; + + if ( !dmapGlobals.drawflag ) { + return; + } + + Draw_ClearWindow(); + + qglBegin( GL_LINES ); + for ( edge = island->edges ; edge ; edge = edge->islandLink ) { + if ( edge->v1 == NULL ) { + continue; + } + qglColor3f( 1, 0, 0 ); + qglVertex3fv( edge->v1->pv.ToFloatPtr() ); + qglColor3f( 0, 0, 0 ); + qglVertex3fv( edge->v2->pv.ToFloatPtr() ); + } + qglEnd(); + qglFlush(); + +// GLimp_SwapBuffers(); +} + +//================================================================= + +/* +================= +VertexBetween +================= +*/ +static bool VertexBetween( const optVertex_t *p1, const optVertex_t *v1, const optVertex_t *v2 ) { + idVec3 d1, d2; + float d; + + d1 = p1->pv - v1->pv; + d2 = p1->pv - v2->pv; + d = d1 * d2; + if ( d < 0 ) { + return true; + } + return false; +} + + +/* +==================== +EdgeIntersection + +Creates a new optVertex_t where the line segments cross. +This should only be called if PointsStraddleLine returned true + +Will return NULL if the lines are colinear +==================== +*/ +static optVertex_t *EdgeIntersection( const optVertex_t *p1, const optVertex_t *p2, + const optVertex_t *l1, const optVertex_t *l2, optimizeGroup_t *opt ) { + float f; + idDrawVert *v; + idVec3 dir1, dir2, cross1, cross2; + + dir1 = p1->pv - l1->pv; + dir2 = p1->pv - l2->pv; + cross1 = dir1.Cross( dir2 ); + + dir1 = p2->pv - l1->pv; + dir2 = p2->pv - l2->pv; + cross2 = dir1.Cross( dir2 ); + + if ( cross1[2] - cross2[2] == 0 ) { + return NULL; + } + + f = cross1[2] / ( cross1[2] - cross2[2] ); + + // FIXME: how are we freeing this, since it doesn't belong to a tri? + v = (idDrawVert *)Mem_Alloc( sizeof( *v ) ); + memset( v, 0, sizeof( *v ) ); + + v->xyz = p1->v.xyz * ( 1.0 - f ) + p2->v.xyz * f; + v->normal = p1->v.normal * ( 1.0 - f ) + p2->v.normal * f; + v->normal.Normalize(); + v->st[0] = p1->v.st[0] * ( 1.0 - f ) + p2->v.st[0] * f; + v->st[1] = p1->v.st[1] * ( 1.0 - f ) + p2->v.st[1] * f; + + return FindOptVertex( v, opt ); +} + + +/* +==================== +PointsStraddleLine + +Colinear is considdered crossing. +==================== +*/ +static bool PointsStraddleLine( optVertex_t *p1, optVertex_t *p2, optVertex_t *l1, optVertex_t *l2 ) { + bool t1, t2; + + t1 = IsTriangleDegenerate( l1, l2, p1 ); + t2 = IsTriangleDegenerate( l1, l2, p2 ); + if ( t1 && t2 ) { + // colinear case + float s1, s2, s3, s4; + bool positive, negative; + + s1 = ( p1->pv - l1->pv ) * ( l2->pv - l1->pv ); + s2 = ( p2->pv - l1->pv ) * ( l2->pv - l1->pv ); + s3 = ( p1->pv - l2->pv ) * ( l2->pv - l1->pv ); + s4 = ( p2->pv - l2->pv ) * ( l2->pv - l1->pv ); + + if ( s1 > 0 || s2 > 0 || s3 > 0 || s4 > 0 ) { + positive = true; + } else { + positive = false; + } + if ( s1 < 0 || s2 < 0 || s3 < 0 || s4 < 0 ) { + negative = true; + } else { + negative = false; + } + + if ( positive && negative ) { + return true; + } + return false; + } else if ( p1 != l1 && p1 != l2 && p2 != l1 && p2 != l2 ) { + // no shared verts + t1 = IsTriangleValid( l1, l2, p1 ); + t2 = IsTriangleValid( l1, l2, p2 ); + if ( t1 && t2 ) { + return false; + } + + t1 = IsTriangleValid( l1, p1, l2 ); + t2 = IsTriangleValid( l1, p2, l2 ); + if ( t1 && t2 ) { + return false; + } + + return true; + } else { + // a shared vert, not colinear, so not crossing + return false; + } +} + + +/* +==================== +EdgesCross +==================== +*/ +static bool EdgesCross( optVertex_t *a1, optVertex_t *a2, optVertex_t *b1, optVertex_t *b2 ) { + // if both verts match, consider it to be crossed + if ( a1 == b1 && a2 == b2 ) { + return true; + } + if ( a1 == b2 && a2 == b1 ) { + return true; + } + // if only one vert matches, it might still be colinear, which + // would be considered crossing + + // if both lines' verts are on opposite sides of the other + // line, it is crossed + if ( !PointsStraddleLine( a1, a2, b1, b2 ) ) { + return false; + } + if ( !PointsStraddleLine( b1, b2, a1, a2 ) ) { + return false; + } + + return true; +} + +/* +==================== +TryAddNewEdge + +==================== +*/ +static bool TryAddNewEdge( optVertex_t *v1, optVertex_t *v2, optIsland_t *island ) { + optEdge_t *e; + + // if the new edge crosses any other edges, don't add it + for ( e = island->edges ; e ; e = e->islandLink ) { + if ( EdgesCross( e->v1, e->v2, v1, v2 ) ) { + return false; + } + } + + if ( dmapGlobals.drawflag ) { + qglBegin( GL_LINES ); + qglColor3f( 0, ( 128 + orandom.RandomInt( 127 ) )/ 255.0, 0 ); + qglVertex3fv( v1->pv.ToFloatPtr() ); + qglVertex3fv( v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + // add it + e = AllocEdge(); + + e->islandLink = island->edges; + island->edges = e; + e->v1 = v1; + e->v2 = v2; + + e->created = true; + + // link the edge to its verts + LinkEdge( e ); + + return true; +} + +typedef struct { + optVertex_t *v1, *v2; + float length; +} edgeLength_t; + + +static int LengthSort( const void *a, const void *b ) { + const edgeLength_t *ea, *eb; + + ea = (const edgeLength_t *)a; + eb = (const edgeLength_t *)b; + if ( ea->length < eb->length ) { + return -1; + } + if ( ea->length > eb->length ) { + return 1; + } + return 0; +} + +/* +================== +AddInteriorEdges + +Add all possible edges between the verts +================== +*/ +static void AddInteriorEdges( optIsland_t *island ) { + int c_addedEdges; + optVertex_t *vert, *vert2; + int c_verts; + edgeLength_t *lengths; + int numLengths; + int i; + + DrawVerts( island ); + + // count the verts + c_verts = 0; + for ( vert = island->verts ; vert ; vert = vert->islandLink ) { + if ( !vert->edges ) { + continue; + } + c_verts++; + } + + // allocate space for all the lengths + lengths = (edgeLength_t *)Mem_Alloc( sizeof( *lengths ) * c_verts * c_verts / 2 ); + numLengths = 0; + for ( vert = island->verts ; vert ; vert = vert->islandLink ) { + if ( !vert->edges ) { + continue; + } + for ( vert2 = vert->islandLink ; vert2 ; vert2 = vert2->islandLink ) { + idVec3 dir; + + if ( !vert2->edges ) { + continue; + } + lengths[numLengths].v1 = vert; + lengths[numLengths].v2 = vert2; + dir = ( vert->pv - vert2->pv ) ; + lengths[numLengths].length = dir.Length(); + numLengths++; + } + } + + + // sort by length, shortest first + qsort( lengths, numLengths, sizeof( lengths[0] ), LengthSort ); + + // try to create them in that order + c_addedEdges = 0; + for ( i = 0 ; i < numLengths ; i++ ) { + if ( TryAddNewEdge( lengths[i].v1, lengths[i].v2, island ) ) { + c_addedEdges++; + } + } + + if ( dmapGlobals.verbose ) { + common->Printf( "%6i tested segments\n", numLengths ); + common->Printf( "%6i added interior edges\n", c_addedEdges ); + } + + Mem_Free( lengths ); +} + + + +//================================================================== + +/* +==================== +RemoveIfColinear + +==================== +*/ +#define COLINEAR_EPSILON 0.1 +static void RemoveIfColinear( optVertex_t *ov, optIsland_t *island ) { + optEdge_t *e, *e1, *e2; + optVertex_t *v1, *v2, *v3; + idVec3 dir1, dir2; + float len, dist; + idVec3 point; + idVec3 offset; + float off; + + v2 = ov; + + // we must find exactly two edges before testing for colinear + e1 = NULL; + e2 = NULL; + for ( e = ov->edges ; e ; ) { + if ( !e1 ) { + e1 = e; + } else if ( !e2 ) { + e2 = e; + } else { + return; // can't remove a vertex with three edges + } + if ( e->v1 == v2 ) { + e = e->v1link; + } else if ( e->v2 == v2 ) { + e = e->v2link; + } else { + common->Error( "RemoveIfColinear: mislinked edge" ); + } + } + + // can't remove if no edges + if ( !e1 ) { + return; + } + + if ( !e2 ) { + // this may still happen legally when a tiny triangle is + // the only thing in a group + common->Printf( "WARNING: vertex with only one edge\n" ); + return; + } + + if ( e1->v1 == v2 ) { + v1 = e1->v2; + } else if ( e1->v2 == v2 ) { + v1 = e1->v1; + } else { + common->Error( "RemoveIfColinear: mislinked edge" ); + } + if ( e2->v1 == v2 ) { + v3 = e2->v2; + } else if ( e2->v2 == v2 ) { + v3 = e2->v1; + } else { + common->Error( "RemoveIfColinear: mislinked edge" ); + } + + if ( v1 == v3 ) { + common->Error( "RemoveIfColinear: mislinked edge" ); + } + + // they must point in opposite directions + dist = ( v3->pv - v2->pv ) * ( v1->pv - v2->pv ); + if ( dist >= 0 ) { + return; + } + + // see if they are colinear + VectorSubtract( v3->v.xyz, v1->v.xyz, dir1 ); + len = dir1.Normalize(); + VectorSubtract( v2->v.xyz, v1->v.xyz, dir2 ); + dist = DotProduct( dir2, dir1 ); + VectorMA( v1->v.xyz, dist, dir1, point ); + VectorSubtract( point, v2->v.xyz, offset ); + off = offset.Length(); + + if ( off > COLINEAR_EPSILON ) { + return; + } + + if ( dmapGlobals.drawflag ) { + qglBegin( GL_LINES ); + qglColor3f( 1, 1, 0 ); + qglVertex3fv( v1->pv.ToFloatPtr() ); + qglVertex3fv( v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + qglBegin( GL_LINES ); + qglColor3f( 0, 1, 1 ); + qglVertex3fv( v2->pv.ToFloatPtr() ); + qglVertex3fv( v3->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + + // replace the two edges with a single edge + UnlinkEdge( e1, island ); + UnlinkEdge( e2, island ); + + // v2 should have no edges now + if ( v2->edges ) { + common->Error( "RemoveIfColinear: didn't remove properly" ); + } + + + // if there is an existing edge that already + // has these exact verts, we have just collapsed a + // sliver triangle out of existance, and all the edges + // can be removed + for ( e = island->edges ; e ; e = e->islandLink ) { + if ( ( e->v1 == v1 && e->v2 == v3 ) + || ( e->v1 == v3 && e->v2 == v1 ) ) { + UnlinkEdge( e, island ); + RemoveIfColinear( v1, island ); + RemoveIfColinear( v3, island ); + return; + } + } + + // if we can't add the combined edge, link + // the originals back in + if ( !TryAddNewEdge( v1, v3, island ) ) { + e1->islandLink = island->edges; + island->edges = e1; + LinkEdge( e1 ); + + e2->islandLink = island->edges; + island->edges = e2; + LinkEdge( e2 ); + return; + } + + // recursively try to combine both verts now, + // because things may have changed since the last combine test + RemoveIfColinear( v1, island ); + RemoveIfColinear( v3, island ); +} + +/* +==================== +CombineColinearEdges +==================== +*/ +static void CombineColinearEdges( optIsland_t *island ) { + int c_edges; + optVertex_t *ov; + optEdge_t *e; + + c_edges = 0; + for ( e = island->edges ; e ; e = e->islandLink ) { + c_edges++; + } + if ( dmapGlobals.verbose ) { + common->Printf( "%6i original exterior edges\n", c_edges ); + } + + for ( ov = island->verts ; ov ; ov = ov->islandLink ) { + RemoveIfColinear( ov, island ); + } + + c_edges = 0; + for ( e = island->edges ; e ; e = e->islandLink ) { + c_edges++; + } + if ( dmapGlobals.verbose ) { + common->Printf( "%6i optimized exterior edges\n", c_edges ); + } +} + + +//================================================================== + +/* +=================== +FreeOptTriangles + +=================== +*/ +static void FreeOptTriangles( optIsland_t *island ) { + optTri_t *opt, *next; + + for ( opt = island->tris ; opt ; opt = next ) { + next = opt->next; + Mem_Free( opt ); + } + + island->tris = NULL; +} + + +/* +================= +IsTriangleValid + +empty area will be considered invalid. +Due to some truly aweful epsilon issues, a triangle can switch between +valid and invalid depending on which order you look at the verts, so +consider it invalid if any one of the possibilities is invalid. +================= +*/ +static bool IsTriangleValid( const optVertex_t *v1, const optVertex_t *v2, const optVertex_t *v3 ) { + idVec3 d1, d2, normal; + + d1 = v2->pv - v1->pv; + d2 = v3->pv - v1->pv; + normal = d1.Cross( d2 ); + if ( normal[2] <= 0 ) { + return false; + } + + d1 = v3->pv - v2->pv; + d2 = v1->pv - v2->pv; + normal = d1.Cross( d2 ); + if ( normal[2] <= 0 ) { + return false; + } + + d1 = v1->pv - v3->pv; + d2 = v2->pv - v3->pv; + normal = d1.Cross( d2 ); + if ( normal[2] <= 0 ) { + return false; + } + + return true; +} + + +/* +================= +IsTriangleDegenerate + +Returns false if it is either front or back facing +================= +*/ +static bool IsTriangleDegenerate( const optVertex_t *v1, const optVertex_t *v2, const optVertex_t *v3 ) { +#if 1 + idVec3 d1, d2, normal; + + d1 = v2->pv - v1->pv; + d2 = v3->pv - v1->pv; + normal = d1.Cross( d2 ); + if ( normal[2] == 0 ) { + return true; + } + return false; +#else + return (bool)!IsTriangleValid( v1, v2, v3 ); +#endif +} + + +/* +================== +PointInTri + +Tests if a 2D point is inside an original triangle +================== +*/ +static bool PointInTri( const idVec3 &p, const mapTri_t *tri, optIsland_t *island ) { + idVec3 d1, d2, normal; + + // the normal[2] == 0 case is not uncommon when a square is triangulated in + // the opposite manner to the original + + d1 = tri->optVert[0]->pv - p; + d2 = tri->optVert[1]->pv - p; + normal = d1.Cross( d2 ); + if ( normal[2] < 0 ) { + return false; + } + + d1 = tri->optVert[1]->pv - p; + d2 = tri->optVert[2]->pv - p; + normal = d1.Cross( d2 ); + if ( normal[2] < 0 ) { + return false; + } + + d1 = tri->optVert[2]->pv - p; + d2 = tri->optVert[0]->pv - p; + normal = d1.Cross( d2 ); + if ( normal[2] < 0 ) { + return false; + } + + return true; +} + + +/* +==================== +LinkTriToEdge + +==================== +*/ +static void LinkTriToEdge( optTri_t *optTri, optEdge_t *edge ) { + if ( ( edge->v1 == optTri->v[0] && edge->v2 == optTri->v[1] ) + || ( edge->v1 == optTri->v[1] && edge->v2 == optTri->v[2] ) + || ( edge->v1 == optTri->v[2] && edge->v2 == optTri->v[0] ) ) { + if ( edge->backTri ) { + common->Printf( "Warning: LinkTriToEdge: already in use\n" ); + return; + } + edge->backTri = optTri; + return; + } + if ( ( edge->v1 == optTri->v[1] && edge->v2 == optTri->v[0] ) + || ( edge->v1 == optTri->v[2] && edge->v2 == optTri->v[1] ) + || ( edge->v1 == optTri->v[0] && edge->v2 == optTri->v[2] ) ) { + if ( edge->frontTri ) { + common->Printf( "Warning: LinkTriToEdge: already in use\n" ); + return; + } + edge->frontTri = optTri; + return; + } + common->Error( "LinkTriToEdge: edge not found on tri" ); +} + +/* +=============== +CreateOptTri +=============== +*/ +static void CreateOptTri( optVertex_t *first, optEdge_t *e1, optEdge_t *e2, optIsland_t *island ) { + optEdge_t *opposite; + optVertex_t *second, *third; + optTri_t *optTri; + mapTri_t *tri; + + if ( e1->v1 == first ) { + second = e1->v2; + } else if ( e1->v2 == first ) { + second = e1->v1; + } else { + common->Error( "CreateOptTri: mislinked edge" ); + } + + if ( e2->v1 == first ) { + third = e2->v2; + } else if ( e2->v2 == first ) { + third = e2->v1; + } else { + common->Error( "CreateOptTri: mislinked edge" ); + } + + if ( !IsTriangleValid( first, second, third ) ) { + common->Error( "CreateOptTri: invalid" ); + } + +//DrawEdges( island ); + + // identify the third edge + if ( dmapGlobals.drawflag ) { + qglColor3f(1,1,0); + qglBegin( GL_LINES ); + qglVertex3fv( e1->v1->pv.ToFloatPtr() ); + qglVertex3fv( e1->v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + qglColor3f(0,1,1); + qglBegin( GL_LINES ); + qglVertex3fv( e2->v1->pv.ToFloatPtr() ); + qglVertex3fv( e2->v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + + for ( opposite = second->edges ; opposite ; ) { + if ( opposite != e1 && ( opposite->v1 == third || opposite->v2 == third ) ) { + break; + } + if ( opposite->v1 == second ) { + opposite = opposite->v1link; + } else if ( opposite->v2 == second ) { + opposite = opposite->v2link; + } else { + common->Error( "BuildOptTriangles: mislinked edge" ); + } + } + + if ( !opposite ) { + common->Printf( "Warning: BuildOptTriangles: couldn't locate opposite\n" ); + return; + } + + if ( dmapGlobals.drawflag ) { + qglColor3f(1,0,1); + qglBegin( GL_LINES ); + qglVertex3fv( opposite->v1->pv.ToFloatPtr() ); + qglVertex3fv( opposite->v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + + // create new triangle + optTri = (optTri_t *)Mem_Alloc( sizeof( *optTri ) ); + optTri->v[0] = first; + optTri->v[1] = second; + optTri->v[2] = third; + optTri->midpoint = ( optTri->v[0]->pv + optTri->v[1]->pv + optTri->v[2]->pv ) * ( 1.0f / 3.0f ); + optTri->next = island->tris; + island->tris = optTri; + + if ( dmapGlobals.drawflag ) { + qglColor3f( 1, 1, 1 ); + qglPointSize( 4 ); + qglBegin( GL_POINTS ); + qglVertex3fv( optTri->midpoint.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + + // find the midpoint, and scan through all the original triangles to + // see if it is inside any of them + for ( tri = island->group->triList ; tri ; tri = tri->next ) { + if ( PointInTri( optTri->midpoint, tri, island ) ) { + break; + } + } + if ( tri ) { + optTri->filled = true; + } else { + optTri->filled = false; + } + if ( dmapGlobals.drawflag ) { + if ( optTri->filled ) { + qglColor3f( ( 128 + orandom.RandomInt( 127 ) )/ 255.0, 0, 0 ); + } else { + qglColor3f( 0, ( 128 + orandom.RandomInt( 127 ) ) / 255.0, 0 ); + } + qglBegin( GL_TRIANGLES ); + qglVertex3fv( optTri->v[0]->pv.ToFloatPtr() ); + qglVertex3fv( optTri->v[1]->pv.ToFloatPtr() ); + qglVertex3fv( optTri->v[2]->pv.ToFloatPtr() ); + qglEnd(); + qglColor3f( 1, 1, 1 ); + qglBegin( GL_LINE_LOOP ); + qglVertex3fv( optTri->v[0]->pv.ToFloatPtr() ); + qglVertex3fv( optTri->v[1]->pv.ToFloatPtr() ); + qglVertex3fv( optTri->v[2]->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + + // link the triangle to it's edges + LinkTriToEdge( optTri, e1 ); + LinkTriToEdge( optTri, e2 ); + LinkTriToEdge( optTri, opposite ); +} + +// debugging tool +static void ReportNearbyVertexes( const optVertex_t *v, const optIsland_t *island ) { + const optVertex_t *ov; + float d; + idVec3 vec; + + common->Printf( "verts near 0x%p (%f, %f)\n", v, v->pv[0], v->pv[1] ); + for ( ov = island->verts ; ov ; ov = ov->islandLink ) { + if ( ov == v ) { + continue; + } + + vec = ov->pv - v->pv; + + d = vec.Length(); + if ( d < 1 ) { + common->Printf( "0x%p = (%f, %f)\n", ov, ov->pv[0], ov->pv[1] ); + } + } +} + +/* +==================== +BuildOptTriangles + +Generate a new list of triangles from the optEdeges +==================== +*/ +static void BuildOptTriangles( optIsland_t *island ) { + optVertex_t *ov, *second, *third, *middle; + optEdge_t *e1, *e1Next, *e2, *e2Next, *check, *checkNext; + + // free them + FreeOptTriangles( island ); + + // clear the vertex emitted flags + for ( ov = island->verts ; ov ; ov = ov->islandLink ) { + ov->emited = false; + } + + // clear the edge triangle links + for ( check = island->edges ; check ; check = check->islandLink ) { + check->frontTri = check->backTri = NULL; + } + + // check all possible triangle made up out of the + // edges coming off the vertex + for ( ov = island->verts ; ov ; ov = ov->islandLink ) { + if ( !ov->edges ) { + continue; + } + +#if 0 +if ( dmapGlobals.drawflag && ov == (optVertex_t *)0x1845a60 ) { +for ( e1 = ov->edges ; e1 ; e1 = e1Next ) { + qglBegin( GL_LINES ); + qglColor3f( 0,1,0 ); + qglVertex3fv( e1->v1->pv.ToFloatPtr() ); + qglVertex3fv( e1->v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + if ( e1->v1 == ov ) { + e1Next = e1->v1link; + } else if ( e1->v2 == ov ) { + e1Next = e1->v2link; + } +} +} +#endif + for ( e1 = ov->edges ; e1 ; e1 = e1Next ) { + if ( e1->v1 == ov ) { + second = e1->v2; + e1Next = e1->v1link; + } else if ( e1->v2 == ov ) { + second = e1->v1; + e1Next = e1->v2link; + } else { + common->Error( "BuildOptTriangles: mislinked edge" ); + } + + // if the vertex has already been used, it can't be used again + if ( second->emited ) { + continue; + } + + for ( e2 = ov->edges ; e2 ; e2 = e2Next ) { + if ( e2->v1 == ov ) { + third = e2->v2; + e2Next = e2->v1link; + } else if ( e2->v2 == ov ) { + third = e2->v1; + e2Next = e2->v2link; + } else { + common->Error( "BuildOptTriangles: mislinked edge" ); + } + if ( e2 == e1 ) { + continue; + } + + // if the vertex has already been used, it can't be used again + if ( third->emited ) { + continue; + } + + // if the triangle is backwards or degenerate, don't use it + if ( !IsTriangleValid( ov, second, third ) ) { + continue; + } + + // see if any other edge bisects these two, which means + // this triangle shouldn't be used + for ( check = ov->edges ; check ; check = checkNext ) { + if ( check->v1 == ov ) { + middle = check->v2; + checkNext = check->v1link; + } else if ( check->v2 == ov ) { + middle = check->v1; + checkNext = check->v2link; + } else { + common->Error( "BuildOptTriangles: mislinked edge" ); + } + + if ( check == e1 || check == e2 ) { + continue; + } + + if ( IsTriangleValid( ov, second, middle ) + && IsTriangleValid( ov, middle, third ) ) { + break; // should use the subdivided ones + } + } + + if ( check ) { + continue; // don't use it + } + + // the triangle is valid + CreateOptTri( ov, e1, e2, island ); + } + } + + // later vertexes will not emit triangles that use an + // edge that this vert has already used + ov->emited = true; + } +} + + + +/* +==================== +RegenerateTriangles + +Add new triangles to the group's regeneratedTris +==================== +*/ +static void RegenerateTriangles( optIsland_t *island ) { + optTri_t *optTri; + mapTri_t *tri; + int c_out; + + c_out = 0; + + for ( optTri = island->tris ; optTri ; optTri = optTri->next ) { + if ( !optTri->filled ) { + continue; + } + + // create a new mapTri_t + tri = AllocTri(); + + tri->material = island->group->material; + tri->mergeGroup = island->group->mergeGroup; + + tri->v[0] = optTri->v[0]->v; + tri->v[1] = optTri->v[1]->v; + tri->v[2] = optTri->v[2]->v; + + idPlane plane; + PlaneForTri( tri, plane ); + if ( plane.Normal() * dmapGlobals.mapPlanes[ island->group->planeNum ].Normal() <= 0 ) { + // this can happen reasonably when a triangle is nearly degenerate in + // optimization planar space, and winds up being degenerate in 3D space + common->Printf( "WARNING: backwards triangle generated!\n" ); + // discard it + FreeTri( tri ); + continue; + } + + c_out++; + tri->next = island->group->regeneratedTris; + island->group->regeneratedTris = tri; + } + + FreeOptTriangles( island ); + + if ( dmapGlobals.verbose ) { + common->Printf( "%6i tris out\n", c_out ); + } +} + +//=========================================================================== + +/* +==================== +RemoveInteriorEdges + +Edges that have triangles of the same type (filled / empty) +on both sides will be removed +==================== +*/ +static void RemoveInteriorEdges( optIsland_t *island ) { + int c_interiorEdges; + int c_exteriorEdges; + optEdge_t *e, *next; + bool front, back; + + c_exteriorEdges = 0; + c_interiorEdges = 0; + for ( e = island->edges ; e ; e = next ) { + // we might remove the edge, so get the next link now + next = e->islandLink; + + if ( !e->frontTri ) { + front = false; + } else { + front = e->frontTri->filled; + } + if ( !e->backTri ) { + back = false; + } else { + back = e->backTri->filled; + } + + if ( front == back ) { + // free the edge + UnlinkEdge( e, island ); + c_interiorEdges++; + continue; + } + + c_exteriorEdges++; + } + + if ( dmapGlobals.verbose ) { + common->Printf( "%6i original interior edges\n", c_interiorEdges ); + common->Printf( "%6i original exterior edges\n", c_exteriorEdges ); + } +} + +//================================================================================== + +typedef struct { + optVertex_t *v1, *v2; +} originalEdges_t; + +/* +================= +AddEdgeIfNotAlready +================= +*/ +void AddEdgeIfNotAlready( optVertex_t *v1, optVertex_t *v2 ) { + optEdge_t *e; + + // make sure that there isn't an identical edge already added + for ( e = v1->edges ; e ; ) { + if ( ( e->v1 == v1 && e->v2 == v2 ) || ( e->v1 == v2 && e->v2 == v1 ) ) { + return; // already added + } + if ( e->v1 == v1 ) { + e = e->v1link; + } else if ( e->v2 == v1 ) { + e = e->v2link; + } else { + common->Error( "SplitEdgeByList: bad edge link" ); + } + } + + // this edge is a keeper + e = AllocEdge(); + e->v1 = v1; + e->v2 = v2; + + e->islandLink = NULL; + + // link the edge to its verts + LinkEdge( e ); +} + + + +/* +================= +DrawOriginalEdges +================= +*/ +static void DrawOriginalEdges( int numOriginalEdges, originalEdges_t *originalEdges ) { + int i; + + if ( !dmapGlobals.drawflag ) { + return; + } + Draw_ClearWindow(); + + qglBegin( GL_LINES ); + for ( i = 0 ; i < numOriginalEdges ; i++ ) { + qglColor3f( 1, 0, 0 ); + qglVertex3fv( originalEdges[i].v1->pv.ToFloatPtr() ); + qglColor3f( 0, 0, 0 ); + qglVertex3fv( originalEdges[i].v2->pv.ToFloatPtr() ); + } + qglEnd(); + qglFlush(); +} + + +typedef struct edgeCrossing_s { + struct edgeCrossing_s *next; + optVertex_t *ov; +} edgeCrossing_t; + +static originalEdges_t *originalEdges; +static int numOriginalEdges; + +/* +================= +AddOriginalTriangle +================= +*/ +static void AddOriginalTriangle( optVertex_t *v[3] ) { + optVertex_t *v1, *v2; + + // if this triangle is backwards (possible with epsilon issues) + // ignore it completely + if ( !IsTriangleValid( v[0], v[1], v[2] ) ) { + common->Printf( "WARNING: backwards triangle in input!\n" ); + return; + } + + for ( int i = 0 ; i < 3 ; i++ ) { + v1 = v[i]; + v2 = v[(i+1)%3]; + + if ( v1 == v2 ) { + // this probably shouldn't happen, because the + // tri would be degenerate + continue; + } + int j; + // see if there is an existing one + for ( j = 0 ; j < numOriginalEdges ; j++ ) { + if ( originalEdges[j].v1 == v1 && originalEdges[j].v2 == v2 ) { + break; + } + if ( originalEdges[j].v2 == v1 && originalEdges[j].v1 == v2 ) { + break; + } + } + + if ( j == numOriginalEdges ) { + // add it + originalEdges[j].v1 = v1; + originalEdges[j].v2 = v2; + numOriginalEdges++; + } + } +} + +/* +================= +AddOriginalEdges +================= +*/ +static void AddOriginalEdges( optimizeGroup_t *opt ) { + mapTri_t *tri; + optVertex_t *v[3]; + int numTris; + + if ( dmapGlobals.verbose ) { + common->Printf( "----\n" ); + common->Printf( "%6i original tris\n", CountTriList( opt->triList ) ); + } + + optBounds.Clear(); + + // allocate space for max possible edges + numTris = CountTriList( opt->triList ); + originalEdges = (originalEdges_t *)Mem_Alloc( numTris * 3 * sizeof( *originalEdges ) ); + numOriginalEdges = 0; + + // add all unique triangle edges + numOptVerts = 0; + numOptEdges = 0; + for ( tri = opt->triList ; tri ; tri = tri->next ) { + v[0] = tri->optVert[0] = FindOptVertex( &tri->v[0], opt ); + v[1] = tri->optVert[1] = FindOptVertex( &tri->v[1], opt ); + v[2] = tri->optVert[2] = FindOptVertex( &tri->v[2], opt ); + + AddOriginalTriangle( v ); + } +} + +/* +===================== +SplitOriginalEdgesAtCrossings +===================== +*/ +void SplitOriginalEdgesAtCrossings( optimizeGroup_t *opt ) { + int i, j, k, l; + int numOriginalVerts; + edgeCrossing_t **crossings; + + numOriginalVerts = numOptVerts; + // now split any crossing edges and create optEdges + // linked to the vertexes + + // debug drawing bounds + dmapGlobals.drawBounds = optBounds; + + dmapGlobals.drawBounds[0][0] -= 2; + dmapGlobals.drawBounds[0][1] -= 2; + dmapGlobals.drawBounds[1][0] += 2; + dmapGlobals.drawBounds[1][1] += 2; + + // generate crossing points between all the original edges + crossings = (edgeCrossing_t **)Mem_ClearedAlloc( numOriginalEdges * sizeof( *crossings ) ); + + for ( i = 0 ; i < numOriginalEdges ; i++ ) { + if ( dmapGlobals.drawflag ) { + DrawOriginalEdges( numOriginalEdges, originalEdges ); + qglBegin( GL_LINES ); + qglColor3f( 0, 1, 0 ); + qglVertex3fv( originalEdges[i].v1->pv.ToFloatPtr() ); + qglColor3f( 0, 0, 1 ); + qglVertex3fv( originalEdges[i].v2->pv.ToFloatPtr() ); + qglEnd(); + qglFlush(); + } + for ( j = i+1 ; j < numOriginalEdges ; j++ ) { + optVertex_t *v1, *v2, *v3, *v4; + optVertex_t *newVert; + edgeCrossing_t *cross; + + v1 = originalEdges[i].v1; + v2 = originalEdges[i].v2; + v3 = originalEdges[j].v1; + v4 = originalEdges[j].v2; + + if ( !EdgesCross( v1, v2, v3, v4 ) ) { + continue; + } + + // this is the only point in optimization where + // completely new points are created, and it only + // happens if there is overlapping coplanar + // geometry in the source triangles + newVert = EdgeIntersection( v1, v2, v3, v4, opt ); + + if ( !newVert ) { +//common->Printf( "lines %i (%i to %i) and %i (%i to %i) are colinear\n", i, v1 - optVerts, v2 - optVerts, +// j, v3 - optVerts, v4 - optVerts ); // !@# + // colinear, so add both verts of each edge to opposite + if ( VertexBetween( v3, v1, v2 ) ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = v3; + cross->next = crossings[i]; + crossings[i] = cross; + } + + if ( VertexBetween( v4, v1, v2 ) ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = v4; + cross->next = crossings[i]; + crossings[i] = cross; + } + + if ( VertexBetween( v1, v3, v4 ) ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = v1; + cross->next = crossings[j]; + crossings[j] = cross; + } + + if ( VertexBetween( v2, v3, v4 ) ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = v2; + cross->next = crossings[j]; + crossings[j] = cross; + } + + continue; + } +#if 0 +if ( newVert && newVert != v1 && newVert != v2 && newVert != v3 && newVert != v4 ) { +common->Printf( "lines %i (%i to %i) and %i (%i to %i) cross at new point %i\n", i, v1 - optVerts, v2 - optVerts, + j, v3 - optVerts, v4 - optVerts, newVert - optVerts ); +} else if ( newVert ) { +common->Printf( "lines %i (%i to %i) and %i (%i to %i) intersect at old point %i\n", i, v1 - optVerts, v2 - optVerts, + j, v3 - optVerts, v4 - optVerts, newVert - optVerts ); +} +#endif + if ( newVert != v1 && newVert != v2 ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = newVert; + cross->next = crossings[i]; + crossings[i] = cross; + } + + if ( newVert != v3 && newVert != v4 ) { + cross = (edgeCrossing_t *)Mem_ClearedAlloc( sizeof( *cross ) ); + cross->ov = newVert; + cross->next = crossings[j]; + crossings[j] = cross; + } + + } + } + + + // now split each edge by its crossing points + // colinear edges will have duplicated edges added, but it won't hurt anything + for ( i = 0 ; i < numOriginalEdges ; i++ ) { + edgeCrossing_t *cross, *nextCross; + int numCross; + optVertex_t **sorted; + + numCross = 0; + for ( cross = crossings[i] ; cross ; cross = cross->next ) { + numCross++; + } + numCross += 2; // account for originals + sorted = (optVertex_t **)Mem_Alloc( numCross * sizeof( *sorted ) ); + sorted[0] = originalEdges[i].v1; + sorted[1] = originalEdges[i].v2; + j = 2; + for ( cross = crossings[i] ; cross ; cross = nextCross ) { + nextCross = cross->next; + sorted[j] = cross->ov; + Mem_Free( cross ); + j++; + } + + // add all possible fragment combinations that aren't divided + // by another point + for ( j = 0 ; j < numCross ; j++ ) { + for ( k = j+1 ; k < numCross ; k++ ) { + for ( l = 0 ; l < numCross ; l++ ) { + if ( sorted[l] == sorted[j] || sorted[l] == sorted[k] ) { + continue; + } + if ( sorted[j] == sorted[k] ) { + continue; + } + if ( VertexBetween( sorted[l], sorted[j], sorted[k] ) ) { + break; + } + } + if ( l == numCross ) { +//common->Printf( "line %i fragment from point %i to %i\n", i, sorted[j] - optVerts, sorted[k] - optVerts ); + AddEdgeIfNotAlready( sorted[j], sorted[k] ); + } + } + } + + Mem_Free( sorted ); + } + + + Mem_Free( crossings ); + Mem_Free( originalEdges ); + + // check for duplicated edges + for ( i = 0 ; i < numOptEdges ; i++ ) { + for ( j = i+1 ; j < numOptEdges ; j++ ) { + if ( ( optEdges[i].v1 == optEdges[j].v1 && optEdges[i].v2 == optEdges[j].v2 ) + || ( optEdges[i].v1 == optEdges[j].v2 && optEdges[i].v2 == optEdges[j].v1 ) ) { + common->Printf( "duplicated optEdge\n" ); + } + } + } + + if ( dmapGlobals.verbose ) { + common->Printf( "%6i original edges\n", numOriginalEdges ); + common->Printf( "%6i edges after splits\n", numOptEdges ); + common->Printf( "%6i original vertexes\n", numOriginalVerts ); + common->Printf( "%6i vertexes after splits\n", numOptVerts ); + } +} + +//================================================================= + + +/* +=================== +CullUnusedVerts + +Unlink any verts with no edges, so they +won't be used in the retriangulation +=================== +*/ +static void CullUnusedVerts( optIsland_t *island ) { + optVertex_t **prev, *vert; + int c_keep, c_free; + optEdge_t *edge; + + c_keep = 0; + c_free = 0; + + for ( prev = &island->verts ; *prev ; ) { + vert = *prev; + + if ( !vert->edges ) { + // free it + *prev = vert->islandLink; + c_free++; + } else { + edge = vert->edges; + if ( ( edge->v1 == vert && !edge->v1link ) + || ( edge->v2 == vert && !edge->v2link ) ) { + // is is occasionally possible to get a vert + // with only a single edge when colinear optimizations + // crunch down a complex sliver + UnlinkEdge( edge, island ); + // free it + *prev = vert->islandLink; + c_free++; + } else { + prev = &vert->islandLink; + c_keep++; + } + } + } + + if ( dmapGlobals.verbose ) { + common->Printf( "%6i verts kept\n", c_keep ); + common->Printf( "%6i verts freed\n", c_free ); + } +} + + + +/* +==================== +OptimizeIsland + +At this point, all needed vertexes are already in the +list, including any that were added at crossing points. + +Interior and colinear vertexes will be removed, and +a new triangulation will be created. +==================== +*/ +static void OptimizeIsland( optIsland_t *island ) { + // add space-filling fake edges so we have a complete + // triangulation of a convex hull before optimization + AddInteriorEdges( island ); + DrawEdges( island ); + + // determine all the possible triangles, and decide if + // the are filled or empty + BuildOptTriangles( island ); + + // remove interior vertexes that have filled triangles + // between all their edges + RemoveInteriorEdges( island ); + DrawEdges( island ); + + ValidateEdgeCounts( island ); + + // remove vertexes that only have two colinear edges + CombineColinearEdges( island ); + CullUnusedVerts( island ); + DrawEdges( island ); + + // add new internal edges between the remaining exterior edges + // to give us a full triangulation again + AddInteriorEdges( island ); + DrawEdges( island ); + + // determine all the possible triangles, and decide if + // the are filled or empty + BuildOptTriangles( island ); + + // make mapTri_t out of the filled optTri_t + RegenerateTriangles( island ); +} + +/* +================ +AddVertexToIsland_r +================ +*/ +static void AddVertexToIsland_r( optVertex_t *vert, optIsland_t *island ) { + optEdge_t *e; + + // we can't just check islandLink, because the + // last vert will have a NULL + if ( vert->addedToIsland ) { + return; + } + vert->addedToIsland = true; + vert->islandLink = island->verts; + island->verts = vert; + + for ( e = vert->edges ; e ; ) { + if ( !e->addedToIsland ) { + e->addedToIsland = true; + + e->islandLink = island->edges; + island->edges = e; + } + + if ( e->v1 == vert ) { + AddVertexToIsland_r( e->v2, island ); + e = e->v1link; + continue; + } + if ( e->v2 == vert ) { + AddVertexToIsland_r( e->v1, island ); + e = e->v2link; + continue; + } + common->Error( "AddVertexToIsland_r: mislinked vert" ); + } + +} + +/* +==================== +SeparateIslands + +While the algorithm should theoretically handle any collection +of triangles, there are speed and stability benefits to making +it work on as small a list as possible, so separate disconnected +collections of edges and process separately. + +FIXME: we need to separate the source triangles before +doing this, because PointInSourceTris() can give a bad answer if +the source list has triangles not used in the optimization +==================== +*/ +static void SeparateIslands( optimizeGroup_t *opt ) { + int i; + optIsland_t island; + int numIslands; + + DrawAllEdges(); + + numIslands = 0; + for ( i = 0 ; i < numOptVerts ; i++ ) { + if ( optVerts[i].addedToIsland ) { + continue; + } + numIslands++; + memset( &island, 0, sizeof( island ) ); + island.group = opt; + AddVertexToIsland_r( &optVerts[i], &island ); + OptimizeIsland( &island ); + } + if ( dmapGlobals.verbose ) { + common->Printf( "%6i islands\n", numIslands ); + } +} + +static void DontSeparateIslands( optimizeGroup_t *opt ) { + int i; + optIsland_t island; + + DrawAllEdges(); + + memset( &island, 0, sizeof( island ) ); + island.group = opt; + + // link everything together + for ( i = 0 ; i < numOptVerts ; i++ ) { + optVerts[i].islandLink = island.verts; + island.verts = &optVerts[i]; + } + + for ( i = 0 ; i < numOptEdges ; i++ ) { + optEdges[i].islandLink = island.edges; + island.edges = &optEdges[i]; + } + + OptimizeIsland( &island ); +} + + +/* +==================== +PointInSourceTris + +This is a sloppy bounding box check +==================== +*/ +static bool PointInSourceTris( float x, float y, float z, optimizeGroup_t *opt ) { + mapTri_t *tri; + idBounds b; + idVec3 p; + + if ( !opt->material->IsDrawn() ) { + return false; + } + + p[0] = x; + p[1] = y; + p[2] = z; + for ( tri = opt->triList ; tri ; tri = tri->next ) { + b.Clear(); + b.AddPoint( tri->v[0].xyz ); + b.AddPoint( tri->v[1].xyz ); + b.AddPoint( tri->v[2].xyz ); + + if ( b.ContainsPoint( p ) ) { + return true; + } + } + return false; +} + +/* +==================== +OptimizeOptList +==================== +*/ +static void OptimizeOptList( optimizeGroup_t *opt ) { + optimizeGroup_t *oldNext; + + // fix the t junctions among this single list + // so we can match edges + // can we avoid doing this if colinear vertexes break edges? + oldNext = opt->nextGroup; + opt->nextGroup = NULL; + FixAreaGroupsTjunctions( opt ); + opt->nextGroup = oldNext; + + // create the 2D vectors + dmapGlobals.mapPlanes[opt->planeNum].Normal().NormalVectors( opt->axis[0], opt->axis[1] ); + + AddOriginalEdges( opt ); + SplitOriginalEdgesAtCrossings( opt ); + +#if 0 + // seperate any discontinuous areas for individual optimization + // to reduce the scope of the problem + SeparateIslands( opt ); +#else + DontSeparateIslands( opt ); +#endif + + // now free the hash verts + FreeTJunctionHash(); + + // free the original list and use the new one + FreeTriList( opt->triList ); + opt->triList = opt->regeneratedTris; + opt->regeneratedTris = NULL; +} + + +/* +================== +SetGroupTriPlaneNums + +Copies the group planeNum to every triangle in each group +================== +*/ +void SetGroupTriPlaneNums( optimizeGroup_t *groups ) { + mapTri_t *tri; + optimizeGroup_t *group; + + for ( group = groups ; group ; group = group->nextGroup ) { + for ( tri = group->triList ; tri ; tri = tri->next ) { + tri->planeNum = group->planeNum; + } + } +} + + +/* +=================== +OptimizeGroupList + +This will also fix tjunctions + +=================== +*/ +void OptimizeGroupList( optimizeGroup_t *groupList ) { + int c_in, c_edge, c_tjunc2; + optimizeGroup_t *group; + + if ( !groupList ) { + return; + } + + c_in = CountGroupListTris( groupList ); + + // optimize and remove colinear edges, which will + // re-introduce some t junctions + for ( group = groupList ; group ; group = group->nextGroup ) { + OptimizeOptList( group ); + } + c_edge = CountGroupListTris( groupList ); + + // fix t junctions again + FixAreaGroupsTjunctions( groupList ); + FreeTJunctionHash(); + c_tjunc2 = CountGroupListTris( groupList ); + + SetGroupTriPlaneNums( groupList ); + + common->Printf( "----- OptimizeAreaGroups Results -----\n" ); + common->Printf( "%6i tris in\n", c_in ); + common->Printf( "%6i tris after edge removal optimization\n", c_edge ); + common->Printf( "%6i tris after final t junction fixing\n", c_tjunc2 ); +} + + +/* +================== +OptimizeEntity +================== +*/ +void OptimizeEntity( uEntity_t *e ) { + int i; + + common->Printf( "----- OptimizeEntity -----\n" ); + for ( i = 0 ; i < e->numAreas ; i++ ) { + OptimizeGroupList( e->areas[i].groups ); + } +} diff --git a/tools/compilers/dmap/optimize_gcc.cpp b/tools/compilers/dmap/optimize_gcc.cpp new file mode 100644 index 000000000..cd50133e5 --- /dev/null +++ b/tools/compilers/dmap/optimize_gcc.cpp @@ -0,0 +1,75 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +/* +crazy gcc 3.3.5 optimization bug +happens even at -O1 +if you remove the 'return NULL;' after Error(), it only happens at -O3 / release +see dmap.gcc.zip test map and .proc outputs +*/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +extern idBounds optBounds; + +#define MAX_OPT_VERTEXES 0x10000 +extern int numOptVerts; +extern optVertex_t optVerts[MAX_OPT_VERTEXES]; + +/* +================ +FindOptVertex +================ +*/ +optVertex_t *FindOptVertex( idDrawVert *v, optimizeGroup_t *opt ) { + int i; + float x, y; + optVertex_t *vert; + + // deal with everything strictly as 2D + x = v->xyz * opt->axis[0]; + y = v->xyz * opt->axis[1]; + + // should we match based on the t-junction fixing hash verts? + for ( i = 0 ; i < numOptVerts ; i++ ) { + if ( optVerts[i].pv[0] == x && optVerts[i].pv[1] == y ) { + return &optVerts[i]; + } + } + + if ( numOptVerts >= MAX_OPT_VERTEXES ) { + common->Error( "MAX_OPT_VERTEXES" ); + return NULL; + } + + numOptVerts++; + + vert = &optVerts[i]; + memset( vert, 0, sizeof( *vert ) ); + vert->v = *v; + vert->pv[0] = x; + vert->pv[1] = y; + vert->pv[2] = 0; + + optBounds.AddPoint( vert->pv ); + + return vert; +} diff --git a/tools/compilers/dmap/output.cpp b/tools/compilers/dmap/output.cpp new file mode 100644 index 000000000..39163df9b --- /dev/null +++ b/tools/compilers/dmap/output.cpp @@ -0,0 +1,673 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +//================================================================================= + + +#if 0 + +should we try and snap values very close to 0.5, 0.25, 0.125, etc? + + do we write out normals, or just a "smooth shade" flag? +resolved: normals. otherwise adjacent facet shaded surfaces get their + vertexes merged, and they would have to be split apart before drawing + + do we save out "wings" for shadow silhouette info? + + +#endif + +static idFile *procFile; + +#define AREANUM_DIFFERENT -2 +/* +============= +PruneNodes_r + +Any nodes that have all children with the same +area can be combined into a single leaf node + +Returns the area number of all children, or +AREANUM_DIFFERENT if not the same. +============= +*/ +int PruneNodes_r( node_t *node ) { + int a1, a2; + + if ( node->planenum == PLANENUM_LEAF ) { + return node->area; + } + + a1 = PruneNodes_r( node->children[0] ); + a2 = PruneNodes_r( node->children[1] ); + + if ( a1 != a2 || a1 == AREANUM_DIFFERENT ) { + return AREANUM_DIFFERENT; + } + + // free all the nodes below this point + FreeTreePortals_r( node->children[0] ); + FreeTreePortals_r( node->children[1] ); + FreeTree_r( node->children[0] ); + FreeTree_r( node->children[1] ); + + // change this node to a leaf + node->planenum = PLANENUM_LEAF; + node->area = a1; + + return a1; +} + +static void WriteFloat( idFile *f, float v ) +{ + if ( idMath::Fabs(v - idMath::Rint(v)) < 0.001 ) { + f->WriteFloatString( "%i ", (int)idMath::Rint(v) ); + } + else { + f->WriteFloatString( "%f ", v ); + } +} + +void Write1DMatrix( idFile *f, int x, float *m ) { + int i; + + f->WriteFloatString( "( " ); + + for ( i = 0; i < x; i++ ) { + WriteFloat( f, m[i] ); + } + + f->WriteFloatString( ") " ); +} + +static int CountUniqueShaders( optimizeGroup_t *groups ) { + optimizeGroup_t *a, *b; + int count; + + count = 0; + + for ( a = groups ; a ; a = a->nextGroup ) { + if ( !a->triList ) { // ignore groups with no tris + continue; + } + for ( b = groups ; b != a ; b = b->nextGroup ) { + if ( !b->triList ) { + continue; + } + if ( a->material != b->material ) { + continue; + } + if ( a->mergeGroup != b->mergeGroup ) { + continue; + } + break; + } + if ( a == b ) { + count++; + } + } + + return count; +} + + +/* +============== +MatchVert +============== +*/ +#define XYZ_EPSILON 0.01 +#define ST_EPSILON 0.001 +#define COSINE_EPSILON 0.999 + +static bool MatchVert( const idDrawVert *a, const idDrawVert *b ) { + if ( idMath::Fabs( a->xyz[0] - b->xyz[0] ) > XYZ_EPSILON ) { + return false; + } + if ( idMath::Fabs( a->xyz[1] - b->xyz[1] ) > XYZ_EPSILON ) { + return false; + } + if ( idMath::Fabs( a->xyz[2] - b->xyz[2] ) > XYZ_EPSILON ) { + return false; + } + if ( idMath::Fabs( a->st[0] - b->st[0] ) > ST_EPSILON ) { + return false; + } + if ( idMath::Fabs( a->st[1] - b->st[1] ) > ST_EPSILON ) { + return false; + } + + // if the normal is 0 (smoothed normals), consider it a match + if ( a->normal[0] == 0 && a->normal[1] == 0 && a->normal[2] == 0 + && b->normal[0] == 0 && b->normal[1] == 0 && b->normal[2] == 0 ) { + return true; + } + + // otherwise do a dot-product cosine check + if ( DotProduct( a->normal, b->normal ) < COSINE_EPSILON ) { + return false; + } + + return true; +} + +/* +==================== +ShareMapTriVerts + +Converts independent triangles to shared vertex triangles +==================== +*/ +srfTriangles_t *ShareMapTriVerts( const mapTri_t *tris ) { + const mapTri_t *step; + int count; + int i, j; + int numVerts; + int numIndexes; + srfTriangles_t *uTri; + + // unique the vertexes + count = CountTriList( tris ); + + uTri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( uTri, count * 3 ); + R_AllocStaticTriSurfIndexes( uTri, count * 3 ); + + numVerts = 0; + numIndexes = 0; + + for ( step = tris ; step ; step = step->next ) { + for ( i = 0 ; i < 3 ; i++ ) { + const idDrawVert *dv; + + dv = &step->v[i]; + + // search for a match + for ( j = 0 ; j < numVerts ; j++ ) { + if ( MatchVert( &uTri->verts[j], dv ) ) { + break; + } + } + if ( j == numVerts ) { + numVerts++; + uTri->verts[j].xyz = dv->xyz; + uTri->verts[j].normal = dv->normal; + uTri->verts[j].st[0] = dv->st[0]; + uTri->verts[j].st[1] = dv->st[1]; + } + + uTri->indexes[numIndexes++] = j; + } + } + + uTri->numVerts = numVerts; + uTri->numIndexes = numIndexes; + + return uTri; +} + +/* +================== +CleanupUTriangles +================== +*/ +static void CleanupUTriangles( srfTriangles_t *tri ) { + // perform cleanup operations + + R_RangeCheckIndexes( tri ); + R_CreateSilIndexes( tri ); +// R_RemoveDuplicatedTriangles( tri ); // this may remove valid overlapped transparent triangles + R_RemoveDegenerateTriangles( tri ); +// R_RemoveUnusedVerts( tri ); + + R_FreeStaticTriSurfSilIndexes( tri ); +} + +/* +==================== +WriteUTriangles + +Writes text verts and indexes to procfile +==================== +*/ +static void WriteUTriangles( const srfTriangles_t *uTris ) { + int col; + int i; + + // emit this chain + procFile->WriteFloatString( "/* numVerts = */ %i /* numIndexes = */ %i\n", + uTris->numVerts, uTris->numIndexes ); + + // verts + col = 0; + for ( i = 0 ; i < uTris->numVerts ; i++ ) { + float vec[8]; + const idDrawVert *dv; + + dv = &uTris->verts[i]; + + vec[0] = dv->xyz[0]; + vec[1] = dv->xyz[1]; + vec[2] = dv->xyz[2]; + vec[3] = dv->st[0]; + vec[4] = dv->st[1]; + vec[5] = dv->normal[0]; + vec[6] = dv->normal[1]; + vec[7] = dv->normal[2]; + Write1DMatrix( procFile, 8, vec ); + + if ( ++col == 3 ) { + col = 0; + procFile->WriteFloatString( "\n" ); + } + } + if ( col != 0 ) { + procFile->WriteFloatString( "\n" ); + } + + // indexes + col = 0; + for ( i = 0 ; i < uTris->numIndexes ; i++ ) { + procFile->WriteFloatString( "%i ", uTris->indexes[i] ); + + if ( ++col == 18 ) { + col = 0; + procFile->WriteFloatString( "\n" ); + } + } + if ( col != 0 ) { + procFile->WriteFloatString( "\n" ); + } +} + + +/* +==================== +WriteShadowTriangles + +Writes text verts and indexes to procfile +==================== +*/ +static void WriteShadowTriangles( const srfTriangles_t *tri ) { + int col; + int i; + + // emit this chain + procFile->WriteFloatString( "/* numVerts = */ %i /* noCaps = */ %i /* noFrontCaps = */ %i /* numIndexes = */ %i /* planeBits = */ %i\n", + tri->numVerts, tri->numShadowIndexesNoCaps, tri->numShadowIndexesNoFrontCaps, tri->numIndexes, tri->shadowCapPlaneBits ); + + // verts + col = 0; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + Write1DMatrix( procFile, 3, &tri->shadowVertexes[i].xyz[0] ); + + if ( ++col == 5 ) { + col = 0; + procFile->WriteFloatString( "\n" ); + } + } + if ( col != 0 ) { + procFile->WriteFloatString( "\n" ); + } + + // indexes + col = 0; + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + procFile->WriteFloatString( "%i ", tri->indexes[i] ); + + if ( ++col == 18 ) { + col = 0; + procFile->WriteFloatString( "\n" ); + } + } + if ( col != 0 ) { + procFile->WriteFloatString( "\n" ); + } +} + + +/* +======================= +GroupsAreSurfaceCompatible + +Planes, texcoords, and groupLights can differ, +but the material and mergegroup must match +======================= +*/ +static bool GroupsAreSurfaceCompatible( const optimizeGroup_t *a, const optimizeGroup_t *b ) { + if ( a->material != b->material ) { + return false; + } + if ( a->mergeGroup != b->mergeGroup ) { + return false; + } + return true; +} + +/* +==================== +WriteOutputSurfaces +==================== +*/ +static void WriteOutputSurfaces( int entityNum, int areaNum ) { + mapTri_t *ambient, *copy; + int surfaceNum; + int numSurfaces; + idMapEntity *entity; + uArea_t *area; + optimizeGroup_t *group, *groupStep; + int i; // , j; +// int col; + srfTriangles_t *uTri; +// mapTri_t *tri; +typedef struct interactionTris_s { + struct interactionTris_s *next; + mapTri_t *triList; + mapLight_t *light; +} interactionTris_t; + + interactionTris_t *interactions, *checkInter; //, *nextInter; + + + area = &dmapGlobals.uEntities[entityNum].areas[areaNum]; + entity = dmapGlobals.uEntities[entityNum].mapEntity; + + numSurfaces = CountUniqueShaders( area->groups ); + + + if ( entityNum == 0 ) { + procFile->WriteFloatString( "model { /* name = */ \"_area%i\" /* numSurfaces = */ %i\n\n", + areaNum, numSurfaces ); + } else { + const char *name; + + entity->epairs.GetString( "name", "", &name ); + if ( !name[0] ) { + common->Error( "Entity %i has surfaces, but no name key", entityNum ); + } + procFile->WriteFloatString( "model { /* name = */ \"%s\" /* numSurfaces = */ %i\n\n", + name, numSurfaces ); + } + + surfaceNum = 0; + for ( group = area->groups ; group ; group = group->nextGroup ) { + if ( group->surfaceEmited ) { + continue; + } + + // combine all groups compatible with this one + // usually several optimizeGroup_t can be combined into a single + // surface, even though they couldn't be merged together to save + // vertexes because they had different planes, texture coordinates, or lights. + // Different mergeGroups will stay in separate surfaces. + ambient = NULL; + + // each light that illuminates any of the groups in the surface will + // get its own list of indexes out of the original surface + interactions = NULL; + + for ( groupStep = group ; groupStep ; groupStep = groupStep->nextGroup ) { + if ( groupStep->surfaceEmited ) { + continue; + } + if ( !GroupsAreSurfaceCompatible( group, groupStep ) ) { + continue; + } + + // copy it out to the ambient list + copy = CopyTriList( groupStep->triList ); + ambient = MergeTriLists( ambient, copy ); + groupStep->surfaceEmited = true; + + // duplicate it into an interaction for each groupLight + for ( i = 0 ; i < groupStep->numGroupLights ; i++ ) { + for ( checkInter = interactions ; checkInter ; checkInter = checkInter->next ) { + if ( checkInter->light == groupStep->groupLights[i] ) { + break; + } + } + if ( !checkInter ) { + // create a new interaction + checkInter = (interactionTris_t *)Mem_ClearedAlloc( sizeof( *checkInter ) ); + checkInter->light = groupStep->groupLights[i]; + checkInter->next = interactions; + interactions = checkInter; + } + copy = CopyTriList( groupStep->triList ); + checkInter->triList = MergeTriLists( checkInter->triList, copy ); + } + } + + if ( !ambient ) { + continue; + } + + if ( surfaceNum >= numSurfaces ) { + common->Error( "WriteOutputSurfaces: surfaceNum >= numSurfaces" ); + } + + procFile->WriteFloatString( "/* surface %i */ { ", surfaceNum ); + surfaceNum++; + procFile->WriteFloatString( "\"%s\" ", ambient->material->GetName() ); + + uTri = ShareMapTriVerts( ambient ); + FreeTriList( ambient ); + + CleanupUTriangles( uTri ); + WriteUTriangles( uTri ); + R_FreeStaticTriSurf( uTri ); + + procFile->WriteFloatString( "}\n\n" ); + } + + procFile->WriteFloatString( "}\n\n" ); +} + +/* +=============== +WriteNode_r + +=============== +*/ +static void WriteNode_r( node_t *node ) { + int child[2]; + int i; + idPlane *plane; + + if ( node->planenum == PLANENUM_LEAF ) { + // we shouldn't get here unless the entire world + // was a single leaf + procFile->WriteFloatString( "/* node 0 */ ( 0 0 0 0 ) -1 -1\n" ); + return; + } + + for ( i = 0 ; i < 2 ; i++ ) { + if ( node->children[i]->planenum == PLANENUM_LEAF ) { + child[i] = -1 - node->children[i]->area; + } else { + child[i] = node->children[i]->nodeNumber; + } + } + + plane = &dmapGlobals.mapPlanes[node->planenum]; + + procFile->WriteFloatString( "/* node %i */ ", node->nodeNumber ); + Write1DMatrix( procFile, 4, plane->ToFloatPtr() ); + procFile->WriteFloatString( "%i %i\n", child[0], child[1] ); + + if ( child[0] > 0 ) { + WriteNode_r( node->children[0] ); + } + if ( child[1] > 0 ) { + WriteNode_r( node->children[1] ); + } +} + +static int NumberNodes_r( node_t *node, int nextNumber ) { + if ( node->planenum == PLANENUM_LEAF ) { + return nextNumber; + } + node->nodeNumber = nextNumber; + nextNumber++; + nextNumber = NumberNodes_r( node->children[0], nextNumber ); + nextNumber = NumberNodes_r( node->children[1], nextNumber ); + + return nextNumber; +} + +/* +==================== +WriteOutputNodes +==================== +*/ +static void WriteOutputNodes( node_t *node ) { + int numNodes; + + // prune unneeded nodes and count + PruneNodes_r( node ); + numNodes = NumberNodes_r( node, 0 ); + + // output + procFile->WriteFloatString( "nodes { /* numNodes = */ %i\n\n", numNodes ); + procFile->WriteFloatString( "/* node format is: ( planeVector ) positiveChild negativeChild */\n" ); + procFile->WriteFloatString( "/* a child number of 0 is an opaque, solid area */\n" ); + procFile->WriteFloatString( "/* negative child numbers are areas: (-1-child) */\n" ); + + WriteNode_r( node ); + + procFile->WriteFloatString( "}\n\n" ); +} + +/* +==================== +WriteOutputPortals +==================== +*/ +static void WriteOutputPortals( uEntity_t *e ) { + int i, j; + interAreaPortal_t *iap; + idWinding *w; + + procFile->WriteFloatString( "interAreaPortals { /* numAreas = */ %i /* numIAP = */ %i\n\n", + e->numAreas, numInterAreaPortals ); + procFile->WriteFloatString( "/* interAreaPortal format is: numPoints positiveSideArea negativeSideArea ( point) ... */\n" ); + for ( i = 0 ; i < numInterAreaPortals ; i++ ) { + iap = &interAreaPortals[i]; + w = iap->side->winding; + procFile->WriteFloatString("/* iap %i */ %i %i %i ", i, w->GetNumPoints(), iap->area0, iap->area1 ); + for ( j = 0 ; j < w->GetNumPoints() ; j++ ) { + Write1DMatrix( procFile, 3, (*w)[j].ToFloatPtr() ); + } + procFile->WriteFloatString("\n" ); + } + + procFile->WriteFloatString( "}\n\n" ); +} + + +/* +==================== +WriteOutputEntity +==================== +*/ +static void WriteOutputEntity( int entityNum ) { + int i; + uEntity_t *e; + + e = &dmapGlobals.uEntities[entityNum]; + + if ( entityNum != 0 ) { + // entities may have enclosed, empty areas that we don't need to write out + if ( e->numAreas > 1 ) { + e->numAreas = 1; + } + } + + for ( i = 0 ; i < e->numAreas ; i++ ) { + WriteOutputSurfaces( entityNum, i ); + } + + // we will completely skip the portals and nodes if it is a single area + if ( entityNum == 0 && e->numAreas > 1 ) { + // output the area portals + WriteOutputPortals( e ); + + // output the nodes + WriteOutputNodes( e->tree->headnode ); + } +} + + +/* +==================== +WriteOutputFile +==================== +*/ +void WriteOutputFile( void ) { + int i; + uEntity_t *entity; + idStr qpath; + + // write the file + common->Printf( "----- WriteOutputFile -----\n" ); + + sprintf( qpath, "%s." PROC_FILE_EXT, dmapGlobals.mapFileBase ); + + common->Printf( "writing %s\n", qpath.c_str() ); + // _D3XP used fs_cdpath + procFile = fileSystem->OpenFileWrite( qpath, "fs_devpath" ); + if ( !procFile ) { + common->Error( "Error opening %s", qpath.c_str() ); + } + + procFile->WriteFloatString( "%s\n\n", PROC_FILE_ID ); + + // write the entity models and information, writing entities first + for ( i=dmapGlobals.num_entities - 1 ; i >= 0 ; i-- ) { + entity = &dmapGlobals.uEntities[i]; + + if ( !entity->primitives ) { + continue; + } + + WriteOutputEntity( i ); + } + + // write the shadow volumes + for ( i = 0 ; i < dmapGlobals.mapLights.Num() ; i++ ) { + mapLight_t *light = dmapGlobals.mapLights[i]; + if ( !light->shadowTris ) { + continue; + } + + procFile->WriteFloatString( "shadowModel { /* name = */ \"_prelight_%s\"\n\n", light->name ); + WriteShadowTriangles( light->shadowTris ); + procFile->WriteFloatString( "}\n\n" ); + + R_FreeStaticTriSurf( light->shadowTris ); + light->shadowTris = NULL; + } + + fileSystem->CloseFile( procFile ); +} diff --git a/tools/compilers/dmap/portals.cpp b/tools/compilers/dmap/portals.cpp new file mode 100644 index 000000000..28615f00c --- /dev/null +++ b/tools/compilers/dmap/portals.cpp @@ -0,0 +1,990 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + + +interAreaPortal_t interAreaPortals[MAX_INTER_AREA_PORTALS]; +int numInterAreaPortals; + + +int c_active_portals; +int c_peak_portals; + +/* +=========== +AllocPortal +=========== +*/ +uPortal_t *AllocPortal (void) +{ + uPortal_t *p; + + c_active_portals++; + if (c_active_portals > c_peak_portals) + c_peak_portals = c_active_portals; + + p = (uPortal_t *)Mem_Alloc (sizeof(uPortal_t )); + memset (p, 0, sizeof(uPortal_t )); + + return p; +} + + +void FreePortal (uPortal_t *p) +{ + if (p->winding) + delete p->winding; + c_active_portals--; + Mem_Free (p); +} + +//============================================================== + +/* +============= +Portal_Passable + +Returns true if the portal has non-opaque leafs on both sides +============= +*/ +static bool Portal_Passable( uPortal_t *p ) { + if (!p->onnode) { + return false; // to global outsideleaf + } + + if (p->nodes[0]->planenum != PLANENUM_LEAF + || p->nodes[1]->planenum != PLANENUM_LEAF) { + common->Error( "Portal_EntityFlood: not a leaf"); + } + + if ( !p->nodes[0]->opaque && !p->nodes[1]->opaque ) { + return true; + } + + return false; +} + + +//============================================================================= + +int c_tinyportals; + +/* +============= +AddPortalToNodes +============= +*/ +void AddPortalToNodes (uPortal_t *p, node_t *front, node_t *back) { + if (p->nodes[0] || p->nodes[1]) { + common->Error( "AddPortalToNode: allready included"); + } + + p->nodes[0] = front; + p->next[0] = front->portals; + front->portals = p; + + p->nodes[1] = back; + p->next[1] = back->portals; + back->portals = p; +} + + +/* +============= +RemovePortalFromNode +============= +*/ +void RemovePortalFromNode (uPortal_t *portal, node_t *l) +{ + uPortal_t **pp, *t; + +// remove reference to the current portal + pp = &l->portals; + while (1) + { + t = *pp; + if (!t) + common->Error( "RemovePortalFromNode: portal not in leaf"); + + if ( t == portal ) + break; + + if (t->nodes[0] == l) + pp = &t->next[0]; + else if (t->nodes[1] == l) + pp = &t->next[1]; + else + common->Error( "RemovePortalFromNode: portal not bounding leaf"); + } + + if ( portal->nodes[0] == l ) { + *pp = portal->next[0]; + portal->nodes[0] = NULL; + } else if ( portal->nodes[1] == l ) { + *pp = portal->next[1]; + portal->nodes[1] = NULL; + } else { + common->Error( "RemovePortalFromNode: mislinked" ); + } +} + +//============================================================================ + +void PrintPortal (uPortal_t *p) +{ + int i; + idWinding *w; + + w = p->winding; + for ( i = 0; i < w->GetNumPoints(); i++ ) + common->Printf("(%5.0f,%5.0f,%5.0f)\n",(*w)[i][0], (*w)[i][1], (*w)[i][2]); +} + +/* +================ +MakeHeadnodePortals + +The created portals will face the global outside_node +================ +*/ +#define SIDESPACE 8 +static void MakeHeadnodePortals( tree_t *tree ) { + idBounds bounds; + int i, j, n; + uPortal_t *p, *portals[6]; + idPlane bplanes[6], *pl; + node_t *node; + + node = tree->headnode; + + tree->outside_node.planenum = PLANENUM_LEAF; + tree->outside_node.brushlist = NULL; + tree->outside_node.portals = NULL; + tree->outside_node.opaque = false; + + // if no nodes, don't go any farther + if ( node->planenum == PLANENUM_LEAF ) { + return; + } + + // pad with some space so there will never be null volume leafs + for (i=0 ; i<3 ; i++) { + bounds[0][i] = tree->bounds[0][i] - SIDESPACE; + bounds[1][i] = tree->bounds[1][i] + SIDESPACE; + if ( bounds[0][i] >= bounds[1][i] ) { + common->Error( "Backwards tree volume" ); + } + } + + for (i=0 ; i<3 ; i++) { + for (j=0 ; j<2 ; j++) { + n = j*3 + i; + + p = AllocPortal (); + portals[n] = p; + + pl = &bplanes[n]; + memset (pl, 0, sizeof(*pl)); + if (j) { + (*pl)[i] = -1; + (*pl)[3] = bounds[j][i]; + } else { + (*pl)[i] = 1; + (*pl)[3] = -bounds[j][i]; + } + p->plane = *pl; + p->winding = new idWinding( *pl ); + AddPortalToNodes (p, node, &tree->outside_node); + } + } + + // clip the basewindings by all the other planes + for (i=0 ; i<6 ; i++) { + for (j=0 ; j<6 ; j++) { + if (j == i) { + continue; + } + portals[i]->winding = portals[i]->winding->Clip( bplanes[j], ON_EPSILON ); + } + } +} + +//=================================================== + + +/* +================ +BaseWindingForNode +================ +*/ +#define BASE_WINDING_EPSILON 0.001f +#define SPLIT_WINDING_EPSILON 0.001f + +idWinding *BaseWindingForNode (node_t *node) { + idWinding *w; + node_t *n; + + w = new idWinding( dmapGlobals.mapPlanes[node->planenum] ); + + // clip by all the parents + for ( n = node->parent ; n && w ; ) { + idPlane &plane = dmapGlobals.mapPlanes[n->planenum]; + + if ( n->children[0] == node ) { + // take front + w = w->Clip( plane, BASE_WINDING_EPSILON ); + } else { + // take back + idPlane back = -plane; + w = w->Clip( back, BASE_WINDING_EPSILON ); + } + node = n; + n = n->parent; + } + + return w; +} + +//============================================================ + +/* +================== +MakeNodePortal + +create the new portal by taking the full plane winding for the cutting plane +and clipping it by all of parents of this node +================== +*/ +static void MakeNodePortal( node_t *node ) { + uPortal_t *new_portal, *p; + idWinding *w; + idVec3 normal; + int side; + + w = BaseWindingForNode (node); + + // clip the portal by all the other portals in the node + for (p = node->portals ; p && w; p = p->next[side]) + { + idPlane plane; + + if (p->nodes[0] == node) + { + side = 0; + plane = p->plane; + } + else if (p->nodes[1] == node) + { + side = 1; + plane = -p->plane; + } + else { + common->Error( "CutNodePortals_r: mislinked portal"); + side = 0; // quiet a compiler warning + } + + w = w->Clip( plane, CLIP_EPSILON ); + } + + if (!w) + { + return; + } + + if ( w->IsTiny() ) + { + c_tinyportals++; + delete w; + return; + } + + + new_portal = AllocPortal (); + new_portal->plane = dmapGlobals.mapPlanes[node->planenum]; + new_portal->onnode = node; + new_portal->winding = w; + AddPortalToNodes (new_portal, node->children[0], node->children[1]); +} + + +/* +============== +SplitNodePortals + +Move or split the portals that bound node so that the node's +children have portals instead of node. +============== +*/ +static void SplitNodePortals( node_t *node ) { + uPortal_t *p, *next_portal, *new_portal; + node_t *f, *b, *other_node; + int side; + idPlane *plane; + idWinding *frontwinding, *backwinding; + + plane = &dmapGlobals.mapPlanes[node->planenum]; + f = node->children[0]; + b = node->children[1]; + + for ( p = node->portals ; p ; p = next_portal ) { + if (p->nodes[0] == node ) { + side = 0; + } else if ( p->nodes[1] == node ) { + side = 1; + } else { + common->Error( "SplitNodePortals: mislinked portal" ); + side = 0; // quiet a compiler warning + } + next_portal = p->next[side]; + + other_node = p->nodes[!side]; + RemovePortalFromNode (p, p->nodes[0]); + RemovePortalFromNode (p, p->nodes[1]); + + // + // cut the portal into two portals, one on each side of the cut plane + // + p->winding->Split( *plane, SPLIT_WINDING_EPSILON, &frontwinding, &backwinding); + + if ( frontwinding && frontwinding->IsTiny() ) + { + delete frontwinding; + frontwinding = NULL; + c_tinyportals++; + } + + if ( backwinding && backwinding->IsTiny() ) + { + delete backwinding; + backwinding = NULL; + c_tinyportals++; + } + + if ( !frontwinding && !backwinding ) + { // tiny windings on both sides + continue; + } + + if (!frontwinding) + { + delete backwinding; + if (side == 0) + AddPortalToNodes (p, b, other_node); + else + AddPortalToNodes (p, other_node, b); + continue; + } + if (!backwinding) + { + delete frontwinding; + if (side == 0) + AddPortalToNodes (p, f, other_node); + else + AddPortalToNodes (p, other_node, f); + continue; + } + + // the winding is split + new_portal = AllocPortal (); + *new_portal = *p; + new_portal->winding = backwinding; + delete p->winding; + p->winding = frontwinding; + + if (side == 0) + { + AddPortalToNodes (p, f, other_node); + AddPortalToNodes (new_portal, b, other_node); + } + else + { + AddPortalToNodes (p, other_node, f); + AddPortalToNodes (new_portal, other_node, b); + } + } + + node->portals = NULL; +} + + +/* +================ +CalcNodeBounds +================ +*/ +void CalcNodeBounds (node_t *node) +{ + uPortal_t *p; + int s; + int i; + + // calc mins/maxs for both leafs and nodes + node->bounds.Clear(); + for (p = node->portals ; p ; p = p->next[s]) { + s = (p->nodes[1] == node); + for ( i = 0; i < p->winding->GetNumPoints(); i++ ) { + node->bounds.AddPoint( (*p->winding)[i].ToVec3() ); + } + } +} + + +/* +================== +MakeTreePortals_r +================== +*/ +void MakeTreePortals_r (node_t *node) +{ + int i; + + CalcNodeBounds( node ); + + if ( node->bounds[0][0] >= node->bounds[1][0]) { + common->Warning( "node without a volume" ); + } + + for ( i = 0; i < 3; i++ ) { + if ( node->bounds[0][i] < MIN_WORLD_COORD || node->bounds[1][i] > MAX_WORLD_COORD ) { + common->Warning( "node with unbounded volume"); + break; + } + } + if ( node->planenum == PLANENUM_LEAF ) { + return; + } + + MakeNodePortal (node); + SplitNodePortals (node); + + MakeTreePortals_r (node->children[0]); + MakeTreePortals_r (node->children[1]); +} + +/* +================== +MakeTreePortals +================== +*/ +void MakeTreePortals (tree_t *tree) +{ + common->Printf( "----- MakeTreePortals -----\n"); + MakeHeadnodePortals (tree); + MakeTreePortals_r (tree->headnode); +} + +/* +========================================================= + +FLOOD ENTITIES + +========================================================= +*/ + +int c_floodedleafs; + +/* +============= +FloodPortals_r +============= +*/ +void FloodPortals_r (node_t *node, int dist) { + uPortal_t *p; + int s; + + if ( node->occupied ) { + return; + } + + if ( node->opaque ) { + return; + } + + c_floodedleafs++; + node->occupied = dist; + + for (p=node->portals ; p ; p = p->next[s]) { + s = (p->nodes[1] == node); + FloodPortals_r (p->nodes[!s], dist+1); + } +} + +/* +============= +PlaceOccupant +============= +*/ +bool PlaceOccupant( node_t *headnode, idVec3 origin, uEntity_t *occupant ) { + node_t *node; + float d; + idPlane *plane; + + // find the leaf to start in + node = headnode; + while ( node->planenum != PLANENUM_LEAF ) { + plane = &dmapGlobals.mapPlanes[node->planenum]; + d = plane->Distance( origin ); + if ( d >= 0.0f ) { + node = node->children[0]; + } else { + node = node->children[1]; + } + } + + if ( node->opaque ) { + return false; + } + node->occupant = occupant; + + FloodPortals_r (node, 1); + + return true; +} + +/* +============= +FloodEntities + +Marks all nodes that can be reached by entites +============= +*/ +bool FloodEntities( tree_t *tree ) { + int i; + idVec3 origin; + const char *cl; + bool inside; + node_t *headnode; + + headnode = tree->headnode; + common->Printf ("--- FloodEntities ---\n"); + inside = false; + tree->outside_node.occupied = 0; + + c_floodedleafs = 0; + bool errorShown = false; + for (i=1 ; iepairs.GetVector( "origin", "", origin) ) { + continue; + } + + // any entity can have "noFlood" set to skip it + if ( mapEnt->epairs.GetString( "noFlood", "", &cl ) ) { + continue; + } + + mapEnt->epairs.GetString( "classname", "", &cl ); + + if ( !strcmp( cl, "light" ) ) { + const char *v; + + // don't place lights that have a light_start field, because they can still + // be valid if their origin is outside the world + mapEnt->epairs.GetString( "light_start", "", &v); + if ( v[0] ) { + continue; + } + + // don't place fog lights, because they often + // have origins outside the light + mapEnt->epairs.GetString( "texture", "", &v); + if ( v[0] ) { + const idMaterial *mat = declManager->FindMaterial( v ); + if ( mat->IsFogLight() ) { + continue; + } + } + } + + if (PlaceOccupant (headnode, origin, &dmapGlobals.uEntities[i])) { + inside = true; + } + + if (tree->outside_node.occupied && !errorShown) { + errorShown = true; + common->Printf("Leak on entity # %d\n", i); + const char *p; + + mapEnt->epairs.GetString( "classname", "", &p); + common->Printf("Entity classname was: %s\n", p); + mapEnt->epairs.GetString( "name", "", &p); + common->Printf("Entity name was: %s\n", p); + idVec3 origin; + if ( mapEnt->epairs.GetVector( "origin", "", origin)) { + common->Printf("Entity origin is: %f %f %f\n\n\n", origin.x, origin.y, origin.z); + } + } + } + + common->Printf("%5i flooded leafs\n", c_floodedleafs ); + + if (!inside) + { + common->Printf ("no entities in open -- no filling\n"); + } + else if (tree->outside_node.occupied) + { + common->Printf ("entity reached from outside -- no filling\n"); + } + + return (bool)(inside && !tree->outside_node.occupied); +} + +/* +========================================================= + +FLOOD AREAS + +========================================================= +*/ + +static int c_areas; +static int c_areaFloods; + +/* +================= +FindSideForPortal +================= +*/ +static side_t *FindSideForPortal( uPortal_t *p ) { + int i, j, k; + node_t *node; + uBrush_t *b, *orig; + side_t *s, *s2; + + // scan both bordering nodes brush lists for a portal brush + // that shares the plane + for ( i = 0 ; i < 2 ; i++ ) { + node = p->nodes[i]; + for ( b = node->brushlist ; b ; b = b->next ) { + if ( !( b->contents & CONTENTS_AREAPORTAL ) ) { + continue; + } + orig = b->original; + for ( j = 0 ; j < orig->numsides ; j++ ) { + s = orig->sides + j; + if ( !s->visibleHull ) { + continue; + } + if ( !( s->material->GetContentFlags() & CONTENTS_AREAPORTAL ) ) { + continue; + } + if ( ( s->planenum & ~1 ) != ( p->onnode->planenum & ~1 ) ) { + continue; + } + // remove the visible hull from any other portal sides of this portal brush + for ( k = 0; k < orig->numsides; k++ ) { + if ( k == j ) { + continue; + } + s2 = orig->sides + k; + if ( s2->visibleHull == NULL ) { + continue; + } + if ( !( s2->material->GetContentFlags() & CONTENTS_AREAPORTAL ) ) { + continue; + } + common->Warning( "brush has multiple area portal sides at %s", s2->visibleHull->GetCenter().ToString() ); + delete s2->visibleHull; + s2->visibleHull = NULL; + } + return s; + } + } + } + return NULL; +} + +/* +============= +FloodAreas_r +============= +*/ +void FloodAreas_r (node_t *node) +{ + uPortal_t *p; + int s; + + if ( node->area != -1 ) { + return; // allready got it + } + if ( node->opaque ) { + return; + } + + c_areaFloods++; + node->area = c_areas; + + for ( p=node->portals ; p ; p = p->next[s] ) { + node_t *other; + + s = (p->nodes[1] == node); + other = p->nodes[!s]; + + if ( !Portal_Passable(p) ) { + continue; + } + + // can't flood through an area portal + if ( FindSideForPortal( p ) ) { + continue; + } + + FloodAreas_r( other ); + } +} + +/* +============= +FindAreas_r + +Just decend the tree, and for each node that hasn't had an +area set, flood fill out from there +============= +*/ +void FindAreas_r( node_t *node ) { + if ( node->planenum != PLANENUM_LEAF ) { + FindAreas_r (node->children[0]); + FindAreas_r (node->children[1]); + return; + } + + if ( node->opaque ) { + return; + } + + if ( node->area != -1 ) { + return; // allready got it + } + + c_areaFloods = 0; + FloodAreas_r (node); + common->Printf( "area %i has %i leafs\n", c_areas, c_areaFloods ); + c_areas++; +} + +/* +============ +CheckAreas_r +============ +*/ +void CheckAreas_r( node_t *node ) { + if ( node->planenum != PLANENUM_LEAF ) { + CheckAreas_r (node->children[0]); + CheckAreas_r (node->children[1]); + return; + } + if ( !node->opaque && node->area < 0 ) { + common->Error( "CheckAreas_r: area = %i", node->area ); + } +} + +/* +============ +ClearAreas_r + +Set all the areas to -1 before filling +============ +*/ +void ClearAreas_r( node_t *node ) { + if ( node->planenum != PLANENUM_LEAF ) { + ClearAreas_r (node->children[0]); + ClearAreas_r (node->children[1]); + return; + } + node->area = -1; +} + +//============================================================= + + +/* +================= +FindInterAreaPortals_r + +================= +*/ +static void FindInterAreaPortals_r( node_t *node ) { + uPortal_t *p; + int s; + int i; + idWinding *w; + interAreaPortal_t *iap; + side_t *side; + + if ( node->planenum != PLANENUM_LEAF ) { + FindInterAreaPortals_r( node->children[0] ); + FindInterAreaPortals_r( node->children[1] ); + return; + } + + if ( node->opaque ) { + return; + } + + for ( p=node->portals ; p ; p = p->next[s] ) { + node_t *other; + + s = (p->nodes[1] == node); + other = p->nodes[!s]; + + if ( other->opaque ) { + continue; + } + + // only report areas going from lower number to higher number + // so we don't report the portal twice + if ( other->area <= node->area ) { + continue; + } + + side = FindSideForPortal( p ); +// w = p->winding; + if ( !side ) { + common->Warning( "FindSideForPortal failed at %s", p->winding->GetCenter().ToString() ); + continue; + } + w = side->visibleHull; + if ( !w ) { + continue; + } + + // see if we have created this portal before + for ( i = 0 ; i < numInterAreaPortals ; i++ ) { + iap = &interAreaPortals[i]; + + if ( side == iap->side && + ( ( p->nodes[0]->area == iap->area0 && p->nodes[1]->area == iap->area1 ) + || ( p->nodes[1]->area == iap->area0 && p->nodes[0]->area == iap->area1 ) ) ) { + break; + } + } + + if ( i != numInterAreaPortals ) { + continue; // already emited + } + + iap = &interAreaPortals[numInterAreaPortals]; + numInterAreaPortals++; + if ( side->planenum == p->onnode->planenum ) { + iap->area0 = p->nodes[0]->area; + iap->area1 = p->nodes[1]->area; + } else { + iap->area0 = p->nodes[1]->area; + iap->area1 = p->nodes[0]->area; + } + iap->side = side; + + } +} + + + + + +/* +============= +FloodAreas + +Mark each leaf with an area, bounded by CONTENTS_AREAPORTAL +Sets e->areas.numAreas +============= +*/ +void FloodAreas( uEntity_t *e ) { + common->Printf ("--- FloodAreas ---\n"); + + // set all areas to -1 + ClearAreas_r( e->tree->headnode ); + + // flood fill from non-opaque areas + c_areas = 0; + FindAreas_r( e->tree->headnode ); + + common->Printf ("%5i areas\n", c_areas); + e->numAreas = c_areas; + + // make sure we got all of them + CheckAreas_r( e->tree->headnode ); + + // identify all portals between areas if this is the world + if ( e == &dmapGlobals.uEntities[0] ) { + numInterAreaPortals = 0; + FindInterAreaPortals_r( e->tree->headnode ); + } +} + +/* +====================================================== + +FILL OUTSIDE + +====================================================== +*/ + +static int c_outside; +static int c_inside; +static int c_solid; + +void FillOutside_r (node_t *node) +{ + if (node->planenum != PLANENUM_LEAF) + { + FillOutside_r (node->children[0]); + FillOutside_r (node->children[1]); + return; + } + + // anything not reachable by an entity + // can be filled away + if (!node->occupied) { + if ( !node->opaque ) { + c_outside++; + node->opaque = true; + } else { + c_solid++; + } + } else { + c_inside++; + } + +} + +/* +============= +FillOutside + +Fill (set node->opaque = true) all nodes that can't be reached by entities +============= +*/ +void FillOutside( uEntity_t *e ) { + c_outside = 0; + c_inside = 0; + c_solid = 0; + common->Printf ("--- FillOutside ---\n"); + FillOutside_r( e->tree->headnode ); + common->Printf ("%5i solid leafs\n", c_solid); + common->Printf ("%5i leafs filled\n", c_outside); + common->Printf ("%5i inside leafs\n", c_inside); +} diff --git a/tools/compilers/dmap/shadowopt3.cpp b/tools/compilers/dmap/shadowopt3.cpp new file mode 100644 index 000000000..11c8da5de --- /dev/null +++ b/tools/compilers/dmap/shadowopt3.cpp @@ -0,0 +1,1267 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" +#include "../../../renderer/tr_local.h" + +/* + + given a set of faces that are clipped to the required frustum + + make 2D projection for each vertex + + for each edge + add edge, generating new points at each edge intersection + + ?add all additional edges to make a full triangulation + + make full triangulation + + for each triangle + find midpoint + find original triangle with midpoint closest to view + annotate triangle with that data + project all vertexes to that plane + output the triangle as a front cap + + snap all vertexes + make a back plane projection for all vertexes + + for each edge + if one side doesn't have a triangle + make a sil edge to back plane projection + continue + if triangles on both sides have two verts in common + continue + make a sil edge from one triangle to the other + + + + + classify triangles on common planes, so they can be optimized + + what about interpenetrating triangles??? + + a perfect shadow volume will have every edge exactly matched with + an opposite, and no two triangles covering the same area on either + the back projection or a silhouette edge. + + Optimizing the triangles on the projected plane can give a significant + improvement, but the quadratic time nature of the optimization process + probably makes it untenable. + + There exists some small room for further triangle count optimizations of the volumes + by collapsing internal surface geometry in some cases, or allowing original triangles + to extend outside the exactly light frustum without being clipped, but it probably + isn't worth it. + + Triangle count optimizations at the expense of a slight fill rate cost + may be apropriate in some cases. + + + Perform the complete clipping on all triangles + for each vertex + project onto the apropriate plane and mark plane bit as in use +for each triangle + if points project onto different planes, clip +*/ + + +typedef struct { + idVec3 v[3]; + idVec3 edge[3]; // positive side is inside the triangle + glIndex_t index[3]; + idPlane plane; // positive side is forward for the triangle, which is away from the light + int planeNum; // from original triangle, not calculated from the clipped verts +} shadowTri_t; + +static const int MAX_SHADOW_TRIS = 32768; + +static shadowTri_t outputTris[MAX_SHADOW_TRIS]; +static int numOutputTris; + +typedef struct shadowOptEdge_s { + glIndex_t index[2]; + struct shadowOptEdge_s *nextEdge; +} shadowOptEdge_t; + +static const int MAX_SIL_EDGES = MAX_SHADOW_TRIS*3; +static shadowOptEdge_t silEdges[MAX_SIL_EDGES]; +static int numSilEdges; + +typedef struct silQuad_s { + int nearV[2]; + int farV[2]; // will always be a projection of near[] + struct silQuad_s *nextQuad; +} silQuad_t; + +static const int MAX_SIL_QUADS = MAX_SHADOW_TRIS*3; +static silQuad_t silQuads[MAX_SIL_QUADS]; +static int numSilQuads; + + +typedef struct { + idVec3 normal; // all sil planes go through the projection origin + shadowOptEdge_t *edges; + silQuad_t *fragmentedQuads; +} silPlane_t; + +static float EDGE_PLANE_EPSILON = 0.1f; +static float UNIQUE_EPSILON = 0.1f; + +static int numSilPlanes; +static silPlane_t *silPlanes; + +// the uniqued verts are still in projection centered space, not global space +static int numUniqued; +static int numUniquedBeforeProjection; +static int maxUniqued; +static idVec3 *uniqued; + +static optimizedShadow_t ret; +static int maxRetIndexes; + +static int FindUniqueVert( idVec3 &v ); + +//===================================================================================== + +/* +================= +CreateEdgesForTri +================= +*/ +static void CreateEdgesForTri( shadowTri_t *tri ) { + for ( int j = 0 ; j < 3 ; j++ ) { + idVec3 &v1 = tri->v[j]; + idVec3 &v2 = tri->v[(j+1)%3]; + + tri->edge[j].Cross( v2, v1 ); + tri->edge[j].Normalize(); + } +} + + +static const float EDGE_EPSILON = 0.1f; + +static bool TriOutsideTri( const shadowTri_t *a, const shadowTri_t *b ) { +#if 0 + if ( a->v[0] * b->edge[0] <= EDGE_EPSILON + && a->v[1] * b->edge[0] <= EDGE_EPSILON + && a->v[2] * b->edge[0] <= EDGE_EPSILON ) { + return true; + } + if ( a->v[0] * b->edge[1] <= EDGE_EPSILON + && a->v[1] * b->edge[1] <= EDGE_EPSILON + && a->v[2] * b->edge[1] <= EDGE_EPSILON ) { + return true; + } + if ( a->v[0] * b->edge[2] <= EDGE_EPSILON + && a->v[1] * b->edge[2] <= EDGE_EPSILON + && a->v[2] * b->edge[2] <= EDGE_EPSILON ) { + return true; + } +#else + for ( int i = 0 ; i < 3 ; i++ ) { + int j; + for ( j = 0 ; j < 3 ; j++ ) { + float d = a->v[j] * b->edge[i]; + if ( d > EDGE_EPSILON ) { + break; + } + } + if ( j == 3 ) { + return true; + } + } +#endif + return false; +} + +static bool TriBehindTri( const shadowTri_t *a, const shadowTri_t *b ) { + float d; + + d = b->plane.Distance( a->v[0] ); + if ( d > 0 ) { + return true; + } + d = b->plane.Distance( a->v[1] ); + if ( d > 0 ) { + return true; + } + d = b->plane.Distance( a->v[2] ); + if ( d > 0 ) { + return true; + } + + return false; +} + +/* +=================== +ClipTriangle_r +=================== +*/ +static int c_removedFragments; +static void ClipTriangle_r( const shadowTri_t *tri, int startTri, int skipTri, int numTris, const shadowTri_t *tris ) { + // create edge planes for this triangle + + // compare against all the other triangles + for ( int i = startTri ; i < numTris ; i++ ) { + if ( i == skipTri ) { + continue; + } + const shadowTri_t *other = &tris[i]; + + if ( TriOutsideTri( tri, other ) ) { + continue; + } + if ( TriOutsideTri( other, tri ) ) { + continue; + } + // they overlap to some degree + + // if other is behind tri, it doesn't clip it + if ( !TriBehindTri( tri, other ) ) { + continue; + } + + // clip it + idWinding *w = new idWinding( tri->v, 3 ); + + for ( int j = 0 ; j < 4 && w ; j++ ) { + idWinding *front, *back; + + // keep any portion in front of other's plane + if ( j == 0 ) { + w->Split( other->plane, ON_EPSILON, &front, &back ); + } else { + w->Split( idPlane( other->edge[j-1], 0.0f ), ON_EPSILON, &front, &back ); + } + if ( back ) { + // recursively clip these triangles to all subsequent triangles + for ( int k = 2 ; k < back->GetNumPoints() ; k++ ) { + shadowTri_t fragment = *tri; + + fragment.v[0] = (*back)[0].ToVec3(); + fragment.v[1] = (*back)[k-1].ToVec3(); + fragment.v[2] = (*back)[k].ToVec3(); + CreateEdgesForTri( &fragment ); + ClipTriangle_r( &fragment, i + 1, skipTri, numTris, tris ); + } + delete back; + } + + delete w; + w = front; + } + if ( w ) { + delete w; + } + + c_removedFragments++; + // any fragments will have been added recursively + return; + } + + // this fragment is frontmost, so add it to the output list + if ( numOutputTris == MAX_SHADOW_TRIS ) { + common->Error( "numOutputTris == MAX_SHADOW_TRIS" ); + } + + outputTris[numOutputTris] = *tri; + numOutputTris++; +} + + +/* +==================== +ClipOccluders + +Generates outputTris by clipping all the triangles against each other, +retaining only those closest to the projectionOrigin +==================== +*/ +static void ClipOccluders( idVec4 *verts, glIndex_t *indexes, int numIndexes, + idVec3 projectionOrigin ) { + int numTris = numIndexes / 3; + int i; + shadowTri_t *tris = (shadowTri_t *)_alloca( numTris * sizeof( *tris ) ); + shadowTri_t *tri; + + common->Printf( "ClipOccluders: %i triangles\n", numTris ); + + for ( i = 0 ; i < numTris ; i++ ) { + tri = &tris[i]; + + // the indexes are in reversed order from tr_stencilshadow + tri->v[0] = verts[indexes[i*3+2]].ToVec3() - projectionOrigin; + tri->v[1] = verts[indexes[i*3+1]].ToVec3() - projectionOrigin; + tri->v[2] = verts[indexes[i*3+0]].ToVec3() - projectionOrigin; + + idVec3 d1 = tri->v[1] - tri->v[0]; + idVec3 d2 = tri->v[2] - tri->v[0]; + + tri->plane.ToVec4().ToVec3().Cross( d2, d1 ); + tri->plane.ToVec4().ToVec3().Normalize(); + tri->plane[3] = - ( tri->v[0] * tri->plane.ToVec4().ToVec3() ); + + // get the plane number before any clipping + // we should avoid polluting the regular dmap planes with these + // that are offset from the light origin... + tri->planeNum = FindFloatPlane( tri->plane ); + + CreateEdgesForTri( tri ); + } + + // clear our output buffer + numOutputTris = 0; + + // for each triangle, clip against all other triangles + int numRemoved = 0; + int numComplete = 0; + int numFragmented = 0; + + for ( i = 0 ; i < numTris ; i++ ) { + int oldOutput = numOutputTris; + c_removedFragments = 0; + ClipTriangle_r( &tris[i], 0, i, numTris, tris ); + if ( numOutputTris == oldOutput ) { + numRemoved++; // completely unused + } else if ( c_removedFragments == 0 ) { + // the entire triangle is visible + numComplete++; + shadowTri_t *out = &outputTris[oldOutput]; + *out = tris[i]; + numOutputTris = oldOutput+1; + } else { + numFragmented++; + // we made at least one fragment + + // if we are at the low optimization level, just use a single + // triangle if it produced any fragments + if ( dmapGlobals.shadowOptLevel == SO_CULL_OCCLUDED ) { + shadowTri_t *out = &outputTris[oldOutput]; + *out = tris[i]; + numOutputTris = oldOutput+1; + } + } + } + common->Printf( "%i triangles completely invisible\n", numRemoved ); + common->Printf( "%i triangles completely visible\n", numComplete ); + common->Printf( "%i triangles fragmented\n", numFragmented ); + common->Printf( "%i shadowing fragments before optimization\n", numOutputTris ); +} + +//===================================================================================== + +/* +================ +OptimizeOutputTris +================ +*/ +static void OptimizeOutputTris( void ) { + int i; + + // optimize the clipped surfaces + optimizeGroup_t *optGroups = NULL; + optimizeGroup_t *checkGroup; + + for ( i = 0 ; i < numOutputTris ; i++ ) { + shadowTri_t *tri = &outputTris[i]; + + int planeNum = tri->planeNum; + + // add it to an optimize group + for ( checkGroup = optGroups ; checkGroup ; checkGroup = checkGroup->nextGroup ) { + if ( checkGroup->planeNum == planeNum ) { + break; + } + } + if ( !checkGroup ) { + // create a new optGroup + checkGroup = (optimizeGroup_t *)Mem_ClearedAlloc( sizeof( *checkGroup ) ); + checkGroup->planeNum = planeNum; + checkGroup->nextGroup = optGroups; + optGroups = checkGroup; + } + + // create a mapTri for the optGroup + mapTri_t *mtri = (mapTri_t *)Mem_ClearedAlloc( sizeof( *mtri ) ); + mtri->v[0].xyz = tri->v[0]; + mtri->v[1].xyz = tri->v[1]; + mtri->v[2].xyz = tri->v[2]; + mtri->next = checkGroup->triList; + checkGroup->triList = mtri; + } + + OptimizeGroupList( optGroups ); + + numOutputTris = 0; + for ( checkGroup = optGroups ; checkGroup ; checkGroup = checkGroup->nextGroup ) { + for ( mapTri_t *mtri = checkGroup->triList ; mtri ; mtri = mtri->next ) { + shadowTri_t *tri = &outputTris[numOutputTris]; + numOutputTris++; + tri->v[0] = mtri->v[0].xyz; + tri->v[1] = mtri->v[1].xyz; + tri->v[2] = mtri->v[2].xyz; + } + } + FreeOptimizeGroupList( optGroups ); +} + +//================================================================================== + +static int EdgeSort( const void *a, const void *b ) { + if ( *(unsigned *)a < *(unsigned *)b ) { + return -1; + } + if ( *(unsigned *)a > *(unsigned *)b ) { + return 1; + } + return 0; +} + +/* +===================== +GenerateSilEdges + +Output tris must be tjunction fixed and vertex uniqued +A edge that is not exactly matched is a silhouette edge +We could skip this and rely completely on the matched quad removal +for all sil edges, but this will avoid the bulk of the checks. +===================== +*/ +static void GenerateSilEdges( void ) { + int i, j; + + unsigned *edges = (unsigned *)_alloca( (numOutputTris*3+1)*sizeof(*edges) ); + int numEdges = 0; + + numSilEdges = 0; + + for ( i = 0 ; i < numOutputTris ; i++ ) { + int a = outputTris[i].index[0]; + int b = outputTris[i].index[1]; + int c = outputTris[i].index[2]; + if ( a == b || a == c || b == c ) { + continue; // degenerate + } + + for ( j = 0 ; j < 3 ; j++ ) { + int v1, v2; + + v1 = outputTris[i].index[j]; + v2 = outputTris[i].index[(j+1)%3]; + if ( v1 == v2 ) { + continue; // degenerate + } + if ( v1 > v2 ) { + edges[numEdges] = ( v1 << 16 ) | ( v2 << 1 ); + } else { + edges[numEdges] = ( v2 << 16 ) | ( v1 << 1 ) | 1; + } + numEdges++; + } + } + + qsort( edges, numEdges, sizeof( edges[0] ), EdgeSort ); + edges[numEdges] = -1; // force the last to make an edge if no matched to previous + + for ( i = 0 ; i < numEdges ; i++ ) { + if ( ( edges[i] ^ edges[i+1] ) == 1 ) { + // skip the next one, because we matched and + // removed both + i++; + continue; + } + // this is an unmatched edge, so we need to generate a sil plane + int v1, v2; + if ( edges[i] & 1 ) { + v2 = edges[i] >> 16; + v1 = ( edges[i] >> 1 ) & 0x7fff; + } else { + v1 = edges[i] >> 16; + v2 = ( edges[i] >> 1 ) & 0x7fff; + } + + if ( numSilEdges == MAX_SIL_EDGES ) { + common->Error( "numSilEdges == MAX_SIL_EDGES" ); + } + silEdges[numSilEdges].index[0] = v1; + silEdges[numSilEdges].index[1] = v2; + numSilEdges++; + } +} + +//================================================================================== + +/* +===================== +GenerateSilPlanes + +Groups the silEdges into common planes +===================== +*/ +void GenerateSilPlanes( void ) { + numSilPlanes = 0; + silPlanes = (silPlane_t *)Mem_Alloc( sizeof( *silPlanes ) * numSilEdges ); + + // identify the silPlanes + numSilPlanes = 0; + for ( int i = 0 ; i < numSilEdges ; i++ ) { + if ( silEdges[i].index[0] == silEdges[i].index[1] ) { + continue; // degenerate + } + + idVec3 &v1 = uniqued[silEdges[i].index[0]]; + idVec3 &v2 = uniqued[silEdges[i].index[1]]; + + // search for an existing plane + int j; + for ( j = 0 ; j < numSilPlanes ; j++ ) { + float d = v1 * silPlanes[j].normal; + float d2 = v2 * silPlanes[j].normal; + + if ( fabs( d ) < EDGE_PLANE_EPSILON + && fabs( d2 ) < EDGE_PLANE_EPSILON ) { + silEdges[i].nextEdge = silPlanes[j].edges; + silPlanes[j].edges = &silEdges[i]; + break; + } + } + + if ( j == numSilPlanes ) { + // create a new silPlane + silPlanes[j].normal.Cross( v2, v1 ); + silPlanes[j].normal.Normalize(); + silEdges[i].nextEdge = NULL; + silPlanes[j].edges = &silEdges[i]; + silPlanes[j].fragmentedQuads = NULL; + numSilPlanes++; + } + } +} + +//================================================================================== + +/* +============= +SaveQuad +============= +*/ +static void SaveQuad( silPlane_t *silPlane, silQuad_t &quad ) { + // this fragment is a final fragment + if ( numSilQuads == MAX_SIL_QUADS ) { + common->Error( "numSilQuads == MAX_SIL_QUADS" ); + } + silQuads[numSilQuads] = quad; + silQuads[numSilQuads].nextQuad = silPlane->fragmentedQuads; + silPlane->fragmentedQuads = &silQuads[numSilQuads]; + numSilQuads++; +} + + +/* +=================== +FragmentSilQuad + +Clip quads, or reconstruct? +Generate them T-junction free, or require another pass of fix-tjunc? +Call optimizer on a per-sil-plane basis? + will this ever introduce tjunctions with the front faces? + removal of planes can allow the rear projection to be farther optimized + +For quad clipping + PlaneThroughEdge + +quad clipping introduces new vertexes + +Cannot just fragment edges, must emit full indexes + +what is the bounds on max indexes? + the worst case is that all edges but one carve an existing edge in the middle, + giving twice the input number of indexes (I think) + +can we avoid knowing about projected positions and still optimize? + +Fragment all edges first +Introduces T-junctions +create additional silEdges, linked to silPlanes + +In theory, we should never have more than one edge clipping a given +fragment, but it is more robust if we check them all +=================== +*/ +static void FragmentSilQuad( silQuad_t quad, silPlane_t *silPlane, + shadowOptEdge_t *startEdge, shadowOptEdge_t *skipEdge ) { + if ( quad.nearV[0] == quad.nearV[1] ) { + return; + } + + for ( shadowOptEdge_t *check = startEdge ; check ; check = check->nextEdge ) { + if ( check == skipEdge ) { + // don't clip against self + continue; + } + + if ( check->index[0] == check->index[1] ) { + continue; + } + + // make planes through both points of check + for ( int i = 0 ; i < 2 ; i++ ) { + idVec3 plane; + + plane.Cross( uniqued[check->index[i]], silPlane->normal ); + plane.Normalize(); + + if ( plane.Length() < 0.9 ) { + continue; + } + + // if the other point on check isn't on the negative side of the plane, + // flip the plane + if ( uniqued[check->index[!i]] * plane > 0 ) { + plane = -plane; + } + + float d1 = uniqued[quad.nearV[0]] * plane; + float d2 = uniqued[quad.nearV[1]] * plane; + + float d3 = uniqued[quad.farV[0]] * plane; + float d4 = uniqued[quad.farV[1]] * plane; + + // it is better to conservatively NOT split the quad, which, at worst, + // will leave some extra overdraw + + // if the plane divides the incoming edge, split it and recurse + // with the outside fraction before continuing with the inside fraction + if ( ( d1 > EDGE_PLANE_EPSILON && d3 > EDGE_PLANE_EPSILON && d2 < -EDGE_PLANE_EPSILON && d4 < -EDGE_PLANE_EPSILON ) + || ( d2 > EDGE_PLANE_EPSILON && d4 > EDGE_PLANE_EPSILON && d1 < -EDGE_PLANE_EPSILON && d3 < -EDGE_PLANE_EPSILON ) ) { + float f = d1 / ( d1 - d2 ); + float f2 = d3 / ( d3 - d4 ); +f = f2; + if ( f <= 0.0001 || f >= 0.9999 ) { + common->Error( "Bad silQuad fraction" ); + } + + // finding uniques may be causing problems here + idVec3 nearMid = (1-f) * uniqued[quad.nearV[0]] + f * uniqued[quad.nearV[1]]; + int nearMidIndex = FindUniqueVert( nearMid ); + idVec3 farMid = (1-f) * uniqued[quad.farV[0]] + f * uniqued[quad.farV[1]]; + int farMidIndex = FindUniqueVert( farMid ); + + silQuad_t clipped = quad; + + if ( d1 > EDGE_PLANE_EPSILON ) { + clipped.nearV[1] = nearMidIndex; + clipped.farV[1] = farMidIndex; + FragmentSilQuad( clipped, silPlane, check->nextEdge, skipEdge ); + quad.nearV[0] = nearMidIndex; + quad.farV[0] = farMidIndex; + } else { + clipped.nearV[0] = nearMidIndex; + clipped.farV[0] = farMidIndex; + FragmentSilQuad( clipped, silPlane, check->nextEdge, skipEdge ); + quad.nearV[1] = nearMidIndex; + quad.farV[1] = farMidIndex; + } + } + } + + // make a plane through the line of check + idPlane separate; + + idVec3 dir = uniqued[check->index[1]] - uniqued[check->index[0]]; + separate.Normal().Cross( dir, silPlane->normal ); + separate.Normal().Normalize(); + separate.ToVec4()[3] = -(uniqued[check->index[1]] * separate.Normal()); + + // this may miss a needed separation when the quad would be + // clipped into a triangle and a quad + float d1 = separate.Distance( uniqued[quad.nearV[0]] ); + float d2 = separate.Distance( uniqued[quad.farV[0]] ); + + if ( ( d1 < EDGE_PLANE_EPSILON && d2 < EDGE_PLANE_EPSILON ) + || ( d1 > -EDGE_PLANE_EPSILON && d2 > -EDGE_PLANE_EPSILON ) ) { + continue; + } + + // split the quad at this plane + float f = d1 / ( d1 - d2 ); + idVec3 mid0 = (1-f) * uniqued[quad.nearV[0]] + f * uniqued[quad.farV[0]]; + int mid0Index = FindUniqueVert( mid0 ); + + d1 = separate.Distance( uniqued[quad.nearV[1]] ); + d2 = separate.Distance( uniqued[quad.farV[1]] ); + f = d1 / ( d1 - d2 ); + if ( f < 0 || f > 1 ) { + continue; + } + + idVec3 mid1 = (1-f) * uniqued[quad.nearV[1]] + f * uniqued[quad.farV[1]]; + int mid1Index = FindUniqueVert( mid1 ); + + silQuad_t clipped = quad; + + clipped.nearV[0] = mid0Index; + clipped.nearV[1] = mid1Index; + FragmentSilQuad( clipped, silPlane, check->nextEdge, skipEdge ); + quad.farV[0] = mid0Index; + quad.farV[1] = mid1Index; + } + + SaveQuad( silPlane, quad ); +} + + +/* +=============== +FragmentSilQuads +=============== +*/ +static void FragmentSilQuads( void ) { + // group the edges into common planes + GenerateSilPlanes(); + + numSilQuads = 0; + + // fragment overlapping edges + for ( int i = 0 ; i < numSilPlanes ; i++ ) { + silPlane_t *sil = &silPlanes[i]; + + for ( shadowOptEdge_t *e1 = sil->edges ; e1 ; e1 = e1->nextEdge ) { + silQuad_t quad; + + quad.nearV[0] = e1->index[0]; + quad.nearV[1] = e1->index[1]; + if ( e1->index[0] == e1->index[1] ) { + common->Error( "FragmentSilQuads: degenerate edge" ); + } + quad.farV[0] = e1->index[0] + numUniquedBeforeProjection; + quad.farV[1] = e1->index[1] + numUniquedBeforeProjection; + FragmentSilQuad( quad, sil, sil->edges, e1 ); + } + } +} + +//======================================================================= + +/* +===================== +EmitFragmentedSilQuads + +===================== +*/ +static void EmitFragmentedSilQuads( void ) { + int i, j, k; + mapTri_t *mtri; + + for ( i = 0 ; i < numSilPlanes ; i++ ) { + silPlane_t *sil = &silPlanes[i]; + + // prepare for optimizing the sil quads on each side of the sil plane + optimizeGroup_t groups[2]; + memset( &groups, 0, sizeof( groups ) ); + idPlane planes[2]; + planes[0].Normal() = sil->normal; + planes[0][3] = 0; + planes[1] = -planes[0]; + groups[0].planeNum = FindFloatPlane( planes[0] ); + groups[1].planeNum = FindFloatPlane( planes[1] ); + + // emit the quads that aren't matched + for ( silQuad_t *f1 = sil->fragmentedQuads ; f1 ; f1 = f1->nextQuad ) { + silQuad_t *f2; + for ( f2 = sil->fragmentedQuads ; f2 ; f2 = f2->nextQuad ) { + if ( f2 == f1 ) { + continue; + } + // in theory, this is sufficient, but we might + // have some cases of tripple+ matching, or unclipped rear projections + if ( f1->nearV[0] == f2->nearV[1] && f1->nearV[1] == f2->nearV[0] ) { + break; + } + } + // if we went through all the quads without finding a match, emit the quad + if ( !f2 ) { + optimizeGroup_t *gr; + idVec3 v1, v2, normal; + + mtri = (mapTri_t *)Mem_ClearedAlloc( sizeof( *mtri ) ); + mtri->v[0].xyz = uniqued[f1->nearV[0]]; + mtri->v[1].xyz = uniqued[f1->nearV[1]]; + mtri->v[2].xyz = uniqued[f1->farV[1]]; + + v1 = mtri->v[1].xyz - mtri->v[0].xyz; + v2 = mtri->v[2].xyz - mtri->v[0].xyz; + normal.Cross( v2, v1 ); + + if ( normal * planes[0].Normal() > 0 ) { + gr = &groups[0]; + } else { + gr = &groups[1]; + } + + mtri->next = gr->triList; + gr->triList = mtri; + + mtri = (mapTri_t *)Mem_ClearedAlloc( sizeof( *mtri ) ); + mtri->v[0].xyz = uniqued[f1->farV[0]]; + mtri->v[1].xyz = uniqued[f1->nearV[0]]; + mtri->v[2].xyz = uniqued[f1->farV[1]]; + + mtri->next = gr->triList; + gr->triList = mtri; + +#if 0 + // emit a sil quad all the way to the projection plane + int index = ret.totalIndexes; + if ( index + 6 > maxRetIndexes ) { + common->Error( "maxRetIndexes exceeded" ); + } + ret.indexes[index+0] = f1->nearV[0]; + ret.indexes[index+1] = f1->nearV[1]; + ret.indexes[index+2] = f1->farV[1]; + ret.indexes[index+3] = f1->farV[0]; + ret.indexes[index+4] = f1->nearV[0]; + ret.indexes[index+5] = f1->farV[1]; + ret.totalIndexes += 6; +#endif + } + } + + + // optimize + for ( j = 0 ; j < 2 ; j++ ) { + if ( !groups[j].triList ) { + continue; + } + if ( dmapGlobals.shadowOptLevel == SO_SIL_OPTIMIZE ) { + OptimizeGroupList( &groups[j] ); + } + // add as indexes + for ( mtri = groups[j].triList ; mtri ; mtri = mtri->next ) { + for ( k = 0 ; k < 3 ; k++ ) { + if ( ret.totalIndexes == maxRetIndexes ) { + common->Error( "maxRetIndexes exceeded" ); + } + ret.indexes[ret.totalIndexes] = FindUniqueVert( mtri->v[k].xyz ); + ret.totalIndexes++; + } + } + FreeTriList( groups[j].triList ); + } + } + + // we don't need the silPlane grouping anymore + Mem_Free( silPlanes ); +} + +/* +================= +EmitUnoptimizedSilEdges +================= +*/ +static void EmitUnoptimizedSilEdges( void ) { + int i; + + for ( i = 0 ; i < numSilEdges ; i++ ) { + int v1 = silEdges[i].index[0]; + int v2 = silEdges[i].index[1]; + int index = ret.totalIndexes; + ret.indexes[index+0] = v1; + ret.indexes[index+1] = v2; + ret.indexes[index+2] = v2+numUniquedBeforeProjection; + ret.indexes[index+3] = v1+numUniquedBeforeProjection; + ret.indexes[index+4] = v1; + ret.indexes[index+5] = v2+numUniquedBeforeProjection; + ret.totalIndexes += 6; + } +} + +//================================================================================== + +/* +================ +FindUniqueVert +================ +*/ +static int FindUniqueVert( idVec3 &v ) { + int k; + + for ( k = 0 ; k < numUniqued ; k++ ) { + idVec3 &check = uniqued[k]; + if ( fabs( v[0] - check[0] ) < UNIQUE_EPSILON + && fabs( v[1] - check[1] ) < UNIQUE_EPSILON + && fabs( v[2] - check[2] ) < UNIQUE_EPSILON ) { + return k; + } + } + if ( numUniqued == maxUniqued ) { + common->Error( "FindUniqueVert: numUniqued == maxUniqued" ); + } + uniqued[numUniqued] = v; + numUniqued++; + + return k; +} + +/* +=================== +UniqueVerts + +Snaps all triangle verts together, setting tri->index[] +and generating numUniqued and uniqued. +These are still in projection-centered space, not global space +=================== +*/ +static void UniqueVerts( void ) { + int i, j; + + // we may add to uniqued later when splitting sil edges, so leave + // some extra room + maxUniqued = 100000; // numOutputTris * 10 + 1000; + uniqued = (idVec3 *)Mem_Alloc( sizeof( *uniqued ) * maxUniqued ); + numUniqued = 0; + + for ( i = 0 ; i < numOutputTris ; i++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + outputTris[i].index[j] = FindUniqueVert( outputTris[i].v[j] ); + } + } +} + +/* +====================== +ProjectUniqued +====================== +*/ +static void ProjectUniqued( idVec3 projectionOrigin, idPlane projectionPlane ) { + // calculate the projection + idVec4 mat[4]; + + R_LightProjectionMatrix( projectionOrigin, projectionPlane, mat ); + + if ( numUniqued * 2 > maxUniqued ) { + common->Error( "ProjectUniqued: numUniqued * 2 > maxUniqued" ); + } + + // this is goofy going back and forth between the spaces, + // but I don't want to change R_LightProjectionMatrix righ tnow... + for ( int i = 0 ; i < numUniqued ; i++ ) { + // put the vert back in global space, instead of light centered space + idVec3 in = uniqued[i] + projectionOrigin; + + // project to far plane + float w, oow; + idVec3 out; + + w = in * mat[3].ToVec3() + mat[3][3]; + + oow = 1.0 / w; + out.x = ( in * mat[0].ToVec3() + mat[0][3] ) * oow; + out.y = ( in * mat[1].ToVec3() + mat[1][3] ) * oow; + out.z = ( in * mat[2].ToVec3() + mat[2][3] ) * oow; + + uniqued[numUniqued+i] = out - projectionOrigin; + } + numUniqued *= 2; +} + +/* +==================== +SuperOptimizeOccluders + +This is the callback from the renderer shadow generation routine, after +verts have been culled against individual frustums of point lights + +==================== +*/ +optimizedShadow_t SuperOptimizeOccluders( idVec4 *verts, glIndex_t *indexes, int numIndexes, + idPlane projectionPlane, idVec3 projectionOrigin ) +{ + memset( &ret, 0, sizeof( ret ) ); + + // generate outputTris, removing fragments that are occluded by closer fragments + ClipOccluders( verts, indexes, numIndexes, projectionOrigin ); + + if ( dmapGlobals.shadowOptLevel >= SO_CULL_OCCLUDED ) { + OptimizeOutputTris(); + } + + // match up common verts + UniqueVerts(); + + // now that we have uniqued the vertexes, we can find unmatched + // edges, which are silhouette planes + GenerateSilEdges(); + + // generate the projected verts + numUniquedBeforeProjection = numUniqued; + ProjectUniqued( projectionOrigin, projectionPlane ); + + // fragment the sil edges where the overlap, + // possibly generating some additional unique verts + if ( dmapGlobals.shadowOptLevel >= SO_CLIP_SILS ) { + FragmentSilQuads(); + } + + // indexes for face and projection caps + ret.numFrontCapIndexes = numOutputTris * 3; + ret.numRearCapIndexes = numOutputTris * 3; + if ( dmapGlobals.shadowOptLevel >= SO_CLIP_SILS ) { + ret.numSilPlaneIndexes = numSilQuads * 12; // this is the worst case with clipping + } else { + ret.numSilPlaneIndexes = numSilEdges * 6; // this is the worst case with clipping + } + + ret.totalIndexes = 0; + + maxRetIndexes = ret.numFrontCapIndexes + ret.numRearCapIndexes + ret.numSilPlaneIndexes; + + ret.indexes = (glIndex_t *)Mem_Alloc( maxRetIndexes * sizeof( ret.indexes[0] ) ); + for ( int i = 0 ; i < numOutputTris ; i++ ) { + // flip the indexes so the surface triangle faces outside the shadow volume + ret.indexes[i*3+0] = outputTris[i].index[2]; + ret.indexes[i*3+1] = outputTris[i].index[1]; + ret.indexes[i*3+2] = outputTris[i].index[0]; + + ret.indexes[(numOutputTris+i)*3+0] = numUniquedBeforeProjection + outputTris[i].index[0]; + ret.indexes[(numOutputTris+i)*3+1] = numUniquedBeforeProjection + outputTris[i].index[1]; + ret.indexes[(numOutputTris+i)*3+2] = numUniquedBeforeProjection + outputTris[i].index[2]; + } + // emit the sil planes + ret.totalIndexes = ret.numFrontCapIndexes + ret.numRearCapIndexes; + + if ( dmapGlobals.shadowOptLevel >= SO_CLIP_SILS ) { + // re-optimize the sil planes, cutting + EmitFragmentedSilQuads(); + } else { + // indexes for silhouette edges + EmitUnoptimizedSilEdges(); + } + + // we have all the verts now + // create twice the uniqued verts + ret.numVerts = numUniqued; + ret.verts = (idVec3 *)Mem_Alloc( ret.numVerts * sizeof( ret.verts[0] ) ); + for ( int i = 0 ; i < numUniqued ; i++ ) { + // put the vert back in global space, instead of light centered space + ret.verts[i] = uniqued[i] + projectionOrigin; + } + + // set the final index count + ret.numSilPlaneIndexes = ret.totalIndexes - (ret.numFrontCapIndexes + ret.numRearCapIndexes); + + // free out local data + Mem_Free( uniqued ); + + return ret; +} + +/* +================= +RemoveDegenerateTriangles +================= +*/ +static void RemoveDegenerateTriangles( srfTriangles_t *tri ) { + int c_removed; + int i; + int a, b, c; + + // check for completely degenerate triangles + c_removed = 0; + for ( i = 0 ; i < tri->numIndexes ; i+=3 ) { + a = tri->indexes[i]; + b = tri->indexes[i+1]; + c = tri->indexes[i+2]; + if ( a == b || a == c || b == c ) { + c_removed++; + memmove( tri->indexes + i, tri->indexes + i + 3, ( tri->numIndexes - i - 3 ) * sizeof( tri->indexes[0] ) ); + tri->numIndexes -= 3; + if ( i < tri->numShadowIndexesNoCaps ) { + tri->numShadowIndexesNoCaps -= 3; + } + if ( i < tri->numShadowIndexesNoFrontCaps ) { + tri->numShadowIndexesNoFrontCaps -= 3; + } + i -= 3; + } + } + + // this doesn't free the memory used by the unused verts + + if ( c_removed ) { + common->Printf( "removed %i degenerate triangles from shadow\n", c_removed ); + } +} + +/* +==================== +CleanupOptimizedShadowTris + +Uniques all verts across the frustums +removes matched sil quads at frustum seams +removes degenerate tris +==================== +*/ +void CleanupOptimizedShadowTris( srfTriangles_t *tri ) { + int i; + + // unique all the verts + maxUniqued = tri->numVerts; + uniqued = (idVec3 *)_alloca( sizeof( *uniqued ) * maxUniqued ); + numUniqued = 0; + + glIndex_t *remap = (glIndex_t *)_alloca( sizeof( *remap ) * tri->numVerts ); + + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + if ( tri->indexes[i] > tri->numVerts || tri->indexes[i] < 0 ) { + common->Error( "CleanupOptimizedShadowTris: index out of range" ); + } + } + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + remap[i] = FindUniqueVert( tri->shadowVertexes[i].xyz.ToVec3() ); + } + tri->numVerts = numUniqued; + for ( i = 0 ; i < tri->numVerts ; i++ ) { + tri->shadowVertexes[i].xyz.ToVec3() = uniqued[i]; + tri->shadowVertexes[i].xyz[3] = 1; + } + + for ( i = 0 ; i < tri->numIndexes ; i++ ) { + tri->indexes[i] = remap[tri->indexes[i]]; + } + + // remove matched quads + int numSilIndexes = tri->numShadowIndexesNoCaps; + for ( int i = 0 ; i < numSilIndexes ; i+=6 ) { + int j; + for ( j = i+6 ; j < numSilIndexes ; j+=6 ) { + // if there is a reversed quad match, we can throw both of them out + // this is not a robust check, it relies on the exact ordering of + // quad indexes + if ( tri->indexes[i+0] == tri->indexes[j+1] + && tri->indexes[i+1] == tri->indexes[j+0] + && tri->indexes[i+2] == tri->indexes[j+3] + && tri->indexes[i+3] == tri->indexes[j+5] + && tri->indexes[i+4] == tri->indexes[j+1] + && tri->indexes[i+5] == tri->indexes[j+3] ) { + break; + } + } + if ( j == numSilIndexes ) { + continue; + } + int k; + // remove first quad + for ( k = i+6 ; k < j ; k++ ) { + tri->indexes[k-6] = tri->indexes[k]; + } + // remove second quad + for ( k = j+6 ; k < tri->numIndexes ; k++ ) { + tri->indexes[k-12] = tri->indexes[k]; + } + numSilIndexes -= 12; + i -= 6; + } + + int removed = tri->numShadowIndexesNoCaps - numSilIndexes; + + tri->numIndexes -= removed; + tri->numShadowIndexesNoCaps -= removed; + tri->numShadowIndexesNoFrontCaps -= removed; + + // remove degenerates after we have removed quads, so the double + // triangle pairing isn't disturbed + RemoveDegenerateTriangles( tri ); +} + +/* +======================== +CreateLightShadow + +This is called from dmap in util/surface.cpp +shadowerGroups should be exactly clipped to the light frustum before calling. +shadowerGroups is optimized by this function, but the contents can be freed, because the returned +lightShadow_t list is a further culling and optimization of the data. +======================== +*/ +srfTriangles_t *CreateLightShadow( optimizeGroup_t *shadowerGroups, const mapLight_t *light ) {; + + common->Printf( "----- CreateLightShadow %p -----\n", light ); + + // optimize all the groups + OptimizeGroupList( shadowerGroups ); + + // combine all the triangles into one list + mapTri_t *combined; + + combined = NULL; + for ( optimizeGroup_t *group = shadowerGroups ; group ; group = group->nextGroup ) { + combined = MergeTriLists( combined, CopyTriList( group->triList ) ); + } + + if ( !combined ) { + return NULL; + } + + // find uniqued vertexes + srfTriangles_t *occluders = ShareMapTriVerts( combined ); + + FreeTriList( combined ); + + // find silhouette information for the triSurf + R_CleanupTriangles( occluders, false, true, false ); + + // let the renderer build the shadow volume normally + idRenderEntityLocal space; + + space.modelMatrix[0] = 1; + space.modelMatrix[5] = 1; + space.modelMatrix[10] = 1; + space.modelMatrix[15] = 1; + + srfCullInfo_t cullInfo; + memset( &cullInfo, 0, sizeof( cullInfo ) ); + + // call the normal shadow creation, but with the superOptimize flag set, which will + // call back to SuperOptimizeOccluders after clipping the triangles to each frustum + srfTriangles_t *shadowTris; + if ( dmapGlobals.shadowOptLevel == SO_MERGE_SURFACES ) { + shadowTris = R_CreateShadowVolume( &space, occluders, &light->def, SG_STATIC, cullInfo ); + } else { + shadowTris = R_CreateShadowVolume( &space, occluders, &light->def, SG_OFFLINE, cullInfo ); + } + R_FreeStaticTriSurf( occluders ); + + R_FreeInteractionCullInfo( cullInfo ); + + if ( shadowTris ) { + dmapGlobals.totalShadowTriangles += shadowTris->numIndexes / 3; + dmapGlobals.totalShadowVerts += shadowTris->numVerts / 3; + } + + return shadowTris; +} diff --git a/tools/compilers/dmap/tritjunction.cpp b/tools/compilers/dmap/tritjunction.cpp new file mode 100644 index 000000000..a34cbb96b --- /dev/null +++ b/tools/compilers/dmap/tritjunction.cpp @@ -0,0 +1,654 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +/* + + T junction fixing never creates more xyz points, but + new vertexes will be created when different surfaces + cause a fix + + The vertex cleaning accomplishes two goals: removing extranious low order + bits to avoid numbers like 1.000001233, and grouping nearby vertexes + together. Straight truncation accomplishes the first foal, but two vertexes + only a tiny epsilon apart could still be spread to different snap points. + To avoid this, we allow the merge test to group points together that + snapped to neighboring integer coordinates. + + Snaping verts can drag some triangles backwards or collapse them to points, + which will cause them to be removed. + + + When snapping to ints, a point can move a maximum of sqrt(3)/2 distance + Two points that were an epsilon apart can then become sqrt(3) apart + + A case that causes recursive overflow with point to triangle fixing: + + A + C D + B + + Triangle ABC tests against point D and splits into triangles ADC and DBC + Triangle DBC then tests against point A again and splits into ABC and ADB + infinite recursive loop + + + For a given source triangle + init the no-check list to hold the three triangle hashVerts + + recursiveFixTriAgainstHash + + recursiveFixTriAgainstHashVert_r + if hashVert is on the no-check list + exit + if the hashVert should split the triangle + add to the no-check list + recursiveFixTriAgainstHash(a) + recursiveFixTriAgainstHash(b) + +*/ + +#define SNAP_FRACTIONS 32 +//#define SNAP_FRACTIONS 8 +//#define SNAP_FRACTIONS 1 + +#define VERTEX_EPSILON ( 1.0 / SNAP_FRACTIONS ) + +#define COLINEAR_EPSILON ( 1.8 * VERTEX_EPSILON ) + +#define HASH_BINS 16 + +typedef struct hashVert_s { + struct hashVert_s *next; + idVec3 v; + int iv[3]; +} hashVert_t; + +static idBounds hashBounds; +static idVec3 hashScale; +static hashVert_t *hashVerts[HASH_BINS][HASH_BINS][HASH_BINS]; +static int numHashVerts, numTotalVerts; +static int hashIntMins[3], hashIntScale[3]; + +/* +=============== +GetHashVert + +Also modifies the original vert to the snapped value +=============== +*/ +struct hashVert_s *GetHashVert( idVec3 &v ) { + int iv[3]; + int block[3]; + int i; + hashVert_t *hv; + + numTotalVerts++; + + // snap the vert to integral values + for ( i = 0 ; i < 3 ; i++ ) { + iv[i] = floor( ( v[i] + 0.5/SNAP_FRACTIONS ) * SNAP_FRACTIONS ); + block[i] = ( iv[i] - hashIntMins[i] ) / hashIntScale[i]; + if ( block[i] < 0 ) { + block[i] = 0; + } else if ( block[i] >= HASH_BINS ) { + block[i] = HASH_BINS - 1; + } + } + + // see if a vertex near enough already exists + // this could still fail to find a near neighbor right at the hash block boundary + for ( hv = hashVerts[block[0]][block[1]][block[2]] ; hv ; hv = hv->next ) { +#if 0 + if ( hv->iv[0] == iv[0] && hv->iv[1] == iv[1] && hv->iv[2] == iv[2] ) { + VectorCopy( hv->v, v ); + return hv; + } +#else + for ( i = 0 ; i < 3 ; i++ ) { + int d; + d = hv->iv[i] - iv[i]; + if ( d < -1 || d > 1 ) { + break; + } + } + if ( i == 3 ) { + VectorCopy( hv->v, v ); + return hv; + } +#endif + } + + // create a new one + hv = (hashVert_t *)Mem_Alloc( sizeof( *hv ) ); + + hv->next = hashVerts[block[0]][block[1]][block[2]]; + hashVerts[block[0]][block[1]][block[2]] = hv; + + hv->iv[0] = iv[0]; + hv->iv[1] = iv[1]; + hv->iv[2] = iv[2]; + + hv->v[0] = (float)iv[0] / SNAP_FRACTIONS; + hv->v[1] = (float)iv[1] / SNAP_FRACTIONS; + hv->v[2] = (float)iv[2] / SNAP_FRACTIONS; + + VectorCopy( hv->v, v ); + + numHashVerts++; + + return hv; +} + + +/* +================== +HashBlocksForTri + +Returns an inclusive bounding box of hash +bins that should hold the triangle +================== +*/ +static void HashBlocksForTri( const mapTri_t *tri, int blocks[2][3] ) { + idBounds bounds; + int i; + + bounds.Clear(); + bounds.AddPoint( tri->v[0].xyz ); + bounds.AddPoint( tri->v[1].xyz ); + bounds.AddPoint( tri->v[2].xyz ); + + // add a 1.0 slop margin on each side + for ( i = 0 ; i < 3 ; i++ ) { + blocks[0][i] = ( bounds[0][i] - 1.0 - hashBounds[0][i] ) / hashScale[i]; + if ( blocks[0][i] < 0 ) { + blocks[0][i] = 0; + } else if ( blocks[0][i] >= HASH_BINS ) { + blocks[0][i] = HASH_BINS - 1; + } + + blocks[1][i] = ( bounds[1][i] + 1.0 - hashBounds[0][i] ) / hashScale[i]; + if ( blocks[1][i] < 0 ) { + blocks[1][i] = 0; + } else if ( blocks[1][i] >= HASH_BINS ) { + blocks[1][i] = HASH_BINS - 1; + } + } +} + + +/* +================= +HashTriangles + +Removes triangles that are degenerated or flipped backwards +================= +*/ +void HashTriangles( optimizeGroup_t *groupList ) { + mapTri_t *a; + int vert; + int i; + optimizeGroup_t *group; + + // clear the hash tables + memset( hashVerts, 0, sizeof( hashVerts ) ); + + numHashVerts = 0; + numTotalVerts = 0; + + // bound all the triangles to determine the bucket size + hashBounds.Clear(); + for ( group = groupList ; group ; group = group->nextGroup ) { + for ( a = group->triList ; a ; a = a->next ) { + hashBounds.AddPoint( a->v[0].xyz ); + hashBounds.AddPoint( a->v[1].xyz ); + hashBounds.AddPoint( a->v[2].xyz ); + } + } + + // spread the bounds so it will never have a zero size + for ( i = 0 ; i < 3 ; i++ ) { + hashBounds[0][i] = floor( hashBounds[0][i] - 1 ); + hashBounds[1][i] = ceil( hashBounds[1][i] + 1 ); + hashIntMins[i] = hashBounds[0][i] * SNAP_FRACTIONS; + + hashScale[i] = ( hashBounds[1][i] - hashBounds[0][i] ) / HASH_BINS; + hashIntScale[i] = hashScale[i] * SNAP_FRACTIONS; + if ( hashIntScale[i] < 1 ) { + hashIntScale[i] = 1; + } + } + + // add all the points to the hash buckets + for ( group = groupList ; group ; group = group->nextGroup ) { + // don't create tjunctions against discrete surfaces (blood decals, etc) + if ( group->material != NULL && group->material->IsDiscrete() ) { + continue; + } + for ( a = group->triList ; a ; a = a->next ) { + for ( vert = 0 ; vert < 3 ; vert++ ) { + a->hashVert[vert] = GetHashVert( a->v[vert].xyz ); + } + } + } +} + +/* +================= +FreeTJunctionHash + +The optimizer may add some more crossing verts +after t junction processing +================= +*/ +void FreeTJunctionHash( void ) { + int i, j, k; + hashVert_t *hv, *next; + + for ( i = 0 ; i < HASH_BINS ; i++ ) { + for ( j = 0 ; j < HASH_BINS ; j++ ) { + for ( k = 0 ; k < HASH_BINS ; k++ ) { + for ( hv = hashVerts[i][j][k] ; hv ; hv = next ) { + next = hv->next; + Mem_Free( hv ); + } + } + } + } + memset( hashVerts, 0, sizeof( hashVerts ) ); +} + + +/* +================== +FixTriangleAgainstHashVert + +Returns a list of two new mapTri if the hashVert is +on an edge of the given mapTri, otherwise returns NULL. +================== +*/ +static mapTri_t *FixTriangleAgainstHashVert( const mapTri_t *a, const hashVert_t *hv ) { + int i; + const idDrawVert *v1, *v2, *v3; + idDrawVert split; + idVec3 dir; + float len; + float frac; + mapTri_t *new1, *new2; + idVec3 temp; + float d, off; + const idVec3 *v; + idPlane plane1, plane2; + + v = &hv->v; + + // if the triangle already has this hashVert as a vert, + // it can't be split by it + if ( a->hashVert[0] == hv || a->hashVert[1] == hv || a->hashVert[2] == hv ) { + return NULL; + } + + // we probably should find the edge that the vertex is closest to. + // it is possible to be < 1 unit away from multiple + // edges, but we only want to split by one of them + for ( i = 0 ; i < 3 ; i++ ) { + v1 = &a->v[i]; + v2 = &a->v[(i+1)%3]; + v3 = &a->v[(i+2)%3]; + VectorSubtract( v2->xyz, v1->xyz, dir ); + len = dir.Normalize(); + + // if it is close to one of the edge vertexes, skip it + VectorSubtract( *v, v1->xyz, temp ); + d = DotProduct( temp, dir ); + if ( d <= 0 || d >= len ) { + continue; + } + + // make sure it is on the line + VectorMA( v1->xyz, d, dir, temp ); + VectorSubtract( temp, *v, temp ); + off = temp.Length(); + if ( off <= -COLINEAR_EPSILON || off >= COLINEAR_EPSILON ) { + continue; + } + + // take the x/y/z from the splitter, + // but interpolate everything else from the original tri + VectorCopy( *v, split.xyz ); + frac = d / len; + split.st[0] = v1->st[0] + frac * ( v2->st[0] - v1->st[0] ); + split.st[1] = v1->st[1] + frac * ( v2->st[1] - v1->st[1] ); + split.normal[0] = v1->normal[0] + frac * ( v2->normal[0] - v1->normal[0] ); + split.normal[1] = v1->normal[1] + frac * ( v2->normal[1] - v1->normal[1] ); + split.normal[2] = v1->normal[2] + frac * ( v2->normal[2] - v1->normal[2] ); + split.normal.Normalize(); + + // split the tri + new1 = CopyMapTri( a ); + new1->v[(i+1)%3] = split; + new1->hashVert[(i+1)%3] = hv; + new1->next = NULL; + + new2 = CopyMapTri( a ); + new2->v[i] = split; + new2->hashVert[i] = hv; + new2->next = new1; + + plane1.FromPoints( new1->hashVert[0]->v, new1->hashVert[1]->v, new1->hashVert[2]->v ); + plane2.FromPoints( new2->hashVert[0]->v, new2->hashVert[1]->v, new2->hashVert[2]->v ); + + d = DotProduct( plane1, plane2 ); + + // if the two split triangle's normals don't face the same way, + // it should not be split + if ( d <= 0 ) { + FreeTriList( new2 ); + continue; + } + + return new2; + } + + + return NULL; +} + + + +/* +================== +FixTriangleAgainstHash + +Potentially splits a triangle into a list of triangles based on tjunctions +================== +*/ +static mapTri_t *FixTriangleAgainstHash( const mapTri_t *tri ) { + mapTri_t *fixed; + mapTri_t *a; + mapTri_t *test, *next; + int blocks[2][3]; + int i, j, k; + hashVert_t *hv; + + // if this triangle is degenerate after point snapping, + // do nothing (this shouldn't happen, because they should + // be removed as they are hashed) + if ( tri->hashVert[0] == tri->hashVert[1] + || tri->hashVert[0] == tri->hashVert[2] + || tri->hashVert[1] == tri->hashVert[2] ) { + return NULL; + } + + fixed = CopyMapTri( tri ); + fixed->next = NULL; + + HashBlocksForTri( tri, blocks ); + for ( i = blocks[0][0] ; i <= blocks[1][0] ; i++ ) { + for ( j = blocks[0][1] ; j <= blocks[1][1] ; j++ ) { + for ( k = blocks[0][2] ; k <= blocks[1][2] ; k++ ) { + for ( hv = hashVerts[i][j][k] ; hv ; hv = hv->next ) { + // fix all triangles in the list against this point + test = fixed; + fixed = NULL; + for ( ; test ; test = next ) { + next = test->next; + a = FixTriangleAgainstHashVert( test, hv ); + if ( a ) { + // cut into two triangles + a->next->next = fixed; + fixed = a; + FreeTri( test ); + } else { + test->next = fixed; + fixed = test; + } + } + } + } + } + } + + return fixed; +} + + +/* +================== +CountGroupListTris +================== +*/ +int CountGroupListTris( const optimizeGroup_t *groupList ) { + int c; + + c = 0; + for ( ; groupList ; groupList = groupList->nextGroup ) { + c += CountTriList( groupList->triList ); + } + + return c; +} + +/* +================== +FixAreaGroupsTjunctions +================== +*/ +void FixAreaGroupsTjunctions( optimizeGroup_t *groupList ) { + const mapTri_t *tri; + mapTri_t *newList; + mapTri_t *fixed; + int startCount, endCount; + optimizeGroup_t *group; + + if ( dmapGlobals.noTJunc ) { + return; + } + + if ( !groupList ) { + return; + } + + startCount = CountGroupListTris( groupList ); + + if ( dmapGlobals.verbose ) { + common->Printf( "----- FixAreaGroupsTjunctions -----\n" ); + common->Printf( "%6i triangles in\n", startCount ); + } + + HashTriangles( groupList ); + + for ( group = groupList ; group ; group = group->nextGroup ) { + // don't touch discrete surfaces + if ( group->material != NULL && group->material->IsDiscrete() ) { + continue; + } + + newList = NULL; + for ( tri = group->triList ; tri ; tri = tri->next ) { + fixed = FixTriangleAgainstHash( tri ); + newList = MergeTriLists( newList, fixed ); + } + FreeTriList( group->triList ); + group->triList = newList; + } + + endCount = CountGroupListTris( groupList ); + if ( dmapGlobals.verbose ) { + common->Printf( "%6i triangles out\n", endCount ); + } +} + + +/* +================== +FixEntityTjunctions +================== +*/ +void FixEntityTjunctions( uEntity_t *e ) { + int i; + + for ( i = 0 ; i < e->numAreas ; i++ ) { + FixAreaGroupsTjunctions( e->areas[i].groups ); + FreeTJunctionHash(); + } +} + +/* +================== +FixGlobalTjunctions +================== +*/ +void FixGlobalTjunctions( uEntity_t *e ) { + mapTri_t *a; + int vert; + int i; + optimizeGroup_t *group; + int areaNum; + + common->Printf( "----- FixGlobalTjunctions -----\n" ); + + // clear the hash tables + memset( hashVerts, 0, sizeof( hashVerts ) ); + + numHashVerts = 0; + numTotalVerts = 0; + + // bound all the triangles to determine the bucket size + hashBounds.Clear(); + for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) { + for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) { + for ( a = group->triList ; a ; a = a->next ) { + hashBounds.AddPoint( a->v[0].xyz ); + hashBounds.AddPoint( a->v[1].xyz ); + hashBounds.AddPoint( a->v[2].xyz ); + } + } + } + + // spread the bounds so it will never have a zero size + for ( i = 0 ; i < 3 ; i++ ) { + hashBounds[0][i] = floor( hashBounds[0][i] - 1 ); + hashBounds[1][i] = ceil( hashBounds[1][i] + 1 ); + hashIntMins[i] = hashBounds[0][i] * SNAP_FRACTIONS; + + hashScale[i] = ( hashBounds[1][i] - hashBounds[0][i] ) / HASH_BINS; + hashIntScale[i] = hashScale[i] * SNAP_FRACTIONS; + if ( hashIntScale[i] < 1 ) { + hashIntScale[i] = 1; + } + } + + // add all the points to the hash buckets + for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) { + for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) { + // don't touch discrete surfaces + if ( group->material != NULL && group->material->IsDiscrete() ) { + continue; + } + + for ( a = group->triList ; a ; a = a->next ) { + for ( vert = 0 ; vert < 3 ; vert++ ) { + a->hashVert[vert] = GetHashVert( a->v[vert].xyz ); + } + } + } + } + + // add all the func_static model vertexes to the hash buckets + // optionally inline some of the func_static models + if ( dmapGlobals.entityNum == 0 ) { + for ( int eNum = 1 ; eNum < dmapGlobals.num_entities ; eNum++ ) { + uEntity_t *entity = &dmapGlobals.uEntities[eNum]; + const char *className = entity->mapEntity->epairs.GetString( "classname" ); + if ( idStr::Icmp( className, "func_static" ) ) { + continue; + } + const char *modelName = entity->mapEntity->epairs.GetString( "model" ); + if ( !modelName ) { + continue; + } + if ( !strstr( modelName, ".lwo" ) && !strstr( modelName, ".ase" ) && !strstr( modelName, ".ma" ) ) { + continue; + } + + idRenderModel *model = renderModelManager->FindModel( modelName ); + +// common->Printf( "adding T junction verts for %s.\n", entity->mapEntity->epairs.GetString( "name" ) ); + + idMat3 axis; + // get the rotation matrix in either full form, or single angle form + if ( !entity->mapEntity->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) { + float angle = entity->mapEntity->epairs.GetFloat( "angle" ); + if ( angle != 0.0f ) { + axis = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } else { + axis.Identity(); + } + } + + idVec3 origin = entity->mapEntity->epairs.GetVector( "origin" ); + + for ( i = 0 ; i < model->NumSurfaces() ; i++ ) { + const modelSurface_t *surface = model->Surface( i ); + const srfTriangles_t *tri = surface->geometry; + + mapTri_t mapTri; + memset( &mapTri, 0, sizeof( mapTri ) ); + mapTri.material = surface->shader; + // don't let discretes (autosprites, etc) merge together + if ( mapTri.material->IsDiscrete() ) { + mapTri.mergeGroup = (void *)surface; + } + for ( int j = 0 ; j < tri->numVerts ; j += 3 ) { + idVec3 v = tri->verts[j].xyz * axis + origin; + GetHashVert( v ); + } + } + } + } + + + + // now fix each area + for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) { + for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) { + // don't touch discrete surfaces + if ( group->material != NULL && group->material->IsDiscrete() ) { + continue; + } + + mapTri_t *newList = NULL; + for ( mapTri_t *tri = group->triList ; tri ; tri = tri->next ) { + mapTri_t *fixed = FixTriangleAgainstHash( tri ); + newList = MergeTriLists( newList, fixed ); + } + FreeTriList( group->triList ); + group->triList = newList; + } + } + + + // done + FreeTJunctionHash(); +} diff --git a/tools/compilers/dmap/tritools.cpp b/tools/compilers/dmap/tritools.cpp new file mode 100644 index 000000000..2d2fce560 --- /dev/null +++ b/tools/compilers/dmap/tritools.cpp @@ -0,0 +1,378 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +/* + + All triangle list functions should behave reasonably with NULL lists. + +*/ + +/* +=============== +AllocTri +=============== +*/ +mapTri_t *AllocTri( void ) { + mapTri_t *tri; + + tri = (mapTri_t *)Mem_Alloc( sizeof( *tri ) ); + memset( tri, 0, sizeof( *tri ) ); + return tri; +} + +/* +=============== +FreeTri +=============== +*/ +void FreeTri( mapTri_t *tri ) { + Mem_Free( tri ); +} + + +/* +=============== +MergeTriLists + +This does not copy any tris, it just relinks them +=============== +*/ +mapTri_t *MergeTriLists( mapTri_t *a, mapTri_t *b ) { + mapTri_t **prev; + + prev = &a; + while ( *prev ) { + prev = &(*prev)->next; + } + + *prev = b; + + return a; +} + + +/* +=============== +FreeTriList +=============== +*/ +void FreeTriList( mapTri_t *a ) { + mapTri_t *next; + + for ( ; a ; a = next ) { + next = a->next; + Mem_Free( a ); + } +} + +/* +=============== +CopyTriList +=============== +*/ +mapTri_t *CopyTriList( const mapTri_t *a ) { + mapTri_t *testList; + const mapTri_t *tri; + + testList = NULL; + for ( tri = a ; tri ; tri = tri->next ) { + mapTri_t *copy; + + copy = CopyMapTri( tri ); + copy ->next = testList; + testList = copy; + } + + return testList; +} + + +/* +============= +CountTriList +============= +*/ +int CountTriList( const mapTri_t *tri ) { + int c; + + c = 0; + while ( tri ) { + c++; + tri = tri->next; + } + + return c; +} + + +/* +=============== +CopyMapTri +=============== +*/ +mapTri_t *CopyMapTri( const mapTri_t *tri ) { + mapTri_t *t; + + t = (mapTri_t *)Mem_Alloc( sizeof( *t ) ); + *t = *tri; + + return t; +} + +/* +=============== +MapTriArea +=============== +*/ +float MapTriArea( const mapTri_t *tri ) { + return idWinding::TriangleArea( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz ); +} + +/* +=============== +RemoveBadTris + +Return a new list with any zero or negative area triangles removed +=============== +*/ +mapTri_t *RemoveBadTris( const mapTri_t *list ) { + mapTri_t *newList; + mapTri_t *copy; + const mapTri_t *tri; + + newList = NULL; + + for ( tri = list ; tri ; tri = tri->next ) { + if ( MapTriArea( tri ) > 0 ) { + copy = CopyMapTri( tri ); + copy->next = newList; + newList = copy; + } + } + + return newList; +} + +/* +================ +BoundTriList +================ +*/ +void BoundTriList( const mapTri_t *list, idBounds &b ) { + b.Clear(); + for ( ; list ; list = list->next ) { + b.AddPoint( list->v[0].xyz ); + b.AddPoint( list->v[1].xyz ); + b.AddPoint( list->v[2].xyz ); + } +} + +/* +================ +DrawTri +================ +*/ +void DrawTri( const mapTri_t *tri ) { + idWinding w; + + w.SetNumPoints( 3 ); + VectorCopy( tri->v[0].xyz, w[0] ); + VectorCopy( tri->v[1].xyz, w[1] ); + VectorCopy( tri->v[2].xyz, w[2] ); + DrawWinding( &w ); +} + + +/* +================ +FlipTriList + +Swaps the vertex order +================ +*/ +void FlipTriList( mapTri_t *tris ) { + mapTri_t *tri; + + for ( tri = tris ; tri ; tri = tri->next ) { + idDrawVert v; + const struct hashVert_s *hv; + struct optVertex_s *ov; + + v = tri->v[0]; + tri->v[0] = tri->v[2]; + tri->v[2] = v; + + hv = tri->hashVert[0]; + tri->hashVert[0] = tri->hashVert[2]; + tri->hashVert[2] = hv; + + ov = tri->optVert[0]; + tri->optVert[0] = tri->optVert[2]; + tri->optVert[2] = ov; + } +} + +/* +================ +WindingForTri +================ +*/ +idWinding *WindingForTri( const mapTri_t *tri ) { + idWinding *w; + + w = new idWinding( 3 ); + w->SetNumPoints( 3 ); + VectorCopy( tri->v[0].xyz, (*w)[0] ); + VectorCopy( tri->v[1].xyz, (*w)[1] ); + VectorCopy( tri->v[2].xyz, (*w)[2] ); + + return w; +} + +/* +================ +TriVertsFromOriginal + +Regenerate the texcoords and colors on a fragmented tri from the plane equations +================ +*/ +void TriVertsFromOriginal( mapTri_t *tri, const mapTri_t *original ) { + int i, j; + float denom; + + denom = idWinding::TriangleArea( original->v[0].xyz, original->v[1].xyz, original->v[2].xyz ); + if ( denom == 0 ) { + return; // original was degenerate, so it doesn't matter + } + + for ( i = 0 ; i < 3 ; i++ ) { + float a, b, c; + + // find the barycentric coordinates + a = idWinding::TriangleArea( tri->v[i].xyz, original->v[1].xyz, original->v[2].xyz ) / denom; + b = idWinding::TriangleArea( tri->v[i].xyz, original->v[2].xyz, original->v[0].xyz ) / denom; + c = idWinding::TriangleArea( tri->v[i].xyz, original->v[0].xyz, original->v[1].xyz ) / denom; + + // regenerate the interpolated values + tri->v[i].st[0] = a * original->v[0].st[0] + + b * original->v[1].st[0] + c * original->v[2].st[0]; + tri->v[i].st[1] = a * original->v[0].st[1] + + b * original->v[1].st[1] + c * original->v[2].st[1]; + + for ( j = 0 ; j < 3 ; j++ ) { + tri->v[i].normal[j] = a * original->v[0].normal[j] + + b * original->v[1].normal[j] + c * original->v[2].normal[j]; + } + tri->v[i].normal.Normalize(); + } +} + +/* +================ +WindingToTriList + +Generates a new list of triangles with proper texcoords from a winding +created by clipping the originalTri + +OriginalTri can be NULL if you don't care about texCoords +================ +*/ +mapTri_t *WindingToTriList( const idWinding *w, const mapTri_t *originalTri ) { + mapTri_t *tri; + mapTri_t *triList; + int i, j; + const idVec3 *vec; + + if ( !w ) { + return NULL; + } + + triList = NULL; + for ( i = 2 ; i < w->GetNumPoints() ; i++ ) { + tri = AllocTri(); + if ( !originalTri ) { + memset( tri, 0, sizeof( *tri ) ); + } else { + *tri = *originalTri; + } + tri->next = triList; + triList = tri; + + for ( j = 0 ; j < 3 ; j++ ) { + if ( j == 0 ) { + vec = &((*w)[0]).ToVec3(); + } else if ( j == 1 ) { + vec = &((*w)[i-1]).ToVec3(); + } else { + vec = &((*w)[i]).ToVec3(); + } + + VectorCopy( *vec, tri->v[j].xyz ); + } + if ( originalTri ) { + TriVertsFromOriginal( tri, originalTri ); + } + } + + return triList; +} + + +/* +================== +ClipTriList +================== +*/ +void ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon, + mapTri_t **front, mapTri_t **back ) { + const mapTri_t *tri; + mapTri_t *newList; + idWinding *w, *frontW, *backW; + + *front = NULL; + *back = NULL; + + for ( tri = list ; tri ; tri = tri->next ) { + w = WindingForTri( tri ); + w->Split( plane, epsilon, &frontW, &backW ); + + newList = WindingToTriList( frontW, tri ); + *front = MergeTriLists( *front, newList ); + + newList = WindingToTriList( backW, tri ); + *back = MergeTriLists( *back, newList ); + + delete w; + } + +} + +/* +================== +PlaneForTri +================== +*/ +void PlaneForTri( const mapTri_t *tri, idPlane &plane ) { + plane.FromPoints( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz ); +} diff --git a/tools/compilers/dmap/ubrush.cpp b/tools/compilers/dmap/ubrush.cpp new file mode 100644 index 000000000..bcf6d4640 --- /dev/null +++ b/tools/compilers/dmap/ubrush.cpp @@ -0,0 +1,700 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + +int c_active_brushes; + +int c_nodes; + +// if a brush just barely pokes onto the other side, +// let it slide by without chopping +#define PLANESIDE_EPSILON 0.001 +//0.1 + + + + +/* +================ +CountBrushList +================ +*/ +int CountBrushList (uBrush_t *brushes) +{ + int c; + + c = 0; + for ( ; brushes ; brushes = brushes->next) + c++; + return c; +} + + +int BrushSizeForSides( int numsides ) { + int c; + + // allocate a structure with a variable number of sides at the end +// c = (int)&(((uBrush_t *)0)->sides[numsides]); // bounds checker complains about this + c = sizeof( uBrush_t ) + sizeof( side_t ) * (numsides - 6); + + return c; +} + +/* +================ +AllocBrush +================ +*/ +uBrush_t *AllocBrush (int numsides) +{ + uBrush_t *bb; + int c; + + c = BrushSizeForSides( numsides ); + + bb = (uBrush_t *)Mem_Alloc(c); + memset (bb, 0, c); + c_active_brushes++; + return bb; +} + +/* +================ +FreeBrush +================ +*/ +void FreeBrush (uBrush_t *brushes) +{ + int i; + + for ( i = 0 ; i < brushes->numsides ; i++ ) { + if ( brushes->sides[i].winding ) { + delete brushes->sides[i].winding; + } + if ( brushes->sides[i].visibleHull ) { + delete brushes->sides[i].visibleHull; + } + } + Mem_Free (brushes); + c_active_brushes--; +} + + +/* +================ +FreeBrushList +================ +*/ +void FreeBrushList (uBrush_t *brushes) +{ + uBrush_t *next; + + for ( ; brushes ; brushes = next) + { + next = brushes->next; + + FreeBrush (brushes); + } +} + +/* +================== +CopyBrush + +Duplicates the brush, the sides, and the windings +================== +*/ +uBrush_t *CopyBrush (uBrush_t *brush) +{ + uBrush_t *newbrush; + int size; + int i; + + size = BrushSizeForSides( brush->numsides ); + + newbrush = AllocBrush (brush->numsides); + memcpy (newbrush, brush, size); + + for (i=0 ; inumsides ; i++) + { + if (brush->sides[i].winding) + newbrush->sides[i].winding = brush->sides[i].winding->Copy(); + } + + return newbrush; +} + + +/* +================ +DrawBrushList +================ +*/ +void DrawBrushList (uBrush_t *brush) +{ + int i; + side_t *s; + + GLS_BeginScene (); + for ( ; brush ; brush=brush->next) + { + for (i=0 ; inumsides ; i++) + { + s = &brush->sides[i]; + if (!s->winding) + continue; + GLS_Winding (s->winding, 0); + } + } + GLS_EndScene (); +} + + +/* +============= +PrintBrush +============= +*/ +void PrintBrush (uBrush_t *brush) +{ + int i; + + common->Printf( "brush: %p\n", brush ); + for ( i=0;inumsides ; i++ ) { + brush->sides[i].winding->Print(); + common->Printf ("\n"); + } +} + +/* +================== +BoundBrush + +Sets the mins/maxs based on the windings +returns false if the brush doesn't enclose a valid volume +================== +*/ +bool BoundBrush (uBrush_t *brush) { + int i, j; + idWinding *w; + + brush->bounds.Clear(); + for ( i = 0; i < brush->numsides; i++ ) { + w = brush->sides[i].winding; + if (!w) + continue; + for ( j = 0; j < w->GetNumPoints(); j++ ) + brush->bounds.AddPoint( (*w)[j].ToVec3() ); + } + + for ( i = 0; i < 3; i++ ) { + if (brush->bounds[0][i] < MIN_WORLD_COORD || brush->bounds[1][i] > MAX_WORLD_COORD + || brush->bounds[0][i] >= brush->bounds[1][i] ) { + return false; + } + } + + return true; +} + +/* +================== +CreateBrushWindings + +makes basewindigs for sides and mins / maxs for the brush +returns false if the brush doesn't enclose a valid volume +================== +*/ +bool CreateBrushWindings (uBrush_t *brush) { + int i, j; + idWinding *w; + idPlane *plane; + side_t *side; + + for ( i = 0; i < brush->numsides; i++ ) { + side = &brush->sides[i]; + plane = &dmapGlobals.mapPlanes[side->planenum]; + w = new idWinding( *plane ); + for ( j = 0; j < brush->numsides && w; j++ ) { + if ( i == j ) { + continue; + } + if ( brush->sides[j].planenum == ( brush->sides[i].planenum ^ 1 ) ) { + continue; // back side clipaway + } + plane = &dmapGlobals.mapPlanes[brush->sides[j].planenum^1]; + w = w->Clip( *plane, 0 );//CLIP_EPSILON); + } + if ( side->winding ) { + delete side->winding; + } + side->winding = w; + } + + return BoundBrush( brush ); +} + +/* +================== +BrushFromBounds + +Creates a new axial brush +================== +*/ +uBrush_t *BrushFromBounds( const idBounds &bounds ) { + uBrush_t *b; + int i; + idPlane plane; + + b = AllocBrush (6); + b->numsides = 6; + for (i=0 ; i<3 ; i++) { + plane[0] = plane[1] = plane[2] = 0; + plane[i] = 1; + plane[3] = -bounds[1][i]; + b->sides[i].planenum = FindFloatPlane( plane ); + + plane[i] = -1; + plane[3] = bounds[0][i]; + b->sides[3+i].planenum = FindFloatPlane( plane ); + } + + CreateBrushWindings (b); + + return b; +} + +/* +================== +BrushVolume + +================== +*/ +float BrushVolume (uBrush_t *brush) { + int i; + idWinding *w; + idVec3 corner; + float d, area, volume; + idPlane *plane; + + if (!brush) + return 0; + + // grab the first valid point as the corner + + w = NULL; + for ( i = 0; i < brush->numsides; i++ ) { + w = brush->sides[i].winding; + if (w) + break; + } + if (!w) { + return 0; + } + VectorCopy ( (*w)[0], corner); + + // make tetrahedrons to all other faces + + volume = 0; + for ( ; i < brush->numsides; i++ ) + { + w = brush->sides[i].winding; + if (!w) + continue; + plane = &dmapGlobals.mapPlanes[brush->sides[i].planenum]; + d = -plane->Distance( corner ); + area = w->GetArea(); + volume += d * area; + } + + volume /= 3; + return volume; +} + + +/* +================== +WriteBspBrushMap + +FIXME: use new brush format +================== +*/ +void WriteBspBrushMap( const char *name, uBrush_t *list ) { + idFile * f; + side_t * s; + int i; + idWinding * w; + + common->Printf ("writing %s\n", name); + f = fileSystem->OpenFileWrite( name ); + + if ( !f ) { + common->Error( "Can't write %s\b", name); + } + + f->Printf( "{\n\"classname\" \"worldspawn\"\n" ); + + for ( ; list ; list=list->next ) + { + f->Printf( "{\n" ); + for (i=0,s=list->sides ; inumsides ; i++,s++) + { + w = new idWinding( dmapGlobals.mapPlanes[s->planenum] ); + + f->Printf ("( %i %i %i ) ", (int)(*w)[0][0], (int)(*w)[0][1], (int)(*w)[0][2]); + f->Printf ("( %i %i %i ) ", (int)(*w)[1][0], (int)(*w)[1][1], (int)(*w)[1][2]); + f->Printf ("( %i %i %i ) ", (int)(*w)[2][0], (int)(*w)[2][1], (int)(*w)[2][2]); + + f->Printf ("notexture 0 0 0 1 1\n" ); + delete w; + } + f->Printf ("}\n"); + } + f->Printf ("}\n"); + + fileSystem->CloseFile(f); + +} + + +//===================================================================================== + +/* +==================== +FilterBrushIntoTree_r + +==================== +*/ +int FilterBrushIntoTree_r( uBrush_t *b, node_t *node ) { + uBrush_t *front, *back; + int c; + + if ( !b ) { + return 0; + } + + // add it to the leaf list + if ( node->planenum == PLANENUM_LEAF ) { + b->next = node->brushlist; + node->brushlist = b; + + // classify the leaf by the structural brush + if ( b->opaque ) { + node->opaque = true; + } + + return 1; + } + + // split it by the node plane + SplitBrush ( b, node->planenum, &front, &back ); + FreeBrush( b ); + + c = 0; + c += FilterBrushIntoTree_r( front, node->children[0] ); + c += FilterBrushIntoTree_r( back, node->children[1] ); + + return c; +} + + +/* +===================== +FilterBrushesIntoTree + +Mark the leafs as opaque and areaportals and put brush +fragments in each leaf so portal surfaces can be matched +to materials +===================== +*/ +void FilterBrushesIntoTree( uEntity_t *e ) { + primitive_t *prim; + uBrush_t *b, *newb; + int r; + int c_unique, c_clusters; + + common->Printf( "----- FilterBrushesIntoTree -----\n"); + + c_unique = 0; + c_clusters = 0; + for ( prim = e->primitives ; prim ; prim = prim->next ) { + b = prim->brush; + if ( !b ) { + continue; + } + c_unique++; + newb = CopyBrush( b ); + r = FilterBrushIntoTree_r( newb, e->tree->headnode ); + c_clusters += r; + } + + common->Printf( "%5i total brushes\n", c_unique ); + common->Printf( "%5i cluster references\n", c_clusters ); +} + + + +/* +================ +AllocTree +================ +*/ +tree_t *AllocTree (void) +{ + tree_t *tree; + + tree = (tree_t *)Mem_Alloc(sizeof(*tree)); + memset (tree, 0, sizeof(*tree)); + tree->bounds.Clear(); + + return tree; +} + +/* +================ +AllocNode +================ +*/ +node_t *AllocNode (void) +{ + node_t *node; + + node = (node_t *)Mem_Alloc(sizeof(*node)); + memset (node, 0, sizeof(*node)); + + return node; +} + +//============================================================ + +/* +================== +BrushMostlyOnSide + +================== +*/ +int BrushMostlyOnSide (uBrush_t *brush, idPlane &plane) { + int i, j; + idWinding *w; + float d, max; + int side; + + max = 0; + side = PSIDE_FRONT; + for ( i = 0; i < brush->numsides; i++ ) { + w = brush->sides[i].winding; + if (!w) + continue; + for ( j = 0; j < w->GetNumPoints(); j++ ) + { + d = plane.Distance( (*w)[j].ToVec3() ); + if (d > max) + { + max = d; + side = PSIDE_FRONT; + } + if (-d > max) + { + max = -d; + side = PSIDE_BACK; + } + } + } + return side; +} + +/* +================ +SplitBrush + +Generates two new brushes, leaving the original +unchanged +================ +*/ +void SplitBrush (uBrush_t *brush, int planenum, uBrush_t **front, uBrush_t **back) { + uBrush_t *b[2]; + int i, j; + idWinding *w, *cw[2], *midwinding; + side_t *s, *cs; + float d, d_front, d_back; + + *front = *back = NULL; + idPlane &plane = dmapGlobals.mapPlanes[planenum]; + + // check all points + d_front = d_back = 0; + for ( i = 0; i < brush->numsides; i++ ) + { + w = brush->sides[i].winding; + if (!w) { + continue; + } + for ( j = 0; j < w->GetNumPoints(); j++ ) { + d = plane.Distance( (*w)[j].ToVec3() ); + if (d > 0 && d > d_front) + d_front = d; + if (d < 0 && d < d_back) + d_back = d; + } + } + if (d_front < 0.1) // PLANESIDE_EPSILON) + { // only on back + *back = CopyBrush( brush ); + return; + } + if (d_back > -0.1) // PLANESIDE_EPSILON) + { // only on front + *front = CopyBrush( brush ); + return; + } + + // create a new winding from the split plane + + w = new idWinding( plane ); + for ( i = 0; i < brush->numsides && w; i++ ) { + idPlane &plane2 = dmapGlobals.mapPlanes[brush->sides[i].planenum ^ 1]; + w = w->Clip( plane2, 0 ); // PLANESIDE_EPSILON); + } + + if ( !w || w->IsTiny() ) { + // the brush isn't really split + int side; + + side = BrushMostlyOnSide( brush, plane ); + if (side == PSIDE_FRONT) + *front = CopyBrush (brush); + if (side == PSIDE_BACK) + *back = CopyBrush (brush); + return; + } + + if ( w->IsHuge() ) { + common->Printf ("WARNING: huge winding\n"); + } + + midwinding = w; + + // split it for real + + for ( i = 0; i < 2; i++ ) { + b[i] = AllocBrush (brush->numsides+1); + memcpy( b[i], brush, sizeof( uBrush_t ) - sizeof( brush->sides ) ); + b[i]->numsides = 0; + b[i]->next = NULL; + b[i]->original = brush->original; + } + + // split all the current windings + + for ( i = 0; i < brush->numsides; i++ ) { + s = &brush->sides[i]; + w = s->winding; + if (!w) + continue; + w->Split( plane, 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1] ); + for ( j = 0; j < 2; j++ ) { + if ( !cw[j] ) { + continue; + } +/* + if ( cw[j]->IsTiny() ) + { + delete cw[j]; + continue; + } +*/ + cs = &b[j]->sides[b[j]->numsides]; + b[j]->numsides++; + *cs = *s; + cs->winding = cw[j]; + } + } + + + // see if we have valid polygons on both sides + + for (i=0 ; i<2 ; i++) + { + if ( !BoundBrush (b[i]) ) { + break; + } + + if ( b[i]->numsides < 3 ) + { + FreeBrush (b[i]); + b[i] = NULL; + } + } + + if ( !(b[0] && b[1]) ) + { + if (!b[0] && !b[1]) + common->Printf ("split removed brush\n"); + else + common->Printf ("split not on both sides\n"); + if (b[0]) + { + FreeBrush (b[0]); + *front = CopyBrush (brush); + } + if (b[1]) + { + FreeBrush (b[1]); + *back = CopyBrush (brush); + } + return; + } + + // add the midwinding to both sides + for (i=0 ; i<2 ; i++) + { + cs = &b[i]->sides[b[i]->numsides]; + b[i]->numsides++; + + cs->planenum = planenum^i^1; + cs->material = NULL; + if (i==0) + cs->winding = midwinding->Copy(); + else + cs->winding = midwinding; + } + +{ + float v1; + int i; + + for (i=0 ; i<2 ; i++) + { + v1 = BrushVolume (b[i]); + if (v1 < 1.0) + { + FreeBrush (b[i]); + b[i] = NULL; +// common->Printf ("tiny volume after clip\n"); + } + } +} + + *front = b[0]; + *back = b[1]; +} diff --git a/tools/compilers/dmap/usurface.cpp b/tools/compilers/dmap/usurface.cpp new file mode 100644 index 000000000..421f093e7 --- /dev/null +++ b/tools/compilers/dmap/usurface.cpp @@ -0,0 +1,1037 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "dmap.h" + + +#define TEXTURE_OFFSET_EQUAL_EPSILON 0.005 +#define TEXTURE_VECTOR_EQUAL_EPSILON 0.001 + +/* +=============== +AddTriListToArea + +The triList is appended to the apropriate optimzeGroup_t, +creating a new one if needed. +The entire list is assumed to come from the same planar primitive +=============== +*/ +static void AddTriListToArea( uEntity_t *e, mapTri_t *triList, int planeNum, int areaNum, textureVectors_t *texVec ) { + uArea_t *area; + optimizeGroup_t *group; + int i, j; + + if ( !triList ) { + return; + } + + area = &e->areas[areaNum]; + for ( group = area->groups ; group ; group = group->nextGroup ) { + if ( group->material == triList->material + && group->planeNum == planeNum + && group->mergeGroup == triList->mergeGroup ) { + // check the texture vectors + for ( i = 0 ; i < 2 ; i++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + if ( idMath::Fabs( texVec->v[i][j] - group->texVec.v[i][j] ) > TEXTURE_VECTOR_EQUAL_EPSILON ) { + break; + } + } + if ( j != 3 ) { + break; + } + if ( idMath::Fabs( texVec->v[i][3] - group->texVec.v[i][3] ) > TEXTURE_OFFSET_EQUAL_EPSILON ) { + break; + } + } + if ( i == 2 ) { + break; // exact match + } else { + // different texture offsets + i = 1; // just for debugger breakpoint + } + } + } + + if ( !group ) { + group = (optimizeGroup_t *)Mem_Alloc( sizeof( *group ) ); + memset( group, 0, sizeof( *group ) ); + group->planeNum = planeNum; + group->mergeGroup = triList->mergeGroup; + group->material = triList->material; + group->nextGroup = area->groups; + group->texVec = *texVec; + area->groups = group; + } + + group->triList = MergeTriLists( group->triList, triList ); +} + +/* +=================== +TexVecForTri +=================== +*/ +static void TexVecForTri( textureVectors_t *texVec, mapTri_t *tri ) { + float area, inva; + idVec3 temp; + idVec5 d0, d1; + idDrawVert *a, *b, *c; + + a = &tri->v[0]; + b = &tri->v[1]; + c = &tri->v[2]; + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = b->st[0] - a->st[0]; + d0[4] = b->st[1] - a->st[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = c->st[0] - a->st[0]; + d1[4] = c->st[1] - a->st[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + inva = 1.0 / area; + + temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva; + temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva; + temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva; + temp.Normalize(); + texVec->v[0].ToVec3() = temp; + texVec->v[0][3] = tri->v[0].xyz * texVec->v[0].ToVec3() - tri->v[0].st[0]; + + temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva; + temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva; + temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva; + temp.Normalize(); + texVec->v[1].ToVec3() = temp; + texVec->v[1][3] = tri->v[0].xyz * texVec->v[0].ToVec3() - tri->v[0].st[1]; +} + + +/* +================= +TriListForSide +================= +*/ +//#define SNAP_FLOAT_TO_INT 8 +#define SNAP_FLOAT_TO_INT 256 +#define SNAP_INT_TO_FLOAT (1.0/SNAP_FLOAT_TO_INT) + +mapTri_t *TriListForSide( const side_t *s, const idWinding *w ) { + int i, j; + idDrawVert *dv; + mapTri_t *tri, *triList; + const idVec3 *vec; + const idMaterial *si; + + si = s->material; + + // skip any generated faces + if ( !si ) { + return NULL; + } + + // don't create faces for non-visible sides + if ( !si->SurfaceCastsShadow() && !si->IsDrawn() ) { + return NULL; + } + + if ( 1 ) { + // triangle fan using only the outer verts + // this gives the minimum triangle count, + // but may have some very distended triangles + triList = NULL; + for ( i = 2 ; i < w->GetNumPoints() ; i++ ) { + tri = AllocTri(); + tri->material = si; + tri->next = triList; + triList = tri; + + for ( j = 0 ; j < 3 ; j++ ) { + if ( j == 0 ) { + vec = &((*w)[0]).ToVec3(); + } else if ( j == 1 ) { + vec = &((*w)[i-1]).ToVec3(); + } else { + vec = &((*w)[i]).ToVec3(); + } + + dv = tri->v + j; +#if 0 + // round the xyz to a given precision + for ( k = 0 ; k < 3 ; k++ ) { + dv->xyz[k] = SNAP_INT_TO_FLOAT * floor( vec[k] * SNAP_FLOAT_TO_INT + 0.5 ); + } +#else + VectorCopy( *vec, dv->xyz ); +#endif + + // calculate texture s/t from brush primitive texture matrix + dv->st[0] = DotProduct( dv->xyz, s->texVec.v[0] ) + s->texVec.v[0][3]; + dv->st[1] = DotProduct( dv->xyz, s->texVec.v[1] ) + s->texVec.v[1][3]; + + // copy normal + dv->normal = dmapGlobals.mapPlanes[s->planenum].Normal(); + if ( dv->normal.Length() < 0.9 || dv->normal.Length() > 1.1 ) { + common->Error( "Bad normal in TriListForSide" ); + } + } + } + } else { + // triangle fan from central point, more verts and tris, but less distended + // I use this when debugging some tjunction problems + triList = NULL; + for ( i = 0 ; i < w->GetNumPoints() ; i++ ) { + idVec3 midPoint; + + tri = AllocTri(); + tri->material = si; + tri->next = triList; + triList = tri; + + for ( j = 0 ; j < 3 ; j++ ) { + if ( j == 0 ) { + vec = &midPoint; + midPoint = w->GetCenter(); + } else if ( j == 1 ) { + vec = &((*w)[i]).ToVec3(); + } else { + vec = &((*w)[(i+1)%w->GetNumPoints()]).ToVec3(); + } + + dv = tri->v + j; + + VectorCopy( *vec, dv->xyz ); + + // calculate texture s/t from brush primitive texture matrix + dv->st[0] = DotProduct( dv->xyz, s->texVec.v[0] ) + s->texVec.v[0][3]; + dv->st[1] = DotProduct( dv->xyz, s->texVec.v[1] ) + s->texVec.v[1][3]; + + // copy normal + dv->normal = dmapGlobals.mapPlanes[s->planenum].Normal(); + if ( dv->normal.Length() < 0.9f || dv->normal.Length() > 1.1f ) { + common->Error( "Bad normal in TriListForSide" ); + } + } + } + } + + // set merge groups if needed, to prevent multiple sides from being + // merged into a single surface in the case of gui shaders, mirrors, and autosprites + if ( s->material->IsDiscrete() ) { + for ( tri = triList ; tri ; tri = tri->next ) { + tri->mergeGroup = (void *)s; + } + } + + return triList; +} + +//================================================================================= + +/* +==================== +ClipSideByTree_r + +Adds non-opaque leaf fragments to the convex hull +==================== +*/ +static void ClipSideByTree_r( idWinding *w, side_t *side, node_t *node ) { + idWinding *front, *back; + + if ( !w ) { + return; + } + + if ( node->planenum != PLANENUM_LEAF ) { + if ( side->planenum == node->planenum ) { + ClipSideByTree_r( w, side, node->children[0] ); + return; + } + if ( side->planenum == ( node->planenum ^ 1) ) { + ClipSideByTree_r( w, side, node->children[1] ); + return; + } + + w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); + delete w; + + ClipSideByTree_r( front, side, node->children[0] ); + ClipSideByTree_r( back, side, node->children[1] ); + + return; + } + + // if opaque leaf, don't add + if ( !node->opaque ) { + if ( !side->visibleHull ) { + side->visibleHull = w->Copy(); + } + else { + side->visibleHull->AddToConvexHull( w, dmapGlobals.mapPlanes[ side->planenum ].Normal() ); + } + } + + delete w; + return; +} + + +/* +===================== +ClipSidesByTree + +Creates side->visibleHull for all visible sides + +The visible hull for a side will consist of the convex hull of +all points in non-opaque clusters, which allows overlaps +to be trimmed off automatically. +===================== +*/ +void ClipSidesByTree( uEntity_t *e ) { + uBrush_t *b; + int i; + idWinding *w; + side_t *side; + primitive_t *prim; + + common->Printf( "----- ClipSidesByTree -----\n"); + + for ( prim = e->primitives ; prim ; prim = prim->next ) { + b = prim->brush; + if ( !b ) { + // FIXME: other primitives! + continue; + } + for ( i = 0 ; i < b->numsides ; i++ ) { + side = &b->sides[i]; + if ( !side->winding) { + continue; + } + w = side->winding->Copy(); + side->visibleHull = NULL; + ClipSideByTree_r( w, side, e->tree->headnode ); + // for debugging, we can choose to use the entire original side + // but we skip this if the side was completely clipped away + if ( side->visibleHull && dmapGlobals.noClipSides ) { + delete side->visibleHull; + side->visibleHull = side->winding->Copy(); + } + } + } +} + + + +//================================================================================= + +/* +==================== +ClipTriIntoTree_r + +This is used for adding curve triangles +The winding will be freed before it returns +==================== +*/ +void ClipTriIntoTree_r( idWinding *w, mapTri_t *originalTri, uEntity_t *e, node_t *node ) { + idWinding *front, *back; + + if ( !w ) { + return; + } + + if ( node->planenum != PLANENUM_LEAF ) { + w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); + delete w; + + ClipTriIntoTree_r( front, originalTri, e, node->children[0] ); + ClipTriIntoTree_r( back, originalTri, e, node->children[1] ); + + return; + } + + // if opaque leaf, don't add + if ( !node->opaque && node->area >= 0 ) { + mapTri_t *list; + int planeNum; + idPlane plane; + textureVectors_t texVec; + + list = WindingToTriList( w, originalTri ); + + PlaneForTri( originalTri, plane ); + planeNum = FindFloatPlane( plane ); + + TexVecForTri( &texVec, originalTri ); + + AddTriListToArea( e, list, planeNum, node->area, &texVec ); + } + + delete w; + return; +} + + + +//============================================================= + +/* +==================== +CheckWindingInAreas_r + +Returns the area number that the winding is in, or +-2 if it crosses multiple areas. + +==================== +*/ +static int CheckWindingInAreas_r( const idWinding *w, node_t *node ) { + idWinding *front, *back; + + if ( !w ) { + return -1; + } + + if ( node->planenum != PLANENUM_LEAF ) { + int a1, a2; +#if 0 + if ( side->planenum == node->planenum ) { + return CheckWindingInAreas_r( w, node->children[0] ); + } + if ( side->planenum == ( node->planenum ^ 1) ) { + return CheckWindingInAreas_r( w, node->children[1] ); + } +#endif + w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); + + a1 = CheckWindingInAreas_r( front, node->children[0] ); + delete front; + a2 = CheckWindingInAreas_r( back, node->children[1] ); + delete back; + + if ( a1 == -2 || a2 == -2 ) { + return -2; // different + } + if ( a1 == -1 ) { + return a2; // one solid + } + if ( a2 == -1 ) { + return a1; // one solid + } + + if ( a1 != a2 ) { + return -2; // cross areas + } + return a1; + } + + return node->area; +} + + + +/* +==================== +PutWindingIntoAreas_r + +Clips a winding down into the bsp tree, then converts +the fragments to triangles and adds them to the area lists +==================== +*/ +static void PutWindingIntoAreas_r( uEntity_t *e, const idWinding *w, side_t *side, node_t *node ) { + idWinding *front, *back; + int area; + + if ( !w ) { + return; + } + + if ( node->planenum != PLANENUM_LEAF ) { + if ( side->planenum == node->planenum ) { + PutWindingIntoAreas_r( e, w, side, node->children[0] ); + return; + } + if ( side->planenum == ( node->planenum ^ 1) ) { + PutWindingIntoAreas_r( e, w, side, node->children[1] ); + return; + } + + // see if we need to split it + // adding the "noFragment" flag to big surfaces like sky boxes + // will avoid potentially dicing them up into tons of triangles + // that take forever to optimize back together + if ( !dmapGlobals.fullCarve || side->material->NoFragment() ) { + area = CheckWindingInAreas_r( w, node ); + if ( area >= 0 ) { + mapTri_t *tri; + + // put in single area + tri = TriListForSide( side, w ); + AddTriListToArea( e, tri, side->planenum, area, &side->texVec ); + return; + } + } + + w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); + + PutWindingIntoAreas_r( e, front, side, node->children[0] ); + if ( front ) { + delete front; + } + + PutWindingIntoAreas_r( e, back, side, node->children[1] ); + if ( back ) { + delete back; + } + + return; + } + + // if opaque leaf, don't add + if ( node->area >= 0 && !node->opaque ) { + mapTri_t *tri; + + tri = TriListForSide( side, w ); + AddTriListToArea( e, tri, side->planenum, node->area, &side->texVec ); + } +} + +/* +================== +AddMapTriToAreas + +Used for curves and inlined models +================== +*/ +void AddMapTriToAreas( mapTri_t *tri, uEntity_t *e ) { + int area; + idWinding *w; + + // skip degenerate triangles from pinched curves + if ( MapTriArea( tri ) <= 0 ) { + return; + } + + if ( dmapGlobals.fullCarve ) { + // always fragment into areas + w = WindingForTri( tri ); + ClipTriIntoTree_r( w, tri, e, e->tree->headnode ); + return; + } + + w = WindingForTri( tri ); + area = CheckWindingInAreas_r( w, e->tree->headnode ); + delete w; + if ( area == -1 ) { + return; + } + if ( area >= 0 ) { + mapTri_t *newTri; + idPlane plane; + int planeNum; + textureVectors_t texVec; + + // put in single area + newTri = CopyMapTri( tri ); + newTri->next = NULL; + + PlaneForTri( tri, plane ); + planeNum = FindFloatPlane( plane ); + + TexVecForTri( &texVec, newTri ); + + AddTriListToArea( e, newTri, planeNum, area, &texVec ); + } else { + // fragment into areas + w = WindingForTri( tri ); + ClipTriIntoTree_r( w, tri, e, e->tree->headnode ); + } +} + +/* +===================== +PutPrimitivesInAreas + +===================== +*/ +void PutPrimitivesInAreas( uEntity_t *e ) { + uBrush_t *b; + int i; + side_t *side; + primitive_t *prim; + mapTri_t *tri; + + common->Printf( "----- PutPrimitivesInAreas -----\n"); + + // allocate space for surface chains for each area + e->areas = (uArea_t *)Mem_Alloc( e->numAreas * sizeof( e->areas[0] ) ); + memset( e->areas, 0, e->numAreas * sizeof( e->areas[0] ) ); + + // for each primitive, clip it to the non-solid leafs + // and divide it into different areas + for ( prim = e->primitives ; prim ; prim = prim->next ) { + b = prim->brush; + + if ( !b ) { + // add curve triangles + for ( tri = prim->tris ; tri ; tri = tri->next ) { + AddMapTriToAreas( tri, e ); + } + continue; + } + + // clip in brush sides + for ( i = 0 ; i < b->numsides ; i++ ) { + side = &b->sides[i]; + if ( !side->visibleHull ) { + continue; + } + PutWindingIntoAreas_r( e, side->visibleHull, side, e->tree->headnode ); + } + } + + + // optionally inline some of the func_static models + if ( dmapGlobals.entityNum == 0 ) { + bool inlineAll = dmapGlobals.uEntities[0].mapEntity->epairs.GetBool( "inlineAllStatics" ); + + for ( int eNum = 1 ; eNum < dmapGlobals.num_entities ; eNum++ ) { + uEntity_t *entity = &dmapGlobals.uEntities[eNum]; + const char *className = entity->mapEntity->epairs.GetString( "classname" ); + if ( idStr::Icmp( className, "func_static" ) ) { + continue; + } + if ( !entity->mapEntity->epairs.GetBool( "inline" ) && !inlineAll ) { + continue; + } + const char *modelName = entity->mapEntity->epairs.GetString( "model" ); + if ( !modelName ) { + continue; + } + idRenderModel *model = renderModelManager->FindModel( modelName ); + + common->Printf( "inlining %s.\n", entity->mapEntity->epairs.GetString( "name" ) ); + + idMat3 axis; + // get the rotation matrix in either full form, or single angle form + if ( !entity->mapEntity->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) { + float angle = entity->mapEntity->epairs.GetFloat( "angle" ); + if ( angle != 0.0f ) { + axis = idAngles( 0.0f, angle, 0.0f ).ToMat3(); + } else { + axis.Identity(); + } + } + + idVec3 origin = entity->mapEntity->epairs.GetVector( "origin" ); + + for ( i = 0 ; i < model->NumSurfaces() ; i++ ) { + const modelSurface_t *surface = model->Surface( i ); + const srfTriangles_t *tri = surface->geometry; + + mapTri_t mapTri; + memset( &mapTri, 0, sizeof( mapTri ) ); + mapTri.material = surface->shader; + // don't let discretes (autosprites, etc) merge together + if ( mapTri.material->IsDiscrete() ) { + mapTri.mergeGroup = (void *)surface; + } + for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) { + for ( int k = 0 ; k < 3 ; k++ ) { + idVec3 v = tri->verts[tri->indexes[j+k]].xyz; + + mapTri.v[k].xyz = v * axis + origin; + + mapTri.v[k].normal = tri->verts[tri->indexes[j+k]].normal * axis; + mapTri.v[k].st = tri->verts[tri->indexes[j+k]].st; + } + AddMapTriToAreas( &mapTri, e ); + } + } + } + } +} + +//============================================================================ + +/* +================= +ClipTriByLight + +Carves a triangle by the frustom planes of a light, producing +a (possibly empty) list of triangles on the inside and outside. + +The original triangle is not modified. + +If no clipping is required, the result will be a copy of the original. + +If clipping was required, the outside fragments will be planar clips, which +will benefit from re-optimization. +================= +*/ +static void ClipTriByLight( const mapLight_t *light, const mapTri_t *tri, + mapTri_t **in, mapTri_t **out ) { + idWinding *inside, *oldInside; + idWinding *outside[6]; + bool hasOutside; + int i; + + *in = NULL; + *out = NULL; + + // clip this winding to the light + inside = WindingForTri( tri ); + hasOutside = false; + for ( i = 0 ; i < 6 ; i++ ) { + oldInside = inside; + if ( oldInside ) { + oldInside->Split( light->def.frustum[i], 0, &outside[i], &inside ); + delete oldInside; + } + else { + outside[i] = NULL; + } + if ( outside[i] ) { + hasOutside = true; + } + } + + if ( !inside ) { + // the entire winding is outside this light + + // free the clipped fragments + for ( i = 0 ; i < 6 ; i++ ) { + if ( outside[i] ) { + delete outside[i]; + } + } + + *out = CopyMapTri( tri ); + (*out)->next = NULL; + + return; + } + + if ( !hasOutside ) { + // the entire winding is inside this light + + // free the inside copy + delete inside; + + *in = CopyMapTri( tri ); + (*in)->next = NULL; + + return; + } + + // the winding is split + *in = WindingToTriList( inside, tri ); + delete inside; + + // combine all the outside fragments + for ( i = 0 ; i < 6 ; i++ ) { + if ( outside[i] ) { + mapTri_t *list; + + list = WindingToTriList( outside[i], tri ); + delete outside[i]; + *out = MergeTriLists( *out, list ); + } + } +} + +/* +================= +BoundOptimizeGroup +================= +*/ +static void BoundOptimizeGroup( optimizeGroup_t *group ) { + group->bounds.Clear(); + for ( mapTri_t *tri = group->triList ; tri ; tri = tri->next ) { + group->bounds.AddPoint( tri->v[0].xyz ); + group->bounds.AddPoint( tri->v[1].xyz ); + group->bounds.AddPoint( tri->v[2].xyz ); + } +} + +/* +==================== +BuildLightShadows + +Build the beam tree and shadow volume surface for a light +==================== +*/ +static void BuildLightShadows( uEntity_t *e, mapLight_t *light ) { + int i; + optimizeGroup_t *group; + mapTri_t *tri; + mapTri_t *shadowers; + optimizeGroup_t *shadowerGroups; + idVec3 lightOrigin; + bool hasPerforatedSurface = false; + + // + // build a group list of all the triangles that will contribute to + // the optimized shadow volume, leaving the original triangles alone + // + + + // shadowers will contain all the triangles that will contribute to the + // shadow volume + shadowerGroups = NULL; + lightOrigin = light->def.globalLightOrigin; + + // if the light is no-shadows, don't add any surfaces + // to the beam tree at all + if ( !light->def.parms.noShadows + && light->def.lightShader->LightCastsShadows() ) { + for ( i = 0 ; i < e->numAreas ; i++ ) { + for ( group = e->areas[i].groups ; group ; group = group->nextGroup ) { + // if the surface doesn't cast shadows, skip it + if ( !group->material->SurfaceCastsShadow() ) { + continue; + } + + // if the group doesn't face away from the light, it + // won't contribute to the shadow volume + if ( dmapGlobals.mapPlanes[ group->planeNum ].Distance( lightOrigin ) > 0 ) { + continue; + } + + // if the group bounds doesn't intersect the light bounds, + // skip it + if ( !group->bounds.IntersectsBounds( light->def.frustumTris->bounds ) ) { + continue; + } + + // build up a list of the triangle fragments inside the + // light frustum + shadowers = NULL; + for ( tri = group->triList ; tri ; tri = tri->next ) { + mapTri_t *in, *out; + + // clip it to the light frustum + ClipTriByLight( light, tri, &in, &out ); + FreeTriList( out ); + shadowers = MergeTriLists( shadowers, in ); + } + + // if we didn't get any out of this group, we don't + // need to create a new group in the shadower list + if ( !shadowers ) { + continue; + } + + // find a group in shadowerGroups to add these to + // we will ignore everything but planenum, and we + // can merge across areas + optimizeGroup_t *check; + + for ( check = shadowerGroups ; check ; check = check->nextGroup ) { + if ( check->planeNum == group->planeNum ) { + break; + } + } + if ( !check ) { + check = (optimizeGroup_t *)Mem_Alloc( sizeof( *check ) ); + *check = *group; + check->triList = NULL; + check->nextGroup = shadowerGroups; + shadowerGroups = check; + } + + // if any surface is a shadow-casting perforated or translucent surface, we + // can't use the face removal optimizations because we can see through + // some of the faces + if ( group->material->Coverage() != MC_OPAQUE ) { + hasPerforatedSurface = true; + } + + check->triList = MergeTriLists( check->triList, shadowers ); + } + } + } + + // take the shadower group list and create a beam tree and shadow volume + light->shadowTris = CreateLightShadow( shadowerGroups, light ); + + if ( light->shadowTris && hasPerforatedSurface ) { + // can't ever remove front faces, because we can see through some of them + light->shadowTris->numShadowIndexesNoCaps = light->shadowTris->numShadowIndexesNoFrontCaps = + light->shadowTris->numIndexes; + } + + // we don't need the original shadower triangles for anything else + FreeOptimizeGroupList( shadowerGroups ); +} + + +/* +==================== +CarveGroupsByLight + +Divide each group into an inside group and an outside group, based +on which fragments are illuminated by the light's beam tree +==================== +*/ +static void CarveGroupsByLight( uEntity_t *e, mapLight_t *light ) { + int i; + optimizeGroup_t *group, *newGroup, *carvedGroups, *nextGroup; + mapTri_t *tri, *inside, *outside; + uArea_t *area; + + for ( i = 0 ; i < e->numAreas ; i++ ) { + area = &e->areas[i]; + carvedGroups = NULL; + + // we will be either freeing or reassigning the groups as we go + for ( group = area->groups ; group ; group = nextGroup ) { + nextGroup = group->nextGroup; + // if the surface doesn't get lit, don't carve it up + if ( ( light->def.lightShader->IsFogLight() && !group->material->ReceivesFog() ) + || ( !light->def.lightShader->IsFogLight() && !group->material->ReceivesLighting() ) + || !group->bounds.IntersectsBounds( light->def.frustumTris->bounds ) ) { + + group->nextGroup = carvedGroups; + carvedGroups = group; + continue; + } + + if ( group->numGroupLights == MAX_GROUP_LIGHTS ) { + common->Error( "MAX_GROUP_LIGHTS around %f %f %f", + group->triList->v[0].xyz[0], group->triList->v[0].xyz[1], group->triList->v[0].xyz[2] ); + } + + // if the group doesn't face the light, + // it won't get carved at all + if ( !light->def.lightShader->LightEffectsBackSides() && + !group->material->ReceivesLightingOnBackSides() && + dmapGlobals.mapPlanes[ group->planeNum ].Distance( light->def.parms.origin ) <= 0 ) { + + group->nextGroup = carvedGroups; + carvedGroups = group; + continue; + } + + // split into lists for hit-by-light, and not-hit-by-light + inside = NULL; + outside = NULL; + + for ( tri = group->triList ; tri ; tri = tri->next ) { + mapTri_t *in, *out; + + ClipTriByLight( light, tri, &in, &out ); + inside = MergeTriLists( inside, in ); + outside = MergeTriLists( outside, out ); + } + + if ( inside ) { + newGroup = (optimizeGroup_t *)Mem_Alloc( sizeof( *newGroup ) ); + *newGroup = *group; + newGroup->groupLights[newGroup->numGroupLights] = light; + newGroup->numGroupLights++; + newGroup->triList = inside; + newGroup->nextGroup = carvedGroups; + carvedGroups = newGroup; + } + + if ( outside ) { + newGroup = (optimizeGroup_t *)Mem_Alloc( sizeof( *newGroup ) ); + *newGroup = *group; + newGroup->triList = outside; + newGroup->nextGroup = carvedGroups; + carvedGroups = newGroup; + } + + // free the original + group->nextGroup = NULL; + FreeOptimizeGroupList( group ); + } + + // replace this area's group list with the new one + area->groups = carvedGroups; + } +} + +/* +===================== +Prelight + +Break optimize groups up into additional groups at light boundaries, so +optimization won't cross light bounds +===================== +*/ +void Prelight( uEntity_t *e ) { + int i; + int start, end; + mapLight_t *light; + + // don't prelight anything but the world entity + if ( dmapGlobals.entityNum != 0 ) { + return; + } + + if ( dmapGlobals.shadowOptLevel > 0 ) { + common->Printf( "----- BuildLightShadows -----\n" ); + start = Sys_Milliseconds(); + + // calc bounds for all the groups to speed things up + for ( i = 0 ; i < e->numAreas ; i++ ) { + uArea_t *area = &e->areas[i]; + + for ( optimizeGroup_t *group = area->groups ; group ; group = group->nextGroup ) { + BoundOptimizeGroup( group ); + } + } + + for ( i = 0 ; i < dmapGlobals.mapLights.Num() ; i++ ) { + light = dmapGlobals.mapLights[i]; + BuildLightShadows( e, light ); + } + + end = Sys_Milliseconds(); + common->Printf( "%5.1f seconds for BuildLightShadows\n", ( end - start ) / 1000.0 ); + } + + + if ( !dmapGlobals.noLightCarve ) { + common->Printf( "----- CarveGroupsByLight -----\n" ); + start = Sys_Milliseconds(); + // now subdivide the optimize groups into additional groups for + // each light that illuminates them + for ( i = 0 ; i < dmapGlobals.mapLights.Num() ; i++ ) { + light = dmapGlobals.mapLights[i]; + CarveGroupsByLight( e, light ); + } + + end = Sys_Milliseconds(); + common->Printf( "%5.1f seconds for CarveGroupsByLight\n", ( end - start ) / 1000.0 ); + } + +} + + + diff --git a/tools/compilers/renderbump/renderbump.cpp b/tools/compilers/renderbump/renderbump.cpp new file mode 100644 index 000000000..6dfd52a9b --- /dev/null +++ b/tools/compilers/renderbump/renderbump.cpp @@ -0,0 +1,1632 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#ifdef WIN32 +#include +#include +#include +#include "../../../sys/win32/win_local.h" +#endif + +#include "../../../renderer/tr_local.h" + +/* + + render a normalmap tga file from an ase model for bump mapping + + To make ray-tracing into the high poly mesh efficient, we preconstruct + a 3D hash table of the triangles that need to be tested for a given source + point. + + This task is easier than a general ray tracing optimization, because we + known that all of the triangles are going to be "near" the source point. + + TraceFraction determines the maximum distance in any direction that + a trace will go. It is expressed as a fraction of the largest axis of + the bounding box, so it doesn't matter what units are used for modeling. + + +*/ + +#define MAX_QPATH 256 + +#define DEFAULT_TRACE_FRACTION 0.05 + +#define INITIAL_TRI_TO_LINK_EXPANSION 16 // can grow as needed +#define HASH_AXIS_BINS 100 + +typedef struct { + int faceNum; + int nextLink; +} triLink_t; + +typedef struct { + int triLink; + int rayNumber; // don't need to test again if still on same ray +} binLink_t; + +#define MAX_LINKS_PER_BLOCK 0x100000 +#define MAX_LINK_BLOCKS 0x100 +typedef struct { + idBounds bounds; + float binSize[3]; + int numLinkBlocks; + triLink_t *linkBlocks[MAX_LINK_BLOCKS]; + binLink_t binLinks[HASH_AXIS_BINS][HASH_AXIS_BINS][HASH_AXIS_BINS]; +} triHash_t; + +typedef struct { + char outputName[MAX_QPATH]; + char highName[MAX_QPATH]; + byte *localPic; + byte *globalPic; + byte *colorPic; + float *edgeDistances; // starts out -1 for untraced, for each texel, 0 = true interior, >0 = off-edge rasterization + int width, height; + int antiAlias; + int outline; + bool saveGlobalMap; + bool saveColorMap; + float traceFrac; + float traceDist; + srfTriangles_t *mesh; // high poly mesh + idRenderModel *highModel; + triHash_t *hash; +} renderBump_t; + +static float traceFraction; +static int rayNumber; // for avoiding retests of bins and faces + +static int oldWidth, oldHeight; + +/* +=============== +SaveWindow +=============== +*/ +static void SaveWindow( void ) { + oldWidth = glConfig.vidWidth; + oldHeight = glConfig.vidHeight; +} + +/* +=============== +ResizeWindow +=============== +*/ +static void ResizeWindow( int width, int height ) { +#ifdef WIN32 + int winWidth, winHeight; + if ( glConfig.isFullscreen ) { + winWidth = width; + winHeight = height; + } else { + RECT r; + + // adjust width and height for window border + r.bottom = height; + r.left = 0; + r.top = 0; + r.right = width; + + AdjustWindowRect (&r, WINDOW_STYLE|WS_SYSMENU, FALSE); + winHeight = r.bottom - r.top; + winWidth = r.right - r.left; + + } + SetWindowPos( win32.hWnd, HWND_TOP, 0, 0, winWidth, winHeight, SWP_SHOWWINDOW ); + + qwglMakeCurrent( win32.hDC, win32.hGLRC ); +#endif +} + +/* +=============== +RestoreWindow +=============== +*/ +static void RestoreWindow( void ) { +#ifdef WIN32 + int winWidth, winHeight; + if ( glConfig.isFullscreen ) { + winWidth = oldWidth; + winHeight = oldHeight; + } else { + RECT r; + + // adjust width and height for window border + r.bottom = oldHeight; + r.left = 0; + r.top = 0; + r.right = oldWidth; + + AdjustWindowRect (&r, WINDOW_STYLE|WS_SYSMENU, FALSE); + winHeight = r.bottom - r.top; + winWidth = r.right - r.left; + } + SetWindowPos( win32.hWnd, HWND_TOP, 0, 0, winWidth, winHeight, SWP_SHOWWINDOW ); +#endif +} + +/* +================ +OutlineNormalMap + +Puts a single pixel border around all non-empty pixels +Does NOT copy the alpha channel, so it can be used as +an alpha test map. +================ +*/ +static void OutlineNormalMap( byte *data, int width, int height, int emptyR, int emptyG, int emptyB ) { + byte *orig; + int i, j, k, l; + idVec3 normal; + byte *out; + + orig = (byte *)Mem_Alloc( width * height * 4 ); + memcpy( orig, data, width * height * 4 ); + + for ( i = 0 ; i < width ; i++ ) { + for ( j = 0 ; j < height ; j++ ) { + out = data + ( j * width + i ) * 4; + if ( out[0] != emptyR || out[1] != emptyG || out[2] != emptyB ) { + continue; + } + + normal = vec3_origin; + for ( k = -1 ; k < 2 ; k++ ) { + for ( l = -1 ; l < 2 ; l++ ) { + byte *in; + + in = orig + ( ((j+l)&(height-1))*width + ((i+k)&(width-1)) ) * 4; + + if ( in[0] == emptyR && in[1] == emptyG && in[2] == emptyB ) { + continue; + } + + normal[0] += ( in[0] - 128 ); + normal[1] += ( in[1] - 128 ); + normal[2] += ( in[2] - 128 ); + } + } + + if ( normal.Normalize() < 0.5 ) { + continue; // no valid samples + } + + out[0] = 128 + 127 * normal[0]; + out[1] = 128 + 127 * normal[1]; + out[2] = 128 + 127 * normal[2]; + } + } + + Mem_Free( orig ); +} + +/* +================ +OutlineColorMap + +Puts a single pixel border around all non-empty pixels +Does NOT copy the alpha channel, so it can be used as +an alpha test map. +================ +*/ +static void OutlineColorMap( byte *data, int width, int height, int emptyR, int emptyG, int emptyB ) { + byte *orig; + int i, j, k, l; + idVec3 normal; + byte *out; + + orig = (byte *)Mem_Alloc( width * height * 4 ); + memcpy( orig, data, width * height * 4 ); + + for ( i = 0 ; i < width ; i++ ) { + for ( j = 0 ; j < height ; j++ ) { + out = data + ( j * width + i ) * 4; + if ( out[0] != emptyR || out[1] != emptyG || out[2] != emptyB ) { + continue; + } + + normal = vec3_origin; + int count = 0; + for ( k = -1 ; k < 2 ; k++ ) { + for ( l = -1 ; l < 2 ; l++ ) { + byte *in; + + in = orig + ( ((j+l)&(height-1))*width + ((i+k)&(width-1)) ) * 4; + + if ( in[0] == emptyR && in[1] == emptyG && in[2] == emptyB ) { + continue; + } + + normal[0] += in[0]; + normal[1] += in[1]; + normal[2] += in[2]; + count++; + } + } + + if ( !count ) { + continue; + } + normal *= (1.0 / count ); + + out[0] = normal[0]; + out[1] = normal[1]; + out[2] = normal[2]; + } + } + + Mem_Free( orig ); +} + + + +/* +================ +FreeTriHash +================ +*/ +static void FreeTriHash( triHash_t *hash ) { + for ( int i = 0 ; i < hash->numLinkBlocks ; i++ ) { + Mem_Free( hash->linkBlocks[i] ); + } + Mem_Free( hash ); +} + +/* +================ +CreateTriHash +================ +*/ +static triHash_t *CreateTriHash( const srfTriangles_t *highMesh ) { + triHash_t *hash; + int i, j, k, l; + idBounds bounds, triBounds; + int iBounds[2][3]; + int maxLinks, numLinks; + + hash = (triHash_t *)Mem_Alloc( sizeof( *hash ) ); + memset( hash, 0, sizeof( *hash ) ); + + // find the bounding volume for the mesh + bounds.Clear(); + for ( i = 0 ; i < highMesh->numVerts ; i++ ) { + bounds.AddPoint( highMesh->verts[i].xyz ); + } + + hash->bounds = bounds; + + // divide each axis as needed + for ( i = 0 ; i < 3 ; i++ ) { + hash->binSize[i] = ( bounds[1][i] - bounds[0][i] ) / HASH_AXIS_BINS; + if ( hash->binSize[i] <= 0 ) { + common->FatalError( "CreateTriHash: bad bounds: (%f %f %f) to (%f %f %f)", + bounds[0][0],bounds[0][1],bounds[0][2], + bounds[1][0],bounds[1][1],bounds[1][2] ); + } + } + + // a -1 link number terminated the link chain + memset( hash->binLinks, -1, sizeof( hash->binLinks ) ); + + numLinks = 0; + + hash->linkBlocks[hash->numLinkBlocks] = (triLink_t *)Mem_Alloc( MAX_LINKS_PER_BLOCK * sizeof( triLink_t ) ); + hash->numLinkBlocks++; + maxLinks = hash->numLinkBlocks * MAX_LINKS_PER_BLOCK; + + // for each triangle, place a triLink in each bin that might reference it + for ( i = 0 ; i < highMesh->numIndexes ; i+=3 ) { + // determine which hash bins the triangle will need to be in + triBounds.Clear(); + for ( j = 0 ; j < 3 ; j++ ) { + triBounds.AddPoint( highMesh->verts[ highMesh->indexes[i+j] ].xyz ); + } + for ( j = 0 ; j < 3 ; j++ ) { + iBounds[0][j] = ( triBounds[0][j] - hash->bounds[0][j] ) / hash->binSize[j]; + iBounds[0][j] -= 0.001; // epsilon + if ( iBounds[0][j] < 0 ) { + iBounds[0][j] = 0; + } else if ( iBounds[0][j] >= HASH_AXIS_BINS ) { + iBounds[0][j] = HASH_AXIS_BINS-1; + } + + iBounds[1][j] = ( triBounds[1][j] - hash->bounds[0][j] ) / hash->binSize[j]; + iBounds[0][j] += 0.001; // epsilon + if ( iBounds[1][j] < 0 ) { + iBounds[1][j] = 0; + } else if ( iBounds[1][j] >= HASH_AXIS_BINS ) { + iBounds[1][j] = HASH_AXIS_BINS-1; + } + } + + // add the links + for ( j = iBounds[0][0] ; j <= iBounds[1][0] ; j++ ) { + for ( k = iBounds[0][1] ; k <= iBounds[1][1] ; k++ ) { + for ( l = iBounds[0][2] ; l <= iBounds[1][2] ; l++ ) { + if ( numLinks == maxLinks ) { + hash->linkBlocks[hash->numLinkBlocks] = (triLink_t *)Mem_Alloc( MAX_LINKS_PER_BLOCK * sizeof( triLink_t ) ); + hash->numLinkBlocks++; + maxLinks = hash->numLinkBlocks * MAX_LINKS_PER_BLOCK; + } + + triLink_t *link = &hash->linkBlocks[ numLinks / MAX_LINKS_PER_BLOCK ][ numLinks % MAX_LINKS_PER_BLOCK ]; + link->faceNum = i / 3; + link->nextLink = hash->binLinks[j][k][l].triLink; + hash->binLinks[j][k][l].triLink = numLinks; + numLinks++; + } + } + } + } + + common->Printf( "%i triangles made %i links\n", highMesh->numIndexes / 3, numLinks ); + + return hash; +} + + +/* +================= +TraceToMeshFace + +Returns the distance from the point to the intersection, or DIST_NO_INTERSECTION +================= +*/ +#define DIST_NO_INTERSECTION -999999999.0f +static float TraceToMeshFace( const srfTriangles_t *highMesh, int faceNum, + float minDist, float maxDist, + const idVec3 &point, const idVec3 &normal, idVec3 &sampledNormal, + byte sampledColor[4] ) { + int j; + float dist; + const idVec3 *v[3]; + const idPlane *plane; + idVec3 edge; + float d; + idVec3 dir[3]; + float baseArea; + float bary[3]; + idVec3 testVert; + + v[0] = &highMesh->verts[ highMesh->indexes[ faceNum * 3 + 0 ] ].xyz; + v[1] = &highMesh->verts[ highMesh->indexes[ faceNum * 3 + 1 ] ].xyz; + v[2] = &highMesh->verts[ highMesh->indexes[ faceNum * 3 + 2 ] ].xyz; + + plane = highMesh->facePlanes + faceNum; + + // only test against planes facing the same direction as our normal + d = plane->Normal() * normal; + if ( d <= 0.0001f ) { + return DIST_NO_INTERSECTION; + } + + // find the point of impact on the plane + dist = plane->Distance( point ); + dist /= -d; + + testVert = point + dist * normal; + + // if this would be beyond our requested trace distance, + // don't even check it + if ( dist > maxDist ) { + return DIST_NO_INTERSECTION; + } + + if ( dist < minDist ) { + return DIST_NO_INTERSECTION; + } + + // if normal is inside all edge planes, this face is hit + VectorSubtract( *v[0], point, dir[0] ); + VectorSubtract( *v[1], point, dir[1] ); + edge = dir[0].Cross( dir[1] ); + d = DotProduct( normal, edge ); + if ( d > 0.0f ) { + return DIST_NO_INTERSECTION; + } + VectorSubtract( *v[2], point, dir[2] ); + edge = dir[1].Cross( dir[2] ); + d = DotProduct( normal, edge ); + if ( d > 0.0f ) { + return DIST_NO_INTERSECTION; + } + edge = dir[2].Cross( dir[0] ); + d = DotProduct( normal, edge ); + if ( d > 0.0f ) { + return DIST_NO_INTERSECTION; + } + + // calculate barycentric coordinates of the impact point + // on the high poly triangle + bary[0] = idWinding::TriangleArea( testVert, *v[1], *v[2] ); + bary[1] = idWinding::TriangleArea( *v[0], testVert, *v[2] ); + bary[2] = idWinding::TriangleArea( *v[0], *v[1], testVert ); + + baseArea = idWinding::TriangleArea( *v[0], *v[1], *v[2] ); + bary[0] /= baseArea; + bary[1] /= baseArea; + bary[2] /= baseArea; + + if ( bary[0] + bary[1] + bary[2] > 1.1 ) { + bary[0] = bary[0]; + return DIST_NO_INTERSECTION; + } + + // triangularly interpolate the normals to the sample point + sampledNormal = vec3_origin; + for ( j = 0 ; j < 3 ; j++ ) { + sampledNormal += bary[j] * highMesh->verts[ highMesh->indexes[ faceNum * 3 + j ] ].normal; + } + sampledNormal.Normalize(); + + sampledColor[0] = sampledColor[1] = sampledColor[2] = sampledColor[3] = 0; + for ( int i = 0 ; i < 4 ; i++ ) { + float color = 0.0f; + for ( j = 0 ; j < 3 ; j++ ) { + color += bary[j] * highMesh->verts[ highMesh->indexes[ faceNum * 3 + j ] ].color[i]; + } + sampledColor[i] = color; + } + return dist; +} + + +/* +================ +SampleHighMesh + +Find the best surface normal in the high poly mesh +for a ray coming from the surface of the low poly mesh + +Returns false if the trace doesn't hit anything +================ +*/ +static bool SampleHighMesh( const renderBump_t *rb, + const idVec3 &point, const idVec3 &direction, idVec3 &sampledNormal, + byte sampledColor[4] ) { + idVec3 p; + binLink_t *bl; + int linkNum; + int faceNum; + float dist, bestDist; + int block[3]; + float maxDist; + int c_hits; + int i; + idVec3 normal; + + // we allow non-normalized directions on input + normal = direction; + normal.Normalize(); + + // increment our uniqueness counter (FIXME: make thread safe?) + rayNumber++; + + // the max distance will be the traceFrac times the longest axis of the high poly model + bestDist = -rb->traceDist; + maxDist = rb->traceDist; + + sampledNormal = vec3_origin; + + c_hits = 0; + + // this is a pretty damn lazy way to walk through a 3D grid, and has a (very slight) + // chance of missing a triangle in a corner crossing case +#define RAY_STEPS 100 + for ( i = 0 ; i < RAY_STEPS ; i++ ) { + p = point - rb->hash->bounds[0] + normal * ( -1.0 + 2.0 * i / RAY_STEPS ) * rb->traceDist; + + block[0] = floor( p[0] / rb->hash->binSize[0] ); + block[1] = floor( p[1] / rb->hash->binSize[1] ); + block[2] = floor( p[2] / rb->hash->binSize[2] ); + + if ( block[0] < 0 || block[0] >= HASH_AXIS_BINS ) { + continue; + } + if ( block[1] < 0 || block[1] >= HASH_AXIS_BINS ) { + continue; + } + if ( block[2] < 0 || block[2] >= HASH_AXIS_BINS ) { + continue; + } + + // FIXME: casting away const + bl = (binLink_t *)&rb->hash->binLinks[block[0]][block[1]][block[2]]; + if ( bl->rayNumber == rayNumber ) { + continue; // already tested this block + } + bl->rayNumber = rayNumber; + linkNum = bl->triLink; + triLink_t *link; + for ( ; linkNum != -1 ; linkNum = link->nextLink ) { + link = &rb->hash->linkBlocks[ linkNum / MAX_LINKS_PER_BLOCK ][ linkNum % MAX_LINKS_PER_BLOCK ]; + + faceNum = link->faceNum; + dist = TraceToMeshFace( rb->mesh, faceNum, + bestDist, maxDist, point, normal, sampledNormal, sampledColor ); + if ( dist == DIST_NO_INTERSECTION ) { + continue; + } + + c_hits++; + // continue looking for a better match + bestDist = dist; + } + } + + return (bool)( bestDist > -rb->traceDist ); +} + +/* +============= +TriTextureArea + +This may be negatove +============= +*/ +static float TriTextureArea( const float a[2], const float b[2], const float c[2] ) { + idVec3 d1, d2; + idVec3 cross; + float area; + + d1[0] = b[0] - a[0]; + d1[1] = b[1] - a[1]; + d1[2] = 0; + + d2[0] = c[0] - a[0]; + d2[1] = c[1] - a[1]; + d2[2] = 0; + + cross = d1.Cross( d2 ); + area = 0.5 * cross.Length(); + + if ( cross[2] < 0 ) { + return -area; + } else { + return area; + } +} + +/* +================ +RasterizeTriangle + +It is ok for the texcoords to wrap around, the rasterization +will deal with it properly. +================ +*/ +static void RasterizeTriangle( const srfTriangles_t *lowMesh, const idVec3 *lowMeshNormals, int lowFaceNum, + renderBump_t *rb ) { + int i, j, k; + float bounds[2][2]; + float ibounds[2][2]; + float verts[3][2]; + float testVert[2]; + float bary[3]; + byte *localDest, *globalDest, *colorDest; + float edge[3][3]; + idVec3 sampledNormal; + byte sampledColor[4]; + idVec3 point, normal, traceNormal, tangents[2]; + float baseArea, totalArea; + int r, g, b; + idVec3 localNormal; + + // this is a brain-dead rasterizer, but compared to the ray trace, + // nothing we do here is going to matter performance-wise + + // adjust for resolution and texel centers + verts[0][0] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+0] ].st[0] * rb->width - 0.5; + verts[1][0] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+1] ].st[0] * rb->width - 0.5; + verts[2][0] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+2] ].st[0] * rb->width - 0.5; + verts[0][1] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+0] ].st[1] * rb->height - 0.5; + verts[1][1] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+1] ].st[1] * rb->height - 0.5; + verts[2][1] = lowMesh->verts[ lowMesh->indexes[lowFaceNum*3+2] ].st[1] * rb->height - 0.5; + + // find the texcoord bounding box + bounds[0][0] = 99999; + bounds[0][1] = 99999; + bounds[1][0] = -99999; + bounds[1][1] = -99999; + for ( i = 0 ; i < 2 ; i++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + if ( verts[j][i] < bounds[0][i] ) { + bounds[0][i] = verts[j][i]; + } + if ( verts[j][i] > bounds[1][i] ) { + bounds[1][i] = verts[j][i]; + } + } + } + + // we intentionally rasterize somewhat outside the triangles, so + // the bilerp support texels (which may be anti-aliased down) + // are not just duplications of what is on the interior + const float edgeOverlap = 4.0; + + ibounds[0][0] = floor( bounds[0][0] - edgeOverlap ); + ibounds[1][0] = ceil( bounds[1][0] + edgeOverlap ); + ibounds[0][1] = floor( bounds[0][1] - edgeOverlap ); + ibounds[1][1] = ceil( bounds[1][1] + edgeOverlap ); + + // calculate edge vectors + for ( i = 0 ; i < 3 ; i++ ) { + float *v1, *v2; + + v1 = verts[i]; + v2 = verts[(i+1)%3]; + + edge[i][0] = v2[1] - v1[1]; + edge[i][1] = v1[0] - v2[0]; + float len = sqrt( edge[i][0] * edge[i][0] + edge[i][1] * edge[i][1] ); + edge[i][0] /= len; + edge[i][1] /= len; + edge[i][2] = -( v1[0] * edge[i][0] + v1[1] * edge[i][1] ); + } + + // itterate over the bounding box, testing against edge vectors + for ( i = ibounds[0][1] ; i < ibounds[1][1] ; i++ ) { + for ( j = ibounds[0][0] ; j < ibounds[1][0] ; j++ ) { + float dists[3]; + + k = ( ( i & (rb->height-1) ) * rb->width + ( j & (rb->width-1) ) ) * 4; + colorDest = &rb->colorPic[k]; + localDest = &rb->localPic[k]; + globalDest = &rb->globalPic[k]; + +#define SKIP_MIRRORS + + float *edgeDistance = &rb->edgeDistances[k/4]; +#ifdef SKIP_MIRRORS + // if this texel has already been filled by a true interior pixel, don't overwrite it + if ( *edgeDistance == 0 ) { + continue; + } +#endif + + // check against the three edges to see if the pixel is inside the triangle + for ( k = 0 ; k < 3 ; k++ ) { + float v; + + v = i * edge[k][1] + j * edge[k][0] + edge[k][2]; + dists[k] = v; + } + + // the edge polarities might be either way + if ( ! ( ( dists[0] >= -edgeOverlap && dists[1] >= -edgeOverlap && dists[2] >= -edgeOverlap ) + || ( dists[0] <= edgeOverlap && dists[1] <= edgeOverlap && dists[2] <= edgeOverlap ) ) ) { + continue; + } + + bool edgeTexel; + + if ( ( dists[0] >= 0 && dists[1] >= 0 && dists[2] >= 0 ) + || ( dists[0] <= 0 && dists[1] <= 0 && dists[2] <= 0 ) ) { + edgeTexel = false; + } else { + edgeTexel = true; +#ifdef SKIP_MIRRORS + // if this texel has already been filled by another edge pixel, don't overwrite it + if ( *edgeDistance == 1 ) { + continue; + } +#endif + } + + // calculate the barycentric coordinates in the triangle for this sample + testVert[0] = j; + testVert[1] = i; + + baseArea = TriTextureArea( verts[0], verts[1], verts[2] ); + bary[0] = TriTextureArea( testVert, verts[1], verts[2] ) / baseArea; + bary[1] = TriTextureArea( verts[0], testVert, verts[2] ) / baseArea; + bary[2] = TriTextureArea( verts[0], verts[1], testVert ) / baseArea; + + totalArea = bary[0] + bary[1] + bary[2]; + if ( totalArea < 0.99 || totalArea > 1.01 ) { + continue; // should never happen + } + + // calculate the interpolated xyz, normal, and tangents of this sample + point = vec3_origin; + traceNormal = vec3_origin; + normal = vec3_origin; + tangents[0] = vec3_origin; + tangents[1] = vec3_origin; + for ( k = 0 ; k < 3 ; k++ ) { + int index; + + index = lowMesh->indexes[lowFaceNum*3+k]; + point += bary[k] * lowMesh->verts[ index ].xyz; + + // traceNormal will differ from normal if the surface uses unsmoothedTangents + traceNormal += bary[k] * lowMeshNormals[ index ]; + + normal += bary[k] * lowMesh->verts[ index ].normal; + tangents[0] += bary[k] * lowMesh->verts[ index ].tangents[0]; + tangents[1] += bary[k] * lowMesh->verts[ index ].tangents[1]; + } + +#if 0 + // this doesn't seem to make much difference + // an argument can be made that these should not be normalized, because the interpolation + // of the light position at rasterization time will be linear, not spherical + normal.Normalize(); + tangents[0].Normalize(); + tangents[1].Normalize(); +#endif + + // find the best triangle in the high poly model for this + // sampledNormal will normalized + if ( !SampleHighMesh( rb, point, traceNormal, sampledNormal, sampledColor ) ) { +#if 0 + // put bright red where all traces missed for debugging. + // for production use, it is better to leave it blank so + // the outlining fills it in + globalDest[0] = 255; + globalDest[1] = 0; + globalDest[2] = 0; + globalDest[3] = 255; + + localDest[0] = 255; + localDest[1] = 0; + localDest[2] = 0; + localDest[3] = 255; +#endif + continue; + } + + + // mark whether this is an interior or edge texel + *edgeDistance = ( edgeTexel ? 1.0 : 0 ); + + // fill the object space normal map spot + r = 128 + 127 * sampledNormal[0]; + g = 128 + 127 * sampledNormal[1]; + b = 128 + 127 * sampledNormal[2]; + + globalDest[0] = r; + globalDest[1] = g; + globalDest[2] = b; + globalDest[3] = 255; + + // transform to local tangent space + idMat3 mat; + mat[0] = tangents[0]; + mat[1] = tangents[1]; + mat[2] = normal; + mat.InverseSelf(); + localNormal = mat * sampledNormal; + + localNormal.Normalize(); + + + r = 128 + 127 * localNormal[0]; + g = 128 + 127 * localNormal[1]; + b = 128 + 127 * localNormal[2]; + + localDest[0] = r; + localDest[1] = g; + localDest[2] = b; + localDest[3] = 255; + + colorDest[0] = sampledColor[0]; + colorDest[1] = sampledColor[1]; + colorDest[2] = sampledColor[2]; + colorDest[3] = sampledColor[3]; + } + } +} + +/* +================ +CombineModelSurfaces + +Frees the model and returns a new model with all triangles combined +into one surface +================ +*/ +static idRenderModel *CombineModelSurfaces( idRenderModel *model ) { + int totalVerts; + int totalIndexes; + int numIndexes; + int numVerts; + int i, j; + + totalVerts = 0; + totalIndexes = 0; + + for ( i = 0 ; i < model->NumSurfaces() ; i++ ) { + const modelSurface_t *surf = model->Surface(i); + + totalVerts += surf->geometry->numVerts; + totalIndexes += surf->geometry->numIndexes; + } + + srfTriangles_t *newTri = R_AllocStaticTriSurf(); + R_AllocStaticTriSurfVerts( newTri, totalVerts ); + R_AllocStaticTriSurfIndexes( newTri, totalIndexes ); + + newTri->numVerts = totalVerts; + newTri->numIndexes = totalIndexes; + + newTri->bounds.Clear(); + + idDrawVert *verts = newTri->verts; + glIndex_t *indexes = newTri->indexes; + numIndexes = 0; + numVerts = 0; + for ( i = 0 ; i < model->NumSurfaces() ; i++ ) { + const modelSurface_t *surf = model->Surface(i); + const srfTriangles_t *tri = surf->geometry; + + memcpy( verts + numVerts, tri->verts, tri->numVerts * sizeof( tri->verts[0] ) ); + for ( j = 0 ; j < tri->numIndexes ; j++ ) { + indexes[numIndexes+j] = numVerts + tri->indexes[j]; + } + newTri->bounds.AddBounds( tri->bounds ); + numIndexes += tri->numIndexes; + numVerts += tri->numVerts; + } + + modelSurface_t surf; + + surf.id = 0; + surf.geometry = newTri; + surf.shader = tr.defaultMaterial; + + idRenderModel *newModel = renderModelManager->AllocModel(); + newModel->AddSurface( surf ); + + renderModelManager->FreeModel( model ); + + return newModel; +} + +/* +============== +RenderBumpTriangles + +============== +*/ +static void RenderBumpTriangles( srfTriangles_t *lowMesh, renderBump_t *rb ) { + int i, j; + + RB_SetGL2D(); + + qglDisable( GL_CULL_FACE ); + + qglColor3f( 1, 1, 1 ); + + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + qglOrtho( 0, 1, 1, 0, -1, 1 ); + qglDisable( GL_BLEND ); + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + qglDisable( GL_DEPTH_TEST ); + + qglClearColor(1,0,0,1); + qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + qglColor3f( 1, 1, 1 ); + + // create smoothed normals for the surface, which might be + // different than the normals at the vertexes if the + // surface uses unsmoothedNormals, which only takes the + // normal from a single triangle. We need properly smoothed + // normals to make sure that the traces always go off normal + // to the true surface. + idVec3 *lowMeshNormals = (idVec3 *)Mem_ClearedAlloc( lowMesh->numVerts * sizeof( *lowMeshNormals ) ); + R_DeriveFacePlanes( lowMesh ); + R_CreateSilIndexes( lowMesh ); // recreate, merging the mirrored verts back together + const idPlane *planes = lowMesh->facePlanes; + for ( i = 0 ; i < lowMesh->numIndexes ; i += 3, planes++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + int index; + + index = lowMesh->silIndexes[i+j]; + lowMeshNormals[index] += (*planes).Normal(); + } + } + // normalize and replicate from silIndexes to all indexes + for ( i = 0 ; i < lowMesh->numIndexes ; i++ ) { + lowMeshNormals[lowMesh->indexes[i]] = lowMeshNormals[lowMesh->silIndexes[i]]; + lowMeshNormals[lowMesh->indexes[i]].Normalize(); + } + + + // rasterize each low poly face + for ( j = 0 ; j < lowMesh->numIndexes ; j+=3 ) { + // pump the event loop so the window can be dragged around + Sys_GenerateEvents(); + + RasterizeTriangle( lowMesh, lowMeshNormals, j/3, rb ); + + qglClearColor(1,0,0,1); + qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + qglRasterPos2f( 0, 1 ); + qglPixelZoom( glConfig.vidWidth / (float)rb->width, glConfig.vidHeight / (float)rb->height ); + qglDrawPixels( rb->width, rb->height, GL_RGBA, GL_UNSIGNED_BYTE, rb->localPic ); + qglPixelZoom( 1, 1 ); + qglFlush(); + GLimp_SwapBuffers(); + } + + Mem_Free( lowMeshNormals ); +} + + +/* +============== +WriteRenderBump + +============== +*/ +static void WriteRenderBump( renderBump_t *rb, int outLinePixels ) { + int width, height; + int i; + idStr filename; + + renderModelManager->FreeModel( rb->highModel ); + + FreeTriHash( rb->hash ); + + width = rb->width; + height = rb->height; + +#if 0 + // save the non-outlined version + filename = source; + filename.setFileExtension(); + filename.append( "_nooutline.tga" ); + common->Printf( "writing %s\n", filename.c_str() ); + WriteTGA( filename, globalPic, width, height ); +#endif + + // outline the image several times to help bilinear filtering across disconnected + // edges, and mip-mapping + for ( i = 0 ; i < outLinePixels ; i++ ) { + OutlineNormalMap( rb->localPic, width, height, 128, 128, 128 ); + OutlineNormalMap( rb->globalPic, width, height, 128, 128, 128 ); + OutlineColorMap( rb->colorPic, width, height, 128, 128, 128 ); + } + + // filter down if we are anti-aliasing + for ( i = 0 ; i < rb->antiAlias ; i++ ) { + byte *old; + + old = rb->localPic; + rb->localPic = R_MipMap( rb->localPic, width, height, false ); + Mem_Free( old ); + + old = rb->globalPic; + rb->globalPic = R_MipMap( rb->globalPic, width, height, false ); + Mem_Free( old ); + + old = rb->colorPic; + rb->colorPic = R_MipMap( rb->colorPic, width, height, false ); + Mem_Free( old ); + + width >>= 1; + height >>= 1; + } + + // write out the local map + filename = rb->outputName; + filename.SetFileExtension( ".tga" ); + common->Printf( "writing %s (%i,%i)\n", filename.c_str(), width, height ); + R_WriteTGA( filename, rb->localPic, width, height ); + + if ( rb->saveGlobalMap ) { + filename = rb->outputName; + filename.StripFileExtension(); + filename.Append( "_global.tga" ); + common->Printf( "writing %s (%i,%i)\n", filename.c_str(), width, height ); + R_WriteTGA( filename, rb->globalPic, width, height ); + } + + if ( rb->saveColorMap ) { + filename = rb->outputName; + filename.StripFileExtension(); + filename.Append( "_color.tga" ); + common->Printf( "writing %s (%i,%i)\n", filename.c_str(), width, height ); + R_WriteTGA( filename, rb->colorPic, width, height ); + } + + Mem_Free( rb->localPic ); + Mem_Free( rb->globalPic ); + Mem_Free( rb->colorPic ); + Mem_Free( rb->edgeDistances ); +} + +/* +=============== +InitRenderBump +=============== +*/ +static void InitRenderBump( renderBump_t *rb ) { + srfTriangles_t *mesh; + idBounds bounds; + int i, c; + + // load the ase file + common->Printf( "loading %s...\n", rb->highName ); + + rb->highModel = renderModelManager->AllocModel(); + rb->highModel->PartialInitFromFile( rb->highName ); + if ( !rb->highModel ) { + common->Error( "failed to load %s", rb->highName ); + } + + // combine the high poly model into a single polyset + if ( rb->highModel->NumSurfaces() != 1 ) { + rb->highModel = CombineModelSurfaces( rb->highModel ); + } + + const modelSurface_t *surf = rb->highModel->Surface( 0 ); + mesh = surf->geometry; + + rb->mesh = mesh; + + R_DeriveFacePlanes( mesh ); + + // create a face hash table to accelerate the tracing + rb->hash = CreateTriHash( mesh ); + + // bound the entire file + R_BoundTriSurf( mesh ); + bounds = mesh->bounds; + + // the traceDist will be the traceFrac times the larges bounds axis + rb->traceDist = 0; + for ( i = 0 ; i < 3 ; i++ ) { + float d; + + d = rb->traceFrac * ( bounds[1][i] - bounds[0][i] ); + if ( d > rb->traceDist ) { + rb->traceDist = d; + } + } + common->Printf( "trace fraction %4.2f = %6.2f model units\n", rb->traceFrac, rb->traceDist ); + + c = rb->width * rb->height * 4; + + // local normal map + rb->localPic = (byte *)Mem_Alloc( c ); + + // global (object space, not surface space) normal map + rb->globalPic = (byte *)Mem_Alloc( c ); + + // color pic for artist reference + rb->colorPic = (byte *)Mem_Alloc( c ); + + // edgeDistance for marking outside-the-triangle traces + rb->edgeDistances = (float *)Mem_Alloc( c ); + + for ( i = 0 ; i < c ; i+=4 ) { + rb->localPic[i+0] = 128; + rb->localPic[i+1] = 128; + rb->localPic[i+2] = 128; + rb->localPic[i+3] = 0; // the artists use this for masking traced pixels sometimes + + rb->globalPic[i+0] = 128; + rb->globalPic[i+1] = 128; + rb->globalPic[i+2] = 128; + rb->globalPic[i+3] = 0; + + rb->colorPic[i+0] = 128; + rb->colorPic[i+1] = 128; + rb->colorPic[i+2] = 128; + rb->colorPic[i+3] = 0; + + rb->edgeDistances[i/4] = -1; // not traced yet + } + +} + +/* +============== +RenderBump_f + +============== +*/ +void RenderBump_f( const idCmdArgs &args ) { + idRenderModel *lowPoly; + idStr source; + int i, j; + const char *cmdLine; + int numRenderBumps; + renderBump_t *renderBumps, *rb; + renderBump_t opt; + int startTime, endTime; + + // update the screen as we print + common->SetRefreshOnPrint( true ); + + // there should be a single parameter, the filename for a game loadable low-poly model + if ( args.Argc() != 2 ) { + common->Error( "Usage: renderbump " ); + } + + common->Printf( "----- Renderbump %s -----\n", args.Argv( 1 ) ); + + startTime = Sys_Milliseconds(); + + // get the lowPoly model + source = args.Argv( 1 ); + lowPoly = renderModelManager->CheckModel( source ); + if ( !lowPoly ) { + common->Error( "Can't load model %s", source.c_str() ); + } + + renderBumps = (renderBump_t *)R_StaticAlloc( lowPoly->NumSurfaces() * sizeof( *renderBumps ) ); + numRenderBumps = 0; + for ( i = 0 ; i < lowPoly->NumSurfaces() ; i++ ) { + const modelSurface_t *ms = lowPoly->Surface( i ); + + // default options + memset( &opt, 0, sizeof( opt ) ); + opt.width = 512; + opt.height = 512; + opt.antiAlias = 1; + opt.outline = 8; + opt.traceFrac = 0.05f; + + // parse the renderbump parameters for this surface + cmdLine = ms->shader->GetRenderBump(); + + common->Printf( "surface %i, shader %s\nrenderBump = %s ", i, + ms->shader->GetName(), cmdLine ); + + if ( !ms->geometry ) { + common->Printf( "(no geometry)\n" ); + continue; + } + + idCmdArgs localArgs; + localArgs.TokenizeString( cmdLine, false ); + + if ( localArgs.Argc() < 2 ) { + common->Printf( "(no action)\n" ); + continue; + } + + common->Printf( "(rendering)\n" ); + + for ( j = 0 ; j < localArgs.Argc() - 2; j++ ) { + const char *s; + + s = localArgs.Argv( j ); + if ( s[0] == '-' ) { + j++; + s = localArgs.Argv( j ); + if ( s[0] == '\0' ) { + continue; + } + } + + if ( !idStr::Icmp( s, "size" ) ) { + if ( j + 2 >= localArgs.Argc() ) { + j = localArgs.Argc(); + break; + } + opt.width = atoi( localArgs.Argv( j + 1 ) ); + opt.height = atoi( localArgs.Argv( j + 2 ) ); + j += 2; + } else if ( !idStr::Icmp( s, "trace" ) ) { + opt.traceFrac = atof( localArgs.Argv( j + 1 ) ); + j += 1; + } else if ( !idStr::Icmp( s, "globalMap" ) ) { + opt.saveGlobalMap = true; + } else if ( !idStr::Icmp( s, "colorMap" ) ) { + opt.saveColorMap = true; + } else if ( !idStr::Icmp( s, "outline" ) ) { + opt.outline = atoi( localArgs.Argv( j + 1 ) ); + j += 1; + } else if ( !idStr::Icmp( s, "aa" ) ) { + opt.antiAlias = atoi( localArgs.Argv( j + 1 ) ); + j += 1; + } else { + common->Printf( "WARNING: Unknown option \"%s\"\n", s ); + break; + } + } + + if ( j != ( localArgs.Argc() - 2 ) ) { + common->Error( "usage: renderBump [-size width height] [-aa <1-2>] [globalMap] [colorMap] [-trace <0.01 - 1.0>] normalMapImageFile highPolyAseFile" ); + } + idStr::Copynz( opt.outputName, localArgs.Argv( j ), sizeof( opt.outputName ) ); + idStr::Copynz( opt.highName, localArgs.Argv( j + 1 ), sizeof( opt.highName ) ); + + // adjust size for anti-aliasing + opt.width <<= opt.antiAlias; + opt.height <<= opt.antiAlias; + + // see if we already have a renderbump going for another surface that this should use + for ( j = 0 ; j < numRenderBumps ; j++ ) { + rb = &renderBumps[j]; + + if ( idStr::Icmp( rb->outputName, opt.outputName ) ) { + continue; + } + // all the other parameters must match, or it is an error + if ( idStr::Icmp( rb->highName, opt.highName) || rb->width != opt.width || + rb->height != opt.height || rb->antiAlias != opt.antiAlias || + rb->traceFrac != opt.traceFrac ) { + common->Error( "mismatched renderbump parameters on image %s", rb->outputName ); + continue; + } + + // saveGlobalMap will be a sticky option + rb->saveGlobalMap = rb->saveGlobalMap | opt.saveGlobalMap; + break; + } + + // create a new renderbump if needed + if ( j == numRenderBumps ) { + numRenderBumps++; + rb = &renderBumps[j]; + *rb = opt; + + InitRenderBump( rb ); + } + + // render the triangles for this surface + RenderBumpTriangles( ms->geometry, rb ); + } + + // + // anti-alias and write out all renderbumps that we have completed + // + for ( i = 0 ; i < numRenderBumps ; i++ ) { + WriteRenderBump( &renderBumps[i], opt.outline << opt.antiAlias ); + } + + R_StaticFree( renderBumps ); + + endTime = Sys_Milliseconds(); + common->Printf( "%5.2f seconds for renderBump\n", ( endTime - startTime ) / 1000.0 ); + common->Printf( "---------- RenderBump Completed ----------\n" ); + + // stop updating the screen as we print + common->SetRefreshOnPrint( false ); +} + + + +/* +================================================================================== + +FLAT + +The flat case is trivial, and accomplished with hardware rendering + +================================================================================== +*/ + + +/* +============== +RenderBumpFlat_f + +============== +*/ +void RenderBumpFlat_f( const idCmdArgs &args ) { + int width, height; + idStr source; + int i; + idBounds bounds; + srfTriangles_t *mesh; + float boundsScale; + + // update the screen as we print + common->SetRefreshOnPrint( true ); + + width = height = 256; + boundsScale = 0; + + // check options + for ( i = 1 ; i < args.Argc() - 1; i++ ) { + const char *s; + + s = args.Argv( i ); + if ( s[0] == '-' ) { + i++; + s = args.Argv( i ); + } + + if ( !idStr::Icmp( s, "size" ) ) { + if ( i + 2 >= args.Argc() ) { + i = args.Argc(); + break; + } + width = atoi( args.Argv( i + 1 ) ); + height = atoi( args.Argv( i + 2 ) ); + i += 2; + } else { + common->Printf( "WARNING: Unknown option \"%s\"\n", s ); + break; + } + } + + if ( i != ( args.Argc() - 1 ) ) { + common->Error( "usage: renderBumpFlat [-size width height] asefile" ); + } + + common->Printf( "Final image size: %i, %i\n", width, height ); + + // load the source in "fastload" mode, because we don't + // need tangent and shadow information + source = args.Argv( i ); + + idRenderModel *highPolyModel = renderModelManager->AllocModel(); + + highPolyModel->PartialInitFromFile( source ); + + if ( highPolyModel->IsDefaultModel() ) { + common->Error( "failed to load %s", source.c_str() ); + } + + // combine the high poly model into a single polyset + if ( highPolyModel->NumSurfaces() != 1 ) { + highPolyModel = CombineModelSurfaces( highPolyModel ); + } + + // create normals if not present in file + const modelSurface_t *surf = highPolyModel->Surface( 0 ); + mesh = surf->geometry; + + // bound the entire file + R_BoundTriSurf( mesh ); + bounds = mesh->bounds; + + SaveWindow(); + ResizeWindow( width, height ); + + // for small images, the viewport may be less than the minimum window + qglViewport( 0, 0, width, height ); + + qglEnable( GL_CULL_FACE ); + qglCullFace( GL_FRONT ); + qglDisable( GL_STENCIL_TEST ); + qglDisable( GL_SCISSOR_TEST ); + qglDisable( GL_ALPHA_TEST ); + qglDisable( GL_BLEND ); + qglEnable( GL_DEPTH_TEST ); + qglDisable( GL_TEXTURE_2D ); + qglDepthMask( GL_TRUE ); + qglDepthFunc( GL_LEQUAL ); + + qglColor3f( 1, 1, 1 ); + + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + qglOrtho( bounds[0][0], bounds[1][0], bounds[0][2], + bounds[1][2], -( bounds[0][1] - 1 ), -( bounds[1][1] + 1 ) ); + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + // flat maps are automatically anti-aliased + + idStr filename; + int j, k, c; + byte *buffer; + int *sumBuffer, *colorSumBuffer; + bool flat; + int sample; + + sumBuffer = (int *)Mem_Alloc( width * height * 4 * 4 ); + memset( sumBuffer, 0, width * height * 4 * 4 ); + buffer = (byte *)Mem_Alloc( width * height * 4 ); + + colorSumBuffer = (int *)Mem_Alloc( width * height * 4 * 4 ); + memset( sumBuffer, 0, width * height * 4 * 4 ); + + flat = false; +//flat = true; + + for ( sample = 0 ; sample < 16 ; sample++ ) { + float xOff, yOff; + + xOff = ( ( sample & 3 ) / 4.0 ) * ( bounds[1][0] - bounds[0][0] ) / width; + yOff = ( ( sample / 4 ) / 4.0 ) * ( bounds[1][2] - bounds[0][2] ) / height; + + for ( int colorPass = 0 ; colorPass < 2 ; colorPass++ ) { + qglClearColor(0.5,0.5,0.5,0); + qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + qglBegin( GL_TRIANGLES ); + for ( i = 0 ; i < highPolyModel->NumSurfaces() ; i++ ) { + const modelSurface_t *surf = highPolyModel->Surface( i ); + + mesh = surf->geometry; + + if ( colorPass ) { + // just render the surface color for artist visualization + for ( j = 0 ; j < mesh->numIndexes ; j+=3 ) { + for ( k = 0 ; k < 3 ; k++ ) { + int v; + float *a; + + v = mesh->indexes[j+k]; + qglColor3ubv( mesh->verts[v].color ); + a = mesh->verts[v].xyz.ToFloatPtr(); + qglVertex3f( a[0] + xOff, a[2] + yOff, a[1] ); + } + } + } else { + // render as normal map + // we can either flat shade from the plane, + // or smooth shade from the vertex normals + for ( j = 0 ; j < mesh->numIndexes ; j+=3 ) { + if ( flat ) { + idPlane plane; + idVec3 *a, *b, *c; + int v1, v2, v3; + + v1 = mesh->indexes[j+0]; + v2 = mesh->indexes[j+1]; + v3 = mesh->indexes[j+2]; + + a = &mesh->verts[ v1 ].xyz; + b = &mesh->verts[ v2 ].xyz; + c = &mesh->verts[ v3 ].xyz; + + plane.FromPoints( *a, *b, *c ); + + // NULLNORMAL is used by the artists to force an area to reflect no + // light at all + if ( surf->shader->GetSurfaceFlags() & SURF_NULLNORMAL ) { + qglColor3f( 0.5, 0.5, 0.5 ); + } else { + qglColor3f( 0.5 + 0.5*plane[0], 0.5 - 0.5*plane[2], 0.5 - 0.5*plane[1] ); + } + + qglVertex3f( (*a)[0] + xOff, (*a)[2] + yOff, (*a)[1] ); + qglVertex3f( (*b)[0] + xOff, (*b)[2] + yOff, (*b)[1] ); + qglVertex3f( (*c)[0] + xOff, (*c)[2] + yOff, (*c)[1] ); + } else { + for ( k = 0 ; k < 3 ; k++ ) { + int v; + float *n; + float *a; + + v = mesh->indexes[j+k]; + n = mesh->verts[v].normal.ToFloatPtr(); + + // NULLNORMAL is used by the artists to force an area to reflect no + // light at all + if ( surf->shader->GetSurfaceFlags() & SURF_NULLNORMAL ) { + qglColor3f( 0.5, 0.5, 0.5 ); + } else { + // we are going to flip the normal Z direction + qglColor3f( 0.5 + 0.5*n[0], 0.5 - 0.5*n[2], 0.5 - 0.5*n[1] ); + } + + a = mesh->verts[v].xyz.ToFloatPtr(); + qglVertex3f( a[0] + xOff, a[2] + yOff, a[1] ); + } + } + } + } + } + + qglEnd(); + qglFlush(); + GLimp_SwapBuffers(); + qglReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer ); + + if ( colorPass ) { + // add to the sum buffer + for ( i = 0 ; i < c ; i++ ) { + colorSumBuffer[i*4+0] += buffer[i*4+0]; + colorSumBuffer[i*4+1] += buffer[i*4+1]; + colorSumBuffer[i*4+2] += buffer[i*4+2]; + colorSumBuffer[i*4+3] += buffer[i*4+3]; + } + } else { + // normalize + c = width * height; + for ( i = 0 ; i < c ; i++ ) { + idVec3 v; + + v[0] = ( buffer[i*4+0] - 128 ) / 127.0; + v[1] = ( buffer[i*4+1] - 128 ) / 127.0; + v[2] = ( buffer[i*4+2] - 128 ) / 127.0; + + v.Normalize(); + + buffer[i*4+0] = 128 + 127 * v[0]; + buffer[i*4+1] = 128 + 127 * v[1]; + buffer[i*4+2] = 128 + 127 * v[2]; + } + + // outline into non-drawn areas + for ( i = 0 ; i < 8 ; i++ ) { + OutlineNormalMap( buffer, width, height, 128, 128, 128 ); + } + + // add to the sum buffer + for ( i = 0 ; i < c ; i++ ) { + sumBuffer[i*4+0] += buffer[i*4+0]; + sumBuffer[i*4+1] += buffer[i*4+1]; + sumBuffer[i*4+2] += buffer[i*4+2]; + sumBuffer[i*4+3] += buffer[i*4+3]; + } + } + } + } + + c = width * height; + + // save out the color map + for ( i = 0 ; i < c ; i++ ) { + buffer[i*4+0] = colorSumBuffer[i*4+0] / 16; + buffer[i*4+1] = colorSumBuffer[i*4+1] / 16; + buffer[i*4+2] = colorSumBuffer[i*4+2] / 16; + buffer[i*4+3] = colorSumBuffer[i*4+3] / 16; + } + filename = source; + filename.StripFileExtension(); + filename.Append( "_color.tga" ); + R_VerticalFlip( buffer, width, height ); + R_WriteTGA( filename, buffer, width, height ); + + // save out the local map + // scale the sum buffer back down to the sample buffer + // we allow this to denormalize + for ( i = 0 ; i < c ; i++ ) { + buffer[i*4+0] = sumBuffer[i*4+0] / 16; + buffer[i*4+1] = sumBuffer[i*4+1] / 16; + buffer[i*4+2] = sumBuffer[i*4+2] / 16; + buffer[i*4+3] = sumBuffer[i*4+3] / 16; + } + + filename = source; + filename.StripFileExtension(); + filename.Append( "_local.tga" ); + common->Printf( "writing %s (%i,%i)\n", filename.c_str(), width, height ); + R_VerticalFlip( buffer, width, height ); + R_WriteTGA( filename, buffer, width, height ); + + + // free the model + renderModelManager->FreeModel( highPolyModel ); + + // free our work buffer + Mem_Free( buffer ); + Mem_Free( sumBuffer ); + Mem_Free( colorSumBuffer ); + + RestoreWindow(); + + // stop updating the screen as we print + common->SetRefreshOnPrint( false ); + + common->Error( "Completed." ); +} diff --git a/tools/compilers/roqvq/NSBitmapImageRep.cpp b/tools/compilers/roqvq/NSBitmapImageRep.cpp new file mode 100644 index 000000000..fee161c89 --- /dev/null +++ b/tools/compilers/roqvq/NSBitmapImageRep.cpp @@ -0,0 +1,96 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "roq.h" + +void R_LoadImage( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 ); + +NSBitmapImageRep::NSBitmapImageRep( void ) { + bmap = NULL; + width = 0; + height = 0; + timestamp = 0; +} + +NSBitmapImageRep::NSBitmapImageRep( const char *filename ) { + + R_LoadImage( filename, &bmap, &width, &height, ×tamp, false ); + if (!width || !height) { + common->FatalError( "roqvq: unable to load image %s\n", filename ); + } +} + +NSBitmapImageRep::NSBitmapImageRep( int wide, int high ) { + bmap = (byte *)Mem_ClearedAlloc( wide * high * 4 ); + width = wide; + height = high; +} + +void R_StaticFree( void *data ); + +NSBitmapImageRep::~NSBitmapImageRep() { + R_StaticFree( bmap ); + bmap = NULL; +} + +int NSBitmapImageRep::samplesPerPixel( void ) { + return 4; +} + +int NSBitmapImageRep::pixelsWide( void ) { + return width; +} + +int NSBitmapImageRep::pixelsHigh( void ) { + return height; +} + +byte * NSBitmapImageRep::bitmapData( void ) { + return bmap; +} + +bool NSBitmapImageRep::hasAlpha( void ) { + return false; +} + +bool NSBitmapImageRep::isPlanar( void ) { + return false; +} + +NSBitmapImageRep &NSBitmapImageRep::operator=( const NSBitmapImageRep &a ) { + + // check for assignment to self + if ( this == &a ) { + return *this; + } + + if (bmap) { + Mem_Free(bmap); + } + bmap = (byte *)Mem_Alloc( a.width * a.height * 4 ); + memcpy( bmap, a.bmap, a.width * a.height * 4 ); + width = a.width; + height = a.height; + timestamp = a.timestamp; + + return *this; +} + diff --git a/tools/compilers/roqvq/codec.cpp b/tools/compilers/roqvq/codec.cpp new file mode 100644 index 000000000..188e9f42d --- /dev/null +++ b/tools/compilers/roqvq/codec.cpp @@ -0,0 +1,1687 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "codec.h" + +float glimit( const float val ) { + if (val<0) return 0; + if (val>255) return 255; + return val; +} + +codec::codec() { + int i; + + common->Printf("init: initing.....\n"); + codebooksize = 256; + codebook2 = (VQDATA **) Mem_ClearedAlloc(256*sizeof(VQDATA *)); + for(i=0; i < 256; i++) { + codebook2[i] = (VQDATA *) Mem_ClearedAlloc(16*sizeof(VQDATA)); + } + codebook4 = (VQDATA **) Mem_ClearedAlloc(256*sizeof(VQDATA *)); + for(i=0; i < 256; i++) { + codebook4[i] = (VQDATA *) Mem_ClearedAlloc(64*sizeof(VQDATA)); + } + previousImage[0] = 0; + previousImage[1] = 0; + image = 0; + whichFrame = 0; + qStatus = 0; + luti = 0; + overAmount = 0; + codebookmade = 0; + slop = 0; +} + +codec::~codec() +{ + common->Printf("codec: resetting\n"); + if (qStatus) Mem_Free( qStatus); + if (luti) Mem_Free(luti); + if (previousImage[0]) delete previousImage[0]; + if (previousImage[1]) delete previousImage[1]; + qStatus = 0; + initRGBtab = 0; + previousImage[0] = 0; + whichFrame = 0; + luti = 0; + return; +} + +/* Because Shellsort is a variation on Insertion Sort, it has the same + * inconsistency that I noted in the InsertionSort class. Notice where I + * subtract a move to compensate for calling a swap for visual purposes. + */ + +void codec::Sort( float *list, int *intIndex, int numElements ) +{ +#define STRIDE_FACTOR 3 // good value for stride factor is not well-understood + // 3 is a fairly good choice (Sedgewick) + int c,d, stride; + bool found; + + stride = 1; + while (stride <= numElements) + stride = stride*STRIDE_FACTOR +1; + + while (stride>(STRIDE_FACTOR-1)) { // loop to sort for each value of stride + stride = stride / STRIDE_FACTOR; + + for (c = stride; c < numElements; c++){ + found = false; + d = c-stride; + while ((d >= 0) && !found) { // move to left until correct place + if (list[d]CurrentFilename()); + sprintf( temptb, "%s.tb", theRoQ->CurrentFilename()); + + onf = 0; + len = (int)strlen(tempcb); + for(x=0;xPrintf("trying %s\n", cbFile); + fpcb = fileSystem->OpenFileRead( cbFile ); + if ( !fpcb ) { + doopen = true; + common->Printf("failed....\n"); + } else { + if ( dimension2 == 16 ) x = 3584; else x = 2560; + if ( fpcb->Read( lineout, x ) != x ) { + doopen = true; + common->Printf("failed....\n"); + } + fileSystem->CloseFile( fpcb ); + } + + if ( doopen ) { + common->Printf("segment: making %s\n", cbFile); + numc = numElements; + if (numElements > numc) numc = numElements; + onf = 0; + + for(x=0;x<256;x++) { + for(y=0;ysamplesPerPixel(); + cbook = (byte *)Mem_ClearedAlloc( 3 * image->pixelsWide() * image->pixelsHigh()); + float *snrBook = (float *)Mem_ClearedAlloc( image->pixelsWide() * image->pixelsHigh() ); + dst = cbook; + int numEntries = 0; + for (i=0; i= MIN_SNR*4) { + for(y=qStatus[i].yat;ybitmapData() + (yy*(bpp*image->pixelsWide())) + (xx*bpp); + memcpy( dst, src, 3); dst += 3; + } + } + } + } + } + } + common->Printf("segment: %d 4x4 cels to vq\n", numEntries ); + + VQ( numEntries, dimension4, cbook, snrBook, codebook4, true ); + + dst = cbook; + numEntries = 0; + + for( i=0; i<256; i++ ) { + for(y=0;y<4;y+=2) { + for(x=0;x<4;x+=2) { + snrBook[numEntries] = 1.0f; + numEntries++; + for(yy=y;yy<(y+2);yy++) { + for(xx=x;xx<(x+2);xx++) { + dst[0] = codebook4[i][yy*12+xx*3+0]; + dst[1] = codebook4[i][yy*12+xx*3+1]; + dst[2] = codebook4[i][yy*12+xx*3+2]; + dst += 3; + } + } + } + } + } + common->Printf("segment: %d 2x2 cels to vq\n", numEntries); + + VQ( numEntries, dimension2, cbook, snrBook, codebook2, false ); + + Mem_Free(cbook); + Mem_Free(snrBook); + + index = 0; + for( onf = 0; onf < 256; onf++ ) { + numc = 0; fcr = fcb = 0; + for( x = 0; x < 4; x++ ) { + fy = RMULT*(float)(codebook2[onf][numc+0]) + + GMULT*(float)(codebook2[onf][numc+1]) + + BMULT*(float)(codebook2[onf][numc+2]) + 0.5f; + if (fy<0) fy = 0; if (fy>255) fy = 255; + + fcr += RIEMULT*(float)(codebook2[onf][numc+0]); + fcr += GIEMULT*(float)(codebook2[onf][numc+1]); + fcr += BIEMULT*(float)(codebook2[onf][numc+2]); + + fcb += RQEMULT*(float)(codebook2[onf][numc+0]); + fcb += GQEMULT*(float)(codebook2[onf][numc+1]); + fcb += BQEMULT*(float)(codebook2[onf][numc+2]); + + lineout[index++] = (byte)fy; + numc += 3; + } + fcr = (fcr/4)+128.5f; if (fcr<0) fcr = 0; if (fcr>255) fcr = 255; + fcb = (fcb/4)+128.5f; if (fcb<0) fcb = 0; if (fcb>255) fcr = 255; + //common->Printf(" fcr == %f, fcb == %f\n", fcr, fcb ); + lineout[index++] = (byte)fcr; + lineout[index++] = (byte)fcb; + } + + for(onf=0;onf<256;onf++) { + for(y=0;y<4;y+=2) { + for(x=0;x<4;x+=2) { + numc = 0; + for(yy=y;yy<(y+2);yy++) { + temp = (yy*dimension2)+x*(dimension2/4); + find[numc++] = (byte)(codebook4[onf][temp+0] + 0.50f); + find[numc++] = (byte)(codebook4[onf][temp+1] + 0.50f); + find[numc++] = (byte)(codebook4[onf][temp+2] + 0.50f); + find[numc++] = (byte)(codebook4[onf][temp+3] + 0.50f); + find[numc++] = (byte)(codebook4[onf][temp+4] + 0.50f); + find[numc++] = (byte)(codebook4[onf][temp+5] + 0.50f); + } + lineout[index++] = BestCodeword( find, dimension2, codebook2 ); + } + } + } + + fpcb = fileSystem->OpenFileWrite( cbFile ); + common->Printf("made up %d entries\n", index); + fpcb->Write( lineout, index ); + fileSystem->CloseFile( fpcb ); + common->Printf("finished write\n"); + } + + for(y=0;y<256;y++) { + x = y*6; + y0 = (float)lineout[x++]; + y1 = (float)lineout[x++]; + y2 = (float)lineout[x++]; + y3 = (float)lineout[x++]; + cb = (float)lineout[x++]; cb -= 128; + cr = (float)lineout[x ]; cr -= 128; + x = 0; + codebook2[y][x++] = glimit( y0 + 1.40200f*cr ); + codebook2[y][x++] = glimit( y0 - 0.34414f*cb - 0.71414f*cr ); + codebook2[y][x++] = glimit( y0 + 1.77200f*cb ); + codebook2[y][x++] = glimit( y1 + 1.40200f*cr ); + codebook2[y][x++] = glimit( y1 - 0.34414f*cb - 0.71414f*cr ); + codebook2[y][x++] = glimit( y1 + 1.77200f*cb ); + codebook2[y][x++] = glimit( y2 + 1.40200f*cr ); + codebook2[y][x++] = glimit( y2 - 0.34414f*cb - 0.71414f*cr ); + codebook2[y][x++] = glimit( y2 + 1.77200f*cb ); + codebook2[y][x++] = glimit( y3 + 1.40200f*cr ); + codebook2[y][x++] = glimit( y3 - 0.34414f*cb - 0.71414f*cr ); + codebook2[y][x++] = glimit( y3 + 1.77200f*cb ); + } + + index = 6*256; + + for(onf=0;onf<256;onf++) { + for(y=0;y<4;y+=2) { + for(x=0;x<4;x+=2) { + best = lineout[index++]; + numc = 0; + for(yy=y;yy<(y+2);yy++) { + temp = (yy*dimension2)+x*(dimension2/4); + codebook4[onf][temp+0] = codebook2[best][numc++]; //r + codebook4[onf][temp+1] = codebook2[best][numc++]; //g + codebook4[onf][temp+2] = codebook2[best][numc++]; //b + codebook4[onf][temp+3] = codebook2[best][numc++]; //r a + codebook4[onf][temp+4] = codebook2[best][numc++]; //g r + codebook4[onf][temp+5] = codebook2[best][numc++]; //b g + } + } + } + } + + theRoQ->WriteCodeBook(lineout); + //PrepareCodeBook(); + + Mem_Free(lineout); +} + +int codec::BestCodeword( unsigned char *tempvector, int dimension, VQDATA **codebook ) +{ + VQDATA dist; + VQDATA bestDist = HUGE; + VQDATA tempvq[64]; + int bestIndex = -1; + + for( int i=0; i= bestDist) { + continue; + } + dist += (g0-g1)*(g0-g1); + if (dist >= bestDist) { + continue; + } + dist += (b0-b1)*(b0-b1); + if (dist >= bestDist) { + continue; + } + } + if ( dist < bestDist ) { + bestDist = dist; + bestIndex = i; + } + } + return bestIndex; +} + +void codec::SetPreviousImage( const char*filename, NSBitmapImageRep *timage ) +{ + if (previousImage[0]) { + delete previousImage[0]; + } + if (previousImage[1]) { + delete previousImage[1]; + } + common->Printf("setPreviousImage:%s\n", filename); + + previousImage[0] = new NSBitmapImageRep( ); + previousImage[1] = new NSBitmapImageRep( ); + whichFrame=1; + + *previousImage[0] = *timage; + *previousImage[1] = *timage; + + pixelsHigh = previousImage[0]->pixelsHigh(); + pixelsWide = previousImage[0]->pixelsWide(); + + common->Printf("setPreviousImage: %dx%d\n", pixelsWide, pixelsHigh ); +} + +void codec::MakePreviousImage( quadcel *pquad ) +{ +int i, dy, dx, pluck, size, ind, xx, yy, pWide; +int x, y; +byte *rgbmap, *idataA, *fccdictionary; +bool diff; + + for(i=0;i<256;i++) { used2[i] = used4[i] = false; } + + pWide = pixelsWide & 0xfff0; + if (!previousImage[0]) { + previousImage[0] = new NSBitmapImageRep( pWide, (pixelsHigh & 0xfff0) ); + previousImage[1] = new NSBitmapImageRep( pWide, (pixelsHigh & 0xfff0) ); + } + + rgbmap = previousImage[(whichFrame&1)]->bitmapData(); + + if ((whichFrame&1) == 1) { + fccdictionary = previousImage[0]->bitmapData(); + } else { + fccdictionary = previousImage[1]->bitmapData(); + } + + idataA = (byte *)Mem_Alloc( 16*16*4 ); + + for(i=0;i>1)*dimension2)+(dx>>1)*(dimension2/4); + if (rgbmap[pluck+0] != codebook4[ind][xx+0]) diff = true; + if (rgbmap[pluck+1] != codebook4[ind][xx+1]) diff = true; + if (rgbmap[pluck+2] != codebook4[ind][xx+2]) diff = true; + if (dimension4 == 64 && rgbmap[pluck+3] != codebook4[ind][xx+3]) diff = true; + + rgbmap[pluck+0] = (byte)codebook4[ind][xx+0]; + rgbmap[pluck+1] = (byte)codebook4[ind][xx+1]; + rgbmap[pluck+2] = (byte)codebook4[ind][xx+2]; + if (dimension4 == 64) + rgbmap[pluck+3] = (byte)codebook4[ind][xx+3]; + else + rgbmap[pluck+3] = 255; + pluck += 4; + } + } + if (diff == false && whichFrame) common->Printf("drawImage: SLD just changed the same thing\n"); + break; + case PAT: + ind = pquad[i].patten[0]; + used4[ind] = true; + for( dy=0; dyPrintf("drawImage: PAT just changed the same thing\n"); + break; + case CCC: + dx = 1; + for(yy=0;yy<4;yy+=2) { + for(xx=0;xx<4;xx+=2) { + ind = pquad[i].patten[dx++]; + used2[ind] = true; + dy = 0; + for(y=yy;y<(yy+2);y++) { + for(x=xx;x<(xx+2);x++) { + pluck = (((y+pquad[i].yat)*pWide)+(pquad[i].xat+x))*4; + if (rgbmap[pluck+0] != codebook2[ind][dy+0]) diff = true; + if (rgbmap[pluck+1] != codebook2[ind][dy+1]) diff = true; + if (rgbmap[pluck+2] != codebook2[ind][dy+2]) diff = true; + if (dimension4 == 64 && rgbmap[pluck+3] != codebook2[ind][dy+3]) diff = true; + + rgbmap[pluck+0] = (byte)codebook2[ind][dy+0]; + rgbmap[pluck+1] = (byte)codebook2[ind][dy+1]; + rgbmap[pluck+2] = (byte)codebook2[ind][dy+2]; + if (dimension4 == 64) { + rgbmap[pluck+3] = (byte)codebook2[ind][dy+3]; + dy += 4; + } else { + rgbmap[pluck+3] = 255; + dy += 3; + } + } + } + } + } + if (diff == false && whichFrame) { + /* + common->Printf("drawImage: CCC just changed the same thing\n"); + common->Printf("sparseEncode: something is wrong here\n"); + common->Printf("xat: %d\n", pquad[i].xat); + common->Printf("yat: %d\n", pquad[i].yat); + common->Printf("size %d\n", pquad[i].size); + common->Printf("type: %d\n", pquad[i].status); + common->Printf("motsnr: %0f\n", pquad[i].snr[FCC]); + common->Printf("cccsnr: %0f\n", pquad[i].snr[CCC]); + common->Printf("rmse: %0f\n", pquad[i].rsnr); + common->Printf("pat0: %0d\n", pquad[i].patten[1]); + common->Printf("pat1: %0d\n", pquad[i].patten[2]); + common->Printf("pat2: %0d\n", pquad[i].patten[3]); + common->Printf("pat3: %0d\n", pquad[i].patten[4]); + //exit(1); + */ + } + break; + case FCC: + dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128); + dy = pquad[i].yat - ((pquad[i].domain & 0xff) - 128); + if (image->pixelsWide()==(image->pixelsHigh()*4)) dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128)*2; + if (theRoQ->Scaleable()) { + dx = pquad[i].xat - ((pquad[i].domain >> 8 ) - 128)*2; + dy = pquad[i].yat - ((pquad[i].domain & 0xff) - 128)*2; + } +// if (pquad[i].yat == 0) common->Printf("dx = %d, dy = %d, xat = %d\n", dx, dy, pquad[i].xat); + + ind = (dy*pWide+dx)*4; + for( dy=0; dyPrintf("drawImage: FCC just changed the same thing\n"); + break; + case MOT: + break; + default: + common->Error( "bad code!!\n"); + break; + } + } + } + if (whichFrame == 0) { + memcpy( previousImage[1]->bitmapData(), previousImage[0]->bitmapData(), pWide*(pixelsHigh & 0xfff0)*4); + } + + x = 0; y = 0; + for(i=0;i<256;i++) { + if (used4[i]) x++; + if (used2[i]) y++; + } + + if (theRoQ->IsQuiet() == false) common->Printf("drawImage: used %d 4x4 and %d 2x2 VQ cels\n", x,y); + + Mem_Free( idataA ); +} + +void codec::InitImages( void ) +{ +int x,y, index0, index1, temp; +float ftemp; +byte *lutimage; + + numQuadCels = ((pixelsWide & 0xfff0)*(pixelsHigh & 0xfff0))/(MINSIZE*MINSIZE); + numQuadCels += numQuadCels/4 + numQuadCels/16; + + if (qStatus) Mem_Free(qStatus); + qStatus = (quadcel *)Mem_ClearedAlloc(numQuadCels*sizeof (quadcel)); + InitQStatus(); +// + if (previousImage[0]) { + pixelsWide = previousImage[0]->pixelsWide(); + pixelsHigh = previousImage[0]->pixelsHigh(); + temp = ((whichFrame+1)&1); + if (!luti) luti = (byte *)Mem_Alloc(pixelsWide*pixelsHigh); + lutimage = previousImage[temp]->bitmapData(); + if (theRoQ->IsQuiet() == false) { + common->Printf("initImage: remaking lut image using buffer %d\n", temp); + } + index0 = index1 = 0; + for(y=0;ysamplesPerPixel(); + index1++; + } + } + } +} + + +void codec::QuadX( int startX, int startY, int quadSize) +{ +int startSize; +int bigx, bigy, lowx, lowy; + + lowx = lowy = 0; + bigx = pixelsWide & 0xfff0; + bigy = pixelsHigh & 0xfff0; + + if ( (startX >= lowx) && (startX+quadSize) <= (bigx) && (startY+quadSize) <= (bigy) && (startY >= lowy) && quadSize <= MAXSIZE) { + qStatus[onQuad].size = quadSize; + qStatus[onQuad].xat = startX; + qStatus[onQuad].yat = startY; + qStatus[onQuad].rsnr = 999999; + onQuad++; + } + + if (quadSize != MINSIZE) { + startSize = quadSize>>1; + QuadX( startX , startY , startSize ); + QuadX( startX+startSize , startY , startSize ); + QuadX( startX , startY+startSize , startSize ); + QuadX( startX+startSize , startY+startSize , startSize ); + } +} + +void codec::InitQStatus( void ) +{ +int i,x,y; + + for (i=0; ipatten[0] = best = BestCodeword( tempImage, dimension4, codebook4 ); + + for(y=0;y<8;y++) { + for(x=0;x<8;x++) { + temp = y*32+x*4; + i = ((y/2)*4*(dimension2/4))+(x/2)*(dimension2/4); + tempImage[temp+0] = (byte)codebook4[best][i+0]; + tempImage[temp+1] = (byte)codebook4[best][i+1]; + tempImage[temp+2] = (byte)codebook4[best][i+2]; + if (dimension4 == 64) + tempImage[temp+3] = (byte)codebook4[best][i+3]; + else + tempImage[temp+3] = 255; + } + } + + pquad->snr[SLD] = Snr( cel, tempImage, 8 )+1.0; +} + +void codec::VqData4( byte *cel, quadcel *pquad ) +{ +byte tempImage[64]; +int i, best, bpp; + +// if (theRoQ->makingVideo] && previousImage[0]) return self; + if (dimension4 == 64) bpp = 4; else bpp = 3; + for(i=0;i<16;i++) { + tempImage[i*bpp+0] = cel[i*4+0]; + tempImage[i*bpp+1] = cel[i*4+1]; + tempImage[i*bpp+2] = cel[i*4+2]; + if (dimension4 == 64) tempImage[i*bpp+3] = cel[i*4+3]; + } + + pquad->patten[0] = best = BestCodeword( tempImage, dimension4, codebook4 ); + + for(i=0;i<16;i++) { + tempImage[i*4+0] = (byte)codebook4[best][i*bpp+0]; + tempImage[i*4+1] = (byte)codebook4[best][i*bpp+1]; + tempImage[i*4+2] = (byte)codebook4[best][i*bpp+2]; + if (dimension4 == 64) + tempImage[i*4+3] = (byte)codebook4[best][i*bpp+3]; + else + tempImage[i*4+3] = 255; + } + + pquad->snr[PAT] = Snr( cel, tempImage, 4 ); +} + +void codec::VqData2( byte *cel, quadcel *pquad ) +{ +byte tempImage[16], tempOut[64]; +int i, j, best,x,y,xx,yy,bpp; + + if (dimension4 == 64) bpp = 4; else bpp = 3; + j = 1; + for(yy=0;yy<4;yy+=2) { + for(xx=0;xx<4;xx+=2) { + i = 0; + for(y=yy;y<(yy+2);y++) { + for(x=xx;x<(xx+2);x++) { + tempImage[i++] = cel[y*16+x*4+0]; + tempImage[i++] = cel[y*16+x*4+1]; + tempImage[i++] = cel[y*16+x*4+2]; + if (dimension4 == 64) tempImage[i++] = cel[y*16+x*4+3]; + } + } + pquad->patten[j++] = best = BestCodeword( tempImage, dimension2, codebook2 ); + i = 0; + for(y=yy;y<(yy+2);y++) { + for(x=xx;x<(xx+2);x++) { + tempOut[y*16+x*4+0] = (byte)codebook2[best][i++]; + tempOut[y*16+x*4+1] = (byte)codebook2[best][i++]; + tempOut[y*16+x*4+2] = (byte)codebook2[best][i++]; + if (dimension4 == 64) + tempOut[y*16+x*4+3] = (byte)codebook2[best][i++]; + else + tempOut[y*16+x*4+3] = 255; + } + } + } + } + + pquad->snr[CCC] = Snr( cel, tempOut, 4 ); +} + +void codec::IRGBtab(void) +{ + initRGBtab++; +} + +float codec::Snr( byte *old, byte *bnew, int size ) { +int i, j; +float fsnr; +register int ind; + + ind = 0; + + for(i=0; idomain = 0x8080; + pquad->snr[FCC] = 9999; + return; + } + + ony = realy - (realy & 0xfff0); + onx = realx - (realx & 0xfff0); + + xLen = previousImage[0]->pixelsWide(); + yLen = previousImage[0]->pixelsHigh(); + ripl = xLen-size; + + breakHigh = 99999999; + + fabort = 0; + lowX = lowY = -1; + depthx = depthy = 1; + searchY = 8; //16; + searchX = 8; //32; + //if (xLen == (yLen*4)) depthx = 2; + //if (theRoQ->Scaleable()) depthx = depthy = 2; + + if (clamp) { searchX = searchY = 8; } + searchX = searchX*depthx; + searchY = searchY*depthy; + xxMean = dxMean*depthx; + yyMean = dyMean*depthy; + + if (((realx-xxMean)+searchX)<0 ||(((realx-xxMean)-searchX)+depthx+size)>xLen || ((realy-yyMean)+searchY)<0 || (((realy-yyMean)-searchY)+depthy+size)>yLen) { + pquad->snr[FCC] = 9999; + return; + } + + int sPsQ = -1; + for( sX=(((realx-xxMean)-searchX)+depthx); sX<=((realx-xxMean)+searchX) && !fabort; sX+=depthx ) { + for( sY=(((realy-yyMean)-searchY)+depthy); sY<=((realy-yyMean)+searchY) && breakHigh; sY+=depthy ) { + temp1 = xLen*sY+sX; + if ( sX >= 0 && (sX+size) <= xLen && sY >= 0 && (sY+size) <= yLen ) { + bpp = previousImage[0]->samplesPerPixel(); + ripl = (xLen-size)*bpp; + mblur0 = 0; + bitma2 = bitmap; + scale1 = previousImage[((whichFrame+1)&1)]->bitmapData() + temp1*bpp; +// mblur0 = 0; +// bitma2 = luty; +// scale1 = luti + temp1; + for( y=0; y breakHigh) { + break; + } + scale1 += ripl; + } + if (breakHigh > mblur0) { + breakHigh = mblur0; + lowX = sX; + lowY = sY; + } + } + } + } + + if (lowX != -1 && lowY != -1) { + bpp = previousImage[0]->samplesPerPixel(); + ripl = (xLen-size)*bpp; + mblur0 = 0; + bitma2 = bitmap; + scale1 = previousImage[((whichFrame+1)&1)]->bitmapData() + (xLen*lowY+lowX)*bpp; + for( y=0; ydomain = (sX<<8)+sY; + pquad->snr[FCC] = lowestSNR; + } +} + + +void codec::GetData( unsigned char *iData, int qSize, int startX, int startY, NSBitmapImageRep *bitmap) +{ +int x,y,yoff,bpp,yend,xend; +byte *iPlane[5]; +int r,g,b,a; + + yend = qSize+startY; + xend = qSize+startX; + + if (startY > bitmap->pixelsHigh()) return; + + if (yend > bitmap->pixelsHigh()) yend = bitmap->pixelsHigh(); + if (xend > bitmap->pixelsWide()) xend = bitmap->pixelsWide(); + + bpp = bitmap->samplesPerPixel(); + + if (bitmap->hasAlpha()) { + iPlane[0] = bitmap->bitmapData(); + for(y=startY;ypixelsWide()*bpp; + for(x=startX;xbitmapData(); + for(y=startY;ypixelsWide()*bpp; + for(x=startX;x theRoQ->NormalFrameSize()) { + quickadd[CCC] = 0.5f; + quickadd[PAT] = 1.0f; + } +*/ + wtemp = 99999; + + for(i=(DEAD-1);i>0;i--) { + if ( qtemp->snr[i]*quickadd[i] < wtemp ) { + *status = i; + *snr = qtemp->snr[i]; + wtemp = qtemp->snr[i]*quickadd[i]; + } + } + + if ( qtemp->mark ) *status = MOT; +} + +int codec::GetCurrentQuadOutputSize( quadcel *pquad ) +{ +int totalbits, i, totalbytes; +int quickadd[DEAD+1]; + + totalbits = 0; + + quickadd[DEP] = 2; + quickadd[SLD] = 10; + quickadd[PAT] = 10; + quickadd[CCC] = 34; + quickadd[MOT] = 2; + quickadd[FCC] = 10; + quickadd[DEAD] = 0; + + for( i=0; i> 3)+2; + return (totalbytes); +} + +float codec::GetCurrentRMSE( quadcel *pquad ) +{ +int i, j; +double totalbits; + + totalbits = 0; + j = 0; + for( i=0; iIsLastFrame() && !detail) { + pquad[i].mark = true; + } + } + LowestQuad( &pquad[i] ,&pquad[i].status, &pquad[i].rsnr, true ); + newsnr += pquad[i].rsnr; + } + Mem_Free(idataA); Mem_Free(idataB); + newsnr /= 4; + LowestQuad( &pquad[lownum], &pquad[lownum].status, &pquad[lownum].rsnr, false ); + + if ( pquad[lownum+nx*0+1].status == MOT && pquad[lownum+nx*1+1].status == MOT + && pquad[lownum+nx*2+1].status == MOT && pquad[lownum+nx*3+1].status == MOT + && nsize == 4) { newsnr = 9999; pquad[lownum].status = MOT; } + + if ( pquad[lownum].rsnr > newsnr ) { + pquad[lownum].status = DEP; + pquad[lownum].rsnr = 0; + for( i=lownum+1; iMarkQuadx( pquad[i].xat, pquad[i].yat, nsize, pquad[i].rsnr, qStatus[i].status ); + } + } else { + theRoQ->MarkQuadx( pquad[lownum].xat, pquad[lownum].yat, nsize*2, pquad[lownum].rsnr, qStatus[lownum].status ); + pquad[lownum+nx*0+1].status = 0; + pquad[lownum+nx*1+1].status = 0; + pquad[lownum+nx*2+1].status = 0; + pquad[lownum+nx*3+1].status = 0; + pquad[lownum+nx*0+1].size = 0; + pquad[lownum+nx*1+1].size = 0; + pquad[lownum+nx*2+1].size = 0; + pquad[lownum+nx*3+1].size = 0; + } + } else { + lownum = -1; + } + return lownum; +} + +int codec::MotMeanX( void ) +{ + return dxMean; +} + +int codec::MotMeanY( void ) +{ + return dyMean; +} + +void codec::SparseEncode( void ) +{ +int i, j, osize, fsize, num[DEAD+1], *ilist, onf, ong, wtype, temp; +float *flist, sRMSE, numredo; +byte *idataA, *idataB; + + osize = 8; + + image = theRoQ->CurrentImage(); + newImage = 0; + + pixelsHigh = image->pixelsHigh(); + pixelsWide = image->pixelsWide(); + + dimension2 = 12; dimension4 = 48; + if (image->hasAlpha()&&(theRoQ->ParamNoAlpha() == false)) { dimension2 = 16; dimension4 = 64; } + + idataA = (byte *)Mem_Alloc( 16*16*4 ); + idataB = (byte *)Mem_Alloc( 16*16*4 ); + + if (!previousImage[0]) common->Printf("sparseEncode: sparsely encoding a %d,%d image\n", pixelsWide, pixelsHigh); + InitImages(); + + flist = (float *)Mem_ClearedAlloc( (numQuadCels+1) *sizeof(float) ); + ilist = (int *)Mem_ClearedAlloc( (numQuadCels+1) *sizeof(int ) ); + + + fsize = 56*1024; + if (theRoQ->NumberOfFrames()>2) { + if (previousImage[0]) fsize = theRoQ->NormalFrameSize(); else fsize = theRoQ->FirstFrameSize(); + if (theRoQ->HasSound() && fsize > 6000 && previousImage[0]) fsize = 6000; + } + fsize += (slop/50); + if (fsize > 64000) { + fsize = 64000; + } + if (previousImage[0] && fsize > theRoQ->NormalFrameSize()*2) { + fsize = theRoQ->NormalFrameSize()*2; + } + dxMean = dyMean = 0; + if (previousImage[0]) wtype = 1; else wtype = 0; + + for( i=0; iIsLastFrame()) { + qStatus[i].mark = true; + } + if (!qStatus[i].mark) { + FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], false ); + } + } + LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype ); + if (qStatus[i].rsnr < 9999) + theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status ); + } else { + if ( qStatus[i].size < osize ) { + qStatus[i].status = 0; + qStatus[i].size = 0; + } else { + qStatus[i].status = DEP; + qStatus[i].rsnr = 0; + } + } + } +// +// the quad is complete, so status can now be used for quad decomposition +// the first thing to do is to set it up for all the 4x4 cels to get output +// and then recurse from there to see what's what +// + sRMSE = GetCurrentRMSE( qStatus ); + + if (theRoQ->IsQuiet() == false) { + common->Printf("sparseEncode: rmse of quad0 is %f, size is %d (meant to be %d)\n", sRMSE, GetCurrentQuadOutputSize(qStatus), fsize ); + } + + onf = 0; + for(i=0;i> 8 ) - 128; + dyMean += (qStatus[i].domain & 0xff) - 128; + temp++; + } + } + if (temp) { dxMean /= temp; dyMean /= temp; } + */ + common->Printf("sparseEncode: dx/dy mean is %d,%d\n", dxMean, dyMean); + + numredo = 0; + detail = false; + if (codebookmade && whichFrame>4) fsize -= 256; + temp = 0; + for( i=0; i 0 ) { + GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image ); + if (osize == 8) VqData8( idataA, &qStatus[i] ); + if (previousImage[0]) { + int dx,dy; + dx = (qStatus[i].domain >> 8 ) - 128 - dxMean + 8; + dy = (qStatus[i].domain & 0xff) - 128 - dyMean + 8; + if (dx<0||dx>15||dy<0||dy>15) { + qStatus[i].snr[FCC] = 9999; + temp++; + FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], true ); + dx = (qStatus[i].domain >> 8 ) - 128 - dxMean + 8; + dy = (qStatus[i].domain & 0xff) - 128 - dyMean + 8; + if ((dx<0||dx>15||dy<0||dy>15)&&qStatus[i].snr[FCC]!=9999&&qStatus[i].status==FCC) { + common->Printf("sparseEncode: something is wrong here, dx/dy is %d,%d after being clamped\n", dx, dy); + common->Printf("xat: %d\n", qStatus[i].xat); + common->Printf("yat: %d\n", qStatus[i].yat); + common->Printf("size %d\n", qStatus[i].size); + common->Printf("type: %d\n", qStatus[i].status); + common->Printf("mot: %04x\n", qStatus[i].domain); + common->Printf("motsnr: %0f\n", qStatus[i].snr[FCC]); + common->Printf("rmse: %0f\n", qStatus[i].rsnr); + common->Error("need to go away now\n"); + } + } + } + LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype ); + theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status ); + /* + if (qStatus[i].status==FCC && qStatus[i].snr[FCC]>qStatus[i].snr[SLD]) { + common->Printf("sparseEncode: something is wrong here\n"); + common->Printf("xat: %d\n", qStatus[i].xat); + common->Printf("yat: %d\n", qStatus[i].yat); + common->Printf("size %d\n", qStatus[i].size); + common->Printf("type: %d\n", qStatus[i].status); + common->Printf("mot: %04x\n", qStatus[i].domain); + common->Printf("motsnr: %0f\n", qStatus[i].snr[FCC]); + common->Printf("sldsnr: %0f\n", qStatus[i].snr[SLD]); + common->Printf("rmse: %0f\n", qStatus[i].rsnr); + //common->Error("need to go away now\n"); + } + */ + } + } + + if (theRoQ->IsQuiet() == false) { + common->Printf("sparseEncode: rmse of quad0 is %f, size is %d (meant to be %d)\n", GetCurrentRMSE( qStatus ), GetCurrentQuadOutputSize( qStatus ), fsize ); + common->Printf("sparseEncode: %d outside fcc limits\n", temp); + } + + onf = 0; + for(i=0;i 0 && qStatus[ilist[ong]].mark == false) { +// badsnr = [self getCurrentRMSE: qStatus]; + osize = AddQuad( qStatus, ilist[ong++] ); +// if ([self getCurrentRMSE: qStatus] >= badsnr) { +// break; +// } + } + + if ( GetCurrentQuadOutputSize( qStatus ) < fsize) { + ong = 0; + while ( GetCurrentQuadOutputSize(qStatus) < fsize && ong < onf) { +// badsnr = [self getCurrentRMSE: qStatus]; + i = ilist[ong++]; + if (qStatus[i].mark) { + detail = false; + qStatus[i].mark = false; + GetData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, image ); + if (qStatus[i].size == 8) VqData8( idataA, &qStatus[i] ); + if (qStatus[i].size == 4) VqData4( idataA, &qStatus[i] ); + if (qStatus[i].size == 4) VqData2( idataA, &qStatus[i] ); + if (previousImage[0]) { + FvqData( idataA, qStatus[i].size, qStatus[i].xat, qStatus[i].yat, &qStatus[i], true ); + } + LowestQuad( &qStatus[i], &qStatus[i].status, &qStatus[i].rsnr, wtype ); + if (qStatus[i].rsnr <= MIN_SNR) { + break; + } + theRoQ->MarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status ); + } +// if ([self getCurrentRMSE: qStatus] >= badsnr) { +// break; +// } + } + ong = 0; + while ( GetCurrentQuadOutputSize( qStatus ) < fsize && ong < onf && flist[ong] > 0) { +// badsnr = [self getCurrentRMSE: qStatus]; + i = ilist[ong++]; +// if (qStatus[i].rsnr <= MIN_SNR) { +// break; +// } + detail = true; + osize = AddQuad( qStatus, i ); +// if ([self getCurrentRMSE: qStatus] >= badsnr) { +// break; +// } + } + } + + common->Printf("sparseEncode: rmse of frame %d is %f, size is %d\n", whichFrame, GetCurrentRMSE(qStatus), GetCurrentQuadOutputSize(qStatus) ); + + if (previousImage[0]) + fsize = theRoQ->NormalFrameSize(); + else + fsize = theRoQ->FirstFrameSize(); + + slop += (fsize - GetCurrentQuadOutputSize(qStatus)); + + if (theRoQ->IsQuiet() == false) { + for(i=0;iPrintf("sparseEncode: for 08x08 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]); + + for(i=0;iPrintf("sparseEncode: for 04x04 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]); + + common->Printf("sparseEncode: average RMSE = %f, numActiveQuadCels = %d, estSize = %d, slop = %d \n", GetCurrentRMSE(qStatus), j, GetCurrentQuadOutputSize(qStatus), slop); + } + + theRoQ->WriteFrame( qStatus ); + MakePreviousImage( qStatus ); + + Mem_Free(idataA); + Mem_Free(idataB); + Mem_Free(flist); + Mem_Free(ilist); + if (newImage) delete newImage; + + whichFrame++; +} + +void codec::EncodeNothing( void ) +{ +int i, j, osize, fsize, num[DEAD+1], *ilist, wtype; +float *flist, sRMSE; +byte *idataA, *idataB; + + osize = 8; + + image = theRoQ->CurrentImage(); + newImage = 0; + + pixelsHigh = image->pixelsHigh(); + pixelsWide = image->pixelsWide(); + + dimension2 = 12; dimension4 = 48; + if (image->hasAlpha()&&(theRoQ->ParamNoAlpha() == false)) { dimension2 = 16; dimension4 = 64; } + + idataA = (byte *)Mem_Alloc( 16*16*4 ); + idataB = (byte *)Mem_Alloc( 16*16*4 ); + + if (!previousImage[0]) common->Printf("sparseEncode: sparsely encoding a %d,%d image\n", pixelsWide, pixelsHigh); + InitImages(); + + flist = (float *)Mem_ClearedAlloc( (numQuadCels+1) * sizeof(float) ); + ilist = (int *)Mem_ClearedAlloc( (numQuadCels+1) * sizeof(int ) ); + + + fsize = 56*1024; + if (theRoQ->NumberOfFrames()>2) { + if (previousImage[0]) fsize = theRoQ->NormalFrameSize(); else fsize = theRoQ->FirstFrameSize(); + if (theRoQ->HasSound() && fsize > 6000 && previousImage[0]) fsize = 6000; + } + + dxMean = dyMean = 0; + if (previousImage[0]) wtype = 1; else wtype = 0; + + for( i=0; iMarkQuadx( qStatus[i].xat, qStatus[i].yat, qStatus[i].size, qStatus[i].rsnr, qStatus[i].status ); + } else { + if ( qStatus[i].size < osize ) { + qStatus[i].status = 0; + qStatus[i].size = 0; + } else { + qStatus[i].status = DEP; + qStatus[i].rsnr = 0; + } + } + } +// +// the quad is complete, so status can now be used for quad decomposition +// the first thing to do is to set it up for all the 4x4 cels to get output +// and then recurse from there to see what's what +// + sRMSE = GetCurrentRMSE( qStatus ); + + common->Printf("sparseEncode: rmse of frame %d is %f, size is %d\n", whichFrame, sRMSE, GetCurrentQuadOutputSize( qStatus ) ); + + + if (theRoQ->IsQuiet() == false) { + for(i=0;iPrintf("sparseEncode: for 08x08 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]); + + for(i=0;iPrintf("sparseEncode: for 04x04 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = %d\n", num[CCC], num[FCC], num[MOT], num[SLD], num[PAT]); + + common->Printf("sparseEncode: average RMSE = %f, numActiveQuadCels = %d, estSize = %d \n", GetCurrentRMSE(qStatus), j, GetCurrentQuadOutputSize(qStatus)); + } + + theRoQ->WriteFrame( qStatus ); + MakePreviousImage( qStatus ); + + Mem_Free(idataA); + Mem_Free(idataB); + Mem_Free(flist); + Mem_Free(ilist); + if (newImage) delete newImage; + + whichFrame++; +} + +void codec::VQ( const int numEntries, const int dimension, const unsigned char *vectors, float *import, VQDATA **codebook, const bool optimize ) { + int startMsec = Sys_Milliseconds(); + + if (numEntries <= 256) { + // + // copy the entries into the codebooks + // + for( int i=0; iPrintf("VQ: has %d entries to process\n", numFinalEntries ); + + // + // are we done? + // + int end; + if (numFinalEntries > 256) { + // + // find the closest two and eliminate one + // + double bestDist = HUGE; + double dist, simport; + int bestIndex = -1; + int bestOtherIndex = 0; + int aentries = 0; + for( i=0; i8192) { + end = i+32; + } else if (numFinalEntries>4096) { + end = i+64; + } else if (numFinalEntries>2048) { + end = i+128; + } else if (numFinalEntries>1024) { + end = i+256; + } else if (numFinalEntries>512) { + end = i+512; + } + if (end>numEntries) { + end = numEntries; + } + } + ibase = i*dimension; + for( j=i+1; j8192) { + end = i+32; + } else if (numFinalEntries>4096) { + end = i+64; + } else if (numFinalEntries>2048) { + end = i+128; + } else if (numFinalEntries>1024) { + end = i+256; + } else if (numFinalEntries>512) { + end = i+512; + } + } + if (end>numEntries) { + end = numEntries; + } + ibase = i*dimension; + for( j=i+1; j scaledBestDist ) { + break; + } +#endif + } + dist *= simport; + if ( dist < bestDist ) { + bestDist = dist; + bestIndex = i; + bestOtherIndex = j; + } + } + snrs[aentries] = bestDist; + indexes[aentries] = bestIndex; + indexet[aentries] = bestOtherIndex; + aentries++; + } + } + // + // and lose one + // + inuse[bestIndex] = false; + numFinalEntries--; + import[bestOtherIndex] += import[bestIndex]; + if ((numFinalEntries&511)==0) { + common->Printf("VQ: has %d entries to process\n", numFinalEntries ); + session->UpdateScreen(); + } + } while (numFinalEntries > 256); + } + // + // copy the entries into the codebooks + // + int onEntry = 0; + for( i=0; iPrintf("First vq = %d\n ", i); + } + if (onEntry == 255) { + common->Printf("last vq = %d\n", i); + } + onEntry++; + } + } + + int endMsec = Sys_Milliseconds(); + common->Printf( "VQ took %i msec\n", endMsec - startMsec ); +} + diff --git a/tools/compilers/roqvq/codec.h b/tools/compilers/roqvq/codec.h new file mode 100644 index 000000000..556224c6c --- /dev/null +++ b/tools/compilers/roqvq/codec.h @@ -0,0 +1,99 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __codec_h__ +#define __codec_h__ + +#define MAXERRORMAX 200 +#define IPSIZE int +const float MOTION_MIN = 1.0f; +const float MIN_SNR = 3.0f; + +#define FULLFRAME 0 +#define JUSTMOTION 1 + +#define VQDATA double + +#include "gdefs.h" +#include "roq.h" +#include "quaddefs.h" + +class codec { +public: + codec(); + ~codec(); + + void SparseEncode( void ); + void EncodeNothing( void ); + void IRGBtab(void); + void InitImages(void); + void QuadX( int startX, int startY, int quadSize); + void InitQStatus(); + float Snr(byte *old, byte *bnew, int size); + void FvqData( byte *bitmap, int size, int realx, int realy, quadcel *pquad, bool clamp); + void GetData( unsigned char *iData, int qSize, int startX, int startY, NSBitmapImageRep *bitmap); + int ComputeMotionBlock( byte *old, byte *bnew, int size); + void VqData8( byte *cel, quadcel *pquad); + void VqData4( byte *cel, quadcel *pquad); + void VqData2( byte *cel, quadcel *pquad); + int MotMeanY(void); + int MotMeanX(void); + void SetPreviousImage( const char*filename, NSBitmapImageRep *timage ); + int BestCodeword( unsigned char *tempvector, int dimension, VQDATA **codebook ); +private: + + void VQ( const int numEntries, const int dimension, const unsigned char *vectors, float *snr, VQDATA **codebook, const bool optimize ); + void Sort( float *list, int *intIndex, int numElements ); + void Segment( int *alist, float *flist, int numElements, float rmse); + void LowestQuad( quadcel*qtemp, int* status, float* snr, int bweigh); + void MakePreviousImage( quadcel *pquad ); + float GetCurrentRMSE( quadcel *pquad ); + int GetCurrentQuadOutputSize( quadcel *pquad ); + int AddQuad( quadcel *pquad, int lownum ); + + NSBitmapImageRep *image; + NSBitmapImageRep *newImage; + NSBitmapImageRep *previousImage[2]; // the ones in video ram and offscreen ram + int numQuadCels; + int whichFrame; + int slop; + bool detail; + int onQuad; + int initRGBtab; + quadcel *qStatus; + int dxMean; + int dyMean; + int codebooksize; + int index2[256]; + int overAmount; + int pixelsWide; + int pixelsHigh; + int codebookmade; + bool used2[256]; + bool used4[256]; + int dimension2; + int dimension4; + + byte luty[256]; + byte *luti; + VQDATA **codebook2; + VQDATA **codebook4; + +}; + +#endif // __codec_h__ diff --git a/tools/compilers/roqvq/gdefs.h b/tools/compilers/roqvq/gdefs.h new file mode 100644 index 000000000..8c2cdb415 --- /dev/null +++ b/tools/compilers/roqvq/gdefs.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __gdefs_h__ +#define __gdefs_h__ + +/*==================* + * TYPE DEFINITIONS * + *==================*/ + +typedef unsigned char byte; +typedef unsigned short word; +#pragma once + +#define dabs(a) (((a)<0) ? -(a) : (a)) +#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v)>(h) ? (h) : v) +#define xswap(a,b) { a^=b; b^=a; a^=b; } +#define lum(a) ( 0.2990*(a>>16) + 0.5870*((a>>8)&0xff) + 0.1140*(a&0xff) ) +#define gsign(a) ((a) < 0 ? -1 : 1) +#define mnint(a) ((a) < 0 ? (int)(a - 0.5) : (int)(a + 0.5)) +#define mmax(a, b) ((a) > (b) ? (a) : (b)) +#define mmin(a, b) ((a) < (b) ? (a) : (b)) +#define RGBDIST( src0, src1 ) ( ((src0[0]-src1[0])*(src0[0]-src1[0])) + \ + ((src0[1]-src1[1])*(src0[1]-src1[1])) + \ + ((src0[2]-src1[2])*(src0[2]-src1[2])) ) + +#define RGBADIST( src0, src1 ) ( ((src0[0]-src1[0])*(src0[0]-src1[0])) + \ + ((src0[1]-src1[1])*(src0[1]-src1[1])) + \ + ((src0[2]-src1[2])*(src0[2]-src1[2])) + \ + ((src0[3]-src1[3])*(src0[3]-src1[3])) ) + + +#define RMULT 0.2990f // use these for televisions +#define GMULT 0.5870f +#define BMULT 0.1140f + +#define RIEMULT -0.16874f +#define RQEMULT 0.50000f +#define GIEMULT -0.33126f +#define GQEMULT -0.41869f +#define BIEMULT 0.50000f +#define BQEMULT -0.08131f + +#endif // gdefs diff --git a/tools/compilers/roqvq/quaddefs.h b/tools/compilers/roqvq/quaddefs.h new file mode 100644 index 000000000..bb038b2d7 --- /dev/null +++ b/tools/compilers/roqvq/quaddefs.h @@ -0,0 +1,122 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __quaddefs_h__ +#define __quaddefs_h__ + +#pragma once + +#define DEP 0 +#define FCC 1 +#define CCC 2 +#define SLD 3 +#define PAT 4 +#define MOT 5 +#define DEAD 6 + +#define COLA 0 +#define COLB 1 +#define COLC 2 +#define COLS 3 +#define COLPATA 4 +#define COLPATB 5 +#define COLPATS 6 +#define GENERATION 7 + +#define CCCBITMAP 0 +#define FCCDOMAIN 1 +#define PATNUMBER 2 +#define PATNUMBE2 3 +#define PATNUMBE3 4 +#define PATNUMBE4 5 +#define PATNUMBE5 6 + +#define MAXSIZE 16 +#define MINSIZE 4 + +#define RoQ_ID 0x1084 +#define RoQ_QUAD 0x1000 +#define RoQ_PUZZLE_QUAD 0x1003 +#define RoQ_QUAD_HANG 0x1013 +#define RoQ_QUAD_SMALL 0x1010 +#define RoQ_QUAD_INFO 0x1001 +#define RoQ_QUAD_VQ 0x1011 +#define RoQ_QUAD_JPEG 0x1012 +#define RoQ_QUAD_CODEBOOK 0x1002 + +typedef struct { + byte size; // 32, 16, 8, or 4 + word xat; // where is it at on the screen + word yat; // +} shortQuadCel; + +typedef struct { + byte size; // 32, 16, 8, or 4 + word xat; // where is it at on the screen + word yat; // + + float cccsnr; // ccc bitmap snr to actual image + float fccsnr; // fcc bitmap snr to actual image + float motsnr; // delta snr to previous image + float sldsnr; // solid color snr + float patsnr; + float dctsnr; + float rsnr; // what's the current snr + + unsigned int cola; // color a for ccc + unsigned int colb; // color b for ccc + unsigned int colc; // color b for ccc + unsigned int sldcol; // sold color + unsigned int colpata; + unsigned int colpatb; + unsigned int colpats; + unsigned int bitmap; // ccc bitmap + + word domain; // where to copy from for fcc + word patten[5]; // which pattern + + int status; + bool mark; + float snr[DEAD+1]; // snrssss +} quadcel; + +typedef struct { + float snr[DEAD+1]; // snrssss + unsigned int cols[8]; + unsigned int bitmaps[7]; // ccc bitmap +} dataQuadCel; + +typedef struct { + float normal; + unsigned short int index; +} norm; + +typedef struct { + unsigned char dtlMap[256]; + int r[4]; + int g[4]; + int b[4]; + int a[4]; + float ymean; +} dtlCel; + +typedef struct { + byte r,g,b,a; +} pPixel; + +#endif // quaddef diff --git a/tools/compilers/roqvq/roq.cpp b/tools/compilers/roqvq/roq.cpp new file mode 100644 index 000000000..b2e94e066 --- /dev/null +++ b/tools/compilers/roqvq/roq.cpp @@ -0,0 +1,846 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "roq.h" +#include "codec.h" + +roq *theRoQ; // current roq file + +roq::roq( void ) +{ + image = 0; + quietMode = false; + encoder = 0; + previousSize = 0; + lastFrame = false; + dataStuff=false; +} + +roq::~roq( void ) +{ + if (image) delete image; + if (encoder) delete encoder; + return; +} + +void roq::EncodeQuietly( bool which ) +{ + quietMode = which; +} + +bool roq::IsQuiet( void ) +{ + return quietMode; +} + +bool roq::IsLastFrame( void ) +{ + return lastFrame; +} + +bool roq::Scaleable( void ) +{ + return paramFile->IsScaleable(); +} + +bool roq::ParamNoAlpha( void ) +{ + return paramFile->NoAlpha(); +} + +bool roq::MakingVideo( void ) +{ + return true; //paramFile->timecode]; +} + +bool roq::SearchType( void ) +{ + return paramFile->SearchType(); +} + +bool roq::HasSound( void ) +{ + return paramFile->HasSound(); +} + +int roq::PreviousFrameSize( void ) +{ + return previousSize; +} + +int roq::FirstFrameSize( void ) +{ + return paramFile->FirstFrameSize(); +} + +int roq::NormalFrameSize( void ) +{ + return paramFile->NormalFrameSize(); +} + +const char * roq::CurrentFilename( void ) +{ + return currentFile.c_str(); +} + +void roq::EncodeStream( const char *paramInputFile ) +{ + int onFrame; + idStr f0, f1, f2; + int morestuff; + + onFrame = 1; + + encoder = new codec; + paramFile = new roqParam; + paramFile->numInputFiles = 0; + + paramFile->InitFromFile( paramInputFile ); + + if (!paramFile->NumberOfFrames()) { + return; + } + + InitRoQFile( paramFile->outputFilename); + + numberOfFrames = paramFile->NumberOfFrames(); + + if (paramFile->NoAlpha()==true) common->Printf("encodeStream: eluding alpha\n"); + + f0 = ""; + f1 = paramFile->GetNextImageFilename(); + if (( paramFile->MoreFrames() == true )) { + f2 = paramFile->GetNextImageFilename(); + } + morestuff = numberOfFrames; + + while( morestuff ) { + LoadAndDisplayImage( f1 ); + + if (onFrame==1) { + encoder->SparseEncode(); +// WriteLossless(); + } else { + if (!strcmp( f0, f1 ) && strcmp( f1, f2) ) { + WriteHangFrame(); + } else { + encoder->SparseEncode(); + } + } + + onFrame++; + f0 = f1; + f1 = f2; + if (paramFile->MoreFrames() == true) { + f2 = paramFile->GetNextImageFilename(); + } + morestuff--; + session->UpdateScreen(); + } + +// if (numberOfFrames != 1) { +// if (image->hasAlpha() && paramFile->NoAlpha()==false) { +// lastFrame = true; +// encoder->SparseEncode(); +// } else { +// WriteLossless(); +// } +// } + CloseRoQFile(); +} + +void roq::Write16Word( word *aWord, idFile *stream ) +{ + byte a, b; + + a = *aWord & 0xff; + b = *aWord >> 8; + + stream->Write( &a, 1 ); + stream->Write( &b, 1 ); +} + +void roq::Write32Word( unsigned int *aWord, idFile *stream ) +{ + byte a, b, c, d; + + a = *aWord & 0xff; + b = (*aWord >> 8) & 0xff; + c = (*aWord >> 16) & 0xff; + d = (*aWord >> 24) & 0xff; + + stream->Write( &a, 1 ); + stream->Write( &b, 1 ); + stream->Write( &c, 1 ); + stream->Write( &d, 1 ); +} + +int roq::SizeFile( idFile *ftosize ) +{ + return ftosize->Length(); +} + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + byte* outfile; /* target stream */ + int size; +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +void roq::JPEGInitDestination (j_compress_ptr cinfo) { + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + dest->pub.next_output_byte = dest->outfile; + dest->pub.free_in_buffer = dest->size; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return true + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +boolean roq::JPEGEmptyOutputBuffer (j_compress_ptr cinfo) { + return true; +} + + +/* + * Compression initialization. + * Before calling this, all parameters and a data destination must be set up. + * + * We require a write_all_tables parameter as a failsafe check when writing + * multiple datastreams from the same compression object. Since prior runs + * will have left all the tables marked sent_table=true, a subsequent run + * would emit an abbreviated stream (no tables) by default. This may be what + * is wanted, but for safety's sake it should not be the default behavior: + * programmers should have to make a deliberate choice to emit abbreviated + * images. Therefore the documentation and examples should encourage people + * to pass write_all_tables=true; then it will take active thought to do the + * wrong thing. + */ + +void roq::JPEGStartCompress (j_compress_ptr cinfo, bool write_all_tables) { + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (write_all_tables) + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + jinit_compress_master(cinfo); + /* Set up for the first pass */ + (*cinfo->master->prepare_for_pass) (cinfo); + /* Ready for application to drive first pass through jpeg_write_scanlines + * or jpeg_write_raw_data. + */ + cinfo->next_scanline = 0; + cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); +} + + +/* + * Write some scanlines of data to the JPEG compressor. + * + * The return value will be the number of lines actually written. + * This should be less than the supplied num_lines only in case that + * the data destination module has requested suspension of the compressor, + * or if more than image_height scanlines are passed in. + * + * Note: we warn about excess calls to jpeg_write_scanlines() since + * this likely signals an application programmer error. However, + * excess scanlines passed in the last valid call are *silently* ignored, + * so that the application need not adjust num_lines for end-of-image + * when using a multiple-scanline buffer. + */ + +JDIMENSION roq::JPEGWriteScanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines) { + JDIMENSION row_ctr, rows_left; + + if (cinfo->global_state != CSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_scanlines. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_scanlines. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Ignore any extra scanlines at bottom of image. */ + rows_left = cinfo->image_height - cinfo->next_scanline; + if (num_lines > rows_left) + num_lines = rows_left; + + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); + cinfo->next_scanline += row_ctr; + return row_ctr; +} + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +static int hackSize; + +void roq::JPEGTermDestination (j_compress_ptr cinfo) { + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = dest->size - dest->pub.free_in_buffer; + hackSize = datacount; +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +void roq::JPEGDest (j_compress_ptr cinfo, byte* outfile, int size) { + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = JPEGInitDestination; + dest->pub.empty_output_buffer = JPEGEmptyOutputBuffer; + dest->pub.term_destination = JPEGTermDestination; + dest->outfile = outfile; + dest->size = size; +} + +void roq::WriteLossless( void ) { + + word direct; + uint directdw; + + if (!dataStuff) { + InitRoQPatterns(); + dataStuff=true; + } + direct = RoQ_QUAD_JPEG; + Write16Word( &direct, RoQFile); + + /* This struct contains the JPEG compression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + * It is possible to have several such structures, representing multiple + * compression/decompression processes, in existence at once. We refer + * to any one struct (and its associated working data) as a "JPEG object". + */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + byte *out; + + /* Step 1: allocate and initialize JPEG compression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + /* Here we use the library-supplied code to send compressed data to a + * stdio stream. You can also write your own code to do something else. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to write binary files. + */ + out = (byte *)Mem_Alloc(image->pixelsWide()*image->pixelsHigh()*4); + JPEGDest(&cinfo, out, image->pixelsWide()*image->pixelsHigh()*4); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = image->pixelsWide(); /* image width and height, in pixels */ + cinfo.image_height = image->pixelsHigh(); + cinfo.input_components = 4; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + /* Now use the library's routine to set default compression parameters. + * (You must set at least cinfo.in_color_space before calling this, + * since the defaults depend on the source color space.) + */ + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, paramFile->JpegQuality(), true /* limit to baseline-JPEG values */); + + /* Step 4: Start compressor */ + + /* true ensures that we will write a complete interchange-JPEG file. + * Pass true unless you are very sure of what you're doing. + */ + JPEGStartCompress(&cinfo, true); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + /* Here we use the library's state variable cinfo.next_scanline as the + * loop counter, so that we don't have to keep track ourselves. + * To keep things simple, we pass one scanline per call; you can pass + * more if you wish, though. + */ + row_stride = image->pixelsWide() * 4; /* JSAMPLEs per row in image_buffer */ + + byte *pixbuf = image->bitmapData(); + while (cinfo.next_scanline < cinfo.image_height) { + /* jpeg_write_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could pass + * more than one scanline at a time if that's more convenient. + */ + row_pointer[0] = &pixbuf[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride]; + (void) JPEGWriteScanlines(&cinfo, row_pointer, 1); + } + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + /* After finish_compress, we can close the output file. */ + + directdw = hackSize; + common->Printf("writeLossless: writing %d bytes to RoQ_QUAD_JPEG\n", hackSize); + Write32Word( &directdw, RoQFile ); + direct = 0; // flags + Write16Word( &direct, RoQFile ); + + RoQFile->Write( out, hackSize ); + Mem_Free(out); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + + /* And we're done! */ + encoder->SetPreviousImage( "first frame", image ); +} + +void roq::InitRoQFile( const char *RoQFilename ) +{ + word i; + static int finit = 0; + + if (!finit) { + finit++; + common->Printf("initRoQFile: %s\n", RoQFilename); + RoQFile = fileSystem->OpenFileWrite( RoQFilename ); +// chmod(RoQFilename, S_IREAD|S_IWRITE|S_ISUID|S_ISGID|0070|0007 ); + if ( !RoQFile ) { + common->Error("Unable to open output file %s.\n", RoQFilename); + } + + i = RoQ_ID; + Write16Word( &i, RoQFile ); + + i = 0xffff; + Write16Word( &i, RoQFile ); + Write16Word( &i, RoQFile ); + + // to retain exact file format write out 32 for new roq's + // on loading this will be noted and converted to 1000 / 30 + // as with any new sound dump avi demos we need to playback + // at the speed the sound engine dumps the audio + i = 30; // framerate + Write16Word( &i, RoQFile ); + } + roqOutfile = RoQFilename; +} + +void roq::InitRoQPatterns( void ) +{ +uint j; +word direct; + + direct = RoQ_QUAD_INFO; + Write16Word( &direct, RoQFile ); + + j = 8; + + Write32Word( &j, RoQFile ); + common->Printf("initRoQPatterns: outputting %d bytes to RoQ_INFO\n", j); + direct = image->hasAlpha(); + if (ParamNoAlpha() == true) direct = 0; + + Write16Word( &direct, RoQFile ); + + direct = image->pixelsWide(); + Write16Word( &direct, RoQFile ); + direct = image->pixelsHigh(); + Write16Word( &direct, RoQFile ); + direct = 8; + Write16Word( &direct, RoQFile ); + direct = 4; + Write16Word( &direct, RoQFile ); +} + +void roq::CloseRoQFile( void ) +{ + common->Printf("closeRoQFile: closing RoQ file\n"); + fileSystem->CloseFile( RoQFile ); +} + +void roq::WriteHangFrame( void ) +{ +uint j; +word direct; + common->Printf("*******************************************************************\n"); + direct = RoQ_QUAD_HANG; + Write16Word( &direct, RoQFile); + j = 0; + Write32Word( &j, RoQFile); + direct = 0; + Write16Word( &direct, RoQFile); +} + +void roq::WriteCodeBookToStream( byte *codebook, int csize, word cflags ) +{ +uint j; +word direct; + + if (!csize) { + common->Printf("writeCodeBook: false VQ DATA!!!!\n"); + return; + } + + direct = RoQ_QUAD_CODEBOOK; + + Write16Word( &direct, RoQFile); + + j = csize; + + Write32Word( &j, RoQFile); + common->Printf("writeCodeBook: outputting %d bytes to RoQ_QUAD_CODEBOOK\n", j); + + direct = cflags; + Write16Word( &direct, RoQFile); + + RoQFile->Write( codebook, j ); +} + +void roq::WriteCodeBook( byte *codebook ) +{ + memcpy( codes, codebook, 4096 ); +} + +void roq::WriteFrame( quadcel *pquad ) +{ +word action, direct; +int onCCC, onAction, i, code; +uint j; +byte *cccList; +bool *use2, *use4; +int dx,dy,dxMean,dyMean,index2[256],index4[256], dimension; + + cccList = (byte *)Mem_Alloc( numQuadCels * 8); // maximum length + use2 = (bool *)Mem_Alloc(256*sizeof(bool)); + use4 = (bool *)Mem_Alloc(256*sizeof(bool)); + + for(i=0;i<256;i++) { + use2[i] = false; + use4[i] = false; + } + + action = 0; + j = onAction = 0; + onCCC = 2; // onAction going to go at zero + + dxMean = encoder->MotMeanX(); + dyMean = encoder->MotMeanY(); + + if (image->hasAlpha()) dimension = 10; else dimension = 6; + + for (i=0; ihasAlpha()) i = 3584; else i = 2560; + WriteCodeBookToStream( codes, i, 0 ); + for(i=0;i<256;i++) { + index2[i] = i; + index4[i] = i; + } + } else { + j = 0; + for(i=0;i<256;i++) { + if (use2[i]) { + index2[i] = j; + for(dx=0;dxPrintf("writeFrame: really used %d 2x2 cels\n", j); + j = 0; + for(i=0;i<256;i++) { + if (use4[i]) { + index4[i] = j; + for(dx=0;dx<4;dx++) cccList[j*4+code+dx] = index2[codes[i*4+(dimension*256)+dx]]; + j++; + } + } + code += j*4; + direct = (direct<<8) + j; + common->Printf("writeFrame: really used %d 4x4 cels\n", j); + if (image->hasAlpha()) i = 3584; else i = 2560; + if ( code == i || j == 256) { + WriteCodeBookToStream( codes, i, 0 ); + } else { + WriteCodeBookToStream( cccList, code, direct ); + } + } + + action = 0; + j = onAction = 0; + + for (i=0; i> 8 )) - 128 - dxMean + 8; + dy = ((pquad[i].domain & 0xff)) - 128 - dyMean + 8; + if (dx>15 || dx<0 || dy>15 || dy<0 ) { + common->Error("writeFrame: FCC error %d,%d mean %d,%d at %d,%d,%d rmse %f\n", dx,dy, dxMean, dyMean,pquad[i].xat,pquad[i].yat,pquad[i].size, pquad[i].snr[FCC] ); + } + cccList[onCCC++] = (dx<<4)+dy; + break; + case PAT: + code = 2; + cccList[onCCC++] = index4[pquad[i].patten[0]]; + break; + case CCC: + code = 3; + cccList[onCCC++] = index2[pquad[i].patten[1]]; + cccList[onCCC++] = index2[pquad[i].patten[2]]; + cccList[onCCC++] = index2[pquad[i].patten[3]]; + cccList[onCCC++] = index2[pquad[i].patten[4]]; + break; + case DEAD: + common->Error("dead cels in picture\n"); + break; + } + if (code == -1) { + common->Error( "writeFrame: an error occurred writing the frame\n"); + } + + action = (action<<2)|code; + j++; + if (j == 8) { + j = 0; + cccList[onAction+0] = (action & 0xff); + cccList[onAction+1] = ((action >> 8) & 0xff); + onAction = onCCC; + onCCC += 2; + } + } + } + + if (j) { + action <<= ((8-j)*2); + cccList[onAction+0] = (action & 0xff); + cccList[onAction+1] = ((action >> 8) & 0xff); + } + + direct = RoQ_QUAD_VQ; + + Write16Word( &direct, RoQFile); + + j = onCCC; + Write32Word( &j, RoQFile); + + direct = dyMean; + direct &= 0xff; + direct += (dxMean<<8); // flags + + Write16Word( &direct, RoQFile); + + common->Printf("writeFrame: outputting %d bytes to RoQ_QUAD_VQ\n", j); + + previousSize = j; + + RoQFile->Write( cccList, onCCC ); + + Mem_Free( cccList ); + Mem_Free( use2 ); + Mem_Free( use4 ); +} + +// +// load a frame, create a window (if neccesary) and display the frame +// +void roq::LoadAndDisplayImage( const char * filename ) +{ + if (image) delete image; + + common->Printf("loadAndDisplayImage: %s\n", filename); + + currentFile = filename; + + image = new NSBitmapImageRep( filename ); + + numQuadCels = ((image->pixelsWide() & 0xfff0)*(image->pixelsHigh() & 0xfff0))/(MINSIZE*MINSIZE); + numQuadCels += numQuadCels/4 + numQuadCels/16; + +// if (paramFile->deltaFrames] == true && cleared == false && [image isPlanar] == false) { +// cleared = true; +// imageData = [image data]; +// memset( imageData, 0, image->pixelsWide()*image->pixelsHigh()*[image samplesPerPixel]); +// } + + if (!quietMode) common->Printf("loadAndDisplayImage: %dx%d\n", image->pixelsWide(), image->pixelsHigh()); +} + +void roq::MarkQuadx( int xat, int yat, int size, float cerror, int choice ) { +} + +NSBitmapImageRep* roq::CurrentImage( void ) +{ + return image; +} + +int roq::NumberOfFrames( void ) { + return numberOfFrames; +} + +void RoQFileEncode_f( const idCmdArgs &args ) { + if ( args.Argc() != 2 ) { + common->Printf( "Usage: roq \n" ); + return; + } + theRoQ = new roq; + int startMsec = Sys_Milliseconds(); + theRoQ->EncodeStream( args.Argv( 1 ) ); + int stopMsec = Sys_Milliseconds(); + common->Printf( "total encoding time: %i second\n", ( stopMsec - startMsec ) / 1000 ); + +} diff --git a/tools/compilers/roqvq/roq.h b/tools/compilers/roqvq/roq.h new file mode 100644 index 000000000..82fed53d8 --- /dev/null +++ b/tools/compilers/roqvq/roq.h @@ -0,0 +1,126 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __roq_h__ +#define __roq_h__ + +#include "gdefs.h" +#include "roqParam.h" +#include "quaddefs.h" +#define JPEG_INTERNALS +extern "C" { +#include "../../../renderer/jpeg-6/jpeglib.h" +} +#pragma once + +class codec; +class roqParam; + +class NSBitmapImageRep { +public: + + NSBitmapImageRep( void ); + NSBitmapImageRep( const char *filename ); + NSBitmapImageRep( int wide, int high ); + ~NSBitmapImageRep(); + + NSBitmapImageRep & operator=( const NSBitmapImageRep &a ); + + int samplesPerPixel( void ); + int pixelsWide( void ); + int pixelsHigh( void ); + byte * bitmapData( void ); + bool hasAlpha( void ); + bool isPlanar( void ); + +private: + + byte * bmap; + int width; + int height; + ID_TIME_T timestamp; + +}; + +class roq { +public: + roq(); + ~roq(); + + void WriteLossless( void ); + void LoadAndDisplayImage( const char *filename ); + void CloseRoQFile( bool which ); + void InitRoQFile( const char *roqFilename ); + void InitRoQPatterns( void ); + void EncodeStream( const char *paramInputFile ); + void EncodeQuietly( bool which ); + bool IsQuiet( void ); + bool IsLastFrame( void ); + NSBitmapImageRep * CurrentImage( void ); + void MarkQuadx( int xat, int yat, int size, float cerror, int choice ); + void WritePuzzleFrame( quadcel *pquad ); + void WriteFrame( quadcel *pquad ); + void WriteCodeBook( byte *codebook ); + void WwriteCodeBookToStream( byte *codes, int csize, word cflags ); + int PreviousFrameSize( void ); + bool MakingVideo( void ); + bool ParamNoAlpha( void ); + bool SearchType( void ); + bool HasSound( void ); + const char * CurrentFilename( void ); + int NormalFrameSize( void ); + int FirstFrameSize( void ); + bool Scaleable( void ); + void WriteHangFrame( void ); + int NumberOfFrames( void ); +private: + void Write16Word( word *aWord, idFile *stream ); + void Write32Word( unsigned int *aWord, idFile *stream ); + int SizeFile( idFile *ftosize ); + void CloseRoQFile( void ); + void WriteCodeBookToStream( byte *codebook, int csize, word cflags ); + + static void JPEGInitDestination( j_compress_ptr cinfo ); + static boolean JPEGEmptyOutputBuffer( j_compress_ptr cinfo ); + static void JPEGTermDestination( j_compress_ptr cinfo ); + + void JPEGStartCompress( j_compress_ptr cinfo, bool write_all_tables ); + JDIMENSION JPEGWriteScanlines( j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines ); + void JPEGDest( j_compress_ptr cinfo, byte* outfile, int size ); + void JPEGSave( char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer ); + + codec * encoder; + roqParam * paramFile; + + idFile * RoQFile; + NSBitmapImageRep * image; + int numQuadCels; + bool quietMode; + bool lastFrame; + idStr roqOutfile; + idStr currentFile; + int numberOfFrames; + int previousSize; + byte codes[4096]; + bool dataStuff; + +}; + +extern roq *theRoQ; // current roq + +#endif /* !__roq_h__ */ diff --git a/tools/compilers/roqvq/roq.m b/tools/compilers/roqvq/roq.m new file mode 100644 index 000000000..196be4f4a --- /dev/null +++ b/tools/compilers/roqvq/roq.m @@ -0,0 +1,933 @@ + +#import "roq.h" +#import "codec.h" + +#ifdef __MACOS__ + +blah + +#endif + +@implementation roq + + +- init +{ + cWindow = eWindow = sWindow = 0; + image = 0; + quietMode = NO; + encoder = 0; + previousSize = 0; + lastFrame = NO; + codes = malloc( 4*1024 ); + dataStuff=NO; + return self; +} + +- (void)dealloc +{ + free( codes ); + + if (image) [image dealloc]; + if (encoder) [encoder dealloc]; + return; +} + +- encodeQuietly:(BOOL)which +{ + quietMode = which; + return self; +} + +- (BOOL)isQuiet +{ + return quietMode; +} + +- (BOOL)isLastFrame +{ + return lastFrame; +} + +- (BOOL)scaleable +{ + return [paramFileId isScaleable]; +} + +- (BOOL)paramNoAlpha +{ + return [paramFileId noAlpha]; +} + +- (BOOL)makingVideo +{ + return YES; //[paramFileId timecode]; +} + +- (BOOL)searchType +{ + return [paramFileId searchType]; +} + +- (BOOL)hasSound +{ + return [paramFileId hasSound]; +} + +- (int)previousFrameSize +{ + return previousSize; +} + +-(int)firstFrameSize +{ + return [paramFileId firstFrameSize]; +} + +-(int)normalFrameSize +{ + return [paramFileId normalFrameSize]; +} + +- (char *)currentFilename +{ + return currentFile; +} + +-encodeStream: (id)paramInputFile +{ +int onFrame; +char f0[MAXPATHLEN], f1[MAXPATHLEN], f2[MAXPATHLEN]; +int morestuff; + + onFrame = 1; + + encoder = [[codec alloc] init: self]; + numberOfFrames = [paramInputFile numberOfFrames]; + paramFileId = paramInputFile; + + if ([paramInputFile noAlpha]==YES) printf("encodeStream: eluding alpha\n"); + + f0[0] = 0; + strcpy( f1, [paramInputFile getNextImageFilename]); + if (( [paramInputFile moreFrames] == YES )) strcpy( f2, [paramInputFile getNextImageFilename]); + morestuff = numberOfFrames; + + while( morestuff ) { + [self loadAndDisplayImage: f1]; + + if (onFrame==1 && ([image hadAlpha]==NO || [paramInputFile noAlpha]==YES) && ![self makingVideo] && ![self scaleable]) { + [encoder sparseEncode: self]; +// [self writeLossless]; + } else { + if (!strcmp( f0, f1 ) && strcmp( f1, f2) ) { + [self writeHangFrame]; + } else { + [encoder sparseEncode: self]; + } + } + + onFrame++; + strcpy( f0, f1 ); + strcpy( f1, f2 ); + if ([paramInputFile moreFrames] == YES) strcpy( f2, [paramInputFile getNextImageFilename]); + morestuff--; + } + + if (numberOfFrames != 1) { + if ([image hadAlpha] && [paramInputFile noAlpha]==NO) { + lastFrame = YES; + [encoder sparseEncode: self]; + } else { + [self writeLossless]; + } + } + return self; +} + +- write16Word:(word *)aWord to:(FILE *)stream +{ + byte a, b; + + a = *aWord & 0xff; + b = *aWord >> 8; + + fputc( a, stream ); + fputc( b, stream ); + + return self; +} + +- write32Word:( unsigned int *)aWord to:(FILE *)stream +{ + byte a, b, c, d; + + a = *aWord & 0xff; + b = (*aWord >> 8) & 0xff; + c = (*aWord >> 16) & 0xff; + d = (*aWord >> 24) & 0xff; + + fputc( a, stream ); + fputc( b, stream ); + fputc( c, stream ); + fputc( d, stream ); + return self; +} + +-(int)sizeFile:(FILE *)ftosize; +{ + long int fat, fend; + fat = ftell(ftosize); + fseek( ftosize, 0, SEEK_END ); + fend = ftell(ftosize); + fseek( ftosize, fat, SEEK_SET); + return (fend); +} + +- convertPlanertoPacked +{ +byte *iPlane[5], *newdata, *olddata; +int x,y,index, sample, pixelsWide, pixelsHigh; +TByteBitmapImageRep *newImage; + + pixelsWide = [image pixelsWide]; + pixelsHigh = [image pixelsHigh]; + + printf("convertPlanertoPacked: converting\n"); + + newImage = [[TByteBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + pixelsWide: pixelsWide + pixelsHigh: pixelsHigh + bitsPerSample: 8 + samplesPerPixel: 4 + hasAlpha: YES + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: 0 + bitsPerPixel: 0]; + + newdata = [newImage bitmapData]; + index = 0; + + if ([image isPlanar]) { + [image getBitmapDataPlanes: iPlane]; + for(y=0;y> 8 )) - 128 - dxMean + 8; + dy = ((pquad[i].domain & 0xff)) - 128 - dyMean + 8; + if (dx>15 || dx<0 || dy>15 || dy<0 ) { + printf("writeFrame: FCC error %d,%d mean %d,%d at %d,%d,%d rmse %f\n", dx,dy, dxMean, dyMean,pquad[i].xat,pquad[i].yat,pquad[i].size, pquad[i].snr[FCC] ); + exit(1); + } + cccList[onCCC++] = (dx<<4)+dy; + break; + case PAT: + code = 2; + cccList[onCCC++] = index4[pquad[i].patten[0]]; + break; + case CCC: + code = 3; + cccList[onCCC++] = index2[pquad[i].patten[1]]; + cccList[onCCC++] = index2[pquad[i].patten[2]]; + cccList[onCCC++] = index2[pquad[i].patten[3]]; + cccList[onCCC++] = index2[pquad[i].patten[4]]; + break; + case DEAD: + fprintf(stderr,"dead cels in picture\n"); + break; + } + if (code == -1) { + fprintf(stderr, "writeFrame: an error occurred writing the frame\n"); + exit(2); + } + + action = (action<<2)|code; + j++; + if (j == 8) { + j = 0; + cccList[onAction+0] = (action & 0xff); + cccList[onAction+1] = ((action >> 8) & 0xff); + onAction = onCCC; + onCCC += 2; + } + } + } + + if (j) { + action <<= ((8-j)*2); + cccList[onAction+0] = (action & 0xff); + cccList[onAction+1] = ((action >> 8) & 0xff); + } + + direct = RoQ_QUAD_VQ; + + [self write16Word: &direct to: RoQFile]; + + j = onCCC; + [self write32Word: &j to: RoQFile]; + + direct = dyMean; + direct &= 0xff; + direct += (dxMean<<8); // flags + + [self write16Word: &direct to: RoQFile]; + + printf("writeFrame: outputting %d bytes to RoQ_QUAD_VQ\n", j); + + previousSize = j; + + fwrite( cccList, onCCC, 1, RoQFile ); + + fflush( RoQFile ); + + free( cccList ); + free( use2 ); + free( use4 ); + + return self; +} + +- writePuzzleFrame:(quadcel *)pquad +{ + return self; +} + +- (TByteBitmapImageRep *)scaleImage: (TByteBitmapImageRep *)toscale +{ +int newx, newy,x,y,s,linesize; +TByteBitmapImageRep *newImage; +unsigned char *i0, *i1; +int newv; + + newx = 288; + + if ([toscale pixelsHigh] == 160) { + newy = 320; + } else { + newy = [toscale pixelsHigh]; + } + newImage = [[TByteBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + pixelsWide: newx + pixelsHigh: newy + bitsPerSample: 8 + samplesPerPixel: 4 + hasAlpha: YES + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: 0 + bitsPerPixel: 0]; + + i0 = [toscale bitmapData]; + i1 = [newImage bitmapData]; + linesize = [toscale pixelsWide]*4; + + for(y=0; y=16 && x<304) { + for(s=0;s<4;s++) { + if ([toscale pixelsHigh] == 160) { + newv = i0[(x*2+0)*4+(y>>1)*linesize+s]; + newv += i0[(x*2+1)*4+(y>>1)*linesize+s]; + newv += i0[(x*2+0)*4+((y>>1)+1)*linesize+s]; + newv += i0[(x*2+1)*4+((y>>1)+1)*linesize+s]; + newv = newv/4; + } else { + newv = i0[(x*2+0)*4+y*linesize+s]; + newv += i0[(x*2+1)*4+y*linesize+s]; + newv = newv/2; + } + i1[(x-16)*4+y*(288*4)+s] = newv; + } + } + } + } + return (newImage); +} + +// +// load a frame, create a window (if neccesary) and display the frame +// +- loadAndDisplayImage: (const char *) filename +{ +NSRect cRect; +char *secondFilename,firstFilename[MAXPATHLEN+1]; +id image1; +NSSize newSize; +// unsigned char *imageData; +// static BOOL cleared = NO; + + if (image) [image dealloc]; + + printf("loadAndDisplayImage: %s\n", filename); + + strcpy( currentFile, filename ); + + image = [TByteBitmapImageRep alloc]; + if (!(secondFilename= strchr(filename,'\n'))) { //one filename, no compositing + [image initFromFile: filename ]; + } + else { + strncpy(firstFilename,filename,secondFilename-filename); + firstFilename[secondFilename-filename]='\0'; + secondFilename++;//point past the \n + image1 = [[TByteBitmapImageRep alloc] initFromFile:firstFilename]; + [image initFromFile: secondFilename ];//result will be in here + //image is the composite of those two... + [self composite:image1 to:image]; + } +// +// wolf stuff +// + newSize.width = 256; + newSize.height = 256; + + [image setSize: newSize]; + + if ([paramFileId output3DO] == YES) { + image1 = [self scaleImage: image]; + [image dealloc]; + image = image1; + } + + numQuadCels = (([image pixelsWide] & 0xfff0)*([image pixelsHigh] & 0xfff0))/(MINSIZE*MINSIZE); + numQuadCels += numQuadCels/4 + numQuadCels/16; + +// if ([paramFileId deltaFrames] == YES && cleared == NO && [image isPlanar] == NO) { +// cleared = YES; +// imageData = [image data]; +// memset( imageData, 0, [image pixelsWide]*[image pixelsHigh]*[image samplesPerPixel]); +// } + + if (!quietMode) printf("loadAndDisplayImage: %dx%d\n", [image pixelsWide], [image pixelsHigh]); + + if (!quietMode) { + if (!cWindow) { + cRect.origin.x = 8.0 * 48.0; + cRect.origin.y = ([image pixelsHigh]+80); + cRect.size.width = [image pixelsWide]; + cRect.size.height = [image pixelsHigh]; + cWindow = [[NSWindow alloc] initWithContentRect:cRect styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered defer:NO]; + cRect.origin.x = cRect.origin.y = 0.0; +// [[cWindow contentView] setClipping:NO]; + [cWindow setTitle: @"current frame"]; + [cWindow makeKeyAndOrderFront: [cWindow contentView]]; + [cWindow display]; + } + + + cRect = [[cWindow contentView] bounds]; + [[cWindow contentView] lockFocus]; + [image drawInRect: cRect]; + [[cWindow contentView] unlockFocus]; + [cWindow flushWindow]; + + if (!eWindow) { + cRect.origin.x = 8.0 * 48.0 - ([image pixelsWide]>>1) - 4; + cRect.origin.y = ([image pixelsHigh]+80); + cRect.size.width = [image pixelsWide] >> 1; + cRect.size.height = [image pixelsHigh] >> 1; + eWindow = [[NSWindow alloc] initWithContentRect:cRect styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered defer:NO]; + cRect.origin.x = cRect.origin.y = 0.0; +// [[eWindow contentView] setClipping:NO]; + [eWindow setTitle: @"cel error"]; + [eWindow makeKeyAndOrderFront: [eWindow contentView]]; + [eWindow display]; + } + + if (!sWindow) { + cRect.origin.x = 8.0 * 48.0 - ([image pixelsWide]>>1) - 4; + cRect.origin.y = ([image pixelsHigh]+80) + (([image pixelsHigh]+48)>>1); + cRect.size.width = [image pixelsWide] >> 1; + cRect.size.height = [image pixelsHigh] >> 1; + sWindow = [[NSWindow alloc] initWithContentRect: cRect styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered defer:NO]; + cRect.origin.x = cRect.origin.y = 0.0; +// [[eWindow contentView] setClipping:NO]; + [sWindow setTitle: @"quadtree map"]; + [sWindow makeKeyAndOrderFront: [sWindow contentView]]; + [sWindow display]; + } + + cRect = [[sWindow contentView] bounds]; + [[sWindow contentView] lockFocus]; + [image drawInRect: cRect]; + [[sWindow contentView] unlockFocus]; + [sWindow flushWindow]; + + cRect = [[eWindow contentView] bounds]; + [[eWindow contentView] lockFocus]; + [image drawInRect: cRect]; + [[eWindow contentView] unlockFocus]; + [eWindow flushWindow]; + + if (!errImage) { + errImage = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + pixelsWide: 1 + pixelsHigh: 1 + bitsPerSample: 8 + samplesPerPixel: 3 + hasAlpha: NO + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: 0 + bitsPerPixel: 0]; + } + +// NSPing(); + } + + return self; +} + + +- markQuadx: (int)xat quady: (int)yat quads: (int)size error: (float)cerror type: (int)choice +{ +NSRect cRect; +byte *err; +static int ywasat = -1; + if (!quietMode) { + cRect.origin.x = (xat)>>1; + cRect.origin.y = ([image pixelsHigh] - yat - size)>>1; + cRect.size.width = cRect.size.height = (size)>>1; + + if (size < 1) { + [[sWindow contentView] lockFocus]; + if (size == 8 && choice == 1) { + PSsetgray(NSWhite); + } else if (size == 8 && choice == 3) { + PSsetgray(NSLightGray); + } else if (size == 4) { + PSsetgray(NSDarkGray); + } else if (size == 2) { + PSsetgray(NSBlack); + } + NSFrameRectWithWidth(cRect,0.0); + [[sWindow contentView] unlockFocus]; + if (!(ywasat & 31)) { + [sWindow flushWindow]; + } + } + + err = [errImage bitmapData]; + err[0] = err[1] = err[2] = 0; + if ( cerror > 31 ) cerror = 31; + if (choice & 1) err[0] = (int)cerror*8; + if (choice & 2) err[1] = (int)cerror*8; + if (choice & 4) err[2] = (int)cerror*8; + + [[eWindow contentView] lockFocus]; + [errImage drawInRect: cRect]; + [[eWindow contentView] unlockFocus]; + if (!(ywasat & 31)) { + [eWindow flushWindow]; + } + ywasat++; + } + + return self; +} + +- (NSBitmapImageRep*)currentImage +{ + return image; +} + +- (id)errorWindow +{ + return eWindow; +} + +- (id)scaleWindow +{ + return sWindow; +} +- (int)numberOfFrames { + return numberOfFrames; +} + +- composite:(NSBitmapImageRep *)source to: (NSBitmapImageRep *)destination +{ +unsigned short value; +int x,y,bpp,inc,pixelsWide,pixelsHigh,yoff,pixel; +byte *iPlane[5], *dPlane[5]; + + bpp = [source samplesPerPixel]; + pixelsWide = [source pixelsWide]; + pixelsHigh = [source pixelsHigh]; + + if ([source isPlanar]) { + [source getBitmapDataPlanes: iPlane]; + [destination getBitmapDataPlanes: dPlane]; + for(y=0;ydPlane[3][yoff+x]) dPlane[3][yoff+x] = iPlane[3][yoff+x]; + } + } + } + } + } else { + iPlane[0] = [source bitmapData]; + dPlane[0] = [destination bitmapData]; + for(y=0;ydPlane[0][yoff+inc+3]) dPlane[0][yoff+inc+3] = iPlane[0][yoff+inc+3]; + } + } + } + } + } + + return self; + + +} +@end diff --git a/tools/compilers/roqvq/roqParam.cpp b/tools/compilers/roqvq/roqParam.cpp new file mode 100644 index 000000000..1f93dbf2a --- /dev/null +++ b/tools/compilers/roqvq/roqParam.cpp @@ -0,0 +1,626 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "roqParam.h" + +// +// read a parameter file in (true I bloddy well had to do this again) (and yet again to c++) +// + +int parseRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ); +int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ); + +void roqParam::InitFromFile( const char *fileName ) +{ + idParser *src; + idToken token; + int i, readarg; + + + src = new idParser( fileName, LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + if ( !src->IsLoaded() ) { + delete src; + common->Printf("Error: can't open param file %s\n", fileName); + return; + } + + common->Printf("initFromFile: %s\n", fileName); + + fullSearch = false; + scaleDown = false; + encodeVideo = false; + addPath = false; + screenShots = false; + startPalette = false; + endPalette = false; + fixedPalette = false; + keyColor = false; + justDelta = false; + useTimecodeForRange = false; + onFrame = 0; + numInputFiles = 0; + currentPath[0] = '\0'; + make3DO = false; + makeVectors = false; + justDeltaFlag = false; + noAlphaAtAll = false; + twentyFourToThirty = false; + hasSound = false; + isScaleable = false; + firstframesize = 56*1024; + normalframesize = 20000; + jpegDefault = 85; + + realnum = 0; + while( 1 ) { + if ( !src->ReadToken( &token ) ) { + break; + } + + readarg = 0; +// input dir + if (token.Icmp( "input_dir") == 0) { + src->ReadToken( &token ); + addPath = true; + currentPath = token; +// common->Printf(" + input directory is %s\n", currentPath ); + readarg++; + continue; + } +// input dir + if (token.Icmp( "scale_down") == 0) { + scaleDown = true; +// common->Printf(" + scaling down input\n" ); + readarg++; + continue; + } +// full search + if (token.Icmp( "fullsearch") == 0) { + normalframesize += normalframesize/2; + fullSearch = true; + readarg++; + continue; + } +// scaleable + if (token.Icmp( "scaleable") == 0) { + isScaleable = true; + readarg++; + continue; + } +// input dir + if (token.Icmp( "no_alpha") == 0) { + noAlphaAtAll = true; +// common->Printf(" + scaling down input\n" ); + readarg++; + continue; + } + if (token.Icmp( "24_fps_in_30_fps_out") == 0) { + twentyFourToThirty = true; + readarg++; + continue; + } +// video in + if (token.Icmp( "video_in") == 0) { + encodeVideo = true; +// common->Printf(" + Using the video port as input\n"); + continue; + } +//timecode range + if (token.Icmp( "timecode") == 0) { + useTimecodeForRange = true; + firstframesize = 12*1024; + normalframesize = 4500; +// common->Printf(" + Using timecode as range\n"); + continue; + } +// soundfile for making a .RnR + if (token.Icmp( "sound") == 0) { + src->ReadToken( &token ); + soundfile = token; + hasSound = true; +// common->Printf(" + Using timecode as range\n"); + continue; + } +// soundfile for making a .RnR + if (token.Icmp( "has_sound") == 0) { + hasSound = true; + continue; + } +// outfile + if (token.Icmp( "filename") == 0) { + src->ReadToken( &token ); + outputFilename = token; + i = strlen(outputFilename); +// common->Printf(" + output file is %s\n", outputFilename ); + readarg++; + continue; + } +// starting palette + if (token.Icmp( "start_palette") == 0) { + src->ReadToken( &token ); + sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); +// common->Error(" + starting palette is %s\n", startPal ); + startPalette = true; + readarg++; + continue; + } +// ending palette + if (token.Icmp( "end_palette") == 0) { + src->ReadToken( &token ); + sprintf(endPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); +// common->Printf(" + ending palette is %s\n", endPal ); + endPalette = true; + readarg++; + continue; + } +// fixed palette + if (token.Icmp( "fixed_palette") == 0) { + src->ReadToken( &token ); + sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); +// common->Printf(" + fixed palette is %s\n", startPal ); + fixedPalette = true; + readarg++; + continue; + } +// these are screen shots + if (token.Icmp( "screenshot") == 0) { +// common->Printf(" + shooting screen shots\n" ); + screenShots = true; + readarg++; + continue; + } +// key_color r g b + if (token.Icmp( "key_color") == 0) { + keyR = src->ParseInt(); + keyG = src->ParseInt(); + keyB = src->ParseInt(); + keyColor = true; +// common->Printf(" + key color is %03d %03d %03d\n", keyR, keyG, keyB ); + readarg++; + continue; + } +// only want deltas + if (token.Icmp( "just_delta") == 0) { +// common->Printf(" + outputting deltas in the night\n" ); +// justDelta = true; +// justDeltaFlag = true; + readarg++; + continue; + } +// doing 3DO + if (token.Icmp( "3DO") == 0) { + make3DO = true; + readarg++; + continue; + } +// makes codebook vector tables + if (token.Icmp( "codebook") == 0) { + makeVectors = true; + readarg++; + continue; + } +// set first frame size + if (token.Icmp( "firstframesize") == 0) { + firstframesize = src->ParseInt(); + readarg++; + continue; + } +// set normal frame size + if (token.Icmp( "normalframesize") == 0) { + normalframesize = src->ParseInt(); + readarg++; + continue; + } +// set normal frame size + if (token.Icmp( "stillframequality") == 0) { + jpegDefault = src->ParseInt(); + readarg++; + continue; + } + if (token.Icmp( "input") == 0) { + int num_files = 255; + + range = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + padding = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) ); + padding2 = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) ); + skipnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + skipnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + startnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + startnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + endnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + endnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + numpadding = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + numpadding2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + numfiles = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); + idStr empty; + file.AssureSize( num_files, empty ); + file.AssureSize( num_files, empty ); + + field = 0; + realnum = 0; + do { + src->ReadToken(&token); + if ( token.Icmp( "end_input") != 0 ) { + idStr arg1, arg2, arg3; + + file[field] = token; + while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { + file[field].Append( token ); + } + + arg1 = token; + while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { + arg1 += token; + } + + arg2 = token; + while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { + arg2 += token; + } + + arg3 = token; + while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { + arg3 += token; + } + + if ( arg1[0] != '[' ) { +// common->Printf(" + reading %s\n", file[field] ); + range[field] = 0; + numfiles[field] = 1; + realnum++; + } + else { + if ( arg1[0] == '[' ) + { + range[field] = 1; + if (useTimecodeForRange) { + realnum += parseTimecodeRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding); +// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); + } + else { + realnum += parseRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding); +// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); + } + } + else if (( arg1[0] != '[' ) && ( arg2[0] == '[') && ( arg3[0] =='[')) { //a double ranger... + int files1,files2; + + file2[field] = arg1; + range[field] = 2; + files1 = parseRange(arg2, field, skipnum, startnum, endnum, numfiles, padding, numpadding); +// common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); + files2 = parseRange(arg3, field, skipnum2, startnum2, endnum2, numfiles, padding2, numpadding2); +// common->Printf(" + reading %s from %d to %d\n", file2[field], startnum2[field], endnum2[field]); + if (files1 != files2) { + common->Error( "You had %d files for %s and %d for %s!", files1, arg1.c_str(), files2, arg2.c_str() ); + } + else { + realnum += files1;//not both, they are parallel + } + } + else { + common->Error("Error: invalid range on open (%s %s %s)\n", arg1.c_str(), arg2.c_str(), arg3.c_str() ); + } + } + field++; + } + } while (token.Icmp( "end_input")); + } + } + + if (TwentyFourToThirty()) realnum = realnum+(realnum>>2); + numInputFiles = realnum; + common->Printf(" + reading a total of %d frames in %s\n", numInputFiles, currentPath.c_str() ); + delete src; +} + +void roqParam::GetNthInputFileName( idStr &fileName, int n ) { + int i, myfield, index,hrs,mins,secs,frs; + char tempfile[33], left[256], right[256], *strp; + if ( n > realnum ) n = realnum; +// overcome starting at zero by ++ing and then --ing. + if (TwentyFourToThirty()) { n++; n = (n/5) * 4 + (n % 5); n--; } + + i = 0; + myfield = 0; + + while (i <= n) { + i += numfiles[myfield++]; + } + myfield--; + i -= numfiles[myfield]; + + if ( range[myfield] == 1 ) { + + strcpy( left, file[myfield] ); + strp = strstr( left, "*" ); + *strp++ = 0; + sprintf(right, "%s", strp); + + if ( startnum[myfield] <= endnum[myfield] ) { + index = startnum[myfield] + ((n-i)*skipnum[myfield]); + } else { + index = startnum[myfield] - ((n-i)*skipnum[myfield]); + } + + if ( padding[myfield] == true ) { + if (useTimecodeForRange) { + hrs = index/(30*60*60) ; + mins = (index/(30*60)) %60; + secs = (index/(30)) % 60; + frs = index % 30; + sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right); + } + else { + sprintf(tempfile, "%032d", index ); + sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right ); + } + } else { + if (useTimecodeForRange) { + hrs = index/(30*60*60) ; + mins = (index/(30*60)) %60; + secs = (index/(30)) % 60; + frs = index % 30; + sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right); + } + else { + sprintf(fileName, "%s%d%s", left, index, right ); + } + } + } else if ( range[myfield] == 2 ) { + + strcpy( left, file[myfield] ); + strp = strstr( left, "*" ); + *strp++ = 0; + sprintf(right, "%s", strp); + + if ( startnum[myfield] <= endnum[myfield] ) { + index = startnum[myfield] + ((n-i)*skipnum[myfield]); + } else { + index = startnum[myfield] - ((n-i)*skipnum[myfield]); + } + + if ( padding[myfield] == true ) { + sprintf(tempfile, "%032d", index ); + sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right ); + } else { + sprintf(fileName, "%s%d%s", left, index, right ); + } + + strcpy( left, file2[myfield] ); + strp = strstr( left, "*" ); + *strp++ = 0; + sprintf(right, "%s", strp); + + if ( startnum2[myfield] <= endnum2[myfield] ) { + index = startnum2[myfield] + ((n-i)*skipnum2[myfield]); + } else { + index = startnum2[myfield] - ((n-i)*skipnum2[myfield]); + } + + if ( padding2[myfield] == true ) { + sprintf(tempfile, "%032d", index ); + fileName += va( "\n%s%s%s", left, &tempfile[ 32-numpadding2[myfield] ], right ); + } else { + fileName += va( "\n%s%d%s", left, index, right ); + } + } else { + fileName = file[myfield]; + } +} + +const char* roqParam::GetNextImageFilename( void ) { + idStr tempBuffer; + int i; + int len; + + GetNthInputFileName( tempBuffer, onFrame++); + if ( justDeltaFlag == true ) { + onFrame--; + justDeltaFlag = false; + } + + if ( addPath == true ) { + currentFile = currentPath + "/" + tempBuffer; + } else { + currentFile = tempBuffer; + } + len = currentFile.Length(); + for(i=0;i= '0' && rangeStr[i] <= '9' ); + *stptr = '\0'; + if ( rangeStr[i++] != '-' ) { + common->Error("Error: invalid range on middle \n"); + } + do { + *enptr++ = rangeStr[i++]; + } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); + *enptr = '\0'; + if ( rangeStr[i] != ']' ) { + if ( rangeStr[i++] != '+' ) { + common->Error("Error: invalid range on close\n"); + } + do { + *skptr++ = rangeStr[i++]; + } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); + *skptr = '\0'; + skipnum[field] = atoi( skip ); + } else { + skipnum[field] = 1; + } + startnum[field] = atoi( start ); + endnum[field] = atoi( end ); + numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1; + realnum += numfiles[field]; + if ( start[0] == '0' && start[1] != '\0' ) { + padding[field] = true; + numpadding[field] = strlen( start ); + } else { + padding[field] = false; + } + return realnum; +} + +int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ) +{ + char start[64], end[64], skip[64]; + char *stptr, *enptr, *skptr; + int i,realnum,hrs,mins,secs,frs; + + i = 1;//skip the '[' + realnum = 0; + stptr = start; + enptr = end; + skptr = skip; + do { + *stptr++ = rangeStr[i++]; + } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); + *stptr = '\0'; + if ( rangeStr[i++] != '-' ) { + common->Error("Error: invalid range on middle \n"); + } + do { + *enptr++ = rangeStr[i++]; + } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); + *enptr = '\0'; + if ( rangeStr[i] != ']' ) { + if ( rangeStr[i++] != '+' ) { + common->Error("Error: invalid range on close\n"); + } + do { + *skptr++ = rangeStr[i++]; + } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); + *skptr = '\0'; + skipnum[field] = atoi( skip ); + } else { + skipnum[field] = 1; + } + sscanf(start,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs); + startnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs; + sscanf(end,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs); + endnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs; + numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1; + realnum += numfiles[field]; + if ( start[0] == '0' && start[1] != '\0' ) { + padding[field] = true; + numpadding[field] = strlen( start ); + } else { + padding[field] = false; + } + return realnum; +} diff --git a/tools/compilers/roqvq/roqParam.h b/tools/compilers/roqvq/roqParam.h new file mode 100644 index 000000000..8728dcc86 --- /dev/null +++ b/tools/compilers/roqvq/roqParam.h @@ -0,0 +1,96 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __roqParam_h__ +#define __roqParam_h__ + +#include "gdefs.h" +#pragma once + +class roqParam +{ +public: + + const char* RoqFilename( void ); + const char* RoqTempFilename( void ); + const char* GetNextImageFilename( void ); + const char* SoundFilename( void ); + void InitFromFile( const char *fileName ); + void GetNthInputFileName( idStr &fileName, int n); + bool MoreFrames( void ); + bool OutputVectors( void ); + bool Timecode( void ); + bool DeltaFrames( void ); + bool NoAlpha( void ); + bool SearchType( void ); + bool TwentyFourToThirty( void ); + bool HasSound( void ); + int NumberOfFrames( void ); + int NormalFrameSize( void ); + int FirstFrameSize( void ); + int JpegQuality( void ); + bool IsScaleable( void ); + + idStr outputFilename; + int numInputFiles; +private: + int *range; + bool *padding, *padding2; + idStrList file; + idStrList file2; + idStr soundfile; + idStr currentPath; + idStr tempFilename; + idStr startPal; + idStr endPal; + idStr currentFile; + int *skipnum, *skipnum2; + int *startnum, *startnum2; + int *endnum, *endnum2; + int *numpadding, *numpadding2; + int *numfiles; + byte keyR, keyG, keyB; + int field; + int realnum; + int onFrame; + int firstframesize; + int normalframesize; + int jpegDefault; + + bool scaleDown; + bool twentyFourToThirty; + bool encodeVideo; + bool useTimecodeForRange; + bool addPath; + bool screenShots; + bool startPalette; + bool endPalette; + bool fixedPalette; + bool keyColor; + bool justDelta; + bool make3DO; + bool makeVectors; + bool justDeltaFlag; + bool noAlphaAtAll; + bool fullSearch; + bool hasSound; + bool isScaleable; +}; + + +#endif // roqParam diff --git a/tools/debugger/DebuggerApp.cpp b/tools/debugger/DebuggerApp.cpp new file mode 100644 index 000000000..ce1107cea --- /dev/null +++ b/tools/debugger/DebuggerApp.cpp @@ -0,0 +1,157 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/debugger_resource.h" +#include "DebuggerApp.h" + +/* +================ +rvDebuggerApp::rvDebuggerApp +================ +*/ +rvDebuggerApp::rvDebuggerApp ( ) : + mOptions ( "Software\\id Software\\DOOM3\\Tools\\Debugger" ) +{ + mInstance = NULL; + mDebuggerWindow = NULL; + mAccelerators = NULL; +} + +/* +================ +rvDebuggerApp::~rvDebuggerApp +================ +*/ +rvDebuggerApp::~rvDebuggerApp ( ) +{ + if ( mAccelerators ) + { + DestroyAcceleratorTable ( mAccelerators ); + } +} + +/* +================ +rvDebuggerApp::Initialize + +Initializes the debugger application by creating the debugger window +================ +*/ +bool rvDebuggerApp::Initialize ( HINSTANCE instance ) +{ + INITCOMMONCONTROLSEX ex; + ex.dwICC = ICC_USEREX_CLASSES | ICC_LISTVIEW_CLASSES | ICC_WIN95_CLASSES; + ex.dwSize = sizeof(INITCOMMONCONTROLSEX); + + mInstance = instance; + + mOptions.Load ( ); + + mDebuggerWindow = new rvDebuggerWindow; + + if ( !mDebuggerWindow->Create ( instance ) ) + { + delete mDebuggerWindow; + return false; + } + + // Initialize the network connection for the debugger + if ( !mClient.Initialize ( ) ) + { + return false; + } + + mAccelerators = LoadAccelerators ( mInstance, MAKEINTRESOURCE(IDR_DBG_ACCELERATORS) ); + + return true; +} + +/* +================ +rvDebuggerApp::ProcessWindowMessages + +Process windows messages +================ +*/ +bool rvDebuggerApp::ProcessWindowMessages ( void ) +{ + MSG msg; + + while ( PeekMessage ( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + if ( !GetMessage (&msg, NULL, 0, 0) ) + { + return false; + } + + if ( !TranslateAccelerator ( &msg ) ) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return true; +} + +/* +================ +rvDebuggerApp::TranslateAccelerator + +Translate any accelerators destined for this window +================ +*/ +bool rvDebuggerApp::TranslateAccelerator ( LPMSG msg ) +{ + if ( mDebuggerWindow && ::TranslateAccelerator ( mDebuggerWindow->GetWindow(), mAccelerators, msg ) ) + { + return true; + } + + return false; +} + +/* +================ +rvDebuggerApp::Run + +Main Loop for the debugger application +================ +*/ +int rvDebuggerApp::Run ( void ) +{ + // Main message loop: + while ( ProcessWindowMessages ( ) ) + { + mClient.ProcessMessages ( ); + + Sleep ( 0 ); + } + + mClient.Shutdown ( ); + mOptions.Save ( ); + + delete mDebuggerWindow; + + return 1; +} + diff --git a/tools/debugger/DebuggerApp.h b/tools/debugger/DebuggerApp.h new file mode 100644 index 000000000..47cf371e4 --- /dev/null +++ b/tools/debugger/DebuggerApp.h @@ -0,0 +1,99 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERAPP_H_ +#define DEBUGGERAPP_H_ + +#include "../../sys/win32/win_local.h" +#include "../../framework/sync/Msg.h" + +#ifndef REGISTRYOPTIONS_H_ +#include "../common/RegistryOptions.h" +#endif + +#ifndef DEBUGGERWINDOW_H_ +#include "DebuggerWindow.h" +#endif + +#ifndef DEBUGGERMESSAGES_H_ +#include "DebuggerMessages.h" +#endif + +#ifndef DEBUGGERCLIENT_H_ +#include "DebuggerClient.h" +#endif + +// These were changed to static by ID so to make it easy we just throw them +// in this header +const int MAX_MSGLEN = 1400; + +class rvDebuggerApp +{ +public: + + rvDebuggerApp ( ); + + bool Initialize ( HINSTANCE hInstance ); + int Run ( void ); + + rvRegistryOptions& GetOptions ( void ); + rvDebuggerClient& GetClient ( void ); + rvDebuggerWindow& GetWindow ( void ); + + HINSTANCE GetInstance ( void ); + + bool TranslateAccelerator ( LPMSG msg ); + +protected: + + rvRegistryOptions mOptions; + rvDebuggerWindow* mDebuggerWindow; + HINSTANCE mInstance; + rvDebuggerClient mClient; + HACCEL mAccelerators; + +private: + + bool ProcessNetMessages ( void ); + bool ProcessWindowMessages ( void ); +}; + +ID_INLINE HINSTANCE rvDebuggerApp::GetInstance ( void ) +{ + return mInstance; +} + +ID_INLINE rvDebuggerClient& rvDebuggerApp::GetClient ( void ) +{ + return mClient; +} + +ID_INLINE rvRegistryOptions& rvDebuggerApp::GetOptions ( void ) +{ + return mOptions; +} + +ID_INLINE rvDebuggerWindow& rvDebuggerApp::GetWindow ( void ) +{ + assert ( mDebuggerWindow ); + return *mDebuggerWindow; +} + +extern rvDebuggerApp gDebuggerApp; + +#endif // DEBUGGERAPP_H_ diff --git a/tools/debugger/DebuggerBreakpoint.cpp b/tools/debugger/DebuggerBreakpoint.cpp new file mode 100644 index 000000000..109a98dde --- /dev/null +++ b/tools/debugger/DebuggerBreakpoint.cpp @@ -0,0 +1,53 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "DebuggerApp.h" +#include "DebuggerBreakpoint.h" + +int rvDebuggerBreakpoint::mNextID = 1; + +rvDebuggerBreakpoint::rvDebuggerBreakpoint ( const char* filename, int linenumber, int id ) +{ + mFilename = filename; + mLineNumber = linenumber; + mEnabled = true; + + if ( id == -1 ) + { + mID = mNextID++; + } + else + { + mID = id; + } +} + +rvDebuggerBreakpoint::rvDebuggerBreakpoint ( rvDebuggerBreakpoint& bp ) +{ + mFilename = bp.mFilename; + mEnabled = bp.mEnabled; + mLineNumber = bp.mLineNumber; +} + +rvDebuggerBreakpoint::~rvDebuggerBreakpoint ( void ) +{ +} diff --git a/tools/debugger/DebuggerBreakpoint.h b/tools/debugger/DebuggerBreakpoint.h new file mode 100644 index 000000000..83e1a2ac7 --- /dev/null +++ b/tools/debugger/DebuggerBreakpoint.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERBREAKPOINT_H_ +#define DEBUGGERBREAKPOINT_H_ + +class rvDebuggerBreakpoint +{ +public: + + rvDebuggerBreakpoint ( const char* filename, int linenumber, int id = -1 ); + rvDebuggerBreakpoint ( rvDebuggerBreakpoint& bp ); + ~rvDebuggerBreakpoint ( void ); + + const char* GetFilename ( void ); + int GetLineNumber ( void ); + int GetID ( void ); + +protected: + + bool mEnabled; + int mID; + int mLineNumber; + idStr mFilename; + +private: + + static int mNextID; +}; + +ID_INLINE const char* rvDebuggerBreakpoint::GetFilename ( void ) +{ + return mFilename; +} + +ID_INLINE int rvDebuggerBreakpoint::GetLineNumber ( void ) +{ + return mLineNumber; +} + +ID_INLINE int rvDebuggerBreakpoint::GetID ( void ) +{ + return mID; +} + +#endif // DEBUGGERBREAKPOINT_H_ diff --git a/tools/debugger/DebuggerClient.cpp b/tools/debugger/DebuggerClient.cpp new file mode 100644 index 000000000..3f2daea4c --- /dev/null +++ b/tools/debugger/DebuggerClient.cpp @@ -0,0 +1,577 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "DebuggerApp.h" + +/* +================ +rvDebuggerClient::rvDebuggerClient +================ +*/ +rvDebuggerClient::rvDebuggerClient ( ) +{ + mConnected = false; + mWaitFor = DBMSG_UNKNOWN; +} + +/* +================ +rvDebuggerClient::~rvDebuggerClient +================ +*/ +rvDebuggerClient::~rvDebuggerClient ( ) +{ + ClearBreakpoints ( ); + ClearCallstack ( ); + ClearThreads ( ); +} + +/* +================ +rvDebuggerClient::Initialize + +Initialize the debugger client +================ +*/ +bool rvDebuggerClient::Initialize ( void ) +{ + // Nothing else can run with the debugger + com_editors = EDITOR_DEBUGGER; + + // Initialize the network connection + if ( !mPort.InitForPort ( 27981 ) ) + { + return false; + } + + // Server must be running on the local host on port 28980 + Sys_StringToNetAdr ( "localhost", &mServerAdrt, true ); + mServerAdr.port = 27980; + + // Attempt to let the server know we are here. The server may not be running so this + // message will just get ignored. + SendMessage ( DBMSG_CONNECT ); + + return true; +} + +/* +================ +rvDebuggerClient::Shutdown + +Shutdown the debugger client and let the debugger server +know we are shutting down +================ +*/ +void rvDebuggerClient::Shutdown ( void ) +{ + if ( mConnected ) + { + SendMessage ( DBMSG_DISCONNECT ); + mConnected = false; + } +} + +/* +================ +rvDebuggerClient::ProcessMessages + +Process all incomding messages from the debugger server +================ +*/ +bool rvDebuggerClient::ProcessMessages ( void ) +{ + netadr_t adrFrom; + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + + // Check for pending udp packets on the debugger port + while ( mPort.GetPacket ( adrFrom, msg.data, msg.cursize, msg.maxsize ) ) + { + unsigned short command; + + // Only accept packets from the debugger server for security reasons + if ( !Sys_CompareNetAdrBase ( adrFrom, mServerAdr ) ) + { + continue; + } + + command = (unsigned short) MSG_ReadShort ( &msg ); + + // Is this what we are waiting for? + if ( command == mWaitFor ) + { + mWaitFor = DBMSG_UNKNOWN; + } + + switch ( command ) + { + case DBMSG_CONNECT: + mConnected = true; + SendMessage ( DBMSG_CONNECTED ); + SendBreakpoints ( ); + break; + + case DBMSG_CONNECTED: + mConnected = true; + SendBreakpoints ( ); + break; + + case DBMSG_DISCONNECT: + mConnected = false; + break; + + case DBMSG_BREAK: + HandleBreak ( &msg ); + break; + + // Callstack being send to the client + case DBMSG_INSPECTCALLSTACK: + HandleInspectCallstack ( &msg ); + break; + + // Thread list is being sent to the client + case DBMSG_INSPECTTHREADS: + HandleInspectThreads ( &msg ); + break; + + case DBMSG_INSPECTVARIABLE: + HandleInspectVariable ( &msg ); + break; + } + + // Give the window a chance to process the message + msg.readcount = 0; + msg.bit = 0; + gDebuggerApp.GetWindow().ProcessNetMessage ( &msg ); + } + + return true; +} + +/* +================ +rvDebuggerClient::HandleBreak + +Handle the DBMSG_BREAK message send from the server. This message is handled +by caching the file and linenumber where the break occured. +================ +*/ +void rvDebuggerClient::HandleBreak ( msg_t* msg ) +{ + char filename[MAX_PATH]; + + mBreak = true; + + // Line number + mBreakLineNumber = MSG_ReadLong ( msg ); + + // Filename + MSG_ReadString ( msg, filename, MAX_PATH ); + mBreakFilename = filename; + + // Clear the variables + mVariables.Clear ( ); + + // Request the callstack and threads + SendMessage ( DBMSG_INSPECTCALLSTACK ); + WaitFor ( DBMSG_INSPECTCALLSTACK, 2000 ); + + SendMessage ( DBMSG_INSPECTTHREADS ); + WaitFor ( DBMSG_INSPECTTHREADS, 2000 ); +} + +/* +================ +rvDebuggerClient::InspectVariable + +Instructs the client to inspect the given variable at the given callstack depth. The +variable is inspected by sending a DBMSG_INSPECTVARIABLE message to the server which +will in turn respond back to the client with the variable value +================ +*/ +void rvDebuggerClient::InspectVariable ( const char* name, int callstackDepth ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_INSPECTVARIABLE ); + MSG_WriteShort ( &msg, (short)(mCallstack.Num()-callstackDepth) ); + MSG_WriteString ( &msg, name ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerClient::HandleInspectCallstack + +Handle the message DBMSG_INSPECTCALLSTACK being sent from the server. This message +is handled by adding the callstack entries to a list for later lookup. +================ +*/ +void rvDebuggerClient::HandleInspectCallstack ( msg_t* msg ) +{ + int depth; + + ClearCallstack ( ); + + // Read all of the callstack entries specfied in the message + for ( depth = (short)MSG_ReadShort ( msg ) ; depth > 0; depth -- ) + { + rvDebuggerCallstack* entry = new rvDebuggerCallstack; + + char temp[1024]; + + // Function name + MSG_ReadString ( msg, temp, 1024 ); + entry->mFunction = temp; + + // Filename + MSG_ReadString ( msg, temp, 1024 ); + entry->mFilename = temp; + + // Line Number + entry->mLineNumber = MSG_ReadLong ( msg ); + + // Add to list + mCallstack.Append ( entry ); + } +} + +/* +================ +rvDebuggerClient::HandleInspectThreads + +Handle the message DBMSG_INSPECTTHREADS being sent from the server. This message +is handled by adding the list of threads to a list for later lookup. +================ +*/ +void rvDebuggerClient::HandleInspectThreads ( msg_t* msg ) +{ + int count; + + ClearThreads ( ); + + // Loop over the number of threads in the message + for ( count = (short)MSG_ReadShort ( msg ) ; count > 0; count -- ) + { + rvDebuggerThread* entry = new rvDebuggerThread; + + char temp[1024]; + + // Thread name + MSG_ReadString ( msg, temp, 1024 ); + entry->mName = temp; + + // Thread ID + entry->mID = MSG_ReadLong ( msg ); + + // Thread state + entry->mCurrent = MSG_ReadBits ( msg, 1 ) ? true : false; + entry->mDoneProcessing = MSG_ReadBits ( msg, 1 ) ? true : false; + entry->mWaiting = MSG_ReadBits ( msg, 1 ) ? true : false; + entry->mDying = MSG_ReadBits ( msg, 1 ) ? true : false; + + // Add thread to list + mThreads.Append ( entry ); + } +} + +/* +================ +rvDebuggerClient::HandleInspectVariable + +Handle the message DBMSG_INSPECTVARIABLE being sent from the server. This message +is handled by adding the inspected variable to a dictionary for later lookup +================ +*/ +void rvDebuggerClient::HandleInspectVariable ( msg_t* msg ) +{ + char var[1024]; + char value[1024]; + int callDepth; + + callDepth = (short)MSG_ReadShort ( msg ); + MSG_ReadString ( msg, var, 1024 ); + MSG_ReadString ( msg, value, 1024 ); + + mVariables.Set ( va("%d:%s", mCallstack.Num()-callDepth, var), value ); +} + +/* +================ +rvDebuggerClient::WaitFor + +Waits the given amount of time for the specified message to be received by the +debugger client. +================ +*/ +bool rvDebuggerClient::WaitFor ( EDebuggerMessage msg, int time ) +{ + int start; + + // Cant wait if not connected + if ( !mConnected ) + { + return false; + } + + start = Sys_Milliseconds ( ); + mWaitFor = msg; + + while ( mWaitFor != DBMSG_UNKNOWN && Sys_Milliseconds()-start < time ) + { + ProcessMessages ( ); + Sleep ( 0 ); + } + + if ( mWaitFor != DBMSG_UNKNOWN ) + { + mWaitFor = DBMSG_UNKNOWN; + return false; + } + + return true; +} + +/* +================ +rvDebuggerClient::FindBreakpoint + +Searches for a breakpoint that maches the given filename and linenumber +================ +*/ +rvDebuggerBreakpoint* rvDebuggerClient::FindBreakpoint ( const char* filename, int linenumber ) +{ + int i; + + for ( i = 0; i < mBreakpoints.Num(); i ++ ) + { + rvDebuggerBreakpoint* bp = mBreakpoints[i]; + + if ( linenumber == bp->GetLineNumber ( ) && !idStr::Icmp ( bp->GetFilename ( ), filename ) ) + { + return bp; + } + } + + return NULL; +} + +/* +================ +rvDebuggerClient::ClearBreakpoints + +Removes all breakpoints from the client and server +================ +*/ +void rvDebuggerClient::ClearBreakpoints ( void ) +{ + int i; + + for ( i = 0; i < GetBreakpointCount(); i ++ ) + { + rvDebuggerBreakpoint* bp = mBreakpoints[i]; + assert ( bp ); + + SendRemoveBreakpoint ( *bp ); + delete bp; + } + + mBreakpoints.Clear ( ); +} + +/* +================ +rvDebuggerClient::AddBreakpoint + +Adds a breakpoint to the client and server with the give nfilename and linenumber +================ +*/ +int rvDebuggerClient::AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly ) +{ + int index = mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber ) ); + + SendAddBreakpoint ( *mBreakpoints[index] ); + + return index; +} + +/* +================ +rvDebuggerClient::RemoveBreakpoint + +Removes the breakpoint with the given ID from the client and server +================ +*/ +bool rvDebuggerClient::RemoveBreakpoint ( int bpID ) +{ + int index; + + for ( index = 0; index < GetBreakpointCount(); index ++ ) + { + if ( mBreakpoints[index]->GetID ( ) == bpID ) + { + SendRemoveBreakpoint ( *mBreakpoints[index] ); + delete mBreakpoints[index]; + mBreakpoints.RemoveIndex ( index ); + return true; + } + } + + return false; +} + +/* +================ +rvDebuggerClient::SendMessage + +Send a message with no data to the debugger server +================ +*/ +void rvDebuggerClient::SendMessage ( EDebuggerMessage dbmsg ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)dbmsg ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerClient::SendBreakpoints + +Send all breakpoints to the debugger server +================ +*/ +void rvDebuggerClient::SendBreakpoints ( void ) +{ + int i; + + if ( !mConnected ) + { + return; + } + + // Send all the breakpoints to the server + for ( i = 0; i < mBreakpoints.Num(); i ++ ) + { + SendAddBreakpoint ( *mBreakpoints[i] ); + } +} + +/* +================ +rvDebuggerClient::SendAddBreakpoint + +Send an individual breakpoint over to the debugger server +================ +*/ +void rvDebuggerClient::SendAddBreakpoint ( rvDebuggerBreakpoint& bp, bool onceOnly ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + + if ( !mConnected ) + { + return; + } + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_ADDBREAKPOINT ); + MSG_WriteBits ( &msg, onceOnly?1:0, 1 ); + MSG_WriteLong ( &msg, (unsigned long) bp.GetLineNumber ( ) ); + MSG_WriteLong ( &msg, bp.GetID ( ) ); + MSG_WriteString ( &msg, bp.GetFilename() ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerClient::SendRemoveBreakpoint + +Sends a remove breakpoint message to the debugger server +================ +*/ +void rvDebuggerClient::SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + + if ( !mConnected ) + { + return; + } + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_REMOVEBREAKPOINT ); + MSG_WriteLong ( &msg, bp.GetID() ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerClient::ClearCallstack + +Clear all callstack entries +================ +*/ +void rvDebuggerClient::ClearCallstack ( void ) +{ + int depth; + + for ( depth = 0; depth < mCallstack.Num(); depth ++ ) + { + delete mCallstack[depth]; + } + + mCallstack.Clear ( ); +} + +/* +================ +rvDebuggerClient::ClearThreads + +Clear all thread entries +================ +*/ +void rvDebuggerClient::ClearThreads ( void ) +{ + int i; + + for ( i = 0; i < mThreads.Num(); i ++ ) + { + delete mThreads[i]; + } + + mThreads.Clear ( ); +} + diff --git a/tools/debugger/DebuggerClient.h b/tools/debugger/DebuggerClient.h new file mode 100644 index 000000000..9667d91bd --- /dev/null +++ b/tools/debugger/DebuggerClient.h @@ -0,0 +1,280 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERCLIENT_H_ +#define DEBUGGERCLIENT_H_ + +class rvDebuggerCallstack +{ +public: + + idStr mFilename; + int mLineNumber; + idStr mFunction; +}; + +class rvDebuggerThread +{ +public: + + idStr mName; + int mID; + bool mCurrent; + bool mDying; + bool mWaiting; + bool mDoneProcessing; +}; + +#ifndef DEBUGGERBREAKPOINT_H_ +#include "DebuggerBreakpoint.h" +#endif + +typedef idList rvDebuggerCallstackList; +typedef idList rvDebuggerThreadList; +typedef idList rvDebuggerBreakpointList; + +class rvDebuggerClient +{ +public: + + rvDebuggerClient ( ); + ~rvDebuggerClient ( ); + + bool Initialize ( void ); + void Shutdown ( void ); + bool ProcessMessages ( void ); + bool WaitFor ( EDebuggerMessage msg, int time ); + + bool IsConnected ( void ); + bool IsStopped ( void ); + + int GetActiveBreakpointID ( void ); + const char* GetBreakFilename ( void ); + int GetBreakLineNumber ( void ); + rvDebuggerCallstackList& GetCallstack ( void ); + rvDebuggerThreadList& GetThreads ( void ); + const char* GetVariableValue ( const char* name, int stackDepth ); + + void InspectVariable ( const char* name, int callstackDepth ); + + void Break ( void ); + void Resume ( void ); + void StepInto ( void ); + void StepOver ( void ); + + // Breakpoints + int AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly = false ); + bool RemoveBreakpoint ( int bpID ); + void ClearBreakpoints ( void ); + int GetBreakpointCount ( void ); + rvDebuggerBreakpoint* GetBreakpoint ( int index ); + rvDebuggerBreakpoint* FindBreakpoint ( const char* filename, int linenumber ); + +protected: + + void SendMessage ( EDebuggerMessage dbmsg ); + void SendBreakpoints ( void ); + void SendAddBreakpoint ( rvDebuggerBreakpoint& bp, bool onceOnly = false ); + void SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp ); + void SendPacket ( void* data, int datasize ); + + bool mConnected; + netadr_t mServerAdr; + idPort mPort; + + bool mBreak; + int mBreakID; + int mBreakLineNumber; + idStr mBreakFilename; + + idDict mVariables; + + rvDebuggerCallstackList mCallstack; + rvDebuggerThreadList mThreads; + rvDebuggerBreakpointList mBreakpoints; + + EDebuggerMessage mWaitFor; + +private: + + void ClearCallstack ( void ); + void ClearThreads ( void ); + + void UpdateWatches ( void ); + + // Network message handlers + void HandleBreak ( msg_t* msg ); + void HandleInspectCallstack ( msg_t* msg ); + void HandleInspectThreads ( msg_t* msg ); + void HandleInspectVariable ( msg_t* msg ); +}; + +/* +================ +rvDebuggerClient::IsConnected +================ +*/ +ID_INLINE bool rvDebuggerClient::IsConnected ( void ) +{ + return mConnected; +} + +/* +================ +rvDebuggerClient::IsStopped +================ +*/ +ID_INLINE bool rvDebuggerClient::IsStopped ( void ) +{ + return mBreak; +} + +/* +================ +rvDebuggerClient::GetActiveBreakpointID +================ +*/ +ID_INLINE int rvDebuggerClient::GetActiveBreakpointID ( void ) +{ + return mBreakID; +} + +/* +================ +rvDebuggerClient::GetBreakFilename +================ +*/ +ID_INLINE const char* rvDebuggerClient::GetBreakFilename ( void ) +{ + return mBreakFilename; +} + +/* +================ +rvDebuggerClient::GetBreakLineNumber +================ +*/ +ID_INLINE int rvDebuggerClient::GetBreakLineNumber ( void ) +{ + return mBreakLineNumber; +} + +/* +================ +rvDebuggerClient::GetCallstack +================ +*/ +ID_INLINE rvDebuggerCallstackList& rvDebuggerClient::GetCallstack ( void ) +{ + return mCallstack; +} + +/* +================ +rvDebuggerClient::GetThreads +================ +*/ +ID_INLINE rvDebuggerThreadList& rvDebuggerClient::GetThreads ( void ) +{ + return mThreads; +} + +/* +================ +rvDebuggerClient::GetVariableValue +================ +*/ +ID_INLINE const char* rvDebuggerClient::GetVariableValue ( const char* var, int stackDepth ) +{ + return mVariables.GetString ( va("%d:%s",stackDepth,var), "" ); +} + +/* +================ +rvDebuggerClient::GetBreakpointCount +================ +*/ +ID_INLINE int rvDebuggerClient::GetBreakpointCount ( void ) +{ + return mBreakpoints.Num ( ); +} + +/* +================ +rvDebuggerClient::GetBreakpoint +================ +*/ +ID_INLINE rvDebuggerBreakpoint* rvDebuggerClient::GetBreakpoint ( int index ) +{ + return mBreakpoints[index]; +} + +/* +================ +rvDebuggerClient::Break +================ +*/ +ID_INLINE void rvDebuggerClient::Break ( void ) +{ + SendMessage ( DBMSG_BREAK ); +} + +/* +================ +rvDebuggerClient::Resume +================ +*/ +ID_INLINE void rvDebuggerClient::Resume ( void ) +{ + mBreak = false; + SendMessage ( DBMSG_RESUME ); +} + +/* +================ +rvDebuggerClient::StepOver +================ +*/ +ID_INLINE void rvDebuggerClient::StepOver ( void ) +{ + mBreak = false; + SendMessage ( DBMSG_STEPOVER ); +} + +/* +================ +rvDebuggerClient::StepInto +================ +*/ +ID_INLINE void rvDebuggerClient::StepInto ( void ) +{ + mBreak = false; + SendMessage ( DBMSG_STEPINTO ); +} + +/* +================ +rvDebuggerClient::SendPacket +================ +*/ +ID_INLINE void rvDebuggerClient::SendPacket ( void* data, int size ) +{ + mPort.SendPacket ( mServerAdr, data, size ); +} + +#endif // DEBUGGERCLIENT_H_ diff --git a/tools/debugger/DebuggerFindDlg.cpp b/tools/debugger/DebuggerFindDlg.cpp new file mode 100644 index 000000000..9b8ee593d --- /dev/null +++ b/tools/debugger/DebuggerFindDlg.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/debugger_resource.h" +#include "DebuggerApp.h" +#include "DebuggerFindDlg.h" + +char rvDebuggerFindDlg::mFindText[ 256 ]; + +/* +================ +rvDebuggerFindDlg::rvDebuggerFindDlg +================ +*/ +rvDebuggerFindDlg::rvDebuggerFindDlg ( void ) +{ +} + +/* +================ +rvDebuggerFindDlg::DoModal + +Launch the dialog +================ +*/ +bool rvDebuggerFindDlg::DoModal ( rvDebuggerWindow* parent ) +{ + if ( DialogBoxParam ( parent->GetInstance(), MAKEINTRESOURCE(IDD_DBG_FIND), parent->GetWindow(), DlgProc, (LONG)this ) ) + { + return true; + } + + return false; +} + +/* +================ +rvrvDebuggerFindDlg::DlgProc + +Dialog Procedure for the find dialog +================ +*/ +INT_PTR CALLBACK rvDebuggerFindDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + rvDebuggerFindDlg* dlg = (rvDebuggerFindDlg*) GetWindowLong ( wnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_CLOSE: + EndDialog ( wnd, 0 ); + break; + + case WM_INITDIALOG: + dlg = (rvDebuggerFindDlg*) lparam; + SetWindowLong ( wnd, GWL_USERDATA, (LONG) dlg ); + dlg->mWnd = wnd; + SetWindowText ( GetDlgItem ( dlg->mWnd, IDC_DBG_FIND ), dlg->mFindText ); + return TRUE; + + case WM_COMMAND: + switch ( LOWORD(wparam) ) + { + case IDOK: + { + GetWindowText ( GetDlgItem ( wnd, IDC_DBG_FIND ), dlg->mFindText, sizeof( dlg->mFindText ) - 1 ); + EndDialog ( wnd, 1 ); + break; + } + + case IDCANCEL: + EndDialog ( wnd, 0 ); + break; + } + break; + } + + return FALSE; +} diff --git a/tools/debugger/DebuggerFindDlg.h b/tools/debugger/DebuggerFindDlg.h new file mode 100644 index 000000000..3147da8ff --- /dev/null +++ b/tools/debugger/DebuggerFindDlg.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERFINDDLG_H_ +#define DEBUGGERFINDDLG_H_ + +class rvDebuggerWindow; + +class rvDebuggerFindDlg +{ +public: + + rvDebuggerFindDlg ( ); + + bool DoModal ( rvDebuggerWindow* window ); + + const char* GetFindText ( void ); + +protected: + + HWND mWnd; + +private: + + static char mFindText[ 256 ]; + + static INT_PTR CALLBACK DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); +}; + +ID_INLINE const char* rvDebuggerFindDlg::GetFindText ( void ) +{ + return mFindText; +} + +#endif // DEBUGGERFINDDLG_H_ \ No newline at end of file diff --git a/tools/debugger/DebuggerMessages.h b/tools/debugger/DebuggerMessages.h new file mode 100644 index 000000000..195b52621 --- /dev/null +++ b/tools/debugger/DebuggerMessages.h @@ -0,0 +1,42 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERMESSAGES_H_ +#define DEBUGGERMESSAGES_H_ + +enum EDebuggerMessage +{ + DBMSG_UNKNOWN, + DBMSG_CONNECT, + DBMSG_CONNECTED, + DBMSG_DISCONNECT, + DBMSG_ADDBREAKPOINT, + DBMSG_REMOVEBREAKPOINT, + DBMSG_HITBREAKPOINT, + DBMSG_RESUME, + DBMSG_RESUMED, + DBMSG_BREAK, + DBMSG_PRINT, + DBMSG_INSPECTVARIABLE, + DBMSG_INSPECTCALLSTACK, + DBMSG_INSPECTTHREADS, + DBMSG_STEPOVER, + DBMSG_STEPINTO, +}; + +#endif // DEBUGGER_MESSAGES_H_ \ No newline at end of file diff --git a/tools/debugger/DebuggerQuickWatchDlg.cpp b/tools/debugger/DebuggerQuickWatchDlg.cpp new file mode 100644 index 000000000..a44e93c82 --- /dev/null +++ b/tools/debugger/DebuggerQuickWatchDlg.cpp @@ -0,0 +1,258 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/debugger_resource.h" +#include "DebuggerApp.h" +#include "DebuggerQuickWatchDlg.h" + +/* +================ +rvDebuggerQuickWatchDlg::rvDebuggerQuickWatchDlg +================ +*/ +rvDebuggerQuickWatchDlg::rvDebuggerQuickWatchDlg ( void ) +{ +} + +/* +================ +rvDebuggerQuickWatchDlg::DoModal + +Launch the dialog +================ +*/ +bool rvDebuggerQuickWatchDlg::DoModal ( rvDebuggerWindow* window, int callstackDepth, const char* variable ) +{ + mCallstackDepth = callstackDepth; + mDebuggerWindow = window; + mVariable = variable?variable:""; + + DialogBoxParam ( window->GetInstance(), MAKEINTRESOURCE(IDD_DBG_QUICKWATCH), window->GetWindow(), DlgProc, (LONG)this ); + + return true; +} + +/* +================ +rvDebuggerQuickWatchDlg::DlgProc + +Dialog Procedure for the quick watch dialog +================ +*/ +INT_PTR CALLBACK rvDebuggerQuickWatchDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + rvDebuggerQuickWatchDlg* dlg = (rvDebuggerQuickWatchDlg*) GetWindowLong ( wnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_GETMINMAXINFO: + { + MINMAXINFO* mmi = (MINMAXINFO*)lparam; + mmi->ptMinTrackSize.x = 300; + mmi->ptMinTrackSize.y = 200; + break; + } + + case WM_CLOSE: + gDebuggerApp.GetOptions().SetWindowPlacement ( "wp_quickwatch", wnd ); + gDebuggerApp.GetOptions().SetColumnWidths ( "cw_quickwatch", GetDlgItem ( wnd, IDC_DBG_CURVALUE ) ); + EndDialog ( wnd, 0 ); + break; + + case WM_SIZE: + { + RECT client; + RECT button; + + GetClientRect ( wnd, &client ); + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_RECALC ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + MoveWindow ( GetDlgItem ( wnd, IDC_DBG_RECALC ), client.right - dlg->mButtonFromRight, button.top, button.right-button.left,button.bottom-button.top, TRUE ); + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_CLOSE ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + MoveWindow ( GetDlgItem ( wnd, IDC_DBG_CLOSE ), client.right - dlg->mButtonFromRight, button.top, button.right-button.left,button.bottom-button.top, TRUE ); + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_ADDWATCH ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + MoveWindow ( GetDlgItem ( wnd, IDC_DBG_ADDWATCH ), client.right - dlg->mButtonFromRight, button.top, button.right-button.left,button.bottom-button.top, TRUE ); + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_VARIABLE ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + MoveWindow ( GetDlgItem ( wnd, IDC_DBG_VARIABLE ), button.left, button.top, client.right-button.left-dlg->mEditFromRight, button.bottom-button.top, TRUE ); + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + MoveWindow ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), button.left, button.top, client.right-button.left-dlg->mEditFromRight, client.bottom-button.top - dlg->mEditFromBottom, TRUE ); + + break; + } + + case WM_INITDIALOG: + { + RECT client; + RECT button; + + // Attach the dialog class pointer to the window + dlg = (rvDebuggerQuickWatchDlg*) lparam; + SetWindowLong ( wnd, GWL_USERDATA, lparam ); + dlg->mWnd = wnd; + + GetClientRect ( wnd, &client ); + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_RECALC ), &button ); + ScreenToClient ( wnd, (POINT*)&button ); + dlg->mButtonFromRight = client.right - button.left; + + GetWindowRect ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), &button ); + ScreenToClient ( wnd, (POINT*)&button.right ); + dlg->mEditFromRight = client.right - button.right; + dlg->mEditFromBottom = client.bottom - button.bottom; + + // Disable the value controls until a variable is entered + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_ADDWATCH ), false ); + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_RECALC ), false ); + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), false ); + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_CURVALUE_STATIC ), false ); + + // Add the columns to the list control + LVCOLUMN col; + col.mask = LVCF_WIDTH|LVCF_TEXT; + col.cx = 100; + col.pszText = "Name"; + ListView_InsertColumn ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), 0, &col ); + col.cx = 150; + col.pszText = "Value"; + ListView_InsertColumn ( GetDlgItem ( wnd, IDC_DBG_CURVALUE ), 1, &col ); + + // Set the initial variable if one was given + if ( dlg->mVariable.Length() ) + { + dlg->SetVariable ( dlg->mVariable, true ); + SetWindowText( GetDlgItem ( wnd, IDC_DBG_VARIABLE ), dlg->mVariable ); + } + + gDebuggerApp.GetOptions().GetWindowPlacement ( "wp_quickwatch", wnd ); + gDebuggerApp.GetOptions().GetColumnWidths ( "cw_quickwatch", GetDlgItem ( wnd, IDC_DBG_CURVALUE ) ); + + return TRUE; + } + + case WM_COMMAND: + switch ( LOWORD(wparam) ) + { + case IDC_DBG_CLOSE: + SendMessage ( wnd, WM_CLOSE, 0, 0 ); + break; + + case IDC_DBG_VARIABLE: + // When the variable text changes to something other than empty + // we can enable the addwatch and recalc buttons + if ( HIWORD(wparam) == EN_CHANGE ) + { + bool enable = GetWindowTextLength ( GetDlgItem ( wnd, IDC_DBG_VARIABLE ) )?true:false; + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_ADDWATCH ), enable ); + EnableWindow ( GetDlgItem ( wnd, IDC_DBG_RECALC ), enable ); + } + break; + + case IDC_DBG_ADDWATCH: + { + char varname[1024]; + GetWindowText ( GetDlgItem ( wnd, IDC_DBG_VARIABLE ), varname, 1023 ); + dlg->mDebuggerWindow->AddWatch ( varname ); + break; + } + + case IDC_DBG_RECALC: + { + char varname[1024]; + GetWindowText ( GetDlgItem ( wnd, IDC_DBG_VARIABLE ), varname, 1023 ); + dlg->SetVariable ( varname ); + break; + } + } + break; + } + + return FALSE; +} + +/* +================ +rvDebuggerQuickWatchDlg::SetVariable + +Sets the current variable being inspected +================ +*/ +void rvDebuggerQuickWatchDlg::SetVariable ( const char* varname, bool force ) +{ + // See if the variable has changed + if ( !force && !mVariable.Icmp ( varname ) ) + { + return; + } + + // Throw up a wait cursor + SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ); + + // Clear the current value list control + ListView_DeleteAllItems ( GetDlgItem ( mWnd, IDC_DBG_CURVALUE ) ); + + // Get the value of the new variable + gDebuggerApp.GetClient().InspectVariable ( varname, mCallstackDepth ); + + // Wait for the variable value to be sent over from the debugger server + if ( !gDebuggerApp.GetClient().WaitFor ( DBMSG_INSPECTVARIABLE, 2500 ) ) + { + return; + } + + // Make sure we got the value of the variable + if ( !gDebuggerApp.GetClient().GetVariableValue(varname, mCallstackDepth)[0] ) + { + return; + } + + // Enable the windows that display the current value + mVariable = varname; + EnableWindow ( GetDlgItem ( mWnd, IDC_DBG_CURVALUE ), true ); + EnableWindow ( GetDlgItem ( mWnd, IDC_DBG_CURVALUE_STATIC ), true ); + + // Add the variablae value to the list control + LVITEM item; + item.mask = LVIF_TEXT; + item.pszText = (LPSTR)varname; + item.iItem = 0; + item.iSubItem = 0; + ListView_InsertItem ( GetDlgItem ( mWnd, IDC_DBG_CURVALUE ), &item ); + ListView_SetItemText ( GetDlgItem ( mWnd, IDC_DBG_CURVALUE ), 0, 1, (LPSTR)gDebuggerApp.GetClient().GetVariableValue(varname,mCallstackDepth) ); + + // Give focus back to the variable edit control and set the cursor back to an arrow + SetFocus ( GetDlgItem ( mWnd, IDC_DBG_VARIABLE ) ); + SetCursor ( LoadCursor ( NULL, IDC_ARROW ) ); +} diff --git a/tools/debugger/DebuggerQuickWatchDlg.h b/tools/debugger/DebuggerQuickWatchDlg.h new file mode 100644 index 000000000..1a2706d03 --- /dev/null +++ b/tools/debugger/DebuggerQuickWatchDlg.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERQUICKWATCHDLG_H_ +#define DEBUGGERQUICKWATCHDLG_H_ + +class rvDebuggerWindow; + +class rvDebuggerQuickWatchDlg +{ +public: + + rvDebuggerQuickWatchDlg ( ); + + bool DoModal ( rvDebuggerWindow* window, int callstackDepth, const char* variable = NULL ); + +protected: + + HWND mWnd; + int mCallstackDepth; + idStr mVariable; + rvDebuggerWindow* mDebuggerWindow; + + void SetVariable ( const char* varname, bool force = false ); + +private: + + int mEditFromRight; + int mButtonFromRight; + int mEditFromBottom; + + static INT_PTR CALLBACK DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); +}; + +#endif // DEBUGGERQUICKWATCHDLG_H_ \ No newline at end of file diff --git a/tools/debugger/DebuggerScript.cpp b/tools/debugger/DebuggerScript.cpp new file mode 100644 index 000000000..84e95eb89 --- /dev/null +++ b/tools/debugger/DebuggerScript.cpp @@ -0,0 +1,235 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "DebuggerApp.h" +#include "DebuggerScript.h" +#include "../../game/script/Script_Program.h" +#include "../../ui/Window.h" +#include "../../ui/UserInterfaceLocal.h" + +/* +================ +rvDebuggerScript::rvDebuggerScript +================ +*/ +rvDebuggerScript::rvDebuggerScript ( void ) +{ + mContents = NULL; + mProgram = NULL; + mInterface = NULL; +} + +/* +================ +rvDebuggerScript::~rvDebuggerScript +================ +*/ +rvDebuggerScript::~rvDebuggerScript ( void ) +{ + Unload ( ); +} + +/* +================ +rvDebuggerScript::Unload + +Unload the script from memory +================ +*/ +void rvDebuggerScript::Unload ( void ) +{ + delete[] mContents; + + if ( mInterface ) + { + delete mInterface; + } + else + { + delete mProgram; + } + + mContents = NULL; + mProgram = NULL; + mInterface = NULL; +} + +/* +================ +rvDebuggerScript::Load + +Loads the debugger script and attempts to compile it using the method +appropriate for the file being loaded. If the script cant be compiled +the loading of the script fails +================ +*/ +bool rvDebuggerScript::Load ( const char* filename ) +{ + void* buffer; + int size; + + // Unload the script before reloading it + Unload ( ); + + // Cache the filename used to load the script + mFilename = filename; + + // Read in the file + size = fileSystem->ReadFile ( filename, &buffer, &mModifiedTime ); + if ( buffer == NULL ) + { + return false; + } + + // Copy the buffer over + mContents = new char [ size + 1 ]; + memcpy ( mContents, buffer, size ); + mContents[size] = 0; + + // Cleanup + fileSystem->FreeFile ( buffer ); + + // Now compile the script so we can tell what a valid line is, etc.. If its + // a gui file then we need to parse it using the userinterface system rather + // than the normal script compiler. + try + { + // Parse the script using the script compiler + mProgram = new idProgram; + mProgram->BeginCompilation ( ); + mProgram->CompileFile ( SCRIPT_DEFAULT ); + + //BSM Nerve: Loads a game specific main script file + idStr gamedir = cvarSystem->GetCVarString( "fs_game" ); + if(gamedir.Length() > 0) { + + idStr scriptFile = va("script/%s_main.script", gamedir.c_str()); + if(fileSystem->ReadFile(scriptFile.c_str(), NULL) > 0) { + mProgram.CompileFile(scriptFile.c_str()); + } + + } + + // Make sure the file isnt already compiled before trying to compile it again + for ( int f = mProgram->NumFilenames() - 1; f >= 0; f -- ) + { + idStr qpath; + qpath = fileSystem->OSPathToRelativePath ( mProgram->GetFilename ( f ) ); + qpath.BackSlashesToSlashes ( ); + if ( !qpath.Cmp ( filename ) ) + { + break; + } + } + + if ( f < 0 ) + { + mProgram->CompileText ( filename, mContents, false ); + } + + mProgram->FinishCompilation ( ); + } + catch ( idException& ) + { + // Failed to parse the script so fail to load the file + delete mProgram; + mProgram = NULL; + delete[] mContents; + mContents = NULL; + + // TODO: Should cache the error for the dialog box + + return false; + } + + return true; +} + +/* +================ +rvDebuggerScript::Reload + +Reload the contents of the script +================ +*/ +bool rvDebuggerScript::Reload ( void ) +{ + return Load ( mFilename ); +} + +/* +================ +rvDebuggerScript::IsValidLine + +Determines whether or not the given line number within the script is a valid line of code +================ +*/ +bool rvDebuggerScript::IsLineCode ( int linenumber ) +{ + int i; + + assert ( mProgram ); + + // Run through all the statements in the program and see if any match the + // linenumber that we are checking. + for ( i = 0; i < mProgram->NumStatements ( ); i ++ ) + { + if ( mProgram->GetStatement ( i ).linenumber == linenumber ) + { + return true; + } + } + + return false; +} + +/* +================ +rvDebuggerScript::IsFileModified + +Determines whether or not the file loaded for this script has been modified since +it was loaded. +================ +*/ +bool rvDebuggerScript::IsFileModified ( bool updateTime ) +{ + ID_TIME_T t; + bool result = false; + + // Grab the filetime and shut the file down + fileSystem->ReadFile ( mFilename, NULL, &t ); + + // Has the file been modified? + if ( t > mModifiedTime ) + { + result = true; + } + + // If updateTime is true then we will update the modified time + // stored in the script with the files current modified time + if ( updateTime ) + { + mModifiedTime = t; + } + + return result; +} diff --git a/tools/debugger/DebuggerScript.h b/tools/debugger/DebuggerScript.h new file mode 100644 index 000000000..53f48ede1 --- /dev/null +++ b/tools/debugger/DebuggerScript.h @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERSCRIPT_H_ +#define DEBUGGERSCRIPT_H_ + +class idProgram; +class idUserInterfaceLocal; + +class rvDebuggerScript +{ +public: + + rvDebuggerScript ( void ); + ~rvDebuggerScript ( void ); + + bool Load ( const char* filename ); + bool Reload ( void ); + + const char* GetFilename ( void ); + const char* GetContents ( void ); + + idProgram& GetProgram ( void ); + + bool IsLineCode ( int linenumber ); + bool IsFileModified ( bool updateTime = false ); + +protected: + + void Unload ( void ); + + idProgram* mProgram; + idUserInterfaceLocal* mInterface; + char* mContents; + idStr mFilename; + ID_TIME_T mModifiedTime; +}; + +ID_INLINE const char* rvDebuggerScript::GetFilename ( void ) +{ + return mFilename; +} + +ID_INLINE const char* rvDebuggerScript::GetContents ( void ) +{ + return mContents?mContents:""; +} + +ID_INLINE idProgram& rvDebuggerScript::GetProgram ( void ) +{ + return *mProgram; +} + +#endif // DEBUGGERSCRIPT_H_ \ No newline at end of file diff --git a/tools/debugger/DebuggerServer.cpp b/tools/debugger/DebuggerServer.cpp new file mode 100644 index 000000000..9e9e18e1a --- /dev/null +++ b/tools/debugger/DebuggerServer.cpp @@ -0,0 +1,705 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../game/gamesys/Event.h" +#include "../../game/gamesys/Class.h" +#include "../../game/script/Script_Program.h" +#include "../../game/script/Script_Interpreter.h" +#include "../../game/script/Script_Thread.h" +#include "../../game/script/Script_Compiler.h" +#include "../../framework/sync/Msg.h" +#include "DebuggerApp.h" +#include "DebuggerServer.h" + +/* +================ +rvDebuggerServer::rvDebuggerServer +================ +*/ +rvDebuggerServer::rvDebuggerServer ( ) +{ + mConnected = false; + mBreakNext = false; + mBreak = false; + mBreakStepOver = false; + mBreakStepInto = false; + mGameThread = NULL; + mLastStatementLine = -1; + mBreakStepOverFunc1 = NULL; + mBreakStepOverFunc2 = NULL; +} + +/* +================ +rvDebuggerServer::~rvDebuggerServer +================ +*/ +rvDebuggerServer::~rvDebuggerServer ( ) +{ +} + +/* +================ +rvDebuggerServer::Initialize + +Initialize the debugger server. This function should be called before the +debugger server is used. +================ +*/ +bool rvDebuggerServer::Initialize ( void ) +{ + // Initialize the network connection + if ( !mPort.InitForPort ( 27980 ) ) + { + return false; + } + + // Get a copy of the game thread handle so we can suspend the thread on a break + DuplicateHandle ( GetCurrentProcess(), GetCurrentThread ( ), GetCurrentProcess(), &mGameThread, 0, FALSE, DUPLICATE_SAME_ACCESS ); + + // Create a critical section to ensure that the shared thread + // variables are protected + InitializeCriticalSection ( &mCriticalSection ); + + // Server must be running on the local host on port 28980 + Sys_StringToNetAdr ( "localhost", &mClientAdr, true ); + mClientAdr.port = 27981; + + // Attempt to let the server know we are here. The server may not be running so this + // message will just get ignored. + SendMessage ( DBMSG_CONNECT ); + + return true; +} + +void rvDebuggerServer::OSPathToRelativePath( const char *osPath, idStr &qpath ) +{ + if ( strchr( osPath, ':' ) ) + { + qpath = fileSystem->OSPathToRelativePath( osPath ); + } + else + { + qpath = osPath; + } +} + +/* +================ +rvDebuggerServer::Shutdown + +Shutdown the debugger server. +================ +*/ +void rvDebuggerServer::Shutdown ( void ) +{ + // Let the debugger client know we are shutting down + if ( mConnected ) + { + SendMessage ( DBMSG_DISCONNECT ); + mConnected = false; + } + + mPort.Close(); + + // dont need the crit section anymore + DeleteCriticalSection ( &mCriticalSection ); +} + +/* +================ +rvDebuggerServer::ProcessMessages + +Process all incoming network messages from the debugger client +================ +*/ +bool rvDebuggerServer::ProcessMessages ( void ) +{ + netadr_t adrFrom; + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + + // Check for pending udp packets on the debugger port + while ( mPort.GetPacket ( adrFrom, msg.data, msg.cursize, msg.maxsize ) ) + { + unsigned short command; + + // Only accept packets from the debugger server for security reasons + if ( !Sys_CompareNetAdrBase ( adrFrom, mClientAdr ) ) + { + continue; + } + + command = (unsigned short) MSG_ReadShort ( &msg ); + + switch ( command ) + { + case DBMSG_CONNECT: + mConnected = true; + SendMessage ( DBMSG_CONNECTED ); + break; + + case DBMSG_CONNECTED: + mConnected = true; + break; + + case DBMSG_DISCONNECT: + ClearBreakpoints ( ); + Resume ( ); + mConnected = false; + break; + + case DBMSG_ADDBREAKPOINT: + HandleAddBreakpoint ( &msg ); + break; + + case DBMSG_REMOVEBREAKPOINT: + HandleRemoveBreakpoint ( &msg ); + break; + + case DBMSG_RESUME: + Resume ( ); + break; + + case DBMSG_BREAK: + mBreakNext = true; + break; + + case DBMSG_STEPOVER: + mBreakStepOver = true; + mBreakStepOverDepth = mBreakInterpreter->GetCallstackDepth ( ); + mBreakStepOverFunc1 = mBreakInterpreter->GetCallstack()[mBreakInterpreter->GetCallstackDepth()].f; + if ( mBreakInterpreter->GetCallstackDepth() > 0 ) + { + mBreakStepOverFunc2 = mBreakInterpreter->GetCallstack()[mBreakInterpreter->GetCallstackDepth()-1].f; + } + else + { + mBreakStepOverFunc2 = NULL; + } + Resume ( ); + break; + + case DBMSG_STEPINTO: + mBreakStepInto = true; + Resume ( ); + break; + + case DBMSG_INSPECTVARIABLE: + HandleInspectVariable ( &msg ); + break; + + case DBMSG_INSPECTCALLSTACK: + HandleInspectCallstack ( &msg ); + break; + + case DBMSG_INSPECTTHREADS: + HandleInspectThreads ( &msg ); + break; + } + } + + return true; +} + +/* +================ +rvDebuggerServer::SendMessage + +Send a message with no data to the debugger server. +================ +*/ +void rvDebuggerServer::SendMessage ( EDebuggerMessage dbmsg ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)dbmsg ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerServer::HandleAddBreakpoint + +Handle the DBMSG_ADDBREAKPOINT message being sent by the debugger client. This +message is handled by adding a new breakpoint to the breakpoint list with the +data supplied in the message. +================ +*/ +void rvDebuggerServer::HandleAddBreakpoint ( msg_t* msg ) +{ + bool onceOnly = false; + long lineNumber; + long id; + char filename[MAX_PATH]; + + // Read the breakpoint info + onceOnly = MSG_ReadBits ( msg, 1 ) ? true : false; + lineNumber = MSG_ReadLong ( msg ); + id = MSG_ReadLong ( msg ); + + MSG_ReadString ( msg, filename, MAX_PATH ); + + // Since breakpoints are used by both threads we need to + // protect them with a crit section + EnterCriticalSection ( &mCriticalSection ); + mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber, id ) ); + LeaveCriticalSection ( &mCriticalSection ); +} + +/* +================ +rvDebuggerServer::HandleRemoveBreakpoint + +Handle the DBMSG_REMOVEBREAKPOINT message being sent by the debugger client. This +message is handled by removing the breakpoint that matches the given id from the +list. +================ +*/ +void rvDebuggerServer::HandleRemoveBreakpoint ( msg_t* msg ) +{ + int i; + int id; + + // ID that we are to remove + id = MSG_ReadLong ( msg ); + + // Since breakpoints are used by both threads we need to + // protect them with a crit section + EnterCriticalSection ( &mCriticalSection ); + + // Find the breakpoint that matches the given id and remove it from the list + for ( i = 0; i < mBreakpoints.Num(); i ++ ) + { + if ( mBreakpoints[i]->GetID ( ) == id ) + { + delete mBreakpoints[i]; + mBreakpoints.RemoveIndex ( i ); + break; + } + } + + LeaveCriticalSection ( &mCriticalSection ); +} + +/* +================ +rvDebuggerServer::MSG_WriteCallstackFunc + +Writes a single callstack entry to the given message +================ +*/ +void rvDebuggerServer::MSG_WriteCallstackFunc ( msg_t* msg, const prstack_t* stack ) +{ + const statement_t* st; + const function_t* func; + + func = stack->f; + + // If the function is unknown then just fill in with default data. + if ( !func ) + { + MSG_WriteString ( msg, "" ); + MSG_WriteString ( msg, "" ); + MSG_WriteLong ( msg, 0 ); + return; + } + else + { + MSG_WriteString ( msg, va("%s( ??? )", func->Name() ) ); + } + + // Use the calling statement as the filename and linenumber where + // the call was made from + st = &mBreakProgram->GetStatement ( stack->s ); + if ( st ) + { + idStr qpath; + OSPathToRelativePath(mBreakProgram->GetFilename( st->file ), qpath); + qpath.BackSlashesToSlashes ( ); + MSG_WriteString ( msg, qpath ); + MSG_WriteLong ( msg, st->linenumber ); + } + else + { + MSG_WriteString ( msg, "" ); + MSG_WriteLong ( msg, 0 ); + } +} + +/* +================ +rvDebuggerServer::HandleInspectCallstack + +Handle an incoming inspect callstack message by sending a message +back to the client with the callstack data. +================ +*/ +void rvDebuggerServer::HandleInspectCallstack ( msg_t* in_msg ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + int i; + prstack_t temp; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_INSPECTCALLSTACK ); + + MSG_WriteShort ( &msg, (int)mBreakInterpreter->GetCallstackDepth ( ) ); + + // write out the current function + temp.f = mBreakInterpreter->GetCurrentFunction ( ); + temp.s = 0; + temp.stackbase = 0; + MSG_WriteCallstackFunc ( &msg, &temp ); + + // Run through all of the callstack and write each to the msg + for ( i = mBreakInterpreter->GetCallstackDepth ( ) - 1; i > 0; i -- ) + { + MSG_WriteCallstackFunc ( &msg, mBreakInterpreter->GetCallstack ( ) + i ); + } + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerServer::HandleInspectThreads + +Send the list of the current threads in the interpreter back to the debugger client +================ +*/ +void rvDebuggerServer::HandleInspectThreads ( msg_t* in_msg ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + int i; + + // Initialize the message + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_INSPECTTHREADS ); + + // Write the number of threads to the message + MSG_WriteShort ( &msg, (int)idThread::GetThreads().Num() ); + + // Loop through all of the threads and write their name and number to the message + for ( i = 0; i < idThread::GetThreads().Num(); i ++ ) + { + idThread* thread = idThread::GetThreads()[i]; + + MSG_WriteString ( &msg, thread->GetThreadName ( ) ); + MSG_WriteLong ( &msg, thread->GetThreadNum ( ) ); + + MSG_WriteBits ( &msg, (int)(thread == mBreakInterpreter->GetThread ( )), 1 ); + MSG_WriteBits ( &msg, (int)thread->IsDoneProcessing(), 1 ); + MSG_WriteBits ( &msg, (int)thread->IsWaiting(), 1 ); + MSG_WriteBits ( &msg, (int)thread->IsDying(), 1 ); + } + + // Send off the inspect threads packet to the debugger client + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerServer::HandleInspectVariable + +Respondes to a request from the debugger client to inspect the value of a given variable +================ +*/ +void rvDebuggerServer::HandleInspectVariable ( msg_t* in_msg ) +{ + char varname[256]; + int scopeDepth; + + if ( !mBreak ) + { + return; + } + + scopeDepth = (short)MSG_ReadShort ( in_msg ); + MSG_ReadString ( in_msg, varname, 256 ); + + idStr varvalue; + + msg_t msg; + byte buffer[MAX_MSGLEN]; + + // Initialize the message + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_INSPECTVARIABLE ); + + if ( !mBreakInterpreter->GetRegisterValue ( varname, varvalue, scopeDepth ) ) + { + varvalue = "???"; + } + + MSG_WriteShort ( &msg, (short)scopeDepth ); + MSG_WriteString ( &msg, varname ); + MSG_WriteString ( &msg, varvalue ); + + SendPacket ( msg.data, msg.cursize ); +} + +/* +================ +rvDebuggerServer::CheckBreakpoints + +Check to see if any breakpoints have been hit. This includes "break next", +"step into", and "step over" break points +================ +*/ +void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram* program, int instructionPointer ) +{ + const statement_t* st; + const char* filename; + int i; + + if ( !mConnected ) { + return; + } + + // Grab the current statement and the filename that it came from + st = &program->GetStatement ( instructionPointer ); + filename = program->GetFilename ( st->file ); + + // Operate on lines, not statements + if ( mLastStatementLine == st->linenumber && mLastStatementFile == st->file ) + { + return; + } + + // Save the last visited line and file so we can prevent + // double breaks on lines with more than one statement + mLastStatementFile = idStr( st->file ); + mLastStatementLine = st->linenumber; + + // Reset stepping when the last function on the callstack is returned from + if ( st->op == OP_RETURN && interpreter->GetCallstackDepth ( ) <= 1 ) + { + mBreakStepOver = false; + mBreakStepInto = false; + } + + // See if we are supposed to break on the next script line + if ( mBreakNext ) + { + Break ( interpreter, program, instructionPointer ); + return; + } + + // Only break on the same callstack depth and thread as the break over + if ( mBreakStepOver ) + { + if ( ( interpreter->GetCurrentFunction ( ) == mBreakStepOverFunc1 || + interpreter->GetCurrentFunction ( ) == mBreakStepOverFunc2 )&& + ( interpreter->GetCallstackDepth ( ) <= mBreakStepOverDepth ) ) + { + Break ( interpreter, program, instructionPointer ); + return; + } + } + + // See if we are supposed to break on the next line + if ( mBreakStepInto ) + { + // Break + Break ( interpreter, program, instructionPointer ); + return; + } + + idStr qpath; + OSPathToRelativePath(filename,qpath); + qpath.BackSlashesToSlashes ( ); + + EnterCriticalSection ( &mCriticalSection ); + + // Check all the breakpoints + for ( i = 0; i < mBreakpoints.Num ( ); i ++ ) + { + rvDebuggerBreakpoint* bp = mBreakpoints[i]; + + // Skip if not match of the line number + if ( st->linenumber != bp->GetLineNumber ( ) ) + { + continue; + } + + // Skip if no match of the filename + if ( idStr::Icmp ( bp->GetFilename(), qpath ) ) + { + continue; + } + + // Pop out of the critical section so we dont get stuck + LeaveCriticalSection ( &mCriticalSection ); + + // We hit a breakpoint, so break + Break ( interpreter, program, instructionPointer ); + + // Back into the critical section since we are going to have to leave it + EnterCriticalSection ( &mCriticalSection ); + + break; + } + + LeaveCriticalSection ( &mCriticalSection ); +} + +/* +================ +rvDebuggerServer::Break + +Halt execution of the game threads and inform the debugger client that +the game has been halted +================ +*/ +void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer ) +{ + msg_t msg; + byte buffer[MAX_MSGLEN]; + const statement_t* st; + const char* filename; + + // Clear all the break types + mBreakStepOver = false; + mBreakStepInto = false; + mBreakNext = false; + + // Grab the current statement and the filename that it came from + st = &program->GetStatement ( instructionPointer ); + filename = program->GetFilename ( st->file ); + + idStr qpath; + OSPathToRelativePath(filename, qpath); + qpath.BackSlashesToSlashes ( ); + + // Give the mouse cursor back to the world + Sys_GrabMouseCursor( false ); + + // Set the break variable so we know the main thread is stopped + mBreak = true; + mBreakProgram = program; + mBreakInterpreter = interpreter; + mBreakInstructionPointer = instructionPointer; + + // Inform the debugger of the breakpoint hit + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_BREAK ); + MSG_WriteLong ( &msg, st->linenumber ); + MSG_WriteString ( &msg, qpath ); + SendPacket ( msg.data, msg.cursize ); + + // Suspend the game thread. Since this will be called from within the main game thread + // execution wont return until after the thread is resumed + SuspendThread ( mGameThread ); + + // Let the debugger client know that we have started back up again + SendMessage ( DBMSG_RESUMED ); + + // This is to give some time between the keypress that + // told us to resume and the setforeground window. Otherwise the quake window + // would just flash + Sleep ( 150 ); + + // Bring the window back to the foreground + SetForegroundWindow ( win32.hWnd ); + SetActiveWindow ( win32.hWnd ); + UpdateWindow ( win32.hWnd ); + SetFocus ( win32.hWnd ); + + // Give the mouse cursor back to the game + Sys_GrabMouseCursor( true ); + + // Clear all commands that were generated before we went into suspended mode. This is + // to ensure we dont have mouse downs with no ups because the context was changed. + idKeyInput::ClearStates(); +} + +/* +================ +rvDebuggerServer::Resume + +Resume execution of the game. +================ +*/ +void rvDebuggerServer::Resume ( void ) +{ + // Cant resume if not paused + if ( !mBreak ) + { + return; + } + + mBreak = false; + + // Start the game thread back up + ResumeThread ( mGameThread ); +} + +/* +================ +rvDebuggerServer::ClearBreakpoints + +Remove all known breakpoints +================ +*/ +void rvDebuggerServer::ClearBreakpoints ( void ) +{ + int i; + + for ( i = 0; i < mBreakpoints.Num(); i ++ ) + { + delete mBreakpoints[i]; + } + + mBreakpoints.Clear ( ); +} + +/* +================ +rvDebuggerServer::Print + +Sends a console print message over to the debugger client +================ +*/ +void rvDebuggerServer::Print ( const char* text ) +{ + if ( !mConnected ) + { + return; + } + + msg_t msg; + byte buffer[MAX_MSGLEN]; + + MSG_Init( &msg, buffer, sizeof( buffer ) ); + MSG_WriteShort ( &msg, (int)DBMSG_PRINT ); + MSG_WriteString ( &msg, text ); + + SendPacket ( msg.data, msg.cursize ); +} diff --git a/tools/debugger/DebuggerServer.h b/tools/debugger/DebuggerServer.h new file mode 100644 index 000000000..78177936d --- /dev/null +++ b/tools/debugger/DebuggerServer.h @@ -0,0 +1,124 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERSERVER_H_ +#define DEBUGGERSERVER_H_ + +#ifndef DEBUGGERMESSAGES_H_ +#include "DebuggerMessages.h" +#endif + +#ifndef DEBUGGERBREAKPOINT_H_ +#include "DebuggerBreakpoint.h" +#endif + +#ifndef __GAME_LOCAL_H__ +#include "../../game/Game.h" +#endif + +class idInterpreter; +class idProgram; + +class rvDebuggerServer +{ +public: + + rvDebuggerServer ( ); + ~rvDebuggerServer ( ); + + bool Initialize ( void ); + void Shutdown ( void ); + + bool ProcessMessages ( void ); + + bool IsConnected ( void ); + + void CheckBreakpoints ( idInterpreter* interpreter, idProgram* program, int instructionPointer ); + + void Print ( const char* text ); + + void OSPathToRelativePath( const char *osPath, idStr &qpath ); + +protected: + + // protected member variables + bool mConnected; + netadr_t mClientAdr; + idPort mPort; + idList mBreakpoints; + CRITICAL_SECTION mCriticalSection; + + HANDLE mGameThread; + + bool mBreak; + bool mBreakNext; + bool mBreakStepOver; + bool mBreakStepInto; + int mBreakStepOverDepth; + const function_t* mBreakStepOverFunc1; + const function_t* mBreakStepOverFunc2; + idProgram* mBreakProgram; + int mBreakInstructionPointer; + idInterpreter* mBreakInterpreter; + + idStr mLastStatementFile; + int mLastStatementLine; + +private: + + void ClearBreakpoints ( void ); + + void Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer ); + void Resume ( void ); + + void SendMessage ( EDebuggerMessage dbmsg ); + void SendPacket ( void* data, int datasize ); + + // Message handlers + void HandleAddBreakpoint ( msg_t* msg ); + void HandleRemoveBreakpoint ( msg_t* msg ); + void HandleResume ( msg_t* msg ); + void HandleInspectVariable ( msg_t* msg ); + void HandleInspectCallstack ( msg_t* msg ); + void HandleInspectThreads ( msg_t* msg ); + + // MSG helper routines + void MSG_WriteCallstackFunc ( msg_t* msg, const prstack_t* stack ); +}; + +/* +================ +rvDebuggerServer::IsConnected +================ +*/ +ID_INLINE bool rvDebuggerServer::IsConnected ( void ) +{ + return mConnected; +} + +/* +================ +rvDebuggerServer::SendPacket +================ +*/ +ID_INLINE void rvDebuggerServer::SendPacket ( void* data, int size ) +{ + mPort.SendPacket ( mClientAdr, data, size ); +} + +#endif // DEBUGGERSERVER_H_ diff --git a/tools/debugger/DebuggerWindow.cpp b/tools/debugger/DebuggerWindow.cpp new file mode 100644 index 000000000..f34892136 --- /dev/null +++ b/tools/debugger/DebuggerWindow.cpp @@ -0,0 +1,2364 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/debugger_resource.h" +#include "DebuggerApp.h" +#include "../Common/OpenFileDialog.h" +#include "DebuggerQuickWatchDlg.h" +#include "DebuggerFindDlg.h" + +#define DEBUGGERWINDOWCLASS "QUAKE4_DEBUGGER_WINDOW" +#define ID_DBG_WINDOWMIN 18900 +#define ID_DBG_WINDOWMAX 19900 + +#define IDC_DBG_SCRIPT 31000 +#define IDC_DBG_OUTPUT 31001 +#define IDC_DBG_SPLITTER 31002 +#define IDC_DBG_TABS 31003 +#define IDC_DBG_BORDER 31004 +#define IDC_DBG_CONSOLE 31005 +#define IDC_DBG_CALLSTACK 31006 +#define IDC_DBG_WATCH 31007 +#define IDC_DBG_THREADS 31008 +#define IDC_DBG_TOOLBAR 31009 + +#define ID_DBG_FILE_MRU1 10000 + +/* +================ +rvDebuggerWindow::rvDebuggerWindow + +Constructor +================ +*/ +rvDebuggerWindow::rvDebuggerWindow ( ) +{ + mWnd = NULL; + mWndScript = NULL; + mInstance = NULL; + mZoomScaleNum = 0; + mZoomScaleDem = 0; + mWindowMenuPos = 0; + mActiveScript = 0; + mSplitterDrag = false; + mLastActiveScript = -1; + mCurrentStackDepth = 0; + mRecentFileInsertPos = 0; + mRecentFileMenu = NULL; + mClient = NULL; +} + +/* +================ +rvDebuggerWindow::~rvDebuggerWindow + +Destructor +================ +*/ +rvDebuggerWindow::~rvDebuggerWindow ( ) +{ + int i; + + if ( mWnd ) + { + DestroyWindow ( mWnd ); + } + + if ( mImageList ) + { + ImageList_Destroy ( mImageList ); + } + + for ( i = 0; i < mScripts.Num (); i ++ ) + { + delete mScripts[i]; + } +} + +/* +================ +rvDebuggerWindow::RegisterClass + +Registers the window class used by the debugger window. This is called when +the window is created. +================ +*/ +bool rvDebuggerWindow::RegisterClass ( void ) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = mInstance; + wcex.hIcon = NULL; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1); + wcex.lpszMenuName = MAKEINTRESOURCE(IDR_DBG_MAIN); + wcex.lpszClassName = DEBUGGERWINDOWCLASS; + wcex.hIconSm = NULL; + + return RegisterClassEx(&wcex) ? true : false; +} + +/* +================ +rvDebuggerWindow::Create + +Creates the debugger window +================ +*/ +bool rvDebuggerWindow::Create ( HINSTANCE instance ) +{ + mInstance = instance; + + if ( !RegisterClass ( ) ) + { + return false; + } + + // Cache the client pointer for ease of use + mClient = &gDebuggerApp.GetClient(); + + // Create the debugger window + mWnd = CreateWindow( DEBUGGERWINDOWCLASS, "", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, mInstance, this); + + if ( !mWnd ) + { + return false; + } + + // Determine where the window names will be added in the menus + mWindowMenu = GetSubMenu ( GetMenu ( mWnd ), 2 ); + mWindowMenuPos = GetMenuItemCount ( mWindowMenu ); + + UpdateTitle ( ); + + Printf ( "Quake 4 Script Debugger v0.1\n\n" ); + + ShowWindow ( mWnd, SW_SHOW ); + UpdateWindow ( mWnd ); + + return true; +} + +/* +================ +rvDebuggerWindow::ScriptWordBreakProc + +Determines where word breaks are in the script window. This is used for determining +the word that someone is over with their mouse cursor. Since the default windows one +doesnt understand the delimiters of the scripting language it had to be overridden. +================ +*/ +int CALLBACK rvDebuggerWindow::ScriptWordBreakProc (LPTSTR text, int current, int max, int action ) +{ + static TCHAR delimiters[]=TEXT("!@#$%^&*()-+=[]{}|\\;:'\"/,.<>? \t\r\n") ; + + switch ( action ) + { + default: + break; + + case WB_ISDELIMITER: + return _tcschr ( delimiters, *(text + current * 2) ) ? TRUE : FALSE; + + case WB_MOVEWORDLEFT: + case WB_LEFT: + + current--; + + // Run as long as the current index is valid. + while ( current > 0 ) + { + // If we hit a delimiter then return the index + 1 since + // it was the last character we were on that was valid + if ( _tcschr ( delimiters, *(text + current * 2) ) ) + { + return current + 1; + } + + // Going backwards + current--; + } + + return current; + + case WB_MOVEWORDRIGHT: + case WB_RIGHT: + + // If we are already on a delimiter then just return the current index + if ( _tcschr ( delimiters, *(text + current * 2) ) ) + { + return current; + } + + // Run until we hit the end of the control + while ( current < max ) + { + // If we found a delimiter then return the index we are on + if ( _tcschr ( delimiters, *(text + current * 2) ) ) + { + return current; + } + + current++; + } + + return current; + } + + return 0; + } + +LRESULT CALLBACK rvDebuggerWindow::ScriptWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + static int lastStart = -1; + static int lastEnd = -1; + rvDebuggerWindow* window = (rvDebuggerWindow*)GetWindowLong ( wnd, GWL_USERDATA ); + WNDPROC wndproc = window->mOldScriptProc; + + switch ( msg ) + { + case WM_RBUTTONUP: + return SendMessage ( wnd, WM_LBUTTONUP, wparam, lparam ); + + case WM_RBUTTONDOWN: + { + POINT point = { LOWORD(lparam), HIWORD(lparam) }; + HMENU menu; + SendMessage ( wnd, WM_LBUTTONDOWN, wparam, lparam ); + menu = LoadMenu ( window->mInstance, MAKEINTRESOURCE(IDR_DBG_SCRIPT_POPUP) ); + ClientToScreen ( wnd, &point ); + TrackPopupMenu ( GetSubMenu( menu, 0 ), TPM_RIGHTBUTTON|TPM_LEFTALIGN, point.x, point.y, 0, window->mWnd, NULL ); + DestroyMenu ( menu ); + return 0; + } + + case WM_MOUSEMOVE: + { + // Figure out the start and end of the mouse is over + POINTL pos = {LOWORD(lparam),HIWORD(lparam)}; + int c = SendMessage ( wnd, EM_CHARFROMPOS, 0, (WPARAM)&pos ); + int start = SendMessage ( wnd, EM_FINDWORDBREAK, WB_LEFT, c ); + int end = SendMessage ( wnd, EM_FINDWORDBREAK, WB_RIGHT, c ); + + // If the start and the end of the word we are over havent changed + // then the word hasnt changed so no need to re-setup the tool tip + if ( lastStart == start && lastEnd == end ) + { + break; + } + + // Save the current start and end for the next mouse move + lastStart = start; + lastEnd = end; + + // Get rid of the last tool tip if there is one + if ( window->mTooltipVar.Length() ) + { + TOOLINFO ti; + ti.cbSize = sizeof(TOOLINFO); + ti.hwnd = wnd; + ti.uId = 0; + SendMessage ( window->mWndToolTips, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti ); + window->mTooltipVar.Empty ( ); + } + + // If there is no word then ignore it + if ( start == end ) + { + break; + } + + TEXTRANGE range; + TOOLINFO ti; + + // grab the actual word from the edit control + char* temp = new char[end-start+10]; + range.chrg.cpMin = start; + range.chrg.cpMax = end; + range.lpstrText = temp; + SendMessage ( wnd, EM_GETTEXTRANGE, 0, (LPARAM) &range ); + window->mTooltipVar = temp; + delete[] temp; + + // Request the variable's value from the debugger server + window->mClient->InspectVariable ( window->mTooltipVar.c_str(), window->mCurrentStackDepth ); + + // Prepare to add the new tooltip + ti.cbSize = sizeof(TOOLINFO); + ti.uFlags = TTF_SUBCLASS; + ti.hwnd = wnd; + ti.hinst = (HINSTANCE)GetModuleHandle(NULL); + ti.uId = 0; + ti.lpszText = (LPSTR)window->mTooltipVar.c_str(); + + // Calculate the bounding box around the word we are over. We do this + // by getting to the top left from the start character and the right side + // from the end character. The bottom is the top from the start character + // plus the height of one line + SendMessage ( wnd, EM_POSFROMCHAR, (WPARAM)&pos, start ); + ti.rect.left = pos.x; + ti.rect.top = pos.y; + SendMessage ( wnd, EM_POSFROMCHAR, (WPARAM)&pos, end ); + ti.rect.right = pos.x; + SendMessage ( wnd, EM_POSFROMCHAR, (WPARAM)&pos, SendMessage ( wnd, EM_LINEINDEX, 0, 0 ) ); + ti.rect.bottom = ti.rect.top - pos.y; + SendMessage ( wnd, EM_POSFROMCHAR, (WPARAM)&pos, SendMessage ( wnd, EM_LINEINDEX, 1, 0 ) ); + ti.rect.bottom = ti.rect.bottom + pos.y; + + // Add the new tool tip to the control + SendMessage ( window->mWndToolTips, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti ); + SendMessage ( window->mWndToolTips, TTM_UPDATE, 0, 0 ); + + break; + } + } + + return CallWindowProc ( wndproc, wnd, msg, wparam, lparam ); +} + +LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLong ( wnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_RBUTTONDOWN: + return SendMessage ( window->mWndScript, WM_RBUTTONDOWN, wparam, lparam ); + + case WM_RBUTTONUP: + return SendMessage ( window->mWndScript, WM_RBUTTONUP, wparam, lparam ); + + case WM_LBUTTONDBLCLK: + { + int result = SendMessage ( window->mWndScript, WM_LBUTTONDBLCLK, wparam, lparam ); + window->ToggleBreakpoint ( ); + return result; + } + + case WM_LBUTTONDOWN: + { + int result = SendMessage ( window->mWndScript, WM_LBUTTONDOWN, wparam, lparam ); + window->ToggleBreakpoint ( ); + return result; + } + + case WM_LBUTTONUP: + return SendMessage ( window->mWndScript, WM_LBUTTONUP, wparam, lparam ); + + case WM_PAINT: + { + HDC dc; + + int size = window->mMarginSize - 2; + + PAINTSTRUCT ps; + RECT rect; + GetClientRect ( wnd, &rect ); + dc = BeginPaint ( wnd, &ps ); + FillRect ( dc, &rect, GetSysColorBrush ( COLOR_3DFACE ) ); + + if ( window->mScripts.Num ( ) ) + { + for ( int i = 0; i < window->mClient->GetBreakpointCount(); i ++ ) + { + rvDebuggerBreakpoint* bp = window->mClient->GetBreakpoint ( i ); + assert( bp ); + + if ( !idStr::Icmp ( window->mScripts[window->mActiveScript]->GetFilename ( ), bp->GetFilename ( ) ) ) + { + int c; + POINTL pos; + + c = SendMessage ( window->mWndScript, EM_LINEINDEX, bp->GetLineNumber ( ) - 1, 0 ); + SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c ); + ImageList_DrawEx ( window->mImageList, 2, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL ); + } + } + + if ( window->mClient->IsStopped ( ) ) + { + if ( !idStr::Icmp ( window->mClient->GetBreakFilename(), + window->mScripts[window->mActiveScript]->GetFilename ( ) ) ) + { + int c; + POINTL pos; + + c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetBreakLineNumber() - 1, 0 ); + SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c ); + ImageList_DrawEx ( window->mImageList, 3, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL ); + } + } + + if ( window->mCurrentStackDepth != 0 ) + { + if ( !window->mClient->GetCallstack()[window->mCurrentStackDepth]->mFilename.Icmp ( window->mScripts[window->mActiveScript]->GetFilename ( ) ) ) + { + int c; + POINTL pos; + + c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetCallstack()[window->mCurrentStackDepth]->mLineNumber - 1, 0 ); + SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c ); + ImageList_DrawEx ( window->mImageList, 1, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL ); + } + } + } + + rect.right-=2; + rect.left = rect.right + 1; + HPEN pen = CreatePen ( PS_SOLID, 1, GetSysColor ( COLOR_3DSHADOW ) ); + HPEN old = (HPEN)SelectObject ( dc, pen ); + MoveToEx ( dc, rect.right, rect.top, NULL ); + LineTo ( dc, rect.right, rect.bottom ); + SelectObject ( dc, old ); + DeleteObject ( pen ); + EndPaint ( wnd, &ps ); + break; + } + } + + return DefWindowProc ( wnd, msg, wparam, lparam ); +} + +/* +================ +rvDebuggerWindow::UpdateTitle + +Updates the window title of the script debugger to show a few states +================ +*/ +void rvDebuggerWindow::UpdateTitle ( void ) +{ + idStr title; + + title = "Quake 4 Script Debugger - "; + + if ( mClient->IsConnected ( ) ) + { + if ( mClient->IsStopped ( ) ) + { + title += "[break]"; + } + else + { + title += "[run]"; + } + } + else + { + title += "[disconnected]"; + } + + if ( mScripts.Num ( ) ) + { + title += " - ["; + title += idStr( mScripts[mActiveScript]->GetFilename() ).StripPath ( ); + title += "]"; + } + + SetWindowText ( mWnd, title ); +} + +/* +================ +rvDebuggerWindow::UpdateScript + +Updates the edit window to contain the current script +================ +*/ +void rvDebuggerWindow::UpdateScript ( void ) +{ + UpdateTitle ( ); + + // Dont reupdate if the given active script is the one being displayed. + if ( mActiveScript == mLastActiveScript ) + { + return; + } + + mLastActiveScript = mActiveScript; + + // Show and hide the script window depending on whether or not + // there are loaded scripts + if ( mScripts.Num ( ) < 1 ) + { + ShowWindow ( mWndScript, SW_HIDE ); + return; + } + else + { + ShowWindow ( mWndScript, SW_SHOW ); + } + + // Update the script + SendMessage ( mWndScript, EM_SETSEL, 0, -1 ); + SendMessage ( mWndScript, EM_REPLACESEL, 0, (LPARAM)"" ); + SendMessage ( mWndScript, EM_SETSEL, 0, -1 ); + SendMessage ( mWndScript, EM_REPLACESEL, 0, (LPARAM)mScripts[mActiveScript]->GetContents ( ) ); +} + +/* +================ +rvDebuggerWindow::UpdateWindowMenu + +Updates the windows displayed in the window menu +================ +*/ +void rvDebuggerWindow::UpdateWindowMenu ( void ) +{ + while ( GetMenuItemCount ( mWindowMenu ) > mWindowMenuPos ) + { + DeleteMenu ( mWindowMenu, mWindowMenuPos, MF_BYPOSITION ); + } + + if ( mScripts.Num() ) + { + AppendMenu ( mWindowMenu, MF_SEPARATOR, 0, "" ); + } + + int i; + for ( i = 0; i < mScripts.Num(); i ++ ) + { + idStr name; + name = mScripts[i]->GetFilename ( ); + name.StripPath ( ); + name = idStr(va("&%d ", i + 1 )) + name; + AppendMenu ( mWindowMenu, MF_STRING, ID_DBG_WINDOWMIN + i, name ); + } +} + +/* +================ +rvDebuggerWindow::UpdateCallstack + +Updates the contents of teh callastack +================ +*/ +void rvDebuggerWindow::UpdateCallstack ( void ) +{ + LVITEM item; + ListView_DeleteAllItems ( mWndCallstack ); + ZeroMemory ( &item, sizeof(item) ); + item.mask = LVIF_TEXT|LVIF_IMAGE; + + for ( int i = 0; i < mClient->GetCallstack().Num(); i ++ ) + { + rvDebuggerCallstack* entry = mClient->GetCallstack()[i]; + item.iItem = ListView_GetItemCount ( mWndCallstack ); + item.pszText = ""; + item.iImage = (i == mCurrentStackDepth) ? 1 : 0; + ListView_InsertItem ( mWndCallstack, &item ); + + ListView_SetItemText ( mWndCallstack, item.iItem, 1, (LPSTR)entry->mFunction.c_str() ); + ListView_SetItemText ( mWndCallstack, item.iItem, 2, va("%d", entry->mLineNumber ) ); + ListView_SetItemText ( mWndCallstack, item.iItem, 3, (LPSTR)entry->mFilename.c_str() ); + } +} + +/* +================ +rvDebuggerWindow::UpdateWatch + +Updates the contents of the watch window +================ +*/ +void rvDebuggerWindow::UpdateWatch ( void ) +{ + int i; + + // Inspect all the variables we are watching + for ( i = 0; i < mWatches.Num(); i ++ ) + { + mWatches[i]->mModified = false; + mClient->InspectVariable ( mWatches[i]->mVariable, mCurrentStackDepth ); + } + + InvalidateRect ( mWndWatch, NULL, FALSE ); + UpdateWindow ( mWndWatch ); +} + +/* +================ +rvDebuggerWindow::HandleInitMenu + +Handles the initialization of the main menu +================ +*/ +int rvDebuggerWindow::HandleInitMenu ( WPARAM wParam, LPARAM lParam ) +{ + int cMenuItems = GetMenuItemCount((HMENU)wParam); + int nPos; + int id; + UINT flags; + HMENU hmenu; + + hmenu = (HMENU) wParam; + + // Run through all the menu items in the menu and see if any of them need + // modification in any way + for (nPos = 0; nPos < cMenuItems; nPos++) + { + id = GetMenuItemID(hmenu, nPos); + flags = 0; + + // Handle popup menus too + if ( id < 0 ) + { + HMENU sub = GetSubMenu ( hmenu, nPos ); + if ( sub ) + { + HandleInitMenu ( (WPARAM) sub, 0 ); + continue; + } + } + + // Handle the dynamic menu items specially + if ( id >= ID_DBG_WINDOWMIN && id <= ID_DBG_WINDOWMAX ) + { + if ( id - ID_DBG_WINDOWMIN == mActiveScript ) + { + CheckMenuItem ( hmenu, nPos, MF_BYPOSITION|MF_CHECKED ); + } + else + { + CheckMenuItem ( hmenu, nPos, MF_BYPOSITION|MF_UNCHECKED ); + } + continue; + } + + // Menu items that are completely unrelated to the workspace + switch ( id ) + { + case ID_DBG_DEBUG_RUN: + { + MENUITEMINFO info; + idStr run; + + info.cbSize = sizeof(info); + info.fMask = MIIM_TYPE|MIIM_STATE; + info.fType = MFT_STRING; + + if ( !mClient->IsConnected() ) + { + run = "Run"; + info.fState = MFS_ENABLED; + } + else + { + run = "Continue"; + info.fState = mClient->IsStopped()?MFS_ENABLED:MFS_GRAYED; + } + + info.dwTypeData = (LPSTR)run.c_str(); + info.cch = run.Length ( ); + + SendMessage ( mWndToolbar, TB_ENABLEBUTTON, id, MAKELONG(((info.fState==MFS_ENABLED) ? TRUE : FALSE), 0) ); + + SetMenuItemInfo ( hmenu, id, FALSE, &info ); + + break; + } + + case ID_DBG_DEBUG_BREAK: + if ( !mClient->IsConnected() || mClient->IsStopped() ) + { + EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION); + SendMessage ( mWndToolbar, TB_ENABLEBUTTON, id, MAKELONG(FALSE,0) ); + } + else + { + EnableMenuItem ( hmenu, nPos, MF_ENABLED|MF_BYPOSITION); + SendMessage ( mWndToolbar, TB_ENABLEBUTTON, id, MAKELONG(TRUE,0) ); + } + break; + + case ID_DBG_DEBUG_RUNTOCURSOR: + case ID_DBG_DEBUG_STEPOUT: + case ID_DBG_DEBUG_STEPOVER: + case ID_DBG_DEBUG_STEPINTO: + case ID_DBG_DEBUG_SHOWNEXTSTATEMENT: +// case ID_DBG_DEBUG_QUICKWATCH: + if ( !mClient->IsConnected() || !mClient->IsStopped() ) + { + EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION ); + SendMessage ( mWndToolbar, TB_ENABLEBUTTON, id, MAKELONG(FALSE,0) ); + } + else + { + EnableMenuItem ( hmenu, nPos, MF_ENABLED|MF_BYPOSITION ); + SendMessage ( mWndToolbar, TB_ENABLEBUTTON, id, MAKELONG(TRUE,0) ); + } + break; + + case ID_DBG_WINDOW_CLOSEALL: + case ID_DBG_FILE_CLOSE: + case ID_DBG_DEBUG_TOGGLEBREAKPOINT: + case ID_DBG_EDIT_FIND: + EnableMenuItem ( hmenu, nPos, (mScripts.Num()?MF_ENABLED:MF_GRAYED)|MF_BYPOSITION); + break; + } + } + + return 0; +} + +/* +================ +rvDebuggerWindow::HandleCreate + +Handles the WM_CREATE command +================ +*/ +int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam ) +{ + UINT tabsize = 16; + TEXTMETRIC tm; + HDC dc; + LOGFONT lf; + int i; + + gDebuggerApp.GetOptions().GetWindowPlacement ( "wp_main", mWnd ); + + // Create the main toolbar + CreateToolbar ( ); + + // Create the script window + LoadLibrary ( "Riched20.dll" ); + mWndScript = CreateWindow ( "RichEdit20A", "", WS_CHILD|WS_BORDER|ES_NOHIDESEL|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_SCRIPT, mInstance, 0 ); + SendMessage ( mWndScript, EM_SETEVENTMASK, 0, ENM_SCROLL|ENM_CHANGE ); + SendMessage ( mWndScript, EM_SETWORDBREAKPROC, 0, (LPARAM) ScriptWordBreakProc ); + mOldScriptProc = (WNDPROC)GetWindowLong ( mWndScript, GWL_WNDPROC ); + SetWindowLong ( mWndScript, GWL_USERDATA, (LONG)this ); + SetWindowLong ( mWndScript, GWL_WNDPROC, (LONG)ScriptWndProc ); + + SendMessage ( mWndScript, EM_SETTABSTOPS, 1, (LPARAM)&tabsize ); + + dc = GetDC ( mWndScript ); + GetTextMetrics ( dc, &tm ); + ZeroMemory ( &lf, sizeof(lf) ); + lf.lfHeight = tm.tmHeight; + strcpy ( lf.lfFaceName, "Courier New" ); + + SendMessage ( mWndScript, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + SendMessage ( mWndScript, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) ); + SendMessage ( mWndScript, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) ); + + mWndOutput = CreateWindow ( "RichEdit20A", "", WS_CHILD|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_OUTPUT, mInstance, 0 ); + SendMessage ( mWndOutput, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + SendMessage ( mWndOutput, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) ); + SendMessage ( mWndOutput, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) ); + + mWndConsole = CreateWindow ( "RichEdit20A", "", WS_CHILD|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_CONSOLE, mInstance, 0 ); + SendMessage ( mWndConsole, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + SendMessage ( mWndConsole, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) ); + SendMessage ( mWndConsole, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) ); + + mWndMargin = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD, 0, 0, 0, 0, mWndScript, (HMENU)IDC_DBG_SPLITTER, mInstance, NULL ); + SetWindowLong ( mWndMargin, GWL_USERDATA, (LONG)this ); + SetWindowLong ( mWndMargin, GWL_WNDPROC, (LONG)MarginWndProc ); + + mWndBorder = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD|SS_GRAYFRAME, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_BORDER, mInstance, NULL ); + + GetClientRect ( mWnd, &mSplitterRect ); + mSplitterRect.top = (mSplitterRect.bottom-mSplitterRect.top) / 2; + mSplitterRect.bottom = mSplitterRect.top + 4; + + mWndTabs = CreateWindow ( WC_TABCONTROL, "", TCS_BOTTOM|WS_CHILD|WS_VISIBLE|TCS_FOCUSNEVER, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_TABS, mInstance, NULL ); + lf.lfHeight = -MulDiv(8, GetDeviceCaps(dc, LOGPIXELSY), 72); + strcpy ( lf.lfFaceName, "Arial" ); + SendMessage ( mWndTabs, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + ReleaseDC ( mWndScript, dc ); + + TCITEM item; + item.mask = TCIF_TEXT; + item.pszText = "Output"; + TabCtrl_InsertItem ( mWndTabs, 0, &item ); + item.pszText = "Console"; + TabCtrl_InsertItem ( mWndTabs, 1, &item ); + item.pszText = "Call Stack"; + TabCtrl_InsertItem ( mWndTabs, 2, &item ); + item.pszText = "Watch"; + TabCtrl_InsertItem ( mWndTabs, 3, &item ); + item.pszText = "Threads"; + TabCtrl_InsertItem ( mWndTabs, 4, &item ); + + mWndCallstack = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_CALLSTACK, mInstance, NULL ); + mWndWatch = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_EDITLABELS|LVS_OWNERDRAWFIXED, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_WATCH, mInstance, NULL ); + mWndThreads = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_THREADS, mInstance, NULL ); + + LVCOLUMN col; + col.mask = LVCF_WIDTH|LVCF_TEXT; + col.cx = 20; + col.pszText = ""; + ListView_InsertColumn ( mWndCallstack, 0, &col ); + col.cx = 150; + col.pszText = "Function"; + ListView_InsertColumn ( mWndCallstack, 1, &col ); + col.cx = 150; + col.pszText = "Line"; + ListView_InsertColumn ( mWndCallstack, 2, &col ); + col.cx = 150; + col.pszText = "Filename"; + ListView_InsertColumn ( mWndCallstack, 3, &col ); + + col.cx = 20; + col.pszText = ""; + ListView_InsertColumn ( mWndThreads, 0, &col ); + col.cx = 25; + col.pszText = "ID"; + ListView_InsertColumn ( mWndThreads, 1, &col ); + col.cx = 150; + col.pszText = "Name"; + ListView_InsertColumn ( mWndThreads, 2, &col ); + col.cx = 100; + col.pszText = "State"; + ListView_InsertColumn ( mWndThreads, 3, &col ); + + col.cx = 150; + col.pszText = "Name"; + ListView_InsertColumn ( mWndWatch, 0, &col ); + col.cx = 200; + col.pszText = "Value"; + ListView_InsertColumn ( mWndWatch, 1, &col ); + + // Create the image list that is used by the threads window, callstack window, and + // margin window + mImageList = ImageList_Create ( 16, 16, ILC_COLOR|ILC_MASK, 0, 2 ); + ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_EMPTY), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) ); + ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) ); + ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_BREAKPOINT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) ); + ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENTLINE), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) ); + ListView_SetImageList ( mWndThreads, mImageList, LVSIL_SMALL ); + ListView_SetImageList ( mWndCallstack, mImageList, LVSIL_SMALL ); + + EnableWindows ( FALSE ); + + ListView_SetExtendedListViewStyle ( mWndCallstack, LVS_EX_FULLROWSELECT ); + ListView_SetExtendedListViewStyle ( mWndThreads, LVS_EX_FULLROWSELECT ); + + gDebuggerApp.GetOptions().GetColumnWidths ( "cw_callstack", mWndCallstack ); + gDebuggerApp.GetOptions().GetColumnWidths ( "cw_threads", mWndThreads ); + gDebuggerApp.GetOptions().GetColumnWidths ( "cw_watch", mWndWatch ); + + mWndToolTips = CreateWindowEx ( WS_EX_TOPMOST, + TOOLTIPS_CLASS, + NULL, + WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + mWnd, + NULL, + mInstance, + NULL + ); + + SendMessage ( mWndToolTips, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELONG(400,0) ); + SendMessage ( mWndToolTips, TTM_SETDELAYTIME, TTDT_RESHOW, MAKELONG(400,0) ); + + SetWindowPos( mWndToolTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + LVITEM lvItem; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + lvItem.mask = LVIF_TEXT; + lvItem.pszText = ""; + ListView_InsertItem ( mWndWatch, &lvItem ); + ListView_SetExtendedListViewStyle ( mWndWatch, LVS_EX_FULLROWSELECT ); + + // Recent files + InitRecentFiles ( ); + UpdateRecentFiles ( ); + + HandleInitMenu ( (WPARAM)GetMenu ( mWnd ), 0 ); + + // Read in the watches + for ( i = 0; ; i ++ ) + { + const char* s = gDebuggerApp.GetOptions().GetString ( va("watch%d", i ) ); + if ( !s || !s[0] ) + { + break; + } + + AddWatch ( s ); + } + + return 0; +} + +/* +================ +rvDebuggerWindow::HandleCommand + +Handles the WM_COMMAND message for this window +================ +*/ +int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam ) +{ + int event = HIWORD(wparam); + int id = LOWORD(wparam); + + // The window menu list needs to be handled specially + if ( id >= ID_DBG_WINDOWMIN && id <= ID_DBG_WINDOWMAX ) + { + mActiveScript = id - ID_DBG_WINDOWMIN; + UpdateScript ( ); + return 0; + } + + // The recent file list needs to be handled specially + if ( LOWORD(wparam) >= ID_DBG_FILE_MRU1 && LOWORD(wparam) < ID_DBG_FILE_MRU1 + rvRegistryOptions::MAX_MRU_SIZE ) + { + idStr filename; + filename = gDebuggerApp.GetOptions().GetRecentFile ( gDebuggerApp.GetOptions().GetRecentFileCount() - (LOWORD(wparam)-ID_DBG_FILE_MRU1) - 1 ); + if ( !OpenScript ( filename ) ) + { + MessageBox ( mWnd, va("Failed to open script '%s'", filename.c_str() ), "Quake 4 Script Debugger", MB_OK ); + } + return 0; + } + + switch ( id ) + { + case ID_DBG_EDIT_FINDSELECTED: + { + idStr text; + GetSelectedText ( text ); + FindNext ( text ); + break; + } + + case ID_DBG_EDIT_FINDSELECTEDPREV: + { + idStr text; + GetSelectedText ( text ); + FindPrev ( text ); + break; + } + + case ID_DBG_EDIT_FINDNEXT: + FindNext ( ); + break; + + case ID_DBG_EDIT_FINDPREV: + FindPrev ( ); + break; + + case ID_DBG_DEBUG_QUICKWATCH: + { + idStr text; + + GetSelectedText ( text ); + rvDebuggerQuickWatchDlg dlg; + dlg.DoModal ( this, mCurrentStackDepth, text ); + break; + } + + case ID_DBG_HELP_ABOUT: + DialogBox ( mInstance, MAKEINTRESOURCE(IDD_DBG_ABOUT), mWnd, AboutDlgProc ); + break; + + case ID_DBG_DEBUG_BREAK: + mClient->Break ( ); + break; + + case ID_DBG_DEBUG_STEPOVER: + EnableWindows ( FALSE ); + mClient->StepOver ( ); + break; + + case ID_DBG_DEBUG_STEPINTO: + EnableWindows ( FALSE ); + mClient->StepInto ( ); + break; + + case ID_DBG_DEBUG_RUN: + // Run the game if its not running + if ( !mClient->IsConnected ( ) ) + { + char exeFile[MAX_PATH]; + char curDir[MAX_PATH]; + + STARTUPINFO startup; + PROCESS_INFORMATION process; + + ZeroMemory ( &startup, sizeof(startup) ); + startup.cb = sizeof(startup); + + GetCurrentDirectory ( MAX_PATH, curDir ); + + GetModuleFileName ( NULL, exeFile, MAX_PATH ); + const char* s = va("%s +set fs_game %s +set fs_cdpath %s", exeFile, cvarSystem->GetCVarString( "fs_game" ), cvarSystem->GetCVarString( "fs_cdpath" ) ); + CreateProcess ( NULL, (LPSTR)s, + NULL, NULL, FALSE, 0, NULL, curDir, &startup, &process ); + + CloseHandle ( process.hThread ); + CloseHandle ( process.hProcess ); + } + else if ( mClient->IsStopped() ) + { + EnableWindows ( FALSE ); + mClient->Resume ( ); + UpdateToolbar ( ); + UpdateTitle ( ); + InvalidateRect ( mWnd, NULL, FALSE ); + } + + break; + + case IDC_DBG_SCRIPT: + { + RECT t; + LONG num; + LONG dem; + + SendMessage ( mWndScript, EM_GETZOOM, (LONG)&num, (LONG)&dem ); + if ( num != mZoomScaleNum || dem != mZoomScaleDem ) + { + mZoomScaleNum = num; + mZoomScaleDem = dem; + GetClientRect ( mWndScript, &t ); + SendMessage ( mWnd, WM_SIZE, 0, MAKELPARAM(t.right-t.left,t.bottom-t.top) ); + } + else + { + InvalidateRect ( mWndMargin, NULL, TRUE ); + } + break; + } + + case ID_DBG_DEBUG_TOGGLEBREAKPOINT: + ToggleBreakpoint ( ); + break; + + case ID_DBG_FILE_EXIT: + PostMessage ( mWnd, WM_CLOSE, 0, 0 ); + break; + + case ID_DBG_FILE_CLOSE: + if ( mScripts.Num() ) + { + delete mScripts[mActiveScript]; + mScripts.RemoveIndex ( mActiveScript ); + if ( mActiveScript >= mScripts.Num ( ) ) + { + mActiveScript --; + } + UpdateWindowMenu ( ); + UpdateScript ( ); + } + break; + + case ID_DBG_FILE_NEXT: + if ( mScripts.Num ( ) > 0 ) + { + mActiveScript++; + if ( mActiveScript >= mScripts.Num ( ) ) + { + mActiveScript = 0; + } + UpdateWindowMenu ( ); + UpdateScript ( ); + } + break; + + case ID_DBG_FILE_OPEN: + { + rvOpenFileDialog dlg; + dlg.SetTitle ( "Open Script" ); + dlg.SetFilter ( "*.script; *.gui; *.state" ); + dlg.SetFlags ( OFD_MUSTEXIST ); + if ( dlg.DoModal ( mWnd ) ) + { + if ( !OpenScript ( dlg.GetFilename ( ) ) ) + { + MessageBox ( mWnd, va("Failed to open script '%s'",dlg.GetFilename ( )), "Quake 4 Script Debugger", MB_OK ); + } + } + break; + } + + case ID_DBG_EDIT_FIND: + { + rvDebuggerFindDlg dlg; + if ( dlg.DoModal ( this ) ) + { + FindNext ( dlg.GetFindText ( ) ); + } + break; + } + + case ID_DBG_WINDOW_CLOSEALL: + { + for ( int i = 0; i < mScripts.Num(); i ++ ) + { + delete mScripts[i]; + } + + mScripts.Clear ( ); + mActiveScript = -1; + + UpdateWindowMenu ( ); + UpdateScript ( ); + break; + } + } + + return 0; +} + +/* +================ +rvDebuggerWindow::WndProc + +Window procedure for the deubgger window +================ +*/ +LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLong ( wnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_INITMENUPOPUP: + window->HandleInitMenu ( wparam, lparam ); + break; + + case WM_DESTROY: + { + gDebuggerApp.GetOptions().SetColumnWidths ( "cw_callstack", window->mWndCallstack ); + gDebuggerApp.GetOptions().SetColumnWidths ( "cw_threads", window->mWndThreads ); + gDebuggerApp.GetOptions().SetColumnWidths ( "cw_watch", window->mWndWatch ); + gDebuggerApp.GetOptions().SetWindowPlacement ( "wp_main", wnd ); + + int i; + for ( i = 0; i < window->mWatches.Num ( ); i ++ ) + { + gDebuggerApp.GetOptions().SetString ( va("watch%d", i ), window->mWatches[i]->mVariable ); + } + gDebuggerApp.GetOptions().SetString ( va("watch%d", i ), "" ); + + window->mWnd = NULL; + SetWindowLong ( wnd, GWL_USERDATA, 0 ); + break; + } + + case WM_ERASEBKGND: + return 0; + + case WM_COMMAND: + window->HandleCommand ( wparam, lparam ); + break; + + case WM_SETCURSOR: + { + POINT point; + GetCursorPos ( &point ); + ScreenToClient ( wnd, &point ); + if ( PtInRect ( &window->mSplitterRect, point ) ) + { + SetCursor ( LoadCursor ( NULL, IDC_SIZENS ) ); + return true; + } + break; + } + + case WM_SIZE: + { + RECT rect; + window->mMarginSize = window->mZoomScaleDem ? ((long)(18.0f * (float)window->mZoomScaleNum / (float)window->mZoomScaleDem)):18; + window->mSplitterRect.left = 0; + window->mSplitterRect.right = LOWORD(lparam); + + SendMessage ( window->mWndToolbar, TB_AUTOSIZE, 0, 0 ); + GetWindowRect ( window->mWndToolbar, &rect ); + MoveWindow ( window->mWndScript, 0, rect.bottom-rect.top, LOWORD(lparam), window->mSplitterRect.top-(rect.bottom-rect.top), TRUE ); + MoveWindow ( window->mWndMargin, 0, 0, window->mMarginSize, window->mSplitterRect.top-(rect.bottom-rect.top), TRUE ); + + SetRect ( &rect, 0, window->mSplitterRect.bottom, LOWORD(lparam), HIWORD(lparam) ); + MoveWindow ( window->mWndTabs, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + SendMessage ( window->mWndTabs, TCM_ADJUSTRECT, FALSE, (LPARAM)&rect ); + rect.bottom -= 4 ; + MoveWindow ( window->mWndBorder, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + InflateRect ( &rect, -1, -1 ); + MoveWindow ( window->mWndOutput, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + MoveWindow ( window->mWndConsole, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + MoveWindow ( window->mWndCallstack, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + MoveWindow ( window->mWndWatch, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + MoveWindow ( window->mWndThreads, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE ); + break; + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC dc = BeginPaint ( wnd, &ps ); + FillRect ( dc, &window->mSplitterRect, GetSysColorBrush ( COLOR_3DFACE ) ); + + if ( !window->mScripts.Num() ) + { + RECT rect; + GetClientRect ( wnd, &rect ); + rect.bottom = window->mSplitterRect.top; + FillRect ( dc, &rect, GetSysColorBrush ( COLOR_APPWORKSPACE ) ); + } + + EndPaint ( wnd, &ps ); + break; + } + + case WM_LBUTTONDOWN: + { + POINT pt = { LOWORD(lparam),HIWORD(lparam) }; + if ( PtInRect ( &window->mSplitterRect, pt ) ) + { + window->mSplitterDrag = true; + SetCapture ( wnd ); + + HDC dc = GetDC ( wnd ); + DrawFocusRect ( dc, &window->mSplitterRect ); + ReleaseDC ( wnd, dc ); + } + break; + } + + case WM_LBUTTONUP: + if ( window->mSplitterDrag ) + { + HDC dc = GetDC ( wnd ); + DrawFocusRect ( dc, &window->mSplitterRect ); + ReleaseDC ( wnd, dc ); + + window->mSplitterDrag = false; + + RECT client; + GetClientRect ( wnd, &client ); + SendMessage ( wnd, WM_SIZE, 0, MAKELPARAM(client.right-client.left,client.bottom-client.top) ); + + InvalidateRect ( wnd, NULL, TRUE ); + + ReleaseCapture ( ); + } + break; + + case WM_MOUSEMOVE: + { + if ( window->mSplitterDrag ) + { + HDC dc = GetDC ( wnd ); + DrawFocusRect ( dc, &window->mSplitterRect ); + ReleaseDC ( wnd, dc ); + + if ( GetCapture ( ) != wnd ) + { + break; + } + + RECT client; + GetClientRect ( wnd, &client ); + + window->mSplitterRect.top = HIWORD(lparam); + if ( window->mSplitterRect.top < client.top ) + { + window->mSplitterRect.top = client.top; + } + else if ( window->mSplitterRect.top + 4 > client.bottom ) + { + window->mSplitterRect.top = client.bottom - 4; + } + window->mSplitterRect.bottom = window->mSplitterRect.top + 4; + + dc = GetDC ( wnd ); + DrawFocusRect ( dc, &window->mSplitterRect ); + ReleaseDC ( wnd, dc ); + } + break; + } + + case WM_DRAWITEM: + window->HandleDrawItem ( wparam, lparam ); + break; + + case WM_CREATE: + { + CREATESTRUCT* cs = (CREATESTRUCT*) lparam; + window = (rvDebuggerWindow*) cs->lpCreateParams; + SetWindowLong ( wnd, GWL_USERDATA, (LONG)cs->lpCreateParams ); + + window->mWnd = wnd; + window->HandleCreate ( wparam, lparam ); + + break; + } + + case WM_ACTIVATE: + window->HandleActivate ( wparam, lparam ); + break; + + case WM_NOTIFY: + { + NMHDR* hdr; + hdr = (NMHDR*)lparam; + + // Tool tips + if ( hdr->code == TTN_GETDISPINFO ) + { + window->HandleTooltipGetDispInfo ( wparam, lparam ); + break; + } + + switch ( hdr->idFrom ) + { + case IDC_DBG_WATCH: + switch ( hdr->code ) + { + case LVN_KEYDOWN: + { + NMLVKEYDOWN* key = (NMLVKEYDOWN*) hdr; + switch ( key->wVKey ) + { + case VK_DELETE: + { + int sel = ListView_GetNextItem ( hdr->hwndFrom, -1, LVNI_SELECTED ); + if ( sel != -1 && sel != ListView_GetItemCount ( hdr->hwndFrom ) - 1 ) + { + LVITEM item; + item.iItem = sel; + item.mask = LVIF_PARAM; + ListView_GetItem ( hdr->hwndFrom, &item ); + ListView_DeleteItem ( hdr->hwndFrom, sel ); + + window->mWatches.Remove ( (rvDebuggerWatch*)item.lParam ); + delete (rvDebuggerWatch*)item.lParam; + + ListView_SetItemState ( hdr->hwndFrom, + sel, + LVIS_SELECTED, LVIS_SELECTED ); + + if ( ListView_GetNextItem ( hdr->hwndFrom, -1, LVNI_SELECTED ) == -1 ) + { + ListView_SetItemState ( hdr->hwndFrom, + ListView_GetItemCount ( hdr->hwndFrom ) - 1, + LVIS_SELECTED, LVIS_SELECTED ); + } + } + break; + } + + case VK_RETURN: + { + int sel = ListView_GetNextItem ( hdr->hwndFrom, -1, LVNI_SELECTED ); + if ( sel != -1 ) + { + ListView_EditLabel ( hdr->hwndFrom, sel ); + } + break; + } + } + break; + } + + case LVN_BEGINLABELEDIT: + { + NMLVDISPINFO* di = (NMLVDISPINFO*)hdr; + + DWORD style = GetWindowLong ( ListView_GetEditControl ( hdr->hwndFrom ), GWL_STYLE ); + SetWindowLong ( ListView_GetEditControl ( hdr->hwndFrom ), GWL_STYLE, style & (~WS_BORDER) ); + + rvDebuggerWatch* watch = (rvDebuggerWatch*)di->item.lParam; + if ( watch ) + { + SetWindowText ( ListView_GetEditControl ( hdr->hwndFrom ), watch->mVariable ); + } + + return FALSE; + } + + case LVN_ENDLABELEDIT: + { + NMLVDISPINFO* di = (NMLVDISPINFO*)hdr; + + if ( di->item.iItem == ListView_GetItemCount ( hdr->hwndFrom ) - 1 ) + { + if ( !di->item.pszText || !di->item.pszText[0] ) + { + return FALSE; + } + + window->AddWatch ( ((NMLVDISPINFO*)hdr)->item.pszText ); + window->UpdateWatch ( ); + return FALSE; + } + else + { + rvDebuggerWatch* watch = (rvDebuggerWatch*) di->item.lParam; + if ( watch && di->item.pszText && di->item.pszText[0] ) + { + watch->mVariable = di->item.pszText; + } + } + + return TRUE; + } + } + break; + + case IDC_DBG_CALLSTACK: + if ( hdr->code == NM_DBLCLK ) + { + int sel = ListView_GetNextItem ( hdr->hwndFrom, -1, LVNI_SELECTED ); + if ( sel != -1 ) + { + window->mCurrentStackDepth = sel; + window->UpdateCallstack ( ); + window->UpdateWatch ( ); + window->OpenScript ( window->mClient->GetCallstack()[window->mCurrentStackDepth]->mFilename, + window->mClient->GetCallstack()[window->mCurrentStackDepth]->mLineNumber ); + } + } + break; + case IDC_DBG_TABS: + if ( hdr->code == TCN_SELCHANGE ) + { + ShowWindow ( window->mWndOutput, SW_HIDE ); + ShowWindow ( window->mWndConsole, SW_HIDE ); + ShowWindow ( window->mWndCallstack, SW_HIDE ); + ShowWindow ( window->mWndWatch, SW_HIDE ); + ShowWindow ( window->mWndThreads, SW_HIDE ); + switch ( TabCtrl_GetCurSel ( hdr->hwndFrom ) ) + { + case 0: + ShowWindow ( window->mWndOutput, SW_SHOW ); + break; + + case 1: + ShowWindow ( window->mWndConsole, SW_SHOW ); + break; + + case 2: + ShowWindow ( window->mWndCallstack, SW_SHOW ); + break; + + case 3: + ShowWindow ( window->mWndWatch, SW_SHOW ); + break; + + case 4: + ShowWindow ( window->mWndThreads, SW_SHOW ); + break; + } + } + break; + } + break; + } + + case WM_CLOSE: + if ( window->mClient->IsConnected ( ) ) + { + if ( IDNO == MessageBox ( wnd, "The debugger is currently connected to a running version of the game. Are you sure you want to close now?", "Quake 4 Script Debugger", MB_YESNO|MB_ICONQUESTION ) ) + { + return 0; + } + } + PostQuitMessage ( 0 ); + break; + } + + return DefWindowProc ( wnd, msg, wparam, lparam ); +} + +/* +================ +rvDebuggerWindow::Activate + +Static method that will activate the currently running debugger. If one is found +and activated then true will be returned. +================ +*/ +bool rvDebuggerWindow::Activate ( void ) +{ + HWND find; + + find = FindWindow ( DEBUGGERWINDOWCLASS, NULL ); + if ( !find ) + { + return false; + } + + SetForegroundWindow ( find ); + + return true; +} + +/* +================ +rvDebuggerWindow::ProcessNetMessage + +Process an incoming network message +================ +*/ +void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg ) +{ + unsigned short command; + + command = (unsigned short)MSG_ReadShort ( msg ); + + switch ( command ) + { + case DBMSG_RESUMED: + UpdateTitle ( ); + UpdateToolbar ( ); + break; + + case DBMSG_INSPECTVARIABLE: + { + char temp[1024]; + char temp2[1024]; + int i; + + MSG_ReadShort ( msg ); + MSG_ReadString ( msg, temp, 1024 ); + MSG_ReadString ( msg, temp2, 1024 ); + if ( mTooltipVar.Icmp ( temp ) == 0 ) + { + mTooltipValue = temp2; + + TOOLINFO info; + info.cbSize = sizeof(info); + info.hwnd = mWndScript; + info.uId = 0; + info.hinst = mInstance; + info.lpszText = va("%s=%s", mTooltipVar.c_str(), mTooltipValue.c_str() ); + SendMessage ( mWndToolTips, TTM_UPDATETIPTEXT, 0, (LPARAM)&info ); + SendMessage ( mWndToolTips, TTM_UPDATE, 0, 0 ); + } + + // See if any of the watches were updated by this inspect + for ( i = 0; i < mWatches.Num(); i ++ ) + { + rvDebuggerWatch* watch = mWatches[i]; + + // See if the name matches the variable + if ( watch->mVariable.Cmp ( temp ) ) + { + continue; + } + + // Has the value changed? + if ( !watch->mValue.Cmp ( temp2 ) ) + { + continue; + } + + watch->mModified = true; + watch->mValue = temp2; + + // Find the list view item that is storing this watch info and redraw it + for ( int l = 0; l < ListView_GetItemCount(mWndWatch); l ++ ) + { + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = l; + ListView_GetItem ( mWndWatch, &item ); + if ( item.lParam == (LPARAM) watch ) + { + ListView_RedrawItems ( mWndWatch, l, l ); + UpdateWindow ( mWndWatch ); + break; + } + } + } + + break; + } + + case DBMSG_CONNECT: + case DBMSG_CONNECTED: + UpdateTitle ( ); + UpdateToolbar ( ); + Printf ( "Connected...\n" ); + break; + + case DBMSG_DISCONNECT: + UpdateTitle ( ); + UpdateToolbar ( ); + Printf ( "Disconnected...\n" ); + break; + + case DBMSG_PRINT: + SendMessage ( mWndConsole, EM_SETSEL, -1, -1 ); + SendMessage ( mWndConsole, EM_REPLACESEL, 0, (LPARAM)(const char*)(msg->data) + msg->readcount ); + SendMessage ( mWndConsole, EM_SCROLLCARET, 0, 0 ); + break; + + case DBMSG_BREAK: + { + Printf ( "Break: line=%d file='%s'\n", mClient->GetBreakLineNumber ( ), mClient->GetBreakFilename() ); + + mCurrentStackDepth = 0; + mClient->InspectVariable ( mTooltipVar, mCurrentStackDepth ); + UpdateWatch ( ); + EnableWindows ( TRUE ); + OpenScript ( mClient->GetBreakFilename(), mClient->GetBreakLineNumber() - 1 ); + UpdateTitle ( ); + UpdateToolbar ( ); + SetForegroundWindow ( mWnd ); + break; + } + + case DBMSG_INSPECTCALLSTACK: + { + UpdateCallstack ( ); + break; + } + + case DBMSG_INSPECTTHREADS: + { + LVITEM item; + ListView_DeleteAllItems ( mWndThreads ); + ZeroMemory ( &item, sizeof(item) ); + item.mask = LVIF_TEXT|LVIF_IMAGE; + + for ( int i = 0; i < mClient->GetThreads().Num(); i ++ ) + { + rvDebuggerThread* entry = mClient->GetThreads()[i]; + item.iItem = ListView_GetItemCount ( mWndThreads ); + item.pszText = ""; + item.iImage = entry->mCurrent ? 1 : 0; + ListView_InsertItem ( mWndThreads, &item ); + + ListView_SetItemText ( mWndThreads, item.iItem, 1, (LPSTR)va("%d", entry->mID) ); + ListView_SetItemText ( mWndThreads, item.iItem, 2, (LPSTR)entry->mName.c_str() ); + + if ( entry->mDying ) + { + ListView_SetItemText ( mWndThreads, item.iItem, 3, "Dying" ); + } + else if ( entry->mWaiting ) + { + ListView_SetItemText ( mWndThreads, item.iItem, 3, "Waiting" ); + } + else if ( entry->mDoneProcessing ) + { + ListView_SetItemText ( mWndThreads, item.iItem, 3, "Stopped" ); + } + else + { + ListView_SetItemText ( mWndThreads, item.iItem, 3, "Running" ); + } + } + break; + } + } +} + +/* +================ +rvDebuggerWindow::Printf + +Sends a formatted message to the output window +================ +*/ +void rvDebuggerWindow::Printf ( const char* fmt, ... ) +{ + va_list argptr; + char msg[4096]; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + SendMessage ( mWndOutput, EM_SETSEL, -1, -1 ); + SendMessage ( mWndOutput, EM_REPLACESEL, 0, (LPARAM)msg ); + SendMessage ( mWndOutput, EM_SCROLLCARET, 0, 0 ); +} + +/* +================ +rvDebuggerWindow::OpenScript + +Opens the script with the given filename and will scroll to the given line +number if one is specified +================ +*/ +bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber ) +{ + int i; + + SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ); + + mActiveScript = -1; + + // See if the script is already loaded + for ( i = 0; i < mScripts.Num(); i ++ ) + { + if ( !idStr::Icmp ( mScripts[i]->GetFilename ( ), filename ) ) + { + if ( mActiveScript != i ) + { + mActiveScript = i; + break; + } + } + } + + // If the script isnt open already then open it + if ( mActiveScript == -1 ) + { + rvDebuggerScript* script = new rvDebuggerScript; + + // Load the script + if ( !script->Load ( filename ) ) + { + delete script; + SetCursor ( LoadCursor ( NULL, IDC_ARROW ) ); + return false; + } + + gDebuggerApp.GetOptions().AddRecentFile ( filename ); + UpdateRecentFiles ( ); + + mActiveScript = mScripts.Append ( script ); + } + + // Test code that will place a breakpoint on all valid lines of code +#if 0 + + for ( i = 0; i < mScripts[mActiveScript]->GetProgram().NumStatements(); i ++ ) + { + dstatement_t* st = &mScripts[mActiveScript]->GetProgram().GetStatement ( i ); + rvDebuggerBreakpoint* bp = new rvDebuggerBreakpoint ( filename, st->linenumber ); + mBreakpoints.Append ( bp ); + } + +#endif + + UpdateScript ( ); + UpdateWindowMenu ( ); + + // Move to a specific line number? + if ( lineNumber != -1 ) + { + int c; + + // Put the caret on the line number specified and scroll it into position. + // This is a bit of a hack since we set the selection twice, but setting the + // selection to (c,c) didnt work for scrolling the caret so we do (c,c+1) + // and then scroll before going back to (c,c). + // NOTE: We scroll to the line before the one we want so its more visible + SetFocus ( mWndScript ); + c = SendMessage ( mWndScript, EM_LINEINDEX, lineNumber - 1, 0 ); + SendMessage ( mWndScript, EM_SETSEL, c, c + 1 ); + SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 ); + c = SendMessage ( mWndScript, EM_LINEINDEX, lineNumber, 0 ); + SendMessage ( mWndScript, EM_SETSEL, c, c ); + } + else + { + SendMessage ( mWndScript, EM_SETSEL, 0, 0 ); + } + + // Make sure the script window is visible + ShowWindow ( mWndScript, SW_SHOW ); + UpdateWindow ( mWndScript ); + + SetCursor ( LoadCursor ( NULL, IDC_ARROW ) ); + + return true; +} + +/* +================ +rvDebuggerWindow::ToggleBreakpoint + +Toggles the breakpoint on the current script line +================ +*/ +void rvDebuggerWindow::ToggleBreakpoint ( void ) +{ + rvDebuggerBreakpoint* bp; + DWORD sel; + int line; + + // Find the currently selected line + SendMessage ( mWndScript, EM_GETSEL, (WPARAM)&sel, 0 ); + line = SendMessage ( mWndScript, EM_LINEFROMCHAR, sel, 0 ) + 1; + + // If there is already a breakpoint there then just remove it, otherwise + // we need to create a new breakpoint + bp = mClient->FindBreakpoint ( mScripts[mActiveScript]->GetFilename ( ), line ); + if ( !bp ) + { + // Make sure the line is code before letting them add a breakpoint there + if ( !mScripts[mActiveScript]->IsLineCode ( line ) ) + { + MessageBeep ( MB_ICONEXCLAMATION ); + return; + } + + mClient->AddBreakpoint ( mScripts[mActiveScript]->GetFilename(), line ); + } + else + { + mClient->RemoveBreakpoint ( bp->GetID ( ) ); + } + + // Force a repaint of the script window + InvalidateRect ( mWndScript, NULL, FALSE ); +} + +/* +================ +rvDebuggerWindow::AboutDlgProc + +Dialog box procedure for the about box +================ +*/ +INT_PTR CALLBACK rvDebuggerWindow::AboutDlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + switch ( msg ) + { + case WM_COMMAND: + EndDialog ( wnd, 0 ); + break; + } + + return FALSE; +} + +/* +================ +rvDebuggerWindow::CreateToolbar + +Create the toolbar and and all of its buttons +================ +*/ +void rvDebuggerWindow::CreateToolbar ( void ) +{ + // Create the toolbar control + mWndToolbar = CreateWindowEx ( 0, TOOLBARCLASSNAME, "", WS_CHILD|WS_VISIBLE,0,0,0,0, mWnd, (HMENU)IDC_DBG_TOOLBAR, mInstance, NULL ); + + // Initialize the toolbar + SendMessage ( mWndToolbar, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 ); + SendMessage ( mWndToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(16,16) ); + SendMessage ( mWndToolbar, TB_SETSTYLE, 0, SendMessage ( mWndToolbar, TB_GETSTYLE, 0, 0 ) | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS ); + + TBMETRICS tbmet; + tbmet.cbSize = sizeof(TBMETRICS); + SendMessage ( mWndToolbar, TB_GETMETRICS, 0, (LPARAM)&tbmet ); + tbmet.cyPad = 0; + tbmet.cyBarPad = 0; + SendMessage ( mWndToolbar, TB_SETMETRICS, 0, (LPARAM)&tbmet ); + + // Add the bitmap containing button images to the toolbar. + TBADDBITMAP tbab; + tbab.hInst = mInstance; + tbab.nID = IDB_DBG_TOOLBAR; + SendMessage( mWndToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab ); + + // Add the buttons to the toolbar + TBBUTTON tbb[] = { { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 }, + { 8, ID_DBG_FILE_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 }, + { 0, ID_DBG_DEBUG_RUN, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 1, ID_DBG_DEBUG_BREAK, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 }, + { 4, ID_DBG_DEBUG_STEPINTO, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 5, ID_DBG_DEBUG_STEPOVER, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 6, ID_DBG_DEBUG_STEPOUT, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 }, + { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 } }; + + SendMessage( mWndToolbar, TB_ADDBUTTONS, (WPARAM)sizeof(tbb)/sizeof(TBBUTTON), (LPARAM) tbb ); +} + +/* +================ +rvDebuggerWindow::HandleTooltipGetDispInfo + +Handle the getdispinfo notification message for tooltips by responding with the +tooptip text for the given toolbar button. +================ +*/ +void rvDebuggerWindow::HandleTooltipGetDispInfo ( WPARAM wparam, LPARAM lparam ) +{ + NMTTDISPINFO* ttdi = (NMTTDISPINFO*) lparam; + switch ( ttdi->hdr.idFrom ) + { + case ID_DBG_FILE_OPEN: + strcpy ( ttdi->szText, "Open Script" ); + break; + + case ID_DBG_DEBUG_STEPINTO: + strcpy ( ttdi->szText, "Step Into" ); + break; + + case ID_DBG_DEBUG_STEPOVER: + strcpy ( ttdi->szText, "Step Over" ); + break; + + case ID_DBG_DEBUG_STEPOUT: + strcpy ( ttdi->szText, "Step Out" ); + break; + + case ID_DBG_DEBUG_BREAK: + strcpy ( ttdi->szText, "Break" ); + break; + + case ID_DBG_DEBUG_RUN: + if ( mClient->IsConnected() ) + { + strcpy ( ttdi->szText, "Continue" ); + } + else + { + strcpy ( ttdi->szText, "Run" ); + } + break; + + default: + strcpy ( ttdi->szText, "" ); + break; + } +} + +/* +================ +rvDebuggerWindow::HandleActivate + +When the main window is activated, check all the loaded scripts and see if any of them +have been modified since the last time they were loaded. If they have then reload +them and adjust all breakpoints that now fall on invalid lines. +================ +*/ +int rvDebuggerWindow::HandleActivate ( WPARAM wparam, LPARAM lparam ) +{ + int i; + + // We are only interested in the activation, not deactivation + if ( !LOWORD(wparam) ) + { + return 0; + } + + // Run through all of the loaded scripts and see if any of them have been modified + for ( i = 0; i < mScripts.Num(); i ++ ) + { + if ( mScripts[i]->IsFileModified ( true ) ) + { + if ( IDYES == MessageBox ( mWnd, va("%s\n\nThis file has been modified outside of the debugger.\nDo you want to reload it?", mScripts[i]->GetFilename() ), "Quake 4 Script Debugger", MB_YESNO|MB_ICONQUESTION ) ) + { + mScripts[i]->Reload ( ); + + // Update the script if it was the active one + if ( mActiveScript == i ) + { + mLastActiveScript = -1; + UpdateScript ( ); + } + + // Loop through the breakpoints and see if any of them have + // moved to invalid lines within the script. If so then just remove + // them. + for ( int b = mClient->GetBreakpointCount() - 1; b >= 0 ; b-- ) + { + rvDebuggerBreakpoint* bp = mClient->GetBreakpoint(b); + assert ( bp ); + + if ( !idStr::Icmp ( bp->GetFilename(), mScripts[i]->GetFilename() ) ) + { + if ( !mScripts[i]->IsLineCode ( bp->GetLineNumber ( ) ) ) + { + mClient->RemoveBreakpoint ( bp->GetID ( ) ); + } + } + } + } + } + } + + return 1; +} + +/* +================ +rvDebuggerWindow::EnableWindows + +Enables and disables all windows with a enable state dependent on the current +connected and paused state of the debugger. +================ +*/ +void rvDebuggerWindow::EnableWindows ( bool state ) +{ + EnableWindow ( mWndCallstack, state ); + EnableWindow ( mWndThreads, state ); + EnableWindow ( mWndWatch, state ); +} + +/* +================ +rvDebuggerWindow::AddWatch + +Add a variable to the watch window. If update is set to true then also query the +debugger client for the value +================ +*/ +void rvDebuggerWindow::AddWatch ( const char* varname, bool update ) +{ + rvDebuggerWatch* watch; + + watch = new rvDebuggerWatch; + watch->mVariable = varname; + watch->mModified = false; + watch->mValue = "???"; + mWatches.Append ( watch ); + + // Add the variable to the watch control + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = ListView_GetItemCount ( mWndWatch ) - 1; + item.iSubItem = 0; + item.lParam = (LPARAM)watch; + ListView_InsertItem ( mWndWatch, &item ); + + // If update is set then request the value from the debugger client + if ( update ) + { + mClient->InspectVariable ( varname, mCurrentStackDepth ); + } +} + +/* +================ +rvDebuggerWindow::InitRecentFiles + +Finds the file menu and the location within it where the MRU should +be added. +================ +*/ +bool rvDebuggerWindow::InitRecentFiles ( void ) +{ + int i; + int count; + + mRecentFileMenu = GetSubMenu ( GetMenu(mWnd), 0 ); + count = GetMenuItemCount ( mRecentFileMenu ); + + for ( i = 0; i < count; i ++ ) + { + if ( GetMenuItemID ( mRecentFileMenu, i ) == ID_DBG_FILE_MRU ) + { + mRecentFileInsertPos = i; + DeleteMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION ); + return true; + } + } + + return false; +} + +/* +================ +rvDebuggerWindow::UpdateRecentFiles + +Updates the mru in the menu +================ +*/ +void rvDebuggerWindow::UpdateRecentFiles ( void ) +{ + int i; + int j; + + // Make sure everything is initialized + if ( !mRecentFileMenu ) + { + InitRecentFiles ( ); + } + + // Delete all the old recent files from the menu's + for ( i = 0; i < rvRegistryOptions::MAX_MRU_SIZE; i ++ ) + { + DeleteMenu ( mRecentFileMenu, ID_DBG_FILE_MRU1 + i, MF_BYCOMMAND ); + } + + // Make sure there is a separator after the recent files + if ( gDebuggerApp.GetOptions().GetRecentFileCount() ) + { + MENUITEMINFO info; + ZeroMemory ( &info, sizeof(info) ); + info.cbSize = sizeof(info); + info.fMask = MIIM_FTYPE; + GetMenuItemInfo ( mRecentFileMenu, mRecentFileInsertPos+1,TRUE, &info ); + if ( !(info.fType & MFT_SEPARATOR ) ) + { + InsertMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION|MF_SEPARATOR|MF_ENABLED, 0, NULL ); + } + } + + // Add the recent files to the menu now + for ( j = 0, i = gDebuggerApp.GetOptions().GetRecentFileCount ( ) - 1; i >= 0; i --, j++ ) + { + UINT id = ID_DBG_FILE_MRU1 + j; + idStr str = va("&%d ", j+1); + str.Append ( gDebuggerApp.GetOptions().GetRecentFile ( i ) ); + InsertMenu ( mRecentFileMenu, mRecentFileInsertPos+j+1, MF_BYPOSITION|MF_STRING|MF_ENABLED, id, str ); + } +} + +/* +================ +rvDebuggerWindow::GetSelectedText + +Function to retrieve the text that is currently selected in the +script control +================ +*/ +int rvDebuggerWindow::GetSelectedText ( idStr& text ) +{ + TEXTRANGE range; + int start; + int end; + char* temp; + + text.Empty ( ); + + if ( mScripts.Num ( ) ) + { + SendMessage ( mWndScript, EM_GETSEL, (WPARAM)&start, (LPARAM)&end ); + if ( start == end ) + { + end = SendMessage ( mWndScript, EM_FINDWORDBREAK, WB_RIGHT, start ); + start = SendMessage ( mWndScript, EM_FINDWORDBREAK, WB_LEFT, start ); + } + + temp = new char[end-start+10]; + range.chrg.cpMin = start; + range.chrg.cpMax = end; + range.lpstrText = temp; + SendMessage ( mWndScript, EM_GETTEXTRANGE, 0, (LPARAM) &range ); + text = temp; + delete[] temp; + + return start; + } + + return -1; +} + +/* +================ +rvDebuggerWindow::FindNext + +Finds the next match of the find text in the active script. The next is +always relative to the current selection. If the text parameter is NULL +then the last text used will be searched for. +================ +*/ +bool rvDebuggerWindow::FindNext ( const char* text ) +{ + int start; + FINDTEXT ft; + + if ( text ) + { + mFind = text; + } + + if ( !mFind.Length ( ) ) + { + return false; + } + + SendMessage ( mWndScript, EM_GETSEL, (WPARAM)&start, (LPARAM)0 ); + if ( start < 0 ) + { + start = 0; + } + + ft.chrg.cpMin = start + 1; + ft.chrg.cpMax = -1; + ft.lpstrText = mFind.c_str(); + start = SendMessage ( mWndScript, EM_FINDTEXT, FR_DOWN, (LPARAM)&ft ); + + if ( start < 0 ) + { + ft.chrg.cpMin = 0; + ft.chrg.cpMax = -1; + ft.lpstrText = mFind.c_str(); + start = SendMessage ( mWndScript, EM_FINDTEXT, FR_DOWN, (LPARAM)&ft ); + + if ( start < 0 ) + { + return false; + } + } + + SendMessage ( mWndScript, EM_SETSEL, start, start + mFind.Length() ); + SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 ); + + return true; +} + +/* +================ +rvDebuggerWindow::FindPrev + +Finds the previous match of the find text in the active script. The previous is +always relative to the current selection. If the text parameter is NULL +then the last text used will be searched for. +================ +*/ +bool rvDebuggerWindow::FindPrev ( const char* text ) +{ + int start; + FINDTEXT ft; + + if ( text ) + { + mFind = text; + } + + if ( !mFind.Length ( ) ) + { + return false; + } + + SendMessage ( mWndScript, EM_GETSEL, (WPARAM)&start, (LPARAM)0 ); + if ( start < 0 ) + { + start = 0; + } + + ft.chrg.cpMin = start; + ft.chrg.cpMax = -1; + ft.lpstrText = mFind.c_str(); + start = SendMessage ( mWndScript, EM_FINDTEXT, 0, (LPARAM)&ft ); + + if ( start < 0 ) + { + GETTEXTLENGTHEX gtl; + gtl.flags = GTL_DEFAULT; + gtl.codepage = CP_ACP; + ft.chrg.cpMin = SendMessage ( mWndScript, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0 ); + ft.chrg.cpMax = 0; + ft.lpstrText = mFind.c_str(); + start = SendMessage ( mWndScript, EM_FINDTEXT, 0, (LPARAM)&ft ); + + if ( start < 0 ) + { + return false; + } + } + + SendMessage ( mWndScript, EM_SETSEL, start, start + mFind.Length() ); + SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 ); + + return true; +} + +/* +================ +rvDebuggerWindow::HandleDrawItem + +Handled the WM_DRAWITEM message. The watch window is custom drawn so a grid can be displayed. +================ +*/ +int rvDebuggerWindow::HandleDrawItem ( WPARAM wparam, LPARAM lparam ) +{ + DRAWITEMSTRUCT* dis; + LVCOLUMN col; + int index; + idStr widths; + RECT rect; + rvDebuggerWatch* watch; + bool selected; + + dis = (DRAWITEMSTRUCT*) lparam; + watch = (rvDebuggerWatch*)dis->itemData; + + col.mask = LVCF_WIDTH; + rect = dis->rcItem; + rect.left = rect.left - 1; + rect.right = rect.left; + rect.bottom++; + + selected = ((dis->itemState & ODS_SELECTED) && GetFocus()==mWndWatch); + + // Set the colors based on the selected state and draw the item background + if ( selected ) + { + FillRect ( dis->hDC, &dis->rcItem, GetSysColorBrush ( COLOR_HIGHLIGHT ) ); + } + else + { + FillRect ( dis->hDC, &dis->rcItem, GetSysColorBrush ( IsWindowEnabled ( mWndWatch ) ? COLOR_WINDOW : COLOR_3DFACE ) ); + } + + // Run through the columns and draw each with a frame around it and the text + // vertically centered in it + for ( index = 0; ListView_GetColumn ( mWndWatch, index, &col ); index ++ ) + { + rect.right = rect.left + col.cx; + FrameRect ( dis->hDC, &rect, GetSysColorBrush ( COLOR_3DFACE ) ); + + // Draw info on the watch if available + if ( watch ) + { + RECT textrect; + textrect = rect; + textrect.left += 5; + + switch ( index ) + { + case 0: + SetTextColor ( dis->hDC, GetSysColor ( selected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT ) ); + DrawText ( dis->hDC, watch->mVariable, -1, &textrect, DT_LEFT|DT_VCENTER ); + break; + + case 1: + if ( watch && watch->mModified && (IsWindowEnabled ( mWndWatch ) ) ) + { + SetTextColor ( dis->hDC, RGB(255,50,50) ); + } + else + { + SetTextColor ( dis->hDC, GetSysColor ( selected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT ) ); + } + DrawText ( dis->hDC, watch->mValue, -1, &textrect, DT_LEFT|DT_VCENTER ); + break; + } + } + + rect.left = rect.right - 1; + } + + return 0; +} \ No newline at end of file diff --git a/tools/debugger/DebuggerWindow.h b/tools/debugger/DebuggerWindow.h new file mode 100644 index 000000000..8dfb6e708 --- /dev/null +++ b/tools/debugger/DebuggerWindow.h @@ -0,0 +1,175 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef DEBUGGERWINDOW_H_ +#define DEBUGGERWINDOW_H_ + +#ifndef DEBUGGERSCRIPT_H_ +#include "DebuggerScript.h" +#endif + +class rvDebuggerWatch +{ +public: + + idStr mVariable; + idStr mValue; + bool mModified; +}; + +typedef idList rvDebuggerWatchList; + +class rvDebuggerClient; + +class rvDebuggerWindow +{ +public: + + rvDebuggerWindow ( ); + ~rvDebuggerWindow ( ); + + bool Create ( HINSTANCE hInstance ); + + static bool Activate ( void ); + + void ProcessNetMessage ( msg_t* msg ); + + void Printf ( const char* format, ... ); + + HWND GetWindow ( void ); + + void AddWatch ( const char* name, bool update = true ); + + HINSTANCE GetInstance ( void ); + +protected: + + bool FindPrev ( const char* text = NULL ); + bool FindNext ( const char* text = NULL ); + + void UpdateWatch ( void ); + void UpdateWindowMenu ( void ); + void UpdateScript ( void ); + void UpdateToolbar ( void ); + void UpdateTitle ( void ); + void UpdateCallstack ( void ); + void UpdateRecentFiles ( void ); + bool OpenScript ( const char* filename, int lineNumber = -1 ); + void EnableWindows ( bool state ); + + int GetSelectedText ( idStr& text ); + + void ToggleBreakpoint ( void ); + + HWND mWnd; + HWND mWndScript; + HWND mWndOutput; + HWND mWndMargin; + HWND mWndTabs; + HWND mWndBorder; + HWND mWndConsole; + HWND mWndCallstack; + HWND mWndWatch; + HWND mWndThreads; + HWND mWndToolTips; + HWND mWndToolbar; + + HMENU mRecentFileMenu; + int mRecentFileInsertPos; + + WNDPROC mOldWatchProc; + WNDPROC mOldScriptProc; + idStr mTooltipVar; + idStr mTooltipValue; + + HINSTANCE mInstance; + HIMAGELIST mImageList; + + RECT mSplitterRect; + bool mSplitterDrag; + + idList mScripts; + int mActiveScript; + int mLastActiveScript; + int mCurrentStackDepth; + + HMENU mWindowMenu; + int mWindowMenuPos; + + int mZoomScaleNum; + int mZoomScaleDem; + int mMarginSize; + + idStr mFind; + + rvDebuggerClient* mClient; + + rvDebuggerWatchList mWatches; + +private: + + bool RegisterClass ( void ); + void CreateToolbar ( void ); + bool InitRecentFiles ( void ); + + int HandleInitMenu ( WPARAM wParam, LPARAM lParam ); + int HandleCommand ( WPARAM wParam, LPARAM lParam ); + int HandleCreate ( WPARAM wparam, LPARAM lparam ); + int HandleActivate ( WPARAM wparam, LPARAM lparam ); + int HandleDrawItem ( WPARAM wparam, LPARAM lparam ); + void HandleTooltipGetDispInfo ( WPARAM wparam, LPARAM lparam ); + + static LRESULT CALLBACK WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); + static LRESULT CALLBACK MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); + static LRESULT CALLBACK ScriptWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); + static INT_PTR CALLBACK AboutDlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam ); + static int CALLBACK ScriptWordBreakProc ( LPTSTR text, int current, int max, int action ); +}; + +/* +================ +rvDebuggerWindow::GetWindow +================ +*/ +ID_INLINE HWND rvDebuggerWindow::GetWindow ( void ) +{ + return mWnd; +} + +/* +================ +rvDebuggerWindow::UpdateToolbar +================ +*/ +ID_INLINE void rvDebuggerWindow::UpdateToolbar ( void ) +{ + HandleInitMenu ( (WPARAM)GetMenu ( mWnd ), 0 ); +} + +/* +================ +rvDebuggerWindow::GetInstance +================ +*/ +ID_INLINE HINSTANCE rvDebuggerWindow::GetInstance ( void ) +{ + return mInstance; +} + +#endif // DEBUGGERWINDOW_H_ + diff --git a/tools/debugger/debugger.cpp b/tools/debugger/debugger.cpp new file mode 100644 index 000000000..97e05668e --- /dev/null +++ b/tools/debugger/debugger.cpp @@ -0,0 +1,226 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/debugger_resource.h" +#include "DebuggerApp.h" +#include "DebuggerServer.h" + +DWORD CALLBACK DebuggerThread ( LPVOID param ); + +rvDebuggerApp gDebuggerApp; +HWND gDebuggerWindow = NULL; +bool gDebuggerSuspend = false; +bool gDebuggerConnnected = false; +HANDLE gDebuggerGameThread = NULL; + +rvDebuggerServer* gDebuggerServer = NULL; +HANDLE gDebuggerServerThread = NULL; +DWORD gDebuggerServerThreadID = 0; +bool gDebuggerServerQuit = false; + +/* +================ +DebuggerMain + +Main entry point for the debugger application +================ +*/ +void DebuggerClientInit( const char *cmdline ) +{ + // See if the debugger is already running + if ( rvDebuggerWindow::Activate ( ) ) + { + goto DebuggerClientInitDone; + } + + if ( !gDebuggerApp.Initialize ( win32.hInstance ) ) + { + goto DebuggerClientInitDone; + } + + gDebuggerApp.Run ( ); + +DebuggerClientInitDone: + + common->Quit(); +} + +/* +================ +DebuggerLaunch + +Launches another instance of the running executable with +debugger appended +to the end to indicate that the debugger should start up. +================ +*/ +void DebuggerClientLaunch ( void ) +{ + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the script debugger in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + // See if the debugger is already running + if ( rvDebuggerWindow::Activate ( ) ) { + return; + } + + char exeFile[MAX_PATH]; + char curDir[MAX_PATH]; + + STARTUPINFO startup; + PROCESS_INFORMATION process; + + ZeroMemory ( &startup, sizeof(startup) ); + startup.cb = sizeof(startup); + + GetCurrentDirectory ( MAX_PATH, curDir ); + + GetModuleFileName ( NULL, exeFile, MAX_PATH ); + const char* s = va("%s +set fs_game %s +set fs_cdpath %s +debugger", exeFile, cvarSystem->GetCVarString( "fs_game" ), cvarSystem->GetCVarString( "fs_cdpath" ) ); + CreateProcess ( NULL, (LPSTR)s, + NULL, NULL, FALSE, 0, NULL, curDir, &startup, &process ); + + CloseHandle ( process.hThread ); + CloseHandle ( process.hProcess ); +} + +/* +================ +DebuggerServerThread + +Thread proc for the debugger server +================ +*/ +DWORD CALLBACK DebuggerServerThread ( LPVOID param ) +{ + assert ( gDebuggerServer ); + + while ( !gDebuggerServerQuit ) + { + gDebuggerServer->ProcessMessages ( ); + Sleep ( 1 ); + } + + return 0; +} + +/* +================ +DebuggerServerInit + +Starts up the debugger server +================ +*/ +bool DebuggerServerInit ( void ) +{ + // Dont do this if we are in the debugger already + if ( com_editors & EDITOR_DEBUGGER ) + { + return false; + } + + // Allocate the new debugger server + gDebuggerServer = new rvDebuggerServer; + if ( !gDebuggerServer ) + { + return false; + } + + // Initialize the debugger server + if ( !gDebuggerServer->Initialize ( ) ) + { + delete gDebuggerServer; + gDebuggerServer = NULL; + return false; + } + + // Start the debugger server thread + gDebuggerServerThread = CreateThread ( NULL, 0, DebuggerServerThread, 0, 0, &gDebuggerServerThreadID ); + + return true; +} + +/* +================ +DebuggerServerShutdown + +Shuts down the debugger server +================ +*/ +void DebuggerServerShutdown ( void ) +{ + if ( gDebuggerServerThread ) + { + // Signal the debugger server to quit + gDebuggerServerQuit = true; + + // Wait for the thread to finish + WaitForSingleObject ( gDebuggerServerThread, INFINITE ); + + // Shutdown the server now + gDebuggerServer->Shutdown(); + + delete gDebuggerServer; + gDebuggerServer = NULL; + + // Cleanup the thread handle + CloseHandle ( gDebuggerServerThread ); + gDebuggerServerThread = NULL; + } +} + +/* +================ +DebuggerServerCheckBreakpoint + +Check to see if there is a breakpoint associtated with this statement +================ +*/ +void DebuggerServerCheckBreakpoint ( idInterpreter* interpreter, idProgram* program, int instructionPointer ) +{ + if ( !gDebuggerServer ) + { + return; + } + + gDebuggerServer->CheckBreakpoints ( interpreter, program, instructionPointer ); +} + +/* +================ +DebuggerServerPrint + +Sends a print message to the debugger client +================ +*/ +void DebuggerServerPrint ( const char* text ) +{ + if ( !gDebuggerServer ) + { + return; + } + + gDebuggerServer->Print ( text ); +} + diff --git a/tools/decl/DialogDeclBrowser.cpp b/tools/decl/DialogDeclBrowser.cpp new file mode 100644 index 000000000..cb154452f --- /dev/null +++ b/tools/decl/DialogDeclBrowser.cpp @@ -0,0 +1,938 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/DeclEditor_resource.h" +#include "../../sys/win32/rc/ScriptEditor_resource.h" + +#include "../comafx/CPathTreeCtrl.h" +#include "../script/DialogScriptEditor.h" +#include "DialogDeclBrowser.h" +#include "DialogDeclEditor.h" +#include "DialogDeclNew.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +const int DECLTYPE_SHIFT = 24; +const int DECLINDEX_MASK = ( 1 << DECLTYPE_SHIFT ) - 1; +const int DECLTYPE_SCRIPT = 126; +const int DECLTYPE_GUI = 127; + +#define GetIdFromTypeAndIndex( type, index ) ( ( (int)type << DECLTYPE_SHIFT ) | index ) +#define GetTypeFromId( id ) ( (declType_t) ( (int)id >> DECLTYPE_SHIFT ) ) +#define GetIndexFromId( id ) ( (int)id & DECLINDEX_MASK ) + +toolTip_t DialogDeclBrowser::toolTips[] = { + { IDC_DECLBROWSER_TREE, "decl browser" }, + { IDC_DECLBROWSER_EDIT_SEARCH_NAMES, "search for declarations with matching name, use meta characters: *, ? and [abc...]" }, + { IDC_DECLBROWSER_EDIT_SEARCH_TEXT, "search for declarations containing text" }, + { IDC_DECLBROWSER_BUTTON_FIND, "find declarations matching the search strings" }, + { IDC_DECLBROWSER_BUTTON_EDIT, "edit selected declaration" }, + { IDC_DECLBROWSER_BUTTON_NEW, "create new declaration" }, + { IDC_DECLBROWSER_BUTTON_RELOAD, "reload declarations" }, + { IDOK, "ok" }, + { IDCANCEL, "cancel" }, + { 0, NULL } +}; + + +static DialogDeclBrowser *g_DeclDialog = NULL; + + +IMPLEMENT_DYNAMIC(DialogDeclBrowser, CDialog) + +/* +================ +DialogDeclBrowser::DialogDeclBrowser +================ +*/ +DialogDeclBrowser::DialogDeclBrowser( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogDeclBrowser::IDD, pParent) + , m_pchTip(NULL) + , m_pwchTip(NULL) +{ +} + +/* +================ +DialogDeclBrowser::~DialogDeclBrowser +================ +*/ +DialogDeclBrowser::~DialogDeclBrowser() { + delete m_pwchTip; + delete m_pchTip; +} + +/* +================ +DialogDeclBrowser::DoDataExchange +================ +*/ +void DialogDeclBrowser::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogDeclBrowser) + DDX_Control(pDX, IDC_DECLBROWSER_TREE, declTree); + DDX_Control(pDX, IDC_DECLBROWSER_STATIC_SEARCH_NAMES, findNameStatic); + DDX_Control(pDX, IDC_DECLBROWSER_STATIC_SEARCH_TEXT, findTextStatic); + DDX_Control(pDX, IDC_DECLBROWSER_EDIT_SEARCH_NAMES, findNameEdit); + DDX_Control(pDX, IDC_DECLBROWSER_EDIT_SEARCH_TEXT, findTextEdit); + DDX_Control(pDX, IDC_DECLBROWSER_BUTTON_FIND, findButton); + DDX_Control(pDX, IDC_DECLBROWSER_BUTTON_EDIT, editButton); + DDX_Control(pDX, IDC_DECLBROWSER_BUTTON_NEW, newButton); + DDX_Control(pDX, IDC_DECLBROWSER_BUTTON_RELOAD, reloadButton); + DDX_Control(pDX, IDCANCEL, cancelButton); + //}}AFX_DATA_MAP +} + +/* +================ +DialogDeclBrowser::AddDeclTypeToTree +================ +*/ +template< class type > +int idListDeclSortCompare( const type *a, const type *b ) { + return idStr::IcmpPath( (*a)->GetName(), (*b)->GetName() ); +} + +void DialogDeclBrowser::AddDeclTypeToTree( declType_t type, const char *root, CPathTreeCtrl &tree ) { + int i; + idList decls; + idPathTreeStack stack; + idStr rootStr, declName; + + decls.SetNum( declManager->GetNumDecls( type ) ); + for ( i = 0; i < decls.Num(); i++ ) { + decls[i] = declManager->DeclByIndex( type, i, false ); + } + decls.Sort( idListDeclSortCompare ); + + rootStr = root; + rootStr += "/"; + + stack.PushRoot( NULL ); + + for ( i = 0; i < decls.Num(); i++) { + declName = rootStr + decls[i]->GetName(); + + declName.BackSlashesToSlashes(); + declName.Strip(' '); + + tree.AddPathToTree( declName, GetIdFromTypeAndIndex( type, decls[i]->Index() ), stack ); + } +} + +/* +================ +DialogDeclBrowser::AddScriptsToTree +================ +*/ +void DialogDeclBrowser::AddScriptsToTree( CPathTreeCtrl &tree ) { + int i; + idPathTreeStack stack; + idStr scriptName; + idFileList *files; + + files = fileSystem->ListFilesTree( "script", ".script", true ); + + stack.PushRoot( NULL ); + + for ( i = 0; i < files->GetNumFiles(); i++) { + scriptName = files->GetFile( i ); + + scriptName.BackSlashesToSlashes(); + scriptName.StripFileExtension(); + + tree.AddPathToTree( scriptName, GetIdFromTypeAndIndex( DECLTYPE_SCRIPT, i ), stack ); + } + + fileSystem->FreeFileList( files ); +} + +/* +================ +DialogDeclBrowser::AddGUIsToTree +================ +*/ +void DialogDeclBrowser::AddGUIsToTree( CPathTreeCtrl &tree ) { + int i; + idPathTreeStack stack; + idStr scriptName; + idFileList *files; + + files = fileSystem->ListFilesTree( "guis", ".gui", true ); + + stack.PushRoot( NULL ); + + for ( i = 0; i < files->GetNumFiles(); i++) { + scriptName = files->GetFile( i ); + + scriptName.BackSlashesToSlashes(); + scriptName.StripFileExtension(); + + tree.AddPathToTree( scriptName, GetIdFromTypeAndIndex( DECLTYPE_GUI, i ), stack ); + } + + fileSystem->FreeFileList( files ); +} + +/* +================ +DialogDeclBrowser::InitBaseDeclTree +================ +*/ +void DialogDeclBrowser::InitBaseDeclTree( void ) { + int i; + + numListedDecls = 0; + baseDeclTree.DeleteAllItems(); + + for ( i = 0; i < declManager->GetNumDeclTypes(); i++ ) { + AddDeclTypeToTree( (declType_t)i, declManager->GetDeclNameFromType( (declType_t)i ), baseDeclTree ); + } + + AddScriptsToTree( baseDeclTree ); + AddGUIsToTree( baseDeclTree ); +} + +/* +================ +DialogDeclBrowser::GetDeclName +================ +*/ +void DialogDeclBrowser::GetDeclName( HTREEITEM item, idStr &typeName, idStr &declName ) const { + HTREEITEM parent; + idStr itemName; + + declName.Clear(); + for( parent = declTree.GetParentItem( item ); parent; parent = declTree.GetParentItem( parent ) ) { + itemName = declTree.GetItemText( item ); + declName = itemName + "/" + declName; + item = parent; + } + declName.Strip( '/' ); + typeName = declTree.GetItemText( item ); +} + +/* +================ +DialogDeclBrowser::GetDeclFromTreeItem +================ +*/ +const idDecl *DialogDeclBrowser::GetDeclFromTreeItem( HTREEITEM item ) const { + int id, index; + declType_t type; + const idDecl *decl; + + if ( declTree.GetChildItem( item ) ) { + return NULL; + } + + id = declTree.GetItemData( item ); + type = GetTypeFromId( id ); + index = GetIndexFromId( id ); + + if ( type < 0 || type >= declManager->GetNumDeclTypes() ) { + return NULL; + } + + decl = declManager->DeclByIndex( type, index, false ); + + return decl; +} + +/* +================ +DialogDeclBrowser::GetSelectedDecl +================ +*/ +const idDecl *DialogDeclBrowser::GetSelectedDecl( void ) const { + return GetDeclFromTreeItem( declTree.GetSelectedItem() ); +} + +/* +================ +DialogDeclBrowser::EditSelected +================ +*/ +void DialogDeclBrowser::EditSelected( void ) const { + int id, index; + idDict spawnArgs; + const idDecl *decl; + declType_t type; + HTREEITEM item; + + item = declTree.GetSelectedItem(); + + if ( declTree.GetChildItem( item ) ) { + return; + } + + id = declTree.GetItemData( item ); + type = GetTypeFromId( id ); + index = GetIndexFromId( id ); + + switch( type ) { + case DECL_AF: { + decl = declManager->DeclByIndex( type, index, false ); + spawnArgs.Set( "articulatedFigure", decl->GetName() ); + AFEditorInit( &spawnArgs ); + break; + } + case DECL_PARTICLE: { + decl = declManager->DeclByIndex( type, index, false ); + spawnArgs.Set( "model", decl->GetName() ); + ParticleEditorInit( &spawnArgs ); + break; + } + case DECL_PDA: { + decl = declManager->DeclByIndex( type, index, false ); + spawnArgs.Set( "pda", decl->GetName() ); + PDAEditorInit( &spawnArgs ); + break; + } + case DECLTYPE_SCRIPT: + case DECLTYPE_GUI: { + idStr typeName, declName; + GetDeclName( item, typeName, declName ); + DialogScriptEditor *scriptEditor; + scriptEditor = new DialogScriptEditor; + scriptEditor->Create( IDD_DIALOG_SCRIPTEDITOR, GetParent() ); + scriptEditor->OpenFile( typeName + "/" + declName + ( ( type == DECLTYPE_SCRIPT ) ? ".script" : ".gui" ) ); + scriptEditor->ShowWindow( SW_SHOW ); + scriptEditor->SetFocus(); + break; + } + default: { + decl = declManager->DeclByIndex( type, index, false ); + DialogDeclEditor *declEditor; + declEditor = new DialogDeclEditor; + declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() ); + declEditor->LoadDecl( const_cast( decl ) ); + declEditor->ShowWindow( SW_SHOW ); + declEditor->SetFocus(); + break; + } + } +} + +/* +================ +DeclBrowserCompareDecl +================ +*/ +bool DeclBrowserCompareDecl( void *data, HTREEITEM item, const char *name ) { + return reinterpret_cast(data)->CompareDecl( item, name ); +} + +/* +================ +DialogDeclBrowser::CompareDecl +================ +*/ +bool DialogDeclBrowser::CompareDecl( HTREEITEM item, const char *name ) const { + if ( findNameString.Length() ) { + if ( !idStr::Filter( findNameString, name, false ) ) { + return false; + } + } + + if ( findTextString.Length() ) { + int id, index; + declType_t type; + + id = declTree.GetItemData( item ); + type = GetTypeFromId( id ); + index = GetIndexFromId( id ); + + if ( type == DECLTYPE_SCRIPT || type == DECLTYPE_GUI ) { + // search for the text in the script or gui + idStr text; + void *buffer; + if ( fileSystem->ReadFile( idStr( name ) + ( ( type == DECLTYPE_SCRIPT ) ? ".script" : ".gui" ), &buffer ) == -1 ) { + return false; + } + text = (char *) buffer; + fileSystem->FreeFile( buffer ); + if ( text.Find( findTextString, false ) == -1 ) { + return false; + } + } else { + // search for the text in the decl + const idDecl *decl = declManager->DeclByIndex( type, index, false ); + char *declText = (char *)_alloca( ( decl->GetTextLength() + 1 ) * sizeof( char ) ); + decl->GetText( declText ); + if ( idStr::FindText( declText, findTextString, false ) == -1 ) { + return false; + } + } + } + + return true; +} + +/* +================ +DialogDeclBrowser::OnInitDialog +================ +*/ +BOOL DialogDeclBrowser::OnInitDialog() { + + com_editors |= EDITOR_DECL; + + CDialog::OnInitDialog(); + + GetClientRect( initialRect ); + + statusBar.CreateEx( SBARS_SIZEGRIP, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, initialRect, this, AFX_IDW_STATUS_BAR ); + + baseDeclTree.Create( 0, initialRect, this, IDC_DECLBROWSER_BASE_TREE ); + + InitBaseDeclTree(); + + findNameString = "*"; + findNameEdit.SetWindowText( findNameString ); + + findTextString = ""; + findTextEdit.SetWindowText( findTextString ); + + numListedDecls = baseDeclTree.SearchTree( DeclBrowserCompareDecl, this, declTree ); + + statusBar.SetWindowText( va( "%d decls listed", numListedDecls ) ); + + EnableToolTips( TRUE ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +/* +================ +DeclBrowserInit +================ +*/ +void DeclBrowserInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the declaration editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_DeclDialog == NULL ) { + InitAfx(); + g_DeclDialog = new DialogDeclBrowser(); + } + + if ( g_DeclDialog->GetSafeHwnd() == NULL) { + g_DeclDialog->Create( IDD_DIALOG_DECLBROWSER ); +/* + // FIXME: restore position + CRect rct; + g_DeclDialog->SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE ); +*/ + } + + idKeyInput::ClearStates(); + + g_DeclDialog->ShowWindow( SW_SHOW ); + g_DeclDialog->SetFocus(); + + if ( spawnArgs ) { + } +} + +/* +================ +DeclBrowserRun +================ +*/ +void DeclBrowserRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +/* +================ +DeclBrowserShutdown +================ +*/ +void DeclBrowserShutdown( void ) { + delete g_DeclDialog; + g_DeclDialog = NULL; +} + +/* +================ +DeclBrowserReloadDeclarations +================ +*/ +void DeclBrowserReloadDeclarations( void ) { + if ( g_DeclDialog ) { + g_DeclDialog->ReloadDeclarations(); + } +} + +/* +================ +DialogDeclBrowser::ReloadDeclarations +================ +*/ +void DialogDeclBrowser::ReloadDeclarations( void ) { + InitBaseDeclTree(); + OnBnClickedFind(); +} + +BEGIN_MESSAGE_MAP(DialogDeclBrowser, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_MOVE() + ON_WM_SIZE() + ON_WM_SIZING() + ON_WM_SETFOCUS() + ON_NOTIFY(TVN_SELCHANGED, IDC_DECLBROWSER_TREE, OnTreeSelChanged) + ON_NOTIFY(NM_DBLCLK, IDC_DECLBROWSER_TREE, OnTreeDblclk) + ON_BN_CLICKED(IDC_DECLBROWSER_BUTTON_FIND, OnBnClickedFind) + ON_BN_CLICKED(IDC_DECLBROWSER_BUTTON_EDIT, OnBnClickedEdit) + ON_BN_CLICKED(IDC_DECLBROWSER_BUTTON_NEW, OnBnClickedNew) + ON_BN_CLICKED(IDC_DECLBROWSER_BUTTON_RELOAD, OnBnClickedReload) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) +END_MESSAGE_MAP() + +// DialogDeclBrowser message handlers + +/* +================ +DialogDeclBrowser::OnActivate +================ +*/ +void DialogDeclBrowser::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogDeclBrowser::OnToolTipNotify +================ +*/ +BOOL DialogDeclBrowser::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + // need to handle both ANSI and UNICODE versions of the message + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + + if ( pNMHDR->hwndFrom == declTree.GetSafeHwnd() ) { + CString toolTip; + const idDecl *decl = GetDeclFromTreeItem( (HTREEITEM) pNMHDR->idFrom ); + + if ( !decl ) { + return FALSE; + } + + toolTip = va( "%s, line: %d", decl->GetFileName(), decl->GetLineNum() ); + +#ifndef _UNICODE + if( pNMHDR->code == TTN_NEEDTEXTA ) { + delete m_pchTip; + m_pchTip = new TCHAR[toolTip.GetLength() + 2]; + lstrcpyn( m_pchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTW->lpszText = (WCHAR*)m_pchTip; + } else { + delete m_pwchTip; + m_pwchTip = new WCHAR[toolTip.GetLength() + 2]; + _mbstowcsz( m_pwchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTW->lpszText = (WCHAR*)m_pwchTip; + } +#else + if( pNMHDR->code == TTN_NEEDTEXTA ) { + delete m_pchTip; + m_pchTip = new TCHAR[toolTip.GetLength() + 2]; + _wcstombsz( m_pchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTA->lpszText = (LPTSTR)m_pchTip; + } else { + delete m_pwchTip; + m_pwchTip = new WCHAR[toolTip.GetLength() + 2]; + lstrcpyn( m_pwchTip, toolTip, toolTip.GetLength() + 1 ); + pTTTA->lpszText = (LPTSTR) m_pwchTip; + } +#endif + return TRUE; + } + + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogDeclBrowser::OnSetFocus +================ +*/ +void DialogDeclBrowser::OnSetFocus( CWnd *pOldWnd ) { + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogDeclBrowser::OnDestroy +================ +*/ +void DialogDeclBrowser::OnDestroy() { + + com_editors &= ~EDITOR_DECL; + + return CDialog::OnDestroy(); +} + +/* +================ +DialogDeclBrowser::OnMove +================ +*/ +void DialogDeclBrowser::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +/* +================ +DialogDeclBrowser::OnMove +================ +*/ +#define BORDER_SIZE 4 +#define BUTTON_SPACE 4 +#define TOOLBAR_HEIGHT 24 + +void DialogDeclBrowser::OnSize( UINT nType, int cx, int cy ) { + CRect clientRect, rect; + + LockWindowUpdate(); + + CDialog::OnSize( nType, cx, cy ); + + GetClientRect( clientRect ); + + if ( declTree.GetSafeHwnd() ) { + rect.left = BORDER_SIZE; + rect.top = BORDER_SIZE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - 100; + declTree.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( findNameStatic.GetSafeHwnd() ) { + rect.left = BORDER_SIZE + 2; + rect.top = clientRect.Height() - 100 + BUTTON_SPACE + 2; + rect.right = BORDER_SIZE + 80; + rect.bottom = clientRect.Height() - 76 + 2; + findNameStatic.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( findTextStatic.GetSafeHwnd() ) { + rect.left = BORDER_SIZE + 2; + rect.top = clientRect.Height() - 78 + BUTTON_SPACE + 2; + rect.right = BORDER_SIZE + 80; + rect.bottom = clientRect.Height() - 54 + 2; + findTextStatic.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( findNameEdit.GetSafeHwnd() ) { + rect.left = BORDER_SIZE + 80; + rect.top = clientRect.Height() - 100 + BUTTON_SPACE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - 76; + findNameEdit.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( findTextEdit.GetSafeHwnd() ) { + rect.left = BORDER_SIZE + 80; + rect.top = clientRect.Height() - 78 + BUTTON_SPACE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - 54; + findTextEdit.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( findButton.GetSafeHwnd() ) { + findButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = BORDER_SIZE; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = BORDER_SIZE + width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + findButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( editButton.GetSafeHwnd() ) { + editButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = BORDER_SIZE + BUTTON_SPACE + width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = BORDER_SIZE + BUTTON_SPACE + 2 * width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + editButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( newButton.GetSafeHwnd() ) { + newButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = BORDER_SIZE + 2 * BUTTON_SPACE + 2 * width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = BORDER_SIZE + 2 * BUTTON_SPACE + 3 * width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + newButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( reloadButton.GetSafeHwnd() ) { + reloadButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = BORDER_SIZE + 3 * BUTTON_SPACE + 3 * width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = BORDER_SIZE + 3 * BUTTON_SPACE + 4 * width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + reloadButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( cancelButton.GetSafeHwnd() ) { + cancelButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = clientRect.Width() - BORDER_SIZE - width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + cancelButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( statusBar.GetSafeHwnd() ) { + rect.left = clientRect.Width() - 2; + rect.top = clientRect.Height() - 2; + rect.right = clientRect.Width() - 2; + rect.bottom = clientRect.Height() - 2; + statusBar.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + UnlockWindowUpdate(); +} + +/* +================ +DialogDeclBrowser::OnSizing +================ +*/ +void DialogDeclBrowser::OnSizing( UINT nSide, LPRECT lpRect ) { + /* + 1 = left + 2 = right + 3 = top + 4 = left - top + 5 = right - top + 6 = bottom + 7 = left - bottom + 8 = right - bottom + */ + + CDialog::OnSizing( nSide, lpRect ); + + if ( ( nSide - 1 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->left = lpRect->right - initialRect.Width(); + } + } else if ( ( nSide - 2 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->right = lpRect->left + initialRect.Width(); + } + } + if ( nSide >= 3 && nSide <= 5 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->top = lpRect->bottom - initialRect.Height(); + } + } else if ( nSide >= 6 && nSide <= 9 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->bottom = lpRect->top + initialRect.Height(); + } + } +} + +/* +================ +DialogDeclBrowser::OnTreeSelChanged +================ +*/ +void DialogDeclBrowser::OnTreeSelChanged( NMHDR* pNMHDR, LRESULT* pResult ) { + LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR; + + const idDecl *decl = GetSelectedDecl(); + if ( decl ) { + statusBar.SetWindowText( va( "%d decls listed - %s, line: %d", numListedDecls, decl->GetFileName(), decl->GetLineNum() ) ); + findNameEdit.SetWindowText( va( "%s/%s", declManager->GetDeclNameFromType( decl->GetType() ), decl->GetName() ) ); + } else { + HTREEITEM item = declTree.GetSelectedItem(); + idStr typeName, declName; + GetDeclName( item, typeName, declName ); + findNameEdit.SetWindowText( va( "%s/%s*", typeName.c_str(), declName.c_str() ) ); + statusBar.SetWindowText( va( "%d decls listed", numListedDecls ) ); + } + + *pResult = 0; +} + +/* +================ +DialogDeclBrowser::OnTreeDblclk +================ +*/ +void DialogDeclBrowser::OnTreeDblclk( NMHDR *pNMHDR, LRESULT *pResult ) { + // post a message as if the edit button was clicked to make sure the editor gets focus + PostMessage( WM_COMMAND, ( BN_CLICKED << 16 ) | editButton.GetDlgCtrlID(), 0 ); + + *pResult = 1; +} + +/* +================ +DialogDeclBrowser::OnBnClickedFind +================ +*/ +void DialogDeclBrowser::OnBnClickedFind() { + CString windowText; + + findNameEdit.GetWindowText( windowText ); + findNameString = windowText; + findNameString.Strip( ' ' ); + + findTextEdit.GetWindowText( windowText ); + findTextString = windowText; + findTextString.Strip( ' ' ); + + numListedDecls = baseDeclTree.SearchTree( DeclBrowserCompareDecl, this, declTree ); + + statusBar.SetWindowText( va( "%d decls listed", numListedDecls ) ); +} + +/* +================ +DialogDeclBrowser::OnBnClickedEdit +================ +*/ +void DialogDeclBrowser::OnBnClickedEdit() { + EditSelected(); +} + +/* +================ +DialogDeclBrowser::OnBnClickedNew +================ +*/ +void DialogDeclBrowser::OnBnClickedNew() { + HTREEITEM item; + idStr typeName, declName; + const idDecl *decl; + DialogDeclNew newDeclDlg; + + newDeclDlg.SetDeclTree( &baseDeclTree ); + + item = declTree.GetSelectedItem(); + if ( item ) { + GetDeclName( item, typeName, declName ); + newDeclDlg.SetDefaultType( typeName ); + newDeclDlg.SetDefaultName( declName ); + } + + decl = GetSelectedDecl(); + if ( decl ) { + newDeclDlg.SetDefaultFile( decl->GetFileName() ); + } + + if ( newDeclDlg.DoModal() != IDOK ) { + return; + } + + decl = newDeclDlg.GetNewDecl(); + + if ( decl ) { + declName = declManager->GetDeclNameFromType( decl->GetType() ); + declName += "/"; + declName += decl->GetName(); + + int id = GetIdFromTypeAndIndex( decl->GetType(), decl->Index() ); + + baseDeclTree.InsertPathIntoTree( declName, id ); + item = declTree.InsertPathIntoTree( declName, id ); + declTree.SelectItem( item ); + + EditSelected(); + } +} + +/* +================ +DialogDeclBrowser::OnBnClickedReload +================ +*/ +void DialogDeclBrowser::OnBnClickedReload() { + + declManager->Reload( false ); + + ReloadDeclarations(); +} + +/* +================ +DialogDeclBrowser::OnBnClickedOk +================ +*/ +void DialogDeclBrowser::OnBnClickedOk() { + // with a modeless dialog once it is closed and re-activated windows seems + // to enjoy mapping ENTER back to the default button ( OK ) even if you have + // it NOT set as the default.. in this case use cancel button exit and ignore + // default IDOK handling. + // OnOK(); +} + +/* +================ +DialogDeclBrowser::OnBnClickedCancel +================ +*/ +void DialogDeclBrowser::OnBnClickedCancel() { + OnCancel(); +} diff --git a/tools/decl/DialogDeclBrowser.h b/tools/decl/DialogDeclBrowser.h new file mode 100644 index 000000000..70ab1f758 --- /dev/null +++ b/tools/decl/DialogDeclBrowser.h @@ -0,0 +1,104 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGDECLBROWSER_H__ +#define __DIALOGDECLBROWSER_H__ + +#pragma once + +// DialogDeclBrowser dialog + +class DialogDeclBrowser : public CDialog { + + DECLARE_DYNAMIC(DialogDeclBrowser) + +public: + DialogDeclBrowser( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogDeclBrowser(); + + void ReloadDeclarations( void ); + bool CompareDecl( HTREEITEM item, const char *name ) const; + + //{{AFX_VIRTUAL(DialogDeclBrowser) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(DialogDeclBrowser) + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnMove( int x, int y ); + afx_msg void OnSize( UINT nType, int cx, int cy ); + afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); + afx_msg void OnTreeSelChanged( NMHDR* pNMHDR, LRESULT* pResult ); + afx_msg void OnTreeDblclk( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedFind(); + afx_msg void OnBnClickedEdit(); + afx_msg void OnBnClickedNew(); + afx_msg void OnBnClickedReload(); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedCancel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + + //{{AFX_DATA(DialogDeclBrowser) + enum { IDD = IDD_DIALOG_DECLBROWSER }; + CStatusBarCtrl statusBar; + CPathTreeCtrl declTree; + CStatic findNameStatic; + CStatic findTextStatic; + CEdit findNameEdit; + CEdit findTextEdit; + CButton findButton; + CButton editButton; + CButton newButton; + CButton reloadButton; + CButton cancelButton; + //}}AFX_DATA + + static toolTip_t toolTips[]; + + CRect initialRect; + CPathTreeCtrl baseDeclTree; + int numListedDecls; + idStr findNameString; + idStr findTextString; + + TCHAR * m_pchTip; + WCHAR * m_pwchTip; + +private: + void AddDeclTypeToTree( declType_t type, const char *root, CPathTreeCtrl &tree ); + void AddScriptsToTree( CPathTreeCtrl &tree ); + void AddGUIsToTree( CPathTreeCtrl &tree ); + void InitBaseDeclTree( void ); + + void GetDeclName( HTREEITEM item, idStr &typeName, idStr &declName ) const; + const idDecl * GetDeclFromTreeItem( HTREEITEM item ) const; + const idDecl * GetSelectedDecl( void ) const; + void EditSelected( void ) const; +}; + +#endif /* !__DIALOGDECLBROWSER_H__ */ diff --git a/tools/decl/DialogDeclEditor.cpp b/tools/decl/DialogDeclEditor.cpp new file mode 100644 index 000000000..05ccfa997 --- /dev/null +++ b/tools/decl/DialogDeclEditor.cpp @@ -0,0 +1,706 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/Common_resource.h" +#include "../../sys/win32/rc/DeclEditor_resource.h" + +#include "../comafx/DialogGoToLine.h" +#include "../comafx/CPathTreeCtrl.h" +#include "DialogDeclBrowser.h" +#include "DialogDeclEditor.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +// DialogDeclEditor dialog + +static UINT FindDialogMessage = ::RegisterWindowMessage( FINDMSGSTRING ); + +toolTip_t DialogDeclEditor::toolTips[] = { + { IDC_DECLEDITOR_BUTTON_TEST, "test decl" }, + { IDOK, "save decl" }, + { IDCANCEL, "cancel" }, + { 0, NULL } +}; + + +IMPLEMENT_DYNAMIC(DialogDeclEditor, CDialog) + +/* +================ +DialogDeclEditor::DialogDeclEditor +================ +*/ +DialogDeclEditor::DialogDeclEditor( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogDeclEditor::IDD, pParent) + , findDlg(NULL) + , matchCase(false) + , matchWholeWords(false) + , decl(NULL) + , firstLine(0) +{ +} + +/* +================ +DialogDeclEditor::~DialogDeclEditor +================ +*/ +DialogDeclEditor::~DialogDeclEditor() { +} + +/* +================ +DialogDeclEditor::DoDataExchange +================ +*/ +void DialogDeclEditor::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogDeclEditor) + DDX_Control(pDX, IDC_DECLEDITOR_EDIT_TEXT, declEdit); + DDX_Control(pDX, IDC_DECLEDITOR_BUTTON_TEST, testButton); + DDX_Control(pDX, IDOK, okButton); + DDX_Control(pDX, IDCANCEL, cancelButton); + //}}AFX_DATA_MAP +} + +/* +================ +DialogDeclEditor::PreTranslateMessage +================ +*/ +BOOL DialogDeclEditor::PreTranslateMessage( MSG* pMsg ) { + if ( WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST ) { + if ( m_hAccel && ::TranslateAccelerator( m_hWnd, m_hAccel, pMsg ) ) { + return TRUE; + } + } + return CWnd::PreTranslateMessage(pMsg); +} + +/* +================ +DialogDeclEditor::TestDecl +================ +*/ +bool DialogDeclEditor::TestDecl( const idStr &declText ) { + idLexer src( LEXFL_NOSTRINGCONCAT ); + idToken token; + int indent; + + src.LoadMemory( declText, declText.Length(), "decl text" ); + + indent = 0; + while( src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + } + } + + if ( indent < 0 ) { + MessageBox( "Missing opening brace!", va( "Error saving %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return false; + } + if ( indent > 0 ) { + MessageBox( "Missing closing brace!", va( "Error saving %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return false; + } + return true; +} + +/* +================ +DialogDeclEditor::UpdateStatusBar +================ +*/ +void DialogDeclEditor::UpdateStatusBar( void ) { + int line, column, character; + + if ( decl ) { + declEdit.GetCursorPos( line, column, character ); + statusBar.SetWindowText( va( "Line: %d, Column: %d, Character: %d", decl->GetLineNum() + line, column, character ) ); + } +} + +/* +================ +DialogDeclEditor::LoadDecl +================ +*/ +void DialogDeclEditor::LoadDecl( idDecl *decl ) { + int numLines = 0; + int numCharsPerLine = 0; + int maxCharsPerLine = 0; + idStr declText; + CRect rect; + + this->decl = decl; + + switch( decl->GetType() ) { + case DECL_ENTITYDEF: + declEdit.SetStringColor( SRE_COLOR_BLUE, SRE_COLOR_DARK_CYAN ); + declEdit.LoadKeyWordsFromFile( "editors/entity.def" ); + break; + case DECL_MATERIAL: + declEdit.LoadKeyWordsFromFile( "editors/material.def" ); + break; + case DECL_SKIN: + declEdit.LoadKeyWordsFromFile( "editors/skin.def" ); + break; + case DECL_SOUND: + declEdit.LoadKeyWordsFromFile( "editors/sound.def" ); + break; + case DECL_FX: + declEdit.LoadKeyWordsFromFile( "editors/fx.def" ); + break; + case DECL_PARTICLE: + declEdit.LoadKeyWordsFromFile( "editors/particle.def" ); + break; + case DECL_AF: + declEdit.LoadKeyWordsFromFile( "editors/af.def" ); + break; + case DECL_TABLE: + declEdit.LoadKeyWordsFromFile( "editors/table.def" ); + break; + case DECL_MODELDEF: + declEdit.LoadKeyWordsFromFile( "editors/model.def" ); + break; + default: + declEdit.LoadKeyWordsFromFile( va( "editors/%s.def", declManager->GetDeclNameFromType( decl->GetType() ) ) ); + break; + } + + firstLine = decl->GetLineNum(); + + char *localDeclText = (char *)_alloca( ( decl->GetTextLength() + 1 ) * sizeof( char ) ); + decl->GetText( localDeclText ); + declText = localDeclText; + + // clean up new-line crapola + declText.Replace( "\r", "" ); + declText.Replace( "\n", "\r" ); + declText.Replace( "\v", "\r" ); + declText.StripLeading( '\r' ); + declText.Append( "\r" ); + + declEdit.SetText( declText ); + + for( const char *ptr = declText.c_str(); *ptr; ptr++ ) { + if ( *ptr == '\r' ) { + if ( numCharsPerLine > maxCharsPerLine ) { + maxCharsPerLine = numCharsPerLine; + } + numCharsPerLine = 0; + numLines++; + } else if ( *ptr == '\t' ) { + numCharsPerLine += TAB_SIZE; + } else { + numCharsPerLine++; + } + } + + SetWindowText( va( "Declaration Editor (%s, line %d)", decl->GetFileName(), decl->GetLineNum() ) ); + + rect.left = initialRect.left; + rect.right = rect.left + maxCharsPerLine * FONT_WIDTH + 32; + rect.top = initialRect.top; + rect.bottom = rect.top + numLines * (FONT_HEIGHT+8) + 24 + 56; + if ( rect.right < initialRect.right ) { + rect.right = initialRect.right; + } else if ( rect.right - rect.left > 1024 ) { + rect.right = rect.left + 1024; + } + if ( rect.bottom < initialRect.bottom ) { + rect.bottom = initialRect.bottom; + } else if ( rect.bottom - rect.top > 768 ) { + rect.bottom = rect.top + 768; + } + MoveWindow( rect ); + + testButton.EnableWindow( FALSE ); + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); + + declEdit.SetFocus(); +} + +/* +================ +DialogDeclEditor::OnInitDialog +================ +*/ +BOOL DialogDeclEditor::OnInitDialog() { + + com_editors |= EDITOR_DECL; + + CDialog::OnInitDialog(); + + // load accelerator table + m_hAccel = ::LoadAccelerators( AfxGetResourceHandle(), MAKEINTRESOURCE( IDR_ACCELERATOR_DECLEDITOR ) ); + + // create status bar + statusBar.CreateEx( SBARS_SIZEGRIP, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, initialRect, this, AFX_IDW_STATUS_BAR ); + + declEdit.Init(); + + GetClientRect( initialRect ); + + EnableToolTips( TRUE ); + + testButton.EnableWindow( FALSE ); + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); + + return FALSE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +BEGIN_MESSAGE_MAP(DialogDeclEditor, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_MOVE() + ON_WM_SIZE() + ON_WM_SIZING() + ON_WM_SETFOCUS() + ON_COMMAND(ID_EDIT_FIND, OnEditFind) + ON_COMMAND(ID_EDIT_REPLACE, OnEditReplace) + ON_COMMAND(ID_DECLEDITOR_FIND_NEXT, OnEditFindNext) + ON_COMMAND(ID_DECLEDITOR_GOTOLINE, OnEditGoToLine) + ON_REGISTERED_MESSAGE(FindDialogMessage, OnFindDialogMessage) + ON_NOTIFY(EN_CHANGE, IDC_DECLEDITOR_EDIT_TEXT, OnEnChangeEdit) + ON_NOTIFY(EN_MSGFILTER, IDC_DECLEDITOR_EDIT_TEXT, OnEnInputEdit) + ON_BN_CLICKED(IDC_DECLEDITOR_BUTTON_TEST, OnBnClickedTest) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) +END_MESSAGE_MAP() + + +// DialogDeclEditor message handlers + +/* +================ +DialogDeclEditor::OnActivate +================ +*/ +void DialogDeclEditor::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogDeclEditor::OnToolTipNotify +================ +*/ +BOOL DialogDeclEditor::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogDeclEditor::OnSetFocus +================ +*/ +void DialogDeclEditor::OnSetFocus( CWnd *pOldWnd ) { + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogDeclEditor::OnDestroy +================ +*/ +void DialogDeclEditor::OnDestroy() { + return CDialog::OnDestroy(); +} + +/* +================ +DialogDeclEditor::OnMove +================ +*/ +void DialogDeclEditor::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +/* +================ +DialogDeclEditor::OnSize +================ +*/ +#define BORDER_SIZE 0 +#define BUTTON_SPACE 4 +#define TOOLBAR_HEIGHT 24 + +void DialogDeclEditor::OnSize( UINT nType, int cx, int cy ) { + CRect clientRect, rect; + + LockWindowUpdate(); + + CDialog::OnSize( nType, cx, cy ); + + GetClientRect( clientRect ); + + if ( declEdit.GetSafeHwnd() ) { + rect.left = BORDER_SIZE; + rect.top = BORDER_SIZE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - 56; + declEdit.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( testButton.GetSafeHwnd() ) { + testButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = BORDER_SIZE; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = BORDER_SIZE + width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + testButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( okButton.GetSafeHwnd() ) { + okButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - 2 * width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + okButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( cancelButton.GetSafeHwnd() ) { + cancelButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = clientRect.Width() - BORDER_SIZE - width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + cancelButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( statusBar.GetSafeHwnd() ) { + rect.left = clientRect.Width() - 2; + rect.top = clientRect.Height() - 2; + rect.right = clientRect.Width() - 2; + rect.bottom = clientRect.Height() - 2; + statusBar.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + UnlockWindowUpdate(); +} + +/* +================ +DialogDeclEditor::OnSizing +================ +*/ +void DialogDeclEditor::OnSizing( UINT nSide, LPRECT lpRect ) { + /* + 1 = left + 2 = right + 3 = top + 4 = left - top + 5 = right - top + 6 = bottom + 7 = left - bottom + 8 = right - bottom + */ + + CDialog::OnSizing( nSide, lpRect ); + + if ( ( nSide - 1 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->left = lpRect->right - initialRect.Width(); + } + } else if ( ( nSide - 2 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->right = lpRect->left + initialRect.Width(); + } + } + if ( nSide >= 3 && nSide <= 5 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->top = lpRect->bottom - initialRect.Height(); + } + } else if ( nSide >= 6 && nSide <= 9 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->bottom = lpRect->top + initialRect.Height(); + } + } +} + +/* +================ +DialogDeclEditor::OnEditGoToLine +================ +*/ +void DialogDeclEditor::OnEditGoToLine() { + DialogGoToLine goToLineDlg; + + goToLineDlg.SetRange( firstLine, firstLine + declEdit.GetLineCount() - 1 ); + if ( goToLineDlg.DoModal() != IDOK ) { + return; + } + declEdit.GoToLine( goToLineDlg.GetLine() - firstLine ); +} + +/* +================ +DialogDeclEditor::OnEditFind +================ +*/ +void DialogDeclEditor::OnEditFind() { + + CString selText = declEdit.GetSelText(); + if ( selText.GetLength() ) { + findStr = selText; + } + + if ( !findDlg ) { + // create find/replace dialog + findDlg = new CFindReplaceDialog(); // Must be created on the heap + findDlg->Create( TRUE, findStr, "", FR_DOWN, this ); + } +} + +/* +================ +DialogDeclEditor::OnEditFindNext +================ +*/ +void DialogDeclEditor::OnEditFindNext() { + if ( declEdit.FindNext( findStr, matchCase, matchWholeWords, searchForward ) ) { + declEdit.SetFocus(); + } else { + AfxMessageBox( "The specified text was not found.", MB_OK | MB_ICONINFORMATION, 0 ); + } +} + +/* +================ +DialogDeclEditor::OnEditReplace +================ +*/ +void DialogDeclEditor::OnEditReplace() { + + CString selText = declEdit.GetSelText(); + if ( selText.GetLength() ) { + findStr = selText; + } + + // create find/replace dialog + if ( !findDlg ) { + findDlg = new CFindReplaceDialog(); // Must be created on the heap + findDlg->Create( FALSE, findStr, "", FR_DOWN, this ); + } +} + +/* +================ +DialogDeclEditor::OnFindDialogMessage +================ +*/ +LRESULT DialogDeclEditor::OnFindDialogMessage( WPARAM wParam, LPARAM lParam ) { + if ( findDlg == NULL ) { + return 0; + } + + if ( findDlg->IsTerminating() ) { + findDlg = NULL; + return 0; + } + + if( findDlg->FindNext() ) { + findStr = findDlg->GetFindString(); + matchCase = findDlg->MatchCase() != FALSE; + matchWholeWords = findDlg->MatchWholeWord() != FALSE; + searchForward = findDlg->SearchDown() != FALSE; + + OnEditFindNext(); + } + + if ( findDlg->ReplaceCurrent() ) { + long selStart, selEnd; + + replaceStr = findDlg->GetReplaceString(); + + declEdit.GetSel( selStart, selEnd ); + if ( selEnd > selStart ) { + declEdit.ReplaceSel( replaceStr, TRUE ); + } + } + + if ( findDlg->ReplaceAll() ) { + replaceStr = findDlg->GetReplaceString(); + findStr = findDlg->GetFindString(); + matchCase = findDlg->MatchCase() != FALSE; + matchWholeWords = findDlg->MatchWholeWord() != FALSE; + + int numReplaces = declEdit.ReplaceAll( findStr, replaceStr, matchCase, matchWholeWords ); + if ( numReplaces == 0 ) { + AfxMessageBox( "The specified text was not found.", MB_OK | MB_ICONINFORMATION, 0 ); + } else { + AfxMessageBox( va( "Replaced %d occurances.", numReplaces ), MB_OK | MB_ICONINFORMATION, 0 ); + } + } + + return 0; +} + +/* +================ +DialogDeclEditor::OnEnChangeEdit +================ +*/ +void DialogDeclEditor::OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + testButton.EnableWindow( TRUE ); + okButton.EnableWindow( TRUE ); +} + +/* +================ +DialogDeclEditor::OnEnInputEdit +================ +*/ +void DialogDeclEditor::OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + MSGFILTER *msgFilter = (MSGFILTER *)pNMHDR; + + if ( msgFilter->msg != 512 && msgFilter->msg != 33 ) { + UpdateStatusBar(); + } + + *pResult = 0; +} + +/* +================ +DialogDeclEditor::OnBnClickedTest +================ +*/ +void DialogDeclEditor::OnBnClickedTest() { + idStr declText; + + if ( decl ) { + + declEdit.GetText( declText ); + + // clean up new-line crapola + declText.Replace( "\n", "" ); + declText.Replace( "\r", "\r\n" ); + declText.Replace( "\v", "\r\n" ); + declText.StripLeading( "\r\n" ); + declText.Insert( "\r\n\r\n", 0 ); + declText.StripTrailing( "\r\n" ); + + if ( !TestDecl( declText ) ) { + return; + } + + char *oldDeclText = (char *)_alloca( ( decl->GetTextLength() + 1 ) * sizeof( char ) ); + decl->GetText( oldDeclText ); + decl->SetText( declText ); + decl->Invalidate(); + declManager->DeclByIndex( decl->GetType(), decl->Index(), true ); + decl->SetText( oldDeclText ); + decl->Invalidate(); + common->Printf( "tested %s\n", decl->GetName() ); + + testButton.EnableWindow( FALSE ); + } +} + +/* +================ +DialogDeclEditor::OnBnClickedOk +================ +*/ +void DialogDeclEditor::OnBnClickedOk() { + idStr declText; + + if ( decl ) { + + declEdit.GetText( declText ); + + // clean up new-line crapola + declText.Replace( "\n", "" ); + declText.Replace( "\r", "\r\n" ); + declText.Replace( "\v", "\r\n" ); + declText.StripLeading( "\r\n" ); + declText.Insert( "\r\n\r\n", 0 ); + declText.StripTrailing( "\r\n" ); + + if ( !TestDecl( declText ) ) { + return; + } + + if ( decl->SourceFileChanged() ) { + if ( MessageBox( va( "Declaration file %s has been modified outside of the editor.\r\nReload declarations and save?", decl->GetFileName() ), + va( "Warning saving: %s", decl->GetFileName() ), MB_OKCANCEL | MB_ICONERROR ) != IDOK ) { + return; + } + declManager->Reload( false ); + DeclBrowserReloadDeclarations(); + } + + decl->SetText( declText ); + if ( !decl->ReplaceSourceFileText() ) { + MessageBox( va( "Couldn't save: %s.\r\nMake sure the declaration file is not read-only.", decl->GetFileName() ), + va( "Error saving: %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return; + } + decl->Invalidate(); + } + + okButton.EnableWindow( FALSE ); +} + +/* +================ +DialogDeclEditor::OnBnClickedCancel +================ +*/ +void DialogDeclEditor::OnBnClickedCancel() { + if ( okButton.IsWindowEnabled() ) { + if ( MessageBox( "Cancel changes?", "Cancel", MB_YESNO | MB_ICONQUESTION ) != IDYES ) { + return; + } + } + OnCancel(); +} diff --git a/tools/decl/DialogDeclEditor.h b/tools/decl/DialogDeclEditor.h new file mode 100644 index 000000000..ea33becb4 --- /dev/null +++ b/tools/decl/DialogDeclEditor.h @@ -0,0 +1,97 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGDECLEDITOR_H__ +#define __DIALOGDECLEDITOR_H__ + +#pragma once + +#include "../comafx/CSyntaxRichEditCtrl.h" + +// DialogDeclEditor dialog + +class DialogDeclEditor : public CDialog { + + DECLARE_DYNAMIC(DialogDeclEditor) + +public: + DialogDeclEditor( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogDeclEditor(); + + void LoadDecl( idDecl *decl ); + + //{{AFX_VIRTUAL(DialogDeclEditor) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual BOOL PreTranslateMessage( MSG* pMsg ); + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(DialogDeclEditor) + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized ); + afx_msg void OnMove( int x, int y ); + afx_msg void OnSize( UINT nType, int cx, int cy ); + afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); + afx_msg void OnEditGoToLine(); + afx_msg void OnEditFind(); + afx_msg void OnEditFindNext(); + afx_msg void OnEditReplace(); + afx_msg LRESULT OnFindDialogMessage( WPARAM wParam, LPARAM lParam ); + afx_msg void OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedTest(); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedCancel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + + //{{AFX_DATA(DialogDeclEditor) + enum { IDD = IDD_DIALOG_DECLEDITOR }; + CStatusBarCtrl statusBar; + CSyntaxRichEditCtrl declEdit; + CButton testButton; + CButton okButton; + CButton cancelButton; + //}}AFX_DATA + + static toolTip_t toolTips[]; + + HACCEL m_hAccel; + CRect initialRect; + CFindReplaceDialog *findDlg; + CString findStr; + CString replaceStr; + bool matchCase; + bool matchWholeWords; + bool searchForward; + idDecl * decl; + int firstLine; + +private: + bool TestDecl( const idStr &declText ); + void UpdateStatusBar( void ); +}; + +#endif /* !__DIALOGDECLEDITOR_H__ */ diff --git a/tools/decl/DialogDeclNew.cpp b/tools/decl/DialogDeclNew.cpp new file mode 100644 index 000000000..1159f047c --- /dev/null +++ b/tools/decl/DialogDeclNew.cpp @@ -0,0 +1,270 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/DeclEditor_resource.h" + +#include "../comafx/CPathTreeCtrl.h" +#include "DialogDeclBrowser.h" +#include "DialogDeclNew.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +toolTip_t DialogDeclNew::toolTips[] = { + { IDC_DECLNEW_COMBO_NEW_TYPE, "select the declaration type to create" }, + { IDC_DECLNEW_EDIT_NEW_NAME, "enter a name for the new declaration" }, + { IDC_DECLNEW_EDIT_NEW_FILE, "enter the name of the file to add the declaration to" }, + { IDC_DECLNEW_BUTTON_NEW_FILE, "select existing file to add the declaration to" }, + { IDOK, "create new declaration" }, + { IDCANCEL, "cancel" }, + { 0, NULL } +}; + + +IMPLEMENT_DYNAMIC(DialogDeclNew, CDialog) + +/* +================ +DialogDeclNew::DialogDeclNew +================ +*/ +DialogDeclNew::DialogDeclNew( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogDeclNew::IDD, pParent) + , declTree(NULL) + , newDecl(NULL) +{ +} + +/* +================ +DialogDeclNew::~DialogDeclNew +================ +*/ +DialogDeclNew::~DialogDeclNew() { +} + +/* +================ +DialogDeclNew::DoDataExchange +================ +*/ +void DialogDeclNew::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogDeclNew) + DDX_Control(pDX, IDC_DECLNEW_COMBO_NEW_TYPE, typeList); + DDX_Control(pDX, IDC_DECLNEW_EDIT_NEW_NAME, nameEdit); + DDX_Control(pDX, IDC_DECLNEW_EDIT_NEW_FILE, fileEdit); + DDX_Control(pDX, IDC_DECLNEW_BUTTON_NEW_FILE, fileButton); + DDX_Control(pDX, IDOK, okButton); + DDX_Control(pDX, IDCANCEL, cancelButton); + //}}AFX_DATA_MAP +} + +/* +================ +DialogDeclNew::InitTypeList +================ +*/ +void DialogDeclNew::InitTypeList( void ) { + int i; + + typeList.ResetContent(); + for ( i = 0; i < declManager->GetNumDeclTypes(); i++ ) { + typeList.AddString( declManager->GetDeclNameFromType( (declType_t)i ) ); + } +} + +/* +================ +DialogDeclNew::OnInitDialog +================ +*/ +BOOL DialogDeclNew::OnInitDialog() { + + CDialog::OnInitDialog(); + + InitTypeList(); + + SetSafeComboBoxSelection( &typeList, defaultType.c_str(), -1 ); + nameEdit.SetWindowText( defaultName.c_str() ); + fileEdit.SetWindowText( defaultFile.c_str() ); + + EnableToolTips( TRUE ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +BEGIN_MESSAGE_MAP(DialogDeclNew, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_SETFOCUS() + ON_BN_CLICKED(IDC_DECLNEW_BUTTON_NEW_FILE, OnBnClickedFile) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) +END_MESSAGE_MAP() + + +// DialogDeclNew message handlers + +/* +================ +DialogDeclNew::OnActivate +================ +*/ +void DialogDeclNew::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogDeclNew::OnToolTipNotify +================ +*/ +BOOL DialogDeclNew::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogDeclNew::OnSetFocus +================ +*/ +void DialogDeclNew::OnSetFocus( CWnd *pOldWnd ) { + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogDeclNew::OnDestroy +================ +*/ +void DialogDeclNew::OnDestroy() { + return CDialog::OnDestroy(); +} + +/* +================ +DialogDeclNew::OnBnClickedFile +================ +*/ +void DialogDeclNew::OnBnClickedFile() { + CString typeName, folder, ext; + idStr path; + const char *errorTitle = "Error selecting file."; + + if ( GetSafeComboBoxSelection( &typeList, typeName, -1 ) == -1 ) { + MessageBox( "Select a declaration type first.", errorTitle, MB_OK ); + return; + } + + declType_t type = declManager->GetDeclTypeFromName( typeName ); + if ( type >= declManager->GetNumDeclTypes() ) { + MessageBox( "Unknown declaration type.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + switch( type ) { + case DECL_TABLE: folder = "materials"; ext = "(*.mtr)|*.mtr|(*.*)|*.*||"; break; + case DECL_MATERIAL: folder = "materials"; ext = "(*.mtr)|*.mtr|(*.*)|*.*||"; break; + case DECL_SKIN: folder = "skins"; ext = "(*.skin)|*.skin|(*.*)|*.*||"; break; + case DECL_SOUND: folder = "sound"; ext = "(*.sndshd|*.sndshd|(*.*)|*.*||"; break; + case DECL_ENTITYDEF: folder = "def"; ext = "(*.def)|*.def|(*.decl)|*.decl|(*.*)|*.*||"; break; + case DECL_MODELDEF: folder = "def"; ext = "(*.def)|*.def|(*.*)|*.*||"; break; + case DECL_FX: folder = "fx"; ext = "(*.fx)|*.fx|(*.*)|*.*||"; break; + case DECL_PARTICLE: folder = "particles"; ext = "(*.prt)|*.prt|(*.*)|*.*||"; break; + case DECL_AF: folder = "af"; ext = "(*.af)|*.af|(*.*)|*.*||"; break; + default: folder = "def"; ext = "(*.decl)|*.decl|(*.*)|*.*||"; break; + } + + path = fileSystem->RelativePathToOSPath( folder ); + path += "\\*"; + + CFileDialog dlgFile( TRUE, "decl", path, 0, ext, this ); + if ( dlgFile.DoModal() == IDOK ) { + path = fileSystem->OSPathToRelativePath( dlgFile.m_ofn.lpstrFile ); + fileEdit.SetWindowText( path ); + } +} + +/* +================ +DialogDeclNew::OnBnClickedOk +================ +*/ +void DialogDeclNew::OnBnClickedOk() { + CString typeName, declName, fileName; + const char *errorTitle = "Error creating declaration."; + + if ( !declTree ) { + MessageBox( "No declaration tree available.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + if ( GetSafeComboBoxSelection( &typeList, typeName, -1 ) == -1 ) { + MessageBox( "No declaration type selected.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + nameEdit.GetWindowText( declName ); + if ( declName.GetLength() == 0 ) { + MessageBox( "No declaration name specified.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + fileEdit.GetWindowText( fileName ); + if ( fileName.GetLength() == 0 ) { + MessageBox( "No file name specified.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + if ( declTree->FindItem( idStr( typeName + "/" + declName ) ) ) { + MessageBox( "Declaration already exists.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + declType_t type = declManager->GetDeclTypeFromName( typeName ); + if ( type >= declManager->GetNumDeclTypes() ) { + MessageBox( "Unknown declaration type.", errorTitle, MB_OK | MB_ICONERROR ); + return; + } + + newDecl = declManager->CreateNewDecl( type, declName, fileName ); + + OnOK(); +} + +/* +================ +DialogDeclNew::OnBnClickedCancel +================ +*/ +void DialogDeclNew::OnBnClickedCancel() { + OnCancel(); +} diff --git a/tools/decl/DialogDeclNew.h b/tools/decl/DialogDeclNew.h new file mode 100644 index 000000000..fa1003c5d --- /dev/null +++ b/tools/decl/DialogDeclNew.h @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGDECLNEW_H__ +#define __DIALOGDECLNEW_H__ + +#pragma once + + +// DialogDeclNew dialog + +class DialogDeclNew : public CDialog { + + DECLARE_DYNAMIC(DialogDeclNew) + +public: + DialogDeclNew( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogDeclNew(); + + void SetDeclTree( CPathTreeCtrl *tree ) { declTree = tree; } + void SetDefaultType( const char *type ) { defaultType = type; } + void SetDefaultName( const char *name ) { defaultName = name; } + void SetDefaultFile( const char *file ) { defaultFile = file; } + idDecl * GetNewDecl( void ) const { return newDecl; } + + //{{AFX_VIRTUAL(DialogDeclNew) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(DialogDeclNew) + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnBnClickedFile(); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedCancel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + + //{{AFX_DATA(DialogDeclNew) + enum { IDD = IDD_DIALOG_DECLNEW }; + CComboBox typeList; + CEdit nameEdit; + CEdit fileEdit; + CButton fileButton; + CButton okButton; + CButton cancelButton; + //}}AFX_DATA + + static toolTip_t toolTips[]; + + CPathTreeCtrl * declTree; + idStr defaultType; + idStr defaultName; + idStr defaultFile; + idDecl * newDecl; + +private: + void InitTypeList( void ); +}; + +#endif /* !__DIALOGDECLNEW_H__ */ diff --git a/tools/decl/DialogEntityDefEditor.cpp b/tools/decl/DialogEntityDefEditor.cpp new file mode 100644 index 000000000..5baa07809 --- /dev/null +++ b/tools/decl/DialogEntityDefEditor.cpp @@ -0,0 +1,851 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/Common_resource.h" +#include "../../sys/win32/rc/DeclEditor_resource.h" + +#include "../comafx/CPathTreeCtrl.h" +#include "DialogDeclBrowser.h" +#include "DialogDeclEditor.h" +#include "DialogEntityDefEditor.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +// DialogEntityDefEditor dialog + +toolTip_t DialogEntityDefEditor::toolTips[] = { + { IDC_DECLEDITOR_BUTTON_TEST, "Test Decl" }, + { IDOK, "Save Decl" }, + { IDCANCEL, "Cancel" }, + { 0, NULL } +}; + + +IMPLEMENT_DYNAMIC(DialogEntityDefEditor, CDialog) + +/* +================ +DialogEntityDefEditor::DialogEntityDefEditor +================ +*/ +DialogEntityDefEditor::DialogEntityDefEditor( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogEntityDefEditor::IDD, pParent) + , decl(NULL) + , firstLine(0) +{ +} + +/* +================ +DialogEntityDefEditor::~DialogEntityDefEditor +================ +*/ +DialogEntityDefEditor::~DialogEntityDefEditor() { +} + +/* +================ +DialogEntityDefEditor::DoDataExchange +================ +*/ +void DialogEntityDefEditor::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogEntityDefEditor) + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_EDIT_DECLNAME, declNameEdit); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_COMBO_INHERIT, inheritCombo); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_COMBO_SPAWNCLASS, spawnclassCombo); + + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_LIST_KEYVALS, keyValsList); + + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_STATIC_KEY, keyLabel); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_EDIT_KEY, keyEdit); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_BUTTON_ADD, addButton); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_BUTTON_DELETE, delButton); + DDX_Control(pDX, IDC_ENTITYDEFEDITOR_LINE, line); + + DDX_Control(pDX, IDC_DECLEDITOR_BUTTON_TEST, testButton); + DDX_Control(pDX, IDOK, okButton); + DDX_Control(pDX, IDCANCEL, cancelButton); + //}}AFX_DATA_MAP +} + +/* +================ +DialogEntityDefEditor::PreTranslateMessage +================ +*/ +BOOL DialogEntityDefEditor::PreTranslateMessage( MSG* pMsg ) { + if ( WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST ) { + if ( m_hAccel && ::TranslateAccelerator( m_hWnd, m_hAccel, pMsg ) ) { + return TRUE; + } + } + return CWnd::PreTranslateMessage(pMsg); +} + +/* +================ +DialogEntityDefEditor::TestDecl +================ +*/ +bool DialogEntityDefEditor::TestDecl( const idStr &declText ) { + idLexer src( LEXFL_NOSTRINGCONCAT ); + idToken token; + int indent; + + src.LoadMemory( declText, declText.Length(), "decl text" ); + + indent = 0; + while( src.ReadToken( &token ) ) { + if ( token == "{" ) { + indent++; + } else if ( token == "}" ) { + indent--; + } + } + + if ( indent < 0 ) { + MessageBox( "Missing opening brace!", va( "Error saving %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return false; + } + if ( indent > 0 ) { + MessageBox( "Missing closing brace!", va( "Error saving %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return false; + } + return true; +} + +/* +================ +DialogEntityDefEditor::UpdateStatusBar +================ +*/ +void DialogEntityDefEditor::UpdateStatusBar( void ) { + if ( decl ) { + statusBar.SetWindowText( "Editing decl" ); + } +} + +/* +================ +DialogEntityDefEditor::LoadDecl +================ +*/ +void DialogEntityDefEditor::LoadDecl( idDeclEntityDef *decl ) { + int numLines = 0; + CRect rect; + + this->decl = decl; + + // Fill up the spawnclass box with all spawn classes + /* + idTypeInfo *c = idClass::GetClass("idClass"); + for (; c; c = c->next) { + spawnclassCombo.AddString(c->classname); + } + */ + + // Fill up the inherit box with all entitydefs + int numDecls = declManager->GetNumDecls(DECL_ENTITYDEF); + for (int i=0; iDeclByIndex(DECL_ENTITYDEF, i, false); + if (d) { + inheritCombo.AddString(d->GetName()); + } + } + + firstLine = decl->GetLineNum(); + + char *declText = (char *)_alloca( ( decl->GetTextLength() + 1 ) * sizeof( char ) ); + decl->GetText( declText ); + + PopulateLists( declText ); + + SetWindowText( va( "EntityDef Editor (%s, line %d)", decl->GetFileName(), decl->GetLineNum() ) ); + + // Hack to get it to reflow the window + GetWindowRect( rect ); + rect.bottom++; + MoveWindow( rect ); + + testButton.EnableWindow( FALSE ); + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); +} + +/* +================= +DialogEntityDefEditor::PopulateLists +================= +*/ +void DialogEntityDefEditor::PopulateLists( const char *declText, const int textLength ) +{ + idLexer src; + idToken token, token2; + + idDict dict; + + src.LoadMemory( declText, textLength, decl->GetFileName(), firstLine); + src.SetFlags( DECL_LEXER_FLAGS ); + src.SkipUntilString( "{" ); + + while (1) { + if ( !src.ReadToken( &token ) ) { + break; + } + + if ( !token.Icmp( "}" ) ) { + break; + } + if ( token.type != TT_STRING ) { + src.Warning( "Expected quoted string, but found '%s'", token.c_str() ); + break; + } + + if ( !src.ReadToken( &token2 ) ) { + src.Warning( "Unexpected end of file" ); + break; + } + + if ( dict.FindKey( token ) ) { + src.Warning( "'%s' already defined", token.c_str() ); + } + dict.Set( token, token2 ); + } + + // Get the parent, and remove the 'inherit' key so it doesn't show up in the list + // We currently don't support multiple inheritence properly, but nothing uses it anyway + idStr inherit; + const idKeyValue *inheritKeyVal = dict.FindKey("inherit"); + if (inheritKeyVal) { + inherit = inheritKeyVal->GetValue(); + dict.Delete(inheritKeyVal->GetKey()); + } + + idStr spawnclass = dict.GetString("spawnclass", ""); + dict.Delete("spawnclass"); + + keyValsList.ResetContent(); + + // Fill up the list with all the main info + size_t numPairs = dict.Size(); + for (unsigned int i=0; iGetKey().c_str(), keyVal->GetValue().c_str(), PIT_EDIT, "")); + } + } + + //inheritCombo.SelectString(0, inherit); + SetInherit(inherit); + inheritCombo.SelectString(0, inherit); + + declNameEdit.SetWindowText(decl->GetName()); + int index = spawnclassCombo.FindString(0, spawnclass); + if (index == CB_ERR) { + index = spawnclassCombo.AddString(spawnclass); + } + spawnclassCombo.SetCurSel(index); +} + +/* +================= +DialogEntityDefEditor::SetInherit +================= +*/ + +void DialogEntityDefEditor::SetInherit(idStr &inherit) +{ + CWaitCursor wc; + + for (int i=0; im_propName[0] == '*') { + delete pItem; + keyValsList.DeleteString(i); + i--; + } + } + } + + CString spawnclass; + // Fill up the rest of the box with inherited info + if (!inherit.IsEmpty()) { + const idDecl *temp = declManager->FindType(DECL_ENTITYDEF, inherit, false); + const idDeclEntityDef *parent = static_cast(temp); + if (parent) { + size_t numPairs = parent->dict.Size(); + for (unsigned int i=0; idict.GetKeyVal(i); + if (keyVal) { + if (spawnclass.IsEmpty() && keyVal->GetKey() == "spawnclass") { + spawnclass = keyVal->GetValue(); + } + else { + CString key = keyVal->GetKey(); + key = "*" + key; + keyValsList.AddPropItem(new CPropertyItem(key, keyVal->GetValue().c_str(), PIT_EDIT, "")); + } + } + } + } + } +} + +/* +================ +DialogEntityDefEditor::OnInitDialog +================ +*/ +BOOL DialogEntityDefEditor::OnInitDialog() { + + com_editors |= EDITOR_ENTITYDEF; + + CDialog::OnInitDialog(); + + // load accelerator table + m_hAccel = ::LoadAccelerators( AfxGetResourceHandle(), MAKEINTRESOURCE( IDR_ACCELERATOR_DECLEDITOR ) ); + + // create status bar + statusBar.CreateEx( SBARS_SIZEGRIP, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, initialRect, this, AFX_IDW_STATUS_BAR ); + + GetClientRect( initialRect ); + + EnableToolTips( TRUE ); + + testButton.EnableWindow( FALSE ); + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); + + return FALSE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +BEGIN_MESSAGE_MAP(DialogEntityDefEditor, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_MOVE() + ON_WM_SIZE() + ON_WM_SIZING() + ON_WM_SETFOCUS() + ON_CBN_EDITCHANGE(IDC_ENTITYDEFEDITOR_COMBO_INHERIT, OnInheritChange) + ON_CBN_SELCHANGE(IDC_ENTITYDEFEDITOR_COMBO_INHERIT, OnInheritChange) + ON_CBN_EDITCHANGE(IDC_ENTITYDEFEDITOR_COMBO_SPAWNCLASS, OnEditChange) + ON_EN_CHANGE(IDC_ENTITYDEFEDITOR_EDIT_DECLNAME, OnEditChange) + ON_NOTIFY(EN_MSGFILTER, IDC_DECLEDITOR_EDIT_TEXT, OnEnInputEdit) + + ON_LBN_SELCHANGE(IDC_ENTITYDEFEDITOR_LIST_KEYVALS, OnKeyValChange) + + ON_BN_CLICKED(IDC_ENTITYDEFEDITOR_BUTTON_ADD, OnBnClickedAdd) + ON_BN_CLICKED(IDC_ENTITYDEFEDITOR_BUTTON_DELETE, OnBnClickedDelete) + + ON_BN_CLICKED(IDC_DECLEDITOR_BUTTON_TEST, OnBnClickedTest) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) + +END_MESSAGE_MAP() + + +// DialogEntityDefEditor message handlers + +/* +================ +DialogEntityDefEditor::OnActivate +================ +*/ +void DialogEntityDefEditor::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogEntityDefEditor::OnToolTipNotify +================ +*/ +BOOL DialogEntityDefEditor::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogEntityDefEditor::OnSetFocus +================ +*/ +void DialogEntityDefEditor::OnSetFocus( CWnd *pOldWnd ) { + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogEntityDefEditor::OnDestroy +================ +*/ +void DialogEntityDefEditor::OnDestroy() { + return CDialog::OnDestroy(); +} + +/* +================ +DialogEntityDefEditor::OnMove +================ +*/ +void DialogEntityDefEditor::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +/* +================ +DialogEntityDefEditor::OnSize +================ +*/ +#define BORDER_SIZE 4 +#define BUTTON_SPACE 4 +#define CONTROL_HEIGHT 24 +#define TOOLBAR_HEIGHT 24 + +void DialogEntityDefEditor::OnSize( UINT nType, int cx, int cy ) { + CRect clientRect, rect; + + LockWindowUpdate(); + + CDialog::OnSize( nType, cx, cy ); + + GetClientRect( clientRect ); + + if ( keyValsList.GetSafeHwnd() ) { + keyValsList.GetClientRect( rect ); + rect.left = BORDER_SIZE; + rect.right = clientRect.right - BORDER_SIZE; + rect.top = (TOOLBAR_HEIGHT * 2) + (BUTTON_SPACE * 3); + rect.bottom = clientRect.bottom - (TOOLBAR_HEIGHT * 4) - BUTTON_SPACE; + keyValsList.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + int keyRowTop = clientRect.Height() - TOOLBAR_HEIGHT * 3 - CONTROL_HEIGHT; + int keyRowBottom = keyRowTop + CONTROL_HEIGHT; + + int lineTop = clientRect.Height() - TOOLBAR_HEIGHT * 3 + (CONTROL_HEIGHT / 2); + + int buttonRowTop = clientRect.Height() - TOOLBAR_HEIGHT - CONTROL_HEIGHT; + int buttonRowBottom = buttonRowTop + CONTROL_HEIGHT; + + if ( keyLabel.GetSafeHwnd() ) { + keyLabel.GetClientRect( rect ); + int width = rect.Width(); + rect.left = BORDER_SIZE; + rect.right = BORDER_SIZE + width; + rect.top = keyRowTop + 8; + rect.bottom = keyRowBottom; + keyLabel.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( keyEdit.GetSafeHwnd() ) { + keyEdit.GetClientRect( rect ); + rect.left = 40; + rect.right = 40 + 200; + rect.top = keyRowTop; + rect.bottom = keyRowBottom; + keyEdit.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + + if ( addButton.GetSafeHwnd() ) { + addButton.GetClientRect( rect ); + int width = rect.Width(); + rect.left = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - 2 * width; + rect.right = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - width; + rect.top = keyRowTop; + rect.bottom = keyRowBottom; + addButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( delButton.GetSafeHwnd() ) { + delButton.GetClientRect( rect ); + int width = rect.Width(); + rect.left = clientRect.Width() - BORDER_SIZE - width; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.top = keyRowTop; + rect.bottom = keyRowBottom; + delButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( line.GetSafeHwnd() ) { + line.GetClientRect( rect ); + int height = rect.Height(); + rect.left = BORDER_SIZE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.top = lineTop; + rect.bottom = lineTop + 3; + line.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( testButton.GetSafeHwnd() ) { + testButton.GetClientRect( rect ); + int width = rect.Width(); + rect.left = BORDER_SIZE; + rect.right = BORDER_SIZE + width; + rect.top = buttonRowTop; + rect.bottom = buttonRowBottom; + testButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( okButton.GetSafeHwnd() ) { + okButton.GetClientRect( rect ); + int width = rect.Width(); + rect.left = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - 2 * width; + rect.right = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - width; + rect.top = buttonRowTop; + rect.bottom = buttonRowBottom; + okButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( cancelButton.GetSafeHwnd() ) { + cancelButton.GetClientRect( rect ); + int width = rect.Width(); + rect.left = clientRect.Width() - BORDER_SIZE - width; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.top = buttonRowTop; + rect.bottom = buttonRowBottom; + cancelButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( statusBar.GetSafeHwnd() ) { + rect.left = clientRect.Width() - 2; + rect.top = clientRect.Height() - 2; + rect.right = clientRect.Width() - 2; + rect.bottom = clientRect.Height() - 2; + statusBar.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + UnlockWindowUpdate(); +} + +/* +================ +DialogEntityDefEditor::OnSizing +================ +*/ +void DialogEntityDefEditor::OnSizing( UINT nSide, LPRECT lpRect ) { + /* + 1 = left + 2 = right + 3 = top + 4 = left - top + 5 = right - top + 6 = bottom + 7 = left - bottom + 8 = right - bottom + */ + + CDialog::OnSizing( nSide, lpRect ); + + if ( ( nSide - 1 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->left = lpRect->right - initialRect.Width(); + } + } else if ( ( nSide - 2 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->right = lpRect->left + initialRect.Width(); + } + } + if ( nSide >= 3 && nSide <= 5 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->top = lpRect->bottom - initialRect.Height(); + } + } else if ( nSide >= 6 && nSide <= 9 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->bottom = lpRect->top + initialRect.Height(); + } + } +} + +/* +================ +DialogEntityDefEditor::OnEditChange +================ +*/ +void DialogEntityDefEditor::OnEditChange( ) { + testButton.EnableWindow( TRUE ); + okButton.EnableWindow( TRUE ); +} + +/* +================ +DialogEntityDefEditor::OnInheritChange +================ +*/ +void DialogEntityDefEditor::OnInheritChange( ) { + testButton.EnableWindow( TRUE ); + okButton.EnableWindow( TRUE ); + + idStr inherit = ""; + + int sel = inheritCombo.GetCurSel(); + if ( sel == CB_ERR ) { + CString temp; + inheritCombo.GetWindowText( temp ); + inherit = temp; + } else { + CString temp; + inheritCombo.GetLBText( sel, temp ); + inherit = temp; + } + SetInherit(inherit); +} + + +/* +================ +DialogEntityDefEditor::OnEnInputEdit +================ +*/ +void DialogEntityDefEditor::OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + MSGFILTER *msgFilter = (MSGFILTER *)pNMHDR; + + if ( msgFilter->msg != 512 && msgFilter->msg != 33 ) { + UpdateStatusBar(); + } + + *pResult = 0; +} + +/* +================ +DialogEntityDefEditor::BuildDeclText +================ +*/ + +void DialogEntityDefEditor::BuildDeclText( idStr &declText ) +{ + CString declName; + declNameEdit.GetWindowText(declName); + CString inherit; + inheritCombo.GetWindowText(inherit); + CString spawnclass; + spawnclassCombo.GetWindowText(spawnclass); + + declText = "entityDef " + declName + "\r{\r"; + declText += "\"inherit\"\t\t\t\"" + inherit + "\"\r"; + declText += "\"spawnclass\"\t\t\t\"" + spawnclass + "\"\r"; + for (int i=0; im_propName[0] == '*') { + break; + } + declText += "\"" + pItem->m_propName + "\"\t\t\t\"" + pItem->m_curValue + "\"\r"; + } + } + declText += "}\r"; + + declText.Replace( "\r", "\r\n" ); + declText.Insert( "\r\n\r\n", 0 ); + declText.StripTrailing( "\r\n" ); +} + +/* +================ +DialogEntityDefEditor::OnBnClickedTest +================ +*/ +void DialogEntityDefEditor::OnBnClickedTest() { + idStr declText, oldDeclText; + + if ( decl ) { + + BuildDeclText(declText); + + if ( !TestDecl( declText ) ) { + return; + } + + char *oldDeclText = (char *)_alloca( ( decl->GetTextLength() + 1 ) * sizeof( char ) ); + decl->GetText( oldDeclText ); + decl->SetText( declText ); + decl->Invalidate(); + declManager->DeclByIndex( decl->GetType(), decl->Index(), true ); + decl->SetText( oldDeclText ); + decl->Invalidate(); + common->Printf( "tested %s\n", decl->GetName() ); + + testButton.EnableWindow( FALSE ); + } +} + +/* +================ +DialogEntityDefEditor::OnBnClickedOk +================ +*/ +void DialogEntityDefEditor::OnBnClickedOk() { + if ( decl ) { + + idStr declText; + BuildDeclText(declText); + + if ( !TestDecl( declText ) ) { + return; + } + + if ( decl->SourceFileChanged() ) { + if ( MessageBox( va( "Declaration file %s has been modified outside of the editor.\r\nReload declarations and save?", decl->GetFileName() ), + va( "Warning saving: %s", decl->GetFileName() ), MB_OKCANCEL | MB_ICONERROR ) != IDOK ) { + return; + } + declManager->Reload( false ); + DeclBrowserReloadDeclarations(); + } + + decl->SetText( declText ); + if ( !decl->ReplaceSourceFileText() ) { + MessageBox( va( "Couldn't save: %s.\r\nMake sure the declaration file is not read-only.", decl->GetFileName() ), + va( "Error saving: %s", decl->GetFileName() ), MB_OK | MB_ICONERROR ); + return; + } + decl->Invalidate(); + } + + okButton.EnableWindow( FALSE ); +} + +/* +================ +DialogEntityDefEditor::OnBnClickedCancel +================ +*/ +void DialogEntityDefEditor::OnBnClickedCancel() { + if ( okButton.IsWindowEnabled() ) { + if ( MessageBox( "Cancel changes?", "Cancel", MB_YESNO | MB_ICONQUESTION ) != IDYES ) { + return; + } + } + OnCancel(); +} + +/* +================ +DialogEntityDefEditor::OnKeyValChange +================ +*/ +void DialogEntityDefEditor::OnKeyValChange() { + int sel = keyValsList.GetCurSel(); + if (sel >= 0) { + CPropertyItem *pItem = (CPropertyItem *)keyValsList.GetItemDataPtr(sel); + keyEdit.SetWindowText(pItem->m_propName); + } +} + +/* +================ +DialogEntityDefEditor::OnBnClickedAdd +================ +*/ +void DialogEntityDefEditor::OnBnClickedAdd() { + CString newKey; + keyEdit.GetWindowText(newKey); + + int matchedInherit = -1; + int matchedKey = -1; + + // See if this key already exists + for (int i=0; im_propName[0] == '*') { + if (newKey = pItem->m_propName.Mid(1)) { + matchedInherit = i; + } + } + else if (pItem->m_propName == newKey) { + matchedKey = i; + break; + } + } + } + + if (matchedKey >= 0) { + MessageBox("Key " + newKey + " already defined"); + return; + } + + if (matchedInherit >= 0) { + delete keyValsList.GetItemDataPtr(matchedInherit); + keyValsList.DeleteString(matchedInherit); + } + keyValsList.AddPropItem(new CPropertyItem(newKey, "", PIT_EDIT, "")); +} + +/* +================ +DialogEntityDefEditor::OnBnClickedDelete +================ +*/ +void DialogEntityDefEditor::OnBnClickedDelete() { + CString delKey; + keyEdit.GetWindowText(delKey); + + int matchedInherit = -1; + int matchedKey = -1; + + // See if this key already exists + for (int i=0; im_propName[0] == '*') { + if (delKey = pItem->m_propName.Mid(1)) { + matchedInherit = i; + } + } + else if (pItem->m_propName == delKey) { + matchedKey = i; + break; + } + } + } + + if (matchedKey >= 0) { + delete keyValsList.GetItemDataPtr(matchedKey); + keyValsList.DeleteString(matchedKey); + } + else if (matchedInherit) { + MessageBox("Cannot delete an inherited value"); + } +} diff --git a/tools/decl/DialogEntityDefEditor.h b/tools/decl/DialogEntityDefEditor.h new file mode 100644 index 000000000..dbba7e925 --- /dev/null +++ b/tools/decl/DialogEntityDefEditor.h @@ -0,0 +1,108 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGENTITYDEFEDITOR_H__ +#define __DIALOGENTITYDEFEDITOR_H__ + +#pragma once + +#include "../radiant/PropertyList.h" + +// DialogEntityDefEditor dialog + +class DialogEntityDefEditor : public CDialog { + + DECLARE_DYNAMIC(DialogEntityDefEditor) + +public: + DialogEntityDefEditor( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogEntityDefEditor(); + + void LoadDecl( idDeclEntityDef *decl ); + + //{{AFX_VIRTUAL(DialogEntityDefEditor) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual BOOL PreTranslateMessage( MSG* pMsg ); + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(DialogEntityDefEditor) + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized ); + afx_msg void OnMove( int x, int y ); + afx_msg void OnSize( UINT nType, int cx, int cy ); + afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); + afx_msg LRESULT OnFindDialogMessage( WPARAM wParam, LPARAM lParam ); + afx_msg void OnEditChange(); + afx_msg void OnInheritChange(); + afx_msg void OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ); + + afx_msg void OnKeyValChange(); + + afx_msg void OnBnClickedAdd(); + afx_msg void OnBnClickedDelete(); + + afx_msg void OnBnClickedTest(); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedCancel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + + //{{AFX_DATA(DialogEntityDefEditor) + enum { IDD = IDD_DIALOG_ENTITYEDITOR }; + CStatusBarCtrl statusBar; + CEdit declNameEdit; + CComboBox inheritCombo; + CComboBox spawnclassCombo; + + CPropertyList keyValsList; + + CStatic keyLabel; + CEdit keyEdit; + CButton addButton; + CButton delButton; + CStatic line; + + CButton testButton; + CButton okButton; + CButton cancelButton; + //}}AFX_DATA + + static toolTip_t toolTips[]; + + HACCEL m_hAccel; + CRect initialRect; + idDeclEntityDef * decl; + int firstLine; + +private: + void PopulateLists(idStr &declText); + void SetInherit(idStr &inherit); + void BuildDeclText(idStr &declText); + bool TestDecl( const idStr &declText ); + void UpdateStatusBar( void ); +}; + +#endif /* !__DIALOGENTITYDEFEDITOR_H__ */ diff --git a/tools/default.svnprops b/tools/default.svnprops deleted file mode 100644 index c724f4579..000000000 Binary files a/tools/default.svnprops and /dev/null differ diff --git a/tools/edit_public.h b/tools/edit_public.h new file mode 100644 index 000000000..82c30f60b --- /dev/null +++ b/tools/edit_public.h @@ -0,0 +1,108 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __EDIT_PUBLIC_H__ +#define __EDIT_PUBLIC_H__ + +/* +=============================================================================== + + Editors. + +=============================================================================== +*/ + + +class idProgram; +class idInterpreter; + + +// Radiant Level Editor +void RadiantInit( void ); +void RadiantShutdown( void ); +void RadiantRun( void ); +void RadiantPrint( const char *text ); +void RadiantSync( const char *mapName, const idVec3 &viewOrg, const idAngles &viewAngles ); + + +// in-game Light Editor +void LightEditorInit( const idDict *spawnArgs ); +void LightEditorShutdown( void ); +void LightEditorRun( void ); + + +// in-game Sound Editor +void SoundEditorInit( const idDict *spawnArgs ); +void SoundEditorShutdown( void ); +void SoundEditorRun( void ); + + +// in-game Articulated Figure Editor +void AFEditorInit( const idDict *spawnArgs ); +void AFEditorShutdown( void ); +void AFEditorRun( void ); + + +// in-game Particle Editor +void ParticleEditorInit( const idDict *spawnArgs ); +void ParticleEditorShutdown( void ); +void ParticleEditorRun( void ); + + +// in-game PDA Editor +void PDAEditorInit( const idDict *spawnArgs ); +void PDAEditorShutdown( void ); +void PDAEditorRun( void ); + + +// in-game Script Editor +void ScriptEditorInit( const idDict *spawnArgs ); +void ScriptEditorShutdown( void ); +void ScriptEditorRun( void ); + + +// in-game Declaration Browser +void DeclBrowserInit( const idDict *spawnArgs ); +void DeclBrowserShutdown( void ); +void DeclBrowserRun( void ); +void DeclBrowserReloadDeclarations( void ); + + +// GUI Editor +void GUIEditorInit( void ); +void GUIEditorShutdown( void ); +void GUIEditorRun( void ); +bool GUIEditorHandleMessage( void *msg ); + + +// Script Debugger +void DebuggerClientLaunch( void ); +void DebuggerClientInit( const char *cmdline ); +bool DebuggerServerInit( void ); +void DebuggerServerShutdown( void ); +void DebuggerServerPrint( const char *text ); +void DebuggerServerCheckBreakpoint( idInterpreter *interpreter, idProgram *program, int instructionPointer ); + +//Material Editor +void MaterialEditorInit( void ); +void MaterialEditorRun( void ); +void MaterialEditorShutdown( void ); +void MaterialEditorPrintConsole( const char *msg ); + +#endif /* !__EDIT_PUBLIC_H__ */ diff --git a/tools/edit_stub.cpp b/tools/edit_stub.cpp new file mode 100644 index 000000000..03c879039 --- /dev/null +++ b/tools/edit_stub.cpp @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +void RadiantInit( void ) { common->Printf( "The level editor Radiant only runs on Win32\n" ); } +void RadiantShutdown( void ) {} +void RadiantRun( void ) {} +void RadiantPrint( const char *text ) {} +void RadiantSync( const char *mapName, const idVec3 &viewOrg, const idAngles &viewAngles ) {} + +void LightEditorInit( const idDict *spawnArgs ) { common->Printf( "The Light Editor only runs on Win32\n" ); } +void LightEditorShutdown( void ) {} +void LightEditorRun( void ) {} + +void SoundEditorInit( const idDict *spawnArgs ) { common->Printf( "The Sound Editor only runs on Win32\n" ); } +void SoundEditorShutdown( void ) {} +void SoundEditorRun( void ) {} + +void AFEditorInit( const idDict *spawnArgs ) { common->Printf( "The Articulated Figure Editor only runs on Win32\n" ); } +void AFEditorShutdown( void ) {} +void AFEditorRun( void ) {} + +void ParticleEditorInit( const idDict *spawnArgs ) { common->Printf( "The Particle Editor only runs on Win32\n" ); } +void ParticleEditorShutdown( void ) {} +void ParticleEditorRun( void ) {} + +void ScriptEditorInit( const idDict *spawnArgs ) { common->Printf( "The Script Editor only runs on Win32\n" ); } +void ScriptEditorShutdown( void ) {} +void ScriptEditorRun( void ) {} + +void DeclBrowserInit( const idDict *spawnArgs ) { common->Printf( "The Declaration Browser only runs on Win32\n" ); } +void DeclBrowserShutdown( void ) {} +void DeclBrowserRun( void ) {} +void DeclBrowserReloadDeclarations( void ) {} + +void GUIEditorInit( void ) { common->Printf( "The GUI Editor only runs on Win32\n" ); } +void GUIEditorShutdown( void ) {} +void GUIEditorRun( void ) {} +bool GUIEditorHandleMessage( void *msg ) { return false; } + +void DebuggerClientLaunch( void ) {} +void DebuggerClientInit( const char *cmdline ) { common->Printf( "The Script Debugger Client only runs on Win32\n" ); } +bool DebuggerServerInit( void ) { return false; } +void DebuggerServerShutdown( void ) {} +void DebuggerServerPrint( const char *text ) {} +void DebuggerServerCheckBreakpoint( idInterpreter *interpreter, idProgram *program, int instructionPointer ) {} + +void PDAEditorInit( const idDict *spawnArgs ) { common->Printf( "The PDA editor only runs on Win32\n" ); } + +void MaterialEditorInit() { common->Printf( "The Material editor only runs on Win32\n" ); } +void MaterialEditorPrintConsole( const char *text ) {} diff --git a/tools/guied/GEApp.cpp b/tools/guied/GEApp.cpp new file mode 100644 index 000000000..81cb29bcb --- /dev/null +++ b/tools/guied/GEApp.cpp @@ -0,0 +1,1375 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include + +#include "../../sys/win32/rc/guied_resource.h" +#include "../../ui/DeviceContext.h" + +#include "GEApp.h" +#include "GEOptionsDlg.h" +#include "GEViewer.h" + +static const int IDM_WINDOWCHILD = 1000; +static const int ID_GUIED_FILE_MRU1 = 10000; + +static INT_PTR CALLBACK AboutDlg_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_COMMAND: + EndDialog ( hwnd, 1 ); + break; + } + + return FALSE; +} + + +rvGEApp::rvGEApp ( ) +{ + mMDIFrame = NULL; + mMDIClient = NULL; + mRecentFileMenu = NULL; + mViewer = NULL; + mRecentFileInsertPos = 0; +} + +rvGEApp::~rvGEApp ( ) +{ + DestroyAcceleratorTable ( mAccelerators ); +} + +/* +================ +rvGEApp::Initialize + +Initialize the gui editor application +================ +*/ +bool rvGEApp::Initialize ( void ) +{ + mOptions.Init(); + + // Mutually exclusive + com_editors = EDITOR_GUI; + + Sys_GrabMouseCursor( false ); + + // Load the options + mOptions.Load ( ); + + mInstance = win32.hInstance; + + // Create the accelerators + mAccelerators = LoadAccelerators ( mInstance, MAKEINTRESOURCE(IDR_GUIED_ACCELERATORS) ); + + // Register the window classes for the main frame and the mdi child window + WNDCLASSEX wndClass; + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "QUAKE4_GUIEDITOR_CLASS"; + wndClass.lpfnWndProc = FrameWndProc; + wndClass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1); + wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); + wndClass.lpszMenuName = MAKEINTRESOURCE(IDR_GUIED_MAIN); + wndClass.hInstance = mInstance; + RegisterClassEx ( &wndClass ); + + wndClass.lpszMenuName = NULL; + wndClass.lpfnWndProc = MDIChildProc; + wndClass.lpszClassName = "QUAKE4_GUIEDITOR_CHILD_CLASS"; + wndClass.style = CS_OWNDC|CS_DBLCLKS|CS_BYTEALIGNWINDOW|CS_VREDRAW|CS_HREDRAW; + wndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH ); + RegisterClassEx ( &wndClass ); + + // Create the main window + mMDIFrame = CreateWindow ( "QUAKE4_GUIEDITOR_CLASS", + "Quake IV GUI Editor", + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, mInstance, (LPVOID)this ); + + if ( !mMDIFrame ) + { + return false; + } + + SetClassLong( mMDIFrame, GCL_HICON, ( LONG )LoadIcon( win32.hInstance, MAKEINTRESOURCE( IDI_GUIED ) ) ); + + // Create the MDI window + CLIENTCREATESTRUCT ccs; + ccs.hWindowMenu = GetSubMenu ( GetMenu ( mMDIFrame ), 5 ); + ccs.idFirstChild = IDM_WINDOWCHILD; + mMDIClient = CreateWindow ( "MDICLIENT", NULL, + WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, 0, 1000, 1000, + mMDIFrame, NULL, + mInstance, &ccs ); + + if ( !mMDIClient ) + { + DestroyWindow ( mMDIFrame ); + return false; + } + + // hide the doom window by default + ::ShowWindow ( win32.hWnd, SW_HIDE ); + + // Show both windows + mOptions.GetWindowPlacement ( "mdiframe", mMDIFrame ); + ShowWindow ( mMDIFrame, SW_SHOW ); + UpdateWindow ( mMDIFrame ); + + ShowWindow ( mMDIClient, SW_SHOW ); + UpdateWindow ( mMDIClient ); + + return true; +} + + +/* +================ +rvGEApp::GetActiveWorkspace + +Retrieves the workspace pointer for the active workspace. If there is no active +workspace then it will return NULL +================ +*/ +rvGEWorkspace* rvGEApp::GetActiveWorkspace ( HWND* ret ) +{ + rvGEWorkspace* workspace; + HWND active; + + workspace = NULL; + active = (HWND)SendMessage ( mMDIClient, WM_MDIGETACTIVE, 0, NULL ); + + // Return the window handle if requested + if ( ret ) + { + *ret = active; + } + + if ( !active ) + { + return NULL; + } + + return rvGEWorkspace::GetWorkspace ( active ); +} + +/* +================ +rvGEApp::TranslateAccelerator + +Translate any accelerators destined for this window +================ +*/ +bool rvGEApp::TranslateAccelerator ( LPMSG msg ) +{ + HWND focus; + + if ( msg->message == WM_SYSCHAR ) + { + SetFocus ( GetMDIClient ( ) ); + msg->hwnd = GetMDIClient ( ); + } + + if ( mViewer ) + { + return false; + } + + focus = GetActiveWindow ( ); + + // Only use accelerators when on the main window or navigator window + if ( focus == mMDIClient || focus == mMDIFrame || + focus == GetNavigator().GetWindow ( ) ) + { + if ( ::TranslateAccelerator ( mMDIFrame, mAccelerators, msg ) ) + { + return true; + } + } + + if ( TranslateMDISysAccel ( mMDIClient, msg ) ) + { + return true; + } + + return false; +} + +/* +================ +rvGEApp::RunFrame + +Runs the current frame which causes the active window to be redrawn +================ +*/ +void rvGEApp::RunFrame ( void ) +{ + HWND wnd; + rvGEWorkspace* workspace = GetActiveWorkspace ( &wnd ); + + if ( workspace ) + { + // Render the workspace using a temp DC + HDC hDC = GetDC ( wnd ); + workspace->Render ( hDC ); + ReleaseDC ( wnd, hDC ); + + if ( mViewer ) + { + mViewer->RunFrame ( ); + } + } +} + +/* +================ +rvGEApp::FrameWndProc + +Main frame window procedure +================ +*/ +LRESULT CALLBACK rvGEApp::FrameWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + rvGEApp* app = (rvGEApp*) GetWindowLong ( hWnd, GWL_USERDATA ); + + switch ( uMsg ) + { + case WM_SIZE: + { + RECT rStatus; + RECT rClient; + + // Tell the status bar to resize + app->mStatusBar.Resize ( LOWORD(lParam), HIWORD(lParam) ); + + // Calculate the new client window rectangle (minus the status bar) + GetWindowRect ( app->mStatusBar.GetWindow ( ), &rStatus ); + GetClientRect ( hWnd, &rClient ); + + if ( app->mOptions.GetStatusBarVisible ( ) ) + { + rClient.bottom -= (rStatus.bottom-rStatus.top); + } + MoveWindow ( app->mMDIClient, 0, 0, rClient.right-rClient.left, rClient.bottom-rClient.top, FALSE ); + + return 0; + } + + case WM_ENABLE: + { + int i; + + // Synchronise all toolwindows to the same state. + for(i = 0; i < app->mToolWindows.Num(); i++) + { + if(app->mToolWindows[i] != hWnd) + { + EnableWindow(app->mToolWindows[i], wParam); + } + } + break; + } + + case WM_NCACTIVATE: + return app->ToolWindowActivate ( hWnd, uMsg, wParam, lParam ); + + case WM_ACTIVATE: + common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE ); + break; + + case WM_INITMENUPOPUP: + app->HandleInitMenu ( wParam, lParam ); + break; + + case WM_CLOSE: + while ( app->mWorkspaces.Num ( ) ) + { + SendMessage ( app->mWorkspaces[0]->GetWindow ( ), WM_CLOSE, 0, 0 ); + } + break; + + case WM_DESTROY: + app->mOptions.SetWindowPlacement ( "mdiframe", hWnd ); + app->mOptions.Save ( ); + ExitProcess(0); + break; + + case WM_COMMAND: + { + int result; + assert ( app ); + result = app->HandleCommand ( wParam, lParam ); + if ( -1 != result ) + { + return result; + } + break; + } + + case WM_CREATE: + { + LPCREATESTRUCT cs; + + cs = (LPCREATESTRUCT) lParam; + app = (rvGEApp*)cs->lpCreateParams; + + assert ( app ); + + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)app ); + + app->mMDIFrame = hWnd; + + app->InitRecentFiles ( ); + app->UpdateRecentFiles ( ); + app->mNavigator.Create ( hWnd, gApp.mOptions.GetNavigatorVisible ( ) ); + app->mTransformer.Create ( hWnd, gApp.mOptions.GetTransformerVisible ( ) ); + app->mStatusBar.Create ( hWnd, 9999, gApp.mOptions.GetStatusBarVisible ( ) ); + app->mProperties.Create ( hWnd, gApp.mOptions.GetPropertiesVisible ( ) ); + + // add all the tool windows to the tool window array + app->mToolWindows.Append ( app->mMDIFrame ); + app->mToolWindows.Append ( app->mNavigator.GetWindow ( ) ); + app->mToolWindows.Append ( app->mProperties.GetWindow ( ) ); + app->mToolWindows.Append ( app->mTransformer.GetWindow ( ) ); + + SendMessage ( app->mNavigator.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 ); + SendMessage ( app->mProperties.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 ); + SendMessage ( app->mTransformer.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 ); + + break; + } + } + + return DefFrameProc ( hWnd, app?app->mMDIClient:NULL, uMsg, wParam, lParam ); +} + +/* +================ +rvGEApp::MDIChildProc + +MDI Child window procedure +================ +*/ +LRESULT CALLBACK rvGEApp::MDIChildProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + rvGEWorkspace* workspace = (rvGEWorkspace*)GetWindowLong ( hWnd, GWL_USERDATA ); + + // Give the active workspace a chance to play with it + if ( workspace ) + { + workspace->HandleMessage ( uMsg, wParam, lParam ); + } + + switch ( uMsg ) + { + case WM_CLOSE: + workspace->GetApplication ( )->mWorkspaces.Remove ( workspace ); + break; + + case WM_CREATE: + { + LPMDICREATESTRUCT mdics; + LPCREATESTRUCT cs; + + // MDI windows have their creation params buried two levels deep, extract + // that param since it is the workspace pointer + cs = (LPCREATESTRUCT) lParam; + mdics = (LPMDICREATESTRUCT) cs->lpCreateParams; + + // Attach the workspace to the window + workspace = (rvGEWorkspace*) mdics->lParam; + workspace->Attach ( hWnd ); + + workspace->GetApplication ( )->mWorkspaces.Append ( workspace ); + + break; + } + + case WM_MDIACTIVATE: + assert ( workspace ); + if ( (HWND)lParam == hWnd ) + { + workspace->GetApplication ( )->GetNavigator().SetWorkspace(workspace); + workspace->GetApplication ( )->GetTransformer().SetWorkspace(workspace); + workspace->GetApplication ( )->GetProperties().SetWorkspace(workspace); + gApp.GetStatusBar ( ).SetSimple ( false ); + } + else if ( lParam == NULL ) + { + gApp.GetStatusBar ( ).SetSimple ( true ); + } + break; + + case WM_DESTROY: + assert ( workspace ); + workspace->Detach ( ); + delete workspace; + break; + + case WM_SETCURSOR: + return 1; + + case WM_ERASEBKGND: + return TRUE; + + case WM_PAINT: + { + HDC dc; + PAINTSTRUCT ps; + + dc = BeginPaint(hWnd, &ps); + + if ( workspace ) + { + workspace->Render ( dc ); + } + + EndPaint(hWnd, &ps); + + break; + } + } + + return DefMDIChildProc ( hWnd, uMsg, wParam, lParam ); +} + +/* +================ +rvGEApp::HandleCommandSave + +Handles the ID_GUIED_FILE_SAVE and ID_GUIED_FILE_SAVEAS commands +================ +*/ +void rvGEApp::HandleCommandSave ( rvGEWorkspace* workspace, const char* filename ) +{ + idStr realFilename; + + // See if we need to browse for a filename + if ( workspace->IsNew ( ) || filename == NULL ) + { + OPENFILENAME ofn; + char szFile[MAX_PATH]; + + strcpy ( szFile, workspace->GetFilename ( ) ); + + // Initialize OPENFILENAME + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mMDIFrame; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "GUI Files\0*.GUI\0All Files\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST; + + // Display the save dialog box. + if ( !GetSaveFileName(&ofn) ) + { + return; + } + + realFilename = ofn.lpstrFile; + realFilename.StripFileExtension ( ); + realFilename.Append ( ".gui" ); + + // If the file already exists then warn about overwriting it + if ( _taccess ( realFilename, 0 ) == 0 ) + { + if ( IDNO == MessageBox ( va("File '%s' already exists. Do you want to replace it?", realFilename.c_str()), MB_YESNO|MB_ICONQUESTION ) ) + { + return; + } + } + } + else + { + realFilename = filename; + } + + // Now performe the file save + if ( workspace->SaveFile ( realFilename ) ) + { + mOptions.AddRecentFile ( workspace->GetFilename ( ) ); + UpdateRecentFiles ( ); + } + else + { + MessageBox ( va("Could not write file '%s'", workspace->GetFilename()), MB_OK|MB_ICONERROR ); + } +} + +/* +================ +rvGEApp::HandleCommand + +Handles the WM_COMMAND message +================ +*/ +int rvGEApp::HandleCommand ( WPARAM wParam, LPARAM lParam ) +{ + HWND active; + rvGEWorkspace* workspace = GetActiveWorkspace ( &active ); + + // The recent file list needs to be handled specially + if ( LOWORD(wParam) >= ID_GUIED_FILE_MRU1 && LOWORD(wParam) < ID_GUIED_FILE_MRU1 + rvGEOptions::MAX_MRU_SIZE ) + { + OpenFile ( mOptions.GetRecentFile ( mOptions.GetRecentFileCount() - (LOWORD(wParam)-ID_GUIED_FILE_MRU1) - 1 ) ); + return 0; + } + + switch ( LOWORD ( wParam ) ) + { + case ID_GUIED_SOURCECONTROL_CHECKIN: + assert ( workspace ); + HandleCommandSave ( workspace, workspace->GetFilename ( ) ); + workspace->CheckIn ( ); + break; + + case ID_GUIED_SOURCECONTROL_CHECKOUT: + assert ( workspace ); + workspace->CheckOut ( ); + break; + + case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT: + assert ( workspace ); + if ( IDYES == MessageBox ( va("Are you sure you want to undo the checkout of the file '%s'?",workspace->GetFilename()), MB_YESNO|MB_ICONQUESTION) ) + { + workspace->UndoCheckout ( ); + } + break; + + case ID_GUIED_TOOLS_RELOADMATERIALS: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT) ) ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadImages\n" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadMaterials\n" ); + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW) ) ); + break; + + case ID_GUIED_EDIT_COPY: + assert ( workspace ); + workspace->Copy ( ); + break; + + case ID_GUIED_EDIT_PASTE: + assert ( workspace ); + workspace->Paste ( ); + break; + + case ID_GUIED_HELP_ABOUT: + DialogBox ( GetInstance(), MAKEINTRESOURCE(IDD_GUIED_ABOUT), mMDIFrame, AboutDlg_WndProc ); + break; + + case ID_GUIED_TOOLS_VIEWER: + { + if ( mViewer ) + { + break; + } + + mViewer = new rvGEViewer; + if ( !mViewer->Create ( mMDIFrame ) ) + { + delete mViewer; + mViewer = NULL; + } + + if ( workspace ) + { + if ( !workspace->IsModified () || HandleCommand ( MAKELONG(ID_GUIED_FILE_SAVE,0), 0 ) ) + { + mViewer->OpenFile ( workspace->GetFilename ( ) ); + } + } + + SetActiveWindow ( mViewer->GetWindow ( ) ); + break; + } + + case ID_GUIED_ITEM_MAKESAMESIZEWIDTH: + assert ( workspace ); + workspace->MakeSelectedSameSize ( true, false ); + break; + + case ID_GUIED_ITEM_MAKESAMESIZEBOTH: + assert ( workspace ); + workspace->MakeSelectedSameSize ( true, true ); + break; + + case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT: + assert ( workspace ); + workspace->MakeSelectedSameSize ( false, true ); + break; + + case ID_GUIED_ITEM_ALIGNLEFTS: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_LEFTS ); + break; + + case ID_GUIED_ITEM_ALIGNCENTERS: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_CENTERS ); + break; + + case ID_GUIED_ITEM_ALIGNRIGHTS: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_RIGHTS ); + break; + + case ID_GUIED_ITEM_ALIGNTOPS: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_TOPS ); + break; + + case ID_GUIED_ITEM_ALIGNMIDDLES: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_MIDDLES ); + break; + + case ID_GUIED_ITEM_ALIGNBOTTOMS: + assert ( workspace ); + workspace->AlignSelected ( rvGEWorkspace::ALIGN_BOTTOMS ); + break; + + case ID_GUIED_ITEM_ARRANGESENDBACKWARD: + assert ( workspace ); + workspace->SendSelectedBackward ( ); + break; + + case ID_GUIED_ITEM_ARRANGESENDTOBACK: + assert ( workspace ); + workspace->SendSelectedToBack( ); + break; + + case ID_GUIED_ITEM_ARRANGEBRINGFORWARD: + assert ( workspace ); + workspace->BringSelectedForward ( ); + break; + + case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT: + assert ( workspace ); + workspace->BringSelectedToFront ( ); + break; + + case ID_GUIED_ITEM_ARRANGEMAKECHILD: + assert ( workspace ); + workspace->MakeSelectedAChild ( ); + break; + + case ID_GUIED_ITEM_PROPERTIES: + assert ( workspace ); + workspace->EditSelectedProperties ( ); + break; + + case ID_GUIED_ITEM_SCRIPTS: + assert ( workspace ); + workspace->EditSelectedScripts ( ); + break; + + case ID_GUIED_ITEM_NEWWINDOWDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_NORMAL ); + break; + + case ID_GUIED_ITEM_NEWEDITDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_EDIT ); + break; + + case ID_GUIED_ITEM_NEWHTMLDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_HTML ); + break; + + case ID_GUIED_ITEM_NEWCHOICEDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_CHOICE ); + break; + + case ID_GUIED_ITEM_NEWSLIDERDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_SLIDER ); + break; + + case ID_GUIED_ITEM_NEWLISTDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_LIST ); + break; + + case ID_GUIED_ITEM_NEWBINDDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_BIND ); + break; + + case ID_GUIED_ITEM_NEWRENDERDEF: + assert ( workspace ); + workspace->AddWindow ( rvGEWindowWrapper::WT_RENDER ); + break; + + case ID_GUIED_WINDOW_TILE: + SendMessage ( mMDIClient, WM_MDITILE, 0, 0 ); + break; + + case ID_GUIED_WINDOW_CASCADE: + SendMessage ( mMDIClient, WM_MDICASCADE, 0, 0 ); + break; + + case ID_GUIED_VIEW_STATUSBAR: + { + RECT rWindow; + + mStatusBar.Show ( mOptions.GetStatusBarVisible()?false:true ); + + GetWindowRect ( mMDIFrame, &rWindow ); + SendMessage ( mMDIFrame, WM_SIZE, 0, MAKELONG ( rWindow.right-rWindow.left, rWindow.bottom-rWindow.top ) ); + break; + } + + case ID_GUIED_WINDOW_SHOWNAVIGATOR: + mNavigator.Show ( mOptions.GetNavigatorVisible()?false:true ); + break; + + case ID_GUIED_WINDOW_SHOWPROPERTIES: + mProperties.Show ( mOptions.GetPropertiesVisible()?false:true ); + break; + + case ID_GUIED_WINDOW_SHOWTRANSFORMER: + mTransformer.Show ( mOptions.GetTransformerVisible()?false:true ); + break; + + case ID_GUIED_EDIT_DELETE: + assert ( workspace ); + workspace->DeleteSelected ( ); + break; + + case ID_GUIED_VIEW_HIDESELECTED: + assert ( workspace ); + workspace->HideSelected ( ); + break; + + case ID_GUIED_VIEW_UNHIDESELECTED: + assert ( workspace ); + workspace->UnhideSelected ( ); + break; + + case ID_GUIED_VIEW_SHOWHIDDEN: + assert ( workspace ); + workspace->ShowHidden ( ); + break; + + case ID_GUIED_EDIT_UNDO: + assert ( workspace ); + workspace->GetModifierStack().Undo ( ); + mNavigator.Update ( ); + mTransformer.Update ( ); + break; + + case ID_GUIED_EDIT_REDO: + assert ( workspace ); + workspace->GetModifierStack().Redo ( ); + mNavigator.Update ( ); + mTransformer.Update ( ); + break; + + case ID_GUIED_VIEW_OPTIONS: + GEOptionsDlg_DoModal ( mMDIFrame ); + break; + + case ID_GUIED_VIEW_SHOWGRID: + mOptions.SetGridVisible ( mOptions.GetGridVisible()?false:true ); + break; + + case ID_GUIED_VIEW_SNAPTOGRID: + mOptions.SetGridSnap ( mOptions.GetGridSnap ()?false:true ); + break; + + case ID_GUIED_VIEW_ZOOMIN: + assert ( workspace ); + workspace->ZoomIn ( ); + break; + + case ID_GUIED_VIEW_ZOOMOUT: + assert ( workspace ); + workspace->ZoomOut ( ); + break; + + case ID_GUIED_FILE_EXIT: + DestroyWindow ( mMDIFrame ); + break; + + case ID_GUIED_FILE_CLOSE: + if ( active ) + { + assert ( workspace ); + SendMessage ( active, WM_CLOSE, 0, 0 ); + } + break; + + case ID_GUIED_FILE_NEW: + NewFile ( ); + break; + + case ID_GUIED_FILE_SAVE: + assert ( workspace ); + HandleCommandSave ( workspace, workspace->GetFilename ( ) ); + break; + + case ID_GUIED_FILE_SAVEAS: + assert ( workspace ); + HandleCommandSave ( workspace, NULL ); + break; + + case ID_GUIED_FILE_OPEN: + { + OPENFILENAME ofn; + char szFile[MAX_PATH] = ""; + + // Initialize OPENFILENAME + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mMDIFrame; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = "GUI Files\0*.GUI\0All Files\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + // Display the Open dialog box. + if (GetOpenFileName(&ofn)==TRUE) + { + OpenFile ( ofn.lpstrFile ); + } + break; + } + } + + return -1; +} + +/* +================ +rvGEApp::HandleInitMenu + +Handles the initialization of the main menu +================ +*/ +int rvGEApp::HandleInitMenu ( WPARAM wParam, LPARAM lParam ) +{ + int cMenuItems = GetMenuItemCount((HMENU)wParam); + int nPos; + int id; + UINT flags; + rvGEWorkspace* workspace; + HMENU hmenu; + + hmenu = (HMENU) wParam; + workspace = GetActiveWorkspace ( ); + + // Run through all the menu items in the menu and see if any of them need + // modification in any way + for (nPos = 0; nPos < cMenuItems; nPos++) + { + id = GetMenuItemID(hmenu, nPos); + flags = 0; + + // Handle popup menus too + if ( id < 0 ) + { + HMENU sub = GetSubMenu ( hmenu, nPos ); + if ( sub ) + { + HandleInitMenu ( (WPARAM) sub, 0 ); + continue; + } + } + + // Menu items that are completely unrelated to the workspace + switch ( id ) + { + case ID_GUIED_VIEW_STATUSBAR: + flags = MF_BYCOMMAND | (mOptions.GetStatusBarVisible()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + + case ID_GUIED_WINDOW_SHOWNAVIGATOR: + flags = MF_BYCOMMAND | (mOptions.GetNavigatorVisible()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + + case ID_GUIED_WINDOW_SHOWPROPERTIES: + flags = MF_BYCOMMAND | (mOptions.GetPropertiesVisible()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + + case ID_GUIED_WINDOW_SHOWTRANSFORMER: + flags = MF_BYCOMMAND | (mOptions.GetTransformerVisible()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + } + + // Handle the basic case where an item is disabled because + // there is no workspace available + if ( !workspace ) + { + switch ( id ) + { + case ID_GUIED_EDIT_UNDO: + case ID_GUIED_EDIT_REDO: + case ID_GUIED_VIEW_SHOWGRID: + case ID_GUIED_VIEW_SNAPTOGRID: + case ID_GUIED_VIEW_HIDESELECTED: + case ID_GUIED_VIEW_UNHIDESELECTED: + case ID_GUIED_EDIT_DELETE: + case ID_GUIED_WINDOW_TILE: + case ID_GUIED_WINDOW_CASCADE: + case ID_GUIED_ITEM_NEWWINDOWDEF: + case ID_GUIED_ITEM_NEWEDITDEF: + case ID_GUIED_ITEM_NEWHTMLDEF: + case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT: + case ID_GUIED_ITEM_ARRANGEBRINGFORWARD: + case ID_GUIED_ITEM_ARRANGESENDTOBACK: + case ID_GUIED_ITEM_ARRANGESENDBACKWARD: + case ID_GUIED_ITEM_PROPERTIES: + case ID_GUIED_ITEM_SCRIPTS: + case ID_GUIED_VIEW_ZOOMIN: + case ID_GUIED_VIEW_ZOOMOUT: + case ID_GUIED_ITEM_ALIGNLEFTS: + case ID_GUIED_ITEM_ALIGNCENTERS: + case ID_GUIED_ITEM_ALIGNRIGHTS: + case ID_GUIED_ITEM_ALIGNBOTTOMS: + case ID_GUIED_ITEM_ALIGNMIDDLES: + case ID_GUIED_ITEM_ALIGNTOPS: + case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT: + case ID_GUIED_ITEM_MAKESAMESIZEWIDTH: + case ID_GUIED_ITEM_MAKESAMESIZEBOTH: + case ID_GUIED_FILE_SAVE: + case ID_GUIED_FILE_SAVEAS: + case ID_GUIED_EDIT_COPY: + case ID_GUIED_EDIT_PASTE: + case ID_GUIED_ITEM_ARRANGEMAKECHILD: + case ID_GUIED_SOURCECONTROL_GETLATESTVERSION: + case ID_GUIED_SOURCECONTROL_CHECKIN: + case ID_GUIED_SOURCECONTROL_CHECKOUT: + case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT: + case ID_GUIED_FILE_CLOSE: + EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION ); + break; + } + + continue; + } + + switch (id) + { + // Undo is greyed out when there is noting to undo and the text is + // modified to include the name of the modifier that will be undone + case ID_GUIED_EDIT_UNDO: + { + MENUITEMINFO info; + idStr undo; + + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE|MIIM_TYPE; + info.fType = MFT_STRING; + + if ( !workspace->GetModifierStack().CanUndo ( ) ) + { + undo = "Undo\tCtrl+Z"; + info.fState = MFS_GRAYED; + } + else + { + undo = "Undo "; + undo.Append ( workspace->GetModifierStack().GetUndoModifier()->GetName ( ) ); + undo.Append ( "\tCtrl+Z" ); + info.fState = MFS_ENABLED; + } + + info.dwTypeData = (LPSTR)undo.c_str(); + info.cch = undo.Length ( ); + + SetMenuItemInfo ( hmenu, id, FALSE, &info ); + + break; + } + + case ID_GUIED_EDIT_REDO: + { + MENUITEMINFO info; + idStr undo; + + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE|MIIM_TYPE; + info.fType = MFT_STRING; + + if ( !workspace || !workspace->GetModifierStack().CanRedo ( ) ) + { + undo = "Redo\tCtrl+Y"; + info.fState = MFS_GRAYED; + } + else + { + undo = "Redo "; + undo.Append ( workspace->GetModifierStack().GetRedoModifier()->GetName ( ) ); + undo.Append ( "\tCtrl+Y" ); + info.fState = MFS_ENABLED; + } + + info.dwTypeData = (LPSTR)undo.c_str(); + info.cch = undo.Length ( ); + + SetMenuItemInfo ( hmenu, id, FALSE, &info ); + + break; + } + + case ID_GUIED_VIEW_SHOWGRID: + flags = MF_BYCOMMAND | (mOptions.GetGridVisible()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + + case ID_GUIED_VIEW_SNAPTOGRID: + flags = MF_BYCOMMAND | (mOptions.GetGridSnap()?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem ( hmenu, id, flags ); + break; + + // All menu items that are greyed out when there is no workspace + case ID_GUIED_WINDOW_TILE: + case ID_GUIED_WINDOW_CASCADE: + case ID_GUIED_ITEM_NEWWINDOWDEF: + case ID_GUIED_ITEM_NEWEDITDEF: + case ID_GUIED_ITEM_NEWHTMLDEF: + case ID_GUIED_VIEW_ZOOMIN: + case ID_GUIED_VIEW_ZOOMOUT: + case ID_GUIED_FILE_SAVE: + case ID_GUIED_FILE_SAVEAS: + case ID_GUIED_FILE_CLOSE: + EnableMenuItem ( hmenu, nPos, MF_ENABLED|MF_BYPOSITION); + break; + + // All menu items that are greyed out unless an item is selected + case ID_GUIED_VIEW_HIDESELECTED: + case ID_GUIED_VIEW_UNHIDESELECTED: + case ID_GUIED_EDIT_DELETE: + case ID_GUIED_EDIT_COPY: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()>0?MF_ENABLED:MF_GRAYED) ); + break; + + // Enable paste if the clipboard has something in it + case ID_GUIED_EDIT_PASTE: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetClipboard().Num()>0?MF_ENABLED:MF_GRAYED) ); + break; + + // All menu items that are greyed out unless a single item is selected + case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT: + case ID_GUIED_ITEM_ARRANGEBRINGFORWARD: + case ID_GUIED_ITEM_ARRANGESENDTOBACK: + case ID_GUIED_ITEM_ARRANGESENDBACKWARD: + case ID_GUIED_ITEM_PROPERTIES: + case ID_GUIED_ITEM_SCRIPTS: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()==1?MF_ENABLED:MF_GRAYED) ); + break; + + // All menu items that are greyed out unless multiple itmes are selected + case ID_GUIED_ITEM_ALIGNLEFTS: + case ID_GUIED_ITEM_ALIGNCENTERS: + case ID_GUIED_ITEM_ALIGNRIGHTS: + case ID_GUIED_ITEM_ALIGNBOTTOMS: + case ID_GUIED_ITEM_ALIGNMIDDLES: + case ID_GUIED_ITEM_ALIGNTOPS: + case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT: + case ID_GUIED_ITEM_MAKESAMESIZEBOTH: + case ID_GUIED_ITEM_MAKESAMESIZEWIDTH: + case ID_GUIED_ITEM_ARRANGEMAKECHILD: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()>1?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_GUIED_SOURCECONTROL_CHECKIN: + case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|((workspace->GetSourceControlState()==rvGEWorkspace::SCS_CHECKEDOUT)?MF_ENABLED:MF_GRAYED) ); + break; + + case ID_GUIED_SOURCECONTROL_CHECKOUT: + EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|((workspace->GetSourceControlState()==rvGEWorkspace::SCS_CHECKEDIN)?MF_ENABLED:MF_GRAYED) ); + break; + + default: + continue; + } + } + + return 0; +} + +/* +================ +rvGEApp::NewFile + +Creates a new file and opens a window for it +================ +*/ +bool rvGEApp::NewFile ( void ) +{ + rvGEWorkspace* workspace = new rvGEWorkspace ( this ); + if ( workspace->NewFile ( ) ) + { + HWND child; + + child = CreateMDIWindow("QUAKE4_GUIEDITOR_CHILD_CLASS", + "Untitled.gui", + WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE, + CW_USEDEFAULT, + CW_USEDEFAULT, + 640, + 480, + mMDIClient, + mInstance, + (LONG)workspace ); + + ShowWindow ( child, SW_SHOW ); + } + + return true; +} + +/* +================ +rvGEApp::OpenFile + +Opens the given file and will fail if its already open or could not +be opened for some reason +================ +*/ +bool rvGEApp::OpenFile ( const char* filename ) +{ + int i; + bool result = false; + idStr error; + + // See if the file is already open and if so just make it active + for ( i = 0; i < mWorkspaces.Num(); i ++ ) + { + if ( !idStr::Icmp ( mWorkspaces[i]->GetFilename(), filename ) ) + { + SendMessage ( mMDIClient, WM_MDIACTIVATE, (WPARAM)mWorkspaces[i]->GetWindow ( ), 0 ); + return false; + } + } + + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT ) ) ); + + // Setup the default error. + error = va("Failed to parse '%s'", filename ); + + rvGEWorkspace* workspace = new rvGEWorkspace ( this ); + if ( workspace->LoadFile ( filename, &error ) ) + { + HWND child; + + child = CreateMDIWindow("QUAKE4_GUIEDITOR_CHILD_CLASS", + "Unamed.gui", + WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE, + CW_USEDEFAULT, + CW_USEDEFAULT, + 640, + 480, + mMDIClient, + mInstance, + (LONG)workspace ); + + ShowWindow ( child, SW_SHOW ); + + mOptions.AddRecentFile ( filename ); + UpdateRecentFiles ( ); + + result = true; + } + else + { + MessageBox ( error, MB_OK|MB_ICONERROR ); + } + + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) ); + + return result;; +} + +/* +================ +rvGEApp::InitRecentFiles + +Finds the file menu and the location within it where the MRU should +be added. +================ +*/ +bool rvGEApp::InitRecentFiles ( void ) +{ + int i; + int count; + + mRecentFileMenu = GetSubMenu ( GetMenu(mMDIFrame), 0 ); + count = GetMenuItemCount ( mRecentFileMenu ); + + for ( i = 0; i < count; i ++ ) + { + if ( GetMenuItemID ( mRecentFileMenu, i ) == ID_GUIED_FILE_MRU ) + { + mRecentFileInsertPos = i; + DeleteMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION ); + return true; + } + } + + return false; +} + +/* +================ +rvGEApp::UpdateRecentFiles + +Updates the mru in the menu +================ +*/ +void rvGEApp::UpdateRecentFiles ( void ) +{ + int i; + int j; + + // Make sure everything is initialized + if ( !mRecentFileMenu ) + { + InitRecentFiles ( ); + } + + // Delete all the old recent files from the menu's + for ( i = 0; i < rvGEOptions::MAX_MRU_SIZE; i ++ ) + { + DeleteMenu ( mRecentFileMenu, ID_GUIED_FILE_MRU1 + i, MF_BYCOMMAND ); + } + + // Make sure there is a separator after the recent files + if ( mOptions.GetRecentFileCount() ) + { + MENUITEMINFO info; + ZeroMemory ( &info, sizeof(info) ); + info.cbSize = sizeof(info); + info.fMask = MIIM_FTYPE; + GetMenuItemInfo ( mRecentFileMenu, mRecentFileInsertPos+1,TRUE, &info ); + if ( !(info.fType & MFT_SEPARATOR ) ) + { + InsertMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION|MF_SEPARATOR|MF_ENABLED, 0, NULL ); + } + } + + // Add the recent files to the menu now + for ( j = 0, i = mOptions.GetRecentFileCount ( ) - 1; i >= 0; i --, j++ ) + { + UINT id = ID_GUIED_FILE_MRU1 + j; + idStr str = va("&%d ", j+1); + str.Append ( mOptions.GetRecentFile ( i ) ); + InsertMenu ( mRecentFileMenu, mRecentFileInsertPos+j+1, MF_BYPOSITION|MF_STRING|MF_ENABLED, id, str ); + } +} + +/* +================ +rvGEApp::CloseViewer + +Closes the gui viewer +================ +*/ +void rvGEApp::CloseViewer ( void ) +{ + if ( !mViewer ) + { + return; + } + + mViewer->Destroy ( ); + delete mViewer; + mViewer = NULL; +} + +/* +================ +rvGEApp::ToolWindowActivate + +Handles the nc activate message for all tool windows +================ +*/ +int rvGEApp::ToolWindowActivate ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + bool keepActive; + bool syncOthers; + int i; + + keepActive = ( wParam != 0 ); + syncOthers = true; + + for ( i = 0; i < mToolWindows.Num (); i ++ ) + { + if ( (HWND)lParam == mToolWindows[i] ) + { + keepActive = true; + syncOthers = false; + break; + } + } + + if ( lParam == -1 ) + { + return DefWindowProc ( hwnd, WM_NCACTIVATE, keepActive, 0 ); + } + + if ( syncOthers ) + { + for ( i = 0; i < mToolWindows.Num(); i ++ ) + { + if ( mToolWindows[i] != hwnd && mToolWindows[i] != (HWND) lParam ) + { + SendMessage ( mToolWindows[i], WM_NCACTIVATE, keepActive, (LONG)-1 ); + } + } + } + + return DefWindowProc ( hwnd, WM_NCACTIVATE, keepActive, lParam ); +} + +/* +================ +rvGEApp::MessageBox + +Displays a modal message box +================ +*/ +int rvGEApp::MessageBox ( const char* text, int flags ) +{ + return ::MessageBox ( mMDIFrame, text, "Quake 4 GUI Editor", flags ); +} + diff --git a/tools/guied/GEApp.h b/tools/guied/GEApp.h new file mode 100644 index 000000000..3ac4bed87 --- /dev/null +++ b/tools/guied/GEApp.h @@ -0,0 +1,182 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEAPP_H_ +#define GEAPP_H_ + +#include "../../sys/win32/win_local.h" + +#include "../../ui/Rectangle.h" +#include "../../ui/Window.h" +#include "../../ui/UserInterfaceLocal.h" + +#ifndef GEOPTIONS_H_ +#include "GEOptions.h" +#endif // GEOPTIONS_H_ + +#ifndef GEWINDOWWRAPPER_H_ +#include "GEWindowWrapper.h" +#endif // GEWINDOWWRAPPER_H_ + +#ifndef GEWORKSPACE_H_ +#include "GEWorkspace.h" +#endif // GEWORKSPACE_H_ + +#ifndef GENAVIGATOR_H_ +#include "GENavigator.h" +#endif // GENAVIGATOR_H_ + +#ifndef GEPROPERTIES_H_ +#include "GEProperties.h" +#endif // GEPROPERTIES_H_ + +#ifndef GETRANSFORMER_H_ +#include "GETransformer.h" +#endif // GETRANSFORMER_H_ + +#ifndef GESTATUSBAR_H_ +#include "GEStatusBar.h" +#endif // GESTATUSBAR_H_ + +// Utility functions +const char *StringFromVec4 ( idVec4& vec ); +bool IsExpression ( const char* s ); + + +class rvGEViewer; + +class rvGEApp +{ +public: + + rvGEApp ( ); + ~rvGEApp ( ); + + bool Initialize ( void ); + void RunFrame ( void ); +// bool Uninitialize ( void ); + + bool TranslateAccelerator ( LPMSG msg ); + + rvGEWorkspace* GetActiveWorkspace ( HWND* retwnd = NULL ); + rvGENavigator& GetNavigator ( void ); + rvGEProperties& GetProperties ( void ); + rvGETransformer& GetTransformer ( void ); + rvGEOptions& GetOptions ( void ); + HINSTANCE GetInstance ( void ); + HWND GetMDIFrame ( void ); + HWND GetMDIClient ( void ); + rvGEStatusBar& GetStatusBar ( void ); + + bool OpenFile ( const char* filename ); + bool SaveFile ( const char* filename ); + bool NewFile ( void ); + + bool IsActive ( void ); + + void CloseViewer ( void ); + + int ToolWindowActivate ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); + + int MessageBox ( const char* text, int flags ); + +protected: + + int HandleCommand ( WPARAM wParam, LPARAM lParam ); + int HandleInitMenu ( WPARAM wParam, LPARAM lParam ); + + void HandleCommandSave ( rvGEWorkspace* workspace, const char* filename ); + + bool InitRecentFiles ( void ); + void UpdateRecentFiles ( void ); + + HWND mMDIFrame; + HWND mMDIClient; + HINSTANCE mInstance; + rvGEOptions mOptions; + HACCEL mAccelerators; + rvGENavigator mNavigator; + rvGETransformer mTransformer; + rvGEStatusBar mStatusBar; + rvGEProperties mProperties; + + HMENU mRecentFileMenu; + int mRecentFileInsertPos; + + rvGEViewer* mViewer; + + idList mWorkspaces; + idList mToolWindows; + +private: + + static LRESULT CALLBACK FrameWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static LRESULT CALLBACK MDIChildProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +}; + +ID_INLINE bool rvGEApp::IsActive ( void ) +{ + return mMDIFrame ? true : false; +} + +ID_INLINE rvGENavigator& rvGEApp::GetNavigator ( void ) +{ + return mNavigator; +} + +ID_INLINE rvGEProperties& rvGEApp::GetProperties ( void ) +{ + return mProperties; +} + +ID_INLINE rvGETransformer& rvGEApp::GetTransformer ( void ) +{ + return mTransformer; +} + +ID_INLINE rvGEOptions& rvGEApp::GetOptions ( void ) +{ + return mOptions; +} + +ID_INLINE HINSTANCE rvGEApp::GetInstance ( void ) +{ + return mInstance; +} + +ID_INLINE rvGEStatusBar& rvGEApp::GetStatusBar ( void ) +{ + return mStatusBar; +} + +ID_INLINE HWND rvGEApp::GetMDIFrame ( void ) +{ + return mMDIFrame; +} + +ID_INLINE HWND rvGEApp::GetMDIClient ( void ) +{ + return mMDIClient; +} + + +extern rvGEApp gApp; + +#endif // GEAPP_H_ diff --git a/tools/guied/GECheckInDlg.cpp b/tools/guied/GECheckInDlg.cpp new file mode 100644 index 000000000..03cb7d4e2 --- /dev/null +++ b/tools/guied/GECheckInDlg.cpp @@ -0,0 +1,105 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" + +typedef struct +{ + const char* mFilename; + idStr* mComment; + +} GECHECKINDLG; + +/* +================ +GECheckInDlg_GeneralProc + +Dialog procedure for the check in dialog +================ +*/ +static INT_PTR CALLBACK GECheckInDlg_GeneralProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + GECHECKINDLG* dlg = (GECHECKINDLG*) GetWindowLong ( hwnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_INITDIALOG: + SetWindowLong ( hwnd, GWL_USERDATA, lParam ); + dlg = (GECHECKINDLG*) lParam; + + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_FILENAME ), dlg->mFilename ); + break; + + case WM_COMMAND: + switch ( LOWORD ( wParam ) ) + { + case IDOK: + { + char* temp; + int tempsize; + + tempsize = GetWindowTextLength ( GetDlgItem ( hwnd, IDC_GUIED_COMMENT ) ); + temp = new char [ tempsize + 2 ]; + GetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_COMMENT ), temp, tempsize + 1 ); + + *dlg->mComment = temp; + + delete[] temp; + + EndDialog ( hwnd, 1 ); + break; + } + + case IDCANCEL: + EndDialog ( hwnd, 0 ); + break; + } + break; + } + + return FALSE; +} + +/* +================ +GECheckInDlg_DoModal + +Starts the check in dialog +================ +*/ +bool GECheckInDlg_DoModal ( HWND parent, const char* filename, idStr* comment ) +{ + GECHECKINDLG dlg; + + dlg.mComment = comment; + dlg.mFilename = filename; + + if ( !DialogBoxParam ( gApp.GetInstance(), MAKEINTRESOURCE(IDD_GUIED_CHECKIN), parent, GECheckInDlg_GeneralProc, (LPARAM) &dlg ) ) + { + return false; + } + + return true; +} + diff --git a/tools/guied/GEDeleteModifier.cpp b/tools/guied/GEDeleteModifier.cpp new file mode 100644 index 000000000..b89dfe42a --- /dev/null +++ b/tools/guied/GEDeleteModifier.cpp @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEDeleteModifier.h" + +rvGEDeleteModifier::rvGEDeleteModifier ( const char* name, idWindow* window ) : + rvGEModifier ( name, window ) +{ +} + +/* +================ +rvGEDeleteModifier::Apply + +Apply the delete modifier by setting the deleted flag in the wrapper +================ +*/ +bool rvGEDeleteModifier::Apply ( void ) +{ + mWrapper->SetDeleted ( true ); + + return true; +} + +/* +================ +rvGEDeleteModifier::Undo + +Undo the delete modifier by unsetting the deleted flag in the wrapper +================ +*/ +bool rvGEDeleteModifier::Undo ( void ) +{ + mWrapper->SetDeleted ( false ); + + return true; +} + diff --git a/tools/guied/GEDeleteModifier.h b/tools/guied/GEDeleteModifier.h new file mode 100644 index 000000000..808441b3e --- /dev/null +++ b/tools/guied/GEDeleteModifier.h @@ -0,0 +1,36 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEDELETEMODIFIER_H_ +#define GEDELETEMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEDeleteModifier : public rvGEModifier +{ +public: + + rvGEDeleteModifier ( const char* name, idWindow* window ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); +}; + +#endif // GEDELETEMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GEHideModifier.cpp b/tools/guied/GEHideModifier.cpp new file mode 100644 index 000000000..8742b2510 --- /dev/null +++ b/tools/guied/GEHideModifier.cpp @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEHideModifier.h" + +rvGEHideModifier::rvGEHideModifier ( const char* name, idWindow* window, bool hide ) : + rvGEModifier ( name, window ) +{ + mParent = NULL; + mHide = hide; + mUndoHide = mWrapper->IsHidden ( ); + + // If unhiding then find any parent window along the way that may be hidden and prevent + // this window from being visible + if ( !hide ) + { + mParent = mWindow; + while ( NULL != (mParent = mParent->GetParent ( ) ) ) + { + if ( rvGEWindowWrapper::GetWrapper(mParent)->IsHidden ( ) ) + { + break; + } + } + } +} + +/* +================ +rvGEHideModifier::Apply + +Apply the hide modifier by setting the visible state of the wrapper window +================ +*/ +bool rvGEHideModifier::Apply ( void ) +{ + mWrapper->SetHidden ( mHide ); + + if ( mParent ) + { + rvGEWindowWrapper::GetWrapper ( mParent )->SetHidden ( mHide ); + } + + return true; +} + +/* +================ +rvGEHideModifier::Undo + +Undo the hide modifier by setting the undo visible state of the wrapper window +================ +*/ +bool rvGEHideModifier::Undo ( void ) +{ + mWrapper->SetHidden ( mUndoHide ); + + if ( mParent ) + { + rvGEWindowWrapper::GetWrapper ( mParent )->SetHidden ( mUndoHide ); + } + + return true; +} + diff --git a/tools/guied/GEHideModifier.h b/tools/guied/GEHideModifier.h new file mode 100644 index 000000000..c862da4db --- /dev/null +++ b/tools/guied/GEHideModifier.h @@ -0,0 +1,42 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEHIDEMODIFIER_H_ +#define GEHIDEMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEHideModifier : public rvGEModifier +{ +public: + + rvGEHideModifier ( const char* name, idWindow* window, bool hide ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + +protected: + + bool mHide; + bool mUndoHide; + idWindow* mParent; +}; + +#endif // GEHIDEMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GEInsertModifier.cpp b/tools/guied/GEInsertModifier.cpp new file mode 100644 index 000000000..67dab523f --- /dev/null +++ b/tools/guied/GEInsertModifier.cpp @@ -0,0 +1,104 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEInsertModifier.h" + +rvGEInsertModifier::rvGEInsertModifier ( const char* name, idWindow* window, idWindow* parent, idWindow* before ) : + rvGEModifier ( name, window ) +{ + mParent = parent; + mBefore = before; + + assert ( mParent ); + + mUndoParent = window->GetParent ( ); + mUndoBefore = NULL; + mUndoRect = mWrapper->GetClientRect ( ); + mRect = mWrapper->GetClientRect ( ); + + // Find the child window the window being inserted is before + if ( mUndoParent ) + { + int index; + rvGEWindowWrapper* pwrapper; + + pwrapper = rvGEWindowWrapper::GetWrapper ( mUndoParent ); + + index = mUndoParent->GetChildIndex ( mWindow ); + + if ( index + 1 < pwrapper->GetChildCount ( ) ) + { + mUndoBefore = pwrapper->GetChild ( index + 1 ); + } + } + + // Since rectangles are relative to the parent rectangle we need to figure + // out the new x and y coordinate as if this window were a child + rvGEWindowWrapper* parentWrapper; + parentWrapper = rvGEWindowWrapper::GetWrapper ( mParent ); + mRect.x = mWrapper->GetScreenRect( )[0] - parentWrapper->GetScreenRect()[0]; + mRect.y = mWrapper->GetScreenRect( )[1] - parentWrapper->GetScreenRect()[1]; +} + +/* +================ +rvGEInsertModifier::Apply + +Apply the insert modifier by removing the child from its original parent and +inserting it as a child of the new parent +================ +*/ +bool rvGEInsertModifier::Apply ( void ) +{ + if ( mUndoParent ) + { + mUndoParent->RemoveChild ( mWindow ); + } + + mParent->InsertChild ( mWindow, mBefore ); + mWrapper->SetRect ( mRect ); + + return true; +} + +/* +================ +rvGEInsertModifier::Undo + +Undo the insert modifier by removing the window from the parent it was +added to and re-inserting it back into its original parent +================ +*/ +bool rvGEInsertModifier::Undo ( void ) +{ + mParent->RemoveChild ( mWindow ); + + if ( mUndoParent ) + { + mUndoParent->InsertChild ( mWindow, mUndoBefore ); + mWrapper->SetRect ( mUndoRect ); + } + + return true; +} + diff --git a/tools/guied/GEInsertModifier.h b/tools/guied/GEInsertModifier.h new file mode 100644 index 000000000..fb27593ec --- /dev/null +++ b/tools/guied/GEInsertModifier.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEINSERTMODIFIER_H_ +#define GEINSERTMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEInsertModifier : public rvGEModifier +{ +public: + + rvGEInsertModifier ( const char* name, idWindow* window, idWindow* parent, idWindow* before ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + +protected: + + idWindow* mUndoParent; + idWindow* mUndoBefore; + idWindow* mParent; + idWindow* mBefore; + idRectangle mRect; + idRectangle mUndoRect; +}; + +#endif // GEINSERTMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GEItemPropsDlg.cpp b/tools/guied/GEItemPropsDlg.cpp new file mode 100644 index 000000000..78f01e194 --- /dev/null +++ b/tools/guied/GEItemPropsDlg.cpp @@ -0,0 +1,1250 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" +#include "../common/ColorButton.h" +#include "../common/MaskEdit.h" + +#include "GEApp.h" +#include "GEItemPropsDlg.h" +#include "GEPropertyPage.h" + +enum +{ + RVITEMPROPS_GENERAL = 0, + RVITEMPROPS_IMAGE, + RVITEMPROPS_TEXT, + RVITEMPROPS_KEYS, + + RVITEMPROPS_MAX +}; + +class rvGEItemPropsImagePage : public rvGEPropertyPage +{ +public: + + rvGEItemPropsImagePage ( idDict* dictValues ); + + virtual bool Init ( void ); + virtual bool SetActive ( void ); + virtual bool KillActive ( void ); + virtual int HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + +protected: + + void UpdateCheckedStates ( void ); + + idDict* mDict; +}; + +rvGEItemPropsImagePage::rvGEItemPropsImagePage ( idDict* dict ) +{ + mDict = dict; +} + +/* +================ +rvGEItemPropsImagePage::Init + +Subclass the custom controls on the page +================ +*/ +bool rvGEItemPropsImagePage::Init ( void ) +{ + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEX ) ); + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEY ) ); + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE ) ); + + return true; +} + +/* +================ +rvGEItemPropsImagePage::UpdateCheckedStates + +Updates the enabled state of all the controls that are linked to a checkbox +================ +*/ +void rvGEItemPropsImagePage::UpdateCheckedStates ( void ) +{ + char temp[64]; + bool state; + bool rstate; + idStr result; + bool enable; + + enable = !IsExpression ( mDict->GetString ( "backcolor", "1,1,1,1" ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_USEBACKCOLOR ), enable ); + + state = IsDlgButtonChecked ( mPage, IDC_GUIED_USEBACKCOLOR ) && IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_USEBACKCOLOR ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLOR ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLORALPHA ), state ); + + state = IsDlgButtonChecked ( mPage, IDC_GUIED_USEMATERIAL) != 0; + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKGROUND ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMVARIABLEBACKGROUND ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEX ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEY ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_XSCALE_STATIC), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_YSCALE_STATIC), state ); + + GetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE ), temp, 64 ); + enable = !IsExpression ( mDict->GetString ( "bordersize", "0" ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE ), enable ); + + state = atol( temp ) ? true : false; + rstate = IsDlgButtonChecked ( mPage, IDC_GUIED_USEBORDERCOLOR ) != 0; + enable = !IsExpression ( mDict->GetString ( "bordercolor", "1,1,1,1" ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_USEBORDERCOLOR ), state && enable ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_USEBORDERMATERIAL ), state && enable); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLOR ), rstate && state && enable); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLORALPHA ), rstate && state && enable ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERMATERIAL ), !rstate && state ); + + state = (state && !rstate) || IsDlgButtonChecked ( mPage, IDC_GUIED_USEMATERIAL); + enable = !IsExpression ( mDict->GetString ( "matcolor", "1,1,1,1" ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLORSTATIC ), state && enable ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLOR ), state && enable ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLORALPHA ), state && enable ); +} + +/* +================ +rvGEItemPropsImagePage::HandleMessage + +Handles messages for the text item properties page +================ +*/ +int rvGEItemPropsImagePage::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_DRAWITEM: + ColorButton_DrawItem ( GetDlgItem ( mPage, wParam ), (LPDRAWITEMSTRUCT)lParam ); + return TRUE; + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case IDC_GUIED_ITEMBORDERSIZE: + if ( HIWORD(wParam) == EN_CHANGE ) + { + UpdateCheckedStates ( ); + } + break; + + case IDC_GUIED_USEBORDERCOLOR: + case IDC_GUIED_USEBORDERMATERIAL: + case IDC_GUIED_USEBACKCOLOR: + case IDC_GUIED_USEMATERIAL: + UpdateCheckedStates ( ); + break; + + case IDC_GUIED_ITEMBACKCOLORALPHA: + case IDC_GUIED_ITEMMATCOLORALPHA: + case IDC_GUIED_ITEMBORDERCOLORALPHA: + { + AlphaButton_OpenPopup ( GetDlgItem ( mPage, LOWORD(wParam) ) ); + break; + } + + case IDC_GUIED_ITEMBORDERCOLOR: + case IDC_GUIED_ITEMBACKCOLOR: + case IDC_GUIED_ITEMMATCOLOR: + { + CHOOSECOLOR col; + ZeroMemory ( &col, sizeof(col) ); + col.lStructSize = sizeof(col); + col.lpCustColors = gApp.GetOptions().GetCustomColors ( ); + col.hwndOwner = mPage; + col.hInstance = NULL; + col.Flags = CC_RGBINIT; + col.rgbResult = ColorButton_GetColor ( GetDlgItem ( mPage, LOWORD(wParam) ) ); + if ( ChooseColor ( &col ) ) + { + ColorButton_SetColor ( GetDlgItem ( mPage, LOWORD(wParam) ), col.rgbResult ); + } + break; + } + } + break; + } + + return rvGEPropertyPage::HandleMessage ( msg, wParam, lParam ); +} + +/* +================ +rvGEItemPropsImagePage::SetActive + +Initializes the text properties page by copying data from the attached +window into the controls +================ +*/ +bool rvGEItemPropsImagePage::SetActive ( void ) +{ + gApp.GetOptions().SetLastOptionsPage ( RVITEMPROPS_IMAGE ); + + ColorButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLOR ), mDict->GetString ( "backcolor", "1,1,1,1" ) ); + AlphaButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLORALPHA ), mDict->GetString ( "backcolor", "1,1,1,1" ) ); + + ColorButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLOR ), mDict->GetString ( "matcolor", "1,1,1,1" ) ); + AlphaButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLORALPHA ), mDict->GetString ( "matcolor", "1,1,1,1" ) ); + + ColorButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLOR ), mDict->GetString ( "bordercolor", "0,0,0,1" ) ); + AlphaButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLORALPHA ), mDict->GetString ( "bordercolor", "0,0,0,1" ) ); + + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKGROUND ), idStr(mDict->GetString ( "background", "" )).StripQuotes ( ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERMATERIAL ), idStr(mDict->GetString ( "borderShader", "" )).StripQuotes ( ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE ), idStr(mDict->GetString ( "bordersize", "0" )).StripQuotes ( ) ); + + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEX ), idStr(mDict->GetString ( "matscalex", "1" )).StripQuotes ( ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEY ), idStr(mDict->GetString ( "matscaley", "1" )).StripQuotes ( ) ); + + CheckDlgButton ( mPage, IDC_GUIED_ITEMVARIABLEBACKGROUND, mDict->GetBool ( "variablebackground", "0" ) ); + + CheckDlgButton ( mPage, IDC_GUIED_USEMATERIAL, idStr(mDict->GetString ( "background", "" )).StripQuotes ( ).Length()?BST_CHECKED:BST_UNCHECKED ); + CheckDlgButton ( mPage, IDC_GUIED_USEBACKCOLOR, idStr(mDict->GetString ( "backcolor", "" )).StripQuotes ( ).Length()?BST_CHECKED:BST_UNCHECKED ); + + CheckRadioButton ( mPage, IDC_GUIED_USEBORDERCOLOR, IDC_GUIED_USEBORDERMATERIAL, + idStr(mDict->GetString("borderShader","")).Length()?IDC_GUIED_USEBORDERMATERIAL:IDC_GUIED_USEBORDERCOLOR ); + + UpdateCheckedStates ( ); + + return true; +} + +/* +================ +rvGEItemPropsImagePage::KillActive + +Applys the settings currently stored in the property page back into the attached window +================ +*/ +bool rvGEItemPropsImagePage::KillActive ( void ) +{ + char temp[1024]; + bool matcolor = false; + idStr s; + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_USEMATERIAL ) ) + { + float val; + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMBACKGROUND), temp, 1024 ); + s = "\""; + s.Append(temp); + s.Append("\"" ); + mDict->Set ( "background", s ); + matcolor = true; + + GetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEX ), temp, 1024 ); + val = atof(temp); + if ( val >= 0.999f && val <= 1.001f ) + { + mDict->Delete ( "matscalex" ); + } + else + { + mDict->Set ( "matscalex", idStr::FloatArrayToString( &val, 1, 8 ) ); + } + + GetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATSCALEY ), temp, 1024 ); + val = atof(temp); + if ( val >= 0.999f && val <= 1.001f ) + { + mDict->Delete ( "matscaley" ); + } + else + { + mDict->Set ( "matscaley", idStr::FloatArrayToString( &val, 1, 8 ) ); + } + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMVARIABLEBACKGROUND ) ) + { + mDict->Set ( "variablebackground", "1" ); + } + else + { + mDict->Delete ( "variablebackground" ); + } + } + else + { + mDict->Delete ( "background" ); + mDict->Delete ( "variablebackground" ); + mDict->Delete ( "matscalex" ); + mDict->Delete ( "matscaley" ); + } + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_USEBACKCOLOR ) ) + { + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLOR ) ) ) + { + COLORREF color = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLOR ) ); + COLORREF alpha = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBACKCOLORALPHA ) ); + mDict->Set ( "backcolor", StringFromVec4 ( idVec4((float)GetRValue ( color ) / 255.0f, (float)GetGValue ( color ) / 255.0f, (float)GetBValue ( color ) / 255.0f, (float)GetRValue(alpha )/255.0f ) ) ); + } + } + else + { + mDict->Delete ( "backcolor" ); + } + + GetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE ), temp, 1024 ); + if ( atoi ( temp ) ) + { + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERSIZE) ) ) + { + mDict->Set ( "bordersize", va("%d", atoi(temp) ) ); + } + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_USEBORDERCOLOR ) ) + { + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLOR ) ) ) + { + COLORREF color = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLOR ) ); + COLORREF alpha = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERCOLORALPHA ) ); + mDict->Set ( "bordercolor", StringFromVec4 ( idVec4((float)GetRValue ( color ) / 255.0f, (float)GetGValue ( color ) / 255.0f, (float)GetBValue ( color ) / 255.0f, (float)GetRValue(alpha )/255.0f ) ) ); + } + mDict->Delete ( "borderShader" ); + } + else + { + GetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMBORDERMATERIAL ), temp, 1024 ); + s = "\""; + s.Append(temp); + s.Append("\"" ); + mDict->Set ( "borderShader", s ); + mDict->Delete ( "bordercolor" ); + matcolor = true; + } + } + else + { + mDict->Delete ( "bordersize" ); + mDict->Delete ( "bordercolor" ); + mDict->Delete ( "borderShader" ); + } + + if ( matcolor ) + { + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLOR ) ) ) + { + COLORREF color = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLOR ) ); + COLORREF alpha = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMMATCOLORALPHA ) ); + mDict->Set ( "matcolor", StringFromVec4 ( idVec4((float)GetRValue ( color ) / 255.0f, (float)GetGValue ( color ) / 255.0f, (float)GetBValue ( color ) / 255.0f, (float)GetRValue(alpha )/255.0f ) ) ); + } + } + else + { + mDict->Delete ( "matcolor" ); + } + + return true; +} + +class rvGEItemPropsTextPage : public rvGEPropertyPage +{ +public: + + rvGEItemPropsTextPage ( idDict* dictValues ); + + virtual bool Init ( void ); + virtual bool SetActive ( void ); + virtual bool KillActive ( void ); + virtual int HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + +protected: + + void UpdateCheckedStates ( void ); + + idDict* mDict; +}; + +rvGEItemPropsTextPage::rvGEItemPropsTextPage ( idDict* dict ) +{ + mDict = dict; +} + +/* +================ +rvGEItemPropsTextPage::Init + +Subclass the custom controls on the page +================ +*/ +bool rvGEItemPropsTextPage::Init ( void ) +{ + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTSCALE ) ); + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNX ) ); + NumberEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNY ) ); + + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), CB_ADDSTRING, 0, (LPARAM)"Left" ); + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), CB_ADDSTRING, 0, (LPARAM)"Center" ); + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), CB_ADDSTRING, 0, (LPARAM)"Right" ); + + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_ADDSTRING, 0, (LONG)"" ); + + idFileList *folders; + int i; + + folders = fileSystem->ListFiles( "fonts", "/" ); + + for ( i = 0; i < folders->GetNumFiles(); i++ ) { + if ( folders->GetFile(i)[0] == '.' ) { + continue; + } + + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_ADDSTRING, 0, (LONG)folders->GetFile(i) ); + } + + fileSystem->FreeFileList( folders ); + + return true; +} + +/* +================ +rvGEItemPropsTextPage::UpdateCheckedStates + +Updates the enabled state of all the controls that are linked to a checkbox +================ +*/ +void rvGEItemPropsTextPage::UpdateCheckedStates ( void ) +{ + bool state; + idStr result; + bool enable; + + state = IsDlgButtonChecked ( mPage, IDC_GUIED_USETEXT ) != 0; + enable = !IsExpression ( mDict->GetString ( "forecolor", "1,1,1,1" ) ); + + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLOR ), state && enable ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLORALPHA ), state && enable ); + + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXT ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTSCALE ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTSCALE ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNX ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNY ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTNOWRAP), state ); + + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_ALIGNMENT ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_X ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_Y ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_SCALE ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_COLOR ), state ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_STATIC_FONT), state ); +} + +/* +================ +rvGEItemPropsTextPage::HandleMessage + +Handles messages for the text item properties page +================ +*/ +int rvGEItemPropsTextPage::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_DRAWITEM: + ColorButton_DrawItem ( GetDlgItem ( mPage, wParam ), (LPDRAWITEMSTRUCT)lParam ); + return TRUE; + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case IDC_GUIED_ITEMTEXTFONT: + break; + + case IDC_GUIED_USETEXT: + UpdateCheckedStates ( ); + break; + + case IDC_GUIED_ITEMFORECOLORALPHA: + AlphaButton_OpenPopup ( GetDlgItem ( mPage, LOWORD(wParam) ) ); + break; + + case IDC_GUIED_ITEMFORECOLOR: + { + CHOOSECOLOR col; + ZeroMemory ( &col, sizeof(col) ); + col.lStructSize = sizeof(col); + col.lpCustColors = gApp.GetOptions().GetCustomColors ( ); + col.hwndOwner = mPage; + col.hInstance = NULL; + col.Flags = CC_RGBINIT; + col.rgbResult = ColorButton_GetColor ( GetDlgItem ( mPage, LOWORD(wParam) ) ); + if ( ChooseColor ( &col ) ) + { + ColorButton_SetColor ( GetDlgItem ( mPage, LOWORD(wParam) ), col.rgbResult ); + } + break; + } + } + break; + } + + return rvGEPropertyPage::HandleMessage ( msg, wParam, lParam ); +} + +/* +================ +rvGEItemPropsTextPage::SetActive + +Initializes the text properties page by copying data from the attached +window into the controls +================ +*/ +bool rvGEItemPropsTextPage::SetActive ( void ) +{ + gApp.GetOptions().SetLastOptionsPage ( RVITEMPROPS_TEXT ); + + ColorButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLOR ), mDict->GetString ( "forecolor", "1,1,1,1" ) ); + AlphaButton_SetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLORALPHA ), mDict->GetString ( "forecolor", "1,1,1,1" ) ); + + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXT ), idStr(mDict->GetString ( "text", "" )).StripQuotes ( ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTSCALE ), mDict->GetString ( "textscale", "1.0" ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNX ), mDict->GetString ( "textalignx", "0" ) ); + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGNY ), mDict->GetString ( "textaligny", "0" ) ); + + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), CB_SETCURSEL, atoi(mDict->GetString("textalign", "0")), 0 ); + + // Figure out which font to select + idStr font = mDict->GetString ( "font", "" ); + int fontSel; + font.StripQuotes ( ); + font.StripPath ( ); + fontSel = SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_FINDSTRING, -1, (LONG)font.c_str () ); + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_SETCURSEL, 0, 0 ); + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_SETCURSEL, fontSel==-1?0:fontSel, 0 ); + + CheckDlgButton ( mPage, IDC_GUIED_USETEXT, idStr(mDict->GetString ( "text", "" )).Length()?BST_CHECKED:BST_UNCHECKED ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMTEXTNOWRAP, atoi(idStr(mDict->GetString ( "nowrap", "0" )).StripQuotes())?BST_CHECKED:BST_UNCHECKED ); + + UpdateCheckedStates ( ); + + return true; +} + +/* +================ +rvGEItemPropsTextPage::KillActive + +Applys the settings currently stored in the property page back into the attached window +================ +*/ +bool rvGEItemPropsTextPage::KillActive ( void ) +{ + idStr s; + char temp[1024]; + int i; + float f; + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_USETEXT ) ) + { + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLOR ) ) ) + { + COLORREF color = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLOR ) ); + COLORREF alpha = ColorButton_GetColor ( GetDlgItem ( mPage, IDC_GUIED_ITEMFORECOLORALPHA ) ); + mDict->Set ( "forecolor", StringFromVec4 ( idVec4((float)GetRValue ( color ) / 255.0f, (float)GetGValue ( color ) / 255.0f, (float)GetBValue ( color ) / 255.0f, (float)GetRValue(alpha )/255.0f ) ) ); + } + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMTEXT), temp, 1024 ); + s = "\""; + s.Append(temp); + s.Append("\"" ); + mDict->Set ( "text", s ); + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMTEXTSCALE), temp, 1024 ); + f = atof( temp ); + mDict->Set ( "textscale", idStr::FloatArrayToString( &f, 1, 8 ) ); + + i = SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTALIGN ), CB_GETCURSEL, 0, 0 ); + s = va("%d", i ); + if ( i != 0 ) + { + mDict->Set ( "textalign", s ); + } + else + { + mDict->Delete ( "textalign" ); + } + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMTEXTALIGNX), temp, 1024 ); + i = atoi(temp); + if ( i ) + { + mDict->Set ( "textalignx", va("%d", i ) ); + } + else + { + mDict->Delete ( "textalignx" ); + } + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMTEXTALIGNY), temp, 1024 ); + i = atoi(temp); + if ( i ) + { + mDict->Set ( "textaligny", va("%d", i ) ); + } + else + { + mDict->Delete ( "textaligny" ); + } + + int fontSel = SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_GETCURSEL, 0, 0 ); + if ( fontSel == 0 ) + { + mDict->Delete ( "font" ); + } + else + { + char fontName[MAX_PATH]; + SendMessage ( GetDlgItem ( mPage, IDC_GUIED_ITEMTEXTFONT ), CB_GETLBTEXT, fontSel, (LONG)fontName ); + mDict->Set ( "font", idStr("\"fonts/") + idStr(fontName) + idStr("\"" ) ); + } + + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMTEXTNOWRAP ) ) + { + mDict->Set ( "nowrap", "1" ); + } + else + { + mDict->Delete ( "nowrap" ); + } + } + else + { + mDict->Delete ( "text" ); + mDict->Delete ( "textscale" ); + mDict->Delete ( "textalign" ); + mDict->Delete ( "textalignx" ); + mDict->Delete ( "textaligny" ); + mDict->Delete ( "forecolor" ); + mDict->Delete ( "font" ); + } + + return true; +} + +class rvGEItemPropsKeysPage : public rvGEPropertyPage +{ +public: + + rvGEItemPropsKeysPage ( idDict* dictValues, rvGEWindowWrapper* wrapper ); + + virtual bool Init ( void ); + virtual bool SetActive ( void ); + virtual int HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + +protected: + + idDict* mDict; + rvGEWindowWrapper* mWrapper; +}; + +rvGEItemPropsKeysPage::rvGEItemPropsKeysPage ( idDict* dict, rvGEWindowWrapper* wrapper ) +{ + mDict = dict; + mWrapper = wrapper; +} + +INT_PTR CALLBACK ModifyItemKeyDlg_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_INITDIALOG: + { + const idKeyValue* keyValue = (const idKeyValue*) lParam; + MaskEdit_Attach ( GetDlgItem ( hwnd, IDC_GUIED_ITEMKEY ), " \t\r\n" ); + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_ITEMVALUE ), idStr(keyValue->GetValue()).StripQuotes ( ) ); + if ( idStr::Icmp ( keyValue->GetKey(), "guied_temp" ) ) + { + if ( !idStr::Icmp ( keyValue->GetKey(), "name" ) || !idStr::Icmp ( keyValue->GetKey(), "rect" ) ) + { + // Dont allow editing the name keyname + EnableWindow ( GetDlgItem ( hwnd, IDC_GUIED_ITEMKEY ), FALSE ); + } + + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_ITEMKEY ), keyValue->GetKey() ); + SetFocus ( GetDlgItem ( hwnd, IDC_GUIED_ITEMVALUE ) ); + SendMessage( GetDlgItem ( hwnd, IDC_GUIED_ITEMVALUE ), EM_SETSEL, 0, -1 ); + + SetWindowText ( hwnd, "New Item Key" ); + } + + SetWindowLong ( hwnd, GWL_USERDATA, lParam ); + return FALSE; + } + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case IDOK: + { + char key[1024]; + char value[1024]; + + const idKeyValue* keyValue = (const idKeyValue*) GetWindowLong ( hwnd, GWL_USERDATA ); + + GetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_ITEMKEY ), key, 1024 ); + GetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_ITEMVALUE ), value, 1024 ); + + if ( strlen ( key ) < 1 ) + { + gApp.MessageBox ( va("Invalid key name '%s'", key), MB_OK|MB_ICONERROR ); + } + else + { + // FIXME: MrE may never change key value pairs directly! + //keyValue->GetKey() = key; + //keyValue->GetValue = value; + + EndDialog ( hwnd, 1); + } + break; + } + + case IDCANCEL: + EndDialog ( hwnd, 0 ); + break; + } + break; + } + + return FALSE; +} + +int rvGEItemPropsKeysPage::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_NOTIFY: + { + NMHDR* nm = (NMHDR*) lParam; + + // There are a few protected keys that need to dissallow deleting so + // check to see if the newly selected key is one of them and if so then + // disable the delete button + if ( nm->code == LVN_ITEMCHANGED ) + { + NMLISTVIEW* nmlv = (NMLISTVIEW*) nm; + if ( nmlv->uNewState & LVIS_SELECTED ) + { + const idKeyValue* keyValue = (idKeyValue*) nmlv->lParam; + assert( keyValue ); + + if ( !idStr::Icmp ( keyValue->GetKey(), "name" ) || !idStr::Icmp ( keyValue->GetKey(), "rect" ) ) + { + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_DELETEKEY ), FALSE ); + } + else + { + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_DELETEKEY ), TRUE ); + } + } + } + break; + } + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case IDC_GUIED_ADDKEY: + { + HWND list = GetDlgItem ( mPage, IDC_GUIED_ITEMKEYS ); + mDict->Set( "guied_temp", "" ); + const idKeyValue* key = mDict->FindKey ( "guied_temp" ); + + idStr old = key->GetValue(); + while ( 1 ) + { + if ( DialogBoxParam ( gApp.GetInstance (), MAKEINTRESOURCE(IDD_GUIED_ITEMKEY), mPage, ModifyItemKeyDlg_WndProc, (LPARAM)key ) ) + { + idStr finalValue; + + finalValue = key->GetValue(); + if ( !mWrapper->VerfiyStateKey ( key->GetKey(), finalValue ) ) + { + finalValue = "\""; + finalValue += key->GetValue(); + finalValue += "\""; + if ( !mWrapper->VerfiyStateKey ( key->GetKey(), finalValue ) ) + { + gApp.MessageBox ( va("Invalid property value '%s' for property '%s'", key->GetValue().c_str(), key->GetKey().c_str()), MB_OK|MB_ICONERROR ); + continue; + } + } + + mDict->Set( key->GetKey(), finalValue ); + + LVITEM item; + ZeroMemory ( &item, sizeof(item) ); + item.mask = LVIF_TEXT|LVIF_PARAM; + item.iItem = ListView_GetItemCount ( list ); + item.pszText = (LPSTR)key->GetKey().c_str ( ); + item.lParam = (LONG) key; + int index = ListView_InsertItem ( list, &item ); + + finalValue.StripQuotes ( ); + ListView_SetItemText ( list, index, 1, (LPSTR)finalValue.c_str ( ) ); + + break; + } + else + { + mDict->Delete ( "guied_temp" ); + break; + } + } + break; + } + + case IDC_GUIED_EDITKEY: + { + HWND list = GetDlgItem ( mPage, IDC_GUIED_ITEMKEYS ); + int index = ListView_GetNextItem ( list, -1, LVNI_SELECTED ); + if ( index != -1 ) + { + LVITEM item; + item.iItem = index; + item.mask = LVIF_PARAM; + ListView_GetItem ( list, &item ); + const idKeyValue* key = (const idKeyValue*)item.lParam; + assert ( key ); + + while ( 1 ) + { + if ( DialogBoxParam ( gApp.GetInstance (), MAKEINTRESOURCE(IDD_GUIED_ITEMKEY), mPage, ModifyItemKeyDlg_WndProc, (LPARAM)key ) ) + { + idStr finalValue; + + finalValue = key->GetValue(); + if ( !mWrapper->VerfiyStateKey ( key->GetKey(), finalValue ) ) + { + finalValue = "\""; + finalValue += key->GetValue(); + finalValue += "\""; + if ( !mWrapper->VerfiyStateKey ( key->GetKey(), finalValue ) ) + { + gApp.MessageBox ( va("Invalid property value '%s' for property '%s'", key->GetValue().c_str(), key->GetKey().c_str()), MB_OK|MB_ICONERROR ); + continue; + } + } + + // FIXME: MrE is this the right thing todo? + mDict->Set( key->GetKey(), finalValue ); + //key->GetValue() = finalValue; + + ListView_SetItemText ( list, index, 0, (LPSTR)key->GetKey().c_str() ); + + finalValue.StripQuotes ( ); + ListView_SetItemText ( list, index, 1, (LPSTR)finalValue.c_str() ); + break; + } + } + } + break; + } + + case IDC_GUIED_DELETEKEY: + { + HWND list = GetDlgItem ( mPage, IDC_GUIED_ITEMKEYS ); + int index = ListView_GetNextItem ( list, -1, LVNI_SELECTED ); + if ( index != -1 ) + { + LVITEM item; + item.iItem = index; + item.mask = LVIF_PARAM; + ListView_GetItem ( list, &item ); + const idKeyValue* key = (const idKeyValue*)item.lParam; + assert ( key ); + + mDict->Delete ( key->GetKey() ); + + ListView_DeleteItem ( list, index ); + } + break; + } + } + break; + } + + return rvGEPropertyPage::HandleMessage ( msg, wParam, lParam ); +} + +/* +================ +rvGEItemPropsKeysPage::Init + +Called when the advanced page is first initialized. Setup the extended +control styles and add the key/value columns +================ +*/ +bool rvGEItemPropsKeysPage::Init ( void ) +{ + HWND list; + RECT rWindow; + + // Get the list control + list = GetDlgItem ( mPage, IDC_GUIED_ITEMKEYS ); + assert ( list ); + + GetClientRect ( list, &rWindow ); + + // Set the full row select for better visual appearance + ListView_SetExtendedListViewStyle ( list, LVS_EX_FULLROWSELECT ); + + // Add the key column + LVCOLUMN col; + col.mask = LVCF_TEXT|LVCF_WIDTH; + col.cx = .3 * (rWindow.right - rWindow.left); + col.pszText = "Key"; + ListView_InsertColumn ( list, 0, &col ); + + // Add the value column + col.pszText = "Value"; + col.cx = (rWindow.right - rWindow.left) - col.cx; + ListView_InsertColumn ( list, 1, &col ); + + return true; +} + +/* +================ +rvGEItemPropsKeysPage::SetActive + +Called when the advanced page is made active and will add an entry to +the keys list view for each key in the properties dictionary +================ +*/ +bool rvGEItemPropsKeysPage::SetActive ( void ) +{ + int i; + HWND list; + + gApp.GetOptions().SetLastOptionsPage ( RVITEMPROPS_KEYS ); + + // Get listview control + list = GetDlgItem ( mPage, IDC_GUIED_ITEMKEYS ); + assert ( list ); + + // Delete anything already in there + ListView_DeleteAllItems ( list ); + + // Add each key in the properties dictionary + for ( i = 0; i < mDict->GetNumKeyVals(); i ++ ) + { + const idKeyValue* key = mDict->GetKeyVal ( i ); + assert ( key ); + + // Add the item + LVITEM item; + ZeroMemory ( &item, sizeof(item) ); + item.mask = LVIF_TEXT|LVIF_PARAM; + item.iItem = ListView_GetItemCount ( list ); + item.pszText = (LPSTR)key->GetKey().c_str ( ); + item.lParam = (LONG) key; + int index = ListView_InsertItem ( list, &item ); + + idStr value; + value = key->GetValue(); + value.StripQuotes ( ); + ListView_SetItemText ( list, index, 1, (LPSTR)value.c_str() ); + } + + return true; +} + +class rvGEItemPropsGeneralPage : public rvGEPropertyPage +{ +public: + + rvGEItemPropsGeneralPage ( idDict* dict, rvGEWindowWrapper::EWindowType type ); + + virtual bool SetActive ( void ); + virtual bool KillActive ( void ); + virtual bool Init ( void ); + virtual int HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + +protected: + + void UpdateCheckedStates ( void ); + + idDict* mDict; + idStr mType; +}; + +rvGEItemPropsGeneralPage::rvGEItemPropsGeneralPage ( idDict* dict, rvGEWindowWrapper::EWindowType type ) +{ + mDict = dict; + mType = rvGEWindowWrapper::WindowTypeToString ( type ); +} + +/* +================ +rvGEItemPropsGeneralPage::UpdateCheckedStates + +Updates the enabled state of all the controls that are linked to a checkbox +================ +*/ +void rvGEItemPropsGeneralPage::UpdateCheckedStates ( void ) +{ +} + +/* +================ +rvGEItemPropsGeneralPage::HandleMessage + +Handles messages for the general item properties page +================ +*/ +int rvGEItemPropsGeneralPage::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ +/* + switch ( msg ) + { + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + } + break; + } +*/ + + return rvGEPropertyPage::HandleMessage ( msg, wParam, lParam ); +} + +/* +================ +rvGEItemPropsGeneralPage::Init + +Subclass the custom controls on the page +================ +*/ +bool rvGEItemPropsGeneralPage::Init ( void ) +{ + MaskEdit_Attach ( GetDlgItem ( mPage, IDC_GUIED_ITEMNAME ), " \t\n\r" ); + + return true; +} + +/* +================ +rvGEItemPropsGeneralPage::SetActive + +Initializes the general properties page by copying data from the attached +window into the controls +================ +*/ +bool rvGEItemPropsGeneralPage::SetActive ( void ) +{ + bool enable; + idStr result; + + gApp.GetOptions().SetLastOptionsPage ( RVITEMPROPS_GENERAL ); + + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_ITEMNAME ), idStr(mDict->GetString ( "name", "unnamed" )).StripQuotes ( ) ); + + enable = !IsExpression ( mDict->GetString ( "visible", "1" ) ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMVISIBLE, atol(idStr(mDict->GetString ( "visible", "1" )).StripQuotes ( ))?BST_CHECKED:BST_UNCHECKED ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMVISIBLE ), enable ); + + enable = !IsExpression ( mDict->GetString ( "notime", "0" ) ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMNOTIME, atol(idStr(mDict->GetString ( "notime", "0" )).StripQuotes ( ))?BST_CHECKED:BST_UNCHECKED ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOTIME ), enable ); + + enable = !IsExpression ( mDict->GetString ( "noevents", "0" ) ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMNOEVENTS, atol(idStr(mDict->GetString ( "noevents", "0" )).StripQuotes ( ))?BST_CHECKED:BST_UNCHECKED ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOEVENTS ), enable ); + + enable = !IsExpression ( mDict->GetString ( "noclip", "0" ) ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMNOCLIP, atol(idStr(mDict->GetString ( "noclip", "0" )).StripQuotes ( ))?BST_CHECKED:BST_UNCHECKED ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOCLIP ), enable ); + + enable = !IsExpression ( mDict->GetString ( "nocursor", "0" ) ); + EnableWindow ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOCURSOR ), enable ); + CheckDlgButton ( mPage, IDC_GUIED_ITEMNOCURSOR, atol(idStr(mDict->GetString ( "nocursor", "0" )).StripQuotes ( ))?BST_CHECKED:BST_UNCHECKED ); + + SetWindowText ( GetDlgItem ( mPage, IDC_GUIED_TYPE ), mType ); + + UpdateCheckedStates ( ); + + return true; +} + + +/* +================ +rvGEItemPropsGeneralPage::KillActive + +Applys the settings currently stored in the property page back into the attached window +================ +*/ +bool rvGEItemPropsGeneralPage::KillActive ( void ) +{ + char temp[1024]; + + GetWindowText ( GetDlgItem(mPage,IDC_GUIED_ITEMNAME), temp, 1024 ); + mDict->Set ( "name", temp ); + + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMVISIBLE ) ) ) + { + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMVISIBLE ) ) + { + mDict->Set ( "visible" , "1" ); + } + else + { + mDict->Set ( "visible" , "0" ); + } + } + + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOTIME ) ) ) + { + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMNOTIME ) ) + { + mDict->Set ( "notime" , "1" ); + } + else + { + mDict->Delete ( "notime" ); + } + } + + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOEVENTS ) ) ) + { + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMNOEVENTS ) ) + { + mDict->Set ( "noevents" , "1" ); + } + else + { + mDict->Delete ( "noevents" ); + } + } + + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOCLIP ) ) ) + { + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMNOCLIP ) ) + { + mDict->Set ( "noclip" , "1" ); + } + else + { + mDict->Delete ( "noclip" ); + } + } + + if ( IsWindowEnabled ( GetDlgItem ( mPage, IDC_GUIED_ITEMNOCURSOR ) ) ) + { + if ( IsDlgButtonChecked ( mPage, IDC_GUIED_ITEMNOCURSOR ) ) + { + mDict->Set ( "nocursor" , "1" ); + } + else + { + mDict->Delete ( "nocursor" ); + } + } + + return true; +} + +/* +================ +GEItemPropsDlg_DoModal + +Starts the item properties dialog +================ +*/ +bool GEItemPropsDlg_DoModal ( HWND parent, idWindow* window, idDict& dict ) +{ + PROPSHEETHEADER propsh; + PROPSHEETPAGE propsp[4]; + rvGEWindowWrapper* wrapper; + bool result; + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + assert ( wrapper ); + + // Start the destination dictionary with the values in the window dictionary + dict.Clear ( ); + dict.Copy ( wrapper->GetStateDict ( )); + + propsp[RVITEMPROPS_GENERAL].dwSize = sizeof(PROPSHEETPAGE); + propsp[RVITEMPROPS_GENERAL].dwFlags = PSP_USETITLE; + propsp[RVITEMPROPS_GENERAL].hInstance = win32.hInstance; + propsp[RVITEMPROPS_GENERAL].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_ITEMPROPS_GENERAL); + propsp[RVITEMPROPS_GENERAL].pfnDlgProc = rvGEPropertyPage::WndProc; + propsp[RVITEMPROPS_GENERAL].pszTitle = "General"; + propsp[RVITEMPROPS_GENERAL].lParam = (LONG)new rvGEItemPropsGeneralPage ( &dict, wrapper->GetWindowType ( ) ); + + propsp[RVITEMPROPS_IMAGE].dwSize = sizeof(PROPSHEETPAGE); + propsp[RVITEMPROPS_IMAGE].dwFlags = PSP_USETITLE; + propsp[RVITEMPROPS_IMAGE].hInstance = win32.hInstance; + propsp[RVITEMPROPS_IMAGE].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_ITEMPROPS_IMAGE); + propsp[RVITEMPROPS_IMAGE].pfnDlgProc = rvGEPropertyPage::WndProc; + propsp[RVITEMPROPS_IMAGE].pszTitle = "Image"; + propsp[RVITEMPROPS_IMAGE].lParam = (LONG)new rvGEItemPropsImagePage ( &dict );; + + propsp[RVITEMPROPS_TEXT].dwSize = sizeof(PROPSHEETPAGE); + propsp[RVITEMPROPS_TEXT].dwFlags = PSP_USETITLE; + propsp[RVITEMPROPS_TEXT].hInstance = win32.hInstance; + propsp[RVITEMPROPS_TEXT].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_ITEMPROPS_TEXT); + propsp[RVITEMPROPS_TEXT].pfnDlgProc = rvGEPropertyPage::WndProc; + propsp[RVITEMPROPS_TEXT].pszTitle = "Text"; + propsp[RVITEMPROPS_TEXT].lParam = (LONG)new rvGEItemPropsTextPage ( &dict );; + + propsp[RVITEMPROPS_KEYS].dwSize = sizeof(PROPSHEETPAGE); + propsp[RVITEMPROPS_KEYS].dwFlags = PSP_USETITLE; + propsp[RVITEMPROPS_KEYS].hInstance = win32.hInstance; + propsp[RVITEMPROPS_KEYS].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_ITEMPROPS_KEYS); + propsp[RVITEMPROPS_KEYS].pfnDlgProc = rvGEPropertyPage::WndProc; + propsp[RVITEMPROPS_KEYS].pszTitle = "Keys"; + propsp[RVITEMPROPS_KEYS].lParam = (LONG)new rvGEItemPropsKeysPage ( &dict, wrapper ); + + propsh.dwSize = sizeof(PROPSHEETHEADER); + propsh.nStartPage = gApp.GetOptions().GetLastOptionsPage ( ); + propsh.dwFlags = PSH_PROPSHEETPAGE|PSH_NOAPPLYNOW|PSH_NOCONTEXTHELP; + propsh.hwndParent = parent; + propsh.pszCaption = "Item Properties"; + propsh.nPages = RVITEMPROPS_MAX; + propsh.ppsp = (LPCPROPSHEETPAGE)&propsp; + + // Bring up the item properties dialog now + result = PropertySheet ( &propsh ) != NULL; + + // Cleanup + delete (rvGEItemPropsGeneralPage*) propsp[0].lParam; + delete (rvGEItemPropsImagePage*) propsp[1].lParam; + delete (rvGEItemPropsTextPage*) propsp[2].lParam; + delete (rvGEItemPropsKeysPage*) propsp[3].lParam; + + return result; +} + \ No newline at end of file diff --git a/tools/guied/GEItemPropsDlg.h b/tools/guied/GEItemPropsDlg.h new file mode 100644 index 000000000..ec5489f17 --- /dev/null +++ b/tools/guied/GEItemPropsDlg.h @@ -0,0 +1,24 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEITEMPROPSDLG_H_ +#define GEITEMPROPSDLG_H_ + +bool GEItemPropsDlg_DoModal ( HWND parent, idWindow* window, idDict& outDict ); + +#endif // GEITEMPROPSDLG_H_ \ No newline at end of file diff --git a/tools/guied/GEItemScriptsDlg.cpp b/tools/guied/GEItemScriptsDlg.cpp new file mode 100644 index 000000000..59bddb348 --- /dev/null +++ b/tools/guied/GEItemScriptsDlg.cpp @@ -0,0 +1,354 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" +#include "GEPropertyPage.h" + +LRESULT CALLBACK GEScriptEdit_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + WNDPROC wndproc = (WNDPROC) GetWindowLong ( hwnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_CHAR: + if ( wParam == VK_ESCAPE ) + { + SendMessage ( GetParent ( hwnd ), WM_CLOSE, 0, 0 ); + } + break; + + case WM_GETDLGCODE: + return DLGC_WANTALLKEYS; + } + + return CallWindowProc ( wndproc, hwnd, msg, wParam, lParam ); +} + +bool GEItescriptsDlg_Init ( HWND hwnd ) +{ + idWindow* window; + rvGEWindowWrapper* wrapper; + HWND script; + + // Extract the window pointer from the win32 windows user data long + window = (idWindow*)GetWindowLong ( hwnd, GWL_USERDATA ); + assert ( window ); + + // Get the window wrapper of the script window + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + assert ( wrapper ); + + // Get the edit box used to edit the script + script = GetDlgItem ( hwnd, IDC_GUIED_SCRIPT ); + + UINT tabsize = 16; + SendMessage ( script, EM_SETTABSTOPS, 1, (LPARAM)&tabsize ); + SetWindowLong ( script, GWL_USERDATA, GetWindowLong ( script, GWL_WNDPROC ) ); + SetWindowLong ( script, GWL_WNDPROC, (LONG) GEScriptEdit_WndProc ); + + TEXTMETRIC tm; + HDC dc; + dc = GetDC ( script ); + GetTextMetrics ( dc, &tm ); + ReleaseDC ( script, dc ); + + LOGFONT lf; + ZeroMemory ( &lf, sizeof(lf) ); + lf.lfHeight = tm.tmHeight; + strcpy ( lf.lfFaceName, "Courier New" ); + + SendMessage ( script, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 ); + + SendMessage ( script, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(10,10) ); + + int i; + + for ( i = 0; i < wrapper->GetVariableDict().GetNumKeyVals ( ); i ++ ) + { + const idKeyValue* key = wrapper->GetVariableDict().GetKeyVal ( i ); + + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)key->GetKey().c_str() ); + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)"\t" ); + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)key->GetValue().c_str() ); + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)"\r\n" ); + } + + if ( i ) + { + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)"\r\n" ); + } + + for ( i = 0; i < wrapper->GetScriptDict().GetNumKeyVals ( ); i ++ ) + { + const idKeyValue* key = wrapper->GetScriptDict().GetKeyVal ( i ); + + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)va("%s\r\n", key->GetKey().c_str() ) ); + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)key->GetValue().c_str() ); + SendMessage ( script, EM_SETSEL, -1, -1 ); + SendMessage ( script, EM_REPLACESEL, FALSE, (LPARAM)"\r\n\r\n" ); + } + + SendMessage ( script, EM_SETSEL, 0, 0 ); + SendMessage ( script, EM_SCROLLCARET, 0, 0 ); + + return true; +} + +bool GEItescriptsDlg_Apply ( HWND hwnd ) +{ + idWindow* window; + rvGEWindowWrapper* wrapper; + HWND script; + + // Extract the window pointer from the win32 windows user data long + window = (idWindow*)GetWindowLong ( hwnd, GWL_USERDATA ); + assert ( window ); + + // Get the window wrapper of the script window + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + assert ( wrapper ); + + // Get the edit box used to edit the script + script = GetDlgItem ( hwnd, IDC_GUIED_SCRIPT ); + + GETTEXTLENGTHEX textLen; + int chars; + textLen.flags = GTL_DEFAULT|GTL_USECRLF; + textLen.codepage = CP_ACP; + chars = SendMessage ( script, EM_GETTEXTLENGTHEX, (WPARAM)&textLen, 0 ); + + char* text = new char[chars+1]; + + GETTEXTEX getText; + getText.cb = chars+1; + getText.codepage = CP_ACP; + getText.flags = GT_DEFAULT|GT_USECRLF; + getText.lpDefaultChar = NULL; + getText.lpUsedDefChar = NULL; + SendMessage ( script, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)text ); + + idStr parse = text; + delete[] text; + + try + { + idParser src ( parse, parse.Length(), "", LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + idToken token; + + wrapper->GetVariableDict().Clear ( ); + wrapper->GetScriptDict().Clear ( ); + + while ( src.ReadToken ( &token ) ) + { + idStr scriptName; + idStr out; + + if ( !token.Icmp ("definevec4") ) + { + idToken token2; + idStr result; + + if ( !src.ReadToken ( &token2 ) ) + { + src.Error ( "expected define name" ); + return false; + } + + idWinVec4 var; + idUserInterfaceLocal ui; + idWindow tempwin ( &ui ); + idStr out; + int i; + + src.SetMarker ( ); + for ( i = 0; i < 3; i ++ ) + { + tempwin.ParseExpression ( &src, &var ); + src.ExpectTokenString(","); + } + + tempwin.ParseExpression ( &src, &var ); + src.GetStringFromMarker ( out, true ); + + wrapper->GetVariableDict().Set ( token + "\t\"" + token2 + "\"", out ); + + continue; + } + else if ( !token.Icmp ( "definefloat" ) || !token.Icmp ( "float" ) ) + { + idToken token2; + idStr result; + + if ( !src.ReadToken ( &token2 ) ) + { + src.Error ( "expected define name" ); + return false; + } + + idWinFloat var; + idUserInterfaceLocal ui; + idWindow tempwin ( &ui ); + idStr out; + + src.SetMarker ( ); + tempwin.ParseExpression ( &src, &var ); + src.GetStringFromMarker ( out, true ); + + wrapper->GetVariableDict().Set ( token + "\t\"" + token2 + "\"", out ); + + continue; + } + // If the token is a scriptdef then just parse out the + // braced section and add it to the list. Right now only + // one scriptdef per window is supported + else if ( !token.Icmp ( "scriptdef" ) ) + { + scriptName = "scriptDef"; + } + else if ( !token.Icmp ( "ontime" ) ) + { + if ( !src.ReadToken ( &token ) ) + { + src.Error ( "expected time" ); + return false; + } + + scriptName = "onTime "; + scriptName.Append ( token ); + } + else if ( !token.Icmp ( "onevent" ) ) + { + if ( !src.ReadToken ( &token ) ) + { + src.Error ( "expected time" ); + return false; + } + + scriptName = "onEvent "; + scriptName.Append ( token ); + } + else + { + int i; + + for( i = 0; i < idWindow::SCRIPT_COUNT; i ++ ) + { + if ( idStr::Icmp ( idWindow::ScriptNames[i], token ) == 0 ) + { + scriptName = idWindow::ScriptNames[i]; + break; + } + } + + if ( i >= idWindow::SCRIPT_COUNT ) + { + src.Error ( "expected script name" ); + return false; + } + } + + if ( !src.ParseBracedSectionExact ( out, 1) ) + { + return false; + } + + wrapper->GetScriptDict().Set ( scriptName, out ); + } + } + catch ( idException &e ) + { + MessageBox ( hwnd, e.error, "Script Error", MB_OK|MB_ICONERROR); + return false; + } + + return true; +} + +INT_PTR CALLBACK GEItescriptsDlg_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_INITDIALOG: + SetWindowLong ( hwnd, GWL_USERDATA, lParam ); + GEItescriptsDlg_Init ( hwnd ); + + gApp.GetOptions().GetWindowPlacement ( "scripts", hwnd ); + + // Let it fall through so the scripts window gets resized. + + case WM_SIZE: + { + RECT rClient; + GetClientRect ( hwnd, &rClient ); + MoveWindow ( GetDlgItem ( hwnd, IDC_GUIED_SCRIPT ), + rClient.left, rClient.top, + rClient.right - rClient.left, + rClient.bottom - rClient.top, + FALSE ); + break; + } + + case WM_ERASEBKGND: + return TRUE; + + + case WM_CLOSE: + if ( !GEItescriptsDlg_Apply ( hwnd ) ) + { + return TRUE; + } + gApp.GetOptions().SetWindowPlacement ( "scripts", hwnd ); + EndDialog ( hwnd, 1 ); + break; + } + + return FALSE; +} + +/* +================ +GEItemScriptsDlg_DoModal + +Starts the item properties dialog +================ +*/ +bool GEItemScriptsDlg_DoModal ( HWND parent, idWindow* window ) +{ + LoadLibrary ( "Riched20.dll" ); + + if ( DialogBoxParam ( gApp.GetInstance(), MAKEINTRESOURCE(IDD_GUIED_SCRIPTS), parent, GEItescriptsDlg_WndProc, (LPARAM) window ) ) + { + return true; + } + + return false; +} + \ No newline at end of file diff --git a/tools/guied/GEItemScriptsDlg.h b/tools/guied/GEItemScriptsDlg.h new file mode 100644 index 000000000..3aca1205a --- /dev/null +++ b/tools/guied/GEItemScriptsDlg.h @@ -0,0 +1,24 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEITEMSCRIPTSDLG_H_ +#define GEITEMSCRIPTSDLG_H_ + +bool GEItemScriptsDlg_DoModal ( HWND parent, idWindow* window ); + +#endif // GEITEMSCRIPTSDLG_H_ \ No newline at end of file diff --git a/tools/guied/GEKeyValueModifier.cpp b/tools/guied/GEKeyValueModifier.cpp new file mode 100644 index 000000000..22fe801ee --- /dev/null +++ b/tools/guied/GEKeyValueModifier.cpp @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEKeyValueModifier.h" + +rvGEKeyValueModifier::rvGEKeyValueModifier ( const char* name, idWindow* window, const char* key, const char* value ) : + rvGEModifier ( name, window ), + mKey ( key ), + mValue ( value ) +{ + mUndoValue = mWrapper->GetStateDict().GetString ( mKey ); +} + +bool rvGEKeyValueModifier::Apply ( void ) +{ + if ( mValue.Length ( ) ) + { + mWrapper->SetStateKey ( mKey, mValue ); + } + else + { + mWrapper->DeleteStateKey ( mKey ); + } + + return true; +} + +bool rvGEKeyValueModifier::Undo ( void ) +{ + mWrapper->SetStateKey ( mKey, mValue ); + + return true; +} + +bool rvGEKeyValueModifier::Merge ( rvGEModifier* mergebase ) +{ + rvGEKeyValueModifier* merge = (rvGEKeyValueModifier*) mergebase; + + mValue = merge->mValue; + + return true; +} diff --git a/tools/guied/GEKeyValueModifier.h b/tools/guied/GEKeyValueModifier.h new file mode 100644 index 000000000..307d89987 --- /dev/null +++ b/tools/guied/GEKeyValueModifier.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEKEYVALUEMODIFIER_H_ +#define GEKEYVALUEMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEKeyValueModifier : public rvGEModifier +{ +public: + + rvGEKeyValueModifier ( const char* name, idWindow* window, const char* key, const char* value ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + + virtual bool CanMerge ( rvGEModifier* merge ); + virtual bool Merge ( rvGEModifier* merge ); + +protected: + + idStr mKey; + idStr mValue; + idStr mUndoValue; +}; + +ID_INLINE bool rvGEKeyValueModifier::CanMerge ( rvGEModifier* merge ) +{ + return !((rvGEKeyValueModifier*)merge)->mKey.Icmp ( mKey ); +} + +#endif // GEKEYVALUEMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GEModifier.cpp b/tools/guied/GEModifier.cpp new file mode 100644 index 000000000..e1be3f629 --- /dev/null +++ b/tools/guied/GEModifier.cpp @@ -0,0 +1,35 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" + +rvGEModifier::rvGEModifier ( const char* name, idWindow* window ) +{ + mWindow = window; + mName = name; + + if ( mWindow ) + { + mWrapper = rvGEWindowWrapper::GetWrapper ( window ); + } +} + diff --git a/tools/guied/GEModifier.h b/tools/guied/GEModifier.h new file mode 100644 index 000000000..c1ff5f6b2 --- /dev/null +++ b/tools/guied/GEModifier.h @@ -0,0 +1,76 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEMODIFIER_H_ +#define GEMODIFIER_H_ + +class idWindow; +class rvGEWindowWrapper; + +class rvGEModifier +{ +public: + + rvGEModifier ( const char* name, idWindow* window ); + virtual ~rvGEModifier ( ) { } + + virtual bool Apply ( void ) = 0; + virtual bool Undo ( void ) = 0; + virtual const char* GetName ( void ); + virtual bool CanMerge ( rvGEModifier* merge ); + + virtual bool IsValid ( void ); + + virtual bool Merge ( rvGEModifier* merge ); + + idWindow* GetWindow ( void ); + + +protected: + + idWindow* mWindow; + rvGEWindowWrapper* mWrapper; + idStr mName; +}; + +ID_INLINE bool rvGEModifier::IsValid ( void ) +{ + return true; +} + +ID_INLINE idWindow* rvGEModifier::GetWindow ( void ) +{ + return mWindow; +} + +ID_INLINE const char* rvGEModifier::GetName ( void ) +{ + return mName; +} + +ID_INLINE bool rvGEModifier::CanMerge ( rvGEModifier* merge ) +{ + return false; +} + +ID_INLINE bool rvGEModifier::Merge ( rvGEModifier* merge ) +{ + return false; +} + +#endif // GEMODIFIER_H_ diff --git a/tools/guied/GEModifierGroup.cpp b/tools/guied/GEModifierGroup.cpp new file mode 100644 index 000000000..8bc42f677 --- /dev/null +++ b/tools/guied/GEModifierGroup.cpp @@ -0,0 +1,139 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEModifierGroup.h" + +rvGEModifierGroup::rvGEModifierGroup ( ) : + rvGEModifier ( "Group", NULL ) +{ +} + +rvGEModifierGroup::~rvGEModifierGroup ( ) +{ + int i; + + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + delete mModifiers[i]; + } + + mModifiers.Clear ( ); +} + +bool rvGEModifierGroup::Append ( rvGEModifier* mod ) +{ + // All modifiers must be the same type + assert ( !mModifiers.Num() || !idStr::Icmp ( mod->GetName ( ), mModifiers[0]->GetName ( ) ) ); + + if ( !mModifiers.Num ( ) ) + { + mName = mod->GetName ( ); + } + + mModifiers.Append ( mod ); + return true; +} + +bool rvGEModifierGroup::IsValid ( void ) +{ + int i; + + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + if ( !mModifiers[i]->IsValid ( ) ) + { + return false; + } + } + + return true; +} + +bool rvGEModifierGroup::Apply ( void ) +{ + int i; + + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + mModifiers[i]->Apply ( ); + } + + return true; +} + +bool rvGEModifierGroup::Undo ( void ) +{ + int i; + + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + mModifiers[i]->Undo ( ); + } + + return true; +} + +bool rvGEModifierGroup::CanMerge ( rvGEModifier* mergebase ) +{ + rvGEModifierGroup* merge = (rvGEModifierGroup*) mergebase; + int i; + + if ( mModifiers.Num() != merge->mModifiers.Num ( ) ) + { + return false; + } + + // Double check the merge is possible + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + if ( mModifiers[i]->GetWindow() != merge->mModifiers[i]->GetWindow() ) + { + return false; + } + + if ( idStr::Icmp ( mModifiers[i]->GetName ( ), merge->mModifiers[i]->GetName ( ) ) ) + { + return false; + } + + if ( !mModifiers[i]->CanMerge ( merge->mModifiers[i] ) ) + { + return false; + } + } + + return true; +} + +bool rvGEModifierGroup::Merge ( rvGEModifier* mergebase ) +{ + rvGEModifierGroup* merge = (rvGEModifierGroup*) mergebase; + int i; + + // Double check the merge is possible + for ( i = 0; i < mModifiers.Num(); i ++ ) + { + mModifiers[i]->Merge ( merge->mModifiers[i] ); + } + + return true; +} diff --git a/tools/guied/GEModifierGroup.h b/tools/guied/GEModifierGroup.h new file mode 100644 index 000000000..3db5c9b10 --- /dev/null +++ b/tools/guied/GEModifierGroup.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEMODIFIERGROUP_H_ +#define GEMODIFIERGROUP_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEModifierGroup : public rvGEModifier +{ +public: + + rvGEModifierGroup ( ); + ~rvGEModifierGroup ( ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + + virtual bool CanMerge ( rvGEModifier* merge ); + + virtual bool Merge ( rvGEModifier* merge ); + + virtual bool IsValid ( void ); + + bool Append ( rvGEModifier* mod ); + int GetCount ( void ); + + +protected: + + idList mModifiers; + +}; + +ID_INLINE int rvGEModifierGroup::GetCount( void ) +{ + return mModifiers.Num ( ); +} + +#endif \ No newline at end of file diff --git a/tools/guied/GEModifierStack.cpp b/tools/guied/GEModifierStack.cpp new file mode 100644 index 000000000..272b15c7e --- /dev/null +++ b/tools/guied/GEModifierStack.cpp @@ -0,0 +1,128 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEModifierStack.h" + +rvGEModifierStack::rvGEModifierStack ( ) +{ + mCurrentModifier = -1; +} + +rvGEModifierStack::~rvGEModifierStack ( ) +{ + Reset ( ); +} + +void rvGEModifierStack::Reset ( void ) +{ + int i; + + for ( i = 0; i < mModifiers.Num ( ); i ++ ) + { + delete mModifiers[i]; + } + + mModifiers.Clear ( ); +} + +bool rvGEModifierStack::Append ( rvGEModifier* modifier ) +{ + // TODO: Add the modifier and clear all redo modifiers + if ( !modifier->IsValid ( ) ) + { + delete modifier; + return false; + } + + while ( mCurrentModifier < mModifiers.Num ( ) - 1 ) + { + delete mModifiers[mModifiers.Num()-1]; + mModifiers.RemoveIndex ( mModifiers.Num()-1 ); + } + + if ( !mMergeBlock && mModifiers.Num ( ) ) + { + rvGEModifier* top = mModifiers[mModifiers.Num()-1]; + + // See if the two modifiers can merge + if ( top->GetWindow() == modifier->GetWindow() && + !idStr::Icmp ( top->GetName ( ), modifier->GetName ( ) ) && + top->CanMerge ( modifier ) ) + { + // Merge the two modifiers + if ( top->Merge ( modifier ) ) + { + top->Apply ( ); + + gApp.GetProperties().Update ( ); + gApp.GetTransformer().Update ( ); + + delete modifier; + return true; + } + } + } + + mModifiers.Append ( modifier ); + mCurrentModifier = mModifiers.Num ( ) - 1; + + modifier->Apply ( ); + + mMergeBlock = false; + + gApp.GetProperties().Update ( ); + gApp.GetTransformer().Update ( ); + + return true; +} + +bool rvGEModifierStack::Undo ( void ) +{ + if ( mCurrentModifier < 0 ) + { + return false; + } + + mModifiers[mCurrentModifier]->Undo ( ); + mCurrentModifier--; + + gApp.GetProperties().Update ( ); + gApp.GetTransformer().Update ( ); + + return true; +} + +bool rvGEModifierStack::Redo ( void ) +{ + if ( mCurrentModifier + 1 < mModifiers.Num ( ) ) + { + mCurrentModifier++; + mModifiers[mCurrentModifier]->Apply ( ); + } + + gApp.GetProperties().Update ( ); + gApp.GetTransformer().Update ( ); + + return true; +} + diff --git a/tools/guied/GEModifierStack.h b/tools/guied/GEModifierStack.h new file mode 100644 index 000000000..7b3e6bf94 --- /dev/null +++ b/tools/guied/GEModifierStack.h @@ -0,0 +1,81 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEMODIFIERSTACK_H_ +#define GEMODIFIERSTACK_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEModifierStack +{ +public: + + rvGEModifierStack ( ); + ~rvGEModifierStack ( ); + + void BlockNextMerge ( void ); + + bool Append ( rvGEModifier* modifier ); + bool Undo ( void ); + bool Redo ( void ); + + void Reset ( void ); + + bool CanUndo ( void ); + bool CanRedo ( void ); + + rvGEModifier* GetUndoModifier ( void ); + rvGEModifier* GetRedoModifier ( void ); + +protected: + + idList mModifiers; + int mCurrentModifier; + bool mMergeBlock; +}; + +ID_INLINE bool rvGEModifierStack::CanRedo ( void ) +{ + return mCurrentModifier < mModifiers.Num()-1; +} + +ID_INLINE bool rvGEModifierStack::CanUndo ( void ) +{ + return mCurrentModifier >= 0; +} + +ID_INLINE void rvGEModifierStack::BlockNextMerge ( void ) +{ + mMergeBlock = true; +} + +ID_INLINE rvGEModifier* rvGEModifierStack::GetUndoModifier ( void ) +{ + assert ( CanUndo ( ) ); + return mModifiers[mCurrentModifier]; +} + +ID_INLINE rvGEModifier* rvGEModifierStack::GetRedoModifier ( void ) +{ + assert ( CanRedo ( ) ); + return mModifiers[mCurrentModifier+1]; +} + +#endif diff --git a/tools/guied/GEMoveModifier.cpp b/tools/guied/GEMoveModifier.cpp new file mode 100644 index 000000000..95bf43986 --- /dev/null +++ b/tools/guied/GEMoveModifier.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEMoveModifier.h" + +rvGEMoveModifier::rvGEMoveModifier ( const char* name, idWindow* window, float x, float y ) : + rvGEModifier ( name, window ) +{ + mOldRect = mWrapper->GetClientRect ( ); + + mNewRect[0] = mOldRect[0] + x; + mNewRect[1] = mOldRect[1] + y; + mNewRect[2] = mOldRect[2]; + mNewRect[3] = mOldRect[3]; +} + +bool rvGEMoveModifier::Merge ( rvGEModifier* mergebase ) +{ + rvGEMoveModifier* merge = (rvGEMoveModifier*) mergebase; + + mNewRect = merge->mNewRect; + + return true; +} + +bool rvGEMoveModifier::Apply ( void ) +{ + mWrapper->SetRect ( mNewRect ); + + return true; +} + +bool rvGEMoveModifier::Undo ( void ) +{ + mWrapper->SetRect ( mOldRect ); + + return true; +} + +bool rvGEMoveModifier::IsValid ( void ) +{ + if ( !mWindow->GetParent ( ) ) + { + return false; + } + + return true; +} diff --git a/tools/guied/GEMoveModifier.h b/tools/guied/GEMoveModifier.h new file mode 100644 index 000000000..adae5c67a --- /dev/null +++ b/tools/guied/GEMoveModifier.h @@ -0,0 +1,47 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEMOVEMODIFIER_H_ +#define GEMOVEMODIFIER_H_ + +class rvGEMoveModifier : public rvGEModifier +{ +public: + + rvGEMoveModifier ( const char* name, idWindow* window, float x, float y ); + + virtual bool CanMerge ( rvGEModifier* merge ); + virtual bool Merge ( rvGEModifier* merge ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + + virtual bool IsValid ( void ); + +protected: + + idRectangle mNewRect; + idRectangle mOldRect; +}; + +ID_INLINE bool rvGEMoveModifier::CanMerge ( rvGEModifier* merge ) +{ + return true; +} + +#endif // GEMOVEMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GENavigator.cpp b/tools/guied/GENavigator.cpp new file mode 100644 index 000000000..6658f9b6c --- /dev/null +++ b/tools/guied/GENavigator.cpp @@ -0,0 +1,587 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" + +#define GENAV_ITEMHEIGHT 22 + +rvGENavigator::rvGENavigator ( ) +{ + mWnd = NULL; + mWorkspace = NULL; + mVisibleIcon = NULL; + mScriptsIcon = NULL; + mVisibleIconDisabled = NULL; + mScriptsLightIcon = NULL; +} + +/* +================ +rvGENavigator::Create + +Creates the navigator window +================ +*/ +bool rvGENavigator::Create ( HWND parent, bool visible ) +{ + WNDCLASSEX wndClass; + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "GUIEDITOR_NAVIGATOR_CLASS"; + wndClass.lpfnWndProc = rvGENavigator::WndProc; + wndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH );; + wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); + wndClass.lpszMenuName = NULL; + wndClass.hInstance = win32.hInstance; + RegisterClassEx ( &wndClass ); + + mVisibleIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_VISIBLE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + mScriptsIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_SCRIPTS), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ); + mScriptsLightIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_SCRIPTSHI), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ); + mVisibleIconDisabled = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_VISIBLEDISABLED), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + mExpandIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_EXPAND), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + mCollapseIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_COLLAPSE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + + mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW, + "GUIEDITOR_NAVIGATOR_CLASS", + "Navigator", + WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD, + 0, 0, 200,300, + parent, + NULL, + win32.hInstance, + this ); + + if ( !mWnd ) + { + return false; + } + + if ( !gApp.GetOptions().GetWindowPlacement ( "navigator", mWnd ) ) + { + RECT rParent; + RECT rNav; + + GetWindowRect ( parent, &rParent ); + GetWindowRect ( mWnd, &rNav ); + SetWindowPos ( mWnd, NULL, + rParent.right - 10 - (rNav.right-rNav.left), + rParent.bottom - 10 - (rNav.bottom-rNav.top), + 0,0, + SWP_NOZORDER|SWP_NOSIZE ); + } + + Show ( visible ); + + return true; +} + +/* +================ +Draw3dRect + +Draws a 3d rectangle using the given brushes +================ +*/ +void Draw3dRect ( HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight ) +{ + RECT rOut; + + SetRect ( &rOut, rect->left, rect->top, rect->right - 1, rect->top + 1 ); + FillRect ( hDC,&rOut, topLeft ); + + SetRect ( &rOut, rect->left, rect->top, rect->left + 1, rect->bottom ); + FillRect( hDC,&rOut, topLeft ); + + SetRect ( &rOut, rect->right, rect->top, rect->right -1, rect->bottom ); + FillRect( hDC,&rOut, bottomRight ); + + SetRect ( &rOut, rect->left, rect->bottom, rect->right, rect->bottom - 1 ); + FillRect( hDC,&rOut, bottomRight ); +} + +/* +================ +rvGENavigator::WndProc + +Window Procedure +================ +*/ +LRESULT CALLBACK rvGENavigator::WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGENavigator* nav = (rvGENavigator*) GetWindowLong ( hWnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_INITMENUPOPUP: + return SendMessage ( gApp.GetMDIFrame ( ), msg, wParam, lParam ); + + case WM_ACTIVATE: + common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE ); + break; + + case WM_ERASEBKGND: + return TRUE; + + case WM_DESTROY: + gApp.GetOptions().SetWindowPlacement ( "navigator", hWnd ); + break; + + case WM_CLOSE: + gApp.GetOptions().SetNavigatorVisible ( false ); + nav->Show ( false ); + return 0; + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT* dis = (DRAWITEMSTRUCT*) lParam; + idWindow* window = (idWindow*)dis->itemData; + + if ( window ) + { + rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( window ); + idStr name = window->GetName(); + RECT rDraw; + float offset; + bool disabled; + + idWindow* parent = window; + offset = 1; + disabled = false; + while ( parent = parent->GetParent ( ) ) + { + if ( rvGEWindowWrapper::GetWrapper ( parent )->IsHidden ( ) ) + { + disabled = true; + } + + offset += 10; + } + + CopyRect ( &rDraw, &dis->rcItem ); + rDraw.right = rDraw.left + GENAV_ITEMHEIGHT; + rDraw.top ++; + + rDraw.right ++; + FrameRect ( dis->hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) ); + rDraw.right --; + + FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DFACE ) ); + + Draw3dRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DHILIGHT ), GetSysColorBrush ( COLOR_3DSHADOW ) ); + + InflateRect ( &rDraw, -3, -3 ); + Draw3dRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DSHADOW ), GetSysColorBrush ( COLOR_3DHILIGHT ) ); + + if ( !wrapper->IsHidden ( ) ) + { + DrawIconEx ( dis->hDC, rDraw.left, rDraw.top, disabled?nav->mVisibleIconDisabled:nav->mVisibleIcon, 16, 16,0, NULL, DI_NORMAL ); + } + + CopyRect ( &rDraw, &dis->rcItem ); + rDraw.left += GENAV_ITEMHEIGHT; + rDraw.left += 1; + + if ( dis->itemState & ODS_SELECTED ) + { + FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_HIGHLIGHT ) ); + } + else + { + FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_WINDOW ) ); + } + + if ( wrapper->CanHaveChildren ( ) && window->GetChildCount ( ) ) + { + if ( wrapper->IsExpanded ( ) ) + { + DrawIconEx ( dis->hDC, rDraw.left + offset, rDraw.top + 3, nav->mCollapseIcon, 16, 16,0, NULL, DI_NORMAL ); + } + else + { + DrawIconEx ( dis->hDC, rDraw.left + offset, rDraw.top + 3, nav->mExpandIcon, 16, 16,0, NULL, DI_NORMAL ); + } + } + + HPEN pen = CreatePen ( PS_SOLID, 1, GetSysColor ( COLOR_3DSHADOW ) ); + HPEN oldpen = (HPEN)SelectObject ( dis->hDC, pen ); + MoveToEx ( dis->hDC, rDraw.left, dis->rcItem.top, NULL ); + LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.top ); + MoveToEx ( dis->hDC, rDraw.left, dis->rcItem.bottom, NULL ); + LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.bottom); + SelectObject ( dis->hDC, oldpen ); + DeleteObject ( pen ); + + rDraw.left += offset; + rDraw.left += 20; + + int colorIndex = ( (dis->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT ); + SetTextColor ( dis->hDC, GetSysColor ( colorIndex ) ); + DrawText ( dis->hDC, name, name.Length(), &rDraw, DT_LEFT|DT_VCENTER|DT_SINGLELINE ); + + if ( wrapper->GetVariableDict().GetNumKeyVals ( ) || wrapper->GetScriptDict().GetNumKeyVals ( ) ) + { + DrawIconEx ( dis->hDC, dis->rcItem.right - 16, (dis->rcItem.bottom+dis->rcItem.top)/2-6, (dis->itemState & ODS_SELECTED)?nav->mScriptsLightIcon:nav->mScriptsIcon, 13, 13,0, NULL, DI_NORMAL ); + } + } + + break; + } + + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT* mis = (MEASUREITEMSTRUCT*) lParam; + mis->itemHeight = 22; + break; + } + + case WM_CREATE: + { + LPCREATESTRUCT cs; + LVCOLUMN col; + + // Attach the class to the window first + cs = (LPCREATESTRUCT) lParam; + nav = (rvGENavigator*) cs->lpCreateParams; + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)nav ); + + // Create the List view + nav->mTree = CreateWindowEx ( 0, "SysListView32", "", WS_VSCROLL|WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_OWNERDRAWFIXED|LVS_NOCOLUMNHEADER|LVS_SHOWSELALWAYS, 0, 0, 0, 0, hWnd, (HMENU)IDC_GUIED_WINDOWTREE, win32.hInstance, 0 ); + ListView_SetExtendedListViewStyle ( nav->mTree, LVS_EX_FULLROWSELECT ); + ListView_SetBkColor ( nav->mTree, GetSysColor ( COLOR_3DFACE ) ); + ListView_SetTextBkColor ( nav->mTree, GetSysColor ( COLOR_3DFACE ) ); + nav->mListWndProc = (WNDPROC)GetWindowLong ( nav->mTree, GWL_WNDPROC ); + SetWindowLong ( nav->mTree, GWL_USERDATA, (LONG)nav ); + SetWindowLong ( nav->mTree, GWL_WNDPROC, (LONG)ListWndProc ); + + // Insert the only column + col.mask = 0; + ListView_InsertColumn ( nav->mTree, 0, &col ); + + break; + } + + case WM_SIZE: + { + RECT rClient; + MoveWindow ( nav->mTree, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE ); + GetClientRect ( nav->mTree, &rClient ); + ListView_SetColumnWidth ( nav->mTree, 0, rClient.right-rClient.left-1 ); + break; + } + + case WM_NCACTIVATE: + return gApp.ToolWindowActivate ( gApp.GetMDIFrame(), msg, wParam, lParam ); + + case WM_NOTIFY: + { + LPNMHDR nh; + + nh = (LPNMHDR) lParam; + + switch ( nh->code ) + { + case NM_CLICK: + case NM_DBLCLK: + { + DWORD dwpos = GetMessagePos(); + LVHITTESTINFO info; + info.pt.x = LOWORD(dwpos); + info.pt.y = HIWORD(dwpos); + MapWindowPoints(HWND_DESKTOP, nh->hwndFrom, &info.pt, 1); + int index = ListView_HitTest ( nav->mTree, &info ); + if ( index != -1 ) + { + RECT rItem; + int offset; + ListView_GetItemRect ( nav->mTree, index, &rItem, LVIR_BOUNDS ); + LVITEM item; + item.mask = LVIF_PARAM; + item.iItem = index; + ListView_GetItem ( nav->mTree, &item ); + idWindow* window = (idWindow*)item.lParam; + rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper(window); + + offset = wrapper->GetDepth ( ) * 10 + 1; + + if ( info.pt.x < GENAV_ITEMHEIGHT ) + { + if ( !rvGEWindowWrapper::GetWrapper(window)->IsHidden ( ) ) + { + nav->mWorkspace->HideWindow ( window ); + } + else + { + nav->mWorkspace->UnhideWindow ( window ); + } + } + else if ( info.pt.x > GENAV_ITEMHEIGHT + offset && info.pt.x < GENAV_ITEMHEIGHT + offset + 16 ) + { + if ( wrapper->CanHaveChildren ( ) && window->GetChildCount ( ) ) + { + if ( wrapper->IsExpanded ( ) ) + { + wrapper->Collapse ( ); + nav->Update ( ); + } + else + { + wrapper->Expand ( ); + nav->Update ( ); + } + } + } + else if ( nh->code == NM_DBLCLK ) + { + SendMessage ( gApp.GetMDIFrame ( ), WM_COMMAND, MAKELONG(ID_GUIED_ITEM_PROPERTIES,0), 0 ); + } + } + + break; + } + + case NM_RCLICK: + { + DWORD dwpos = GetMessagePos(); + LVHITTESTINFO info; + info.pt.x = LOWORD(dwpos); + info.pt.y = HIWORD(dwpos); + MapWindowPoints(HWND_DESKTOP, nh->hwndFrom, &info.pt, 1); + int index = ListView_HitTest ( nav->mTree, &info ); + + if ( index != -1 ) + { + ClientToScreen ( hWnd, &info.pt ); + HMENU menu = GetSubMenu ( LoadMenu ( gApp.GetInstance(), MAKEINTRESOURCE(IDR_GUIED_ITEM_POPUP) ), 0 ); + TrackPopupMenu ( menu, TPM_RIGHTBUTTON|TPM_LEFTALIGN, info.pt.x, info.pt.y, 0, gApp.GetMDIFrame ( ), NULL ); + DestroyMenu ( menu ); + } + + break; + } + + case LVN_ITEMCHANGED: + { + NMLISTVIEW* nml = (NMLISTVIEW*) nh; + if ( (nml->uNewState & LVIS_SELECTED) != (nml->uOldState & LVIS_SELECTED) ) + { + LVITEM item; + item.iItem = nml->iItem; + item.mask = LVIF_PARAM; + ListView_GetItem ( nav->mTree, &item ); + + if ( nml->uNewState & LVIS_SELECTED ) + { + nav->mWorkspace->GetSelectionMgr().Add ( (idWindow*)item.lParam, false ); + } + else + { + nav->mWorkspace->GetSelectionMgr().Remove ( (idWindow*)item.lParam ); + } + } + break; + } + } + + break; + } + } + + return DefWindowProc ( hWnd, msg, wParam, lParam ); +} + +/* +================ +rvGENavigator::ListWndProc + +Window Procedure for the embedded list control +================ +*/ +LRESULT CALLBACK rvGENavigator::ListWndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGENavigator* nav = (rvGENavigator*) GetWindowLong ( hWnd, GWL_USERDATA ); + assert ( nav ); + + switch ( msg ) + { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + if ( nav->mWorkspace ) + { + return SendMessage ( nav->mWorkspace->GetWindow(), msg, wParam, lParam ); + } + break; + } + + return CallWindowProc ( nav->mListWndProc, hWnd, msg, wParam, lParam ); +} + +/* +================ +rvGENavigator::AddWindow + +Adds a new window to the navigator +================ +*/ +void rvGENavigator::AddWindow ( idWindow* window ) +{ + int index; + LVITEM item; + rvGEWindowWrapper* wrapper; + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + + // Dont add deleted windows + if ( !wrapper || wrapper->IsDeleted ( ) ) + { + return; + } + + // Insert the window into the tree + ZeroMemory ( &item, sizeof(item) ); + item.mask = LVIF_PARAM|LVIF_STATE|LVIF_IMAGE; + item.iItem = ListView_GetItemCount ( mTree ); + item.lParam = (LONG) window; + item.iImage = 0; + item.state = rvGEWindowWrapper::GetWrapper(window)->IsSelected ()? LVIS_SELECTED:0; + item.stateMask = LVIS_SELECTED; + ListView_InsertItem ( mTree, &item ); + + if ( item.state & LVIS_SELECTED ) + { + ListView_EnsureVisible ( mTree, item.iItem, false ); + } + + // Dont continue if not expanded. + if ( !wrapper->IsExpanded ( ) ) + { + return; + } + + // Insert all the child windows into the tree + for ( index = 0; index < wrapper->GetChildCount(); index ++ ) + { + AddWindow ( wrapper->GetChild(index) ); + } +} + +/* +================ +rvGENavigator::SetWorkspace + +Sets a new workspace for the navigator window +================ +*/ +void rvGENavigator::SetWorkspace ( rvGEWorkspace* workspace ) +{ + mWorkspace = workspace; + + Update ( ); +} + +/* +================ +rvGENavigator::Update + +Updates the contents of the navigator window from the current workspace +================ +*/ +void rvGENavigator::Update ( void ) +{ + // Clear the list first + ListView_DeleteAllItems ( mTree ); + + // Add starting with the desktop window + if ( mWorkspace ) + { + AddWindow ( mWorkspace->GetInterface ( )->GetDesktop ( ) ); + } + + // For some reason the horizontal scrollbar wants to show up initially after an update + // so this forces it not to + RECT rClient; + GetClientRect ( mTree, &rClient ); + ListView_SetColumnWidth ( mTree, 0, rClient.right-rClient.left-1 ); +} + +/* +================ +rvGENavigator::UpdateSelection + +Updates the currently selected items +================ +*/ +void rvGENavigator::UpdateSelections ( void ) +{ + int count = ListView_GetItemCount ( mTree ); + int i; + + for ( i = 0; i < count; i++ ) + { + LVITEM item; + idWindow* window; + rvGEWindowWrapper* wrapper; + + item.iItem = i; + item.mask = LVIF_PARAM; + ListView_GetItem ( mTree, &item ); + window = (idWindow*) item.lParam; + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + + ListView_SetItemState ( mTree, i, wrapper->IsSelected ( )?LVIS_SELECTED:0, LVIS_SELECTED ); + + if ( wrapper->IsSelected ( ) ) + { + ListView_EnsureVisible ( mTree, i, false ); + } + } +} + +/* +================ +rvGENavigator::Refresh + +Repaints the navigator window +================ +*/ +void rvGENavigator::Refresh ( void ) +{ + InvalidateRect ( mTree, NULL, FALSE ); +// UpdateWindow ( mTree ); +} + +/* +================ +rvGENavigator::Show + +Shows and hides the navigator window +================ +*/ +void rvGENavigator::Show ( bool visible ) +{ + gApp.GetOptions().SetNavigatorVisible ( visible ); + ShowWindow ( mWnd, visible?SW_SHOW:SW_HIDE ); +} + diff --git a/tools/guied/GENavigator.h b/tools/guied/GENavigator.h new file mode 100644 index 000000000..c47099fcd --- /dev/null +++ b/tools/guied/GENavigator.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GENAVIGATOR_H_ +#define GENAVIGATOR_H_ + +class rvGEWorkspace; +class idWindow; + +class rvGENavigator +{ +public: + + rvGENavigator ( ); + + bool Create ( HWND parent, bool visible ); + void Show ( bool visibile ); + + void Refresh ( void ); + + void SetWorkspace ( rvGEWorkspace* workspace ); + + void Update ( void ); + void UpdateSelections ( void ); + + HWND GetWindow ( void ); + +protected: + + void AddWindow ( idWindow* window ); + + static LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + static LRESULT CALLBACK ListWndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + static LRESULT FAR PASCAL GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam ); + + HWND mWnd; + HWND mTree; + HICON mVisibleIcon; + HICON mVisibleIconDisabled; + HICON mScriptsIcon; + HICON mScriptsLightIcon; + HICON mCollapseIcon; + HICON mExpandIcon; + rvGEWorkspace* mWorkspace; + WNDPROC mListWndProc; +}; + +ID_INLINE HWND rvGENavigator::GetWindow ( void ) +{ + return mWnd; +} + +#endif // GENAVIGATOR_H_ \ No newline at end of file diff --git a/tools/guied/GEOptions.cpp b/tools/guied/GEOptions.cpp new file mode 100644 index 000000000..a0604933a --- /dev/null +++ b/tools/guied/GEOptions.cpp @@ -0,0 +1,181 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../ui/Window.h" +#include "../../ui/UserInterfaceLocal.h" + +#include "GEOptions.h" + +rvGEOptions::rvGEOptions() { + // Grid options + mGridColor.Set ( 0.2f, 0.2f, 1.0f, 1.0f ); + mGridWidth = 10; + mGridHeight = 10; + mGridSnap = false; + mGridVisible = false; + mNavigatorVisible = true; + mTransformerVisible = true; + mIgnoreDesktopSelect = true; + mStatusBarVisible = true; + mPropertiesVisible = true; + + mWorkspaceColor.Set ( 0.0f, 0.0f, 0.0f, 1.0f ); + mSelectionColor.Set ( 0.5f, 0.5f, 1.0f, 1.0f ); + + memset ( mCustomColors, 0, sizeof(mCustomColors) ); +} + +/* +================ +rvGEOptions::Init +================ +*/ +void rvGEOptions::Init( void ) { + mRegistry.Init( "Software\\id Software\\DOOM3\\Tools\\GUIEditor" ); +} + +/* +================ +rvGEOptions::Save + +Writes the options to the registry so they can later be read using the Load method +================ +*/ +bool rvGEOptions::Save ( void ) +{ + // Write the last page we visited + mRegistry.SetLong ( "lastOptionsPage", mLastOptionsPage ); + + // Write the grid settings + mRegistry.SetVec4 ( "gridColor", idVec4(mGridColor[0],mGridColor[1],mGridColor[2],1.0f) ); + mRegistry.SetLong ( "gridWidth", mGridWidth ); + mRegistry.SetLong ( "gridHeight", mGridHeight ); + mRegistry.SetBool ( "gridSnap", mGridSnap ); + mRegistry.SetBool ( "gridVisible", mGridVisible ); + + // Tool window states + mRegistry.SetBool ( "navigatorVisible", mNavigatorVisible ); + mRegistry.SetBool ( "PropertiesVisible", mPropertiesVisible ); + mRegistry.SetBool ( "transformerVisible", mTransformerVisible ); + mRegistry.SetBool ( "statusBarVisible", mStatusBarVisible ); + + // General stuff + mRegistry.SetVec4 ( "selectionColor", mSelectionColor ); + mRegistry.SetBool ( "ignoreDesktopSelect", mIgnoreDesktopSelect ); + + // Custom colors + int i; + for ( i = 0; i < 16; i ++ ) + { + mRegistry.SetLong ( va("customcol%d",i), mCustomColors[i] ); + } + + return mRegistry.Save ( ); +} + +/* +================ +rvGEOptions::Load + +Loads previsouly saved options from the registry +================ +*/ +bool rvGEOptions::Load ( void ) +{ + if ( !mRegistry.Load ( ) ) + { + return false; + } + + // Read the general stuff + mLastOptionsPage = mRegistry.GetLong ( "lastOptionsPage" ); + + // Read the grid settings + mGridColor = mRegistry.GetVec4 ( "gridColor" ); + mGridWidth = mRegistry.GetLong ( "gridWidth" ); + mGridHeight = mRegistry.GetLong ( "gridHeight" ); + mGridSnap = mRegistry.GetBool ( "gridSnap" ); + mGridVisible = mRegistry.GetBool ( "gridVisible" ); + + // Tool window states + mNavigatorVisible = mRegistry.GetBool ( "navigatorVisible" ); + mPropertiesVisible = mRegistry.GetBool ( "PropertiesVisible" ); + mTransformerVisible = mRegistry.GetBool ( "transformerVisible" ); + mStatusBarVisible = mRegistry.GetBool ( "statusBarVisible" ); + + // General stuff + mSelectionColor = mRegistry.GetVec4 ( "selectionColor" ); + mIgnoreDesktopSelect = mRegistry.GetBool ( "ignoreDesktopSelect" ); + + // Custom colors + int i; + for ( i = 0; i < 16; i ++ ) + { + mCustomColors[i] = mRegistry.GetLong ( va("customcol%d",i) ); + } + + return true; +} + +/* +================ +rvGEOptions::SnapRectToGrid + +Snap the rectangle to the grid +================ +*/ +void rvGEOptions::SnapRectToGrid ( idRectangle& rect, bool snapLeft, bool snapTop, bool snapWidth, bool snapHeight ) +{ + if ( snapLeft ) + { + float offset = (int)(rect.x + GetGridWidth() / 2) / GetGridWidth() * GetGridWidth(); + offset -= rect.x; + rect.x += offset; + rect.w -= offset; + } + + if ( snapWidth ) + { + float offset = (int)(rect.x + rect.w + GetGridWidth() / 2) / GetGridWidth() * GetGridWidth(); + offset -= rect.x; + offset -= rect.w; + rect.w += offset; + } + + if ( snapTop ) + { + float offset = (int)(rect.y + GetGridHeight() / 2) / GetGridHeight() * GetGridHeight(); + offset -= rect.y; + rect.y += offset; + rect.h -= offset; + } + + if ( snapHeight ) + { + float offset = (int)(rect.y + rect.h + GetGridHeight() / 2) / GetGridHeight() * GetGridHeight(); + offset -= rect.y; + offset -= rect.h; + rect.h += offset; + } +} + + diff --git a/tools/guied/GEOptions.h b/tools/guied/GEOptions.h new file mode 100644 index 000000000..d821d491c --- /dev/null +++ b/tools/guied/GEOptions.h @@ -0,0 +1,305 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEOPTIONS_H_ +#define GEOPTIONS_H_ + +#ifndef REGISTRYOPTIONS_H_ +#include "../common/registryoptions.h" +#endif + +class idRectangle; + +class rvGEOptions +{ +public: + + static const int MAX_MRU_SIZE = rvRegistryOptions::MAX_MRU_SIZE; + + rvGEOptions(); + + void Init( void ); + + // Write the options to the registery + bool Save ( void ); + + // Read the options from the registry + bool Load ( void ); + + void SetSelectionColor ( idVec4& color ); + void SetSelectionColor ( COLORREF color ); + void SetGridColor ( idVec4& color ); + void SetGridColor ( COLORREF color ); + void SetGridWidth ( int width ); + void SetGridHeight ( int height ); + void SetGridVisible ( bool vis ); + void SetGridSnap ( bool snap ); + void SetLastOptionsPage ( int page ); + void SetNavigatorVisible ( bool vis ); + void SetPropertiesVisible ( bool vis ); + void SetTransformerVisible ( bool vis ); + void SetIgnoreDesktopSelect ( bool ignore ); + void SetStatusBarVisible ( bool vis ); + + void AddRecentFile ( const char* filename ); + int GetRecentFileCount ( void ); + const char* GetRecentFile ( int index ); + + idVec4& GetGridColor ( void ); + int GetGridWidth ( void ); + int GetGridHeight ( void ); + bool GetGridVisible ( void ); + bool GetGridSnap ( void ); + int GetLastOptionsPage ( void ); + idVec4& GetWorkspaceColor ( void ); + bool GetNavigatorVisible ( void ); + bool GetTransformerVisible ( void ); + bool GetPropertiesVisible ( void ); + idVec4& GetSelectionColor ( void ); + COLORREF* GetCustomColors ( void ); + bool GetIgnoreDesktopSelect ( void ); + bool GetStatusBarVisible ( void ); + + void SetWindowPlacement ( const char* name, HWND hwnd ); + bool GetWindowPlacement ( const char* name, HWND hwnd ); + + void SnapRectToGrid ( idRectangle& rect, bool snapLeft = true, bool snapTop = true, bool snapWidth = true, bool snapHeight = true ); + +protected: + + void ConvertColor ( COLORREF src, idVec4& dest ); + void SetModified ( bool mod ); + + bool mModified; + int mLastOptionsPage; + + idVec4 mGridColor; + int mGridWidth; + int mGridHeight; + bool mGridSnap; + bool mGridVisible; + + idVec4 mWorkspaceColor; + idVec4 mSelectionColor; + + bool mNavigatorVisible; + bool mPropertiesVisible; + bool mTransformerVisible; + bool mStatusBarVisible; + bool mIgnoreDesktopSelect; + + idList mRecentFiles; + + COLORREF mCustomColors[16]; + + rvRegistryOptions mRegistry; +}; + +ID_INLINE void rvGEOptions::SetModified ( bool mod ) +{ + mModified = mod; +} + +ID_INLINE void rvGEOptions::ConvertColor ( COLORREF src, idVec4& dest ) +{ + dest[0] = (float)GetRValue ( src ) / 255.0f; + dest[1] = (float)GetGValue ( src ) / 255.0f; + dest[2] = (float)GetBValue ( src ) / 255.0f; + dest[3] = 1.0f; +} + +ID_INLINE void rvGEOptions::SetGridWidth ( int width ) +{ + mGridWidth = width; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetGridHeight ( int height ) +{ + mGridHeight = height; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetGridSnap ( bool snap ) +{ + mGridSnap = snap; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetGridVisible ( bool vis ) +{ + mGridVisible = vis; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetStatusBarVisible ( bool vis ) +{ + mStatusBarVisible = vis; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetGridColor ( COLORREF color ) +{ + ConvertColor ( color, mGridColor ); + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetSelectionColor ( idVec4& color ) +{ + VectorCopy ( color, mSelectionColor ); + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetSelectionColor ( COLORREF color ) +{ + ConvertColor ( color, mSelectionColor ); + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetGridColor ( idVec4& color ) +{ + VectorCopy ( color, mGridColor ); + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetNavigatorVisible ( bool vis ) +{ + mNavigatorVisible = vis; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetPropertiesVisible ( bool vis ) +{ + mPropertiesVisible = vis; + SetModified ( true ); +} + +ID_INLINE void rvGEOptions::SetTransformerVisible ( bool vis ) +{ + mTransformerVisible = vis; + SetModified ( true ); +} + +ID_INLINE idVec4& rvGEOptions::GetGridColor ( void ) +{ + return mGridColor; +} + +ID_INLINE int rvGEOptions::GetGridWidth ( void ) +{ + return mGridWidth; +} + +ID_INLINE int rvGEOptions::GetGridHeight ( void ) +{ + return mGridHeight; +} + +ID_INLINE bool rvGEOptions::GetGridVisible ( void ) +{ + return mGridVisible; +} + +ID_INLINE bool rvGEOptions::GetGridSnap ( void ) +{ + return mGridSnap; +} + +ID_INLINE idVec4& rvGEOptions::GetWorkspaceColor ( void ) +{ + return mWorkspaceColor; +} + +ID_INLINE int rvGEOptions::GetLastOptionsPage ( void ) +{ + return mLastOptionsPage; +} + +ID_INLINE void rvGEOptions::SetLastOptionsPage ( int page ) +{ + mLastOptionsPage = page; +} + +ID_INLINE bool rvGEOptions::GetNavigatorVisible ( void ) +{ + return mNavigatorVisible; +} + +ID_INLINE bool rvGEOptions::GetPropertiesVisible ( void ) +{ + return mPropertiesVisible; +} + +ID_INLINE bool rvGEOptions::GetTransformerVisible ( void ) +{ + return mTransformerVisible; +} + +ID_INLINE bool rvGEOptions::GetStatusBarVisible ( void ) +{ + return mStatusBarVisible; +} + +ID_INLINE idVec4& rvGEOptions::GetSelectionColor ( void ) +{ + return mSelectionColor; +} + +ID_INLINE COLORREF* rvGEOptions::GetCustomColors ( void ) +{ + return mCustomColors; +} + +ID_INLINE void rvGEOptions::SetIgnoreDesktopSelect ( bool ignore ) +{ + mIgnoreDesktopSelect = ignore; +} + +ID_INLINE bool rvGEOptions::GetIgnoreDesktopSelect ( void ) +{ + return mIgnoreDesktopSelect; +} + +ID_INLINE void rvGEOptions::SetWindowPlacement ( const char* name, HWND hwnd ) +{ + mRegistry.SetWindowPlacement ( name, hwnd ); +} + +ID_INLINE bool rvGEOptions::GetWindowPlacement ( const char* name, HWND hwnd ) +{ + return mRegistry.GetWindowPlacement ( name, hwnd ); +} + +ID_INLINE void rvGEOptions::AddRecentFile ( const char* filename ) +{ + mRegistry.AddRecentFile ( filename ); +} + +ID_INLINE int rvGEOptions::GetRecentFileCount ( void ) +{ + return mRegistry.GetRecentFileCount ( ); +} + +ID_INLINE const char* rvGEOptions::GetRecentFile ( int index ) +{ + return mRegistry.GetRecentFile ( index ); +} + +#endif // _GEOPTIONS_H_ + diff --git a/tools/guied/GEOptionsDlg.cpp b/tools/guied/GEOptionsDlg.cpp new file mode 100644 index 000000000..2b8e2269e --- /dev/null +++ b/tools/guied/GEOptionsDlg.cpp @@ -0,0 +1,201 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" +#include "../common/ColorButton.h" + +#include "GEApp.h" + +/* +================ +GEOptionsDlg_GeneralProc + +Dialog procedure for the general options tab +================ +*/ +static INT_PTR CALLBACK GEOptionsDlg_GeneralProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_INITDIALOG: + ColorButton_SetColor ( GetDlgItem ( hwnd, IDC_GUIED_SELECTIONCOLOR ), + RGB(gApp.GetOptions().GetSelectionColor()[0]*255, + gApp.GetOptions().GetSelectionColor()[1]*255, + gApp.GetOptions().GetSelectionColor()[2]*255) ); + CheckDlgButton ( hwnd, IDC_GUIED_IGNOREDESKTOP, gApp.GetOptions().GetIgnoreDesktopSelect()?BST_CHECKED:BST_UNCHECKED ); + break; + + case WM_COMMAND: + switch ( LOWORD ( wParam ) ) + { + case IDC_GUIED_SELECTIONCOLOR: + { + CHOOSECOLOR col; + ZeroMemory ( &col, sizeof(col) ); + col.lStructSize = sizeof(col); + col.lpCustColors = gApp.GetOptions().GetCustomColors ( ); + col.hwndOwner = hwnd; + col.hInstance = NULL; + col.Flags = CC_RGBINIT; + col.rgbResult = ColorButton_GetColor ( GetDlgItem ( hwnd, IDC_GUIED_SELECTIONCOLOR ) ); + if ( ChooseColor ( &col ) ) + { + ColorButton_SetColor ( GetDlgItem ( hwnd, IDC_GUIED_SELECTIONCOLOR ), col.rgbResult ); + } + break; + } + } + break; + + case WM_DRAWITEM: + ColorButton_DrawItem ( GetDlgItem ( hwnd, wParam ), (LPDRAWITEMSTRUCT)lParam ); + return TRUE; + + case WM_NOTIFY: + switch (((NMHDR FAR *) lParam)->code) + { + case PSN_APPLY: + gApp.GetOptions().SetLastOptionsPage ( PropSheet_HwndToIndex ( GetParent ( hwnd ), PropSheet_GetCurrentPageHwnd ( GetParent ( hwnd ) ) ) ); + gApp.GetOptions().SetSelectionColor ( ColorButton_GetColor ( GetDlgItem ( hwnd, IDC_GUIED_SELECTIONCOLOR ) ) ); + gApp.GetOptions().SetIgnoreDesktopSelect ( IsDlgButtonChecked ( hwnd, IDC_GUIED_IGNOREDESKTOP ) != 0 ); + break; + } + break; + } + + return FALSE; +} + +/* +================ +GEOptionsDlg_GridProc + +Dialog procedure for the grid settings tab +================ +*/ +static INT_PTR CALLBACK GEOptionsDlg_GridProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_INITDIALOG: + // Copy the options information to the dialog controls + ColorButton_SetColor ( GetDlgItem ( hwnd, IDC_GUIED_GRIDCOLOR ), RGB(gApp.GetOptions().GetGridColor()[0]*255,gApp.GetOptions().GetGridColor()[1]*255,gApp.GetOptions().GetGridColor()[2]*255) ); + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_SPACINGWIDTH ), va("%d", gApp.GetOptions().GetGridWidth ( ) ) ); + SetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_SPACINGHEIGHT ), va("%d", gApp.GetOptions().GetGridHeight ( ) ) ); + CheckDlgButton ( hwnd, IDC_GUIED_GRIDVISIBLE, gApp.GetOptions().GetGridVisible()?BST_CHECKED:BST_UNCHECKED ); + CheckDlgButton ( hwnd, IDC_GUIED_GRIDSNAP, gApp.GetOptions().GetGridSnap()?BST_CHECKED:BST_UNCHECKED ); + return TRUE; + + case WM_DRAWITEM: + ColorButton_DrawItem ( GetDlgItem ( hwnd, wParam ), (LPDRAWITEMSTRUCT)lParam ); + return TRUE; + + case WM_NOTIFY: + switch (((NMHDR FAR *) lParam)->code) + { + case PSN_APPLY: + { + char temp[32]; + + // Copy the dialog control data back to the options + GetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_SPACINGWIDTH ), temp, 32 ); + gApp.GetOptions().SetGridWidth(atol(temp)); + GetWindowText ( GetDlgItem ( hwnd, IDC_GUIED_SPACINGHEIGHT ), temp, 32 ); + gApp.GetOptions().SetGridHeight(atol(temp)); + gApp.GetOptions().SetGridVisible ( IsDlgButtonChecked ( hwnd, IDC_GUIED_GRIDVISIBLE ) != 0 ); + gApp.GetOptions().SetGridSnap ( IsDlgButtonChecked ( hwnd, IDC_GUIED_GRIDSNAP ) != 0 ); + gApp.GetOptions().SetGridColor ( ColorButton_GetColor ( GetDlgItem ( hwnd, IDC_GUIED_GRIDCOLOR ) ) ); + break; + } + } + break; + + case WM_COMMAND: + switch ( LOWORD ( wParam ) ) + { + case IDC_GUIED_GRIDCOLOR: + { + CHOOSECOLOR col; + ZeroMemory ( &col, sizeof(col) ); + col.lStructSize = sizeof(col); + col.lpCustColors = gApp.GetOptions().GetCustomColors ( ); + col.hwndOwner = hwnd; + col.hInstance = NULL; + col.Flags = CC_RGBINIT; + col.rgbResult = RGB(gApp.GetOptions().GetGridColor()[0]*255,gApp.GetOptions().GetGridColor()[1]*255,gApp.GetOptions().GetGridColor()[2]*255); + if ( ChooseColor ( &col ) ) + { + ColorButton_SetColor ( GetDlgItem ( hwnd, IDC_GUIED_GRIDCOLOR ), col.rgbResult ); + } + break; + } + } + return TRUE; + } + + return FALSE; +} + +/* +================ +GEOptionsDlg_DoModal + +Starts the options dialog and updates the global options if ok is pressed +================ +*/ +bool GEOptionsDlg_DoModal ( HWND parent ) +{ + PROPSHEETHEADER propsh; + PROPSHEETPAGE propsp[2]; + + propsp[0].dwSize = sizeof(PROPSHEETPAGE); + propsp[0].dwFlags = PSP_USETITLE; + propsp[0].hInstance = win32.hInstance; + propsp[0].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_OPTIONS_GENERAL); + propsp[0].pfnDlgProc = GEOptionsDlg_GeneralProc; + propsp[0].pszTitle = "General"; + propsp[0].lParam = 0; + + propsp[1].dwSize = sizeof(PROPSHEETPAGE); + propsp[1].dwFlags = PSP_USETITLE; + propsp[1].hInstance = win32.hInstance; + propsp[1].pszTemplate = MAKEINTRESOURCE(IDD_GUIED_OPTIONS_GRID); + propsp[1].pfnDlgProc = GEOptionsDlg_GridProc; + propsp[1].pszTitle = "Grid"; + propsp[1].lParam = 0; + + propsh.dwSize = sizeof(PROPSHEETHEADER); + propsh.nStartPage = gApp.GetOptions().GetLastOptionsPage ( ); + propsh.dwFlags = PSH_PROPSHEETPAGE|PSH_NOAPPLYNOW|PSH_NOCONTEXTHELP; + propsh.hwndParent = parent; + propsh.pszCaption = "Options"; + propsh.nPages = 2; + propsh.ppsp = (LPCPROPSHEETPAGE)&propsp; + + if ( PropertySheet ( &propsh ) ) + { + gApp.GetOptions().Save ( ); + return true; + } + + return false; +} diff --git a/tools/guied/GEOptionsDlg.h b/tools/guied/GEOptionsDlg.h new file mode 100644 index 000000000..e6637140b --- /dev/null +++ b/tools/guied/GEOptionsDlg.h @@ -0,0 +1,24 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEOPTIONSDLG_H_ +#define GEOPTIONSDLG_H_ + +bool GEOptionsDlg_DoModal ( HWND parent ); + +#endif // GEOPTIONSDLG_H_ \ No newline at end of file diff --git a/tools/guied/GEProperties.cpp b/tools/guied/GEProperties.cpp new file mode 100644 index 000000000..8cdf86ff1 --- /dev/null +++ b/tools/guied/GEProperties.cpp @@ -0,0 +1,302 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" +#include "GEProperties.h" +#include "GEWindowWrapper.h" +#include "GEStateModifier.h" + +/* +================ +rvGEProperties::rvGEProperties + +constructor +================ +*/ +rvGEProperties::rvGEProperties( void ) +{ + mWrapper = NULL; + mWnd = NULL; + mWorkspace = NULL; +} + +/* +================ +rvGEProperties::Create + +Create the property window as a child of the given window +================ +*/ +bool rvGEProperties::Create ( HWND parent, bool visible ) +{ + WNDCLASSEX wndClass; + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "GUIEDITOR_PROPERTIES_CLASS"; + wndClass.lpfnWndProc = WndProc; + wndClass.hbrBackground = (HBRUSH)GetSysColorBrush ( COLOR_3DFACE ); + wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); + wndClass.lpszMenuName = NULL; + wndClass.hInstance = win32.hInstance; + RegisterClassEx ( &wndClass ); + + mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW, + "GUIEDITOR_PROPERTIES_CLASS", + "Properties", + WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD, + 0, 0, 200,300, + parent, + NULL, + win32.hInstance, + this ); + + if ( !mWnd ) + { + return false; + } + + if ( !gApp.GetOptions().GetWindowPlacement ( "properties", mWnd ) ) + { + RECT rParent; + RECT rClient; + + GetWindowRect ( parent, &rParent ); + GetWindowRect ( mWnd, &rClient ); + SetWindowPos ( mWnd, NULL, + rParent.right - 10 - (rClient.right-rClient.left), + rParent.bottom - 10 - (rClient.bottom-rClient.top), + 0,0, + SWP_NOZORDER|SWP_NOSIZE ); + } + + Show ( visible ); + + return true; +} + +/* +================ +rvGEProperties::Show + +Show/Hide the properties window +================ +*/ +void rvGEProperties::Show ( bool visible ) +{ + gApp.GetOptions().SetPropertiesVisible ( visible ); + ShowWindow ( mWnd, visible?SW_SHOW:SW_HIDE ); +} + +/* +================ +rvGEProperties::Update + +Update the properties in the window +================ +*/ +void rvGEProperties::Update ( void ) +{ + int i; + + if ( mWorkspace && mWorkspace->GetSelectionMgr ( ).Num ( ) == 1 ) + { + mWrapper = rvGEWindowWrapper::GetWrapper ( mWorkspace->GetSelectionMgr()[0] ); + } + else + { + mWrapper = NULL; + } + + ShowWindow ( mGrid.GetWindow ( ), mWrapper?SW_SHOW:SW_HIDE ); + + mGrid.RemoveAllItems ( ); + + if ( mWrapper ) + { + for ( i = 0; i < (int)mWrapper->GetStateDict().GetNumKeyVals ( ); i ++ ) + { + const idKeyValue* kv = mWrapper->GetStateDict().GetKeyVal ( i ); + idStr temp; + temp = kv->GetValue(); + temp.StripQuotes ( ); + mGrid.AddItem ( kv->GetKey(), temp ); + } + } +} + +/* +================ +rvGEProperties::AddModifier + +Add a state modifier for the given key / value pair +================ +*/ +bool rvGEProperties::AddModifier ( const char* name, const char* value ) +{ + idDict tempstate; + idStr tempvalue; + + tempvalue = value; + if ( !mWrapper->VerfiyStateKey ( name, tempvalue ) ) + { + tempvalue = "\""; + tempvalue += value; + tempvalue += "\""; + if ( !mWrapper->VerfiyStateKey ( name, tempvalue ) ) + { + gApp.MessageBox ( va("Invalid property value '%s' for property '%s'", value, name), MB_OK ); + return false; + } + } + + tempstate = mWrapper->GetStateDict ( ); + + tempstate.Set ( name, tempvalue ); + + mWorkspace->GetModifierStack().Append ( new rvGEStateModifier ( "Property Change", mWrapper->GetWindow(), tempstate ) ); + mWorkspace->SetModified ( true ); + gApp.GetNavigator().Update ( ); + + return true; +} + +/* +================ +rvGEProperties::WndProc + +Window Procedure for the properties window +================ +*/ +LRESULT CALLBACK rvGEProperties::WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGEProperties* kv = (rvGEProperties*) GetWindowLong ( hWnd, GWL_USERDATA ); + + if ( kv && kv->mGrid.ReflectMessage ( hWnd, msg, wParam, lParam ) ) + { + return 0; + } + + switch ( msg ) + { + case WM_ACTIVATE: + common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE ); + break; + + case WM_NOTIFY: + { + NMHDR* hdr; + hdr = (NMHDR*)lParam; + if ( hdr->idFrom == 999 ) + { + NMPROPGRID* nmpg = (NMPROPGRID*)hdr; + switch ( hdr->code ) + { + case PGN_ITEMCHANGED: + return (int)kv->AddModifier ( nmpg->mName, nmpg->mValue ); +/* + case NM_KEYDOWN: + { + NMKEY* nmkey = (NMKEY*)hdr; + if ( nmkey->nVKey == VK_DELETE ) + { + int sel = kv->mGrid.GetCurSel ( ); + if ( sel != -1 ) + { + const char* prop; + + prop = kv->mGrid.GetItemName(sel); + if ( !idStr::Icmp ( prop, "rect" ) || + !idStr::Icmp ( prop, "visible" ) || + !idStr::Icmp ( prop, "name" ) ) + { + MessageBeep ( MB_ICONASTERISK ); + } + else + { + idDict tempstate; + tempstate = kv->mWrapper->GetStateDict ( ); + tempstate.Delete ( prop ); + kv->mWorkspace->GetModifierStack().Append ( new rvGEStateModifier ( "Property Change", kv->mWrapper->GetWindow(), tempstate ) ); + kv->mWorkspace->SetModified ( true ); + kv->mGrid.RemoveItem ( sel ); + } + } + } + else + { + SendMessage ( gApp.GetMDIFrame(), WM_KEYDOWN, nmkey->nVKey, nmkey->uFlags ); + } + break; + } +*/ + } + } + break; + } + + case WM_CREATE: + { + LPCREATESTRUCT cs; + + // Attach the class to the window first + cs = (LPCREATESTRUCT) lParam; + kv = (rvGEProperties*) cs->lpCreateParams; + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)kv ); + + kv->mGrid.Create ( hWnd, 999, PGS_ALLOWINSERT ); + + kv->SetWorkspace ( NULL ); + kv->Update ( ); + + break; + } + + case WM_ERASEBKGND: + if ( kv->mWrapper ) + { + return FALSE; + } + break; + + case WM_SIZE: + kv->mGrid.Move ( 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE ); + break; + + case WM_CLOSE: + gApp.GetOptions().SetPropertiesVisible ( false ); + kv->Show ( false ); + return 0; + + case WM_NCACTIVATE: + return gApp.ToolWindowActivate ( hWnd, msg, wParam, lParam ); + + case WM_DESTROY: + gApp.GetOptions().SetWindowPlacement ( "properties", hWnd ); + break; + } + + return DefWindowProc ( hWnd, msg, wParam, lParam ); +} + + diff --git a/tools/guied/GEProperties.h b/tools/guied/GEProperties.h new file mode 100644 index 000000000..c204b0e60 --- /dev/null +++ b/tools/guied/GEProperties.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEPROPERTIES_H_ +#define GEPROPERTIES_H_ + +#ifndef PROPERTYGRID_H_ +#include "../common/PropertyGrid.h" +#endif + +class rvGEWorkspace; +class rvGEWindowWrapper; + +class rvGEProperties +{ +public: + + rvGEProperties ( ); + + bool Create ( HWND parent, bool visible ); + void Show ( bool visibile ); + + void SetWorkspace ( rvGEWorkspace* workspace ); + + void Update ( void ); + + HWND GetWindow ( void ); + +protected: + + bool AddModifier ( const char* name, const char* value ); + + static LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); + + HWND mWnd; + rvPropertyGrid mGrid; + rvGEWindowWrapper* mWrapper; + rvGEWorkspace* mWorkspace; +}; + +ID_INLINE HWND rvGEProperties::GetWindow ( void ) +{ + return mWnd; +} + +ID_INLINE void rvGEProperties::SetWorkspace ( rvGEWorkspace* workspace ) +{ + mWorkspace = workspace; + Update ( ); +} + +#endif // GEPROPERTIES_H_ \ No newline at end of file diff --git a/tools/guied/GEPropertyPage.cpp b/tools/guied/GEPropertyPage.cpp new file mode 100644 index 000000000..51da5a128 --- /dev/null +++ b/tools/guied/GEPropertyPage.cpp @@ -0,0 +1,101 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../common/ColorButton.h" +#include "GEApp.h" +#include "GEPropertyPage.h" + +rvGEPropertyPage::rvGEPropertyPage ( ) +{ + mPage = NULL; +} + +/* +================ +rvGEPropertyPage::WndProc + +Window procedure for the property page class. +================ +*/ +INT_PTR CALLBACK rvGEPropertyPage::WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGEPropertyPage* page = (rvGEPropertyPage*) GetWindowLong ( hwnd, GWL_USERDATA ); + + // Pages dont get the init dialog since their Init method is called instead + if ( msg == WM_INITDIALOG ) + { + PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam; + + page = (rvGEPropertyPage*) psp->lParam; + + SetWindowLong ( hwnd, GWL_USERDATA, (LONG)page ); + page->mPage = hwnd; + + page->Init ( ); + + return FALSE; + } + else if ( !page ) + { + return FALSE; + } + + // See if the derived class wants to handle the message + return page->HandleMessage ( msg, wParam, lParam ); +} + +/* +================ +rvGEPropertyPage::HandleMessage + +Handles all messages that the base property page must handle. +================ +*/ +int rvGEPropertyPage::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_NOTIFY: + switch (((NMHDR FAR *) lParam)->code) + { + case PSN_APPLY: + if ( !Apply ( ) ) + { + SetWindowLong ( mPage, DWL_MSGRESULT, PSNRET_INVALID ); + return TRUE; + } + break; + + case PSN_SETACTIVE: + SetActive ( ); + break; + + case PSN_KILLACTIVE: + KillActive ( ); + break; + } + break; + } + + return FALSE; +} + diff --git a/tools/guied/GEPropertyPage.h b/tools/guied/GEPropertyPage.h new file mode 100644 index 000000000..b869e1444 --- /dev/null +++ b/tools/guied/GEPropertyPage.h @@ -0,0 +1,42 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEPROPERTYPAGE_H_ +#define GEPROPERTYPAGE_H_ + +class rvGEPropertyPage +{ +public: + + rvGEPropertyPage ( ); + + virtual bool Init ( void ) { return true; } + virtual bool Apply ( void ) { return true; } + virtual bool SetActive ( void ) { return true; } + virtual bool KillActive ( void ) { return true; } + virtual int HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + + static INT_PTR CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); + +protected: + + HWND mPage; +}; + +#endif // GEPROPERTYPAGE_H_ \ No newline at end of file diff --git a/tools/guied/GESelectionMgr.cpp b/tools/guied/GESelectionMgr.cpp new file mode 100644 index 000000000..723536067 --- /dev/null +++ b/tools/guied/GESelectionMgr.cpp @@ -0,0 +1,465 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../renderer/tr_local.h" +#include "../../sys/win32/win_local.h" + +#include "GEApp.h" +#include "GESelectionMgr.h" + +#define GUIED_GRABSIZE 7 +#define GUIED_CENTERSIZE 5 + +rvGESelectionMgr::rvGESelectionMgr ( ) +{ + mWorkspace = NULL; +} + +/* +================ +rvGESelectionMgr::SetSelection + +Sets the only selection for the workspace to the given window +================ +*/ +void rvGESelectionMgr::Set ( idWindow* window ) +{ + // Get rid of any current selections + Clear ( ); + + // Add this selection now + return Add ( window ); +} + +/* +================ +rvGESelectionMgr::Add + +Adds the given window to the selection list +================ +*/ +void rvGESelectionMgr::Add ( idWindow* window, bool expand ) +{ + rvGEWindowWrapper* wrapper; + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + assert ( wrapper ); + + // If the window is already selected then dont add the selection + if ( wrapper->IsSelected ( ) ) + { + return; + } + + wrapper->SetSelected ( true ); + + mSelections.Append ( window ); + + if ( expand && wrapper->Expand ( ) ) + { + gApp.GetNavigator ( ).Update ( ); + } + + gApp.GetNavigator ( ).UpdateSelections ( ); + gApp.GetNavigator ( ).Refresh ( ); + gApp.GetTransformer ( ).Update ( ); + gApp.GetProperties().Update ( ); + + UpdateExpression ( ); +} + +/* +================ +rvGESelectionMgr::RemoveSelection + +Removes the selection from the current workspace +================ +*/ +void rvGESelectionMgr::Remove ( idWindow* window ) +{ + rvGEWindowWrapper* wrapper; + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + assert ( wrapper ); + + // Dont bother if the window isnt selectd already + if ( !wrapper->IsSelected ( ) ) + { + return; + } + + wrapper->SetSelected ( false ); + + mSelections.Remove ( window ); + + gApp.GetNavigator ( ).UpdateSelections ( ); + gApp.GetNavigator ( ).Refresh ( ); + gApp.GetTransformer ( ).Update ( ); + gApp.GetProperties().Update ( ); + + UpdateExpression ( ); +} + +/* +================ +rvGESelectionMgr::ClearSelections + +Remove all of the current selections +================ +*/ +void rvGESelectionMgr::Clear ( void ) +{ + int i; + + for ( i = 0; i < mSelections.Num ( ); i ++ ) + { + rvGEWindowWrapper::GetWrapper ( mSelections[i] )->SetSelected ( false ); + } + + mSelections.Clear ( ); + + gApp.GetNavigator ( ).UpdateSelections ( ); + gApp.GetNavigator ( ).Refresh ( ); + gApp.GetTransformer ( ).Update ( ); + gApp.GetProperties().Update ( ); + + mExpression = false; +} + +/* +================ +rvGESelectionMgr::Render + +Render the selections including the move/size bars +================ +*/ +void rvGESelectionMgr::Render ( void ) +{ + if ( !mSelections.Num ( ) ) + { + return; + } + + qglEnable(GL_BLEND); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + UpdateRectangle ( ); + + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE ); + + idVec4& color = gApp.GetOptions().GetSelectionColor ( ); + qglColor4f ( color[0],color[1],color[2], 1.0f ); + + qglBegin(GL_LINE_LOOP ); + qglVertex2f ( mRect.x, mRect.y ); + qglVertex2f ( mRect.x + mRect.w, mRect.y ); + qglVertex2f ( mRect.x + mRect.w, mRect.y + mRect.h); + qglVertex2f ( mRect.x, mRect.y + mRect.h); + qglEnd ( ); + + qglColor4f ( color[0],color[1],color[2], 0.75f ); + + int i; + for ( i = 0; i < mSelections.Num(); i ++ ) + { + rvGEWindowWrapper* wrapper; + idRectangle rect; + + wrapper = rvGEWindowWrapper::GetWrapper ( mSelections[i] ); + assert ( wrapper ); + + rect = wrapper->GetScreenRect ( ); + mWorkspace->WorkspaceToWindow ( rect ); + + if ( i == 0 ) + { + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL ); + qglBegin ( GL_TRIANGLES ); + qglVertex2f ( rect.x, rect.y ); + qglVertex2f ( rect.x + GUIED_GRABSIZE, rect.y ); + qglVertex2f ( rect.x, rect.y + GUIED_GRABSIZE ); + qglEnd ( ); + } + + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE ); + qglBegin(GL_LINE_LOOP ); + qglVertex2f ( rect.x, rect.y ); + qglVertex2f ( rect.x + rect.w, rect.y ); + qglVertex2f ( rect.x + rect.w, rect.y + rect.h); + qglVertex2f ( rect.x, rect.y + rect.h); + qglEnd ( ); + + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL ); + qglBegin( GL_QUADS ); + qglVertex2f ( rect.x + (rect.w - GUIED_CENTERSIZE) / 2, rect.y + (rect.h - GUIED_CENTERSIZE) / 2 ); + qglVertex2f ( rect.x + (rect.w + GUIED_CENTERSIZE) / 2, rect.y + (rect.h - GUIED_CENTERSIZE) / 2 ); + qglVertex2f ( rect.x + (rect.w + GUIED_CENTERSIZE) / 2, rect.y + (rect.h + GUIED_CENTERSIZE) / 2 ); + qglVertex2f ( rect.x + (rect.w - GUIED_CENTERSIZE) / 2, rect.y + (rect.h + GUIED_CENTERSIZE) / 2 ); + qglEnd ( ); + } + + if ( mExpression ) + { + return; + } + + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE ); + + qglColor4f ( color[0],color[1],color[2], 1.0f ); + qglBegin(GL_QUADS); + + // Top Left + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x - 1, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x - 1, mRect.y - 1 ); + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y - 1 ); + + // Left + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2); + qglVertex2f ( mRect.x - 1, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2 ); + qglVertex2f ( mRect.x - 1, mRect.y + mRect.h / 2 + GUIED_GRABSIZE / 2 ); + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h / 2 + GUIED_GRABSIZE / 2 ); + + // Bototm Left + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x - 1, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x - 1, mRect.y + mRect.h + GUIED_GRABSIZE ); + qglVertex2f ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h + GUIED_GRABSIZE ); + + // Bottom + qglVertex2f ( mRect.x - GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x + GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x + GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y + mRect.h + GUIED_GRABSIZE ); + qglVertex2f ( mRect.x - GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y + mRect.h + GUIED_GRABSIZE ); + + // Bottom Right + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y + mRect.h + 1 ); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y + mRect.h + GUIED_GRABSIZE ); + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y + mRect.h + GUIED_GRABSIZE ); + + // Right + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2 ); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y + mRect.h / 2 + GUIED_GRABSIZE / 2 ); + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y + mRect.h / 2 + GUIED_GRABSIZE / 2 ); + + // Top Right + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x + mRect.w + GUIED_GRABSIZE, mRect.y - 1 ); + qglVertex2f ( mRect.x + mRect.w + 1, mRect.y - 1 ); + + // Top + qglVertex2f ( mRect.x - GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x + GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y - GUIED_GRABSIZE ); + qglVertex2f ( mRect.x + GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y - 1 ); + qglVertex2f ( mRect.x - GUIED_GRABSIZE / 2 + mRect.w / 2, mRect.y - 1 ); + + qglEnd ( ); + + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL ); +} + +/* +================ +rvGESelectionMgr::UpdateRectangle + +Update the selection rectangle from all the currently selected items. +================ +*/ +void rvGESelectionMgr::UpdateRectangle ( void ) +{ + int i; + idVec2 point; + + assert ( mWorkspace ); + + if ( mSelections.Num ( ) <= 0 ) + { + return; + } + + // Start with the first selections retangle + mRect = rvGEWindowWrapper::GetWrapper( mSelections[0] )->GetScreenRect ( ); + + // Its easier to do the calculates with it being top left and bottom right + // so temporarly convert width and height to right and bottom + mRect.w += mRect.x; + mRect.h += mRect.y; + + // Merge all the rest of the rectangles to make the actual selection rectangle + for ( i = 1; i < mSelections.Num(); i ++ ) + { + idRectangle selRect; + selRect = rvGEWindowWrapper::GetWrapper ( mSelections[i] )->GetScreenRect ( ); + + mRect.w = max(selRect.x+selRect.w,mRect.w); + mRect.h = max(selRect.y+selRect.h,mRect.h); + mRect.x = min(selRect.x,mRect.x); + mRect.y = min(selRect.y,mRect.y); + } + + mRect.w -= mRect.x; + mRect.h -= mRect.y; + + mWorkspace->WorkspaceToWindow ( mRect ); +} + +/* +================ +rvGESelectionMgr::UpdateExpression + +Update whether or not the selection has an expression in it +================ +*/ +void rvGESelectionMgr::UpdateExpression ( void ) +{ + int i; + + mExpression = false; + for ( i = 0; i < mSelections.Num(); i ++ ) + { + rvGEWindowWrapper* wrapper; + wrapper = rvGEWindowWrapper::GetWrapper ( mSelections[i] ); + if ( wrapper && !wrapper->CanMoveAndSize ( ) ) + { + mExpression = true; + break; + } + } +} + +/* +================ +rvGESelectionMgr::HitTest + +Test to see if the given coordinate is within the selection rectangle and if it is +see what its over. +================ +*/ +rvGESelectionMgr::EHitTest rvGESelectionMgr::HitTest ( float x, float y ) +{ + if ( !mSelections.Num ( ) ) + { + return HT_NONE; + } + + UpdateRectangle ( ); + + // Inside the rectangle is moving + if ( mRect.Contains ( x, y ) ) + { + return mExpression?HT_SELECT:HT_MOVE; + } + + if ( mExpression ) + { + return HT_NONE; + } + + // Check for top left sizing + if ( idRectangle ( mRect.x - GUIED_GRABSIZE, mRect.y - GUIED_GRABSIZE, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_TOPLEFT; + } + + // Check for left sizing + if ( idRectangle ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_LEFT; + } + + // Check for bottom left sizing + if ( idRectangle ( mRect.x - GUIED_GRABSIZE, mRect.y + mRect.h, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_BOTTOMLEFT; + } + + // Check for bottom sizing + if ( idRectangle ( mRect.x + mRect.w / 2 - GUIED_GRABSIZE / 2, mRect.y + mRect.h, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_BOTTOM; + } + + // Check for bottom right sizing + if ( idRectangle ( mRect.x + mRect.w, mRect.y + mRect.h, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_BOTTOMRIGHT; + } + + // Check for right sizing + if ( idRectangle ( mRect.x + mRect.w, mRect.y + mRect.h / 2 - GUIED_GRABSIZE / 2, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_RIGHT; + } + + // Check for top right sizing + if ( idRectangle ( mRect.x + mRect.w, mRect.y - GUIED_GRABSIZE, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_TOPRIGHT; + } + + // Check for top sizing + if ( idRectangle ( mRect.x + mRect.w / 2 - GUIED_GRABSIZE / 2, mRect.y - GUIED_GRABSIZE, GUIED_GRABSIZE, GUIED_GRABSIZE ).Contains ( x, y ) ) + { + return HT_SIZE_TOP; + } + + return HT_NONE; +} + +/* +================ +rvGESelectionMgr::GetBottomMost + +Returns the bottom most selected window. +================ +*/ +idWindow* rvGESelectionMgr::GetBottomMost ( void ) +{ + idWindow* bottom; + int depth; + int i; + + depth = 9999; + bottom = NULL; + + // Loop through all the selections and find the bottom most window + for ( i = 0; i < mSelections.Num(); i ++ ) + { + idWindow* parent; + int tempDepth; + + // Calculate the depth of the window by iterating back through the windows parents + for ( tempDepth = 0, parent = mSelections[i]; parent; parent = parent->GetParent ( ), tempDepth++ ); + + // If the new depth is less than the current depth then this window is below + if ( tempDepth < depth ) + { + depth = tempDepth; + bottom = mSelections[i]; + } + } + + return bottom; +} diff --git a/tools/guied/GESelectionMgr.h b/tools/guied/GESelectionMgr.h new file mode 100644 index 000000000..1b28ceb34 --- /dev/null +++ b/tools/guied/GESelectionMgr.h @@ -0,0 +1,112 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GESELECTIONMGR_H_ +#define GESELECTIONMGR_H_ + +class rvGEWorkspace; + +class rvGESelectionMgr +{ +public: + + enum EHitTest + { + HT_NONE, + HT_SELECT, + HT_MOVE, + HT_SIZE_TOPLEFT, + HT_SIZE_TOP, + HT_SIZE_TOPRIGHT, + HT_SIZE_RIGHT, + HT_SIZE_BOTTOMRIGHT, + HT_SIZE_BOTTOM, + HT_SIZE_BOTTOMLEFT, + HT_SIZE_LEFT + }; + + rvGESelectionMgr ( ); + + void SetWorkspace ( rvGEWorkspace* workspace ); + + void Set ( idWindow* ); + void Add ( idWindow* window, bool expand = true ); + void Remove ( idWindow* ); + void Clear ( void ); + + int Num ( void ); + + void Render ( void ); + + EHitTest HitTest ( float x, float y ); + + bool IsSelected ( idWindow* window ); + bool IsExpression ( void ); + + idRectangle& GetRect ( void ); + idWindow* GetBottomMost ( void ); + + idWindow*& operator[]( int index ); + +protected: + + void UpdateRectangle ( void ); + void UpdateExpression ( void ); + + idList mSelections; + idRectangle mRect; + rvGEWorkspace* mWorkspace; + bool mExpression; +}; + +ID_INLINE int rvGESelectionMgr::Num ( void ) +{ + return mSelections.Num ( ); +} + +ID_INLINE idWindow*& rvGESelectionMgr::operator[]( int index ) +{ + assert( index >= 0 ); + assert( index < mSelections.Num() ); + + return mSelections[ index ]; +} + +ID_INLINE void rvGESelectionMgr::SetWorkspace ( rvGEWorkspace* workspace ) +{ + mWorkspace = workspace; +} + +ID_INLINE idRectangle& rvGESelectionMgr::GetRect ( void ) +{ + UpdateRectangle ( ); + return mRect; +} + +ID_INLINE bool rvGESelectionMgr::IsSelected ( idWindow* window ) +{ + return mSelections.FindIndex ( window ) != -1 ? true : false; +} + +ID_INLINE bool rvGESelectionMgr::IsExpression ( void ) +{ + return mExpression; +} + +#endif // GESELECTIONMGR_H_ diff --git a/tools/guied/GESizeModifier.cpp b/tools/guied/GESizeModifier.cpp new file mode 100644 index 000000000..6194f242b --- /dev/null +++ b/tools/guied/GESizeModifier.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GESizeModifier.h" + +rvGESizeModifier::rvGESizeModifier ( const char* name, idWindow* window, float l, float t, float r, float b ) : + rvGEModifier ( name, window ) +{ + mOldRect = mWrapper->GetClientRect ( ); + + mNewRect[0] = mOldRect[0] + l; + mNewRect[1] = mOldRect[1] + t; + mNewRect[2] = mOldRect[2] + r - l; + mNewRect[3] = mOldRect[3] + b - t; +} + +bool rvGESizeModifier::Merge ( rvGEModifier* mergebase ) +{ + rvGESizeModifier* merge = (rvGESizeModifier*) mergebase; + + mNewRect = merge->mNewRect; + + return true; +} + +bool rvGESizeModifier::Apply ( void ) +{ + mWrapper->SetRect ( mNewRect ); + + return true; +} + +bool rvGESizeModifier::Undo ( void ) +{ + mWrapper->SetRect ( mOldRect ); + + return true; +} + +bool rvGESizeModifier::IsValid ( void ) +{ + if ( !mWindow->GetParent ( ) ) + { + return false; + } + + return true; +} diff --git a/tools/guied/GESizeModifier.h b/tools/guied/GESizeModifier.h new file mode 100644 index 000000000..9c32c46eb --- /dev/null +++ b/tools/guied/GESizeModifier.h @@ -0,0 +1,47 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GESIZEMODIFIER_H_ +#define GESIZEMODIFIER_H_ + +class rvGESizeModifier : public rvGEModifier +{ +public: + + rvGESizeModifier ( const char* name, idWindow* window, float l, float t, float r, float b ); + + virtual bool CanMerge ( rvGEModifier* merge ); + virtual bool Merge ( rvGEModifier* merge ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + + virtual bool IsValid ( void ); + +protected: + + idRectangle mNewRect; + idRectangle mOldRect; +}; + +ID_INLINE bool rvGESizeModifier::CanMerge ( rvGEModifier* merge ) +{ + return true; +} + +#endif // GESIZEMODIFIER_H_ diff --git a/tools/guied/GEStateModifier.cpp b/tools/guied/GEStateModifier.cpp new file mode 100644 index 000000000..0245f3b06 --- /dev/null +++ b/tools/guied/GEStateModifier.cpp @@ -0,0 +1,86 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEStateModifier.h" + +rvGEStateModifier::rvGEStateModifier ( const char* name, idWindow* window, idDict& dict ) : + rvGEModifier ( name, window ), + mDict ( dict ) +{ + mDict.Copy ( dict ); + + // Make a copy of the current dictionary + mUndoDict.Copy ( mWrapper->GetStateDict() ); +} + +/* +================ +rvGEStateModifier::Apply + +Applys the new state dictionary to the window +================ +*/ +bool rvGEStateModifier::Apply ( void ) +{ + return SetState ( mDict ); +} + +/* +================ +rvGEStateModifier::Undo + +Applies the undo dictionary to the window +================ +*/ +bool rvGEStateModifier::Undo ( void ) +{ + return SetState ( mUndoDict ); +} + +/* +================ +rvGEStateModifier::Apply + +Applys the given dictionary to the window +================ +*/ +bool rvGEStateModifier::SetState ( idDict& dict ) +{ + const idKeyValue* key; + int i; + + // Delete any key thats gone in the new dict + for ( i = 0; i < mWrapper->GetStateDict().GetNumKeyVals(); i ++ ) + { + key = mWrapper->GetStateDict().GetKeyVal ( i ); + if ( !key ) + { + continue; + } + } + + mWrapper->SetState ( dict ); + + return true; +} + diff --git a/tools/guied/GEStateModifier.h b/tools/guied/GEStateModifier.h new file mode 100644 index 000000000..b7418b720 --- /dev/null +++ b/tools/guied/GEStateModifier.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GESTATEMODIFIER_H_ +#define GESTATEMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEStateModifier : public rvGEModifier +{ +public: + + rvGEStateModifier ( const char* name, idWindow* window, idDict& dict ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + +protected: + + bool SetState ( idDict& dict ); + + rvGEWindowWrapper::EWindowType mWindowType; + rvGEWindowWrapper::EWindowType mUndoWindowType; + idDict mDict; + idDict mUndoDict; +}; + +#endif // GESTATEMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/GEStatusBar.cpp b/tools/guied/GEStatusBar.cpp new file mode 100644 index 000000000..766bd742e --- /dev/null +++ b/tools/guied/GEStatusBar.cpp @@ -0,0 +1,119 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" + +rvGEStatusBar::rvGEStatusBar ( ) +{ + mSimple = true; + mZoom = 0; + mTriangles = 0; +} + +/* +================ +rvGEStatusBar::Create + +Creates a new status bar +================ +*/ +bool rvGEStatusBar::Create ( HWND parent, UINT id, bool visible ) +{ + mWnd = CreateStatusWindow ( WS_CHILD|WS_VISIBLE|WS_BORDER, "", parent, id ); + + if ( !mWnd ) + { + return false; + } + + Show ( visible ); + + return true; +} + +/* +================ +rvGEStatusBar::Resize + +Resizes the status bar and updates the content +================ +*/ +void rvGEStatusBar::Resize ( int width, int height ) +{ + SendMessage ( mWnd, WM_SIZE, 0, MAKELONG(width,height) ); + + Update ( ); +} + +/* +================ +rvGEStatusBar::Update + +Updates the status bar by setting up each part's width and text +================ +*/ +void rvGEStatusBar::Update ( void ) +{ + RECT rStatus; + SIZE zoomSize; + SIZE trisSize; + int parts[5]; + + GetWindowRect ( mWnd, &rStatus ); + + if ( mSimple ) + { + parts[0] = -1; + + SendMessage ( mWnd, SB_SETPARTS, 1, (LONG)parts ); + SendMessage ( mWnd, SB_SETTEXT, 1, (LPARAM) "" ); + } + else + { + zoomSize.cx = 85; + trisSize.cx = 65; + + parts[0] = (rStatus.right - rStatus.left) - zoomSize.cx - trisSize.cx - 40; + parts[1] = parts[0] + trisSize.cx; + parts[2] = parts[1] + zoomSize.cx; + parts[3] = parts[2] + 40; + parts[4] = -1; + + SendMessage ( mWnd, SB_SETPARTS, 5, (LONG)parts ); + SendMessage ( mWnd, SB_SETTEXT, 0, (LPARAM) "" ); + SendMessage ( mWnd, SB_SETTEXT, 1, (LPARAM) va(" Tris: %d", mTriangles ) ); + SendMessage ( mWnd, SB_SETTEXT, 2, (LPARAM) va(" Zoom: %d%%", mZoom ) ); + } +} + +/* +================ +rvGEStatusBar::Show + +Shows and hides the status bar +================ +*/ +void rvGEStatusBar::Show ( bool visible ) +{ + gApp.GetOptions().SetStatusBarVisible ( visible ); + ShowWindow ( mWnd, visible?SW_SHOW:SW_HIDE ); +} diff --git a/tools/guied/GEStatusBar.h b/tools/guied/GEStatusBar.h new file mode 100644 index 000000000..4b40c9686 --- /dev/null +++ b/tools/guied/GEStatusBar.h @@ -0,0 +1,80 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GESTATUSBAR_H_ +#define GESTATUSBAR_H_ + +class rvGEStatusBar +{ +public: + + rvGEStatusBar ( ); + + bool Create ( HWND parent, UINT id, bool visible = true ); + void Resize ( int width, int height ); + + HWND GetWindow ( void ); + + void SetZoom ( int zoom ); + void SetTriangles ( int tris ); + void SetSimple ( bool simple ); + + void Show ( bool state ); + void Update ( void ); + +protected: + + HWND mWnd; + bool mSimple; + int mZoom; + int mTriangles; +}; + +ID_INLINE HWND rvGEStatusBar::GetWindow ( void ) +{ + return mWnd; +} + +ID_INLINE void rvGEStatusBar::SetZoom ( int zoom ) +{ + if ( mZoom != zoom ) + { + mZoom = zoom; + Update ( ); + } +} + +ID_INLINE void rvGEStatusBar::SetTriangles ( int triangles ) +{ + if ( triangles != mTriangles ) + { + mTriangles = triangles; + Update ( ); + } +} + +ID_INLINE void rvGEStatusBar::SetSimple ( bool simple ) +{ + if ( mSimple != simple ) + { + mSimple = simple; + Update ( ); + } +} + +#endif // GESTATUSBAR_H_ \ No newline at end of file diff --git a/tools/guied/GETransformer.cpp b/tools/guied/GETransformer.cpp new file mode 100644 index 000000000..608bdfe98 --- /dev/null +++ b/tools/guied/GETransformer.cpp @@ -0,0 +1,336 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" +#include "../common/MaskEdit.h" + +HHOOK gTransHook = NULL; +HWND gTransDlg = NULL; + +rvGETransformer::rvGETransformer ( ) +{ + mWnd = NULL; + mWorkspace = NULL; +} + +bool rvGETransformer::Create ( HWND parent, bool visible ) +{ + WNDCLASSEX wndClass; + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "GUIEDITOR_TRANSFORMER_CLASS"; + wndClass.lpfnWndProc = rvGETransformer::WndProc; + wndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH );; + wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); + wndClass.lpszMenuName = NULL; + wndClass.hInstance = win32.hInstance; + RegisterClassEx ( &wndClass ); + + mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW, + "GUIEDITOR_TRANSFORMER_CLASS", + "Transformer", + WS_SYSMENU|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD, + 0, 0, 200,100, + parent, + NULL, + win32.hInstance, + this ); + + if ( !mWnd ) + { + return false; + } + + if ( !gApp.GetOptions().GetWindowPlacement ( "transformer", mWnd ) ) + { + RECT rParent; + RECT rTrans; + + GetWindowRect ( parent, &rParent ); + GetWindowRect ( mWnd, &rTrans ); + SetWindowPos ( mWnd, NULL, + rParent.right - 10 - (rTrans.right-rTrans.left), + rParent.bottom - 10 - (rTrans.bottom-rTrans.top), + 0,0, + SWP_NOZORDER|SWP_NOSIZE ); + } + + Show ( visible ); + + return true; +} + +LRESULT CALLBACK rvGETransformer::WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGETransformer* trans = (rvGETransformer*) GetWindowLong ( hWnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_NCACTIVATE: + return gApp.ToolWindowActivate ( hWnd, msg, wParam, lParam ); + + case WM_ACTIVATE: + common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE ); + break; + + case WM_DESTROY: + gApp.GetOptions().SetWindowPlacement ( "transformer", hWnd ); + break; + + case WM_ERASEBKGND: + return TRUE; + + case WM_CREATE: + { + LPCREATESTRUCT cs; + + // Attach the class to the window first + cs = (LPCREATESTRUCT) lParam; + trans = (rvGETransformer*) cs->lpCreateParams; + SetWindowLong ( hWnd, GWL_USERDATA, (LONG)trans ); + + trans->mWnd = hWnd; + trans->mDlg = CreateDialogParam ( gApp.GetInstance(), MAKEINTRESOURCE(IDD_GUIED_TRANSFORMER), + hWnd, DlgProc, (LPARAM)trans ); + + RECT rDlg; + RECT rWindow; + RECT rClient; + + GetWindowRect ( trans->mWnd, &rWindow ); + GetClientRect ( trans->mWnd, &rClient ); + GetWindowRect ( trans->mDlg, &rDlg ); + + SetWindowPos ( trans->mWnd, NULL, 0, 0, + (rWindow.right-rWindow.left)-(rClient.right-rClient.left) + (rDlg.right-rDlg.left), + (rWindow.bottom-rWindow.top)-(rClient.bottom-rClient.top) + (rDlg.bottom-rDlg.top), + SWP_NOZORDER ); + + ShowWindow ( trans->mDlg, SW_SHOW ); + UpdateWindow ( trans->mDlg ); + + break; + } + } + + return DefWindowProc ( hWnd, msg, wParam, lParam ); +} + +INT_PTR CALLBACK rvGETransformer::DlgProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGETransformer* trans = (rvGETransformer*) GetWindowLong ( hWnd, GWL_USERDATA ); + + switch ( msg ) + { + case WM_DESTROY: + if ( gTransHook ) + { + UnhookWindowsHookEx( gTransHook ); + } + gTransDlg = NULL; + break; + + case WM_INITDIALOG: + trans = (rvGETransformer*) lParam; + trans->mDlg = hWnd; + SetWindowLong ( hWnd, GWL_USERDATA, lParam ); + NumberEdit_Attach ( GetDlgItem ( hWnd, IDC_GUIED_ITEMRECTX ) ); + NumberEdit_Attach ( GetDlgItem ( hWnd, IDC_GUIED_ITEMRECTY ) ); + NumberEdit_Attach ( GetDlgItem ( hWnd, IDC_GUIED_ITEMRECTW ) ); + NumberEdit_Attach ( GetDlgItem ( hWnd, IDC_GUIED_ITEMRECTH ) ); + gTransDlg = hWnd; + gTransHook = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId() ); + break; + + case WM_COMMAND: + if ( LOWORD ( wParam ) == IDOK ) + { + SendMessage ( hWnd, WM_NEXTDLGCTL, 0, 0 ); + } + else if ( HIWORD ( wParam ) == EN_KILLFOCUS && trans && trans->mWorkspace ) + { + char temp[64]; + int value; + GetWindowText ( GetDlgItem ( hWnd, LOWORD(wParam) ), temp, 64 ); + value = atoi ( temp ); + + idRectangle rect = trans->mWorkspace->GetSelectionMgr().GetRect ( ); + trans->mWorkspace->WindowToWorkspace ( rect ); + + // The transformer coords are relative to the botto most selected window's parent so + // adjust the rect accordingly + if ( trans->mRelative ) + { + idRectangle& screenRect = rvGEWindowWrapper::GetWrapper ( trans->mRelative )->GetScreenRect ( ); + rect.x -= screenRect.x; + rect.y -= screenRect.y; + } + + switch ( LOWORD ( wParam ) ) + { + case IDC_GUIED_ITEMRECTX: + if ( value - rect[0] ) + { + trans->mWorkspace->AddModifierMove ( "Transform Move", value - rect[0], 0, false ); + } + break; + + case IDC_GUIED_ITEMRECTY: + if ( value - rect[1] ) + { + trans->mWorkspace->AddModifierMove ( "Transform Move", 0, value - rect[1], false ); + } + break; + + case IDC_GUIED_ITEMRECTW: + if ( value - rect[2] ) + { + trans->mWorkspace->AddModifierSize ( "Transform Size", 0, 0, value - rect[2], 0, false ); + } + break; + + case IDC_GUIED_ITEMRECTH: + if ( value - rect[3] ) + { + trans->mWorkspace->AddModifierSize ( "Transform Size", 0, 0, 0, value - rect[3], false ); + } + break; + } + } + break; + } + + return FALSE; +} + +/* +================ +rvGETransformer::Show + +Shows and hides the transformer window +================ +*/ +void rvGETransformer::Show ( bool visible ) +{ + gApp.GetOptions().SetTransformerVisible ( visible ); + ShowWindow ( mWnd, visible?SW_SHOW:SW_HIDE ); + Update ( ); +} + +/* +================ +rvGETransformer::SetWorkspace + +Sets a new workspace for the transformer window +================ +*/ +void rvGETransformer::SetWorkspace ( rvGEWorkspace* workspace ) +{ + mWorkspace = workspace; + + Update ( ); +} + +/* +================ +rvGETransformer::Update + +Update the enabled/disabled states based on the selections and update +the rectangle coordinates +================ +*/ +void rvGETransformer::Update ( void ) +{ + bool state = false; + + mRelative = NULL; + + if ( mWorkspace && mWorkspace->GetSelectionMgr ( ).Num ( ) ) + { + state = true; + mRelative = mWorkspace->GetSelectionMgr().GetBottomMost ( ); + mRelative = mRelative->GetParent ( ); + + idRectangle rect = mWorkspace->GetSelectionMgr ( ).GetRect ( ); + mWorkspace->WindowToWorkspace ( rect ); + + // Make the rectangle relative to the given parent + if ( mRelative ) + { + idRectangle& screenRect = rvGEWindowWrapper::GetWrapper ( mRelative )->GetScreenRect ( ); + rect.x -= screenRect.x; + rect.y -= screenRect.y; + } + + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTX ), va("%d",(int)rect[0]) ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTY ), va("%d",(int)rect[1]) ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTW ), va("%d",(int)rect[2]) ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTH ), va("%d",(int)rect[3]) ); + } + + if ( !state ) + { + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTX ), "" ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTY ), "" ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTW ), "" ); + SetWindowText ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTH ), "" ); + } + + EnableWindow ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTX ), state ); + EnableWindow ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTY ), state ); + EnableWindow ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTW ), state ); + EnableWindow ( GetDlgItem ( mDlg, IDC_GUIED_ITEMRECTH ), state ); +} + +/* +================ +rvGETransformer::GetMsgProc + +Ensures normal dialog functions work in the transformer dialog +================ +*/ +LRESULT FAR PASCAL rvGETransformer::GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam ) +{ + LPMSG lpMsg = (LPMSG) lParam; + + if ( nCode >= 0 && PM_REMOVE == wParam ) + { + // Don't translate non-input events. + if ( lpMsg->message != WM_SYSCHAR && (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) ) + { + if ( IsDialogMessage( gTransDlg, lpMsg) ) + { + // The value returned from this hookproc is ignored, + // and it cannot be used to tell Windows the message has been handled. + // To avoid further processing, convert the message to WM_NULL + // before returning. + lpMsg->message = WM_NULL; + lpMsg->lParam = 0; + lpMsg->wParam = 0; + } + } + } + + return CallNextHookEx(gTransHook, nCode, wParam, lParam); +} diff --git a/tools/guied/GETransformer.h b/tools/guied/GETransformer.h new file mode 100644 index 000000000..f373820e0 --- /dev/null +++ b/tools/guied/GETransformer.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GETRANSFORMER_H_ +#define GETRANSFORMER_H_ + +class rvGETransformer +{ +public: + + rvGETransformer ( ); + + bool Create ( HWND parent, bool visible ); + void Show ( bool show ); + + void SetWorkspace ( rvGEWorkspace* workspace ); + void Update ( void ); + + HWND GetWindow ( void ); + +protected: + + HWND mWnd; + HWND mDlg; + rvGEWorkspace* mWorkspace; + idWindow* mRelative; + +private: + + static LRESULT CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); + static INT_PTR CALLBACK DlgProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); + static LRESULT FAR PASCAL GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam ); +}; + +ID_INLINE HWND rvGETransformer::GetWindow ( void ) +{ + return mWnd; +} + +#endif // GETRANSFORMER_H_ \ No newline at end of file diff --git a/tools/guied/GEViewer.cpp b/tools/guied/GEViewer.cpp new file mode 100644 index 000000000..a1b0057f8 --- /dev/null +++ b/tools/guied/GEViewer.cpp @@ -0,0 +1,542 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" +#include "../../renderer/tr_local.h" + +#include "GEApp.h" +#include "GEViewer.h" + +rvGEViewer::rvGEViewer ( ) +{ + mInterface = NULL; + mPaused = true; + mTime = 0; +} + +bool rvGEViewer::Create ( HWND parent ) +{ + WNDCLASSEX wndClass; + + // Make sure the alpha slider window class is registered + memset ( &wndClass, 0, sizeof(wndClass) ); + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = "GUIED_VIEWER"; + wndClass.lpfnWndProc = rvGEViewer::WndProc; + wndClass.hInstance = gApp.GetInstance ( ); + wndClass.style = CS_OWNDC|CS_BYTEALIGNWINDOW|CS_VREDRAW|CS_HREDRAW; + wndClass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1); + RegisterClassEx ( &wndClass ); + + mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW, "GUIED_VIEWER", "GUI Viewer", + WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD, + CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, + parent, NULL, gApp.GetInstance(), this ); + + gApp.GetOptions().GetWindowPlacement ( "viewer", mWnd ); + + + ShowWindow ( mWnd, SW_SHOW ); + UpdateWindow ( mWnd ); + + return true; +} + +void rvGEViewer::Play ( void ) +{ + if ( !mPaused ) + { + return; + } + + mLastTime = eventLoop->Milliseconds(); + mPaused = false; + + TBBUTTONINFO tbinfo; + tbinfo.cbSize = sizeof(TBBUTTONINFO); + tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE; + tbinfo.iImage = 1; + tbinfo.idCommand = ID_GUIED_VIEWER_PAUSE; + SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PLAY, (LPARAM)&tbinfo ); +} + +void rvGEViewer::Pause ( void ) +{ + if ( mPaused ) + { + return; + } + + mPaused = true; + + TBBUTTONINFO tbinfo; + tbinfo.cbSize = sizeof(TBBUTTONINFO); + tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE; + tbinfo.iImage = 0; + tbinfo.idCommand = ID_GUIED_VIEWER_PLAY; + SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PAUSE, (LPARAM)&tbinfo ); +} + + +bool rvGEViewer::Destroy ( void ) +{ + gApp.GetOptions().SetWindowPlacement ( "viewer", mWnd ); + + DestroyWindow ( mWnd ); + return true; +} + +bool rvGEViewer::OpenFile ( const char* filename ) +{ + idStr tempfile; + idStr ospath; + + delete mInterface; + + tempfile = filename; + tempfile.StripPath (); + tempfile.StripFileExtension ( ); + tempfile = va("guis/temp.guied", tempfile.c_str() ); + ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" ); + + // Make sure the gui directory exists + idStr createDir = ospath; + createDir.StripFilename ( ); + CreateDirectory ( createDir, NULL ); + + SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL ); + DeleteFile ( ospath ); + CopyFile ( filename, ospath, FALSE ); + SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL ); + + mInterface = reinterpret_cast< idUserInterfaceLocal* >( uiManager->FindGui( tempfile, true, true ) ); + + mInterface->SetStateString( "guied_item_0", "guied 1" ); + mInterface->SetStateString( "guied_item_1", "guied 2" ); + mInterface->SetStateString( "guied_item_2", "guied 3" ); + + mTime = 0; + + mInterface->Activate ( true, mTime ); + + DeleteFile ( ospath ); + + Play ( ); + + return true; +} + +/* +======= +MapKey + +Map from windows to Doom keynums +======= +*/ +static int MapKey (int key) +{ + int result; + int modified; + bool is_extended; + + modified = ( key >> 16 ) & 255; + + if ( modified > 127 ) + return 0; + + if ( key & ( 1 << 24 ) ) { + is_extended = true; + } + else { + is_extended = false; + } + + const unsigned char *scanToKey = Sys_GetScanTable(); + result = scanToKey[modified]; + + // common->Printf( "Key: 0x%08x Modified: 0x%02x Extended: %s Result: 0x%02x\n", key, modified, (is_extended?"Y":"N"), result); + + if ( is_extended ) { + switch ( result ) + { + case K_PAUSE: + return K_KP_NUMLOCK; + case 0x0D: + return K_KP_ENTER; + case 0x2F: + return K_KP_SLASH; + case 0xAF: + return K_KP_PLUS; + } + } + else { + switch ( result ) + { + case K_HOME: + return K_KP_HOME; + case K_UPARROW: + return K_KP_UPARROW; + case K_PGUP: + return K_KP_PGUP; + case K_LEFTARROW: + return K_KP_LEFTARROW; + case K_RIGHTARROW: + return K_KP_RIGHTARROW; + case K_END: + return K_KP_END; + case K_DOWNARROW: + return K_KP_DOWNARROW; + case K_PGDN: + return K_KP_PGDN; + case K_INS: + return K_KP_INS; + case K_DEL: + return K_KP_DEL; + } + } + + return result; +} + +LRESULT CALLBACK rvGEViewer::WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + rvGEViewer* viewer = (rvGEViewer*) GetWindowLong ( hwnd, GWL_USERDATA ); + + switch ( msg ) + { + + case WM_COMMAND: + switch ( LOWORD(wParam) ) + { + case ID_GUIED_VIEWER_PLAY: + viewer->Play ( ); + break; + + case ID_GUIED_VIEWER_PAUSE: + viewer->Pause ( ); + break; + } + break; + + case WM_SIZE: + { + RECT rToolbar; + SendMessage ( viewer->mToolbar, TB_AUTOSIZE, 0, 0 ); + GetWindowRect ( viewer->mToolbar, &rToolbar ); + viewer->mToolbarHeight = rToolbar.bottom - rToolbar.top; + break; + } + + case WM_ACTIVATE: + common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE ); + break; + + case WM_ERASEBKGND: + return TRUE; + + case WM_PAINT: + assert ( viewer ); + viewer->HandlePaint ( wParam, lParam ); + break; + + case WM_LBUTTONDOWN: + if ( viewer->mInterface ) + { + sysEvent_t event; + bool visuals; + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_KEY; + event.evValue = K_MOUSE1; + event.evValue2 = true; + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_LBUTTONUP: + if ( viewer->mInterface ) + { + sysEvent_t event; + bool visuals; + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_KEY; + event.evValue = K_MOUSE1; + event.evValue2 = false; + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_KEYDOWN: + if ( viewer->mInterface ) + { + sysEvent_t event; + bool visuals; + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_KEY; + event.evValue = MapKey( lParam ); + event.evValue2 = true; + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + if ( viewer->mInterface ) + { + sysEvent_t event; + bool visuals; + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_KEY; + event.evValue = MapKey( lParam ); + event.evValue2 = false; + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_CHAR: + + if ( wParam == VK_ESCAPE ) + { + SendMessage ( hwnd, WM_CLOSE, 0, 0 ); + break; + } + + if ( viewer->mInterface ) + { + sysEvent_t event; + bool visuals; + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_CHAR; + event.evValue = wParam; + event.evValue2 = false; + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_MOUSEMOVE: + if ( viewer->mInterface ) + { + float x = (float)(LOWORD(lParam)) / (float)viewer->mWindowWidth * SCREEN_WIDTH; + float y = (float)(HIWORD(lParam)) / (float)(viewer->mWindowHeight - viewer->mToolbarHeight) * SCREEN_HEIGHT; + sysEvent_t event; + bool visuals; + + ZeroMemory ( &event, sizeof(event) ) ; + event.evType = SE_MOUSE; + event.evValue = (int)x - viewer->mInterface->CursorX(); + event.evValue2 = (int)y - viewer->mInterface->CursorY(); + viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals ); + } + break; + + case WM_CLOSE: + viewer->mInterface = NULL; + gApp.CloseViewer ( ); + return 0; + + case WM_CREATE: + { + CREATESTRUCT* cs = (CREATESTRUCT*) lParam; + SetWindowLong ( hwnd, GWL_USERDATA, (LONG)cs->lpCreateParams ); + + viewer = (rvGEViewer*)cs->lpCreateParams; + viewer->mWnd = hwnd; + viewer->SetupPixelFormat ( ); + + viewer->mToolbar = CreateWindowEx ( 0, TOOLBARCLASSNAME, "", CCS_BOTTOM|WS_CHILD|WS_VISIBLE,0,0,0,0, hwnd, (HMENU)IDR_GUIED_VIEWERTOOLBAR, gApp.GetInstance(), NULL ); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility. + SendMessage( viewer->mToolbar, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 ); + + SendMessage ( viewer->mToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(16,15) ); + + SendMessage ( viewer->mToolbar, TB_SETSTYLE, 0, SendMessage ( viewer->mToolbar, TB_GETSTYLE, 0, 0 ) | TBSTYLE_FLAT ); + + TBMETRICS tbmet; + tbmet.cbSize = sizeof(TBMETRICS); + SendMessage ( viewer->mToolbar, TB_GETMETRICS, 0, (LPARAM)&tbmet ); + tbmet.cyPad = 0; + tbmet.cyBarPad = 0; + SendMessage ( viewer->mToolbar, TB_SETMETRICS, 0, (LPARAM)&tbmet ); + + // Add the bitmap containing button images to the toolbar. + TBADDBITMAP tbab; + tbab.hInst = win32.hInstance; + tbab.nID = IDR_GUIED_VIEWERTOOLBAR; + SendMessage( viewer->mToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab ); + + TBBUTTON tbb[4]; + tbb[0].fsStyle = BTNS_SEP; + tbb[0].fsState = 0; + + tbb[1].idCommand = ID_GUIED_VIEWER_START; + tbb[1].iBitmap = 2; + tbb[1].fsState = 0; + tbb[1].fsStyle = BTNS_BUTTON; + tbb[1].dwData = 0; + tbb[1].iString = -1; + + tbb[2].idCommand = ID_GUIED_VIEWER_PAUSE; + tbb[2].iBitmap = 1; + tbb[2].fsState = TBSTATE_ENABLED; + tbb[2].fsStyle = BTNS_BUTTON; + tbb[2].dwData = 0; + tbb[2].iString = -1; + + tbb[3].fsStyle = BTNS_SEP; + tbb[3].fsState = 0; + + SendMessage( viewer->mToolbar, TB_ADDBUTTONS, (WPARAM)4, (LPARAM) &tbb ); + + break; + } + + case WM_SETCURSOR: + SetCursor ( NULL ); + break; + } + + return DefWindowProc ( hwnd, msg, wParam, lParam ); +} + +LRESULT rvGEViewer::HandlePaint ( WPARAM wParam, LPARAM lParam ) +{ + HDC dc; + PAINTSTRUCT ps; + + dc = BeginPaint ( mWnd, &ps ); + + Render ( dc ); + + EndPaint ( mWnd, &ps ); + + return 1; +} + +/* +================ +rvGEViewer::SetupPixelFormat + +Setup the pixel format for the opengl context +================ +*/ +bool rvGEViewer::SetupPixelFormat ( void ) +{ + HDC hDC = GetDC ( mWnd ); + bool result = true; + + int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + if (pixelFormat > 0) + { + if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) + { + result = false; + } + } + else + { + result = false; + } + + ReleaseDC ( mWnd, hDC ); + + return result; +} + +void rvGEViewer::Render ( HDC dc ) +{ + int frontEnd; + int backEnd; + + // Switch GL contexts to our dc + if (!qwglMakeCurrent( dc, win32.hGLRC )) + { + common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError()); + common->Printf("Please restart Q3Radiant if the Map view is not working\n"); + return; + } + + if ( !mPaused ) + { + mTime += eventLoop->Milliseconds() - mLastTime; + mLastTime = eventLoop->Milliseconds(); + } + + RECT rClient; + RECT rToolbar; + GetClientRect ( mWnd, &rClient ); + GetClientRect ( mToolbar, &rToolbar ); + mWindowWidth = rClient.right - rClient.left; + mWindowHeight = rClient.bottom - rClient.top; + + qglViewport(0, 0, mWindowWidth, mWindowHeight ); + qglScissor(0, 0, mWindowWidth, mWindowHeight ); + qglClearColor ( 0, 0, 0, 0 ); + + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_CULL_FACE); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Render the workspace below + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if ( mInterface ) + { + viewDef_t viewDef; + memset ( &viewDef, 0, sizeof(viewDef) ); + tr.viewDef = &viewDef; + viewDef.renderView.x = 0; + viewDef.renderView.y = mToolbarHeight; + viewDef.renderView.width = mWindowWidth; + viewDef.renderView.height = mWindowHeight - mToolbarHeight; + viewDef.scissor.x1 = 0; + viewDef.scissor.y1 = 0; // (rToolbar.bottom-rToolbar.top); + viewDef.scissor.x2 = mWindowWidth; + viewDef.scissor.y2 = mWindowHeight; + viewDef.isEditor = true; + + // Prepare the renderSystem view to draw the GUI in + renderSystem->BeginFrame(mWindowWidth, mWindowHeight ); + + // Draw the gui + mInterface->Redraw ( mTime ); + + // We are done using the renderSystem now + renderSystem->EndFrame( &frontEnd, &backEnd ); + } + + qglFinish ( ); + qwglSwapBuffers(dc); +} + +void rvGEViewer::RunFrame ( void ) +{ + if ( !mPaused ) + { + HDC hDC = GetDC ( mWnd ); + Render ( hDC ); + ReleaseDC ( mWnd, hDC ); + } +} diff --git a/tools/guied/GEViewer.h b/tools/guied/GEViewer.h new file mode 100644 index 000000000..563a62a8c --- /dev/null +++ b/tools/guied/GEViewer.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEVIEWER_H_ +#define GEVIEWER_H_ + +class rvGEViewer +{ +public: + + rvGEViewer ( ); + + bool Create ( HWND parent ); + bool Destroy ( void ); + bool OpenFile ( const char* filename ); + + void RunFrame ( void ); + + HWND GetWindow ( void ); + +protected: + + void Render ( HDC dc ); + void Play ( void ); + void Pause ( void ); + + HWND mWnd; + int mWindowWidth; + int mWindowHeight; + int mToolbarHeight; + idUserInterfaceLocal* mInterface; + bool mPaused; + HWND mToolbar; + int mLastTime; + int mTime; + + LRESULT HandlePaint ( WPARAM wParam, LPARAM lParam ); + +private: + + bool SetupPixelFormat ( void ); + + static LRESULT CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); +}; + +ID_INLINE HWND rvGEViewer::GetWindow ( void ) +{ + return mWnd; +} + +#endif // GEVIEWER_H_ \ No newline at end of file diff --git a/tools/guied/GEWindowWrapper.cpp b/tools/guied/GEWindowWrapper.cpp new file mode 100644 index 000000000..f7266025c --- /dev/null +++ b/tools/guied/GEWindowWrapper.cpp @@ -0,0 +1,581 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" +#include "../../renderer/tr_local.h" +#include "../../ui/EditWindow.h" +#include "../../ui/ListWindow.h" +#include "../../ui/BindWindow.h" +#include "../../ui/RenderWindow.h" +#include "../../ui/ChoiceWindow.h" + +#include "GEApp.h" + +rvGEWindowWrapper::rvGEWindowWrapper( idWindow *window,EWindowType type ) { + assert(window); + + mWindow = window; + mFlippedHorz = false; + mFlippedVert = false; + mHidden = false; + mDeleted = false; + mSelected = false; + mType = type; + mExpanded = false; + mOldVisible = false; + mMoveable = true; + + if ( dynamic_cast< idEditWindow*>(window) ) { + mType = WT_EDIT; + } else if ( dynamic_cast< idListWindow*>(window) ) { + mType = WT_LIST; + } else if ( dynamic_cast< idBindWindow*>(window) ) { + mType = WT_BIND; + } else if ( dynamic_cast< idRenderWindow*>(window) ) { + mType = WT_RENDER; + } else if ( dynamic_cast< idChoiceWindow*>(window) ) { + mType = WT_CHOICE; + } else { + mType = WT_NORMAL; + } + + // Attach the wrapper to the window by adding a defined variable + // with the wrappers pointer stuffed into an integer + idWinInt *var = new idWinInt(); + int x = (int)this; + *var = x; + var->SetEval(false); + var->SetName("guied_wrapper"); + mWindow->AddDefinedVar(var); + + SetStateKey("name", mWindow->GetName(), false); +} + +/* +================ +rvGEWindowWrapper::GetWrapper + +Static method that returns the window wrapper for the given window class +================ +*/ +rvGEWindowWrapper * rvGEWindowWrapper::GetWrapper( idWindow *window ) { + idWinInt *var; + var = dynamic_cast< idWinInt*>(window->GetWinVarByName("guied_wrapper")); + return var ? ((rvGEWindowWrapper *) (int) (*var)) : NULL; +} + +/* +================ +rvGEWindowWrapper::UpdateRect + +Updates the gui editor's representation of the window rectangle from the +windows rectangle +================ +*/ +void rvGEWindowWrapper::UpdateRect( void ) { + idVec4 rect; + idWinRectangle *winrect; + + winrect = dynamic_cast< idWinRectangle*>(mWindow->GetWinVarByName("rect")); + assert(winrect); + rect = winrect->ToVec4(); + + mFlippedHorz = false; + mFlippedVert = false; + + if ( rect[2] < 0 ) { + mFlippedHorz = true; + rect[2] *= -1; + } + + if ( rect[3] < 0 ) { + mFlippedVert = true; + rect[3] *= -1; + } + + mClientRect = rect; + + CalcScreenRect(); + + const char *rstr = mState.GetString("rect", "0,0,0,0"); + mMoveable = !IsExpression(rstr); +} + +/* +================ +rvGEWindowWrapper::CalcScreenRect + +Calculates the screen rectangle from the client rectangle by running through +the parent windows and adding their offsets +================ +*/ +void rvGEWindowWrapper::CalcScreenRect( void ) { + idWindow *parent; + + mScreenRect = mClientRect; + + if ( NULL != (parent = mWindow->GetParent()) ) { + rvGEWindowWrapper *wrapper = GetWrapper(parent); + assert(wrapper); + + mScreenRect[0] += wrapper->GetScreenRect()[0]; + mScreenRect[1] += wrapper->GetScreenRect()[1]; + } + + // Since our screen rectangle has changed we need to tell all our our children to update + // their screen rectangles as well. + int i; + int count; + rvGEWindowWrapper *pwrapper; + + pwrapper = rvGEWindowWrapper::GetWrapper(mWindow); + + for ( count = pwrapper->GetChildCount(), i = 0; i < count; i ++ ) { + rvGEWindowWrapper *wrapper; + + wrapper = rvGEWindowWrapper::GetWrapper(pwrapper->GetChild(i)); + + // Usually we assert if there is no wrapper but since this method is called + // when the wrappers are being attached to the windows there may be no wrappers + // for any of the children. + if ( !wrapper ) { + continue; + } + + wrapper->CalcScreenRect(); + } +} + +/* +================ +rvGEWindowWrapper::SetRect + +Sets the wrapper's rectangle and the attached windows rectangle as well +================ +*/ +void rvGEWindowWrapper::SetRect( idRectangle &rect ) { + const char *s; + + mClientRect = rect; + CalcScreenRect(); + + s = va("%d,%d,%d,%d", (int) (rect.x + 0.5f), (int) (rect.y + 0.5f), (int) ((rect.w + 0.5f) * (mFlippedHorz ? -1 : 1)), (int) ((rect.h + 0.5f) * (mFlippedVert ? -1 : 1))); + + mState.Set("rect", s); + + UpdateWindowState(); +} + +/* +================ +rvGEWindowWrapper::SetHidden + +Sets the wrappers hidden state +================ +*/ +void rvGEWindowWrapper::SetHidden( bool h ) { + mHidden = h; + + UpdateWindowState(); +} + +/* +================ +rvGEWindowWrapper::SetDeleted + +Sets the deleted state of the wrapper which in turns sets whether or +not the window is visible +================ +*/ +void rvGEWindowWrapper::SetDeleted( bool del ) { + mDeleted = del; + + UpdateWindowState(); +} + +/* +================ +rvGEWindowWrapper::SetState + +Sets the window state from the given dictionary +================ +*/ +void rvGEWindowWrapper::SetState( const idDict &dict ) { + mState.Clear(); + mState.Copy(dict); + + // Push the window state to the window itself + UpdateWindowState(); + + // Update the internal rectangle since it may have changed in the state + UpdateRect(); +} + +/* +================ +rvGEWindowWrapper::SetStateKey + +Sets the given state key and updates the +================ +*/ +void rvGEWindowWrapper::SetStateKey( const char *key,const char *value,bool update ) { + mState.Set(key, value); + + if ( update ) { + UpdateWindowState(); + + // Make sure the rectangle gets updated if its changing + if ( !idStr::Icmp(key, "rect") ) { + UpdateRect(); + } + } +} + +/* +================ +rvGEWindowWrapper::DeleteStateKey + +Sets the given state key and updates the +================ +*/ +void rvGEWindowWrapper::DeleteStateKey( const char *key ) { + if ( !idStr::Icmp(key, "rect") || !idStr::Icmp(key, "name") ) { + return; + } + + mState.Delete(key); +} + +/* +================ +rvGEWindowWrapper::UpdateWindowState + +Updates the windows real state with wrappers internal state. Visibility is +handled specially +================ +*/ +void rvGEWindowWrapper::UpdateWindowState( void ) { + idStr realVisible; + bool tempVisible; + // int i; + + realVisible = mState.GetString("visible", "1"); + tempVisible = atoi(realVisible) ? true : false; + if ( tempVisible != mOldVisible ) { + mHidden = !tempVisible; + mOldVisible = tempVisible; + } + + tempVisible = !mDeleted && !mHidden; + + // Temporarily change the visible state so we can hide/unhide the window + mState.Set("visible", tempVisible ? "1" : "0"); + + mWindow->UpdateFromDictionary(mState); + + // Put the visible state back to the real value + mState.Set("visible", realVisible); +} + +/* +================ +rvGEWindowWrapper::WindowFromPoint + +Returns the topmost window under the given point +================ +*/ +idWindow * rvGEWindowWrapper::WindowFromPoint( float x,float y,bool visibleOnly ) { + int count; + int i; + rvGEWindowWrapper *pwrapper; + + // If the window isnt visible then skip it + if ( visibleOnly && (mHidden || mDeleted) ) { + return NULL; + } + + // Now check our children next + pwrapper = GetWrapper(mWindow); + count = pwrapper->GetChildCount(); + + for ( i = count - 1; i >= 0; i -- ) { + rvGEWindowWrapper *wrapper; + idWindow *child; + + child = pwrapper->GetChild(i); + assert(child); + + wrapper = rvGEWindowWrapper::GetWrapper(child); + if ( !wrapper ) { + continue; + } + + if ( child = wrapper->WindowFromPoint(x, y) ) { + return child; + } + } + + // We have to check this last because a child could be out outside of the parents + // rectangle and we still want it selectable. + if ( !mScreenRect.Contains(x, y) ) { + return NULL; + } + + return mWindow; +} + +/* +================ +rvGEWindowWrapper::StringToWindowType + +Converts the given string to a window type +================ +*/ +rvGEWindowWrapper::EWindowType rvGEWindowWrapper::StringToWindowType( const char *string ) { + if ( !idStr::Icmp(string, "windowDef") ) { + return WT_NORMAL; + } else if ( !idStr::Icmp(string, "editDef") ) { + return WT_EDIT; + } else if ( !idStr::Icmp(string, "choiceDef") ) { + return WT_CHOICE; + } else if ( !idStr::Icmp(string, "sliderDef") ) { + return WT_SLIDER; + } else if ( !idStr::Icmp(string, "bindDef") ) { + return WT_BIND; + } else if ( !idStr::Icmp(string, "listDef") ) { + return WT_LIST; + } else if ( !idStr::Icmp(string, "renderDef") ) { + return WT_RENDER; + } else if ( !idStr::Icmp(string, "htmlDef") ) { + return WT_HTML; + } + + return WT_UNKNOWN; +} + +/* +================ +rvGEWindowWrapper::WindowTypeToString + +Converts the given window type to a string +================ +*/ +const char * rvGEWindowWrapper::WindowTypeToString( EWindowType type ) { + static const char *typeNames[] = { + "Unknown", "windowDef", "editDef", "htmlDef", "choiceDef", "sliderDef", "bindDef", "listDef", "renderDef" + }; + + return typeNames[(int) type]; +} + +/* +================ +rvGEWindowWrapper::GetChildCount + +Returns the number of children the window being wrapped has +================ +*/ +int rvGEWindowWrapper::GetChildCount( void ) { + if ( !CanHaveChildren() ) { + return 0; + } + + return mWindow->GetChildCount(); +} + +/* +================ +rvGEWindowWrapper::EnumChildren + +Enumerates over the child windows while properly ignoring any that +are not wrapped. +================ +*/ +bool rvGEWindowWrapper::EnumChildren( PFNENUMCHILDRENPROC proc,void *data ) { + int count; + int i; + + if ( !CanHaveChildren() ) { + return false; + } + + for ( count = GetChildCount(), i = 0; i < count; i ++ ) { + if ( !proc(rvGEWindowWrapper::GetWrapper(GetChild(i)), data) ) { + return false; + } + } + + return true; +} + +/* +================ +rvGEWindowWrapper::CanHaveChildren + +Returns true if the window is allowed to have child windows +================ +*/ +bool rvGEWindowWrapper::CanHaveChildren( void ) { + if ( mType == WT_HTML || mType == WT_LIST ) { + return false; + } + + return true; +} + +/* +================ +rvGEWindowWrapper::GetDepth + +Returns the depth of the wrapped window +================ +*/ +int rvGEWindowWrapper::GetDepth( void ) { + idWindow *parent; + int depth; + + for ( depth = 0, parent = mWindow->GetParent(); parent; parent = parent->GetParent(), depth++ ) + ; + + return depth; +} + +/* +================ +rvGEWindowWrapper::Expand + +Expand the window in the navigator and all of its parents too +================ +*/ +bool rvGEWindowWrapper::Expand( void ) { + bool result; + + if ( mWindow->GetParent() ) { + result = rvGEWindowWrapper::GetWrapper(mWindow->GetParent())->Expand(); + } else { + result = false; + } + + if ( mExpanded || !CanHaveChildren() || !GetChildCount() ) { + return result; + } + + mExpanded = true; + + return true; +} + +/* +================ +rvGEWindowWrapper::Collapse + +Returns the depth of the wrapped window +================ +*/ +bool rvGEWindowWrapper::Collapse( void ) { + bool result; + + if ( mWindow->GetParent() ) { + result = rvGEWindowWrapper::GetWrapper(mWindow->GetParent())->Expand(); + } else { + result = false; + } + + if ( !mExpanded ) { + return result; + } + + mExpanded = false; + + return true; +} + +/* +================ +rvGEWindowWrapper::Finish + +After a the windwo wrapper is attached to a window and the window is parsed +the finish method is called to finish up any last details +================ +*/ +void rvGEWindowWrapper::Finish( void ) { + mOldVisible = ((bool) * dynamic_cast< idWinBool*>(mWindow->GetWinVarByName("visible"))); + mHidden = mOldVisible ? false : true; + UpdateRect(); +} + +/* +================ +rvGEWindowWrapper::Finish + +After a the windwo wrapper is attached to a window and the window is parsed +the finish method is called to finish up any last details +================ +*/ +bool rvGEWindowWrapper::VerfiyStateKey( const char *name,const char *value,idStr *result ) { + idStr old; + bool failed; + idParser src(value, strlen(value), "", LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT); + + // Save the current value + old = mState.GetString(name); + failed = false; + + // Try to parse in the value + try { + if ( !mWindow->ParseInternalVar(name, &src) ) { + // Kill the old register since the parse reg entry will add a new one + if ( !mWindow->ParseRegEntry(name, &src) ) { + failed = true; + } + } + } catch ( idException &) { + failed = true; + } + + // Restore the old value + idParser src2(old, old.Length(), "", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT); + if ( !mWindow->ParseInternalVar(name, &src2) ) { + if ( !mWindow->ParseRegEntry(name, &src2) ) { + } + } + + // Check to see if the old value matches the new value + idStr before; + idStr after; + + before = value; + before.StripTrailingWhitespace(); + src.GetStringFromMarker(after); + after.StripTrailingWhitespace(); + + if ( result ) { + *result = after; + } + + if ( failed || before.Cmp(after) ) { + return false; + } + + return true; +} + diff --git a/tools/guied/GEWindowWrapper.h b/tools/guied/GEWindowWrapper.h new file mode 100644 index 000000000..2a257174d --- /dev/null +++ b/tools/guied/GEWindowWrapper.h @@ -0,0 +1,214 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef GEWINDOWWRAPPER_H_ +#define GEWINDOWWRAPPER_H_ + +class idWindow; +class rvGEWindowWrapper; + +typedef bool (*PFNENUMCHILDRENPROC) ( rvGEWindowWrapper* wrapper, void* data ); + +class rvGEWindowWrapper +{ +public: + + enum EWindowType + { + WT_UNKNOWN, + WT_NORMAL, + WT_EDIT, + WT_HTML, + WT_CHOICE, + WT_SLIDER, + WT_BIND, + WT_LIST, + WT_RENDER, + WT_TRANSITION + }; + + rvGEWindowWrapper ( idWindow* window, EWindowType type ); + + static rvGEWindowWrapper* GetWrapper ( idWindow* window ); + + idWindow* GetWindow ( void ); + idDict& GetStateDict ( void ); + idDict& GetVariableDict ( void ); + idDict& GetScriptDict ( void ); + idRectangle& GetClientRect ( void ); + idRectangle& GetScreenRect ( void ); + EWindowType GetWindowType ( void ); + int GetChildCount ( void ); + int GetDepth ( void ); + idWindow* GetChild ( int index ); + + void SetRect ( idRectangle& rect ); + void SetState ( const idDict& dict ); + void SetStateKey ( const char* key, const char* value, bool update = true ); + void DeleteStateKey ( const char* key ); + bool VerfiyStateKey ( const char* name, const char* value, idStr* result = NULL ); + + bool IsFlippedHorz ( void ); + bool IsFlippedVert ( void ); + bool IsHidden ( void ); + bool IsDeleted ( void ); + bool IsSelected ( void ); + bool IsExpanded ( void ); + + bool CanHaveChildren ( void ); + bool CanMoveAndSize ( void ); + + void SetFlippedHorz ( bool f ); + void SetFlippedVert ( bool f ); + void SetHidden ( bool v ); + void SetDeleted ( bool del ); + void SetSelected ( bool sel ); + void SetWindowType ( EWindowType type ); + + bool Expand ( void ); + bool Collapse ( void ); + + bool EnumChildren ( PFNENUMCHILDRENPROC proc, void* data ); + + idWindow* WindowFromPoint ( float x, float y, bool visibleOnly = true ); + + void Finish ( void ); + + static EWindowType StringToWindowType ( const char* string ); + static const char* WindowTypeToString ( EWindowType type ); + +protected: + + void CalcScreenRect ( void ); + void UpdateRect ( void ); + void UpdateWindowState ( void ); + + idRectangle mClientRect; + idRectangle mScreenRect; + idWindow* mWindow; + idDict mState; + idDict mVariables; + idDict mScripts; + bool mFlippedHorz; + bool mFlippedVert; + bool mHidden; + bool mDeleted; + bool mSelected; + bool mExpanded; + bool mOldVisible; + bool mMoveable; + EWindowType mType; +}; + +ID_INLINE idDict& rvGEWindowWrapper::GetStateDict ( void ) +{ + return mState; +} + +ID_INLINE idDict& rvGEWindowWrapper::GetVariableDict ( void ) +{ + return mVariables; +} + +ID_INLINE idDict& rvGEWindowWrapper::GetScriptDict ( void ) +{ + return mScripts; +} + +ID_INLINE bool rvGEWindowWrapper::IsFlippedHorz ( void ) +{ + return mFlippedHorz; +} + +ID_INLINE bool rvGEWindowWrapper::IsFlippedVert ( void ) +{ + return mFlippedVert; +} + +ID_INLINE bool rvGEWindowWrapper::IsExpanded ( void ) +{ + return mExpanded; +} + +ID_INLINE void rvGEWindowWrapper::SetFlippedHorz ( bool f ) +{ + mFlippedHorz = f; +} + +ID_INLINE void rvGEWindowWrapper::SetFlippedVert ( bool f ) +{ + mFlippedVert = f; +} + +ID_INLINE idRectangle& rvGEWindowWrapper::GetClientRect ( void ) +{ + return mClientRect; +} + +ID_INLINE idRectangle& rvGEWindowWrapper::GetScreenRect ( void ) +{ + return mScreenRect; +} + +ID_INLINE bool rvGEWindowWrapper::IsHidden ( void ) +{ + return mHidden; +} + +ID_INLINE bool rvGEWindowWrapper::IsDeleted ( void ) +{ + return mDeleted; +} + +ID_INLINE bool rvGEWindowWrapper::IsSelected ( void ) +{ + return mSelected; +} + +ID_INLINE void rvGEWindowWrapper::SetSelected ( bool sel ) +{ + mSelected = sel; +} + +ID_INLINE rvGEWindowWrapper::EWindowType rvGEWindowWrapper::GetWindowType ( void ) +{ + return mType; +} + +ID_INLINE void rvGEWindowWrapper::SetWindowType ( rvGEWindowWrapper::EWindowType type ) +{ + mType = type; +} + +ID_INLINE idWindow* rvGEWindowWrapper::GetChild ( int index ) +{ + return mWindow->GetChild ( index ); +} + +ID_INLINE idWindow* rvGEWindowWrapper::GetWindow ( void ) +{ + return mWindow; +} + +ID_INLINE bool rvGEWindowWrapper::CanMoveAndSize ( void ) +{ + return mMoveable; +} + +#endif // GEWINDOWWRAPPER_H_ diff --git a/tools/guied/GEWindowWrapper_stub.cpp b/tools/guied/GEWindowWrapper_stub.cpp new file mode 100644 index 000000000..efe04cca7 --- /dev/null +++ b/tools/guied/GEWindowWrapper_stub.cpp @@ -0,0 +1,38 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../ui/EditWindow.h" +#include "../../ui/ListWindow.h" +#include "../../ui/BindWindow.h" +#include "../../ui/RenderWindow.h" +#include "../../ui/ChoiceWindow.h" + +#include "GEWindowWrapper.h" + +static rvGEWindowWrapper stub_wrap( NULL, rvGEWindowWrapper::WT_UNKNOWN ); + +rvGEWindowWrapper::rvGEWindowWrapper( idWindow* window, EWindowType type ) { } + +rvGEWindowWrapper* rvGEWindowWrapper::GetWrapper ( idWindow* window ) { return &stub_wrap; } + +void rvGEWindowWrapper::SetStateKey( const char*, const char*, bool ) { } + +void rvGEWindowWrapper::Finish() { } diff --git a/tools/guied/GEWorkspace.cpp b/tools/guied/GEWorkspace.cpp new file mode 100644 index 000000000..4d5ae3ccd --- /dev/null +++ b/tools/guied/GEWorkspace.cpp @@ -0,0 +1,2055 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/guied_resource.h" +#include "../../renderer/tr_local.h" +#include "../../sys/win32/win_local.h" +#include "../../ui/DeviceContext.h" +#include "../../ui/EditWindow.h" +#include "../../ui/ListWindow.h" +#include "../../ui/BindWindow.h" +#include "../../ui/RenderWindow.h" +#include "../../ui/ChoiceWindow.h" + +#include "GEApp.h" +#include "GEItemPropsDlg.h" +#include "GEItemScriptsDlg.h" + +// Modifiers +#include "GEModifierGroup.h" +#include "GEMoveModifier.h" +#include "GESizeModifier.h" +#include "GEStateModifier.h" +#include "GEZOrderModifier.h" +#include "GEInsertModifier.h" +#include "GEHideModifier.h" +#include "GEDeleteModifier.h" + +static float g_ZoomScales[rvGEWorkspace::ZOOM_MAX] = { 0, 0.25f, 0.33f, 0.50f, 0.66f, 1.0f, 1.5f, 2.0f, 3.0f }; + +static const int ID_GUIED_SELECT_FIRST = 9800; +static const int ID_GUIED_SELECT_LAST = 9900; + +idList rvGEWorkspace::mClipboard; + +rvGEWorkspace::rvGEWorkspace ( rvGEApp* app ) : mApplication ( app ) +{ + mWnd = 0; + mInterface = 0; + mZoom = ZOOM_100; + mScrollHorz = false; + mScrollVert = false; + mModified = false; + mNew = false; + mDragScroll = false; + mSourceControlState = SCS_CHECKEDOUT; + mFilename = "guis/Untitled.gui"; + mDragType = rvGESelectionMgr::HT_NONE; + mHandCursor = LoadCursor ( app->GetInstance(), MAKEINTRESOURCE(IDC_GUIED_HAND) ); + mDontAdd = false; + + mSelections.SetWorkspace ( this ); +} + +rvGEWorkspace::~rvGEWorkspace ( ) +{ + // Make sure all the wrappers get cleaned up + rvGEWindowWrapper::GetWrapper ( mInterface->GetDesktop ( ) )->EnumChildren ( CleanupEnumProc, NULL ); + + DestroyCursor ( mHandCursor ); + + delete mInterface; +} + +/* +================ +rvGEWorkspace::CleanupEnumProc + +Window enumeration procedure that deletes all the wrapper classes +================ +*/ +bool rvGEWorkspace::CleanupEnumProc ( rvGEWindowWrapper* wrapper, void* data ) +{ + bool result; + + if ( !wrapper ) + { + return true; + } + + result = wrapper->EnumChildren ( CleanupEnumProc, data ); + + // Cleanup the window wrapper + delete wrapper; + + return result; +} + +/* +================ +rvGEWorkspace::GetZoomScale + +Returns the scale of the current zoom level +================ +*/ +float rvGEWorkspace::GetZoomScale ( void ) +{ + return g_ZoomScales [ mZoom ]; +} + +/* +================ +rvGEWorkspace::Attach + +Attaches the workspace to the given window. This is usually done after the +window is created and the file has been loaded. +================ +*/ +bool rvGEWorkspace::Attach ( HWND wnd ) +{ + assert ( wnd ); + + mWnd = wnd; + + // Initialize the pixel format for this window + SetupPixelFormat ( ); + + // Jam the workspace pointer into the userdata window long so + // we can retrieve the workspace from the window later + SetWindowLong ( mWnd, GWL_USERDATA, (LONG) this ); + + UpdateTitle ( ); + + return true; +} + +/* +================ +rvGEWorkspace::Detach + +Detaches the workspace from the window it is currently attached to +================ +*/ +void rvGEWorkspace::Detach ( void ) +{ + assert ( mWnd ); + + SetWindowLong ( mWnd, GWL_USERDATA, 0 ); + mWnd = NULL; +} + +/* +================ +rvGEWorkspace::SetupPixelFormat + +Setup the pixel format for the opengl context +================ +*/ +bool rvGEWorkspace::SetupPixelFormat ( void ) +{ + HDC hDC = GetDC ( mWnd ); + bool result = true; + + int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + if (pixelFormat > 0) + { + if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) + { + result = false; + } + } + else + { + result = false; + } + + ReleaseDC ( mWnd, hDC ); + + return result; +} + +/* +================ +rvGEWorkspace::RenderGrid + +Renders the grid on top of the user interface +================ +*/ +void rvGEWorkspace::RenderGrid ( void ) +{ + float x; + float y; + float step; + idVec4& color = mApplication->GetOptions().GetGridColor ( ); + + // See if the grid is off before rendering it + if ( !mApplication->GetOptions().GetGridVisible ( )) + { + return; + } + + qglEnable(GL_BLEND); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + qglColor4f ( color[0], color[1], color[2], 0.5f ); + + qglBegin ( GL_LINES ); + step = mApplication->GetOptions().GetGridWidth ( ) * g_ZoomScales[mZoom]; + for ( x = mRect.x + mRect.w; x >= mRect.x ; x -= step ) + { + qglVertex2f ( x, mRect.y ); + qglVertex2f ( x, mRect.y + mRect.h ); + } + step = mApplication->GetOptions().GetGridHeight ( ) * g_ZoomScales[mZoom]; + for ( y = mRect.y + mRect.h; y >= mRect.y ; y -= step ) + { + qglVertex2f ( mRect.x, y ); + qglVertex2f ( mRect.x + mRect.w, y ); + } + qglEnd ( ); + + qglDisable(GL_BLEND); + qglColor3f ( color[0], color[1], color[2] ); + + qglBegin ( GL_LINES ); + step = mApplication->GetOptions().GetGridWidth ( ) * g_ZoomScales[mZoom]; + for ( x = mRect.x + mRect.w; x >= mRect.x ; x -= step * 4 ) + { + qglVertex2f ( x, mRect.y ); + qglVertex2f ( x, mRect.y + mRect.h ); + } + step = mApplication->GetOptions().GetGridHeight ( ) * g_ZoomScales[mZoom]; + for ( y = mRect.y + mRect.h; y >= mRect.y ; y -= step * 4 ) + { + qglVertex2f ( mRect.x, y ); + qglVertex2f ( mRect.x + mRect.w, y ); + } + qglEnd ( ); +} + +/* +================ +rvGEWorkspace::Render + +Renders the workspace to the given DC +================ +*/ +void rvGEWorkspace::Render ( HDC hdc ) +{ + int front; + int back; + float scale; + + scale = g_ZoomScales[mZoom]; + + // Switch GL contexts to our dc + if (!qwglMakeCurrent( hdc, win32.hGLRC )) + { + common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError()); + common->Printf("Please restart Q3Radiant if the Map view is not working\n"); + return; + } + + // Prepare the view and clear it + GL_State( GLS_DEFAULT ); + qglViewport(0, 0, mWindowWidth, mWindowHeight ); + qglScissor(0, 0, mWindowWidth, mWindowHeight ); + qglClearColor ( 0.75f, 0.75f, 0.75f, 0 ); + + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_CULL_FACE); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Render the workspace below + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + qglColor3f ( mApplication->GetOptions().GetWorkspaceColor()[0], mApplication->GetOptions().GetWorkspaceColor()[1], mApplication->GetOptions().GetWorkspaceColor()[2] ); + qglBegin ( GL_QUADS ); + qglVertex2f ( mRect.x, mRect.y ); + qglVertex2f ( mRect.x + mRect.w, mRect.y ); + qglVertex2f ( mRect.x + mRect.w, mRect.y + mRect.h ); + qglVertex2f ( mRect.x, mRect.y + mRect.h ); + qglEnd ( ); + + // Prepare the renderSystem view to draw the GUI in + viewDef_t viewDef; + memset ( &viewDef, 0, sizeof(viewDef) ); + tr.viewDef = &viewDef; + tr.viewDef->renderView.x = mRect.x; + tr.viewDef->renderView.y = mWindowHeight - mRect.y - mRect.h; + tr.viewDef->renderView.width = mRect.w; + tr.viewDef->renderView.height = mRect.h; + tr.viewDef->scissor.x1 = 0; + tr.viewDef->scissor.y1 = 0; + tr.viewDef->scissor.x2 = mRect.w; + tr.viewDef->scissor.y2 = mRect.h; + tr.viewDef->isEditor = true; + renderSystem->BeginFrame(mWindowWidth, mWindowHeight ); + + // Draw the gui + mInterface->Redraw ( 0 ); // eventLoop->Milliseconds() ); + + // We are done using the renderSystem now + renderSystem->EndFrame( &front, &back ); + + if ( mApplication->GetActiveWorkspace ( ) == this ) + { + mApplication->GetStatusBar().SetTriangles ( backEnd.pc.c_drawIndexes/3 ); + } + + // Prepare the viewport for drawing selections, etc. + GL_State( GLS_DEFAULT ); + qglDisable( GL_TEXTURE_CUBE_MAP_EXT ); +// qglDisable(GL_BLEND); + qglDisable(GL_CULL_FACE); + + qglViewport(0, 0, mWindowWidth, mWindowHeight ); + qglScissor(0, 0, mWindowWidth, mWindowHeight ); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + RenderGrid ( ); + + mSelections.Render ( ); + + qglFinish ( ); + qwglSwapBuffers(hdc); + + qglEnable( GL_TEXTURE_CUBE_MAP_EXT ); + qglEnable( GL_CULL_FACE); +} + +/* +================ +rvGEWorkspace::UpdateTitle + +Updates the window title with the name of the file and the zoom level and weither its open or not +================ +*/ +void rvGEWorkspace::UpdateTitle ( void ) +{ + // Set the window title based on the current filename + SetWindowText ( mWnd, va("%s%s (%d%%)", idStr(mFilename).StripPath ( ).c_str( ), mModified?"*":"", (int) (g_ZoomScales[mZoom] * 100)) ); + + gApp.GetStatusBar().SetZoom ( (int)(g_ZoomScales[mZoom] * 100.0f) ); +} + +/* +================ +rvGEWorkspace::UpdateRectangle + +Updates the rectangle (not counting scrolling) +================ +*/ +void rvGEWorkspace::UpdateRectangle ( bool useScroll ) +{ + RECT rcClient; + float x; + float y; + float scale; + + scale = g_ZoomScales[mZoom]; + + // Grab the current client rectangle of the window and cache off the width and height + GetClientRect ( mWnd, &rcClient ); + mWindowWidth = rcClient.right - rcClient.left; + mWindowHeight = rcClient.bottom - rcClient.top; + + // The workspace is always centered in the window + x = mRect.x = mWindowWidth / 2 - (SCREEN_WIDTH * scale) / 2; + y = mRect.y = mWindowHeight / 2 - (SCREEN_HEIGHT * scale) / 2; + mRect.w = (SCREEN_WIDTH * scale); + mRect.h = (SCREEN_HEIGHT * scale); + + // When using the scroll position offset the rectangle based on the scrollbar positions + if ( useScroll ) + { + // Adjust the start of the rectangle for the scroll positiond + mRect.y -= (float)GetScrollPos ( mWnd, SB_VERT ) / 1000.0f; + mRect.x -= (float)GetScrollPos ( mWnd, SB_HORZ ) / 1000.0f; + } +} + +/* +================ +rvGEWorkspace::Scroll + +Adjusts the given scrollbar by the given offset +================ +*/ +void rvGEWorkspace::Scroll ( int scrollbar, int offset ) +{ + SCROLLINFO si; + + if ( scrollbar == SB_HORZ && !mScrollHorz ) + { + return; + } + else if ( scrollbar == SB_VERT && !mScrollVert ) + { + return; + } + + // Get all the vertial scroll bar information + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + + // Save the position for comparison later on + GetScrollInfo ( mWnd, scrollbar, &si); + + si.nPos += (1000 * offset); + if ( si.nPos < si.nMin ) si.nPos = si.nMin; + if ( si.nPos > si.nMax ) si.nPos = si.nMax; + + si.fMask = SIF_POS; + SetScrollInfo (mWnd, scrollbar, &si, TRUE); + GetScrollInfo (mWnd, scrollbar, &si); + + UpdateRectangle ( ); +} + +int rvGEWorkspace::HandleScroll ( int scrollbar, WPARAM wParam, LPARAM lParam ) +{ + SCROLLINFO si; + + // Get all the vertial scroll bar information + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + + // Save the position for comparison later on + GetScrollInfo ( mWnd, scrollbar, &si); + + switch (LOWORD (wParam)) + { + // user clicked left or up arrow + case SB_LINELEFT: + si.nPos -= 1000; + break; + + // user clicked right or down arrow + case SB_LINERIGHT: + si.nPos += 1000; + break; + + // user clicked shaft left of the scroll box + case SB_PAGELEFT: + si.nPos -= si.nPage; + break; + + // user clicked shaft right of the scroll box + case SB_PAGERIGHT: + si.nPos += si.nPage; + break; + + // user dragged the scroll box + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default : + break; + } + + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo (mWnd, scrollbar, &si, TRUE); + GetScrollInfo (mWnd, scrollbar, &si); + + UpdateRectangle ( ); + + return 0; +} + +/* +================ +rvGEWorkspace::UpdateScrollbars + +Updates the states and the ranges of the scrollbars as well as the rectangle +================ +*/ +void rvGEWorkspace::UpdateScrollbars ( void ) +{ + SCROLLINFO info; + + // First update the rectangle without applying scroll positions so + // we know the real sizes and coordinates + UpdateRectangle ( false ); + + // Setup the veritcal scrollbar + info.cbSize = sizeof(info); + info.fMask = SIF_RANGE|SIF_PAGE; + info.nMax = (mRect.h - mWindowHeight + 10) * 1000 / 2; + info.nMin = -info.nMax; + info.nPage = (int)((float)info.nMax * (float)((float)mWindowHeight / mRect.h)); + info.nMax += info.nPage; + + // If there is something to scroll then turn on the vertical scroll bar + // if its not on and update the scroll info. + if ( info.nMax > 0 ) + { + if ( !mScrollVert ) + { + mScrollVert = true; + ShowScrollBar ( mWnd, SB_VERT, mScrollVert ); + } + SetScrollInfo ( mWnd, SB_VERT, &info, TRUE ); + } + // Nothing to scroll, turn off the scrollbar if its on. + else if ( mScrollVert ) + { + mScrollVert = false; + SetScrollPos ( mWnd, SB_VERT, 0, FALSE ); + ShowScrollBar ( mWnd, SB_VERT, mScrollVert ); + } + + // Setup the horizontal scrollbar + info.nMax = (mRect.w - mWindowWidth + 10) * 1000 / 2; + info.nMin = -info.nMax; + info.nPage = (int)((float)info.nMax * (float)((float)mWindowWidth / mRect.w)); + info.nMax += info.nPage; + + // If there is something to scroll then turn on the vertical scroll bar + // if its not on and update the scroll info. + if ( info.nMax > 0 ) + { + if ( !mScrollHorz ) + { + mScrollHorz = true; + ShowScrollBar ( mWnd, SB_HORZ, mScrollHorz ); + } + + SetScrollInfo ( mWnd, SB_HORZ, &info, TRUE ); + } + // Nothing to scroll, turn off the scrollbar if its on. + else if ( mScrollHorz ) + { + mScrollHorz = false; + SetScrollPos ( mWnd, SB_HORZ, 0, FALSE ); + ShowScrollBar ( mWnd, SB_HORZ, mScrollHorz ); + } + + // Need to update the rectangle again to take the scrollbar changes into account + UpdateRectangle ( true ); +} + +/* +================ +rvGEWorkspace::UpdateCursor + +Called to update the cursor when the mouse is within the workspace window +================ +*/ +void rvGEWorkspace::UpdateCursor ( rvGESelectionMgr::EHitTest type ) +{ + switch ( type ) + { + case rvGESelectionMgr::HT_SELECT: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW) ) ); + break; + + case rvGESelectionMgr::HT_MOVE: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZEALL) ) ); + break; + + case rvGESelectionMgr::HT_SIZE_LEFT: + case rvGESelectionMgr::HT_SIZE_RIGHT: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZEWE ) ) ); + break; + + case rvGESelectionMgr::HT_SIZE_TOP: + case rvGESelectionMgr::HT_SIZE_BOTTOM: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENS ) ) ); + break; + + case rvGESelectionMgr::HT_SIZE_TOPRIGHT: + case rvGESelectionMgr::HT_SIZE_BOTTOMLEFT: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENESW ) ) ); + break; + + case rvGESelectionMgr::HT_SIZE_BOTTOMRIGHT: + case rvGESelectionMgr::HT_SIZE_TOPLEFT: + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENWSE ) ) ); + break; + } +} + +void rvGEWorkspace::UpdateCursor ( float x, float y ) +{ + idVec2 point; + rvGESelectionMgr::EHitTest type; + + // First convert the worspace coord to a window coord + point = WorkspaceToWindow ( idVec2( x, y ) ); + + // See if it hits anything + type = mSelections.HitTest ( point.x, point.y ); + + // If it hits something then use it to update the cursor + if ( rvGESelectionMgr::HT_NONE != type ) + { + UpdateCursor ( type ); + } + else + { + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) ); + } +} + +void rvGEWorkspace::UpdateCursor ( void ) +{ + if ( mDragType == rvGESelectionMgr::HT_NONE ) + { + POINT point; + idVec2 cursor; + + GetCursorPos ( &point ); + cursor.Set ( point.x, point.y ); + WindowToWorkspace ( cursor ); + + UpdateCursor ( cursor.x, cursor.y ); + } + else + { + UpdateCursor ( mDragType ); + } +} + +/* +================ +rvGEWorkspace::HandleMessage + +Handles window messages to the workspace +================ +*/ +void rvGEWorkspace::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_CLOSE: + { + + if ( IsModified ( ) ) + { + if ( IDYES == gApp.MessageBox ( va("Save changes to the document \"%s\" before closing?", GetFilename() ), MB_YESNO|MB_ICONQUESTION ) ) + { + SendMessage ( mApplication->GetMDIFrame(), WM_COMMAND, MAKELONG(ID_GUIED_FILE_SAVE,0), 0 ); + } + } + + + GetApplication ( )->GetNavigator().SetWorkspace(NULL); + GetApplication ( )->GetTransformer().SetWorkspace(NULL); + GetApplication ( )->GetProperties().SetWorkspace(NULL); + break; + } + + case WM_CAPTURECHANGED: + if ( (HWND)lParam != mWnd ) + { + mDragScroll = false; + mDragType = rvGESelectionMgr::HT_NONE; + } + break; + + case WM_SETCURSOR: + { + POINT point; + idVec2 cursor; + GetCursorPos ( &point ); + cursor.Set ( point.x, point.y ); + WindowToWorkspace ( cursor ); + if ( mDragType == rvGESelectionMgr::HT_NONE ) + { + UpdateCursor ( cursor.x, cursor.y ); + } + else + { + UpdateCursor ( mDragType ); + } + break; + } + + case WM_MOUSEWHEEL: + if ( (short)HIWORD(wParam) > 0 ) + { + ZoomIn ( ); + } + else if ( (short)HIWORD(wParam) < 0 ) + { + ZoomOut ( ); + } + break; + + case WM_MOUSEMOVE: + HandleMouseMove ( wParam, lParam ); + break; + + case WM_MBUTTONDOWN: + HandleMButtonDown ( wParam, lParam ); + break; + + case WM_MBUTTONUP: + HandleMButtonUp ( wParam, lParam ); + break; + + case WM_LBUTTONDOWN: + HandleLButtonDown ( wParam, lParam ); + break; + + case WM_LBUTTONUP: + HandleLButtonUp ( wParam, lParam ); + break; + + case WM_LBUTTONDBLCLK: + HandleLButtonDblClk ( wParam, lParam ); + break; + + case WM_INITMENUPOPUP: + SendMessage ( mApplication->GetMDIFrame(), msg, wParam, lParam ); + break; + + case WM_COMMAND: + HandleCommand ( wParam, lParam ); + break; + + case WM_RBUTTONDOWN: + HandleRButtonDown ( wParam, lParam ); + break; + + case WM_SIZE: + UpdateScrollbars(); + break; + + case WM_VSCROLL: + HandleScroll ( SB_VERT, wParam, lParam ); + break; + + case WM_HSCROLL: + HandleScroll ( SB_HORZ, wParam, lParam ); + break; + + case WM_KEYDOWN: + HandleKeyDown ( wParam, lParam ); + break; + } +} +/* +================ +rvGEWorkspace::HandleCommand + +Handles command messages destined for the workspace window. This is for +special workspace commands, any unhandled commands are forwarded to the main window +================ +*/ +int rvGEWorkspace::HandleCommand ( WPARAM wParam, LPARAM lParam ) +{ + // Select command + if ( LOWORD(wParam) >= ID_GUIED_SELECT_FIRST && LOWORD(wParam) <= ID_GUIED_SELECT_LAST ) + { + idWindow* window = mSelectMenu[LOWORD(wParam)-ID_GUIED_SELECT_FIRST]; + rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( window ); + + // Handle multi select as well + if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) + { + if ( wrapper->IsSelected ( ) ) + { + mSelections.Remove ( window ); + } + else + { + mSelections.Add ( window ); + } + } + else + { + mSelections.Set ( window ); + } + } + + return SendMessage ( mApplication->GetMDIFrame(), WM_COMMAND, wParam, lParam ); +} + +/* +================ +rvGEWorkspace::HandleMButtonDown + +Handles the middle mouse down message in the workspace +================ +*/ +int rvGEWorkspace::HandleMButtonDown ( WPARAM wParam, LPARAM lParam ) +{ + if ( mDragType != rvGESelectionMgr::HT_NONE ) + { + return 0; + } + + mDragPoint.Set ( LOWORD(lParam), HIWORD(lParam) ); + mDragScroll = true; + SetCursor ( mHandCursor ); + SetCapture ( mWnd ); + + WindowToWorkspace ( mDragPoint ); + + return 0; +} + +/* +================ +rvGEWorkspace::HandleMButtonUp + +Handles the middle mouse up message in the workspace +================ +*/ +int rvGEWorkspace::HandleMButtonUp ( WPARAM wParam, LPARAM lParam ) +{ + if ( mDragScroll ) + { + mDragScroll = false; + ReleaseCapture ( ); + } + + return 0; +} + +/* +================ +rvGEWorkspace::HandleRButtonDown + +Handles the left mouse down message in the workspace +================ +*/ +int rvGEWorkspace::HandleRButtonDown ( WPARAM wParam, LPARAM lParam ) +{ + POINT point = { LOWORD(lParam), HIWORD(lParam) }; + HMENU menu; + + // Add the select menu + mSelectMenu.Clear ( ); + + // Cache where the menu is being brought up so we can + // figure out which windows are under the point + mSelectMenuPos[0] = point.x; + mSelectMenuPos[1] = point.y; + WindowToWorkspace ( mSelectMenuPos ); + + // Build a list of all the windows under the menu point + rvGEWindowWrapper::GetWrapper ( mInterface->GetDesktop() )->EnumChildren ( BuildSelectMenuEnumProc, this ); + + // Add the desktop window always + mSelectMenu.Append ( mInterface->GetDesktop() ); + + // + menu = GetSubMenu ( LoadMenu ( mApplication->GetInstance(), MAKEINTRESOURCE(IDR_GUIED_ITEM_POPUP) ), 0 ); + + HMENU popup = CreatePopupMenu ( ); + + int i; + for ( i = 0; i < mSelectMenu.Num(); i ++ ) + { + rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( mSelectMenu[i] ); + AppendMenu ( popup, MF_STRING|MF_ENABLED|(wrapper->IsSelected()?MF_CHECKED:0), ID_GUIED_SELECT_FIRST + i, mSelectMenu[i]->GetName() ); + } + + InsertMenu ( menu, 1, MF_POPUP|MF_BYPOSITION, (LONG) popup, "Select" ); + + // Bring up the popup menu + ClientToScreen ( mWnd, &point ); + TrackPopupMenu ( menu, TPM_RIGHTBUTTON|TPM_LEFTALIGN, point.x, point.y, 0, mWnd, NULL ); + + DestroyMenu ( popup ); + DestroyMenu ( menu ); + + return 0; +} + +/* +================ +rvGEWorkspace::HandleLButtonDown + +Handles the left mouse down message in the workspace +================ +*/ +int rvGEWorkspace::HandleLButtonDown ( WPARAM wParam, LPARAM lParam ) +{ + if ( mDragScroll ) + { + return 0; + } + + idVec2 point ( LOWORD(lParam), HIWORD(lParam) ); + WindowToWorkspace ( point ); + + // Make sure whatever modifications get generated cant be merged into whats already there + mModifiers.BlockNextMerge ( ); + + mDragPoint.Set ( LOWORD(lParam), HIWORD(lParam) ); + mDragTime = Sys_Milliseconds ( ); + mDragX = true; + mDragY = true; + + // If we have selections then start a drag + if ( mSelections.Num ( ) ) + { + mDragType = mSelections.HitTest ( mDragPoint.x, mDragPoint.y ); + } + + rvGEWindowWrapper* wrapper; + wrapper = rvGEWindowWrapper::GetWrapper ( mInterface->GetDesktop ( ) ); + + idWindow* window = wrapper->WindowFromPoint ( point.x, point.y ); + + // dissallow selection of the desktop. + if ( gApp.GetOptions().GetIgnoreDesktopSelect() && window == mInterface->GetDesktop ( ) ) + { + window = NULL; + } + + if ( mDragType == rvGESelectionMgr::HT_MOVE || mDragType == rvGESelectionMgr::HT_NONE ) + { + if ( window ) + { + bool selected; + + selected = mSelections.IsSelected ( window ); + + if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) + { + if ( !selected ) + { + mSelections.Add ( window ); + mDragType = rvGESelectionMgr::HT_MOVE; + } + else + { + mSelections.Remove ( window ); + } + } + else if ( !selected && mDragType == rvGESelectionMgr::HT_NONE ) + { + mSelections.Set ( window ); + mDragType = rvGESelectionMgr::HT_MOVE; + } + } + else + { + mSelections.Clear ( ); + } + } + + if ( mSelections.IsExpression ( ) ) + { + mDragType = rvGESelectionMgr::HT_SELECT; + } + // Windows capture + else if ( mDragType != rvGESelectionMgr::HT_NONE ) + { + SetCapture ( mWnd ); + } + + WindowToWorkspace ( mDragPoint ); + + return 0; +} + +/* +================ +rvGEWorkspace::HandleLButtonUp + +Handles the left mouse up message in the workspace +================ +*/ +int rvGEWorkspace::HandleLButtonUp ( WPARAM wParam, LPARAM lParam ) +{ + if ( mDragType != rvGESelectionMgr::HT_NONE ) + { + ReleaseCapture ( ); + mModifiers.BlockNextMerge ( ); + + // Update the transformer + mApplication->GetTransformer().Update ( ); + } + + // No more dragging + mDragType = rvGESelectionMgr::HT_NONE; + + return 0; +} + +/* +================ +rvGEWorkspace::HandleLButtonDblClk + +Handle a double click by opening properties +================ +*/ +int rvGEWorkspace::HandleLButtonDblClk ( WPARAM wParam, LPARAM lParam ) +{ + EditSelectedProperties ( ); + return 0; +} + +/* +================ +rvGEWorkspace::HandleMouseMove + +Handles the moving of the mouse for dragging and cursor updating +================ +*/ +int rvGEWorkspace::HandleMouseMove ( WPARAM wParam, LPARAM lParam ) +{ + idVec2 cursor; + + cursor.Set ( (short)LOWORD(lParam), (short)HIWORD(lParam) ); + + // Convert the window point to the workspace before updating the + // cursor with the position + WindowToWorkspace ( cursor ); + + // Scrolling the window around + if ( mDragScroll ) + { + Scroll ( SB_HORZ, mDragPoint.x - cursor.x ); + Scroll ( SB_VERT, mDragPoint.y - cursor.y ); + + SetCursor ( mHandCursor ); + + mDragPoint = cursor; + + return 0; + } + + // If not dragging then just update the cursor and return + if ( mDragType == rvGESelectionMgr::HT_NONE ) + { + UpdateCursor ( cursor.x, cursor.y ); + return 0; + } + + // Dont allow a drag move start until the button has been down for 100 ms or so + if ( mDragType == rvGESelectionMgr::HT_MOVE && Sys_Milliseconds() - mDragTime <= 50 ) + { + return 0; + } + + // Handle grid snapping + if ( gApp.GetOptions().GetGridSnap ( ) ) + { + cursor.x = (float)(((int)cursor.x + gApp.GetOptions().GetGridWidth()/2) / gApp.GetOptions().GetGridWidth() * gApp.GetOptions().GetGridWidth()); + cursor.y = (float)(((int)cursor.y + gApp.GetOptions().GetGridWidth()/2) / gApp.GetOptions().GetGridWidth() * gApp.GetOptions().GetGridWidth()); + } + + // If the cursor hasnt moved then there is nothing to update with the drag + if ( (int) cursor.x == (int) mDragPoint.x && (int) cursor.y == (int) mDragPoint.y ) + { + return 0; + } + + switch ( mDragType ) + { + case rvGESelectionMgr::HT_MOVE: + AddModifierMove ( "Move", cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_BOTTOM: + AddModifierSize ( "Size", 0, 0, 0, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_TOP: + AddModifierSize ( "Size", 0, cursor.y - mDragPoint.y, 0, 0, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_RIGHT: + AddModifierSize ( "Size", 0, 0, cursor.x - mDragPoint.x, 0, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_LEFT: + AddModifierSize ( "Size", cursor.x - mDragPoint.x, 0, 0, 0, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_TOPLEFT: + AddModifierSize ( "Size", cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, 0, 0, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_TOPRIGHT: + AddModifierSize ( "Size", 0, cursor.y - mDragPoint.y, cursor.x - mDragPoint.x, 0, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_BOTTOMLEFT: + AddModifierSize ( "Size", cursor.x - mDragPoint.x, 0, 0, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) ); + break; + + case rvGESelectionMgr::HT_SIZE_BOTTOMRIGHT: + AddModifierSize ( "Size", 0, 0, cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) ); + break; + } + + UpdateCursor ( mDragType ); + + // If the x coordinate has changed then update it + if ( (int)cursor.x != (int)mDragPoint.x && mDragX ) + { + mDragPoint.x = cursor.x; + } + + // If the y coordinate has changed then update it + if ( (int)cursor.y != (int)mDragPoint.y && mDragY ) + { + mDragPoint.y = cursor.y; + } + + return 0; +} + +/* +================ +rvGEWorkspace::HandleKeyDown + +Handles the the pressing of a key +================ +*/ +int rvGEWorkspace::HandleKeyDown ( WPARAM wParam, LPARAM lParam ) +{ + bool shift = (GetAsyncKeyState ( VK_SHIFT ) & 0x8000) ? true : false; + + switch ( wParam ) + { + case VK_LEFT: + if ( shift ) + { + AddModifierSizeNudge ( -1, 0, false ); + } + else + { + AddModifierMoveNudge ( -1, 0, false ); + } + break; + + case VK_RIGHT: + if ( shift ) + { + AddModifierSizeNudge ( 1, 0, false ); + } + else + { + AddModifierMoveNudge ( 1, 0, false ); + } + break; + + case VK_DOWN: + if ( shift ) + { + AddModifierSizeNudge ( 0, 1, false ); + } + else + { + AddModifierMoveNudge ( 0, 1, false ); + } + break; + + case VK_UP: + if ( shift ) + { + AddModifierSizeNudge ( 0, -1, false ); + } + else + { + AddModifierMoveNudge ( 0, -1, false ); + } + break; + + case VK_ESCAPE: + mSelections.Clear ( ); + mApplication->GetNavigator().Update ( ); + break; + } + + return 0; +} + +/* +================ +rvGEWorkspace::WindowToWorkspace + +Converts the given coordinates in windows space to the workspace's coordinates. +================ +*/ +idVec2& rvGEWorkspace::WindowToWorkspace ( idVec2& point ) +{ + point.x = (point.x - mRect.x) / mRect.w * SCREEN_WIDTH; + point.y = (point.y - mRect.y) / mRect.h * SCREEN_HEIGHT; + + return point; +} + +idRectangle& rvGEWorkspace::WindowToWorkspace ( idRectangle& rect ) +{ + rect.x = (rect.x - mRect.x) / mRect.w * SCREEN_WIDTH; + rect.y = (rect.y - mRect.y) / mRect.h * SCREEN_HEIGHT; + rect.w = rect.w / mRect.w * SCREEN_WIDTH; + rect.h = rect.h / mRect.h * SCREEN_HEIGHT; + + return rect; +} + +/* +================ +rvGEWorkspace::WindowToWorkspace + +Converts the given workspace coordinates to the windows coordinates. +================ +*/ +idVec2& rvGEWorkspace::WorkspaceToWindow ( idVec2& point ) +{ + point.x = mRect.x + (point.x / SCREEN_WIDTH * mRect.w); + point.y = mRect.y + (point.y / SCREEN_HEIGHT * mRect.h); + + return point; +} + +idRectangle& rvGEWorkspace::WorkspaceToWindow ( idRectangle& rect ) +{ + rect.x = mRect.x + (rect.x / SCREEN_WIDTH * mRect.w); + rect.y = mRect.y + (rect.y / SCREEN_HEIGHT * mRect.h); + rect.w = rect.w / SCREEN_WIDTH * mRect.w; + rect.h = rect.h / SCREEN_HEIGHT * mRect.h; + + return rect; +} + +/* +================ +rvGEWorkspace::ZoomIn + +Zooms the workspace in by one zoom level +================ +*/ +rvGEWorkspace::EZoomLevel rvGEWorkspace::ZoomIn ( void ) +{ + mZoom = mZoom + 1; + if ( mZoom >= ZOOM_MAX ) + { + mZoom = ZOOM_MAX - 1; + } + + UpdateScrollbars ( ); + UpdateTitle ( ); + + InvalidateRect ( mWnd, NULL, FALSE ); + + return (EZoomLevel)mZoom; +} + +/* +================ +rvGEWorkspace::ZoomOut + +Zooms the workspace out by one level +================ +*/ +rvGEWorkspace::EZoomLevel rvGEWorkspace::ZoomOut ( void ) +{ + mZoom--; + if ( mZoom <= ZOOM_MIN ) + { + mZoom = ZOOM_MIN + 1; + } + + UpdateScrollbars ( ); + UpdateTitle ( ); + + InvalidateRect ( mWnd, NULL, FALSE ); + + return (EZoomLevel)mZoom; +} + +/* +================ +rvGEWorkspace::CreateModifier + +Creates a new modifier of the given type for the given window. This function is called +specifically from the add modifiers function with the variable args list forwarded. +================ +*/ +rvGEModifier* rvGEWorkspace::CreateModifier ( EModifierType type, idWindow* window, va_list args ) +{ + rvGEModifier* mod; + + switch ( type ) + { + case MOD_DELETE: + mod = new rvGEDeleteModifier ( "Delete", window ); + break; + + case MOD_HIDE: + mod = new rvGEHideModifier ( "Hide", window, true ); + break; + + case MOD_UNHIDE: + mod = new rvGEHideModifier ( "Hide", window, false ); + break; + + case MOD_SEND_BACKWARD: + mod = new rvGEZOrderModifier ( "Send Backward", window, rvGEZOrderModifier::ZO_BACKWARD ); + break; + + case MOD_SEND_BACK: + mod = new rvGEZOrderModifier ( "Send to Back", window, rvGEZOrderModifier::ZO_BACK ); + break; + + case MOD_BRING_FORWARD: + mod = new rvGEZOrderModifier ( "Bring Forward", window, rvGEZOrderModifier::ZO_FORWARD ); + break; + + case MOD_BRING_FRONT: + mod = new rvGEZOrderModifier ( "Bring to Front", window, rvGEZOrderModifier::ZO_FRONT ); + break; + + default: + mod = NULL; + break; + } + + return mod; +} + +/* +================ +rvGEWorkspace::AddModifiers + +Add the specific modifier for the given window +================ +*/ +void rvGEWorkspace::AddModifiers ( idWindow* window, EModifierType type, ... ) +{ + va_list args; + + va_start(args,type) ; + mModifiers.Append ( CreateModifier ( type, window, args ) ); + va_end (args) ; + + SetModified ( true ); +} + +void rvGEWorkspace::AddModifiers ( EModifierType type, ... ) +{ + va_list args; + + // Nothing to move if there is no selection + if ( !mSelections.Num ( ) ) + { + return; + } + // More than one selection requires a modifier group + else if ( mSelections.Num ( ) > 1 ) + { + rvGEModifierGroup* group = new rvGEModifierGroup; + int i; + + for ( i = 0; i < mSelections.Num(); i ++ ) + { + va_start(args,type); + group->Append ( CreateModifier ( type, mSelections[i], args ) ); + va_end (args); + } + + mModifiers.Append ( group ); + } + // Single modifier + else + { + va_start(args,type) ; + mModifiers.Append ( CreateModifier ( type, mSelections[0], args ) ); + va_end (args) ; + } + + SetModified ( true ); +} + +bool rvGEWorkspace::BuildSelectMenuEnumProc ( rvGEWindowWrapper* wrapper, void* data ) +{ + rvGEWorkspace* workspace; + + workspace = (rvGEWorkspace*) data; + assert ( workspace ); + + if ( !wrapper ) + { + return true; + } + + wrapper->EnumChildren ( BuildSelectMenuEnumProc, data ); + + if ( wrapper->IsDeleted ( ) || wrapper->IsHidden ( ) ) + { + return true; + } + + if ( wrapper->GetScreenRect ( ).Contains ( workspace->mSelectMenuPos[0], workspace->mSelectMenuPos[1] ) ) + { + workspace->mSelectMenu.Append ( wrapper->GetWindow ( )); + } + + return true; +} + +bool rvGEWorkspace::ShowAllEnumProc ( rvGEWindowWrapper* wrapper, void* data ) +{ + rvGEModifierGroup* group = (rvGEModifierGroup*) data; + + wrapper->EnumChildren ( ShowAllEnumProc, data ); + + if ( wrapper->IsHidden ( ) ) + { + group->Append ( new rvGEHideModifier ( "Show Hidden", wrapper->GetWindow ( ), false ) ); + } + + return true; +} + +void rvGEWorkspace::AddModifierShowAll ( void ) +{ + rvGEModifierGroup* group = new rvGEModifierGroup; + + rvGEWindowWrapper::GetWrapper( mInterface->GetDesktop ( ) )->EnumChildren ( ShowAllEnumProc, group ); + + if ( !group->GetCount ( ) ) + { + delete group; + } + else + { + mModifiers.Append ( group ); + } + + mApplication->GetNavigator().Refresh ( ); +} + +void rvGEWorkspace::DeleteSelected ( void ) +{ + AddModifiers ( MOD_DELETE ); + mSelections.Clear ( ); + mApplication->GetNavigator().Update ( ); +} + +/* +================ +rvGEWorkspace::NewWindow + +Create a new window +================ +*/ +idWindow* rvGEWorkspace::NewWindow ( idDict* state, rvGEWindowWrapper::EWindowType type ) +{ + idWindow* window = new idWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + rvGEWindowWrapper* wrapper; + int count; + idStr baseName; + + switch ( type ) + { + case rvGEWindowWrapper::WT_NORMAL: + window = new idWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + break; + + case rvGEWindowWrapper::WT_BIND: + window = new idBindWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + break; + + case rvGEWindowWrapper::WT_RENDER: + window = new idRenderWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + break; + + case rvGEWindowWrapper::WT_CHOICE: + window = new idChoiceWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + break; + + case rvGEWindowWrapper::WT_EDIT: + window = new idEditWindow ( mInterface->GetDesktop()->GetDC(), mInterface ); + break; + + default: + assert ( false ); + return NULL; + } + + baseName = state ? state->GetString("name","unnamed") : "unnamed"; + baseName.StripQuotes ( ); + + count = 0; + if ( mInterface->GetDesktop()->FindChildByName ( baseName ) ) + { + count = 1; + while ( 1 ) + { + drawWin_t* dw = mInterface->GetDesktop()->FindChildByName ( va("%s%d",baseName.c_str(),count) ); + if ( !dw ) + { + break; + } + assert ( dw->win ); + wrapper = rvGEWindowWrapper::GetWrapper ( dw->win ); + if ( wrapper && wrapper->IsDeleted ( ) ) + { + break; + } + count++; + } + } + + idStr winName; + idStr winTemplate; + + if ( count ) + { + winName = va("%s%d", baseName.c_str(), count ); + } + else + { + winName = baseName; + } + winTemplate = winName + " { }"; + + idParser src( winTemplate, winTemplate.Length(), "", LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + window->Parse ( &src ); + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + + if ( state ) + { + wrapper->SetState ( *state ); + } + + wrapper->SetStateKey ( "name", winName ); + wrapper->Finish ( ); + + SetModified ( true ); + + + return window; +} + +idWindow* rvGEWorkspace::AddWindow ( rvGEWindowWrapper::EWindowType type ) +{ + idWindow* window; + idDict state; + + state.Set ( "rect", "0,0,100,100" ); + state.Set ( "visible", "1" ); + + window = NewWindow ( &state, type ); + assert ( window ); + + mModifiers.Append ( new rvGEInsertModifier ( "New", window, mInterface->GetDesktop(), NULL ) ); + + mSelections.Set ( window ); + mApplication->GetNavigator().Update ( ); + mApplication->GetTransformer().Update ( ); + mApplication->GetProperties().Update ( ); + + return window; +} + +bool rvGEWorkspace::EditSelectedProperties ( void ) +{ + if ( !mSelections.Num ( ) || mSelections.Num() > 1 ) + { + return false; + } + + idDict dict; + if ( GEItemPropsDlg_DoModal ( mWnd, mSelections[0], dict ) ) + { + mModifiers.Append ( new rvGEStateModifier ( "Item Properties", mSelections[0], dict ) ); + SetModified ( true ); + } + + mApplication->GetNavigator().Update ( ); + mApplication->GetTransformer().Update ( ); + mApplication->GetProperties().Update ( ); + + return true; +} + +bool rvGEWorkspace::EditSelectedScripts ( void ) +{ + if ( GEItemScriptsDlg_DoModal ( mWnd, mSelections[0] ) ) + { + gApp.GetNavigator().Refresh ( ); + SetModified ( true ); + } + + return true; +} + +void rvGEWorkspace::BringSelectedForward ( void ) +{ + AddModifiers ( MOD_BRING_FORWARD ); + mApplication->GetNavigator().Update ( ); +} + +void rvGEWorkspace::BringSelectedToFront ( void ) +{ + AddModifiers ( MOD_BRING_FRONT ); + mApplication->GetNavigator().Update ( ); +} + +void rvGEWorkspace::SendSelectedToBack ( void ) +{ + AddModifiers ( MOD_SEND_BACK ); + mApplication->GetNavigator().Update ( ); +} + +void rvGEWorkspace::SendSelectedBackward ( void ) +{ + AddModifiers ( MOD_SEND_BACKWARD ); + mApplication->GetNavigator().Update ( ); +} + +/* +================ +rvGEWorkspace::MakeSelectedSameSize + +Align the selected items to the first one using the given align type +================ +*/ +void rvGEWorkspace::MakeSelectedSameSize ( bool changeWidth, bool changeHeight ) +{ + rvGEModifierGroup* group; + idRectangle rectTo; + int i; + + group = new rvGEModifierGroup ( ); + + rectTo = rvGEWindowWrapper::GetWrapper ( mSelections[0] )->GetClientRect ( ); + + for ( i = 1; i < mSelections.Num(); i ++ ) + { + idRectangle rectFrom; + float width = 0; + float height = 0; + + rectFrom = rvGEWindowWrapper::GetWrapper(mSelections[i])->GetClientRect (); + + if ( changeWidth ) + { + width = rectTo.w - rectFrom.w; + } + + if ( changeHeight ) + { + height = rectTo.h - rectFrom.h; + } + + group->Append ( new rvGESizeModifier ( "Make Same Size", mSelections[i], 0, 0, width, height ) ); + } + + mModifiers.Append ( group ); + + // Cant merge alignments + mModifiers.BlockNextMerge ( ); + + SetModified ( true ); +} + +/* +================ +rvGEWorkspace::AlignSelected + +Align the selected items to the first one using the given align type +================ +*/ +void rvGEWorkspace::AlignSelected ( EItemAlign align ) +{ + static const char* alignNames[]={"Lefts","Centers","Rights","Tops","Middles","Bottoms" }; + int i; + idStr modName; + rvGEModifierGroup* group; + + assert ( mSelections.Num() > 1 ); + + modName = "Align " + idStr(alignNames[align]); + + group = new rvGEModifierGroup ( ); + + idRectangle rectTo; + rectTo = rvGEWindowWrapper::GetWrapper ( mSelections[0] )->GetScreenRect ( ); + + // Everything gets aligned to the first selection so run + // through all other selections and move them. + for ( i = 1; i < mSelections.Num(); i ++ ) + { + float x; + float y; + idRectangle rectFrom; + + rectFrom = rvGEWindowWrapper::GetWrapper ( mSelections[i] )->GetScreenRect ( ); + + switch ( align ) + { + case ALIGN_LEFTS: + x = rectTo[0] - rectFrom[0]; + y = 0; + break; + + case ALIGN_RIGHTS: + x = (rectTo[0]+rectTo[2]) - (rectFrom[0]+rectFrom[2]); + y = 0; + break; + + case ALIGN_CENTERS: + x = (rectTo[0]+rectTo[2]/2) - (rectFrom[0]+rectFrom[2]/2); + y = 0; + break; + + case ALIGN_TOPS: + y = rectTo[1] - rectFrom[1]; + x = 0; + break; + + case ALIGN_BOTTOMS: + x = 0; + y = (rectTo[1]+rectTo[3]) - (rectFrom[1]+rectFrom[3]); + break; + + case ALIGN_MIDDLES: + x = 0; + y = (rectTo[1]+rectTo[3]/2) - (rectFrom[1]+rectFrom[3]/2); + break; + + default: + assert ( false ); + break; + } + + group->Append ( new rvGEMoveModifier ( modName, mSelections[i], x, y ) ); + } + + mModifiers.Append ( group ); + + // Cant merge alignments + mModifiers.BlockNextMerge ( ); + + SetModified ( true ); +} + +/* +================ +rvGEWorkspace::AddModifierMove + +Adds a move modifier with the given offsets +================ +*/ +void rvGEWorkspace::AddModifierMove ( const char* modName, float x, float y, bool snap ) +{ + idRectangle scaleRect; + idRectangle newRect; + + scaleRect = mSelections.GetRect ( ); + WindowToWorkspace ( scaleRect ); + newRect = scaleRect; + newRect.x += x; + newRect.y += y; + + if ( snap ) + { + gApp.GetOptions ().SnapRectToGrid ( newRect, true, true, false, false ); + } + + rvGEModifierGroup* group = new rvGEModifierGroup; + for ( int i = 0; i < mSelections.Num(); i ++ ) + { + if ( !mSelections[i]->GetParent ( ) ) + { + continue; + } + + // IF the parent window is being moved around as well then dont move this one. + if ( rvGEWindowWrapper::GetWrapper ( mSelections[i]->GetParent ( ) )->IsSelected ( ) ) + { + // We still need the modifier there so the selection can be restored and + // so the rectangle gets updated + group->Append ( new rvGEMoveModifier ( modName, mSelections[i], 0, 0 ) ); + continue; + } + + group->Append ( new rvGEMoveModifier ( modName, mSelections[i], newRect.x-scaleRect.x, newRect.y-scaleRect.y ) ); + } + + mModifiers.Append ( group ); + + SetModified ( true ); +} + +/* +================ +rvGEWorkspace::AddModifierSize + +Adds a size modifier with the given offsets +================ +*/ +void rvGEWorkspace::AddModifierSize ( const char* modName, float l, float t, float r, float b, bool snap ) +{ + idRectangle scaleRect; + idRectangle sizeRect; + idRectangle newRect; + + scaleRect = mSelections.GetRect ( ); + WindowToWorkspace ( scaleRect ); + newRect = scaleRect; + newRect.x += l; + newRect.y += t; + newRect.w += (r - l); + newRect.h += (b - t); + + // Restrict sizing below 1 width + if ( newRect.w <= 1 ) + { + newRect.x = newRect.x - (l ? (1 - newRect.w) : 0); + mDragPoint.x = newRect.x; + newRect.w = 1; + mDragX = false; + } + else + { + mDragX = true; + } + + // Restrict sizing below 1 height + if ( newRect.h <= 1 ) + { + newRect.y = newRect.y - (t ? (1 - newRect.h) : 0); + mDragPoint.y = newRect.y; + newRect.h = 1; + mDragY = false; + } + else + { + mDragY = true; + } + + if ( snap ) + { + gApp.GetOptions ().SnapRectToGrid ( newRect, l != 0.0f, t != 0.0f, r != 0.0f, b != 0.0f ); + } + + rvGEModifierGroup* group = new rvGEModifierGroup; + for ( int i = 0; i < mSelections.Num(); i ++ ) + { + sizeRect = rvGEWindowWrapper::GetWrapper ( mSelections[i] )->GetScreenRect ( ); + + l = (newRect.x + ((sizeRect.x - scaleRect.x) / scaleRect.w) * newRect.w) - sizeRect.x; + t = (newRect.y + ((sizeRect.y - scaleRect.y) / scaleRect.h) * newRect.h) - sizeRect.y; + r = (sizeRect.w / scaleRect.w * newRect.w) - sizeRect.w + l; + b = (sizeRect.h / scaleRect.h * newRect.h) - sizeRect.h + t; + + // This is sorta crufty but needs to be done. When a parent is being sized at the same + // time as a child you will get double movement because the child is relative to the parent. Therefore + // we need to subtract out the closest parents sizing. + idWindow* parent = mSelections[i]; + while ( NULL != (parent = parent->GetParent ( ) ) ) + { + rvGEWindowWrapper* pwrapper = rvGEWindowWrapper::GetWrapper ( parent ); + float offset; + + if ( !pwrapper->IsSelected ( ) ) + { + continue; + } + + sizeRect = pwrapper->GetScreenRect ( ); + + // Subtract out the left and right modifications + offset = ((newRect.x + ((sizeRect.x - scaleRect.x) / scaleRect.w) * newRect.w) - sizeRect.x); + l -= offset; + r -= offset; + + // Subtract out the top and bottom modifications + offset = ((newRect.y + ((sizeRect.y - scaleRect.y) / scaleRect.h) * newRect.h) - sizeRect.y); + t -= offset; + b -= offset; + + break; + } + + group->Append ( new rvGESizeModifier ( modName, mSelections[i], l, t, r, b ) ); + } + + mModifiers.Append ( group ); + + SetModified ( true ); +} + +/* +================ +rvGEWorkspace::MakeSelectedAChild + +Makes the selected windows a child of the first selected window +================ +*/ +void rvGEWorkspace::MakeSelectedAChild ( void ) +{ + rvGEModifierGroup* group; + int i; + + if ( !rvGEWindowWrapper::GetWrapper ( mSelections[0] )->CanHaveChildren ( ) ) + { + gApp.MessageBox ( "Cannot add children to an htmlDef item", MB_OK|MB_ICONERROR ); + return; + } + + group = new rvGEModifierGroup; + + for ( i = 1; i < mSelections.Num(); i ++ ) + { + if ( mSelections[i]->GetParent ( ) == mSelections[0] ) + { + continue; + } + + if ( !mSelections[i]->GetParent ( ) ) + { + continue; + } + + group->Append ( new rvGEInsertModifier ( "Make Child", mSelections[i], mSelections[0], NULL ) ); + } + + mModifiers.Append ( group ); + + // Navigator needs an update since the ordering has changed + gApp.GetNavigator().Update ( ); + + SetModified ( true ); +} + +void rvGEWorkspace::Copy ( void ) +{ + int i; + + // Clear the current clipboard + for ( i = 0; i < mClipboard.Num(); i ++ ) + { + delete mClipboard[i]; + } + + mClipboard.Clear ( ); + + for ( i = 0; i < mSelections.Num(); i ++ ) + { + rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( mSelections[i] ); + assert ( wrapper ); + + rvGEClipboardItem* item = new rvGEClipboardItem; + item->mStateDict = wrapper->GetStateDict ( ); + item->mScriptDict = wrapper->GetScriptDict ( ); + item->mVarDict = wrapper->GetVariableDict ( ); + + item->mStateDict.Set ( "windowType", rvGEWindowWrapper::WindowTypeToString ( wrapper->GetWindowType ( ) ) ); + + mClipboard.Append ( item ); + } +} + +void rvGEWorkspace::Paste ( void ) +{ + int i; + + rvGEModifierGroup* group = new rvGEModifierGroup; + + mSelections.Clear ( ); + + for ( i = 0; i < mClipboard.Num(); i ++ ) + { + idDict state; + rvGEWindowWrapper::EWindowType type; + + state.Copy ( mClipboard[i]->mStateDict ); + type = rvGEWindowWrapper::StringToWindowType ( state.GetString ( "windowType", "windowDef" ) ); + state.Delete ( "windowType" ); + + idWindow* window = NewWindow ( &state, type ); + group->Append ( new rvGEInsertModifier ( "Paste", window, mInterface->GetDesktop(), NULL ) ); + mSelections.Add ( window ); + + rvGEWindowWrapper::GetWrapper ( window )->GetScriptDict ( ) = mClipboard[i]->mScriptDict; + rvGEWindowWrapper::GetWrapper ( window )->GetVariableDict ( ) = mClipboard[i]->mVarDict; + } + + mModifiers.Append ( group ); + + mApplication->GetNavigator().Update ( ); + + SetModified ( true ); +} + +void rvGEWorkspace::HideSelected ( void ) +{ + AddModifiers ( MOD_HIDE ); + mSelections.Clear ( ); + mApplication->GetNavigator().Refresh ( ); +} + +void rvGEWorkspace::UnhideSelected ( void ) +{ + AddModifiers ( MOD_UNHIDE ); + mApplication->GetNavigator().Refresh ( ); +} + +void rvGEWorkspace::HideWindow ( idWindow* window ) +{ + AddModifiers ( window, MOD_HIDE ); + mApplication->GetNavigator().Refresh ( ); +} + +void rvGEWorkspace::UnhideWindow ( idWindow* window ) +{ + AddModifiers ( window, MOD_UNHIDE ); + mApplication->GetNavigator().Refresh ( ); +} + +/* +================ +rvGEWorkspace::SetModified + +Sets the modified state of the window and if source control is enabled it +will attempt to check out the file +================ +*/ +void rvGEWorkspace::SetModified ( bool mod ) +{ + if ( mModified != mod ) + { + + mModified = mod; + UpdateTitle ( ); + + } +} diff --git a/tools/guied/GEWorkspace.h b/tools/guied/GEWorkspace.h new file mode 100644 index 000000000..8d7086c8d --- /dev/null +++ b/tools/guied/GEWorkspace.h @@ -0,0 +1,329 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef _GEWORKSPACE_H_ +#define _GEWORKSPACE_H_ + +#ifndef GESELECTIONMGR_H_ +#include "GESelectionMgr.h" +#endif // GESELECTIONMGR_H_ + +#ifndef GEMODIFIERSTACK_H_ +#include "GEModifierStack.h" +#endif // GEMODIFIERSTACK_H_ + +class rvGEApp; + +class rvGEClipboardItem +{ +public: + + idDict mStateDict; + idDict mScriptDict; + idDict mVarDict; +}; + +class rvGEWorkspace +{ +public: + + enum ESourceControlState + { + SCS_NONE, + SCS_CHECKEDOUT, + SCS_CHECKEDIN, + }; + + enum EZoomLevel + { + ZOOM_MIN, + ZOOM_25, + ZOOM_33, + ZOOM_50, + ZOOM_66, + ZOOM_100, + ZOOM_150, + ZOOM_200, + ZOOM_300, + ZOOM_MAX + }; + + enum EItemAlign + { + ALIGN_LEFTS, + ALIGN_CENTERS, + ALIGN_RIGHTS, + ALIGN_TOPS, + ALIGN_MIDDLES, + ALIGN_BOTTOMS, + }; + + rvGEWorkspace ( rvGEApp* app ); + ~rvGEWorkspace ( ); + + // Attach the workspace to a win32 window + bool Attach ( HWND wnd ); + + // Detach the workspace from the current win32 window + void Detach ( void ); + + bool NewFile ( void ); + bool LoadFile ( const char* filename, idStr* error = NULL ); + bool SaveFile ( const char* filename ); + const char* GetFilename ( void ); + + // Source control methods + bool CheckOut ( void ); + bool CheckIn ( void ); + bool UndoCheckout ( void ); + ESourceControlState GetSourceControlState ( void ); + + void Render ( HDC hDC ); + + rvGEApp* GetApplication ( void ); + + void HideSelected ( void ); + void UnhideSelected ( void ); + void DeleteSelected ( void ); + bool EditSelectedProperties ( void ); + bool EditSelectedScripts ( void ); + void BringSelectedForward ( void ); + void BringSelectedToFront ( void ); + void SendSelectedBackward ( void ); + void SendSelectedToBack ( void ); + void AlignSelected ( EItemAlign align ); + void MakeSelectedSameSize ( bool width, bool height ); + void MakeSelectedAChild ( void ); + + bool CanHide ( void ); + void ShowHidden ( void ); + void HideWindow ( idWindow* window ); + void UnhideWindow ( idWindow* window ); + + EZoomLevel ZoomIn ( void ); + EZoomLevel ZoomOut ( void ); + EZoomLevel GetZoom ( void ); + float GetZoomScale ( void ); + + static rvGEWorkspace* GetWorkspace ( HWND wnd ); + rvGEModifierStack& GetModifierStack ( void ); + idUserInterfaceLocal* GetInterface ( void ); + rvGESelectionMgr& GetSelectionMgr ( void ); + idList GetClipboard ( void ); + HWND GetWindow ( void ); + + void HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam ); + + idVec2& WindowToWorkspace ( idVec2& point ); + idVec2& WorkspaceToWindow ( idVec2& point ); + idRectangle& WindowToWorkspace ( idRectangle& rect ); + idRectangle& WorkspaceToWindow ( idRectangle& rect ); + + bool IsModified ( void ); + bool IsNew ( void ); + + idWindow* AddWindow ( rvGEWindowWrapper::EWindowType type ); + +// void Cut ( void ); + void Copy ( void ); + void Paste ( void ); + + void AddModifierMove ( const char* modName, float x, float y, bool snap ); + void AddModifierSize ( const char* modName, float l, float t, float r, float b, bool snap ); + + void SetModified ( bool mod ); + +protected: + + enum EModifierType + { + MOD_UNKNOWN, + MOD_DELETE, + MOD_HIDE, + MOD_UNHIDE, + MOD_SHOWHIDDEN, + MOD_SEND_BACKWARD, + MOD_BRING_FORWARD, + MOD_SEND_BACK, + MOD_BRING_FRONT, + }; + + bool SetupPixelFormat ( void ); + void UpdateSelections ( void ); + + // Additional rendering routines + void RenderGrid ( void ); + + // File related methods + void WriteTabs ( idFile* file, int depth ); + bool WriteWindow ( idFile* file, int depth, idWindow* window ); + + // Message handlers + int HandleRButtonDown ( WPARAM wParam, LPARAM lParam ); + int HandleLButtonDown ( WPARAM wParam, LPARAM lParam ); + int HandleLButtonUp ( WPARAM wParam, LPARAM lParam ); + int HandleLButtonDblClk ( WPARAM wParam, LPARAM lParam ); + int HandleMButtonDown ( WPARAM wParam, LPARAM lParam ); + int HandleMButtonUp ( WPARAM wParam, LPARAM lParam ); + int HandleMouseMove ( WPARAM wParam, LPARAM lParam ); + int HandleKeyDown ( WPARAM wParam, LPARAM lParam ); + int HandleScroll ( int scrollbar, WPARAM wParam, LPARAM lParam ); + int HandleCommand ( WPARAM wParam, LPARAM lParam ); + + // General protected functions + void UpdateScrollbars ( void ); + void UpdateRectangle ( bool useScroll = true ); + void UpdateCursor ( void ); + void UpdateCursor ( float x, float y ); + void UpdateCursor ( rvGESelectionMgr::EHitTest type ); + void UpdateTitle ( void ); + idWindow* NewWindow ( idDict* state, rvGEWindowWrapper::EWindowType type ); + void Scroll ( int scrollbar, int offset ); + + // Modifier methods + void AddModifierMoveNudge( float x, float y, bool snap ); + void AddModifierSizeNudge( float w, float h, bool snap ); + void AddModifierShowAll ( void ); + + void AddModifiers ( EModifierType type, ... ); + void AddModifiers ( idWindow* window, EModifierType type, ... ); + rvGEModifier* CreateModifier ( EModifierType type, idWindow* window, va_list args ); + + idUserInterfaceLocal* mInterface; + HWND mWnd; + + int mZoom; + idRectangle mRect; + + bool mScrollHorz; + bool mScrollVert; + + int mWindowWidth; + int mWindowHeight; + + idStr mFilename; + + rvGEModifierStack mModifiers; + rvGESelectionMgr mSelections; + + rvGESelectionMgr::EHitTest mDragType; + idVec2 mDragPoint; + int mDragTime; + bool mDragX; + bool mDragY; + bool mDragScroll; + + rvGEApp* mApplication; + + static idList mClipboard; + idList mSelectMenu; + idVec2 mSelectMenuPos; + +private: + + static bool CleanupEnumProc ( rvGEWindowWrapper* wrapper, void* data ); + static bool ShowAllEnumProc ( rvGEWindowWrapper* wrapper, void* data ); + static bool BuildSelectMenuEnumProc ( rvGEWindowWrapper* wrapper, void* data ); + + // States + bool mModified; + bool mNew; + bool mDontAdd; + ESourceControlState mSourceControlState; + + // Resources + HCURSOR mHandCursor; +}; + +ID_INLINE rvGEWorkspace::EZoomLevel rvGEWorkspace::GetZoom ( void ) +{ + return (EZoomLevel)mZoom; +} + +ID_INLINE rvGEWorkspace* rvGEWorkspace::GetWorkspace ( HWND wnd ) +{ + return (rvGEWorkspace*) GetWindowLong ( wnd, GWL_USERDATA ); +} + +ID_INLINE const char* rvGEWorkspace::GetFilename ( void ) +{ + return mFilename; +} + +ID_INLINE bool rvGEWorkspace::IsModified ( void ) +{ + return mModified; +} + +ID_INLINE bool rvGEWorkspace::IsNew ( void ) +{ + return mNew; +} + +ID_INLINE rvGEModifierStack& rvGEWorkspace::GetModifierStack ( void ) +{ + return mModifiers; +} + +ID_INLINE rvGESelectionMgr& rvGEWorkspace::GetSelectionMgr ( void ) +{ + return mSelections; +} + +ID_INLINE void rvGEWorkspace::ShowHidden ( void ) +{ + AddModifierShowAll ( ); +} + +ID_INLINE void rvGEWorkspace::AddModifierMoveNudge ( float x, float y, bool snap ) +{ + AddModifierMove ( "Nudge Move", x, y, snap ); +} + +ID_INLINE void rvGEWorkspace::AddModifierSizeNudge ( float w, float h, bool snap ) +{ + AddModifierSize ( "Nudge Size", 0, 0, w, h, snap ); +} + +ID_INLINE idUserInterfaceLocal* rvGEWorkspace::GetInterface ( void ) +{ + return mInterface; +} + +ID_INLINE rvGEApp* rvGEWorkspace::GetApplication ( void ) +{ + return mApplication; +} + +ID_INLINE HWND rvGEWorkspace::GetWindow ( void ) +{ + return mWnd; +} + +ID_INLINE idList rvGEWorkspace::GetClipboard ( void ) +{ + return mClipboard; +} + +ID_INLINE rvGEWorkspace::ESourceControlState rvGEWorkspace::GetSourceControlState ( void ) +{ + return mSourceControlState; +} + +#endif // _GEWORKSPACE_H_ diff --git a/tools/guied/GEWorkspaceFile.cpp b/tools/guied/GEWorkspaceFile.cpp new file mode 100644 index 000000000..f172d7c86 --- /dev/null +++ b/tools/guied/GEWorkspaceFile.cpp @@ -0,0 +1,386 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" + +bool GECheckInDlg_DoModal ( HWND parent, const char* filename, idStr* comment ); + +/* +================ +rvGEWorkspace::SaveFile + +Writes the contents of the open gui file to disk +================ +*/ +bool rvGEWorkspace::SaveFile ( const char* filename ) +{ + idFile* file; + idWindow* window; + + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT ) ) ); + + mFilename = filename; + + // Since quake can only write to its path we will write a temp file then copy it over + idStr tempfile; + idStr ospath; + + tempfile = "guis/temp.guied"; + ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" ); + + // Open the output file for write + if ( !(file = fileSystem->OpenFileWrite ( tempfile ) ) ) + { + int error = GetLastError ( ); + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) ); + return false; + } + + window = mInterface->GetDesktop ( ); + + WriteWindow ( file, 1, window ); + + fileSystem->CloseFile ( file ); + + if ( !CopyFile ( ospath, filename, FALSE ) ) + { + DeleteFile ( ospath ); + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) ); + return false; + } + + DeleteFile ( ospath ); + + mFilename = filename; + mModified = false; + mNew = false; + UpdateTitle ( ); + + SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) ); + + return true; +} + +/* +================ +rvGEWorkspace::WriteTabs + +Writes the given number of tabs to the given file +================ +*/ +void rvGEWorkspace::WriteTabs ( idFile* file, int depth ) +{ + int i; + + for ( i = 0; i < depth; i ++ ) + { + file->Write ( "\t", 1 ); + } +} + +/* +================ +rvGEWorkspace::WriteWindow + +Writes the contents of the given window to the file +================ +*/ +bool rvGEWorkspace::WriteWindow ( idFile* file, int depth, idWindow* window ) +{ + idStr out; + rvGEWindowWrapper* wrapper; + int i; + + wrapper = rvGEWindowWrapper::GetWrapper ( window ); + if ( !wrapper ) + { + return true; + } + + if ( wrapper->IsDeleted ( ) ) + { + return true; + } + + // Window def header + WriteTabs ( file, depth - 1 ); + + out = wrapper->WindowTypeToString ( wrapper->GetWindowType ( ) ); + out.Append ( " " ); + file->Write ( out, out.Length() ); + + out = window->GetName ( ); + file->Write ( out, out.Length() ); + file->Write ( "\r\n", 2 ); + + WriteTabs ( file, depth - 1 ); + + out = "{\r\n"; + file->Write ( out, out.Length() ); + file->ForceFlush ( ); + + for ( i = 0; i < wrapper->GetStateDict().GetNumKeyVals(); i ++ ) + { + const idKeyValue* key = wrapper->GetStateDict().GetKeyVal ( i ); + + // Dont write name to the files + if ( !key->GetKey().Icmp ( "name" ) ) + { + continue; + } + + WriteTabs ( file, depth ); + + out = key->GetKey(); + out.Append ( "\t" ); + file->Write ( out, out.Length() ); + + const char* p; + for ( p = key->GetValue().c_str(); *p; p ++ ) + { + switch ( *p ) + { + case '\n': + file->Write ( "\\n", 2 ); + break; + + default: + file->Write ( p, 1 ); + break; + } + } + + file->Write ( "\r\n", 2 ); + } + + for ( i = 0; i < wrapper->GetVariableDict().GetNumKeyVals(); i ++ ) + { + const idKeyValue* key = wrapper->GetVariableDict().GetKeyVal ( i ); + + WriteTabs ( file, depth ); + + out = key->GetKey(); + out.Append ( "\t" ); + out.Append ( key->GetValue() ); + out.Append ( "\r\n" ); + + file->Write ( out, out.Length() ); + } + + if ( wrapper->GetScriptDict().GetNumKeyVals() ) + { + file->Write ( "\r\n", 2 ); + } + + for ( i = 0; i < wrapper->GetScriptDict().GetNumKeyVals(); i ++ ) + { + const idKeyValue* key = wrapper->GetScriptDict().GetKeyVal ( i ); + + WriteTabs ( file, depth ); + + file->Write ( key->GetKey(), key->GetKey().Length() ); + file->Write ( " ", 1 ); + + idLexer src( key->GetValue(), key->GetValue().Length(), "", LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + src.ParseBracedSectionExact ( out, depth + 1); + + file->Write ( out, out.Length() ); + file->Write ( "\r\n", 2 ); + file->Write ( "\r\n", 2 ); + } + + for ( i = 0; i < wrapper->GetChildCount(); i ++ ) + { + idWindow* child = wrapper->GetChild ( i ); + + WriteWindow ( file, depth + 1, child ); + } + + // Window def footer + WriteTabs ( file, depth - 1 ); + + out = "}\r\n"; + file->Write ( out, out.Length() ); + file->ForceFlush ( ); + + return true; +} + +/* +================ +rvGEWorkspace::NewFile + +Opens a new file for editing +================ +*/ +bool rvGEWorkspace::NewFile ( void ) +{ + idStr empty; + idStr ospath; + idFile* file; + + // Make a temporary file with nothing in it so we can just use + // load to do all the work + ospath = fileSystem->RelativePathToOSPath ( "guis/Untitled.guiednew", "fs_basepath" ); + DeleteFile ( ospath ); + + file = fileSystem->OpenFileWrite ( "guis/Untitled.guiednew" ); + if ( NULL == file ) + { + return false; + } + + empty = "windowDef Desktop { rect 0,0,640,480 }"; + file->Write ( empty, empty.Length() ); + fileSystem->CloseFile ( file ); + + // Load the temporary file + if ( !LoadFile ( ospath, NULL ) ) + { + // Ensure the temp file doesnt hang around + DeleteFile ( ospath ); + return false; + } + + mNew = true; + + // Ensure the temp file doesnt hang around + DeleteFile ( ospath ); + + // Go back to using a .gui extensions + ospath.StripFileExtension ( ); + ospath.Append ( ".gui" ); + + mFilename = ospath; + + return true; +} + +/* +================ +rvGEWorkspace::LoadFile + +Loads the given gui file. +================ +*/ +bool rvGEWorkspace::LoadFile ( const char* filename, idStr* error ) +{ + delete mInterface; + + idStr tempfile; + idStr ospath; + bool result; + + tempfile = "guis/temp.guied"; + ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" ); + + // Make sure the gui directory exists + idStr createDir = ospath; + createDir.StripFilename ( ); + CreateDirectory ( createDir, NULL ); + + SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL ); + DeleteFile ( ospath ); + if ( !CopyFile ( filename, ospath, FALSE ) ) + { + if ( error ) + { + *error = "File not found"; + } + return false; + } + + SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL ); + + mFilename = filename; + UpdateTitle ( ); + + // Let the real window system parse it first + mInterface = NULL; + result = true; + try + { + mInterface = reinterpret_cast< idUserInterfaceLocal* >( uiManager->FindGui( tempfile, true, true ) ); + if ( !mInterface && error ) + { + *error = "File not found"; + } + } + catch ( idException& e ) + { + result = false; + if ( error ) + { + *error = e.error; + } + return false; + } + + if ( result ) + { + rvGEWindowWrapper::GetWrapper ( mInterface->GetDesktop ( ) )->Expand ( ); + } + else + { + DeleteFile ( ospath ); + } + + return result; +} + +/* +================ +rvGEWorkspace::CheckIn + +Checks in the current workspace file into source control +================ +*/ +bool rvGEWorkspace::CheckIn ( void ) +{ + return false; + +} + +/* +================ +rvGEWorkspace::CheckOut + +Checks out the current workspace file from source control +================ +*/ +bool rvGEWorkspace::CheckOut ( void ) +{ + return false; +} + +/* +================ +rvGEWorkspace::UndoCheckout + +Undoes the checkout of the current file +================ +*/ +bool rvGEWorkspace::UndoCheckout ( void ) +{ + return false; +} + diff --git a/tools/guied/GEZOrderModifier.cpp b/tools/guied/GEZOrderModifier.cpp new file mode 100644 index 000000000..0fca4f46c --- /dev/null +++ b/tools/guied/GEZOrderModifier.cpp @@ -0,0 +1,120 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "GEApp.h" +#include "GEZOrderModifier.h" + + +rvGEZOrderModifier::rvGEZOrderModifier ( const char* name, idWindow* window, EZOrderChange change ) : + rvGEModifier ( name, window ) +{ + int count; + int index; + idWindow* parent; + + parent = window->GetParent ( ); + if ( !parent ) + { + return; + } + + count = parent->GetChildCount ( ); + index = parent->GetChildIndex ( mWindow ); + + if ( index + 1 >= count ) + { + mUndoBefore = NULL; + } + else + { + mUndoBefore = parent->GetChild ( index + 1 ); + } + + switch ( change ) + { + case ZO_FORWARD: + index+=2; + break; + + case ZO_BACKWARD: + if ( index == 0 ) + { + index = 1; + } + else + { + index-=1; + } + break; + + case ZO_BACK: + index = 0; + break; + + case ZO_FRONT: + index = count; + break; + } + + if ( index >= count ) + { + mBefore = NULL; + } + else + { + mBefore = parent->GetChild ( index ); + } +} + +bool rvGEZOrderModifier::Apply ( void ) +{ + idWindow* parent; + + parent = mWindow->GetParent ( ); + + parent->RemoveChild ( mWindow ); + parent->InsertChild ( mWindow, mBefore ); + + return true; +} + +bool rvGEZOrderModifier::Undo ( void ) +{ + idWindow* parent; + + parent = mWindow->GetParent ( ); + + parent->RemoveChild ( mWindow ); + parent->InsertChild ( mWindow, mUndoBefore ); + + return true; +} + +bool rvGEZOrderModifier::IsValid ( void ) +{ + if ( !mWindow->GetParent ( ) ) + { + return false; + } + + return true; +} diff --git a/tools/guied/GEZOrderModifier.h b/tools/guied/GEZOrderModifier.h new file mode 100644 index 000000000..04ad51348 --- /dev/null +++ b/tools/guied/GEZOrderModifier.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef GEZORDERMODIFIER_H_ +#define GEZORDERMODIFIER_H_ + +#ifndef GEMODIFIER_H_ +#include "GEModifier.h" +#endif + +class rvGEZOrderModifier : public rvGEModifier +{ +public: + + enum EZOrderChange + { + ZO_FORWARD, + ZO_BACKWARD, + ZO_FRONT, + ZO_BACK, + }; + + rvGEZOrderModifier ( const char* name, idWindow* window, EZOrderChange change ); + + virtual bool Apply ( void ); + virtual bool Undo ( void ); + virtual bool IsValid ( void ); + +protected: + + idWindow* mBefore; + idWindow* mUndoBefore; +}; + +#endif // GEZORDERMODIFIER_H_ \ No newline at end of file diff --git a/tools/guied/guied.cpp b/tools/guied/guied.cpp new file mode 100644 index 000000000..dfe154d61 --- /dev/null +++ b/tools/guied/guied.cpp @@ -0,0 +1,190 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../renderer/tr_local.h" +#include "../../sys/win32/win_local.h" +#include + +#include "../../ui/DeviceContext.h" +#include "../../sys/win32/rc/guied_resource.h" + +#include "GEApp.h" + +rvGEApp gApp; + +/* +================ +GUIEditorInit + +Start the gui editor +================ +*/ +void GUIEditorInit( void ) +{ + gApp.Initialize(); +} + +/* +================ +GUIEditorShutdown +================ +*/ +void GUIEditorShutdown( void ) { +} + +/* +================ +GUIEditorHandleMessage + +Handle translator messages +================ +*/ +bool GUIEditorHandleMessage ( void *msg ) +{ + if ( !gApp.IsActive ( ) ) + { + return false; + } + + return gApp.TranslateAccelerator( reinterpret_cast(msg) ); +} + +/* +================ +GUIEditorRun + +Run a frame +================ +*/ +void GUIEditorRun() +{ + MSG msg; + + // pump the message loop + while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if ( !GetMessage (&msg, NULL, 0, 0) ) + { + common->Quit(); + } + + // save the msg time, because wndprocs don't have access to the timestamp + if ( win32.sysMsgTime && win32.sysMsgTime > (int)msg.time ) + { + } + else + { + win32.sysMsgTime = msg.time; + } + + if ( gApp.TranslateAccelerator ( &msg ) ) + { + continue; + } + + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + gApp.RunFrame ( ); + + // The GUI editor runs too hot so we need to slow it down a bit. + Sleep ( 1 ); +} + +/* +================ +StringFromVec4 + +Returns a clean string version of the given vec4 +================ +*/ +const char *StringFromVec4 ( idVec4& v ) +{ + return va( "%s,%s,%s,%s", + idStr::FloatArrayToString( &v[0], 1, 8 ), + idStr::FloatArrayToString( &v[1], 1, 8 ), + idStr::FloatArrayToString( &v[2], 1, 8 ), + idStr::FloatArrayToString( &v[3], 1, 8 ) ); +} + +/* +================ +IsExpression + +Returns true if the given string is an expression +================ +*/ +bool IsExpression ( const char* s ) +{ + idParser src( s, strlen ( s ), "", + LEXFL_ALLOWMULTICHARLITERALS | + LEXFL_NOSTRINGCONCAT | + LEXFL_ALLOWBACKSLASHSTRINGCONCAT | + LEXFL_NOFATALERRORS ); + + idToken token; + bool needComma = false; + bool needNumber = false; + while ( src.ReadToken ( &token ) ) + { + switch ( token.type ) + { + case TT_NUMBER: + needComma = true; + needNumber = false; + break; + + case TT_PUNCTUATION: + if ( needNumber ) + { + return true; + } + if ( token[0] == ',' ) + { + if ( !needComma ) + { + return true; + } + + needComma = false; + break; + } + + if ( needComma ) + { + return true; + } + + if ( token[0] == '-' ) + { + needNumber = true; + } + break; + + default: + return true; + } + } + + return false; +} diff --git a/tools/materialeditor/ConsoleView.cpp b/tools/materialeditor/ConsoleView.cpp new file mode 100644 index 000000000..c09f0361b --- /dev/null +++ b/tools/materialeditor/ConsoleView.cpp @@ -0,0 +1,290 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "ConsoleView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +#define EDIT_HEIGHT 25 + + +IMPLEMENT_DYNCREATE(ConsoleView, CFormView) + +BEGIN_MESSAGE_MAP(ConsoleView, CFormView) + ON_WM_SIZE() +END_MESSAGE_MAP() + +/** +* Constructor for ConsoleView. +*/ +ConsoleView::ConsoleView() +: CFormView(ConsoleView::IDD) { +} + +/** +* Destructor for ConsoleView. +*/ +ConsoleView::~ConsoleView() { +} + +/** +* Adds text to the end of the console output window. +* @param msg The text to append. +* \todo: BMatt Nerve: Fix scroll code so the output window will scroll as text +* is added if the cursor is at the end of the window. +*/ +void ConsoleView::AddText( const char *msg ) { + + if(!editConsole.GetSafeHwnd()) + return; + + idStr work; + CString work2; + + work = msg; + work.RemoveColors(); + work = TranslateString( work.c_str() ); + + editConsole.GetWindowText( work2 ); + int len = work2.GetLength(); + if ( len + work.Length() > (int)editConsole.GetLimitText() ) { + work2 = work2.Right( editConsole.GetLimitText() * .75f ); + len = work2.GetLength(); + editConsole.SetWindowText(work2); + } + editConsole.SetSel( len, len ); + editConsole.ReplaceSel( work ); + + //Hack: scrolls down a bit + editConsole.LineScroll(100); +} + +/** +* Replaces the text in the console window with the specified text. +* @param text The text to place in the console window. +*/ +void ConsoleView::SetConsoleText ( const idStr& text ) { + editInput.Clear (); + editInput.SetWindowText ( text.c_str() ); +} + +/** +* Executes the specified console command. If the command is passed +* as a parameter then it is executed otherwise the command in the +* input box is executed. +* @param cmd The text to execute. If this string is empty then the +* input edit box text is used. +*/ +void ConsoleView::ExecuteCommand ( const idStr& cmd ) { + + CString str; + if ( cmd.Length() > 0 ) { + str = cmd; + } + else { + editInput.GetWindowText(str); + } + + if ( str != "" ) { + editInput.SetWindowText(""); + common->Printf("%s\n", str.GetBuffer(0)); + + //avoid adding multiple identical commands in a row + int index = consoleHistory.Num (); + + if ( index == 0 || str.GetBuffer(0) != consoleHistory[index-1]) { + //keep the history to 16 commands, removing the oldest command + if ( consoleHistory.Num () > 16 ) { + consoleHistory.RemoveIndex ( 0 ); + } + currentHistoryPosition = consoleHistory.Append ( str.GetBuffer (0) ); + } + else { + currentHistoryPosition = consoleHistory.Num () - 1; + } + + currentCommand.Clear (); + + bool propogateCommand = true; + + //process some of our own special commands + if ( str.CompareNoCase ( "clear" ) == 0) { + editConsole.SetSel ( 0 , -1 ); + editConsole.Clear (); + } + else if ( str.CompareNoCase ( "edit" ) == 0) { + propogateCommand = false; + } + if ( propogateCommand ) { + cmdSystem->BufferCommandText(CMD_EXEC_NOW, str); + } + } +} + +/** +* Handles keyboard input to process the "Enter" key to execute +* commands and command history. +*/ +BOOL ConsoleView::PreTranslateMessage(MSG* pMsg) { + + if (pMsg->hwnd == editInput.GetSafeHwnd()) { + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + this->ExecuteCommand(); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_UP ) { + //save off the current in-progress command so we can get back to it + if ( saveCurrentCommand == true ) { + CString str; + editInput.GetWindowText ( str ); + currentCommand = str.GetBuffer ( 0 ); + saveCurrentCommand = false; + } + + if ( consoleHistory.Num () > 0 ) { + editInput.SetWindowText ( consoleHistory[currentHistoryPosition] ); + + int selLocation = consoleHistory[currentHistoryPosition].Length (); + editInput.SetSel ( selLocation , selLocation + 1); + } + + if ( currentHistoryPosition > 0) { + --currentHistoryPosition; + } + + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DOWN ) { + int selLocation = 0; + if ( currentHistoryPosition < consoleHistory.Num () - 1 ) { + ++currentHistoryPosition; + editInput.SetWindowText ( consoleHistory[currentHistoryPosition] ); + selLocation = consoleHistory[currentHistoryPosition].Length (); + } + else { + editInput.SetWindowText ( currentCommand ); + selLocation = currentCommand.Length (); + currentCommand.Clear (); + saveCurrentCommand = true; + } + + editInput.SetSel ( selLocation , selLocation + 1); + + return TRUE; + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB ) { + common->Printf ( "Command History\n----------------\n" ); + for ( int i = 0 ; i < consoleHistory.Num ();i++ ) + { + common->Printf ( "[cmd %d]: %s\n" , i , consoleHistory[i].c_str() ); + } + common->Printf ( "----------------\n" ); + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_NEXT) { + editConsole.LineScroll ( 10 ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_PRIOR ) { + editConsole.LineScroll ( -10 ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_HOME ) { + editConsole.LineScroll ( -editConsole.GetLineCount() ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_END ) { + editConsole.LineScroll ( editConsole.GetLineCount() ); + } + } + + return CFormView::PreTranslateMessage(pMsg); +} + +/** +* Transfers data to and from the controls in the console. +*/ +void ConsoleView::DoDataExchange(CDataExchange* pDX) { + CFormView::DoDataExchange(pDX); + + DDX_Control(pDX, IDC_CONSOLE_OUTPUT, editConsole); + DDX_Control(pDX, IDC_CONSOLE_EDIT, editInput); +} + +/** +* Transfers data to and from the controls in the console. +*/ +void ConsoleView::OnInitialUpdate() { + + CFormView::OnInitialUpdate(); + + CRect rect; + GetWindowRect(rect); + + if(editConsole.m_hWnd) + editConsole.MoveWindow(0, 0, rect.Width(), rect.Height()-EDIT_HEIGHT); + + if(editInput.m_hWnd) + editInput.MoveWindow(0, rect.Height()-EDIT_HEIGHT, rect.Width(), EDIT_HEIGHT); +} + +/** +* Windows message called when the window is resized. +*/ +void ConsoleView::OnSize(UINT nType, int cx, int cy) { + CFormView::OnSize(nType, cx, cy); + + //Move the edit windows around + if(editConsole.GetSafeHwnd()) + editConsole.MoveWindow(0, 0, cx, cy-EDIT_HEIGHT); + + if(editInput.GetSafeHwnd()) + editInput.MoveWindow(0, cy-EDIT_HEIGHT, cx, EDIT_HEIGHT); +} + +/** +* Replaces \\n with \\r\\n for carriage returns in an edit control. +*/ +const char *ConsoleView::TranslateString(const char *buf) { + static char buf2[32768]; + int i, l; + char *out; + + l = strlen(buf); + out = buf2; + for (i = 0; i < l; i++) { + if (buf[i] == '\n') { + *out++ = '\r'; + *out++ = '\n'; + } + else { + *out++ = buf[i]; + } + } + + *out++ = 0; + + return buf2; +} diff --git a/tools/materialeditor/ConsoleView.h b/tools/materialeditor/ConsoleView.h new file mode 100644 index 000000000..15675405b --- /dev/null +++ b/tools/materialeditor/ConsoleView.h @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" + +/** +* View in the Material Editor that functions as a Doom III +* console. It allows users to view console output as well as issue +* console commands to the engine. +*/ +class ConsoleView : public CFormView +{ + +public: + enum{ IDD = IDD_CONSOLE_FORM }; + + CEdit editConsole; + CEdit editInput; + + idStr consoleStr; + idStrList consoleHistory; + idStr currentCommand; + int currentHistoryPosition; + bool saveCurrentCommand; + +public: + virtual ~ConsoleView(); + + //Public Operations + void AddText(const char *msg); + void SetConsoleText ( const idStr& text ); + void ExecuteCommand ( const idStr& cmd = "" ); + + +protected: + ConsoleView(); + DECLARE_DYNCREATE(ConsoleView) + + //CFormView Overrides + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual void DoDataExchange(CDataExchange* pDX); + virtual void OnInitialUpdate(); + + //Message Handlers + afx_msg void OnSize(UINT nType, int cx, int cy); + DECLARE_MESSAGE_MAP() + + //Protected Operations + const char* TranslateString(const char *buf); + + +}; diff --git a/tools/materialeditor/FindDialog.cpp b/tools/materialeditor/FindDialog.cpp new file mode 100644 index 000000000..e2311029c --- /dev/null +++ b/tools/materialeditor/FindDialog.cpp @@ -0,0 +1,136 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "FindDialog.h" + +#include "MEMainFrame.h" + +IMPLEMENT_DYNAMIC(FindDialog, CDialog) + +BEGIN_MESSAGE_MAP(FindDialog, CDialog) + ON_BN_CLICKED(ID_FIND_NEXT, OnBnClickedFindNext) +END_MESSAGE_MAP() + +/** +* Constructor for FindDialog. +*/ +FindDialog::FindDialog(CWnd* pParent) +: CDialog(FindDialog::IDD, pParent) { + registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor\\Find"); + parent = (MEMainFrame*)pParent; +} + +/** +* Destructor for FindDialog. +*/ +FindDialog::~FindDialog() { +} + +/** +* Creates and instance of the find dialog. +*/ +BOOL FindDialog::Create() { + return CDialog::Create(FindDialog::IDD, parent); +} + +/** +* Transfers data to and from the controls in the find dialog. +*/ +void FindDialog::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + CString temp = searchData.searchText; + DDX_Text(pDX, IDC_EDIT_FINDTEXT, temp); + DDX_Check(pDX, IDC_CHECK_NAME_ONLY, searchData.nameOnly); + DDX_Radio(pDX, IDC_RADIO_SEARCHFILE, searchData.searchScope); + + searchData.searchText = temp; +} + +/** +* Called while the dialog is being initialized to load the find parameters +* from the registry and set the focus to the correct control. +*/ +BOOL FindDialog::OnInitDialog() { + CDialog::OnInitDialog(); + + LoadFindSettings(); + + GetDlgItem(IDC_EDIT_FINDTEXT)->SetFocus(); + + return FALSE; +} + +/** +* Triggers a search based on the parameters in the dialog. +*/ +void FindDialog::OnBnClickedFindNext() { + + UpdateData(); + searchData.searched = false; + parent->FindNext(&searchData); +} + +/** +* Saves the search parameters and closes the find dialog. +*/ +void FindDialog::OnCancel() +{ + SaveFindSettings(); + + parent->CloseFind(); + DestroyWindow(); +} + +/** +* Loads the search parameters from the registry and makes sure the controls are properly +* initialized. +*/ +void FindDialog::LoadFindSettings() { + registry.Load(); + + searchData.searchText = registry.GetString("searchText"); + searchData.nameOnly = (int)registry.GetFloat("nameOnly"); + searchData.searchScope = (int)registry.GetFloat("searchScope"); + + registry.GetWindowPlacement("findDialog", GetSafeHwnd()); + + UpdateData(FALSE); +} + +/** +* Saves the search parameters to the registry. +*/ +void FindDialog::SaveFindSettings() { + + UpdateData(); + + registry.SetString("searchText", searchData.searchText); + registry.SetFloat("nameOnly", searchData.nameOnly); + registry.SetFloat("searchScope", searchData.searchScope); + + registry.SetWindowPlacement("findDialog", GetSafeHwnd()); + + registry.Save(); +} + + diff --git a/tools/materialeditor/FindDialog.h b/tools/materialeditor/FindDialog.h new file mode 100644 index 000000000..24c86b3ba --- /dev/null +++ b/tools/materialeditor/FindDialog.h @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" +#include "../common/registryoptions.h" + +class MEMainFrame; + +/** +* Dialog that provides an input box and several checkboxes to define +* the parameters of a search. These parameters include: text string, search +* scope and search only name flag. +*/ +class FindDialog : public CDialog +{ + +public: + enum { IDD = IDD_FIND }; + +public: + FindDialog(CWnd* pParent = NULL); + virtual ~FindDialog(); + + BOOL Create(); + +protected: + DECLARE_DYNAMIC(FindDialog) + + //Overrides + virtual void DoDataExchange(CDataExchange* pDX); + virtual BOOL OnInitDialog(); + + //Messages + afx_msg void OnBnClickedFindNext(); + virtual void OnCancel(); + DECLARE_MESSAGE_MAP() + + //Protected Operations + void LoadFindSettings(); + void SaveFindSettings(); + +protected: + MEMainFrame* parent; + MaterialSearchData_t searchData; + rvRegistryOptions registry; +}; diff --git a/tools/materialeditor/MEMainFrame.cpp b/tools/materialeditor/MEMainFrame.cpp new file mode 100644 index 000000000..15f4d7adf --- /dev/null +++ b/tools/materialeditor/MEMainFrame.cpp @@ -0,0 +1,928 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialEditor.h" +#include "MEMainFrame.h" +#include "MaterialDef.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +#define TAB_CONTROL 0x1006 + +IMPLEMENT_DYNAMIC(MEMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(MEMainFrame, CFrameWnd) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_DESTROY() + ON_WM_SIZE() + + ON_NOTIFY(TCN_SELCHANGE, TAB_CONTROL, OnTcnSelChange) + + ON_COMMAND(ID_ME_FILE_EXIT, OnFileExit) + ON_COMMAND(ID_ME_FILE_SAVEMATERIAL, OnFileSaveMaterial) + ON_COMMAND(ID_ME_FILE_SAVEFILE, OnFileSaveFile) + ON_COMMAND(ID_ME_FILE_SAVE, OnFileSaveAll) + ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVEMATERIAL, OnFileSaveMaterialUpdate ) + ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVEFILE, OnFileSaveFileUpdate ) + ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVE, OnFileSaveAllUpdate ) + + ON_COMMAND(ID_ME_PREVIEW_APPLYCHANGES, OnApplyMaterial) + ON_COMMAND(ID_ME_PREVIEW_APPLYFILE, OnApplyFile) + ON_COMMAND(ID_ME_PREVIEW_APPLYALL, OnApplyAll) + ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYCHANGES, OnApplyMaterialUpdate ) + ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYFILE, OnApplyFileUpdate ) + ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYALL, OnApplyAllUpdate ) + + ON_COMMAND(ID_ME_EDIT_CUT, OnEditCut) + ON_COMMAND(ID_ME_EDIT_COPY, OnEditCopy) + ON_COMMAND(ID_ME_EDIT_PASTE, OnEditPaste) + ON_COMMAND(ID_ME_EDIT_DELETE, OnEditDelete) + ON_COMMAND(ID_ME_EDIT_RENAME, OnEditRename) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_CUT, OnEditCutUpdate) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_COPY, OnEditCopyUpdate) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_PASTE, OnEditPasteUpdate) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_DELETE, OnEditDeleteUpdate) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_RENAME, OnEditRenameUpdate) + + ON_COMMAND(ID_ME_EDIT_FIND, OnEditFind) + ON_COMMAND(ID_ME_EDIT_FIND_NEXT, OnEditFindNext) + + ON_COMMAND(ID_ME_EDIT_UNDO, OnEditUndo) + ON_COMMAND(ID_ME_EDIT_REDO, OnEditRedo) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_UNDO, OnEditUndoUpdate ) + ON_UPDATE_COMMAND_UI(ID_ME_EDIT_REDO, OnEditRedoUpdate ) + + ON_COMMAND(ID_VIEW_INCLUDEFILENAME, OnViewIncludeFile) + ON_COMMAND(ID_PREVIEW_RELOADARBPROGRAMS, OnReloadArbPrograms) + ON_COMMAND(ID_PREVIEW_RELOADIMAGES, OnReloadImages ) +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +/** +* Constructor for MEMainFrame. Initialize some member data and load the options. +*/ +MEMainFrame::MEMainFrame() { + + currentDoc = NULL; + m_find = NULL; + + searchData.searched = false; + + options.Load(); +} + +/** +* Destructor for MEMainFrame. +*/ +MEMainFrame::~MEMainFrame() { +} + +/** +* Called to add console text to the console view. +* @param msg The text that is to be added to the console. +*/ +void MEMainFrame::PrintConsoleMessage(const char *msg) { + m_consoleView->AddText(msg); +} + +/** +* Sets a few window styles for the main window during the creation process. +*/ +BOOL MEMainFrame::PreCreateWindow(CREATESTRUCT& cs) { + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + + cs.dwExStyle &= ~WS_EX_CLIENTEDGE; + cs.lpszClass = AfxRegisterWndClass(0); + + return TRUE; +} + +/** +* Called by the MFC framework to allow the window to create any client windows. This method +* creates all of the spliter windows and registers all of the views with the document manager. +*/ +BOOL MEMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { + CCreateContext consoleContext; + consoleContext.m_pNewViewClass = RUNTIME_CLASS(ConsoleView); + + m_consoleView = (ConsoleView*)CreateView(&consoleContext); + m_consoleView->ShowWindow(SW_HIDE); + + m_tabs.Create(TCS_BOTTOM | TCS_FLATBUTTONS | WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, TAB_CONTROL); + m_tabs.InsertItem(0, "Editor"); + m_tabs.InsertItem(1, "Console"); + m_tabs.SetFont(materialEditorFont); + + m_splitterWnd.CreateStatic(this, 2, 1); + + + m_editSplitter.CreateStatic(&m_splitterWnd, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER, m_splitterWnd.IdFromRowCol(0, 0)); + + if(!m_editSplitter.CreateView(0, 0, RUNTIME_CLASS(MaterialTreeView), CSize(300, 200), pContext)) { + TRACE0("Failed to create material list pane\n"); + return FALSE; + } + + if(!m_editSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialEditView), CSize(200, 200), pContext)) { + TRACE0("Failed to create stage property pane\n"); + return FALSE; + } + + + m_previewSplitter.CreateStatic(&m_splitterWnd, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER, m_splitterWnd.IdFromRowCol(1, 0)); + + if(!m_previewSplitter.CreateView(0, 0, RUNTIME_CLASS(MaterialPreviewPropView), CSize(300, 200), pContext)) { + TRACE0("Failed to create preview property pane\n"); + return FALSE; + } + + if(!m_previewSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialPreviewView), CSize(100, 200), pContext)) { + TRACE0("Failed to create preview pane\n"); + return FALSE; + } + + //Get references to all of the views + m_materialTreeView = (MaterialTreeView*)m_editSplitter.GetPane(0, 0); + m_previewPropertyView = (MaterialPreviewPropView*)m_previewSplitter.GetPane(0, 0); + m_materialPreviewView = (MaterialPreviewView*)m_previewSplitter.GetPane(0, 1); + + m_materialEditView = (MaterialEditView*)m_editSplitter.GetPane(0, 1); + m_stageView = m_materialEditView->m_stageView; + m_materialPropertyView = m_materialEditView->m_materialPropertyView; + m_materialEditSplitter = &m_materialEditView->m_editSplitter; + + //Load the splitter positions from the registry + int val = options.GetMaterialEditHeight(); + if(val <= 0) + val = 300; + m_splitterWnd.SetRowInfo(0, val, 0); + + val = options.GetMaterialTreeWidth(); + if(val <= 0) + val = 300; + m_editSplitter.SetColumnInfo(0, val, 0); + + val = options.GetStageWidth(); + if(val <= 0) + val = 200; + m_materialEditSplitter->SetColumnInfo(0, val, 0); + + val = options.GetPreviewPropertiesWidth(); + if(val <= 0) + val = 300; + m_previewSplitter.SetColumnInfo(0, val, 0); + + + + //Register the views with the document manager + materialDocManager.RegisterMaterialView(this); + materialDocManager.RegisterMaterialView(m_materialTreeView); + materialDocManager.RegisterMaterialView(m_stageView); + materialDocManager.RegisterMaterialView(m_materialPropertyView); + materialDocManager.RegisterMaterialView(m_materialPreviewView); + materialDocManager.RegisterMaterialView(m_materialEditView); + + //Let the stage window know about the prop window + m_stageView->SetMaterialPropertyView(m_materialPropertyView); + + //Let the preview props now about the preview window + m_previewPropertyView->RegisterPreviewView(m_materialPreviewView); + m_previewPropertyView->InitializePropTree(); + m_previewPropertyView->GetPropertyTreeCtrl().SetColumn(120); + + MaterialDefManager::InitializeMaterialDefLists(); + + //Some prop tree initialization + //m_materialPropertyView->InitializePropTreeDefs(); + val = options.GetMaterialPropHeadingWidth(); + if(val <= 0) + val = 200; + m_materialPropertyView->GetPropertyTreeCtrl().SetColumn(val); + m_materialPropertyView->LoadSettings(); + + + val = options.GetPreviewPropHeadingWidth(); + if(val <= 0) + val = 120; + m_previewPropertyView->GetPropertyTreeCtrl().SetColumn(val); + + //Build the material list + m_materialTreeView->InitializeMaterialList(true); + + SetActiveView(m_materialTreeView); + + return CFrameWnd::OnCreateClient(lpcs, pContext); +} + +/** +* Called by the framework while the window is being created. This methods +* creates the tool bars and status bars +* /todo Bmatt Nerve: Need to get the toolbars to work correctly. +*/ +int MEMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + + if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || + !m_wndToolBar.LoadToolBar(IDR_ME_MAINFRAME)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + //Load the window placement from the options + options.GetWindowPlacement ( "mainframe", m_hWnd ); + + return 0; +} + +/** +* Called by the MFC framework while the window is being destroyed. This method +* saves the splitter and window positions. +*/ +void MEMainFrame::OnDestroy() { + CFrameWnd::OnDestroy(); + + int cur; + int min; + + m_splitterWnd.GetRowInfo(0, cur, min); + options.SetMaterialEditHeight(cur); + + m_editSplitter.GetColumnInfo(0, cur, min); + options.SetMaterialTreeWidth(cur); + + m_materialEditSplitter->GetColumnInfo(0, cur, min); + options.SetStageWidth(cur); + + m_previewSplitter.GetColumnInfo(0, cur, min); + options.SetPreviewPropertiesWidth(cur); + + + cur = m_materialPropertyView->GetPropertyTreeCtrl().GetColumn(); + options.SetMaterialPropHeadingWidth(cur); + + cur = m_previewPropertyView->GetPropertyTreeCtrl().GetColumn(); + options.SetPreviewPropHeadingWidth(cur); + + options.SetWindowPlacement ( "mainframe", m_hWnd ); + options.Save(); + + m_materialPropertyView->SaveSettings(); + + MaterialDefManager::DestroyMaterialDefLists(); + + AfxGetApp()->ExitInstance(); +} + +/** +* Called by the MFC framework when the window size is changed. This method adjusts the console view +* so that it is always at the bottom of the window and resizes the splitter window to fit +* the remaining space. +*/ +void MEMainFrame::OnSize(UINT nType, int cx, int cy) +{ + CFrameWnd::OnSize(nType, cx, cy); + + CRect statusRect; + m_wndStatusBar.GetWindowRect(statusRect); + + CRect toolbarRect; + m_wndToolBar.GetWindowRect(toolbarRect); + + CRect tabRect; + m_tabs.GetItemRect(0, tabRect); + + int tabHeight = tabRect.Height()+5; + + m_splitterWnd.MoveWindow(0, toolbarRect.Height(), cx, cy-statusRect.Height()-toolbarRect.Height()-tabHeight); + + m_tabs.MoveWindow(0, cy-statusRect.Height()-tabHeight, cx, tabHeight); + + m_consoleView->MoveWindow(0, toolbarRect.Height(), cx, cy-statusRect.Height()-toolbarRect.Height()-tabHeight); +} + +/** +* Called when the user changes the editor/console tab selection. This methods shows and hides +* the appropriate windows. +*/ +void MEMainFrame::OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult) { + + int sel = m_tabs.GetCurSel(); + + switch(sel) { + case 0: + m_splitterWnd.ShowWindow(SW_SHOW); + m_consoleView->ShowWindow(SW_HIDE); + + break; + case 1: + m_splitterWnd.ShowWindow(SW_HIDE); + m_consoleView->ShowWindow(SW_SHOW); + + CRect rect; + GetWindowRect(rect); + MoveWindow(rect); + break; + } +} + +/** +* Shuts down the material editor. +* /todo BMatt Nerve: Need to warn the user if a file is modified. +*/ +void MEMainFrame::OnFileExit() { + PostMessage(WM_DESTROY, 0, 0); +} + +/** +* Saves the selected material. +*/ +void MEMainFrame::OnFileSaveMaterial() { + MaterialDoc* material = materialDocManager.GetCurrentMaterialDoc(); + if(material) { + materialDocManager.SaveMaterial(material); + } +} + +/** +* Saves the selected file. +*/ +void MEMainFrame::OnFileSaveFile() { + + idStr filename = m_materialTreeView->GetSaveFilename(); + if(filename.Length() > 0) { + materialDocManager.SaveFile(filename); + } +} + +/** +* Saves all modified materials. +*/ +void MEMainFrame::OnFileSaveAll() { + materialDocManager.SaveAllMaterials(); +} + +/** +* Enables the save material menu item if a material is selected and has been modified. +*/ +void MEMainFrame::OnFileSaveMaterialUpdate(CCmdUI *pCmdUI) { + + MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc(); + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + if(pDoc && pDoc->modified) { + pCmdUI->Enable(TRUE); + + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Enables the Save File menu item if the current file contains a modified material. +*/ +void MEMainFrame::OnFileSaveFileUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + if(m_materialTreeView->CanSaveFile()) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Enables the Save All menu item if there are any materials that have been modified. +*/ +void MEMainFrame::OnFileSaveAllUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + if(materialDocManager.IsAnyModified()) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Apply the selected material. +*/ +void MEMainFrame::OnApplyMaterial() { + MaterialDoc* material = materialDocManager.GetCurrentMaterialDoc(); + if(material) { + materialDocManager.ApplyMaterial(material); + } +} + +/** +* Applies all modified materials in the selected file. +*/ +void MEMainFrame::OnApplyFile() { + + idStr filename = m_materialTreeView->GetSaveFilename(); + if(filename.Length() > 0) { + materialDocManager.ApplyFile(filename); + } +} + +/** +* Applies all modified materials. +*/ +void MEMainFrame::OnApplyAll() { + materialDocManager.ApplyAll(); +} + +/** +* Enables the Apply Material menu item if the current material has an apply waiting. +*/ +void MEMainFrame::OnApplyMaterialUpdate(CCmdUI *pCmdUI) { + MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc(); + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + if(pDoc && pDoc->applyWaiting) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Enables the apply file menu item if the current file contains any materials +* that need to be applied. +*/ +void MEMainFrame::OnApplyFileUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc(); + + if(pDoc && materialDocManager.DoesFileNeedApply(pDoc->renderMaterial->GetFileName())) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Enables the apply all menu item if there are any materials that need +* to be applied. +*/ +void MEMainFrame::OnApplyAllUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + if(materialDocManager.DoesAnyNeedApply()) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + +/** +* Performs a cut operation on the selected material. +*/ +void MEMainFrame::OnEditCut() { + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + m_materialTreeView->OnCut(); + } + } +} + +/** +* Performs a copy operation on the selected material or stage. +*/ +void MEMainFrame::OnEditCopy() { + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + m_stageView->OnCopy(); + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + m_materialTreeView->OnCopy(); + } + } +} + +/** +* Performs a paste operation on the selected material or stage. +*/ +void MEMainFrame::OnEditPaste() { + CWnd* focus = GetFocus(); + + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + m_stageView->OnPaste(); + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + m_materialTreeView->OnPaste(); + } + } +} + +/** +* Performs a delete operation on the selected material or stage. +*/ +void MEMainFrame::OnEditDelete() { + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + m_stageView->OnDeleteStage(); + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + m_materialTreeView->OnDeleteMaterial(); + } + } +} + +/** +* Performs a rename operation on the selected material or stage. +*/ +void MEMainFrame::OnEditRename() { + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + m_stageView->OnRenameStage(); + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + m_materialTreeView->OnRenameMaterial(); + } + } +} + + +/** +* Enable the cut menu item if a material is selected. +*/ +void MEMainFrame::OnEditCutUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + BOOL enable = FALSE; + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + if(m_stageView->CanCut()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + if(m_materialTreeView->CanCut()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + enable = TRUE; + } + } + + pCmdUI->Enable(enable); +} + +/** +* Enables the copy menu item if a material or stage is selected. +*/ +void MEMainFrame::OnEditCopyUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + BOOL enable = FALSE; + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + if(m_stageView->CanCopy()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + if(m_materialTreeView->CanCopy()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + enable = TRUE; + } + } + + pCmdUI->Enable(enable); +} + +/** +* Enables a paste operation when a material or stage has been copied. +*/ +void MEMainFrame::OnEditPasteUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + BOOL enable = FALSE; + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + if(m_stageView->CanPaste()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + if(m_materialTreeView->CanPaste()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + enable = TRUE; + } + } + + pCmdUI->Enable(enable); +} + +/** +* Enables a delete operation when a material or stage is selected. +*/ +void MEMainFrame::OnEditDeleteUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + BOOL enable = FALSE; + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + if(m_stageView->CanDelete()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + if(m_materialTreeView->CanDelete()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + enable = TRUE; + } + + } + + pCmdUI->Enable(enable); +} + +/** +* Enables a rename operation when a material, folder or stage is selected. +*/ +void MEMainFrame::OnEditRenameUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + BOOL enable = FALSE; + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(StageView))) { + if(m_stageView->CanRename()) { + enable = TRUE; + } + } else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) { + if(m_materialTreeView->CanRename()) { + enable = TRUE; + } + } + } + pCmdUI->Enable(enable); +} + +/** +* Opens the find dialog. +*/ +void MEMainFrame::OnEditFind() { + + if (m_find== NULL) + { + m_find = new FindDialog(this); + m_find->Create(); + m_find->ShowWindow(SW_SHOW); + } + else + m_find->SetActiveWindow(); +} + +/** +* Performs a search with the previously selected search parameters. +*/ +void MEMainFrame::OnEditFindNext() { + FindNext(NULL); +} + +/** +* Performs an undo operation. +*/ +void MEMainFrame::OnEditUndo() { + + //Check for undo operation on special windows + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + m_materialEditView->m_textView.Undo(); + return; + } + } + + materialDocManager.Undo(); +} + +/** +* Performs a redo operation. +*/ +void MEMainFrame::OnEditRedo() { + + //Check for redo operation on special windows + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + m_materialEditView->m_textView.Redo(); + return; + } + } + + materialDocManager.Redo(); +} + +/** +* Enables the undo menu item if an undo is available. +*/ +void MEMainFrame::OnEditUndoUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + pCmdUI->Enable(m_materialEditView->m_textView.CanUndo()); + return; + } + } + + pCmdUI->Enable(materialDocManager.IsUndoAvailable()); +} + +/** +* Enables the redo menu item if a redo is available. +*/ +void MEMainFrame::OnEditRedoUpdate(CCmdUI *pCmdUI) { + + if(pCmdUI->m_pMenu == NULL) { + pCmdUI->Enable(TRUE); + return; + } + + CWnd* focus = GetFocus(); + if(focus) { + if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) { + pCmdUI->Enable(m_materialEditView->m_textView.CanRedo()); + return; + } + } + + pCmdUI->Enable(materialDocManager.IsRedoAvailable()); +} + +/** +* Toggles between including the file into the material list and not. +*/ +void MEMainFrame::OnViewIncludeFile() { + + CMenu* mmenu = GetMenu(); + + UINT state = mmenu->GetMenuState(ID_VIEW_INCLUDEFILENAME, MF_BYCOMMAND); + ASSERT(state != 0xFFFFFFFF); + + if (state & MF_CHECKED) { + mmenu->CheckMenuItem(ID_VIEW_INCLUDEFILENAME, MF_UNCHECKED | MF_BYCOMMAND); + m_materialTreeView->InitializeMaterialList(false); + } else { + mmenu->CheckMenuItem(ID_VIEW_INCLUDEFILENAME, MF_CHECKED | MF_BYCOMMAND); + m_materialTreeView->InitializeMaterialList(true); + } +} + +/** +* Executes the reloadARBPrograms console command for convinience. +*/ +void MEMainFrame::OnReloadArbPrograms() { + cmdSystem->BufferCommandText(CMD_EXEC_NOW, "reloadARBprograms"); +} + +/** +* Executes the reloadImages command to reload images that have been changed outside +* of the editor. +*/ +void MEMainFrame::OnReloadImages() { + cmdSystem->BufferCommandText(CMD_EXEC_NOW, "reloadImages"); +} + +/** +* Called by the find dialog when it is closing. +*/ +void MEMainFrame::CloseFind() { + m_find = NULL; +} + +/** +* Begins a search based on the provided parameters or the previously used +* parameters. +*/ +void MEMainFrame::FindNext(MaterialSearchData_t* search) { + + if(search) { + searchData = *search; + } else { + if(!searchData.searched) { + return; + } + } + + //The material tree controls the searching + if(!m_materialTreeView->FindNextMaterial(&searchData)) { + MessageBox(va("Unable to find '%s'.", searchData.searchText.c_str()), "Find"); + } + searchData.searched = true; +} + +/** +* Called when the selected material has changed. +* @param pMaterial The newly selected material. +*/ +void MEMainFrame::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) { + +} diff --git a/tools/materialeditor/MEMainFrame.h b/tools/materialeditor/MEMainFrame.h new file mode 100644 index 000000000..35ed2cf71 --- /dev/null +++ b/tools/materialeditor/MEMainFrame.h @@ -0,0 +1,145 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include +#include "MaterialEditor.h" +#include "MaterialTreeView.h" +#include "MaterialPropTreeView.h" +#include "MaterialPreviewView.h" +#include "StageView.h" +#include "MaterialPreviewPropView.h" +#include "MEOptions.h" +#include "ConsoleView.h" +#include "FindDialog.h" +#include "../common/PropTree/PropTreeView.h" +#include "MaterialDocManager.h" +#include "MaterialEditView.h" + +/** +* The main window for the material editor. +*/ +class MEMainFrame : public CFrameWnd, public MaterialView +{ + +public: + MEMainFrame(); + virtual ~MEMainFrame(); + + //Public Operations + void PrintConsoleMessage(const char *msg); + +protected: + DECLARE_DYNAMIC(MEMainFrame) + + // Overrides + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); + + //Message Handlers + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult); + + //Menu Message Handlers + afx_msg void OnFileExit(); + afx_msg void OnFileSaveMaterial(); + afx_msg void OnFileSaveFile(); + afx_msg void OnFileSaveAll(); + afx_msg void OnFileSaveMaterialUpdate(CCmdUI *pCmdUI); + afx_msg void OnFileSaveFileUpdate(CCmdUI *pCmdUI); + afx_msg void OnFileSaveAllUpdate(CCmdUI *pCmdUI); + + afx_msg void OnApplyMaterial(); + afx_msg void OnApplyFile(); + afx_msg void OnApplyAll(); + afx_msg void OnApplyMaterialUpdate(CCmdUI *pCmdUI); + afx_msg void OnApplyFileUpdate(CCmdUI *pCmdUI); + afx_msg void OnApplyAllUpdate(CCmdUI *pCmdUI); + + afx_msg void OnEditCut(); + afx_msg void OnEditCopy(); + afx_msg void OnEditPaste(); + afx_msg void OnEditDelete(); + afx_msg void OnEditRename(); + afx_msg void OnEditCutUpdate(CCmdUI *pCmdUI); + afx_msg void OnEditCopyUpdate(CCmdUI *pCmdUI); + afx_msg void OnEditPasteUpdate(CCmdUI *pCmdUI); + afx_msg void OnEditDeleteUpdate(CCmdUI *pCmdUI); + afx_msg void OnEditRenameUpdate(CCmdUI *pCmdUI); + + afx_msg void OnEditFind(); + afx_msg void OnEditFindNext(); + + afx_msg void OnEditUndo(); + afx_msg void OnEditRedo(); + afx_msg void OnEditUndoUpdate(CCmdUI *pCmdUI); + afx_msg void OnEditRedoUpdate(CCmdUI *pCmdUI); + + afx_msg void OnViewIncludeFile(); + afx_msg void OnReloadArbPrograms(); + afx_msg void OnReloadImages(); + + DECLARE_MESSAGE_MAP() + + //Methods for Find interactions + friend FindDialog; + void CloseFind(); + void FindNext(MaterialSearchData_t* search); + + //MaterialView Interface + virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial); + +protected: + //Status and Toolbars + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + + //Splitter windows + CTabCtrl m_tabs; + CSplitterWnd m_splitterWnd; + CSplitterWnd m_editSplitter; + CSplitterWnd m_previewSplitter; + CSplitterWnd* m_materialEditSplitter; + + //Child Views + MaterialTreeView* m_materialTreeView; + StageView* m_stageView; + MaterialPropTreeView* m_materialPropertyView; + MaterialPreviewView* m_materialPreviewView; + MaterialPreviewPropView* m_previewPropertyView; + ConsoleView* m_consoleView; + + MaterialEditView* m_materialEditView; + + //Find Data + FindDialog* m_find; + MaterialSearchData_t searchData; + + //Document Management + MaterialDocManager materialDocManager; + MaterialDoc* currentDoc; + + //Options + MEOptions options; + +}; + + diff --git a/tools/materialeditor/MEOptions.cpp b/tools/materialeditor/MEOptions.cpp new file mode 100644 index 000000000..1cac977b6 --- /dev/null +++ b/tools/materialeditor/MEOptions.cpp @@ -0,0 +1,79 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MEOptions.h" + +/** +* Constructor for MEOptions. +*/ +MEOptions::MEOptions ( ) { + + registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor"); + + materialTreeWidth = 0; + stageWidth = 0; + previewPropertiesWidth = 0; + materialEditHeight = 0; + materialPropHeadingWidth = 0; + previewPropHeadingWidth = 0; + +} + +/** +* Destructor for MEOptions. +*/ +MEOptions::~MEOptions() { +} + +/** +* Saves the material editor options to the registry. +*/ +bool MEOptions::Save (void) { + + registry.SetFloat("materialTreeWidth", materialTreeWidth); + registry.SetFloat("stageWidth", stageWidth); + registry.SetFloat("previewPropertiesWidth", previewPropertiesWidth); + registry.SetFloat("materialEditHeight", materialEditHeight); + registry.SetFloat("materialPropHeadingWidth", materialPropHeadingWidth); + registry.SetFloat("previewPropHeadingWidth", previewPropHeadingWidth); + + return registry.Save(); +} + +/** +* Loads the material editor options from the registry. +*/ +bool MEOptions::Load (void) { + + if(!registry.Load()) { + return false; + } + + materialTreeWidth = (int)registry.GetFloat("materialTreeWidth"); + stageWidth = (int)registry.GetFloat("stageWidth"); + previewPropertiesWidth = (int)registry.GetFloat("previewPropertiesWidth"); + materialEditHeight = (int)registry.GetFloat("materialEditHeight"); + materialPropHeadingWidth = (int)registry.GetFloat("materialPropHeadingWidth"); + previewPropHeadingWidth = (int)registry.GetFloat("previewPropHeadingWidth"); + + return true; + +} \ No newline at end of file diff --git a/tools/materialeditor/MEOptions.h b/tools/materialeditor/MEOptions.h new file mode 100644 index 000000000..1c5d1cc8b --- /dev/null +++ b/tools/materialeditor/MEOptions.h @@ -0,0 +1,143 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "../common/registryoptions.h" + +/** +* Wrapper class that is responsible for reading and writing Material Editor +* settings to the registry. Settings are written to +* Software\\id Software\\DOOM3\\Tools\\MaterialEditor +*/ +class MEOptions { + +public: + MEOptions(); + ~MEOptions(); + + bool Save (void); + bool Load (void); + + /** + * Sets the flag that determines if the settings need to be saved because + * they where modified. + */ + void SetModified(bool mod = true) { modified = mod; }; + /** + * Get the flag that determines if the settings need to be saved because + * they where modified. + */ + bool GetModified() { return modified; }; + + void SetWindowPlacement ( const char* name, HWND hwnd ); + bool GetWindowPlacement ( const char* name, HWND hwnd ); + + void SetMaterialTreeWidth(int width); + int GetMaterialTreeWidth(); + + void SetStageWidth(int width); + int GetStageWidth(); + + void SetPreviewPropertiesWidth(int width); + int GetPreviewPropertiesWidth(); + + void SetMaterialEditHeight(int height); + int GetMaterialEditHeight(); + + void SetMaterialPropHeadingWidth(int width); + int GetMaterialPropHeadingWidth(); + + void SetPreviewPropHeadingWidth(int width); + int GetPreviewPropHeadingWidth(); + +protected: + rvRegistryOptions registry; + + bool modified; + + int materialTreeWidth; + int stageWidth; + int previewPropertiesWidth; + int materialEditHeight; + int materialPropHeadingWidth; + int previewPropHeadingWidth; +}; + + +ID_INLINE void MEOptions::SetWindowPlacement ( const char* name, HWND hwnd ) { + registry.SetWindowPlacement ( name, hwnd ); +} + +ID_INLINE bool MEOptions::GetWindowPlacement ( const char* name, HWND hwnd ) { + return registry.GetWindowPlacement ( name, hwnd ); +} + +ID_INLINE void MEOptions::SetMaterialTreeWidth(int width) { + materialTreeWidth = width; + SetModified(true); +} + +ID_INLINE int MEOptions::GetMaterialTreeWidth() { + return materialTreeWidth; +} + +ID_INLINE void MEOptions::SetStageWidth(int width) { + stageWidth = width; + SetModified(true); +} + +ID_INLINE int MEOptions::GetStageWidth() { + return stageWidth; +} + +ID_INLINE void MEOptions::SetPreviewPropertiesWidth(int width) { + previewPropertiesWidth = width; + SetModified(true); +} + +ID_INLINE int MEOptions::GetPreviewPropertiesWidth() { + return previewPropertiesWidth; +} + +ID_INLINE void MEOptions::SetMaterialEditHeight(int height) { + materialEditHeight = height; + SetModified(true); +} + +ID_INLINE int MEOptions::GetMaterialEditHeight() { + return materialEditHeight; +} + +ID_INLINE void MEOptions::SetMaterialPropHeadingWidth(int width) { + materialPropHeadingWidth = width; + SetModified(true); +} + +ID_INLINE int MEOptions::GetMaterialPropHeadingWidth() { + return materialPropHeadingWidth; +} + +ID_INLINE void MEOptions::SetPreviewPropHeadingWidth(int width) { + previewPropHeadingWidth = width; + SetModified(true); +} + +ID_INLINE int MEOptions::GetPreviewPropHeadingWidth() { + return previewPropHeadingWidth; +} \ No newline at end of file diff --git a/tools/materialeditor/MaterialDef.cpp b/tools/materialeditor/MaterialDef.cpp new file mode 100644 index 000000000..05012ecb5 --- /dev/null +++ b/tools/materialeditor/MaterialDef.cpp @@ -0,0 +1,190 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialDef.h" + + +/** +* Constructor. +*/ +MaterialDef::MaterialDef(void) { + type = 0; + quotes = false; +} + +/** +* Destructor. +*/ +MaterialDef::~MaterialDef(void) { +} + +/** +* Returns view specific data associated with the material definition. +*/ +DWORD MaterialDef::GetViewData(const char* viewName) { + DWORD* value = NULL; + viewData.Get(viewName, &value); + return *value; +} + +/** +* Sets view specific data for the material definition. +*/ +void MaterialDef::SetViewData(const char* viewName, DWORD value) { + viewData.Set(viewName, value); +} + +#define MATERIAL_DEF_FILE "MaterialEditorDefs.med" + +MaterialDefList MaterialDefManager::materialDefs[MaterialDefManager::MATERIAL_DEF_NUM]; + + +/** +* Loads the material definition file instatiates MaterialDef objects for each definition +* and groups the definitions. +*/ +void MaterialDefManager::InitializeMaterialDefLists() { + + char *buffer; + int length = fileSystem->ReadFile( MATERIAL_DEF_FILE, (void **)&buffer); + + if ( length == -1 ) { + common->Error( "Couldn't load material editor definition: %s", MATERIAL_DEF_FILE ); + return; + } + + idLexer src; + if ( !src.LoadMemory( buffer, length, MATERIAL_DEF_FILE ) ) { + common->Error( "Couldn't parse %s", MATERIAL_DEF_FILE ); + fileSystem->FreeFile(buffer); + } + + + InitializeMaterialDefList(&src, "materialprops", &materialDefs[MATERIAL_DEF_MATERIAL]); + InitializeMaterialDefList(&src, "stageprops", &materialDefs[MATERIAL_DEF_STAGE]); + InitializeMaterialDefList(&src, "specialmapstageprops", &materialDefs[MATERIAL_DEF_SPECIAL_STAGE]); + + fileSystem->FreeFile(buffer); +} + +/** +* Loads a single type of material attributes and adds them to the supplied MaterialDefList object. +* @param src The idLexer object that contains the file. +* @param typeName The name of the attribute grouping to search for in the file. +* @param list The MaterialDefList object to append the MaterialDef instances to. +*/ +void MaterialDefManager::InitializeMaterialDefList(idLexer* src, const char* typeName, MaterialDefList* list) { + + idToken token; + + src->Reset(); + src->SkipUntilString(typeName); + src->SkipUntilString("{"); + + while(1) { + if ( !src->ExpectAnyToken( &token ) ) { + //Todo: Add some error checking here + return; + } + + if ( token == "}" ) { + break; + } + + MaterialDef* newProp = new MaterialDef(); + + if(!token.Icmp("TYPE_GROUP")) { + newProp->type = MaterialDef::MATERIAL_DEF_TYPE_GROUP; + } else if(!token.Icmp("TYPE_BOOL")) { + newProp->type = MaterialDef::MATERIAL_DEF_TYPE_BOOL; + } else if(!token.Icmp("TYPE_STRING")) { + newProp->type = MaterialDef::MATERIAL_DEF_TYPE_STRING; + } else if(!token.Icmp("TYPE_FLOAT")) { + newProp->type = MaterialDef::MATERIAL_DEF_TYPE_FLOAT; + } else if(!token.Icmp("TYPE_INT")) { + newProp->type = MaterialDef::MATERIAL_DEF_TYPE_INT; + } + + //Skip the , + src->ReadToken(&token); + + //Read Dict Name + src->ReadToken(&token); + newProp->dictName = token; + + //Skip the , + src->ReadToken(&token); + + //Read Display Name + src->ReadToken(&token); + newProp->displayName = token; + + //Skip the , + src->ReadToken(&token); + + //Read Display Info + src->ReadToken(&token); + newProp->displayInfo = token; + + //Type Specific Data + if(newProp->type == MaterialDef::MATERIAL_DEF_TYPE_STRING) { + + newProp->quotes = false; + + //Skip the , + src->ReadToken(&token); + + //Read validate flag + src->ReadToken(&token); + if(token == "1") { + newProp->quotes = true; + } + } + + src->SkipRestOfLine(); + + list->Append(newProp); + } +} + +/** +* Destroys all MaterialDef instances and clears the material attribute grouping lists. +*/ +void MaterialDefManager::DestroyMaterialDefLists() { + + for(int i = 0; i < MATERIAL_DEF_NUM; i++) { + for(int j = 0; j < materialDefs[i].Num(); j++) { + delete materialDefs[i][j]; + } + materialDefs[i].Clear(); + } +} + +/** +* Returns the MaterialDefList for the specified attribute grouping. +* @param type The attribute grouping for which to retreive the attribute list. +*/ +MaterialDefList* MaterialDefManager::GetMaterialDefs(int type) { + if(type >= 0 && type < MATERIAL_DEF_NUM) { + return &materialDefs[type]; + } + return NULL; +} \ No newline at end of file diff --git a/tools/materialeditor/MaterialDef.h b/tools/materialeditor/MaterialDef.h new file mode 100644 index 000000000..6695b1b3a --- /dev/null +++ b/tools/materialeditor/MaterialDef.h @@ -0,0 +1,93 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +/** +* Represents a single attribute in a material. Represents material, stage +* and special stage attributes. The MaterialDef manager loads these +* definitions from the material definition file as the editor +* is being initialized. +*/ +class MaterialDef { + +public: + /** + * Defines possible attribute types. + */ + enum { + MATERIAL_DEF_TYPE_GROUP, + MATERIAL_DEF_TYPE_BOOL, + MATERIAL_DEF_TYPE_STRING, + MATERIAL_DEF_TYPE_FLOAT, + MATERIAL_DEF_TYPE_INT + }; + + int type; + idStr dictName; + idStr displayName; + idStr displayInfo; + bool quotes; + idHashTable viewData; + +public: + + MaterialDef(void); + virtual ~MaterialDef(void); + + DWORD GetViewData(const char* viewName); + void SetViewData(const char* viewName, DWORD value); +}; + +/** +* A list of material attributes. Material, stage, and special stage attributes +* are grouped together during the load process for use by the different view and +* MaterialDoc. +*/ +typedef idList MaterialDefList; + +/** +* This class contains static utility functions that view and MaterialDoc use +* to access the MaterialDef and MaterialDefList data that is loaded. This class +* is also responsible for loading and destroying the MaterialDef instances. +*/ +class MaterialDefManager { + +public: + + /** + * Defines the groupings of material attributes. + */ + enum { + MATERIAL_DEF_MATERIAL = 0, + MATERIAL_DEF_STAGE, + MATERIAL_DEF_SPECIAL_STAGE, + MATERIAL_DEF_NUM + }; + + static void InitializeMaterialDefLists(); + static void InitializeMaterialDefList(idLexer* src, const char* typeName, MaterialDefList* list); + + static void DestroyMaterialDefLists(); + + static MaterialDefList* GetMaterialDefs(int type); + + +protected: + static MaterialDefList materialDefs[MATERIAL_DEF_NUM]; +}; diff --git a/tools/materialeditor/MaterialDoc.cpp b/tools/materialeditor/MaterialDoc.cpp new file mode 100644 index 000000000..4fbd55fe9 --- /dev/null +++ b/tools/materialeditor/MaterialDoc.cpp @@ -0,0 +1,957 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialDoc.h" +#include "MaterialView.h" + +/** +* Constructor for MaterialDoc. +*/ +MaterialDoc::MaterialDoc(void) { + modified = false; + applyWaiting = false; + sourceModify = false; +} + +/** +* Destructor for MaterialDoc. +*/ +MaterialDoc::~MaterialDoc(void) { + ClearEditMaterial(); +} + +/** +* Initializes the MaterialDoc instance with a specific idMaterial. This method will +* parse the material into the internal dictionary representation and optionally +* allow the idMaterial object to reparse the source. +* @param material The idMaterial instance to use. +* @param parseMaterial Flag to determine if the material should be parsed into the editor representation. +* @param parseRenderMaterial Flag to determine if the idMaterial object should be reparsed. +*/ +void MaterialDoc::SetRenderMaterial(idMaterial* material, bool parseMaterial, bool parseRenderMatierial) { + + renderMaterial = material; + + + if(!parseMaterial || !renderMaterial) + return; + + if(parseRenderMatierial) { + char *declText = (char *) _alloca( material->GetTextLength() + 1 ); + material->GetText( declText ); + + renderMaterial->GetText(declText); + ParseMaterialText(declText); + + } + + ClearEditMaterial(); + + name = material->GetName(); + + idLexer src; + + char *declText = (char *) _alloca( material->GetTextLength() + 1 ); + material->GetText( declText ); + + renderMaterial->GetText(declText); + src.LoadMemory(declText, strlen(declText), "Material"); + + ParseMaterial(&src); +} + +/** +* Returns the number of stages in this material. +*/ +int MaterialDoc::GetStageCount() { + return editMaterial.stages.Num(); +} + +/** +* Returns the index of the stage with the specified type and name or -1 +* if the stage does not exist. +* @param stageType The type of stage to find. +* @param name The name of the stage to find. +*/ +int MaterialDoc::FindStage(int stageType, const char* name) { + + for(int i = 0; i < editMaterial.stages.Num(); i++) { + int type = GetAttributeInt(i, "stagetype"); + idStr localname = GetAttribute(i, "name"); + if(stageType == type && !localname.Icmp(name)) + return i; + } + return -1; +} + +/** +* Returns a copy of the specified stage. +* @param stage The stage to return. +*/ +MEStage_t MaterialDoc::GetStage(int stage) { + assert(stage >= 0 && stage < GetStageCount()); + return *editMaterial.stages[stage]; + +} + +/** +* Specifies the enabled state of a single stage. +* @param stage The stage to change. +* @param enabled The enabled state. +*/ +void MaterialDoc::EnableStage(int stage, bool enabled) { + + assert(stage >= 0 && stage < GetStageCount()); + editMaterial.stages[stage]->enabled = enabled; + + OnMaterialChanged(); +} + +/** +* Sets the enabled state of all stages. +* @param enabled The enabled state. +*/ +void MaterialDoc::EnableAllStages(bool enabled) { + for(int i = 0; i < GetStageCount(); i++) { + editMaterial.stages[i]->enabled = enabled; + } +} + +/** +* Returns the enabled state of a stage. +* @param stage The stage to check. +*/ +bool MaterialDoc::IsStageEnabled(int stage) { + assert(stage >= 0 && stage < GetStageCount()); + return editMaterial.stages[stage]->enabled; +} + +/** +* Returns an attribute string from the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param defaultString The default value if the attribute is not specified. +*/ +const char* MaterialDoc::GetAttribute(int stage, const char* attribName, const char* defaultString) { + + if(stage == -1) { + return editMaterial.materialData.GetString(attribName, defaultString); + } else { + assert(stage >= 0 && stage < GetStageCount()); + MEStage_t* pStage = editMaterial.stages[stage]; + return pStage->stageData.GetString(attribName, defaultString); + } +} + +/** +* Returns an attribute int from the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param defaultString The default value if the attribute is not specified. +*/ +int MaterialDoc::GetAttributeInt(int stage, const char* attribName, const char* defaultString) { + if(stage == -1) { + return editMaterial.materialData.GetInt(attribName, defaultString); + } else { + assert(stage >= 0 && stage < GetStageCount()); + MEStage_t* pStage = editMaterial.stages[stage]; + return pStage->stageData.GetInt(attribName, defaultString); + } +} + +/** +* Returns an attribute float from the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param defaultString The default value if the attribute is not specified. +*/ +float MaterialDoc::GetAttributeFloat(int stage, const char* attribName, const char* defaultString) { + if(stage == -1) { + return editMaterial.materialData.GetFloat(attribName, defaultString); + } else { + assert(stage >= 0 && stage < GetStageCount()); + MEStage_t* pStage = editMaterial.stages[stage]; + return pStage->stageData.GetFloat(attribName, defaultString); + } +} + +/** +* Returns an attribute bool from the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param defaultString The default value if the attribute is not specified. +*/ +bool MaterialDoc::GetAttributeBool(int stage, const char* attribName, const char* defaultString) { + if(stage == -1) { + return editMaterial.materialData.GetBool(attribName, defaultString); + } else { + assert(stage >= 0 && stage < GetStageCount()); + MEStage_t* pStage = editMaterial.stages[stage]; + return pStage->stageData.GetBool(attribName, defaultString); + } +} + +/** +* Sets an attribute string in the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param value The value to set. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::SetAttribute(int stage, const char* attribName, const char* value, bool addUndo) { + + //Make sure we need to set the attribute + idStr orig = GetAttribute(stage, attribName); + if(orig.Icmp(value)) { + + idDict* dict; + if(stage == -1) { + dict = &editMaterial.materialData; + } else { + assert(stage >= 0 && stage < GetStageCount()); + dict = &editMaterial.stages[stage]->stageData; + } + + if(addUndo) { + //Create a new Modifier for this change so we can undo and redo later + AttributeMaterialModifierString* mod = new AttributeMaterialModifierString(manager, name, stage, attribName, value, orig); + manager->AddMaterialUndoModifier(mod); + } + + dict->Set(attribName, value); + + manager->AttributeChanged(this, stage, attribName); + OnMaterialChanged(); + } +} + +/** +* Sets an attribute int in the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param value The value to set. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::SetAttributeInt(int stage, const char* attribName, int value, bool addUndo) { + //Make sure we need to set the attribute + int orig = GetAttributeInt(stage, attribName); + if(orig != value) { + + idDict* dict; + if(stage == -1) { + dict = &editMaterial.materialData; + } else { + assert(stage >= 0 && stage < GetStageCount()); + dict = &editMaterial.stages[stage]->stageData; + } + + dict->SetInt(attribName, value); + + manager->AttributeChanged(this, stage, attribName); + OnMaterialChanged(); + } +} + +/** +* Sets an attribute float in the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param value The value to set. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::SetAttributeFloat(int stage, const char* attribName, float value, bool addUndo) { + //Make sure we need to set the attribute + float orig = GetAttributeFloat(stage, attribName); + if(orig != value) { + + idDict* dict; + if(stage == -1) { + dict = &editMaterial.materialData; + } else { + assert(stage >= 0 && stage < GetStageCount()); + dict = &editMaterial.stages[stage]->stageData; + } + + dict->SetFloat(attribName, value); + + manager->AttributeChanged(this, stage, attribName); + OnMaterialChanged(); + } +} + +/** +* Sets an attribute bool in the material or a stage. +* @param stage The stage or -1 for the material. +* @param attribName The name of the attribute. +* @param value The value to set. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::SetAttributeBool(int stage, const char* attribName, bool value, bool addUndo) { + //Make sure we need to set the attribute + bool orig = GetAttributeBool(stage, attribName); + if(orig != value) { + + idDict* dict; + if(stage == -1) { + dict = &editMaterial.materialData; + } else { + assert(stage >= 0 && stage < GetStageCount()); + dict = &editMaterial.stages[stage]->stageData; + } + + if(addUndo) { + //Create a new Modifier for this change so we can undo and redo later + AttributeMaterialModifierBool* mod = new AttributeMaterialModifierBool(manager, name, stage, attribName, value, orig); + manager->AddMaterialUndoModifier(mod); + } + + dict->SetBool(attribName, value); + + manager->AttributeChanged(this, stage, attribName); + OnMaterialChanged(); + } +} + +/** +* Sets the material name. +* @param materialName The new name of the material. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::SetMaterialName(const char* materialName, bool addUndo) { + idStr oldName = name; + + declManager->RenameDecl(DECL_MATERIAL, oldName, materialName); + name = renderMaterial->GetName(); + + if(addUndo) { + RenameMaterialModifier* mod = new RenameMaterialModifier(manager, name, oldName); + manager->AddMaterialUndoModifier(mod); + } + + manager->MaterialNameChanged(oldName, this); + + OnMaterialChanged(); + + //Need to do an instant apply for material name changes + ApplyMaterialChanges(); +} + +/** +* Sets the entire dictionary for a material or stage +* @param stage The stage or -1 for the material. +* @param data The dictionary to copy. +*/ +void MaterialDoc::SetData(int stage, idDict* data) { + idDict* dict; + if(stage == -1) { + dict = &editMaterial.materialData; + } else { + assert(stage >= 0 && stage < GetStageCount()); + dict = &editMaterial.stages[stage]->stageData; + } + dict->Clear(); + dict->Copy(*data); +} + +/** +* Called when the editor modifies the source of the material. +* @param text The new source text. +*/ +void MaterialDoc::SourceModify(SourceModifyOwner* owner) { + + sourceModifyOwner = owner; + sourceModify = true; + OnMaterialChanged(); +} + +/** +* Returns true if the source text of this material has been edited. +*/ +bool MaterialDoc::IsSourceModified() { + return sourceModify; +} + +/** +* Applies any source changes to the edit representation of the material. +*/ +void MaterialDoc::ApplySourceModify(idStr& text) { + + if(sourceModify) { + + //Changes in the source need to clear any undo redo buffer because we have no idea what has changed + manager->ClearUndo(); + manager->ClearRedo(); + + ClearEditMaterial(); + + idLexer src; + src.LoadMemory(text, text.Length(), "Material"); + + src.SetFlags( + LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated + LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings + LEXFL_ALLOWPATHNAMES | // allow path seperators in names + LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals + LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated + LEXFL_NOFATALERRORS // just set a flag instead of fatal erroring + ); + + idToken token; + if(!src.ReadToken(&token)) { + src.Warning( "Missing decl name" ); + return; + } + + ParseMaterial(&src); + sourceModify = false; + + //Check to see if the name has changed + if(token.Icmp(name)) { + SetMaterialName(token, false); + } + } +} + +/** +* Returns the appropriate source for the editing +*/ +const char* MaterialDoc::GetEditSourceText() { + + return GenerateSourceText(); +} + +/** +* Adds a stage to the material. +* @param stageType The type of the stage: normal or special. +* @param stageName The name of the stage. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::AddStage(int stageType, const char* stageName, bool addUndo) { + MEStage_t* newStage = new MEStage_t(); + + int index = editMaterial.stages.Append(newStage); + newStage->stageData.Set("name", stageName); + newStage->stageData.SetInt("stagetype", stageType); + newStage->enabled = true; + + if(addUndo) { + StageInsertModifier* mod = new StageInsertModifier(manager, name, index, stageType, stageName); + manager->AddMaterialUndoModifier(mod); + } + + manager->StageAdded(this, index); + + OnMaterialChanged(); +} + +/** +* Inserts a new stage to the material at a specified location. +* @param stage The location to insert the stage. +* @param stageType The type of the stage: normal or special. +* @param stageName The name of the stage. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::InsertStage(int stage, int stageType, const char* stageName, bool addUndo) { + MEStage_t* newStage = new MEStage_t(); + + editMaterial.stages.Insert(newStage, stage); + newStage->stageData.Set("name", stageName); + newStage->stageData.SetInt("stagetype", stageType); + newStage->enabled = true; + + if(addUndo) { + StageInsertModifier* mod = new StageInsertModifier(manager, name, stage, stageType, stageName); + manager->AddMaterialUndoModifier(mod); + } + + manager->StageAdded(this, stage); + + OnMaterialChanged(); +} + +/** +* Removes a stage from the material. +* @param stage The stage to remove. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::RemoveStage(int stage, bool addUndo) { + assert(stage >= 0 && stage < GetStageCount()); + + if(addUndo) { + //Add modifier to undo this operation + StageDeleteModifier* mod = new StageDeleteModifier(manager, name, stage, editMaterial.stages[stage]->stageData); + manager->AddMaterialUndoModifier(mod); + } + + //delete the stage and remove it from the list + delete editMaterial.stages[stage]; + editMaterial.stages.RemoveIndex(stage); + + manager->StageDeleted(this, stage); + + OnMaterialChanged(); +} + +/** +* Removes all stages from the material. +*/ +void MaterialDoc::ClearStages() { + + //Delete each stage and clear the list + for(int i = GetStageCount() - 1; i >= 0; i--) { + RemoveStage(i); + } +} + +/** +* Moves a stage from one location to another. +* @param from The original location of the stage. +* @param to The new location of the stage. +* @param addUndo Flag that specifies if the system should add an undo operation. +*/ +void MaterialDoc::MoveStage(int from, int to, bool addUndo) { + assert(from >= 0 && from < GetStageCount()); + assert(to >= 0 && to < GetStageCount()); + + int origFrom = from; + int origTo = to; + + if(from < to) + to++; + + MEStage_t* pMove = editMaterial.stages[from]; + editMaterial.stages.Insert(pMove, to); + + if(from > to) + from++; + + editMaterial.stages.RemoveIndex(from); + + manager->StageMoved(this, origFrom, origTo); + + if(addUndo) { + StageMoveModifier *mod = new StageMoveModifier(manager, name, origFrom, origTo); + manager->AddMaterialUndoModifier(mod); + } + + OnMaterialChanged(); +} + +/** +* Applies any changes to the material +* @param force If true then the material will be applied regardless of the number of changes. +*/ +void MaterialDoc::ApplyMaterialChanges(bool force) { + + if(force || applyWaiting) { + + if(sourceModify && sourceModifyOwner) { + idStr text = sourceModifyOwner->GetSourceText(); + ApplySourceModify(text); + } + + ReplaceSourceText(); + + char *declText = (char *) _alloca( renderMaterial->GetTextLength() + 1 ); + renderMaterial->GetText( declText ); + + renderMaterial->GetText(declText); + + ParseMaterialText(declText); + + applyWaiting = false; + + assert(manager); + manager->MaterialApplied(this); + } +} + +/** +* Saves the material. +*/ +void MaterialDoc::Save() { + + EnableAllStages(true); + + //Apply the material so that the renderMaterial has the source text + if(!deleted) { + ApplyMaterialChanges(true); + } else { + //Replace the text with nothing + renderMaterial->SetText(" "); + } + + if(renderMaterial->Save()) { + + modified = false; + + //Notify the world + assert(manager); + manager->MaterialSaved(this); + } else { + MessageBox(GetMaterialEditorWindow(), va("Unable to save '%s'. It may be read-only", name.c_str()), "Save Error", MB_OK | MB_ICONERROR); + } +} + +/** +* Deletes the material. +*/ +void MaterialDoc::Delete() { + deleted = true; + + OnMaterialChanged(); +} + +/** +* Sets the proper internal states and notifies the MaterialDocManager once a material has been changed. +*/ +void MaterialDoc::OnMaterialChanged() { + + modified = true; + applyWaiting = true; + + assert(manager); + manager->MaterialChanged(this); +} + +/** +* Passes text to a render material for parsing. +* @param source The text that sould be applied to the idMaterial. +*/ +void MaterialDoc::ParseMaterialText(const char* source) { + + /*idLexer src; + src.LoadMemory(source, strlen(source), "material"); + src.SetFlags( + LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated + LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings + LEXFL_ALLOWPATHNAMES | // allow path seperators in names + LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals + LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated + LEXFL_NOFATALERRORS // just set a flag instead of fatal erroring + ); + + //Skip the name becuase the material parsing code expects it + src.SkipUntilString("{");*/ + + //Now let the material parse the text + renderMaterial->Parse(source, strlen(source)); +} + +/** +* Parses the source text from an idMaterial and initializes the editor dictionary representation +* of the material. +* @param src The idLexer object that contains the material text. +*/ +void MaterialDoc::ParseMaterial(idLexer* src) { + + idToken token; + + //Parse past the name + src->SkipUntilString("{"); + + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + //Todo: Add some error checking here + return; + } + + if ( token == "}" ) { + break; + } + + if(ParseMaterialDef(&token, src, MaterialDefManager::MATERIAL_DEF_MATERIAL, &editMaterial.materialData)) { + continue; + } + + if ( !token.Icmp( "diffusemap" ) ) { + //Added as a special stage + idStr str; + src->ReadRestOfLine( str ); + AddSpecialMapStage("diffusemap", str); + } + else if ( !token.Icmp( "specularmap" ) ) { + idStr str; + src->ReadRestOfLine( str ); + AddSpecialMapStage("specularmap", str); + } + else if ( !token.Icmp( "bumpmap" ) ) { + idStr str; + src->ReadRestOfLine( str ); + AddSpecialMapStage("bumpmap", str); + } + else if( token == "{" ) { + ParseStage(src); + } + } +} + +/** +* Parses a single stage from the source text from an idMaterial and initializes the editor dictionary +* representation of the material. +* @param src The idLexer object that contains the material text. +*/ +void MaterialDoc::ParseStage(idLexer* src) { + + MEStage_t* newStage = new MEStage_t(); + int index = editMaterial.stages.Append(newStage); + + newStage->stageData.SetInt("stagetype", STAGE_TYPE_NORMAL); + newStage->enabled = true; + + idToken token; + + while ( 1 ) { + + if ( !src->ExpectAnyToken( &token ) ) { + //Todo: Add some error checking here + return; + } + + if ( token == "}" ) { + break; + } + + if(ParseMaterialDef(&token, src, MaterialDefManager::MATERIAL_DEF_STAGE, &newStage->stageData)) { + continue; + } + + if(!token.Icmp("name")) { + + idStr str; + src->ReadRestOfLine( str ); + str.StripTrailing('\"'); + str.StripLeading('\"'); + newStage->stageData.Set("name", str); + continue; + } + } + + idStr name; + newStage->stageData.GetString("name", "", name); + if(name.Length() <= 0) + newStage->stageData.Set("name", va("Stage %d", index+1)); + +} + +/** +* Adds a special stage to the material. +* @param stageName The name of the special stage bumpmap, diffusemap or specularmap +* @param map The map for the special stage. +*/ +void MaterialDoc::AddSpecialMapStage(const char* stageName, const char* map) { + MEStage_t* newStage = new MEStage_t(); + int index = editMaterial.stages.Append(newStage); + newStage->stageData.Set("name", stageName); + newStage->stageData.Set("map", map); + newStage->stageData.SetInt("stagetype", STAGE_TYPE_SPECIALMAP); + newStage->enabled = true; +} + +/** +* Finds the appropriate material definition for the supplied token and initializes the +* internal dictionary data. +* @param token The token to lookup +* @param src The idLexer that contains the material source text. +* @param type The type of attribute grouping to use material, stage or special stage. +* @param dict The dictionary to initialize. +*/ +bool MaterialDoc::ParseMaterialDef(idToken* token, idLexer* src, int type, idDict* dict) { + + MaterialDefList* defs = MaterialDefManager::GetMaterialDefs(type); + + for(int i = 0; i < defs->Num(); i++) { + if(!token->Icmp((*defs)[i]->dictName)) { + + switch((*defs)[i]->type) { + case MaterialDef::MATERIAL_DEF_TYPE_STRING: + { + idStr str; + src->ReadRestOfLine( str ); + if((*defs)[i]->quotes) { + str.StripTrailing('\"'); + str.StripLeading('\"'); + } + dict->Set((*defs)[i]->dictName, str); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_BOOL: + { + src->SkipRestOfLine(); + dict->SetBool((*defs)[i]->dictName, true); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_FLOAT: + { + idStr str; + src->ReadRestOfLine( str ); + dict->Set((*defs)[i]->dictName, str); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_INT: + { + idStr str; + src->ReadRestOfLine( str ); + dict->Set((*defs)[i]->dictName, str); + } + break; + } + return true; + } + } + return false; +} + +/** +* Cleans up the edit material by deleting the stage data structures. +*/ +void MaterialDoc::ClearEditMaterial() { + + for(int i = 0; i < GetStageCount(); i++) { + delete editMaterial.stages[i]; + } + editMaterial.stages.Clear(); + editMaterial.materialData.Clear(); +} + +/** +* Writes the internal dictionary data to the standard format. +*/ +const char* MaterialDoc::GenerateSourceText() { + + idFile_Memory f; + + f.WriteFloatString("\n\n/*\n" + "\tGenerated by the Material Editor.\n" + "\tType 'materialeditor' at the console to launch the material editor.\n" + "*/\n" ); + + f.WriteFloatString("%s\n", name.c_str()); + f.WriteFloatString( "{\n" ); + WriteMaterialDef(-1, &f, MaterialDefManager::MATERIAL_DEF_MATERIAL, 1); + + for(int i = 0; i < editMaterial.stages.Num(); i++) { + if(editMaterial.stages[i]->enabled) { + WriteStage(i, &f); + } + } + + f.WriteFloatString( "}\n" ); + + return f.GetDataPtr(); + +} + +/** +* Writes the internal dictionary data to the standard format and replaces the +* idMaterial source text with the newly generated text. +*/ +void MaterialDoc::ReplaceSourceText() { + renderMaterial->SetText(GenerateSourceText()); +} + +/** +* Writes a single stage. +* @param stage The stage to write. +* @param file The file where the stage should be wirtten +*/ +void MaterialDoc::WriteStage(int stage, idFile_Memory* file) { + + //idStr stageName = GetAttribute(stage, "name"); + int type = GetAttributeInt(stage, "stagetype"); + //if(!stageName.Icmp("diffusemap") || !stageName.Icmp("specularmap") || !stageName.Icmp("bumpmap")) { + if(type == STAGE_TYPE_SPECIALMAP) { + WriteSpecialMapStage(stage, file); + return; + } + + file->WriteFloatString( "\t{\n" ); + idStr name = GetAttribute(stage, "name"); + if(name.Length() > 0) { + file->WriteFloatString("\t\tname\t\"%s\"\n", name.c_str()); + } + WriteMaterialDef(stage, file, MaterialDefManager::MATERIAL_DEF_STAGE, 2); + file->WriteFloatString( "\t}\n" ); + +} + +/** +* Writes a single special stage. +* @param stage The stage to write. +* @param file The file where the stage should be wirtten +*/ +void MaterialDoc::WriteSpecialMapStage(int stage, idFile_Memory* file) { + idStr stageName = GetAttribute(stage, "name"); + idStr map = GetAttribute(stage, "map"); + + file->WriteFloatString( "\t%s\t%s\n", stageName.c_str(), map.c_str() ); +} + +/** +* Writes a set of material attributes to a file. +* @param stage The stage to write or -1 for the material. +* @param file The file where the stage should be wirtten. +* @param type The attribute grouping to use. +* @param indent The number of tabs to indent the text. +*/ +void MaterialDoc::WriteMaterialDef(int stage, idFile_Memory* file, int type, int indent) { + + idStr prefix = ""; + for(int i = 0; i < indent; i++) { + prefix += "\t"; + } + + MaterialDefList* defs = MaterialDefManager::GetMaterialDefs(type); + for(int i = 0; i < defs->Num(); i++) { + switch((*defs)[i]->type) { + case MaterialDef::MATERIAL_DEF_TYPE_STRING: + { + idStr attrib = GetAttribute(stage, (*defs)[i]->dictName); + if(attrib.Length() > 0) { + if((*defs)[i]->quotes) + file->WriteFloatString("%s%s\t\"%s\"\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str()); + else + file->WriteFloatString("%s%s\t%s\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str()); + } + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_BOOL: + { + if(GetAttributeBool(stage, (*defs)[i]->dictName)) + file->WriteFloatString("%s%s\t\n",prefix.c_str(), (*defs)[i]->dictName.c_str()); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_FLOAT: + { + float val = GetAttributeFloat(stage, (*defs)[i]->dictName); + file->WriteFloatString("%s%s\t%f\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_INT: + { + int val = GetAttributeInt(stage, (*defs)[i]->dictName); + file->WriteFloatString("%s%s\t%d\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val); + } + break; + } + } +} + diff --git a/tools/materialeditor/MaterialDoc.h b/tools/materialeditor/MaterialDoc.h new file mode 100644 index 000000000..66a6ae79d --- /dev/null +++ b/tools/materialeditor/MaterialDoc.h @@ -0,0 +1,147 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" +#include "MaterialModifier.h" +#include "MaterialDef.h" + +/** +* Dictionary representation of a Material Stage. +*/ +typedef struct { + idDict stageData; + bool enabled; +} MEStage_t; + +/** +* Dictionary representation of a material. +*/ +typedef struct { + idDict materialData; + idList stages; +} MEMaterial_t; + +/** +* Implemented by the edit window that is responsible for modifying the material source text. +*/ +class SourceModifyOwner { + +public: + SourceModifyOwner() {}; + virtual ~SourceModifyOwner() {}; + + virtual idStr GetSourceText() { return ""; }; +}; + +class MaterialDocManager; + +/** +* Responsible for managing a single material that is being viewed and/or edited. +*/ +class MaterialDoc { + +public: + MaterialDocManager* manager; + idStr name; + idMaterial* renderMaterial; + MEMaterial_t editMaterial; + + bool modified; + bool applyWaiting; + bool deleted; + + bool sourceModify; + SourceModifyOwner* sourceModifyOwner; + +public: + MaterialDoc(void); + ~MaterialDoc(void); + + /** + * Define the types of stages in a material. + */ + enum { + STAGE_TYPE_NORMAL, + STAGE_TYPE_SPECIALMAP + }; + + //Initialization Methods + void SetRenderMaterial(idMaterial* material, bool parseMaterial = true, bool parseRenderMatierial = false); + + //Stage Info Methods + int GetStageCount(); + int FindStage(int stageType, const char* name); + MEStage_t GetStage(int stage); + void EnableStage(int stage, bool enabled); + void EnableAllStages(bool enabled); + bool IsStageEnabled(int stage); + + //Get Attributes + const char* GetAttribute(int stage, const char* attribName, const char* defaultString = ""); + int GetAttributeInt(int stage, const char* attribName, const char* defaultString = "0"); + float GetAttributeFloat(int stage, const char* attribName, const char* defaultString = "0"); + bool GetAttributeBool(int stage, const char* attribName, const char* defaultString = "0"); + + //Set Attribute Methods + void SetAttribute(int stage, const char* attribName, const char* value, bool addUndo = true); + void SetAttributeInt(int stage, const char* attribName, int value, bool addUndo = true); + void SetAttributeFloat(int stage, const char* attribName, float value, bool addUndo = true); + void SetAttributeBool(int stage, const char* attribName, bool value, bool addUndo = true); + void SetMaterialName(const char* materialName, bool addUndo = true); + void SetData(int stage, idDict* data); + + //Source Editing Methods + void SourceModify(SourceModifyOwner* owner); + bool IsSourceModified(); + void ApplySourceModify(idStr& text); + const char* GetEditSourceText(); + + //Stage Modification Methods + void AddStage(int stageType, const char* stageName, bool addUndo = true); + void InsertStage(int stage, int stageType, const char* stageName, bool addUndo = true); + void RemoveStage(int stage, bool addUndo = true); + void ClearStages(); + void MoveStage(int from, int to, bool addUndo = true); + + void ApplyMaterialChanges(bool force = false); + void Save(); + void Delete(); + +protected: + + //Internal Notifications + void OnMaterialChanged(); + + //Load Material Methods + void ParseMaterialText(const char* source); + void ParseMaterial(idLexer* src); + void ParseStage(idLexer* src); + void AddSpecialMapStage(const char* stageName, const char* map); + bool ParseMaterialDef(idToken* token, idLexer* src, int type, idDict* dict); + void ClearEditMaterial(); + + //Save/Apply Material Methods + const char* GenerateSourceText(); + void ReplaceSourceText(); + void WriteStage(int stage, idFile_Memory* file); + void WriteSpecialMapStage(int stage, idFile_Memory* file); + void WriteMaterialDef(int stage, idFile_Memory* file, int type, int indent); +}; + diff --git a/tools/materialeditor/MaterialDocManager.cpp b/tools/materialeditor/MaterialDocManager.cpp new file mode 100644 index 000000000..67893dc5e --- /dev/null +++ b/tools/materialeditor/MaterialDocManager.cpp @@ -0,0 +1,884 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialDocManager.h" +#include "MaterialView.h" + + +/** +* Constructor for MaterialDocManager. +*/ +MaterialDocManager::MaterialDocManager(void) { + currentMaterial = NULL; + cutMaterial = false; +} + +/** +* Destructor for MaterialDocManager. +*/ +MaterialDocManager::~MaterialDocManager(void) { + UnRegisterAllMaterialViews(); + + ClearUndo(); + ClearRedo(); +} + +/** +* Registers an object to receive notifications about changes made to materials. +* @param view The object that would like to receive material notifications. +*/ +void MaterialDocManager::RegisterMaterialView(MaterialView* view) { + ASSERT(view); + UnRegisterMaterialView(view); + materialViews.Append(view); + + //Notify the view of myself + view->SetMaterialDocManager(this); +} + +/** +* Tells the MaterialDocManager to stop sending notifications to a view. +* @param view The view that no longer wants notifications. +*/ +void MaterialDocManager::UnRegisterMaterialView(MaterialView* view) { + ASSERT(view); + materialViews.Remove(view); + + //Remove the reference to myself + view->SetMaterialDocManager(NULL); +} + +/** +* Unregisters all of the views that are registered to get material change +* notifications. +*/ +void MaterialDocManager::UnRegisterAllMaterialViews() { + + //Remove the reference to myself + int c = materialViews.Num(); + for(int i = 0; i < c; i++) { + materialViews[i]->SetMaterialDocManager(NULL); + } + materialViews.Clear(); +} + +/** +* Tells the MaterialDocManager which material has been selected for editing. +* @param material The material that has been selected. +*/ +void MaterialDocManager::SetSelectedMaterial(idMaterial* material) { + + bool change = false; + + //Do we need to change the material + if(material) { + if(currentMaterial) { + if(strcmp(material->GetName(), currentMaterial->renderMaterial->GetName())) { + change = true; + } + } else { + change = true; + } + } else { + if(currentMaterial) { + change = true; + } + } + + //Now make the change + if(change) { + if(currentMaterial) { + + //Delete the material unless it has been changed + if(!inProgressMaterials.Get(currentMaterial->name.c_str())) { + delete currentMaterial; + currentMaterial = NULL; + } + } + + MaterialDoc** tempDoc; + if(material && inProgressMaterials.Get(material->GetName(), &tempDoc)) { + currentMaterial = *tempDoc; + + } else { + currentMaterial = CreateMaterialDoc(material); + } + + NotifyViews(currentMaterial, SELECTION_CHANGE); + } +} + +/** +* Returns true if the specified file needs to be applied and false otherwise. +*/ +bool MaterialDocManager::DoesFileNeedApply(const char* filename) { + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename) && (*pDoc)->applyWaiting) + return true; + } + return false; +} + +/** +* Returns true if any material needs to be applied. +*/ +bool MaterialDocManager::DoesAnyNeedApply() { + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + if((*pDoc)->applyWaiting) + return true; + } + return false; +} + +/** +* Returns true if the specified file has been modified. +*/ +bool MaterialDocManager::IsFileModified(const char* filename) { + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename)) + return true; + } + return false; +} + +/** +* Returns true if any material has been modified. +*/ +bool MaterialDocManager::IsAnyModified() { + return (inProgressMaterials.Num() > 0); +} + +/** +* Adds a material. +* @param name The name of the material. +* @param filename The file to place the material in. +* @param sourceText The initial material definition. +* @param addUndo Can this operation be undone. +*/ +void MaterialDocManager::AddMaterial(const char* name, const char* filename, const char* sourceText, bool addUndo) { + + if(addUndo) { + AddMaterialModifier* mod = new AddMaterialModifier(this, name, filename); + AddMaterialUndoModifier(mod); + } + + MaterialDoc* newDoc = new MaterialDoc(); + newDoc->manager = this; + newDoc->modified = true; + + idMaterial* rendMat = (idMaterial*)declManager->CreateNewDecl(DECL_MATERIAL, name, filename); + + if(sourceText) { + rendMat->SetText(sourceText); + } + + newDoc->SetRenderMaterial(rendMat, true, sourceText ? true : false); + + inProgressMaterials.Set(newDoc->name.c_str(), newDoc); + + NotifyViews(newDoc, MATERIAL_ADD); + + //Force an apply so the text will be generated to match the new file + newDoc->applyWaiting = true; + newDoc->ApplyMaterialChanges(); +} + +/** +* Used to redo an add material and undo a delete material. +* The undo for adding a material deletes the material. Instead of adding a completely +* new material RedoAddMaterial finds the one that was just deleted and uses that. +* @param name The name of the material that was added/deleted. +* @param clearData Should the material definition be reset to the default definition. +*/ +void MaterialDocManager::RedoAddMaterial(const char* name, bool clearData) { + + MaterialDoc* newDoc = new MaterialDoc(); + newDoc->manager = this; + newDoc->modified = true; + + idMaterial* rendMat = const_cast(declManager->FindMaterial(name, false)); + + if(clearData) { + rendMat->SetText(rendMat->DefaultDefinition()); + } + + newDoc->SetRenderMaterial(rendMat, true, true); + + inProgressMaterials.Set(newDoc->name.c_str(), newDoc); + + NotifyViews(newDoc, MATERIAL_ADD); + + //Force an apply so the text will be generated to match the new file + newDoc->applyWaiting = true; + newDoc->ApplyMaterialChanges(); +} + +/** +* Deletes a material. +* @param material The material to be deleted. +* @param addUndo Can this operation be undone. +*/ +void MaterialDocManager::DeleteMaterial(MaterialDoc* material, bool addUndo) { + + assert(material); + + //This will just flag for delete. The actual delete will happen during the save + material->Delete(); + + if(addUndo) { + DeleteMaterialModifier* mod = new DeleteMaterialModifier(this, material->name); + AddMaterialUndoModifier(mod); + } + + NotifyViews(material, MATERIAL_DELETE); +} + +/** +* Applys changes to a material. +* @param materialDoc The material to be applied. +*/ +void MaterialDocManager::ApplyMaterial(MaterialDoc* materialDoc) { + assert(materialDoc); + materialDoc->ApplyMaterialChanges(); +} + +/** +* Applies all materials in the specified filename. +* @param filename The file to apply. +*/ +void MaterialDocManager::ApplyFile(const char* filename) { + + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename)) + (*pDoc)->ApplyMaterialChanges(); + } +} + +/** +* Applies all materials that have been changed. +*/ +void MaterialDocManager::ApplyAll() { + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + (*pDoc)->ApplyMaterialChanges(); + } +} + +/** +* Saves a single material. +* @param material The material to save. +*/ +void MaterialDocManager::SaveMaterial(MaterialDoc* material) { + assert(material); + material->Save(); +} + +/** +* Saves all materials in the specified file. +* @param filename The file to save. +*/ +void MaterialDocManager::SaveFile(const char* filename) { + + for(int i = inProgressMaterials.Num()-1; i >= 0; i--) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename)) + (*pDoc)->Save(); + } + + //Notify everyone + NotifyViews(NULL, MATERIAL_SAVE_FILE, filename); +} + +/** +* Saves all materials that have been changed. +*/ +void MaterialDocManager::SaveAllMaterials() { + for(int i = inProgressMaterials.Num()-1; i >= 0; i--) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + (*pDoc)->Save(); + } +} + +/** +* Reloads a specified file. +* @param filename The file to reload. +*/ +void MaterialDocManager::ReloadFile(const char *filename) { + + declManager->ReloadFile(filename, true); + + //purge the changes of any in progress materials + for(int j = inProgressMaterials.Num()-1; j >= 0; j--) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(j); + if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename)) { + (*pDoc)->SetRenderMaterial((*pDoc)->renderMaterial); + inProgressMaterials.Remove((*pDoc)->name); + } + } + + //Reparse the current material + if(currentMaterial) { + currentMaterial->SetRenderMaterial(currentMaterial->renderMaterial); + + //Trigger all the views to refresh + NotifyViews(currentMaterial, SELECTION_CHANGE); + } + + NotifyViews(NULL, FILE_RELOAD, filename); +} + +/** +* Creates a MaterialDoc object for the specified material name. If a MaterialDoc +* object already exists then it is used. +* @param materialName The name of the material for which to create a MaterialDoc object. +*/ +MaterialDoc* MaterialDocManager::CreateMaterialDoc(const char* materialName) { + + const idMaterial* material = declManager->FindMaterial(materialName); + return CreateMaterialDoc(const_cast(material)); +} + +/** +* Creates a MaterialDoc object for the specified material. If a MaterialDoc +* object already exists then it is used. +* @param material The material for which to create a MaterialDoc object. +*/ +MaterialDoc* MaterialDocManager::CreateMaterialDoc(idMaterial* material) { + + MaterialDoc* existingDoc = GetInProgressDoc(material); + if(existingDoc) { + return existingDoc; + } + + if(currentMaterial && material && !currentMaterial->name.Icmp(material->GetName())) { + return currentMaterial; + } + + if(material) { + MaterialDoc* newDoc = new MaterialDoc(); + newDoc->manager = this; + newDoc->SetRenderMaterial(material); + + return newDoc; + } + + return NULL; +} + +/** +* Checks the current list of in progress MaterialDoc objects to see if +* a MaterialDoc object already exists. +* @param material The material to check for. +*/ +MaterialDoc* MaterialDocManager::GetInProgressDoc(idMaterial* material) { + + if(material) { + for(int i = 0; i < inProgressMaterials.Num(); i++) { + MaterialDoc** pDoc = inProgressMaterials.GetIndex(i); + + if(!(*pDoc)->name.Icmp(material->GetName())) + return *pDoc; + } + } + return NULL; +} + +/** +* Prepares a material for a copy/cut and paste operations. +* @param materialDoc The material to copy. +* @param cut Is this a cut operation. +*/ +void MaterialDocManager::CopyMaterial(MaterialDoc* materialDoc, bool cut) { + + cutMaterial = cut; + + if(materialDoc) + copyMaterial = materialDoc->name; + else + ClearCopy(); +} + +/** +* Clears the copy buffer for a material. +*/ +void MaterialDocManager::ClearCopy() { + copyMaterial.Empty(); +} + +/** +* Returns true if there is a material in the copy buffer. +*/ +bool MaterialDocManager::IsCopyMaterial() { + return (copyMaterial.Length() ) ? true : false; +} + +/** +* Returns the name of the material in the copy buffer. +*/ +idStr MaterialDocManager::GetCopyMaterialName() { + return copyMaterial; +} + +/** +* Performs a material paste operation for a material in the copy buffer. +* @param name The new name for the material that is being copied. +* @param filename The file to paste the material in. +*/ +void MaterialDocManager::PasteMaterial(const char* name, const char* filename) { + + if(!IsCopyMaterial()) { + return; + } + + //Apply the material if there are some changes + MaterialDoc* copyMat = CreateMaterialDoc(copyMaterial); + if(copyMat->applyWaiting) { + copyMat->ApplyMaterialChanges(); + } + //Paste the material + idMaterial* material = copyMat->renderMaterial; + + //Add a material with the existing source text + char *declText = (char *) _alloca( material->GetTextLength() + 1 ); + material->GetText( declText ); + + AddMaterial(name, filename, declText, !cutMaterial); + + //If this is a cut then remove the original + if(cutMaterial) { + MaterialDoc* cutMaterial = CreateMaterialDoc(material); + DeleteMaterial(cutMaterial, false); + + MoveMaterialModifier* mod = new MoveMaterialModifier(this, name, filename, copyMaterial); + AddMaterialUndoModifier(mod); + + ClearCopy(); + } + +} + +/** +* Prepares a material stage for a copy/paste operation. +* @param materialDoc The materialDoc that contains the stage to be copied. +* @param stageNum the stage to copy. +*/ +void MaterialDocManager::CopyStage(MaterialDoc* materialDoc, int stageNum) { + + assert(materialDoc); + + copyStageMaterial = materialDoc->name; + copyStage = materialDoc->GetStage(stageNum); + + idStr stageName = copyStage.stageData.GetString("name"); +} + +/** +* Clears the copy buffer for copied stages. +*/ +void MaterialDocManager::ClearCopyStage() { + copyStageMaterial.Empty(); + copyStage.stageData.Clear(); +} + +/** +* Returns true if there is a stage in the copy buffer. +*/ +bool MaterialDocManager::IsCopyStage() { + return (copyStageMaterial.Length() ) ? true : false; +} + +/** +* Performs a paste operation of the stage in the copy buffer. +* @param materialDoc The materialDoc to paste the stage in. +*/ +void MaterialDocManager::PasteStage(MaterialDoc* materialDoc) { + + assert(materialDoc); + + int stageType = copyStage.stageData.GetInt("stagetype"); + + //Create a new stage and copy the data + materialDoc->AddStage(stageType, copyStage.stageData.GetString("name")); + materialDoc->SetData(materialDoc->GetStageCount()-1, ©Stage.stageData); +} + +/** +* Returns information about the stage in the copy buffer. +* @param type Holds the type of the stage in the copy buffer. +* @param name Hold the name of the stage in the copy buffer. +*/ +void MaterialDocManager::GetCopyStageInfo(int& type, idStr& name) { + if(IsCopyStage()) { + type = copyStage.stageData.GetInt("stagetype"); + name = copyStage.stageData.GetString("name"); + } +} + +/** +* Performs the first available undo operation. +*/ +void MaterialDocManager::Undo() { + + if(IsUndoAvailable()) { + MaterialModifier* mod = undoModifiers[undoModifiers.Num()-1]; + undoModifiers.RemoveIndex(undoModifiers.Num()-1); + + mod->Undo(); + + //Add this modifier to the redo list + AddMaterialRedoModifier(mod); + } +} + +/** +* Returns true if an undo operation is available. +*/ +bool MaterialDocManager::IsUndoAvailable() { + return (undoModifiers.Num() > 0); +} + +/** +* Clears the entire undo buffer. +*/ +void MaterialDocManager::ClearUndo() { + + int c = undoModifiers.Num(); + for(int i = 0; i < c; i++) { + delete undoModifiers[i]; + } + undoModifiers.Clear(); +} + +/** +* Performs the first available redo operation. +*/ +void MaterialDocManager::Redo() { + + if(IsRedoAvailable()) { + MaterialModifier* mod = redoModifiers[redoModifiers.Num()-1]; + redoModifiers.RemoveIndex(redoModifiers.Num()-1); + + mod->Redo(); + + //Done with the mod because the redo process will set + //attributes and create the appropriate redo modifier + AddMaterialUndoModifier(mod, false); + } +} + +/** +* Returns true if a redo operation is available. +*/ +bool MaterialDocManager::IsRedoAvailable() { + return (redoModifiers.Num() > 0); +} + +/** +* Clears the redo buffer. +*/ +void MaterialDocManager::ClearRedo() { + + int c = redoModifiers.Num(); + for(int i = 0; i < c; i++) { + delete redoModifiers[i]; + } + redoModifiers.Clear(); +} + +/** +* Adds an undo operation to the undo buffer. +* @param mod The MaterialModifier object that contains the undo data. +* @param clearRedo Should we clear the redo buffer. +*/ +void MaterialDocManager::AddMaterialUndoModifier(MaterialModifier* mod, bool clearRedo) { + undoModifiers.Append(mod); + + while(undoModifiers.Num() > MAX_UNDOREDO) { + undoModifiers.RemoveIndex(0); + } + + if(clearRedo) { + ClearRedo(); + } +} + +/** +* Adds a redo operation to the redo buffer. +* @param mod The MaterialModifier object that contains the redo data. +*/ +void MaterialDocManager::AddMaterialRedoModifier(MaterialModifier* mod) { + redoModifiers.Append(mod); + + while(redoModifiers.Num() > MAX_UNDOREDO) { + redoModifiers.RemoveIndex(0); + } +} + +/** +* Searches for a material that matches the specified search data. +* @param name The name of the material to search. +* @param searchData The search parameters. +* @param checkName If true then the name of the material will be checked along with the material text. +*/ +bool MaterialDocManager::FindMaterial(const char* name, MaterialSearchData_t* searchData, bool checkName) { + + //Fast way of finding the material without parsing + const idMaterial* material = static_cast(declManager->FindDeclWithoutParsing(DECL_MATERIAL, name, false)); + + if(material) { + + int findPos; + + if(checkName) { + //Check the name + idStr name = material->GetName(); + + findPos = name.Find(searchData->searchText, false); + if(findPos != -1) { + return true; + } + } + + //Skip to the open braket so the name is not checked + char *declText = (char *) _alloca( material->GetTextLength() + 1 ); + material->GetText( declText ); + + idStr text = declText; + int start = text.Find("{"); + if(start != -1) { + text = text.Right(text.Length()-start); + } + + findPos = text.Find(searchData->searchText, false); + if(findPos != -1) { + //Todo: Include match whole word + return true; + } + } + return false; +} + +/** +* Returns a unique material name given a base name. This is used to resolve materials with the same name. +* @param name The base name of the material. +*/ +idStr MaterialDocManager::GetUniqueMaterialName(idStr name) { + int num = 0; + while(1) { + idStr testName; + if(num == 0) + testName = name; + else + testName = va("%s%d", name.c_str(), num); + + const idMaterial* mat = declManager->FindMaterial(testName.c_str(), false); + if(!mat) { + return testName; + } else { + + //We can reuse delete material names + if(mat->GetTextLength() < 1) + return testName; + } + num++; + } +} + +/** +* Notifies all registered views of a material event. +* @param materialDoc The material that has been affected. +* @param notifyType The type of event that has occured. +* @param ... Notification specific data. See MaterialView. +*/ +void MaterialDocManager::NotifyViews(MaterialDoc* materialDoc, int notifyType, ... ) { + + va_list argptr; + + int c = materialViews.Num(); + for(int i = 0; i < c; i++) { + va_start( argptr, notifyType ); + switch(notifyType) { + case SELECTION_CHANGE: + materialViews[i]->MV_OnMaterialSelectionChange(materialDoc); + break; + case MATERIAL_CHANGE: + materialViews[i]->MV_OnMaterialChange(materialDoc); + break; + case MATERIAL_APPLY: + materialViews[i]->MV_OnMaterialApply(materialDoc); + break; + case MATERIAL_SAVE: + materialViews[i]->MV_OnMaterialSaved(materialDoc); + break; + case MATERIAL_SAVE_FILE: + materialViews[i]->MV_OnMaterialSaveFile(va_arg(argptr, const char*)); + break; + case MATERIAL_ADD: + materialViews[i]->MV_OnMaterialAdd(materialDoc); + break; + case MATERIAL_DELETE: + materialViews[i]->MV_OnMaterialDelete(materialDoc); + break; + case MATERIAL_ADD_STAGE: + materialViews[i]->MV_OnMaterialStageAdd(materialDoc, va_arg(argptr, int)); + break; + case MATERIAL_DELETE_STAGE: + materialViews[i]->MV_OnMaterialStageDelete(materialDoc, va_arg(argptr, int)); + break; + case MATERIAL_MOVE_STAGE: + { + int from = va_arg(argptr, int); + int to = va_arg(argptr, int); + materialViews[i]->MV_OnMaterialStageMove(materialDoc, from, to); + } + break; + case MATERIAL_ATTRIBUTE_CHANGE: + { + int stage = va_arg(argptr, int); + const char* attribName = va_arg(argptr, const char*); + materialViews[i]->MV_OnMaterialAttributeChanged(materialDoc, stage, attribName); + } + break; + case MATERIAL_NAME_CHANGE: + { + const char* oldName = va_arg(argptr, const char*); + materialViews[i]->MV_OnMaterialNameChanged(materialDoc, oldName); + } + break; + case FILE_RELOAD: + { + const char* filename = va_arg(argptr, const char*); + materialViews[i]->MV_OnFileReload(filename); + } + break; + } + va_end( argptr ); + } +} + +/** +* Called when a material has been edited and notifies all views of the change. +* @param materialDoc The material that has changed. +*/ +void MaterialDocManager::MaterialChanged(MaterialDoc* materialDoc) { + + //Make sure this material is in our list of changed materials + if(!inProgressMaterials.Get(materialDoc->name.c_str())) { + inProgressMaterials.Set(materialDoc->name.c_str(), materialDoc); + } + + //Notify everyone + NotifyViews(materialDoc, MATERIAL_CHANGE); +} + +/** +* Called when a material has been applied and notifies all views of the apply. +* @param materialDoc The material that has been applied. +*/ +void MaterialDocManager::MaterialApplied(MaterialDoc* materialDoc) { + + //Notify everyone + NotifyViews(materialDoc, MATERIAL_APPLY); +} + +/** +* Called when a material has been saved and notifies all views of the save. +* @param materialDoc The material that has been saved. +*/ +void MaterialDocManager::MaterialSaved(MaterialDoc* materialDoc) { + + MaterialDoc** tempDoc; + if(inProgressMaterials.Get(materialDoc->name.c_str(), &tempDoc)) { + + idStr name = materialDoc->name.c_str(); + + //Remove this file from our in progress list + inProgressMaterials.Remove(name.c_str()); + + //Notify everyone + NotifyViews(materialDoc, MATERIAL_SAVE); + + if(materialDoc != currentMaterial) + delete materialDoc; + } +} + +/** +* Called when a material name has been changed and notifies all views of the change. +* @param materialDoc The material that has changed. +*/ +void MaterialDocManager::MaterialNameChanged(const char* oldName, MaterialDoc* materialDoc) { + + MaterialDoc** tempDoc; + if(inProgressMaterials.Get(oldName, &tempDoc)) { + inProgressMaterials.Set(materialDoc->name, *tempDoc); + inProgressMaterials.Remove(oldName); + } + + NotifyViews(materialDoc, MATERIAL_NAME_CHANGE, oldName); +} + +/** +* Called when a stage is added and notifies all views of the addition. +* @param materialDoc The material that has changed. +* @param stageNum The stage that was added. +*/ +void MaterialDocManager::StageAdded(MaterialDoc* materialDoc, int stageNum) { + //Notify everyone + NotifyViews(materialDoc, MATERIAL_ADD_STAGE, stageNum); +} + +/** +* Called when a stage has been deleted and notifies all views of the change. +* @param materialDoc The material that has changed. +* @param stageNum The stage that was deleted. +*/ +void MaterialDocManager::StageDeleted(MaterialDoc* materialDoc, int stageNum) { + //Notify everyone + NotifyViews(materialDoc, MATERIAL_DELETE_STAGE, stageNum); +} + +/** +* Called when a stage has been movied and notifies all views of the change. +* @param materialDoc The material that has changed. +* @param from The original position of the stage. +* @param to The new position of the stage. +*/ +void MaterialDocManager::StageMoved(MaterialDoc* materialDoc, int from, int to) { + //Notify everyone + NotifyViews(materialDoc, MATERIAL_MOVE_STAGE, from, to); +} + +/** +* Called when a material attribute has been edited and notifies all views of the change. +* @param materialDoc The material that has changed. +* @param stage The stage that contains the changed attribute. +* @param attribName The name of the attribute that changed. +*/ +void MaterialDocManager::AttributeChanged(MaterialDoc* materialDoc, int stage, const char* attribName) { + //Notify everyone + NotifyViews(materialDoc, MATERIAL_ATTRIBUTE_CHANGE, stage, attribName); +} diff --git a/tools/materialeditor/MaterialDocManager.h b/tools/materialeditor/MaterialDocManager.h new file mode 100644 index 000000000..ecede9e1a --- /dev/null +++ b/tools/materialeditor/MaterialDocManager.h @@ -0,0 +1,154 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" +#include "MaterialModifier.h" +#include "MaterialDoc.h" + +class MaterialView; + +#define MAX_UNDOREDO 32 + +/** +* Responsible for managing the materials that are being viewed and/or edited. +*/ +class MaterialDocManager { + +public: + MaterialDocManager(void); + ~MaterialDocManager(void); + + //Reg/UnReg Material Views + void RegisterMaterialView(MaterialView* view); + void UnRegisterMaterialView(MaterialView* view); + void UnRegisterAllMaterialViews(); + + //Material Selection + void SetSelectedMaterial(idMaterial* material); + MaterialDoc* GetCurrentMaterialDoc() { return currentMaterial; }; + + //State Checking Methods + bool DoesFileNeedApply(const char* filename); + bool DoesAnyNeedApply(); + bool IsFileModified(const char* filename); + bool IsAnyModified(); + + //Adding or deleting a material + void AddMaterial(const char* name, const char* filename, const char* sourceText = NULL, bool addUndo = true); + void RedoAddMaterial(const char* name, bool clearData = true); + void DeleteMaterial(MaterialDoc* material, bool addUndo = true); + + //Applying + void ApplyMaterial(MaterialDoc* materialDoc); + void ApplyFile(const char* filename); + void ApplyAll(); + + //Saving + void SaveMaterial(MaterialDoc* material); + void SaveFile(const char* filename); + void SaveAllMaterials(); + + //File Reloading + void ReloadFile(const char *filename); + + + //Used to get and/or create a MaterialDoc object for editing + MaterialDoc* CreateMaterialDoc(const char* materialName); + MaterialDoc* CreateMaterialDoc(idMaterial* material); + MaterialDoc* GetInProgressDoc(idMaterial* material); + + //Copy Paste + void CopyMaterial(MaterialDoc* materialDoc = NULL, bool cut = false); + void ClearCopy(); + bool IsCopyMaterial(); + idStr GetCopyMaterialName(); + void PasteMaterial(const char* name, const char* filename); + + void CopyStage(MaterialDoc* materialDoc, int stageNum); + void ClearCopyStage(); + bool IsCopyStage(); + void PasteStage(MaterialDoc* materialDoc); + void GetCopyStageInfo(int& type, idStr& name); + + //Undo/Redo + void Undo(); + bool IsUndoAvailable(); + void ClearUndo(); + void Redo(); + bool IsRedoAvailable(); + void ClearRedo(); + void AddMaterialUndoModifier(MaterialModifier* mod, bool clearRedo = true); + void AddMaterialRedoModifier(MaterialModifier* mod); + + //Searching + bool FindMaterial(const char* name, MaterialSearchData_t* searchData, bool checkName); + + //Misc + idStr GetUniqueMaterialName(idStr name); + +protected: + + /** + * View notification types + */ + enum { + SELECTION_CHANGE, + MATERIAL_CHANGE, + MATERIAL_APPLY, + MATERIAL_SAVE, + MATERIAL_SAVE_FILE, + MATERIAL_ADD, + MATERIAL_DELETE, + MATERIAL_ADD_STAGE, + MATERIAL_DELETE_STAGE, + MATERIAL_MOVE_STAGE, + MATERIAL_ATTRIBUTE_CHANGE, + MATERIAL_NAME_CHANGE, + FILE_RELOAD + }; + void NotifyViews(MaterialDoc* materialDoc, int notifyType, ... ); + + //Doc Notification members + friend MaterialDoc; + void MaterialChanged(MaterialDoc* materialDoc); + void MaterialApplied(MaterialDoc* materialDoc); + void MaterialSaved(MaterialDoc* materialDoc); + void MaterialNameChanged(const char* oldName, MaterialDoc* materialDoc); + void StageAdded(MaterialDoc* materialDoc, int stageNum); + void StageDeleted(MaterialDoc* materialDoc, int stageNum); + void StageMoved(MaterialDoc* materialDoc, int from, int to); + void AttributeChanged(MaterialDoc* materialDoc, int stage, const char* attribName); + +protected: + idList materialViews; + MaterialDoc* currentMaterial; + idHashTable inProgressMaterials; + + idList undoModifiers; + idList redoModifiers; + + //Copy/Paste + bool cutMaterial; + idStr copyMaterial; + + //Copy/Paste Stage + idStr copyStageMaterial; + MEStage_t copyStage; +}; \ No newline at end of file diff --git a/tools/materialeditor/MaterialEditView.cpp b/tools/materialeditor/MaterialEditView.cpp new file mode 100644 index 000000000..8152f9c1e --- /dev/null +++ b/tools/materialeditor/MaterialEditView.cpp @@ -0,0 +1,299 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialEditView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +#define EDIT_HEIGHT 25 + +#define EDIT_TAB_CONTROL 0x2006 +#define NAME_CONTROL 0x2007 + +IMPLEMENT_DYNCREATE(MaterialEditView, CFormView) + +BEGIN_MESSAGE_MAP(MaterialEditView, CFormView) + ON_WM_SIZE() + ON_WM_CREATE() + ON_NOTIFY(TCN_SELCHANGE, EDIT_TAB_CONTROL, OnTcnSelChange) + ON_NOTIFY(EN_CHANGE, IDC_MATERIALEDITOR_EDIT_TEXT, OnEnChangeEdit) +END_MESSAGE_MAP() + +/** +* Constructor for MaterialEditView. +*/ +MaterialEditView::MaterialEditView() +: CFormView(MaterialEditView::IDD) { + + initHack = false; + sourceInit = false; + sourceChanged = false; +} + +/** +* Destructor for MaterialEditView. +*/ +MaterialEditView::~MaterialEditView() { +} + +/** +* Called when the selected material has changed. +* @param pMaterial The newly selected material. +*/ +void MaterialEditView::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) { + + //Apply any text changes that have been made + ApplyMaterialSource(); + + if(pMaterial) { + m_nameEdit.SetWindowText(pMaterial->name); + m_textView.SetReadOnly(false); + + //If the edit tab is selected then get the source + int sel = m_tabs.GetCurSel(); + if (sel == 1) { + GetMaterialSource(); + } + + currentMaterialName = pMaterial->name; + } else { + m_nameEdit.SetWindowText(""); + + GetMaterialSource(); + m_textView.SetReadOnly(true); + + currentMaterialName = ""; + } +} + +void MaterialEditView::MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName) { + if(!currentMaterialName.Icmp(oldName)) { + currentMaterialName = pMaterial->name; + } +} + +/** +* Returns the current source text in the source edit control. +*/ +idStr MaterialEditView::GetSourceText() { + idStr text; + m_textView.GetText(text); + + text.Replace( "\n", "" ); + text.Replace( "\r", "\r\n" ); + text.Replace( "\v", "\r\n" ); + text.StripLeading( "\r\n" ); + text.Insert( "\r\n\r\n", 0 ); + text.StripTrailing( "\r\n" ); + + return text; +} + +/** +* Gets the source of the current document and populates the +* source edit control. +*/ +void MaterialEditView::GetMaterialSource() { + + //Clear it + sourceInit = true; + m_textView.SetText(""); + sourceInit = false; + + if(materialDocManager) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(material) { + idStr text = material->GetEditSourceText(); + + // clean up new-line crapola + text.Replace( "\r", "" ); + text.Replace( "\n", "\r" ); + text.Replace( "\v", "\r" ); + text.StripLeading( '\r' ); + text.Append( "\r" ); + + sourceInit = true; + m_textView.SetText(text); + sourceInit = false; + } + } +} + +/** +* Takes the source out of the edit control and applies it +* to the material. +*/ +void MaterialEditView::ApplyMaterialSource() { + + if(!sourceChanged) + return; + + MaterialDoc* material = materialDocManager->CreateMaterialDoc(currentMaterialName); + + if(material) { + idStr text = GetSourceText(); + material->ApplySourceModify(text); + } + + sourceChanged = false; +} + +/** +* Transfers data to and from the controls in the console. +*/ +void MaterialEditView::DoDataExchange(CDataExchange* pDX) { + + CFormView::DoDataExchange(pDX); + + DDX_Control(pDX, IDC_MATERIALEDITOR_EDIT_TEXT, m_textView); +} + +/** +* Called by the MFC framework when the view is being created. +*/ +void MaterialEditView::OnInitialUpdate() { + + CFormView::OnInitialUpdate(); + + if(!initHack) { + initHack = true; + m_textView.Init(); + m_textView.LoadKeyWordsFromFile( "editors/material.def" ); + m_textView.ShowWindow(SW_HIDE); + + m_textView.SetText(""); + m_textView.SetReadOnly(true); + } +} + +/** +* Called by the MFC framework when the view is being created. +*/ +int MaterialEditView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFormView::OnCreate(lpCreateStruct) == -1) + return -1; + + m_nameEdit.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_READONLY, CRect(0,0,0,0), this, NAME_CONTROL); + + m_editSplitter.CreateStatic(this, 1, 2); + + if(!m_editSplitter.CreateView(0, 0, RUNTIME_CLASS(StageView), CSize(200, 200), NULL)) { + TRACE0("Failed to create stage property pane\n"); + return -1; + } + + if(!m_editSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialPropTreeView), CSize(500, 200), NULL)) { + TRACE0("Failed to create property pane\n"); + return -1; + } + + m_nameEdit.SetFont(materialEditorFont); + + m_stageView = (StageView*)m_editSplitter.GetPane(0, 0); + m_materialPropertyView = (MaterialPropTreeView*)m_editSplitter.GetPane(0, 1); + + m_tabs.Create(TCS_BOTTOM | TCS_FLATBUTTONS | WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, EDIT_TAB_CONTROL); + m_tabs.InsertItem(0, "Properties"); + m_tabs.InsertItem(1, "Text"); + + m_tabs.SetFont(materialEditorFont); + + return 0; +} + +/** +* Windows message called when the window is resized. +*/ +void MaterialEditView::OnSize(UINT nType, int cx, int cy) { + CFormView::OnSize(nType, cx, cy); + + CRect tabRect; + m_tabs.GetItemRect(0, tabRect); + + int tabHeight = tabRect.Height()+5; + + //Hardcode the edit window height + if(m_nameEdit.GetSafeHwnd()) { + m_nameEdit.MoveWindow(1,1, cx-2, 20); + } + + if(m_tabs.GetSafeHwnd()) { + m_tabs.MoveWindow(0, cy-tabHeight, cx, tabHeight); + } + + if(m_editSplitter.GetSafeHwnd()) { + m_editSplitter.MoveWindow(1, 22, cx-2, cy-tabHeight-22); + } + + if(m_textView.GetSafeHwnd()) { + m_textView.MoveWindow(1, 22, cx-2, cy-tabHeight-22); + } +} + +/** +* Called when the user changes the properties/text tab selection. This methods shows and hides +* the appropriate windows. +*/ +void MaterialEditView::OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult) { + + int sel = m_tabs.GetCurSel(); + + switch(sel) { + case 0: + m_editSplitter.ShowWindow(SW_SHOW); + m_textView.ShowWindow(SW_HIDE); + + ApplyMaterialSource(); + + m_stageView->RefreshStageList(); + + break; + case 1: + m_editSplitter.ShowWindow(SW_HIDE); + m_textView.ShowWindow(SW_SHOW); + + GetMaterialSource(); + m_textView.SetReadOnly(false); + } +} + +/** +* Called when the user changes text in the edit control +*/ +void MaterialEditView::OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + if(materialDocManager && !sourceInit) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(material && !material->IsSourceModified()) { + sourceChanged = true; + material->SourceModify(this); + } + } +} + + + + + + + diff --git a/tools/materialeditor/MaterialEditView.h b/tools/materialeditor/MaterialEditView.h new file mode 100644 index 000000000..7049aea5b --- /dev/null +++ b/tools/materialeditor/MaterialEditView.h @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" +#include "MaterialPropTreeView.h" +#include "StageView.h" + +#include "../comafx/CSyntaxRichEditCtrl.h" + +/** +* View that contains the material edit controls. These controls include +* the stage view, the properties view and the source view. +*/ +class MaterialEditView : public CFormView, public MaterialView, SourceModifyOwner { + +public: + enum{ IDD = IDD_MATERIALEDIT_FORM }; + + CEdit m_nameEdit; + CSplitterWnd m_editSplitter; + + StageView* m_stageView; + MaterialPropTreeView* m_materialPropertyView; + CTabCtrl m_tabs; + CSyntaxRichEditCtrl m_textView; + +public: + virtual ~MaterialEditView(); + + //MaterialView Interface + virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial); + virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName); + + //SourceModifyOwner Interface + virtual idStr GetSourceText(); + +protected: + MaterialEditView(); + DECLARE_DYNCREATE(MaterialEditView) + + void GetMaterialSource(); + void ApplyMaterialSource(); + + //CFormView Overrides + virtual void DoDataExchange(CDataExchange* pDX); + virtual void OnInitialUpdate(); + + //Message Handlers + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ); + DECLARE_MESSAGE_MAP() + +protected: + bool initHack; + bool sourceInit; + + bool sourceChanged; + idStr currentMaterialName; +}; diff --git a/tools/materialeditor/MaterialEditor.cpp b/tools/materialeditor/MaterialEditor.cpp new file mode 100644 index 000000000..07b811c76 --- /dev/null +++ b/tools/materialeditor/MaterialEditor.cpp @@ -0,0 +1,167 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/win_local.h" + +#include "MaterialEditor.h" +#include "MEMainFrame.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +MEMainFrame* meMainFrame = NULL; + +CFont* materialEditorFont = NULL; + +/** +* Initializes the material editor tool. +*/ +void MaterialEditorInit( void ) { + + InitPropTree(win32.hInstance); + + com_editors = EDITOR_MATERIAL; + + Sys_GrabMouseCursor( false ); + + InitAfx(); + + InitCommonControls(); + + // Initialize OLE libraries + if (!AfxOleInit()) + { + return; + } + AfxEnableControlContainer(); + + NONCLIENTMETRICS info; + info.cbSize = sizeof(info); + + ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + + LOGFONT lf; + memset(&lf, 0, sizeof (LOGFONT)); + + CWindowDC dc(NULL); + lf.lfCharSet = (BYTE)GetTextCharsetInfo(dc.GetSafeHdc(), NULL, 0); + + lf.lfHeight = info.lfMenuFont.lfHeight; + lf.lfWeight = info.lfMenuFont.lfWeight; + lf.lfItalic = info.lfMenuFont.lfItalic; + + // check if we should use system font + _tcscpy(lf.lfFaceName, info.lfMenuFont.lfFaceName); + + materialEditorFont = new CFont; + materialEditorFont->CreateFontIndirect(&lf); + + + // To create the main window, this code creates a new frame window + // object and then sets it as the application's main window object + meMainFrame = new MEMainFrame; + + // create and load the frame with its resources + meMainFrame->LoadFrame(IDR_ME_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); + + + // hide the doom window by default + ::ShowWindow ( win32.hWnd, SW_HIDE ); + + // The one and only window has been initialized, so show and update it + meMainFrame->ShowWindow(SW_SHOW); + meMainFrame->UpdateWindow(); +} + +/** +* Called every frame by the doom engine to allow the material editor to process messages. +*/ +void MaterialEditorRun( void ) { + + MSG *msg = AfxGetCurrentMessage(); + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +/** +* Called by the doom engine when the material editor needs to be destroyed. +*/ +void MaterialEditorShutdown( void ) { + + delete meMainFrame; + + delete materialEditorFont; + + meMainFrame = NULL; +} + +/** +* Allows the doom engine to reflect console output to the material editors console. +*/ +void MaterialEditorPrintConsole( const char *msg ) { + if(com_editors & EDITOR_MATERIAL) + meMainFrame->PrintConsoleMessage(msg); +} + +/** +* Returns the handle to the main Material Editor Window +*/ +HWND GetMaterialEditorWindow() { + return meMainFrame->GetSafeHwnd(); +} + +/** +* Simple about box for the material editor. +*/ +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + + enum { IDD = IDD_ME_ABOUTBOX }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +}; + +/** +* Constructor for the about box. +*/ +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { +} + +/** +* Called by the MFC framework to exchange data with the window controls. +*/ +void CAboutDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) +END_MESSAGE_MAP() + diff --git a/tools/materialeditor/MaterialEditor.h b/tools/materialeditor/MaterialEditor.h new file mode 100644 index 000000000..63751404d --- /dev/null +++ b/tools/materialeditor/MaterialEditor.h @@ -0,0 +1,36 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "../../sys/win32/rc/MaterialEditor_resource.h" + +/** +* Structure used to store the user defined search parameters. +*/ +typedef struct { + bool searched; + idStr searchText; + int nameOnly; + int searchScope; +} MaterialSearchData_t; + + +extern CFont* materialEditorFont; + +extern HWND GetMaterialEditorWindow(); \ No newline at end of file diff --git a/tools/materialeditor/MaterialModifier.cpp b/tools/materialeditor/MaterialModifier.cpp new file mode 100644 index 000000000..b27d97d83 --- /dev/null +++ b/tools/materialeditor/MaterialModifier.cpp @@ -0,0 +1,419 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialModifier.h" +#include "MaterialDocManager.h" +#include "MaterialTreeView.h" + +////////////////////////////////////////////////////////////////////////////// +//MaterialModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for MaterialModifier +*/ +MaterialModifier::MaterialModifier(MaterialDocManager* manager, const char* materialName) { + this->manager = manager; + this->materialName = materialName; +} + +////////////////////////////////////////////////////////////////////////////// +//AttributeMaterialModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for AttributeMaterialModifier +*/ +AttributeMaterialModifier::AttributeMaterialModifier(MaterialDocManager* manager, const char* materialName, int stage, const char* key) +: MaterialModifier(manager, materialName) { + + this->stage = stage; + this->key = key; + +} + +////////////////////////////////////////////////////////////////////////////// +//AttributeMaterialModifierString +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for AttributeMaterialModifierString +*/ +AttributeMaterialModifierString::AttributeMaterialModifierString(MaterialDocManager* manager, const char* materialName, int stage, const char* key, const char* value, const char* oldValue) +: AttributeMaterialModifier(manager, materialName, stage, key) { + + this->value = value; + this->oldValue = oldValue; +} + +/** +* Performs an undo operation of a string attribute change. +*/ +void AttributeMaterialModifierString::Undo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->SetAttribute(stage, key, oldValue, false); +} + +/** +* Performs a redo operation of a string attribute change. +*/ +void AttributeMaterialModifierString::Redo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->SetAttribute(stage, key, value, false); +} + +////////////////////////////////////////////////////////////////////////////// +//AttributeMaterialModifierBool +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for AttributeMaterialModifierBool +*/ +AttributeMaterialModifierBool::AttributeMaterialModifierBool(MaterialDocManager* manager, const char* materialName, int stage, const char* key, bool value, bool oldValue) +: AttributeMaterialModifier(manager, materialName, stage, key) { + + this->value = value; + this->oldValue = oldValue; +} + +/** +* Performs an undo operation of a boolean attribute change. +*/ +void AttributeMaterialModifierBool::Undo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->SetAttributeBool(stage, key, oldValue, false); +} + +/** +* Performs a redo operation of a boolean attribute change. +*/ +void AttributeMaterialModifierBool::Redo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->SetAttributeBool(stage, key, value, false); +} + +////////////////////////////////////////////////////////////////////////////// +//StageMoveModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for StageMoveModifier +*/ +StageMoveModifier::StageMoveModifier(MaterialDocManager* manager, const char* materialName, int from, int to) +: MaterialModifier(manager, materialName) { + this->from = from; + this->to = to; +} + +/** +* Performs an undo operation of a stage move. +*/ +void StageMoveModifier::Undo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->MoveStage(to, from, false); +} + +/** +* Performs a redo operation of a moved stage. +*/ +void StageMoveModifier::Redo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->MoveStage(from, to, false); +} + +////////////////////////////////////////////////////////////////////////////// +//StageDeleteModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for StageDeleteModifier +*/ +StageDeleteModifier::StageDeleteModifier(MaterialDocManager* manager, const char* materialName, int stageNum, idDict stageData) +: MaterialModifier(manager, materialName) { + this->stageNum = stageNum; + this->stageData = stageData; +} + +/** +* Performs an undo operation of a deleted stage. +*/ +void StageDeleteModifier::Undo() { + + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->InsertStage(stageNum, stageData.GetInt("stagetype"), stageData.GetString("name"), false); + material->SetData(stageNum, &stageData); + +} + +/** +* Performs a redo operation of a deleted stage. +*/ +void StageDeleteModifier::Redo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->RemoveStage(stageNum, false); +} + +////////////////////////////////////////////////////////////////////////////// +//StageInsertModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for StageInsertModifier +*/ +StageInsertModifier::StageInsertModifier(MaterialDocManager* manager, const char* materialName, int stageNum, int stageType, const char* stageName) +: MaterialModifier(manager, materialName) { + this->stageNum = stageNum; + this->stageType = stageType; + this->stageName = stageName; +} + +/** +* Performs an undo operation of an inserted stage. +*/ +void StageInsertModifier::Undo() { + + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->RemoveStage(stageNum, false); +} + +/** +* Performs a redo operation of an inserted stage. +*/ +void StageInsertModifier::Redo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->InsertStage(stageNum, stageType, stageName, false); +} + +////////////////////////////////////////////////////////////////////////////// +//AddMaterialModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for AddMaterialModifier +*/ +AddMaterialModifier::AddMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile) +: MaterialModifier(manager, materialName) { + this->materialFile = materialFile; +} + +/** +* Performs an undo operation of an added material. +*/ +void AddMaterialModifier::Undo() { + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + manager->DeleteMaterial(material, false); +} + +/** +* Performs a redo operation of an added material. +*/ +void AddMaterialModifier::Redo() { + manager->RedoAddMaterial(materialName); +} + +////////////////////////////////////////////////////////////////////////////// +//DeleteMaterialModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for DeleteMaterialModifier +*/ +DeleteMaterialModifier::DeleteMaterialModifier(MaterialDocManager* manager, const char* materialName) +: MaterialModifier(manager, materialName) { +} + +/** +* Performs an undo operation of a deleted material. +*/ +void DeleteMaterialModifier::Undo() { + + manager->RedoAddMaterial(materialName, false); +} + +/** +* Performs a redo operation of a deleted material. +*/ +void DeleteMaterialModifier::Redo() { + + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + manager->DeleteMaterial(material, false); +} + + +////////////////////////////////////////////////////////////////////////////// +//MoveMaterialModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for MoveMaterialModifier +*/ +MoveMaterialModifier::MoveMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile, const char* copyMaterial) +: MaterialModifier(manager, materialName) { + this->materialFile = materialFile; + this->copyMaterial = copyMaterial; +} + +/** +* Performs an undo operation of a moved material +*/ +void MoveMaterialModifier::Undo() { + + //Delete New Material + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + manager->DeleteMaterial(material, false); + + //RedoAdd Old Material + manager->RedoAddMaterial(copyMaterial, false); +} + +/** +* Performs a redo operation of a moved material. +*/ +void MoveMaterialModifier::Redo() { + //Delete Old Material + MaterialDoc* material = manager->CreateMaterialDoc(copyMaterial); + manager->DeleteMaterial(material, false); + + //Redo Add New Material + manager->RedoAddMaterial(materialName, false); +} + +////////////////////////////////////////////////////////////////////////////// +//RenameMaterialModifier +////////////////////////////////////////////////////////////////////////////// +/** +* Constructor for RenameMaterialModifier +*/ +RenameMaterialModifier::RenameMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* oldName) +: MaterialModifier(manager, materialName) { + this->oldName = oldName; +} + +/** +* Performs an undo operation of a renamed material +*/ +void RenameMaterialModifier::Undo() { + + MaterialDoc* material = manager->CreateMaterialDoc(materialName); + material->SetMaterialName(oldName, false); +} + +/** +* Performs a redo operation of a renamed material. +*/ +void RenameMaterialModifier::Redo() { + + MaterialDoc* material = manager->CreateMaterialDoc(oldName); + material->SetMaterialName(materialName, false); +} + +////////////////////////////////////////////////////////////////////////////// +//AddMaterialFolderModifier +////////////////////////////////////////////////////////////////////////////// +/** +* Constructor for AddMaterialFolderModifier +*/ +AddMaterialFolderModifier::AddMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, HTREEITEM parent) +: MaterialModifier(manager, materialName) { + this->view = view; + this->item = item; + this->parent = parent; +} + +/** +* Performs an undo operation of an added material folder. +*/ +void AddMaterialFolderModifier::Undo() { + view->DeleteFolder(item, false); +} + +/** +* Performs a redo operation of an added material folder. +*/ +void AddMaterialFolderModifier::Redo() { + view->AddFolder(materialName, parent); +} + +////////////////////////////////////////////////////////////////////////////// +//RenameMaterialFolderModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for RenameMaterialFolderModifier +*/ +RenameMaterialFolderModifier::RenameMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, const char* oldName) +: MaterialModifier(manager, materialName) { + this->view = view; + this->item = item; + this->oldName = oldName; +} + +/** +* Performs an undo operation of a renamed material folder. +*/ +void RenameMaterialFolderModifier::Undo() { + view->RenameFolder(item, oldName); +} + +/** +* Performs a redo operation of a renamed material folder. +*/ +void RenameMaterialFolderModifier::Redo() { + view->RenameFolder(item, materialName); +} + + +////////////////////////////////////////////////////////////////////////////// +//DeleteMaterialFolderModifier +////////////////////////////////////////////////////////////////////////////// + +/** +* Constructor for DeleteMaterialFolderModifier +*/ +DeleteMaterialFolderModifier::DeleteMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM parent, idStrList* affectedMaterials) +: MaterialModifier(manager, materialName) { + this->view = view; + this->parent = parent; + this->affectedMaterials = *affectedMaterials; +} + +/** +* Performs an undo operation of a deleted material folder. +*/ +void DeleteMaterialFolderModifier::Undo() { + + //Add the folder back and save the folder position for the redo + item = view->AddFolder(materialName, parent); + + //Add each of the children back + for(int i = 0; i < affectedMaterials.Num(); i++) { + manager->RedoAddMaterial(affectedMaterials[i], false); + } +} + +/** +* Performs a redo operation of a deleted material folder. +*/ +void DeleteMaterialFolderModifier::Redo() { + + view->DeleteFolder(item, false); +} + diff --git a/tools/materialeditor/MaterialModifier.h b/tools/materialeditor/MaterialModifier.h new file mode 100644 index 000000000..83574077b --- /dev/null +++ b/tools/materialeditor/MaterialModifier.h @@ -0,0 +1,259 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialEditor.h" + +class MaterialDocManager; +class MaterialTreeView; + +/** +* Base class for modifications that can be made to a material that can be undone and redone. +*/ +class MaterialModifier { + +public: + MaterialModifier(MaterialDocManager* manager, const char* materialName); + virtual ~MaterialModifier() {}; + + virtual void Undo() = 0; + virtual void Redo() = 0; + +protected: + MaterialDocManager* manager; + idStr materialName; +}; + +/** +* Base class for Undo/Redo operations for attribute changes +*/ +class AttributeMaterialModifier : public MaterialModifier { + +public: + AttributeMaterialModifier(MaterialDocManager* manager, const char* materialName, int stage, const char* key); + virtual ~AttributeMaterialModifier() {}; + + virtual void Undo() = 0; + virtual void Redo() = 0; + +protected: + int stage; + idStr key; +}; + +/** +* Undo/Redo operation for string attribute changes +*/ +class AttributeMaterialModifierString : public AttributeMaterialModifier { + +public: + AttributeMaterialModifierString(MaterialDocManager* manager, const char* materialName, int stage, const char* key, const char* value, const char* oldValue); + virtual ~AttributeMaterialModifierString() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + idStr value; + idStr oldValue; + +}; + +/** +* Undo/Redo operation for boolean attribute changes +*/ +class AttributeMaterialModifierBool : public AttributeMaterialModifier { + +public: + AttributeMaterialModifierBool(MaterialDocManager* manager, const char* materialName, int stage, const char* key, bool value, bool oldValue); + virtual ~AttributeMaterialModifierBool() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + bool value; + bool oldValue; + +}; + +/** +* Undo/Redo operation for stage moves +*/ +class StageMoveModifier : public MaterialModifier { + +public: + StageMoveModifier(MaterialDocManager* manager, const char* materialName, int from, int to); + virtual ~StageMoveModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + int from; + int to; +}; + +/** +* Undo/Redo operation for stage deletes +*/ +class StageDeleteModifier : public MaterialModifier { +public: + StageDeleteModifier(MaterialDocManager* manager, const char* materialName, int stageNum, idDict stageData); + virtual ~StageDeleteModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + int stageNum; + idDict stageData; +}; + +/** +* Undo/Redo operation for stage inserts +*/ +class StageInsertModifier : public MaterialModifier { +public: + StageInsertModifier(MaterialDocManager* manager, const char* materialName, int stageNum, int stageType, const char* stageName); + virtual ~StageInsertModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + int stageNum; + int stageType; + idStr stageName; +}; + +/** +* Undo/Redo operation for adding materials +*/ +class AddMaterialModifier : public MaterialModifier { +public: + AddMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile); + virtual ~AddMaterialModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + idStr materialFile; +}; + +/** +* Undo/Redo operation for deleting materials +*/ +class DeleteMaterialModifier : public MaterialModifier { +public: + DeleteMaterialModifier(MaterialDocManager* manager, const char* materialName); + virtual ~DeleteMaterialModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + +}; + +/** +* Undo/Redo operation for moving materials +*/ +class MoveMaterialModifier : public MaterialModifier { +public: + MoveMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile, const char* copyMaterial); + virtual ~MoveMaterialModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + idStr materialFile; + idStr copyMaterial; +}; + +/** +* Undo/Redo operation for renaming materials +*/ +class RenameMaterialModifier : public MaterialModifier { +public: + RenameMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* oldName); + virtual ~RenameMaterialModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + idStr oldName; +}; + +/** +* Undo/Redo operation for adding material folders +*/ +class AddMaterialFolderModifier : public MaterialModifier { +public: + AddMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, HTREEITEM parent); + virtual ~AddMaterialFolderModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + MaterialTreeView* view; + HTREEITEM item; + HTREEITEM parent; +}; + +/** +* Undo/Redo operation for renaming a material folder +*/ +class RenameMaterialFolderModifier : public MaterialModifier { +public: + RenameMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, const char* oldName); + virtual ~RenameMaterialFolderModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + MaterialTreeView* view; + HTREEITEM item; + idStr oldName; +}; + +/** +* Undo/Redo operation for deleting a material folder +*/ +class DeleteMaterialFolderModifier : public MaterialModifier { +public: + DeleteMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM parent, idStrList* affectedMaterials); + virtual ~DeleteMaterialFolderModifier() {}; + + virtual void Undo(); + virtual void Redo(); + +protected: + MaterialTreeView* view; + idStrList affectedMaterials; + + HTREEITEM item; + HTREEITEM parent; +}; + diff --git a/tools/materialeditor/MaterialPreviewPropView.cpp b/tools/materialeditor/MaterialPreviewPropView.cpp new file mode 100644 index 000000000..c26c407f3 --- /dev/null +++ b/tools/materialeditor/MaterialPreviewPropView.cpp @@ -0,0 +1,359 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + + +#include "MaterialPreviewPropView.h" + + +// MaterialPropTreeView + +IMPLEMENT_DYNCREATE(MaterialPreviewPropView, CPropTreeView) + + +MaterialPreviewPropView::MaterialPreviewPropView() { + numLights = 0; + materialPreview = NULL; +} + +MaterialPreviewPropView::~MaterialPreviewPropView() { +} + +BEGIN_MESSAGE_MAP(MaterialPreviewPropView, CPropTreeView) + ON_NOTIFY( PTN_ITEMCHANGED, IDC_PROPERTYTREE, OnPropertyChangeNotification ) + ON_NOTIFY( PTN_ITEMBUTTONCLICK, IDC_PROPERTYTREE, OnPropertyButtonClick ) +END_MESSAGE_MAP() + + +void MaterialPreviewPropView::AddLight( void ) { + int i, count, lightShaderIndex = 0; + const idMaterial *mat; + + CPropTreeItemButton* pRoot; + CPropTreeItemCombo* pCombo; + CPropTreeItemColor* pColor; + CPropTreeItemCheck* pCheck; + CPropTreeItemEdit* pEdit; + + //Increase the number of lights + numLights++; + + pRoot = (CPropTreeItemButton*)m_Tree.InsertItem(new CPropTreeItemButton()); + pRoot->SetLabelText(_T(va("Light #%d", numLights))); + pRoot->SetInfoText(_T(va("Parameters for light number %d.", numLights))); + pRoot->SetButtonText( "Remove" ); + pRoot->SetCtrlID( numLights - 1 ); + pRoot->Expand(); + + pCombo = (CPropTreeItemCombo*)m_Tree.InsertItem(new CPropTreeItemCombo(), pRoot); + pCombo->SetLabelText( _T("Shader") ); + pCombo->SetInfoText( _T("Set the light shader.") ); + pCombo->SetDropDownHeight( 200 ); + pCombo->CreateComboBox(); + // Add all light shaders to the combo box + count = declManager->GetNumDecls( DECL_MATERIAL ); + for (i = 0; i < count; i++) { + mat = declManager->MaterialByIndex(i, false); + + idStr materialName = mat->GetName(); + materialName.ToLower(); + + if ( materialName.Left(7) == "lights/" || materialName.Left(5) == "fogs/" ) { + pCombo->InsertString( lightShaderIndex, materialName ); + pCombo->SetItemData( lightShaderIndex, lightShaderIndex ); + + if ( materialName == "lights/defaultpointlight" ) { + pCombo->SetCurSel( lightShaderIndex ); + } + + lightShaderIndex++; + } + } + + pColor = (CPropTreeItemColor*)m_Tree.InsertItem(new CPropTreeItemColor(), pRoot); + pColor->SetLabelText(_T("Color")); + pColor->SetInfoText(_T("Color of the light.")); + pColor->SetItemValue((LPARAM)RGB(0xff, 0xff, 0xff)); // default as color white + + pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pRoot); + pEdit->SetLabelText(_T("Radius")); + pEdit->SetInfoText(_T("Radius of the light.")); + pEdit->SetItemValue( (LPARAM)_T("300.0") ); + + pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem(new CPropTreeItemCheck(), pRoot); + pCheck->SetLabelText(_T("Move light")); + pCheck->SetInfoText(_T("When checked, allow light to move.")); + pCheck->CreateCheckBox(); + pCheck->SetCheckState( BST_CHECKED ); + + if ( materialPreview ) { + materialPreview->OnAddLight(); + } +} + +//Create sample data for the preview properties +void MaterialPreviewPropView::InitializePropTree( void ) { + int i; + CPropTreeItem *pRoot; + CPropTreeItem *pParmRoot; + CPropTreeItemCheck *pCheck; + CPropTreeItemEdit *pEdit; + + pRoot = m_Tree.InsertItem(new CPropTreeItem()); + pRoot->SetLabelText(_T("Preview Properties")); + pRoot->SetInfoText(_T("Properties for the preview window.")); + pRoot->Expand(); // have this item expanded by default + + CPropTreeItemCombo* pCombo; + pCombo = (CPropTreeItemCombo*)m_Tree.InsertItem(new CPropTreeItemCombo(), pRoot); + pCombo->SetLabelText(_T("Model Type")); + pCombo->SetInfoText(_T("Select the type of model on which to preview the material.")); + pCombo->CreateComboBox(); + pCombo->InsertString( 0, "Cube" ); + pCombo->InsertString( 1, "Box - 2:1"); + pCombo->InsertString( 2, "Box - 4:1"); + pCombo->InsertString( 3, "Box - 1:2"); + pCombo->InsertString( 4, "Box - 1:4"); + pCombo->InsertString( 5, "Cylinder - V"); + pCombo->InsertString( 6, "Cylinder - H"); + pCombo->InsertString( 7, "Sphere"); + pCombo->SetItemData( 0, 0 ); + pCombo->SetItemData( 1, 1 ); + pCombo->SetItemData( 2, 2 ); + pCombo->SetItemData( 3, 3 ); + pCombo->SetItemData( 4, 4 ); + pCombo->SetItemData( 5, 5 ); + pCombo->SetItemData( 6, 6 ); + pCombo->SetItemData( 7, 7 ); + + pCombo->SetCurSel( 0 ); + + // Custom model entry + /*pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pRoot ); + pEdit->SetLabelText(_T("Custom Model")); + pEdit->SetInfoText(_T("Specify any model to display the current material.")); + pEdit->SetItemValue((LPARAM)_T(""));*/ + CPropTreeItemEditButton *pCutomButton; + pCutomButton = (CPropTreeItemEditButton*)m_Tree.InsertItem(new CPropTreeItemEditButton(), pRoot ); + pCutomButton->SetButtonText(_T("...")); + pCutomButton->SetLabelText(_T("Custom Model")); + pCutomButton->SetInfoText(_T("Specify any model to display the current material.")); + pCutomButton->SetItemValue((LPARAM)_T("")); + + // Checkbox for showing debug light spheres + pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem( new CPropTreeItemCheck(), pRoot ); + pCheck->SetLabelText(_T("Show Lights")); + pCheck->SetInfoText(_T("Show the light origin sphere and number in the preview.")); + pCheck->CreateCheckBox(); + pCheck->SetCheckState( BST_CHECKED ); + + // Local and Global shader parms + pParmRoot = m_Tree.InsertItem(new CPropTreeItem()); + pParmRoot->SetLabelText(_T("Local Parms")); + pParmRoot->SetInfoText(_T("Local shaderparms for the model being displayed.")); + pParmRoot->Expand( FALSE ); // have this item NOT expanded by default + + for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { + pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pParmRoot ); + pEdit->SetLabelText(_T(va("parm%d", i))); + pEdit->SetInfoText(_T("Set the local shaderparm for the model")); + if ( i < 4 ) { + pEdit->SetItemValue((LPARAM)_T("1")); + } else { + pEdit->SetItemValue((LPARAM)_T("0")); + } + } + + pParmRoot = m_Tree.InsertItem(new CPropTreeItem()); + pParmRoot->SetLabelText(_T("Global Parms")); + pParmRoot->SetInfoText(_T("Global shaderparms for the renderworld being displayed.")); + pParmRoot->Expand( FALSE ); // have this item NOT expanded by default + + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pParmRoot ); + pEdit->SetLabelText(_T(va("global%d", i))); + pEdit->SetInfoText(_T("Set the global shaderparm for the renderworld")); + if ( i < 4 ) { + pEdit->SetItemValue((LPARAM)_T("1")); + } else { + pEdit->SetItemValue((LPARAM)_T("0")); + } + } + + // Lights + + pRoot = m_Tree.InsertItem(new CPropTreeItem()); + pRoot->SetLabelText(_T("")); + pRoot->SetInfoText(_T("")); + + CPropTreeItemButton *pButton; + pButton = (CPropTreeItemButton*)m_Tree.InsertItem(new CPropTreeItemButton()); + pButton->SetButtonText(_T(" Add Light ")); + pButton->SetLabelText(_T("Preview Lights")); + pButton->SetInfoText(_T("Test the button.")); + + pRoot = m_Tree.InsertItem(new CPropTreeItem()); + pRoot->SetLabelText(_T("")); + pRoot->SetInfoText(_T("")); + + AddLight(); +} + +// MaterialPreviewPropView drawing + +void MaterialPreviewPropView::OnDraw(CDC* pDC) +{ + // TODO: add draw code here +} + +// MaterialPreviewPropView diagnostics + +#ifdef _DEBUG +void MaterialPreviewPropView::AssertValid() const +{ + CPropTreeView::AssertValid(); +} + +void MaterialPreviewPropView::Dump(CDumpContext& dc) const +{ + CPropTreeView::Dump(dc); +} +#endif //_DEBUG + + +void MaterialPreviewPropView::RegisterPreviewView( MaterialPreviewView *view ) { + materialPreview = view; +} + +// MaterialPreviewPropView message handlers + +void MaterialPreviewPropView::OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ) { + idVec3 testColor; + int lightId = 0; + COLORREF color; + NMPROPTREE *nmProp; + CPropTreeItem *item; + CPropTreeItem *parent; + + nmProp = (NMPROPTREE *)nmhdr; + item = nmProp->pItem; + + // Determine which light this item modifies + parent = item->GetParent(); + if ( parent ) { + lightId = parent->GetCtrlID(); + } + + idStr itemLabel = item->GetLabelText(); + + if ( itemLabel == "Model Type" ) { + materialPreview->OnModelChange( item->GetItemValue() ); + + } else if ( itemLabel == "Custom Model" ) { + materialPreview->OnCustomModelChange( (const char *)item->GetItemValue() ); + + } else if ( itemLabel == "Show Lights" ) { + materialPreview->OnShowLightsChange( item->GetItemValue() ? true : false ); + + } else if ( itemLabel == "Shader" ) { + CPropTreeItemCombo *combo = (CPropTreeItemCombo *)item; + CString materialName; + + combo->GetLBText( combo->GetCurSel(), materialName ); + + materialPreview->OnLightShaderChange( lightId, materialName.GetBuffer() ); + + } else if ( itemLabel == "Radius" ) { + materialPreview->OnLightRadiusChange( lightId, atof( (char *)item->GetItemValue() ) ); + + } else if ( itemLabel == "Color" ) { + color = item->GetItemValue(); + + testColor.x = (float)GetRValue( color ) * (float)( 1.f/255.f ); + testColor.y = (float)GetGValue( color ) * (float)( 1.f/255.f ); + testColor.z = (float)GetBValue( color ) * (float)( 1.f/255.f ); + + materialPreview->OnLightColorChange( lightId, testColor ); + + } else if ( itemLabel == "Move light" ) { + materialPreview->OnLightAllowMoveChange( lightId, item->GetItemValue() ? true : false ); + + } else if ( itemLabel.Left(4) == "parm" ) { + int index; + + itemLabel.Strip( "parm" ); + index = atoi( itemLabel.c_str() ); + + materialPreview->OnLocalParmChange( index, atof( (char *)item->GetItemValue() ) ); + + } else if ( itemLabel.Left(6) == "global" ) { + int index; + + itemLabel.Strip( "global" ); + index = atoi( itemLabel.c_str() ); + + materialPreview->OnGlobalParmChange( index, atof( (char *)item->GetItemValue() ) ); + } +} + +void MaterialPreviewPropView::OnPropertyButtonClick( NMHDR *nmhdr, LRESULT *lresult ) { + NMPROPTREE *nmProp; + CPropTreeItem *item; + + nmProp = (NMPROPTREE *)nmhdr; + item = nmProp->pItem; + + idStr itemLabel = item->GetLabelText(); + + if ( itemLabel == "Preview Lights" ) { + AddLight(); + + } else if ( itemLabel.Left(5) == "Light" ) { + CPropTreeItem *light; + int lightId = item->GetCtrlID(); + int testLightNum = 0; + + m_Tree.DeleteItem( item ); + + for( light = m_Tree.GetRootItem()->GetChild(); light != NULL; light = light->GetSibling() ) { + idStr label = light->GetLabelText(); + + if ( label.Left(5) == "Light" ) { + testLightNum++; + light->SetLabelText(_T(va("Light #%d", testLightNum))); + light->SetInfoText(_T(va("Parameters for light number %d.", testLightNum))); + light->SetCtrlID( testLightNum - 1 ); + } + } + + materialPreview->OnDeleteLight( lightId ); + + numLights--; + } else if ( itemLabel == "Custom Model" ) { + CFileDialog dlg(TRUE); + dlg.m_ofn.Flags |= OFN_FILEMUSTEXIST; + item->Check(FALSE); + if( dlg.DoModal()== IDOK) { + item->Check(FALSE); + item->SetItemValue((LPARAM)fileSystem->OSPathToRelativePath(dlg.m_ofn.lpstrFile)); + m_Tree.SendNotify(PTN_ITEMCHANGED, item); + } + } +} diff --git a/tools/materialeditor/MaterialPreviewPropView.h b/tools/materialeditor/MaterialPreviewPropView.h new file mode 100644 index 000000000..5ed7f82d2 --- /dev/null +++ b/tools/materialeditor/MaterialPreviewPropView.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "../common/PropTree/PropTreeView.h" +#include "MaterialPreviewView.h" + +// MaterialPreviewPropView view + +class MaterialPreviewPropView : public CPropTreeView +{ + DECLARE_DYNCREATE(MaterialPreviewPropView) + +protected: + MaterialPreviewPropView(); // protected constructor used by dynamic creation + virtual ~MaterialPreviewPropView(); + +public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view + + afx_msg void OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ); + afx_msg void OnPropertyButtonClick( NMHDR *nmhdr, LRESULT *lresult ); + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + + void AddLight( void ); + void InitializePropTree( void ); + + void RegisterPreviewView( MaterialPreviewView *view ); + +protected: + + int numLights; + + MaterialPreviewView *materialPreview; + + DECLARE_MESSAGE_MAP() +}; + + diff --git a/tools/materialeditor/MaterialPreviewView.cpp b/tools/materialeditor/MaterialPreviewView.cpp new file mode 100644 index 000000000..07c2d556e --- /dev/null +++ b/tools/materialeditor/MaterialPreviewView.cpp @@ -0,0 +1,646 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + + +#include "../../../idlib/precompiled.h" +#pragma hdrstop + +#include "../radiant/QE3.H" +#include "MaterialPreviewView.h" + + +// MaterialPreviewView +IMPLEMENT_DYNCREATE(MaterialPreviewView, CView) + +MaterialPreviewView::MaterialPreviewView() { + // Initialize the rendered material + renderedView.setMedia( "_default" ); +} + +MaterialPreviewView::~MaterialPreviewView() { +} + +BEGIN_MESSAGE_MAP(MaterialPreviewView, CView) + ON_WM_CREATE() + ON_WM_SIZE() +END_MESSAGE_MAP() + + +// MaterialPreviewView drawing + +void MaterialPreviewView::OnDraw(CDC* pDC) { +} + +// MaterialPreviewView diagnostics + +#ifdef _DEBUG +void MaterialPreviewView::AssertValid() const { + CView::AssertValid(); +} + +void MaterialPreviewView::Dump(CDumpContext& dc) const { + CView::Dump(dc); +} +#endif //_DEBUG + +// MaterialPreviewView message handlers + +int MaterialPreviewView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) + return -1; + + DWORD dwStyle; + CRect rc; + + dwStyle = WS_CHILD|WS_VISIBLE; + + // Init the control's size to cover the entire client area + GetClientRect(rc); + + // Initialize the rendered window and material + renderWindow.Create( NULL, "renderWindow", dwStyle, rc, this, 1010 ); + + renderWindow.setDrawable( &renderedView ); + renderWindow.SetWindowPos(NULL, 0, 0, rc.Width(), rc.Height(), SWP_SHOWWINDOW); + + return 0; +} + +void MaterialPreviewView::OnSize(UINT nType, int cx, int cy) +{ + CRect rc; + + CView::OnSize( nType, cx, cy ); + + GetClientRect( rc ); + + renderWindow.SetWindowPos(NULL, 0, 0, rc.Width(), rc.Height(), SWP_SHOWWINDOW); + renderWindow.Invalidate(); + renderWindow.RedrawWindow(); +} + +void MaterialPreviewView::MV_OnMaterialSelectionChange( MaterialDoc *pMaterial ) +{ + if ( pMaterial && pMaterial->renderMaterial ) { + + currentMaterial = pMaterial->renderMaterial->GetName(); + renderedView.setMedia( currentMaterial ); + + renderWindow.Invalidate(); + renderWindow.RedrawWindow(); + } +} + +void MaterialPreviewView::OnLocalParmChange( int parmNum, float value ) { + + renderedView.setLocalParm( parmNum, value ); +} + +void MaterialPreviewView::OnGlobalParmChange( int parmNum, float value ) { + + renderedView.setGlobalParm( parmNum, value ); +} + +void MaterialPreviewView::OnLightShaderChange( int lightId, idStr shaderName ) { + + renderedView.setLightShader( lightId, shaderName ); +} + +void MaterialPreviewView::OnLightColorChange( int lightId, idVec3 &color ) { + + renderedView.setLightColor( lightId, color ); +} + +void MaterialPreviewView::OnLightRadiusChange( int lightId, float radius ) { + + renderedView.setLightRadius( lightId, radius ); +} + +void MaterialPreviewView::OnLightAllowMoveChange( int lightId, bool move ) { + + renderedView.setLightAllowMove( lightId, move ); +} + +void MaterialPreviewView::OnAddLight( void ) { + + renderedView.addLight(); +} + +void MaterialPreviewView::OnDeleteLight( int lightId ) { + + renderedView.deleteLight( lightId ); +} + +void MaterialPreviewView::OnModelChange( int modelId ) { + + renderedView.setObject( modelId ); +} + +void MaterialPreviewView::OnCustomModelChange( idStr modelName ) { + + renderedView.setCustomModel( modelName ); +} + +void MaterialPreviewView::OnShowLightsChange( bool showLights ) { + + renderedView.setShowLights( showLights ); +} + +/* + ============================================================================= + ============================================================================= + ============================================================================= + */ + +extern bool Sys_KeyDown(int key); +extern float fDiff(float f1, float f2); + +idGLDrawableView::idGLDrawableView() { + material = NULL; + modelDefHandle = -1; + + objectId = 0; + showLights = true; + realTime = 16; + + viewOrigin.Set( 0.f, 0.f, 0.f ); + viewRotation.Set( 0.f, 0.f, 0.f ); + viewDistance = -196.f; + + world = NULL; + worldModel = NULL; + + ResetView(); +} + +idGLDrawableView::~idGLDrawableView() { + delete world; + delete worldModel; +} + +void idGLDrawableView::ResetView( void ) { + idDict spawnArgs; + + InitWorld(); + + memset( &worldEntity, 0, sizeof( worldEntity ) ); + spawnArgs.Clear(); + spawnArgs.Set("classname", "func_static"); + spawnArgs.Set("name", spawnArgs.GetString("model")); + spawnArgs.Set("origin", "0 0 0"); + + gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity); + + // load a model and set the current material as its customshader + worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase"); + worldEntity.hModel = worldModel; + + // current material + worldEntity.customShader = material; + + // current rotation + worldEntity.axis = mat3_identity; + + // set global shader parms + memset( globalParms, 0, sizeof( globalParms ) ); + globalParms[0] = globalParms[1] = globalParms[2] = globalParms[3] = 1.f; + + worldEntity.shaderParms[0] = 1.f; + worldEntity.shaderParms[1] = 1.f; + worldEntity.shaderParms[2] = 1.f; + worldEntity.shaderParms[3] = 1.f; + modelDefHandle = world->AddEntityDef( &worldEntity ); +} + +void idGLDrawableView::InitWorld() { + + if ( world == NULL ) { + world = renderSystem->AllocRenderWorld(); + } + if ( worldModel == NULL ) { + worldModel = renderModelManager->AllocModel(); + } + + world->InitFromMap( NULL ); + worldModel->InitEmpty( "GLWorldModel" ); + + viewLights.Clear(); +} + +void idGLDrawableView::buttonDown(int _button, float x, float y) { + pressX = x; + pressY = y; + button = _button; + if ( button == MK_RBUTTON || button == MK_LBUTTON || button == MK_MBUTTON ) { + handleMove = true; + } +} + +void idGLDrawableView::mouseMove(float x, float y) { + bool doZoom; + float sensitivity = 0.5f; + + if (handleMove) { + + // Left mouse button rotates and zooms the view + if (button == MK_LBUTTON) { + doZoom = Sys_KeyDown(VK_MENU); + if (doZoom) { + if ( y != pressY ) { + viewDistance -= ( y - pressY ); + pressY = y; + } + } else { + float xo = 0.f; + float yo = 0.f; + + if (x != pressX) { + xo = (x - pressX); + pressX = x; + } + if (y != pressY) { + yo = (y - pressY); + pressY = y; + } + + viewRotation.yaw += -(xo * sensitivity); + viewRotation.pitch += (yo * sensitivity); + + viewRotation.pitch = idMath::ClampFloat( -89.9f, 89.9f, viewRotation.pitch ); + } + + // Right mouse button moves lights in the view plane + } else if (button == MK_RBUTTON) { + int i; + float lightMovement = 0; + idVec3 lightForward, lightRight, lightUp; + idVec3 lightMove; + + lightMove.Zero(); + viewRotation.ToVectors( &lightForward, &lightRight, &lightUp ); + + doZoom = Sys_KeyDown(VK_MENU); + if (doZoom) { + if ( y != pressY ) { + lightMovement = -( y - pressY ) * sensitivity; + pressY = y; + + lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement ); + lightMove = lightForward * lightMovement; + } + } else { + if (x != pressX) { + lightMovement = (x - pressX) * sensitivity; + pressX = x; + + lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement ); + lightMove = lightRight * lightMovement; + } + if (y != pressY) { + lightMovement = -(y - pressY) * sensitivity; + pressY = y; + + lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement ); + lightMove += lightUp * lightMovement; + } + } + + // Go through the lights and move the ones that are set to allow movement + for ( i = 0; i < viewLights.Num(); i++ ) { + lightInfo_t *vLight = &viewLights[i]; + + if ( vLight->allowMove ) { + vLight->origin += lightMove; + } + } + + // Middle mouse button moves object up and down + } else if ( button == MK_MBUTTON ) { + float yo = 0.f; + + if (y != pressY) { + yo = (y - pressY); + pressY = y; + } + + viewOrigin.z -= yo; + + UpdateModel(); + } + } +} + +void idGLDrawableView::addLight( void ) { + int lightId; + idStr str; + lightInfo_t viewLight; + idDict spawnArgs; + + lightId = viewLights.Num(); + + spawnArgs.Set( "classname", "light" ); + spawnArgs.Set( "name", va( "light_%d", lightId ) ); + spawnArgs.Set( "origin", va( "-128 0 %d", (lightId * 16) ) ); + spawnArgs.Set( "light", "300" ); + spawnArgs.Set( "texture", "lights/defaultPointLight" ); + sprintf( str, "%f %f %f", 1.f, 1.f, 1.f ); + spawnArgs.Set( "_color", str ); + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &viewLight.renderLight ); + + viewLight.lightDefHandle = world->AddLightDef( &viewLight.renderLight ); + viewLight.origin = viewLight.renderLight.origin; + viewLight.shader = declManager->FindMaterial( "lights/defaultPointLight", false ); + viewLight.color.x = viewLight.renderLight.shaderParms[ SHADERPARM_RED ]; + viewLight.color.y = viewLight.renderLight.shaderParms[ SHADERPARM_GREEN ]; + viewLight.color.z = viewLight.renderLight.shaderParms[ SHADERPARM_BLUE ]; + viewLight.radius = 300.f; + viewLight.allowMove = true; + + // Add light to the list + viewLights.Append( viewLight ); +} + +void idGLDrawableView::deleteLight( const int lightId ) { + if ( lightId < viewLights.Num() ) { + world->FreeLightDef( viewLights[lightId].lightDefHandle ); + + viewLights.RemoveIndex( lightId ); + } +} + +void idGLDrawableView::UpdateCamera( renderView_t *refdef ) { + idVec3 pos, dir; + idAngles angs; + + // Set the camera origin + pos = viewRotation.ToForward(); + pos *= viewDistance; + refdef->vieworg = pos; + + // Set the view to point back at the origin + dir = vec3_origin - pos; + angs = dir.ToAngles(); + refdef->viewaxis = angs.ToMat3(); +} + + +void idGLDrawableView::UpdateModel( void ) { + + switch( objectId ) { + case 0: + worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase"); + break; + case 1: + worldModel = renderModelManager->FindModel("models/materialeditor/box128x64.ase"); + break; + case 2: + worldModel = renderModelManager->FindModel("models/materialeditor/box128x32.ase"); + break; + case 3: + worldModel = renderModelManager->FindModel("models/materialeditor/box64x128.ase"); + break; + case 4: + worldModel = renderModelManager->FindModel("models/materialeditor/box32x128.ase"); + break; + case 5: + worldModel = renderModelManager->FindModel("models/materialeditor/cylinder_v.ase"); + break; + case 6: + worldModel = renderModelManager->FindModel("models/materialeditor/cylinder_h.ase"); + break; + case 7: + worldModel = renderModelManager->FindModel("models/materialeditor/sphere64.ase"); + break; + case -1: + worldModel = renderModelManager->FindModel( customModelName.c_str() ); + break; + default: + worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase"); + break; + }; + + worldEntity.hModel = worldModel; + + // current material + worldEntity.customShader = material; + // current rotation + worldEntity.origin = viewOrigin; + + worldEntity.axis = mat3_identity; + + world->UpdateEntityDef( modelDefHandle, &worldEntity ); +} + +void idGLDrawableView::UpdateLights( void ) { + int i; + + for ( i = 0; i < viewLights.Num(); i++ ) { + lightInfo_t *vLight = &viewLights[i]; + + vLight->renderLight.shader = vLight->shader; + + vLight->renderLight.shaderParms[ SHADERPARM_RED ] = vLight->color.x; + vLight->renderLight.shaderParms[ SHADERPARM_GREEN ] = vLight->color.y; + vLight->renderLight.shaderParms[ SHADERPARM_BLUE ] = vLight->color.z; + + vLight->renderLight.lightRadius[0] = vLight->renderLight.lightRadius[1] = + vLight->renderLight.lightRadius[2] = vLight->radius; + + vLight->renderLight.origin = vLight->origin; + + world->UpdateLightDef( vLight->lightDefHandle, &vLight->renderLight ); + } +} + +void idGLDrawableView::drawLights( renderView_t *refdef ) { + int i; + + for ( i=0; i < viewLights.Num(); i++ ) { + lightInfo_t *vLight = &viewLights[i]; + + idVec4 lColor; + lColor.x = vLight->color.x; + lColor.y = vLight->color.y; + lColor.z = vLight->color.z; + lColor.w = 1.f; + + idSphere sphere(vLight->renderLight.origin, 4); + session->rw->DebugSphere( lColor, sphere, 0, true ); + session->rw->DrawText( va( "%d", i+1 ), vLight->renderLight.origin + idVec3(0,0,5), 0.25f, idVec4(1,1,0,1), refdef->viewaxis, 1, 0, true ); + } +} + + +void idGLDrawableView::draw(int x, int y, int w, int h) { + int i; + renderView_t refdef; + const idMaterial *mat = material; + + if (mat) { + qglViewport(x, y, w, h); + qglScissor(x, y, w, h); + qglMatrixMode(GL_PROJECTION); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglClear(GL_COLOR_BUFFER_BIT); + + UpdateLights(); + + // render it + renderSystem->BeginFrame(w, h); + + memset( &refdef, 0, sizeof( refdef ) ); + + UpdateCamera( &refdef ); + + // Copy global shaderparms to view + for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) { + refdef.shaderParms[ i ] = globalParms[ i ]; + } + + refdef.width = SCREEN_WIDTH; + refdef.height = SCREEN_HEIGHT; + refdef.fov_x = 90; + refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG; + + refdef.time = eventLoop->Milliseconds(); + + world->RenderScene( &refdef ); + + if ( showLights ) { + drawLights( &refdef ); + } + + renderSystem->EndFrame( NULL, NULL ); + + world->DebugClearLines( refdef.time ); + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + } +} + +// ============================ +// Interface to PropTree Window +// ============================ + +void idGLDrawableView::setMedia(const char *name) { + float ratio = 1; + + if (name && *name) { + material = declManager->FindMaterial(name); + } else { + material = NULL; + } + + if ( material->GetNumStages() == 0 ) { + material = declManager->FindMaterial( "_default" ); + } + + if ( material->GetStage(0)->texture.image ) { + ratio = (float)((float)material->GetImageWidth() / (float)material->GetImageHeight()); + } + + if ( objectId == -1 ) { + // Don't change a custom model + } else if ( ratio == 1 ) { + objectId = 0; + } else if ( ratio == 2 ) { + objectId = 1; + } else if ( ratio == 4 ) { + objectId = 2; + } else if ( ratio == 0.5 ) { + objectId = 3; + } else if ( ratio == 0.25 ) { + objectId = 4; + } + + UpdateModel(); +} + +void idGLDrawableView::setLocalParm( int parmNum, float value ) { + if ( parmNum < 0 || parmNum >= MAX_ENTITY_SHADER_PARMS ) { + return; + } + + worldEntity.shaderParms[ parmNum ] = value; + + UpdateModel(); +} + +void idGLDrawableView::setGlobalParm( int parmNum, float value ) { + if ( parmNum < 0 || parmNum >= MAX_GLOBAL_SHADER_PARMS ) { + return; + } + + globalParms[ parmNum ] = value; +} + +void idGLDrawableView::setLightShader( const int lightId, const idStr shaderName ) { + + if ( lightId < viewLights.Num() ) { + viewLights[ lightId ].shader = declManager->FindMaterial( shaderName, false ); + } +} + +void idGLDrawableView::setLightColor( const int lightId, const idVec3 &value ) { + + if ( lightId < viewLights.Num() ) { + // Update this lights color + viewLights[ lightId ].color = value; + } +} + +void idGLDrawableView::setLightRadius( const int lightId, const float radius ) { + + if ( lightId < viewLights.Num() ) { + viewLights[ lightId ].radius = radius; + } +} + +void idGLDrawableView::setLightAllowMove( const int lightId, const bool move ) { + + if ( lightId < viewLights.Num() ) { + viewLights[ lightId ].allowMove = move; + } +} + +void idGLDrawableView::setObject( int Id ) { + objectId = Id; + + UpdateModel(); +} + +void idGLDrawableView::setCustomModel( const idStr modelName ) { + + if ( modelName.Length() ) { + objectId = -1; + } else { + objectId = 0; + } + + customModelName = modelName; + + UpdateModel(); +} + +void idGLDrawableView::setShowLights( bool _showLights ) { + showLights = _showLights; +} + diff --git a/tools/materialeditor/MaterialPreviewView.h b/tools/materialeditor/MaterialPreviewView.h new file mode 100644 index 000000000..414770532 --- /dev/null +++ b/tools/materialeditor/MaterialPreviewView.h @@ -0,0 +1,140 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialView.h" +#include "../radiant/GLWidget.h" + + +class idGLDrawableView : public idGLDrawable { + +public: + idGLDrawableView(); + ~idGLDrawableView(); + + virtual void setMedia(const char *name); + virtual void draw(int x, int y, int w, int h); + virtual void buttonUp(int button){} + virtual void buttonDown(int _button, float x, float y); + virtual void mouseMove(float x, float y); + virtual void Update() {}; + + void UpdateCamera( renderView_t *refdef ); + void UpdateModel( void ); + void UpdateLights( void ); + + void addLight( void ); + void deleteLight( const int lightId ); + void drawLights( renderView_t *refdef ); + + void InitWorld(); + void ResetView( void ); + + void setLightShader( const int lightId, const idStr shaderName ); + void setLightColor( const int lightId, const idVec3 &value ); + void setLightRadius( const int lightId, const float radius ); + void setLightAllowMove( const int lightId, const bool move ); + void setObject( int Id ); + void setCustomModel( const idStr modelName ); + void setShowLights( bool _showLights ); + void setLocalParm( int parmNum, float value ); + void setGlobalParm( int parmNum, float value ); + +protected: + idRenderWorld *world; + idRenderModel *worldModel; + const idMaterial *material; + + bool showLights; + + idVec3 viewOrigin; + idAngles viewRotation; + float viewDistance; + + renderEntity_t worldEntity; + qhandle_t modelDefHandle; + + int objectId; + idStr customModelName; + + float globalParms[MAX_GLOBAL_SHADER_PARMS]; + + typedef struct { + renderLight_t renderLight; + qhandle_t lightDefHandle; + idVec3 origin; + const idMaterial *shader; + float radius; + idVec3 color; + bool allowMove; + } lightInfo_t; + + idList viewLights; +}; + + +// ================================================================== +// ================================================================== + +class MaterialPreviewView : public CView, public MaterialView +{ + DECLARE_DYNCREATE(MaterialPreviewView) + +protected: + MaterialPreviewView(); + virtual ~MaterialPreviewView(); + +public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view + + void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial); + + void OnModelChange( int modelId ); + void OnCustomModelChange( idStr modelName ); + void OnShowLightsChange( bool showLights ); + + void OnLocalParmChange( int parmNum, float value ); + void OnGlobalParmChange( int parmNum, float value ); + + void OnLightShaderChange( int lightId, idStr shaderName ); + void OnLightRadiusChange( int lightId, float radius ); + void OnLightColorChange( int lightId, idVec3 &color ); + void OnLightAllowMoveChange( int lightId, bool move ); + + void OnAddLight( void ); + void OnDeleteLight( int lightId ); + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + idGLWidget renderWindow; + idGLDrawableView renderedView; + + idStr currentMaterial; + + DECLARE_MESSAGE_MAP() + +public: + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); +}; + diff --git a/tools/materialeditor/MaterialPropTreeView.cpp b/tools/materialeditor/MaterialPropTreeView.cpp new file mode 100644 index 000000000..e6584b518 --- /dev/null +++ b/tools/materialeditor/MaterialPropTreeView.cpp @@ -0,0 +1,239 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialPropTreeView.h" + +#define PROP_TREE_VIEW "PropTreeView" + + +IMPLEMENT_DYNCREATE(MaterialPropTreeView, CPropTreeView) + +BEGIN_MESSAGE_MAP(MaterialPropTreeView, CPropTreeView) + ON_NOTIFY( PTN_ITEMCHANGED, IDC_PROPERTYTREE, OnPropertyChangeNotification ) + ON_NOTIFY( PTN_ITEMEXPANDING, IDC_PROPERTYTREE, OnPropertyItemExpanding ) +END_MESSAGE_MAP() + + +/** +* Constructor for MaterialPropTreeView. +*/ +MaterialPropTreeView::MaterialPropTreeView() { + registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor\\PropertySettings"); + internalChange = false; +} + +/** +* Destructor for MaterialPropTreeView. +*/ +MaterialPropTreeView::~MaterialPropTreeView() { +} + +/** +* Initializes the list of properties based on the type (material, stage, special stage). +* @param listType The type of list (material, stage, special stage) +* @param stageNum The stage from which to get the attributes. +*/ +void MaterialPropTreeView::SetPropertyListType(int listType, int stageNum) { + + currentListType = listType; + currentStage = stageNum; + + m_Tree.DeleteAllItems(); + + //idList* propList = NULL; + MaterialDefList* propList = MaterialDefManager::GetMaterialDefs(currentListType); + currentPropDefs = propList; + + if(!propList) + return; + + CPropTreeItem* pCurrentGroup = NULL; + CPropTreeItem* pCurrentNode = NULL; + + for(int i = 0; i < propList->Num(); i++) { + switch((*propList)[i]->type) { + case MaterialDef::MATERIAL_DEF_TYPE_GROUP: + { + pCurrentGroup = m_Tree.InsertItem(new CPropTreeItem()); + pCurrentNode = pCurrentGroup; + + if(!registry.GetBool(va("Expand%d%s", currentListType, (*propList)[i]->displayName.c_str()))) + pCurrentGroup->Expand(); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_BOOL: + { + CPropTreeItemCheck* pCheck; + pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem(new CPropTreeItemCheck(), pCurrentGroup); + pCheck->CreateCheckBox(); + pCurrentNode = pCheck; + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_STRING: + { + //pCurrentNode = m_Tree.InsertItem(new CPropTreeItemEdit(), pCurrentGroup); + pCurrentNode = m_Tree.InsertItem(new CPropTreeItemFileEdit(), pCurrentGroup); + + } + break; + } + + if(pCurrentNode) { + (*propList)[i]->SetViewData(PROP_TREE_VIEW, pCurrentNode->GetCtrlID()); + pCurrentNode->SetLabelText((*propList)[i]->displayName); + pCurrentNode->SetInfoText((*propList)[i]->displayInfo); + } + } + + RefreshProperties(); +} + +/** +* Loads the property view settings from the registry. +*/ +void MaterialPropTreeView::LoadSettings() { + registry.Load(); +} + +/** +* Saves the property view settings to the registry. +*/ +void MaterialPropTreeView::SaveSettings() { + registry.Save(); +} + +/** +* Called when the material has changed but not applied. +* @param pMaterial The selected material. +*/ +void MaterialPropTreeView::MV_OnMaterialChange(MaterialDoc* pMaterial) { + + if(materialDocManager->GetCurrentMaterialDoc()) { + idStr currentName = materialDocManager->GetCurrentMaterialDoc()->name; + if(!internalChange && !pMaterial->name.Icmp(currentName)) { + RefreshProperties(); + } + } +} + +/** +* Updated the material when an attribute has been changed. +*/ +void MaterialPropTreeView::OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ) { + + NMPROPTREE *nmProp = (NMPROPTREE *)nmhdr; + CPropTreeItem *item = nmProp->pItem; + + internalChange = true; + + MaterialDef* propItem = FindDefForTreeID(item->GetCtrlID()); + if(propItem) { + MaterialDoc* materialDoc = materialDocManager->GetCurrentMaterialDoc(); + + switch(propItem->type) { + case MaterialDef::MATERIAL_DEF_TYPE_BOOL: + { + BOOL val = item->GetItemValue(); + materialDoc->SetAttributeBool(currentStage, propItem->dictName, val ? true : false); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_STRING: + { + idStr val = (LPCTSTR)item->GetItemValue(); + materialDoc->SetAttribute(currentStage, propItem->dictName, val); + } + break; + } + } + + internalChange = false; + + *lresult = 0; +} + +/** +* Changes the property setting of a group when is expanding. +*/ +void MaterialPropTreeView::OnPropertyItemExpanding( NMHDR *nmhdr, LRESULT *lresult ) { + + NMPROPTREE *nmProp = (NMPROPTREE *)nmhdr; + CPropTreeItem *item = nmProp->pItem; + + //The item isn't toggled till after this returns so use the opposite of the current state. + registry.SetBool(va("Expand%d%s", currentListType, item->GetLabelText()), item->IsExpanded() ? true : false); + registry.Save(); + + *lresult = 0; +} + +/** +* Returns the MeterialDef for a given property tree item. +* @param treeID The id of the tree item in question. +*/ +MaterialDef* MaterialPropTreeView::FindDefForTreeID(UINT treeID) { + + int c = currentPropDefs->Num(); + for(int i = 0; i < c; i++) { + if((*currentPropDefs)[i]->GetViewData(PROP_TREE_VIEW) == treeID) + return (*currentPropDefs)[i]; + } + + return NULL; +} + +/** +* Initializes the property tree with the data from the currently selected material. +*/ +void MaterialPropTreeView::RefreshProperties() { + + MaterialDefList* propList = MaterialDefManager::GetMaterialDefs(currentListType); + + if(!propList) + return; + + MaterialDoc* materialDoc = materialDocManager->GetCurrentMaterialDoc(); + + for(int i = 0; i < propList->Num(); i++) { + switch((*propList)[i]->type) { + case MaterialDef::MATERIAL_DEF_TYPE_BOOL: + { + bool val = materialDoc->GetAttributeBool(currentStage, (*propList)[i]->dictName); + CPropTreeItemCheck* item = (CPropTreeItemCheck*)m_Tree.FindItem((*propList)[i]->GetViewData(PROP_TREE_VIEW)); + item->SetCheckState(val ? TRUE:FALSE); + } + break; + case MaterialDef::MATERIAL_DEF_TYPE_STRING: + { + idStr val = materialDoc->GetAttribute(currentStage, (*propList)[i]->dictName); + CPropTreeItemEdit* item = (CPropTreeItemEdit*)m_Tree.FindItem((*propList)[i]->GetViewData(PROP_TREE_VIEW)); + item->SetItemValue((LPARAM)val.c_str()); + } + break; + } + } + + Invalidate(); +} + + + + + diff --git a/tools/materialeditor/MaterialPropTreeView.h b/tools/materialeditor/MaterialPropTreeView.h new file mode 100644 index 000000000..c88a3b01f --- /dev/null +++ b/tools/materialeditor/MaterialPropTreeView.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "../common/PropTree/PropTreeView.h" +#include "MaterialView.h" + +#include "../common/registryoptions.h" +#include "MaterialDef.h" + + +/** +* View that displays material and stage properties and allows the user to edit the properties. +*/ +class MaterialPropTreeView : public CPropTreeView, public MaterialView { + +public: + virtual ~MaterialPropTreeView(); + + void SetPropertyListType(int listType, int stageNum = -1); + + void LoadSettings(); + void SaveSettings(); + + //Material Interface + virtual void MV_OnMaterialChange(MaterialDoc* pMaterial); + +protected: + MaterialPropTreeView(); + DECLARE_DYNCREATE(MaterialPropTreeView) + + afx_msg void OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ); + afx_msg void OnPropertyItemExpanding( NMHDR *nmhdr, LRESULT *lresult ); + DECLARE_MESSAGE_MAP() + + MaterialDef* FindDefForTreeID(UINT treeID); + void RefreshProperties(); + +protected: + + MaterialDoc* currentMaterial; + int currentListType; + int currentStage; + MaterialDefList* currentPropDefs; + rvRegistryOptions registry; + bool internalChange; +}; + + diff --git a/tools/materialeditor/MaterialTreeView.cpp b/tools/materialeditor/MaterialTreeView.cpp new file mode 100644 index 000000000..1bf1148a5 --- /dev/null +++ b/tools/materialeditor/MaterialTreeView.cpp @@ -0,0 +1,1917 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "MaterialTreeView.h" + +#define IMAGE_FOLDER 0 +#define IMAGE_FILE 1 +#define IMAGE_MATERIAL 2 +#define IMAGE_MATERIAL_FOLDER 3 +#define IMAGE_FILE_MOD 4 +#define IMAGE_MATERIAL_MOD 5 +#define IMAGE_MATERIAL_MOD_APPLY 6 + +#define HOVER_EXPAND_DELAY 500 + +#define MSG_RENAME_FOLDER_COMPLETE (WM_USER + 1000) +#define MSG_RENAME_MATERIAL_COMPLETE (WM_USER + 1001) + +IMPLEMENT_DYNCREATE(MaterialTreeView, CTreeView) + +BEGIN_MESSAGE_MAP(MaterialTreeView, CTreeView) + ON_WM_CREATE() + ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnTvnSelchanged) + ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginlabeledit) + ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndlabeledit) + ON_WM_CONTEXTMENU() + ON_NOTIFY_REFLECT(NM_RCLICK, OnNMRclick) + ON_WM_CHAR() + ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnTvnBegindrag) + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONUP() + + ON_COMMAND(ID_POPUP_APPLYMATERIAL, OnApplyMaterial) + ON_COMMAND(ID_POPUP_APPLYFILE, OnApplyFile) + ON_COMMAND(ID_POPUP_APPLYALL, OnApplyAll) + ON_COMMAND(ID_POPUP_SAVEMATERIAL, OnSaveMaterial) + ON_COMMAND(ID_POPUP_SAVEFILE, OnSaveFile) + ON_COMMAND(ID_POPUP_SAVEALL, OnSaveAll) + ON_COMMAND(ID_POPUP_RENAMEMATERIAL, OnRenameMaterial) + ON_COMMAND(ID_POPUP_ADDMATERIAL, OnAddMaterial) + ON_COMMAND(ID_POPUP_ADDFOLDER, OnAddFolder) + ON_COMMAND(ID_POPUP_DELETEMATERIAL, OnDeleteMaterial) + ON_COMMAND(ID_POPUP_RELOADFILE, OnReloadFile) + + ON_COMMAND(ID_POPUP_CUT, OnCut) + ON_COMMAND(ID_POPUP_COPY, OnCopy) + ON_COMMAND(ID_POPUP_PASTE, OnPaste) + + ON_MESSAGE(MSG_RENAME_FOLDER_COMPLETE, OnRenameFolderComplete) + ON_MESSAGE(MSG_RENAME_MATERIAL_COMPLETE, OnRenameMaterialComplete) +END_MESSAGE_MAP() + +/** +* Constructor for MaterialTreeView +*/ +MaterialTreeView::MaterialTreeView() { + treeWithFile = false; + bDragging = false; + hoverItem = NULL; + internalChange = false; +} + +/** +* Destructor for MaterialTreeView +*/ +MaterialTreeView::~MaterialTreeView() { +} + +/** +* Clears the tree and rebuilds it. +* @param includeFile Should the list include the filename +* @param filename The file to load or NULL to load all files. +*/ +void MaterialTreeView::InitializeMaterialList(bool includeFile, const char* filename) { + + treeWithFile = includeFile; + + CTreeCtrl& tree = GetTreeCtrl(); + + tree.DeleteAllItems(); + quickTree.Clear(); + materialToTree.Clear(); + fileToTree.Clear(); + + BuildMaterialList(includeFile, filename); +} + +/** +* Builds the tree of materials. +* @param includeFile Should the list include the filename +* @param filename The file to load or NULL to load all files. +*/ +void MaterialTreeView::BuildMaterialList(bool includeFile, const char* filename) { + + CTreeCtrl& tree = GetTreeCtrl(); + + idStrList list(1024); + + int count = declManager->GetNumDecls( DECL_MATERIAL ); + if (count > 0) { + for (int i = 0; i < count; i++) { + const idMaterial *mat = declManager->MaterialByIndex(i, false); + + if(filename && strcmp(filename, mat->GetFileName())) { + continue; + } + + idStr temp; + + //Do Not Include Implicit File Definitions + idStr filename = mat->GetFileName(); + if(!filename.Icmp("")) { + continue; + } + + if(filename.Find("def") != -1) { + int x = 0; + } + + if(includeFile) { + filename.StripPath(); + temp = idStr(mat->GetFileName()) + "/" + idStr(mat->GetName()) + "|" + filename; + } else { + temp = mat->GetName(); + } + + list.Append(temp); + } + AddStrList(NULL, &list, includeFile); + } +} + +/** +* Called when the material has changed but not applied. +* @param pMaterial The selected material. +*/ +void MaterialTreeView::MV_OnMaterialChange(MaterialDoc* pMaterial) { + + CTreeCtrl& tree = GetTreeCtrl(); + + //When a material changes place an asterik next to the material and the file + HTREEITEM* materialItem = NULL; + materialToTree.Get(pMaterial->name, &materialItem); + + + if(!materialItem) + return; + + tree.SetItemImage(*materialItem, IMAGE_MATERIAL_MOD_APPLY, IMAGE_MATERIAL_MOD_APPLY); + + + if(treeWithFile) { + HTREEITEM* fileItem = NULL; + idStr file = pMaterial->renderMaterial->GetFileName(); + + //common->Printf("Filename = %s\n", file.c_str()); + + if(fileToTree.Get(file, &fileItem)){ + //common->Printf("Found: %d\n", *fileItem); + tree.SetItemImage(*fileItem, IMAGE_FILE_MOD, IMAGE_FILE_MOD); + } + } +} + +/** +* Called when the material changes have been applied. +* @param pMaterial The selected material. +*/ +void MaterialTreeView::MV_OnMaterialApply(MaterialDoc* pMaterial) { + CTreeCtrl& tree = GetTreeCtrl(); + + //When a material is applied then just change the image to material modified + HTREEITEM* materialItem = NULL; + materialToTree.Get(pMaterial->name, &materialItem); + + if(!materialItem) + return; + + tree.SetItemImage(*materialItem, IMAGE_MATERIAL_MOD, IMAGE_MATERIAL_MOD); +} + +/** +* Called when the material changes have been saved. +* @param pMaterial The saved material. +*/ +void MaterialTreeView::MV_OnMaterialSaved(MaterialDoc* pMaterial) { + CTreeCtrl& tree = GetTreeCtrl(); + + //Remove the asterik + HTREEITEM* materialItem = NULL; + materialToTree.Get(pMaterial->name, &materialItem); + + //We will get this message for a delete file so the material will not be in the tree + if(materialItem) { + tree.SetItemImage(*materialItem, IMAGE_MATERIAL, IMAGE_MATERIAL); + } + + //Check if the file is completely saved + if(treeWithFile) { + + if(!materialDocManager->IsFileModified(pMaterial->renderMaterial->GetFileName())) { + + HTREEITEM* fileItem = NULL; + idStr file = pMaterial->renderMaterial->GetFileName(); + + if(fileToTree.Get(file, &fileItem)) { + tree.SetItemImage(*fileItem, IMAGE_FILE, IMAGE_FILE); + } + } + } +} + +/** +* Called when a material is added +* @param pMaterial The material that was added. +*/ +void MaterialTreeView::MV_OnMaterialAdd(MaterialDoc* pMaterial) { + + idStrList list(1024); + + idMaterial *mat = pMaterial->renderMaterial; + idStr temp; + + if(treeWithFile) { + idStr filename = mat->GetFileName(); + filename.StripPath(); + temp = idStr(mat->GetFileName()) + "/" + idStr(mat->GetName()) + "|" + filename; + } else { + temp = mat->GetName(); + } + + list.Append(temp); + AddStrList(NULL, &list, treeWithFile); + + //Keep the items sorted + HTREEITEM* item = NULL; + materialToTree.Get(pMaterial->name, &item); + if(*item) { + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM parent = tree.GetParentItem(*item); + tree.SortChildren(parent); + } + + MV_OnMaterialChange(pMaterial); +} + +/** +* Called when a material is deleted +* @param pMaterial The material that was deleted. +*/ +void MaterialTreeView::MV_OnMaterialDelete(MaterialDoc* pMaterial) { + + //Our doc told us a material has been deleted. Lets find and remove the item from our tree + HTREEITEM* materialItem = NULL; + materialToTree.Get(pMaterial->name, &materialItem); + + CTreeCtrl& tree = GetTreeCtrl(); + tree.DeleteItem(*materialItem); + + //Remove our old quick lookup value + materialToTree.Remove(pMaterial->name.c_str()); +} + +/** +* Called when the material name has changed +* @param pMaterial The material that was deleted. +* @param oldName The old name of the material. +*/ +void MaterialTreeView::MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName) { + + CTreeCtrl& tree = GetTreeCtrl(); + + if(!internalChange) { + + //Delete the old tree item + HTREEITEM* item = NULL; + materialToTree.Get(oldName, &item); + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM tempItem = *item; + CleanLookupTrees(tempItem); + tree.DeleteItem(tempItem); + + + //Now add it back + idStrList list(1024); + idMaterial *mat = pMaterial->renderMaterial; + idStr temp; + + if(treeWithFile) { + idStr filename = mat->GetFileName(); + filename.StripPath(); + temp = idStr(mat->GetFileName()) + "/" + idStr(mat->GetName()) + "|" + filename; + } else { + temp = mat->GetName(); + } + + list.Append(temp); + AddStrList(NULL, &list, treeWithFile); + + //Keep the items sorted + //item = NULL; + materialToTree.Get(pMaterial->name.c_str(), &item); + if(*item) { + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM parent = tree.GetParentItem(*item); + tree.SortChildren(parent); + } + + MV_OnMaterialChange(pMaterial); + + } +} + +/** +* Called when a file has been reloaded +* @param filename The file that was reloaded. +*/ +void MaterialTreeView::MV_OnFileReload(const char* filename) { + + HTREEITEM* fileItem = NULL; + fileToTree.Get(filename, &fileItem); + + HTREEITEM item = *fileItem; + + CTreeCtrl& tree = GetTreeCtrl(); + CleanLookupTrees(item); + tree.DeleteItem(item); + + BuildMaterialList(treeWithFile, filename); + + //Resort the parent to make sure the file is back where it was + HTREEITEM* newItem = NULL; + fileToTree.Get(filename, &newItem); + if(*newItem) { + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM parent = tree.GetParentItem(*newItem); + tree.SortChildren(parent); + } +} + +/** +* Returns true if the user can copy the selected item. +*/ +bool MaterialTreeView::CanCopy() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(item && itemType == TYPE_MATERIAL) { + return true; + } else { + return false; + } +} + +/** +* Returns true if the user can paste an item in the copy buffer. +*/ +bool MaterialTreeView::CanPaste() { + return materialDocManager->IsCopyMaterial(); +} + +/** +* Returns true if the user can cut the selected item. +*/ +bool MaterialTreeView::CanCut() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(item && itemType == TYPE_MATERIAL) { + return true; + } else { + return false; + } +} + +/** +* Returns true if the user can delete the selected item. +*/ +bool MaterialTreeView::CanDelete() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL_FOLDER || itemType == TYPE_MATERIAL) { + return true; + } + + return false; +} + +/** +* Returns true if the user can rename the selected item. +*/ +bool MaterialTreeView::CanRename() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL_FOLDER || itemType == TYPE_MATERIAL) { + return true; + } + return false; +} + +/** +* Returns true if the currently selected file needs to be saved. +*/ +bool MaterialTreeView::CanSaveFile() { + + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM item = tree.GetSelectedItem(); + + idStr filename; + if(item && GetFileName(item, filename)) { + if(materialDocManager->IsFileModified(filename.c_str())) + return true; + else + return false; + } else { + return false; + } +} + +/** +* Returns the filename of currently selected file. +*/ +idStr MaterialTreeView::GetSaveFilename() { + + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM item = tree.GetSelectedItem(); + + idStr filename = ""; + if(item) { + if(!GetFileName(item, filename)) { + filename = ""; + } + } + + return filename; +} + +/** +* Searches for a material given the supplied search parameters. +* @param searchData The parameters to use for the search. +*/ +bool MaterialTreeView::FindNextMaterial(MaterialSearchData_t* searchData) { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM selected = tree.GetSelectedItem(); + if(!selected) { + selected = tree.GetRootItem(); + if(!selected) { + return false; + } + } + + //Make sure we are in a file + if(searchData->searchScope == 0) { + DWORD type = tree.GetItemData(selected); + if(type == TYPE_FOLDER || type == TYPE_ROOT) + return false; + } + + HTREEITEM search =selected; + + while((search = GetNextSeachItem(search, (searchData->searchScope == 0))) != NULL) { + HTREEITEM found = FindNextMaterial(search, searchData); + if(found) { + tree.SelectItem(found); + return true; + } + } + return false; +} + +/** +* Searches for a material given the supplied search parameters. Returns the tree item where +* the item was found or NULL if no material was found. +* @param item The tree item from where to start the search. +* @param searchData The parameters to use for the search. +*/ +HTREEITEM MaterialTreeView::FindNextMaterial(HTREEITEM item, MaterialSearchData_t* searchData) { + + CTreeCtrl& tree = GetTreeCtrl(); + DWORD type = tree.GetItemData(item); + + if(type == TYPE_MATERIAL) { + //check the tree name first + idStr itemName = tree.GetItemText(item); + int findPos = itemName.Find(searchData->searchText, false); + if(findPos != -1) { + //Todo: Include match whole word + return item; + } + + if(!searchData->nameOnly) { + //Check the material + idStr materialName = GetMediaPath(item, TYPE_MATERIAL); + if(materialDocManager->FindMaterial(materialName, searchData, false)) { + return item; + } + } + } else { + //Just check the tree name + idStr itemName = tree.GetItemText(item); + + int findPos = itemName.Find(searchData->searchText, false); + if(findPos != -1) { + //Todo: Include match whole word + return item; + } + } + return NULL; +} + +/** +* Returns the next item to search or NULL if there is nothing else to search. +* @param item The last item searched. +* @param stayInFile True if the search should stay in the current file. +*/ +HTREEITEM MaterialTreeView::GetNextSeachItem(HTREEITEM item, bool stayInFile) { + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM nextItem = NULL; + + //Check our children + if(tree.ItemHasChildren(item)) { + nextItem = tree.GetChildItem(item); + return nextItem; + } + + //Check our siblings + nextItem = tree.GetNextSiblingItem(item); + if(nextItem) { + return nextItem; + } + + //Check our parents next sibiling + HTREEITEM parent = item; + while((parent = tree.GetParentItem(parent)) != NULL) { + DWORD parType = tree.GetItemData(parent); + if(stayInFile && parType == TYPE_FILE) + break; + + HTREEITEM sib = tree.GetNextSiblingItem(parent); + if(sib) { + nextItem = sib; + break; + } + } + return nextItem; +} + +/** +* Deletes a given folder. +* @param item The folder to delete. +* @param addUndo True if this operation can be undone. +*/ +void MaterialTreeView::DeleteFolder(HTREEITEM item, bool addUndo) { + + CTreeCtrl& tree = GetTreeCtrl(); + + idList materialsToDelete; + + //Get the complete list of materials to delete + GetMaterialPaths(item, &materialsToDelete); + + idStrList affectedMaterials; + + //Now delete the materials + for(int i = 0; i < materialsToDelete.Num(); i++) { + + affectedMaterials.Append(materialsToDelete[i].materialName); + + const idMaterial* material = declManager->FindMaterial(materialsToDelete[i].materialName); + + MaterialDoc* pMaterial = NULL; + pMaterial = materialDocManager->CreateMaterialDoc(const_cast(material)); + materialDocManager->DeleteMaterial(pMaterial, false); + } + + //Make our undo modifier + if(addUndo) { + DeleteMaterialFolderModifier* mod = new DeleteMaterialFolderModifier(materialDocManager, tree.GetItemText(item), this, tree.GetParentItem(item), &affectedMaterials); + materialDocManager->AddMaterialUndoModifier(mod); + } + + + //Now clean up the folders and quicktree + CleanLookupTrees(item); + + //Remove any folders that were there + tree.DeleteItem(item); +} + +/** +* Adds a new material folder. +* @param name The name of the folder. +* @param parent The parent item of the folder. +*/ +HTREEITEM MaterialTreeView::AddFolder(const char* name, HTREEITEM parent) { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM newItem = tree.InsertItem(name, parent); + tree.SetItemImage(newItem, IMAGE_MATERIAL_FOLDER, IMAGE_MATERIAL_FOLDER); + tree.SetItemData(newItem, TYPE_MATERIAL_FOLDER); + tree.Expand(newItem, TVE_EXPAND); + + //Make sure the tree is still sorted + tree.SortChildren(parent); + + //Build the entire path to this item for the quicktree + idStr qt = GetQuicktreePath(newItem); + quickTree.Set(qt, newItem); + + return newItem; +} + +/** +* Renames a material folder. +* @param item The folder tree item. +* @param name The new name of the material folder. +*/ +void MaterialTreeView::RenameFolder(HTREEITEM item, const char* name) { + + CTreeCtrl& tree = GetTreeCtrl(); + + //Clean up the quicktree with the current tree before we allow the edit to commit + CleanLookupTrees(item); + + //Store some data so the we can make the appropriate changes after the commit + renamedFolder = item; + + affectedMaterials.Clear(); + GetMaterialPaths(renamedFolder, &affectedMaterials); + + tree.SetItemText(item, name); + + PostMessage(MSG_RENAME_FOLDER_COMPLETE); +} + +/** +* Handles the keyboard shortcut for delete. +*/ +BOOL MaterialTreeView::PreTranslateMessage(MSG* pMsg) { + + CTreeCtrl& tree = GetTreeCtrl(); + if (pMsg->hwnd == tree.GetSafeHwnd()) { + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE) { + OnDeleteMaterial(); + return TRUE; + } + } + return FALSE; +} + +/** +* Called by the MFC framework as the view is being created. +*/ +int MaterialTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) { + + lpCreateStruct->style |= TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | TVS_INFOTIP; + if (CTreeView::OnCreate(lpCreateStruct) == -1) + return -1; + + CTreeCtrl& tree = GetTreeCtrl(); + m_image.Create(IDB_ME_TREEBITMAP, 16, 1, RGB(255, 255, 255)); + tree.SetImageList(&m_image, TVSIL_NORMAL); + + return 0; +} + +/** +* Changes the selected material when the select tree item changes. +*/ +void MaterialTreeView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) { + + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + + if(pNMTreeView->itemNew.hItem) { + CTreeCtrl& tree = GetTreeCtrl(); + + DWORD type = tree.GetItemData(pNMTreeView->itemNew.hItem); + if(type == TYPE_MATERIAL) { + idStr mediaName = GetMediaPath(pNMTreeView->itemNew.hItem, type); + const idMaterial* material = declManager->FindMaterial(mediaName); + + materialDocManager->SetSelectedMaterial(const_cast(material)); + + } else { + + materialDocManager->SetSelectedMaterial(NULL); + } + + } else { + + materialDocManager->SetSelectedMaterial(NULL); + } + + *pResult = 0; +} + +/** +* Determines if a tree item's label can be edited. +*/ +void MaterialTreeView::OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { + + LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); + + CTreeCtrl& tree = GetTreeCtrl(); + DWORD type = tree.GetItemData(pTVDispInfo->item.hItem); + + //Only allow renaming of materials and material folders + if(type == TYPE_MATERIAL || type == TYPE_MATERIAL_FOLDER) { + *pResult = 0; + } else { + *pResult = 1; + } +} + +/** +* Makes sure that a rename operation can be performed after a label edit is complete and +* performs the folder or material rename. +*/ +void MaterialTreeView::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { + + LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); + + *pResult = 0; + + if(pTVDispInfo->item.pszText) { + + //Convert any edited text to lower case to keep the name canonical + idStr newLabel = pTVDispInfo->item.pszText; + newLabel.ToLower(); + strncpy( pTVDispInfo->item.pszText, newLabel.c_str(), pTVDispInfo->item.cchTextMax); + + CTreeCtrl& tree = GetTreeCtrl(); + DWORD type = tree.GetItemData(pTVDispInfo->item.hItem); + + if(type == TYPE_MATERIAL) { + + MaterialDoc* pMaterial = materialDocManager->GetCurrentMaterialDoc(); + + //Remove our old quick lookup value + materialToTree.Remove(pMaterial->name.c_str()); + + //Generate the new name + idStr material; + HTREEITEM parent = tree.GetParentItem(pTVDispInfo->item.hItem); + DWORD parentType = tree.GetItemData(parent); + if(parentType == TYPE_MATERIAL_FOLDER) { + //Need to include the material folder + material = GetMediaPath(parent, TYPE_MATERIAL_FOLDER); + material += "/"; + } + + material += pTVDispInfo->item.pszText; + + if(declManager->FindMaterial(material, false)) { + //Can't rename because it conflicts with an existing file + MessageBox("Unable to rename material because it conflicts with another material", "Error"); + } else { + //Add it to our quick lookup + materialToTree.Set(material, pTVDispInfo->item.hItem); + + //Finally make the change + internalChange = true; + pMaterial->SetMaterialName(material); + internalChange = false; + + renamedFolder = pTVDispInfo->item.hItem; + PostMessage(MSG_RENAME_MATERIAL_COMPLETE); + + *pResult = 1; + } + + } else if (type == TYPE_MATERIAL_FOLDER) { + + //Clean up the quicktree with the current tree before we allow the edit to commit + CleanLookupTrees(pTVDispInfo->item.hItem); + + //Store some data so the we can make the appropriate changes after the commit + renamedFolder = pTVDispInfo->item.hItem; + + affectedMaterials.Clear(); + GetMaterialPaths(renamedFolder, &affectedMaterials); + + PostMessage(MSG_RENAME_FOLDER_COMPLETE); + + RenameMaterialFolderModifier* mod = new RenameMaterialFolderModifier(materialDocManager, pTVDispInfo->item.pszText, this, pTVDispInfo->item.hItem, tree.GetItemText(pTVDispInfo->item.hItem)); + materialDocManager->AddMaterialUndoModifier(mod); + + *pResult = 1; + } + } +} + +/** +* Displays the popup menu. +*/ +void MaterialTreeView::OnContextMenu(CWnd* pWnd, CPoint point) +{ + ScreenToClient (&point); + PopupMenu (&point); +} + +/** +* Displays the popup menu. +*/ +void MaterialTreeView::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult) +{ + CTreeCtrl& tree = GetTreeCtrl(); + + DWORD dwPos = GetMessagePos(); + + CPoint pt( LOWORD( dwPos ), HIWORD ( dwPos ) ); + + CPoint spt = pt; + tree.ScreenToClient( &spt ); + + UINT test; + HTREEITEM item = tree.HitTest( spt, &test ); + + if ( item != NULL ) + { + if ( test & TVHT_ONITEM ) + { + //Select the item + tree.SelectItem(item); + OnContextMenu( this, pt ); + } + } + + *pResult = 0; +} + +/** +* Handles keyboard shortcut for cut, copy and paste +*/ +void MaterialTreeView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + if(nChar == 3 && GetKeyState(VK_CONTROL)) { + OnCopy(); + } + + if(nChar == 22 && GetKeyState(VK_CONTROL)) { + OnPaste(); + } + + if(nChar == 24 && GetKeyState(VK_CONTROL)) { + OnCut(); + } + + CTreeView::OnChar(nChar, nRepCnt, nFlags); +} + +/** +* Begins the process of a drag cut/copy. +*/ +void MaterialTreeView::OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult) +{ + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM selecteditem = tree.GetSelectedItem(); + + //Check to see if the are clicking on an item + UINT flags; + HTREEITEM item = tree.HitTest(pNMTreeView->ptDrag, &flags); + + if(item && (TVHT_ONITEM & flags)) { + if(item != selecteditem) { + tree.SelectItem(item); + } + } + + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL) { + + //Create the drag image + dragImage = tree.CreateDragImage(item); + dragImage->BeginDrag(0, CPoint (8, 8)); + dragImage->DragEnter(GetDesktopWindow(), pNMTreeView->ptDrag); + + //Drag is in progress + bDragging = true; + + dragItem = item; + + //Capture the messages + SetCapture(); + } + + *pResult = 0; +} + +/** +* Handles mouse movement as an item is being dragged. +*/ +void MaterialTreeView::OnMouseMove(UINT nFlags, CPoint point) { + if( bDragging ) { + CTreeCtrl& tree = GetTreeCtrl(); + + dropPoint = point; + ClientToScreen(&dropPoint); + + //Move the drag image + dragImage->DragMove(dropPoint); + dragImage->DragShowNolock(FALSE); + + dragImage->DragShowNolock(TRUE); + } + + if(bDragging) { + //Test the hover item + + CTreeCtrl& tree = GetTreeCtrl(); + + CPoint point; + GetCursorPos(&point); + ScreenToClient(&point); + + UINT flags; + HTREEITEM item = tree.HitTest(point, &flags); + if(item && (TVHT_ONITEM & flags)) { + if(item != hoverItem) { + hoverItem = item; + hoverStartTime = timeGetTime(); + } else { + DWORD currentTime = timeGetTime(); + if(currentTime - hoverStartTime > HOVER_EXPAND_DELAY) { + + UINT state = tree.GetItemState(hoverItem, TVIS_EXPANDED); + if(state != TVIS_EXPANDED && tree.ItemHasChildren(hoverItem)) { + tree.Expand(hoverItem, TVE_EXPAND); + } + + } + } + } + } + + CTreeView::OnMouseMove(nFlags, point); +} + +/** +* Handles the end of a drag copy/move when the user releases the left mouse button. +*/ +void MaterialTreeView::OnLButtonUp(UINT nFlags, CPoint point) { + CTreeCtrl& tree = GetTreeCtrl(); + + if( bDragging ) { + //Release mouse capture + ReleaseCapture(); + + //Delete the drag image + dragImage->DragLeave(GetDesktopWindow()); + dragImage->EndDrag(); + + bDragging = false; + + delete dragImage; + + UINT flags; + HTREEITEM item = tree.HitTest(point, &flags); + if(item && (TVHT_ONITEM & flags)) { + + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL) //Backup one if a file is selected + item = tree.GetParentItem(item); + + //Make sure we aren't dragging to the same place + HTREEITEM dragItemParent = tree.GetParentItem(dragItem); + if(dragItemParent != item) { + + + idStr dragFile; + GetFileName(dragItem, dragFile); + + idStr filename; + GetFileName(item, filename); + + //Move within a file copy across files + if(!dragFile.Icmp(filename)) { + materialDocManager->CopyMaterial(materialDocManager->GetCurrentMaterialDoc(), true); + } else { + materialDocManager->CopyMaterial(materialDocManager->GetCurrentMaterialDoc(), false); + } + + //Generate the name + + idStr materialName = GetMediaPath(item, itemType); + + idStr copyName = materialDocManager->GetCopyMaterialName(); + idStr copyMaterialName; + copyName.ExtractFileName(copyMaterialName); + materialName += "/" + copyMaterialName; + + //If the material name already exists add numbers until we don't find it + materialName = materialDocManager->GetUniqueMaterialName(materialName); + + //Paste + materialDocManager->PasteMaterial(materialName, filename); + } + } + } + + CTreeView::OnLButtonUp(nFlags, point); +} + +/** +* Applies the current material. +*/ +void MaterialTreeView::OnApplyMaterial() { + materialDocManager->ApplyMaterial(materialDocManager->GetCurrentMaterialDoc()); +} + +/** +* Applies all materials in the currently selected file. +*/ +void MaterialTreeView::OnApplyFile() { + idStr filename; + HTREEITEM item = GetTreeCtrl().GetSelectedItem(); + if(GetFileName(item, filename)) { + materialDocManager->ApplyFile(filename.c_str()); + } +} + +/** +* Applies all materials that need to be applied. +*/ +void MaterialTreeView::OnApplyAll() { + materialDocManager->ApplyAll(); +} + +/** +* Saves the selected material. +*/ +void MaterialTreeView::OnSaveMaterial() { + materialDocManager->SaveMaterial(materialDocManager->GetCurrentMaterialDoc()); +} + +/** +* Saves all materials in the selected file. +*/ +void MaterialTreeView::OnSaveFile() { + idStr filename; + HTREEITEM item = GetTreeCtrl().GetSelectedItem(); + if(GetFileName(item, filename)) { + materialDocManager->SaveFile(filename.c_str()); + } +} + +/** +* Save all materials that have been changed. +*/ +void MaterialTreeView::OnSaveAll() { + materialDocManager->SaveAllMaterials(); +} + +/** +* Begins a label edit to rename a material or material folder. +*/ +void MaterialTreeView::OnRenameMaterial() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + tree.EditLabel(item); +} + +/** +* Adds a new material. +*/ +void MaterialTreeView::OnAddMaterial() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + //Determine the file + HTREEITEM parent = NULL; + if(itemType != TYPE_FILE) { + + parent = tree.GetParentItem(item); + while(1) { + if(tree.GetItemData(parent) == TYPE_FILE) + break; + parent = tree.GetParentItem(parent); + } + } else { + parent = item; + } + idStr filename = GetMediaPath(parent, TYPE_FILE); + + + //Determine the material folder + idStr materialFolder = ""; + switch(itemType) { + case TYPE_MATERIAL: + { + HTREEITEM parentFolderItem = tree.GetParentItem(item); + if(tree.GetItemData(parentFolderItem) == TYPE_MATERIAL_FOLDER) + materialFolder = GetMediaPath(parentFolderItem, TYPE_MATERIAL_FOLDER); + } + break; + case TYPE_MATERIAL_FOLDER: + materialFolder = GetMediaPath(item, TYPE_MATERIAL_FOLDER); + break; + case TYPE_FILE: + //There is no material folder + break; + } + + idStr name; + int num = 1; + while(1) { + if(materialFolder.Length() > 0) { + name = va("%s/newmaterial%d", materialFolder.c_str(), num); + } else { + name = va("newmaterial%d", num); + } + if(!declManager->FindMaterial(name, false)) + break; + num++; + } + + materialDocManager->AddMaterial(name.c_str(), filename.c_str()); + +} + +/** +* Adds a new folder +*/ +void MaterialTreeView::OnAddFolder() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + + //Backup if the selected item is a material + if(itemType == TYPE_MATERIAL) { + item = tree.GetParentItem(item); + } + + //Pick a unique material name + idStr newFolder; + int num = 1; + while(1) { + newFolder = va("newfolder%d", num); + if(tree.ItemHasChildren(item)) { + HTREEITEM hChildItem = tree.GetChildItem(item); + bool found = false; + while (hChildItem != NULL) + { + if(!newFolder.Icmp(tree.GetItemText(hChildItem))) { + found = true; + break; + } + hChildItem = tree.GetNextSiblingItem(hChildItem); + } + if(!found) + break; + } else { + break; + } + num++; + } + + HTREEITEM newItem = AddFolder(newFolder, item); + + AddMaterialFolderModifier* mod = new AddMaterialFolderModifier(materialDocManager, newFolder, this, newItem, item); + materialDocManager->AddMaterialUndoModifier(mod); +} + +/** +* Deletes a material or material folder. +*/ +void MaterialTreeView::OnDeleteMaterial() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL_FOLDER) { + int result = MessageBox("Are you sure you want to delete this folder?", "Delete?", MB_ICONQUESTION | MB_YESNO); + if(result == IDYES) { + DeleteFolder(item); + } + } else if (itemType == TYPE_MATERIAL) { + int result = MessageBox("Are you sure you want to delete this material?", "Delete?", MB_ICONQUESTION | MB_YESNO); + if(result == IDYES) { + materialDocManager->DeleteMaterial(materialDocManager->GetCurrentMaterialDoc()); + } + } +} + +/** +* Reloads the selected file. +*/ +void MaterialTreeView::OnReloadFile() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL || itemType == TYPE_FILE || itemType == TYPE_MATERIAL_FOLDER) { + idStr filename; + GetFileName(item, filename); + + if(materialDocManager->IsFileModified(filename)) { + int result = MessageBox("This file has been modified. Are you sure you want to reload this file?", "Reload?", MB_ICONQUESTION | MB_YESNO); + if(result != IDYES) { + return; + } + } + materialDocManager->ReloadFile(filename); + } +} + +/** +* Performs a cut operation. +*/ +void MaterialTreeView::OnCut() { + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(item && itemType == TYPE_MATERIAL) { + materialDocManager->CopyMaterial(materialDocManager->GetCurrentMaterialDoc(), true); + } else if (itemType == TYPE_MATERIAL_FOLDER) { + } +} + +/** +* Performs a copy operation. +*/ +void MaterialTreeView::OnCopy() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + if(itemType == TYPE_MATERIAL) { + materialDocManager->CopyMaterial(materialDocManager->GetCurrentMaterialDoc(), false); + } else if (itemType == TYPE_MATERIAL_FOLDER) { + } +} + +/** +* Performs a paste operation. +*/ +void MaterialTreeView::OnPaste() { + + CTreeCtrl& tree = GetTreeCtrl(); + + HTREEITEM item = tree.GetSelectedItem(); + DWORD itemType = tree.GetItemData(item); + + //Paste a material + if(item && materialDocManager->IsCopyMaterial() && itemType >= TYPE_FILE) { + + //Generate the name + if(itemType == TYPE_MATERIAL) {//Backup one if a file is selected + item = tree.GetParentItem(item); + itemType = tree.GetItemData(item); + } + + idStr materialName = ""; + if(itemType != TYPE_FILE) { + materialName = GetMediaPath(item, itemType) + "/"; + } + + idStr copyName = materialDocManager->GetCopyMaterialName(); + idStr copyMaterialName; + copyName.ExtractFileName(copyMaterialName); + materialName += copyMaterialName; + + idStr filename; + GetFileName(item, filename); + + //If the material name already exists add numbers until we don't find it + materialName = materialDocManager->GetUniqueMaterialName(materialName); + + //Paste + materialDocManager->PasteMaterial(materialName, filename); + + } +} + +/** +* This message is sent after the label edit is complete to actually perform the rename +* operation. +*/ +LRESULT MaterialTreeView::OnRenameFolderComplete(WPARAM wParam, LPARAM lParam) { + + //Generate new quick tree info for all material folders + BuildLookupTrees(renamedFolder); + + //Go through the list of affected materials and rename them + for(int i = 0; i < affectedMaterials.Num(); i++) { + RenameMaterial(affectedMaterials[i].treeItem, affectedMaterials[i].materialName); + } + + //Make sure the tree stays sorted + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM parent = tree.GetParentItem(renamedFolder); + tree.SortChildren(parent); + + return 0; +} + +/** +* This message is sent after the label edit is complete to ensure that the sorting stays consistent. +*/ +LRESULT MaterialTreeView::OnRenameMaterialComplete(WPARAM wParam, LPARAM lParam) { + + //Make sure the tree stays sorted + CTreeCtrl& tree = GetTreeCtrl(); + HTREEITEM parent = tree.GetParentItem(renamedFolder); + tree.SortChildren(parent); + + return 0; +} + +/** +* Handles all of the little problems associated with renaming a folder. +*/ +void MaterialTreeView::RenameMaterial(HTREEITEM item, const char* originalName) { + + CTreeCtrl& tree = GetTreeCtrl(); + + const idMaterial* material = declManager->FindMaterial(originalName); + + MaterialDoc* pMaterial; + //pMaterial = materialDocManager->GetInProgressDoc(material); + + //if(!pMaterial) { + pMaterial = materialDocManager->CreateMaterialDoc(const_cast(material)); + //} + + //Remove our old quick lookup value + materialToTree.Remove(originalName); + + //Generate the new name + idStr materialName; + HTREEITEM parent = tree.GetParentItem(item); + DWORD parentType = tree.GetItemData(parent); + if(parentType == TYPE_MATERIAL_FOLDER) { + //Need to include the material folder + materialName = GetMediaPath(parent, TYPE_MATERIAL_FOLDER); + materialName += "/"; + } + materialName += tree.GetItemText(item); + + + //Add it to our quick lookup + materialToTree.Set(materialName, item); + + //Finally make the change + internalChange = true; + pMaterial->SetMaterialName(materialName, false); + internalChange = false; +} + +/** +* Returns the filename of the provided item. +* @param item The item for which to generate the filename +* @param out The location the filename will be placed. +*/ +bool MaterialTreeView::GetFileName(HTREEITEM item, idStr& out) { + + out = ""; + + CTreeCtrl& tree = GetTreeCtrl(); + DWORD type = tree.GetItemData(item); + + if(type != TYPE_MATERIAL && type != TYPE_MATERIAL_FOLDER && type != TYPE_FILE) + return false; + + if(type == TYPE_FILE) { + out = GetMediaPath(item, TYPE_FILE); + return true; + } + + HTREEITEM parent = tree.GetParentItem( item ); + while ( parent != NULL ) { + DWORD parentType = tree.GetItemData(parent); + if(parentType == TYPE_FILE) { + out = GetMediaPath(parent, TYPE_FILE); + return true; + } + parent = tree.GetParentItem( parent ); + } + + return false; +} + +/** +* Returns the Doom III name for the provided item +* @param item The item for which to generate the name +* @param type The type of the selected item +*/ +idStr MaterialTreeView::GetMediaPath(HTREEITEM item, DWORD type) { + + //Determine when to stop building the path + DWORD stopType = TYPE_ROOT; + switch(type) { + case TYPE_MATERIAL: + stopType = TYPE_FILE; + break; + case TYPE_MATERIAL_FOLDER: + stopType = TYPE_FILE; + break; + case TYPE_FILE: + stopType = TYPE_ROOT; + break; + }; + + CTreeCtrl& tree = GetTreeCtrl(); + + idStr mediaName = tree.GetItemText( item ); + + // have to build the name back up + HTREEITEM parent = tree.GetParentItem( item ); + while ( parent != NULL ) { + + //stop the iteration once we have found a specific type + DWORD parentType = tree.GetItemData(parent); + if(parentType == stopType) { + break; + } + + idStr strParent = tree.GetItemText( parent ); + strParent += "/"; + strParent += mediaName; + mediaName = strParent; + parent = tree.GetParentItem( parent ); + + } + + return mediaName; +} + +/** +* Creates a list of material paths for all materials under the provided item. +* @param item The base item for which to generate the list +* @param list The list in which the paths will be stored. +*/ +void MaterialTreeView::GetMaterialPaths(HTREEITEM item, idList* list) { + + CTreeCtrl& tree = GetTreeCtrl(); + if(tree.ItemHasChildren(item)) { + + HTREEITEM childItem = tree.GetChildItem(item); + while(childItem != NULL) { + + DWORD childType = tree.GetItemData(childItem); + if (childType == TYPE_MATERIAL) { + MaterialTreeItem_t mat; + mat.materialName = GetMediaPath(childItem, TYPE_MATERIAL); + mat.treeItem = childItem; + list->Append(mat); + } else if (childType == TYPE_MATERIAL_FOLDER) { + GetMaterialPaths(childItem, list); + } + childItem = tree.GetNextSiblingItem(childItem); + } + } +} + +/** +* Adds a string list of materials to the tree creating the proper hierarchy. +* @param root The name of the root item or NULL for no root item. +* @param list The list of materials. +* @param includeFile If true the materials will be sorted by file. +*/ +void MaterialTreeView::AddStrList(const char *root, idStrList *list, bool includeFile) { + + CTreeCtrl& treeMedia = GetTreeCtrl(); + + idStr out, path; + HTREEITEM base = NULL; + + if(root) { + base = treeMedia.GetRootItem(); + if (base) { + out = treeMedia.GetItemText(base); + if (stricmp(root, out)) { + base = NULL; + } + } + + if (base == NULL) { + base = treeMedia.InsertItem(root); + treeMedia.SetItemData(base, TYPE_ROOT); + } + } + + HTREEITEM item = base; + HTREEITEM add; + + list->Sort(); + int count = list->Num(); + + idStr last, qt; + for (int i = 0; i < count; i++) { + idStr *strItem = &(*list)[i]; + + + idStr name = strItem->c_str(); + + idStr filename; + bool afterFile = true; + if(includeFile) { + int index = name.Find("|"); + if(index >= 0) { + afterFile = false; + filename = name.Right(name.Length() - index - 1); + name = name.Left(index); + } + } + + // now break the name down convert to slashes + name.BackSlashesToSlashes(); + name.Strip(' '); + + int index; + int len = last.Length(); + if (len == 0) { + index = name.Last('/'); + if (index >= 0) { + name.Left(index, last); + } + } + else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) { + name.Right(name.Length() - len - 1, out); + add = treeMedia.InsertItem(out, item); + qt = root; + qt += "/"; + qt += name; + quickTree.Set(qt, add); + treeMedia.SetItemImage(add, IMAGE_MATERIAL, IMAGE_MATERIAL); + treeMedia.SetItemData(add, TYPE_MATERIAL); + + //Add the item to a quick lookup table + idStr material = GetMediaPath(add, TYPE_MATERIAL); + materialToTree.Set(material, add); + + continue; + } + else { + last.Empty(); + } + + index = 0; + item = base; + path = ""; + while (index >= 0) { + index = name.Find('/'); + if (index >= 0) { + HTREEITEM newItem = NULL; + HTREEITEM *check = NULL; + name.Left(index, out); + path += out; + qt = root; + qt += "/"; + qt += path; + if (quickTree.Get(qt, &check)) { + newItem = *check; + } + + bool thisisfile = false; + if(out == filename) { + thisisfile = true; + afterFile = true; + + } + + if (newItem == NULL) { + newItem = treeMedia.InsertItem(out, item); + qt = root; + qt += "/"; + qt += path; + quickTree.Set(qt, newItem); + + + if(!afterFile || thisisfile) { + if(thisisfile) { + afterFile = true; + treeMedia.SetItemImage(newItem, IMAGE_FILE, IMAGE_FILE); + treeMedia.SetItemData(newItem, TYPE_FILE); + + //Add the item to a quick lookup table + idStr file = GetMediaPath(newItem, TYPE_FILE); + //common->Printf("Adding fileToTree: %s - %d\n", file.c_str(), newItem); + fileToTree.Set(file, newItem); + + } else { + treeMedia.SetItemImage(newItem, IMAGE_FOLDER, IMAGE_FOLDER); + treeMedia.SetItemData(newItem, TYPE_FOLDER); + } + } else { + treeMedia.SetItemImage(newItem, IMAGE_MATERIAL_FOLDER, IMAGE_MATERIAL_FOLDER); + treeMedia.SetItemData(newItem, TYPE_MATERIAL_FOLDER); + + } + } + + + item = newItem; + name.Right(name.Length() - index - 1, out); + name = out; + path += "/"; + } + else { + add = treeMedia.InsertItem(name, item); + qt = root; + qt += "/"; + qt += path; + qt += name; + quickTree.Set(qt, add); + treeMedia.SetItemImage(add, IMAGE_MATERIAL, IMAGE_MATERIAL); + treeMedia.SetItemData(add, TYPE_MATERIAL); + path = ""; + + //Add the item to a quick lookup table + idStr material = GetMediaPath(add, TYPE_MATERIAL); + materialToTree.Set(material, add); + } + } + } +} + +/** +* Displays the popup menu with all of the appropriate menu items enabled. +* @param pt The location where the menu should be displayed. +*/ +void MaterialTreeView::PopupMenu(CPoint* pt) { + + //Determine the type of object clicked on + CTreeCtrl& tree = GetTreeCtrl(); + UINT test; + HTREEITEM item = tree.HitTest( *pt, &test ); + if ( item == NULL || !(test & TVHT_ONITEM) ) + return; + + ClientToScreen (pt); + + CMenu FloatingMenu; + VERIFY(FloatingMenu.LoadMenu(IDR_ME_MATERIALTREE_POPUP)); + CMenu* pPopupMenu = FloatingMenu.GetSubMenu (0); + + DWORD itemType = tree.GetItemData(item); + + //Enable/Disable based on the state + MaterialDoc* pDoc = materialDocManager->GetCurrentMaterialDoc(); + + + //Apply Changes + if(pDoc && pDoc->applyWaiting) { + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYMATERIAL, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYMATERIAL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + //Apply File + idStr filename; + if(GetFileName(item, filename)) { + if(materialDocManager->DoesFileNeedApply(filename.c_str())) + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYFILE, MF_BYCOMMAND | MF_ENABLED); + else + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYFILE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYFILE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + //Apply All + if(materialDocManager->DoesAnyNeedApply()) { + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYALL, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_APPLYALL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + //Save Material + if(pDoc && pDoc->modified) { + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEMATERIAL, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEMATERIAL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + //Save File + if(GetFileName(item, filename)) { + if(materialDocManager->IsFileModified(filename.c_str())) + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEFILE, MF_BYCOMMAND | MF_ENABLED); + else + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEFILE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEFILE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + //Save All + if(materialDocManager->IsAnyModified()) { + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEALL, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_SAVEALL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if(itemType == TYPE_MATERIAL || itemType == TYPE_MATERIAL_FOLDER) { + pPopupMenu->EnableMenuItem(ID_POPUP_RENAMEMATERIAL, MF_BYCOMMAND | MF_ENABLED); + pPopupMenu->EnableMenuItem(ID_POPUP_DELETEMATERIAL, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_RENAMEMATERIAL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_POPUP_DELETEMATERIAL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if(itemType == TYPE_FILE || itemType == TYPE_MATERIAL_FOLDER || itemType == TYPE_MATERIAL) { + pPopupMenu->EnableMenuItem(ID_POPUP_ADDMATERIAL, MF_BYCOMMAND | MF_ENABLED); + pPopupMenu->EnableMenuItem(ID_POPUP_ADDFOLDER, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_ADDMATERIAL, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_POPUP_ADDFOLDER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if(itemType == TYPE_MATERIAL) { + pPopupMenu->EnableMenuItem(ID_POPUP_CUT, MF_BYCOMMAND | MF_ENABLED); + pPopupMenu->EnableMenuItem(ID_POPUP_COPY, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_POPUP_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if((itemType == TYPE_MATERIAL || itemType == TYPE_FILE || itemType == TYPE_MATERIAL_FOLDER) && materialDocManager->IsCopyMaterial()) { + pPopupMenu->EnableMenuItem(ID_POPUP_PASTE, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_PASTE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if(itemType == TYPE_MATERIAL || itemType == TYPE_FILE || itemType == TYPE_MATERIAL_FOLDER) { + pPopupMenu->EnableMenuItem(ID_POPUP_RELOADFILE, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_POPUP_RELOADFILE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt->x, pt->y, &GetTreeCtrl()); +} + +/** +* Sets the appropriate item image based on the state of the item. +* @param item The item to set. +* @param mod Is the item modified +* @param apply Does the item need an apply +* @param children Should this method recurse through the items children and set their icons. +*/ +void MaterialTreeView::SetItemImage(HTREEITEM item, bool mod, bool apply, bool children) { + + CTreeCtrl& tree = GetTreeCtrl(); + + int image; + + DWORD itemType = tree.GetItemData(item); + switch(itemType) { + case TYPE_FILE: + if(mod) + image = IMAGE_FILE_MOD; + else + image = IMAGE_FILE; + break; + case TYPE_MATERIAL_FOLDER: + image = IMAGE_MATERIAL_FOLDER; + break; + case TYPE_MATERIAL: + if(mod && apply) + image = IMAGE_MATERIAL_MOD_APPLY; + else if(mod) + image = IMAGE_MATERIAL_MOD; + else + image = IMAGE_MATERIAL; + break; + } + + tree.SetItemImage(item, image, image); + + if(children) { + if(tree.ItemHasChildren(item)) { + HTREEITEM hChildItem = tree.GetChildItem(item); + while (hChildItem != NULL) { + SetItemImage(hChildItem, mod, apply, children); + hChildItem = tree.GetNextSiblingItem(hChildItem); + } + } + } +} + +/** +* Cleans the lookup tables for the provided item and all children. +* @param item The item to start from +*/ +void MaterialTreeView::CleanLookupTrees(HTREEITEM item) { + + idStr qt = GetQuicktreePath(item); + quickTree.Remove(qt); + + CTreeCtrl& tree = GetTreeCtrl(); + + //Clean special lookup tables + DWORD type = tree.GetItemData(item); + if(type == TYPE_FILE) { + idStr file = GetMediaPath(item, TYPE_FILE); + fileToTree.Remove(file); + } else if(type == TYPE_MATERIAL) { + idStr name = GetMediaPath(item, TYPE_MATERIAL); + materialToTree.Remove(name); + } + + //Clean all my children + if(tree.ItemHasChildren(item)) { + HTREEITEM childItem = tree.GetChildItem(item); + while(childItem != NULL) { + CleanLookupTrees(childItem); + childItem = tree.GetNextSiblingItem(childItem); + } + } +} + +/** +* Build the lookup tree for a given item and all of its children. +* @param item The item to start from +*/ +void MaterialTreeView::BuildLookupTrees(HTREEITEM item) { + + //Add my quicktree item + idStr qt = GetQuicktreePath(item); + quickTree.Set(qt, item); + + CTreeCtrl& tree = GetTreeCtrl(); + if(tree.ItemHasChildren(item)) { + HTREEITEM childItem = tree.GetChildItem(item); + while(childItem != NULL) { + DWORD childType = tree.GetItemData(childItem); + if(childType == TYPE_MATERIAL_FOLDER) { + //Recursively call this method for all my child folders + BuildLookupTrees(childItem); + } + childItem = tree.GetNextSiblingItem(childItem); + } + } +} + +/** +* Returns the quicktree path for a given item. +* @param item The item for which to generate the quicktree path +*/ +idStr MaterialTreeView::GetQuicktreePath(HTREEITEM item) { + CTreeCtrl& tree = GetTreeCtrl(); + + idStr qt = ""; + HTREEITEM pathItem = item; + while(pathItem != NULL) { + qt = "/" + idStr(tree.GetItemText(pathItem)) + qt; + pathItem = tree.GetParentItem(pathItem); + } + return qt; +} + + + + + + + + + + + diff --git a/tools/materialeditor/MaterialTreeView.h b/tools/materialeditor/MaterialTreeView.h new file mode 100644 index 000000000..2b7f05a3b --- /dev/null +++ b/tools/materialeditor/MaterialTreeView.h @@ -0,0 +1,166 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include +#include "../common/PropTree/PropTreeView.h" +#include "MaterialEditor.h" +#include "MaterialView.h" + +/** +* Structure used associate a material name with a tree item. +*/ +typedef struct { + idStr materialName; + HTREEITEM treeItem; +} MaterialTreeItem_t; + +/** +* A tree view of all the materials that have been defined. +*/ +class MaterialTreeView : public CTreeView, public MaterialView { + +public: + virtual ~MaterialTreeView(); + + void InitializeMaterialList(bool includeFile = true, const char* filename = NULL); + void BuildMaterialList(bool includeFile = true, const char* filename = NULL); + + //Material Interface + virtual void MV_OnMaterialChange(MaterialDoc* pMaterial); + virtual void MV_OnMaterialApply(MaterialDoc* pMaterial); + virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial); + virtual void MV_OnMaterialAdd(MaterialDoc* pMaterial); + virtual void MV_OnMaterialDelete(MaterialDoc* pMaterial); + virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName); + virtual void MV_OnFileReload(const char* filename); + + bool CanCopy(); + bool CanPaste(); + bool CanCut(); + bool CanDelete(); + bool CanRename(); + bool CanSaveFile(); + idStr GetSaveFilename(); + + bool FindNextMaterial(MaterialSearchData_t* searchData); + HTREEITEM FindNextMaterial(HTREEITEM item, MaterialSearchData_t* searchData); + HTREEITEM GetNextSeachItem(HTREEITEM item, bool stayInFile); + + void DeleteFolder(HTREEITEM item, bool addUndo = true); + HTREEITEM AddFolder(const char* name, HTREEITEM parent); + void RenameFolder(HTREEITEM item, const char* name); + + +protected: + MaterialTreeView(); + DECLARE_DYNCREATE(MaterialTreeView) + + /** + * List of tree item types + */ + enum { + TYPE_ROOT = 0, + TYPE_FOLDER, + TYPE_FILE, + TYPE_MATERIAL_FOLDER, + TYPE_MATERIAL + }; + + //Overrides + virtual BOOL PreTranslateMessage(MSG* pMsg); + + //Window Messages + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + + //Menu Commands + afx_msg void OnApplyMaterial(); + afx_msg void OnApplyFile(); + afx_msg void OnApplyAll(); + afx_msg void OnSaveMaterial(); + afx_msg void OnSaveFile(); + afx_msg void OnSaveAll(); + afx_msg void OnRenameMaterial(); + afx_msg void OnAddMaterial(); + afx_msg void OnAddFolder(); + afx_msg void OnDeleteMaterial(); + afx_msg void OnReloadFile(); + afx_msg void OnCut(); + afx_msg void OnCopy(); + afx_msg void OnPaste(); + + //Internal Messages + afx_msg LRESULT OnRenameFolderComplete(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnRenameMaterialComplete(WPARAM wParam, LPARAM lParam); + + DECLARE_MESSAGE_MAP() + + + //Utility methods + void RenameMaterial(HTREEITEM item, const char* originalName); + bool GetFileName(HTREEITEM item, idStr& out); + idStr GetMediaPath(HTREEITEM item, DWORD type); + void GetMaterialPaths(HTREEITEM item, idList* list); + void AddStrList(const char *root, idStrList *list, bool includeFile); + void PopupMenu(CPoint* pt); + void SetItemImage(HTREEITEM item, bool mod, bool apply, bool children); + + + //Methods for working with the quicktree + void CleanLookupTrees(HTREEITEM item); + void BuildLookupTrees(HTREEITEM item); + idStr GetQuicktreePath(HTREEITEM item); + + +protected: + CImageList m_image; + bool treeWithFile; + + //Hashtables for quick lookups + idHashTable quickTree; + idHashTable materialToTree; + idHashTable fileToTree; + + + //Member variables for renaming folders + HTREEITEM renamedFolder; + idList affectedMaterials; + + CImageList* dragImage; + bool bDragging; + CPoint dropPoint; + HTREEITEM dragItem; + + //Hover Expand + HTREEITEM hoverItem; + DWORD hoverStartTime; + + bool internalChange; +}; + + diff --git a/tools/materialeditor/MaterialView.cpp b/tools/materialeditor/MaterialView.cpp new file mode 100644 index 000000000..0dcd65f1e --- /dev/null +++ b/tools/materialeditor/MaterialView.cpp @@ -0,0 +1,23 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "materialview.h" + diff --git a/tools/materialeditor/MaterialView.h b/tools/materialeditor/MaterialView.h new file mode 100644 index 000000000..9b5fd94ab --- /dev/null +++ b/tools/materialeditor/MaterialView.h @@ -0,0 +1,139 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "MaterialDocManager.h" + +/** +* MaterialView Interface. Interface to be implemented by classes that want +* notifications of material changes. Classes that implement this interface +* must register themself with the MaterialDocManager class with the +* RegisterView method. +*/ +class MaterialView { +public: + /** + * Constructor. + */ + MaterialView(void) { materialDocManager = NULL; }; + /** + * Destructor. + */ + virtual ~MaterialView(void) {}; + + ////////////////////////////////////////////////////////////////////////// + //Public Interface to be implemented by subclasses + ////////////////////////////////////////////////////////////////////////// + + /** + * Sets the material document manager for this view instance. + * @param docManager The material document manager for this view instance. + */ + virtual void SetMaterialDocManager(MaterialDocManager* docManager) { materialDocManager = docManager; }; + + /** + * Called when the selected material has changed. + * @param pMaterial The newly selected material. + */ + virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) {}; + + /** + * Called when the material has changed but not applied. + * @param pMaterial The selected material. + */ + virtual void MV_OnMaterialChange(MaterialDoc* pMaterial) {}; + + /** + * Called when the material changes have been applied. + * @param pMaterial The selected material. + */ + virtual void MV_OnMaterialApply(MaterialDoc* pMaterial) {}; + + /** + * Called when the material changes have been saved. + * @param pMaterial The saved material. + */ + virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial) {}; + + /** + * Called when a material file has been saved + * @param filename path of the file that was saved. + */ + virtual void MV_OnMaterialSaveFile(const char* filename) {}; + + /** + * Called when a material is added + * @param pMaterial The material that was added. + */ + virtual void MV_OnMaterialAdd(MaterialDoc* pMaterial) {}; + + /** + * Called when a material is deleted + * @param pMaterial The material that was deleted. + */ + virtual void MV_OnMaterialDelete(MaterialDoc* pMaterial) {}; + + /** + * Called when a stage is added + * @param pMaterial The material that was affected. + * @param stageNum The index of the stage that was added + */ + virtual void MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum) {}; + + /** + * Called when a stage is deleted + * @param pMaterial The material that was affected. + * @param stageNum The index of the stage that was deleted + */ + virtual void MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum) {}; + + /** + * Called when a stage is moved + * @param pMaterial The material that was deleted. + * @param from The from index + * @param to The to index + */ + virtual void MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to) {}; + + /** + * Called when an attribute is changed + * @param pMaterial The material that was deleted. + * @param stage The stage that contains the change. + * @param attribName The attribute that has changed. + */ + virtual void MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName) {}; + + + /** + * Called when the material name has changed + * @param pMaterial The material that was deleted. + * @param oldName The old name of the material. + */ + virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName) {}; + + /** + * Called when a file has been reloaded + * @param filename The file that was reloaded. + */ + virtual void MV_OnFileReload(const char* filename) {}; + + +protected: + MaterialDocManager* materialDocManager; +}; diff --git a/tools/materialeditor/StageView.cpp b/tools/materialeditor/StageView.cpp new file mode 100644 index 000000000..66c435729 --- /dev/null +++ b/tools/materialeditor/StageView.cpp @@ -0,0 +1,819 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "StageView.h" + +IMPLEMENT_DYNCREATE(StageView, ToggleListView) + +BEGIN_MESSAGE_MAP(StageView, ToggleListView) + ON_WM_CREATE() + ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnLvnItemchanged) + ON_NOTIFY_REFLECT(LVN_DELETEALLITEMS, OnLvnDeleteallitems) + ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnLvnBegindrag) + ON_WM_LBUTTONUP() + ON_WM_MOUSEMOVE() + ON_NOTIFY_REFLECT(NM_RCLICK, OnNMRclick) + + ON_COMMAND(ID_STAGEPOPUP_RENAMESTAGE, OnRenameStage) + ON_COMMAND(ID_STAGEPOPUP_DELETESTAGE, OnDeleteStage) + ON_COMMAND(ID_STAGEPOPUP_DELETEALLSTAGES, OnDeleteAllStages) + ON_COMMAND(ID_STAGEPOPUP_ADDSTAGE, OnAddStage) + ON_COMMAND(ID_STAGEPOPUP_ADDBUMPMAP, OnAddBumpmapStage) + ON_COMMAND(ID_STAGEPOPUP_ADDDIFFUSEMAP, OnAddDiffuseStage) + ON_COMMAND(ID_STAGEPOPUP_ADDSPECULAR, OnAddSpecualarStage) + + ON_COMMAND(ID_STAGEPOPUP_COPY, OnCopy) + ON_COMMAND(ID_STAGEPOPUP_PASTE, OnPaste) + + ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnLvnBeginlabeledit) + ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnLvnEndlabeledit) + ON_WM_CHAR() +END_MESSAGE_MAP() + +/** +* Constructor for StageView. +*/ +StageView::StageView() { + currentMaterial = NULL; + bDragging = false; + internalChange = false; +} + +/** +* Destructor for StageView. +*/ +StageView::~StageView() { +} + +/** +* Called when the selected material has changed. +* @param pMaterial The newly selected material. +*/ +void StageView::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) { + + currentMaterial = pMaterial; + + RefreshStageList(); +} + +/** +* Called when the material changes have been saved. +* @param pMaterial The saved material. +*/ +void StageView::MV_OnMaterialSaved(MaterialDoc* pMaterial) { + + CListCtrl& list = GetListCtrl(); + + //Saving a material reenables all of the stages + if(pMaterial == currentMaterial) { + for(int i = 1; i < list.GetItemCount(); i++) { + SetToggleState(i, ToggleListView::TOGGLE_STATE_ON); + } + } +} + +/** +* Called when a stage is added +* @param pMaterial The material that was affected. +* @param stageNum The index of the stage that was added +*/ +void StageView::MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum) { + + CListCtrl& list = GetListCtrl(); + + idStr name = pMaterial->GetAttribute(stageNum, "name"); + + int index = list.InsertItem(stageNum+1, name.c_str()); + SetToggleState(index, ToggleListView::TOGGLE_STATE_ON); +} + +/** +* Called when a stage is deleted +* @param pMaterial The material that was affected. +* @param stageNum The index of the stage that was deleted +*/ +void StageView::MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum) { + CListCtrl& list = GetListCtrl(); + list.DeleteItem(stageNum+1); +} + +/** +* Called when a stage is moved +* @param pMaterial The material that was deleted. +* @param from The from index +* @param to The to index +*/ +void StageView::MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to) { + + if(!internalChange) { + from++; + to++; + + CListCtrl& list = GetListCtrl(); + + char szLabel[256]; + LV_ITEM lvi; + ZeroMemory(&lvi, sizeof(LV_ITEM)); + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM; + lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED; + lvi.pszText = szLabel; + lvi.iItem = from; + lvi.cchTextMax = 255; + list.GetItem(&lvi); + + //Delete the original item + list.DeleteItem(from); + + //Insert the item + lvi.iItem = to; + list.InsertItem(&lvi); + + int type = -1; + + int stageType = currentMaterial->GetAttributeInt(to-1, "stagetype"); + switch(stageType) { + case MaterialDoc::STAGE_TYPE_NORMAL: + type = MaterialDefManager::MATERIAL_DEF_STAGE; + break; + case MaterialDoc::STAGE_TYPE_SPECIALMAP: + type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE; + break; + } + + m_propView->SetPropertyListType(type, to-1); + + Invalidate(); + + } +} + +/** +* Called when an attribute is changed +* @param pMaterial The material that was deleted. +* @param stage The stage that contains the change. +* @param attribName The attribute that has changed. +*/ +void StageView::MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName) { + + //Refresh this stage list if a material name has changed + if(!internalChange && currentMaterial == pMaterial && stage >= 0 && attribName && !strcmp(attribName, "name") ) { + CListCtrl& list = GetListCtrl(); + list.SetItemText(stage+1, 0, currentMaterial->GetAttribute(stage, attribName)); + } +} + +/** +* Returns true if the current state of the stage view will allow a copy operation +*/ +bool StageView::CanCopy() { + + CListCtrl& list = GetListCtrl(); + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) + nItem = list.GetNextSelectedItem(pos); + + if(nItem > 0) { + return true; + } else { + return false; + } +} + +/** +* Returns true if the current state of the stage view will allow a paste operation +*/ +bool StageView::CanPaste() { + return materialDocManager->IsCopyStage(); +} + +/** +* Cut is not supported for stages. +*/ +bool StageView::CanCut() { + //No cut for stages + return false; +} + +/** +* Returns true if the current state of the stage view will allow a delete operation +*/ +bool StageView::CanDelete() { + CListCtrl& list = GetListCtrl(); + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) { + nItem = list.GetNextSelectedItem(pos); + } + + if(nItem > 0) + return true; + + return false; +} + +/** +* Returns true if the current state of the stage view will allow a rename operation +*/ +bool StageView::CanRename() { + CListCtrl& list = GetListCtrl(); + + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) { + nItem = list.GetNextSelectedItem(pos); + } + + if(nItem > 0) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(nItem > 0 && material->GetAttributeInt(nItem-1, "stagetype") == MaterialDoc::STAGE_TYPE_NORMAL) { + return true; + } + } + + return false; +} + +/** +* Rebuilds the list of stages based on the currently selected material +*/ +void StageView::RefreshStageList() { + + CListCtrl& list = GetListCtrl(); + + POSITION pos = list.GetFirstSelectedItemPosition(); + int selectedItem = -1; + if(pos) + selectedItem = list.GetNextSelectedItem(pos); + + list.DeleteAllItems(); + + if(currentMaterial) { + + //Always add the material item for the main material properties + list.InsertItem(0, "Material"); + SetToggleState(0, ToggleListView::TOGGLE_STATE_DISABLED); + + //Get the stage info + int stageCount = currentMaterial->GetStageCount(); + for(int i = 0; i < stageCount; i++) { + const char* name = currentMaterial->GetAttribute(i, "name"); + + int itemNum = list.InsertItem(list.GetItemCount(), name); + + if(currentMaterial->IsStageEnabled(i)) { + SetToggleState(itemNum, ToggleListView::TOGGLE_STATE_ON); + } else { + SetToggleState(itemNum, ToggleListView::TOGGLE_STATE_OFF); + } + } + + if(selectedItem < 0) { + //Select the material + list.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } else { + list.SetItemState(selectedItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } + } +} + +/** +* Called by the MFC framework when the view is being created. +*/ +int StageView::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (ToggleListView::OnCreate(lpCreateStruct) == -1) + return -1; + + SetToggleIcons(MAKEINTRESOURCE(IDI_ME_DISABLED_ICON), MAKEINTRESOURCE(IDI_ME_ON_ICON), MAKEINTRESOURCE(IDI_ME_OFF_ICON)); + + return 0; +} + +/** +* Called when the user changes the selection in the list box. This method will notify the +* property view of the change so that it can display the appropriate properties. +*/ +void StageView::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + + if(!bDragging) { + + //The state has changed and changed to selected + if(pNMLV->uChanged && LVIF_STATE && pNMLV->uNewState & LVIS_SELECTED) { + + int type = -1; + + if(pNMLV->iItem >= 0) { + if(pNMLV->iItem == 0) + type = MaterialDefManager::MATERIAL_DEF_MATERIAL; + else { + int stageType = currentMaterial->GetAttributeInt(pNMLV->iItem-1, "stagetype"); + switch(stageType) { + case MaterialDoc::STAGE_TYPE_NORMAL: + type = MaterialDefManager::MATERIAL_DEF_STAGE; + break; + case MaterialDoc::STAGE_TYPE_SPECIALMAP: + type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE; + break; + } + } + } + + m_propView->SetPropertyListType(type, pNMLV->iItem-1); + } + + if(pNMLV->uChanged && LVIF_STATE && pNMLV->uOldState & LVIS_SELECTED && !(pNMLV->uNewState & LVIS_SELECTED)) { + //This item was deselected. + //If there is no item selected then clear the prop list + CListCtrl& list = GetListCtrl(); + POSITION pos = list.GetFirstSelectedItemPosition(); + if(!pos) + m_propView->SetPropertyListType(-1); + } + } + *pResult = 0; +} + +/** +* Notifies the property view that all stages have been removed. +*/ +void StageView::OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + + //The list has been cleared so clear the prop view + m_propView->SetPropertyListType(-1); + + *pResult = 0; +} + +/** +* Starts the stage drag operation. +*/ +void StageView::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult) { + LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + + CListCtrl& list = GetListCtrl(); + + //Start a drag if the item isn't the material + if(pNMLV->iItem > 0) { + + + dragIndex = pNMLV->iItem; + + //Trun off ownerdrawn to create the drag image correctly + list.ModifyStyle(LVS_OWNERDRAWFIXED, 0); + + //Create the drag image + POINT pt; + pt.x = 8; + pt.y = 8; + dragImage = list.CreateDragImage(dragIndex, &pt); + dragImage->BeginDrag(0, CPoint (8, 8)); + dragImage->DragEnter(GetDesktopWindow(), pNMLV->ptAction); + + //Turn the owner draw back on + list.ModifyStyle(0, LVS_OWNERDRAWFIXED); + + //Drag is in progress + bDragging = true; + dropIndex = -1; + dropWnd = &list; + + //Capture the messages + SetCapture(); + } + + *pResult = 0; +} + +/** +* Finishes a stage drag operation of the user was dragging a stage. +*/ +void StageView::OnLButtonUp(UINT nFlags, CPoint point) { + if( bDragging ) { + //Release mouse capture + ReleaseCapture(); + + //Delete the drag image + dragImage->DragLeave(GetDesktopWindow()); + dragImage->EndDrag(); + + //Where did we drop + CPoint pt(point); + ClientToScreen(&pt); + dropWnd = WindowFromPoint(pt); + + if( dropWnd->IsKindOf(RUNTIME_CLASS(StageView)) ) + DropItemOnList(); + + bDragging = false; + } + + ToggleListView::OnLButtonUp(nFlags, point); +} + +/** +* Handles drawing the drag image when a user is draging a stage. +*/ +void StageView::OnMouseMove(UINT nFlags, CPoint point) { + if( bDragging ) { + dropPoint = point; + ClientToScreen(&dropPoint); + + //Move the drag image + dragImage->DragMove(dropPoint); + dragImage->DragShowNolock(FALSE); + + dropWnd = WindowFromPoint(dropPoint); + dropWnd->ScreenToClient(&dropPoint); + + dragImage->DragShowNolock(TRUE); + } + ToggleListView::OnMouseMove(nFlags, point); +} + +/** +* Displays the popup menu when the user performs a right mouse click. +*/ +void StageView::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult) { + if(materialDocManager->GetCurrentMaterialDoc()) { + CListCtrl& list = GetListCtrl(); + + DWORD dwPos = GetMessagePos(); + + CPoint pt( LOWORD( dwPos ), HIWORD ( dwPos ) ); + + CPoint spt = pt; + list.ScreenToClient( &spt ); + + PopupMenu(&spt); + } + *pResult = 0; +} + +/** +* Begins a label edit when the user selects the rename menu option. +*/ +void StageView::OnRenameStage() { + + CListCtrl& list = GetListCtrl(); + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) { + nItem = list.GetNextSelectedItem(pos); + list.EditLabel(nItem); + } +} + +/** +* Deletes the selected stage when the user selects the delete menu option. +*/ +void StageView::OnDeleteStage() { + + CListCtrl& list = GetListCtrl(); + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) { + nItem = list.GetNextSelectedItem(pos); + if(nItem > 0) { + int result = MessageBox("Are you sure you want to delete this stage?", "Delete?", MB_ICONQUESTION | MB_YESNO); + if(result == IDYES) { + + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + material->RemoveStage(nItem-1); + } + } + } +} + +/** +* Conforms the user wants to delete all stages and then performs the operation. +*/ +void StageView::OnDeleteAllStages() { + int result = MessageBox("Are you sure you want to delete all stages?", "Delete?", MB_ICONQUESTION | MB_YESNO); + if(result == IDYES) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + material->ClearStages(); + } +} + +/** +* Adds a new stage when the user selects the menu option. +*/ +void StageView::OnAddStage() { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + + idStr name = va("Stage %d", material->GetStageCount()+1); + material->AddStage(MaterialDoc::STAGE_TYPE_NORMAL, name.c_str()); +} + +/** +* Adds a new bumpmap stage when the user selects the menu option. +*/ +void StageView::OnAddBumpmapStage() { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "bumpmap"); +} + +/** +* Adds a new diffusemap stage when the user selects the menu option. +*/ +void StageView::OnAddDiffuseStage() { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "diffusemap"); +} + +/** +* Adds a new specularmap stage when the user selects the menu option. +*/ +void StageView::OnAddSpecualarStage() { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "specularmap"); +} + +/** +* Performs a copy operation when the user selects the menu option. +*/ +void StageView::OnCopy() { + + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + + CListCtrl& list = GetListCtrl(); + + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) + nItem = list.GetNextSelectedItem(pos); + + if(nItem > 0) { + materialDocManager->CopyStage(material, nItem-1); + } +} + +/** +* Performs a paste operation when the user selects the menu option. +*/ +void StageView::OnPaste() { + if(materialDocManager->IsCopyStage()) { + + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + + int type; + idStr name; + + materialDocManager->GetCopyStageInfo(type, name); + + int existingIndex = material->FindStage(type, name); + + if(type != MaterialDoc::STAGE_TYPE_SPECIALMAP || existingIndex == -1) { + materialDocManager->PasteStage(material); + } else { + if(MessageBox(va("Do you want to replace '%s' stage?", name.c_str()), "Replace?", MB_ICONQUESTION | MB_YESNO) == IDYES) { + material->RemoveStage(existingIndex); + materialDocManager->PasteStage(material); + } + } + } +} + +/** +* Determines is a label edit can be performed on the selected stage. +*/ +void StageView::OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { + NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); + + //if this is a special stage then don't allow edit + int index = pDispInfo->item.iItem; + + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(index <= 0 || material->GetAttributeInt(index-1, "stagetype") != MaterialDoc::STAGE_TYPE_NORMAL) + { + *pResult = 1; + return; + } + + //ToDo: Can we move the edit box + /*HWND edit = ListView_GetEditControl(m_hWnd); + CWnd* editWnd = CWnd::FromHandle(edit); + CRect rect; + editWnd->GetWindowRect(rect); + rect.left += 22; + rect.right += 22; + editWnd->MoveWindow(rect);*/ + + + *pResult = 0; +} + +/** +* Performs the stage name change after the label edit is done. +*/ +void StageView::OnLvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { + NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); + + if(pDispInfo->item.pszText) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + internalChange = true; + material->SetAttribute(pDispInfo->item.iItem-1, "name", pDispInfo->item.pszText); + internalChange = false; + *pResult = 1; + } else { + *pResult = 0; + } +} + +/** +* Handles keyboard shortcuts for copy and paste operations. +*/ +void StageView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { + if(nChar == 3 && GetKeyState(VK_CONTROL)) { + OnCopy(); + } + + if(nChar == 22 && GetKeyState(VK_CONTROL)) { + OnPaste(); + } + + + ToggleListView::OnChar(nChar, nRepCnt, nFlags); +} + +/** +* Handles keyboard shortcut for the delete operations. +*/ +BOOL StageView::PreTranslateMessage(MSG* pMsg) { + + CListCtrl& list = GetListCtrl(); + if (pMsg->hwnd == list.GetSafeHwnd()) { + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE) { + OnDeleteStage(); + return TRUE; + } + } + return FALSE; +} + +/** +* Sets window styles before the window is created. +*/ +BOOL StageView::PreCreateWindow(CREATESTRUCT& cs) { + cs.style &= ~LVS_TYPEMASK; + cs.style |= LVS_SINGLESEL | LVS_EDITLABELS; + + return ToggleListView::PreCreateWindow(cs); +} + +/** +* Called by the ToggleListView when the toggle state has changed. +*/ +void StageView::OnStateChanged(int index, int toggleState) { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(material && index > 0) { + if (toggleState == ToggleListView::TOGGLE_STATE_ON) { + material->EnableStage(index-1, true); + } else if (toggleState == ToggleListView::TOGGLE_STATE_OFF) { + material->EnableStage(index-1, false); + } + } +} + +/** +* Dispalys the popup menu with the appropriate menu items enabled. +*/ +void StageView::PopupMenu(CPoint* pt) { + + //Determine the type of object clicked on + CListCtrl& list = GetListCtrl(); + + + ClientToScreen (pt); + + CMenu FloatingMenu; + VERIFY(FloatingMenu.LoadMenu(IDR_ME_STAGELIST_POPUP)); + CMenu* pPopupMenu = FloatingMenu.GetSubMenu (0); + ASSERT(pPopupMenu != NULL); + + POSITION pos = list.GetFirstSelectedItemPosition(); + int nItem = -1; + if(pos) + nItem = list.GetNextSelectedItem(pos); + + if(nItem <= 0) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_RENAMESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_DELETESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(material->GetAttributeInt(nItem-1, "stagetype") != MaterialDoc::STAGE_TYPE_NORMAL) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_RENAMESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + } + + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "bumpmap") >= 0) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDBUMPMAP, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "diffusemap") >= 0) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDDIFFUSEMAP, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "specularmap") >= 0) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDSPECULAR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + if(materialDocManager->IsCopyStage()) { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_PASTE, MF_BYCOMMAND | MF_ENABLED); + } else { + pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_PASTE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } + + pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt->x, pt->y, &list); +} + +/** +* Performs the stage move when the user has dragged and dropped a stage. +*/ +void StageView::DropItemOnList() { + CListCtrl& list = GetListCtrl(); + + int toStage; + + //Get and adjust the drop index based on the direction of the move + dropIndex = list.HitTest(dropPoint); + if(dropIndex < 0) dropIndex = list.GetItemCount()-1; + + //Ignore the drop if the index is the same or they are droping on the material + if(dropIndex == dragIndex || dropIndex == 0) + return; + + //Move the stage data + MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc(); + + internalChange = true; + toStage = dropIndex-1; + material->MoveStage(dragIndex-1, dropIndex-1); + internalChange = false; + + if(dragIndex < dropIndex) { + dropIndex++; + } + + //Get the item + char szLabel[256]; + LV_ITEM lvi; + ZeroMemory(&lvi, sizeof(LV_ITEM)); + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM; + lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED; + lvi.pszText = szLabel; + lvi.iItem = dragIndex; + lvi.cchTextMax = 255; + list.GetItem(&lvi); + + //Insert the item + lvi.iItem = dropIndex; + list.InsertItem(&lvi); + + //Adjust the drag index if the move was up in the list + if(dragIndex > dropIndex) { + dragIndex++; + } + + //Delete the original item + list.DeleteItem(dragIndex); + + int type = -1; + int stageType = currentMaterial->GetAttributeInt(toStage, "stagetype"); + switch(stageType) { + case MaterialDoc::STAGE_TYPE_NORMAL: + type = MaterialDefManager::MATERIAL_DEF_STAGE; + break; + case MaterialDoc::STAGE_TYPE_SPECIALMAP: + type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE; + break; + } + m_propView->SetPropertyListType(type, toStage); +} + + + + diff --git a/tools/materialeditor/StageView.h b/tools/materialeditor/StageView.h new file mode 100644 index 000000000..1faf13def --- /dev/null +++ b/tools/materialeditor/StageView.h @@ -0,0 +1,123 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include +#include + +#include "MaterialEditor.h" +#include "ToggleListView.h" +#include "MaterialView.h" +#include "MaterialPropTreeView.h" + +/** +* View that handles managing the material stages. +*/ +class StageView : public ToggleListView, public MaterialView +{ + +public: + virtual ~StageView(); + + /** + * Defines the type of stages + */ + enum { + STAGE_TYPE_MATERIAL, + STAGE_TYPE_STAGE, + STAGE_TYPE_SPECIAL_MAP_STAGE + }; + + //Associates a property view with this stage view + void SetMaterialPropertyView(MaterialPropTreeView* propView) { m_propView = propView; }; + + //MaterialView Interface + virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial); + virtual void MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum); + virtual void MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum); + virtual void MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to); + virtual void MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName); + virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial); + + //Edit Operation Tests + bool CanCopy(); + bool CanPaste(); + bool CanCut(); + bool CanDelete(); + bool CanRename(); + + //Refresh the stage list + void RefreshStageList(); + +protected: + StageView(); + DECLARE_DYNCREATE(StageView) + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult); + + afx_msg void OnRenameStage(); + afx_msg void OnDeleteStage(); + afx_msg void OnDeleteAllStages(); + afx_msg void OnAddStage(); + afx_msg void OnAddBumpmapStage(); + afx_msg void OnAddDiffuseStage(); + afx_msg void OnAddSpecualarStage(); + + afx_msg void OnCopy(); + afx_msg void OnPaste(); + + afx_msg void OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + DECLARE_MESSAGE_MAP() + + //Overrides + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + + //Toggle List View Interface + virtual void OnStateChanged(int index, int toggleState); + + void PopupMenu(CPoint* pt); + + void DropItemOnList(); + +protected: + + MaterialPropTreeView* m_propView; + MaterialDoc* currentMaterial; + + //Manual handing of the row dragging + CImageList* dragImage; + bool bDragging; + int dragIndex; + int dropIndex; + CWnd* dropWnd; + CPoint dropPoint; + + bool internalChange; +}; + + diff --git a/tools/materialeditor/ToggleListView.cpp b/tools/materialeditor/ToggleListView.cpp new file mode 100644 index 000000000..f9aa93432 --- /dev/null +++ b/tools/materialeditor/ToggleListView.cpp @@ -0,0 +1,297 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "ToggleListView.h" + +#define TOGGLELIST_ITEMHEIGHT 22 +#define TEXT_OFFSET 6 + + +IMPLEMENT_DYNCREATE(ToggleListView, CListView) + +BEGIN_MESSAGE_MAP(ToggleListView, CListView) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_MEASUREITEM_REFLECT() + ON_NOTIFY_REFLECT(NM_CLICK, OnNMClick) +END_MESSAGE_MAP() + + +/** +* Protected constructor used by dynamic creation. +*/ +ToggleListView::ToggleListView() { + onIcon = NULL; + offIcon = NULL; + disabledIcon = NULL; +} + +/** +* Destructor. +*/ +ToggleListView::~ToggleListView() { +} + + +/** +* Sets the tree icons to dispay for each of the three states. Sets the +* icons to display for each of the three states. The values passed in +* are the resource name that can be generated using MAKEINTRESOUCE. If +* the value passed in is NULL then an icon will not be drawn for that +* state. +* @param disabled The icon to draw when the state is TOGGLE_STATE_DISABLED. +* @param on The icon to draw when the state is TOGGLE_STATE_ON. +* @param off The icon to draw when the state is TOGGLE_STATE_OFF. +*/ +void ToggleListView::SetToggleIcons(LPCSTR disabled, LPCSTR on, LPCSTR off) { + if(on) { + onIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), on, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + } else { + onIcon = NULL; + } + + if(off) { + offIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), off, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + } else { + offIcon = NULL; + } + + if(disabled) { + disabledIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), disabled, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS ); + } else { + disabledIcon = NULL; + } +} + +/** +* Sets the state of an item in the list. +* @param index Index of the item whose state should be changed. +* @param toggleState The state to set +* @param notify Determines if the notification method OnStateChanged should +* be called. OnStateChanged will also not be called if the state has not changed. +*/ +void ToggleListView::SetToggleState(int index, int toggleState, bool notify) { + CListCtrl& list = GetListCtrl(); + assert(index >= 0 && index < list.GetItemCount()); + + int oldState = GetToggleState(index); + list.SetItemData(index, toggleState); + + if(notify && oldState != toggleState) + OnStateChanged(index, toggleState); +} + +/** +* Gets the state of an item in the list +* @param index Index of the item of which to retreive the state. +*/ +int ToggleListView::GetToggleState(int index) { + CListCtrl& list = GetListCtrl(); + assert(index >= 0 && index < list.GetItemCount()); + + DWORD data = list.GetItemData(index); + return data; +} + +/** +* Called as the window is being created and initializes icons and window styles +*/ +int ToggleListView::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CListView::OnCreate(lpCreateStruct) == -1) + return -1; + + CListCtrl& list = GetListCtrl(); + + list.SetExtendedStyle(LVS_EX_FULLROWSELECT); + + //Turn off the horizontal scroll bar + //Todo: Figure out why the damn scroll bar pops up + list.ModifyStyle(WS_HSCROLL, 0L); + + + //Insert the one column + LVCOLUMN col; + col.mask = 0; + list.InsertColumn(0, &col); + + SetToggleIcons(); + + return 0; +} + +/** +* Called when the window is being resized. +*/ +void ToggleListView::OnSize(UINT nType, int cx, int cy) { + CListView::OnSize(nType, cx, cy); + + CListCtrl& list = GetListCtrl(); + list.SetColumnWidth(0, cx-1); +} + +/** +* Returns the size of each item in the toggle list. +*/ +void ToggleListView::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { + lpMeasureItemStruct->itemHeight = TOGGLELIST_ITEMHEIGHT; +} + +/** +* Toggles the state of an item when the user clicks in the window. +*/ +void ToggleListView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) { + CListCtrl& list = GetListCtrl(); + + DWORD dwpos = GetMessagePos(); + + LVHITTESTINFO info; + info.pt.x = LOWORD(dwpos); + info.pt.y = HIWORD(dwpos); + + ::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &info.pt, 1); + + int index = list.HitTest(&info); + if ( index != -1 ) { + int toggleState = GetToggleState(index); + if(toggleState != TOGGLE_STATE_DISABLED) { + + RECT rItem; + list.GetItemRect(index, &rItem, LVIR_BOUNDS); + + if ( info.pt.x < TOGGLELIST_ITEMHEIGHT ) { + if(toggleState == TOGGLE_STATE_ON) { + SetToggleState(index, TOGGLE_STATE_OFF, true); + } else { + SetToggleState(index, TOGGLE_STATE_ON, true); + } + } + } + } + *pResult = 0; +} + +/** +* Sets some window styles before the window is created. +*/ +BOOL ToggleListView::PreCreateWindow(CREATESTRUCT& cs) { + //Set the required style for the toggle view + cs.style &= ~LVS_TYPEMASK; + cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS; + + return CListView::PreCreateWindow(cs); +} + +/** +* Responsible for drawing each list item. +*/ +void ToggleListView::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { + + CListCtrl& ListCtrl=GetListCtrl(); + int nItem = lpDrawItemStruct->itemID; + + // get item data + LV_ITEM lvi; + _TCHAR szBuff[MAX_PATH]; + + memset(&lvi, 0, sizeof(LV_ITEM)); + lvi.mask = LVIF_TEXT; + lvi.iItem = nItem; + lvi.pszText = szBuff; + lvi.cchTextMax = sizeof(szBuff); + ListCtrl.GetItem(&lvi); + + RECT rDraw; + + + CopyRect ( &rDraw, &lpDrawItemStruct->rcItem ); + rDraw.right = rDraw.left + TOGGLELIST_ITEMHEIGHT; + rDraw.top ++; + + rDraw.right ++; + FrameRect ( lpDrawItemStruct->hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) ); + rDraw.right --; + + FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DFACE ) ); + + Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DHILIGHT ), GetSysColorBrush ( COLOR_3DSHADOW ) ); + + InflateRect ( &rDraw, -3, -3 ); + Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DSHADOW ), GetSysColorBrush ( COLOR_3DHILIGHT ) ); + + switch(GetToggleState(lvi.iItem)) { + case TOGGLE_STATE_DISABLED: + if(disabledIcon) { + DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, disabledIcon, 16, 16,0, NULL, DI_NORMAL ); + } + break; + case TOGGLE_STATE_ON: + if(onIcon) { + DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, onIcon, 16, 16,0, NULL, DI_NORMAL ); + } + break; + case TOGGLE_STATE_OFF: + if(offIcon) { + DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, offIcon, 16, 16,0, NULL, DI_NORMAL ); + } + break; + }; + + CopyRect ( &rDraw, &lpDrawItemStruct->rcItem ); + rDraw.left += TOGGLELIST_ITEMHEIGHT; + rDraw.left += 1; + + if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { + FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_HIGHLIGHT ) ); + } else { + FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_WINDOW ) ); + } + + rDraw.left += TEXT_OFFSET; + + int colorIndex = ( (lpDrawItemStruct->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT ); + SetTextColor ( lpDrawItemStruct->hDC, GetSysColor ( colorIndex ) ); + DrawText ( lpDrawItemStruct->hDC, szBuff, strlen(szBuff), &rDraw, DT_LEFT|DT_VCENTER|DT_SINGLELINE ); + +} + + +/** +* Draws a 3d rectangle using the given brushes this code was taken from the gui editor +*/ +void ToggleListView::Draw3dRect (HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight) { + RECT rOut; + + SetRect ( &rOut, rect->left, rect->top, rect->right - 1, rect->top + 1 ); + FillRect ( hDC,&rOut, topLeft ); + + SetRect ( &rOut, rect->left, rect->top, rect->left + 1, rect->bottom ); + FillRect( hDC,&rOut, topLeft ); + + SetRect ( &rOut, rect->right, rect->top, rect->right -1, rect->bottom ); + FillRect( hDC,&rOut, bottomRight ); + + SetRect ( &rOut, rect->left, rect->bottom, rect->right, rect->bottom - 1 ); + FillRect( hDC,&rOut, bottomRight ); +} + + + + diff --git a/tools/materialeditor/ToggleListView.h b/tools/materialeditor/ToggleListView.h new file mode 100644 index 000000000..2ff07aa5c --- /dev/null +++ b/tools/materialeditor/ToggleListView.h @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include + +/** +* A simple list view that supports a toggle button. ToggleListView is a simple extension +* to the CListView class that support a toggle button. It is limited to a single column +* and always uses full row select. The toggle state is stored in the data for each item +* so users of this class should not attempt to use the data field for storage. lparam can +* be used instead. +*/ +class ToggleListView : public CListView { + +public: + /** + * Enumeration that defines the possible states of the toggle button. + */ + enum { + TOGGLE_STATE_DISABLED = 0, + TOGGLE_STATE_ON, + TOGGLE_STATE_OFF + }; + +public: + void SetToggleIcons(LPCSTR disabled = NULL, LPCSTR on = NULL, LPCSTR off = NULL); + void SetToggleState(int index, int toggleState, bool notify = false); + int GetToggleState(int index); + + //Windows messages + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct); + afx_msg void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult); + + DECLARE_MESSAGE_MAP() + + +protected: + ToggleListView(); + virtual ~ToggleListView(); + + DECLARE_DYNCREATE(ToggleListView) + + //Overrides + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + + //Virtual Event Methods for sub-classes + virtual void OnStateChanged(int index, int toggleState) {}; + + void Draw3dRect(HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight); + +protected: + HICON onIcon; + HICON offIcon; + HICON disabledIcon; + +}; + + diff --git a/tools/particle/DialogParticleEditor.cpp b/tools/particle/DialogParticleEditor.cpp new file mode 100644 index 000000000..b9c26c92f --- /dev/null +++ b/tools/particle/DialogParticleEditor.cpp @@ -0,0 +1,1486 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../game/game.h" +#include "../../sys/win32/win_local.h" +#include "../../sys/win32/rc/common_resource.h" +#include "../../sys/win32/rc/Radiant_resource.h" +#include "../../sys/win32/rc/ParticleEditor_resource.h" +#include "../comafx/DialogName.h" +#include "../comafx/VectorCtl.h" +#include "../comafx/DialogColorPicker.h" +#include "../radiant/GLWidget.h" +#include "../radiant/PreviewDlg.h" + +#include "DialogParticleEditor.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +const int StageEnableID[] = { + IDC_EDIT_MATERIAL, + IDC_BUTTON_BROWSEMATERIAL, + IDC_EDIT_ANIMFRAMES, + IDC_EDIT_ANIMRATE, + IDC_EDIT_COLOR, + IDC_BUTTON_BROWSECOLOR, + IDC_EDIT_FADECOLOR, + IDC_BUTTON_BROWSEFADECOLOR, + IDC_EDIT_FADEIN, + IDC_SLIDER_FADEIN, + IDC_EDIT_FADEOUT, + IDC_EDIT_FADEFRACTION, + IDC_SLIDER_FADEOUT, + IDC_SLIDER_FADEFRACTION, + IDC_EDIT_BUNCHING, + IDC_SLIDER_BUNCHING, + IDC_EDIT_COUNT, + IDC_SLIDER_COUNT, + IDC_EDIT_TIME, + IDC_SLIDER_TIME, + IDC_EDIT_CYCLES, + IDC_EDIT_TIMEOFFSET, + IDC_EDIT_DEADTIME, + IDC_CHECK_WORLDGRAVITY, + IDC_EDIT_GRAVITY, + IDC_SLIDER_GRAVITY, + IDC_RADIO_RECT, + IDC_RADIO_CYLINDER, + IDC_RADIO_SPHERE, + IDC_EDIT_OFFSET, + IDC_EDIT_XSIZE, + IDC_EDIT_YSIZE, + IDC_EDIT_ZSIZE, + IDC_EDIT_RINGOFFSET, + IDC_RADIO_CONE, + IDC_RADIO_OUTWARD, + IDC_EDIT_DIRECTIONPARM, + IDC_RADIO_AIMED, + IDC_RADIO_VIEW, + IDC_RADIO_X, + IDC_RADIO_Y, + IDC_RADIO_Z, + IDC_EDIT_ORIENTATIONPARM1, + IDC_EDIT_ORIENTATIONPARM2, + IDC_SLIDER_SPEEDFROM, + IDC_EDIT_SPEEDFROM, + IDC_EDIT_SPEEDTO, + IDC_SLIDER_SPEEDTO, + IDC_SLIDER_ROTATIONFROM, + IDC_EDIT_ROTATIONFROM, + IDC_EDIT_ROTATIONTO, + IDC_SLIDER_ROTATIONTO, + IDC_SLIDER_SIZEFROM, + IDC_EDIT_SIZEFROM, + IDC_EDIT_SIZETO, + IDC_SLIDER_SIZETO, + IDC_SLIDER_ASPECTFROM, + IDC_EDIT_ASPECTFROM, + IDC_EDIT_ASPECTTO, + IDC_SLIDER_ASPECTTO, + IDC_COMBO_CUSTOMPATH, + IDC_CHECK_ENTITYCOLOR, +}; + +const int StageIDCount = sizeof( StageEnableID ) / sizeof ( const int ); + +const int EditEnableID[] = { + IDC_BUTTON_XDN, + IDC_BUTTON_XUP, + IDC_BUTTON_YUP, + IDC_BUTTON_YDN, + IDC_BUTTON_ZUP, + IDC_BUTTON_ZDN, + IDC_BUTTON_DROPEMITTER, + IDC_BUTTON_VECTOR, + IDC_BUTTON_BROWSECOLOR_ENTITY +}; + +const int EditIDCount = sizeof ( EditEnableID ) / sizeof ( const int ); + + +CDialogParticleEditor *g_ParticleDialog = NULL; + + +/* +================ +ParticleEditorInit +================ +*/ +void ParticleEditorInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the particle editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_ParticleDialog == NULL ) { + InitAfx(); + g_ParticleDialog = new CDialogParticleEditor(); + } + + if ( g_ParticleDialog->GetSafeHwnd() == NULL) { + g_ParticleDialog->Create( IDD_DIALOG_PARTICLE_EDITOR ); + /* + // FIXME: restore position + CRect rct; + g_AFDialog->SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE ); + */ + } + + idKeyInput::ClearStates(); + + g_ParticleDialog->ShowWindow( SW_SHOW ); + g_ParticleDialog->SetFocus(); + + if ( spawnArgs ) { + idStr str = spawnArgs->GetString( "model" ); + str.StripFileExtension(); + g_ParticleDialog->SelectParticle( str ); + g_ParticleDialog->SetParticleVisualization( static_cast( CDialogParticleEditor::SELECTED ) ); + } + + cvarSystem->SetCVarBool( "r_useCachedDynamicModels", false ); +} + + +/* +================ +ParticleEditorRun +================ +*/ +void ParticleEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +/* +================ +ParticleEditorShutdown +================ +*/ +void ParticleEditorShutdown( void ) { + delete g_ParticleDialog; + g_ParticleDialog = NULL; +} + + +// CDialogParticleEditor dialog + +IMPLEMENT_DYNAMIC(CDialogParticleEditor, CDialog) +CDialogParticleEditor::CDialogParticleEditor(CWnd* pParent /*=NULL*/) + : CDialog(CDialogParticleEditor::IDD, pParent) + , matName(_T("")) + , animFrames(_T("")) + , animRate(_T("")) + , color(_T("")) + , fadeColor(_T("")) + , fadeIn(_T("")) + , fadeOut(_T("")) + , fadeFraction(_T("")) + , count(_T("")) + , time(_T("")) + , timeOffset(_T("")) + , deadTime(_T("")) + , gravity(_T("")) + , bunching(_T("")) + , offset(_T("")) + , xSize(_T("")) + , ySize(_T("")) + , zSize(_T("")) + , ringOffset(_T("")) + , directionParm(_T("")) + , direction(0) + , orientation(0) + , distribution(0) + , viewOrigin(_T("")) + , speedFrom(_T("")) + , speedTo(_T("")) + , rotationFrom(_T("")) + , rotationTo(_T("")) + , sizeFrom(_T("")) + , sizeTo(_T("")) + , aspectFrom(_T("")) + , aspectTo(_T("")) + , customPath(_T("")) + , customParms(_T("")) + , trails(_T("")) + , trailTime(_T("")) + , worldGravity(TRUE) + , entityColor(TRUE) + , randomDistribution(TRUE) + , initialAngle(_T("")) + , boundsExpansion(_T("")) + , customDesc(_T("")) + , particleMode(FALSE) +{ + visualization = TESTMODEL; + mapModified = false; +} + +CDialogParticleEditor::~CDialogParticleEditor() { +} + +void CDialogParticleEditor::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_EDIT_DEPTHHACK, depthHack); + DDX_Check(pDX, IDC_CHECK_WORLDGRAVITY, worldGravity); + DDX_Check(pDX, IDC_CHECK_ENTITYCOLOR, entityColor); + DDX_Control(pDX, IDC_COMBO_PARTICLES, comboParticle); + DDX_Control(pDX, IDC_LIST_STAGES, listStages); + DDX_Text(pDX, IDC_COMBO_CUSTOMPATH, customPath ); + DDX_Text(pDX, IDC_EDIT_CUSTOMPARMS, customParms ); + DDX_Text(pDX, IDC_EDIT_MATERIAL, matName); + DDX_Text(pDX, IDC_EDIT_ANIMFRAMES, animFrames); + DDX_Text(pDX, IDC_EDIT_ANIMRATE, animRate); + DDX_Text(pDX, IDC_EDIT_COLOR, color); + DDX_Text(pDX, IDC_EDIT_FADECOLOR, fadeColor); + DDX_Text(pDX, IDC_EDIT_FADEIN, fadeIn); + DDX_Text(pDX, IDC_EDIT_FADEOUT, fadeOut); + DDX_Text(pDX, IDC_EDIT_FADEFRACTION, fadeFraction); + DDX_Text(pDX, IDC_EDIT_COUNT, count); + DDX_Text(pDX, IDC_EDIT_TIME, time); + DDX_Text(pDX, IDC_EDIT_TIMEOFFSET, timeOffset); + DDX_Text(pDX, IDC_EDIT_DEADTIME, deadTime); + DDX_Text(pDX, IDC_EDIT_GRAVITY, gravity); + DDX_Text(pDX, IDC_EDIT_BUNCHING, bunching); + DDX_Text(pDX, IDC_EDIT_OFFSET, offset); + DDX_Text(pDX, IDC_EDIT_XSIZE, xSize); + DDX_Text(pDX, IDC_EDIT_YSIZE, ySize); + DDX_Text(pDX, IDC_EDIT_ZSIZE, zSize); + DDX_Text(pDX, IDC_EDIT_RINGOFFSET, ringOffset); + DDX_Text(pDX, IDC_EDIT_CYCLES, cycles); + DDX_Control(pDX, IDC_STATIC_DIRPARM, staticDirectionParm); + DDX_Text(pDX, IDC_EDIT_DIRECTIONPARM, directionParm); + DDX_Text(pDX, IDC_EDIT_SPEEDFROM, speedFrom); + DDX_Text(pDX, IDC_EDIT_SPEEDTO, speedTo); + DDX_Text(pDX, IDC_EDIT_ROTATIONFROM, rotationFrom); + DDX_Text(pDX, IDC_EDIT_ROTATIONTO, rotationTo); + DDX_Text(pDX, IDC_EDIT_SIZEFROM, sizeFrom); + DDX_Text(pDX, IDC_EDIT_SIZETO, sizeTo); + DDX_Text(pDX, IDC_EDIT_ASPECTFROM, aspectFrom); + DDX_Text(pDX, IDC_EDIT_ASPECTTO, aspectTo); + DDX_Text(pDX, IDC_EDIT_ORIENTATIONPARM1, trails); + DDX_Text(pDX, IDC_EDIT_ORIENTATIONPARM2, trailTime); + DDX_Check(pDX, IDC_CHECK_RANDOMDISTRIBUTION, randomDistribution); + DDX_Text(pDX, IDC_EDIT_INITIALANGLE, initialAngle); + DDX_Text(pDX, IDC_EDIT_BOUNDSEXPANSION, boundsExpansion); + DDX_Text(pDX, IDC_STATIC_DESC, customDesc); + DDX_Control(pDX, IDC_EDIT_RINGOFFSET, editRingOffset); + DDX_Radio(pDX, IDC_RADIO_RECT, distribution); + DDX_Radio(pDX, IDC_RADIO_CONE, direction); + DDX_Radio(pDX, IDC_RADIO_VIEW, orientation); + DDX_Control(pDX, IDC_SLIDER_BUNCHING, sliderBunching); + DDX_Control(pDX, IDC_SLIDER_FADEIN, sliderFadeIn); + DDX_Control(pDX, IDC_SLIDER_FADEOUT, sliderFadeOut); + DDX_Control(pDX, IDC_SLIDER_FADEFRACTION, sliderFadeFraction); + DDX_Control(pDX, IDC_SLIDER_COUNT, sliderCount); + DDX_Control(pDX, IDC_SLIDER_TIME, sliderTime); + DDX_Control(pDX, IDC_SLIDER_GRAVITY, sliderGravity); + DDX_Control(pDX, IDC_SLIDER_SPEEDFROM, sliderSpeedFrom); + DDX_Control(pDX, IDC_SLIDER_SPEEDTO, sliderSpeedTo); + DDX_Control(pDX, IDC_SLIDER_ROTATIONFROM, sliderRotationFrom); + DDX_Control(pDX, IDC_SLIDER_ROTATIONTO, sliderRotationTo); + DDX_Control(pDX, IDC_SLIDER_SIZEFROM, sliderSizeFrom); + DDX_Control(pDX, IDC_SLIDER_SIZETO, sliderSizeTo); + DDX_Control(pDX, IDC_SLIDER_ASPECTFROM, sliderAspectFrom); + DDX_Control(pDX, IDC_SLIDER_ASPECTTO, sliderAspectTo); + DDX_Control(pDX, IDC_BUTTON_VECTOR, vectorControl); +} + + +BEGIN_MESSAGE_MAP(CDialogParticleEditor, CDialog) + ON_BN_CLICKED(IDC_BUTTON_ADDSTAGE, OnBnClickedButtonAddstage) + ON_BN_CLICKED(IDC_BUTTON_REMOVESTAGE, OnBnClickedButtonRemovestage) + ON_BN_CLICKED(IDC_BUTTON_BROWSEMATERIAL, OnBnClickedButtonBrowsematerial) + ON_BN_CLICKED(IDC_BUTTON_BROWSECOLOR, OnBnClickedButtonBrowsecolor) + ON_BN_CLICKED(IDC_BUTTON_BROWSEFADECOLOR, OnBnClickedButtonBrowsefadecolor) + ON_BN_CLICKED(IDC_BUTTON_BROWSECOLOR_ENTITY, OnBnClickedButtonBrowseEntitycolor) + ON_BN_CLICKED(IDC_BUTTON_UPDATE, OnBnClickedButtonUpdate) + ON_CBN_SELCHANGE(IDC_COMBO_PARTICLES, OnCbnSelchangeComboParticles) + ON_CBN_SELCHANGE(IDC_COMBO_CUSTOMPATH, OnCbnSelchangeComboPath) + ON_BN_CLICKED(IDC_RADIO_RECT, OnBnClickedRadioRect) + ON_BN_CLICKED(IDC_RADIO_SPHERE, OnBnClickedRadioSphere) + ON_BN_CLICKED(IDC_RADIO_CYLINDER, OnBnClickedRadioCylinder) + ON_BN_CLICKED(IDC_RADIO_CONE, OnBnClickedRadioCone) + ON_BN_CLICKED(IDC_RADIO_OUTWARD, OnBnClickedRadioOutward) + ON_BN_CLICKED(IDC_RADIO_VIEW, OnBnClickedRadioView) + ON_BN_CLICKED(IDC_RADIO_AIMED, OnBnClickedRadioAimed) + ON_BN_CLICKED(IDC_RADIO_X, OnBnClickedRadioX) + ON_BN_CLICKED(IDC_RADIO_Y, OnBnClickedRadioY) + ON_BN_CLICKED(IDC_RADIO_Z, OnBnClickedRadioZ) + ON_BN_CLICKED(IDC_BUTTON_HIDESTAGE, OnBnClickedButtonHidestage) + ON_BN_CLICKED(IDC_BUTTON_SHOWSTAGE, OnBnClickedButtonShowstage) + ON_BN_CLICKED(IDC_CHECK_WORLDGRAVITY, OnBnClickedWorldGravity) + ON_BN_CLICKED(IDC_CHECK_ENTITYCOLOR, OnBnClickedEntityColor) + ON_LBN_SELCHANGE(IDC_LIST_STAGES, OnLbnSelchangeListStages) + ON_BN_CLICKED(IDC_BUTTON_NEW, OnBnClickedButtonNew) + ON_BN_CLICKED(IDC_BUTTON_SAVE_PARTICLE, OnBnClickedButtonSave) + ON_BN_CLICKED(IDC_BUTTON_SAVE_PARTICLE_AS, OnBnClickedButtonSaveAs) + ON_BN_CLICKED(IDC_BUTTON_SAVE_PARTICLEENTITIES, OnBnClickedButtonSaveParticles) + ON_BN_CLICKED(IDC_BUTTON_TESTMODEL, OnBnClickedTestModel) + ON_BN_CLICKED(IDC_BUTTON_IMPACT, OnBnClickedImpact) + ON_BN_CLICKED(IDC_BUTTON_MUZZLE, OnBnClickedMuzzle) + ON_BN_CLICKED(IDC_BUTTON_FLIGHT, OnBnClickedFlight) + ON_BN_CLICKED(IDC_BUTTON_SELECTED, OnBnClickedSelected) + ON_BN_CLICKED(IDC_BUTTON_DOOM, OnBnClickedDoom) + ON_BN_CLICKED(IDC_CHECK_EDITPARTICLEMODE, OnBnClickedParticleMode) + ON_BN_CLICKED(IDC_BUTTON_DROPEMITTER, OnBtnDrop) + ON_BN_CLICKED(IDC_BUTTON_YUP, OnBtnYup) + ON_BN_CLICKED(IDC_BUTTON_YDN, OnBtnYdn) + ON_BN_CLICKED(IDC_BUTTON_XDN, OnBtnXdn) + ON_BN_CLICKED(IDC_BUTTON_XUP, OnBtnXup) + ON_BN_CLICKED(IDC_BUTTON_ZUP, OnBtnZup) + ON_BN_CLICKED(IDC_BUTTON_ZDN, OnBtnZdn) + ON_WM_HSCROLL() +END_MESSAGE_MAP() + + +// CDialogParticleEditor message handlers + +void CDialogParticleEditor::OnBnClickedParticleMode() { + particleMode = !particleMode; + cvarSystem->SetCVarInteger( "g_editEntityMode", ( particleMode ) ? 4 : 0 ); + EnableEditControls(); +} + + +void CDialogParticleEditor::OnBnClickedButtonSaveAs() { + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + DialogName dlg("New Particle"); + if (dlg.DoModal() == IDOK) { + if ( declManager->FindType( DECL_PARTICLE, dlg.m_strName, false ) ) { + MessageBox( "Particle already exists!", "Particle exists", MB_OK ); + return; + } + CFileDialog dlgSave( TRUE, "prt", NULL, OFN_CREATEPROMPT, "Particle Files (*.prt)|*.prt||All Files (*.*)|*.*||", AfxGetMainWnd() ); + if ( dlgSave.DoModal() == IDOK ) { + idStr fileName; + fileName = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile ); + idDeclParticle *decl = dynamic_cast( declManager->CreateNewDecl( DECL_PARTICLE, dlg.m_strName, fileName ) ); + if ( decl ) { + decl->stages.DeleteContents( true ); + decl->depthHack = idp->depthHack; + for ( int i = 0; i < idp->stages.Num(); i++ ) { + idParticleStage *stage = new idParticleStage(); + *stage = *idp->stages[i]; + decl->stages.Append( stage ); + } + EnumParticles(); + int index = comboParticle.FindStringExact( -1, dlg.m_strName ); + if ( index >= 0 ) { + comboParticle.SetCurSel( index ); + } + OnBnClickedButtonSave(); + OnCbnSelchangeComboParticles(); + OnBnClickedButtonUpdate(); + } + } + } +} + + +void CDialogParticleEditor::OnBnClickedButtonSaveParticles() { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "saveParticles" ); + CWnd *wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( FALSE ); + } +} + +void CDialogParticleEditor::OnBnClickedButtonAddstage() { + AddStage(); +} + +void CDialogParticleEditor::OnBnClickedButtonRemovestage() { + RemoveStage(); +} + +void CDialogParticleEditor::OnBnClickedButtonBrowsematerial() { + CPreviewDlg matDlg( this ); + matDlg.SetMode(CPreviewDlg::MATERIALS, "particles" ); + matDlg.SetDisablePreview( true ); + if ( matDlg.DoModal() == IDOK ) { + matName = matDlg.mediaName; + DlgVarsToCurStage(); + CurStageToDlgVars(); + } +} + +void CDialogParticleEditor::OnBnClickedButtonBrowsecolor() { + int r, g, b; + float ob; + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + r = ps->color.x * 255.0f; + g = ps->color.y * 255.0f; + b = ps->color.z * 255.0f; + ob = 1.0f; + if ( DoNewColor( &r, &g, &b, &ob ) ) { + color.Format( "%f %f %f %f", (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0f ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } +} + +void CDialogParticleEditor::OnBnClickedButtonBrowseEntitycolor() { + int r, g, b; + float ob; + idList list; + idDict dict2; + idStr str; + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[0] ); + if ( dict ) { + idVec3 clr = dict->GetVector( "_color", "1 1 1" ); + r = clr.x * 255.0f; + g = clr.y * 255.0f; + b = clr.z * 255.0f; + ob = 1.0f; + if ( DoNewColor( &r, &g, &b, &ob ) ) { + for ( int i = 0; i < count; i++ ) { + dict = gameEdit->EntityGetSpawnArgs( list[i] ); + const char *name = dict->GetString( "name" ); + idEntity *ent = gameEdit->FindEntity( name ); + if ( ent ) { + gameEdit->EntitySetColor( ent, idVec3( (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f ) ); + str = va( "%f %f %f", (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f ); + dict2.Clear(); + dict2.Set( "_color", str ); + gameEdit->EntityChangeSpawnArgs( ent, &dict2 ); + gameEdit->MapSetEntityKeyVal( name, "_color", str ); + } + } + } + } + CWnd *wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( TRUE ); + } + } + +} + +void CDialogParticleEditor::OnBnClickedButtonBrowsefadecolor() { + int r, g, b; + float ob; + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + r = ps->fadeColor.x * 255.0f; + g = ps->fadeColor.y * 255.0f; + b = ps->fadeColor.z * 255.0f; + ob = 1.0f; + if ( DoNewColor( &r, &g, &b, &ob ) ) { + fadeColor.Format( "%f %f %f %f", (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0f ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } +} + +void CDialogParticleEditor::OnBnClickedButtonUpdate() { + UpdateData( TRUE ); + DlgVarsToCurStage(); + CurStageToDlgVars(); +} + +void CDialogParticleEditor::SelectParticle( const char *name ) { + int index = comboParticle.FindString( 0, name ); + if ( index >= 0 ) { + comboParticle.SetCurSel( index ); + UpdateParticleData(); + } +} + +idDeclParticle *CDialogParticleEditor::GetCurParticle() { + int sel = comboParticle.GetCurSel(); + if ( sel == CB_ERR ) { + return NULL; + } + int index = comboParticle.GetItemData( sel ); + return static_cast( const_cast( declManager->DeclByIndex( DECL_PARTICLE, index ) ) ); +} + +void CDialogParticleEditor::UpdateParticleData() { + + listStages.ResetContent(); + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + for ( int i = 0; i < idp->stages.Num(); i++ ) { + int index = listStages.AddString( va( "stage %i", i ) ); + if ( index >= 0 ) { + listStages.SetItemData( index, i ); + } + } + listStages.SetCurSel( 0 ); + OnLbnSelchangeListStages(); + CWnd *wnd = GetDlgItem( IDC_STATIC_INFILE ); + if ( wnd ) { + wnd->SetWindowText( va( "Particle file: %s", idp->GetFileName() ) ); + } + + SetParticleView(); +} + +void CDialogParticleEditor::OnCbnSelchangeComboParticles() { + UpdateParticleData(); +} + + +void CDialogParticleEditor::OnCbnSelchangeComboPath() { + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::UpdateControlInfo() { + CWnd *wnd = GetDlgItem( IDC_EDIT_RINGOFFSET ); + if ( wnd ) { + wnd->EnableWindow( distribution == 2 ); + } + wnd = GetDlgItem( IDC_STATIC_DIRPARM ); + if ( wnd ) { + wnd->SetWindowText( (direction == 0 ) ? "Angle" : "Upward Bias" ); + } + wnd = GetDlgItem( IDC_EDIT_ORIENTATIONPARM1 ); + if ( wnd ) { + wnd->EnableWindow( orientation == 1 ); + } + wnd = GetDlgItem( IDC_EDIT_ORIENTATIONPARM2 ); + if ( wnd ) { + wnd->EnableWindow( orientation == 1 ); + } + + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + sliderBunching.SetValuePos( ps->spawnBunching ); + sliderFadeIn.SetValuePos( ps->fadeInFraction ); + sliderFadeOut.SetValuePos( ps->fadeOutFraction ); + sliderFadeFraction.SetValuePos( ps->fadeIndexFraction ); + sliderCount.SetValuePos( ps->totalParticles ); + sliderTime.SetValuePos( ps->particleLife ); + sliderGravity.SetValuePos( ps->gravity ); + sliderSpeedFrom.SetValuePos( ps->speed.from ); + sliderSpeedTo.SetValuePos( ps->speed.to ); + sliderRotationFrom.SetValuePos( ps->rotationSpeed.from ); + sliderRotationTo.SetValuePos( ps->rotationSpeed.to ); + sliderSizeFrom.SetValuePos( ps->size.from ); + sliderSizeTo.SetValuePos( ps->size.to ); + sliderAspectFrom.SetValuePos( ps->aspect.from ); + sliderAspectTo.SetValuePos( ps->aspect.to ); +} + +void CDialogParticleEditor::OnBnClickedRadioRect() { + distribution = 0; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioSphere() { + distribution = 2; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioCylinder() { + distribution = 1; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioCone() { + direction = 0; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioOutward() { + direction = 1; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioView() { + orientation = 0; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioAimed() { + orientation = 1; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioX() { + orientation = 2; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioY() { + orientation = 3; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedRadioZ() { + orientation = 4; + DlgVarsToCurStage(); + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnBnClickedDoom() { + ::SetFocus(win32.hWnd); +} + + +void CDialogParticleEditor::OnBnClickedTestModel() { + visualization = TESTMODEL; + SetParticleView(); +} + +void CDialogParticleEditor::OnBnClickedImpact() { + visualization = IMPACT; + SetParticleView(); +} + +void CDialogParticleEditor::OnBnClickedMuzzle(){ + visualization = MUZZLE; + SetParticleView(); +} + +void CDialogParticleEditor::OnBnClickedFlight() { + visualization = FLIGHT; + SetParticleView(); +} + +void CDialogParticleEditor::OnBnClickedSelected() { + visualization = SELECTED; + SetParticleView(); +} + +void CDialogParticleEditor::SetParticleVisualization( int i ) { + visualization = i; + SetParticleView(); +} + +void CDialogParticleEditor::SetParticleView() { + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "testmodel" ); + idStr str; + switch ( visualization ) { + case TESTMODEL : + str = idp->GetName(); + str.SetFileExtension( ".prt" ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va("testmodel %s\n", str.c_str() ) ); + break; + case IMPACT : + str = idp->GetName(); + str.SetFileExtension( ".prt" ); + cvarSystem->SetCVarInteger( "g_testParticle", TEST_PARTICLE_IMPACT ); + cvarSystem->SetCVarString( "g_testParticleName", str ); + break; + case MUZZLE : + str = idp->GetName(); + str.SetFileExtension( ".prt" ); + cvarSystem->SetCVarInteger( "g_testParticle", TEST_PARTICLE_MUZZLE ); + cvarSystem->SetCVarString( "g_testParticleName", str ); + break; + case FLIGHT : + str = idp->GetName(); + str.SetFileExtension( ".prt" ); + cvarSystem->SetCVarInteger( "g_testParticle", TEST_PARTICLE_FLIGHT ); + cvarSystem->SetCVarString( "g_testParticleName", str ); + break; + case SELECTED : + str = idp->GetName(); + str.SetFileExtension( ".prt" ); + cvarSystem->SetCVarInteger( "g_testParticle", TEST_PARTICLE_FLIGHT ); + SetSelectedModel( str ); + break; + } +} + +void CDialogParticleEditor::SetSelectedModel( const char *val ) { + idList list; + idMat3 axis; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + for ( int i = 0; i < count; i++ ) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + gameEdit->EntitySetModel( list[i], val ); + gameEdit->EntityUpdateVisuals( list[i] ); + gameEdit->EntityGetAxis( list[i], axis ); + vectorControl.SetidAxis( axis ); + gameEdit->MapSetEntityKeyVal( name, "model", val ); + } + CWnd *wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( TRUE ); + } + } +} + + +void CDialogParticleEditor::OnBnClickedButtonHidestage() { + HideStage(); +} + +void CDialogParticleEditor::OnBnClickedButtonShowstage() { + ShowStage(); +} + + +void CDialogParticleEditor::OnBnClickedWorldGravity() { + worldGravity = !worldGravity; + DlgVarsToCurStage(); + CurStageToDlgVars(); +} + +void CDialogParticleEditor::OnBnClickedEntityColor() { + entityColor = !entityColor; + DlgVarsToCurStage(); + CurStageToDlgVars(); +} + + +void CDialogParticleEditor::AddStage() { + + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + + idParticleStage *stage = new idParticleStage; + + if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + idParticleStage *source = GetCurStage(); + if ( source == NULL ) { + delete stage; + return; + } + *stage = *source; + } else { + stage->Default(); + } + int newIndex = idp->stages.Append( stage ); + int index = listStages.AddString( va( "stage %i", newIndex ) ); + listStages.SetCurSel( index ); + listStages.SetItemData( index, newIndex ); + ShowCurrentStage(); + EnableStageControls(); +} + +void CDialogParticleEditor::RemoveStage() { + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + + if ( MessageBox( "Are you sure you want to remove this stage?", "Remove Stage", MB_YESNO | MB_ICONQUESTION ) != IDYES ) { + return; + } + + int index = listStages.GetCurSel(); + if ( index >= 0 ) { + int newIndex = listStages.GetItemData( index ); + if ( newIndex >= 0 && newIndex < idp->stages.Num() ) { + idp->stages.RemoveIndex( newIndex ); + index += ( index >= 1 ) ? -1 : 1; + newIndex = comboParticle.FindStringExact( -1, idp->GetName() ); + EnumParticles(); + if ( newIndex >= 0 ) { + comboParticle.SetCurSel( newIndex ); + } + OnCbnSelchangeComboParticles(); + listStages.SetCurSel( index ); + ShowCurrentStage(); + } + } + EnableStageControls(); +} + +void CDialogParticleEditor::ShowStage() { + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + ps->hidden = false; + int index = listStages.GetCurSel(); + int newIndex = listStages.GetItemData( index ); + listStages.DeleteString ( index ); + listStages.InsertString( index, va("stage %i", index ) ); + listStages.SetItemData( index, newIndex ); + listStages.SetCurSel( index ); + EnableStageControls(); +} + +void CDialogParticleEditor::HideStage() { + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + ps->hidden = true; + int index = listStages.GetCurSel(); + int newIndex = listStages.GetItemData( index ); + listStages.DeleteString ( index ); + listStages.InsertString( index, va("stage %i (H) ", index ) ); + listStages.SetItemData( index, newIndex ); + listStages.SetCurSel( index ); + EnableStageControls(); +} + +idParticleStage *CDialogParticleEditor::GetCurStage() { + idDeclParticle *idp = GetCurParticle(); + int sel = listStages.GetCurSel(); + int index = listStages.GetItemData( sel ); + if ( idp == NULL || sel == LB_ERR || index >= idp->stages.Num() ) { + return NULL; + } + return idp->stages[index]; +} + +void CDialogParticleEditor::ClearDlgVars() { + matName = ""; + animFrames = ""; + animRate = ""; + color = ""; + fadeColor = ""; + fadeIn = ""; + fadeOut = ""; + fadeFraction = ""; + count = ""; + time = ""; + timeOffset = ""; + deadTime = ""; + gravity = ""; + bunching = ""; + offset = ""; + xSize = ""; + ySize = ""; + zSize = ""; + ringOffset = ""; + directionParm = ""; + direction = 1; + orientation = 1; + distribution = 1; + speedFrom = ""; + speedTo = ""; + rotationFrom = ""; + rotationTo = ""; + sizeFrom = ""; + sizeTo = ""; + aspectFrom = ""; + aspectTo = ""; + customPath = ""; + customParms = ""; + trails = ""; + trailTime = ""; + worldGravity = FALSE; + entityColor = FALSE; + randomDistribution = TRUE; + initialAngle = ""; + customDesc = ""; + UpdateData( FALSE ); +} + +void CDialogParticleEditor::CurStageToDlgVars() { + + // go ahead and get the two system vars too + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + + depthHack = va( "%.3f", idp->depthHack ); + + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + matName = ps->material->GetName(); + animFrames = va( "%i", ps->animationFrames ); + animRate = va( "%i", ps->animationRate ); + color = ps->color.ToString(); + fadeColor = ps->fadeColor.ToString(); + fadeIn = va( "%.3f", ps->fadeInFraction ); + fadeOut = va( "%.3f", ps->fadeOutFraction ); + fadeFraction = va( "%.3f", ps->fadeIndexFraction ); + count = va( "%i", ps->totalParticles ); + time = va( "%.3f", ps->particleLife ); + timeOffset = va( "%.3f", ps->timeOffset ); + deadTime = va( "%.3f", ps->deadTime ); + gravity = va( "%.3f", ps->gravity ); + bunching = va( "%.3f", ps->spawnBunching ); + offset = ps->offset.ToString( 0 ); + xSize = va( "%.3f", ps->distributionParms[0] ); + ySize = va( "%.3f", ps->distributionParms[1] ); + zSize = va( "%.3f", ps->distributionParms[2] ); + ringOffset = va( "%.3f", ps->distributionParms[3] ); + directionParm = va( "%.3f", ps->directionParms[0] ); + direction = ps->directionType; + orientation = ps->orientation; + distribution = ps->distributionType; + speedFrom = va( "%.3f", ps->speed.from ); + speedTo = va( "%.3f", ps->speed.to ); + rotationFrom = va( "%.3f", ps->rotationSpeed.from ); + rotationTo = va( "%.3f", ps->rotationSpeed.to ); + sizeFrom = va( "%.3f", ps->size.from ); + sizeTo = va( "%.3f", ps->size.to ); + aspectFrom = va( "%.3f", ps->aspect.from ); + aspectTo = va( "%.3f", ps->aspect.to ); + trails = va( "%f", ps->orientationParms[0] ); + trailTime = va( "%.3f", ps->orientationParms[1] ); + cycles = va( "%.3f", ps->cycles ); + customPath = ps->GetCustomPathName(); + customParms = ""; + customDesc = ps->GetCustomPathDesc(); + if ( ps->customPathType != PPATH_STANDARD ) { + for ( int i = 0; i < ps->NumCustomPathParms(); i++ ) { + customParms += va( "%.1f ", ps->customPathParms[i] ); + } + } + worldGravity = ps->worldGravity; + initialAngle = va( "%.3f", ps->initialAngle ); + boundsExpansion = va( "%.3f", ps->boundsExpansion ); + randomDistribution = ps->randomDistribution; + entityColor = ps->entityColor; + UpdateData( FALSE ); +} + +void CDialogParticleEditor::DlgVarsToCurStage() { + + // go ahead and set the two system vars too + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + idp->depthHack = atof( depthHack ); + + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + ps->material = declManager->FindMaterial( matName ); + ps->animationFrames = atoi( animFrames ); + ps->animationRate = atoi( animRate ); + sscanf( color, "%f %f %f %f", &ps->color.x, &ps->color.y, &ps->color.z, &ps->color.w ); + sscanf( fadeColor, "%f %f %f %f", &ps->fadeColor.x, &ps->fadeColor.y, &ps->fadeColor.z, &ps->fadeColor.w ); + ps->fadeInFraction = atof( fadeIn ); + ps->fadeOutFraction = atof( fadeOut ); + ps->fadeIndexFraction = atof( fadeFraction ); + ps->totalParticles = atoi( count ); + ps->particleLife = atof( time ); + ps->timeOffset = atof( timeOffset ); + ps->deadTime = atof( deadTime ); + ps->gravity = atof( gravity ); + ps->spawnBunching = atof( bunching ); + sscanf( offset, "%f %f %f", &ps->offset.x, &ps->offset.y, &ps->offset.z ); + ps->distributionParms[0] = atof( xSize ); + ps->distributionParms[1] = atof( ySize ); + ps->distributionParms[2] = atof( zSize ); + ps->distributionParms[3] = atof( ringOffset ); + ps->directionParms[0] = atof( directionParm ); + ps->directionType = static_cast( direction ); + ps->orientation = static_cast( orientation ); + ps->distributionType = static_cast( distribution ); + ps->speed.from = atof( speedFrom ); + ps->speed.to = atof( speedTo ); + ps->rotationSpeed.from = atof( rotationFrom ); + ps->rotationSpeed.to = atof( rotationTo ); + ps->size.from = atof( sizeFrom ); + ps->size.to = atof( sizeTo ); + ps->aspect.from = atof( aspectFrom ); + ps->aspect.to = atof( aspectTo ); + ps->orientationParms[0] = atof( trails ); + ps->orientationParms[1] = atof( trailTime ); + ps->worldGravity = ( worldGravity == TRUE ); + ps->cycles = atof( cycles ); + ps->cycleMsec = ( ps->particleLife + ps->deadTime ) * 1000; + + sscanf( customParms, "%f %f %f %f %f %f %f %f", &ps->customPathParms[0], &ps->customPathParms[1], &ps->customPathParms[2], + &ps->customPathParms[3], &ps->customPathParms[4], &ps->customPathParms[5], + &ps->customPathParms[6], &ps->customPathParms[7] ); + + ps->SetCustomPathType( customPath ); + + ps->initialAngle = atof( initialAngle ); + ps->boundsExpansion = atof( boundsExpansion ); + ps->randomDistribution = ( randomDistribution != FALSE ); + ps->entityColor = ( entityColor == TRUE ); + +} + +void CDialogParticleEditor::ShowCurrentStage() { + ClearDlgVars(); + idParticleStage *ps = GetCurStage(); + if ( ps == NULL ) { + return; + } + CurStageToDlgVars(); + UpdateControlInfo(); +} + +void CDialogParticleEditor::OnLbnSelchangeListStages() { + ShowCurrentStage(); + EnableStageControls(); +} + +void CDialogParticleEditor::OnBnClickedButtonNew() { + DialogName dlg("New Particle"); + if (dlg.DoModal() == IDOK) { + CFileDialog dlgSave( TRUE, "prt", NULL, OFN_CREATEPROMPT, "Particle Files (*.prt)|*.prt||All Files (*.*)|*.*||", AfxGetMainWnd() ); + if ( dlgSave.DoModal() == IDOK ) { + if ( declManager->FindType( DECL_PARTICLE, dlg.m_strName, false ) ) { + MessageBox( "Particle already exists!", "Particle exists", MB_OK ); + return; + } + idStr fileName; + fileName = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile ); + idDecl *decl = declManager->CreateNewDecl( DECL_PARTICLE, dlg.m_strName, fileName ); + if ( decl ) { + if ( MessageBox( "Copy current particle?", "Copy current", MB_YESNO | MB_ICONQUESTION ) == IDYES ) { + MessageBox( "Copy current particle not implemented yet.. Stay tuned" ); + } + EnumParticles(); + int index = comboParticle.FindStringExact( -1, dlg.m_strName ); + if ( index >= 0 ) { + comboParticle.SetCurSel( index ); + } + OnBnClickedButtonSave(); + OnCbnSelchangeComboParticles(); + } + } + } +} + +void CDialogParticleEditor::OnBnClickedButtonSave() { + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + + if ( strstr( idp->GetFileName(), "implicit" ) ) { + // defaulted, need to choose a file + CFileDialog dlgSave( FALSE, "prt", NULL, OFN_OVERWRITEPROMPT, "Particle Files (*.prt)|*.prt||All Files (*.*)|*.*||", AfxGetMainWnd() ); + if ( dlgSave.DoModal() == IDOK ) { + idStr fileName; + fileName = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile ); + idp->Save( fileName ); + EnumParticles(); + } + } else { + idp->Save(); + } + +} + +void CDialogParticleEditor::EnumParticles() { + CWaitCursor cursor; + comboParticle.ResetContent(); + for ( int i = 0; i < declManager->GetNumDecls( DECL_PARTICLE ); i++ ) { + const idDecl *idp = declManager->DeclByIndex( DECL_PARTICLE, i ); + int index = comboParticle.AddString( idp->GetName() ); + if ( index >= 0 ) { + comboParticle.SetItemData( index, i ); + } + } + comboParticle.SetCurSel( 0 ); + OnCbnSelchangeComboParticles(); +} + +void CDialogParticleEditor::OnDestroy() { + com_editors &= ~EDITOR_PARTICLE; + return CDialog::OnDestroy(); +} + +void VectorCallBack( idQuat rotation ) { + if ( g_ParticleDialog && g_ParticleDialog->GetSafeHwnd() ) { + g_ParticleDialog->SetVectorControlUpdate( rotation ); + } +} + +void CDialogParticleEditor::SetVectorControlUpdate( idQuat rotation ) { + if ( particleMode ) { + idList list; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + for ( int i = 0; i < count; i++ ) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + gameEdit->EntitySetAxis( list[i], rotation.ToMat3() ); + gameEdit->EntityUpdateVisuals( list[i] ); + gameEdit->MapSetEntityKeyVal( name, "rotation", rotation.ToMat3().ToString() ); + } + CWnd *wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( TRUE ); + } + } + } +} + +BOOL CDialogParticleEditor::OnInitDialog() { + + com_editors |= EDITOR_PARTICLE; + + particleMode = ( cvarSystem->GetCVarInteger( "g_editEntityMode" ) == 4 ); + mapModified = false; + + CDialog::OnInitDialog(); + + sliderBunching.SetRange( 0, 20 ); + sliderBunching.SetValueRange( 0.0f, 1.0f ); + sliderFadeIn.SetRange( 0, 20 ); + sliderFadeIn.SetValueRange( 0.0f, 1.0f ); + sliderFadeOut.SetRange( 0, 20 ); + sliderFadeOut.SetValueRange( 0.0f, 1.0f ); + sliderCount.SetRange( 0, 1024 ); + sliderCount.SetValueRange( 0, 4096 ); + sliderTime.SetRange( 0, 200 ); + sliderTime.SetValueRange( 0.0f, 10.0f ); + sliderGravity.SetRange( 0, 600 ); + sliderGravity.SetValueRange( -300.0f, 300.0f ); + sliderSpeedFrom.SetRange( 0, 600 ); + sliderSpeedFrom.SetValueRange( -300.0f, 300.0f ); + sliderSpeedTo.SetRange( 0, 600 ); + sliderSpeedTo.SetValueRange( -300.0f, 300.0f ); + sliderRotationFrom.SetRange( 0, 100 ); + sliderRotationFrom.SetValueRange( 0.0f, 100.0f ); + sliderRotationTo.SetRange( 0, 100 ); + sliderRotationTo.SetValueRange( 0.0f, 100.0f ); + sliderSizeFrom.SetRange( 0, 256 ); + sliderSizeFrom.SetValueRange( 0.0f, 128.0f ); + sliderSizeTo.SetRange( 0, 256 ); + sliderSizeTo.SetValueRange( 0.0f, 128.0f ); + sliderAspectFrom.SetRange( 0, 256 ); + sliderAspectFrom.SetValueRange( 0.0f, 128.0f ); + sliderAspectTo.SetRange( 0, 256 ); + sliderAspectTo.SetValueRange( 0.0f, 128.0f ); + sliderFadeFraction.SetRange( 0, 20 ); + sliderFadeFraction.SetValueRange( 0.0f, 1.0f ); + + EnumParticles(); + SetParticleView(); + + toolTipCtrl.Create( this ); + toolTipCtrl.Activate( TRUE ); + + CWnd* wnd = GetWindow( GW_CHILD ); + CString str; + while ( wnd ) { + if ( str.LoadString( wnd->GetDlgCtrlID() ) ) { + toolTipCtrl.AddTool( wnd, str ); + } + wnd = wnd->GetWindow( GW_HWNDNEXT ); + } + + wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( FALSE ); + } + EnableEditControls(); + + vectorControl.SetVectorChangingCallback( VectorCallBack ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CDialogParticleEditor::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { + CDialog::OnHScroll( nSBCode, nPos, pScrollBar ); + CSliderCtrl *ctrl = dynamic_cast< CSliderCtrl* >( pScrollBar ); + if ( !ctrl ) { + return; + } + if ( ctrl == &sliderBunching ) { + // handle bunching + bunching = va( "%.3f", sliderBunching.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderFadeIn ) { + fadeIn = va( "%.3f", sliderFadeIn.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderFadeOut ) { + fadeOut = va( "%.3f", sliderFadeOut.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderFadeFraction ) { + fadeFraction = va( "%.3f", sliderFadeFraction.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderCount ) { + count = va( "%i", (int)sliderCount.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderTime ) { + time = va( "%.3f", sliderTime.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderGravity ) { + gravity = va( "%.3f", sliderGravity.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderSpeedFrom ) { + speedFrom = va( "%.3f", sliderSpeedFrom.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderSpeedTo ) { + speedTo = va( "%.3f", sliderSpeedTo.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderRotationFrom ) { + rotationFrom = va( "%.3f", sliderRotationFrom.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderRotationTo ) { + rotationTo = va( "%.3f", sliderRotationTo.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderSizeFrom ) { + sizeFrom = va( "%.3f", sliderSizeFrom.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderSizeTo ) { + sizeTo = va( "%.3f", sliderSizeTo.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderAspectFrom ) { + aspectFrom = va( "%.3f", sliderAspectFrom.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } else if ( ctrl == &sliderAspectTo ) { + aspectTo = va( "%.3f", sliderAspectTo.GetValue() ); + DlgVarsToCurStage(); + CurStageToDlgVars(); + } +} + + +BOOL CDialogParticleEditor::PreTranslateMessage(MSG *pMsg) { + if ( pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST ) { + toolTipCtrl.RelayEvent( pMsg ); + } + return CDialog::PreTranslateMessage(pMsg); +} + +void CDialogParticleEditor::EnableStageControls() { + idParticleStage *stage = GetCurStage(); + bool b = ( stage && stage->hidden ) ? false : true; + for ( int i = 0; i < StageIDCount; i++ ) { + CWnd *wnd = GetDlgItem( StageEnableID[ i ] ); + if ( wnd ) { + wnd->EnableWindow( b ); + } + } +} + +void CDialogParticleEditor::EnableEditControls() { + for ( int i = 0; i < EditIDCount; i++ ) { + CWnd *wnd = GetDlgItem( EditEnableID[ i ] ); + if ( wnd ) { + wnd->EnableWindow( particleMode ); + } + } +} + +void CDialogParticleEditor::UpdateSelectedOrigin( float x, float y, float z ) { + idList list; + idVec3 origin; + idVec3 vec(x, y, z); + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + for ( int i = 0; i < count; i++ ) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + gameEdit->EntityTranslate( list[i], vec ); + gameEdit->EntityUpdateVisuals( list[i] ); + gameEdit->MapEntityTranslate( name, vec ); + } + CWnd *wnd = GetDlgItem( IDC_BUTTON_SAVE_PARTICLEENTITIES ); + if ( wnd ) { + wnd->EnableWindow( TRUE ); + } + } +} + +void CDialogParticleEditor::OnBtnYup() +{ + UpdateSelectedOrigin(0, 8, 0); +} + +void CDialogParticleEditor::OnBtnYdn() +{ + UpdateSelectedOrigin(0, -8, 0); +} + +void CDialogParticleEditor::OnBtnXdn() +{ + UpdateSelectedOrigin(-8, 0, 0); +} + +void CDialogParticleEditor::OnBtnXup() +{ + UpdateSelectedOrigin(8, 0, 0); +} + +void CDialogParticleEditor::OnBtnZup() +{ + UpdateSelectedOrigin(0, 0, 8); +} + +void CDialogParticleEditor::OnBtnZdn() +{ + UpdateSelectedOrigin(0, 0, -8); +} + +void CDialogParticleEditor::OnBtnDrop() +{ + idStr classname; + idStr key; + idStr value; + idVec3 org; + idDict args; + idAngles viewAngles; + + if ( !gameEdit->PlayerIsValid() ) { + return; + } + + gameEdit->PlayerGetViewAngles( viewAngles ); + gameEdit->PlayerGetEyePosition( org ); + + org += idAngles( 0, viewAngles.yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); + args.Set("origin", org.ToString()); + args.Set("classname", "func_emitter"); + args.Set("angle", va( "%f", viewAngles.yaw + 180 )); + + idDeclParticle *idp = GetCurParticle(); + if ( idp == NULL ) { + return; + } + idStr str = idp->GetName(); + str.SetFileExtension( ".prt" ); + + args.Set("model", str); + + idStr name = gameEdit->GetUniqueEntityName( "func_emitter" ); + bool nameValid = false; + while (!nameValid) { + DialogName dlg("Name Particle", this); + dlg.m_strName = name; + if (dlg.DoModal() == IDOK) { + idEntity *gameEnt = gameEdit->FindEntity( dlg.m_strName ); + if (gameEnt) { + if (MessageBox("Please choose another name", "Duplicate Entity Name!", MB_OKCANCEL) == IDCANCEL) { + return; + } + } else { + nameValid = true; + name = dlg.m_strName; + } + } + } + + args.Set("name", name.c_str()); + + idEntity *ent = NULL; + gameEdit->SpawnEntityDef( args, &ent ); + if (ent) { + gameEdit->EntityUpdateChangeableSpawnArgs( ent, NULL ); + gameEdit->ClearEntitySelection(); + gameEdit->AddSelectedEntity( ent ); + } + + gameEdit->MapAddEntity( &args ); +} + +void CDialogParticleEditor::OnOK() +{ + // never return on OK as windows will map this at times when you don't want + // ENTER closing the dialog + // CDialog::OnOK(); +} diff --git a/tools/particle/DialogParticleEditor.h b/tools/particle/DialogParticleEditor.h new file mode 100644 index 000000000..fe2bc788c --- /dev/null +++ b/tools/particle/DialogParticleEditor.h @@ -0,0 +1,214 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGPARTICLEEDITOR_H__ +#define __DIALOGPARTICLEEDITOR_H__ + +#pragma once + +class CRangeSlider : public CSliderCtrl { +public: + void SetValueRange(float _low, float _high) { + low = _low; + high = _high; + } + + void SetValuePos( float val ) { + SetPos( GetRangeMin() + ( GetRangeMax() - GetRangeMin() ) * ( val - low ) / ( high - low ) ); + } + + float GetValue() { + return low + ( high - low ) * ( float )( GetPos() - GetRangeMin() ) / ( GetRangeMax() - GetRangeMin() ); + } +private: + float low, high; +}; + +// CDialogParticleEditor dialog + +class CDialogParticleEditor : public CDialog { + + DECLARE_DYNAMIC(CDialogParticleEditor) + +public: + CDialogParticleEditor(CWnd* pParent = NULL); // standard constructor + virtual ~CDialogParticleEditor(); + + void SelectParticle( const char *name ); + void SetParticleVisualization( int i ); + void SetVectorControlUpdate( idQuat rotation ); + + enum { TESTMODEL, IMPACT, MUZZLE, FLIGHT, SELECTED }; + + //{{AFX_VIRTUAL(CDialogParticleEditor) + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(CDialogParticleEditor) + afx_msg void OnCbnSelchangeComboParticles(); + afx_msg void OnCbnSelchangeComboPath(); + afx_msg void OnLbnSelchangeListStages(); + afx_msg void OnBnClickedButtonAddstage(); + afx_msg void OnBnClickedButtonRemovestage(); + afx_msg void OnBnClickedButtonBrowsematerial(); + afx_msg void OnBnClickedButtonBrowsecolor(); + afx_msg void OnBnClickedButtonBrowsefadecolor(); + afx_msg void OnBnClickedButtonBrowseEntitycolor(); + afx_msg void OnBnClickedRadioRect(); + afx_msg void OnBnClickedRadioSphere(); + afx_msg void OnBnClickedRadioCylinder(); + afx_msg void OnBnClickedRadioCone(); + afx_msg void OnBnClickedRadioOutward(); + afx_msg void OnBnClickedRadioView(); + afx_msg void OnBnClickedRadioAimed(); + afx_msg void OnBnClickedRadioX(); + afx_msg void OnBnClickedRadioY(); + afx_msg void OnBnClickedRadioZ(); + afx_msg void OnBnClickedButtonHidestage(); + afx_msg void OnBnClickedButtonShowstage(); + afx_msg void OnBnClickedCheckOneshot(); + afx_msg void OnBnClickedButtonNew(); + afx_msg void OnBnClickedButtonSave(); + afx_msg void OnBnClickedButtonSaveAs(); + afx_msg void OnBnClickedButtonSaveParticles(); + afx_msg void OnBnClickedWorldGravity(); + afx_msg void OnBnClickedEntityColor(); + afx_msg void OnBnClickedTestModel(); + afx_msg void OnBnClickedImpact(); + afx_msg void OnBnClickedMuzzle(); + afx_msg void OnBnClickedFlight(); + afx_msg void OnBnClickedSelected(); + afx_msg void OnBnClickedDoom(); + afx_msg void OnBnClickedButtonUpdate(); + afx_msg void OnBnClickedParticleMode(); + afx_msg void OnBtnYup(); + afx_msg void OnBtnYdn(); + afx_msg void OnBtnXdn(); + afx_msg void OnBtnXup(); + afx_msg void OnBtnZup(); + afx_msg void OnBtnZdn(); + afx_msg void OnBtnDrop(); + afx_msg void OnDestroy(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(CDialogParticleEditor) + enum { IDD = IDD_DIALOG_PARTICLE_EDITOR }; + CComboBox comboParticle; + CListBox listStages; + CRangeSlider sliderBunching; + CRangeSlider sliderFadeIn; + CRangeSlider sliderFadeOut; + CRangeSlider sliderFadeFraction; + CRangeSlider sliderCount; + CRangeSlider sliderTime; + CRangeSlider sliderGravity; + CRangeSlider sliderSpeedFrom; + CRangeSlider sliderSpeedTo; + CRangeSlider sliderRotationFrom; + CRangeSlider sliderRotationTo; + CRangeSlider sliderSizeFrom; + CRangeSlider sliderSizeTo; + CRangeSlider sliderAspectFrom; + CRangeSlider sliderAspectTo; + CVectorCtl vectorControl; + CString depthHack; + CString matName; + CString animFrames; + CString animRate; + CString color; + CString fadeColor; + CString fadeIn; + CString fadeOut; + CString fadeFraction; + CString count; + CString time; + CString timeOffset; + CString deadTime; + CString gravity; + CString bunching; + CString offset; + CString xSize; + CString ySize; + CString zSize; + CString ringOffset; + CStatic staticDirectionParm; + CString directionParm; + int direction; + int orientation; + int distribution; + CString viewOrigin; + CString speedFrom; + CString speedTo; + CString rotationFrom; + CString rotationTo; + CString sizeFrom; + CString sizeTo; + CString aspectFrom; + CString aspectTo; + CString customPath; + CString customParms; + CString trails; + CString trailTime; + CString cycles; + CEdit editRingOffset; + BOOL worldGravity; + BOOL entityColor; + BOOL randomDistribution; + CString initialAngle; + CString boundsExpansion; + CString customDesc; + + BOOL particleMode; + //}}AFX_DATA + + int visualization; + +private: + void EnumParticles(); + void AddStage(); + void RemoveStage(); + void ShowStage(); + void HideStage(); + idDeclParticle * GetCurParticle(); + idParticleStage * GetCurStage(); + void ClearDlgVars(); + void CurStageToDlgVars(); + void DlgVarsToCurStage(); + void ShowCurrentStage(); + void UpdateControlInfo(); + void SetParticleView(); + void UpdateParticleData(); + CToolTipCtrl toolTipCtrl; + BOOL PreTranslateMessage(MSG *pMsg); + void SetSelectedModel( const char *val ); + void EnableStageControls(); + void EnableEditControls(); + void UpdateSelectedOrigin( float x, float y, float z ); + bool mapModified; +protected: + virtual void OnOK(); +}; + +#endif /* !__DIALOGPARTICLEEDITOR_H__ */ diff --git a/tools/pda/DialogPDAEditor.cpp b/tools/pda/DialogPDAEditor.cpp new file mode 100644 index 000000000..c22ab240c --- /dev/null +++ b/tools/pda/DialogPDAEditor.cpp @@ -0,0 +1,519 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../game/game.h" +#include "../../sys/win32/win_local.h" +#include "../../sys/win32/rc/common_resource.h" +#include "../../sys/win32/rc/PDAEditor_resource.h" +#include "../comafx/DialogName.h" + +#include "DialogPDAEditor.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +///////////////////////////////////////////////////////////////////////////// +// CCDialogPDAEditor dialog +CDialogPDAEditor *g_PDAEditorDialog = NULL; + + +CDialogPDAEditor::CDialogPDAEditor(CWnd* pParent /*=NULL*/) + : CDialog(CDialogPDAEditor::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogPDAEditor) + //}}AFX_DATA_INIT +} + + +void CDialogPDAEditor::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogPDAEditor) + DDX_Control( pDX, IDC_LIST_PDAS, pdaList ); + DDX_Control( pDX, IDC_LIST_EMAIL, emailList ); + DDX_Control( pDX, IDC_LIST_AUDIO, audioList ); + DDX_Control( pDX, IDC_LIST_VIDEO, videoList ); + + DDX_Text( pDX, IDC_EDIT_FULLNAME, fullName ); + DDX_Text( pDX, IDC_EDIT_SHORTNAME, shortName ); + DDX_Text( pDX, IDC_EDIT_POST, post ); + DDX_Text( pDX, IDC_EDIT_TITLE, title ); + DDX_Text( pDX, IDC_EDIT_SECURITY, security ); + DDX_Text( pDX, IDC_EDIT_IDNUM, idnum ); + + DDX_Control( pDX, IDC_BUTTON_SAVE, saveButton ); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogPDAEditor, CDialog) + //{{AFX_MSG_MAP(CDialogPDAEditor) + ON_LBN_SELCHANGE( IDC_LIST_PDAS, OnSelChangePDA ) + ON_BN_CLICKED( IDC_BUTTON_SAVE, OnBtnClickedSave ) + ON_BN_CLICKED( IDC_BUTTON_RANDOMID, OnBtnClickedRandom ) + ON_BN_CLICKED( IDC_BUTTON_PDA_ADD, OnBtnClickedPDAAdd ) + ON_BN_CLICKED( IDC_BUTTON_PDA_DEL, OnBtnClickedPDADel ) + ON_BN_CLICKED( IDC_BUTTON_EMAIL_ADD, OnBtnClickedEmailAdd ) + ON_BN_CLICKED( IDC_BUTTON_EMAIL_EDIT, OnBtnClickedEmailEdit ) + ON_BN_CLICKED( IDC_BUTTON_EMAIL_DELETE, OnBtnClickedEmailDel ) + ON_BN_CLICKED( IDC_BUTTON_AUDIO_ADD, OnBtnClickedAudioAdd ) + ON_BN_CLICKED( IDC_BUTTON_AUDIO_EDIT, OnBtnClickedAudioEdit ) + ON_BN_CLICKED( IDC_BUTTON_AUDIO_DELETE, OnBtnClickedAudioDel ) + ON_BN_CLICKED( IDC_BUTTON_VIDEO_ADD, OnBtnClickedVideoAdd ) + ON_BN_CLICKED( IDC_BUTTON_VIDEO_EDIT, OnBtnClickedVideoEdit ) + ON_BN_CLICKED( IDC_BUTTON_VIDEO_DELETE, OnBtnClickedVideoDel ) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogPDAEditor message handlers + +void PDAEditorInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the PDA editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_PDAEditorDialog == NULL ) { + InitAfx(); + g_PDAEditorDialog = new CDialogPDAEditor(); + } + + if ( g_PDAEditorDialog->GetSafeHwnd() == NULL ) { + g_PDAEditorDialog->Create(IDD_DIALOG_PDA_EDITOR); +/* + // FIXME: restore position + CRect rct; + g_PDAEditorDialog->SetWindowPos( NULL, rct.left, rct.top, 0,0, SWP_NOSIZE ); +*/ + } + + idKeyInput::ClearStates(); + + g_PDAEditorDialog->ShowWindow( SW_SHOW ); + g_PDAEditorDialog->SetFocus(); + + if ( spawnArgs ) { + // select PDA based on spawn args + const char *name = spawnArgs->GetString( "pda" ); + idDeclPDA *decl = static_cast( const_cast( declManager->FindType( DECL_PDA, name ) ) ); + // FIXME: select this PDA + } +} + +void PDAEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +void PDAEditorShutdown( void ) { + delete g_PDAEditorDialog; + g_PDAEditorDialog = NULL; +} + +void CDialogPDAEditor::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); + if ( nState != WA_INACTIVE ) { + } +} + +void CDialogPDAEditor::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +void CDialogPDAEditor::OnDestroy() { + + com_editors &= ~EDITOR_PDA; + + return CDialog::OnDestroy(); +} + +BOOL CDialogPDAEditor::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // Indicate the PDA dialog is opened + com_editors |= EDITOR_PDA; + + PopulatePDAList(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +BOOL CDialogPDAEditor::PreTranslateMessage(MSG* pMsg) +{ + return CDialog::PreTranslateMessage(pMsg); +} + +void CDialogPDAEditor::PopulatePDAList() +{ + pdaList.ResetContent(); + + int i; + int num = declManager->GetNumDecls(DECL_PDA); + for ( i=0; i < num; i++ ) { + const idDeclPDA *pda = dynamic_cast( declManager->DeclByIndex(DECL_PDA, i) ); + pdaList.AddString( pda->GetName() ); + } +} + +void CDialogPDAEditor::OnSelChangePDA() +{ + int i, num; + + int index = pdaList.GetCurSel(); + if ( index < 0 ) { + return; + } + + const idDeclPDA *pda = dynamic_cast( declManager->DeclByIndex(DECL_PDA, index) ); + if ( !pda ) { + return; + } + + CString windowTitle; + windowTitle.Format("PDA Editor - %s", pda->GetName()); + + idFile *file = fileSystem->OpenFileAppend( pda->GetFileName() ); + if ( file ) { + fileSystem->CloseFile(file); + saveButton.EnableWindow( true ); + } else { + windowTitle += " [Read Only]"; + saveButton.EnableWindow( false ); + } + + SetWindowText( windowTitle ); + + emailList.ResetContent(); + num = pda->GetNumEmails(); + for ( i=0; i < num; i++ ) { + emailList.AddString( pda->GetEmailByIndex( i )->GetSubject() ); + } + + audioList.ResetContent(); + num = pda->GetNumAudios(); + for ( i=0; i < num; i++ ) { + audioList.AddString( pda->GetAudioByIndex( i )->GetAudioName() ); + } + + videoList.ResetContent(); + num = pda->GetNumVideos(); + for ( i=0; i < num; i++ ) { + videoList.AddString( pda->GetVideoByIndex( i )->GetVideoName() ); + } + + fullName = pda->GetFullName(); + shortName = pda->GetPdaName(); + post = pda->GetPost(); + title = pda->GetTitle(); + security = pda->GetSecurity(); + idnum = pda->GetID(); + + UpdateData( FALSE ); +} + +void CDialogPDAEditor::OnBtnClickedSave() +{ + UpdateData(); + + int index = pdaList.GetCurSel(); + if ( index < 0 ) { + return; + } + + const idDeclPDA *pdaConst = dynamic_cast( declManager->DeclByIndex(DECL_PDA, index) ); + if ( pdaConst ) { + idDeclPDA *pda = const_cast(pdaConst); + + CString declText = "\n"; + declText += "pda "; + declText += pda->GetName(); + declText += " {\n"; + + declText += "\tname \t\t\"" + shortName + "\"\n"; + declText += "\tfullname\t\t\"" + fullName + "\"\n"; + declText += "\ticon \t\t\"\"\n"; + declText += "\tid \t\t\"" + idnum + "\"\n"; + declText += "\tpost \t\t\"" + post + "\"\n"; + declText += "\ttitle \t\t\"" + title + "\"\n"; + declText += "\tsecurity\t\t\"" + security + "\"\n"; + + for ( int i = 0; i < pda->GetNumEmails(); i++ ) { + declText += "\tpda_email\t\t\""; + declText += pda->GetEmailByIndex(i)->GetName(); + declText += "\"\n"; + } + + for ( int i = 0; i < pda->GetNumAudios(); i++ ) { + declText += "\tpda_audio\t\t\""; + declText += pda->GetAudioByIndex(i)->GetName(); + declText += "\"\n"; + } + + for ( int i = 0; i < pda->GetNumVideos(); i++ ) { + declText += "\tpda_video\t\t\""; + declText += pda->GetVideoByIndex(i)->GetName(); + declText += "\"\n"; + } + + declText += "}"; + + pda->SetText( declText ); + pda->ReplaceSourceFileText(); + pda->Invalidate(); + } +} + +void CDialogPDAEditor::OnBtnClickedRandom() +{ + idnum.Format("%d-%02X", 1000+(rand()%8999), (rand()%255)); + UpdateData( FALSE ); +} + +class CDialogPDAAdd : public CDialog +{ +public: + CDialogPDAAdd() : CDialog(IDD_DIALOG_PDA_ADD) {} + CString name; + void OnOK() { GetDlgItemText( IDC_EDIT1, name ); CDialog::OnOK(); } +}; + +void CDialogPDAEditor::OnBtnClickedPDAAdd() +{ + CDialogPDAAdd dlg; + if ( dlg.DoModal() == IDOK ) { + dlg.name.MakeLower(); + idDecl *decl = declManager->CreateNewDecl( DECL_PDA, dlg.name, "newpdas/" + dlg.name + ".pda" ); + decl->ReplaceSourceFileText(); + decl->Invalidate(); + PopulatePDAList(); + pdaList.SelectString( 0, dlg.name ); + OnSelChangePDA(); + } +} + +void CDialogPDAEditor::OnBtnClickedPDADel() +{ +} + +void CDialogPDAEditor::OnBtnClickedEmailAdd() +{ + int index = pdaList.GetCurSel(); + if ( index < 0 ) { + return; + } + const idDeclPDA *pda = dynamic_cast( declManager->DeclByIndex(DECL_PDA, index) ); + + if ( pda ) { + CString name; + + // Search for an unused name + int newIndex = pda->GetNumEmails(); + do { + name.Format("%s_email_%d", pda->GetName(), newIndex++); + } while ( declManager->FindType(DECL_EMAIL, name, false) != NULL ); + + CDialogPDAEditEmail addDlg; + addDlg.SetName(name); + if ( addDlg.DoModal() == IDOK ) { + idDeclEmail *email = static_cast(declManager->CreateNewDecl(DECL_EMAIL, name, pda->GetFileName())); + email->SetText( addDlg.GetDeclText() ); + email->ReplaceSourceFileText(); + email->Invalidate(); + + pda->AddEmail( name ); + + // Get it again to reparse + const idDeclEmail *emailConst = static_cast( declManager->FindType( DECL_EMAIL, name) ); + emailList.AddString( emailConst->GetSubject() ); + + // Save the pda to include this email in the list + // This has a side-effect of saving any other changes, but I don't really care right now + OnBtnClickedSave(); + } + } +} + +void CDialogPDAEditor::OnBtnClickedEmailEdit() +{ + int index = pdaList.GetCurSel(); + if ( index < 0 ) { + return; + } + const idDeclPDA *pda = dynamic_cast( declManager->DeclByIndex(DECL_PDA, index) ); + + if ( pda ) { + index = emailList.GetCurSel(); + if ( index < 0 ) { + return; + } + + CDialogPDAEditEmail editDlg; + editDlg.SetEmail( pda->GetEmailByIndex( index ) ); + if ( editDlg.DoModal() == IDOK ) { + idDeclEmail *email = const_cast( pda->GetEmailByIndex( index ) ); + email->SetText( editDlg.GetDeclText() ); + email->ReplaceSourceFileText(); + email->Invalidate(); + + // Get it again to reparse + email = const_cast( pda->GetEmailByIndex( index ) ); + + emailList.DeleteString( index ); + emailList.InsertString( index, email->GetSubject() ); + } + } +} + +void CDialogPDAEditor::OnBtnClickedEmailDel() +{ +} + +void CDialogPDAEditor::OnBtnClickedAudioAdd() +{ +} + +void CDialogPDAEditor::OnBtnClickedAudioEdit() +{ +} + +void CDialogPDAEditor::OnBtnClickedAudioDel() +{ +} + +void CDialogPDAEditor::OnBtnClickedVideoAdd() +{ +} + +void CDialogPDAEditor::OnBtnClickedVideoEdit() +{ +} + +void CDialogPDAEditor::OnBtnClickedVideoDel() +{ +} + + + + +CDialogPDAEditEmail::CDialogPDAEditEmail(CWnd* pParent /*=NULL*/) + : CDialog(CDialogPDAEditEmail::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogPDAEditEmail) + //}}AFX_DATA_INIT +} + + +void CDialogPDAEditEmail::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogPDAEditEmail) + DDX_Text( pDX, IDC_EDIT_TO, to ); + DDX_Text( pDX, IDC_EDIT_FROM, from ); + DDX_Text( pDX, IDC_EDIT_DATE, date ); + DDX_Text( pDX, IDC_EDIT_SUBJECT, subject ); + DDX_Text( pDX, IDC_EDIT_BODY, body ); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogPDAEditEmail, CDialog) + //{{AFX_MSG_MAP(CDialogPDAEditEmail) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogPDAEditor message handlers + +BOOL CDialogPDAEditEmail::OnInitDialog() +{ + CDialog::OnInitDialog(); + + SetWindowText( "Editing Email: " + name ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CDialogPDAEditEmail::SetName( CString &_name ) +{ + name = _name; +} + +void CDialogPDAEditEmail::SetEmail( const idDeclEmail *email ) +{ + to = email->GetTo(); + from = email->GetFrom(); + date = email->GetDate(); + subject = email->GetSubject(); + body = email->GetBody(); + body.Replace("\n", "\r\n"); + + name = email->GetName(); + + if ( IsWindow( m_hWnd ) ) { + UpdateData(FALSE); + } +} + +CString CDialogPDAEditEmail::GetDeclText() +{ + CString mungedBody = body; + mungedBody.Replace("\r\n\r\n", "\\n\\n\"\n\n\""); + mungedBody.Replace("\r\n", "\\n\"\n\""); + + CString declText; + declText += "\n"; + declText += "email " + name + " {\n"; + declText += "\tto \t\t\"" + to + "\"\n"; + declText += "\tfrom \t\t\"" + from + "\"\n"; + declText += "\tdate \t\t\"" + date + "\"\n"; + declText += "\tsubject\t\t\"" + subject + "\"\n"; + declText += "\ttext {\n"; + declText += "\"" + mungedBody + "\"\n"; + declText += "\t}\n"; + declText += "}"; + + return declText; +} + diff --git a/tools/pda/DialogPDAEditor.h b/tools/pda/DialogPDAEditor.h new file mode 100644 index 000000000..eead4eae6 --- /dev/null +++ b/tools/pda/DialogPDAEditor.h @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGPDAEDITOR_H__ +#define __DIALOGPDAEDITOR_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CCDialogPDAEditor dialog + +class CDialogPDAEditor : public CDialog { +public: + CDialogPDAEditor(CWnd* pParent = NULL); // standard constructor + + //{{AFX_VIRTUAL(CDialogPDAEditor) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(CDialogPDAEditor) + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnMove( int x, int y ); + afx_msg void OnDestroy(); + + afx_msg void OnSelChangePDA(); + + afx_msg void OnBtnClickedSave(); + afx_msg void OnBtnClickedRandom(); + + afx_msg void OnBtnClickedPDAAdd(); + afx_msg void OnBtnClickedPDADel(); + + afx_msg void OnBtnClickedEmailAdd(); + afx_msg void OnBtnClickedEmailEdit(); + afx_msg void OnBtnClickedEmailDel(); + + afx_msg void OnBtnClickedAudioAdd(); + afx_msg void OnBtnClickedAudioEdit(); + afx_msg void OnBtnClickedAudioDel(); + + afx_msg void OnBtnClickedVideoAdd(); + afx_msg void OnBtnClickedVideoEdit(); + afx_msg void OnBtnClickedVideoDel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(CDialogPDAEditor) + enum { IDD = IDD_DIALOG_PDA_EDITOR }; + CListBox pdaList; + CListBox emailList; + CListBox audioList; + CListBox videoList; + + CString fullName; + CString shortName; + CString post; + CString title; + CString security; + CString idnum; + + CButton saveButton; + //}}AFX_DATA + +private: + virtual BOOL PreTranslateMessage(MSG* pMsg); + + void PopulatePDAList(); +}; + +class CDialogPDAEditEmail : public CDialog { +public: + CDialogPDAEditEmail(CWnd* pParent = NULL); // standard constructor + + //{{AFX_VIRTUAL(CDialogPDAEditEmail) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + void SetName( CString &name ); + void SetEmail( const idDeclEmail *email ); + + CString GetDeclText(); + +protected: + //{{AFX_MSG(CDialogPDAEditEmail) + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(CDialogPDAEditEmail) + enum { IDD = IDD_DIALOG_PDA_EDIT_EMAIL }; + + CString to; + CString from; + CString date; + CString subject; + CString body; + + CString name; + //}}AFX_DATA +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif /* !__DIALOGPDAEDITOR_H__ */ diff --git a/tools/radiant/CSG.CPP b/tools/radiant/CSG.CPP new file mode 100644 index 000000000..c95d4c92f --- /dev/null +++ b/tools/radiant/CSG.CPP @@ -0,0 +1,678 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +const float PLANE_EPSILON = 0.0001f; + +/* +============= +CSG_MakeHollow +============= +*/ +void CSG_MakeHollow (void) +{ + brush_t *b, *front, *back, *next; + face_t *f; + face_t split; + idVec3 move; + int i; + + for (b = selected_brushes.next ; b != &selected_brushes ; b=next) + { + next = b->next; + + if (b->owner->eclass->fixedsize || b->pPatch || b->hiddenBrush || b->modelHandle > 0) + continue; + + for ( f = b->brush_faces; f; f = f->next ) { + split = *f; + VectorScale (f->plane, g_qeglobals.d_gridsize, move); + for (i=0 ; i<3 ; i++) + VectorSubtract (split.planepts[i], move, split.planepts[i]); + + Brush_SplitBrushByFace (b, &split, &front, &back); + if (back) + Brush_Free (back); + if (front) + Brush_AddToList (front, &selected_brushes); + } + Brush_Free (b); + } + Sys_UpdateWindows (W_ALL); +} + +/* +============= +Brush_Merge + + Returns a new brush that is created by merging brush1 and brush2. + May return NULL if brush1 and brush2 do not create a convex brush when merged. + The input brushes brush1 and brush2 stay intact. + + if onlyshape is true then the merge is allowed based on the shape only + otherwise the texture/shader references of faces in the same plane have to + be the same as well. +============= +*/ +brush_t *Brush_Merge(brush_t *brush1, brush_t *brush2, int onlyshape) +{ + int i, shared; + brush_t *newbrush; + face_t *face1, *face2, *newface, *f; + + // check for bounding box overlapp + for (i = 0; i < 3; i++) + { + if (brush1->mins[i] > brush2->maxs[i] + ON_EPSILON + || brush1->maxs[i] < brush2->mins[i] - ON_EPSILON) + { + // never merge if the brushes overlap + return NULL; + } + } + // + shared = 0; + // check if the new brush would be convex... flipped planes make a brush non-convex + for (face1 = brush1->brush_faces; face1; face1 = face1->next) + { + // don't check the faces of brush 1 and 2 touching each other + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + if ( face1->plane.Compare( -face2->plane, PLANE_EPSILON ) ) + { + shared++; + // there may only be ONE shared side + if (shared > 1) + return NULL; + break; + } + } + // if this face plane is shared + if (face2) continue; + // + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + // don't check the faces of brush 1 and 2 touching each other + for ( f = brush1->brush_faces; f; f = f->next ) { + if ( face2->plane.Compare( -f->plane, PLANE_EPSILON ) ) { + break; + } + } + if ( f ) { + continue; + } + + if ( face1->plane.Compare( face2->plane, PLANE_EPSILON ) ) + { + //if the texture/shader references should be the same but are not + if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) + return NULL; + continue; + } + // + if ( face1->face_winding->PlanesConcave( *face2->face_winding, + face1->plane.Normal(), face2->plane.Normal(), -face1->plane[3], -face2->plane[3])) + { + return NULL; + } //end if + } //end for + } //end for + // + newbrush = Brush_Alloc(); + // + for (face1 = brush1->brush_faces; face1; face1 = face1->next) + { + // don't add the faces of brush 1 and 2 touching each other + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + if ( face1->plane.Compare( -face2->plane, PLANE_EPSILON ) ) { + break; + } + } + if ( face2 ) + continue; + // don't add faces with the same plane twice + for (f = newbrush->brush_faces; f; f = f->next) + { + if ( face1->plane.Compare( f->plane, PLANE_EPSILON ) ) + break; + if ( face1->plane.Compare( -f->plane, PLANE_EPSILON ) ) + break; + } + if ( f ) { + continue; + } + + newface = Face_Alloc(); + newface->texdef = face1->texdef; + VectorCopy(face1->planepts[0], newface->planepts[0]); + VectorCopy(face1->planepts[1], newface->planepts[1]); + VectorCopy(face1->planepts[2], newface->planepts[2]); + newface->plane = face1->plane; + newface->next = newbrush->brush_faces; + newbrush->brush_faces = newface; + } + + for (face2 = brush2->brush_faces; face2; face2 = face2->next) { + // don't add the faces of brush 1 and 2 touching each other + for (face1 = brush1->brush_faces; face1; face1 = face1->next) + { + if ( face2->plane.Compare( -face1->plane, PLANE_EPSILON ) ) { + break; + } + } + if (face1) + continue; + // don't add faces with the same plane twice + for (f = newbrush->brush_faces; f; f = f->next) + { + if ( face2->plane.Compare( f->plane, PLANE_EPSILON ) ) + break; + if ( face2->plane.Compare( -f->plane, PLANE_EPSILON ) ) + break; + } + if ( f ) { + continue; + } + // + newface = Face_Alloc(); + newface->texdef = face2->texdef; + VectorCopy(face2->planepts[0], newface->planepts[0]); + VectorCopy(face2->planepts[1], newface->planepts[1]); + VectorCopy(face2->planepts[2], newface->planepts[2]); + newface->plane = face2->plane; + newface->next = newbrush->brush_faces; + newbrush->brush_faces = newface; + } + // link the new brush to an entity + Entity_LinkBrush (brush1->owner, newbrush); + // build windings for the faces + Brush_BuildWindings( newbrush, false); + return newbrush; +} + +/* +============= +Brush_MergeListPairs + + Returns a list with merged brushes. + Tries to merge brushes pair wise. + The input list is destroyed. + Input and output should be a single linked list using .next +============= +*/ +brush_t *Brush_MergeListPairs(brush_t *brushlist, int onlyshape) +{ + int nummerges, merged; + brush_t *b1, *b2, *tail, *newbrush, *newbrushlist; + brush_t *lastb2; + + if (!brushlist) return NULL; + + nummerges = 0; + do + { + for (tail = brushlist; tail; tail = tail->next) + { + if (!tail->next) break; + } + merged = 0; + newbrushlist = NULL; + for (b1 = brushlist; b1; b1 = brushlist) + { + lastb2 = b1; + for (b2 = b1->next; b2; b2 = b2->next) + { + newbrush = Brush_Merge(b1, b2, onlyshape); + if (newbrush) + { + tail->next = newbrush; + lastb2->next = b2->next; + brushlist = brushlist->next; + b1->next = b1->prev = NULL; + b2->next = b2->prev = NULL; + Brush_Free(b1); + Brush_Free(b2); + for (tail = brushlist; tail; tail = tail->next) + { + if (!tail->next) break; + } //end for + merged++; + nummerges++; + break; + } + lastb2 = b2; + } + //if b1 can't be merged with any of the other brushes + if (!b2) + { + brushlist = brushlist->next; + //keep b1 + b1->next = newbrushlist; + newbrushlist = b1; + } + } + brushlist = newbrushlist; + } while(merged); + return newbrushlist; +} + +/* +============= +Brush_MergeList + + Tries to merge all brushes in the list into one new brush. + The input brush list stays intact. + Returns NULL if no merged brush can be created. + To create a new brush the brushes in the list may not overlap and + the outer faces of the brushes together should make a new convex brush. + + if onlyshape is true then the merge is allowed based on the shape only + otherwise the texture/shader references of faces in the same plane have to + be the same as well. +============= +*/ +brush_t *Brush_MergeList(brush_t *brushlist, int onlyshape) +{ + brush_t *brush1, *brush2, *brush3, *newbrush; + face_t *face1, *face2, *face3, *newface, *f; + + if (!brushlist) return NULL; + for (brush1 = brushlist; brush1; brush1 = brush1->next) + { + // check if the new brush would be convex... flipped planes make a brush concave + for (face1 = brush1->brush_faces; face1; face1 = face1->next) + { + // don't check face1 if it touches another brush + for (brush2 = brushlist; brush2; brush2 = brush2->next) + { + if (brush2 == brush1) continue; + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + if ( face1->plane.Compare( -face2->plane, PLANE_EPSILON ) ) { + break; + } + } + if (face2) + break; + } + // if face1 touches another brush + if (brush2) + continue; + // + for (brush2 = brush1->next; brush2; brush2 = brush2->next) + { + // don't check the faces of brush 2 touching another brush + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + for (brush3 = brushlist; brush3; brush3 = brush3->next) + { + if (brush3 == brush2) continue; + for (face3 = brush3->brush_faces; face3; face3 = face3->next) + { + if ( face2->plane.Compare( -face3->plane, PLANE_EPSILON ) ) + break; + } + if (face3) + break; + } + // if face2 touches another brush + if (brush3) + continue; + // + if ( face1->plane.Compare( face2->plane, PLANE_EPSILON ) ) + { + //if the texture/shader references should be the same but are not + if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) + return NULL; + continue; + } + // + if ( face1->face_winding->PlanesConcave( *face2->face_winding, + face1->plane.Normal(), face2->plane.Normal(), -face1->plane[3], -face2->plane[3])) + { + return NULL; + } + } + } + } + } + // + newbrush = Brush_Alloc(); + // + for (brush1 = brushlist; brush1; brush1 = brush1->next) + { + for (face1 = brush1->brush_faces; face1; face1 = face1->next) + { + // don't add face1 to the new brush if it touches another brush + for (brush2 = brushlist; brush2; brush2 = brush2->next) + { + if (brush2 == brush1) continue; + for (face2 = brush2->brush_faces; face2; face2 = face2->next) + { + if ( face1->plane.Compare( -face2->plane, PLANE_EPSILON ) ) { + break; + } + } + if (face2) + break; + } + if (brush2) + continue; + // don't add faces with the same plane twice + for (f = newbrush->brush_faces; f; f = f->next) + { + if ( face1->plane.Compare( f->plane, PLANE_EPSILON ) ) + break; + if ( face1->plane.Compare( -f->plane, PLANE_EPSILON ) ) + break; + } + if (f) + continue; + // + newface = Face_Alloc(); + newface->texdef = face1->texdef; + VectorCopy(face1->planepts[0], newface->planepts[0]); + VectorCopy(face1->planepts[1], newface->planepts[1]); + VectorCopy(face1->planepts[2], newface->planepts[2]); + newface->plane = face1->plane; + newface->next = newbrush->brush_faces; + newbrush->brush_faces = newface; + } + } + // link the new brush to an entity + Entity_LinkBrush (brushlist->owner, newbrush); + // build windings for the faces + Brush_BuildWindings( newbrush, false); + return newbrush; +} + +/* +============= +Brush_Subtract + + Returns a list of brushes that remain after B is subtracted from A. + May by empty if A is contained inside B. + The originals are undisturbed. +============= +*/ +brush_t *Brush_Subtract(brush_t *a, brush_t *b) +{ + // a - b = out (list) + brush_t *front, *back; + brush_t *in, *out, *next; + face_t *f; + + in = a; + out = NULL; + for (f = b->brush_faces; f && in; f = f->next) + { + Brush_SplitBrushByFace(in, f, &front, &back); + if (in != a) Brush_Free(in); + if (front) + { // add to list + front->next = out; + out = front; + } + in = back; + } + //NOTE: in != a just in case brush b has no faces + if (in && in != a) + { + Brush_Free(in); + } + else + { //didn't really intersect + for (b = out; b; b = next) + { + next = b->next; + b->next = b->prev = NULL; + Brush_Free(b); + } + return a; + } + return out; +} + +/* +============= +CSG_Subtract +============= +*/ +void CSG_Subtract (void) +{ + brush_t *b, *s, *fragments, *nextfragment, *frag, *next, *snext; + brush_t fragmentlist; + int i, numfragments, numbrushes; + + Sys_Status ("Subtracting...\n"); + + if (selected_brushes.next == &selected_brushes) + { + Sys_Status("No brushes selected.\n"); + return; + } + + fragmentlist.next = &fragmentlist; + fragmentlist.prev = &fragmentlist; + + numfragments = 0; + numbrushes = 0; + for (b = selected_brushes.next ; b != &selected_brushes ; b=next) + { + next = b->next; + + if (b->owner->eclass->fixedsize || b->modelHandle > 0) + continue; // can't use texture from a fixed entity, so don't subtract + + // chop all fragments further up + for (s = fragmentlist.next; s != &fragmentlist; s = snext) + { + snext = s->next; + + for (i=0 ; i<3 ; i++) + if (b->mins[i] >= s->maxs[i] - ON_EPSILON + || b->maxs[i] <= s->mins[i] + ON_EPSILON) + break; + if (i != 3) + continue; // definately don't touch + fragments = Brush_Subtract(s, b); + // if the brushes did not really intersect + if (fragments == s) + continue; + // try to merge fragments + fragments = Brush_MergeListPairs(fragments, true); + // add the fragments to the list + for (frag = fragments; frag; frag = nextfragment) + { + nextfragment = frag->next; + frag->next = NULL; + frag->owner = s->owner; + Brush_AddToList(frag, &fragmentlist); + } + // free the original brush + Brush_Free(s); + } + + // chop any active brushes up + for (s = active_brushes.next; s != &active_brushes; s = snext) + { + snext = s->next; + + if (s->owner->eclass->fixedsize || s->pPatch || s->hiddenBrush || s->modelHandle > 0) + continue; + + //face_t *pFace = s->brush_faces; + if ( s->brush_faces->d_texture && ( s->brush_faces->d_texture->GetContentFlags()& CONTENTS_NOCSG ) ) + { + continue; + } + + for (i=0 ; i<3 ; i++) + if (b->mins[i] >= s->maxs[i] - ON_EPSILON + || b->maxs[i] <= s->mins[i] + ON_EPSILON) + break; + if (i != 3) + continue; // definately don't touch + + fragments = Brush_Subtract(s, b); + // if the brushes did not really intersect + if (fragments == s) + continue; + // + Undo_AddBrush(s); + // one extra brush chopped up + numbrushes++; + // try to merge fragments + fragments = Brush_MergeListPairs(fragments, true); + // add the fragments to the list + for (frag = fragments; frag; frag = nextfragment) + { + nextfragment = frag->next; + frag->next = NULL; + frag->owner = s->owner; + Brush_AddToList(frag, &fragmentlist); + } + // free the original brush + Brush_Free(s); + } + } + + // move all fragments to the active brush list + for (frag = fragmentlist.next; frag != &fragmentlist; frag = nextfragment) + { + nextfragment = frag->next; + numfragments++; + Brush_RemoveFromList(frag); + Brush_AddToList(frag, &active_brushes); + Undo_EndBrush(frag); + } + + if (numfragments == 0) + { + common->Printf("Selected brush%s did not intersect with any other brushes.\n", + (selected_brushes.next->next == &selected_brushes) ? "":"es"); + return; + } + Sys_Status("done."); + common->Printf(" (created %d fragment%s out of %d brush%s)\n", numfragments, (numfragments == 1)?"":"s", + numbrushes, (numbrushes == 1)?"":"es"); + Sys_UpdateWindows(W_ALL); +} + +/* +============= +CSG_Merge +============= +*/ +void CSG_Merge(void) +{ + brush_t *b, *next, *newlist, *newbrush; + struct entity_s *owner; + + Sys_Status("Merging...\n"); + + if (selected_brushes.next == &selected_brushes) + { + Sys_Status("No brushes selected.\n"); + return; + } + + if (selected_brushes.next->next == &selected_brushes) + { + Sys_Status("At least two brushes have to be selected.\n"); + return; + } + + owner = selected_brushes.next->owner; + + for (b = selected_brushes.next; b != &selected_brushes; b = next) + { + next = b->next; + + if (b->owner->eclass->fixedsize || b->modelHandle > 0) + { + // can't use texture from a fixed entity, so don't subtract + Sys_Status("Cannot add fixed size entities.\n"); + return; + } + + if (b->pPatch) + { + Sys_Status("Cannot add patches.\n"); + return; + } + + if ( b->brush_faces->d_texture && ( b->brush_faces->d_texture->GetContentFlags() & CONTENTS_NOCSG ) ) + { + Sys_Status("Cannot add brushes using shaders that don't allows CSG operations.\n"); + return; + } + + if (b->owner != owner) + { + Sys_Status("Cannot add brushes from different entities.\n"); + return; + } + + } + + newlist = NULL; + for (b = selected_brushes.next; b != &selected_brushes; b = next) + { + next = b->next; + + Brush_RemoveFromList(b); + b->next = newlist; + b->prev = NULL; + newlist = b; + } + + newbrush = Brush_MergeList(newlist, true); + // if the new brush would not be convex + if (!newbrush) + { + // add the brushes back into the selection + for (b = newlist; b; b = next) + { + next = b->next; + b->next = NULL; + b->prev = NULL; + Brush_AddToList(b, &selected_brushes); + } + Sys_Status("Cannot add a set of brushes with a concave hull.\n"); + return; + } + // free the original brushes + for (b = newlist; b; b = next) + { + next = b->next; + b->next = NULL; + b->prev = NULL; + Brush_Free(b); + } + Brush_AddToList(newbrush, &selected_brushes); + + Sys_Status ("done.\n"); + Sys_UpdateWindows (W_ALL); +} diff --git a/tools/radiant/CamWnd.cpp b/tools/radiant/CamWnd.cpp new file mode 100644 index 000000000..04e9c9906 --- /dev/null +++ b/tools/radiant/CamWnd.cpp @@ -0,0 +1,2159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "XYWnd.h" +#include "CamWnd.h" +#include "splines.h" +#include + +#include "../../renderer/tr_local.h" +#include "../../renderer/model_local.h" // for idRenderModelMD5 + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif +extern void DrawPathLines(); + +int g_axialAnchor = -1; +int g_axialDest = -1; +bool g_bAxialMode = false; + +void ValidateAxialPoints() { + int faceCount = g_ptrSelectedFaces.GetSize(); + if (faceCount > 0) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0)); + if (g_axialAnchor >= selFace->face_winding->GetNumPoints()) { + g_axialAnchor = 0; + } + if (g_axialDest >= selFace->face_winding->GetNumPoints()) { + g_axialDest = 0; + } + } else { + g_axialDest = 0; + g_axialAnchor = 0; + } +} + +// CCamWnd +IMPLEMENT_DYNCREATE(CCamWnd, CWnd); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CCamWnd::CCamWnd() { + m_pXYFriend = NULL; + memset(&m_Camera, 0, sizeof(camera_t)); + m_pSide_select = NULL; + m_bClipMode = false; + worldDirty = true; + worldModel = NULL; + renderMode = false; + rebuildMode = false; + entityMode = false; + animationMode = false; + selectMode = false; + soundMode = false; + saveValid = false; + Cam_Init(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CCamWnd::~CCamWnd() { +} + +BEGIN_MESSAGE_MAP(CCamWnd, CWnd) +//{{AFX_MSG_MAP(CCamWnd) + ON_WM_KEYDOWN() + ON_WM_PAINT() + ON_WM_DESTROY() + ON_WM_CLOSE() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONDOWN() + ON_WM_MBUTTONUP() + ON_WM_RBUTTONDOWN() + ON_WM_RBUTTONUP() + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_KEYUP() + ON_WM_NCCALCSIZE() + ON_WM_KILLFOCUS() + ON_WM_SETFOCUS() + ON_WM_TIMER() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() +/* + ======================================================================================================================= + ======================================================================================================================= + */ +LONG WINAPI CamWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + RECT rect; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_KILLFOCUS: + case WM_SETFOCUS: + SendMessage(hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0); + return 0; + + case WM_NCCALCSIZE: // don't let windows copy pixels + DefWindowProc(hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +// +// ======================================================================================================================= +// CCamWnd message handlers +// ======================================================================================================================= +// +BOOL CCamWnd::PreCreateWindow(CREATESTRUCT &cs) { + WNDCLASS wc; + HINSTANCE hInstance = AfxGetInstanceHandle(); + if (::GetClassInfo(hInstance, CAMERA_WINDOW_CLASS, &wc) == FALSE) { + // Register a new class + memset(&wc, 0, sizeof(wc)); + + // wc.style = CS_NOCLOSE | CS_OWNDC; + wc.style = CS_NOCLOSE; + wc.lpszClassName = CAMERA_WINDOW_CLASS; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpfnWndProc = CamWndProc; + if (AfxRegisterClass(&wc) == FALSE) { + Error("CCamWnd RegisterClass: failed"); + } + } + + cs.lpszClass = CAMERA_WINDOW_CLASS; + cs.lpszName = "CAM"; + if (cs.style != QE3_CHILDSTYLE) { + cs.style = QE3_SPLITTER_STYLE; + } + + BOOL bResult = CWnd::PreCreateWindow(cs); + + // + // See if the class already exists and if not then we need to register our new + // window class. + // + return bResult; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); +} + +brush_t *g_pSplitList = NULL; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnPaint() { + CPaintDC dc(this); // device context for painting + bool bPaint = true; + + if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) { + common->Printf("ERROR: wglMakeCurrent failed..\n "); + common->Printf("Please restart " EDITOR_WINDOWTEXT " if the camera view is not working\n"); + } + else { + QE_CheckOpenGLForErrors(); + g_pSplitList = NULL; + if (g_bClipMode) { + if (g_Clip1.Set() && g_Clip2.Set()) { + g_pSplitList = ((g_pParentWnd->ActiveXY()->GetViewType() == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits; + } + } + + Cam_Draw(); + QE_CheckOpenGLForErrors(); + qwglSwapBuffers(dc.m_hDC); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::SetXYFriend(CXYWnd *pWnd) { + m_pXYFriend = pWnd; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnDestroy() { + CWnd::OnDestroy(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnClose() { + CWnd::OnClose(); +} + +extern void Select_RotateTexture(float amt, bool absolute); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) { + CRect r; + GetClientRect(r); + if (GetCapture() == this && (GetAsyncKeyState(VK_MENU) & 0x8000) && !((GetAsyncKeyState(VK_SHIFT) & 0x8000) || (GetAsyncKeyState(VK_CONTROL) & 0x8000))) { + if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { + Select_RotateTexture((float)point.y - m_ptLastCursor.y); + } + else if (GetAsyncKeyState(VK_SHIFT) & 0x8000) { + Select_ScaleTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y); + } + else { + Select_ShiftTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y); + } + } + else { + Cam_MouseMoved(point.x, r.bottom - 1 - point.y, nFlags); + } + + m_ptLastCursor = point; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) { + m_ptLastCursor = point; + OriginalMouseDown(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) { + OriginalMouseUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) { + OriginalMouseDown(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) { + OriginalMouseUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) { + OriginalMouseDown(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) { + OriginalMouseUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CWnd::OnCreate(lpCreateStruct) == -1) { + return -1; + } + + CDC *pDC = GetDC(); + HDC hDC = pDC->GetSafeHdc(); + + QEW_SetupPixelFormat(hDC, true); + + HFONT hfont = CreateFont( + 12, // logical height of font + 0, // logical average character width + 0, // angle of escapement + 0, // base-line orientation angle + 0, // font weight + 0, // italic attribute flag + 0, // underline attribute flag + 0, // strikeout attribute flag + 0, // character set identifier + 0, // output precision + 0, // clipping precision + 0, // output quality + FIXED_PITCH | FF_MODERN, // pitch and family + "Lucida Console" // pointer to typeface name string + ); + + if (!hfont) { + Error("couldn't create font"); + } + + HFONT hOldFont = (HFONT)SelectObject(hDC, hfont); + + wglMakeCurrent (hDC, win32.hGLRC); + + if ((g_qeglobals.d_font_list = qglGenLists(256)) == 0) { + common->Warning( "couldn't create font dlists" ); + } + + // create the bitmap display lists we're making images of glyphs 0 thru 255 + if ( !qwglUseFontBitmaps(hDC, 0, 255, g_qeglobals.d_font_list) ) { + common->Warning( "wglUseFontBitmaps failed (%d). Trying again.", GetLastError() ); + + // FIXME: This is really wacky, sometimes the first call fails, but calling it again makes it work + // This probably indicates there's something wrong somewhere else in the code, but I'm not sure what + if ( !qwglUseFontBitmaps(hDC, 0, 255, g_qeglobals.d_font_list) ) { + common->Warning( "wglUseFontBitmaps failed again (%d). Trying outlines.", GetLastError() ); + + if (!qwglUseFontOutlines(hDC, 0, 255, g_qeglobals.d_font_list, 0.0f, 0.1f, WGL_FONT_LINES, NULL)) { + common->Warning( "wglUseFontOutlines also failed (%d), no coordinate text will be visible.", GetLastError() ); + } + } + } + + SelectObject(hDC, hOldFont); + ReleaseDC(pDC); + + // indicate start of glyph display lists + qglListBase(g_qeglobals.d_font_list); + + // report OpenGL information + common->Printf("GL_VENDOR: %s\n", qglGetString(GL_VENDOR)); + common->Printf("GL_RENDERER: %s\n", qglGetString(GL_RENDERER)); + common->Printf("GL_VERSION: %s\n", qglGetString(GL_VERSION)); + common->Printf("GL_EXTENSIONS: %s\n", qglGetString(GL_EXTENSIONS)); + + return 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OriginalMouseUp(UINT nFlags, CPoint point) { + CRect r; + GetClientRect(r); + Cam_MouseUp(point.x, r.bottom - 1 - point.y, nFlags); + if (!(nFlags & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON))) { + ReleaseCapture(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OriginalMouseDown(UINT nFlags, CPoint point) { + // if (GetTopWindow()->GetSafeHwnd() != GetSafeHwnd()) BringWindowToTop(); + CRect r; + GetClientRect(r); + SetFocus(); + SetCapture(); + + // if (!(GetAsyncKeyState(VK_MENU) & 0x8000)) + Cam_MouseDown(point.x, r.bottom - 1 - point.y, nFlags); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_Init() { + // m_Camera.draw_mode = cd_texture; + m_Camera.origin[0] = 0.0f; + m_Camera.origin[1] = 20.0f; + m_Camera.origin[2] = 72.0f; + m_Camera.color[0] = 0.3f; + m_Camera.color[1] = 0.3f; + m_Camera.color[2] = 0.3f; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_BuildMatrix() { + float xa, ya; + float matrix[4][4]; + int i; + + xa = ((renderMode) ? -m_Camera.angles[PITCH] : m_Camera.angles[PITCH]) * idMath::M_DEG2RAD; + ya = m_Camera.angles[YAW] * idMath::M_DEG2RAD; + + // the movement matrix is kept 2d + m_Camera.forward[0] = cos(ya); + m_Camera.forward[1] = sin(ya); + m_Camera.right[0] = m_Camera.forward[1]; + m_Camera.right[1] = -m_Camera.forward[0]; + + qglGetFloatv(GL_PROJECTION_MATRIX, &matrix[0][0]); + + for (i = 0; i < 3; i++) { + m_Camera.vright[i] = matrix[i][0]; + m_Camera.vup[i] = matrix[i][1]; + m_Camera.vpn[i] = matrix[i][2]; + } + + m_Camera.vright.Normalize(); + m_Camera.vup.Normalize(); + m_Camera.vpn.Normalize(); + InitCull(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void CCamWnd::Cam_ChangeFloor(bool up) { + brush_t *b; + float d, bestd, current; + idVec3 start, dir; + + start[0] = m_Camera.origin[0]; + start[1] = m_Camera.origin[1]; + start[2] = HUGE_DISTANCE; + dir[0] = dir[1] = 0; + dir[2] = -1; + + current = HUGE_DISTANCE - (m_Camera.origin[2] - 72); + if (up) { + bestd = 0; + } + else { + bestd = HUGE_DISTANCE*2; + } + + for (b = active_brushes.next; b != &active_brushes; b = b->next) { + if (!Brush_Ray(start, dir, b, &d)) { + continue; + } + + if (up && d < current && d > bestd) { + bestd = d; + } + + if (!up && d > current && d < bestd) { + bestd = d; + } + } + + if (bestd == 0 || bestd == HUGE_DISTANCE*2) { + return; + } + + m_Camera.origin[2] += current - bestd; + Sys_UpdateWindows(W_CAMERA | W_Z_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_PositionDrag() { + int x, y; + Sys_GetCursorPos(&x, &y); + if (x != m_ptCursor.x || y != m_ptCursor.y) { + x -= m_ptCursor.x; + VectorMA(m_Camera.origin, x, m_Camera.vright, m_Camera.origin); + y -= m_ptCursor.y; + m_Camera.origin[2] -= y; + SetCursorPos(m_ptCursor.x, m_ptCursor.y); + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY); + } +} + +void CCamWnd::Cam_MouseLook() { + CPoint current; + + GetCursorPos(¤t); + if (current.x != m_ptCursor.x || current.y != m_ptCursor.y) { + + current.x -= m_ptCursor.x; + current.y -= m_ptCursor.y; + + m_Camera.angles[PITCH] -= (float)((float)current.y * 0.25f); + m_Camera.angles[YAW] -= (float)((float)current.x * 0.25f); + + SetCursorPos(m_ptCursor.x, m_ptCursor.y); + + Cam_BuildMatrix(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_MouseControl(float dtime) { + int xl, xh; + int yl, yh; + float xf, yf; + if (g_PrefsDlg.m_nMouseButtons == 2) { + if (m_nCambuttonstate != (MK_RBUTTON | MK_SHIFT)) { + return; + } + } + else { + if (m_nCambuttonstate != MK_RBUTTON) { + return; + } + } + + xf = (float)(m_ptButton.x - m_Camera.width / 2) / (m_Camera.width / 2); + yf = (float)(m_ptButton.y - m_Camera.height / 2) / (m_Camera.height / 2); + + xl = m_Camera.width / 3; + xh = xl * 2; + yl = m_Camera.height / 3; + yh = yl * 2; + + // common->Printf("xf-%f yf-%f xl-%i xh-i% yl-i% yh-i%\n",xf,yf,xl,xh,yl,yh); +#if 0 + + // strafe + if (buttony < yl && (buttonx < xl || buttonx > xh)) { + VectorMA(camera.origin, xf * dtime * g_nMoveSpeed, camera.right, camera.origin); + } + else +#endif + { + xf *= 1.0f - idMath::Fabs(yf); + if ( xf < 0.0f ) { + xf += 0.1f; + if ( xf > 0.0f ) { + xf = 0.0f; + } + } + else { + xf -= 0.1f; + if ( xf < 0.0f ) { + xf = 0.0f; + } + } + + VectorMA(m_Camera.origin, yf * dtime * g_PrefsDlg.m_nMoveSpeed, m_Camera.forward, m_Camera.origin); + m_Camera.angles[YAW] += xf * -dtime * g_PrefsDlg.m_nAngleSpeed; + } + + Cam_BuildMatrix(); + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); + g_pParentWnd->PostMessage(WM_TIMER, 0, 0); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_MouseDown(int x, int y, int buttons) { + idVec3 dir; + float f, r, u; + int i; + + // calc ray direction + u = (float)(y - m_Camera.height / 2) / (m_Camera.width / 2); + r = (float)(x - m_Camera.width / 2) / (m_Camera.width / 2); + f = 1; + + for (i = 0; i < 3; i++) { + dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u; + } + + dir.Normalize(); + + GetCursorPos(&m_ptCursor); + + m_nCambuttonstate = buttons; + m_ptButton.x = x; + m_ptButton.y = y; + + // + // LBUTTON = manipulate selection shift-LBUTTON = select middle button = grab + // texture ctrl-middle button = set entire brush to texture ctrl-shift-middle + // button = set single face to texture + // + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + if + ( + (buttons == MK_LBUTTON) || + (buttons == (MK_LBUTTON | MK_SHIFT)) || + (buttons == (MK_LBUTTON | MK_CONTROL)) || + (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) || + (buttons == nMouseButton) || + (buttons == (nMouseButton | MK_SHIFT)) || + (buttons == (nMouseButton | MK_CONTROL)) || + (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL)) + ) { + if (g_PrefsDlg.m_nMouseButtons == 2 && (buttons == (MK_RBUTTON | MK_SHIFT))) { + Cam_MouseControl( 0.1f ); + } + else { + // something global needs to track which window is responsible for stuff + Patch_SetView(W_CAMERA); + Drag_Begin(x, y, buttons, m_Camera.vright, m_Camera.vup, m_Camera.origin, dir); + } + + return; + } + + if ( buttons == MK_RBUTTON ) { + Cam_MouseControl( 0.1f ); + return; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_MouseUp(int x, int y, int buttons) { + m_nCambuttonstate = 0; + Drag_MouseUp(buttons); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::Cam_MouseMoved(int x, int y, int buttons) { + m_nCambuttonstate = buttons; + if (!buttons) { + return; + } + + m_ptButton.x = x; + m_ptButton.y = y; + + if (buttons == (MK_RBUTTON | MK_CONTROL)) { + Cam_PositionDrag(); + Sys_UpdateWindows(W_XY | W_CAMERA | W_Z); + return; + } + else if ( buttons == (MK_RBUTTON | MK_CONTROL | MK_SHIFT) ) { + Cam_MouseLook(); + Sys_UpdateWindows(W_XY | W_CAMERA | W_Z); + return; + } + + GetCursorPos(&m_ptCursor); + + if (buttons & (MK_LBUTTON | MK_MBUTTON)) { + Drag_MouseMoved(x, y, buttons); + Sys_UpdateWindows(W_XY | W_CAMERA | W_Z); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::InitCull() { + int i; + + VectorSubtract(m_Camera.vpn, m_Camera.vright, m_vCull1); + VectorAdd(m_Camera.vpn, m_Camera.vright, m_vCull2); + + for (i = 0; i < 3; i++) { + if (m_vCull1[i] > 0) { + m_nCullv1[i] = 3 + i; + } + else { + m_nCullv1[i] = i; + } + + if (m_vCull2[i] > 0) { + m_nCullv2[i] = 3 + i; + } + else { + m_nCullv2[i] = i; + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CCamWnd::CullBrush(brush_t *b, bool cubicOnly) { + int i; + idVec3 point; + float d; + + if ( b->forceVisibile ) { + return false; + } + + if (g_PrefsDlg.m_bCubicClipping) { + + float distance = g_PrefsDlg.m_nCubicScale * 64; + + idVec3 mid; + for (int i = 0; i < 3; i++) { + mid[i] = (b->mins[i] + ((b->maxs[i] - b->mins[i]) / 2)); + } + + point = mid - m_Camera.origin; + if (point.Length() > distance) { + return true; + } + + } + + if (cubicOnly) { + return false; + } + + for (i = 0; i < 3; i++) { + point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i]; + } + + d = DotProduct(point, m_vCull1); + if (d < -1) { + return true; + } + + for (i = 0; i < 3; i++) { + point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i]; + } + + d = DotProduct(point, m_vCull2); + if (d < -1) { + return true; + } + + return false; +} + +#if 0 + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::DrawLightRadius(brush_t *pBrush) { + // if lighting + int nRadius = Brush_LightRadius(pBrush); + if (nRadius > 0) { + Brush_SetLightColor(pBrush); + qglEnable(GL_BLEND); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable(GL_BLEND); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } +} +#endif + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void setGLMode(int mode) { + switch (mode) + { + case cd_wire: + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + globalImages->BindNull(); + qglDisable(GL_BLEND); + qglDisable(GL_DEPTH_TEST); + qglColor3f( 1.0f, 1.0f, 1.0f ); + break; + + case cd_solid: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel(GL_FLAT); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + globalImages->BindNull(); + qglDisable(GL_BLEND); + qglEnable(GL_DEPTH_TEST); + qglDepthFunc(GL_LEQUAL); + break; + + case cd_texture: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel(GL_FLAT); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_BLEND); + qglEnable(GL_DEPTH_TEST); + qglDepthFunc(GL_LEQUAL); + break; + + case cd_blend: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel(GL_FLAT); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_DEPTH_TEST); + qglEnable(GL_BLEND); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + } +} + + +extern void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label); +void DrawAxial(face_t *selFace) { + if (g_bAxialMode) { + idVec3 points[4]; + + for (int j = 0; j < selFace->face_winding->GetNumPoints(); j++) { + glLabeledPoint(idVec4(1, 1, 1, 1), (*selFace->face_winding)[j].ToVec3(), 3, va("%i", j)); + } + + ValidateAxialPoints(); + points[0] = (*selFace->face_winding)[g_axialAnchor].ToVec3(); + VectorMA (points[0], 1, selFace->plane, points[0]); + VectorMA (points[0], 4, selFace->plane, points[1]); + points[3] = (*selFace->face_winding)[g_axialDest].ToVec3(); + VectorMA (points[3], 1, selFace->plane, points[3]); + VectorMA (points[3], 4, selFace->plane, points[2]); + glLabeledPoint(idVec4(1, 0, 0, 1), points[1], 3, "Anchor"); + glLabeledPoint(idVec4(1, 1, 0, 1), points[2], 3, "Dest"); + qglBegin (GL_LINE_STRIP); + qglVertex3fv( points[0].ToFloatPtr() ); + qglVertex3fv( points[1].ToFloatPtr() ); + qglVertex3fv( points[2].ToFloatPtr() ); + qglVertex3fv( points[3].ToFloatPtr() ); + qglEnd(); + } +} + + +/* + ======================================================================================================================= + Cam_Draw + ======================================================================================================================= + */ +void CCamWnd::SetProjectionMatrix() { + float xfov = 90; + float yfov = 2 * atan((float)m_Camera.height / m_Camera.width) * idMath::M_RAD2DEG; +#if 0 + float screenaspect = (float)m_Camera.width / m_Camera.height; + qglLoadIdentity(); + gluPerspective(yfov, screenaspect, 2, 8192); +#else + float xmin, xmax, ymin, ymax; + float width, height; + float zNear; + float projectionMatrix[16]; + + // + // set up projection matrix + // + zNear = r_znear.GetFloat(); + + ymax = zNear * tan( yfov * idMath::PI / 360.0f ); + ymin = -ymax; + + xmax = zNear * tan( xfov * idMath::PI / 360.0f ); + xmin = -xmax; + + width = xmax - xmin; + height = ymax - ymin; + + projectionMatrix[0] = 2 * zNear / width; + projectionMatrix[4] = 0; + projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0 + projectionMatrix[12] = 0; + + projectionMatrix[1] = 0; + projectionMatrix[5] = 2 * zNear / height; + projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 + projectionMatrix[13] = 0; + + // this is the far-plane-at-infinity formulation + projectionMatrix[2] = 0; + projectionMatrix[6] = 0; + projectionMatrix[10] = -1; + projectionMatrix[14] = -2 * zNear; + + projectionMatrix[3] = 0; + projectionMatrix[7] = 0; + projectionMatrix[11] = -1; + projectionMatrix[15] = 0; + + qglLoadMatrixf( projectionMatrix ); +#endif +} + +void CCamWnd::Cam_Draw() { + brush_t *brush; + face_t *face; + + // float yfov; + int i; + + if (!active_brushes.next) { + return; // not valid yet + } + + // set the sound origin for both simple draw and rendered mode + // the editor uses opposite pitch convention + idMat3 axis = idAngles( -m_Camera.angles.pitch, m_Camera.angles.yaw, m_Camera.angles.roll ).ToMat3(); + g_qeglobals.sw->PlaceListener( m_Camera.origin, axis, 0, Sys_Milliseconds(), "Undefined" ); + + if (renderMode) { + Cam_Render(); + } + + qglViewport(0, 0, m_Camera.width, m_Camera.height); + qglScissor(0, 0, m_Camera.width, m_Camera.height); + qglClearColor(g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0); + + if (!renderMode) { + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + qglDisable(GL_LIGHTING); + qglMatrixMode(GL_PROJECTION); + + SetProjectionMatrix(); + + qglRotatef(-90, 1, 0, 0); // put Z going up + qglRotatef(90, 0, 0, 1); // put Z going up + qglRotatef(m_Camera.angles[0], 0, 1, 0); + qglRotatef(-m_Camera.angles[1], 0, 0, 1); + qglTranslatef(-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); + + Cam_BuildMatrix(); + + for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) { + + if ( CullBrush(brush, false) ) { + continue; + } + + if ( FilterBrush(brush) ) { + continue; + } + + if (renderMode) { + if (!(entityMode && brush->owner->eclass->fixedsize)) { + continue; + } + } + + setGLMode(m_Camera.draw_mode); + Brush_Draw(brush); + } + + + //qglDepthMask ( 1 ); // Ok, write now + qglMatrixMode(GL_PROJECTION); + + qglTranslatef(g_qeglobals.d_select_translate[0],g_qeglobals.d_select_translate[1],g_qeglobals.d_select_translate[2]); + + brush_t *pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes; + + if (!renderMode) { + // draw normally + for (brush = pList->next; brush != pList; brush = brush->next) { + if (brush->pPatch) { + continue; + } + setGLMode(m_Camera.draw_mode); + Brush_Draw(brush, true); + } + } + + // blend on top + + setGLMode(m_Camera.draw_mode); + qglDisable(GL_LIGHTING); + qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2], 0.25f ); + qglEnable(GL_BLEND); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + globalImages->BindNull(); + for (brush = pList->next; brush != pList; brush = brush->next) { + if (brush->pPatch || brush->modelHandle > 0) { + Brush_Draw(brush, true); + + // DHM - Nerve:: patch display lists/models mess with the state + qglEnable(GL_BLEND); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2], 0.25f ); + globalImages->BindNull(); + continue; + } + + if ( brush->owner->eclass->entityModel ) { + continue; + } + + for (face = brush->brush_faces; face; face = face->next) { + Face_Draw(face); + } + } + + int nCount = g_ptrSelectedFaces.GetSize(); + + if (!renderMode) { + for (int i = 0; i < nCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + Face_Draw(selFace); + DrawAxial(selFace); + } + } + + // non-zbuffered outline + qglDisable(GL_BLEND); + qglDisable(GL_DEPTH_TEST); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + if (renderMode) { + qglColor3f(1, 0, 0); + for (int i = 0; i < nCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + Face_Draw(selFace); + } + } + + qglColor3f(1, 1, 1); + for (brush = pList->next; brush != pList; brush = brush->next) { + if (brush->pPatch || brush->modelHandle > 0) { + continue; + } + + for (face = brush->brush_faces; face; face = face->next) { + Face_Draw(face); + } + } + // edge / vertex flags + if (g_qeglobals.d_select_mode == sel_vertex) { + qglPointSize(4); + qglColor3f(0, 1, 0); + qglBegin(GL_POINTS); + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + qglVertex3fv( g_qeglobals.d_points[i].ToFloatPtr() ); + } + + qglEnd(); + qglPointSize(1); + } + else if (g_qeglobals.d_select_mode == sel_edge) { + float *v1, *v2; + + qglPointSize(4); + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for (i = 0; i < g_qeglobals.d_numedges; i++) { + v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr(); + v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr(); + qglVertex3f( (v1[0] + v2[0]) * 0.5f, (v1[1] + v2[1]) * 0.5f, (v1[2] + v2[2]) * 0.5f ); + } + + qglEnd(); + qglPointSize(1); + } + + g_splineList->draw (static_cast(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)); + + if ( g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint) ) { + g_qeglobals.selectObject->drawSelection(); + } + + // draw pointfile + qglEnable(GL_DEPTH_TEST); + + DrawPathLines(); + + if (g_qeglobals.d_pointfile_display_list) { + Pointfile_Draw(); + } + + // + // bind back to the default texture so that we don't have problems elsewhere + // using/modifying texture maps between contexts + // + globalImages->BindNull(); + + qglFinish(); + QE_CheckOpenGLForErrors(); + + if (!renderMode) { + // clean up any deffered tri's + R_ToggleSmpFrame(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnSize(UINT nType, int cx, int cy) { + CWnd::OnSize(nType, cx, cy); + + CRect rect; + GetClientRect(rect); + m_Camera.width = rect.right; + m_Camera.height = rect.bottom; + InvalidateRect(NULL, false); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); +} + +// +// ======================================================================================================================= +// Timo brush primitive texture shifting, using camera view to select translations:: +// ======================================================================================================================= +// +void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y) { +/* + idVec3 texS, texT; + idVec3 viewX, viewY; + int XS, XT, YS, YT; + int outS, outT; +#ifdef _DEBUG + if (!g_qeglobals.m_bBrushPrimitMode) { + common->Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n"); + return; + } +#endif + // compute face axis base + //ComputeAxisBase(f->plane.Normal(), texS, texT); + + // compute camera view vectors + VectorCopy(m_Camera.vup, viewY); + VectorCopy(m_Camera.vright, viewX); + + // compute best vectors + //ComputeBest2DVector(viewX, texS, texT, XS, XT); + //ComputeBest2DVector(viewY, texS, texT, YS, YT); + + // check this is not a degenerate case + if ((XS == YS) && (XT == YT)) + { +#ifdef _DEBUG + common->Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n"); +#endif + // forget it + Select_ShiftTexture_BrushPrimit(f, x, y, false); + return; + } + + // compute best fitted translation in face axis base + outS = XS * x + YS * y; + outT = XT * x + YT * y; + + // call actual texture shifting code + Select_ShiftTexture_BrushPrimit(f, outS, outT, false); +*/ +} + + +bool IsBModel(brush_t *b) { + const char *v = ValueForKey( b->owner, "model" ); + if (v && *v) { + const char *n = ValueForKey( b->owner, "name"); + return (stricmp( n, v ) == 0); + } + return false; +} + +/* +================ +BuildEntityRenderState + +Creates or updates modelDef and lightDef for an entity +================ +*/ +int Brush_ToTris(brush_t *brush, idTriList *tris, idMatList *mats, bool models, bool bmodel); + +void CCamWnd::BuildEntityRenderState( entity_t *ent, bool update) { + const char *v; + idDict spawnArgs; + const char *name = NULL; + + Entity_UpdateSoundEmitter( ent ); + + // delete the existing def if we aren't creating a brand new world + if ( !update ) { + if ( ent->lightDef >= 0 ) { + g_qeglobals.rw->FreeLightDef( ent->lightDef ); + ent->lightDef = -1; + } + + if ( ent->modelDef >= 0 ) { + g_qeglobals.rw->FreeEntityDef( ent->modelDef ); + ent->modelDef = -1; + } + } + + // if an entity doesn't have any brushes at all, don't do anything + if ( ent->brushes.onext == &ent->brushes ) { + return; + } + + // if the brush isn't displayed (filtered or culled), don't do anything + if (FilterBrush(ent->brushes.onext)) { + return; + } + + spawnArgs = ent->epairs; + if (ent->eclass->defArgs.FindKey("model")) { + spawnArgs.Set("model", ent->eclass->defArgs.GetString("model")); + } + + // any entity can have a model + name = ValueForKey( ent, "name" ); + v = spawnArgs.GetString("model"); + if ( v && *v ) { + renderEntity_t refent; + + refent.referenceSound = ent->soundEmitter; + + if ( !stricmp( name, v ) ) { + // build the model from brushes + idTriList tris(1024); + idMatList mats(1024); + + for (brush_t *b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { + Brush_ToTris( b, &tris, &mats, false, true); + } + + if ( ent->modelDef >= 0 ) { + g_qeglobals.rw->FreeEntityDef( ent->modelDef ); + ent->modelDef = -1; + } + + idRenderModel *bmodel = renderModelManager->FindModel( name ); + + if ( bmodel ) { + renderModelManager->RemoveModel( bmodel ); + renderModelManager->FreeModel( bmodel ); + } + + bmodel = renderModelManager->AllocModel(); + + bmodel->InitEmpty( name ); + + // add the surfaces to the renderModel + modelSurface_t surf; + for ( int i = 0 ; i < tris.Num() ; i++ ) { + surf.geometry = tris[i]; + surf.shader = mats[i]; + bmodel->AddSurface( surf ); + } + + bmodel->FinishSurfaces(); + + renderModelManager->AddModel( bmodel ); + + // FIXME: brush entities + gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &refent ); + + ent->modelDef = g_qeglobals.rw->AddEntityDef( &refent ); + + } else { + // use the game's epair parsing code so + // we can use the same renderEntity generation + gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &refent ); + idRenderModelMD5 *md5 = dynamic_cast( refent.hModel ); + if (md5) { + idStr str; + spawnArgs.GetString("anim", "idle", str); + refent.numJoints = md5->NumJoints(); + if ( update && refent.joints ) { + Mem_Free16( refent.joints ); + } + refent.joints = ( idJointMat * )Mem_Alloc16( refent.numJoints * sizeof( *refent.joints ) ); + const idMD5Anim *anim = gameEdit->ANIM_GetAnimFromEntityDef(spawnArgs.GetString("classname"), str); + int frame = spawnArgs.GetInt("frame") + 1; + if ( frame < 1 ) { + frame = 1; + } + const idVec3 &offset = gameEdit->ANIM_GetModelOffsetFromEntityDef( spawnArgs.GetString("classname") ); + gameEdit->ANIM_CreateAnimFrame( md5, anim, refent.numJoints, refent.joints, ( frame * 1000 ) / 24, offset, false ); + } + if (ent->modelDef >= 0) { + g_qeglobals.rw->FreeEntityDef( ent->modelDef ); + } + ent->modelDef = g_qeglobals.rw->AddEntityDef( &refent ); + } + } + + // check for lightdefs + if (!(ent->eclass->nShowFlags & ECLASS_LIGHT)) { + return; + } + + if ( spawnArgs.GetBool( "start_off" ) ) { + return; + } + // use the game's epair parsing code so + // we can use the same renderLight generation + + renderLight_t lightParms; + + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &lightParms ); + lightParms.referenceSound = ent->soundEmitter; + + if (update && ent->lightDef >= 0) { + g_qeglobals.rw->UpdateLightDef( ent->lightDef, &lightParms ); + } else { + if (ent->lightDef >= 0) { + g_qeglobals.rw->FreeLightDef(ent->lightDef); + } + ent->lightDef = g_qeglobals.rw->AddLightDef( &lightParms ); + } + +} + +void Tris_ToOBJ(const char *outFile, idTriList *tris, idMatList *mats) { + idFile *f = fileSystem->OpenExplicitFileWrite( outFile ); + if ( f ) { + char out[1024]; + strcpy(out, outFile); + StripExtension(out); + + idList matNames; + int i, j, k; + int indexBase = 1; + idStr lastMaterial(""); + int matCount = 0; + //idStr basePath = cvarSystem->GetCVarString( "fs_savepath" ); + f->Printf( "mtllib %s.mtl\n", out ); + for (i = 0; i < tris->Num(); i++) { + srfTriangles_t *tri = (*tris)[i]; + for (j = 0; j < tri->numVerts; j++) { + f->Printf( "v %f %f %f\n", tri->verts[j].xyz.x, tri->verts[j].xyz.z, -tri->verts[j].xyz.y ); + } + for (j = 0; j < tri->numVerts; j++) { + f->Printf( "vt %f %f\n", tri->verts[j].st.x, 1.0f - tri->verts[j].st.y ); + } + for (j = 0; j < tri->numVerts; j++) { + f->Printf( "vn %f %f %f\n", tri->verts[j].normal.x, tri->verts[j].normal.y, tri->verts[j].normal.z ); + } + + if (stricmp( (*mats)[i]->GetName(), lastMaterial)) { + lastMaterial = (*mats)[i]->GetName(); + + bool found = false; + for (k = 0; k < matNames.Num(); k++) { + if ( idStr::Icmp(matNames[k]->c_str(), lastMaterial.c_str()) == 0 ) { + found = true; + // f->Printf( "usemtl m%i\n", k ); + f->Printf( "usemtl %s\n", lastMaterial.c_str() ); + break; + } + } + + if (!found) { + // f->Printf( "usemtl m%i\n", matCount++ ); + f->Printf( "usemtl %s\n", lastMaterial.c_str() ); + matNames.Append(new idStr(lastMaterial)); + } + } + + for (int j = 0; j < tri->numIndexes; j += 3) { + int i1, i2, i3; + i1 = tri->indexes[j+2] + indexBase; + i2 = tri->indexes[j+1] + indexBase; + i3 = tri->indexes[j] + indexBase; + f->Printf( "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i1,i1,i1, i2,i2,i2, i3,i3,i3 ); + } + + indexBase += tri->numVerts; + + } + fileSystem->CloseFile( f ); + + strcat(out, ".mtl"); + f = fileSystem->OpenExplicitFileWrite( out ); + if (f) { + for (k = 0; k < matNames.Num(); k++) { + // This presumes the diffuse tga name matches the material name + f->Printf( "newmtl %s\n\tNs 0\n\td 1\n\tillum 2\n\tKd 0 0 0 \n\tKs 0.22 0.22 0.22 \n\tKa 0 0 0 \n\tmap_Kd %s/base/%s.tga\n\n\n", matNames[k]->c_str(), "z:/d3xp", matNames[k]->c_str() ); + } + fileSystem->CloseFile( f ); + } + + } +} + +int Brush_TransformModel(brush_t *brush, idTriList *tris, idMatList *mats) { + int ret = 0; + if (brush->modelHandle > 0 ) { + idRenderModel *model = brush->modelHandle; + if (model) { + float a = FloatForKey(brush->owner, "angle"); + float s, c; + //FIXME: support full rotation matrix + bool matrix = false; + if (a) { + s = sin( DEG2RAD(a) ); + c = cos( DEG2RAD(a) ); + } + idMat3 mat; + if (GetMatrixForKey(brush->owner, "rotation", mat)) { + matrix = true; + } + + + for (int i = 0; i < model->NumSurfaces() ; i++) { + const modelSurface_t *surf = model->Surface( i ); + srfTriangles_t *tri = surf->geometry; + srfTriangles_t *tri2 = R_CopyStaticTriSurf(tri); + for (int j = 0; j < tri2->numVerts; j++) { + idVec3 v; + if (matrix) { + v = tri2->verts[j].xyz * brush->owner->rotation + brush->owner->origin; + } else { + v = tri2->verts[j].xyz; + VectorAdd(v, brush->owner->origin, v); + float x = v[0]; + float y = v[1]; + if (a) { + float x2 = (((x - brush->owner->origin[0]) * c) - ((y - brush->owner->origin[1]) * s)) + brush->owner->origin[0]; + float y2 = (((x - brush->owner->origin[0]) * s) + ((y - brush->owner->origin[1]) * c)) + brush->owner->origin[1]; + x = x2; + y = y2; + } + v[0] = x; + v[1] = y; + } + tri2->verts[j].xyz = v; + } + tris->Append(tri2); + mats->Append( surf->shader ); + } + return model->NumSurfaces(); + } + } + return ret; +} + + +#define MAX_TRI_SURFACES 16384 +int Brush_ToTris(brush_t *brush, idTriList *tris, idMatList *mats, bool models, bool bmodel) { + int i, j; + srfTriangles_t *tri; + // + // patches + // + if (brush->modelHandle > 0 ) { + if (!models) { + return 0; + } else { + return Brush_TransformModel(brush, tris, mats); + } + } + + int numSurfaces = 0; + + if ( brush->owner->eclass->fixedsize && !brush->entityModel) { + return NULL; + } + + if ( brush->pPatch ) { + patchMesh_t *pm; + int width, height; + + pm = brush->pPatch; + + // build a patch mesh + idSurface_Patch *cp = new idSurface_Patch( pm->width * 6, pm->height * 6 ); + cp->SetSize( pm->width, pm->height ); + for ( i = 0; i < pm->width; i++ ) { + for ( j = 0; j < pm->height; j++ ) { + (*cp)[j*cp->GetWidth()+i].xyz = pm->ctrl(i, j).xyz; + (*cp)[j*cp->GetWidth()+i].st = pm->ctrl(i, j).st; + } + } + + // subdivide it + if ( pm->explicitSubdivisions ) { + cp->SubdivideExplicit( pm->horzSubdivisions, pm->vertSubdivisions, true ); + } else { + cp->Subdivide( DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_LENGTH, true ); + } + width = cp->GetWidth(); + height = cp->GetHeight(); + + // convert to srfTriangles + tri = R_AllocStaticTriSurf(); + tri->numVerts = width * height; + tri->numIndexes = 6 * ( width - 1 ) * ( height - 1 ); + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + for ( i = 0 ; i < tri->numVerts ; i++ ) { + tri->verts[i] = (*cp)[i]; + if (bmodel) { + tri->verts[i].xyz -= brush->owner->origin; + } + } + + tri->numIndexes = 0; + for ( i = 1 ; i < width ; i++ ) { + for ( j = 1 ; j < height ; j++ ) { + tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i; + tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i - 1; + tri->indexes[tri->numIndexes++] = j * width + i - 1; + + tri->indexes[tri->numIndexes++] = j * width + i; + tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i; + tri->indexes[tri->numIndexes++] = j * width + i - 1; + } + } + + delete cp; + + tris->Append(tri); + mats->Append(pm->d_texture); + //surfaces[numSurfaces] = tri; + //materials[numSurfaces] = pm->d_texture; + return 1; + } + + // + // normal brush + // + for ( face_t *face = brush->brush_faces ; face; face = face->next ) { + idWinding *w; + + w = face->face_winding; + if (!w) { + continue; // freed or degenerate face + } + + tri = R_AllocStaticTriSurf(); + tri->numVerts = w->GetNumPoints(); + tri->numIndexes = ( w->GetNumPoints() - 2 ) * 3; + R_AllocStaticTriSurfVerts( tri, tri->numVerts ); + R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); + + for ( i = 0 ; i < tri->numVerts ; i++ ) { + + tri->verts[i].Clear(); + + tri->verts[i].xyz[0] = (*w)[i][0]; + tri->verts[i].xyz[1] = (*w)[i][1]; + tri->verts[i].xyz[2] = (*w)[i][2]; + + if ( bmodel ) { + tri->verts[i].xyz -= brush->owner->origin; + } + + tri->verts[i].st[0] = (*w)[i][3]; + tri->verts[i].st[1] = (*w)[i][4]; + + tri->verts[i].normal = face->plane.Normal(); + } + + tri->numIndexes = 0; + for ( i = 2 ; i < w->GetNumPoints() ; i++ ) { + tri->indexes[tri->numIndexes++] = 0; + tri->indexes[tri->numIndexes++] = i-1; + tri->indexes[tri->numIndexes++] = i; + } + + tris->Append(tri); + mats->Append(face->d_texture); + numSurfaces++; + } + + return numSurfaces; +} + +void Select_ToOBJ() { + int i; + CFileDialog dlgFile(FALSE, "obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Wavefront object files (*.obj)|*.obj||", g_pParentWnd); + if (dlgFile.DoModal() == IDOK) { + idTriList tris(1024); + idMatList mats(1024); + + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + + if ( b->hiddenBrush ) { + continue; + } + + if (FilterBrush(b)) { + continue; + } + + Brush_ToTris(b, &tris, &mats, true, false); + } + + Tris_ToOBJ(dlgFile.GetPathName().GetBuffer(0), &tris, &mats); + + for( i = 0; i < tris.Num(); i++ ) { + R_FreeStaticTriSurf( tris[i] ); + } + tris.Clear(); + } +} + +void Select_ToCM() { + CFileDialog dlgFile( FALSE, "lwo, ase", NULL, 0, "(*.lwo)|*.lwo|(*.ase)|*.ase|(*.ma)|*.ma||", g_pParentWnd ); + + if ( dlgFile.DoModal() == IDOK ) { + idMapEntity *mapEnt; + idMapPrimitive *p; + idStr name; + + name = fileSystem->OSPathToRelativePath( dlgFile.GetPathName() ); + name.BackSlashesToSlashes(); + + mapEnt = new idMapEntity(); + mapEnt->epairs.Set( "name", name.c_str() ); + + for ( brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next ) { + + if ( b->hiddenBrush ) { + continue; + } + + if ( FilterBrush( b ) ) { + continue; + } + + p = BrushToMapPrimitive( b, b->owner->origin ); + if ( p ) { + mapEnt->AddPrimitive( p ); + } + } + + collisionModelManager->WriteCollisionModelForMapEntity( mapEnt, name.c_str() ); + + delete mapEnt; + } +} + + +/* +================= +BuildRendererState + +Builds models, lightdefs, and modeldefs for the current editor data +so it can be rendered by the game renderSystem +================= +*/ +void CCamWnd::BuildRendererState() { + renderEntity_t worldEntity; + entity_t *ent; + brush_t *brush; + + FreeRendererState(); + + // the renderWorld holds all the references and defs + g_qeglobals.rw->InitFromMap( NULL ); + + // create the raw model for all the brushes + int numBrushes = 0; + int numSurfaces = 0; + + // the renderModel for the world holds all the geometry that isn't in an entity + worldModel = renderModelManager->AllocModel(); + worldModel->InitEmpty( "EditorWorldModel" ); + + for ( brush_t *brushList = &active_brushes ; brushList ; + brushList = (brushList == &active_brushes) ? &selected_brushes : NULL ) { + + for (brush = brushList->next; brush != brushList; brush = brush->next) { + + if ( brush->hiddenBrush ) { + continue; + } + + if (FilterBrush(brush)) { + continue; + } + + if (CullBrush(brush, true)) { + continue; + } + + idTriList tris(1024); + idMatList mats(1024); + + if (!IsBModel(brush)) { + numSurfaces += Brush_ToTris( brush, &tris, &mats, false, false ); + } + + // add the surfaces to the renderModel + modelSurface_t surf; + for ( int i = 0 ; i < tris.Num() ; i++ ) { + surf.geometry = tris[i]; + surf.shader = mats[i]; + worldModel->AddSurface( surf ); + } + + numBrushes++; + } + } + + // bound and clean the triangles + worldModel->FinishSurfaces(); + + // the worldEntity just has the handle for the worldModel + memset( &worldEntity, 0, sizeof( worldEntity ) ); + worldEntity.hModel = worldModel; + worldEntity.axis = mat3_default; + worldEntity.shaderParms[0] = 1; + worldEntity.shaderParms[1] = 1; + worldEntity.shaderParms[2] = 1; + worldEntity.shaderParms[3] = 1; + + worldModelDef = g_qeglobals.rw->AddEntityDef( &worldEntity ); + + // create the light and model entities exactly the way the game code would + for ( ent = entities.next ; ent != &entities ; ent = ent->next ) { + if ( ent->brushes.onext == &ent->brushes ) { + continue; + } + + if (CullBrush(ent->brushes.onext, true)) { + continue; + } + + if (Map_IsBrushFiltered(ent->brushes.onext)) { + continue; + } + + BuildEntityRenderState( ent, false ); + } + + //common->Printf("Render data used %d brushes\n", numBrushes); + worldDirty = false; + UpdateCaption(); +} + +/* +=============================== +CCamWnd::UpdateRenderEntities + + Creates a new entity state list + returns true if a repaint is needed +=============================== +*/ +bool CCamWnd::UpdateRenderEntities() { + + if (rebuildMode) { + return false; + } + + bool ret = false; + for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) { + BuildEntityRenderState( ent, (ent->lightDef != -1 || ent->modelDef != -1 || ent->soundEmitter ) ? true : false ); + if (ret == false && ent->modelDef || ent->lightDef) { + ret = true; + } + } + return ret; +} + +/* +============================ +CCamWnd::FreeRendererState + + Frees the render state data +============================ +*/ +void CCamWnd::FreeRendererState() { + + for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) { + if (ent->lightDef >= 0) { + g_qeglobals.rw->FreeLightDef( ent->lightDef ); + ent->lightDef = -1; + } + + if (ent->modelDef >= 0) { + renderEntity_t *refent = const_cast(g_qeglobals.rw->GetRenderEntity( ent->modelDef )); + if ( refent ) { + if ( refent->callbackData ) { + Mem_Free( refent->callbackData ); + refent->callbackData = NULL; + } + if ( refent->joints ) { + Mem_Free16(refent->joints); + refent->joints = NULL; + } + } + g_qeglobals.rw->FreeEntityDef( ent->modelDef ); + ent->modelDef = -1; + } + } + + if ( worldModel ) { + renderModelManager->FreeModel( worldModel ); + worldModel = NULL; + } + +} + + +/* +======================== +CCamWnd::UpdateCaption + + updates the caption based on rendermode and whether the render mode needs updated +======================== +*/ +void CCamWnd::UpdateCaption() { + + idStr strCaption; + + if (worldDirty) { + strCaption = "*"; + } + // FIXME: + strCaption += (renderMode) ? "RENDER" : "CAM"; + if (renderMode) { + strCaption += (rebuildMode) ? " (Realtime)" : ""; + strCaption += (entityMode) ? " +lights" : ""; + strCaption += (selectMode) ? " +selected" : ""; + strCaption += (animationMode) ? " +anim" : ""; + } + strCaption += (soundMode) ? " +snd" : ""; + SetWindowText(strCaption); +} + +/* +=========================== +CCamWnd::ToggleRenderMode + + Toggles the render mode +=========================== +*/ +void CCamWnd::ToggleRenderMode() { + renderMode ^= 1; + UpdateCaption(); +} + +/* +=========================== +CCamWnd::ToggleRebuildMode + + Toggles the rebuild mode +=========================== +*/ +void CCamWnd::ToggleRebuildMode() { + rebuildMode ^= 1; + UpdateCaption(); +} + +/* +=========================== +CCamWnd::ToggleEntityMode + + Toggles the entity mode +=========================== +*/ +void CCamWnd::ToggleEntityMode() { + entityMode ^= 1; + UpdateCaption(); +} + + +/* +=========================== +CCamWnd::ToggleRenderMode + + Toggles the render mode +=========================== +*/ +void CCamWnd::ToggleAnimationMode() { + animationMode ^= 1; + if (animationMode) { + SetTimer(0, 10, NULL); + } else { + KillTimer(0); + } + UpdateCaption(); +} + +/* +=========================== +CCamWnd::ToggleSoundMode + + Toggles the sound mode +=========================== +*/ +void CCamWnd::ToggleSoundMode() { + soundMode ^= 1; + + UpdateCaption(); + + for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) { + Entity_UpdateSoundEmitter( ent ); + } +} + +/* +=========================== +CCamWnd::ToggleRenderMode + + Toggles the render mode +=========================== +*/ +void CCamWnd::ToggleSelectMode() { + selectMode ^= 1; + UpdateCaption(); +} + +/* +========================= +CCamWnd::MarkWorldDirty + + marks the render world as dirty +========================= +*/ +void CCamWnd::MarkWorldDirty() { + worldDirty = true; + UpdateCaption(); +} + + +/* +========================= +CCamWnd::DrawEntityData + + Draws entity data ( experimental ) +========================= +*/ +extern void glBox(idVec4 &color, idVec3 &point, float size); + +void CCamWnd::DrawEntityData() { + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + + SetProjectionMatrix(); + + qglRotatef(-90, 1, 0, 0); // put Z going up + qglRotatef(90, 0, 0, 1); // put Z going up + qglRotatef(m_Camera.angles[0], 0, 1, 0); + qglRotatef(-m_Camera.angles[1], 0, 0, 1); + qglTranslatef(-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); + + Cam_BuildMatrix(); + + if (!(entityMode || selectMode)) { + return; + } + + qglDisable(GL_BLEND); + qglDisable(GL_DEPTH_TEST); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + globalImages->BindNull(); + idVec3 color(0, 1, 0); + qglColor3fv( color.ToFloatPtr() ); + + brush_t *brushList = &active_brushes; + int pass = 0; + while (brushList) { + for (brush_t *brush = brushList->next; brush != brushList; brush = brush->next) { + + if (CullBrush(brush, true)) { + continue; + } + + if (FilterBrush(brush)) { + continue; + } + + if ((pass == 1 && selectMode) || (entityMode && pass == 0 && brush->owner->lightDef >= 0)) { + Brush_DrawXY(brush, 0, true, true); + } + + } + brushList = (brushList == &active_brushes) ? &selected_brushes : NULL; + color.x = 1; + color.y = 0; + pass++; + qglColor3fv( color.ToFloatPtr() ); + } + +} + + +/* + ======================================================================================================================= + Cam_Render + + This used the renderSystem to draw a fully lit view of the world + ======================================================================================================================= + */ +void CCamWnd::Cam_Render() { + + renderView_t refdef; + CPaintDC dc(this); // device context for painting + + + if (!active_brushes.next) { + return; // not valid yet + } + + if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) { + common->Printf("ERROR: wglMakeCurrent failed..\n "); + common->Printf("Please restart " EDITOR_WINDOWTEXT " if the camera view is not working\n"); + return; + } + + // save the editor state + //qglPushAttrib( GL_ALL_ATTRIB_BITS ); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglScissor( 0, 0, m_Camera.width, m_Camera.height ); + qglClear( GL_COLOR_BUFFER_BIT ); + + // qwglSwapBuffers(dc.m_hDC); + + // create the model, using explicit normals + if ( rebuildMode && worldDirty ) { + BuildRendererState(); + } + + // render it + renderSystem->BeginFrame( m_Camera.width, m_Camera.height ); + + memset( &refdef, 0, sizeof( refdef ) ); + refdef.vieworg = m_Camera.origin; + + // the editor uses opposite pitch convention + refdef.viewaxis = idAngles( -m_Camera.angles.pitch, m_Camera.angles.yaw, m_Camera.angles.roll ).ToMat3(); + + refdef.width = SCREEN_WIDTH; + refdef.height = SCREEN_HEIGHT; + refdef.fov_x = 90; + refdef.fov_y = 2 * atan((float)m_Camera.height / m_Camera.width) * idMath::M_RAD2DEG; + + // only set in animation mode to give a consistent look + if (animationMode) { + refdef.time = eventLoop->Milliseconds(); + } + + g_qeglobals.rw->RenderScene( &refdef ); + + int frontEnd, backEnd; + + renderSystem->EndFrame( &frontEnd, &backEnd ); +//common->Printf( "front:%i back:%i\n", frontEnd, backEnd ); + + //qglPopAttrib(); + //DrawEntityData(); + + //qwglSwapBuffers(dc.m_hDC); + // get back to the editor state + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + Cam_BuildMatrix(); +} + + +void CCamWnd::OnTimer(UINT nIDEvent) +{ + if (animationMode || nIDEvent == 1) { + Sys_UpdateWindows(W_CAMERA); + } + if (nIDEvent == 1) { + KillTimer(1); + } + + if (!animationMode ) { + KillTimer(0); + } +} + + +void CCamWnd::UpdateCameraView() { + if (QE_SingleBrush(true, true)) { + brush_t *b = selected_brushes.next; + if (b->owner->eclass->nShowFlags & ECLASS_CAMERAVIEW) { + // find the entity that targets this + const char *name = ValueForKey(b->owner, "name"); + entity_t *ent = FindEntity("target", name); + if (ent) { + if (!saveValid) { + saveOrg = m_Camera.origin; + saveAng = m_Camera.angles; + saveValid = true; + } + idVec3 v = b->owner->origin - ent->origin; + v.Normalize(); + idAngles ang = v.ToMat3().ToAngles(); + ang.pitch = -ang.pitch; + ang.roll = 0.0f; + SetView( ent->origin, ang ); + Cam_BuildMatrix(); + Sys_UpdateWindows( W_CAMERA ); + return; + } + } + } + if (saveValid) { + SetView(saveOrg, saveAng); + Cam_BuildMatrix(); + Sys_UpdateWindows(W_CAMERA); + saveValid = false; + } +} + diff --git a/tools/radiant/CamWnd.h b/tools/radiant/CamWnd.h new file mode 100644 index 000000000..d8c473fb0 --- /dev/null +++ b/tools/radiant/CamWnd.h @@ -0,0 +1,196 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_CAMWND_H__44B4BA03_781B_11D1_B53C_00AA00A410FC__INCLUDED_) +#define AFX_CAMWND_H__44B4BA03_781B_11D1_B53C_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +typedef enum +{ + cd_wire, + cd_solid, + cd_texture, + cd_light, + cd_blend +} camera_draw_mode; + +typedef struct +{ + int width, height; + + idVec3 origin; + idAngles angles; + + camera_draw_mode draw_mode; + + idVec3 color; // background + + idVec3 forward, right, up; // move matrix + idVec3 vup, vpn, vright; // view matrix +} camera_t; + + +///////////////////////////////////////////////////////////////////////////// +// CCamWnd window +class CXYWnd; + +class CCamWnd : public CWnd +{ + DECLARE_DYNCREATE(CCamWnd); +// Construction +public: + CCamWnd(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCamWnd) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + void ShiftTexture_BrushPrimit(face_t *f, int x, int y); + CXYWnd* m_pXYFriend; + void SetXYFriend(CXYWnd* pWnd); + virtual ~CCamWnd(); + camera_t& Camera(){return m_Camera;}; + void Cam_MouseControl(float dtime); + void Cam_ChangeFloor(bool up); + void BuildRendererState(); + void ToggleRenderMode(); + void ToggleRebuildMode(); + void ToggleEntityMode(); + void ToggleSelectMode(); + void ToggleAnimationMode(); + void ToggleSoundMode(); + void SetProjectionMatrix(); + void UpdateCameraView(); + + void BuildEntityRenderState( entity_t *ent, bool update ); + bool GetRenderMode() { + return renderMode; + } + bool GetRebuildMode() { + return rebuildMode; + } + bool GetEntityMode() { + return entityMode; + } + bool GetAnimationMode() { + return animationMode; + } + bool GetSelectMode() { + return selectMode; + } + bool GetSoundMode() { + return soundMode; + } + + + bool UpdateRenderEntities(); + void MarkWorldDirty(); + + void SetView( const idVec3 &origin, const idAngles &angles ) { + m_Camera.origin = origin; + m_Camera.angles = angles; + } + +protected: + void Cam_Init(); + void Cam_BuildMatrix(); + void Cam_PositionDrag(); + void Cam_MouseLook(); + void Cam_MouseDown(int x, int y, int buttons); + void Cam_MouseUp (int x, int y, int buttons); + void Cam_MouseMoved (int x, int y, int buttons); + void InitCull(); + bool CullBrush (brush_t *b, bool cubicOnly); + void Cam_Draw(); + void Cam_Render(); + + // game renderer interaction + qhandle_t worldModelDef; + idRenderModel *worldModel; // createRawModel of the brush and patch geometry + bool worldDirty; + bool renderMode; + bool rebuildMode; + bool entityMode; + bool selectMode; + bool animationMode; + bool soundMode; + void FreeRendererState(); + void UpdateCaption(); + bool BuildBrushRenderData(brush_t *brush); + void DrawEntityData(); + + + camera_t m_Camera; + int m_nCambuttonstate; + CPoint m_ptButton; + CPoint m_ptCursor; + CPoint m_ptLastCursor; + face_t* m_pSide_select; + idVec3 m_vCull1; + idVec3 m_vCull2; + int m_nCullv1[3]; + int m_nCullv2[3]; + bool m_bClipMode; + idVec3 saveOrg; + idAngles saveAng; + bool saveValid; + + // Generated message map functions +protected: + void OriginalMouseDown(UINT nFlags, CPoint point); + void OriginalMouseUp(UINT nFlags, CPoint point); + //{{AFX_MSG(CCamWnd) + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnPaint(); + afx_msg void OnDestroy(); + afx_msg void OnClose(); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnTimer(UINT nIDEvent); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CAMWND_H__44B4BA03_781B_11D1_B53C_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/CameraTargetDlg.cpp b/tools/radiant/CameraTargetDlg.cpp new file mode 100644 index 000000000..30717d567 --- /dev/null +++ b/tools/radiant/CameraTargetDlg.cpp @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "CameraTargetDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CCameraTargetDlg dialog + + +CCameraTargetDlg::CCameraTargetDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCameraTargetDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CCameraTargetDlg) + m_nType = 0; + m_strName = _T(""); + //}}AFX_DATA_INIT +} + + +void CCameraTargetDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CCameraTargetDlg) + DDX_Radio(pDX, IDC_RADIO_FIXED, m_nType); + DDX_Text(pDX, IDC_EDIT_NAME, m_strName); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CCameraTargetDlg, CDialog) + //{{AFX_MSG_MAP(CCameraTargetDlg) + ON_COMMAND(ID_POPUP_NEWCAMERA_FIXED, OnPopupNewcameraFixed) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CCameraTargetDlg message handlers + +void CCameraTargetDlg::OnPopupNewcameraFixed() +{ + // TODO: Add your command handler code here + +} diff --git a/tools/radiant/CameraTargetDlg.h b/tools/radiant/CameraTargetDlg.h new file mode 100644 index 000000000..6fae36094 --- /dev/null +++ b/tools/radiant/CameraTargetDlg.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_CAMERATARGETDLG_H__DE6597C1_1F63_4835_8949_5D2D5F208C6B__INCLUDED_) +#define AFX_CAMERATARGETDLG_H__DE6597C1_1F63_4835_8949_5D2D5F208C6B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// CameraTargetDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CCameraTargetDlg dialog + +class CCameraTargetDlg : public CDialog +{ +// Construction +public: + CCameraTargetDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CCameraTargetDlg) + enum { IDD = IDD_DLG_CAMERATARGET }; + int m_nType; + CString m_strName; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCameraTargetDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CCameraTargetDlg) + afx_msg void OnPopupNewcameraFixed(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CAMERATARGETDLG_H__DE6597C1_1F63_4835_8949_5D2D5F208C6B__INCLUDED_) diff --git a/tools/radiant/CapDialog.cpp b/tools/radiant/CapDialog.cpp new file mode 100644 index 000000000..c743bfcb6 --- /dev/null +++ b/tools/radiant/CapDialog.cpp @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "CapDialog.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CCapDialog dialog + + +CCapDialog::CCapDialog(CWnd* pParent /*=NULL*/) + : CDialog(CCapDialog::IDD, pParent) +{ + //{{AFX_DATA_INIT(CCapDialog) + m_nCap = 0; + //}}AFX_DATA_INIT +} + + +void CCapDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CCapDialog) + DDX_Radio(pDX, IDC_RADIO_CAP, m_nCap); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CCapDialog, CDialog) + //{{AFX_MSG_MAP(CCapDialog) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CCapDialog message handlers diff --git a/tools/radiant/CapDialog.h b/tools/radiant/CapDialog.h new file mode 100644 index 000000000..31b55d616 --- /dev/null +++ b/tools/radiant/CapDialog.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_CAPDIALOG_H__10637162_2BD2_11D2_B030_00AA00A410FC__INCLUDED_) +#define AFX_CAPDIALOG_H__10637162_2BD2_11D2_B030_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// CapDialog.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CCapDialog dialog + +class CCapDialog : public CDialog +{ +// Construction +public: + static enum {BEVEL = 0, ENDCAP, IBEVEL, IENDCAP}; + CCapDialog(CWnd* pParent = NULL); // standard constructor + + int getCapType() {return m_nCap;}; +// Dialog Data + //{{AFX_DATA(CCapDialog) + enum { IDD = IDD_DIALOG_CAP }; + int m_nCap; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCapDialog) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CCapDialog) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CAPDIALOG_H__10637162_2BD2_11D2_B030_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/CommandsDlg.cpp b/tools/radiant/CommandsDlg.cpp new file mode 100644 index 000000000..69d860e8f --- /dev/null +++ b/tools/radiant/CommandsDlg.cpp @@ -0,0 +1,107 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "CommandsDlg.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CCommandsDlg dialog + + +CCommandsDlg::CCommandsDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCommandsDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CCommandsDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CCommandsDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CCommandsDlg) + DDX_Control(pDX, IDC_LIST_COMMANDS, m_lstCommands); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CCommandsDlg, CDialog) + //{{AFX_MSG_MAP(CCommandsDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CCommandsDlg message handlers + +BOOL CCommandsDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_lstCommands.SetTabStops(120); + int nCount = g_nCommandCount; + + CFile fileout; + fileout.Open("c:/commandlist.txt", CFile::modeCreate | CFile::modeWrite); + for (int n = 0; n < nCount; n++) + { + CString strLine; + char c = g_Commands[n].m_nKey; + CString strKeys = CString( c ); + for (int k = 0; k < g_nKeyCount; k++) + { + if (g_Keys[k].m_nVKKey == g_Commands[n].m_nKey) + { + strKeys = g_Keys[k].m_strName; + break; + } + } + CString strMod(""); + if (g_Commands[n].m_nModifiers & RAD_SHIFT) + strMod = "Shift"; + if (g_Commands[n].m_nModifiers & RAD_ALT) + strMod += (strMod.GetLength() > 0) ? " + Alt" : "Alt"; + if (g_Commands[n].m_nModifiers & RAD_CONTROL) + strMod += (strMod.GetLength() > 0) ? " + Control" : "Control"; + if (strMod.GetLength() > 0) + { + strMod += " + "; + } + strLine.Format("%s \t%s%s", g_Commands[n].m_strCommand, strMod, strKeys); + m_lstCommands.AddString(strLine); + + strLine.Format("%s \t\t\t%s%s", g_Commands[n].m_strCommand, strMod, strKeys); + + fileout.Write(strLine, strLine.GetLength()); + fileout.Write("\r\n", 2); + } + fileout.Close(); + return TRUE; +} + diff --git a/tools/radiant/CommandsDlg.h b/tools/radiant/CommandsDlg.h new file mode 100644 index 000000000..1b909c9e3 --- /dev/null +++ b/tools/radiant/CommandsDlg.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_COMMANDSDLG_H__C80F6E42_8531_11D1_B548_00AA00A410FC__INCLUDED_) +#define AFX_COMMANDSDLG_H__C80F6E42_8531_11D1_B548_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// CommandsDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CCommandsDlg dialog + +class CCommandsDlg : public CDialog +{ +// Construction +public: + CCommandsDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CCommandsDlg) + enum { IDD = IDD_DLG_COMMANDLIST }; + CListBox m_lstCommands; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCommandsDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CCommandsDlg) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_COMMANDSDLG_H__C80F6E42_8531_11D1_B548_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/CommentsDlg.cpp b/tools/radiant/CommentsDlg.cpp new file mode 100644 index 000000000..83a86476d --- /dev/null +++ b/tools/radiant/CommentsDlg.cpp @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "CommentsDlg.h" + + +// CCommentsDlg dialog + +IMPLEMENT_DYNAMIC(CCommentsDlg, CDialog) +CCommentsDlg::CCommentsDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCommentsDlg::IDD, pParent) + , strName(_T("")) + , strPath(_T("")) + , strComments(_T("")) +{ +} + +CCommentsDlg::~CCommentsDlg() +{ +} + +void CCommentsDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_EDIT_NAME, strName); + DDX_Text(pDX, IDC_EDIT_PATH, strPath); + DDX_Text(pDX, IDC_EDIT_COMMENTS, strComments); +} + + +BEGIN_MESSAGE_MAP(CCommentsDlg, CDialog) +END_MESSAGE_MAP() + + +// CCommentsDlg message handlers diff --git a/tools/radiant/CommentsDlg.h b/tools/radiant/CommentsDlg.h new file mode 100644 index 000000000..051d7123e --- /dev/null +++ b/tools/radiant/CommentsDlg.h @@ -0,0 +1,44 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once +#include "afxwin.h" + + +// CCommentsDlg dialog + +class CCommentsDlg : public CDialog +{ + DECLARE_DYNAMIC(CCommentsDlg) + +public: + CCommentsDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CCommentsDlg(); + +// Dialog Data + enum { IDD = IDD_DIALOG_COMMENTS }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + CString strName; + CString strPath; + CString strComments; +}; diff --git a/tools/radiant/ConsoleDlg.cpp b/tools/radiant/ConsoleDlg.cpp new file mode 100644 index 000000000..312789a7b --- /dev/null +++ b/tools/radiant/ConsoleDlg.cpp @@ -0,0 +1,252 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "ConsoleDlg.h" + + +// CConsoleDlg dialog + +IMPLEMENT_DYNCREATE(CConsoleDlg, CDialog) +CConsoleDlg::CConsoleDlg(CWnd* pParent /*=NULL*/) + : CDialog(CConsoleDlg::IDD) +{ + currentHistoryPosition = -1; + currentCommand = ""; + saveCurrentCommand = true; +} + +CConsoleDlg::~CConsoleDlg() +{ +} + +void CConsoleDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT_CONSOLE, editConsole); + DDX_Control(pDX, IDC_EDIT_INPUT, editInput); +} + +void CConsoleDlg::AddText( const char *msg ) { + idStr work; + CString work2; + + work = msg; + work.RemoveColors(); + work = CEntityDlg::TranslateString( work.c_str() ); + editConsole.GetWindowText( work2 ); + int len = work2.GetLength(); + if ( len + work.Length() > (int)editConsole.GetLimitText() ) { + work2 = work2.Right( editConsole.GetLimitText() * 0.75 ); + len = work2.GetLength(); + editConsole.SetWindowText(work2); + } + editConsole.SetSel( len, len ); + editConsole.ReplaceSel( work ); +} + + +BEGIN_MESSAGE_MAP(CConsoleDlg, CDialog) + ON_WM_SIZE() + ON_WM_SETFOCUS() + ON_WM_ACTIVATE() +END_MESSAGE_MAP() + + +// CConsoleDlg message handlers + +void CConsoleDlg::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + + if (editInput.GetSafeHwnd() == NULL) { + return; + } + + CRect rect, crect; + GetWindowRect(rect); + editInput.GetWindowRect(crect); + + editInput.SetWindowPos(NULL, 4, rect.Height() - 4 - crect.Height(), rect.Width() - 8, crect.Height(), SWP_SHOWWINDOW); + editConsole.SetWindowPos(NULL, 4, 4, rect.Width() - 8, rect.Height() - crect.Height() - 8, SWP_SHOWWINDOW); +} + +BOOL CConsoleDlg::PreTranslateMessage(MSG* pMsg) +{ + + if (pMsg->hwnd == editInput.GetSafeHwnd()) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE ) { + Select_Deselect(); + g_pParentWnd->SetFocus (); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + ExecuteCommand(); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE ) { + if (pMsg->wParam == VK_ESCAPE) { + g_pParentWnd->GetCamera()->SetFocus(); + Select_Deselect(); + } + + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_UP ) { + //save off the current in-progress command so we can get back to it + if ( saveCurrentCommand == true ) { + CString str; + editInput.GetWindowText ( str ); + currentCommand = str.GetBuffer ( 0 ); + saveCurrentCommand = false; + } + + if ( consoleHistory.Num () > 0 ) { + editInput.SetWindowText ( consoleHistory[currentHistoryPosition] ); + + int selLocation = consoleHistory[currentHistoryPosition].Length (); + editInput.SetSel ( selLocation , selLocation + 1); +} + + if ( currentHistoryPosition > 0) { + --currentHistoryPosition; + } + + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DOWN ) { + int selLocation = 0; + if ( currentHistoryPosition < consoleHistory.Num () - 1 ) { + ++currentHistoryPosition; + editInput.SetWindowText ( consoleHistory[currentHistoryPosition] ); + selLocation = consoleHistory[currentHistoryPosition].Length (); + } + else { + editInput.SetWindowText ( currentCommand ); + selLocation = currentCommand.Length (); + currentCommand.Clear (); + saveCurrentCommand = true; + } + + editInput.SetSel ( selLocation , selLocation + 1); + + return TRUE; + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB ) { + common->Printf ( "Command History\n----------------\n" ); + for ( int i = 0 ; i < consoleHistory.Num ();i++ ) +{ + common->Printf ( "[cmd %d]: %s\n" , i , consoleHistory[i].c_str() ); + } + common->Printf ( "----------------\n" ); + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_NEXT) { + editConsole.LineScroll ( 10 ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_PRIOR ) { + editConsole.LineScroll ( -10 ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_HOME ) { + editConsole.LineScroll ( -editConsole.GetLineCount() ); + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_END ) { + editConsole.LineScroll ( editConsole.GetLineCount() ); + } + } + + return CDialog::PreTranslateMessage(pMsg); +} + +void CConsoleDlg::OnSetFocus(CWnd* pOldWnd) { + CDialog::OnSetFocus(pOldWnd); + editInput.SetFocus(); +} + +void CConsoleDlg::SetConsoleText ( const idStr& text ) { + editInput.Clear (); + editInput.SetWindowText ( text.c_str() ); +} + +void CConsoleDlg::ExecuteCommand ( const idStr& cmd ) { + CString str; + if ( cmd.Length() > 0 ) { + str = cmd; + } + else { + editInput.GetWindowText(str); + } + + if ( str != "" ) { + editInput.SetWindowText(""); + common->Printf("%s\n", str.GetBuffer(0)); + + //avoid adding multiple identical commands in a row + int index = consoleHistory.Num (); + + if ( index == 0 || str.GetBuffer(0) != consoleHistory[index-1]) { + //keep the history to 16 commands, removing the oldest command + if ( consoleHistory.Num () > 16 ) { + consoleHistory.RemoveIndex ( 0 ); + } + currentHistoryPosition = consoleHistory.Append ( str.GetBuffer (0) ); + } + else { + currentHistoryPosition = consoleHistory.Num () - 1; + } + + currentCommand.Clear (); + + bool propogateCommand = true; + + //process some of our own special commands + if ( str.CompareNoCase ( "clear" ) == 0) { + editConsole.SetSel ( 0 , -1 ); + editConsole.Clear (); + } + else if ( str.CompareNoCase ( "edit" ) == 0) { + propogateCommand = false; + } + if ( propogateCommand ) { + cmdSystem->BufferCommandText( CMD_EXEC_NOW, str ); + } + + Sys_UpdateWindows(W_ALL); + } +} + +void CConsoleDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) +{ + CDialog::OnActivate(nState, pWndOther, bMinimized); + + if ( nState == WA_ACTIVE || nState == WA_CLICKACTIVE ) + { + editInput.SetFocus(); + } +} diff --git a/tools/radiant/ConsoleDlg.h b/tools/radiant/ConsoleDlg.h new file mode 100644 index 000000000..8a9870798 --- /dev/null +++ b/tools/radiant/ConsoleDlg.h @@ -0,0 +1,57 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once +#include "afxwin.h" + + +// CConsoleDlg dialog + +class CConsoleDlg : public CDialog +{ + DECLARE_DYNCREATE(CConsoleDlg) + +public: + CConsoleDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CConsoleDlg(); + +// Dialog Data + enum { IDD = IDD_DIALOG_CONSOLE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + CEdit editConsole; + CEdit editInput; + void AddText(const char *msg); + void SetConsoleText ( const idStr& text ); + void ExecuteCommand ( const idStr& cmd = "" ); + + idStr consoleStr; + idStrList consoleHistory; + idStr currentCommand; + int currentHistoryPosition; + bool saveCurrentCommand; + + afx_msg void OnSize(UINT nType, int cx, int cy); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); +}; diff --git a/tools/radiant/CurveDlg.cpp b/tools/radiant/CurveDlg.cpp new file mode 100644 index 000000000..ac16c60be --- /dev/null +++ b/tools/radiant/CurveDlg.cpp @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "CurveDlg.h" + + +// CCurveDlg dialog + +IMPLEMENT_DYNAMIC(CCurveDlg, CDialog) +CCurveDlg::CCurveDlg(CWnd* pParent /*=NULL*/) + : CDialog(CCurveDlg::IDD, pParent) +{ +} + +CCurveDlg::~CCurveDlg() +{ +} + +void CCurveDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO_CURVES, comboCurve); +} + +void CCurveDlg::OnOK() { + UpdateData(TRUE); + CString str; + comboCurve.GetWindowText( str ); + strCurveType = str; + CDialog::OnOK(); +} + +BEGIN_MESSAGE_MAP(CCurveDlg, CDialog) +END_MESSAGE_MAP() + + +// CCurveDlg message handlers diff --git a/tools/radiant/CurveDlg.h b/tools/radiant/CurveDlg.h new file mode 100644 index 000000000..dbe0db480 --- /dev/null +++ b/tools/radiant/CurveDlg.h @@ -0,0 +1,42 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + + +// CCurveDlg dialog + +class CCurveDlg : public CDialog +{ + DECLARE_DYNAMIC(CCurveDlg) + +public: + CCurveDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CCurveDlg(); + +// Dialog Data + enum { IDD = IDD_DIALOG_NEWCURVE }; + + idStr strCurveType; +protected: + CComboBox comboCurve; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual void OnOK(); + + DECLARE_MESSAGE_MAP() +}; diff --git a/tools/radiant/DRAG.CPP b/tools/radiant/DRAG.CPP new file mode 100644 index 000000000..67331136d --- /dev/null +++ b/tools/radiant/DRAG.CPP @@ -0,0 +1,754 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "splines.h" + +/* drag either multiple brushes, or select plane points from a single brush. */ +bool g_moveOnly = false; +bool drag_ok; +idVec3 drag_xvec; +idVec3 drag_yvec; + +static int buttonstate; +int pressx, pressy; +static idVec3 pressdelta; +static idVec3 vPressStart; +static int buttonx, buttony; + +// int num_move_points; float *move_points[1024]; +int lastx, lasty; + +bool drag_first; + +/* +================ +AxializeVector +================ +*/ +static void AxializeVector( idVec3 &v ) { + idVec3 a; + float o; + int i; + + if (!v[0] && !v[1]) { + return; + } + + if (!v[1] && !v[2]) { + return; + } + + if (!v[0] && !v[2]) { + return; + } + + for (i = 0; i < 3; i++) { + a[i] = idMath::Fabs(v[i]); + } + + if (a[0] > a[1] && a[0] > a[2]) { + i = 0; + } + else if (a[1] > a[0] && a[1] > a[2]) { + i = 1; + } + else { + i = 2; + } + + o = v[i]; + VectorCopy(vec3_origin, v); + if (o < 0) { + v[i] = -1; + } + else { + v[i] = 1; + } +} + +extern bool UpdateActiveDragPoint(const idVec3 &move); +extern void SetActiveDrag(CDragPoint *p); + +/* +================ +Draw_Setup +================ +*/ +static void Drag_Setup( int x, int y, int buttons, + const idVec3 &xaxis, const idVec3 &yaxis, const idVec3 &origin, const idVec3 &dir ) { + qertrace_t t; + face_t *f; + + drag_first = true; + + VectorCopy(vec3_origin, pressdelta); + pressx = x; + pressy = y; + + VectorCopy(xaxis, drag_xvec); + AxializeVector(drag_xvec); + VectorCopy(yaxis, drag_yvec); + AxializeVector(drag_yvec); + + if (g_qeglobals.d_select_mode == sel_addpoint) { + if (g_qeglobals.selectObject) { + g_qeglobals.selectObject->addPoint(origin); + } + else { + g_qeglobals.d_select_mode = sel_brush; + } + + return; + } + + if (g_qeglobals.d_select_mode == sel_editpoint) { + + g_Inspectors->entityDlg.SelectCurvePointByRay( origin, dir, buttons ); + + if ( g_qeglobals.d_num_move_points ) { + drag_ok = true; + } + + Sys_UpdateWindows(W_ALL); + + return; + } + + if (g_qeglobals.d_select_mode == sel_curvepoint) { + SelectCurvePointByRay(origin, dir, buttons); + + if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_area) { + drag_ok = true; + } + + Sys_UpdateWindows(W_ALL); + + Undo_Start("drag curve point"); + Undo_AddBrushList(&selected_brushes); + + return; + } + else { + g_qeglobals.d_num_move_points = 0; + } + + if (selected_brushes.next == &selected_brushes) { + // + // in this case a new brush is created when the dragging takes place in the XYWnd, + // An useless undo is created when the dragging takes place in the CamWnd + // + Undo_Start("create brush"); + + Sys_Status("No selection to drag\n", 0); + return; + } + + if (g_qeglobals.d_select_mode == sel_vertex) { + + if ( radiant_entityMode.GetBool() ) { + return; + } + + SelectVertexByRay(origin, dir); + if (g_qeglobals.d_num_move_points) { + drag_ok = true; + Undo_Start("drag vertex"); + Undo_AddBrushList(&selected_brushes); + return; + } + } + + if (g_qeglobals.d_select_mode == sel_edge) { + + if ( radiant_entityMode.GetBool() ) { + return; + } + + SelectEdgeByRay(origin, dir); + if (g_qeglobals.d_num_move_points) { + drag_ok = true; + Undo_Start("drag edge"); + Undo_AddBrushList(&selected_brushes); + return; + } + } + + // check for direct hit first + t = Test_Ray(origin, dir, true); + SetActiveDrag(t.point); + if (t.point) { + drag_ok = true; + + // point was hit + return; + } + + if (t.selected) { + drag_ok = true; + + Undo_Start("drag selection"); + Undo_AddBrushList(&selected_brushes); + + if (buttons == (MK_LBUTTON | MK_CONTROL)) { + Sys_Status("Shear dragging face\n"); + Brush_SelectFaceForDragging(t.brush, t.face, true); + } + else if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) { + Sys_Status("Sticky dragging brush\n"); + for (f = t.brush->brush_faces; f; f = f->next) { + Brush_SelectFaceForDragging(t.brush, f, false); + } + } + else { + Sys_Status("Dragging entire selection\n"); + } + + return; + } + + if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge) { + return; + } + + if ( radiant_entityMode.GetBool() ) { + return; + } + + // check for side hit multiple brushes selected? + if (selected_brushes.next->next != &selected_brushes) { + // yes, special handling + bool bOK = ( g_PrefsDlg.m_bALTEdge ) ? ( ::GetAsyncKeyState( VK_MENU ) != 0 ) : true; + if (bOK) { + for (brush_t * pBrush = selected_brushes.next; pBrush != &selected_brushes; pBrush = pBrush->next) { + if (buttons & MK_CONTROL) { + Brush_SideSelect(pBrush, origin, dir, true); + } + else { + Brush_SideSelect(pBrush, origin, dir, false); + } + } + } + else { + Sys_Status("press ALT to drag multiple edges\n"); + return; + } + } + else { + // single select.. trying to drag fixed entities handle themselves and just move + if (buttons & MK_CONTROL) { + Brush_SideSelect(selected_brushes.next, origin, dir, true); + } + else { + Brush_SideSelect(selected_brushes.next, origin, dir, false); + } + } + + Sys_Status("Side stretch\n"); + drag_ok = true; + + Undo_Start("side stretch"); + Undo_AddBrushList(&selected_brushes); +} + +extern void Face_GetScale_BrushPrimit(face_t *face, float *s, float *t, float *rot); + +/* +================ +Drag_Begin +================ +*/ +void Drag_Begin( int x, int y, int buttons, + const idVec3 &xaxis, const idVec3 &yaxis, const idVec3 &origin, const idVec3 &dir ) { + qertrace_t t; + + drag_ok = false; + VectorCopy(vec3_origin, pressdelta); + VectorCopy(vec3_origin, vPressStart); + + drag_first = true; + + // shift LBUTTON = select entire brush + if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { + int nFlag = ( ::GetAsyncKeyState( VK_MENU ) != 0 ) ? SF_CYCLE : 0; + if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) { // extremely low chance of this happening from camera + Select_Ray(origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY + } + else { + Select_Ray(origin, dir, nFlag); + } + + return; + } + + // ctrl-shift LBUTTON = select single face + if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { + if ( radiant_entityMode.GetBool() ) { + return; + } + + // _D3XP disabled + //Select_Deselect( ( ::GetAsyncKeyState( VK_MENU ) == 0 ) ); + Select_Ray(origin, dir, SF_SINGLEFACE); + return; + } + + // LBUTTON + all other modifiers = manipulate selection + if (buttons & MK_LBUTTON) { + Drag_Setup(x, y, buttons, xaxis, yaxis, origin, dir); + return; + } + + if ( radiant_entityMode.GetBool() ) { + return; + } + + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + + // middle button = grab texture + if (buttons == nMouseButton) { + t = Test_Ray(origin, dir, false); + if (t.face) { + g_qeglobals.d_new_brush_bottom = t.brush->mins; + g_qeglobals.d_new_brush_top = t.brush->maxs; + + // use a local brushprimit_texdef fitted to a default 2x2 texture + brushprimit_texdef_t bp_local; + if (t.brush && t.brush->pPatch) { + texdef_t localtd; + memset(&bp_local.coords, 0, sizeof(bp_local.coords)); + bp_local.coords[0][0] = 1.0f; + bp_local.coords[1][1] = 1.0f; + localtd.SetName(t.brush->pPatch->d_texture->GetName()); + Texture_SetTexture(&localtd, &bp_local, false, true); + Select_CopyPatchTextureCoords ( t.brush->pPatch ); + } else { + Select_ProjectFaceOntoPatch( t.face ); + ConvertTexMatWithQTexture(&t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL); + Texture_SetTexture(&t.face->texdef, &bp_local, false, true); + } + UpdateSurfaceDialog(); + UpdatePatchInspector(); + UpdateLightInspector(); + } + else { + Sys_Status("Did not select a texture\n"); + } + + return; + } + + // ctrl-middle button = set entire brush to texture + if (buttons == (nMouseButton | MK_CONTROL)) { + t = Test_Ray(origin, dir, false); + if (t.brush) { + if (t.brush->brush_faces->texdef.name[0] == '(') { + Sys_Status("Can't change an entity texture\n"); + } + else { + Brush_SetTexture + ( + t.brush, + &g_qeglobals.d_texturewin.texdef, + &g_qeglobals.d_texturewin.brushprimit_texdef, + false + ); + Sys_UpdateWindows(W_ALL); + } + } + else { + Sys_Status("Didn't hit a btrush\n"); + } + + return; + } + + // ctrl-shift-middle button = set single face to texture + if (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL)) { + t = Test_Ray(origin, dir, false); + if (t.brush) { + if (t.brush->brush_faces->texdef.name[0] == '(') { + Sys_Status("Can't change an entity texture\n"); + } + else { + SetFaceTexdef + ( + t.brush, + t.face, + &g_qeglobals.d_texturewin.texdef, + &g_qeglobals.d_texturewin.brushprimit_texdef + ); + Brush_Build(t.brush); + Sys_UpdateWindows(W_ALL); + } + } + else { + Sys_Status("Didn't hit a btrush\n"); + } + + return; + } + + if (buttons == (nMouseButton | MK_SHIFT)) { + Sys_Status("Set brush face texture info\n"); + t = Test_Ray(origin, dir, false); + if (t.brush && !t.brush->owner->eclass->fixedsize) { +/* + if (t.brush->brush_faces->texdef.name[0] == '(') { + if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT) { + CString strBuff; + idMaterial *pTex = declManager->FindMaterial(g_qeglobals.d_texturewin.texdef.name); + if (pTex) { + idVec3 vColor = pTex->getColor(); + + float fLargest = 0.0f; + for (int i = 0; i < 3; i++) { + if (vColor[i] > fLargest) { + fLargest = vColor[i]; + } + } + + if (fLargest == 0.0f) { + vColor[0] = vColor[1] = vColor[2] = 1.0f; + } + else { + float fScale = 1.0f / fLargest; + for (int i = 0; i < 3; i++) { + vColor[i] *= fScale; + } + } + + strBuff.Format("%f %f %f", pTex->getColor().x, pTex->getColor().y, pTex->getColor().z); + SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0)); + Sys_UpdateWindows(W_ALL); + } + } + else { + Sys_Status("Can't select an entity brush face\n"); + } + } + + else { +*/ + // strcpy(t.face->texdef.name,g_qeglobals.d_texturewin.texdef.name); + t.face->texdef.SetName(g_qeglobals.d_texturewin.texdef.name); + Brush_Build(t.brush); + Sys_UpdateWindows(W_ALL); +// } + } + else { + Sys_Status("Didn't hit a brush\n"); + } + + return; + } +} + + +void Brush_GetBounds(brush_t *b, idVec3 &mins, idVec3 &maxs) { + int i; + + for (i = 0; i < 3; i++) { + mins[i] = 999999; + maxs[i] = -999999; + } + + for (i = 0; i < 3; i++) { + if (b->mins[i] < mins[i]) { + mins[i] = b->mins[i]; + } + + if (b->maxs[i] > maxs[i]) { + maxs[i] = b->maxs[i]; + } + } +} + + +/* +================ +MoveSelection +================ +*/ +static void MoveSelection( const idVec3 &orgMove ) { + int i, success; + brush_t *b; + CString strStatus; + idVec3 vTemp, vTemp2, end, move; + + move = orgMove; + + if (!move[0] && !move[1] && !move[2]) { + return; + } + + move[0] = (g_nScaleHow & SCALE_X) ? 0 : move[0]; + move[1] = (g_nScaleHow & SCALE_Y) ? 0 : move[1]; + move[2] = (g_nScaleHow & SCALE_Z) ? 0 : move[2]; + + if (g_pParentWnd->ActiveXY()->RotateMode() || g_bPatchBendMode) { + float fDeg = -move[2]; + float fAdj = move[2]; + int axis = 0; + if (g_pParentWnd->ActiveXY()->GetViewType() == XY) { + fDeg = -move[1]; + fAdj = move[1]; + axis = 2; + } + else if (g_pParentWnd->ActiveXY()->GetViewType() == XZ) { + fDeg = move[2]; + fAdj = move[2]; + axis = 1; + } + + g_pParentWnd->ActiveXY()->Rotation()[g_qeglobals.rotateAxis] += fAdj; + strStatus.Format + ( + "%s x:: %.1f y:: %.1f z:: %.1f", + (g_bPatchBendMode) ? "Bend angle" : "Rotation", + g_pParentWnd->ActiveXY()->Rotation()[0], + g_pParentWnd->ActiveXY()->Rotation()[1], + g_pParentWnd->ActiveXY()->Rotation()[2] + ); + g_pParentWnd->SetStatusText(2, strStatus); + + if (g_bPatchBendMode) { + Patch_SelectBendNormal(); + Select_RotateAxis(axis, fDeg * 2, false, true); + Patch_SelectBendAxis(); + Select_RotateAxis(axis, fDeg, false, true); + } + else { + Select_RotateAxis(g_qeglobals.rotateAxis, fDeg, false, true); + } + + return; + } + + if (g_pParentWnd->ActiveXY()->ScaleMode()) { + idVec3 v; + v[0] = v[1] = v[2] = 1.0f; + for (int i = 0; i < 3; i++) { + if ( move[i] > 0.0f ) { + v[i] = 1.1f; + } else if ( move[i] < 0.0f ) { + v[i] = 0.9f; + } + } + + Select_Scale(v.x, v.y, v.z); + Sys_UpdateWindows(W_ALL); + return; + } + + idVec3 vDistance; + VectorSubtract(pressdelta, vPressStart, vDistance); + strStatus.Format("Distance x: %.3f y: %.3f z: %.3f", vDistance[0], vDistance[1], vDistance[2]); + g_pParentWnd->SetStatusText(3, strStatus); + + // dragging only a part of the selection + if (UpdateActiveDragPoint(move)) { + UpdateLightInspector(); + return; + } + + // + // this is fairly crappy way to deal with curvepoint and area selection but it + // touches the smallest amount of code this way + // + if (g_qeglobals.d_num_move_points || g_qeglobals.d_num_move_planes || g_qeglobals.d_select_mode == sel_area) { + // area selection + if (g_qeglobals.d_select_mode == sel_area) { + VectorAdd(g_qeglobals.d_vAreaBR, move, g_qeglobals.d_vAreaBR); + return; + } + + // curve point selection + if (g_qeglobals.d_select_mode == sel_curvepoint) { + Patch_UpdateSelected(move); + return; + } + + // vertex selection + if (g_qeglobals.d_select_mode == sel_vertex) { + success = true; + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + success &= Brush_MoveVertex(selected_brushes.next, *g_qeglobals.d_move_points[0], move, end, true); + } + + // if (success) + VectorCopy(end, *g_qeglobals.d_move_points[0]); + return; + } + + // all other selection types + for (i = 0; i < g_qeglobals.d_num_move_points; i++) { + VectorAdd(*g_qeglobals.d_move_points[i], move, *g_qeglobals.d_move_points[i]); + } + + if ( g_qeglobals.d_select_mode == sel_editpoint ) { + g_Inspectors->entityDlg.UpdateEntityCurve(); + } + + // + // VectorScale(move, .5, move); for (i=0 ; inext) { + VectorCopy(b->maxs, vTemp); + VectorSubtract(vTemp, b->mins, vTemp); + Brush_Build(b); + for (i = 0; i < 3; i++) { + if + ( + b->mins[i] > b->maxs[i] || + b->maxs[i] - b->mins[i] > MAX_WORLD_SIZE || + b->maxs[i] - b->mins[i] == 0.0f + ) { + break; // dragged backwards or messed up + } + } + + if (i != 3) { + break; + } + + if (b->pPatch) { + VectorCopy(b->maxs, vTemp2); + VectorSubtract(vTemp2, b->mins, vTemp2); + VectorSubtract(vTemp2, vTemp, vTemp2); + + // if (!Patch_DragScale(b->nPatchID, vTemp2, move)) + if (!Patch_DragScale(b->pPatch, vTemp2, move)) { + b = NULL; + break; + } + } + } + + // if any of the brushes were crushed out of existance calcel the entire move + if (b != &selected_brushes) { + Sys_Status("Brush dragged backwards, move canceled\n"); + for (i = 0; i < g_qeglobals.d_num_move_points; i++) { + VectorSubtract(*g_qeglobals.d_move_points[i], move, *g_qeglobals.d_move_points[i]); + } + + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + Brush_Build(b); + } + } + } + else { + // + // reset face originals from vertex edit mode this is dirty, but unfortunately + // necessary because Brush_Build can remove windings + // + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + Brush_ResetFaceOriginals(b); + } + + Select_Move(move); + } +} + +/* +================ +Drag_MouseMoved +================ +*/ +void Drag_MouseMoved(int x, int y, int buttons) { + idVec3 move, delta; + int i; + + if (!buttons || !drag_ok) { + drag_ok = false; + return; + } + + // clear along one axis + if (buttons & MK_SHIFT) { + drag_first = false; + if (abs(x - pressx) > abs(y - pressy)) { + y = pressy; + } + else { + x = pressx; + } + } + + for (i = 0; i < 3; i++) { + move[i] = drag_xvec[i] * (x - pressx) + drag_yvec[i] * (y - pressy); + if (!g_PrefsDlg.m_bNoClamp) { + move[i] = floor(move[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + } + + VectorSubtract(move, pressdelta, delta); + VectorCopy(move, pressdelta); + + if (buttons & MK_CONTROL && g_pParentWnd->ActiveXY()->RotateMode()) { + for (i = 0; i < 3; i++) { + if (delta[i] != 0) { + if (delta[i] > 0) { + delta[i] = 15; + } + else { + delta[i] = -15; + } + } + } + } + + MoveSelection(delta); +} + +/* +================ +Drag_MouseUp +================ +*/ +void Drag_MouseUp(int nButtons) { + Sys_Status("drag completed.", 0); + + if (g_qeglobals.d_select_mode == sel_area) { + Patch_SelectAreaPoints(); + g_qeglobals.d_select_mode = sel_curvepoint; + Sys_UpdateWindows(W_ALL); + } + + if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2]) { + Select_Move(g_qeglobals.d_select_translate); + VectorCopy(vec3_origin, g_qeglobals.d_select_translate); + Sys_UpdateWindows(W_CAMERA); + } + + g_pParentWnd->SetStatusText(3, ""); + +/* + if (g_pParentWnd->GetCamera()->UpdateRenderEntities()) { + Sys_UpdateWindows(W_CAMERA); + } +*/ + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} diff --git a/tools/radiant/DialogInfo.cpp b/tools/radiant/DialogInfo.cpp new file mode 100644 index 000000000..ae8dee92a --- /dev/null +++ b/tools/radiant/DialogInfo.cpp @@ -0,0 +1,92 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "DialogInfo.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDialogInfo dialog +CDialogInfo g_dlgInfo; + +void ShowInfoDialog(const char* pText) +{ + if (g_dlgInfo.GetSafeHwnd()) + { + g_dlgInfo.m_wndInfo.SetWindowText(pText); + g_dlgInfo.ShowWindow(SW_SHOW); + } + else + { + g_dlgInfo.Create(IDD_DLG_INFORMATION); + g_dlgInfo.m_wndInfo.SetWindowText(pText); + g_dlgInfo.ShowWindow(SW_SHOW); + } + g_pParentWnd->SetFocus(); +} + +void HideInfoDialog() +{ + if (g_dlgInfo.GetSafeHwnd()) + g_dlgInfo.ShowWindow(SW_HIDE); +} + + +CDialogInfo::CDialogInfo(CWnd* pParent /*=NULL*/) + : CDialog(CDialogInfo::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogInfo) + //}}AFX_DATA_INIT +} + + +void CDialogInfo::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogInfo) + DDX_Control(pDX, IDC_EDIT1, m_wndInfo); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogInfo, CDialog) + //{{AFX_MSG_MAP(CDialogInfo) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogInfo message handlers + +BOOL CDialogInfo::OnInitDialog() +{ + CDialog::OnInitDialog(); + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/tools/radiant/DialogInfo.h b/tools/radiant/DialogInfo.h new file mode 100644 index 000000000..aa16b681b --- /dev/null +++ b/tools/radiant/DialogInfo.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_DIALOGINFO_H__81DF2A33_A552_11D1_B58E_00AA00A410FC__INCLUDED_) +#define AFX_DIALOGINFO_H__81DF2A33_A552_11D1_B58E_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// DialogInfo.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CDialogInfo dialog +void HideInfoDialog(); +void ShowInfoDialog(const char* pText); + +class CDialogInfo : public CDialog +{ +// Construction +public: + CDialogInfo(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CDialogInfo) + enum { IDD = IDD_DLG_INFORMATION }; + CEdit m_wndInfo; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDialogInfo) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDialogInfo) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DIALOGINFO_H__81DF2A33_A552_11D1_B58E_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/DialogTextures.cpp b/tools/radiant/DialogTextures.cpp new file mode 100644 index 000000000..6b59c5e23 --- /dev/null +++ b/tools/radiant/DialogTextures.cpp @@ -0,0 +1,1042 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "WaitDlg.h" +#include "DialogTextures.h" +#include "DialogInfo.h" +#include "EditViewDlg.h" + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent); +extern void Select_SetKeyVal(const char *key, const char *val); + +const char *CDialogTextures::TypeNames[] = { + "None", + "Textures", + "Materials", + "Models", + "Scripts", + "Sounds", + "SoundParent", + "Guis", + "Particles", + "Fx" +}; + +// +// ======================================================================================================================= +// CDialogTextures dialog +// ======================================================================================================================= +// +CDialogTextures::CDialogTextures(CWnd *pParent /* =NULL */ ) : + CDialog(CDialogTextures::IDD, pParent) { + setTexture = true; + ignoreCollapse = false; + mode = TEXTURES; + editMaterial = NULL; + editGui = ""; + //{{AFX_DATA_INIT(CDialogTextures) + //}}AFX_DATA_INIT +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::DoDataExchange(CDataExchange *pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogTextures) + DDX_Control(pDX, IDC_CHECK_HIDEROOT, m_chkHideRoot); + DDX_Control(pDX, IDC_REFRESH, m_btnRefresh); + DDX_Control(pDX, IDC_LOAD, m_btnLoad); + DDX_Control(pDX, IDC_PREVIEW, m_wndPreview); + DDX_Control(pDX, IDC_TREE_TEXTURES, m_treeTextures); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CDialogTextures, CDialog) +//{{AFX_MSG_MAP(CDialogTextures) + ON_BN_CLICKED(IDC_LOAD, OnLoad) + ON_BN_CLICKED(IDC_REFRESH, OnRefresh) + ON_NOTIFY(NM_CLICK, IDC_TREE_TEXTURES, OnClickTreeTextures) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_TEXTURES, OnSelchangedTreeTextures) + ON_NOTIFY(NM_DBLCLK, IDC_TREE_TEXTURES, OnDblclkTreeTextures) + ON_BN_CLICKED(IDC_PREVIEW, OnPreview) + ON_WM_CREATE() + ON_WM_SIZE() + ON_BN_CLICKED(IDC_CHECK_HIDEROOT, OnCheckHideroot) + ON_COMMAND(ID_MATERIAL_EDIT, OnMaterialEdit) + ON_COMMAND(ID_MATERIAL_INFO, OnMaterialInfo) + //}}AFX_MSG_MAP + ON_WM_SETFOCUS() + ON_NOTIFY(NM_RCLICK, IDC_TREE_TEXTURES, OnNMRclickTreeTextures) +END_MESSAGE_MAP() +// +// ======================================================================================================================= +// CDialogTextures message handlers +// ======================================================================================================================= +// +void CDialogTextures::OnOK() { + //CDialog::OnOK(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CDialogTextures::OnInitDialog() { + CDialog::OnInitDialog(); + + m_image.Create(IDB_BITMAP_MATERIAL, 16, 1, RGB(255, 255, 255)); + m_treeTextures.SetImageList(&m_image, TVSIL_NORMAL); + + // m_wndPreview.SubclassDlgItem(IDC_PREVIEW, this); + m_wndPreview.setDrawable(&m_testDrawable); + BuildTree(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CDialogTextures::loadTree( HTREEITEM item, const idStr &name, CWaitDlg *dlg ) { + + if ( item == NULL ) { + return true; + } + + if ( m_treeTextures.ItemHasChildren( item ) ) { + + idStr childName; + HTREEITEM nextItem; + HTREEITEM childItem = m_treeTextures.GetChildItem(item); + + while ( childItem != NULL ) { + + nextItem = m_treeTextures.GetNextItem( childItem, TVGN_NEXT ); + childName = name + "/" + (const char *)m_treeTextures.GetItemText( childItem ); + + if ( m_treeTextures.ItemHasChildren( childItem ) ) { + if ( !loadTree( childItem, childName, dlg ) ) { + return false; + } + } else { + DWORD dw = m_treeTextures.GetItemData( childItem ); + if ( dw == TEXTURES || dw == MATERIALS ) { + if ( dw == TEXTURES ) { + childName = "textures/" + childName; + } + dlg->SetText( childName.c_str() ); + Texture_ForName( childName ); + } + } + if ( dlg->CancelPressed() ) { + return false; + } + + childItem = nextItem; + } + } + + return true; +} + +HTREEITEM CDialogTextures::findItem(const char *name, HTREEITEM item, HTREEITEM *foundItem) { + if (*foundItem || item == NULL) { + return *foundItem; + } + if (m_treeTextures.ItemHasChildren(item)) { + HTREEITEM nextItem; + HTREEITEM childItem = m_treeTextures.GetChildItem(item); + while (childItem != NULL && *foundItem == NULL) { + nextItem = childItem; + if (m_treeTextures.ItemHasChildren(nextItem)) { + findItem(name, nextItem, foundItem); + } else { + DWORD dw = m_treeTextures.GetItemData(nextItem); + if (dw == TEXTURES) { + const char *matName = buildItemName(nextItem, TypeNames[TEXTURES]); + if ( !idStr::Icmpn( name, "textures/", 9 ) && stricmp(name + 9, matName) == 0) { + *foundItem = nextItem; + return *foundItem; + } + } else if (dw == MATERIALS) { + const char *matName = buildItemName(nextItem, TypeNames[MATERIALS]); + if (stricmp(name, matName) == 0) { + *foundItem = nextItem; + return *foundItem; + } + } else if (dw == SOUNDS) { + if (stricmp(name, m_treeTextures.GetItemText(nextItem)) == 0) { + *foundItem = nextItem; + return *foundItem; + } + } + } + childItem = m_treeTextures.GetNextItem(childItem, TVGN_NEXT); + //childItem = nextItem; + } + } + return *foundItem; +} + +void CDialogTextures::CollapseChildren(HTREEITEM parent) { + HTREEITEM nextItem; + HTREEITEM childItem = m_treeTextures.GetChildItem(parent); + while (childItem) { + nextItem = m_treeTextures.GetNextItem(childItem, TVGN_NEXT); + if (m_treeTextures.ItemHasChildren(childItem)) { + CollapseChildren(childItem); + m_treeTextures.Expand(childItem, TVE_COLLAPSE); + } + childItem = nextItem; + } +} + +void CDialogTextures::SelectCurrentItem(bool collapse, const char *name, int id) { + HTREEITEM root = m_treeTextures.GetRootItem(); + idStr qt; + if ((id == TEXTURES) || (id == MATERIALS)) { + HTREEITEM matItem = NULL; + HTREEITEM *matPtr = &matItem; + + // FIXME: This is a hack. How should this really work? + if (id == MATERIALS && !idStr::Icmpn( name, "textures/", 9 ) ) { + // Texture_SetTexture calls SelectCurrentItem with id == MATERIALS + id = TEXTURES; + } + setTexture = false; + if (root) { + if (collapse && !ignoreCollapse) { + CollapseChildren(root); + } + + HTREEITEM *check = NULL; + qt = TypeNames[id]; + qt += "/"; + if (id == TEXTURES && !idStr::Icmpn( name, "textures/", 9 ) ) { + // strip off "textures/" + qt += name + 9; + } else { + qt += name; + } + if (quickTree.Get(qt, &check)) { + matItem = *check; + } + if (matItem == NULL) { + matItem = findItem(name, root, matPtr); + } + if (matItem) { + m_treeTextures.SelectItem(matItem); + } + } + setTexture = true; + } else if (id == SOUNDS) { + if (root) { + if (collapse && !ignoreCollapse) { + CollapseChildren(root); + } + HTREEITEM sel = FindTreeItem(&m_treeTextures, root, name, NULL); + if (sel) { + m_treeTextures.SelectItem(sel); + } + } + } +} + +void CDialogTextures::OnLoad() { + CWaitCursor cursor; + CWaitDlg dlg; + dlg.AllowCancel( true ); + dlg.SetWindowText( "Loading textures..." ); + Texture_HideAll(); + HTREEITEM item = m_treeTextures.GetSelectedItem(); + idStr name = buildItemName( item, TypeNames[TEXTURES] ); + if ( !name.Cmpn( TypeNames[MATERIALS], strlen( TypeNames[MATERIALS] ) ) ) { + name = buildItemName( item, TypeNames[MATERIALS] ); + } + loadTree( item, name, &dlg ); +} + +const char *CDialogTextures::buildItemName(HTREEITEM item, const char *rootName) { + itemName = m_treeTextures.GetItemText(item); + + // have to build the name back up + HTREEITEM parent = m_treeTextures.GetParentItem(item); + while (true) { + idStr strParent = m_treeTextures.GetItemText(parent); + if ( idStr::Icmp(strParent, rootName) == 0 ) { + break; + } + strParent += "/"; + strParent += itemName; + itemName = strParent; + parent = m_treeTextures.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + return itemName; +} +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::OnRefresh() { + quickTree.Clear(); + + addModels( true ); + + if (mode == TEXTURES) { + idStrList textures(1024); + int count = declManager->GetNumDecls( DECL_MATERIAL ); + int i; + const idMaterial *mat; + + for (i = 0; i < count; i++) { + mat = declManager->MaterialByIndex(i, false); + if ( mat->IsValid() && mat->TestMaterialFlag(MF_EDITOR_VISIBLE) && !idStr::Icmpn( mat->GetName(), "textures/", 9 ) ) { + textures.Append(mat->GetName()); + } + } + + declManager->Reload( false ); + + BuildTree(); + count = textures.Num(); + for (i = 0; i < count; i++) { + mat = declManager->FindMaterial(textures[i].c_str()); + if ( mat ) { + mat->SetMaterialFlag(MF_EDITOR_VISIBLE); + } + } + SelectCurrentItem(false, g_qeglobals.d_texturewin.texdef.name, CDialogTextures::TEXTURES); + } else if (mode == MATERIALS) { + idStrList textures(1024); + int count = declManager->GetNumDecls( DECL_MATERIAL ); + int i; + const idMaterial *mat; + + for (i = 0; i < count; i++) { + mat = declManager->MaterialByIndex(i, false); + if ( mat->IsValid() && mat->TestMaterialFlag(MF_EDITOR_VISIBLE) && idStr::Icmpn( mat->GetName(), "textures/", 9 ) ) { + textures.Append(mat->GetName()); + } + } + + declManager->Reload( false ); + + BuildTree(); + count = textures.Num(); + for (i = 0; i < count; i++) { + mat = declManager->FindMaterial(textures[i].c_str()); + if ( mat ) { + mat->SetMaterialFlag(MF_EDITOR_VISIBLE); + } + } + SelectCurrentItem(false, g_qeglobals.d_texturewin.texdef.name, CDialogTextures::MATERIALS); + } else if (mode == SOUNDS || mode == SOUNDPARENT) { + HTREEITEM root = m_treeTextures.GetRootItem(); + HTREEITEM sib = m_treeTextures.GetNextItem(root, TVGN_ROOT); + while (sib) { + idStr str = m_treeTextures.GetItemText(sib); + if (str.Icmp(TypeNames[SOUNDS]) == 0) { + CWaitCursor cursor; + m_treeTextures.DeleteItem(sib); + + declManager->Reload( false ); + bool rootItems = m_chkHideRoot.GetCheck() == 0; + addSounds(rootItems); + return; + } + sib = m_treeTextures.GetNextSiblingItem(sib); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent) { + HTREEITEM theItem = NULL; + if (root) { + if ((theItem = tree->GetNextSiblingItem(root)) != NULL) { + theItem = FindTreeItem(tree, theItem, text, NULL); + if (theItem) { + if (forceParent) { + if (tree->GetParentItem(theItem) == forceParent) { + return theItem; + } + } else { + return theItem; + } + } + } + } + + if ((theItem = tree->GetChildItem(root)) != NULL) { + theItem = FindTreeItem(tree, theItem, text, NULL); + if (theItem) { + if (forceParent) { + if (tree->GetParentItem(theItem) == forceParent) { + return theItem; + } + } else { + return theItem; + } + } + } + + if (text && idStr::Icmp(tree->GetItemText(root), text) == 0 ) { + return root; + } + + if (theItem && forceParent) { + if (tree->GetParentItem(theItem) != forceParent) { + theItem = NULL; + } + } + return theItem; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::BuildTree() { + CWaitCursor cursor; + m_treeTextures.DeleteAllItems(); + bool rootItems = m_chkHideRoot.GetCheck() == 0; + + idTimer timer; + + timer.Start(); + + addMaterials( rootItems ); + // _D3XP removed + //addModels( rootItems ); + addScripts( rootItems ); + addSounds( rootItems ); + addGuis( rootItems ); + addParticles( rootItems ); + + timer.Stop(); + + common->Printf( "CDialogTextures::BuildTree() took %.0f milliseconds\n", timer.Milliseconds() ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::OnClickTreeTextures(NMHDR *pNMHDR, LRESULT *pResult) { + *pResult = 0; + + CPoint pt; + GetCursorPos(&pt); + m_treeTextures.ScreenToClient(&pt); + HTREEITEM item = m_treeTextures.HitTest(pt); + + if (item) { + DWORD dw = m_treeTextures.GetItemData(item); + mode = dw; + if (mode == SOUNDS) { + idStr loadName; + if (!m_treeTextures.ItemHasChildren(item)) { + loadName = m_treeTextures.GetItemText(item); + idStr actionName = m_treeTextures.GetItemText(item); + soundSystem->SetMute( false ); + g_qeglobals.sw->PlayShaderDirectly(actionName); + } else { + loadName = m_treeTextures.GetItemText(item); + } + + } else { + g_qeglobals.sw->StopAllSounds(); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::OnSelchangedTreeTextures(NMHDR *pNMHDR, LRESULT *pResult) { + NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *) pNMHDR; + *pResult = 0; + + editMaterial = NULL; + editGui = ""; + mediaName = ""; + currentFile.Empty(); + m_wndPreview.setDrawable(&m_testDrawable); + HTREEITEM item = m_treeTextures.GetSelectedItem(); + if (item) { + DWORD dw = m_treeTextures.GetItemData(item); + mode = dw; + if ((dw == TEXTURES) || (dw == MATERIALS)) { + idStr matName = m_treeTextures.GetItemText(item); + + // have to build the name back up + HTREEITEM parent = m_treeTextures.GetParentItem(item); + while (true) { + idStr strParent = m_treeTextures.GetItemText(parent); + if ( idStr::Icmp(strParent, TypeNames[dw]) == 0 ) { + break; + } + strParent += "/"; + strParent += matName; + matName = strParent; + parent = m_treeTextures.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + if ( dw == TEXTURES ) { + matName = "textures/" + matName; + } + + const idMaterial *mat = Texture_ForName(matName); + editMaterial = mat; + m_drawMaterial.setMedia(matName); + m_wndPreview.setDrawable(&m_drawMaterial); + m_wndPreview.RedrawWindow(); + + ignoreCollapse = true; + Select_SetDefaultTexture(mat, false, setTexture); + ignoreCollapse = false; + } else if (dw == MODELS) { + idStr strParent; + idStr modelName = m_treeTextures.GetItemText(item); + // have to build the name back up + HTREEITEM parent = m_treeTextures.GetParentItem(item); + while (true) { + strParent = m_treeTextures.GetItemText(parent); + if ( idStr::Icmp(strParent, TypeNames[MODELS]) == 0 ) { + break; + } + strParent += "/"; + strParent += modelName; + modelName = strParent; + parent = m_treeTextures.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + strParent = "models/"; + strParent += modelName; + m_drawModel.setMedia(strParent); + mediaName = strParent; + m_wndPreview.setDrawable(&m_drawModel); + m_drawModel.SetRealTime(0); + m_wndPreview.RedrawWindow(); + } else if (dw == SCRIPTS) { + } else if (dw == SOUNDS) { + } else if (dw == PARTICLES) { + idStr strParent; + idStr modelName = m_treeTextures.GetItemText(item); + // have to build the name back up + HTREEITEM parent = m_treeTextures.GetParentItem(item); + while (true) { + strParent = m_treeTextures.GetItemText(parent); + if ( idStr::Icmp(strParent, TypeNames[PARTICLES]) == 0 ) { + break; + } + strParent += "/"; + strParent += modelName; + modelName = strParent; + parent = m_treeTextures.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + strParent = modelName; + mediaName = strParent; + mediaName += ".prt"; + m_drawModel.setMedia(mediaName); + m_drawModel.SetRealTime(50); + m_wndPreview.setDrawable(&m_drawModel); + m_wndPreview.RedrawWindow(); + } else if (dw == GUIS) { + idStr strParent; + idStr modelName = m_treeTextures.GetItemText(item); + // have to build the name back up + HTREEITEM parent = m_treeTextures.GetParentItem(item); + while (true) { + strParent = m_treeTextures.GetItemText(parent); + if ( idStr::Icmp(strParent, TypeNames[GUIS]) == 0 ) { + break; + } + strParent += "/"; + strParent += modelName; + modelName = strParent; + parent = m_treeTextures.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + strParent = "guis/"; + strParent += modelName; + const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview"); + mat->SetGui(strParent); + editGui = strParent; + m_drawMaterial.setMedia("guisurfs/guipreview"); + m_drawMaterial.setScale(4.4f); + m_wndPreview.setDrawable(&m_drawMaterial); + m_wndPreview.RedrawWindow(); + } + } + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::addMaterials( bool rootItems ) { + idStrList textures(1024); + idStrList materials(1024); + + textures.SetGranularity( 1024 ); + materials.SetGranularity( 1024 ); + + int count = declManager->GetNumDecls( DECL_MATERIAL ); + if ( count > 0 ) { + for ( int i = 0; i < count; i++ ) { + const idMaterial *mat = declManager->MaterialByIndex( i, false ); + if ( !rootItems ) { + if ( strchr( mat->GetName(), '/' ) == NULL && strchr( mat->GetName(), '\\' ) == NULL ) { + continue; + } + } + // add everything except the textures/ materials + if ( idStr::Icmpn( mat->GetName(), "textures/", 9 ) == 0 ) { + textures.Append( mat->GetName() ); + } else { + materials.Append( mat->GetName() ); + } + } + idStrListSortPaths( textures ); + addStrList( TypeNames[TEXTURES], textures, TEXTURES ); + idStrListSortPaths( materials ); + addStrList( TypeNames[MATERIALS], materials, MATERIALS ); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::addParticles( bool rootItems ) { + idStrList list(1024); + int count = declManager->GetNumDecls( DECL_PARTICLE ); + if (count > 0) { + for (int i = 0; i < count; i++) { + const idDecl *ips = declManager->DeclByIndex( DECL_PARTICLE, i, false ); + if (!rootItems) { + if (strchr(ips->GetName(), '/') == NULL && strchr(ips->GetName(), '\\') == NULL) { + continue; + } + } + list.Append(ips->GetName()); + } + idStrListSortPaths( list ); + addStrList( TypeNames[PARTICLES], list, PARTICLES ); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::addSounds(bool rootItems) { + int i, j; + idStrList list(1024); + idStrList list2(1024); + HTREEITEM base = m_treeTextures.InsertItem(TypeNames[SOUNDS]); + + for(i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++) { + const idSoundShader *poo = declManager->SoundByIndex(i, false); + list.AddUnique( poo->GetFileName() ); + } + idStrListSortPaths( list ); + + for (i = 0; i < list.Num(); i++) { + HTREEITEM child = m_treeTextures.InsertItem(list[i], base); + m_treeTextures.SetItemData(child, SOUNDPARENT); + m_treeTextures.SetItemImage(child, 0, 1); + list2.Clear(); + for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) { + const idSoundShader *poo = declManager->SoundByIndex(j, false); + if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) { + list2.Append( poo->GetName() ); + } + } + idStrListSortPaths( list2 ); + for (j = 0; j < list2.Num(); j++) { + HTREEITEM child2 = m_treeTextures.InsertItem( list2[j], child ); + m_treeTextures.SetItemData(child2, SOUNDS); + m_treeTextures.SetItemImage(child2, 2, 2); + } + } + +} + +void CDialogTextures::addStrList( const char *root, const idStrList &list, int id ) { + idStr out, path; + + HTREEITEM base = m_treeTextures.GetRootItem(); + while (base) { + out = m_treeTextures.GetItemText(base); + if (stricmp(root, out) == 0) { + break; + } + base = m_treeTextures.GetNextSiblingItem(base); + } + + if (base == NULL) { + base = m_treeTextures.InsertItem(root); + } + + HTREEITEM item = base; + HTREEITEM add; + + int count = list.Num(); + + idStr last, qt; + for (int i = 0; i < count; i++) { + idStr name = list[i]; + + // now break the name down convert to slashes + name.BackSlashesToSlashes(); + name.Strip(' '); + + int index; + int len = last.Length(); + if (len == 0) { + index = name.Last('/'); + if (index >= 0) { + name.Left(index, last); + } + } + else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) { + name.Right(name.Length() - len - 1, out); + add = m_treeTextures.InsertItem(out, item); + qt = root; + qt += "/"; + qt += name; + quickTree.Set(qt, add); + m_treeTextures.SetItemData(add, id); + m_treeTextures.SetItemImage(add, 2, 2); + continue; + } + else { + last.Empty(); + } + + index = 0; + item = base; + path = ""; + while (index >= 0) { + index = name.Find('/'); + if (index >= 0) { + HTREEITEM newItem = NULL; + HTREEITEM *check = NULL; + name.Left( index, out ); + path += out; + qt = root; + qt += "/"; + qt += path; + if (quickTree.Get(qt, &check)) { + newItem = *check; + } + //HTREEITEM newItem = FindTreeItem(&m_treeTextures, item, name.Left(index, out), item); + if (newItem == NULL) { + newItem = m_treeTextures.InsertItem(out, item); + qt = root; + qt += "/"; + qt += path; + quickTree.Set(qt, newItem); + m_treeTextures.SetItemImage(newItem, 0, 1); + } + + assert(newItem); + item = newItem; + name.Right( name.Length() - index - 1, out ); + name = out; + path += "/"; + } + else { + add = m_treeTextures.InsertItem(name, item); + qt = root; + qt += "/"; + qt += path; + qt += name; + quickTree.Set(qt, add); + m_treeTextures.SetItemData(add, id); + m_treeTextures.SetItemImage(add, 2, 2); + path = ""; + } + } + } + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::addModels(bool rootItems) { + idFileList *files; + + files = fileSystem->ListFilesTree( "models", ".ase|.lwo|.ma", true ); + + if ( files->GetNumFiles() ) { + addStrList( TypeNames[MODELS], files->GetList(), MODELS ); + } + + fileSystem->FreeFileList( files ); +} + +void CDialogTextures::addGuis( bool rootItems ) { + idFileList *files; + + files = fileSystem->ListFilesTree( "guis", ".gui", true ); + + if ( files->GetNumFiles() ) { + addStrList( TypeNames[GUIS], files->GetList(), GUIS ); + } + + fileSystem->FreeFileList( files ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::addScripts(bool rootItems) { +/* + idFileList *files; + + files = fileSystem->ListFilesExt( "def", ".script" ); + + if ( files->GetNumFiles() ) { + addStrList("Scripts", files->GetList(), 3); + } +*/ +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::OnDblclkTreeTextures(NMHDR *pNMHDR, LRESULT *pResult) { + CPoint pt; + GetCursorPos(&pt); + m_treeTextures.ScreenToClient(&pt); + HTREEITEM item = m_treeTextures.HitTest(pt); + if (item) { + DWORD dw = m_treeTextures.GetItemData(item); + mode = dw; + if (mode == SOUNDS) { + if (!m_treeTextures.ItemHasChildren(item)) { + idStr shaderName = m_treeTextures.GetItemText(item); + Select_SetKeyVal("s_shader", shaderName); + entity_t *ent = selected_brushes.next->owner; + if (ent) { + g_Inspectors->UpdateEntitySel(ent->eclass); + MessageBeep(MB_OK); + } + } + } else if (mode == MODELS || mode == PARTICLES ) { + if (mediaName.Length()) { + g_Inspectors->entityDlg.UpdateKeyVal("model", mediaName); + } + } else if (mode <= MATERIALS) { + OnLoad(); + } + } + + *pResult = 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CDialogTextures::OnPreview() { + // TODO: Add your control notification handler code here +} + + +//void CDialogTextures::OnSave() +//{ +/* + CString str; + m_wndEditShader.GetWindowText(str); + if (currentFile.length() && str.GetLength()) { + fileSystem->WriteFile(currentFile, str.GetBuffer(0), str.GetLength()); + } +*/ +//} + +int CDialogTextures::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CDialog::OnCreate(lpCreateStruct) == -1) + return -1; + + // TODO: Add your specialized creation code here + + return 0; +} + +void CDialogTextures::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + + if (m_btnLoad.GetSafeHwnd() == NULL) { + return; + } + + CRect rect, rect2, rect3; + GetClientRect(rect); + m_btnLoad.GetWindowRect(rect2); + + m_btnLoad.SetWindowPos(NULL, rect.left + 4, rect.top + 4, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + m_btnRefresh.SetWindowPos(NULL, rect.left + rect2.Width() + 4, rect.top + 4, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + + + int right = rect.right - 4 - rect3.Width() - 4; + + + right = rect3.right - 4 - rect3.Width() - 4; + + m_chkHideRoot.GetWindowRect(rect3); + m_chkHideRoot.SetWindowPos(NULL, right - rect3.Width() * 2, rect.top + 4, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + m_chkHideRoot.ShowWindow(SW_HIDE); + + int verticalSpace = (rect.Height() - rect2.Height() - 12) / 2; + + m_treeTextures.SetWindowPos(NULL, rect.left + 4, rect.top + 8 + rect2.Height(), (rect.Width() - 8), verticalSpace, SWP_SHOWWINDOW); + m_wndPreview.SetWindowPos(NULL, rect.left + 4, rect.top + 12 + rect2.Height() + verticalSpace, (rect.Width() - 8), verticalSpace, SWP_SHOWWINDOW); + + RedrawWindow(); +} + +BOOL CDialogTextures::PreCreateWindow(CREATESTRUCT& cs) +{ + return CDialog::PreCreateWindow(cs); +} + +void CDialogTextures::OnCheckHideroot() +{ + BuildTree(); +} + +void CDialogTextures::CollapseEditor() { + if (g_qeglobals.d_savedinfo.editorExpanded) { + } +} + + +void CDialogTextures::OnCancel() { +} + + +BOOL CDialogTextures::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)) { + if (pMsg->wParam == VK_ESCAPE) { + g_pParentWnd->GetCamera()->SetFocus(); + Select_Deselect(); + } + return TRUE; + } + + return CDialog::PreTranslateMessage(pMsg); +} + +void CDialogTextures::OnSetFocus(CWnd* pOldWnd) +{ + CDialog::OnSetFocus(pOldWnd); + RedrawWindow(); +} + +void CDialogTextures::OnNMRclickTreeTextures(NMHDR *pNMHDR, LRESULT *pResult) +{ + *pResult = 0; + + CPoint pt; + GetCursorPos(&pt); + m_treeTextures.ScreenToClient(&pt); + HTREEITEM item = m_treeTextures.HitTest(pt); + + if (item) { + DWORD dw = m_treeTextures.GetItemData(item); + mode = dw; + if (mode == TEXTURES || mode == MATERIALS || mode == GUIS) { + m_treeTextures.SelectItem(item); + HandlePopup(this, IDR_POPUP_MATERIAL); + } + } +} + +void CDialogTextures::OnMaterialEdit() { + CEditViewDlg dlg; + if ((mode == TEXTURES || mode == MATERIALS) && editMaterial) { + dlg.SetMode(CEditViewDlg::MATERIALS); + dlg.SetMaterialInfo(editMaterial->GetName(), editMaterial->GetFileName(), editMaterial->GetLineNum()); + dlg.DoModal(); + } else if (mode == GUIS && editGui.Length()) { + dlg.SetMode(CEditViewDlg::GUIS); + dlg.SetGuiInfo(editGui); + dlg.DoModal(); + } +} + +void CDialogTextures::OnMaterialInfo() { +/* + idStr str; + if (editMaterial) { + str = "File: "; + str += editMaterial->getFileName(); + str += "\r\nName: "; + str = editMaterial->getName(); + ShowInfoDialog(str); + } else if (editGui.Length()) { + str = "File: "; + str += editGui; + ShowInfoDialog(str); + } +*/ +} diff --git a/tools/radiant/DialogTextures.h b/tools/radiant/DialogTextures.h new file mode 100644 index 000000000..c869defd0 --- /dev/null +++ b/tools/radiant/DialogTextures.h @@ -0,0 +1,115 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __DIALOGTEXTURES_H +#define __DIALOGTEXTURES_H + +// DialogTextures.h : header file +// + +#include +#include "GLWidget.h" + +///////////////////////////////////////////////////////////////////////////// +// CDialogTextures dialog + +class CDialogTextures : public CDialog +{ +// Construction +public: + enum { NONE, TEXTURES, MATERIALS, MODELS, SCRIPTS, SOUNDS, SOUNDPARENT, GUIS, PARTICLES, FX,NUMIDS }; + static const char *TypeNames[NUMIDS]; + CDialogTextures(CWnd* pParent = NULL); // standard constructor + void OnCancel(); + void CollapseEditor(); + void SelectCurrentItem(bool collapse, const char *name, int id); +// Dialog Data + //{{AFX_DATA(CDialogTextures) + enum { IDD = IDD_DIALOG_TEXTURELIST }; + CButton m_chkHideRoot; + CButton m_btnRefresh; + CButton m_btnLoad; + idGLWidget m_wndPreview; + CTreeCtrl m_treeTextures; + //}}AFX_DATA + + CImageList m_image; + idGLDrawable m_testDrawable; + idGLDrawableMaterial m_drawMaterial; + idGLDrawableModel m_drawModel; + const idMaterial *editMaterial; + idStr editGui; + idStr currentFile; + idStr mediaName; + bool setTexture; + bool ignoreCollapse; + int mode; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDialogTextures) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +protected: + void addStrList(const char *root, const idStrList &list, int id); + void addScripts(bool rootItems); + void addModels(bool rootItems); + void addMaterials(bool rootItems); + void addSounds(bool rootItems); + void addGuis(bool rootItems); + void addParticles(bool rootItems); + void BuildTree(); + void CollapseChildren(HTREEITEM parent); + const char *buildItemName(HTREEITEM item, const char *rootName); + bool loadTree( HTREEITEM item, const idStr &name, CWaitDlg *dlg ); + HTREEITEM findItem(const char *name, HTREEITEM item, HTREEITEM *foundItem); + // Generated message map functions + //{{AFX_MSG(CDialogTextures) + virtual void OnOK(); + virtual BOOL OnInitDialog(); + afx_msg void OnLoad(); + afx_msg void OnRefresh(); + afx_msg void OnClickTreeTextures(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnSelchangedTreeTextures(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDblclkTreeTextures(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnPreview(); + afx_msg void OnMaterialEdit(); + afx_msg void OnMaterialInfo(); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnCheckHideroot(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + idHashTable quickTree; + idStr itemName; + +public: + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnNMRclickTreeTextures(NMHDR *pNMHDR, LRESULT *pResult); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DIALOGTEXTURES_H__F3F3F984_E47E_11D1_B61B_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/DialogThick.cpp b/tools/radiant/DialogThick.cpp new file mode 100644 index 000000000..5af1e7a19 --- /dev/null +++ b/tools/radiant/DialogThick.cpp @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "DialogThick.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDialogThick dialog + + +CDialogThick::CDialogThick(CWnd* pParent /*=NULL*/) + : CDialog(CDialogThick::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogThick) + m_bSeams = TRUE; + m_nAmount = 8; + //}}AFX_DATA_INIT +} + + +void CDialogThick::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogThick) + DDX_Check(pDX, IDC_CHECK_SEAMS, m_bSeams); + DDX_Text(pDX, IDC_EDIT_AMOUNT, m_nAmount); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogThick, CDialog) + //{{AFX_MSG_MAP(CDialogThick) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogThick message handlers diff --git a/tools/radiant/DialogThick.h b/tools/radiant/DialogThick.h new file mode 100644 index 000000000..2582f5d04 --- /dev/null +++ b/tools/radiant/DialogThick.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_DIALOGTHICK_H__59F46602_553D_11D2_B082_00AA00A410FC__INCLUDED_) +#define AFX_DIALOGTHICK_H__59F46602_553D_11D2_B082_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// DialogThick.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CDialogThick dialog + +class CDialogThick : public CDialog +{ +// Construction +public: + CDialogThick(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CDialogThick) + enum { IDD = IDD_DIALOG_THICKEN }; + BOOL m_bSeams; + int m_nAmount; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDialogThick) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDialogThick) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DIALOGTHICK_H__59F46602_553D_11D2_B082_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/DlgCamera.cpp b/tools/radiant/DlgCamera.cpp new file mode 100644 index 000000000..b56aa2ee1 --- /dev/null +++ b/tools/radiant/DlgCamera.cpp @@ -0,0 +1,364 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/common_resource.h" +#include "../comafx/DialogName.h" + +#include "qe3.h" +#include "DlgCamera.h" +#include "DlgEvent.h" +#include "splines.h" +#include "CameraTargetDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +CDlgCamera g_dlgCamera; + + +void showCameraInspector() { + if (g_dlgCamera.GetSafeHwnd() == NULL) { + g_dlgCamera.Create(IDD_DLG_CAMERA); + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("Radiant::CameraInspector", &rct, &lSize)) { + g_dlgCamera.SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE | SWP_SHOWWINDOW); + } + Sys_UpdateWindows(W_ALL); + } + g_dlgCamera.ShowWindow(SW_SHOW); + g_dlgCamera.setupFromCamera(); +} +///////////////////////////////////////////////////////////////////////////// +// CDlgCamera dialog + + +CDlgCamera::CDlgCamera(CWnd* pParent /*=NULL*/) + : CDialog(CDlgCamera::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDlgCamera) + m_strName = _T(""); + m_fSeconds = 0.0f; + m_trackCamera = TRUE; + m_numSegments = 0; + m_currentSegment = 0; + m_strType = _T(""); + m_editPoints = 0; + //}}AFX_DATA_INIT +} + + +void CDlgCamera::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDlgCamera) + DDX_Control(pDX, IDC_SCROLLBAR_SEGMENT, m_wndSegments); + DDX_Control(pDX, IDC_LIST_EVENTS, m_wndEvents); + DDX_Control(pDX, IDC_COMBO_SPLINES, m_wndSplines); + DDX_Text(pDX, IDC_EDIT_CAM_NAME, m_strName); + DDX_Text(pDX, IDC_EDIT_LENGTH, m_fSeconds); + DDX_Check(pDX, IDC_CHECK_TRACKCAMERA, m_trackCamera); + DDX_Text(pDX, IDC_EDIT_TOTALSEGMENTS, m_numSegments); + DDX_Text(pDX, IDC_EDIT_SEGMENT, m_currentSegment); + DDX_Text(pDX, IDC_EDIT_TYPE, m_strType); + DDX_Radio(pDX, IDC_RADIO_EDITPOINTS, m_editPoints); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDlgCamera, CDialog) + //{{AFX_MSG_MAP(CDlgCamera) + ON_BN_CLICKED(IDC_BTN_ADDEVENT, OnBtnAddevent) + ON_BN_CLICKED(IDC_BTN_ADDTARGET, OnBtnAddtarget) + ON_BN_CLICKED(IDC_BTN_DELEVENT, OnBtnDelevent) + ON_CBN_DBLCLK(IDC_COMBO_SPLINES, OnDblclkComboSplines) + ON_CBN_SELCHANGE(IDC_COMBO_SPLINES, OnSelchangeComboSplines) + ON_LBN_SELCHANGE(IDC_LIST_EVENTS, OnSelchangeListEvents) + ON_LBN_DBLCLK(IDC_LIST_EVENTS, OnDblclkListEvents) + ON_WM_DESTROY() + ON_BN_CLICKED(IDC_APPLY, OnApply) + ON_WM_HSCROLL() + ON_BN_CLICKED(ID_FILE_NEW, OnFileNew) + ON_BN_CLICKED(ID_FILE_OPEN, OnFileOpen) + ON_BN_CLICKED(ID_FILE_SAVE, OnFileSave) + ON_BN_CLICKED(IDC_TESTCAMERA, OnTestcamera) + ON_BN_CLICKED(IDC_BTN_DELETEPOINTS, OnBtnDeletepoints) + ON_BN_CLICKED(IDC_BTN_SELECTALL, OnBtnSelectall) + ON_BN_CLICKED(IDC_RADIO_EDITPOINTS, OnRadioEditpoints) + ON_BN_CLICKED(IDC_RADIO_EDITPOINTS2, OnRadioAddPoints) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDlgCamera message handlers + +void CDlgCamera::OnBtnAddevent() +{ + CDlgEvent dlg; + if (dlg.DoModal() == IDOK) { + long n = m_wndSegments.GetScrollPos() / 4 * 1000; + g_splineList->addEvent(static_cast(dlg.m_event+1), dlg.m_strParm, n); + setupFromCamera(); + } +} + +void CDlgCamera::OnBtnAddtarget() +{ + CCameraTargetDlg dlg; + if (dlg.DoModal() == IDOK) { + g_splineList->addTarget(dlg.m_strName, static_cast(dlg.m_nType)); + setupFromCamera(); + m_wndSplines.SetCurSel(g_splineList->numTargets()); + OnSelchangeComboSplines(); + } +} + +void CDlgCamera::OnBtnDelevent() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnBtnDeltarget() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnDblclkComboSplines() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnSelchangeComboSplines() +{ + UpdateData(TRUE); + g_qeglobals.d_select_mode = (m_editPoints == 0) ? sel_editpoint : sel_addpoint; + g_qeglobals.d_numpoints = 0; + g_qeglobals.d_num_move_points = 0; + int i = m_wndSplines.GetCurSel(); + if (i > 0) { + g_splineList->setActiveTarget(i-1); + g_qeglobals.selectObject = g_splineList->getActiveTarget(i-1); + g_splineList->startEdit(false); + } else { + g_splineList->startEdit(true); + g_qeglobals.selectObject = g_splineList->getPositionObj(); + } + + // * 4.0 to set increments in quarter seconds + m_wndSegments.SetScrollRange(0, g_splineList->getTotalTime() * 4.0); + + Sys_UpdateWindows(W_ALL); +} + +void CDlgCamera::OnSelchangeListEvents() +{ + int sel = m_wndEvents.GetCurSel(); + //g_splineList->setActiveSegment(sel >= 0 ? sel : 0); +} + +void CDlgCamera::OnDblclkListEvents() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::setupFromCamera() +{ + if (m_wndSplines.GetSafeHwnd()) { + int i; + idStr str; + m_strName = g_splineList->getName(); + m_strType = g_splineList->getPositionObj()->typeStr(); + m_wndSplines.ResetContent(); + m_wndSplines.AddString("Path"); + for (i = 0; i < g_splineList->numTargets(); i++) { + m_wndSplines.AddString(g_splineList->getActiveTarget(i)->getName()); + } + m_wndSplines.SetCurSel(0); + m_fSeconds = g_splineList->getTotalTime(); + m_wndSegments.SetScrollRange(0, g_splineList->getTotalTime() * 4.0); + + m_wndEvents.ResetContent(); + for (i = 0; i < g_splineList->numEvents(); i++) { + str = va("%s\t%s", g_splineList->getEvent(i)->typeStr(), g_splineList->getEvent(i)->getParam()); + m_wndEvents.AddString(str); + } + //m_currentSegment = g_splineList->getActiveSegment(); + //m_numSegments = g_splineList->numSegments(); + } + g_splineList->startEdit(true); + UpdateData(FALSE); +} + +BOOL CDlgCamera::OnInitDialog() +{ + CDialog::OnInitDialog(); + setupFromCamera(); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CDlgCamera::OnOK() +{ + g_dlgCamera.ShowWindow(SW_HIDE); + g_qeglobals.d_select_mode = sel_brush; + g_splineList->stopEdit(); + Sys_UpdateWindows(W_ALL); +} + +void CDlgCamera::OnDestroy() +{ + if (GetSafeHwnd()) { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::CameraInspector", &rct, sizeof(rct)); + } + CDialog::OnDestroy(); + Sys_UpdateWindows(W_ALL); +} + + +void CDlgCamera::OnApply() +{ + UpdateData(TRUE); + g_splineList->setBaseTime(m_fSeconds); + g_splineList->setName(m_strName); + g_splineList->buildCamera(); + m_wndSegments.SetScrollRange(0, g_splineList->getTotalTime() * 4.0); +} + +void CDlgCamera::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + CDialog::OnHScroll(nSBCode, nPos, pScrollBar); + int max = g_splineList->getTotalTime() * 4; + if (max == 0) { + max = 1; + } + int n = pScrollBar->GetScrollPos(); + switch (nSBCode) { + case SB_LINEUP : { + n--; + } + break; + case SB_LINEDOWN : { + n++; + } + break; + case SB_PAGEUP : { + n -= (float)max * 0.10; + } + break; + case SB_PAGEDOWN : { + n += (float)max * 0.10; + } + break; + case SB_THUMBPOSITION : { + n = nPos; + } + break; + case SB_THUMBTRACK : { + n = nPos; + } + } +// if (n < 0) { +// n = 0; +// } else if (n >= g_splineList->numSegments()) { +// if (g_splineList->numSegments() == 0) { +// g_splineList->buildCamera(); +// } +// n = g_splineList->numSegments() - 1; +// } + pScrollBar->SetScrollPos(n); + if (m_trackCamera) { + float p = (float)n / max; + p *= g_splineList->getTotalTime() * 1000; + g_splineList->startCamera(0); + g_splineList->buildCamera(); + idVec3 dir; + float fov; + g_splineList->getCameraInfo(p, g_pParentWnd->GetCamera()->Camera().origin, dir, &fov); + g_pParentWnd->GetCamera()->Camera().angles[1] = atan2 (dir[1], dir[0])*180/3.14159; + g_pParentWnd->GetCamera()->Camera().angles[0] = asin (dir[2])*180/3.14159; + + } + UpdateData(FALSE); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +void CDlgCamera::OnFileNew() +{ + g_splineList->clear(); + setupFromCamera(); +} + +void CDlgCamera::OnFileOpen() +{ + DialogName dlg("Open Camera File"); + if (dlg.DoModal() == IDOK) { + g_splineList->clear(); + g_splineList->load(va("cameras/%s.camera", dlg.m_strName)); + } +} + +void CDlgCamera::OnFileSave() +{ + DialogName dlg("Save Camera File"); + if (dlg.DoModal() == IDOK) { + g_splineList->save(va("cameras/%s.camera", dlg.m_strName)); + } +} + +void CDlgCamera::OnTestcamera() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnBtnDeletepoints() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnBtnSelectall() +{ + // TODO: Add your control notification handler code here + +} + +void CDlgCamera::OnRadioEditpoints() +{ + UpdateData(TRUE); + g_qeglobals.d_select_mode = sel_editpoint; +} + +void CDlgCamera::OnRadioAddPoints() +{ + UpdateData(TRUE); + g_qeglobals.d_select_mode = sel_addpoint; +} diff --git a/tools/radiant/DlgCamera.h b/tools/radiant/DlgCamera.h new file mode 100644 index 000000000..8dae0567c --- /dev/null +++ b/tools/radiant/DlgCamera.h @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_DLGCAMERA_H__59C12359_E3EB_4081_9F28_01793D75CF20__INCLUDED_) +#define AFX_DLGCAMERA_H__59C12359_E3EB_4081_9F28_01793D75CF20__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DlgCamera.h : header file +// + +extern void showCameraInspector(); + +///////////////////////////////////////////////////////////////////////////// +// CDlgCamera dialog + +class CDlgCamera : public CDialog +{ +// Construction +public: + CDlgCamera(CWnd* pParent = NULL); // standard constructor + void setupFromCamera(); + +// Dialog Data + //{{AFX_DATA(CDlgCamera) + enum { IDD = IDD_DLG_CAMERA }; + CScrollBar m_wndSegments; + CListBox m_wndEvents; + CComboBox m_wndSplines; + CString m_strName; + float m_fSeconds; + BOOL m_trackCamera; + int m_numSegments; + int m_currentSegment; + CString m_strType; + int m_editPoints; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDlgCamera) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + // Generated message map functions + //{{AFX_MSG(CDlgCamera) + afx_msg void OnBtnAddevent(); + afx_msg void OnBtnAddtarget(); + afx_msg void OnBtnDelevent(); + afx_msg void OnBtnDeltarget(); + afx_msg void OnDblclkComboSplines(); + afx_msg void OnSelchangeComboSplines(); + afx_msg void OnSelchangeListEvents(); + afx_msg void OnDblclkListEvents(); + virtual BOOL OnInitDialog(); + virtual void OnOK(); + afx_msg void OnDestroy(); + afx_msg void OnApply(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + afx_msg void OnFileSave(); + afx_msg void OnTestcamera(); + afx_msg void OnBtnDeletepoints(); + afx_msg void OnBtnSelectall(); + afx_msg void OnRadioEditpoints(); + afx_msg void OnRadioAddPoints(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DLGCAMERA_H__59C12359_E3EB_4081_9F28_01793D75CF20__INCLUDED_) diff --git a/tools/radiant/DlgEvent.cpp b/tools/radiant/DlgEvent.cpp new file mode 100644 index 000000000..5364b7c11 --- /dev/null +++ b/tools/radiant/DlgEvent.cpp @@ -0,0 +1,63 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "DlgEvent.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDlgEvent dialog + + +CDlgEvent::CDlgEvent(CWnd* pParent /*=NULL*/) + : CDialog(CDlgEvent::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDlgEvent) + m_strParm = _T(""); + m_event = 0; + //}}AFX_DATA_INIT +} + + +void CDlgEvent::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDlgEvent) + DDX_Text(pDX, IDC_EDIT_PARAM, m_strParm); + DDX_Radio(pDX, IDC_RADIO_EVENT, m_event); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDlgEvent, CDialog) + //{{AFX_MSG_MAP(CDlgEvent) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDlgEvent message handlers diff --git a/tools/radiant/DlgEvent.h b/tools/radiant/DlgEvent.h new file mode 100644 index 000000000..c360c0e96 --- /dev/null +++ b/tools/radiant/DlgEvent.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_DLGEVENT_H__B12EEBE1_FB71_407B_9075_50F63B168567__INCLUDED_) +#define AFX_DLGEVENT_H__B12EEBE1_FB71_407B_9075_50F63B168567__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DlgEvent.h : header file +// + +#include "splines.h" +///////////////////////////////////////////////////////////////////////////// +// CDlgEvent dialog + +class CDlgEvent : public CDialog +{ +// Construction +public: + CDlgEvent(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CDlgEvent) + enum { IDD = IDD_DLG_CAMERAEVENT }; + CString m_strParm; + int m_event; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDlgEvent) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDlgEvent) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DLGEVENT_H__B12EEBE1_FB71_407B_9075_50F63B168567__INCLUDED_) diff --git a/tools/radiant/ECLASS.CPP b/tools/radiant/ECLASS.CPP new file mode 100644 index 000000000..c65fd3e29 --- /dev/null +++ b/tools/radiant/ECLASS.CPP @@ -0,0 +1,445 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "io.h" +#include "../../renderer/tr_local.h" + +struct evarPrefix_t { + int type; + const char *prefix; +}; + +const evarPrefix_t EvarPrefixes[] = { + { EVAR_STRING, "editor_var " }, + { EVAR_INT, "editor_int " }, + { EVAR_FLOAT, "editor_float " }, + { EVAR_BOOL, "editor_bool " }, + { EVAR_COLOR, "editor_color " }, + { EVAR_MATERIAL,"editor_mat " }, + { EVAR_MODEL, "editor_model " }, + { EVAR_GUI, "editor_gui " }, + { EVAR_SOUND, "editor_snd "} +}; + +const int NumEvarPrefixes = sizeof(EvarPrefixes) / sizeof(evarPrefix_t); + +eclass_t *eclass = NULL; +eclass_t *eclass_bad = NULL; +char eclass_directory[1024]; + +// md3 cache for misc_models +eclass_t *g_md3Cache = NULL; + +/* + +the classname, color triple, and bounding box are parsed out of comments +A ? size means take the exact brush size. + +/*QUAKED (0 0 0) ? +/*QUAKED (0 0 0) (-8 -8 -8) (8 8 8) + +Flag names can follow the size description: + +/*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY + +*/ + +void CleanEntityList( eclass_t *&pList ) { + while (pList) { + eclass_t* pTemp = pList->next; + delete pList; + pList = pTemp; + } + pList = NULL; +} + + +void CleanUpEntities() +{ + CleanEntityList(eclass); + CleanEntityList(g_md3Cache); + + if ( eclass_bad ) { + delete eclass_bad; + eclass_bad = NULL; + } +} + +void ExtendBounds(idVec3 v, idVec3 &vMin, idVec3 &vMax) +{ + for (int i = 0 ;i < 3 ;i++) + { + float f = v[i]; + + if (f < vMin[i]) + { + vMin[i] = f; + } + + if (f > vMax[i]) + { + vMax[i] = f; + } + } +} + +bool LoadModel(const char *pLocation, eclass_t *e, idVec3 &vMin, idVec3 &vMax, const char *pSkin) +{ + vMin[0] = vMin[1] = vMin[2] = 999999; + vMax[0] = vMax[1] = vMax[2] = -999999; + + if (strstr(pLocation, ".ase") != NULL) // FIXME: not correct! + { + idBounds b; + e->modelHandle = renderModelManager->FindModel( pLocation ); + b = e->modelHandle->Bounds( NULL ); + VectorCopy(b[0], vMin); + VectorCopy(b[1], vMax); + return true; + } + return false; +} + +eclass_t *EClass_Alloc( void ) { + eclass_t *e; + e = new eclass_t; + if ( e == NULL ) { + return NULL; + } + e->fixedsize = false; + e->unknown = false; + e->mins.Zero(); + e->maxs.Zero(); + e->color.Zero(); + memset( &e->texdef, 0, sizeof( e->texdef ) ); + e->modelHandle = NULL; + e->entityModel = NULL; + e->nFrame = 0; + e->nShowFlags = 0; + e->hPlug = 0; + e->next = NULL; + return e; +} + + +eclass_t *EClass_InitFromDict( const idDict *d, const char *name ) { + eclass_t *e; + const idKeyValue *kv; + + // only include entityDefs with "editor_" values in them + if ( !d->MatchPrefix( "editor_" ) ) { + return NULL; + } + + e = EClass_Alloc(); + if ( !e ) { + return NULL; + } + + e->defArgs = *d; + + idStr str; + idStr text; + idStr varname; + idStr defaultStr; + + e->name = name; + d->GetVector("editor_color", "0 0 1", e->color); + + d->GetString("editor_mins", "", str); + if (str != "?") { + d->GetVector("editor_mins", "0 0 0", e->mins); + d->GetVector("editor_maxs", "0 0 0", e->maxs); + e->fixedsize = true; + } else { + e->fixedsize = false; + } + + + d->GetString("editor_material", "", e->defMaterial); + + //str = d->GetString("model"); + //if (str.Length()) { + // e->entityModel = renderModelManager->FindModel(str); + //} + + str = ""; + + // concatenate all editor usage comments + text = ""; + kv = d->MatchPrefix( "editor_usage" ); + while( kv != NULL ) { + text += kv->GetValue(); + if ( !kv->GetValue().Length() || ( text[ text.Length() - 1 ] != '\n' ) ) { + text += "\n"; + } + kv = d->MatchPrefix( "editor_usage", kv ); + } + + e->desc = text; + + str += "Spawn args:\n"; + for (int i = 0; i < NumEvarPrefixes; i++) { + kv = d->MatchPrefix(EvarPrefixes[i].prefix); + while (kv) { + evar_t ev; + kv->GetKey().Right( kv->GetKey().Length() - strlen(EvarPrefixes[i].prefix), ev.name ); + ev.desc = kv->GetValue(); + ev.type = EvarPrefixes[i].type; + e->vars.Append(ev); + kv = d->MatchPrefix(EvarPrefixes[i].prefix, kv); + } + } + +/* + while( kv != NULL ) { + kv->key.Right( kv->key.Length() - 11, varname ); + str += va( "'%s':\t %s", varname.c_str(), kv->value.c_str() ); + if ( d->GetString( varname, "", defaultStr ) && defaultStr.Length() ) { + str += va( " Default '%s'.", defaultStr.c_str() ); + } + str += "\n"; + kv = d->MatchPrefix( "editor_var ", kv ); + } + + e->comments = Mem_CopyString( str.c_str() ); +*/ + + + // concatenate all variable comments + kv = d->MatchPrefix( "editor_copy" ); + while (kv) { + const char *temp = d->GetString(kv->GetValue()); + if (temp && *temp) { + e->args.Set(kv->GetValue(), d->GetString(kv->GetValue())); + } + kv = d->MatchPrefix("editor_copy", kv); + } + + // setup show flags + e->nShowFlags = 0; + if (d->GetBool("editor_rotatable")) { + e->nShowFlags |= ECLASS_ROTATABLE; + } + + if (d->GetBool("editor_showangle")) { + e->nShowFlags |= ECLASS_ANGLE; + } + + if (d->GetBool("editor_mover")) { + e->nShowFlags |= ECLASS_MOVER; + } + + if (d->GetBool("editor_env") || idStr::Icmpn(e->name, "env_", 4) == 0) { + e->nShowFlags |= (ECLASS_ENV | ECLASS_ROTATABLE); + if (d->GetBool("editor_ragdoll")) { + e->defArgs.Set("model", ""); + } + } + + if (d->GetBool("editor_combatnode")) { + e->nShowFlags |= ECLASS_COMBATNODE; + } + + if (d->GetBool("editor_light")) { + e->nShowFlags |= ECLASS_LIGHT; + } + + if ( idStr::Icmp(e->name, "light") == 0 ) { + e->nShowFlags |= ECLASS_LIGHT; + } else if ( idStr::Icmp(e->name, "path") == 0 ) { + e->nShowFlags |= ECLASS_PATH; + } else if ( idStr::Icmp(e->name, "target_null") == 0 ) { + e->nShowFlags |= ECLASS_CAMERAVIEW; + } else if ( idStr::Icmp(e->name, "worldspawn") == 0 ) { + e->nShowFlags |= ECLASS_WORLDSPAWN; + } else if ( idStr::Icmp(e->name, "speaker") == 0 ) { + e->nShowFlags |= ECLASS_SPEAKER; + } else if ( idStr::Icmp( e->name, "func_emitter" ) == 0 || idStr::Icmp( e->name, "func_splat" ) == 0 ) { + e->nShowFlags |= ECLASS_PARTICLE; + } else if ( idStr::Icmp(e->name, "func_liquid") == 0 ) { + e->nShowFlags |= ECLASS_LIQUID; + } + + return e; +} + +void EClass_InsertSortedList(eclass_t *&pList, eclass_t *e) +{ + eclass_t *s; + + if (!pList) + { + pList = e; + return; + } + + + s = pList; + if (stricmp (e->name, s->name) < 0) + { + e->next = s; + pList = e; + return; + } + + do + { + if (!s->next || stricmp (e->name, s->next->name) < 0) + { + e->next = s->next; + s->next = e; + return; + } + s=s->next; + } while (1); +} + +/* +================= +Eclass_InsertAlphabetized +================= +*/ +void Eclass_InsertAlphabetized (eclass_t *e) +{ +#if 1 + EClass_InsertSortedList(eclass, e); +#else + eclass_t *s; + + if (!eclass) + { + eclass = e; + return; + } + + + s = eclass; + if (stricmp (e->name, s->name) < 0) + { + e->next = s; + eclass = e; + return; + } + + do + { + if (!s->next || stricmp (e->name, s->next->name) < 0) + { + e->next = s->next; + s->next = e; + return; + } + s=s->next; + } while (1); +#endif +} + + +void Eclass_InitForSourceDirectory (const char *path) +{ + int c = declManager->GetNumDecls(DECL_ENTITYDEF); + for (int i = 0; i < c; i++) { + const idDeclEntityDef *def = static_cast( declManager->DeclByIndex( DECL_ENTITYDEF, i ) ); + if ( def ) { + eclass_t *e = EClass_InitFromDict( &def->dict, def->GetName() ); + if ( e ) { + Eclass_InsertAlphabetized (e); + } + } + } + + eclass_bad = EClass_Alloc(); + if ( !eclass_bad ) { + return; + } + eclass_bad->color.x = 0.0f; + eclass_bad->color.y = 0.5f; + eclass_bad->color.z = 0.0f; + eclass_bad->fixedsize = false; + eclass_bad->name = Mem_CopyString( "UKNOWN ENTITY CLASS" ); +} + +eclass_t *Eclass_ForName (const char *name, bool has_brushes) +{ + eclass_t *e; + char buff[1024]; + + if (!name) { + return eclass_bad; + } + + for ( e = eclass; e; e = e->next ) { + if ( !strcmp( name, e->name ) ) { + return e; + } + } + + e = EClass_Alloc(); + if ( !e ) { + return NULL; + } + e->name = Mem_CopyString( name ); + sprintf(buff, "%s not found in def/*.def\n", name); + e->comments = Mem_CopyString( buff ); + e->color.x = 0.0f; + e->color.y = 0.5f; + e->color.z = 0.0f; + e->fixedsize = !has_brushes; + e->mins.x = e->mins.y = e->mins.z = -8.0f; + e->maxs.x = e->maxs.y = e->maxs.z = 8.0f; + Eclass_InsertAlphabetized( e ); + + return e; +} + + +eclass_t* GetCachedModel(entity_t *pEntity, const char *pName, idVec3 &vMin, idVec3 &vMax) +{ + eclass_t *e = NULL; + if (pName == NULL || strlen(pName) == 0) { + return NULL; + } + + for (e = g_md3Cache; e ; e = e->next) { + if (!strcmp (pName, e->name)) { + pEntity->md3Class = e; + VectorCopy(e->mins, vMin); + VectorCopy(e->maxs, vMax); + return e; + } + } + + e = (eclass_t*)Mem_ClearedAlloc(sizeof(*e)); + memset (e, 0, sizeof(*e)); + e->name = Mem_CopyString( pName ); + e->color[0] = e->color[2] = 0.85f; + if (LoadModel(pName, e, vMin, vMax, NULL)) { + EClass_InsertSortedList(g_md3Cache, e); + VectorCopy(vMin, e->mins); + VectorCopy(vMax, e->maxs); + pEntity->md3Class = e; + return e; + } + return NULL; +} diff --git a/tools/radiant/EditViewDlg.cpp b/tools/radiant/EditViewDlg.cpp new file mode 100644 index 000000000..ec1e47970 --- /dev/null +++ b/tools/radiant/EditViewDlg.cpp @@ -0,0 +1,294 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "EditViewDlg.h" + + +// CEditViewDlg dialog + +IMPLEMENT_DYNAMIC(CEditViewDlg, CDialog) +CEditViewDlg::CEditViewDlg(CWnd* pParent /*=NULL*/) + : CDialog(CEditViewDlg::IDD, pParent) +{ + findDlg = NULL; +} + +CEditViewDlg::~CEditViewDlg() { +} + +void CEditViewDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT_INFO, editInfo); +} + + +static UINT FindDialogMessage = ::RegisterWindowMessage(FINDMSGSTRING); + +BEGIN_MESSAGE_MAP(CEditViewDlg, CDialog) + ON_WM_SIZE() + ON_BN_CLICKED(IDC_BUTTON_OPEN, OnBnClickedButtonOpen) + ON_BN_CLICKED(IDC_BUTTON_SAVE, OnBnClickedButtonSave) + ON_WM_DESTROY() + ON_WM_TIMER() + ON_BN_CLICKED(IDC_BUTTON_GOTO, OnBnClickedButtonGoto) + ON_REGISTERED_MESSAGE(FindDialogMessage, OnFindDialogMessage) +END_MESSAGE_MAP() + + +// CEditViewDlg message handlers + +void CEditViewDlg::OnSize(UINT nType, int cx, int cy) { + CDialog::OnSize(nType, cx, cy); + if (GetSafeHwnd() == NULL) { + return; + } + CRect rect, crect; + GetClientRect(rect); + CWnd *wnd = GetDlgItem(IDC_BUTTON_OPEN); + if (wnd == NULL || (wnd && wnd->GetSafeHwnd() == NULL)) { + return; + } + wnd->GetWindowRect(crect); + wnd->SetWindowPos(NULL, 4, 4, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + wnd = GetDlgItem(IDC_BUTTON_SAVE); + int left = 8 + crect.Width(); + wnd->SetWindowPos(NULL, left, 4, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + wnd = GetDlgItem(IDOK); + wnd->SetWindowPos(NULL, rect.Width() - crect.Width() - 4, 4, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + editInfo.SetWindowPos(NULL, 4, 8 + crect.Height(), rect.Width() - 8, rect.Height() - crect.Height() * 2 - 16, SWP_SHOWWINDOW); + wnd = GetDlgItem(IDC_BUTTON_GOTO); + wnd->SetWindowPos(NULL, 4, rect.Height() - 4 - crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW); + wnd = GetDlgItem(IDC_EDIT_GOTO); + wnd->SetWindowPos(NULL, 8 + crect.Width(), rect.Height() - 3 - crect.Height(), crect.Width() + 8, crect.Height() - 3, SWP_SHOWWINDOW); + wnd = GetDlgItem(IDC_STATIC_LINE); + wnd->SetWindowPos(NULL, 30 + crect.Width() * 2, rect.Height() - crect.Height(), crect.Width() * 2, crect.Height(), SWP_SHOWWINDOW); + wnd = GetDlgItem(IDC_EDIT_LINE); + wnd->SetWindowPos(NULL, 40 + crect.Width() * 3, rect.Height() - crect.Height(), crect.Width() + 8, crect.Height(), SWP_SHOWWINDOW); +} + +void CEditViewDlg::ShowFindDlg() { + if (findDlg) { + return; + } + findDlg = new CFindReplaceDialog(); + findDlg->Create(TRUE, findStr, NULL, FR_DOWN, this); + +} + +void CEditViewDlg::OnBnClickedButtonOpen() { + CPreviewDlg *dlg = NULL; + dlg = ((mode == MATERIALS) ? CEntityDlg::ShowMaterialChooser() : CEntityDlg::ShowGuiChooser()); + if (dlg) { + if (mode == MATERIALS) { + const idMaterial *mat = declManager->FindMaterial(dlg->mediaName); + SetMaterialInfo(mat->GetName(), mat->GetFileName(), mat->GetLineNum()); + } else { + SetGuiInfo(dlg->mediaName); + } + } +} + +void CEditViewDlg::OnBnClickedButtonSave() { + if (fileName.Length()) { + CString text; + editInfo.GetWindowText(text); + fileSystem->WriteFile(fileName, text.GetBuffer(0), text.GetLength(), "fs_devpath"); + if (mode == MATERIALS) { + declManager->Reload( false ); + } else { + uiManager->Reload(false); + } + } +} + +void CEditViewDlg::UpdateEditPreview() { + if (GetSafeHwnd() && editInfo.GetSafeHwnd()) { + editInfo.SetWindowText(editText); + editInfo.LineScroll(line); + int cindex = editInfo.LineIndex(line); + int len = editInfo.LineLength(line); + editInfo.SetSel(cindex, cindex); + mediaPreview.SetMode((mode == MATERIALS) ? CMediaPreviewDlg::MATERIALS : CMediaPreviewDlg::GUIS); + mediaPreview.SetMedia((mode == MATERIALS) ? matName : fileName); + SetWindowText(va("Editing %s in file <%s>", (mode == MATERIALS) ? matName.c_str() : fileName.c_str(), fileName.c_str())); + editInfo.SetFocus(); + } +} + +BOOL CEditViewDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + mediaPreview.Create(IDD_DIALOG_EDITPREVIEW, this); + mediaPreview.ShowWindow(SW_SHOW); + + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("Radiant::EditViewWindow", &rct, &lSize)) { + SetWindowPos(NULL, rct.left, rct.top, rct.Width(), rct.Height(), SWP_SHOWWINDOW); + } + + editInfo.SetTabStops(); + editInfo.SetLimitText(1024 * 1024); + + UpdateEditPreview(); + + SetTimer(1, 250, NULL); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CEditViewDlg::OnDestroy() { + if (GetSafeHwnd()) { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::EditViewWindow", &rct, sizeof(rct)); + } + + CDialog::OnDestroy(); +} + +void CEditViewDlg::SetMaterialInfo(const char *name, const char *file, int _line) { + idStr str; + void *buf; + fileName = ""; + matName = ""; + line = 0; + str = fileSystem->OSPathToRelativePath( file ); + int size = fileSystem->ReadFile( str, &buf ); + if (size > 0) { + fileName = str; + matName = name; + line = _line - 1; + if (line < 0) { + line = 0; + } + editText = (char*)buf; + fileSystem->FreeFile(buf); + } + UpdateEditPreview(); +} + +void CEditViewDlg::SetGuiInfo(const char *name) { + fileName = ""; + line = 0; + void *buf; + int size = fileSystem->ReadFile(name, &buf, NULL); + if (size > 0) { + fileName = name; + editText = (char*)buf; + fileSystem->FreeFile(buf); + } + UpdateEditPreview(); +} + +void CEditViewDlg::OnTimer(UINT nIDEvent) { + CDialog::OnTimer(nIDEvent); + CWnd *wnd = GetDlgItem(IDC_EDIT_LINE); + if (wnd) { + int start, end; + editInfo.GetSel(start, end); + wnd->SetWindowText(va("%i",editInfo.LineFromChar(start))); + } + +} + +void CEditViewDlg::OnBnClickedButtonGoto() { + CWnd *wnd = GetDlgItem(IDC_EDIT_GOTO); + if (wnd) { + CString str; + wnd->GetWindowText(str); + if (str.GetLength()) { + int l = atoi(str); + editInfo.SetSel(0, 0); + editInfo.LineScroll(l); + int cindex = editInfo.LineIndex(l); + int len = editInfo.LineLength(l); + editInfo.SetSel(cindex, cindex); + editInfo.RedrawWindow(); + editInfo.SetFocus(); + } + } +} + +BOOL CEditViewDlg::PreTranslateMessage(MSG* pMsg) { + + if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == 's' || pMsg->wParam == 'S') && GetAsyncKeyState(VK_CONTROL) & 0x8000) { + OnBnClickedButtonSave(); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == 'o' || pMsg->wParam == 'O') && GetAsyncKeyState(VK_CONTROL) & 0x8000) { + OnBnClickedButtonOpen(); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == 'f' || pMsg->wParam == 'F') && GetAsyncKeyState(VK_CONTROL) & 0x8000) { + ShowFindDlg(); + return TRUE; + } + + if (pMsg->hwnd == editInfo.GetSafeHwnd() && (pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB)) { + // get the char index of the caret position + int nPos = LOWORD(editInfo.CharFromPos(editInfo.GetCaretPos())); + // select zero chars + editInfo.SetSel(nPos, nPos); + // then replace that selection with a TAB + editInfo.ReplaceSel("\t", TRUE); + return TRUE; + } + + return CDialog::PreTranslateMessage(pMsg); +} + +LRESULT CEditViewDlg::OnFindDialogMessage(WPARAM wParam, LPARAM lParam) { + if (findDlg == NULL) { + return 0; + } + + if (findDlg->IsTerminating()) { + findDlg = NULL; + return 0; + } + + // If the FR_FINDNEXT flag is set, + // call the application-defined search routine + // to search for the requested string. + if(findDlg->FindNext()) { + //read data from dialog + findStr = findDlg->GetFindString().GetBuffer(0); + CString str; + editInfo.GetWindowText(str); + editText = str; + int start, end; + editInfo.GetSel(start, end); + start = editText.Find(findStr, false, end); + if (start >= 0) { + editInfo.SetSel(start, start + findStr.Length()); + editInfo.Invalidate(); + editInfo.RedrawWindow(); + } + } + return 0; +} diff --git a/tools/radiant/EditViewDlg.h b/tools/radiant/EditViewDlg.h new file mode 100644 index 000000000..7dea687ed --- /dev/null +++ b/tools/radiant/EditViewDlg.h @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +#include "mediapreviewdlg.h" + +// CEditViewDlg dialog + +class CEditViewDlg : public CDialog +{ + DECLARE_DYNAMIC(CEditViewDlg) + +public: + enum {MATERIALS, GUIS}; + CEditViewDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CEditViewDlg(); + + void SetMode(int _mode) { + mode = _mode; + } + + void SetMaterialInfo(const char *name, const char *file, int line); + void SetGuiInfo(const char *name); + void UpdateEditPreview(); + + void OpenMedia(const char *name); +// Dialog Data + enum { IDD = IDD_DIALOG_EDITVIEW }; + +protected: + CFindReplaceDialog *findDlg; + CMediaPreviewDlg mediaPreview; + int mode; + idStr fileName; + idStr matName; + idStr editText; + idStr findStr; + int line; + CEdit editInfo; + + void ShowFindDlg(); + + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnBnClickedButtonOpen(); + afx_msg void OnBnClickedButtonSave(); + virtual BOOL OnInitDialog(); + afx_msg void OnDestroy(); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnBnClickedButtonGoto(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg LRESULT OnFindDialogMessage(WPARAM wParam, LPARAM lParam); + +}; diff --git a/tools/radiant/EditorBrush.cpp b/tools/radiant/EditorBrush.cpp new file mode 100644 index 000000000..4eb9b83d9 --- /dev/null +++ b/tools/radiant/EditorBrush.cpp @@ -0,0 +1,5211 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include + +#include "../../renderer/tr_local.h" +#include "../../renderer/model_local.h" // for idRenderModelMD5 + +void Brush_UpdateLightPoints(brush_t *b, const idVec3 &offset); +void Brush_DrawCurve( brush_t *b, bool bSelected, bool cam ); + +// globals +int g_nBrushId = 0; +bool g_bShowLightVolumes = false; +bool g_bShowLightTextures = false; + +void GLCircle(float x, float y, float z, float r); + +const int POINTS_PER_KNOT = 50; + +/* +================ +DrawRenderModel +================ +*/ +void DrawRenderModel( idRenderModel *model, idVec3 &origin, idMat3 &axis, bool cameraView ) { + for ( int i = 0; i < model->NumSurfaces(); i++ ) { + const modelSurface_t *surf = model->Surface( i ); + const idMaterial *material = surf->shader; + + int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode; + + if ( cameraView && (nDrawMode == cd_texture || nDrawMode == cd_light) ) { + material->GetEditorImage()->Bind(); + } + + qglBegin( GL_TRIANGLES ); + + const srfTriangles_t *tri = surf->geometry; + for ( int j = 0; j < tri->numIndexes; j += 3 ) { + for ( int k = 0; k < 3; k++ ) { + int index = tri->indexes[j + k]; + idVec3 v; + + v = tri->verts[index].xyz * axis + origin; + qglTexCoord2f( tri->verts[index].st.x, tri->verts[index].st.y ); + qglVertex3fv( v.ToFloatPtr() ); + } + } + + qglEnd(); + } +} + +/* +================ +SnapVectorToGrid +================ +*/ +void SnapVectorToGrid(idVec3 &v) { + v.x = floor(v.x / g_qeglobals.d_gridsize + 0.5f) * g_qeglobals.d_gridsize; + v.y = floor(v.y / g_qeglobals.d_gridsize + 0.5f) * g_qeglobals.d_gridsize; + v.z = floor(v.z / g_qeglobals.d_gridsize + 0.5f) * g_qeglobals.d_gridsize; +} + +/* +================ +Brush_Name +================ +*/ +const char *Brush_Name( brush_t *b ) { + static char cBuff[1024]; + + b->numberId = g_nBrushId++; + if (g_qeglobals.m_bBrushPrimitMode) { + sprintf(cBuff, "Brush %i", b->numberId); + Brush_SetEpair(b, "Name", cBuff); + } + + return cBuff; +} + +/* +================ +Brush_Alloc +================ +*/ +brush_t *Brush_Alloc( void ) { + brush_t *b = new brush_t; + b->prev = b->next = NULL; + b->oprev = b->onext = NULL; + b->owner = NULL; + b->mins.Zero(); + b->maxs.Zero(); + + b->lightCenter.Zero(); + b->lightRight.Zero(); + b->lightTarget.Zero(); + b->lightUp.Zero(); + b->lightRadius.Zero(); + b->lightOffset.Zero(); + b->lightColor.Zero(); + b->lightStart.Zero(); + b->lightEnd.Zero(); + b->pointLight = false; + b->startEnd = false; + b->lightTexture = 0; + b->trackLightOrigin = false; + + b->entityModel = false; + b->brush_faces = NULL; + b->hiddenBrush = false; + b->pPatch = NULL; + b->pUndoOwner = NULL; + b->undoId = 0; + b->redoId = 0; + b->ownerId = 0; + b->numberId = 0; + b->itemOwner = 0; + b->bModelFailed = false; + b->modelHandle = NULL; + b->forceVisibile = false; + b->forceWireFrame = false; + return b; +} + +/* +================ +TextureAxisFromPlane +================ +*/ +idVec3 baseaxis[18] = { + idVec3(0, 0, 1), + idVec3(1, 0, 0), + idVec3(0, -1, 0), + + // floor + idVec3(0, 0, -1), + idVec3(1, 0, 0), + idVec3(0, -1, 0), + + // ceiling + idVec3(1, 0, 0), + idVec3(0, 1, 0), + idVec3(0, 0, -1), + + // west wall + idVec3(-1, 0, 0), + idVec3(0, 1, 0), + idVec3(0, 0, -1), + + // east wall + idVec3(0, 1, 0), + idVec3(1, 0, 0), + idVec3(0, 0, -1), + + // south wall + idVec3(0, -1, 0), + idVec3(1, 0, 0), + idVec3(0, 0, -1) // north wall +}; + +void TextureAxisFromPlane( const idPlane &pln, idVec3 &xv, idVec3 &yv) { + int bestaxis; + float dot, best; + int i; + + best = 0; + bestaxis = 0; + + for (i = 0; i < 6; i++) { + dot = DotProduct(pln, baseaxis[i * 3]); + if (dot > best) { + best = dot; + bestaxis = i; + } + } + + VectorCopy(baseaxis[bestaxis * 3 + 1], xv); + VectorCopy(baseaxis[bestaxis * 3 + 2], yv); +} + +/* +================ +ShadeForNormal + + Light different planes differently to improve recognition +================ +*/ +float lightaxis[3] = { 0.6f, 0.8f, 1.0f }; + +float ShadeForNormal(idVec3 normal) { + int i; + float f; + + // axial plane + for (i = 0; i < 3; i++) { + if ( idMath::Fabs(normal[i]) > 0.9f ) { + f = lightaxis[i]; + return f; + } + } + + // between two axial planes + for (i = 0; i < 3; i++) { + if ( idMath::Fabs(normal[i]) < 0.1f ) { + f = (lightaxis[(i + 1) % 3] + lightaxis[(i + 2) % 3]) / 2; + return f; + } + } + + // other + f = (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3; + return f; +} + +/* +================ +Face_Alloc +================ +*/ +face_t *Face_Alloc(void) { + brushprimit_texdef_t bp; + + face_t *f = (face_t *) Mem_ClearedAlloc(sizeof(*f)); + + bp.coords[0][0] = 0.0f; + bp.coords[1][1] = 0.0f; + f->brushprimit_texdef = bp; + f->dirty = true; + return f; +} + +/* +================ +Face_Free +================ +*/ +void Face_Free(face_t *f) { + assert(f != 0); + + if (f->face_winding) { + delete f->face_winding; + } + + f->texdef.~texdef_t(); + + Mem_Free(f); +} + +/* +================ +Face_Clone +================ +*/ +face_t *Face_Clone(face_t *f) { + face_t *n; + + n = Face_Alloc(); + n->texdef = f->texdef; + n->brushprimit_texdef = f->brushprimit_texdef; + + memcpy(n->planepts, f->planepts, sizeof(n->planepts)); + n->plane = f->plane; + n->originalPlane = f->originalPlane; + n->dirty = f->dirty; + + // all other fields are derived, and will be set by Brush_Build + return n; +} + +/* +================ +Face_FullClone + + Used by Undo. + Makes an exact copy of the face. +================ +*/ +face_t *Face_FullClone(face_t *f) { + face_t *n; + + n = Face_Alloc(); + n->texdef = f->texdef; + n->brushprimit_texdef = f->brushprimit_texdef; + memcpy(n->planepts, f->planepts, sizeof(n->planepts)); + n->plane = f->plane; + n->originalPlane = f->originalPlane; + n->dirty = f->dirty; + if (f->face_winding) { + n->face_winding = f->face_winding->Copy(); + } + else { + n->face_winding = NULL; + } + + n->d_texture = Texture_ForName(n->texdef.name); + return n; +} + +/* +================ +Clamp +================ +*/ +void Clamp(float &f, int nClamp) { + float fFrac = f - static_cast(f); + f = static_cast(f) % nClamp; + f += fFrac; +} + +/* +================ +Face_MoveTexture +================ +*/ +void Face_MoveTexture(face_t *f, idVec3 delta) { + idVec3 vX, vY; + + /* + * #ifdef _DEBUG if (g_PrefsDlg.m_bBrushPrimitMode) common->Printf("Warning : + * Face_MoveTexture not done in brush primitive mode\n"); #endif + */ + if (g_qeglobals.m_bBrushPrimitMode) { + Face_MoveTexture_BrushPrimit(f, delta); + } + else { + TextureAxisFromPlane( f->plane, vX, vY ); + + idVec3 vDP, vShift; + vDP[0] = DotProduct(delta, vX); + vDP[1] = DotProduct(delta, vY); + + double fAngle = DEG2RAD( f->texdef.rotate ); + double c = cos(fAngle); + double s = sin(fAngle); + + vShift[0] = vDP[0] * c - vDP[1] * s; + vShift[1] = vDP[0] * s + vDP[1] * c; + + if (!f->texdef.scale[0]) { + f->texdef.scale[0] = 1; + } + + if (!f->texdef.scale[1]) { + f->texdef.scale[1] = 1; + } + + f->texdef.shift[0] -= vShift[0] / f->texdef.scale[0]; + f->texdef.shift[1] -= vShift[1] / f->texdef.scale[1]; + + // clamp the shifts + Clamp(f->texdef.shift[0], f->d_texture->GetEditorImage()->uploadWidth); + Clamp(f->texdef.shift[1], f->d_texture->GetEditorImage()->uploadHeight); + } +} + +/* +================ +Face_SetColor +================ +*/ +void Face_SetColor(brush_t *b, face_t *f, float fCurveColor) { + float shade; + const idMaterial *q; + + q = f->d_texture; + + // set shading for face + shade = ShadeForNormal( f->plane.Normal() ); + if (g_pParentWnd->GetCamera()->Camera().draw_mode == cd_texture && (b->owner && !b->owner->eclass->fixedsize)) { + // if (b->curveBrush) shade = fCurveColor; + f->d_color[0] = f->d_color[1] = f->d_color[2] = shade; + } + else if ( f && b && b->owner ) { + f->d_color[0] = shade * b->owner->eclass->color.x; + f->d_color[1] = shade * b->owner->eclass->color.y; + f->d_color[2] = shade * b->owner->eclass->color.z; + } +} + +/* +================ +Face_TextureVectors + + NOTE: this is never to get called while in brush primitives mode +================ +*/ +void Face_TextureVectors(face_t *f, float STfromXYZ[2][4]) { + idVec3 pvecs[2]; + int sv, tv; + float ang, sinv, cosv; + float ns, nt; + int i, j; + const idMaterial *q; + texdef_t *td; + +#ifdef _DEBUG + + // + // ++timo when playing with patches, this sometimes get called and the Warning is + // displayed find some way out .. + // + if (g_qeglobals.m_bBrushPrimitMode && !g_qeglobals.bNeedConvert) { + common->Printf("Warning : illegal call of Face_TextureVectors in brush primitive mode\n"); + } +#endif + td = &f->texdef; + q = f->d_texture; + + memset(STfromXYZ, 0, 8 * sizeof (float)); + + if (!td->scale[0]) { + td->scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 2 : 1; + } + + if (!td->scale[1]) { + td->scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 2 : 1; + } + + // get natural texture axis + TextureAxisFromPlane( f->plane, pvecs[0], pvecs[1]); + + // rotate axis + if (td->rotate == 0) { + sinv = 0; + cosv = 1; + } + else if (td->rotate == 90) { + sinv = 1; + cosv = 0; + } + else if (td->rotate == 180) { + sinv = 0; + cosv = -1; + } + else if (td->rotate == 270) { + sinv = -1; + cosv = 0; + } + else { + ang = DEG2RAD( td->rotate ); + sinv = sin(ang); + cosv = cos(ang); + } + + if (pvecs[0][0]) { + sv = 0; + } + else if (pvecs[0][1]) { + sv = 1; + } + else { + sv = 2; + } + + if (pvecs[1][0]) { + tv = 0; + } + else if (pvecs[1][1]) { + tv = 1; + } + else { + tv = 2; + } + + for (i = 0; i < 2; i++) { + ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv]; + nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv]; + STfromXYZ[i][sv] = ns; + STfromXYZ[i][tv] = nt; + } + + // scale + for (i = 0; i < 2; i++) { + for (j = 0; j < 3; j++) { + STfromXYZ[i][j] = STfromXYZ[i][j] / td->scale[i]; + } + } + + // shift + STfromXYZ[0][3] = td->shift[0]; + STfromXYZ[1][3] = td->shift[1]; + + for (j = 0; j < 4; j++) { + STfromXYZ[0][j] /= q->GetEditorImage()->uploadWidth; + STfromXYZ[1][j] /= q->GetEditorImage()->uploadHeight; + } +} + +/* +================ +Face_MakePlane +================ +*/ +void Face_MakePlane(face_t *f) { + int j; + idVec3 t1, t2, t3; + + idPlane oldPlane = f->plane; + + // convert to a vector / dist plane + for (j = 0; j < 3; j++) { + t1[j] = f->planepts[0][j] - f->planepts[1][j]; + t2[j] = f->planepts[2][j] - f->planepts[1][j]; + t3[j] = f->planepts[1][j]; + } + + f->plane = t1.Cross( t2 ); + //if ( f->plane.Compare( vec3_origin ) ) { + // printf("WARNING: brush plane with no normal\n"); + //} + + f->plane.Normalize(false); + f->plane[3] = - (t3 * f->plane.Normal()); + + if ( !f->dirty && !f->plane.Compare( oldPlane, 0.01f ) ) { + f->dirty = true; + } +} + +/* +================ +EmitTextureCoordinates +================ +*/ +void EmitTextureCoordinates(idVec5 &xyzst, const idMaterial *q, face_t *f, bool force) { + float STfromXYZ[2][4]; + + if (g_qeglobals.m_bBrushPrimitMode && !force) { + EmitBrushPrimitTextureCoordinates(f, f->face_winding); + } + else { + Face_TextureVectors(f, STfromXYZ); + xyzst[3] = DotProduct(xyzst, STfromXYZ[0]) + STfromXYZ[0][3]; + xyzst[4] = DotProduct(xyzst, STfromXYZ[1]) + STfromXYZ[1][3]; + } +} + +/* +================ +Brush_MakeFacePlanes +================ +*/ +void Brush_MakeFacePlanes(brush_t *b) { + face_t *f; + + for (f = b->brush_faces; f; f = f->next) { + Face_MakePlane(f); + } +} + +/* +================ +DrawBrushEntityName +================ +*/ +void DrawBrushEntityName(brush_t *b) { + const char *name; + + // float a, s, c; vec3_t mid; int i; + if (!b->owner) { + return; // during contruction + } + + if (b->owner == world_entity) { + return; + } + + if (b != b->owner->brushes.onext) { + return; // not key brush + } + + if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES)) { + // draw the angle pointer + float a = FloatForKey(b->owner, "angle"); + if (a) { + float s = sin( DEG2RAD( a ) ); + float c = cos( DEG2RAD( a ) ); + + idVec3 mid = (b->mins + b->maxs) / 2.0f; + + qglBegin(GL_LINE_STRIP); + qglVertex3fv(mid.ToFloatPtr()); + mid[0] += c * 8; + mid[1] += s * 8; + mid[2] += s * 8; + qglVertex3fv(mid.ToFloatPtr()); + mid[0] -= c * 4; + mid[1] -= s * 4; + mid[2] -= s * 4; + mid[0] -= s * 4; + mid[1] += c * 4; + mid[2] += c * 4; + qglVertex3fv(mid.ToFloatPtr()); + mid[0] += c * 4; + mid[1] += s * 4; + mid[2] += s * 4; + mid[0] += s * 4; + mid[1] -= c * 4; + mid[2] -= c * 4; + qglVertex3fv(mid.ToFloatPtr()); + mid[0] -= c * 4; + mid[1] -= s * 4; + mid[2] -= s * 4; + mid[0] += s * 4; + mid[1] -= c * 4; + mid[2] -= c * 4; + qglVertex3fv(mid.ToFloatPtr()); + qglEnd(); + } + } + + int viewType = g_pParentWnd->ActiveXY()->GetViewType(); + float scale = g_pParentWnd->ActiveXY()->Scale(); + + if (g_qeglobals.d_savedinfo.show_names && scale >= 1.0f) { + name = ValueForKey(b->owner, "name"); + int nameLen = strlen(name); + if ( nameLen == 0 ) { + name = ValueForKey(b->owner, "classname"); + nameLen = strlen(name); + } + if ( nameLen > 0 ) { + idVec3 origin = b->owner->origin; + + float halfWidth = ( (nameLen / 2) * (7.0f / scale) ); + float halfHeight = 4.0f / scale; + + switch (viewType) { + case XY: + origin.x -= halfWidth; + origin.y += halfHeight; + break; + case XZ: + origin.x -= halfWidth; + origin.z += halfHeight; + break; + case YZ: + origin.y -= halfWidth; + origin.z += halfHeight; + break; + } + qglRasterPos3fv( origin.ToFloatPtr() ); + qglCallLists(nameLen, GL_UNSIGNED_BYTE, name); + } + } +} + +/* +================ +Brush_MakeFaceWinding + + returns the visible winding +================ +*/ +idWinding *Brush_MakeFaceWinding(brush_t *b, face_t *face, bool keepOnPlaneWinding) { + idWinding *w; + face_t *clip; + idPlane plane; + bool past; + + // get a poly that covers an effectively infinite area + w = new idWinding( face->plane ); + + // chop the poly by all of the other faces + past = false; + for (clip = b->brush_faces; clip && w; clip = clip->next) { + if (clip == face) { + past = true; + continue; + } + + if ( DotProduct(face->plane, clip->plane) > 0.999f && + idMath::Fabs(face->plane[3] - clip->plane[3]) < 0.01f ) { // identical plane, use the later one + if (past) { + delete w; + common->Printf("Unable to create face winding on brush\n"); + return NULL; + } + continue; + } + + // flip the plane, because we want to keep the back side + VectorSubtract(vec3_origin, clip->plane, plane ); + plane[3] = -clip->plane[3]; + + w = w->Clip( plane, ON_EPSILON, keepOnPlaneWinding ); + if ( !w ) { + return w; + } + } + + if ( w->GetNumPoints() < 3) { + delete w; + w = NULL; + } + + if (!w) { + Sys_Status("Unable to create face winding on brush\n"); + } + return w; +} + +/* +================ +Brush_Build + + Builds a brush rendering data and also sets the min/max bounds + TTimo added a bConvert flag to convert between old and new brush texture formats + TTimo brush grouping: update the group treeview if necessary +================ +*/ +void Brush_Build(brush_t *b, bool bSnap, bool bMarkMap, bool bConvert, bool updateLights) { + bool bLocalConvert = false; + +#ifdef _DEBUG + if (!g_qeglobals.m_bBrushPrimitMode && bConvert) { + common->Printf("Warning : conversion from brush primitive to old brush format not implemented\n"); + } +#endif + // + // if bConvert is set and g_qeglobals.bNeedConvert is not, that just means we need + // convert for this brush only + // + if (bConvert && !g_qeglobals.bNeedConvert) { + bLocalConvert = true; + g_qeglobals.bNeedConvert = true; + } + + /* build the windings and generate the bounding box */ + Brush_BuildWindings(b, bSnap, EntityHasModel(b->owner) || b->pPatch, updateLights); + + /* move the points and edges if in select mode */ + if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge) { + SetupVertexSelection(); + } + + if (bMarkMap) { + Sys_MarkMapModified(); + g_pParentWnd->GetCamera()->MarkWorldDirty(); + } + + if (bLocalConvert) { + g_qeglobals.bNeedConvert = false; + } +} + +/* +================ +Brush_SplitBrushByFace + + The incoming brush is NOT freed. The incoming face is NOT left referenced. +================ +*/ +void Brush_SplitBrushByFace(brush_t *in, face_t *f, brush_t **front, brush_t **back) { + brush_t *b; + face_t *nf; + idVec3 temp; + + b = Brush_Clone(in); + nf = Face_Clone(f); + + nf->texdef = b->brush_faces->texdef; + nf->brushprimit_texdef = b->brush_faces->brushprimit_texdef; + nf->next = b->brush_faces; + b->brush_faces = nf; + + Brush_Build(b); + Brush_RemoveEmptyFaces(b); + if (!b->brush_faces) { // completely clipped away + Brush_Free(b); + *back = NULL; + } + else { + Entity_LinkBrush(in->owner, b); + *back = b; + } + + b = Brush_Clone(in); + nf = Face_Clone(f); + + // swap the plane winding + VectorCopy(nf->planepts[0], temp); + VectorCopy(nf->planepts[1], nf->planepts[0]); + VectorCopy(temp, nf->planepts[1]); + + nf->texdef = b->brush_faces->texdef; + nf->brushprimit_texdef = b->brush_faces->brushprimit_texdef; + nf->next = b->brush_faces; + b->brush_faces = nf; + + Brush_Build(b); + Brush_RemoveEmptyFaces(b); + if (!b->brush_faces) { // completely clipped away + Brush_Free(b); + *front = NULL; + } + else { + Entity_LinkBrush(in->owner, b); + *front = b; + } +} + +/* +================ +Brush_BestSplitFace + + returns the best face to split the brush with. return NULL if the brush is convex +================ +*/ +face_t *Brush_BestSplitFace(brush_t *b) { + face_t *face, *f, *bestface; + idWinding *front, *back; + int splits, tinywindings, value, bestvalue; + + bestvalue = 999999; + bestface = NULL; + for ( face = b->brush_faces; face; face = face->next ) { + splits = 0; + tinywindings = 0; + for ( f = b->brush_faces; f; f = f->next ) { + if ( f == face ) { + continue; + } + + f->face_winding->Split( face->plane, 0.1f, &front, &back ); + + if ( !front ) { + delete back; + } + else if ( !back ) { + delete front; + } + else { + splits++; + if ( front->IsTiny() ) { + tinywindings++; + } + + if ( back->IsTiny() ) { + tinywindings++; + } + delete front; + delete back; + } + } + + if ( splits ) { + value = splits + 50 * tinywindings; + if ( value < bestvalue ) { + bestvalue = value; + bestface = face; + } + } + } + + return bestface; +} + +/* +================ +Brush_MakeConvexBrushes + + MrE FIXME: this doesn't work because the old Brush_SplitBrushByFace is used + Turns the brush into a minimal number of convex brushes. + If the input brush is convex then it will be returned. Otherwise the input + brush will be freed. + NOTE: the input brush should have windings for the faces. +================ +*/ +brush_t *Brush_MakeConvexBrushes(brush_t *b) { + brush_t *front, *back, *end; + face_t *face; + + b->next = NULL; + face = Brush_BestSplitFace(b); + if (!face) { + return b; + } + + Brush_SplitBrushByFace(b, face, &front, &back); + + // this should never happen + if (!front && !back) { + return b; + } + + Brush_Free(b); + if (!front) { + return Brush_MakeConvexBrushes(back); + } + + b = Brush_MakeConvexBrushes(front); + if (back) { + for (end = b; end->next; end = end->next); + end->next = Brush_MakeConvexBrushes(back); + } + + return b; +} + +/* +================ +Brush_Convex + + returns true if the brush is convex +================ +*/ +int Brush_Convex(brush_t *b) { + face_t *face1, *face2; + + for (face1 = b->brush_faces; face1; face1 = face1->next) { + if (!face1->face_winding) { + continue; + } + + for (face2 = b->brush_faces; face2; face2 = face2->next) { + if (face1 == face2) { + continue; + } + + if (!face2->face_winding) { + continue; + } + + if ( face1->face_winding->PlanesConcave( *face2->face_winding, + face1->plane.Normal(), face2->plane.Normal(), -face1->plane[3], -face2->plane[3] ) ) { + return false; + } + } + } + + return true; +} + +/* +================ +Brush_MoveVertexes + + The input brush must be convex. + The input brush must have face windings. + The output brush will be convex. + Returns true if the WHOLE vertex movement is performed. +================ +*/ +#define MAX_MOVE_FACES 64 +#define TINY_EPSILON 0.0325f + +int Brush_MoveVertex(brush_t *b, const idVec3 &vertex, const idVec3 &delta, idVec3 &end, bool bSnap) { + face_t *f, *face, *newface, *lastface, *nextface; + face_t *movefaces[MAX_MOVE_FACES]; + int movefacepoints[MAX_MOVE_FACES]; + idWinding *w, tmpw(3); + idVec3 start, mid; + idPlane plane; + int i, j, k, nummovefaces, result, done; + float dot, front, back, frac, smallestfrac; + + result = true; + tmpw.SetNumPoints( 3 ); + VectorCopy(vertex, start); + VectorAdd(vertex, delta, end); + + // snap or not? + // + if (bSnap) { + for (i = 0; i < 3; i++) { + end[i] = floor( end[i] / 0.125f + 0.5f ) * 0.125f; + } + } + + VectorCopy(end, mid); + + // if the start and end are the same + if ( start.Compare( end, TINY_EPSILON ) ) { + return false; + } + + // the end point may not be the same as another vertex + for ( face = b->brush_faces; face; face = face->next ) { + w = face->face_winding; + if (!w) { + continue; + } + + for (i = 0; i < w->GetNumPoints(); i++) { + if ( end.Compare( (*w)[i].ToVec3(), TINY_EPSILON ) ) { + VectorCopy(vertex, end); + return false; + } + } + } + + done = false; + while (!done) { + // + // chop off triangles from all brush faces that use the to be moved vertex store + // pointers to these chopped off triangles in movefaces[] + // + nummovefaces = 0; + for (face = b->brush_faces; face; face = face->next) { + w = face->face_winding; + if (!w) { + continue; + } + + for (i = 0; i < w->GetNumPoints(); i++) { + if ( start.Compare( (*w)[i].ToVec3(), TINY_EPSILON ) ) { + if (face->face_winding->GetNumPoints() <= 3) { + movefacepoints[nummovefaces] = i; + movefaces[nummovefaces++] = face; + break; + } + + dot = DotProduct(end, face->plane) + face->plane[3]; + + // if the end point is in front of the face plane + //if ( dot > 0.1f ) { + if ( dot > TINY_EPSILON ) { + // fanout triangle subdivision + for (k = i; k < i + w->GetNumPoints() - 3; k++) { + VectorCopy((*w)[i], tmpw[0]); + VectorCopy((*w)[(k + 1) % w->GetNumPoints()], tmpw[1]); + VectorCopy((*w)[(k + 2) % w->GetNumPoints()], tmpw[2]); + newface = Face_Clone(face); + + // get the original + for (f = face; f->original; f = f->original) {}; + + newface->original = f; + + // store the new winding + if (newface->face_winding) { + delete newface->face_winding; + } + + newface->face_winding = tmpw.Copy(); + + // get the texture + newface->d_texture = Texture_ForName(newface->texdef.name); + + // add the face to the brush + newface->next = b->brush_faces; + b->brush_faces = newface; + + // add this new triangle to the move faces + movefacepoints[nummovefaces] = 0; + movefaces[nummovefaces++] = newface; + } + + // give the original face a new winding + VectorCopy((*w)[(i - 2 + w->GetNumPoints()) % w->GetNumPoints()], tmpw[0]); + VectorCopy((*w)[(i - 1 + w->GetNumPoints()) % w->GetNumPoints()], tmpw[1]); + VectorCopy((*w)[i], tmpw[2]); + delete face->face_winding; + face->face_winding = tmpw.Copy(); + + // add the original face to the move faces + movefacepoints[nummovefaces] = 2; + movefaces[nummovefaces++] = face; + } + else { + // chop a triangle off the face + VectorCopy((*w)[(i - 1 + w->GetNumPoints()) % w->GetNumPoints()], tmpw[0]); + VectorCopy((*w)[i], tmpw[1]); + VectorCopy((*w)[(i + 1) % w->GetNumPoints()], tmpw[2]); + + // remove the point from the face winding + w->RemovePoint( i ); + + // get texture crap right + Face_SetColor(b, face, 1.0); + for (j = 0; j < w->GetNumPoints(); j++) { + EmitTextureCoordinates( (*w)[j], face->d_texture, face ); + } + + // make a triangle face + newface = Face_Clone(face); + + // get the original + for (f = face; f->original; f = f->original) {}; + + newface->original = f; + + // store the new winding + if (newface->face_winding) { + delete newface->face_winding; + } + + newface->face_winding = tmpw.Copy(); + + // get the texture + newface->d_texture = Texture_ForName(newface->texdef.name); + + // add the face to the brush + newface->next = b->brush_faces; + b->brush_faces = newface; + movefacepoints[nummovefaces] = 1; + movefaces[nummovefaces++] = newface; + } + break; + } + } + } + + // + // now movefaces contains pointers to triangle faces that contain the to be moved + // vertex + // + done = true; + VectorCopy(end, mid); + smallestfrac = 1; + for (face = b->brush_faces; face; face = face->next) { + // check if there is a move face that has this face as the original + for (i = 0; i < nummovefaces; i++) { + if (movefaces[i]->original == face) { + break; + } + } + + if (i >= nummovefaces) { + continue; + } + + // check if the original is not a move face itself + for (j = 0; j < nummovefaces; j++) { + if (face == movefaces[j]) { + break; + } + } + + // if the original is not a move face itself + if (j >= nummovefaces) { + memcpy(&plane, &movefaces[i]->original->plane, sizeof(plane)); + } + else { + k = movefacepoints[j]; + w = movefaces[j]->face_winding; + VectorCopy((*w)[(k + 1) % w->GetNumPoints()], tmpw[0]); + VectorCopy((*w)[(k + 2) % w->GetNumPoints()], tmpw[1]); + + k = movefacepoints[i]; + w = movefaces[i]->face_winding; + VectorCopy((*w)[(k + 1) % w->GetNumPoints()], tmpw[2]); + + if ( !plane.FromPoints( tmpw[0].ToVec3(), tmpw[1].ToVec3(), tmpw[2].ToVec3(), false ) ) { + VectorCopy((*w)[(k + 2) % w->GetNumPoints()], tmpw[2]); + if ( !plane.FromPoints( tmpw[0].ToVec3(), tmpw[1].ToVec3(), tmpw[2].ToVec3() ), false ) { + // this should never happen otherwise the face merge did + // a crappy job a previous pass + continue; + } + } + plane[0] = -plane[0]; + plane[1] = -plane[1]; + plane[2] = -plane[2]; + plane[3] = -plane[3]; + } + + // now we've got the plane to check against + front = DotProduct(start, plane) + plane[3]; + back = DotProduct(end, plane) + plane[3]; + + // if the whole move is at one side of the plane + if (front < TINY_EPSILON && back < TINY_EPSILON) { + continue; + } + + if (front > -TINY_EPSILON && back > -TINY_EPSILON) { + continue; + } + + // if there's no movement orthogonal to this plane at all + if ( idMath::Fabs(front - back) < 0.001f ) { + continue; + } + + // ok first only move till the plane is hit + frac = front / (front - back); + if (frac < smallestfrac) { + mid[0] = start[0] + (end[0] - start[0]) * frac; + mid[1] = start[1] + (end[1] - start[1]) * frac; + mid[2] = start[2] + (end[2] - start[2]) * frac; + smallestfrac = frac; + } + + done = false; + } + + // move the vertex + for (i = 0; i < nummovefaces; i++) { + // move vertex to end position + VectorCopy( mid, (*movefaces[i]->face_winding)[movefacepoints[i]] ); + + // create new face plane + for (j = 0; j < 3; j++) { + VectorCopy( (*movefaces[i]->face_winding)[j], movefaces[i]->planepts[j] ); + } + + Face_MakePlane( movefaces[i] ); + if ( movefaces[i]->plane.Normal().Length() < TINY_EPSILON ) { + result = false; + } + } + + // if the brush is no longer convex + if (!result || !Brush_Convex(b)) { + for (i = 0; i < nummovefaces; i++) { + // move the vertex back to the initial position + VectorCopy( start, (*movefaces[i]->face_winding)[movefacepoints[i]] ); + + // create new face plane + for (j = 0; j < 3; j++) { + VectorCopy( (*movefaces[i]->face_winding)[j], movefaces[i]->planepts[j] ); + } + + Face_MakePlane(movefaces[i]); + } + + result = false; + VectorCopy(start, end); + done = true; + } + else { + VectorCopy(mid, start); + } + + // get texture crap right + for (i = 0; i < nummovefaces; i++) { + Face_SetColor( b, movefaces[i], 1.0f ); + for (j = 0; j < movefaces[i]->face_winding->GetNumPoints(); j++) { + EmitTextureCoordinates( (*movefaces[i]->face_winding)[j], movefaces[i]->d_texture, movefaces[i] ); + } + } + + // now try to merge faces with their original faces + lastface = NULL; + for (face = b->brush_faces; face; face = nextface) { + nextface = face->next; + if (!face->original) { + lastface = face; + continue; + } + + if ( !face->plane.Compare( face->original->plane, 0.0001f ) ) { + lastface = face; + continue; + } + + w = face->face_winding->TryMerge( *face->original->face_winding, face->plane.Normal(), true ); + if (!w) { + lastface = face; + continue; + } + + delete face->original->face_winding; + face->original->face_winding = w; + + // get texture crap right + Face_SetColor( b, face->original, 1.0f ); + for (j = 0; j < face->original->face_winding->GetNumPoints(); j++) { + EmitTextureCoordinates( (*face->original->face_winding)[j], face->original->d_texture, face->original); + } + + // remove the face that was merged with the original + if (lastface) { + lastface->next = face->next; + } + else { + b->brush_faces = face->next; + } + + Face_Free(face); + } + } + + return result; +} + +/* +================ +Brush_InsertVertexBetween + + Adds a vertex to the brush windings between the given two points. +================ +*/ +int Brush_InsertVertexBetween(brush_t *b, idVec3 p1, idVec3 p2) { + face_t *face; + idWinding *w, *neww; + idVec3 point; + int i, insert; + + if ( p1.Compare( p2, TINY_EPSILON ) ) { + return false; + } + + VectorAdd( p1, p2, point ); + VectorScale( point, 0.5f, point ); + insert = false; + + // the end point may not be the same as another vertex + for (face = b->brush_faces; face; face = face->next) { + w = face->face_winding; + if (!w) { + continue; + } + + neww = NULL; + for (i = 0; i < w->GetNumPoints(); i++) { + if (! p1.Compare((*w)[i].ToVec3(), TINY_EPSILON)) { + continue; + } + + if ( p2.Compare( (*w)[(i + 1) % w->GetNumPoints()].ToVec3(), TINY_EPSILON ) ) { + neww = new idWinding( *w ); + neww->InsertPoint( point, (i + 1) % w->GetNumPoints() ); + break; + } + else if ( p2.Compare( (*w)[(i - 1 + w->GetNumPoints()) % w->GetNumPoints()].ToVec3(), TINY_EPSILON ) ) { + neww = new idWinding( *w ); + neww->InsertPoint( point, i ); + break; + } + } + + if (neww) { + delete face->face_winding; + face->face_winding = neww; + insert = true; + } + } + + return insert; +} + +/* +================ +Brush_ResetFaceOriginals + + reset points to original faces to NULL +================ +*/ +void Brush_ResetFaceOriginals(brush_t *b) { + face_t *face; + + for (face = b->brush_faces; face; face = face->next) { + face->original = NULL; + } +} + +/* +================ +Brush_Parse + + The brush is NOT linked to any list + FIXME: when using old brush primitives, the test loop for "Brush" and "patchDef2" "patchDef3" + run before each face parsing. It works, but it's a performance hit +================ +*/ +brush_t *Brush_Parse(idVec3 origin) { + brush_t *b; + face_t *f; + int i, j; + idVec3 useOrigin = origin; + + g_qeglobals.d_parsed_brushes++; + b = Brush_Alloc(); + do { + if (!GetToken(true)) { + break; + } + + if (!strcmp(token, "}")) { + break; + } + + // handle "Brush" primitive + if ( idStr::Icmp(token, "brushDef") == 0 || idStr::Icmp(token, "brushDef2") == 0 || idStr::Icmp(token, "brushDef3") == 0 ) { + // Timo parsing new brush format + g_qeglobals.bPrimitBrushes = true; + + // check the map is not mixing the two kinds of brushes + if (g_qeglobals.m_bBrushPrimitMode) { + if (g_qeglobals.bOldBrushes) { + common->Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n"); + } + } + else { + // ++Timo write new brush primitive -> old conversion code for Q3->Q2 conversions ? + common->Printf("Warning : conversion code from brush primitive not done ( Brush_Parse )\n"); + } + + bool newFormat = false; + if ( idStr::Icmp(token, "brushDef2") == 0 ) { + newFormat = true; + + // useOrigin.Zero(); + } + else if ( idStr::Icmp(token, "brushDef3") == 0 ) { + newFormat = true; + } + + + BrushPrimit_Parse(b, newFormat, useOrigin); + + if (newFormat) { + //Brush_BuildWindings(b, true, true, false, false); + } + + if (b == NULL) { + Warning("parsing brush primitive"); + return NULL; + } + else { + continue; + } + } + + if ( idStr::Icmp(token, "patchDef2") == 0 || idStr::Icmp(token, "patchDef3") == 0 ) { + Brush_Free(b); + + // double string compare but will go away soon + b = Patch_Parse( idStr::Icmp(token, "patchDef2") == 0 ); + if (b == NULL) { + Warning("parsing patch/brush"); + return NULL; + } + else { + continue; + } + + // handle inline patch + } + else { + // Timo parsing old brush format + g_qeglobals.bOldBrushes = true; + if (g_qeglobals.m_bBrushPrimitMode) { + // check the map is not mixing the two kinds of brushes + if (g_qeglobals.bPrimitBrushes) { + common->Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n"); + } + + // set the "need" conversion flag + g_qeglobals.bNeedConvert = true; + } + + f = Face_Alloc(); + + // + // add the brush to the end of the chain, so loading and saving a map doesn't + // reverse the order + // + f->next = NULL; + if (!b->brush_faces) { + b->brush_faces = f; + } + else { + face_t *scan; + for (scan = b->brush_faces; scan->next; scan = scan->next) + ; + scan->next = f; + } + + // read the three point plane definition + for (i = 0; i < 3; i++) { + if (i != 0) { + GetToken(true); + } + + if (strcmp(token, "(")) { + Warning("parsing brush"); + return NULL; + } + + for (j = 0; j < 3; j++) { + GetToken(false); + f->planepts[i][j] = atof(token); + } + + GetToken(false); + if (strcmp(token, ")")) { + Warning("parsing brush"); + return NULL; + } + } + } + + // read the texturedef + GetToken(false); + f->texdef.SetName(token); + if (token[0] == '(') { + int i = 32; + } + + GetToken(false); + f->texdef.shift[0] = atoi(token); + GetToken(false); + f->texdef.shift[1] = atoi(token); + GetToken(false); + f->texdef.rotate = atoi(token); + GetToken(false); + f->texdef.scale[0] = atof(token); + GetToken(false); + f->texdef.scale[1] = atof(token); + + // the flags and value field aren't necessarily present + f->d_texture = Texture_ForName(f->texdef.name); + + // + // FIXME: idMaterial f->texdef.flags = f->d_texture->flags; f->texdef.value = + // f->d_texture->value; f->texdef.contents = f->d_texture->contents; + // + if (TokenAvailable()) { + GetToken(false); + GetToken(false); + GetToken(false); + f->texdef.value = atoi(token); + } + } while (1); + + return b; +} + +/* +================ +QERApp_MapPrintf_FILE + + callback for surface properties plugin must fit a PFN_QERAPP_MAPPRINTF ( see isurfaceplugin.h ) + carefully initialize ! +================ +*/ +FILE *g_File; + +void WINAPI QERApp_MapPrintf_FILE(char *text, ...) { + va_list argptr; + char buf[32768]; + + va_start(argptr, text); + vsprintf(buf, text, argptr); + va_end(argptr); + + fprintf(g_File, buf); +} + +/* +================ +Brush_SetEpair + + sets an epair for the given brush +================ +*/ +void Brush_SetEpair(brush_t *b, const char *pKey, const char *pValue) { + if (g_qeglobals.m_bBrushPrimitMode) { + if (b->pPatch) { + Patch_SetEpair(b->pPatch, pKey, pValue); + } + else { + b->epairs.Set(pKey, pValue); + } + } + else { + Sys_Status("Can only set key/values in Brush primitive mode\n"); + } +} + +/* +================ +Brush_GetKeyValue +================ +*/ +const char *Brush_GetKeyValue(brush_t *b, const char *pKey) { + if (g_qeglobals.m_bBrushPrimitMode) { + if (b->pPatch) { + return Patch_GetKeyValue(b->pPatch, pKey); + } + else { + return b->epairs.GetString(pKey); + } + } + else { + Sys_Status("Can only set brush/patch key/values in Brush primitive mode\n"); + } + + return ""; +} + +/* +================ +Brush_Write + + save all brushes as Brush primitive format +================ +*/ +void Brush_Write(brush_t *b, FILE *f, const idVec3 &origin, bool newFormat) { + face_t *fa; + char *pname; + int i; + + if (b->pPatch) { + Patch_Write(b->pPatch, f); + return; + } + + if (g_qeglobals.m_bBrushPrimitMode) { + // save brush primitive format + if (newFormat) { + WriteFileString(f, "{\nbrushDef3\n{\n"); + } + else { + WriteFileString(f, "{\nbrushDef\n{\n"); + } + + // brush epairs + int count = b->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + WriteFileString(f, "\"%s\" \"%s\"\n", b->epairs.GetKeyVal(j)->GetKey().c_str(), b->epairs.GetKeyVal(j)->GetValue().c_str()); + } + + for (fa = b->brush_faces; fa; fa = fa->next) { + // save planepts + if (newFormat) { + idPlane plane; + + if (fa->dirty) { + fa->planepts[0] -= origin; + fa->planepts[1] -= origin; + fa->planepts[2] -= origin; + plane.FromPoints( fa->planepts[0], fa->planepts[1], fa->planepts[2], false ); + fa->planepts[0] += origin; + fa->planepts[1] += origin; + fa->planepts[2] += origin; + } else { + plane = fa->originalPlane; + } + + WriteFileString(f, " ( "); + for (i = 0; i < 4; i++) { + if (plane[i] == (int)plane[i]) { + WriteFileString(f, "%i ", (int)plane[i]); + } + else { + WriteFileString(f, "%f ", plane[i]); + } + } + + WriteFileString(f, ") "); + } + else { + for (i = 0; i < 3; i++) { + WriteFileString(f, "( "); + for (int j = 0; j < 3; j++) { + if (fa->planepts[i][j] == static_cast(fa->planepts[i][j])) { + WriteFileString(f, "%i ", static_cast(fa->planepts[i][j])); + } + else { + WriteFileString(f, "%f ", fa->planepts[i][j]); + } + } + + WriteFileString(f, ") "); + } + } + + // save texture coordinates + WriteFileString(f, "( ( "); + for (i = 0; i < 3; i++) { + if (fa->brushprimit_texdef.coords[0][i] == static_cast(fa->brushprimit_texdef.coords[0][i])) { + WriteFileString(f, "%i ", static_cast(fa->brushprimit_texdef.coords[0][i])); + } + else { + WriteFileString(f, "%f ", fa->brushprimit_texdef.coords[0][i]); + } + } + + WriteFileString(f, ") ( "); + for (i = 0; i < 3; i++) { + if (fa->brushprimit_texdef.coords[1][i] == static_cast(fa->brushprimit_texdef.coords[1][i])) { + WriteFileString(f, "%i ", static_cast(fa->brushprimit_texdef.coords[1][i])); + } + else { + WriteFileString(f, "%f ", fa->brushprimit_texdef.coords[1][i]); + } + } + + WriteFileString(f, ") ) "); + + char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "notexture"; + WriteFileString(f, "\"%s\" ", pName); + WriteFileString(f, "%i %i %i\n", 0, 0, 0); + } + + WriteFileString(f, "}\n}\n"); + } + else { + WriteFileString(f, "{\n"); + for (fa = b->brush_faces; fa; fa = fa->next) { + for (i = 0; i < 3; i++) { + WriteFileString(f, "( "); + for (int j = 0; j < 3; j++) { + if (fa->planepts[i][j] == static_cast(fa->planepts[i][j])) { + WriteFileString(f, "%i ", static_cast(fa->planepts[i][j])); + } + else { + WriteFileString(f, "%f ", fa->planepts[i][j]); + } + } + + WriteFileString(f, ") "); + } + + pname = fa->texdef.name; + if (pname[0] == 0) { + pname = "unnamed"; + } + + WriteFileString + ( + f, + "%s %i %i %i ", + pname, + (int)fa->texdef.shift[0], + (int)fa->texdef.shift[1], + (int)fa->texdef.rotate + ); + + if (fa->texdef.scale[0] == (int)fa->texdef.scale[0]) { + WriteFileString(f, "%i ", (int)fa->texdef.scale[0]); + } + else { + WriteFileString(f, "%f ", (float)fa->texdef.scale[0]); + } + + if (fa->texdef.scale[1] == (int)fa->texdef.scale[1]) { + WriteFileString(f, "%i", (int)fa->texdef.scale[1]); + } + else { + WriteFileString(f, "%f", (float)fa->texdef.scale[1]); + } + + WriteFileString(f, " %i %i %i",0, 0, 0); + + WriteFileString(f, "\n"); + } + + WriteFileString(f, "}\n"); + } +} + +/* +================ +QERApp_MapPrintf_MEMFILE + + callback for surface properties plugin must fit a PFN_QERAPP_MAPPRINTF ( see isurfaceplugin.h ) + carefully initialize ! +================ +*/ +CMemFile *g_pMemFile; + +void WINAPI QERApp_MapPrintf_MEMFILE(char *text, ...) { + va_list argptr; + char buf[32768]; + + va_start(argptr, text); + vsprintf(buf, text, argptr); + va_end(argptr); + + MemFile_fprintf(g_pMemFile, buf); +} + +/* +================ +Brush_Write + + save all brushes as Brush primitive format to a CMemFile* +================ +*/ +void Brush_Write(brush_t *b, CMemFile *pMemFile, const idVec3 &origin, bool newFormat) { + face_t *fa; + char *pname; + int i; + + if (b->pPatch) { + Patch_Write(b->pPatch, pMemFile); + return; + } + + if (g_qeglobals.m_bBrushPrimitMode) { + // brush primitive format + if (newFormat) { + MemFile_fprintf(pMemFile, "{\nBrushDef2\n{\n"); + } + else { + MemFile_fprintf(pMemFile, "{\nBrushDef\n{\n"); + } + + // brush epairs + // brush epairs + int count = b->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + MemFile_fprintf(pMemFile, "\"%s\" \"%s\"\n", b->epairs.GetKeyVal(j)->GetKey().c_str(), b->epairs.GetKeyVal(j)->GetValue().c_str()); + } + + for (fa = b->brush_faces; fa; fa = fa->next) { + if (newFormat) { + // save planepts + idPlane plane; + + if (fa->dirty) { + fa->planepts[0] -= origin; + fa->planepts[1] -= origin; + fa->planepts[2] -= origin; + plane.FromPoints( fa->planepts[0], fa->planepts[1], fa->planepts[2], false ); + fa->planepts[0] += origin; + fa->planepts[1] += origin; + fa->planepts[2] += origin; + } else { + plane = fa->originalPlane; + } + + MemFile_fprintf(pMemFile, " ( "); + for (i = 0; i < 4; i++) { + if (plane[i] == (int)plane[i]) { + MemFile_fprintf(pMemFile, "%i ", (int)plane[i]); + } + else { + MemFile_fprintf(pMemFile, "%f ", plane[i]); + } + } + + MemFile_fprintf(pMemFile, ") "); + } + else { + for (i = 0; i < 3; i++) { + MemFile_fprintf(pMemFile, "( "); + for (int j = 0; j < 3; j++) { + if (fa->planepts[i][j] == static_cast(fa->planepts[i][j])) { + MemFile_fprintf(pMemFile, "%i ", static_cast(fa->planepts[i][j])); + } + else { + MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]); + } + } + + MemFile_fprintf(pMemFile, ") "); + } + } + + // save texture coordinates + MemFile_fprintf(pMemFile, "( ( "); + for (i = 0; i < 3; i++) { + if (fa->brushprimit_texdef.coords[0][i] == static_cast(fa->brushprimit_texdef.coords[0][i])) { + MemFile_fprintf(pMemFile, "%i ", static_cast(fa->brushprimit_texdef.coords[0][i])); + } + else { + MemFile_fprintf(pMemFile, "%f ", fa->brushprimit_texdef.coords[0][i]); + } + } + + MemFile_fprintf(pMemFile, ") ( "); + for (i = 0; i < 3; i++) { + if (fa->brushprimit_texdef.coords[1][i] == static_cast(fa->brushprimit_texdef.coords[1][i])) { + MemFile_fprintf(pMemFile, "%i ", static_cast(fa->brushprimit_texdef.coords[1][i])); + } + else { + MemFile_fprintf(pMemFile, "%f ", fa->brushprimit_texdef.coords[1][i]); + } + } + + MemFile_fprintf(pMemFile, ") ) "); + + // save texture attribs + char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "unnamed"; + MemFile_fprintf(pMemFile, "\"%s\" ", pName); + MemFile_fprintf(pMemFile, "%i %i %i\n", 0, 0, 0); + } + + MemFile_fprintf(pMemFile, "}\n}\n"); + } + else { + // old brushes format also handle surface properties plugin + MemFile_fprintf(pMemFile, "{\n"); + for (fa = b->brush_faces; fa; fa = fa->next) { + for (i = 0; i < 3; i++) { + MemFile_fprintf(pMemFile, "( "); + for (int j = 0; j < 3; j++) { + if (fa->planepts[i][j] == static_cast(fa->planepts[i][j])) { + MemFile_fprintf(pMemFile, "%i ", static_cast(fa->planepts[i][j])); + } + else { + MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]); + } + } + + MemFile_fprintf(pMemFile, ") "); + } + + pname = fa->texdef.name; + if (pname[0] == 0) { + pname = "unnamed"; + } + + MemFile_fprintf + ( + pMemFile, + "%s %i %i %i ", + pname, + (int)fa->texdef.shift[0], + (int)fa->texdef.shift[1], + (int)fa->texdef.rotate + ); + + if (fa->texdef.scale[0] == (int)fa->texdef.scale[0]) { + MemFile_fprintf(pMemFile, "%i ", (int)fa->texdef.scale[0]); + } + else { + MemFile_fprintf(pMemFile, "%f ", (float)fa->texdef.scale[0]); + } + + if (fa->texdef.scale[1] == (int)fa->texdef.scale[1]) { + MemFile_fprintf(pMemFile, "%i", (int)fa->texdef.scale[1]); + } + else { + MemFile_fprintf(pMemFile, "%f", (float)fa->texdef.scale[1]); + } + + MemFile_fprintf(pMemFile, " %i %i %i", 0, 0, 0); + + MemFile_fprintf(pMemFile, "\n"); + } + + MemFile_fprintf(pMemFile, "}\n"); + } +} + +/* +================ +Brush_Create + + Create non-textured blocks for entities The brush is NOT linked to any list +================ +*/ +brush_t *Brush_Create(idVec3 mins, idVec3 maxs, texdef_t *texdef) { + int i, j; + idVec3 pts[4][2]; + face_t *f; + brush_t *b; + + // + // brush primitive mode : convert texdef to brushprimit_texdef ? most of the time + // texdef is empty + // + for (i = 0; i < 3; i++) { + if (maxs[i] < mins[i]) { + Error("Brush_InitSolid: backwards"); + } + } + + b = Brush_Alloc(); + + pts[0][0][0] = mins[0]; + pts[0][0][1] = mins[1]; + + pts[1][0][0] = mins[0]; + pts[1][0][1] = maxs[1]; + + pts[2][0][0] = maxs[0]; + pts[2][0][1] = maxs[1]; + + pts[3][0][0] = maxs[0]; + pts[3][0][1] = mins[1]; + + for (i = 0; i < 4; i++) { + pts[i][0][2] = mins[2]; + pts[i][1][0] = pts[i][0][0]; + pts[i][1][1] = pts[i][0][1]; + pts[i][1][2] = maxs[2]; + } + + for (i = 0; i < 4; i++) { + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + j = (i + 1) % 4; + + VectorCopy(pts[j][1], f->planepts[0]); + VectorCopy(pts[i][1], f->planepts[1]); + VectorCopy(pts[i][0], f->planepts[2]); + } + + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy(pts[0][1], f->planepts[0]); + VectorCopy(pts[1][1], f->planepts[1]); + VectorCopy(pts[2][1], f->planepts[2]); + + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy(pts[2][0], f->planepts[0]); + VectorCopy(pts[1][0], f->planepts[1]); + VectorCopy(pts[0][0], f->planepts[2]); + + return b; +} + +/* +============= +Brush_Scale +============= +*/ +void Brush_Scale(brush_t* b) { + for ( face_t *f = b->brush_faces; f; f = f->next ) { + for ( int i = 0; i < 3; i++ ) { + VectorScale( f->planepts[i], g_qeglobals.d_gridsize, f->planepts[i] ); + } + } +} + +/* +================ +Brush_CreatePyramid + + Create non-textured pyramid for light entities The brush is NOT linked to any list +================ +*/ +brush_t *Brush_CreatePyramid(idVec3 mins, idVec3 maxs, texdef_t *texdef) { + // ++timo handle new brush primitive ? return here ?? + return Brush_Create(mins, maxs, texdef); + + int i; + for (i = 0; i < 3; i++) { + if (maxs[i] < mins[i]) { + Error("Brush_InitSolid: backwards"); + } + } + + brush_t *b = Brush_Alloc(); + + idVec3 corners[4]; + + float fMid = idMath::Rint(mins[2] + (idMath::Rint((maxs[2] - mins[2]) / 2))); + + corners[0][0] = mins[0]; + corners[0][1] = mins[1]; + corners[0][2] = fMid; + + corners[1][0] = mins[0]; + corners[1][1] = maxs[1]; + corners[1][2] = fMid; + + corners[2][0] = maxs[0]; + corners[2][1] = maxs[1]; + corners[2][2] = fMid; + + corners[3][0] = maxs[0]; + corners[3][1] = mins[1]; + corners[3][2] = fMid; + + idVec3 top, bottom; + + top[0] = idMath::Rint(mins[0] + ((maxs[0] - mins[0]) / 2)); + top[1] = idMath::Rint(mins[1] + ((maxs[1] - mins[1]) / 2)); + top[2] = idMath::Rint(maxs[2]); + + VectorCopy(top, bottom); + bottom[2] = mins[2]; + + // sides + for (i = 0; i < 4; i++) { + face_t *f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + int j = (i + 1) % 4; + + VectorCopy(top, f->planepts[0]); + VectorCopy(corners[i], f->planepts[1]); + VectorCopy(corners[j], f->planepts[2]); + + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy(bottom, f->planepts[2]); + VectorCopy(corners[i], f->planepts[1]); + VectorCopy(corners[j], f->planepts[0]); + } + + return b; +} + +/* +================ +Brush_MakeSided + + Makes the current brush have the given number of 2d sides +================ +*/ +void Brush_MakeSided(int sides) { + int i, axis; + idVec3 mins, maxs; + brush_t *b; + texdef_t *texdef; + face_t *f; + idVec3 mid; + float width; + float sv, cv; + + if (sides < 3) { + Sys_Status("Bad sides number", 0); + return; + } + + if (sides >= MAX_POINTS_ON_WINDING - 4) { + Sys_Status("too many sides.\n"); + return; + } + + if (!QE_SingleBrush()) { + Sys_Status("Must have a single brush selected", 0); + return; + } + + b = selected_brushes.next; + VectorCopy(b->mins, mins); + VectorCopy(b->maxs, maxs); + texdef = &g_qeglobals.d_texturewin.texdef; + + Brush_Free(b); + + if (g_pParentWnd->ActiveXY()) { + switch (g_pParentWnd->ActiveXY()->GetViewType()) + { + case XY: + axis = 2; + break; + case XZ: + axis = 1; + break; + case YZ: + axis = 0; + break; + } + } + else { + axis = 2; + } + + // find center of brush + width = 8; + for (i = 0; i < 3; i++) { + mid[i] = (maxs[i] + mins[i]) * 0.5f; + if (i == axis) { + continue; + } + + if ((maxs[i] - mins[i]) * 0.5f > width) { + width = (maxs[i] - mins[i]) * 0.5f; + } + } + + b = Brush_Alloc(); + + // create top face + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + f->planepts[2][(axis + 1) % 3] = mins[(axis + 1) % 3]; + f->planepts[2][(axis + 2) % 3] = mins[(axis + 2) % 3]; + f->planepts[2][axis] = maxs[axis]; + f->planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; + f->planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; + f->planepts[1][axis] = maxs[axis]; + f->planepts[0][(axis + 1) % 3] = maxs[(axis + 1) % 3]; + f->planepts[0][(axis + 2) % 3] = maxs[(axis + 2) % 3]; + f->planepts[0][axis] = maxs[axis]; + + // create bottom face + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + f->planepts[0][(axis + 1) % 3] = mins[(axis + 1) % 3]; + f->planepts[0][(axis + 2) % 3] = mins[(axis + 2) % 3]; + f->planepts[0][axis] = mins[axis]; + f->planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; + f->planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; + f->planepts[1][axis] = mins[axis]; + f->planepts[2][(axis + 1) % 3] = maxs[(axis + 1) % 3]; + f->planepts[2][(axis + 2) % 3] = maxs[(axis + 2) % 3]; + f->planepts[2][axis] = mins[axis]; + + for (i = 0; i < sides; i++) { + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + sv = sin(i * 3.14159265 * 2 / sides); + cv = cos(i * 3.14159265 * 2 / sides); + + f->planepts[0][(axis + 1) % 3] = floor(mid[(axis + 1) % 3] + width * cv + 0.5f); + f->planepts[0][(axis + 2) % 3] = floor(mid[(axis + 2) % 3] + width * sv + 0.5f); + f->planepts[0][axis] = mins[axis]; + + f->planepts[1][(axis + 1) % 3] = f->planepts[0][(axis + 1) % 3]; + f->planepts[1][(axis + 2) % 3] = f->planepts[0][(axis + 2) % 3]; + f->planepts[1][axis] = maxs[axis]; + + f->planepts[2][(axis + 1) % 3] = floor(f->planepts[0][(axis + 1) % 3] - width * sv + 0.5f); + f->planepts[2][(axis + 2) % 3] = floor(f->planepts[0][(axis + 2) % 3] + width * cv + 0.5f); + f->planepts[2][axis] = maxs[axis]; + } + + Brush_AddToList(b, &selected_brushes); + + Entity_LinkBrush(world_entity, b); + + Brush_Build(b); + + Sys_UpdateWindows(W_ALL); +} + +/* +================ +Brush_Free + + Frees the brush with all of its faces and display list. + Unlinks the brush from whichever chain it is in. + Decrements the owner entity's brushcount. + Removes owner entity if this was the last brush unless owner is the world. + Removes from groups + + set bRemoveNode to false to avoid trying to delete the item in group view tree control +================ +*/ +void Brush_Free(brush_t *b, bool bRemoveNode) { + face_t *f, *next; + + // free the patch if it's there + if ( b->pPatch ) { + Patch_Delete(b->pPatch); + } + + // free faces + for ( f = b->brush_faces; f; f = next ) { + next = f->next; + Face_Free(f); + } + + b->epairs.Clear(); + + // unlink from active/selected list + if ( b->next ) { + Brush_RemoveFromList(b); + } + + // unlink from entity list + if ( b->onext ) { + Entity_UnlinkBrush(b); + } + + delete b; +} + +/* +================ +Face_MemorySize + + returns the size in memory of the face +================ +*/ +int Face_MemorySize(face_t *f) { + int size = 0; + + if ( f->face_winding ) { + size += sizeof( idWinding ) + f->face_winding->GetNumPoints() * sizeof( (f->face_winding)[0] ); + } + size += sizeof( face_t ); + return size; +} + +/* +================ +Brush_MemorySize + + returns the size in memory of the brush +================ +*/ +int Brush_MemorySize( brush_t *b ) { + face_t *f; + int size = 0; + if ( b->pPatch ) { + size += Patch_MemorySize( b->pPatch ); + } + + for ( f = b->brush_faces; f; f = f->next ) { + size += Face_MemorySize(f); + } + + size += sizeof( brush_t ) + b->epairs.Size(); + return size; +} + +/* +================ +Brush_Clone + + does not add the brush to any lists +================ +*/ +brush_t *Brush_Clone(brush_t *b) { + brush_t *n = NULL; + face_t *f, *nf; + + if (b->pPatch) { + patchMesh_t *p = Patch_Duplicate(b->pPatch); + Brush_RemoveFromList(p->pSymbiot); + Entity_UnlinkBrush(p->pSymbiot); + n = p->pSymbiot; + } + else { + n = Brush_Alloc(); + n->numberId = g_nBrushId++; + n->owner = b->owner; + n->lightColor = b->lightColor; + n->lightEnd = b->lightEnd; + n->lightOffset = b->lightOffset; + n->lightRadius = b->lightRadius; + n->lightRight = b->lightRight; + n->lightStart = b->lightStart; + n->lightTarget = b->lightTarget; + n->lightCenter = b->lightCenter; + n->lightTexture = b->lightTexture; + n->lightUp = b->lightUp; + n->modelHandle = b->modelHandle; + n->pointLight = b->pointLight; + for (f = b->brush_faces; f; f = f->next) { + nf = Face_Clone(f); + nf->next = n->brush_faces; + n->brush_faces = nf; + } + } + + return n; +} + +/* +================ +Brush_FullClone + + Used by Undo. + Makes an exact copy of the brush. + Does NOT add the new brush to any lists. +================ +*/ +brush_t *Brush_FullClone(brush_t *b) { + brush_t *n = NULL; + face_t *f, *nf, *f2, *nf2; + int j; + + if (b->pPatch) { + patchMesh_t *p = Patch_Duplicate(b->pPatch); + Brush_RemoveFromList(p->pSymbiot); + Entity_UnlinkBrush(p->pSymbiot); + n = p->pSymbiot; + n->owner = b->owner; + Brush_Build(n); + } + else { + n = Brush_Alloc(); + n->numberId = g_nBrushId++; + n->owner = b->owner; + n->lightColor = b->lightColor; + n->lightEnd = b->lightEnd; + n->lightOffset = b->lightOffset; + n->lightRadius = b->lightRadius; + n->lightRight = b->lightRight; + n->lightStart = b->lightStart; + n->lightTarget = b->lightTarget; + n->lightCenter = b->lightCenter; + n->lightTexture = b->lightTexture; + n->lightUp = b->lightUp; + n->modelHandle = b->modelHandle; + n->pointLight = b->pointLight; + VectorCopy(b->mins, n->mins); + VectorCopy(b->maxs, n->maxs); + for (f = b->brush_faces; f; f = f->next) { + if (f->original) { + continue; + } + + nf = Face_FullClone(f); + nf->next = n->brush_faces; + n->brush_faces = nf; + + // copy all faces that have the original set to this face + for (f2 = b->brush_faces; f2; f2 = f2->next) { + if (f2->original == f) { + nf2 = Face_FullClone(f2); + nf2->next = n->brush_faces; + n->brush_faces = nf2; + + // set original + nf2->original = nf; + } + } + } + + for (nf = n->brush_faces; nf; nf = nf->next) { + Face_SetColor( n, nf, 1.0f ); + if (nf->face_winding) { + if (g_qeglobals.m_bBrushPrimitMode) { + EmitBrushPrimitTextureCoordinates(nf, nf->face_winding); + } + else { + for (j = 0; j < nf->face_winding->GetNumPoints(); j++) { + EmitTextureCoordinates( (*nf->face_winding)[j], nf->d_texture, nf ); + } + } + } + } + } + + return n; +} + +extern bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat); +extern bool Patch_Intersect(patchMesh_t *pm, idVec3 origin, idVec3 direction , float &scale); +extern bool RayIntersectsTri + ( + const idVec3 &origin, + const idVec3 &direction, + const idVec3 &vert0, + const idVec3 &vert1, + const idVec3 &vert2, + float &scale + ); + + +/* +================ +RotateVector +================ +*/ +void RotateVector(idVec3 &v, idVec3 origin, float a, float c, float s) { + float x = v[0]; + float y = v[1]; + if (a) { + float x2 = (((x - origin[0]) * c) - ((y - origin[1]) * s)) + origin[0]; + float y2 = (((x - origin[0]) * s) + ((y - origin[1]) * c)) + origin[1]; + x = x2; + y = y2; + } + v[0] = x; + v[1] = y; +} +/* +================ +Brush_ModelIntersect +================ +*/ + +bool Brush_ModelIntersect(brush_t *b, idVec3 origin, idVec3 dir,float &scale) { + idRenderModel *model = b->modelHandle; + idRenderModel *md5; + + if ( !model ) + model = b->owner->eclass->entityModel; + + scale = 0; + if (model) { + if ( model->IsDynamicModel() != DM_STATIC ) { + if ( dynamic_cast( model ) ) { + // take care of animated models + md5 = b->owner->eclass->entityModel; + + const char *classname = ValueForKey( b->owner, "classname" ); + if (stricmp(classname, "func_static") == 0) { + classname = ValueForKey(b->owner, "animclass"); + } + const char *anim = ValueForKey( b->owner, "anim" ); + int frame = IntForKey( b->owner, "frame" ) + 1; + if ( frame < 1 ) { + frame = 1; + } + if ( !anim || !anim[ 0 ] ) { + anim = "idle"; + } + model = gameEdit->ANIM_CreateMeshForAnim( md5, classname, anim, frame, false ); + if ( !model ) { + model = renderModelManager->DefaultModel(); + } + } + } + + bool matrix = false; + idMat3 mat; + float a, s, c; + if (GetMatrixForKey(b->owner, "rotation", mat)) { + matrix = true; + } else { + a = FloatForKey(b->owner, "angle"); + if (a) { + s = sin( DEG2RAD( a ) ); + c = cos( DEG2RAD( a ) ); + } + else { + s = c = 0; + } + } + + for (int i = 0; i < model->NumSurfaces() ; i++) { + const modelSurface_t *surf = model->Surface( i ); + srfTriangles_t *tri = surf->geometry; + for (int j = 0; j < tri->numIndexes; j += 3) { + idVec3 v1, v2, v3; + v1 = tri->verts[tri->indexes[j]].xyz; + v2 = tri->verts[tri->indexes[j + 1]].xyz; + v3 = tri->verts[tri->indexes[j + 2]].xyz; + + if (matrix) { + v1 *= b->owner->rotation; + v1 += b->owner->origin; + v2 *= b->owner->rotation; + v2 += b->owner->origin; + v3 *= b->owner->rotation; + v3 += b->owner->origin; + } else { + v1 += b->owner->origin; + v2 += b->owner->origin; + v3 += b->owner->origin; + RotateVector(v1, b->owner->origin, a, c, s); + RotateVector(v2, b->owner->origin, a, c, s); + RotateVector(v3, b->owner->origin, a, c, s); + } + + if (RayIntersectsTri(origin, dir, v1, v2, v3,scale)) { + return true; + } + } + } + } + + return false; +} + +face_t *Brush_Ray(idVec3 origin, idVec3 dir, brush_t *b, float *dist, bool testPrimitive) { + face_t *f, *firstface = NULL; + idVec3 p1, p2; + float frac, d1, d2; + int i; + float scale = HUGE_DISTANCE * 2; + VectorCopy(origin, p1); + for (i = 0; i < 3; i++) { + p2[i] = p1[i] + dir[i] * HUGE_DISTANCE * 2; + } + + for (f = b->brush_faces; f; f = f->next) { + d1 = DotProduct(p1, f->plane) + f->plane[3]; + d2 = DotProduct(p2, f->plane) + f->plane[3]; + if (d1 >= 0 && d2 >= 0) { + *dist = 0; + return NULL; // ray is on front side of face + } + + if (d1 <= 0 && d2 <= 0) { + continue; + } + + // clip the ray to the plane + frac = d1 / (d1 - d2); + if (d1 > 0) { + firstface = f; + for (i = 0; i < 3; i++) { + p1[i] = p1[i] + frac * (p2[i] - p1[i]); + } + } + else { + for (i = 0; i < 3; i++) { + p2[i] = p1[i] + frac * (p2[i] - p1[i]); + } + } + } + + // find distance p1 is along dir + VectorSubtract(p1, origin, p1); + d1 = DotProduct(p1, dir); + + if (testPrimitive && !g_PrefsDlg.m_selectByBoundingBrush) { + if (b->pPatch) { + if (!Patch_Intersect(b->pPatch, origin, dir, scale)) { + *dist = 0; + return NULL; + } + } + else if ( b->modelHandle != NULL && dynamic_cast( b->modelHandle ) == NULL && dynamic_cast< idRenderModelLiquid*> ( b->modelHandle ) == NULL ) { + if (!Brush_ModelIntersect(b, origin, dir, scale)) { + *dist = 0; + return NULL; + } + } + } + + *dist = d1; + return firstface; +} + +/* +================ +Brush_Point +================ +*/ +face_t *Brush_Point(idVec3 origin, brush_t *b) { + face_t *f; + float d1; + + for (f = b->brush_faces; f; f = f->next) { + d1 = DotProduct(origin, f->plane) + f->plane[3]; + if (d1 > 0) { + return NULL; // point is on front side of face + } + } + + return b->brush_faces; +} + +/* +================ +Brush_AddToList +================ +*/ +void Brush_AddToList(brush_t *b, brush_t *list) { + if (b->next || b->prev) { + Error("Brush_AddToList: allready linked"); + } + + if (list == &selected_brushes || list == &active_brushes) { + if (b->pPatch && list == &selected_brushes) { + Patch_Select(b->pPatch); + } + } + + b->list = list; + b->next = list->next; + list->next->prev = b; + list->next = b; + b->prev = list; + +} + +/* +================ +Brush_RemoveFromList +================ +*/ +void Brush_RemoveFromList(brush_t *b) { + if (!b->next || !b->prev) { + Error("Brush_RemoveFromList: not linked"); + } + + if (b->pPatch) { + Patch_Deselect(b->pPatch); + + // Patch_Deselect(b->nPatchID); + } + + b->list = NULL; + b->next->prev = b->prev; + b->prev->next = b->next; + b->next = b->prev = NULL; +} + +/* +================ +SetFaceTexdef + + Doesn't set the curve flags. + NOTE: never trust f->d_texture here, f->texdef and f->d_texture are out of sync when + called by Brush_SetTexture use Texture_ForName() to find the right shader + FIXME: send the right shader ( qtexture_t * ) in the parameters ? + TTimo: surface plugin, added an IPluginTexdef* parameter if not NULL, + get ->Copy() of it into the face ( and remember to hook ) if NULL, ask for a default +================ +*/ +void SetFaceTexdef( brush_t *b, face_t *f, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale ) { + + if (g_qeglobals.m_bBrushPrimitMode) { + f->texdef = *texdef; + ConvertTexMatWithQTexture(brushprimit_texdef, NULL, &f->brushprimit_texdef, Texture_ForName(f->texdef.name)); + } + else if (bFitScale) { + f->texdef = *texdef; + + // fit the scaling of the texture on the actual plane + idVec3 p1, p2, p3; // absolute coordinates + + // compute absolute coordinates + ComputeAbsolute(f, p1, p2, p3); + + // compute the scale + idVec3 vx, vy; + VectorSubtract(p2, p1, vx); + vx.Normalize(); + VectorSubtract(p3, p1, vy); + vy.Normalize(); + + // assign scale + VectorScale(vx, texdef->scale[0], vx); + VectorScale(vy, texdef->scale[1], vy); + VectorAdd(p1, vx, p2); + VectorAdd(p1, vy, p3); + + // compute back shift scale rot + AbsoluteToLocal(f->plane, f, p1, p2, p3); + } + else { + f->texdef = *texdef; + } + +} + +/* +================ +Brush_SetTexture +================ +*/ +void Brush_SetTexture(brush_t *b, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale) { + if (b->pPatch) { + Patch_SetTexture(b->pPatch, texdef); + } + else { + for (face_t * f = b->brush_faces; f; f = f->next) { + SetFaceTexdef(b, f, texdef, brushprimit_texdef, bFitScale); + } + + Brush_Build(b); + } +} + +/* +==================== +Brush_SetTextureName +==================== +*/ +void Brush_SetTextureName(brush_t *b, const char *name) { + if (b->pPatch) { + Patch_SetTextureName(b->pPatch, name); + } + else { + for (face_t * f = b->brush_faces; f; f = f->next) { + f->texdef.SetName(name); + } + Brush_Build(b); + } +} + +/* +================ +ClipLineToFace +================ +*/ +bool ClipLineToFace(idVec3 &p1, idVec3 &p2, face_t *f) { + float d1, d2, fr; + int i; + float *v; + + d1 = DotProduct(p1, f->plane) + f->plane[3]; + d2 = DotProduct(p2, f->plane) + f->plane[3]; + + if (d1 >= 0 && d2 >= 0) { + return false; // totally outside + } + + if (d1 <= 0 && d2 <= 0) { + return true; // totally inside + } + + fr = d1 / (d1 - d2); + + if (d1 > 0) { + v = p1.ToFloatPtr(); + } + else { + v = p2.ToFloatPtr(); + } + + for (i = 0; i < 3; i++) { + v[i] = p1[i] + fr * (p2[i] - p1[i]); + } + + return true; +} + +/* +================ +AddPlanept +================ +*/ +int AddPlanept(idVec3 *f) { + int i; + + for (i = 0; i < g_qeglobals.d_num_move_points; i++) { + if (g_qeglobals.d_move_points[i] == f) { + return 0; + } + } + + if (g_qeglobals.d_num_move_points < MAX_MOVE_POINTS) { + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = f; + } else { + Sys_Status("Trying to move too many points\n"); + return 0; + } + + return 1; +} + +/* +================ +AddMovePlane +================ +*/ +void AddMovePlane( idPlane *p ) { + + for (int i = 0; i < g_qeglobals.d_num_move_planes; i++) { + if (g_qeglobals.d_move_planes[i] == p) { + return; + } + } + + if (g_qeglobals.d_num_move_planes < MAX_MOVE_PLANES) { + g_qeglobals.d_move_planes[g_qeglobals.d_num_move_planes++] = p; + } else { + Sys_Status("Trying to move too many planes\n"); + } + +} + +/* +================ +Brush_SelectFaceForDragging + + Adds the faces planepts to move_points, and rotates and adds the planepts of adjacent face if shear is set +================ +*/ +void Brush_SelectFaceForDragging(brush_t *b, face_t *f, bool shear) { + int i; + face_t *f2; + idWinding *w; + float d; + brush_t *b2; + int c; + + if (b->owner->eclass->fixedsize || EntityHasModel(b->owner)) { + return; + } + + c = 0; + for (i = 0; i < 3; i++) { + c += AddPlanept(&f->planepts[i]); + } + + //AddMovePlane(&f->plane); + + if (c == 0) { + return; // allready completely added + } + + // select all points on this plane in all brushes the selection + for (b2 = selected_brushes.next; b2 != &selected_brushes; b2 = b2->next) { + if (b2 == b) { + continue; + } + + for (f2 = b2->brush_faces; f2; f2 = f2->next) { + for (i = 0; i < 3; i++) { + if (idMath::Fabs(DotProduct(f2->planepts[i], f->plane) + f->plane[3]) > ON_EPSILON) { + break; + } + } + + if (i == 3) { // move this face as well + Brush_SelectFaceForDragging(b2, f2, shear); + break; + } + } + } + + // + // if shearing, take all the planes adjacent to selected faces and rotate their + // points so the edge clipped by a selcted face has two of the points + // + if (!shear) { + return; + } + + for (f2 = b->brush_faces; f2; f2 = f2->next) { + if (f2 == f) { + continue; + } + + w = Brush_MakeFaceWinding(b, f2, false); + if (!w) { + continue; + } + + // any points on f will become new control points + for (i = 0; i < w->GetNumPoints(); i++) { + d = DotProduct( (*w)[i], f->plane ) + f->plane[3]; + if (d > -ON_EPSILON && d < ON_EPSILON) { + break; + } + } + + // if none of the points were on the plane, leave it alone + if (i != w->GetNumPoints()) { + if (i == 0) { // see if the first clockwise point was the + /// + /// last point on the winding + d = DotProduct( (*w)[w->GetNumPoints() - 1], f->plane ) + f->plane[3]; + if (d > -ON_EPSILON && d < ON_EPSILON) { + i = w->GetNumPoints() - 1; + } + } + + AddPlanept(&f2->planepts[0]); + //AddMovePlane(&f2->plane); + + VectorCopy((*w)[i], f2->planepts[0]); + if (++i == w->GetNumPoints()) { + i = 0; + } + + // see if the next point is also on the plane + d = DotProduct( (*w)[i], f->plane ) + f->plane[3]; + if (d > -ON_EPSILON && d < ON_EPSILON) { + AddPlanept(&f2->planepts[1]); + } + + VectorCopy( (*w)[i], f2->planepts[1] ); + if (++i == w->GetNumPoints()) { + i = 0; + } + + // the third point is never on the plane + VectorCopy( (*w)[i], f2->planepts[2] ); + } + + delete w; + } +} + +/* +================ +Brush_SideSelect + + The mouse click did not hit the brush, so grab one or more side planes for dragging. +================ +*/ +void Brush_SideSelect(brush_t *b, idVec3 origin, idVec3 dir, bool shear) { + face_t *f, *f2; + idVec3 p1, p2; + + if (g_moveOnly) { + return; + } + + // if (b->pPatch) return; Patch_SideSelect(b->nPatchID, origin, dir); + for (f = b->brush_faces; f; f = f->next) { + VectorCopy(origin, p1); + VectorMA(origin, MAX_WORLD_SIZE, dir, p2); + + for (f2 = b->brush_faces; f2; f2 = f2->next) { + if (f2 == f) { + continue; + } + + ClipLineToFace(p1, p2, f2); + } + + if (f2) { + continue; + } + + if ( p1.Compare( origin ) ) { + continue; + } + + if (ClipLineToFace(p1, p2, f)) { + continue; + } + + Brush_SelectFaceForDragging(b, f, shear); + } +} + +extern void UpdateSelectablePoint(brush_t *b, idVec3 v, int type); +extern void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority); +extern void ClearSelectablePoints(brush_t *b); + +/* +================ +Brush_TransformedPoint +================ +*/ +extern void VectorSnapGrid(idVec3 &v); + +idMat3 Brush_RotationMatrix(brush_t *b) { + idMat3 mat; + mat.Identity(); + if (!GetMatrixForKey(b->owner, "light_rotation", mat)) { + GetMatrixForKey(b->owner, "rotation", mat); + } + return mat; +} + +idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in) { + idVec3 out = in; + out -= b->owner->origin; + out *= Brush_RotationMatrix(b); + out += b->owner->origin; + return out; +} +/* +================ +Brush_UpdateLightPoints +================ +*/ +void Brush_UpdateLightPoints(brush_t *b, const idVec3 &offset) { + + if (!(b->owner->eclass->nShowFlags & ECLASS_LIGHT)) { + if (b->modelHandle) { + g_bScreenUpdates = false; + g_pParentWnd->GetCamera()->BuildEntityRenderState(b->owner, true); + g_bScreenUpdates = true; + } + return; + } + + if (b->entityModel) { + return; + } + + idVec3 vCenter; + idVec3 *origin = (b->trackLightOrigin) ? &b->owner->lightOrigin : &b->owner->origin; + + if (!GetVectorForKey(b->owner, "_color", b->lightColor)) { + b->lightColor[0] = b->lightColor[1] = b->lightColor[2] = 1; + } + + const char *str = ValueForKey(b->owner, "texture"); + b->lightTexture = -1; + if (str && strlen(str) > 0) { + const idMaterial *q = Texture_LoadLight(str); + if (q) { + b->lightTexture = q->GetEditorImage()->texnum; + } + } + + str = ValueForKey(b->owner, "light_right"); + if (str && *str) { + idVec3 vRight, vUp, vTarget, vTemp; + + if (GetVectorForKey(b->owner, "light_start", b->lightStart)) { + b->startEnd = true; + if (!GetVectorForKey(b->owner, "light_end", b->lightEnd)) { + GetVectorForKey(b->owner, "light_target", b->lightEnd); + } + + + VectorAdd(b->lightEnd, *origin, b->lightEnd); + VectorAdd(b->lightStart, *origin, b->lightStart); + VectorAdd(b->lightStart, offset, b->lightStart); + } + else { + b->startEnd = false; + } + + GetVectorForKey(b->owner, "light_right", vRight); + GetVectorForKey(b->owner, "light_up", vUp); + GetVectorForKey(b->owner, "light_target", vTarget); + if (offset.x || offset.y || offset.z) { + CString str; + VectorAdd(vTarget, offset, vTarget); + SetKeyVec3(b->owner, "light_target", vTarget); + } + + VectorAdd(vTarget, *origin, b->lightTarget); + VectorAdd(b->lightTarget, vRight, b->lightRight); + VectorAdd(b->lightTarget, vUp, b->lightUp); + + UpdateSelectablePoint(b, Brush_TransformedPoint(b, b->lightUp), LIGHT_UP); + UpdateSelectablePoint(b, Brush_TransformedPoint(b, b->lightRight), LIGHT_RIGHT); + UpdateSelectablePoint(b, Brush_TransformedPoint(b, b->lightTarget), LIGHT_TARGET); + UpdateSelectablePoint(b, Brush_TransformedPoint(b, b->lightStart), LIGHT_START); + UpdateSelectablePoint(b, Brush_TransformedPoint(b, b->lightEnd), LIGHT_END); + b->pointLight = false; + } + else { + b->pointLight = true; + + if (GetVectorForKey(b->owner, "light_center", vCenter)) { + + if (offset.x || offset.y || offset.z) { + CString str; + VectorAdd(vCenter, offset, vCenter); + SetKeyVec3(b->owner, "light_center", vCenter); + } + + VectorAdd(vCenter, *origin, b->lightCenter); + UpdateSelectablePoint(b, b->lightCenter, LIGHT_CENTER); + } + + if (!GetVectorForKey(b->owner, "light_radius", b->lightRadius)) { + float f = FloatForKey(b->owner, "light"); + if (f == 0) { + f = 300; + } + + b->lightRadius[0] = b->lightRadius[1] = b->lightRadius[2] = f; + } + else { + } + } + + g_bScreenUpdates = false; + g_pParentWnd->GetCamera()->BuildEntityRenderState(b->owner, true); + g_bScreenUpdates = true; + +} + +/* +================ +Brush_BuildWindings +================ +*/ +void Brush_BuildWindings(brush_t *b, bool bSnap, bool keepOnPlaneWinding, bool updateLights, bool makeFacePlanes) { + idWinding *w; + face_t *face; + float v; + + // clear the mins/maxs bounds + b->mins[0] = b->mins[1] = b->mins[2] = 999999; + b->maxs[0] = b->maxs[1] = b->maxs[2] = -999999; + + if (makeFacePlanes) { + Brush_MakeFacePlanes(b); + } + + face = b->brush_faces; + + float fCurveColor = 1.0f; + + for (; face; face = face->next) { + int i, j; + delete face->face_winding; + w = face->face_winding = Brush_MakeFaceWinding(b, face, keepOnPlaneWinding); + face->d_texture = Texture_ForName(face->texdef.name); + + if (!w) { + continue; + } + + for (i = 0; i < w->GetNumPoints(); i++) { + // add to bounding box + for (j = 0; j < 3; j++) { + v = (*w)[i][j]; + if (v > b->maxs[j]) { + b->maxs[j] = v; + } + + if (v < b->mins[j]) { + b->mins[j] = v; + } + } + } + + // setup s and t vectors, and set color if (!g_PrefsDlg.m_bGLLighting) { + if (makeFacePlanes) { + Face_SetColor(b, face, fCurveColor); + + // } + fCurveColor -= 0.1f; + if ( fCurveColor <= 0.0f ) { + fCurveColor = 1.0f; + } + + // computing ST coordinates for the windings + if (g_qeglobals.m_bBrushPrimitMode) { + if (g_qeglobals.bNeedConvert) { + // + // we have parsed old brushes format and need conversion convert old brush texture + // representation to new format + // + FaceToBrushPrimitFace(face); + #ifdef _DEBUG + // use old texture coordinates code to check against + for (i = 0; i < w->GetNumPoints(); i++) { + EmitTextureCoordinates((*w)[i], face->d_texture, face); + } + #endif + } + + // + // use new texture representation to compute texture coordinates in debug mode we + // will check against old code and warn if there are differences + // + EmitBrushPrimitTextureCoordinates(face, w); + } + else { + for (i = 0; i < w->GetNumPoints(); i++) { + EmitTextureCoordinates((*w)[i], face->d_texture, face); + } + } + } + + } + + if (updateLights) { + idVec3 offset; + offset.Zero(); + Brush_UpdateLightPoints(b, offset); + } +} + +/* +================ +Brush_RemoveEmptyFaces + + Frees any overconstraining faces +================ +*/ +void Brush_RemoveEmptyFaces(brush_t *b) { + face_t *f, *next; + + f = b->brush_faces; + b->brush_faces = NULL; + + for (; f; f = next) { + next = f->next; + if (!f->face_winding) { + Face_Free(f); + } + else { + f->next = b->brush_faces; + b->brush_faces = f; + } + } +} + +/* +================ +Brush_SnapToGrid +================ +*/ +void Brush_SnapToGrid(brush_t *pb) { + int i; + for (face_t * f = pb->brush_faces; f; f = f->next) { + idWinding *w = f->face_winding; + + if (!w) { + continue; // freed face + } + + for (i = 0; i < w->GetNumPoints(); i++) { + SnapVectorToGrid( (*w)[i].ToVec3() ); + } + + for (i = 0; i < 3; i++) { + f->planepts[i].x = (*w)[i].x; + f->planepts[i].y = (*w)[i].y; + f->planepts[i].z = (*w)[i].z; + } + } + idVec3 v; + idStr str; + if (GetVectorForKey(pb->owner, "origin", v)) { + SnapVectorToGrid(pb->owner->origin); + sprintf(str, "%i %i %i", (int)pb->owner->origin.x, (int)pb->owner->origin.y, (int)pb->owner->origin.z); + SetKeyValue(pb->owner, "origin", str); + } + + if (pb->owner->eclass->nShowFlags & ECLASS_LIGHT) { + if (GetVectorForKey(pb->owner, "light_right", v)) { + // projected + SnapVectorToGrid(v); + pb->lightRight = v; + SetKeyVec3(pb->owner, "light_right", v); + GetVectorForKey(pb->owner, "light_up", v); + SnapVectorToGrid(v); + pb->lightUp = v; + SetKeyVec3(pb->owner, "light_up", v); + GetVectorForKey(pb->owner, "light_target", v); + SnapVectorToGrid(v); + pb->lightTarget = v; + SetKeyVec3(pb->owner, "light_target", v); + if (GetVectorForKey(pb->owner, "light_start", v)) { + SnapVectorToGrid(v); + pb->lightStart = v; + SetKeyVec3(pb->owner, "light_start", v); + GetVectorForKey(pb->owner, "light_end", v); + SnapVectorToGrid(v); + pb->lightEnd = v; + SetKeyVec3(pb->owner, "light_end", v); + } + } else { + // point + if (GetVectorForKey(pb->owner, "light_center", v)) { + SnapVectorToGrid(v); + SetKeyVec3(pb->owner, "light_center", v); + } + } + } + + if ( pb->owner->curve ) { + int c = pb->owner->curve->GetNumValues(); + for ( i = 0; i < c; i++ ) { + v = pb->owner->curve->GetValue( i ); + SnapVectorToGrid( v ); + pb->owner->curve->SetValue( i, v ); + } + } + + Brush_Build(pb); +} + +/* +================ +Brush_Rotate +================ +*/ +void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild) { + for (face_t * f = b->brush_faces; f; f = f->next) { + for (int i = 0; i < 3; i++) { + f->planepts[i] -= origin; + f->planepts[i] *= matrix; + f->planepts[i] += origin; + } + } + + if (bBuild) { + Brush_Build(b, false, false); + } +} + +extern void VectorRotate3Origin( const idVec3 &vIn, const idVec3 &vRotation, const idVec3 &vOrigin, idVec3 &out ); + +/* +================ +Brush_Rotate +================ +*/ +void Brush_Rotate(brush_t *b, idVec3 vAngle, idVec3 vOrigin, bool bBuild) { + for (face_t * f = b->brush_faces; f; f = f->next) { + for (int i = 0; i < 3; i++) { + VectorRotate3Origin(f->planepts[i], vAngle, vOrigin, f->planepts[i]); + } + } + + if (bBuild) { + Brush_Build(b, false, false); + } +} + +/* +================ +Brush_Center +================ +*/ +void Brush_Center(brush_t *b, idVec3 vNewCenter) { + idVec3 vMid; + + // get center of the brush + for (int j = 0; j < 3; j++) { + vMid[j] = b->mins[j] + abs((b->maxs[j] - b->mins[j]) * 0.5f); + } + + // calc distance between centers + VectorSubtract(vNewCenter, vMid, vMid); + Brush_Move(b, vMid, true); +} + +/* +================ +Brush_Resize + + the brush must be a true axial box +================ +*/ +void Brush_Resize( brush_t *b, idVec3 vMin, idVec3 vMax ) { + int i, j; + face_t *f; + + assert( vMin[0] < vMax[0] && vMin[1] < vMax[1] && vMin[2] < vMax[2] ); + + Brush_MakeFacePlanes( b ); + + for( f = b->brush_faces; f; f = f->next ) { + for ( i = 0; i < 3; i++ ) { + if ( f->plane.Normal()[i] >= 0.999f ) { + for ( j = 0; j < 3; j++ ) { + f->planepts[j][i] = vMax[i]; + } + break; + } + if ( f->plane.Normal()[i] <= -0.999f ) { + for ( j = 0; j < 3; j++ ) { + f->planepts[j][i] = vMin[i]; + } + break; + } + } + //assert( i < 3 ); + } + + Brush_Build( b, true ); +} + +/* +================ +HasModel +================ +*/ +eclass_t *HasModel(brush_t *b) { + idVec3 vMin, vMax; + vMin[0] = vMin[1] = vMin[2] = 999999; + vMax[0] = vMax[1] = vMax[2] = -999999; + + if (b->owner->md3Class != NULL) { + return b->owner->md3Class; + } + + if (b->owner->eclass->modelHandle > 0) { + return b->owner->eclass; + } + + eclass_t *e = NULL; + + // FIXME: entity needs to track whether a cache hit failed and not ask again + if (b->owner->eclass->nShowFlags & ECLASS_MISCMODEL) { + const char *pModel = ValueForKey(b->owner, "model"); + if (pModel != NULL && strlen(pModel) > 0) { + e = GetCachedModel(b->owner, pModel, vMin, vMax); + if (e != NULL) { + // + // we need to scale the brush to the proper size based on the model load recreate + // brush just like in load/save + // + VectorAdd(vMin, b->owner->origin, vMin); + VectorAdd(vMax, b->owner->origin, vMax); + Brush_Resize(b, vMin, vMax); + b->bModelFailed = false; + } + else { + b->bModelFailed = true; + } + } + } + + return e; +} + +/* +================ +Entity_GetRotationMatrixAngles +================ +*/ +bool Entity_GetRotationMatrixAngles( entity_t *e, idMat3 &mat, idAngles &angles ) { + int angle; + + /* the angle keyword is a yaw value, except for two special markers */ + if ( GetMatrixForKey( e, "rotation", mat ) ) { + angles = mat.ToAngles(); + return true; + } + else if ( e->epairs.GetInt( "angle", "0", angle ) ) { + if ( angle == -1 ) { // up + angles.Set( 270, 0, 0 ); + } + else if ( angle == -2 ) { // down + angles.Set( 90, 0, 0 ); + } + else { + angles.Set( 0, angle, 0 ); + } + mat = angles.ToMat3(); + return true; + } + else { + mat.Identity(); + angles.Zero(); + return false; + } +} + +/* +================ +FacingVectors +================ +*/ +static void FacingVectors(entity_t *e, idVec3 &forward, idVec3 &right, idVec3 &up) { + idAngles angles; + idMat3 mat; + + Entity_GetRotationMatrixAngles(e, mat, angles); + angles.ToVectors( &forward, &right, &up); +} + +/* +================ +Brush_DrawFacingAngle +================ +*/ +void Brush_DrawFacingAngle( brush_t *b, entity_t *e, bool particle ) { + idVec3 forward, right, up; + idVec3 endpoint, tip1, tip2; + idVec3 start; + float dist; + + VectorAdd(e->brushes.onext->mins, e->brushes.onext->maxs, start); + VectorScale(start, 0.5f, start); + dist = (b->maxs[0] - start[0]) * 2.5f; + + FacingVectors(e, forward, right, up); + VectorMA(start, dist, ( particle ) ? up : forward, endpoint); + + dist = (b->maxs[0] - start[0]) * 0.5f; + VectorMA(endpoint, -dist, ( particle ) ? up : forward, tip1); + VectorMA(tip1, -dist, ( particle ) ? forward : up, tip1); + VectorMA(tip1, 2 * dist, ( particle ) ? forward : up, tip2); + globalImages->BindNull(); + qglColor4f(1, 1, 1, 1); + qglLineWidth(2); + qglBegin(GL_LINES); + qglVertex3fv(start.ToFloatPtr()); + qglVertex3fv(endpoint.ToFloatPtr()); + qglVertex3fv(endpoint.ToFloatPtr()); + qglVertex3fv(tip1.ToFloatPtr()); + qglVertex3fv(endpoint.ToFloatPtr()); + qglVertex3fv(tip2.ToFloatPtr()); + qglEnd(); + qglLineWidth(0.5f); +} + +/* +================ +DrawProjectedLight +================ +*/ +void DrawProjectedLight(brush_t *b, bool bSelected, bool texture) { + int i; + idVec3 v1, v2, cross, vieworg, edge[8][2], v[4]; + idVec3 target, start; + + if (!bSelected && !g_bShowLightVolumes) { + return; + } + + // use the renderer to get the volume outline + idPlane lightProject[4]; + idPlane planes[6]; + srfTriangles_t *tri; + + // use the game's epair parsing code so + // we can use the same renderLight generation + entity_t *ent = b->owner; + idDict spawnArgs; + renderLight_t parms; + + spawnArgs = ent->epairs; + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms ); + R_RenderLightFrustum( parms, planes ); + + tri = R_PolytopeSurface(6, planes, NULL); + + qglColor3f(1, 0, 1); + for (i = 0; i < tri->numIndexes; i += 3) { + qglBegin(GL_LINE_LOOP); + glVertex3fv(tri->verts[tri->indexes[i]].xyz.ToFloatPtr()); + glVertex3fv(tri->verts[tri->indexes[i + 1]].xyz.ToFloatPtr()); + glVertex3fv(tri->verts[tri->indexes[i + 2]].xyz.ToFloatPtr()); + qglEnd(); + } + + R_FreeStaticTriSurf(tri); + + // draw different selection points for point lights or projected + // lights (FIXME: rotate these based on parms!) + if ( !bSelected ) { + return; + } + + idMat3 mat; + bool transform = GetMatrixForKey(b->owner, "light_rotation", mat); + if (!transform) { + transform = GetMatrixForKey(b->owner, "rotation", mat); + } + idVec3 tv; + idVec3 *origin = (b->trackLightOrigin) ? &b->owner->lightOrigin : &b->owner->origin; + if (b->pointLight) { + if ( b->lightCenter[0] || b->lightCenter[1] || b->lightCenter[2] ) { + qglPointSize(8); + qglColor3f( 1.0f, 0.4f, 0.8f ); + qglBegin(GL_POINTS); + tv = b->lightCenter; + if (transform) { + tv -= *origin; + tv *= mat; + tv += *origin; + } + qglVertex3fv(tv.ToFloatPtr()); + qglEnd(); + qglPointSize(1); + } + return; + } + + // projected light + qglPointSize(8); + qglColor3f( 1.0f, 0.4f, 0.8f ); + qglBegin(GL_POINTS); + tv = b->lightRight; + if (transform) { + tv -= *origin; + tv *= mat; + tv += *origin; + } + qglVertex3fv(tv.ToFloatPtr()); + tv = b->lightTarget; + if (transform) { + tv -= *origin; + tv *= mat; + tv += *origin; + } + qglVertex3fv(tv.ToFloatPtr()); + tv = b->lightUp; + if (transform) { + tv -= *origin; + tv *= mat; + tv += *origin; + } + qglVertex3fv(tv.ToFloatPtr()); + qglEnd(); + + if (b->startEnd) { + qglColor3f( 0.4f, 1.0f, 0.8f ); + qglBegin(GL_POINTS); + qglVertex3fv(b->lightStart.ToFloatPtr()); + qglVertex3fv(b->lightEnd.ToFloatPtr()); + qglEnd(); + } + + qglPointSize(1); +} + +/* +================ +GLCircle +================ +*/ +void GLCircle(float x, float y, float z, float r) +{ + float ix = 0; + float iy = r; + float ig = 3 - 2 * r; + float idgr = -6; + float idgd = 4 * r - 10; + qglPointSize(0.5f); + qglBegin(GL_POINTS); + while (ix <= iy) { + if (ig < 0) { + ig += idgd; + idgd -= 8; + iy--; + } else { + ig += idgr; + idgd -= 4; + } + idgr -= 4; + ix++; + qglVertex3f(x + ix, y + iy, z); + qglVertex3f(x - ix, y + iy, z); + qglVertex3f(x + ix, y - iy, z); + qglVertex3f(x - ix, y - iy, z); + qglVertex3f(x + iy, y + ix, z); + qglVertex3f(x - iy, y + ix, z); + qglVertex3f(x + iy, y - ix, z); + qglVertex3f(x - iy, y - ix, z); + } + qglEnd(); +} + +/* +================ +DrawSpeaker +================ +*/ +void DrawSpeaker(brush_t *b, bool bSelected, bool twoD) { + + if (!(g_qeglobals.d_savedinfo.showSoundAlways || (g_qeglobals.d_savedinfo.showSoundWhenSelected && bSelected))) { + return; + } + + // convert to units ( inches ) + float min = FloatForKey(b->owner, "s_mindistance"); + float max = FloatForKey(b->owner, "s_maxdistance"); + + const char *s = b->owner->epairs.GetString("s_shader"); + if (s && *s) { + const idSoundShader *shader = declManager->FindSound( s, false ); + if ( shader ) { + if ( !min ) { + min = shader->GetMinDistance(); + } + if ( !max ) { + max = shader->GetMaxDistance(); + } + } + } + + if (min == 0 && max == 0) { + return; + } + + + // convert from meters to doom units + min *= METERS_TO_DOOM; + max *= METERS_TO_DOOM; + + if (twoD) { + if (bSelected) { + qglColor4f(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z, .5); + } else { + qglColor4f(b->owner->eclass->color.x, b->owner->eclass->color.y, b->owner->eclass->color.z, .5); + } + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + GLCircle(b->owner->origin.x, b->owner->origin.y, b->owner->origin.z, min); + if (bSelected) { + qglColor4f(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z, 1); + } else { + qglColor4f(b->owner->eclass->color.x, b->owner->eclass->color.y, b->owner->eclass->color.z, 1); + } + GLCircle(b->owner->origin.x, b->owner->origin.y, b->owner->origin.z, max); + } else { + qglPushMatrix(); + qglTranslatef(b->owner->origin.x, b->owner->origin.y, b->owner->origin.z ); + qglColor3f( 0.4f, 0.4f, 0.4f ); + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + GLUquadricObj* qobj = gluNewQuadric(); + gluSphere(qobj, min, 8, 8); + qglColor3f( 0.8f, 0.8f, 0.8f ); + gluSphere(qobj, max, 8, 8); + qglEnable(GL_BLEND); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + globalImages->BindNull(); + if (bSelected) { + qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z, 0.35f ); + } else { + qglColor4f( b->owner->eclass->color.x, b->owner->eclass->color.y, b->owner->eclass->color.z, 0.35f ); + } + gluSphere(qobj, min, 8, 8); + if (bSelected) { + qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z, 0.1f ); + } else { + qglColor4f( b->owner->eclass->color.x, b->owner->eclass->color.y, b->owner->eclass->color.z, 0.1f ); + } + gluSphere(qobj, max, 8, 8); + gluDeleteQuadric(qobj); + qglPopMatrix(); + } + + +} + +/* +================ +DrawLight +================ +*/ +void DrawLight(brush_t *b, bool bSelected) { + idVec3 vTriColor; + bool bTriPaint = false; + + vTriColor[0] = vTriColor[2] = 1.0f; + vTriColor[1] = 1.0f; + bTriPaint = true; + + CString strColor = ValueForKey(b->owner, "_color"); + if (strColor.GetLength() > 0) { + float fR, fG, fB; + int n = sscanf(strColor, "%f %f %f", &fR, &fG, &fB); + if (n == 3) { + vTriColor[0] = fR; + vTriColor[1] = fG; + vTriColor[2] = fB; + } + } + + qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]); + + idVec3 vCorners[4]; + float fMid = b->mins[2] + (b->maxs[2] - b->mins[2]) / 2; + + vCorners[0][0] = b->mins[0]; + vCorners[0][1] = b->mins[1]; + vCorners[0][2] = fMid; + + vCorners[1][0] = b->mins[0]; + vCorners[1][1] = b->maxs[1]; + vCorners[1][2] = fMid; + + vCorners[2][0] = b->maxs[0]; + vCorners[2][1] = b->maxs[1]; + vCorners[2][2] = fMid; + + vCorners[3][0] = b->maxs[0]; + vCorners[3][1] = b->mins[1]; + vCorners[3][2] = fMid; + + idVec3 vTop, vBottom; + + vTop[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) / 2); + vTop[1] = b->mins[1] + ((b->maxs[1] - b->mins[1]) / 2); + vTop[2] = b->maxs[2]; + + VectorCopy(vTop, vBottom); + vBottom[2] = b->mins[2]; + + idVec3 vSave; + VectorCopy(vTriColor, vSave); + + globalImages->BindNull(); + qglBegin(GL_TRIANGLE_FAN); + qglVertex3fv(vTop.ToFloatPtr()); + int i; + for (i = 0; i <= 3; i++) { + vTriColor[0] *= 0.95f; + vTriColor[1] *= 0.95f; + vTriColor[2] *= 0.95f; + qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]); + qglVertex3fv(vCorners[i].ToFloatPtr()); + } + + qglVertex3fv(vCorners[0].ToFloatPtr()); + qglEnd(); + + VectorCopy(vSave, vTriColor); + vTriColor[0] *= 0.95f; + vTriColor[1] *= 0.95f; + vTriColor[2] *= 0.95f; + + qglBegin(GL_TRIANGLE_FAN); + qglVertex3fv(vBottom.ToFloatPtr()); + qglVertex3fv(vCorners[0].ToFloatPtr()); + for (i = 3; i >= 0; i--) { + vTriColor[0] *= 0.95f; + vTriColor[1] *= 0.95f; + vTriColor[2] *= 0.95f; + qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]); + qglVertex3fv(vCorners[i].ToFloatPtr()); + } + + qglEnd(); + + DrawProjectedLight(b, bSelected, true); +} + +/* +================ +Control_Draw +================ +*/ +void Control_Draw(brush_t *b) { + face_t *face; + int i, order; + qtexture_t *prev = 0; + idWinding *w; + + // guarantee the texture will be set first + prev = NULL; + for ( face = b->brush_faces, order = 0; face; face = face->next, order++ ) { + w = face->face_winding; + if (!w) { + continue; // freed face + } + + qglColor4f(1, 1, .5, 1); + qglBegin(GL_POLYGON); + for (i = 0; i < w->GetNumPoints(); i++) { + qglVertex3fv( (*w)[i].ToFloatPtr() ); + } + + qglEnd(); + } +} + +/* +================ +Brush_DrawModel +================ +*/ +void Brush_DrawModel( brush_t *b, bool camera, bool bSelected ) { + idMat3 axis; + idAngles angles; + int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode; + + if ( camera && g_PrefsDlg.m_nEntityShowState != ENTITY_WIREFRAME && nDrawMode != cd_wire ) { + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else { + qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + + idRenderModel *model = b->modelHandle; + if ( model == NULL ) { + model = b->owner->eclass->entityModel; + } + if ( model ) { + idRenderModel *model2; + + model2 = NULL; + bool fixedBounds = false; + + if ( model->IsDynamicModel() != DM_STATIC ) { + if ( dynamic_cast( model ) ) { + const char *classname = ValueForKey( b->owner, "classname" ); + if (stricmp(classname, "func_static") == 0) { + classname = ValueForKey(b->owner, "animclass"); + } + const char *anim = ValueForKey( b->owner, "anim" ); + int frame = IntForKey( b->owner, "frame" ) + 1; + if ( frame < 1 ) { + frame = 1; + } + if ( !anim || !anim[ 0 ] ) { + anim = "idle"; + } + model2 = gameEdit->ANIM_CreateMeshForAnim( model, classname, anim, frame, false ); + } else if ( dynamic_cast( model ) || dynamic_cast( model ) ) { + fixedBounds = true; + } + + if ( !model2 ) { + idBounds bounds; + if (fixedBounds) { + bounds.Zero(); + bounds.ExpandSelf(12.0f); + } else { + bounds = model->Bounds( NULL ); + } + idVec4 color; + color.w = 1.0f; + if (bSelected) { + color.x = g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x; + color.y = g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y; + color.z = g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z; + } else { + color.x = b->owner->eclass->color.x; + color.y = b->owner->eclass->color.y; + color.z = b->owner->eclass->color.z; + } + idVec3 center = bounds.GetCenter(); + glBox(color, b->owner->origin + center, bounds.GetRadius( center ) ); + model = renderModelManager->DefaultModel(); + } else { + model = model2; + } + } + + Entity_GetRotationMatrixAngles( b->owner, axis, angles ); + + idVec4 colorSave; + qglGetFloatv(GL_CURRENT_COLOR, colorSave.ToFloatPtr()); + + if ( bSelected ) { + qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr() ); + } + + DrawRenderModel( model, b->owner->origin, axis, camera ); + + qglColor4fv( colorSave.ToFloatPtr() ); + + if ( bSelected && camera ) + { + //draw selection tints + /* + if ( camera && g_PrefsDlg.m_nEntityShowState != ENTITY_WIREFRAME ) { + qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ); + qglColor3fv ( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr () ); + qglEnable ( GL_BLEND ); + qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + DrawRenderModel( model, b->owner->origin, axis, camera ); + } + */ + + //draw white triangle outlines + globalImages->BindNull(); + + qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + qglDisable( GL_BLEND ); + qglDisable( GL_DEPTH_TEST ); + qglColor3f( 1.0f, 1.0f, 1.0f ); + qglPolygonOffset( 1.0f, 3.0f ); + DrawRenderModel( model, b->owner->origin, axis, false ); + qglEnable( GL_DEPTH_TEST ); + } + + if ( model2 ) { + delete model2; + model2 = NULL; + } + } + + if ( bSelected && camera ) { + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else if ( camera ) { + globalImages->BindNull(); + } + + if ( g_bPatchShowBounds ) { + for ( face_t *face = b->brush_faces; face; face = face->next ) { + // only draw polygons facing in a direction we care about + idWinding *w = face->face_winding; + if (!w) { + continue; + } + + // + // if (b->alphaBrush && !(face->texdef.flags & SURF_ALPHA)) continue; + // draw the polygon + // + qglBegin(GL_LINE_LOOP); + for (int i = 0; i < w->GetNumPoints(); i++) { + qglVertex3fv( (*w)[i].ToFloatPtr() ); + } + qglEnd(); + } + } +} + +/* +================ +GLTransformedVertex +================ +*/ +void GLTransformedVertex(float x, float y, float z, idMat3 mat, idVec3 origin, idVec3 color, float maxDist) { + idVec3 v(x,y,z); + v -= origin; + v *= mat; + v += origin; + + idVec3 n = v - g_pParentWnd->GetCamera()->Camera().origin; + float max = n.Length() / maxDist; + if (color.x) { + color.x = max; + } else if (color.y) { + color.y = max; + } else { + color.z = max; + } + qglColor3f(color.x, color.y, color.z); + qglVertex3f(v.x, v.y, v.z); + +} + +/* +================ +GLTransformedCircle +================ +*/ +void GLTransformedCircle(int type, idVec3 origin, float r, idMat3 mat, float pointSize, idVec3 color, float maxDist) { + qglPointSize(pointSize); + qglBegin(GL_POINTS); + for (int i = 0; i < 360; i++) { + float cx = origin.x; + float cy = origin.y; + float cz = origin.z; + switch (type) { + case 0: + cx += r * cos((float)i); + cy += r * sin((float)i); + break; + case 1: + cx += r * cos((float)i); + cz += r * sin((float)i); + break; + case 2: + cy += r * sin((float)i); + cz += r * cos((float)i); + break; + default: + break; + } + GLTransformedVertex(cx, cy, cz, mat, origin, color, maxDist); + } + qglEnd(); +} + +/* +================ +Brush_DrawAxis +================ +*/ +void Brush_DrawAxis(brush_t *b) { + if ( g_pParentWnd->ActiveXY()->RotateMode() && b->modelHandle ) { + bool matrix = false; + idMat3 mat; + float a, s, c; + if (GetMatrixForKey(b->owner, "rotation", mat)) { + matrix = true; + } else { + a = FloatForKey(b->owner, "angle"); + if (a) { + s = sin( DEG2RAD( a ) ); + c = cos( DEG2RAD( a ) ); + } + else { + s = c = 0; + } + } + + idBounds bo; + bo.FromTransformedBounds(b->modelHandle->Bounds(), b->owner->origin, b->owner->rotation); + + float dist = (g_pParentWnd->GetCamera()->Camera().origin - bo[0]).Length(); + float dist2 = (g_pParentWnd->GetCamera()->Camera().origin - bo[1]).Length(); + if (dist2 > dist) { + dist = dist2; + } + + float xr, yr, zr; + xr = (b->modelHandle->Bounds()[1].x > b->modelHandle->Bounds()[0].x) ? b->modelHandle->Bounds()[1].x - b->modelHandle->Bounds()[0].x : b->modelHandle->Bounds()[0].x - b->modelHandle->Bounds()[1].x; + yr = (b->modelHandle->Bounds()[1].y > b->modelHandle->Bounds()[0].y) ? b->modelHandle->Bounds()[1].y - b->modelHandle->Bounds()[0].y : b->modelHandle->Bounds()[0].y - b->modelHandle->Bounds()[1].y; + zr = (b->modelHandle->Bounds()[1].z > b->modelHandle->Bounds()[0].z) ? b->modelHandle->Bounds()[1].z - b->modelHandle->Bounds()[0].z : b->modelHandle->Bounds()[0].z - b->modelHandle->Bounds()[1].z; + + globalImages->BindNull(); + + GLTransformedCircle(0, b->owner->origin, xr, mat, 1.25, idVec3(0, 0, 1), dist); + GLTransformedCircle(1, b->owner->origin, yr, mat, 1.25, idVec3(0, 1, 0), dist); + GLTransformedCircle(2, b->owner->origin, zr, mat, 1.25, idVec3(1, 0, 0), dist); + + float wr = xr; + int type = 0; + idVec3 org = b->owner->origin; + if (g_qeglobals.rotateAxis == 0) { + wr = zr; + type = 2; + } else if (g_qeglobals.rotateAxis == 1) { + wr = yr; + type = 1; + } + + if (g_qeglobals.flatRotation) { + if (yr > wr) { + wr = yr; + } + if (zr > wr) { + wr = zr; + } + idVec3 vec = vec3_origin; + vec[g_qeglobals.rotateAxis] = 1.0f; + if (g_qeglobals.flatRotation == 1) { + org = g_pParentWnd->ActiveXY()->RotateOrigin(); + float t = (org - bo.GetCenter()).Length(); + if (t > wr) { + wr = t; + } + } else { + org = bo.GetCenter(); + } + idRotation rot(org, vec, 0); + mat = rot.ToMat3(); + } + GLTransformedCircle(type, org, wr * 1.03f, mat, 1.45f, idVec3(1, 1, 1), dist); + } +} + +/* +================ +Brush_DrawModelInfo +================ +*/ +void Brush_DrawModelInfo(brush_t *b, bool selected) { + if (b->modelHandle > 0) { + GLfloat color[4]; + qglGetFloatv(GL_CURRENT_COLOR, &color[0]); + if (selected) { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); + } + else { + qglColor3fv(b->owner->eclass->color.ToFloatPtr()); + } + + Brush_DrawModel(b, true, selected); + qglColor4fv(color); + + if ( selected ) { + Brush_DrawAxis(b); + } + return; + } +} + +/* +================ +Brush_DrawEmitter +================ +*/ +void Brush_DrawEmitter(brush_t *b, bool bSelected, bool cam) { + if ( !( b->owner->eclass->nShowFlags & ECLASS_PARTICLE ) ) { + return; + } + + if (bSelected) { + qglColor4f(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].x, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].y, g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].z, .5); + } else { + qglColor4f(b->owner->eclass->color.x, b->owner->eclass->color.y, b->owner->eclass->color.z, .5); + } + + if ( cam ) { + Brush_DrawFacingAngle( b, b->owner, true ); + } +} + +/* +================ +Brush_DrawEnv +================ +*/ +void Brush_DrawEnv( brush_t *b, bool cameraView, bool bSelected ) { + idVec3 origin, newOrigin; + idMat3 axis, newAxis; + idAngles newAngles; + bool poseIsSet; + + idRenderModel *model = gameEdit->AF_CreateMesh( b->owner->epairs, origin, axis, poseIsSet ); + + if ( !poseIsSet ) { + if ( Entity_GetRotationMatrixAngles( b->owner, newAxis, newAngles ) ) { + axis = newAxis; + } + if ( b->owner->epairs.GetVector( "origin", "0 0 0", newOrigin ) ) { + origin = newOrigin; + } + } + + if ( model ) { + if ( cameraView && g_PrefsDlg.m_nEntityShowState != ENTITY_WIREFRAME ) { + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else { + qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + + idVec4 colorSave; + qglGetFloatv(GL_CURRENT_COLOR, colorSave.ToFloatPtr()); + + if ( bSelected ) { + qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr() ); + } else { + qglColor3f( 1.f, 1.f, 1.f ); + } + DrawRenderModel( model, origin, axis, true ); + globalImages->BindNull(); + delete model; + model = NULL; + + qglColor4fv( colorSave.ToFloatPtr() ); + } +} + +/* +================ +Brush_DrawCombatNode +================ +*/ +void Brush_DrawCombatNode( brush_t *b, bool cameraView, bool bSelected ) { + float min_dist = b->owner->epairs.GetFloat( "min" ); + float max_dist = b->owner->epairs.GetFloat( "max" ); + float fov = b->owner->epairs.GetFloat( "fov", "60" ); + float yaw = b->owner->epairs.GetFloat("angle"); + idVec3 offset = b->owner->epairs.GetVector("offset"); + + idAngles leftang( 0.0f, yaw + fov * 0.5f - 90.0f, 0.0f ); + idVec3 cone_left = leftang.ToForward(); + idAngles rightang( 0.0f, yaw - fov * 0.5f + 90.0f, 0.0f ); + idVec3 cone_right = rightang.ToForward(); + bool disabled = b->owner->epairs.GetBool( "start_off" ); + + idVec4 color; + if ( bSelected ) { + color = colorRed; + } else { + color = colorBlue; + } + + idVec3 leftDir( -cone_left.y, cone_left.x, 0.0f ); + idVec3 rightDir( cone_right.y, -cone_right.x, 0.0f ); + leftDir.NormalizeFast(); + rightDir.NormalizeFast(); + + idMat3 axis = idAngles(0, yaw, 0).ToMat3(); + idVec3 org = b->owner->origin + offset; + idVec3 entorg = b->owner->origin; + float cone_dot = cone_right * axis[ 1 ]; + if ( idMath::Fabs( cone_dot ) > 0.1 ) { + idVec3 pt, pt1, pt2, pt3, pt4; + float cone_dist = max_dist / cone_dot; + pt1 = org + leftDir * min_dist; + pt2 = org + leftDir * cone_dist; + pt3 = org + rightDir * cone_dist; + pt4 = org + rightDir * min_dist; + qglColor4fv(color.ToFloatPtr()); + qglBegin(GL_LINE_STRIP); + qglVertex3fv( pt1.ToFloatPtr()); + qglVertex3fv( pt2.ToFloatPtr()); + qglVertex3fv( pt3.ToFloatPtr()); + qglVertex3fv( pt4.ToFloatPtr()); + qglVertex3fv( pt1.ToFloatPtr()); + qglEnd(); + + qglColor4fv(colorGreen.ToFloatPtr()); + qglBegin(GL_LINE_STRIP); + qglVertex3fv( entorg.ToFloatPtr()); + pt = (pt1 + pt4) * 0.5f; + qglVertex3fv( pt.ToFloatPtr()); + pt = (pt2 + pt3) * 0.5f; + qglVertex3fv( pt.ToFloatPtr()); + idVec3 tip = pt; + idVec3 dir = ((pt1 + pt2) * 0.5f) - tip; + dir.Normalize(); + pt = tip + dir * 15.0f; + qglVertex3fv( pt.ToFloatPtr()); + qglVertex3fv( tip.ToFloatPtr()); + dir = ((pt4 + pt3) * 0.5f) - tip; + dir.Normalize(); + pt = tip + dir * 15.0f; + qglVertex3fv( pt.ToFloatPtr()); + qglEnd(); + } + +} + +/* +================ +Brush_Draw +================ +*/ +void Brush_Draw(brush_t *b, bool bSelected) { + face_t *face; + int i, order; + const idMaterial *prev = NULL; + idWinding *w; + bool model = false; + + // + // (TTimo) NOTE: added by build 173, I check after pPlugEnt so it doesn't + // interfere ? + // + if ( b->hiddenBrush ) { + return; + } + + Brush_DrawCurve( b, bSelected, true ); + + if (b->pPatch) { + Patch_DrawCam(b->pPatch, bSelected); + return; + } + + int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode; + + if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES) && (b->owner->eclass->nShowFlags & ECLASS_ANGLE)) { + Brush_DrawFacingAngle(b, b->owner, false); + } + + if ( b->owner->eclass->fixedsize ) { + + DrawSpeaker( b, bSelected, false ); + + if ( g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT) && !(b->modelHandle || b->entityModel) ) { + DrawLight( b, bSelected ); + return; + } + + if ( b->owner->eclass->nShowFlags & ECLASS_ENV ) { + Brush_DrawEnv( b, true, bSelected ); + } + + if ( b->owner->eclass->nShowFlags & ECLASS_COMBATNODE ) { + Brush_DrawCombatNode( b, true, bSelected ); + } + + } + + + if (!(b->owner && (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN))) { + qglColor4f( 1.0f, 0.0f, 0.0f, 0.8f ); + qglPointSize(4); + qglBegin(GL_POINTS); + qglVertex3fv(b->owner->origin.ToFloatPtr()); + qglEnd(); + } + + if ( b->owner->eclass->entityModel ) { + qglColor3fv( b->owner->eclass->color.ToFloatPtr() ); + Brush_DrawModel( b, true, bSelected ); + return; + } + + Brush_DrawEmitter( b, bSelected, true ); + + if ( b->modelHandle > 0 && !model ) { + Brush_DrawModelInfo( b, bSelected ); + return; + } + + // guarantee the texture will be set first + prev = NULL; + for (face = b->brush_faces, order = 0; face; face = face->next, order++) { + w = face->face_winding; + if (!w) { + continue; // freed face + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { + if (strstr(face->texdef.name, "caulk")) { + continue; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_VISPORTALS) { + if (strstr(face->texdef.name, "visportal")) { + continue; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_NODRAW) { + if (strstr(face->texdef.name, "nodraw")) { + continue; + } + } + + if ( (nDrawMode == cd_texture || nDrawMode == cd_light) && face->d_texture != prev && !b->forceWireFrame ) { + // set the texture for this face + prev = face->d_texture; + face->d_texture->GetEditorImage()->Bind(); + } + + if (model) { + qglEnable(GL_BLEND); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglColor4f( face->d_color.x, face->d_color.y, face->d_color.z, 0.1f ); + } else { + qglColor4f( face->d_color.x, face->d_color.y, face->d_color.z, face->d_texture->GetEditorAlpha() ); + } + + qglBegin(GL_POLYGON); + + for (i = 0; i < w->GetNumPoints(); i++) { + if ( !b->forceWireFrame && ( nDrawMode == cd_texture || nDrawMode == cd_light ) ) { + qglTexCoord2fv( &(*w)[i][3] ); + } + + qglVertex3fv( (*w)[i].ToFloatPtr() ); + } + + qglEnd(); + + if (model) { + qglDisable(GL_BLEND); + } + } + + globalImages->BindNull(); +} + +/* +================ +Face_Draw +================ +*/ +void Face_Draw(face_t *f) { + int i; + + if (f->face_winding == NULL) { + return; + } + + qglBegin(GL_POLYGON); + for (i = 0; i < f->face_winding->GetNumPoints(); i++) { + qglVertex3fv( (*f->face_winding)[i].ToFloatPtr() ); + } + + qglEnd(); +} + + +idSurface_SweptSpline *SplineToSweptSpline( idCurve *curve ) { + // expects a vec3 curve and creates a vec4 based swept spline + // must be either nurbs or catmull + idCurve_Spline *newCurve = NULL; + if ( dynamic_cast*>( curve ) ) { + newCurve = new idCurve_NURBS; + } else if ( dynamic_cast*>( curve ) ) { + newCurve = new idCurve_CatmullRomSpline; + } + + if ( curve == NULL || newCurve == NULL ) { + return NULL; + } + + int c = curve->GetNumValues(); + float len = 0.0f; + for ( int i = 0; i < c; i++ ) { + idVec3 v = curve->GetValue( i ); + newCurve->AddValue( curve->GetTime( i ), idVec4( v.x, v.y, v.z, len ) ); + if ( i < c - 1 ) { + len += curve->GetLengthBetweenKnots( i, i + 1 ) * 0.1f; + } + } + + idSurface_SweptSpline *ss = new idSurface_SweptSpline; + ss->SetSpline( newCurve ); + ss->SetSweptCircle( 10.0f ); + ss->Tessellate( newCurve->GetNumValues() * 6, 6 ); + + return ss; +} + +/* +================ +Brush_DrawCurve +================ +*/ +void Brush_DrawCurve( brush_t *b, bool bSelected, bool cam ) { + if ( b == NULL || b->owner->curve == NULL ) { + return; + } + + int maxage = b->owner->curve->GetNumValues(); + int i, time = 0; + qglColor3f( 0.0f, 0.0f, 1.0f ); + for ( i = 0; i < maxage; i++) { + + if ( bSelected && g_qeglobals.d_select_mode == sel_editpoint ) { + idVec3 v = b->owner->curve->GetValue( i ); + if ( cam ) { + glBox( colorBlue, v, 6.0f ); + if ( PointInMoveList( b->owner->curve->GetValueAddress( i ) ) >= 0 ) { + glBox(colorBlue, v, 8.0f ); + } + } else { + qglPointSize( 4.0f ); + qglBegin( GL_POINTS ); + qglVertex3f( v.x, v.y, v.z ); + qglEnd(); + + if ( PointInMoveList( b->owner->curve->GetValueAddress( i ) ) >= 0 ) { + glBox(colorBlue, v, 4.0f ); + } + } + } +/* + if ( cam ) { + idSurface_SweptSpline *ss = SplineToSweptSpline( b->owner->curve ); + if ( ss ) { + idMaterial *mat = declManager->FindMaterial( "_default" ); + mat->GetEditorImage()->Bind(); + qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + qglBegin( GL_TRIANGLES ); + const int *indexes = ss->GetIndexes(); + const idDrawVert *verts = ss->GetVertices(); + for ( j = 0; j < ss->GetNumIndexes(); j += 3 ) { + for ( k = 0; k < 3; k++ ) { + int index = indexes[ j + 2 - k ]; + float f = ShadeForNormal( verts[index].normal ); + qglColor3f( f, f, f ); + qglTexCoord2fv( verts[index].st.ToFloatPtr() ); + qglVertex3fv( verts[index].xyz.ToFloatPtr() ); + } + } + qglEnd(); + delete ss; + } + } else { +*/ +/* qglPointSize( 1.0f ); + qglBegin( GL_POINTS ); + if ( i + 1 < maxage ) { + int start = b->owner->curve->GetTime( i ); + int end = b->owner->curve->GetTime( i + 1 ); + int inc = (end - start) / POINTS_PER_KNOT; + for ( int j = 0; j < POINTS_PER_KNOT; j++ ) { + idVec3 v = b->owner->curve->GetCurrentValue( start ); + qglVertex3f( v.x, v.y, v.z ); + start += inc; + } + }*/ + // DHM - _D3XP : Makes it easier to see curve + qglBegin( GL_LINE_STRIP ); + if ( i + 1 < maxage ) { + int start = b->owner->curve->GetTime( i ); + int end = b->owner->curve->GetTime( i + 1 ); + int inc = (end - start) / POINTS_PER_KNOT; + for ( int j = 0; j <= POINTS_PER_KNOT; j++ ) { + idVec3 v = b->owner->curve->GetCurrentValue( start ); + qglVertex3f( v.x, v.y, v.z ); + start += inc; + } + } + qglEnd(); +/* + } +*/ + + } + qglPointSize(1); +} + +/* +================ +Brush_DrawXY +================ +*/ +void Brush_DrawXY(brush_t *b, int nViewType, bool bSelected, bool ignoreViewType) { + face_t *face; + int order; + idWinding *w; + int i; + + if ( b->hiddenBrush ) { + return; + } + + idVec4 colorSave; + qglGetFloatv(GL_CURRENT_COLOR, colorSave.ToFloatPtr()); + + if (!(b->owner && (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN))) { + qglColor4f( 1.0f, 0.0f, 0.0f, 0.8f ); + qglPointSize(4); + qglBegin(GL_POINTS); + qglVertex3fv(b->owner->origin.ToFloatPtr()); + qglEnd(); + } + + Brush_DrawCurve( b, bSelected, false ); + + qglColor4fv(colorSave.ToFloatPtr()); + + + if (b->pPatch) { + Patch_DrawXY(b->pPatch); + if (!g_bPatchShowBounds) { + return; + } + } + + if (b->owner->eclass->fixedsize) { + + DrawSpeaker(b, bSelected, true); + if (g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT) && !(b->modelHandle || b->entityModel)) { + idVec3 vCorners[4]; + float fMid = b->mins[2] + (b->maxs[2] - b->mins[2]) / 2; + + vCorners[0][0] = b->mins[0]; + vCorners[0][1] = b->mins[1]; + vCorners[0][2] = fMid; + + vCorners[1][0] = b->mins[0]; + vCorners[1][1] = b->maxs[1]; + vCorners[1][2] = fMid; + + vCorners[2][0] = b->maxs[0]; + vCorners[2][1] = b->maxs[1]; + vCorners[2][2] = fMid; + + vCorners[3][0] = b->maxs[0]; + vCorners[3][1] = b->mins[1]; + vCorners[3][2] = fMid; + + idVec3 vTop, vBottom; + + vTop[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) / 2); + vTop[1] = b->mins[1] + ((b->maxs[1] - b->mins[1]) / 2); + vTop[2] = b->maxs[2]; + + VectorCopy(vTop, vBottom); + vBottom[2] = b->mins[2]; + + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + qglBegin(GL_TRIANGLE_FAN); + qglVertex3fv(vTop.ToFloatPtr()); + qglVertex3fv(vCorners[0].ToFloatPtr()); + qglVertex3fv(vCorners[1].ToFloatPtr()); + qglVertex3fv(vCorners[2].ToFloatPtr()); + qglVertex3fv(vCorners[3].ToFloatPtr()); + qglVertex3fv(vCorners[0].ToFloatPtr()); + qglEnd(); + qglBegin(GL_TRIANGLE_FAN); + qglVertex3fv(vBottom.ToFloatPtr()); + qglVertex3fv(vCorners[0].ToFloatPtr()); + qglVertex3fv(vCorners[3].ToFloatPtr()); + qglVertex3fv(vCorners[2].ToFloatPtr()); + qglVertex3fv(vCorners[1].ToFloatPtr()); + qglVertex3fv(vCorners[0].ToFloatPtr()); + qglEnd(); + DrawBrushEntityName(b); + DrawProjectedLight(b, bSelected, false); + return; + } else if (b->owner->eclass->nShowFlags & ECLASS_MISCMODEL) { + // if (PaintedModel(b, false)) return; + } else if (b->owner->eclass->nShowFlags & ECLASS_ENV) { + Brush_DrawEnv( b, false, bSelected ); + } else if (b->owner->eclass->nShowFlags & ECLASS_COMBATNODE) { + Brush_DrawCombatNode(b, false, bSelected); + } + + if (b->owner->eclass->entityModel) { + Brush_DrawModel( b, false, bSelected ); + DrawBrushEntityName(b); + qglColor4fv(colorSave.ToFloatPtr()); + return; + } + + } + + qglColor4fv(colorSave.ToFloatPtr()); + + if (b->modelHandle > 0) { + Brush_DrawEmitter( b, bSelected, false ); + Brush_DrawModel(b, false, bSelected); + qglColor4fv(colorSave.ToFloatPtr()); + return; + } + + for (face = b->brush_faces, order = 0; face; face = face->next, order++) { + // only draw polygons facing in a direction we care about + if (!ignoreViewType) { + if (nViewType == XY) { + if (face->plane[2] <= 0) { + continue; + } + } else { + if (nViewType == XZ) { + if (face->plane[1] <= 0) { + continue; + } + } else { + if (face->plane[0] <= 0) { + continue; + } + } + } + } + + w = face->face_winding; + if (!w) { + continue; + } + + // + // if (b->alphaBrush && !(face->texdef.flags & SURF_ALPHA)) continue; + // draw the polygon + // + qglBegin(GL_LINE_LOOP); + for (i = 0; i < w->GetNumPoints(); i++) { + qglVertex3fv( (*w)[i].ToFloatPtr() ); + } + qglEnd(); +/* + for (i = 0; i < 3; i++) { + glLabeledPoint(idVec4(1, 0, 0, 1), face->planepts[i], 3, va("%i", i)); + } +*/ + } + + DrawBrushEntityName(b); +} + +/* +================== +PointValueInPointList +================== +*/ +static int PointValueInPointList( idVec3 v ) { + for ( int i = 0; i < g_qeglobals.d_numpoints; i++ ) { + if ( v == g_qeglobals.d_points[i] ) { + return i; + } + } + return -1; +} + + +extern bool Sys_KeyDown(int key); +/* +================ +Brush_Move +================ +*/ +void Brush_Move(brush_t *b, const idVec3 move, bool bSnap, bool updateOrigin) { + int i; + face_t *f; + char text[128]; + + for (f = b->brush_faces; f; f = f->next) { + idVec3 vTemp; + VectorCopy(move, vTemp); + + if (g_PrefsDlg.m_bTextureLock) { + Face_MoveTexture(f, vTemp); + } + + for (i = 0; i < 3; i++) { + VectorAdd(f->planepts[i], move, f->planepts[i]); + } + } + + bool controlDown = Sys_KeyDown(VK_CONTROL); + Brush_Build(b, bSnap, true, false, !controlDown); + + if (b->pPatch) { + Patch_Move(b->pPatch, move); + } + + if ( b->owner->curve ) { + b->owner->curve->Translate( move ); + Entity_UpdateCurveData( b->owner ); + } + + idVec3 temp; + + // PGM - keep the origin vector up to date on fixed size entities. + if (b->owner->eclass->fixedsize || EntityHasModel(b->owner) || (updateOrigin && GetVectorForKey(b->owner, "origin", temp))) { +// if (!b->entityModel) { + bool adjustOrigin = true; + if(b->trackLightOrigin) { + b->owner->lightOrigin += move; + sprintf(text, "%i %i %i", (int)b->owner->lightOrigin[0], (int)b->owner->lightOrigin[1], (int)b->owner->lightOrigin[2]); + SetKeyValue(b->owner, "light_origin", text); + if (QE_SingleBrush(true, true)) { + adjustOrigin = false; + } + } + + if (adjustOrigin && updateOrigin) { + b->owner->origin += move; + if (g_moveOnly) { + sprintf(text, "%g %g %g", b->owner->origin[0], b->owner->origin[1], b->owner->origin[2]); + } else { + sprintf(text, "%i %i %i", (int)b->owner->origin[0], (int)b->owner->origin[1], (int)b->owner->origin[2]); + } + SetKeyValue(b->owner, "origin", text); + } + + // rebuild the light dragging points now that the origin has changed + idVec3 offset; + offset.Zero(); + if (controlDown) { + offset.x = -move.x; + offset.y = -move.y; + offset.z = -move.z; + Brush_UpdateLightPoints(b, offset); + } else { + offset.Zero(); + Brush_UpdateLightPoints(b, offset); + } + + //} + if (b->owner->eclass->nShowFlags & ECLASS_ENV) { + const idKeyValue *arg = b->owner->epairs.MatchPrefix( "body ", NULL ); + idStr val; + idVec3 org; + idAngles ang; + while ( arg ) { + sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll ); + org += move; + val = org.ToString(8); + val += " "; + val += ang.ToString(8); + b->owner->epairs.Set(arg->GetKey(), val); + arg = b->owner->epairs.MatchPrefix( "body ", arg ); + } + } + } +} + +/* +================ +Select_AddProjectedLight +================ +*/ +void Select_AddProjectedLight() { + idVec3 vTemp; + CString str; + + // if (!QE_SingleBrush ()) return; + brush_t *b = selected_brushes.next; + + if (b->owner->eclass->nShowFlags & ECLASS_LIGHT) { + vTemp[0] = vTemp[1] = 0; + vTemp[2] = -256; + str.Format("%f %f %f", vTemp[0], vTemp[1], vTemp[2]); + SetKeyValue(b->owner, "light_target", str); + + vTemp[2] = 0; + vTemp[1] = -128; + str.Format("%f %f %f", vTemp[0], vTemp[1], vTemp[2]); + SetKeyValue(b->owner, "light_up", str); + + vTemp[1] = 0; + vTemp[0] = -128; + str.Format("%f %f %f", vTemp[0], vTemp[1], vTemp[2]); + SetKeyValue(b->owner, "light_right", str); + Brush_Build(b); + } +} + +/* +================ +Brush_Print +================ +*/ +void Brush_Print(brush_t *b) { + int nFace = 0; + for (face_t * f = b->brush_faces; f; f = f->next) { + common->Printf("Face %i\n", nFace++); + common->Printf("%f %f %f\n", f->planepts[0][0], f->planepts[0][1], f->planepts[0][2]); + common->Printf("%f %f %f\n", f->planepts[1][0], f->planepts[1][1], f->planepts[1][2]); + common->Printf("%f %f %f\n", f->planepts[2][0], f->planepts[2][1], f->planepts[2][2]); + } +} + +/* +================ +Brush_MakeSidedCone + + Makes the current brush have the given number of 2d sides and turns it into a cone +================ +*/ +void Brush_MakeSidedCone(int sides) { + int i; + idVec3 mins, maxs; + brush_t *b; + texdef_t *texdef; + face_t *f; + idVec3 mid; + float width; + float sv, cv; + + if (sides < 3) { + Sys_Status("Bad sides number", 0); + return; + } + + if (!QE_SingleBrush()) { + Sys_Status("Must have a single brush selected", 0); + return; + } + + b = selected_brushes.next; + VectorCopy(b->mins, mins); + VectorCopy(b->maxs, maxs); + texdef = &g_qeglobals.d_texturewin.texdef; + + Brush_Free(b); + + // find center of brush + width = 8; + for (i = 0; i < 2; i++) { + mid[i] = (maxs[i] + mins[i]) * 0.5f; + if (maxs[i] - mins[i] > width) { + width = maxs[i] - mins[i]; + } + } + + width *= 0.5f; + + b = Brush_Alloc(); + + // create bottom face + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + f->planepts[0][0] = mins[0]; + f->planepts[0][1] = mins[1]; + f->planepts[0][2] = mins[2]; + f->planepts[1][0] = maxs[0]; + f->planepts[1][1] = mins[1]; + f->planepts[1][2] = mins[2]; + f->planepts[2][0] = maxs[0]; + f->planepts[2][1] = maxs[1]; + f->planepts[2][2] = mins[2]; + + for (i = 0; i < sides; i++) { + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + sv = sin(i * idMath::TWO_PI / sides); + cv = cos(i * idMath::TWO_PI / sides); + + f->planepts[0][0] = floor( mid[0] + width * cv + 0.5f ); + f->planepts[0][1] = floor( mid[1] + width * sv + 0.5f ); + f->planepts[0][2] = mins[2]; + + f->planepts[1][0] = mid[0]; + f->planepts[1][1] = mid[1]; + f->planepts[1][2] = maxs[2]; + + f->planepts[2][0] = floor( f->planepts[0][0] - width * sv + 0.5f ); + f->planepts[2][1] = floor( f->planepts[0][1] + width * cv + 0.5f ); + f->planepts[2][2] = maxs[2]; + } + + Brush_AddToList(b, &selected_brushes); + + Entity_LinkBrush(world_entity, b); + + Brush_Build(b); + + Sys_UpdateWindows(W_ALL); +} + +/* +================ +Brush_MakeSidedSphere + + Makes the current brushhave the given number of 2d sides and turns it into a sphere +================ +*/ +void Brush_MakeSidedSphere(int sides) { + int i, j; + idVec3 mins, maxs; + brush_t *b; + texdef_t *texdef; + face_t *f; + idVec3 mid; + float radius; + + if (sides < 4) { + Sys_Status("Bad sides number", 0); + return; + } + + if (!QE_SingleBrush()) { + Sys_Status("Must have a single brush selected", 0); + return; + } + + b = selected_brushes.next; + mins = b->mins; + maxs = b->maxs; + texdef = &g_qeglobals.d_texturewin.texdef; + + Brush_Free(b); + + // find center of brush + radius = 8; + for ( i = 0; i < 3; i++ ) { + mid[i] = (maxs[i] + mins[i]) * 0.5f; + if (maxs[i] - mins[i] > radius) { + radius = maxs[i] - mins[i]; + } + } + + radius *= 0.5f; + + b = Brush_Alloc(); + + for (i = 0; i < sides; i++) { + for (j = 0; j < sides - 1; j++) { + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + f->planepts[0] = idPolar3(radius, idMath::TWO_PI * i / sides, idMath::PI * ((float)(j) / sides - 0.5f) ).ToVec3() + mid; + f->planepts[1] = idPolar3(radius, idMath::TWO_PI * i / sides, idMath::PI * ((float)(j+1) / sides - 0.5f) ).ToVec3() + mid; + f->planepts[2] = idPolar3(radius, idMath::TWO_PI * (i+1) / sides, idMath::PI * ((float)(j+1) / sides - 0.5f) ).ToVec3() + mid; + } + } + + Brush_AddToList(b, &selected_brushes); + + Entity_LinkBrush(world_entity, b); + + Brush_Build(b); + + Sys_UpdateWindows(W_ALL); +} + +extern void Face_FitTexture_BrushPrimit(face_t *f, idVec3 mins, idVec3 maxs, float nHeight, float nWidth); + +/* +================ +Face_FitTexture +================ +*/ +void Face_FitTexture(face_t *face, float nHeight, float nWidth) { + if (g_qeglobals.m_bBrushPrimitMode) { + idVec3 mins, maxs; + mins[0] = maxs[0] = 0; + Face_FitTexture_BrushPrimit(face, mins, maxs, nHeight, nWidth); + } + else { + /* + * winding_t *w; idBounds bounds; int i; float width, height, temp; float rot_width, + * rot_height; float cosv,sinv,ang; float min_t, min_s, max_t, max_s; float s,t; + * idVec3 vecs[2]; idVec3 coords[4]; texdef_t *td; if (nHeight < 1) { nHeight = 1; + * } if (nWidth < 1) { nWidth = 1; } bounds.Clear(); td = &face->texdef; w = + * face->face_winding; if (!w) { return; } for (i=0 ; inumpoints ; i++) { + * bounds.AddPoint( w->p[i] ); } // // get the current angle // ang = td->rotate / + * 180 * Q_PI; sinv = sin(ang); cosv = cos(ang); // get natural texture axis + * TextureAxisFromPlane(&face->plane, vecs[0], vecs[1]); min_s = DotProduct( + * bounds.b[0], vecs[0] ); min_t = DotProduct( bounds.b[0], vecs[1] ); max_s = + * DotProduct( bounds.b[1], vecs[0] ); max_t = DotProduct( bounds.b[1], vecs[1] ); + * width = max_s - min_s; height = max_t - min_t; coords[0][0] = min_s; + * coords[0][1] = min_t; coords[1][0] = max_s; coords[1][1] = min_t; coords[2][0] + * = min_s; coords[2][1] = max_t; coords[3][0] = max_s; coords[3][1] = max_t; + * min_s = min_t = 999999; max_s = max_t = -999999; for (i=0; i<4; i++) { s = cosv + * * coords[i][0] - sinv * coords[i][1]; t = sinv * coords[i][0] + cosv * + * coords[i][1]; if (i&1) { if (s > max_s) { max_s = s; } } else { if (s < min_s) + * { min_s = s; } if (i<2) { if (t < min_t) { min_t = t; } } else { if (t > max_t) + * { max_t = t; } } } } rot_width = (max_s - min_s); rot_height = (max_t - min_t); + * td->scale[0] = + * -(rot_width/((float)(face->d_texture->GetEditorImage()->uploadWidth*nWidth))); + * td->scale[1] = + * -(rot_height/((float)(face->d_texture->GetEditorImage()->uploadHeight*nHeight))); + * td->shift[0] = min_s/td->scale[0]; temp = (int)(td->shift[0] / + * (face->d_texture->GetEditorImage()->uploadWidth*nWidth)); temp = + * (temp+1)*face->d_texture->GetEditorImage()->uploadWidth*nWidth; td->shift[0] = + * (int)(temp - + * td->shift[0])%(face->d_texture->GetEditorImage()->uploadWidth*nWidth); + * td->shift[1] = min_t/td->scale[1]; temp = (int)(td->shift[1] / + * (face->d_texture->GetEditorImage()->uploadHeight*nHeight)); temp = + * (temp+1)*(face->d_texture->GetEditorImage()->uploadHeight*nHeight); + * td->shift[1] = (int)(temp - + * td->shift[1])%(face->d_texture->GetEditorImage()->uploadHeight*nHeight); + */ + } +} + +/* +================ +Brush_FitTexture +================ +*/ +void Brush_FitTexture(brush_t *b, float nHeight, float nWidth) { + face_t *face; + for (face = b->brush_faces; face; face = face->next) { + Face_FitTexture(face, nHeight, nWidth); + } +} + +void Brush_GetBounds( brush_t *b, idBounds &bo ) { + if ( b == NULL ) { + return; + } + + bo.Clear(); + bo.AddPoint( b->mins ); + bo.AddPoint( b->maxs ); + + if ( b->owner->curve ) { + int c = b->owner->curve->GetNumValues(); + for ( int i = 0; i < c; i++ ) { + bo.AddPoint ( b->owner->curve->GetValue( i ) ); + } + } + +} diff --git a/tools/radiant/EditorBrush.h b/tools/radiant/EditorBrush.h new file mode 100644 index 000000000..ca3a4714c --- /dev/null +++ b/tools/radiant/EditorBrush.h @@ -0,0 +1,70 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// brush.h + +brush_t * Brush_Alloc(); +void Brush_Free (brush_t *b, bool bRemoveNode = true); +int Brush_MemorySize(brush_t *b); +void Brush_MakeSided (int sides); +void Brush_MakeSidedCone (int sides); +void Brush_Move (brush_t *b, const idVec3 move, bool bSnap = true, bool updateOrigin = true); +int Brush_MoveVertex(brush_t *b, const idVec3 &vertex, const idVec3 &delta, idVec3 &end, bool bSnap); +void Brush_ResetFaceOriginals(brush_t *b); +brush_t * Brush_Parse (const idVec3 origin); +face_t * Brush_Ray (idVec3 origin, idVec3 dir, brush_t *b, float *dist, bool testPrimitive = false); +void Brush_RemoveFromList (brush_t *b); +void Brush_AddToList (brush_t *b, brush_t *list); +void Brush_Build(brush_t *b, bool bSnap = true, bool bMarkMap = true, bool bConvert = false, bool updateLights = true); +void Brush_BuildWindings( brush_t *b, bool bSnap = true, bool keepOnPlaneWinding = false, bool updateLights = true, bool makeFacePlanes = true ); +brush_t * Brush_Clone (brush_t *b); +brush_t * Brush_FullClone(brush_t *b); +brush_t * Brush_Create (idVec3 mins, idVec3 maxs, texdef_t *texdef); +void Brush_Draw( brush_t *b, bool bSelected = false); +void Brush_DrawXY(brush_t *b, int nViewType, bool bSelected = false, bool ignoreViewType = false); +void Brush_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back); +void Brush_SelectFaceForDragging (brush_t *b, face_t *f, bool shear); +void Brush_SetTexture (brush_t *b, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale = false); +void Brush_SideSelect (brush_t *b, idVec3 origin, idVec3 dir, bool shear); +void Brush_SnapToGrid(brush_t *pb); +void Brush_Rotate(brush_t *b, idVec3 vAngle, idVec3 vOrigin, bool bBuild = true); +void Brush_MakeSidedSphere(int sides); +void Brush_Write (brush_t *b, FILE *f, const idVec3 &origin, bool newFormat); +void Brush_Write (brush_t *b, CMemFile* pMemFile, const idVec3 &origin, bool NewFormat); +void Brush_RemoveEmptyFaces ( brush_t *b ); +idWinding * Brush_MakeFaceWinding (brush_t *b, face_t *face, bool keepOnPlaneWinding = false); +void Brush_SetTextureName(brush_t *b, const char *name); +void Brush_Print(brush_t* b); +void Brush_FitTexture( brush_t *b, float height, float width ); +void Brush_SetEpair(brush_t *b, const char *pKey, const char *pValue); +const char *Brush_GetKeyValue(brush_t *b, const char *pKey); +const char *Brush_Name(brush_t *b); +void Brush_RebuildBrush(brush_t *b, idVec3 vMins, idVec3 vMaxs, bool patch = true); +void Brush_GetBounds( brush_t *b, idBounds &bo ); + +face_t * Face_Alloc( void ); +void Face_Free( face_t *f ); +face_t * Face_Clone (face_t *f); +void Face_MakePlane (face_t *f); +void Face_Draw( face_t *face ); +void Face_TextureVectors (face_t *f, float STfromXYZ[2][4]); +void Face_FitTexture( face_t * face, float height, float width ); +void SetFaceTexdef (brush_t *b, face_t *f, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale = false); + +int AddPlanept (idVec3 *f); diff --git a/tools/radiant/EditorBrushPrimit.cpp b/tools/radiant/EditorBrushPrimit.cpp new file mode 100644 index 000000000..aefdcd025 --- /dev/null +++ b/tools/radiant/EditorBrushPrimit.cpp @@ -0,0 +1,1230 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +#define ZERO_EPSILON 1.0E-6 + +class idVec3D { +public: + double x, y, z; + double & operator[]( const int index ) { + return (&x)[index]; + } + void Zero() { + x = y = z = 0.0; + } +}; + +// +// ======================================================================================================================= +// compute a determinant using Sarrus rule ++timo "inline" this with a macro NOTE:: the three idVec3D are understood as +// columns of the matrix +// ======================================================================================================================= +// +double SarrusDet(idVec3D a, idVec3D b, idVec3D c) { + return (double)a[0] * (double)b[1] * (double)c[2] + (double)b[0] * (double)c[1] * (double)a[2] + (double)c[0] * (double)a[1] * (double)b[2] - (double)c[0] * (double)b[1] * (double)a[2] - (double)a[1] * (double)b[0] * (double)c[2] - (double)a[0] * (double)b[2] * (double)c[1]; +} + +// +// ======================================================================================================================= +// ++timo replace everywhere texX by texS etc. ( > and in q3map !) NOTE:: ComputeAxisBase here and in q3map code must +// always BE THE SAME ! WARNING:: special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere +// when x == 0 rotation by (0,RotY,RotZ) assigns X to normal +// ======================================================================================================================= +// +void ComputeAxisBase(idVec3 &normal, idVec3D &texS, idVec3D &texT) { + double RotY, RotZ; + + // do some cleaning + if (idMath::Fabs(normal[0]) < 1e-6) { + normal[0] = 0.0f; + } + + if (idMath::Fabs(normal[1]) < 1e-6) { + normal[1] = 0.0f; + } + + if (idMath::Fabs(normal[2]) < 1e-6) { + normal[2] = 0.0f; + } + + RotY = -atan2(normal[2], idMath::Sqrt(normal[1] * normal[1] + normal[0] * normal[0])); + RotZ = atan2(normal[1], normal[0]); + + // rotate (0,1,0) and (0,0,1) to compute texS and texT + texS[0] = -sin(RotZ); + texS[1] = cos(RotZ); + texS[2] = 0; + + // the texT vector is along -Z ( T texture coorinates axis ) + texT[0] = -sin(RotY) * cos(RotZ); + texT[1] = -sin(RotY) * sin(RotZ); + texT[2] = -cos(RotY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void FaceToBrushPrimitFace(face_t *f) { + idVec3D texX, texY; + idVec3D proj; + + // ST of (0,0) (1,0) (0,1) + idVec5 ST[3]; // [ point index ] [ xyz ST ] + + // + // ++timo not used as long as brushprimit_texdef and texdef are static + // f->brushprimit_texdef.contents=f->texdef.contents; + // f->brushprimit_texdef.flags=f->texdef.flags; + // f->brushprimit_texdef.value=f->texdef.value; + // strcpy(f->brushprimit_texdef.name,f->texdef.name); + // +#ifdef _DEBUG + if (f->plane[0] == 0.0f && f->plane[1] == 0.0f && f->plane[2] == 0.0f) { + common->Printf("Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n"); + } + + // check d_texture + if (!f->d_texture) { + common->Printf("Warning : f.d_texture is NULL in FaceToBrushPrimitFace\n"); + return; + } +#endif + // compute axis base + ComputeAxisBase(f->plane.Normal(), texX, texY); + + // compute projection vector + VectorCopy( f->plane, proj ); + VectorScale(proj, -f->plane[3], proj); + + // + // (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the + // affine plane (1,0) in plane axis base is texX in world coordinates + projection + // on the affine plane (0,1) in plane axis base is texY in world coordinates + + // projection on the affine plane use old texture code to compute the ST coords of + // these points + // + VectorCopy(proj, ST[0]); + EmitTextureCoordinates(ST[0], f->d_texture, f); + VectorCopy(texX, ST[1]); + VectorAdd(ST[1], proj, ST[1]); + EmitTextureCoordinates(ST[1], f->d_texture, f); + VectorCopy(texY, ST[2]); + VectorAdd(ST[2], proj, ST[2]); + EmitTextureCoordinates(ST[2], f->d_texture, f); + + // compute texture matrix + f->brushprimit_texdef.coords[0][2] = ST[0][3]; + f->brushprimit_texdef.coords[1][2] = ST[0][4]; + f->brushprimit_texdef.coords[0][0] = ST[1][3] - f->brushprimit_texdef.coords[0][2]; + f->brushprimit_texdef.coords[1][0] = ST[1][4] - f->brushprimit_texdef.coords[1][2]; + f->brushprimit_texdef.coords[0][1] = ST[2][3] - f->brushprimit_texdef.coords[0][2]; + f->brushprimit_texdef.coords[1][1] = ST[2][4] - f->brushprimit_texdef.coords[1][2]; +} + +// +// ======================================================================================================================= +// compute texture coordinates for the winding points +// ======================================================================================================================= +// +void EmitBrushPrimitTextureCoordinates(face_t *f, idWinding *w, patchMesh_t *patch) { + idVec3D texX, texY; + double x, y; + + if (f== NULL || (w == NULL && patch == NULL)) { + return; + } + + // compute axis base + ComputeAxisBase(f->plane.Normal(), texX, texY); + + // + // in case the texcoords matrix is empty, build a default one same behaviour as if + // scale[0]==0 && scale[1]==0 in old code + // + if ( f->brushprimit_texdef.coords[0][0] == 0 && + f->brushprimit_texdef.coords[1][0] == 0 && + f->brushprimit_texdef.coords[0][1] == 0 && + f->brushprimit_texdef.coords[1][1] == 0 ) { + f->brushprimit_texdef.coords[0][0] = 1.0f; + f->brushprimit_texdef.coords[1][1] = 1.0f; + ConvertTexMatWithQTexture(&f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture); + } + + int i; + if (w) { + for (i = 0; i < w->GetNumPoints(); i++) { + x = DotProduct((*w)[i], texX); + y = DotProduct((*w)[i], texY); + (*w)[i][3] = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; + (*w)[i][4] = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; + } + } + + if (patch) { + int j; + for ( i = 0; i < patch->width; i++ ) { + for ( j = 0; j < patch->height; j++ ) { + x = DotProduct(patch->ctrl(i, j).xyz, texX); + y = DotProduct(patch->ctrl(i, j).xyz, texY); + patch->ctrl(i, j).st.x = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; + patch->ctrl(i, j).st.y = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; + } + } + } +} + +// +// ======================================================================================================================= +// parse a brush in brush primitive format +// ======================================================================================================================= +// +void BrushPrimit_Parse(brush_t *b, bool newFormat, const idVec3 origin) { + face_t *f; + int i, j; + GetToken(true); + if (strcmp(token, "{")) { + Warning("parsing brush primitive"); + return; + } + + do { + if (!GetToken(true)) { + break; + } + + if (!strcmp(token, "}")) { + break; + } + + // reading of b->epairs if any + if (strcmp(token, "(")) { + ParseEpair(&b->epairs); + } + else { // it's a face + f = Face_Alloc(); + f->next = NULL; + if (!b->brush_faces) { + b->brush_faces = f; + } + else { + face_t *scan; + for (scan = b->brush_faces; scan->next; scan = scan->next) + ; + scan->next = f; + } + + if (newFormat) { + // read the three point plane definition + idPlane plane; + for (j = 0; j < 4; j++) { + GetToken(false); + plane[j] = atof(token); + } + + f->plane = plane; + f->originalPlane = plane; + f->dirty = false; + + //idWinding *w = Brush_MakeFaceWinding(b, f, true); + idWinding w; + w.BaseForPlane( plane ); + + for (j = 0; j < 3; j++) { + f->planepts[j].x = w[j].x + origin.x; + f->planepts[j].y = w[j].y + origin.y; + f->planepts[j].z = w[j].z + origin.z; + } + + GetToken(false); + } + else { + for (i = 0; i < 3; i++) { + if (i != 0) { + GetToken(true); + } + + if (strcmp(token, "(")) { + Warning("parsing brush"); + return; + } + + for (j = 0; j < 3; j++) { + GetToken(false); + f->planepts[i][j] = atof(token); + } + + GetToken(false); + if (strcmp(token, ")")) { + Warning("parsing brush"); + return; + } + } + } + + // texture coordinates + GetToken(false); + if (strcmp(token, "(")) { + Warning("parsing brush primitive"); + return; + } + + GetToken(false); + if (strcmp(token, "(")) { + Warning("parsing brush primitive"); + return; + } + + for (j = 0; j < 3; j++) { + GetToken(false); + f->brushprimit_texdef.coords[0][j] = atof(token); + } + + GetToken(false); + if (strcmp(token, ")")) { + Warning("parsing brush primitive"); + return; + } + + GetToken(false); + if (strcmp(token, "(")) { + Warning("parsing brush primitive"); + return; + } + + for (j = 0; j < 3; j++) { + GetToken(false); + f->brushprimit_texdef.coords[1][j] = atof(token); + } + + GetToken(false); + if (strcmp(token, ")")) { + Warning("parsing brush primitive"); + return; + } + + GetToken(false); + if (strcmp(token, ")")) { + Warning("parsing brush primitive"); + return; + } + + // read the texturedef + GetToken(false); + + // strcpy(f->texdef.name, token); + if (g_qeglobals.mapVersion < 2.0) { + f->texdef.SetName(va("textures/%s", token)); + } + else { + f->texdef.SetName(token); + } + + if (TokenAvailable()) { + GetToken(false); + GetToken(false); + GetToken(false); + f->texdef.value = atoi(token); + } + } + } while (1); +} + +// +// ======================================================================================================================= +// compute a fake shift scale rot representation from the texture matrix these shift scale rot values are to be +// understood in the local axis base +// ======================================================================================================================= +// +void TexMatToFakeTexCoords(float texMat[2][3], float shift[2], float *rot, float scale[2]) +{ +#ifdef _DEBUG + + // check this matrix is orthogonal + if (idMath::Fabs(texMat[0][0] * texMat[0][1] + texMat[1][0] * texMat[1][1]) > ZERO_EPSILON) { + common->Printf("Warning : non orthogonal texture matrix in TexMatToFakeTexCoords\n"); + } +#endif + scale[0] = idMath::Sqrt(texMat[0][0] * texMat[0][0] + texMat[1][0] * texMat[1][0]); + scale[1] = idMath::Sqrt(texMat[0][1] * texMat[0][1] + texMat[1][1] * texMat[1][1]); +#ifdef _DEBUG + if (scale[0] < ZERO_EPSILON || scale[1] < ZERO_EPSILON) { + common->Printf("Warning : unexpected scale==0 in TexMatToFakeTexCoords\n"); + } +#endif + // compute rotate value + if (idMath::Fabs(texMat[0][0]) < ZERO_EPSILON) + { +#ifdef _DEBUG + // check brushprimit_texdef[1][0] is not zero + if (idMath::Fabs(texMat[1][0]) < ZERO_EPSILON) { + common->Printf("Warning : unexpected texdef[1][0]==0 in TexMatToFakeTexCoords\n"); + } +#endif + // rotate is +-90 + if (texMat[1][0] > 0) { + *rot = 90.0f; + } + else { + *rot = -90.0f; + } + } + else { + *rot = RAD2DEG(atan2(texMat[1][0], texMat[0][0])); + } + + shift[0] = -texMat[0][2]; + shift[1] = texMat[1][2]; +} + +// +// ======================================================================================================================= +// compute back the texture matrix from fake shift scale rot the matrix returned must be understood as a qtexture_t +// with width=2 height=2 ( the default one ) +// ======================================================================================================================= +// +void FakeTexCoordsToTexMat(float shift[2], float rot, float scale[2], float texMat[2][3]) { + texMat[0][0] = scale[0] * cos(DEG2RAD(rot)); + texMat[1][0] = scale[0] * sin(DEG2RAD(rot)); + texMat[0][1] = -1.0f * scale[1] * sin(DEG2RAD(rot)); + texMat[1][1] = scale[1] * cos(DEG2RAD(rot)); + texMat[0][2] = -shift[0]; + texMat[1][2] = shift[1]; +} + +// +// ======================================================================================================================= +// convert a texture matrix between two qtexture_t if NULL for qtexture_t, basic 2x2 texture is assumed ( straight +// mapping between s/t coordinates and geometric coordinates ) +// ======================================================================================================================= +// +void ConvertTexMatWithQTexture(float texMat1[2][3], const idMaterial *qtex1, float texMat2[2][3], const idMaterial *qtex2, float sScale = 1.0, float tScale = 1.0) { + float s1, s2; + s1 = (qtex1 ? static_cast(qtex1->GetEditorImage()->uploadWidth) : 2.0f) / (qtex2 ? static_cast(qtex2->GetEditorImage()->uploadWidth) : 2.0f); + s2 = (qtex1 ? static_cast(qtex1->GetEditorImage()->uploadHeight) : 2.0f) / (qtex2 ? static_cast(qtex2->GetEditorImage()->uploadHeight) : 2.0f); + s1 *= sScale; + s2 *= tScale; + texMat2[0][0] = s1 * texMat1[0][0]; + texMat2[0][1] = s1 * texMat1[0][1]; + texMat2[0][2] = s1 * texMat1[0][2]; + texMat2[1][0] = s2 * texMat1[1][0]; + texMat2[1][1] = s2 * texMat1[1][1]; + texMat2[1][2] = s2 * texMat1[1][2]; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ConvertTexMatWithQTexture(brushprimit_texdef_t *texMat1, const idMaterial *qtex1, brushprimit_texdef_t *texMat2, const idMaterial *qtex2, float sScale, float tScale) { + ConvertTexMatWithQTexture(texMat1->coords, qtex1, texMat2->coords, qtex2, sScale, tScale); +} + + +// +// ======================================================================================================================= +// texture locking +// ======================================================================================================================= +// +void Face_MoveTexture_BrushPrimit(face_t *f, idVec3 delta) { + idVec3D texS, texT; + double tx, ty; + idVec3D M[3]; // columns of the matrix .. easier that way + double det; + idVec3D D[2]; + + // compute plane axis base ( doesn't change with translation ) + ComputeAxisBase(f->plane.Normal(), texS, texT); + + // compute translation vector in plane axis base + tx = DotProduct(delta, texS); + ty = DotProduct(delta, texT); + + // fill the data vectors + M[0][0] = tx; + M[0][1] = 1.0f + tx; + M[0][2] = tx; + M[1][0] = ty; + M[1][1] = ty; + M[1][2] = 1.0f + ty; + M[2][0] = 1.0f; + M[2][1] = 1.0f; + M[2][2] = 1.0f; + D[0][0] = f->brushprimit_texdef.coords[0][2]; + D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; + D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; + D[1][0] = f->brushprimit_texdef.coords[1][2]; + D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; + D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; + + // solve + det = SarrusDet(M[0], M[1], M[2]); + f->brushprimit_texdef.coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det; + f->brushprimit_texdef.coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det; + f->brushprimit_texdef.coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det; + f->brushprimit_texdef.coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det; + f->brushprimit_texdef.coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det; + f->brushprimit_texdef.coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det; +} + +// +// ======================================================================================================================= +// call Face_MoveTexture_BrushPrimit after idVec3D computation +// ======================================================================================================================= +// +void Select_ShiftTexture_BrushPrimit(face_t *f, float x, float y, bool autoAdjust) { +#if 0 + idVec3D texS, texT; + idVec3D delta; + ComputeAxisBase(f->plane.normal, texS, texT); + VectorScale(texS, x, texS); + VectorScale(texT, y, texT); + VectorCopy(texS, delta); + VectorAdd(delta, texT, delta); + Face_MoveTexture_BrushPrimit(f, delta); +#else + if (autoAdjust) { + x /= f->d_texture->GetEditorImage()->uploadWidth; + y /= f->d_texture->GetEditorImage()->uploadHeight; + } + f->brushprimit_texdef.coords[0][2] += x; + f->brushprimit_texdef.coords[1][2] += y; + EmitBrushPrimitTextureCoordinates(f, f->face_winding); +#endif +} + +// +// ======================================================================================================================= +// best fitted 2D vector is x.X+y.Y +// ======================================================================================================================= +// +void ComputeBest2DVector(idVec3 v, idVec3 X, idVec3 Y, int &x, int &y) { + double sx, sy; + sx = DotProduct(v, X); + sy = DotProduct(v, Y); + if (idMath::Fabs(sy) > idMath::Fabs(sx)) { + x = 0; + if (sy > 0.0) { + y = 1; + } + else { + y = -1; + } + } + else { + y = 0; + if (sx > 0.0) { + x = 1; + } + else { + x = -1; + } + } +} + +// +// ======================================================================================================================= +// in many case we know three points A,B,C in two axis base B1 and B2 and we want the matrix M so that A(B1) = T * +// A(B2) NOTE: 2D homogeneous space stuff NOTE: we don't do any check to see if there's a solution or we have a +// particular case .. need to make sure before calling NOTE: the third coord of the A,B,C point is ignored NOTE: see +// the commented out section to fill M and D ++timo TODO: update the other members to use this when possible +// ======================================================================================================================= +// +void MatrixForPoints(idVec3D M[3], idVec3D D[2], brushprimit_texdef_t *T) { + // + // idVec3D M[3]; // columns of the matrix .. easier that way (the indexing is not + // standard! it's column-line .. later computations are easier that way) + // + double det; + + // idVec3D D[2]; + M[2][0] = 1.0f; + M[2][1] = 1.0f; + M[2][2] = 1.0f; +#if 0 + + // fill the data vectors + M[0][0] = A2[0]; + M[0][1] = B2[0]; + M[0][2] = C2[0]; + M[1][0] = A2[1]; + M[1][1] = B2[1]; + M[1][2] = C2[1]; + M[2][0] = 1.0f; + M[2][1] = 1.0f; + M[2][2] = 1.0f; + D[0][0] = A1[0]; + D[0][1] = B1[0]; + D[0][2] = C1[0]; + D[1][0] = A1[1]; + D[1][1] = B1[1]; + D[1][2] = C1[1]; +#endif + // solve + det = SarrusDet(M[0], M[1], M[2]); + T->coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det; + T->coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det; + T->coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det; + T->coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det; + T->coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det; + T->coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det; +} + +// +// ======================================================================================================================= +// ++timo FIXME quick'n dirty hack, doesn't care about current texture settings (angle) can be improved .. bug #107311 +// mins and maxs are the face bounding box ++timo fixme: we use the face info, mins and maxs are irrelevant +// ======================================================================================================================= +// +void Face_FitTexture_BrushPrimit(face_t *f, idVec3 mins, idVec3 maxs, float height, float width) { + idVec3D BBoxSTMin, BBoxSTMax; + idWinding *w; + int i, j; + double val; + idVec3D M[3], D[2]; + + // idVec3D N[2],Mf[2]; + brushprimit_texdef_t N; + idVec3D Mf[2]; + + + + //memset(f->brushprimit_texdef.coords, 0, sizeof(f->brushprimit_texdef.coords)); + //f->brushprimit_texdef.coords[0][0] = 1.0f; + //f->brushprimit_texdef.coords[1][1] = 1.0f; + //ConvertTexMatWithQTexture(&f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture); + // + // we'll be working on a standardized texture size ConvertTexMatWithQTexture( + // &f->brushprimit_texdef, f->d_texture, &f->brushprimit_texdef, NULL ); compute + // the BBox in ST coords + // + EmitBrushPrimitTextureCoordinates(f, f->face_winding); + BBoxSTMin[0] = BBoxSTMin[1] = BBoxSTMin[2] = 999999; + BBoxSTMax[0] = BBoxSTMax[1] = BBoxSTMax[2] = -999999; + + w = f->face_winding; + if (w) { + for (i = 0; i < w->GetNumPoints(); i++) { + // AddPointToBounds in 2D on (S,T) coordinates + for (j = 0; j < 2; j++) { + val = (*w)[i][j + 3]; + if (val < BBoxSTMin[j]) { + BBoxSTMin[j] = val; + } + + if (val > BBoxSTMax[j]) { + BBoxSTMax[j] = val; + } + } + } + } + + // + // we have the three points of the BBox (BBoxSTMin[0].BBoxSTMin[1]) + // (BBoxSTMax[0],BBoxSTMin[1]) (BBoxSTMin[0],BBoxSTMax[1]) in ST space the BP + // matrix we are looking for gives (0,0) (nwidth,0) (0,nHeight) coordinates in + // (Sfit,Tfit) space to these three points we have A(Sfit,Tfit) = (0,0) = Mf * + // A(TexS,TexT) = N * M * A(TexS,TexT) = N * A(S,T) so we solve the system for N + // and then Mf = N * M + // + M[0][0] = BBoxSTMin[0]; + M[0][1] = BBoxSTMax[0]; + M[0][2] = BBoxSTMin[0]; + M[1][0] = BBoxSTMin[1]; + M[1][1] = BBoxSTMin[1]; + M[1][2] = BBoxSTMax[1]; + D[0][0] = 0.0f; + D[0][1] = width; + D[0][2] = 0.0f; + D[1][0] = 0.0f; + D[1][1] = 0.0f; + D[1][2] = height; + MatrixForPoints(M, D, &N); + +#if 0 + + // + // FIT operation gives coordinates of three points of the bounding box in (S',T'), + // our target axis base A(S',T')=(0,0) B(S',T')=(nWidth,0) C(S',T')=(0,nHeight) + // and we have them in (S,T) axis base: A(S,T)=(BBoxSTMin[0],BBoxSTMin[1]) + // B(S,T)=(BBoxSTMax[0],BBoxSTMin[1]) C(S,T)=(BBoxSTMin[0],BBoxSTMax[1]) we + // compute the N transformation so that: A(S',T') = N * A(S,T) + // + N[0][0] = (BBoxSTMax[0] - BBoxSTMin[0]) / width; + N[0][1] = 0.0f; + N[0][2] = BBoxSTMin[0]; + N[1][0] = 0.0f; + N[1][1] = (BBoxSTMax[1] - BBoxSTMin[1]) / height; + N[1][2] = BBoxSTMin[1]; +#endif + // the final matrix is the product (Mf stands for Mfit) + Mf[0][0] = N.coords[0][0] * + f->brushprimit_texdef.coords[0][0] + + N.coords[0][1] * + f->brushprimit_texdef.coords[1][0]; + Mf[0][1] = N.coords[0][0] * + f->brushprimit_texdef.coords[0][1] + + N.coords[0][1] * + f->brushprimit_texdef.coords[1][1]; + Mf[0][2] = N.coords[0][0] * + f->brushprimit_texdef.coords[0][2] + + N.coords[0][1] * + f->brushprimit_texdef.coords[1][2] + + N.coords[0][2]; + Mf[1][0] = N.coords[1][0] * + f->brushprimit_texdef.coords[0][0] + + N.coords[1][1] * + f->brushprimit_texdef.coords[1][0]; + Mf[1][1] = N.coords[1][0] * + f->brushprimit_texdef.coords[0][1] + + N.coords[1][1] * + f->brushprimit_texdef.coords[1][1]; + Mf[1][2] = N.coords[1][0] * + f->brushprimit_texdef.coords[0][2] + + N.coords[1][1] * + f->brushprimit_texdef.coords[1][2] + + N.coords[1][2]; + + // copy back + VectorCopy(Mf[0], f->brushprimit_texdef.coords[0]); + VectorCopy(Mf[1], f->brushprimit_texdef.coords[1]); + + // + // handle the texture size ConvertTexMatWithQTexture( &f->brushprimit_texdef, + // NULL, &f->brushprimit_texdef, f->d_texture ); + // +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Face_ScaleTexture_BrushPrimit(face_t *face, float sS, float sT) { + if (!g_qeglobals.m_bBrushPrimitMode) { + Sys_Status("BP mode required\n"); + return; + } + + brushprimit_texdef_t *pBP = &face->brushprimit_texdef; + BPMatScale(pBP->coords, sS, sT); + + // now emit the coordinates on the winding + EmitBrushPrimitTextureCoordinates(face, face->face_winding); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Face_RotateTexture_BrushPrimit(face_t *face, float amount, idVec3 origin) { + brushprimit_texdef_t *pBP = &face->brushprimit_texdef; + if (amount) { + float x = pBP->coords[0][0]; + float y = pBP->coords[0][1]; + float x1 = pBP->coords[1][0]; + float y1 = pBP->coords[1][1]; + float s = sin( DEG2RAD( amount ) ); + float c = cos( DEG2RAD( amount ) ); + pBP->coords[0][0] = (((x - origin[0]) * c) - ((y - origin[1]) * s)) + origin[0]; + pBP->coords[0][1] = (((x - origin[0]) * s) + ((y - origin[1]) * c)) + origin[1]; + pBP->coords[1][0] = (((x1 - origin[0]) * c) - ((y1 - origin[1]) * s)) + origin[0]; + pBP->coords[1][1] = (((x1 - origin[0]) * s) + ((y1 - origin[1]) * c)) + origin[1]; + EmitBrushPrimitTextureCoordinates(face, face->face_winding); + } +} + +// +// TEXTURE LOCKING (Relevant to the editor only?) +// internally used for texture locking on rotation and flipping the general +// algorithm is the same for both lockings, it's only the geometric transformation +// part that changes so I wanted to keep it in a single function if there are more +// linear transformations that need the locking, going to a C++ or code pointer +// solution would be best (but right now I want to keep brush_primit.cpp striclty +// C) +// +bool txlock_bRotation; + +// rotation locking params +int txl_nAxis; +double txl_fDeg; +idVec3D txl_vOrigin; + +// flip locking params +idVec3D txl_matrix[3]; +idVec3D txl_origin; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void TextureLockTransformation_BrushPrimit(face_t *f) { + idVec3D Orig, texS, texT; // axis base of initial plane + + // used by transformation algo + idVec3D temp; + int j; + //idVec3D vRotate; // rotation vector + + idVec3D rOrig, rvecS, rvecT; // geometric transformation of (0,0) (1,0) (0,1) { initial plane axis base } + idVec3 rNormal; + idVec3D rtexS, rtexT; // axis base for the transformed plane + idVec3D lOrig, lvecS, lvecT; // [2] are not used ( but usefull for debugging ) + idVec3D M[3]; + double det; + idVec3D D[2]; + + // silence compiler warnings + rOrig.Zero(); + rvecS = rOrig; + rvecT = rOrig; + rNormal.x = rOrig.x; + rNormal.y = rOrig.y; + rNormal.z = rOrig.z; + + // compute plane axis base + ComputeAxisBase(f->plane.Normal(), texS, texT); + Orig.x = vec3_origin.x; + Orig.y = vec3_origin.y; + Orig.z = vec3_origin.z; + + // + // compute coordinates of (0,0) (1,0) (0,1) ( expressed in initial plane axis base + // ) after transformation (0,0) (1,0) (0,1) ( expressed in initial plane axis base + // ) <-> (0,0,0) texS texT ( expressed world axis base ) input: Orig, texS, texT + // (and the global locking params) ouput: rOrig, rvecS, rvecT, rNormal + // + if (txlock_bRotation) { +/* + // rotation vector + vRotate.x = vec3_origin.x; + vRotate.y = vec3_origin.y; + vRotate.z = vec3_origin.z; + vRotate[txl_nAxis] = txl_fDeg; + VectorRotate3Origin(Orig, vRotate, txl_vOrigin, rOrig); + VectorRotate3Origin(texS, vRotate, txl_vOrigin, rvecS); + VectorRotate3Origin(texT, vRotate, txl_vOrigin, rvecT); + + // compute normal of plane after rotation + VectorRotate3(f->plane.Normal(), vRotate, rNormal); +*/ + } + else { + VectorSubtract(Orig, txl_origin, temp); + for (j = 0; j < 3; j++) { + rOrig[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j]; + } + + VectorSubtract(texS, txl_origin, temp); + for (j = 0; j < 3; j++) { + rvecS[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j]; + } + + VectorSubtract(texT, txl_origin, temp); + for (j = 0; j < 3; j++) { + rvecT[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j]; + } + + // + // we also need the axis base of the target plane, apply the transformation matrix + // to the normal too.. + // + for (j = 0; j < 3; j++) { + rNormal[j] = DotProduct(f->plane, txl_matrix[j]); + } + } + + // compute rotated plane axis base + ComputeAxisBase(rNormal, rtexS, rtexT); + + // compute S/T coordinates of the three points in rotated axis base ( in M matrix ) + lOrig[0] = DotProduct(rOrig, rtexS); + lOrig[1] = DotProduct(rOrig, rtexT); + lvecS[0] = DotProduct(rvecS, rtexS); + lvecS[1] = DotProduct(rvecS, rtexT); + lvecT[0] = DotProduct(rvecT, rtexS); + lvecT[1] = DotProduct(rvecT, rtexT); + M[0][0] = lOrig[0]; + M[1][0] = lOrig[1]; + M[2][0] = 1.0f; + M[0][1] = lvecS[0]; + M[1][1] = lvecS[1]; + M[2][1] = 1.0f; + M[0][2] = lvecT[0]; + M[1][2] = lvecT[1]; + M[2][2] = 1.0f; + + // fill data vector + D[0][0] = f->brushprimit_texdef.coords[0][2]; + D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; + D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; + D[1][0] = f->brushprimit_texdef.coords[1][2]; + D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; + D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; + + // solve + det = SarrusDet(M[0], M[1], M[2]); + f->brushprimit_texdef.coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det; + f->brushprimit_texdef.coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det; + f->brushprimit_texdef.coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det; + f->brushprimit_texdef.coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det; + f->brushprimit_texdef.coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det; + f->brushprimit_texdef.coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det; +} + +// +// ======================================================================================================================= +// texture locking called before the points on the face are actually rotated +// ======================================================================================================================= +// +void RotateFaceTexture_BrushPrimit(face_t *f, int nAxis, float fDeg, idVec3 vOrigin) { + // this is a placeholder to call the general texture locking algorithm + txlock_bRotation = true; + txl_nAxis = nAxis; + txl_fDeg = fDeg; + VectorCopy(vOrigin, txl_vOrigin); + TextureLockTransformation_BrushPrimit(f); +} + +// +// ======================================================================================================================= +// compute the new brush primit texture matrix for a transformation matrix and a flip order flag (change plane o +// rientation) this matches the select_matrix algo used in select.cpp this needs to be called on the face BEFORE any +// geometric transformation it will compute the texture matrix that will represent the same texture on the face after +// the geometric transformation is done +// ======================================================================================================================= +// +void ApplyMatrix_BrushPrimit(face_t *f, idMat3 matrix, idVec3 origin) { + // this is a placeholder to call the general texture locking algorithm + txlock_bRotation = false; + VectorCopy(matrix[0], txl_matrix[0]); + VectorCopy(matrix[1], txl_matrix[1]); + VectorCopy(matrix[2], txl_matrix[2]); + VectorCopy(origin, txl_origin); + TextureLockTransformation_BrushPrimit(f); +} + +// +// ======================================================================================================================= +// don't do C==A! +// ======================================================================================================================= +// +void BPMatMul(float A[2][3], float B[2][3], float C[2][3]) { + C[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0]; + C[1][0] = A[1][0] * B[0][0] + A[1][1] * B[1][0]; + C[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1]; + C[1][1] = A[1][0] * B[0][1] + A[1][1] * B[1][1]; + C[0][2] = A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2]; + C[1][2] = A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2]; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void BPMatDump(float A[2][3]) { + common->Printf("%g %g %g\n%g %g %g\n0 0 1\n", A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], A[1][2]); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void BPMatRotate(float A[2][3], float theta) { + float m[2][3]; + float aux[2][3]; + memset(&m, 0, sizeof (float) *6); + m[0][0] = cos( DEG2RAD( theta ) ); + m[0][1] = -sin( DEG2RAD( theta ) ); + m[1][0] = -m[0][1]; + m[1][1] = m[0][0]; + BPMatMul(A, m, aux); + BPMatCopy(aux, A); +} + +void Face_GetScale_BrushPrimit(face_t *face, float *s, float *t, float *rot) { + idVec3D texS, texT; + ComputeAxisBase(face->plane.Normal(), texS, texT); + + if (face == NULL || face->face_winding == NULL) { + return; + } + // find ST coordinates for the center of the face + double Os = 0, Ot = 0; + for (int i = 0; i < face->face_winding->GetNumPoints(); i++) { + Os += DotProduct((*face->face_winding)[i], texS); + Ot += DotProduct((*face->face_winding)[i], texT); + } + + Os /= face->face_winding->GetNumPoints(); + Ot /= face->face_winding->GetNumPoints(); + + brushprimit_texdef_t *pBP = &face->brushprimit_texdef; + + // here we have a special case, M is a translation and it's inverse is easy + float BPO[2][3]; + float aux[2][3]; + float m[2][3]; + memset(&m, 0, sizeof (float) *6); + m[0][0] = 1; + m[1][1] = 1; + m[0][2] = -Os; + m[1][2] = -Ot; + BPMatMul(m, pBP->coords, aux); + m[0][2] = Os; + m[1][2] = Ot; // now M^-1 + BPMatMul(aux, m, BPO); + + // apply a given scale (on S and T) + ConvertTexMatWithQTexture(BPO, face->d_texture, aux, NULL); + + *s = idMath::Sqrt(aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0]); + *t = idMath::Sqrt(aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1]); + + // compute rotate value + if (idMath::Fabs(face->brushprimit_texdef.coords[0][0]) < ZERO_EPSILON) + { + // rotate is +-90 + if (face->brushprimit_texdef.coords[1][0] > 0) { + *rot = 90.0f; + } + else { + *rot = -90.0f; + } + } + else { + *rot = RAD2DEG(atan2(face->brushprimit_texdef.coords[1][0] / (*s) ? (*s) : 1.0f, face->brushprimit_texdef.coords[0][0] / (*t) ? (*t) : 1.0f)); + } + + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Face_SetExplicitScale_BrushPrimit(face_t *face, float s, float t) { + idVec3D texS, texT; + ComputeAxisBase(face->plane.Normal(), texS, texT); + + // find ST coordinates for the center of the face + double Os = 0, Ot = 0; + + for (int i = 0; i < face->face_winding->GetNumPoints(); i++) { + Os += DotProduct((*face->face_winding)[i], texS); + Ot += DotProduct((*face->face_winding)[i], texT); + } + + Os /= face->face_winding->GetNumPoints(); + Ot /= face->face_winding->GetNumPoints(); + + brushprimit_texdef_t *pBP = &face->brushprimit_texdef; + + // here we have a special case, M is a translation and it's inverse is easy + float BPO[2][3]; + float aux[2][3]; + float m[2][3]; + memset(&m, 0, sizeof (float) *6); + m[0][0] = 1; + m[1][1] = 1; + m[0][2] = -Os; + m[1][2] = -Ot; + BPMatMul(m, pBP->coords, aux); + m[0][2] = Os; + m[1][2] = Ot; // now M^-1 + BPMatMul(aux, m, BPO); + + // apply a given scale (on S and T) + ConvertTexMatWithQTexture(BPO, face->d_texture, aux, NULL); + + // reset the scale (normalize the matrix) + double v1, v2; + v1 = idMath::Sqrt(aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0]); + v2 = idMath::Sqrt(aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1]); + + if (s == 0.0) { + s = v1; + } + if (t == 0.0) { + t = v2; + } + + double sS, sT; + + // put the values for scale on S and T here: + sS = s / v1; + sT = t / v2; + aux[0][0] *= sS; + aux[1][0] *= sS; + aux[0][1] *= sT; + aux[1][1] *= sT; + ConvertTexMatWithQTexture(aux, NULL, BPO, face->d_texture); + BPMatMul(m, BPO, aux); // m is M^-1 + m[0][2] = -Os; + m[1][2] = -Ot; + BPMatMul(aux, m, pBP->coords); + + // now emit the coordinates on the winding + EmitBrushPrimitTextureCoordinates(face, face->face_winding); +} + + +void Face_FlipTexture_BrushPrimit(face_t *f, bool y) { + + float s, t, rot; + Face_GetScale_BrushPrimit(f, &s, &t, &rot); + if (y) { + Face_SetExplicitScale_BrushPrimit(f, 0.0, -t); + } else { + Face_SetExplicitScale_BrushPrimit(f, -s, 0.0); + } +#if 0 + + idVec3D texS, texT; + ComputeAxisBase(f->plane.normal, texS, texT); + double Os = 0, Ot = 0; + for (int i = 0; i < f->face_winding->numpoints; i++) { + Os += DotProduct(f->face_winding->p[i], texS); + Ot += DotProduct(f->face_winding->p[i], texT); + } + + Ot = abs(Ot); + Ot *= t; + Ot /= f->d_texture->GetEditorImage()->uploadHeight; + + Os = abs(Os); + Os *= s; + Os /= f->d_texture->GetEditorImage()->uploadWidth; + + + if (y) { + Face_FitTexture_BrushPrimit(f, texS, texT, -Ot, 1.0); + } else { + Face_FitTexture_BrushPrimit(f, texS, texT, 1.0, -Os); + } + EmitBrushPrimitTextureCoordinates(f, f->face_winding); +#endif +} + +void Brush_FlipTexture_BrushPrimit(brush_t *b, bool y) { + for (face_t *f = b->brush_faces; f; f = f->next) { + Face_FlipTexture_BrushPrimit(f, y); + } +} + +void Face_SetAxialScale_BrushPrimit(face_t *face, bool y) { + + if (!face) { + return; + } + + if (!face->face_winding) { + return; + } + + //float oldS, oldT, oldR; + //Face_GetScale_BrushPrimit(face, &oldS, &oldT, &oldR); + + idVec3D min, max; + min.x = min.y = min.z = 999999.0; + max.x = max.y = max.z = -999999.0; + for (int i = 0; i < face->face_winding->GetNumPoints(); i++) { + for (int j = 0; j < 3; j++) { + if ((*face->face_winding)[i][j] < min[j]) { + min[j] = (*face->face_winding)[i][j]; + } + if ((*face->face_winding)[i][j] > max[j]) { + max[j] = (*face->face_winding)[i][j]; + } + } + } + + idVec3 len; + + if (g_bAxialMode) { + if (g_axialAnchor >= 0 && g_axialAnchor < face->face_winding->GetNumPoints() && + g_axialDest >= 0 && g_axialDest < face->face_winding->GetNumPoints() && + g_axialAnchor != g_axialDest) { + len = (*face->face_winding)[g_axialDest].ToVec3() - (*face->face_winding)[g_axialAnchor].ToVec3(); + } else { + return; + } + } else { + if (y) { + len = (*face->face_winding)[2].ToVec3() - (*face->face_winding)[1].ToVec3(); + } else { + len = (*face->face_winding)[1].ToVec3() - (*face->face_winding)[0].ToVec3(); + } + } + + double dist = len.Length(); + double width = idMath::Fabs(max.x - min.x); + double height = idMath::Fabs(max.z - min.z); + + //len = maxs[2] - mins[2]; + //double yDist = len.Length(); + + + if (dist != 0.0) { + if (dist > face->d_texture->GetEditorImage()->uploadHeight) { + height = 1.0 / (dist / face->d_texture->GetEditorImage()->uploadHeight); + } else { + height /= dist; + } + if (dist > face->d_texture->GetEditorImage()->uploadWidth) { + width = 1.0 / (dist / face->d_texture->GetEditorImage()->uploadWidth); + } else { + width /= dist; + } + } + + if (y) { + Face_SetExplicitScale_BrushPrimit(face, 0.0, height); + //oldT = oldT / height * 10; + //Select_ShiftTexture_BrushPrimit(face, 0, -oldT, true); + } else { + Face_SetExplicitScale_BrushPrimit(face, width, 0.0); + } +/* + common->Printf("Face x: %f y: %f xr: %f yr: %f\n", x, y, xRatio, yRatio); + common->Printf("Texture x: %i y: %i \n",face->d_texture->GetEditorImage()->uploadWidth, face->d_texture->GetEditorImage()->uploadHeight); + + idVec3D texS, texT; + ComputeAxisBase(face->plane.normal, texS, texT); + float Os = 0, Ot = 0; + for (int i = 0; i < face->face_winding->numpoints; i++) { + Os += DotProduct(face->face_winding->p[i], texS); + Ot += DotProduct(face->face_winding->p[i], texT); + } + + common->Printf("Face2 x: %f y: %f \n", Os, Ot); + Os /= face->face_winding->numpoints; + Ot /= face->face_winding->numpoints; + + + //Os /= face->face_winding->numpoints; + //Ot /= face->face_winding->numpoints; + +*/ +} + diff --git a/tools/radiant/EditorEntity.cpp b/tools/radiant/EditorEntity.cpp new file mode 100644 index 000000000..5649ee7a9 --- /dev/null +++ b/tools/radiant/EditorEntity.cpp @@ -0,0 +1,1392 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "../../renderer/tr_local.h" +#include "../../renderer/model_local.h" // for idRenderModelMD5 +int g_entityId = 1; + +#define CURVE_TAG "curve_" + +extern void Brush_Resize(brush_t *b, idVec3 vMin, idVec3 vMax); + +int GetNumKeys(entity_t *ent) +{ +// int iCount = 0; +// for (epair_t* ep=ent->epairs ; ep ; ep=ep->next) +// { +// iCount++; +// } + + int iCount = ent->epairs.GetNumKeyVals(); + return iCount; +} + +const char *GetKeyString(entity_t *ent, int iIndex) +{ +// for (epair_t* ep=ent->epairs ; ep ; ep=ep->next) +// { +// if (!iIndex--) +// return ep->key; +// } +// +// assert(0); +// return NULL; + + if ( iIndex < GetNumKeys(ent) ) + { + return ent->epairs.GetKeyVal(iIndex)->GetKey().c_str(); + } + + assert(0); + return NULL; +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +const char *ValueForKey(entity_t *ent, const char *key) { + return ent->epairs.GetString(key); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void TrackMD3Angles(entity_t *e, const char *key, const char *value) { + if ( idStr::Icmp(key, "angle") != 0 ) { + return; + } + + if ((e->eclass->fixedsize && e->eclass->nShowFlags & ECLASS_MISCMODEL) || EntityHasModel(e)) { + float a = FloatForKey(e, "angle"); + float b = atof(value); + if (a != b) { + idVec3 vAngle; + vAngle[0] = vAngle[1] = 0; + vAngle[2] = -a; + Brush_Rotate(e->brushes.onext, vAngle, e->origin, true); + vAngle[2] = b; + Brush_Rotate(e->brushes.onext, vAngle, e->origin, true); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SetKeyValue(entity_t *ent, const char *key, const char *value, bool trackAngles) { + if (ent == NULL) { + return; + } + + if (!key || !key[0]) { + return; + } + + if (trackAngles) { + TrackMD3Angles(ent, key, value); + } + + ent->epairs.Set(key, value); + GetVectorForKey(ent, "origin", ent->origin); + + // update sound in case this key was relevent + Entity_UpdateSoundEmitter( ent ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SetKeyVec3(entity_t *ent, const char *key, idVec3 v) { + if (ent == NULL) { + return; + } + + if (!key || !key[0]) { + return; + } + + idStr str; + sprintf(str, "%g %g %g", v.x, v.y, v.z); + ent->epairs.Set(key, str); + GetVectorForKey(ent, "origin", ent->origin); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SetKeyMat3(entity_t *ent, const char *key, idMat3 m) { + if (ent == NULL) { + return; + } + + if (!key || !key[0]) { + return; + } + + idStr str; + + sprintf(str, "%g %g %g %g %g %g %g %g %g",m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2]); + + ent->epairs.Set(key, str); + GetVectorForKey(ent, "origin", ent->origin); +} + + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void DeleteKey(entity_t *ent, const char *key) { + ent->epairs.Delete(key); + if (stricmp(key, "rotation") == 0) { + ent->rotation.Identity(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +float FloatForKey(entity_t *ent, const char *key) { + const char *k; + + k = ValueForKey(ent, key); + if (k && *k) { + return atof(k); + } + + return 0.0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int IntForKey(entity_t *ent, const char *key) { + const char *k; + + k = ValueForKey(ent, key); + return atoi(k); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool GetVectorForKey(entity_t *ent, const char *key, idVec3 &vec) { + const char *k; + k = ValueForKey(ent, key); + if (k && strlen(k) > 0) { + sscanf(k, "%f %f %f", &vec[0], &vec[1], &vec[2]); + return true; + } + else { + vec[0] = vec[1] = vec[2] = 0; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool GetVector4ForKey(entity_t *ent, const char *key, idVec4 &vec) { + const char *k; + k = ValueForKey(ent, key); + if (k && strlen(k) > 0) { + sscanf(k, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]); + return true; + } + else { + vec[0] = vec[1] = vec[2] = vec[3] = 0; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool GetFloatForKey(entity_t *ent, const char *key, float *f) { + const char *k; + k = ValueForKey(ent, key); + if (k && strlen(k) > 0) { + *f = atof(k); + return true; + } + + *f = 0; + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat) { + const char *k; + k = ValueForKey(ent, key); + if (k && strlen(k) > 0) { + sscanf + ( + k, + "%f %f %f %f %f %f %f %f %f ", + &mat[0][0], + &mat[0][1], + &mat[0][2], + &mat[1][0], + &mat[1][1], + &mat[1][2], + &mat[2][0], + &mat[2][1], + &mat[2][2] + ); + return true; + } + else { + mat.Identity(); + } + + return false; +} + +/* + ======================================================================================================================= + Entity_FreeEpairs Frees the entity epairs. + ======================================================================================================================= + */ +void Entity_FreeEpairs(entity_t *e) { + e->epairs.Clear(); +} + +/* + ======================================================================================================================= + Entity_AddToList + ======================================================================================================================= + */ +void Entity_AddToList(entity_t *e, entity_t *list) { + if (e->next || e->prev) { + Error("Entity_AddToList: allready linked"); + } + + e->next = list->next; + list->next->prev = e; + list->next = e; + e->prev = list; +} + +/* + ======================================================================================================================= + Entity_RemoveFromList + ======================================================================================================================= + */ +void Entity_RemoveFromList(entity_t *e) { + if ( !e->next || !e->prev ) { + Error("Entity_RemoveFromList: not linked"); + } + + e->next->prev = e->prev; + e->prev->next = e->next; + e->next = e->prev = NULL; +} + +/* + ======================================================================================================================= + Entity_Free Frees the entity and any brushes is has. The entity is removed from the global entities list. + ======================================================================================================================= + */ +void Entity_Free( entity_t *e ) { + + while ( e->brushes.onext != &e->brushes ) { + Brush_Free(e->brushes.onext); + } + + if ( e->next ) { + e->next->prev = e->prev; + e->prev->next = e->next; + } + + Entity_FreeEpairs( e ); + + delete e; +} + +/* + ======================================================================================================================= + Entity_MemorySize + ======================================================================================================================= + */ + +int Entity_MemorySize( entity_t *e ) +{ + brush_t *b; + int size; + + size = sizeof( entity_t ) + e->epairs.Size(); + for( b = e->brushes.onext; b != &e->brushes; b = b->onext ) + { + size += Brush_MemorySize( b ); +} + return( size ); +} + +/* + ======================================================================================================================= + ParseEpair + ======================================================================================================================= + */ + +struct EpairFixup { + const char *name; + int type; +}; + + +const EpairFixup FloatFixups[] = { + { "origin", 1 }, + { "rotation", 2 }, + { "_color", 1 }, + { "falloff", 0 }, + { "light", 0 }, + { "light_target", 1 }, + { "light_up", 1 }, + { "light_right", 1 }, + { "light_start", 1 }, + { "light_center", 1 }, + { "light_end", 1 }, + { "light_radius", 1 }, + { "light_origin", 1 } +}; + +const int FixupCount = sizeof(FloatFixups) / sizeof(EpairFixup); + +void FixFloats(idDict *dict) { + int count = dict->GetNumKeyVals(); + for (int i = 0; i < count; i++) { + const idKeyValue *kv = dict->GetKeyVal(i); + for (int j = 0; j < FixupCount; j++) { + if (kv->GetKey().Icmp(FloatFixups[j].name) == 0) { + idStr val; + if (FloatFixups[j].type == 1) { + idVec3 v; + sscanf(kv->GetValue().c_str(), "%f %f %f", &v.x, &v.y, &v.z); + sprintf(val, "%g %g %g", v.x, v.y, v.z); + } else if (FloatFixups[j].type == 2) { + idMat3 mat; + sscanf(kv->GetValue().c_str(), "%f %f %f %f %f %f %f %f %f ",&mat[0][0],&mat[0][1],&mat[0][2],&mat[1][0],&mat[1][1],&mat[1][2],&mat[2][0],&mat[2][1],&mat[2][2]); + sprintf(val, "%g %g %g %g %g %g %g %g %g",mat[0][0],mat[0][1],mat[0][2],mat[1][0],mat[1][1],mat[1][2],mat[2][0],mat[2][1],mat[2][2]); + } else { + float f = atof(kv->GetValue().c_str()); + sprintf(val, "%g", f); + } + dict->Set(kv->GetKey(), val); + break; + } + } + } +} + +void ParseEpair(idDict *dict) { + idStr key = token; + GetToken(false); + idStr val = token; + + if (key.Length() > 0) { + dict->Set(key, val); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool EntityHasModel(entity_t *ent) { + if (ent) { + const char *model = ValueForKey(ent, "model"); + const char *name = ValueForKey(ent, "name"); + if (model && *model) { + if ( idStr::Icmp(model, name) ) { + return true; + } + } + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *Entity_New() { + entity_t *ent = new entity_t; + + ent->prev = ent->next = NULL; + ent->brushes.prev = ent->brushes.next = NULL; + ent->brushes.oprev = ent->brushes.onext = NULL; + ent->brushes.owner = NULL; + ent->undoId = 0; + ent->redoId = 0; + ent->entityId = g_entityId++; + ent->origin.Zero(); + ent->eclass = NULL; + ent->md3Class = NULL; + ent->lightOrigin.Zero(); + ent->lightRotation.Identity(); + ent->trackLightOrigin = false; + ent->rotation.Identity(); + ent->lightDef = -1; + ent->modelDef = -1; + ent->soundEmitter = NULL; + ent->curve = NULL; + return ent; +} + +void Entity_UpdateCurveData( entity_t *ent ) { + + if ( ent == NULL || ent->curve == NULL ) { + return; + } + + const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG ); + if ( kv == NULL ) { + if ( ent->curve ) { + delete ent->curve; + ent->curve = NULL; + if ( g_qeglobals.d_select_mode == sel_editpoint ) { + g_qeglobals.d_select_mode = sel_brush; + } + } + return; + } + + int c = ent->curve->GetNumValues(); + idStr str = va( "%i ( ", c ); + idVec3 v; + for ( int i = 0; i < c; i++ ) { + v = ent->curve->GetValue( i ); + str += " "; + str += v.ToString(); + str += " "; + } + str += " )"; + + ent->epairs.Set( kv->GetKey(), str ); + +} + +idCurve *Entity_MakeCurve( entity_t *ent ) { + const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG ); + if ( kv ) { + idStr str = kv->GetKey().Right( kv->GetKey().Length() - strlen( CURVE_TAG ) ); + if ( str.Icmp( "CatmullRomSpline" ) == 0 ) { + return new idCurve_CatmullRomSpline(); + } else if ( str.Icmp( "Nurbs" ) == 0 ) { + return new idCurve_NURBS(); + } + } + return NULL; +} + +void Entity_SetCurveData( entity_t *ent ) { + + ent->curve = Entity_MakeCurve( ent ); + const idKeyValue *kv = ent->epairs.MatchPrefix( CURVE_TAG ); + if ( kv && ent->curve ) { + idLexer lex; + lex.LoadMemory( kv->GetValue(), kv->GetValue().Length(), "_curve" ); + int numPoints = lex.ParseInt(); + if ( numPoints > 0 ) { + float *fp = new float[numPoints * 3]; + lex.Parse1DMatrix( numPoints * 3, fp ); + int time = 0; + for ( int i = 0; i < numPoints * 3; i += 3 ) { + idVec3 v; + v.x = fp[i]; + v.y = fp[i+1]; + v.z = fp[i+2]; + ent->curve->AddValue( time, v ); + time += 100; + } + delete []fp; + } + } + +} + +entity_t *Entity_PostParse(entity_t *ent, brush_t *pList) { + bool has_brushes; + eclass_t *e; + brush_t *b; + idVec3 mins, maxs, zero; + idBounds bo; + + zero.Zero(); + + Entity_SetCurveData( ent ); + + if (ent->brushes.onext == &ent->brushes) { + has_brushes = false; + } + else { + has_brushes = true; + } + + bool needsOrigin = !GetVectorForKey(ent, "origin", ent->origin); + const char *pModel = ValueForKey(ent, "model"); + + const char *cp = ValueForKey(ent, "classname"); + + if (strlen(cp)) { + e = Eclass_ForName(cp, has_brushes); + } else { + const char *cp2 = ValueForKey(ent, "name"); + if (strlen(cp2)) { + char buff[1024]; + strcpy(buff, cp2); + int len = strlen(buff); + while ((isdigit(buff[len-1]) || buff[len-1] == '_') && len > 0) { + buff[len-1] = '\0'; + len--; + } + e = Eclass_ForName(buff, has_brushes); + SetKeyValue(ent, "classname", buff, false); + } else { + e = Eclass_ForName("", has_brushes); + } + } + + idStr str; + + if (e->defArgs.GetString("model", "", str) && e->entityModel == NULL) { + e->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &e->defArgs ); + } + + ent->eclass = e; + + bool hasModel = EntityHasModel(ent); + + if (hasModel) { + ent->eclass->defArgs.GetString("model", "", str); + if (str.Length()) { + hasModel = false; + ent->epairs.Delete("model"); + } + } + + if (e->nShowFlags & ECLASS_WORLDSPAWN) { + ent->origin.Zero(); + needsOrigin = false; + ent->epairs.Delete( "model" ); + } else if (e->nShowFlags & ECLASS_LIGHT) { + if (GetVectorForKey(ent, "light_origin", ent->lightOrigin)) { + GetMatrixForKey(ent, "light_rotation", ent->lightRotation); + ent->trackLightOrigin = true; + } else if (hasModel) { + SetKeyValue(ent, "light_origin", ValueForKey(ent, "origin")); + ent->lightOrigin = ent->origin; + if (GetMatrixForKey(ent, "rotation", ent->lightRotation)) { + SetKeyValue(ent, "light_rotation", ValueForKey(ent, "rotation")); + } + ent->trackLightOrigin = true; + } + } else if ( e->nShowFlags & ECLASS_ENV ) { + // need to create an origin from the bones here + idVec3 org; + idAngles ang; + bo.Clear(); + bool hasBody = false; + const idKeyValue *arg = ent->epairs.MatchPrefix( "body ", NULL ); + while ( arg ) { + sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll ); + bo.AddPoint( org ); + arg = ent->epairs.MatchPrefix( "body ", arg ); + hasBody = true; + } + if (hasBody) { + ent->origin = bo.GetCenter(); + } + } + + if (e->fixedsize || hasModel) { // fixed size entity + if (ent->brushes.onext != &ent->brushes) { + for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { + b->entityModel = true; + } + } + + if (hasModel) { + // model entity + idRenderModel *modelHandle = renderModelManager->FindModel( pModel ); + + if ( dynamic_cast( modelHandle ) || dynamic_cast( modelHandle ) ) { + bo.Zero(); + bo.ExpandSelf( 12.0f ); + } else { + bo = modelHandle->Bounds( NULL ); + } + + VectorCopy(bo[0], mins); + VectorCopy(bo[1], maxs); + for (int i = 0; i < 3; i++) { + if (mins[i] == maxs[i]) { + mins[i]--; + maxs[i]++; + } + } + VectorAdd(mins, ent->origin, mins); + VectorAdd(maxs, ent->origin, maxs); + b = Brush_Create(mins, maxs, &e->texdef); + b->modelHandle = modelHandle; + + float yaw = 0; + bool convertAngles = GetFloatForKey(ent, "angle", &yaw); + extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild); + extern void Brush_Rotate(brush_t *b, idVec3 rot, idVec3 origin, bool bBuild); + + if (convertAngles) { + idVec3 rot(0, 0, yaw); + Brush_Rotate(b, rot, ent->origin, false); + } + + if (GetMatrixForKey(ent, "rotation", ent->rotation)) { + idBounds bo2; + bo2.FromTransformedBounds(bo, ent->origin, ent->rotation); + b->owner = ent; + Brush_Resize(b, bo2[0], bo2[1]); + } + Entity_LinkBrush(ent, b); + } + + if (!hasModel || (ent->eclass->nShowFlags & ECLASS_LIGHT && hasModel)) { + // create a custom brush + if (ent->trackLightOrigin) { + mins = e->mins + ent->lightOrigin; + maxs = e->maxs + ent->lightOrigin; + } else { + mins = e->mins + ent->origin; + maxs = e->maxs + ent->origin; + } + + b = Brush_Create(mins, maxs, &e->texdef); + GetMatrixForKey(ent, "rotation", ent->rotation); + Entity_LinkBrush(ent, b); + b->trackLightOrigin = ent->trackLightOrigin; + if ( e->texdef.name == NULL ) { + brushprimit_texdef_t bp; + texdef_t td; + td.SetName( ent->eclass->defMaterial ); + Brush_SetTexture( b, &td, &bp, false ); + } + } + } else { // brush entity + if (ent->brushes.next == &ent->brushes) { + printf("Warning: Brush entity with no brushes\n"); + } + + if (!needsOrigin) { + idStr cn = ValueForKey(ent, "classname"); + idStr name = ValueForKey(ent, "name"); + idStr model = ValueForKey(ent, "model"); + if (cn.Icmp("func_static") == 0) { + if (name.Icmp(model) == 0) { + needsOrigin = true; + } + } + } + + if (needsOrigin) { + idVec3 mins, maxs, mid; + int i; + char text[32]; + mins[0] = mins[1] = mins[2] = 999999; + maxs[0] = maxs[1] = maxs[2] = -999999; + + // add in the origin + for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { + Brush_Build(b, true, false, false); + for (i = 0; i < 3; i++) { + if (b->mins[i] < mins[i]) { + mins[i] = b->mins[i]; + } + + if (b->maxs[i] > maxs[i]) { + maxs[i] = b->maxs[i]; + } + } + } + + for (i = 0; i < 3; i++) { + ent->origin[i] = (mins[i] + ((maxs[i] - mins[i]) / 2)); + } + + sprintf(text, "%i %i %i", (int)ent->origin[0], (int)ent->origin[1], (int)ent->origin[2]); + SetKeyValue(ent, "origin", text); + } + + if (!(e->nShowFlags & ECLASS_WORLDSPAWN)) { + if (e->defArgs.FindKey("model") == NULL && (pModel == NULL || (pModel && strlen(pModel) == 0))) { + SetKeyValue(ent, "model", ValueForKey(ent, "name")); + } + } + else { + DeleteKey(ent, "origin"); + } + } + + // add all the brushes to the main list + if (pList) { + for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { + b->next = pList->next; + pList->next->prev = b; + b->prev = pList; + pList->next = b; + } + } + + FixFloats(&ent->epairs); + + return ent; + +} + +/* + ======================================================================================================================= + Entity_Parse If onlypairs is set, the classname info will not be looked up, and the entity will not be added to the + global list. Used for parsing the project. + ======================================================================================================================= + */ +entity_t *Entity_Parse(bool onlypairs, brush_t *pList) { + entity_t *ent; + + if (!GetToken(true)) { + return NULL; + } + + if (strcmp(token, "{")) { + Error("ParseEntity: { not found"); + } + + ent = Entity_New(); + ent->brushes.onext = ent->brushes.oprev = &ent->brushes; + ent->origin.Zero(); + + int n = 0; + do { + if (!GetToken(true)) { + Warning("ParseEntity: EOF without closing brace"); + return NULL; + } + + if (!strcmp(token, "}")) { + break; + } + + if (!strcmp(token, "{")) { + GetVectorForKey(ent, "origin", ent->origin); + brush_t *b = Brush_Parse(ent->origin); + if (b != NULL) { + b->owner = ent; + + // add to the end of the entity chain + b->onext = &ent->brushes; + b->oprev = ent->brushes.oprev; + ent->brushes.oprev->onext = b; + ent->brushes.oprev = b; + } + else { + break; + } + } + else { + ParseEpair(&ent->epairs); + } + } while (1); + + if (onlypairs) { + return ent; + } + + return Entity_PostParse(ent, pList); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void VectorMidpoint(idVec3 va, idVec3 vb, idVec3 &out) { + for (int i = 0; i < 3; i++) { + out[i] = va[i] + ((vb[i] - va[i]) / 2); + } +} + +/* + ======================================================================================================================= + Entity_Write + ======================================================================================================================= + */ +void Entity_Write(entity_t *e, FILE *f, bool use_region) { + brush_t *b; + idVec3 origin; + char text[128]; + int count; + + // if none of the entities brushes are in the region, don't write the entity at all + if (use_region) { + // in region mode, save the camera position as playerstart + if (!strcmp(ValueForKey(e, "classname"), "info_player_start")) { + fprintf(f, "{\n"); + fprintf(f, "\"classname\" \"info_player_start\"\n"); + fprintf + ( + f, + "\"origin\" \"%i %i %i\"\n", + (int)g_pParentWnd->GetCamera()->Camera().origin[0], + (int)g_pParentWnd->GetCamera()->Camera().origin[1], + (int)g_pParentWnd->GetCamera()->Camera().origin[2] + ); + fprintf(f, "\"angle\" \"%i\"\n", (int)g_pParentWnd->GetCamera()->Camera().angles[YAW]); + fprintf(f, "}\n"); + return; + } + + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (!Map_IsBrushFiltered(b)) { + break; // got one + } + } + + if (b == &e->brushes) { + return; // nothing visible + } + } + + if (e->eclass->nShowFlags & ECLASS_PLUGINENTITY) { + // NOTE: the whole brush placement / origin stuff is a mess + VectorCopy(e->origin, origin); + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + } + + // if fixedsize, calculate a new origin based on the current brush position + else if (e->eclass->fixedsize || EntityHasModel(e)) { + if (!GetVectorForKey(e, "origin", origin)) { + VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + } + } + + fprintf(f, "{\n"); + + count = e->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + fprintf(f, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str()); + } + + if (!EntityHasModel(e)) { + count = 0; + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (e->eclass->fixedsize && !b->entityModel) { + continue; + } + if (!use_region || !Map_IsBrushFiltered(b)) { + fprintf(f, "// brush %i\n", count); + count++; + Brush_Write( b, f, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) ); + } + } + } + + fprintf(f, "}\n"); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool IsBrushSelected(brush_t *bSel) { + for (brush_t * b = selected_brushes.next; b != NULL && b != &selected_brushes; b = b->next) { + if (b == bSel) { + return true; + } + } + + return false; +} + +// +// ======================================================================================================================= +// Entity_WriteSelected +// ======================================================================================================================= +// +void Entity_WriteSelected(entity_t *e, FILE *f) { + brush_t *b; + idVec3 origin; + char text[128]; + int count; + + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (IsBrushSelected(b)) { + break; // got one + } + } + + if (b == &e->brushes) { + return; // nothing selected + } + + // if fixedsize, calculate a new origin based on the current brush position + if (e->eclass->fixedsize || EntityHasModel(e)) { + if (!GetVectorForKey(e, "origin", origin)) { + VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + } + } + + fprintf(f, "{\n"); + + count = e->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + fprintf(f, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str()); + } + + if (!EntityHasModel(e)) { + count = 0; + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (e->eclass->fixedsize && !b->entityModel) { + continue; + } + if (IsBrushSelected(b)) { + fprintf(f, "// brush %i\n", count); + count++; + Brush_Write( b, f, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) ); + } + } + } + + fprintf(f, "}\n"); +} + +// +// ======================================================================================================================= +// Entity_WriteSelected to a CMemFile +// ======================================================================================================================= +// +void Entity_WriteSelected(entity_t *e, CMemFile *pMemFile) { + brush_t *b; + idVec3 origin; + char text[128]; + int count; + + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (IsBrushSelected(b)) { + break; // got one + } + } + + if (b == &e->brushes) { + return; // nothing selected + } + + // if fixedsize, calculate a new origin based on the current brush position + if (e->eclass->fixedsize || EntityHasModel(e)) { + if (!GetVectorForKey(e, "origin", origin)) { + VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + } + } + + MemFile_fprintf(pMemFile, "{\n"); + + count = e->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + MemFile_fprintf(pMemFile, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str()); + } + + if (!EntityHasModel(e)) { + count = 0; + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (e->eclass->fixedsize && !b->entityModel) { + continue; + } + if (IsBrushSelected(b)) { + MemFile_fprintf(pMemFile, "// brush %i\n", count); + count++; + Brush_Write( b, pMemFile, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) ); + } + } + } + + MemFile_fprintf(pMemFile, "}\n"); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Entity_SetName(entity_t *e, const char *name) { + CString oldName = ValueForKey(e, "name"); + CString oldModel = ValueForKey(e, "model"); + SetKeyValue(e, "name", name); + if (oldName == oldModel) { + SetKeyValue(e, "model", name); + } +} + +extern bool Entity_NameIsUnique(const char *name); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Entity_Name(entity_t *e, bool force) { + const char *name = ValueForKey(e, "name"); + + if (!force && name && name[0]) { + return; + } + + if (name && name[0] && Entity_NameIsUnique(name)) { + return; + } + + bool setModel = false; + if (name[0]) { + const char *model = ValueForKey(e, "model"); + if (model[0]) { + if ( idStr::Icmp(model, name) == 0 ) { + setModel = true; + } + } + } + + const char *eclass = ValueForKey(e, "classname"); + if (eclass && eclass[0]) { + idStr str = cvarSystem->GetCVarString( "radiant_nameprefix" ); + int id = Map_GetUniqueEntityID(str, eclass); + if (str.Length()) { + SetKeyValue(e, "name", va("%s_%s_%i", str.c_str(), eclass, id)); + } else { + SetKeyValue(e, "name", va("%s_%i", eclass, id)); + } + if (setModel) { + if (str.Length()) { + SetKeyValue(e, "model", va("%s_%s_%i", str.c_str(), eclass, id)); + } else { + SetKeyValue(e, "model", va("%s_%i", eclass, id)); + } + } + } +} + +/* + ======================================================================================================================= + Entity_Create Creates a new entity out of the selected_brushes list. If the entity class is fixed size, the brushes + are only used to find a midpoint. Otherwise, the brushes have their ownership transfered to the new entity. + ======================================================================================================================= + */ +entity_t *Entity_Create(eclass_t *c, bool forceFixed) { + entity_t *e; + brush_t *b; + idVec3 mins, maxs, origin; + char text[32]; + texdef_t td; + brushprimit_texdef_t bp; + + // check to make sure the brushes are ok + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->owner != world_entity) { + Sys_Status("Entity NOT created, brushes not all from world\n"); + Sys_Beep(); + return NULL; + } + } + + idStr str; + if (c->defArgs.GetString("model", "", str) && c->entityModel == NULL) { + c->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &c->defArgs ); + } + + // create it + e = Entity_New(); + e->brushes.onext = e->brushes.oprev = &e->brushes; + e->eclass = c; + e->epairs.Copy(c->args); + SetKeyValue(e, "classname", c->name); + Entity_Name(e, false); + + // add the entity to the entity list + Entity_AddToList(e, &entities); + + if (c->fixedsize) { + // + // just use the selection for positioning b = selected_brushes.next; for (i=0 ; + // i<3 ; i++) { e->origin[i] = b->mins[i] - c->mins[i]; } + // + Select_GetMid(e->origin); + VectorCopy(e->origin, origin); + + // create a custom brush + VectorAdd(c->mins, e->origin, mins); + VectorAdd(c->maxs, e->origin, maxs); + + b = Brush_Create(mins, maxs, &c->texdef); + + Entity_LinkBrush(e, b); + + if (c->defMaterial.Length()) { + td.SetName(c->defMaterial); + Brush_SetTexture(b, &td, &bp, false); + } + + + // delete the current selection + Select_Delete(); + + // select the new brush + b->next = b->prev = &selected_brushes; + selected_brushes.next = selected_brushes.prev = b; + + Brush_Build(b); + } + else { + + Select_GetMid(origin); + + // change the selected brushes over to the new entity + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + Entity_UnlinkBrush(b); + Entity_LinkBrush(e, b); + Brush_Build(b); // so the key brush gets a name + if (c->defMaterial.Length()) { + td.SetName(c->defMaterial); + Brush_SetTexture(b, &td, &bp, false); + } + + } + + //for (int i = 0; i < 3; i++) { + // origin[i] = vMin[i] + vMax[i] * 0.5; + //} + + if (!forceFixed) { + SetKeyValue(e, "model", ValueForKey(e, "name")); + } + } + + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + VectorCopy(origin, e->origin); + + Sys_UpdateWindows(W_ALL); + return e; +} + +void Brush_MakeDirty(brush_t *b) { + for (face_t *f = b->brush_faces; f; f = f->next) { + f->dirty = true; + } +} +/* + ======================================================================================================================= + Entity_LinkBrush + ======================================================================================================================= + */ +void Entity_LinkBrush(entity_t *e, brush_t *b) { + if (b->oprev || b->onext) { + Error("Entity_LinkBrush: Allready linked"); + } + + Brush_MakeDirty(b); + + b->owner = e; + + b->onext = e->brushes.onext; + b->oprev = &e->brushes; + e->brushes.onext->oprev = b; + e->brushes.onext = b; +} + +/* + ======================================================================================================================= + Entity_UnlinkBrush + ======================================================================================================================= + */ +void Entity_UnlinkBrush(brush_t *b) { + // if (!b->owner || !b->onext || !b->oprev) + if (!b->onext || !b->oprev) { + Error("Entity_UnlinkBrush: Not currently linked"); + } + + b->onext->oprev = b->oprev; + b->oprev->onext = b->onext; + b->onext = b->oprev = NULL; + b->owner = NULL; +} + +/* + ======================================================================================================================= + Entity_Clone + ======================================================================================================================= + */ +entity_t *Entity_Clone(entity_t *e) { + entity_t *n; + + n = Entity_New(); + n->brushes.onext = n->brushes.oprev = &n->brushes; + n->eclass = e->eclass; + n->rotation = e->rotation; + n->origin = e->origin; + + // add the entity to the entity list + Entity_AddToList(n, &entities); + + n->epairs = e->epairs; + + return n; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int GetUniqueTargetId(int iHint) { + int iMin, iMax, i; + BOOL fFound; + entity_t *pe; + + fFound = FALSE; + pe = entities.next; + iMin = 0; + iMax = 0; + + for (; pe != NULL && pe != &entities; pe = pe->next) { + i = IntForKey(pe, "target"); + if (i) { + iMin = Min(i, iMin); + iMax = Max(i, iMax); + if (i == iHint) { + fFound = TRUE; + } + } + } + + if (fFound) { + return iMax + 1; + } + else { + return iHint; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *FindEntity(const char *pszKey, const char *pszValue) { + entity_t *pe; + + pe = entities.next; + + for (; pe != NULL && pe != &entities; pe = pe->next) { + if (!strcmp(ValueForKey(pe, pszKey), pszValue)) { + return pe; + } + } + + return NULL; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *FindEntityInt(const char *pszKey, int iValue) { + entity_t *pe; + + pe = entities.next; + + for (; pe != NULL && pe != &entities; pe = pe->next) { + if (IntForKey(pe, pszKey) == iValue) { + return pe; + } + } + + return NULL; +} + +/* +==================== +Entity_UpdateSoundEmitter + +Deletes the soundEmitter if the entity should not emit a sound due +to it not having one, being filtered away, or the sound mode being turned off. + +Creates or updates the soundEmitter if needed +==================== +*/ +void Entity_UpdateSoundEmitter( entity_t *ent ) { + bool playing = false; + + // if an entity doesn't have any brushes at all, don't do anything + // if the brush isn't displayed (filtered or culled), don't do anything + if ( g_pParentWnd->GetCamera()->GetSoundMode() + && ent->brushes.onext != &ent->brushes && !FilterBrush(ent->brushes.onext) ) { + // check for sounds + const char *v = ValueForKey( ent, "s_shader" ); + if ( v[0] ) { + refSound_t sound; + + gameEdit->ParseSpawnArgsToRefSound( &ent->epairs, &sound ); + if ( !sound.waitfortrigger ) { // waitfortrigger will not start playing immediately + if ( !ent->soundEmitter ) { + ent->soundEmitter = g_qeglobals.sw->AllocSoundEmitter(); + } + playing = true; + ent->soundEmitter->UpdateEmitter( ent->origin, 0, &sound.parms ); + // always play on a single channel, so updates always override + ent->soundEmitter->StartSound( sound.shader, SCHANNEL_ONE ); + } + } + } + + // delete the soundEmitter if not used + if ( !playing && ent->soundEmitter ) { + ent->soundEmitter->Free( true ); + ent->soundEmitter = NULL; + } + +} + diff --git a/tools/radiant/EditorEntity.h b/tools/radiant/EditorEntity.h new file mode 100644 index 000000000..61a1b62db --- /dev/null +++ b/tools/radiant/EditorEntity.h @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +void Eclass_InitForSourceDirectory( const char *path ); +eclass_t * Eclass_ForName( const char *name, bool has_brushes ); +bool Eclass_hasModel(eclass_t *e, idVec3 &vMin, idVec3 &vMax); + +typedef struct entity_s { + struct entity_s *prev, *next; + brush_t brushes; // head/tail of list + int undoId, redoId, entityId; // used for undo/redo + idVec3 origin; + qhandle_t lightDef; + qhandle_t modelDef; + idSoundEmitter *soundEmitter; + eclass_t * eclass; + idDict epairs; + eclass_t * md3Class; + idMat3 rotation; + idVec3 lightOrigin; // for lights that have been combined with models + idMat3 lightRotation; // '' + bool trackLightOrigin; + idCurve *curve; +} entity_t; + +void ParseEpair(idDict *dict); +const char *ValueForKey(entity_t *ent, const char *key); +int GetNumKeys(entity_t *ent); +const char *GetKeyString(entity_t *ent, int iIndex); +void SetKeyValue (entity_t *ent, const char *key, const char *value, bool trackAngles = true); +void DeleteKey (entity_t *ent, const char *key); +float FloatForKey (entity_t *ent, const char *key); +int IntForKey (entity_t *ent, const char *key); +bool GetVectorForKey (entity_t *ent, const char *key, idVec3 &vec); +bool GetVector4ForKey (entity_t *ent, const char *key, idVec4 &vec); +bool GetFloatForKey(entity_t *end, const char *key, float *f); +void SetKeyVec3(entity_t *ent, const char *key, idVec3 v); +void SetKeyMat3(entity_t *ent, const char *key, idMat3 m); +bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat); + +void Entity_UpdateSoundEmitter( entity_t *ent ); +idCurve *Entity_MakeCurve( entity_t *e ); +void Entity_UpdateCurveData( entity_t *e ); +void Entity_SetCurveData( entity_t *e ); +void Entity_Free (entity_t *e); +void Entity_FreeEpairs(entity_t *e); +int Entity_MemorySize(entity_t *e); +entity_t * Entity_Parse (bool onlypairs, brush_t* pList = NULL); +void Entity_Write (entity_t *e, FILE *f, bool use_region); +void Entity_WriteSelected(entity_t *e, FILE *f); +void Entity_WriteSelected(entity_t *e, CMemFile*); +entity_t * Entity_Create (eclass_t *c, bool forceFixed = false); +entity_t * Entity_Clone (entity_t *e); +void Entity_AddToList(entity_t *e, entity_t *list); +void Entity_RemoveFromList(entity_t *e); +bool EntityHasModel(entity_t *ent); + +void Entity_LinkBrush (entity_t *e, brush_t *b); +void Entity_UnlinkBrush (brush_t *b); +entity_t * FindEntity(const char *pszKey, const char *pszValue); +entity_t * FindEntityInt(const char *pszKey, int iValue); +entity_t * Entity_New(); +void Entity_SetName(entity_t *e, const char *name); + +int GetUniqueTargetId(int iHint); +eclass_t * GetCachedModel(entity_t *pEntity, const char *pName, idVec3 &vMin, idVec3 &vMax); + +//Timo : used for parsing epairs in brush primitive +void Entity_Name(entity_t *e, bool force); + +bool IsBrushSelected(brush_t* bSel); diff --git a/tools/radiant/EditorMap.cpp b/tools/radiant/EditorMap.cpp new file mode 100644 index 000000000..e93aa7906 --- /dev/null +++ b/tools/radiant/EditorMap.cpp @@ -0,0 +1,1615 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +int mapModified; // for quit confirmation (0 = clean, 1 = unsaved, + +// 2 = autosaved, but not regular saved) +char currentmap[1024]; + +brush_t active_brushes; // brushes currently being displayed +brush_t selected_brushes; // highlighted + +face_t *selected_face; +brush_t *selected_face_brush; + +brush_t filtered_brushes; // brushes that have been filtered or regioned + +entity_t entities; // head/tail of doubly linked list + +entity_t *world_entity = NULL; // "classname" "worldspawn" ! + +void AddRegionBrushes(void); +void RemoveRegionBrushes(void); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void DupLists() { + DWORD dw = GetTickCount(); +} + +/* + * Cross map selection saving this could mess this up if you have only part of a + * complex entity selected... + */ +brush_t between_brushes; +entity_t between_entities; + +bool g_bRestoreBetween = false; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Map_SaveBetween(void) { + if (g_pParentWnd->ActiveXY()) { + g_bRestoreBetween = true; + g_pParentWnd->ActiveXY()->Copy(); + } + + return; + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Map_RestoreBetween(void) { + if (g_pParentWnd->ActiveXY() && g_bRestoreBetween) { + g_pParentWnd->ActiveXY()->Paste(); + } + + return; + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CheckForTinyBrush(brush_t *b, int n, float fSize) { + bool bTiny = false; + for (int i = 0; i < 3; i++) { + if (b->maxs[i] - b->mins[i] < fSize) { + bTiny = true; + } + } + + if (bTiny) { + common->Printf("Possible problem brush (too small) #%i ", n); + } + + return bTiny; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Map_BuildBrushData(void) { + brush_t *b, *next; + + if (active_brushes.next == NULL) { + return; + } + + Sys_BeginWait(); // this could take a while + + int n = 0; + for (b = active_brushes.next; b != NULL && b != &active_brushes; b = next) { + next = b->next; + Brush_Build(b, true, false, false); + if (!b->brush_faces || (g_PrefsDlg.m_bCleanTiny && CheckForTinyBrush(b, n++, g_PrefsDlg.m_fTinySize))) { + Brush_Free(b); + common->Printf("Removed degenerate brush\n"); + } + } + + Sys_EndWait(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *Map_FindClass(char *cname) { + entity_t *ent; + + for (ent = entities.next; ent != &entities; ent = ent->next) { + if (!strcmp(cname, ValueForKey(ent, "classname"))) { + return ent; + } + } + + return NULL; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int Map_GetUniqueEntityID(const char *prefix, const char *eclass) { + entity_t *ent; + int id = 0; + for (ent = entities.next; ent != &entities; ent = ent->next) { + if (!strcmp(eclass, ValueForKey(ent, "classname"))) { + const char *name = ValueForKey(ent, "name"); + if (name && name[0]) { + const char *buf; + if (prefix && *prefix) { + buf = va("%s_%s_", prefix, eclass); + } else { + buf = va("%s_", eclass); + } + int len = strlen(buf); + if ( idStr::Cmpn(name, buf, len) == 0 ) { + int j = atoi(name + len); + if (j > id) { + id = j; + } + } + } + } + } + + return id + 1; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool Entity_NameIsUnique(const char *name) { + entity_t *ent; + if (name == NULL) { + return false; + } + + for (ent = entities.next; ent != &entities; ent = ent->next) { + const char *testName = ValueForKey(ent, "name"); + if (testName) { + if ( idStr::Icmp(name, testName) == 0 ) { + return false; + } + } + } + + return true; +} + +/* + ======================================================================================================================= + Map_Free + ======================================================================================================================= + */ +void Map_Free(void) { + g_bRestoreBetween = false; + if (selected_brushes.next && (selected_brushes.next != &selected_brushes)) { + if (g_pParentWnd->MessageBox("Copy selection?", "", MB_YESNO) == IDYES) { + Map_SaveBetween(); + } + } + + // clear all the render and sound system data + g_qeglobals.rw->InitFromMap( NULL ); + g_qeglobals.sw->ClearAllSoundEmitters(); + + Texture_ClearInuse(); + Pointfile_Clear(); + strcpy(currentmap, "unnamed.map"); + Sys_SetTitle(currentmap); + g_qeglobals.d_num_entities = 0; + + if (!active_brushes.next) { // first map + active_brushes.prev = active_brushes.next = &active_brushes; + selected_brushes.prev = selected_brushes.next = &selected_brushes; + filtered_brushes.prev = filtered_brushes.next = &filtered_brushes; + + entities.prev = entities.next = &entities; + } + else { + while (active_brushes.next != &active_brushes) { + Brush_Free(active_brushes.next, false); + } + + while (selected_brushes.next != &selected_brushes) { + Brush_Free(selected_brushes.next, false); + } + + while (filtered_brushes.next != &filtered_brushes) { + Brush_Free(filtered_brushes.next, false); + } + + while (entities.next != &entities) { + Entity_Free(entities.next); + } + } + + if (world_entity) { + Entity_Free(world_entity); + } + + world_entity = NULL; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *AngledEntity() { + entity_t *ent = Map_FindClass("info_player_start"); + if (!ent) { + ent = Map_FindClass("info_player_deathmatch"); + } + + if (!ent) { + ent = Map_FindClass("info_player_deathmatch"); + } + + if (!ent) { + ent = Map_FindClass("team_CTF_redplayer"); + } + + if (!ent) { + ent = Map_FindClass("team_CTF_blueplayer"); + } + + if (!ent) { + ent = Map_FindClass("team_CTF_redspawn"); + } + + if (!ent) { + ent = Map_FindClass("team_CTF_bluespawn"); + } + + return ent; +} + + +brush_t *BrushFromMapPatch(idMapPatch *mappatch, idVec3 origin) { + patchMesh_t *pm = MakeNewPatch(mappatch->GetWidth(), mappatch->GetHeight()); + pm->d_texture = Texture_ForName(mappatch->GetMaterial()); + for (int i = 0; i < mappatch->GetWidth(); i++) { + for (int j = 0; j < mappatch->GetHeight(); j++) { + pm->ctrl(i, j).xyz = (*mappatch)[j * mappatch->GetWidth() + i].xyz + origin; + pm->ctrl(i, j).st = (*mappatch)[j * mappatch->GetWidth() + i].st; + } + } + pm->horzSubdivisions = mappatch->GetHorzSubdivisions(); + pm->vertSubdivisions = mappatch->GetVertSubdivisions(); + pm->explicitSubdivisions = mappatch->GetExplicitlySubdivided(); + if (mappatch->epairs.GetNumKeyVals()) { + pm->epairs = new idDict; + *pm->epairs = mappatch->epairs; + } + brush_t *b = AddBrushForPatch(pm, false); + return b; +} + +brush_t *BrushFromMapBrush(idMapBrush *mapbrush, idVec3 origin) { + brush_t *b = NULL; + if (mapbrush) { + b = Brush_Alloc(); + int count = mapbrush->GetNumSides(); + for (int i = 0; i < count; i++) { + idMapBrushSide *side = mapbrush->GetSide(i); + face_t *f = Face_Alloc(); + f->next = NULL; + if (!b->brush_faces) { + b->brush_faces = f; + } + else { + face_t *scan; + for (scan = b->brush_faces; scan->next; scan = scan->next) { + ; + } + scan->next = f; + } + f->plane = side->GetPlane(); + f->originalPlane = f->plane; + f->dirty = false; + + idWinding w; + w.BaseForPlane(f->plane); + + for (int j = 0; j < 3; j++) { + f->planepts[j].x = w[j].x + origin.x; + f->planepts[j].y = w[j].y + origin.y; + f->planepts[j].z = w[j].z + origin.z; + } + + idVec3 mat[2]; + side->GetTextureMatrix(mat[0], mat[1]); + f->brushprimit_texdef.coords[0][0] = mat[0][0]; + f->brushprimit_texdef.coords[0][1] = mat[0][1]; + f->brushprimit_texdef.coords[0][2] = mat[0][2]; + f->brushprimit_texdef.coords[1][0] = mat[1][0]; + f->brushprimit_texdef.coords[1][1] = mat[1][1]; + f->brushprimit_texdef.coords[1][2] = mat[1][2]; + + f->texdef.SetName(side->GetMaterial()); + } + } + return b; +} + +entity_t *EntityFromMapEntity(idMapEntity *mapent, CWaitDlg *dlg) { + entity_t *ent = NULL; + if (mapent) { + ent = Entity_New(); + ent->brushes.onext = ent->brushes.oprev = &ent->brushes; + ent->origin.Zero(); + ent->epairs = mapent->epairs; + GetVectorForKey(ent, "origin", ent->origin); + int count = mapent->GetNumPrimitives(); + long lastUpdate = 0; + idStr status; + for (int i = 0; i < count; i++) { + idMapPrimitive *prim = mapent->GetPrimitive(i); + if (prim) { + // update 20 times a second + if ( (GetTickCount() - lastUpdate) > 50 ) { + lastUpdate = GetTickCount(); + if (prim->GetType() == idMapPrimitive::TYPE_BRUSH) { + sprintf(status, "Reading primitive %i (brush)", i); + } else if (prim->GetType() == idMapPrimitive::TYPE_PATCH) { + sprintf(status, "Reading primitive %i (patch)", i); + } + dlg->SetText(status, true); + } + if ( dlg->CancelPressed() ) { + return ent; + } + + brush_t *b = NULL; + if (prim->GetType() == idMapPrimitive::TYPE_BRUSH) { + idMapBrush *mapbrush = reinterpret_cast(prim); + b = BrushFromMapBrush(mapbrush, ent->origin); + } else if (prim->GetType() == idMapPrimitive::TYPE_PATCH) { + idMapPatch *mappatch = reinterpret_cast(prim); + b = BrushFromMapPatch(mappatch, ent->origin); + } + if (b) { + b->owner = ent; + // add to the end of the entity chain + b->onext = &ent->brushes; + b->oprev = ent->brushes.oprev; + ent->brushes.oprev->onext = b; + ent->brushes.oprev = b; + } + } + } + } + return ent; +} + +extern entity_t *Entity_PostParse(entity_t *ent, brush_t *pList); + /* + ======================================================================================================================= + Map_LoadFile + ======================================================================================================================= + */ +void Map_LoadFile(const char *filename) { + entity_t *ent; + CWaitDlg dlg; + idStr fileStr, status; + idMapFile mapfile; + + Sys_BeginWait(); + Select_Deselect(); + + dlg.AllowCancel( true ); + idStr( filename ).ExtractFileName( fileStr ); + sprintf( status, "Loading %s...", fileStr.c_str() ); + dlg.SetWindowText( status ); + sprintf( status, "Reading file %s...", fileStr.c_str() ); + dlg.SetText( status ); + + // SetInspectorMode(W_CONSOLE); + fileStr = filename; + fileStr.BackSlashesToSlashes(); + + common->Printf( "Map_LoadFile: %s\n", fileStr.c_str() ); + + Map_Free(); + + g_qeglobals.d_parsed_brushes = 0; + strcpy( currentmap, filename ); + + if(mapfile.Parse(filename, true, true)) { + g_qeglobals.bNeedConvert = false; + g_qeglobals.bOldBrushes = false; + g_qeglobals.bPrimitBrushes = false; + g_qeglobals.mapVersion = 1.0; + + long lastUpdate = 0; + int count = mapfile.GetNumEntities(); + for (int i = 0; i < count; i++) { + idMapEntity *mapent = mapfile.GetEntity(i); + if (mapent) { + idStr classname = mapent->epairs.GetString("classname"); + // Update 20 times a second + if ( (GetTickCount() - lastUpdate) > 50 ) { + lastUpdate = GetTickCount(); + sprintf(status, "Loading entity %i (%s)...", i, classname.c_str()); + dlg.SetText(status); + } + if ( dlg.CancelPressed() ) { + Sys_Status("Map load cancelled.\n"); + Map_New(); + return; + } + if (classname == "worldspawn") { + world_entity = EntityFromMapEntity(mapent, &dlg); + Entity_PostParse(world_entity, &active_brushes); + } else { + ent = EntityFromMapEntity(mapent, &dlg); + Entity_PostParse(ent, &active_brushes); + Entity_Name(ent, true); + // add the entity to the end of the entity list + ent->next = &entities; + ent->prev = entities.prev; + entities.prev->next = ent; + entities.prev = ent; + g_qeglobals.d_num_entities++; + } + } + } + } + + if (!world_entity) { + Sys_Status("No worldspawn in map.\n"); + Map_New(); + return; + } + + common->Printf("--- LoadMapFile ---\n"); + common->Printf("%s\n", fileStr.c_str()); + + common->Printf("%5i brushes\n", g_qeglobals.d_parsed_brushes); + common->Printf("%5i entities\n", g_qeglobals.d_num_entities); + + dlg.SetText("Restoring Between"); + Map_RestoreBetween(); + + dlg.SetText("Building Brush Data"); + common->Printf("Map_BuildAllDisplayLists\n"); + Map_BuildBrushData(); + + // + // reset the "need conversion" flag conversion to the good format done in + // Map_BuildBrushData + // + g_qeglobals.bNeedConvert = false; + + // move the view to a start position + ent = AngledEntity(); + + g_pParentWnd->GetCamera()->Camera().angles[PITCH] = 0; + + if (ent) { + GetVectorForKey(ent, "origin", g_pParentWnd->GetCamera()->Camera().origin); + GetVectorForKey(ent, "origin", g_pParentWnd->GetXYWnd()->GetOrigin()); + g_pParentWnd->GetCamera()->Camera().angles[YAW] = FloatForKey(ent, "angle"); + } + else { + g_pParentWnd->GetCamera()->Camera().angles[YAW] = 0; + VectorCopy(vec3_origin, g_pParentWnd->GetCamera()->Camera().origin); + VectorCopy(vec3_origin, g_pParentWnd->GetXYWnd()->GetOrigin()); + } + + Map_RegionOff(); + + mapModified = 0; + + if (GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY) { + fileStr += " (read only) "; + } + Sys_SetTitle(fileStr); + + Texture_ShowInuse(); + + if (g_pParentWnd->GetCamera()->GetRenderMode()) { + g_pParentWnd->GetCamera()->BuildRendererState(); + } + + Sys_EndWait(); + Sys_UpdateWindows(W_ALL); +} + + +void Map_VerifyCurrentMap(const char *map) { + if ( idStr::Icmp( map, currentmap ) != 0 ) { + Map_LoadFile( map ); + } +} + +idMapPrimitive *BrushToMapPrimitive( const brush_t *b, const idVec3 &origin ) { + if ( b->pPatch ) { + idMapPatch *patch = new idMapPatch( b->pPatch->width * 6, b->pPatch->height * 6 ); + patch->SetSize( b->pPatch->width, b->pPatch->height ); + for ( int i = 0; i < b->pPatch->width; i++ ) { + for ( int j = 0; j < b->pPatch->height; j++ ) { + (*patch)[j*patch->GetWidth()+i].xyz = b->pPatch->ctrl(i, j).xyz - origin; + (*patch)[j*patch->GetWidth()+i].st = b->pPatch->ctrl(i, j).st; + } + } + patch->SetExplicitlySubdivided( b->pPatch->explicitSubdivisions ); + if ( b->pPatch->explicitSubdivisions ) { + patch->SetHorzSubdivisions( b->pPatch->horzSubdivisions ); + patch->SetVertSubdivisions( b->pPatch->vertSubdivisions ); + } + patch->SetMaterial( b->pPatch->d_texture->GetName() ); + if ( b->pPatch->epairs ) { + patch->epairs = *b->pPatch->epairs; + } + return patch; + } + else { + idMapBrush *mapbrush = new idMapBrush; + for ( face_t *f = b->brush_faces; f; f = f->next ) { + idMapBrushSide *side = new idMapBrushSide; + + idPlane plane; + if ( f->dirty ) { + f->planepts[0] -= origin; + f->planepts[1] -= origin; + f->planepts[2] -= origin; + plane.FromPoints( f->planepts[0], f->planepts[1], f->planepts[2], false ); + f->planepts[0] += origin; + f->planepts[1] += origin; + f->planepts[2] += origin; + } else { + plane = f->originalPlane; + } + side->SetPlane( plane ); + side->SetMaterial( f->d_texture->GetName() ); + idVec3 mat[2]; + mat[0][0] = f->brushprimit_texdef.coords[0][0]; + mat[0][1] = f->brushprimit_texdef.coords[0][1]; + mat[0][2] = f->brushprimit_texdef.coords[0][2]; + mat[1][0] = f->brushprimit_texdef.coords[1][0]; + mat[1][1] = f->brushprimit_texdef.coords[1][1]; + mat[1][2] = f->brushprimit_texdef.coords[1][2]; + side->SetTextureMatrix(mat); + mapbrush->AddSide(side); + mapbrush->epairs = b->epairs; + } + return mapbrush; + } +} + +idMapEntity *EntityToMapEntity(entity_t *e, bool use_region, CWaitDlg *dlg) { + idMapEntity *mapent = new idMapEntity; + mapent->epairs = e->epairs; + idStr status; + int count = 0; + long lastUpdate = 0; + if ( !EntityHasModel( e ) ) { + for ( brush_t *b = e->brushes.onext; b != &e->brushes; b = b->onext ) { + count++; + if ( e->eclass->fixedsize && !b->entityModel ) { + continue; + } + if ( !use_region || !Map_IsBrushFiltered( b ) ) { + // Update 20 times a second + if ( GetTickCount() - lastUpdate > 50 ) { + lastUpdate = GetTickCount(); + if ( b->pPatch ) { + sprintf( status, "Adding primitive %i (patch)", count ); + dlg->SetText( status, true ); + } else { + sprintf( status, "Adding primitive %i (brush)", count ); + dlg->SetText( status, true ); + } + } + idMapPrimitive *prim = BrushToMapPrimitive( b, e->origin ); + if ( prim ) { + mapent->AddPrimitive( prim ); + } + } + } + } + return mapent; +} + +/* + ======================================================================================================================= + Map_SaveFile + ======================================================================================================================= + */ +bool Map_SaveFile(const char *filename, bool use_region, bool autosave) { + entity_t *e, *next; + idStr temp; + int count; + brush_t *b; + idStr status; + + int len = strlen(filename); + WIN32_FIND_DATA FileData; + if (FindFirstFile(filename, &FileData) != INVALID_HANDLE_VALUE) { + // the file exists; + if (len > 0 && GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY) { + g_pParentWnd->MessageBox("File is read only", "Read Only", MB_OK); + return false; + } + } + + if (filename == NULL || len == 0 || (filename && stricmp(filename, "unnamed.map") == 0)) { + CFileDialog dlgSave(FALSE,"map",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Map Files (*.map)|*.map||",AfxGetMainWnd()); + if (dlgSave.DoModal() == IDOK) { + filename = dlgSave.m_ofn.lpstrFile; + strcpy(currentmap, filename); + } + else { + return false; + } + } + + MEMORYSTATUSEX statex; + statex.dwLength = sizeof (statex); + GlobalMemoryStatusEx (&statex); + if ( statex.dwMemoryLoad > 95 ) { + g_pParentWnd->MessageBox("Physical memory is over 95% utilized. Consider saving and restarting", "Memory"); + } + + CWaitDlg dlg; + Pointfile_Clear(); + + temp = filename; + temp.BackSlashesToSlashes(); + + if ( !use_region ) { + idStr backup; + backup = temp; + backup.StripFileExtension(); + backup.SetFileExtension( ".bak" ); + if ( _unlink(backup) != 0 && errno != 2 ) { // errno 2 means the file doesn't exist, which we don't care about + g_pParentWnd->MessageBox( va("Unable to delete %s: %s", backup.c_str(), strerror(errno) ), "File Error" ); + } + + if ( rename(filename, backup) != 0 ) { + g_pParentWnd->MessageBox( va("Unable to rename %s to %s: %s", filename, backup.c_str(), strerror(errno) ), "File Error" ); + } + } + + common->Printf("Map_SaveFile: %s\n", filename); + + idStr mapFile; + bool localFile = (strstr(filename, ":") != NULL); + if (autosave || localFile) { + mapFile = filename; + } else { + mapFile = fileSystem->OSPathToRelativePath( filename ); + } + + if (use_region) { + AddRegionBrushes(); + } + + idMapFile map; + world_entity->origin.Zero(); + idMapEntity *mapentity = EntityToMapEntity(world_entity, use_region, &dlg); + dlg.SetText("Saving worldspawn..."); + map.AddEntity(mapentity); + + if ( use_region ) { + idStr buf; + sprintf( buf, "{\n\"classname\" \"info_player_start\"\n\"origin\"\t \"%i %i %i\"\n\"angle\"\t \"%i\"\n}\n", + (int)g_pParentWnd->GetCamera()->Camera().origin[0], + (int)g_pParentWnd->GetCamera()->Camera().origin[1], + (int)g_pParentWnd->GetCamera()->Camera().origin[2], + (int)g_pParentWnd->GetCamera()->Camera().angles[YAW] ); + idLexer src( LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + src.LoadMemory( buf, buf.Length(), "regionbuf" ); + idMapEntity *playerstart = idMapEntity::Parse( src ); + map.AddEntity( playerstart ); + } + + count = -1; + for ( e = entities.next; e != &entities; e = next ) { + count++; + next = e->next; + if (e->brushes.onext == &e->brushes) { + Entity_Free(e); // no brushes left, so remove it + } + else { + if (use_region) { + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + if (!Map_IsBrushFiltered(b)) { + break; // got one + } + } + + if (b == &e->brushes) { + continue; // nothing visible + } + + } + idVec3 origin; + if (!GetVectorForKey(e, "origin", origin)) { + idStr text; + VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); + sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue(e, "origin", text); + } + + if (use_region && !idStr::Icmp(ValueForKey(e, "classname"), "info_player_start")) { + continue; + } + + idStr classname = e->epairs.GetString("classname"); + sprintf(status, "Saving entity %i (%s)...", count, classname.c_str()); + dlg.SetText(status); + + map.AddEntity(EntityToMapEntity(e, use_region, &dlg)); + count++; + } + } + + mapFile.StripFileExtension(); + idStr mapExt = (use_region) ? ".reg" : ".map"; + sprintf(status, "Writing file %s.%s...", mapFile.c_str(), mapExt.c_str()); + dlg.SetText(status); + map.Write(mapFile, mapExt, !(autosave || localFile)); + mapModified = 0; + + if (use_region) { + RemoveRegionBrushes(); + } + + if (!strstr(temp, "autosave")) { + Sys_SetTitle(temp); + } + + Sys_Status("Saved.\n", 0); + + return true; +} + +/* + ======================================================================================================================= + Map_New + ======================================================================================================================= + */ +void Map_New(void) { + common->Printf("Map_New\n"); + Map_Free(); + + Patch_Cleanup(); + g_Inspectors->entityDlg.SetEditEntity ( NULL ); + + world_entity = Entity_New(); + world_entity->brushes.onext = world_entity->brushes.oprev = &world_entity->brushes; + SetKeyValue(world_entity, "classname", "worldspawn"); + world_entity->eclass = Eclass_ForName("worldspawn", true); + + g_pParentWnd->GetCamera()->Camera().angles[YAW] = 0; + g_pParentWnd->GetCamera()->Camera().angles[PITCH] = 0; + VectorCopy(vec3_origin, g_pParentWnd->GetCamera()->Camera().origin); + g_pParentWnd->GetCamera()->Camera().origin[2] = 48; + VectorCopy(vec3_origin, g_pParentWnd->GetXYWnd()->GetOrigin()); + + Map_RestoreBetween(); + + Sys_UpdateWindows(W_ALL); + mapModified = 0; + + g_qeglobals.mapVersion = MAP_VERSION; + +} + + +bool region_active; +idVec3 region_mins(MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD); +idVec3 region_maxs(MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD); + +brush_t *region_sides[6]; + +/* + ======================================================================================================================= + AddRegionBrushes a regioned map will have temp walls put up at the region boundary + ======================================================================================================================= + */ +void AddRegionBrushes(void) { + idVec3 mins, maxs; + int i; + texdef_t td; + + if (!region_active) { + return; + } + + memset(&td, 0, sizeof(td)); + td = g_qeglobals.d_texturewin.texdef; + + // strcpy (td.name, "REGION"); + td.SetName("textures/REGION"); + +const int REGION_WIDTH = 1024; + + + mins[0] = region_mins[0] - REGION_WIDTH; + maxs[0] = region_mins[0] + 1; + mins[1] = region_mins[1] - REGION_WIDTH; + maxs[1] = region_maxs[1] + REGION_WIDTH; + mins[2] = MIN_WORLD_COORD; + maxs[2] = MAX_WORLD_COORD; + region_sides[0] = Brush_Create(mins, maxs, &td); + + + mins[0] = region_maxs[0] - 1; + maxs[0] = region_maxs[0] + REGION_WIDTH; + region_sides[1] = Brush_Create(mins, maxs, &td); + + mins[0] = region_mins[0] - REGION_WIDTH; + maxs[0] = region_maxs[0] + REGION_WIDTH; + mins[1] = region_mins[1] - REGION_WIDTH; + maxs[1] = region_mins[1] + 1; + region_sides[2] = Brush_Create(mins, maxs, &td); + + mins[1] = region_maxs[1] - 1; + maxs[1] = region_maxs[1] + REGION_WIDTH; + region_sides[3] = Brush_Create(mins, maxs, &td); + + mins = region_mins; + maxs = region_maxs; + maxs[2] = mins[2] + REGION_WIDTH; + region_sides[4] = Brush_Create(mins, maxs, &td); + + mins = region_mins; + maxs = region_maxs; + mins[2] = maxs[2] - REGION_WIDTH; + region_sides[5] = Brush_Create(mins, maxs, &td); + + for (i = 0; i < 6; i++) { + Brush_AddToList(region_sides[i], &selected_brushes); + Entity_LinkBrush(world_entity, region_sides[i]); + Brush_Build(region_sides[i]); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void RemoveRegionBrushes(void) { + int i; + + if (!region_active) { + return; + } + + for (i = 0; i < 6; i++) { + Brush_Free(region_sides[i]); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool Map_IsBrushFiltered(brush_t *b) { + int i; + + if (!region_active) { + return false; + } + + for (i = 0; i < 3; i++) { + if (b->mins[i] > region_maxs[i]) { + return true; + } + + if (b->maxs[i] < region_mins[i]) { + return true; + } + } + + return false; +} + +/* + ======================================================================================================================= + Map_RegionOff Other filtering options may still be on + ======================================================================================================================= + */ +void Map_RegionOff(void) { + brush_t *b, *next; + int i; + + region_active = false; + for (i = 0; i < 3; i++) { + region_maxs[i] = MAX_WORLD_COORD; // 4096; + region_mins[i] = MIN_WORLD_COORD; // -4096; + } + + for (b = filtered_brushes.next; b != &filtered_brushes; b = next) { + next = b->next; + if (Map_IsBrushFiltered(b)) { + continue; // still filtered + } + + Brush_RemoveFromList(b); + if (active_brushes.next == NULL || active_brushes.prev == NULL) { + active_brushes.next = &active_brushes; + active_brushes.prev = &active_brushes; + } + + Brush_AddToList(b, &active_brushes); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Map_ApplyRegion(void) { + brush_t *b, *next; + + region_active = true; + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + if (!Map_IsBrushFiltered(b)) { + continue; // still filtered + } + + Brush_RemoveFromList(b); + Brush_AddToList(b, &filtered_brushes); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Map_RegionSelectedBrushes + ======================================================================================================================= + */ +void Map_RegionSelectedBrushes(void) { + Map_RegionOff(); + + if (selected_brushes.next == &selected_brushes) { // nothing selected + Sys_Status("Tried to region with no selection...\n"); + return; + } + + region_active = true; + Select_GetBounds(region_mins, region_maxs); + + // move the entire active_brushes list to filtered_brushes + filtered_brushes.next = active_brushes.next; + filtered_brushes.prev = active_brushes.prev; + filtered_brushes.next->prev = &filtered_brushes; + filtered_brushes.prev->next = &filtered_brushes; + + Patch_Deselect(); + // move the entire selected_brushes list to active_brushes + active_brushes.next = selected_brushes.next; + active_brushes.prev = selected_brushes.prev; + active_brushes.next->prev = &active_brushes; + active_brushes.prev->next = &active_brushes; + + // clear selected_brushes + selected_brushes.next = selected_brushes.prev = &selected_brushes; + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Map_RegionXY + ======================================================================================================================= + */ +void Map_RegionXY(void) { + Map_RegionOff(); + + region_mins[0] = g_pParentWnd->GetXYWnd()->GetOrigin()[0] - + 0.5 * + g_pParentWnd->GetXYWnd()->Width() / + g_pParentWnd->GetXYWnd()->Scale(); + region_maxs[0] = g_pParentWnd->GetXYWnd()->GetOrigin()[0] + + 0.5 * + g_pParentWnd->GetXYWnd()->Width() / + g_pParentWnd->GetXYWnd()->Scale(); + region_mins[1] = g_pParentWnd->GetXYWnd()->GetOrigin()[1] - + 0.5 * + g_pParentWnd->GetXYWnd()->Height() / + g_pParentWnd->GetXYWnd()->Scale(); + region_maxs[1] = g_pParentWnd->GetXYWnd()->GetOrigin()[1] + + 0.5 * + g_pParentWnd->GetXYWnd()->Height() / + g_pParentWnd->GetXYWnd()->Scale(); + region_mins[2] = MIN_WORLD_COORD; + region_maxs[2] = MAX_WORLD_COORD; + Map_ApplyRegion(); +} + +/* + ======================================================================================================================= + Map_RegionTallBrush + ======================================================================================================================= + */ +void Map_RegionTallBrush(void) { + brush_t *b; + + if (!QE_SingleBrush()) { + return; + } + + b = selected_brushes.next; + + Map_RegionOff(); + + VectorCopy(b->mins, region_mins); + VectorCopy(b->maxs, region_maxs); + region_mins[2] = MIN_WORLD_COORD; + region_maxs[2] = MAX_WORLD_COORD; + + Select_Delete(); + Map_ApplyRegion(); +} + +/* + ======================================================================================================================= + Map_RegionBrush + ======================================================================================================================= + */ +void Map_RegionBrush(void) { + brush_t *b; + + if (!QE_SingleBrush()) { + return; + } + + b = selected_brushes.next; + + Map_RegionOff(); + + VectorCopy(b->mins, region_mins); + VectorCopy(b->maxs, region_maxs); + + Select_Delete(); + Map_ApplyRegion(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void UniqueTargetName(idStr &rStr) { + // make a unique target value + int maxtarg = 0; + for (entity_t * e = entities.next; e != &entities; e = e->next) { + const char *tn = ValueForKey(e, "name"); + if (tn && tn[0]) { + int targetnum = atoi(tn + 1); + if (targetnum > maxtarg) { + maxtarg = targetnum; + } + } + else { + tn = ValueForKey(e, "target"); + if (tn && tn[0]) { + int targetnum = atoi(tn + 1); + if (targetnum > maxtarg) { + maxtarg = targetnum; + } + } + } + } + + sprintf(rStr, "t%i", maxtarg + 1); +} + +// +// ======================================================================================================================= +// Map_ImportFile Timo 09/01/99:: called by CXYWnd::Paste & Map_ImportFile if Map_ImportFile ( prefab ), the buffer +// may contain brushes in old format ( conversion needed ) +// ======================================================================================================================= +// +void Map_ImportBuffer(char *buf, bool renameEntities) { + entity_t *ent; + brush_t *b = NULL; + CPtrArray ptrs; + + Select_Deselect(); + + Undo_Start("import buffer"); + + g_qeglobals.d_parsed_brushes = 0; + if (buf) { + CMapStringToString mapStr; + StartTokenParsing(buf); + g_qeglobals.d_num_entities = 0; + + // + // Timo will be used in Entity_Parse to detect if a conversion between brush + // formats is needed + // + g_qeglobals.bNeedConvert = false; + g_qeglobals.bOldBrushes = false; + g_qeglobals.bPrimitBrushes = false; + g_qeglobals.mapVersion = 1.0; + + if (GetToken(true)) { + if (stricmp(token, "Version") == 0) { + GetToken(false); + g_qeglobals.mapVersion = atof(token); + common->Printf("Map version: %1.2f\n", g_qeglobals.mapVersion); + } else { + UngetToken(); + } + } + + idDict RemappedNames; // since I can't use "map "... sigh. So much for STL... + + while (1) { + // + // use the selected brushes list as it's handy ent = Entity_Parse (false, + // &selected_brushes); + // + ent = Entity_Parse(false, &active_brushes); + if (!ent) { + break; + } + + // end entity for undo + Undo_EndEntity(ent); + + // end brushes for undo + for (b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) { + Undo_EndBrush(b); + } + + if (!strcmp(ValueForKey(ent, "classname"), "worldspawn")) { + // world brushes need to be added to the current world entity + b = ent->brushes.onext; + while (b && b != &ent->brushes) { + brush_t *bNext = b->onext; + Entity_UnlinkBrush(b); + Entity_LinkBrush(world_entity, b); + ptrs.Add(b); + b = bNext; + } + } + else { + // the following bit remaps conflicting target/targetname key/value pairs + CString str = ValueForKey(ent, "target"); + CString strKey; + CString strTarget(""); + if (str.GetLength() > 0) { + if (FindEntity("target", str.GetBuffer(0))) { + if (!mapStr.Lookup(str, strKey)) { + idStr key; + UniqueTargetName(key); + strKey = key; + mapStr.SetAt(str, strKey); + } + + strTarget = strKey; + SetKeyValue(ent, "target", strTarget.GetBuffer(0)); + } + } + + /* + * str = ValueForKey(ent, "name"); if (str.GetLength() > 0) { if + * (FindEntity("name", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { + * UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } Entity_SetName(ent, + * strKey.GetBuffer(0)); } } + */ + CString cstrNameOld = ValueForKey(ent, "name"); + Entity_Name(ent, renameEntities); + CString cstrNameNew = ValueForKey(ent, "name"); + if (cstrNameOld != cstrNameNew) + { + RemappedNames.Set(cstrNameOld, cstrNameNew); + } + // + // if (strTarget.GetLength() > 0) SetKeyValue(ent, "target", + // strTarget.GetBuffer(0)); + // add the entity to the end of the entity list + // + ent->next = &entities; + ent->prev = entities.prev; + entities.prev->next = ent; + entities.prev = ent; + g_qeglobals.d_num_entities++; + + for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { + ptrs.Add(b); + } + } + } + + // now iterate through the remapped names, and see if there are any target-connections that need remaking... + // + // (I could probably write this in half the size with STL, but WTF, work with what we have...) + // + int iNumKeyVals = RemappedNames.GetNumKeyVals(); + for (int iKeyVal=0; iKeyVal < iNumKeyVals; iKeyVal++) + { + const idKeyValue *pKeyVal = RemappedNames.GetKeyVal( iKeyVal ); + + LPCSTR psOldName = pKeyVal->GetKey().c_str(); + LPCSTR psNewName = pKeyVal->GetValue().c_str(); + + entity_t *pEntOld = FindEntity("name", psOldName); // original ent we cloned from + entity_t *pEntNew = FindEntity("name", psNewName); // cloned ent + + if (pEntOld && pEntNew) + { + CString cstrTargetNameOld = ValueForKey(pEntOld, "target"); + if (!cstrTargetNameOld.IsEmpty()) + { + // ok, this ent was targeted at another ent, so it's clone needs updating to point to + // the clone of that target, so... + // + entity_t *pEntOldTarget = FindEntity("name", cstrTargetNameOld); + if ( pEntOldTarget ) + { + LPCSTR psNewTargetName = RemappedNames.GetString( cstrTargetNameOld ); + if (psNewTargetName && psNewTargetName[0]) + { + SetKeyValue(pEntNew, "target", psNewTargetName); + } + } + } + } + } + } + + // + // ::ShowWindow(g_qeglobals.d_hwndEntity, FALSE); + // ::LockWindowUpdate(g_qeglobals.d_hwndEntity); + // + g_bScreenUpdates = false; + for (int i = 0; i < ptrs.GetSize(); i++) { + Brush_Build(reinterpret_cast < brush_t * > (ptrs[i]), true, false); + Select_Brush(reinterpret_cast < brush_t * > (ptrs[i]), true, false); + } + + // ::LockWindowUpdate(NULL); + g_bScreenUpdates = true; + + ptrs.RemoveAll(); + + // + // reset the "need conversion" flag conversion to the good format done in + // Map_BuildBrushData + // + g_qeglobals.bNeedConvert = false; + + Sys_UpdateWindows(W_ALL); + + // Sys_MarkMapModified(); + mapModified = 1; + + Undo_End(); +} + +// +// ======================================================================================================================= +// Map_ImportFile +// ======================================================================================================================= +// +void Map_ImportFile(char *fileName) { + char *buf; + idStr temp; + Sys_BeginWait(); + temp = fileName; + temp.BackSlashesToSlashes(); + if (LoadFile( temp, (void **) &buf) != -1) { + Map_ImportBuffer(buf); + Mem_Free( buf ); + Map_BuildBrushData(); + } + + Sys_UpdateWindows(W_ALL); + mapModified = 1; + Sys_EndWait(); +} + +// +// ======================================================================================================================= +// Map_SaveSelected Saves selected world brushes and whole entities with partial/full selections +// ======================================================================================================================= +// +void Map_SaveSelected(char *fileName) { + entity_t *e, *next; + FILE *f; + idStr temp; + int count; + + temp = fileName; + temp.BackSlashesToSlashes(); + f = fopen(temp, "w"); + + if ( !f ) { + common->Printf( "ERROR!!!! Couldn't open %s\n", temp.c_str() ); + return; + } + + // write version + g_qeglobals.mapVersion = MAP_VERSION; + fprintf( f, "Version %1.2f\n", MAP_VERSION ); + + // write world entity second + world_entity->origin.Zero(); + Entity_WriteSelected( world_entity, f ); + + // then write all other ents + count = 1; + for ( e = entities.next; e != &entities; e = next ) { + fprintf( f, "// entity %i\n", count ); + count++; + Entity_WriteSelected( e, f ); + next = e->next; + } + + fclose( f ); +} + +// +// ======================================================================================================================= +// Map_SaveSelected Saves selected world brushes and whole entities with partial/full selections +// ======================================================================================================================= +// +void Map_SaveSelected(CMemFile *pMemFile, CMemFile *pPatchFile) { + entity_t *e, *next; + int count; + CString strTemp; + + // write version + g_qeglobals.mapVersion = MAP_VERSION; + MemFile_fprintf(pMemFile, "Version %1.2f\n", MAP_VERSION); + + // write world entity first + world_entity->origin.Zero(); + Entity_WriteSelected(world_entity, pMemFile); + + // then write all other ents + count = 1; + for (e = entities.next; e != &entities; e = next) { + MemFile_fprintf(pMemFile, "// entity %i\n", count); + count++; + Entity_WriteSelected(e, pMemFile); + next = e->next; + } + + // if (pPatchFile) Patch_WriteFile(pPatchFile); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +/* +================ +WriteFileString +================ +*/ +bool WriteFileString( FILE *fp, char *string, ... ) { + long i; + unsigned long u; + double f; + char *str; + idStr buf; + va_list argPtr; + + va_start( argPtr, string ); + + while( *string ) { + switch( *string ) { + case '%': + string++; + while ( (*string >= '0' && *string <= '9') || + *string == '.' || *string == '-' || *string == '+' || *string == '#') { + string++; + } + switch( *string ) { + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + f = va_arg( argPtr, double ); + sprintf( buf, "%1.10f", f ); + buf.StripTrailing( '0' ); + buf.StripTrailing( '.' ); + fprintf( fp, "%s", buf.c_str() ); + break; + case 'd': + case 'i': + i = va_arg( argPtr, long ); + fprintf( fp, "%d", i ); + break; + case 'u': + u = va_arg( argPtr, unsigned long ); + fprintf( fp, "%u", u ); + break; + case 'o': + u = va_arg( argPtr, unsigned long ); + fprintf( fp, "%o", u ); + break; + case 'x': + u = va_arg( argPtr, unsigned long ); + fprintf( fp, "%x", u ); + break; + case 'X': + u = va_arg( argPtr, unsigned long ); + fprintf( fp, "%X", u ); + break; + case 'c': + i = va_arg( argPtr, long ); + fprintf( fp, "%c", (char) i ); + break; + case 's': + str = va_arg( argPtr, char * ); + fprintf( fp, "%s", str ); + break; + case '%': + fprintf( fp, "%%" ); + break; + default: + common->Error( "WriteFileString: invalid %%%c", *string ); + break; + } + string++; + break; + case '\\': + string++; + switch( *string ) { + case 't': + fprintf( fp, "\t" ); + break; + case 'n': + fprintf( fp, "\n" ); + default: + common->Error( "WriteFileString: unknown escape character \'%c\'", *string ); + break; + } + string++; + break; + default: + fprintf( fp, "%c", *string ); + string++; + break; + } + } + + va_end( argPtr ); + + return true; +} + +/* +================ +MemFile_fprintf +================ +*/ +void MemFile_fprintf( CMemFile *pMemFile, const char *string, ... ) { + char Buffer[4096]; + long i; + unsigned long u; + double f; + char *str; + idStr buf, out; + va_list argPtr; + + char *buff = Buffer; + + va_start( argPtr, string ); + + while( *string ) { + switch( *string ) { + case '%': + string++; + while ( (*string >= '0' && *string <= '9') || + *string == '.' || *string == '-' || *string == '+' || *string == '#') { + string++; + } + switch( *string ) { + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + f = va_arg( argPtr, double ); + sprintf( buf, "%1.10f", f ); + buf.StripTrailing( '0' ); + buf.StripTrailing( '.' ); + sprintf( buff, "%s", buf.c_str() ); + break; + case 'd': + case 'i': + i = va_arg( argPtr, long ); + sprintf( buff, "%d", i ); + break; + case 'u': + u = va_arg( argPtr, unsigned long ); + sprintf( buff, "%u", u ); + break; + case 'o': + u = va_arg( argPtr, unsigned long ); + sprintf( buff, "%o", u ); + break; + case 'x': + u = va_arg( argPtr, unsigned long ); + sprintf( buff, "%x", u ); + break; + case 'X': + u = va_arg( argPtr, unsigned long ); + sprintf( buff, "%X", u ); + break; + case 'c': + i = va_arg( argPtr, long ); + sprintf( buff, "%c", (char) i ); + break; + case 's': + str = va_arg( argPtr, char * ); + sprintf( buff, "%s", str ); + break; + case '%': + sprintf( buff, "%%" ); + break; + default: + common->Error( "MemFile_fprintf: invalid %%%c", *string ); + break; + } + string++; + break; + case '\\': + string++; + switch( *string ) { + case 't': + sprintf( buff, "\t" ); + break; + case 'n': + sprintf( buff, "\n" ); + default: + common->Error( "MemFile_fprintf: unknown escape character \'%c\'", *string ); + break; + } + string++; + break; + default: + sprintf( buff, "%c", *string ); + string++; + break; + } + + buff = Buffer + strlen(Buffer); + } + + va_end( argPtr ); + + out = Buffer; + pMemFile->Write( out.c_str(), out.Length() ); +} diff --git a/tools/radiant/EditorMap.h b/tools/radiant/EditorMap.h new file mode 100644 index 000000000..5923e3c3c --- /dev/null +++ b/tools/radiant/EditorMap.h @@ -0,0 +1,58 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +extern char currentmap[1024]; + +// head/tail of doubly linked lists +extern brush_t active_brushes; // brushes currently being displayed +extern brush_t selected_brushes; // highlighted + + +extern CPtrArray& g_ptrSelectedFaces; +extern CPtrArray& g_ptrSelectedFaceBrushes; +//extern face_t *selected_face; +//extern brush_t *selected_face_brush; +extern brush_t filtered_brushes; // brushes that have been filtered or regioned + +extern entity_t entities; +extern entity_t *world_entity; // the world entity is NOT included in + // the entities chain + +extern int modified; // for quit confirmations + +extern idVec3 region_mins, region_maxs; +extern bool region_active; + +void Map_LoadFile (const char *filename); +bool Map_SaveFile (const char *filename, bool use_region, bool autosave = false); +void Map_New (void); +void Map_BuildBrushData(void); + +void Map_RegionOff (void); +void Map_RegionXY (void); +void Map_RegionTallBrush (void); +void Map_RegionBrush (void); +void Map_RegionSelectedBrushes (void); +bool Map_IsBrushFiltered (brush_t *b); + +void Map_SaveSelected(CMemFile* pMemFile, CMemFile* pPatchFile = NULL); +void Map_ImportBuffer (char* buf, bool renameEntities = true); +int Map_GetUniqueEntityID(const char *prefix, const char *eclass); + +idMapPrimitive *BrushToMapPrimitive( const brush_t *b, const idVec3 &origin ); diff --git a/tools/radiant/EntKeyFindReplace.cpp b/tools/radiant/EntKeyFindReplace.cpp new file mode 100644 index 000000000..d6e68406a --- /dev/null +++ b/tools/radiant/EntKeyFindReplace.cpp @@ -0,0 +1,190 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +//#include "stdafx.h" +#include "radiant.h" +#include "GetString.h" // for ErrorBox() etc +#include "qe3.h" + +#include "EntKeyFindReplace.h" +//#include "oddbits.h" +/* +#include "stdafx.h" +#include "Radiant.h" +#include "ZWnd.h" +#include "qe3.h" +#include "zclip.h" +*/ + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CEntKeyFindReplace dialog + +CEntKeyFindReplace::CEntKeyFindReplace( CString* p_strFindKey, + CString* p_strFindValue, + CString* p_strReplaceKey, + CString* p_strReplaceValue, + bool* p_bWholeStringMatchOnly, + bool* p_bSelectAllMatchingEnts, + CWnd* pParent /*=NULL*/) + : CDialog(CEntKeyFindReplace::IDD, pParent) +{ + m_pStrFindKey = p_strFindKey; + m_pStrFindValue = p_strFindValue; + m_pStrReplaceKey = p_strReplaceKey; + m_pStrReplaceValue = p_strReplaceValue; + m_pbWholeStringMatchOnly = p_bWholeStringMatchOnly; + m_pbSelectAllMatchingEnts= p_bSelectAllMatchingEnts; + + //{{AFX_DATA_INIT(CEntKeyFindReplace) + m_strFindKey = *m_pStrFindKey; + m_strFindValue = *m_pStrFindValue; + m_strReplaceKey = *m_pStrReplaceKey; + m_strReplaceValue = *m_pStrReplaceValue; + m_bWholeStringMatchOnly = *m_pbWholeStringMatchOnly; + m_bSelectAllMatchingEnts = *m_pbSelectAllMatchingEnts; + //}}AFX_DATA_INIT +} + + +void CEntKeyFindReplace::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CEntKeyFindReplace) + DDX_Text(pDX, IDC_EDIT_FIND_KEY, m_strFindKey); + DDX_Text(pDX, IDC_EDIT_FIND_VALUE, m_strFindValue); + DDX_Text(pDX, IDC_EDIT_REPLACE_KEY, m_strReplaceKey); + DDX_Text(pDX, IDC_EDIT_REPLACE_VALUE, m_strReplaceValue); + DDX_Check(pDX, IDC_CHECK_FIND_WHOLESTRINGMATCHONLY, m_bWholeStringMatchOnly); + DDX_Check(pDX, IDC_CHECK_SELECTALLMATCHING, m_bSelectAllMatchingEnts); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CEntKeyFindReplace, CDialog) + //{{AFX_MSG_MAP(CEntKeyFindReplace) + ON_BN_CLICKED(IDC_REPLACE, OnReplace) + ON_BN_CLICKED(IDC_FIND, OnFind) + ON_BN_CLICKED(IDC_KEYCOPY, OnKeycopy) + ON_BN_CLICKED(IDC_VALUECOPY, OnValuecopy) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CEntKeyFindReplace message handlers + +void CEntKeyFindReplace::OnCancel() +{ + CDialog::OnCancel(); +} + +void CEntKeyFindReplace::OnReplace() +{ + // quick check, if no key value is specified then there's not much to do... + // + UpdateData(DIALOG_TO_DATA); + if (m_strFindKey.IsEmpty()) + { + ErrorBox("Empty FIND !\n\n(This is only permitted for FIND, not replace, for safety reasons)"); + } + else + { + if (!m_strFindValue.IsEmpty() || GetYesNo(va("Empty FIND means replace any existing ( & non-blank ) for \"%s\"\n\nProceed?",(LPCSTR)m_strFindKey))) + { + // another check, if they're trying to do a replace with a missing replace key, it'll just delete found keys... + // + if ((!m_strReplaceKey.IsEmpty() && !m_strReplaceValue.IsEmpty()) || GetYesNo(va("Empty REPLACE or fields will just delete all occurence of \"%s\"\n\nProceed?",m_strFindKey))) + { + if (GetYesNo("Sure?")) + { + CopyFields(); + EndDialog(ID_RET_REPLACE); + } + } + } + } +} + +void CEntKeyFindReplace::OnFind() +{ + // quick check, if no key value is specified then there's not much to do... + // + UpdateData(DIALOG_TO_DATA); + + if (m_strFindKey.IsEmpty() && m_strFindValue.IsEmpty()) + { + ErrorBox("Empty FIND fields!"); + } + else + { +// if (m_strFindKey.IsEmpty() && m_bSelectAllMatchingEnts) +// { +// if (GetYesNo("Warning! Having a blank FIND and ticking \"Select all matching ents\" can take a LONG time to do (and is probably a wrong choice anyway?)\n\nProceed?")) +// { +// CopyFields(); +// EndDialog(ID_RET_FIND); +// } +// } +// else + { + CopyFields(); + EndDialog(ID_RET_FIND); + } + } +} + +void CEntKeyFindReplace::CopyFields() +{ + UpdateData(DIALOG_TO_DATA); + + *m_pStrFindKey = m_strFindKey; + *m_pStrFindValue = m_strFindValue; + *m_pStrReplaceKey = m_strReplaceKey; + *m_pStrReplaceValue = m_strReplaceValue; + *m_pbWholeStringMatchOnly = m_bWholeStringMatchOnly != 0; + *m_pbSelectAllMatchingEnts = m_bSelectAllMatchingEnts != 0; +} + + +void CEntKeyFindReplace::OnKeycopy() +{ + UpdateData(DIALOG_TO_DATA); + + m_strReplaceKey = m_strFindKey; + + UpdateData(DATA_TO_DIALOG); +} + +void CEntKeyFindReplace::OnValuecopy() +{ + UpdateData(DIALOG_TO_DATA); + + m_strReplaceValue = m_strFindValue; + + UpdateData(DATA_TO_DIALOG); +} + diff --git a/tools/radiant/EntKeyFindReplace.h b/tools/radiant/EntKeyFindReplace.h new file mode 100644 index 000000000..143ca8651 --- /dev/null +++ b/tools/radiant/EntKeyFindReplace.h @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_ENTKEYFINDREPLACE_H__1AE54C31_FC22_11D3_8A60_00500424438B__INCLUDED_) +#define AFX_ENTKEYFINDREPLACE_H__1AE54C31_FC22_11D3_8A60_00500424438B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// EntKeyFindReplace.h : header file +// + + +// return vals for modal dialogue, any values will do that don't clash with the first 9 or so defined by IDOK etc +// +#define ID_RET_REPLACE 100 +#define ID_RET_FIND 101 + + +///////////////////////////////////////////////////////////////////////////// +// CEntKeyFindReplace dialog + +class CEntKeyFindReplace : public CDialog +{ +// Construction +public: + CEntKeyFindReplace(CString* p_strFindKey, + CString* p_strFindValue, + CString* p_strReplaceKey, + CString* p_strReplaceValue, + bool* p_bWholeStringMatchOnly, + bool* p_bSelectAllMatchingEnts, + CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CEntKeyFindReplace) + enum { IDD = IDD_ENTFINDREPLACE }; + CString m_strFindKey; + CString m_strFindValue; + CString m_strReplaceKey; + CString m_strReplaceValue; + BOOL m_bWholeStringMatchOnly; + BOOL m_bSelectAllMatchingEnts; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEntKeyFindReplace) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CEntKeyFindReplace) + virtual void OnCancel(); + afx_msg void OnReplace(); + afx_msg void OnFind(); + afx_msg void OnKeycopy(); + afx_msg void OnValuecopy(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + CString* m_pStrFindKey; + CString* m_pStrFindValue; + CString* m_pStrReplaceKey; + CString* m_pStrReplaceValue; + bool* m_pbWholeStringMatchOnly; + bool* m_pbSelectAllMatchingEnts; + + void CopyFields(); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ENTKEYFINDREPLACE_H__1AE54C31_FC22_11D3_8A60_00500424438B__INCLUDED_) diff --git a/tools/radiant/EntityDlg.cpp b/tools/radiant/EntityDlg.cpp new file mode 100644 index 000000000..623a3f33a --- /dev/null +++ b/tools/radiant/EntityDlg.cpp @@ -0,0 +1,1368 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "GLWidget.h" +#include "PropertyList.h" +#include "entitydlg.h" +#include "PreviewDlg.h" +#include "CurveDlg.h" + +#include "../../renderer/model_local.h" // for idRenderModelPrt + +void Select_Ungroup(); + +// CEntityDlg dialog + +IMPLEMENT_DYNAMIC(CEntityDlg, CDialog) +CEntityDlg::CEntityDlg(CWnd* pParent /*=NULL*/) + : CDialog(CEntityDlg::IDD, pParent) +{ + editEntity = NULL; + multipleEntities = false; + currentAnimation = NULL; +} + +CEntityDlg::~CEntityDlg() +{ +} + +void CEntityDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST_KEYVAL, listKeyVal); + DDX_Control(pDX, IDC_COMBO_CLASS, comboClass); + DDX_Control(pDX, IDC_EDIT_KEY, editKey); + DDX_Control(pDX, IDC_EDIT_VAL, editVal); + DDX_Control(pDX, IDC_STATIC_TITLE, staticTitle); + DDX_Control(pDX, IDC_STATIC_KEY, staticKey); + DDX_Control(pDX, IDC_STATIC_VAL, staticVal); + DDX_Control(pDX, IDC_BUTTON_BROWSE, btnBrowse); + DDX_Control(pDX, IDC_E_135, btn135); + DDX_Control(pDX, IDC_E_90, btn90); + DDX_Control(pDX, IDC_E_45, btn45); + DDX_Control(pDX, IDC_E_180, btn180); + DDX_Control(pDX, IDC_E_0, btn360); + DDX_Control(pDX, IDC_E_225, btn225); + DDX_Control(pDX, IDC_E_270, btn270); + DDX_Control(pDX, IDC_E_315, btn315); + DDX_Control(pDX, IDC_E_UP, btnUp); + DDX_Control(pDX, IDC_E_DOWN, btnDown); + DDX_Control(pDX, IDC_BUTTON_MODEL, btnModel); + DDX_Control(pDX, IDC_BUTTON_SOUND, btnSound); + DDX_Control(pDX, IDC_BUTTON_GUI, btnGui); + DDX_Control(pDX, IDC_BUTTON_PARTICLE, btnParticle); + DDX_Control(pDX, IDC_BUTTON_SKIN, btnSkin); + DDX_Control(pDX, IDC_BUTTON_CURVE, btnCurve); + DDX_Control(pDX, IDC_BUTTON_CREATE, btnCreate); + DDX_Control(pDX, IDC_LIST_VARS, listVars); + DDX_Control(pDX, IDC_ENTITY_ANIMATIONS , cbAnimations); + DDX_Control(pDX, IDC_ANIMATION_SLIDER , slFrameSlider); + DDX_Control(pDX, IDC_ENTITY_CURRENT_ANIM , staticFrame); + DDX_Control(pDX, IDC_ENTITY_PLAY_ANIM , btnPlayAnim); + DDX_Control(pDX, IDC_ENTITY_STOP_ANIM , btnStopAnim); +} + + + +BOOL CEntityDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + listKeyVal.SetUpdateInspectors(true); + listKeyVal.SetDivider(100); + listVars.SetDivider(100); + staticFrame.SetWindowText ( "0" ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +int CEntityDlg::OnToolHitTest(CPoint point, TOOLINFO* pTI) const +{ + // TODO: Add your specialized code here and/or call the base class + + return CDialog::OnToolHitTest(point, pTI); +} + + +void CEntityDlg::AddClassNames() { + comboClass.ResetContent(); + for (eclass_t *pec = eclass; pec; pec = pec->next) { + comboClass.AddString(pec->name); + } + +} + +BEGIN_MESSAGE_MAP(CEntityDlg, CDialog) + ON_WM_SIZE() + ON_CBN_SELCHANGE(IDC_COMBO_CLASS, OnCbnSelchangeComboClass) + ON_LBN_SELCHANGE(IDC_LIST_KEYVAL, OnLbnSelchangeListkeyval) + ON_BN_CLICKED(IDC_E_135, OnBnClickedE135) + ON_BN_CLICKED(IDC_E_90, OnBnClickedE90) + ON_BN_CLICKED(IDC_E_45, OnBnClickedE45) + ON_BN_CLICKED(IDC_E_180, OnBnClickedE180) + ON_BN_CLICKED(IDC_E_0, OnBnClickedE0) + ON_BN_CLICKED(IDC_E_225, OnBnClickedE225) + ON_BN_CLICKED(IDC_E_270, OnBnClickedE270) + ON_BN_CLICKED(IDC_E_315, OnBnClickedE315) + ON_BN_CLICKED(IDC_E_UP, OnBnClickedEUp) + ON_BN_CLICKED(IDC_E_DOWN, OnBnClickedEDown) + ON_BN_CLICKED(IDC_BUTTON_MODEL, OnBnClickedButtonModel) + ON_BN_CLICKED(IDC_BUTTON_SOUND, OnBnClickedButtonSound) + ON_BN_CLICKED(IDC_BUTTON_GUI, OnBnClickedButtonGui) + ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse) + ON_CBN_DBLCLK(IDC_COMBO_CLASS, OnCbnDblclkComboClass) + ON_BN_CLICKED(IDC_BUTTON_CREATE, OnBnClickedButtonCreate) + ON_LBN_DBLCLK(IDC_LIST_KEYVAL, OnLbnDblclkListkeyval) + ON_LBN_SELCHANGE(IDC_LIST_VARS, OnLbnSelchangeListVars) + ON_LBN_DBLCLK(IDC_LIST_VARS, OnLbnDblclkListVars) + ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_ANIMATION_SLIDER, OnNMReleasedcaptureSlider1) + ON_BN_CLICKED(IDC_BUTTON_PARTICLE, OnBnClickedButtonParticle) + ON_BN_CLICKED(IDC_BUTTON_SKIN, OnBnClickedButtonSkin) + ON_BN_CLICKED(IDC_BUTTON_CURVE, OnBnClickedButtonCurve) + ON_CBN_SELCHANGE(IDC_ENTITY_ANIMATIONS, OnCbnAnimationChange) + ON_BN_CLICKED(IDC_ENTITY_PLAY_ANIM , OnBnClickedStartAnimation) + ON_BN_CLICKED(IDC_ENTITY_STOP_ANIM , OnBnClickedStopAnimation) + ON_WM_TIMER() + ON_BN_CLICKED(IDOK, OnOK) +END_MESSAGE_MAP() + +void CEntityDlg::OnSize(UINT nType, int cx, int cy) +{ + if (staticTitle.GetSafeHwnd() == NULL) { + return; + } + CDialog::OnSize(nType, cx, cy); + CRect rect, crect, crect2; + GetClientRect(rect); + int bh = (float)rect.Height() * (rect.Height() - 210) / rect.Height() / 2; + staticTitle.GetWindowRect(crect); + staticTitle.SetWindowPos(NULL, 4, 4, rect.Width() -8, crect.Height(), SWP_SHOWWINDOW); + int top = 4 + crect.Height() + 4; + comboClass.GetWindowRect(crect); + btnCreate.GetWindowRect(crect2); + comboClass.SetWindowPos(NULL, 4, top, rect.Width() - 12 - crect2.Width(), crect.Height(), SWP_SHOWWINDOW); + btnCreate.SetWindowPos(NULL, rect.Width() - crect2.Width() - 4, top, crect2.Width(), crect.Height(), SWP_SHOWWINDOW); + top += crect.Height() + 4; + listVars.SetWindowPos(NULL, 4, top, rect.Width() - 8, bh, SWP_SHOWWINDOW); + top += bh + 4; + listKeyVal.SetWindowPos(NULL, 4, top, rect.Width() - 8, bh, SWP_SHOWWINDOW); + top += bh + 4; + staticKey.GetWindowRect(crect); + staticKey.SetWindowPos(NULL, 4, top + 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + int left = 4 + crect.Width() + 4; + int pad = crect.Width(); + editKey.GetWindowRect(crect); + editKey.SetWindowPos(NULL, left, top, rect.Width() - 12 - pad, crect.Height(), SWP_SHOWWINDOW); + top += crect.Height() + 4; + staticVal.GetWindowRect(crect); + staticVal.SetWindowPos(NULL, 4, top + 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + editVal.GetWindowRect(crect); + bh = crect.Height(); + editVal.SetWindowPos(NULL, left, top, rect.Width() - 16 - bh - pad, crect.Height(), SWP_SHOWWINDOW); + btnBrowse.SetWindowPos(NULL, rect.right - 4 - bh, top, bh, bh, SWP_SHOWWINDOW); + top += crect.Height() + 8; + btnModel.GetWindowRect(crect); + btnModel.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 8, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + btnSound.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW); + btnGui.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + btnParticle.SetWindowPos(NULL, rect.right - 8 - (crect.Width() * 2), top + 16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW); + btnSkin.SetWindowPos( NULL, rect.right - 8 - ( crect.Width() * 2 ), top + 12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW ); + btnCurve.SetWindowPos( NULL, rect.right - 8 - ( crect.Width() * 2 ), top + 8, crect.Width(), crect.Height(), SWP_SHOWWINDOW ); + + //************************************* + //animation controls + //************************************* + int rightAnimAreaBorder = rect.right - 75 - crect.Width (); /*models, etc button width*/ + + btnStopAnim.GetWindowRect(crect); + btnStopAnim.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (), + top + 8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW); + + left = rightAnimAreaBorder - crect.Width() - 4; + btnPlayAnim.GetWindowRect(crect); + btnPlayAnim.SetWindowPos(NULL,left-crect.Width () ,top + 8 , crect.Width(),crect.Height(),SWP_SHOWWINDOW); + + left -= crect.Width() + 4; + cbAnimations.GetWindowRect(crect); + cbAnimations.SetWindowPos(NULL,left-crect.Width (),top + 8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW); + + staticFrame.GetWindowRect(crect); + staticFrame.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (), + top + 34 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW); + + left = rightAnimAreaBorder - crect.Width () - 4; + + slFrameSlider.GetWindowRect(crect); + slFrameSlider.SetWindowPos(NULL,left - crect.Width (), + top + 32 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW); + + //************************************* + //************************************* + + btn135.GetWindowRect(crect); + bh = crect.Width(); + btn135.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW); + btn90.SetWindowPos(NULL, 4 + 2 + bh, top, bh, bh, SWP_SHOWWINDOW); + btn45.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW); + btnUp.SetWindowPos(NULL, 4 + 2 + 2 + 6 + bh * 3, top + bh / 2,bh,bh, SWP_SHOWWINDOW); + btnDown.SetWindowPos(NULL, 4 + 2 + 2 + 6 + bh *3, top + bh / 2 + bh + 2,bh,bh, SWP_SHOWWINDOW); + top += bh + 2; + btn180.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW); + btn360.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW); + top += bh + 2; + btn225.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW); + btn270.SetWindowPos(NULL, 4 + 2 + bh, top, bh, bh, SWP_SHOWWINDOW); + btn315.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW); + Invalidate(); +} + +void CEntityDlg::OnCbnSelchangeComboClass() +{ + int index = comboClass.GetCurSel(); + if (index != LB_ERR) { + CString str; + comboClass.GetLBText(index, str); + eclass_t *ent = Eclass_ForName (str, false); + if (ent) { + if (selected_brushes.next == &selected_brushes) { + editEntity = world_entity; + multipleEntities = false; + } else { + editEntity = selected_brushes.next->owner; + for (brush_t *b = selected_brushes.next->next; b != &selected_brushes; b = b->next) { + if (b->owner != editEntity) { + multipleEntities = true; + break; + } + } + } + listVars.ResetContent(); + CPropertyItem *pi = new CPropertyItem("Usage:", ent->desc.c_str(), PIT_VAR, ""); + listVars.AddPropItem(pi); + + int c = ent->vars.Num(); + for (int i = 0; i < c; i++) { + pi = new CPropertyItem(ent->vars[i].name.c_str(), ent->vars[i].desc.c_str(), PIT_VAR, ""); + pi->SetData(ent->vars[i].type); + listVars.AddPropItem(pi); + } + listVars.Invalidate(); + SetKeyValPairs(); + } + } +} + +const char *CEntityDlg::TranslateString(const char *buf) { + static char buf2[32768]; + int i, l; + char *out; + + l = strlen(buf); + out = buf2; + for (i = 0; i < l; i++) { + if (buf[i] == '\n') { + *out++ = '\r'; + *out++ = '\n'; + } + else { + *out++ = buf[i]; + } + } + + *out++ = 0; + + return buf2; + +} + +void CEntityDlg::UpdateFromListBox() { + if (editEntity == NULL) { + return; + } + int c = listKeyVal.GetCount(); + for (int i = 0 ; i < c; i++) { + CPropertyItem* pItem = (CPropertyItem*)listKeyVal.GetItemDataPtr(i); + if (pItem) { + editEntity->epairs.Set(pItem->m_propName, pItem->m_curValue); + } + } + SetKeyValPairs(); +} + +void CEntityDlg::SetKeyValPairs( bool updateAnims ) { + if (editEntity) { + listKeyVal.ResetContent(); + int c = editEntity->epairs.GetNumKeyVals(); + for (int i = 0; i < c; i++) { + const idKeyValue *kv = editEntity->epairs.GetKeyVal(i); + CPropertyItem *pi = new CPropertyItem(kv->GetKey().c_str(), kv->GetValue().c_str(), PIT_EDIT, ""); + bool found = false; + int vc = editEntity->eclass->vars.Num(); + for (int j = 0; j < vc; j++) { + if (editEntity->eclass->vars[j].name.Icmp(kv->GetKey()) == 0) { + switch (editEntity->eclass->vars[j].type) { + case EVAR_STRING : + case EVAR_INT : + case EVAR_FLOAT : + pi->m_nItemType = PIT_EDIT; + break; + case EVAR_BOOL : + pi->m_nItemType = PIT_EDIT; + //pi->m_cmbItems = "0|1"; + break; + case EVAR_COLOR : + pi->m_nItemType = PIT_COLOR; + break; + case EVAR_MATERIAL : + pi->m_nItemType = PIT_MATERIAL; + break; + case EVAR_MODEL : + pi->m_nItemType = PIT_MODEL; + break; + case EVAR_GUI : + pi->m_nItemType = PIT_GUI; + break; + case EVAR_SOUND : + pi->m_nItemType = PIT_SOUND; + break; + } + found = true; + break; + } + } + if (!found) { + if (kv->GetKey().Icmp("model") == 0) { + pi->m_nItemType = PIT_MODEL; + } + if (kv->GetKey().Icmp("_color") == 0) { + pi->m_nItemType = PIT_COLOR; + } + if (kv->GetKey().Icmp("gui") == 0) { + pi->m_nItemType = PIT_GUI; + } + if (kv->GetKey().Icmp("gui2") == 0) { + pi->m_nItemType = PIT_GUI; + } + if (kv->GetKey().Icmp("gui3") == 0) { + pi->m_nItemType = PIT_GUI; + } + if (kv->GetKey().Icmp("s_shader") == 0) { + pi->m_nItemType = PIT_SOUND; + } + } + listKeyVal.AddPropItem(pi); + } + + if ( updateAnims ) { + int i, num; + + cbAnimations.ResetContent(); + num = gameEdit->ANIM_GetNumAnimsFromEntityDef( &editEntity->eclass->defArgs ); + for( i = 0; i < num; i++ ) { + cbAnimations.AddString( gameEdit->ANIM_GetAnimNameFromEntityDef( &editEntity->eclass->defArgs, i ) ); + } + + const idKeyValue* kv = editEntity->epairs.FindKey ( "anim" ); + if ( kv ) { + int selIndex = cbAnimations.FindStringExact( 0 , kv->GetValue().c_str() ); + if ( selIndex != -1 ) { + cbAnimations.SetCurSel( selIndex ); + OnCbnAnimationChange (); + } + } + } + } +} + +void CEntityDlg::UpdateEntitySel(eclass_t *ent) { + assert ( ent ); + assert ( ent->name ); + int index = comboClass.FindString(-1, ent->name); + if (index != LB_ERR) { + comboClass.SetCurSel(index); + OnCbnSelchangeComboClass(); + } +} + +void CEntityDlg::OnLbnSelchangeListkeyval() +{ + int index = listKeyVal.GetCurSel(); + if (index != LB_ERR) { + CString str; + listKeyVal.GetText(index, str); + int i; + for (i = 0; str[i] != '\t' && str[i] != '\0'; i++) { + } + + idStr key = str.Left(i); + while (str[i] == '\t' && str[i] != '\0') { + i++; + } + + idStr val = str.Right(str.GetLength() - i); + + editKey.SetWindowText(key); + editVal.SetWindowText(val); + } +} + +static int TabOrder[] = { + IDC_COMBO_CLASS, + IDC_BUTTON_CREATE, + //IDC_EDIT_INFO, + IDC_LIST_KEYVAL, + IDC_EDIT_KEY, + IDC_EDIT_VAL, + IDC_BUTTON_BROWSE, + IDC_E_135, + IDC_E_90, + IDC_E_45, + IDC_E_180, + IDC_E_0, + IDC_E_225, + IDC_E_270, + IDC_E_315, + IDC_E_UP, + IDC_E_DOWN, + IDC_BUTTON_MODEL, + IDC_BUTTON_SOUND, + IDC_BUTTON_GUI, + IDC_ENTITY_ANIMATIONS +}; + +int TabCount = sizeof(TabOrder) / sizeof(int); + +void CEntityDlg::DelProp() { + CString key; + + if (editEntity == NULL) { + return; + } + + editKey.GetWindowText(key); + if (multipleEntities) { + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + DeleteKey(b->owner, key); + Entity_UpdateCurveData( b->owner ); + } + } else { + DeleteKey(editEntity, key); + Entity_UpdateCurveData( editEntity ); + } + + // refresh the prop listbox + SetKeyValPairs(); + Sys_UpdateWindows( W_ENTITY | W_XY | W_CAMERA ); +} + + +BOOL CEntityDlg::PreTranslateMessage(MSG* pMsg) +{ + + if (pMsg->hwnd == editVal.GetSafeHwnd()) { + if (pMsg->message == WM_LBUTTONDOWN) { + editVal.SetFocus(); + return TRUE; + } + } + + if (pMsg->hwnd == editKey.GetSafeHwnd()) { + if (pMsg->message == WM_LBUTTONDOWN) { + editKey.SetFocus(); + return TRUE; + } + } + + if (GetFocus() == &editVal || GetFocus() == &editKey) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + AddProp(); + return TRUE; + } + + } + + if (GetFocus() == listKeyVal.GetEditBox()) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + listKeyVal.OnChangeEditBox(); + listKeyVal.OnSelchange(); + listKeyVal.OnKillfocusEditBox(); + AddProp(); + SetKeyValPairs(); + return TRUE; + } + } + + if (GetFocus() == &listKeyVal) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE && editEntity) { + DelProp(); + return TRUE; + } + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { + if (pMsg->wParam == VK_ESCAPE) { + g_pParentWnd->GetCamera()->SetFocus(); + Select_Deselect(); + } + return TRUE; + } + + if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + // keeps ENTER from closing the dialog + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB) { + if (GetFocus()) { + int id = GetFocus()->GetDlgCtrlID(); + for (int i = 0; i < TabCount; i++) { + if (TabOrder[i] == id) { + i++; + if (i >= TabCount) { + i = 0; + } + CWnd *next = GetDlgItem(TabOrder[i]); + if (next) { + next->SetFocus(); + if (TabOrder[i] == IDC_EDIT_VAL) { + editVal.SetSel(0, -1); + } + return TRUE; + } + } + } + } + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RIGHT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) { + int pos = slFrameSlider.GetPos() + 1; + pos = (pos % slFrameSlider.GetRangeMax()); + slFrameSlider.SetPos ( pos ); + UpdateFromAnimationFrame (); + return TRUE; + } + + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_LEFT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) { + int pos = slFrameSlider.GetPos() - 1; + + if ( pos < 1 ) { + pos = slFrameSlider.GetRangeMax(); + } + + slFrameSlider.SetPos ( pos ); + UpdateFromAnimationFrame (); + return TRUE; + } + + return CDialog::PreTranslateMessage(pMsg); +} + + +/* + ======================================================================================================================= + AddProp + ======================================================================================================================= + */ +void CEntityDlg::AddProp() { + + if (editEntity == NULL) { + return; + } + + CString Key, Value; + editKey.GetWindowText(Key); + editVal.GetWindowText(Value); + + bool isName = (stricmp(Key, "name") == 0); + bool isModel = static_cast((stricmp(Key, "model") == 0 && Value.GetLength() > 0)); + bool isOrigin = ( idStr::Icmp( Key, "origin" ) == 0 ); + + if (multipleEntities) { + brush_t *b; + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (isName) { + Entity_SetName(b->owner, Value); + } else { + if ( ! ( ( isModel || isOrigin ) && ( b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) { + SetKeyValue(b->owner, Key, Value); + } + } + } + } + else { + if (isName) { + Entity_SetName(editEntity, Value); + } else { + if ( ! ( ( isModel || isOrigin ) && ( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) { + SetKeyValue(editEntity, Key, Value); + } + } + + if ( isModel && !( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) { + idBounds bo; + idVec3 mins, maxs; + + selected_brushes.next->modelHandle = renderModelManager->FindModel( Value ); + if ( dynamic_cast( selected_brushes.next->modelHandle ) || dynamic_cast( selected_brushes.next->modelHandle ) ) { + bo.Zero(); + bo.ExpandSelf( 12.0f ); + } else { + bo = selected_brushes.next->modelHandle->Bounds( NULL ); + } + + VectorCopy(bo[0], mins); + VectorCopy(bo[1], maxs); + VectorAdd(mins, editEntity->origin, mins); + VectorAdd(maxs, editEntity->origin, maxs); + Brush_RebuildBrush(selected_brushes.next, mins, maxs, false); + Brush_Build ( selected_brushes.next , false, false , false, true ); + } + } + + // refresh the prop listbox + SetKeyValPairs(); + Sys_UpdateWindows(W_ALL); + +} + +const char *CEntityDlg::AngleKey() { + if (editEntity == NULL) { + return ""; + } + + if (editEntity->eclass->nShowFlags & ECLASS_MOVER) { + return "movedir"; + } + + return "angle"; +} + + +void CEntityDlg::OnBnClickedE135() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("135"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE90() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("90"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE45() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("45"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE180() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("180"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE0() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("0"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE225() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("225"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE270() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("270"); + AddProp(); +} + +void CEntityDlg::OnBnClickedE315() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("315"); + AddProp(); +} + +void CEntityDlg::OnBnClickedEUp() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("-1"); + AddProp(); +} + +void CEntityDlg::OnBnClickedEDown() +{ + if (editEntity == NULL) { + return; + } + editKey.SetWindowText(AngleKey()); + editVal.SetWindowText("-2"); + AddProp(); +} + +CPreviewDlg *CEntityDlg::ShowModelChooser() { + static CPreviewDlg modelDlg; + modelDlg.SetMode(CPreviewDlg::MODELS); + modelDlg.SetModal(); + if (modelDlg.GetSafeHwnd() == NULL) { + modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + modelDlg.ShowWindow( SW_SHOW ); + modelDlg.BringWindowToTop(); + while (modelDlg.Waiting()) { + } + return &modelDlg; +} + +CPreviewDlg *CEntityDlg::ShowParticleChooser() { + static CPreviewDlg modelDlg; + modelDlg.SetMode(CPreviewDlg::PARTICLES); + modelDlg.SetModal(); + if (modelDlg.GetSafeHwnd() == NULL) { + modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + modelDlg.ShowWindow(SW_SHOW); + modelDlg.BringWindowToTop(); + while (modelDlg.Waiting()) { + } + return &modelDlg; +} + +CPreviewDlg *CEntityDlg::ShowSkinChooser(entity_t *ent) { + static CPreviewDlg modelDlg; + modelDlg.SetMode(CPreviewDlg::SKINS); + modelDlg.SetModal(); + if (modelDlg.GetSafeHwnd() == NULL) { + modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + modelDlg.RebuildTree( ( ent ) ? ent->epairs.GetString( "model" ) : "" ); + modelDlg.ShowWindow(SW_SHOW); + modelDlg.BringWindowToTop(); + while (modelDlg.Waiting()) { + } + return &modelDlg; +} + +CPreviewDlg *CEntityDlg::ShowGuiChooser() { + static CPreviewDlg guiDlg; + guiDlg.SetMode(CPreviewDlg::GUIS); + guiDlg.SetModal(); + if (guiDlg.GetSafeHwnd() == NULL) { + guiDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + guiDlg.ShowWindow(SW_SHOW); + guiDlg.BringWindowToTop(); + while (guiDlg.Waiting()) { + } + return &guiDlg; +} + +CPreviewDlg *CEntityDlg::ShowSoundChooser() { + static CPreviewDlg soundDlg; + soundDlg.SetMode(CPreviewDlg::SOUNDS); + soundDlg.SetModal(); + if (soundDlg.GetSafeHwnd() == NULL) { + soundDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + soundDlg.ShowWindow(SW_SHOW); + while (soundDlg.Waiting()) { + } + return &soundDlg; +} + +CPreviewDlg *CEntityDlg::ShowMaterialChooser() { + static CPreviewDlg matDlg; + matDlg.SetMode(CPreviewDlg::MATERIALS); + matDlg.SetModal(); + if (matDlg.GetSafeHwnd() == NULL) { + matDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW)); + } + matDlg.ShowWindow(SW_SHOW); + matDlg.BringWindowToTop(); + while (matDlg.Waiting()) { + } + return &matDlg; +} + +void CEntityDlg::AssignModel () +{ + OnBnClickedButtonModel(); +} +void CEntityDlg::OnBnClickedButtonModel() { + CPreviewDlg *dlg = ShowModelChooser(); + if (dlg->returnCode == IDOK) { + editKey.SetWindowText("model"); + editVal.SetWindowText(dlg->mediaName); + AddProp(); + } +} + +void CEntityDlg::OnBnClickedButtonSound() { + CPreviewDlg *dlg = ShowSoundChooser(); + if (dlg->returnCode == IDOK) { + editKey.SetWindowText("s_shader"); + editVal.SetWindowText(dlg->mediaName); + AddProp(); + } +} + +void CEntityDlg::OnBnClickedButtonGui() { + CPreviewDlg *dlg = ShowGuiChooser(); + if (dlg->returnCode == IDOK) { + editKey.SetWindowText("gui"); + editVal.SetWindowText(dlg->mediaName); + AddProp(); + } +} + +void CEntityDlg::OnBnClickedButtonParticle() { + CPreviewDlg *dlg = ShowParticleChooser(); + if (dlg->returnCode == IDOK) { + editKey.SetWindowText("model"); + editVal.SetWindowText(dlg->mediaName); + AddProp(); + } +} + +void CEntityDlg::OnBnClickedButtonSkin() { + CPreviewDlg *dlg = ShowSkinChooser( editEntity ); + if (dlg->returnCode == IDOK) { + editKey.SetWindowText("skin"); + editVal.SetWindowText(dlg->mediaName); + AddProp(); + } + +} + +void CEntityDlg::OnBnClickedButtonCurve() { + CCurveDlg dlg; + if ( dlg.DoModal() == IDOK ) { + if ( editEntity ) { + idStr str = "curve_" + dlg.strCurveType; + editKey.SetWindowText( str ); + idVec3 org = editEntity->origin; + str = "3 ( "; + str += org.ToString(); + org.x += 64; + str += " "; + str += org.ToString(); + org.y += 64; + str += " "; + str += org.ToString(); + str += " )"; + editVal.SetWindowText( str ); + AddProp(); + Entity_SetCurveData( editEntity ); + } + } +} + +void CEntityDlg::OnBnClickedButtonBrowse() { + DelProp(); +} + +void CEntityDlg::OnCbnDblclkComboClass() +{ + // TODO: Add your control notification handler code here +} + +// +// ======================================================================================================================= +// CreateEntity Creates a new entity based on the currently selected brush and entity type. +// ======================================================================================================================= +// +void CEntityDlg::CreateEntity() { + entity_t *petNew; + bool forceFixed = false; + + // check to make sure we have a brush + CXYWnd *pWnd = g_pParentWnd->ActiveXY(); + if (pWnd) { + CRect rctZ; + pWnd->GetClientRect(rctZ); + + brush_t *pBrush; + if (selected_brushes.next == &selected_brushes) { + pBrush = CreateEntityBrush(g_nSmartX, rctZ.Height() - 1 - g_nSmartY, pWnd); + forceFixed = true; + } + } + else { + if (selected_brushes.next == &selected_brushes) { + MessageBox("You must have a selected brush to create an entity", "info", 0); + return; + } + } + + int index = comboClass.GetCurSel(); + if (index == LB_ERR) { + MessageBox("You must have a selected class to create an entity", "info", 0); + return; + } + + CString str; + comboClass.GetLBText(index, str); + + if (!stricmp(str, "worldspawn")) { + MessageBox("Can't create an entity with worldspawn.", "info", 0); + return; + } + + eclass_t *pecNew = Eclass_ForName (str, false); + + // create it + if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + // MAJOR hack for xian +extern void Brush_CopyList(brush_t *pFrom, brush_t *pTo); + brush_t temp_brushes; + temp_brushes.next = &temp_brushes; + Brush_CopyList(&selected_brushes, &temp_brushes); + Select_Deselect(); + brush_t *pBrush = temp_brushes.next; + while (pBrush != NULL && pBrush != &temp_brushes) { + brush_t *pNext = pBrush->next; + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, &selected_brushes); + pBrush = pNext; + petNew = Entity_Create(pecNew, forceFixed); + Select_Deselect(); + } + } else if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) { + Select_Ungroup(); + petNew = Entity_Create(pecNew, forceFixed); + } else { + petNew = Entity_Create(pecNew, forceFixed); + } + + if (petNew == NULL) { + MessageBox("Failed to create entity.", "info", 0); + return; + } + + if (selected_brushes.next == &selected_brushes) { + editEntity = world_entity; + } + else { + editEntity = selected_brushes.next->owner; + } + + SetKeyValPairs(); + Select_Deselect(); + Select_Brush(editEntity->brushes.onext); + Sys_UpdateWindows(W_ALL); +} + +void CEntityDlg::OnBnClickedButtonCreate() +{ + CreateEntity(); +} + +void CEntityDlg::OnLbnDblclkListkeyval() +{ + CString Key, Value; + idStr work; + editKey.GetWindowText( Key ); + editVal.GetWindowText( Value ); + if ( stricmp( Key, "script" ) == 0 ) { + Key = Value; + Value = "script/" + Key; + if ( fileSystem->ReadFile( Value, NULL, NULL ) == -1) { + sprintf( work, "// Script for %s\n// \n\nvoid main() {\n\n}\n\n", currentmap ); + fileSystem->WriteFile( Value, work.c_str(), work.Length(), "fs_devpath" ); + } + work = fileSystem->RelativePathToOSPath( Value ); + WinExec( va( "notepad.exe %s", work.c_str() ), SW_SHOW ); + } +} + +void CEntityDlg::OnLbnSelchangeListVars() { + +} + +void CEntityDlg::OnLbnDblclkListVars() { + if (editEntity == NULL) { + return; + } + int sel = listVars.GetCurSel(); + CPropertyItem *pi = (CPropertyItem*)listVars.GetItemDataPtr(sel); + if (pi) { + if (editEntity->epairs.FindKey(pi->m_propName) == NULL) { + editKey.SetWindowText(pi->m_propName); + editVal.SetWindowText(""); + editVal.SetFocus(); + } + } +} + + +void CEntityDlg::UpdateKeyVal(const char *key, const char *val) { + if (editEntity) { + editEntity->epairs.Set(key, val); + SetKeyValPairs(); + g_pParentWnd->GetCamera()->BuildEntityRenderState(editEntity, true); + Entity_UpdateSoundEmitter(editEntity); + } +} + + +void CEntityDlg::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult) +{ + if ( !editEntity ) + { + return; + } + + UpdateFromAnimationFrame (); + + *pResult = 0; +} + +void CEntityDlg::UpdateFromAnimationFrame ( bool updateKeyValueDisplay ) +{ + int frame = slFrameSlider.GetPos (); + editEntity->epairs.SetInt( "frame" , frame ); + SetDlgItemText ( IDC_ENTITY_CURRENT_ANIM , va ( "%i" , frame)); + if ( updateKeyValueDisplay ) { + SetKeyValPairs(); + } + + g_pParentWnd->GetCamera ()->BuildEntityRenderState (editEntity , true ); + Sys_UpdateWindows ( W_ALL ); + +} + +void CEntityDlg::OnCbnAnimationChange () +{ + if ( !editEntity ) + { + return; + } + + int sel = cbAnimations.GetCurSel(); + CString animName; + currentAnimation = NULL; + int currFrame = 0; + + if ( sel != -1 ) { + cbAnimations.GetLBText( sel , animName ); + if ( animName.GetLength() > 0 ) { + //preserve the existing frame number + currFrame = editEntity->epairs.GetInt ( "frame" , "1" ); + + editEntity->epairs.Set("anim" , animName.GetBuffer(0)); + SetKeyValPairs(false/*don't update anims combo box :)*/ ); + + //update the slider + currentAnimation = gameEdit->ANIM_GetAnimFromEntityDef(editEntity->eclass->name , animName.GetBuffer(0)); + currentAnimationFrame = 0; + + if ( currentAnimation ) { + slFrameSlider.SetRange( 1 , gameEdit->ANIM_GetNumFrames( currentAnimation ), TRUE ); + slFrameSlider.SetPos( currFrame ); + currentAnimationFrame = currFrame; + } + + Sys_UpdateWindows(W_ALL); + } + } +} + +void CEntityDlg::OnBnClickedStartAnimation() +{ + if (!editEntity) { + return; + } + SetTimer ( 0 , 1000/24 , NULL ); +} + +void CEntityDlg::OnBnClickedStopAnimation() +{ + KillTimer ( 0 ); +} + +void CEntityDlg::OnTimer(UINT nIDEvent) +{ + if ( !editEntity ) { + OnBnClickedStopAnimation (); + return; + } + + if ( currentAnimation ) { + currentAnimationFrame = ( (currentAnimationFrame++) % gameEdit->ANIM_GetNumFrames( currentAnimation ) ); + editEntity->epairs.SetInt ( "frame" , currentAnimationFrame ); + slFrameSlider.SetPos ( currentAnimationFrame ); + UpdateFromAnimationFrame (false/*don't update key/value display*/); + + Sys_UpdateWindows ( W_CAMERA | W_XY ); + } +} + +void CEntityDlg::AddCurvePoints() { + if ( editEntity == NULL || editEntity->curve == NULL ) { + return; + } + + // add one point 64 units from the direction of the two points int he curve + int c = editEntity->curve->GetNumValues(); + idVec3 start; + idVec3 end; + if ( c > 1 ) { + start = editEntity->curve->GetValue( c - 2 ); + end = editEntity->curve->GetValue( c - 1 ); + idVec3 dir = end - start; + dir.Normalize(); + start = end + 64 * dir; + } else if ( c > 0 ) { + start = editEntity->curve->GetValue( 0 ); + start.x += 64; + start.y += 64; + } else { + start = editEntity->origin; + } + + editEntity->curve->AddValue( editEntity->curve->GetNumValues() * 100, start ); + + if ( g_qeglobals.d_select_mode == sel_editpoint ) { + g_qeglobals.d_select_mode = sel_brush; + EditCurvePoints(); + } + + Sys_UpdateWindows( W_CAMERA | W_XY ); + +} + +void CEntityDlg::EditCurvePoints() { + + if ( editEntity == NULL || editEntity->curve == NULL ) { + return; + } + + if ( g_qeglobals.d_select_mode == sel_editpoint ) { + g_qeglobals.d_select_mode = sel_brush; + return; + } + + g_qeglobals.d_select_mode = sel_editpoint; + + g_qeglobals.d_numpoints = 0; + g_qeglobals.d_num_move_points = 0; + int c = editEntity->curve->GetNumValues(); + for ( int i = 0; i < c; i++ ) { + if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) { + g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i ); + } + } + Sys_UpdateWindows( W_XY | W_CAMERA ); + +} + +void CEntityDlg::InsertCurvePoint() { + if ( editEntity == NULL || editEntity->curve == NULL ) { + return; + } + + if ( g_qeglobals.d_select_mode != sel_editpoint ) { + return; + } + + if ( g_qeglobals.d_num_move_points == 0 ) { + return; + } + + for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) { + if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) { + if ( i == editEntity->curve->GetNumValues() - 1 ) { + // just do an add + AddCurvePoints(); + } else { + idCurve *newCurve = Entity_MakeCurve( editEntity ); + + if ( newCurve == NULL ) { + return; + } + + for ( int j = 0; j < editEntity->curve->GetNumValues(); j++ ) { + if ( j == i ) { + idVec3 start; + idVec3 end; + if ( i > 0 ) { + start = editEntity->curve->GetValue( i - 1 ); + end = editEntity->curve->GetValue( i ); + start += end; + start *= 0.5f; + } else { + start = editEntity->curve->GetValue( 0 ); + if ( editEntity->curve->GetNumValues() > 1 ) { + end = start; + start = editEntity->curve->GetValue ( 1 ); + idVec3 dir = end - start; + dir.Normalize(); + start = end + 64 * dir; + } else { + end = start; + end.x += 64; + end.y += 64; + } + } + newCurve->AddValue( newCurve->GetNumValues() * 100, start ); + } + newCurve->AddValue( newCurve->GetNumValues() * 100, editEntity->curve->GetValue( j ) ); + } + delete editEntity->curve; + editEntity->curve = newCurve; + } + g_qeglobals.d_num_move_points = 0; + break; + } + } + UpdateEntityCurve(); + + Sys_UpdateWindows( W_XY | W_CAMERA ); + +} + +void CEntityDlg::DeleteCurvePoint() { + + if ( editEntity == NULL || editEntity->curve == NULL ) { + return; + } + + if ( g_qeglobals.d_select_mode != sel_editpoint ) { + return; + } + + + if ( g_qeglobals.d_num_move_points == 0 ) { + return; + } + + for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) { + if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) { + editEntity->curve->RemoveIndex( i ); + g_qeglobals.d_num_move_points = 0; + break; + } + } + UpdateEntityCurve(); + + Sys_UpdateWindows( W_XY | W_CAMERA ); + +} + + +void CEntityDlg::UpdateEntityCurve() { + + if ( editEntity == NULL ) { + return; + } + + Entity_UpdateCurveData( editEntity ); + + if ( g_qeglobals.d_select_mode == sel_editpoint ) { + g_qeglobals.d_numpoints = 0; + int c = editEntity->curve->GetNumValues(); + for ( int i = 0; i < c; i++ ) { + if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) { + g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i ); + } + } + } + + Sys_UpdateWindows( W_ENTITY ); +} + + +void CEntityDlg::SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) { + int i, besti; + float d, bestd; + idVec3 temp; + + if ( editEntity == NULL ) { + return; + } + // find the point closest to the ray + float scale = g_pParentWnd->ActiveXY()->Scale(); + besti = -1; + bestd = 8 / scale / 2; + //bestd = 8; + + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + temp = g_qeglobals.d_points[i] - org; + d = temp * dir; + temp = org + d * dir; + temp = g_qeglobals.d_points[i] - temp; + d = temp.Length(); + if ( d <= bestd ) { + bestd = d; + besti = i; + } + } + + if (besti == -1) { + return; + } + + g_qeglobals.d_num_move_points = 0; + assert ( besti < editEntity->curve->GetNumValues() ); + g_qeglobals.d_move_points[ g_qeglobals.d_num_move_points++ ] = editEntity->curve->GetValueAddress( besti ); +} + diff --git a/tools/radiant/EntityDlg.h b/tools/radiant/EntityDlg.h new file mode 100644 index 000000000..1fb0b04f8 --- /dev/null +++ b/tools/radiant/EntityDlg.h @@ -0,0 +1,159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once +#include "afxcmn.h" +#include "afxwin.h" +#include "PropertyList.h" +#include "PreviewDlg.h" + +// CEntityDlg dialog + + + +class CEntityDlg : public CDialog +{ + DECLARE_DYNAMIC(CEntityDlg) +public: + CEntityDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CEntityDlg(); + void SetDict(idDict *_dict) { + dict = dict; + } + void SetEditEntity(entity_t *ent) { + editEntity = ent; + } + void CreateEntity(); + void AssignModel (); + static CPreviewDlg *ShowModelChooser(); + static CPreviewDlg *ShowGuiChooser(); + static CPreviewDlg *ShowSoundChooser(); + static CPreviewDlg *ShowMaterialChooser(); + static CPreviewDlg *ShowParticleChooser(); + static CPreviewDlg *ShowSkinChooser( entity_t *ent ); + + void SetKeyVal(const char *key, const char *val) { + editKey.SetWindowText(key); + editVal.SetWindowText(val); + } + + void EditCurvePoints(); + void AddCurvePoints(); + void InsertCurvePoint(); + void DeleteCurvePoint(); + +// Dialog Data + enum { IDD = IDD_DIALOG_ENTITY }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + //DECLARE_MESSAGE_MAP() +public: + + virtual BOOL OnInitDialog(); + virtual int OnToolHitTest(CPoint point, TOOLINFO* pTI) const; + void AddClassNames(); + void UpdateEntitySel(eclass_t *ent); + void SetKeyValPairs( bool updateAnims = true ); + static const char *TranslateString(const char *p); + void AddProp(); + void DelProp(); + void UpdateFromListBox(); + CEdit editKey; + CEdit editVal; + void UpdateKeyVal(const char *key, const char *val); + void SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons); + void UpdateEntityCurve(); + + +private: + entity_t *editEntity; + bool multipleEntities; + CPropertyList listKeyVal; + CPropertyList listVars; + CComboBox comboClass; + idDict *dict; + const idMD5Anim* currentAnimation; + int currentAnimationFrame; + + const char *AngleKey(); + + idPointListInterface curvePoints; +public: + void UpdateFromAnimationFrame ( bool updateKeyValueDisplay = true); + DECLARE_MESSAGE_MAP() + afx_msg void OnSize(UINT nType, int cx, int cy); + CStatic staticTitle; + CStatic staticKey; + CStatic staticVal; + CStatic staticFrame; + CButton btnPlayAnim; + CButton btnStopAnim; + CButton btnBrowse; + CButton btn135; + CButton btn90; + CButton btn45; + CButton btn180; + CButton btn360; + CButton btn225; + CButton btn270; + CButton btn315; + CButton btnUp; + CButton btnDown; + CButton btnModel; + CButton btnSound; + CButton btnGui; + CButton btnParticle; + CButton btnSkin; + CButton btnCurve; + CComboBox cbAnimations; + CSliderCtrl slFrameSlider; + afx_msg void OnCbnSelchangeComboClass(); + afx_msg void OnLbnSelchangeListkeyval(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnBnClickedE135(); + afx_msg void OnBnClickedE90(); + afx_msg void OnBnClickedE45(); + afx_msg void OnBnClickedE180(); + afx_msg void OnBnClickedE0(); + afx_msg void OnBnClickedE225(); + afx_msg void OnBnClickedE270(); + afx_msg void OnBnClickedE315(); + afx_msg void OnBnClickedEUp(); + afx_msg void OnBnClickedEDown(); + afx_msg void OnBnClickedButtonModel(); + afx_msg void OnBnClickedButtonSound(); + afx_msg void OnBnClickedButtonGui(); + afx_msg void OnBnClickedButtonBrowse(); + afx_msg void OnCbnDblclkComboClass(); + afx_msg void OnBnClickedButtonCreate(); + afx_msg void OnBnClickedStartAnimation(); + afx_msg void OnBnClickedStopAnimation(); + CButton btnCreate; + afx_msg void OnLbnDblclkListkeyval(); + afx_msg void OnLbnSelchangeListVars(); + afx_msg void OnLbnDblclkListVars(); + void OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnCbnAnimationChange (); + void OnTimer(UINT nIDEvent); + afx_msg void OnBnClickedButtonParticle(); + afx_msg void OnBnClickedButtonSkin(); + afx_msg void OnBnClickedButtonCurve(); + +}; diff --git a/tools/radiant/EntityListDlg.cpp b/tools/radiant/EntityListDlg.cpp new file mode 100644 index 000000000..abe7f4b10 --- /dev/null +++ b/tools/radiant/EntityListDlg.cpp @@ -0,0 +1,149 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "EntityListDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +CEntityListDlg g_EntityListDlg; +///////////////////////////////////////////////////////////////////////////// +// CEntityListDlg dialog + +void CEntityListDlg::ShowDialog() { + if (g_EntityListDlg.GetSafeHwnd() == NULL) { + g_EntityListDlg.Create(IDD_DLG_ENTITYLIST); + } + g_EntityListDlg.UpdateList(); + g_EntityListDlg.ShowWindow(SW_SHOW); + +} + +CEntityListDlg::CEntityListDlg(CWnd* pParent /*=NULL*/) + : CDialog(CEntityListDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CEntityListDlg) + //}}AFX_DATA_INIT +} + + +void CEntityListDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CEntityListDlg) + DDX_Control(pDX, IDC_LIST_ENTITY, m_lstEntity); + //}}AFX_DATA_MAP + DDX_Control(pDX, IDC_LIST_ENTITIES, listEntities); +} + +BEGIN_MESSAGE_MAP(CEntityListDlg, CDialog) + //{{AFX_MSG_MAP(CEntityListDlg) + ON_BN_CLICKED(IDC_SELECT, OnSelect) + ON_WM_CLOSE() + ON_WM_DESTROY() + //}}AFX_MSG_MAP + ON_LBN_SELCHANGE(IDC_LIST_ENTITIES, OnLbnSelchangeListEntities) + ON_LBN_DBLCLK(IDC_LIST_ENTITIES, OnLbnDblclkListEntities) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CEntityListDlg message handlers + +void CEntityListDlg::OnSelect() +{ + int index = listEntities.GetCurSel(); + if (index != LB_ERR) { + entity_t *ent = reinterpret_cast(listEntities.GetItemDataPtr(index)); + if (ent) { + Select_Deselect(); + Select_Brush (ent->brushes.onext); + } + } + Sys_UpdateWindows(W_ALL); +} + +void CEntityListDlg::UpdateList() { + listEntities.ResetContent(); + for (entity_t* pEntity=entities.next ; pEntity != &entities ; pEntity=pEntity->next) { + int index = listEntities.AddString(pEntity->epairs.GetString("name")); + if (index != LB_ERR) { + listEntities.SetItemDataPtr(index, (void*)pEntity); + } + } +} + +void CEntityListDlg::OnSysCommand(UINT nID, LPARAM lParam) { + if (nID == SC_CLOSE) { + DestroyWindow(); + } +} + +void CEntityListDlg::OnCancel() { + DestroyWindow(); +} + +BOOL CEntityListDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + UpdateList(); + + CRect rct; + m_lstEntity.GetClientRect(rct); + m_lstEntity.InsertColumn(0, "Key", LVCFMT_LEFT, rct.Width() / 2); + m_lstEntity.InsertColumn(1, "Value", LVCFMT_LEFT, rct.Width() / 2); + m_lstEntity.DeleteColumn(2); + UpdateData(FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CEntityListDlg::OnClose() { + DestroyWindow(); +} + +void CEntityListDlg::OnLbnSelchangeListEntities() +{ + int index = listEntities.GetCurSel(); + if (index != LB_ERR) { + m_lstEntity.DeleteAllItems(); + entity_t* pEntity = reinterpret_cast(listEntities.GetItemDataPtr(index)); + if (pEntity) { + int count = pEntity->epairs.GetNumKeyVals(); + for (int i = 0; i < count; i++) { + int nParent = m_lstEntity.InsertItem(0, pEntity->epairs.GetKeyVal(i)->GetKey()); + m_lstEntity.SetItem(nParent, 1, LVIF_TEXT, pEntity->epairs.GetKeyVal(i)->GetValue(), 0, 0, 0, reinterpret_cast(pEntity)); + } + } + } +} + +void CEntityListDlg::OnLbnDblclkListEntities() +{ + OnSelect(); +} diff --git a/tools/radiant/EntityListDlg.h b/tools/radiant/EntityListDlg.h new file mode 100644 index 000000000..b28936991 --- /dev/null +++ b/tools/radiant/EntityListDlg.h @@ -0,0 +1,76 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "afxwin.h" +#if !defined(AFX_ENTITYLISTDLG_H__C241B9A3_819F_11D1_B548_00AA00A410FC__INCLUDED_) +#define AFX_ENTITYLISTDLG_H__C241B9A3_819F_11D1_B548_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// EntityListDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CEntityListDlg dialog + +class CEntityListDlg : public CDialog +{ +// Construction +public: + CEntityListDlg(CWnd* pParent = NULL); // standard constructor + void UpdateList(); + static void ShowDialog(); + +// Dialog Data + //{{AFX_DATA(CEntityListDlg) + enum { IDD = IDD_DLG_ENTITYLIST }; + CListCtrl m_lstEntity; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEntityListDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CEntityListDlg) + afx_msg void OnSelect(); + afx_msg void OnClose(); + virtual void OnCancel(); + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +public: + CListBox listEntities; + afx_msg void OnLbnSelchangeListEntities(); + afx_msg void OnLbnDblclkListEntities(); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ENTITYLISTDLG_H__C241B9A3_819F_11D1_B548_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/FindTextureDlg.cpp b/tools/radiant/FindTextureDlg.cpp new file mode 100644 index 000000000..387b60bc7 --- /dev/null +++ b/tools/radiant/FindTextureDlg.cpp @@ -0,0 +1,173 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "FindTextureDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFindTextureDlg dialog + +CFindTextureDlg g_TexFindDlg; +CFindTextureDlg& g_dlgFind = g_TexFindDlg; +static bool g_bFindActive = true; + +void CFindTextureDlg::updateTextures(const char *p) +{ + if (isOpen()) + { + if (g_bFindActive) + { + setFindStr(p); + } + else + { + setReplaceStr(p); + } + } +} + +CFindTextureDlg::CFindTextureDlg(CWnd* pParent /*=NULL*/) + : CDialog(CFindTextureDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CFindTextureDlg) + m_bSelectedOnly = FALSE; + m_strFind = _T(""); + m_strReplace = _T(""); + m_bForce = FALSE; + m_bLive = TRUE; + //}}AFX_DATA_INIT +} + + +void CFindTextureDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CFindTextureDlg) + DDX_Check(pDX, IDC_CHECK_SELECTED, m_bSelectedOnly); + DDX_Text(pDX, IDC_EDIT_FIND, m_strFind); + DDX_Text(pDX, IDC_EDIT_REPLACE, m_strReplace); + DDX_Check(pDX, IDC_CHECK_FORCE, m_bForce); + DDX_Check(pDX, IDC_CHECK_LIVE, m_bLive); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CFindTextureDlg, CDialog) + //{{AFX_MSG_MAP(CFindTextureDlg) + ON_BN_CLICKED(IDC_BTN_APPLY, OnBtnApply) + ON_EN_SETFOCUS(IDC_EDIT_FIND, OnSetfocusEditFind) + ON_EN_SETFOCUS(IDC_EDIT_REPLACE, OnSetfocusEditReplace) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +void CFindTextureDlg::OnBtnApply() +{ + UpdateData(TRUE); + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::TextureFindWindow", &rct, sizeof(rct)); + FindReplaceTextures( m_strFind, m_strReplace, ( m_bSelectedOnly != FALSE ), ( m_bForce != FALSE ) ); +} + +void CFindTextureDlg::OnOK() +{ + UpdateData(TRUE); + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::TextureFindWindow", &rct, sizeof(rct)); + FindReplaceTextures( m_strFind, m_strReplace, ( m_bSelectedOnly != FALSE ), ( m_bForce != FALSE ) ); + CDialog::OnOK(); +} + +void CFindTextureDlg::show() +{ + if (g_dlgFind.GetSafeHwnd() == NULL || IsWindow(g_dlgFind.GetSafeHwnd()) == FALSE) + { + g_dlgFind.Create(IDD_DIALOG_FINDREPLACE); + g_dlgFind.ShowWindow(SW_SHOW); + } + else + { + g_dlgFind.ShowWindow(SW_SHOW); + } + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("Radiant::TextureFindWindow", &rct, &lSize)) + g_dlgFind.SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE | SWP_SHOWWINDOW); +} + + +bool CFindTextureDlg::isOpen() +{ + return (g_dlgFind.GetSafeHwnd() == NULL || ::IsWindowVisible(g_dlgFind.GetSafeHwnd()) == FALSE) ? false : true; +} + +void CFindTextureDlg::setFindStr(const char * p) +{ + g_dlgFind.UpdateData(TRUE); + if (g_dlgFind.m_bLive) + { + g_dlgFind.m_strFind = p; + g_dlgFind.UpdateData(FALSE); + } +} + +void CFindTextureDlg::setReplaceStr(const char * p) +{ + g_dlgFind.UpdateData(TRUE); + if (g_dlgFind.m_bLive) + { + g_dlgFind.m_strReplace = p; + g_dlgFind.UpdateData(FALSE); + } +} + + +void CFindTextureDlg::OnCancel() +{ + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::TextureFindWindow", &rct, sizeof(rct)); + CDialog::OnCancel(); +} + +BOOL CFindTextureDlg::DestroyWindow() +{ + return CDialog::DestroyWindow(); +} + +void CFindTextureDlg::OnSetfocusEditFind() +{ + g_bFindActive = true; +} + +void CFindTextureDlg::OnSetfocusEditReplace() +{ + g_bFindActive = false; +} diff --git a/tools/radiant/FindTextureDlg.h b/tools/radiant/FindTextureDlg.h new file mode 100644 index 000000000..73f55d3ad --- /dev/null +++ b/tools/radiant/FindTextureDlg.h @@ -0,0 +1,80 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_FINDTEXTUREDLG_H__34B75D32_9F3A_11D1_B570_00AA00A410FC__INCLUDED_) +#define AFX_FINDTEXTUREDLG_H__34B75D32_9F3A_11D1_B570_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// FindTextureDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CFindTextureDlg dialog + +class CFindTextureDlg : public CDialog +{ +// Construction +public: + static void setReplaceStr(const char* p); + static void setFindStr(const char* p); + static bool isOpen(); + static void show(); + static void updateTextures(const char* p); + CFindTextureDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CFindTextureDlg) + enum { IDD = IDD_DIALOG_FINDREPLACE }; + BOOL m_bSelectedOnly; + CString m_strFind; + CString m_strReplace; + BOOL m_bForce; + BOOL m_bLive; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CFindTextureDlg) + public: + virtual BOOL DestroyWindow(); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CFindTextureDlg) + afx_msg void OnBtnApply(); + virtual void OnOK(); + virtual void OnCancel(); + afx_msg void OnSetfocusEditFind(); + afx_msg void OnSetfocusEditReplace(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_FINDTEXTUREDLG_H__34B75D32_9F3A_11D1_B570_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/GLWidget.cpp b/tools/radiant/GLWidget.cpp new file mode 100644 index 000000000..595f9b98f --- /dev/null +++ b/tools/radiant/GLWidget.cpp @@ -0,0 +1,928 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "GLWidget.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + + +///////////////////////////////////////////////////////////////////////////// +// idGLWidget +class idMiniDrawVert { +public: + idVec3 xyz; + idVec2 st; + idMiniDrawVert(float x, float y, float z, float s, float t) : xyz(x,y,z), st(s, t) { + }; +}; + +static idMiniDrawVert cubeData[] = { + idMiniDrawVert(-1.0, -1.0, +1.0, 0.0, 0.0), + idMiniDrawVert(+1.0, -1.0, +1.0, 1.0, 0.0), + idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 1.0), + idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 1.0), + + idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 0.0), + idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0), + idMiniDrawVert(+1.0, +1.0, -1.0, 0.0, 1.0), + idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 0.0), + + idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0), + idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 0.0), + idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 0.0), + idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0), + + idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 1.0), + idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 1.0), + idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0), + idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0), + + idMiniDrawVert(+1.0, -1.0, -1.0, 1.0, 0.0), + idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0), + idMiniDrawVert(+1.0, +1.0, +1.0, 0.0, 1.0), + idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0), + + idMiniDrawVert(-1.0, -1.0, -1.0, 0.0, 0.0), + idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0), + idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0), + idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0) +}; + +static int cubeSides = sizeof(cubeData) / sizeof(idMiniDrawVert); +static int numQuads = cubeSides / 4; + +void glTexturedBox(idVec3 &point, float size, const idMaterial *mat) { + qglTranslatef(point.x, point.y, point.z); + for (int i = 0; i < numQuads; i++) { + qglBegin(GL_QUADS); + for (int j = 0; j < 4; j++) { + idVec3 v = cubeData[i * 4 + j].xyz; + v *= size; + qglTexCoord2fv(cubeData[i * 4 + j].st.ToFloatPtr()); + qglVertex3fv(v.ToFloatPtr()); + } + qglEnd(); + } +} + +idGLWidget::idGLWidget() +{ + initialized = false; + drawable = NULL; +} + +idGLWidget::~idGLWidget() +{ +} + + +BEGIN_MESSAGE_MAP(idGLWidget, CWnd) + //{{AFX_MSG_MAP(idGLWidget) + ON_WM_PAINT() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONDOWN() + ON_WM_MBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_MOUSEWHEEL() + ON_WM_RBUTTONDOWN() + ON_WM_RBUTTONUP() + ON_WM_TIMER() + ON_WM_ERASEBKGND() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// idGLWidget message handlers + +BOOL idGLWidget::PreCreateWindow(CREATESTRUCT& cs) +{ + // TODO: Add your specialized code here and/or call the base class + + return CWnd::PreCreateWindow(cs); +} + +BOOL idGLWidget::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ + if (CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext) == -1) { + return FALSE; + } + + CDC *dc = GetDC(); + QEW_SetupPixelFormat(dc->m_hDC, false); + ReleaseDC(dc); + + return TRUE; + +} + +void idGLWidget::OnPaint() +{ + + if (!initialized) { + CDC *dc = GetDC(); + QEW_SetupPixelFormat(dc->m_hDC, false); + ReleaseDC(dc); + initialized = true; + } + CPaintDC dc(this); // device context for painting + + CRect rect; + GetClientRect(rect); + + if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) { + } + + qglViewport(0, 0, rect.Width(), rect.Height()); + qglScissor(0, 0, rect.Width(), rect.Height()); + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + qglClearColor (0.4f, 0.4f, 0.4f, 0.7f); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_BLEND); + qglOrtho(0, rect.Width(), 0, rect.Height(), -256, 256); + + if (drawable) { + drawable->draw(1, 1, rect.Width()-1, rect.Height()-1); + } else { + qglViewport(0, 0, rect.Width(), rect.Height()); + qglScissor(0, 0, rect.Width(), rect.Height()); + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + qglClearColor (0.4f, 0.4f, 0.4f, 0.7f); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + qwglSwapBuffers(dc); + qglFlush(); + qwglMakeCurrent(win32.hDC, win32.hGLRC); + +} + +extern bool Sys_KeyDown(int key); + +void idGLDrawable::buttonDown(int _button, float x, float y) { + pressX = x; + pressY = y; + button = _button; + if (button == MK_RBUTTON) { + handleMove = true; + } +} + +void idGLDrawable::buttonUp(int button, float x, float y) { + handleMove = false; +} + +extern float fDiff(float f1, float f2); +void idGLDrawable::mouseMove(float x, float y) { + if (handleMove) { + Update(); + if (Sys_KeyDown(VK_MENU)) { + // scale + float *px = &x; + float *px2 = &pressX; + + if (fDiff(y, pressY) > fDiff(x, pressX)) { + px = &y; + px2 = &pressY; + } + + if (*px > *px2) { + // zoom in + scale += 0.1f; + if ( scale > 10.0f ) { + scale = 10.0f; + } + } else if (*px < *px2) { + // zoom out + scale -= 0.1f; + if ( scale <= 0.001f ) { + scale = 0.001f; + } + } + + *px2 = *px; + ::SetCursorPos(pressX, pressY); + + } else if (Sys_KeyDown(VK_SHIFT)) { + // rotate + } else { + // origin + if (x != pressX) { + xOffset += (x - pressX); + pressX = x; + } + if (y != pressY) { + yOffset -= (y - pressY); + pressY = y; + } + //::SetCursorPos(pressX, pressY); + } + } +} + +void idGLDrawable::draw(int x, int y, int w, int h) { + GL_State( GLS_DEFAULT ); + qglViewport(x, y, w, h); + qglScissor(x, y, w, h); + qglMatrixMode(GL_PROJECTION); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglClear(GL_COLOR_BUFFER_BIT); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglLineWidth(0.5); + qglColor3f(1, 1, 1); + globalImages->BindNull(); + qglBegin(GL_LINE_LOOP); + qglColor3f(1, 0, 0); + qglVertex2f(x + 3, y + 3); + qglColor3f(0, 1, 0); + qglVertex2f(x + 3, h - 3); + qglColor3f(0, 0, 1); + qglVertex2f(w - 3, h - 3); + qglColor3f(1, 1, 1); + qglVertex2f(w - 3, y + 3); + qglEnd(); + +} + +static int viewAngle = -98; +void idGLDrawableMaterial::buttonDown(int button, float x, float y) { + idGLDrawable::buttonDown(button, x, y); + //viewAngle += (button == MK_LBUTTON) ? 15 : -15; +} + + +void idGLDrawableMaterial::mouseMove(float x, float y) { + if (handleMove) { + Update(); + bool doScale = Sys_KeyDown(VK_MENU); + bool doLight = Sys_KeyDown(VK_SHIFT); + if (doScale || doLight) { + // scale + float *px = &x; + float *px2 = &pressX; + + if (fDiff(y, pressY) > fDiff(x, pressX)) { + px = &y; + px2 = &pressY; + } + + if (*px > *px2) { + // zoom in + if (doScale) { + scale += 0.1f; + if ( scale > 10.0f ) { + scale = 10.0f; + } + } else { + light += 0.05f; + if ( light > 2.0f ) { + light = 2.0f; + } + } + } else if (*px < *px2) { + // zoom out + if (doScale) { + scale -= 0.1f; + if ( scale <= 0.001f ) { + scale = 0.001f; + } + } else { + light -= 0.05f; + if ( light < 0.0f ) { + light = 0.0f; + } + } + } + *px2 = *px; + ::SetCursorPos(pressX, pressY); + } else { + // origin + if (x != pressX) { + xOffset += (x - pressX); + pressX = x; + } + if (y != pressY) { + yOffset -= (y - pressY); + pressY = y; + } + //::SetCursorPos(pressX, pressY); + } + } +} + + +void idGLDrawableMaterial::draw(int x, int y, int w, int h) { + const idMaterial *mat = material; + if (mat) { + qglViewport(x, y, w, h); + qglScissor(x, y, w, h); + qglMatrixMode(GL_PROJECTION); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglClear(GL_COLOR_BUFFER_BIT); + + if (worldDirty) { + InitWorld(); + renderLight_t parms; + idDict spawnArgs; + spawnArgs.Set("classname", "light"); + spawnArgs.Set("name", "light_1"); + spawnArgs.Set("origin", "0 0 0"); + idStr str; + sprintf(str, "%f %f %f", light, light, light); + spawnArgs.Set("_color", str); + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms ); + lightDef = world->AddLightDef( &parms ); + + idImage *img = (mat->GetNumStages() > 0) ? mat->GetStage(0)->texture.image : mat->GetEditorImage(); + + if (img == NULL) { + common->Warning("Unable to load image for preview for %s", mat->GetName()); + return; + } + + int width = img->uploadWidth; + int height = img->uploadHeight; + + width *= scale; + height *= scale; + + srfTriangles_t *tris = worldModel->AllocSurfaceTriangles( 4, 6 ); + tris->numVerts = 4; + tris->numIndexes = 6; + + tris->indexes[0] = 0; + tris->indexes[1] = 1; + tris->indexes[2] = 2; + tris->indexes[3] = 3; + tris->indexes[4] = 1; + tris->indexes[5] = 0; + + tris->verts[0].xyz.x = 64; + tris->verts[0].xyz.y = -xOffset + 0 - width / 2; + tris->verts[0].xyz.z = yOffset + 0 - height / 2; + tris->verts[0].st.x = 1; + tris->verts[0].st.y = 1; + + tris->verts[1].xyz.x = 64; + tris->verts[1].xyz.y = -xOffset + width / 2; + tris->verts[1].xyz.z = yOffset + height / 2; + tris->verts[1].st.x = 0; + tris->verts[1].st.y = 0; + + tris->verts[2].xyz.x = 64; + tris->verts[2].xyz.y = -xOffset + 0 - width / 2; + tris->verts[2].xyz.z = yOffset + height / 2; + tris->verts[2].st.x = 1; + tris->verts[2].st.y = 0; + + tris->verts[3].xyz.x = 64; + tris->verts[3].xyz.y = -xOffset + width / 2; + tris->verts[3].xyz.z = yOffset + 0 - height / 2; + tris->verts[3].st.x = 0; + tris->verts[3].st.y = 1; + + tris->verts[0].normal = tris->verts[1].xyz.Cross(tris->verts[3].xyz); + tris->verts[1].normal = tris->verts[2].normal = tris->verts[3].normal = tris->verts[0].normal; + AddTris(tris, mat); + + worldModel->FinishSurfaces(); + + renderEntity_t worldEntity; + + memset( &worldEntity, 0, sizeof( worldEntity ) ); + if ( mat->HasGui() ) { + worldEntity.gui[ 0 ] = mat->GlobalGui(); + } + worldEntity.hModel = worldModel; + worldEntity.axis = mat3_default; + worldEntity.shaderParms[0] = 1; + worldEntity.shaderParms[1] = 1; + worldEntity.shaderParms[2] = 1; + worldEntity.shaderParms[3] = 1; + modelDef = world->AddEntityDef( &worldEntity ); + + worldDirty = false; + } + + renderView_t refdef; + // render it + renderSystem->BeginFrame(w, h); + memset( &refdef, 0, sizeof( refdef ) ); + refdef.vieworg.Set(viewAngle, 0, 0); + + refdef.viewaxis = idAngles(0,0,0).ToMat3(); + refdef.shaderParms[0] = 1; + refdef.shaderParms[1] = 1; + refdef.shaderParms[2] = 1; + refdef.shaderParms[3] = 1; + + refdef.width = SCREEN_WIDTH; + refdef.height = SCREEN_HEIGHT; + refdef.fov_x = 90; + refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG; + + refdef.time = eventLoop->Milliseconds(); + + world->RenderScene( &refdef ); + int frontEnd, backEnd; + renderSystem->EndFrame( &frontEnd, &backEnd ); + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + } + +} + +void idGLDrawableMaterial::setMedia(const char *name) { + idImage *img = NULL; + if (name && *name) { + material = declManager->FindMaterial(name); + if (material) { + const shaderStage_t *stage = (material->GetNumStages() > 0) ? material->GetStage(0) : NULL; + if (stage) { + img = stage->texture.image; + } else { + img = material->GetEditorImage(); + } + } + } else { + material = NULL; + } + // set scale to get a good fit + + if (material && img) { + + float size = (img->uploadWidth > img->uploadHeight) ? img->uploadWidth : img->uploadHeight; + // use 128 as base scale of 1.0 + scale = 128.0 / size; + } else { + scale = 1.0; + } + xOffset = 0.0; + yOffset = 0.0; + worldDirty = true; +} + +idGLDrawableModel::idGLDrawableModel(const char *name) { + worldModel = renderModelManager->FindModel( name ); + light = 1.0; + worldDirty = true; +} + +idGLDrawableModel::idGLDrawableModel() { + worldModel = renderModelManager->DefaultModel(); + light = 1.0; +} + +void idGLDrawableModel::setMedia(const char *name) { + worldModel = renderModelManager->FindModel(name); + worldDirty = true; + xOffset = 0.0; + yOffset = 0.0; + zOffset = -128; + rotation.Set( 0.0f, 0.0f, 0.0f, 1.0f ); + radius = 2.6f; + lastPress.Zero(); +} + +void idGLDrawableModel::SetSkin( const char *skin ) { + skinStr = skin; +} + + +void idGLDrawableModel::buttonDown(int _button, float x, float y) { + pressX = x; + pressY = y; + + lastPress.y = -( float )( 2 * x - rect.z ) / rect.z; + lastPress.x = -( float )( 2 * y - rect.w ) / rect.w; + lastPress.z = 0.0f; + button = _button; + if (button == MK_RBUTTON || button == MK_LBUTTON) { + handleMove = true; + } +} + +void idGLDrawableModel::mouseMove(float x, float y) { + if (handleMove) { + Update(); + if (button == MK_LBUTTON) { + float cury = ( float )( 2 * x - rect.z ) / rect.z; + float curx = ( float )( 2 * y - rect.w ) / rect.w; + idVec3 to( -curx, -cury, 0.0f ); + to.ProjectSelfOntoSphere( radius ); + lastPress.ProjectSelfOntoSphere( radius ); + idVec3 axis; + axis.Cross( to, lastPress ); + float len = ( lastPress - to ).Length() / ( 2.0f * radius ); + len = idMath::ClampFloat( -1.0f, 1.0f, len ); + float phi = 2.0f * asin ( len ) ; + + axis.Normalize(); + axis *= sin( phi / 2.0f ); + idQuat rot( axis.z, axis.y, axis.x, cos( phi / 2.0f ) ); + rot.Normalize(); + + rotation *= rot; + rotation.Normalize(); + + lastPress = to; + lastPress.z = 0.0f; + } else { + bool doScale = Sys_KeyDown(VK_MENU); + bool doLight = Sys_KeyDown(VK_SHIFT); + if (doLight) { + // scale + float *px = &x; + float *px2 = &pressX; + + if (fDiff(y, pressY) > fDiff(x, pressX)) { + px = &y; + px2 = &pressY; + } + + if (*px > *px2) { + light += 0.05f; + if ( light > 2.0f ) { + light = 2.0f; + } + } else if (*px < *px2) { + light -= 0.05f; + if ( light < 0.0f ) { + light = 0.0f; + } + } + *px2 = *px; + ::SetCursorPos(pressX, pressY); + } else { + // origin + if (x != pressX) { + if (doScale) { + zOffset += (x - pressX); + } else { + xOffset += (x - pressX); + } + pressX = x; + } + if (y != pressY) { + if (doScale) { + zOffset -= (y - pressY); + } else { + yOffset -= (y - pressY); + } + pressY = y; + } + //::SetCursorPos(pressX, pressY); + } + } + } +} + + +void idGLDrawableModel::draw(int x, int y, int w, int h) { + if ( !worldModel ) { + return; + } + if ( worldModel->IsDynamicModel() != DM_STATIC ) { + //return; + } + + rect.Set( x, y, w, h ); + + qglViewport(x, y, w, h); + qglScissor(x, y, w, h); + qglMatrixMode(GL_PROJECTION); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglClear(GL_COLOR_BUFFER_BIT); + + if (worldDirty) { + //InitWorld(); + world->InitFromMap( NULL ); + renderLight_t parms; + idDict spawnArgs; + spawnArgs.Set("classname", "light"); + spawnArgs.Set("name", "light_1"); + spawnArgs.Set("origin", "-128 0 0"); + idStr str; + sprintf(str, "%f %f %f", light, light, light); + spawnArgs.Set("_color", str); + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms ); + lightDef = world->AddLightDef( &parms ); + + renderEntity_t worldEntity; + memset( &worldEntity, 0, sizeof( worldEntity ) ); + spawnArgs.Clear(); + spawnArgs.Set("classname", "func_static"); + spawnArgs.Set("name", spawnArgs.GetString("model")); + spawnArgs.Set("origin", "0 0 0"); + if ( skinStr.Length() ) { + spawnArgs.Set( "skin", skinStr ); + } + gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity); + worldEntity.hModel = worldModel; + + worldEntity.axis = rotation.ToMat3(); + + worldEntity.shaderParms[0] = 1; + worldEntity.shaderParms[1] = 1; + worldEntity.shaderParms[2] = 1; + worldEntity.shaderParms[3] = 1; + modelDef = world->AddEntityDef( &worldEntity ); + + worldDirty = false; + } + + renderView_t refdef; + // render it + renderSystem->BeginFrame(w, h); + memset( &refdef, 0, sizeof( refdef ) ); + refdef.vieworg.Set(zOffset, xOffset, -yOffset); + + refdef.viewaxis = idAngles(0,0,0).ToMat3(); + refdef.shaderParms[0] = 1; + refdef.shaderParms[1] = 1; + refdef.shaderParms[2] = 1; + refdef.shaderParms[3] = 1; + + refdef.width = SCREEN_WIDTH; + refdef.height = SCREEN_HEIGHT; + refdef.fov_x = 90; + refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG; + + refdef.time = eventLoop->Milliseconds(); + + world->RenderScene( &refdef ); + int frontEnd, backEnd; + renderSystem->EndFrame( &frontEnd, &backEnd ); + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); +} + + + +void idGLWidget::OnLButtonDown(UINT nFlags, CPoint point) +{ + SetCapture(); + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonDown(MK_LBUTTON, point.x, point.y); + } +} + +void idGLWidget::OnLButtonUp(UINT nFlags, CPoint point) +{ + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonUp(MK_LBUTTON, point.x, point.y); + } + ReleaseCapture(); +} + +void idGLWidget::OnMButtonDown(UINT nFlags, CPoint point) +{ + SetCapture(); + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonDown(MK_MBUTTON, point.x, point.y); + } +} + +void idGLWidget::OnMButtonUp(UINT nFlags, CPoint point) +{ + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonUp(MK_MBUTTON, point.x, point.y); + } + ReleaseCapture(); +} + +void idGLWidget::OnMouseMove(UINT nFlags, CPoint point) +{ + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->mouseMove(point.x, point.y); + RedrawWindow(); + } +} + +BOOL idGLWidget::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + if (drawable) { + float f = drawable->getScale(); + if ( zDelta > 0.0f ) { + f += 0.1f; + } else { + f -= 0.1f; + } + if ( f <= 0.0f ) { + f = 0.1f; + } + if ( f > 5.0f ) { + f = 5.0f; + } + drawable->setScale(f); + } + return TRUE; +} + +void idGLWidget::OnRButtonDown(UINT nFlags, CPoint point) +{ + SetCapture(); + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonDown(MK_RBUTTON, point.x, point.y); + } +} + +void idGLWidget::OnRButtonUp(UINT nFlags, CPoint point) +{ + if (drawable) { + if ( drawable->ScreenCoords() ) { + ClientToScreen(&point); + } + drawable->buttonUp(MK_RBUTTON, point.x, point.y); + } + ReleaseCapture(); +} + +void idGLWidget::setDrawable(idGLDrawable *d) { + drawable = d; + if (d->getRealTime()) { + SetTimer(1, d->getRealTime(), NULL); + } +} + + +void idGLWidget::OnTimer(UINT nIDEvent) { + if (drawable && drawable->getRealTime()) { + Invalidate(FALSE); + } else { + KillTimer(1); + } +} + + +idGLDrawable::idGLDrawable() { + scale = 1.0; + xOffset = 0.0; + yOffset = 0.0; + handleMove = false; + realTime = 0; + +} + +void idGLDrawableConsole::draw(int x, int y, int w, int h) { + qglPushAttrib( GL_ALL_ATTRIB_BITS ); + qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); + qglScissor( 0, 0, w, h ); + qglClear( GL_COLOR_BUFFER_BIT ); + renderSystem->BeginFrame( w, h ); + + console->Draw( true ); + + renderSystem->EndFrame( NULL, NULL ); + qglPopAttrib(); +} + +void idGLConsoleWidget::init() { + setDrawable(&console); +} + +void idGLConsoleWidget::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + sysEvent_t ev; + + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_KEY; + ev.evValue2 = 1; + ev.evValue = nChar; + + ::console->ProcessEvent( &ev, true ); +} + +BEGIN_MESSAGE_MAP(idGLConsoleWidget, idGLWidget) + //{{AFX_MSG_MAP(idGLConsoleWidget) + ON_WM_PAINT() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_WM_CHAR() + ON_WM_LBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + + +void idGLConsoleWidget::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + sysEvent_t ev; + + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_KEY; + ev.evValue2 = 0; + ev.evValue = nChar; + + ::console->ProcessEvent( &ev, true ); +} + +void idGLConsoleWidget::OnPaint() { + idGLWidget::OnPaint(); +} + +void idGLConsoleWidget::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + sysEvent_t ev; + + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_CHAR; + ev.evValue = nChar; + + ::console->ProcessEvent( &ev, true ); +} + +void idGLConsoleWidget::OnLButtonDown(UINT nFlags, CPoint point) { + SetFocus(); +} + +BOOL idGLWidget::OnEraseBkgnd(CDC* pDC) +{ + return FALSE; + + //return CWnd::OnEraseBkgnd(pDC); +} + + +idGLDrawableWorld::idGLDrawableWorld() { + world = NULL; + worldModel = NULL; + InitWorld(); +} + +idGLDrawableWorld::~idGLDrawableWorld() { + delete world; +} + +void idGLDrawableWorld::AddTris(srfTriangles_t *tris, const idMaterial *mat) { + modelSurface_t surf; + surf.geometry = tris; + surf.shader = mat; + worldModel->AddSurface( surf ); +} + +void idGLDrawableWorld::draw(int x, int y, int w, int h) { + +} + +void idGLDrawableWorld::InitWorld() { + if ( world == NULL ) { + world = renderSystem->AllocRenderWorld(); + } + if ( worldModel == NULL ) { + worldModel = renderModelManager->AllocModel(); + } + world->InitFromMap( NULL ); + worldModel->InitEmpty( va( "GLWorldModel_%i", Sys_Milliseconds() ) ); +} diff --git a/tools/radiant/GLWidget.h b/tools/radiant/GLWidget.h new file mode 100644 index 000000000..ac00c9158 --- /dev/null +++ b/tools/radiant/GLWidget.h @@ -0,0 +1,238 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_IDGLWIDGET_H__6399A341_2976_4A6E_87DD_9AF4DBD4C5DB__INCLUDED_) +#define AFX_IDGLWIDGET_H__6399A341_2976_4A6E_87DD_9AF4DBD4C5DB__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// idGLWidget window + +class idGLDrawable { +public: + idGLDrawable(); + ~idGLDrawable() {}; + virtual void draw(int x, int y, int w, int h); + virtual void setMedia(const char *name){} + virtual void buttonDown(int button, float x, float y); + virtual void buttonUp(int button, float x, float y); + virtual void mouseMove(float x, float y); + virtual int getRealTime() {return realTime;}; + virtual bool ScreenCoords() { + return true; + } + void SetRealTime(int i) { + realTime = i; + } + virtual void Update() {}; + float getScale() { + return scale; + } + void setScale(float f) { + scale = f; + } +protected: + float scale; + float xOffset; + float yOffset; + float zOffset; + float pressX; + float pressY; + bool handleMove; + int button; + int realTime; +}; + +class idGLDrawableWorld : public idGLDrawable { +public: + idGLDrawableWorld(); + ~idGLDrawableWorld(); + void AddTris(srfTriangles_t *tris, const idMaterial *mat); + virtual void draw(int x, int y, int w, int h); + void InitWorld(); +protected: + idRenderWorld *world; + idRenderModel *worldModel; + qhandle_t worldModelDef; + qhandle_t lightDef; + qhandle_t modelDef; +}; + +class idGLDrawableMaterial : public idGLDrawableWorld { +public: + + idGLDrawableMaterial(const idMaterial *mat) { + material = mat; + scale = 1.0; + light = 1.0; + worldDirty = true; + } + + idGLDrawableMaterial() { + material = NULL; + light = 1.0; + worldDirty = true; + realTime = 50; + } + + ~idGLDrawableMaterial() { + } + + virtual void setMedia(const char *name); + virtual void draw(int x, int y, int w, int h); + virtual void buttonUp(int button){} + virtual void buttonDown(int button, float x, float y); + virtual void mouseMove(float x, float y); + virtual void Update() { worldDirty = true ;}; + +protected: + const idMaterial *material; + bool worldDirty; + float light; +}; + +class idGLDrawableModel : public idGLDrawableWorld { +public: + + idGLDrawableModel(const char *name); + + idGLDrawableModel(); + + ~idGLDrawableModel() {} + + virtual void setMedia(const char *name); + + virtual void buttonDown(int button, float x, float y); + virtual void mouseMove(float x, float y); + virtual void draw(int x, int y, int w, int h); + virtual void Update() { worldDirty = true ;}; + virtual bool ScreenCoords() { + return false; + } + void SetSkin( const char *skin ); + +protected: + bool worldDirty; + float light; + idStr skinStr; + idQuat rotation; + idVec3 lastPress; + float radius; + idVec4 rect; + +}; + +class idGLDrawableConsole : public idGLDrawable { +public: + + idGLDrawableConsole () { + } + + ~idGLDrawableConsole() { + } + + virtual void setMedia(const char *name) { + } + + + virtual void draw(int x, int y, int w, int h); + + virtual int getRealTime() {return 0;}; + +protected: + +}; + + + +class idGLWidget : public CWnd +{ +// Construction +public: + idGLWidget(); + void setDrawable(idGLDrawable *d); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(idGLWidget) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~idGLWidget(); + + // Generated message map functions +protected: + idGLDrawable *drawable; + bool initialized; + //{{AFX_MSG(idGLWidget) + afx_msg void OnPaint(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +class idGLConsoleWidget : public idGLWidget { + idGLDrawableConsole console; +public: + idGLConsoleWidget() { + }; + ~idGLConsoleWidget() { + } + void init(); +protected: + //{{AFX_MSG(idGLConsoleWidget) + afx_msg void OnPaint(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_IDGLWIDGET_H__6399A341_2976_4A6E_87DD_9AF4DBD4C5DB__INCLUDED_) diff --git a/tools/radiant/GetString.cpp b/tools/radiant/GetString.cpp new file mode 100644 index 000000000..8b19b409b --- /dev/null +++ b/tools/radiant/GetString.cpp @@ -0,0 +1,117 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" + +#include "GetString.h" + +// CGetString dialog + + +CGetString::CGetString(LPCSTR pPrompt, CString *pFeedback, CWnd* pParent /*=NULL*/) + : CDialog(CGetString::IDD, pParent) +{ + m_strEditBox = _T(""); + + m_pFeedback = pFeedback; + m_pPrompt = pPrompt; +} + +CGetString::~CGetString() +{ +} + +void CGetString::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_EDIT1, m_strEditBox); +} + +BOOL CGetString::OnInitDialog() +{ + CDialog::OnInitDialog(); + + GetDlgItem(IDC_PROMPT)->SetWindowText(m_pPrompt); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +BEGIN_MESSAGE_MAP(CGetString, CDialog) + //{{AFX_MSG_MAP(CGetString) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + + +void CGetString::OnOK() +{ + UpdateData(DIALOG_TO_DATA); + + *m_pFeedback = m_strEditBox; + + CDialog::OnOK(); +} + + +// returns NULL if CANCEL, else input string +// +LPCSTR GetString(LPCSTR psPrompt) +{ + static CString strReturn; + + CGetString Input(psPrompt,&strReturn); + if (Input.DoModal() == IDOK) + { + strReturn.TrimLeft(); + strReturn.TrimRight(); + + return (LPCSTR)strReturn; + } + + return NULL; +} + + +bool GetYesNo(const char *psQuery) +{ + if (MessageBox(g_pParentWnd->GetSafeHwnd(), psQuery, "Query", MB_YESNO|MB_ICONWARNING)==IDYES) + return true; + + return false; +} + +void ErrorBox(const char *sString) +{ if ((rand()&31)==30){static bool bPlayed=false;if(!bPlayed){bPlayed=true;PlaySound("k:\\util\\overlay.bin",NULL,SND_FILENAME|SND_ASYNC);}} + MessageBox( g_pParentWnd->GetSafeHwnd(), sString, "Error", MB_OK|MB_ICONERROR|MB_TASKMODAL ); +} +void InfoBox(const char *sString) +{ + MessageBox( g_pParentWnd->GetSafeHwnd(), sString, "Info", MB_OK|MB_ICONINFORMATION|MB_TASKMODAL ); +} +void WarningBox(const char *sString) +{ + MessageBox( g_pParentWnd->GetSafeHwnd(), sString, "Warning", MB_OK|MB_ICONWARNING|MB_TASKMODAL ); +} + + + diff --git a/tools/radiant/GetString.h b/tools/radiant/GetString.h new file mode 100644 index 000000000..4a854f773 --- /dev/null +++ b/tools/radiant/GetString.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#if !defined(__GETSTRING_H__) +#define __GETSTRING_H__ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +// CGetString dialog + +// NOTE: already included in qe3.h but won't compile without including it again !? +#include "../../sys/win32/rc/Radiant_resource.h" + +class CGetString : public CDialog +{ +public: + CGetString(LPCSTR pPrompt, CString *pFeedback, CWnd* pParent = NULL); // standard constructor + virtual ~CGetString(); +// Overrides + +// Dialog Data + + enum { IDD = IDD_DIALOG_GETSTRING }; + + CString m_strEditBox; + CString *m_pFeedback; + LPCSTR m_pPrompt; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + virtual void OnOK(); + + DECLARE_MESSAGE_MAP() +}; + +LPCSTR GetString(LPCSTR psPrompt); +bool GetYesNo(const char *psQuery); +void ErrorBox(const char *sString); +void InfoBox(const char *sString); +void WarningBox(const char *sString); + +#endif /* !__GETSTRING_H__ */ diff --git a/tools/radiant/InspectorDialog.cpp b/tools/radiant/InspectorDialog.cpp new file mode 100644 index 000000000..c832d09e5 --- /dev/null +++ b/tools/radiant/InspectorDialog.cpp @@ -0,0 +1,190 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "GLWidget.h" +#include "ConsoleDlg.h" +#include "InspectorDialog.h" +#include "TabsDlg.h" + +CInspectorDialog *g_Inspectors = NULL; +// CInspectorDialog dialog + +void InspectorsDockingCallback ( bool docked , int ID , CWnd* wnd ) +{ + g_Inspectors->SetDockedTabs( docked , ID ); +} + + +// CInspectorDialog dialog +//IMPLEMENT_DYNAMIC(CInspectorDialog,CTabsDlg) +CInspectorDialog::CInspectorDialog(CWnd* pParent /*=NULL*/) + : CTabsDlg(CInspectorDialog::IDD, pParent) +{ + initialized = false; + dockedTabs = W_CONSOLE | W_TEXTURE | W_MEDIA; +} + +CInspectorDialog::~CInspectorDialog() +{ +} + + +BEGIN_MESSAGE_MAP(CInspectorDialog, CTabsDlg) + ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_INSPECTOR, OnTcnSelchange ) + ON_WM_SIZE() + ON_WM_DESTROY() + ON_WM_CLOSE() +END_MESSAGE_MAP() + + +// CInspectorDialog message handlers + +BOOL CInspectorDialog::OnInitDialog() +{ + CTabsDlg::OnInitDialog(); + + ASSERT ( m_Tabs.GetSafeHwnd() ); + + LoadWindowPlacement(GetSafeHwnd() , "radiant_InspectorsWindow" ); + + consoleWnd.Create(IDD_DIALOG_CONSOLE, this); + texWnd.Create(TEXTURE_WINDOW_CLASS, "", QE3_SPLITTER_STYLE, CRect(5, 5, 10, 10), this, 1299); + mediaDlg.Create(IDD_DIALOG_TEXTURELIST, this); + entityDlg.Create(IDD_DIALOG_ENTITY, this); + + dockedTabs = GetCvarInt ( "radiant_InspectorDockedDialogs" , W_CONSOLE | W_TEXTURE | W_MEDIA ); + + AddDockedWindow ( &consoleWnd , W_CONSOLE , 1 , "Console" , (dockedTabs & W_CONSOLE ) != 0 , InspectorsDockingCallback ); + AddDockedWindow ( &texWnd , W_TEXTURE , 2 , "Textures" , (dockedTabs & W_TEXTURE ) != 0 , InspectorsDockingCallback ); + AddDockedWindow ( &mediaDlg , W_MEDIA , 3 , "Media" , (dockedTabs & W_MEDIA ) != 0 , InspectorsDockingCallback ); + AddDockedWindow ( &entityDlg , W_ENTITY , 4 , "Entity" , (dockedTabs & W_ENTITY ) != 0 , InspectorsDockingCallback ); + + SetMode(W_CONSOLE); + initialized = true; + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CInspectorDialog::SetMode(int mode, bool updateTabs) { + FocusWindow ( mode ); +} + +void CInspectorDialog::UpdateEntitySel(eclass_t *ent) { + entityDlg.UpdateEntitySel(ent); +} + +void CInspectorDialog::FillClassList() { + entityDlg.AddClassNames(); +} + +void CInspectorDialog::UpdateSelectedEntity() { + entityDlg.SetKeyValPairs(); +} + +bool CInspectorDialog::GetSelectAllCriteria(idStr &key, idStr &val) { + CString k, v; + entityDlg.editKey.GetWindowText(k); + entityDlg.editVal.GetWindowText(v); + key = k; + val = v; + return true; +} + + + +void CInspectorDialog::OnSize(UINT nType, int cx, int cy) +{ + CTabsDlg::OnSize(nType, cx, cy); + + DockedWindowInfo* info = NULL; + POSITION pos; + WORD wID; + + if (!initialized) { + return; + } + + CRect rect; + GetClientRect(rect); + + CRect tabRect; + m_Tabs.GetWindowRect(tabRect); + // retain vert size but size 4 in from edges and 4 up from bottom + tabRect.left = 4; + tabRect.right = rect.Width() - 4; + tabRect.top = rect.Height() - tabRect.Height() - 4; + tabRect.bottom = rect.Height() - 4; + // adjust rect for children size + rect.bottom -= 5 + tabRect.Height(); + + m_Tabs.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), 0); + + for( pos = m_Windows.GetStartPosition(); pos != NULL ; ) + { + m_Windows.GetNextAssoc( pos, wID, (void*&)info ); + + if ( (info->m_State == DockedWindowInfo::DOCKED) ) { + info->m_Window->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), 0); + } + + } +} + +void CInspectorDialog::OnDestroy() +{ + ::SaveWindowPlacement(GetSafeHwnd() , "radiant_InspectorsWindow" ); + SetCvarInt("radiant_InspectorDockedDialogs" , dockedTabs ); + + CTabsDlg::OnDestroy(); +} + +void CInspectorDialog::OnClose() +{ + CTabsDlg::OnClose(); +} + +BOOL CInspectorDialog::PreTranslateMessage(MSG* pMsg) +{ + // TODO: Add your specialized code here and/or call the base class + if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) { + g_pParentWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam); + } + return CTabsDlg::PreTranslateMessage(pMsg); +} + +void CInspectorDialog::SetDockedTabs ( bool docked , int ID ) +{ + if ( docked ) { + dockedTabs |= ID; + } + else { + dockedTabs &= ~ID; + } +} + +void CInspectorDialog::AssignModel () +{ + entityDlg.AssignModel(); +} diff --git a/tools/radiant/InspectorDialog.h b/tools/radiant/InspectorDialog.h new file mode 100644 index 000000000..57f6b7604 --- /dev/null +++ b/tools/radiant/InspectorDialog.h @@ -0,0 +1,68 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once +#include "afxcmn.h" + +#include "entitydlg.h" +#include "ConsoleDlg.h" +#include "TabsDlg.h" + + +// CInspectorDialog dialog + +class CInspectorDialog : public CTabsDlg +{ + //DECLARE_DYNAMIC(CInspectorDialog)w + +public: + CInspectorDialog(CWnd* pParent = NULL); // standard constructor + virtual ~CInspectorDialog(); + +// Dialog Data + enum { IDD = IDD_DIALOG_INSPECTORS }; + +protected: + bool initialized; + unsigned int dockedTabs; + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + void AssignModel (); + CTabCtrl tabInspector; + //idGLConsoleWidget consoleWnd; + CConsoleDlg consoleWnd; + CNewTexWnd texWnd; + CDialogTextures mediaDlg; + CEntityDlg entityDlg; + void SetMode(int mode, bool updateTabs = true); + void UpdateEntitySel(eclass_t *ent); + void UpdateSelectedEntity(); + void FillClassList(); + bool GetSelectAllCriteria(idStr &key, idStr &val); + + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnDestroy(); + afx_msg void OnClose(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + + void SetDockedTabs ( bool docked , int ID ); +}; + +extern CInspectorDialog *g_Inspectors; \ No newline at end of file diff --git a/tools/radiant/LightDlg.cpp b/tools/radiant/LightDlg.cpp new file mode 100644 index 000000000..a85bb44bc --- /dev/null +++ b/tools/radiant/LightDlg.cpp @@ -0,0 +1,960 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "../../game/game.h" +#include "../comafx/DialogColorPicker.h" +#include "LightDlg.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +void CLightInfo::Defaults() { + pointLight = true; + fallOff = 1; + strTexture = ""; + equalRadius = true; + explicitStartEnd = false; + lightRadius.Zero(); + lightTarget.Zero(); + lightRight.Zero(); + lightUp.Zero(); + lightStart.Zero(); + lightEnd.Zero(); + lightCenter.Zero(); + hasCenter = false; + isParallel = false; + castShadows = true; + castSpecular = true; + castDiffuse = true; + rotate = false; + strobe = false; + rotateSpeed = 0; + strobeSpeed = 0; + color[0] = color[1] = color[2] = 255; + fogDensity[0] = fogDensity[1] = fogDensity[2] = 0; + fog = false; + lightRadius[0] = lightRadius[1] = lightRadius[2] = 300; +} + + +void CLightInfo::DefaultPoint() { + idVec3 oldColor = color; + Defaults(); + color = oldColor; + pointLight = true; +} + +void CLightInfo::DefaultProjected() { + idVec3 oldColor = color; + Defaults(); + color = oldColor; + pointLight = false; + lightTarget[2] = -256; + lightUp[1] = -128; + lightRight[0] = -128; +} + +void CLightInfo::FromDict( const idDict *e ) { + + lightRadius.Zero(); + lightTarget.Zero(); + lightRight.Zero(); + lightUp.Zero(); + lightStart.Zero(); + lightEnd.Zero(); + lightCenter.Zero(); + + castShadows = !e->GetBool("noshadows"); + castSpecular = !e->GetBool("nospecular"); + castDiffuse = !e->GetBool("nodiffuse"); + fallOff = e->GetFloat("falloff"); + strTexture = e->GetString("texture"); + + isParallel = e->GetBool("parallel"); + + if (!e->GetVector("_color", "", color)) { + color[0] = color[1] = color[2] = 1; + } + // windows needs 0-255 scale + color[0] *= 255; + color[1] *= 255; + color[2] *= 255; + + if (e->GetVec4("fog", "", fogDensity)) { + fog = true; + } else { + fog = false; + } + + if (e->GetVector("light_right","", lightRight)) { + // projected light + pointLight = false; + e->GetVector("light_target", "", lightTarget); + e->GetVector("light_up", "", lightUp); + if (e->GetVector("light_start", "", lightStart)) { + // explicit start and end points + explicitStartEnd = true; + if (!e->GetVector("light_end", "", lightEnd)) { + // no end, use target + VectorCopy(lightTarget, lightEnd); + } + } else { + explicitStartEnd = false; + // create a start a quarter of the way to the target + lightStart = lightTarget * 0.25; + VectorCopy(lightTarget, lightEnd); + } + } else { + pointLight = true; + if (e->GetVector("light_radius", "", lightRadius)) { + equalRadius = false; + } else { + float radius = e->GetFloat("light"); + if (radius == 0) { + radius = 300; + } + lightRadius[0] = lightRadius[1] = lightRadius[2] = radius; + equalRadius = true; + } + if (e->GetVector("light_center", "", lightCenter)) { + hasCenter = true; + } + } +} + +void CLightInfo::ToDictFromDifferences ( idDict *e, const idDict *differences ) { + for ( int i = 0 ; i < differences->GetNumKeyVals () ; i ++ ) { + const idKeyValue *kv = differences->GetKeyVal( i ); + + if ( kv->GetValue().Length() > 0 ) { + e->Set ( kv->GetKey() ,kv->GetValue() ); + } else { + e->Delete ( kv->GetKey() ); + } + + common->Printf( "Applied difference: %s %s\n" , kv->GetKey().c_str() , kv->GetValue().c_str() ); + } +} + +//write all info to a dict, regardless of light type +void CLightInfo::ToDictWriteAllInfo( idDict *e ) { + e->Set("noshadows", (!castShadows) ? "1" : "0"); + e->Set("nospecular", (!castSpecular) ? "1" : "0"); + e->Set("nodiffuse", (!castDiffuse) ? "1" : "0"); + + e->SetFloat("falloff",fallOff); + + if (strTexture.GetLength() > 0 ) { + e->Set("texture", strTexture); + } + + idVec3 temp = color; + temp /= 255; + e->SetVector("_color", temp); + + if (!equalRadius) { + e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2])); + } else { + e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0])); + } + + e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2])); + e->Set("parallel", isParallel?"1":"0"); + + e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2])); + e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2])); + e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2])); + e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2])); + e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2])); +} + +void CLightInfo::ToDict( idDict *e ) { + + e->Delete("noshadows"); + e->Delete("nospecular"); + e->Delete("nodiffuse"); + e->Delete("falloff"); + e->Delete("parallel"); + e->Delete("texture"); + e->Delete("_color"); + e->Delete("fog"); + e->Delete("light_target"); + e->Delete("light_right"); + e->Delete("light_up"); + e->Delete("light_start"); + e->Delete("light_end"); + e->Delete("light_radius"); + e->Delete("light_center"); + e->Delete("light"); + + e->Set("noshadows", (!castShadows) ? "1" : "0"); + e->Set("nospecular", (!castSpecular) ? "1" : "0"); + e->Set("nodiffuse", (!castDiffuse) ? "1" : "0"); + + e->SetFloat("falloff",fallOff); + + if (strTexture.GetLength() > 0) { + e->Set("texture", strTexture); + } + + idVec3 temp = color; + temp /= 255; + e->SetVector("_color", temp); + + if (fog) { + e->Set("fog", va("%g %g %g %g", fogDensity[0]/255.0, fogDensity[1]/255.0, fogDensity[2]/255.0, fogDensity[3]/255.0)); + } + + if (pointLight) { + if (!equalRadius) { + e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2])); + } else { + e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0])); + } + + if (hasCenter) { + e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2])); + } + + if (isParallel) { + e->Set("parallel", "1"); + } + } else { + e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2])); + e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2])); + e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2])); + if (explicitStartEnd) { + e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2])); + e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2])); + } + } +} + +CLightInfo::CLightInfo() { + Defaults(); +} + + + +///////////////////////////////////////////////////////////////////////////// +// CLightDlg dialog + +CLightDlg *g_LightDialog = NULL; + + +CLightDlg::CLightDlg(CWnd* pParent /*=NULL*/) + : CDialog(CLightDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CLightDlg) + m_bEqualRadius = FALSE; + m_bExplicitFalloff = FALSE; + m_bPointLight = FALSE; + m_bCheckProjected = FALSE; + m_fFallloff = 0.0f; + m_nFalloff = -1; + m_bRotate = FALSE; + m_bShadows = FALSE; + m_bSpecular = FALSE; + m_bDiffuse = FALSE; + m_fEndX = 0.0f; + m_fEndY = 0.0f; + m_fEndZ = 0.0f; + m_fRadiusX = 0.0f; + m_fRadiusY = 0.0f; + m_fRadiusZ = 0.0f; + m_fRightX = 0.0f; + m_fRightY = 0.0f; + m_fRightZ = 0.0f; + m_fRotate = 0.0f; + m_fStartX = 0.0f; + m_fStartY = 0.0f; + m_fStartZ = 0.0f; + m_fTargetX = 0.0f; + m_fTargetY = 0.0f; + m_fTargetZ = 0.0f; + m_fUpX = 0.0f; + m_fUpY = 0.0f; + m_fUpZ = 0.0f; + m_hasCenter = FALSE; + m_centerX = 0.0f; + m_centerY = 0.0f; + m_centerZ = 0.0f; + m_bIsParallel = FALSE; + //}}AFX_DATA_INIT + m_drawMaterial = new idGLDrawableMaterial(); +} + +CLightDlg::~CLightDlg() { + delete m_drawMaterial; +} + +void CLightDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CLightDlg) + if ( com_editorActive ) { + DDX_Control(pDX, IDC_LIGHTPREVIEW, m_wndPreview); + } + DDX_Control(pDX, IDC_COMBO_TEXTURE, m_wndLights); + DDX_Check(pDX, IDC_CHECK_EQUALRADIUS, m_bEqualRadius); + DDX_Check(pDX, IDC_CHECK_EXPLICITFALLOFF, m_bExplicitFalloff); + DDX_Check(pDX, IDC_CHECK_POINT, m_bPointLight); + DDX_Check(pDX, IDC_CHECK_PROJECTED, m_bCheckProjected); + DDX_Radio(pDX, IDC_RADIO_FALLOFF, m_nFalloff); + DDX_Check(pDX, IDC_CHECK_SHADOWS, m_bShadows); + DDX_Check(pDX, IDC_CHECK_SPECULAR, m_bSpecular); + DDX_Check(pDX, IDC_CHECK_DIFFUSE, m_bDiffuse); + DDX_Check(pDX , IDC_CHECK_PARALLEL , m_bIsParallel ); + DDX_Text(pDX, IDC_EDIT_ENDX, m_fEndX); + DDX_Text(pDX, IDC_EDIT_ENDY, m_fEndY); + DDX_Text(pDX, IDC_EDIT_ENDZ, m_fEndZ); + DDX_Text(pDX, IDC_EDIT_RADIUSX, m_fRadiusX); + DDX_Text(pDX, IDC_EDIT_RADIUSY, m_fRadiusY); + DDX_Text(pDX, IDC_EDIT_RADIUSZ, m_fRadiusZ); + DDX_Text(pDX, IDC_EDIT_RIGHTX, m_fRightX); + DDX_Text(pDX, IDC_EDIT_RIGHTY, m_fRightY); + DDX_Text(pDX, IDC_EDIT_RIGHTZ, m_fRightZ); + DDX_Text(pDX, IDC_EDIT_STARTX, m_fStartX); + DDX_Text(pDX, IDC_EDIT_STARTY, m_fStartY); + DDX_Text(pDX, IDC_EDIT_STARTZ, m_fStartZ); + DDX_Text(pDX, IDC_EDIT_TARGETX, m_fTargetX); + DDX_Text(pDX, IDC_EDIT_TARGETY, m_fTargetY); + DDX_Text(pDX, IDC_EDIT_TARGETZ, m_fTargetZ); + DDX_Text(pDX, IDC_EDIT_UPX, m_fUpX); + DDX_Text(pDX, IDC_EDIT_UPY, m_fUpY); + DDX_Text(pDX, IDC_EDIT_UPZ, m_fUpZ); + DDX_Check(pDX, IDC_CHECK_CENTER, m_hasCenter); + DDX_Text(pDX, IDC_EDIT_CENTERX, m_centerX); + DDX_Text(pDX, IDC_EDIT_CENTERY, m_centerY); + DDX_Text(pDX, IDC_EDIT_CENTERZ, m_centerZ); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CLightDlg, CDialog) + //{{AFX_MSG_MAP(CLightDlg) + ON_BN_CLICKED(IDC_BTN_TEXTURE, OnBtnTexture) + ON_BN_CLICKED(IDC_CHECK_EQUALRADIUS, OnCheckEqualradius) + ON_BN_CLICKED(IDC_CHECK_EXPLICITFALLOFF, OnCheckExplicitfalloff) + ON_BN_CLICKED(IDC_CHECK_POINT, OnCheckPoint) + ON_BN_CLICKED(IDC_CHECK_PROJECTED, OnCheckProjected) + ON_BN_CLICKED(IDC_RADIO_FALLOFF, OnRadioFalloff) + ON_BN_CLICKED(IDC_APPLY, OnApply) + ON_BN_CLICKED(IDC_APPLY_DIFFERENT, OnApplyDifferences) + ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor) + ON_WM_CTLCOLOR() + ON_CBN_SELCHANGE(IDC_COMBO_TEXTURE, OnSelchangeComboTexture) + ON_BN_CLICKED(IDC_CHECK_CENTER, OnCheckCenter) + ON_BN_CLICKED(IDC_CHECK_PARALLEL, OnCheckParallel) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CLightDlg message handlers + +void CLightDlg::SetSpecifics() { + if (lightInfo.pointLight) { + GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(!lightInfo.equalRadius); + GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(!lightInfo.equalRadius); + GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.hasCenter); + GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.hasCenter); + GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.hasCenter); + } else { + GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(lightInfo.explicitStartEnd); + GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(lightInfo.explicitStartEnd); + GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(lightInfo.explicitStartEnd); + GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(lightInfo.explicitStartEnd); + GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(lightInfo.explicitStartEnd); + GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(lightInfo.explicitStartEnd); + } +} + +void CLightDlg::EnableControls() { + GetDlgItem(IDC_CHECK_EQUALRADIUS)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RADIUSX)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_RADIO_FALLOFF)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_RADIO_FALLOFF2)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_RADIO_FALLOFF3)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_TARGETX)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_TARGETY)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_TARGETZ)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RIGHTX)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RIGHTY)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_RIGHTZ)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_UPX)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_UPY)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_UPZ)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_CHECK_EXPLICITFALLOFF)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_CHECK_POINT)->EnableWindow(!lightInfo.pointLight); + GetDlgItem(IDC_CHECK_PROJECTED)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.pointLight); + GetDlgItem(IDC_CHECK_CENTER)->EnableWindow(lightInfo.pointLight); + + reinterpret_cast(GetDlgItem(IDC_CHECK_PROJECTED))->SetCheck(!lightInfo.pointLight); + reinterpret_cast(GetDlgItem(IDC_CHECK_POINT))->SetCheck(lightInfo.pointLight); + + SetSpecifics(); +} + +void CLightDlg::UpdateDialogFromLightInfo( void ) { + m_hasCenter = lightInfo.hasCenter; + m_bEqualRadius = lightInfo.equalRadius; + m_bExplicitFalloff = lightInfo.explicitStartEnd; + m_bPointLight = lightInfo.pointLight; + m_bCheckProjected = !lightInfo.pointLight; + m_fFallloff = lightInfo.fallOff; + if (lightInfo.fallOff < 0.35) { + m_nFalloff = 0; + } else if (lightInfo.fallOff < 0.70) { + m_nFalloff = 1; + } else { + m_nFalloff = 2; + } + //m_bFog = lightInfo.fog; + m_bRotate = lightInfo.rotate; + m_bShadows = lightInfo.castShadows; + m_bSpecular = lightInfo.castSpecular; + //m_bStrobe = lightInfo.strobe; + //m_fStrobe = lightInfo.strobeSpeed; + int sel = m_wndLights.FindStringExact(-1, lightInfo.strTexture); + m_wndLights.SetCurSel(sel); + if (sel >= 0) { + m_drawMaterial->setMedia(lightInfo.strTexture); + } else { + m_drawMaterial->setMedia(lightInfo.strTexture); + } + + m_bDiffuse = lightInfo.castDiffuse; + m_fEndX = lightInfo.lightEnd[0]; + m_fEndY = lightInfo.lightEnd[1]; + m_fEndZ = lightInfo.lightEnd[2]; + m_fRadiusX = lightInfo.lightRadius[0]; + m_fRadiusY = lightInfo.lightRadius[1]; + m_fRadiusZ = lightInfo.lightRadius[2]; + m_fRightX = lightInfo.lightRight[0]; + m_fRightY = lightInfo.lightRight[1]; + m_fRightZ = lightInfo.lightRight[2]; + //m_bRotate = lightInfo.rotate; + //m_fRotate = lightInfo.rotateSpeed; + m_fStartX = lightInfo.lightStart[0]; + m_fStartY = lightInfo.lightStart[1]; + m_fStartZ = lightInfo.lightStart[2]; + m_fTargetX = lightInfo.lightTarget[0]; + m_fTargetY = lightInfo.lightTarget[1]; + m_fTargetZ = lightInfo.lightTarget[2]; + m_fUpX = lightInfo.lightUp[0]; + m_fUpY = lightInfo.lightUp[1]; + m_fUpZ = lightInfo.lightUp[2]; + VectorCopy(lightInfo.color, color); + //m_fFogAlpha = lightInfo.fogDensity[3]; + m_centerX = lightInfo.lightCenter[0]; + m_centerY = lightInfo.lightCenter[1]; + m_centerZ = lightInfo.lightCenter[2]; + + //jhefty - added parallel light updating + m_bIsParallel = lightInfo.isParallel; + + UpdateData(FALSE); +} + +void CLightDlg::UpdateLightInfoFromDialog( void ) { + UpdateData( TRUE ); + + lightInfo.pointLight = ( m_bPointLight != FALSE ); + lightInfo.equalRadius = ( m_bEqualRadius != FALSE ); + lightInfo.explicitStartEnd = ( m_bExplicitFalloff != FALSE ); + + if (lightInfo.pointLight) { + if (m_nFalloff == 0) { + m_fFallloff = 0.0; + } else if (m_nFalloff == 1) { + m_fFallloff = 0.5; + } else { + m_fFallloff = 1.0; + } + } + + lightInfo.fallOff = m_fFallloff; + + //lightInfo.fog = m_bFog; + lightInfo.rotate = ( m_bRotate != FALSE ); + lightInfo.castShadows = ( m_bShadows != FALSE ); + lightInfo.castSpecular = ( m_bSpecular != FALSE ); + + VectorCopy(color, lightInfo.color); + lightInfo.isParallel = (m_bIsParallel == TRUE); + + //lightInfo.fogDensity[3] = m_fFogAlpha; + + //lightInfo.strobe = m_bStrobe; + //lightInfo.strobeSpeed = m_fStrobe; + //lightInfo.rotate = m_bRotate; + //lightInfo.rotateSpeed = m_fRotate; + + int sel = m_wndLights.GetCurSel(); + CString str(""); + if (sel >= 0) { + m_wndLights.GetLBText(sel, str); + } + lightInfo.strTexture = str; + + lightInfo.castDiffuse = ( m_bDiffuse != FALSE ); + lightInfo.lightEnd[0] = m_fEndX; + lightInfo.lightEnd[1] = m_fEndY; + lightInfo.lightEnd[2] = m_fEndZ; + lightInfo.lightRadius[0] = m_fRadiusX; + lightInfo.lightRadius[1] = m_fRadiusY; + lightInfo.lightRadius[2] = m_fRadiusZ; + lightInfo.lightRight[0] = m_fRightX; + lightInfo.lightRight[1] = m_fRightY; + lightInfo.lightRight[2] = m_fRightZ; + lightInfo.lightStart[0] = m_fStartX; + lightInfo.lightStart[1] = m_fStartY; + lightInfo.lightStart[2] = m_fStartZ; + lightInfo.lightTarget[0] = m_fTargetX; + lightInfo.lightTarget[1] = m_fTargetY; + lightInfo.lightTarget[2] = m_fTargetZ; + lightInfo.lightUp[0] = m_fUpX; + lightInfo.lightUp[1] = m_fUpY; + lightInfo.lightUp[2] = m_fUpZ; + + lightInfo.hasCenter = ( m_hasCenter != FALSE ); + lightInfo.lightCenter[0] = m_centerX; + lightInfo.lightCenter[1] = m_centerY; + lightInfo.lightCenter[2] = m_centerZ; +} + +void CLightDlg::SaveLightInfo( const idDict *differences ) { + + if ( com_editorActive ) { + + // used from Radiant + for ( brush_t *b = selected_brushes.next; b && b != &selected_brushes; b = b->next ) { + if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { + if ( differences ) { + lightInfo.ToDictFromDifferences( &b->owner->epairs, differences ); + } else { + lightInfo.ToDict( &b->owner->epairs ); + } + Brush_Build( b ); + } + } + + } else { + + // used in-game + idList list; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + for ( int i = 0; i < count; i++ ) { + if ( differences ) { + gameEdit->EntityChangeSpawnArgs( list[i], differences ); + gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL ); + } else { + idDict newArgs; + lightInfo.ToDict( &newArgs ); + gameEdit->EntityChangeSpawnArgs( list[i], &newArgs ); + gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL ); + } + gameEdit->EntityUpdateVisuals( list[i] ); + } + } +} + +void CLightDlg::ColorButtons() { + CRect r; + + CClientDC dc(this); + + CButton *pBtn = (CButton *)GetDlgItem(IDC_BTN_COLOR); + pBtn->GetClientRect(&r); + colorBitmap.DeleteObject(); + colorBitmap.CreateCompatibleBitmap(&dc, r.Width(), r.Height()); + CDC MemDC; + MemDC.CreateCompatibleDC(&dc); + CBitmap *pOldBmp = MemDC.SelectObject(&colorBitmap); + { + CBrush br(RGB(color[0], color[1], color[2])); + MemDC.FillRect(r,&br); + } + dc.SelectObject(pOldBmp); + pBtn->SetBitmap(HBITMAP(colorBitmap)); +} + + +void CLightDlg::LoadLightTextures() { + int count = declManager->GetNumDecls( DECL_MATERIAL ); + int i; + const idMaterial *mat; + for (i = 0; i < count; i++) { + mat = declManager->MaterialByIndex(i, false); + idStr str = mat->GetName(); + str.ToLower(); + if (str.Icmpn("lights/", strlen("lights/")) == 0 || str.Icmpn("fogs/", strlen("fogs/")) == 0) { + m_wndLights.AddString(mat->GetName()); + } + } +} + +BOOL CLightDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + com_editors |= EDITOR_LIGHT; + + UpdateDialog( true ); + + LoadLightTextures(); + + if ( com_editorActive ) { + m_wndPreview.setDrawable(m_drawMaterial); + } + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CLightDlg::OnDestroy() { + + com_editors &= ~EDITOR_LIGHT; + + return CDialog::OnDestroy(); +} + +void CLightDlg::OnBtnTexture() +{ + // TODO: Add your control notification handler code here + +} + +void CLightDlg::OnCheckEqualradius() +{ + lightInfo.equalRadius = ( reinterpret_cast(GetDlgItem(IDC_CHECK_EQUALRADIUS))->GetCheck() != 0 ); + SetSpecifics(); +} + +void CLightDlg::OnCheckExplicitfalloff() +{ + lightInfo.explicitStartEnd = ( reinterpret_cast(GetDlgItem(IDC_CHECK_EXPLICITFALLOFF))->GetCheck() != 0 ); + SetSpecifics(); +} + +void CLightDlg::OnCheckPoint() +{ + lightInfo.DefaultPoint(); + UpdateDialogFromLightInfo(); + EnableControls(); +} + +void CLightDlg::OnCheckProjected() +{ + lightInfo.DefaultProjected(); + UpdateDialogFromLightInfo(); + EnableControls(); +} + +void CLightDlg::OnRadioFalloff() +{ +} + +void CLightDlg::OnOK() { + UpdateLightInfoFromDialog(); + SaveLightInfo( NULL ); + Sys_UpdateWindows(W_ALL); + CDialog::OnOK(); +} + +entity_t *SingleLightSelected() { + if ( QE_SingleBrush( true, true ) ) { + brush_t *b = selected_brushes.next; + if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { + return b->owner; + } + } + return NULL; +} + +void CLightDlg::UpdateDialog( bool updateChecks ) +{ + CString title; + + lightInfo.Defaults(); + lightInfoOriginal.Defaults (); + + if ( com_editorActive ) { + // used from Radiant + entity_t *e = SingleLightSelected(); + if ( e ) { + lightInfo.FromDict(&e->epairs); + lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compare against for apply differences + title = "Light Editor"; + } else { + //find the last brush belonging to the last entity selected and use that as the source + e = NULL; + for ( brush_t *b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) { + if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { + e = b->owner; + break; + } + } + + if ( e ) { + lightInfo.FromDict( &e->epairs ); + lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compaer against for apply differences + title = "Light Editor - (Multiple lights selected)"; + } else { + title = "Light Editor - (No lights selected)"; + } + } + } else { + // used in-game + idList list; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count > 0 ) { + lightInfo.FromDict( gameEdit->EntityGetSpawnArgs( list[count-1] ) ); + title = "Light Editor"; + } else { + title = "Light Editor - (No entities selected)"; + } + } + + SetWindowText( title ); + + UpdateDialogFromLightInfo(); + ColorButtons(); + + if ( updateChecks ) { + EnableControls(); + } +} + +void LightEditorInit( const idDict *spawnArgs ) { + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the light editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_LightDialog == NULL ) { + InitAfx(); + g_LightDialog = new CLightDlg(); + } + + if ( g_LightDialog->GetSafeHwnd() == NULL ) { + g_LightDialog->Create( IDD_DIALOG_LIGHT ); + CRect rct; + LONG lSize = sizeof( rct ); + if ( LoadRegistryInfo( "Radiant::LightWindow", &rct, &lSize ) ) { + g_LightDialog->SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE); + } + } + + idKeyInput::ClearStates(); + + g_LightDialog->ShowWindow( SW_SHOW ); + g_LightDialog->SetFocus(); + g_LightDialog->UpdateDialog( true ); + + if ( spawnArgs ) { + // FIXME: select light based on spawn args + } +} + +void LightEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +void LightEditorShutdown( void ) { + delete g_LightDialog; + g_LightDialog = NULL; +} + +void UpdateLightInspector() { + if ( g_LightDialog && g_LightDialog->GetSafeHwnd() != NULL ) { + g_LightDialog->UpdateDialog(true); //jhefty - update ALL info about the light, including check boxes + } +} + +void CLightDlg::OnApply() { + UpdateLightInfoFromDialog(); + SaveLightInfo( NULL ); + Sys_UpdateWindows( W_ALL ); +} + +void UpdateLightDialog( float r, float g, float b, float a ) { + UpdateRadiantColor( 0.0f, 0.0f, 0.0f, 0.0f ); + g_LightDialog->UpdateColor( r, g, b, a ); +} + +void CLightDlg::UpdateColor( float r, float g, float b, float a ) { + color[0] = a * r; + color[1] = a * g; + color[2] = a * b; + ColorButtons(); + UpdateLightInfoFromDialog(); + SaveLightInfo( NULL ); + Sys_UpdateWindows( W_CAMERA ); +} + +void CLightDlg::OnBtnColor() { + int r, g, b; + float ob; + r = color[0]; + g = color[1]; + b = color[2]; + if ( DoNewColor( &r, &g, &b, &ob, UpdateLightDialog ) ) { + color[0] = ob * r; + color[1] = ob * g; + color[2] = ob * b; + ColorButtons(); + } +} + +void CLightDlg::OnCancel() { + CDialog::OnCancel(); +} + +HBRUSH CLightDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); + + return hbr; +} + +BOOL CLightDlg::DestroyWindow() +{ + if (GetSafeHwnd()) + { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::LightWindow", &rct, sizeof(rct)); + } + return CDialog::DestroyWindow(); +} + +void CLightDlg::OnSelchangeComboTexture() +{ + UpdateData(TRUE); + int sel = m_wndLights.GetCurSel(); + CString str; + if (sel >= 0) { + m_wndLights.GetLBText(sel, str); + m_drawMaterial->setMedia(str); + if ( com_editorActive ) { + m_wndPreview.RedrawWindow(); + } + } + Sys_UpdateWindows(W_ALL); +} + +void CLightDlg::OnCheckCenter() +{ + if (reinterpret_cast(GetDlgItem(IDC_CHECK_CENTER))->GetCheck()) { + lightInfo.hasCenter = true; + lightInfo.lightCenter.x = 0; + lightInfo.lightCenter.y = 0; + lightInfo.lightCenter.z = 32; + } else { + lightInfo.hasCenter = false; + lightInfo.lightCenter.Zero(); + } + UpdateDialogFromLightInfo(); + SetSpecifics(); +} + +void CLightDlg::OnCheckParallel() { + if ( reinterpret_cast(GetDlgItem(IDC_CHECK_PARALLEL))->GetCheck() ) { + lightInfo.hasCenter = true; + lightInfo.isParallel = true; + lightInfo.lightCenter.x = 0; + lightInfo.lightCenter.y = 0; + lightInfo.lightCenter.z = 32; + } else { + lightInfo.isParallel = false; + lightInfo.hasCenter = false; + } + + UpdateDialogFromLightInfo(); + SetSpecifics(); +} + +//jhefty - only apply settings that are different +void CLightDlg::OnApplyDifferences () { + idDict differences, modified, original; + + UpdateLightInfoFromDialog(); + + lightInfo.ToDict( &modified ); + lightInfoOriginal.ToDictWriteAllInfo( &original ); + + differences = modified; + + // jhefty - compile a set of modified values to apply + for ( int i = 0; i < modified.GetNumKeyVals (); i ++ ) { + const idKeyValue* valModified = modified.GetKeyVal ( i ); + const idKeyValue* valOriginal = original.FindKey ( valModified->GetKey() ); + + //if it hasn't changed, remove it from the list of values to apply + if ( !valOriginal || ( valModified->GetValue() == valOriginal->GetValue() ) ) { + differences.Delete ( valModified->GetKey() ); + } + } + + SaveLightInfo( &differences ); + + lightInfoOriginal.FromDict( &modified ); + + Sys_UpdateWindows( W_ALL ); +} diff --git a/tools/radiant/LightDlg.h b/tools/radiant/LightDlg.h new file mode 100644 index 000000000..9d1aeaec6 --- /dev/null +++ b/tools/radiant/LightDlg.h @@ -0,0 +1,179 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_LIGHTDLG_H__9DF57520_ED11_4BD8_968A_F6A7E34167D2__INCLUDED_) +#define AFX_LIGHTDLG_H__9DF57520_ED11_4BD8_968A_F6A7E34167D2__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "GLWidget.h" + +class CLightInfo { +public: + CLightInfo(); + + bool pointLight; + float fallOff; + CString strTexture; + bool equalRadius; + bool explicitStartEnd; + idVec3 lightStart; + idVec3 lightEnd; + idVec3 lightUp; + idVec3 lightRight; + idVec3 lightTarget; + idVec3 lightCenter; + idVec3 color; + bool fog; + idVec4 fogDensity; + + bool strobe; + float strobeSpeed; + bool rotate; + float rotateSpeed; + + idVec3 lightRadius; + bool castShadows; + bool castSpecular; + bool castDiffuse; + bool hasCenter; + bool isParallel; + + void Defaults(); + void DefaultProjected(); + void DefaultPoint(); + void FromDict( const idDict *e ); + void ToDict( idDict *e ); + void ToDictFromDifferences( idDict *e, const idDict *differences ); + void ToDictWriteAllInfo( idDict *e ); +}; + +///////////////////////////////////////////////////////////////////////////// +// CLightDlg dialog + +class CLightDlg : public CDialog { +public: + CLightDlg(CWnd* pParent = NULL); // standard constructor + ~CLightDlg(); + + void UpdateDialogFromLightInfo( void ); + void UpdateDialog( bool updateChecks ); + void UpdateLightInfoFromDialog( void ); + void UpdateColor( float r, float g, float b, float a ); + void SetSpecifics(); + void EnableControls(); + void LoadLightTextures(); + void ColorButtons(); + void SaveLightInfo( const idDict *differences ); + +// Dialog Data + //{{AFX_DATA(CLightDlg) + enum { IDD = IDD_DIALOG_LIGHT }; + idGLWidget m_wndPreview; + CComboBox m_wndLights; + CSliderCtrl m_wndFalloff; + BOOL m_bEqualRadius; + BOOL m_bExplicitFalloff; + BOOL m_bPointLight; + BOOL m_bCheckProjected; + float m_fFallloff; + int m_nFalloff; + BOOL m_bRotate; + BOOL m_bShadows; + BOOL m_bSpecular; + BOOL m_bDiffuse; + float m_fEndX; + float m_fEndY; + float m_fEndZ; + float m_fRadiusX; + float m_fRadiusY; + float m_fRadiusZ; + float m_fRightX; + float m_fRightY; + float m_fRightZ; + float m_fRotate; + float m_fStartX; + float m_fStartY; + float m_fStartZ; + float m_fTargetX; + float m_fTargetY; + float m_fTargetZ; + float m_fUpX; + float m_fUpY; + float m_fUpZ; + BOOL m_hasCenter; + float m_centerX; + float m_centerY; + float m_centerZ; + BOOL m_bIsParallel; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CLightDlg) + public: + virtual BOOL DestroyWindow(); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CLightDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnDestroy(); + afx_msg void OnBtnTexture(); + afx_msg void OnCheckEqualradius(); + afx_msg void OnCheckExplicitfalloff(); + afx_msg void OnCheckPoint(); + afx_msg void OnCheckProjected(); + afx_msg void OnRadioFalloff(); + virtual void OnOK(); + afx_msg void OnApply(); + afx_msg void OnBtnColor(); + afx_msg void OnBtnFog(); + afx_msg void OnCheckFog(); + afx_msg void OnCheckRotate(); + afx_msg void OnCheckStrobe(); + virtual void OnCancel(); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + afx_msg void OnSelchangeComboTexture(); + afx_msg void OnCheckCenter(); + afx_msg void OnCheckParallel(); + afx_msg void OnApplyDifferences(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +private: + CBitmap colorBitmap; + CBitmap fogBitmap; + CLightInfo lightInfo; + CLightInfo lightInfoOriginal; + idVec3 color; + idGLDrawableMaterial * m_drawMaterial; +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_LIGHTDLG_H__9DF57520_ED11_4BD8_968A_F6A7E34167D2__INCLUDED_) diff --git a/tools/radiant/MRU.CPP b/tools/radiant/MRU.CPP new file mode 100644 index 000000000..fb5d8e522 --- /dev/null +++ b/tools/radiant/MRU.CPP @@ -0,0 +1,670 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include +#include "mru.h" + +//************************************************************* +// File name: mru.c +// +// Description: +// +// Routines for MRU support +// +// Development Team: +// +// Gilles Vollant (100144.2636@compuserve.com) +// +//************************************************************* + + +// CreateMruMenu : MRUMENU constructor +// wNbLruShowInit : nb of item showed in menu +// wNbLruMenuInit : nb of item stored in memory +// wMaxSizeLruItemInit : size max. of filename + + +//************************************************************* +// +// CreateMruMenu() +// +// Purpose: +// +// Allocate and Initialize an MRU and return a pointer on it +// +// +// Parameters: +// +// WORD wNbLruShowInit - Maximum number of item displayed on menu +// WORD wNbLruMenuInit - Maximum number of item stored in memory +// WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname) +// WORD wIdMruInit - ID of the first item in the menu (default:IDMRU) +// +// +// Return: (LPMRUMENU) +// +// Pointer on a MRUMENU structure, used by other function +// +// +// Comments: +// wNbLruShowInit <= wNbLruMenuInit +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* + +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit, + WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit) +{ +LPMRUMENU lpMruMenu; + lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU)); + + lpMruMenu->wNbItemFill = 0; + lpMruMenu->wNbLruMenu = wNbLruMenuInit; + lpMruMenu->wNbLruShow = wNbLruShowInit; + lpMruMenu->wIdMru = wIdMruInit; + lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit; + lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND, + lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem); + if (lpMruMenu->lpMRU == NULL) + { + GlobalFreePtr(lpMruMenu); + lpMruMenu = NULL; + } + return lpMruMenu; +} + +//************************************************************* +// +// CreateMruMenuDefault() +// +// Purpose: +// +// Allocate and Initialize an MRU and return a pointer on it +// Use default parameter +// +// +// Parameters: +// +// +// Return: (LPMRUMENU) +// +// Pointer on a MRUMENU structure, used by other function +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* + +LPMRUMENU CreateMruMenuDefault() +{ + return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU); +} + + +//************************************************************* +// +// DeleteMruMenu() +// +// Purpose: +// Destructor : +// Clean and free a MRUMENU structure +// +// Parameters: +// +// LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated +// by CreateMruMenu() or CreateMruMenuDefault() +// +// +// Return: void +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void DeleteMruMenu(LPMRUMENU lpMruMenu) +{ + GlobalFreePtr(lpMruMenu->lpMRU); + GlobalFreePtr(lpMruMenu); +} + +//************************************************************* +// +// SetNbLruShow() +// +// Purpose: +// Change the maximum number of item displayed on menu +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wNbLruShowInit - Maximum number of item displayed on menu +// +// +// Return: void +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit) +{ + lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu); +} + +//************************************************************* +// +// SetMenuItem() +// +// Purpose: +// Set the filename of an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// LPSTR lpItem - String, contain the filename of the item +// +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// used when load .INI or reg database +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem) +{ + if (wItem >= NBMRUMENU) + return FALSE; + _fstrncpy((lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem), + lpItem,lpMruMenu->wMaxSizeLruItem-1); + lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1); + return TRUE; +} + +//************************************************************* +// +// GetMenuItem() +// +// Purpose: +// Get the filename of an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// BOOL fIDMBased - TRUE : wItem is based on ID menu item +// FALSE : wItem is zero-based +// LPSTR lpItem - String where the filename of the item will be +// stored by GetMenuItem() +// UINT uiSize - Size of the lpItem buffer +// +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used for saving in .INI or reg database, or when user select +// an MRU in File menu +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + BOOL fIDMBased,LPSTR lpItem,UINT uiSize) +{ + if (fIDMBased) + wItem -= (lpMruMenu->wIdMru + 1); + if (wItem >= lpMruMenu->wNbItemFill) + return FALSE; + _fstrncpy(lpItem,(lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize); + *(lpItem+uiSize-1) = '\0'; + return TRUE; +} + +//************************************************************* +// +// AddNewItem() +// +// Purpose: +// Add an item at the begin of the list +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpItem - String contain the filename to add +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used when used open a file (using File Open common +// dialog, Drag and drop or MRU) +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem) +{ +WORD i,j; + for (i=0;iwNbItemFill;i++) + if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0) + { + // Shift the other items + for (j=i;j>0;j--) + lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j), + (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1))); + _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1); + return ; + } + lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu); + for (i=lpMruMenu->wNbItemFill-1;i>0;i--) + lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i), + lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1))); + _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1); +} + +//************************************************************* +// +// DelMenuItem() +// +// Purpose: +// Delete an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// BOOL fIDMBased - TRUE : wItem is based on ID menu item +// FALSE : wItem is zero-based +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used when used open a file, using MRU, and when an error +// occured (by example, when file was deleted) +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased) +{ +WORD i; + if (fIDMBased) + wItem -= (lpMruMenu->wIdMru + 1); + if (lpMruMenu->wNbItemFill <= wItem) + return FALSE; + lpMruMenu->wNbItemFill--; + for (i=wItem;iwNbItemFill;i++) + lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i), + lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1))); + return TRUE; +} + +//************************************************************* +// +// PlaceMenuMRUItem() +// +// Purpose: +// Add MRU at the end of a menu +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// HMENU hMenu - Handle of menu where MRU must be added +// UINT uiItem - Item of menu entry where MRU must be added +// +// Return: void +// +// +// Comments: +// Used MRU is modified, for refresh the File menu +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem) +{ +int i; +WORD wNbShow; + if (hMenu == NULL) + return; + // remove old MRU in menu + for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++) + RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND); + + if (lpMruMenu->wNbItemFill == 0) + return; + + // If they are item, insert a separator before the files + InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL); + + wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow); + for (i=(int)wNbShow-1;i>=0;i--) + { + LPSTR lpTxt; + if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20)) + { + wsprintf(lpTxt,"&%lu %s", + (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i)); + InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru, + MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt); + GlobalFreePtr(lpTxt); + } + } + +} + +/////////////////////////////////////////// + + + +//************************************************************* +// +// SaveMruInIni() +// +// Purpose: +// Save MRU in a private .INI +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszSection - Points to a null-terminated string containing +// the name of the section +// LPSTR lpszFile - Points to a null-terminated string that names +// the initialization file. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// See WritePrivateProfileString API for more info on lpszSection and lpszFile +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) +{ +LPSTR lpTxt; +WORD i; + + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) + *lpTxt = '\0'; + WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile); + } + GlobalFreePtr(lpTxt); + WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache + return TRUE; +} + + +//************************************************************* +// +// LoadMruInIni() +// +// Purpose: +// Load MRU from a private .INI +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszSection - Points to a null-terminated string containing +// the name of the section +// LPSTR lpszFile - Points to a null-terminated string that names +// the initialization file. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// See GetPrivateProfileString API for more info on lpszSection and lpszFile +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) +{ +LPSTR lpTxt; +WORD i; + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + + wsprintf(szEntry,"File%lu",(DWORD)i+1); + GetPrivateProfileString(lpszSection,szEntry,"",lpTxt, + lpMruMenu->wMaxSizeLruItem + 10,lpszFile); + if (*lpTxt == '\0') + break; + SetMenuItem(lpMruMenu,i,lpTxt); + } + GlobalFreePtr(lpTxt); + return TRUE; +} + +#ifdef WIN32 + +BOOL IsWin395OrHigher(void) +{ + WORD wVer; + + wVer = LOWORD(GetVersion()); + wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); + + return (wVer >= 0x035F); // 5F = 95 dec +} + + +//************************************************************* +// +// SaveMruInReg() +// +// Purpose: +// Save MRU in the registry +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszKey - Points to a null-terminated string +// specifying the name of a key that +// this function opens or creates. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegCreateKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) +{ +LPSTR lpTxt; +WORD i; +HKEY hCurKey; +DWORD dwDisp; + + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL, + REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp); + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) + *lpTxt = '\0'; + RegSetValueEx(hCurKey,szEntry,0,REG_SZ,(unsigned char*)lpTxt,lstrlen(lpTxt)); + } + RegCloseKey(hCurKey); + GlobalFreePtr(lpTxt); + return TRUE; +} + +//************************************************************* +// +// LoadMruInReg() +// +// Purpose: +// Load MRU from the registry +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszKey - Points to a null-terminated string +// specifying the name of a key that +// this function opens or creates. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegOpenKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) +{ +LPSTR lpTxt; +WORD i; +HKEY hCurKey; +DWORD dwType; + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey); + + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + DWORD dwSizeBuf; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + *lpTxt = '\0'; + dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10; + RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf); + *(lpTxt+dwSizeBuf)='\0'; + if (*lpTxt == '\0') + break; + SetMenuItem(lpMruMenu,i,lpTxt); + } + RegCloseKey(hCurKey); + GlobalFreePtr(lpTxt); + return TRUE; +} + + +//************************************************************* +// +// GetWin32Kind() +// +// Purpose: +// Get the Win32 platform +// +// Parameters: +// +// Return: (WIN32KIND) +// WINNT - Run under Windows NT +// WIN32S - Run under Windows 3.1x + Win32s +// WIN95ORGREATHER - Run under Windows 95 +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegOpenKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +WIN32KIND GetWin32Kind() +{ +BOOL IsWin395OrHigher(void); + + WORD wVer; + + if ((GetVersion() & 0x80000000) == 0) + return WINNT; + wVer = LOWORD(GetVersion()); + wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); + + if (wVer >= 0x035F) + return WIN95ORGREATHER; + else + return WIN32S; +} +#endif diff --git a/tools/radiant/MRU.H b/tools/radiant/MRU.H new file mode 100644 index 000000000..f189b4dc2 --- /dev/null +++ b/tools/radiant/MRU.H @@ -0,0 +1,85 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __MRU_H__ +#define __MRU_H__ + +#define NBMRUMENUSHOW 6 // Default number of MRU showed in the menu File +#define NBMRUMENU 9 // Default number of MRU stored +#define IDMRU 8000 // Default First ID of MRU +#ifdef OFS_MAXPATHNAME +#define MAXSIZEMRUITEM OFS_MAXPATHNAME +#else +#define MAXSIZEMRUITEM 128 // Default max size of an entry +#endif + +typedef struct +{ +WORD wNbItemFill; +WORD wNbLruShow; +WORD wNbLruMenu; +WORD wMaxSizeLruItem; +WORD wIdMru; +LPSTR lpMRU; +} MRUMENU; + +typedef MRUMENU FAR * LPMRUMENU; + +#ifdef __cplusplus +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit=NBMRUMENUSHOW, + WORD wNbLruMenuInit=NBMRUMENU, + WORD wMaxSizeLruItemInit=MAXSIZEMRUITEM, + WORD wIdMruInit=IDMRU); +#else +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit, + WORD wNbLruMenuInit, + WORD wMaxSizeLruItemInit, + WORD wIdMruInit); +#endif + +LPMRUMENU CreateMruMenuDefault(); +void DeleteMruMenu (LPMRUMENU lpMruMenu); + +void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit); +BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + LPSTR lpItem); +BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + BOOL fIDMBased,LPSTR lpItem,UINT uiSize); +BOOL DelMenuItem (LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased); +void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem); +void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem); + +BOOL SaveMruInIni (LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile); +BOOL LoadMruInIni (LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile); +#ifdef WIN32 +BOOL SaveMruInReg (LPMRUMENU lpMruMenu,LPSTR lpszKey); +BOOL LoadMruInReg (LPMRUMENU lpMruMenu,LPSTR lpszKey); + +typedef enum +{ +WIN32S, +WINNT, +WIN95ORGREATHER +} WIN32KIND; +WIN32KIND GetWin32Kind(); +#endif + + +////////////////////////////////////////////////////////////// +#endif diff --git a/tools/radiant/MainFrm.cpp b/tools/radiant/MainFrm.cpp new file mode 100644 index 000000000..6d9ae88c6 --- /dev/null +++ b/tools/radiant/MainFrm.cpp @@ -0,0 +1,6893 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "ZWnd.h" +#include "CamWnd.h" +#include "MapInfo.h" +#include "MainFrm.h" +#include "RotateDlg.h" +#include "EntityListDlg.h" +#include "NewProjDlg.h" +#include "CommandsDlg.h" +#include "ScaleDialog.h" +#include "FindTextureDlg.h" +#include "SurfaceDlg.h" +#include "shlobj.h" +#include "DialogTextures.h" +#include "PatchDensityDlg.h" +#include "DialogThick.h" +#include "PatchDialog.h" +#include "Undo.h" +#include "NewTexWnd.h" +#include "splines.h" +#include "dlgcamera.h" +#include "mmsystem.h" +#include "LightDlg.h" +#include "GetString.h" +#include "EntKeyFindReplace.h" +#include "InspectorDialog.h" +#include "autocaulk.h" + +#include "../../sys/win32/rc/common_resource.h" +#include "../comafx/DialogName.h" +#include "../comafx/DialogColorPicker.h" + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// globals +CString g_strAppPath; // holds the full path of the executable +CMainFrame *g_pParentWnd = NULL; // used to precast to CMainFrame +CPrefsDlg g_Preferences; // global prefs instance +CPrefsDlg &g_PrefsDlg = g_Preferences; // reference used throughout +int g_nUpdateBits = 0; // window update flags +bool g_bScreenUpdates = true; // whether window painting is active, used in a few places + +// +// to disable updates for speed reasons both of the above should be made members +// of CMainFrame +// bool g_bSnapToGrid = true; // early use, no longer in use, clamping pref will +// be used +// +CString g_strProject; // holds the active project filename + +#define D3XP_ID_FILE_SAVE_COPY ( WM_USER + 28476 ) +#define D3XP_ID_SHOW_MODELS ( WM_USER + 28477 ) + +// +// CMainFrame +// command mapping stuff m_strCommand is the command string m_nKey is the windows +// VK_??? equivelant m_nModifiers are key states as follows bit 0 - shift 1 - alt +// 2 - control 4 - press only +// +#define SPEED_MOVE 32.0f +#define SPEED_TURN 22.5f + +#define MAX_GRID 64.0f +#define MIN_GRID 0.125f + +SCommandInfo g_Commands[] = { + { "Texture_AxialByHeight", 'U', 0, ID_SELECT_AXIALTEXTURE_BYHEIGHT }, + { "Texture_AxialArbitrary", 'U', RAD_SHIFT, ID_SELECT_AXIALTEXTURE_ARBITRARY }, + { "Texture_AxialByWidth", 'U', RAD_CONTROL, ID_SELECT_AXIALTEXTURE_BYWIDTH }, + { "Texture_Decrement", VK_SUBTRACT, RAD_SHIFT, ID_SELECTION_TEXTURE_DEC }, + { "Texture_Increment", VK_ADD, RAD_SHIFT, ID_SELECTION_TEXTURE_INC }, + { "Texture_Fit", '5', RAD_SHIFT, ID_SELECTION_TEXTURE_FIT }, + { "Texture_RotateClock", VK_NEXT, RAD_SHIFT, ID_SELECTION_TEXTURE_ROTATECLOCK }, + { "Texture_RotateCounter", VK_PRIOR, RAD_SHIFT, ID_SELECTION_TEXTURE_ROTATECOUNTER }, + { "Texture_ScaleUp", VK_UP, RAD_CONTROL, ID_SELECTION_TEXTURE_SCALEUP }, + { "Texture_ScaleDown", VK_DOWN, RAD_CONTROL, ID_SELECTION_TEXTURE_SCALEDOWN }, + { "Texture_ShiftLeft", VK_LEFT, RAD_SHIFT, ID_SELECTION_TEXTURE_SHIFTLEFT }, + { "Texture_ShiftRight", VK_RIGHT, RAD_SHIFT, ID_SELECTION_TEXTURE_SHIFTRIGHT }, + { "Texture_ShiftUp", VK_UP, RAD_SHIFT, ID_SELECTION_TEXTURE_SHIFTUP }, + { "Texture_ShiftDown", VK_DOWN, RAD_SHIFT, ID_SELECTION_TEXTURE_SHIFTDOWN }, + { "Texture_ScaleLeft", VK_LEFT, RAD_CONTROL, ID_SELECTION_TEXTURE_SCALELEFT }, + { "Texture_ScaleRight", VK_RIGHT, RAD_CONTROL, ID_SELECTION_TEXTURE_SCALERIGHT }, + { "Texture_InvertX", 'I', RAD_CONTROL|RAD_SHIFT, ID_CURVE_NEGATIVETEXTUREY }, + { "Texture_InvertY", 'I', RAD_SHIFT, ID_CURVE_NEGATIVETEXTUREX }, + { "Texture_ToggleLock", 'T', RAD_SHIFT, ID_TOGGLE_LOCK }, + + { "Texture_ShowAllTextures", 'A', RAD_CONTROL, ID_TEXTURES_SHOWALL }, + + { "Edit_Copy", 'C', RAD_CONTROL, ID_EDIT_COPYBRUSH }, + { "Edit_Paste", 'V', RAD_CONTROL, ID_EDIT_PASTEBRUSH }, + { "Edit_Undo", 'Z', RAD_CONTROL, ID_EDIT_UNDO }, + { "Edit_Redo", 'Y', RAD_CONTROL, ID_EDIT_REDO }, + + { "Camera_Forward", VK_UP, 0, ID_CAMERA_FORWARD }, + { "Camera_Back", VK_DOWN, 0, ID_CAMERA_BACK }, + { "Camera_Left", VK_LEFT, 0, ID_CAMERA_LEFT }, + { "Camera_Right", VK_RIGHT, 0, ID_CAMERA_RIGHT }, + { "Camera_Up", 'D', 0, ID_CAMERA_UP }, + { "Camera_Down", 'C', 0, ID_CAMERA_DOWN }, + { "Camera_AngleUp", 'A', 0, ID_CAMERA_ANGLEUP }, + { "Camera_AngleDown", 'Z', 0, ID_CAMERA_ANGLEDOWN }, + { "Camera_StrafeRight", VK_PERIOD, 0, ID_CAMERA_STRAFERIGHT }, + { "Camera_StrafeLeft", VK_COMMA, 0, ID_CAMERA_STRAFELEFT }, + { "Camera_UpFloor", VK_PRIOR, 0, ID_VIEW_UPFLOOR }, + { "Camera_DownFloor", VK_NEXT, 0, ID_VIEW_DOWNFLOOR }, + { "Camera_CenterView", VK_END, 0, ID_VIEW_CENTER }, + + { "Grid_ZoomOut", VK_INSERT, 0, ID_VIEW_ZOOMOUT }, + { "FileSaveCopy", 'C', RAD_CONTROL|RAD_ALT|RAD_SHIFT, D3XP_ID_FILE_SAVE_COPY }, + { "ShowHideModels", 'M', RAD_CONTROL, D3XP_ID_SHOW_MODELS }, + { "NextView", VK_HOME, 0, ID_VIEW_NEXTVIEW }, + { "Grid_ZoomIn", VK_DELETE, 0, ID_VIEW_ZOOMIN }, + + { "Grid_SetPoint5", '4', RAD_SHIFT, ID_GRID_POINT5 }, + { "Grid_SetPoint25", '3', RAD_SHIFT, ID_GRID_POINT25 }, + { "Grid_SetPoint125", '2', RAD_SHIFT, ID_GRID_POINT125 }, + //{ "Grid_SetPoint0625", '1', RAD_SHIFT, ID_GRID_POINT0625 }, + { "Grid_Set1", '1', 0, ID_GRID_1 }, + { "Grid_Set2", '2', 0, ID_GRID_2 }, + { "Grid_Set4", '3', 0, ID_GRID_4 }, + { "Grid_Set8", '4', 0, ID_GRID_8 }, + { "Grid_Set16", '5', 0, ID_GRID_16 }, + { "Grid_Set32", '6', 0, ID_GRID_32 }, + { "Grid_Set64", '7', 0, ID_GRID_64 }, + { "Grid_Down", 219, 0, ID_GRID_PREV }, + { "Grid_Up", 221, 0, ID_GRID_NEXT }, + + { "Grid_Toggle", '0', 0, ID_GRID_TOGGLE }, + { "Grid_ToggleSizePaint", 'Q', RAD_PRESS, ID_SELECTION_TOGGLESIZEPAINT }, + + { "Grid_PrecisionCursorMode",VK_F11, 0 , ID_PRECISION_CURSOR_CYCLE}, + + { "Grid_NextView", VK_TAB, RAD_CONTROL, ID_VIEW_NEXTVIEW }, + { "Grid_ToggleCrosshairs", 'X', RAD_SHIFT, ID_VIEW_CROSSHAIR }, + + { "Grid_ZZoomOut", VK_INSERT, RAD_CONTROL, ID_VIEW_ZZOOMOUT }, + { "Grid_ZZoomIn", VK_DELETE, RAD_CONTROL, ID_VIEW_ZZOOMIN }, + + { "Brush_Make3Sided", '3', RAD_CONTROL, ID_BRUSH_3SIDED }, + { "Brush_Make4Sided", '4', RAD_CONTROL, ID_BRUSH_4SIDED }, + { "Brush_Make5Sided", '5', RAD_CONTROL, ID_BRUSH_5SIDED }, + { "Brush_Make6Sided", '6', RAD_CONTROL, ID_BRUSH_6SIDED }, + { "Brush_Make7Sided", '7', RAD_CONTROL, ID_BRUSH_7SIDED }, + { "Brush_Make8Sided", '8', RAD_CONTROL, ID_BRUSH_8SIDED }, + { "Brush_Make9Sided", '9', RAD_CONTROL, ID_BRUSH_9SIDED }, + + { "Leak_NextSpot", 'K', RAD_CONTROL|RAD_SHIFT, ID_MISC_NEXTLEAKSPOT }, + { "Leak_PrevSpot", 'L', RAD_CONTROL|RAD_SHIFT, ID_MISC_PREVIOUSLEAKSPOT }, + + { "File_Open", 'O', RAD_CONTROL, ID_FILE_OPEN }, + { "File_Save", 'S', RAD_CONTROL, ID_FILE_SAVE }, + + { "TAB", VK_TAB, 0, ID_PATCH_TAB }, + { "TAB", VK_TAB, RAD_SHIFT, ID_PATCH_TAB }, + + { "Patch_BendMode", 'B', 0, ID_PATCH_BEND }, + { "Patch_FreezeVertices", 'F', 0, ID_CURVE_FREEZE }, + { "Patch_UnFreezeVertices", 'F', RAD_CONTROL, ID_CURVE_UNFREEZE }, + { "Patch_UnFreezeAllVertices",'F', RAD_CONTROL|RAD_SHIFT, ID_CURVE_UNFREEZEALL }, + { "Patch_Thicken", 'T', RAD_CONTROL, ID_CURVE_THICKEN }, + { "Patch_ClearOverlays", 'Y', RAD_SHIFT, ID_CURVE_OVERLAY_CLEAR }, + { "Patch_MakeOverlay", 'Y', 0, ID_CURVE_OVERLAY_SET }, + { "Patch_CycleCapTexturing", 'P', RAD_CONTROL|RAD_SHIFT, ID_CURVE_CYCLECAP }, + { "Patch_CycleCapTexturingAlt",'P', RAD_SHIFT, ID_CURVE_CYCLECAPALT }, + { "Patch_InvertCurve", 'I', RAD_CONTROL, ID_CURVE_NEGATIVE }, + { "Patch_IncPatchColumn", VK_ADD, RAD_CONTROL|RAD_SHIFT, ID_CURVE_INSERTCOLUMN }, + { "Patch_IncPatchRow", VK_ADD, RAD_CONTROL, ID_CURVE_INSERTROW }, + { "Patch_DecPatchColumn", VK_SUBTRACT, RAD_CONTROL|RAD_SHIFT, ID_CURVE_DELETECOLUMN }, + { "Patch_DecPatchRow", VK_SUBTRACT, RAD_CONTROL, ID_CURVE_DELETEROW }, + { "Patch_RedisperseRows", 'E', RAD_CONTROL, ID_CURVE_REDISPERSE_ROWS }, + { "Patch_RedisperseCols", 'E', RAD_CONTROL|RAD_SHIFT, ID_CURVE_REDISPERSE_COLS }, + { "Patch_Naturalize", 'N', RAD_CONTROL, ID_PATCH_NATURALIZE }, + { "Patch_SnapToGrid", 'G', RAD_CONTROL, ID_SELECT_SNAPTOGRID }, + { "Patch_CapCurrentCurve", 'C', RAD_SHIFT, ID_CURVE_CAP }, + + { "Clipper_Toggle", 'X', 0, ID_VIEW_CLIPPER }, + { "Clipper_ClipSelected", VK_RETURN, 0, ID_CLIP_SELECTED }, + { "Clipper_SplitSelected", VK_RETURN, RAD_SHIFT, ID_SPLIT_SELECTED }, + { "Clipper_FlipClip", VK_RETURN, RAD_CONTROL, ID_FLIP_CLIP }, + + { "CameraClip_ZoomOut", 219, RAD_CONTROL, ID_VIEW_CUBEOUT }, + { "CameraClip_ZoomIn", 221, RAD_CONTROL, ID_VIEW_CUBEIN }, + { "CameraClip_Toggle", 220, RAD_CONTROL, ID_VIEW_CUBICCLIPPING }, + + { "ViewTab_EntityInfo", 'N', 0, ID_VIEW_ENTITY }, + { "ViewTab_Console", 'O', 0, ID_VIEW_CONSOLE }, + { "ViewTab_Textures", 'T', 0, ID_VIEW_TEXTURE }, + { "ViewTab_MediaBrowser", 'M', 0, ID_VIEW_MEDIABROWSER }, + + { "Window_SurfaceInspector",'S', 0, ID_TEXTURES_INSPECTOR }, + { "Window_PatchInspector", 'S', RAD_SHIFT, ID_PATCH_INSPECTOR }, + { "Window_EntityList", 'I', 0, ID_EDIT_ENTITYINFO }, + { "Window_Preferences", 'P', 0, ID_PREFS }, + { "Window_ToggleCamera", 'C', RAD_CONTROL|RAD_SHIFT, ID_TOGGLECAMERA }, + { "Window_ToggleView", 'V', RAD_CONTROL|RAD_SHIFT, ID_TOGGLEVIEW }, + { "Window_ToggleZ", 'Z', RAD_CONTROL|RAD_SHIFT, ID_TOGGLEZ }, + { "Window_LightEditor", 'J', 0, ID_PROJECTED_LIGHT }, + { "Window_EntityColor", 'K', 0, ID_MISC_SELECTENTITYCOLOR }, + + { "Selection_DragEdges", 'E', 0, ID_SELECTION_DRAGEDGES }, + { "Selection_DragVertices", 'V', 0, ID_SELECTION_DRAGVERTECIES }, + { "Selection_Clone", VK_SPACE, 0, ID_SELECTION_CLONE }, + { "Selection_Delete", VK_BACK, 0, ID_SELECTION_DELETE }, + { "Selection_UnSelect", VK_ESCAPE, 0, ID_SELECTION_DESELECT }, + { "Selection_Invert", 'I' , 0 , ID_SELECTION_INVERT }, + { "Selection_ToggleMoveOnly",'W', 0, ID_SELECTION_MOVEONLY }, + + { "Selection_MoveDown", VK_SUBTRACT, 0, ID_SELECTION_MOVEDOWN }, + { "Selection_MoveUp", VK_ADD, 0, ID_SELECTION_MOVEUP }, + { "Selection_DumpBrush", 'D', RAD_SHIFT, ID_SELECTION_PRINT }, + { "Selection_NudgeLeft", VK_LEFT, RAD_ALT, ID_SELECTION_SELECT_NUDGELEFT }, + { "Selection_NudgeRight", VK_RIGHT, RAD_ALT, ID_SELECTION_SELECT_NUDGERIGHT }, + { "Selection_NudgeUp", VK_UP, RAD_ALT, ID_SELECTION_SELECT_NUDGEUP }, + { "Selection_NudgeDown", VK_DOWN, RAD_ALT, ID_SELECTION_SELECT_NUDGEDOWN }, + { "Selection_Combine", 'K', RAD_SHIFT, ID_SELECTION_COMBINE }, + { "Selection_Connect", 'K', RAD_CONTROL, ID_SELECTION_CONNECT }, + { "Selection_Ungroup", 'G', RAD_SHIFT, ID_SELECTION_UNGROUPENTITY }, + { "Selection_CSGMerge", 'M', RAD_SHIFT, ID_SELECTION_CSGMERGE }, + + { "Selection_CenterOrigin", 'O', RAD_SHIFT, ID_SELECTION_CENTER_ORIGIN }, + { "Selection_SelectCompleteEntity", 'E' , RAD_CONTROL|RAD_ALT|RAD_SHIFT , ID_SELECT_COMPLETE_ENTITY }, + { "Selection_SelectAllOfType", 'A', RAD_SHIFT, ID_SELECT_ALL }, + + { "Show_ToggleLights", '0' , RAD_ALT , ID_VIEW_SHOWLIGHTS }, + { "Show_TogglePatches", 'P', RAD_CONTROL, ID_VIEW_SHOWCURVES }, + { "Show_ToggleClip", 'L', RAD_CONTROL, ID_VIEW_SHOWCLIP }, + + { "Show_HideSelected", 'H', 0, ID_VIEW_HIDESHOW_HIDESELECTED }, + { "Show_ShowHidden", 'H', RAD_SHIFT, ID_VIEW_HIDESHOW_SHOWHIDDEN }, + { "Show_HideNotSelected", 'H', RAD_CONTROL|RAD_SHIFT, ID_VIEW_HIDESHOW_HIDENOTSELECTED }, + + { "Render_ToggleSound", VK_F9, 0, ID_VIEW_RENDERSOUND }, + { "Render_ToggleSelections", VK_F8, 0, ID_VIEW_RENDERSELECTION }, + { "Render_RebuildData", VK_F7, 0, ID_VIEW_REBUILDRENDERDATA }, + { "Render_ToggleAnimation", VK_F6, 0, ID_VIEW_MATERIALANIMATION}, + { "Render_ToggleEntityOutlines", VK_F5, 0, ID_VIEW_RENDERENTITYOUTLINES }, + { "Render_ToggleRealtimeBuild", VK_F4, 0, ID_VIEW_REALTIMEREBUILD }, + { "Render_Toggle", VK_F3, 0, ID_VIEW_RENDERMODE }, + + { "Find_Textures", 'F', RAD_SHIFT, ID_TEXTURE_REPLACEALL }, + { "Find_Entity", VK_F3, RAD_CONTROL, ID_MISC_FINDORREPLACEENTITY}, + { "Find_NextEntity", VK_F3,RAD_SHIFT, ID_MISC_FINDNEXTENT}, + + { "_ShowDOOM", VK_F2, 0, ID_SHOW_DOOM }, + + { "Rotate_MouseRotate", 'R', 0, ID_SELECT_MOUSEROTATE }, + { "Rotate_ToggleFlatRotation", 'R', RAD_CONTROL, ID_VIEW_CAMERAUPDATE }, + { "Rotate_CycleRotationAxis", 'R', RAD_SHIFT, ID_TOGGLE_ROTATELOCK }, + + { "_AutoCaulk", 'A', RAD_CONTROL|RAD_SHIFT, ID_AUTOCAULK }, // ctrl-shift-a, since SHIFT-A is already taken +}; + +int g_nCommandCount = sizeof(g_Commands) / sizeof(SCommandInfo); + +SKeyInfo g_Keys[] = { + { "Space", VK_SPACE }, + { "Backspace", VK_BACK }, + { "Escape", VK_ESCAPE }, + { "End", VK_END }, + { "Insert", VK_INSERT }, + { "Delete", VK_DELETE }, + { "PageUp", VK_PRIOR }, + { "PageDown", VK_NEXT }, + { "Up", VK_UP }, + { "Down", VK_DOWN }, + { "Left", VK_LEFT }, + { "Right", VK_RIGHT }, + { "F1", VK_F1 }, + { "F2", VK_F2 }, + { "F3", VK_F3 }, + { "F4", VK_F4 }, + { "F5", VK_F5 }, + { "F6", VK_F6 }, + { "F7", VK_F7 }, + { "F8", VK_F8 }, + { "F9", VK_F9 }, + { "F10", VK_F10 }, + { "F11", VK_F11 }, + { "F12", VK_F12 }, + { "Tab", VK_TAB }, + { "Return", VK_RETURN }, + { "Comma", VK_COMMA }, + { "Period", VK_PERIOD }, + { "Plus", VK_ADD }, + { "Multiply", VK_MULTIPLY }, + { "Subtract", VK_SUBTRACT }, + { "NumPad0", VK_NUMPAD0 }, + { "NumPad1", VK_NUMPAD1 }, + { "NumPad2", VK_NUMPAD2 }, + { "NumPad3", VK_NUMPAD3 }, + { "NumPad4", VK_NUMPAD4 }, + { "NumPad5", VK_NUMPAD5 }, + { "NumPad6", VK_NUMPAD6 }, + { "NumPad7", VK_NUMPAD7 }, + { "NumPad8", VK_NUMPAD8 }, + { "NumPad9", VK_NUMPAD9 }, + { "[", 219 }, + { "]", 221 }, + { "\\", 220 } +}; + +int g_nKeyCount = sizeof(g_Keys) / sizeof(SKeyInfo); + +const int CMD_TEXTUREWAD_END = CMD_TEXTUREWAD + 127; +const int CMD_BSPCOMMAND_END = CMD_BSPCOMMAND + 127; +const int IDMRU_END = IDMRU + 9; + +const int g_msgBSPDone = RegisterWindowMessage(DMAP_DONE); +const int g_msgBSPStatus = RegisterWindowMessage(DMAP_MSGID); + +IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) +//{{AFX_MSG_MAP(CMainFrame) + ON_WM_PARENTNOTIFY() + ON_WM_CREATE() + ON_WM_TIMER() + ON_WM_DESTROY() + ON_WM_CLOSE() + ON_WM_KEYDOWN() + ON_WM_SIZE() + ON_COMMAND(ID_VIEW_CAMERATOGGLE, ToggleCamera) + ON_COMMAND(ID_FILE_CLOSE, OnFileClose) + ON_COMMAND(ID_FILE_EXIT, OnFileExit) + ON_COMMAND(ID_FILE_LOADPROJECT, OnFileLoadproject) + ON_COMMAND(ID_FILE_NEW, OnFileNew) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_POINTFILE, OnFilePointfile) + ON_COMMAND(ID_FILE_PRINT, OnFilePrint) + ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_FILE_SAVEAS, OnFileSaveas) + ON_COMMAND(D3XP_ID_FILE_SAVE_COPY, OnFileSaveCopy) + ON_COMMAND(D3XP_ID_SHOW_MODELS, OnViewShowModels ) + ON_COMMAND(ID_VIEW_100, OnView100) + ON_COMMAND(ID_VIEW_CENTER, OnViewCenter) + ON_COMMAND(ID_VIEW_CONSOLE, OnViewConsole) + ON_COMMAND(ID_VIEW_DOWNFLOOR, OnViewDownfloor) + ON_COMMAND(ID_VIEW_ENTITY, OnViewEntity) + ON_COMMAND(ID_VIEW_MEDIABROWSER, OnViewMediaBrowser) + ON_COMMAND(ID_VIEW_FRONT, OnViewFront) + ON_COMMAND(ID_VIEW_SHOWBLOCKS, OnViewShowblocks) + ON_COMMAND(ID_VIEW_SHOWCLIP, OnViewShowclip) + ON_COMMAND(ID_VIEW_SHOWTRIGGERS, OnViewShowTriggers) + ON_COMMAND(ID_VIEW_SHOWCOORDINATES, OnViewShowcoordinates) + ON_COMMAND(ID_VIEW_SHOWENT, OnViewShowent) + ON_COMMAND(ID_VIEW_SHOWLIGHTS, OnViewShowlights) + ON_COMMAND(ID_VIEW_SHOWNAMES, OnViewShownames) + ON_COMMAND(ID_VIEW_SHOWPATH, OnViewShowpath) + ON_COMMAND(ID_VIEW_SHOWCOMBATNODES, OnViewShowCombatNodes) + ON_COMMAND(ID_VIEW_SHOWWATER, OnViewShowwater) + ON_COMMAND(ID_VIEW_SHOWWORLD, OnViewShowworld) + ON_COMMAND(ID_VIEW_TEXTURE, OnViewTexture) + ON_COMMAND(ID_VIEW_UPFLOOR, OnViewUpfloor) + ON_COMMAND(ID_VIEW_XY, OnViewXy) + ON_COMMAND(ID_VIEW_Z100, OnViewZ100) + ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin) + ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout) + ON_COMMAND(ID_VIEW_ZZOOMIN, OnViewZzoomin) + ON_COMMAND(ID_VIEW_ZZOOMOUT, OnViewZzoomout) + ON_COMMAND(ID_VIEW_SIDE, OnViewSide) + ON_COMMAND(ID_TEXTURES_SHOWINUSE, OnTexturesShowinuse) + ON_COMMAND(ID_TEXTURES_INSPECTOR, OnTexturesInspector) + ON_COMMAND(ID_MISC_FINDBRUSH, OnMiscFindbrush) + ON_COMMAND(ID_MISC_GAMMA, OnMiscGamma) + ON_COMMAND(ID_MISC_NEXTLEAKSPOT, OnMiscNextleakspot) + ON_COMMAND(ID_MISC_PREVIOUSLEAKSPOT, OnMiscPreviousleakspot) + ON_COMMAND(ID_MISC_PRINTXY, OnMiscPrintxy) + ON_COMMAND(ID_MISC_SELECTENTITYCOLOR, OnMiscSelectentitycolor) + ON_COMMAND(ID_MISC_FINDORREPLACEENTITY, OnMiscFindOrReplaceEntity) + ON_COMMAND(ID_MISC_FINDNEXTENT, OnMiscFindNextEntity) + ON_COMMAND(ID_MISC_SETVIEWPOS, OnMiscSetViewPos) + ON_COMMAND(ID_TEXTUREBK, OnTexturebk) + ON_COMMAND(ID_COLORS_MAJOR, OnColorsMajor) + ON_COMMAND(ID_COLORS_MINOR, OnColorsMinor) + ON_COMMAND(ID_COLORS_XYBK, OnColorsXybk) + ON_COMMAND(ID_BRUSH_3SIDED, OnBrush3sided) + ON_COMMAND(ID_BRUSH_4SIDED, OnBrush4sided) + ON_COMMAND(ID_BRUSH_5SIDED, OnBrush5sided) + ON_COMMAND(ID_BRUSH_6SIDED, OnBrush6sided) + ON_COMMAND(ID_BRUSH_7SIDED, OnBrush7sided) + ON_COMMAND(ID_BRUSH_8SIDED, OnBrush8sided) + ON_COMMAND(ID_BRUSH_9SIDED, OnBrush9sided) + ON_COMMAND(ID_BRUSH_ARBITRARYSIDED, OnBrushArbitrarysided) + ON_COMMAND(ID_BRUSH_FLIPX, OnBrushFlipx) + ON_COMMAND(ID_BRUSH_FLIPY, OnBrushFlipy) + ON_COMMAND(ID_BRUSH_FLIPZ, OnBrushFlipz) + ON_COMMAND(ID_BRUSH_ROTATEX, OnBrushRotatex) + ON_COMMAND(ID_BRUSH_ROTATEY, OnBrushRotatey) + ON_COMMAND(ID_BRUSH_ROTATEZ, OnBrushRotatez) + ON_COMMAND(ID_REGION_OFF, OnRegionOff) + ON_COMMAND(ID_REGION_SETBRUSH, OnRegionSetbrush) + ON_COMMAND(ID_REGION_SETSELECTION, OnRegionSetselection) + ON_COMMAND(ID_REGION_SETTALLBRUSH, OnRegionSettallbrush) + ON_COMMAND(ID_REGION_SETXY, OnRegionSetxy) + ON_COMMAND(ID_SELECTION_ARBITRARYROTATION, OnSelectionArbitraryrotation) + ON_COMMAND(ID_SELECTION_CLONE, OnSelectionClone) + ON_COMMAND(ID_SELECTION_CONNECT, OnSelectionConnect) + ON_COMMAND(ID_SELECTION_CSGSUBTRACT, OnSelectionCsgsubtract) + ON_COMMAND(ID_SELECTION_CSGMERGE, OnSelectionCsgmerge) + ON_COMMAND(ID_SELECTION_DELETE, OnSelectionDelete) + ON_COMMAND(ID_SELECTION_DESELECT, OnSelectionDeselect) + ON_COMMAND(ID_SELECTION_DRAGEDGES, OnSelectionDragedges) + ON_COMMAND(ID_SELECTION_DRAGVERTECIES, OnSelectionDragvertecies) + ON_COMMAND(ID_SELECTION_CENTER_ORIGIN, OnSelectionCenterOrigin) + ON_COMMAND(ID_SELECTION_MAKEHOLLOW, OnSelectionMakehollow) + ON_COMMAND(ID_SELECTION_SELECTCOMPLETETALL, OnSelectionSelectcompletetall) + ON_COMMAND(ID_SELECTION_SELECTINSIDE, OnSelectionSelectinside) + ON_COMMAND(ID_SELECTION_SELECTPARTIALTALL, OnSelectionSelectpartialtall) + ON_COMMAND(ID_SELECTION_SELECTTOUCHING, OnSelectionSelecttouching) + ON_COMMAND(ID_SELECTION_UNGROUPENTITY, OnSelectionUngroupentity) + ON_COMMAND(ID_TEXTURES_POPUP, OnTexturesPopup) + ON_COMMAND(ID_SPLINES_POPUP, OnSplinesPopup) + ON_COMMAND(ID_SPLINES_EDITPOINTS, OnSplinesEditPoints) + ON_COMMAND(ID_SPLINES_ADDPOINTS, OnSplinesAddPoints) + ON_COMMAND(ID_SPLINES_INSERTPOINTS, OnSplinesInsertPoint) + ON_COMMAND(ID_SPLINES_DELETEPOINTS, OnSplinesDeletePoint) + ON_COMMAND(ID_POPUP_SELECTION, OnPopupSelection) + ON_COMMAND(ID_VIEW_CHANGE, OnViewChange) + ON_COMMAND(ID_VIEW_CAMERAUPDATE, OnViewCameraupdate) + ON_WM_SIZING() + ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout) + ON_COMMAND(ID_VIEW_CLIPPER, OnViewClipper) + ON_COMMAND(ID_CAMERA_ANGLEDOWN, OnCameraAngledown) + ON_COMMAND(ID_CAMERA_ANGLEUP, OnCameraAngleup) + ON_COMMAND(ID_CAMERA_BACK, OnCameraBack) + ON_COMMAND(ID_CAMERA_DOWN, OnCameraDown) + ON_COMMAND(ID_CAMERA_FORWARD, OnCameraForward) + ON_COMMAND(ID_CAMERA_LEFT, OnCameraLeft) + ON_COMMAND(ID_CAMERA_RIGHT, OnCameraRight) + ON_COMMAND(ID_CAMERA_STRAFELEFT, OnCameraStrafeleft) + ON_COMMAND(ID_CAMERA_STRAFERIGHT, OnCameraStraferight) + ON_COMMAND(ID_CAMERA_UP, OnCameraUp) + ON_COMMAND(ID_GRID_TOGGLE, OnGridToggle) + ON_COMMAND(ID_PREFS, OnPrefs) + ON_COMMAND(ID_TOGGLECAMERA, OnTogglecamera) + ON_COMMAND(ID_TOGGLEVIEW, OnToggleview) + ON_COMMAND(ID_TOGGLEZ, OnTogglez) + ON_COMMAND(ID_TOGGLE_LOCK, OnToggleLock) + ON_COMMAND(ID_EDIT_MAPINFO, OnEditMapinfo) + ON_COMMAND(ID_EDIT_ENTITYINFO, OnEditEntityinfo) + ON_COMMAND(ID_VIEW_NEXTVIEW, OnViewNextview) + ON_COMMAND(ID_HELP_COMMANDLIST, OnHelpCommandlist) + ON_COMMAND(ID_FILE_NEWPROJECT, OnFileNewproject) + ON_COMMAND(ID_FLIP_CLIP, OnFlipClip) + ON_COMMAND(ID_CLIP_SELECTED, OnClipSelected) + ON_COMMAND(ID_SPLIT_SELECTED, OnSplitSelected) + ON_COMMAND(ID_TOGGLEVIEW_XZ, OnToggleviewXz) + ON_COMMAND(ID_TOGGLEVIEW_YZ, OnToggleviewYz) + ON_COMMAND(ID_COLORS_BRUSH, OnColorsBrush) + ON_COMMAND(ID_COLORS_CLIPPER, OnColorsClipper) + ON_COMMAND(ID_COLORS_GRIDTEXT, OnColorsGridtext) + ON_COMMAND(ID_COLORS_SELECTEDBRUSH, OnColorsSelectedbrush) + ON_COMMAND(ID_COLORS_GRIDBLOCK, OnColorsGridblock) + ON_COMMAND(ID_COLORS_VIEWNAME, OnColorsViewname) + ON_COMMAND(ID_COLOR_SETORIGINAL, OnColorSetoriginal) + ON_COMMAND(ID_COLOR_SETQER, OnColorSetqer) + ON_COMMAND(ID_COLOR_SUPERMAL, OnColorSetSuperMal) + ON_COMMAND(ID_THEMES_MAX , OnColorSetMax ) + ON_COMMAND(ID_COLOR_SETBLACK, OnColorSetblack) + ON_COMMAND(ID_SNAPTOGRID, OnSnaptogrid) + ON_COMMAND(ID_SELECT_SCALE, OnSelectScale) + ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate) + ON_COMMAND(ID_EDIT_COPYBRUSH, OnEditCopybrush) + ON_COMMAND(ID_EDIT_PASTEBRUSH, OnEditPastebrush) + ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) + ON_COMMAND(ID_EDIT_REDO, OnEditRedo) + ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) + ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) + ON_COMMAND(ID_SELECTION_INVERT, OnSelectionInvert) + ON_COMMAND(ID_SELECTION_TEXTURE_DEC, OnSelectionTextureDec) + ON_COMMAND(ID_SELECTION_TEXTURE_FIT, OnSelectionTextureFit) + ON_COMMAND(ID_SELECTION_TEXTURE_INC, OnSelectionTextureInc) + ON_COMMAND(ID_SELECTION_TEXTURE_ROTATECLOCK, OnSelectionTextureRotateclock) + ON_COMMAND(ID_SELECTION_TEXTURE_ROTATECOUNTER, OnSelectionTextureRotatecounter) + ON_COMMAND(ID_SELECTION_TEXTURE_SCALEDOWN, OnSelectionTextureScaledown) + ON_COMMAND(ID_SELECTION_TEXTURE_SCALEUP, OnSelectionTextureScaleup) + ON_COMMAND(ID_SELECTION_TEXTURE_SHIFTDOWN, OnSelectionTextureShiftdown) + ON_COMMAND(ID_SELECTION_TEXTURE_SHIFTLEFT, OnSelectionTextureShiftleft) + ON_COMMAND(ID_SELECTION_TEXTURE_SHIFTRIGHT, OnSelectionTextureShiftright) + ON_COMMAND(ID_SELECTION_TEXTURE_SHIFTUP, OnSelectionTextureShiftup) + ON_COMMAND(ID_GRID_NEXT, OnGridNext) + ON_COMMAND(ID_GRID_PREV, OnGridPrev) + ON_COMMAND(ID_SELECTION_TEXTURE_SCALELEFT, OnSelectionTextureScaleLeft) + ON_COMMAND(ID_SELECTION_TEXTURE_SCALERIGHT, OnSelectionTextureScaleRight) + ON_COMMAND(ID_TEXTURE_REPLACEALL, OnTextureReplaceall) + ON_COMMAND(ID_SCALELOCKX, OnScalelockx) + ON_COMMAND(ID_SCALELOCKY, OnScalelocky) + ON_COMMAND(ID_SCALELOCKZ, OnScalelockz) + ON_COMMAND(ID_SELECT_MOUSESCALE, OnSelectMousescale) + ON_COMMAND(ID_VIEW_CUBICCLIPPING, OnViewCubicclipping) + ON_COMMAND(ID_FILE_IMPORT, OnFileImport) + ON_COMMAND(ID_FILE_PROJECTSETTINGS, OnFileProjectsettings) + ON_UPDATE_COMMAND_UI(ID_FILE_IMPORT, OnUpdateFileImport) + ON_COMMAND(ID_VIEW_CUBEIN, OnViewCubein) + ON_COMMAND(ID_VIEW_CUBEOUT, OnViewCubeout) + ON_COMMAND(ID_FILE_SAVEREGION, OnFileSaveregion) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVEREGION, OnUpdateFileSaveregion) + ON_COMMAND(ID_SELECTION_MOVEDOWN, OnSelectionMovedown) + ON_COMMAND(ID_SELECTION_MOVEUP, OnSelectionMoveup) + ON_COMMAND(ID_TOOLBAR_MAIN, OnToolbarMain) + ON_COMMAND(ID_TOOLBAR_TEXTURE, OnToolbarTexture) + ON_COMMAND(ID_SELECTION_PRINT, OnSelectionPrint) + ON_COMMAND(ID_SELECTION_TOGGLESIZEPAINT, OnSelectionTogglesizepaint) + ON_COMMAND(ID_BRUSH_MAKECONE, OnBrushMakecone) + ON_COMMAND(ID_TEXTURES_LOAD, OnTexturesLoad) + ON_COMMAND(ID_TOGGLE_ROTATELOCK, OnToggleRotatelock) + ON_COMMAND(ID_CURVE_BEVEL, OnCurveBevel) + ON_COMMAND(ID_CURVE_INCREASE_VERT, OnCurveIncreaseVert) + ON_COMMAND(ID_CURVE_DECREASE_VERT, OnCurveDecreaseVert) + ON_COMMAND(ID_CURVE_INCREASE_HORZ, OnCurveIncreaseHorz) + ON_COMMAND(ID_CURVE_DECREASE_HORZ, OnCurveDecreaseHorz) + ON_COMMAND(ID_CURVE_CYLINDER, OnCurveCylinder) + ON_COMMAND(ID_CURVE_EIGHTHSPHERE, OnCurveEighthsphere) + ON_COMMAND(ID_CURVE_ENDCAP, OnCurveEndcap) + ON_COMMAND(ID_CURVE_HEMISPHERE, OnCurveHemisphere) + ON_COMMAND(ID_CURVE_INVERTCURVE, OnCurveInvertcurve) + ON_COMMAND(ID_CURVE_QUARTER, OnCurveQuarter) + ON_COMMAND(ID_CURVE_SPHERE, OnCurveSphere) + ON_COMMAND(ID_FILE_IMPORTMAP, OnFileImportmap) + ON_COMMAND(ID_FILE_EXPORTMAP, OnFileExportmap) + ON_COMMAND(ID_EDIT_LOADPREFAB, OnEditLoadprefab) + ON_COMMAND(ID_VIEW_SHOWCURVES, OnViewShowcurves) + ON_COMMAND(ID_SELECTION_SELECT_NUDGEDOWN, OnSelectionSelectNudgedown) + ON_COMMAND(ID_SELECTION_SELECT_NUDGELEFT, OnSelectionSelectNudgeleft) + ON_COMMAND(ID_SELECTION_SELECT_NUDGERIGHT, OnSelectionSelectNudgeright) + ON_COMMAND(ID_SELECTION_SELECT_NUDGEUP, OnSelectionSelectNudgeup) + ON_WM_SYSKEYDOWN() + ON_COMMAND(ID_TEXTURES_LOADLIST, OnTexturesLoadlist) + ON_COMMAND(ID_DYNAMIC_LIGHTING, OnDynamicLighting) + ON_COMMAND(ID_CURVE_SIMPLEPATCHMESH, OnCurveSimplepatchmesh) + ON_COMMAND(ID_PATCH_SHOWBOUNDINGBOX, OnPatchToggleBox) + ON_COMMAND(ID_PATCH_WIREFRAME, OnPatchWireframe) + ON_COMMAND(ID_CURVE_PATCHCONE, OnCurvePatchcone) + ON_COMMAND(ID_CURVE_PATCHTUBE, OnCurvePatchtube) + ON_COMMAND(ID_PATCH_WELD, OnPatchWeld) + ON_COMMAND(ID_CURVE_PATCHBEVEL, OnCurvePatchbevel) + ON_COMMAND(ID_CURVE_PATCHENDCAP, OnCurvePatchendcap) + ON_COMMAND(ID_CURVE_PATCHINVERTEDBEVEL, OnCurvePatchinvertedbevel) + ON_COMMAND(ID_CURVE_PATCHINVERTEDENDCAP, OnCurvePatchinvertedendcap) + ON_COMMAND(ID_PATCH_DRILLDOWN, OnPatchDrilldown) + ON_COMMAND(ID_CURVE_INSERTCOLUMN, OnCurveInsertcolumn) + ON_COMMAND(ID_CURVE_INSERTROW, OnCurveInsertrow) + ON_COMMAND(ID_CURVE_DELETECOLUMN, OnCurveDeletecolumn) + ON_COMMAND(ID_CURVE_DELETEROW, OnCurveDeleterow) + ON_COMMAND(ID_CURVE_INSERT_ADDCOLUMN, OnCurveInsertAddcolumn) + ON_COMMAND(ID_CURVE_INSERT_ADDROW, OnCurveInsertAddrow) + ON_COMMAND(ID_CURVE_INSERT_INSERTCOLUMN, OnCurveInsertInsertcolumn) + ON_COMMAND(ID_CURVE_INSERT_INSERTROW, OnCurveInsertInsertrow) + ON_COMMAND(ID_CURVE_NEGATIVE, OnCurveNegative) + ON_COMMAND(ID_CURVE_NEGATIVETEXTUREX, OnCurveNegativeTextureX) + ON_COMMAND(ID_CURVE_NEGATIVETEXTUREY, OnCurveNegativeTextureY) + ON_COMMAND(ID_CURVE_DELETE_FIRSTCOLUMN, OnCurveDeleteFirstcolumn) + ON_COMMAND(ID_CURVE_DELETE_FIRSTROW, OnCurveDeleteFirstrow) + ON_COMMAND(ID_CURVE_DELETE_LASTCOLUMN, OnCurveDeleteLastcolumn) + ON_COMMAND(ID_CURVE_DELETE_LASTROW, OnCurveDeleteLastrow) + ON_COMMAND(ID_PATCH_BEND, OnPatchBend) + ON_COMMAND(ID_PATCH_INSDEL, OnPatchInsdel) + ON_COMMAND(ID_PATCH_ENTER, OnPatchEnter) + ON_COMMAND(ID_PATCH_TAB, OnPatchTab) + ON_COMMAND(ID_CURVE_PATCHDENSETUBE, OnCurvePatchdensetube) + ON_COMMAND(ID_CURVE_PATCHVERYDENSETUBE, OnCurvePatchverydensetube) + ON_COMMAND(ID_CURVE_CAP, OnCurveCap) + ON_COMMAND(ID_CURVE_CAP_INVERTEDBEVEL, OnCurveCapInvertedbevel) + ON_COMMAND(ID_CURVE_CAP_INVERTEDENDCAP, OnCurveCapInvertedendcap) + ON_COMMAND(ID_CURVE_REDISPERSE_COLS, OnCurveRedisperseCols) + ON_COMMAND(ID_CURVE_REDISPERSE_ROWS, OnCurveRedisperseRows) + ON_COMMAND(ID_PATCH_NATURALIZE, OnPatchNaturalize) + ON_COMMAND(ID_PATCH_NATURALIZEALT, OnPatchNaturalizeAlt) + ON_COMMAND(ID_SELECT_SNAPTOGRID, OnSnapToGrid) + ON_COMMAND(ID_CURVE_PATCHSQUARE, OnCurvePatchsquare) + ON_COMMAND(ID_TEXTURES_TEXTUREWINDOWSCALE_10, OnTexturesTexturewindowscale10) + ON_COMMAND(ID_TEXTURES_TEXTUREWINDOWSCALE_100, OnTexturesTexturewindowscale100) + ON_COMMAND(ID_TEXTURES_TEXTUREWINDOWSCALE_200, OnTexturesTexturewindowscale200) + ON_COMMAND(ID_TEXTURES_TEXTUREWINDOWSCALE_25, OnTexturesTexturewindowscale25) + ON_COMMAND(ID_TEXTURES_TEXTUREWINDOWSCALE_50, OnTexturesTexturewindowscale50) + ON_COMMAND(ID_TEXTURES_FLUSH, OnTexturesFlush) + ON_COMMAND(ID_CURVE_OVERLAY_CLEAR, OnCurveOverlayClear) + ON_COMMAND(ID_CURVE_OVERLAY_SET, OnCurveOverlaySet) + ON_COMMAND(ID_CURVE_THICKEN, OnCurveThicken) + ON_COMMAND(ID_CURVE_CYCLECAP, OnCurveCyclecap) + ON_COMMAND(ID_CURVE_CYCLECAPALT, OnCurveCyclecapAlt) + ON_COMMAND(ID_CURVE_MATRIX_TRANSPOSE, OnCurveMatrixTranspose) + ON_COMMAND(ID_TEXTURES_RELOADSHADERS, OnTexturesReloadshaders) + ON_COMMAND(ID_SHOW_ENTITIES, OnShowEntities) + ON_COMMAND(ID_VIEW_ENTITIESAS_SKINNED, OnViewEntitiesasSkinned) + ON_COMMAND(ID_VIEW_ENTITIESAS_WIREFRAME, OnViewEntitiesasWireframe) + ON_COMMAND(ID_VIEW_SHOWHINT, OnViewShowhint) + ON_UPDATE_COMMAND_UI(ID_TEXTURES_SHOWINUSE, OnUpdateTexturesShowinuse) + ON_COMMAND(ID_TEXTURES_SHOWALL, OnTexturesShowall) + ON_COMMAND(ID_TEXTURES_HIDEALL, OnTexturesHideall) + ON_COMMAND(ID_PATCH_INSPECTOR, OnPatchInspector) + ON_COMMAND(ID_VIEW_OPENGLLIGHTING, OnViewOpengllighting) + ON_COMMAND(ID_SELECT_ALL, OnSelectAll) + ON_COMMAND(ID_VIEW_SHOWCAULK, OnViewShowcaulk) + ON_COMMAND(ID_CURVE_FREEZE, OnCurveFreeze) + ON_COMMAND(ID_CURVE_UNFREEZE, OnCurveUnFreeze) + ON_COMMAND(ID_CURVE_UNFREEZEALL, OnCurveUnFreezeAll) + ON_COMMAND(ID_SELECT_RESELECT, OnSelectReselect) + ON_COMMAND(ID_VIEW_SHOWANGLES, OnViewShowangles) + ON_COMMAND(ID_EDIT_SAVEPREFAB, OnEditSaveprefab) + ON_COMMAND(ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL, OnCurveMoreendcapsbevelsSquarebevel) + ON_COMMAND(ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP, OnCurveMoreendcapsbevelsSquareendcap) + ON_COMMAND(ID_BRUSH_PRIMITIVES_SPHERE, OnBrushPrimitivesSphere) + ON_COMMAND(ID_VIEW_CROSSHAIR, OnViewCrosshair) + ON_COMMAND(ID_VIEW_HIDESHOW_HIDESELECTED, OnViewHideshowHideselected) + ON_COMMAND(ID_VIEW_HIDESHOW_HIDENOTSELECTED, OnViewHideshowHideNotselected) + ON_COMMAND(ID_VIEW_HIDESHOW_SHOWHIDDEN, OnViewHideshowShowhidden) + ON_COMMAND(ID_TEXTURES_SHADERS_SHOW, OnTexturesShadersShow) + ON_COMMAND(ID_TEXTURES_FLUSH_UNUSED, OnTexturesFlushUnused) + ON_COMMAND(ID_PROJECTED_LIGHT, OnProjectedLight) + ON_COMMAND(ID_SHOW_LIGHTTEXTURES, OnShowLighttextures) + ON_COMMAND(ID_SHOW_LIGHTVOLUMES, OnShowLightvolumes) + ON_WM_ACTIVATE() + ON_COMMAND(ID_SPLINES_MODE, OnSplinesMode) + ON_COMMAND(ID_SPLINES_LOAD, OnSplinesLoad) + ON_COMMAND(ID_SPLINES_SAVE, OnSplinesSave) + //ON_COMMAND(ID_SPLINES_EDIT, OnSplinesEdit) + ON_COMMAND(ID_SPLINE_TEST, OnSplineTest) + ON_COMMAND(ID_POPUP_NEWCAMERA_INTERPOLATED, OnPopupNewcameraInterpolated) + ON_COMMAND(ID_POPUP_NEWCAMERA_SPLINE, OnPopupNewcameraSpline) + ON_COMMAND(ID_POPUP_NEWCAMERA_FIXED, OnPopupNewcameraFixed) + ON_COMMAND(ID_SELECTION_MOVEONLY, OnSelectionMoveonly) + ON_COMMAND(ID_SELECT_BRUSHESONLY, OnSelectBrushesOnly) + ON_COMMAND(ID_SELECT_BYBOUNDINGBRUSH, OnSelectByBoundingBrush) + ON_COMMAND(ID_SELECTION_COMBINE, OnSelectionCombine) + ON_COMMAND(ID_PATCH_COMBINE, OnPatchCombine) + ON_COMMAND(ID_SHOW_DOOM, OnShowDoom) + ON_COMMAND(ID_VIEW_RENDERMODE, OnViewRendermode) + ON_COMMAND(ID_VIEW_REBUILDRENDERDATA, OnViewRebuildrenderdata) + ON_COMMAND(ID_VIEW_REALTIMEREBUILD, OnViewRealtimerebuild) + ON_COMMAND(ID_VIEW_RENDERENTITYOUTLINES, OnViewRenderentityoutlines) + ON_COMMAND(ID_VIEW_MATERIALANIMATION, OnViewMaterialanimation) + ON_COMMAND(ID_SELECT_AXIALTEXTURE_BYWIDTH, OnAxialTextureByWidth) + ON_COMMAND(ID_SELECT_AXIALTEXTURE_BYHEIGHT, OnAxialTextureByHeight) + ON_COMMAND(ID_SELECT_AXIALTEXTURE_ARBITRARY, OnAxialTextureArbitrary) + ON_COMMAND(ID_SELECTION_EXPORT_TOOBJ, OnSelectionExportToobj) + ON_COMMAND(ID_SELECTION_EXPORT_TOCM, OnSelectionExportToCM) + ON_COMMAND(ID_VIEW_RENDERSELECTION, OnViewRenderselection) + ON_COMMAND(ID_SELECT_NOMODELS, OnSelectNomodels) + ON_COMMAND(ID_VIEW_SHOW_SHOWVISPORTALS, OnViewShowShowvisportals) + ON_COMMAND(ID_VIEW_SHOW_NODRAW, OnViewShowNoDraw) + ON_COMMAND(ID_VIEW_RENDERSOUND, OnViewRendersound) + ON_COMMAND(ID_SOUND_SHOWSOUNDVOLUMES, OnSoundShowsoundvolumes) + ON_COMMAND(ID_SOUND_SHOWSELECTEDSOUNDVOLUMES, OnSoundShowselectedsoundvolumes) + ON_COMMAND(ID_PATCH_NURBEDITOR, OnNurbEditor) + ON_COMMAND(ID_SELECT_COMPLETE_ENTITY, OnSelectCompleteEntity) + ON_COMMAND(ID_PRECISION_CURSOR_CYCLE , OnPrecisionCursorCycle) + ON_COMMAND(ID_MATERIALS_GENERATEMATERIALSLIST,OnGenerateMaterialsList) + ON_COMMAND(ID_SELECTION_VIEW_WIREFRAMEON, OnSelectionWireFrameOn) + ON_COMMAND(ID_SELECTION_VIEW_WIREFRAMEOFF, OnSelectionWireFrameOff) + ON_COMMAND(ID_SELECTION_VIEW_VISIBLEON, OnSelectionVisibleOn) + ON_COMMAND(ID_SELECTION_VIEW_VISIBLEOFF, OnSelectionVisibleOff) + //}}AFX_MSG_MAP + ON_COMMAND_RANGE(CMD_TEXTUREWAD, CMD_TEXTUREWAD_END, OnTextureWad) + ON_COMMAND_RANGE(CMD_BSPCOMMAND, CMD_BSPCOMMAND_END, OnBspCommand) + ON_COMMAND_RANGE(IDMRU, IDMRU_END, OnMru) + ON_COMMAND_RANGE(ID_VIEW_NEAREST, ID_TEXTURES_FLATSHADE, OnViewNearest) + ON_COMMAND_RANGE(ID_GRID_POINT0625, ID_GRID_64, OnGrid1) +#if _MSC_VER < 1300 + ON_REGISTERED_MESSAGE(g_msgBSPDone, OnBSPDone) + ON_REGISTERED_MESSAGE(g_msgBSPStatus, OnBSPStatus) + ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange) +#endif + ON_COMMAND(ID_AUTOCAULK, OnAutocaulk) + ON_UPDATE_COMMAND_UI(ID_AUTOCAULK, OnUpdateAutocaulk) + ON_COMMAND(ID_SELECT_ALLTARGETS, OnSelectAlltargets) + END_MESSAGE_MAP() +static UINT indicators[] = { + ID_SEPARATOR, // status line indicator + ID_SEPARATOR, // status line indicator + ID_SEPARATOR, // status line indicator + ID_SEPARATOR, // status line indicator + ID_SEPARATOR, // status line indicator + ID_SEPARATOR, // status line indicator +}; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnDisplayChange(UINT wParam, long lParam) { + int n = wParam; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBSPStatus(UINT wParam, long lParam) { + // lparam is an atom contain the text + char buff[1024]; + if (::GlobalGetAtomName(static_cast(lParam), buff, sizeof(buff))) { + common->Printf("%s", buff); + ::GlobalDeleteAtom(static_cast(lParam)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBSPDone(UINT wParam, long lParam) { + idStr str = cvarSystem->GetCVarString( "radiant_bspdone" ); + if (str.Length()) { + sndPlaySound(str.c_str(), SND_FILENAME | SND_ASYNC); + } +} + +// +// ======================================================================================================================= +// CMainFrame construction/destruction +// ======================================================================================================================= +// +CMainFrame::CMainFrame() { + m_bDoLoop = false; + g_pParentWnd = this; + m_pXYWnd = NULL; + m_pCamWnd = NULL; + m_pZWnd = NULL; + m_pYZWnd = NULL; + m_pXZWnd = NULL; + m_pActiveXY = NULL; + m_bCamPreview = true; + nurbMode = 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CMainFrame::~CMainFrame() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void HandlePopup(CWnd *pWindow, unsigned int uId) { + // Get the current position of the mouse + CPoint ptMouse; + GetCursorPos(&ptMouse); + + // Load up a menu that has the options we are looking for in it + CMenu mnuPopup; + VERIFY(mnuPopup.LoadMenu(uId)); + mnuPopup.GetSubMenu(0)->TrackPopupMenu + ( + TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, + ptMouse.x, + ptMouse.y, + pWindow + ); + mnuPopup.DestroyMenu(); + + // Set focus back to window + pWindow->SetFocus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnParentNotify(UINT message, LPARAM lParam) { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetButtonMenuStates() { + CMenu *pMenu = GetMenu(); + if (pMenu) { + // + pMenu->CheckMenuItem(ID_VIEW_SHOWNAMES, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWCOMBATNODES, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_ENTITY, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWTRIGGERS, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWHINT, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWCAULK, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOW_SHOWVISPORTALS, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOW_NODRAW, MF_BYCOMMAND | MF_CHECKED); + pMenu->CheckMenuItem(ID_VIEW_SHOWANGLES, MF_BYCOMMAND | MF_CHECKED); + + if (!g_qeglobals.d_savedinfo.show_names) { + pMenu->CheckMenuItem(ID_VIEW_SHOWNAMES, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (!g_qeglobals.d_savedinfo.show_coordinates) { + pMenu->CheckMenuItem(ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS) { + pMenu->CheckMenuItem(ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_COMBATNODES) { + pMenu->CheckMenuItem(ID_VIEW_SHOWCOMBATNODES, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT) { + pMenu->CheckMenuItem(ID_VIEW_ENTITY, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) { + pMenu->CheckMenuItem(ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DYNAMICS) { + pMenu->CheckMenuItem(ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) { + pMenu->CheckMenuItem(ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) { + pMenu->CheckMenuItem(ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) { + pMenu->CheckMenuItem(ID_VIEW_SHOWTRIGGERS, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT) { + pMenu->CheckMenuItem(ID_VIEW_SHOWHINT, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { + pMenu->CheckMenuItem(ID_VIEW_SHOWCAULK, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_VISPORTALS) { + pMenu->CheckMenuItem(ID_VIEW_SHOW_SHOWVISPORTALS, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_NODRAW) { + pMenu->CheckMenuItem(ID_VIEW_SHOW_NODRAW, MF_BYCOMMAND | MF_UNCHECKED); + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES) { + pMenu->CheckMenuItem(ID_VIEW_SHOWANGLES, MF_BYCOMMAND | MF_UNCHECKED); + } + + pMenu->CheckMenuItem(ID_TOGGLE_LOCK, MF_BYCOMMAND | (g_PrefsDlg.m_bTextureLock) ? MF_CHECKED : MF_UNCHECKED); + pMenu->CheckMenuItem + ( + ID_TOGGLE_ROTATELOCK, + MF_BYCOMMAND | (g_PrefsDlg.m_bRotateLock) ? MF_CHECKED : MF_UNCHECKED + ); + pMenu->CheckMenuItem + ( + ID_VIEW_CUBICCLIPPING, + MF_BYCOMMAND | (g_PrefsDlg.m_bCubicClipping) ? MF_CHECKED : MF_UNCHECKED + ); + pMenu->CheckMenuItem + ( + ID_VIEW_OPENGLLIGHTING, + MF_BYCOMMAND | (g_PrefsDlg.m_bGLLighting) ? MF_CHECKED : MF_UNCHECKED + ); + pMenu->CheckMenuItem(ID_SNAPTOGRID, MF_BYCOMMAND | (!g_PrefsDlg.m_bNoClamp) ? MF_CHECKED : MF_UNCHECKED); + if (m_wndToolBar.GetSafeHwnd()) { + m_wndToolBar.GetToolBarCtrl().CheckButton + ( + ID_VIEW_CUBICCLIPPING, + (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE + ); + } + + int n = g_PrefsDlg.m_nTextureScale; + int id; + switch (n) + { + case 10: + id = ID_TEXTURES_TEXTUREWINDOWSCALE_10; + break; + case 25: + id = ID_TEXTURES_TEXTUREWINDOWSCALE_25; + break; + case 50: + id = ID_TEXTURES_TEXTUREWINDOWSCALE_50; + break; + case 200: + id = ID_TEXTURES_TEXTUREWINDOWSCALE_200; + break; + default: + id = ID_TEXTURES_TEXTUREWINDOWSCALE_100; + break; + } + + CheckTextureScale(id); + } + + if (g_qeglobals.d_project_entity) { + // FillTextureMenu(); // redundant but i'll clean it up later.. yeah right.. + FillBSPMenu(); + LoadMruInReg(g_qeglobals.d_lpMruMenu, "Software\\" EDITOR_REGISTRY_KEY "\\MRU" ); + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, ::GetSubMenu(::GetMenu(GetSafeHwnd()), 0), ID_FILE_EXIT); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::ShowMenuItemKeyBindings(CMenu *pMenu) { + int i, j; + char key[1024], *ptr; + MENUITEMINFO MenuItemInfo; + + // return; + for (i = 0; i < g_nCommandCount; i++) { + memset(&MenuItemInfo, 0, sizeof(MENUITEMINFO)); + MenuItemInfo.cbSize = sizeof(MENUITEMINFO); + MenuItemInfo.fMask = MIIM_TYPE; + MenuItemInfo.dwTypeData = key; + MenuItemInfo.cch = sizeof(key); + if (!pMenu->GetMenuItemInfo(g_Commands[i].m_nCommand, &MenuItemInfo)) { + continue; + } + + if (MenuItemInfo.fType != MFT_STRING) { + continue; + } + + ptr = strchr(key, '\t'); + if (ptr) { + *ptr = '\0'; + } + + strcat(key, "\t"); + if (g_Commands[i].m_nModifiers) { // are there modifiers present? + if (g_Commands[i].m_nModifiers & RAD_SHIFT) { + strcat(key, "Shift-"); + } + + if (g_Commands[i].m_nModifiers & RAD_ALT) { + strcat(key, "Alt-"); + } + + if (g_Commands[i].m_nModifiers & RAD_CONTROL) { + strcat(key, "Ctrl-"); + } + } + + for (j = 0; j < g_nKeyCount; j++) { + if (g_Commands[i].m_nKey == g_Keys[j].m_nVKKey) { + strcat(key, g_Keys[j].m_strName); + break; + } + } + + if (j >= g_nKeyCount) { + sprintf(&key[strlen(key)], "%c", g_Commands[i].m_nKey); + } + + memset(&MenuItemInfo, 0, sizeof(MENUITEMINFO)); + MenuItemInfo.cbSize = sizeof(MENUITEMINFO); + MenuItemInfo.fMask = MIIM_TYPE; + MenuItemInfo.fType = MFT_STRING; + MenuItemInfo.dwTypeData = key; + MenuItemInfo.cch = strlen(key); + SetMenuItemInfo(pMenu->m_hMenu, g_Commands[i].m_nCommand, FALSE, &MenuItemInfo); + } +} + +/* +============== +MFCCreate +============== +*/ +void MFCCreate( HINSTANCE hInstance ) +{ + HMENU hMenu = NULL; + int i = sizeof(g_qeglobals.d_savedinfo); + long l = i; + + g_qeglobals.d_savedinfo.exclude |= (EXCLUDE_HINT | EXCLUDE_CLIP); + LoadRegistryInfo("radiant_SavedInfo", &g_qeglobals.d_savedinfo, &l); + + int nOldSize = g_qeglobals.d_savedinfo.iSize; + if (g_qeglobals.d_savedinfo.iSize != sizeof(g_qeglobals.d_savedinfo)) { + // fill in new defaults + g_qeglobals.d_savedinfo.iSize = sizeof(g_qeglobals.d_savedinfo); + g_qeglobals.d_savedinfo.fGamma = 1.0; + g_qeglobals.d_savedinfo.iTexMenu = ID_VIEW_BILINEARMIPMAP; + g_qeglobals.d_savedinfo.m_nTextureTweak = 1.0; + + //g_qeglobals.d_savedinfo.exclude = INCLUDE_EASY | INCLUDE_NORMAL | INCLUDE_HARD | INCLUDE_DEATHMATCH; + g_qeglobals.d_savedinfo.show_coordinates = true; + g_qeglobals.d_savedinfo.show_names = false; + + for (i=0 ; i<3 ; i++) { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25; + } + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0; + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0; + + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0; + + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0; + + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0; + + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75; + + + // old size was smaller, reload original prefs + if (nOldSize > 0 && nOldSize < sizeof(g_qeglobals.d_savedinfo)) { + long l = nOldSize; + LoadRegistryInfo("radiant_SavedInfo", &g_qeglobals.d_savedinfo, &l); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { + char *pBuffer = g_strAppPath.GetBufferSetLength(_MAX_PATH + 1); + int nResult = ::GetModuleFileName(NULL, pBuffer, _MAX_PATH); + ASSERT(nResult != 0); + pBuffer[g_strAppPath.ReverseFind('\\') + 1] = '\0'; + g_strAppPath.ReleaseBuffer(); + + com_editors |= EDITOR_RADIANT; + + InitCommonControls(); + g_qeglobals.d_hInstance = AfxGetInstanceHandle(); + MFCCreate(AfxGetInstanceHandle()); + + // g_PrefsDlg.LoadPrefs(); + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) { + return -1; + } + + UINT nID = (g_PrefsDlg.m_bWideToolbar) ? IDR_TOOLBAR_ADVANCED : IDR_TOOLBAR1; + + if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP + | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(nID)) { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT))) { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_bCamPreview = true; + + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKX, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKY, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKZ, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_BYBOUNDINGBRUSH, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_BRUSHESONLY, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_SHOWBOUNDINGBOX, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_WELD, TRUE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_DRILLDOWN, TRUE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SHOW_LIGHTVOLUMES, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SHOW_LIGHTTEXTURES, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECTION_MOVEONLY, FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundAlways); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSELECTEDSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundWhenSelected); + + m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); + EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndToolBar); + + g_nScaleHow = 0; + + m_wndTextureBar.Create(this, IDD_TEXTUREBAR, CBRS_BOTTOM, 7433); + m_wndTextureBar.EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndTextureBar); + + g_qeglobals.d_lpMruMenu = CreateMruMenuDefault(); + + m_bAutoMenuEnable = FALSE; + + LoadCommandMap(); + + CMenu *pMenu = GetMenu(); + ShowMenuItemKeyBindings(pMenu); + + CFont *pFont = new CFont(); + pFont->CreatePointFont(g_PrefsDlg.m_nStatusSize * 10, "Arial"); + m_wndStatusBar.SetFont(pFont); + + + if (g_PrefsDlg.m_bRunBefore == FALSE) { + g_PrefsDlg.m_bRunBefore = TRUE; + g_PrefsDlg.SavePrefs(); + + /* + * if (MessageBox("Would you like QERadiant to build and load a default project? + * If this is the first time you have run QERadiant or you are not familiar with + * editing QE4 project files directly, this is HIGHLY recommended", "Create a + * default project?", MB_YESNO) == IDYES) { OnFileNewproject(); } + */ + } + else + { + // load plugins before the first Map_LoadFile required for model plugins + if (g_PrefsDlg.m_bLoadLastMap && g_PrefsDlg.m_strLastMap.GetLength() > 0) { + Map_LoadFile(g_PrefsDlg.m_strLastMap.GetBuffer(0)); + } + } + + SetGridStatus(); + SetTexValStatus(); + SetButtonMenuStates(); + LoadBarState("RadiantToolBars2"); + + SetActiveXY(m_pXYWnd); + m_pXYWnd->SetFocus(); + + PostMessage(WM_KEYDOWN, 'O', NULL); + + if ( radiant_entityMode.GetBool() ) { + g_qeglobals.d_savedinfo.exclude |= (EXCLUDE_PATHS | EXCLUDE_CLIP | EXCLUDE_CAULK | EXCLUDE_VISPORTALS | EXCLUDE_NODRAW | EXCLUDE_TRIGGERS); + } + + Sys_UpdateWindows ( W_ALL ); + return 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void FindReplace(CString& strContents, const char* pTag, const char* pValue) { + if (strcmp(pTag, pValue) == 0) + return; + for (int nPos = strContents.Find(pTag); nPos >= 0; nPos = strContents.Find(pTag)) { + int nRightLen = strContents.GetLength() - strlen(pTag) - nPos; + CString strLeft = strContents.Left(nPos); + CString strRight = strContents.Right(nRightLen); + strLeft += pValue; + strLeft += strRight; + strContents = strLeft; + } +} + +void CMainFrame::LoadCommandMap() { + CString strINI; + char pBuff[1024]; + strINI = g_strAppPath; + strINI += "\\radiant.ini"; + + for (int i = 0; i < g_nCommandCount; i++) { + int nLen = GetPrivateProfileString("Commands", g_Commands[i].m_strCommand, "", pBuff, 1024, strINI); + if (nLen > 0) { + CString strBuff = pBuff; + strBuff.TrimLeft(); + strBuff.TrimRight(); + + int nSpecial = strBuff.Find("+alt"); + g_Commands[i].m_nModifiers = 0; + if (nSpecial >= 0) { + g_Commands[i].m_nModifiers |= RAD_ALT; + FindReplace(strBuff, "+alt", ""); + } + + nSpecial = strBuff.Find("+ctrl"); + if (nSpecial >= 0) { + g_Commands[i].m_nModifiers |= RAD_CONTROL; + FindReplace(strBuff, "+ctrl", ""); + } + + nSpecial = strBuff.Find("+shift"); + if (nSpecial >= 0) { + g_Commands[i].m_nModifiers |= RAD_SHIFT; + FindReplace(strBuff, "+shift", ""); + } + + strBuff.TrimLeft(); + strBuff.TrimRight(); + strBuff.MakeUpper(); + if (nLen == 1) { // most often case.. deal with first + g_Commands[i].m_nKey = __toascii(strBuff.GetAt(0)); + } + else { // special key + for (int j = 0; j < g_nKeyCount; j++) { + if (strBuff.CompareNoCase(g_Keys[j].m_strName) == 0) { + g_Commands[i].m_nKey = g_Keys[j].m_nVKKey; + break; + } + } + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &cs) { + // TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs + return CFrameWnd::PreCreateWindow(cs); +} + +// CMainFrame diagnostics +#ifdef _DEBUG + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::AssertValid() const { + CFrameWnd::AssertValid(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::Dump(CDumpContext &dc) const { + CFrameWnd::Dump(dc); +} +#endif // _DEBUG + +// +// ======================================================================================================================= +// CMainFrame message handlers +// ======================================================================================================================= +// +void CMainFrame::CreateQEChildren() { + // + // the project file can be specified on the command line, or implicitly found in + // the basedir directory + // + bool bProjectLoaded = false; + if (g_PrefsDlg.m_bLoadLast && g_PrefsDlg.m_strLastProject.GetLength() > 0) { + bProjectLoaded = QE_LoadProject(g_PrefsDlg.m_strLastProject.GetBuffer(0)); + } + if (!bProjectLoaded) { + bProjectLoaded = QE_LoadProject( EDITOR_DEFAULT_PROJECT ); + } + + if (!bProjectLoaded) { + CFileDialog dlgFile( true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, EDITOR_WINDOWTEXT " Project files (*.qe4, *.prj)|*.qe4|*.prj||", this ); + if (dlgFile.DoModal() == IDOK) { + bProjectLoaded = QE_LoadProject(dlgFile.GetPathName().GetBuffer(0)); + } + } + + if (!bProjectLoaded) { + Error("Unable to load project file. It was unavailable in the scripts path and the default could not be found"); + } + + QE_Init(); + + common->Printf("Entering message loop\n"); + + m_bDoLoop = true; + SetTimer(QE_TIMER0, 100, NULL); + SetTimer(QE_TIMER1, g_PrefsDlg.m_nAutoSave * 60 * 1000, NULL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) { + return CFrameWnd::OnCommand(wParam, lParam); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { + //RoutineProcessing(); + return CFrameWnd::DefWindowProc(message, wParam, lParam); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::RoutineProcessing() { + if (m_bDoLoop) { + double time = 0.0; + static double oldtime = 0.0; + double delta = 0.0; + + time = Sys_DoubleTime(); + delta = time - oldtime; + oldtime = time; + if (delta > 0.2) { + delta = 0.2; + } + + // run time dependant behavior + if (m_pCamWnd) { + m_pCamWnd->Cam_MouseControl(delta); + } + + if (g_PrefsDlg.m_bQE4Painting && g_nUpdateBits) { + int nBits = g_nUpdateBits; // this is done to keep this routine from being + g_nUpdateBits = 0; // re-entered due to the paint process.. only + UpdateWindows(nBits); // happens in rare cases but causes a stack overflow + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { + return CFrameWnd::WindowProc(message, wParam, lParam); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool MouseDown() { + if (::GetAsyncKeyState(VK_LBUTTON)) { + return true; + } + + if (::GetAsyncKeyState(VK_RBUTTON)) { + return true; + } + + if (::GetAsyncKeyState(VK_MBUTTON)) { + return true; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void CMainFrame::OnTimer(UINT nIDEvent) { + static bool autoSavePending = false; + + if ( nIDEvent == QE_TIMER0 && !MouseDown() ) { + QE_CountBrushesAndUpdateStatusBar(); + } + if ( nIDEvent == QE_TIMER1 || autoSavePending ) { + if ( MouseDown() ) { + autoSavePending = true; + return; + } + if ( Sys_Waiting() ) { + autoSavePending = true; + return; + } + QE_CheckAutoSave(); + autoSavePending = false; + } +} + +struct SplitInfo { + int m_nMin; + int m_nCur; +}; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool LoadWindowPlacement(HWND hwnd, const char *pName) { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + + LONG lSize = sizeof(wp); + if (LoadRegistryInfo(pName, &wp, &lSize)) { + ::SetWindowPlacement(hwnd, &wp); + return true; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SaveWindowPlacement(HWND hwnd, const char *pName) { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + if (::GetWindowPlacement(hwnd, &wp)) { + SaveRegistryInfo(pName, &wp, sizeof(wp)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnDestroy() { + KillTimer(QE_TIMER0); + + SaveBarState("RadiantToolBars2"); + + // FIXME original mru stuff needs replaced with mfc stuff + SaveMruInReg(g_qeglobals.d_lpMruMenu, "Software\\" EDITOR_REGISTRY_KEY "\\MRU"); + + DeleteMruMenu(g_qeglobals.d_lpMruMenu); + + SaveRegistryInfo("radiant_SavedInfo", &g_qeglobals.d_savedinfo, sizeof(g_qeglobals.d_savedinfo)); + + SaveWindowPlacement(GetSafeHwnd(), "radiant_MainWindowPlace"); + + SaveWindowPlacement(m_pXYWnd->GetSafeHwnd(), "radiant_xywindow"); + SaveWindowPlacement(m_pXZWnd->GetSafeHwnd(), "radiant_xzwindow"); + SaveWindowPlacement(m_pYZWnd->GetSafeHwnd(), "radiant_yzwindow"); + SaveWindowPlacement(m_pCamWnd->GetSafeHwnd(), "radiant_camerawindow"); + SaveWindowPlacement(m_pZWnd->GetSafeHwnd(), "radiant_zwindow"); + SaveWindowState(g_Inspectors->texWnd.GetSafeHwnd(), "radiant_texwindow"); + + if (m_pXYWnd->GetSafeHwnd()) { + m_pXYWnd->SendMessage(WM_DESTROY, 0, 0); + } + + delete m_pXYWnd; + m_pXYWnd = NULL; + + if (m_pYZWnd->GetSafeHwnd()) { + m_pYZWnd->SendMessage(WM_DESTROY, 0, 0); + } + + delete m_pYZWnd; + m_pYZWnd = NULL; + + if (m_pXZWnd->GetSafeHwnd()) { + m_pXZWnd->SendMessage(WM_DESTROY, 0, 0); + } + + delete m_pXZWnd; + m_pXZWnd = NULL; + + if (m_pZWnd->GetSafeHwnd()) { + m_pZWnd->SendMessage(WM_DESTROY, 0, 0); + } + + delete m_pZWnd; + m_pZWnd = NULL; + + if (m_pCamWnd->GetSafeHwnd()) { + m_pCamWnd->SendMessage(WM_DESTROY, 0, 0); + } + + delete m_pCamWnd; + m_pCamWnd = NULL; + + if ( idStr::Icmp(currentmap, "unnamed.map") != 0 ) { + g_PrefsDlg.m_strLastMap = currentmap; + g_PrefsDlg.SavePrefs(); + } + + CleanUpEntities(); + + while (active_brushes.next != &active_brushes) { + Brush_Free(active_brushes.next, false); + } + + while (selected_brushes.next != &selected_brushes) { + Brush_Free(selected_brushes.next, false); + } + + while (filtered_brushes.next != &filtered_brushes) { + Brush_Free(filtered_brushes.next, false); + } + + while (entities.next != &entities) { + Entity_Free(entities.next); + } + + + g_qeglobals.d_project_entity->epairs.Clear(); + + entity_t *pEntity = g_qeglobals.d_project_entity->next; + while (pEntity != NULL && pEntity != g_qeglobals.d_project_entity) { + entity_t *pNextEntity = pEntity->next; + Entity_Free(pEntity); + pEntity = pNextEntity; + } + + Texture_Cleanup(); + + if (world_entity) { + Entity_Free(world_entity); + } + + // + // FIXME: idMaterial + // if (notexture) { // Timo // Surface properties plugin #ifdef _DEBUG if ( + // !notexture->pData ) common->Printf("WARNING: found a qtexture_t* with no + // IPluginQTexture\n"); #endif if ( notexture->pData ) + // GETPLUGINTEXDEF(notexture)->DecRef(); Mem_Free(notexture); } + // if (current_texture) free(current_texture); + // + + // FIXME: idMaterial FreeShaders(); + CFrameWnd::OnDestroy(); + + AfxGetApp()->ExitInstance(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnClose() { + if (ConfirmModified()) { + g_Inspectors->SaveWindowPlacement (); + CFrameWnd::OnClose(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { + // run through our list to see if we have a handler for nChar + + for (int i = 0; i < g_nCommandCount; i++) { + if (g_Commands[i].m_nKey == nChar) { // find a match? + bool bGo = true; + if (g_Commands[i].m_nModifiers & RAD_PRESS) { + int nModifiers = g_Commands[i].m_nModifiers &~RAD_PRESS; + if (nModifiers) { // are there modifiers present? + if (nModifiers & RAD_ALT) { + if (!(GetAsyncKeyState(VK_MENU) & 0x8000)) { + bGo = false; + } + } + + if (nModifiers & RAD_CONTROL) { + if (!(GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + bGo = false; + } + } + + if (nModifiers & RAD_SHIFT) { + if (!(GetAsyncKeyState(VK_SHIFT) & 0x8000)) { + bGo = false; + } + } + } + else { // no modifiers make sure none of those keys are pressed + if (GetAsyncKeyState(VK_MENU) & 0x8000) { + bGo = false; + } + + if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { + bGo = false; + } + + if (GetAsyncKeyState(VK_SHIFT) & 0x8000) { + bGo = false; + } + } + + if (bGo) { + SendMessage(WM_COMMAND, g_Commands[i].m_nCommand, 0); + break; + } + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CamOK(unsigned int nKey) { + if (nKey == VK_UP || nKey == VK_LEFT || nKey == VK_RIGHT || nKey == VK_DOWN) { + if (::GetAsyncKeyState(nKey)) { + return true; + } + else { + return false; + } + } + + return true; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + // OnKeyDown(nChar, nRepCnt, nFlags); + if (nChar == VK_DOWN) { + OnKeyDown(nChar, nRepCnt, nFlags); + } + + CFrameWnd::OnSysKeyDown(nChar, nRepCnt, nFlags); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + + for (int i = 0; i < g_nCommandCount; i++) { + if (g_Commands[i].m_nKey == nChar) { // find a match? + // check modifiers + unsigned int nState = 0; + if (GetAsyncKeyState(VK_MENU) & 0x8000) { + nState |= RAD_ALT; + } + + if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { + nState |= RAD_CONTROL; + } + + if (GetAsyncKeyState(VK_SHIFT) & 0x8000) { + nState |= RAD_SHIFT; + } + + if ((g_Commands[i].m_nModifiers & 0x7) == nState) { + SendMessage(WM_COMMAND, g_Commands[i].m_nCommand, 0); + break; + } + } + } + + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext) { + + g_Inspectors = new CInspectorDialog( this ); + g_Inspectors->Create(IDD_DIALOG_INSPECTORS, this); + + LoadWindowPlacement(g_Inspectors->GetSafeHwnd(), "radiant_InspectorsWindow"); + g_Inspectors->ShowWindow(SW_SHOW); + + CRect r; + g_Inspectors->GetWindowRect ( r ); + + //stupid hack to get the window resize itself properly + r.DeflateRect(0,0,0,1); + g_Inspectors->MoveWindow(r); + r.InflateRect(0,0,0,1); + g_Inspectors->MoveWindow(r); + + + if (!LoadWindowPlacement(GetSafeHwnd(), "radiant_MainWindowPlace")) { + } + + CRect rect(5, 25, 100, 100); + CRect rctParent; + GetClientRect(rctParent); + + m_pCamWnd = new CCamWnd(); + m_pCamWnd->Create(CAMERA_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1234); + + m_pZWnd = new CZWnd(); + m_pZWnd->Create(Z_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1238); + + m_pXYWnd = new CXYWnd(); + m_pXYWnd->Create(XY_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1235); + m_pXYWnd->SetViewType(XY); + + m_pXZWnd = new CXYWnd(); + m_pXZWnd->Create(XY_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1236); + m_pXZWnd->SetViewType(XZ); + + m_pYZWnd = new CXYWnd(); + m_pYZWnd->Create(XY_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1237); + m_pYZWnd->SetViewType(YZ); + + m_pCamWnd->SetXYFriend(m_pXYWnd); + + CRect rctWork; + + LoadWindowPlacement(m_pXYWnd->GetSafeHwnd(), "radiant_xywindow"); + LoadWindowPlacement(m_pXZWnd->GetSafeHwnd(), "radiant_xzwindow"); + LoadWindowPlacement(m_pYZWnd->GetSafeHwnd(), "radiant_yzwindow"); + LoadWindowPlacement(m_pCamWnd->GetSafeHwnd(), "radiant_camerawindow"); + LoadWindowPlacement(m_pZWnd->GetSafeHwnd(), "radiant_zwindow"); + + if (!g_PrefsDlg.m_bXZVis) { + m_pXZWnd->ShowWindow(SW_HIDE); + } + + if (!g_PrefsDlg.m_bYZVis) { + m_pYZWnd->ShowWindow(SW_HIDE); + } + + if (!g_PrefsDlg.m_bZVis) { + m_pZWnd->ShowWindow(SW_HIDE); + } + + CreateQEChildren(); + + if (m_pXYWnd) { + m_pXYWnd->SetActive(true); + } + + Texture_SetMode(g_qeglobals.d_savedinfo.iTexMenu); + + g_Inspectors->SetMode(W_CONSOLE); + return TRUE; +} + +CRect g_rctOld(0, 0, 0, 0); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSize(UINT nType, int cx, int cy) { + CFrameWnd::OnSize(nType, cx, cy); + + CRect rctParent; + GetClientRect(rctParent); + + UINT nID; + UINT nStyle; + int nWidth; + if (m_wndStatusBar.GetSafeHwnd()) { + m_wndStatusBar.GetPaneInfo( 0, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 0, nID, nStyle, rctParent.Width() * 0.15f ); + m_wndStatusBar.GetPaneInfo( 1, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 1, nID, nStyle, rctParent.Width() * 0.15f); + m_wndStatusBar.GetPaneInfo( 2, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 2, nID, nStyle, rctParent.Width() * 0.15f ); + m_wndStatusBar.GetPaneInfo( 3, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 3, nID, nStyle, rctParent.Width() * 0.39f ); + m_wndStatusBar.GetPaneInfo( 4, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 4, nID, nStyle, rctParent.Width() * 0.15f ); + m_wndStatusBar.GetPaneInfo( 5, nID, nStyle, nWidth); + m_wndStatusBar.SetPaneInfo( 5, nID, nStyle, rctParent.Width() * 0.01f ); + } +} + +void OpenDialog(void); +void SaveAsDialog(bool bRegion); +void Select_Ungroup(); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::ToggleCamera() { + if (m_bCamPreview) { + m_bCamPreview = false; + } + else { + m_bCamPreview = true; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileClose() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileExit() { + PostMessage(WM_CLOSE, 0, 0L); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileLoadproject() { + if (ConfirmModified()) { + ProjectDialog(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileNew() { + if (ConfirmModified()) { + Map_New(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileOpen() { + if (ConfirmModified()) { + OpenDialog(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFilePointfile() { + if (g_qeglobals.d_pointfile_display_list) { + Pointfile_Clear(); + } + else { + Pointfile_Check(); + } + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFilePrint() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFilePrintPreview() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileSave() { + if (!strcmp(currentmap, "unnamed.map")) { + SaveAsDialog(false); + } + else { + Map_SaveFile(currentmap, false); + } + + // DHM - _D3XP + SetTimer(QE_TIMER1, g_PrefsDlg.m_nAutoSave * 60 * 1000, NULL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileSaveas() { + SaveAsDialog(false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileSaveCopy() { + char aFile[260] = "\0"; + char aFilter[260] = "Map\0*.map\0\0"; + char aTitle[260] = "Save a Copy\0"; + OPENFILENAME afn; + + memset( &afn, 0, sizeof(OPENFILENAME) ); + + CString strPath = ValueForKey(g_qeglobals.d_project_entity, "basepath"); + AddSlash(strPath); + strPath += "maps"; + if (g_PrefsDlg.m_strMaps.GetLength() > 0) { + strPath += va("\\%s", g_PrefsDlg.m_strMaps); + } + + /* Place the terminating null character in the szFile. */ + aFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + afn.lStructSize = sizeof(OPENFILENAME); + afn.hwndOwner = g_pParentWnd->GetSafeHwnd(); + afn.lpstrFilter = aFilter; + afn.nFilterIndex = 1; + afn.lpstrFile = aFile; + afn.nMaxFile = sizeof(aFile); + afn.lpstrFileTitle = NULL; + afn.nMaxFileTitle = 0; + afn.lpstrInitialDir = strPath; + afn.lpstrTitle = aTitle; + afn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT; + + /* Display the Open dialog box. */ + if (!GetSaveFileName(&afn)) { + return; // canceled + } + + DefaultExtension(afn.lpstrFile, ".map"); + Map_SaveFile(afn.lpstrFile, false); // ignore region + + // Set the title back to the current working map + Sys_SetTitle(currentmap); +} + +/* +================================================================================================== +*/ +void CMainFrame::OnViewShowModels() { + g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_MODELS; + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnView100() { + if (m_pXYWnd) { + m_pXYWnd->SetScale(1); + } + + if (m_pXZWnd) { + m_pXZWnd->SetScale(1); + } + + if (m_pYZWnd) { + m_pYZWnd->SetScale(1); + } + + Sys_UpdateWindows(W_XY | W_XY_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCenter() { + m_pCamWnd->Camera().angles[ROLL] = m_pCamWnd->Camera().angles[PITCH] = 0; + m_pCamWnd->Camera().angles[YAW] = 22.5 * floor((m_pCamWnd->Camera().angles[YAW] + 11) / 22.5); + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewConsole() { + g_Inspectors->SetMode(W_CONSOLE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewDownfloor() { + m_pCamWnd->Cam_ChangeFloor(false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewEntity() { + g_Inspectors->SetMode(W_ENTITY); +} + +void CMainFrame::OnViewMediaBrowser() { + g_Inspectors->SetMode(W_MEDIA); +} + + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewFront() { + m_pXYWnd->SetViewType(YZ); + m_pXYWnd->PositionView(); + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +BOOL DoMru(HWND hWnd,WORD wId) +{ + char szFileName[128]; + OFSTRUCT of; + BOOL fExist; + + GetMenuItem(g_qeglobals.d_lpMruMenu, wId, TRUE, szFileName, sizeof(szFileName)); + + // Test if the file exists. + + fExist = OpenFile(szFileName ,&of,OF_EXIST) != HFILE_ERROR; + + if (fExist) { + + // Place the file on the top of MRU. + AddNewItem(g_qeglobals.d_lpMruMenu,(LPSTR)szFileName); + + // Now perform opening this file !!! + Map_LoadFile (szFileName); + } + else + // Remove the file on MRU. + DelMenuItem(g_qeglobals.d_lpMruMenu,wId,TRUE); + + // Refresh the File menu. + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0), + ID_FILE_EXIT); + + return fExist; +} + +void CMainFrame::OnMru(unsigned int nID) { + // DHM - _D3XP + if (ConfirmModified()) { + DoMru(GetSafeHwnd(), nID); +} +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewNearest(unsigned int nID) { + Texture_SetMode(nID); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTextureWad(unsigned int nID) { + Sys_BeginWait(); + + // FIXME: idMaterial Texture_ShowDirectory (nID); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +/* +============ +RunBsp + +This is the new all-internal bsp +============ +*/ +void RunBsp (const char *command) { + char sys[2048]; + char name[2048]; + char *in; + + // bring the console window forward for feedback + g_Inspectors->SetMode(W_CONSOLE); + + // decide if we are doing a .map or a .reg + strcpy (name, currentmap); + if ( region_active ) { + Map_SaveFile (name, false); + StripExtension (name); + strcat (name, ".reg"); + } + + if ( !Map_SaveFile ( name, region_active ) ) { + return; + } + + // name should be a full pathname, but we only + // want to pass the maps/ part to dmap + in = strstr(name, "maps/"); + if ( !in ) { + in = strstr(name, "maps\\"); + } + if ( !in ) { + in = name; + } + + if (idStr::Icmpn(command, "bspext", strlen("runbsp")) == 0) { + PROCESS_INFORMATION ProcessInformation; + STARTUPINFO startupinfo; + char buff[2048]; + + idStr base = cvarSystem->GetCVarString( "fs_basepath" ); + idStr cd = cvarSystem->GetCVarString( "fs_cdpath" ); + idStr paths; + if (base.Length()) { + paths += "+set fs_basepath "; + paths += base; + } + if (cd.Length()) { + paths += "+set fs_cdpath "; + paths += cd; + } + + ::GetModuleFileName(AfxGetApp()->m_hInstance, buff, sizeof(buff)); + if (strlen(command) > strlen("bspext")) { + idStr::snPrintf( sys, sizeof(sys), "%s %s +set r_fullscreen 0 +dmap editorOutput %s %s +quit", buff, paths.c_str(), command + strlen("bspext"), in ); + } else { + idStr::snPrintf( sys, sizeof(sys), "%s %s +set r_fullscreen 0 +dmap editorOutput %s +quit", buff, paths.c_str(), in ); + } + + ::GetStartupInfo (&startupinfo); + if (!CreateProcess(NULL, sys, NULL, NULL, FALSE, 0, NULL, NULL, &startupinfo, &ProcessInformation)) { + common->Printf("Could not start bsp process %s %s/n", buff, sys); + } + g_pParentWnd->SetFocus(); + + } else { // assumes bsp is the command + if (strlen(command) > strlen("bsp")) { + idStr::snPrintf( sys, sizeof(sys), "dmap %s %s", command + strlen("bsp"), in ); + } else { + idStr::snPrintf( sys, sizeof(sys), "dmap %s", in ); + } + + cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect\n" ); + + // issue the bsp command + Dmap_f( idCmdArgs( sys, false ) ); + } +} + +void CMainFrame::OnBspCommand(unsigned int nID) { + if (g_PrefsDlg.m_bSnapShots && stricmp(currentmap, "unnamed.map") != 0) { + Map_Snapshot(); + } + + RunBsp(bsp_commands[LOWORD(nID - CMD_BSPCOMMAND)]); + + // DHM - _D3XP + SetTimer(QE_TIMER1, g_PrefsDlg.m_nAutoSave * 60 * 1000, NULL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowblocks() { + g_qeglobals.show_blocks = !(g_qeglobals.show_blocks); + CheckMenuItem + ( + ::GetMenu(GetSafeHwnd()), + ID_VIEW_SHOWBLOCKS, + MF_BYCOMMAND | (g_qeglobals.show_blocks ? MF_CHECKED : MF_UNCHECKED) + ); + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowclip() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CLIP) & EXCLUDE_CLIP) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowTriggers() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_TRIGGERS) & EXCLUDE_TRIGGERS) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWTRIGGERS, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWTRIGGERS, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowcoordinates() { + g_qeglobals.d_savedinfo.show_coordinates ^= 1; + CheckMenuItem + ( + ::GetMenu(GetSafeHwnd()), + ID_VIEW_SHOWCOORDINATES, + MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_coordinates ? MF_CHECKED : MF_UNCHECKED) + ); + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowent() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_ENT) & EXCLUDE_ENT) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowlights() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIGHTS) & EXCLUDE_LIGHTS) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShownames() { + g_qeglobals.d_savedinfo.show_names = !(g_qeglobals.d_savedinfo.show_names); + CheckMenuItem + ( + ::GetMenu(GetSafeHwnd()), + ID_VIEW_SHOWNAMES, + MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_names ? MF_CHECKED : MF_UNCHECKED) + ); + Map_BuildBrushData(); + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowpath() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_PATHS) & EXCLUDE_PATHS) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowCombatNodes() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_COMBATNODES) & EXCLUDE_COMBATNODES) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCOMBATNODES, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCOMBATNODES, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowwater() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_DYNAMICS) & EXCLUDE_DYNAMICS) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowworld() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WORLD) & EXCLUDE_WORLD) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewTexture() { + g_Inspectors->SetMode(W_TEXTURE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewUpfloor() { + m_pCamWnd->Cam_ChangeFloor(true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewXy() { + m_pXYWnd->SetViewType(XY); + m_pXYWnd->PositionView(); + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewZ100() { + z.scale = 1; + Sys_UpdateWindows(W_Z | W_Z_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewZoomin() { + if ( m_pXYWnd && m_pXYWnd->Active() ) { + m_pXYWnd->SetScale( m_pXYWnd->Scale() * 5.0f / 4.0f ); + if ( m_pXYWnd->Scale() > 256.0f ) { + m_pXYWnd->SetScale( 256.0f ); + } + } + + if ( m_pXZWnd && m_pXZWnd->Active() ) { + m_pXZWnd->SetScale( m_pXZWnd->Scale() * 5.0f / 4.0f ); + if ( m_pXZWnd->Scale() > 256.0f ) { + m_pXZWnd->SetScale( 256.0f ); + } + } + + if ( m_pYZWnd && m_pYZWnd->Active() ) { + m_pYZWnd->SetScale( m_pYZWnd->Scale() * 5.0f / 4.0f ); + if ( m_pYZWnd->Scale() > 256.0f ) { + m_pYZWnd->SetScale( 256.0f ); + } + } + + Sys_UpdateWindows( W_XY | W_XY_OVERLAY ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewZoomout() { + if ( m_pXYWnd && m_pXYWnd->Active() ) { + m_pXYWnd->SetScale( m_pXYWnd->Scale() * 4.0f / 5.0f ); + if ( m_pXYWnd->Scale() < 0.1f / 32.0f ) { + m_pXYWnd->SetScale( 0.1f / 32.0f ); + } + } + + if ( m_pXZWnd && m_pXZWnd->Active() ) { + m_pXZWnd->SetScale( m_pXZWnd->Scale() * 4.0f / 5.0f ); + if ( m_pXZWnd->Scale() < 0.1f / 32.0f ) { + m_pXZWnd->SetScale( 0.1f / 32.0f ); + } + } + + if ( m_pYZWnd && m_pYZWnd->Active() ) { + m_pYZWnd->SetScale( m_pYZWnd->Scale() * 4.0f / 5.0f ); + if ( m_pYZWnd->Scale() < 0.1f / 32.0f ) { + m_pYZWnd->SetScale( 0.1f / 32.0f ); + } + } + + Sys_UpdateWindows(W_XY | W_XY_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewZzoomin() { + z.scale *= 5.0f / 4.0f; + if ( z.scale > 4.0f ) { + z.scale = 4.0f; + } + + Sys_UpdateWindows(W_Z | W_Z_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewZzoomout() { + z.scale *= 4.0f / 5.0f; + if ( z.scale < 0.125f ) { + z.scale = 0.125f; + } + + Sys_UpdateWindows(W_Z | W_Z_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewSide() { + m_pXYWnd->SetViewType(XZ); + m_pXYWnd->PositionView(); + Sys_UpdateWindows(W_XY); +} + +static void UpdateGrid(void) +{ + // g_qeglobals.d_gridsize = 1 << g_qeglobals.d_gridsize; + if (g_PrefsDlg.m_bSnapTToGrid) { + g_qeglobals.d_savedinfo.m_nTextureTweak = g_qeglobals.d_gridsize; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnGrid1(unsigned int nID) { + switch (nID) + { + case ID_GRID_1: + g_qeglobals.d_gridsize = 1; + break; + case ID_GRID_2: + g_qeglobals.d_gridsize = 2; + break; + case ID_GRID_4: + g_qeglobals.d_gridsize = 4; + break; + case ID_GRID_8: + g_qeglobals.d_gridsize = 8; + break; + case ID_GRID_16: + g_qeglobals.d_gridsize = 16; + break; + case ID_GRID_32: + g_qeglobals.d_gridsize = 32; + break; + case ID_GRID_64: + g_qeglobals.d_gridsize = 64; + break; + case ID_GRID_POINT5: + g_qeglobals.d_gridsize = 0.5f; + break; + case ID_GRID_POINT25: + g_qeglobals.d_gridsize = 0.25f; + break; + case ID_GRID_POINT125: + g_qeglobals.d_gridsize = 0.125f; + break; + //case ID_GRID_POINT0625: + // g_qeglobals.d_gridsize = 0.0625f; + // break; + } + + UpdateGrid(); + + SetGridStatus(); + SetGridChecks(nID); + Sys_UpdateWindows(W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesShowinuse() { + Sys_BeginWait(); + Texture_ShowInuse(); + g_Inspectors->texWnd.RedrawWindow(); +} + +// from TexWnd.cpp +extern bool texture_showinuse; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnUpdateTexturesShowinuse(CCmdUI *pCmdUI) { + pCmdUI->SetCheck(texture_showinuse); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesInspector() { + DoSurface(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnMiscFindbrush() { + DoFind(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnMiscGamma() { + float fSave = g_qeglobals.d_savedinfo.fGamma; + DoGamma(); + if (fSave != g_qeglobals.d_savedinfo.fGamma) { + MessageBox("You must restart Q3Radiant for Gamma settings to take place"); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnMiscNextleakspot() { + Pointfile_Next(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnMiscPreviousleakspot() { + Pointfile_Prev(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnMiscPrintxy() { + WXY_Print(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void UpdateRadiantColor( float r, float g, float b, float a ) { + if ( g_pParentWnd ) { + g_pParentWnd->RoutineProcessing(); + } +} + +bool DoColor( int iIndex ) { + COLORREF cr = (int)(g_qeglobals.d_savedinfo.colors[iIndex][0]*255) + + (((int)(g_qeglobals.d_savedinfo.colors[iIndex][1]*255))<<8) + + (((int)(g_qeglobals.d_savedinfo.colors[iIndex][2]*255))<<16); + + CDialogColorPicker dlg(cr); + + dlg.UpdateParent = UpdateRadiantColor; + + if ( dlg.DoModal() == IDOK ) { + g_qeglobals.d_savedinfo.colors[iIndex][0] = (dlg.GetColor() & 255)/255.0; + g_qeglobals.d_savedinfo.colors[iIndex][1] = ((dlg.GetColor() >> 8)&255)/255.0; + g_qeglobals.d_savedinfo.colors[iIndex][2] = ((dlg.GetColor() >> 16)&255)/255.0; + + Sys_UpdateWindows (W_ALL); + return true; + } else { + return false; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +extern void Select_SetKeyVal(const char *key, const char *val); +void CMainFrame::OnMiscSelectentitycolor() { + + entity_t *ent = NULL; + if (QE_SingleBrush(true, true)) { + ent = selected_brushes.next->owner; + CString strColor = ValueForKey(ent, "_color"); + if (strColor.GetLength() > 0) { + float fR, fG, fB; + int n = sscanf(strColor, "%f %f %f", &fR, &fG, &fB); + if (n == 3) { + g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0] = fR; + g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1] = fG; + g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2] = fB; + } + } + } + + if (DoColor(COLOR_ENTITY)) { + char buffer[100]; + sprintf(buffer, "%f %f %f", g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0], g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1],g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2]); + Select_SetKeyVal("_color", buffer); + if (ent) { + g_Inspectors->UpdateEntitySel(ent->eclass); + } + Sys_UpdateWindows(W_ALL); + } +} + +CString strFindKey; +CString strFindValue; +CString strReplaceKey; +CString strReplaceValue; +bool gbWholeStringMatchOnly = true; +bool gbSelectAllMatchingEnts= false; +brush_t* gpPrevEntBrushFound = NULL; + +// all this because there's no ansi stristr(), sigh... +// +LPCSTR String_ToLower(LPCSTR psString) +{ + const int iBufferSize = 4096; + static char sString[8][iBufferSize]; + static int iIndex=0; + + if (strlen(psString)>=iBufferSize) + { + assert(0); + common->Printf("String_ToLower(): Warning, input string was %d bytes too large, performing strlwr() inline!\n",strlen(psString)-(iBufferSize-1)); + return strlwr(const_cast(psString)); + } + + iIndex = ++ iIndex & 7; + + strcpy(sString[iIndex],psString); + strlwr(sString[iIndex]); + + return sString[iIndex]; +} + + +bool FindNextBrush(brush_t* pPrevFoundBrush) // can be NULL for fresh search +{ + bool bFoundSomething = false; + entity_t *pLastFoundEnt; + brush_t *pLastFoundBrush; + + CWaitCursor waitcursor; + + Select_Deselect(true); // bool bDeSelectToListBack + + // see whether to start search from prev_brush->next by checking if prev_brush is still in the active list... + // + brush_t *pStartBrush = active_brushes.next; + + if (pPrevFoundBrush && !gbSelectAllMatchingEnts) + { + brush_t *pPrev = NULL; + for (brush_t* b = active_brushes.next ; b != &active_brushes ; b = b->next) + { + if (pPrev == pPrevFoundBrush && pPrevFoundBrush) + { + pStartBrush = b; + break; + } + pPrev = b; + } + } + + // now do the search proper... + // + int iBrushesScanned = 0; + int iBrushesSelected=0; + int iEntsScanned = 0; + + brush_t* pNextBrush; + for (brush_t* b = pStartBrush; b != &active_brushes ; b = pNextBrush) + { + // setup the ptr before going any further (because selecting a brush down below moves it to a + // different link list), but we need to ensure that the next brush has a different ent-owner than the current + // one, or multi-brush ents will confuse the list process if they get selected (infinite loop badness)... + // + // pNextBrush = &active_brushes; // default to loop-stop condition + pNextBrush = b->next; + while (pNextBrush->owner == b->owner && pNextBrush!=&active_brushes) + { + pNextBrush = pNextBrush->next; + } + + iBrushesScanned++; + + // a simple progress bar so they don't think it's locked up on long searches... + // + static int iDotBodge=0; + if (!(++iDotBodge&15)) + common->Printf("."); // cut down on printing + + bool bMatch = false; + entity_t* ent = b->owner; + + if (ent && ent!= world_entity) // needed! + { + iEntsScanned++; + if (FilterBrush (b)) + continue; + + // only check the find-key if there was one specified... + // + if (!strFindKey.IsEmpty()) + { + const char *psEntFoundValue = ValueForKey(ent, strFindKey); + + if (strlen(psEntFoundValue) + && + ( +// (stricmp(strFindValue, psEntFoundValue)==0) // found this exact key/value + ( + (gbWholeStringMatchOnly && stricmp(psEntFoundValue, strFindValue)==0) + || + (!gbWholeStringMatchOnly && strstr(String_ToLower(psEntFoundValue), String_ToLower(strFindValue))) + ) + || // or + (strFindValue.IsEmpty()) // any value for this key if blank value search specified + ) + ) + { + bMatch = true; + } + } + else + { + // no FIND key specified, so just scan all of them... + // + int iNumEntKeys = GetNumKeys(ent); + for (int i=0; i search specified then any found-value is ok + || + (gbWholeStringMatchOnly && stricmp(psEntFoundValue, strFindValue)==0) + || + (!gbWholeStringMatchOnly && strstr(String_ToLower(psEntFoundValue), String_ToLower(strFindValue))) + ) + { + if (!gbWholeStringMatchOnly && strstr(String_ToLower(psEntFoundValue), String_ToLower(strFindValue))) + { +// OutputDebugString(va("Matching because: psEntFoundValue '%s' & strFindValue '%s'\n",psEntFoundValue, strFindValue)); +// Sys_Printf("Matching because: psEntFoundValue '%s' & strFindValue '%s'\n",psEntFoundValue, strFindValue); + +// if (strstr(psEntFoundValue,"killsplat")) +// { +// DebugBreak(); +// } + } + bMatch = true; + break; + } + } + } + } + + if (bMatch) + { + bFoundSomething = true; + pLastFoundEnt = ent; + pLastFoundBrush = b; + iBrushesSelected++; + + g_bScreenUpdates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! + + Select_Brush(b); + + g_bScreenUpdates = true; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (!gbSelectAllMatchingEnts) + break; + } + } + } + if (gbSelectAllMatchingEnts) + { + common->Printf("\nBrushes Selected: %d (Brushes Scanned %d, Ents Scanned %d)\n", iBrushesSelected, iBrushesScanned, iEntsScanned); + } + + if (bFoundSomething) + { + idVec3 v3Origin; + + if (pLastFoundEnt->origin[0] != 0.0f || pLastFoundEnt->origin[1] != 0.0f || pLastFoundEnt->origin[2] != 0.0f) + { + VectorCopy(pLastFoundEnt->origin,v3Origin); + } + else + { + // pLastFoundEnt's origin is zero, so use average point of brush mins maxs instead... + // + v3Origin[0] = (pLastFoundBrush->mins[0] + pLastFoundBrush->maxs[0])/2; + v3Origin[1] = (pLastFoundBrush->mins[1] + pLastFoundBrush->maxs[1])/2; + v3Origin[2] = (pLastFoundBrush->mins[2] + pLastFoundBrush->maxs[2])/2; + } + + // got one, jump the camera to it... + // + VectorCopy(v3Origin, g_pParentWnd->GetCamera()->Camera().origin); + g_pParentWnd->GetCamera()->Camera().origin[1] -= 32; // back off a touch to look at it + g_pParentWnd->GetCamera()->Camera().angles[0] = 0; + g_pParentWnd->GetCamera()->Camera().angles[1] = 90; + g_pParentWnd->GetCamera()->Camera().angles[2] = 0; + + // force main screen into XY camera mode (just in case)... + // + g_pParentWnd->SetActiveXY(g_pParentWnd->GetXYWnd()); + g_pParentWnd->GetXYWnd()->PositionView(); + + Sys_UpdateWindows (W_ALL); + // + // and record for next find request (F3)... + // + gpPrevEntBrushFound = pLastFoundBrush; + } + + return bFoundSomething; +} + + +void CMainFrame::OnMiscFindOrReplaceEntity() +{ + CEntKeyFindReplace FindReplace(&strFindKey, &strFindValue, &strReplaceKey, &strReplaceValue, &gbWholeStringMatchOnly, &gbSelectAllMatchingEnts); + switch (FindReplace.DoModal()) + { + case ID_RET_REPLACE: + { + brush_t* next = NULL; + int iOccurences = 0; + for (brush_t* b = active_brushes.next ; b != &active_brushes ; b = next) + { + next = b->next; // important to do this here, in case brush gets linked to a different list + entity_t* ent = b->owner; + + if (ent) // needed! + { + if (FilterBrush (b)) + continue; + + const char *psEntFoundValue = ValueForKey(ent, strFindKey); + + if (stricmp(strFindValue, psEntFoundValue)==0 || // found this exact key/value + (strlen(psEntFoundValue) && strFindValue.IsEmpty()) // or any value for this key if blank value search specified + ) + { + // found this search key/value, so delete it... + // + DeleteKey(ent,strFindKey); + // + // and replace with the new key/value (if specified)... + // + if (!strReplaceKey.IsEmpty() && !strReplaceValue.IsEmpty()) + { + SetKeyValue (ent, strReplaceKey, strReplaceValue); + } + iOccurences++; + } + } + } + if (iOccurences) + { + common->Printf("%d occurence(s) replaced\n",iOccurences); + } + else + { + common->Printf("Nothing found to replace\n"); + } + } + break; + case ID_RET_FIND: + { + gpPrevEntBrushFound = NULL; + FindNextBrush(NULL); + } + break; + } +} +void CMainFrame::OnMiscFindNextEntity() +{ + // try it once, if it fails, try it again from top, and give up if still failed after that... + // + if (!FindNextBrush(gpPrevEntBrushFound)) + { + gpPrevEntBrushFound = NULL; + FindNextBrush(NULL); + } +} + +void CMainFrame::OnMiscSetViewPos() +{ + CString psNewCoords = GetString("Input coords (x y z [rot])\n\nUse spaces to seperate numbers"); + if (!psNewCoords.IsEmpty()) + { + idVec3 v3Viewpos; + float fYaw = 0; + + psNewCoords.Remove(','); + int iArgsFound = sscanf(psNewCoords,"%f %f %f",&v3Viewpos[0], &v3Viewpos[1], &v3Viewpos[2]); + if (iArgsFound == 3) + { + // try for an optional 4th (note how this wasn't part of the sscanf() above, so I can check 1st-3, not just any 3) + // + int iArgsFound = sscanf(psNewCoords,"%f %f %f %f", &v3Viewpos[0], &v3Viewpos[1], &v3Viewpos[2], &fYaw); + if (iArgsFound != 4) + { + fYaw = 0; // jic + } + + g_pParentWnd->GetCamera()->Camera().angles[YAW] = fYaw; + VectorCopy (v3Viewpos, g_pParentWnd->GetCamera()->Camera().origin); + VectorCopy (v3Viewpos, g_pParentWnd->GetXYWnd()->GetOrigin()); + Sys_UpdateWindows (W_ALL); + } + else + { + ErrorBox(va("\"%s\" wasn't 3 valid floats with spaces",psNewCoords)); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturebk() { + DoColor(COLOR_TEXTUREBACK); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsMajor() { + DoColor(COLOR_GRIDMAJOR); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsMinor() { + DoColor(COLOR_GRIDMINOR); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsXybk() { + DoColor(COLOR_GRIDBACK); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush3sided() { + Undo_Start("3 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(3); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush4sided() { + Undo_Start("4 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(4); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush5sided() { + Undo_Start("5 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(5); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush6sided() { + Undo_Start("6 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(6); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush7sided() { + Undo_Start("7 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(7); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush8sided() { + Undo_Start("8 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(8); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrush9sided() { + Undo_Start("9 sided"); + Undo_AddBrushList(&selected_brushes); + Brush_MakeSided(9); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushArbitrarysided() { + Undo_Start("arbitrary sided"); + Undo_AddBrushList(&selected_brushes); + DoSides(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushFlipx() { + Undo_Start("flip X"); + Undo_AddBrushList(&selected_brushes); + + Select_FlipAxis(0); + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->owner->eclass->fixedsize) { + char buf[16]; + float a = FloatForKey(b->owner, "angle"); + a = div((180 - a), 180).rem; + SetKeyValue(b->owner, "angle", itoa(a, buf, 10)); + Brush_Build(b); + } + } + Patch_ToggleInverted(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushFlipy() { + Undo_Start("flip Y"); + Undo_AddBrushList(&selected_brushes); + + Select_FlipAxis(1); + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->owner->eclass->fixedsize) { + float a = FloatForKey(b->owner, "angle"); + if (a == 0 || a == 180 || a == 360) { + continue; + } + + if (a == 90 || a == 270) { + a += 180; + } + else if (a > 270) { + a += 90; + } + else if (a > 180) { + a -= 90; + } + else if (a > 90) { + a += 90; + } + else { + a -= 90; + } + + a = (int)a % 360; + + char buf[16]; + SetKeyValue(b->owner, "angle", itoa(a, buf, 10)); + Brush_Build(b); + } + } + Patch_ToggleInverted(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushFlipz() { + Undo_Start("flip Z"); + Undo_AddBrushList(&selected_brushes); + Select_FlipAxis(2); + Patch_ToggleInverted(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushRotatex() { + Undo_Start("rotate X"); + Undo_AddBrushList(&selected_brushes); + Select_RotateAxis(0, 90); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushRotatey() { + Undo_Start("rotate Y"); + Undo_AddBrushList(&selected_brushes); + Select_RotateAxis(1, 90); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushRotatez() { + Undo_Start("rotate Z"); + Undo_AddBrushList(&selected_brushes); + Select_RotateAxis(2, 90); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnRegionOff() { + Map_RegionOff(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnRegionSetbrush() { + Map_RegionBrush(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnRegionSetselection() { + Map_RegionSelectedBrushes(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnRegionSettallbrush() { + Map_RegionTallBrush(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnRegionSetxy() { + Map_RegionXY(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionArbitraryrotation() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("arbitrary rotation"); + Undo_AddBrushList(&selected_brushes); + + CRotateDlg dlg; + dlg.DoModal(); + + // DoRotate (); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionClone() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Select_Clone(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionConnect() { + ConnectEntities(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionMakehollow() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("hollow"); + Undo_AddBrushList(&selected_brushes); + CSG_MakeHollow(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionCsgsubtract() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("CSG subtract"); + CSG_Subtract(); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionCsgmerge() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("CSG merge"); + Undo_AddBrushList(&selected_brushes); + CSG_Merge(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionDelete() { + brush_t *brush; + + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("delete"); + Undo_AddBrushList(&selected_brushes); + + // add all deleted entities to the undo + for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { + Undo_AddEntity(brush->owner); + } + + // NOTE: Select_Delete does NOT delete entities + Select_Delete(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionDeselect() { + if (!ByeByeSurfaceDialog()) { + if (g_bClipMode) { + OnViewClipper(); + } else if (g_bRotateMode) { + OnSelectMouserotate(); + } else if (g_bScaleMode) { + OnSelectMousescale(); + } else if (g_bPathMode) { + if (ActiveXY()) { + ActiveXY()->KillPathMode(); + } + } else if (g_bAxialMode) { + g_bAxialMode = false; + Sys_UpdateWindows(W_CAMERA); + } else { + if (g_qeglobals.d_select_mode == sel_curvepoint && g_qeglobals.d_num_move_points > 0) { + g_qeglobals.d_num_move_points = 0; + Sys_UpdateWindows(W_ALL); + } else { + Select_Deselect(); + SetStatusText(2, " "); + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionDragedges() { + if (g_qeglobals.d_select_mode == sel_edge) { + g_qeglobals.d_select_mode = sel_brush; + Sys_UpdateWindows(W_ALL); + } + else { + SetupVertexSelection(); + if (g_qeglobals.d_numpoints) { + g_qeglobals.d_select_mode = sel_edge; + } + + Sys_UpdateWindows(W_ALL); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionDragvertecies() { + if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_curvepoint) { + g_qeglobals.d_select_mode = sel_brush; + Sys_UpdateWindows(W_ALL); + } + else { + // --if (QE_SingleBrush() && selected_brushes.next->patchBrush) + if (OnlyPatchesSelected()) { + Patch_EditPatch(); + } + else if (!AnyPatchesSelected()) { + SetupVertexSelection(); + if (g_qeglobals.d_numpoints) { + g_qeglobals.d_select_mode = sel_vertex; + } + } + + Sys_UpdateWindows(W_ALL); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionCenterOrigin() { + Undo_Start("center origin"); + Undo_AddBrushList(&selected_brushes); + Select_CenterOrigin(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectcompletetall() { + //if (ActiveXY()) { + // ActiveXY()->UndoCopy(); + //} + + Select_CompleteTall(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectinside() { + Select_Inside(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectpartialtall() { + Select_PartialTall(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelecttouching() { + Select_Touching(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionUngroupentity() { + Select_Ungroup(); +} + +void CMainFrame::OnAutocaulk() +{ + Select_AutoCaulk(); +} +void CMainFrame::OnUpdateAutocaulk(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( selected_brushes.next != &selected_brushes); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesPopup() { + HandlePopup(this, IDR_POPUP_TEXTURE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesPopup() { + HandlePopup(this, IDR_POPUP_SPLINE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPopupSelection() { + HandlePopup(this, IDR_POPUP_SELECTION); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewChange() { + OnViewNextview(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCameraupdate() { + g_qeglobals.flatRotation++; + + if (g_qeglobals.flatRotation > 2) { + g_qeglobals.flatRotation = 0; + } + + if (g_qeglobals.flatRotation) { + g_qeglobals.rotateAxis = 0; + if (ActiveXY()->GetViewType() == XY) { + g_qeglobals.rotateAxis = 2; + } else if (ActiveXY()->GetViewType() == XZ) { + g_qeglobals.rotateAxis = 1; + } + } + Select_InitializeRotation(); + Sys_UpdateWindows(W_CAMERA | W_XY); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect) { + CFrameWnd::OnSizing(fwSide, pRect); + GetClientRect(g_rctOld); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnHelpAbout() { + DoAbout(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewClipper() { + if (ActiveXY()) { + if (ActiveXY()->ClipMode()) { + ActiveXY()->SetClipMode(false); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_VIEW_CLIPPER, FALSE); + } + else { + if (ActiveXY()->RotateMode()) { + OnSelectMouserotate(); + } + + ActiveXY()->SetClipMode(true); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_VIEW_CLIPPER); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraAngledown() { + m_pCamWnd->Camera().angles[0] -= SPEED_TURN; + if (m_pCamWnd->Camera().angles[0] < -85) { + m_pCamWnd->Camera().angles[0] = -85; + } + + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraAngleup() { + m_pCamWnd->Camera().angles[0] += SPEED_TURN; + if (m_pCamWnd->Camera().angles[0] > 85) { + m_pCamWnd->Camera().angles[0] = 85; + } + + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraBack() { + VectorMA(m_pCamWnd->Camera().origin, -SPEED_MOVE, m_pCamWnd->Camera().forward, m_pCamWnd->Camera().origin); + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraDown() { + m_pCamWnd->Camera().origin[2] -= SPEED_MOVE; + Sys_UpdateWindows(W_CAMERA | W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraForward() { + VectorMA(m_pCamWnd->Camera().origin, SPEED_MOVE, m_pCamWnd->Camera().forward, m_pCamWnd->Camera().origin); + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraLeft() { + m_pCamWnd->Camera().angles[1] += SPEED_TURN; + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraRight() { + m_pCamWnd->Camera().angles[1] -= SPEED_TURN; + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraStrafeleft() { + VectorMA(m_pCamWnd->Camera().origin, -SPEED_MOVE, m_pCamWnd->Camera().right, m_pCamWnd->Camera().origin); + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraStraferight() { + VectorMA(m_pCamWnd->Camera().origin, SPEED_MOVE, m_pCamWnd->Camera().right, m_pCamWnd->Camera().origin); + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows(nUpdate); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCameraUp() { + m_pCamWnd->Camera().origin[2] += SPEED_MOVE; + Sys_UpdateWindows(W_CAMERA | W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnGridToggle() { + g_qeglobals.d_showgrid ^= 1; + Sys_UpdateWindows(W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPrefs() { + BOOL bToolbar = g_PrefsDlg.m_bWideToolbar; + g_PrefsDlg.LoadPrefs(); + if (g_PrefsDlg.DoModal() == IDOK) { + if (g_PrefsDlg.m_bWideToolbar != bToolbar) { + MessageBox("You need to restart Q3Radiant for the view changes to take place."); + } + + g_Inspectors->texWnd.UpdatePrefs(); + + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem(ID_SNAPTOGRID, MF_BYCOMMAND | (!g_PrefsDlg.m_bNoClamp) ? MF_CHECKED : MF_UNCHECKED); + } + } +} + +// +// ======================================================================================================================= +// 0 = radiant styel 1 = qe4 style +// ======================================================================================================================= +// +void CMainFrame::SetWindowStyle(int nStyle) { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTogglecamera() { + if (m_pCamWnd->IsWindowVisible()) { + m_pCamWnd->ShowWindow(SW_HIDE); + } else { + m_pCamWnd->ShowWindow(SW_SHOW); + } +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToggleview() { + if (m_pXYWnd && m_pXYWnd->GetSafeHwnd()) { + if (m_pXYWnd->IsWindowVisible()) { + m_pXYWnd->ShowWindow(SW_HIDE); + } else { + m_pXYWnd->ShowWindow(SW_SHOW); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTogglez() { + if (m_pZWnd && m_pZWnd->GetSafeHwnd()) { + if (m_pZWnd->IsWindowVisible()) { + m_pZWnd->ShowWindow(SW_HIDE); + } else { + m_pZWnd->ShowWindow(SW_SHOW); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToggleLock() { + g_PrefsDlg.m_bTextureLock = !g_PrefsDlg.m_bTextureLock; + + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem(ID_TOGGLE_LOCK, MF_BYCOMMAND | (g_PrefsDlg.m_bTextureLock) ? MF_CHECKED : MF_UNCHECKED); + } + + g_PrefsDlg.SavePrefs(); + SetGridStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditMapinfo() { + CMapInfo dlg; + dlg.DoModal(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditEntityinfo() { + CEntityListDlg::ShowDialog(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewNextview() { + if (m_pXYWnd->GetViewType() == XY) { + m_pXYWnd->SetViewType(XZ); + } + else if (m_pXYWnd->GetViewType() == XZ) { + m_pXYWnd->SetViewType(YZ); + } + else { + m_pXYWnd->SetViewType(XY); + } + + m_pXYWnd->PositionView(); + if (g_qeglobals.flatRotation) { + g_qeglobals.rotateAxis = 0; + if (ActiveXY()->GetViewType() == XY) { + g_qeglobals.rotateAxis = 2; + } else if (ActiveXY()->GetViewType() == XZ) { + g_qeglobals.rotateAxis = 1; + } + } + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnHelpCommandlist() { + CCommandsDlg dlg; + dlg.DoModal(); +#if 0 + if (g_b3Dfx) { + C3DFXCamWnd *pWnd = new C3DFXCamWnd(); + CRect rect(50, 50, 400, 400); + pWnd->Create(_3DFXCAMERA_WINDOW_CLASS, "", QE3_CHILDSTYLE, rect, this, 1234); + pWnd->ShowWindow(SW_SHOW); + } +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileNewproject() +{ +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::UpdateStatusText() { + for (int n = 0; n < 6; n++) { + if (m_strStatus[n].GetLength() >= 0 && m_wndStatusBar.GetSafeHwnd()) { + m_wndStatusBar.SetPaneText(n, m_strStatus[n]); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetStatusText(int nPane, const char *pText) { + if (pText && nPane <= 5 && nPane >= 0) { + m_strStatus[nPane] = pText; + UpdateStatusText(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::UpdateWindows(int nBits) { + + if (!g_bScreenUpdates) { + return; + } + + if (nBits & (W_XY | W_XY_OVERLAY)) { + if (m_pXYWnd) { + m_pXYWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + + if (m_pXZWnd) { + m_pXZWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + + if (m_pYZWnd) { + m_pYZWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + } + + if (nBits & W_CAMERA || ((nBits & W_CAMERA_IFON) && m_bCamPreview)) { + if (m_pCamWnd) { + m_pCamWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + } + + if (nBits & (W_Z | W_Z_OVERLAY)) { + if (m_pZWnd) { + m_pZWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + } + + if (nBits & W_TEXTURE) { + g_Inspectors->texWnd.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void WINAPI Sys_UpdateWindows(int nBits) { + if (g_PrefsDlg.m_bQE4Painting) { + g_nUpdateBits |= nBits; + } + else if ( g_pParentWnd ) { + g_pParentWnd->UpdateWindows(nBits); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFlipClip() { + if (m_pActiveXY) { + m_pActiveXY->FlipClip(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnClipSelected() { + if (m_pActiveXY && m_pActiveXY->ClipMode()) { + Undo_Start("clip selected"); + Undo_AddBrushList(&selected_brushes); + m_pActiveXY->Clip(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); + } else { + if (g_bPatchBendMode) { + Patch_BendHandleENTER(); + } else if (g_bAxialMode) { + + } + //else if (g_bPatchBendMode) { + // Patch_InsDelHandleENTER(); + //} + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplitSelected() { + if (m_pActiveXY) { + Undo_Start("split selected"); + Undo_AddBrushList(&selected_brushes); + m_pActiveXY->SplitClip(); + Undo_EndBrushList(&selected_brushes); + Undo_End(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CXYWnd *CMainFrame::ActiveXY() { + return m_pActiveXY; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToggleviewXz() { + if (m_pXZWnd && m_pXZWnd->GetSafeHwnd()) { + // get windowplacement doesn't actually save this so we will here + g_PrefsDlg.m_bXZVis = m_pXZWnd->IsWindowVisible(); + if (g_PrefsDlg.m_bXZVis) { + m_pXZWnd->ShowWindow(SW_HIDE); + } else { + m_pXZWnd->ShowWindow(SW_SHOW); + } + + g_PrefsDlg.m_bXZVis ^= 1; + g_PrefsDlg.SavePrefs(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToggleviewYz() { + if (m_pYZWnd && m_pYZWnd->GetSafeHwnd()) { + g_PrefsDlg.m_bYZVis = m_pYZWnd->IsWindowVisible(); + if (g_PrefsDlg.m_bYZVis) { + m_pYZWnd->ShowWindow(SW_HIDE); + } else { + m_pYZWnd->ShowWindow(SW_SHOW); + } + + g_PrefsDlg.m_bYZVis ^= 1; + g_PrefsDlg.SavePrefs(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void CMainFrame::OnToggleToolbar() +{ + ShowControlBar(&m_wndToolBar, !m_wndToolBar.IsWindowVisible(), false); +} + +void CMainFrame::OnToggleTextureBar() +{ + ShowControlBar(&m_wndTextureBar, !m_wndTextureBar.IsWindowVisible(), false); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsBrush() { + DoColor(COLOR_BRUSHES); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsClipper() { + DoColor(COLOR_CLIPPER); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsGridtext() { + DoColor(COLOR_GRIDTEXT); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsSelectedbrush() { + DoColor(COLOR_SELBRUSHES); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsGridblock() { + DoColor(COLOR_GRIDBLOCK); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorsViewname() { + DoColor(COLOR_VIEWNAME); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorSetoriginal() { + for (int i = 0; i < 3; i++) { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f; + } + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f; + + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][0] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][2] = 1.0; + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorSetqer() { + for (int i = 0; i < 3; i++) { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f; + } + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f; + + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][0] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][2] = 1.0; + + Sys_UpdateWindows(W_ALL); +} + +//FIXME: these just need to be read from a def file +void CMainFrame::OnColorSetSuperMal() { + OnColorSetqer(); + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0] = 0.35f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1] = 0.35f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2] = 0.35f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][0] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][1] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][2] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][0] = 0.39f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][1] = 0.39f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][2] = 0.39f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.90f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.90f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.74f; + + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnColorSetblack() { + for (int i = 0; i < 3; i++) { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f; + } + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][0] = 0.3f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][1] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][2] = 0.5f; + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.7f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.7f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][0] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][1] = 0.0; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][2] = 1.0; + + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnColorSetMax() { + for (int i=0 ; i<3 ; i++) { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 0.77f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.83f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.89f; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f; + } + + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f; + + //g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0] = 0.0f; + //g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1] = 1.0f; + //g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2] = 1.0f; + + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][0] = 1.0f; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][1] = 0.0f; + g_qeglobals.d_savedinfo.colors[COLOR_PRECISION_CROSSHAIR][2] = 1.0f; + + Sys_UpdateWindows (W_ALL); + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSnaptogrid() { + g_PrefsDlg.m_bNoClamp ^= 1; + g_PrefsDlg.SavePrefs(); + + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem(ID_SNAPTOGRID, MF_BYCOMMAND | (!g_PrefsDlg.m_bNoClamp) ? MF_CHECKED : MF_UNCHECKED); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectScale() { + // if (ActiveXY()) ActiveXY()->UndoCopy(); + Undo_Start("scale"); + Undo_AddBrushList(&selected_brushes); + + CScaleDialog dlg; + if (dlg.DoModal() == IDOK) { + if (dlg.m_fX > 0 && dlg.m_fY > 0 && dlg.m_fZ > 0) { + Select_Scale(dlg.m_fX, dlg.m_fY, dlg.m_fZ); + Sys_UpdateWindows(W_ALL); + } + else { + common->Printf("Warning.. Tried to scale by a zero value."); + } + } + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectMouserotate() { + if (ActiveXY()) { + if (ActiveXY()->ClipMode()) { + OnViewClipper(); + } + + if (ActiveXY()->RotateMode()) { + ActiveXY()->SetRotateMode(false); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSEROTATE, FALSE); + Map_BuildBrushData(); + } + else { + // may not work if no brush selected, see return value + if (ActiveXY()->SetRotateMode(true)) { + g_qeglobals.rotateAxis = 0; + if (ActiveXY()->GetViewType() == XY) { + g_qeglobals.rotateAxis = 2; + } else if (ActiveXY()->GetViewType() == XZ) { + g_qeglobals.rotateAxis = 1; + } + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSEROTATE, TRUE); + } + else { // if MFC called, we need to set back to FALSE ourselves + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSEROTATE, FALSE); + } + } + } + Sys_UpdateWindows(W_CAMERA | W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditCopybrush() { + if (ActiveXY()) { + ActiveXY()->Copy(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditPastebrush() { + if (ActiveXY()) { + ActiveXY()->Paste(); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditUndo() { + // if (ActiveXY()) ActiveXY()->Undo(); + Undo_Undo(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditRedo() { + Undo_Redo(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnUpdateEditUndo(CCmdUI *pCmdUI) { + /* + * BOOL bEnable = false; if (ActiveXY()) bEnable = ActiveXY()->UndoAvailable(); + * pCmdUI->Enable(bEnable); + */ + pCmdUI->Enable(Undo_UndoAvailable()); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnUpdateEditRedo(CCmdUI *pCmdUI) { + pCmdUI->Enable(Undo_RedoAvailable()); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureDec() { + g_qeglobals.d_savedinfo.m_nTextureTweak -= 1.0f; + if ( g_qeglobals.d_savedinfo.m_nTextureTweak == 0.0f ) { + g_qeglobals.d_savedinfo.m_nTextureTweak -= 1.0f; + } + + SetTexValStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureFit() { + Select_FitTexture( 1.0f, 1.0f ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureInc() { + g_qeglobals.d_savedinfo.m_nTextureTweak += 1.0f; + if ( g_qeglobals.d_savedinfo.m_nTextureTweak == 0.0f ) { + g_qeglobals.d_savedinfo.m_nTextureTweak += 1.0f; + } + + SetTexValStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureRotateclock() { + Select_RotateTexture(abs(g_PrefsDlg.m_nRotation)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureRotatecounter() { + Select_RotateTexture(-abs(g_PrefsDlg.m_nRotation)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureScaledown() { + Select_ScaleTexture(0, -g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureScaleup() { + Select_ScaleTexture(0, g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureScaleLeft() { + Select_ScaleTexture(g_qeglobals.d_savedinfo.m_nTextureTweak, 0); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureScaleRight() { + Select_ScaleTexture(g_qeglobals.d_savedinfo.m_nTextureTweak, 0); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureShiftdown() { + Select_ShiftTexture(0, -g_qeglobals.d_savedinfo.m_nTextureTweak, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureShiftleft() { + Select_ShiftTexture(-g_qeglobals.d_savedinfo.m_nTextureTweak, 0, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureShiftright() { + Select_ShiftTexture(g_qeglobals.d_savedinfo.m_nTextureTweak, 0, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTextureShiftup() { + Select_ShiftTexture(0, g_qeglobals.d_savedinfo.m_nTextureTweak, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetGridChecks(int id) { + HMENU hMenu = ::GetMenu(GetSafeHwnd()); + CheckMenuItem(hMenu, ID_GRID_1, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_2, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_4, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_8, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_16, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_32, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_64, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_POINT5, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_POINT25, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_POINT125, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_POINT0625, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, id, MF_BYCOMMAND | MF_CHECKED); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnGridNext() { + if (g_qeglobals.d_gridsize >= MAX_GRID) { + return; + } + + g_qeglobals.d_gridsize *= 2.0f; + + float minGrid = MIN_GRID; + int id = ID_GRID_START; + + while (minGrid < g_qeglobals.d_gridsize && id < ID_GRID_END) { + minGrid *= 2.0f; + id++; + } + + UpdateGrid(); + + SetGridChecks(id); + SetGridStatus(); + Sys_UpdateWindows(W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnGridPrev() { + if (g_qeglobals.d_gridsize <= MIN_GRID) { + return; + } + + g_qeglobals.d_gridsize /= 2; + + float maxGrid = MAX_GRID; + int id = ID_GRID_END; + + while (maxGrid > g_qeglobals.d_gridsize && id > ID_GRID_START) { + maxGrid /= 2.0f; + id--; + } + + UpdateGrid(); + + SetGridChecks(id); + SetGridStatus(); + Sys_UpdateWindows(W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetGridStatus() { + CString strStatus; + char c1; + char c2; + c1 = (g_PrefsDlg.m_bTextureLock) ? 'M' : ' '; + c2 = (g_PrefsDlg.m_bRotateLock) ? 'R' : ' '; + strStatus.Format + ( + "G:%1.2f T:%1.2f R:%i C:%i L:%c%c", + g_qeglobals.d_gridsize, + g_qeglobals.d_savedinfo.m_nTextureTweak, + g_PrefsDlg.m_nRotation, + g_PrefsDlg.m_nCubicScale, + c1, + c2 + ); + SetStatusText(4, strStatus); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetTexValStatus() { + // + // CString strStatus; strStatus.Format("T: %i C: %i", g_nTextureTweak, + // g_nCubicScale); SetStatusText(5, strStatus.GetBuffer(0)); + // + SetGridStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTextureReplaceall() { + CFindTextureDlg::show(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnScalelockx() { + if (g_nScaleHow & SCALE_X) { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKX, FALSE); + } + else { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKX); + } + + g_nScaleHow ^= SCALE_X; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnScalelocky() { + if (g_nScaleHow & SCALE_Y) { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKY, FALSE); + } + else { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKY); + } + + g_nScaleHow ^= SCALE_Y; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnScalelockz() { + if (g_nScaleHow & SCALE_Z) { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKZ, FALSE); + } + else { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SCALELOCKZ); + } + + g_nScaleHow ^= SCALE_Z; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectMousescale() { + if (ActiveXY()) { + if (ActiveXY()->ClipMode()) { + OnViewClipper(); + } + + if (ActiveXY()->RotateMode()) { + // SetRotateMode(false) always works + ActiveXY()->SetRotateMode(false); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSESCALE, FALSE); + } + + if (ActiveXY()->ScaleMode()) { + ActiveXY()->SetScaleMode(false); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSESCALE, FALSE); + } + else { + ActiveXY()->SetScaleMode(true); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_MOUSESCALE); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileImport() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileProjectsettings() { + DoProjectSettings(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnUpdateFileImport(CCmdUI *pCmdUI) { + pCmdUI->Enable(FALSE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCubein() { + g_PrefsDlg.m_nCubicScale--; + if (g_PrefsDlg.m_nCubicScale < 1) { + g_PrefsDlg.m_nCubicScale = 1; + } + + g_PrefsDlg.SavePrefs(); + Sys_UpdateWindows(W_CAMERA); + SetTexValStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCubeout() { + g_PrefsDlg.m_nCubicScale++; + if (g_PrefsDlg.m_nCubicScale > 99) { + g_PrefsDlg.m_nCubicScale = 99; + } + + g_PrefsDlg.SavePrefs(); + Sys_UpdateWindows(W_CAMERA); + SetTexValStatus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCubicclipping() { + g_PrefsDlg.m_bCubicClipping ^= 1; + + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem + ( + ID_VIEW_CUBICCLIPPING, + MF_BYCOMMAND | (g_PrefsDlg.m_bCubicClipping) ? MF_CHECKED : MF_UNCHECKED + ); + } + + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_VIEW_CUBICCLIPPING, (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE); + g_PrefsDlg.SavePrefs(); + Map_BuildBrushData(); + Sys_UpdateWindows(W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileSaveregion() { + SaveAsDialog(true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnUpdateFileSaveregion(CCmdUI *pCmdUI) { + pCmdUI->Enable (static_cast(region_active)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionMovedown() { + Undo_Start("move up"); + Undo_AddBrushList(&selected_brushes); + + idVec3 vAmt; + vAmt[0] = vAmt[1] = 0.0f; + vAmt[2] = -g_qeglobals.d_gridsize; + Select_Move(vAmt); + Sys_UpdateWindows(W_CAMERA | W_XY | W_Z); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionMoveup() { + idVec3 vAmt; + vAmt[0] = vAmt[1] = 0.0f; + vAmt[2] = g_qeglobals.d_gridsize; + Select_Move(vAmt); + Sys_UpdateWindows(W_CAMERA | W_XY | W_Z); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToolbarMain() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToolbarTexture() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionPrint() { + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + Brush_Print(b); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::UpdateTextureBar() { + if (m_wndTextureBar.GetSafeHwnd()) { + m_wndTextureBar.GetSurfaceAttributes(); + } +} + +bool g_bTABDown = false; +bool g_bOriginalFlag; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionTogglesizepaint() { + if (::GetAsyncKeyState('Q')) { + if (!g_bTABDown) { + g_bTABDown = true; + g_bOriginalFlag = ( g_PrefsDlg.m_bSizePaint != FALSE ); + g_PrefsDlg.m_bSizePaint = !g_bOriginalFlag; + Sys_UpdateWindows(W_XY); + return; + } + } + else { + g_bTABDown = false; + g_PrefsDlg.m_bSizePaint = g_bOriginalFlag; + Sys_UpdateWindows(W_XY); + return; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushMakecone() { + Undo_Start("make cone"); + Undo_AddBrushList(&selected_brushes); + DoSides(true); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesLoad() { + BROWSEINFO bi; + CString strPath; + char *p = strPath.GetBuffer(MAX_PATH + 1); + bi.hwndOwner = GetSafeHwnd(); + bi.pidlRoot = NULL; + bi.pszDisplayName = p; + bi.lpszTitle = "Load textures from path"; + bi.ulFlags = 0; + bi.lpfn = NULL; + bi.lParam = NULL; + bi.iImage = 0; + + LPITEMIDLIST pidlBrowse; + pidlBrowse = SHBrowseForFolder(&bi); + if (pidlBrowse) { + SHGetPathFromIDList(pidlBrowse, p); + strPath.ReleaseBuffer(); + AddSlash(strPath); + //FIXME: idMaterial + //Texture_ShowDirectory(strPath.GetBuffer(0)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnToggleRotatelock() { + g_qeglobals.flatRotation = false; + g_qeglobals.rotateAxis++; + if (g_qeglobals.rotateAxis > 2) { + g_qeglobals.rotateAxis = 0; + } + Select_InitializeRotation(); + Sys_UpdateWindows(W_CAMERA | W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveBevel() { + // Curve_MakeCurvedBrush (false, false, false, false, false, true, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveCylinder() { + // Curve_MakeCurvedBrush (false, false, false, true, true, true, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveEighthsphere() { + // Curve_MakeCurvedBrush (false, true, false, true, true, false, false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveEndcap() { + // Curve_MakeCurvedBrush (false, false, false, false, true, true, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveHemisphere() { + // Curve_MakeCurvedBrush (false, true, false, true, true, true, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInvertcurve() { + // Curve_Invert (); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveQuarter() { + // Curve_MakeCurvedBrush (false, true, false, true, true, true, false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveSphere() { + // Curve_MakeCurvedBrush (false, true, true, true, true, true, true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileImportmap() { + CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Map files (*.map)|*.map||", this); + if (dlgFile.DoModal() == IDOK) { + Map_ImportFile(dlgFile.GetPathName().GetBuffer(0)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnFileExportmap() { + CFileDialog dlgFile(FALSE, "map", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Map files (*.map)|*.map||", this); + if (dlgFile.DoModal() == IDOK) { + Map_SaveSelected(dlgFile.GetPathName().GetBuffer(0)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowcurves() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CURVES) & EXCLUDE_CURVES) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCURVES, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCURVES, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectNudgedown() { + NudgeSelection(3, g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectNudgeleft() { + NudgeSelection(0, g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectNudgeright() { + NudgeSelection(2, g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionSelectNudgeup() { + NudgeSelection(1, g_qeglobals.d_savedinfo.m_nTextureTweak); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::NudgeSelection(int nDirection, float fAmount) { + if (ActiveXY()->RotateMode()) { + int nAxis = 0; + if (ActiveXY()->GetViewType() == XY) { + nAxis = 2; + } else if (g_pParentWnd->ActiveXY()->GetViewType() == XZ) { + nAxis = 1; + fAmount = -fAmount; + } + + if (nDirection == 2 || nDirection == 3) { + fAmount = -fAmount; + } + + float fDeg = -fAmount; + + g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAmount; + + CString strStatus; + strStatus.Format + ( + "Rotation x:: %.1f y:: %.1f z:: %.1f", + g_pParentWnd->ActiveXY()->Rotation()[0], + g_pParentWnd->ActiveXY()->Rotation()[1], + g_pParentWnd->ActiveXY()->Rotation()[2] + ); + g_pParentWnd->SetStatusText(2, strStatus); + Select_RotateAxis(nAxis, fDeg, false, true); + Sys_UpdateWindows(W_ALL); + } + else if (ActiveXY()->ScaleMode()) { + if (nDirection == 0 || nDirection == 3) { + fAmount = -fAmount; + } + + idVec3 v; + v[0] = v[1] = v[2] = 1.0f; + if (fAmount > 0) { + v[0] = 1.1f; + v[1] = 1.1f; + v[2] = 1.1f; + } + else { + v[0] = 0.9f; + v[1] = 0.9f; + v[2] = 0.9f; + } + + Select_Scale + ( + (g_nScaleHow & SCALE_X) ? v[0] : 1.0f, + (g_nScaleHow & SCALE_Y) ? v[1] : 1.0f, + (g_nScaleHow & SCALE_Z) ? v[2] : 1.0f + ); + Sys_UpdateWindows(W_ALL); + } + else { + // 0 - left, 1 - up, 2 - right, 3 - down + int nDim; + if (nDirection == 0) { + nDim = ActiveXY()->GetViewType() == YZ ? 1 : 0; + fAmount = -fAmount; + } + else if (nDirection == 1) { + nDim = ActiveXY()->GetViewType() == XY ? 1 : 2; + } + else if (nDirection == 2) { + nDim = ActiveXY()->GetViewType() == YZ ? 1 : 0; + } + else { + nDim = ActiveXY()->GetViewType() == XY ? 1 : 2; + fAmount = -fAmount; + } + + Nudge(nDim, fAmount); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CMainFrame::PreTranslateMessage(MSG *pMsg) { + return CFrameWnd::PreTranslateMessage(pMsg); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::Nudge(int nDim, float fNudge) { + idVec3 vMove; + vMove[0] = vMove[1] = vMove[2] = 0; + vMove[nDim] = fNudge; + Select_Move(vMove, true); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesLoadlist() { + CDialogTextures dlg; + dlg.DoModal(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectByBoundingBrush() { + g_PrefsDlg.m_selectByBoundingBrush ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton + ( + ID_SELECT_BYBOUNDINGBRUSH, + (g_PrefsDlg.m_selectByBoundingBrush) ? TRUE : FALSE + ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectBrushesOnly() { + g_PrefsDlg.m_selectOnlyBrushes ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_BRUSHESONLY, (g_PrefsDlg.m_selectOnlyBrushes) ? TRUE : FALSE); +} + + + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnDynamicLighting() { + CCamWnd *pCam = new CCamWnd(); + CRect rect(100, 100, 300, 300); + pCam->Create(CAMERA_WINDOW_CLASS, "", WS_OVERLAPPEDWINDOW, rect, GetDesktopWindow(), 12345); + pCam->ShowWindow(SW_SHOW); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveSimplepatchmesh() { + Undo_Start("make simpe patch mesh"); + Undo_AddBrushList(&selected_brushes); + + CPatchDensityDlg dlg; + dlg.DoModal(); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchToggleBox() { + g_bPatchShowBounds ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_SHOWBOUNDINGBOX, (g_bPatchShowBounds) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchWireframe() { + g_bPatchWireFrame ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_WIREFRAME, (g_bPatchWireFrame) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchcone() { + Undo_Start("make curve cone"); + Undo_AddBrushList(&selected_brushes); + Patch_BrushToMesh(true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchtube() { + Undo_Start("make curve cylinder"); + Undo_AddBrushList(&selected_brushes); + Patch_BrushToMesh(false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchWeld() { + g_bPatchWeld ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_WELD, (g_bPatchWeld) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchbevel() { + Undo_Start("make bevel"); + Undo_AddBrushList(&selected_brushes); + Patch_BrushToMesh(false, true, false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchendcap() { + Undo_Start("make end cap"); + Undo_AddBrushList(&selected_brushes); + Patch_BrushToMesh(false, false, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchinvertedbevel() { + // Patch_BrushToMesh(false, true, false, true); Sys_UpdateWindows (W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchinvertedendcap() { + // Patch_BrushToMesh(false, false, true, true); Sys_UpdateWindows (W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchDrilldown() { + g_bPatchDrillDown ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_DRILLDOWN, (g_bPatchDrillDown) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertcolumn() { + Undo_Start("insert colum"); + Undo_AddBrushList(&selected_brushes); + + // Patch_AdjustSelectedRowCols(0, 2); + Patch_AdjustSelected(true, true, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertrow() { + Undo_Start("insert row"); + Undo_AddBrushList(&selected_brushes); + + // Patch_AdjustSelectedRowCols(2, 0); + Patch_AdjustSelected(true, false, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeletecolumn() { + Undo_Start("delete column"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, true, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeleterow() { + Undo_Start("delete row"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, false, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertAddcolumn() { + Undo_Start("add (2) columns"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(true, true, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertAddrow() { + Undo_Start("add (2) rows"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(true, false, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertInsertcolumn() { + Undo_Start("insert (2) columns"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(true, true, false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveInsertInsertrow() { + Undo_Start("insert (2) rows"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(true, false, false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveNegative() { + Patch_ToggleInverted(); + + // Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveNegativeTextureX() { + Select_FlipTexture(false); + + // Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveNegativeTextureY() { + Select_FlipTexture(true); + // Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeleteFirstcolumn() { + Undo_Start("delete first (2) columns"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, true, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeleteFirstrow() { + Undo_Start("delete first (2) rows"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, false, true); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeleteLastcolumn() { + Undo_Start("delete last (2) columns"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, true, false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDeleteLastrow() { + Undo_Start("delete last (2) rows"); + Undo_AddBrushList(&selected_brushes); + Patch_AdjustSelected(false, false, false); + Sys_UpdateWindows(W_ALL); + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchBend() { + Patch_BendToggle(); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_BEND, (g_bPatchBendMode) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchInsdel() { + Patch_InsDelToggle(); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_INSDEL, (g_bPatchInsertMode) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchEnter() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +extern bool Sys_KeyDown(int key); +void CMainFrame::OnPatchTab() { + if (g_bPatchBendMode) { + Patch_BendHandleTAB(); + } + else if (g_bPatchInsertMode) { + Patch_InsDelHandleTAB(); + } + else if (g_bAxialMode) { + int faceCount = g_ptrSelectedFaces.GetSize(); + if (faceCount > 0) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0)); + int *ip = (Sys_KeyDown(VK_SHIFT)) ? &g_axialAnchor : &g_axialDest; + (*ip)++; + if ( *ip >= selFace->face_winding->GetNumPoints() ) { + *ip = 0; + } + } + Sys_UpdateWindows(W_CAMERA); + } else { + // + // check to see if the selected brush is part of a func group if it is, deselect + // everything and reselect the next brush in the group + // + brush_t *b = selected_brushes.next; + entity_t *e; + if (b != &selected_brushes) { + if ( idStr::Icmp(b->owner->eclass->name, "worldspawn") != 0 ) { + e = b->owner; + Select_Deselect(); + brush_t *b2; + for (b2 = e->brushes.onext; b2 != &e->brushes; b2 = b2->onext) { + if (b == b2) { + b2 = b2->onext; + break; + } + } + + if (b2 == &e->brushes) { + b2 = b2->onext; + } + + Select_Brush(b2, false); + Sys_UpdateWindows(W_ALL); + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::UpdatePatchToolbarButtons() { + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_BEND, (g_bPatchBendMode) ? TRUE : FALSE); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_PATCH_INSDEL, (g_bPatchInsertMode) ? TRUE : FALSE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchdensetube() { + Undo_Start("dense cylinder"); + Undo_AddBrushList(&selected_brushes); + + Patch_BrushToMesh(false); + OnCurveInsertAddrow(); + OnCurveInsertInsertrow(); + Sys_UpdateWindows(W_ALL); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchverydensetube() { + Undo_Start("very dense cylinder"); + Undo_AddBrushList(&selected_brushes); + + Patch_BrushToMesh(false); + OnCurveInsertAddrow(); + OnCurveInsertInsertrow(); + OnCurveInsertAddrow(); + OnCurveInsertInsertrow(); + Sys_UpdateWindows(W_ALL); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveCap() { + Patch_CapCurrent(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveCapInvertedbevel() { + Patch_CapCurrent(true); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveCapInvertedendcap() { + Patch_CapCurrent(false, true); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveRedisperseCols() { + Patch_DisperseColumns(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveRedisperseRows() { + Patch_DisperseRows(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchNaturalize() { + Patch_NaturalizeSelected(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchNaturalizeAlt() { + Patch_NaturalizeSelected(false, false, true); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSnapToGrid() { + Select_SnapToGrid(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurvePatchsquare() { + Undo_Start("square cylinder"); + Undo_AddBrushList(&selected_brushes); + + Patch_BrushToMesh(false, false, false, true); + Sys_UpdateWindows(W_ALL); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::CheckTextureScale(int id) { + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem(ID_TEXTURES_TEXTUREWINDOWSCALE_10, MF_BYCOMMAND | MF_UNCHECKED); + pMenu->CheckMenuItem(ID_TEXTURES_TEXTUREWINDOWSCALE_25, MF_BYCOMMAND | MF_UNCHECKED); + pMenu->CheckMenuItem(ID_TEXTURES_TEXTUREWINDOWSCALE_50, MF_BYCOMMAND | MF_UNCHECKED); + pMenu->CheckMenuItem(ID_TEXTURES_TEXTUREWINDOWSCALE_100, MF_BYCOMMAND | MF_UNCHECKED); + pMenu->CheckMenuItem(ID_TEXTURES_TEXTUREWINDOWSCALE_200, MF_BYCOMMAND | MF_UNCHECKED); + pMenu->CheckMenuItem(id, MF_BYCOMMAND | MF_CHECKED); + } + + g_PrefsDlg.SavePrefs(); + //FIXME: idMaterial + //Texture_ResetPosition(); + Sys_UpdateWindows(W_TEXTURE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesTexturewindowscale10() { + g_PrefsDlg.m_nTextureScale = 10; + CheckTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_10); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesTexturewindowscale100() { + g_PrefsDlg.m_nTextureScale = 100; + CheckTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_100); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesTexturewindowscale200() { + g_PrefsDlg.m_nTextureScale = 200; + CheckTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_200); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesTexturewindowscale25() { + g_PrefsDlg.m_nTextureScale = 25; + CheckTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_25); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesTexturewindowscale50() { + g_PrefsDlg.m_nTextureScale = 50; + CheckTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_50); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesFlush() { + //FIXME: idMaterial + //Texture_Flush(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveOverlayClear() { + Patch_ClearOverlays(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveOverlaySet() { + Patch_SetOverlays(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveThicken() { + Undo_Start("curve thicken"); + Undo_AddBrushList(&selected_brushes); + + CDialogThick dlg; + if ( dlg.DoModal() == IDOK ) { + Patch_Thicken( dlg.m_nAmount, ( dlg.m_bSeams != FALSE ) ); + Sys_UpdateWindows(W_ALL); + } + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveCyclecap() { + Patch_NaturalizeSelected(true, true); + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnCurveCyclecapAlt() { + Patch_NaturalizeSelected(true, true, true); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveMatrixTranspose() { + Patch_Transpose(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesReloadshaders() { + CWaitCursor wait; + declManager->Reload( false ); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::SetEntityCheck() { + CMenu *pMenu = GetMenu(); + if (pMenu) { + pMenu->CheckMenuItem(ID_VIEW_ENTITIESAS_WIREFRAME, MF_BYCOMMAND | (g_PrefsDlg.m_nEntityShowState == ENTITY_WIRE) ? MF_CHECKED : MF_UNCHECKED); + pMenu->CheckMenuItem(ID_VIEW_ENTITIESAS_SKINNED, MF_BYCOMMAND | (g_PrefsDlg.m_nEntityShowState == ENTITY_SKINNED) ? MF_CHECKED : MF_UNCHECKED); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnShowEntities() { + HandlePopup(this, IDR_POPUP_ENTITY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewEntitiesasSkinned() { + g_PrefsDlg.m_nEntityShowState = ENTITY_SKINNED; + SetEntityCheck(); + g_PrefsDlg.SavePrefs(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewEntitiesasWireframe() { + g_PrefsDlg.m_nEntityShowState = ENTITY_WIRE; + SetEntityCheck(); + g_PrefsDlg.SavePrefs(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowhint() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_HINT) & EXCLUDE_HINT) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWHINT, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWHINT, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesShowall() { + Texture_ShowAll(); +} + +void CMainFrame::OnTexturesHideall() { + Texture_HideAll(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPatchInspector() { + DoPatchInspector(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewOpengllighting() { + g_PrefsDlg.m_bGLLighting ^= 1; + g_PrefsDlg.SavePrefs(); + CheckMenuItem + ( + ::GetMenu(GetSafeHwnd()), + ID_VIEW_OPENGLLIGHTING, + MF_BYCOMMAND | (g_PrefsDlg.m_bGLLighting) ? MF_CHECKED : MF_UNCHECKED + ); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectAll() { + Select_AllOfType(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowcaulk() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CAULK) & EXCLUDE_CAULK) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCAULK, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWCAULK, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveFreeze() { + Patch_Freeze(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveUnFreeze() { + Patch_UnFreeze(false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveUnFreezeAll() { + Patch_UnFreeze(true); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectReselect() { + Select_Reselect(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewShowangles() { + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_ANGLES) & EXCLUDE_ANGLES) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWANGLES, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOWANGLES, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditSaveprefab() { + CFileDialog dlgFile + ( + FALSE, + "pfb", + NULL, + OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + "Prefab files (*.pfb)|*.pfb||", + this + ); + char CurPath[1024]; + ::GetCurrentDirectory(1024, CurPath); + + dlgFile.m_ofn.lpstrInitialDir = CurPath; + if (dlgFile.DoModal() == IDOK) { + Map_SaveSelected(dlgFile.GetPathName().GetBuffer(0)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnEditLoadprefab() { + CFileDialog dlgFile + ( + TRUE, + "pfb", + NULL, + OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + "Prefab files (*.pfb)|*.pfb||", + this + ); + char CurPath[1024]; + ::GetCurrentDirectory(1024, CurPath); + dlgFile.m_ofn.lpstrInitialDir = CurPath; + if (dlgFile.DoModal() == IDOK) { + Map_ImportFile(dlgFile.GetPathName().GetBuffer(0)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveMoreendcapsbevelsSquarebevel() { + Undo_Start("square bevel"); + Undo_AddBrushList(&selected_brushes); + + Patch_BrushToMesh(false, true, false, true); + Sys_UpdateWindows(W_ALL); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveMoreendcapsbevelsSquareendcap() { + Undo_Start("square endcap"); + Undo_AddBrushList(&selected_brushes); + + Patch_BrushToMesh(false, false, true, true); + Sys_UpdateWindows(W_ALL); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnBrushPrimitivesSphere() { + Undo_Start("make sphere"); + Undo_AddBrushList(&selected_brushes); + + DoSides(false, true); + + Undo_EndBrushList(&selected_brushes); + Undo_End(); +} + +extern bool g_bCrossHairs; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewCrosshair() { + g_bCrossHairs ^= 1; + Sys_UpdateWindows(W_XY); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewHideshowHideselected() { + Select_Hide(); + Select_Deselect(); +} + +void CMainFrame::OnViewHideshowHideNotselected() { + Select_Hide(true); + Select_Deselect(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnViewHideshowShowhidden() { + Select_ShowAllHidden(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesShadersShow() { + // + // g_PrefsDlg.m_bShowShaders ^= 1; CheckMenuItem ( + // ::GetMenu(GetSafeHwnd()), ID_TEXTURES_SHADERS_SHOW, MF_BYCOMMAND | + // ((g_PrefsDlg.m_bShowShaders) ? MF_CHECKED : MF_UNCHECKED )); + // Sys_UpdateWindows(W_TEXTURE); + // +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnTexturesFlushUnused() { + //FIXME: idMaterial + //Texture_FlushUnused(); + Sys_UpdateWindows(W_TEXTURE); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionInvert() { + Select_Invert(); + Sys_UpdateWindows(W_XY | W_Z | W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnProjectedLight() { + LightEditorInit( NULL ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnShowLighttextures() { + g_bShowLightTextures ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SHOW_LIGHTTEXTURES, (g_bShowLightTextures) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnShowLightvolumes() { + g_bShowLightVolumes ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SHOW_LIGHTVOLUMES, (g_bShowLightVolumes) ? TRUE : FALSE); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized) { + CFrameWnd::OnActivate(nState, pWndOther, bMinimized); + + if ( nState != WA_INACTIVE ) { + common->ActivateTool( true ); + if (::IsWindowVisible(win32.hWnd)) { + ::ShowWindow(win32.hWnd, SW_HIDE); + } + + // start playing the editor sound world + soundSystem->SetPlayingSoundWorld( g_qeglobals.sw ); + } + else { + //com_editorActive = false; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesMode() { + g_qeglobals.d_select_mode = sel_addpoint; + g_splineList->clear(); + g_splineList->startEdit(true); + showCameraInspector(); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesLoad() { + g_splineList->load("maps/test.camera"); + g_splineList->buildCamera(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesSave() { + g_splineList->save("maps/test.camera"); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesEdit() { + showCameraInspector(); + Sys_UpdateWindows(W_ALL); +} + +extern void testCamSpeed(); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplineTest() { + long start = GetTickCount(); + g_splineList->startCamera(start); + + float cycle = g_splineList->getTotalTime(); + long msecs = cycle * 1000; + long current = start; + idVec3 lookat(0, 0, 0); + idVec3 dir; + + while (current < start + msecs) { + float fov; + g_splineList->getCameraInfo(current, g_pParentWnd->GetCamera()->Camera().origin, dir, &fov); + g_pParentWnd->GetCamera()->Camera().angles[1] = atan2(dir[1], dir[0]) * 180 / 3.14159; + g_pParentWnd->GetCamera()->Camera().angles[0] = asin(dir[2]) * 180 / 3.14159; + g_pParentWnd->UpdateWindows(W_XY | W_CAMERA); + current = GetTickCount(); + } + + g_splineList->setRunning(false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesTargetPoints() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSplinesCameraPoints() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPopupNewcameraInterpolated() { + g_qeglobals.d_select_mode = sel_addpoint; + g_qeglobals.selectObject = g_splineList->startNewCamera(idCameraPosition::INTERPOLATED); + OnSplinesEdit(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPopupNewcameraSpline() { + g_qeglobals.d_select_mode = sel_addpoint; + g_qeglobals.selectObject = g_splineList->startNewCamera(idCameraPosition::SPLINE); + OnSplinesEdit(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnPopupNewcameraFixed() { + g_qeglobals.d_select_mode = sel_addpoint; + g_qeglobals.selectObject = g_splineList->startNewCamera(idCameraPosition::FIXED); + OnSplinesEdit(); +} + +extern void Patch_AdjustSubdivisions(float hadj, float vadj); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveIncreaseVert() { + Patch_AdjustSubdivisions( 0.0f, -0.5f ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDecreaseVert() { + Patch_AdjustSubdivisions( 0.0f, 0.5f ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveIncreaseHorz() { + Patch_AdjustSubdivisions( -0.5f, 0.0f ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnCurveDecreaseHorz() { + Patch_AdjustSubdivisions( 0.5f, 0.0f ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CMainFrame::OnSelectionMoveonly() { + g_moveOnly ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECTION_MOVEONLY, (g_moveOnly) ? TRUE : FALSE); +} + +void CMainFrame::OnSelectBrushlight() +{ + // TODO: Add your command handler code here + +} + +void CMainFrame::OnSelectionCombine() +{ + if (g_qeglobals.d_select_count < 2) { + Sys_Status("Must have at least two things selected.", 0); + Sys_Beep(); + return; + } + + entity_t *e1 = g_qeglobals.d_select_order[0]->owner; + + if (e1 == world_entity) { + Sys_Status("First selection must not be world.", 0); + Sys_Beep(); + return; + } + + idStr str; + idMat3 mat; + idVec3 v; + if (e1->eclass->nShowFlags & ECLASS_LIGHT) { + // copy the lights origin and rotation matrix to + // light_origin and light_rotation + e1->trackLightOrigin = true; + e1->brushes.onext->trackLightOrigin = true; + if (GetVectorForKey(e1, "origin", v)) { + SetKeyVec3(e1, "light_origin", v); + e1->lightOrigin = v; + } + if (!GetMatrixForKey(e1, "rotation", mat)) { + mat.Identity(); + } + sprintf(str, "%g %g %g %g %g %g %g %g %g", mat[0][0], mat[0][1], mat[0][2], mat[1][0], mat[1][1], mat[1][2], mat[2][0], mat[2][1], mat[2][2]); + SetKeyValue(e1, "light_rotation", str, false); + e1->lightRotation = mat; + } + + bool setModel = true; + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->owner != e1) { + if (e1->eclass->nShowFlags & ECLASS_LIGHT) { + if (GetVectorForKey(b->owner, "origin", v)) { + e1->origin = b->owner->origin; + SetKeyVec3(e1, "origin", b->owner->origin); + } + if (GetMatrixForKey(b->owner, "rotation", mat)) { + e1->rotation = b->owner->rotation; + mat = b->owner->rotation; + sprintf(str, "%g %g %g %g %g %g %g %g %g", mat[0][0], mat[0][1], mat[0][2], mat[1][0], mat[1][1], mat[1][2], mat[2][0], mat[2][1], mat[2][2]); + SetKeyValue(e1, "rotation", str, false); + } + if (b->modelHandle) { + SetKeyValue(e1, "model", ValueForKey(b->owner, "model")); + setModel = false; + } else { + b->entityModel = true; + } + } + Entity_UnlinkBrush(b); + Entity_LinkBrush(e1, b); + } + } + + if (setModel) { + SetKeyValue(e1, "model", ValueForKey(e1, "name")); + } + + Select_Deselect(); + Select_Brush(g_qeglobals.d_select_order[0]); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +extern void Patch_Weld(patchMesh_t *p, patchMesh_t *p2); +void CMainFrame::OnPatchCombine() { + patchMesh_t *p, *p2; + p = p2 = NULL; + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->pPatch) { + if (p == NULL) { + p = b->pPatch; + } else if (p2 == NULL) { + p2 = b->pPatch; + Patch_Weld(p, p2); + return; + } + } + } +} + +void CMainFrame::OnShowDoom() +{ + int show = ::IsWindowVisible(win32.hWnd) ? SW_HIDE : SW_NORMAL; + if (show == SW_NORMAL) { + g_Inspectors->SetMode(W_TEXTURE); + } + ::ShowWindow(win32.hWnd, show); +} + +void CMainFrame::OnViewRendermode() +{ + m_pCamWnd->ToggleRenderMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_RENDERMODE, MF_BYCOMMAND | (m_pCamWnd->GetRenderMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnViewRebuildrenderdata() +{ + m_pCamWnd->BuildRendererState(); + if (!m_pCamWnd->GetRenderMode()) { + OnViewRendermode(); + } + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnViewRealtimerebuild() +{ + m_pCamWnd->ToggleRebuildMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_REALTIMEREBUILD, MF_BYCOMMAND | (m_pCamWnd->GetRebuildMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnViewRenderentityoutlines() +{ + m_pCamWnd->ToggleEntityMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_RENDERENTITYOUTLINES, MF_BYCOMMAND | (m_pCamWnd->GetEntityMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_ALL); +} + +void CMainFrame::OnViewMaterialanimation() +{ + m_pCamWnd->ToggleAnimationMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_MATERIALANIMATION, MF_BYCOMMAND | (m_pCamWnd->GetAnimationMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_ALL); +} + +extern void Face_SetAxialScale_BrushPrimit(face_t *face, bool y); +void CMainFrame::OnAxialTextureByWidth() { + // temp test code + int faceCount = g_ptrSelectedFaces.GetSize(); + + if (faceCount > 0) { + for (int i = 0; i < faceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + Face_SetAxialScale_BrushPrimit(selFace, false); + } + Sys_UpdateWindows(W_CAMERA); + } + +} + +void CMainFrame::OnAxialTextureByHeight() { + // temp test code + int faceCount = g_ptrSelectedFaces.GetSize(); + + if (faceCount > 0) { + for (int i = 0; i < faceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + Face_SetAxialScale_BrushPrimit(selFace, true); + } + Sys_UpdateWindows(W_CAMERA); + } +} + +void CMainFrame::OnAxialTextureArbitrary() { + if (g_bAxialMode) { + g_bAxialMode = false; + } + int faceCount = g_ptrSelectedFaces.GetSize(); + if (faceCount > 0) { + g_axialAnchor = 0; + g_axialDest = 1; + g_bAxialMode = true; + } + Sys_UpdateWindows(W_CAMERA); +} + +extern void Select_ToOBJ(); +void CMainFrame::OnSelectionExportToobj() +{ + Select_ToOBJ(); +} + +extern void Select_ToCM(); +void CMainFrame::OnSelectionExportToCM() +{ + Select_ToCM(); +} + +void CMainFrame::OnSelectionWireFrameOff() { + Select_WireFrame( false ); +} + +void CMainFrame::OnSelectionWireFrameOn() { + Select_WireFrame( true ); +} + +void CMainFrame::OnSelectionVisibleOn() { + Select_ForceVisible( true ); +} + +void CMainFrame::OnSelectionVisibleOff() { + Select_ForceVisible( false ); +} + + +void CMainFrame::OnViewRenderselection() +{ + m_pCamWnd->ToggleSelectMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_RENDERSELECTION, MF_BYCOMMAND | (m_pCamWnd->GetSelectMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_CAMERA); +} + +void CMainFrame::OnSelectNomodels() +{ + g_PrefsDlg.m_selectNoModels ^= 1; + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SELECT_NOMODELS, (g_PrefsDlg.m_selectNoModels) ? TRUE : FALSE); +} + +void CMainFrame::OnViewShowShowvisportals() +{ + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_VISPORTALS) & EXCLUDE_VISPORTALS) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOW_SHOWVISPORTALS, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOW_SHOWVISPORTALS, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +void CMainFrame::OnViewShowNoDraw() +{ + if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_NODRAW) & EXCLUDE_NODRAW) { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOW_NODRAW, MF_BYCOMMAND | MF_UNCHECKED); + } + else { + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_SHOW_NODRAW, MF_BYCOMMAND | MF_CHECKED); + } + + Sys_UpdateWindows(W_XY | W_CAMERA); +} + + + +void CMainFrame::OnViewRendersound() +{ + m_pCamWnd->ToggleSoundMode(); + CheckMenuItem(::GetMenu(GetSafeHwnd()), ID_VIEW_RENDERSOUND, MF_BYCOMMAND | (m_pCamWnd->GetSoundMode()) ? MF_CHECKED : MF_UNCHECKED); + Sys_UpdateWindows(W_CAMERA); +} + + +void CMainFrame::OnSoundShowsoundvolumes() +{ + g_qeglobals.d_savedinfo.showSoundAlways ^= 1; + if (g_qeglobals.d_savedinfo.showSoundAlways) { + g_qeglobals.d_savedinfo.showSoundWhenSelected = false; + } + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundAlways); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSELECTEDSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundWhenSelected); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +void CMainFrame::OnNurbEditor() { + nurbMode ^= 1; + if (nurbMode) { + int num = nurb.GetNumValues(); + idStr temp = va("%i 3 ", num); + for (int i = 0; i < num; i++) { + temp += va("(%i %i) ", (int)nurb.GetValue(i).x, (int)nurb.GetValue(i).y); + } + temp += "\r\n"; + if (OpenClipboard()) { + ::EmptyClipboard(); + HGLOBAL clip; + char* buff; + clip = ::GlobalAlloc(GMEM_DDESHARE, temp.Length()+1); + buff = (char*)::GlobalLock(clip); + strcpy(buff, temp); + ::GlobalUnlock(clip); + ::SetClipboardData(CF_TEXT, clip); + ::CloseClipboard(); + } + nurb.Clear(); + } +} + + +void CMainFrame::OnSoundShowselectedsoundvolumes() +{ + g_qeglobals.d_savedinfo.showSoundWhenSelected ^= 1; + if (g_qeglobals.d_savedinfo.showSoundWhenSelected) { + g_qeglobals.d_savedinfo.showSoundAlways = false; + } + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundAlways); + m_wndToolBar.GetToolBarCtrl().CheckButton(ID_SOUND_SHOWSELECTEDSOUNDVOLUMES,g_qeglobals.d_savedinfo.showSoundWhenSelected); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +void CMainFrame::OnSelectAlltargets() +{ + Select_AllTargets(); +} + + +void CMainFrame::OnSelectCompleteEntity() +{ + brush_t* b = NULL; + entity_t* e = NULL; + + b = selected_brushes.next; + if ( b == &selected_brushes ) + { + return; //no brushes selected + } + + e = b->owner; + if ( b->owner == world_entity ) + { + return; //don't select the world entity + } + + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) + { + Select_Brush ( b , false ); + } + Sys_UpdateWindows ( W_ALL ); +} + + + + +//--------------------------------------------------------------------------- +// OnPrecisionCursorCycle +// +// Called when the user presses the "cycle precision cursor mode" key. +// Cycles the precision cursor among the following three modes: +// PRECISION_CURSOR_NONE +// PRECISION_CURSOR_SNAP +// PRECISION_CURSOR_FREE +//--------------------------------------------------------------------------- +void CMainFrame::OnPrecisionCursorCycle() +{ + m_pActiveXY->CyclePrecisionCrosshairMode(); +} + +void CMainFrame::OnGenerateMaterialsList() +{ + idStrList mtrList; + idStr mtrName,mtrFileName; + + + g_Inspectors->consoleWnd.ExecuteCommand ( "clear" ); + Sys_BeginWait (); + common->Printf ( "Generating list of active materials...\n" ); + + for ( brush_t* b = active_brushes.next ; b != &active_brushes ; b=b->next ) { + if ( b->pPatch ){ + mtrName = b->pPatch->d_texture->GetName(); + if ( !mtrList.Find( mtrName) ) { + mtrList.Insert ( mtrName ); + } + + } + else { + for ( face_t* f = b->brush_faces ; f != NULL ; f=f->next) + { + mtrName = f->d_texture->GetName(); + if ( !mtrList.Find( mtrName) ) { + mtrList.Insert ( mtrName ); + } + + } + } + } + + mtrList.Sort(); + for ( int i = 0 ; i < mtrList.Num() ; i++ ) { + common->Printf ( "%s\n" , mtrList[i].c_str()); + } + + mtrFileName = currentmap; +// mtrFileName.ExtractFileName( mtrFileName ); + mtrFileName = mtrFileName.StripPath(); + + common->Printf ( "Done...found %i unique materials\n" , mtrList.Num()); + mtrFileName = mtrFileName + idStr ( "_Materials.txt" ); + g_Inspectors->SetMode ( W_CONSOLE , true ); + g_Inspectors->consoleWnd.SetConsoleText ( va ( "condump %s" , mtrFileName.c_str()) ); + + Sys_EndWait (); +} + +/* +======================================================================================================================= +======================================================================================================================= +*/ + + +void CMainFrame::OnSplinesAddPoints() { + g_Inspectors->entityDlg.AddCurvePoints(); +} + +void CMainFrame::OnSplinesEditPoints() { + g_Inspectors->entityDlg.EditCurvePoints(); +} + +void CMainFrame::OnSplinesDeletePoint() { + g_Inspectors->entityDlg.DeleteCurvePoint(); +} + +void CMainFrame::OnSplinesInsertPoint() { + g_Inspectors->entityDlg.InsertCurvePoint(); +} diff --git a/tools/radiant/MainFrm.h b/tools/radiant/MainFrm.h new file mode 100644 index 000000000..4c32ad7d4 --- /dev/null +++ b/tools/radiant/MainFrm.h @@ -0,0 +1,550 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#if !defined(AFX_MAINFRM_H__330BBF0A_731C_11D1_B539_00AA00A410FC__INCLUDED_) +#define AFX_MAINFRM_H__330BBF0A_731C_11D1_B539_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "XYWnd.h" +#include "NewTexWnd.h" +#include "ZWnd.h" +#include "CamWnd.h" +#include "TextureBar.h" + + +const int RAD_SHIFT = 0x01; +const int RAD_ALT = 0x02; +const int RAD_CONTROL = 0x04; +const int RAD_PRESS = 0x08; + +struct SCommandInfo +{ + char* m_strCommand; + unsigned int m_nKey; + unsigned int m_nModifiers; + unsigned int m_nCommand; +}; + +struct SKeyInfo +{ + char* m_strName; + unsigned int m_nVKKey; +}; + + + + +class CMainFrame : public CFrameWnd +{ + DECLARE_DYNAMIC(CMainFrame) +public: + CMainFrame(); + void HandleKey(UINT nChar, UINT nRepCnt, UINT nFlags, bool bDown = true) + { + if (bDown) + OnKeyDown(nChar, nRepCnt, nFlags); + else + OnKeyUp(nChar, nRepCnt, nFlags); + }; + + // Attributes +public: + + // Operations +public: + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) +public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL PreTranslateMessage(MSG* pMsg); +protected: + virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); + virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); + virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); + virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); + //}}AFX_VIRTUAL + + // Implementation +public: + void UpdatePatchToolbarButtons(); + void NudgeSelection(int nDirection, float fAmount); + void UpdateTextureBar(); + void SetButtonMenuStates(); + void SetTexValStatus(); + void SetGridStatus(); + void RoutineProcessing(); + CXYWnd* ActiveXY(); + void UpdateWindows(int nBits); + void SetStatusText(int nPane, const char* pText); + void UpdateStatusText(); + void SetWindowStyle(int nStyle); + bool GetNurbMode() { + return nurbMode; + } + idCurve_NURBS *GetNurb() { + return &nurb; + } + void OnPrecisionCursorCycle(); + + virtual ~CMainFrame(); + CXYWnd* GetXYWnd() {return m_pXYWnd;}; + CXYWnd* GetXZWnd() {return m_pXZWnd;}; + CXYWnd* GetYZWnd() {return m_pYZWnd;}; + CCamWnd* GetCamera() {return m_pCamWnd;}; + CZWnd* GetZWnd() {return m_pZWnd;}; + + void SetActiveXY(CXYWnd* p) + { + if (m_pActiveXY) + m_pActiveXY->SetActive(false); + m_pActiveXY = p; + + if (m_pActiveXY) + m_pActiveXY->SetActive(true); + + }; + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + CTextureBar m_wndTextureBar; + CSplitterWnd m_wndSplit; + CSplitterWnd m_wndSplit2; + CSplitterWnd m_wndSplit3; + CXYWnd* m_pXYWnd; + CXYWnd* m_pYZWnd; + CXYWnd* m_pXZWnd; + CCamWnd* m_pCamWnd; + CZWnd* m_pZWnd; + CString m_strStatus[15]; + CXYWnd* m_pActiveXY; + bool m_bCamPreview; + bool busy; + bool nurbMode; + idCurve_NURBS nurb; + // Generated message map functions +protected: + bool m_bDoLoop; + void CreateQEChildren(); + void LoadCommandMap(); + void SaveCommandMap(); + void ShowMenuItemKeyBindings(CMenu *pMenu); + void SetEntityCheck(); + void SetGridChecks(int nID); +public: + void Nudge(int nDim, float fNudge); + void SetBusy(bool b) { + busy = b; + } + + + // these are public so i can easily reflect messages + // from child windows.. + //{{AFX_MSG(CMainFrame) + afx_msg void OnBSPStatus(UINT wParam, long lParam); + afx_msg void OnBSPDone(UINT wParam, long lParam); + afx_msg void OnParentNotify(UINT message, LPARAM lParam); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnDestroy(); + afx_msg void OnClose(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void ToggleCamera(); + afx_msg void OnFileClose(); + afx_msg void OnFileExit(); + afx_msg void OnFileLoadproject(); + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + afx_msg void OnFilePointfile(); + afx_msg void OnFilePrint(); + afx_msg void OnFilePrintPreview(); + afx_msg void OnFileSave(); + afx_msg void OnFileSaveas(); + afx_msg void OnFileSaveCopy(); + afx_msg void OnViewShowModels(); + afx_msg void OnView100(); + afx_msg void OnViewCenter(); + afx_msg void OnViewConsole(); + afx_msg void OnViewDownfloor(); + afx_msg void OnViewEntity(); + afx_msg void OnViewMediaBrowser(); + afx_msg void OnViewFront(); + afx_msg void OnViewShowblocks(); + afx_msg void OnViewShowclip(); + afx_msg void OnViewShowTriggers(); + afx_msg void OnViewShowcoordinates(); + afx_msg void OnViewShowent(); + afx_msg void OnViewShowlights(); + afx_msg void OnViewShownames(); + afx_msg void OnViewShowpath(); + afx_msg void OnViewShowCombatNodes(); + afx_msg void OnViewShowwater(); + afx_msg void OnViewShowworld(); + afx_msg void OnViewTexture(); + afx_msg void OnViewUpfloor(); + afx_msg void OnViewXy(); + afx_msg void OnViewZ100(); + afx_msg void OnViewZoomin(); + afx_msg void OnViewZoomout(); + afx_msg void OnViewZzoomin(); + afx_msg void OnViewZzoomout(); + afx_msg void OnViewSide(); + afx_msg void OnTexturesShowinuse(); + afx_msg void OnTexturesInspector(); + afx_msg void OnMiscFindbrush(); + afx_msg void OnMiscGamma(); + afx_msg void OnMiscNextleakspot(); + afx_msg void OnMiscPreviousleakspot(); + afx_msg void OnMiscPrintxy(); + afx_msg void OnMiscSelectentitycolor(); + afx_msg void OnMiscFindOrReplaceEntity(); + afx_msg void OnMiscFindNextEntity(); + afx_msg void OnMiscSetViewPos(); + afx_msg void OnTexturebk(); + afx_msg void OnColorsMajor(); + afx_msg void OnColorsMinor(); + afx_msg void OnColorsXybk(); + afx_msg void OnBrush3sided(); + afx_msg void OnBrush4sided(); + afx_msg void OnBrush5sided(); + afx_msg void OnBrush6sided(); + afx_msg void OnBrush7sided(); + afx_msg void OnBrush8sided(); + afx_msg void OnBrush9sided(); + afx_msg void OnBrushArbitrarysided(); + afx_msg void OnBrushFlipx(); + afx_msg void OnBrushFlipy(); + afx_msg void OnBrushFlipz(); + afx_msg void OnBrushRotatex(); + afx_msg void OnBrushRotatey(); + afx_msg void OnBrushRotatez(); + afx_msg void OnRegionOff(); + afx_msg void OnRegionSetbrush(); + afx_msg void OnRegionSetselection(); + afx_msg void OnRegionSettallbrush(); + afx_msg void OnRegionSetxy(); + afx_msg void OnSelectionArbitraryrotation(); + afx_msg void OnSelectionClone(); + afx_msg void OnSelectionConnect(); + afx_msg void OnSelectionCsgsubtract(); + afx_msg void OnSelectionCsgmerge(); + afx_msg void OnSelectionDelete(); + afx_msg void OnSelectionDeselect(); + afx_msg void OnSelectionDragedges(); + afx_msg void OnSelectionDragvertecies(); + afx_msg void OnSelectionCenterOrigin(); + afx_msg void OnSelectionMakehollow(); + afx_msg void OnSelectionSelectcompletetall(); + afx_msg void OnSelectionSelectinside(); + afx_msg void OnSelectionSelectpartialtall(); + afx_msg void OnSelectionSelecttouching(); + afx_msg void OnSelectionUngroupentity(); + afx_msg void OnSelectionWireFrameOn(); + afx_msg void OnSelectionWireFrameOff(); + afx_msg void OnSelectionVisibleOn(); + afx_msg void OnSelectionVisibleOff(); + afx_msg void OnAutocaulk(); + afx_msg void OnUpdateAutocaulk(CCmdUI* pCmdUI); + + afx_msg void OnTexturesPopup(); + afx_msg void OnSplinesPopup(); + afx_msg void OnSplinesEditPoints(); + afx_msg void OnSplinesAddPoints(); + afx_msg void OnSplinesDeletePoint(); + afx_msg void OnSplinesInsertPoint(); + afx_msg void OnPopupSelection(); + afx_msg void OnViewChange(); + afx_msg void OnViewCameraupdate(); + afx_msg void OnUpdateViewCameraupdate(CCmdUI* pCmdUI); + afx_msg void OnSizing(UINT fwSide, LPRECT pRect); + afx_msg void OnHelpAbout(); + afx_msg void OnViewClipper(); + afx_msg void OnCameraAngledown(); + afx_msg void OnCameraAngleup(); + afx_msg void OnCameraBack(); + afx_msg void OnCameraDown(); + afx_msg void OnCameraForward(); + afx_msg void OnCameraLeft(); + afx_msg void OnCameraRight(); + afx_msg void OnCameraStrafeleft(); + afx_msg void OnCameraStraferight(); + afx_msg void OnCameraUp(); + afx_msg void OnGridToggle(); + afx_msg void OnPrefs(); + afx_msg void OnToggleToolbar(); + afx_msg void OnToggleTextureBar(); + afx_msg void OnTogglecamera(); + afx_msg void OnToggleview(); + afx_msg void OnTogglez(); + afx_msg void OnToggleLock(); + afx_msg void OnEditMapinfo(); + afx_msg void OnEditEntityinfo(); + afx_msg void OnViewNextview(); + afx_msg void OnHelpCommandlist(); + afx_msg void OnFileNewproject(); + afx_msg void OnFlipClip(); + afx_msg void OnClipSelected(); + afx_msg void OnSplitSelected(); + afx_msg void OnToggleviewXz(); + afx_msg void OnToggleviewYz(); + afx_msg void OnColorsBrush(); + afx_msg void OnColorsClipper(); + afx_msg void OnColorsGridtext(); + afx_msg void OnColorsSelectedbrush(); + afx_msg void OnColorsGridblock(); + afx_msg void OnColorsViewname(); + afx_msg void OnColorSetoriginal(); + afx_msg void OnColorSetqer(); + afx_msg void OnColorSetblack(); + afx_msg void OnColorSetSuperMal(); + afx_msg void OnColorSetMax(); + afx_msg void OnSnaptogrid(); + afx_msg void OnSelectScale(); + afx_msg void OnSelectMouserotate(); + afx_msg void OnEditCopybrush(); + afx_msg void OnEditPastebrush(); + afx_msg void OnEditUndo(); + afx_msg void OnEditRedo(); + afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI); + afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI); + afx_msg void OnSelectionInvert(); + afx_msg void OnSelectionTextureDec(); + afx_msg void OnSelectionTextureFit(); + afx_msg void OnSelectionTextureInc(); + afx_msg void OnSelectionTextureRotateclock(); + afx_msg void OnSelectionTextureRotatecounter(); + afx_msg void OnSelectionTextureScaledown(); + afx_msg void OnSelectionTextureScaleup(); + afx_msg void OnSelectionTextureShiftdown(); + afx_msg void OnSelectionTextureShiftleft(); + afx_msg void OnSelectionTextureShiftright(); + afx_msg void OnSelectionTextureShiftup(); + afx_msg void OnGridNext(); + afx_msg void OnGridPrev(); + afx_msg void OnSelectionTextureScaleLeft(); + afx_msg void OnSelectionTextureScaleRight(); + afx_msg void OnTextureReplaceall(); + afx_msg void OnScalelockx(); + afx_msg void OnScalelocky(); + afx_msg void OnScalelockz(); + afx_msg void OnSelectMousescale(); + afx_msg void OnViewCubicclipping(); + afx_msg void OnFileImport(); + afx_msg void OnFileProjectsettings(); + afx_msg void OnUpdateFileImport(CCmdUI* pCmdUI); + afx_msg void OnViewCubein(); + afx_msg void OnViewCubeout(); + afx_msg void OnFileSaveregion(); + afx_msg void OnUpdateFileSaveregion(CCmdUI* pCmdUI); + afx_msg void OnSelectionMovedown(); + afx_msg void OnSelectionMoveup(); + afx_msg void OnToolbarMain(); + afx_msg void OnToolbarTexture(); + afx_msg void OnSelectionPrint(); + afx_msg void OnSelectionTogglesizepaint(); + afx_msg void OnBrushMakecone(); + afx_msg void OnTexturesLoad(); + afx_msg void OnToggleRotatelock(); + afx_msg void OnCurveBevel(); + afx_msg void OnCurveIncreaseVert(); + afx_msg void OnCurveDecreaseVert(); + afx_msg void OnCurveIncreaseHorz(); + afx_msg void OnCurveDecreaseHorz(); + afx_msg void OnCurveCylinder(); + afx_msg void OnCurveEighthsphere(); + afx_msg void OnCurveEndcap(); + afx_msg void OnCurveHemisphere(); + afx_msg void OnCurveInvertcurve(); + afx_msg void OnCurveQuarter(); + afx_msg void OnCurveSphere(); + afx_msg void OnFileImportmap(); + afx_msg void OnFileExportmap(); + afx_msg void OnEditLoadprefab(); + afx_msg void OnViewShowcurves(); + afx_msg void OnSelectionSelectNudgedown(); + afx_msg void OnSelectionSelectNudgeleft(); + afx_msg void OnSelectionSelectNudgeright(); + afx_msg void OnSelectionSelectNudgeup(); + afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnTexturesLoadlist(); + afx_msg void OnDontselectcurve(); + afx_msg void OnDynamicLighting(); + afx_msg void OnCurveSimplepatchmesh(); + afx_msg void OnPatchToggleBox(); + afx_msg void OnPatchWireframe(); + afx_msg void OnCurvePatchcone(); + afx_msg void OnCurvePatchtube(); + afx_msg void OnPatchWeld(); + afx_msg void OnCurvePatchbevel(); + afx_msg void OnCurvePatchendcap(); + afx_msg void OnCurvePatchinvertedbevel(); + afx_msg void OnCurvePatchinvertedendcap(); + afx_msg void OnPatchDrilldown(); + afx_msg void OnCurveInsertcolumn(); + afx_msg void OnCurveInsertrow(); + afx_msg void OnCurveDeletecolumn(); + afx_msg void OnCurveDeleterow(); + afx_msg void OnCurveInsertAddcolumn(); + afx_msg void OnCurveInsertAddrow(); + afx_msg void OnCurveInsertInsertcolumn(); + afx_msg void OnCurveInsertInsertrow(); + afx_msg void OnCurveNegative(); + afx_msg void OnCurveNegativeTextureX(); + afx_msg void OnCurveNegativeTextureY(); + afx_msg void OnCurveDeleteFirstcolumn(); + afx_msg void OnCurveDeleteFirstrow(); + afx_msg void OnCurveDeleteLastcolumn(); + afx_msg void OnCurveDeleteLastrow(); + afx_msg void OnPatchBend(); + afx_msg void OnPatchInsdel(); + afx_msg void OnPatchEnter(); + afx_msg void OnPatchTab(); + afx_msg void OnCurvePatchdensetube(); + afx_msg void OnCurvePatchverydensetube(); + afx_msg void OnCurveCap(); + afx_msg void OnCurveCapInvertedbevel(); + afx_msg void OnCurveCapInvertedendcap(); + afx_msg void OnCurveRedisperseCols(); + afx_msg void OnCurveRedisperseRows(); + afx_msg void OnPatchNaturalize(); + afx_msg void OnPatchNaturalizeAlt(); + afx_msg void OnSnapToGrid(); + afx_msg void OnCurvePatchsquare(); + afx_msg void OnTexturesTexturewindowscale10(); + afx_msg void OnTexturesTexturewindowscale100(); + afx_msg void OnTexturesTexturewindowscale200(); + afx_msg void OnTexturesTexturewindowscale25(); + afx_msg void OnTexturesTexturewindowscale50(); + afx_msg void OnTexturesFlush(); + afx_msg void OnCurveOverlayClear(); + afx_msg void OnCurveOverlaySet(); + afx_msg void OnCurveThicken(); + afx_msg void OnCurveCyclecap(); + afx_msg void OnCurveCyclecapAlt(); + afx_msg void OnCurveMatrixTranspose(); + afx_msg void OnTexturesReloadshaders(); + afx_msg void OnShowEntities(); + afx_msg void OnViewEntitiesasBoundingbox(); + afx_msg void OnViewEntitiesasSelectedskinned(); + afx_msg void OnViewEntitiesasSelectedwireframe(); + afx_msg void OnViewEntitiesasSkinned(); + afx_msg void OnViewEntitiesasSkinnedandboxed(); + afx_msg void OnViewEntitiesasWireframe(); + afx_msg void OnViewShowhint(); + afx_msg void OnUpdateTexturesShowinuse(CCmdUI* pCmdUI); + afx_msg void OnTexturesShowall(); + afx_msg void OnTexturesHideall(); + afx_msg void OnPatchInspector(); + afx_msg void OnViewOpengllighting(); + afx_msg void OnSelectAll(); + afx_msg void OnViewShowcaulk(); + afx_msg void OnCurveFreeze(); + afx_msg void OnCurveUnFreeze(); + afx_msg void OnCurveUnFreezeAll(); + afx_msg void OnSelectReselect(); + afx_msg void OnViewShowangles(); + afx_msg void OnEditSaveprefab(); + afx_msg void OnCurveMoreendcapsbevelsSquarebevel(); + afx_msg void OnCurveMoreendcapsbevelsSquareendcap(); + afx_msg void OnBrushPrimitivesSphere(); + afx_msg void OnViewCrosshair(); + afx_msg void OnViewHideshowHideselected(); + afx_msg void OnViewHideshowHideNotselected(); + afx_msg void OnViewHideshowShowhidden(); + afx_msg void OnTexturesShadersShow(); + afx_msg void OnTexturesFlushUnused(); + afx_msg void OnViewGroups(); + afx_msg void OnDropGroupAddtoWorld(); + afx_msg void OnDropGroupName(); + afx_msg void OnDropGroupNewgroup(); + afx_msg void OnDropGroupRemove(); + afx_msg void OnProjectedLight(); + afx_msg void OnShowLighttextures(); + afx_msg void OnShowLightvolumes(); + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnSplinesMode(); + afx_msg void OnSplinesLoad(); + afx_msg void OnSplinesSave(); + afx_msg void OnSplinesEdit(); + afx_msg void OnSplineTest(); + afx_msg void OnSplinesTarget(); + afx_msg void OnSplinesTargetPoints(); + afx_msg void OnSplinesCameraPoints(); + afx_msg void OnPopupNewcameraInterpolated(); + afx_msg void OnPopupNewcameraSpline(); + afx_msg void OnPopupNewcameraFixed(); + afx_msg void OnSelectionMoveonly(); + afx_msg void OnSelectBrushesOnly(); + afx_msg void OnSelectByBoundingBrush(); + afx_msg void OnSelectBrushlight(); + afx_msg void OnSelectionCombine(); + afx_msg void OnPatchCombine(); + afx_msg void OnShowDoom(); + afx_msg void OnViewRendermode(); + afx_msg void OnViewRebuildrenderdata(); + afx_msg void OnViewRealtimerebuild(); + afx_msg void OnViewRenderentityoutlines(); + afx_msg void OnViewMaterialanimation(); + afx_msg void OnAxialTextureByWidth(); + afx_msg void OnAxialTextureByHeight(); + afx_msg void OnAxialTextureArbitrary(); + afx_msg void OnSelectionExportToobj(); + afx_msg void OnSelectionExportToCM(); + afx_msg void OnViewRenderselection(); + afx_msg void OnSelectNomodels(); + afx_msg void OnViewShowShowvisportals(); + afx_msg void OnViewShowNoDraw(); + afx_msg void OnViewRendersound(); + afx_msg void OnSoundShowsoundvolumes(); + afx_msg void OnSoundShowselectedsoundvolumes(); + afx_msg void OnNurbEditor(); + afx_msg void OnSelectCompleteEntity(); + afx_msg void OnGenerateMaterialsList(); + afx_msg void OnMru(unsigned int nID); + afx_msg void OnViewNearest(unsigned int nID); + afx_msg void OnTextureWad(unsigned int nID); + afx_msg void OnBspCommand(unsigned int nID); + afx_msg void OnGrid1(unsigned int nID); + afx_msg void OnDisplayChange(WPARAM wp, LPARAM lp); + afx_msg void OnSelectAlltargets(); + + //}}AFX_MSG + void CheckTextureScale(int id); + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__330BBF0A_731C_11D1_B539_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/MapInfo.cpp b/tools/radiant/MapInfo.cpp new file mode 100644 index 000000000..b3082042b --- /dev/null +++ b/tools/radiant/MapInfo.cpp @@ -0,0 +1,111 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "MapInfo.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMapInfo dialog + + +CMapInfo::CMapInfo(CWnd* pParent /*=NULL*/) + : CDialog(CMapInfo::IDD, pParent) +{ + //{{AFX_DATA_INIT(CMapInfo) + m_nNet = 0; + m_nTotalBrushes = 0; + m_nTotalEntities = 0; + //}}AFX_DATA_INIT +} + + +void CMapInfo::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CMapInfo) + DDX_Control(pDX, IDC_LIST_ENTITIES, m_lstEntity); + DDX_Text(pDX, IDC_EDIT_NET, m_nNet); + DDX_Text(pDX, IDC_EDIT_TOTALBRUSHES, m_nTotalBrushes); + DDX_Text(pDX, IDC_EDIT_TOTALENTITIES, m_nTotalEntities); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CMapInfo, CDialog) + //{{AFX_MSG_MAP(CMapInfo) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMapInfo message handlers + +BOOL CMapInfo::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_nTotalBrushes = 0; + m_nTotalEntities = 0; + m_nNet = 0; + for (brush_t* pBrush=active_brushes.next ; pBrush != &active_brushes ; pBrush=pBrush->next) + { + m_nTotalBrushes++; + if (pBrush->owner == world_entity) + m_nNet++; + } + + + CMapStringToPtr mapEntity; + + int nValue = 0; + for (entity_t* pEntity=entities.next ; pEntity != &entities ; pEntity=pEntity->next) + { + m_nTotalEntities++; + nValue = 0; + mapEntity.Lookup(pEntity->eclass->name, reinterpret_cast(nValue)); + nValue++ ; + mapEntity.SetAt(pEntity->eclass->name, reinterpret_cast(nValue)); + } + + m_lstEntity.ResetContent(); + m_lstEntity.SetTabStops(96); + CString strKey; + POSITION pos = mapEntity.GetStartPosition(); + while (pos) + { + mapEntity.GetNextAssoc(pos, strKey, reinterpret_cast(nValue)); + CString strList; + strList.Format("%s\t%i", strKey, nValue); + m_lstEntity.AddString(strList); + } + + UpdateData(FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/tools/radiant/MapInfo.h b/tools/radiant/MapInfo.h new file mode 100644 index 000000000..be6665c0f --- /dev/null +++ b/tools/radiant/MapInfo.h @@ -0,0 +1,67 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_MAPINFO_H__C241B9A2_819F_11D1_B548_00AA00A410FC__INCLUDED_) +#define AFX_MAPINFO_H__C241B9A2_819F_11D1_B548_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// MapInfo.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CMapInfo dialog + +class CMapInfo : public CDialog +{ +// Construction +public: + CMapInfo(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CMapInfo) + enum { IDD = IDD_DLG_MAPINFO }; + CListBox m_lstEntity; + int m_nNet; + int m_nTotalBrushes; + int m_nTotalEntities; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMapInfo) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CMapInfo) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAPINFO_H__C241B9A2_819F_11D1_B548_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/MediaPreviewDlg.cpp b/tools/radiant/MediaPreviewDlg.cpp new file mode 100644 index 000000000..a303a08d4 --- /dev/null +++ b/tools/radiant/MediaPreviewDlg.cpp @@ -0,0 +1,172 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "mediapreviewdlg.h" + + +// CMediaPreviewDlg dialog + +IMPLEMENT_DYNAMIC(CMediaPreviewDlg, CDialog) +CMediaPreviewDlg::CMediaPreviewDlg(CWnd* pParent /*=NULL*/) + : CDialog(CMediaPreviewDlg::IDD, pParent) +{ + mode = MATERIALS; + media = ""; +} + +void CMediaPreviewDlg::SetMedia(const char *_media) { + media = _media; + Refresh(); +} + +void CMediaPreviewDlg::Refresh() { + if (mode == GUIS) { + const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview"); + mat->SetGui( media ); + drawMaterial.setMedia("guisurfs/guipreview"); + drawMaterial.setScale( 4.4f ); + } else { + drawMaterial.setMedia(media); + drawMaterial.setScale( 1.0f ); + } + wndPreview.setDrawable(&drawMaterial); + wndPreview.Invalidate(); + wndPreview.RedrawWindow(); + RedrawWindow(); +} + +CMediaPreviewDlg::~CMediaPreviewDlg() +{ +} + +void CMediaPreviewDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_PREVIEW, wndPreview); +} + + +BEGIN_MESSAGE_MAP(CMediaPreviewDlg, CDialog) + ON_WM_SIZE() + ON_WM_DESTROY() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MOUSEMOVE() +END_MESSAGE_MAP() + + +// CMediaPreviewDlg message handlers + +BOOL CMediaPreviewDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + wndPreview.setDrawable(&testDrawable); + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("Radiant::EditPreviewWindow", &rct, &lSize)) { + SetWindowPos(NULL, rct.left, rct.top, rct.Width(), rct.Height(), SWP_SHOWWINDOW); + } + + GetClientRect(rct); + int h = (mode == GUIS) ? (rct.Width() - 8) / 1.333333f : rct.Height() - 8; + wndPreview.SetWindowPos(NULL, 4, 4, rct.Width() - 8, h, SWP_SHOWWINDOW); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CMediaPreviewDlg::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + if (wndPreview.GetSafeHwnd() == NULL) { + return; + } + CRect rect; + GetClientRect(rect); + //int h = (mode == GUIS) ? (rect.Width() - 8) / 1.333333f : rect.Height() - 8; + int h = rect.Height() - 8; + wndPreview.SetWindowPos(NULL, 4, 4, rect.Width() - 8, h, SWP_SHOWWINDOW); +} + +void CMediaPreviewDlg::OnDestroy() +{ + if (GetSafeHwnd()) { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::EditPreviewWindow", &rct, sizeof(rct)); + } + + CDialog::OnDestroy(); +} + +void CMediaPreviewDlg::OnLButtonDown(UINT nFlags, CPoint point) +{ + if (mode == GUIS) { + idUserInterface *gui = uiManager->FindGui( media ); + if (gui) { + sysEvent_t ev; + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_KEY; + ev.evValue = K_MOUSE1; + ev.evValue2 = 1; + gui->HandleEvent(&ev,0); + } + } + CDialog::OnLButtonDown(nFlags, point); +} + +void CMediaPreviewDlg::OnLButtonUp(UINT nFlags, CPoint point) +{ + if (mode == GUIS) { + idUserInterface *gui = uiManager->FindGui( media ); + if (gui) { + sysEvent_t ev; + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_KEY; + ev.evValue = K_MOUSE1; + ev.evValue2 = 0; + gui->HandleEvent(&ev,0); + } + } + CDialog::OnLButtonUp(nFlags, point); +} + +void CMediaPreviewDlg::OnMouseMove(UINT nFlags, CPoint point) +{ + if (mode == GUIS) { + idUserInterface *gui = uiManager->FindGui( media ); + if (gui) { + CRect rct; + wndPreview.GetClientRect(rct); + sysEvent_t ev; + memset( &ev, 0, sizeof( ev ) ); + ev.evType = SE_MOUSE; + ev.evValue = (point.x / rct.Width()) * 640.0f; + ev.evValue2 = (point.y / rct.Height()) * 480.0f; + gui->HandleEvent(&ev, 0); + } + } + CDialog::OnMouseMove(nFlags, point); +} diff --git a/tools/radiant/MediaPreviewDlg.h b/tools/radiant/MediaPreviewDlg.h new file mode 100644 index 000000000..41815bf42 --- /dev/null +++ b/tools/radiant/MediaPreviewDlg.h @@ -0,0 +1,60 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + + +// CMediaPreviewDlg dialog + +class CMediaPreviewDlg : public CDialog +{ + DECLARE_DYNAMIC(CMediaPreviewDlg) + +public: + enum { MATERIALS, GUIS }; + CMediaPreviewDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CMediaPreviewDlg(); + + void SetMode(int _mode) { + mode = _mode; + } + + void SetMedia(const char *_media); + void Refresh(); + +// Dialog Data + enum { IDD = IDD_DIALOG_EDITPREVIEW }; + +protected: + idGLDrawable testDrawable; + idGLDrawableMaterial drawMaterial; + idGLWidget wndPreview; + int mode; + idStr media; + + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnDestroy(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); +}; diff --git a/tools/radiant/NewProjDlg.cpp b/tools/radiant/NewProjDlg.cpp new file mode 100644 index 000000000..0732c0b28 --- /dev/null +++ b/tools/radiant/NewProjDlg.cpp @@ -0,0 +1,62 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "NewProjDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CNewProjDlg dialog + + +CNewProjDlg::CNewProjDlg(CWnd* pParent /*=NULL*/) + : CDialog(CNewProjDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CNewProjDlg) + m_strName = _T(""); + //}}AFX_DATA_INIT +} + + +void CNewProjDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CNewProjDlg) + DDX_Text(pDX, IDC_EDIT_NAME, m_strName); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CNewProjDlg, CDialog) + //{{AFX_MSG_MAP(CNewProjDlg) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CNewProjDlg message handlers diff --git a/tools/radiant/NewProjDlg.h b/tools/radiant/NewProjDlg.h new file mode 100644 index 000000000..088eacbab --- /dev/null +++ b/tools/radiant/NewProjDlg.h @@ -0,0 +1,64 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_NEWPROJDLG_H__1E2527A2_8447_11D1_B548_00AA00A410FC__INCLUDED_) +#define AFX_NEWPROJDLG_H__1E2527A2_8447_11D1_B548_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// NewProjDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CNewProjDlg dialog + +class CNewProjDlg : public CDialog +{ +// Construction +public: + CNewProjDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CNewProjDlg) + enum { IDD = IDD_DLG_NEWPROJECT }; + CString m_strName; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CNewProjDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CNewProjDlg) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_NEWPROJDLG_H__1E2527A2_8447_11D1_B548_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/NewTexWnd.cpp b/tools/radiant/NewTexWnd.cpp new file mode 100644 index 000000000..3456a7440 --- /dev/null +++ b/tools/radiant/NewTexWnd.cpp @@ -0,0 +1,913 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "NewTexWnd.h" +#include "io.h" + +#include "../../renderer/tr_local.h" + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool Sys_KeyDown( int key ) { + return ( ( ::GetAsyncKeyState( key ) & 0x8000 ) != 0 ); +} + +// CNewTexWnd +IMPLEMENT_DYNCREATE(CNewTexWnd, CWnd); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CNewTexWnd::CNewTexWnd() { + m_bNeedRange = true; + hglrcTexture = NULL; + hdcTexture = NULL; + cursor.x = cursor.y = 0; + origin.x = origin.y = 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CNewTexWnd::~CNewTexWnd() { +} + +BEGIN_MESSAGE_MAP(CNewTexWnd, CWnd) +//{{AFX_MSG_MAP(CNewTexWnd) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_PARENTNOTIFY() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_WM_PAINT() + ON_WM_VSCROLL() + ON_WM_LBUTTONDOWN() + ON_WM_MBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONUP() + ON_WM_RBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_MOUSEWHEEL() + //}}AFX_MSG_MAP + ON_WM_SETFOCUS() +END_MESSAGE_MAP() +// +// ======================================================================================================================= +// CNewTexWnd message handlers +// ======================================================================================================================= +// +BOOL CNewTexWnd::PreCreateWindow(CREATESTRUCT &cs) { + WNDCLASS wc; + HINSTANCE hInstance = AfxGetInstanceHandle(); + if (::GetClassInfo(hInstance, TEXTURE_WINDOW_CLASS, &wc) == FALSE) { + // Register a new class + memset(&wc, 0, sizeof(wc)); + wc.style = CS_NOCLOSE | CS_PARENTDC; // | CS_OWNDC; + wc.lpszClassName = TEXTURE_WINDOW_CLASS; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpfnWndProc = ::DefWindowProc; + if (AfxRegisterClass(&wc) == FALSE) { + Error("CNewTexWnd RegisterClass: failed"); + } + } + + cs.lpszClass = TEXTURE_WINDOW_CLASS; + cs.lpszName = "TEX"; + if (cs.style != QE3_CHILDSTYLE && cs.style != QE3_STYLE) { + cs.style = QE3_SPLITTER_STYLE; + } + + return CWnd::PreCreateWindow(cs); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int CNewTexWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CWnd::OnCreate(lpCreateStruct) == -1) { + return -1; + } + + ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); + m_bNeedRange = true; + + hdcTexture = GetDC(); + QEW_SetupPixelFormat(hdcTexture->m_hDC, false); + + EnableToolTips(TRUE); + EnableTrackingToolTips(TRUE); + + return 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnSize(UINT nType, int cx, int cy) { + CWnd::OnSize(nType, cx, cy); + GetClientRect(rectClient); + m_bNeedRange = true; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnParentNotify(UINT message, LPARAM lParam) { + CWnd::OnParentNotify(message, lParam); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::UpdatePrefs() { + ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); + m_bNeedRange = true; + Invalidate(); + UpdateWindow(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +const idMaterial *CNewTexWnd::NextPos() { + const idMaterial *mat = NULL; + while (1) { + if (currentIndex >= declManager->GetNumDecls( DECL_MATERIAL )) { + return NULL; + } + + mat = declManager->MaterialByIndex(currentIndex, false); + + currentIndex++; + + //if (mat->getName()[0] == '(') { // fake color texture + // continue; + //} + + if ( !mat->IsValid() ) { + continue; + } + + if (!mat->TestMaterialFlag(MF_EDITOR_VISIBLE)) { + continue; + } + break; + } + + // ensure it is uploaded + declManager->FindMaterial(mat->GetName()); + + int width = mat->GetEditorImage()->uploadWidth * ((float)g_PrefsDlg.m_nTextureScale / 100); + int height = mat->GetEditorImage()->uploadHeight * ((float)g_PrefsDlg.m_nTextureScale / 100); + + if (current.x + width > rectClient.Width() - 8 && currentRow) { + // go to the next row unless the texture is the first on the row + current.x = 8; + current.y -= currentRow + FONT_HEIGHT + 4; + currentRow = 0; + } + + draw = current; + + // Is our texture larger than the row? If so, grow the row height to match it + if (currentRow < height) { + currentRow = height; + } + + // never go less than 64, or the names get all crunched up + current.x += width < 64 ? 64 : width; + current.x += 8; + return mat; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnPaint() { + + CPaintDC dc(this); // device context for painting + + int nOld = g_qeglobals.d_texturewin.m_nTotalHeight; + + //hdcTexture = GetDC(); + if (!qwglMakeCurrent(dc.GetSafeHdc(), win32.hGLRC)) { + common->Printf("ERROR: wglMakeCurrent failed..\n "); + } + else { + const char *name; + qglClearColor + ( + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0], + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1], + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2], + 0 + ); + qglViewport(0, 0, rectClient.Width(), rectClient.Height()); + qglScissor(0, 0, rectClient.Width(), rectClient.Height()); + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_BLEND); + qglOrtho(0, rectClient.Width(), origin.y - rectClient.Height(), origin.y, -100, 100); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // init stuff + current.x = 8; + current.y = -8; + currentRow = 0; + currentIndex = 0; + while (1) { + const idMaterial *mat = NextPos(); + if (mat == NULL) { + break; + } + + int width = mat->GetEditorImage()->uploadWidth * ((float)g_PrefsDlg.m_nTextureScale / 100); + int height = mat->GetEditorImage()->uploadHeight * ((float)g_PrefsDlg.m_nTextureScale / 100); + + // Is this texture visible? + if ((draw.y - height - FONT_HEIGHT < origin.y) && (draw.y > origin.y - rectClient.Height())) { + // if in use, draw a background + qglLineWidth(1); + qglColor3f(1, 1, 1); + globalImages->BindNull(); + qglBegin(GL_LINE_LOOP); + qglVertex2f(draw.x - 1, draw.y + 1 - FONT_HEIGHT); + qglVertex2f(draw.x - 1, draw.y - height - 1 - FONT_HEIGHT); + qglVertex2f(draw.x + 1 + width, draw.y - height - 1 - FONT_HEIGHT); + qglVertex2f(draw.x + 1 + width, draw.y + 1 - FONT_HEIGHT); + qglEnd(); + + // Draw the texture + float fScale = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? ((float)g_PrefsDlg.m_nTextureScale / 100) : 1.0; + + mat->GetEditorImage()->Bind(); + QE_CheckOpenGLForErrors(); + qglColor3f(1, 1, 1); + qglBegin(GL_QUADS); + qglTexCoord2f(0, 0); + qglVertex2f(draw.x, draw.y - FONT_HEIGHT); + qglTexCoord2f(1, 0); + qglVertex2f(draw.x + width, draw.y - FONT_HEIGHT); + qglTexCoord2f(1, 1); + qglVertex2f(draw.x + width, draw.y - FONT_HEIGHT - height); + qglTexCoord2f(0, 1); + qglVertex2f(draw.x, draw.y - FONT_HEIGHT - height); + qglEnd(); + + // draw the selection border + if ( !idStr::Icmp(g_qeglobals.d_texturewin.texdef.name, mat->GetName()) ) { + qglLineWidth(3); + qglColor3f(1, 0, 0); + globalImages->BindNull(); + + qglBegin(GL_LINE_LOOP); + qglVertex2f(draw.x - 4, draw.y - FONT_HEIGHT + 4); + qglVertex2f(draw.x - 4, draw.y - FONT_HEIGHT - height - 4); + qglVertex2f(draw.x + 4 + width, draw.y - FONT_HEIGHT - height - 4); + qglVertex2f(draw.x + 4 + width, draw.y - FONT_HEIGHT + 4); + qglEnd(); + + qglLineWidth(1); + } + + // draw the texture name + globalImages->BindNull(); + qglColor3f(1, 1, 1); + qglRasterPos2f(draw.x, draw.y - FONT_HEIGHT + 2); + + // don't draw the directory name + for (name = mat->GetName(); *name && *name != '/' && *name != '\\'; name++) { + ; + } + + if (!*name) { + name = mat->GetName(); + } + else { + name++; + } + qglCallLists(strlen(name), GL_UNSIGNED_BYTE, name); + //qglCallLists(va("%s -- %d, %d" strlen(name), GL_UNSIGNED_BYTE, name); + } + } + + g_qeglobals.d_texturewin.m_nTotalHeight = abs(draw.y) + 100; + + // reset the current texture + globalImages->BindNull(); + qglFinish(); + qwglSwapBuffers(dc.GetSafeHdc()); + TRACE("Texture Paint\n"); + } + + if (g_PrefsDlg.m_bTextureScrollbar && (m_bNeedRange || g_qeglobals.d_texturewin.m_nTotalHeight != nOld)) { + m_bNeedRange = false; + SetScrollRange(SB_VERT, 0, g_qeglobals.d_texturewin.m_nTotalHeight, TRUE); + } + + //ReleaseDC(hdcTexture); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) { + CWnd::OnVScroll(nSBCode, nPos, pScrollBar); + + int n = GetScrollPos(SB_VERT); + switch (nSBCode) + { + case SB_LINEUP: { + n = (n - 15 > 0) ? n - 15 : 0; + break; + } + + case SB_LINEDOWN: { + n = (n + 15 < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + 15 : n; + break; + } + + case SB_PAGEUP: { + n = (n - g_qeglobals.d_texturewin.height > 0) ? n - g_qeglobals.d_texturewin.height : 0; + break; + } + + case SB_PAGEDOWN: { + n = (n + g_qeglobals.d_texturewin.height < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + g_qeglobals.d_texturewin.height : n; + break; + } + + case SB_THUMBPOSITION: { + n = nPos; + break; + } + + case SB_THUMBTRACK: { + n = nPos; + break; + } + } + + SetScrollPos(SB_VERT, n); + origin.y = -n; + Invalidate(); + UpdateWindow(); + + // Sys_UpdateWindows(W_TEXTURE); +} + +BOOL CNewTexWnd::DestroyWindow() { + ReleaseDC(hdcTexture); + return CWnd::DestroyWindow(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CNewTexWnd::Create +( + LPCTSTR lpszClassName, + LPCTSTR lpszWindowName, + DWORD dwStyle, + const RECT &rect, + CWnd *pParentWnd, + UINT nID, + CCreateContext *pContext +) { + BOOL ret = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); + if (ret) { + hdcTexture = GetDC(); + QEW_SetupPixelFormat(hdcTexture->m_hDC, false); + } + + return ret; +} + +const idMaterial *CNewTexWnd::getMaterialAtPoint(CPoint point) { + + // init stuff + int my = rectClient.Height() - 1 - point.y; + my += origin.y - rectClient.Height(); + + current.x = 8; + current.y = -8; + currentRow = 0; + currentIndex = 0; + + while (1) { + const idMaterial *mat = NextPos(); + if (mat == NULL) { + return NULL; + } + + int width = mat->GetEditorImage()->uploadWidth * ((float)g_PrefsDlg.m_nTextureScale / 100); + int height = mat->GetEditorImage()->uploadHeight * ((float)g_PrefsDlg.m_nTextureScale / 100); + //if (point.x > draw.x && point.x - draw.x < width && my < draw.y && my + draw.y < height + FONT_HEIGHT) { + if (point.x > draw.x && point.x - draw.x < width && my < draw.y && draw.y - my < height + FONT_HEIGHT) { + return mat; + } + + } + +} +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnLButtonDown(UINT nFlags, CPoint point) { + cursor = point; + + SetFocus(); + bool fitScale = Sys_KeyDown(VK_CONTROL); + bool edit = Sys_KeyDown(VK_SHIFT) && !fitScale; + + const idMaterial *mat = getMaterialAtPoint(point); + if (mat) { + Select_SetDefaultTexture(mat, fitScale, true); + } else { + Sys_Status("Did not select a texture\n", 0); + } + + // + UpdateSurfaceDialog(); + UpdatePatchInspector(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnMButtonDown(UINT nFlags, CPoint point) { + CWnd::OnMButtonDown(nFlags, point); + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnRButtonDown(UINT nFlags, CPoint point) { + cursor = point; + SetFocus(); +} + +/* + ===============================t======================================================================================== + ======================================================================================================================= + */ +void CNewTexWnd::OnLButtonUp(UINT nFlags, CPoint point) { + CWnd::OnLButtonUp(nFlags, point); + g_pParentWnd->SetFocus(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnMButtonUp(UINT nFlags, CPoint point) { + CWnd::OnMButtonUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnRButtonUp(UINT nFlags, CPoint point) { + CWnd::OnRButtonUp(nFlags, point); +} + +extern float fDiff(float f1, float f2); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::OnMouseMove(UINT nFlags, CPoint point) { + int scale = 1; + + if (Sys_KeyDown(VK_SHIFT)) { + scale = 4; + } + + // rbutton = drag texture origin + if (Sys_KeyDown(VK_RBUTTON)) { + if (point.y != cursor.y) { + if (Sys_KeyDown(VK_MENU)) { + long *px = &point.x; + long *px2 = &cursor.x; + + if (fDiff(point.y, cursor.y) > fDiff(point.x, cursor.x)) { + px = &point.y; + px2 = &cursor.y; + } + + if (*px > *px2) { + // zoom in + g_PrefsDlg.m_nTextureScale += 4; + if (g_PrefsDlg.m_nTextureScale > 500) { + g_PrefsDlg.m_nTextureScale = 500; + } + } + else if (*px < *px2) { + // zoom out + g_PrefsDlg.m_nTextureScale -= 4; + if (g_PrefsDlg.m_nTextureScale < 1) { + g_PrefsDlg.m_nTextureScale = 1; + } + } + + *px2 = *px; + CPoint screen = cursor; + ClientToScreen(&screen); + SetCursorPos(screen.x, screen.y); + //Sys_SetCursorPos(cursor.x, cursor.y); + InvalidateRect(NULL, false); + UpdateWindow(); + } + else if (point.y != cursor.y || point.x != cursor.x) { + origin.y += (point.y - cursor.y) * scale; + if (origin.y > 0) { + origin.y = 0; + } + + //Sys_SetCursorPos(cursor.x, cursor.y); + CPoint screen = cursor; + ClientToScreen(&screen); + SetCursorPos(screen.x, screen.y); + if (g_PrefsDlg.m_bTextureScrollbar) { + SetScrollPos(SB_VERT, abs(origin.y)); + } + + InvalidateRect(NULL, false); + UpdateWindow(); + } + } + + return; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CNewTexWnd::LoadMaterials() { +} + + +void Texture_SetTexture(texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, bool bSetSelection) { + + if (texdef->name[0] == '(') { + Sys_Status("Can't select an entity texture\n", 0); + return; + } + + g_qeglobals.d_texturewin.texdef = *texdef; + + // + // store the texture coordinates for new brush primitive mode be sure that all the + // callers are using the default 2x2 texture + // + if (g_qeglobals.m_bBrushPrimitMode) { + g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef; + } + + g_dlgFind.updateTextures(texdef->name); + + if (!g_dlgFind.isOpen() && bSetSelection) { + Select_SetTexture(texdef, brushprimit_texdef, bFitScale); + } + + g_Inspectors->texWnd.EnsureTextureIsVisible(texdef->name); + + if ( g_Inspectors->mediaDlg.IsWindowVisible() ) { + g_Inspectors->mediaDlg.SelectCurrentItem(true, g_qeglobals.d_texturewin.texdef.name, CDialogTextures::MATERIALS); + } + + g_qeglobals.d_texturewin.texdef = *texdef; + // store the texture coordinates for new brush primitive mode be sure that all the + // callers are using the default 2x2 texture + // + if (g_qeglobals.m_bBrushPrimitMode) { + g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef; + } + + + Sys_UpdateWindows(W_TEXTURE); + + +} + +const idMaterial *Texture_LoadLight(const char *name) { + return declManager->FindMaterial(name); +} + + +void Texture_ClearInuse(void) { +} + +void Texture_ShowAll(void) { + int count = declManager->GetNumDecls( DECL_MATERIAL ); + for (int i = 0; i < count; i++) { + const idMaterial *mat = declManager->MaterialByIndex(i, false); + if ( mat ) { + mat->SetMaterialFlag(MF_EDITOR_VISIBLE); + } + } + g_Inspectors->SetWindowText("Textures (all)"); + Sys_UpdateWindows(W_TEXTURE); +} + +void Texture_HideAll() { + int count = declManager->GetNumDecls( DECL_MATERIAL ); + for (int i = 0; i < count; i++) { + const idMaterial *mat = declManager->MaterialByIndex(i, false); + if ( mat ) { + mat->ClearMaterialFlag(MF_EDITOR_VISIBLE); + } + } + g_Inspectors->SetWindowText("Textures (all)"); + Sys_UpdateWindows(W_TEXTURE); +} + +const idMaterial *Texture_ForName(const char *name) { + const idMaterial *mat = declManager->FindMaterial(name); + if ( !mat ) { + mat = declManager->FindMaterial("_default"); + } else { + mat->SetMaterialFlag(MF_EDITOR_VISIBLE); + } + return mat; +} + +void Texture_ShowInuse(void) { + Texture_HideAll(); + + brush_t *b; + for (b = active_brushes.next; b != NULL && b != &active_brushes; b = b->next) { + if (b->pPatch) { + Texture_ForName(b->pPatch->d_texture->GetName()); + } else { + for (face_t *f = b->brush_faces; f; f = f->next) { + Texture_ForName(f->texdef.name); + } + } + } + + for (b = selected_brushes.next; b != NULL && b != &selected_brushes; b = b->next) { + if (b->pPatch) { + Texture_ForName(b->pPatch->d_texture->GetName()); + } else { + for (face_t *f = b->brush_faces; f; f = f->next) { + Texture_ForName(f->texdef.name); + } + } + } + + Sys_UpdateWindows(W_TEXTURE); + + g_Inspectors->SetWindowText("Textures (in use)"); +} + +void Texture_Cleanup(CStringList *pList) { +} + +int texture_mode = GL_LINEAR_MIPMAP_LINEAR; +bool texture_showinuse = true; + + +/* + ======================================================================================================================= + Texture_SetMode + ======================================================================================================================= + */ +void Texture_SetMode(int iMenu) { + int iMode; + HMENU hMenu; + bool texturing = true; + + hMenu = GetMenu(g_pParentWnd->GetSafeHwnd()); + + switch (iMenu) + { + case ID_VIEW_NEAREST: + iMode = GL_NEAREST; + break; + case ID_VIEW_NEARESTMIPMAP: + iMode = GL_NEAREST_MIPMAP_NEAREST; + break; + case ID_VIEW_LINEAR: + iMode = GL_NEAREST_MIPMAP_LINEAR; + break; + case ID_VIEW_BILINEAR: + iMode = GL_LINEAR; + break; + case ID_VIEW_BILINEARMIPMAP: + iMode = GL_LINEAR_MIPMAP_NEAREST; + break; + case ID_VIEW_TRILINEAR: + iMode = GL_LINEAR_MIPMAP_LINEAR; + break; + + case ID_TEXTURES_WIREFRAME: + iMode = 0; + texturing = false; + break; + + case ID_TEXTURES_FLATSHADE: + default: + iMode = 0; + texturing = false; + break; + } + + CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED); + + CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED); + + g_qeglobals.d_savedinfo.iTexMenu = iMenu; + texture_mode = iMode; + + if (!texturing && iMenu == ID_TEXTURES_WIREFRAME) { + g_pParentWnd->GetCamera()->Camera().draw_mode = cd_wire; + Map_BuildBrushData(); + Sys_UpdateWindows(W_ALL); + return; + } + else if (!texturing && iMenu == ID_TEXTURES_FLATSHADE) { + g_pParentWnd->GetCamera()->Camera().draw_mode = cd_solid; + Map_BuildBrushData(); + Sys_UpdateWindows(W_ALL); + return; + } + + if (g_pParentWnd->GetCamera()->Camera().draw_mode != cd_texture) { + g_pParentWnd->GetCamera()->Camera().draw_mode = cd_texture; + Map_BuildBrushData(); + } + + Sys_UpdateWindows(W_ALL); +} + + + +void CNewTexWnd::EnsureTextureIsVisible(const char *name) { + // scroll origin so the texture is completely on screen + // init stuff + current.x = 8; + current.y = -8; + currentRow = 0; + currentIndex = 0; + + while (1) { + const idMaterial *mat = NextPos(); + if (mat == NULL) { + break; + } + + int width = mat->GetEditorImage()->uploadWidth * ((float)g_PrefsDlg.m_nTextureScale / 100); + int height = mat->GetEditorImage()->uploadHeight * ((float)g_PrefsDlg.m_nTextureScale / 100); + + if ( !idStr::Icmp(name, mat->GetName()) ) { + if (current.y > origin.y) { + origin.y = current.y; + Sys_UpdateWindows(W_TEXTURE); + return; + } + + if (current.y - height - 2 * FONT_HEIGHT < origin.y - rectClient.Height()) { + origin.y = current.y - height - 2 * FONT_HEIGHT + rectClient.Height(); + Sys_UpdateWindows(W_TEXTURE); + return; + } + + return; + } + } + +} + + +BOOL CNewTexWnd::OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { + static char tip[1024]; + CPoint point; + GetCursorPos(&point); + const idMaterial *mat = getMaterialAtPoint(point); + + if (mat) { + TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; + strcpy(tip, mat->GetDescription()); + pTTT->lpszText = tip; + pTTT->hinst = NULL; + return(TRUE); + } + return(FALSE); +} + +int CNewTexWnd::OnToolHitTest(CPoint point, TOOLINFO * pTI) +{ + const idMaterial *mat = getMaterialAtPoint(point); + if (mat) { + return 0; + } + return -1; +} + +BOOL CNewTexWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + OnVScroll((zDelta >= 0) ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + return TRUE; +} + +BOOL CNewTexWnd::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_ESCAPE) { + g_pParentWnd->GetCamera()->SetFocus(); + Select_Deselect(); + return TRUE; + } + if (pMsg->wParam == VK_RIGHT || pMsg->wParam == VK_LEFT || pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN) { + g_pParentWnd->PostMessage(WM_KEYDOWN, pMsg->wParam); + return TRUE; + } + } + return CWnd::PreTranslateMessage(pMsg); +} + +void CNewTexWnd::OnSetFocus(CWnd* pOldWnd) +{ + CWnd::OnSetFocus(pOldWnd); + Invalidate(); + RedrawWindow(); +} diff --git a/tools/radiant/NewTexWnd.h b/tools/radiant/NewTexWnd.h new file mode 100644 index 000000000..175b14de6 --- /dev/null +++ b/tools/radiant/NewTexWnd.h @@ -0,0 +1,117 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(NEWTEXWND_H) +#define NEWTEXWND_H + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// TexWnd.h : header file +// +#include "../../renderer/tr_local.h" +//#include "texwnd.h" + +///////////////////////////////////////////////////////////////////////////// +// CTexWnd window + +class CNewTexWnd : public CWnd +{ + DECLARE_DYNCREATE(CNewTexWnd); +// Construction +public: + CNewTexWnd(); + void UpdateFilter(const char* pFilter); + void UpdatePrefs(); + void FocusEdit(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CNewTexWnd) + public: + virtual BOOL DestroyWindow(); + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + void EnsureTextureIsVisible(const char *name); + void LoadMaterials(); + virtual ~CNewTexWnd(); + BOOL OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ); + int CNewTexWnd::OnToolHitTest(CPoint point, TOOLINFO * pTI); + virtual BOOL PreTranslateMessage(MSG* pMsg); + +protected: + //CTexEdit m_wndFilter; + //CButton m_wndShaders; + bool m_bNeedRange; + HGLRC hglrcTexture; + CDC *hdcTexture; + CPoint cursor; + CPoint origin; + CPoint draw; + CPoint drawRow; + CPoint current; + CRect rectClient; + int currentRow; + int currentIndex; + idList materialList; + + // Generated message map functions +protected: + const idMaterial* NextPos(); + const idMaterial *getMaterialAtPoint(CPoint point); + void InitPos(); + //{{AFX_MSG(CNewTexWnd) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnParentNotify(UINT message, LPARAM lParam); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnPaint(); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + //}}AFX_MSG + afx_msg void OnShaderClick(); + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnSetFocus(CWnd* pOldWnd); +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(NEWTEXWND_H) diff --git a/tools/radiant/PARSE.CPP b/tools/radiant/PARSE.CPP new file mode 100644 index 000000000..7323d912d --- /dev/null +++ b/tools/radiant/PARSE.CPP @@ -0,0 +1,148 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +char token[MAXTOKEN]; +bool unget; +const char *script_p; +int scriptline; + +void StartTokenParsing (const char *data) +{ + scriptline = 1; + script_p = data; + unget = false; +} + +bool WINAPI GetToken (bool crossline) +{ + char *token_p; + + if (unget) // is a token allready waiting? + { + unget = false; + return true; + } + +// +// skip space +// +skipspace: + while (*script_p <= 32) + { + if (!*script_p) + { + if (!crossline) + common->Printf("Warning: Line %i is incomplete [01]\n",scriptline); + return false; + } + if (*script_p++ == '\n') + { + if (!crossline) + common->Printf("Warning: Line %i is incomplete [02]\n",scriptline); + scriptline++; + } + } + + if (script_p[0] == '/' && script_p[1] == '/') // comment field + { + if (!crossline) + common->Printf("Warning: Line %i is incomplete [03]\n",scriptline); + while (*script_p++ != '\n') + if (!*script_p) + { + if (!crossline) + common->Printf("Warning: Line %i is incomplete [04]\n",scriptline); + return false; + } + goto skipspace; + } + +// +// copy token +// + token_p = token; + + if (*script_p == '"') + { + script_p++; + //if (*script_p == '"') // handle double quotes i suspect they are put in by other editors cccasionally + // script_p++; + while ( *script_p != '"' ) + { + if (!*script_p) + Error ("EOF inside quoted token"); + *token_p++ = *script_p++; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i",scriptline); + } + script_p++; + //if (*script_p == '"') // handle double quotes i suspect they are put in by other editors cccasionally + // script_p++; + } + else while ( *script_p > 32 ) + { + *token_p++ = *script_p++; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i",scriptline); + } + + *token_p = 0; + + return true; +} + +void WINAPI UngetToken (void) +{ + unget = true; +} + + +/* +============== +TokenAvailable + +Returns true if there is another token on the line +============== +*/ +bool TokenAvailable (void) +{ + const char *search_p; + + search_p = script_p; + + while ( *search_p <= 32) + { + if (*search_p == '\n') + return false; + if (*search_p == 0) + return false; + search_p++; + } + + if (*search_p == ';') + return false; + + return true; +} + diff --git a/tools/radiant/PARSE.H b/tools/radiant/PARSE.H new file mode 100644 index 000000000..3f6fe3d8f --- /dev/null +++ b/tools/radiant/PARSE.H @@ -0,0 +1,30 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#define MAXTOKEN 1024 + +extern char token[MAXTOKEN]; +extern int scriptline; + +// NOTE: added WINAPI call syntax to export these for plugins in _QERScripLibTable +void StartTokenParsing (const char *data); +bool WINAPI GetToken (bool crossline); +void WINAPI UngetToken (void); +bool TokenAvailable (void); + diff --git a/tools/radiant/PMESH.CPP b/tools/radiant/PMESH.CPP new file mode 100644 index 000000000..6959e6f0c --- /dev/null +++ b/tools/radiant/PMESH.CPP @@ -0,0 +1,4452 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "DialogInfo.h" +#include "CapDialog.h" + +// externs +extern void MemFile_fprintf( CMemFile *pMemFile,const char *pText,... ); +extern face_t *Face_Alloc( void ); +void _Write3DMatrix( FILE *f,int y,int x,int z,float *m ); +void _Write3DMatrix( CMemFile *f,int y,int x,int z,float *m ); +extern void SamplePatch( float ctrl[3][3][5],int baseCol,int baseRow,int width,int horzSub,int vertSub,idDrawVert *outVerts,idDrawVert *drawVerts ); +patchMesh_t *Patch_GenerateGeneric( int width,int height,int orientation,const idVec3 &mins,const idVec3 &maxs ); + + + +patchMesh_t * MakeNewPatch( int width,int height ) { + patchMesh_t *pm = reinterpret_cast< patchMesh_t*>(Mem_ClearedAlloc(sizeof(patchMesh_t))); + pm->horzSubdivisions = DEFAULT_CURVE_SUBDIVISION; + pm->vertSubdivisions = DEFAULT_CURVE_SUBDIVISION; + pm->explicitSubdivisions = false; + pm->width = width; + pm->height = height; + pm->verts = reinterpret_cast< idDrawVert*>(Mem_ClearedAlloc(sizeof(idDrawVert) * width * height)); + //pm->ctrl = reinterpret_cast(Mem_ClearedAlloc(sizeof(idDrawVert) * width * height)); + //pm->ctrl = &pm->verts; + return pm; +} + + +void Patch_AdjustSize( patchMesh_t *p,int wadj,int hadj ) { + idDrawVert *newverts = reinterpret_cast< idDrawVert*>(Mem_ClearedAlloc(sizeof(idDrawVert) * (p->width + wadj) * (p->height + hadj))); + int copyWidth = (wadj < 0) ? p->width + wadj : p->width; + int copyHeight = (hadj < 0) ? p->height + hadj : p->height; + int copysize = copyWidth *copyHeight * sizeof(idDrawVert); + + for ( int i = 0; i < p->width; i++ ) { + for ( int j = 0; j < p->height; j++ ) { + newverts[j * (p->width + wadj) + i] = p->ctrl(i, j); + } + } + + p->width += wadj; + p->height += hadj; + Mem_Free(p->verts); + p->verts = newverts; +} + +// algorithm from Journal of graphics tools, 2(1):21-28, 1997 +bool RayIntersectsTri( const idVec3 &origin,const idVec3 &direction,const idVec3 &vert0,const idVec3 &vert1,const idVec3 &vert2,float &scale ) { + idVec3 edge1, edge2, tvec, pvec, qvec; + float det, inv_det; + scale = 0; + + /* find vectors for two edges sharing vert0 */ + edge1 = vert1 - vert0; + edge2 = vert2 - vert0; + + /* begin calculating determinant - also used to calculate U parameter */ + pvec.Cross(direction, edge2); + + /* if determinant is near zero, ray lies in plane of triangle */ + det = edge1 * pvec; + + if ( det > -VECTOR_EPSILON && det < VECTOR_EPSILON ) { + return false; + } + + inv_det = 1.0f / det; + + /* calculate distance from vert0 to ray origin */ + tvec = origin - vert0; + + /* calculate U parameter and test bounds */ + float u = (tvec *pvec) * inv_det; + if ( u < 0.0f || u> 1.0f ) { + return false; + } + + /* prepare to test V parameter */ + qvec.Cross(tvec, edge1); + + /* calculate V parameter and test bounds */ + float v = (direction *qvec) * inv_det; + if ( v < 0.0f || u + v> 1.0f ) { + return false; + } + + scale = tvec.Length(); + return true; +} + +bool Patch_Intersect( patchMesh_t *pm,idVec3 origin,idVec3 direction,float &scale ) { + int i, j; + //float scale; + idSurface_Patch cp (pm->width * 6, pm->height * 6); + + cp.SetSize(pm->width, pm->height); + for ( i = 0; i < pm->width; i++ ) { + for ( j = 0; j < pm->height; j++ ) { + (cp)[j * cp.GetWidth() + i].xyz = pm->ctrl(i, j).xyz; + (cp)[j * cp.GetWidth() + i].st = pm->ctrl(i, j).st; + } + } + + if ( pm->explicitSubdivisions ) { + cp.SubdivideExplicit(pm->horzSubdivisions, pm->vertSubdivisions, false); + } else { + cp.Subdivide(DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_LENGTH, false); + } + + if ( cp.RayIntersection(origin, direction, scale) ) { + return true; + } else { + return false; + } + + /* + int width = cp.GetWidth(); + int height = cp.GetHeight(); + for ( i = 0 ; i < width - 1; i++ ) { + for ( j = 0 ; j < height - 1; j++ ) { + // v1-v2-v3-v4 makes a quad + int v1, v2, v3, v4; + v1 = j * width + i; + v2 = v1 + 1; + v3 = v1 + width + 1; + v4 = v1 + width; + if (RayIntersectsTri(origin, direction, (cp)[v1].xyz, (cp)[v2].xyz, (cp)[v3].xyz)) { + return true; + } + if (RayIntersectsTri(origin, direction, (cp)[v3].xyz, (cp)[v4].xyz, (cp)[v1].xyz)) { + return true; + } + } + } + return false; + */ +} + +patchMesh_t * Patch_MakeNew( patchMesh_t *p,int newWidth,int newHeight ) { + patchMesh_t *newPatch = MakeNewPatch(newWidth, newHeight); + newPatch->d_texture = p->d_texture; + newPatch->horzSubdivisions = p->horzSubdivisions; + newPatch->vertSubdivisions = p->vertSubdivisions; + newPatch->explicitSubdivisions = p->explicitSubdivisions; + return newPatch; +} + +void Patch_Combine( patchMesh_t *p,patchMesh_t *p2,int sourceCol1,int sourceCol2,int sourceRow1,int sourceRow2,bool invert1,bool invert2 ) { + int i, j, out; + patchMesh_t *newPatch = NULL; + if ( sourceCol1 >= 0 ) { + // adding width + if ( sourceCol2 >= 0 ) { + // from width + newPatch = Patch_MakeNew(p, p->width + p2->width - 1, p->height); + int adj1 = 1; + int adj2 = 1; + int col1 = 0; + int col2 = 1; + if ( sourceCol1 != 0 ) { + adj1 = -1; + col1 = p->width - 1; + } + if ( sourceCol2 != 0 ) { + adj2 = -1; + col2 = p2->width - 2; + } + + out = 0; + for ( i = 0; i < p->width; i++, col1 += adj1 ) { + int in = (invert1) ? p->height - 1 : 0; + for ( j = 0; j < p->height; j++ ) { + newPatch->ctrl(out, j) = p->ctrl(col1, in); + in += (invert1) ? -1 : 1; + } + out++; + } + + for ( i = 1; i < p2->width; i++, col2 += adj2 ) { + int in = (invert2) ? p2->height - 1 : 0; + for ( j = 0; j < p2->height; j++ ) { + newPatch->ctrl(out, j) = p2->ctrl(col2, in); + in += (invert2) ? -1 : 1; + } + out++; + } + } else { + // from height + newPatch = Patch_MakeNew(p, p->width + p2->height - 1, p->height); + int adj1 = 1; + int adj2 = 1; + int col1 = 0; + int row2 = 1; + if ( sourceCol1 != 0 ) { + adj1 = -1; + col1 = p->width - 1; + } + if ( sourceRow2 != 0 ) { + adj2 = -1; + row2 = p2->height - 2; + } + + out = 0; + for ( i = 0; i < p->width; i++, col1 += adj1 ) { + int in = (invert1) ? p->height - 1 : 0; + for ( j = 0; j < p->height; j++ ) { + newPatch->ctrl(out, j) = p->ctrl(col1, in); + in += (invert1) ? -1 : 1; + } + out++; + } + + for ( i = 1; i < p2->height; i++, row2 += adj2 ) { + int in = (invert2) ? p2->width - 1 : 0; + for ( j = 0; j < p2->width; j++ ) { + newPatch->ctrl(out, j) = p2->ctrl(in, row2); + in += (invert2) ? -1 : 1; + } + out++; + } + } + } else { + // adding height + if ( sourceRow1 >= 0 ) { + // from height + newPatch = Patch_MakeNew(p, p->width, p->height + p2->height - 1); + int adj1 = 1; + int adj2 = 1; + int row1 = 0; + int row2 = 0; + if ( sourceRow1 != 0 ) { + adj1 = -1; + row1 = p->height - 1; + } + if ( sourceRow2 != 0 ) { + adj2 = -1; + row2 = p2->height - 2; + } + + out = 0; + for ( i = 0; i < p->height; i++, row1 += adj1 ) { + int in = (invert1) ? p->width - 1 : 0; + for ( j = 0; j < p->width; j++ ) { + newPatch->ctrl(j, out) = p->ctrl(in, row1); + in += (invert1) ? -1 : 1; + } + out++; + } + + for ( i = 1; i < p2->height; i++, row2 += adj2 ) { + int in = (invert2) ? p->width - 1 : 0; + for ( j = 0; j < p2->width; j++ ) { + newPatch->ctrl(j, out) = p2->ctrl(in, row2); + in += (invert1) ? -1 : 1; + } + out++; + } + } else { + // from width + newPatch = Patch_MakeNew(p, p->width, p->height + p2->width - 1); + int adj1 = 1; + int adj2 = 1; + int row1 = 0; + int col2 = 0; + if ( sourceRow1 != 0 ) { + adj1 = -1; + row1 = p->height - 1; + } + if ( sourceCol2 != 0 ) { + adj2 = -1; + col2 = p2->width - 2; + } + + out = 0; + for ( i = 0; i < p->height; i++, row1 += adj1 ) { + int in = (invert1) ? p->width - 1 : 0; + for ( j = 0; j < p->width; j++ ) { + newPatch->ctrl(j, out) = p->ctrl(in, row1); + in += (invert1) ? -1 : 1; + } + out++; + } + + for ( i = 1; i < p2->width; i++, col2 += adj2 ) { + int in = (invert2) ? p->height - 1 : 0; + for ( j = 0; j < p2->height; j++ ) { + newPatch->ctrl(j, out) = p2->ctrl(col2, in); + in += (invert1) ? -1 : 1; + } + out++; + } + } + } + if ( newPatch ) { + AddBrushForPatch(newPatch, true); + Brush_Free(p->pSymbiot, true); + Brush_Free(p2->pSymbiot, true); + Patch_Naturalize(newPatch, true, true); + } +} + +#define WELD_EPSILON 0.001f + +void Patch_Weld( patchMesh_t *p,patchMesh_t *p2 ) { + // check against all 4 edges of p2 + // could roll this up but left it out for some semblence of clarity + // + + if ( p->width == p2->width ) { + int row = 0; + int row2 = 0; + while ( 1 ) { + bool match = true; + + // need to see if any of the corners match then run down or up based + // on the match edges + int col1 = 0; + int col2 = 0; + int adj1 = 1; + int adj2 = 1; + if ( p->ctrl(0, row).xyz.Compare(p2->ctrl(0, row2).xyz, WELD_EPSILON) ) { + } else if ( p->ctrl(0, row).xyz.Compare(p2->ctrl(p2->width - 1, row2).xyz, WELD_EPSILON) ) { + col2 = p2->width - 1; + adj2 = -1; + } else if ( p->ctrl(p->width - 1, row).xyz.Compare(p2->ctrl(p2->width - 1, row2).xyz, WELD_EPSILON) ) { + col2 = p2->width - 1; + adj2 = -1; + col1 = p->width - 1; + adj1 = -1; + } else if ( p->ctrl(p->width - 1, row).xyz.Compare(p2->ctrl(0, row2).xyz, WELD_EPSILON) ) { + col1 = p->width - 1; + adj1 = -1; + } else { + adj1 = 0; + } + + if ( adj1 ) { + for ( int col = 0; col < p->width; col++, col2 += adj2, col1 += adj1 ) { + if ( !p->ctrl(col1, row).xyz.Compare(p2->ctrl(col2, row2).xyz, WELD_EPSILON) ) { + match = false; + break; + } + } + } else { + match = false; + } + + if ( match ) { + // have a match weld these edges + common->Printf("Welding row %i with row %i\n", row, row2); + row = (row == 0) ? p->height - 1 : 0; + Patch_Combine(p, p2, -1, -1, row, row2, (adj1 == -1), (adj2 == -1)); + return; + } else if ( row2 == 0 ) { + row2 = p2->height - 1; + } else if ( row == 0 ) { + row = p->height - 1; + row2 = 0; + } else { + break; + } + } + } + + if ( p->width == p2->height ) { + int row = 0; + int col2 = 0; + while ( 1 ) { + bool match = true; + + int col1 = 0; + int adj1 = 1; + int row2 = 0; + int adj2 = 1; + if ( p->ctrl(0, row).xyz.Compare(p2->ctrl(col2, 0).xyz, WELD_EPSILON) ) { + } else if ( p->ctrl(0, row).xyz.Compare(p2->ctrl(col2, p2->height - 1).xyz, WELD_EPSILON) ) { + row2 = p2->height - 1; + adj2 = -1; + } else if ( p->ctrl(p->width - 1, row).xyz.Compare(p2->ctrl(col2, p2->height - 1).xyz, WELD_EPSILON) ) { + row2 = p2->height - 1; + adj2 = -1; + col1 = p->width - 1; + adj1 = -1; + } else if ( p->ctrl(p->width - 1, row).xyz.Compare(p2->ctrl(col2, 0).xyz, WELD_EPSILON) ) { + col1 = p->width - 1; + adj1 = -1; + } else { + adj1 = 0; + } + + if ( adj1 ) { + for ( int col = 0; col < p->width; col++, col1 += adj1, row2 += adj2 ) { + if ( !p->ctrl(col1, row).xyz.Compare(p2->ctrl(col2, row2).xyz, WELD_EPSILON) ) { + match = false; + break; + } + } + } else { + match = false; + } + + if ( match ) { + // have a match weld these edges + common->Printf("Welding row %i with col %i\n", row, col2); + row = (row == 0) ? p->height - 1 : 0; + Patch_Combine(p, p2, -1, col2, row, -1, (adj1 == -1), (adj2 == -1)); + return; + } else if ( col2 == 0 ) { + col2 = p2->width - 1; + } else if ( row == 0 ) { + row = p->height - 1; + col2 = 0; + } else { + break; + } + } + } + + if ( p->height == p2->width ) { + int col = 0; + int row2 = 0; + while ( 1 ) { + bool match = true; + + + int row1 = 0; + int adj1 = 1; + int col2 = 0; + int adj2 = 1; + if ( p->ctrl(col, 0).xyz.Compare(p2->ctrl(0, row2).xyz, WELD_EPSILON) ) { + } else if ( p->ctrl(col, 0).xyz.Compare(p2->ctrl(p2->width - 1, row2).xyz, WELD_EPSILON) ) { + col2 = p2->width - 1; + adj2 = -1; + } else if ( p->ctrl(col, p->height - 1).xyz.Compare(p2->ctrl(p2->width - 1, row2).xyz, WELD_EPSILON) ) { + col2 = p2->width - 1; + adj2 = -1; + row1 = p2->height - 1; + adj2 = -1; + } else if ( p->ctrl(col, p->height - 1).xyz.Compare(p2->ctrl(0, row2).xyz, WELD_EPSILON) ) { + row1 = p2->height - 1; + adj2 = -1; + } else { + adj1 = 0; + } + + if ( adj1 ) { + for ( int row = 0; row < p->height; row++, row1 += adj1, col2 += adj2 ) { + if ( !p->ctrl(col, row1).xyz.Compare(p2->ctrl(col2, row2).xyz, WELD_EPSILON) ) { + match = false; + break; + } + } + } else { + match = false; + } + + if ( match ) { + // have a match weld these edges + common->Printf("Welding col %i with row %i\n", col, row2); + col = (col == 0) ? p->width - 1 : 0; + Patch_Combine(p, p2, col, -1, -1, row2, (adj1 == -1), (adj2 == -1)); + return; + } else if ( row2 == 0 ) { + row2 = p2->height - 1; + } else if ( col == 0 ) { + col = p->width - 1; + row2 = 0; + } else { + break; + } + } + } + + if ( p->height == p2->height ) { + int col = 0; + int col2 = 0; + while ( 1 ) { + bool match = true; + + + int row1 = 0; + int adj1 = 1; + int row2 = 0; + int adj2 = 1; + if ( p->ctrl(col, 0).xyz.Compare(p2->ctrl(col2, 0).xyz, WELD_EPSILON) ) { + } else if ( p->ctrl(col, 0).xyz.Compare(p2->ctrl(col2, p2->height - 1).xyz, WELD_EPSILON) ) { + row2 = p2->height - 1; + adj2 = -1; + } else if ( p->ctrl(col, p2->height - 1).xyz.Compare(p2->ctrl(col2, p2->height - 1).xyz, WELD_EPSILON) ) { + row2 = p2->height - 1; + adj2 = -1; + row1 = p->height - 1; + adj1 = -1; + } else if ( p->ctrl(col, p2->height - 1).xyz.Compare(p2->ctrl(col2, 0).xyz, WELD_EPSILON) ) { + row1 = p->height - 1; + adj1 = -1; + } else { + adj1 = 0; + } + + if ( adj1 ) { + for ( int row = 0; row < p->height; row++, row1 += adj1, row2 += adj2 ) { + if ( !p->ctrl(col, row1).xyz.Compare(p2->ctrl(col2, row2).xyz, WELD_EPSILON) ) { + match = false; + break; + } + } + } else { + match = false; + } + + if ( match ) { + // have a match weld these edges + common->Printf("Welding col %i with col %i\n", col, col2); + col = (col == 0) ? p->width - 1 : 0; + Patch_Combine(p, p2, col, col2, -1, -1, (adj1 == -1), (adj2 == -1)); + return; + } else if ( col2 == 0 ) { + col2 = p2->width - 1; + } else if ( col == 0 ) { + col = p->width - 1; + col2 = 0; + } else { + break; + } + } + } + + + Sys_Status("Unable to weld patches, no common sized edges.\n"); +} + + +// used for a save spot +patchMesh_t *patchSave = NULL; + +// Tracks the selected patch for point manipulation/update. FIXME: Need to revert back to a generalized +// brush approach +//--int g_nSelectedPatch = -1; + +// HACK: for tracking which view generated the click +// as we dont want to deselect a point on a same point +// click if it is from a different view +int g_nPatchClickedView = -1; +bool g_bSameView = false; + + +// globals +bool g_bPatchShowBounds = false; +bool g_bPatchWireFrame = false; +bool g_bPatchWeld = true; +bool g_bPatchDrillDown = true; +bool g_bPatchInsertMode = false; +bool g_bPatchBendMode = false; +int g_nPatchBendState = -1; +int g_nPatchInsertState = -1; +int g_nBendOriginIndex = 0; +idVec3 g_vBendOrigin; + +bool g_bPatchAxisOnRow = true; +int g_nPatchAxisIndex = 0; +bool g_bPatchLowerEdge = true; + +// BEND states +enum { + BEND_SELECT_ROTATION = 0, + BEND_SELECT_ORIGIN, + BEND_SELECT_EDGE, + BEND_BENDIT, + BEND_STATE_COUNT +}; + +const char *g_pBendStateMsg[] = { + "Use TAB to cycle through available bend axis. Press ENTER when the desired one is highlighted.", "Use TAB to cycle through available rotation axis. This will LOCK around that point. You may also use Shift + Middle Click to select an arbitrary point. Press ENTER when the desired one is highlighted", "Use TAB to choose which side to bend. Press ENTER when the desired one is highlighted.", "Use the MOUSE to bend the patch. It uses the same ui rules as Free Rotation. Press ENTER to accept the bend, press ESC to abandon it and exit Bend mode", "" +}; + +// INSERT states +enum { + INSERT_SELECT_EDGE = 0, + INSERT_STATE_COUNT +}; + +const char *g_pInsertStateMsg[] = { + "Use TAB to cycle through available rows/columns for insertion/deletion. Press INS to insert at the highlight, DEL to remove the pair" +}; + + +float *g_InversePoints[1024]; + +const float fFullBright = 1.0f; +const float fLowerLimit = 0.5f; +const float fDec = 0.05f; + + +void Patch_SetType( patchMesh_t *p,int nType ) { + p->type = (p->type & PATCH_STYLEMASK) | nType; +} + +void Patch_SetStyle( patchMesh_t *p,int nStyle ) { + p->type = (p->type & PATCH_TYPEMASK) | nStyle; +} + +/* +================== +Patch_MemorySize +================== +*/ +int Patch_MemorySize( patchMesh_t *p ) { + return (sizeof(patchMesh_t) + p->width * p->height * sizeof(idDrawVert)); +} + + + +/* +=============== +InterpolateInteriorPoints +=============== +*/ +void InterpolateInteriorPoints( patchMesh_t *p ) { + int i, j, k; + int next, prev; + + for ( i = 0 ; i < p->width ; i += 2 ) { + next = (i == p->width - 1) ? 1 : (i + 1) % p->width; + prev = (i == 0) ? p->width - 2 : i - 1; + for ( j = 0 ; j < p->height ; j++ ) { + for ( k = 0 ; k < 3 ; k++ ) { + p->ctrl(i, j).xyz[k] = (p->ctrl(next, j).xyz[k] + p->ctrl(prev, j).xyz[k]) * 0.5; + } + } + } +} + +/* +================= +MakeMeshNormals + +================= +*/ +int neighbors[8][2] = { + {0,1}, {1,1}, {1,0}, {1, -1}, {0, -1}, { - 1, -1}, { - 1,0}, { - 1,1} +}; + +void Patch_MeshNormals( patchMesh_t *in ) { + int i, j, k, dist; + idVec3 normal; + idVec3 sum; + int count; + idVec3 base; + idVec3 delta; + int x, y; + idDrawVert *dv; + idVec3 around[8], temp; + bool good[8]; + bool wrapWidth, wrapHeight; + float len; + + wrapWidth = false; + for ( i = 0 ; i < in->height ; i++ ) { + VectorSubtract(in->ctrl(0, i).xyz, in->ctrl(in->width - 1, i).xyz, delta); + len = delta.Length(); + if ( len > 1.0f ) { + break; + } + } + if ( i == in->height ) { + wrapWidth = true; + } + + wrapHeight = false; + for ( i = 0 ; i < in->width ; i++ ) { + VectorSubtract(in->ctrl(i, 0).xyz, in->ctrl(i, in->height - 1).xyz, delta); + len = delta.Length(); + if ( len > 1.0f ) { + break; + } + } + if ( i == in->width ) { + wrapHeight = true; + } + + + for ( i = 0 ; i < in->width ; i++ ) { + for ( j = 0 ; j < in->height ; j++ ) { + count = 0; + //--dv = reinterpret_cast(in.ctrl[j*in.width+i]); + dv = &in->ctrl(i, j); + VectorCopy(dv->xyz, base); + for ( k = 0 ; k < 8 ; k++ ) { + around[k] = vec3_origin; + good[k] = false; + + for ( dist = 1 ; dist <= 3 ; dist++ ) { + x = i + neighbors[k][0] * dist; + y = j + neighbors[k][1] * dist; + if ( wrapWidth ) { + if ( x < 0 ) { + x = in->width - 1 + x; + } else if ( x >= in->width ) { + x = 1 + x - in->width; + } + } + if ( wrapHeight ) { + if ( y < 0 ) { + y = in->height - 1 + y; + } else if ( y >= in->height ) { + y = 1 + y - in->height; + } + } + + if ( x < 0 || x >= in->width || y < 0 || y >= in->height ) { + break; // edge of patch + } + //--VectorSubtract( in.ctrl[y*in.width+x]->xyz, base, temp ); + VectorSubtract(in->ctrl(x, y).xyz, base, temp); + if ( temp.Normalize() == 0 ) { + continue; // degenerate edge, get more dist + } else { + good[k] = true; + VectorCopy(temp, around[k]); + break; // good edge + } + } + } + + sum = vec3_origin; + for ( k = 0 ; k < 8 ; k++ ) { + if ( !good[k] || !good[(k + 1) & 7] ) { + continue; // didn't get two points + } + normal = around[(k + 1) & 7].Cross(around[k]); + if ( normal.Normalize() == 0 ) { + continue; + } + VectorAdd(normal, sum, sum); + count++; + } + if ( count == 0 ) { + //printf("bad normal\n"); + count = 1; + //continue; + } + dv->normal = sum; + dv->normal.Normalize(); + } + } +} + +void Patch_MakeDirty( patchMesh_t *p ) { + assert(p); + p->nListID = -1; + p->nListIDCam = -1; + p->nListSelected = -1; +} + + +/* +================== +Patch_CalcBounds +================== +*/ +void Patch_CalcBounds( patchMesh_t *p,idVec3 &vMin,idVec3 &vMax ) { + vMin[0] = vMin[1] = vMin[2] = 999999; + vMax[0] = vMax[1] = vMax[2] = -999999; + + Patch_MakeDirty(p); + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + for ( int j = 0; j < 3; j++ ) { + float f = p->ctrl(w, h).xyz[j]; + if ( f < vMin[j] ) + vMin[j] = f; + if ( f > vMax[j] ) + vMax[j] = f; + } + } + } +} + +/* +================== +Brush_RebuildBrush +================== +*/ +void Brush_RebuildBrush( brush_t *b,idVec3 vMins,idVec3 vMaxs,bool patch ) { + // + // Total hack job + // Rebuilds a brush + int i, j; + face_t *f, *next; + idVec3 pts[4][2]; + texdef_t texdef; + // free faces + + for ( j = 0; j < 3; j++ ) { + if ( (int) vMins[j] == (int) vMaxs[j] ) { + vMins[j] -= 4; + vMaxs[j] += 4; + } + } + + + for ( f = b->brush_faces ; f ; f = next ) { + next = f->next; + if ( f ) { + texdef = f->texdef; + } + Face_Free(f); + } + + b->brush_faces = NULL; + + // left the last face so we can use its texdef + + for ( i = 0 ; i < 3 ; i++ ) { + if ( vMaxs[i] < vMins[i] ) { + Error("Brush_RebuildBrush: backwards"); + } + } + + pts[0][0][0] = vMins[0]; + pts[0][0][1] = vMins[1]; + + pts[1][0][0] = vMins[0]; + pts[1][0][1] = vMaxs[1]; + + pts[2][0][0] = vMaxs[0]; + pts[2][0][1] = vMaxs[1]; + + pts[3][0][0] = vMaxs[0]; + pts[3][0][1] = vMins[1]; + + for ( i = 0 ; i < 4 ; i++ ) { + pts[i][0][2] = vMins[2]; + pts[i][1][0] = pts[i][0][0]; + pts[i][1][1] = pts[i][0][1]; + pts[i][1][2] = vMaxs[2]; + } + + for ( i = 0 ; i < 4 ; i++ ) { + f = Face_Alloc(); + f->texdef = texdef; + f->next = b->brush_faces; + b->brush_faces = f; + j = (i + 1) % 4; + + VectorCopy(pts[j][1], f->planepts[0]); + VectorCopy(pts[i][1], f->planepts[1]); + VectorCopy(pts[i][0], f->planepts[2]); + } + + f = Face_Alloc(); + f->texdef = texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy(pts[0][1], f->planepts[0]); + VectorCopy(pts[1][1], f->planepts[1]); + VectorCopy(pts[2][1], f->planepts[2]); + + f = Face_Alloc(); + f->texdef = texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy(pts[2][0], f->planepts[0]); + VectorCopy(pts[1][0], f->planepts[1]); + VectorCopy(pts[0][0], f->planepts[2]); + + Brush_Build(b); +} + +void WINAPI Patch_Rebuild( patchMesh_t *p ) { + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + Patch_MakeDirty(p); +} + +/* +================== +AddBrushForPatch +================== + adds a patch brush and ties it to this patch id +*/ +brush_t * AddBrushForPatch( patchMesh_t *pm,bool bLinkToWorld ) { + // find the farthest points in x,y,z + idVec3 vMin, vMax; + Patch_CalcBounds(pm, vMin, vMax); + + for ( int j = 0; j < 3; j++ ) { + if ( idMath::Fabs(vMin[j] - vMax[j]) <= VECTOR_EPSILON ) { + vMin[j] -= 4; + vMax[j] += 4; + } + } + + texdef_t td; + //td.SetName(pm->d_texture->getName()); + brush_t *b = Brush_Create(vMin, vMax, &td); + //brush_t *b = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef); + + // FIXME: this entire type of linkage needs to be fixed + b->pPatch = pm; + pm->pSymbiot = b; + pm->bSelected = false; + pm->bOverlay = false; + pm->nListID = -1; + pm->nListIDCam = -1; + + if ( bLinkToWorld ) { + Brush_AddToList(b, &active_brushes); + Entity_LinkBrush(world_entity, b); + Brush_Build(b); + } + + return b; +} + +void Patch_SetPointIntensities( int n ) { +#if 0 + patchMesh_t *p = patchMeshes[n]; + for (int i = 0; i < p->width; i++) { + for (int j = 0; j < p->height; j++) { + + } + } +#endif +} + +// very approximate widths and heights + +/* +================== +Patch_Width +================== +*/ +float Patch_Width( patchMesh_t *p ) { + float f = 0; + for ( int j = 0; j < p->height - 1; j++ ) { + float t = 0; + for ( int i = 0; i < p->width - 1; i++ ) { + idVec3 vTemp; + vTemp = p->ctrl(i, j).xyz - p->ctrl(i + 1, j).xyz; + t += vTemp.Length(); + } + if ( f < t ) { + f = t; + } + } + return f; +} + +/* +================== +Patch_Height +================== +*/ +float Patch_Height( patchMesh_t *p ) { + float f = 0; + for ( int j = 0; j < p->width - 1; j++ ) { + float t = 0; + for ( int i = 0; i < p->height - 1; i++ ) { + idVec3 vTemp; + vTemp = p->ctrl(j, i).xyz - p->ctrl(j, i + 1).xyz; + t += vTemp.Length(); + } + if ( f < t ) { + f = t; + } + } + return f; +} + +/* +================== +Patch_WidthDistanceTo +================== +*/ +float Patch_WidthDistanceTo( patchMesh_t *p,int j ) { + float f = 0; + for ( int i = 0; i < j ; i++ ) { + idVec3 vTemp; + vTemp = p->ctrl(i, 0).xyz - p->ctrl(i + 1, 0).xyz; + f += vTemp.Length(); + } + return f; +} + +/* +================== +Patch_HeightDistanceTo +================== +*/ +float Patch_HeightDistanceTo( patchMesh_t *p,int j ) { + float f = 0; + for ( int i = 0; i < j ; i++ ) { + idVec3 vTemp; + vTemp = p->ctrl(0, i).xyz - p->ctrl(0, i + 1).xyz; + f += vTemp.Length(); + } + return f; +} + + + +/* +================== +Patch_Naturalize +================== +texture = TotalTexture * LengthToThisControlPoint / TotalControlPointLength + +dist( this control point to first control point ) / dist ( last control pt to first) +*/ +void Patch_Naturalize( patchMesh_t *p,bool horz,bool vert,bool alt ) { + int i, j; + + int nWidth = p->d_texture->GetEditorImage()->uploadWidth * 0.5; + int nHeight = p->d_texture->GetEditorImage()->uploadHeight * 0.5; + float fPWidth = Patch_Width(p); + float fPHeight = Patch_Height(p); + float xAccum = 0; + for ( i = 0 ; i < ((alt) ? p->height : p->width) ; i++ ) { + float yAccum = 0; + for ( j = 0 ; j < ((alt) ? p->width : p->height) ; j++ ) { + int r = ((alt) ? j : i); + int c = ((alt) ? i : j); + p->ctrl(r, c).st[0] = (fPWidth / nWidth) * xAccum / fPWidth; + p->ctrl(r, c).st[1] = (fPHeight / nHeight) * yAccum / fPHeight; + if ( alt ) { + yAccum = Patch_WidthDistanceTo(p, j + 1); + } else { + yAccum = Patch_HeightDistanceTo(p, j + 1); + } + } + if ( alt ) { + xAccum = Patch_HeightDistanceTo(p, i + 1); + } else { + xAccum = Patch_WidthDistanceTo(p, i + 1); + } + } + + Patch_MakeDirty(p); +} + +/* + if (bIBevel) + { + VectorCopy(p->ctrl(1,0], p->ctrl(1,1]); + } + + if (bIEndcap) + { + VectorCopy(p->ctrl(3,0], p->ctrl(4,1]); + VectorCopy(p->ctrl(2,0], p->ctrl(3,1]); + VectorCopy(p->ctrl(2,0], p->ctrl(2,1]); + VectorCopy(p->ctrl(2,0], p->ctrl(1,1]); + VectorCopy(p->ctrl(1,0], p->ctrl(0,1]); + VectorCopy(p->ctrl(1,0], p->ctrl(0,2]); + VectorCopy(p->ctrl(1,0], p->ctrl(1,2]); + VectorCopy(p->ctrl(2,0], p->ctrl(2,2]); + VectorCopy(p->ctrl(3,0], p->ctrl(3,2]); + VectorCopy(p->ctrl(3,0], p->ctrl(4,2]); + } +*/ + +int Index3By[][2] = { + {0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {1,2}, {0,2}, {0,1}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} +}; + +int Index5By[][2] = { + {0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}, {3,4}, {2,4}, {1,4}, {0,4}, {0,3}, {0,2}, {0,1} +}; + + + +int Interior3By[][2] = { + {1,1} +}; + +int Interior5By[][2] = { + {1,1}, {2,1}, {3,1}, {1,2}, {2,2}, {3,2}, {1,3}, {2,3}, {3,3} +}; + +int Interior3ByCount = sizeof(Interior3By) / sizeof(int[2]); +int Interior5ByCount = sizeof(Interior5By) / sizeof(int[2]); + +face_t * Patch_GetAxisFace( patchMesh_t *p ) { + face_t *f = NULL; + idVec3 vTemp; + brush_t *b = p->pSymbiot; + + for ( f = b->brush_faces ; f ; f = f->next ) { + vTemp = (*f->face_winding)[1].ToVec3() - (*f->face_winding)[0].ToVec3(); + int nScore = 0; + + // default edge faces on caps are 8 high so + // as soon as we hit one that is bigger it should be on the right axis + for ( int j = 0; j < 3; j++ ) { + if ( vTemp[j] > 8 ) + nScore++; + } + + if ( nScore > 0 ) { + break; + } + } + + if ( f == NULL ) { + f = b->brush_faces; + } + return f; +} + +int g_nFaceCycle = 0; + +face_t * nextFace( patchMesh_t *p ) { + brush_t *b = p->pSymbiot; + face_t *f = NULL; + int n = 0; + for ( f = b->brush_faces ; f && n <= g_nFaceCycle; f = f->next ) { + n++; + } + + g_nFaceCycle++; + + if ( g_nFaceCycle > 5 ) { + g_nFaceCycle = 0; + f = b->brush_faces; + } + + return f; +} + + +void Patch_CapTexture( patchMesh_t *p,bool bFaceCycle = false,bool alt = false ) { + Patch_MeshNormals(p); + face_t *f = (bFaceCycle) ? nextFace(p) : Patch_GetAxisFace(p); + idVec3 vSave; + VectorCopy(f->plane, vSave); + float fRotate = f->texdef.rotate; + f->texdef.rotate = 0; + float fScale[2]; + fScale[0] = f->texdef.scale[0]; + fScale[1] = f->texdef.scale[1]; + f->texdef.scale[0] = (float) p->d_texture->GetEditorImage()->uploadWidth / 32.0f; + f->texdef.scale[1] = (float) p->d_texture->GetEditorImage()->uploadHeight / 32.0f; + float fShift[2]; + fShift[0] = f->texdef.shift[0]; + fShift[1] = f->texdef.shift[1]; + f->texdef.shift[0] = 0; + f->texdef.shift[1] = 0; + + for ( int i = 0 ; i < p->width; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + if ( !bFaceCycle ) { + VectorCopy(p->ctrl(i, j).normal, f->plane); + } + idVec5 temp; + temp.x = p->ctrl(i, j).xyz.x; + temp.y = p->ctrl(i, j).xyz.y; + temp.z = p->ctrl(i, j).xyz.z; + EmitTextureCoordinates(temp, f->d_texture, f, true); + p->ctrl(i, j).st.x = temp.s; + p->ctrl(i, j).st.y = temp.t; + } + } + + VectorCopy(vSave, f->plane); + f->texdef.rotate = fRotate; + f->texdef.scale[0] = fScale[0]; + f->texdef.scale[1] = fScale[1]; + f->texdef.shift[0] = fShift[0]; + f->texdef.shift[1] = fShift[1]; + Patch_ScaleTexture(p, 1.0f, -1.0f, false); + Patch_MakeDirty(p); +} + +void FillPatch( patchMesh_t *p,idVec3 v ) { + for ( int i = 0; i < p->width; i++ ) { + for ( int j = 0; j < p->height; j++ ) { + VectorCopy(v, p->ctrl(i, j).xyz); + } + } +} + +brush_t * Cap( patchMesh_t *pParent,bool bByColumn,bool bFirst ) { + brush_t *b; + patchMesh_t *p; + idVec3 vMin, vMax; + int i, j; + + bool bSmall = true; + // make a generic patch + if ( pParent->width <= 9 ) { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + } else { + b = Patch_GenericMesh(5, 5, 2, false, false, pParent); + bSmall = false; + } + + if ( !b ) { + Sys_Status("Unable to cap. You may need to ungroup the patch.\n"); + return NULL; + } + + p = b->pPatch; + p->type |= PATCH_CAP; + + vMin[0] = vMin[1] = vMin[2] = 99999; + vMax[0] = vMax[1] = vMax[2] = -99999; + + // we seam the column edge, FIXME: this might need to be able to seem either edge + // + int nSize = (bByColumn) ? pParent->width : pParent->height; + int nIndex = (bFirst) ? 0 : (bByColumn) ? pParent->height - 1 : pParent->width - 1; + + FillPatch(p, pParent->ctrl(0, nIndex).xyz); + + for ( i = 0; i < nSize; i++ ) { + if ( bByColumn ) { + if ( bSmall ) { + VectorCopy(pParent->ctrl(i, nIndex).xyz, p->ctrl(Index3By[i][0], Index3By[i][1]).xyz); + } else { + VectorCopy(pParent->ctrl(i, nIndex).xyz, p->ctrl(Index5By[i][0], Index5By[i][1]).xyz); + } + } else { + if ( bSmall ) { + VectorCopy(pParent->ctrl(nIndex, i).xyz, p->ctrl(Index3By[i][0], Index3By[i][1]).xyz); + } else { + VectorCopy(pParent->ctrl(nIndex, i).xyz, p->ctrl(Index5By[i][0], Index5By[i][1]).xyz); + } + } + + for ( j = 0; j < 3; j++ ) { + float f = (bSmall) ? p->ctrl(Index3By[i][0], Index3By[i][1]).xyz[j] : p->ctrl(Index5By[i][0], Index5By[i][1]).xyz[j]; + if ( f < vMin[j] ) + vMin[j] = f; + if ( f > vMax[j] ) + vMax[j] = f; + } + } + + idVec3 vTemp; + for ( j = 0; j < 3; j++ ) { + vTemp[j] = vMin[j] + abs((vMax[j] - vMin[j]) * 0.5); + } + + int nCount = (bSmall) ? Interior3ByCount : Interior5ByCount; + for ( j = 0; j < nCount; j++ ) { + if ( bSmall ) { + VectorCopy(vTemp, p->ctrl(Interior3By[j][0], Interior3By[j][1]).xyz); + } else { + VectorCopy(vTemp, p->ctrl(Interior5By[j][0], Interior5By[j][1]).xyz); + } + } + + if ( bFirst ) { + idDrawVert vertTemp; + for ( i = 0; i < p->width; i++ ) { + for ( j = 0; j < p->height / 2; j++ ) { + memcpy(&vertTemp, &p->ctrl(i, p->height - 1 - j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, p->height - 1 - j), &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &vertTemp, sizeof(idDrawVert)); + } + } + } + + Patch_Rebuild(p); + Patch_CapTexture(p); + return p->pSymbiot; +} + +brush_t * CapSpecial( patchMesh_t *pParent,int nType,bool bFirst ) { + brush_t *b; + patchMesh_t *p; + idVec3 vMin, vMax, vTemp; + int i, j; + + if ( nType == CCapDialog::IENDCAP ) { + b = Patch_GenericMesh(5, 3, 2, false, false, pParent); + } else { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + } + + if ( !b ) { + Sys_Status("Unable to cap. Make sure you ungroup before re-capping."); + return NULL; + } + + p = b->pPatch; + p->type |= PATCH_CAP; + + vMin[0] = vMin[1] = vMin[2] = 99999; + vMax[0] = vMax[1] = vMax[2] = -99999; + + int nSize = pParent->width; + int nIndex = (bFirst) ? 0 : pParent->height - 1; + + // parent bounds are used for some things + Patch_CalcBounds(pParent, vMin, vMax); + + for ( j = 0; j < 3; j++ ) { + vTemp[j] = vMin[j] + abs((vMax[j] - vMin[j]) * 0.5); + } + + if ( nType == CCapDialog::IBEVEL ) { + VectorCopy(pParent->ctrl(0, nIndex).xyz, p->ctrl(0, 0).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(0, 2).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(0, 1).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(2, 2).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 0).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 1).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 2).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(2, 0).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(2, 1).xyz); + } else if ( nType == CCapDialog::BEVEL ) { + idVec3 p1, p2, p3, p4, temp, dir; + + VectorCopy(pParent->ctrl(0, nIndex).xyz, p3); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p1); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p2); + + VectorSubtract(p3, p2, dir); + dir.Normalize(); + VectorSubtract(p1, p2, temp); + float dist = DotProduct(temp, dir); + + VectorScale(dir, dist, temp); + + VectorAdd(p2, temp, temp); + + VectorSubtract(temp, p1, temp); + VectorScale(temp, 2, temp); + VectorAdd(p1, temp, p4); + + VectorCopy(p4, p->ctrl(0, 0).xyz); + VectorCopy(p4, p->ctrl(1, 0).xyz); + VectorCopy(p4, p->ctrl(0, 1).xyz); + VectorCopy(p4, p->ctrl(1, 1).xyz); + VectorCopy(p4, p->ctrl(0, 2).xyz); + VectorCopy(p4, p->ctrl(1, 2).xyz); + VectorCopy(p3, p->ctrl(2, 0).xyz); + VectorCopy(p1, p->ctrl(2, 1).xyz); + VectorCopy(p2, p->ctrl(2, 2).xyz); + } else if ( nType == CCapDialog::ENDCAP ) { + VectorAdd(pParent->ctrl(4, nIndex).xyz, pParent->ctrl(0, nIndex).xyz, vTemp); + VectorScale(vTemp, 0.5, vTemp); + VectorCopy(pParent->ctrl(0, nIndex).xyz, p->ctrl(0, 0).xyz); + VectorCopy(vTemp, p->ctrl(1, 0).xyz); + VectorCopy(pParent->ctrl(4, nIndex).xyz, p->ctrl(2, 0).xyz); + + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(0, 2).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(1, 2).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(2, 2).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(1, 1).xyz); + + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(0, 1).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(2, 1).xyz); + } else { + VectorCopy(pParent->ctrl(0, nIndex).xyz, p->ctrl(0, 0).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 0).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(2, 0).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(3, 0).xyz); + VectorCopy(pParent->ctrl(4, nIndex).xyz, p->ctrl(4, 0).xyz); + + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(0, 1).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 1).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(2, 1).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(3, 1).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(4, 1).xyz); + + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(0, 2).xyz); + VectorCopy(pParent->ctrl(1, nIndex).xyz, p->ctrl(1, 2).xyz); + VectorCopy(pParent->ctrl(2, nIndex).xyz, p->ctrl(2, 2).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(3, 2).xyz); + VectorCopy(pParent->ctrl(3, nIndex).xyz, p->ctrl(4, 2).xyz); + } + + + bool bEndCap = (nType == CCapDialog::ENDCAP || nType == CCapDialog::IENDCAP); + if ( (!bFirst && !bEndCap) || (bFirst && bEndCap) ) { + idDrawVert vertTemp; + for ( i = 0; i < p->width; i++ ) { + for ( j = 0; j < p->height / 2; j++ ) { + memcpy(&vertTemp, &p->ctrl(i, p->height - 1 - j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, p->height - 1 - j), &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &vertTemp, sizeof(idDrawVert)); + } + } + } + + //--Patch_CalcBounds(p, vMin, vMax); + //--Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + Patch_Rebuild(p); + Patch_CapTexture(p); + return p->pSymbiot; +} + + +void Patch_CapCurrent( bool bInvertedBevel,bool bInvertedEndcap ) { + patchMesh_t *pParent = NULL; + brush_t *b[4]; + brush_t *pCap = NULL; + b[0] = b[1] = b[2] = b[3] = NULL; + int nIndex = 0; + + if ( !QE_SingleBrush() ) { + Sys_Status("Cannot cap multiple selection. Please select a single patch.\n"); + return; + } + + + for ( brush_t*pb = selected_brushes.next ; pb != NULL && pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pParent = pb->pPatch; + // decide which if any ends we are going to cap + // if any of these compares hit, it is a closed patch and as such + // the generic capping will work.. if we do not find a closed edge + // then we need to ask which kind of cap to add + if ( pParent->ctrl(0, 0).xyz.Compare(pParent->ctrl(pParent->width - 1, 0).xyz) ) { + pCap = Cap(pParent, true, false); + if ( pCap != NULL ) { + b[nIndex++] = pCap; + } + } + if ( pParent->ctrl(0, pParent->height - 1).xyz.Compare(pParent->ctrl(pParent->width - 1, pParent->height - 1).xyz) ) { + pCap = Cap(pParent, true, true); + if ( pCap != NULL ) { + b[nIndex++] = pCap; + } + } + if ( pParent->ctrl(0, 0).xyz.Compare(pParent->ctrl(0, pParent->height - 1).xyz) ) { + pCap = Cap(pParent, false, false); + if ( pCap != NULL ) { + b[nIndex++] = pCap; + } + } + if ( pParent->ctrl(pParent->width - 1, 0).xyz.Compare(pParent->ctrl(pParent->width - 1, pParent->height - 1).xyz) ) { + pCap = Cap(pParent, false, true); + if ( pCap != NULL ) { + b[nIndex++] = pCap; + } + } + } + } + + if ( pParent ) { + // if we did not cap anything with the above tests + if ( nIndex == 0 ) { + CCapDialog dlg; + if ( dlg.DoModal() == IDOK ) { + b[nIndex++] = CapSpecial(pParent, dlg.getCapType(), false); + b[nIndex++] = CapSpecial(pParent, dlg.getCapType(), true); + } + } + + if ( nIndex > 0 ) { + while ( nIndex > 0 ) { + nIndex--; + if ( b[nIndex] ) { + Select_Brush(b[nIndex]); + } + } + eclass_t*pecNew = Eclass_ForName("func_static", false); + if ( pecNew ) { + entity_t*e = Entity_Create(pecNew); + SetKeyValue(e, "type", "patchCapped"); + } + } + } +} + + +//FIXME: Table drive all this crap +// +void GenerateEndCaps( brush_t *brushParent,bool bBevel,bool bEndcap,bool bInverted ) { + brush_t *b, *b2; + patchMesh_t *p, *p2, *pParent; + idVec3 vTemp, vMin, vMax; + int i, j; + + pParent = brushParent->pPatch; + + Patch_CalcBounds(pParent, vMin, vMax); + // basically generate two endcaps, place them, and link the three brushes with a func_group + + if ( pParent->width > 9 ) { + b = Patch_GenericMesh(5, 3, 2, false, false, pParent); + } else { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + } + p = b->pPatch; + + vMin[0] = vMin[1] = vMin[2] = 99999; + vMax[0] = vMax[1] = vMax[2] = -99999; + + for ( i = 0; i < pParent->width; i++ ) { + VectorCopy(pParent->ctrl(i, 0).xyz, p->ctrl(Index3By[i][0], Index3By[i][1]).xyz); + for ( j = 0; j < 3; j++ ) { + if ( pParent->ctrl(i, 0).xyz[j] < vMin[j] ) + vMin[j] = pParent->ctrl(i, 0).xyz[j]; + if ( pParent->ctrl(i, 0).xyz[j] > vMax[j] ) + vMax[j] = pParent->ctrl(i, 0).xyz[j]; + } + } + + for ( j = 0; j < 3; j++ ) { + vTemp[j] = vMin[j] + abs((vMax[j] - vMin[j]) * 0.5); + } + + for ( i = 0; i < Interior3ByCount; i++ ) { + VectorCopy(vTemp, p->ctrl(Interior3By[i][0], Interior3By[i][1]).xyz); + } + + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + Select_Brush(p->pSymbiot); + return; + + bool bCreated = false; + + if ( bInverted ) { + if ( bBevel ) { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p = b->pPatch; + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(1, 2).xyz); + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(2, 1).xyz); + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(0, 1).xyz); + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(1, 0).xyz); + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(1, 1).xyz); + VectorCopy(p->ctrl(2, 0).xyz, p->ctrl(0, 0).xyz); + + b2 = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p2 = b2->pPatch; + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(1, 2).xyz); + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(2, 1).xyz); + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(0, 1).xyz); + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(1, 0).xyz); + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(1, 1).xyz); + VectorCopy(p2->ctrl(2, 0).xyz, p2->ctrl(0, 0).xyz); + + + bCreated = true; + } else if ( bEndcap ) { + b = Patch_GenericMesh(5, 5, 2, false, false, pParent); + p = b->pPatch; + VectorCopy(p->ctrl(4, 4).xyz, p->ctrl(4, 3).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(1, 4).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(2, 4).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(3, 4).xyz); + + VectorCopy(p->ctrl(4, 0).xyz, p->ctrl(4, 1).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(1, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(2, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(3, 0).xyz); + + for ( i = 1; i < 4; i++ ) { + for ( j = 0; j < 4; j++ ) { + VectorCopy(p->ctrl(4, i).xyz, p->ctrl(j, i).xyz); + } + } + + + b2 = Patch_GenericMesh(5, 5, 2, false, false, pParent); + p2 = b2->pPatch; + VectorCopy(p2->ctrl(4, 4).xyz, p2->ctrl(4, 3).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(1, 4).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(2, 4).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(3, 4).xyz); + + VectorCopy(p2->ctrl(4, 0).xyz, p2->ctrl(4, 1).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(1, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(2, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(3, 0).xyz); + + for ( i = 1; i < 4; i++ ) { + for ( j = 0; j < 4; j++ ) { + VectorCopy(p2->ctrl(4, i).xyz, p2->ctrl(j, i).xyz); + } + } + + + bCreated = true; + } + } else { + if ( bBevel ) { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p = b->pPatch; + VectorCopy(p->ctrl(2, 0).xyz, p->ctrl(2, 1).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(1, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(2, 0).xyz); + + b2 = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p2 = b2->pPatch; + VectorCopy(p2->ctrl(2, 0).xyz, p2->ctrl(2, 1).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(1, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(2, 0).xyz); + bCreated = true; + } else if ( bEndcap ) { + b = Patch_GenericMesh(5, 5, 2, false, false, pParent); + p = b->pPatch; + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(1, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(2, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(3, 0).xyz); + VectorCopy(p->ctrl(4, 0).xyz, p->ctrl(4, 1).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(4, 0).xyz); + + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(1, 4).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(2, 4).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(3, 4).xyz); + VectorCopy(p->ctrl(4, 4).xyz, p->ctrl(4, 3).xyz); + VectorCopy(p->ctrl(0, 4).xyz, p->ctrl(4, 4).xyz); + + b2 = Patch_GenericMesh(5, 5, 2, false, false, pParent); + p2 = b2->pPatch; + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(1, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(2, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(3, 0).xyz); + VectorCopy(p2->ctrl(4, 0).xyz, p2->ctrl(4, 1).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(4, 0).xyz); + + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(1, 4).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(2, 4).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(3, 4).xyz); + VectorCopy(p2->ctrl(4, 4).xyz, p2->ctrl(4, 3).xyz); + VectorCopy(p2->ctrl(0, 4).xyz, p2->ctrl(4, 4).xyz); + bCreated = true; + } else { + b = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p = b->pPatch; + + VectorCopy(p->ctrl(0, 1).xyz, vTemp); + VectorCopy(p->ctrl(0, 2).xyz, p->ctrl(0, 1).xyz); + VectorCopy(p->ctrl(1, 2).xyz, p->ctrl(0, 2).xyz); + VectorCopy(p->ctrl(2, 2).xyz, p->ctrl(1, 2).xyz); + VectorCopy(p->ctrl(2, 1).xyz, p->ctrl(2, 2).xyz); + VectorCopy(p->ctrl(2, 0).xyz, p->ctrl(2, 1).xyz); + VectorCopy(p->ctrl(1, 0).xyz, p->ctrl(2, 0).xyz); + VectorCopy(p->ctrl(0, 0).xyz, p->ctrl(1, 0).xyz); + VectorCopy(vTemp, p->ctrl(0, 0).xyz); + + b2 = Patch_GenericMesh(3, 3, 2, false, false, pParent); + p2 = b2->pPatch; + VectorCopy(p2->ctrl(0, 1).xyz, vTemp); + VectorCopy(p2->ctrl(0, 2).xyz, p2->ctrl(0, 1).xyz); + VectorCopy(p2->ctrl(1, 2).xyz, p2->ctrl(0, 2).xyz); + VectorCopy(p2->ctrl(2, 2).xyz, p2->ctrl(1, 2).xyz); + VectorCopy(p2->ctrl(2, 1).xyz, p2->ctrl(2, 2).xyz); + VectorCopy(p2->ctrl(2, 0).xyz, p2->ctrl(2, 1).xyz); + VectorCopy(p2->ctrl(1, 0).xyz, p2->ctrl(2, 0).xyz); + VectorCopy(p2->ctrl(0, 0).xyz, p2->ctrl(1, 0).xyz); + VectorCopy(vTemp, p2->ctrl(0, 0).xyz); + bCreated = true; + } + } + + if ( bCreated ) { + idDrawVert vertTemp; + for ( i = 0; i < p->width; i++ ) { + for ( j = 0; j < p->height; j++ ) { + p->ctrl(i, j).xyz[2] = vMin[2]; + p2->ctrl(i, j).xyz[2] = vMax[2]; + } + + for ( j = 0; j < p->height / 2; j++ ) { + memcpy(&vertTemp, &p->ctrl(i, p->height - 1 - j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, p->height - 1 - j), &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &vertTemp, sizeof(idDrawVert)); + } + } + //Select_Delete(); + + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + Patch_CalcBounds(p2, vMin, vMax); + Brush_RebuildBrush(p2->pSymbiot, vMin, vMax); + Select_Brush(p->pSymbiot); + Select_Brush(p2->pSymbiot); + } else { + Select_Delete(); + } + //Select_Brush(brushParent); + +} + + +/* +=============== +BrushToPatchMesh +=============== +*/ +void Patch_BrushToMesh( bool bCone,bool bBevel,bool bEndcap,bool bSquare,int nHeight ) { + brush_t *b; + patchMesh_t *p; + int i, j; + + int width = 9; + if ( bBevel & !bSquare ) { + width = 3; + } else if ( bEndcap & !bSquare ) { + width = 5; + } + + if ( !QE_SingleBrush() ) { + return; + } + + b = selected_brushes.next; + + p = MakeNewPatch(width, nHeight); + + p->d_texture = b->brush_faces->d_texture; + + p->type = PATCH_CYLINDER; + if ( bBevel & !bSquare ) { + p->type = PATCH_BEVEL; + int nStep = (b->maxs[2] - b->mins[2]) / (p->height - 1); + int nStart = b->mins[2]; + for ( i = 0; i < p->height; i++ ) { + p->ctrl(0, i).xyz[0] = b->mins[0]; + p->ctrl(0, i).xyz[1] = b->mins[1]; + p->ctrl(0, i).xyz[2] = nStart; + + p->ctrl(1, i).xyz[0] = b->maxs[0]; + p->ctrl(1, i).xyz[1] = b->mins[1]; + p->ctrl(1, i).xyz[2] = nStart; + + p->ctrl(2, i).xyz[0] = b->maxs[0]; + p->ctrl(2, i).xyz[1] = b->maxs[1]; + p->ctrl(2, i).xyz[2] = nStart; + nStart += nStep; + } + } else if ( bEndcap & !bSquare ) { + p->type = PATCH_ENDCAP; + int nStep = (b->maxs[2] - b->mins[2]) / (p->height - 1); + int nStart = b->mins[2]; + for ( i = 0; i < p->height; i++ ) { + p->ctrl(0, i).xyz[0] = b->mins[0]; + p->ctrl(0, i).xyz[1] = b->mins[1]; + p->ctrl(0, i).xyz[2] = nStart; + + p->ctrl(1, i).xyz[0] = b->mins[0]; + p->ctrl(1, i).xyz[1] = b->maxs[1]; + p->ctrl(1, i).xyz[2] = nStart; + + p->ctrl(2, i).xyz[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) * 0.5); + p->ctrl(2, i).xyz[1] = b->maxs[1]; + p->ctrl(2, i).xyz[2] = nStart; + + p->ctrl(3, i).xyz[0] = b->maxs[0]; + p->ctrl(3, i).xyz[1] = b->maxs[1]; + p->ctrl(3, i).xyz[2] = nStart; + + p->ctrl(4, i).xyz[0] = b->maxs[0]; + p->ctrl(4, i).xyz[1] = b->mins[1]; + p->ctrl(4, i).xyz[2] = nStart; + nStart += nStep; + } + } else { + p->ctrl(1, 0).xyz[0] = b->mins[0]; + p->ctrl(1, 0).xyz[1] = b->mins[1]; + + p->ctrl(3, 0).xyz[0] = b->maxs[0]; + p->ctrl(3, 0).xyz[1] = b->mins[1]; + + p->ctrl(5, 0).xyz[0] = b->maxs[0]; + p->ctrl(5, 0).xyz[1] = b->maxs[1]; + + p->ctrl(7, 0).xyz[0] = b->mins[0]; + p->ctrl(7, 0).xyz[1] = b->maxs[1]; + + for ( i = 1 ; i < p->width - 1 ; i += 2 ) { + p->ctrl(i, 0).xyz[2] = b->mins[2]; + + VectorCopy(p->ctrl(i, 0).xyz, p->ctrl(i, 2).xyz); + + p->ctrl(i, 2).xyz[2] = b->maxs[2]; + + p->ctrl(i, 1).xyz[0] = (p->ctrl(i, 0).xyz[0] + p->ctrl(i, 2).xyz[0]) * 0.5; + p->ctrl(i, 1).xyz[1] = (p->ctrl(i, 0).xyz[1] + p->ctrl(i, 2).xyz[1]) * 0.5; + p->ctrl(i, 1).xyz[2] = (p->ctrl(i, 0).xyz[2] + p->ctrl(i, 2).xyz[2]) * 0.5; + } + InterpolateInteriorPoints(p); + + if ( bSquare ) { + if ( bBevel || bEndcap ) { + if ( bBevel ) { + for ( i = 0; i < p->height; i++ ) { + VectorCopy(p->ctrl(1, i).xyz, p->ctrl(2, i).xyz); + VectorCopy(p->ctrl(7, i).xyz, p->ctrl(6, i).xyz); + } + } else { + for ( i = 0; i < p->height; i++ ) { + VectorCopy(p->ctrl(5, i).xyz, p->ctrl(4, i).xyz); + VectorCopy(p->ctrl(1, i).xyz, p->ctrl(2, i).xyz); + VectorCopy(p->ctrl(7, i).xyz, p->ctrl(6, i).xyz); + VectorCopy(p->ctrl(8, i).xyz, p->ctrl(7, i).xyz); + } + } + } else { + for ( i = 0; i < p->width - 1; i ++ ) { + for ( j = 0; j < p->height; j++ ) { + VectorCopy(p->ctrl(i + 1, j).xyz, p->ctrl(i, j).xyz); + } + } + for ( j = 0; j < p->height; j++ ) { + VectorCopy(p->ctrl(0, j).xyz, p->ctrl(8, j).xyz); + } + } + } + } + + + Patch_Naturalize(p); + + if ( bCone ) { + p->type = PATCH_CONE; + float xc = (b->maxs[0] + b->mins[0]) * 0.5; + float yc = (b->maxs[1] + b->mins[1]) * 0.5; + + for ( i = 0 ; i < p->width ; i ++ ) { + p->ctrl(i, 2).xyz[0] = xc; + p->ctrl(i, 2).xyz[1] = yc; + } + } + b = AddBrushForPatch(p); + + Select_Delete(); + Select_Brush(b); +} + +patchMesh_t * Patch_GenerateGeneric( int width,int height,int orientation,const idVec3 &mins,const idVec3 &maxs ) { + patchMesh_t *p = MakeNewPatch(width, height); + p->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); + + p->type = PATCH_GENERIC; + + int nFirst = 0; + int nSecond = 1; + if ( orientation == 0 ) { + nFirst = 1; + nSecond = 2; + } else if ( orientation == 1 ) { + nSecond = 2; + } + + + int xStep = mins[nFirst]; + float xAdj = abs((maxs[nFirst] - mins[nFirst]) / (width - 1)); + float yAdj = abs((maxs[nSecond] - mins[nSecond]) / (height - 1)); + + for ( int i = 0; i < width; i++ ) { + int yStep = mins[nSecond]; + for ( int j = 0; j < height; j++ ) { + p->ctrl(i, j).xyz[nFirst] = xStep; + p->ctrl(i, j).xyz[nSecond] = yStep; + p->ctrl(i, j).xyz[orientation] = g_qeglobals.d_new_brush_bottom[orientation]; + yStep += yAdj; + } + xStep += xAdj; + } + + return p; +} + +/* +================== +Patch_GenericMesh +================== +*/ +brush_t * Patch_GenericMesh( int width,int height,int orientation,bool bDeleteSource,bool bOverride,patchMesh_t *parent ) { + if ( height < 3 || height> 15 || width < 3 || width> 15 ) { + Sys_Status("Invalid patch width or height.\n"); + return NULL; + } + + if ( !bOverride && !QE_SingleBrush() ) { + Sys_Status("Cannot generate a patch from multiple selections.\n"); + return NULL; + } + + brush_t *b = selected_brushes.next; + + patchMesh_t *p = Patch_GenerateGeneric(width, height, orientation, b->mins, b->maxs); + + if ( parent ) { + p->explicitSubdivisions = parent->explicitSubdivisions; + p->horzSubdivisions = parent->horzSubdivisions; + p->vertSubdivisions = parent->vertSubdivisions; + } + + Patch_Naturalize(p); + + b = AddBrushForPatch(p); + + if ( bDeleteSource ) { + Select_Delete(); + Select_Brush(b); + } + + return b; +} + +/* +================== +PointInMoveList +================== +*/ +int PointInMoveList( idVec3 *pf ) { + for ( int i = 0; i < g_qeglobals.d_num_move_points; i++ ) { + if ( pf == g_qeglobals.d_move_points[i] ) { + return i; + } + } + return -1; +} + +/* +================== +PointValueInMoveList +================== +*/ +static int PointValueInMoveList( idVec3 v ) { + for ( int i = 0; i < g_qeglobals.d_num_move_points; i++ ) { + if ( v.Compare(*g_qeglobals.d_move_points[i]) ) { + return i; + } + } + return -1; +} + +/* +================== +RemovePointFromMoveList +================== +*/ +void RemovePointFromMoveList( idVec3 v ) { + int n; + while ( (n = PointValueInMoveList(v)) >= 0 ) { + for ( int i = n; i < g_qeglobals.d_num_move_points - 1; i++ ) { + g_qeglobals.d_move_points[i] = g_qeglobals.d_move_points[i + 1]; + } + g_qeglobals.d_num_move_points--; + } +} + +/* +================== +ColumnSelected +================== +*/ +bool ColumnSelected( patchMesh_t *p,int nCol ) { + for ( int i = 0; i < p->height; i++ ) { + if ( PointInMoveList(&p->ctrl(nCol, i).xyz) == -1 ) { + return false; + } + } + return true; +} + + +/* +================== +AddPoint +================== +*/ +static void AddPoint( patchMesh_t *p,idVec3 *v,bool bWeldOrDrill = true ) { + int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0; + int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2; + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = v; + if ( (g_bPatchWeld || g_bPatchDrillDown) && bWeldOrDrill ) { + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + if ( g_bPatchWeld ) { + if ( (*v).Compare(p->ctrl(i, j).xyz) && PointInMoveList(&p->ctrl(i, j).xyz) == -1 ) { + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &p->ctrl(i, j).xyz; + continue; + } + } + if ( g_bPatchDrillDown && g_nPatchClickedView != W_CAMERA ) { + if ( (idMath::Fabs((*v)[nDim1] - p->ctrl(i, j).xyz[nDim1]) <= VECTOR_EPSILON) && (idMath::Fabs((*v)[nDim2] - p->ctrl(i, j).xyz[nDim2]) <= VECTOR_EPSILON) ) { + if ( PointInMoveList(&p->ctrl(i, j).xyz) == -1 ) { + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &p->ctrl(i, j).xyz; + continue; + } + } +#if 0 + int l = 0; + for ( int k = 0; k < 2; k++ ) { + if (idMath::Fabs(v[k] - p->ctrl(i,j).xyz[k]) > VECTOR_EPSILON) + continue; + l++; + } + if (l >= 2 && PointInMoveList(&p->ctrl(i,j).xyz) == -1) { + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = p->ctrl(i,j).xyz; + continue; + } +#endif + } + } + } + } +#if 0 + if (g_qeglobals.d_num_move_points == 1) { + // single point selected + // FIXME: the two loops can probably be reduced to one + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + int n = PointInMoveList(v); + if (n >= 0) { + if (((i & 0x01) && (j & 0x01)) == 0) { + // put any sibling fixed points + // into the inverse list + int p1, p2, p3, p4; + p1 = i + 2; + p2 = i - 2; + p3 = j + 2; + p4 = j - 2; + if (p1 < p->width) { + + } + if (p2 >= 0) { + } + if (p3 < p->height) { + } + if (p4 >= 0) { + } + } + } + } + } + } +#endif +} + +/* +================== +SelectRow +================== +*/ +void SelectRow( patchMesh_t *p,int nRow,bool bMulti ) { + if ( !bMulti ) { + g_qeglobals.d_num_move_points = 0; + } + for ( int i = 0; i < p->width; i++ ) { + AddPoint(p, &p->ctrl(i, nRow).xyz, false); + } + //common->Printf("Selected Row %d\n", nRow); +} + +/* +================== +SelectColumn +================== +*/ +void SelectColumn( patchMesh_t *p,int nCol,bool bMulti ) { + if ( !bMulti ) { + g_qeglobals.d_num_move_points = 0; + } + for ( int i = 0; i < p->height; i++ ) { + AddPoint(p, &p->ctrl(nCol, i).xyz, false); + } + //common->Printf("Selected Col %d\n", nCol); +} + + +/* +================== +AddPatchMovePoint +================== +*/ +void AddPatchMovePoint( idVec3 v,bool bMulti,bool bFull ) { + if ( !g_bSameView && !bMulti && !bFull ) { + g_bSameView = true; + return; + } + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + if ( v.Compare(p->ctrl(i, j).xyz) ) { + if ( PointInMoveList(&p->ctrl(i, j).xyz) == -1 ) { + if ( bFull ) // if we want the full row/col this is on + { + SelectColumn(p, i, bMulti); + } else { + if ( !bMulti ) + g_qeglobals.d_num_move_points = 0; + AddPoint(p, &p->ctrl(i, j).xyz); + //common->Printf("Selected col:row %d:%d\n", i, j); + } + //--if (!bMulti) + return; + } else { + if ( bFull ) { + if ( ColumnSelected(p, i) ) { + SelectRow(p, j, bMulti); + } else { + SelectColumn(p, i, bMulti); + } + return; + } + if ( g_bSameView ) { + RemovePointFromMoveList(v); + return; + } + } + } + } + } + } + } +} +/* +================== +Patch_UpdateSelected +================== +*/ +void Patch_UpdateSelected( idVec3 vMove ) { + int i, j; + for ( i = 0 ; i < g_qeglobals.d_num_move_points ; i++ ) { + VectorAdd(*g_qeglobals.d_move_points[i], vMove, *g_qeglobals.d_move_points[i]); + if ( g_qeglobals.d_num_move_points == 1 ) { + } + } + + //--patchMesh_t* p = &patchMeshes[g_nSelectedPatch]; + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + + + g_qeglobals.d_numpoints = 0; + for ( i = 0 ; i < p->width ; i++ ) { + for ( j = 0 ; j < p->height ; j++ ) { + VectorCopy(p->ctrl(i, j).xyz, g_qeglobals.d_points[g_qeglobals.d_numpoints]); + if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) { + g_qeglobals.d_numpoints++; + } + } + } + + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + } + } + //Brush_Free(p->pSymbiot); + //Select_Brush(AddBrushForPatch(g_nSelectedPatch)); +} + + +void Patch_AdjustSubdivisions( float hadj,float vadj ) { + brush_t *pb; + for ( pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + p->horzSubdivisions += hadj; + p->vertSubdivisions += vadj; + Patch_MakeDirty(p); + } + } + Sys_UpdateWindows(W_ALL); +} + +extern float ShadeForNormal( idVec3 normal ); + +/* +================= +DrawPatchMesh +================= +*/ +//FIXME: this routine needs to be reorganized.. should be about 1/4 the size and complexity +void DrawPatchMesh( patchMesh_t *pm,bool bPoints,int *list,bool bShade = false ) { + int i, j; + + bool bOverlay = pm->bOverlay; + int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode; + + // patches use two display lists, one for camera one for xy + if ( *list <= 0 ) { + if ( *list <= 0 ) { + *list = qglGenLists(1); + } + + if ( *list > 0 ) { + qglNewList(*list, GL_COMPILE_AND_EXECUTE); + } + + //FIXME: finish consolidating all the patch crap + idSurface_Patch *cp = new idSurface_Patch(pm->width * 6, pm->height * 6); + cp->SetSize(pm->width, pm->height); + for ( i = 0; i < pm->width; i++ ) { + for ( j = 0; j < pm->height; j++ ) { + (*cp)[j * cp->GetWidth() + i].xyz = pm->ctrl(i, j).xyz; + (*cp)[j * cp->GetWidth() + i].st = pm->ctrl(i, j).st; + } + } + + if ( pm->explicitSubdivisions ) { + cp->SubdivideExplicit(pm->horzSubdivisions, pm->vertSubdivisions, true); + } else { + cp->Subdivide(DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_ERROR, DEFAULT_CURVE_MAX_LENGTH, true); + } + + + int width = cp->GetWidth(); + int height = cp->GetHeight(); + /* + for (i = 0; i < width; i++) { + for (j = 0; j < height; j++) { + qglBegin(GL_POINTS); + int index = j * width + i; + qglVertex3fv((*cp)[index].xyz); + qglEnd(); + char msg[64]; + sprintf(msg, "(%0.3f, %0.3f, %0.3f)(%0.3f, %0.3f)", (*cp)[index].xyz.x, (*cp)[index].xyz.y, (*cp)[index].xyz.z, (*cp)[index].st.x, (*cp)[index].st.y); + qglRasterPos3f((*cp)[index].xyz.x + 1, (*cp)[index].xyz.y + 1, (*cp)[index].xyz.z + 1); + qglCallLists (strlen(msg), GL_UNSIGNED_BYTE, msg); + } + } + */ +#ifdef TEST_SURFACE_CLIPPING + int n; + idSurface *surf = cp; + idSurface *front, *back; + + surf->Split(idPlane(1, 0, 0, 0), 0.1f, &front, &back); + if ( front && back ) { + front->TranslateSelf(idVec3(10, 10, 10)); + (*front) += (*back); + surf = front; + } else { + surf = cp; + } + // surf->ClipInPlace( idPlane( 1, 0, 0, 0 ), 0.1f, true ); + + qglBegin(GL_TRIANGLES); + for ( i = 0; i < surf->GetNumIndexes(); i += 3 ) { + n = surf->GetIndexes()[i + 0]; + qglTexCoord2fv((*surf)[n].st.ToFloatPtr()); + qglVertex3fv((*surf)[n].xyz.ToFloatPtr()); + n = surf->GetIndexes()[i + 1]; + qglTexCoord2fv((*surf)[n].st.ToFloatPtr()); + qglVertex3fv((*surf)[n].xyz.ToFloatPtr()); + n = surf->GetIndexes()[i + 2]; + qglTexCoord2fv((*surf)[n].st.ToFloatPtr()); + qglVertex3fv((*surf)[n].xyz.ToFloatPtr()); + } + qglEnd(); + + if ( front ) { + delete front; + } + if ( back ) { + delete back; + } +#else + for ( i = 0 ; i < width - 1; i++ ) { + qglBegin(GL_QUAD_STRIP); + for ( j = 0 ; j < height; j++ ) { + // v1-v2-v3-v4 makes a quad + int v1, v2; + float f; + v1 = j * width + i; + v2 = v1 + 1; + if ( bShade ) { + f = ShadeForNormal((*cp)[v2].normal); + qglColor3f(f, f, f); + } + qglTexCoord2fv((*cp)[v2].st.ToFloatPtr()); + qglVertex3fv((*cp)[v2].xyz.ToFloatPtr()); + if ( bShade ) { + f = ShadeForNormal((*cp)[v1].normal); + qglColor3f(f, f, f); + } + qglTexCoord2fv((*cp)[v1].st.ToFloatPtr()); + qglVertex3fv((*cp)[v1].xyz.ToFloatPtr()); + } + qglEnd(); + } +#endif + + if ( list == &pm->nListSelected ) { + globalImages->BindNull(); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + qglColor3f(1.0f, 1.0f, 1.0f); + for ( i = 0 ; i < width - 1; i++ ) { + qglBegin(GL_QUAD_STRIP); + for ( j = 0 ; j < height; j++ ) { + int v1, v2; + v1 = j * width + i; + v2 = v1 + 1; + qglVertex3fv((*cp)[v2].xyz.ToFloatPtr()); + qglVertex3fv((*cp)[v1].xyz.ToFloatPtr()); + } + qglEnd(); + } + } + + delete cp; + + if ( *list > 0 ) { + qglEndList(); + } + } else { + qglCallList(*list); + } + + idVec3 *pSelectedPoints[256]; + int nIndex = 0; + + // FIXME: this bend painting code needs to be rolled up significantly as it is a mess right now + if ( bPoints && (g_qeglobals.d_select_mode == sel_curvepoint || g_qeglobals.d_select_mode == sel_area || g_bPatchBendMode || g_bPatchInsertMode) ) { + bOverlay = false; + + // bending or inserting + if ( g_bPatchBendMode || g_bPatchInsertMode ) { + qglPointSize(6); + if ( g_bPatchAxisOnRow ) { + qglColor3f(1, 0, 1); + qglBegin(GL_POINTS); + for ( i = 0; i < pm->width; i++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(i, g_nPatchAxisIndex).xyz)); + } + qglEnd(); + + // could do all of this in one loop but it was pretty messy + if ( g_bPatchInsertMode ) { + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for ( i = 0; i < pm->width; i++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(i, g_nPatchAxisIndex).xyz)); + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(i, g_nPatchAxisIndex + 1).xyz)); + } + qglEnd(); + } else { + if ( g_nPatchBendState == BEND_SELECT_EDGE || g_nPatchBendState == BEND_BENDIT || g_nPatchBendState == BEND_SELECT_ORIGIN ) { + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + if ( g_nPatchBendState == BEND_SELECT_ORIGIN ) { + qglVertex3fv(g_vBendOrigin.ToFloatPtr()); + } else { + for ( i = 0; i < pm->width; i++ ) { + if ( g_bPatchLowerEdge ) { + for ( j = 0; j < g_nPatchAxisIndex; j++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(i, j).xyz)); + } + } else { + for ( j = pm->height - 1; j > g_nPatchAxisIndex; j-- ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(i, j).xyz)); + } + } + } + } + qglEnd(); + } + } + } else { + qglColor3f(1, 0, 1); + qglBegin(GL_POINTS); + for ( i = 0; i < pm->height; i++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(g_nPatchAxisIndex, i).xyz)); + } + qglEnd(); + + // could do all of this in one loop but it was pretty messy + if ( g_bPatchInsertMode ) { + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for ( i = 0; i < pm->height; i++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(g_nPatchAxisIndex, i).xyz)); + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(g_nPatchAxisIndex + 1, i).xyz)); + } + qglEnd(); + } else { + if ( g_nPatchBendState == BEND_SELECT_EDGE || g_nPatchBendState == BEND_BENDIT || g_nPatchBendState == BEND_SELECT_ORIGIN ) { + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for ( i = 0; i < pm->height; i++ ) { + if ( g_nPatchBendState == BEND_SELECT_ORIGIN ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(g_nBendOriginIndex, i).xyz)); + } else { + if ( g_bPatchLowerEdge ) { + for ( j = 0; j < g_nPatchAxisIndex; j++ ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(j, i).xyz)); + } + } else { + for ( j = pm->width - 1; j > g_nPatchAxisIndex; j-- ) { + qglVertex3fv(reinterpret_cast< float(*)>(&pm->ctrl(j, i).xyz)); + } + } + } + } + qglEnd(); + } + } + } + } else { + qglPointSize(6); + for ( i = 0 ; i < pm->width ; i++ ) { + for ( j = 0 ; j < pm->height ; j++ ) { + qglBegin(GL_POINTS); + // FIXME: need to not do loop lookups inside here + int n = PointValueInMoveList(pm->ctrl(i, j).xyz); + if ( n >= 0 ) { + pSelectedPoints[nIndex++] = &pm->ctrl(i, j).xyz; + } + + if ( i & 0x01 || j & 0x01 ) { + qglColor3f(1, 0, 1); + } else { + qglColor3f(0, 1, 0); + } + qglVertex3fv(pm->ctrl(i, j).xyz.ToFloatPtr()); + qglEnd(); + } + } + } + + if ( nIndex > 0 ) { + qglBegin(GL_POINTS); + qglColor3f(0, 0, 1); + while ( nIndex-- > 0 ) { + qglVertex3fv((*pSelectedPoints[nIndex]).ToFloatPtr()); + } + qglEnd(); + } + } + if ( bOverlay ) { + qglPointSize(6); + qglColor3f(0.5, 0.5, 0.5); + for ( i = 0 ; i < pm->width ; i++ ) { + qglBegin(GL_POINTS); + for ( j = 0 ; j < pm->height ; j++ ) { + if ( i & 0x01 || j & 0x01 ) { + qglColor3f(0.5, 0, 0.5); + } else { + qglColor3f(0, 0.5, 0); + } + qglVertex3fv(pm->ctrl(i, j).xyz.ToFloatPtr()); + } + qglEnd(); + } + } +} + +/* +================== +Patch_DrawXY +================== +*/ +void Patch_DrawXY( patchMesh_t *pm ) { + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if ( pm->bSelected ) { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); + //qglDisable (GL_LINE_STIPPLE); + //qglLineWidth (1); + } else { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES].ToFloatPtr()); + } + + DrawPatchMesh(pm, pm->bSelected, &pm->nListID); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if ( pm->bSelected ) { + //qglLineWidth (2); + //qglEnable (GL_LINE_STIPPLE); + } +} + +/* +================== +Patch_DrawCam +================== +*/ +void Patch_DrawCam( patchMesh_t *pm,bool selected ) { + + int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode; + + if ( !selected ) { + qglColor3f(1, 1, 1); + } + + if ( g_bPatchWireFrame || nDrawMode == cd_wire ) { + qglDisable(GL_CULL_FACE); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + globalImages->BindNull(); + DrawPatchMesh(pm, pm->bSelected, &pm->nListIDCam, true); + qglEnable(GL_CULL_FACE); + } else { + qglEnable(GL_CULL_FACE); + qglCullFace(GL_FRONT); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + if ( nDrawMode == cd_texture || nDrawMode == cd_light ) { + pm->d_texture->GetEditorImage()->Bind(); + } + + if ( !selected && pm->d_texture->GetEditorAlpha() != 1.0f ) { + qglEnable(GL_BLEND); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + DrawPatchMesh(pm, pm->bSelected, &pm->nListIDCam, true); + + if ( !selected && pm->d_texture->GetEditorAlpha() != 1.0f ) { + qglDisable(GL_BLEND); + } + + globalImages->BindNull(); + + if ( !selected ) { + qglCullFace(GL_BACK); + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + qglDisable(GL_BLEND); + } else { + qglEnable(GL_BLEND); + qglColor4f(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0], g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1], g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2], 0.25); + qglDisable(GL_CULL_FACE); + } + DrawPatchMesh(pm, pm->bSelected, (selected) ? &pm->nListSelected : &pm->nListIDCam, !selected); + qglEnable(GL_CULL_FACE); + } + +#if 0 // this paints normal indicators on the ctrl points + //--qglDisable (GL_DEPTH_TEST); + qglColor3f (1,1,1); + for (int i = 0; i < pm->width; i++) { + for (int j = 0; j < pm->height; j++) { + idVec3 temp; + qglBegin (GL_LINES); + qglVertex3fv (pm->ctrl(i,j).xyz); + VectorMA (pm->ctrl(i,j).xyz, 8, pm->ctrl(i,j].normal, temp); + qglVertex3fv (temp); + qglEnd (); + } + } + //--qglEnable (GL_DEPTH_TEST); +#endif + +} + + + + +void ConvexHullForSection( float section[2][4][7] ) { +} + +void BrushesForSection( float section[2][4][7] ) { +} + + +/* +================== +Patch_Move +================== +*/ +void Patch_Move( patchMesh_t *pm,const idVec3 vMove,bool bRebuild ) { + Patch_MakeDirty(pm); + for ( int w = 0; w < pm->width; w++ ) { + for ( int h = 0; h < pm->height; h++ ) { + VectorAdd(pm->ctrl(w, h).xyz, vMove, pm->ctrl(w, h).xyz); + } + } + if ( bRebuild ) { + idVec3 vMin, vMax; + Patch_CalcBounds(pm, vMin, vMax); + //Brush_RebuildBrush(patchMeshes[n].pSymbiot, vMin, vMax); + } + UpdatePatchInspector(); +} + +/* +================== +Patch_ApplyMatrix +================== +*/ +void Patch_ApplyMatrix( patchMesh_t *p,const idVec3 vOrigin,const idMat3 matrix,bool bSnap ) { + idVec3 vTemp; + + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + if ( (g_qeglobals.d_select_mode == sel_curvepoint || g_bPatchBendMode) && PointInMoveList(&p->ctrl(w, h).xyz) == -1 ) { + continue; + } + vTemp = p->ctrl(w, h).xyz - vOrigin; + vTemp *= matrix; + p->ctrl(w, h).xyz = vTemp + vOrigin; + } + } + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); +} + +/* +================== +Patch_EditPatch +================== +*/ +void Patch_EditPatch() { + //--patchMesh_t* p = &patchMeshes[n]; + g_qeglobals.d_numpoints = 0; + g_qeglobals.d_num_move_points = 0; + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + VectorCopy(p->ctrl(i, j).xyz, g_qeglobals.d_points[g_qeglobals.d_numpoints]); + if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) { + g_qeglobals.d_numpoints++; + } + } + } + } + } + g_qeglobals.d_select_mode = sel_curvepoint; + //--g_nSelectedPatch = n; +} + + + +/* +================== +Patch_Deselect +================== +*/ +//FIXME: need all sorts of asserts throughout a lot of this crap +void Patch_Deselect() { + //--g_nSelectedPatch = -1; + g_qeglobals.d_select_mode = sel_brush; + + for ( brush_t*b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) { + if ( b->pPatch ) { + b->pPatch->bSelected = false; + } + } + + if ( g_bPatchBendMode ) { + Patch_BendToggle(); + } + + if ( g_bPatchInsertMode ) { + Patch_InsDelToggle(); + } +} + + +/* +================== +Patch_Select +================== +*/ +void Patch_Select( patchMesh_t *p ) { + // maintained for point manip.. which i need to fix as this + // is pf error prone + //--g_nSelectedPatch = n; + p->bSelected = true; +} + + +/* +================== +Patch_Deselect +================== +*/ +void Patch_Deselect( patchMesh_t *p ) { + p->bSelected = false; +} + + +/* +================== +Patch_Delete +================== +*/ +void Patch_Delete( patchMesh_t *p ) { + if ( p->pSymbiot ) { + p->pSymbiot->pPatch = NULL; + } + + Mem_Free(p->verts); + if ( p->epairs ) { + delete p->epairs; + } + Mem_Free(p); + + p = NULL; + + UpdatePatchInspector(); +} + + +/* +================== +Patch_Scale +================== +*/ +void Patch_Scale( patchMesh_t *p,const idVec3 vOrigin,const idVec3 vAmt,bool bRebuild ) { + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + if ( g_qeglobals.d_select_mode == sel_curvepoint && PointInMoveList(&p->ctrl(w, h).xyz) == -1 ) + continue; + for ( int i = 0 ; i < 3 ; i++ ) { + p->ctrl(w, h).xyz[i] -= vOrigin[i]; + p->ctrl(w, h).xyz[i] *= vAmt[i]; + p->ctrl(w, h).xyz[i] += vOrigin[i]; + } + } + } + if ( bRebuild ) { + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + } + UpdatePatchInspector(); +} + + +/* +================== +Patch_Cleanup +================== +*/ +void Patch_Cleanup() { + //--g_nSelectedPatch = -1; + //numPatchMeshes = 0; +} + + + +/* +================== +Patch_SetView +================== +*/ +void Patch_SetView( int n ) { + g_bSameView = (n == g_nPatchClickedView); + g_nPatchClickedView = n; +} + + +/* +================== +Patch_SetTexture +================== +*/ +// FIXME: need array validation throughout +void Patch_SetTexture( patchMesh_t *p,texdef_t *tex_def ) { + p->d_texture = Texture_ForName(tex_def->name); + UpdatePatchInspector(); +} + +/* +================== +Patch_SetTexture +================== +*/ +// FIXME: need array validation throughout +void Patch_SetTextureName( patchMesh_t *p,const char *name ) { + p->d_texture = Texture_ForName(name); + UpdatePatchInspector(); +} + + +/* +================== +Patch_DragScale +================== +*/ +bool Patch_DragScale( patchMesh_t *p,idVec3 vAmt,idVec3 vMove ) { + idVec3 vMin, vMax, vScale, vTemp, vMid; + int i; + + Patch_CalcBounds(p, vMin, vMax); + + VectorSubtract(vMax, vMin, vTemp); + + // if we are scaling in the same dimension the patch has no depth + for ( i = 0; i < 3; i ++ ) { + if ( vTemp[i] == 0 && vMove[i] != 0 ) { + //Patch_Move(n, vMove, true); + return false; + } + } + + for ( i = 0 ; i < 3 ; i++ ) + vMid[i] = (vMin[i] + ((vMax[i] - vMin[i]) / 2)); + + for ( i = 0; i < 3; i++ ) { + if ( vAmt[i] != 0 ) { + vScale[i] = 1.0f + vAmt[i] / vTemp[i]; + } else { + vScale[i] = 1.0f; + } + } + + Patch_Scale(p, vMid, vScale, false); + + VectorSubtract(vMax, vMin, vTemp); + + Patch_CalcBounds(p, vMin, vMax); + + VectorSubtract(vMax, vMin, vMid); + + VectorSubtract(vMid, vTemp, vTemp); + + VectorScale(vTemp, 0.5, vTemp); + + // abs of both should always be equal + if ( !vMove.Compare(vAmt) ) { + for ( i = 0; i < 3; i++ ) { + if ( vMove[i] != vAmt[i] ) { + vTemp[i] = -(vTemp[i]); + } + } + } + + Patch_Move(p, vTemp); + return true; +} + + +/* +================== +Patch_InsertColumn +================== +*/ +void Patch_InsertColumn( patchMesh_t *p,bool bAdd ) { + int h, w, i, j; + idVec3 vTemp; + + if ( p->width + 2 >= MAX_PATCH_WIDTH ) { + return; + } + + Patch_AdjustSize(p, 2, 0); + + // re-adjust til after routine + //p->width -= 2; + + if ( bAdd ) { + // add column? + for ( h = 0; h < p->height; h++ ) { + j = p->width - 3; + + VectorSubtract(p->ctrl(j, h).xyz, p->ctrl(j - 1, h).xyz, vTemp); + + for ( i = 0; i < 3; i++ ) { + vTemp[i] /= 3; + } + + memcpy(&p->ctrl(j + 2, h), &p->ctrl(j, h), sizeof(idDrawVert)); + memcpy(&p->ctrl(j, h), &p->ctrl(j - 1, h), sizeof(idDrawVert)); + + VectorAdd(p->ctrl(j, h).xyz, vTemp, p->ctrl(j, h).xyz); + memcpy(&p->ctrl(j + 1, h), &p->ctrl(j, h), sizeof(idDrawVert)); + VectorAdd(p->ctrl(j + 1, h).xyz, vTemp, p->ctrl(j + 1, h).xyz); + } + } else { + for ( h = 0; h < p->height; h++ ) { + w = p->width - 3; + while ( w >= 0 ) { + memcpy(&p->ctrl(w + 2, h), &p->ctrl(w, h), sizeof(idDrawVert)); + w--; + } + VectorSubtract(p->ctrl(1, h).xyz, p->ctrl(0, h).xyz, vTemp); + for ( i = 0; i < 3; i++ ) { + vTemp[i] /= 3; + } + VectorCopy(p->ctrl(0, h).xyz, p->ctrl(1, h).xyz); + VectorAdd(p->ctrl(1, h).xyz, vTemp, p->ctrl(1, h).xyz); + VectorCopy(p->ctrl(1, h).xyz, p->ctrl(2, h).xyz); + VectorAdd(p->ctrl(2, h).xyz, vTemp, p->ctrl(2, h).xyz); + } + } + //p->width += 2; + UpdatePatchInspector(); +} + + +/* +================== +Patch_InsertRow +================== +*/ +void Patch_InsertRow( patchMesh_t *p,bool bAdd ) { + int h, w, i, j; + idVec3 vTemp; + + if ( p->height + 2 >= MAX_PATCH_HEIGHT ) { + return; + } + + Patch_AdjustSize(p, 0, 2); + + if ( bAdd ) { + // add column? + for ( w = 0; w < p->width; w++ ) { + j = p->height - 3; + VectorSubtract(p->ctrl(w, j).xyz, p->ctrl(w, j - 1).xyz, vTemp); + for ( i = 0; i < 3; i++ ) { + vTemp[i] /= 3; + } + + memcpy(&p->ctrl(w, j + 2), &p->ctrl(w, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(w, j), &p->ctrl(w, j - 1), sizeof(idDrawVert)); + + VectorAdd(p->ctrl(w, j).xyz, vTemp, p->ctrl(w, j).xyz); + memcpy(&p->ctrl(w, j + 1), &p->ctrl(w, j), sizeof(idDrawVert)); + VectorAdd(p->ctrl(w, j + 1).xyz, vTemp, p->ctrl(w, j + 1).xyz); + } + } else { + for ( w = 0; w < p->width; w++ ) { + h = p->height - 3; + while ( h >= 0 ) { + memcpy(&p->ctrl(w, h + 2), &p->ctrl(w, h), sizeof(idDrawVert)); + h--; + } + VectorSubtract(p->ctrl(w, 1).xyz, p->ctrl(w, 0).xyz, vTemp); + for ( i = 0; i < 3; i++ ) { + vTemp[i] /= 3; + } + + VectorCopy(p->ctrl(w, 0).xyz, p->ctrl(w, 1).xyz); + VectorAdd(p->ctrl(w, 1).xyz, vTemp, p->ctrl(w, 1).xyz); + VectorCopy(p->ctrl(w, 1).xyz, p->ctrl(w, 2).xyz); + VectorAdd(p->ctrl(w, 2).xyz, vTemp, p->ctrl(w, 2).xyz); + } + } + + UpdatePatchInspector(); +} + + +/* +================== +Patch_RemoveRow +================== +*/ +void Patch_RemoveRow( patchMesh_t *p,bool bFirst ) { + if ( p->height <= MIN_PATCH_HEIGHT ) { + return; + } + + if ( bFirst ) { + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height - 2; h++ ) { + memcpy(&p->ctrl(w, h), &p->ctrl(w, h + 2), sizeof(idDrawVert)); + } + } + } + + Patch_AdjustSize(p, 0, -2); + + UpdatePatchInspector(); +} + + +/* +================== +Patch_RemoveColumn +================== +*/ +void Patch_RemoveColumn( patchMesh_t *p,bool bFirst ) { + if ( p->width <= MIN_PATCH_WIDTH ) { + return; + } + + if ( bFirst ) { + for ( int h = 0; h < p->height; h++ ) { + for ( int w = 0; w < p->width - 2; w++ ) { + memcpy(&p->ctrl(w, h), &p->ctrl(w + 2, h), sizeof(idDrawVert)); + } + } + } + + Patch_AdjustSize(p, -2, 0); + + UpdatePatchInspector(); +} + + +void Patch_DisperseRows() { + idVec3 vTemp, vTemp2; + int i, w, h; + + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + Patch_Rebuild(p); + for ( w = 0; w < p->width; w++ ) { + // for each row, we need to evenly disperse p->height number + // of points across the old bounds + + // calc total distance to interpolate + VectorSubtract(p->ctrl(w, p->height - 1).xyz, p->ctrl(w, 0).xyz, vTemp); + + //vTemp[0] = vTemp[1] = vTemp[2] = 0; + //for (h = 0; h < p->height - nRows; h ++) + //{ + // VectorAdd(vTemp, p->ctrl(w,h], vTemp); + //} + + // amount per cycle + for ( i = 0; i < 3; i ++ ) { + vTemp2[i] = vTemp[i] / (p->height - 1); + } + + // move along + for ( h = 0; h < p->height - 1; h++ ) { + VectorAdd(p->ctrl(w, h).xyz, vTemp2, p->ctrl(w, h + 1).xyz); + } + Patch_Naturalize(p); + } + } + } + UpdatePatchInspector(); +} + +/* +================== +Patch_AdjustColumns +================== +*/ +void Patch_DisperseColumns() { + idVec3 vTemp, vTemp2; + int i, w, h; + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + Patch_Rebuild(p); + + for ( h = 0; h < p->height; h++ ) { + // for each column, we need to evenly disperse p->width number + // of points across the old bounds + + // calc total distance to interpolate + VectorSubtract(p->ctrl(p->width - 1, h).xyz, p->ctrl(0, h).xyz, vTemp); + + // amount per cycle + for ( i = 0; i < 3; i ++ ) { + vTemp2[i] = vTemp[i] / (p->width - 1); + } + + // move along + for ( w = 0; w < p->width - 1; w++ ) { + VectorAdd(p->ctrl(w, h).xyz, vTemp2, p->ctrl(w + 1, h).xyz); + } + } + Patch_Naturalize(p); + } + } + UpdatePatchInspector(); +} + + + +/* +================== +Patch_AdjustSelected +================== +*/ +void Patch_AdjustSelected( bool bInsert,bool bColumn,bool bFlag ) { + bool bUpdate = false; + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + if ( bInsert ) { + if ( bColumn ) { + Patch_InsertColumn(pb->pPatch, bFlag); + } else { + Patch_InsertRow(pb->pPatch, bFlag); + } + } else { + if ( bColumn ) { + Patch_RemoveColumn(pb->pPatch, bFlag); + } else { + Patch_RemoveRow(pb->pPatch, bFlag); + } + } + bUpdate = true; + idVec3 vMin, vMax; + patchMesh_t *p = pb->pPatch; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + } + } + if ( bUpdate ) { + Sys_UpdateWindows(W_ALL); + } +} + +void Parse1DMatrix( int x,float *p ) { + GetToken(true); // ( + for ( int i = 0; i < x; i++ ) { + GetToken(false); + p[i] = atof(token); + } + GetToken(true); // ) +} + +void Parse2DMatrix( int y,int x,float *p ) { + GetToken(true); // ( + for ( int i = 0; i < y; i++ ) { + Parse1DMatrix(x, p + i * x); + } + GetToken(true); // ) +} + +void Parse3DMatrix( int z,int y,int x,float *p ) { + GetToken(true); // ( + for ( int i = 0; i < z; i++ ) { + Parse2DMatrix(y, x, p + i * (x * MAX_PATCH_HEIGHT)); + } + GetToken(true); // ) +} + +// parses a patch +brush_t * Patch_Parse( bool bOld ) { + const idMaterial *tex = declManager->FindMaterial(NULL); + GetToken(true); + + if ( strcmp(token, "{") ) { + return NULL; + } + + patchMesh_t *pm = NULL; + + if ( g_qeglobals.bSurfacePropertiesPlugin ) { + assert(true); + //GETPLUGINTEXDEF(pm)->ParsePatchTexdef(); + } else { + // texture def + GetToken(true); + + // band-aid + if ( strcmp(token, "(") ) { + if ( g_qeglobals.mapVersion < 2.0f ) { + tex = Texture_ForName(va("textures/%s", token)); + } else { + tex = Texture_ForName(token); + } + GetToken(true); + } else { + common->Printf("Warning: Patch read with no texture, using notexture... \n"); + } + + if ( strcmp(token, "(") ) { + return NULL; + } + + // width, height, flags (currently only negative) + GetToken(false); + int width = atoi(token); + + GetToken(false); + int height = atoi(token); + + pm = MakeNewPatch(width, height); + pm->d_texture = tex; + + if ( !bOld ) { + GetToken(false); + pm->horzSubdivisions = atoi(token); + GetToken(false); + pm->vertSubdivisions = atoi(token); + pm->explicitSubdivisions = true; + } + + GetToken(false); + pm->contents = atoi(token); + + GetToken(false); + pm->flags = atoi(token); + + GetToken(false); + pm->value = atoi(token); + + //if (!bOld) + //{ + // GetToken(false); + // pm->type = atoi(token); + //} + + GetToken(false); + if ( strcmp(token, ")") ) + return NULL; + } + + + + float ctrl[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT][5]; + Parse3DMatrix(pm->width, pm->height, 5, reinterpret_cast< float*>(&ctrl)); + + int w, h; + + for ( w = 0; w < pm->width; w++ ) { + for ( h = 0; h < pm->height; h++ ) { + pm->ctrl(w, h).xyz[0] = ctrl[w][h][0]; + pm->ctrl(w, h).xyz[1] = ctrl[w][h][1]; + pm->ctrl(w, h).xyz[2] = ctrl[w][h][2]; + pm->ctrl(w, h).st[0] = ctrl[w][h][3]; + pm->ctrl(w, h).st[1] = ctrl[w][h][4]; + } + } + + GetToken(true); + + if ( g_qeglobals.m_bBrushPrimitMode ) { + // we are in brush primit mode, but maybe it's a classic patch that needs converting, test "}" + if ( strcmp(token, "}") && strcmp(token, "(") ) { + ParseEpair(pm->epairs); + GetToken(true); + } + } + + if ( strcmp(token, "}") ) { + return NULL; + } + + brush_t *b = AddBrushForPatch(pm, false); + + return b; +} + + +/* +================== +Patch_Write +================== +*/ +void Patch_Write( patchMesh_t *p,CMemFile *file ) { + if ( g_qeglobals.bSurfacePropertiesPlugin ) { + common->Printf("WARNING: Patch_Write to a CMemFile and Surface Properties plugin not done\n"); + } + + if ( p->explicitSubdivisions ) { + MemFile_fprintf(file, " {\n patchDef3\n {\n"); + MemFile_fprintf(file, " \"%s\"\n", p->d_texture->GetName()); + MemFile_fprintf(file, " ( %i %i %i %i %i %i %i ) \n", p->width, p->height, p->horzSubdivisions, p->vertSubdivisions, p->contents, p->flags, p->value); + } else { + MemFile_fprintf(file, " {\n patchDef2\n {\n"); + MemFile_fprintf(file, " \"%s\"\n", p->d_texture->GetName()); + MemFile_fprintf(file, " ( %i %i %i %i %i ) \n", p->width, p->height, p->contents, p->flags, p->value); + } + + + float ctrl[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT][5]; + + int w, h; + for ( w = 0; w < p->width; w++ ) { + for ( h = 0; h < p->height; h++ ) { + ctrl[w][h][0] = p->ctrl(w, h).xyz[0]; + ctrl[w][h][1] = p->ctrl(w, h).xyz[1]; + ctrl[w][h][2] = p->ctrl(w, h).xyz[2]; + ctrl[w][h][3] = p->ctrl(w, h).st[0]; + ctrl[w][h][4] = p->ctrl(w, h).st[1]; + } + } + + _Write3DMatrix(file, p->width, p->height, 5, reinterpret_cast< float*>(&ctrl)); + + if ( g_qeglobals.m_bBrushPrimitMode ) { + if ( p->epairs ) { + int count = p->epairs->GetNumKeyVals(); + for ( int i = 0; i < count; i++ ) { + MemFile_fprintf(file, "\"%s\" \"%s\"\n", p->epairs->GetKeyVal(i)->GetKey().c_str(), p->epairs->GetKeyVal(i)->GetValue().c_str()); + } + } + } + + MemFile_fprintf(file, " }\n }\n"); +} + +void Patch_Write( patchMesh_t *p,FILE *file ) { + if ( p->explicitSubdivisions ) { + fprintf(file, " {\n patchDef3\n {\n"); + fprintf(file, " \"%s\"\n", p->d_texture->GetName()); + fprintf(file, " ( %i %i %i %i %i %i %i ) \n", p->width, p->height, p->horzSubdivisions, p->vertSubdivisions, p->contents, p->flags, p->value); + } else { + fprintf(file, " {\n patchDef2\n {\n"); + fprintf(file, " \"%s\"\n", p->d_texture->GetName()); + fprintf(file, " ( %i %i %i %i %i ) \n", p->width, p->height, p->contents, p->flags, p->value); + } + + float ctrl[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT][5]; + + int w, h; + for ( w = 0; w < p->width; w++ ) { + for ( h = 0; h < p->height; h++ ) { + ctrl[w][h][0] = p->ctrl(w, h).xyz[0]; + ctrl[w][h][1] = p->ctrl(w, h).xyz[1]; + ctrl[w][h][2] = p->ctrl(w, h).xyz[2]; + ctrl[w][h][3] = p->ctrl(w, h).st[0]; + ctrl[w][h][4] = p->ctrl(w, h).st[1]; + } + } + + _Write3DMatrix(file, p->width, p->height, 5, reinterpret_cast< float*>(&ctrl)); + + if ( g_qeglobals.m_bBrushPrimitMode ) { + if ( p->epairs ) { + int count = p->epairs->GetNumKeyVals(); + for ( int i = 0; i < count; i++ ) { + fprintf(file, "\"%s\" \"%s\"\n", p->epairs->GetKeyVal(i)->GetKey().c_str(), p->epairs->GetKeyVal(i)->GetValue().c_str()); + } + } + } + + fprintf(file, " }\n }\n"); +} + + +/* +================== +Patch_RotateTexture +================== +*/ +void Patch_RotateTexture( patchMesh_t *p,float fAngle ) { + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Patch_MakeDirty(p); + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + if ( g_qeglobals.d_select_mode == sel_curvepoint && PointInMoveList(&p->ctrl(w, h).xyz) == -1 ) { + continue; + } + + float x = p->ctrl(w, h).st[0]; + float y = p->ctrl(w, h).st[1]; + p->ctrl(w, h).st[0] = x * cos(DEG2RAD(fAngle)) - y * sin(DEG2RAD(fAngle)); + p->ctrl(w, h).st[1] = y * cos(DEG2RAD(fAngle)) + x * sin(DEG2RAD(fAngle)); + } + } +} + + +/* +================== +Patch_ScaleTexture +================== +*/ +void Patch_ScaleTexture( patchMesh_t *p,float fx,float fy,bool absolute ) { + if ( fx == 0 ) { + fx = 1.0f; + } + if ( fy == 0 ) { + fy = 1.0f; + } + + if ( absolute ) { + Patch_ResetTexturing(1, 1); + } + + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + if ( g_qeglobals.d_select_mode == sel_curvepoint && PointInMoveList(&p->ctrl(w, h).xyz) == -1 ) { + continue; + } + p->ctrl(w, h).st[0] *= fx; + p->ctrl(w, h).st[1] *= fy; + } + } + Patch_MakeDirty(p); +} + +/* +================== +Patch_ShiftTexture +================== +*/ +void Patch_ShiftTexture( patchMesh_t *p,float fx,float fy,bool autoAdjust ) { + //if (fx) + // fx = (fx > 0) ? 0.1 : -0.1; + //if (fy) + // fy = (fy > 0) ? 0.1 : -0.1; + + if ( autoAdjust ) { + fx /= p->d_texture->GetEditorImage()->uploadWidth; + fy /= p->d_texture->GetEditorImage()->uploadHeight; + } + + for ( int w = 0; w < p->width; w++ ) { + for ( int h = 0; h < p->height; h++ ) { + if ( g_qeglobals.d_select_mode == sel_curvepoint && PointInMoveList(&p->ctrl(w, h).xyz) == -1 ) + continue; + + p->ctrl(w, h).st[0] += fx; + p->ctrl(w, h).st[1] += fy; + } + } + Patch_MakeDirty(p); +} + +void patchInvert( patchMesh_t *p ) { + idDrawVert vertTemp; + Patch_MakeDirty(p); + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0; j < p->height / 2; j++ ) { + memcpy(&vertTemp, &p->ctrl(i, p->height - 1 - j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, p->height - 1 - j), &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &vertTemp, sizeof(idDrawVert)); + } + } +} + +/* +================== +Patch_ToggleInverted +================== +*/ +void Patch_ToggleInverted() { + bool bUpdate = false; + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + bUpdate = true; + patchInvert(pb->pPatch); + } + } + + if ( bUpdate ) { + Sys_UpdateWindows(W_ALL); + } + UpdatePatchInspector(); +} + +void Patch_FlipTexture( patchMesh_t *p,bool y ) { + idVec2 temp; + Patch_MakeDirty(p); + if ( y ) { + for ( int i = 0 ; i < p->height ; i++ ) { + for ( int j = 0; j < p->width / 2; j++ ) { + temp = p->ctrl(p->width - 1 - j, i).st; + p->ctrl(p->width - 1 - j, i).st = p->ctrl(j, i).st; + p->ctrl(j, i).st = temp; + } + } + } else { + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0; j < p->height / 2; j++ ) { + temp = p->ctrl(i, p->height - 1 - j).st; + p->ctrl(i, p->height - 1 - j).st = p->ctrl(i, j).st; + p->ctrl(i, j).st = temp; + } + } + } +} + + +/* +================== +Patch_ToggleInverted +================== +*/ +void Patch_InvertTexture( bool bY ) { + bool bUpdate = false; + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + bUpdate = true; + Patch_FlipTexture(pb->pPatch, bY); + } + } + + if ( bUpdate ) { + Sys_UpdateWindows(W_ALL); + } + + UpdatePatchInspector(); +} + + + + +/* +================== +Patch_Save +================== + Saves patch ctrl info (originally to deal with a + cancel in the surface dialog +*/ +void Patch_Save( patchMesh_t *p ) { + if ( patchSave ) { + Mem_Free(patchSave->verts); + Mem_Free(patchSave); + } + + patchSave = MakeNewPatch(p->width, p->height); + memcpy(patchSave->verts, p->verts, sizeof(p->verts[0]) * p->width * p->height); +} + + +/* +================== +Patch_Restore +================== +*/ +void Patch_Restore( patchMesh_t *p ) { + if ( patchSave ) { + p->width = patchSave->width; + p->height = patchSave->height; + memcpy(p->verts, patchSave->verts, sizeof(p->verts[0]) * p->width * p->height); + Mem_Free(patchSave->verts); + Mem_Free(patchSave); + patchSave = NULL; + } +} + +void Patch_FitTexture( patchMesh_t *p,float fx,float fy ) { + Patch_MakeDirty(p); + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + p->ctrl(i, j).st[0] = fx * (float) i / (p->width - 1); + p->ctrl(i, j).st[1] = fy * (float) j / (p->height - 1); + } + } +} + +void Patch_ResetTexturing( float fx,float fy ) { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + Patch_MakeDirty(p); + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + p->ctrl(i, j).st[0] = fx * (float) i / (p->width - 1); + p->ctrl(i, j).st[1] = fy * (float) j / (p->height - 1); + } + } + } + } +} + + +void Patch_FitTexturing() { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + Patch_MakeDirty(p); + for ( int i = 0 ; i < p->width ; i++ ) { + for ( int j = 0 ; j < p->height ; j++ ) { + p->ctrl(i, j).st[0] = 1 * (float) i / (p->width - 1); + p->ctrl(i, j).st[1] = 1 * (float) j / (p->height - 1); + } + } + } + } +} + +void Patch_SetTextureInfo( texdef_t *pt ) { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + if ( pt->rotate ) + Patch_RotateTexture(pb->pPatch, pt->rotate); + + if ( pt->shift[0] || pt->shift[1] ) + Patch_ShiftTexture(pb->pPatch, pt->shift[0], pt->shift[1], false); + + if ( pt->scale[0] || pt->scale[1] ) + Patch_ScaleTexture(pb->pPatch, pt->scale[0], pt->scale[1], false); + + patchMesh_t *p = pb->pPatch; + p->value = pt->value; + } + } +} + +bool WINAPI OnlyPatchesSelected() { + if ( g_ptrSelectedFaces.GetSize() > 0 || selected_brushes.next == &selected_brushes ) { + return false; + } + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( !pb->pPatch ) { + return false; + } + } + return true; +} + +bool WINAPI AnyPatchesSelected() { + if ( g_ptrSelectedFaces.GetSize() > 0 || selected_brushes.next == &selected_brushes ) { + return false; + } + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + return true; + } + } + return false; +} + +patchMesh_t * SinglePatchSelected() { + if ( selected_brushes.next->pPatch ) { + return selected_brushes.next->pPatch; + } + return NULL; +} + +void Patch_BendToggle() { + if ( g_bPatchBendMode ) { + g_bPatchBendMode = false; + HideInfoDialog(); + g_pParentWnd->UpdatePatchToolbarButtons() ; + return; + } + + brush_t *b = selected_brushes.next; + + if ( !QE_SingleBrush() || !b->pPatch ) { + Sys_Status("Must bend a single patch"); + return; + } + + Patch_Save(b->pPatch); + g_bPatchBendMode = true; + g_nPatchBendState = BEND_SELECT_ROTATION; + g_bPatchAxisOnRow = true; + g_nPatchAxisIndex = 1; + ShowInfoDialog(g_pBendStateMsg[BEND_SELECT_ROTATION]); +} + +void Patch_BendHandleTAB() { + if ( !g_bPatchBendMode ) { + return; + } + + brush_t *b = selected_brushes.next; + if ( !QE_SingleBrush() || !b->pPatch ) { + Patch_BendToggle(); + Sys_Status("No patch to bend!"); + return; + } + + patchMesh_t *p = b->pPatch; + + bool bShift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); + + if ( g_nPatchBendState == BEND_SELECT_ROTATION ) { + // only able to deal with odd numbered rows/cols + g_nPatchAxisIndex += (bShift) ? -2 : 2; + if ( g_bPatchAxisOnRow ) { + if ( (bShift) ? g_nPatchAxisIndex <= 0 : g_nPatchAxisIndex >= p->height ) { + g_bPatchAxisOnRow = false; + g_nPatchAxisIndex = (bShift) ? p->width - 1 : 1; + } + } else { + if ( (bShift) ? g_nPatchAxisIndex <= 0 : g_nPatchAxisIndex >= p->width ) { + g_bPatchAxisOnRow = true; + g_nPatchAxisIndex = (bShift) ? p->height - 1 : 1; + } + } + } else if ( g_nPatchBendState == BEND_SELECT_ORIGIN ) { + g_nBendOriginIndex += (bShift) ? -1 : 1; + if ( g_bPatchAxisOnRow ) { + if ( bShift ) { + if ( g_nBendOriginIndex < 0 ) + g_nBendOriginIndex = p->width - 1; + } else { + if ( g_nBendOriginIndex > p->width - 1 ) + g_nBendOriginIndex = 0; + } + VectorCopy(p->ctrl(g_nBendOriginIndex, g_nPatchAxisIndex).xyz, g_vBendOrigin); + } else { + if ( bShift ) { + if ( g_nBendOriginIndex < 0 ) + g_nBendOriginIndex = p->height - 1; + } else { + if ( g_nBendOriginIndex > p->height - 1 ) + g_nBendOriginIndex = 0; + } + VectorCopy(p->ctrl(g_nPatchAxisIndex, g_nBendOriginIndex).xyz, g_vBendOrigin); + } + } else if ( g_nPatchBendState == BEND_SELECT_EDGE ) { + g_bPatchLowerEdge ^= 1; + } + Sys_UpdateWindows(W_ALL); +} + +void Patch_BendHandleENTER() { + if ( !g_bPatchBendMode ) { + return; + } + + if ( g_nPatchBendState < BEND_BENDIT ) { + g_nPatchBendState++; + ShowInfoDialog(g_pBendStateMsg[g_nPatchBendState]); + if ( g_nPatchBendState == BEND_SELECT_ORIGIN ) { + g_vBendOrigin[0] = g_vBendOrigin[1] = g_vBendOrigin[2] = 0; + g_nBendOriginIndex = 0; + Patch_BendHandleTAB(); + } else if ( g_nPatchBendState == BEND_SELECT_EDGE ) { + g_bPatchLowerEdge = true; + } else if ( g_nPatchBendState == BEND_BENDIT ) { + // basically we go into rotation mode, set the axis to the center of the + } + } else { + // done + Patch_BendToggle(); + } + Sys_UpdateWindows(W_ALL); +} + + +void Patch_BendHandleESC() { + if ( !g_bPatchBendMode ) { + return; + } + Patch_BendToggle(); + brush_t *b = selected_brushes.next; + if ( QE_SingleBrush() && b->pPatch ) { + Patch_Restore(b->pPatch); + } + Sys_UpdateWindows(W_ALL); +} + +void Patch_SetBendRotateOrigin( patchMesh_t *p ) { + int nType = g_pParentWnd->ActiveXY()->GetViewType(); + int nDim3 = (nType == XY) ? 2 : (nType == YZ) ? 0 : 1; + g_vBendOrigin[nDim3] = 0; + VectorCopy(g_vBendOrigin, g_pParentWnd->ActiveXY()->RotateOrigin()); + return; +} + +// also sets the rotational origin +void Patch_SelectBendAxis() { + brush_t *b = selected_brushes.next; + if ( !QE_SingleBrush() || !b->pPatch ) { + // should not ever happen + Patch_BendToggle(); + return; + } + + patchMesh_t *p = b->pPatch; + if ( g_bPatchAxisOnRow ) { + SelectRow(p, g_nPatchAxisIndex, false); + } else { + SelectColumn(p, g_nPatchAxisIndex, false); + } + + Patch_SetBendRotateOrigin(p); +} + +void Patch_SelectBendNormal() { + brush_t *b = selected_brushes.next; + if ( !QE_SingleBrush() || !b->pPatch ) { + // should not ever happen + Patch_BendToggle(); + return; + } + + patchMesh_t *p = b->pPatch; + + g_qeglobals.d_num_move_points = 0; + if ( g_bPatchAxisOnRow ) { + if ( g_bPatchLowerEdge ) { + for ( int j = 0; j < g_nPatchAxisIndex; j++ ) + SelectRow(p, j, true); + } else { + for ( int j = p->height - 1; j > g_nPatchAxisIndex; j-- ) + SelectRow(p, j, true); + } + } else { + if ( g_bPatchLowerEdge ) { + for ( int j = 0; j < g_nPatchAxisIndex; j++ ) + SelectColumn(p, j, true); + } else { + for ( int j = p->width - 1; j > g_nPatchAxisIndex; j-- ) + SelectColumn(p, j, true); + } + } + Patch_SetBendRotateOrigin(p); +} + + + +void Patch_InsDelToggle() { + if ( g_bPatchInsertMode ) { + g_bPatchInsertMode = false; + HideInfoDialog(); + g_pParentWnd->UpdatePatchToolbarButtons() ; + return; + } + + brush_t *b = selected_brushes.next; + + if ( !QE_SingleBrush() || !b->pPatch ) { + Sys_Status("Must work with a single patch"); + return; + } + + Patch_Save(b->pPatch); + g_bPatchInsertMode = true; + g_nPatchInsertState = INSERT_SELECT_EDGE; + g_bPatchAxisOnRow = true; + g_nPatchAxisIndex = 0; + ShowInfoDialog(g_pInsertStateMsg[INSERT_SELECT_EDGE]); +} + +void Patch_InsDelESC() { + if ( !g_bPatchInsertMode ) { + return; + } + Patch_InsDelToggle(); + Sys_UpdateWindows(W_ALL); +} + + +void Patch_InsDelHandleENTER() { +} + +void Patch_InsDelHandleTAB() { + if ( !g_bPatchInsertMode ) { + Patch_InsDelToggle(); + return; + } + + brush_t *b = selected_brushes.next; + if ( !QE_SingleBrush() || !b->pPatch ) { + Patch_BendToggle(); + common->Printf("No patch to bend!"); + return; + } + + patchMesh_t *p = b->pPatch; + + // only able to deal with odd numbered rows/cols + g_nPatchAxisIndex += 2; + if ( g_bPatchAxisOnRow ) { + if ( g_nPatchAxisIndex >= p->height - 1 ) { + g_bPatchAxisOnRow = false; + g_nPatchAxisIndex = 0; + } + } else { + if ( g_nPatchAxisIndex >= p->width - 1 ) { + g_bPatchAxisOnRow = true; + g_nPatchAxisIndex = 0; + } + } + Sys_UpdateWindows(W_ALL); +} + + +void _Write1DMatrix( FILE *f,int x,float *m ) { + int i; + + fprintf(f, "( "); + for ( i = 0 ; i < x ; i++ ) { + if ( m[i] == (int) m[i] ) { + fprintf(f, "%i ", (int) m[i]); + } else { + fprintf(f, "%f ", m[i]); + } + } + fprintf(f, ")"); +} + +void _Write2DMatrix( FILE *f,int y,int x,float *m ) { + int i; + + fprintf(f, "( "); + for ( i = 0 ; i < y ; i++ ) { + _Write1DMatrix(f, x, m + i * x); + fprintf(f, " "); + } + fprintf(f, ")\n"); +} + + +void _Write3DMatrix( FILE *f,int z,int y,int x,float *m ) { + int i; + + fprintf(f, "(\n"); + for ( i = 0 ; i < z ; i++ ) { + _Write2DMatrix(f, y, x, m + i * (x * MAX_PATCH_HEIGHT)); + } + fprintf(f, ")\n"); +} + +void _Write1DMatrix( CMemFile *f,int x,float *m ) { + int i; + + MemFile_fprintf(f, "( "); + for ( i = 0 ; i < x ; i++ ) { + if ( m[i] == (int) m[i] ) { + MemFile_fprintf(f, "%i ", (int) m[i]); + } else { + MemFile_fprintf(f, "%f ", m[i]); + } + } + MemFile_fprintf(f, ")"); +} + +void _Write2DMatrix( CMemFile *f,int y,int x,float *m ) { + int i; + + MemFile_fprintf(f, "( "); + for ( i = 0 ; i < y ; i++ ) { + _Write1DMatrix(f, x, m + i * x); + MemFile_fprintf(f, " "); + } + MemFile_fprintf(f, ")\n"); +} + + +void _Write3DMatrix( CMemFile *f,int z,int y,int x,float *m ) { + int i; + + MemFile_fprintf(f, "(\n"); + for ( i = 0 ; i < z ; i++ ) { + _Write2DMatrix(f, y, x, m + i * (x * MAX_PATCH_HEIGHT)); + } + MemFile_fprintf(f, ")\n"); +} + + +void Patch_NaturalizeSelected( bool bCap,bool bCycleCap,bool alt ) { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + if ( bCap ) { + Patch_CapTexture(pb->pPatch, bCycleCap, alt); + } else { + Patch_Naturalize(pb->pPatch, true, true, alt); + } + } + } +} + +void Patch_SubdivideSelected( bool subdivide,int horz,int vert ) { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->explicitSubdivisions = subdivide; + if ( horz <= 0 ) { + horz = 1; + } + if ( vert <= 0 ) { + vert = 1; + } + pb->pPatch->horzSubdivisions = horz; + pb->pPatch->vertSubdivisions = vert; + Patch_MakeDirty(pb->pPatch); + } + } +} + + + +bool within( idVec3 vTest,idVec3 vTL,idVec3 vBR ) { + int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0; + int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2; + if ( (vTest[nDim1] > vTL[nDim1] && vTest[nDim1] < vBR[nDim1]) || (vTest[nDim1] < vTL[nDim1] && vTest[nDim1] > vBR[nDim1]) ) { + if ( (vTest[nDim2] > vTL[nDim2] && vTest[nDim2] < vBR[nDim2]) || (vTest[nDim2] < vTL[nDim2] && vTest[nDim2] > vBR[nDim2]) ) { + return true; + } + } + return false; +} + + +void Patch_SelectAreaPoints() { + //jhefty - make patch selection additive ALWAYS + //g_qeglobals.d_num_move_points = 0; + g_nPatchClickedView = -1; + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + for ( int i = 0; i < p->width; i++ ) { + for ( int j = 0; j < p->height; j++ ) { + if ( within(p->ctrl(i, j).xyz, g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR) ) { + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &p->ctrl(i, j).xyz; + } + } + } + } + } +} + +const char * Patch_GetTextureName() { + brush_t *b = selected_brushes.next; + if ( b->pPatch ) { + patchMesh_t *p = b->pPatch; + if ( p->d_texture->GetName() ) + return p->d_texture->GetName(); + } + return ""; +} + +patchMesh_t * Patch_Duplicate( patchMesh_t *pFrom ) { + patchMesh_t *p = MakeNewPatch(pFrom->width, pFrom->height); + p->contents = pFrom->contents; + p->value = pFrom->value; + p->horzSubdivisions = pFrom->horzSubdivisions; + p->vertSubdivisions = pFrom->vertSubdivisions; + p->explicitSubdivisions = pFrom->explicitSubdivisions; + p->d_texture = pFrom->d_texture; + p->bSelected = false; + p->bOverlay = false; + p->nListID = -1; + + memcpy(p->verts, pFrom->verts, p->width * p->height * sizeof(idDrawVert)); + + AddBrushForPatch(p); + return p; +} + + +void Patch_Thicken( int nAmount,bool bSeam ) { + int i, j, h, w; + brush_t *b; + patchMesh_t *pSeam; + idVec3 vMin, vMax; + CPtrArray brushes; + + nAmount = -nAmount; + + + if ( !QE_SingleBrush() ) { + Sys_Status("Cannot thicken multiple patches. Please select a single patch.\n"); + return; + } + + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( !pb->pPatch ) { + return; + } + + patchMesh_t *p = pb->pPatch; + Patch_MeshNormals(p); + patchMesh_t *pNew = Patch_Duplicate(p); + for ( i = 0; i < p->width; i++ ) { + for ( j = 0; j < p->height; j++ ) { + VectorMA(p->ctrl(i, j).xyz, nAmount, p->ctrl(i, j).normal, pNew->ctrl(i, j).xyz); + } + } + + Patch_Rebuild(pNew); + pNew->type |= PATCH_THICK; + brushes.Add(pNew->pSymbiot); + + if ( bSeam ) { + // FIXME: this should detect if any edges of the patch are closed and act appropriately + // + if ( !(p->type & PATCH_CYLINDER) ) { + b = Patch_GenericMesh(3, p->height, 2, false, true, p); + pSeam = b->pPatch; + pSeam->type |= PATCH_SEAM; + for ( i = 0; i < p->height; i++ ) { + VectorCopy(p->ctrl(0, i).xyz, pSeam->ctrl(0, i).xyz); + VectorCopy(pNew->ctrl(0, i).xyz, pSeam->ctrl(2, i).xyz); + VectorAdd(pSeam->ctrl(0, i).xyz, pSeam->ctrl(2, i).xyz, pSeam->ctrl(1, i).xyz); + VectorScale(pSeam->ctrl(1, i).xyz, 0.5, pSeam->ctrl(1, i).xyz); + } + + + Patch_CalcBounds(pSeam, vMin, vMax); + Brush_RebuildBrush(pSeam->pSymbiot, vMin, vMax); + //--Patch_CapTexture(pSeam); + Patch_Naturalize(pSeam); + patchInvert(pSeam); + brushes.Add(b); + + w = p->width - 1; + b = Patch_GenericMesh(3, p->height, 2, false, true, p); + pSeam = b->pPatch; + pSeam->type |= PATCH_SEAM; + for ( i = 0; i < p->height; i++ ) { + VectorCopy(p->ctrl(w, i).xyz, pSeam->ctrl(0, i).xyz); + VectorCopy(pNew->ctrl(w, i).xyz, pSeam->ctrl(2, i).xyz); + VectorAdd(pSeam->ctrl(0, i).xyz, pSeam->ctrl(2, i).xyz, pSeam->ctrl(1, i).xyz); + VectorScale(pSeam->ctrl(1, i).xyz, 0.5, pSeam->ctrl(1, i).xyz); + } + Patch_CalcBounds(pSeam, vMin, vMax); + Brush_RebuildBrush(pSeam->pSymbiot, vMin, vMax); + //--Patch_CapTexture(pSeam); + Patch_Naturalize(pSeam); + brushes.Add(b); + } + + //--{ + // otherwise we will add one per end + b = Patch_GenericMesh(p->width, 3, 2, false, true, p); + pSeam = b->pPatch; + pSeam->type |= PATCH_SEAM; + for ( i = 0; i < p->width; i++ ) { + VectorCopy(p->ctrl(i, 0).xyz, pSeam->ctrl(i, 0).xyz); + VectorCopy(pNew->ctrl(i, 0).xyz, pSeam->ctrl(i, 2).xyz); + VectorAdd(pSeam->ctrl(i, 0).xyz, pSeam->ctrl(i, 2).xyz, pSeam->ctrl(i, 1).xyz); + VectorScale(pSeam->ctrl(i, 1).xyz, 0.5, pSeam->ctrl(i, 1).xyz); + } + + + Patch_CalcBounds(pSeam, vMin, vMax); + Brush_RebuildBrush(pSeam->pSymbiot, vMin, vMax); + //--Patch_CapTexture(pSeam); + Patch_Naturalize(pSeam); + patchInvert(pSeam); + brushes.Add(b); + + h = p->height - 1; + b = Patch_GenericMesh(p->width, 3, 2, false, true, p); + pSeam = b->pPatch; + pSeam->type |= PATCH_SEAM; + for ( i = 0; i < p->width; i++ ) { + VectorCopy(p->ctrl(i, h).xyz, pSeam->ctrl(i, 0).xyz); + VectorCopy(pNew->ctrl(i, h).xyz, pSeam->ctrl(i, 2).xyz); + VectorAdd(pSeam->ctrl(i, 0).xyz, pSeam->ctrl(i, 2).xyz, pSeam->ctrl(i, 1).xyz); + VectorScale(pSeam->ctrl(i, 1).xyz, 0.5, pSeam->ctrl(i, 1).xyz); + } + Patch_CalcBounds(pSeam, vMin, vMax); + Brush_RebuildBrush(pSeam->pSymbiot, vMin, vMax); + //--Patch_CapTexture(pSeam); + Patch_Naturalize(pSeam); + brushes.Add(b); + //--} + } + patchInvert(pNew); + } + + for ( i = 0; i < brushes.GetSize(); i++ ) { + Select_Brush(reinterpret_cast< brush_t*>(brushes.GetAt(i))); + } + + if ( brushes.GetSize() > 0 ) { + eclass_t*pecNew = Eclass_ForName("func_static", false); + if ( pecNew ) { + entity_t*e = Entity_Create(pecNew); + SetKeyValue(e, "type", "patchThick"); + } + } + + UpdatePatchInspector(); +} + + +/* +lets get another list together as far as necessities.. + +*snapping stuff to the grid (i will only snap movements by the mouse to the grid.. snapping the rotational bend stuff will fubar everything) + +capping bevels/endcaps + +hot keys + +texture fix for caps + +clear clipboard + +*region fix + +*surface dialog + +*/ + +void Patch_SetOverlays() { + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->bOverlay = true; + } + } +} + + + +void Patch_ClearOverlays() { + brush_t *pb; + for ( pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->bOverlay = false; + } + } + + for ( pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->bOverlay = false; + } + } +} + +// freezes selected vertices +void Patch_Freeze() { + brush_t *pb; + for ( pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->bOverlay = false; + } + } + + for ( pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + pb->pPatch->bOverlay = false; + } + } +} + +void Patch_UnFreeze( bool bAll ) { +} + + +void Patch_Transpose() { + int i, j, w; + idDrawVert dv; + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + + if ( p->width > p->height ) { + for ( i = 0 ; i < p->height ; i++ ) { + for ( j = i + 1 ; j < p->width ; j++ ) { + if ( j < p->height ) { + // swap the value + memcpy(&dv, &p->ctrl(j, i), sizeof(idDrawVert)); + memcpy(&p->ctrl(j, i), &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &dv, sizeof(idDrawVert)); + } else { + // just copy + memcpy(&p->ctrl(j, i), &p->ctrl(i, j), sizeof(idDrawVert)); + } + } + } + } else { + for ( i = 0 ; i < p->width ; i++ ) { + for ( j = i + 1 ; j < p->height ; j++ ) { + if ( j < p->width ) { + // swap the value + memcpy(&dv, &p->ctrl(i, j), sizeof(idDrawVert)); + memcpy(&p->ctrl(i, j), &p->ctrl(j, i), sizeof(idDrawVert)); + memcpy(&p->ctrl(j, i), &dv, sizeof(idDrawVert)); + } else { + // just copy + memcpy(&p->ctrl(i, j), &p->ctrl(j, i), sizeof(idDrawVert)); + } + } + } + } + + w = p->width; + p->width = p->height; + p->height = w; + patchInvert(p); + Patch_Rebuild(p); + } + } +} + + + +void Select_SnapToGrid() { + int i, j, k; + for ( brush_t*pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + for ( i = 0; i < p->width; i++ ) { + for ( j = 0; j < p->height; j++ ) { + for ( k = 0; k < 3; k++ ) { + p->ctrl(i, j).xyz[k] = floor(p->ctrl(i, j).xyz[k] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + } + } + idVec3 vMin, vMax; + Patch_CalcBounds(p, vMin, vMax); + Brush_RebuildBrush(p->pSymbiot, vMin, vMax); + } else { + Brush_SnapToGrid(pb); + } + } +} + + +void Patch_FindReplaceTexture( brush_t *pb,const char *pFind,const char *pReplace,bool bForce ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + if ( bForce || idStr::Icmp(p->d_texture->GetName(), pFind) == 0 ) { + p->d_texture = Texture_ForName(pReplace); + //strcpy(p->d_texture->name, pReplace); + } + } +} + +void Patch_ReplaceQTexture( brush_t *pb,idMaterial *pOld,idMaterial *pNew ) { + if ( pb->pPatch ) { + patchMesh_t *p = pb->pPatch; + if ( p->d_texture == pOld ) { + p->d_texture = pNew; + } + } +} + +void Patch_Clone( patchMesh_t *p,brush_t *pNewOwner ) { +} + +void Patch_FromTriangle( idVec5 vx,idVec5 vy,idVec5 vz ) { + patchMesh_t *p = MakeNewPatch(3, 3); + p->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); + p->type = PATCH_TRIANGLE; + + // 0 0 goes to x + // 0 1 goes to x + // 0 2 goes to x + + // 1 0 goes to mid of x and z + // 1 1 goes to mid of x y and z + // 1 2 goes to mid of x and y + + // 2 0 goes to z + // 2 1 goes to mid of y and z + // 2 2 goes to y + + idVec5 vMidXZ; + idVec5 vMidXY; + idVec5 vMidYZ; + + + vMidXZ.Lerp(vx, vz, 0.5); + vMidXY.Lerp(vx, vy, 0.5); + vMidYZ.Lerp(vy, vz, 0.5); + + p->ctrl(0, 0).xyz = vx.ToVec3(); + p->ctrl(0, 1).xyz = vx.ToVec3(); + p->ctrl(0, 2).xyz = vx.ToVec3(); + p->ctrl(0, 0).st[0] = vx[3]; + p->ctrl(0, 0).st[1] = vx[4]; + p->ctrl(0, 1).st[0] = vx[3]; + p->ctrl(0, 1).st[1] = vx[4]; + p->ctrl(0, 2).st[0] = vx[3]; + p->ctrl(0, 2).st[1] = vx[4]; + + p->ctrl(1, 0).xyz = vMidXY.ToVec3(); + p->ctrl(1, 1).xyz = vx.ToVec3(); + p->ctrl(1, 2).xyz = vMidXZ.ToVec3(); + p->ctrl(1, 0).st[0] = vMidXY[3]; + p->ctrl(1, 0).st[1] = vMidXY[4]; + p->ctrl(1, 1).st[0] = vx[3]; + p->ctrl(1, 1).st[1] = vx[4]; + p->ctrl(1, 2).st[0] = vMidXZ[3]; + p->ctrl(1, 2).st[1] = vMidXZ[4]; + + p->ctrl(2, 0).xyz = vy.ToVec3(); + p->ctrl(2, 1).xyz = vMidYZ.ToVec3(); + p->ctrl(2, 2).xyz = vz.ToVec3(); + p->ctrl(2, 0).st[0] = vy[3]; + p->ctrl(2, 0).st[1] = vy[4]; + p->ctrl(2, 1).st[0] = vMidYZ[3]; + p->ctrl(2, 1).st[1] = vMidYZ[4]; + p->ctrl(2, 2).st[0] = vz[3]; + p->ctrl(2, 2).st[1] = vz[4]; + + + //Patch_Naturalize(p); + + brush_t *b = AddBrushForPatch(p); +} + + +/* +============== +Patch_SetEpair +sets an epair for the given patch +============== +*/ +void Patch_SetEpair( patchMesh_t *p,const char *pKey,const char *pValue ) { + if ( g_qeglobals.m_bBrushPrimitMode ) { + if ( p->epairs == NULL ) { + p->epairs = new idDict; + } + p->epairs->Set(pKey, pValue); + } +} + +/* +================= +Patch_GetKeyValue +================= +*/ +const char * Patch_GetKeyValue( patchMesh_t *p,const char *pKey ) { + if ( g_qeglobals.m_bBrushPrimitMode ) { + if ( p->epairs ) { + return p->epairs->GetString(pKey); + } + } + return ""; +} + + +//Real nitpicky, but could you make CTRL-S save the current map with the current name? (ie: File/Save) +/* +Feature addition. +When reading in textures, please check for the presence of a file called "textures.link" or something, which contains one line such as; + +g:\quake3\baseq3\textures\common + + So that, when I'm reading in, lets say, my \eerie directory, it goes through and adds my textures to the palette, along with everything in common. + + Don't forget to add "Finer texture alignment" to the list. I'd like to be able to move in 0.1 increments using the Shift-Arrow Keys. + + No. Sometimes textures are drawn the wrong way on patches. We'd like the ability to flip a texture. Like the way X/Y scale -1 used to worked. + + 1) Easier way of deleting rows, columns +2) Fine tuning of textures on patches (X/Y shifts other than with the surface dialog) +2) Patch matrix transposition + + 1) Actually, bump texture flipping on patches to the top of the list of things to do. +2) When you select a patch, and hit S, it should read in the selected patch texture. Should not work if you multiselect patches and hit S +3) Brandon has a wierd anomoly. He fine-tunes a patch with caps. It looks fine when the patch is selected, but as soon as he escapes out, it reverts to it's pre-tuned state. When he selects the patch again, it looks tuned + + +*1) Flipping textures on patches +*2) When you select a patch, and hit S, it should read in the selected patch texture. Should not work if you multiselect patches and hit S +3) Easier way of deleting rows columns +*4) Thick Curves +5) Patch matrix transposition +6) Inverted cylinder capping +*7) bugs +*8) curve speed + + Have a new feature request. "Compute Bounding Box" for mapobjects (md3 files). This would be used for misc_mapobject (essentially, drop in 3DS Max models into our maps) + + Ok, Feature Request. Load and draw MD3's in the Camera view with proper bounding boxes. This should be off misc_model + + Feature Addition: View/Hide Hint Brushes -- This should be a specific case. +*/ + + + diff --git a/tools/radiant/PMESH.H b/tools/radiant/PMESH.H new file mode 100644 index 000000000..fec055081 --- /dev/null +++ b/tools/radiant/PMESH.H @@ -0,0 +1,115 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// patch stuff +patchMesh_t* MakeNewPatch(int width, int height); +brush_t* AddBrushForPatch(patchMesh_t *pm, bool bLinkToWorld = true); +brush_t* Patch_GenericMesh(int nWidth, int nHeight, int nOrientation = 2, bool bDeleteSource = true, bool bOverride = false, patchMesh_t *parent = NULL); +void Patch_ReadFile (char *name); +void Patch_WriteFile (char *name); +void Patch_BuildPoints (brush_t *b); +void Patch_Move(patchMesh_t *p, const idVec3 vMove, bool bRebuild = false); +//++timo had to add a default value for bSnap (see Patch_ApplyMatrix call from Select_ApplyMatrix in select.cpp) +void Patch_ApplyMatrix(patchMesh_t *p, const idVec3 vOrigin, const idMat3 matrix, bool bSnap = false); +void Patch_EditPatch(); +void Patch_Deselect(); +void Patch_Deselect(patchMesh_t *p); +void Patch_Delete(patchMesh_t *p); +int Patch_MemorySize(patchMesh_t *p); +void Patch_Select(patchMesh_t *p); +void Patch_Scale(patchMesh_t *p, const idVec3 vOrigin, const idVec3 vAmt, bool bRebuilt = true); +void Patch_Cleanup(); +void Patch_SetView(int n); +void Patch_SetTexture(patchMesh_t *p, texdef_t *tex_def); +void Patch_SetTextureName(patchMesh_t *p, const char *name); +void Patch_BrushToMesh(bool bCone = false, bool bBevel = false, bool bEndcap = false, bool bSquare = false, int nHeight = 3); +bool Patch_DragScale(patchMesh_t *p, idVec3 vAmt, idVec3 vMove); +void Patch_ReadBuffer(char* pBuff, bool bSelect = false); +void Patch_WriteFile (CMemFile* pMemFile); +void Patch_UpdateSelected(idVec3 vMove); +void Patch_AddRow(patchMesh_t *p); +brush_t* Patch_Parse(bool bOld); +void Patch_Write (patchMesh_t *p, FILE *f); +void Patch_Write (patchMesh_t *p, CMemFile *file); +void Patch_AdjustColumns(patchMesh_t *p, int nCols); +void Patch_AdjustRows(patchMesh_t *p, int nRows); +void Patch_AdjustSelected(bool bInsert, bool bColumn, bool bFlag); +patchMesh_t* Patch_Duplicate(patchMesh_t *pFrom); +void Patch_RotateTexture(patchMesh_t *p, float fAngle); +void Patch_ScaleTexture(patchMesh_t *p, float fx, float fy, bool absolute); +void Patch_ShiftTexture(patchMesh_t *p, float fx, float fy, bool autoAdjust); +void Patch_DrawCam(patchMesh_t *p, bool selected); +void Patch_DrawXY(patchMesh_t *p); +void Patch_InsertColumn(patchMesh_t *p, bool bAdd); +void Patch_InsertRow(patchMesh_t *p, bool bAdd); +void Patch_RemoveRow(patchMesh_t *p, bool bFirst); +void Patch_RemoveColumn(patchMesh_t *p, bool bFirst); +void Patch_ToggleInverted(); +void Patch_Restore(patchMesh_t *p); +void Patch_Save(patchMesh_t *p); +void Patch_SetTextureInfo(texdef_t* pt); +void Patch_NaturalTexturing(); +void Patch_ResetTexturing(float fx, float fy); +void Patch_FitTexture(patchMesh_t *p, float fx, float fy); +void Patch_FitTexturing(); +void Patch_BendToggle(); +void Patch_StartInsDel(); +void Patch_BendHandleTAB(); +void Patch_BendHandleENTER(); +void Patch_SelectBendNormal(); +void Patch_SelectBendAxis(); +patchMesh_t* SinglePatchSelected(); +void Patch_CapCurrent(bool bInvertedBevel = false, bool bInvertedEndcap = false); +void Patch_DisperseRows(); +void Patch_DisperseColumns(); +void Patch_NaturalizeSelected(bool bCap = false, bool bCycleCap = false, bool alt = false); +void Patch_SubdivideSelected(bool subdivide, int horz, int vert); +void Patch_Naturalize(patchMesh_t *p, bool horz = true, bool vert = true, bool alt = false); +void Patch_SelectAreaPoints(); +void Patch_InvertTexture(bool bY); +void Patch_InsDelToggle(); +void Patch_InsDelHandleTAB(); +void Patch_InsDelHandleENTER(); +void Patch_SetOverlays(); +void Patch_ClearOverlays(); +void Patch_Thicken(int nAmount, bool bSeam); +void Patch_Transpose(); +void Patch_Freeze(); +void Patch_MakeDirty(patchMesh_t *p); +void Patch_UnFreeze(bool bAll); +const char* Patch_GetTextureName(); +void Patch_FindReplaceTexture(brush_t *pb, const char *pFind, const char *pReplace, bool bForce); +void Patch_ReplaceQTexture(brush_t *pb, idMaterial *pOld, idMaterial *pNew); +void Select_SnapToGrid(); +void Patch_FromTriangle(idVec5 vx, idVec5 vy, idVec5 vz); +const char* Patch_GetKeyValue(patchMesh_t *p, const char *pKey); +void Patch_SetEpair(patchMesh_t *p, const char *pKey, const char *pValue); +void Patch_FlipTexture(patchMesh_t *p, bool y); + +bool WINAPI OnlyPatchesSelected(); +bool WINAPI AnyPatchesSelected(); +void WINAPI Patch_Rebuild(patchMesh_t *p); + +extern bool g_bPatchShowBounds; +extern bool g_bPatchWireFrame; +extern bool g_bPatchWeld; +extern bool g_bPatchDrillDown; +extern bool g_bPatchInsertMode; +extern bool g_bPatchBendMode; +extern idVec3 g_vBendOrigin; diff --git a/tools/radiant/PatchDensityDlg.cpp b/tools/radiant/PatchDensityDlg.cpp new file mode 100644 index 000000000..9714f9e46 --- /dev/null +++ b/tools/radiant/PatchDensityDlg.cpp @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "PatchDensityDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPatchDensityDlg dialog + + +CPatchDensityDlg::CPatchDensityDlg(CWnd* pParent /*=NULL*/) + : CDialog(CPatchDensityDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CPatchDensityDlg) + //}}AFX_DATA_INIT +} + + +void CPatchDensityDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPatchDensityDlg) + DDX_Control(pDX, IDC_COMBO_WIDTH, m_wndWidth); + DDX_Control(pDX, IDC_COMBO_HEIGHT, m_wndHeight); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CPatchDensityDlg, CDialog) + //{{AFX_MSG_MAP(CPatchDensityDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPatchDensityDlg message handlers + +int g_nXLat[] = {3,5,7,9,11,13,15}; + +void CPatchDensityDlg::OnOK() +{ + int nWidth = m_wndWidth.GetCurSel(); + int nHeight = m_wndHeight.GetCurSel(); + + if (nWidth >= 0 && nWidth <= 6 && nHeight >= 0 && nHeight <= 6) + { + Patch_GenericMesh(g_nXLat[nWidth], g_nXLat[nHeight], g_pParentWnd->ActiveXY()->GetViewType()); + Sys_UpdateWindows(W_ALL); + } + + CDialog::OnOK(); +} + +BOOL CPatchDensityDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_wndWidth.SetCurSel(0); + m_wndHeight.SetCurSel(0); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/tools/radiant/PatchDensityDlg.h b/tools/radiant/PatchDensityDlg.h new file mode 100644 index 000000000..2ce4a1631 --- /dev/null +++ b/tools/radiant/PatchDensityDlg.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_PATCHDENSITYDLG_H__509162A1_1023_11D2_AFFB_00AA00A410FC__INCLUDED_) +#define AFX_PATCHDENSITYDLG_H__509162A1_1023_11D2_AFFB_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// PatchDensityDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CPatchDensityDlg dialog + +class CPatchDensityDlg : public CDialog +{ +// Construction +public: + CPatchDensityDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CPatchDensityDlg) + enum { IDD = IDD_DIALOG_NEWPATCH }; + CComboBox m_wndWidth; + CComboBox m_wndHeight; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPatchDensityDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CPatchDensityDlg) + virtual void OnOK(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PATCHDENSITYDLG_H__509162A1_1023_11D2_AFFB_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/PatchDialog.cpp b/tools/radiant/PatchDialog.cpp new file mode 100644 index 000000000..ca7be5588 --- /dev/null +++ b/tools/radiant/PatchDialog.cpp @@ -0,0 +1,349 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "PatchDialog.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPatchDialog dialog + +CPatchDialog g_PatchDialog; + +CPatchDialog::CPatchDialog(CWnd* pParent /*=NULL*/) + : CDialog(CPatchDialog::IDD, pParent) +{ + //{{AFX_DATA_INIT(CPatchDialog) + m_strName = _T(""); + m_fS = 0.0f; + m_fT = 0.0f; + m_fX = 0.0f; + m_fY = 0.0f; + m_fZ = 0.0f; + m_fHScale = 0.05f; + m_fHShift = 0.05f; + m_fRotate = 45; + m_fVScale = 0.05f; + m_fVShift = 0.05f; + //}}AFX_DATA_INIT + m_Patch = NULL; +} + + +void CPatchDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPatchDialog) + DDX_Control(pDX, IDC_SPIN_VSHIFT, m_wndVShift); + DDX_Control(pDX, IDC_SPIN_VSCALE, m_wndVScale); + DDX_Control(pDX, IDC_SPIN_ROTATE, m_wndRotate); + DDX_Control(pDX, IDC_SPIN_HSHIFT, m_wndHShift); + DDX_Control(pDX, IDC_SPIN_HSCALE, m_wndHScale); + DDX_Control(pDX, IDC_COMBO_TYPE, m_wndType); + DDX_Control(pDX, IDC_COMBO_ROW, m_wndRows); + DDX_Control(pDX, IDC_COMBO_COL, m_wndCols); + DDX_Text(pDX, IDC_EDIT_NAME, m_strName); + DDX_Text(pDX, IDC_EDIT_S, m_fS); + DDX_Text(pDX, IDC_EDIT_T, m_fT); + DDX_Text(pDX, IDC_EDIT_X, m_fX); + DDX_Text(pDX, IDC_EDIT_Y, m_fY); + DDX_Text(pDX, IDC_EDIT_Z, m_fZ); + DDX_Text(pDX, IDC_HSCALE, m_fHScale); + DDX_Text(pDX, IDC_HSHIFT, m_fHShift); + DDX_Text(pDX, IDC_ROTATE, m_fRotate); + DDX_Text(pDX, IDC_VSCALE, m_fVScale); + DDX_Text(pDX, IDC_VSHIFT, m_fVShift); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CPatchDialog, CDialog) + //{{AFX_MSG_MAP(CPatchDialog) + ON_BN_CLICKED(IDC_BTN_PATCHDETAILS, OnBtnPatchdetails) + ON_BN_CLICKED(IDC_BTN_PATCHFIT, OnBtnPatchfit) + ON_BN_CLICKED(IDC_BTN_PATCHNATURAL, OnBtnPatchnatural) + ON_BN_CLICKED(IDC_BTN_PATCHRESET, OnBtnPatchreset) + ON_CBN_SELCHANGE(IDC_COMBO_COL, OnSelchangeComboCol) + ON_CBN_SELCHANGE(IDC_COMBO_ROW, OnSelchangeComboRow) + ON_CBN_SELCHANGE(IDC_COMBO_TYPE, OnSelchangeComboType) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSCALE, OnDeltaposSpin) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ROTATE, OnDeltaposSpin) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSCALE, OnDeltaposSpin) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSHIFT, OnDeltaposSpin) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSHIFT, OnDeltaposSpin) + ON_WM_DESTROY() + ON_BN_CLICKED(IDC_APPLY, OnApply) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPatchDialog message handlers + +void CPatchDialog::OnBtnPatchdetails() +{ + Patch_NaturalizeSelected(true); + Sys_UpdateWindows(W_ALL); +} + +void CPatchDialog::OnBtnPatchfit() +{ + Patch_FitTexturing(); + Sys_UpdateWindows(W_ALL); +} + +void CPatchDialog::OnBtnPatchnatural() +{ + Patch_NaturalizeSelected(); + Sys_UpdateWindows(W_ALL); +} + +void CPatchDialog::OnBtnPatchreset() +{ + //CTextureLayout dlg; + //if (dlg.DoModal() == IDOK) + //{ + // Patch_ResetTexturing(dlg.m_fX, dlg.m_fY); + //} + //Sys_UpdateWindows(W_ALL); +} + +void CPatchDialog::OnSelchangeComboCol() +{ + UpdateRowColInfo(); +} + +void CPatchDialog::OnSelchangeComboRow() +{ + UpdateRowColInfo(); +} + +void CPatchDialog::OnSelchangeComboType() +{ + // TODO: Add your control notification handler code here + +} + +void CPatchDialog::OnOK() +{ + m_Patch = NULL; + + CDialog::OnOK(); +} + +void CPatchDialog::OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + UpdateSpinners((pNMUpDown->iDelta > 0), pNMUpDown->hdr.idFrom); + *pResult = 0; +} + +BOOL CPatchDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_wndHScale.SetRange(0, 1000); + m_wndVScale.SetRange(0, 1000); + m_wndHShift.SetRange(0, 1000); + m_wndVShift.SetRange(0, 1000); + m_wndRotate.SetRange(0, 1000); + + GetPatchInfo(); + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + + +void CPatchDialog::GetPatchInfo() +{ + m_Patch = SinglePatchSelected(); + if (m_Patch != NULL) + { + CString str; + int i; + m_wndRows.ResetContent(); + for (i = 0; i < m_Patch->height; i++) + { + str.Format("%i", i); + m_wndRows.AddString(str); + } + m_wndRows.SetCurSel(0); + m_wndCols.ResetContent(); + for (i = 0; i < m_Patch->width; i++) + { + str.Format("%i", i); + m_wndCols.AddString(str); + } + m_wndCols.SetCurSel(0); + } + UpdateRowColInfo(); +} + +void CPatchDialog::SetPatchInfo() +{ + +} + +void DoPatchInspector() +{ + if (g_PatchDialog.GetSafeHwnd() == NULL) + { + g_PatchDialog.Create(IDD_DIALOG_PATCH); + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("Radiant::PatchWindow", &rct, &lSize)) + { + g_PatchDialog.SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE); + } + } + g_PatchDialog.ShowWindow(SW_SHOW); + g_PatchDialog.GetPatchInfo(); +} + +void UpdatePatchInspector() +{ + if (g_PatchDialog.GetSafeHwnd() != NULL) + { + g_PatchDialog.UpdateInfo(); + } + +} + +void CPatchDialog::OnDestroy() +{ + if (GetSafeHwnd()) + { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("Radiant::PatchWindow", &rct, sizeof(rct)); + } + CDialog::OnDestroy(); +} + +void CPatchDialog::UpdateRowColInfo() +{ + m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0; + + if (m_Patch != NULL) + { + int r = m_wndRows.GetCurSel(); + int c = m_wndCols.GetCurSel(); + if (r >= 0 && r < m_Patch->height && c >= 0 && c < m_Patch->width) + { + m_fX = m_Patch->ctrl(c,r).xyz[0]; + m_fY = m_Patch->ctrl(c,r).xyz[1]; + m_fZ = m_Patch->ctrl(c,r).xyz[2]; + m_fS = m_Patch->ctrl(c,r).st[0]; + m_fT = m_Patch->ctrl(c,r).st[1]; + } + } + UpdateData(FALSE); +} + +void CPatchDialog::UpdateInfo() +{ + GetPatchInfo(); +} + +void CPatchDialog::OnApply() +{ + UpdateData(TRUE); + if (m_Patch != NULL) + { + int r = m_wndRows.GetCurSel(); + int c = m_wndCols.GetCurSel(); + if (r >= 0 && r < m_Patch->height && c >= 0 && c < m_Patch->width) + { + m_Patch->ctrl(c,r).xyz[0] = m_fX; + m_Patch->ctrl(c,r).xyz[1] = m_fY; + m_Patch->ctrl(c,r).xyz[2] = m_fZ; + m_Patch->ctrl(c,r).st[0] = m_fS; + m_Patch->ctrl(c,r).st[1] = m_fT; + Patch_MakeDirty(m_Patch); + Sys_UpdateWindows(W_ALL); + } + } +} + +void CPatchDialog::UpdateSpinners(bool bUp, int nID) +{ + texdef_t td; + + td.rotate = 0.0; + td.scale[0] = td.scale[1] = 0.0; + td.shift[0] = td.shift[1] = 0.0; + td.value = 0; + + + UpdateData(TRUE); + + if (nID == IDC_SPIN_ROTATE) + { + if (bUp) + td.rotate = m_fRotate; + else + td.rotate = -m_fRotate; + } + else if (nID == IDC_SPIN_HSCALE) + { + if (bUp) + td.scale[0] = 1 - m_fHScale; + else + td.scale[0] = 1 + m_fHScale; + } + else if (nID == IDC_SPIN_VSCALE) + { + if (bUp) + td.scale[1] = 1 - m_fVScale; + else + td.scale[1] = 1 + m_fVScale; + } + + else if (nID == IDC_SPIN_HSHIFT) + { + if (bUp) + td.shift[0] = m_fHShift; + else + td.shift[0] = -m_fHShift; + } + else if (nID == IDC_SPIN_VSHIFT) + { + if (bUp) + td.shift[1] = m_fVShift; + else + td.shift[1] = -m_fVShift; + } + + Patch_SetTextureInfo(&td); + Sys_UpdateWindows(W_CAMERA); +} + + diff --git a/tools/radiant/PatchDialog.h b/tools/radiant/PatchDialog.h new file mode 100644 index 000000000..458aef624 --- /dev/null +++ b/tools/radiant/PatchDialog.h @@ -0,0 +1,99 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_PATCHDIALOG_H__DE62DFB4_E9EC_11D2_A509_0020AFEB881A__INCLUDED_) +#define AFX_PATCHDIALOG_H__DE62DFB4_E9EC_11D2_A509_0020AFEB881A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PatchDialog.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CPatchDialog dialog + +class CPatchDialog : public CDialog +{ + patchMesh_t *m_Patch; +// Construction +public: + void UpdateInfo(); + void SetPatchInfo(); + void GetPatchInfo(); + CPatchDialog(CWnd* pParent = NULL); // standard constructor + void UpdateSpinners(bool bUp, int nID); + +// Dialog Data + //{{AFX_DATA(CPatchDialog) + enum { IDD = IDD_DIALOG_PATCH }; + CSpinButtonCtrl m_wndVShift; + CSpinButtonCtrl m_wndVScale; + CSpinButtonCtrl m_wndRotate; + CSpinButtonCtrl m_wndHShift; + CSpinButtonCtrl m_wndHScale; + CComboBox m_wndType; + CComboBox m_wndRows; + CComboBox m_wndCols; + CString m_strName; + float m_fS; + float m_fT; + float m_fX; + float m_fY; + float m_fZ; + float m_fHScale; + float m_fHShift; + float m_fRotate; + float m_fVScale; + float m_fVShift; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPatchDialog) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + void UpdateRowColInfo(); + + // Generated message map functions + //{{AFX_MSG(CPatchDialog) + afx_msg void OnBtnPatchdetails(); + afx_msg void OnBtnPatchfit(); + afx_msg void OnBtnPatchnatural(); + afx_msg void OnBtnPatchreset(); + afx_msg void OnSelchangeComboCol(); + afx_msg void OnSelchangeComboRow(); + afx_msg void OnSelchangeComboType(); + virtual void OnOK(); + afx_msg void OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult); + virtual BOOL OnInitDialog(); + afx_msg void OnDestroy(); + afx_msg void OnApply(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PATCHDIALOG_H__DE62DFB4_E9EC_11D2_A509_0020AFEB881A__INCLUDED_) diff --git a/tools/radiant/PointFile.cpp b/tools/radiant/PointFile.cpp new file mode 100644 index 000000000..1aa74495c --- /dev/null +++ b/tools/radiant/PointFile.cpp @@ -0,0 +1,154 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +#define MAX_POINTFILE 8192 +static idVec3 s_pointvecs[MAX_POINTFILE]; +static int s_num_points, s_check_point; + +void Pointfile_Delete (void) +{ + char name[1024]; + + strcpy (name, currentmap); + StripExtension (name); + strcat (name, ".lin"); + + remove(name); +} + +// advance camera to next point +void Pointfile_Next (void) +{ + idVec3 dir; + + if (s_check_point >= s_num_points-2) + { + Sys_Status ("End of pointfile", 0); + return; + } + s_check_point++; + VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetCamera()->Camera().origin); + VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin()); + VectorSubtract (s_pointvecs[s_check_point+1], g_pParentWnd->GetCamera()->Camera().origin, dir); + dir.Normalize(); + g_pParentWnd->GetCamera()->Camera().angles[1] = atan2 (dir[1], dir[0])*180/3.14159; + g_pParentWnd->GetCamera()->Camera().angles[0] = asin (dir[2])*180/3.14159; + + Sys_UpdateWindows (W_ALL); +} + +// advance camera to previous point +void Pointfile_Prev (void) +{ + idVec3 dir; + + if ( s_check_point == 0) + { + Sys_Status ("Start of pointfile", 0); + return; + } + s_check_point--; + VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetCamera()->Camera().origin); + VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin()); + VectorSubtract (s_pointvecs[s_check_point+1], g_pParentWnd->GetCamera()->Camera().origin, dir); + dir.Normalize(); + g_pParentWnd->GetCamera()->Camera().angles[1] = atan2 (dir[1], dir[0])*180/3.14159; + g_pParentWnd->GetCamera()->Camera().angles[0] = asin (dir[2])*180/3.14159; + + Sys_UpdateWindows (W_ALL); +} + +void WINAPI Pointfile_Check (void) +{ + char name[1024]; + FILE *f; + idVec3 v; + + strcpy (name, currentmap); + StripExtension (name); + strcat (name, ".lin"); + + f = fopen (name, "r"); + if (!f) + return; + + common->Printf ("Reading pointfile %s\n", name); + + if (!g_qeglobals.d_pointfile_display_list) + g_qeglobals.d_pointfile_display_list = qglGenLists(1); + + s_num_points = 0; + qglNewList (g_qeglobals.d_pointfile_display_list, GL_COMPILE); + qglColor3f (1, 0, 0); + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_TEXTURE_1D); + qglLineWidth (2); + qglBegin(GL_LINE_STRIP); + do + { + if (fscanf (f, "%f %f %f\n", &v[0], &v[1], &v[2]) != 3) + break; + if (s_num_points < MAX_POINTFILE) + { + VectorCopy (v, s_pointvecs[s_num_points]); + s_num_points++; + } + qglVertex3fv( v.ToFloatPtr() ); + } while (1); + qglEnd(); + qglLineWidth (0.5); + qglEndList (); + + s_check_point = 0; + fclose (f); + //Pointfile_Next (); +} + +void Pointfile_Draw( void ) +{ + int i; + + qglColor3f( 1.0F, 0.0F, 0.0F ); + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_TEXTURE_1D); + qglLineWidth (2); + qglBegin(GL_LINE_STRIP); + for ( i = 0; i < s_num_points; i++ ) + { + qglVertex3fv( s_pointvecs[i].ToFloatPtr() ); + } + qglEnd(); + qglLineWidth( 0.5 ); +} + +void Pointfile_Clear (void) +{ + if (!g_qeglobals.d_pointfile_display_list) + return; + + qglDeleteLists (g_qeglobals.d_pointfile_display_list, 1); + g_qeglobals.d_pointfile_display_list = 0; + Sys_UpdateWindows (W_ALL); +} + diff --git a/tools/radiant/PrefsDlg.cpp b/tools/radiant/PrefsDlg.cpp new file mode 100644 index 000000000..3b12a2298 --- /dev/null +++ b/tools/radiant/PrefsDlg.cpp @@ -0,0 +1,443 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "shlobj.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define MOUSE_KEY "radiant_MouseButtons" +#define TLOCK_KEY "radiant_TextureLock" +#define RLOCK_KEY "radiant_RotateLock" +#define LOADLAST_KEY "radiant_LoadLast" +#define LOADLASTMAP_KEY "radiant_LoadLastMap" +#define LASTPROJ_KEY "radiant_LastProject" +#define LASTMAP_KEY "radiant_LastMap" +#define RUN_KEY "radiant_RunBefore" +#define FACE_KEY "radiant_NewFaceGrab" +#define BSP_KEY "radiant_InternalBSP" +#define RCLICK_KEY "radiant_NewRightClick" +#define VERTEX_KEY "radiant_NewVertex" +#define AUTOSAVE_KEY "radiant_Autosave" +#define AUTOSAVETIME_KEY "radiant_AutosaveMinutes" +#define PAK_KEY "radiant_UsePAK" +#define NEWAPPLY_KEY "radiant_ApplyDismissesSurface" +#define HACK_KEY "radiant_Gatewayescapehack" +#define TEXTURE_KEY "radiant_NewTextureWindowStuff" +#define TINYBRUSH_KEY "radiant_CleanTinyBrushes" +#define TINYSIZE_KEY "radiant_CleanTinyBrusheSize" +#define SNAPSHOT_KEY "radiant_Snapshots" +#define PAKFILE_KEY "radiant_PAKFile" +#define STATUS_KEY "radiant_StatusPointSize" +#define MOVESPEED_KEY "radiant_MoveSpeed" +#define ANGLESPEED_KEY "radiant_AngleSpeed" +#define SETGAME_KEY "radiant_UseSetGame" +#define CAMXYUPDATE_KEY "radiant_CamXYUpdate" +#define LIGHTDRAW_KEY "radiant_NewLightStyle" +#define WHATGAME_KEY "radiant_WhichGame" +#define CUBICCLIP_KEY "radiant_CubicClipping" +#define CUBICSCALE_KEY "radiant_CubicScale" +#define ALTEDGE_KEY "radiant_ALTEdgeDrag" +#define FACECOLORS_KEY "radiant_FaceColors" +#define QE4PAINT_KEY "radiant_QE4Paint" +#define SNAPT_KEY "radiant_SnapT" +#define XZVIS_KEY "radiant_XZVIS" +#define YZVIS_KEY "radiant_YZVIS" +#define ZVIS_KEY "radiant_ZVIS" +#define SIZEPAINT_KEY "radiant_SizePainting" +#define DLLENTITIES_KEY "radiant_DLLEntities" +#define WIDETOOLBAR_KEY "radiant_WideToolBar" +#define NOCLAMP_KEY "radiant_NoClamp" +#define PREFAB_KEY "radiant_PrefabPath" +#define USERINI_KEY "radiant_UserINIPath" +#define ROTATION_KEY "radiant_Rotation" +#define SGIOPENGL_KEY "radiant_SGIOpenGL" +#define BUGGYICD_KEY "radiant_BuggyICD" +#define HICOLOR_KEY "radiant_HiColorTextures" +#define CHASEMOUSE_KEY "radiant_ChaseMouse" +#define ENTITYSHOW_KEY "radiant_EntityShow" +#define TEXTURESCALE_KEY "radiant_TextureScale" +#define TEXTURESCROLLBAR_KEY "radiant_TextureScrollbar" +#define DISPLAYLISTS_KEY "radiant_UseDisplayLists" +#define NORMALIZECOLORS_KEY "radiant_NormalizeColors" +#define SHADERS_KEY "radiant_UseShaders" +#define SWITCHCLIP_KEY "radiant_SwitchClipKey" +#define SELWHOLEENTS_KEY "radiant_SelectWholeEntitiesKey" +#define TEXTURESUBSET_KEY "radiant_UseTextureSubsetLoading" +#define TEXTUREQUALITY_KEY "radiant_TextureQuality" +#define SHOWSHADERS_KEY "radiant_ShowShaders" +#define SHADERTEST_KEY "radiant_ShaderTest" +#define GLLIGHTING_KEY "radiant_UseGLLighting" +#define NOSTIPPLE_KEY "radiant_NoStipple" +#define UNDOLEVELS_KEY "radiant_UndoLevels" +#define MAPS_KEY "radiant_RadiantMapPath" +#define MODELS_KEY "radiant_ModelPath" +#define NEWMAPFORMAT_KEY "radiant_NewMapFormat" + +#define WINDOW_DEF 0 +#define TLOCK_DEF 1 +#define LOADLAST_DEF 1 +#define RUN_DEF 0 + +///////////////////////////////////////////////////////////////////////////// +// CPrefsDlg dialog + + +CPrefsDlg::CPrefsDlg(CWnd* pParent /*=NULL*/) + : CDialog(CPrefsDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CPrefsDlg) + m_bLoadLast = FALSE; + m_bFace = FALSE; + m_bRightClick = FALSE; + m_bVertex = FALSE; + m_bAutoSave = TRUE; + m_bNewApplyHandling = FALSE; + m_strAutoSave = _T("5"); + m_bLoadLastMap = FALSE; + m_bTextureWindow = FALSE; + m_bSnapShots = FALSE; + m_fTinySize = 0.5; + m_bCleanTiny = FALSE; + m_nStatusSize = 10; + m_bCamXYUpdate = FALSE; + m_bNewLightDraw = FALSE; + m_bALTEdge = FALSE; + m_bQE4Painting = TRUE; + m_bSnapTToGrid = FALSE; + m_bXZVis = FALSE; + m_bYZVis = FALSE; + m_bZVis = FALSE; + m_bSizePaint = FALSE; + m_bWideToolbar = TRUE; + m_bNoClamp = FALSE; + m_nRotation = 0; + m_bHiColorTextures = TRUE; + m_bChaseMouse = FALSE; + m_bTextureScrollbar = TRUE; + m_bDisplayLists = TRUE; + m_bNoStipple = FALSE; + m_strMaps = _T(""); + m_strModels = _T(""); + m_bNewMapFormat = TRUE; + //}}AFX_DATA_INIT + //LoadPrefs(); + m_selectByBoundingBrush = FALSE; + m_selectOnlyBrushes = FALSE; + m_selectNoModels = FALSE; + m_nEntityShowState = 0; + m_nTextureScale = 2; + m_bSwitchClip = FALSE; + m_bSelectWholeEntities = TRUE; + m_nTextureQuality = 3; + m_bGLLighting = FALSE; + m_nUndoLevels = 63; +} + +void CPrefsDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPrefsDlg) + DDX_Control(pDX, IDC_SPIN_UNDO, m_wndUndoSpin); + DDX_Control(pDX, IDC_SPIN_POINTSIZE, m_wndFontSpin); + DDX_Control(pDX, IDC_SLIDER_TEXTUREQUALITY, m_wndTexturequality); + DDX_Control(pDX, IDC_SLIDER_CAMSPEED, m_wndCamSpeed); + DDX_Control(pDX, IDC_SPIN_AUTOSAVE, m_wndSpin); + DDX_Check(pDX, IDC_CHECK_LOADLAST, m_bLoadLast); + DDX_Check(pDX, IDC_CHECK_FACE, m_bFace); + DDX_Check(pDX, IDC_CHECK_RIGHTCLICK, m_bRightClick); + DDX_Check(pDX, IDC_CHECK_AUTOSAVE, m_bAutoSave); + DDX_Text(pDX, IDC_EDIT_AUTOSAVE, m_strAutoSave); + DDX_Check(pDX, IDC_CHECK_LOADLASTMAP, m_bLoadLastMap); + DDX_Check(pDX, IDC_CHECK_TEXTUREWINDOW, m_bTextureWindow); + DDX_Check(pDX, IDC_CHECK_SNAPSHOTS, m_bSnapShots); + DDX_Text(pDX, IDC_EDIT_STATUSPOINTSIZE, m_nStatusSize); + DDV_MinMaxInt(pDX, m_nStatusSize, 2, 14); + DDX_Check(pDX, IDC_CHECK_CAMXYUPDATE, m_bCamXYUpdate); + DDX_Check(pDX, IDC_CHECK_LIGHTDRAW, m_bNewLightDraw); + DDX_Check(pDX, IDC_CHECK_ALTDRAG, m_bALTEdge); + DDX_Check(pDX, IDC_CHECK_QE4PAINTING, m_bQE4Painting); + DDX_Check(pDX, IDC_CHECK_SNAPT, m_bSnapTToGrid); + DDX_Check(pDX, IDC_CHECK_SIZEPAINT, m_bSizePaint); + DDX_Check(pDX, IDC_CHECK_WIDETOOLBAR, m_bWideToolbar); + DDX_Check(pDX, IDC_CHECK_NOCLAMP, m_bNoClamp); + DDX_Text(pDX, IDC_EDIT_ROTATION, m_nRotation); + DDX_Check(pDX, IDC_CHECK_HICOLOR, m_bHiColorTextures); + DDX_Check(pDX, IDC_CHECK_MOUSECHASE, m_bChaseMouse); + DDX_Check(pDX, IDC_CHECK_TEXTURESCROLLBAR, m_bTextureScrollbar); + DDX_Check(pDX, IDC_CHECK_DISPLAYLISTS, m_bDisplayLists); + DDX_Check(pDX, IDC_CHECK_NOSTIPPLE, m_bNoStipple); + DDX_Text(pDX, IDC_EDIT_UNDOLEVELS, m_nUndoLevels); + DDV_MinMaxInt(pDX, m_nUndoLevels, 1, 64); + DDX_Text(pDX, IDC_EDIT_MAPS, m_strMaps); + DDX_Check(pDX, IDC_CHECK_NEWMAPFORMAT, m_bNewMapFormat); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CPrefsDlg, CDialog) + //{{AFX_MSG_MAP(CPrefsDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPrefsDlg message handlers + +BOOL CPrefsDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_wndSpin.SetRange(1,60); + m_wndCamSpeed.SetRange(10, 5000); + m_wndCamSpeed.SetPos(m_nMoveSpeed); + + this->m_wndTexturequality.SetRange(0, 3); + this->m_wndTexturequality.SetPos(m_nTextureQuality); + + m_wndFontSpin.SetRange(4,24); + m_wndUndoSpin.SetRange(1,64); + + GetDlgItem(IDC_CHECK_HICOLOR)->EnableWindow(TRUE); + GetDlgItem(IDC_CHECK_NOCLAMP)->EnableWindow(TRUE); + + //GetDlgItem(IDC_CHECK_NOCLAMP)->EnableWindow(FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CPrefsDlg::OnOK() +{ + m_nMoveSpeed = m_wndCamSpeed.GetPos(); + m_nAngleSpeed = (float)m_nMoveSpeed * 0.50; + this->m_nTextureQuality = m_wndTexturequality.GetPos(); + SavePrefs(); + + if ( g_pParentWnd ) { + g_pParentWnd->SetGridStatus(); + } + Sys_UpdateWindows(W_ALL); + Undo_SetMaxSize(m_nUndoLevels); + CDialog::OnOK(); +} + +int GetCvarInt(const char *name, const int def) { + idCVar *cvar = cvarSystem->Find( name ); + if ( cvar ) { + return cvar->GetInteger(); + } else { + return def; + } +} + +const char *GetCvarString( const char *name, const char *def ) { + idCVar *cvar = cvarSystem->Find( name ); + if ( cvar ) { + return cvar->GetString(); + } else { + return def; + } +} + +static const char hexDigits[] = "0123456789ABCDEF"; + +void SetCvarInt( const char *name, const int value ) { + cvarSystem->SetCVarInteger( name, value, CVAR_TOOL ); +} + +void SetCvarString( const char *name, const char *value ) { + cvarSystem->SetCVarString( name, value, CVAR_TOOL ); +} + +void SetCvarBinary(const char *name, void *pv, int size) { + unsigned char *in = new unsigned char[size]; + idStr s; + memset( in, 0, size ); + memcpy( in, pv, size ); + for ( int i = 0; i < size; i++ ) { + s += hexDigits[in[i] >> 4]; + s += hexDigits[in[i] & 0x0f]; + } + delete []in; + SetCvarString(name, s); +} + +bool GetCvarBinary( const char *name, void *pv, int size ) { + bool ret = false; + unsigned char *out = new unsigned char[size]; + idStr s = GetCvarString( name, "" ); + if ( s.Length() / 2 == size ) { + int j = 0; + for ( int i = 0; i < s.Length(); i += 2 ) { + char c; + if (s[i] > '9') { + c = s[i] - 'A' + 0x0a; + } else { + c = s[i] - 0x30; + } + c <<= 4; + if (s[i+1] > '9') { + c |= s[i+1] - 'A' + 0x0a; + } else { + c |= s[i+1] - 0x30; + } + out[j++] = c; + } + memcpy(pv, out, size); + ret = true; + } + delete []out; + return ret; +} + +void CPrefsDlg::LoadPrefs() { + CString strBuff; + CString strPrefab = g_strAppPath; + AddSlash(strPrefab); + strPrefab += "Prefabs\\"; + + m_nMouseButtons = 3; + + m_bTextureLock = GetCvarInt( TLOCK_KEY, TLOCK_DEF ); + m_bRotateLock = GetCvarInt( RLOCK_KEY, TLOCK_DEF ); + m_strLastProject = GetCvarString( LASTPROJ_KEY, "" ); + m_strLastMap = GetCvarString( LASTMAP_KEY, "" ); + m_bLoadLast = GetCvarInt( LOADLAST_KEY, LOADLAST_DEF ); + m_bRunBefore = GetCvarInt( RUN_KEY, RUN_DEF ); + m_bFace = GetCvarInt( FACE_KEY, 1 ); + m_bRightClick = GetCvarInt( RCLICK_KEY, 1 ); + m_bVertex = GetCvarInt( VERTEX_KEY, 1 ); + m_bAutoSave = GetCvarInt( AUTOSAVE_KEY, 1 ); + m_bNewApplyHandling = GetCvarInt( NEWAPPLY_KEY, 0 ); + m_bLoadLastMap = GetCvarInt( LOADLASTMAP_KEY, 0 ); + m_bGatewayHack = GetCvarInt( HACK_KEY, 0 ); + m_bTextureWindow = GetCvarInt( TEXTURE_KEY, 0 ); + m_bCleanTiny = GetCvarInt( TINYBRUSH_KEY, 0 ); + strBuff = GetCvarString( TINYSIZE_KEY, "0.5" ); + m_fTinySize = atof(strBuff ); + m_nAutoSave = GetCvarInt( AUTOSAVETIME_KEY, 5 ); + if ( m_nAutoSave <= 0 ) { m_nAutoSave = 1; } + m_strAutoSave.Format("%i", m_nAutoSave ); + m_bSnapShots = GetCvarInt( SNAPSHOT_KEY, 0 ); + m_nStatusSize = GetCvarInt( STATUS_KEY, 10 ); + m_nMoveSpeed = GetCvarInt( MOVESPEED_KEY, 400 ); + m_nAngleSpeed = GetCvarInt( ANGLESPEED_KEY, 300 ); + m_bCamXYUpdate = GetCvarInt( CAMXYUPDATE_KEY, 1 ); + m_bNewLightDraw = GetCvarInt( LIGHTDRAW_KEY, 1 ); + m_bCubicClipping = ( GetCvarInt( CUBICCLIP_KEY, 1) != 0 ); + m_nCubicScale = GetCvarInt( CUBICSCALE_KEY, 13 ); + m_bALTEdge = GetCvarInt( ALTEDGE_KEY, 0 ); + m_bQE4Painting = GetCvarInt( QE4PAINT_KEY, 1 ); + m_bSnapTToGrid = GetCvarInt( SNAPT_KEY, 0 ); + m_bXZVis = GetCvarInt( XZVIS_KEY, 0 ); + m_bYZVis = GetCvarInt( YZVIS_KEY, 0 ); + m_bZVis = GetCvarInt( ZVIS_KEY, 1 ); + m_bSizePaint = GetCvarInt( SIZEPAINT_KEY, 0 ); + m_bWideToolbar = GetCvarInt( WIDETOOLBAR_KEY, 1 ); + m_bNoClamp = GetCvarInt( NOCLAMP_KEY, 0 ); + m_nRotation = GetCvarInt( ROTATION_KEY, 45 ); + m_bHiColorTextures = GetCvarInt( HICOLOR_KEY, 1 ); + m_bChaseMouse = GetCvarInt( CHASEMOUSE_KEY, 1 ); + m_nEntityShowState = GetCvarInt( ENTITYSHOW_KEY, 0 ); + m_nTextureScale = GetCvarInt( TEXTURESCALE_KEY, 50 ); + m_bTextureScrollbar = GetCvarInt( TEXTURESCROLLBAR_KEY, TRUE ); + m_bDisplayLists = GetCvarInt( DISPLAYLISTS_KEY, TRUE ); + m_bSwitchClip = GetCvarInt( SWITCHCLIP_KEY, TRUE ); + m_bSelectWholeEntities = GetCvarInt( SELWHOLEENTS_KEY, TRUE ); + m_nTextureQuality = GetCvarInt( TEXTUREQUALITY_KEY, 6 ); + m_bGLLighting = GetCvarInt( GLLIGHTING_KEY, FALSE ); + m_bNoStipple = GetCvarInt( NOSTIPPLE_KEY, 0 ); + m_nUndoLevels = GetCvarInt( UNDOLEVELS_KEY, 63 ); + m_strMaps = GetCvarString( MAPS_KEY, "" ); + m_strModels = GetCvarString( MODELS_KEY, "" ); + m_bNoStipple = GetCvarInt( NEWMAPFORMAT_KEY, 1 ); + + if ( m_bRunBefore == FALSE ) { + SetGamePrefs(); + } +} + +void CPrefsDlg::SavePrefs() { + if ( GetSafeHwnd() ) { + UpdateData(TRUE); + } + + m_nMouseButtons = 3; + + SetCvarInt( TLOCK_KEY, m_bTextureLock ); + SetCvarInt( RLOCK_KEY, m_bRotateLock ); + SetCvarInt( LOADLAST_KEY, m_bLoadLast ); + SetCvarString( LASTPROJ_KEY, m_strLastProject ); + SetCvarString( LASTMAP_KEY, m_strLastMap ); + SetCvarInt( RUN_KEY, m_bRunBefore ); + SetCvarInt( FACE_KEY, m_bFace ); + SetCvarInt( RCLICK_KEY, m_bRightClick ); + SetCvarInt( VERTEX_KEY, m_bVertex ); + SetCvarInt( AUTOSAVE_KEY, m_bAutoSave ); + SetCvarInt( LOADLASTMAP_KEY, m_bLoadLastMap ); + SetCvarInt( TEXTURE_KEY, m_bTextureWindow ); + m_nAutoSave = atoi( m_strAutoSave ); + SetCvarInt( AUTOSAVETIME_KEY, m_nAutoSave ); + SetCvarInt( SNAPSHOT_KEY, m_bSnapShots ); + SetCvarInt( STATUS_KEY, m_nStatusSize ); + SetCvarInt( CAMXYUPDATE_KEY, m_bCamXYUpdate ); + SetCvarInt( LIGHTDRAW_KEY, m_bNewLightDraw ); + SetCvarInt( MOVESPEED_KEY, m_nMoveSpeed ); + SetCvarInt( ANGLESPEED_KEY, m_nAngleSpeed ); + SetCvarInt( CUBICCLIP_KEY, m_bCubicClipping ); + SetCvarInt( CUBICSCALE_KEY, m_nCubicScale ); + SetCvarInt( ALTEDGE_KEY, m_bALTEdge ); + SetCvarInt( QE4PAINT_KEY, m_bQE4Painting ); + SetCvarInt( SNAPT_KEY, m_bSnapTToGrid ); + SetCvarInt( XZVIS_KEY, m_bXZVis ); + SetCvarInt( YZVIS_KEY, m_bYZVis ); + SetCvarInt( ZVIS_KEY, m_bZVis ); + SetCvarInt( SIZEPAINT_KEY, m_bSizePaint ); + SetCvarInt( WIDETOOLBAR_KEY, m_bWideToolbar ); + SetCvarInt( NOCLAMP_KEY, m_bNoClamp ); + SetCvarInt( ROTATION_KEY, m_nRotation ); + SetCvarInt( HICOLOR_KEY, m_bHiColorTextures ); + SetCvarInt( CHASEMOUSE_KEY, m_bChaseMouse ); + SetCvarInt( ENTITYSHOW_KEY, m_nEntityShowState ); + SetCvarInt( TEXTURESCALE_KEY, m_nTextureScale ); + SetCvarInt( TEXTURESCROLLBAR_KEY, m_bTextureScrollbar ); + SetCvarInt( DISPLAYLISTS_KEY, m_bDisplayLists ); + SetCvarInt( SWITCHCLIP_KEY, m_bSwitchClip ); + SetCvarInt( SELWHOLEENTS_KEY, m_bSelectWholeEntities ); + SetCvarInt( TEXTUREQUALITY_KEY, m_nTextureQuality ); + SetCvarInt( GLLIGHTING_KEY, m_bGLLighting ); + SetCvarInt( NOSTIPPLE_KEY, m_bNoStipple ); + SetCvarInt( UNDOLEVELS_KEY, m_nUndoLevels ); + SetCvarString( MAPS_KEY, m_strMaps ); + SetCvarString( MODELS_KEY, m_strModels ); + SetCvarInt( NEWMAPFORMAT_KEY, m_bNewMapFormat ); + common->WriteFlaggedCVarsToFile( "editor.cfg", CVAR_TOOL, "sett" ); +} + +void CPrefsDlg::SetGamePrefs() { + m_bHiColorTextures = TRUE; + m_bWideToolbar = TRUE; + SavePrefs(); +} diff --git a/tools/radiant/PrefsDlg.h b/tools/radiant/PrefsDlg.h new file mode 100644 index 000000000..457131d88 --- /dev/null +++ b/tools/radiant/PrefsDlg.h @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __PREFSDLG_H__ +#define __PREFSDLG_H__ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +///////////////////////////////////////////////////////////////////////////// +// CPrefsDlg dialog + +#define MAX_TEXTURE_QUALITY 3 + +class CPrefsDlg : public CDialog +{ +// Construction +public: + CPrefsDlg(CWnd* pParent = NULL); // standard constructor + + void LoadPrefs(); + void SavePrefs(); + void SetGamePrefs(); + +// Dialog Data + //{{AFX_DATA(CPrefsDlg) + enum { IDD = IDD_DLG_PREFS }; + + CSpinButtonCtrl m_wndUndoSpin; + CSpinButtonCtrl m_wndFontSpin; + CSliderCtrl m_wndTexturequality; + CSliderCtrl m_wndCamSpeed; + CSpinButtonCtrl m_wndSpin; + BOOL m_bTextureLock; + BOOL m_bLoadLast; + BOOL m_bRunBefore; + CString m_strLastProject; + CString m_strLastMap; + BOOL m_bFace; + BOOL m_bRightClick; + BOOL m_bVertex; + BOOL m_bAutoSave; + BOOL m_bNewApplyHandling; + CString m_strAutoSave; + BOOL m_bLoadLastMap; + BOOL m_bGatewayHack; + BOOL m_bTextureWindow; + BOOL m_bSnapShots; + float m_fTinySize; + BOOL m_bCleanTiny; + int m_nStatusSize; + BOOL m_bCamXYUpdate; + BOOL m_bNewLightDraw; + BOOL m_bALTEdge; + BOOL m_bQE4Painting; + BOOL m_bSnapTToGrid; + BOOL m_bXZVis; + BOOL m_bYZVis; + BOOL m_bZVis; + BOOL m_bSizePaint; + BOOL m_bRotateLock; + BOOL m_bWideToolbar; + BOOL m_bNoClamp; + int m_nRotation; + BOOL m_bHiColorTextures; + BOOL m_bChaseMouse; + BOOL m_bTextureScrollbar; + BOOL m_bDisplayLists; + BOOL m_bNoStipple; + int m_nUndoLevels; + CString m_strMaps; + CString m_strModels; + BOOL m_bNewMapFormat; + //}}AFX_DATA + int m_nMouseButtons; + int m_nAngleSpeed; + int m_nMoveSpeed; + int m_nAutoSave; + bool m_bCubicClipping; + int m_nCubicScale; + BOOL m_selectOnlyBrushes; + BOOL m_selectNoModels; + BOOL m_selectByBoundingBrush; + int m_nEntityShowState; + int m_nTextureScale; + BOOL m_bNormalizeColors; + BOOL m_bSwitchClip; + BOOL m_bSelectWholeEntities; + int m_nTextureQuality; + BOOL m_bGLLighting; + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPrefsDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +protected: + // Generated message map functions + //{{AFX_MSG(CPrefsDlg) + afx_msg void OnBtnBrowse(); + virtual BOOL OnInitDialog(); + virtual void OnOK(); + afx_msg void OnBtnBrowsepak(); + afx_msg void OnBtnBrowseprefab(); + afx_msg void OnBtnBrowseuserini(); + afx_msg void OnSelchangeComboWhatgame(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#endif /* !__PREFSDLG_H__ */ diff --git a/tools/radiant/PreviewDlg.cpp b/tools/radiant/PreviewDlg.cpp new file mode 100644 index 000000000..e8bd3a66a --- /dev/null +++ b/tools/radiant/PreviewDlg.cpp @@ -0,0 +1,660 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "WaitDlg.h" +#include "PreviewDlg.h" +#include "CommentsDlg.h" + +const int PARENTID = 99999; + +extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent); + +// CPreviewDlg dialog + +IMPLEMENT_DYNAMIC(CPreviewDlg, CDialog) +CPreviewDlg::CPreviewDlg(CWnd* pParent /*=NULL*/) + : CDialog(CPreviewDlg::IDD, pParent) +{ + currentMode = MODELS; + disablePreview = false; +} + +CPreviewDlg::~CPreviewDlg() +{ +} + +void CPreviewDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TREE_MEDIA, treeMedia); + DDX_Control(pDX, IDC_EDIT_INFO, editInfo); + DDX_Control(pDX, IDC_PREVIEW, wndPreview); +} + + +BEGIN_MESSAGE_MAP(CPreviewDlg, CDialog) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_MEDIA, OnTvnSelchangedTreeMedia) + ON_BN_CLICKED(IDC_BUTTON_RELOAD, OnBnClickedButtonReload) + ON_BN_CLICKED(IDC_BUTTON_ADD, OnBnClickedButtonAdd) + ON_BN_CLICKED(IDC_BUTTON_PLAY, OnBnClickedButtonPlay) +END_MESSAGE_MAP() + + +// CPreviewDlg message handlers + +BOOL CPreviewDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_image.Create(IDB_BITMAP_MATERIAL, 16, 1, RGB(255, 255, 255)); + treeMedia.SetImageList(&m_image, TVSIL_NORMAL); + if ( disablePreview ) { + wndPreview.ShowWindow( SW_HIDE ); + } else { + wndPreview.setDrawable(&m_testDrawable); + } + + SetMode(currentMode); + BuildTree(); + + if ( mediaName.Length() ) { + HTREEITEM root = treeMedia.GetRootItem(); + HTREEITEM sel = FindTreeItem(&treeMedia, root, mediaName, NULL ); + if (sel) { + treeMedia.SelectItem(sel); + } + } + mediaName = ""; + return TRUE; // return TRUE unless you set the focus to a control + +} + +void CPreviewDlg::BuildTree() { + + CWaitCursor cursor; + quickTree.Clear(); + treeMedia.DeleteAllItems(); + + idFileList *files; + + if ( currentMode == GUIS ) { + files = fileSystem->ListFilesTree( "guis", ".gui" ); + AddStrList( "base", files->GetList(), GUIS ); + fileSystem->FreeFileList( files ); + } else if ( currentMode == MODELS ) { + files = fileSystem->ListFilesTree( "models", ".lwo" ); + AddStrList( "base", files->GetList(), MODELS ); + fileSystem->FreeFileList( files ); + files = fileSystem->ListFilesTree( "models", ".ase" ); + AddStrList( "base", files->GetList(), MODELS ); + fileSystem->FreeFileList( files ); + files = fileSystem->ListFilesTree( "models", ".ma" ); + AddStrList( "base", files->GetList(), MODELS ); + fileSystem->FreeFileList( files ); + } else if ( currentMode == SOUNDS ) { + AddSounds( true ); + } else if ( currentMode == MATERIALS ) { + AddMaterials( true ); + } else if ( currentMode == PARTICLES ) { + AddParticles( true ); + } else if ( currentMode == SKINS ) { + AddSkins( true ); + } +} + +void CPreviewDlg::RebuildTree( const char *_data ) { + data = _data; + data.ToLower(); + BuildTree(); +} + +void CPreviewDlg::AddCommentedItems() { + const char *buffer = NULL; + const char *path; + items.Clear(); + path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented"; + idParser src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + if (fileSystem->ReadFile(path, (void**)&buffer, NULL) && buffer) { + src.LoadMemory(buffer, strlen(buffer), path); + if (src.IsLoaded()) { + idToken token, tok1, tok2, tok3; + while( src.ReadToken( &token ) ) { + if (token == "{") { + // start a new commented item + CommentedItem ci; + if (src.ReadToken(&tok1) && src.ReadToken(&tok2) && src.ReadToken(&tok3)) { + ci.Name = tok1; + ci.Path = tok2; + ci.Comments = tok3; + items.Append(ci); + } + } + } + } + fileSystem->FreeFile((void*)buffer); + } + commentItem = treeMedia.InsertItem("Commented"); + int c = items.Num(); + if (c) { + for (int i = 0; i < c; i++) { + HTREEITEM child = treeMedia.InsertItem(items[i].Name, commentItem); + treeMedia.SetItemData(child, -1 - i); + treeMedia.SetItemImage(child, 2, 2); + } + } +} + + + +void CPreviewDlg::AddStrList( const char *root, const idStrList &list, int id ) { + idStr out, path; + HTREEITEM base = treeMedia.GetRootItem(); + if (base) { + out = treeMedia.GetItemText(base); + if (stricmp(root, out)) { + base = NULL; + } + } + + if (base == NULL) { + base = treeMedia.InsertItem(root); + treeMedia.SetItemData(base, PARENTID); + } + + HTREEITEM item = base; + HTREEITEM add; + + int count = list.Num(); + + idStr last, qt; + for (int i = 0; i < count; i++) { + idStr name = list[i]; + + // now break the name down convert to slashes + name.BackSlashesToSlashes(); + name.Strip(' '); + + int index; + int len = last.Length(); + if (len == 0) { + index = name.Last('/'); + if (index >= 0) { + name.Left(index, last); + } + } + else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) { + name.Right(name.Length() - len - 1, out); + add = treeMedia.InsertItem(out, item); + qt = root; + qt += "/"; + qt += name; + quickTree.Set(qt, add); + treeMedia.SetItemImage(add, 2, 2); + treeMedia.SetItemData(add, id); + continue; + } + else { + last.Empty(); + } + + index = 0; + item = base; + path = ""; + while (index >= 0) { + index = name.Find('/'); + if (index >= 0) { + HTREEITEM newItem = NULL; + HTREEITEM *check = NULL; + name.Left( index, out ); + path += out; + qt = root; + qt += "/"; + qt += path; + if (quickTree.Get(qt, &check)) { + newItem = *check; + } + //HTREEITEM newItem = FindTreeItem(&treeMedia, item, name.Left(index, out), item); + if (newItem == NULL) { + newItem = treeMedia.InsertItem(out, item); + qt = root; + qt += "/"; + qt += path; + quickTree.Set(qt, newItem); + treeMedia.SetItemImage(newItem, 0, 1); + treeMedia.SetItemData(newItem, PARENTID); + } + + assert(newItem); + item = newItem; + name.Right(name.Length() - index - 1, out); + name = out; + path += "/"; + } + else { + add = treeMedia.InsertItem(name, item); + qt = root; + qt += "/"; + qt += path; + qt += name; + quickTree.Set(qt, add); + treeMedia.SetItemImage(add, 2, 2); + treeMedia.SetItemData(add, id); + path = ""; + } + } + } + +} + +void CPreviewDlg::OnTvnSelchangedTreeMedia(NMHDR *pNMHDR, LRESULT *pResult) +{ + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + HTREEITEM item = treeMedia.GetSelectedItem(); + mediaName = ""; + CWnd *add = GetDlgItem(IDC_BUTTON_ADD); + if (add) { + add->EnableWindow(treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS); + } + if (item) { + + editInfo.SetWindowText("No comments for this item"); + int id = treeMedia.GetItemData(item); + if ( id == GUIS || id == MODELS || id == MATERIALS || id == WAVES || id == PARTICLES || id == SKINS ) { + mediaName = treeMedia.GetItemText( item ); + + // have to build the name back up + HTREEITEM parent = treeMedia.GetParentItem( item ); + while ( parent != NULL ) { + idStr strParent = treeMedia.GetItemText( parent ); + strParent += "/"; + strParent += mediaName; + mediaName = strParent; + parent = treeMedia.GetParentItem( parent ); + } + // strip the leading "base/" + if (id == MATERIALS) { + mediaName.Strip("Materials/"); + } else if (id == WAVES) { + mediaName.Strip( "Wave files/" ); + } else if (id == PARTICLES) { + mediaName.Strip("Particles/"); + mediaName += ".prt"; + } else if ( id == SKINS ) { + mediaName.Strip( "Matching Skins/" ); + mediaName.Strip( "Skins/" ); + } else { + mediaName.Strip( "base/" ); + } + + } else if (id == WAVES || id == SOUNDS) { + mediaName = treeMedia.GetItemText( item ); + } else if (id < 0) { + if ( treeMedia.ItemHasChildren(item) == FALSE ) { + int dw = abs(( int )treeMedia.GetItemData( item )) - 1; + if ( dw < items.Num() ) { + idStr work = items[dw].Path; + work += "\r\n\r\n"; + work += items[dw].Comments; + editInfo.SetWindowText( work ); + mediaName = items[dw].Path; + } + } + } + + if ( currentMode == MODELS || currentMode == SKINS ) { + idStr modelMedia; + if ( currentMode == MODELS ) { + modelMedia = mediaName; + } else { + modelMedia = data; + } + if ( modelMedia.Length() ) { + int size = fileSystem->ReadFile( modelMedia, NULL, NULL ); + int lsize; + if ( strstr( modelMedia, ".lwo" ) ) { + lsize = 128 * 1024; + } + else { + lsize = 768 * 1024; + } + if ( size > lsize ) { + if ( MessageBox("Model appears to be quite large, are you sure you want to preview it?", "High Poly Model?", MB_YESNO ) == IDNO ) { + *pResult = 0; + return; + } + } + m_drawModel.setMedia( modelMedia ); + if ( currentMode == SKINS ) { + m_drawModel.SetSkin( mediaName ); + } + } + m_drawModel.SetRealTime(0); + wndPreview.setDrawable( &m_drawModel ); + wndPreview.Invalidate(); + wndPreview.RedrawWindow(); + RedrawWindow(); + } + else if ( currentMode == PARTICLES ) { + m_drawModel.setMedia( mediaName ); + m_drawModel.SetRealTime(50); + wndPreview.setDrawable( &m_drawModel ); + wndPreview.Invalidate(); + wndPreview.RedrawWindow(); + RedrawWindow(); + } else if ( currentMode == GUIS ) { + const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview"); + mat->SetGui(mediaName); + m_drawMaterial.setMedia("guisurfs/guipreview"); + m_drawMaterial.setScale(4.4f); + wndPreview.setDrawable(&m_drawMaterial); + wndPreview.Invalidate(); + wndPreview.RedrawWindow(); + idUserInterface *gui = uiManager->FindGui( mediaName, false, false, true ); + if ( gui ) { + idStr str = gui->Comment(); + str.Replace( "\n", "\r\n" ); + if ( str != "" ) { + editInfo.SetWindowText( str ); + } + } + RedrawWindow(); + } else if (currentMode == MATERIALS) { + m_drawMaterial.setMedia(mediaName); + m_drawMaterial.setScale(1.0); + wndPreview.setDrawable(&m_drawMaterial); + wndPreview.Invalidate(); + wndPreview.RedrawWindow(); + RedrawWindow(); + } + + //m_drawGui.setMedia(matName); + //wndPreview.setDrawable(&m_drawMaterial); + //wndPreview.RedrawWindow(); + } + + *pResult = 0; +} + + +BOOL CPreviewDlg::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd) +{ + BOOL b = CDialog::Create(lpszTemplateName, pParentWnd); + ShowWindow(SW_SHOW); + return b; +} + +void CPreviewDlg::OnCancel() +{ + if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) { + GetParent()->EnableWindow(TRUE); + g_qeglobals.sw->StopAllSounds(); + ShowWindow(SW_HIDE); + } else { + CDialog::OnCancel(); + } + returnCode = IDCANCEL; +} + +void CPreviewDlg::OnOK() +{ + if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) { + GetParent()->EnableWindow(TRUE); + g_qeglobals.sw->StopAllSounds(); + ShowWindow(SW_HIDE); + } else { + CDialog::OnOK(); + } + returnCode = IDOK; +} + +bool CPreviewDlg::Waiting() { + AfxGetApp()->PumpMessage(); + return (returnCode == -1); +} + +void CPreviewDlg::SetModal() { + returnCode = -1; +} +void CPreviewDlg::OnBnClickedButtonReload() +{ + BuildTree(); + g_qeglobals.sw->StopAllSounds(); +} + +void CPreviewDlg::OnBnClickedButtonAdd() +{ + HTREEITEM item = treeMedia.GetSelectedItem(); + if (treeMedia.ItemHasChildren(item) == FALSE && (treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS)) { + CCommentsDlg dlg; + dlg.strPath = mediaName; + if (dlg.DoModal()) { + CommentedItem ci; + ci.Name = dlg.strName; + ci.Path = dlg.strPath; + ci.Comments = dlg.strComments; + items.Append(ci); + item = treeMedia.InsertItem(ci.Name, commentItem); + treeMedia.SetItemData(item, -1 - (items.Num() + 1)); + treeMedia.SetItemImage(item, 2, 2); + const char *path; + path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented"; + idStr str; + void *buffer; + fileSystem->ReadFile( path, &buffer ); + str = (char *) buffer; + fileSystem->FreeFile( buffer ); + str += "\r\n\r\n{\r\n\t\""; + str += ci.Name; + str += "\"\r\n\t\""; + str += ci.Path; + str += "\"\r\n\t\""; + str += ci.Comments; + str += "\"\r\n}\r\n"; + fileSystem->WriteFile(path, (void*)&str[0], str.Length(), "fs_devpath"); + + } + } +} + + +void CPreviewDlg::AddSounds(bool rootItems) { + int i, j; + idStrList list(1024); + idStrList list2(1024); + HTREEITEM base = treeMedia.InsertItem("Sound Shaders"); + + for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++ ) { + const idSoundShader *poo = declManager->SoundByIndex( i, false ); + list.AddUnique( poo->GetFileName() ); + } + list.Sort(); + + for ( i = 0; i < list.Num(); i++ ) { + HTREEITEM child = treeMedia.InsertItem(list[i], base); + treeMedia.SetItemData(child, SOUNDPARENT); + treeMedia.SetItemImage(child, 0, 1); + list2.Clear(); + for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) { + const idSoundShader *poo = declManager->SoundByIndex( j, false ); + if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) { + list2.Append( poo->GetName() ); + } + } + list2.Sort(); + for (j = 0; j < list2.Num(); j++) { + HTREEITEM child2 = treeMedia.InsertItem( list2[j], child ); + treeMedia.SetItemData(child2, SOUNDS); + treeMedia.SetItemImage(child2, 2, 2); + } + } + + idFileList *files; + files = fileSystem->ListFilesTree( "sound", ".wav" ); + AddStrList( "Wave files", files->GetList(), WAVES ); + fileSystem->FreeFileList( files ); +} + +void CPreviewDlg::SetMode( int mode, const char *preSelect ) { + + currentMode = mode; + if ( preSelect ) { + mediaName = preSelect; + } + + if (GetSafeHwnd() == NULL) { + return; + } + + CWnd *wnd; + switch (currentMode) { + case GUIS : + case SKINS : + case MODELS : + case PARTICLES : + wndPreview.ShowWindow(SW_SHOW); + wnd = GetDlgItem(IDC_BUTTON_PLAY); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + wnd = GetDlgItem(IDC_BUTTON_ADD); + if (wnd) { + wnd->ShowWindow(SW_SHOW); + } + wnd = GetDlgItem(IDC_EDIT_INFO); + if (wnd) { + wnd->ShowWindow(SW_SHOW); + } + break; + case MATERIALS : + wndPreview.ShowWindow(SW_SHOW); + wnd = GetDlgItem(IDC_BUTTON_PLAY); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + wnd = GetDlgItem(IDC_BUTTON_ADD); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + wnd = GetDlgItem(IDC_EDIT_INFO); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + break; + case SOUNDS : + case WAVES : + wndPreview.ShowWindow(SW_HIDE); + wnd = GetDlgItem(IDC_BUTTON_PLAY); + if (wnd) { + wnd->ShowWindow(SW_SHOW); + } + wnd = GetDlgItem(IDC_BUTTON_ADD); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + wnd = GetDlgItem(IDC_EDIT_INFO); + if (wnd) { + wnd->ShowWindow(SW_HIDE); + } + break; + } +} + +void CPreviewDlg::OnBnClickedButtonPlay() { + g_qeglobals.sw->PlayShaderDirectly(mediaName); +} + +void CPreviewDlg::AddMaterials(bool rootItems) { + idStrList list(1024); + //char temp[2048]; + int count = declManager->GetNumDecls( DECL_MATERIAL ); + if (count > 0) { + for (int i = 0; i < count; i++) { + const idMaterial *mat = declManager->MaterialByIndex(i, false); + if (!rootItems) { + if (strchr(mat->GetName(), '/') == NULL && strchr(mat->GetName(), '\\') == NULL) { + continue; + } + } + list.Append(mat->GetName()); + } + list.Sort(); + AddStrList("Materials", list, MATERIALS); + } + +} + +void CPreviewDlg::AddParticles(bool rootItems) { + idStrList list(1024); + int count = declManager->GetNumDecls( DECL_PARTICLE ); + if (count > 0) { + for (int i = 0; i < count; i++) { + const idDecl *ips = declManager->DeclByIndex( DECL_PARTICLE, i ); + if (!rootItems) { + if (strchr(ips->GetName(), '/') == NULL && strchr(ips->GetName(), '\\') == NULL) { + continue; + } + } + list.Append(ips->GetName()); + } + list.Sort(); + AddStrList("Particles", list, PARTICLES); + } +} + +void CPreviewDlg::AddSkins( bool rootItems ) { + idStrList list(1024); + idStrList list2(1024); + idStr str; + int count = declManager->GetNumDecls( DECL_SKIN ); + if (count > 0) { + for (int i = 0; i < count; i++) { + const idDeclSkin *skin = declManager->SkinByIndex(i); + if (!rootItems) { + if (strchr(skin->GetName(), '/') == NULL && strchr(skin->GetName(), '\\') == NULL) { + continue; + } + } + if ( data.Length() ) { + for ( int j = 0; j < skin->GetNumModelAssociations(); j++ ){ + str = skin->GetAssociatedModel( j ); + str.ToLower(); + if ( data.Cmp(str) == 0 ) { + list.Append(skin->GetName()); + } + } + } + list2.Append(skin->GetName()); + } + list.Sort(); + list2.Sort(); + AddStrList( "Matching Skins", list, SKINS ); + AddStrList( "Skins", list2, SKINS ); + } +} + +void CPreviewDlg::OnShowWindow( BOOL bShow, UINT status ) { + if ( bShow && AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) { + GetParent()->EnableWindow( FALSE ); + } +} diff --git a/tools/radiant/PreviewDlg.h b/tools/radiant/PreviewDlg.h new file mode 100644 index 000000000..fcbfca695 --- /dev/null +++ b/tools/radiant/PreviewDlg.h @@ -0,0 +1,92 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once +#include "afxcmn.h" +#include "afxwin.h" + + +// CPreviewDlg dialog + +struct CommentedItem { + idStr Name; + idStr Path; + idStr Comments; +}; + +class CPreviewDlg : public CDialog +{ +public: + enum {MODELS, GUIS, SOUNDS, MATERIALS, SCRIPTS, SOUNDPARENT, WAVES, PARTICLES, MODELPARENT, GUIPARENT, COMMENTED, SKINS}; + CPreviewDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CPreviewDlg(); + void SetMode( int mode, const char *preSelect = NULL ); + void RebuildTree( const char *data ); + void SetDisablePreview( bool b ) { + disablePreview = b; + } + + idStr mediaName; + int returnCode; + + bool Waiting(); + void SetModal(); +// Dialog Data + enum { IDD = IDD_DIALOG_PREVIEW }; +private: + DECLARE_DYNAMIC(CPreviewDlg) + + CTreeCtrl treeMedia; + CEdit editInfo; + HTREEITEM commentItem; + CImageList m_image; + idGLDrawable m_testDrawable; + idGLDrawableMaterial m_drawMaterial; + idGLDrawableModel m_drawModel; + idGLWidget wndPreview; + idHashTable quickTree; + idList items; + virtual BOOL OnInitDialog(); + int currentMode; + void AddCommentedItems(); + idStr data; + bool disablePreview; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + void BuildTree(); + void AddStrList(const char *root, const idStrList &list, int type); + void AddSounds(bool rootItems); + void AddMaterials(bool rootItems); + void AddParticles(bool rootItems); + void AddSkins( bool rootItems ); + + DECLARE_MESSAGE_MAP() + +public: + afx_msg void OnTvnSelchangedTreeMedia(NMHDR *pNMHDR, LRESULT *pResult); + virtual BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL); +protected: + virtual void OnCancel(); + virtual void OnOK(); + virtual void OnShowWindow( BOOL bShow, UINT status ); +public: + afx_msg void OnBnClickedButtonReload(); + afx_msg void OnBnClickedButtonAdd(); + afx_msg void OnBnClickedButtonPlay(); +}; diff --git a/tools/radiant/PropertyList.cpp b/tools/radiant/PropertyList.cpp new file mode 100644 index 000000000..f693e6cf4 --- /dev/null +++ b/tools/radiant/PropertyList.cpp @@ -0,0 +1,531 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "PropertyList.h" + +#include "../comafx/DialogColorPicker.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPropertyList + +CPropertyList::CPropertyList() { + measureItem = NULL; + updateInspectors = false; +} + +CPropertyList::~CPropertyList() { +} + + +BEGIN_MESSAGE_MAP(CPropertyList, CListBox) + //{{AFX_MSG_MAP(CPropertyList) + ON_WM_CREATE() + ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelchange) + ON_WM_LBUTTONUP() + ON_WM_KILLFOCUS() + ON_WM_LBUTTONDOWN() + ON_WM_MOUSEMOVE() + //}}AFX_MSG_MAP + ON_CBN_CLOSEUP(IDC_PROPCMBBOX, OnKillfocusCmbBox) + ON_CBN_SELCHANGE(IDC_PROPCMBBOX, OnSelchangeCmbBox) + ON_EN_KILLFOCUS(IDC_PROPEDITBOX, OnKillfocusEditBox) + ON_EN_CHANGE(IDC_PROPEDITBOX, OnChangeEditBox) + ON_BN_CLICKED(IDC_PROPBTNCTRL, OnButton) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPropertyList message handlers + +BOOL CPropertyList::PreCreateWindow(CREATESTRUCT& cs) { + if (!CListBox::PreCreateWindow(cs)) { + return FALSE; + } + + cs.style &= ~(LBS_OWNERDRAWVARIABLE | LBS_SORT); + cs.style |= LBS_OWNERDRAWFIXED; + + m_bTracking = FALSE; + m_nDivider = 0; + m_bDivIsSet = FALSE; + + return TRUE; +} + +void CPropertyList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { + if (measureItem && !measureItem->m_curValue.IsEmpty()) { + CRect rect; + GetClientRect(rect); + if (m_nDivider==0) { + m_nDivider = rect.Width() / 2; + } + rect.left = m_nDivider; + CDC * dc = GetDC(); + dc->DrawText(measureItem->m_curValue, rect, DT_CALCRECT | DT_LEFT | DT_WORDBREAK); + ReleaseDC(dc); + lpMeasureItemStruct->itemHeight = (rect.Height() >= 20) ? rect.Height() : 20; //pixels + } else { + lpMeasureItemStruct->itemHeight = 20; //pixels + } +} + + +void CPropertyList::DrawItem(LPDRAWITEMSTRUCT lpDIS) { + CDC dc; + dc.Attach(lpDIS->hDC); + CRect rectFull = lpDIS->rcItem; + CRect rect = rectFull; + if (m_nDivider==0) { + m_nDivider = rect.Width() / 2; + } + rect.left = m_nDivider; + CRect rect2 = rectFull; + rect2.right = rect.left - 1; + UINT nIndex = lpDIS->itemID; + + if (nIndex != (UINT) -1) { + //get the CPropertyItem for the current row + CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(nIndex); + //draw two rectangles, one for each row column + if (pItem->m_nItemType == PIT_VAR) { + dc.FillSolidRect(rect2,RGB(220,220,220)); + } else { + dc.FillSolidRect(rect2,RGB(192,192,192)); + } + dc.DrawEdge(rect2,EDGE_SUNKEN,BF_BOTTOMRIGHT); + dc.DrawEdge(rect,EDGE_SUNKEN,BF_BOTTOM); + + if (lpDIS->itemState == ODS_SELECTED) { + dc.DrawFocusRect(rect2); + } + + //write the property name in the first rectangle + dc.SetBkMode(TRANSPARENT); + dc.DrawText(pItem->m_propName,CRect(rect2.left+3,rect2.top+3, + rect2.right-3,rect2.bottom+3), + DT_LEFT | DT_SINGLELINE); + + //write the initial property value in the second rectangle + dc.DrawText(pItem->m_curValue,CRect(rect.left+3,rect.top+3, rect.right+3,rect.bottom+3), DT_LEFT | (pItem->m_nItemType == PIT_VAR) ? DT_WORDBREAK : DT_SINGLELINE); + } + dc.Detach(); +} + +int CPropertyList::AddItem(CString txt) { + measureItem = NULL; + int nIndex = AddString(txt); + return nIndex; +} + +int CPropertyList::AddPropItem(CPropertyItem* pItem) { + if (pItem->m_nItemType == PIT_VAR) { + measureItem = pItem; + } else { + measureItem = NULL; + } + int nIndex = AddString(_T("")); + measureItem = NULL; + SetItemDataPtr(nIndex,pItem); + return nIndex; +} + +int CPropertyList::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CListBox::OnCreate(lpCreateStruct) == -1) { + return -1; + } + + m_bDivIsSet = FALSE; + m_nDivider = 0; + m_bTracking = FALSE; + + m_hCursorSize = AfxGetApp()->LoadStandardCursor(IDC_SIZEWE); + m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + m_SSerif8Font.CreatePointFont(80,_T("MS Sans Serif")); + + return 0; +} + +void CPropertyList::OnSelchange() { + CRect rect; + CString lBoxSelText; + static int recurse = 0; + //m_curSel = GetCurSel(); + + + GetItemRect(m_curSel,rect); + rect.left = m_nDivider; + + CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel); + + if (updateInspectors) { + g_Inspectors->entityDlg.SetKeyVal(pItem->m_propName, pItem->m_curValue); + } + + if (m_btnCtrl) { + m_btnCtrl.ShowWindow(SW_HIDE); + } + + if (pItem->m_nItemType==PIT_COMBO) { + //display the combo box. If the combo box has already been + //created then simply move it to the new location, else create it + m_nLastBox = 0; + if (m_cmbBox) { + m_cmbBox.MoveWindow(rect); + } else { + rect.bottom += 300; + m_cmbBox.Create(CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_CHILD | WS_BORDER,rect,this,IDC_PROPCMBBOX); + m_cmbBox.SetFont(&m_SSerif8Font); + } + + //add the choices for this particular property + CString cmbItems = pItem->m_cmbItems; + lBoxSelText = pItem->m_curValue; + + m_cmbBox.ResetContent(); + m_cmbBox.AddString(""); + int i,i2; + i=0; + while ((i2=cmbItems.Find('|',i)) != -1) { + m_cmbBox.AddString(cmbItems.Mid(i,i2-i)); + i=i2+1; + } + + m_cmbBox.ShowWindow(SW_SHOW); + //m_cmbBox.SetFocus(); + + //jump to the property's current value in the combo box + int j = m_cmbBox.FindStringExact(0,lBoxSelText); + if (j != CB_ERR) { + m_cmbBox.SetCurSel(j); + } else { + m_cmbBox.SetCurSel(0); + } + //m_cmbBox.ShowDropDown(); + } + else if (pItem->m_nItemType==PIT_EDIT) { + //display edit box + m_nLastBox = 1; + m_prevSel = m_curSel; + rect.bottom -= 3; + if (m_editBox) { + m_editBox.MoveWindow(rect); + } else { + m_editBox.Create(ES_LEFT | ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD | WS_BORDER,rect,this,IDC_PROPEDITBOX); + m_editBox.SetFont(&m_SSerif8Font); + } + + lBoxSelText = pItem->m_curValue; + + m_editBox.ShowWindow(SW_SHOW); + m_editBox.SetFocus(); + //set the text in the edit box to the property's current value + bool b = updateInspectors; + updateInspectors = false; + m_editBox.SetWindowText(lBoxSelText); + updateInspectors = b; + } else if (pItem->m_nItemType != PIT_VAR) { + DisplayButton(rect); + } +} + +void CPropertyList::DisplayButton(CRect region) { + //displays a button if the property is a file/color/font chooser + m_nLastBox = 2; + m_prevSel = m_curSel; + + if (region.Width() > 25) { + region.left = region.right - 25; + } + region.bottom -= 3; + + if (m_btnCtrl) { + m_btnCtrl.MoveWindow(region); + } else { + m_btnCtrl.Create("...",BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,region,this,IDC_PROPBTNCTRL); + m_btnCtrl.SetFont(&m_SSerif8Font); + } + + m_btnCtrl.ShowWindow(SW_SHOW); + m_btnCtrl.SetFocus(); +} + +void CPropertyList::ResetContent() { + if (m_btnCtrl.GetSafeHwnd()) { + m_btnCtrl.ShowWindow(SW_HIDE); + } + int c = this->GetCount(); + for (int i = 0; i < c; i++) { + CPropertyItem *pi = reinterpret_cast(GetItemDataPtr(i)); + if (pi) { + delete pi; + } + } + CListBox::ResetContent(); +} + +void CPropertyList::OnKillFocus(CWnd* pNewWnd) { + //m_btnCtrl.ShowWindow(SW_HIDE); + CListBox::OnKillFocus(pNewWnd); +} + +void CPropertyList::OnKillfocusCmbBox() { + m_cmbBox.ShowWindow(SW_HIDE); + Invalidate(); +} + +void CPropertyList::OnKillfocusEditBox() { + CString newStr; + m_editBox.ShowWindow(SW_HIDE); + Invalidate(); +} + +void CPropertyList::OnSelchangeCmbBox() { + CString selStr; + if (m_cmbBox) { + m_cmbBox.GetLBText(m_cmbBox.GetCurSel(),selStr); + CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel); + pItem->m_curValue = selStr; + if (updateInspectors) { + g_Inspectors->entityDlg.UpdateFromListBox(); + } + } +} + +void CPropertyList::OnChangeEditBox() { + CString newStr; + m_editBox.GetWindowText(newStr); + + CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel); + pItem->m_curValue = newStr; +} + +void CPropertyList::OnButton() { + CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel); + + //display the appropriate common dialog depending on what type + //of chooser is associated with the property + if (pItem->m_nItemType == PIT_COLOR) { + idVec3 color; + sscanf(pItem->m_curValue, "%f %f %f", &color.x, &color.y, &color.z); + + COLORREF cr = (int)(color.x * 255) + (((int)(color.y * 255))<<8) + (((int)(color.z * 255))<<16); + + CDialogColorPicker dlg(cr); + + dlg.UpdateParent = UpdateRadiantColor; + + if (dlg.DoModal() == IDOK) { + color.x = (dlg.GetColor() & 255)/255.0; + color.y = ((dlg.GetColor() >> 8)&255)/255.0; + color.z = ((dlg.GetColor() >> 16)&255)/255.0; + pItem->m_curValue = color.ToString(4); + } + if (updateInspectors) { + g_Inspectors->entityDlg.UpdateFromListBox(); + } + m_btnCtrl.ShowWindow(SW_HIDE); + Invalidate(); + } else if (pItem->m_nItemType == PIT_FILE) { + CString SelectedFile; + CString Filter("Gif Files (*.gif)|*.gif||"); + + CFileDialog FileDlg(TRUE, NULL, NULL, NULL, Filter); + + CString currPath = pItem->m_curValue; + FileDlg.m_ofn.lpstrTitle = "Select file"; + if (currPath.GetLength() > 0) { + FileDlg.m_ofn.lpstrInitialDir = currPath.Left(currPath.GetLength() - currPath.ReverseFind('\\')); + } + + if(IDOK == FileDlg.DoModal()) { + SelectedFile = FileDlg.GetPathName(); + m_btnCtrl.ShowWindow(SW_HIDE); + pItem->m_curValue = SelectedFile; + Invalidate(); + } + } else if (pItem->m_nItemType == PIT_FONT) { + CFontDialog FontDlg(NULL,CF_EFFECTS | CF_SCREENFONTS,NULL,this); + if(IDOK == FontDlg.DoModal()) { + CString faceName = FontDlg.GetFaceName(); + m_btnCtrl.ShowWindow(SW_HIDE); + pItem->m_curValue = faceName; + Invalidate(); + } + } else if (pItem->m_nItemType == PIT_MODEL) { + CPreviewDlg *dlg = CEntityDlg::ShowModelChooser(); + if (dlg->returnCode == IDOK) { + pItem->m_curValue = dlg->mediaName; + m_btnCtrl.ShowWindow(SW_HIDE); + if (updateInspectors) { + g_Inspectors->entityDlg.UpdateFromListBox(); + } + Invalidate(); + } + } else if (pItem->m_nItemType == PIT_GUI) { + CPreviewDlg *dlg = CEntityDlg::ShowGuiChooser(); + if (dlg->returnCode == IDOK) { + pItem->m_curValue = dlg->mediaName; + m_btnCtrl.ShowWindow(SW_HIDE); + if (updateInspectors) { + g_Inspectors->entityDlg.UpdateFromListBox(); + } + Invalidate(); + } + } else if (pItem->m_nItemType == PIT_MATERIAL) { + CPreviewDlg *dlg = CEntityDlg::ShowMaterialChooser(); + if (dlg->returnCode == IDOK) { + pItem->m_curValue = dlg->mediaName; + m_btnCtrl.ShowWindow(SW_HIDE); + if (updateInspectors) { + g_Inspectors->entityDlg.UpdateFromListBox(); + } + Invalidate(); + } + } +} + +void CPropertyList::OnLButtonUp(UINT nFlags, CPoint point) { + if (m_bTracking) { + //if columns were being resized then this indicates + //that mouse is up so resizing is done. Need to redraw + //columns to reflect their new widths. + + m_bTracking = FALSE; + //if mouse was captured then release it + if (GetCapture()==this) { + ::ReleaseCapture(); + } + + ::ClipCursor(NULL); + + CClientDC dc(this); + InvertLine(&dc,CPoint(point.x,m_nDivTop),CPoint(point.x,m_nDivBtm)); + //set the divider position to the new value + m_nDivider = point.x; + + //redraw + Invalidate(); + } else { + BOOL loc; + int i = ItemFromPoint(point,loc); + m_curSel = i; + CListBox::OnLButtonUp(nFlags, point); + } +} + +void CPropertyList::OnLButtonDown(UINT nFlags, CPoint point) { + if ((point.x>=m_nDivider-5) && (point.x<=m_nDivider+5)) { + //if mouse clicked on divider line, then start resizing + ::SetCursor(m_hCursorSize); + CRect windowRect; + GetWindowRect(windowRect); + windowRect.left += 10; windowRect.right -= 10; + //do not let mouse leave the list box boundary + ::ClipCursor(windowRect); + + if (m_cmbBox) { + m_cmbBox.ShowWindow(SW_HIDE); + } + if (m_editBox) { + m_editBox.ShowWindow(SW_HIDE); + } + + CRect clientRect; + GetClientRect(clientRect); + + m_bTracking = TRUE; + m_nDivTop = clientRect.top; + m_nDivBtm = clientRect.bottom; + m_nOldDivX = point.x; + + CClientDC dc(this); + InvertLine(&dc,CPoint(m_nOldDivX,m_nDivTop),CPoint(m_nOldDivX,m_nDivBtm)); + + //capture the mouse + SetCapture(); + } else { + m_bTracking = FALSE; + CListBox::OnLButtonDown(nFlags, point); + } +} + +void CPropertyList::OnMouseMove(UINT nFlags, CPoint point) { + if (m_bTracking) { + //move divider line to the mouse pos. if columns are + //currently being resized + CClientDC dc(this); + //remove old divider line + InvertLine(&dc,CPoint(m_nOldDivX,m_nDivTop),CPoint(m_nOldDivX,m_nDivBtm)); + //draw new divider line + InvertLine(&dc,CPoint(point.x,m_nDivTop),CPoint(point.x,m_nDivBtm)); + m_nOldDivX = point.x; + } else if ((point.x >= m_nDivider-5) && (point.x <= m_nDivider+5)) { + //set the cursor to a sizing cursor if the cursor is over the row divider + ::SetCursor(m_hCursorSize); + } else { + CListBox::OnMouseMove(nFlags, point); + } +} + +void CPropertyList::InvertLine(CDC* pDC,CPoint ptFrom,CPoint ptTo) { + int nOldMode = pDC->SetROP2(R2_NOT); + pDC->MoveTo(ptFrom); + pDC->LineTo(ptTo); + pDC->SetROP2(nOldMode); +} + +void CPropertyList::PreSubclassWindow() { + m_bDivIsSet = FALSE; + m_nDivider = 0; + m_bTracking = FALSE; + m_curSel = 1; + + m_hCursorSize = AfxGetApp()->LoadStandardCursor(IDC_SIZEWE); + m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + m_SSerif8Font.CreatePointFont(80,_T("MS Sans Serif")); +} + + +void CPropertyList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { + if (m_cmbBox) { + m_cmbBox.ShowWindow(SW_HIDE); + } + if (m_editBox) { + m_editBox.ShowWindow(SW_HIDE); + } + if (m_btnCtrl) { + m_btnCtrl.ShowWindow(SW_HIDE); + } + Invalidate(); + + CListBox::OnVScroll(nSBCode, nPos, pScrollBar); +} + diff --git a/tools/radiant/PropertyList.h b/tools/radiant/PropertyList.h new file mode 100644 index 000000000..4eab79484 --- /dev/null +++ b/tools/radiant/PropertyList.h @@ -0,0 +1,161 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_PROPERTYLIST_H__74205380_1B56_11D4_BC48_00105AA2186F__INCLUDED_) +#define AFX_PROPERTYLIST_H__74205380_1B56_11D4_BC48_00105AA2186F__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PropertyList.h : header file +// + +#define PIT_COMBO 0 //PIT = property item type +#define PIT_EDIT 1 +#define PIT_COLOR 2 +#define PIT_FONT 3 +#define PIT_FILE 4 +#define PIT_SCRIPT 5 +#define PIT_MODEL 6 +#define PIT_SOUND 7 +#define PIT_GUI 8 +#define PIT_MATERIAL 9 +#define PIT_VAR 10 + +#define IDC_PROPCMBBOX 712 +#define IDC_PROPEDITBOX 713 +#define IDC_PROPBTNCTRL 714 + + +///////////////////////////////////////////////////////////////////////////// +//CPropertyList Items +class CPropertyItem +{ +// Attributes +public: + CString m_propName; + CString m_curValue; + int m_nItemType; + CString m_cmbItems; + int data; + +public: + CPropertyItem(CString propName, CString curValue, + int nItemType, CString cmbItems) + { + m_propName = propName; + m_curValue = curValue; + m_nItemType = nItemType; + m_cmbItems = cmbItems; + data = -1; + } + void SetData(int d) { + data = d; + } +}; + +///////////////////////////////////////////////////////////////////////////// +// CPropertyList window + +class CPropertyList : public CListBox +{ +// Construction +public: + CPropertyList(); + +// Attributes +public: + +// Operations +public: + int AddItem(CString txt); + int AddPropItem(CPropertyItem* pItem); + void ResetContent(); + CEdit *GetEditBox() { + return &m_editBox; + } + void SetUpdateInspectors(bool b) { + updateInspectors = b; + } + void SetDivider( int div ) { + m_nDivider = div; + } + afx_msg void OnKillfocusEditBox(); + afx_msg void OnChangeEditBox(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPropertyList) + public: + virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct); + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + afx_msg void OnSelchange(); + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual void PreSubclassWindow(); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CPropertyList(); + + // Generated message map functions +protected: + //{{AFX_MSG(CPropertyList) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnKillFocus(CWnd* pNewWnd); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + + //}}AFX_MSG + afx_msg void OnKillfocusCmbBox(); + afx_msg void OnSelchangeCmbBox(); + afx_msg void OnButton(); + + DECLARE_MESSAGE_MAP() + + void InvertLine(CDC* pDC,CPoint ptFrom,CPoint ptTo); + void DisplayButton(CRect region); + + CComboBox m_cmbBox; + CEdit m_editBox; + CButton m_btnCtrl; + CFont m_SSerif8Font; + + int m_curSel,m_prevSel; + int m_nDivider; + int m_nDivTop; + int m_nDivBtm; + int m_nOldDivX; + int m_nLastBox; + BOOL m_bTracking; + BOOL m_bDivIsSet; + HCURSOR m_hCursorArrow; + HCURSOR m_hCursorSize; + CPropertyItem *measureItem; + bool updateInspectors; +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROPERTYLIST_H__74205380_1B56_11D4_BC48_00105AA2186F__INCLUDED_) diff --git a/tools/radiant/QE3.CPP b/tools/radiant/QE3.CPP new file mode 100644 index 000000000..22f8f82b8 --- /dev/null +++ b/tools/radiant/QE3.CPP @@ -0,0 +1,431 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include +#include +#include "WaitDlg.h" + +QEGlobals_t g_qeglobals; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void WINAPI QE_CheckOpenGLForErrors(void) { + CString strMsg; + int i = qglGetError(); + if (i != GL_NO_ERROR) { + if (i == GL_OUT_OF_MEMORY) { + // + // strMsg.Format("OpenGL out of memory error %s\nDo you wish to save before + // exiting?", gluErrorString((GLenum)i)); + // + if (g_pParentWnd->MessageBox(strMsg, EDITOR_WINDOWTEXT " Error", MB_YESNO) == IDYES) { + Map_SaveFile(NULL, false); + } + + exit(1); + } + else { + // strMsg.Format("Warning: OpenGL Error %s\n ", gluErrorString((GLenum)i)); + common->Printf(strMsg.GetBuffer(0)); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool DoesFileExist(const char *pBuff, long &lSize) { + CFile file; + if (file.Open(pBuff, CFile::modeRead | CFile::shareDenyNone)) { + lSize += file.GetLength(); + file.Close(); + return true; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool ExtractPath_and_Filename(const char *pPath, CString &strPath, CString &strFilename) { + CString strPathName = pPath; + int nSlash = strPathName.ReverseFind('\\'); + if (nSlash >= 0) { + strPath = strPathName.Left(nSlash + 1); + strFilename = strPathName.Right(strPathName.GetLength() - nSlash - 1); + } + else { + strFilename = pPath; + } + + return true; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Map_Snapshot() { + CString strMsg; + + // + // we need to do the following 1. make sure the snapshot directory exists (create + // it if it doesn't) 2. find out what the lastest save is based on number 3. inc + // that and save the map + // + CString strOrgPath, strOrgFile; + ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile); + AddSlash(strOrgPath); + strOrgPath += "snapshots"; + + bool bGo = true; + struct _stat Stat; + if (_stat(strOrgPath, &Stat) == -1) { + bGo = (_mkdir(strOrgPath) != -1); + } + + AddSlash(strOrgPath); + if (bGo) { + int nCount = 0; + long lSize = 0; + CString strNewPath = strOrgPath; + strNewPath += strOrgFile; + + CString strFile; + while (bGo) { + strFile.Format("%s.%i", strNewPath, nCount); + bGo = DoesFileExist(strFile, lSize); + nCount++; + } + + // strFile has the next available slot + Map_SaveFile(strFile.GetBuffer(0), false); + Sys_SetTitle(currentmap); + if (lSize > 12 * 1024 * 1024) { // total size of saves > 4 mb + common->Printf + ( + "The snapshot files in the [%s] directory total more than 4 megabytes. You might consider cleaning the directory up.", + strOrgPath + ); + } + } + else { + strMsg.Format("Snapshot save failed.. unabled to create directory\n%s", strOrgPath); + g_pParentWnd->MessageBox(strMsg); + } +} + +/* + ======================================================================================================================= + QE_CheckAutoSave If five minutes have passed since making a change and the map hasn't been saved, save it out. + ======================================================================================================================= + */ +void QE_CheckAutoSave(void) { + static bool inAutoSave = false; + static bool autoToggle = false; + if (inAutoSave) { + Sys_Status("Did not autosave due recursive entry into autosave routine\n"); + return; + } + + if ( !mapModified ) { + return; + } + + inAutoSave = true; + + if ( g_PrefsDlg.m_bAutoSave ) { + CString strMsg = g_PrefsDlg.m_bSnapShots ? "Autosaving snapshot..." : "Autosaving..."; + Sys_Status(strMsg.GetBuffer(0), 0); + + if (g_PrefsDlg.m_bSnapShots && stricmp(currentmap, "unnamed.map") != 0) { + Map_Snapshot(); + } else { + Map_SaveFile(ValueForKey(g_qeglobals.d_project_entity, (autoToggle == 0) ? "autosave1" : "autosave2" ), false, true); + autoToggle ^= 1; + } + Sys_Status("Autosaving...Saved.", 0); + mapModified = 0; // DHM - _D3XP + } else { + common->Printf("Autosave skipped...\n"); + Sys_Status("Autosave skipped...", 0); + } + + inAutoSave = false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +const char *g_pPathFixups[] = { + "basepath", + + // "remotebasepath", + "entitypath", + + // "texturepath", + "autosave", + + // "mapspath" +}; + +const int g_nPathFixupCount = sizeof(g_pPathFixups) / sizeof (const char *); + +/* + ======================================================================================================================= + QE_LoadProject + ======================================================================================================================= + */ +bool QE_LoadProject(char *projectfile) { + char *data; + ID_TIME_T time; + + common->Printf("QE_LoadProject (%s)\n", projectfile); + + if ( fileSystem->ReadFile( projectfile, reinterpret_cast < void ** > (&data), &time) <= 0 ) { + return false; + } + + g_strProject = projectfile; + g_PrefsDlg.m_strLastProject = projectfile; + g_PrefsDlg.SavePrefs(); + + CString strData = data; + + fileSystem->FreeFile( data ); + + StartTokenParsing(strData.GetBuffer(0)); + g_qeglobals.d_project_entity = Entity_Parse(true); + if (!g_qeglobals.d_project_entity) { + Error("Couldn't parse %s", projectfile); + } + + // set here some default project settings you need + if (strlen(ValueForKey(g_qeglobals.d_project_entity, "brush_primit")) == 0) { + SetKeyValue(g_qeglobals.d_project_entity, "brush_primit", "0"); + } + + g_qeglobals.m_bBrushPrimitMode = IntForKey(g_qeglobals.d_project_entity, "brush_primit"); + + Eclass_InitForSourceDirectory(ValueForKey(g_qeglobals.d_project_entity, "entitypath")); + g_Inspectors->FillClassList(); // list in entity window + + Map_New(); + + // FillTextureMenu(); + FillBSPMenu(); + + return true; +} + +/* + ======================================================================================================================= + QE_SaveProject £ + ======================================================================================================================= + */ +bool QE_SaveProject(const char *pProjectFile) { + + idFile *file = fileSystem->OpenFileWrite(pProjectFile); + if ( !file ) { + return false; + } + + file->Write("{\n", 2); + + int count = g_qeglobals.d_project_entity->epairs.GetNumKeyVals(); + for (int i = 0; i < count; i++) { + file->WriteFloatString( "\"%s\" \"%s\"\n", g_qeglobals.d_project_entity->epairs.GetKeyVal(i)->GetKey().c_str(), g_qeglobals.d_project_entity->epairs.GetKeyVal(i)->GetValue().c_str()); + } + + file->Write("}\n", 2); + + fileSystem->CloseFile( file ); + + return true; +} + +/* QE_KeyDown */ +#define SPEED_MOVE 32 +#define SPEED_TURN 22.5 + +/* + ======================================================================================================================= + ConnectEntities Sets target / name on the two entities selected from the first selected to the secon + ======================================================================================================================= + */ +void ConnectEntities(void) { + entity_t *e1; + const char *target; + idStr strTarget; + int i, t; + + if (g_qeglobals.d_select_count < 2) { + Sys_Status("Must have at least two brushes selected.", 0); + Sys_Beep(); + return; + } + + e1 = g_qeglobals.d_select_order[0]->owner; + + for (i = 0; i < g_qeglobals.d_select_count; i++) { + if (g_qeglobals.d_select_order[i]->owner == world_entity) { + Sys_Status("Can't connect to the world.", 0); + Sys_Beep(); + return; + } + } + + for (i = 1; i < g_qeglobals.d_select_count; i++) { + if (e1 == g_qeglobals.d_select_order[i]->owner) { + Sys_Status("Brushes are from same entity.", 0); + Sys_Beep(); + return; + } + } + + target = ValueForKey(e1, "target"); + if ( target && *target) { + for (t = 1; t < 2048; t++) { + target = ValueForKey(e1, va("target%i", t)); + if (target && *target) { + continue; + } else { + break; + } + } + } else { + t = 0; + } + + for (i = 1; i < g_qeglobals.d_select_count; i++) { + target = ValueForKey(g_qeglobals.d_select_order[i]->owner, "name"); + if (target && *target) { + strTarget = target; + } else { + UniqueTargetName(strTarget); + } + if (t == 0) { + SetKeyValue(e1, "target", strTarget); + } else { + SetKeyValue(e1, va("target%i", t), strTarget); + } + t++; + } + + Sys_UpdateWindows(W_XY | W_CAMERA); + + Select_Deselect(); + Select_Brush(g_qeglobals.d_select_order[1]); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool QE_SingleBrush(bool bQuiet, bool entityOK) { + if ((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes)) { + if (!bQuiet) { + Sys_Status("Error: you must have a single brush selected\n"); + } + + return false; + } + + if (!entityOK && selected_brushes.next->owner->eclass->fixedsize) { + if (!bQuiet) { + Sys_Status("Error: you cannot manipulate fixed size entities\n"); + } + + return false; + } + + return true; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void QE_Init(void) { + /* initialize variables */ + g_qeglobals.d_gridsize = 8; + g_qeglobals.d_showgrid = true; + + /* + * other stuff £ + * FIXME: idMaterial Texture_Init (true); Cam_Init (); XY_Init (); + */ + Z_Init(); +} + + +int g_numbrushes, g_numentities; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void QE_CountBrushesAndUpdateStatusBar(void) { + static int s_lastbrushcount, s_lastentitycount; + static bool s_didonce; + + // entity_t *e; + brush_t *b, *next; + + g_numbrushes = 0; + g_numentities = 0; + + if (active_brushes.next != NULL) { + for (b = active_brushes.next; b != NULL && b != &active_brushes; b = next) { + next = b->next; + if (b->brush_faces) { + if (!b->owner->eclass->fixedsize) { + g_numbrushes++; + } + else { + g_numentities++; + } + } + } + } + + /* + * if ( entities.next != NULL ) { for ( e = entities.next ; e != &entities && + * g_numentities != MAX_MAP_ENTITIES ; e = e->next) { g_numentities++; } } + */ + if (((g_numbrushes != s_lastbrushcount) || (g_numentities != s_lastentitycount)) || (!s_didonce)) { + Sys_UpdateStatusBar(); + + s_lastbrushcount = g_numbrushes; + s_lastentitycount = g_numentities; + s_didonce = true; + } +} + diff --git a/tools/radiant/QE3.H b/tools/radiant/QE3.H new file mode 100644 index 000000000..23686bfa3 --- /dev/null +++ b/tools/radiant/QE3.H @@ -0,0 +1,486 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __QE3_H__ +#define __QE3_H__ + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +// this define to use HTREEITEM and MFC stuff in the headers +#define QERTYPES_USE_MFC +#include "qertypes.h" +#include "cmdlib.h" +#include "parse.h" + +#include +#include "afxres.h" +#include "../../sys/win32/rc/Radiant_resource.h" // main symbols +#include "../../sys/win32/win_local.h" + +#include "qedefs.h" + +// stuff from old qfiles.h +#define MAX_MAP_ENTITIES 2048 +const int MAX_MOVE_POINTS = 4096; +const int MAX_MOVE_PLANES = 2048; + +// assume that all maps fit within this +const float HUGE_DISTANCE = 100000; + +#include "textures.h" +#include "EditorBrush.h" +#include "EditorEntity.h" +#include "EditorMap.h" +#include "select.h" +#include "splines.h" + +#include "z.h" +#include "mru.h" +#include "waitdlg.h" +#include "MainFrm.h" +#include "PrefsDlg.h" +#include "FindTextureDlg.h" +#include "dialogtextures.h" +#include "InspectorDialog.h" +#include "undo.h" +#include "PMESH.H" + +// the dec offsetof macro doesn't work very well... +#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier) + + +void Error (char *error, ...); +void Warning (char *error, ...); + +typedef struct +{ + int p1, p2; + face_t *f1, *f2; +} pedge_t; + +typedef struct +{ + int iSize; + int iTexMenu; // nearest, linear, etc + float fGamma; // gamma for textures + char szProject[256]; // last project loaded + idVec3 colors[COLOR_LAST]; + bool show_names; + bool show_coordinates; + int exclude; + float m_nTextureTweak; + bool editorExpanded; + RECT oldEditRect; + bool showSoundAlways; + bool showSoundWhenSelected; +} SavedInfo_t; + +// +// system functions +// +// TTimo NOTE: WINAPI funcs can be accessed by plugins +void Sys_UpdateStatusBar( void ); +void WINAPI Sys_UpdateWindows (int bits); +void Sys_Beep (void); +double Sys_DoubleTime (void); +void Sys_GetCursorPos (int *x, int *y); +void Sys_SetCursorPos (int x, int y); +void Sys_SetTitle (const char *text); +void Sys_BeginWait (void); +bool Sys_Waiting(); +void Sys_EndWait (void); +void Sys_Status(const char *psz, int part = -1); + +/* +** most of the QE globals are stored in this structure +*/ +typedef struct +{ + bool d_showgrid; + float d_gridsize; + + int rotateAxis; // 0, 1 or 2 + int flatRotation; // 0, 1 or 2, 0 == off, 1 == rotate about the rotation origin, 1 == rotate about the selection mid point + + int d_num_entities; + + entity_t *d_project_entity; + + idVec3 d_new_brush_bottom, d_new_brush_top; + + HINSTANCE d_hInstance; + + idVec3 d_points[MAX_POINTS]; + int d_numpoints; + pedge_t d_edges[MAX_EDGES]; + int d_numedges; + + int d_num_move_points; + idVec3 *d_move_points[MAX_MOVE_POINTS]; + + int d_num_move_planes; + idPlane *d_move_planes[MAX_MOVE_PLANES]; + + qtexture_t *d_qtextures; + + texturewin_t d_texturewin; + + int d_pointfile_display_list; + + LPMRUMENU d_lpMruMenu; + + SavedInfo_t d_savedinfo; + + int d_workcount; + + // connect entities uses the last two brushes selected + int d_select_count; + brush_t *d_select_order[MAX_MAP_ENTITIES]; + idVec3 d_select_translate; // for dragging w/o making new display lists + select_t d_select_mode; + idPointListInterface *selectObject; // + + int d_font_list; + + int d_parsed_brushes; + + bool show_blocks; + + // Timo + // tells if we are internally using brush primitive (texture coordinates and map format) + // this is a shortcut for IntForKey( g_qeglobals.d_project_entity, "brush_primit" ) + // NOTE: must keep the two ones in sync + BOOL m_bBrushPrimitMode; + + // used while importing brush data from file or memory buffer + // tells if conversion between map format and internal preferences ( m_bBrushPrimitMode ) is needed + bool bNeedConvert; + bool bOldBrushes; + bool bPrimitBrushes; + float mapVersion; + + idVec3 d_vAreaTL; + idVec3 d_vAreaBR; + + // tells if we are using .INI files for prefs instead of registry + bool use_ini; + // even in .INI mode we use the registry for all void* prefs + char use_ini_registry[64]; + + //Timo + // tells we have surface properties plugin + bool bSurfacePropertiesPlugin; + // tells we are using a BSP frontend plugin + bool bBSPFrontendPlugin; + + // the editor has its own soundWorld and renderWorld, completely distinct from the game + idRenderWorld *rw; + idSoundWorld *sw; +} QEGlobals_t; + + +void Pointfile_Delete (void); +void WINAPI Pointfile_Check (void); +void Pointfile_Next (void); +void Pointfile_Prev (void); +void Pointfile_Clear (void); +void Pointfile_Draw( void ); +void Pointfile_Load( void ); + +// +// drag.c +// +void Drag_Begin (int x, int y, int buttons, + const idVec3 &xaxis, const idVec3 &yaxis, + const idVec3 &origin, const idVec3 &dir); +void Drag_MouseMoved (int x, int y, int buttons); +void Drag_MouseUp (int nButtons = 0); +extern bool g_moveOnly; +// +// csg.c +// +void CSG_MakeHollow (void); +void CSG_Subtract (void); +void CSG_Merge (void); + +// +// vertsel.c +// + +void SetupVertexSelection (void); +void SelectEdgeByRay (idVec3 org, idVec3 dir); +void SelectVertexByRay (idVec3 org, idVec3 dir); + +void ConnectEntities (void); + +extern int update_bits; + +extern int screen_width; +extern int screen_height; + +extern HANDLE bsp_process; +extern HANDLE g_hBSPOutput; +extern HANDLE g_hBSPInput; + + +char *TranslateString (char *buf); + +void ProjectDialog (void); + +void FillTextureMenu (CStringArray* pArray = NULL); +void FillBSPMenu (void); + +BOOL CALLBACK Win_Dialog ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter +); + + +// +// win_cam.c +// +void WCam_Create (HINSTANCE hInstance); + + +// +// win_xy.c +// +void WXY_Create (HINSTANCE hInstance); + +// +// win_z.c +// +void WZ_Create (HINSTANCE hInstance); + +// +// win_ent.c +// + + +// +// win_main.c +// +void Main_Create (HINSTANCE hInstance); +extern bool SaveWindowState(HWND hWnd, const char *pszName); +extern bool LoadWindowState(HWND hWnd, const char *pszName); + +extern bool SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize); +extern bool LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize); + + + +// win_dlg.c + +void DoGamma(void); +void DoFind(void); +void DoRotate(void); +void DoSides(bool bCone = false, bool bSphere = false, bool bTorus = false); +void DoAbout(void); +void DoSurface(); + +/* +** QE function declarations +*/ +void QE_CheckAutoSave( void ); +void QE_CountBrushesAndUpdateStatusBar( void ); +void WINAPI QE_CheckOpenGLForErrors(void); +void QE_ExpandBspString (char *bspaction, char *out, char *mapname, bool useTemps); +void QE_Init (void); +bool QE_KeyDown (int key, int nFlags = 0); +bool QE_LoadProject (char *projectfile); +bool QE_SingleBrush (bool bQuiet = false, bool entityOK = false); + + +// sys stuff +void Sys_MarkMapModified (void); + +/* +** QE Win32 function declarations +*/ +int WINAPI QEW_SetupPixelFormat(HDC hDC, bool zbuffer ); + +/* +** extern declarations +*/ +extern QEGlobals_t g_qeglobals; +extern int mapModified; // for quit confirmation (0 = clean, 1 = unsaved, + +//++timo clean (moved into qertypes.h) +//enum VIEWTYPE {YZ, XZ, XY}; + + +extern bool g_bAxialMode; +extern int g_axialAnchor; +extern int g_axialDest; + +extern void Face_FlipTexture_BrushPrimit(face_t *face, bool y); +extern void Brush_FlipTexture_BrushPrimit(brush_t *b, bool y); + +// Timo +// new brush primitive stuff +//void ComputeAxisBase( idVec3 &normal,idVec3 &texS,idVec3 &texT ); +void FaceToBrushPrimitFace(face_t *f); +void EmitBrushPrimitTextureCoordinates(face_t *, idWinding *, patchMesh_t *patch = NULL); +// EmitTextureCoordinates, is old code used for brush to brush primitive conversion +void EmitTextureCoordinates ( idVec5 &xyzst, const idMaterial *q, face_t *f, bool force = false); +void BrushPrimit_Parse(brush_t *, bool newFormat, const idVec3 origin); +// compute a fake shift scale rot representation from the texture matrix +void TexMatToFakeTexCoords( float texMat[2][3], float shift[2], float *rot, float scale[2] ); +void FakeTexCoordsToTexMat( float shift[2], float rot, float scale[2], float texMat[2][3] ); +void ConvertTexMatWithQTexture( brushprimit_texdef_t *texMat1, const idMaterial *qtex1, brushprimit_texdef_t *texMat2, const idMaterial *qtex2, float sScale = 1.0, float tScale = 1.0 ); +// texture locking +void Face_MoveTexture_BrushPrimit(face_t *f, idVec3 delta); +void Select_ShiftTexture_BrushPrimit( face_t *f, float x, float y, bool autoAdjust ); +void RotateFaceTexture_BrushPrimit(face_t *f, int nAxis, float fDeg, idVec3 vOrigin ); +// used in CCamWnd::ShiftTexture_BrushPrimit +void ComputeBest2DVector( idVec3 v, idVec3 X, idVec3 Y, int &x, int &y ); + +void ApplyMatrix_BrushPrimit(face_t *f, idMat3 matrix, idVec3 origin); +// low level functions .. put in mathlib? +#define BPMatCopy(a,b) {b[0][0] = a[0][0]; b[0][1] = a[0][1]; b[0][2] = a[0][2]; b[1][0] = a[1][0]; b[1][1] = a[1][1]; b[1][2] = a[1][2];} +// apply a scale transformation to the BP matrix +#define BPMatScale(m,sS,sT) {m[0][0]*=sS; m[1][0]*=sS; m[0][1]*=sT; m[1][1]*=sT;} +// apply a translation transformation to a BP matrix +#define BPMatTranslate(m,s,t) {m[0][2] += m[0][0]*s + m[0][1]*t; m[1][2] += m[1][0]*s+m[1][1]*t;} +// 2D homogeneous matrix product C = A*B +void BPMatMul(float A[2][3], float B[2][3], float C[2][3]); +// apply a rotation (degrees) +void BPMatRotate(float A[2][3], float theta); +#ifdef _DEBUG +void BPMatDump(float A[2][3]); +#endif + + +// +// eclass.cpp +// +extern bool parsing_single; +extern bool eclass_found; +extern eclass_t *eclass_e; +void Eclass_ScanFile( char *filename ); +void FillClassList (void); + +extern bool g_bShowLightVolumes; +extern bool g_bShowLightTextures; +extern const idMaterial *Texture_LoadLight(const char *name); + +#define FONT_HEIGHT 10 + +void UniqueTargetName(idStr& rStr); + +#define MAP_VERSION 2.0 + +extern CMainFrame* g_pParentWnd; +extern CString g_strAppPath; +extern CPrefsDlg& g_PrefsDlg; +extern CFindTextureDlg& g_dlgFind; +extern idCVar radiant_entityMode; + +// layout styles +#define QR_SPLIT 0 +#define QR_QE4 1 +#define QR_4WAY 2 +#define QR_SPLITZ 3 + + +// externs +extern void AddSlash(CString&); +extern void DLLBuildDone(); +extern void CleanUpEntities(); +extern void QE_CountBrushesAndUpdateStatusBar(); +extern void QE_CheckAutoSave(); +extern qtexture_t *notexture; +extern qtexture_t *current_texture; +extern bool SaveWindowState(HWND hWnd, const char *pszName); +extern void Map_Snapshot(); +extern void WXY_Print(); +extern void AddProp( void ); +extern int inspector_mode; +extern bool g_bRotateMode; +extern bool g_bClipMode; +extern bool g_bScaleMode; +extern int g_nScaleHow; +extern bool g_bPathMode; +extern void RunScript(char* pBuffer); +extern HINSTANCE g_hOpenGL32; + +extern void FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected, bool bForce); +extern void DoProjectSettings(); +extern bool region_active; +extern void Texture_ShowDirectory (char* pPath, bool Linked = false); +extern void Map_ImportFile (char *filename); +extern void Map_SaveSelected(char* pFilename); +extern bool g_bNewFace; +extern bool g_bSwitch; +extern brush_t g_brFrontSplits; +extern brush_t g_brBackSplits; +extern CClipPoint g_Clip1; +extern CClipPoint g_Clip2; +extern brush_t* g_pSplitList; +extern CClipPoint g_PathPoints[256]; +extern void AcquirePath(int nCount, PFNPathCallback* pFunc); +extern bool g_bScreenUpdates; +extern SCommandInfo g_Commands[]; +extern int g_nCommandCount; +extern SKeyInfo g_Keys[]; +extern int g_nKeyCount; +extern int inspector_mode; +extern const char *bsp_commands[256]; +extern void HandlePopup(CWnd* pWindow, unsigned int uId); +extern z_t z; +extern CString g_strProject; +extern void TextureAxisFromPlane( const idPlane &pln, idVec3 &xv, idVec3 &yv); +extern bool QE_SaveProject (const char* pProjectFile); +extern void Clamp(float& f, int nClamp); +extern bool WriteFileString( FILE *fp, char *string, ... ); +extern void MemFile_fprintf(CMemFile* pMemFile, const char* pText, ...); +extern void SaveWindowPlacement(HWND hwnd, const char* pName); +extern bool LoadWindowPlacement(HWND hwnd, const char* pName); +extern bool ConfirmModified (void); +extern void DoPatchInspector(); +void UpdatePatchInspector(); +extern int g_nSmartX; +extern int g_nSmartY; +extern brush_t* CreateEntityBrush(int x, int y, CXYWnd* pWnd); +int PointInMoveList( idVec3 *pf ); + +extern bool ByeByeSurfaceDialog(); +extern void UpdateSurfaceDialog(); +extern void UpdateLightInspector(); + +BOOL UpdateEntitySel(eclass_t *pec); +void SetInspectorMode(int iType); +BOOL GetSelectAllCriteria(CString &strKey, CString &strVal); + +int GetCvarInt(const char *name, const int def); +const char *GetCvarString(const char *name, const char *def); +void SetCvarInt(const char *name, const int value); +void SetCvarString(const char *name, const char *value); +void SetCvarBinary(const char *name, void *pv, int size); +bool GetCvarBinary(const char *name, void *pv, int size); + +void UpdateRadiantColor( float r, float g, float b, float a ); + +#endif /* !__QE3_H__ */ diff --git a/tools/radiant/QEDEFS.H b/tools/radiant/QEDEFS.H new file mode 100644 index 000000000..f811a5358 --- /dev/null +++ b/tools/radiant/QEDEFS.H @@ -0,0 +1,162 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __QEDEFS_H__ +#define __QEDEFS_H__ + +#define QE_VERSION 0x0501 + +#define QE3_STYLE (WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_CHILD) +#define QE3_STYLE2 (WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU) +#define QE3_CHILDSTYLE (WS_OVERLAPPED | WS_MINIMIZEBOX | WS_THICKFRAME | WS_CAPTION | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZEBOX) + +#define QE3_SPLITTER_STYLE (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) + + + +#define QE_AUTOSAVE_INTERVAL 5 // number of minutes between autosaves + +#define _3DFXCAMERA_WINDOW_CLASS "Q3DFXCamera" +#define CAMERA_WINDOW_CLASS "QCamera" +#define XY_WINDOW_CLASS "QXY" +#define Z_WINDOW_CLASS "QZ" +#define ENT_WINDOW_CLASS "QENT" +#define TEXTURE_WINDOW_CLASS "QTEX" + +#define ZWIN_WIDTH 40 +#define CWIN_SIZE (0.4) + +#define MAX_EDGES 512 +#define MAX_POINTS 1024 + +#define CMD_TEXTUREWAD 60000 +#define CMD_BSPCOMMAND 61000 + +#define PITCH 0 +#define YAW 1 +#define ROLL 2 + +#define QE_TIMER0 1 +#define QE_TIMER1 2 + +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +// #define ON_EPSILON 0.01 + +#define KEY_FORWARD 1 +#define KEY_BACK 2 +#define KEY_TURNLEFT 4 +#define KEY_TURNRIGHT 8 +#define KEY_LEFT 16 +#define KEY_RIGHT 32 +#define KEY_LOOKUP 64 +#define KEY_LOOKDOWN 128 +#define KEY_UP 256 +#define KEY_DOWN 512 + +// xy.c +#define EXCLUDE_LIGHTS 0x00000001 +#define EXCLUDE_ENT 0x00000002 +#define EXCLUDE_PATHS 0x00000004 +#define EXCLUDE_DYNAMICS 0x00000008 +#define EXCLUDE_WORLD 0x00000010 +#define EXCLUDE_CLIP 0x00000020 +//#define EXCLUDE_DETAIL 0x00000040 +#define EXCLUDE_CURVES 0x00000080 +#define INCLUDE_EASY 0x00000100 +#define INCLUDE_NORMAL 0x00000200 +#define INCLUDE_HARD 0x00000400 +#define INCLUDE_DEATHMATCH 0x00000800 +#define EXCLUDE_HINT 0x00001000 +#define EXCLUDE_CAULK 0x00002000 +#define EXCLUDE_ANGLES 0x00004000 +#define EXCLUDE_VISPORTALS 0x00008000 +#define EXCLUDE_NODRAW 0x00010000 +#define EXCLUDE_COMBATNODES 0x00020000 +#define EXCLUDE_TRIGGERS 0x00040000 +// _D3XP +#define EXCLUDE_MODELS 0x00080000 + + +// +// menu indexes for modifying menus +// +#define MENU_VIEW 2 +#define MENU_BSP 4 +#define MENU_TEXTURE 6 +#define MENU_PLUGIN 11 + + +// odd things not in windows header... +#define VK_COMMA 188 +#define VK_PERIOD 190 + +/* +** window bits +*/ +//++timo moved to qertypes.h +// clean +/* +#define W_CAMERA 0x0001 +#define W_XY 0x0002 +#define W_XY_OVERLAY 0x0004 +#define W_Z 0x0008 +#define W_TEXTURE 0x0010 +#define W_Z_OVERLAY 0x0020 +#define W_CONSOLE 0x0040 +#define W_ENTITY 0x0080 +#define W_CAMERA_IFON 0x0100 +#define W_XZ 0x0200 //--| only used for patch vertex manip stuff +#define W_YZ 0x0400 //--| +#define W_ALL 0xFFFFFFFF +*/ + +enum { + COLOR_TEXTUREBACK, + COLOR_GRIDBACK, + COLOR_GRIDMINOR, + COLOR_GRIDMAJOR, + COLOR_CAMERABACK, + COLOR_ENTITY, + COLOR_GRIDBLOCK, + COLOR_GRIDTEXT, + COLOR_BRUSHES, + COLOR_SELBRUSHES, + COLOR_CLIPPER, + COLOR_VIEWNAME, + COLOR_PRECISION_CROSSHAIR, + COLOR_LAST +}; + +// classes +#define ENTITY_WIREFRAME 0x00001 +#define ENTITY_SKIN_MODEL 0x00010 +#define ENTITY_SELECTED_ONLY 0x00100 +#define ENTITY_BOXED 0x01000 + +// menu settings +#define ENTITY_WIRE 0x00001 +#define ENTITY_SKINNED 0x00002 + + +#endif diff --git a/tools/radiant/QERTYPES.H b/tools/radiant/QERTYPES.H new file mode 100644 index 000000000..db35f0b2e --- /dev/null +++ b/tools/radiant/QERTYPES.H @@ -0,0 +1,420 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef _QERTYPE_H +#define _QERTYPE_H + +#define MAXPOINTS 16 + +class texdef_t +{ +public: + texdef_t() + { + name = ""; + shift[0] = shift[1] = 0.0; + rotate = 0; + scale[0] = scale[1] = 0; + value = 0; + } + ~texdef_t() + { + if ( name && name[0] ) { + delete []name; + } + name = NULL; + } + + void SetName( const char *p ) + { + if ( name && name[0] ) { + delete []name; + } + if ( p && p[0] ) { + name = strcpy( new char[strlen(p)+1], p ); + } + else { + name = ""; + } + } + + texdef_t& operator =(const texdef_t& rhs) + { + if ( &rhs != this ) { + SetName(rhs.name); + shift[0] = rhs.shift[0]; + shift[1] = rhs.shift[1]; + rotate = rhs.rotate; + scale[0] = rhs.scale[0]; + scale[1] = rhs.scale[1]; + value = rhs.value; + } + return *this; + } + //char name[128]; + char * name; + float shift[2]; + float rotate; + float scale[2]; + int value; +}; + +// Timo +// new brush primitive texdef +//typedef struct brushprimit_texdef_s +//{ +// float coords[2][3]; +//} brushprimit_texdef_t; + +class brushprimit_texdef_t { +public: + float coords[2][3]; + brushprimit_texdef_t() { + memset(&coords, 0, sizeof(coords)); + coords[0][0] = 1.0; + coords[1][1] = 1.0; + } +}; + +class texturewin_t +{ +public: + texturewin_t() { + memset(&brushprimit_texdef.coords, 0, sizeof(brushprimit_texdef.coords)); + brushprimit_texdef.coords[0][0] = 1.0; + brushprimit_texdef.coords[1][1] = 1.0; + } + + ~texturewin_t() { + } + int width, height; + int originy; + // add brushprimit_texdef_t for brush primitive coordinates storage + brushprimit_texdef_t brushprimit_texdef; + int m_nTotalHeight; + // surface plugin, must be casted to a IPluginTexdef* + void* pTexdef; + texdef_t texdef; +}; + +#define QER_TRANS 0x00000001 +#define QER_NOCARVE 0x00000002 + +typedef struct qtexture_s +{ + struct qtexture_s *next; + char name[64]; // includes partial directory and extension + int width, height; + int contents; + int flags; + int value; + int texture_number; // gl bind number + + // name of the .shader file + char shadername[1024]; // old shader stuff + bool bFromShader; // created from a shader + float fTrans; // amount of transparency + int nShaderFlags; // qer_ shader flags + idVec3 color; // for flat shade mode + bool inuse; // true = is present on the level + + // cast this one to an IPluginQTexture if you are using it + // NOTE: casting can be done with a GETPLUGINQTEXTURE defined in isurfaceplugin.h + // TODO: if the __ISURFACEPLUGIN_H_ header is used, use a union { void *pData; IPluginQTexture *pPluginQTexture } kind of thing ? + void *pData; + + //++timo FIXME: this is the actual filename of the texture + // this will be removed after shader code cleanup + char filename[64]; + +} qtexture_t; + +//++timo texdef and brushprimit_texdef are static +// TODO : do dynamic ? +typedef struct face_s +{ + struct face_s *next; + struct face_s *original; //used for vertex movement + idVec3 planepts[3]; + idVec3 orgplanepts[3]; // used for arbitrary rotation + texdef_t texdef; + + idPlane plane; + idPlane originalPlane; + bool dirty; + + idWinding *face_winding; + + idVec3 d_color; + const idMaterial *d_texture; + + // Timo new brush primit texdef + brushprimit_texdef_t brushprimit_texdef; + + // cast this one to an IPluginTexdef if you are using it + // NOTE: casting can be done with a GETPLUGINTEXDEF defined in isurfaceplugin.h + // TODO: if the __ISURFACEPLUGIN_H_ header is used, use a union { void *pData; IPluginTexdef *pPluginTexdef } kind of thing ? + void *pData; +} face_t; + +typedef struct { + idVec3 xyz; + float sideST[2]; + float capST[2]; +} curveVertex_t; + +typedef struct { + curveVertex_t v[2]; +} sideVertex_t; + + +#define MIN_PATCH_WIDTH 3 +#define MIN_PATCH_HEIGHT 3 + +#define MAX_PATCH_WIDTH 64 +#define MAX_PATCH_HEIGHT 64 + +// patch type info +// type in lower 16 bits, flags in upper +// endcaps directly follow this patch in the list + +// types +#define PATCH_GENERIC 0x00000000 // generic flat patch +#define PATCH_CYLINDER 0x00000001 // cylinder +#define PATCH_BEVEL 0x00000002 // bevel +#define PATCH_ENDCAP 0x00000004 // endcap +#define PATCH_HEMISPHERE 0x00000008 // hemisphere +#define PATCH_CONE 0x00000010 // cone +#define PATCH_TRIANGLE 0x00000020 // simple tri, assumes 3x3 patch + +// behaviour styles +#define PATCH_CAP 0x00001000 // flat patch applied as a cap +#define PATCH_SEAM 0x00002000 // flat patch applied as a seam +#define PATCH_THICK 0x00004000 // patch applied as a thick portion + +// styles +#define PATCH_BEZIER 0x00000000 // default bezier +#define PATCH_BSPLINE 0x10000000 // bspline + +#define PATCH_TYPEMASK 0x00000fff // +#define PATCH_BTYPEMASK 0x0000f000 // +#define PATCH_STYLEMASK 0xffff0000 // + + +struct brush_s; +typedef struct brush_s brush_t; + +typedef struct { + int width, height; // in control points, not patches + int horzSubdivisions; + int vertSubdivisions; + bool explicitSubdivisions; + int contents, flags, value, type; + const idMaterial *d_texture; + idDrawVert *verts; + //idDrawVert *ctrl; + brush_t * pSymbiot; + bool bSelected; + bool bOverlay; + int nListID; + int nListIDCam; + int nListSelected; + + idDict * epairs; + // cast this one to an IPluginTexdef if you are using it + // NOTE: casting can be done with a GETPLUGINTEXDEF defined in isurfaceplugin.h + // TODO: if the __ISURFACEPLUGIN_H_ header is used, use a union { void *pData; IPluginTexdef *pPluginTexdef } kind of thing ? + void * pData; + ID_INLINE idDrawVert &ctrl( int col, int row ) { + if ( col < 0 || col >= width || row < 0 || row >= height ) { + common->Warning( "patchMesh_t::ctrl: control point out of range" ); + return verts[0]; + } + else { + return verts[row * width + col]; + } + } +} patchMesh_t; + +enum { + LIGHT_TARGET, + LIGHT_RIGHT, + LIGHT_UP, + LIGHT_RADIUS, + LIGHT_X, + LIGHT_Y, + LIGHT_Z, + LIGHT_START, + LIGHT_END, + LIGHT_CENTER +}; + + +typedef struct brush_s +{ + struct brush_s *prev, *next; // links in active/selected + struct brush_s *oprev, *onext; // links in entity + brush_t * list; //keep a handy link to the list its in + struct entity_s *owner; + idVec3 mins, maxs; + + idVec3 lightCenter; // for moving the shading center of point lights + idVec3 lightRight; + idVec3 lightTarget; + idVec3 lightUp; + idVec3 lightRadius; + idVec3 lightOffset; + idVec3 lightColor; + idVec3 lightStart; + idVec3 lightEnd; + bool pointLight; + bool startEnd; + int lightTexture; + + bool trackLightOrigin; // this brush is a special case light brush + bool entityModel; + + face_t *brush_faces; + + bool bModelFailed; + // + // curve brush extensions + // all are derived from brush_faces + bool hiddenBrush; + bool forceWireFrame; + bool forceVisibile; + + patchMesh_t *pPatch; + struct entity_s *pUndoOwner; + + int undoId; //undo ID + int redoId; //redo ID + int ownerId; //entityId of the owner entity for undo + + // TTimo: HTREEITEM is MFC, some plugins really don't like it +#ifdef QERTYPES_USE_MFC + int numberId; // brush number + HTREEITEM itemOwner; // owner for grouping +#else + int numberId; + DWORD itemOwner; +#endif + + idRenderModel *modelHandle; + + // brush primitive only + idDict epairs; + +} brush_t; + + +#define MAX_FLAGS 8 + + +typedef struct trimodel_t +{ + idVec3 v[3]; + float st[3][2]; +} trimodel; + + +// eclass show flags + +#define ECLASS_LIGHT 0x00000001 +#define ECLASS_ANGLE 0x00000002 +#define ECLASS_PATH 0x00000004 +#define ECLASS_MISCMODEL 0x00000008 +#define ECLASS_PLUGINENTITY 0x00000010 +#define ECLASS_PROJECTEDLIGHT 0x00000020 +#define ECLASS_WORLDSPAWN 0x00000040 +#define ECLASS_SPEAKER 0x00000080 +#define ECLASS_PARTICLE 0x00000100 +#define ECLASS_ROTATABLE 0x00000200 +#define ECLASS_CAMERAVIEW 0x00000400 +#define ECLASS_MOVER 0x00000800 +#define ECLASS_ENV 0x00001000 +#define ECLASS_COMBATNODE 0x00002000 +#define ECLASS_LIQUID 0x00004000 + +enum EVAR_TYPES { + EVAR_STRING, + EVAR_INT, + EVAR_FLOAT, + EVAR_BOOL, + EVAR_COLOR, + EVAR_MATERIAL, + EVAR_MODEL, + EVAR_GUI, + EVAR_SOUND +}; + +typedef struct evar_s { + int type; + idStr name; + idStr desc; +} evar_t; + +typedef struct eclass_s +{ + struct eclass_s *next; + idStr name; + bool fixedsize; + bool unknown; // wasn't found in source + idVec3 mins, maxs; + idVec3 color; + texdef_t texdef; + idStr comments; + idStr desc; + + idRenderModel *modelHandle; + idRenderModel *entityModel; + + int nFrame; + unsigned int nShowFlags; + idStr defMaterial; + idDict args; + idDict defArgs; + idList vars; + + HMODULE hPlug; +} eclass_t; + +extern eclass_t *eclass; + +/* +** window bits +*/ +#define W_CAMERA 0x0001 +#define W_XY 0x0002 +#define W_XY_OVERLAY 0x0004 +#define W_Z 0x0008 +#define W_TEXTURE 0x0010 +#define W_Z_OVERLAY 0x0020 +#define W_CONSOLE 0x0040 +#define W_ENTITY 0x0080 +#define W_CAMERA_IFON 0x0100 +#define W_XZ 0x0200 //--| only used for patch vertex manip stuff +#define W_YZ 0x0400 //--| +#define W_MEDIA 0x1000 +#define W_GAME 0x2000 +#define W_ALL 0xFFFFFFFF + +// used in some Drawing routines +enum VIEWTYPE {YZ, XZ, XY}; + +#endif diff --git a/tools/radiant/Radiant.cpp b/tools/radiant/Radiant.cpp new file mode 100644 index 000000000..5cc589484 --- /dev/null +++ b/tools/radiant/Radiant.cpp @@ -0,0 +1,463 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "radiant.h" +#include "MainFrm.h" +#include "lightdlg.h" + +#include // for _beginthreadex and _endthreadex +#include // for MSGF_DDEMGR + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +idCVar radiant_entityMode( "radiant_entityMode", "0", CVAR_TOOL | CVAR_ARCHIVE, "" ); + +///////////////////////////////////////////////////////////////////////////// +// CRadiantApp + +BEGIN_MESSAGE_MAP(CRadiantApp, CWinApp) + //{{AFX_MSG_MAP(CRadiantApp) + ON_COMMAND(ID_HELP, OnHelp) + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) + // Standard print setup command + ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CRadiantApp construction + +CRadiantApp::CRadiantApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CRadiantApp object + +CRadiantApp theApp; +HINSTANCE g_DoomInstance = NULL; +bool g_editorAlive = false; + +void RadiantPrint( const char *text ) { + if ( g_editorAlive && g_Inspectors ) { + if (g_Inspectors->consoleWnd.GetSafeHwnd()) { + g_Inspectors->consoleWnd.AddText( text ); + } + } +} + +void RadiantShutdown( void ) { + theApp.ExitInstance(); +} + +/* +================= +RadiantInit + +This is also called when you 'quit' in doom +================= +*/ +void RadiantInit( void ) { + + // make sure the renderer is initialized + if ( !renderSystem->IsOpenGLRunning() ) { + common->Printf( "no OpenGL running\n" ); + return; + } + + g_editorAlive = true; + + // allocate a renderWorld and a soundWorld + if ( g_qeglobals.rw == NULL ) { + g_qeglobals.rw = renderSystem->AllocRenderWorld(); + g_qeglobals.rw->InitFromMap( NULL ); + } + if ( g_qeglobals.sw == NULL ) { + g_qeglobals.sw = soundSystem->AllocSoundWorld( g_qeglobals.rw ); + } + + if ( g_DoomInstance ) { + if ( ::IsWindowVisible( win32.hWnd ) ) { + ::ShowWindow( win32.hWnd, SW_HIDE ); + g_pParentWnd->ShowWindow( SW_SHOW ); + g_pParentWnd->SetFocus(); + } + } else { + Sys_GrabMouseCursor( false ); + + g_DoomInstance = win32.hInstance; + CWinApp* pApp = AfxGetApp(); + CWinThread *pThread = AfxGetThread(); + + InitAfx(); + + // App global initializations (rare) + pApp->InitApplication(); + + // Perform specific initializations + pThread->InitInstance(); + + qglFinish(); + //qwglMakeCurrent(0, 0); + qwglMakeCurrent(win32.hDC, win32.hGLRC); + + // hide the doom window by default + ::ShowWindow( win32.hWnd, SW_HIDE ); + } +} + + +extern void Map_VerifyCurrentMap(const char *map); + +void RadiantSync( const char *mapName, const idVec3 &viewOrg, const idAngles &viewAngles ) { + if ( g_DoomInstance == NULL ) { + RadiantInit(); + } + + if ( g_DoomInstance ) { + idStr osPath; + osPath = fileSystem->RelativePathToOSPath( mapName ); + Map_VerifyCurrentMap( osPath ); + idAngles flip = viewAngles; + flip.pitch = -flip.pitch; + g_pParentWnd->GetCamera()->SetView( viewOrg, flip ); + g_pParentWnd->SetFocus(); + Sys_UpdateWindows( W_ALL ); + g_pParentWnd->RoutineProcessing(); + } +} + +void RadiantRun( void ) { + static bool exceptionErr = false; + int show = ::IsWindowVisible(win32.hWnd); + + try { + if (!exceptionErr && !show) { + //qglPushAttrib(GL_ALL_ATTRIB_BITS); + qglDepthMask(true); + theApp.Run(); + //qglPopAttrib(); + //qwglMakeCurrent(0, 0); + qwglMakeCurrent(win32.hDC, win32.hGLRC); + } + } + catch( idException &ex ) { + ::MessageBox(NULL, ex.error, "Exception error", MB_OK); + RadiantShutdown(); + } +} + +///////////////////////////////////////////////////////////////////////////// +// CRadiantApp initialization + +HINSTANCE g_hOpenGL32 = NULL; +HINSTANCE g_hOpenGL = NULL; +bool g_bBuildList = false; + +BOOL CRadiantApp::InitInstance() +{ + //g_hOpenGL32 = ::LoadLibrary("opengl32.dll"); + // AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + //AfxEnableMemoryTracking(FALSE); + +#ifdef _AFXDLL + //Enable3dControls(); // Call this when using MFC in a shared DLL +#else + //Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // If there's a .INI file in the directory use it instead of registry + + char RadiantPath[_MAX_PATH]; + GetModuleFileName( NULL, RadiantPath, _MAX_PATH ); + + // search for exe + CFileFind Finder; + Finder.FindFile( RadiantPath ); + Finder.FindNextFile(); + // extract root + CString Root = Finder.GetRoot(); + // build root\*.ini + CString IniPath = Root + "\\REGISTRY.INI"; + // search for ini file + Finder.FindNextFile(); + if (Finder.FindFile( IniPath )) + { + Finder.FindNextFile(); + // use the .ini file instead of the registry + free((void*)m_pszProfileName); + m_pszProfileName=_tcsdup(_T(Finder.GetFilePath())); + // look for the registry key for void* buffers storage ( these can't go into .INI files ) + int i=0; + CString key; + HKEY hkResult; + DWORD dwDisp; + DWORD type; + char iBuf[3]; + do + { + sprintf( iBuf, "%d", i ); + key = "Software\\Q3Radiant\\IniPrefs" + CString(iBuf); + // does this key exists ? + if ( RegOpenKeyEx( HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkResult ) != ERROR_SUCCESS ) + { + // this key doesn't exist, so it's the one we'll use + strcpy( g_qeglobals.use_ini_registry, key.GetBuffer(0) ); + RegCreateKeyEx( HKEY_CURRENT_USER, key, 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkResult, &dwDisp ); + RegSetValueEx( hkResult, "RadiantName", 0, REG_SZ, reinterpret_cast(RadiantPath), strlen( RadiantPath )+1 ); + RegCloseKey( hkResult ); + break; + } + else + { + char RadiantAux[ _MAX_PATH ]; + unsigned long size = _MAX_PATH; + // the key exists, is it the one we are looking for ? + RegQueryValueEx( hkResult, "RadiantName", 0, &type, reinterpret_cast(RadiantAux), &size ); + RegCloseKey( hkResult ); + if ( !strcmp( RadiantAux, RadiantPath ) ) + { + // got it ! + strcpy( g_qeglobals.use_ini_registry, key.GetBuffer(0) ); + break; + } + } + i++; + } while (1); + g_qeglobals.use_ini = true; + } + else + { + // Change the registry key under which our settings are stored. + SetRegistryKey( EDITOR_REGISTRY_KEY ); + g_qeglobals.use_ini = false; + } + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + +// CMultiDocTemplate* pDocTemplate; +// pDocTemplate = new CMultiDocTemplate( +// IDR_RADIANTYPE, +// RUNTIME_CLASS(CRadiantDoc), +// RUNTIME_CLASS(CMainFrame), // custom MDI child frame +// RUNTIME_CLASS(CRadiantView)); +// AddDocTemplate(pDocTemplate); + + // create main MDI Frame window + + g_PrefsDlg.LoadPrefs(); + + qglEnableClientState( GL_VERTEX_ARRAY ); + + CString strTemp = m_lpCmdLine; + strTemp.MakeLower(); + if (strTemp.Find("builddefs") >= 0) { + g_bBuildList = true; + } + + CMainFrame* pMainFrame = new CMainFrame; + if (!pMainFrame->LoadFrame(IDR_MENU_QUAKE3)) { + return FALSE; + } + + if (pMainFrame->m_hAccelTable) { + ::DestroyAcceleratorTable(pMainFrame->m_hAccelTable); + } + + pMainFrame->LoadAccelTable(MAKEINTRESOURCE(IDR_MINIACCEL)); + + m_pMainWnd = pMainFrame; + + // The main window has been initialized, so show and update it. + pMainFrame->ShowWindow(m_nCmdShow); + pMainFrame->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CRadiantApp commands + +int CRadiantApp::ExitInstance() +{ + common->Shutdown(); + g_pParentWnd = NULL; + int ret = CWinApp::ExitInstance(); + ExitProcess(0); + return ret; +} + + +BOOL CRadiantApp::OnIdle(LONG lCount) { + if (g_pParentWnd) { + g_pParentWnd->RoutineProcessing(); + } + return FALSE; + //return CWinApp::OnIdle(lCount); +} + +void CRadiantApp::OnHelp() +{ + ShellExecute(m_pMainWnd->GetSafeHwnd(), "open", "http://www.idDevNet.com", NULL, NULL, SW_SHOW); +} + +int CRadiantApp::Run( void ) +{ + BOOL bIdle = TRUE; + LONG lIdleCount = 0; + + +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + // phase1: check to see if we can do idle work + while (bIdle && !::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE)) { + // call OnIdle while in bIdle state + if (!OnIdle(lIdleCount++)) { + bIdle = FALSE; // assume "no idle" state + } + } + + // phase2: pump messages while available + do { + // pump message, but quit on WM_QUIT + if (!PumpMessage()) { + return ExitInstance(); + } + + // reset "no idle" state after pumping "normal" message + if (IsIdleMessage(msg)) { + bIdle = TRUE; + lIdleCount = 0; + } + + } while (::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE)); + + return 0; +} + + +/* +============================================================= + +REGISTRY INFO + +============================================================= +*/ + +bool SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize) +{ + SetCvarBinary(pszName, pvBuf, lSize); + common->WriteFlaggedCVarsToFile( "editor.cfg", CVAR_TOOL, "sett" ); + return true; +} + +bool LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize) +{ + return GetCvarBinary(pszName, pvBuf, *plSize); +} + +bool SaveWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + GetWindowRect(hWnd, &rc); + if (hWnd != g_pParentWnd->GetSafeHwnd()) { + if (::GetParent(hWnd) != g_pParentWnd->GetSafeHwnd()) { + ::SetParent(hWnd, g_pParentWnd->GetSafeHwnd()); + } + MapWindowPoints(NULL, g_pParentWnd->GetSafeHwnd(), (POINT *)&rc, 2); + } + return SaveRegistryInfo(pszName, &rc, sizeof(rc)); +} + + +bool LoadWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + LONG lSize = sizeof(rc); + + if (LoadRegistryInfo(pszName, &rc, &lSize)) + { + if (rc.left < 0) + rc.left = 0; + if (rc.top < 0) + rc.top = 0; + if (rc.right < rc.left + 16) + rc.right = rc.left + 16; + if (rc.bottom < rc.top + 16) + rc.bottom = rc.top + 16; + + MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE); + return true; + } + + return false; +} + +/* +=============================================================== + + STATUS WINDOW + +=============================================================== +*/ + +void Sys_UpdateStatusBar( void ) +{ + extern int g_numbrushes, g_numentities; + + char numbrushbuffer[100] = ""; + + sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities ); + Sys_Status( numbrushbuffer, 2 ); +} + +void Sys_Status(const char *psz, int part ) +{ + if ( part < 0 ) { + common->Printf("%s", psz); + part = 0; + } + g_pParentWnd->SetStatusText(part, psz); +} diff --git a/tools/radiant/Radiant.h b/tools/radiant/Radiant.h new file mode 100644 index 000000000..e701bfa29 --- /dev/null +++ b/tools/radiant/Radiant.h @@ -0,0 +1,69 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#if !defined(AFX_RADIANT_H__330BBF06_731C_11D1_B539_00AA00A410FC__INCLUDED_) +#define AFX_RADIANT_H__330BBF06_731C_11D1_B539_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +///////////////////////////////////////////////////////////////////////////// +// CRadiantApp: +// See Radiant.cpp for the implementation of this class +// + +class CRadiantApp : public CWinApp +{ + +public: + CRadiantApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CRadiantApp) + public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + virtual BOOL OnIdle(LONG lCount); + virtual int Run( void ); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CRadiantApp) + afx_msg void OnHelp(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#define DATA_TO_DIALOG FALSE +#define DIALOG_TO_DATA TRUE + +#endif // !defined(AFX_RADIANT_H__330BBF06_731C_11D1_B539_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/RotateDlg.cpp b/tools/radiant/RotateDlg.cpp new file mode 100644 index 000000000..5067a29e5 --- /dev/null +++ b/tools/radiant/RotateDlg.cpp @@ -0,0 +1,128 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "RotateDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CRotateDlg dialog + + +CRotateDlg::CRotateDlg(CWnd* pParent /*=NULL*/) + : CDialog(CRotateDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CRotateDlg) + m_strX = _T(""); + m_strY = _T(""); + m_strZ = _T(""); + //}}AFX_DATA_INIT +} + + +void CRotateDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CRotateDlg) + DDX_Control(pDX, IDC_SPIN3, m_wndSpin3); + DDX_Control(pDX, IDC_SPIN2, m_wndSpin2); + DDX_Control(pDX, IDC_SPIN1, m_wndSpin1); + DDX_Text(pDX, IDC_ROTX, m_strX); + DDX_Text(pDX, IDC_ROTY, m_strY); + DDX_Text(pDX, IDC_ROTZ, m_strZ); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CRotateDlg, CDialog) + //{{AFX_MSG_MAP(CRotateDlg) + ON_BN_CLICKED(IDC_APPLY, OnApply) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN2, OnDeltaposSpin2) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN3, OnDeltaposSpin3) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CRotateDlg message handlers + +void CRotateDlg::OnOK() +{ + OnApply(); + CDialog::OnOK(); +} + +void CRotateDlg::OnApply() +{ + UpdateData(TRUE); + float f = atof(m_strX); + if (f != 0.0) + Select_RotateAxis(0,f); + f = atof(m_strY); + if (f != 0.0) + Select_RotateAxis(1,f); + f = atof(m_strZ); + if (f != 0.0) + Select_RotateAxis(2,f); +} + +BOOL CRotateDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_wndSpin1.SetRange(0, 359); + m_wndSpin2.SetRange(0, 359); + m_wndSpin3.SetRange(0, 359); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CRotateDlg::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + Select_RotateAxis(0, pNMUpDown->iDelta); + *pResult = 0; +} + +void CRotateDlg::OnDeltaposSpin2(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + Select_RotateAxis(1, pNMUpDown->iDelta); + *pResult = 0; +} + +void CRotateDlg::OnDeltaposSpin3(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + Select_RotateAxis(2, pNMUpDown->iDelta); + *pResult = 0; +} + +void CRotateDlg::ApplyNoPaint() +{ + +} diff --git a/tools/radiant/RotateDlg.h b/tools/radiant/RotateDlg.h new file mode 100644 index 000000000..18c3fb72f --- /dev/null +++ b/tools/radiant/RotateDlg.h @@ -0,0 +1,75 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_ROTATEDLG_H__D4B79152_7A7E_11D1_B541_00AA00A410FC__INCLUDED_) +#define AFX_ROTATEDLG_H__D4B79152_7A7E_11D1_B541_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// RotateDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CRotateDlg dialog + +class CRotateDlg : public CDialog +{ +// Construction +public: + CRotateDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CRotateDlg) + enum { IDD = IDD_ROTATE }; + CSpinButtonCtrl m_wndSpin3; + CSpinButtonCtrl m_wndSpin2; + CSpinButtonCtrl m_wndSpin1; + CString m_strX; + CString m_strY; + CString m_strZ; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CRotateDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + void ApplyNoPaint(); + + // Generated message map functions + //{{AFX_MSG(CRotateDlg) + virtual void OnOK(); + afx_msg void OnApply(); + virtual BOOL OnInitDialog(); + afx_msg void OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpin2(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpin3(NMHDR* pNMHDR, LRESULT* pResult); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ROTATEDLG_H__D4B79152_7A7E_11D1_B541_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/SELECT.CPP b/tools/radiant/SELECT.CPP new file mode 100644 index 000000000..4bc385b12 --- /dev/null +++ b/tools/radiant/SELECT.CPP @@ -0,0 +1,2201 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "../../renderer/model_local.h" // for idRenderModelPrt + +// externs +CPtrArray g_SelectedFaces; +CPtrArray g_SelectedFaceBrushes; +CPtrArray &g_ptrSelectedFaces = g_SelectedFaces; +CPtrArray &g_ptrSelectedFaceBrushes = g_SelectedFaceBrushes; + +extern void Brush_Resize(brush_t *b, idVec3 vMin, idVec3 vMax); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +qertrace_t Test_Ray(const idVec3 &origin, const idVec3 &dir, int flags) { + brush_t *brush; + face_t *face; + float dist; + qertrace_t t; + + memset(&t, 0, sizeof(t)); + t.dist = HUGE_DISTANCE*2; + + // check for points first + CDragPoint *drag = PointRay(origin, dir, &dist); + if (drag) { + t.dist = dist; + t.brush = NULL; + t.face = NULL; + t.point = drag; + t.selected = false; + return t; + } + + if (flags & SF_CYCLE) { + CPtrArray array; + brush_t *pToSelect = (selected_brushes.next != &selected_brushes) ? selected_brushes.next : NULL; + Select_Deselect(); + + // go through active brushes and accumulate all "hit" brushes + for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) { + // if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue; + if (FilterBrush(brush)) { + continue; + } + + if (g_PrefsDlg.m_selectOnlyBrushes) { + if (brush->pPatch || brush->modelHandle > 0) { + continue; + } + } + + if (g_PrefsDlg.m_selectNoModels) { + if (brush->modelHandle > 0) { + continue; + } + } + + // if (!g_bShowPatchBounds && brush->pPatch) continue; + face = Brush_Ray(origin, dir, brush, &dist, true); + + if (face) { + array.Add(brush); + } + } + + int nSize = array.GetSize(); + if (nSize > 0) { + bool bFound = false; + for (int i = 0; i < nSize; i++) { + brush_t *b = reinterpret_cast < brush_t * > (array.GetAt(i)); + + // did we hit the last one selected yet ? + if (b == pToSelect) { + // yes we want to select the next one in the list + int n = (i > 0) ? i - 1 : nSize - 1; + pToSelect = reinterpret_cast < brush_t * > (array.GetAt(n)); + bFound = true; + break; + } + } + + if (!bFound) { + pToSelect = reinterpret_cast < brush_t * > (array.GetAt(0)); + } + } + + if (pToSelect) { + face = Brush_Ray(origin, dir, pToSelect, &dist, true); + t.dist = dist; + t.brush = pToSelect; + t.face = face; + t.selected = false; + return t; + } + } + + if (!(flags & SF_SELECTED_ONLY)) { + for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) { + if ((flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) { + continue; + } + + if (FilterBrush(brush)) { + continue; + } + + if (g_PrefsDlg.m_selectOnlyBrushes) { + if (brush->pPatch || brush->modelHandle > 0) { + continue; + } + } + + if (g_PrefsDlg.m_selectNoModels) { + if (brush->modelHandle > 0) { + continue; + } + } + + face = Brush_Ray(origin, dir, brush, &dist, true); + if (dist > 0 && dist < t.dist) { + t.dist = dist; + t.brush = brush; + t.face = face; + t.selected = false; + } + } + } + + for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { + if ((flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) { + continue; + } + + if (FilterBrush(brush)) { + continue; + } + + if (g_PrefsDlg.m_selectOnlyBrushes) { + if (brush->pPatch || brush->modelHandle > 0) { + continue; + } + } + + if (g_PrefsDlg.m_selectNoModels) { + if (brush->modelHandle > 0) { + continue; + } + } + + face = Brush_Ray(origin, dir, brush, &dist, true); + if (dist > 0 && dist < t.dist) { + t.dist = dist; + t.brush = brush; + t.face = face; + t.selected = true; + } + } + + // if entites first, but didn't find any, check regular + if ((flags & SF_ENTITIES_FIRST) && t.brush == NULL) { + return Test_Ray(origin, dir, flags - SF_ENTITIES_FIRST); + } + + return t; +} + +extern void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority); +extern void ClearSelectablePoints(brush_t *b); +extern idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in); + +/* + ======================================================================================================================= + Select_Brush + ======================================================================================================================= + */ +void Select_Brush(brush_t *brush, bool bComplete, bool bStatus) { + brush_t *b; + entity_t *e; + + g_ptrSelectedFaces.RemoveAll(); + g_ptrSelectedFaceBrushes.RemoveAll(); + + // selected_face = NULL; + if (g_qeglobals.d_select_count < MAX_MAP_ENTITIES) { + g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush; + } + + g_qeglobals.d_select_count++; + + e = brush->owner; + if (e) { + + if ( e == world_entity && radiant_entityMode.GetBool() ) { + return; + } + // select complete entity on first click + if (e != world_entity && bComplete == true) { + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->owner == e) { + goto singleselect; + } + } + + for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + else + { +singleselect: + Brush_RemoveFromList(brush); + Brush_AddToList(brush, &selected_brushes); + UpdateSurfaceDialog(); + UpdatePatchInspector(); + UpdateLightInspector(); + } + + if (e->eclass) { + g_Inspectors->UpdateEntitySel(brush->owner->eclass); + if ( radiant_entityMode.GetBool() && e->eclass->nShowFlags & (ECLASS_LIGHT | ECLASS_SPEAKER) ) { + const char *p = ValueForKey(e, "s_shader"); + if (p && *p) { + g_Inspectors->mediaDlg.SelectCurrentItem(true, p, CDialogTextures::SOUNDS); + } + + } + if ( ( e->eclass->nShowFlags & ECLASS_LIGHT ) && !brush->entityModel ) { + if (brush->pointLight) { + // add center drag point if not at the origin + if (brush->lightCenter[0] || brush->lightCenter[1] || brush->lightCenter[2]) { + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightCenter), LIGHT_CENTER, false); + } + } + else { + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightTarget), LIGHT_TARGET, true); + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightUp), LIGHT_UP, false); + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightRight), LIGHT_RIGHT, false); + if (brush->startEnd) { + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightStart), LIGHT_START, false); + AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightEnd), LIGHT_END, false); + } + } + UpdateLightInspector(); + } + if (e->eclass->nShowFlags & ECLASS_CAMERAVIEW) { + g_pParentWnd->GetCamera()->UpdateCameraView(); + } + } + } + + if (bStatus) { + idVec3 vMin, vMax, vSize; + Select_GetBounds(vMin, vMax); + VectorSubtract(vMax, vMin, vSize); + + CString strStatus; + strStatus.Format("Selection X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]); + g_pParentWnd->SetStatusText(2, strStatus); + } +} + +/* + ======================================================================================================================= + Select_Ray If the origin is inside a brush, that brush will be ignored. + ======================================================================================================================= + */ +void Select_Ray(idVec3 origin, idVec3 dir, int flags) { + qertrace_t t; + + t = Test_Ray(origin, dir, flags); + + if (!t.brush) { + return; + } + + if (flags == SF_SINGLEFACE) { + int nCount = g_SelectedFaces.GetSize(); + bool bOk = true; + for (int i = 0; i < nCount; i++) { + if (t.face == reinterpret_cast < face_t * > (g_SelectedFaces.GetAt(i))) { + bOk = false; + + // need to move remove i'th entry + g_SelectedFaces.RemoveAt(i, 1); + g_SelectedFaceBrushes.RemoveAt(i, 1); + nCount--; + } + } + + if (bOk) { + if ( t.selected ) { + face_t *face; + + // DeSelect brush + Brush_RemoveFromList(t.brush); + Brush_AddToList(t.brush, &active_brushes); + + // Select all brush faces + for ( face = t.brush->brush_faces; face; face = face->next ) { + //Don't add face that was clicked + if ( face != t.face ) { + g_SelectedFaces.Add( face ); + g_SelectedFaceBrushes.Add( t.brush ); + } + } + } else { + g_SelectedFaces.Add(t.face); + g_SelectedFaceBrushes.Add(t.brush); + } + } + + // selected_face = t.face; selected_face_brush = t.brush; + Sys_UpdateWindows(W_ALL); + g_qeglobals.d_select_mode = sel_brush; + + + //common->Printf("before\n"); + //extern void Face_Info_BrushPrimit(face_t *face); + //Face_Info_BrushPrimit(t.face); + //common->Printf("after\n"); + + // + // Texture_SetTexture requires a brushprimit_texdef fitted to the default width=2 + // height=2 texture + // + brushprimit_texdef_t brushprimit_texdef; + ConvertTexMatWithQTexture(&t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL); + Texture_SetTexture(&t.face->texdef, &brushprimit_texdef, false, false); + UpdateSurfaceDialog(); + + + return; + } + + // move the brush to the other list + g_qeglobals.d_select_mode = sel_brush; + + if (t.selected) { + Brush_RemoveFromList(t.brush); + Brush_AddToList(t.brush, &active_brushes); + UpdatePatchInspector(); + UpdateSurfaceDialog(); + + entity_t *e = t.brush->owner; + if (e->eclass->nShowFlags & ECLASS_LIGHT && !t.brush->entityModel) { + if (t.brush->pointLight) { + } + else { + ClearSelectablePoints(t.brush); + } + } + } + else { + Select_Brush(t.brush, !(GetAsyncKeyState(VK_MENU) & 0x8000)); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Delete(void) { + brush_t *brush; + + g_ptrSelectedFaces.RemoveAll(); + g_ptrSelectedFaceBrushes.RemoveAll(); + + // selected_face = NULL; + g_qeglobals.d_select_mode = sel_brush; + + g_qeglobals.d_select_count = 0; + g_qeglobals.d_num_move_points = 0; + while (selected_brushes.next != &selected_brushes) { + brush = selected_brushes.next; + if (brush->pPatch) { + // Patch_Delete(brush->nPatchID); + Patch_Delete(brush->pPatch); + } + + Brush_Free(brush); + } + + // FIXME: remove any entities with no brushes + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Deselect(bool bDeselectFaces) { + brush_t *b; + + ClearSelectablePoints(NULL); + Patch_Deselect(); + + g_pParentWnd->ActiveXY()->UndoClear(); + + g_qeglobals.d_workcount++; + g_qeglobals.d_select_count = 0; + g_qeglobals.d_num_move_points = 0; + b = selected_brushes.next; + + if (b == &selected_brushes) { + if (bDeselectFaces) { + g_ptrSelectedFaces.RemoveAll(); + g_ptrSelectedFaceBrushes.RemoveAll(); + + // selected_face = NULL; + } + + Sys_UpdateWindows(W_ALL); + return; + } + + if (bDeselectFaces) { + g_ptrSelectedFaces.RemoveAll(); + g_ptrSelectedFaceBrushes.RemoveAll(); + + // selected_face = NULL; + } + + g_qeglobals.d_select_mode = sel_brush; + + // grab top / bottom height for new brushes + if (b->mins[2] < b->maxs[2]) { + g_qeglobals.d_new_brush_bottom = b->mins; + g_qeglobals.d_new_brush_top = b->maxs; + } + + selected_brushes.next->prev = &active_brushes; + selected_brushes.prev->next = active_brushes.next; + active_brushes.next->prev = selected_brushes.prev; + active_brushes.next = selected_brushes.next; + selected_brushes.prev = selected_brushes.next = &selected_brushes; + + g_pParentWnd->GetCamera()->UpdateCameraView(); + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Select_Move + ======================================================================================================================= + */ +void Select_Move(idVec3 delta, bool bSnap) { + brush_t *b; + + // actually move the selected brushes + bool updateOrigin = true; + entity_t *lastOwner = selected_brushes.next->owner; + + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + Brush_Move(b, delta, bSnap, updateOrigin); + if (updateOrigin) { + updateOrigin = false; + } + + if (b->next->owner != lastOwner) { + updateOrigin = true; + lastOwner = b->next->owner; + } + } + + idVec3 vMin, vMax; + Select_GetBounds(vMin, vMax); + + CString strStatus; + strStatus.Format("Origin X:: %.1f Y:: %.1f Z:: %.1f", vMin[0], vMax[1], vMax[2]); + g_pParentWnd->SetStatusText(2, strStatus); + g_pParentWnd->GetCamera()->UpdateCameraView(); + + // Sys_UpdateWindows (W_ALL); +} + +/* + ======================================================================================================================= + Select_Clone Creates an exact duplicate of the selection in place, then moves the selected brushes off of their old + positions + ======================================================================================================================= + */ +void Select_Clone(void) { + ASSERT(g_pParentWnd->ActiveXY()); + g_bScreenUpdates = false; + g_pParentWnd->ActiveXY()->Copy(); + g_pParentWnd->ActiveXY()->Paste(); + g_pParentWnd->NudgeSelection(2, g_qeglobals.d_gridsize); + g_pParentWnd->NudgeSelection(3, g_qeglobals.d_gridsize); + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Select_SetTexture Timo:: bFitScale to compute scale on the plane and counteract plane / axial plane snapping Timo:: + brush primitive texturing the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes + ) Timo:: texture plugin, added an IPluginTexdef* parameter must be casted to an IPluginTexdef! if not NULL, get + ->Copy() of it into each face or brush ( and remember to hook ) if NULL, means we have no information, ask for a + default + ======================================================================================================================= + */ +void WINAPI Select_SetTexture(texdef_t *texdef,brushprimit_texdef_t *brushprimit_texdef,bool bFitScale,void *pPlugTexdef,bool update) { + brush_t *b; + int nCount = g_ptrSelectedFaces.GetSize(); + if (nCount > 0) { + Undo_Start("set face textures"); + ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize()); + for (int i = 0; i < nCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + Undo_AddBrush(selBrush); + SetFaceTexdef(selBrush,selFace,texdef,brushprimit_texdef,bFitScale); + Brush_Build(selBrush, bFitScale); + Undo_EndBrush(selBrush); + } + + Undo_End(); + } + else if (selected_brushes.next != &selected_brushes) { + Undo_Start("set brush textures"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (!b->owner->eclass->fixedsize) { + Undo_AddBrush(b); + Brush_SetTexture(b, texdef, brushprimit_texdef, bFitScale); + Undo_EndBrush(b); + } else if (b->owner->eclass->nShowFlags & ECLASS_LIGHT) { + if ( idStr::Cmpn(texdef->name, "lights/", strlen("lights/")) == 0 ) { + SetKeyValue(b->owner, "texture", texdef->name); + g_Inspectors->UpdateEntitySel(b->owner->eclass); + UpdateLightInspector(); + Brush_Build(b); + } else { + Undo_AddBrush(b); + Brush_SetTexture(b, texdef, brushprimit_texdef, bFitScale); + Undo_EndBrush(b); + } + } + } + + Undo_End(); + } + + if (update) { + Sys_UpdateWindows(W_ALL); + } +} + +/* + ======================================================================================================================= + TRANSFORMATIONS + ======================================================================================================================= + */ +void Select_GetBounds(idVec3 &mins, idVec3 &maxs) { + brush_t *b; + int i; + + for (i = 0; i < 3; i++) { + mins[i] = 999999; + maxs[i] = -999999; + } + + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (i = 0; i < 3; i++) { + if (b->mins[i] < mins[i]) { + mins[i] = b->mins[i]; + } + + if (b->maxs[i] > maxs[i]) { + maxs[i] = b->maxs[i]; + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_GetTrueMid(idVec3 &mid) { + idVec3 mins, maxs; + Select_GetBounds(mins, maxs); + + for (int i = 0; i < 3; i++) { + mid[i] = (mins[i] + ((maxs[i] - mins[i]) / 2)); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_GetMid(idVec3 &mid) { +#if 0 + Select_GetTrueMid(mid); + return; +#else + idVec3 mins, maxs; + int i; + + //if (g_PrefsDlg.m_bNoClamp) { + // Select_GetTrueMid(mid); + // return; + //} + + Select_GetBounds(mins, maxs); + + for (i = 0; i < 3; i++) { + mid[i] = g_qeglobals.d_gridsize * floor(((mins[i] + maxs[i]) * 0.5) / g_qeglobals.d_gridsize); + } +#endif +} + +idVec3 select_origin; +idMat3 select_matrix; +idMat3 select_bmatrix; +idRotation select_rotation; +bool select_fliporder; +int select_flipAxis; +float select_orgDeg; + +void Select_InitializeRotation() { + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (face_t *f = b->brush_faces; f; f = f->next) { + for (int i = 0; i < 3; i++) { + f->orgplanepts[i] = f->planepts[i]; + } + } + } + select_orgDeg = 0.0; +} + +void Select_FinalizeRotation() { + +} + +bool Select_OnlyModelsSelected() { + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (!b->modelHandle) { + return false; + } + } + return true; +} + +bool OkForRotationKey(brush_t *b) { + if (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) { + return false; + } + + if (stricmp(b->owner->epairs.GetString("name"), b->owner->epairs.GetString("model")) == 0) { + return false; + } + + return true; +} + +/* +================= +VectorRotate3 + + rotation order is roll - pitch - yaw +================= +*/ +void VectorRotate3( const idVec3 &vIn, const idVec3 &vRotation, idVec3 &out) { +#if 1 + int i, nIndex[3][2]; + idVec3 vWork, va; + + va = vIn; + vWork = va; + nIndex[0][0] = 1; nIndex[0][1] = 2; + nIndex[1][0] = 2; nIndex[1][1] = 0; + nIndex[2][0] = 0; nIndex[2][1] = 1; + + for (i = 0; i < 3; i++) { + if ( vRotation[i] != 0.0f ) { + double dAngle = DEG2RAD( vRotation[i] ); + double c = cos( dAngle ); + double s = sin( dAngle ); + vWork[nIndex[i][0]] = va[nIndex[i][0]] * c - va[nIndex[i][1]] * s; + vWork[nIndex[i][1]] = va[nIndex[i][0]] * s + va[nIndex[i][1]] * c; + } + va = vWork; + } + out = vWork; +#else + idAngles angles; + + angles.pitch = vRotation[1]; + angles.yaw = vRotation[2]; + angles.roll = vRotation[0]; + + out = vIn * angles.ToMat3(); +#endif +} + +/* +================= +VectorRotate3Origin +================= +*/ +void VectorRotate3Origin( const idVec3 &vIn, const idVec3 &vRotation, const idVec3 &vOrigin, idVec3 &out ) { + out = vIn - vOrigin; + VectorRotate3( out, vRotation, out ); + out += vOrigin; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild); + +void Select_ApplyMatrix(bool bSnap, bool rotateOrigins) { + brush_t *b; + face_t *f; + int i; + idVec3 temp; + idStr str; + char text[128]; + entity_t *lastOwner = NULL; + + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + + bool doBrush = true; + if (!(b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) && b->owner != lastOwner) { + if (b->modelHandle || b->owner->eclass->nShowFlags & ECLASS_ROTATABLE) { + if (rotateOrigins) { + b->owner->rotation *= select_matrix; + b->owner->origin *= select_rotation; + SetKeyVec3(b->owner, "origin", b->owner->origin); + if (b->trackLightOrigin) { + b->owner->lightRotation *= select_matrix; + b->owner->lightOrigin *= select_rotation; + SetKeyVec3(b->owner, "light_origin", b->owner->lightOrigin); + } + } else { + + b->owner->rotation *= select_matrix; + if ( select_fliporder ) { + if ( select_flipAxis == 0 ) { + temp = b->owner->rotation[1]; + b->owner->rotation[1] = b->owner->rotation[2]; + b->owner->rotation[2] = temp; + } else if ( select_flipAxis == 1 ) { + temp = b->owner->rotation[0]; + b->owner->rotation[0] = b->owner->rotation[1]; + b->owner->rotation[1] = temp; + } else { + temp = b->owner->rotation[0]; + b->owner->rotation[0] = b->owner->rotation[2]; + b->owner->rotation[2] = temp; + } + } + + if (b->trackLightOrigin) { + b->owner->lightRotation = select_matrix * b->owner->lightRotation; + } + } + b->owner->rotation.OrthoNormalizeSelf(); + b->owner->lightRotation.OrthoNormalizeSelf(); + + if (b->modelHandle) { + idBounds bo, bo2; + bo2.Zero(); + if ( dynamic_cast( b->modelHandle ) || dynamic_cast( b->modelHandle ) ) { + bo2.ExpandSelf( 12.0f ); + } else { + bo2 = b->modelHandle->Bounds(); + } + bo.FromTransformedBounds(bo2, b->owner->origin, b->owner->rotation); + Brush_Resize(b, bo[0], bo[1]); + doBrush = false; + } + if (b->owner->eclass->fixedsize) { + doBrush = false; + } + } else if (b->owner->eclass->fixedsize && !rotateOrigins) { + doBrush = false; + } else { + b->owner->origin -= select_origin; + b->owner->origin *= select_matrix; + b->owner->origin += select_origin; + sprintf(text, "%i %i %i", (int)b->owner->origin[0], (int)b->owner->origin[1], (int)b->owner->origin[2]); + + SetKeyValue(b->owner, "origin", text); + } + + + + if (OkForRotationKey(b)) { + sprintf(str, "%g %g %g %g %g %g %g %g %g",b->owner->rotation[0][0],b->owner->rotation[0][1],b->owner->rotation[0][2], + b->owner->rotation[1][0],b->owner->rotation[1][1],b->owner->rotation[1][2],b->owner->rotation[2][0], + b->owner->rotation[2][1],b->owner->rotation[2][2]); + SetKeyValue(b->owner, "rotation", str); + } + + if (b->trackLightOrigin) { + sprintf(str, "%g %g %g %g %g %g %g %g %g",b->owner->lightRotation[0][0],b->owner->lightRotation[0][1],b->owner->lightRotation[0][2], + b->owner->lightRotation[1][0],b->owner->lightRotation[1][1],b->owner->lightRotation[1][2],b->owner->lightRotation[2][0], + b->owner->lightRotation[2][1],b->owner->lightRotation[2][2]); + SetKeyValue(b->owner, "light_rotation", str); + } + DeleteKey(b->owner, "angle"); + DeleteKey(b->owner, "angles"); + } + + if (doBrush) { + for (f = b->brush_faces; f; f = f->next) { + for (i = 0; i < 3; i++) { + f->planepts[i] = ( ((g_bRotateMode) ? f->orgplanepts[i] : f->planepts[i]) - select_origin ) * ((g_bRotateMode) ? select_bmatrix : select_matrix) + select_origin; + } + + if ( select_fliporder ) { + VectorCopy(f->planepts[0], temp); + VectorCopy(f->planepts[2], f->planepts[0]); + VectorCopy(temp, f->planepts[2]); + } + } + } + + if (b->owner->eclass->fixedsize && b->owner->eclass->entityModel == NULL) { + idVec3 min, max; + if (b->trackLightOrigin) { + min = b->owner->lightOrigin + b->owner->eclass->mins; + max = b->owner->lightOrigin + b->owner->eclass->maxs; + } else { + min = b->owner->origin + b->owner->eclass->mins; + max = b->owner->origin + b->owner->eclass->maxs; + } + Brush_Resize(b, min, max); + } else { + Brush_Build(b, bSnap); + } + + if (b->pPatch) { + Patch_ApplyMatrix(b->pPatch, select_origin, select_matrix, bSnap); + } + + if ( b->owner->curve ) { + int c = b->owner->curve->GetNumValues(); + for ( i = 0; i < c; i++ ) { + idVec3 v = b->owner->curve->GetValue( i ); + v -= select_origin; + v *= select_matrix; + v += select_origin; + b->owner->curve->SetValue( i, v ); + } + } + + lastOwner = b->owner; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void RotateFaceTexture(face_t *f, int nAxis, float fDeg) { + idVec3 p1, p2, p3, rota; + p1[0] = p1[1] = p1[2] = 0; + VectorCopy(p1, p2); + VectorCopy(p1, p3); + VectorCopy(p1, rota); + ComputeAbsolute(f, p1, p2, p3); + + rota[nAxis] = fDeg; + VectorRotate3Origin(p1, rota, select_origin, p1); + VectorRotate3Origin(p2, rota, select_origin, p2); + VectorRotate3Origin(p3, rota, select_origin, p3); + + idPlane normal2; + idVec3 vNormal; + vNormal[0] = f->plane[0]; + vNormal[1] = f->plane[1]; + vNormal[2] = f->plane[2]; + VectorRotate3(vNormal, rota, vNormal); + normal2[0] = vNormal[0]; + normal2[1] = vNormal[1]; + normal2[2] = vNormal[2]; + AbsoluteToLocal(normal2, f, p1, p2, p3); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void RotateTextures(int nAxis, float fDeg, idVec3 vOrigin) { + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (face_t * f = b->brush_faces; f; f = f->next) { + if (g_qeglobals.m_bBrushPrimitMode) { + RotateFaceTexture_BrushPrimit(f, nAxis, fDeg, vOrigin); + } + else { + RotateFaceTexture(f, nAxis, fDeg); + } + + // ++timo removed that call .. works fine .. ??????? Brush_Build(b, false); + } + + Brush_Build(b, false); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_ApplyMatrix_BrushPrimit() { + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (face_t * f = b->brush_faces; f; f = f->next) { + ApplyMatrix_BrushPrimit(f, select_matrix, select_origin); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_RotateAxis(int axis, float deg, bool bPaint, bool bMouse) { + idVec3 temp; + + if (deg == 0) { + return; + } + + if (bMouse) { + if (g_qeglobals.flatRotation == 2) { + Select_GetTrueMid(select_origin); + } else { + VectorCopy(g_pParentWnd->ActiveXY()->RotateOrigin(), select_origin); + } + } else { + Select_GetMid(select_origin); + } + + select_fliporder = false; + + idVec3 vec = vec3_origin; + vec[axis] = 1.0f; + + if (g_bRotateMode) { + select_orgDeg += deg; + } + + select_rotation.Set( select_origin, vec, deg ); + select_matrix = select_rotation.ToMat3(); + idRotation rot(select_origin, vec, select_orgDeg); + rot.Normalize360(); + select_bmatrix = rot.ToMat3(); + + + if (g_PrefsDlg.m_bRotateLock) { + select_matrix.TransposeSelf(); + Select_ApplyMatrix_BrushPrimit(); + //RotateTextures(axis, -deg, select_origin); + } + + select_matrix.TransposeSelf(); + Select_ApplyMatrix( !bMouse, ( g_qeglobals.flatRotation != 0 ) ); + + if (bPaint) { + Sys_UpdateWindows(W_ALL); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ProjectOnPlane( const idVec3 &normal, float dist, idVec3 &ez, idVec3 &p) { + if (idMath::Fabs(ez[0]) == 1) { + p[0] = (dist - normal[1] * p[1] - normal[2] * p[2]) / normal[0]; + } + else if (idMath::Fabs(ez[1]) == 1) { + p[1] = (dist - normal[0] * p[0] - normal[2] * p[2]) / normal[1]; + } + else { + p[2] = (dist - normal[0] * p[0] - normal[1] * p[1]) / normal[2]; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Back(idVec3 &dir, idVec3 &p) { + if (idMath::Fabs(dir[0]) == 1) { + p[0] = 0; + } + else if (idMath::Fabs(dir[1]) == 1) { + p[1] = 0; + } + else { + p[2] = 0; + } +} + +// +// ======================================================================================================================= +// using scale[0] and scale[1] +// ======================================================================================================================= +// +void ComputeScale(idVec3 &rex, idVec3 &rey, idVec3 &p, face_t *f) { + float px = DotProduct(rex, p); + float py = DotProduct(rey, p); + px *= f->texdef.scale[0]; + py *= f->texdef.scale[1]; + + idVec3 aux; + VectorCopy(rex, aux); + VectorScale(aux, px, aux); + VectorCopy(aux, p); + VectorCopy(rey, aux); + VectorScale(aux, py, aux); + VectorAdd(p, aux, p); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ComputeAbsolute(face_t *f, idVec3 &p1, idVec3 &p2, idVec3 &p3) { + idVec3 ex, ey, ez; // local axis base + +#ifdef _DEBUG + if (g_qeglobals.m_bBrushPrimitMode) { + common->Printf("Warning : illegal call of ComputeAbsolute in brush primitive mode\n"); + } +#endif + // compute first local axis base + TextureAxisFromPlane( f->plane, ex, ey ); + ez = ex.Cross( ey ); + + idVec3 aux; + VectorCopy(ex, aux); + VectorScale(aux, -f->texdef.shift[0], aux); + VectorCopy(aux, p1); + VectorCopy(ey, aux); + VectorScale(aux, -f->texdef.shift[1], aux); + VectorAdd(p1, aux, p1); + VectorCopy(p1, p2); + VectorAdd(p2, ex, p2); + VectorCopy(p1, p3); + VectorAdd(p3, ey, p3); + VectorCopy(ez, aux); + VectorScale(aux, -f->texdef.rotate, aux); + VectorRotate3(p1, aux, p1); + VectorRotate3(p2, aux, p2); + VectorRotate3(p3, aux, p3); + + // computing rotated local axis base + idVec3 rex, rey; + VectorCopy(ex, rex); + VectorRotate3(rex, aux, rex); + VectorCopy(ey, rey); + VectorRotate3(rey, aux, rey); + + ComputeScale(rex, rey, p1, f); + ComputeScale(rex, rey, p2, f); + ComputeScale(rex, rey, p3, f); + + // project on normal plane along ez assumes plane normal is normalized + ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p1); + ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p2); + ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p3); +}; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void AbsoluteToLocal( const idPlane &normal2, face_t *f, idVec3 &p1, idVec3 &p2, idVec3 &p3) { + idVec3 ex, ey, ez; + +#ifdef _DEBUG + if (g_qeglobals.m_bBrushPrimitMode) { + common->Printf("Warning : illegal call of AbsoluteToLocal in brush primitive mode\n"); + } +#endif + // computing new local axis base + TextureAxisFromPlane( normal2, ex, ey ); + ez = ex.Cross( ey ); + + // projecting back on (ex,ey) + Back(ez, p1); + Back(ez, p2); + Back(ez, p3); + + idVec3 aux; + + // rotation + VectorCopy(p2, aux); + VectorSubtract(aux, p1, aux); + + float x = DotProduct(aux, ex); + float y = DotProduct(aux, ey); + f->texdef.rotate = RAD2DEG( atan2(y, x) ); + + idVec3 rex, rey; + + // computing rotated local axis base + VectorCopy(ez, aux); + VectorScale(aux, f->texdef.rotate, aux); + VectorCopy(ex, rex); + VectorRotate3(rex, aux, rex); + VectorCopy(ey, rey); + VectorRotate3(rey, aux, rey); + + // scale + VectorCopy(p2, aux); + VectorSubtract(aux, p1, aux); + f->texdef.scale[0] = DotProduct(aux, rex); + VectorCopy(p3, aux); + VectorSubtract(aux, p1, aux); + f->texdef.scale[1] = DotProduct(aux, rey); + + // shift only using p1 + x = DotProduct(rex, p1); + y = DotProduct(rey, p1); + x /= f->texdef.scale[0]; + y /= f->texdef.scale[1]; + + VectorCopy(rex, p1); + VectorScale(p1, x, p1); + VectorCopy(rey, aux); + VectorScale(aux, y, aux); + VectorAdd(p1, aux, p1); + VectorCopy(ez, aux); + VectorScale(aux, -f->texdef.rotate, aux); + VectorRotate3(p1, aux, p1); + f->texdef.shift[0] = -DotProduct(p1, ex); + f->texdef.shift[1] = -DotProduct(p1, ey); + + // stored rot is good considering local axis base change it if necessary + f->texdef.rotate = -f->texdef.rotate; + + Clamp(f->texdef.shift[0], f->d_texture->GetEditorImage()->uploadWidth); + Clamp(f->texdef.shift[1], f->d_texture->GetEditorImage()->uploadHeight); + Clamp(f->texdef.rotate, 360); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_FlipAxis(int axis) { + + Select_GetMid( select_origin ); + + for ( int i = 0; i < 3; i++) { + VectorCopy(vec3_origin, select_matrix[i]); + select_matrix[i][i] = 1; + } + + select_matrix[axis][axis] = -1; + + select_matrix.Identity(); + select_matrix[axis][axis] = -1; + + select_fliporder = true; + select_flipAxis = axis; + + // texture locking + if (g_PrefsDlg.m_bRotateLock) { + // + // axis flipping inverts space orientation, we have to use a general texture + // locking algorithm instead of the RotateFaceTexture + // + if (g_qeglobals.m_bBrushPrimitMode) { + Select_ApplyMatrix_BrushPrimit(); + } + else { + // + // there's never been flip locking for non BP mode, this would be tricky to write + // and there's not much interest for it with the coming of BP format what could be + // done is converting regular to BP, locking, then back to regular :) + // Sys_FPrintf(SYS_WRN, "WARNING: regular texturing doesn't have texture lock on + // flipping operations\n"); + // + } + } + + // geometric transformation + Select_ApplyMatrix(true, false); + Sys_UpdateWindows(W_ALL);} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Scale(float x, float y, float z) { + Select_GetMid(select_origin); + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (face_t * f = b->brush_faces; f; f = f->next) { + for (int i = 0; i < 3; i++) { + f->planepts[i][0] -= select_origin[0]; + f->planepts[i][1] -= select_origin[1]; + f->planepts[i][2] -= select_origin[2]; + f->planepts[i][0] *= x; + + // + // f->planepts[i][0] = floor(f->planepts[i][0] / g_qeglobals.d_gridsize + 0.5) * + // g_qeglobals.d_gridsize; + // + f->planepts[i][1] *= y; + + // + // f->planepts[i][1] = floor(f->planepts[i][1] / g_qeglobals.d_gridsize + 0.5) * + // g_qeglobals.d_gridsize; + // + f->planepts[i][2] *= z; + + // + // f->planepts[i][2] = floor(f->planepts[i][2] / g_qeglobals.d_gridsize + 0.5) * + // g_qeglobals.d_gridsize; + // + f->planepts[i][0] += select_origin[0]; + f->planepts[i][1] += select_origin[1]; + f->planepts[i][2] += select_origin[2]; + } + } + + Brush_Build(b, false); + if (b->pPatch) { + idVec3 v; + v[0] = x; + v[1] = y; + v[2] = z; + + // Patch_Scale(b->nPatchID, select_origin, v); + Patch_Scale(b->pPatch, select_origin, v); + } + } +} + +/* + ======================================================================================================================= + GROUP SELECTIONS + ======================================================================================================================= + */ +void Select_CompleteTall(void) { + brush_t *b, *next; + + // int i; + idVec3 mins, maxs; + + if (!QE_SingleBrush()) { + return; + } + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy(selected_brushes.next->mins, mins); + VectorCopy(selected_brushes.next->maxs, maxs); + Select_Delete(); + + int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0; + int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2; + + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if ((b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1]) || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2])) { + if (!(b->owner->origin[nDim1] > mins[nDim1] && b->owner->origin[nDim1] < maxs[nDim1] && b->owner->origin[nDim2] > mins[nDim2] && b->owner->origin[nDim2] < maxs[nDim2])) { + continue; + } + if (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) { + continue; + } + } + + if (FilterBrush(b)) { + continue; + } + + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_PartialTall(void) { + brush_t *b, *next; + + // int i; + idVec3 mins, maxs; + + if (!QE_SingleBrush()) { + return; + } + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy(selected_brushes.next->mins, mins); + VectorCopy(selected_brushes.next->maxs, maxs); + Select_Delete(); + + int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0; + int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2; + + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if + ( + (b->mins[nDim1] > maxs[nDim1] || b->maxs[nDim1] < mins[nDim1]) || + (b->mins[nDim2] > maxs[nDim2] || b->maxs[nDim2] < mins[nDim2]) + ) { + continue; + } + + if (FilterBrush(b)) { + continue; + } + + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + +#if 0 + // old stuff + for (i = 0; i < 2; i++) { + if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i]) { + break; + } + } + + if (i == 2) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } +#endif + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Touching(void) { + brush_t *b, *next; + int i; + idVec3 mins, maxs; + + if (!QE_SingleBrush()) { + return; + } + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy(selected_brushes.next->mins, mins); + VectorCopy(selected_brushes.next->maxs, maxs); + + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if (FilterBrush(b)) { + continue; + } + + for (i = 0; i < 3; i++) { + if (b->mins[i] > maxs[i] + 1 || b->maxs[i] < mins[i] - 1) { + break; + } + } + + if (i == 3) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Inside(void) { + brush_t *b, *next; + int i; + idVec3 mins, maxs; + + if (!QE_SingleBrush()) { + return; + } + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy(selected_brushes.next->mins, mins); + VectorCopy(selected_brushes.next->maxs, maxs); + Select_Delete(); + + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if (FilterBrush(b)) { + continue; + } + + for (i = 0; i < 3; i++) { + if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) { + break; + } + } + + if (i == 3) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Select_Ungroup Turn the currently selected entity back into normal brushes + ======================================================================================================================= + */ +void Select_Ungroup() { + int numselectedgroups; + entity_t *e; + brush_t *b, *sb; + + numselectedgroups = 0; + for (sb = selected_brushes.next; sb != &selected_brushes; sb = sb->next) { + e = sb->owner; + + if (!e || e == world_entity) { + continue; + } + + for (b = e->brushes.onext; b != &e->brushes; b = e->brushes.onext) { + Entity_UnlinkBrush(b); + Entity_LinkBrush(world_entity, b); + Brush_Build(b); + b->owner = world_entity; + } + + Entity_Free(e); + numselectedgroups++; + } + + if (numselectedgroups <= 0) { + Sys_Status("No grouped entities selected.\n"); + return; + } + + common->Printf("Ungrouped %d entit%s.\n", numselectedgroups, (numselectedgroups == 1) ? "y" : "ies"); + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_ShiftTexture(float x, float y, bool autoAdjust) { + brush_t *b; + face_t *f; + + int nFaceCount = g_ptrSelectedFaces.GetSize(); + + if (selected_brushes.next == &selected_brushes && nFaceCount == 0) { + return; + } + + x = -x; + + Undo_Start("Select shift textures"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (f = b->brush_faces; f; f = f->next) { + if (g_qeglobals.m_bBrushPrimitMode) { + // use face normal to compute a true translation + Select_ShiftTexture_BrushPrimit(f, x, y, autoAdjust); + } + else { + f->texdef.shift[0] += x; + f->texdef.shift[1] += y; + } + } + + Brush_Build(b); + if (b->pPatch) { + // Patch_ShiftTexture(b->nPatchID, x, y); + Patch_ShiftTexture(b->pPatch, x, y, autoAdjust); + } + } + + if (nFaceCount > 0) { + for (int i = 0; i < nFaceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + if (g_qeglobals.m_bBrushPrimitMode) { + // + // use face normal to compute a true translation Select_ShiftTexture_BrushPrimit( + // selected_face, x, y ); use camera view to compute texture shift + // + Select_ShiftTexture_BrushPrimit(selFace, x, y, autoAdjust); + } + else { + selFace->texdef.shift[0] += x; + selFace->texdef.shift[1] += y; + } + + Brush_Build(selBrush); + } + } + + Undo_End(); + Sys_UpdateWindows(W_CAMERA); +} + +extern void Face_SetExplicitScale_BrushPrimit(face_t *face, float s, float t); +extern void Face_ScaleTexture_BrushPrimit(face_t *face, float sS, float sT); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_ScaleTexture(float x, float y, bool update, bool absolute) { + brush_t *b; + face_t *f; + + int nFaceCount = g_ptrSelectedFaces.GetSize(); + + if (selected_brushes.next == &selected_brushes && nFaceCount == 0) { + return; + } + + Undo_Start("Select_SetExplicitScale_BrushPrimit"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (f = b->brush_faces; f; f = f->next) { + if (g_qeglobals.m_bBrushPrimitMode && f->face_winding) { + if (absolute) { + Face_SetExplicitScale_BrushPrimit(f, x, y); + } else { + Face_ScaleTexture_BrushPrimit(f, x, y); + } + } + else { + f->texdef.scale[0] += x; + f->texdef.scale[1] += y; + } + } + + Brush_Build(b); + if (b->pPatch) { + Patch_ScaleTexture(b->pPatch, x, y, absolute); + } + } + + if (nFaceCount > 0) { + for (int i = 0; i < nFaceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + if (g_qeglobals.m_bBrushPrimitMode) { + if (absolute) { + Face_SetExplicitScale_BrushPrimit(selFace, x, y); + } else { + Face_ScaleTexture_BrushPrimit(selFace, x, y); + } + } + else { + selFace->texdef.scale[0] += x; + selFace->texdef.scale[1] += y; + } + + Brush_Build(selBrush); + } + } + + Undo_End(); + if (update) { + Sys_UpdateWindows(W_CAMERA); + } +} + +extern void Face_RotateTexture_BrushPrimit(face_t *face, float amount, idVec3 origin); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_RotateTexture(float amt, bool absolute) { + brush_t *b; + face_t *f; + + int nFaceCount = g_ptrSelectedFaces.GetSize(); + + if (selected_brushes.next == &selected_brushes && nFaceCount == 0) { + return; + } + + Undo_Start("Select_RotateTexture_BrushPrimit"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (f = b->brush_faces; f; f = f->next) { + if (g_qeglobals.m_bBrushPrimitMode) { + Face_RotateTexture_BrushPrimit(f, amt, b->owner->origin); + } + else { + f->texdef.rotate += amt; + f->texdef.rotate = static_cast(f->texdef.rotate) % 360; + } + } + + Brush_Build(b); + if (b->pPatch) { + // Patch_RotateTexture(b->nPatchID, amt); + Patch_RotateTexture(b->pPatch, amt); + } + } + + if (nFaceCount > 0) { + for (int i = 0; i < nFaceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + if (g_qeglobals.m_bBrushPrimitMode) { + idVec3 org; + org.Zero(); + //Face_RotateTexture_BrushPrimit(selFace, amt, selBrush->owner->origin); + Face_RotateTexture_BrushPrimit(selFace, amt, org); + } + else { + selFace->texdef.rotate += amt; + selFace->texdef.rotate = static_cast(selFace->texdef.rotate) % 360; + } + + Brush_Build(selBrush); + } + } + + Undo_End(); + Sys_UpdateWindows(W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected, bool bForce) { + brush_t *pList = (bSelected) ? &selected_brushes : &active_brushes; + if (!bSelected) { + Select_Deselect(); + } + + for (brush_t * pBrush = pList->next; pBrush != pList; pBrush = pBrush->next) { + if (pBrush->pPatch) { + Patch_FindReplaceTexture(pBrush, pFind, pReplace, bForce); + } + + for (face_t * pFace = pBrush->brush_faces; pFace; pFace = pFace->next) { + if (bForce || idStr::Icmp(pFace->texdef.name, pFind) == 0 ) { + pFace->d_texture = Texture_ForName(pReplace); + + // strcpy(pFace->texdef.name, pReplace); + pFace->texdef.SetName(pReplace); + } + } + + Brush_Build(pBrush); + } + + Sys_UpdateWindows(W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_AllOfType() { + brush_t *b, *next; + entity_t *e; + if ((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes)) { + CString strName; + if (g_ptrSelectedFaces.GetSize() == 0) { + strName = g_qeglobals.d_texturewin.texdef.name; + } + else { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0)); + strName = selFace->texdef.name; + } + + Select_Deselect(); + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if (FilterBrush(b)) { + continue; + } + + if (b->pPatch) { + if ( idStr::Icmp(strName, b->pPatch->d_texture->GetName()) == 0 ) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + else { + for (face_t * pFace = b->brush_faces; pFace; pFace = pFace->next) { + if ( idStr::Icmp(strName, pFace->texdef.name) == 0 ) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + } + } + + Sys_UpdateWindows(W_ALL); + return; + } + + b = selected_brushes.next; + e = b->owner; + if (e != NULL) { + if (e != world_entity) { + CString strName = e->eclass->name; + idStr strKey, strVal; + bool bCriteria = g_Inspectors->GetSelectAllCriteria(strKey, strVal); + common->Printf("Selecting all %s(s)\n", strName); + Select_Deselect(); + + for (b = active_brushes.next; b != &active_brushes; b = next) { + next = b->next; + + if (FilterBrush(b)) { + continue; + } + + e = b->owner; + if (e != NULL) { + if ( idStr::Icmp(e->eclass->name, strName) == 0 ) { + bool doIt = true; + if (bCriteria) { + CString str = ValueForKey(e, strKey); + if (str.CompareNoCase(strVal) != 0) { + doIt = false; + } + } + + if (doIt) { + Brush_RemoveFromList(b); + Brush_AddToList(b, &selected_brushes); + } + } + } + } + } + } + + + if ( selected_brushes.next && selected_brushes.next->owner ) { + g_Inspectors->UpdateEntitySel( selected_brushes.next->owner->eclass ); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Reselect() { + CPtrArray holdArray; + brush_t *b; + for ( b = selected_brushes.next; b && b != &selected_brushes; b = b->next ) { + holdArray.Add(reinterpret_cast < void * > (b)); + } + + int n = holdArray.GetSize(); + while (n-- > 0) { + b = reinterpret_cast < brush_t * > (holdArray.GetAt(n)); + Select_Brush(b); + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_FitTexture(float height, float width) { + brush_t *b; + int nFaceCount = g_ptrSelectedFaces.GetSize(); + + if (selected_brushes.next == &selected_brushes && nFaceCount == 0) { + return; + } + + Undo_Start("Select_FitTexture"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->pPatch) { + Patch_FitTexture(b->pPatch, width, height); + } + else { + Brush_FitTexture(b, height, width); + Brush_Build(b); + } + } + + if (nFaceCount > 0) { + for (int i = 0; i < nFaceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + Face_FitTexture(selFace, height, width); + Brush_Build(selBrush); + } + } + + Undo_End(); + Sys_UpdateWindows(W_CAMERA); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_AxialTexture() { +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_Hide(bool invert) { + + if (invert) { + for (brush_t * b = active_brushes.next; b && b != &active_brushes; b = b->next) { + b->hiddenBrush = true; + } + } else { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + b->hiddenBrush = true; + } + } + Sys_UpdateWindows(W_ALL); +} + +void Select_WireFrame( bool wireFrame ) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + b->forceWireFrame = wireFrame; + } + Sys_UpdateWindows(W_ALL); +} + +void Select_ForceVisible( bool visible ) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + b->forceVisibile = visible; + } + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_ShowAllHidden() { + brush_t *b; + for (b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + b->hiddenBrush = false; + } + + for (b = active_brushes.next; b && b != &active_brushes; b = b->next) { + b->hiddenBrush = false; + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + Select_Invert + ======================================================================================================================= + */ +void Select_Invert(void) { + brush_t *next, *prev; + + Sys_Status("inverting selection...\n"); + + next = active_brushes.next; + prev = active_brushes.prev; + if (selected_brushes.next != &selected_brushes) { + active_brushes.next = selected_brushes.next; + active_brushes.prev = selected_brushes.prev; + active_brushes.next->prev = &active_brushes; + active_brushes.prev->next = &active_brushes; + } + else { + active_brushes.next = &active_brushes; + active_brushes.prev = &active_brushes; + } + + if (next != &active_brushes) { + selected_brushes.next = next; + selected_brushes.prev = prev; + selected_brushes.next->prev = &selected_brushes; + selected_brushes.prev->next = &selected_brushes; + } + else { + selected_brushes.next = &selected_brushes; + selected_brushes.prev = &selected_brushes; + } + + Sys_UpdateWindows(W_ALL); + + Sys_Status("done.\n"); +} + +/* + ======================================================================================================================= + Select_Name + ======================================================================================================================= + */ +void Select_Name(const char *pName) { + if (g_qeglobals.m_bBrushPrimitMode) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + Brush_SetEpair(b, "Name", pName); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_CenterOrigin() { + idVec3 mid; + + Select_GetTrueMid(mid); + mid.Snap(); + + brush_t *b = selected_brushes.next; + entity_t *e = b->owner; + if (e != NULL) { + if (e != world_entity) { + char text[1024]; + sprintf(text, "%i %i %i", (int)mid[0], (int)mid[1], (int)mid[2]); + SetKeyValue(e, "origin", text); + VectorCopy(mid, e->origin); + } + } + + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int Select_NumSelectedFaces() { + return g_ptrSelectedFaces.GetSize(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +face_t *Select_GetSelectedFace(int index) { + assert(index >= 0 && index < Select_NumSelectedFaces()); + return reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(index)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +brush_t *Select_GetSelectedFaceBrush(int index) { + assert(index >= 0 && index < Select_NumSelectedFaces()); + return reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(index)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_SetDefaultTexture(const idMaterial *mat, bool fitScale, bool setTexture) { + texdef_t tex; + brushprimit_texdef_t brushprimit_tex; + memset(&tex, 0, sizeof(tex)); + memset(&brushprimit_tex, 0, sizeof(brushprimit_tex)); + if (g_qeglobals.m_bBrushPrimitMode) { + // brushprimit fitted to a 2x2 texture + brushprimit_tex.coords[0][0] = 1.0f; + brushprimit_tex.coords[1][1] = 1.0f; + } + else { + tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1; + tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1; + } + + tex.SetName(mat->GetName()); + Texture_SetTexture(&tex, &brushprimit_tex, fitScale, setTexture); + + CString strTex; + strTex.Format + ( + "%s (%s) W: %i H: %i", + mat->GetName(), + mat->GetDescription(), + mat->GetEditorImage()->uploadWidth, + mat->GetEditorImage()->uploadHeight + ); + g_pParentWnd->SetStatusText(3, strTex); +} + + +void Select_UpdateTextureName(const char *name) { + brush_t *b; + int nCount = g_ptrSelectedFaces.GetSize(); + if (nCount > 0) { + Undo_Start("set face texture name"); + ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize()); + for (int i = 0; i < nCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + Undo_AddBrush(selBrush); + selFace->texdef.SetName(name); + Brush_Build(selBrush); + Undo_EndBrush(selBrush); + } + + Undo_End(); + } + else if (selected_brushes.next != &selected_brushes) { + Undo_Start("set brush textures"); + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (!b->owner->eclass->fixedsize) { + Undo_AddBrush(b); + Brush_SetTextureName(b, name); + Undo_EndBrush(b); + } else if (b->owner->eclass->nShowFlags & ECLASS_LIGHT) { + if ( idStr::Cmpn(name, "lights/", strlen("lights/")) == 0 ) { + SetKeyValue(b->owner, "texture", name); + g_Inspectors->UpdateEntitySel(b->owner->eclass); + UpdateLightInspector(); + Brush_Build(b); + } + } + } + + Undo_End(); + } + + Sys_UpdateWindows(W_ALL); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Select_FlipTexture(bool y) { + + int faceCount = g_ptrSelectedFaces.GetSize(); + + Undo_Start("Select_FlipTexture"); + for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) { + if (b->pPatch) { + Patch_FlipTexture(b->pPatch, y); + } else { + Brush_FlipTexture_BrushPrimit(b, y); + } + } + + if (faceCount > 0) { + for (int i = 0; i < faceCount; i++) { + face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i)); + brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i)); + Face_FlipTexture_BrushPrimit(selFace, y); + } + } + + Undo_End(); + Sys_UpdateWindows(W_CAMERA); +} + + + + +/* + ======================================================================================================================= + Select_SetKeyVal + sets values on non-world entities + ======================================================================================================================= + */ +void Select_SetKeyVal(const char *key, const char *val) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + if (b->owner != world_entity) { + SetKeyValue(b->owner, key, val, false); + } + } +} + +/* + ======================================================================================================================= + Select_CopyPatchTextureCoords( patchMesh_t *p ) + ======================================================================================================================= + */ +void Select_CopyPatchTextureCoords( patchMesh_t *p ) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + if (b->pPatch) { + if ( b->pPatch->width <= p->width && b->pPatch->height <= p->height ) { + for ( int i = 0; i < b->pPatch->width; i ++ ) { + for ( int j = 0; j < b->pPatch->height; j++ ) { + b->pPatch->ctrl(i, j).st = p->ctrl(i, j).st; + } + } + } + } + } +} + + +/* + ======================================================================================================================= + Select_SetProjectFaceOntoPatch + ======================================================================================================================= + */ +void Select_ProjectFaceOntoPatch( face_t *face ) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + if (b->pPatch) { + EmitBrushPrimitTextureCoordinates(face, NULL, b->pPatch); + Patch_MakeDirty(b->pPatch); + } + } +} + +/* + ======================================================================================================================= + Select_SetPatchFit + ======================================================================================================================= + */ +extern float Patch_Width(patchMesh_t *p); +extern float Patch_Height(patchMesh_t *p); +void Select_SetPatchFit(float dim1, float dim2, float srcWidth, float srcHeight, float rot) { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + if (b->pPatch) { + float w = Patch_Width(b->pPatch); + float h = Patch_Height(b->pPatch); + Patch_RotateTexture(b->pPatch, -90 + rot); + Patch_FitTexture(b->pPatch, dim1 * (w / srcWidth), dim2 * (h / srcHeight)); + Patch_FlipTexture(b->pPatch, true); + } + } +} + +void Select_SetPatchST(float s1, float t1, float s2, float t2) { +} + + +void Select_AllTargets() { + for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) { + if (b->owner != world_entity) { + const idKeyValue *kv = b->owner->epairs.MatchPrefix("target", NULL); + while (kv) { + entity_t *ent = FindEntity("name", kv->GetValue()); + if (ent) { + Select_Brush(ent->brushes.onext, true, false); + } + kv = b->owner->epairs.MatchPrefix("target", kv); + } + } + } +} \ No newline at end of file diff --git a/tools/radiant/SELECT.H b/tools/radiant/SELECT.H new file mode 100644 index 000000000..227667d5e --- /dev/null +++ b/tools/radiant/SELECT.H @@ -0,0 +1,135 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SELECT_H_ +#define __SELECT_H_ + +typedef enum +{ + sel_brush, + // sel_sticky_brush, + // sel_face, + sel_vertex, + sel_edge, + sel_singlevertex, + sel_curvepoint, + sel_area, + sel_addpoint, // for dropping points + sel_editpoint // for editing points +} select_t; + +class CDragPoint { +public: + idVec3 vec; + brush_t *pBrush; + int nType; + bool priority; + CDragPoint() {}; + CDragPoint(brush_t *b, idVec3 v, int type, bool p) { + pBrush = b; + VectorCopy(v, vec); + nType = type; + priority = p; + } + + void Set(brush_t *b, idVec3 v, int type) { + pBrush = b; + VectorCopy(v, vec); + nType = type; + } + + bool PointWithin(idVec3 p, int nView = -1); +}; + + +typedef struct +{ + brush_t *brush; + face_t *face; + CDragPoint *point; + float dist; + bool selected; +} qertrace_t; + + +#define SF_SELECTED_ONLY 0x01 +#define SF_ENTITIES_FIRST 0x02 +#define SF_SINGLEFACE 0x04 +#define SF_IGNORECURVES 0x08 +#define SF_IGNOREGROUPS 0x10 +#define SF_CYCLE 0x20 + + +qertrace_t Test_Ray ( const idVec3 &origin, const idVec3 &dir, int flags ); +CDragPoint *PointRay( const idVec3 &org, const idVec3 &dir, float *dist); +void SelectCurvePointByRay( const idVec3 &org, const idVec3 &dir, int buttons); +void SelectSplinePointByRay( const idVec3 &org, const idVec3 &dir, int buttons); + +void Select_GetBounds (idVec3 &mins, idVec3 &maxs); +void Select_Brush (brush_t *b, bool bComplete = true, bool bStatus = true); +void Select_Ray (idVec3 origin, idVec3 dir, int flags); +void Select_Delete (void); +void Select_Deselect (bool bDeselectFaces = true); +void Select_Invert(void); +void Select_Clone (void); +void Select_Move (idVec3 delta, bool bSnap = true); +void WINAPI Select_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale = false, void* pPlugTexdef = NULL, bool update = true); +void Select_FlipAxis (int axis); +void Select_RotateAxis (int axis, float deg, bool bPaint = true, bool bMouse = false); +void Select_CompleteTall (void); +void Select_PartialTall (void); +void Select_Touching (void); +void Select_Inside (void); +void Select_CenterOrigin(); +void Select_AllOfType(); +void Select_Reselect(); +void Select_FitTexture(float height = 1.0, float width = 1.0); +void Select_InitializeRotation(); +void Select_FinalizeRotation(); + +// absolute texture coordinates +// TTimo NOTE: this is stuff for old brushes format and rotation texture lock .. sort of in-between with bush primitives +void ComputeAbsolute(face_t* f, idVec3& p1, idVec3& p2, idVec3& p3); +void AbsoluteToLocal( const idPlane &normal2, face_t* f, idVec3& p1, idVec3& p2, idVec3& p3); +void Select_Hide(bool invert = false); +void Select_ShowAllHidden(); +void Select_WireFrame( bool wireFrame ); +void Select_ForceVisible( bool visible ); +void Select_Name(const char *pName); +void Select_AddProjectedLight(); +void Select_GetMid (idVec3 &mid); +void Select_SetDefaultTexture(const idMaterial *mat, bool fitScale, bool setTexture); +void Select_UpdateTextureName(const char *name); + +void Select_FlipTexture(bool y); +void Select_SetPatchFit(float dim1, float dim2, float srcWidth, float srcHeight, float rot); +void Select_SetPatchST(float s1, float t1, float s2, float t2); +void Select_ProjectFaceOntoPatch( face_t *face ); +void Select_CopyPatchTextureCoords( patchMesh_t *p ); +void Select_AllTargets(); +void Select_Scale(float x, float y, float z); +void Select_RotateTexture(float amt, bool absolute = false); +void Select_ScaleTexture(float x, float y, bool update = true, bool absolute = true); +void Select_DefaultTextureScale(bool horz, bool vert, bool update = true); +void Select_ShiftTexture(float x, float y, bool autoAdjust = false); +void Select_GetTrueMid (idVec3 &mid); +void Select_Scale(float x, float y, float z); + + +#endif \ No newline at end of file diff --git a/tools/radiant/ScaleDialog.cpp b/tools/radiant/ScaleDialog.cpp new file mode 100644 index 000000000..bc58c4e2d --- /dev/null +++ b/tools/radiant/ScaleDialog.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "ScaleDialog.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CScaleDialog dialog + + +CScaleDialog::CScaleDialog(CWnd* pParent /*=NULL*/) + : CDialog(CScaleDialog::IDD, pParent) +{ + //{{AFX_DATA_INIT(CScaleDialog) + m_fZ = 1.0f; + m_fX = 1.0f; + m_fY = 1.0f; + //}}AFX_DATA_INIT +} + + +void CScaleDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CScaleDialog) + DDX_Text(pDX, IDC_EDIT_Z, m_fZ); + DDX_Text(pDX, IDC_EDIT_X, m_fX); + DDX_Text(pDX, IDC_EDIT_Y, m_fY); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CScaleDialog, CDialog) + //{{AFX_MSG_MAP(CScaleDialog) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CScaleDialog message handlers diff --git a/tools/radiant/ScaleDialog.h b/tools/radiant/ScaleDialog.h new file mode 100644 index 000000000..a8b4a2cb6 --- /dev/null +++ b/tools/radiant/ScaleDialog.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_SCALEDIALOG_H__8A9B33B2_9922_11D1_B568_00AA00A410FC__INCLUDED_) +#define AFX_SCALEDIALOG_H__8A9B33B2_9922_11D1_B568_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// ScaleDialog.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CScaleDialog dialog + +class CScaleDialog : public CDialog +{ +// Construction +public: + CScaleDialog(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CScaleDialog) + enum { IDD = IDD_DIALOG_SCALE }; + float m_fZ; + float m_fX; + float m_fY; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CScaleDialog) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CScaleDialog) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SCALEDIALOG_H__8A9B33B2_9922_11D1_B568_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/SurfaceDlg.cpp b/tools/radiant/SurfaceDlg.cpp new file mode 100644 index 000000000..7d8d18e6d --- /dev/null +++ b/tools/radiant/SurfaceDlg.cpp @@ -0,0 +1,620 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "SurfaceDlg.h" +#include "mainfrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSurfaceDlg dialog + +CSurfaceDlg g_dlgSurface; + + +CSurfaceDlg::CSurfaceDlg(CWnd* pParent /*=NULL*/) + : CDialog(CSurfaceDlg::IDD, pParent) { + //{{AFX_DATA_INIT(CSurfaceDlg) + m_nHorz = 3; + m_nVert = 3; + m_horzScale = 1.0f; + m_horzShift = 0.5f; + m_rotate = 15.0f; + m_vertScale = 1.0f; + m_vertShift = 0.5f; + m_strMaterial = _T(""); + m_subdivide = FALSE; + m_fHeight = 1.0f; + m_fWidth = 1.0f; + m_absolute = FALSE; + //}}AFX_DATA_INIT +} + + +void CSurfaceDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSurfaceDlg) + DDX_Control(pDX, IDC_ROTATE, m_wndRotateEdit); + DDX_Control(pDX, IDC_EDIT_VERT, m_wndVert); + DDX_Control(pDX, IDC_EDIT_HORZ, m_wndHorz); + DDX_Control(pDX, IDC_SLIDER_VERT, m_wndVerticalSubdivisions); + DDX_Control(pDX, IDC_SLIDER_HORZ, m_wndHorzSubdivisions); + DDX_Control(pDX, IDC_SPIN_WIDTH, m_wndWidth); + DDX_Control(pDX, IDC_SPIN_HEIGHT, m_wndHeight); + DDX_Control(pDX, IDC_SPIN_VSHIFT, m_wndVShift); + DDX_Control(pDX, IDC_SPIN_ROTATE, m_wndRotate); + DDX_Control(pDX, IDC_SPIN_HSHIFT, m_wndHShift); + DDX_Text(pDX, IDC_EDIT_HORZ, m_nHorz); + DDV_MinMaxInt(pDX, m_nHorz, 1, 64); + DDX_Text(pDX, IDC_EDIT_VERT, m_nVert); + DDV_MinMaxInt(pDX, m_nVert, 1, 64); + DDX_Text(pDX, IDC_HSCALE, m_horzScale); + DDX_Text(pDX, IDC_HSHIFT, m_horzShift); + DDX_Text(pDX, IDC_ROTATE, m_rotate); + DDX_Text(pDX, IDC_VSCALE, m_vertScale); + DDX_Text(pDX, IDC_VSHIFT, m_vertShift); + DDX_Text(pDX, IDC_TEXTURE, m_strMaterial); + DDX_Check(pDX, IDC_CHECK_SUBDIVIDE, m_subdivide); + DDX_Text(pDX, IDC_EDIT_HEIGHT, m_fHeight); + DDX_Text(pDX, IDC_EDIT_WIDTH, m_fWidth); + DDX_Check(pDX, IDC_CHECK_ABSOLUTE, m_absolute); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSurfaceDlg, CDialog) + //{{AFX_MSG_MAP(CSurfaceDlg) + ON_WM_HSCROLL() + ON_WM_KEYDOWN() + ON_WM_VSCROLL() + ON_WM_CLOSE() + ON_WM_DESTROY() + ON_BN_CLICKED(IDCANCEL, OnBtnCancel) + ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor) + ON_WM_CTLCOLOR() + ON_WM_CREATE() + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSHIFT, OnDeltaPosSpin) + ON_BN_CLICKED(IDC_BTN_PATCHDETAILS, OnBtnPatchdetails) + ON_BN_CLICKED(IDC_BTN_PATCHNATURAL, OnBtnPatchnatural) + ON_BN_CLICKED(IDC_BTN_PATCHRESET, OnBtnPatchreset) + ON_BN_CLICKED(IDC_BTN_AXIAL, OnBtnAxial) + ON_BN_CLICKED(IDC_BTN_BRUSHFIT, OnBtnBrushfit) + ON_BN_CLICKED(IDC_BTN_FACEFIT, OnBtnFacefit) + ON_BN_CLICKED(IDC_CHECK_SUBDIVIDE, OnCheckSubdivide) + ON_EN_CHANGE(IDC_EDIT_HORZ, OnChangeEditHorz) + ON_EN_CHANGE(IDC_EDIT_VERT, OnChangeEditVert) + ON_EN_SETFOCUS(IDC_HSCALE, OnSetfocusHscale) + ON_EN_KILLFOCUS(IDC_HSCALE, OnKillfocusHscale) + ON_EN_KILLFOCUS(IDC_VSCALE, OnKillfocusVscale) + ON_EN_SETFOCUS(IDC_VSCALE, OnSetfocusVscale) + ON_EN_KILLFOCUS(IDC_EDIT_WIDTH, OnKillfocusEditWidth) + ON_EN_SETFOCUS(IDC_EDIT_WIDTH, OnSetfocusEditWidth) + ON_EN_KILLFOCUS(IDC_EDIT_HEIGHT, OnKillfocusEditHeight) + ON_EN_SETFOCUS(IDC_EDIT_HEIGHT, OnSetfocusEditHeight) + ON_BN_CLICKED(IDC_BTN_FLIPX, OnBtnFlipx) + ON_BN_CLICKED(IDC_BTN_FLIPY, OnBtnFlipy) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ROTATE, OnDeltaPosSpin) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSHIFT, OnDeltaPosSpin) + ON_EN_KILLFOCUS(IDC_ROTATE, OnKillfocusRotate) + ON_EN_SETFOCUS(IDC_ROTATE, OnSetfocusRotate) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSurfaceDlg message handlers + + +/* +=================================================== + + SURFACE INSPECTOR + +=================================================== +*/ + +texdef_t g_old_texdef; +texdef_t g_patch_texdef; +HWND g_surfwin = NULL; +bool g_changed_surface; + +/* +============== +SetTexMods + +Set the fields to the current texdef +if one face selected -> will read this face texdef, else current texdef +if only patches selected, will read the patch texdef +=============== +*/ +extern void Face_GetScale_BrushPrimit(face_t *face, float *s, float *t, float *rot); +void CSurfaceDlg::SetTexMods() { + UpdateData(TRUE); + m_strMaterial = g_qeglobals.d_texturewin.texdef.name; + patchMesh_t *p = SinglePatchSelected(); + if (p) { + m_subdivide = p->explicitSubdivisions; + m_strMaterial = p->d_texture->GetName(); + } else { + m_subdivide = false; + } + + int faceCount = g_ptrSelectedFaces.GetSize(); + face_t *selFace = NULL; + if (faceCount) { + selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0)); + } else { + if (selected_brushes.next != &selected_brushes) { + brush_t *b = selected_brushes.next; + if (!b->pPatch) { + selFace = b->brush_faces; + } + } + } + + if (selFace) { + float rot; + Face_GetScale_BrushPrimit(selFace, &m_horzScale, &m_vertScale, &rot); + } else { + m_horzScale = 1.0f; + m_vertScale = 1.0f; + } + + UpdateData(FALSE); +} + + +bool g_bNewFace = false; +bool g_bNewApplyHandling = false; +bool g_bGatewayhack = false; + + +/* +================= +UpdateSpinners +================= +*/ + +void CSurfaceDlg::UpdateSpinners(bool up, int nID) { + UpdateData(TRUE); + float hdiv = 0.0f; + float vdiv = 0.0f; + switch (nID) { + case IDC_SPIN_ROTATE : + Select_RotateTexture((up) ? m_rotate : -m_rotate); + break; + case IDC_SPIN_HSCALE : + m_horzScale += (up) ? 0.1f : -0.1f; + hdiv = (m_horzScale == 0.0f) ? 1.0f : m_horzScale; + Select_ScaleTexture( 1.0f / hdiv, 0.0f, true, ( m_absolute != FALSE ) ); + UpdateData(FALSE); + break; + case IDC_SPIN_VSCALE : + m_vertScale += (up) ? 0.1f : -0.1f; + vdiv = (m_vertScale == 0.0f) ? 1.0f : m_vertScale; + Select_ScaleTexture( 0.0f, 1.0f / vdiv, true, ( m_absolute != FALSE ) ); + UpdateData(FALSE); + break; + case IDC_SPIN_HSHIFT : + Select_ShiftTexture((up) ? m_horzShift : -m_horzShift, 0); + break; + case IDC_SPIN_VSHIFT : + Select_ShiftTexture(0, (up) ? m_vertShift : -m_vertShift); + break; + } + g_changed_surface = true; +} + +void CSurfaceDlg::UpdateSpinners(int nScrollCode, int nPos, CScrollBar* pBar) { + + return; + UpdateData(TRUE); + if ((nScrollCode != SB_LINEUP) && (nScrollCode != SB_LINEDOWN)) { + return; + } + + bool up = (nScrollCode == SB_LINEUP); + +// FIXME: bad resource define +#define IDC_ROTATEA 0 +#define IDC_HSCALEA 0 +#define IDC_VSCALEA 0 +#define IDC_HSHIFTA 0 +#define IDC_VSHIFTA 0 + + if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_ROTATEA)) { + Select_RotateTexture((up) ? m_rotate : -m_rotate); + } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSCALEA)) { + Select_ScaleTexture((up) ? -m_horzScale : m_horzScale, 0, true, ( m_absolute != FALSE ) ); + } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSCALEA)) { + Select_ScaleTexture(0, (up) ? -m_vertScale : m_vertScale, true, ( m_absolute != FALSE ) ); + } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSHIFTA)) { + Select_ShiftTexture((up) ? -m_horzShift : m_horzShift, 0); + } else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSHIFTA)) { + Select_ShiftTexture((up) ? -m_vertShift : m_vertShift, 0); + } + + g_changed_surface = true; +} + +void UpdateSurfaceDialog() { + if (g_surfwin) { + g_dlgSurface.SetTexMods(); + } + g_pParentWnd->UpdateTextureBar(); +} + +bool ByeByeSurfaceDialog(); + +void DoSurface (void) { + + g_bNewFace = ( g_PrefsDlg.m_bFace != FALSE ); + g_bNewApplyHandling = ( g_PrefsDlg.m_bNewApplyHandling != FALSE ); + g_bGatewayhack = ( g_PrefsDlg.m_bGatewayHack != FALSE ); + // save current state for cancel + g_old_texdef = g_qeglobals.d_texturewin.texdef; + g_changed_surface = false; + + if (g_surfwin == NULL && g_dlgSurface.GetSafeHwnd() == NULL) { + g_patch_texdef.scale[0] = 0.05f; + g_patch_texdef.scale[1] = 0.05f; + g_patch_texdef.shift[0] = 0.05f; + g_patch_texdef.shift[1] = 0.05f; + // use rotation increment from preferences + g_patch_texdef.rotate = g_PrefsDlg.m_nRotation; + + g_dlgSurface.Create(IDD_SURFACE); + CRect rct; + LONG lSize = sizeof(rct); + if (LoadRegistryInfo("radiant_SurfaceWindow", &rct, &lSize)) { + g_dlgSurface.SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW ); + } + g_dlgSurface.ShowWindow(SW_SHOW); + Sys_UpdateWindows(W_ALL); + } else { + g_surfwin = g_dlgSurface.GetSafeHwnd(); + g_dlgSurface.SetTexMods (); + g_dlgSurface.ShowWindow(SW_SHOW); + } +} + +bool ByeByeSurfaceDialog() { + if (g_surfwin) { + if (g_bGatewayhack) { + PostMessage(g_surfwin, WM_COMMAND, IDC_APPLY, 0); + } else { + PostMessage(g_surfwin, WM_COMMAND, IDCANCEL, 0); + } + return true; + } else { + return false; + } +} + +BOOL CSurfaceDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + g_surfwin = GetSafeHwnd(); + SetTexMods (); + + //m_wndHScale.SetRange(0, 100); + //m_wndVScale.SetRange(0, 100); + m_wndHShift.SetRange(0, 100); + m_wndVShift.SetRange(0, 100); + m_wndRotate.SetRange(0, 100); + m_wndWidth.SetRange(1, 32); + m_wndHeight.SetRange(1, 32); + + m_wndVerticalSubdivisions.SetRange(1, 32); + m_wndVerticalSubdivisions.SetBuddy(&m_wndVert, FALSE); + m_wndHorzSubdivisions.SetRange(1, 32); + m_wndHorzSubdivisions.SetBuddy(&m_wndHorz, FALSE); + m_wndVerticalSubdivisions.SetPos(m_nVert); + m_wndHorzSubdivisions.SetPos(m_nHorz); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CSurfaceDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { + UpdateData(TRUE); + if (pScrollBar->IsKindOf(RUNTIME_CLASS(CSliderCtrl))) { + CSliderCtrl *ctrl = reinterpret_cast(pScrollBar); + assert(ctrl); + if (ctrl == &m_wndVerticalSubdivisions) { + m_nVert = ctrl->GetPos(); + } else { + m_nHorz = ctrl->GetPos(); + } + UpdateData(FALSE); + + if (m_subdivide) { + Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert ); + } + } + Sys_UpdateWindows(W_CAMERA | W_XY); +} + +void CSurfaceDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + + CDialog::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CSurfaceDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { + //UpdateSpinners(nSBCode, nPos, pScrollBar); + //Sys_UpdateWindows(W_CAMERA); +} + + +void CSurfaceDlg::OnOK() { + //GetTexMods(); + UpdateData(TRUE); + if (m_strMaterial.Find(":") >= 0) { + const idMaterial *mat = declManager->FindMaterial(m_strMaterial); + Select_UpdateTextureName(m_strMaterial); + } + g_surfwin = NULL; + CDialog::OnOK(); + Sys_UpdateWindows(W_ALL); +} + +void CSurfaceDlg::OnClose() { + g_surfwin = NULL; + CDialog::OnClose(); +} + +void CSurfaceDlg::OnCancel() { + if (g_bGatewayhack) { + OnOK(); + } else { + OnBtnCancel(); + } +} + +void CSurfaceDlg::OnDestroy() { + if (GetSafeHwnd()) { + CRect rct; + GetWindowRect(rct); + SaveRegistryInfo("radiant_SurfaceWindow", &rct, sizeof(rct)); + } + CDialog::OnDestroy(); + g_surfwin = NULL; + Sys_UpdateWindows(W_ALL); +} + +void CSurfaceDlg::OnBtnCancel() { + g_qeglobals.d_texturewin.texdef = g_old_texdef; + if (g_changed_surface) { + //++timo if !g_qeglobals.m_bBrushPrimitMode send a NULL brushprimit_texdef + if (!g_qeglobals.m_bBrushPrimitMode) { + common->Printf("Warning : non brush primitive mode call to CSurfaceDlg::GetTexMods broken\n"); + common->Printf(" ( Select_SetTexture not called )\n"); + } + // Select_SetTexture(&g_qeglobals.d_texturewin.texdef); + } + g_surfwin = NULL; + DestroyWindow(); +} + +void CSurfaceDlg::OnBtnColor() { +} + +HBRUSH CSurfaceDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { + HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); + return hbr; +} + +int CSurfaceDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CDialog::OnCreate(lpCreateStruct) == -1) + return -1; + + return 0; +} + +BOOL CSurfaceDlg::PreCreateWindow(CREATESTRUCT& cs) { + // TODO: Add your specialized code here and/or call the base class + + return CDialog::PreCreateWindow(cs); +} + + +void CSurfaceDlg::OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult) { + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + UpdateSpinners((pNMUpDown->iDelta > 0), pNMUpDown->hdr.idFrom); + *pResult = 0; +} + +void CSurfaceDlg::OnBtnPatchdetails() { + Patch_NaturalizeSelected(true); + g_pParentWnd->GetCamera()->MarkWorldDirty (); + Sys_UpdateWindows(W_ALL); +} + +void CSurfaceDlg::OnBtnPatchnatural() { + Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false); + Patch_NaturalizeSelected(); + g_pParentWnd->GetCamera()->MarkWorldDirty (); + g_changed_surface = true; + Sys_UpdateWindows(W_ALL); +} + +void CSurfaceDlg::OnBtnPatchreset() { + //CTextureLayout dlg; + //if (dlg.DoModal() == IDOK) { + // Patch_ResetTexturing(dlg.m_fX, dlg.m_fY); + //} + //Sys_UpdateWindows(W_ALL); +} + +void CSurfaceDlg::OnBtnAxial() { +} + +void CSurfaceDlg::OnBtnBrushfit() { + // TODO: Add your control notification handler code here + +} + +void CSurfaceDlg::OnBtnFacefit() { + UpdateData(TRUE); +/* + brush_t *b; + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) { + if (!b->patchBrush) { + for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next) { + g_ptrSelectedFaces.Add(pFace); + g_ptrSelectedFaceBrushes.Add(b); + } + } + } +*/ + Select_FitTexture(m_fHeight, m_fWidth); + g_pParentWnd->GetCamera()->MarkWorldDirty (); + //SetTexMods(); + g_changed_surface = true; + Sys_UpdateWindows(W_ALL); +} + + +void CSurfaceDlg::OnCheckSubdivide() { + UpdateData( TRUE ); + // turn any patches in explicit subdivides + Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert ); + g_pParentWnd->GetCamera()->MarkWorldDirty (); + Sys_UpdateWindows( W_CAMERA | W_XY ); +} + +void CSurfaceDlg::OnChangeEditHorz() +{ + // TODO: If this is a RICHEDIT control, the control will not + // send this notification unless you override the CDialog::OnInitDialog() + // function and call CRichEditCtrl().SetEventMask() + // with the ENM_CHANGE flag ORed into the mask. + + // TODO: Add your control notification handler code here + UpdateData(TRUE); + // turn any patches in explicit subdivides + Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert ); + Sys_UpdateWindows(W_CAMERA | W_XY); + +} + +void CSurfaceDlg::OnChangeEditVert() +{ + // TODO: If this is a RICHEDIT control, the control will not + // send this notification unless you override the CDialog::OnInitDialog() + // function and call CRichEditCtrl().SetEventMask() + // with the ENM_CHANGE flag ORed into the mask. + + // TODO: Add your control notification handler code here + UpdateData(TRUE); + // turn any patches in explicit subdivides + Patch_SubdivideSelected( ( m_subdivide != FALSE ), m_nHorz, m_nVert ); + Sys_UpdateWindows(W_CAMERA | W_XY); + +} + +BOOL CSurfaceDlg::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_RETURN) { + if (focusControl) { + UpdateData(TRUE); + if (focusControl == &m_wndHScale) { + Select_ScaleTexture( m_horzScale, 1.0f, true, ( m_absolute != FALSE ) ); + } else if (focusControl == &m_wndVScale) { + Select_ScaleTexture( 1.0f, m_vertScale, true, ( m_absolute != FALSE ) ); + } else if (focusControl == &m_wndRotateEdit) { + Select_RotateTexture( m_rotate, true ); + } else if (focusControl == &m_wndHeight || focusControl == &m_wndWidth) { + Select_FitTexture( m_fHeight, m_fWidth ); + } + } + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +void CSurfaceDlg::OnSetfocusHscale() +{ + focusControl = &m_wndHScale; +} + +void CSurfaceDlg::OnKillfocusHscale() +{ + focusControl = NULL; +} + +void CSurfaceDlg::OnKillfocusVscale() +{ + focusControl = NULL; +} + +void CSurfaceDlg::OnSetfocusVscale() +{ + focusControl = &m_wndVScale; +} + +void CSurfaceDlg::OnKillfocusEditWidth() +{ + focusControl = NULL; +} + +void CSurfaceDlg::OnSetfocusEditWidth() +{ + focusControl = &m_wndWidth; +} + +void CSurfaceDlg::OnKillfocusEditHeight() +{ + focusControl = NULL; +} + +void CSurfaceDlg::OnSetfocusEditHeight() +{ + focusControl = &m_wndHeight; +} + +void CSurfaceDlg::OnBtnFlipx() +{ + Select_FlipTexture(false); +} + +void CSurfaceDlg::OnBtnFlipy() +{ + Select_FlipTexture(true); +} + +void CSurfaceDlg::OnKillfocusRotate() +{ + focusControl = NULL; +} + +void CSurfaceDlg::OnSetfocusRotate() +{ + focusControl = &m_wndRotateEdit; +} diff --git a/tools/radiant/SurfaceDlg.h b/tools/radiant/SurfaceDlg.h new file mode 100644 index 000000000..7bd4797ba --- /dev/null +++ b/tools/radiant/SurfaceDlg.h @@ -0,0 +1,130 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_SURFACEDLG_H__D84E0C22_9EEA_11D1_B570_00AA00A410FC__INCLUDED_) +#define AFX_SURFACEDLG_H__D84E0C22_9EEA_11D1_B570_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// SurfaceDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSurfaceDlg dialog + +class CSurfaceDlg : public CDialog +{ + bool m_bPatchMode; + CWnd *focusControl; + + // Construction +public: + CSurfaceDlg(CWnd* pParent = NULL); // standard constructor + void SetTexMods(); + +// Dialog Data + //{{AFX_DATA(CSurfaceDlg) + enum { IDD = IDD_SURFACE }; + CEdit m_wndRotateEdit; + CEdit m_wndVert; + CEdit m_wndHorz; + CSliderCtrl m_wndVerticalSubdivisions; + CSliderCtrl m_wndHorzSubdivisions; + CSpinButtonCtrl m_wndWidth; + CSpinButtonCtrl m_wndHeight; + CSpinButtonCtrl m_wndVShift; + CSpinButtonCtrl m_wndVScale; + CSpinButtonCtrl m_wndRotate; + CSpinButtonCtrl m_wndHShift; + CSpinButtonCtrl m_wndHScale; + int m_nHorz; + int m_nVert; + float m_horzScale; + float m_horzShift; + float m_rotate; + float m_vertScale; + float m_vertShift; + CString m_strMaterial; + BOOL m_subdivide; + float m_fHeight; + float m_fWidth; + BOOL m_absolute; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSurfaceDlg) + public: + virtual BOOL PreTranslateMessage(MSG* pMsg); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +protected: + + void UpdateSpinners(int nScrollCode, int nPos, CScrollBar* pBar); + void UpdateSpinners(bool bUp, int nID); + // Generated message map functions + //{{AFX_MSG(CSurfaceDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnApply(); + virtual void OnOK(); + afx_msg void OnClose(); + virtual void OnCancel(); + afx_msg void OnDestroy(); + afx_msg void OnBtnCancel(); + afx_msg void OnBtnColor(); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnBtnPatchdetails(); + afx_msg void OnBtnPatchnatural(); + afx_msg void OnBtnPatchreset(); + afx_msg void OnBtnAxial(); + afx_msg void OnBtnBrushfit(); + afx_msg void OnBtnFacefit(); + afx_msg void OnCheckSubdivide(); + afx_msg void OnChangeEditHorz(); + afx_msg void OnChangeEditVert(); + afx_msg void OnSetfocusHscale(); + afx_msg void OnKillfocusHscale(); + afx_msg void OnKillfocusVscale(); + afx_msg void OnSetfocusVscale(); + afx_msg void OnKillfocusEditWidth(); + afx_msg void OnSetfocusEditWidth(); + afx_msg void OnKillfocusEditHeight(); + afx_msg void OnSetfocusEditHeight(); + afx_msg void OnBtnFlipx(); + afx_msg void OnBtnFlipy(); + afx_msg void OnKillfocusRotate(); + afx_msg void OnSetfocusRotate(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SURFACEDLG_H__D84E0C22_9EEA_11D1_B570_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/TabsDlg.cpp b/tools/radiant/TabsDlg.cpp new file mode 100644 index 000000000..bb6be6e2b --- /dev/null +++ b/tools/radiant/TabsDlg.cpp @@ -0,0 +1,343 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "QE3.H" +#include "TabsDlg.h" +// CTabsDlg dialog + +//IMPLEMENT_DYNAMIC ( CTabsDlg , CDialog ) +CTabsDlg::CTabsDlg(UINT ID , CWnd* pParent /*=NULL*/) + : CDialog(ID, pParent) +{ + m_DragTabActive = false; +} + +BEGIN_MESSAGE_MAP(CTabsDlg, CDialog) + //}}AFX_MSG_MAP +// ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1) +ON_WM_LBUTTONDOWN() +ON_WM_LBUTTONUP() +ON_WM_MOUSEMOVE() +ON_WM_DESTROY() +END_MESSAGE_MAP() + +void CTabsDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TAB_INSPECTOR, m_Tabs); +} + +// CTabsDlg message handlers + +BOOL CTabsDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CTabsDlg::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult) +{ + int ID = TabCtrl_GetCurSel ( pNMHDR->hwndFrom ); + + if ( ID >= 0 ) + { + TCITEM item; + item.mask = TCIF_PARAM; + + ShowAllWindows ( FALSE ); + TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , ID , &item); + + DockedWindowInfo* info = (DockedWindowInfo*)item.lParam; + ASSERT ( info ); + + info->m_TabControlIndex = ID; + info->m_Window->ShowWindow(TRUE); + } +} + +void CTabsDlg::DockWindow ( int ID , bool dock ) +{ + DockedWindowInfo* info = NULL; + m_Windows.Lookup ( (WORD)ID , (void*&)info ); + + ASSERT ( info ); + ASSERT ( m_Tabs.GetSafeHwnd() ); + + ShowAllWindows ( FALSE ); + + if ( !dock ) + { + //make a containing window and assign the dialog to it + CRect rect; + CString classname = AfxRegisterWndClass ( CS_DBLCLKS , 0 , 0 , 0 ); + info->m_State = DockedWindowInfo::FLOATING; + + info->m_Window->GetWindowRect(rect); + info->m_Container.CreateEx ( WS_EX_TOOLWINDOW , classname , info->m_Title , WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_CAPTION, rect , this , 0 ); + info->m_Window->SetParent ( &info->m_Container ); + info->m_Window->ShowWindow(TRUE); + + info->m_Container.SetDockManager(this); + info->m_Container.ShowWindow(TRUE); + info->m_Container.SetDialog ( info->m_Window , info->m_ID ); + + if (info->m_TabControlIndex >= 0 ) + { + m_Tabs.DeleteItem( info->m_TabControlIndex ); + } + + if ( m_Tabs.GetItemCount() > 0 ) + { + m_Tabs.SetCurFocus( 0 ); + } + + CString placementName = info->m_Title + "Placement"; + LoadWindowPlacement(info->m_Container , placementName); + } + else + { + info->m_State = DockedWindowInfo::DOCKED; + + info->m_TabControlIndex = m_Tabs.InsertItem( TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM , 0 , info->m_Title , info->m_ImageID , (LPARAM)info); + + info->m_Window->SetParent ( this ); + info->m_Window->ShowWindow (TRUE); + + info->m_Container.SetDockManager( NULL ); //so it doesn't try to call back and redock this window + info->m_Container.DestroyWindow (); + + CRect rect; + GetWindowRect ( rect ); + + //stupid hack to get the window reitself properly + rect.DeflateRect(0,0,0,1); + MoveWindow(rect); + rect.InflateRect(0,0,0,1); + MoveWindow(rect); + } + + UpdateTabControlIndices (); + FocusWindow ( ID ); + + if ( info->m_DockCallback ) + { + info->m_DockCallback ( dock , info->m_ID , info->m_Window ); + } + SaveWindowPlacement (); +} + +int CTabsDlg::PreTranslateMessage ( MSG* msg ) +{ + if ( msg->message == WM_LBUTTONDBLCLK && msg->hwnd == m_Tabs.GetSafeHwnd() ) + { + HandleUndock (); + return TRUE; + } + + //steal lbutton clicks for the main dialog too, but let the tabs do their default thing as well + if ( msg->message == WM_LBUTTONDOWN && msg->hwnd == m_Tabs.GetSafeHwnd()) { + m_Tabs.SendMessage ( msg->message , msg->wParam , msg->lParam ); + m_DragTabActive = true; + } + else if ( msg->message == WM_LBUTTONUP && msg->hwnd == m_Tabs.GetSafeHwnd()) { + m_Tabs.SendMessage ( msg->message , msg->wParam , msg->lParam ); + m_DragTabActive = false; + } + + return CDialog::PreTranslateMessage(msg); +} + +bool CTabsDlg::RectWithinDockManager ( CRect& rect ) +{ + CRect tabsRect,intersectionRect; + + m_Tabs.GetWindowRect ( tabsRect ); + intersectionRect.IntersectRect( tabsRect , rect ); + + return !(intersectionRect.IsRectEmpty()); +} + +void CTabsDlg::OnLButtonDown(UINT nFlags, CPoint point) +{ + CDialog::OnLButtonDown(nFlags, point); +} + +void CTabsDlg::OnLButtonUp(UINT nFlags, CPoint point) +{ + if ( m_DragTabActive && ((abs ( point.x - m_DragDownPoint.x ) > 50) || (abs ( point.y - m_DragDownPoint.y ) > 50))) + { + HandleUndock(); + m_DragTabActive = false; + } + CDialog::OnLButtonUp(nFlags, point); +} + + +void CTabsDlg::HandleUndock () +{ + TCITEM item; + item.mask = TCIF_PARAM; + + int curSel = TabCtrl_GetCurSel ( m_Tabs.GetSafeHwnd()); + + TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , curSel , &item); + + DockedWindowInfo* info = (DockedWindowInfo*)item.lParam; + ASSERT ( info ); + + DockWindow ( info->m_ID , false ); +} + +void CTabsDlg::OnMouseMove(UINT nFlags, CPoint point) +{ + CDialog::OnMouseMove(nFlags, point); +} + + +void CTabsDlg::AddDockedWindow ( CWnd* wnd , int ID , int imageID , const CString& title , bool dock , pfnOnDockEvent dockCallback ) +{ + DockedWindowInfo* info = NULL; + m_Windows.Lookup( (WORD)ID , (void*&)info); + + ASSERT ( wnd ); + ASSERT ( info == NULL ); + + info = new DockedWindowInfo ( wnd , ID , imageID , title , dockCallback); + + m_Windows.SetAt ( (WORD)ID , info ); + DockWindow ( ID , dock ); + + UpdateTabControlIndices (); +} + +void CTabsDlg::ShowAllWindows ( bool show ) +{ + POSITION pos; + WORD ID; + DockedWindowInfo* info = NULL; + for( pos = m_Windows.GetStartPosition(); pos != NULL ; ) + { + m_Windows.GetNextAssoc( pos, ID, (void*&)info ); + ASSERT ( info->m_Window ); + if ( info->m_State == DockedWindowInfo::DOCKED ) + { + info->m_Window->ShowWindow( show ); + } + } +} + +void CTabsDlg::FocusWindow ( int ID ) +{ + DockedWindowInfo* info = NULL; + m_Windows.Lookup( (WORD)ID , (void*&)info); + + ASSERT ( info ); + ASSERT ( info->m_Window ); + + if ( info->m_State == DockedWindowInfo::DOCKED ) + { + TabCtrl_SetCurFocus ( m_Tabs.GetSafeHwnd() , info->m_TabControlIndex ); + } + else + { + info->m_Container.SetFocus(); + } +} + +void CTabsDlg::UpdateTabControlIndices () +{ + TCITEM item; + item.mask = TCIF_PARAM; + + DockedWindowInfo* info = NULL; + int itemCount = m_Tabs.GetItemCount(); + + for ( int i = 0 ; i < itemCount ; i ++ ) + { + if ( !m_Tabs.GetItem( i , &item ) ) + { + Sys_Error ( "UpdateTabControlIndices(): GetItem failed!\n" ); + } + info = (DockedWindowInfo*)item.lParam; + + info->m_TabControlIndex = i; + } +} +void CTabsDlg::OnDestroy() +{ + TCITEM item; + item.mask = TCIF_PARAM; + + DockedWindowInfo* info = NULL; + + for ( int i = 0 ; i < m_Tabs.GetItemCount() ; i ++ ) + { + m_Tabs.GetItem( i , &item ); + info = (DockedWindowInfo*)item.lParam; + ASSERT( info ); + + delete info; + } + CDialog::OnDestroy(); +} + + +bool CTabsDlg::IsDocked ( CWnd* wnd ) +{ + bool docked = false; + DockedWindowInfo* info = NULL; + + CString placementName; + POSITION pos; + WORD wID; + + for( pos = m_Windows.GetStartPosition(); pos != NULL ; ) + { + m_Windows.GetNextAssoc( pos, wID, (void*&)info ); + + if ( info->m_Window == wnd ) { + docked = (info->m_State == DockedWindowInfo::DOCKED); + break; + } + } + return docked; +} + +void CTabsDlg::SaveWindowPlacement( int ID ) +{ + DockedWindowInfo* info = NULL; + + CString placementName; + POSITION pos; + WORD wID = ID; + + for( pos = m_Windows.GetStartPosition(); pos != NULL ; ) + { + m_Windows.GetNextAssoc( pos, wID, (void*&)info ); + + if ( (info->m_State == DockedWindowInfo::FLOATING) && ((ID == -1) || (ID == info->m_ID))) { + placementName = info->m_Title + "Placement"; + ::SaveWindowPlacement(info->m_Container.GetSafeHwnd() , placementName); + } + } +} \ No newline at end of file diff --git a/tools/radiant/TabsDlg.h b/tools/radiant/TabsDlg.h new file mode 100644 index 000000000..3b0a2a350 --- /dev/null +++ b/tools/radiant/TabsDlg.h @@ -0,0 +1,110 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#pragma once +#include "afxcmn.h" +#include "TearoffContainerWindow.h" + + +// CTabsDlg dialog +class CTabsDlg : public CDialog +{ +// DECLARE_DYNAMIC ( CTabsDlg ) + // Construction +public: + + CTabsDlg(UINT ID ,CWnd* pParent = NULL); // standard constructor + + typedef void (*pfnOnDockEvent)( bool , int , CWnd* ); + + void AddDockedWindow ( CWnd* wnd , int ID , int imageID , const CString& title , bool dock , pfnOnDockEvent dockCallback = NULL); + void DockWindow ( int ID , bool dock ); + bool RectWithinDockManager ( CRect& rect ); + void FocusWindow ( int ID ); + void SetImageList ( CImageList* list ) + { + ASSERT ( list ); + m_Tabs.SetImageList( list ); + } + + bool IsDocked ( CWnd* wnd ); + + protected: + int CTabsDlg::PreTranslateMessage ( MSG* msg ); + +// Implementation +protected: + CImageList m_TabImages; + CPoint m_DragDownPoint; + CMapWordToPtr m_Windows; + bool m_DragTabActive; + + void DoDataExchange(CDataExchange* pDX); + + //private struct that holds the info we need about each window + struct DockedWindowInfo { + DockedWindowInfo ( CWnd* wnd , int ID , int imageID , const CString& title = "" , pfnOnDockEvent dockCallback = NULL) + { + ASSERT ( wnd ); + m_Window = wnd; + m_ID = ID; + m_ImageID = imageID; + m_TabControlIndex = -1; + if ( title.GetLength() == 0 ) + { + m_Window->GetWindowText( m_Title ); + + } + else + { + m_Title = title; + } + m_State = DOCKED; + m_DockCallback = dockCallback; + } + + enum eState {DOCKED,FLOATING} ; + CTearoffContainerWindow m_Container; //the floating window that will hold m_Window when it's undocked + CWnd* m_Window; + CString m_Title; + int m_ImageID; + int m_ID; + int m_TabControlIndex; + eState m_State; + pfnOnDockEvent m_DockCallback; + }; + void ShowAllWindows ( bool show = true ); + + void HandleUndock (); + void UpdateTabControlIndices (); + + // Generated message map functions + virtual BOOL OnInitDialog(); + DECLARE_MESSAGE_MAP() + +public: + CTabCtrl m_Tabs; + afx_msg void OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnDestroy(); + + void SaveWindowPlacement ( int ID = -1 ); +}; diff --git a/tools/radiant/TearoffContainerWindow.cpp b/tools/radiant/TearoffContainerWindow.cpp new file mode 100644 index 000000000..0cb390e34 --- /dev/null +++ b/tools/radiant/TearoffContainerWindow.cpp @@ -0,0 +1,141 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +// TearoffContainerWindow.cpp : implementation file +// + +#include "TabsDlg.h" +#include "TearoffContainerWindow.h" + + +// CTearoffContainerWindow + +IMPLEMENT_DYNAMIC(CTearoffContainerWindow, CWnd) +CTearoffContainerWindow::CTearoffContainerWindow() +{ + m_DragPreviewActive = false; + m_ContainedDialog = NULL; + m_DockManager = NULL; +} + +CTearoffContainerWindow::~CTearoffContainerWindow() +{ +} + + +BEGIN_MESSAGE_MAP(CTearoffContainerWindow, CWnd) + ON_WM_NCLBUTTONDBLCLK() + ON_WM_CLOSE() + ON_WM_SIZE() + ON_WM_DESTROY() + ON_WM_SETFOCUS() +END_MESSAGE_MAP() + +// CTearoffContainerWindow message handlers + + +void CTearoffContainerWindow::OnNcLButtonDblClk(UINT nHitTest, CPoint point) +{ + if ( nHitTest == HTCAPTION ) + { + m_DockManager->DockWindow ( m_DialogID , true ); + } + + CWnd::OnNcLButtonDblClk(nHitTest, point); +} + + +void CTearoffContainerWindow::SetDialog ( CWnd* dlg , int ID ) +{ + m_DialogID = ID; + m_ContainedDialog = dlg; + + CRect rect; + CPoint point (-10 , -10); + m_ContainedDialog->GetWindowRect ( rect ); + + rect.OffsetRect(point); //move the window slightly so you can tell it's been popped up + + //stupid hack to get the window resize itself properly + rect.DeflateRect(0,0,0,1); + MoveWindow(rect); + rect.InflateRect(0,0,0,1); + MoveWindow(rect); +} + +void CTearoffContainerWindow::SetDockManager ( CTabsDlg* dlg ) +{ + m_DockManager = dlg; +} +void CTearoffContainerWindow::OnClose() +{ + if ( m_DockManager ) + { + //send it back to the docking window (for now at least) + m_DockManager->DockWindow ( m_DialogID , true ); + } +} + + +BOOL CTearoffContainerWindow:: PreTranslateMessage( MSG* pMsg ) +{ + if ( pMsg->message == WM_NCLBUTTONUP ) + { +/* CRect rect; + GetWindowRect ( rect ); + + rect.DeflateRect( 0,0,0,rect.Height() - GetSystemMetrics(SM_CYSMSIZE)); + if ( m_DockManager->RectWithinDockManager ( rect )) + { + m_DockManager->DockDialog ( m_DialogID , true ); + } +*/ + } + + return CWnd::PreTranslateMessage(pMsg); +} +void CTearoffContainerWindow::OnSize(UINT nType, int cx, int cy) +{ + if ( m_ContainedDialog ) + { + m_ContainedDialog->MoveWindow ( 0,0,cx,cy); + } + + CWnd::OnSize(nType, cx, cy); +} + +void CTearoffContainerWindow::OnDestroy() +{ + CWnd::OnDestroy(); + + // TODO: Add your message handler code here +} + +void CTearoffContainerWindow::OnSetFocus(CWnd* pOldWnd) +{ + CWnd::OnSetFocus(pOldWnd); + if ( m_ContainedDialog ) + { + m_ContainedDialog->SetFocus(); + } + // TODO: Add your message handler code here +} diff --git a/tools/radiant/TearoffContainerWindow.h b/tools/radiant/TearoffContainerWindow.h new file mode 100644 index 000000000..b4ca0cf69 --- /dev/null +++ b/tools/radiant/TearoffContainerWindow.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#pragma once + +// CTearoffContainerWindow + +class CTabsDlg; +class CTearoffContainerWindow : public CWnd +{ + DECLARE_DYNAMIC(CTearoffContainerWindow) + +public: + CTearoffContainerWindow(); + virtual ~CTearoffContainerWindow(); + + CWnd* m_ContainedDialog; //dialog that is being docked/undocked + int m_DialogID; //identifier for this dialog + CTabsDlg* m_DockManager; //the dialog that contains m_ContainedDialog when docked + +protected: + DECLARE_MESSAGE_MAP() + bool m_DragPreviewActive; +public: + afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point); + void SetDialog ( CWnd* dlg , int ID ); + void SetDockManager ( CTabsDlg* dlg ); + afx_msg void OnClose(); + BOOL PreTranslateMessage( MSG* pMsg ); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnDestroy(); + afx_msg void OnSetFocus(CWnd* pOldWnd); +}; + + diff --git a/tools/radiant/TextureBar.cpp b/tools/radiant/TextureBar.cpp new file mode 100644 index 000000000..6323436b5 --- /dev/null +++ b/tools/radiant/TextureBar.cpp @@ -0,0 +1,206 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "TextureBar.h" + +//++timo TODO : the whole CTextureBar has to be modified for the new texture code + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTextureBar dialog + + +CTextureBar::CTextureBar() + : CDialogBar() +{ + //{{AFX_DATA_INIT(CTextureBar) + m_nHShift = 0; + m_nHScale = 0; + m_nRotate = 0; + m_nVShift = 0; + m_nVScale = 0; + m_nRotateAmt = 45; + //}}AFX_DATA_INIT +} + + +void CTextureBar::DoDataExchange(CDataExchange* pDX) +{ + CDialogBar::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTextureBar) + DDX_Control(pDX, IDC_SPIN_ROTATE, m_spinRotate); + DDX_Control(pDX, IDC_SPIN_VSCALE, m_spinVScale); + DDX_Control(pDX, IDC_SPIN_VSHIFT, m_spinVShift); + DDX_Control(pDX, IDC_SPIN_HSCALE, m_spinHScale); + DDX_Control(pDX, IDC_SPIN_HSHIFT, m_spinHShift); + DDX_Text(pDX, IDC_HSHIFT, m_nHShift); + DDX_Text(pDX, IDC_HSCALE, m_nHScale); + DDX_Text(pDX, IDC_ROTATE, m_nRotate); + DDX_Text(pDX, IDC_VSHIFT, m_nVShift); + DDX_Text(pDX, IDC_VSCALE, m_nVScale); + DDX_Text(pDX, IDC_EDIT_ROTATEAMT, m_nRotateAmt); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTextureBar, CDialogBar) + //{{AFX_MSG_MAP(CTextureBar) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSHIFT, OnDeltaposSpinHshift) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSHIFT, OnDeltaposSpinVshift) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSCALE, OnDeltaposSpinHScale) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSCALE, OnDeltaposSpinVScale) + ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ROTATE, OnDeltaposSpinRotate) + ON_COMMAND(ID_SELECTION_PRINT, OnSelectionPrint) + ON_WM_CREATE() + ON_BN_CLICKED(IDC_BTN_APPLYTEXTURESTUFF, OnBtnApplytexturestuff) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTextureBar message handlers + +void CTextureBar::OnDeltaposSpinHshift(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + *pResult = 0; + + if (pNMUpDown->iDelta < 0) + Select_ShiftTexture(abs(g_qeglobals.d_savedinfo.m_nTextureTweak), 0); + else + Select_ShiftTexture(-abs(g_qeglobals.d_savedinfo.m_nTextureTweak), 0); + GetSurfaceAttributes(); +} + +void CTextureBar::OnDeltaposSpinVshift(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + // TODO: Add your control notification handler code here + + *pResult = 0; + if (pNMUpDown->iDelta < 0) + Select_ShiftTexture(0, abs(g_qeglobals.d_savedinfo.m_nTextureTweak)); + else + Select_ShiftTexture(0, -abs(g_qeglobals.d_savedinfo.m_nTextureTweak)); + GetSurfaceAttributes(); +} + +void CTextureBar::OnDeltaposSpinHScale(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + // TODO: Add your control notification handler code here + + *pResult = 0; + if (pNMUpDown->iDelta < 0) + Select_ScaleTexture((float)abs(g_qeglobals.d_savedinfo.m_nTextureTweak),0); + else + Select_ScaleTexture((float)-abs(g_qeglobals.d_savedinfo.m_nTextureTweak),0); + GetSurfaceAttributes(); +} + +void CTextureBar::OnDeltaposSpinVScale(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + // TODO: Add your control notification handler code here + + *pResult = 0; + if (pNMUpDown->iDelta < 0) + Select_ScaleTexture(0, (float)abs(g_qeglobals.d_savedinfo.m_nTextureTweak)); + else + Select_ScaleTexture(0, (float)-abs(g_qeglobals.d_savedinfo.m_nTextureTweak)); + GetSurfaceAttributes(); +} + +void CTextureBar::OnDeltaposSpinRotate(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; + *pResult = 0; + UpdateData(TRUE); + if (pNMUpDown->iDelta < 0) + Select_RotateTexture(abs(m_nRotateAmt)); + else + Select_RotateTexture(-abs(m_nRotateAmt)); + GetSurfaceAttributes(); +} + + +void CTextureBar::OnSelectionPrint() +{ + // TODO: Add your command handler code here + +} + +int CTextureBar::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CDialogBar::OnCreate(lpCreateStruct) == -1) + return -1; + return 0; +} + + +void CTextureBar::OnBtnApplytexturestuff() +{ + SetSurfaceAttributes(); +} + +void CTextureBar::GetSurfaceAttributes() +{ + texdef_t* pt = (g_ptrSelectedFaces.GetSize() > 0) ? &(reinterpret_cast(g_ptrSelectedFaces.GetAt(0)))->texdef : &g_qeglobals.d_texturewin.texdef; + + if (pt) + { + m_nHShift = pt->shift[0]; + m_nVShift = pt->shift[1]; + m_nHScale = pt->scale[0]; + m_nVScale = pt->scale[1]; + m_nRotate = pt->rotate; + UpdateData(FALSE); + } +} + +//++timo implement brush primitive here +void CTextureBar::SetSurfaceAttributes() +{ + if (g_ptrSelectedFaces.GetSize() > 0) + { + if (g_qeglobals.m_bBrushPrimitMode) + { + common->Printf("Warning : brush primitive mode not implemented in CTextureBar"); + } + face_t *selFace = reinterpret_cast(g_ptrSelectedFaces.GetAt(0)); + + texdef_t* pt = &selFace->texdef; + UpdateData(TRUE); + pt->shift[0] = m_nHShift; + pt->shift[1] = m_nVShift; + pt->scale[0] = m_nHScale; + pt->scale[1] = m_nVScale; + pt->rotate = m_nRotate; + Sys_UpdateWindows(W_CAMERA); + } +} diff --git a/tools/radiant/TextureBar.h b/tools/radiant/TextureBar.h new file mode 100644 index 000000000..e88310f48 --- /dev/null +++ b/tools/radiant/TextureBar.h @@ -0,0 +1,82 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_TEXTUREBAR_H__86220273_B656_11D1_B59F_00AA00A410FC__INCLUDED_) +#define AFX_TEXTUREBAR_H__86220273_B656_11D1_B59F_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// TextureBar.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CTextureBar dialog + +class CTextureBar : public CDialogBar +{ +// Construction +public: + void GetSurfaceAttributes(); + void SetSurfaceAttributes(); + CTextureBar(); + +// Dialog Data + //{{AFX_DATA(CTextureBar) + enum { IDD = IDD_TEXTUREBAR }; + CSpinButtonCtrl m_spinRotate; + CSpinButtonCtrl m_spinVScale; + CSpinButtonCtrl m_spinVShift; + CSpinButtonCtrl m_spinHScale; + CSpinButtonCtrl m_spinHShift; + int m_nHShift; + int m_nHScale; + int m_nRotate; + int m_nVShift; + int m_nVScale; + int m_nRotateAmt; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTextureBar) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + // Generated message map functions + //{{AFX_MSG(CTextureBar) + afx_msg void OnDeltaposSpinHshift(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpinVshift(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpinHScale(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpinVScale(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDeltaposSpinRotate(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnSelectionPrint(); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnBtnApplytexturestuff(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TEXTUREBAR_H__86220273_B656_11D1_B59F_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/Textures.h b/tools/radiant/Textures.h new file mode 100644 index 000000000..08e95143b --- /dev/null +++ b/tools/radiant/Textures.h @@ -0,0 +1,50 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// a texturename of the form (0 0 0) will +// create a solid color texture + +void Texture_Init (bool bHardInit = true); +void Texture_FlushUnused (); +void Texture_Flush (bool bReload = false); +void Texture_ClearInuse (void); +void Texture_ShowInuse (void); +void Texture_ShowDirectory (int menunum, bool bLinked = false); +void Texture_ShowAll(); +void Texture_HideAll(); +void Texture_Cleanup(CStringList *pList = NULL); + +// TTimo: added bNoAlpha flag to ignore alpha channel when parsing a .TGA file, transparency is usually achieved through qer_trans keyword in shaders +// in some cases loading an empty alpha channel causes display bugs (brushes not seen) +//qtexture_t *Texture_ForName (const char *name, bool bReplace = false, bool bShader = false, bool bNoAlpha = false, bool bReload = false, bool makeShader = true); + +const idMaterial *Texture_ForName(const char *name); + +void Texture_Init (void); +void Texture_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale = false, bool bSetSelection = true); + +void Texture_SetMode(int iMenu); // GL_TEXTURE_NEAREST, etc.. +void Texture_ResetPosition(); + +void FreeShaders(); +void LoadShaders(); +void ReloadShaders(); +int WINAPI Texture_LoadSkin(char *pName, int *pnWidth, int *pnHeight); +void Texture_StartPos (void); +qtexture_t *Texture_NextPos (int *x, int *y); diff --git a/tools/radiant/Undo.cpp b/tools/radiant/Undo.cpp new file mode 100644 index 000000000..321b6271c --- /dev/null +++ b/tools/radiant/Undo.cpp @@ -0,0 +1,900 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" + +/* + + QERadiant Undo/Redo + + +basic setup: + +<-g_undolist---------g_lastundo> <---map data---> <-g_lastredo---------g_redolist-> + + + undo/redo on the world_entity is special, only the epair changes are remembered + and the world entity never gets deleted. + + FIXME: maybe reset the Undo system at map load + maybe also reset the entityId at map load +*/ + +typedef struct undo_s +{ + double time; //time operation was performed + int id; //every undo has an unique id + int done; //true when undo is build + char *operation; //name of the operation + brush_t brushlist; //deleted brushes + entity_t entitylist; //deleted entities + struct undo_s *prev, *next; //next and prev undo in list +} undo_t; + +undo_t *g_undolist; //first undo in the list +undo_t *g_lastundo; //last undo in the list +undo_t *g_redolist; //first redo in the list +undo_t *g_lastredo; //last undo in list +int g_undoMaxSize = 64; //maximum number of undos +int g_undoSize = 0; //number of undos in the list +int g_undoMaxMemorySize = 2*1024*1024; //maximum undo memory (default 2 MB) +int g_undoMemorySize = 0; //memory size of undo buffer +int g_undoId = 1; //current undo ID (zero is invalid id) +int g_redoId = 1; //current redo ID (zero is invalid id) + + +/* +============= +Undo_MemorySize +============= +*/ +int Undo_MemorySize(void) +{ + /* + int size; + undo_t *undo; + brush_t *pBrush; + entity_t *pEntity; + + size = 0; + for (undo = g_undolist; undo; undo = undo->next) + { + for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pBrush->next) + { + size += Brush_MemorySize(pBrush); + } + for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pEntity->next) + { + size += Entity_MemorySize(pEntity); + } + size += sizeof(undo_t); + } + return size; + */ + return g_undoMemorySize; +} + +/* +============= +Undo_ClearRedo +============= +*/ +void Undo_ClearRedo(void) +{ + undo_t *redo, *nextredo; + brush_t *pBrush, *pNextBrush; + entity_t *pEntity, *pNextEntity; + + for (redo = g_redolist; redo; redo = nextredo) + { + nextredo = redo->next; + for (pBrush = redo->brushlist.next ; pBrush != NULL && pBrush != &redo->brushlist ; pBrush = pNextBrush) + { + pNextBrush = pBrush->next; + Brush_Free(pBrush); + } + for (pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = pNextEntity) + { + pNextEntity = pEntity->next; + Entity_Free(pEntity); + } + Mem_Free(redo); + } + g_redolist = NULL; + g_lastredo = NULL; + g_redoId = 1; +} + +/* +============= +Undo_Clear + + Clears the undo buffer. +============= +*/ +void Undo_Clear(void) +{ + undo_t *undo, *nextundo; + brush_t *pBrush, *pNextBrush; + entity_t *pEntity, *pNextEntity; + + Undo_ClearRedo(); + for (undo = g_undolist; undo; undo = nextundo) + { + nextundo = undo->next; + for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush) + { + pNextBrush = pBrush->next; + g_undoMemorySize -= Brush_MemorySize(pBrush); + Brush_Free(pBrush); + } + for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity) + { + pNextEntity = pEntity->next; + g_undoMemorySize -= Entity_MemorySize(pEntity); + Entity_Free(pEntity); + } + g_undoMemorySize -= sizeof(undo_t); + Mem_Free(undo); + } + g_undolist = NULL; + g_lastundo = NULL; + g_undoSize = 0; + g_undoMemorySize = 0; + g_undoId = 1; +} + +/* +============= +Undo_SetMaxSize +============= +*/ +void Undo_SetMaxSize(int size) +{ + Undo_Clear(); + if (size < 1) g_undoMaxSize = 1; + else g_undoMaxSize = size; +} + +/* +============= +Undo_GetMaxSize +============= +*/ +int Undo_GetMaxSize(void) +{ + return g_undoMaxSize; +} + +/* +============= +Undo_SetMaxMemorySize +============= +*/ +void Undo_SetMaxMemorySize(int size) +{ + Undo_Clear(); + if (size < 1024) g_undoMaxMemorySize = 1024; + else g_undoMaxMemorySize = size; +} + +/* +============= +Undo_GetMaxMemorySize +============= +*/ +int Undo_GetMaxMemorySize(void) +{ + return g_undoMaxMemorySize; +} + +/* +============= +Undo_FreeFirstUndo +============= +*/ +void Undo_FreeFirstUndo(void) +{ + undo_t *undo; + brush_t *pBrush, *pNextBrush; + entity_t *pEntity, *pNextEntity; + + //remove the oldest undo from the undo buffer + undo = g_undolist; + g_undolist = g_undolist->next; + g_undolist->prev = NULL; + // + for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush) + { + pNextBrush = pBrush->next; + g_undoMemorySize -= Brush_MemorySize(pBrush); + Brush_Free(pBrush); + } + for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity) + { + pNextEntity = pEntity->next; + g_undoMemorySize -= Entity_MemorySize(pEntity); + Entity_Free(pEntity); + } + g_undoMemorySize -= sizeof(undo_t); + Mem_Free(undo); + g_undoSize--; +} + +/* +============= +Undo_GeneralStart +============= +*/ +void Undo_GeneralStart(char *operation) +{ + undo_t *undo; + brush_t *pBrush; + entity_t *pEntity; + + + if (g_lastundo) + { + if (!g_lastundo->done) + { + common->Printf("Undo_Start: WARNING last undo not finished.\n"); + } + } + + undo = (undo_t *) Mem_ClearedAlloc(sizeof(undo_t)); + if (!undo) return; + memset(undo, 0, sizeof(undo_t)); + undo->brushlist.next = &undo->brushlist; + undo->brushlist.prev = &undo->brushlist; + undo->entitylist.next = &undo->entitylist; + undo->entitylist.prev = &undo->entitylist; + if (g_lastundo) g_lastundo->next = undo; + else g_undolist = undo; + undo->prev = g_lastundo; + undo->next = NULL; + g_lastundo = undo; + + undo->time = Sys_DoubleTime(); + // + if (g_undoId > g_undoMaxSize * 2) g_undoId = 1; + if (g_undoId <= 0) g_undoId = 1; + undo->id = g_undoId++; + undo->done = false; + undo->operation = operation; + //reset the undo IDs of all brushes using the new ID + for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pBrush->next) + { + if (pBrush->undoId == undo->id) + { + pBrush->undoId = 0; + } + } + for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) + { + if (pBrush->undoId == undo->id) + { + pBrush->undoId = 0; + } + } + //reset the undo IDs of all entities using thew new ID + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) + { + if (pEntity->undoId == undo->id) + { + pEntity->undoId = 0; + } + } + g_undoMemorySize += sizeof(undo_t); + g_undoSize++; + //undo buffer is bound to a max + if (g_undoSize > g_undoMaxSize) + { + Undo_FreeFirstUndo(); + } +} + +/* +============= +Undo_BrushInUndo +============= +*/ +int Undo_BrushInUndo(undo_t *undo, brush_t *brush) +{ + brush_t *b; + + for (b = undo->brushlist.next; b != &undo->brushlist; b = b->next) + { + if (b == brush) return true; + } + return false; +} + +/* +============= +Undo_EntityInUndo +============= +*/ +int Undo_EntityInUndo(undo_t *undo, entity_t *ent) +{ + entity_t *e; + + for (e = undo->entitylist.next; e != &undo->entitylist; e = e->next) + { + if (e == ent) return true; + } + return false; +} + +/* +============= +Undo_Start +============= +*/ +void Undo_Start(char *operation) +{ + Undo_ClearRedo(); + Undo_GeneralStart(operation); +} + +/* +============= +Undo_AddBrush +============= +*/ +void Undo_AddBrush(brush_t *pBrush) +{ + if (!g_lastundo) + { + Sys_Status("Undo_AddBrushList: no last undo.\n"); + return; + } + if (g_lastundo->entitylist.next != &g_lastundo->entitylist) + { + Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); + } + //if the brush is already in the undo + if (Undo_BrushInUndo(g_lastundo, pBrush)) + return; + //clone the brush + brush_t* pClone = Brush_FullClone(pBrush); + //save the ID of the owner entity + pClone->ownerId = pBrush->owner->entityId; + + if (pBrush->owner && !(pBrush->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN)) { + Undo_AddEntity(pBrush->owner); + } + + //save the old undo ID for previous undos + pClone->undoId = pBrush->undoId; + Brush_AddToList (pClone, &g_lastundo->brushlist); + // + g_undoMemorySize += Brush_MemorySize(pClone); +} + +/* +============= +Undo_AddBrushList +============= +*/ +void Undo_AddBrushList(brush_t *brushlist) +{ + brush_t *pBrush; + + if (!g_lastundo) + { + Sys_Status("Undo_AddBrushList: no last undo.\n"); + return; + } + if (g_lastundo->entitylist.next != &g_lastundo->entitylist) + { + Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); + } + //copy the brushes to the undo + for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) + { + //if the brush is already in the undo + if (Undo_BrushInUndo(g_lastundo, pBrush)) + continue; + //clone the brush + brush_t* pClone = Brush_FullClone(pBrush); + //save the ID of the owner entity + pClone->ownerId = pBrush->owner->entityId; + //save the old undo ID from previous undos + pClone->undoId = pBrush->undoId; + + if ( pBrush->owner && pBrush->owner != world_entity ) { + Undo_AddEntity(pBrush->owner); + } + + + Brush_AddToList (pClone, &g_lastundo->brushlist); + // + g_undoMemorySize += Brush_MemorySize(pClone); + } +} + +/* +============= +Undo_EndBrush +============= +*/ +void Undo_EndBrush(brush_t *pBrush) +{ + if (!g_lastundo) + { + //Sys_Status("Undo_End: no last undo.\n"); + return; + } + if (g_lastundo->done) + { + //Sys_Status("Undo_End: last undo already finished.\n"); + return; + } + pBrush->undoId = g_lastundo->id; +} + +/* +============= +Undo_EndBrushList +============= +*/ +void Undo_EndBrushList(brush_t *brushlist) +{ + if (!g_lastundo) + { + //Sys_Status("Undo_End: no last undo.\n"); + return; + } + if (g_lastundo->done) + { + //Sys_Status("Undo_End: last undo already finished.\n"); + return; + } + for (brush_t* pBrush = brushlist->next; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) + { + pBrush->undoId = g_lastundo->id; + } +} + +/* +============= +Undo_AddEntity +============= +*/ +void Undo_AddEntity(entity_t *entity) +{ + entity_t* pClone; + + if (!g_lastundo) + { + Sys_Status("Undo_AddEntity: no last undo.\n"); + return; + } + //if the entity is already in the undo + if (Undo_EntityInUndo(g_lastundo, entity)) + return; + //clone the entity + pClone = Entity_Clone(entity); + //NOTE: Entity_Clone adds the entity to the entity list + // so we remove it from that list here + Entity_RemoveFromList(pClone); + //save the old undo ID for previous undos + pClone->undoId = entity->undoId; + //save the entity ID (we need a full clone) + pClone->entityId = entity->entityId; + // + Entity_AddToList(pClone, &g_lastundo->entitylist); + // + g_undoMemorySize += Entity_MemorySize(pClone); +} + +/* +============= +Undo_EndEntity +============= +*/ +void Undo_EndEntity(entity_t *entity) +{ + if (!g_lastundo) + { + //Sys_Status("Undo_End: no last undo.\n"); + return; + } + if (g_lastundo->done) + { + //Sys_Status("Undo_End: last undo already finished.\n"); + return; + } + if (entity == world_entity) + { + //Sys_Status("Undo_AddEntity: undo on world entity.\n"); + //NOTE: we never delete the world entity when undoing an operation + // we only transfer the epairs + return; + } + entity->undoId = g_lastundo->id; +} + +/* +============= +Undo_End +============= +*/ +void Undo_End(void) +{ + if (!g_lastundo) + { + //Sys_Status("Undo_End: no last undo.\n"); + return; + } + if (g_lastundo->done) + { + //Sys_Status("Undo_End: last undo already finished.\n"); + return; + } + g_lastundo->done = true; + + //undo memory size is bound to a max + while (g_undoMemorySize > g_undoMaxMemorySize) + { + //always keep one undo + if (g_undolist == g_lastundo) break; + Undo_FreeFirstUndo(); + } + // + //Sys_Status("undo size = %d, undo memory = %d\n", g_undoSize, g_undoMemorySize); +} + +/* +============= +Undo_Undo +============= +*/ +void Undo_Undo(void) +{ + undo_t *undo, *redo; + brush_t *pBrush, *pNextBrush; + entity_t *pEntity, *pNextEntity, *pUndoEntity; + + if (!g_lastundo) + { + Sys_Status("Nothing left to undo.\n"); + return; + } + if (!g_lastundo->done) + { + Sys_Status("Undo_Undo: WARNING: last undo not yet finished!\n"); + } + // get the last undo + undo = g_lastundo; + if (g_lastundo->prev) g_lastundo->prev->next = NULL; + else g_undolist = NULL; + g_lastundo = g_lastundo->prev; + + //allocate a new redo + redo = (undo_t *) Mem_ClearedAlloc(sizeof(undo_t)); + if (!redo) return; + memset(redo, 0, sizeof(undo_t)); + redo->brushlist.next = &redo->brushlist; + redo->brushlist.prev = &redo->brushlist; + redo->entitylist.next = &redo->entitylist; + redo->entitylist.prev = &redo->entitylist; + if (g_lastredo) g_lastredo->next = redo; + else g_redolist = redo; + redo->prev = g_lastredo; + redo->next = NULL; + g_lastredo = redo; + redo->time = Sys_DoubleTime(); + redo->id = g_redoId++; + redo->done = true; + redo->operation = undo->operation; + + //reset the redo IDs of all brushes using the new ID + for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pBrush->next) + { + if (pBrush->redoId == redo->id) + { + pBrush->redoId = 0; + } + } + for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) + { + if (pBrush->redoId == redo->id) + { + pBrush->redoId = 0; + } + } + //reset the redo IDs of all entities using thew new ID + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) + { + if (pEntity->redoId == redo->id) + { + pEntity->redoId = 0; + } + } + + // remove current selection + Select_Deselect(); + // move "created" brushes to the redo + for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush=pNextBrush) + { + pNextBrush = pBrush->next; + if (pBrush->undoId == undo->id) + { + //Brush_Free(pBrush); + //move the brush to the redo + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, &redo->brushlist); + //make sure the ID of the owner is stored + pBrush->ownerId = pBrush->owner->entityId; + //unlink the brush from the owner entity + Entity_UnlinkBrush(pBrush); + } + } + // move "created" entities to the redo + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) + { + pNextEntity = pEntity->next; + if (pEntity->undoId == undo->id) + { + // check if this entity is in the undo + for (pUndoEntity = undo->entitylist.next; pUndoEntity != NULL && pUndoEntity != &undo->entitylist; pUndoEntity = pUndoEntity->next) + { + // move brushes to the undo entity + if (pUndoEntity->entityId == pEntity->entityId) + { + pUndoEntity->brushes.next = pEntity->brushes.next; + pUndoEntity->brushes.prev = pEntity->brushes.prev; + pEntity->brushes.next = &pEntity->brushes; + pEntity->brushes.prev = &pEntity->brushes; + } + } + // + //Entity_Free(pEntity); + //move the entity to the redo + Entity_RemoveFromList(pEntity); + Entity_AddToList(pEntity, &redo->entitylist); + } + } + // add the undo entities back into the entity list + for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = undo->entitylist.next) + { + g_undoMemorySize -= Entity_MemorySize(pEntity); + //if this is the world entity + if (pEntity->entityId == world_entity->entityId) + { + //free the epairs of the world entity + Entity_FreeEpairs(world_entity); + //set back the original epairs + world_entity->epairs = pEntity->epairs; + //free the world_entity clone that stored the epairs + Entity_Free(pEntity); + } + else + { + Entity_RemoveFromList(pEntity); + Entity_AddToList(pEntity, &entities); + pEntity->redoId = redo->id; + } + } + // add the undo brushes back into the selected brushes + for (pBrush = undo->brushlist.next; pBrush != NULL && pBrush != &undo->brushlist; pBrush = undo->brushlist.next) + { + g_undoMemorySize -= Brush_MemorySize(pBrush); + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, &active_brushes); + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) + { + if (pEntity->entityId == pBrush->ownerId) + { + Entity_LinkBrush(pEntity, pBrush); + break; + } + } + //if the brush is not linked then it should be linked into the world entity + if (pEntity == NULL || pEntity == &entities) + { + Entity_LinkBrush(world_entity, pBrush); + } + //build the brush + //Brush_Build(pBrush); + Select_Brush(pBrush); + pBrush->redoId = redo->id; + } + // + common->Printf("%s undone.\n", undo->operation); + // free the undo + g_undoMemorySize -= sizeof(undo_t); + Mem_Free(undo); + g_undoSize--; + g_undoId--; + if (g_undoId <= 0) g_undoId = 2 * g_undoMaxSize; + // + + Sys_BeginWait(); + brush_t *b, *next; + for (b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next) { + next = b->next; + Brush_Build( b, true, false, false ); + } + for (b = selected_brushes.next ; b != NULL && b != &selected_brushes ; b=next) { + next = b->next; + Brush_Build( b, true, false, false ); + } + Sys_EndWait(); + + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); +} + +/* +============= +Undo_Redo +============= +*/ +void Undo_Redo(void) +{ + undo_t *redo; + brush_t *pBrush, *pNextBrush; + entity_t *pEntity, *pNextEntity, *pRedoEntity; + + if (!g_lastredo) + { + Sys_Status("Nothing left to redo.\n"); + return; + } + if (g_lastundo) + { + if (!g_lastundo->done) + { + Sys_Status("WARNING: last undo not finished.\n"); + } + } + // get the last redo + redo = g_lastredo; + if (g_lastredo->prev) g_lastredo->prev->next = NULL; + else g_redolist = NULL; + g_lastredo = g_lastredo->prev; + // + Undo_GeneralStart(redo->operation); + // remove current selection + Select_Deselect(); + // move "created" brushes back to the last undo + for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pNextBrush) + { + pNextBrush = pBrush->next; + if (pBrush->redoId == redo->id) + { + //move the brush to the undo + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, &g_lastundo->brushlist); + g_undoMemorySize += Brush_MemorySize(pBrush); + pBrush->ownerId = pBrush->owner->entityId; + Entity_UnlinkBrush(pBrush); + } + } + // move "created" entities back to the last undo + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) + { + pNextEntity = pEntity->next; + if (pEntity->redoId == redo->id) + { + // check if this entity is in the redo + for (pRedoEntity = redo->entitylist.next; pRedoEntity != NULL && pRedoEntity != &redo->entitylist; pRedoEntity = pRedoEntity->next) + { + // move brushes to the redo entity + if (pRedoEntity->entityId == pEntity->entityId) + { + pRedoEntity->brushes.next = pEntity->brushes.next; + pRedoEntity->brushes.prev = pEntity->brushes.prev; + pEntity->brushes.next = &pEntity->brushes; + pEntity->brushes.prev = &pEntity->brushes; + } + } + // + //Entity_Free(pEntity); + //move the entity to the redo + Entity_RemoveFromList(pEntity); + Entity_AddToList(pEntity, &g_lastundo->entitylist); + g_undoMemorySize += Entity_MemorySize(pEntity); + } + } + // add the undo entities back into the entity list + for (pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = redo->entitylist.next) + { + //if this is the world entity + if (pEntity->entityId == world_entity->entityId) + { + //free the epairs of the world entity + Entity_FreeEpairs(world_entity); + //set back the original epairs + world_entity->epairs = pEntity->epairs; + //free the world_entity clone that stored the epairs + Entity_Free(pEntity); + } + else + { + Entity_RemoveFromList(pEntity); + Entity_AddToList(pEntity, &entities); + } + } + // add the redo brushes back into the selected brushes + for (pBrush = redo->brushlist.next; pBrush != NULL && pBrush != &redo->brushlist; pBrush = redo->brushlist.next) + { + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, &active_brushes); + for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) + { + if (pEntity->entityId == pBrush->ownerId) + { + Entity_LinkBrush(pEntity, pBrush); + break; + } + } + //if the brush is not linked then it should be linked into the world entity + if (pEntity == NULL || pEntity == &entities) + { + Entity_LinkBrush(world_entity, pBrush); + } + //build the brush + //Brush_Build(pBrush); + Select_Brush(pBrush); + } + // + Undo_End(); + // + common->Printf("%s redone.\n", redo->operation); + // + g_redoId--; + // free the undo + Mem_Free(redo); + // + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); +} + +/* +============= +Undo_RedoAvailable +============= +*/ +int Undo_RedoAvailable(void) +{ + if (g_lastredo) return true; + return false; +} + +/* +============= +Undo_UndoAvailable +============= +*/ +int Undo_UndoAvailable(void) +{ + if (g_lastundo) + { + if (g_lastundo->done) + return true; + } + return false; +} diff --git a/tools/radiant/Undo.h b/tools/radiant/Undo.h new file mode 100644 index 000000000..c088ca9cb --- /dev/null +++ b/tools/radiant/Undo.h @@ -0,0 +1,56 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +//start operation +void Undo_Start(char *operation); +//end operation +void Undo_End(void); +//add brush to the undo +void Undo_AddBrush(brush_t *pBrush); +//add a list with brushes to the undo +void Undo_AddBrushList(brush_t *brushlist); +//end a brush after the operation is performed +void Undo_EndBrush(brush_t *pBrush); +//end a list with brushes after the operation is performed +void Undo_EndBrushList(brush_t *brushlist); +//add entity to undo +void Undo_AddEntity(entity_t *entity); +//end an entity after the operation is performed +void Undo_EndEntity(entity_t *entity); +//undo last operation +void Undo_Undo(void); +//redo last undone operation +void Undo_Redo(void); +//returns true if there is something to be undone available +int Undo_UndoAvailable(void); +//returns true if there is something to redo available +int Undo_RedoAvailable(void); +//clear the undo buffer +void Undo_Clear(void); +//set maximum undo size (default 64) +void Undo_SetMaxSize(int size); +//get maximum undo size +int Undo_GetMaxSize(void); +//set maximum undo memory in bytes (default 2 MB) +void Undo_SetMaxMemorySize(int size); +//get maximum undo memory in bytes +int Undo_GetMaxMemorySize(void); +//returns the amount of memory used by undo +int Undo_MemorySize(void); + diff --git a/tools/radiant/VERTSEL.CPP b/tools/radiant/VERTSEL.CPP new file mode 100644 index 000000000..0b7e246e1 --- /dev/null +++ b/tools/radiant/VERTSEL.CPP @@ -0,0 +1,419 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +#define NEWEDGESEL 1 + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int FindPoint(idVec3 point) { + int i, j; + + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + for (j = 0; j < 3; j++) { + if (idMath::Fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1) { + break; + } + } + + if (j == 3) { + return i; + } + } + + VectorCopy(point, g_qeglobals.d_points[g_qeglobals.d_numpoints]); + if (g_qeglobals.d_numpoints < MAX_POINTS - 1) { + g_qeglobals.d_numpoints++; + } + + return g_qeglobals.d_numpoints - 1; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int FindEdge(int p1, int p2, face_t *f) { + int i; + + for (i = 0; i < g_qeglobals.d_numedges; i++) { + if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1) { + g_qeglobals.d_edges[i].f2 = f; + return i; + } + } + + g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1; + g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2; + g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f; + + if (g_qeglobals.d_numedges < MAX_EDGES - 1) { + g_qeglobals.d_numedges++; + } + + return g_qeglobals.d_numedges - 1; +} + +#ifdef NEWEDGESEL +void MakeFace (brush_t * b, face_t * f) +#else +void MakeFace (face_t * f) +#endif +{ + idWinding *w; + int i; + int pnum[128]; + +#ifdef NEWEDGESEL + w = Brush_MakeFaceWinding(b, f); +#else + w = Brush_MakeFaceWinding(selected_brushes.next, f); +#endif + if (!w) { + return; + } + for (i = 0; i < w->GetNumPoints(); i++) { + pnum[i] = FindPoint( (*w)[i].ToVec3() ); + } + for (i = 0; i < w->GetNumPoints(); i++) { + FindEdge(pnum[i], pnum[(i + 1) % w->GetNumPoints()], f); + } + delete w; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SetupVertexSelection(void) { + face_t *f; + brush_t *b; + + g_qeglobals.d_numpoints = 0; + g_qeglobals.d_numedges = 0; + +#ifdef NEWEDGESEL + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (f = b->brush_faces; f; f = f->next) { + MakeFace(b, f); + } + } + +#else + if (!QE_SingleBrush()) { + return; + } + + b = selected_brushes.next; + for (f = b->brush_faces; f; f = f->next) { + MakeFace(b, f); + } +#endif +} + +#ifdef NEWEDGESEL +void SelectFaceEdge (brush_t * b, face_t * f, int p1, int p2) +#else +void SelectFaceEdge (face_t * f, int p1, int p2) +#endif +{ + idWinding *w; + int i, j, k; + int pnum[128]; + +#ifdef NEWEDGESEL + w = Brush_MakeFaceWinding(b, f); +#else + w = Brush_MakeFaceWinding(selected_brushes.next, f); +#endif + if (!w) { + return; + } + for (i = 0; i < w->GetNumPoints(); i++) { + pnum[i] = FindPoint( (*w)[i].ToVec3() ); + } + for (i = 0; i < w->GetNumPoints(); i++) { + if (pnum[i] == p1 && pnum[(i + 1) % w->GetNumPoints()] == p2) { + VectorCopy(g_qeglobals.d_points[pnum[i]], f->planepts[0]); + VectorCopy(g_qeglobals.d_points[pnum[(i + 1) % w->GetNumPoints()]], f->planepts[1]); + VectorCopy(g_qeglobals.d_points[pnum[(i + 2) % w->GetNumPoints()]], f->planepts[2]); + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) { + f->planepts[j][k] = + floor(f->planepts[j][k] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + } + AddPlanept(&f->planepts[0]); + AddPlanept(&f->planepts[1]); + break; + } + } + if ( i == w->GetNumPoints() ) { + Sys_Status("SelectFaceEdge: failed\n"); + } + delete w; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SelectVertex(int p1) { + brush_t *b; + idWinding *w; + int i, j, k; + face_t *f; + +#ifdef NEWEDGESEL + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + for (f = b->brush_faces; f; f = f->next) { + w = Brush_MakeFaceWinding(b, f); + if (!w) { + continue; + } + + for (i = 0; i < w->GetNumPoints(); i++) { + if ( FindPoint( (*w)[i].ToVec3() ) == p1 ) { + VectorCopy((*w)[(i + w->GetNumPoints() - 1) % w->GetNumPoints()], f->planepts[0]); + VectorCopy((*w)[i], f->planepts[1]); + VectorCopy((*w)[(i + 1) % w->GetNumPoints()], f->planepts[2]); + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) { + // f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + } + + AddPlanept(&f->planepts[1]); + + // MessageBeep(-1); + break; + } + } + + delete w; + } + } + +#else + b = selected_brushes.next; + for (f = b->brush_faces; f; f = f->next) { + w = Brush_MakeFaceWinding(b, f); + if (!w) { + continue; + } + + for (i = 0; i < w->GetNumPoints(); i++) { + if (FindPoint(w[i]) == p1) { + VectorCopy(w[(i + w->GetNumPoints() - 1) % w->GetNumPoints()], f->planepts[0]); + VectorCopy(w[i], f->planepts[1]); + VectorCopy(w[(i + 1) % w->GetNumPoints()], f->planepts[2]); + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) { + // f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + } + + AddPlanept(&f->planepts[1]); + + // MessageBeep(-1); + break; + } + } + + delete w; + } +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SelectEdgeByRay(idVec3 org, idVec3 dir) { + int i, j, besti; + float d, bestd; + idVec3 mid, temp; + pedge_t *e; + + // find the edge closest to the ray + besti = -1; + bestd = 8; + + for (i = 0; i < g_qeglobals.d_numedges; i++) { + for (j = 0; j < 3; j++) { + mid[j] = 0.5 * (g_qeglobals.d_points[g_qeglobals.d_edges[i].p1][j] + g_qeglobals.d_points[g_qeglobals.d_edges[i].p2][j]); + } + + temp = mid - org; + d = temp * dir; + temp = org + d * dir; + temp = mid - temp; + d = temp.Length(); + if ( d < bestd ) { + bestd = d; + besti = i; + } + } + + if (besti == -1) { + Sys_Status("Click didn't hit an edge\n"); + return; + } + + Sys_Status("hit edge\n"); + + // + // make the two faces that border the edge use the two edge points as primary drag + // points + // + g_qeglobals.d_num_move_points = 0; + e = &g_qeglobals.d_edges[besti]; +#ifdef NEWEDGESEL + for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) { + SelectFaceEdge(b, e->f1, e->p1, e->p2); + SelectFaceEdge(b, e->f2, e->p2, e->p1); + } + +#else + SelectFaceEdge(e->f1, e->p1, e->p2); + SelectFaceEdge(e->f2, e->p2, e->p1); +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SelectVertexByRay(idVec3 org, idVec3 dir) { + int i, besti; + float d, bestd; + idVec3 temp; + + float scale = g_pParentWnd->ActiveXY()->Scale(); + // find the point closest to the ray + besti = -1; + bestd = 8 / scale / 2; + + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + temp = g_qeglobals.d_points[i] - org; + d = temp * dir; + temp = org + d * dir; + temp = g_qeglobals.d_points[i] - temp; + d = temp.Length(); + if ( d < bestd ) { + bestd = d; + besti = i; + } + } + + if (besti == -1 || bestd > 8 / scale / 2 ) { + Sys_Status("Click didn't hit a vertex\n"); + return; + } + + Sys_Status("hit vertex\n"); + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti]; + + // SelectVertex (besti); +} + +extern void AddPatchMovePoint(idVec3 v, bool bMulti, bool bFull); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) { + int i, besti; + float d, bestd; + idVec3 temp; + + // find the point closest to the ray + float scale = g_pParentWnd->ActiveXY()->Scale(); + besti = -1; + bestd = 8 / scale / 2; + //bestd = 8; + + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + temp = g_qeglobals.d_points[i] - org; + d = temp * dir; + temp = org + d * dir; + temp = g_qeglobals.d_points[i] - temp; + d = temp.Length(); + if ( d <= bestd ) { + bestd = d; + besti = i; + } + } + + if (besti == -1) { + if (g_pParentWnd->ActiveXY()->AreaSelectOK()) { + g_qeglobals.d_select_mode = sel_area; + VectorCopy(org, g_qeglobals.d_vAreaTL); + VectorCopy(org, g_qeglobals.d_vAreaBR); + } + + return; + } + + // Sys_Status ("hit vertex\n"); + AddPatchMovePoint( g_qeglobals.d_points[besti], ( buttons & MK_CONTROL ) != 0, ( buttons & MK_SHIFT ) != 0 ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SelectSplinePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) { + int i, besti; + float d, bestd; + idVec3 temp; + + // find the point closest to the ray + besti = -1; + bestd = 8; + + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + temp = g_qeglobals.d_points[i] - org; + d = temp * dir; + temp = org + d * dir; + temp = g_qeglobals.d_points[i] - temp; + d = temp.Length(); + if ( d <= bestd ) { + bestd = d; + besti = i; + } + } + + if (besti == -1) { + return; + } + + Sys_Status("hit curve point\n"); + g_qeglobals.d_num_move_points = 0; + g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti]; + + // g_splineList->setSelectedPoint(&g_qeglobals.d_points[besti]); +} diff --git a/tools/radiant/WIN_DLG.CPP b/tools/radiant/WIN_DLG.CPP new file mode 100644 index 000000000..3a562506d --- /dev/null +++ b/tools/radiant/WIN_DLG.CPP @@ -0,0 +1,626 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +BOOL CALLBACK EditCommandDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char key[1024]; + char value[1024]; + const char *temp; + int index; + HWND hOwner; + + hOwner = GetParent (hwndDlg); + + switch (uMsg) + { + case WM_INITDIALOG: + index = SendDlgItemMessage (hOwner, IDC_CMD_LIST, LB_GETCURSEL, 0, 0); + if (index >= 0) + { + SendDlgItemMessage(hOwner, IDC_CMD_LIST, LB_GETTEXT, index, (LPARAM) (LPCTSTR) key); + temp = ValueForKey (g_qeglobals.d_project_entity, key); + strcpy (value, temp); + SetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key); + SetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value); + } + return FALSE; + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (!GetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key, 64)) + { + common->Printf ("Command not added\n"); + return FALSE; + } + + if (!GetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value, 64)) + { + common->Printf ("Command not added\n"); + return FALSE; + } + + //if (key[0] == 'b' && key[1] == 's' && key[2] == 'p') + //{ + SetKeyValue (g_qeglobals.d_project_entity, key, value); + FillBSPMenu (); + //} + //else + // common->Printf ("BSP commands must be preceded by \"bsp\""); + + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + +BOOL CALLBACK AddCommandDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char key[64]; + char value[128]; + + switch (uMsg) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (!GetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key, 64)) + { + common->Printf ("Command not added\n"); + return FALSE; + } + + if (!GetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value, 64)) + { + common->Printf ("Command not added\n"); + return FALSE; + } + + if (key[0] == 'b' && key[1] == 's' && key[2] == 'p') + { + SetKeyValue (g_qeglobals.d_project_entity, key, value); + FillBSPMenu (); + } + else + common->Printf ("BSP commands must be preceded by \"bsp\""); + + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + +void UpdateBSPCommandList (HWND hwndDlg) +{ + int i; + + SendDlgItemMessage(hwndDlg, IDC_CMD_LIST, LB_RESETCONTENT, 0 , 0); + + i = 0; + int count = g_qeglobals.d_project_entity->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + if (g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[0] == 'b' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[1] == 's' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[2] == 'p') { + SendDlgItemMessage(hwndDlg, IDC_CMD_LIST, LB_ADDSTRING, i , (LPARAM) g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey().c_str()); + i++; + } + } +} + + +// FIXME: turn this into an MFC dialog +BOOL CALLBACK ProjectDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char key[1024]; + char value[1024]; + int index; + + switch (uMsg) + { + case WM_INITDIALOG: + SetDlgItemText(hwndDlg, IDC_PRJBASEPATH, ValueForKey (g_qeglobals.d_project_entity, "basepath")); + SetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, ValueForKey (g_qeglobals.d_project_entity, "mapspath")); + SetDlgItemText(hwndDlg, IDC_PRJRSHCMD, ValueForKey (g_qeglobals.d_project_entity, "rshcmd")); + SetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, ValueForKey (g_qeglobals.d_project_entity, "remotebasepath")); + SetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, ValueForKey (g_qeglobals.d_project_entity, "entitypath")); + SetDlgItemText(hwndDlg, IDC_PRJTEXPATH, ValueForKey (g_qeglobals.d_project_entity, "texturepath")); + UpdateBSPCommandList (hwndDlg); + // Timo + // additional fields + CheckDlgButton( hwndDlg, IDC_CHECK_BPRIMIT, (g_qeglobals.m_bBrushPrimitMode) ? BST_CHECKED : BST_UNCHECKED ); +// SendMessage( ::GetDlgItem( hwndDlg, IDC_CHECK_BPRIMIT ), BM_SETCHECK, (WPARAM) g_qeglobals.m_bBrushPrimitMode, 0 ); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_ADDCMD: +// DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, AddCommandDlgProc); + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, AddCommandDlgProc); + UpdateBSPCommandList (hwndDlg); + break; + + case IDC_EDITCMD: +// DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, EditCommandDlgProc); + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, EditCommandDlgProc); + UpdateBSPCommandList (hwndDlg); + break; + + case IDC_REMCMD: + index = SendDlgItemMessage (hwndDlg, IDC_CMD_LIST, LB_GETCURSEL, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_CMD_LIST, LB_GETTEXT, index, (LPARAM) (LPCTSTR) key); + DeleteKey (g_qeglobals.d_project_entity, key); + common->Printf ("Selected %d\n", index); + UpdateBSPCommandList (hwndDlg); + break; + + case IDOK: + GetDlgItemText(hwndDlg, IDC_PRJBASEPATH, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "basepath", value); + GetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "mapspath", value); + GetDlgItemText(hwndDlg, IDC_PRJRSHCMD, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "rshcmd", value); + GetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "remotebasepath", value); + GetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "entitypath", value); + GetDlgItemText(hwndDlg, IDC_PRJTEXPATH, value, 1024); + SetKeyValue (g_qeglobals.d_project_entity, "texturepath", value); + // Timo + // read additional fields + if ( IsDlgButtonChecked( hwndDlg, IDC_CHECK_BPRIMIT ) ) + { + g_qeglobals.m_bBrushPrimitMode = TRUE; + } + else + { + g_qeglobals.m_bBrushPrimitMode = FALSE; + } + SetKeyValue ( g_qeglobals.d_project_entity, "brush_primit", ( g_qeglobals.m_bBrushPrimitMode ? "1" : "0" ) ); + + EndDialog(hwndDlg, 1); + QE_SaveProject(g_strProject); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + +void DoProjectSettings() +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_PROJECT, g_pParentWnd->GetSafeHwnd(), ProjectDlgProc); +} + + + +BOOL CALLBACK GammaDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char sz[256]; + + switch (uMsg) + { + case WM_INITDIALOG: + sprintf(sz, "%1.1f", g_qeglobals.d_savedinfo.fGamma); + SetWindowText(GetDlgItem(hwndDlg, IDC_G_EDIT), sz); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_G_EDIT), sz, 255); + g_qeglobals.d_savedinfo.fGamma = atof(sz); + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + + + +void DoGamma(void) +{ + if ( DialogBox(g_qeglobals.d_hInstance, (char *)IDD_GAMMA, g_pParentWnd->GetSafeHwnd(), GammaDlgProc)) + { + } +} + +//================================================ + + +void SelectBrush (int entitynum, int brushnum) +{ + entity_t *e; + brush_t *b; + int i; + + if (entitynum == 0) + e = world_entity; + else + { + e = entities.next; + while (--entitynum) + { + e=e->next; + if (e == &entities) + { + Sys_Status ("No such entity.", 0); + return; + } + } + } + + b = e->brushes.onext; + if (b == &e->brushes) + { + Sys_Status ("No such brush.", 0); + return; + } + while (brushnum--) + { + b=b->onext; + if (b == &e->brushes) + { + Sys_Status ("No such brush.", 0); + return; + } + } + + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + + + Sys_UpdateWindows (W_ALL); + for (i=0 ; i<3 ; i++) + { + if (g_pParentWnd->GetXYWnd()) + g_pParentWnd->GetXYWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; + + if (g_pParentWnd->GetXZWnd()) + g_pParentWnd->GetXZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; + + if (g_pParentWnd->GetYZWnd()) + g_pParentWnd->GetYZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; + } + + Sys_Status ("Selected.", 0); +} + +/* +================= +GetSelectionIndex +================= +*/ +void GetSelectionIndex (int *ent, int *brush) +{ + brush_t *b, *b2; + entity_t *entity; + + *ent = *brush = 0; + + b = selected_brushes.next; + if (b == &selected_brushes) + return; + + // find entity + if (b->owner != world_entity) + { + (*ent)++; + for (entity = entities.next ; entity != &entities + ; entity=entity->next, (*ent)++) + ; + } + + // find brush + for (b2=b->owner->brushes.onext + ; b2 != b && b2 != &b->owner->brushes + ; b2=b2->onext, (*brush)++) + ; +} + +BOOL CALLBACK FindBrushDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char entstr[256]; + char brushstr[256]; + HWND h; + int ent, brush; + + switch (uMsg) + { + case WM_INITDIALOG: + // set entity and brush number + GetSelectionIndex (&ent, &brush); + sprintf (entstr, "%i", ent); + sprintf (brushstr, "%i", brush); + SetWindowText(GetDlgItem(hwndDlg, IDC_FIND_ENTITY), entstr); + SetWindowText(GetDlgItem(hwndDlg, IDC_FIND_BRUSH), brushstr); + + h = GetDlgItem(hwndDlg, IDC_FIND_ENTITY); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_FIND_ENTITY), entstr, 255); + GetWindowText(GetDlgItem(hwndDlg, IDC_FIND_BRUSH), brushstr, 255); + SelectBrush (atoi(entstr), atoi(brushstr)); + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + + + +void DoFind(void) +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_FINDBRUSH, g_pParentWnd->GetSafeHwnd(), FindBrushDlgProc); +} + +/* +=================================================== + + ARBITRARY ROTATE + +=================================================== +*/ + + +BOOL CALLBACK RotateDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char str[256]; + HWND h; + float v; + + switch (uMsg) + { + case WM_INITDIALOG: + h = GetDlgItem(hwndDlg, IDC_FIND_ENTITY); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTX), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (0, v); + + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTY), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (1, v); + + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTZ), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (2, v); + + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + + return FALSE; +} + + + +void DoRotate(void) +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ROTATE, g_pParentWnd->GetSafeHwnd(), RotateDlgProc); +} + +/* +=================================================== + + ARBITRARY SIDES + +=================================================== +*/ + +bool g_bDoCone = false; +bool g_bDoSphere = false; +BOOL CALLBACK SidesDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char str[256]; + HWND h; + + switch (uMsg) + { + case WM_INITDIALOG: + h = GetDlgItem(hwndDlg, IDC_SIDES); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_SIDES), str, 255); + if (g_bDoCone) + Brush_MakeSidedCone(atoi(str)); + else if (g_bDoSphere) + Brush_MakeSidedSphere(atoi(str)); + else + Brush_MakeSided (atoi(str)); + + EndDialog(hwndDlg, 1); + break; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + break; + } + default: + return FALSE; + } +} + + +void DoSides(bool bCone, bool bSphere, bool bTorus) +{ + g_bDoCone = bCone; + g_bDoSphere = bSphere; + //g_bDoTorus = bTorus; + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_SIDES, g_pParentWnd->GetSafeHwnd(), SidesDlgProc); +} + + +//====================================================================== + +/* +=================== +DoAbout +=================== +*/ +BOOL CALLBACK AboutDlgProc( HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + char buffer[1024]; + idStr::snPrintf(buffer, 1024, "DOOM Radiant Build %d\nCopyright ©1999-2004 Id Software, Inc.\n", BUILD_NUMBER); +// SetDlgItemText( hwndDlg, IDC_ABOUT_INFO, buffer); + + idStr::snPrintf( buffer, 1024, "Renderer:\t%s", qglGetString( GL_RENDERER ) ); + SetDlgItemText( hwndDlg, IDC_ABOUT_GLRENDERER, buffer ); + + idStr::snPrintf( buffer, 1024, "Version:\t\t%s", qglGetString( GL_VERSION ) ); + SetDlgItemText( hwndDlg, IDC_ABOUT_GLVERSION, buffer ); + + idStr::snPrintf( buffer, 1024, "Vendor:\t\t%s", qglGetString( GL_VENDOR ) ); + SetDlgItemText( hwndDlg, IDC_ABOUT_GLVENDOR, buffer); + + char extensions[4096]; + idStr::snPrintf( extensions, 4096, "%s", qglGetString( GL_EXTENSIONS ) ); + HWND hWndExtensions = GetDlgItem( hwndDlg, IDC_ABOUT_GLEXTENSIONS ); + + char *start = extensions; + char *end; + do { + end = strchr(start, ' '); + if ( end ) { + *end = 0; + } + SendMessage( hWndExtensions, LB_ADDSTRING, 0, (LPARAM)start ); + start = end + 1; + } while ( end ); + } + + return TRUE; + + case WM_CLOSE: + EndDialog( hwndDlg, 1 ); + return TRUE; + + case WM_COMMAND: + if ( LOWORD( wParam ) == IDOK ) + EndDialog(hwndDlg, 1); + return TRUE; + } + return FALSE; +} + +void DoAbout(void) +{ + DialogBox( g_qeglobals.d_hInstance, ( char * ) IDD_ABOUT, g_pParentWnd->GetSafeHwnd(), AboutDlgProc ); +} + + diff --git a/tools/radiant/WIN_QE3.CPP b/tools/radiant/WIN_QE3.CPP new file mode 100644 index 000000000..652cd54cc --- /dev/null +++ b/tools/radiant/WIN_QE3.CPP @@ -0,0 +1,499 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "mru.h" + +extern CEdit *g_pEdit; + +int screen_width; +int screen_height; +bool have_quit; + +int update_bits; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Sys_MarkMapModified(void) { + idStr title; + + if (mapModified != 1) { + mapModified = 1; // mark the map as changed + title = currentmap; + title += " *"; + title.BackSlashesToSlashes(); + Sys_SetTitle(title); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Sys_SetTitle(const char *text) { + g_pParentWnd->SetWindowText(va("%s: %s",EDITOR_WINDOWTEXT, text)); +} + +/* + ======================================================================================================================= + Wait Functions + ======================================================================================================================= + */ +HCURSOR waitcursor; + +void Sys_BeginWait(void) { + waitcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); +} + +bool Sys_Waiting() { + return (waitcursor != NULL); +} + +void Sys_EndWait(void) { + if (waitcursor) { + SetCursor(waitcursor); + waitcursor = NULL; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Sys_GetCursorPos(int *x, int *y) { + POINT lpPoint; + + GetCursorPos(&lpPoint); + *x = lpPoint.x; + *y = lpPoint.y; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Sys_SetCursorPos(int x, int y) { + SetCursorPos(x, y); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Sys_Beep(void) { + MessageBeep(MB_ICONASTERISK); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +char *TranslateString(char *buf) { + static char buf2[32768]; + int i, l; + char *out; + + l = strlen(buf); + out = buf2; + for (i = 0; i < l; i++) { + if (buf[i] == '\n') { + *out++ = '\r'; + *out++ = '\n'; + } + else { + *out++ = buf[i]; + } + } + + *out++ = 0; + + return buf2; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +double Sys_DoubleTime(void) { + return clock() / 1000.0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void PrintPixels(HDC hDC) { + int i; + PIXELFORMATDESCRIPTOR p[64]; + + printf("### flags color layer\n"); + for (i = 1; i < 64; i++) { + if (!DescribePixelFormat(hDC, i, sizeof(p[0]), &p[i])) { + break; + } + + printf("%3i %5i %5i %5i\n", i, p[i].dwFlags, p[i].cColorBits, p[i].bReserved); + } + + printf("%i modes\n", i - 1); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int WINAPI QEW_SetupPixelFormat(HDC hDC, bool zbuffer) +{ +#if 1 + + int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd); + if (pixelFormat > 0) { + if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) { + Error("SetPixelFormat failed."); + } + } + else { + Error("ChoosePixelFormat failed."); + } + + return pixelFormat; +#else + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, + 0, + 0, + 0, + 0, + 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, + 0, + 0, + 0, // accum bits ignored + 32, // depth bits + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, + 0, + 0 // layer masks ignored + }; + int pixelformat = 0; + + zbuffer = true; + if (!zbuffer) { + pfd.cDepthBits = 0; + } + + if ((pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0) { + printf("%d", GetLastError()); + Error("ChoosePixelFormat failed"); + } + + if (!SetPixelFormat(hDC, pixelformat, &pfd)) { + Error("SetPixelFormat failed"); + } + + return pixelformat; +#endif +} + +/* + ======================================================================================================================= + Error For abnormal program terminations + ======================================================================================================================= + */ +void Error(char *error, ...) { + va_list argptr; + char text[1024]; + char text2[1024]; + int err; + + err = GetLastError(); + + int i = qglGetError(); + + va_start(argptr, error); + vsprintf(text, error, argptr); + va_end(argptr); + + sprintf + ( + text2, + "%s\nGetLastError() = %i - %i\nAn unrecoverable error has occured. Would you like to edit Preferences before exiting Q3Radiant?", + text, + err, + i + ); + + if (g_pParentWnd->MessageBox(text2, "Error", MB_YESNO) == IDYES) { + g_PrefsDlg.LoadPrefs(); + g_PrefsDlg.DoModal(); + } + + common->FatalError( text ); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Warning(char *error, ...) { + va_list argptr; + char text[1024]; + int err; + + err = GetLastError(); + + int i = qglGetError(); + + va_start(argptr, error); + vsprintf(text, error, argptr); + va_end(argptr); + + common->Printf(text); +} + +/* + ======================================================================================================================= + FILE DIALOGS + ======================================================================================================================= + */ +bool ConfirmModified(void) { + if (!mapModified) { + return true; + } + + if (g_pParentWnd->MessageBox("This will lose changes to the map", "warning", MB_OKCANCEL) == IDCANCEL) { + return false; + } + + return true; +} + +static OPENFILENAME ofn; /* common dialog box structure */ +static char szDirName[MAX_PATH]; /* directory string */ +static char szFile[260]; /* filename string */ +static char szFileTitle[260]; /* file title string */ +static char szFilter[260] = /* filter string */ +"Map file (*.map, *.reg)\0*.map;*.reg\0"; +static char szProjectFilter[260] = /* filter string */ +"Q3Radiant project (*.qe4, *.prj)\0*.qe4\0*.prj\0\0"; +static char chReplace; /* string separator for szFilter */ +static int i, cbString; /* integer count variables */ +static HANDLE hf; /* file handle */ + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void OpenDialog(void) { + /* Obtain the system directory name and store it in szDirName. */ + strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "mapspath")); + if (strlen(szDirName) == 0) { + strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath")); + strcat(szDirName, "\\maps"); + } + + if (g_PrefsDlg.m_strMaps.GetLength() > 0) { + strcat(szDirName, va("\\%s", g_PrefsDlg.m_strMaps)); + } + + /* Place the terminating null character in the szFile. */ + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = g_pParentWnd->GetSafeHwnd(); + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + /* Display the Open dialog box. */ + if (!GetOpenFileName(&ofn)) { + return; // canceled + } + + // Add the file in MRU. FIXME + AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile); + + // Refresh the File menu. FIXME + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT); + + /* Open the file. */ + Map_LoadFile(ofn.lpstrFile); + + g_PrefsDlg.SavePrefs(); + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ProjectDialog(void) { + /* Obtain the system directory name and store it in szDirName. */ + strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath")); + + /* Place the terminating null character in the szFile. */ + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = g_pParentWnd->GetSafeHwnd(); + ofn.lpstrFilter = szProjectFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + /* Display the Open dialog box. */ + if (!GetOpenFileName(&ofn)) { + return; // canceled + } + + // Refresh the File menu. + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT); + + /* Open the file. */ + if (!QE_LoadProject(ofn.lpstrFile)) { + Error("Couldn't load project file"); + } +} + +extern void AddSlash(CString &strPath); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SaveAsDialog(bool bRegion) { + strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath")); + + CString strPath = szDirName; + AddSlash(strPath); + strPath += "maps"; + if (g_PrefsDlg.m_strMaps.GetLength() > 0) { + strPath += va("\\%s", g_PrefsDlg.m_strMaps); + } + + /* Place the terminating null character in the szFile. */ + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = g_pParentWnd->GetSafeHwnd(); + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = strPath; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT; + + /* Display the Open dialog box. */ + if (!GetSaveFileName(&ofn)) { + return; // canceled + } + + if (bRegion) { + DefaultExtension(ofn.lpstrFile, ".reg"); + } + else { + DefaultExtension(ofn.lpstrFile, ".map"); + } + + if (!bRegion) { + strcpy(currentmap, ofn.lpstrFile); + AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile); + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT); + } + + Map_SaveFile(ofn.lpstrFile, bRegion); // ignore region +} + +/* + * Menu modifications £ + * FillBSPMenu + */ +const char *bsp_commands[256]; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void FillBSPMenu(void) { + HMENU hmenu; + int i; + static int count; + + hmenu = GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), MENU_BSP); + + for (i = 0; i < count; i++) { + DeleteMenu(hmenu, CMD_BSPCOMMAND + i, MF_BYCOMMAND); + } + + i = 0; + count = g_qeglobals.d_project_entity->epairs.GetNumKeyVals(); + for (int j = 0; j < count; j++) { + if (g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[0] == 'b' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[1] == 's' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[2] == 'p') { + bsp_commands[i] = g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey().c_str(); + AppendMenu(hmenu, MF_ENABLED | MF_STRING, CMD_BSPCOMMAND + i, (LPCTSTR) g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey().c_str()); + i++; + } + } + + count = i; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void AddSlash(CString &strPath) { + if (strPath.GetLength() > 0) { + if (strPath.GetAt(strPath.GetLength() - 1) != '\\') { + strPath += '\\'; + } + } +} diff --git a/tools/radiant/WIN_QE3.RC2 b/tools/radiant/WIN_QE3.RC2 new file mode 100644 index 000000000..06dab11e8 --- /dev/null +++ b/tools/radiant/WIN_QE3.RC2 @@ -0,0 +1,693 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New", ID_FILE_NEW + MENUITEM "&Open", ID_FILE_OPEN + MENUITEM "&Save", ID_FILE_SAVE + MENUITEM "Save &as...", ID_FILE_SAVEAS + MENUITEM "&Pointfile", ID_FILE_POINTFILE + MENUITEM "Load &project", ID_FILE_LOADPROJECT + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Copy brush", ID_EDIT_COPYBRUSH, GRAYED + MENUITEM "&Paste brush", ID_EDIT_PASTEBRUSH, GRAYED + END + POPUP "&View" + BEGIN + MENUITEM "Texture View\tT", ID_VIEW_TEXTURE + MENUITEM "Console View\tO", ID_VIEW_CONSOLE + MENUITEM "Entity View\tN", ID_VIEW_ENTITY + MENUITEM SEPARATOR + MENUITEM "&Center\tEnd", ID_VIEW_CENTER + MENUITEM "&Up Floor\tPage Up", ID_VIEW_UPFLOOR + MENUITEM "&Down Floor\tPage Down", ID_VIEW_DOWNFLOOR + MENUITEM SEPARATOR + MENUITEM "&XY 100%", ID_VIEW_100 + MENUITEM "XY Zoom &In\tDelete", ID_VIEW_ZOOMIN + MENUITEM "XY Zoom &Out\tInsert", ID_VIEW_ZOOMOUT + MENUITEM SEPARATOR + MENUITEM "Show &Names", ID_VIEW_SHOWNAMES, CHECKED + MENUITEM "Show Blocks", ID_VIEW_SHOWBLOCKS + MENUITEM "Show C&oordinates", ID_VIEW_SHOWCOORDINATES + , CHECKED + MENUITEM "Show &Entities", ID_VIEW_SHOWENT, CHECKED + MENUITEM "Show &Path", ID_VIEW_SHOWPATH, CHECKED + MENUITEM "Show &Lights", ID_VIEW_SHOWLIGHTS, CHECKED + MENUITEM "Show &Water", ID_VIEW_SHOWWATER, CHECKED + MENUITEM "Show Clip &Brush", ID_VIEW_SHOWCLIP, CHECKED + MENUITEM "Show Wor&ld", ID_VIEW_SHOWWORLD, CHECKED + MENUITEM "Show Detail\tctrl-D", ID_VIEW_SHOWDETAIL, CHECKED + MENUITEM SEPARATOR + MENUITEM "&Z 100%", ID_VIEW_Z100 + MENUITEM "Z Zoo&m In\tctrl-Delete", ID_VIEW_ZZOOMIN + MENUITEM "Z Zoom O&ut\tctrl-Insert", ID_VIEW_ZZOOMOUT + END + POPUP "&Selection" + BEGIN + MENUITEM "Drag &Edges\tE", ID_SELECTION_DRAGEDGES + MENUITEM "Drag &Vertecies\tV", ID_SELECTION_DRAGVERTECIES + MENUITEM "&Clone\tspace", ID_SELECTION_CLONE + MENUITEM "Deselect\tEsc", ID_SELECTION_DESELECT + MENUITEM "&Delete\tBackspace", ID_SELECTION_DELETE + MENUITEM "Flip &X", ID_BRUSH_FLIPX + MENUITEM "Flip &Y", ID_BRUSH_FLIPY + MENUITEM "Flip &Z", ID_BRUSH_FLIPZ + MENUITEM "Rotate X", ID_BRUSH_ROTATEX + MENUITEM "Rotate Y", ID_BRUSH_ROTATEY + MENUITEM "Rotate Z", ID_BRUSH_ROTATEZ + MENUITEM "Arbitrary rotation", ID_SELECTION_ARBITRARYROTATION + + MENUITEM "Make &Hollow", ID_SELECTION_MAKEHOLLOW + MENUITEM "CSG &Subtract", ID_SELECTION_CSGSUBTRACT + MENUITEM "Select Complete &Tall", ID_SELECTION_SELECTCOMPLETETALL + + MENUITEM "Select T&ouching", ID_SELECTION_SELECTTOUCHING + MENUITEM "Select &Partial Tall", ID_SELECTION_SELECTPARTIALTALL + + MENUITEM "Select &Inside", ID_SELECTION_SELECTINSIDE + MENUITEM "Connect entities\tCtrl-k", ID_SELECTION_CONNECT + MENUITEM "Ungroup entity", ID_SELECTION_UNGROUPENTITY + MENUITEM "Make detail\tCtrl-m", ID_SELECTION_MAKE_DETAIL + MENUITEM "Make structural", ID_SELECTION_MAKE_STRUCTURAL + END + POPUP "&Bsp" + BEGIN + MENUITEM SEPARATOR + END + POPUP "&Grid" + BEGIN + MENUITEM "Grid1\t&1", ID_GRID_1 + MENUITEM "Grid2\t&2", ID_GRID_2 + MENUITEM "Grid4\t&3", ID_GRID_4 + MENUITEM "Grid8\t&4", ID_GRID_8, CHECKED + MENUITEM "Grid16\t&5", ID_GRID_16 + MENUITEM "Grid32\t&6", ID_GRID_32 + MENUITEM "Grid64\t&7", ID_GRID_64 + END + POPUP "&Textures" + BEGIN + MENUITEM "Show In &Use\tU", ID_TEXTURES_SHOWINUSE + MENUITEM "&Surface inspector\tS", ID_TEXTURES_INSPECTOR + MENUITEM SEPARATOR + MENUITEM "&Wireframe", ID_TEXTURES_WIREFRAME + MENUITEM "&Flat shade", ID_TEXTURES_FLATSHADE + MENUITEM "&Nearest", ID_VIEW_NEAREST + MENUITEM "Nearest &Mipmap", ID_VIEW_NEARESTMIPMAP + MENUITEM "&Linear", ID_VIEW_LINEAR + MENUITEM "&Bilinear", ID_VIEW_BILINEAR + MENUITEM "B&ilinear Mipmap", ID_VIEW_BILINEARMIPMAP + MENUITEM "T&rilinear", ID_VIEW_TRILINEAR + MENUITEM SEPARATOR + END + POPUP "&Misc" + BEGIN + MENUITEM "&Benchmark", ID_MISC_BENCHMARK + POPUP "&Colors" + BEGIN + MENUITEM "&Texture Background", ID_TEXTUREBK + MENUITEM "Grid Background", ID_COLORS_XYBK + MENUITEM "Grid Major", ID_COLORS_MAJOR + MENUITEM "Grid Minor", ID_COLORS_MINOR + END + MENUITEM "&Gamma", ID_MISC_GAMMA + MENUITEM "Find brush", ID_MISC_FINDBRUSH + MENUITEM "Next leak spot\tctrl-l", ID_MISC_NEXTLEAKSPOT + MENUITEM "Previous leak spot\tctrl-p", ID_MISC_PREVIOUSLEAKSPOT + MENUITEM "&Print XY View", ID_MISC_PRINTXY + MENUITEM "&Select Entity Color\tK", ID_MISC_SELECTENTITYCOLOR + END + POPUP "&Region" + BEGIN + MENUITEM "&Off", ID_REGION_OFF + MENUITEM "&Set XY", ID_REGION_SETXY + MENUITEM "Set &Tall Brush", ID_REGION_SETTALLBRUSH + MENUITEM "Set &Brush", ID_REGION_SETBRUSH + MENUITEM "Set Se&lected Brushes", ID_REGION_SETSELECTION + END + POPUP "&Brush" + BEGIN + MENUITEM "3 sided\tctrl-3", ID_BRUSH_3SIDED + MENUITEM "4 sided\tctrl-4", ID_BRUSH_4SIDED + MENUITEM "5 sided\tctrl-5", ID_BRUSH_5SIDED + MENUITEM "6 sided\tctrl-6", ID_BRUSH_6SIDED + MENUITEM "7 sided\tctrl-7", ID_BRUSH_7SIDED + MENUITEM "8 sided\tctrl-8", ID_BRUSH_8SIDED + MENUITEM "9 sided\tctrl-9", ID_BRUSH_9SIDED + MENUITEM "Arbitrary sided", ID_BRUSH_ARBITRARYSIDED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_HELP_ABOUT + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FINDTEXTURE DIALOG DISCARDABLE 0, 0, 129, 53 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Find Texture" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,10,30,50,14 + PUSHBUTTON "Cancel",IDCANCEL,70,30,50,14 + EDITTEXT IDC_EDIT1,10,10,110,14,ES_AUTOHSCROLL +END + +IDD_ENTITY DIALOGEX 0, 0, 234, 389 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | + WS_CAPTION | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE +CAPTION "Entity" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + LISTBOX IDC_E_LIST,5,5,180,99,LBS_SORT | LBS_NOINTEGRALHEIGHT | + LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP, + WS_EX_CLIENTEDGE + EDITTEXT IDC_E_COMMENT,5,106,180,50,ES_MULTILINE | ES_READONLY | + WS_VSCROLL,WS_EX_CLIENTEDGE + PUSHBUTTON "135",IDC_E_135,5,290,15,15 + PUSHBUTTON "180",IDC_E_180,5,305,15,15 + PUSHBUTTON "225",IDC_E_225,5,320,15,15 + PUSHBUTTON "270",IDC_E_270,21,320,15,15 + PUSHBUTTON "90",IDC_E_90,21,290,15,15 + PUSHBUTTON "45",IDC_E_45,35,290,15,15 + PUSHBUTTON "0",IDC_E_0,35,305,15,15 + PUSHBUTTON "315",IDC_E_315,35,320,15,15 + PUSHBUTTON "Up",IDC_E_UP,60,295,15,15 + PUSHBUTTON "Dn",IDC_E_DOWN,60,310,15,15 + CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,160,50,8 + CONTROL "",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,170,50,8 + CONTROL "",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,180,50,8 + CONTROL "",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,190,50,8 + CONTROL "",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,160,50,8 + CONTROL "",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,170,50,8 + CONTROL "",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,180,50,8 + CONTROL "",IDC_CHECK8,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,190,50,8 + CONTROL "!Easy",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 125,160,50,8 + CONTROL "!Medium",IDC_CHECK10,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,170,50,8 + CONTROL "!Hard",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,180,50,10 + CONTROL "!DeathMatch",IDC_CHECK12,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,190,55,10 + LISTBOX IDC_E_PROPS,5,205,180,50,LBS_SORT | LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT | + WS_VSCROLL | WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "Del Key/Pair",IDC_E_DELPROP,105,295,45,15 + EDITTEXT IDC_E_STATUS,83,312,95,30,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL + LTEXT "Key",IDC_STATIC_KEY,5,260,25,10 + LTEXT "Value",IDC_STATIC_VALUE,5,275,25,10 + EDITTEXT IDC_E_KEY_FIELD,40,260,135,14,ES_AUTOHSCROLL + EDITTEXT IDC_E_VALUE_FIELD,40,275,135,14,ES_AUTOHSCROLL +END + +IDD_GAMMA DIALOGEX 0, 0, 127, 76 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Gamma" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,10,40,50,14 + PUSHBUTTON "Cancel",IDCANCEL,65,40,50,14 + EDITTEXT IDC_G_EDIT,30,15,66,13,ES_AUTOHSCROLL,WS_EX_CLIENTEDGE +END + +IDD_FINDBRUSH DIALOGEX 0, 0, 127, 76 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Find brush" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,5,55,50,14 + PUSHBUTTON "Cancel",IDCANCEL,65,55,50,14 + EDITTEXT IDC_FIND_ENTITY,80,15,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + EDITTEXT IDC_FIND_BRUSH,80,30,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + LTEXT "Entity number",IDC_STATIC,10,15,60,8 + LTEXT "Brush number",IDC_STATIC,10,30,65,8 +END + +IDD_ROTATE DIALOG DISCARDABLE 0, 0, 186, 71 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrary rotation" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + EDITTEXT IDC_ROTX,30,5,40,14,ES_AUTOHSCROLL + LTEXT "x",IDC_STATIC,5,10,8,8 + EDITTEXT IDC_ROTZ,30,45,40,14,ES_AUTOHSCROLL + LTEXT "y",IDC_STATIC,5,25,8,8 + EDITTEXT IDC_ROTY,30,25,40,14,ES_AUTOHSCROLL + LTEXT "z",IDC_STATIC,5,45,8,8 +END + +IDD_SIDES DIALOG DISCARDABLE 0, 0, 186, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrrary sides" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + EDITTEXT IDC_SIDES,50,15,40,14,ES_AUTOHSCROLL + LTEXT "Sides",IDC_STATIC,15,15,18,8 +END + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 274, 212 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About QuakeEd" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,217,7,50,14 + CONTROL 127,IDC_STATIC,"Static",SS_BITMAP,7,7,83,58 + CONTROL "QuakeEd 4.0(beta)\nCopyright (C) 1997 id Software, Inc.", + IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,100,10, + 110,23 + GROUPBOX "OpenGL Properties",IDC_STATIC,5,75,265,50 + LTEXT "Vendor:\t\tWHOEVER",IDC_ABOUT_GLVENDOR,10,90,125,10 + LTEXT "Version:\t\t1.1",IDC_ABOUT_GLVERSION,10,100,125,10 + LTEXT "Renderer:\tWHATEVER",IDC_ABOUT_GLRENDERER,10,110,125,10 + LTEXT "WHATEVER",IDC_ABOUT_GLEXTENSIONS,10,140,255,60 + GROUPBOX "OpenGL Extensions",IDC_STATIC,5,130,265,80 +END + +IDD_SURFACE DIALOG DISCARDABLE 400, 100, 392, 181 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Surface inspector" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,5,155,40,14 + PUSHBUTTON "Cancel",IDCANCEL,105,155,40,14 + EDITTEXT IDC_HSHIFT,85,45,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_HSHIFTA,120,45,10,15,SBS_VERT + LTEXT "Horizontal shift",IDC_STATIC,10,45,65,8 + LTEXT "Vertical shift",IDC_STATIC,10,60,65,8 + LTEXT "Horizontal stretch",IDC_STATIC,10,75,65,8 + LTEXT "Vertical stretch",IDC_STATIC,10,90,65,8 + LTEXT "Rotate",IDC_STATIC,10,105,65,8 + LTEXT "value",IDC_STATIC,10,120,65,8 + EDITTEXT IDC_VSHIFT,85,60,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_VSHIFTA,120,60,10,15,SBS_VERT + EDITTEXT IDC_HSCALE,85,75,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_HSCALEA,120,75,10,15,SBS_VERT + EDITTEXT IDC_VSCALE,85,90,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_VSCALEA,120,90,10,15,SBS_VERT + EDITTEXT IDC_ROTATE,85,105,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_ROTATEA,120,105,10,15,SBS_VERT + EDITTEXT IDC_VALUE,85,120,35,15,ES_AUTOHSCROLL + EDITTEXT IDC_TEXTURE,50,15,80,14,ES_AUTOHSCROLL + CONTROL "light",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,10,41,8 + CONTROL "slick",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,20,41,8 + CONTROL "sky",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,30,41,8 + CONTROL "warp",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,40,41,8 + CONTROL "trans33",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,50,41,8 + CONTROL "trans66",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,60,41,8 + CONTROL "flowing",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,70,41,8 + CONTROL "nodraw",IDC_CHECK8,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,80,41,8 + CONTROL "100",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,90,41,8 + CONTROL "200",IDC_CHECK10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,100,41,8 + CONTROL "400",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,110,41,8 + CONTROL "800",IDC_CHECK12,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,120,41,8 + CONTROL "1000",IDC_CHECK13,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,130,41,8 + CONTROL "2000",IDC_CHECK14,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,140,41,8 + CONTROL "4000",IDC_CHECK15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,150,41,8 + CONTROL "8000",IDC_CHECK16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,160,41,8 + LTEXT "Texture",IDC_STATIC,10,18,30,8 + PUSHBUTTON "Apply",IDAPPLY,55,155,40,14 + CONTROL "10000",IDC_CHECK17,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,10,41,8 + CONTROL "20000",IDC_CHECK18,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,20,41,8 + CONTROL "40000",IDC_CHECK19,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,30,41,8 + CONTROL "80000",IDC_CHECK20,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,40,41,8 + CONTROL "100000",IDC_CHECK21,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,50,41,8 + CONTROL "200000",IDC_CHECK22,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,60,41,8 + CONTROL "400000",IDC_CHECK23,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,70,41,8 + CONTROL "800000",IDC_CHECK24,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,80,41,8 + CONTROL "1000000",IDC_CHECK25,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,90,41,8 + CONTROL "2000000",IDC_CHECK26,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,100,41,8 + CONTROL "4000000",IDC_CHECK27,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,110,41,8 + CONTROL "8000000",IDC_CHECK28,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,120,41,8 + CONTROL "10000000",IDC_CHECK29,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,130,40,8 + CONTROL "20000000",IDC_CHECK30,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,140,45,8 + CONTROL "40000000",IDC_CHECK31,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,150,45,8 + CONTROL "80000000",IDC_CHECK32,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,160,45,8 + CONTROL "solid",IDC_CHECK33,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,10,41,8 + CONTROL "window",IDC_CHECK34,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,20,41,8 + CONTROL "aux",IDC_CHECK35,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,31,41,8 + CONTROL "lava",IDC_CHECK36,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,41,41,8 + CONTROL "slime",IDC_CHECK37,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,50,41,8 + CONTROL "water",IDC_CHECK38,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,60,41,8 + CONTROL "mist",IDC_CHECK39,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,71,41,8 + CONTROL "80",IDC_CHECK40,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,81,41,8 + CONTROL "100",IDC_CHECK41,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,90,41,8 + CONTROL "200",IDC_CHECK42,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,100,41,8 + CONTROL "400",IDC_CHECK43,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,111,41,8 + CONTROL "800",IDC_CHECK44,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,121,41,8 + CONTROL "1000",IDC_CHECK45,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,130,41,8 + CONTROL "2000",IDC_CHECK46,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,140,41,8 + CONTROL "4000",IDC_CHECK47,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,151,41,8 + CONTROL "8000",IDC_CHECK48,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,161,41,8 + CONTROL "playerclip",IDC_CHECK49,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,10,41,8 + CONTROL "monsterclip",IDC_CHECK50,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,20,50,8 + CONTROL "current_0",IDC_CHECK51,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,31,50,8 + CONTROL "current_90",IDC_CHECK52,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,41,50,8 + CONTROL "current_180",IDC_CHECK53,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,50,50,8 + CONTROL "current_270",IDC_CHECK54,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,60,50,8 + CONTROL "current_up",IDC_CHECK55,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,71,50,8 + CONTROL "current_dn",IDC_CHECK56,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,81,50,8 + CONTROL "origin",IDC_CHECK57,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,90,41,8 + CONTROL "monster",IDC_CHECK58,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,100,41,8 + CONTROL "corpse",IDC_CHECK59,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,111,41,8 + CONTROL "detail",IDC_CHECK60,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,121,41,8 + CONTROL "translucent",IDC_CHECK61,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,130,50,8 + CONTROL "ladder",IDC_CHECK62,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,140,45,8 + CONTROL "40000000",IDC_CHECK63,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,151,45,8 + CONTROL "80000000",IDC_CHECK64,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,161,45,8 + GROUPBOX "Surf flags",IDC_STATIC,150,0,115,175 + GROUPBOX "Content flags",IDC_STATIC,270,0,115,175 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Id Software\0" + VALUE "FileDescription", "qe3\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "qe3\0" + VALUE "LegalCopyright", "Copyright © 1996\0" + VALUE "OriginalFilename", "qe3.exe\0" + VALUE "ProductName", "Id Software qe3\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "3", ID_BRUSH_3SIDED, VIRTKEY, CONTROL, NOINVERT + "4", ID_BRUSH_4SIDED, VIRTKEY, CONTROL, NOINVERT + "5", ID_BRUSH_5SIDED, VIRTKEY, CONTROL, NOINVERT + "6", ID_BRUSH_6SIDED, VIRTKEY, CONTROL, NOINVERT + "7", ID_BRUSH_7SIDED, VIRTKEY, CONTROL, NOINVERT + "8", ID_BRUSH_8SIDED, VIRTKEY, CONTROL, NOINVERT + "9", ID_BRUSH_9SIDED, VIRTKEY, CONTROL, NOINVERT + "D", ID_VIEW_SHOWDETAIL, VIRTKEY, CONTROL, NOINVERT + "K", ID_SELECTION_CONNECT, VIRTKEY, CONTROL, NOINVERT + "L", ID_MISC_NEXTLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "M", ID_SELECTION_MAKE_DETAIL, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", ID_MISC_PREVIOUSLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_VIEW_ZZOOMIN, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, ID_VIEW_ZZOOMOUT, VIRTKEY, CONTROL, NOINVERT + "X", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_TOOLBAR1 TOOLBAR DISCARDABLE 16, 15 +BEGIN + BUTTON ID_BRUSH_FLIPX + BUTTON ID_BRUSH_ROTATEX + BUTTON ID_BRUSH_FLIPY + BUTTON ID_BRUSH_ROTATEY + BUTTON ID_BRUSH_FLIPZ + BUTTON ID_BRUSH_ROTATEZ + BUTTON ID_SELECTION_SELECTCOMPLETETALL + BUTTON ID_SELECTION_SELECTTOUCHING + BUTTON ID_SELECTION_SELECTPARTIALTALL + BUTTON ID_SELECTION_SELECTINSIDE + BUTTON ID_SELECTION_CSGSUBTRACT + BUTTON ID_SELECTION_MAKEHOLLOW + BUTTON ID_TEXTURES_WIREFRAME + BUTTON ID_TEXTURES_FLATSHADE + BUTTON ID_VIEW_TRILINEAR +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_TOOLBAR1 BITMAP DISCARDABLE "toolbar1.bmp" +IDB_BITMAP1 BITMAP DISCARDABLE "q.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ENTITY, DIALOG + BEGIN + RIGHTMARGIN, 227 + BOTTOMMARGIN, 387 + END + + IDD_GAMMA, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 120 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END + + IDD_FINDBRUSH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 120 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END + + IDD_ROTATE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_SIDES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 267 + TOPMARGIN, 7 + BOTTOMMARGIN, 205 + END + + IDD_SURFACE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 385 + TOPMARGIN, 7 + BOTTOMMARGIN, 174 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "icon1.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tools/radiant/WaitDlg.cpp b/tools/radiant/WaitDlg.cpp new file mode 100644 index 000000000..ea67b2857 --- /dev/null +++ b/tools/radiant/WaitDlg.cpp @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "WaitDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CWaitDlg dialog + + +CWaitDlg::CWaitDlg(CWnd* pParent, const char *msg) + : CDialog(CWaitDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CWaitDlg) + waitStr = msg; + //}}AFX_DATA_INIT + cancelPressed = false; + Create(CWaitDlg::IDD); + //g_pParentWnd->SetBusy(true); +} + +CWaitDlg::~CWaitDlg() { + g_pParentWnd->SetBusy(false); +} + +void CWaitDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CWaitDlg) + DDX_Text(pDX, IDC_WAITSTR, waitStr); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CWaitDlg, CDialog) + //{{AFX_MSG_MAP(CWaitDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CWaitDlg message handlers + +BOOL CWaitDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + //GetDlgItem(IDC_WAITSTR)->SetWindowText(waitStr); + GetDlgItem(IDC_WAITSTR)->SetFocus(); + UpdateData(FALSE); + ShowWindow(SW_SHOW); + + // cancel disabled by default + AllowCancel( false ); + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CWaitDlg::SetText(const char *msg, bool append) { + if (append) { + waitStr = text; + waitStr += "\r\n"; + waitStr += msg; + } else { + waitStr = msg; + text = msg; + } + UpdateData(FALSE); + Invalidate(); + UpdateWindow(); + ShowWindow (SW_SHOWNORMAL); +} + +void CWaitDlg::AllowCancel( bool enable ) { + // this shows or hides the Cancel button + CWnd* pCancelButton = GetDlgItem (IDCANCEL); + ASSERT (pCancelButton); + if ( enable ) { + pCancelButton->ShowWindow (SW_NORMAL); + } else { + pCancelButton->ShowWindow (SW_HIDE); + } +} + +bool CWaitDlg::CancelPressed( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } + + return cancelPressed; +} + +void CWaitDlg::OnCancel() { + cancelPressed = true; +} diff --git a/tools/radiant/WaitDlg.h b/tools/radiant/WaitDlg.h new file mode 100644 index 000000000..4e360bae6 --- /dev/null +++ b/tools/radiant/WaitDlg.h @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_) +#define AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// WaitDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CWaitDlg dialog + +class CWaitDlg : public CDialog +{ +// Construction +public: + CWaitDlg(CWnd* pParent = NULL, const char *msg = "Wait..."); // standard constructor + ~CWaitDlg(); + void SetText(const char *msg, bool append = false); + void AllowCancel( bool enable ); + bool CancelPressed( void ); + +// Dialog Data + //{{AFX_DATA(CWaitDlg) + enum { IDD = IDD_DLG_WAIT }; + CString waitStr; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CWaitDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CWaitDlg) + virtual BOOL OnInitDialog(); + virtual void OnCancel(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +private: + idStr text; + bool cancelPressed; +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_) diff --git a/tools/radiant/WaveOpen.cpp b/tools/radiant/WaveOpen.cpp new file mode 100644 index 000000000..6a73507b8 --- /dev/null +++ b/tools/radiant/WaveOpen.cpp @@ -0,0 +1,96 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "WaveOpen.h" +#include "mmsystem.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CWaveOpen + +IMPLEMENT_DYNAMIC(CWaveOpen, CFileDialog) + +CWaveOpen::CWaveOpen(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName, + DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) : + CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd) +{ + m_ofn.Flags |= (OFN_EXPLORER | OFN_ENABLETEMPLATE); + m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_PLAYWAVE); +} + + +BEGIN_MESSAGE_MAP(CWaveOpen, CFileDialog) + //{{AFX_MSG_MAP(CWaveOpen) + ON_BN_CLICKED(IDC_BTN_PLAY, OnBtnPlay) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +void CWaveOpen::OnFileNameChange() +{ + CString str = GetPathName(); + str.MakeLower(); + CWnd *pWnd = GetDlgItem(IDC_BTN_PLAY); + if (pWnd == NULL) + { + return; + } + if (str.Find(".wav") >= 0) + { + pWnd->EnableWindow(TRUE); + } + else + { + pWnd->EnableWindow(FALSE); + } +} + +void CWaveOpen::OnBtnPlay() +{ + sndPlaySound(NULL, NULL); + CString str = GetPathName(); + if (str.GetLength() > 0) + { + sndPlaySound(str, SND_FILENAME | SND_ASYNC); + } +} + +BOOL CWaveOpen::OnInitDialog() +{ + CFileDialog::OnInitDialog(); + + CWnd *pWnd = GetDlgItem(IDC_BTN_PLAY); + if (pWnd != NULL) + { + pWnd->EnableWindow(FALSE); + } + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/tools/radiant/WaveOpen.h b/tools/radiant/WaveOpen.h new file mode 100644 index 000000000..889d878d7 --- /dev/null +++ b/tools/radiant/WaveOpen.h @@ -0,0 +1,55 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_WAVEOPEN_H__0FB9DA11_EB02_11D2_A50A_0020AFEB881A__INCLUDED_) +#define AFX_WAVEOPEN_H__0FB9DA11_EB02_11D2_A50A_0020AFEB881A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// WaveOpen.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CWaveOpen dialog + +class CWaveOpen : public CFileDialog +{ + DECLARE_DYNAMIC(CWaveOpen) + +public: + CWaveOpen(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + LPCTSTR lpszFilter = NULL, + CWnd* pParentWnd = NULL); + + virtual void OnFileNameChange( ); +protected: + //{{AFX_MSG(CWaveOpen) + afx_msg void OnBtnPlay(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_WAVEOPEN_H__0FB9DA11_EB02_11D2_A50A_0020AFEB881A__INCLUDED_) diff --git a/tools/radiant/XYWnd.cpp b/tools/radiant/XYWnd.cpp new file mode 100644 index 000000000..57dfae518 --- /dev/null +++ b/tools/radiant/XYWnd.cpp @@ -0,0 +1,4560 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "XYWnd.h" +#include "DialogInfo.h" +#include "splines.h" +#include "../../renderer/tr_local.h" +#include "../../renderer/model_local.h" // for idRenderModelLiquid + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +const char *g_pDimStrings[] = { "x:%.f", "y:%.f", "z:%.f" }; +const char *g_pOrgStrings[] = { "(x:%.f y:%.f)", "(x:%.f z:%.f)", "(y:%.f z:%.f)" }; +CString g_strDim; +CString g_strStatus; + +bool g_bCrossHairs = false; +bool g_bScaleMode; +int g_nScaleHow; +bool g_bRotateMode; +bool g_bClipMode; +bool g_bRogueClipMode; +bool g_bSwitch; +CClipPoint g_Clip1; +CClipPoint g_Clip2; +CClipPoint g_Clip3; +CClipPoint *g_pMovingClip; +brush_t g_brFrontSplits; +brush_t g_brBackSplits; + +brush_t g_brClipboard; +brush_t g_brUndo; +entity_t g_enClipboard; + +idVec3 g_vRotateOrigin; +idVec3 g_vRotation; + +bool g_bPathMode; +CClipPoint g_PathPoints[256]; +CClipPoint *g_pMovingPath; +int g_nPathCount; +int g_nPathLimit; + +bool g_bSmartGo; + +bool g_bPointMode; +CClipPoint g_PointPoints[512]; +CClipPoint *g_pMovingPoint; +int g_nPointCount; +int g_nPointLimit; + +const int XY_LEFT = 0x01; +const int XY_RIGHT = 0x02; +const int XY_UP = 0x04; +const int XY_DOWN = 0x08; + +PFNPathCallback *g_pPathFunc = NULL; +void Select_Ungroup(); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void AcquirePath(int nCount, PFNPathCallback *pFunc) { + g_nPathCount = 0; + g_nPathLimit = nCount; + g_pPathFunc = pFunc; + g_bPathMode = true; +} + +CPtrArray g_ptrMenus; + +CMemFile g_Clipboard(4096); +CMemFile g_PatchClipboard(4096); + +extern int pressx; +extern int pressy; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +float fDiff(float f1, float f2) { + if (f1 > f2) { + return f1 - f2; + } + else { + return f2 - f1; + } +} + +#define MAX_DRAG_POINTS 128 + +CPtrArray dragPoints; +static CDragPoint *activeDrag = NULL; +static bool activeDragging = false; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CDragPoint::PointWithin(idVec3 p, int nView) { + if (nView == -1) { + if (fDiff(p[0], vec[0]) <= 3 && fDiff(p[1], vec[1]) <= 3 && fDiff(p[2], vec[2]) <= 3) { + return true; + } + } + else { + int nDim1 = (nView == YZ) ? 1 : 0; + int nDim2 = (nView == XY) ? 1 : 2; + if (fDiff(p[nDim1], vec[nDim1]) <= 3 && fDiff(p[nDim2], vec[nDim2]) <= 3) { + return true; + } + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CDragPoint *PointRay(const idVec3 &org, const idVec3 &dir, float *dist) { + int i, besti; + float d, bestd; + idVec3 temp; + CDragPoint *drag = NULL; + CDragPoint *priority = NULL; + + // find the point closest to the ray + float scale = g_pParentWnd->ActiveXY()->Scale(); + besti = -1; + bestd = 12 / scale / 2; + + int count = dragPoints.GetSize(); + for (i = 0; i < count; i++) { + drag = reinterpret_cast < CDragPoint * > (dragPoints[i]); + temp = drag->vec - org; + d = temp * dir; + temp = org + d * dir; + temp = drag->vec - temp; + d = temp.Length(); + if ( d < bestd ) { + bestd = d; + besti = i; + if (priority == NULL) { + priority = reinterpret_cast < CDragPoint * > (dragPoints[besti]); + if (!priority->priority) { + priority = NULL; + } + } + } + } + + if (besti == -1) { + return NULL; + } + + drag = reinterpret_cast < CDragPoint * > (dragPoints[besti]); + if (priority && !drag->priority) { + drag = priority; + } + + return drag; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ClearSelectablePoints(brush_t *b) { + if (b == NULL) { + dragPoints.RemoveAll(); + } + else { + CPtrArray ptr; + ptr.Copy(dragPoints); + dragPoints.RemoveAll(); + + int count = ptr.GetSize(); + for (int i = 0; i < count; i++) { + if (b == reinterpret_cast < CDragPoint * > ( ptr.GetAt(i))->pBrush ) { + continue; + } + else { + dragPoints.Add(ptr.GetAt(i)); + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority) { + dragPoints.Add(new CDragPoint(b, v, type, priority)); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void UpdateSelectablePoint(brush_t *b, idVec3 v, int type) { + int count = dragPoints.GetSize(); + for (int i = 0; i < count; i++) { + CDragPoint *drag = reinterpret_cast < CDragPoint * > (dragPoints.GetAt(i)); + if (b == drag->pBrush && type == drag->nType) { + VectorCopy(v, drag->vec); + return; + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void VectorToAngles(idVec3 vec, idVec3 angles) { + float forward; + float yaw, pitch; + + if ((vec[0] == 0) && (vec[1] == 0)) { + yaw = 0; + if (vec[2] > 0) { + pitch = 90; + } + else { + pitch = 270; + } + } + else { + yaw = RAD2DEG( atan2(vec[1], vec[0]) ); + if (yaw < 0) { + yaw += 360; + } + + forward = (float)idMath::Sqrt(vec[0] * vec[0] + vec[1] * vec[1]); + pitch = RAD2DEG( atan2(vec[2], forward) ); + if (pitch < 0) { + pitch += 360; + } + } + + angles[0] = pitch; + angles[1] = yaw; + angles[2] = 0; +} + +/* + ======================================================================================================================= + RotateLight target is relative to the light origin up and right are relative to the target up and right are + perpendicular and are on a plane through the target with the target vector as normal delta is the movement of the + target relative to the light + ======================================================================================================================= +*/ +void VectorSnapGrid(idVec3 &v) { + v.x = floor(v.x / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + v.y = floor(v.y / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + v.z = floor(v.z / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; +} + +/* + ======================================================================================================================= + ======================================================================================================================= +*/ +static void RotateLight(idVec3 &target, idVec3 &up, idVec3 &right, const idVec3 &delta) { + idVec3 newtarget, cross, dst; + idVec3 normal; + double angle, dist, d, len; + idMat3 rot; + + // calculate new target + newtarget = target + delta; + + // get the up and right vector relative to the light origin + up += target; + right += target; + + len = target.Length() * newtarget.Length(); + + if (len > 0.1) { + // calculate the rotation angle between the vectors + double dp = target * newtarget; + double dv = dp / len; + + angle = RAD2DEG( idMath::ACos( dv ) ); + + // get a vector orthogonal to the rotation plane + cross = target.Cross( newtarget ); + cross.Normalize(); + + if (cross[0] || cross[1] || cross[2]) { + // build the rotation matrix + rot = idRotation( vec3_origin, cross, angle ).ToMat3(); + + rot.ProjectVector(target, dst); + target = dst; + rot.ProjectVector( up, dst ); + up = dst; + rot.ProjectVector( right, dst); + right = dst; + } + } + + // + // project the up and right vectors onto a plane that goes through the target and + // has normal vector target.Normalize() + // + normal = target; + normal.Normalize(); + dist = normal * target; + + d = (normal * up) - dist; + up -= d * normal; + + d = (normal * right) - dist; + right -= d * normal; + + // + // FIXME: maybe calculate the right vector with a cross product between the target + // and up vector, just to make sure the up and right vectors are perpendicular + // get the up and right vectors relative to the target + // + up -= target; + right -= target; + + // move the target in the (target - light_origin) direction + target = newtarget; + VectorSnapGrid(target); + VectorSnapGrid(up); + VectorSnapGrid(right); +} + +/* + ======================================================================================================================= + ======================================================================================================================= +*/ +extern idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in); +extern idMat3 Brush_RotationMatrix(brush_t *b); +bool UpdateActiveDragPoint(const idVec3 &move) { + if (activeDrag) { + idMat3 mat = Brush_RotationMatrix(activeDrag->pBrush); + idMat3 invmat = mat.Transpose(); + idVec3 target, up, right, start, end; + CString str; + if (activeDrag->nType == LIGHT_TARGET) { + GetVectorForKey(activeDrag->pBrush->owner, "light_target", target); + GetVectorForKey(activeDrag->pBrush->owner, "light_up", up); + GetVectorForKey(activeDrag->pBrush->owner, "light_right", right); + target *= mat; + up *= mat; + right *= mat; + RotateLight(target, up, right, move); + target *= invmat; + up *= invmat; + right *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_target", target); + SetKeyVec3(activeDrag->pBrush->owner, "light_up", up); + SetKeyVec3(activeDrag->pBrush->owner, "light_right", right); + target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush, target), LIGHT_TARGET); + up += target; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,up), LIGHT_UP); + right += target; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,right), LIGHT_RIGHT); + } + else if (activeDrag->nType == LIGHT_UP) { + GetVectorForKey(activeDrag->pBrush->owner, "light_up", up); + up *= mat; + up += move; + up *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_up", up); + GetVectorForKey(activeDrag->pBrush->owner, "light_target", target); + target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + up += target; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,up), LIGHT_UP); + } + else if (activeDrag->nType == LIGHT_RIGHT) { + GetVectorForKey(activeDrag->pBrush->owner, "light_right", right); + right *= mat; + right += move; + right *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_right", right); + GetVectorForKey(activeDrag->pBrush->owner, "light_target", target); + target += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + right += target; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,right), LIGHT_RIGHT); + } + else if (activeDrag->nType == LIGHT_START) { + GetVectorForKey(activeDrag->pBrush->owner, "light_start", start); + start *= mat; + start += move; + start *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_start", start); + start += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,start), LIGHT_START); + } + else if (activeDrag->nType == LIGHT_END) { + GetVectorForKey(activeDrag->pBrush->owner, "light_end", end); + end *= mat; + end += move; + end *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_end", end); + end += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush,end), LIGHT_END); + } + else if (activeDrag->nType == LIGHT_CENTER) { + GetVectorForKey(activeDrag->pBrush->owner, "light_center", end); + end *= mat; + end += move; + end *= invmat; + SetKeyVec3(activeDrag->pBrush->owner, "light_center", end); + end += (activeDrag->pBrush->trackLightOrigin) ? activeDrag->pBrush->owner->lightOrigin : activeDrag->pBrush->owner->origin; + UpdateSelectablePoint(activeDrag->pBrush, Brush_TransformedPoint(activeDrag->pBrush, end), LIGHT_CENTER); + } + + // FIXME: just build the frustrum values + Brush_Build(activeDrag->pBrush); + return true; + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= +*/ +bool SetDragPointCursor(idVec3 p, int nView) { + activeDrag = NULL; + + int numDragPoints = dragPoints.GetSize(); + for (int i = 0; i < numDragPoints; i++) { + if (reinterpret_cast < CDragPoint * > (dragPoints[i])->PointWithin(p, nView)) { + activeDrag = reinterpret_cast < CDragPoint * > (dragPoints[i]); + return true; + } + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void SetActiveDrag(CDragPoint *p) { + activeDrag = p; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ClearActiveDrag() { + activeDrag = NULL; +} + +// CXYWnd +IMPLEMENT_DYNCREATE(CXYWnd, CWnd); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CXYWnd::CXYWnd() { + g_brClipboard.next = &g_brClipboard; + g_brUndo.next = &g_brUndo; + g_nScaleHow = 0; + g_bRotateMode = false; + g_bClipMode = false; + g_bRogueClipMode = false; + g_bSwitch = true; + g_pMovingClip = NULL; + g_pMovingPath = NULL; + g_brFrontSplits.next = &g_brFrontSplits; + g_brBackSplits.next = &g_brBackSplits; + m_bActive = false; + + m_bRButtonDown = false; + m_nUpdateBits = W_XY; + g_bPathMode = false; + g_nPathCount = 0; + g_nPathLimit = 0; + m_nTimerID = -1; + m_nButtonstate = 0; + XY_Init(); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +CXYWnd::~CXYWnd() { + int nSize = g_ptrMenus.GetSize(); + while (nSize > 0) { + CMenu *pMenu = reinterpret_cast < CMenu * > (g_ptrMenus.GetAt(nSize - 1)); + ASSERT(pMenu); + pMenu->DestroyMenu(); + delete pMenu; + nSize--; + } + + g_ptrMenus.RemoveAll(); + m_mnuDrop.DestroyMenu(); +} + +BEGIN_MESSAGE_MAP(CXYWnd, CWnd) +//{{AFX_MSG_MAP(CXYWnd) + ON_WM_CREATE() + ON_WM_LBUTTONDOWN() + ON_WM_MBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONUP() + ON_WM_RBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_PAINT() + ON_WM_KEYDOWN() + ON_WM_SIZE() + ON_WM_DESTROY() + ON_COMMAND(ID_SELECT_MOUSEROTATE, OnSelectMouserotate) + ON_WM_TIMER() + ON_WM_KEYUP() + ON_WM_NCCALCSIZE() + ON_WM_KILLFOCUS() + ON_WM_SETFOCUS() + ON_WM_CLOSE() + ON_WM_ERASEBKGND() + ON_WM_MOUSEWHEEL() + ON_COMMAND(ID_DROP_NEWMODEL, OnDropNewmodel) + //}}AFX_MSG_MAP + ON_COMMAND_RANGE(ID_ENTITY_START, ID_ENTITY_END, OnEntityCreate) +END_MESSAGE_MAP() +// CXYWnd message handlers +LONG WINAPI XYWndProc(HWND, UINT, WPARAM, LPARAM); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CXYWnd::PreCreateWindow(CREATESTRUCT &cs) { + WNDCLASS wc; + HINSTANCE hInstance = AfxGetInstanceHandle(); + if (::GetClassInfo(hInstance, XY_WINDOW_CLASS, &wc) == FALSE) { + // Register a new class + memset(&wc, 0, sizeof(wc)); + wc.style = CS_NOCLOSE; + wc.lpszClassName = XY_WINDOW_CLASS; + wc.hCursor = NULL; // LoadCursor (NULL,IDC_ARROW); + wc.lpfnWndProc = ::DefWindowProc; + if (AfxRegisterClass(&wc) == FALSE) { + Error("CCamWnd RegisterClass: failed"); + } + } + + cs.lpszClass = XY_WINDOW_CLASS; + cs.lpszName = "VIEW"; + if (cs.style != QE3_CHILDSTYLE) { + cs.style = QE3_SPLITTER_STYLE; + } + + return CWnd::PreCreateWindow(cs); +} + +HDC s_hdcXY; +HGLRC s_hglrcXY; + +static unsigned s_stipple[32] = { + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, + 0xaaaaaaaa, + 0x55555555, +}; + +/* + ======================================================================================================================= + WXY_WndProc + ======================================================================================================================= + */ +LONG WINAPI XYWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) + { + case WM_DESTROY: + return 0; + + case WM_NCCALCSIZE: // don't let windows copy pixels + DefWindowProc(hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + + case WM_KILLFOCUS: + case WM_SETFOCUS: + SendMessage(hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0); + return 0; + + case WM_CLOSE: + DestroyWindow(hWnd); + return 0; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +static void WXY_InitPixelFormat(PIXELFORMATDESCRIPTOR *pPFD) { + memset(pPFD, 0, sizeof(*pPFD)); + + pPFD->nSize = sizeof(PIXELFORMATDESCRIPTOR); + pPFD->nVersion = 1; + pPFD->dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pPFD->iPixelType = PFD_TYPE_RGBA; + pPFD->cColorBits = 24; + pPFD->cDepthBits = 32; + pPFD->iLayerType = PFD_MAIN_PLANE; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void WXY_Print(void) { + DOCINFO di; + + PRINTDLG pd; + + /* initialize the PRINTDLG struct and execute it */ + memset(&pd, 0, sizeof(pd)); + pd.lStructSize = sizeof(pd); + pd.hwndOwner = g_pParentWnd->GetXYWnd()->GetSafeHwnd(); + pd.Flags = PD_RETURNDC; + pd.hInstance = 0; + if (!PrintDlg(&pd) || !pd.hDC) { + g_pParentWnd->MessageBox("Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR); + return; + } + + /* StartDoc */ + memset(&di, 0, sizeof(di)); + di.cbSize = sizeof(di); + di.lpszDocName = "QE4"; + if (StartDoc(pd.hDC, &di) <= 0) { + g_pParentWnd->MessageBox("Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR); + return; + } + + /* StartPage */ + if (StartPage(pd.hDC) <= 0) { + g_pParentWnd->MessageBox("Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR); + return; + } { /* read pixels from the XY window */ + int bmwidth = 320, bmheight = 320; + int pwidth, pheight; + + RECT r; + + GetWindowRect(g_pParentWnd->GetXYWnd()->GetSafeHwnd(), &r); + + bmwidth = r.right - r.left; + bmheight = r.bottom - r.top; + + pwidth = GetDeviceCaps(pd.hDC, PHYSICALWIDTH) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETX); + pheight = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETY); + + StretchBlt(pd.hDC, 0, 0, pwidth, pheight, s_hdcXY, 0, 0, bmwidth, bmheight, SRCCOPY); + } + + /* EndPage and EndDoc */ + if (EndPage(pd.hDC) <= 0) { + g_pParentWnd->MessageBox("QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR); + return; + } + + if (EndDoc(pd.hDC) <= 0) { + g_pParentWnd->MessageBox("QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR); + return; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +int CXYWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CWnd::OnCreate(lpCreateStruct) == -1) { + return -1; + } + + s_hdcXY = ::GetDC(GetSafeHwnd()); + QEW_SetupPixelFormat(s_hdcXY, false); + + qglPolygonStipple((unsigned char *)s_stipple); + qglLineStipple(3, 0xaaaa); + return 0; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +float ptSum(idVec3 pt) { + return pt[0] + pt[1] + pt[2]; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::DropClipPoint(UINT nFlags, CPoint point) { + CRect rctZ; + GetClientRect(rctZ); + if (g_pMovingClip) { + SetCapture(); + SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *g_pMovingClip); + } + else { + idVec3 *pPt = NULL; + if (g_Clip1.Set() == false) { + pPt = g_Clip1; + g_Clip1.Set(true); + g_Clip1.m_ptScreen = point; + } + else if (g_Clip2.Set() == false) { + pPt = g_Clip2; + g_Clip2.Set(true); + g_Clip2.m_ptScreen = point; + } + else if (g_Clip3.Set() == false) { + pPt = g_Clip3; + g_Clip3.Set(true); + g_Clip3.m_ptScreen = point; + } + else { + RetainClipMode(true); + pPt = g_Clip1; + g_Clip1.Set(true); + g_Clip1.m_ptScreen = point; + } + + SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *pPt); + + // Put the off-viewaxis coordinate at the top or bottom of selected brushes + if ( GetAsyncKeyState(VK_CONTROL) & 0x8000 ) { + if ( selected_brushes.next != &selected_brushes ) { + idVec3 smins, smaxs; + Select_GetBounds( smins, smaxs ); + + if ( m_nViewType == XY ) { + if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) { + pPt->z = smaxs.z; + } else { + pPt->z = smins.z; + } + } else if ( m_nViewType == YZ ) { + if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) { + pPt->x = smaxs.x; + } else { + pPt->x = smins.x; + } + } else { + if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) { + pPt->y = smaxs.y; + } else { + pPt->y = smins.y; + } + } + } + } + } + + Sys_UpdateWindows(XY | W_CAMERA_IFON); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::DropPathPoint(UINT nFlags, CPoint point) { + CRect rctZ; + GetClientRect(rctZ); + if (g_pMovingPath) { + SetCapture(); + SnapToPoint(point.x, rctZ.Height() - 1 - point.y, *g_pMovingPath); + } + else { + g_PathPoints[g_nPathCount].Set(true); + g_PathPoints[g_nPathCount].m_ptScreen = point; + SnapToPoint(point.x, rctZ.Height() - 1 - point.y, g_PathPoints[g_nPathCount]); + g_nPathCount++; + if (g_nPathCount == g_nPathLimit) { + if (g_pPathFunc) { + g_pPathFunc(true, g_nPathCount); + } + + g_nPathCount = 0; + g_bPathMode = false; + g_pPathFunc = NULL; + } + } + + Sys_UpdateWindows(XY | W_CAMERA_IFON); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::AddPointPoint(UINT nFlags, idVec3 *pVec) { + g_PointPoints[g_nPointCount].Set(true); + + // g_PointPoints[g_nPointCount].m_ptScreen = point; + g_PointPoints[g_nPointCount].m_ptClip = *pVec; + g_PointPoints[g_nPointCount].SetPointPtr(pVec); + g_nPointCount++; + Sys_UpdateWindows(XY | W_CAMERA_IFON); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnLButtonDown(UINT nFlags, CPoint point) { + g_pParentWnd->SetActiveXY(this); + UndoCopy(); + + if (g_pParentWnd->GetNurbMode()) { + int i, num = g_pParentWnd->GetNurb()->GetNumValues(); + idList temp; + for (i = 0; i < num; i++) { + temp.Append(g_pParentWnd->GetNurb()->GetValue(i)); + } + CRect rctZ; + GetClientRect(rctZ); + idVec3 v3; + SnapToPoint(point.x, rctZ.Height() - 1 - point.y, v3); + temp.Append(idVec2(v3.x, v3.y)); + num++; + g_pParentWnd->GetNurb()->Clear(); + for (i = 0; i < num; i++) { + g_pParentWnd->GetNurb()->AddValue((1000 * i)/num, temp[i]); + } + } + if (ClipMode() && !RogueClipMode()) { + DropClipPoint(nFlags, point); + } + else if (PathMode()) { + DropPathPoint(nFlags, point); + } + else { + OriginalButtonDown(nFlags, point); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnMButtonDown(UINT nFlags, CPoint point) { + OriginalButtonDown(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +float Betwixt(float f1, float f2) { + if (f1 > f2) { + return f2 + ((f1 - f2) / 2); + } + else { + return f1 + ((f2 - f1) / 2); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::ProduceSplits(brush_t **pFront, brush_t **pBack) { + *pFront = NULL; + *pBack = NULL; + if (ClipMode()) { + if (g_Clip1.Set() && g_Clip2.Set()) { + face_t face; + VectorCopy(g_Clip1.m_ptClip, face.planepts[0]); + VectorCopy(g_Clip2.m_ptClip, face.planepts[1]); + VectorCopy(g_Clip3.m_ptClip, face.planepts[2]); + if (selected_brushes.next && (selected_brushes.next->next == &selected_brushes)) { + if (g_Clip3.Set() == false) { + if (m_nViewType == XY) { + face.planepts[0][2] = selected_brushes.next->mins[2]; + face.planepts[1][2] = selected_brushes.next->mins[2]; + face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]); + face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]); + face.planepts[2][2] = selected_brushes.next->maxs[2]; + } + else if (m_nViewType == YZ) { + face.planepts[0][0] = selected_brushes.next->mins[0]; + face.planepts[1][0] = selected_brushes.next->mins[0]; + face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]); + face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]); + face.planepts[2][0] = selected_brushes.next->maxs[0]; + } + else { + face.planepts[0][1] = selected_brushes.next->mins[1]; + face.planepts[1][1] = selected_brushes.next->mins[1]; + face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]); + face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]); + face.planepts[2][1] = selected_brushes.next->maxs[1]; + } + } + + Brush_SplitBrushByFace(selected_brushes.next, &face, pFront, pBack); + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CleanList(brush_t *pList) { + brush_t *pBrush = pList->next; + while (pBrush != NULL && pBrush != pList) { + brush_t *pNext = pBrush->next; + Brush_Free(pBrush); + pBrush = pNext; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::ProduceSplitLists() { + if (AnyPatchesSelected()) { + Sys_Status("Deslecting patches for clip operation.\n"); + + brush_t *next; + for (brush_t * pb = selected_brushes.next; pb != &selected_brushes; pb = next) { + next = pb->next; + if (pb->pPatch) { + Brush_RemoveFromList(pb); + Brush_AddToList(pb, &active_brushes); + UpdatePatchInspector(); + } + } + } + + CleanList(&g_brFrontSplits); + CleanList(&g_brBackSplits); + g_brFrontSplits.next = &g_brFrontSplits; + g_brBackSplits.next = &g_brBackSplits; + + brush_t *pBrush; + for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { + brush_t *pFront = NULL; + brush_t *pBack = NULL; + if (ClipMode()) { + if (g_Clip1.Set() && g_Clip2.Set()) { + face_t face; + VectorCopy(g_Clip1.m_ptClip, face.planepts[0]); + VectorCopy(g_Clip2.m_ptClip, face.planepts[1]); + VectorCopy(g_Clip3.m_ptClip, face.planepts[2]); + if (g_Clip3.Set() == false) { + if (g_pParentWnd->ActiveXY()->GetViewType() == XY) { + face.planepts[0][2] = pBrush->mins[2]; + face.planepts[1][2] = pBrush->mins[2]; + face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]); + face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]); + face.planepts[2][2] = pBrush->maxs[2]; + } + else if (g_pParentWnd->ActiveXY()->GetViewType() == YZ) { + face.planepts[0][0] = pBrush->mins[0]; + face.planepts[1][0] = pBrush->mins[0]; + face.planepts[2][1] = Betwixt(g_Clip1.m_ptClip[1], g_Clip2.m_ptClip[1]); + face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]); + face.planepts[2][0] = pBrush->maxs[0]; + } + else { + face.planepts[0][1] = pBrush->mins[1]; + face.planepts[1][1] = pBrush->mins[1]; + face.planepts[2][0] = Betwixt(g_Clip1.m_ptClip[0], g_Clip2.m_ptClip[0]); + face.planepts[2][2] = Betwixt(g_Clip1.m_ptClip[2], g_Clip2.m_ptClip[2]); + face.planepts[2][1] = pBrush->maxs[1]; + } + } + + Brush_SplitBrushByFace(pBrush, &face, &pFront, &pBack); + if (pBack) { + Brush_AddToList(pBack, &g_brBackSplits); + } + + if (pFront) { + Brush_AddToList(pFront, &g_brFrontSplits); + } + } + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void Brush_CopyList(brush_t *pFrom, brush_t *pTo) { + brush_t *pBrush = pFrom->next; + while (pBrush != NULL && pBrush != pFrom) { + brush_t *pNext = pBrush->next; + Brush_RemoveFromList(pBrush); + Brush_AddToList(pBrush, pTo); + pBrush = pNext; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnRButtonDown(UINT nFlags, CPoint point) { + g_pParentWnd->SetActiveXY(this); + m_ptDown = point; + m_bRButtonDown = true; + + if (g_PrefsDlg.m_nMouseButtons == 3) { // 3 button mouse + if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + if (ClipMode()) { // already there? + DropClipPoint(nFlags, point); + } + else { + SetClipMode(true); + g_bRogueClipMode = true; + DropClipPoint(nFlags, point); + } + + return; + } + } + + OriginalButtonDown(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnLButtonUp(UINT nFlags, CPoint point) { + + if (ClipMode()) { + if (g_pMovingClip) { + ReleaseCapture(); + g_pMovingClip = NULL; + } + } + + OriginalButtonUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnMButtonUp(UINT nFlags, CPoint point) { + OriginalButtonUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnRButtonUp(UINT nFlags, CPoint point) { + m_bRButtonDown = false; + if (point == m_ptDown) { // mouse didn't move + bool bGo = true; + if ((GetAsyncKeyState(VK_MENU) & 0x8000)) { + bGo = false; + } + + if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + bGo = false; + } + + if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) { + bGo = false; + } + + if (bGo) { + HandleDrop(); + } + } + + OriginalButtonUp(nFlags, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OriginalButtonDown(UINT nFlags, CPoint point) { + CRect rctZ; + GetClientRect(rctZ); + SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + if (g_pParentWnd->GetTopWindow() != this) { + BringWindowToTop(); + } + + SetFocus(); + SetCapture(); + XY_MouseDown(point.x, rctZ.Height() - 1 - point.y, nFlags); + m_nScrollFlags = nFlags; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OriginalButtonUp(UINT nFlags, CPoint point) { + CRect rctZ; + GetClientRect(rctZ); + XY_MouseUp(point.x, rctZ.Height() - 1 - point.y, nFlags); + if (!(nFlags & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON))) { + ReleaseCapture(); + } +} + +idVec3 tdp; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnMouseMove(UINT nFlags, CPoint point) { + + m_ptDown.x = 0; + m_ptDown.y = 0; + + if + ( + g_PrefsDlg.m_bChaseMouse == TRUE && + (point.x < 0 || point.y < 0 || point.x > m_nWidth || point.y > m_nHeight) && + GetCapture() == this + ) { + float fAdjustment = (g_qeglobals.d_gridsize / 8 * 64) / m_fScale; + + // m_ptDrag = point; + m_ptDragAdj.x = 0; + m_ptDragAdj.y = 0; + if (point.x < 0) { + m_ptDragAdj.x = -fAdjustment; + } + else if (point.x > m_nWidth) { + m_ptDragAdj.x = fAdjustment; + } + + if (point.y < 0) { + m_ptDragAdj.y = -fAdjustment; + } + else if (point.y > m_nHeight) { + m_ptDragAdj.y = fAdjustment; + } + + if (m_nTimerID == -1) { + m_nTimerID = SetTimer(100, 50, NULL); + m_ptDrag = point; + m_ptDragTotal = 0; + } + + return; + } + + // else if (m_nTimerID != -1) + if (m_nTimerID != -1) { + KillTimer(m_nTimerID); + pressx -= m_ptDragTotal.x; + pressy += m_ptDragTotal.y; + m_nTimerID = -1; + + // return; + } + + bool bCrossHair = false; + if (!m_bRButtonDown) { + tdp[0] = tdp[1] = tdp[2] = 0.0; + SnapToPoint(point.x, m_nHeight - 1 - point.y, tdp); + + g_strStatus.Format("x:: %.1f y:: %.1f z:: %.1f", tdp[0], tdp[1], tdp[2]); + g_pParentWnd->SetStatusText(1, g_strStatus); + + // + // i need to generalize the point code.. having 3 flavors pretty much sucks.. once + // the new curve stuff looks like it is going to stick i will rationalize this + // down to a single interface.. + // + if (PointMode()) { + if (g_pMovingPoint && GetCapture() == this) { + bCrossHair = true; + SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingPoint->m_ptClip); + g_pMovingPoint->UpdatePointPtr(); + Sys_UpdateWindows(XY | W_CAMERA_IFON); + } + else { + g_pMovingPoint = NULL; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + for (int n = 0; n < g_nPointCount; n++) { + if + ( + fDiff(g_PointPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 && + fDiff(g_PointPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 + ) { + bCrossHair = true; + g_pMovingPoint = &g_PointPoints[n]; + } + } + } + } + else if (ClipMode()) { + if (g_pMovingClip && GetCapture() == this) { + bCrossHair = true; + SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingClip->m_ptClip); + Sys_UpdateWindows(XY | W_CAMERA_IFON); + } + else { + g_pMovingClip = NULL; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + if (g_Clip1.Set()) { + if + ( + fDiff(g_Clip1.m_ptClip[nDim1], tdp[nDim1]) < 3 && + fDiff(g_Clip1.m_ptClip[nDim2], tdp[nDim2]) < 3 + ) { + bCrossHair = true; + g_pMovingClip = &g_Clip1; + } + } + + if (g_Clip2.Set()) { + if + ( + fDiff(g_Clip2.m_ptClip[nDim1], tdp[nDim1]) < 3 && + fDiff(g_Clip2.m_ptClip[nDim2], tdp[nDim2]) < 3 + ) { + bCrossHair = true; + g_pMovingClip = &g_Clip2; + } + } + + if (g_Clip3.Set()) { + if + ( + fDiff(g_Clip3.m_ptClip[nDim1], tdp[nDim1]) < 3 && + fDiff(g_Clip3.m_ptClip[nDim2], tdp[nDim2]) < 3 + ) { + bCrossHair = true; + g_pMovingClip = &g_Clip3; + } + } + } + + if (bCrossHair == false) { + XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags); + } + } + else if (PathMode()) { + if (g_pMovingPath && GetCapture() == this) { + bCrossHair = true; + SnapToPoint(point.x, m_nHeight - 1 - point.y, g_pMovingPath->m_ptClip); + Sys_UpdateWindows(XY | W_CAMERA_IFON); + } + else { + g_pMovingPath = NULL; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + for (int n = 0; n < g_nPathCount; n++) { + if + ( + fDiff(g_PathPoints[n].m_ptClip[nDim1], tdp[nDim1]) < 3 && + fDiff(g_PathPoints[n].m_ptClip[nDim2], tdp[nDim2]) < 3 + ) { + bCrossHair = true; + g_pMovingPath = &g_PathPoints[n]; + } + } + } + } + else { + bCrossHair = XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags); + } + } + else { + bCrossHair = XY_MouseMoved(point.x, m_nHeight - 1 - point.y, nFlags); + } + + if (bCrossHair) { + SetCursor(::LoadCursor(NULL, IDC_CROSS)); + } + else { + SetCursor(::LoadCursor(NULL, IDC_ARROW)); + } + + /// If precision crosshair is active, force redraw of the 2d view on mouse move + if( m_precisionCrosshairMode != PRECISION_CROSSHAIR_NONE ) + { + /// Force 2d view redraw (so that the precision cursor moves with the mouse) + Sys_UpdateWindows( W_XY ); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::RetainClipMode(bool bMode) { + bool bSave = g_bRogueClipMode; + SetClipMode(bMode); + if (bMode == true) { + g_bRogueClipMode = bSave; + } + else { + g_bRogueClipMode = false; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SetClipMode(bool bMode) { + g_bClipMode = bMode; + g_bRogueClipMode = false; + if (bMode) { + g_Clip1.Reset(); + g_Clip2.Reset(); + g_Clip3.Reset(); + CleanList(&g_brFrontSplits); + CleanList(&g_brBackSplits); + g_brFrontSplits.next = &g_brFrontSplits; + g_brBackSplits.next = &g_brBackSplits; + } + else { + if (g_pMovingClip) { + ReleaseCapture(); + g_pMovingClip = NULL; + } + + CleanList(&g_brFrontSplits); + CleanList(&g_brBackSplits); + g_brFrontSplits.next = &g_brFrontSplits; + g_brBackSplits.next = &g_brBackSplits; + Sys_UpdateWindows(XY | W_CAMERA_IFON); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::ClipMode() { + return g_bClipMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::RogueClipMode() { + return g_bRogueClipMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::PathMode() { + return g_bPathMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::PointMode() { + return g_bPointMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SetPointMode(bool b) { + g_bPointMode = b; + if (!b) { + g_nPointCount = 0; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnPaint() { + CPaintDC dc(this); // device context for painting + bool bPaint = true; + if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) { + common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError()); + common->Printf("Please restart Q3Radiant if the Map view is not working\n"); + bPaint = false; + } + + if (bPaint) { + QE_CheckOpenGLForErrors(); + XY_Draw(); + QE_CheckOpenGLForErrors(); + + if (m_nViewType != XY) { + qglPushMatrix(); + if (m_nViewType == YZ) { + qglRotatef(-90, 0, 1, 0); // put Z going up + } + + qglRotatef(-90, 1, 0, 0); // put Z going up + } + + if ( g_bCrossHairs ) { + qglColor4f( 0.2f, 0.9f, 0.2f, 0.8f ); + qglBegin(GL_LINES); + if (m_nViewType == XY) { + qglVertex2f(-16384, tdp[1]); + qglVertex2f(16384, tdp[1]); + qglVertex2f(tdp[0], -16384); + qglVertex2f(tdp[0], 16384); + } + else if (m_nViewType == YZ) { + qglVertex3f(tdp[0], -16384, tdp[2]); + qglVertex3f(tdp[0], 16384, tdp[2]); + qglVertex3f(tdp[0], tdp[1], -16384); + qglVertex3f(tdp[0], tdp[1], 16384); + } + else { + qglVertex3f(-16384, tdp[1], tdp[2]); + qglVertex3f(16384, tdp[1], tdp[2]); + qglVertex3f(tdp[0], tdp[1], -16384); + qglVertex3f(tdp[0], tdp[1], 16384); + } + + qglEnd(); + } + + if (ClipMode()) { + qglPointSize(4); + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER].ToFloatPtr()); + qglBegin(GL_POINTS); + if (g_Clip1.Set()) { + qglVertex3fv(g_Clip1); + } + + if (g_Clip2.Set()) { + qglVertex3fv(g_Clip2); + } + + if (g_Clip3.Set()) { + qglVertex3fv(g_Clip3); + } + + qglEnd(); + qglPointSize(1); + + CString strMsg; + if (g_Clip1.Set()) { + qglRasterPos3f(g_Clip1.m_ptClip[0] + 2, g_Clip1.m_ptClip[1] + 2, g_Clip1.m_ptClip[2] + 2); + strMsg = "1"; + + // strMsg.Format("1 (%f, %f, %f)", g_Clip1[0], g_Clip1[1], g_Clip1[2]); + qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg); + } + + if (g_Clip2.Set()) { + qglRasterPos3f(g_Clip2.m_ptClip[0] + 2, g_Clip2.m_ptClip[1] + 2, g_Clip2.m_ptClip[2] + 2); + strMsg = "2"; + + // strMsg.Format("2 (%f, %f, %f)", g_Clip2[0], g_Clip2[1], g_Clip2[2]); + qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg); + } + + if (g_Clip3.Set()) { + qglRasterPos3f(g_Clip3.m_ptClip[0] + 2, g_Clip3.m_ptClip[1] + 2, g_Clip3.m_ptClip[2] + 2); + strMsg = "3"; + + // strMsg.Format("3 (%f, %f, %f)", g_Clip3[0], g_Clip3[1], g_Clip3[2]); + qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg); + } + + if (g_Clip1.Set() && g_Clip2.Set() && selected_brushes.next != &selected_brushes) { + ProduceSplitLists(); + + brush_t *pBrush; + brush_t *pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits; + for (pBrush = pList->next; pBrush != NULL && pBrush != pList; pBrush = pBrush->next) { + qglColor3f(1, 1, 0); + + face_t *face; + int order; + for (face = pBrush->brush_faces, order = 0; face; face = face->next, order++) { + idWinding *w = face->face_winding; + if (!w) { + continue; + } + + // draw the polygon + qglBegin(GL_LINE_LOOP); + for (int i = 0; i < w->GetNumPoints(); i++) { + qglVertex3fv( (*w)[i].ToFloatPtr() ); + } + + qglEnd(); + } + } + } + } + + if (PathMode()) { + qglPointSize(4); + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER].ToFloatPtr()); + qglBegin(GL_POINTS); + + int n; + for ( n = 0; n < g_nPathCount; n++) { + qglVertex3fv(g_PathPoints[n]); + } + + qglEnd(); + qglPointSize(1); + + CString strMsg; + for (n = 0; n < g_nPathCount; n++) { + qglRasterPos3f + ( + g_PathPoints[n].m_ptClip[0] + 2, + g_PathPoints[n].m_ptClip[1] + 2, + g_PathPoints[n].m_ptClip[2] + 2 + ); + strMsg.Format("%i", n + 1); + qglCallLists(strMsg.GetLength(), GL_UNSIGNED_BYTE, strMsg); + } + } + + if (m_nViewType != XY) { + qglPopMatrix(); + } + + qwglSwapBuffers(dc.m_hDC); + TRACE("XY Paint\n"); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); +} + +// +// ======================================================================================================================= +// FIXME: the brush_t *pBrush is never used. ( Entity_Create uses selected_brushes ) +// ======================================================================================================================= +// +void CreateEntityFromName(char *pName, brush_t *pBrush, bool forceFixed, idVec3 min, idVec3 max, idVec3 org) { + eclass_t *pecNew; + entity_t *petNew; + if (stricmp(pName, "worldspawn") == 0) { + g_pParentWnd->MessageBox("Can't create an entity with worldspawn.", "info", 0); + return; + } + + pecNew = Eclass_ForName(pName, false); + + if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) { + Select_Ungroup(); + } + + // create it + petNew = Entity_Create(pecNew, forceFixed); + + if (petNew && idStr::Icmp(pName, "light") == 0 ) { + idVec3 rad = max - min; + rad *= 0.5; + if (rad.x != 0 && rad.y != 0 && rad.z != 0) { + SetKeyValue(petNew, "light_radius", va("%g %g %g", idMath::Fabs(rad.x), idMath::Fabs(rad.y), idMath::Fabs(rad.z))); + DeleteKey(petNew, "light"); + } + } + + + if (petNew == NULL) { + if (!((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes))) { + brush_t *b = selected_brushes.next; + if (b->owner != world_entity && ((b->owner->eclass->fixedsize && pecNew->fixedsize) || forceFixed)) { + idVec3 mins, maxs; + idVec3 origin; + for (int i = 0; i < 3; i++) { + origin[i] = b->mins[i] - pecNew->mins[i]; + } + + VectorAdd(pecNew->mins, origin, mins); + VectorAdd(pecNew->maxs, origin, maxs); + + brush_t *nb = Brush_Create(mins, maxs, &pecNew->texdef); + Entity_LinkBrush(b->owner, nb); + nb->owner->eclass = pecNew; + SetKeyValue(nb->owner, "classname", pName); + Brush_Free(b); + Brush_Build(nb); + Brush_AddToList(nb, &active_brushes); + Select_Brush(nb); + return; + } + } + + g_pParentWnd->MessageBox("Failed to create entity.", "info", 0); + return; + } + + Select_Deselect(); + + // + // entity_t* pEntity = world_entity; if (selected_brushes.next != + // &selected_brushes) pEntity = selected_brushes.next->owner; + // + Select_Brush(petNew->brushes.onext); + Brush_Build(petNew->brushes.onext); + +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +brush_t *CreateEntityBrush(int x, int y, CXYWnd *pWnd) { + idVec3 mins, maxs; + int i; + float temp; + brush_t *n; + + pWnd->SnapToPoint(x, y, mins); + x += 32; + y += 32; + pWnd->SnapToPoint(x, y, maxs); + + int nDim = (pWnd->GetViewType() == XY) ? 2 : (pWnd->GetViewType() == YZ) ? 0 : 1; + mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom[nDim] / g_qeglobals.d_gridsize)); + maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top[nDim] / g_qeglobals.d_gridsize)); + + if (maxs[nDim] <= mins[nDim]) { + maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize; + } + + for (i = 0; i < 3; i++) { + if (mins[i] == maxs[i]) { + maxs[i] += 16; // don't create a degenerate brush + } + + if (mins[i] > maxs[i]) { + temp = mins[i]; + mins[i] = maxs[i]; + maxs[i] = temp; + } + } + + n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef); + if (!n) { + return NULL; + } + + Brush_AddToList(n, &selected_brushes); + Entity_LinkBrush(world_entity, n); + Brush_Build(n); + return n; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CreateRightClickEntity(CXYWnd *pWnd, int x, int y, char *pName) { + idVec3 min, max, org; + Select_GetBounds(min, max); + Select_GetMid(org); + + CRect rctZ; + pWnd->GetClientRect(rctZ); + + brush_t *pBrush; + if (selected_brushes.next == &selected_brushes) { + pBrush = CreateEntityBrush(x, rctZ.Height() - 1 - y, pWnd); + min.Zero(); + max.Zero(); + CreateEntityFromName(pName, pBrush, true, min, max, org); + } + else { + pBrush = selected_brushes.next; + CreateEntityFromName(pName, pBrush, false, min, max, org); + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +brush_t *CreateSmartBrush(idVec3 v) { + idVec3 mins, maxs; + int i; + brush_t *n; + + for (i = 0; i < 3; i++) { + mins[i] = v[i] - 16; + maxs[i] = v[i] + 16; + } + + n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef); + if (!n) { + return NULL; + } + + Brush_AddToList(n, &selected_brushes); + + // Entity_LinkBrush(world_entity, n); + Brush_Build(n); + return n; +} + +CString g_strSmartEntity; +int g_nSmartX; +int g_nSmartY; +bool g_bSmartWaiting; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void _SmartPointDone(bool b, int n) { + g_bSmartWaiting = false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CreateSmartEntity(CXYWnd *pWnd, int x, int y, const char *pName) { + g_nSmartX = x; + g_nSmartY = y; + g_strSmartEntity = pName; + if (g_strSmartEntity.Find("Smart_Train") >= 0) { + ShowInfoDialog("Select the path of the train by left clicking in XY, YZ and/or XZ views. You can move an already dropped point by grabbing and moving it. When you are finished, press ENTER to accept and create the entity and path(s), press ESC to abandon the creation"); + g_bPathMode = true; + g_nPathLimit = 0; + g_nPathCount = 0; + g_bSmartGo = true; + } + else if (g_strSmartEntity.Find("Smart_Monster...") >= 0) { + g_bPathMode = true; + g_nPathLimit = 0; + g_nPathCount = 0; + } + else if (g_strSmartEntity.Find("Smart_Rotating") >= 0) { + g_bSmartWaiting = true; + ShowInfoDialog("Left click to specify the rotation origin"); + AcquirePath(1, &_SmartPointDone); + while (g_bSmartWaiting) { + MSG msg; + if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + HideInfoDialog(); + + CPtrArray array; + g_bScreenUpdates = false; + CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_rotating"); + array.Add(reinterpret_cast < void * > (selected_brushes.next)); + Select_Deselect(); + + brush_t *pBrush = CreateSmartBrush(g_PathPoints[0]); + array.Add(pBrush); + Select_Deselect(); + Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(0))); + Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(1))); + ConnectEntities(); + g_bScreenUpdates = true; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void FinishSmartCreation() { + CPtrArray array; + HideInfoDialog(); + + brush_t *pEntities = NULL; + if (g_strSmartEntity.Find("Smart_Train") >= 0) { + g_bScreenUpdates = false; + CreateRightClickEntity(g_pParentWnd->ActiveXY(), g_nSmartX, g_nSmartY, "func_train"); + array.Add(reinterpret_cast < void * > (selected_brushes.next)); + int n; + for (n = 0; n < g_nPathCount; n++) { + Select_Deselect(); + CreateRightClickEntity + ( + g_pParentWnd->ActiveXY(), + g_PathPoints[n].m_ptScreen.x, + g_PathPoints[n].m_ptScreen.y, + "path_corner" + ); + array.Add(reinterpret_cast < void * > (selected_brushes.next)); + } + + for (n = 0; n < g_nPathCount; n++) { + Select_Deselect(); + Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(n))); + Select_Brush(reinterpret_cast < brush_t * > (array.GetAt(n + 1))); + ConnectEntities(); + } + + g_bScreenUpdates = true; + } + + g_nPathCount = 0; + g_bPathMode = false; + Sys_UpdateWindows(W_ALL); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::KillPathMode() { + g_bSmartGo = false; + g_bPathMode = false; + if (g_pPathFunc) { + g_pPathFunc(false, g_nPathCount); + } + + g_nPathCount = 0; + g_pPathFunc = NULL; + Sys_UpdateWindows(W_ALL); +} + +// +// ======================================================================================================================= +// gets called for drop down menu messages TIP: it's not always about EntityCreate +// ======================================================================================================================= +// +void CXYWnd::OnEntityCreate(unsigned int nID) { + if (m_mnuDrop.GetSafeHmenu()) { + CString strItem; + m_mnuDrop.GetMenuString(nID, strItem, MF_BYCOMMAND); + + if (strItem.CompareNoCase("Add to...") == 0) { + // + // ++timo TODO: fill the menu with current groups? this one is for adding to + // existing groups only + // + common->Printf("TODO: Add to... in CXYWnd::OnEntityCreate\n"); + } + else if (strItem.CompareNoCase("Remove") == 0) { + // remove selected brushes from their current group + brush_t *b; + for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { + } + } + + // ++timo FIXME: remove when all hooks are in + if + ( + strItem.CompareNoCase("Add to...") == 0 || + strItem.CompareNoCase("Remove") == 0 || + strItem.CompareNoCase("Name...") == 0 || + strItem.CompareNoCase("New group...") == 0 + ) { + common->Printf("TODO: hook drop down group menu\n"); + return; + } + + if (strItem.Find("Smart_") >= 0) { + CreateSmartEntity(this, m_ptDown.x, m_ptDown.y, strItem); + } + else { + CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, strItem.GetBuffer(0)); + } + + Sys_UpdateWindows(W_ALL); + + // OnLButtonDown((MK_LBUTTON | MK_SHIFT), CPoint(m_ptDown.x+2, m_ptDown.y+2)); + } +} + +BOOL CXYWnd::OnCmdMsg( UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo ) +{ + if ( CWnd::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) { + return TRUE; + } + return AfxGetMainWnd()->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ); +} + +bool MergeMenu(CMenu * pMenuDestination, const CMenu * pMenuAdd, bool bTopLevel /*=false*/) +{ + // get the number menu items in the menus + int iMenuAddItemCount = pMenuAdd->GetMenuItemCount(); + int iMenuDestItemCount = pMenuDestination->GetMenuItemCount(); + + // if there are no items return + if (iMenuAddItemCount == 0) + return true; + + // if we are not at top level and the destination menu is not empty + // -> we append a seperator + if (!bTopLevel && iMenuDestItemCount > 0) + pMenuDestination->AppendMenu(MF_SEPARATOR); + + // iterate through the top level of + for(int iLoop = 0; iLoop < iMenuAddItemCount; iLoop++) + { + // get the menu string from the add menu + CString sMenuAddString; + pMenuAdd->GetMenuString(iLoop, sMenuAddString, MF_BYPOSITION); + + // try to get the submenu of the current menu item + CMenu* pSubMenu = pMenuAdd->GetSubMenu(iLoop); + + // check if we have a sub menu + if (!pSubMenu) + { + // normal menu item + // read the source and append at the destination + UINT nState = pMenuAdd->GetMenuState(iLoop, MF_BYPOSITION); + UINT nItemID = pMenuAdd->GetMenuItemID(iLoop); + if (pMenuDestination->AppendMenu(nState, nItemID, sMenuAddString)) + { + // menu item added, don't forget to correct the item count + iMenuDestItemCount++; + } + else + { + TRACE("MergeMenu: AppendMenu failed!\n"); + return false; + } + } + else + { + // create or insert a new popup menu item + + // default insert pos is like ap + int iInsertPosDefault = -1; + + // if we are at top level merge into existing popups rather than + // creating new ones + if(bTopLevel) + { + ASSERT(sMenuAddString != "&?" && sMenuAddString != + "?"); + CString csAdd(sMenuAddString); + csAdd.Remove('&'); // for comparison of menu items supress '&' + bool bAdded = false; + + // try to find existing popup + for( int iLoop1 = 0; iLoop1 < iMenuDestItemCount; iLoop1++ ) + { + // get the menu string from the destination menu + CString sDest; + pMenuDestination->GetMenuString(iLoop1, sDest, MF_BYPOSITION); + sDest.Remove('&'); // for a better compare (s.a.) + + if (csAdd == sDest) + { + // we got a hit -> merge the two popups + // try to get the submenu of the desired destination menu item + CMenu* pSubMenuDest = + pMenuDestination->GetSubMenu(iLoop1); + + if (pSubMenuDest) + { + // merge the popup recursivly and continue with outer for loop + if (!MergeMenu(pSubMenuDest, pSubMenu, false)) + return false; + bAdded = true; + break; + } + } + + // alternativ insert before or + if (iInsertPosDefault == -1 && (sDest == "Window" + || sDest == "?" || sDest == "Help")) + { + iInsertPosDefault = iLoop1; + } + } // for (iLoop1) + if (bAdded) + { + // menu added, so go on with loop over pMenuAdd's top level + continue; + } + } // if (bTopLevel) + + // if the top level search did not find a position append the menu + if( iInsertPosDefault == -1 ) + { + iInsertPosDefault = pMenuDestination->GetMenuItemCount(); + } + + // create a new popup and insert before or + CMenu NewPopupMenu; + if (!NewPopupMenu.CreatePopupMenu()) + { + TRACE("MergeMenu: CreatePopupMenu failed!\n"); + return false; + } + + // merge the new popup recursivly + if (!MergeMenu(&NewPopupMenu, pSubMenu, false)) + return false; + + // insert the new popup menu into the destination menu + HMENU hNewMenu = NewPopupMenu.GetSafeHmenu(); + if (pMenuDestination->InsertMenu(iInsertPosDefault, + MF_BYPOSITION | MF_POPUP | MF_ENABLED, + (UINT)hNewMenu, sMenuAddString )) + { + // don't forget to correct the item count + iMenuDestItemCount++; + } + else + { + TRACE("MergeMenu: InsertMenu failed!\n"); + return false; + } + + // don't destroy the new menu + NewPopupMenu.Detach(); + } // if (pSubMenu) + } // for (iLoop) + return true; +} + + + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::HandleDrop() { + if (g_PrefsDlg.m_bRightClick == false) { + return; + } + + if (!m_mnuDrop.GetSafeHmenu()) { // first time, load it up + m_mnuDrop.CreatePopupMenu(); + + CMenu *drop = new CMenu; + drop->LoadMenu( IDR_MENU_DROP ); + + MergeMenu( &m_mnuDrop, drop, false ); + + int nID = ID_ENTITY_START; + + CMenu *pMakeEntityPop = &m_mnuDrop; + + // Todo: Make this a config option maybe? + const int entitiesOnSubMenu = false; + if ( entitiesOnSubMenu ) { + pMakeEntityPop = new CMenu; + pMakeEntityPop->CreateMenu(); + } + + CMenu *pChild = NULL; + + eclass_t *e; + CString strActive; + CString strLast; + CString strName; + for (e = eclass; e; e = e->next) { + strLast = strName; + strName = e->name; + + int n_ = strName.Find("_"); + if (n_ > 0) { + CString strLeft = strName.Left(n_); + CString strRight = strName.Right(strName.GetLength() - n_ - 1); + if (strLeft == strActive) { // this is a child + ASSERT(pChild); + pChild->AppendMenu(MF_STRING, nID++, strName); + } + else { + if (pChild) { + pMakeEntityPop->AppendMenu ( + MF_POPUP, + reinterpret_cast < unsigned int > (pChild->GetSafeHmenu()), + strActive + ); + g_ptrMenus.Add(pChild); + + // pChild->DestroyMenu(); delete pChild; + pChild = NULL; + } + + strActive = strLeft; + pChild = new CMenu; + pChild->CreateMenu(); + pChild->AppendMenu(MF_STRING, nID++, strName); + } + } + else { + if (pChild) { + pMakeEntityPop->AppendMenu ( + MF_POPUP, + reinterpret_cast < unsigned int > (pChild->GetSafeHmenu()), + strActive + ); + g_ptrMenus.Add(pChild); + + // pChild->DestroyMenu(); delete pChild; + pChild = NULL; + } + + strActive = ""; + pMakeEntityPop->AppendMenu(MF_STRING, nID++, strName); + } + } + if ( pMakeEntityPop != &m_mnuDrop ) { + m_mnuDrop.AppendMenu ( + MF_POPUP, + reinterpret_cast < unsigned int > (pMakeEntityPop->GetSafeHmenu()), + "Make Entity" + ); + } + } + + CPoint ptMouse; + GetCursorPos(&ptMouse); + m_mnuDrop.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptMouse.x, ptMouse.y, this); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::XY_Init() { + m_vOrigin[0] = 0; + m_vOrigin[1] = 20; + m_vOrigin[2] = 46; + m_fScale = 1; + m_precisionCrosshairMode = PRECISION_CROSSHAIR_NONE; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SnapToPoint(int x, int y, idVec3 &point) { + if (g_PrefsDlg.m_bNoClamp) { + XY_ToPoint(x, y, point); + } + else { + XY_ToGridPoint(x, y, point); + } + + // -- else -- XY_ToPoint(x, y, point); -- //XY_ToPoint(x, y, point); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::XY_ToPoint(int x, int y, idVec3 &point) { + float fx = x; + float fy = y; + float fw = m_nWidth; + float fh = m_nHeight; + if (m_nViewType == XY) { + point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; + point[1] = m_vOrigin[1] + (fy - fh / 2) / m_fScale; + + // point[2] = 0; + } + else if (m_nViewType == YZ) { + // + // //point[0] = 0; point[1] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; point[2] = + // m_vOrigin[1] + (fy - fh / 2 ) / m_fScale; + // + point[1] = m_vOrigin[1] + (fx - fw / 2) / m_fScale; + point[2] = m_vOrigin[2] + (fy - fh / 2) / m_fScale; + } + else { + // + // point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; /point[1] = 0; point[2] = + // m_vOrigin[1] + (fy - fh / 2) / m_fScale; + // + point[0] = m_vOrigin[0] + (fx - fw / 2) / m_fScale; + + // point[1] = 0; + point[2] = m_vOrigin[2] + (fy - fh / 2) / m_fScale; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::XY_ToGridPoint(int x, int y, idVec3 &point) { + if (m_nViewType == XY) { + point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; + point[1] = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale; + + // point[2] = 0; + point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + else if (m_nViewType == YZ) { + // + // point[0] = 0; point[1] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; point[2] + // = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale; + // + point[1] = m_vOrigin[1] + (x - m_nWidth / 2) / m_fScale; + point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale; + point[1] = floor(point[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + else { + // + // point[1] = 0; point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; point[2] + // = m_vOrigin[1] + (y - m_nHeight / 2) / m_fScale; + // + point[0] = m_vOrigin[0] + (x - m_nWidth / 2) / m_fScale; + point[2] = m_vOrigin[2] + (y - m_nHeight / 2) / m_fScale; + point[0] = floor(point[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + point[2] = floor(point[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +idVec3 dragOrigin; +idVec3 dragDir; +idVec3 dragX; +idVec3 dragY; + +void CXYWnd::XY_MouseDown(int x, int y, int buttons) { + idVec3 point,center; + idVec3 origin, dir, right, up; + + m_nButtonstate = buttons; + m_nPressx = x; + m_nPressy = y; + VectorCopy(vec3_origin, m_vPressdelta); + + point.Zero(); + + XY_ToPoint(x, y, point); + + VectorCopy(point, origin); + + dir.Zero(); + if (m_nViewType == XY) { + origin[2] = HUGE_DISTANCE; + dir[2] = -1; + right[0] = 1 / m_fScale; + right[1] = 0; + right[2] = 0; + up[0] = 0; + up[1] = 1 / m_fScale; + up[2] = 0; + point[2] = g_pParentWnd->GetCamera()->Camera().origin[2]; + } + else if (m_nViewType == YZ) { + origin[0] = HUGE_DISTANCE; + dir[0] = -1; + right[1] = 1 / m_fScale; + right[2] = 0; + right[0] = 0; + up[0] = 0; + up[2] = 1 / m_fScale; + up[1] = 0; + point[0] = g_pParentWnd->GetCamera()->Camera().origin[0]; + } + else { + origin[1] = HUGE_DISTANCE; + dir[1] = -1; + right[0] = 1 / m_fScale; + right[2] = 0; + right[1] = 0; + up[0] = 0; + up[2] = 1 / m_fScale; + up[1] = 0; + point[1] = g_pParentWnd->GetCamera()->Camera().origin[1]; + } + + dragOrigin = m_vOrigin; + dragDir = dir; + dragX = right; + dragY = up; + + m_bPress_selection = (selected_brushes.next != &selected_brushes); + + GetCursorPos(&m_ptCursor); + + // Sys_GetCursorPos (&m_ptCursor.x, &m_ptCursor.y); + if (buttons == MK_LBUTTON && activeDrag) { + activeDragging = true; + } + else { + activeDragging = false; + } + + // lbutton = manipulate selection shift-LBUTTON = select + if + ( + (buttons == MK_LBUTTON) || + (buttons == (MK_LBUTTON | MK_SHIFT)) || + (buttons == (MK_LBUTTON | MK_CONTROL)) || + (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) + ) { + if (g_qeglobals.d_select_mode == sel_addpoint) { + XY_ToGridPoint(x, y, point); + if (g_qeglobals.selectObject) { + g_qeglobals.selectObject->addPoint(point); + } + + return; + } + + Patch_SetView((m_nViewType == XY) ? W_XY : (m_nViewType == YZ) ? W_YZ : W_XZ); + Drag_Begin(x, y, buttons, right, up, origin, dir); + return; + } + + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + + // control mbutton = move camera + if (m_nButtonstate == (MK_CONTROL | nMouseButton)) { + VectorCopyXY(point, g_pParentWnd->GetCamera()->Camera().origin); + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY); + } + + // mbutton = angle camera + if + ( + (g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) || + (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT | MK_CONTROL | MK_RBUTTON)) + ) { + VectorSubtract(point, g_pParentWnd->GetCamera()->Camera().origin, point); + + int n1 = (m_nViewType == XY) ? 1 : 2; + int n2 = (m_nViewType == YZ) ? 1 : 0; + int nAngle = (m_nViewType == XY) ? YAW : PITCH; + if (point[n1] || point[n2]) { + g_pParentWnd->GetCamera()->Camera().angles[nAngle] = RAD2DEG( atan2(point[n1], point[n2]) ); + Sys_UpdateWindows(W_CAMERA_IFON | W_XY_OVERLAY); + } + } + + // shift mbutton = move z checker + if (m_nButtonstate == (MK_SHIFT | nMouseButton)) { + if (RotateMode() || g_bPatchBendMode) { + SnapToPoint(x, y, point); + VectorCopyXY(point, g_vRotateOrigin); + if (g_bPatchBendMode) { + VectorCopy(point, g_vBendOrigin); + } + + Sys_UpdateWindows(W_XY); + return; + } + else { + SnapToPoint(x, y, point); + if (m_nViewType == XY) { + z.origin[0] = point[0]; + z.origin[1] = point[1]; + } + else if (m_nViewType == YZ) { + z.origin[0] = point[1]; + z.origin[1] = point[2]; + } + else { + z.origin[0] = point[0]; + z.origin[1] = point[2]; + } + + Sys_UpdateWindows(W_XY_OVERLAY | W_Z); + return; + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::XY_MouseUp(int x, int y, int buttons) { + activeDragging = false; + Drag_MouseUp(buttons); + if (!m_bPress_selection) { + Sys_UpdateWindows(W_ALL); + } + + m_nButtonstate = 0; + while (::ShowCursor(TRUE) < 0) + ; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::DragDelta(int x, int y, idVec3 &move) { + idVec3 xvec, yvec, delta; + int i; + + xvec[0] = 1 / m_fScale; + xvec[1] = xvec[2] = 0; + yvec[1] = 1 / m_fScale; + yvec[0] = yvec[2] = 0; + + for (i = 0; i < 3; i++) { + delta[i] = xvec[i] * (x - m_nPressx) + yvec[i] * (y - m_nPressy); + if (!g_PrefsDlg.m_bNoClamp) { + delta[i] = floor(delta[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + } + } + + VectorSubtract(delta, m_vPressdelta, move); + VectorCopy(delta, m_vPressdelta); + + + if (move[0] || move[1] || move[2]) { + return true; + } + + return false; +} + +/* + ======================================================================================================================= + NewBrushDrag + ======================================================================================================================= + */ +void CXYWnd::NewBrushDrag(int x, int y) { + idVec3 mins, maxs, junk; + int i; + float temp; + brush_t *n; + + if ( radiant_entityMode.GetBool() ) { + return; + } + + if (!DragDelta(x, y, junk)) { + return; + } + + // delete the current selection + if (selected_brushes.next != &selected_brushes) { + Brush_Free(selected_brushes.next); + } + + SnapToPoint(m_nPressx, m_nPressy, mins); + + int nDim = (m_nViewType == XY) ? 2 : (m_nViewType == YZ) ? 0 : 1; + + mins[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom[nDim] / g_qeglobals.d_gridsize)); + SnapToPoint(x, y, maxs); + maxs[nDim] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top[nDim] / g_qeglobals.d_gridsize)); + if (maxs[nDim] <= mins[nDim]) { + maxs[nDim] = mins[nDim] + g_qeglobals.d_gridsize; + } + + for (i = 0; i < 3; i++) { + if (mins[i] == maxs[i]) { + return; // don't create a degenerate brush + } + + if (mins[i] > maxs[i]) { + temp = mins[i]; + mins[i] = maxs[i]; + maxs[i] = temp; + } + } + + n = Brush_Create(mins, maxs, &g_qeglobals.d_texturewin.texdef); + if (!n) { + return; + } + + idVec3 vSize; + VectorSubtract(maxs, mins, vSize); + g_strStatus.Format("Size X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]); + g_pParentWnd->SetStatusText(2, g_strStatus); + + Brush_AddToList(n, &selected_brushes); + + Entity_LinkBrush(world_entity, n); + + Brush_Build(n); + + // Sys_UpdateWindows (W_ALL); + Sys_UpdateWindows(W_XY | W_CAMERA); +} + +/* + ======================================================================================================================= + XY_MouseMoved + ======================================================================================================================= + */ +bool CXYWnd::XY_MouseMoved(int x, int y, int buttons) { + idVec3 point; + + if (!m_nButtonstate) { + if (g_bCrossHairs) { + ::ShowCursor(FALSE); + Sys_UpdateWindows(W_XY | W_XY_OVERLAY); + ::ShowCursor(TRUE); + } + + return false; + } + + // + // lbutton without selection = drag new brush if (m_nButtonstate == MK_LBUTTON && + // !m_bPress_selection && g_qeglobals.d_select_mode != sel_curvepoint && + // g_qeglobals.d_select_mode != sel_splineedit) + // + if (m_nButtonstate == MK_LBUTTON && !m_bPress_selection && g_qeglobals.d_select_mode == sel_brush) { + NewBrushDrag(x, y); + return false; + } + + // lbutton (possibly with control and or shift) with selection = drag selection + if (m_nButtonstate & MK_LBUTTON) { + Drag_MouseMoved(x, y, buttons); + Sys_UpdateWindows(W_XY_OVERLAY | W_CAMERA_IFON | W_Z); + return false; + } + + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + + // control mbutton = move camera + if (m_nButtonstate == (MK_CONTROL | nMouseButton)) { + SnapToPoint(x, y, point); + VectorCopyXY(point, g_pParentWnd->GetCamera()->Camera().origin); + Sys_UpdateWindows(W_XY_OVERLAY | W_CAMERA); + return false; + } + + // shift mbutton = move z checker + if (m_nButtonstate == (MK_SHIFT | nMouseButton)) { + if (RotateMode() || g_bPatchBendMode) { + SnapToPoint(x, y, point); + VectorCopyXY(point, g_vRotateOrigin); + if (g_bPatchBendMode) { + VectorCopy(point, g_vBendOrigin); + } + + Sys_UpdateWindows(W_XY); + return false; + } + else { + SnapToPoint(x, y, point); + if (m_nViewType == XY) { + z.origin[0] = point[0]; + z.origin[1] = point[1]; + } + else if (m_nViewType == YZ) { + z.origin[0] = point[1]; + z.origin[1] = point[2]; + } + else { + z.origin[0] = point[0]; + z.origin[1] = point[2]; + } + } + + Sys_UpdateWindows(W_XY_OVERLAY | W_Z); + return false; + } + + // mbutton = angle camera + if + ( + (g_PrefsDlg.m_nMouseButtons == 3 && m_nButtonstate == MK_MBUTTON) || + (g_PrefsDlg.m_nMouseButtons == 2 && m_nButtonstate == (MK_SHIFT | MK_CONTROL | MK_RBUTTON)) + ) { + SnapToPoint(x, y, point); + VectorSubtract(point, g_pParentWnd->GetCamera()->Camera().origin, point); + + int n1 = (m_nViewType == XY) ? 1 : 2; + int n2 = (m_nViewType == YZ) ? 1 : 0; + int nAngle = (m_nViewType == XY) ? YAW : PITCH; + if (point[n1] || point[n2]) { + g_pParentWnd->GetCamera()->Camera().angles[nAngle] = RAD2DEG( atan2(point[n1], point[n2]) ); + Sys_UpdateWindows(W_CAMERA_IFON | W_XY_OVERLAY); + } + + return false; + } + + // rbutton = drag xy origin + if (m_nButtonstate == MK_RBUTTON) { + Sys_GetCursorPos(&x, &y); + + if (x != m_ptCursor.x || y != m_ptCursor.y) { + if ((GetAsyncKeyState(VK_MENU) & 0x8000)) { + int *px = &x; + long *px2 = &m_ptCursor.x; + + if (fDiff(y, m_ptCursor.y) > fDiff(x, m_ptCursor.x)) { + px = &y; + px2 = &m_ptCursor.y; + } + + if (*px > *px2) { + // zoom in + SetScale( Scale() * 1.1f ); + if ( Scale() < 0.1f ) { + SetScale( 0.1f ); + } + } + else if (*px < *px2) { + // zoom out + SetScale( Scale() * 0.9f ); + if ( Scale() > 16.0f ) { + SetScale( 16.0f ); + } + } + + *px2 = *px; + Sys_UpdateWindows(W_XY | W_XY_OVERLAY); + } + else { + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + m_vOrigin[nDim1] -= (x - m_ptCursor.x) / m_fScale; + m_vOrigin[nDim2] += (y - m_ptCursor.y) / m_fScale; + SetCursorPos(m_ptCursor.x, m_ptCursor.y); + ::ShowCursor(FALSE); + + // XY_Draw(); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + Sys_UpdateWindows(W_XY | W_XY_OVERLAY); + + // ::ShowCursor(TRUE); + } + } + + return false; + } + + return false; +} + +/* + ======================================================================================================================= + DRAWING £ + XY_DrawGrid + ======================================================================================================================= + */ +void CXYWnd::XY_DrawGrid() { + float x, y, xb, xe, yb, ye; + int w, h; + char text[32]; + + int startPos = max ( 64 , g_qeglobals.d_gridsize ); + + w = m_nWidth / 2 / m_fScale; + h = m_nHeight / 2 / m_fScale; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + + // int nDim1 = 0; int nDim2 = 1; + xb = m_vOrigin[nDim1] - w; + if (xb < region_mins[nDim1]) { + xb = region_mins[nDim1]; + } + + xb = startPos * floor(xb / startPos); + + xe = m_vOrigin[nDim1] + w; + if (xe > region_maxs[nDim1]) { + xe = region_maxs[nDim1]; + } + + xe = startPos * ceil(xe / startPos); + + yb = m_vOrigin[nDim2] - h; + if (yb < region_mins[nDim2]) { + yb = region_mins[nDim2]; + } + + yb = startPos * floor(yb / startPos); + + ye = m_vOrigin[nDim2] + h; + if (ye > region_maxs[nDim2]) { + ye = region_maxs[nDim2]; + } + + ye = startPos * ceil(ye / startPos); + + // draw major blocks + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR].ToFloatPtr()); + + int stepSize = 64 * 0.1 / m_fScale; + if (stepSize < 64) { + stepSize = max ( 64 , g_qeglobals.d_gridsize ); + } + else { + int i; + for (i = 1; i < stepSize; i <<= 1) { + } + + stepSize = i; + } + + if (g_qeglobals.d_showgrid) { + qglBegin(GL_LINES); + + for (x = xb; x <= xe; x += stepSize) { + qglVertex2f(x, yb); + qglVertex2f(x, ye); + } + + for (y = yb; y <= ye; y += stepSize) { + qglVertex2f(xb, y); + qglVertex2f(xe, y); + } + + qglEnd(); + } + + // draw minor blocks + if ( m_fScale > .1 && + g_qeglobals.d_showgrid && + g_qeglobals.d_gridsize * m_fScale >= 4 && + !g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].Compare( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) ) { + + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].ToFloatPtr()); + + qglBegin(GL_LINES); + for (x = xb; x < xe; x += g_qeglobals.d_gridsize) { + if (!((int)x & (startPos - 1))) { + continue; + } + + qglVertex2f(x, yb); + qglVertex2f(x, ye); + } + + for (y = yb; y < ye; y += g_qeglobals.d_gridsize) { + if (!((int)y & (startPos - 1))) { + continue; + } + + qglVertex2f(xb, y); + qglVertex2f(xe, y); + } + + qglEnd(); + } + + + // draw ZClip boundaries (if applicable)... + // + if (m_nViewType == XZ || m_nViewType == YZ) + { + if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case at this point I think, but this is safer + { + if (g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled()) + { + qglColor3f(ZCLIP_COLOUR); + qglLineWidth(2); + qglBegin (GL_LINES); + + qglVertex2f (xb, g_pParentWnd->GetZWnd()->m_pZClip->GetTop()); + qglVertex2f (xe, g_pParentWnd->GetZWnd()->m_pZClip->GetTop()); + + qglVertex2f (xb, g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()); + qglVertex2f (xe, g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()); + + qglEnd (); + qglLineWidth(1); + } + } + } + + + + + // draw coordinate text if needed + if (g_qeglobals.d_savedinfo.show_coordinates) { + // glColor4f(0, 0, 0, 0); + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT].ToFloatPtr()); + + float lastRaster = xb; + + for (x = xb; x < xe; x += stepSize) { + qglRasterPos2f(x, m_vOrigin[nDim2] + h - 10 / m_fScale); + sprintf(text, "%i", (int)x); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); + } + + for (y = yb; y < ye; y += stepSize) { + qglRasterPos2f(m_vOrigin[nDim1] - w + 1, y); + sprintf(text, "%i", (int)y); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); + } + + if (Active()) { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME].ToFloatPtr()); + } + + qglRasterPos2f(m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); + + char cView[20]; + if (m_nViewType == XY) { + strcpy(cView, "XY Top"); + } + else if (m_nViewType == XZ) { + strcpy(cView, "XZ Front"); + } + else { + strcpy(cView, "YZ Side"); + } + + qglCallLists(strlen(cView), GL_UNSIGNED_BYTE, cView); + } + + /* + * if (true) { qglColor3f(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]); + * qglBegin (GL_LINES); qglVertex2f (x, yb); qglVertex2f (x, ye); qglEnd(); } + */ +} + +/* + ======================================================================================================================= + XY_DrawBlockGrid + ======================================================================================================================= + */ +void CXYWnd::XY_DrawBlockGrid() { + float x, y, xb, xe, yb, ye; + int w, h; + char text[32]; + + w = m_nWidth / 2 / m_fScale; + h = m_nHeight / 2 / m_fScale; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + + xb = m_vOrigin[nDim1] - w; + if (xb < region_mins[nDim1]) { + xb = region_mins[nDim1]; + } + + xb = 1024 * floor(xb / 1024); + + xe = m_vOrigin[nDim1] + w; + if (xe > region_maxs[nDim1]) { + xe = region_maxs[nDim1]; + } + + xe = 1024 * ceil(xe / 1024); + + yb = m_vOrigin[nDim2] - h; + if (yb < region_mins[nDim2]) { + yb = region_mins[nDim2]; + } + + yb = 1024 * floor(yb / 1024); + + ye = m_vOrigin[nDim2] + h; + if (ye > region_maxs[nDim2]) { + ye = region_maxs[nDim2]; + } + + ye = 1024 * ceil(ye / 1024); + + // draw major blocks + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK].ToFloatPtr()); + qglLineWidth(0.5); + + qglBegin(GL_LINES); + + for (x = xb; x <= xe; x += 1024) { + qglVertex2f(x, yb); + qglVertex2f(x, ye); + } + + for (y = yb; y <= ye; y += 1024) { + qglVertex2f(xb, y); + qglVertex2f(xe, y); + } + + qglEnd(); + qglLineWidth(0.25); + + // draw coordinate text if needed + for (x = xb; x < xe; x += 1024) { + for (y = yb; y < ye; y += 1024) { + qglRasterPos2f(x + 512, y + 512); + sprintf(text, "%i,%i", (int)floor(x / 1024), (int)floor(y / 1024)); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); + } + } + + qglColor4f(0, 0, 0, 0); +} + +void GLColoredBoxWithLabel(float x, float y, float size, idVec4 color, const char *text, idVec4 textColor, float xofs, float yofs, float lineSize) { + globalImages->BindNull(); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_CULL_FACE); + qglDisable(GL_BLEND); + qglColor4f(color[0], color[1], color[2], color[3]); + qglBegin(GL_QUADS); + qglVertex3f(x - size, y - size, 0); + qglVertex3f(x + size, y - size, 0); + qglVertex3f(x + size, y + size, 0); + qglVertex3f(x - size, y + size, 0); + qglEnd(); + + qglColor4f(textColor[0], textColor[1], textColor[2], textColor[3]); + qglLineWidth(lineSize); + qglRasterPos2f(x + xofs, y + yofs); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::DrawRotateIcon() { + float x, y; + + if (m_nViewType == XY) { + x = g_vRotateOrigin[0]; + y = g_vRotateOrigin[1]; + } + else if (m_nViewType == YZ) { + x = g_vRotateOrigin[1]; + y = g_vRotateOrigin[2]; + } + else { + x = g_vRotateOrigin[0]; + y = g_vRotateOrigin[2]; + } + + qglEnable(GL_BLEND); + globalImages->BindNull(); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_CULL_FACE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglColor4f( 0.8f, 0.1f, 0.9f, 0.25f ); + + qglBegin(GL_QUADS); + qglVertex3f(x - 4, y - 4, 0); + qglVertex3f(x + 4, y - 4, 0); + qglVertex3f(x + 4, y + 4, 0); + qglVertex3f(x - 4, y + 4, 0); + qglEnd(); + qglDisable(GL_BLEND); + + qglColor4f( 1.0f, 0.2f, 1.0f, 1.0f ); + qglBegin(GL_POINTS); + qglVertex3f(x, y, 0); + qglEnd(); + + + int w = m_nWidth / 2 / m_fScale; + int h = m_nHeight / 2 / m_fScale; + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + x = m_vOrigin[nDim1] - w + 35 / m_fScale; + y = m_vOrigin[nDim2] + h - 40 / m_fScale; + const char *p = "Rotate Z Axis"; + if (g_qeglobals.rotateAxis == 1) { + p = "Rotate Y Axis"; + } else if (g_qeglobals.rotateAxis == 0) { + p = "Rotate X Axis"; + } + idStr str = p; + if (g_qeglobals.flatRotation) { + str += g_qeglobals.flatRotation == 2 ? " Flat [center] " : " Flat [ rot origin ] "; + } + qglRasterPos2f(x, y); + qglCallLists(str.Length(), GL_UNSIGNED_BYTE, str.c_str()); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::DrawCameraIcon() { + float x, y, a; + + if (m_nViewType == XY) { + x = g_pParentWnd->GetCamera()->Camera().origin[0]; + y = g_pParentWnd->GetCamera()->Camera().origin[1]; + a = g_pParentWnd->GetCamera()->Camera().angles[YAW] * idMath::M_DEG2RAD; + } + else if (m_nViewType == YZ) { + x = g_pParentWnd->GetCamera()->Camera().origin[1]; + y = g_pParentWnd->GetCamera()->Camera().origin[2]; + a = g_pParentWnd->GetCamera()->Camera().angles[PITCH] * idMath::M_DEG2RAD; + } + else { + x = g_pParentWnd->GetCamera()->Camera().origin[0]; + y = g_pParentWnd->GetCamera()->Camera().origin[2]; + a = g_pParentWnd->GetCamera()->Camera().angles[PITCH] * idMath::M_DEG2RAD; + } + + float scale = 1.0/m_fScale; //jhefty - keep the camera icon proportionally the same size + + qglColor3f(0.0, 0.0, 1.0); + qglBegin(GL_LINE_STRIP); + qglVertex3f(x - 16*scale, y, 0); + qglVertex3f(x, y + 8*scale, 0); + qglVertex3f(x + 16*scale, y, 0); + qglVertex3f(x, y - 8*scale, 0); + qglVertex3f(x - 16*scale, y, 0); + qglVertex3f(x + 16*scale, y, 0); + qglEnd(); + + qglBegin(GL_LINE_STRIP); + qglVertex3f(x + (48 * cos( a + idMath::PI * 0.25f )*scale), y + (48 * sin( a + idMath::PI * 0.25f )*scale), 0); + qglVertex3f(x, y, 0); + qglVertex3f(x + (48 * cos( a - idMath::PI * 0.25f )*scale), y + (48 * sin( a - idMath::PI * 0.25f )*scale), 0); + qglEnd(); + +#if 0 + + char text[128]; + qglRasterPos2f(x + 64, y + 64); + sprintf(text, "%f", g_pParentWnd->GetCamera()->Camera().angles[YAW]); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::DrawZIcon(void) { + if (m_nViewType == XY) { + float x = z.origin[0]; + float y = z.origin[1]; + qglEnable(GL_BLEND); + globalImages->BindNull(); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_CULL_FACE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglColor4f(0.0, 0.0, 1.0, 0.25); + qglBegin(GL_QUADS); + qglVertex3f(x - 8, y - 8, 0); + qglVertex3f(x + 8, y - 8, 0); + qglVertex3f(x + 8, y + 8, 0); + qglVertex3f(x - 8, y + 8, 0); + qglEnd(); + qglDisable(GL_BLEND); + + qglColor4f(0.0, 0.0, 1.0, 1); + + qglBegin(GL_LINE_LOOP); + qglVertex3f(x - 8, y - 8, 0); + qglVertex3f(x + 8, y - 8, 0); + qglVertex3f(x + 8, y + 8, 0); + qglVertex3f(x - 8, y + 8, 0); + qglEnd(); + + qglBegin(GL_LINE_STRIP); + qglVertex3f(x - 4, y + 4, 0); + qglVertex3f(x + 4, y + 4, 0); + qglVertex3f(x - 4, y - 4, 0); + qglVertex3f(x + 4, y - 4, 0); + qglEnd(); + } +} + +/* + ======================================================================================================================= + FilterBrush + ======================================================================================================================= + */ +bool FilterBrush(brush_t *pb) { + + if (!pb->owner) { + return false; // during construction + } + + if (pb->hiddenBrush) { + return true; + } + + if ( pb->forceVisibile ) { + return false; + } + + if (g_pParentWnd->GetZWnd()->m_pZClip) // ZClip class up and running? (and hence Z window built) + { + if (g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled()) + { + // ZClipping active... + // + if (pb->mins[2] > g_pParentWnd->GetZWnd()->m_pZClip->GetTop() // brush bottom edge is above clip top + || + pb->maxs[2] < g_pParentWnd->GetZWnd()->m_pZClip->GetBottom()// brush top edge is below clip bottom + ) + { + return TRUE; + } + } + } + + if (g_qeglobals.d_savedinfo.exclude & (EXCLUDE_CAULK | EXCLUDE_VISPORTALS)) { + // + // filter out the brush only if all faces are caulk if not don't hide the whole + // brush, proceed on a per-face basis (Cam_Draw) ++timo TODO: set this as a + // preference .. show caulk: hide any brush with caulk // don't draw caulk faces + // + face_t *f; + f = pb->brush_faces; + while (f) { + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { + if (!strstr(f->texdef.name, "caulk")) { + break; + } + } else { + if (strstr(f->texdef.name, "visportal")) { + return true; + } + } + + f = f->next; + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) { + if (!f) { + return true; + } + } + + // ++timo FIXME: .. same deal here? + if (strstr(pb->brush_faces->texdef.name, "donotenter")) { + return true; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINT) { + if (strstr(pb->brush_faces->texdef.name, "hint")) { + return true; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) { + if (strstr(pb->brush_faces->texdef.name, "clip")) { + return true; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) { + if (strstr(pb->brush_faces->texdef.name, "trig")) { + return true; + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_NODRAW) { + if (strstr(pb->brush_faces->texdef.name, "nodraw")) { + return true; + } + } + + + if (strstr(pb->brush_faces->texdef.name, "skip")) { + return true; + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DYNAMICS) { + if (pb->modelHandle > 0) { + idRenderModel *model = pb->modelHandle; + if ( dynamic_cast(model) ) { + return true; + } + } + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES) { + if (pb->pPatch) { + return true; + } + } + + if (pb->owner == world_entity) { + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) { + return true; + } + + return false; + } + else { + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT ) { + return ( idStr::Cmpn( pb->owner->eclass->name, "func_static", 10 ) != 0 ); + } + } + + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS && pb->owner->eclass->nShowFlags & ECLASS_LIGHT ) { + return true; + } + + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_COMBATNODES && pb->owner->eclass->nShowFlags & ECLASS_COMBATNODE ) { + return true; + } + + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS && pb->owner->eclass->nShowFlags & ECLASS_PATH) { + return true; + } + + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS && ( pb->owner->eclass->entityModel != NULL || pb->modelHandle > 0 ) ) { + return true; + } + + return false; +} + +/* + ======================================================================================================================= + PATH LINES £ + DrawPathLines Draws connections between entities. Needs to consider all entities, not just ones on screen, because + the lines can be visible when neither end is. Called for both camera view and xy view. + ======================================================================================================================= + */ +void DrawPathLines(void) { + int i, k; + idVec3 mid, mid1; + entity_t *se, *te; + brush_t *sb, *tb; + const char *psz; + idVec3 dir, s1, s2; + float len, f; + int arrows; + int num_entities; + const char *ent_target[MAX_MAP_ENTITIES]; + entity_t *ent_entity[MAX_MAP_ENTITIES]; + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) { + return; + } + + num_entities = 0; + for (te = entities.next; te != &entities && num_entities != MAX_MAP_ENTITIES; te = te->next) { + for (int i = 0; i < 2048; i++) { + if (i == 0) { + ent_target[num_entities] = ValueForKey(te, "target"); + } else { + ent_target[num_entities] = ValueForKey(te, va("target%i", i)); + } + if (ent_target[num_entities][0]) { + ent_entity[num_entities] = te; + num_entities++; + } else if (i > 16) { + break; + } + } + } + + for (se = entities.next; se != &entities; se = se->next) { + psz = ValueForKey(se, "name"); + + if (psz == NULL || psz[0] == '\0') { + continue; + } + + sb = se->brushes.onext; + if (sb == &se->brushes) { + continue; + } + + for (k = 0; k < num_entities; k++) { + if (strcmp(ent_target[k], psz)) { + continue; + } + + te = ent_entity[k]; + tb = te->brushes.onext; + if (tb == &te->brushes) { + continue; + } + + mid = sb->owner->origin; + mid1 = tb->owner->origin; + + VectorSubtract(mid1, mid, dir); + len = dir.Normalize(); + s1[0] = -dir[1] * 8 + dir[0] * 8; + s2[0] = dir[1] * 8 + dir[0] * 8; + s1[1] = dir[0] * 8 + dir[1] * 8; + s2[1] = -dir[0] * 8 + dir[1] * 8; + + qglColor3f(se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]); + + qglBegin(GL_LINES); + qglVertex3fv(mid.ToFloatPtr()); + qglVertex3fv(mid1.ToFloatPtr()); + + arrows = (int)(len / 256) + 1; + + for (i = 0; i < arrows; i++) { + f = len * (i + 0.5) / arrows; + + mid1 = mid + (f * dir); + + qglVertex3fv(mid1.ToFloatPtr()); + qglVertex3f(mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]); + qglVertex3fv(mid1.ToFloatPtr()); + qglVertex3f(mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]); + } + + qglEnd(); + } + } + + return; +} + +// +// ======================================================================================================================= +// can be greatly simplified but per usual i am in a hurry which is not an excuse, just a fact +// ======================================================================================================================= +// +void CXYWnd::PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds) { + idVec3 vSize; + VectorSubtract(vMaxBounds, vMinBounds, vSize); + + qglColor3f + ( + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] * .65, + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] * .65, + g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] * .65 + ); + + if (m_nViewType == XY) { + qglBegin(GL_LINES); + + qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); + qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); + + qglVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); + qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); + + qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); + qglVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); + + qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); + + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); + + qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); + + qglEnd(); + + qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale, 0.0f); + g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f); + g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f); + g_strDim.Format(g_pOrgStrings[0], vMinBounds[nDim1], vMaxBounds[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + } + else if (m_nViewType == XZ) { + qglBegin(GL_LINES); + + qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); + qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); + qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); + qglVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); + + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); + + qglVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]); + qglVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); + + qglEnd(); + + qglRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0 / m_fScale); + g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(vMaxBounds[nDim1] + 16.0 / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); + g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale); + g_strDim.Format(g_pOrgStrings[1], vMinBounds[nDim1], vMaxBounds[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + } + else { + qglBegin(GL_LINES); + + qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); + qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); + qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); + qglVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); + + qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]); + qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); + + qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); + qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); + + qglVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]); + qglVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); + + qglEnd(); + + qglRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0 / m_fScale); + g_strDim.Format(g_pDimStrings[nDim1], vSize[nDim1]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(0, vMaxBounds[nDim1] + 16.0 / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); + g_strDim.Format(g_pDimStrings[nDim2], vSize[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + + qglRasterPos3f(0, vMinBounds[nDim1] + 4.0, vMaxBounds[nDim2] + 8 / m_fScale); + g_strDim.Format(g_pOrgStrings[2], vMinBounds[nDim1], vMaxBounds[nDim2]); + qglCallLists(g_strDim.GetLength(), GL_UNSIGNED_BYTE, g_strDim); + } +} + +/* XY_Draw */ +long g_lCount = 0; +long g_lTotal = 0; +extern void DrawBrushEntityName(brush_t *b); + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::XY_Draw() { + brush_t *brush; + float w, h; + entity_t *e; + idVec3 mins, maxs; + int drawn, culled; + int i; + + if (!active_brushes.next) { + return; // not valid yet + } + + // clear + m_bDirty = false; + + GL_State( GLS_DEFAULT ); + qglViewport(0, 0, m_nWidth, m_nHeight); + qglScissor(0, 0, m_nWidth, m_nHeight); + qglClearColor + ( + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], + 0 + ); + + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_CULL_FACE); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // set up viewpoint + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + + w = m_nWidth / 2 / m_fScale; + h = m_nHeight / 2 / m_fScale; + + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + mins[0] = m_vOrigin[nDim1] - w; + maxs[0] = m_vOrigin[nDim1] + w; + mins[1] = m_vOrigin[nDim2] - h; + maxs[1] = m_vOrigin[nDim2] + h; + + idBounds viewBounds( mins, maxs ); + viewBounds[0].z = -99999; + viewBounds[1].z = 99999; + + qglOrtho(mins[0], maxs[0], mins[1], maxs[1], MIN_WORLD_COORD, MAX_WORLD_COORD); + + // draw stuff + globalImages->BindNull(); + // now draw the grid + qglLineWidth(0.25); + XY_DrawGrid(); + qglLineWidth(0.5); + + drawn = culled = 0; + + if (m_nViewType != XY) { + qglPushMatrix(); + if (m_nViewType == YZ) { + qglRotatef(-90, 0, 1, 0); // put Z going up + } + + // else + qglRotatef(-90, 1, 0, 0); // put Z going up + } + + e = world_entity; + + for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next ) { + if ( brush->forceVisibile || ( brush->owner->eclass->nShowFlags & ( ECLASS_LIGHT | ECLASS_PROJECTEDLIGHT ) ) ) { + } else if ( brush->mins[nDim1] > maxs[0] || brush->mins[nDim2] > maxs[1] || brush->maxs[nDim1] < mins[0] || brush->maxs[nDim2] < mins[1] ) { + culled++; + continue; // off screen + } + + if ( FilterBrush(brush) ) { + continue; + } + + drawn++; + + if (brush->owner != e && brush->owner) { + qglColor3fv(brush->owner->eclass->color.ToFloatPtr()); + } + else { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES].ToFloatPtr()); + } + + Brush_DrawXY( brush, m_nViewType ); + } + + DrawPathLines(); + + // draw pointfile + if (g_qeglobals.d_pointfile_display_list) { + qglCallList(g_qeglobals.d_pointfile_display_list); + } + + if (!(m_nViewType == XY)) { + qglPopMatrix(); + } + + // draw block grid + if (g_qeglobals.show_blocks) { + XY_DrawBlockGrid(); + } + + // now draw selected brushes + if (m_nViewType != XY) { + qglPushMatrix(); + if (m_nViewType == YZ) { + qglRotatef(-90, 0, 1, 0); // put Z going up + } + + // else + qglRotatef(-90, 1, 0, 0); // put Z going up + } + + qglPushMatrix(); + qglTranslatef + ( + g_qeglobals.d_select_translate[0], + g_qeglobals.d_select_translate[1], + g_qeglobals.d_select_translate[2] + ); + + if (RotateMode()) { + qglColor3f( 0.8f, 0.1f, 0.9f ); + } + else if (ScaleMode()) { + qglColor3f( 0.1f, 0.8f, 0.1f ); + } + else { + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); + } + + if (g_PrefsDlg.m_bNoStipple == FALSE) { + qglEnable(GL_LINE_STIPPLE); + qglLineStipple(3, 0xaaaa); + } + + qglLineWidth(1); + + idVec3 vMinBounds; + idVec3 vMaxBounds; + vMinBounds[0] = vMinBounds[1] = vMinBounds[2] = 999999.9f; + vMaxBounds[0] = vMaxBounds[1] = vMaxBounds[2] = -999999.9f; + + int nSaveDrawn = drawn; + bool bFixedSize = false; + for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { + drawn++; + Brush_DrawXY(brush, m_nViewType, true); + + if (!bFixedSize) { + if (brush->owner->eclass->fixedsize) { + bFixedSize = true; + } + + if (g_PrefsDlg.m_bSizePaint) { + for (i = 0; i < 3; i++) { + if (brush->mins[i] < vMinBounds[i]) { + vMinBounds[i] = brush->mins[i]; + } + + if (brush->maxs[i] > vMaxBounds[i]) { + vMaxBounds[i] = brush->maxs[i]; + } + } + } + } + } + + if (g_PrefsDlg.m_bNoStipple == FALSE) { + qglDisable(GL_LINE_STIPPLE); + } + + qglLineWidth(0.5); + + if (!bFixedSize && !RotateMode() && !ScaleMode() && drawn - nSaveDrawn > 0 && g_PrefsDlg.m_bSizePaint) { + PaintSizeInfo(nDim1, nDim2, vMinBounds, vMaxBounds); + } + + // edge / vertex flags + if (g_qeglobals.d_select_mode == sel_vertex) { + qglPointSize(4); + qglColor3f(0, 1, 0); + qglBegin(GL_POINTS); + for (i = 0; i < g_qeglobals.d_numpoints; i++) { + qglVertex3fv(g_qeglobals.d_points[i].ToFloatPtr()); + } + + qglEnd(); + qglPointSize(1); + } + else if (g_qeglobals.d_select_mode == sel_edge) { + float *v1, *v2; + + qglPointSize(4); + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for (i = 0; i < g_qeglobals.d_numedges; i++) { + v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr(); + v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr(); + qglVertex3f((v1[0] + v2[0]) * 0.5, (v1[1] + v2[1]) * 0.5, (v1[2] + v2[2]) * 0.5); + } + + qglEnd(); + qglPointSize(1); + } + + g_splineList->draw (static_cast(g_qeglobals.d_select_mode == sel_editpoint || g_qeglobals.d_select_mode == sel_addpoint)); + + if (g_pParentWnd->GetNurbMode() && g_pParentWnd->GetNurb()->GetNumValues()) { + int maxage = g_pParentWnd->GetNurb()->GetNumValues(); + int time = 0; + qglColor3f(0, 0, 1); + qglPointSize(1); + qglBegin(GL_POINTS); + g_pParentWnd->GetNurb()->SetOrder(3); + for (i = 0; i < 100; i++) { + idVec2 v = g_pParentWnd->GetNurb()->GetCurrentValue(time); + qglVertex3f(v.x, v.y, 0.0f); + time += 10; + } + qglEnd(); + qglPointSize(4); + qglColor3f(0, 0, 1); + qglBegin(GL_POINTS); + for (i = 0; i < maxage; i++) { + idVec2 v = g_pParentWnd->GetNurb()->GetValue(i); + qglVertex3f(v.x, v.y, 0.0f); + } + qglEnd(); + qglPointSize(1); + } + + qglPopMatrix(); + + qglTranslatef + ( + -g_qeglobals.d_select_translate[0], + -g_qeglobals.d_select_translate[1], + -g_qeglobals.d_select_translate[2] + ); + + if (!(m_nViewType == XY)) { + qglPopMatrix(); + } + + // area selection hack + if (g_qeglobals.d_select_mode == sel_area) { + qglEnable(GL_BLEND); + qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglColor4f(0.0, 0.0, 1.0, 0.25); + qglRectf + ( + g_qeglobals.d_vAreaTL[nDim1], + g_qeglobals.d_vAreaTL[nDim2], + g_qeglobals.d_vAreaBR[nDim1], + g_qeglobals.d_vAreaBR[nDim2] + ); + qglDisable(GL_BLEND); + qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ); + qglColor3f(1.0f, 1.0f, 1.0f); + qglRectf + ( + g_qeglobals.d_vAreaTL[nDim1], + g_qeglobals.d_vAreaTL[nDim2], + g_qeglobals.d_vAreaBR[nDim1], + g_qeglobals.d_vAreaBR[nDim2] + ); + + } + + // now draw camera point + DrawCameraIcon(); + DrawZIcon(); + + if (RotateMode()) { + DrawRotateIcon(); + } + + /// Draw a "precision crosshair" if enabled + if( m_precisionCrosshairMode != PRECISION_CROSSHAIR_NONE ) + DrawPrecisionCrosshair(); + + qglFlush(); + + // QE_CheckOpenGLForErrors(); +} + + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +idVec3 &CXYWnd::GetOrigin() { + return m_vOrigin; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SetOrigin(idVec3 org) { + m_vOrigin[0] = org[0]; + m_vOrigin[1] = org[1]; + m_vOrigin[2] = org[2]; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnSize(UINT nType, int cx, int cy) { + CWnd::OnSize(nType, cx, cy); + + CRect rect; + GetClientRect(rect); + m_nWidth = rect.Width(); + m_nHeight = rect.Height(); + InvalidateRect(NULL, false); +} + +brush_t hold_brushes; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::Clip() { + if (ClipMode()) { + hold_brushes.next = &hold_brushes; + ProduceSplitLists(); + + // brush_t* pList = (g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; + brush_t *pList; + if (g_PrefsDlg.m_bSwitchClip) { + pList = ((m_nViewType == XZ) ? g_bSwitch : !g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; + } + else { + pList = ((m_nViewType == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brFrontSplits : &g_brBackSplits; + } + + if (pList->next != pList) { + Brush_CopyList(pList, &hold_brushes); + CleanList(&g_brFrontSplits); + CleanList(&g_brBackSplits); + Select_Delete(); + Brush_CopyList(&hold_brushes, &selected_brushes); + if (RogueClipMode()) { + RetainClipMode(false); + } + else { + RetainClipMode(true); + } + + Sys_UpdateWindows(W_ALL); + } + } + else if (PathMode()) { + FinishSmartCreation(); + if (g_pPathFunc) { + g_pPathFunc(true, g_nPathCount); + } + + g_pPathFunc = NULL; + g_nPathCount = 0; + g_bPathMode = false; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SplitClip() { + ProduceSplitLists(); + if ((g_brFrontSplits.next != &g_brFrontSplits) && (g_brBackSplits.next != &g_brBackSplits)) { + Select_Delete(); + Brush_CopyList(&g_brFrontSplits, &selected_brushes); + Brush_CopyList(&g_brBackSplits, &selected_brushes); + CleanList(&g_brFrontSplits); + CleanList(&g_brBackSplits); + if (RogueClipMode()) { + RetainClipMode(false); + } + else { + RetainClipMode(true); + } + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::FlipClip() { + g_bSwitch = !g_bSwitch; + Sys_UpdateWindows(XY | W_CAMERA_IFON); +} + +// +// ======================================================================================================================= +// makes sure the selected brush or camera is in view +// ======================================================================================================================= +// +void CXYWnd::PositionView() { + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + brush_t *b = selected_brushes.next; + if (b && b->next != b) { + m_vOrigin[nDim1] = b->mins[nDim1]; + m_vOrigin[nDim2] = b->mins[nDim2]; + } + else { + m_vOrigin[nDim1] = g_pParentWnd->GetCamera()->Camera().origin[nDim1]; + m_vOrigin[nDim2] = g_pParentWnd->GetCamera()->Camera().origin[nDim2]; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::VectorCopyXY(const idVec3 &in, idVec3 &out) { + if (m_nViewType == XY) { + out[0] = in[0]; + out[1] = in[1]; + } + else if (m_nViewType == XZ) { + out[0] = in[0]; + out[2] = in[2]; + } + else { + out[1] = in[1]; + out[2] = in[2]; + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnDestroy() { + CWnd::OnDestroy(); + + // delete this; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SetViewType(int n) { + m_nViewType = n; + char *p = "YZ Side"; + if (m_nViewType == XY) { + p = "XY Top"; + } else if (m_nViewType == XZ) { + p = "XZ Front"; + } + SetWindowText(p); +}; + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::Redraw(unsigned int nBits) { + m_nUpdateBits = nBits; + RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + m_nUpdateBits = W_XY; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::RotateMode() { + return g_bRotateMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::ScaleMode() { + return g_bScaleMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +extern bool Select_OnlyModelsSelected(); +bool CXYWnd::SetRotateMode(bool bMode) { + if (bMode && selected_brushes.next != &selected_brushes) { + g_bRotateMode = true; + if (Select_OnlyModelsSelected()) { + Select_GetTrueMid(g_vRotateOrigin); + } else { + Select_GetMid(g_vRotateOrigin); + } + g_vRotation.Zero(); + Select_InitializeRotation(); + } + else { + if (bMode) { + Sys_Status("Need a brush selected to turn on Mouse Rotation mode\n"); + } + + g_bRotateMode = false; + Select_FinalizeRotation(); + } + + RedrawWindow(); + return g_bRotateMode; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::SetScaleMode(bool bMode) { + g_bScaleMode = bMode; + RedrawWindow(); +} + +// +// ======================================================================================================================= +// xy - z xz - y yz - x +// ======================================================================================================================= +// +void CXYWnd::OnSelectMouserotate() { + // TODO: Add your command handler code here +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CleanCopyEntities() { + entity_t *pe = g_enClipboard.next; + while (pe != NULL && pe != &g_enClipboard) { + entity_t *next = pe->next; + pe->epairs.Clear(); + + Entity_Free(pe); + pe = next; + } + + g_enClipboard.next = g_enClipboard.prev = &g_enClipboard; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +entity_t *Entity_CopyClone(entity_t *e) { + entity_t *n; + + n = Entity_New(); + n->brushes.onext = n->brushes.oprev = &n->brushes; + n->eclass = e->eclass; + n->rotation = e->rotation; + + // add the entity to the entity list + n->next = g_enClipboard.next; + g_enClipboard.next = n; + n->next->prev = n; + n->prev = &g_enClipboard; + + n->epairs = e->epairs; + + return n; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool OnList(entity_t *pFind, CPtrArray *pList) { + int nSize = pList->GetSize(); + while (nSize-- > 0) { + entity_t *pEntity = reinterpret_cast < entity_t * > (pList->GetAt(nSize)); + if (pEntity == pFind) { + return true; + } + } + + return false; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::Copy() +{ +#if 1 + CWaitCursor WaitCursor; + g_Clipboard.SetLength(0); + g_PatchClipboard.SetLength(0); + + Map_SaveSelected(&g_Clipboard, &g_PatchClipboard); + + bool bClipped = false; + UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); + if (nClipboard > 0) { + if (OpenClipboard()) { + ::EmptyClipboard(); + + long lSize = g_Clipboard.GetLength(); + HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof (long)); + if (h != NULL) { + unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); + memcpy(cp, &lSize, sizeof (long)); + cp += sizeof (long); + g_Clipboard.SeekToBegin(); + g_Clipboard.Read(cp, lSize); + ::GlobalUnlock(h); + ::SetClipboardData(nClipboard, h); + ::CloseClipboard(); + bClipped = true; + } + } + } + + if (!bClipped) { + common->Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible"); + } + + /* + * CString strOut; ::GetTempPath(1024, strOut.GetBuffer(1024)); + * strOut.ReleaseBuffer(); AddSlash(strOut); strOut += "RadiantClipboard.$$$"; + * Map_SaveSelected(strOut.GetBuffer(0)); + */ +#else + CPtrArray holdArray; + CleanList(&g_brClipboard); + CleanCopyEntities(); + for (brush_t * pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { + if (pBrush->owner == world_entity) { + brush_t *pClone = Brush_Clone(pBrush); + pClone->owner = NULL; + Brush_AddToList(pClone, &g_brClipboard); + } + else { + if (!OnList(pBrush->owner, &holdArray)) { + entity_t *e = pBrush->owner; + holdArray.Add(reinterpret_cast < void * > (e)); + + entity_t *pEClone = Entity_CopyClone(e); + for (brush_t * pEB = e->brushes.onext; pEB != &e->brushes; pEB = pEB->onext) { + brush_t *pClone = Brush_Clone(pEB); + + // Brush_AddToList (pClone, &g_brClipboard); + Entity_LinkBrush(pEClone, pClone); + Brush_Build(pClone); + } + } + } + } +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::Undo() { + /* + * if (g_brUndo.next != &g_brUndo) { g_bScreenUpdates = false; Select_Delete(); + * for (brush_t* pBrush = g_brUndo.next ; pBrush != NULL && pBrush != &g_brUndo ; + * pBrush=pBrush->next) { brush_t* pClone = Brush_Clone(pBrush); Brush_AddToList + * (pClone, &active_brushes); Entity_LinkBrush (pBrush->pUndoOwner, pClone); + * Brush_Build(pClone); Select_Brush(pClone); } CleanList(&g_brUndo); + * g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else common->Printf("Nothing + * to undo.../n"); + */ +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::UndoClear() { + /* CleanList(&g_brUndo); */ +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::UndoCopy() { + /* + * CleanList(&g_brUndo); for (brush_t* pBrush = selected_brushes.next ; pBrush != + * NULL && pBrush != &selected_brushes ; pBrush=pBrush->next) { brush_t* pClone = + * Brush_Clone(pBrush); pClone->pUndoOwner = pBrush->owner; Brush_AddToList + * (pClone, &g_brUndo); } + */ +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +bool CXYWnd::UndoAvailable() { + return(g_brUndo.next != &g_brUndo); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::Paste() +{ +#if 1 + + CWaitCursor WaitCursor; + bool bPasted = false; + UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings"); + if (nClipboard > 0 && OpenClipboard() && ::IsClipboardFormatAvailable(nClipboard)) { + HANDLE h = ::GetClipboardData(nClipboard); + if (h) { + g_Clipboard.SetLength(0); + + unsigned char *cp = reinterpret_cast < unsigned char * > (::GlobalLock(h)); + long lSize = 0; + memcpy(&lSize, cp, sizeof (long)); + cp += sizeof (long); + g_Clipboard.Write(cp, lSize); + } + + ::GlobalUnlock(h); + ::CloseClipboard(); + } + + if (g_Clipboard.GetLength() > 0) { + g_Clipboard.SeekToBegin(); + + int nLen = g_Clipboard.GetLength(); + char *pBuffer = new char[nLen + 1]; + memset(pBuffer, 0, sizeof(pBuffer)); + g_Clipboard.Read(pBuffer, nLen); + pBuffer[nLen] = '\0'; + Map_ImportBuffer(pBuffer, !(GetAsyncKeyState(VK_SHIFT) & 0x8000)); + delete[] pBuffer; + } + + #if 0 + if (g_PatchClipboard.GetLength() > 0) { + g_PatchClipboard.SeekToBegin(); + + int nLen = g_PatchClipboard.GetLength(); + char *pBuffer = new char[nLen + 1]; + g_PatchClipboard.Read(pBuffer, nLen); + pBuffer[nLen] = '\0'; + Patch_ReadBuffer(pBuffer, true); + delete[] pBuffer; + } + #endif +#else + if (g_brClipboard.next != &g_brClipboard || g_enClipboard.next != &g_enClipboard) { + Select_Deselect(); + + for (brush_t * pBrush = g_brClipboard.next; pBrush != NULL && pBrush != &g_brClipboard; pBrush = pBrush->next) { + brush_t *pClone = Brush_Clone(pBrush); + + // pClone->owner = pBrush->owner; + if (pClone->owner == NULL) { + Entity_LinkBrush(world_entity, pClone); + } + + Brush_AddToList(pClone, &selected_brushes); + Brush_Build(pClone); + } + + for + ( + entity_t * pEntity = g_enClipboard.next; + pEntity != NULL && pEntity != &g_enClipboard; + pEntity = pEntity->next + ) { + entity_t *pEClone = Entity_Clone(pEntity); + for (brush_t * pEB = pEntity->brushes.onext; pEB != &pEntity->brushes; pEB = pEB->onext) { + brush_t *pClone = Brush_Clone(pEB); + Brush_AddToList(pClone, &selected_brushes); + Entity_LinkBrush(pEClone, pClone); + Brush_Build(pClone); + if (pClone->owner && pClone->owner != world_entity) { + g_Inspectors->UpdateEntitySel(pClone->owner->eclass); + } + } + } + + Sys_UpdateWindows(W_ALL); + } + else { + common->Printf("Nothing to paste.../n"); + } +#endif +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +idVec3 &CXYWnd::Rotation() { + return g_vRotation; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +idVec3 &CXYWnd::RotateOrigin() { + return g_vRotateOrigin; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnTimer(UINT nIDEvent) { + if (nIDEvent == 100) { + int nDim1 = (m_nViewType == YZ) ? 1 : 0; + int nDim2 = (m_nViewType == XY) ? 1 : 2; + m_vOrigin[nDim1] += m_ptDragAdj.x / m_fScale; + m_vOrigin[nDim2] -= m_ptDragAdj.y / m_fScale; + Sys_UpdateWindows(W_XY | W_CAMERA); + + // int nH = (m_ptDrag.y == 0) ? -1 : m_ptDrag.y; + m_ptDrag += m_ptDragAdj; + m_ptDragTotal += m_ptDragAdj; + XY_MouseMoved(m_ptDrag.x, m_nHeight - 1 - m_ptDrag.y, m_nScrollFlags); + + // + // m_vOrigin[nDim1] -= m_ptDrag.x / m_fScale; m_vOrigin[nDim1] -= m_ptDrag.x / + // m_fScale; + // + } +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); + + // CWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR *lpncsp) { + CWnd::OnNcCalcSize(bCalcValidRects, lpncsp); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnKillFocus(CWnd *pNewWnd) { + CWnd::OnKillFocus(pNewWnd); + SendMessage(WM_NCACTIVATE, FALSE, 0); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnSetFocus(CWnd *pOldWnd) { + CWnd::OnSetFocus(pOldWnd); + SendMessage(WM_NCACTIVATE, TRUE, 0); +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void CXYWnd::OnClose() { + CWnd::OnClose(); +} + +// +// ======================================================================================================================= +// should be static as should be the rotate scale stuff +// ======================================================================================================================= +// +bool CXYWnd::AreaSelectOK() { + return RotateMode() ? false : ScaleMode() ? false : true; +} + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +BOOL CXYWnd::OnEraseBkgnd(CDC *pDC) { + return TRUE; + + // return CWnd::OnEraseBkgnd(pDC); +} + +extern void AssignModel(); +void CXYWnd::OnDropNewmodel() +{ + CPoint point; + GetCursorPos(&point); + CreateRightClickEntity(this, m_ptDown.x, m_ptDown.y, "func_static"); + g_Inspectors->SetMode(W_ENTITY); + g_Inspectors->AssignModel(); +} + +BOOL CXYWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + if (zDelta > 0) { + g_pParentWnd->OnViewZoomin(); + } else { + g_pParentWnd->OnViewZoomout(); + } + return TRUE; +} + + + + + //--------------------------------------------------------------------------- + // CyclePrecisionCrosshairMode + // + // Called when the user presses the "cycle precision cursor mode" key. + // Cycles the precision cursor among the following three modes: + // PRECISION_CURSOR_NONE + // PRECISION_CURSOR_SNAP + // PRECISION_CURSOR_FREE + //--------------------------------------------------------------------------- + void CXYWnd::CyclePrecisionCrosshairMode( void ) + { + common->Printf("TODO: Make DrawPrecisionCrosshair work..." ); + + /// Cycle to next mode, wrap if necessary + m_precisionCrosshairMode ++; + if( m_precisionCrosshairMode >= PRECISION_CROSSHAIR_MAX ) + m_precisionCrosshairMode = PRECISION_CROSSHAIR_NONE; + Sys_UpdateWindows( W_XY ); + } + + //--------------------------------------------------------------------------- +// DrawPrecisionCrosshair +// +// Draws a precision crosshair beneath the cursor in the 2d (XY) view, +// depending on one of the following values for m_precisionCrosshairMode: +// +// PRECISION_CROSSHAIR_NONE No crosshair is drawn. Do not force refresh of XY view. +// PRECISION_CROSSHAIR_SNAP Crosshair snaps to grid size. Force refresh of XY view. +// PRECISION_CROSSHAIR_FREE Crosshair does not snap to grid. Force refresh of XY view. +//--------------------------------------------------------------------------- +void CXYWnd::DrawPrecisionCrosshair( void ) +{ + // FIXME: m_mouseX, m_mouseY, m_axisHoriz, m_axisVert, etc... are never set + return; + + idVec3 mouse3dPos (0.0f, 0.0f, 0.0f); + float x, y; + idVec4 crossEndColor (1.0f, 0.0f, 1.0f, 1.0f); // the RGBA color of the precision crosshair at its ends + idVec4 crossMidColor; // the RGBA color of the precision crosshair at the crossing point + + /// Transform the mouse coordinates into axis-correct map-coordinates + if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_SNAP ) + SnapToPoint( m_mouseX, m_mouseY, mouse3dPos ); + else + XY_ToPoint( m_mouseX, m_mouseY, mouse3dPos ); + x = mouse3dPos[ m_axisHoriz ]; + y = mouse3dPos[ m_axisVert ]; + + /// Use the color specified by the user + + crossEndColor[0] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][0]; + crossEndColor[1] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][1]; + crossEndColor[2] = g_qeglobals.d_savedinfo.colors[ COLOR_PRECISION_CROSSHAIR ][2]; + crossEndColor[3] = 1.0f; + + crossMidColor = crossEndColor; + + if( m_precisionCrosshairMode == PRECISION_CROSSHAIR_FREE ) + crossMidColor[ 3 ] = 0.0f; // intersection-color is 100% transparent (alpha = 0.0f) + + /// Set up OpenGL states (for drawing smooth-shaded plain-colored lines) + qglEnable( GL_BLEND ); + qglDisable( GL_TEXTURE_2D ); + qglShadeModel( GL_SMOOTH ); + qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + /// Draw a fullscreen-sized crosshair over the cursor + qglBegin( GL_LINES ); + { + /// Draw the horizontal precision line (in two pieces) + qglColor4fv( crossEndColor.ToFloatPtr() ); + qglVertex2f( m_mcLeft, y ); + qglColor4fv( crossMidColor.ToFloatPtr() ); + qglVertex2f( x, y ); + qglColor4fv( crossMidColor.ToFloatPtr() ); + qglVertex2f( x, y ); + qglColor4fv( crossEndColor.ToFloatPtr() ); + qglVertex2f( m_mcRight, y ); + + /// Draw the vertical precision line (in two pieces) + qglColor4fv( crossEndColor.ToFloatPtr() ); + qglVertex2f( x, m_mcTop ); + qglColor4fv( crossMidColor.ToFloatPtr() ); + qglVertex2f( x, y ); + qglColor4fv( crossMidColor.ToFloatPtr() ); + qglVertex2f( x, y ); + qglColor4fv( crossEndColor.ToFloatPtr() ); + qglVertex2f( x, m_mcBottom ); + } + qglEnd(); // GL_LINES + + // Radiant was in opaque, flat-shaded mode by default; restore this to prevent possible slowdown + qglShadeModel( GL_FLAT ); + qglDisable( GL_BLEND ); +} diff --git a/tools/radiant/XYWnd.h b/tools/radiant/XYWnd.h new file mode 100644 index 000000000..56c65301d --- /dev/null +++ b/tools/radiant/XYWnd.h @@ -0,0 +1,255 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_XYWND_H__44B4BA04_781B_11D1_B53C_00AA00A410FC__INCLUDED_) +#define AFX_XYWND_H__44B4BA04_781B_11D1_B53C_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// XYWnd.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CXYWnd window + +#include "qe3.h" +#include "CamWnd.h" + +const int SCALE_X = 0x01; +const int SCALE_Y = 0x02; +const int SCALE_Z = 0x04; + +bool FilterBrush(brush_t *pb); + +typedef void (PFNPathCallback)(bool, int); +// as i didn't really encapsulate anything this +// should really be a struct.. +class CClipPoint +{ +public: + CClipPoint(){ Reset(); }; + void Reset(){ m_ptClip[0] = m_ptClip[1] = m_ptClip[2] = 0.0; m_bSet = false; m_pVec3 = NULL;}; + bool Set(){ return m_bSet; }; + void Set(bool b) { m_bSet = b; }; + void UpdatePointPtr() { if (m_pVec3) VectorCopy(m_ptClip, *m_pVec3); }; + void SetPointPtr(idVec3* p) { m_pVec3 = p; }; + idVec3 m_ptClip; // the 3d point + idVec3* m_pVec3; // optional ptr for 3rd party updates + CPoint m_ptScreen; // the onscreen xy point (for mousability) + bool m_bSet; + operator idVec3&() {return m_ptClip;}; + operator idVec3*() {return &m_ptClip;}; + operator float*() {return m_ptClip.ToFloatPtr();}; +}; + +class CXYWnd : public CWnd +{ + DECLARE_DYNCREATE(CXYWnd); +// Construction +public: + CXYWnd(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CXYWnd) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + bool AreaSelectOK(); + idVec3& RotateOrigin(); + idVec3& Rotation(); + void UndoClear(); + bool UndoAvailable(); + void KillPathMode(); + void Undo(); + void UndoCopy(); + void Copy(); + void Paste(); + void Redraw(unsigned int nBits); + void VectorCopyXY( const idVec3 &in, idVec3 &out ); + void PositionView(); + void FlipClip(); + void SplitClip(); + void Clip(); + idVec3& GetOrigin(); + void SetOrigin(idVec3 org); // PGM + void XY_Init(); + void XY_Draw(); + void DrawZIcon(); + void DrawRotateIcon(); + void DrawCameraIcon(); + void XY_DrawBlockGrid(); + void XY_DrawGrid(); + bool XY_MouseMoved (int x, int y, int buttons); + void NewBrushDrag (int x, int y); + bool DragDelta (int x, int y, idVec3 &move); + void XY_MouseUp(int x, int y, int buttons); + void XY_MouseDown (int x, int y, int buttons); + void XY_ToGridPoint (int x, int y, idVec3 &point); + void XY_ToPoint (int x, int y, idVec3 &point); + void SnapToPoint (int x, int y, idVec3 &point); + void SetActive(bool b) {m_bActive = b;}; + bool Active() {return m_bActive;}; + void DropClipPoint(UINT nFlags, CPoint point); + + int GetAxisHoriz() { return m_axisHoriz; }; + int GetAxisVert() { return m_axisVert; }; + void AnalogMouseZoom( int mouseDeltaY ); + + + bool RogueClipMode(); + bool ClipMode(); + void SetClipMode(bool bMode); + void RetainClipMode(bool bMode); + + bool RotateMode(); + bool SetRotateMode(bool bMode); + bool ScaleMode(); + void SetScaleMode(bool bMode); + + bool PathMode(); + void DropPathPoint(UINT nFlags, CPoint point); + + bool PointMode(); + void AddPointPoint(UINT nFlags, idVec3* pVec); + void SetPointMode(bool b); + + + virtual ~CXYWnd(); + void SetViewType(int n); + int GetViewType() {return m_nViewType; }; + void SetScale(float f) {m_fScale = f;}; + float Scale() {return m_fScale;}; + int Width() {return m_nWidth;} + int Height() {return m_nHeight;} + bool m_bActive; + + void UpdateViewDependencies( void ); + + void DrawPrecisionCrosshair(); + void CyclePrecisionCrosshairMode(); + enum + { + PRECISION_CROSSHAIR_NONE = 0, + PRECISION_CROSSHAIR_SNAP = 1, + PRECISION_CROSSHAIR_FREE = 2, + PRECISION_CROSSHAIR_MAX, + }; + + int m_precisionCrosshairMode; + int m_mouseX; + int m_mouseY; + + + // Generated message map functions +protected: + int m_nUpdateBits; + int m_nWidth; + int m_nHeight; + float m_fScale; + float m_TopClip; + float m_BottomClip; + bool m_bDirty; + idVec3 m_vOrigin; + CPoint m_ptCursor; + bool m_bRButtonDown; + + int m_nButtonstate; + int m_nPressx; + int m_nPressy; + idVec3 m_vPressdelta; + bool m_bPress_selection; + + int m_axisHoriz; // and are one of AXIS_X, AXIS_Y, AXIS_Z and + int m_axisVert; // reflect which axes are represented horizontally and vertically in the 2d view (XY, XZ, etc) + + /// Each of the following _mc fields are stored in map-coordinates, NOT screen-pixels + float m_mcWidth; + float m_mcHeight; + float m_mcLeft; + float m_mcRight; + float m_mcTop; + float m_mcBottom; + + + friend CCamWnd; + //friend C3DFXCamWnd; + + CMenu m_mnuDrop; + int m_nViewType; + + unsigned int m_nTimerID; + int m_nScrollFlags; + CPoint m_ptDrag; + CPoint m_ptDragAdj; + CPoint m_ptDragTotal; + + void OriginalButtonUp(UINT nFlags, CPoint point); + void OriginalButtonDown(UINT nFlags, CPoint point); + void ProduceSplits(brush_t** pFront, brush_t** pBack); + void ProduceSplitLists(); + void HandleDrop(); + void PaintSizeInfo(int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds); + void DrawSelectedCentroid( int nDim1, int nDim2, idVec3 vMinBounds, idVec3 vMaxBounds ); + + void OnEntityCreate(unsigned int nID); + CPoint m_ptDown; + //{{AFX_MSG(CXYWnd) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnPaint(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnDestroy(); + afx_msg void OnSelectMouserotate(); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp); + afx_msg void OnKillFocus(CWnd* pNewWnd); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnClose(); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnDropNewmodel(); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + afx_msg BOOL OnCmdMsg( UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo ); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_XYWND_H__44B4BA04_781B_11D1_B53C_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/Z.CPP b/tools/radiant/Z.CPP new file mode 100644 index 000000000..73c352caf --- /dev/null +++ b/tools/radiant/Z.CPP @@ -0,0 +1,483 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" + +#define PAGEFLIPS 2 + +z_t z; + +/* + ======================================================================================================================= + Z_Init + ======================================================================================================================= + */ +void Z_Init(void) { + z.origin[0] = 0; + z.origin[1] = 20; + z.origin[2] = 46; + + z.scale = 1; +} + +/* MOUSE ACTIONS */ +static int cursorx, cursory; + +/* + ======================================================================================================================= + Z_MouseDown + ======================================================================================================================= + */ +void Z_MouseDown(int x, int y, int buttons) { + idVec3 org, dir, vup, vright; + brush_t *b; + + Sys_GetCursorPos(&cursorx, &cursory); + + vup[0] = 0; + vup[1] = 0; + vup[2] = 1 / z.scale; + + VectorCopy(z.origin, org); + org[2] += (y - (z.height / 2)) / z.scale; + org[1] = MIN_WORLD_COORD; + + b = selected_brushes.next; + if (b != &selected_brushes) { + org[0] = (b->mins[0] + b->maxs[0]) / 2; + } + + dir[0] = 0; + dir[1] = 1; + dir[2] = 0; + + vright[0] = 0; + vright[1] = 0; + vright[2] = 0; + + + // new mouse code for ZClip, I'll do this stuff before falling through into the standard ZWindow mouse code... + // + if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case I think, but this is safer + { + bool bToggle = false; + bool bSetTop = false; + bool bSetBot = false; + bool bReset = false; + + if (g_PrefsDlg.m_nMouseButtons == 2) + { + // 2 button mice... + // + bToggle = (GetKeyState(VK_F1) & 0x8000) != 0; + bSetTop = (GetKeyState(VK_F2) & 0x8000) != 0; + bSetBot = (GetKeyState(VK_F3) & 0x8000) != 0; + bReset = (GetKeyState(VK_F4) & 0x8000) != 0; + } + else + { + // 3 button mice... + // + bToggle = (buttons == (MK_RBUTTON|MK_SHIFT|MK_CONTROL)); + bSetTop = (buttons == (MK_RBUTTON|MK_SHIFT)); + bSetBot = (buttons == (MK_RBUTTON|MK_CONTROL)); + bReset = (GetKeyState(VK_F4) & 0x8000) != 0; + } + + if (bToggle) + { + g_pParentWnd->GetZWnd()->m_pZClip->Enable(!(g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled())); + Sys_UpdateWindows (W_ALL); + return; + } + + if (bSetTop) + { + g_pParentWnd->GetZWnd()->m_pZClip->SetTop(org[2]); + Sys_UpdateWindows (W_ALL); + return; + } + + if (bSetBot) + { + g_pParentWnd->GetZWnd()->m_pZClip->SetBottom(org[2]); + Sys_UpdateWindows (W_ALL); + return; + } + + if (bReset) + { + g_pParentWnd->GetZWnd()->m_pZClip->Reset(); + Sys_UpdateWindows (W_ALL); + return; + } + } + + // + // LBUTTON = manipulate selection shift-LBUTTON = select middle button = grab + // texture ctrl-middle button = set entire brush to texture ctrl-shift-middle + // button = set single face to texture + // + + // see code above for these next 3, I just commented them here as well for clarity... + // + // ctrl-shift-RIGHT button = toggle ZClip on/off + // shift-RIGHT button = set ZClip top marker + // ctrl-RIGHT button = set ZClip bottom marker + + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + if + ( + (buttons == MK_LBUTTON) || + (buttons == (MK_LBUTTON | MK_SHIFT)) || + (buttons == MK_MBUTTON) // || (buttons == (MK_MBUTTON|MK_CONTROL)) + || + (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL)) + ) { + Drag_Begin(x, y, buttons, vright, vup, org, dir); + return; + } + + // control mbutton = move camera + if ((buttons == (MK_CONTROL | nMouseButton)) || (buttons == (MK_CONTROL | MK_LBUTTON))) { + g_pParentWnd->GetCamera()->Camera().origin[2] = org[2]; + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY | W_Z); + } +} + +/* + ======================================================================================================================= + Z_MouseUp + ======================================================================================================================= + */ +void Z_MouseUp(int x, int y, int buttons) { + Drag_MouseUp(); +} + +/* + ======================================================================================================================= + Z_MouseMoved + ======================================================================================================================= + */ +void Z_MouseMoved(int x, int y, int buttons) { + if (!buttons) { + return; + } + + if (buttons == MK_LBUTTON) { + Drag_MouseMoved(x, y, buttons); + Sys_UpdateWindows(W_Z | W_CAMERA_IFON | W_XY); + return; + } + + // rbutton = drag z origin + if (buttons == MK_RBUTTON) { + Sys_GetCursorPos(&x, &y); + if (y != cursory) { + z.origin[2] += y - cursory; + Sys_SetCursorPos(cursorx, cursory); + Sys_UpdateWindows(W_Z); + } + + return; + } + + // control mbutton = move camera + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + if ((buttons == (MK_CONTROL | nMouseButton)) || (buttons == (MK_CONTROL | MK_LBUTTON))) { + g_pParentWnd->GetCamera()->Camera().origin[2] = z.origin[2] + (y - (z.height / 2)) / z.scale; + Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY | W_Z); + } +} + +/* + ======================================================================================================================= + DRAWING £ + Z_DrawGrid + ======================================================================================================================= + */ +void Z_DrawGrid(void) { + float zz, zb, ze; + int w, h; + char text[32]; + + w = z.width / 2 / z.scale; + h = z.height / 2 / z.scale; + + zb = z.origin[2] - h; + if (zb < region_mins[2]) { + zb = region_mins[2]; + } + + zb = 64 * floor(zb / 64); + + ze = z.origin[2] + h; + if (ze > region_maxs[2]) { + ze = region_maxs[2]; + } + + ze = 64 * ceil(ze / 64); + + // draw major blocks + qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR].ToFloatPtr() ); + + qglBegin(GL_LINES); + + qglVertex2f(0, zb); + qglVertex2f(0, ze); + + for (zz = zb; zz < ze; zz += 64) { + qglVertex2f(-w, zz); + qglVertex2f(w, zz); + } + + qglEnd(); + + // draw minor blocks + if ( g_qeglobals.d_showgrid && + g_qeglobals.d_gridsize * z.scale >= 4 && + !g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].Compare( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) ) { + + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].ToFloatPtr()); + + qglBegin(GL_LINES); + for (zz = zb; zz < ze; zz += g_qeglobals.d_gridsize) { + if (!((int)zz & 63)) { + continue; + } + + qglVertex2f(-w, zz); + qglVertex2f(w, zz); + } + + qglEnd(); + } + + // draw coordinate text if needed + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT].ToFloatPtr()); + + for (zz = zb; zz < ze; zz += 64) { + qglRasterPos2f(-w + 1, zz); + sprintf(text, "%i", (int)zz); + qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); + } +} + +#define CAM_HEIGHT 48 // height of main part +#define CAM_GIZMO 8 // height of the gizmo + +/* + ======================================================================================================================= + ======================================================================================================================= + */ +void ZDrawCameraIcon(void) { + float x, y; + int xCam = z.width / 4; + + x = 0; + y = g_pParentWnd->GetCamera()->Camera().origin[2]; + + qglColor3f(0.0, 0.0, 1.0); + qglBegin(GL_LINE_STRIP); + qglVertex3f(x - xCam, y, 0); + qglVertex3f(x, y + CAM_GIZMO, 0); + qglVertex3f(x + xCam, y, 0); + qglVertex3f(x, y - CAM_GIZMO, 0); + qglVertex3f(x - xCam, y, 0); + qglVertex3f(x + xCam, y, 0); + qglVertex3f(x + xCam, y - CAM_HEIGHT, 0); + qglVertex3f(x - xCam, y - CAM_HEIGHT, 0); + qglVertex3f(x - xCam, y, 0); + qglEnd(); +} + +void ZDrawZClip() +{ + float x,y; + + x = 0; + y = g_pParentWnd->GetCamera()->Camera().origin[2]; + + if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case I think + g_pParentWnd->GetZWnd()->m_pZClip->Paint(); +} + + +GLbitfield glbitClear = GL_COLOR_BUFFER_BIT; // HACK + +/* + ======================================================================================================================= + Z_Draw + ======================================================================================================================= + */ +void Z_Draw(void) { + brush_t *brush; + float w, h; + float top, bottom; + idVec3 org_top, org_bottom, dir_up, dir_down; + int xCam = z.width / 3; + + if (!active_brushes.next) { + return; // not valid yet + } + + // clear + qglViewport(0, 0, z.width, z.height); + qglScissor(0, 0, z.width, z.height); + + qglClearColor + ( + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], + 0 + ); + + /* + * GL Bug £ + * When not using hw acceleration, gl will fault if we clear the depth buffer bit + * on the first pass. The hack fix is to set the GL_DEPTH_BUFFER_BIT only after + * Z_Draw() has been called once. Yeah, right. £ + * qglClear(glbitClear); + */ + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // + // glbitClear |= GL_DEPTH_BUFFER_BIT; + // qglClear(GL_DEPTH_BUFFER_BIT); + // + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + + w = z.width / 2 / z.scale; + h = z.height / 2 / z.scale; + qglOrtho(-w, w, z.origin[2] - h, z.origin[2] + h, -8, 8); + + globalImages->BindNull(); + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_BLEND); + + // now draw the grid + Z_DrawGrid(); + + // draw stuff + qglDisable(GL_CULL_FACE); + + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + globalImages->BindNull(); + + // draw filled interiors and edges + dir_up[0] = 0; + dir_up[1] = 0; + dir_up[2] = 1; + dir_down[0] = 0; + dir_down[1] = 0; + dir_down[2] = -1; + VectorCopy(z.origin, org_top); + org_top[2] = 4096; + VectorCopy(z.origin, org_bottom); + org_bottom[2] = -4096; + + for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) { + if + ( + brush->mins[0] >= z.origin[0] || + brush->maxs[0] <= z.origin[0] || + brush->mins[1] >= z.origin[1] || + brush->maxs[1] <= z.origin[1] + ) { + continue; + } + + if (!Brush_Ray(org_top, dir_down, brush, &top)) { + continue; + } + + top = org_top[2] - top; + if (!Brush_Ray(org_bottom, dir_up, brush, &bottom)) { + continue; + } + + bottom = org_bottom[2] + bottom; + + //q = declManager->FindMaterial(brush->brush_faces->texdef.name); + qglColor3f(brush->owner->eclass->color.x, brush->owner->eclass->color.y, brush->owner->eclass->color.z); + qglBegin(GL_QUADS); + qglVertex2f(-xCam, bottom); + qglVertex2f(xCam, bottom); + qglVertex2f(xCam, top); + qglVertex2f(-xCam, top); + qglEnd(); + + qglColor3f(1, 1, 1); + qglBegin(GL_LINE_LOOP); + qglVertex2f(-xCam, bottom); + qglVertex2f(xCam, bottom); + qglVertex2f(xCam, top); + qglVertex2f(-xCam, top); + qglEnd(); + } + + // now draw selected brushes + for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { + if + ( + !( + brush->mins[0] >= z.origin[0] || + brush->maxs[0] <= z.origin[0] || + brush->mins[1] >= z.origin[1] || + brush->maxs[1] <= z.origin[1] + ) + ) { + if (Brush_Ray(org_top, dir_down, brush, &top)) { + top = org_top[2] - top; + if (Brush_Ray(org_bottom, dir_up, brush, &bottom)) { + bottom = org_bottom[2] + bottom; + + //q = declManager->FindMaterial(brush->brush_faces->texdef.name); + qglColor3f(brush->owner->eclass->color.x, brush->owner->eclass->color.y, brush->owner->eclass->color.z); + qglBegin(GL_QUADS); + qglVertex2f(-xCam, bottom); + qglVertex2f(xCam, bottom); + qglVertex2f(xCam, top); + qglVertex2f(-xCam, top); + qglEnd(); + } + } + } + + qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); + qglBegin(GL_LINE_LOOP); + qglVertex2f(-xCam, brush->mins[2]); + qglVertex2f(xCam, brush->mins[2]); + qglVertex2f(xCam, brush->maxs[2]); + qglVertex2f(-xCam, brush->maxs[2]); + qglEnd(); + } + + ZDrawCameraIcon(); + ZDrawZClip(); + + qglFinish(); + QE_CheckOpenGLForErrors(); +} diff --git a/tools/radiant/Z.H b/tools/radiant/Z.H new file mode 100644 index 000000000..641ec2127 --- /dev/null +++ b/tools/radiant/Z.H @@ -0,0 +1,37 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +// window system independent camera view code + +typedef struct +{ + int width, height; + + idVec3 origin; // at center of window + float scale; +} z_t; + +extern z_t z; + +void Z_Init (void); +void Z_MouseDown (int x, int y, int buttons); +void Z_MouseUp (int x, int y, int buttons); +void Z_MouseMoved (int x, int y, int buttons); +void Z_Draw (void); + diff --git a/tools/radiant/ZClip.cpp b/tools/radiant/ZClip.cpp new file mode 100644 index 000000000..17280463a --- /dev/null +++ b/tools/radiant/ZClip.cpp @@ -0,0 +1,190 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" + +#include "zclip.h" + + +CZClip::CZClip() +{ + LONG + lSize = sizeof(m_bEnabled); + if (!LoadRegistryInfo("radiant_ZClipEnabled", &m_bEnabled, &lSize)) + m_bEnabled = false; + + lSize = sizeof(m_iZClipTop); + if (!LoadRegistryInfo("radiant_ZClipTop", &m_iZClipTop, &lSize)) + m_iZClipTop = 64; + + lSize = sizeof(m_iZClipBottom); + if (!LoadRegistryInfo("radiant_ZClipBottom", &m_iZClipBottom, &lSize)) + m_iZClipBottom = -64; + + Legalise(); +} + +CZClip::~CZClip() +{ + // TODO: registry save + + SaveRegistryInfo("radiant_ZClipEnabled", &m_bEnabled, sizeof(m_bEnabled)); + SaveRegistryInfo("radiant_ZClipTop", &m_iZClipTop, sizeof(m_iZClipTop)); + SaveRegistryInfo("radiant_ZClipBottom", &m_iZClipBottom, sizeof(m_iZClipBottom)); +} + +void CZClip::Reset(void) +{ + m_iZClipTop = 64; // arb. starting values, but must be at least 64 apart + m_iZClipBottom = -64; + m_bEnabled = false; + + Legalise(); +} + + +int CZClip::GetTop(void) +{ + return m_iZClipTop; +} + +int CZClip::GetBottom(void) +{ + return m_iZClipBottom; +} + +void CZClip::Legalise(void) +{ + // need swapping? + // + if (m_iZClipTop < m_iZClipBottom) + { + int iTemp = m_iZClipTop; + m_iZClipTop = m_iZClipBottom; + m_iZClipBottom = iTemp; + } + + // too close together? + // +#define ZCLIP_MIN_SPACING 64 + + if (abs(m_iZClipTop - m_iZClipBottom) < ZCLIP_MIN_SPACING) + m_iZClipBottom = m_iZClipTop - ZCLIP_MIN_SPACING; +} + + +void CZClip::SetTop(int iNewZ) +{ + m_iZClipTop = iNewZ; + + Legalise(); +} + +void CZClip::SetBottom(int iNewZ) +{ + m_iZClipBottom = iNewZ; + + Legalise(); +} + +bool CZClip::IsEnabled(void) +{ + return m_bEnabled; +} + + +bool CZClip::Enable(bool bOnOff) +{ + m_bEnabled = !m_bEnabled; + return IsEnabled(); +} + +#define ZCLIP_BAR_THICKNESS 8 +#define ZCLIP_ARROWHEIGHT (ZCLIP_BAR_THICKNESS*8) + +void CZClip::Paint(void) +{ + float x, y; + int xCam = z.width/4; // hmmm, a rather unpleasant and obscure global name, but it was already called that so... + + qglColor3f (ZCLIP_COLOUR);//1.0, 0.0, 1.0); + + // draw TOP marker... + // + x = 0; + y = m_iZClipTop; + + if (m_bEnabled) + qglBegin(GL_QUADS); + else + qglBegin(GL_LINE_LOOP); + + qglVertex3f (x-xCam,y,0); + qglVertex3f (x-xCam,y+ZCLIP_BAR_THICKNESS,0); + qglVertex3f (x+xCam,y+ZCLIP_BAR_THICKNESS,0); + qglVertex3f (x+xCam,y,0); + qglEnd (); + + qglColor3f (ZCLIP_COLOUR_DIM);//0.8, 0.0, 0.8); + + if (m_bEnabled) + qglBegin(GL_TRIANGLES); + else + qglBegin(GL_LINE_LOOP); + qglVertex3f (x,(y+ZCLIP_BAR_THICKNESS),0); + qglVertex3f (x-xCam,(y+ZCLIP_BAR_THICKNESS)+(ZCLIP_ARROWHEIGHT/2),0); + qglVertex3f (x+xCam,(y+ZCLIP_BAR_THICKNESS)+(ZCLIP_ARROWHEIGHT/2),0); + qglEnd (); + + // draw bottom marker... + // + qglColor3f (ZCLIP_COLOUR);//1.0, 0.0, 1.0); + x = 0; + y = m_iZClipBottom; + + if (m_bEnabled) + qglBegin(GL_QUADS); + else + qglBegin(GL_LINE_LOOP); + qglVertex3f (x-xCam,y,0); + qglVertex3f (x-xCam,y-ZCLIP_BAR_THICKNESS,0); + qglVertex3f (x+xCam,y-ZCLIP_BAR_THICKNESS,0); + qglVertex3f (x+xCam,y,0); + qglEnd (); + + qglColor3f (ZCLIP_COLOUR_DIM);//0.8, 0.0, 0.8); + + if (m_bEnabled) + qglBegin(GL_TRIANGLES); + else + qglBegin(GL_LINE_LOOP); + qglVertex3f (x,(y-ZCLIP_BAR_THICKNESS),0); + qglVertex3f (x-xCam,(y-ZCLIP_BAR_THICKNESS)-(ZCLIP_ARROWHEIGHT/2),0); + qglVertex3f (x+xCam,(y-ZCLIP_BAR_THICKNESS)-(ZCLIP_ARROWHEIGHT/2),0); + qglEnd (); +} + + +///////////////// eof /////////////////// + + diff --git a/tools/radiant/ZClip.h b/tools/radiant/ZClip.h new file mode 100644 index 000000000..fcbcd7d53 --- /dev/null +++ b/tools/radiant/ZClip.h @@ -0,0 +1,59 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef ZCLIP_H +#define ZCLIP_H + +// I don't like doing macros without braces and with whitespace, but the compiler moans if I do these differently, +// and since they're only for use within glColor3f() calls anyway then this is ok... (that's my excuse anyway) +// +#define ZCLIP_COLOUR 1.0f, 0.0f, 1.0f +#define ZCLIP_COLOUR_DIM 0.8f, 0.0f, 0.8f + + +class CZClip +{ +public: + CZClip(); + ~CZClip(); + + int GetTop(void); + int GetBottom(void); + void SetTop(int iNewZ); + void SetBottom(int iNewZ); + void Reset(void); + bool IsEnabled(void); + bool Enable(bool bOnOff); + void Paint(void); + +protected: + void Legalise(void); + + bool m_bEnabled; + int m_iZClipTop; + int m_iZClipBottom; +}; + + +#endif // #ifndef ZCLIP_H + + +///////////// eof /////////////// + + diff --git a/tools/radiant/ZWnd.cpp b/tools/radiant/ZWnd.cpp new file mode 100644 index 000000000..d04d202fd --- /dev/null +++ b/tools/radiant/ZWnd.cpp @@ -0,0 +1,261 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "ZWnd.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CZWnd +IMPLEMENT_DYNCREATE(CZWnd, CWnd); + + +CZWnd::CZWnd() +{ + m_pZClip = NULL; +} + +CZWnd::~CZWnd() +{ +} + + +BEGIN_MESSAGE_MAP(CZWnd, CWnd) + //{{AFX_MSG_MAP(CZWnd) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_KEYDOWN() + ON_WM_LBUTTONDOWN() + ON_WM_MBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_PAINT() + ON_WM_GETMINMAXINFO() + ON_WM_MOUSEMOVE() + ON_WM_SIZE() + ON_WM_NCCALCSIZE() + ON_WM_KILLFOCUS() + ON_WM_SETFOCUS() + ON_WM_CLOSE() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONUP() + ON_WM_RBUTTONUP() + ON_WM_KEYUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CZWnd message handlers + +int CZWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + m_dcZ = ::GetDC(GetSafeHwnd()); + QEW_SetupPixelFormat(m_dcZ, false); + + m_pZClip = new CZClip(); + + return 0; +} + +void CZWnd::OnDestroy() +{ + if (m_pZClip) + { + delete m_pZClip; + m_pZClip = NULL; + } + + CWnd::OnDestroy(); +} + +void CZWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); +} + +void CZWnd::OnLButtonDown(UINT nFlags, CPoint point) +{ + SetFocus(); + SetCapture(); + CRect rctZ; + GetClientRect(rctZ); + Z_MouseDown (point.x, rctZ.Height() - 1 - point.y , nFlags); +} + +void CZWnd::OnMButtonDown(UINT nFlags, CPoint point) +{ + SetFocus(); + SetCapture(); + CRect rctZ; + GetClientRect(rctZ); + Z_MouseDown (point.x, rctZ.Height() - 1 - point.y , nFlags); +} + +void CZWnd::OnRButtonDown(UINT nFlags, CPoint point) +{ + SetFocus(); + SetCapture(); + CRect rctZ; + GetClientRect(rctZ); + Z_MouseDown (point.x, rctZ.Height() - 1 - point.y , nFlags); +} + +void CZWnd::OnPaint() +{ + CPaintDC dc(this); // device context for painting + //if (!wglMakeCurrent(m_dcZ, m_hglrcZ)) + //if (!qwglMakeCurrent(dc.m_hDC, m_hglrcZ)) + if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) + { + common->Printf("ERROR: wglMakeCurrent failed..\n "); + common->Printf("Please restart " EDITOR_WINDOWTEXT " if the Z view is not working\n"); + } + else + { + QE_CheckOpenGLForErrors(); + + Z_Draw (); + //qwglSwapBuffers(m_dcZ); + qwglSwapBuffers(dc.m_hDC); + TRACE("Z Paint\n"); + } +} + +void CZWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) +{ + lpMMI->ptMinTrackSize.x = ZWIN_WIDTH; +} + +void CZWnd::OnMouseMove(UINT nFlags, CPoint point) +{ + CRect rctZ; + GetClientRect(rctZ); + float fz = z.origin[2] + ((rctZ.Height() - 1 - point.y) - (z.height/2)) / z.scale; + fz = floor(fz / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize; + CString strStatus; + strStatus.Format("Z:: %.1f", fz); + g_pParentWnd->SetStatusText(1, strStatus); + Z_MouseMoved (point.x, rctZ.Height() - 1 - point.y, nFlags); +} + +void CZWnd::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + CRect rctZ; + GetClientRect(rctZ); + z.width = rctZ.right; + z.height = rctZ.bottom; + if (z.width < 10) + z.width = 10; + if (z.height < 10) + z.height = 10; + Invalidate(); +} + +void CZWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) +{ + CWnd::OnNcCalcSize(bCalcValidRects, lpncsp); +} + +void CZWnd::OnKillFocus(CWnd* pNewWnd) +{ + CWnd::OnKillFocus(pNewWnd); + SendMessage(WM_NCACTIVATE, FALSE , 0 ); +} + +void CZWnd::OnSetFocus(CWnd* pOldWnd) +{ + CWnd::OnSetFocus(pOldWnd); + SendMessage(WM_NCACTIVATE, TRUE , 0 ); +} + +void CZWnd::OnClose() +{ + CWnd::OnClose(); +} + +void CZWnd::OnLButtonUp(UINT nFlags, CPoint point) +{ + CRect rctZ; + GetClientRect(rctZ); + Z_MouseUp (point.x, rctZ.bottom - 1 - point.y, nFlags); + if (! (nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); +} + +void CZWnd::OnMButtonUp(UINT nFlags, CPoint point) +{ + CRect rctZ; + GetClientRect(rctZ); + Z_MouseUp (point.x, rctZ.bottom - 1 - point.y, nFlags); + if (! (nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); +} + +void CZWnd::OnRButtonUp(UINT nFlags, CPoint point) +{ + CRect rctZ; + GetClientRect(rctZ); + Z_MouseUp (point.x, rctZ.bottom - 1 - point.y, nFlags); + if (! (nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); +} + + +BOOL CZWnd::PreCreateWindow(CREATESTRUCT& cs) +{ + WNDCLASS wc; + HINSTANCE hInstance = AfxGetInstanceHandle(); + if (::GetClassInfo(hInstance, Z_WINDOW_CLASS, &wc) == FALSE) + { + // Register a new class + memset (&wc, 0, sizeof(wc)); + wc.style = CS_NOCLOSE;// | CS_OWNDC; + wc.lpszClassName = Z_WINDOW_CLASS; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.lpfnWndProc = ::DefWindowProc; + if (AfxRegisterClass(&wc) == FALSE) + Error ("CZWnd RegisterClass: failed"); + } + + cs.lpszClass = Z_WINDOW_CLASS; + cs.lpszName = "Z"; + if (cs.style != QE3_CHILDSTYLE) + cs.style = QE3_SPLITTER_STYLE; + + return CWnd::PreCreateWindow(cs); +} + + +void CZWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); +} diff --git a/tools/radiant/ZWnd.h b/tools/radiant/ZWnd.h new file mode 100644 index 000000000..6c699541e --- /dev/null +++ b/tools/radiant/ZWnd.h @@ -0,0 +1,91 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_ZWND_H__44B4BA02_781B_11D1_B53C_00AA00A410FC__INCLUDED_) +#define AFX_ZWND_H__44B4BA02_781B_11D1_B53C_00AA00A410FC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// ZWnd.h : header file +// + +#include "zclip.h" + +///////////////////////////////////////////////////////////////////////////// +// CZWnd window + +class CZWnd : public CWnd +{ + DECLARE_DYNCREATE(CZWnd); +// Construction +public: + CZWnd(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CZWnd) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CZWnd(); + + CZClip *m_pZClip; + + // Generated message map functions +protected: + HDC m_dcZ; + HGLRC m_hglrcZ; + //{{AFX_MSG(CZWnd) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnPaint(); + afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp); + afx_msg void OnKillFocus(CWnd* pNewWnd); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnClose(); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ZWND_H__44B4BA02_781B_11D1_B53C_00AA00A410FC__INCLUDED_) diff --git a/tools/radiant/autocaulk.cpp b/tools/radiant/autocaulk.cpp new file mode 100644 index 000000000..b33453d22 --- /dev/null +++ b/tools/radiant/autocaulk.cpp @@ -0,0 +1,331 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "Radiant.h" +#include "autocaulk.h" + +// Note: the code in here looks pretty goofy in places, and probably doesn't use the new Q4 class stuff fully, +// but I just got it in and compiling from the JK2/SOF2 Radiants via some ugly code replaces, and it works, so there. +// Also, a bunch of Radiant fields no longer exist in this codebase, likewise the whole point of passing in the bool +// to this code, but I've just left it as-is. A designer tested it and pronounced it fine. + +//#pragma warning( disable : 4786) +//#include +//using namespace std; +//#pragma warning( disable : 4786) + +#undef strnicmp +#define strnicmp idStr::Icmpn + +#if 1 + + +//extern void ClearBounds (idVec3 mins, idVec3 maxs); +//extern void AddPointToBounds (const idVec3 v, idVec3 mins, idVec3 maxs); +void ClearBounds (idVec3 &mins, idVec3 &maxs) +{ + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; +} + +void AddPointToBounds( const idVec3 &v, idVec3 &mins, idVec3 &maxs ) +{ + int i; + float val; + + for (i=0 ; i<3 ; i++) + { + val = v[i]; + if (val < mins[i]) + mins[i] = val; + if (val > maxs[i]) + maxs[i] = val; + } +} + + +static void FloorBounds(idVec3 &mins, idVec3 &maxs) +{ + for (int i=0 ; i<3 ; i++) + { + mins[i] = floor(mins[i] + 0.5); + maxs[i] = floor(maxs[i] + 0.5); + } +} + + +static LPCSTR vtos(idVec3 &v3) +{ + return va("%.3ff,%.3f,%.3f",v3[0],v3[1],v3[2]); +} +struct PairBrushFace_t +{ + face_t* pFace; + brush_t* pBrush; +}; +idList < PairBrushFace_t > FacesToCaulk; +void Select_AutoCaulk() +{ + /*Sys_Printf*/common->Printf("Caulking...\n"); + + FacesToCaulk.Clear(); + + int iSystemBrushesSkipped = 0; + face_t *pSelectedFace; + + brush_t *next; + for (brush_t *pSelectedBrush = selected_brushes.next ; pSelectedBrush != &selected_brushes ; pSelectedBrush = next) + { + next = pSelectedBrush->next; + + if (pSelectedBrush->owner->eclass->fixedsize) + continue; // apparently this means it's a model, so skip it... + + // new check, we can't caulk a brush that has any "system/" faces... + // + bool bSystemFacePresent = false; + for ( pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next) + { + if (!strnicmp(pSelectedFace->d_texture->GetName(),"system/",7)) + { + bSystemFacePresent = true; + break; + } + } + if (bSystemFacePresent) + { + iSystemBrushesSkipped++; + continue; // verboten to caulk this. + } + + for (int iBrushListToScan = 0; iBrushListToScan<2; iBrushListToScan++) + { + brush_t *snext; + for (brush_t *pScannedBrush = (iBrushListToScan?active_brushes.next:selected_brushes.next); pScannedBrush != (iBrushListToScan?&active_brushes:&selected_brushes) ; pScannedBrush = snext) + { + snext = pScannedBrush->next; + + if ( pScannedBrush == pSelectedBrush) + continue; + + if (pScannedBrush->owner->eclass->fixedsize || pScannedBrush->pPatch || pScannedBrush->hiddenBrush) + continue; + + if (FilterBrush(pScannedBrush)) + continue; + +// idMaterial stuff no longer support this, not sure what else to do. +// Searching for other occurences of QER_NOCARVE just shows people REMing the code and ignoring ths issue... +// +// if (pScannedBrush->brush_faces->d_texture->bFromShader && (pScannedBrush->brush_faces->d_texture->TestMaterialFlag(QER_NOCARVE))) +// continue; + + // basic-reject first to see if brushes can even possibly touch (coplanar counts as touching) + // + int i; + for (i=0 ; i<3 ; i++) + { + if (pSelectedBrush->mins[i] > pScannedBrush->maxs[i] || + pSelectedBrush->maxs[i] < pScannedBrush->mins[i]) + { + break; + } + } + if (i != 3) + continue; // can't be touching + + // ok, now for the clever stuff, we need to detect only those faces that are both coplanar and smaller + // or equal to the face they're coplanar with... + // + for (pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next) + { + idWinding *pSelectedWinding = pSelectedFace->face_winding; + + if (!pSelectedWinding) + continue; // freed face, probably won't happen here, but who knows with this program? + + // SquaredFace_t SelectedSquaredFace; + // WindingToSquaredFace( &SelectedSquaredFace, pSelectedWinding); + + for (face_t *pScannedFace = pScannedBrush->brush_faces; pScannedFace; pScannedFace = pScannedFace->next) + { + // don't even try caulking against a system face, because these are often transparent and will leave holes + // + if (!strnicmp(pScannedFace->d_texture->GetName(),"system/",7)) + continue; + + // and don't try caulking against something inherently transparent... + // + if (pScannedFace->d_texture->TestMaterialFlag(QER_TRANS)) + continue; + + idWinding *pScannedWinding = pScannedFace->face_winding; + + if (!pScannedWinding) + continue; // freed face, probably won't happen here, but who knows with this program? + + // SquaredFace_t ScannedSquaredFace; + // WindingToSquaredFace( &ScannedSquaredFace, pScannedWinding); + + /* if (VectorCompare(ScannedSquaredFace.v3NormalisedRotationVector, SelectedSquaredFace.v3NormalisedRotationVector) + && + VectorCompare(ScannedSquaredFace.v3NormalisedElevationVector, SelectedSquaredFace.v3NormalisedElevationVector) + ) + */ + { + // brush faces are in parallel planes to each other, so check that their normals + // are opposite, by adding them together and testing for zero... + // (if normals are opposite, then faces can be against/touching each other?) + // + idVec3 v3ZeroTest; + idVec3 v3Zero;v3Zero.Zero(); //static idVec3 v3Zero={0,0,0}; + + VectorAdd(pSelectedFace->plane.Normal(),pScannedFace->plane.Normal(),v3ZeroTest); + if (v3ZeroTest == v3Zero) + { + // planes are facing each other... + // + // coplanar? (this is some maths of Gil's, which I don't even pretend to understand) + // + float fTotalDist = 0; + for (int _i=0; _i<3; _i++) + { + fTotalDist += fabs( DotProduct(pSelectedFace->plane.Normal(),(*pSelectedWinding)[0]) + - + DotProduct(pSelectedFace->plane.Normal(),(*pScannedWinding)[i]) + ); + } + //OutputDebugString(va("Dist = %g\n",fTotalDist)); + + if (fTotalDist > 0.01) + continue; + + // every point in the selected face must be within (or equal to) the bounds of the + // scanned face... + // + // work out the bounds first... + // + idVec3 v3ScannedBoundsMins, v3ScannedBoundsMaxs; + ClearBounds (v3ScannedBoundsMins, v3ScannedBoundsMaxs); + int iPoint; + for (iPoint=0; iPointGetNumPoints(); iPoint++) + { + AddPointToBounds( (*pScannedWinding)[iPoint].ToVec3(), v3ScannedBoundsMins, v3ScannedBoundsMaxs); + } + // floor 'em... (or .001 differences mess things up... + // + FloorBounds(v3ScannedBoundsMins, v3ScannedBoundsMaxs); + + + // now check points from selected face... + // + bool bWithin = true; + for (iPoint=0; iPoint < pSelectedWinding->GetNumPoints(); iPoint++) + { + for (int iXYZ=0; iXYZ<3; iXYZ++) + { + float f = floor((*pSelectedWinding)[iPoint][iXYZ] + 0.5); + if (! + ( + f >= v3ScannedBoundsMins[iXYZ] + && + f <= v3ScannedBoundsMaxs[iXYZ] + ) + ) + { + bWithin = false; + } + } + } + + if (bWithin) + { + PairBrushFace_t PairBrushFace; + PairBrushFace.pFace = pSelectedFace; + PairBrushFace.pBrush= pSelectedBrush; + FacesToCaulk.Append(PairBrushFace); + } + } + } + } + } + } + } + } + + + // apply caulk... + // + int iFacesCaulked = 0; + if (FacesToCaulk.Num()) + { + LPCSTR psCaulkName = "textures/common/caulk"; + const idMaterial *pCaulk = Texture_ForName(psCaulkName); + + if (pCaulk) + { + // + // and call some other junk that Radiant wants so so we can use it later... + // + texdef_t tex; + memset (&tex, 0, sizeof(tex)); + tex.scale[0] = 1; + tex.scale[1] = 1; + //tex.flags = pCaulk->flags; // field missing in Q4 + //tex.value = pCaulk->value; // ditto + //tex.contents = pCaulk->contents; // ditto + tex.SetName( pCaulk->GetName() ); + + //Texture_SetTexture (&tex); + + for (int iListEntry = 0; iListEntry < FacesToCaulk.Num(); iListEntry++) + { + PairBrushFace_t &PairBrushFace = FacesToCaulk[iListEntry]; + face_t *pFace = PairBrushFace.pFace; + brush_t*pBrush= PairBrushFace.pBrush; + + pFace->d_texture = pCaulk; + pFace->texdef = tex; + + Face_FitTexture(pFace, 1, 1); // this doesn't work here for some reason... duh. + Brush_Build(pBrush); + + iFacesCaulked++; + } + } + else + { + /*Sys_Printf*/common->Printf(" Unable to locate caulk texture at: \"%s\"!\n",psCaulkName); + } + } + + /*Sys_Printf*/common->Printf("( %d faces caulked )\n",iFacesCaulked); + + if (iSystemBrushesSkipped) + { + /*Sys_Printf*/common->Printf("( %d system-faced brushes skipped )\n",iSystemBrushesSkipped); + } + + Sys_UpdateWindows (W_ALL); +} +#endif \ No newline at end of file diff --git a/tools/radiant/autocaulk.h b/tools/radiant/autocaulk.h new file mode 100644 index 000000000..a85d7fde3 --- /dev/null +++ b/tools/radiant/autocaulk.h @@ -0,0 +1,30 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef AUTOCAULK_H +#define AUTOCAULK_H + + +void Select_AutoCaulk(); + + +#endif // AUTOCAULK_H + +///////////////// eof ////////////// + diff --git a/tools/radiant/cmdlib.cpp b/tools/radiant/cmdlib.cpp new file mode 100644 index 000000000..deecaf8b7 --- /dev/null +++ b/tools/radiant/cmdlib.cpp @@ -0,0 +1,227 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "qe3.h" +#include "cmdlib.h" + +#define PATHSEPERATOR '/' + +// rad additions +// 11.29.99 +PFN_ERR *g_pfnError = NULL; +PFN_PRINTF *g_pfnPrintf = NULL; +PFN_ERR_NUM *g_pfnErrorNum = NULL; +PFN_PRINTF_NUM *g_pfnPrintfNum = NULL; + + +void Error(const char *pFormat, ...) +{ + if (g_pfnError) + { + va_list arg_ptr; + va_start(arg_ptr, pFormat); + g_pfnError(pFormat, arg_ptr); + va_end(arg_ptr); + } +} + +void Printf(const char *pFormat, ...) +{ + if (g_pfnPrintf) + { + va_list arg_ptr; + va_start(arg_ptr, pFormat); + g_pfnPrintf(pFormat, arg_ptr); + va_end(arg_ptr); + } +} + +void ErrorNum(int nErr, const char *pFormat, ...) +{ + if (g_pfnErrorNum) + { + va_list arg_ptr; + va_start(arg_ptr, pFormat); + g_pfnErrorNum(nErr, pFormat, arg_ptr); + va_end(arg_ptr); + } +} + +void PrintfNum(int nErr, const char *pFormat, ...) +{ + if (g_pfnPrintfNum) + { + va_list arg_ptr; + va_start(arg_ptr, pFormat); + g_pfnPrintfNum(nErr, pFormat, arg_ptr); + va_end(arg_ptr); + } +} + +void SetErrorHandler(PFN_ERR pe) +{ + g_pfnError = pe; +} + +void SetPrintfHandler(PFN_PRINTF pe) +{ + g_pfnPrintf = pe; +} + +void SetErrorHandlerNum(PFN_ERR_NUM pe) +{ + g_pfnErrorNum = pe; +} + +void SetPrintfHandler(PFN_PRINTF_NUM pe) +{ + g_pfnPrintfNum = pe; +} + + +/* +================ +Q_filelength +================ +*/ +int Q_filelength (FILE *f) +{ + int pos; + int end; + + pos = ftell (f); + fseek (f, 0, SEEK_END); + end = ftell (f); + fseek (f, pos, SEEK_SET); + + return end; +} + +/* +============== +LoadFile +============== +*/ +int LoadFile (const char *filename, void **bufferptr) +{ + FILE *f; + int length; + void *buffer; + + *bufferptr = NULL; + + if ( filename == NULL || strlen(filename) == 0 ) { + return -1; + } + + f = fopen( filename, "rb" ); + if ( !f ) { + return -1; + } + length = Q_filelength( f ); + buffer = Mem_ClearedAlloc( length+1 ); + ((char *)buffer)[length] = 0; + if ( (int)fread( buffer, 1, length, f ) != length ) { + Error( "File read failure" ); + } + fclose( f ); + + *bufferptr = buffer; + return length; +} + +/* +============== +DefaultExtension +============== +*/ +void DefaultExtension (char *path, char *extension) +{ + char *src; + // + // if path doesn't have a .EXT, append extension + // (extension should include the .) + // + src = path + strlen(path) - 1; + + while (*src != PATHSEPERATOR && src != path) + { + if (*src == '.') + return; // it has an extension + src--; + } + + strcat (path, extension); +} + +/* +============== +DefaultPath +============== +*/ +void DefaultPath (char *path, char *basepath) +{ + char temp[128]; + + if (path[0] == PATHSEPERATOR) + return; // absolute path location + strcpy (temp,path); + strcpy (path,basepath); + strcat (path,temp); +} + +/* +============== +StripFilename +============== +*/ +void StripFilename (char *path) +{ + int length; + + length = strlen(path)-1; + while (length > 0 && path[length] != PATHSEPERATOR) { + length--; + } + path[length] = 0; +} + +/* +============== +StripExtension +============== +*/ +void StripExtension (char *path) +{ + int length; + + length = strlen(path)-1; + while (length > 0 && path[length] != '.') + { + length--; + if (path[length] == '/') + return; // no extension + } + if (length) { + path[length] = 0; + } +} diff --git a/tools/radiant/cmdlib.h b/tools/radiant/cmdlib.h new file mode 100644 index 000000000..3aef29753 --- /dev/null +++ b/tools/radiant/cmdlib.h @@ -0,0 +1,54 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __CMDLIB__ +#define __CMDLIB__ + +#include +#include +#include +#include +#include +#include +#include + + +int LoadFile( const char *filename, void **bufferptr ); +void DefaultExtension( char *path, char *extension ); +void DefaultPath( char *path, char *basepath ); +void StripFilename( char *path ); +void StripExtension( char *path ); + +// error and printf functions +typedef void (PFN_ERR)( const char *pFormat, ... ); +typedef void (PFN_PRINTF)( const char *pFormat, ... ); +typedef void (PFN_ERR_NUM)( int nNum, const char *pFormat, ... ); +typedef void (PFN_PRINTF_NUM)( int nNum, const char *pFormat, ... ); + +void Error( const char *pFormat, ... ); +void Printf( const char *pFormat, ... ); +void ErrorNum( int n, const char *pFormat, ... ); +void PrintfNum( int n, const char *pFormat, ... ); + +void SetErrorHandler( PFN_ERR pe ); +void SetPrintfHandler( PFN_PRINTF pe ); +void SetErrorHandlerNum( PFN_ERR_NUM pe ); +void SetPrintfHandlerNum( PFN_PRINTF_NUM pe ); + +#endif /* !__CMDLIB__ */ diff --git a/tools/radiant/splines.cpp b/tools/radiant/splines.cpp new file mode 100644 index 000000000..c9d5bd937 --- /dev/null +++ b/tools/radiant/splines.cpp @@ -0,0 +1,2028 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "splines.h" + +idCameraDef splineList; +idCameraDef *g_splineList = &splineList; + +/* +================ +glLabeledPoint +================ +*/ +void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label) { + qglColor3fv( color.ToFloatPtr() ); + qglPointSize( size ); + qglBegin( GL_POINTS ); + qglVertex3fv( point.ToFloatPtr() ); + qglEnd(); + idVec3 v = point; + v.x += 1; + v.y += 1; + v.z += 1; + qglRasterPos3fv( v.ToFloatPtr() ); + qglCallLists( strlen(label), GL_UNSIGNED_BYTE, label ); +} + +/* +================ +glBox +================ +*/ +void glBox(idVec4 &color, idVec3 &point, float size) { + idVec3 mins(point); + idVec3 maxs(point); + mins[0] -= size; + mins[1] += size; + mins[2] -= size; + maxs[0] += size; + maxs[1] -= size; + maxs[2] += size; + idVec4 saveColor; + qglGetFloatv(GL_CURRENT_COLOR, saveColor.ToFloatPtr()); + qglColor3fv( color.ToFloatPtr() ); + qglBegin(GL_LINE_LOOP); + qglVertex3f(mins[0],mins[1],mins[2]); + qglVertex3f(maxs[0],mins[1],mins[2]); + qglVertex3f(maxs[0],maxs[1],mins[2]); + qglVertex3f(mins[0],maxs[1],mins[2]); + qglEnd(); + qglBegin(GL_LINE_LOOP); + qglVertex3f(mins[0],mins[1],maxs[2]); + qglVertex3f(maxs[0],mins[1],maxs[2]); + qglVertex3f(maxs[0],maxs[1],maxs[2]); + qglVertex3f(mins[0],maxs[1],maxs[2]); + qglEnd(); + + qglBegin(GL_LINES); + qglVertex3f(mins[0],mins[1],mins[2]); + qglVertex3f(mins[0],mins[1],maxs[2]); + qglVertex3f(mins[0],maxs[1],maxs[2]); + qglVertex3f(mins[0],maxs[1],mins[2]); + qglVertex3f(maxs[0],mins[1],mins[2]); + qglVertex3f(maxs[0],mins[1],maxs[2]); + qglVertex3f(maxs[0],maxs[1],maxs[2]); + qglVertex3f(maxs[0],maxs[1],mins[2]); + qglEnd(); + qglColor4fv(saveColor.ToFloatPtr()); + +} + +/* +================ +splineTest +================ +*/ +void splineTest() { + //g_splineList->load("p:/doom/base/maps/test_base1.camera"); +} + +/* +================ +splineDraw +================ +*/ +void splineDraw() { + //g_splineList->addToRenderer(); +} + +/* +================ +debugLine +================ +*/ +void debugLine(idVec4 &color, float x, float y, float z, float x2, float y2, float z2) { + idVec3 from(x, y, z); + idVec3 to(x2, y2, z2); + session->rw->DebugLine(color, from, to); +} + + +/* +================================================================================= + +idPointListInterface + +================================================================================= +*/ + +/* +================ +idPointListInterface::selectPointByRay +================ +*/ +int idPointListInterface::selectPointByRay(const idVec3 &origin, const idVec3 &direction, bool single) { + int i, besti, count; + float d, bestd; + idVec3 temp, temp2; + + // find the point closest to the ray + besti = -1; + bestd = 8; + count = numPoints(); + + for (i=0; i < count; i++) { + temp = *getPoint(i); + temp2 = temp; + temp -= origin; + d = DotProduct(temp, direction); + VectorMA (origin, d, direction, temp); + temp2 -= temp; + d = temp2.Length(); + if (d <= bestd) { + bestd = d; + besti = i; + } + } + + if (besti >= 0) { + selectPoint(besti, single); + } + + return besti; +} + +/* +================ +idPointListInterface::isPointSelected +================ +*/ +int idPointListInterface::isPointSelected(int index) { + int count = selectedPoints.Num(); + for (int i = 0; i < count; i++) { + if (selectedPoints[i] == index) { + return i; + } + } + return -1; +} + +/* +================ +idPointListInterface::selectPoint +================ +*/ +int idPointListInterface::selectPoint(int index, bool single) { + if (index >= 0 && index < numPoints()) { + if (single) { + deselectAll(); + } else { + if (isPointSelected(index) >= 0) { + selectedPoints.Remove(index); + } + } + return selectedPoints.Append(index); + } + return -1; +} + +/* +================ +idPointListInterface::selectAll +================ +*/ +void idPointListInterface::selectAll() { + selectedPoints.Clear(); + for (int i = 0; i < numPoints(); i++) { + selectedPoints.Append(i); + } +} + +/* +================ +idPointListInterface::deselectAll +================ +*/ +void idPointListInterface::deselectAll() { + selectedPoints.Clear(); +} + +/* +================ +idPointListInterface::getSelectedPoint +================ +*/ +idVec3 *idPointListInterface::getSelectedPoint( int index ) { + assert(index >= 0 && index < numSelectedPoints()); + return getPoint(selectedPoints[index]); +} + +/* +================ +idPointListInterface::updateSelection +================ +*/ +void idPointListInterface::updateSelection(const idVec3 &move) { + int count = selectedPoints.Num(); + for (int i = 0; i < count; i++) { + *getPoint(selectedPoints[i]) += move; + } +} + +/* +================ +idPointListInterface::drawSelection +================ +*/ +void idPointListInterface::drawSelection() { + int count = selectedPoints.Num(); + for (int i = 0; i < count; i++) { + glBox(colorRed, *getPoint(selectedPoints[i]), 4); + } +} + +/* +================================================================================= + +idSplineList + +================================================================================= +*/ + +/* +================ +idSplineList::clearControl +================ +*/ +void idSplineList::clearControl() { + for (int i = 0; i < controlPoints.Num(); i++) { + delete controlPoints[i]; + } + controlPoints.Clear(); +} + +/* +================ +idSplineList::clearSpline +================ +*/ +void idSplineList::clearSpline() { + for (int i = 0; i < splinePoints.Num(); i++) { + delete splinePoints[i]; + } + splinePoints.Clear(); +} + +/* +================ +idSplineList::clear +================ +*/ +void idSplineList::clear() { + clearControl(); + clearSpline(); + splineTime.Clear(); + selected = NULL; + dirty = true; + activeSegment = 0; + granularity = 0.025f; + pathColor = idVec4(1.0f, 0.5f, 0.0f, 1.0f); + controlColor = idVec4(0.7f, 0.0f, 1.0f, 1.0f); + segmentColor = idVec4(0.0f, 0.0f, 1.0f, 1.0); + activeColor = idVec4(1.0f, 0.0f, 0.0f, 1.0f); +} + +/* +================ +idSplineList::setColors +================ +*/ +void idSplineList::setColors(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active) { + pathColor = path; + segmentColor = segment; + controlColor = control; + activeColor = active; +} + +/* +================ +idSplineList::validTime +================ +*/ +bool idSplineList::validTime() { + if (dirty) { + buildSpline(); + } + // gcc doesn't allow static casting away from bools + // why? I've no idea... + return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num()); +} + +/* +================ +idSplineList::addToRenderer +================ +*/ +void idSplineList::addToRenderer() { + int i; + idVec3 mins, maxs; + + if (controlPoints.Num() == 0) { + return; + } + + for(i = 0; i < controlPoints.Num(); i++) { + VectorCopy(*controlPoints[i], mins); + VectorCopy(mins, maxs); + mins[0] -= 8; + mins[1] += 8; + mins[2] -= 8; + maxs[0] += 8; + maxs[1] -= 8; + maxs[2] += 8; + debugLine( colorYellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2]); + debugLine( colorYellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2]); + debugLine( colorYellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2]); + debugLine( colorYellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2]); + + debugLine( colorYellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2]); + debugLine( colorYellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2]); + debugLine( colorYellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2]); + debugLine( colorYellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2]); + + } + + int step = 0; + idVec3 step1; + for(i = 3; i < controlPoints.Num(); i++) { + for (float tension = 0.0f; tension < 1.001f; tension += 0.1f) { + float x = 0; + float y = 0; + float z = 0; + for (int j = 0; j < 4; j++) { + x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension); + y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension); + z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension); + } + if (step == 0) { + step1[0] = x; + step1[1] = y; + step1[2] = z; + step = 1; + } else { + debugLine( colorWhite, step1[0], step1[1], step1[2], x, y, z); + step = 0; + } + + } + } +} + +/* +================ +idSplineList::buildSpline +================ +*/ +void idSplineList::buildSpline() { + int start = Sys_Milliseconds(); + clearSpline(); + for(int i = 3; i < controlPoints.Num(); i++) { + for (float tension = 0.0f; tension < 1.001f; tension += granularity) { + float x = 0; + float y = 0; + float z = 0; + for (int j = 0; j < 4; j++) { + x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension); + y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension); + z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension); + } + splinePoints.Append(new idVec3(x, y, z)); + } + } + dirty = false; + //common->Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000); +} + +/* +================ +idSplineList::draw +================ +*/ +void idSplineList::draw(bool editMode) { + int i; + + if (controlPoints.Num() == 0) { + return; + } + + if (dirty) { + buildSpline(); + } + + + qglColor3fv( controlColor.ToFloatPtr() ); + qglPointSize( 5 ); + + qglBegin(GL_POINTS); + for (i = 0; i < controlPoints.Num(); i++) { + qglVertex3fv( (*controlPoints[i]).ToFloatPtr() ); + } + qglEnd(); + + if (editMode) { + for(i = 0; i < controlPoints.Num(); i++) { + glBox(activeColor, *controlPoints[i], 4); + } + } + + //Draw the curve + qglColor3fv( pathColor.ToFloatPtr() ); + qglBegin(GL_LINE_STRIP); + int count = splinePoints.Num(); + for (i = 0; i < count; i++) { + qglVertex3fv( (*splinePoints[i]).ToFloatPtr() ); + } + qglEnd(); + + if (editMode) { + qglColor3fv( segmentColor.ToFloatPtr() ); + qglPointSize(3); + qglBegin(GL_POINTS); + for (i = 0; i < count; i++) { + qglVertex3fv( (*splinePoints[i]).ToFloatPtr() ); + } + qglEnd(); + } + if (count > 0) { + //assert(activeSegment >=0 && activeSegment < count); + if (activeSegment >=0 && activeSegment < count) { + glBox(activeColor, *splinePoints[activeSegment], 6); + glBox(colorYellow, *splinePoints[activeSegment], 8); + } + } + +} + +/* +================ +idSplineList::totalDistance +================ +*/ +float idSplineList::totalDistance() { + + // FIXME: save dist and return + // + if (controlPoints.Num() == 0) { + return 0.0f; + } + + if (dirty) { + buildSpline(); + } + + float dist = 0.0f; + idVec3 temp; + int count = splinePoints.Num(); + for(int i = 1; i < count; i++) { + temp = *splinePoints[i-1]; + temp -= *splinePoints[i]; + dist += temp.Length(); + } + return dist; +} + +/* +================ +idSplineList::initPosition +================ +*/ +void idSplineList::initPosition(long bt, long totalTime) { + + if (dirty) { + buildSpline(); + } + + if (splinePoints.Num() == 0) { + return; + } + + baseTime = bt; + time = totalTime; + + // calc distance to travel ( this will soon be broken into time segments ) + splineTime.Clear(); + splineTime.Append(bt); + double dist = totalDistance(); + double distSoFar = 0.0; + idVec3 temp; + int count = splinePoints.Num(); + //for(int i = 2; i < count - 1; i++) { + for(int i = 1; i < count; i++) { + temp = *splinePoints[i-1]; + temp -= *splinePoints[i]; + distSoFar += temp.Length(); + double percent = distSoFar / dist; + percent *= totalTime; + splineTime.Append(percent + bt); + } + assert(splineTime.Num() == splinePoints.Num()); + activeSegment = 0; +} + +/* +================ +idSplineList::calcSpline +================ +*/ +float idSplineList::calcSpline(int step, float tension) { + switch(step) { + case 0: return (pow(1 - tension, 3)) / 6; + case 1: return (3 * pow(tension, 3) - 6 * pow(tension, 2) + 4) / 6; + case 2: return (-3 * pow(tension, 3) + 3 * pow(tension, 2) + 3 * tension + 1) / 6; + case 3: return pow(tension, 3) / 6; + } + return 0.0f; +} + +/* +================ +idSplineList::updateSelection +================ +*/ +void idSplineList::updateSelection(const idVec3 &move) { + if (selected) { + dirty = true; + VectorAdd(*selected, move, *selected); + } +} + +/* +================ +idSplineList::setSelectedPoint +================ +*/ +void idSplineList::setSelectedPoint(idVec3 *p) { + if (p) { + p->SnapInt(); + for(int i = 0; i < controlPoints.Num(); i++) { + if ( (*p).Compare( *controlPoints[i], VECTOR_EPSILON ) ) { + selected = controlPoints[i]; + } + } + } else { + selected = NULL; + } +} + +/* +================ +idSplineList::getPosition +================ +*/ +const idVec3 *idSplineList::getPosition(long t) { + static idVec3 interpolatedPos; + + int count = splineTime.Num(); + if (count == 0) { + return &vec3_zero; + } + + assert(splineTime.Num() == splinePoints.Num()); + +#if 0 + float velocity = getVelocity(t); + float timePassed = t - lastTime; + lastTime = t; + + // convert to seconds + timePassed /= 1000; + + float distToTravel = timePassed * velocity; + + distSoFar += distToTravel; + float tempDistance = 0; + + idVec3 temp; + int count = splinePoints.Num(); + //for(int i = 2; i < count - 1; i++) { + for(int i = 1; i < count; i++) { + temp = *splinePoints[i-1]; + temp -= *splinePoints[i]; + tempDistance += temp.Length(); + if (tempDistance >= distSoFar) { + break; + } + } + + if (i == count) { + interpolatedPos = splinePoints[i-1]; + } else { + double timeHi = splineTime[i + 1]; + double timeLo = splineTime[i - 1]; + double percent = (timeHi - t) / (timeHi - timeLo); + idVec3 v1 = *splinePoints[i - 1]; + idVec3 v2 = *splinePoints[i + 1]; + v2 *= (1.0f - percent); + v1 *= percent; + v2 += v1; + interpolatedPos = v2; + } + return &interpolatedPos; + +#else + while (activeSegment < count) { + if (splineTime[activeSegment] >= t) { + if (activeSegment > 0 && activeSegment < count - 1) { + double timeHi = splineTime[activeSegment + 1]; + double timeLo = splineTime[activeSegment - 1]; + //float percent = (float)(baseTime + time - t) / time; + double percent = (timeHi - t) / (timeHi - timeLo); + // pick two bounding points + idVec3 v1 = *splinePoints[activeSegment-1]; + idVec3 v2 = *splinePoints[activeSegment+1]; + v2 *= (1.0f - percent); + v1 *= percent; + v2 += v1; + interpolatedPos = v2; + return &interpolatedPos; + } + return splinePoints[activeSegment]; + } else { + activeSegment++; + } + } + return splinePoints[count-1]; +#endif +} + +/* +================ +idSplineList::parse +================ +*/ +void idSplineList::parse( idParser *src ) { + idToken token; + idStr key; + + src->ExpectTokenString( "{" ); + + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + // if token is not a brace, it is a key for a key/value pair + if ( token == "(" ) { + src->UnreadToken( &token ); + // read the control point + idVec3 point; + src->Parse1DMatrix( 3, point.ToFloatPtr() ); + addPoint(point.x, point.y, point.z); + } + else { + key = token; + src->ReadTokenOnLine( &token ); + if ( !key.Icmp( "granularity" ) ) { + granularity = atof(token.c_str()); + } + else if ( !key.Icmp( "name" ) ) { + name = token; + } + else { + src->Error( "unknown spline list key: %s", key.c_str() ); + break; + } + } + } + dirty = true; +} + +/* +================ +idSplineList::write +================ +*/ +void idSplineList::write( idFile *f, const char *p) { + f->Printf( "\t\t%s {\n", p ); + + //f->Printf( "\t\tname %s\n", name.c_str() ); + f->Printf( "\t\t\tgranularity %f\n", granularity ); + int count = controlPoints.Num(); + for (int i = 0; i < count; i++) { + f->Printf( "\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z ); + } + f->Printf( "\t\t}\n" ); +} + +/* +================================================================================= + +idCamaraDef + +================================================================================= +*/ + +/* +================ +idCameraDef::clear +================ +*/ +void idCameraDef::clear() { + currentCameraPosition = 0; + cameraRunning = false; + lastDirection.Zero(); + baseTime = 30; + activeTarget = 0; + name = "camera01"; + fov.SetFOV(90); + int i; + for (i = 0; i < targetPositions.Num(); i++) { + delete targetPositions[i]; + } + for (i = 0; i < events.Num(); i++) { + delete events[i]; + } + delete cameraPosition; + cameraPosition = NULL; + events.Clear(); + targetPositions.Clear(); +} + +/* +================ +idCameraDef::startNewCamera +================ +*/ +idCameraPosition *idCameraDef::startNewCamera( idCameraPosition::positionType type ) { + clear(); + if (type == idCameraPosition::SPLINE) { + cameraPosition = new idSplinePosition(); + } else if (type == idCameraPosition::INTERPOLATED) { + cameraPosition = new idInterpolatedPosition(); + } else { + cameraPosition = new idFixedPosition(); + } + return cameraPosition; +} + +/* +================ +idCameraDef::addTarget +================ +*/ +void idCameraDef::addTarget(const char *name, idCameraPosition::positionType type) { + const char *text = (name == NULL) ? va("target0%d", numTargets()+1) : name; + idCameraPosition *pos = newFromType(type); + if (pos) { + pos->setName(name); + targetPositions.Append(pos); + activeTarget = numTargets()-1; + if (activeTarget == 0) { + // first one + addEvent(idCameraEvent::EVENT_TARGET, name, 0); + } + } +} + +/* +================ +idCameraDef::getActiveTarget +================ +*/ +idCameraPosition *idCameraDef::getActiveTarget() { + if (targetPositions.Num() == 0) { + addTarget(NULL, idCameraPosition::FIXED); + } + return targetPositions[activeTarget]; +} + +/* +================ +idCameraDef::getActiveTarget +================ +*/ +idCameraPosition *idCameraDef::getActiveTarget(int index) { + if (targetPositions.Num() == 0) { + addTarget(NULL, idCameraPosition::FIXED); + return targetPositions[0]; + } + return targetPositions[index]; +} + +/* +================ +idCameraDef::setActiveTargetByName +================ +*/ +void idCameraDef::setActiveTargetByName( const char *name ) { + for (int i = 0; i < targetPositions.Num(); i++) { + if (idStr::Icmp(name, targetPositions[i]->getName()) == 0) { + setActiveTarget(i); + return; + } + } +} + +/* +================ +idCameraDef::setActiveTarget +================ +*/ +void idCameraDef::setActiveTarget( int index ) { + assert(index >= 0 && index < targetPositions.Num()); + activeTarget = index; +} + +/* +================ +idCameraDef::draw +================ +*/ +void idCameraDef::draw( bool editMode ) { + // gcc doesn't allow casting away from bools + // why? I've no idea... + if (cameraPosition) { + cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit)); + int count = targetPositions.Num(); + for (int i = 0; i < count; i++) { + targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit)); + } + } +} + +/* +================ +idCameraDef::numPoints +================ +*/ +int idCameraDef::numPoints() { + if (cameraEdit) { + return cameraPosition->numPoints(); + } + return getActiveTarget()->numPoints(); +} + +/* +================ +idCameraDef::getPoint +================ +*/ +const idVec3 *idCameraDef::getPoint(int index) { + if (cameraEdit) { + return cameraPosition->getPoint(index); + } + return getActiveTarget()->getPoint(index); +} + +/* +================ +idCameraDef::stopEdit +================ +*/ +void idCameraDef::stopEdit() { + editMode = false; + if (cameraEdit) { + cameraPosition->stopEdit(); + } else { + getActiveTarget()->stopEdit(); + } +} + +/* +================ +idCameraDef::startEdit +================ +*/ +void idCameraDef::startEdit(bool camera) { + cameraEdit = camera; + if (camera) { + cameraPosition->startEdit(); + for (int i = 0; i < targetPositions.Num(); i++) { + targetPositions[i]->stopEdit(); + } + } else { + getActiveTarget()->startEdit(); + cameraPosition->stopEdit(); + } + editMode = true; +} + +/* +================ +idCameraDef::getPositionObj +================ +*/ +idCameraPosition *idCameraDef::getPositionObj() { + if (cameraPosition == NULL) { + cameraPosition = new idFixedPosition(); + } + return cameraPosition; +} + +/* +================ +idCameraDef::getActiveSegmentInfo +================ +*/ +void idCameraDef::getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fov) { +#if 0 + if (!cameraSpline.validTime()) { + buildCamera(); + } + double d = (double)segment / numSegments(); + getCameraInfo(d * totalTime * 1000, origin, direction, fov); +#endif +/* + if (!cameraSpline.validTime()) { + buildCamera(); + } + origin = *cameraSpline.getSegmentPoint(segment); + + + idVec3 temp; + + int numTargets = getTargetSpline()->controlPoints.Num(); + int count = cameraSpline.splineTime.Num(); + if (numTargets == 0) { + // follow the path + if (cameraSpline.getActiveSegment() < count - 1) { + temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; + } + } else if (numTargets == 1) { + temp = *getTargetSpline()->controlPoints[0]; + } else { + temp = *getTargetSpline()->getSegmentPoint(segment); + } + + temp -= origin; + temp.Normalize(); + direction = temp; +*/ +} + +/* +================ +idCameraDef::getCameraInfo +================ +*/ +bool idCameraDef::getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv) { + char buff[ 1024 ]; + int i; + + if ((time - startTime) / 1000 <= totalTime) { + + for( i = 0; i < events.Num(); i++ ) { + if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) { + events[i]->setTriggered(true); + if (events[i]->getType() == idCameraEvent::EVENT_TARGET) { + setActiveTargetByName(events[i]->getParam()); + getActiveTarget()->start(startTime + events[i]->getTime()); + //common->Printf("Triggered event switch to target: %s\n",events[i]->getParam()); + } else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) { +#if 0 +//FIXME: seperate game and editor spline code + idEntity *ent; + ent = gameLocal.FindEntity( events[i]->getParam() ); + if (ent) { + ent->Signal( SIG_TRIGGER ); + ent->ProcessEvent( &EV_Activate, gameLocal.world ); + } +#endif + } else if (events[i]->getType() == idCameraEvent::EVENT_FOV) { + memset(buff, 0, sizeof(buff)); + strcpy(buff, events[i]->getParam()); + const char *param1 = strtok(buff, " \t,\0"); + const char *param2 = strtok(NULL, " \t,\0"); + fov.reset(fov.GetFOV(time), atof(param1), time, atoi(param2)); + //*fv = fov = atof(events[i]->getParam()); + } else if (events[i]->getType() == idCameraEvent::EVENT_CAMERA) { + } else if (events[i]->getType() == idCameraEvent::EVENT_STOP) { + return false; + } + } + } + } else { + } + + origin = *cameraPosition->getPosition(time); + + *fv = fov.GetFOV(time); + + idVec3 temp = origin; + + int numTargets = targetPositions.Num(); + if (numTargets == 0) { +/* + // follow the path + if (cameraSpline.getActiveSegment() < count - 1) { + temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; + if (temp == origin) { + int index = cameraSpline.getActiveSegment() + 2; + while (temp == origin && index < count - 1) { + temp = *cameraSpline.splinePoints[index++]; + } + } + } +*/ + } else { + temp = *getActiveTarget()->getPosition(time); + } + + temp -= origin; + temp.Normalize(); + direction = temp; + + return true; +} + +/* +================ +idCameraDef::waitEvent +================ +*/ +bool idCameraDef::waitEvent(int index) { + //for (int i = 0; i < events.Num(); i++) { + // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) { + // return true; + // } + //} + return false; +} + +/* +================ +idCameraDef::buildCamera +================ +*/ +#define NUM_CCELERATION_SEGS 10 +#define CELL_AMT 5 + +void idCameraDef::buildCamera() { + int i; + int lastSwitch = 0; + idList waits; + idList targets; + + totalTime = baseTime; + cameraPosition->setTime(totalTime * 1000); + // we have a base time layout for the path and the target path + // now we need to layer on any wait or speed changes + for (i = 0; i < events.Num(); i++) { + idCameraEvent *ev = events[i]; + events[i]->setTriggered(false); + switch (events[i]->getType()) { + case idCameraEvent::EVENT_TARGET : { + targets.Append(i); + break; + } + case idCameraEvent::EVENT_FEATHER : { + long startTime = 0; + float speed = 0; + long loopTime = 10; + float stepGoal = cameraPosition->getBaseVelocity() / (1000 / loopTime); + while (startTime <= 1000) { + cameraPosition->addVelocity(startTime, loopTime, speed); + speed += stepGoal; + if (speed > cameraPosition->getBaseVelocity()) { + speed = cameraPosition->getBaseVelocity(); + } + startTime += loopTime; + } + + startTime = totalTime * 1000 - 1000; + long endTime = startTime + 1000; + speed = cameraPosition->getBaseVelocity(); + while (startTime < endTime) { + speed -= stepGoal; + if (speed < 0) { + speed = 0; + } + cameraPosition->addVelocity(startTime, loopTime, speed); + startTime += loopTime; + } + break; + + } + case idCameraEvent::EVENT_WAIT : { + waits.Append(atof(events[i]->getParam())); + + //FIXME: this is quite hacky for Wolf E3, accel and decel needs + // do be parameter based etc.. + long startTime = events[i]->getTime() - 1000; + if (startTime < 0) { + startTime = 0; + } + float speed = cameraPosition->getBaseVelocity(); + long loopTime = 10; + float steps = speed / ((events[i]->getTime() - startTime) / loopTime); + while (startTime <= events[i]->getTime() - loopTime) { + cameraPosition->addVelocity(startTime, loopTime, speed); + speed -= steps; + startTime += loopTime; + } + cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0); + + startTime = events[i]->getTime() + atof(events[i]->getParam()) * 1000; + long endTime = startTime + 1000; + speed = 0; + while (startTime <= endTime) { + cameraPosition->addVelocity(startTime, loopTime, speed); + speed += steps; + startTime += loopTime; + } + break; + } + case idCameraEvent::EVENT_TARGETWAIT : { + //targetWaits.Append(i); + break; + } + case idCameraEvent::EVENT_SPEED : { +/* + // take the average delay between up to the next five segments + float adjust = atof(events[i]->getParam()); + int index = events[i]->getSegment(); + total = 0; + count = 0; + + // get total amount of time over the remainder of the segment + for (j = index; j < cameraSpline.numSegments() - 1; j++) { + total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j); + count++; + } + + // multiply that by the adjustment + double newTotal = total * adjust; + // what is the difference.. + newTotal -= total; + totalTime += newTotal / 1000; + + // per segment difference + newTotal /= count; + int additive = newTotal; + + // now propogate that difference out to each segment + for (j = index; j < cameraSpline.numSegments(); j++) { + cameraSpline.addSegmentTime(j, additive); + additive += newTotal; + } + break; +*/ + } + } + } + + + for (i = 0; i < waits.Num(); i++) { + totalTime += waits[i]; + } + + // on a new target switch, we need to take time to this point ( since last target switch ) + // and allocate it across the active target, then reset time to this point + long timeSoFar = 0; + long total = totalTime * 1000; + for (i = 0; i < targets.Num(); i++) { + long t; + if (i < targets.Num() - 1) { + t = events[targets[i+1]]->getTime(); + } else { + t = total - timeSoFar; + } + // t is how much time to use for this target + setActiveTargetByName(events[targets[i]]->getParam()); + getActiveTarget()->setTime(t); + timeSoFar += t; + } +} + +/* +================ +idCameraDef::startCamera +================ +*/ +void idCameraDef::startCamera(long t) { + cameraPosition->clearVelocities(); + cameraPosition->start(t); + buildCamera(); + //for (int i = 0; i < targetPositions.Num(); i++) { + // targetPositions[i]-> + //} + startTime = t; + cameraRunning = true; +} + +/* +================ +idCameraDef::parse +================ +*/ +void idCameraDef::parse( idParser *src ) { + idToken token; + + src->ReadToken(&token); + src->ExpectTokenString( "{" ); + while ( 1 ) { + + src->ExpectAnyToken( &token ); + + if ( token == "}" ) { + break; + } + else if ( !token.Icmp( "time" ) ) { + baseTime = src->ParseFloat(); + } + else if ( !token.Icmp( "camera_fixed") ) { + cameraPosition = new idFixedPosition(); + cameraPosition->parse( src ); + } + else if ( !token.Icmp( "camera_interpolated") ) { + cameraPosition = new idInterpolatedPosition(); + cameraPosition->parse( src ); + } + else if ( !token.Icmp( "camera_spline") ) { + cameraPosition = new idSplinePosition(); + cameraPosition->parse( src ); + } + else if ( !token.Icmp( "target_fixed") ) { + idFixedPosition *pos = new idFixedPosition(); + pos->parse( src ); + targetPositions.Append(pos); + } + else if ( !token.Icmp( "target_interpolated") ) { + idInterpolatedPosition *pos = new idInterpolatedPosition(); + pos->parse( src ); + targetPositions.Append(pos); + } + else if ( !token.Icmp( "target_spline") ) { + idSplinePosition *pos = new idSplinePosition(); + pos->parse( src ); + targetPositions.Append(pos); + } + else if ( !token.Icmp( "fov") ) { + fov.parse( src ); + } + else if ( !token.Icmp( "event") ) { + idCameraEvent *event = new idCameraEvent(); + event->parse( src ); + addEvent(event); + } + else { + src->Error( "unknown camera def: %s", token.c_str() ); + break; + } + } + + if ( !cameraPosition ) { + common->Printf( "no camera position specified\n" ); + // prevent a crash later on + cameraPosition = new idFixedPosition(); + } +} + +/* +================ +idCameraDef::load +================ +*/ +bool idCameraDef::load( const char *filename ) { + idParser *src; + + src = new idParser( filename, LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); + if ( !src->IsLoaded() ) { + common->Printf( "couldn't load %s\n", filename ); + delete src; + return false; + } + + clear(); + parse( src ); + + delete src; + + return true; +} + +/* +================ +idCameraDef::save +================ +*/ +void idCameraDef::save(const char *filename) { + idFile *f = fileSystem->OpenFileWrite( filename, "fs_devpath" ); + if ( f ) { + int i; + f->Printf( "cameraPathDef { \n" ); + f->Printf( "\ttime %f\n", baseTime ); + + cameraPosition->write( f, va("camera_%s",cameraPosition->typeStr()) ); + + for (i = 0; i < numTargets(); i++) { + targetPositions[i]->write( f, va("target_%s", targetPositions[i]->typeStr()) ); + } + + for (i = 0; i < events.Num(); i++) { + events[i]->write( f, "event" ); + } + + fov.write( f, "fov" ); + + f->Printf( "}\n" ); + } + fileSystem->CloseFile( f ); +} + +/* +================ +idCameraDef::sortEvents +================ +*/ +int idCameraDef::sortEvents(const void *p1, const void *p2) { + idCameraEvent *ev1 = (idCameraEvent*)(p1); + idCameraEvent *ev2 = (idCameraEvent*)(p2); + + if (ev1->getTime() > ev2->getTime()) { + return -1; + } + if (ev1->getTime() < ev2->getTime()) { + return 1; + } + return 0; +} + +/* +================ +idCameraDef::addEvent +================ +*/ +void idCameraDef::addEvent(idCameraEvent *event) { + events.Append(event); + //events.Sort(&sortEvents); + +} + +/* +================ +idCameraDef::addEvent +================ +*/ +void idCameraDef::addEvent(idCameraEvent::eventType t, const char *param, long time) { + addEvent(new idCameraEvent(t, param, time)); + buildCamera(); +} + +/* +================ +idCameraDef::newFromType +================ +*/ +idCameraPosition *idCameraDef::newFromType( idCameraPosition::positionType t ) { + switch (t) { + case idCameraPosition::FIXED : return new idFixedPosition(); + case idCameraPosition::INTERPOLATED : return new idInterpolatedPosition(); + case idCameraPosition::SPLINE : return new idSplinePosition(); + }; + return NULL; +} + + +/* +================================================================================= + +idCamaraEvent + +================================================================================= +*/ + +/* +================ +idCameraEvent::eventStr +================ +*/ +const char *idCameraEvent::eventStr[] = { + "NA", + "WAIT", + "TARGETWAIT", + "SPEED", + "TARGET", + "SNAPTARGET", + "FOV", + "CMD", + "TRIGGER", + "STOP", + "CAMERA", + "FADEOUT", + "FADEIN", + "FEATHER" +}; + +/* +================ +idCameraEvent::parse +================ +*/ +void idCameraEvent::parse( idParser *src ) { + idToken token; + idStr key; + + src->ExpectTokenString( "{" ); + + while ( 1 ) { + + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + + key = token; + src->ReadTokenOnLine( &token ); + if ( !key.Icmp( "type" ) ) { + type = static_cast(atoi(token.c_str())); + } + else if ( !key.Icmp( "param" ) ) { + paramStr = token; + } + else if ( !key.Icmp( "time" ) ) { + time = atoi(token.c_str()); + } + else { + src->Error( "unknown camera event key: %s", key.c_str() ); + break; + } + } +} + +/* +================ +idCameraEvent::write +================ +*/ +void idCameraEvent::write( idFile *f, const char *name) { + f->Printf( "\t%s {\n", name ); + f->Printf( "\t\ttype %d\n", static_cast(type) ); + f->Printf( "\t\tparam \"%s\"\n", paramStr.c_str() ); + f->Printf( "\t\ttime %d\n", time ); + f->Printf( "\t}\n" ); +} + +/* +================================================================================= + +idCamaraPosition + +================================================================================= +*/ + +/* +================ +idCameraPosition::positionStr +================ +*/ +const char *idCameraPosition::positionStr[] = { + "Fixed", + "Interpolated", + "Spline", +}; + +/* +================ +idCameraPosition::positionStr +================ +*/ +void idCameraPosition::clearVelocities() { + for (int i = 0; i < velocities.Num(); i++) { + delete velocities[i]; + velocities[i] = NULL; + } + velocities.Clear(); +} + +/* +================ +idCameraPosition::positionStr +================ +*/ +float idCameraPosition::getVelocity( long t ) { + long check = t - startTime; + for ( int i = 0; i < velocities.Num(); i++ ) { + if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) { + return velocities[i]->speed; + } + } + return baseVelocity; +} + +/* +================ +idCameraPosition::parseToken +================ +*/ +bool idCameraPosition::parseToken( const idStr &key, idParser *src ) { + idToken token; + + if ( !key.Icmp( "time" ) ) { + time = src->ParseInt(); + return true; + } + else if ( !key.Icmp( "type" ) ) { + type = static_cast ( src->ParseInt() ); + return true; + } + else if ( !key.Icmp( "velocity" ) ) { + long t = atol(token); + long d = src->ParseInt(); + float s = src->ParseFloat(); + addVelocity(t, d, s); + return true; + } + else if ( !key.Icmp( "baseVelocity" ) ) { + baseVelocity = src->ParseFloat(); + return true; + } + else if ( !key.Icmp( "name" ) ) { + src->ReadToken( &token ); + name = token; + return true; + } + else if ( !key.Icmp( "time" ) ) { + time = src->ParseInt(); + return true; + } + else { + src->Error( "unknown camera position key: %s", key.c_str() ); + return false; + } +} + +/* +================ +idCameraPosition::write +================ +*/ +void idCameraPosition::write( idFile *f, const char *p ) { + f->Printf( "\t\ttime %i\n", time ); + f->Printf( "\t\ttype %i\n", static_cast(type) ); + f->Printf( "\t\tname %s\n", name.c_str() ); + f->Printf( "\t\tbaseVelocity %f\n", baseVelocity ); + for (int i = 0; i < velocities.Num(); i++) { + f->Printf( "\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed ); + } +} + +/* +================================================================================= + +idInterpolatedPosition + +================================================================================= +*/ + +/* +================ +idInterpolatedPosition::getPoint +================ +*/ +idVec3 *idInterpolatedPosition::getPoint( int index ) { + assert( index >= 0 && index < 2 ); + if ( index == 0 ) { + return &startPos; + } + return &endPos; +} + +/* +================ +idInterpolatedPosition::addPoint +================ +*/ +void idInterpolatedPosition::addPoint( const float x, const float y, const float z ) { + if (first) { + startPos.Set(x, y, z); + first = false; + } else { + endPos.Set(x, y, z); + first = true; + } +} + +/* +================ +idInterpolatedPosition::addPoint +================ +*/ +void idInterpolatedPosition::addPoint( const idVec3 &v ) { + if (first) { + startPos = v; + first = false; + } + else { + endPos = v; + first = true; + } +} + +/* +================ +idInterpolatedPosition::draw +================ +*/ +void idInterpolatedPosition::draw( bool editMode ) { + glLabeledPoint(colorBlue, startPos, (editMode) ? 5 : 3, "Start interpolated"); + glLabeledPoint(colorBlue, endPos, (editMode) ? 5 : 3, "End interpolated"); + qglBegin(GL_LINES); + qglVertex3fv( startPos.ToFloatPtr() ); + qglVertex3fv( endPos.ToFloatPtr() ); + qglEnd(); +} + +/* +================ +idInterpolatedPosition::start +================ +*/ +void idInterpolatedPosition::start( long t ) { + idCameraPosition::start(t); + lastTime = startTime; + distSoFar = 0.0f; + idVec3 temp = startPos; + temp -= endPos; + calcVelocity(temp.Length()); +} + +/* +================ +idInterpolatedPosition::getPosition +================ +*/ +const idVec3 *idInterpolatedPosition::getPosition( long t ) { + static idVec3 interpolatedPos; + + if (t - startTime > 6000) { + int i = 0; + } + + float velocity = getVelocity(t); + float timePassed = t - lastTime; + lastTime = t; + + // convert to seconds + timePassed /= 1000; + + if (velocity != getBaseVelocity()) { + int i = 0; + } + + float distToTravel = timePassed * velocity; + + idVec3 temp = startPos; + temp -= endPos; + float distance = temp.Length(); + + distSoFar += distToTravel; + float percent = (float)(distSoFar) / distance; + + if ( percent > 1.0f ) { + percent = 1.0f; + } else if ( percent < 0.0f ) { + percent = 0.0f; + } + + // the following line does a straigt calc on percentage of time + // float percent = (float)(startTime + time - t) / time; + + idVec3 v1 = startPos; + idVec3 v2 = endPos; + v1 *= (1.0f - percent); + v2 *= percent; + v1 += v2; + interpolatedPos = v1; + return &interpolatedPos; +} + +/* +================ +idInterpolatedPosition::parse +================ +*/ +void idInterpolatedPosition::parse( idParser *src ) { + idToken token; + + src->ExpectTokenString( "{" ); + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "startPos" ) ) { + src->Parse1DMatrix( 3, startPos.ToFloatPtr() ); + } + else if ( !token.Icmp( "endPos" ) ) { + src->Parse1DMatrix( 3, endPos.ToFloatPtr() ); + } + else { + idCameraPosition::parseToken( token, src); + } + } +} + +/* +================ +idInterpolatedPosition::write +================ +*/ +void idInterpolatedPosition::write( idFile *f, const char *p ) { + f->Printf( "\t%s {\n", p ); + idCameraPosition::write( f, p ); + f->Printf( "\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z ); + f->Printf( "\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z ); + f->Printf( "\t}\n" ); +} + +/* +================================================================================= + +idCameraFOV + +================================================================================= +*/ + +/* +================ +idCameraFOV::GetFOV +================ +*/ +float idCameraFOV::GetFOV( long t ) { + if (time) { + assert(startTime); + float percent = (t - startTime) / length; + if ( percent < 0.0f ) { + percent = 0.0f; + } else if ( percent > 1.0f ) { + percent = 1.0f; + } + float temp = endFOV - startFOV; + temp *= percent; + fov = startFOV + temp; + } + return fov; +} + +/* +================ +idCameraFOV::reset +================ +*/ +void idCameraFOV::reset( float startfov, float endfov, int start, int len ) { + startFOV = startfov; + endFOV = endfov; + startTime = start; + length = len; +} + +/* +================ +idCameraFOV::parse +================ +*/ +void idCameraFOV::parse( idParser *src ) { + idToken token; + + src->ExpectTokenString( "{" ); + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "fov" ) ) { + fov = src->ParseFloat(); + } + else if ( !token.Icmp( "startFOV" ) ) { + startFOV = src->ParseFloat(); + } + else if ( !token.Icmp( "endFOV" ) ) { + endFOV = src->ParseFloat(); + } + else if ( !token.Icmp( "time" ) ) { + time = src->ParseInt(); + } + else { + src->Error( "unknown camera FOV key: %s", token.c_str() ); + break; + } + } +} + +/* +================ +idCameraFOV::write +================ +*/ +void idCameraFOV::write( idFile *f, const char *p ) { + f->Printf( "\t%s {\n", p ); + f->Printf( "\t\tfov %f\n", fov ); + f->Printf( "\t\tstartFOV %f\n", startFOV ); + f->Printf( "\t\tendFOV %f\n", endFOV ); + f->Printf( "\t\ttime %i\n", time ); + f->Printf( "\t}\n" ); +} + +/* +================================================================================= + +idFixedPosition + +================================================================================= +*/ + +/* +================ +idFixedPosition::parse +================ +*/ +void idFixedPosition::parse( idParser *src ) { + idToken token; + + src->ExpectTokenString( "{" ); + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + + if ( !token.Icmp( "pos" ) ) { + src->Parse1DMatrix( 3, pos.ToFloatPtr() ); + } + else { + idCameraPosition::parseToken( token, src ); + } + } +} + +/* +================ +idFixedPosition::write +================ +*/ +void idFixedPosition::write( idFile *f, const char *p ) { + f->Printf( "\t%s {\n", p ); + idCameraPosition::write( f, p ); + f->Printf( "\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z ); + f->Printf( "\t}\n" ); +} + +/* +================================================================================= + +idSplinePosition + +================================================================================= +*/ + +/* +================ +idSplinePosition::start +================ +*/ +void idSplinePosition::start( long t ) { + idCameraPosition::start( t ); + target.initPosition(t, time); + lastTime = startTime; + distSoFar = 0.0f; + calcVelocity(target.totalDistance()); +} + +/* +================ +idSplinePosition::parse +================ +*/ +void idSplinePosition::parse( idParser *src ) { + idToken token; + + src->ExpectTokenString( "{" ); + while ( 1 ) { + if ( !src->ExpectAnyToken( &token ) ) { + break; + } + if ( token == "}" ) { + break; + } + if ( !token.Icmp( "target" ) ) { + target.parse( src ); + } + else { + idCameraPosition::parseToken( token, src ); + } + } +} + +/* +================ +idSplinePosition::write +================ +*/ +void idSplinePosition::write( idFile *f, const char *p ) { + f->Printf( "\t%s {\n", p ); + idCameraPosition::write( f, p ); + target.write( f, "target" ); + f->Printf( "\t}\n" ); +} + +/* +================ +idSplinePosition::getPosition +================ +*/ +const idVec3 *idSplinePosition::getPosition(long t) { + static idVec3 interpolatedPos; + + float velocity = getVelocity(t); + float timePassed = t - lastTime; + lastTime = t; + + // convert to seconds + timePassed /= 1000; + + float distToTravel = timePassed * velocity; + + distSoFar += distToTravel; + double tempDistance = target.totalDistance(); + + double percent = (double)(distSoFar) / tempDistance; + + double targetDistance = percent * tempDistance; + tempDistance = 0; + + double lastDistance1,lastDistance2; + lastDistance1 = lastDistance2 = 0; + //FIXME: calc distances on spline build + idVec3 temp; + int count = target.numSegments(); + //for(int i = 2; i < count - 1; i++) { + int i; + for( i = 1; i < count; i++) { + temp = *target.getSegmentPoint(i-1); + temp -= *target.getSegmentPoint(i); + tempDistance += temp.Length(); + if (i & 1) { + lastDistance1 = tempDistance; + } else { + lastDistance2 = tempDistance; + } + if (tempDistance >= targetDistance) { + break; + } + } + + if (i >= count - 1) { + interpolatedPos = *target.getSegmentPoint(i-1); + } else { +#if 0 + double timeHi = target.getSegmentTime(i + 1); + double timeLo = target.getSegmentTime(i - 1); + double percent = (timeHi - t) / (timeHi - timeLo); + idVec3 v1 = *target.getSegmentPoint(i - 1); + idVec3 v2 = *target.getSegmentPoint(i + 1); + v2 *= (1.0f - percent); + v1 *= percent; + v2 += v1; + interpolatedPos = v2; +#else + if (lastDistance1 > lastDistance2) { + double d = lastDistance2; + lastDistance2 = lastDistance1; + lastDistance1 = d; + } + + idVec3 v1 = *target.getSegmentPoint(i - 1); + idVec3 v2 = *target.getSegmentPoint(i); + double percent = (lastDistance2 - targetDistance) / (lastDistance2 - lastDistance1); + v2 *= (1.0f - percent); + v1 *= percent; + v2 += v1; + interpolatedPos = v2; +#endif + } + return &interpolatedPos; + +} diff --git a/tools/radiant/splines.h b/tools/radiant/splines.h new file mode 100644 index 000000000..9ab5e1d7b --- /dev/null +++ b/tools/radiant/splines.h @@ -0,0 +1,390 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SPLINES_H__ +#define __SPLINES_H__ + +extern void glBox(idVec4 &color, idVec3 &point, float size); +extern void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label); + + +class idPointListInterface { +public: + idPointListInterface() { selectedPoints.Clear(); }; + ~idPointListInterface() {}; + + virtual int numPoints() { return 0; } + virtual void addPoint( const float x, const float y, const float z ) {} + virtual void addPoint( const idVec3 &v ) {} + virtual void removePoint( int index ) {} + virtual idVec3 * getPoint( int index ) { return NULL; } + + int numSelectedPoints() { return selectedPoints.Num(); } + idVec3 * getSelectedPoint( int index ); + int selectPointByRay( const idVec3 &origin, const idVec3 &direction, bool single ); + int isPointSelected( int index ); + int selectPoint( int index, bool single ); + void selectAll(); + void deselectAll(); + virtual void updateSelection( const idVec3 &move ); + void drawSelection(); + +protected: + idList selectedPoints; +}; + + +class idSplineList { + friend class idCamera; + +public: + + idSplineList() { clear(); } + idSplineList( const char *p ) { clear(); name = p; } + ~idSplineList() { clear(); } + + void clearControl(); + void clearSpline(); + void parse( idParser *src ); + void write( idFile *f, const char *name ); + + void clear(); + void initPosition( long startTime, long totalTime ); + const idVec3 * getPosition( long time ); + + void draw( bool editMode ); + void addToRenderer(); + + void setSelectedPoint( idVec3 *p ); + idVec3 * getSelectedPoint() { return selected; } + + void addPoint( const idVec3 &v ) { controlPoints.Append(new idVec3(v) ); dirty = true; } + void addPoint( float x, float y, float z ) { controlPoints.Append(new idVec3(x, y, z)); dirty = true; } + + void updateSelection(const idVec3 &move); + void startEdit() { editMode = true; } + void stopEdit() { editMode = false; } + void buildSpline(); + void setGranularity( float f ) { granularity = f; } + float getGranularity() { return granularity; } + + int numPoints() { return controlPoints.Num(); } + idVec3 * getPoint(int index) { assert(index >= 0 && index < controlPoints.Num()); return controlPoints[index]; } + idVec3 * getSegmentPoint(int index) { assert(index >= 0 && index < splinePoints.Num()); return splinePoints[index]; } + void setSegmentTime(int index, int time) { assert(index >= 0 && index < splinePoints.Num()); splineTime[index] = time; } + int getSegmentTime(int index) { assert(index >= 0 && index < splinePoints.Num()); return splineTime[index]; } + void addSegmentTime(int index, int time) { assert(index >= 0 && index < splinePoints.Num()); splineTime[index] += time; } + float totalDistance(); + + int getActiveSegment() { return activeSegment; } + void setActiveSegment( int i ) { /* assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num())); */ activeSegment = i; } + int numSegments() { return splinePoints.Num(); } + + void setColors(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active); + + const char * getName() { return name.c_str(); } + void setName( const char *p ) { name = p; } + + bool validTime(); + void setTime( long t ) { time = t; } + void setBaseTime( long t ) { baseTime = t; } + +protected: + idStr name; + float calcSpline(int step, float tension); + idList controlPoints; + idList splinePoints; + idList splineTime; + idVec3 * selected; + idVec4 pathColor, segmentColor, controlColor, activeColor; + float granularity; + bool editMode; + bool dirty; + int activeSegment; + long baseTime; + long time; +}; + +// time in milliseconds +// velocity where 1.0 equal rough walking speed +struct idVelocity { + idVelocity( long start, long duration, float s ) { startTime = start; time = duration; speed = s; } + long startTime; + long time; + float speed; +}; + +// can either be a look at or origin position for a camera +class idCameraPosition : public idPointListInterface { +public: + + idCameraPosition() { time = 0; name = "position"; } + idCameraPosition( const char *p ) { name = p; } + idCameraPosition( long t ) { time = t; } + virtual ~idCameraPosition() { clear(); } + + // this can be done with RTTI syntax but i like the derived classes setting a type + // makes serialization a bit easier to see + // + enum positionType { + FIXED = 0x00, + INTERPOLATED, + SPLINE, + POSITION_COUNT + }; + + virtual void clearVelocities(); + virtual void clear() { editMode = false; time = 5000; clearVelocities(); } + virtual void start( long t ) { startTime = t; } + long getTime() { return time; } + virtual void setTime(long t) { time = t; } + float getVelocity( long t ); + float getBaseVelocity() { return baseVelocity; } + void addVelocity( long start, long duration, float speed ) { velocities.Append(new idVelocity(start, duration, speed)); } + virtual const idVec3 *getPosition( long t ) { return NULL; } + virtual void draw( bool editMode ) {}; + virtual void parse( idParser *src ) {}; + virtual void write( idFile *f, const char *name); + virtual bool parseToken( const idStr &key, idParser *src ); + const char * getName() { return name.c_str(); } + void setName( const char *p ) { name = p; } + virtual void startEdit() { editMode = true; } + virtual void stopEdit() { editMode = false; } + virtual void draw() {}; + const char * typeStr() { return positionStr[static_cast(type)]; } + void calcVelocity( float distance ) { float secs = (float)time / 1000; baseVelocity = distance / secs; } + +protected: + static const char * positionStr[POSITION_COUNT]; + long startTime; + long time; + positionType type; + idStr name; + bool editMode; + idList velocities; + float baseVelocity; +}; + +class idFixedPosition : public idCameraPosition { +public: + + idFixedPosition() : idCameraPosition() { init(); } + idFixedPosition(idVec3 p) : idCameraPosition() { init(); pos = p; } + ~idFixedPosition() { } + + void init() { pos.Zero(); type = idCameraPosition::FIXED; } + + virtual void addPoint( const idVec3 &v ) { pos = v; } + virtual void addPoint( const float x, const float y, const float z ) { pos.Set(x, y, z); } + virtual const idVec3 *getPosition( long t ) { return &pos; } + void parse( idParser *src ); + void write( idFile *f, const char *name ); + virtual int numPoints() { return 1; } + virtual idVec3 * getPoint( int index ) { assert( index == 0 ); return &pos; } + virtual void draw( bool editMode ) { glLabeledPoint(colorBlue, pos, (editMode) ? 5 : 3, "Fixed point"); } + +protected: + idVec3 pos; +}; + +class idInterpolatedPosition : public idCameraPosition { +public: + idInterpolatedPosition() : idCameraPosition() { init(); } + idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition(time) { init(); startPos = start; endPos = end; } + ~idInterpolatedPosition() { } + + void init() { type = idCameraPosition::INTERPOLATED; first = true; startPos.Zero(); endPos.Zero(); } + + virtual const idVec3 *getPosition(long t); + void parse( idParser *src ); + void write( idFile *f, const char *name ); + virtual int numPoints() { return 2; } + virtual idVec3 * getPoint( int index ); + virtual void addPoint( const float x, const float y, const float z ); + virtual void addPoint( const idVec3 &v ); + virtual void draw( bool editMode ); + virtual void start( long t ); + +protected: + bool first; + idVec3 startPos; + idVec3 endPos; + long lastTime; + float distSoFar; +}; + +class idSplinePosition : public idCameraPosition { +public: + + idSplinePosition() : idCameraPosition() { init(); } + idSplinePosition( long time ) : idCameraPosition( time ) { init(); } + ~idSplinePosition() { } + + void init() { type = idCameraPosition::SPLINE; } + virtual void start( long t ); + virtual const idVec3 *getPosition( long t ); + void addControlPoint( idVec3 &v ) { target.addPoint(v); } + void parse( idParser *src ); + void write( idFile *f, const char *name ); + virtual int numPoints() { return target.numPoints(); } + virtual idVec3 * getPoint( int index ) { return target.getPoint(index); } + virtual void addPoint( const idVec3 &v ) { target.addPoint( v ); } + virtual void draw( bool editMode ) { target.draw( editMode ); } + virtual void updateSelection( const idVec3 &move ) { idCameraPosition::updateSelection(move); target.buildSpline(); } + +protected: + idSplineList target; + long lastTime; + float distSoFar; +}; + +class idCameraFOV { +public: + idCameraFOV() { time = 0; fov = 90; } + idCameraFOV( int v ) { time = 0; fov = v; } + idCameraFOV( int s, int e, long t ) { startFOV = s; endFOV = e; time = t; } + ~idCameraFOV() { } + + void SetFOV( float f ) { fov = f; } + float GetFOV( long t ); + void start( long t ) { startTime = t; } + void reset( float startfov, float endfov, int start, int len ); + void parse( idParser *src ); + void write( idFile *f, const char *name ); + +protected: + float fov; + float startFOV; + float endFOV; + int startTime; + int time; + int length; +}; + +class idCameraEvent { +public: + enum eventType { + EVENT_NA = 0x00, + EVENT_WAIT, + EVENT_TARGETWAIT, + EVENT_SPEED, + EVENT_TARGET, + EVENT_SNAPTARGET, + EVENT_FOV, + EVENT_CMD, + EVENT_TRIGGER, + EVENT_STOP, + EVENT_CAMERA, + EVENT_FADEOUT, + EVENT_FADEIN, + EVENT_FEATHER, + EVENT_COUNT + }; + + idCameraEvent() { paramStr = ""; type = EVENT_NA; time = 0; } + idCameraEvent( eventType t, const char *param, long n ) { type = t; paramStr = param; time = n; } + ~idCameraEvent() { } + + eventType getType() { return type; } + const char * typeStr() { return eventStr[static_cast(type)]; } + const char * getParam() { return paramStr.c_str(); } + long getTime() { return time; } + void setTime(long n) { time = n; } + void parse( idParser *src ); + void write( idFile *f, const char *name ); + void setTriggered( bool b ) { triggered = b; } + bool getTriggered() { return triggered; } + + static const char * eventStr[EVENT_COUNT]; + +protected: + eventType type; + idStr paramStr; + long time; + bool triggered; + +}; + +class idCameraDef { +public: + idCameraDef() { cameraPosition = NULL; clear(); } + ~idCameraDef() { clear(); } + + void clear(); + idCameraPosition * startNewCamera(idCameraPosition::positionType type); + void addEvent( idCameraEvent::eventType t, const char *param, long time ); + void addEvent( idCameraEvent *event ); + static int sortEvents( const void *p1, const void *p2 ); + int numEvents() { return events.Num(); } + idCameraEvent * getEvent(int index) { assert(index >= 0 && index < events.Num()); return events[index]; } + void parse( idParser *src ); + bool load( const char *filename ); + void save( const char *filename ); + void buildCamera(); + + void addTarget( const char *name, idCameraPosition::positionType type ); + + idCameraPosition * getActiveTarget(); + idCameraPosition * getActiveTarget( int index ); + int numTargets() { return targetPositions.Num(); } + void setActiveTargetByName(const char *name); + void setActiveTarget( int index ); + void setRunning( bool b ) { cameraRunning = b; } + void setBaseTime( float f ) { baseTime = f; } + float getBaseTime() { return baseTime; } + float getTotalTime() { return totalTime; } + void startCamera( long t ); + void stopCamera() { cameraRunning = true; } + void getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fv); + bool getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv); + void draw( bool editMode ); + int numPoints(); + const idVec3 * getPoint( int index ); + void stopEdit(); + void startEdit( bool camera ); + bool waitEvent( int index ); + const char * getName() { return name.c_str(); } + void setName( const char *p ) { name = p; } + idCameraPosition * getPositionObj(); + + static idCameraPosition *newFromType( idCameraPosition::positionType t ); + +protected: + idStr name; + int currentCameraPosition; + idVec3 lastDirection; + bool cameraRunning; + idCameraPosition * cameraPosition; + idList targetPositions; + idList events; + idCameraFOV fov; + int activeTarget; + float totalTime; + float baseTime; + long startTime; + + bool cameraEdit; + bool editMode; +}; + +extern bool g_splineMode; + +extern idCameraDef *g_splineList; + +#endif /* !__SPLINES_H__ */ diff --git a/tools/script/DialogScriptEditor.cpp b/tools/script/DialogScriptEditor.cpp new file mode 100644 index 000000000..f66aa3631 --- /dev/null +++ b/tools/script/DialogScriptEditor.cpp @@ -0,0 +1,747 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/Common_resource.h" +#include "../../sys/win32/rc/ScriptEditor_resource.h" + +#include "../comafx/DialogGoToLine.h" +#include "DialogScriptEditor.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + + +typedef struct scriptEventInfo_s { + idStr name; + idStr parms; + idStr help; +} scriptEventInfo_t; + +static idList scriptEvents; + +static DialogScriptEditor *g_ScriptDialog = NULL; + +// DialogScriptEditor dialog + +static UINT FindDialogMessage = ::RegisterWindowMessage( FINDMSGSTRING ); + +toolTip_t DialogScriptEditor::toolTips[] = { + { IDOK, "save" }, + { IDCANCEL, "cancel" }, + { 0, NULL } +}; + + +IMPLEMENT_DYNAMIC(DialogScriptEditor, CDialog) + +/* +================ +DialogScriptEditor::DialogScriptEditor +================ +*/ +DialogScriptEditor::DialogScriptEditor( CWnd* pParent /*=NULL*/ ) + : CDialog(DialogScriptEditor::IDD, pParent) + , findDlg(NULL) + , matchCase(false) + , matchWholeWords(false) + , firstLine(0) +{ +} + +/* +================ +DialogScriptEditor::~DialogScriptEditor +================ +*/ +DialogScriptEditor::~DialogScriptEditor() { +} + +/* +================ +DialogScriptEditor::DoDataExchange +================ +*/ +void DialogScriptEditor::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DialogScriptEditor) + DDX_Control(pDX, IDC_SCRIPTEDITOR_EDIT_TEXT, scriptEdit); + DDX_Control(pDX, IDOK, okButton); + DDX_Control(pDX, IDCANCEL, cancelButton); + //}}AFX_DATA_MAP +} + +/* +================ +DialogScriptEditor::PreTranslateMessage +================ +*/ +BOOL DialogScriptEditor::PreTranslateMessage( MSG* pMsg ) { + if ( WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST ) { + if ( m_hAccel && ::TranslateAccelerator( m_hWnd, m_hAccel, pMsg ) ) { + return TRUE; + } + } + return CWnd::PreTranslateMessage(pMsg); +} + +/* +================ +DialogScriptEditor::UpdateStatusBar +================ +*/ +void DialogScriptEditor::UpdateStatusBar( void ) { + int line, column, character; + + scriptEdit.GetCursorPos( line, column, character ); + statusBar.SetWindowText( va( "Line: %d, Column: %d, Character: %d", line, column, character ) ); +} + +/* +================ +DialogScriptEditor::InitScriptEvents +================ +*/ +void DialogScriptEditor::InitScriptEvents( void ) { + int index; + idParser src; + idToken token; + idStr whiteSpace; + scriptEventInfo_t info; + + if ( !src.LoadFile( "script/doom_events.script" ) ) { + return; + } + + scriptEvents.Clear(); + + while( src.ReadToken( &token ) ) { + if ( token == "scriptEvent" ) { + + src.GetLastWhiteSpace( whiteSpace ); + index = whiteSpace.Find( "//" ); + if ( index != -1 ) { + info.help = whiteSpace.Right( whiteSpace.Length() - index ); + info.help.Replace( "\r", "" ); + info.help.Replace( "\n", "\r\n" ); + } else { + info.help = ""; + } + + src.ExpectTokenType( TT_NAME, 0, &token ); + + info.parms = token; + + src.ExpectTokenType( TT_NAME, 0, &token ); + + info.name = token; + + src.ExpectTokenString( "(" ); + + info.parms += " " + info.name + "("; + while( src.ReadToken( &token ) && token != ";" ) { + info.parms.Append( " " + token ); + } + + scriptEvents.Append( info ); + } + } +} + +/* +================ +GetScriptEvents +================ +*/ +bool GetScriptEvents( const char *objectName, CListBox &listBox ) { + for ( int i = 0; i < scriptEvents.Num(); i++ ) { + listBox.AddString( scriptEvents[i].name ); + } + return true; +} + +/* +================ +GetFunctionParms +================ +*/ +bool GetFunctionParms( const char *funcName, CString &parmString ) { + for ( int i = 0; i < scriptEvents.Num(); i++ ) { + if ( scriptEvents[i].name.Cmp( funcName ) == 0 ) { + parmString = scriptEvents[i].parms; + return true; + } + } + return false; +} + +/* +================ +GetToolTip +================ +*/ +bool GetToolTip( const char *name, CString &string ) { + for ( int i = 0; i < scriptEvents.Num(); i++ ) { + if ( scriptEvents[i].name.Cmp( name ) == 0 ) { + string = scriptEvents[i].help + scriptEvents[i].parms; + return true; + } + } + return false; +} + +/* +================ +DialogScriptEditor::OpenFile +================ +*/ +void DialogScriptEditor::OpenFile( const char *fileName ) { + int numLines = 0; + int numCharsPerLine = 0; + int maxCharsPerLine = 0; + idStr scriptText, extension; + CRect rect; + void *buffer; + + scriptEdit.Init(); + scriptEdit.AllowPathNames( false ); + + idStr( fileName ).ExtractFileExtension( extension ); + + if ( extension.Icmp( "script" ) == 0 ) { + InitScriptEvents(); + scriptEdit.SetCaseSensitive( true ); + scriptEdit.LoadKeyWordsFromFile( "editors/script.def" ); + scriptEdit.SetObjectMemberCallback( GetScriptEvents ); + scriptEdit.SetFunctionParmCallback( GetFunctionParms ); + scriptEdit.SetToolTipCallback( GetToolTip ); + } else if ( extension.Icmp( "gui" ) == 0 ) { + scriptEdit.SetStringColor( SRE_COLOR_DARK_CYAN, SRE_COLOR_LIGHT_BROWN ); + scriptEdit.LoadKeyWordsFromFile( "editors/gui.def" ); + } + + if ( fileSystem->ReadFile( fileName, &buffer ) == -1 ) { + return; + } + scriptText = (char *) buffer; + fileSystem->FreeFile( buffer ); + + this->fileName = fileName; + + // clean up new-line crapola + scriptText.Replace( "\r", "" ); + scriptText.Replace( "\n", "\r" ); + scriptText.Replace( "\v", "\r" ); + + scriptEdit.SetText( scriptText ); + + for( const char *ptr = scriptText.c_str(); *ptr; ptr++ ) { + if ( *ptr == '\r' ) { + if ( numCharsPerLine > maxCharsPerLine ) { + maxCharsPerLine = numCharsPerLine; + } + numCharsPerLine = 0; + numLines++; + } else if ( *ptr == '\t' ) { + numCharsPerLine += TAB_SIZE; + } else { + numCharsPerLine++; + } + } + + SetWindowText( va( "Script Editor (%s)", fileName ) ); + + rect.left = initialRect.left; + rect.right = rect.left + maxCharsPerLine * FONT_WIDTH + 32; + rect.top = initialRect.top; + rect.bottom = rect.top + numLines * (FONT_HEIGHT+8) + 24 + 56; + if ( rect.right < initialRect.right ) { + rect.right = initialRect.right; + } else if ( rect.right - rect.left > 1024 ) { + rect.right = rect.left + 1024; + } + if ( rect.bottom < initialRect.bottom ) { + rect.bottom = initialRect.bottom; + } else if ( rect.bottom - rect.top > 768 ) { + rect.bottom = rect.top + 768; + } + MoveWindow( rect ); + + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); + + scriptEdit.SetFocus(); +} + +/* +================ +DialogScriptEditor::OnInitDialog +================ +*/ +BOOL DialogScriptEditor::OnInitDialog() { + + com_editors |= EDITOR_SCRIPT; + + CDialog::OnInitDialog(); + + // load accelerator table + m_hAccel = ::LoadAccelerators( AfxGetResourceHandle(), MAKEINTRESOURCE( IDR_ACCELERATOR_SCRIPTEDITOR ) ); + + // create status bar + statusBar.CreateEx( SBARS_SIZEGRIP, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, initialRect, this, AFX_IDW_STATUS_BAR ); + + scriptEdit.LimitText( 1024 * 1024 ); + + GetClientRect( initialRect ); + + SetWindowText( "Script Editor" ); + + EnableToolTips( TRUE ); + + okButton.EnableWindow( FALSE ); + + UpdateStatusBar(); + + return FALSE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +BEGIN_MESSAGE_MAP(DialogScriptEditor, CDialog) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) + ON_WM_DESTROY() + ON_WM_ACTIVATE() + ON_WM_MOVE() + ON_WM_SIZE() + ON_WM_SIZING() + ON_WM_SETFOCUS() + ON_COMMAND(ID_EDIT_FIND, OnEditFind) + ON_COMMAND(ID_EDIT_REPLACE, OnEditReplace) + ON_COMMAND(ID_SCRIPTEDITOR_FIND_NEXT, OnEditFindNext) + ON_COMMAND(ID_SCRIPTEDITOR_GOTOLINE, OnEditGoToLine) + ON_REGISTERED_MESSAGE(FindDialogMessage, OnFindDialogMessage) + ON_NOTIFY(EN_CHANGE, IDC_SCRIPTEDITOR_EDIT_TEXT, OnEnChangeEdit) + ON_NOTIFY(EN_MSGFILTER, IDC_SCRIPTEDITOR_EDIT_TEXT, OnEnInputEdit) + ON_BN_CLICKED(IDOK, OnBnClickedOk) + ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) +END_MESSAGE_MAP() + +/* +================ +ScriptEditorInit +================ +*/ +void ScriptEditorInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the script editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_ScriptDialog == NULL ) { + InitAfx(); + g_ScriptDialog = new DialogScriptEditor(); + } + + if ( g_ScriptDialog->GetSafeHwnd() == NULL) { + g_ScriptDialog->Create( IDD_DIALOG_SCRIPTEDITOR ); +/* + // FIXME: restore position + CRect rct; + g_ScriptDialog->SetWindowPos( NULL, rct.left, rct.top, 0, 0, SWP_NOSIZE ); +*/ + } + + idKeyInput::ClearStates(); + + g_ScriptDialog->ShowWindow( SW_SHOW ); + g_ScriptDialog->SetFocus(); + + if ( spawnArgs ) { + } +} + +/* +================ +ScriptEditorRun +================ +*/ +void ScriptEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +/* +================ +ScriptEditorShutdown +================ +*/ +void ScriptEditorShutdown( void ) { + delete g_ScriptDialog; + g_ScriptDialog = NULL; + scriptEvents.Clear(); +} + + +// DialogScriptEditor message handlers + +/* +================ +DialogScriptEditor::OnActivate +================ +*/ +void DialogScriptEditor::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); +} + +/* +================ +DialogScriptEditor::OnToolTipNotify +================ +*/ +BOOL DialogScriptEditor::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) { + return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult ); +} + +/* +================ +DialogScriptEditor::OnSetFocus +================ +*/ +void DialogScriptEditor::OnSetFocus( CWnd *pOldWnd ) { + CDialog::OnSetFocus( pOldWnd ); +} + +/* +================ +DialogScriptEditor::OnDestroy +================ +*/ +void DialogScriptEditor::OnDestroy() { + return CDialog::OnDestroy(); +} + +/* +================ +DialogScriptEditor::OnMove +================ +*/ +void DialogScriptEditor::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +/* +================ +DialogScriptEditor::OnSize +================ +*/ +#define BORDER_SIZE 0 +#define BUTTON_SPACE 4 +#define TOOLBAR_HEIGHT 24 + +void DialogScriptEditor::OnSize( UINT nType, int cx, int cy ) { + CRect clientRect, rect; + + LockWindowUpdate(); + + CDialog::OnSize( nType, cx, cy ); + + GetClientRect( clientRect ); + + if ( scriptEdit.GetSafeHwnd() ) { + rect.left = BORDER_SIZE; + rect.top = BORDER_SIZE; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - 56; + scriptEdit.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( okButton.GetSafeHwnd() ) { + okButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - 2 * width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = clientRect.Width() - BORDER_SIZE - BUTTON_SPACE - width; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + okButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( cancelButton.GetSafeHwnd() ) { + cancelButton.GetClientRect( rect ); + int width = rect.Width(); + int height = rect.Height(); + rect.left = clientRect.Width() - BORDER_SIZE - width; + rect.top = clientRect.Height() - TOOLBAR_HEIGHT - height; + rect.right = clientRect.Width() - BORDER_SIZE; + rect.bottom = clientRect.Height() - TOOLBAR_HEIGHT; + cancelButton.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + if ( statusBar.GetSafeHwnd() ) { + rect.left = clientRect.Width() - 2; + rect.top = clientRect.Height() - 2; + rect.right = clientRect.Width() - 2; + rect.bottom = clientRect.Height() - 2; + statusBar.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() ); + } + + UnlockWindowUpdate(); +} + +/* +================ +DialogScriptEditor::OnSizing +================ +*/ +void DialogScriptEditor::OnSizing( UINT nSide, LPRECT lpRect ) { + /* + 1 = left + 2 = right + 3 = top + 4 = left - top + 5 = right - top + 6 = bottom + 7 = left - bottom + 8 = right - bottom + */ + + CDialog::OnSizing( nSide, lpRect ); + + if ( ( nSide - 1 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->left = lpRect->right - initialRect.Width(); + } + } else if ( ( nSide - 2 ) % 3 == 0 ) { + if ( lpRect->right - lpRect->left < initialRect.Width() ) { + lpRect->right = lpRect->left + initialRect.Width(); + } + } + if ( nSide >= 3 && nSide <= 5 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->top = lpRect->bottom - initialRect.Height(); + } + } else if ( nSide >= 6 && nSide <= 9 ) { + if ( lpRect->bottom - lpRect->top < initialRect.Height() ) { + lpRect->bottom = lpRect->top + initialRect.Height(); + } + } +} + +/* +================ +DialogScriptEditor::OnEditGoToLine +================ +*/ +void DialogScriptEditor::OnEditGoToLine() { + DialogGoToLine goToLineDlg; + + goToLineDlg.SetRange( firstLine, firstLine + scriptEdit.GetLineCount() - 1 ); + if ( goToLineDlg.DoModal() != IDOK ) { + return; + } + scriptEdit.GoToLine( goToLineDlg.GetLine() - firstLine ); +} + +/* +================ +DialogScriptEditor::OnEditFind +================ +*/ +void DialogScriptEditor::OnEditFind() { + + CString selText = scriptEdit.GetSelText(); + if ( selText.GetLength() ) { + findStr = selText; + } + + // create find/replace dialog + if ( !findDlg ) { + findDlg = new CFindReplaceDialog(); // Must be created on the heap + findDlg->Create( TRUE, findStr, "", FR_DOWN, this ); + } +} + +/* +================ +DialogScriptEditor::OnEditFindNext +================ +*/ +void DialogScriptEditor::OnEditFindNext() { + if ( scriptEdit.FindNext( findStr, matchCase, matchWholeWords, searchForward ) ) { + scriptEdit.SetFocus(); + } else { + AfxMessageBox( "The specified text was not found.", MB_OK | MB_ICONINFORMATION, 0 ); + } +} + +/* +================ +DialogScriptEditor::OnEditReplace +================ +*/ +void DialogScriptEditor::OnEditReplace() { + + CString selText = scriptEdit.GetSelText(); + if ( selText.GetLength() ) { + findStr = selText; + } + + // create find/replace dialog + if ( !findDlg ) { + findDlg = new CFindReplaceDialog(); // Must be created on the heap + findDlg->Create( FALSE, findStr, "", FR_DOWN, this ); + } +} + +/* +================ +DialogScriptEditor::OnFindDialogMessage +================ +*/ +LRESULT DialogScriptEditor::OnFindDialogMessage( WPARAM wParam, LPARAM lParam ) { + if ( findDlg == NULL ) { + return 0; + } + + if ( findDlg->IsTerminating() ) { + findDlg = NULL; + return 0; + } + + if( findDlg->FindNext() ) { + findStr = findDlg->GetFindString(); + matchCase = findDlg->MatchCase() != FALSE; + matchWholeWords = findDlg->MatchWholeWord() != FALSE; + searchForward = findDlg->SearchDown() != FALSE; + + OnEditFindNext(); + } + + if ( findDlg->ReplaceCurrent() ) { + long selStart, selEnd; + + replaceStr = findDlg->GetReplaceString(); + + scriptEdit.GetSel( selStart, selEnd ); + if ( selEnd > selStart ) { + scriptEdit.ReplaceSel( replaceStr, TRUE ); + } + } + + if ( findDlg->ReplaceAll() ) { + replaceStr = findDlg->GetReplaceString(); + findStr = findDlg->GetFindString(); + matchCase = findDlg->MatchCase() != FALSE; + matchWholeWords = findDlg->MatchWholeWord() != FALSE; + + int numReplaces = scriptEdit.ReplaceAll( findStr, replaceStr, matchCase, matchWholeWords ); + if ( numReplaces == 0 ) { + AfxMessageBox( "The specified text was not found.", MB_OK | MB_ICONINFORMATION, 0 ); + } else { + AfxMessageBox( va( "Replaced %d occurances.", numReplaces ), MB_OK | MB_ICONINFORMATION, 0 ); + } + } + + return 0; +} + +/* +================ +DialogScriptEditor::OnEnChangeEdit +================ +*/ +void DialogScriptEditor::OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + okButton.EnableWindow( TRUE ); +} + +/* +================ +DialogScriptEditor::OnEnInputEdit +================ +*/ +void DialogScriptEditor::OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ) { + MSGFILTER *msgFilter = (MSGFILTER *)pNMHDR; + + if ( msgFilter->msg != 512 && msgFilter->msg != 33 ) { + UpdateStatusBar(); + } + + *pResult = 0; +} + +/* +================ +DialogScriptEditor::OnBnClickedOk +================ +*/ +void DialogScriptEditor::OnBnClickedOk() { + idStr scriptText; + + common->Printf( "Writing \'%s\'...\n", fileName.c_str() ); + + scriptEdit.GetText( scriptText ); + + // clean up new-line crapola + scriptText.Replace( "\n", "" ); + scriptText.Replace( "\r", "\r\n" ); + scriptText.Replace( "\v", "\r\n" ); + + if ( fileSystem->WriteFile( fileName, scriptText, scriptText.Length(), "fs_devpath" ) == -1 ) { + MessageBox( va( "Couldn't save: %s", fileName.c_str() ), va( "Error saving: %s", fileName.c_str() ), MB_OK | MB_ICONERROR ); + return; + } + + okButton.EnableWindow( FALSE ); +} + +/* +================ +DialogScriptEditor::OnBnClickedCancel +================ +*/ +void DialogScriptEditor::OnBnClickedCancel() { + if ( okButton.IsWindowEnabled() ) { + if ( MessageBox( "Cancel changes?", "Cancel", MB_YESNO | MB_ICONQUESTION ) != IDYES ) { + return; + } + } + OnCancel(); +} diff --git a/tools/script/DialogScriptEditor.h b/tools/script/DialogScriptEditor.h new file mode 100644 index 000000000..a0226d771 --- /dev/null +++ b/tools/script/DialogScriptEditor.h @@ -0,0 +1,95 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGSCRIPTEDITOR_H__ +#define __DIALOGSCRIPTEDITOR_H__ + +#pragma once + +#include "../comafx/CSyntaxRichEditCtrl.h" + + +// DialogScriptEditor dialog + +class DialogScriptEditor : public CDialog { + + DECLARE_DYNAMIC(DialogScriptEditor) + +public: + DialogScriptEditor( CWnd* pParent = NULL ); // standard constructor + virtual ~DialogScriptEditor(); + + void OpenFile( const char *fileName ); + + //{{AFX_VIRTUAL(DialogScriptEditor) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support + virtual BOOL PreTranslateMessage( MSG* pMsg ); + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(DialogScriptEditor) + afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnSetFocus( CWnd *pOldWnd ); + afx_msg void OnDestroy(); + afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized ); + afx_msg void OnMove( int x, int y ); + afx_msg void OnSize( UINT nType, int cx, int cy ); + afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); + afx_msg void OnEditGoToLine(); + afx_msg void OnEditFind(); + afx_msg void OnEditFindNext(); + afx_msg void OnEditReplace(); + afx_msg LRESULT OnFindDialogMessage( WPARAM wParam, LPARAM lParam ); + afx_msg void OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult ); + afx_msg void OnBnClickedOk(); + afx_msg void OnBnClickedCancel(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(DialogScriptEditor) + enum { IDD = IDD_DIALOG_SCRIPTEDITOR }; + CStatusBarCtrl statusBar; + CSyntaxRichEditCtrl scriptEdit; + CButton okButton; + CButton cancelButton; + //}}AFX_DATA + + static toolTip_t toolTips[]; + + HACCEL m_hAccel; + CRect initialRect; + CFindReplaceDialog *findDlg; + CString findStr; + CString replaceStr; + bool matchCase; + bool matchWholeWords; + bool searchForward; + idStr fileName; + int firstLine; + +private: + void InitScriptEvents( void ); + void UpdateStatusBar( void ); +}; + +#endif /* !__DIALOGSCRIPTEDITOR_H__ */ diff --git a/tools/sound/DialogSound.cpp b/tools/sound/DialogSound.cpp new file mode 100644 index 000000000..87e2a317a --- /dev/null +++ b/tools/sound/DialogSound.cpp @@ -0,0 +1,965 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../game/game.h" +#include "../../sys/win32/win_local.h" +#include "../../sys/win32/rc/common_resource.h" +#include "../../sys/win32/rc/SoundEditor_resource.h" +#include "../comafx/DialogName.h" +#include "../../sys/win32/rc/DeclEditor_resource.h" +#include "../decl/DialogDeclEditor.h" + +#include "DialogSound.h" +#include "DialogSoundGroup.h" + +#ifdef ID_DEBUG_MEMORY +#undef new +#undef DEBUG_NEW +#define DEBUG_NEW new +#endif + +extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent); + + +///////////////////////////////////////////////////////////////////////////// +// CDialogSound dialog +CDialogSound *g_SoundDialog = NULL; + + +CDialogSound::CDialogSound(CWnd* pParent /*=NULL*/) + : CDialog(CDialogSound::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogSound) + strName = _T(""); + fVolume = 0.0f; + fMax = 0.0f; + fMin = 0.0f; + strShader = _T(""); + bPlay = TRUE; + bTriggered = FALSE; + bOmni = FALSE; + strGroup = _T(""); + bGroupOnly = FALSE; + bOcclusion = FALSE; + leadThrough = 0.0f; + plain = FALSE; + inUseTree = NULL; + random = 0.0f; + wait = 0.0f; + shakes = 0.0f; + looping = TRUE; + unclamped = FALSE; + //}}AFX_DATA_INIT +} + + +void CDialogSound::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogSound) + DDX_Control(pDX, IDC_COMBO_SPEAKERS, comboSpeakers); + DDX_Control(pDX, IDC_COMBO_GROUPS, comboGroups); + DDX_Control(pDX, IDC_EDIT_VOLUME, editVolume); + DDX_Control(pDX, IDC_TREE_SOUNDS, treeSounds); + DDX_Text(pDX, IDC_EDIT_SOUND_NAME, strName); + DDX_Text(pDX, IDC_EDIT_VOLUME, fVolume); + DDX_Text(pDX, IDC_EDIT_RANDOM, random); + DDX_Text(pDX, IDC_EDIT_WAIT, wait); + DDX_Text(pDX, IDC_EDIT_MAXDIST, fMax); + DDX_Text(pDX, IDC_EDIT_MINDIST, fMin); + DDX_Text(pDX, IDC_EDIT_SHADER, strShader); + DDX_Check(pDX, IDC_CHECK_PLAY, bPlay); + DDX_Check(pDX, IDC_CHECKP_TRIGGERED, bTriggered); + DDX_Check(pDX, IDC_CHECK_OMNI, bOmni); + DDX_Text(pDX, IDC_EDIT_GROUP, strGroup); + DDX_Check(pDX, IDC_CHECK_GROUPONLY, bGroupOnly); + DDX_Check(pDX, IDC_CHECK_OCCLUSION, bOcclusion); + DDX_Text(pDX, IDC_EDIT_LEADTHROUGH, leadThrough); + DDX_Check(pDX, IDC_CHECK_PLAIN, plain); + DDX_Check(pDX, IDC_CHECK_LOOPING, looping); + DDX_Check(pDX, IDC_CHECK_UNCLAMPED, unclamped); + DDX_Text(pDX, IDC_EDIT_SHAKES, shakes); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogSound, CDialog) + //{{AFX_MSG_MAP(CDialogSound) + ON_BN_CLICKED(IDC_BTN_SAVEMAP, OnBtnSavemap) + ON_BN_CLICKED(IDC_BTN_SWITCHTOGAME, OnBtnSwitchtogame) + ON_BN_CLICKED(IDC_BTN_APPLY_SOUND, OnBtnApply) + ON_EN_CHANGE(IDC_EDIT_VOLUME, OnChangeEditVolume) + ON_BN_CLICKED(IDC_BTN_REFRESH, OnBtnRefresh) + ON_BN_CLICKED(IDC_BTN_PLAYSOUND, OnBtnPlaysound) + ON_NOTIFY(NM_DBLCLK, IDC_TREE_SOUNDS, OnDblclkTreeSounds) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_SOUNDS, OnSelchangedTreeSounds) + ON_BN_CLICKED(IDC_CHECK_PLAY, OnCheckPlay) + ON_BN_CLICKED(IDC_BTN_EDIT_SOUND, OnBtnEdit) + ON_BN_CLICKED(IDC_BTN_DROP, OnBtnDrop) + ON_BN_CLICKED(IDC_BTN_GROUP, OnBtnGroup) + ON_BN_CLICKED(IDC_BTN_SAVEMAPAS, OnBtnSavemapas) + ON_BN_CLICKED(IDC_BTN_YUP, OnBtnYup) + ON_BN_CLICKED(IDC_BTN_YDN, OnBtnYdn) + ON_BN_CLICKED(IDC_BTN_XDN, OnBtnXdn) + ON_BN_CLICKED(IDC_BTN_XUP, OnBtnXup) + ON_BN_CLICKED(IDC_BTN_ZUP, OnBtnZup) + ON_BN_CLICKED(IDC_BTN_ZDN, OnBtnZdn) + ON_BN_CLICKED(IDC_BTN_TRIGGER, OnBtnTrigger) + ON_WM_HSCROLL() + ON_BN_CLICKED(IDC_CHECK_GROUPONLY, OnCheckGrouponly) + ON_CBN_SELCHANGE(IDC_COMBO_GROUPS, OnSelchangeComboGroups) + ON_CBN_SELCHANGE(IDC_COMBO_SPEAKERS, OnSelchangeComboSpeakers) + ON_BN_CLICKED(IDC_BTN_DOWN, OnBtnDown) + ON_BN_CLICKED(IDC_BTN_UP, OnBtnUp) + ON_BN_CLICKED(IDC_BTN_REFRESHSPEAKERS, OnBtnRefreshspeakers) + ON_BN_CLICKED(IDC_BTN_REFRESHWAVE, OnBtnRefreshwave) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogSound message handlers + +void SoundEditorInit( const idDict *spawnArgs ) { + + if ( renderSystem->IsFullScreen() ) { + common->Printf( "Cannot run the sound editor in fullscreen mode.\n" + "Set r_fullscreen to 0 and vid_restart.\n" ); + return; + } + + if ( g_SoundDialog == NULL ) { + InitAfx(); + g_SoundDialog = new CDialogSound(); + } + + if ( g_SoundDialog->GetSafeHwnd() == NULL ) { + g_SoundDialog->Create(IDD_DIALOG_SOUND); +/* + // FIXME: restore position + CRect rct; + g_SoundDialog->SetWindowPos( NULL, rct.left, rct.top, 0,0, SWP_NOSIZE ); +*/ + } + + idKeyInput::ClearStates(); + + g_SoundDialog->ShowWindow( SW_SHOW ); + g_SoundDialog->SetFocus(); + + if ( spawnArgs ) { + const char *name = spawnArgs->GetString( "name" ); + const idDict *dict = gameEdit->MapGetEntityDict( name ); + g_SoundDialog->Set( dict ); + } +} + +void SoundEditorRun( void ) { +#if _MSC_VER >= 1300 + MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! +#else + MSG *msg = &m_msgCur; +#endif + + while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { + // pump message + if ( !AfxGetApp()->PumpMessage() ) { + } + } +} + +void SoundEditorShutdown( void ) { + delete g_SoundDialog; + g_SoundDialog = NULL; +} + +void CDialogSound::OnActivate( UINT nState, CWnd *pWndOther, BOOL bMinimized ) { + CDialog::OnActivate( nState, pWndOther, bMinimized ); + if ( nState != WA_INACTIVE ) { + } +} + +void CDialogSound::OnMove( int x, int y ) { + if ( GetSafeHwnd() ) { + CRect rct; + GetWindowRect( rct ); + // FIXME: save position + } + CDialog::OnMove( x, y ); +} + +void CDialogSound::OnDestroy() { + + com_editors &= ~EDITOR_SOUND; + + return CDialog::OnDestroy(); +} + +void CDialogSound::Set( const idDict *source ) { + + if ( source == NULL ) { + return; + } + + fVolume = source->GetFloat( "s_volume", "0" ); + fMin = source->GetFloat( "s_mindistance", "1" ); + fMax = source->GetFloat( "s_maxdistance", "10" ); + leadThrough = source->GetFloat( "s_leadthrough", "0.1" ); + plain = source->GetBool( "s_plain" ); + strShader = source->GetString( "s_shader" ); + strGroup = source->GetString( "soundgroup" ); + bOmni = source->GetInt( "s_omni", "-1" ); + bOcclusion = source->GetBool( "s_occlusion", "0" ); + bTriggered = source->GetInt( "s_waitfortrigger", "-1" ); + random = source->GetFloat( "random" ); + wait = source->GetFloat( "wait" ); + strName = source->GetString("name"); + looping = source->GetBool( "s_looping" ); + unclamped = source->GetBool( "s_unclamped" ); + shakes = source->GetFloat( "s_shakes" ); + if (comboSpeakers.SelectString(-1, strName) == CB_ERR) { + comboSpeakers.SetCurSel(-1); + } + if (comboGroups.SelectString(-1, strGroup) == CB_ERR) { + comboGroups.SetCurSel(-1); + } + UpdateData(FALSE); +} + +void CDialogSound::Get( idDict *source ) { + + if ( source == NULL ) { + return; + } + UpdateData( TRUE ); + float f = source->GetFloat( "s_volume" ); + source->SetFloat( "s_volume", f ); + source->SetFloat( "s_mindistance", fMin ); + source->SetFloat( "s_maxdistance", fMax ); + source->Set( "s_shader", strShader ); + source->SetInt( "s_omni", bOmni ); + source->SetBool( "s_occlusion", ( bOcclusion != FALSE ) ); + source->SetInt("s_waitfortrigger", bTriggered ); + source->Set( "soundgroup", strGroup ); + source->Set( "name", strName ); + source->SetFloat( "s_leadthrough", leadThrough ); + source->SetBool( "s_plain", ( plain != FALSE ) ); + source->SetFloat( "wait", wait ); + source->SetFloat( "random", random ); + source->SetBool( "s_looping", looping == TRUE ); + source->SetBool( "s_unclamped", unclamped == TRUE ); + source->SetFloat( "s_shakes", shakes ); +} + +void CDialogSound::OnBtnSavemap() +{ + OnBtnApply(); + gameEdit->MapSave(); +} + +void CDialogSound::OnBtnSwitchtogame() +{ + ::SetFocus(win32.hWnd); +} + +void CDialogSound::SetVolume( float vol ) { + idList list; + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + // we might be in either the game or the editor + idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); + if ( sw ) { + sw->PlayShaderDirectly( "" ); + } + + for (int i = 0; i < count; i++) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + const idDict *dict2 = gameEdit->MapGetEntityDict( name ); + if ( dict2 ) { + gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", vol ) ); + gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" ); + gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 ); + fVolume = vol; + UpdateData( FALSE ); + } + } + } +} + +void CDialogSound::ApplyChanges( bool volumeOnly, bool updateInUseTree ) { + idList list; + float vol; + + vol = fVolume; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + // we might be in either the game or the editor + idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); + if ( sw ) { + sw->PlayShaderDirectly( "" ); + } + + for (int i = 0; i < count; i++) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + const idDict *dict2 = gameEdit->MapGetEntityDict( name ); + if ( dict2 ) { + if ( volumeOnly ) { + float f = dict2->GetFloat( "s_volume" ); + f += vol; + gameEdit->MapSetEntityKeyVal( name, "s_volume", va( "%f", f ) ); + gameEdit->MapSetEntityKeyVal( name, "s_justVolume", "1" ); + gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 ); + fVolume = f; + UpdateData( FALSE ); + } else { + idDict src; + src.SetFloat( "s_volume", dict2->GetFloat( "s_volume" )); + Get( &src ); + src.SetBool( "s_justVolume", true ); + gameEdit->MapCopyDictToEntity( name, &src ); + gameEdit->EntityUpdateChangeableSpawnArgs( list[i], dict2 ); + Set( dict2 ); + } + } + } + } + + AddGroups(); + AddSpeakers(); + if ( updateInUseTree ) { + AddInUseSounds(); + } +} + +void CDialogSound::OnBtnApply() +{ + ApplyChanges(); +} + +void CDialogSound::OnChangeEditVolume() +{ + // TODO: If this is a RICHEDIT control, the control will not + // send this notification unless you override the CDialog::OnInitDialog() + // function and call CRichEditCtrl().SetEventMask() + // with the ENM_CHANGE flag ORed into the mask. + + // TODO: Add your control notification handler code here + +} + +HTREEITEM CDialogSound::AddStrList(const char *root, const idStrList &list, int id) { + idStr out; + + HTREEITEM base = treeSounds.InsertItem(root); + HTREEITEM item = base; + HTREEITEM add; + + int count = list.Num(); + + idStr last, path, path2; + for (int i = 0; i < count; i++) { + idStr name = list[i]; + + // now break the name down convert to slashes + name.BackSlashesToSlashes(); + name.Strip(' '); + + int index; + int len = last.Length(); + if (len == 0) { + index = name.Last('/'); + if (index >= 0) { + name.Left(index, last); + } + } + else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) { + name.Right(name.Length() - len - 1, out); + add = treeSounds.InsertItem(out, item); + quickTree.Set(name, add); + treeSounds.SetItemData(add, id); + treeSounds.SetItemImage(add, 2, 2); + continue; + } + else { + last.Empty(); + } + + index = 0; + item = base; + path = ""; + path2 = ""; + while (index >= 0) { + index = name.Find('/'); + if (index >= 0) { + HTREEITEM newItem = NULL; + HTREEITEM *check = NULL; + name.Left( index, out ); + path += out; + if (quickTree.Get(path, &check)) { + newItem = *check; + } + + //HTREEITEM newItem = FindTreeItem(&treeSounds, item, name.Left(index, out), item); + if (newItem == NULL) { + newItem = treeSounds.InsertItem(out, item); + quickTree.Set(path, newItem); + treeSounds.SetItemData(newItem, WAVEDIR); + treeSounds.SetItemImage(newItem, 0, 1); + } + + assert(newItem); + item = newItem; + name.Right( name.Length() - index - 1, out ); + name = out; + path += "/"; + } + else { + add = treeSounds.InsertItem(name, item); + treeSounds.SetItemData(add, id); + treeSounds.SetItemImage(add, 2, 2); + path = ""; + } + } + } + return base; +} + +void CDialogSound::AddSounds(bool rootItems) { + int i, j; + idStrList list(1024); + idStrList list2(1024); + HTREEITEM base = treeSounds.InsertItem("Sound Shaders"); + + for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ) ; i++ ) { + const idSoundShader *poo = declManager->SoundByIndex(i, false); + list.AddUnique( poo->GetFileName() ); + } + list.Sort(); + + for ( i = 0; i < list.Num(); i++ ) { + HTREEITEM child = treeSounds.InsertItem(list[i], base); + treeSounds.SetItemData(child, SOUNDPARENT); + treeSounds.SetItemImage(child, 0, 1); + list2.Clear(); + for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) { + const idSoundShader *poo = declManager->SoundByIndex(j, false); + if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) { + list2.Append( poo->GetName() ); + } + } + list2.Sort(); + for (j = 0; j < list2.Num(); j++) { + HTREEITEM child2 = treeSounds.InsertItem( list2[j], child ); + treeSounds.SetItemData(child2, SOUNDS); + treeSounds.SetItemImage(child2, 2, 2); + } + } + + idFileList *files; + files = fileSystem->ListFilesTree( "sound", ".wav|.ogg", true ); + AddStrList( "Wave files", files->GetList(), WAVES ); + fileSystem->FreeFileList( files ); +} + +void CDialogSound::AddGroups() { + comboGroups.ResetContent(); + idStr work; + CWaitCursor cursor; + + idList list; + list.SetNum( 1024 ); + int count = gameEdit->MapGetUniqueMatchingKeyVals( "soundgroup", list.Ptr(), list.Num() ); + for ( int i = 0; i < count; i++ ) { + comboGroups.AddString( list[i] ); + } +} + +void CDialogSound::AddInUseSounds() { + if ( inUseTree ) { + treeSounds.DeleteItem( inUseTree ); + inUseTree = NULL; + } + inUseTree = treeSounds.InsertItem("Sounds in use"); + idList< const char *> list; + list.SetNum( 512 ); + int i, count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", "", list.Ptr(), list.Num() ); + idStrList list2; + for ( i = 0; i < count; i++ ) { + const idDict *dict = gameEdit->MapGetEntityDict( list[i] ); + if ( dict ) { + const char *p = dict->GetString( "s_shader" ); + if ( p && *p ) { + list2.AddUnique( p ); + } + } + } + list2.Sort(); + count = list2.Num(); + for ( i = 0; i < count; i++ ) { + HTREEITEM child = treeSounds.InsertItem( list2[i], inUseTree ); + treeSounds.SetItemData( child, INUSESOUNDS ); + treeSounds.SetItemImage( child, 2, 2 ); + } +} + +void CDialogSound::AddSpeakers() { + UpdateData( TRUE ); + comboSpeakers.ResetContent(); + + CWaitCursor cursor; + idList< const char *> list; + list.SetNum( 512 ); + + CString group( "" ); + if (bGroupOnly && comboGroups.GetCurSel() >= 0) { + comboGroups.GetLBText( comboGroups.GetCurSel(), group ); + } + int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() ); + + for ( int i = 0; i < count; i++ ) { + comboSpeakers.AddString(list[i]); + } +} + +BOOL CDialogSound::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // Indicate the sound dialog is opened + com_editors |= EDITOR_SOUND; + + inUseTree = NULL; + AddSounds(true); + AddGroups(); + AddSpeakers(); + AddInUseSounds(); + SetWaveSize(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CDialogSound::OnBtnRefresh() +{ + CWaitCursor cursor; + treeSounds.DeleteAllItems(); + quickTree.Clear(); + declManager->Reload( false ); + AddSounds(true); +} + +void CDialogSound::OnBtnPlaysound() +{ + if (playSound.GetLength()) { + // we might be in either the game or the editor + idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); + if ( sw ) { + sw->PlayShaderDirectly(playSound); + } + } + +} + +void CDialogSound::OnDblclkTreeSounds(NMHDR* pNMHDR, LRESULT* pResult) +{ + *pResult = 0; + CPoint pt; + GetCursorPos( &pt ); + treeSounds.ScreenToClient( &pt ); + HTREEITEM item = treeSounds.HitTest( pt ); + + if (item) { + DWORD dw = treeSounds.GetItemData( item ); + if ( dw == SOUNDS || dw == INUSESOUNDS ) { + if ( !treeSounds.ItemHasChildren( item ) ) { + strShader = treeSounds.GetItemText( item ); + UpdateData( FALSE ); + ApplyChanges( false, ( dw == SOUNDS ) ); + } + } else if ( dw == WAVES ) { + strShader = RebuildItemName( "Wave Files", item ); + UpdateData( FALSE ); + OnBtnApply(); + } + } + *pResult = 0; +} + +void CDialogSound::SetWaveSize( const char *p ) { + CWnd *wnd = GetDlgItem( IDC_STATIC_WAVESIZE ); + if ( wnd ) { + wnd->SetWindowText( ( p && *p ) ? p : "unknown" ); + } +} + +void CDialogSound::OnSelchangedTreeSounds(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; + HTREEITEM item = treeSounds.GetSelectedItem(); + SetWaveSize(); + if (item) { + DWORD dw = treeSounds.GetItemData(item); + if ( dw == SOUNDS || dw == INUSESOUNDS ) { + playSound = treeSounds.GetItemText(item); + if (bPlay){ + OnBtnPlaysound(); + } + } else if (dw == WAVES) { + playSound = RebuildItemName("Wave Files", item); + float size = fileSystem->ReadFile( playSound, NULL ); + SetWaveSize( va( "%0.2f mb", size / ( 1024 * 1024) ) ); + if (bPlay){ + OnBtnPlaysound(); + } + } + } + + *pResult = 0; +} + +void CDialogSound::OnCheckPlay() +{ + UpdateData(TRUE); +} + +void CDialogSound::OnBtnEdit() +{ + const idDecl *decl = declManager->FindDeclWithoutParsing( DECL_SOUND, strShader, false ); + + if ( decl ) { + DialogDeclEditor *declEditor; + + declEditor = new DialogDeclEditor; + declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() ); + declEditor->LoadDecl( const_cast( decl ) ); + declEditor->ShowWindow( SW_SHOW ); + declEditor->SetFocus(); + } +} + +void CDialogSound::OnBtnDrop() +{ + idStr classname; + idStr key; + idStr value; + idVec3 org; + idDict args; + idAngles viewAngles; + + + gameEdit->PlayerGetViewAngles( viewAngles ); + gameEdit->PlayerGetEyePosition( org ); + org += idAngles( 0, viewAngles.yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 ); + args.Set("origin", org.ToString()); + args.Set("classname", "speaker"); + args.Set("angle", va( "%f", viewAngles.yaw + 180 )); + args.Set("s_shader", strShader); + args.Set("s_looping", "1" ); + args.Set("s_shakes", "0" ); + + + idStr name = gameEdit->GetUniqueEntityName( "speaker" ); + bool nameValid = false; + while (!nameValid) { + DialogName dlg("Name Speaker", this); + dlg.m_strName = name; + if (dlg.DoModal() == IDOK) { + idEntity *gameEnt = gameEdit->FindEntity(dlg.m_strName); + if (gameEnt) { + if (MessageBox("Please choose another name", "Duplicate Entity Name!", MB_OKCANCEL) == IDCANCEL) { + return; + } + } else { + nameValid = true; + name = dlg.m_strName; + } + } + } + + args.Set("name", name.c_str()); + + idEntity *ent = NULL; + gameEdit->SpawnEntityDef( args, &ent ); + if (ent) { + gameEdit->EntityUpdateChangeableSpawnArgs( ent, NULL ); + gameEdit->ClearEntitySelection(); + gameEdit->AddSelectedEntity( ent ); + } + + gameEdit->MapAddEntity( &args ); + const idDict *dict = gameEdit->MapGetEntityDict( args.GetString( "name" ) ); + Set( dict ); + AddGroups(); + AddSpeakers(); +} + +void CDialogSound::OnBtnGroup() +{ + idList list; + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + bool removed = false; + if (count) { + for (int i = 0; i < count; i++) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString("name"); + dict = gameEdit->MapGetEntityDict( name ); + if ( dict ) { + if (MessageBox("Are you Sure?", "Delete Selected Speakers", MB_YESNO) == IDYES) { + gameEdit->MapRemoveEntity( name ); + idEntity *gameEnt = gameEdit->FindEntity( name ); + if ( gameEnt ) { + gameEdit->EntityStopSound( gameEnt ); + gameEdit->EntityDelete( gameEnt ); + removed = true; + } + } + } + } + } + + if (removed) { + AddGroups(); + AddSpeakers(); + } + +} + +void CDialogSound::OnBtnSavemapas() +{ + CFileDialog dlgSave(FALSE,"map",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Map Files (*.map)|*.map||",AfxGetMainWnd()); + if (dlgSave.DoModal() == IDOK) { + OnBtnApply(); + idStr work; + work = fileSystem->OSPathToRelativePath( dlgSave.m_ofn.lpstrFile ); + gameEdit->MapSave( work ); + } +} + +idStr CDialogSound::RebuildItemName(const char *root, HTREEITEM item) { + // have to build the name back up + idStr strParent; + HTREEITEM parent = treeSounds.GetParentItem(item); + idStr name = treeSounds.GetItemText(item); + while (true && parent) { + idStr test = treeSounds.GetItemText(parent); + if ( idStr::Icmp(test, root) == 0 ) { + break; + } + strParent = test; + strParent += "/"; + strParent += name; + name = strParent; + parent = treeSounds.GetParentItem(parent); + if (parent == NULL) { + break; + } + } + return strParent; +} + + +void CDialogSound::UpdateSelectedOrigin( float x, float y, float z ) { + idList list; + idVec3 origin; + idVec3 vec(x, y, z); + + list.SetNum( 128 ); + int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); + list.SetNum( count ); + + if ( count ) { + for ( int i = 0; i < count; i++ ) { + const idDict *dict = gameEdit->EntityGetSpawnArgs( list[i] ); + if ( dict == NULL ) { + continue; + } + const char *name = dict->GetString( "name" ); + gameEdit->EntityTranslate( list[i], vec ); + gameEdit->EntityUpdateVisuals( list[i] ); + gameEdit->MapEntityTranslate( name, vec ); + } + } +} + +void CDialogSound::OnBtnYup() +{ + UpdateSelectedOrigin(0, 8, 0); +} + +void CDialogSound::OnBtnYdn() +{ + UpdateSelectedOrigin(0, -8, 0); +} + +void CDialogSound::OnBtnXdn() +{ + UpdateSelectedOrigin(-8, 0, 0); +} + +void CDialogSound::OnBtnXup() +{ + UpdateSelectedOrigin(8, 0, 0); +} + +void CDialogSound::OnBtnZup() +{ + UpdateSelectedOrigin(0, 0, 8); +} + +void CDialogSound::OnBtnZdn() +{ + UpdateSelectedOrigin(0, 0, -8); +} + +void CDialogSound::OnBtnTrigger() { + gameEdit->TriggerSelected(); +} + +void CDialogSound::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { +} + + +void CDialogSound::OnCheckGrouponly() +{ + AddSpeakers(); +} + +void CDialogSound::OnSelchangeComboGroups() { + CWaitCursor cursor; + gameEdit->ClearEntitySelection(); + if ( comboGroups.GetCurSel() >= 0 ) { + CString group; + comboGroups.GetLBText( comboGroups.GetCurSel(), group ); + + idList< const char *> list; + list.SetNum( 512 ); + int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", group, list.Ptr(), list.Num() ); + for ( int i = 0; i < count; i++ ) { + idEntity *gameEnt = gameEdit->FindEntity( list[i] ); + if (gameEnt) { + gameEdit->AddSelectedEntity( gameEnt ); + Set( gameEdit->EntityGetSpawnArgs( gameEnt ) ); + } + } + } + AddSpeakers(); +} + +void CDialogSound::OnSelchangeComboSpeakers() { + CWaitCursor cursor; + gameEdit->ClearEntitySelection(); + if ( comboSpeakers.GetCurSel() >= 0 ) { + CString speaker; + comboSpeakers.GetLBText( comboSpeakers.GetCurSel(), speaker ); + idList< const char *> list; + list.SetNum( 512 ); + int count = gameEdit->MapGetEntitiesMatchingClassWithString( "speaker", speaker, list.Ptr(), list.Num() ); + for ( int i = 0; i < count; i++ ) { + idEntity *gameEnt = gameEdit->FindEntity( list[i] ); + if (gameEnt) { + gameEdit->AddSelectedEntity( gameEnt ); + Set( gameEdit->EntityGetSpawnArgs( gameEnt ) ); + } + } + } +} + +void CDialogSound::OnBtnDown() { + fVolume = -1.0; + UpdateData( FALSE ); + ApplyChanges( true, false ); +} + +void CDialogSound::OnBtnUp() { + fVolume = 1.0; + UpdateData( FALSE ); + ApplyChanges( true, false ); +} + +void CDialogSound::OnBtnRefreshspeakers() +{ + AddGroups(); + AddSpeakers(); +} + +void CDialogSound::OnBtnRefreshwave() +{ + HTREEITEM item = treeSounds.GetSelectedItem(); + if (item && treeSounds.GetItemData( item ) == WAVEDIR) { + idStr path = "sound/"; + path += RebuildItemName("sound", item); + idFileList *files; + files = fileSystem->ListFilesTree( path, ".wav" ); + HTREEITEM child = treeSounds.GetChildItem(item); + while (child) { + HTREEITEM next = treeSounds.GetNextSiblingItem(child); + if (treeSounds.GetItemData(child) == WAVES) { + treeSounds.DeleteItem(child); + } + child = next; + } + int c = files->GetNumFiles(); + for (int i = 0; i < c; i++) { + idStr work = files->GetFile( i ); + work.StripPath(); + child = treeSounds.InsertItem(work, item); + treeSounds.SetItemData( child, WAVES ); + treeSounds.SetItemImage( child, 2, 2 ); + } + fileSystem->FreeFileList( files ); + } +} + +BOOL CDialogSound::PreTranslateMessage(MSG* pMsg) +{ + CWnd *wnd = GetDlgItem( IDC_EDIT_VOLUME ); + if ( wnd && pMsg->hwnd == wnd->GetSafeHwnd() ) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) { + CString str; + wnd->GetWindowText( str ); + SetVolume( atof( str ) ); + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} diff --git a/tools/sound/DialogSound.h b/tools/sound/DialogSound.h new file mode 100644 index 000000000..397e5f8ce --- /dev/null +++ b/tools/sound/DialogSound.h @@ -0,0 +1,129 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DIALOGSOUND_H__ +#define __DIALOGSOUND_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CDialogSound dialog + +class CDialogSound : public CDialog { +public: + CDialogSound(CWnd* pParent = NULL); // standard constructor\ + + void Set( const idDict *source ); + void Get( idDict *dest ); + + enum { NONE, SOUNDS, SOUNDPARENT, WAVES, WAVEDIR, INUSESOUNDS }; + + //{{AFX_VIRTUAL(CDialogSound) + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +protected: + //{{AFX_MSG(CDialogSound) + afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); + afx_msg void OnMove( int x, int y ); + afx_msg void OnDestroy(); + afx_msg void OnBtnSavemap(); + afx_msg void OnBtnSwitchtogame(); + afx_msg void OnBtnApply(); + afx_msg void OnChangeEditVolume(); + afx_msg void OnBtnRefresh(); + afx_msg void OnBtnPlaysound(); + afx_msg void OnDblclkTreeSounds(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnSelchangedTreeSounds(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnCheckPlay(); + afx_msg void OnBtnEdit(); + afx_msg void OnBtnDrop(); + afx_msg void OnBtnGroup(); + afx_msg void OnBtnSavemapas(); + afx_msg void OnBtnYup(); + afx_msg void OnBtnYdn(); + afx_msg void OnBtnXdn(); + afx_msg void OnBtnXup(); + afx_msg void OnBtnZup(); + afx_msg void OnBtnZdn(); + afx_msg void OnBtnTrigger(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnCheckGrouponly(); + afx_msg void OnSelchangeComboGroups(); + afx_msg void OnSelchangeComboSpeakers(); + afx_msg void OnBtnDown(); + afx_msg void OnBtnUp(); + afx_msg void OnBtnRefreshspeakers(); + afx_msg void OnBtnRefreshwave(); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() + +private: + //{{AFX_DATA(CDialogSound) + enum { IDD = IDD_DIALOG_SOUND }; + CComboBox comboSpeakers; + CComboBox comboGroups; + CEdit editVolume; + CTreeCtrl treeSounds; + CString strName; + float fVolume; + float fMax; + float fMin; + CString strShader; + BOOL bPlay; + int bTriggered; + int bOmni; + CString strGroup; + BOOL bGroupOnly; + BOOL bOcclusion; + float leadThrough; + BOOL plain; + float random; + float wait; + float shakes; + BOOL looping; + BOOL unclamped; + //}}AFX_DATA + + CString playSound; + idHashTable quickTree; + HTREEITEM inUseTree; +private: + void AddSounds(bool rootItem); + HTREEITEM AddStrList(const char *root, const idStrList &list, int id); + HTREEITEM InsertTreeItem(const char *name, const char *fullName, HTREEITEM item); + idStr RebuildItemName(const char *root, HTREEITEM item); + void UpdateSelectedOrigin(float x, float y, float z); + void AddGroups(); + void AddSpeakers(); + void AddInUseSounds(); + void ApplyChanges( bool volumeOnly = false , bool updateInUseTree = true ); + void SetWaveSize( const char *p = NULL ); + void SetVolume( float f ); + virtual BOOL PreTranslateMessage(MSG* pMsg); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif /* !__DIALOGSOUND_H__ */ diff --git a/tools/sound/DialogSoundGroup.cpp b/tools/sound/DialogSoundGroup.cpp new file mode 100644 index 000000000..c4f3d70de --- /dev/null +++ b/tools/sound/DialogSoundGroup.cpp @@ -0,0 +1,80 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../../idlib/precompiled.h" +#pragma hdrstop + +#include "../../sys/win32/rc/SoundEditor_resource.h" + +#include "DialogSoundGroup.h" + +///////////////////////////////////////////////////////////////////////////// +// CDialogSoundGroup dialog + + +CDialogSoundGroup::CDialogSoundGroup(CWnd* pParent /*=NULL*/) + : CDialog(CDialogSoundGroup::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDialogSoundGroup) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CDialogSoundGroup::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDialogSoundGroup) + DDX_Control(pDX, IDC_LIST_GROUPS, lstGroups); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CDialogSoundGroup, CDialog) + //{{AFX_MSG_MAP(CDialogSoundGroup) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDialogSoundGroup message handlers + +void CDialogSoundGroup::OnOK() +{ + CString str; + int count = lstGroups.GetSelCount(); + for (int i = 0; i < count; i++) { + lstGroups.GetText(i, str); + list.Append(str.GetBuffer(0)); + } + + CDialog::OnOK(); +} + +BOOL CDialogSoundGroup::OnInitDialog() +{ + CDialog::OnInitDialog(); + + int count = list.Num(); + for (int i = 0; i < count; i++) { + lstGroups.AddString(list[i]); + } + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/tools/sound/DialogSoundGroup.h b/tools/sound/DialogSoundGroup.h new file mode 100644 index 000000000..979d20255 --- /dev/null +++ b/tools/sound/DialogSoundGroup.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#if !defined(AFX_DIALOGSOUNDGROUP_H__3503E935_1F86_4484_903F_021CBDAB7729__INCLUDED_) +#define AFX_DIALOGSOUNDGROUP_H__3503E935_1F86_4484_903F_021CBDAB7729__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DialogSoundGroup.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CDialogSoundGroup dialog + +class CDialogSoundGroup : public CDialog +{ +// Construction +public: + idStrList list; + CDialogSoundGroup(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CDialogSoundGroup) + enum { IDD = IDD_DIALOG_SOUNDGROUP }; + CListBox lstGroups; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDialogSoundGroup) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDialogSoundGroup) + virtual void OnOK(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DIALOGSOUNDGROUP_H__3503E935_1F86_4484_903F_021CBDAB7729__INCLUDED_) diff --git a/tools/vcprojects/2003/MayaImport.vcproj b/tools/vcprojects/2003/MayaImport.vcproj deleted file mode 100644 index a6de46d0a..000000000 --- a/tools/vcprojects/2003/MayaImport.vcproj +++ /dev/null @@ -1,2471 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2003/d3game.sln b/tools/vcprojects/2003/d3game.sln deleted file mode 100644 index ecb59834a..000000000 --- a/tools/vcprojects/2003/d3game.sln +++ /dev/null @@ -1,41 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Game", "d3game.vcproj", "{49BEC5C6-B964-417A-851E-808886B57430}" - ProjectSection(ProjectDependencies) = postProject - {49BEC5C6-B964-417A-851E-808886B57400} = {49BEC5C6-B964-417A-851E-808886B57400} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idLib", "idlib.vcproj", "{49BEC5C6-B964-417A-851E-808886B57400}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject - -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Debug with inlines = Debug with inlines - Debug with inlines and memory log = Debug with inlines and memory log - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {49BEC5C6-B964-417A-851E-808886B57430}.Debug.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release.Build.0 = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/tools/vcprojects/2003/d3game.vcproj b/tools/vcprojects/2003/d3game.vcproj deleted file mode 100644 index ffc885a56..000000000 --- a/tools/vcprojects/2003/d3game.vcproj +++ /dev/null @@ -1,1816 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2003/idlib.vcproj b/tools/vcprojects/2003/idlib.vcproj deleted file mode 100644 index e66c42e6b..000000000 --- a/tools/vcprojects/2003/idlib.vcproj +++ /dev/null @@ -1,703 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2005/MayaImport.vcproj b/tools/vcprojects/2005/MayaImport.vcproj deleted file mode 100644 index a6de46d0a..000000000 --- a/tools/vcprojects/2005/MayaImport.vcproj +++ /dev/null @@ -1,2471 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2005/d3game.sln b/tools/vcprojects/2005/d3game.sln deleted file mode 100644 index caa93f46d..000000000 --- a/tools/vcprojects/2005/d3game.sln +++ /dev/null @@ -1,54 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Game", "d3game.vcproj", "{49BEC5C6-B964-417A-851E-808886B57430}" - ProjectSection(ProjectDependencies) = postProject - {49BEC5C6-B964-417A-851E-808886B57400} = {49BEC5C6-B964-417A-851E-808886B57400} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idLib", "idlib.vcproj", "{49BEC5C6-B964-417A-851E-808886B57400}" -EndProject -Project("{8BC9CEB9-8B4A-11D0-8D11-00A0C91BC942}") = "DOOM3.exe", "..\DOOM3.exe", "{B94FB3AB-33F4-4208-A9C9-DCE989C70BD7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rcfLib", "rcflib.vcproj", "{20022013-22BA-4338-9FE0-3E31AC5ACB3D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug with inlines and memory log|Win32 = Debug with inlines and memory log|Win32 - Debug with inlines|Win32 = Debug with inlines|Win32 - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Debug|Win32.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57430}.Release|Win32.Build.0 = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.ActiveCfg = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines and memory log|Win32.Build.0 = Debug with inlines and memory log|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.ActiveCfg = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug with inlines|Win32.Build.0 = Debug with inlines|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.ActiveCfg = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Debug|Win32.Build.0 = Debug|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.ActiveCfg = Release|Win32 - {49BEC5C6-B964-417A-851E-808886B57400}.Release|Win32.Build.0 = Release|Win32 - {B94FB3AB-33F4-4208-A9C9-DCE989C70BD7}.Debug with inlines and memory log|Win32.ActiveCfg = Debug - {B94FB3AB-33F4-4208-A9C9-DCE989C70BD7}.Debug with inlines|Win32.ActiveCfg = Debug - {B94FB3AB-33F4-4208-A9C9-DCE989C70BD7}.Debug|Win32.ActiveCfg = Debug - {B94FB3AB-33F4-4208-A9C9-DCE989C70BD7}.Release|Win32.ActiveCfg = Debug - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug with inlines and memory log|Win32.ActiveCfg = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug with inlines and memory log|Win32.Build.0 = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug with inlines|Win32.ActiveCfg = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug with inlines|Win32.Build.0 = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug|Win32.ActiveCfg = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Debug|Win32.Build.0 = Debug|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Release|Win32.ActiveCfg = Release|Win32 - {20022013-22BA-4338-9FE0-3E31AC5ACB3D}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/tools/vcprojects/2005/d3game.vcproj b/tools/vcprojects/2005/d3game.vcproj deleted file mode 100644 index 797d6c680..000000000 --- a/tools/vcprojects/2005/d3game.vcproj +++ /dev/null @@ -1,2107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2005/idlib.vcproj b/tools/vcprojects/2005/idlib.vcproj deleted file mode 100644 index 6e8507fd0..000000000 --- a/tools/vcprojects/2005/idlib.vcproj +++ /dev/null @@ -1,951 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/vcprojects/2005/rcflib.vcproj b/tools/vcprojects/2005/rcflib.vcproj deleted file mode 100644 index f51102975..000000000 --- a/tools/vcprojects/2005/rcflib.vcproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/typeinfo.vcxproj b/typeinfo.vcxproj new file mode 100644 index 000000000..a1ee1c103 --- /dev/null +++ b/typeinfo.vcxproj @@ -0,0 +1,192 @@ + + + + + Debug with inlines and memory log + Win32 + + + Debug with inlines + Win32 + + + Debug + Win32 + + + Dedicated Debug with inlines + Win32 + + + Dedicated Debug + Win32 + + + Dedicated Release + Win32 + + + Release + Win32 + + + + TypeInfo + {6EA6406F-3E65-47D9-8246-D6660A81606F} + TypeInfo + + + + + + + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + nafxcwd.lib;libcmtd.lib;%(AdditionalDependencies) + nafxcwd.lib;libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + + + + + Create + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + {49bec5c6-b964-417a-851e-808886b57400} + false + + + + + + \ No newline at end of file diff --git a/typeinfo.vcxproj.filters b/typeinfo.vcxproj.filters new file mode 100644 index 000000000..a134746cd --- /dev/null +++ b/typeinfo.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {2ba46bfc-0458-4729-89bf-a9ca1bbc49cb} + + + {40a69fce-c497-466a-ad0d-cc5a4293aab0} + + + + + TypeInfo + + + TypeInfo + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + + + TypeInfo + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + Framework + + + \ No newline at end of file diff --git a/ui/BindWindow.cpp b/ui/BindWindow.cpp new file mode 100644 index 000000000..993ade92a --- /dev/null +++ b/ui/BindWindow.cpp @@ -0,0 +1,119 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "BindWindow.h" + + +void idBindWindow::CommonInit() { + bindName = ""; + waitingOnKey = false; +} + +idBindWindow::idBindWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idBindWindow::idBindWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idBindWindow::~idBindWindow() { + +} + + +const char *idBindWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + static char ret[ 256 ]; + + if (!(event->evType == SE_KEY && event->evValue2)) { + return ""; + } + + int key = event->evValue; + + if (waitingOnKey) { + waitingOnKey = false; + if (key == K_ESCAPE) { + idStr::snPrintf( ret, sizeof( ret ), "clearbind \"%s\"", bindName.GetName()); + } else { + idStr::snPrintf( ret, sizeof( ret ), "bind %i \"%s\"", key, bindName.GetName()); + } + return ret; + } else { + if (key == K_MOUSE1) { + waitingOnKey = true; + gui->SetBindHandler(this); + return ""; + } + } + + return ""; +} + +idWinVar *idBindWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { + + if (idStr::Icmp(_name, "bind") == 0) { + return &bindName; + } + + return idWindow::GetWinVarByName(_name, fixup,owner); +} + +void idBindWindow::PostParse() { + idWindow::PostParse(); + bindName.SetGuiInfo( gui->GetStateDict(), bindName ); + bindName.Update(); + //bindName = state.GetString("bind"); + flags |= (WIN_HOLDCAPTURE | WIN_CANFOCUS); +} + +void idBindWindow::Draw(int time, float x, float y) { + idVec4 color = foreColor; + + idStr str; + if ( waitingOnKey ) { + str = common->GetLanguageDict()->GetString( "#str_07000" ); + } else if ( bindName.Length() ) { + str = bindName.c_str(); + } else { + str = common->GetLanguageDict()->GetString( "#str_07001" ); + } + + if ( waitingOnKey || ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) ) { + color = hoverColor; + } else { + hover = false; + } + + dc->DrawText(str, textScale, textAlign, color, textRect, false, -1); +} + +void idBindWindow::Activate( bool activate, idStr &act ) { + idWindow::Activate( activate, act ); + bindName.Update(); +} diff --git a/ui/BindWindow.h b/ui/BindWindow.h new file mode 100644 index 000000000..ca8b7372f --- /dev/null +++ b/ui/BindWindow.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __BINDWINDOW_H +#define __BINDWINDOW_H + +class idUserInterfaceLocal; +class idBindWindow : public idWindow { +public: + idBindWindow(idUserInterfaceLocal *gui); + idBindWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idBindWindow(); + + virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual size_t Allocated(){return idWindow::Allocated();}; +// +// + virtual idWinVar *GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL ); +// + virtual void Activate( bool activate, idStr &act ); + +private: + void CommonInit(); + idWinStr bindName; + bool waitingOnKey; +}; + +#endif // __BINDWINDOW_H diff --git a/ui/ChoiceWindow.cpp b/ui/ChoiceWindow.cpp new file mode 100644 index 000000000..e5721ecdd --- /dev/null +++ b/ui/ChoiceWindow.cpp @@ -0,0 +1,393 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "ChoiceWindow.h" + +/* +============ +idChoiceWindow::InitVars +============ +*/ +void idChoiceWindow::InitVars( ) { + if ( cvarStr.Length() ) { + cvar = cvarSystem->Find( cvarStr ); + if ( !cvar ) { + common->Warning( "idChoiceWindow::InitVars: gui '%s' window '%s' references undefined cvar '%s'", gui->GetSourceFile(), name.c_str(), cvarStr.c_str() ); + return; + } + updateStr.Append( &cvarStr ); + } + if ( guiStr.Length() ) { + updateStr.Append( &guiStr ); + } + updateStr.SetGuiInfo( gui->GetStateDict() ); + updateStr.Update(); +} + +/* +============ +idChoiceWindow::CommonInit +============ +*/ +void idChoiceWindow::CommonInit() { + currentChoice = 0; + choiceType = 0; + cvar = NULL; + liveUpdate = true; + choices.Clear(); +} + +idChoiceWindow::idChoiceWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idChoiceWindow::idChoiceWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idChoiceWindow::~idChoiceWindow() { + +} + +void idChoiceWindow::RunNamedEvent( const char* eventName ) { + idStr event, group; + + if ( !idStr::Cmpn( eventName, "cvar read ", 10 ) ) { + event = eventName; + group = event.Mid( 10, event.Length() - 10 ); + if ( !group.Cmp( updateGroup ) ) { + UpdateVars( true, true ); + } + } else if ( !idStr::Cmpn( eventName, "cvar write ", 11 ) ) { + event = eventName; + group = event.Mid( 11, event.Length() - 11 ); + if ( !group.Cmp( updateGroup ) ) { + UpdateVars( false, true ); + } + } +} + +void idChoiceWindow::UpdateVars( bool read, bool force ) { + if ( force || liveUpdate ) { + if ( cvar && cvarStr.NeedsUpdate() ) { + if ( read ) { + cvarStr.Set( cvar->GetString() ); + } else { + cvar->SetString( cvarStr.c_str() ); + } + } + if ( !read && guiStr.NeedsUpdate() ) { + guiStr.Set( va( "%i", currentChoice ) ); + } + } +} + +const char *idChoiceWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + int key; + bool runAction = false; + bool runAction2 = false; + + if ( event->evType == SE_KEY ) { + key = event->evValue; + + if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MOUSE1) { + // never affects the state, but we want to execute script handlers anyway + if ( !event->evValue2 ) { + RunScript( ON_ACTIONRELEASE ); + return cmd; + } + currentChoice++; + if (currentChoice >= choices.Num()) { + currentChoice = 0; + } + runAction = true; + } + + if ( key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MOUSE2) { + // never affects the state, but we want to execute script handlers anyway + if ( !event->evValue2 ) { + RunScript( ON_ACTIONRELEASE ); + return cmd; + } + currentChoice--; + if (currentChoice < 0) { + currentChoice = choices.Num() - 1; + } + runAction = true; + } + + if ( !event->evValue2 ) { + // is a key release with no action catch + return ""; + } + + } else if ( event->evType == SE_CHAR ) { + + key = event->evValue; + + int potentialChoice = -1; + for ( int i = 0; i < choices.Num(); i++ ) { + if ( toupper(key) == toupper(choices[i][0]) ) { + if ( i < currentChoice && potentialChoice < 0 ) { + potentialChoice = i; + } else if ( i > currentChoice ) { + potentialChoice = -1; + currentChoice = i; + break; + } + } + } + if ( potentialChoice >= 0 ) { + currentChoice = potentialChoice; + } + + runAction = true; + runAction2 = true; + + } else { + return ""; + } + + if ( runAction ) { + RunScript( ON_ACTION ); + } + + if ( choiceType == 0 ) { + cvarStr.Set( va( "%i", currentChoice ) ); + } else if ( values.Num() ) { + cvarStr.Set( values[ currentChoice ] ); + } else { + cvarStr.Set( choices[ currentChoice ] ); + } + + UpdateVars( false ); + + if ( runAction2 ) { + RunScript( ON_ACTIONRELEASE ); + } + + return cmd; +} + +void idChoiceWindow::ValidateChoice() { + if ( currentChoice < 0 || currentChoice >= choices.Num() ) { + currentChoice = 0; + } + if ( choices.Num() == 0 ) { + choices.Append( "No Choices Defined" ); + } +} + +void idChoiceWindow::UpdateChoice() { + if ( !updateStr.Num() ) { + return; + } + UpdateVars( true ); + updateStr.Update(); + if ( choiceType == 0 ) { + // ChoiceType 0 stores current as an integer in either cvar or gui + // If both cvar and gui are defined then cvar wins, but they are both updated + if ( updateStr[ 0 ]->NeedsUpdate() ) { + currentChoice = atoi( updateStr[ 0 ]->c_str() ); + } + ValidateChoice(); + } else { + // ChoiceType 1 stores current as a cvar string + int c = ( values.Num() ) ? values.Num() : choices.Num(); + int i; + for ( i = 0; i < c; i++ ) { + if ( idStr::Icmp( cvarStr.c_str(), ( values.Num() ) ? values[i] : choices[i] ) == 0 ) { + break; + } + } + if (i == c) { + i = 0; + } + currentChoice = i; + ValidateChoice(); + } +} + +bool idChoiceWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "choicetype") == 0) { + choiceType = src->ParseInt(); + return true; + } + if (idStr::Icmp(_name, "currentchoice") == 0) { + currentChoice = src->ParseInt(); + return true; + } + return idWindow::ParseInternalVar(_name, src); +} + + +idWinVar *idChoiceWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { + if ( idStr::Icmp( _name, "choices" ) == 0 ) { + return &choicesStr; + } + if ( idStr::Icmp( _name, "values" ) == 0 ) { + return &choiceVals; + } + if ( idStr::Icmp( _name, "cvar" ) == 0 ) { + return &cvarStr; + } + if ( idStr::Icmp( _name, "gui" ) == 0 ) { + return &guiStr; + } + if ( idStr::Icmp( _name, "liveUpdate" ) == 0 ) { + return &liveUpdate; + } + if ( idStr::Icmp( _name, "updateGroup" ) == 0 ) { + return &updateGroup; + } + + return idWindow::GetWinVarByName(_name, fixup, owner); +} + +// update the lists whenever the WinVar have changed +void idChoiceWindow::UpdateChoicesAndVals( void ) { + idToken token; + idStr str2, str3; + idLexer src; + + if ( latchedChoices.Icmp( choicesStr ) ) { + choices.Clear(); + src.FreeSource(); + src.SetFlags( LEXFL_NOFATALERRORS | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + src.LoadMemory( choicesStr, choicesStr.Length(), "" ); + if ( src.IsLoaded() ) { + while( src.ReadToken( &token ) ) { + if ( token == ";" ) { + if ( str2.Length() ) { + str2.StripTrailingWhitespace(); + str2 = common->GetLanguageDict()->GetString( str2 ); + choices.Append(str2); + str2 = ""; + } + continue; + } + str2 += token; + str2 += " "; + } + if ( str2.Length() ) { + str2.StripTrailingWhitespace(); + choices.Append( str2 ); + } + } + latchedChoices = choicesStr.c_str(); + } + if ( choiceVals.Length() && latchedVals.Icmp( choiceVals ) ) { + values.Clear(); + src.FreeSource(); + src.SetFlags( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + src.LoadMemory( choiceVals, choiceVals.Length(), "" ); + str2 = ""; + bool negNum = false; + if ( src.IsLoaded() ) { + while( src.ReadToken( &token ) ) { + if (token == "-") { + negNum = true; + continue; + } + if (token == ";") { + if (str2.Length()) { + str2.StripTrailingWhitespace(); + values.Append( str2 ); + str2 = ""; + } + continue; + } + if ( negNum ) { + str2 += "-"; + negNum = false; + } + str2 += token; + str2 += " "; + } + if ( str2.Length() ) { + str2.StripTrailingWhitespace(); + values.Append( str2 ); + } + } + if ( choices.Num() != values.Num() ) { + common->Warning( "idChoiceWindow:: gui '%s' window '%s' has value count unequal to choices count", gui->GetSourceFile(), name.c_str()); + } + latchedVals = choiceVals.c_str(); + } +} + +void idChoiceWindow::PostParse() { + idWindow::PostParse(); + UpdateChoicesAndVals(); + + InitVars(); + UpdateChoice(); + UpdateVars(false); + + flags |= WIN_CANFOCUS; +} + +void idChoiceWindow::Draw(int time, float x, float y) { + idVec4 color = foreColor; + + UpdateChoicesAndVals(); + UpdateChoice(); + + // FIXME: It'd be really cool if textAlign worked, but a lot of the guis have it set wrong because it used to not work + textAlign = 0; + + if ( textShadow ) { + idStr shadowText = choices[currentChoice]; + idRectangle shadowRect = textRect; + + shadowText.RemoveColors(); + shadowRect.x += textShadow; + shadowRect.y += textShadow; + + dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, false, -1 ); + } + + if ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) { + color = hoverColor; + } else { + hover = false; + } + if ( flags & WIN_FOCUS ) { + color = hoverColor; + } + + dc->DrawText( choices[currentChoice], textScale, textAlign, color, textRect, false, -1 ); +} + +void idChoiceWindow::Activate( bool activate, idStr &act ) { + idWindow::Activate( activate, act ); + if ( activate ) { + // sets the gui state based on the current choice the window contains + UpdateChoice(); + } +} diff --git a/ui/ChoiceWindow.h b/ui/ChoiceWindow.h new file mode 100644 index 000000000..0005e1356 --- /dev/null +++ b/ui/ChoiceWindow.h @@ -0,0 +1,73 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __CHOICEWINDOW_H +#define __CHOICEWINDOW_H + +#include "Window.h" + +class idUserInterfaceLocal; +class idChoiceWindow : public idWindow { +public: + idChoiceWindow(idUserInterfaceLocal *gui); + idChoiceWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idChoiceWindow(); + + virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual void Activate( bool activate, idStr &act ); + virtual size_t Allocated(){return idWindow::Allocated();}; + + virtual idWinVar *GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + + void RunNamedEvent( const char* eventName ); + +private: + virtual bool ParseInternalVar(const char *name, idParser *src); + void CommonInit(); + void UpdateChoice(); + void ValidateChoice(); + + void InitVars(); + // true: read the updated cvar from cvar system, gui from dict + // false: write to the cvar system, to the gui dict + // force == true overrides liveUpdate 0 + void UpdateVars( bool read, bool force = false ); + + void UpdateChoicesAndVals( void ); + + int currentChoice; + int choiceType; + idStr latchedChoices; + idWinStr choicesStr; + idStr latchedVals; + idWinStr choiceVals; + idStrList choices; + idStrList values; + + idWinStr guiStr; + idWinStr cvarStr; + idCVar * cvar; + idMultiWinVar updateStr; + + idWinBool liveUpdate; + idWinStr updateGroup; +}; + +#endif // __CHOICEWINDOW_H diff --git a/ui/DeviceContext.cpp b/ui/DeviceContext.cpp new file mode 100644 index 000000000..89454de07 --- /dev/null +++ b/ui/DeviceContext.cpp @@ -0,0 +1,1089 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" + +idVec4 idDeviceContext::colorPurple; +idVec4 idDeviceContext::colorOrange; +idVec4 idDeviceContext::colorYellow; +idVec4 idDeviceContext::colorGreen; +idVec4 idDeviceContext::colorBlue; +idVec4 idDeviceContext::colorRed; +idVec4 idDeviceContext::colorBlack; +idVec4 idDeviceContext::colorWhite; +idVec4 idDeviceContext::colorNone; + + +idCVar gui_smallFontLimit( "gui_smallFontLimit", "0.30", CVAR_GUI | CVAR_ARCHIVE, "" ); +idCVar gui_mediumFontLimit( "gui_mediumFontLimit", "0.60", CVAR_GUI | CVAR_ARCHIVE, "" ); + + +idList idDeviceContext::fonts; + +int idDeviceContext::FindFont( const char *name ) { + int c = fonts.Num(); + for (int i = 0; i < c; i++) { + if (idStr::Icmp(name, fonts[i].name) == 0) { + return i; + } + } + + // If the font was not found, try to register it + idStr fileName = name; + fileName.Replace("fonts", va("fonts/%s", fontLang.c_str()) ); + + fontInfoEx_t fontInfo; + int index = fonts.Append( fontInfo ); + if ( renderSystem->RegisterFont( fileName, fonts[index] ) ){ + idStr::Copynz( fonts[index].name, name, sizeof( fonts[index].name ) ); + return index; + } else { + common->Printf( "Could not register font %s [%s]\n", name, fileName.c_str() ); + return -1; +} +} + +void idDeviceContext::SetupFonts() { + fonts.SetGranularity( 1 ); + + fontLang = cvarSystem->GetCVarString( "sys_lang" ); + + // western european languages can use the english font + if ( fontLang == "french" || fontLang == "german" || fontLang == "spanish" || fontLang == "italian" ) { + fontLang = "english"; + } + + // Default font has to be added first + FindFont( "fonts" ); +} + +void idDeviceContext::SetFont( int num ) { + if ( num >= 0 && num < fonts.Num() ) { + activeFont = &fonts[num]; + } else { + activeFont = &fonts[0]; + } +} + + +void idDeviceContext::Init() { + xScale = 0.0; + SetSize(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); + whiteImage = declManager->FindMaterial("guis/assets/white.tga"); + whiteImage->SetSort( SS_GUI ); + mbcs = false; + SetupFonts(); + activeFont = &fonts[0]; + colorPurple = idVec4(1, 0, 1, 1); + colorOrange = idVec4(1, 1, 0, 1); + colorYellow = idVec4(0, 1, 1, 1); + colorGreen = idVec4(0, 1, 0, 1); + colorBlue = idVec4(0, 0, 1, 1); + colorRed = idVec4(1, 0, 0, 1); + colorWhite = idVec4(1, 1, 1, 1); + colorBlack = idVec4(0, 0, 0, 1); + colorNone = idVec4(0, 0, 0, 0); + cursorImages[CURSOR_ARROW] = declManager->FindMaterial("ui/assets/guicursor_arrow.tga"); + cursorImages[CURSOR_HAND] = declManager->FindMaterial("ui/assets/guicursor_hand.tga"); + scrollBarImages[SCROLLBAR_HBACK] = declManager->FindMaterial("ui/assets/scrollbarh.tga"); + scrollBarImages[SCROLLBAR_VBACK] = declManager->FindMaterial("ui/assets/scrollbarv.tga"); + scrollBarImages[SCROLLBAR_THUMB] = declManager->FindMaterial("ui/assets/scrollbar_thumb.tga"); + scrollBarImages[SCROLLBAR_RIGHT] = declManager->FindMaterial("ui/assets/scrollbar_right.tga"); + scrollBarImages[SCROLLBAR_LEFT] = declManager->FindMaterial("ui/assets/scrollbar_left.tga"); + scrollBarImages[SCROLLBAR_UP] = declManager->FindMaterial("ui/assets/scrollbar_up.tga"); + scrollBarImages[SCROLLBAR_DOWN] = declManager->FindMaterial("ui/assets/scrollbar_down.tga"); + cursorImages[CURSOR_ARROW]->SetSort( SS_GUI ); + cursorImages[CURSOR_HAND]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_HBACK]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_VBACK]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_THUMB]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_RIGHT]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_LEFT]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_UP]->SetSort( SS_GUI ); + scrollBarImages[SCROLLBAR_DOWN]->SetSort( SS_GUI ); + cursor = CURSOR_ARROW; + enableClipping = true; + overStrikeMode = true; + mat.Identity(); + origin.Zero(); + initialized = true; +} + +void idDeviceContext::Shutdown() { + fontName.Clear(); + clipRects.Clear(); + fonts.Clear(); + Clear(); +} + +void idDeviceContext::Clear() { + initialized = false; + useFont = NULL; + activeFont = NULL; + mbcs = false; +} + +idDeviceContext::idDeviceContext() { + Clear(); +} + +void idDeviceContext::SetTransformInfo(const idVec3 &org, const idMat3 &m) { + origin = org; + mat = m; +} + +// +// added method +void idDeviceContext::GetTransformInfo(idVec3& org, idMat3& m ) +{ + m = mat; + org = origin; +} +// + +void idDeviceContext::PopClipRect() { + if (clipRects.Num()) { + clipRects.RemoveIndex(clipRects.Num()-1); + } +} + +void idDeviceContext::PushClipRect(idRectangle r) { + clipRects.Append(r); +} + +void idDeviceContext::PushClipRect(float x, float y, float w, float h) { + clipRects.Append(idRectangle(x, y, w, h)); +} + +bool idDeviceContext::ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2) { + + if ( enableClipping == false || clipRects.Num() == 0 ) { + return false; + } + + int c = clipRects.Num(); + while( --c > 0 ) { + idRectangle *clipRect = &clipRects[c]; + + float ox = *x; + float oy = *y; + float ow = *w; + float oh = *h; + + if ( ow <= 0.0f || oh <= 0.0f ) { + break; + } + + if (*x < clipRect->x) { + *w -= clipRect->x - *x; + *x = clipRect->x; + } else if (*x > clipRect->x + clipRect->w) { + *x = *w = *y = *h = 0; + } + if (*y < clipRect->y) { + *h -= clipRect->y - *y; + *y = clipRect->y; + } else if (*y > clipRect->y + clipRect->h) { + *x = *w = *y = *h = 0; + } + if (*w > clipRect->w) { + *w = clipRect->w - *x + clipRect->x; + } else if (*x + *w > clipRect->x + clipRect->w) { + *w = clipRect->Right() - *x; + } + if (*h > clipRect->h) { + *h = clipRect->h - *y + clipRect->y; + } else if (*y + *h > clipRect->y + clipRect->h) { + *h = clipRect->Bottom() - *y; + } + + if ( s1 && s2 && t1 && t2 && ow > 0.0f ) { + float ns1, ns2, nt1, nt2; + // upper left + float u = ( *x - ox ) / ow; + ns1 = *s1 * ( 1.0f - u ) + *s2 * ( u ); + + // upper right + u = ( *x + *w - ox ) / ow; + ns2 = *s1 * ( 1.0f - u ) + *s2 * ( u ); + + // lower left + u = ( *y - oy ) / oh; + nt1 = *t1 * ( 1.0f - u ) + *t2 * ( u ); + + // lower right + u = ( *y + *h - oy ) / oh; + nt2 = *t1 * ( 1.0f - u ) + *t2 * ( u ); + + // set values + *s1 = ns1; + *s2 = ns2; + *t1 = nt1; + *t2 = nt2; + } + } + + return (*w == 0 || *h == 0) ? true : false; +} + + +void idDeviceContext::AdjustCoords(float *x, float *y, float *w, float *h) { + if (x) { + *x *= xScale; + } + if (y) { + *y *= yScale; + } + if (w) { + *w *= xScale; + } + if (h) { + *h *= yScale; + } +} + +void idDeviceContext::DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader) { + idDrawVert verts[4]; + glIndex_t indexes[6]; + indexes[0] = 3; + indexes[1] = 0; + indexes[2] = 2; + indexes[3] = 2; + indexes[4] = 0; + indexes[5] = 1; + verts[0].xyz[0] = x; + verts[0].xyz[1] = y; + verts[0].xyz[2] = 0; + verts[0].st[0] = s1; + verts[0].st[1] = t1; + verts[0].normal[0] = 0; + verts[0].normal[1] = 0; + verts[0].normal[2] = 1; + verts[0].tangents[0][0] = 1; + verts[0].tangents[0][1] = 0; + verts[0].tangents[0][2] = 0; + verts[0].tangents[1][0] = 0; + verts[0].tangents[1][1] = 1; + verts[0].tangents[1][2] = 0; + verts[1].xyz[0] = x + w; + verts[1].xyz[1] = y; + verts[1].xyz[2] = 0; + verts[1].st[0] = s2; + verts[1].st[1] = t1; + verts[1].normal[0] = 0; + verts[1].normal[1] = 0; + verts[1].normal[2] = 1; + verts[1].tangents[0][0] = 1; + verts[1].tangents[0][1] = 0; + verts[1].tangents[0][2] = 0; + verts[1].tangents[1][0] = 0; + verts[1].tangents[1][1] = 1; + verts[1].tangents[1][2] = 0; + verts[2].xyz[0] = x + w; + verts[2].xyz[1] = y + h; + verts[2].xyz[2] = 0; + verts[2].st[0] = s2; + verts[2].st[1] = t2; + verts[2].normal[0] = 0; + verts[2].normal[1] = 0; + verts[2].normal[2] = 1; + verts[2].tangents[0][0] = 1; + verts[2].tangents[0][1] = 0; + verts[2].tangents[0][2] = 0; + verts[2].tangents[1][0] = 0; + verts[2].tangents[1][1] = 1; + verts[2].tangents[1][2] = 0; + verts[3].xyz[0] = x; + verts[3].xyz[1] = y + h; + verts[3].xyz[2] = 0; + verts[3].st[0] = s1; + verts[3].st[1] = t2; + verts[3].normal[0] = 0; + verts[3].normal[1] = 0; + verts[3].normal[2] = 1; + verts[3].tangents[0][0] = 1; + verts[3].tangents[0][1] = 0; + verts[3].tangents[0][2] = 0; + verts[3].tangents[1][0] = 0; + verts[3].tangents[1][1] = 1; + verts[3].tangents[1][2] = 0; + + bool ident = !mat.IsIdentity(); + if ( ident ) { + verts[0].xyz -= origin; + verts[0].xyz *= mat; + verts[0].xyz += origin; + verts[1].xyz -= origin; + verts[1].xyz *= mat; + verts[1].xyz += origin; + verts[2].xyz -= origin; + verts[2].xyz *= mat; + verts[2].xyz += origin; + verts[3].xyz -= origin; + verts[3].xyz *= mat; + verts[3].xyz += origin; + } + + renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, ident ); + +} + + +void idDeviceContext::DrawMaterial(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex, float scaley) { + + renderSystem->SetColor(color); + + float s0, s1, t0, t1; +// +// handle negative scales as well + if ( scalex < 0 ) + { + w *= -1; + scalex *= -1; + } + if ( scaley < 0 ) + { + h *= -1; + scaley *= -1; + } +// + if( w < 0 ) { // flip about vertical + w = -w; + s0 = 1 * scalex; + s1 = 0; + } + else { + s0 = 0; + s1 = 1 * scalex; + } + + if( h < 0 ) { // flip about horizontal + h = -h; + t0 = 1 * scaley; + t1 = 0; + } + else { + t0 = 0; + t1 = 1 * scaley; + } + + if ( ClippedCoords( &x, &y, &w, &h, &s0, &t0, &s1, &t1 ) ) { + return; + } + + AdjustCoords(&x, &y, &w, &h); + + DrawStretchPic( x, y, w, h, s0, t0, s1, t1, mat); +} + +void idDeviceContext::DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex, float scaley, float angle) { + + renderSystem->SetColor(color); + + float s0, s1, t0, t1; + // + // handle negative scales as well + if ( scalex < 0 ) + { + w *= -1; + scalex *= -1; + } + if ( scaley < 0 ) + { + h *= -1; + scaley *= -1; + } + // + if( w < 0 ) { // flip about vertical + w = -w; + s0 = 1 * scalex; + s1 = 0; + } + else { + s0 = 0; + s1 = 1 * scalex; + } + + if( h < 0 ) { // flip about horizontal + h = -h; + t0 = 1 * scaley; + t1 = 0; + } + else { + t0 = 0; + t1 = 1 * scaley; + } + + if ( angle == 0.0f && ClippedCoords( &x, &y, &w, &h, &s0, &t0, &s1, &t1 ) ) { + return; + } + + AdjustCoords(&x, &y, &w, &h); + + DrawStretchPicRotated( x, y, w, h, s0, t0, s1, t1, mat, angle); +} + +void idDeviceContext::DrawStretchPicRotated(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader, float angle) { + + idDrawVert verts[4]; + glIndex_t indexes[6]; + indexes[0] = 3; + indexes[1] = 0; + indexes[2] = 2; + indexes[3] = 2; + indexes[4] = 0; + indexes[5] = 1; + verts[0].xyz[0] = x; + verts[0].xyz[1] = y; + verts[0].xyz[2] = 0; + verts[0].st[0] = s1; + verts[0].st[1] = t1; + verts[0].normal[0] = 0; + verts[0].normal[1] = 0; + verts[0].normal[2] = 1; + verts[0].tangents[0][0] = 1; + verts[0].tangents[0][1] = 0; + verts[0].tangents[0][2] = 0; + verts[0].tangents[1][0] = 0; + verts[0].tangents[1][1] = 1; + verts[0].tangents[1][2] = 0; + verts[1].xyz[0] = x + w; + verts[1].xyz[1] = y; + verts[1].xyz[2] = 0; + verts[1].st[0] = s2; + verts[1].st[1] = t1; + verts[1].normal[0] = 0; + verts[1].normal[1] = 0; + verts[1].normal[2] = 1; + verts[1].tangents[0][0] = 1; + verts[1].tangents[0][1] = 0; + verts[1].tangents[0][2] = 0; + verts[1].tangents[1][0] = 0; + verts[1].tangents[1][1] = 1; + verts[1].tangents[1][2] = 0; + verts[2].xyz[0] = x + w; + verts[2].xyz[1] = y + h; + verts[2].xyz[2] = 0; + verts[2].st[0] = s2; + verts[2].st[1] = t2; + verts[2].normal[0] = 0; + verts[2].normal[1] = 0; + verts[2].normal[2] = 1; + verts[2].tangents[0][0] = 1; + verts[2].tangents[0][1] = 0; + verts[2].tangents[0][2] = 0; + verts[2].tangents[1][0] = 0; + verts[2].tangents[1][1] = 1; + verts[2].tangents[1][2] = 0; + verts[3].xyz[0] = x; + verts[3].xyz[1] = y + h; + verts[3].xyz[2] = 0; + verts[3].st[0] = s1; + verts[3].st[1] = t2; + verts[3].normal[0] = 0; + verts[3].normal[1] = 0; + verts[3].normal[2] = 1; + verts[3].tangents[0][0] = 1; + verts[3].tangents[0][1] = 0; + verts[3].tangents[0][2] = 0; + verts[3].tangents[1][0] = 0; + verts[3].tangents[1][1] = 1; + verts[3].tangents[1][2] = 0; + + bool ident = !mat.IsIdentity(); + if ( ident ) { + verts[0].xyz -= origin; + verts[0].xyz *= mat; + verts[0].xyz += origin; + verts[1].xyz -= origin; + verts[1].xyz *= mat; + verts[1].xyz += origin; + verts[2].xyz -= origin; + verts[2].xyz *= mat; + verts[2].xyz += origin; + verts[3].xyz -= origin; + verts[3].xyz *= mat; + verts[3].xyz += origin; + } + + //Generate a translation so we can translate to the center of the image rotate and draw + idVec3 origTrans; + origTrans.x = x+(w/2); + origTrans.y = y+(h/2); + origTrans.z = 0; + + + //Rotate the verts about the z axis before drawing them + idMat4 rotz; + rotz.Identity(); + float sinAng = idMath::Sin(angle); + float cosAng = idMath::Cos(angle); + rotz[0][0] = cosAng; + rotz[0][1] = sinAng; + rotz[1][0] = -sinAng; + rotz[1][1] = cosAng; + for(int i = 0; i < 4; i++) { + //Translate to origin + verts[i].xyz -= origTrans; + + //Rotate + verts[i].xyz = rotz * verts[i].xyz; + + //Translate back + verts[i].xyz += origTrans; + } + + + renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, (angle == 0.0) ? false : true ); +} + +void idDeviceContext::DrawFilledRect( float x, float y, float w, float h, const idVec4 &color) { + + if ( color.w == 0.0f ) { + return; + } + + renderSystem->SetColor(color); + + if (ClippedCoords(&x, &y, &w, &h, NULL, NULL, NULL, NULL)) { + return; + } + + AdjustCoords(&x, &y, &w, &h); + DrawStretchPic( x, y, w, h, 0, 0, 0, 0, whiteImage); +} + + +void idDeviceContext::DrawRect( float x, float y, float w, float h, float size, const idVec4 &color) { + + if ( color.w == 0.0f ) { + return; + } + + renderSystem->SetColor(color); + + if (ClippedCoords(&x, &y, &w, &h, NULL, NULL, NULL, NULL)) { + return; + } + + AdjustCoords(&x, &y, &w, &h); + DrawStretchPic( x, y, size, h, 0, 0, 0, 0, whiteImage ); + DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, whiteImage ); + DrawStretchPic( x, y, w, size, 0, 0, 0, 0, whiteImage ); + DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, whiteImage ); +} + +void idDeviceContext::DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color) { + + if ( color.w == 0.0f ) { + return; + } + + renderSystem->SetColor(color); + DrawMaterial( x, y, size, h, mat, color ); + DrawMaterial( x + w - size, y, size, h, mat, color ); + DrawMaterial( x, y, w, size, mat, color ); + DrawMaterial( x, y + h - size, w, size, mat, color ); +} + + +void idDeviceContext::SetCursor(int n) { + cursor = (n < CURSOR_ARROW || n >= CURSOR_COUNT) ? CURSOR_ARROW : n; +} + +void idDeviceContext::DrawCursor(float *x, float *y, float size) { + if (*x < 0) { + *x = 0; + } + + if (*x >= vidWidth) { + *x = vidWidth; + } + + if (*y < 0) { + *y = 0; + } + + if (*y >= vidHeight) { + *y = vidHeight; + } + + renderSystem->SetColor(colorWhite); + AdjustCoords(x, y, &size, &size); + DrawStretchPic( *x, *y, size, size, 0, 0, 1, 1, cursorImages[cursor]); +} +/* + ======================================================================================================================= + ======================================================================================================================= + */ + +void idDeviceContext::PaintChar(float x,float y,float width,float height,float scale,float s,float t,float s2,float t2,const idMaterial *hShader) { + float w, h; + w = width * scale; + h = height * scale; + + if (ClippedCoords(&x, &y, &w, &h, &s, &t, &s2, &t2)) { + return; + } + + AdjustCoords(&x, &y, &w, &h); + DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader); +} + + +void idDeviceContext::SetFontByScale(float scale) { + if (scale <= gui_smallFontLimit.GetFloat()) { + useFont = &activeFont->fontInfoSmall; + activeFont->maxHeight = activeFont->maxHeightSmall; + activeFont->maxWidth = activeFont->maxWidthSmall; + } else if (scale <= gui_mediumFontLimit.GetFloat()) { + useFont = &activeFont->fontInfoMedium; + activeFont->maxHeight = activeFont->maxHeightMedium; + activeFont->maxWidth = activeFont->maxWidthMedium; + } else { + useFont = &activeFont->fontInfoLarge; + activeFont->maxHeight = activeFont->maxHeightLarge; + activeFont->maxWidth = activeFont->maxWidthLarge; + } +} + +int idDeviceContext::DrawText(float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor) { + int len, count; + idVec4 newColor; + const glyphInfo_t *glyph; + float useScale; + SetFontByScale(scale); + useScale = scale * useFont->glyphScale; + count = 0; + if ( text && color.w != 0.0f ) { + const unsigned char *s = (const unsigned char*)text; + renderSystem->SetColor(color); + memcpy(&newColor[0], &color[0], sizeof(idVec4)); + len = strlen(text); + if (limit > 0 && len > limit) { + len = limit; + } + + while (s && *s && count < len) { + if ( *s < GLYPH_START || *s > GLYPH_END ) { + s++; + continue; + } + glyph = &useFont->glyphs[*s]; + + // + // int yadj = Assets.textFont.glyphs[text[i]].bottom + + // Assets.textFont.glyphs[text[i]].top; float yadj = scale * + // (Assets.textFont.glyphs[text[i]].imageHeight - + // Assets.textFont.glyphs[text[i]].height); + // + if ( idStr::IsColor((const char*)s) ) { + if ( *(s+1) == C_COLOR_DEFAULT ) { + newColor = color; + } else { + newColor = idStr::ColorForIndex( *(s+1) ); + newColor[3] = color[3]; + } + if (cursor == count || cursor == count+1) { + float partialSkip = ((glyph->xSkip * useScale) + adjust) / 5.0f; + if ( cursor == count ) { + partialSkip *= 2.0f; + } else { + renderSystem->SetColor(newColor); + } + DrawEditCursor(x - partialSkip, y, scale); + } + renderSystem->SetColor(newColor); + s += 2; + count += 2; + continue; + } else { + float yadj = useScale * glyph->top; + PaintChar(x,y - yadj,glyph->imageWidth,glyph->imageHeight,useScale,glyph->s,glyph->t,glyph->s2,glyph->t2,glyph->glyph); + + if (cursor == count) { + DrawEditCursor(x, y, scale); + } + x += (glyph->xSkip * useScale) + adjust; + s++; + count++; + } + } + if (cursor == len) { + DrawEditCursor(x, y, scale); + } + } + return count; +} + +void idDeviceContext::SetSize(float width, float height) { + vidWidth = VIRTUAL_WIDTH; + vidHeight = VIRTUAL_HEIGHT; + xScale = yScale = 0.0f; + if ( width != 0.0f && height != 0.0f ) { + xScale = vidWidth * ( 1.0f / width ); + yScale = vidHeight * ( 1.0f / height ); + } +} + +int idDeviceContext::CharWidth( const char c, float scale ) { + glyphInfo_t *glyph; + float useScale; + SetFontByScale(scale); + fontInfo_t *font = useFont; + useScale = scale * font->glyphScale; + glyph = &font->glyphs[(const unsigned char)c]; + return idMath::FtoiFast( glyph->xSkip * useScale ); +} + +int idDeviceContext::TextWidth( const char *text, float scale, int limit ) { + int i, width; + + SetFontByScale( scale ); + const glyphInfo_t *glyphs = useFont->glyphs; + + if ( text == NULL ) { + return 0; + } + + width = 0; + if ( limit > 0 ) { + for ( i = 0; text[i] != '\0' && i < limit; i++ ) { + if ( idStr::IsColor( text + i ) ) { + i++; + } else { + width += glyphs[((const unsigned char *)text)[i]].xSkip; + } + } + } else { + for ( i = 0; text[i] != '\0'; i++ ) { + if ( idStr::IsColor( text + i ) ) { + i++; + } else { + width += glyphs[((const unsigned char *)text)[i]].xSkip; + } + } + } + return idMath::FtoiFast( scale * useFont->glyphScale * width ); +} + +int idDeviceContext::TextHeight(const char *text, float scale, int limit) { + int len, count; + float max; + glyphInfo_t *glyph; + float useScale; + const char *s = text; + SetFontByScale(scale); + fontInfo_t *font = useFont; + + useScale = scale * font->glyphScale; + max = 0; + if (text) { + len = strlen(text); + if (limit > 0 && len > limit) { + len = limit; + } + + count = 0; + while (s && *s && count < len) { + if ( idStr::IsColor(s) ) { + s += 2; + continue; + } + else { + glyph = &font->glyphs[*(const unsigned char*)s]; + if (max < glyph->height) { + max = glyph->height; + } + + s++; + count++; + } + } + } + + return idMath::FtoiFast( max * useScale ); +} + +int idDeviceContext::MaxCharWidth(float scale) { + SetFontByScale(scale); + float useScale = scale * useFont->glyphScale; + return idMath::FtoiFast( activeFont->maxWidth * useScale ); +} + +int idDeviceContext::MaxCharHeight(float scale) { + SetFontByScale(scale); + float useScale = scale * useFont->glyphScale; + return idMath::FtoiFast( activeFont->maxHeight * useScale ); +} + +const idMaterial *idDeviceContext::GetScrollBarImage(int index) { + if (index >= SCROLLBAR_HBACK && index < SCROLLBAR_COUNT) { + return scrollBarImages[index]; + } + return scrollBarImages[SCROLLBAR_HBACK]; +} + +// this only supports left aligned text +idRegion *idDeviceContext::GetTextRegion(const char *text, float textScale, idRectangle rectDraw, float xStart, float yStart) { +#if 0 + const char *p, *textPtr, *newLinePtr; + char buff[1024]; + int len, textWidth, newLine, newLineWidth; + float y; + + float charSkip = MaxCharWidth(textScale) + 1; + float lineSkip = MaxCharHeight(textScale); + + textWidth = 0; + newLinePtr = NULL; +#endif + return NULL; +/* + if (text == NULL) { + return; + } + + textPtr = text; + if (*textPtr == '\0') { + return; + } + + y = lineSkip + rectDraw.y + yStart; + len = 0; + buff[0] = '\0'; + newLine = 0; + newLineWidth = 0; + p = textPtr; + + textWidth = 0; + while (p) { + if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0') { + newLine = len; + newLinePtr = p + 1; + newLineWidth = textWidth; + } + + if ((newLine && textWidth > rectDraw.w) || *p == '\n' || *p == '\0') { + if (len) { + + float x = rectDraw.x ; + + buff[newLine] = '\0'; + DrawText(x, y, textScale, color, buff, 0, 0, 0); + if (!wrap) { + return; + } + } + + if (*p == '\0') { + break; + } + + y += lineSkip + 5; + p = newLinePtr; + len = 0; + newLine = 0; + newLineWidth = 0; + continue; + } + + buff[len++] = *p++; + buff[len] = '\0'; + textWidth = TextWidth( buff, textScale, -1 ); + } +*/ +} + +void idDeviceContext::DrawEditCursor( float x, float y, float scale ) { + if ( (int)( com_ticNumber >> 4 ) & 1 ) { + return; + } + SetFontByScale(scale); + float useScale = scale * useFont->glyphScale; + const glyphInfo_t *glyph2 = &useFont->glyphs[(overStrikeMode) ? '_' : '|']; + float yadj = useScale * glyph2->top; + PaintChar(x, y - yadj,glyph2->imageWidth,glyph2->imageHeight,useScale,glyph2->s,glyph2->t,glyph2->s2,glyph2->t2,glyph2->glyph); +} + +int idDeviceContext::DrawText( const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor, bool calcOnly, idList *breaks, int limit ) { + const char *p, *textPtr, *newLinePtr; + char buff[1024]; + int len, newLine, newLineWidth, count; + float y; + float textWidth; + + float charSkip = MaxCharWidth( textScale ) + 1; + float lineSkip = MaxCharHeight( textScale ); + + float cursorSkip = ( cursor >= 0 ? charSkip : 0 ); + + bool lineBreak, wordBreak; + + SetFontByScale( textScale ); + + textWidth = 0; + newLinePtr = NULL; + + if (!calcOnly && !(text && *text)) { + if (cursor == 0) { + renderSystem->SetColor(color); + DrawEditCursor(rectDraw.x, lineSkip + rectDraw.y, textScale); + } + return idMath::FtoiFast( rectDraw.w / charSkip ); + } + + textPtr = text; + + y = lineSkip + rectDraw.y; + len = 0; + buff[0] = '\0'; + newLine = 0; + newLineWidth = 0; + p = textPtr; + + if ( breaks ) { + breaks->Append(0); + } + count = 0; + textWidth = 0; + lineBreak = false; + wordBreak = false; + while (p) { + + if ( *p == '\n' || *p == '\r' || *p == '\0' ) { + lineBreak = true; + if ((*p == '\n' && *(p + 1) == '\r') || (*p == '\r' && *(p + 1) == '\n')) { + p++; + } + } + + int nextCharWidth = ( idStr::CharIsPrintable(*p) ? CharWidth( *p, textScale ) : cursorSkip ); + // FIXME: this is a temp hack until the guis can be fixed not not overflow the bounding rectangles + // the side-effect is that list boxes and edit boxes will draw over their scroll bars + // The following line and the !linebreak in the if statement below should be removed + nextCharWidth = 0; + + if ( !lineBreak && ( textWidth + nextCharWidth ) > rectDraw.w ) { + // The next character will cause us to overflow, if we haven't yet found a suitable + // break spot, set it to be this character + if ( len > 0 && newLine == 0 ) { + newLine = len; + newLinePtr = p; + newLineWidth = textWidth; + } + wordBreak = true; + } else if ( lineBreak || ( wrap && (*p == ' ' || *p == '\t') ) ) { + // The next character is in view, so if we are a break character, store our position + newLine = len; + newLinePtr = p + 1; + newLineWidth = textWidth; + } + + if ( lineBreak || wordBreak ) { + float x = rectDraw.x; + + if (textAlign == ALIGN_RIGHT) { + x = rectDraw.x + rectDraw.w - newLineWidth; + } else if (textAlign == ALIGN_CENTER) { + x = rectDraw.x + (rectDraw.w - newLineWidth) / 2; + } + + if ( wrap || newLine > 0 ) { + buff[newLine] = '\0'; + + // This is a special case to handle breaking in the middle of a word. + // if we didn't do this, the cursor would appear on the end of this line + // and the beginning of the next. + if ( wordBreak && cursor >= newLine && newLine == len ) { + cursor++; + } + } + + if (!calcOnly) { + count += DrawText(x, y, textScale, color, buff, 0, 0, 0, cursor); + } + + if ( cursor < newLine ) { + cursor = -1; + } else if ( cursor >= 0 ) { + cursor -= ( newLine + 1 ); + } + + if ( !wrap ) { + return newLine; + } + + if ( ( limit && count > limit ) || *p == '\0' ) { + break; + } + + y += lineSkip + 5; + + if ( !calcOnly && y > rectDraw.Bottom() ) { + break; + } + + p = newLinePtr; + + if (breaks) { + breaks->Append(p - text); + } + + len = 0; + newLine = 0; + newLineWidth = 0; + textWidth = 0; + lineBreak = false; + wordBreak = false; + continue; + } + + buff[len++] = *p++; + buff[len] = '\0'; + // update the width + if ( *( buff + len - 1 ) != C_COLOR_ESCAPE && (len <= 1 || *( buff + len - 2 ) != C_COLOR_ESCAPE)) { + textWidth += textScale * useFont->glyphScale * useFont->glyphs[ (const unsigned char)*( buff + len - 1 ) ].xSkip; + } + } + + return idMath::FtoiFast( rectDraw.w / charSkip ); +} + +/* +============= +idRectangle::String +============= +*/ +char *idRectangle::String( void ) const { + static int index = 0; + static char str[ 8 ][ 48 ]; + char *s; + + // use an array so that multiple toString's won't collide + s = str[ index ]; + index = (index + 1)&7; + + sprintf( s, "%.2f %.2f %.2f %.2f", x, y, w, h ); + + return s; +} diff --git a/ui/DeviceContext.h b/ui/DeviceContext.h new file mode 100644 index 000000000..3555b5e0d --- /dev/null +++ b/ui/DeviceContext.h @@ -0,0 +1,159 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __DEVICECONTEXT_H__ +#define __DEVICECONTEXT_H__ + +// device context support for gui stuff +// + +#include "Rectangle.h" + +const int VIRTUAL_WIDTH = 640; +const int VIRTUAL_HEIGHT = 480; +const int BLINK_DIVISOR = 200; + +class idDeviceContext { +public: + idDeviceContext(); + ~idDeviceContext() { } + + void Init(); + void Shutdown(); + bool Initialized() { return initialized; } + void EnableLocalization(); + + void GetTransformInfo(idVec3& origin, idMat3& mat ); + + void SetTransformInfo(const idVec3 &origin, const idMat3 &mat); + void DrawMaterial(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex = 1.0, float scaley = 1.0); + void DrawRect(float x, float y, float width, float height, float size, const idVec4 &color); + void DrawFilledRect(float x, float y, float width, float height, const idVec4 &color); + int DrawText(const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor = -1, bool calcOnly = false, idList *breaks = NULL, int limit = 0 ); + void DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color); + void DrawStretchPic(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat); + + void DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex = 1.0, float scaley = 1.0, float angle = 0.0f); + void DrawStretchPicRotated(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat, float angle = 0.0f); + + int CharWidth( const char c, float scale ); + int TextWidth(const char *text, float scale, int limit); + int TextHeight(const char *text, float scale, int limit); + int MaxCharHeight(float scale); + int MaxCharWidth(float scale); + + int FindFont( const char *name ); + void SetupFonts(); + + idRegion *GetTextRegion(const char *text, float textScale, idRectangle rectDraw, float xStart, float yStart); + + void SetSize(float width, float height); + + const idMaterial *GetScrollBarImage(int index); + + void DrawCursor(float *x, float *y, float size); + void SetCursor(int n); + + void AdjustCoords(float *x, float *y, float *w, float *h); + bool ClippedCoords(float *x, float *y, float *w, float *h); + bool ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2); + + void PushClipRect(float x, float y, float w, float h); + void PushClipRect(idRectangle r); + void PopClipRect(); + + void EnableClipping(bool b) { enableClipping = b; }; + void SetFont( int num ); + + void SetOverStrike(bool b) { overStrikeMode = b; } + + bool GetOverStrike() { return overStrikeMode; } + + void DrawEditCursor(float x, float y, float scale); + + enum { + CURSOR_ARROW, + CURSOR_HAND, + CURSOR_COUNT + }; + + enum { + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT + }; + + enum { + SCROLLBAR_HBACK, + SCROLLBAR_VBACK, + SCROLLBAR_THUMB, + SCROLLBAR_RIGHT, + SCROLLBAR_LEFT, + SCROLLBAR_UP, + SCROLLBAR_DOWN, + SCROLLBAR_COUNT + }; + + static idVec4 colorPurple; + static idVec4 colorOrange; + static idVec4 colorYellow; + static idVec4 colorGreen; + static idVec4 colorBlue; + static idVec4 colorRed; + static idVec4 colorWhite; + static idVec4 colorBlack; + static idVec4 colorNone; + +private: + int DrawText(float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor = -1); + void PaintChar(float x,float y,float width,float height,float scale,float s,float t,float s2,float t2,const idMaterial *hShader); + void SetFontByScale( float scale ); + void Clear( void ); + + const idMaterial *cursorImages[CURSOR_COUNT]; + const idMaterial *scrollBarImages[SCROLLBAR_COUNT]; + const idMaterial *whiteImage; + fontInfoEx_t *activeFont; + fontInfo_t *useFont; + idStr fontName; + float xScale; + float yScale; + + float vidHeight; + float vidWidth; + + int cursor; + + idList clipRects; + + static idList fonts; + idStr fontLang; + + bool enableClipping; + + bool overStrikeMode; + + idMat3 mat; + idVec3 origin; + bool initialized; + + bool mbcs; +}; + +#endif /* !__DEVICECONTEXT_H__ */ diff --git a/ui/EditWindow.cpp b/ui/EditWindow.cpp new file mode 100644 index 000000000..2b63fb824 --- /dev/null +++ b/ui/EditWindow.cpp @@ -0,0 +1,639 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "SliderWindow.h" +#include "EditWindow.h" + + +bool idEditWindow::ParseInternalVar( const char *_name, idParser *src ) { + if ( idStr::Icmp( _name, "maxchars" ) == 0) { + maxChars = src->ParseInt(); + return true; + } + if ( idStr::Icmp( _name, "numeric" ) == 0) { + numeric = src->ParseBool(); + return true; + } + if ( idStr::Icmp( _name, "wrap" ) == 0) { + wrap = src->ParseBool(); + return true; + } + if ( idStr::Icmp( _name, "readonly" ) == 0) { + readonly = src->ParseBool(); + return true; + } + if ( idStr::Icmp( _name, "forceScroll" ) == 0) { + forceScroll = src->ParseBool(); + return true; + } + if ( idStr::Icmp( _name, "source" ) == 0) { + ParseString( src, sourceFile ); + return true; + } + if ( idStr::Icmp( _name, "password" ) == 0 ) { + password = src->ParseBool(); + return true; + } + if ( idStr::Icmp( _name, "cvarMax" ) == 0) { + cvarMax = src->ParseInt(); + return true; + } + + return idWindow::ParseInternalVar( _name, src ); +} + +idWinVar *idEditWindow::GetWinVarByName( const char *_name, bool fixup, drawWin_t** owner ) { + if ( idStr::Icmp( _name, "cvar" ) == 0 ) { + return &cvarStr; + } + if ( idStr::Icmp( _name, "password" ) == 0 ) { + return &password; + } + if ( idStr::Icmp( _name, "liveUpdate" ) == 0 ) { + return &liveUpdate; + } + if ( idStr::Icmp( _name, "cvarGroup" ) == 0 ) { + return &cvarGroup; + } + return idWindow::GetWinVarByName( _name, fixup, owner ); +} + +void idEditWindow::CommonInit() { + maxChars = 128; + numeric = false; + paintOffset = 0; + cursorPos = 0; + cursorLine = 0; + cvarMax = 0; + wrap = false; + sourceFile = ""; + scroller = NULL; + sizeBias = 0; + lastTextLength = 0; + forceScroll = false; + password = false; + cvar = NULL; + liveUpdate = true; + readonly = false; + + scroller = new idSliderWindow(dc, gui); +} + + +idEditWindow::idEditWindow( idDeviceContext *d, idUserInterfaceLocal *g ) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idEditWindow::idEditWindow( idUserInterfaceLocal *g ) : idWindow(g) { + gui = g; + CommonInit(); +} + +idEditWindow::~idEditWindow() { + +} + +void idEditWindow::GainFocus() { + cursorPos = text.Length(); + EnsureCursorVisible(); +} + +void idEditWindow::Draw( int time, float x, float y ) { + idVec4 color = foreColor; + + UpdateCvar( true ); + + int len = text.Length(); + if ( len != lastTextLength ) { + scroller->SetValue( 0.0f ); + EnsureCursorVisible(); + lastTextLength = len; + } + float scale = textScale; + + idStr pass; + const char* buffer; + if ( password ) { + const char* temp = text; + for ( ; *temp; temp++ ) { + pass += "*"; + } + buffer = pass; + } else { + buffer = text; + } + + if ( cursorPos > len ) { + cursorPos = len; + } + + idRectangle rect = textRect; + + rect.x -= paintOffset; + rect.w += paintOffset; + + if ( wrap && scroller->GetHigh() > 0.0f ) { + float lineHeight = GetMaxCharHeight( ) + 5; + rect.y -= scroller->GetValue() * lineHeight; + rect.w -= sizeBias; + rect.h = ( breaks.Num() + 1 ) * lineHeight; + } + + if ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) { + color = hoverColor; + } else { + hover = false; + } + if ( flags & WIN_FOCUS ) { + color = hoverColor; + } + + dc->DrawText( buffer, scale, 0, color, rect, wrap, (flags & WIN_FOCUS) ? cursorPos : -1); +} + +/* +============= +idEditWindow::HandleEvent +============= +*/ +const char *idEditWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + static char buffer[ MAX_EDITFIELD ]; + const char *ret = ""; + + if ( wrap ) { + // need to call this to allow proper focus and capturing on embedded children + ret = idWindow::HandleEvent( event, updateVisuals ); + if ( ret && *ret ) { + return ret; + } + } + + if ( ( event->evType != SE_CHAR && event->evType != SE_KEY ) ) { + return ret; + } + + idStr::Copynz( buffer, text.c_str(), sizeof( buffer ) ); + int key = event->evValue; + int len = text.Length(); + + if ( event->evType == SE_CHAR ) { + if ( event->evValue == Sys_GetConsoleKey( false ) || event->evValue == Sys_GetConsoleKey( true ) ) { + return ""; + } + + if ( updateVisuals ) { + *updateVisuals = true; + } + + if ( maxChars && len > maxChars ) { + len = maxChars; + } + + if ( ( key == K_ENTER || key == K_KP_ENTER ) && event->evValue2 ) { + RunScript( ON_ACTION ); + RunScript( ON_ENTER ); + return cmd; + } + + if ( key == K_ESCAPE ) { + RunScript( ON_ESC ); + return cmd; + } + + if ( readonly ) { + return ""; + } + + if ( key == 'h' - 'a' + 1 || key == K_BACKSPACE ) { // ctrl-h is backspace + if ( cursorPos > 0 ) { + if ( cursorPos >= len ) { + buffer[len - 1] = 0; + cursorPos = len - 1; + } else { + memmove( &buffer[ cursorPos - 1 ], &buffer[ cursorPos ], len + 1 - cursorPos); + cursorPos--; + } + + text = buffer; + UpdateCvar( false ); + RunScript( ON_ACTION ); + } + + return ""; + } + + // + // ignore any non printable chars (except enter when wrap is enabled) + // + if ( wrap && (key == K_ENTER || key == K_KP_ENTER) ) { + } else if ( !idStr::CharIsPrintable( key ) ) { + return ""; + } + + if ( numeric ) { + if ( ( key < '0' || key > '9' ) && key != '.' ) { + return ""; + } + } + + if ( dc->GetOverStrike() ) { + if ( maxChars && cursorPos >= maxChars ) { + return ""; + } + } else { + if ( ( len == MAX_EDITFIELD - 1 ) || ( maxChars && len >= maxChars ) ) { + return ""; + } + memmove( &buffer[ cursorPos + 1 ], &buffer[ cursorPos ], len + 1 - cursorPos ); + } + + buffer[ cursorPos ] = key; + + text = buffer; + UpdateCvar( false ); + RunScript( ON_ACTION ); + + if ( cursorPos < len + 1 ) { + cursorPos++; + } + EnsureCursorVisible(); + + } else if ( event->evType == SE_KEY && event->evValue2 ) { + + if ( updateVisuals ) { + *updateVisuals = true; + } + + if ( key == K_DEL ) { + if ( readonly ) { + return ret; + } + if ( cursorPos < len ) { + memmove( &buffer[cursorPos], &buffer[cursorPos + 1], len - cursorPos); + text = buffer; + UpdateCvar( false ); + RunScript( ON_ACTION ); + } + return ret; + } + + if ( key == K_RIGHTARROW ) { + if ( cursorPos < len ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + // skip to next word + while( ( cursorPos < len ) && ( buffer[ cursorPos ] != ' ' ) ) { + cursorPos++; + } + + while( ( cursorPos < len ) && ( buffer[ cursorPos ] == ' ' ) ) { + cursorPos++; + } + } else { + if ( cursorPos < len ) { + cursorPos++; + } + } + } + + EnsureCursorVisible(); + + return ret; + } + + if ( key == K_LEFTARROW ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + // skip to previous word + while( ( cursorPos > 0 ) && ( buffer[ cursorPos - 1 ] == ' ' ) ) { + cursorPos--; + } + + while( ( cursorPos > 0 ) && ( buffer[ cursorPos - 1 ] != ' ' ) ) { + cursorPos--; + } + } else { + if ( cursorPos > 0 ) { + cursorPos--; + } + } + + EnsureCursorVisible(); + + return ret; + } + + if ( key == K_HOME ) { + if ( idKeyInput::IsDown( K_CTRL ) || cursorLine <= 0 || ( cursorLine >= breaks.Num() ) ) { + cursorPos = 0; + } else { + cursorPos = breaks[cursorLine]; + } + EnsureCursorVisible(); + return ret; + } + + if ( key == K_END ) { + if ( idKeyInput::IsDown( K_CTRL ) || (cursorLine < -1) || ( cursorLine >= breaks.Num() - 1 ) ) { + cursorPos = len; + } else { + cursorPos = breaks[cursorLine + 1] - 1; + } + EnsureCursorVisible(); + return ret; + } + + if ( key == K_INS ) { + if ( !readonly ) { + dc->SetOverStrike( !dc->GetOverStrike() ); + } + return ret; + } + + if ( key == K_DOWNARROW ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + scroller->SetValue( scroller->GetValue() + 1.0f ); + } else { + if ( cursorLine < breaks.Num() - 1 ) { + int offset = cursorPos - breaks[cursorLine]; + cursorPos = breaks[cursorLine + 1] + offset; + EnsureCursorVisible(); + } + } + } + + if (key == K_UPARROW ) { + if ( idKeyInput::IsDown( K_CTRL ) ) { + scroller->SetValue( scroller->GetValue() - 1.0f ); + } else { + if ( cursorLine > 0 ) { + int offset = cursorPos - breaks[cursorLine]; + cursorPos = breaks[cursorLine - 1] + offset; + EnsureCursorVisible(); + } + } + } + + if ( key == K_ENTER || key == K_KP_ENTER ) { + RunScript( ON_ACTION ); + RunScript( ON_ENTER ); + return cmd; + } + + if ( key == K_ESCAPE ) { + RunScript( ON_ESC ); + return cmd; + } + + } else if ( event->evType == SE_KEY && !event->evValue2 ) { + if ( key == K_ENTER || key == K_KP_ENTER ) { + RunScript( ON_ENTERRELEASE ); + return cmd; + } else { + RunScript( ON_ACTIONRELEASE ); + } + } + + return ret; +} + +void idEditWindow::PostParse() { + idWindow::PostParse(); + + if ( maxChars == 0 ) { + maxChars = 10; + } + if ( sourceFile.Length() ) { + void *buffer; + fileSystem->ReadFile( sourceFile, &buffer ); + text = (char *) buffer; + fileSystem->FreeFile( buffer ); + } + + InitCvar(); + InitScroller(false); + + EnsureCursorVisible(); + + flags |= WIN_CANFOCUS; +} + +/* +================ +idEditWindow::InitScroller + +This is the same as in idListWindow +================ +*/ +void idEditWindow::InitScroller( bool horizontal ) +{ + const char *thumbImage = "guis/assets/scrollbar_thumb.tga"; + const char *barImage = "guis/assets/scrollbarv.tga"; + const char *scrollerName = "_scrollerWinV"; + + if (horizontal) { + barImage = "guis/assets/scrollbarh.tga"; + scrollerName = "_scrollerWinH"; + } + + const idMaterial *mat = declManager->FindMaterial( barImage ); + mat->SetSort( SS_GUI ); + sizeBias = mat->GetImageWidth(); + + idRectangle scrollRect; + if (horizontal) { + sizeBias = mat->GetImageHeight(); + scrollRect.x = 0; + scrollRect.y = (clientRect.h - sizeBias); + scrollRect.w = clientRect.w; + scrollRect.h = sizeBias; + } else { + scrollRect.x = (clientRect.w - sizeBias); + scrollRect.y = 0; + scrollRect.w = sizeBias; + scrollRect.h = clientRect.h; + } + + scroller->InitWithDefaults(scrollerName, scrollRect, foreColor, matColor, mat->GetName(), thumbImage, !horizontal, true); + InsertChild(scroller, NULL); + scroller->SetBuddy(this); +} + +void idEditWindow::HandleBuddyUpdate( idWindow *buddy ) { +} + +void idEditWindow::EnsureCursorVisible() +{ + if ( readonly ) { + cursorPos = -1; + } else if ( maxChars == 1 ) { + cursorPos = 0; + } + + if ( !dc ) { + return; + } + + SetFont(); + if ( !wrap ) { + int cursorX = 0; + if ( password ) { + cursorX = cursorPos * dc->CharWidth( '*', textScale ); + } else { + int i = 0; + while ( i < text.Length() && i < cursorPos ) { + if ( idStr::IsColor( &text[i] ) ) { + i += 2; + } else { + cursorX += dc->CharWidth( text[i], textScale ); + i++; + } + } + } + int maxWidth = GetMaxCharWidth( ); + int left = cursorX - maxWidth; + int right = ( cursorX - textRect.w ) + maxWidth; + + if ( paintOffset > left ) { + // When we go past the left side, we want the text to jump 6 characters + paintOffset = left - maxWidth * 6; + } + if ( paintOffset < right) { + paintOffset = right; + } + if ( paintOffset < 0 ) { + paintOffset = 0; + } + scroller->SetRange(0.0f, 0.0f, 1.0f); + + } else { + // Word wrap + + breaks.Clear(); + idRectangle rect = textRect; + rect.w -= sizeBias; + dc->DrawText(text, textScale, textAlign, colorWhite, rect, true, (flags & WIN_FOCUS) ? cursorPos : -1, true, &breaks ); + + int fit = textRect.h / (GetMaxCharHeight() + 5); + if ( fit < breaks.Num() + 1 ) { + scroller->SetRange(0, breaks.Num() + 1 - fit, 1); + } else { + // The text fits completely in the box + scroller->SetRange(0.0f, 0.0f, 1.0f); + } + + if ( forceScroll ) { + scroller->SetValue( breaks.Num() - fit ); + } else if ( readonly ) { + } else { + cursorLine = 0; + for ( int i = 1; i < breaks.Num(); i++ ) { + if ( cursorPos >= breaks[i] ) { + cursorLine = i; + } else { + break; + } + } + int topLine = idMath::FtoiFast( scroller->GetValue() ); + if ( cursorLine < topLine ) { + scroller->SetValue( cursorLine ); + } else if ( cursorLine >= topLine + fit) { + scroller->SetValue( ( cursorLine - fit ) + 1 ); + } + } + } +} + +void idEditWindow::Activate(bool activate, idStr &act) { + idWindow::Activate(activate, act); + if ( activate ) { + UpdateCvar( true, true ); + EnsureCursorVisible(); + } +} + +/* +============ +idEditWindow::InitCvar +============ +*/ +void idEditWindow::InitCvar( ) { + if ( cvarStr[0] == '\0' ) { + if ( text.GetName() == NULL ) { + common->Warning( "idEditWindow::InitCvar: gui '%s' window '%s' has an empty cvar string", gui->GetSourceFile(), name.c_str() ); + } + cvar = NULL; + return; + } + + cvar = cvarSystem->Find( cvarStr ); + if ( !cvar ) { + common->Warning( "idEditWindow::InitCvar: gui '%s' window '%s' references undefined cvar '%s'", gui->GetSourceFile(), name.c_str(), cvarStr.c_str() ); + return; + } +} + +/* +============ +idEditWindow::UpdateCvar +============ +*/ +void idEditWindow::UpdateCvar( bool read, bool force ) { + if ( force || liveUpdate ) { + if ( cvar ) { + if ( read ) { + text = cvar->GetString(); + } else { + cvar->SetString( text ); + if ( cvarMax && ( cvar->GetInteger() > cvarMax ) ) { + cvar->SetInteger( cvarMax ); + } + } + } + } +} + +/* +============ +idEditWindow::RunNamedEvent +============ +*/ +void idEditWindow::RunNamedEvent( const char* eventName ) { + idStr event, group; + + if ( !idStr::Cmpn( eventName, "cvar read ", 10 ) ) { + event = eventName; + group = event.Mid( 10, event.Length() - 10 ); + if ( !group.Cmp( cvarGroup ) ) { + UpdateCvar( true, true ); + } + } else if ( !idStr::Cmpn( eventName, "cvar write ", 11 ) ) { + event = eventName; + group = event.Mid( 11, event.Length() - 11 ); + if ( !group.Cmp( cvarGroup ) ) { + UpdateCvar( false, true ); + } + } +} diff --git a/ui/EditWindow.h b/ui/EditWindow.h new file mode 100644 index 000000000..5ed37c168 --- /dev/null +++ b/ui/EditWindow.h @@ -0,0 +1,87 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __EDITWINDOW_H__ +#define __EDITWINDOW_H__ + +#include "Window.h" + +const int MAX_EDITFIELD = 4096; + +class idUserInterfaceLocal; +class idSliderWindow; + +class idEditWindow : public idWindow { +public: + idEditWindow(idUserInterfaceLocal *gui); + idEditWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idEditWindow(); + + virtual void Draw( int time, float x, float y ); + virtual const char *HandleEvent( const sysEvent_t *event, bool *updateVisuals ); + virtual void PostParse(); + virtual void GainFocus(); + virtual size_t Allocated(){return idWindow::Allocated();}; + + virtual idWinVar * GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL ); + + virtual void HandleBuddyUpdate(idWindow *buddy); + virtual void Activate(bool activate, idStr &act); + + void RunNamedEvent( const char* eventName ); + +private: + + virtual bool ParseInternalVar(const char *name, idParser *src); + + void InitCvar(); + // true: read the updated cvar from cvar system + // false: write to the cvar system + // force == true overrides liveUpdate 0 + void UpdateCvar( bool read, bool force = false ); + + void CommonInit(); + void EnsureCursorVisible(); + void InitScroller( bool horizontal ); + + int maxChars; + int paintOffset; + int cursorPos; + int cursorLine; + int cvarMax; + bool wrap; + bool readonly; + bool numeric; + idStr sourceFile; + idSliderWindow * scroller; + idList breaks; + float sizeBias; + int textIndex; + int lastTextLength; + bool forceScroll; + idWinBool password; + + idWinStr cvarStr; + idCVar * cvar; + + idWinBool liveUpdate; + idWinStr cvarGroup; +}; + +#endif /* !__EDITWINDOW_H__ */ diff --git a/ui/FieldWindow.cpp b/ui/FieldWindow.cpp new file mode 100644 index 000000000..d49c7f8aa --- /dev/null +++ b/ui/FieldWindow.cpp @@ -0,0 +1,96 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "FieldWindow.h" + + +void idFieldWindow::CommonInit() { + cursorPos = 0; + lastTextLength = 0; + lastCursorPos = 0; + paintOffset = 0; + showCursor = false; +} + +idFieldWindow::idFieldWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idFieldWindow::idFieldWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idFieldWindow::~idFieldWindow() { + +} + +bool idFieldWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "cursorvar") == 0) { + ParseString(src, cursorVar); + return true; + } + if (idStr::Icmp(_name, "showcursor") == 0) { + showCursor = src->ParseBool(); + return true; + } + return idWindow::ParseInternalVar(_name, src); +} + + +void idFieldWindow::CalcPaintOffset(int len) { + lastCursorPos = cursorPos; + lastTextLength = len; + paintOffset = 0; + int tw = dc->TextWidth(text, textScale, -1); + if (tw < textRect.w) { + return; + } + while (tw > textRect.w && len > 0) { + tw = dc->TextWidth(text, textScale, --len); + paintOffset++; + } +} + + +void idFieldWindow::Draw(int time, float x, float y) { + float scale = textScale; + int len = text.Length(); + cursorPos = gui->State().GetInt( cursorVar ); + if (len != lastTextLength || cursorPos != lastCursorPos) { + CalcPaintOffset(len); + } + idRectangle rect = textRect; + if (paintOffset >= len) { + paintOffset = 0; + } + if (cursorPos > len) { + cursorPos = len; + } + dc->DrawText(&text[paintOffset], scale, 0, foreColor, rect, false, ((flags & WIN_FOCUS) || showCursor) ? cursorPos - paintOffset : -1); +} + diff --git a/ui/FieldWindow.h b/ui/FieldWindow.h new file mode 100644 index 000000000..6b935a2e7 --- /dev/null +++ b/ui/FieldWindow.h @@ -0,0 +1,45 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __FIELDWINDOW_H +#define __FIELDWINDOW_H + +#include "Window.h" + + +class idFieldWindow : public idWindow { +public: + idFieldWindow(idUserInterfaceLocal *gui); + idFieldWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idFieldWindow(); + + virtual void Draw(int time, float x, float y); + +private: + virtual bool ParseInternalVar(const char *name, idParser *src); + void CommonInit(); + void CalcPaintOffset(int len); + int cursorPos; + int lastTextLength; + int lastCursorPos; + int paintOffset; + bool showCursor; + idStr cursorVar; +}; + +#endif // __FIELDWINDOW_H diff --git a/ui/GameBearShootWindow.cpp b/ui/GameBearShootWindow.cpp new file mode 100644 index 000000000..2e0552569 --- /dev/null +++ b/ui/GameBearShootWindow.cpp @@ -0,0 +1,886 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "../framework/Session_local.h" + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "GameBearShootWindow.h" + + +#define BEAR_GRAVITY 240 +#define BEAR_SIZE 24.f +#define BEAR_SHRINK_TIME 2000.f + +#define MAX_WINDFORCE 100.f + +idCVar bearTurretAngle( "bearTurretAngle", "0", CVAR_FLOAT, "" ); +idCVar bearTurretForce( "bearTurretForce", "200", CVAR_FLOAT, "" ); + +/* +***************************************************************************** +* BSEntity +**************************************************************************** +*/ +BSEntity::BSEntity(idGameBearShootWindow* _game) { + game = _game; + visible = true; + + entColor = colorWhite; + materialName = ""; + material = NULL; + width = height = 8; + rotation = 0.f; + rotationSpeed = 0.f; + fadeIn = false; + fadeOut = false; + + position.Zero(); + velocity.Zero(); +} + +BSEntity::~BSEntity() { +} + +/* +====================== +BSEntity::WriteToSaveGame +====================== +*/ +void BSEntity::WriteToSaveGame( idFile *savefile ) { + + game->WriteSaveGameString( materialName, savefile ); + + savefile->Write( &width, sizeof(width) ); + savefile->Write( &height, sizeof(height) ); + savefile->Write( &visible, sizeof(visible) ); + + savefile->Write( &entColor, sizeof(entColor) ); + savefile->Write( &position, sizeof(position) ); + savefile->Write( &rotation, sizeof(rotation) ); + savefile->Write( &rotationSpeed, sizeof(rotationSpeed) ); + savefile->Write( &velocity, sizeof(velocity) ); + + savefile->Write( &fadeIn, sizeof(fadeIn) ); + savefile->Write( &fadeOut, sizeof(fadeOut) ); +} + +/* +====================== +BSEntity::ReadFromSaveGame +====================== +*/ +void BSEntity::ReadFromSaveGame( idFile *savefile, idGameBearShootWindow* _game ) { + game = _game; + + game->ReadSaveGameString( materialName, savefile ); + SetMaterial( materialName ); + + savefile->Read( &width, sizeof(width) ); + savefile->Read( &height, sizeof(height) ); + savefile->Read( &visible, sizeof(visible) ); + + savefile->Read( &entColor, sizeof(entColor) ); + savefile->Read( &position, sizeof(position) ); + savefile->Read( &rotation, sizeof(rotation) ); + savefile->Read( &rotationSpeed, sizeof(rotationSpeed) ); + savefile->Read( &velocity, sizeof(velocity) ); + + savefile->Read( &fadeIn, sizeof(fadeIn) ); + savefile->Read( &fadeOut, sizeof(fadeOut) ); +} + +/* +====================== +BSEntity::SetMaterial +====================== +*/ +void BSEntity::SetMaterial(const char* name) { + materialName = name; + material = declManager->FindMaterial( name ); + material->SetSort( SS_GUI ); +} + +/* +====================== +BSEntity::SetSize +====================== +*/ +void BSEntity::SetSize( float _width, float _height ) { + width = _width; + height = _height; +} + +/* +====================== +BSEntity::SetVisible +====================== +*/ +void BSEntity::SetVisible( bool isVisible ) { + visible = isVisible; +} + +/* +====================== +BSEntity::Update +====================== +*/ +void BSEntity::Update( float timeslice ) { + + if ( !visible ) { + return; + } + + // Fades + if ( fadeIn && entColor.w < 1.f ) { + entColor.w += 1 * timeslice; + if ( entColor.w >= 1.f ) { + entColor.w = 1.f; + fadeIn = false; + } + } + if ( fadeOut && entColor.w > 0.f ) { + entColor.w -= 1 * timeslice; + if ( entColor.w <= 0.f ) { + entColor.w = 0.f; + fadeOut = false; + } + } + + // Move the entity + position += velocity * timeslice; + + // Rotate Entity + rotation += rotationSpeed * timeslice; +} + +/* +====================== +BSEntity::Draw +====================== +*/ +void BSEntity::Draw(idDeviceContext *dc) { + if ( visible ) { + dc->DrawMaterialRotated( position.x, position.y, width, height, material, entColor, 1.0f, 1.0f, DEG2RAD(rotation) ); + } +} + +/* +***************************************************************************** +* idGameBearShootWindow +**************************************************************************** +*/ +idGameBearShootWindow::idGameBearShootWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idGameBearShootWindow::idGameBearShootWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idGameBearShootWindow::~idGameBearShootWindow() { + entities.DeleteContents(true); +} + +/* +============================= +idGameBearShootWindow::WriteToSaveGame +============================= +*/ +void idGameBearShootWindow::WriteToSaveGame( idFile *savefile ) { + idWindow::WriteToSaveGame( savefile ); + + gamerunning.WriteToSaveGame( savefile ); + onFire.WriteToSaveGame( savefile ); + onContinue.WriteToSaveGame( savefile ); + onNewGame.WriteToSaveGame( savefile ); + + savefile->Write( &timeSlice, sizeof(timeSlice) ); + savefile->Write( &timeRemaining, sizeof(timeRemaining) ); + savefile->Write( &gameOver, sizeof(gameOver) ); + + savefile->Write( ¤tLevel, sizeof(currentLevel) ); + savefile->Write( &goalsHit, sizeof(goalsHit) ); + savefile->Write( &updateScore, sizeof(updateScore) ); + savefile->Write( &bearHitTarget, sizeof(bearHitTarget) ); + + savefile->Write( &bearScale, sizeof(bearScale) ); + savefile->Write( &bearIsShrinking, sizeof(bearIsShrinking) ); + savefile->Write( &bearShrinkStartTime, sizeof(bearShrinkStartTime) ); + + savefile->Write( &turretAngle, sizeof(turretAngle) ); + savefile->Write( &turretForce, sizeof(turretForce) ); + + savefile->Write( &windForce, sizeof(windForce) ); + savefile->Write( &windUpdateTime, sizeof(windUpdateTime) ); + + int numberOfEnts = entities.Num(); + savefile->Write( &numberOfEnts, sizeof(numberOfEnts) ); + + for ( int i=0; iWriteToSaveGame( savefile ); + } + + int index; + index = entities.FindIndex( turret ); + savefile->Write( &index, sizeof(index) ); + index = entities.FindIndex( bear ); + savefile->Write( &index, sizeof(index) ); + index = entities.FindIndex( helicopter ); + savefile->Write( &index, sizeof(index) ); + index = entities.FindIndex( goal ); + savefile->Write( &index, sizeof(index) ); + index = entities.FindIndex( wind ); + savefile->Write( &index, sizeof(index) ); + index = entities.FindIndex( gunblast ); + savefile->Write( &index, sizeof(index) ); +} + +/* +============================= +idGameBearShootWindow::ReadFromSaveGame +============================= +*/ +void idGameBearShootWindow::ReadFromSaveGame( idFile *savefile ) { + idWindow::ReadFromSaveGame( savefile ); + + // Remove all existing entities + entities.DeleteContents(true); + + gamerunning.ReadFromSaveGame( savefile ); + onFire.ReadFromSaveGame( savefile ); + onContinue.ReadFromSaveGame( savefile ); + onNewGame.ReadFromSaveGame( savefile ); + + savefile->Read( &timeSlice, sizeof(timeSlice) ); + savefile->Read( &timeRemaining, sizeof(timeRemaining) ); + savefile->Read( &gameOver, sizeof(gameOver) ); + + savefile->Read( ¤tLevel, sizeof(currentLevel) ); + savefile->Read( &goalsHit, sizeof(goalsHit) ); + savefile->Read( &updateScore, sizeof(updateScore) ); + savefile->Read( &bearHitTarget, sizeof(bearHitTarget) ); + + savefile->Read( &bearScale, sizeof(bearScale) ); + savefile->Read( &bearIsShrinking, sizeof(bearIsShrinking) ); + savefile->Read( &bearShrinkStartTime, sizeof(bearShrinkStartTime) ); + + savefile->Read( &turretAngle, sizeof(turretAngle) ); + savefile->Read( &turretForce, sizeof(turretForce) ); + + savefile->Read( &windForce, sizeof(windForce) ); + savefile->Read( &windUpdateTime, sizeof(windUpdateTime) ); + + int numberOfEnts; + savefile->Read( &numberOfEnts, sizeof(numberOfEnts) ); + + for ( int i=0; iReadFromSaveGame( savefile, this ); + entities.Append( ent ); + } + + int index; + savefile->Read( &index, sizeof(index) ); + turret = entities[index]; + savefile->Read( &index, sizeof(index) ); + bear = entities[index]; + savefile->Read( &index, sizeof(index) ); + helicopter = entities[index]; + savefile->Read( &index, sizeof(index) ); + goal = entities[index]; + savefile->Read( &index, sizeof(index) ); + wind = entities[index]; + savefile->Read( &index, sizeof(index) ); + gunblast = entities[index]; +} + +/* +============================= +idGameBearShootWindow::ResetGameState +============================= +*/ +void idGameBearShootWindow::ResetGameState() { + gamerunning = false; + gameOver = false; + onFire = false; + onContinue = false; + onNewGame = false; + + // Game moves forward 16 milliseconds every frame + timeSlice = 0.016f; + timeRemaining = 60.f; + goalsHit = 0; + updateScore = false; + bearHitTarget = false; + currentLevel = 1; + turretAngle = 0.f; + turretForce = 200.f; + windForce = 0.f; + windUpdateTime = 0; + + bearIsShrinking = false; + bearShrinkStartTime = 0; + bearScale = 1.f; +} + +/* +============================= +idGameBearShootWindow::CommonInit +============================= +*/ +void idGameBearShootWindow::CommonInit() { + BSEntity * ent; + + // Precache sounds + declManager->FindSound( "arcade_beargroan" ); + declManager->FindSound( "arcade_sargeshoot" ); + declManager->FindSound( "arcade_balloonpop" ); + declManager->FindSound( "arcade_levelcomplete1" ); + + // Precache dynamically used materials + declManager->FindMaterial( "game/bearshoot/helicopter_broken" ); + declManager->FindMaterial( "game/bearshoot/goal_dead" ); + declManager->FindMaterial( "game/bearshoot/gun_blast" ); + + ResetGameState(); + + ent = new BSEntity( this ); + turret = ent; + ent->SetMaterial( "game/bearshoot/turret" ); + ent->SetSize( 272, 144 ); + ent->position.x = -44; + ent->position.y = 260; + entities.Append( ent ); + + ent = new BSEntity( this ); + ent->SetMaterial( "game/bearshoot/turret_base" ); + ent->SetSize( 144, 160 ); + ent->position.x = 16; + ent->position.y = 280; + entities.Append( ent ); + + ent = new BSEntity( this ); + bear = ent; + ent->SetMaterial( "game/bearshoot/bear" ); + ent->SetSize( BEAR_SIZE, BEAR_SIZE ); + ent->SetVisible( false ); + ent->position.x = 0; + ent->position.y = 0; + entities.Append( ent ); + + ent = new BSEntity( this ); + helicopter = ent; + ent->SetMaterial( "game/bearshoot/helicopter" ); + ent->SetSize( 64, 64 ); + ent->position.x = 550; + ent->position.y = 100; + entities.Append( ent ); + + ent = new BSEntity( this ); + goal = ent; + ent->SetMaterial( "game/bearshoot/goal" ); + ent->SetSize( 64, 64 ); + ent->position.x = 550; + ent->position.y = 164; + entities.Append( ent ); + + ent = new BSEntity( this ); + wind = ent; + ent->SetMaterial( "game/bearshoot/wind" ); + ent->SetSize( 100, 40 ); + ent->position.x = 500; + ent->position.y = 430; + entities.Append( ent ); + + ent = new BSEntity( this ); + gunblast = ent; + ent->SetMaterial( "game/bearshoot/gun_blast" ); + ent->SetSize( 64, 64 ); + ent->SetVisible( false ); + entities.Append( ent ); +} + +/* +============================= +idGameBearShootWindow::HandleEvent +============================= +*/ +const char *idGameBearShootWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + int key = event->evValue; + + // need to call this to allow proper focus and capturing on embedded children + const char *ret = idWindow::HandleEvent(event, updateVisuals); + + if ( event->evType == SE_KEY ) { + + if ( !event->evValue2 ) { + return ret; + } + if ( key == K_MOUSE1) { + // Mouse was clicked + } else { + return ret; + } + } + + return ret; +} + +/* +============================= +idGameBearShootWindow::ParseInternalVar +============================= +*/ +bool idGameBearShootWindow::ParseInternalVar(const char *_name, idParser *src) { + if ( idStr::Icmp(_name, "gamerunning") == 0 ) { + gamerunning = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onFire") == 0 ) { + onFire = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onContinue") == 0 ) { + onContinue = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onNewGame") == 0 ) { + onNewGame = src->ParseBool(); + return true; + } + + return idWindow::ParseInternalVar(_name, src); +} + +/* +============================= +idGameBearShootWindow::GetWinVarByName +============================= +*/ +idWinVar *idGameBearShootWindow::GetWinVarByName(const char *_name, bool winLookup, drawWin_t** owner) { + idWinVar *retVar = NULL; + + if ( idStr::Icmp(_name, "gamerunning") == 0 ) { + retVar = &gamerunning; + } else if ( idStr::Icmp(_name, "onFire") == 0 ) { + retVar = &onFire; + } else if ( idStr::Icmp(_name, "onContinue") == 0 ) { + retVar = &onContinue; + } else if ( idStr::Icmp(_name, "onNewGame") == 0 ) { + retVar = &onNewGame; + } + + if(retVar) { + return retVar; + } + + return idWindow::GetWinVarByName(_name, winLookup, owner); +} + +/* +============================= +idGameBearShootWindow::PostParse +============================= +*/ +void idGameBearShootWindow::PostParse() { + idWindow::PostParse(); +} + +/* +============================= +idGameBearShootWindow::Draw +============================= +*/ +void idGameBearShootWindow::Draw(int time, float x, float y) { + int i; + + //Update the game every frame before drawing + UpdateGame(); + + for( i = entities.Num()-1; i >= 0; i-- ) { + entities[i]->Draw(dc); + } +} + +/* +============================= +idGameBearShootWindow::Activate +============================= +*/ +const char *idGameBearShootWindow::Activate(bool activate) { + return ""; +} + +/* +============================= +idGameBearShootWindow::UpdateTurret +============================= +*/ +void idGameBearShootWindow::UpdateTurret() { + idVec2 pt; + idVec2 turretOrig; + idVec2 right; + float dot, angle; + + pt.x = gui->CursorX(); + pt.y = gui->CursorY(); + turretOrig.Set( 80.f, 348.f ); + + pt = pt - turretOrig; + pt.NormalizeFast(); + + right.x = 1.f; + right.y = 0.f; + + dot = pt * right; + + angle = RAD2DEG( acosf( dot ) ); + + turretAngle = idMath::ClampFloat( 0.f, 90.f, angle ); +} + +/* +============================= +idGameBearShootWindow::UpdateBear +============================= +*/ +void idGameBearShootWindow::UpdateBear() { + int time = gui->GetTime(); + bool startShrink = false; + + // Apply gravity + bear->velocity.y += BEAR_GRAVITY * timeSlice; + + // Apply wind + bear->velocity.x += windForce * timeSlice; + + // Check for collisions + if ( !bearHitTarget && !gameOver ) { + idVec2 bearCenter; + bool collision = false; + + bearCenter.x = bear->position.x + bear->width/2; + bearCenter.y = bear->position.y + bear->height/2; + + if ( bearCenter.x > (helicopter->position.x + 16) && bearCenter.x < (helicopter->position.x + helicopter->width - 29) ) { + if ( bearCenter.y > (helicopter->position.y + 12) && bearCenter.y < (helicopter->position.y + helicopter->height - 7) ) { + collision = true; + } + } + + if ( collision ) { + // balloons pop and bear tumbles to ground + helicopter->SetMaterial( "game/bearshoot/helicopter_broken" ); + helicopter->velocity.y = 230.f; + goal->velocity.y = 230.f; + session->sw->PlayShaderDirectly( "arcade_balloonpop" ); + + bear->SetVisible( false ); + if ( bear->velocity.x > 0 ) { + bear->velocity.x *= -1.f; + } + bear->velocity *= 0.666f; + bearHitTarget = true; + updateScore = true; + startShrink = true; + } + } + + // Check for ground collision + if ( bear->position.y > 380 ) { + bear->position.y = 380; + + if ( bear->velocity.Length() < 25 ) { + bear->velocity.Zero(); + } else { + startShrink = true; + + bear->velocity.y *= -1.f; + bear->velocity *= 0.5f; + + if ( bearScale ) { + session->sw->PlayShaderDirectly( "arcade_balloonpop" ); + } + } + } + + // Bear rotation is based on velocity + float angle; + idVec2 dir; + + dir = bear->velocity; + dir.NormalizeFast(); + + angle = RAD2DEG( atan2( dir.x, dir.y ) ); + bear->rotation = angle - 90; + + // Update Bear scale + if ( bear->position.x > 650 ) { + startShrink = true; + } + + if ( !bearIsShrinking && bearScale && startShrink ) { + bearShrinkStartTime = time; + bearIsShrinking = true; + } + + if ( bearIsShrinking ) { + if ( bearHitTarget ) { + bearScale = 1 - ( (float)(time - bearShrinkStartTime) / BEAR_SHRINK_TIME ); + } else { + bearScale = 1 - ( (float)(time - bearShrinkStartTime) / 750 ); + } + bearScale *= BEAR_SIZE; + bear->SetSize( bearScale, bearScale ); + + if ( bearScale < 0 ) { + gui->HandleNamedEvent( "EnableFireButton" ); + bearIsShrinking = false; + bearScale = 0.f; + + if ( bearHitTarget ) { + goal->SetMaterial( "game/bearshoot/goal" ); + goal->position.x = 550; + goal->position.y = 164; + goal->velocity.Zero(); + goal->velocity.y = (currentLevel-1) * 30; + goal->entColor.w = 0.f; + goal->fadeIn = true; + goal->fadeOut = false; + + helicopter->SetVisible( true ); + helicopter->SetMaterial( "game/bearshoot/helicopter" ); + helicopter->position.x = 550; + helicopter->position.y = 100; + helicopter->velocity.Zero(); + helicopter->velocity.y = goal->velocity.y; + helicopter->entColor.w = 0.f; + helicopter->fadeIn = true; + helicopter->fadeOut = false; + } + } + } +} + +/* +============================= +idGameBearShootWindow::UpdateHelicopter +============================= +*/ +void idGameBearShootWindow::UpdateHelicopter() { + + if ( bearHitTarget && bearIsShrinking ) { + if ( helicopter->velocity.y != 0 && helicopter->position.y > 264 ) { + helicopter->velocity.y = 0; + goal->velocity.y = 0; + + helicopter->SetVisible( false ); + goal->SetMaterial( "game/bearshoot/goal_dead" ); + session->sw->PlayShaderDirectly( "arcade_beargroan", 1 ); + + helicopter->fadeOut = true; + goal->fadeOut = true; + } + } else if ( currentLevel > 1 ) { + int height = helicopter->position.y; + float speed = (currentLevel-1) * 30; + + if ( height > 240 ) { + helicopter->velocity.y = -speed; + goal->velocity.y = -speed; + } else if ( height < 30 ) { + helicopter->velocity.y = speed; + goal->velocity.y = speed; + } + } +} + +/* +============================= +idGameBearShootWindow::UpdateButtons +============================= +*/ +void idGameBearShootWindow::UpdateButtons() { + + if ( onFire ) { + idVec2 vec; + + gui->HandleNamedEvent( "DisableFireButton" ); + session->sw->PlayShaderDirectly( "arcade_sargeshoot" ); + + bear->SetVisible( true ); + bearScale = 1.f; + bear->SetSize( BEAR_SIZE, BEAR_SIZE ); + + vec.x = idMath::Cos( DEG2RAD(turretAngle) ); + vec.x += ( 1 - vec.x ) * 0.18f; + vec.y = -idMath::Sin( DEG2RAD(turretAngle) ); + + turretForce = bearTurretForce.GetFloat(); + + bear->position.x = 80 + ( 96 * vec.x ); + bear->position.y = 334 + ( 96 * vec.y ); + bear->velocity.x = vec.x * turretForce; + bear->velocity.y = vec.y * turretForce; + + gunblast->position.x = 55 + ( 96 * vec.x ); + gunblast->position.y = 310 + ( 100 * vec.y ); + gunblast->SetVisible( true ); + gunblast->entColor.w = 1.f; + gunblast->rotation = turretAngle; + gunblast->fadeOut = true; + + bearHitTarget = false; + + onFire = false; + } +} + +/* +============================= +idGameBearShootWindow::UpdateScore +============================= +*/ +void idGameBearShootWindow::UpdateScore() { + + if ( gameOver ) { + gui->HandleNamedEvent( "GameOver" ); + return; + } + + goalsHit++; + gui->SetStateString( "player_score", va("%i", goalsHit ) ); + + // Check for level progression + if ( !(goalsHit % 5) ) { + currentLevel++; + gui->SetStateString( "current_level", va("%i", currentLevel ) ); + session->sw->PlayShaderDirectly( "arcade_levelcomplete1", 3 ); + + timeRemaining += 30; + } +} + +/* +============================= +idGameBearShootWindow::UpdateGame +============================= +*/ +void idGameBearShootWindow::UpdateGame() { + int i; + + if ( onNewGame ) { + ResetGameState(); + + goal->position.x = 550; + goal->position.y = 164; + goal->velocity.Zero(); + helicopter->position.x = 550; + helicopter->position.y = 100; + helicopter->velocity.Zero(); + bear->SetVisible( false ); + + bearTurretAngle.SetFloat( 0.f ); + bearTurretForce.SetFloat( 200.f ); + + gamerunning = true; + } + if ( onContinue ) { + gameOver = false; + timeRemaining = 60.f; + + onContinue = false; + } + + if(gamerunning == true) { + int current_time = gui->GetTime(); + idRandom rnd( current_time ); + + // Check for button presses + UpdateButtons(); + + if ( bear ) { + UpdateBear(); + } + if ( helicopter && goal ) { + UpdateHelicopter(); + } + + // Update Wind + if ( windUpdateTime < current_time ) { + float scale; + int width; + + windForce = rnd.CRandomFloat() * ( MAX_WINDFORCE * 0.75f ); + if (windForce > 0) { + windForce += ( MAX_WINDFORCE * 0.25f ); + wind->rotation = 0; + } else { + windForce -= ( MAX_WINDFORCE * 0.25f ); + wind->rotation = 180; + } + + scale = 1.f - (( MAX_WINDFORCE - idMath::Fabs(windForce) ) / MAX_WINDFORCE); + width = 100*scale; + + if ( windForce < 0 ) { + wind->position.x = 500 - width + 1; + } else { + wind->position.x = 500; + } + wind->SetSize( width, 40 ); + + windUpdateTime = current_time + 7000 + rnd.RandomInt(5000); + } + + // Update turret rotation angle + if ( turret ) { + turretAngle = bearTurretAngle.GetFloat(); + turret->rotation = turretAngle; + } + + for( i = 0; i < entities.Num(); i++ ) { + entities[i]->Update( timeSlice ); + } + + // Update countdown timer + timeRemaining -= timeSlice; + timeRemaining = idMath::ClampFloat( 0.f, 99999.f, timeRemaining ); + gui->SetStateString( "time_remaining", va("%2.1f", timeRemaining ) ); + + if ( timeRemaining <= 0.f && !gameOver ) { + gameOver = true; + updateScore = true; + } + + if ( updateScore ) { + UpdateScore(); + updateScore = false; + } + } +} diff --git a/ui/GameBearShootWindow.h b/ui/GameBearShootWindow.h new file mode 100644 index 000000000..c0fa75173 --- /dev/null +++ b/ui/GameBearShootWindow.h @@ -0,0 +1,124 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_BEARSHOOT_WINDOW_H__ +#define __GAME_BEARSHOOT_WINDOW_H__ + +class idGameBearShootWindow; + +class BSEntity { +public: + const idMaterial * material; + idStr materialName; + float width, height; + bool visible; + + idVec4 entColor; + idVec2 position; + float rotation; + float rotationSpeed; + idVec2 velocity; + + bool fadeIn; + bool fadeOut; + + idGameBearShootWindow * game; + +public: + BSEntity(idGameBearShootWindow* _game); + virtual ~BSEntity(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameBearShootWindow* _game ); + + void SetMaterial(const char* name); + void SetSize( float _width, float _height ); + void SetVisible( bool isVisible ); + + virtual void Update( float timeslice ); + virtual void Draw(idDeviceContext *dc); + +private: +}; + + +class idGameBearShootWindow : public idWindow { +public: + idGameBearShootWindow(idUserInterfaceLocal *gui); + idGameBearShootWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + ~idGameBearShootWindow(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + + virtual const char* HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual const char* Activate(bool activate); + virtual idWinVar * GetWinVarByName (const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + +private: + void CommonInit(); + void ResetGameState(); + + void UpdateBear(); + void UpdateHelicopter(); + void UpdateTurret(); + void UpdateButtons(); + void UpdateGame(); + void UpdateScore(); + + virtual bool ParseInternalVar(const char *name, idParser *src); + +private: + + idWinBool gamerunning; + idWinBool onFire; + idWinBool onContinue; + idWinBool onNewGame; + + float timeSlice; + float timeRemaining; + bool gameOver; + + int currentLevel; + int goalsHit; + bool updateScore; + bool bearHitTarget; + + float bearScale; + bool bearIsShrinking; + int bearShrinkStartTime; + + float turretAngle; + float turretForce; + + float windForce; + int windUpdateTime; + + idList entities; + + BSEntity *turret; + BSEntity *bear; + BSEntity *helicopter; + BSEntity *goal; + BSEntity *wind; + BSEntity *gunblast; +}; + +#endif //__GAME_BEARSHOOT_WINDOW_H__ diff --git a/ui/GameBustOutWindow.cpp b/ui/GameBustOutWindow.cpp new file mode 100644 index 000000000..559788997 --- /dev/null +++ b/ui/GameBustOutWindow.cpp @@ -0,0 +1,1333 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "../framework/Session_local.h" +#include "../renderer/Image.h" + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "GameBustOutWindow.h" + +#define BALL_RADIUS 12.f +#define BALL_SPEED 250.f +#define BALL_MAXSPEED 450.f + +#define S_UNIQUE_CHANNEL 6 + +/* +***************************************************************************** +* BOEntity +**************************************************************************** +*/ +BOEntity::BOEntity(idGameBustOutWindow* _game) { + game = _game; + visible = true; + + materialName = ""; + material = NULL; + width = height = 8; + color = colorWhite; + powerup = POWERUP_NONE; + + position.Zero(); + velocity.Zero(); + + removed = false; + fadeOut = 0; +} + +BOEntity::~BOEntity() { +} + +/* +====================== +BOEntity::WriteToSaveGame +====================== +*/ +void BOEntity::WriteToSaveGame( idFile *savefile ) { + + savefile->Write( &visible, sizeof(visible) ); + + game->WriteSaveGameString( materialName, savefile ); + + savefile->Write( &width, sizeof(width) ); + savefile->Write( &height, sizeof(height) ); + + savefile->Write( &color, sizeof(color) ); + savefile->Write( &position, sizeof(position) ); + savefile->Write( &velocity, sizeof(velocity) ); + + savefile->Write( &powerup, sizeof(powerup) ); + savefile->Write( &removed, sizeof(removed) ); + savefile->Write( &fadeOut, sizeof(fadeOut) ); +} + +/* +====================== +BOEntity::ReadFromSaveGame +====================== +*/ +void BOEntity::ReadFromSaveGame( idFile *savefile, idGameBustOutWindow* _game ) { + game = _game; + + savefile->Read( &visible, sizeof(visible) ); + + game->ReadSaveGameString( materialName, savefile ); + SetMaterial( materialName ); + + savefile->Read( &width, sizeof(width) ); + savefile->Read( &height, sizeof(height) ); + + savefile->Read( &color, sizeof(color) ); + savefile->Read( &position, sizeof(position) ); + savefile->Read( &velocity, sizeof(velocity) ); + + savefile->Read( &powerup, sizeof(powerup) ); + savefile->Read( &removed, sizeof(removed) ); + savefile->Read( &fadeOut, sizeof(fadeOut) ); +} + +/* +====================== +BOEntity::SetMaterial +====================== +*/ +void BOEntity::SetMaterial(const char* name) { + materialName = name; + material = declManager->FindMaterial( name ); + material->SetSort( SS_GUI ); +} + +/* +====================== +BOEntity::SetSize +====================== +*/ +void BOEntity::SetSize( float _width, float _height ) { + width = _width; + height = _height; +} + +/* +====================== +BOEntity::SetVisible +====================== +*/ +void BOEntity::SetColor( float r, float g, float b, float a ) { + color.x = r; + color.y = g; + color.z = b; + color.w = a; +} + +/* +====================== +BOEntity::SetVisible +====================== +*/ +void BOEntity::SetVisible( bool isVisible ) { + visible = isVisible; +} + +/* +====================== +BOEntity::Update +====================== +*/ +void BOEntity::Update( float timeslice, int guiTime ) { + + if ( !visible ) { + return; + } + + // Move the entity + position += velocity * timeslice; + + // Fade out the ent + if ( fadeOut ) { + color.w -= timeslice * 2.5; + + if ( color.w <= 0.f ) { + color.w = 0.f; + removed = true; + } + } +} + +/* +====================== +BOEntity::Draw +====================== +*/ +void BOEntity::Draw(idDeviceContext *dc) { + if ( visible ) { + dc->DrawMaterialRotated( position.x, position.y, width, height, material, color, 1.0f, 1.0f, DEG2RAD(0.f) ); + } +} + +/* +***************************************************************************** +* BOBrick +**************************************************************************** +*/ +BOBrick::BOBrick( void ) { + ent = NULL; + x = y = width = height = 0; + powerup = POWERUP_NONE; + isBroken = false; +} + +BOBrick::BOBrick( BOEntity *_ent, float _x, float _y, float _width, float _height ) { + ent = _ent; + x = _x; + y = _y; + width = _width; + height = _height; + powerup = POWERUP_NONE; + + isBroken = false; + + ent->position.x = x; + ent->position.y = y; + ent->SetSize( width, height ); + ent->SetMaterial( "game/bustout/brick" ); + + ent->game->entities.Append( ent ); +} + +BOBrick::~BOBrick( void ) { +} + +/* +====================== +BOBrick::WriteToSaveGame +====================== +*/ +void BOBrick::WriteToSaveGame( idFile *savefile ) { + savefile->Write( &x, sizeof(x) ); + savefile->Write( &y, sizeof(y) ); + savefile->Write( &width, sizeof(width) ); + savefile->Write( &height, sizeof(height) ); + + savefile->Write( &powerup, sizeof(powerup) ); + savefile->Write( &isBroken, sizeof(isBroken) ); + + int index = ent->game->entities.FindIndex( ent ); + savefile->Write( &index, sizeof(index) ); +} + +/* +====================== +BOBrick::ReadFromSaveGame +====================== +*/ +void BOBrick::ReadFromSaveGame( idFile *savefile, idGameBustOutWindow *game ) { + savefile->Read( &x, sizeof(x) ); + savefile->Read( &y, sizeof(y) ); + savefile->Read( &width, sizeof(width) ); + savefile->Read( &height, sizeof(height) ); + + savefile->Read( &powerup, sizeof(powerup) ); + savefile->Read( &isBroken, sizeof(isBroken) ); + + int index; + savefile->Read( &index, sizeof(index) ); + ent = game->entities[index]; +} + +/* +====================== +BOBrick::SetColor +====================== +*/ +void BOBrick::SetColor( idVec4 bcolor ) { + ent->SetColor( bcolor.x, bcolor.y, bcolor.z, bcolor.w ); +} + +/* +====================== +BOBrick::checkCollision +====================== +*/ +collideDir_t BOBrick::checkCollision( idVec2 pos, idVec2 vel ) { + idVec2 ptA, ptB; + float dist; + + collideDir_t result = COLLIDE_NONE; + + if ( isBroken ) { + return result; + } + + // Check for collision with each edge + idVec2 vec; + + // Bottom + ptA.x = x; + ptA.y = y + height; + + ptB.x = x + width; + ptB.y = y + height; + + if ( vel.y < 0 && pos.y > ptA.y ) { + if( pos.x > ptA.x && pos.x < ptB.x ) { + dist = pos.y - ptA.y; + + if ( dist < BALL_RADIUS ) { + result = COLLIDE_DOWN; + } + } else { + if ( pos.x <= ptA.x ) { + vec = pos - ptA; + } else { + vec = pos - ptB; + } + + if ( (idMath::Fabs(vec.y) > idMath::Fabs(vec.x)) && (vec.LengthFast() < BALL_RADIUS) ) { + result = COLLIDE_DOWN; + } + } + } + + if ( result == COLLIDE_NONE ) { + // Top + ptA.y = y; + ptB.y = y; + + if ( vel.y > 0 && pos.y < ptA.y ) { + if( pos.x > ptA.x && pos.x < ptB.x ) { + dist = ptA.y - pos.y; + + if ( dist < BALL_RADIUS ) { + result = COLLIDE_UP; + } + } else { + if ( pos.x <= ptA.x ) { + vec = pos - ptA; + } else { + vec = pos - ptB; + } + + if ( (idMath::Fabs(vec.y) > idMath::Fabs(vec.x)) && (vec.LengthFast() < BALL_RADIUS) ) { + result = COLLIDE_UP; + } + } + } + + if ( result == COLLIDE_NONE ) { + // Left side + ptA.x = x; + ptA.y = y; + + ptB.x = x; + ptB.y = y + height; + + if ( vel.x > 0 && pos.x < ptA.x ) { + if( pos.y > ptA.y && pos.y < ptB.y ) { + dist = ptA.x - pos.x; + + if ( dist < BALL_RADIUS ) { + result = COLLIDE_LEFT; + } + } else { + if ( pos.y <= ptA.y ) { + vec = pos - ptA; + } else { + vec = pos - ptB; + } + + if ( (idMath::Fabs(vec.x) >= idMath::Fabs(vec.y)) && (vec.LengthFast() < BALL_RADIUS) ) { + result = COLLIDE_LEFT; + } + } + } + + if ( result == COLLIDE_NONE ) { + // Right side + ptA.x = x + width; + ptB.x = x + width; + + if ( vel.x < 0 && pos.x > ptA.x ) { + if( pos.y > ptA.y && pos.y < ptB.y ) { + dist = pos.x - ptA.x; + + if ( dist < BALL_RADIUS ) { + result = COLLIDE_LEFT; + } + } else { + if ( pos.y <= ptA.y ) { + vec = pos - ptA; + } else { + vec = pos - ptB; + } + + if ( (idMath::Fabs(vec.x) >= idMath::Fabs(vec.y)) && (vec.LengthFast() < BALL_RADIUS) ) { + result = COLLIDE_LEFT; + } + } + } + + } + } + } + + return result; +} + +/* +***************************************************************************** +* idGameBustOutWindow +**************************************************************************** +*/ +idGameBustOutWindow::idGameBustOutWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idGameBustOutWindow::idGameBustOutWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idGameBustOutWindow::~idGameBustOutWindow() { + entities.DeleteContents(true); + + Mem_Free( levelBoardData ); +} + +/* +============================= +idGameBustOutWindow::WriteToSaveGame +============================= +*/ +void idGameBustOutWindow::WriteToSaveGame( idFile *savefile ) { + idWindow::WriteToSaveGame( savefile ); + + gamerunning.WriteToSaveGame( savefile ); + onFire.WriteToSaveGame( savefile ); + onContinue.WriteToSaveGame( savefile ); + onNewGame.WriteToSaveGame( savefile ); + onNewLevel.WriteToSaveGame( savefile ); + + savefile->Write( &timeSlice, sizeof(timeSlice) ); + savefile->Write( &gameOver, sizeof(gameOver) ); + savefile->Write( &numLevels, sizeof(numLevels) ); + + // Board Data is loaded when GUI is loaded, don't need to save + + savefile->Write( &numBricks, sizeof(numBricks) ); + savefile->Write( ¤tLevel, sizeof(currentLevel) ); + + savefile->Write( &updateScore, sizeof(updateScore) ); + savefile->Write( &gameScore, sizeof(gameScore) ); + savefile->Write( &nextBallScore, sizeof(nextBallScore) ); + + savefile->Write( &bigPaddleTime, sizeof(bigPaddleTime) ); + savefile->Write( &paddleVelocity, sizeof(paddleVelocity) ); + + savefile->Write( &ballSpeed, sizeof(ballSpeed) ); + savefile->Write( &ballsRemaining, sizeof(ballsRemaining) ); + savefile->Write( &ballsInPlay, sizeof(ballsInPlay) ); + savefile->Write( &ballHitCeiling, sizeof(ballHitCeiling) ); + + // Write Entities + int i; + int numberOfEnts = entities.Num(); + savefile->Write( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iWriteToSaveGame( savefile ); + } + + // Write Balls + numberOfEnts = balls.Num(); + savefile->Write( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iWrite( &ballIndex, sizeof(ballIndex) ); + } + + // Write Powerups + numberOfEnts = powerUps.Num(); + savefile->Write( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iWrite( &powerIndex, sizeof(powerIndex) ); + } + + // Write paddle + paddle->WriteToSaveGame( savefile ); + + // Write Bricks + int row; + for ( row=0; rowWrite( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iWriteToSaveGame( savefile ); + } + } +} + +/* +============================= +idGameBustOutWindow::ReadFromSaveGame +============================= +*/ +void idGameBustOutWindow::ReadFromSaveGame( idFile *savefile ) { + idWindow::ReadFromSaveGame( savefile ); + + // Clear out existing paddle and entities from GUI load + delete paddle; + entities.DeleteContents( true ); + + gamerunning.ReadFromSaveGame( savefile ); + onFire.ReadFromSaveGame( savefile ); + onContinue.ReadFromSaveGame( savefile ); + onNewGame.ReadFromSaveGame( savefile ); + onNewLevel.ReadFromSaveGame( savefile ); + + savefile->Read( &timeSlice, sizeof(timeSlice) ); + savefile->Read( &gameOver, sizeof(gameOver) ); + savefile->Read( &numLevels, sizeof(numLevels) ); + + // Board Data is loaded when GUI is loaded, don't need to save + + savefile->Read( &numBricks, sizeof(numBricks) ); + savefile->Read( ¤tLevel, sizeof(currentLevel) ); + + savefile->Read( &updateScore, sizeof(updateScore) ); + savefile->Read( &gameScore, sizeof(gameScore) ); + savefile->Read( &nextBallScore, sizeof(nextBallScore) ); + + savefile->Read( &bigPaddleTime, sizeof(bigPaddleTime) ); + savefile->Read( &paddleVelocity, sizeof(paddleVelocity) ); + + savefile->Read( &ballSpeed, sizeof(ballSpeed) ); + savefile->Read( &ballsRemaining, sizeof(ballsRemaining) ); + savefile->Read( &ballsInPlay, sizeof(ballsInPlay) ); + savefile->Read( &ballHitCeiling, sizeof(ballHitCeiling) ); + + int i; + int numberOfEnts; + + // Read entities + savefile->Read( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iReadFromSaveGame( savefile, this ); + entities.Append( ent ); + } + + // Read balls + savefile->Read( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iRead( &ballIndex, sizeof(ballIndex) ); + balls.Append( entities[ballIndex] ); + } + + // Read powerups + savefile->Read( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iRead( &powerIndex, sizeof(powerIndex) ); + balls.Append( entities[powerIndex] ); + } + + // Read paddle + paddle = new BOBrick(); + paddle->ReadFromSaveGame( savefile, this ); + + // Read board + int row; + for ( row=0; rowRead( &numberOfEnts, sizeof(numberOfEnts) ); + for ( i=0; iReadFromSaveGame( savefile, this ); + board[row].Append( brick ); + } + } +} + +/* +============================= +idGameBustOutWindow::ResetGameState +============================= +*/ +void idGameBustOutWindow::ResetGameState() { + gamerunning = false; + gameOver = false; + onFire = false; + onContinue = false; + onNewGame = false; + onNewLevel = false; + + // Game moves forward 16 milliseconds every frame + timeSlice = 0.016f; + ballsRemaining = 3; + ballSpeed = BALL_SPEED; + ballsInPlay = 0; + updateScore = false; + numBricks = 0; + currentLevel = 1; + gameScore = 0; + bigPaddleTime = 0; + nextBallScore = gameScore + 10000; + + ClearBoard(); +} + +/* +============================= +idGameBustOutWindow::CommonInit +============================= +*/ +void idGameBustOutWindow::CommonInit() { + BOEntity *ent; + + // Precache images + declManager->FindMaterial( "game/bustout/ball" ); + declManager->FindMaterial( "game/bustout/doublepaddle" ); + declManager->FindMaterial( "game/bustout/powerup_bigpaddle" ); + declManager->FindMaterial( "game/bustout/powerup_multiball" ); + declManager->FindMaterial( "game/bustout/brick" ); + + // Precache sounds + declManager->FindSound( "arcade_ballbounce" ); + declManager->FindSound( "arcade_brickhit" ); + declManager->FindSound( "arcade_missedball" ); + declManager->FindSound( "arcade_sadsound" ); + declManager->FindSound( "arcade_extraball" ); + declManager->FindSound( "arcade_powerup" ); + + ResetGameState(); + + numLevels = 0; + boardDataLoaded = false; + levelBoardData = NULL; + + // Create Paddle + ent = new BOEntity( this ); + paddle = new BOBrick( ent, 260.f, 440.f, 96.f, 24.f ); + paddle->ent->SetMaterial( "game/bustout/paddle" ); +} + +/* +============================= +idGameBustOutWindow::HandleEvent +============================= +*/ +const char *idGameBustOutWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + int key = event->evValue; + + // need to call this to allow proper focus and capturing on embedded children + const char *ret = idWindow::HandleEvent(event, updateVisuals); + + if ( event->evType == SE_KEY ) { + + if ( !event->evValue2 ) { + return ret; + } + if ( key == K_MOUSE1) { + // Mouse was clicked + if ( ballsInPlay == 0 ) { + BOEntity *ball = CreateNewBall(); + + ball->SetVisible( true ); + ball->position.x = paddle->ent->position.x + 48.f; + ball->position.y = 430.f; + + ball->velocity.x = ballSpeed; + ball->velocity.y = -ballSpeed*2.f; + ball->velocity.NormalizeFast(); + ball->velocity *= ballSpeed; + } + } else { + return ret; + } + } + + return ret; +} + +/* +============================= +idGameBustOutWindow::ParseInternalVar +============================= +*/ +bool idGameBustOutWindow::ParseInternalVar(const char *_name, idParser *src) { + if ( idStr::Icmp(_name, "gamerunning") == 0 ) { + gamerunning = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onFire") == 0 ) { + onFire = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onContinue") == 0 ) { + onContinue = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onNewGame") == 0 ) { + onNewGame = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "onNewLevel") == 0 ) { + onNewLevel = src->ParseBool(); + return true; + } + if ( idStr::Icmp(_name, "numLevels") == 0 ) { + numLevels = src->ParseInt(); + + // Load all the level images + LoadBoardFiles(); + return true; + } + + return idWindow::ParseInternalVar(_name, src); +} + +/* +============================= +idGameBustOutWindow::GetWinVarByName +============================= +*/ +idWinVar *idGameBustOutWindow::GetWinVarByName(const char *_name, bool winLookup, drawWin_t** owner) { + idWinVar *retVar = NULL; + + if ( idStr::Icmp(_name, "gamerunning") == 0 ) { + retVar = &gamerunning; + } else if ( idStr::Icmp(_name, "onFire") == 0 ) { + retVar = &onFire; + } else if ( idStr::Icmp(_name, "onContinue") == 0 ) { + retVar = &onContinue; + } else if ( idStr::Icmp(_name, "onNewGame") == 0 ) { + retVar = &onNewGame; + } else if ( idStr::Icmp(_name, "onNewLevel") == 0 ) { + retVar = &onNewLevel; + } + + if(retVar) { + return retVar; + } + + return idWindow::GetWinVarByName(_name, winLookup, owner); +} + +/* +============================= +idGameBustOutWindow::PostParse +============================= +*/ +void idGameBustOutWindow::PostParse() { + idWindow::PostParse(); +} + +/* +============================= +idGameBustOutWindow::Draw +============================= +*/ +void idGameBustOutWindow::Draw(int time, float x, float y) { + int i; + + //Update the game every frame before drawing + UpdateGame(); + + for( i = entities.Num()-1; i >= 0; i-- ) { + entities[i]->Draw(dc); + } +} + +/* +============================= +idGameBustOutWindow::Activate +============================= +*/ +const char *idGameBustOutWindow::Activate(bool activate) { + return ""; +} + + +/* +============================= +idGameBustOutWindow::UpdateScore +============================= +*/ +void idGameBustOutWindow::UpdateScore() { + + if ( gameOver ) { + gui->HandleNamedEvent( "GameOver" ); + return; + } + + // Check for level progression + if ( numBricks == 0 ) { + ClearBalls(); + + gui->HandleNamedEvent( "levelComplete" ); + } + + // Check for new ball score + if ( gameScore >= nextBallScore ) { + ballsRemaining++; + gui->HandleNamedEvent( "extraBall" ); + + // Play sound + session->sw->PlayShaderDirectly( "arcade_extraball", S_UNIQUE_CHANNEL ); + + nextBallScore = gameScore + 10000; + } + + gui->SetStateString( "player_score", va("%i", gameScore ) ); + gui->SetStateString( "balls_remaining", va("%i", ballsRemaining ) ); + gui->SetStateString( "current_level", va("%i", currentLevel ) ); + gui->SetStateString( "next_ball_score", va("%i", nextBallScore ) ); +} + +/* +============================= +idGameBustOutWindow::ClearBoard +============================= +*/ +void idGameBustOutWindow::ClearBoard( void ) { + int i,j; + + ClearPowerups(); + + ballHitCeiling = false; + + for ( i=0; ient->removed = true; + } + + board[i].DeleteContents( true ); + } +} + +/* +============================= +idGameBustOutWindow::ClearPowerups +============================= +*/ +void idGameBustOutWindow::ClearPowerups( void ) { + while ( powerUps.Num() ) { + powerUps[0]->removed = true; + powerUps.RemoveIndex( 0 ); + } +} + +/* +============================= +idGameBustOutWindow::ClearBalls +============================= +*/ +void idGameBustOutWindow::ClearBalls( void ) { + while ( balls.Num() ) { + balls[0]->removed = true; + balls.RemoveIndex( 0 ); + } + + ballsInPlay = 0; +} + +/* +============================= +idGameBustOutWindow::LoadBoardFiles +============================= +*/ +void idGameBustOutWindow::LoadBoardFiles( void ) { + int i; + int w,h; + ID_TIME_T time; + int boardSize; + byte *currentBoard; + + if ( boardDataLoaded ) { + return; + } + + boardSize = 9 * 12 * 4; + levelBoardData = (byte*)Mem_Alloc( boardSize * numLevels ); + + currentBoard = levelBoardData; + + for ( i=0; iDWarning( "Hell Bust-Out level image not correct dimensions! (%d x %d)", w, h ); + } + + memcpy( currentBoard, pic, boardSize ); + Mem_Free(pic); + } + + currentBoard += boardSize; + } + + boardDataLoaded = true; +} + +/* +============================= +idGameBustOutWindow::SetCurrentBoard +============================= +*/ +void idGameBustOutWindow::SetCurrentBoard( void ) { + int i,j; + int realLevel = ((currentLevel-1) % numLevels); + int boardSize; + byte *currentBoard; + float bx = 11.f; + float by = 24.f; + float stepx = 619.f / 9.f; + float stepy = ( 256 / 12.f ); + + boardSize = 9 * 12 * 4; + currentBoard = levelBoardData + ( realLevel * boardSize ); + + for ( j=0; jSetColor( bcolor ); + + pType = currentBoard[pixelindex + 3] / 255.f; + if ( pType > 0.f && pType < 1.f ) { + if ( pType < 0.5f ) { + brick->powerup = POWERUP_BIGPADDLE; + } else { + brick->powerup = POWERUP_MULTIBALL; + } + } + + board[j].Append( brick ); + numBricks++; + } + + bx += stepx; + } + + by += stepy; + } +} + +/* +============================= +idGameBustOutWindow::CreateNewBall +============================= +*/ +BOEntity * idGameBustOutWindow::CreateNewBall( void ) { + BOEntity *ball; + + ball = new BOEntity( this ); + ball->position.x = 300.f; + ball->position.y = 416.f; + ball->SetMaterial( "game/bustout/ball" ); + ball->SetSize( BALL_RADIUS*2.f, BALL_RADIUS*2.f ); + ball->SetVisible( false ); + + ballsInPlay++; + + balls.Append( ball ); + entities.Append( ball ); + + return ball; +} + +/* +============================= +idGameBustOutWindow::CreatePowerup +============================= +*/ +BOEntity * idGameBustOutWindow::CreatePowerup( BOBrick *brick ) { + BOEntity *powerEnt = new BOEntity( this ); + + powerEnt->position.x = brick->x; + powerEnt->position.y = brick->y; + powerEnt->velocity.x = 0.f; + powerEnt->velocity.y = 64.f; + + powerEnt->powerup = brick->powerup; + + switch( powerEnt->powerup ) { + case POWERUP_BIGPADDLE: + powerEnt->SetMaterial( "game/bustout/powerup_bigpaddle" ); + break; + case POWERUP_MULTIBALL: + powerEnt->SetMaterial( "game/bustout/powerup_multiball" ); + break; + default: + powerEnt->SetMaterial( "textures/common/nodraw" ); + break; + } + + powerEnt->SetSize( 619/9, 256/12 ); + powerEnt->SetVisible( true ); + + powerUps.Append( powerEnt ); + entities.Append( powerEnt ); + + return powerEnt; +} + +/* +============================= +idGameBustOutWindow::UpdatePowerups +============================= +*/ +void idGameBustOutWindow::UpdatePowerups( void ) { + idVec2 pos; + + for ( int i=0; i < powerUps.Num(); i++ ) { + BOEntity *pUp = powerUps[i]; + + // Check for powerup falling below screen + if ( pUp->position.y > 480 ) { + + powerUps.RemoveIndex( i ); + pUp->removed = true; + continue; + } + + // Check for the paddle catching a powerup + pos.x = pUp->position.x + ( pUp->width / 2 ); + pos.y = pUp->position.y + ( pUp->height / 2 ); + + collideDir_t collision = paddle->checkCollision( pos, pUp->velocity ); + if ( collision != COLLIDE_NONE ) { + BOEntity *ball; + + // Give the powerup to the player + switch( pUp->powerup ) { + case POWERUP_BIGPADDLE: + bigPaddleTime = gui->GetTime() + 15000; + break; + case POWERUP_MULTIBALL: + // Create 2 new balls in the spot of the existing ball + for ( int b=0; b<2; b++ ) { + ball = CreateNewBall(); + ball->position = balls[0]->position; + ball->velocity = balls[0]->velocity; + + if ( b == 0 ) { + ball->velocity.x -= 35.f; + } else { + ball->velocity.x += 35.f; + } + ball->velocity.NormalizeFast(); + ball->velocity *= ballSpeed; + + ball->SetVisible( true ); + } + break; + default: + break; + } + + // Play the sound + session->sw->PlayShaderDirectly( "arcade_powerup", S_UNIQUE_CHANNEL ); + + // Remove it + powerUps.RemoveIndex( i ); + pUp->removed = true; + } + } +} + +/* +============================= +idGameBustOutWindow::UpdatePaddle +============================= +*/ +void idGameBustOutWindow::UpdatePaddle( void ) { + idVec2 cursorPos; + float oldPos = paddle->x; + + cursorPos.x = gui->CursorX(); + cursorPos.y = gui->CursorY(); + + if ( bigPaddleTime > gui->GetTime() ) { + paddle->x = cursorPos.x - 80.f; + paddle->width = 160; + paddle->ent->width = 160; + paddle->ent->SetMaterial( "game/bustout/doublepaddle" ); + } else { + paddle->x = cursorPos.x - 48.f; + paddle->width = 96; + paddle->ent->width = 96; + paddle->ent->SetMaterial( "game/bustout/paddle" ); + } + paddle->ent->position.x = paddle->x; + + paddleVelocity = (paddle->x - oldPos); +} + +/* +============================= +idGameBustOutWindow::UpdateBall +============================= +*/ +void idGameBustOutWindow::UpdateBall( void ) { + int ballnum,i,j; + bool playSoundBounce = false; + bool playSoundBrick = false; + static int bounceChannel = 1; + + if ( ballsInPlay == 0 ) { + return; + } + + for ( ballnum = 0; ballnum < balls.Num(); ballnum++ ) { + BOEntity *ball = balls[ballnum]; + + // Check for ball going below screen, lost ball + if ( ball->position.y > 480.f ) { + ball->removed = true; + continue; + } + + // Check world collision + if ( ball->position.y < 20 && ball->velocity.y < 0 ) { + ball->velocity.y = -ball->velocity.y; + + // Increase ball speed when it hits ceiling + if ( !ballHitCeiling ) { + ballSpeed *= 1.25f; + ballHitCeiling = true; + } + playSoundBounce = true; + } + + if ( ball->position.x > 608 && ball->velocity.x > 0 ) { + ball->velocity.x = -ball->velocity.x; + playSoundBounce = true; + } else if ( ball->position.x < 8 && ball->velocity.x < 0 ) { + ball->velocity.x = -ball->velocity.x; + playSoundBounce = true; + } + + // Check for Paddle collision + idVec2 ballCenter = ball->position + idVec2( BALL_RADIUS, BALL_RADIUS ); + collideDir_t collision = paddle->checkCollision( ballCenter, ball->velocity ); + + if ( collision == COLLIDE_UP ) { + if ( ball->velocity.y > 0 ) { + idVec2 paddleVec( paddleVelocity*2, 0 ); + float centerX; + + if ( bigPaddleTime > gui->GetTime() ) { + centerX = paddle->x + 80.f; + } else { + centerX = paddle->x + 48.f; + } + + ball->velocity.y = -ball->velocity.y; + + paddleVec.x += (ball->position.x - centerX) * 2; + + ball->velocity += paddleVec; + ball->velocity.NormalizeFast(); + ball->velocity *= ballSpeed; + + playSoundBounce = true; + } + } else if ( collision == COLLIDE_LEFT || collision == COLLIDE_RIGHT ) { + if ( ball->velocity.y > 0 ) { + ball->velocity.x = -ball->velocity.x; + playSoundBounce = true; + } + } + + collision = COLLIDE_NONE; + + // Check for collision with bricks + for ( i=0; icheckCollision( ballCenter, ball->velocity ); + if ( collision ) { + // Now break the brick if there was a collision + brick->isBroken = true; + brick->ent->fadeOut = true; + + if ( brick->powerup > POWERUP_NONE ) { + BOEntity *pUp = CreatePowerup( brick ); + } + + numBricks--; + gameScore += 100; + updateScore = true; + + // Go ahead an forcibly remove the last brick, no fade + if ( numBricks == 0 ) { + brick->ent->removed = true; + } + board[i].Remove( brick ); + break; + } + } + + if ( collision ) { + playSoundBrick = true; + break; + } + } + + if ( collision == COLLIDE_DOWN || collision == COLLIDE_UP ) { + ball->velocity.y *= -1; + } else if ( collision == COLLIDE_LEFT || collision == COLLIDE_RIGHT ) { + ball->velocity.x *= -1; + } + + if ( playSoundBounce ) { + session->sw->PlayShaderDirectly( "arcade_ballbounce", bounceChannel ); + } else if ( playSoundBrick ) { + session->sw->PlayShaderDirectly( "arcade_brickhit", bounceChannel ); + } + + if ( playSoundBounce || playSoundBrick ) { + bounceChannel++; + if ( bounceChannel == 4 ) { + bounceChannel = 1; + } + } + } + + // Check to see if any balls were removed from play + for ( ballnum=0; ballnumremoved ) { + ballsInPlay--; + balls.RemoveIndex( ballnum ); + } + } + + // If all the balls were removed, update the game accordingly + if ( ballsInPlay == 0 ) { + if ( ballsRemaining == 0 ) { + gameOver = true; + + // Game Over sound + session->sw->PlayShaderDirectly( "arcade_sadsound", S_UNIQUE_CHANNEL ); + } else { + ballsRemaining--; + + // Ball was lost, but game is not over + session->sw->PlayShaderDirectly( "arcade_missedball", S_UNIQUE_CHANNEL ); + } + + ClearPowerups(); + updateScore = true; + } +} + +/* +============================= +idGameBustOutWindow::UpdateGame +============================= +*/ +void idGameBustOutWindow::UpdateGame() { + int i; + + if ( onNewGame ) { + ResetGameState(); + + // Create Board + SetCurrentBoard(); + + gamerunning = true; + } + if ( onContinue ) { + gameOver = false; + ballsRemaining = 3; + + onContinue = false; + } + if ( onNewLevel ) { + currentLevel++; + + ClearBoard(); + SetCurrentBoard(); + + ballSpeed = BALL_SPEED * ( 1.f + ((float)currentLevel/5.f) ); + if ( ballSpeed > BALL_MAXSPEED ) { + ballSpeed = BALL_MAXSPEED; + } + updateScore = true; + onNewLevel = false; + } + + if(gamerunning == true) { + + UpdatePaddle(); + UpdateBall(); + UpdatePowerups(); + + for( i = 0; i < entities.Num(); i++ ) { + entities[i]->Update( timeSlice, gui->GetTime() ); + } + + // Delete entities that need to be deleted + for( i = entities.Num()-1; i >= 0; i-- ) { + if( entities[i]->removed ) { + BOEntity* ent = entities[i]; + delete ent; + entities.RemoveIndex(i); + } + } + + if ( updateScore ) { + UpdateScore(); + updateScore = false; + } + } +} diff --git a/ui/GameBustOutWindow.h b/ui/GameBustOutWindow.h new file mode 100644 index 000000000..65ec57232 --- /dev/null +++ b/ui/GameBustOutWindow.h @@ -0,0 +1,177 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_BUSTOUT_WINDOW_H__ +#define __GAME_BUSTOUT_WINDOW_H__ + +class idGameBustOutWindow; + +typedef enum { + POWERUP_NONE = 0, + POWERUP_BIGPADDLE, + POWERUP_MULTIBALL +} powerupType_t; + +class BOEntity { +public: + bool visible; + + idStr materialName; + const idMaterial * material; + float width, height; + idVec4 color; + idVec2 position; + idVec2 velocity; + + powerupType_t powerup; + + bool removed; + bool fadeOut; + + idGameBustOutWindow * game; + +public: + BOEntity(idGameBustOutWindow* _game); + virtual ~BOEntity(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameBustOutWindow* _game ); + + void SetMaterial(const char* name); + void SetSize( float _width, float _height ); + void SetColor( float r, float g, float b, float a ); + void SetVisible( bool isVisible ); + + virtual void Update( float timeslice, int guiTime ); + virtual void Draw(idDeviceContext *dc); + +private: +}; + +typedef enum { + COLLIDE_NONE = 0, + COLLIDE_DOWN, + COLLIDE_UP, + COLLIDE_LEFT, + COLLIDE_RIGHT +} collideDir_t; + +class BOBrick { +public: + float x; + float y; + float width; + float height; + powerupType_t powerup; + + bool isBroken; + + BOEntity *ent; + +public: + BOBrick(); + BOBrick( BOEntity *_ent, float _x, float _y, float _width, float _height ); + ~BOBrick(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameBustOutWindow *game ); + + void SetColor( idVec4 bcolor ); + collideDir_t checkCollision( idVec2 pos, idVec2 vel ); + +private: +}; + +#define BOARD_ROWS 12 + +class idGameBustOutWindow : public idWindow { +public: + idGameBustOutWindow(idUserInterfaceLocal *gui); + idGameBustOutWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + ~idGameBustOutWindow(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + + virtual const char* HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual const char* Activate(bool activate); + virtual idWinVar * GetWinVarByName (const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + + idList entities; + +private: + void CommonInit(); + void ResetGameState(); + + void ClearBoard(); + void ClearPowerups(); + void ClearBalls(); + + void LoadBoardFiles(); + void SetCurrentBoard(); + void UpdateGame(); + void UpdatePowerups(); + void UpdatePaddle(); + void UpdateBall(); + void UpdateScore(); + + BOEntity * CreateNewBall(); + BOEntity * CreatePowerup( BOBrick *brick ); + + virtual bool ParseInternalVar(const char *name, idParser *src); + +private: + + idWinBool gamerunning; + idWinBool onFire; + idWinBool onContinue; + idWinBool onNewGame; + idWinBool onNewLevel; + + float timeSlice; + bool gameOver; + + int numLevels; + byte * levelBoardData; + bool boardDataLoaded; + + int numBricks; + int currentLevel; + + bool updateScore; + int gameScore; + int nextBallScore; + + int bigPaddleTime; + float paddleVelocity; + + float ballSpeed; + int ballsRemaining; + int ballsInPlay; + bool ballHitCeiling; + + idList balls; + idList powerUps; + + BOBrick *paddle; + idList board[BOARD_ROWS]; +}; + +#endif //__GAME_BUSTOUT_WINDOW_H__ diff --git a/ui/GameSSDWindow.cpp b/ui/GameSSDWindow.cpp new file mode 100644 index 000000000..3112bda30 --- /dev/null +++ b/ui/GameSSDWindow.cpp @@ -0,0 +1,2290 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "../framework/Session_local.h" + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "GameSSDWindow.h" + + +#define Z_NEAR 100.0f +#define Z_FAR 4000.0f +#define ENTITY_START_DIST 3000 + +#define V_WIDTH 640.0f +#define V_HEIGHT 480.0f + +/* +***************************************************************************** +* SSDCrossHair +**************************************************************************** +*/ + +#define CROSSHAIR_STANDARD_MATERIAL "game/SSD/crosshair_standard" +#define CROSSHAIR_SUPER_MATERIAL "game/SSD/crosshair_super" + +SSDCrossHair::SSDCrossHair() { +} + +SSDCrossHair::~SSDCrossHair() { +} + +void SSDCrossHair::WriteToSaveGame( idFile *savefile ) { + + savefile->Write(¤tCrosshair, sizeof(currentCrosshair)); + savefile->Write(&crosshairWidth, sizeof(crosshairWidth)); + savefile->Write(&crosshairHeight, sizeof(crosshairHeight)); + +} + +void SSDCrossHair::ReadFromSaveGame( idFile *savefile ) { + + InitCrosshairs(); + + savefile->Read(¤tCrosshair, sizeof(currentCrosshair)); + savefile->Read(&crosshairWidth, sizeof(crosshairWidth)); + savefile->Read(&crosshairHeight, sizeof(crosshairHeight)); + +} + +void SSDCrossHair::InitCrosshairs() { + + crosshairMaterial[CROSSHAIR_STANDARD] = declManager->FindMaterial( CROSSHAIR_STANDARD_MATERIAL ); + crosshairMaterial[CROSSHAIR_SUPER] = declManager->FindMaterial( CROSSHAIR_SUPER_MATERIAL ); + + crosshairWidth = 64; + crosshairHeight = 64; + + currentCrosshair = CROSSHAIR_STANDARD; + +} + +void SSDCrossHair::Draw(idDeviceContext *dc, const idVec2& cursor) { + + float x,y; + x = cursor.x-(crosshairWidth/2); + y = cursor.y-(crosshairHeight/2); + dc->DrawMaterial(x, y, crosshairWidth, crosshairHeight, crosshairMaterial[currentCrosshair], colorWhite, 1.0f, 1.0f); + +} + +/* +***************************************************************************** +* SSDEntity +**************************************************************************** +*/ + +SSDEntity::SSDEntity() { + EntityInit(); +} + +SSDEntity::~SSDEntity() { +} + +void SSDEntity::WriteToSaveGame( idFile *savefile ) { + + savefile->Write(&type, sizeof(type)); + game->WriteSaveGameString(materialName, savefile); + savefile->Write(&position, sizeof(position)); + savefile->Write(&size, sizeof(size)); + savefile->Write(&radius, sizeof(radius)); + savefile->Write(&hitRadius, sizeof(hitRadius)); + savefile->Write(&rotation, sizeof(rotation)); + + savefile->Write(&matColor, sizeof(matColor)); + + game->WriteSaveGameString(text, savefile); + savefile->Write(&textScale, sizeof(textScale)); + savefile->Write(&foreColor, sizeof(foreColor)); + + savefile->Write(¤tTime, sizeof(currentTime)); + savefile->Write(&lastUpdate, sizeof(lastUpdate)); + savefile->Write(&elapsed, sizeof(elapsed)); + + savefile->Write(&destroyed, sizeof(destroyed)); + savefile->Write(&noHit, sizeof(noHit)); + savefile->Write(&noPlayerDamage, sizeof(noPlayerDamage)); + + savefile->Write(&inUse, sizeof(inUse)); + +} + +void SSDEntity::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + + savefile->Read(&type, sizeof(type)); + game->ReadSaveGameString(materialName, savefile); + SetMaterial(materialName); + savefile->Read(&position, sizeof(position)); + savefile->Read(&size, sizeof(size)); + savefile->Read(&radius, sizeof(radius)); + savefile->Read(&hitRadius, sizeof(hitRadius)); + savefile->Read(&rotation, sizeof(rotation)); + + savefile->Read(&matColor, sizeof(matColor)); + + game->ReadSaveGameString(text, savefile); + savefile->Read(&textScale, sizeof(textScale)); + savefile->Read(&foreColor, sizeof(foreColor)); + + game = _game; + savefile->Read(¤tTime, sizeof(currentTime)); + savefile->Read(&lastUpdate, sizeof(lastUpdate)); + savefile->Read(&elapsed, sizeof(elapsed)); + + savefile->Read(&destroyed, sizeof(destroyed)); + savefile->Read(&noHit, sizeof(noHit)); + savefile->Read(&noPlayerDamage, sizeof(noPlayerDamage)); + + savefile->Read(&inUse, sizeof(inUse)); +} + +void SSDEntity::EntityInit() { + + inUse = false; + + + type = SSD_ENTITY_BASE; + + materialName = ""; + material = NULL; + position.Zero(); + size.Zero(); + radius = 0.0f; + hitRadius = 0.0f; + rotation = 0.0f; + + + currentTime = 0; + lastUpdate = 0; + + destroyed = false; + noHit = false; + noPlayerDamage = false; + + matColor.Set(1, 1, 1, 1); + + text = ""; + textScale = 1.0f; + foreColor.Set(1, 1, 1, 1); +} + +void SSDEntity::SetGame(idGameSSDWindow* _game) { + game = _game; +} + +void SSDEntity::SetMaterial(const char* name) { + materialName = name; + material = declManager->FindMaterial( name ); + material->SetSort( SS_GUI ); +} + +void SSDEntity::SetPosition(const idVec3& _position) { + position = _position; +} + +void SSDEntity::SetSize(const idVec2& _size) { + size = _size; +} + +void SSDEntity::SetRadius(float _radius, float _hitFactor) { + radius = _radius; + hitRadius = _radius*_hitFactor; +} + +void SSDEntity::SetRotation(float _rotation) { + rotation = _rotation; +} + +void SSDEntity::Update() { + + currentTime = game->ssdTime; + + //Is this the first update + if(lastUpdate == 0) { + lastUpdate = currentTime; + return; + } + + elapsed = currentTime - lastUpdate; + + EntityUpdate(); + + lastUpdate = currentTime; +} + +bool SSDEntity::HitTest(const idVec2& pt) { + + if(noHit) { + return false; + } + + idVec3 screenPos = WorldToScreen(position); + + + //Scale the radius based on the distance from the player + float scale = 1.0f -((screenPos.z-Z_NEAR)/(Z_FAR-Z_NEAR)); + float scaledRad = scale*hitRadius; + + //So we can compare against the square of the length between two points + float scaleRadSqr = scaledRad*scaledRad; + + idVec2 diff = screenPos.ToVec2()-pt; + float dist = idMath::Fabs(diff.LengthSqr()); + + if(dist < scaleRadSqr) { + return true; + } + return false; +} + +void SSDEntity::Draw(idDeviceContext *dc) { + + + idVec2 persize; + float x,y; + + idBounds bounds; + bounds[0] = idVec3(position.x - (size.x/2.0f), position.y - (size.y/2.0f), position.z); + bounds[1] = idVec3(position.x + (size.x/2.0f), position.y + (size.y/2.0f), position.z); + + idBounds screenBounds = WorldToScreen(bounds); + persize.x = idMath::Fabs(screenBounds[1].x - screenBounds[0].x); + persize.y = idMath::Fabs(screenBounds[1].y - screenBounds[0].y); + + idVec3 center = screenBounds.GetCenter(); + + x = screenBounds[0].x; + y = screenBounds[1].y; + dc->DrawMaterialRotated(x, y, persize.x, persize.y, material, matColor, 1.0f, 1.0f, DEG2RAD(rotation)); + + if(text.Length() > 0) { + idRectangle rect( x, y, VIRTUAL_WIDTH, VIRTUAL_HEIGHT ); + dc->DrawText( text, textScale, 0, foreColor, rect, false ); + } + +} + +void SSDEntity::DestroyEntity() { + inUse = false; +} + +idBounds SSDEntity::WorldToScreen(const idBounds worldBounds) { + + idVec3 screenMin = WorldToScreen(worldBounds[0]); + idVec3 screenMax = WorldToScreen(worldBounds[1]); + + idBounds screenBounds(screenMin, screenMax); + return screenBounds; +} + +idVec3 SSDEntity::WorldToScreen(const idVec3& worldPos) { + + float d = 0.5f*V_WIDTH*idMath::Tan(DEG2RAD(90.0f)/2.0f); + + //World To Camera Coordinates + idVec3 cameraTrans(0,0,d); + idVec3 cameraPos; + cameraPos = worldPos + cameraTrans; + + //Camera To Screen Coordinates + idVec3 screenPos; + screenPos.x = d*cameraPos.x/cameraPos.z + (0.5f*V_WIDTH-0.5f); + screenPos.y = -d*cameraPos.y/cameraPos.z + (0.5f*V_HEIGHT-0.5f); + screenPos.z = cameraPos.z; + + return screenPos; +} + +idVec3 SSDEntity::ScreenToWorld(const idVec3& screenPos) { + + idVec3 worldPos; + + worldPos.x = screenPos.x - 0.5f * V_WIDTH; + worldPos.y = -(screenPos.y - 0.5f * V_HEIGHT); + worldPos.z = screenPos.z; + + return worldPos; +} + +/* +***************************************************************************** +* SSDMover +**************************************************************************** +*/ + +SSDMover::SSDMover() { +} + +SSDMover::~SSDMover() { +} + +void SSDMover::WriteToSaveGame( idFile *savefile ) { + SSDEntity::WriteToSaveGame(savefile); + + savefile->Write(&speed, sizeof(speed)); + savefile->Write(&rotationSpeed, sizeof(rotationSpeed)); +} + +void SSDMover::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDEntity::ReadFromSaveGame(savefile, _game); + + savefile->Read(&speed, sizeof(speed)); + savefile->Read(&rotationSpeed, sizeof(rotationSpeed)); +} + +void SSDMover::MoverInit(const idVec3& _speed, float _rotationSpeed) { + + speed = _speed; + rotationSpeed = _rotationSpeed; +} + +void SSDMover::EntityUpdate() { + + SSDEntity::EntityUpdate(); + + //Move forward based on speed (units per second) + idVec3 moved = ((float)elapsed/1000.0f)*speed; + position += moved; + + float rotated = ((float)elapsed/1000.0f)*rotationSpeed*360.0f; + rotation += rotated; + if(rotation >= 360) { + rotation -= 360.0f; + } + if(rotation < 0) { + rotation += 360.0f; + } +} + + +/* +***************************************************************************** +* SSDAsteroid +**************************************************************************** +*/ + +SSDAsteroid SSDAsteroid::asteroidPool[MAX_ASTEROIDS]; + +#define ASTEROID_MATERIAL "game/SSD/asteroid" + +SSDAsteroid::SSDAsteroid() { +} + +SSDAsteroid::~SSDAsteroid() { +} + +void SSDAsteroid::WriteToSaveGame( idFile *savefile ) { + SSDMover::WriteToSaveGame(savefile); + + savefile->Write(&health, sizeof(health)); +} + +void SSDAsteroid::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDMover::ReadFromSaveGame(savefile, _game); + + savefile->Read(&health, sizeof(health)); +} + +void SSDAsteroid::Init(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health) { + + EntityInit(); + MoverInit(idVec3(0,0, -_speed), rotate); + + SetGame(_game); + + type = SSD_ENTITY_ASTEROID; + + SetMaterial(ASTEROID_MATERIAL); + SetSize(_size); + SetRadius(Max(size.x, size.y), 0.3f); + SetRotation(game->random.RandomInt(360)); + + + position = startPosition; + + health = _health; +} + +void SSDAsteroid::EntityUpdate() { + + SSDMover::EntityUpdate(); +} + +SSDAsteroid* SSDAsteroid::GetNewAsteroid(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health) { + for(int i = 0; i < MAX_ASTEROIDS; i++) { + if(!asteroidPool[i].inUse) { + asteroidPool[i].Init(_game, startPosition, _size, _speed, rotate, _health); + asteroidPool[i].inUse = true; + asteroidPool[i].id = i; + + return &asteroidPool[i]; + } + } + return NULL; +} + +SSDAsteroid* SSDAsteroid::GetSpecificAsteroid(int id) { + return &asteroidPool[id]; +} + +void SSDAsteroid::WriteAsteroids(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_ASTEROIDS; i++) { + if(asteroidPool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_ASTEROIDS; i++) { + if(asteroidPool[i].inUse) { + savefile->Write(&(asteroidPool[i].id), sizeof(asteroidPool[i].id)); + asteroidPool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDAsteroid::ReadAsteroids(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDAsteroid* ent = GetSpecificAsteroid(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* SSDAstronaut +**************************************************************************** +*/ + +SSDAstronaut SSDAstronaut::astronautPool[MAX_ASTRONAUT]; + +#define ASTRONAUT_MATERIAL "game/SSD/astronaut" + +SSDAstronaut::SSDAstronaut() { +} + +SSDAstronaut::~SSDAstronaut() { +} + +void SSDAstronaut::WriteToSaveGame( idFile *savefile ) { + SSDMover::WriteToSaveGame(savefile); + + savefile->Write(&health, sizeof(health)); +} + +void SSDAstronaut::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDMover::ReadFromSaveGame(savefile, _game); + + savefile->Read(&health, sizeof(health)); +} + +void SSDAstronaut::Init(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health) { + + EntityInit(); + MoverInit(idVec3(0,0, -_speed), rotate); + + SetGame(_game); + + type = SSD_ENTITY_ASTRONAUT; + + SetMaterial(ASTRONAUT_MATERIAL); + SetSize(idVec2(256,256)); + SetRadius(Max(size.x, size.y), 0.3f); + SetRotation(game->random.RandomInt(360)); + + position = startPosition; + health = _health; +} + +SSDAstronaut* SSDAstronaut::GetNewAstronaut(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health) { + for(int i = 0; i < MAX_ASTRONAUT; i++) { + if(!astronautPool[i].inUse) { + astronautPool[i].Init(_game, startPosition, _speed, rotate, _health); + astronautPool[i].inUse = true; + astronautPool[i].id = i; + return &astronautPool[i]; + } + } + return NULL; +} + +SSDAstronaut* SSDAstronaut::GetSpecificAstronaut(int id) { + return &astronautPool[id]; + +} + +void SSDAstronaut::WriteAstronauts(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_ASTRONAUT; i++) { + if(astronautPool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_ASTRONAUT; i++) { + if(astronautPool[i].inUse) { + savefile->Write(&(astronautPool[i].id), sizeof(astronautPool[i].id)); + astronautPool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDAstronaut::ReadAstronauts(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDAstronaut* ent = GetSpecificAstronaut(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* SSDExplosion +**************************************************************************** +*/ + +SSDExplosion SSDExplosion::explosionPool[MAX_EXPLOSIONS]; + + +//#define EXPLOSION_MATERIAL "game/SSD/fball" +//#define EXPLOSION_TELEPORT "game/SSD/teleport" + +const char* explosionMaterials[] = { + "game/SSD/fball", + "game/SSD/teleport" +}; + +#define EXPLOSION_MATERIAL_COUNT 2 + +SSDExplosion::SSDExplosion() { + type = SSD_ENTITY_EXPLOSION; +} + +SSDExplosion::~SSDExplosion() { +} + +void SSDExplosion::WriteToSaveGame( idFile *savefile ) { + SSDEntity::WriteToSaveGame(savefile); + + savefile->Write(&finalSize, sizeof(finalSize)); + savefile->Write(&length, sizeof(length)); + savefile->Write(&beginTime, sizeof(beginTime)); + savefile->Write(&endTime, sizeof(endTime)); + savefile->Write(&explosionType, sizeof(explosionType)); + + + savefile->Write(&(buddy->type), sizeof(buddy->type)); + savefile->Write(&(buddy->id), sizeof(buddy->id)); + + savefile->Write(&killBuddy, sizeof(killBuddy)); + savefile->Write(&followBuddy, sizeof(followBuddy)); +} + +void SSDExplosion::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDEntity::ReadFromSaveGame(savefile, _game); + + savefile->Read(&finalSize, sizeof(finalSize)); + savefile->Read(&length, sizeof(length)); + savefile->Read(&beginTime, sizeof(beginTime)); + savefile->Read(&endTime, sizeof(endTime)); + savefile->Read(&explosionType, sizeof(explosionType)); + + int type, id; + savefile->Read(&type, sizeof(type)); + savefile->Read(&id, sizeof(id)); + + //Get a pointer to my buddy + buddy = _game->GetSpecificEntity(type, id); + + savefile->Read(&killBuddy, sizeof(killBuddy)); + savefile->Read(&followBuddy, sizeof(followBuddy)); +} + +void SSDExplosion::Init(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy, bool _followBuddy) { + + EntityInit(); + + SetGame(_game); + + type = SSD_ENTITY_EXPLOSION; + explosionType = _type; + + SetMaterial(explosionMaterials[explosionType]); + SetPosition(_position); + position.z -= 50; + + finalSize = _size; + length = _length; + beginTime = game->ssdTime; + endTime = beginTime + length; + + buddy = _buddy; + killBuddy = _killBuddy; + followBuddy = _followBuddy; + + //Explosion Starts from nothing and will increase in size until it gets to final size + size.Zero(); + + noPlayerDamage = true; + noHit = true; +} + +void SSDExplosion::EntityUpdate() { + + SSDEntity::EntityUpdate(); + + //Always set my position to my buddies position except change z to be on top + if(followBuddy) { + position = buddy->position; + position.z -= 50; + } else { + //Only mess with the z if we are not following + position.z = buddy->position.z - 50; + } + + //Scale the image based on the time + size = finalSize*((float)(currentTime-beginTime)/(float)length); + + //Destroy myself after the explosion is done + if(currentTime > endTime) { + destroyed = true; + + if(killBuddy) { + //Destroy the exploding object + buddy->destroyed = true; + } + } +} + +SSDExplosion* SSDExplosion::GetNewExplosion(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy, bool _followBuddy) { + for(int i = 0; i < MAX_EXPLOSIONS; i++) { + if(!explosionPool[i].inUse) { + explosionPool[i].Init(_game, _position, _size, _length, _type, _buddy, _killBuddy, _followBuddy); + explosionPool[i].inUse = true; + return &explosionPool[i]; + } + } + return NULL; +} + +SSDExplosion* SSDExplosion::GetSpecificExplosion(int id) { + return &explosionPool[id]; +} + +void SSDExplosion::WriteExplosions(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_EXPLOSIONS; i++) { + if(explosionPool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_EXPLOSIONS; i++) { + if(explosionPool[i].inUse) { + savefile->Write(&(explosionPool[i].id), sizeof(explosionPool[i].id)); + explosionPool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDExplosion::ReadExplosions(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDExplosion* ent = GetSpecificExplosion(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* SSDPoints +**************************************************************************** +*/ + +SSDPoints SSDPoints::pointsPool[MAX_POINTS]; + +SSDPoints::SSDPoints() { + type = SSD_ENTITY_POINTS; +} + +SSDPoints::~SSDPoints() { +} + +void SSDPoints::WriteToSaveGame( idFile *savefile ) { + SSDEntity::WriteToSaveGame(savefile); + + savefile->Write(&length, sizeof(length)); + savefile->Write(&distance, sizeof(distance)); + savefile->Write(&beginTime, sizeof(beginTime)); + savefile->Write(&endTime, sizeof(endTime)); + + savefile->Write(&beginPosition, sizeof(beginPosition)); + savefile->Write(&endPosition, sizeof(endPosition)); + + savefile->Write(&beginColor, sizeof(beginColor)); + savefile->Write(&endColor, sizeof(endColor)); + +} + +void SSDPoints::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDEntity::ReadFromSaveGame(savefile, _game); + + savefile->Read(&length, sizeof(length)); + savefile->Read(&distance, sizeof(distance)); + savefile->Read(&beginTime, sizeof(beginTime)); + savefile->Read(&endTime, sizeof(endTime)); + + savefile->Read(&beginPosition, sizeof(beginPosition)); + savefile->Read(&endPosition, sizeof(endPosition)); + + savefile->Read(&beginColor, sizeof(beginColor)); + savefile->Read(&endColor, sizeof(endColor)); +} + +void SSDPoints::Init(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color) { + + EntityInit(); + + SetGame(_game); + + length = _length; + distance = _distance; + beginTime = game->ssdTime; + endTime = beginTime + length; + + textScale = 0.4f; + text = va("%d", _points); + + float width = 0; + for(int i = 0; i < text.Length(); i++) { + width += game->GetDC()->CharWidth(text[i], textScale); + } + + size.Set(0,0); + + //Set the start position at the top of the passed in entity + position = WorldToScreen(_ent->position); + position = ScreenToWorld(position); + + position.z = 0; + position.x -= (width/2.0f); + + beginPosition = position; + + endPosition = beginPosition; + endPosition.y += _distance; + + //beginColor.Set(0,1,0,1); + endColor.Set(1,1,1,0); + + beginColor = color; + beginColor.w = 1; + + noPlayerDamage = true; + noHit = true; +} + +void SSDPoints::EntityUpdate() { + + float t = (float)(currentTime - beginTime)/(float)length; + + //Move up from the start position + position.Lerp(beginPosition, endPosition, t); + + //Interpolate the color + foreColor.Lerp(beginColor, endColor, t); + + if(currentTime > endTime) { + destroyed = true; + } +} + +SSDPoints* SSDPoints::GetNewPoints(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color) { + for(int i = 0; i < MAX_POINTS; i++) { + if(!pointsPool[i].inUse) { + pointsPool[i].Init(_game, _ent, _points, _length, _distance, color); + pointsPool[i].inUse = true; + return &pointsPool[i]; + } + } + return NULL; +} + +SSDPoints* SSDPoints::GetSpecificPoints(int id) { + return &pointsPool[id]; +} + +void SSDPoints::WritePoints(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_POINTS; i++) { + if(pointsPool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_POINTS; i++) { + if(pointsPool[i].inUse) { + savefile->Write(&(pointsPool[i].id), sizeof(pointsPool[i].id)); + pointsPool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDPoints::ReadPoints(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDPoints* ent = GetSpecificPoints(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* SSDProjectile +**************************************************************************** +*/ + +SSDProjectile SSDProjectile::projectilePool[MAX_PROJECTILES]; + +#define PROJECTILE_MATERIAL "game/SSD/fball" + +SSDProjectile::SSDProjectile() { + type = SSD_ENTITY_PROJECTILE; +} + +SSDProjectile::~SSDProjectile() { +} + +void SSDProjectile::WriteToSaveGame( idFile *savefile ) { + SSDEntity::WriteToSaveGame(savefile); + + savefile->Write(&dir, sizeof(dir)); + savefile->Write(&speed, sizeof(speed)); + savefile->Write(&beginTime, sizeof(beginTime)); + savefile->Write(&endTime, sizeof(endTime)); + + savefile->Write(&endPosition, sizeof(endPosition)); +} + +void SSDProjectile::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDEntity::ReadFromSaveGame(savefile, _game); + + savefile->Read(&dir, sizeof(dir)); + savefile->Read(&speed, sizeof(speed)); + savefile->Read(&beginTime, sizeof(beginTime)); + savefile->Read(&endTime, sizeof(endTime)); + + savefile->Read(&endPosition, sizeof(endPosition)); +} + +void SSDProjectile::Init(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size) { + + EntityInit(); + + SetGame(_game); + + SetMaterial(PROJECTILE_MATERIAL); + size.Set(_size,_size); + + position = _beginPosition; + endPosition = _endPosition; + + dir = _endPosition - position; + dir.Normalize(); + + //speed.Zero(); + speed.x = speed.y = speed.z = _speed; + + noHit = true; +} + +void SSDProjectile::EntityUpdate() { + + SSDEntity::EntityUpdate(); + + //Move forward based on speed (units per second) + idVec3 moved = dir*((float)elapsed/1000.0f)*speed.z; + position += moved; + + if(position.z > endPosition.z) { + //We have reached our position + destroyed = true; + } +} + +SSDProjectile* SSDProjectile::GetNewProjectile(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size) { + for(int i = 0; i < MAX_PROJECTILES; i++) { + if(!projectilePool[i].inUse) { + projectilePool[i].Init(_game, _beginPosition, _endPosition, _speed, _size); + projectilePool[i].inUse = true; + return &projectilePool[i]; + } + } + return NULL; +} + +SSDProjectile* SSDProjectile::GetSpecificProjectile(int id) { + return &projectilePool[id]; +} + +void SSDProjectile::WriteProjectiles(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_PROJECTILES; i++) { + if(projectilePool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_PROJECTILES; i++) { + if(projectilePool[i].inUse) { + savefile->Write(&(projectilePool[i].id), sizeof(projectilePool[i].id)); + projectilePool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDProjectile::ReadProjectiles(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDProjectile* ent = GetSpecificProjectile(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* SSDPowerup +**************************************************************************** +*/ + +const char* powerupMaterials[][2] = { + "game/SSD/powerupHealthClosed", "game/SSD/powerupHealthOpen", + "game/SSD/powerupSuperBlasterClosed", "game/SSD/powerupSuperBlasterOpen", + "game/SSD/powerupNukeClosed", "game/SSD/powerupNukeOpen", + "game/SSD/powerupRescueClosed", "game/SSD/powerupRescueOpen", + "game/SSD/powerupBonusPointsClosed", "game/SSD/powerupBonusPointsOpen", + "game/SSD/powerupDamageClosed", "game/SSD/powerupDamageOpen", +}; + +#define POWERUP_MATERIAL_COUNT 6 + +SSDPowerup SSDPowerup::powerupPool[MAX_POWERUPS]; + +SSDPowerup::SSDPowerup() { + +} + +SSDPowerup::~SSDPowerup() { +} + +void SSDPowerup::WriteToSaveGame( idFile *savefile ) { + SSDMover::WriteToSaveGame(savefile); + + savefile->Write(&powerupState, sizeof(powerupState)); + savefile->Write(&powerupType, sizeof(powerupType)); +} + +void SSDPowerup::ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ) { + SSDMover::ReadFromSaveGame(savefile, _game); + + savefile->Read(&powerupState, sizeof(powerupState)); + savefile->Read(&powerupType, sizeof(powerupType)); +} + +void SSDPowerup::OnHit(int key) { + + if(powerupState == POWERUP_STATE_CLOSED) { + + //Small explosion to indicate it is opened + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(game, position, size*2.0f, 300, SSDExplosion::EXPLOSION_NORMAL, this, false, true); + game->entities.Append(explosion); + + + powerupState = POWERUP_STATE_OPEN; + SetMaterial(powerupMaterials[powerupType][powerupState]); + } else { + //Destory the powerup with a big explosion + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(game, position, size*2, 300, SSDExplosion::EXPLOSION_NORMAL, this); + game->entities.Append(explosion); + game->PlaySound("arcade_explode"); + + noHit = true; + noPlayerDamage = true; + } +} + +void SSDPowerup::OnStrikePlayer() { + + if(powerupState == POWERUP_STATE_OPEN) { + //The powerup was open so activate it + OnActivatePowerup(); + } + + //Just destroy the powerup + destroyed = true; +} + +void SSDPowerup::OnOpenPowerup() { +} + +void SSDPowerup::OnActivatePowerup() { + switch(powerupType) { + case POWERUP_TYPE_HEALTH: + { + game->AddHealth(10); + break; + } + case POWERUP_TYPE_SUPER_BLASTER: + { + game->OnSuperBlaster(); + break; + } + case POWERUP_TYPE_ASTEROID_NUKE: + { + game->OnNuke(); + break; + } + case POWERUP_TYPE_RESCUE_ALL: + { + game->OnRescueAll(); + break; + } + case POWERUP_TYPE_BONUS_POINTS: + { + int points = (game->random.RandomInt(5)+1) * 100; + game->AddScore(this, points); + break; + } + case POWERUP_TYPE_DAMAGE: + { + game->AddDamage(10); + game->PlaySound("arcade_explode"); + break; + } + + } +} + + +void SSDPowerup::Init(idGameSSDWindow* _game, float _speed, float _rotation) { + + EntityInit(); + MoverInit(idVec3(0,0, -_speed), _rotation); + + SetGame(_game); + SetSize(idVec2(200,200)); + SetRadius(Max(size.x, size.y), 0.3f); + + type = SSD_ENTITY_POWERUP; + + idVec3 startPosition; + startPosition.x = game->random.RandomInt(V_WIDTH)-(V_WIDTH/2.0f); + startPosition.y = game->random.RandomInt(V_HEIGHT)-(V_HEIGHT/2.0f); + startPosition.z = ENTITY_START_DIST; + + position = startPosition; + //SetPosition(startPosition); + + powerupState = POWERUP_STATE_CLOSED; + powerupType = game->random.RandomInt(POWERUP_TYPE_MAX+1); + if(powerupType >= POWERUP_TYPE_MAX) { + powerupType = 0; + } + + /*OutputDebugString(va("Powerup: %d\n", powerupType)); + if(powerupType == 0) { + int x = 0; + }*/ + + SetMaterial(powerupMaterials[powerupType][powerupState]); +} + +SSDPowerup* SSDPowerup::GetNewPowerup(idGameSSDWindow* _game, float _speed, float _rotation) { + + for(int i = 0; i < MAX_POWERUPS; i++) { + if(!powerupPool[i].inUse) { + powerupPool[i].Init(_game, _speed, _rotation); + powerupPool[i].inUse = true; + return &powerupPool[i]; + } + } + return NULL; +} + +SSDPowerup* SSDPowerup::GetSpecificPowerup(int id) { + return &powerupPool[id]; +} + +void SSDPowerup::WritePowerups(idFile* savefile) { + int count = 0; + for(int i = 0; i < MAX_POWERUPS; i++) { + if(powerupPool[i].inUse) { + count++; + } + } + savefile->Write(&count, sizeof(count)); + for(int i = 0; i < MAX_POWERUPS; i++) { + if(powerupPool[i].inUse) { + savefile->Write(&(powerupPool[i].id), sizeof(powerupPool[i].id)); + powerupPool[i].WriteToSaveGame(savefile); + } + } +} + +void SSDPowerup::ReadPowerups(idFile* savefile, idGameSSDWindow* _game) { + + int count; + savefile->Read(&count, sizeof(count)); + for(int i = 0; i < count; i++) { + int id; + savefile->Read(&id, sizeof(id)); + SSDPowerup* ent = GetSpecificPowerup(id); + ent->ReadFromSaveGame(savefile, _game); + } +} + +/* +***************************************************************************** +* idGameSSDWindow +**************************************************************************** +*/ + +idRandom idGameSSDWindow::random; + +idGameSSDWindow::idGameSSDWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idGameSSDWindow::idGameSSDWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idGameSSDWindow::~idGameSSDWindow() { + ResetGameStats(); +} + +void idGameSSDWindow::WriteToSaveGame( idFile *savefile ) { + idWindow::WriteToSaveGame(savefile); + + savefile->Write(&ssdTime, sizeof(ssdTime)); + + beginLevel.WriteToSaveGame(savefile); + resetGame.WriteToSaveGame(savefile); + continueGame.WriteToSaveGame(savefile); + refreshGuiData.WriteToSaveGame(savefile); + + crosshair.WriteToSaveGame(savefile); + savefile->Write(&screenBounds, sizeof(screenBounds)); + + savefile->Write(&levelCount, sizeof(levelCount)); + for(int i = 0; i < levelCount; i++) { + savefile->Write(&(levelData[i]), sizeof(SSDLevelData_t)); + savefile->Write(&(asteroidData[i]), sizeof(SSDAsteroidData_t)); + savefile->Write(&(astronautData[i]), sizeof(SSDAstronautData_t)); + savefile->Write(&(powerupData[i]), sizeof(SSDPowerupData_t)); + } + + savefile->Write(&weaponCount, sizeof(weaponCount)); + for(int i = 0; i < weaponCount; i++) { + savefile->Write(&(weaponData[i]), sizeof(SSDWeaponData_t)); + } + + savefile->Write(&superBlasterTimeout, sizeof(superBlasterTimeout)); + savefile->Write(&gameStats, sizeof(SSDGameStats_t)); + + //Write All Static Entities + SSDAsteroid::WriteAsteroids(savefile); + SSDAstronaut::WriteAstronauts(savefile); + SSDExplosion::WriteExplosions(savefile); + SSDPoints::WritePoints(savefile); + SSDProjectile::WriteProjectiles(savefile); + SSDPowerup::WritePowerups(savefile); + + int entCount = entities.Num(); + savefile->Write(&entCount, sizeof(entCount)); + for(int i = 0; i < entCount; i++) { + savefile->Write(&(entities[i]->type), sizeof(entities[i]->type)); + savefile->Write(&(entities[i]->id), sizeof(entities[i]->id)); + } +} + +void idGameSSDWindow::ReadFromSaveGame( idFile *savefile ) { + idWindow::ReadFromSaveGame(savefile); + + + savefile->Read(&ssdTime, sizeof(ssdTime)); + + beginLevel.ReadFromSaveGame(savefile); + resetGame.ReadFromSaveGame(savefile); + continueGame.ReadFromSaveGame(savefile); + refreshGuiData.ReadFromSaveGame(savefile); + + crosshair.ReadFromSaveGame(savefile); + savefile->Read(&screenBounds, sizeof(screenBounds)); + + savefile->Read(&levelCount, sizeof(levelCount)); + for(int i = 0; i < levelCount; i++) { + SSDLevelData_t newLevel; + savefile->Read(&newLevel, sizeof(SSDLevelData_t)); + levelData.Append(newLevel); + + SSDAsteroidData_t newAsteroid; + savefile->Read(&newAsteroid, sizeof(SSDAsteroidData_t)); + asteroidData.Append(newAsteroid); + + SSDAstronautData_t newAstronaut; + savefile->Read(&newAstronaut, sizeof(SSDAstronautData_t)); + astronautData.Append(newAstronaut); + + SSDPowerupData_t newPowerup; + savefile->Read(&newPowerup, sizeof(SSDPowerupData_t)); + powerupData.Append(newPowerup); + } + + savefile->Read(&weaponCount, sizeof(weaponCount)); + for(int i = 0; i < weaponCount; i++) { + SSDWeaponData_t newWeapon; + savefile->Read(&newWeapon, sizeof(SSDWeaponData_t)); + weaponData.Append(newWeapon); + } + + savefile->Read(&superBlasterTimeout, sizeof(superBlasterTimeout)); + + savefile->Read(&gameStats, sizeof(SSDGameStats_t)); + //Reset this because it is no longer valid + gameStats.levelStats.targetEnt = NULL; + + SSDAsteroid::ReadAsteroids(savefile, this); + SSDAstronaut::ReadAstronauts(savefile, this); + SSDExplosion::ReadExplosions(savefile, this); + SSDPoints::ReadPoints(savefile, this); + SSDProjectile::ReadProjectiles(savefile, this); + SSDPowerup::ReadPowerups(savefile, this); + + int entCount; + savefile->Read(&entCount, sizeof(entCount)); + + for(int i = 0; i < entCount; i++) { + int type, id; + savefile->Read(&type, sizeof(type)); + savefile->Read(&id, sizeof(id)); + + SSDEntity* ent = GetSpecificEntity(type, id); + if(ent) { + entities.Append(ent); + } + } +} + +const char *idGameSSDWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + + // need to call this to allow proper focus and capturing on embedded children + const char *ret = idWindow::HandleEvent(event, updateVisuals); + + if(!gameStats.gameRunning) { + return ret; + } + + int key = event->evValue; + + if ( event->evType == SE_KEY ) { + + if ( !event->evValue2 ) { + return ret; + } + + if ( key == K_MOUSE1 || key == K_MOUSE2) { + FireWeapon(key); + } else { + return ret; + } + } + return ret; +} + +idWinVar *idGameSSDWindow::GetWinVarByName (const char *_name, bool winLookup, drawWin_t** owner) { + + idWinVar *retVar = NULL; + + if (idStr::Icmp(_name, "beginLevel") == 0) { + retVar = &beginLevel; + } + + if (idStr::Icmp(_name, "resetGame") == 0) { + retVar = &resetGame; + } + + if (idStr::Icmp(_name, "continueGame") == 0) { + retVar = &continueGame; + } + if (idStr::Icmp(_name, "refreshGuiData") == 0) { + retVar = &refreshGuiData; + } + + + if(retVar) { + return retVar; + } + + return idWindow::GetWinVarByName(_name, winLookup, owner); +} + + +void idGameSSDWindow::Draw(int time, float x, float y) { + + //Update the game every frame before drawing + UpdateGame(); + + RefreshGuiData(); + + if(gameStats.gameRunning) { + + ZOrderEntities(); + + //Draw from back to front + for(int i = entities.Num()-1; i >= 0; i--) { + entities[i]->Draw(dc); + } + + //The last thing to draw is the crosshair + idVec2 cursor; + //GetCursor(cursor); + cursor.x = gui->CursorX(); + cursor.y = gui->CursorY(); + + crosshair.Draw(dc, cursor); + } +} + + +bool idGameSSDWindow::ParseInternalVar(const char *_name, idParser *src) { + + if (idStr::Icmp(_name, "beginLevel") == 0) { + beginLevel = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "resetGame") == 0) { + resetGame = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "continueGame") == 0) { + continueGame = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "refreshGuiData") == 0) { + refreshGuiData = src->ParseBool(); + return true; + } + + if(idStr::Icmp(_name, "levelcount") == 0) { + levelCount = src->ParseInt(); + for(int i = 0; i < levelCount; i++) { + SSDLevelData_t newLevel; + memset(&newLevel, 0, sizeof(SSDLevelData_t)); + levelData.Append(newLevel); + + SSDAsteroidData_t newAsteroid; + memset(&newAsteroid, 0, sizeof(SSDAsteroidData_t)); + asteroidData.Append(newAsteroid); + + SSDAstronautData_t newAstronaut; + memset(&newAstronaut, 0, sizeof(SSDAstronautData_t)); + astronautData.Append(newAstronaut); + + SSDPowerupData_t newPowerup; + memset(&newPowerup, 0, sizeof(SSDPowerupData_t)); + powerupData.Append(newPowerup); + + + } + return true; + } + if(idStr::Icmp(_name, "weaponCount") == 0) { + weaponCount = src->ParseInt(); + for(int i = 0; i < weaponCount; i++) { + SSDWeaponData_t newWeapon; + memset(&newWeapon, 0, sizeof(SSDWeaponData_t)); + weaponData.Append(newWeapon); + } + return true; + } + + if(idStr::FindText(_name, "leveldata", false) >= 0) { + idStr tempName = _name; + int level = atoi(tempName.Right(2))-1; + + idStr levelData; + ParseString(src, levelData); + ParseLevelData(level, levelData); + return true; + } + + if(idStr::FindText(_name, "asteroiddata", false) >= 0) { + idStr tempName = _name; + int level = atoi(tempName.Right(2))-1; + + idStr asteroidData; + ParseString(src, asteroidData); + ParseAsteroidData(level, asteroidData); + return true; + } + + if(idStr::FindText(_name, "weapondata", false) >= 0) { + idStr tempName = _name; + int weapon = atoi(tempName.Right(2))-1; + + idStr weaponData; + ParseString(src, weaponData); + ParseWeaponData(weapon, weaponData); + return true; + } + + if(idStr::FindText(_name, "astronautdata", false) >= 0) { + idStr tempName = _name; + int level = atoi(tempName.Right(2))-1; + + idStr astronautData; + ParseString(src, astronautData); + ParseAstronautData(level, astronautData); + return true; + } + + if(idStr::FindText(_name, "powerupdata", false) >= 0) { + idStr tempName = _name; + int level = atoi(tempName.Right(2))-1; + + idStr powerupData; + ParseString(src, powerupData); + ParsePowerupData(level, powerupData); + return true; + } + + return idWindow::ParseInternalVar(_name, src); +} + +void idGameSSDWindow::ParseLevelData(int level, const idStr& levelDataString) { + + idParser parser; + idToken token; + parser.LoadMemory(levelDataString.c_str(), levelDataString.Length(), "LevelData"); + + levelData[level].spawnBuffer = parser.ParseFloat(); + levelData[level].needToWin = parser.ParseInt(); //Required Destroyed + +} + +void idGameSSDWindow::ParseAsteroidData(int level, const idStr& asteroidDataString) { + + idParser parser; + idToken token; + parser.LoadMemory(asteroidDataString.c_str(), asteroidDataString.Length(), "AsteroidData"); + + asteroidData[level].speedMin = parser.ParseFloat(); //Speed Min + asteroidData[level].speedMax = parser.ParseFloat(); //Speed Max + + asteroidData[level].sizeMin = parser.ParseFloat(); //Size Min + asteroidData[level].sizeMax = parser.ParseFloat(); //Size Max + + asteroidData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second) + asteroidData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second) + + asteroidData[level].spawnMin = parser.ParseInt(); //Spawn Min + asteroidData[level].spawnMax = parser.ParseInt(); //Spawn Max + + asteroidData[level].asteroidHealth = parser.ParseInt(); //Health of the asteroid + asteroidData[level].asteroidDamage = parser.ParseInt(); //Asteroid Damage + asteroidData[level].asteroidPoints = parser.ParseInt(); //Points awarded for destruction +} + +void idGameSSDWindow::ParsePowerupData(int level, const idStr& powerupDataString) { + + idParser parser; + idToken token; + parser.LoadMemory(powerupDataString.c_str(), powerupDataString.Length(), "PowerupData"); + + powerupData[level].speedMin = parser.ParseFloat(); //Speed Min + powerupData[level].speedMax = parser.ParseFloat(); //Speed Max + + powerupData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second) + powerupData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second) + + powerupData[level].spawnMin = parser.ParseInt(); //Spawn Min + powerupData[level].spawnMax = parser.ParseInt(); //Spawn Max + +} + +void idGameSSDWindow::ParseWeaponData(int weapon, const idStr& weaponDataString) { + + idParser parser; + idToken token; + parser.LoadMemory(weaponDataString.c_str(), weaponDataString.Length(), "WeaponData"); + + weaponData[weapon].speed = parser.ParseFloat(); + weaponData[weapon].damage = parser.ParseFloat(); + weaponData[weapon].size = parser.ParseFloat(); +} + +void idGameSSDWindow::ParseAstronautData(int level, const idStr& astronautDataString) { + + idParser parser; + idToken token; + parser.LoadMemory(astronautDataString.c_str(), astronautDataString.Length(), "AstronautData"); + + astronautData[level].speedMin = parser.ParseFloat(); //Speed Min + astronautData[level].speedMax = parser.ParseFloat(); //Speed Max + + astronautData[level].rotateMin = parser.ParseFloat(); //Rotate Min (rotations per second) + astronautData[level].rotateMax = parser.ParseFloat(); //Rotate Max (rotations per second) + + astronautData[level].spawnMin = parser.ParseInt(); //Spawn Min + astronautData[level].spawnMax = parser.ParseInt(); //Spawn Max + + astronautData[level].health = parser.ParseInt(); //Health of the asteroid + astronautData[level].points = parser.ParseInt(); //Asteroid Damage + astronautData[level].penalty = parser.ParseInt(); //Points awarded for destruction +} + +void idGameSSDWindow::CommonInit() { + crosshair.InitCrosshairs(); + + + beginLevel = false; + resetGame = false; + continueGame = false; + refreshGuiData = false; + + ssdTime = 0; + levelCount = 0; + weaponCount = 0; + screenBounds = idBounds(idVec3(-320,-240,0), idVec3(320,240,0)); + + superBlasterTimeout = 0; + + currentSound = 0; + + //Precahce all assets that are loaded dynamically + declManager->FindMaterial(ASTEROID_MATERIAL); + declManager->FindMaterial(ASTRONAUT_MATERIAL); + + for(int i = 0; i < EXPLOSION_MATERIAL_COUNT; i++) { + declManager->FindMaterial(explosionMaterials[i]); + } + declManager->FindMaterial(PROJECTILE_MATERIAL); + for(int i = 0; i < POWERUP_MATERIAL_COUNT; i++) { + declManager->FindMaterial(powerupMaterials[i][0]); + declManager->FindMaterial(powerupMaterials[i][1]); + } + + // Precache sounds + declManager->FindSound( "arcade_blaster" ); + declManager->FindSound( "arcade_capture " ); + declManager->FindSound( "arcade_explode" ); + + ResetGameStats(); +} + +void idGameSSDWindow::ResetGameStats() { + + ResetEntities(); + + //Reset the gamestats structure + memset(&gameStats, 0, sizeof(gameStats)); + + gameStats.health = 100; + +} + +void idGameSSDWindow::ResetLevelStats() { + + ResetEntities(); + + //Reset the level statistics structure + memset(&gameStats.levelStats, 0, sizeof(gameStats.levelStats)); + + +} + +void idGameSSDWindow::ResetEntities() { + //Destroy all of the entities + for(int i = 0; i < entities.Num(); i++) { + entities[i]->DestroyEntity(); + } + entities.Clear(); +} + +void idGameSSDWindow::StartGame() { + + gameStats.gameRunning = true; +} + +void idGameSSDWindow::StopGame() { + + gameStats.gameRunning = false; +} + +void idGameSSDWindow::GameOver() { + + + StopGame(); + + gui->HandleNamedEvent("gameOver"); +} + +void idGameSSDWindow::BeginLevel(int level) { + + ResetLevelStats(); + + gameStats.currentLevel = level; + + StartGame(); +} + +/** +* Continue game resets the players health +*/ +void idGameSSDWindow::ContinueGame() { + gameStats.health = 100; + + StartGame(); +} + +void idGameSSDWindow::LevelComplete() { + + gameStats.prebonusscore = gameStats.score; + + // Add the bonuses + int accuracy; + if( !gameStats.levelStats.shotCount ) { + accuracy = 0; + } else { + accuracy = (int)( ( (float)gameStats.levelStats.hitCount / (float)gameStats.levelStats.shotCount ) * 100.0f ); + } + int accuracyPoints = Max( 0, accuracy - 50 ) * 20; + + gui->SetStateString("player_accuracy_score", va("%i", accuracyPoints)); + + gameStats.score += accuracyPoints; + + int saveAccuracy; + int totalAst = gameStats.levelStats.savedAstronauts + gameStats.levelStats.killedAstronauts; + if( !totalAst ) { + saveAccuracy = 0; + } else { + saveAccuracy = (int)( ( (float)gameStats.levelStats.savedAstronauts / (float)totalAst ) * 100.0f ); + } + accuracyPoints = Max( 0, saveAccuracy - 50 ) * 20; + + gui->SetStateString("save_accuracy_score", va("%i", accuracyPoints)); + + gameStats.score += accuracyPoints; + + + + StopSuperBlaster(); + + gameStats.nextLevel++; + + if(gameStats.nextLevel >= levelCount) { + //Have they beaten the game + GameComplete(); + } else { + + //Make sure we don't go above the levelcount + //min(gameStats.nextLevel, levelCount-1); + + StopGame(); + gui->HandleNamedEvent("levelComplete"); + } +} + +void idGameSSDWindow::GameComplete() { + StopGame(); + gui->HandleNamedEvent("gameComplete"); +} + + +void idGameSSDWindow::UpdateGame() { + + //Check to see if and functions where called by the gui + if(beginLevel == true) { + beginLevel = false; + BeginLevel(gameStats.nextLevel); + } + if(resetGame == true) { + resetGame = false; + ResetGameStats(); + } + if(continueGame == true) { + continueGame = false; + ContinueGame(); + } + if(refreshGuiData == true) { + refreshGuiData = false; + RefreshGuiData(); + } + + if(gameStats.gameRunning) { + + //We assume an upate every 16 milliseconds + ssdTime += 16; + + if(superBlasterTimeout && ssdTime > superBlasterTimeout) { + StopSuperBlaster(); + } + + //Find if we are targeting and enemy + idVec2 cursor; + //GetCursor(cursor); + cursor.x = gui->CursorX(); + cursor.y = gui->CursorY(); + gameStats.levelStats.targetEnt = EntityHitTest(cursor); + + //Update from back to front + for(int i = entities.Num()-1; i >= 0; i--) { + entities[i]->Update(); + } + + CheckForHits(); + + //Delete entities that need to be deleted + for(int i = entities.Num()-1; i >= 0; i--) { + if(entities[i]->destroyed) { + SSDEntity* ent = entities[i]; + ent->DestroyEntity(); + entities.RemoveIndex(i); + } + } + + //Check if we can spawn an asteroid + SpawnAsteroid(); + + //Check if we should spawn an astronaut + SpawnAstronaut(); + + //Check if we should spawn an asteroid + SpawnPowerup(); + } +} + +void idGameSSDWindow::CheckForHits() { + + //See if the entity has gotten close enough + for(int i = 0; i < entities.Num(); i++) { + SSDEntity* ent = entities[i]; + if(ent->position.z <= Z_NEAR) { + + if(!ent->noPlayerDamage) { + + //Is the object still in the screen + idVec3 entPos = ent->position; + entPos.z = 0; + + idBounds entBounds(entPos); + entBounds.ExpandSelf(ent->hitRadius); + + if(screenBounds.IntersectsBounds(entBounds)) { + + ent->OnStrikePlayer(); + + //The entity hit the player figure out what is was and act appropriately + if(ent->type == SSD_ENTITY_ASTEROID) { + AsteroidStruckPlayer(static_cast(ent)); + } else if(ent->type == SSD_ENTITY_ASTRONAUT) { + AstronautStruckPlayer(static_cast(ent)); + } + } else { + //Tag for removal later in the frame + ent->destroyed = true; + } + } + } + } +} + +void idGameSSDWindow::ZOrderEntities() { + //Z-Order the entities + //Using a simple sorting method + for (int i = entities.Num()-1; i >= 0; i--) { + bool flipped = false; + for (int j = 0; jposition.z > entities[j+1]->position.z) { + SSDEntity* ent = entities[j]; + entities[j] = entities[j+1]; + entities[j+1] = ent; + flipped = true; + } + } + if (!flipped) { + //Jump out because it is sorted + break; + } + } +} + +void idGameSSDWindow::SpawnAsteroid() { + + int currentTime = ssdTime; + + if(currentTime < gameStats.levelStats.nextAsteroidSpawnTime) { + //Not time yet + return; + } + + //Lets spawn it + idVec3 startPosition; + + float spawnBuffer = levelData[gameStats.currentLevel].spawnBuffer*2.0f; + startPosition.x = random.RandomInt(V_WIDTH+spawnBuffer)-((V_WIDTH/2.0f)+spawnBuffer); + startPosition.y = random.RandomInt(V_HEIGHT+spawnBuffer)-((V_HEIGHT/2.0f)+spawnBuffer); + startPosition.z = ENTITY_START_DIST; + + float speed = random.RandomInt(asteroidData[gameStats.currentLevel].speedMax - asteroidData[gameStats.currentLevel].speedMin) + asteroidData[gameStats.currentLevel].speedMin; + float size = random.RandomInt(asteroidData[gameStats.currentLevel].sizeMax - asteroidData[gameStats.currentLevel].sizeMin) + asteroidData[gameStats.currentLevel].sizeMin; + float rotate = (random.RandomFloat() * (asteroidData[gameStats.currentLevel].rotateMax - asteroidData[gameStats.currentLevel].rotateMin)) + asteroidData[gameStats.currentLevel].rotateMin; + + SSDAsteroid* asteroid = SSDAsteroid::GetNewAsteroid(this, startPosition, idVec2(size, size), speed, rotate, asteroidData[gameStats.currentLevel].asteroidHealth); + entities.Append(asteroid); + + gameStats.levelStats.nextAsteroidSpawnTime = currentTime + random.RandomInt(asteroidData[gameStats.currentLevel].spawnMax - asteroidData[gameStats.currentLevel].spawnMin) + asteroidData[gameStats.currentLevel].spawnMin; +} + +void idGameSSDWindow::FireWeapon(int key) { + + idVec2 cursorWorld = GetCursorWorld(); + idVec2 cursor; + //GetCursor(cursor); + cursor.x = gui->CursorX(); + cursor.y = gui->CursorY(); + + if(key == K_MOUSE1) { + + gameStats.levelStats.shotCount++; + + if(gameStats.levelStats.targetEnt) { + //Aim the projectile from the bottom of the screen directly at the ent + //SSDProjectile* newProj = new SSDProjectile(this, idVec3(320,0,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size); + SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size); + entities.Append(newProj); + //newProj = SSDProjectile::GetNewProjectile(this, idVec3(-320,-0,0), gameStats.levelStats.targetEnt->position, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size); + //entities.Append(newProj); + + //We hit something + gameStats.levelStats.hitCount++; + + gameStats.levelStats.targetEnt->OnHit(key); + + if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTEROID) { + HitAsteroid(static_cast(gameStats.levelStats.targetEnt), key); + } else if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) { + HitAstronaut(static_cast(gameStats.levelStats.targetEnt), key); + } else if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) { + + } + } else { + ////Aim the projectile at the cursor position all the way to the far clipping + //SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), idVec3(cursorWorld.x, cursorWorld.y, (Z_FAR-Z_NEAR)/2.0f), weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size); + + //Aim the projectile so it crosses the cursor 1/4 of screen + idVec3 vec = idVec3(cursorWorld.x, cursorWorld.y, (Z_FAR-Z_NEAR)/8.0f); + vec *= 8; + SSDProjectile* newProj = SSDProjectile::GetNewProjectile(this, idVec3(0,-180,0), vec, weaponData[gameStats.currentWeapon].speed, weaponData[gameStats.currentWeapon].size); + entities.Append(newProj); + + } + + + //Play the blaster sound + PlaySound("arcade_blaster"); + + } /*else if (key == K_MOUSE2) { + if(gameStats.levelStats.targetEnt) { + if(gameStats.levelStats.targetEnt->type == SSD_ENTITY_ASTRONAUT) { + HitAstronaut(static_cast(gameStats.levelStats.targetEnt), key); + } + } + }*/ +} + +SSDEntity* idGameSSDWindow::EntityHitTest(const idVec2& pt) { + + for(int i = 0; i < entities.Num(); i++) { + //Since we ZOrder the entities every frame we can stop at the first entity we hit. + //ToDo: Make sure this assumption is true + if(entities[i]->HitTest(pt)) { + return entities[i]; + } + } + return NULL; +} + +void idGameSSDWindow::HitAsteroid(SSDAsteroid* asteroid, int key) { + + + + asteroid->health -= weaponData[gameStats.currentWeapon].damage; + + if(asteroid->health <= 0) { + + //The asteroid has been destroyed + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, asteroid); + entities.Append(explosion); + PlaySound("arcade_explode"); + + AddScore(asteroid, asteroidData[gameStats.currentLevel].asteroidPoints); + + //Don't let the player hit it anymore because + asteroid->noHit = true; + + gameStats.levelStats.destroyedAsteroids++; + //if(gameStats.levelStats.destroyedAsteroids >= levelData[gameStats.currentLevel].needToWin) { + // LevelComplete(); + //} + + } else { + //This was a damage hit so create a real small quick explosion + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size/2.0f, 200, SSDExplosion::EXPLOSION_NORMAL, asteroid, false, false); + entities.Append(explosion); + } +} + +void idGameSSDWindow::AsteroidStruckPlayer(SSDAsteroid* asteroid) { + + asteroid->noPlayerDamage = true; + asteroid->noHit = true; + + AddDamage(asteroidData[gameStats.currentLevel].asteroidDamage); + + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, asteroid->position, asteroid->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, asteroid); + entities.Append(explosion); + PlaySound("arcade_explode"); +} + +void idGameSSDWindow::AddScore(SSDEntity* ent, int points) { + + SSDPoints* pointsEnt; + + if(points > 0) { + pointsEnt = SSDPoints::GetNewPoints(this, ent, points, 1000, 50, idVec4(0,1,0,1)); + } else { + pointsEnt = SSDPoints::GetNewPoints(this, ent, points, 1000, 50, idVec4(1,0,0,1)); + } + entities.Append(pointsEnt); + + gameStats.score += points; + gui->SetStateString( "player_score", va("%i", gameStats.score ) ); +} + +void idGameSSDWindow::AddDamage(int damage) { + gameStats.health -= damage; + gui->SetStateString( "player_health", va("%i", gameStats.health ) ); + + gui->HandleNamedEvent( "playerDamage" ); + + if(gameStats.health <= 0) { + //The player is dead + GameOver(); + } +} + +void idGameSSDWindow::AddHealth(int health) { + gameStats.health += health; + gameStats.health = Min( 100, gameStats.health ); +} + + +void idGameSSDWindow::OnNuke() { + + gui->HandleNamedEvent("nuke"); + + //Destory All Asteroids + for(int i = 0 ; i < entities.Num(); i++) { + + if(entities[i]->type == SSD_ENTITY_ASTEROID) { + + //The asteroid has been destroyed + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, entities[i]->position, entities[i]->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, entities[i]); + entities.Append(explosion); + + AddScore(entities[i], asteroidData[gameStats.currentLevel].asteroidPoints); + + //Don't let the player hit it anymore because + entities[i]->noHit = true; + + gameStats.levelStats.destroyedAsteroids++; + } + } + PlaySound("arcade_explode"); + + //Check to see if a nuke ends the level + /*if(gameStats.levelStats.destroyedAsteroids >= levelData[gameStats.currentLevel].needToWin) { + LevelComplete(); + + }*/ +} + +void idGameSSDWindow::OnRescueAll() { + + gui->HandleNamedEvent("rescueAll"); + + //Rescue All Astronauts + for(int i = 0 ; i < entities.Num(); i++) { + + if(entities[i]->type == SSD_ENTITY_ASTRONAUT) { + + AstronautStruckPlayer((SSDAstronaut*)entities[i]); + } + } +} + +void idGameSSDWindow::OnSuperBlaster() { + + StartSuperBlaster(); +} + + + +void idGameSSDWindow::RefreshGuiData() { + + + gui->SetStateString("nextLevel", va("%i", gameStats.nextLevel+1)); + gui->SetStateString("currentLevel", va("%i", gameStats.currentLevel+1)); + + float accuracy; + if(!gameStats.levelStats.shotCount) { + accuracy = 0; + } else { + accuracy = ((float)gameStats.levelStats.hitCount/(float)gameStats.levelStats.shotCount)*100.0f; + } + gui->SetStateString( "player_accuracy", va("%d%%", (int)accuracy)); + + float saveAccuracy; + int totalAst = gameStats.levelStats.savedAstronauts + gameStats.levelStats.killedAstronauts; + + if(!totalAst) { + saveAccuracy = 0; + } else { + saveAccuracy = ((float)gameStats.levelStats.savedAstronauts/(float)totalAst)*100.0f; + } + gui->SetStateString( "save_accuracy", va("%d%%", (int)saveAccuracy)); + + + + + if(gameStats.levelStats.targetEnt) { + int dist = (gameStats.levelStats.targetEnt->position.z/100.0f); + dist *= 100; + gui->SetStateString("target_info", va("%i meters", dist)); + } else { + gui->SetStateString("target_info", "No Target"); + } + + gui->SetStateString( "player_health", va("%i", gameStats.health ) ); + gui->SetStateString( "player_score", va("%i", gameStats.score ) ); + gui->SetStateString( "player_prebonusscore", va("%i", gameStats.prebonusscore ) ); + gui->SetStateString( "level_complete", va("%i/%i", gameStats.levelStats.savedAstronauts, levelData[gameStats.currentLevel].needToWin )); + + + if(superBlasterTimeout) { + float timeRemaining = (superBlasterTimeout - ssdTime)/1000.0f; + gui->SetStateString("super_blaster_time", va("%.2f", timeRemaining)); + } +} + +idVec2 idGameSSDWindow::GetCursorWorld() { + + idVec2 cursor; + //GetCursor(cursor); + cursor.x = gui->CursorX(); + cursor.y = gui->CursorY(); + cursor.x = cursor.x - 0.5f * V_WIDTH; + cursor.y = -(cursor.y - 0.5f * V_HEIGHT); + return cursor; +} + +void idGameSSDWindow::SpawnAstronaut() { + + int currentTime = ssdTime; + + if(currentTime < gameStats.levelStats.nextAstronautSpawnTime) { + //Not time yet + return; + } + + //Lets spawn it + idVec3 startPosition; + + startPosition.x = random.RandomInt(V_WIDTH)-(V_WIDTH/2.0f); + startPosition.y = random.RandomInt(V_HEIGHT)-(V_HEIGHT/2.0f); + startPosition.z = ENTITY_START_DIST; + + float speed = random.RandomInt(astronautData[gameStats.currentLevel].speedMax - astronautData[gameStats.currentLevel].speedMin) + astronautData[gameStats.currentLevel].speedMin; + float rotate = (random.RandomFloat() * (astronautData[gameStats.currentLevel].rotateMax - astronautData[gameStats.currentLevel].rotateMin)) + astronautData[gameStats.currentLevel].rotateMin; + + SSDAstronaut* astronaut = SSDAstronaut::GetNewAstronaut(this, startPosition, speed, rotate, astronautData[gameStats.currentLevel].health); + entities.Append(astronaut); + + gameStats.levelStats.nextAstronautSpawnTime = currentTime + random.RandomInt(astronautData[gameStats.currentLevel].spawnMax - astronautData[gameStats.currentLevel].spawnMin) + astronautData[gameStats.currentLevel].spawnMin; +} + +void idGameSSDWindow::HitAstronaut(SSDAstronaut* astronaut, int key) { + + + if(key == K_MOUSE1) { + astronaut->health -= weaponData[gameStats.currentWeapon].damage; + + if(astronaut->health <= 0) { + + gameStats.levelStats.killedAstronauts++; + + //The astronaut has been destroyed + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size*2, 300, SSDExplosion::EXPLOSION_NORMAL, astronaut); + entities.Append(explosion); + PlaySound("arcade_explode"); + + //Add the penalty for killing the astronaut + AddScore(astronaut, astronautData[gameStats.currentLevel].penalty); + + //Don't let the player hit it anymore + astronaut->noHit = true; + } else { + //This was a damage hit so create a real small quick explosion + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size/2.0f, 200, SSDExplosion::EXPLOSION_NORMAL, astronaut, false, false); + entities.Append(explosion); + } + } +} + +void idGameSSDWindow::AstronautStruckPlayer(SSDAstronaut* astronaut) { + + gameStats.levelStats.savedAstronauts++; + + astronaut->noPlayerDamage = true; + astronaut->noHit = true; + + //We are saving an astronaut + SSDExplosion* explosion = SSDExplosion::GetNewExplosion(this, astronaut->position, astronaut->size*2, 300, SSDExplosion::EXPLOSION_TELEPORT, astronaut); + entities.Append(explosion); + PlaySound("arcade_capture"); + + //Give the player points for saving the astronaut + AddScore(astronaut, astronautData[gameStats.currentLevel].points); + + if(gameStats.levelStats.savedAstronauts >= levelData[gameStats.currentLevel].needToWin) { + LevelComplete(); + } + +} + +void idGameSSDWindow::SpawnPowerup() { + + int currentTime = ssdTime; + + if(currentTime < gameStats.levelStats.nextPowerupSpawnTime) { + //Not time yet + return; + } + + float speed = random.RandomInt(powerupData[gameStats.currentLevel].speedMax - powerupData[gameStats.currentLevel].speedMin) + powerupData[gameStats.currentLevel].speedMin; + float rotate = (random.RandomFloat() * (powerupData[gameStats.currentLevel].rotateMax - powerupData[gameStats.currentLevel].rotateMin)) + powerupData[gameStats.currentLevel].rotateMin; + + SSDPowerup* powerup = SSDPowerup::GetNewPowerup(this, speed, rotate); + entities.Append(powerup); + + gameStats.levelStats.nextPowerupSpawnTime = currentTime + random.RandomInt(powerupData[gameStats.currentLevel].spawnMax - powerupData[gameStats.currentLevel].spawnMin) + powerupData[gameStats.currentLevel].spawnMin; + +} + +void idGameSSDWindow::StartSuperBlaster() { + + gui->HandleNamedEvent("startSuperBlaster"); + gameStats.currentWeapon = 1; + superBlasterTimeout = ssdTime + 10000; + +} +void idGameSSDWindow::StopSuperBlaster() { + gui->HandleNamedEvent("stopSuperBlaster"); + gameStats.currentWeapon = 0; + superBlasterTimeout = 0; + +} + +SSDEntity* idGameSSDWindow::GetSpecificEntity(int type, int id) { + SSDEntity* ent = NULL; + switch(type) { + case SSD_ENTITY_ASTEROID: + ent = SSDAsteroid::GetSpecificAsteroid(id); + break; + case SSD_ENTITY_ASTRONAUT: + ent = SSDAstronaut::GetSpecificAstronaut(id); + break; + case SSD_ENTITY_EXPLOSION: + ent = SSDExplosion::GetSpecificExplosion(id); + break; + case SSD_ENTITY_POINTS: + ent = SSDPoints::GetSpecificPoints(id); + break; + case SSD_ENTITY_PROJECTILE: + ent = SSDProjectile::GetSpecificProjectile(id); + break; + case SSD_ENTITY_POWERUP: + ent = SSDPowerup::GetSpecificPowerup(id); + break; + } + return ent; +} + +#define MAX_SOUND_CHANNEL 8 + +void idGameSSDWindow::PlaySound(const char* sound) { + + session->sw->PlayShaderDirectly(sound, currentSound); + + currentSound++; + if(currentSound >= MAX_SOUND_CHANNEL) { + currentSound = 0; + } +} diff --git a/ui/GameSSDWindow.h b/ui/GameSSDWindow.h new file mode 100644 index 000000000..d3a5a0023 --- /dev/null +++ b/ui/GameSSDWindow.h @@ -0,0 +1,607 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GAME_SSD_WINDOW_H__ +#define __GAME_SSD_WINDOW_H__ + +class idGameSSDWindow; + +class SSDCrossHair { + +public: + enum { + CROSSHAIR_STANDARD = 0, + CROSSHAIR_SUPER, + CROSSHAIR_COUNT + }; + const idMaterial* crosshairMaterial[CROSSHAIR_COUNT]; + int currentCrosshair; + float crosshairWidth, crosshairHeight; + +public: + SSDCrossHair(); + ~SSDCrossHair(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + + void InitCrosshairs(); + void Draw(idDeviceContext *dc, const idVec2& cursor); +}; + +enum { + SSD_ENTITY_BASE = 0, + SSD_ENTITY_ASTEROID, + SSD_ENTITY_ASTRONAUT, + SSD_ENTITY_EXPLOSION, + SSD_ENTITY_POINTS, + SSD_ENTITY_PROJECTILE, + SSD_ENTITY_POWERUP +}; + +class SSDEntity { + +public: + //SSDEntity Information + int type; + int id; + idStr materialName; + const idMaterial* material; + idVec3 position; + idVec2 size; + float radius; + float hitRadius; + float rotation; + + idVec4 matColor; + + idStr text; + float textScale; + idVec4 foreColor; + + idGameSSDWindow* game; + int currentTime; + int lastUpdate; + int elapsed; + + bool destroyed; + bool noHit; + bool noPlayerDamage; + + bool inUse; + + +public: + SSDEntity(); + virtual ~SSDEntity(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void EntityInit(); + + void SetGame(idGameSSDWindow* _game); + void SetMaterial(const char* _name); + void SetPosition(const idVec3& _position); + void SetSize(const idVec2& _size); + void SetRadius(float _radius, float _hitFactor = 1.0f); + void SetRotation(float _rotation); + + void Update(); + bool HitTest(const idVec2& pt); + + + virtual void EntityUpdate() {}; + virtual void Draw(idDeviceContext *dc); + virtual void DestroyEntity(); + + virtual void OnHit(int key) {}; + virtual void OnStrikePlayer() {}; + + idBounds WorldToScreen(const idBounds worldBounds); + idVec3 WorldToScreen(const idVec3& worldPos); + + idVec3 ScreenToWorld(const idVec3& screenPos); + +}; + +/* +***************************************************************************** +* SSDMover +**************************************************************************** +*/ + +class SSDMover : public SSDEntity { + +public: + idVec3 speed; + float rotationSpeed; + +public: + SSDMover(); + virtual ~SSDMover(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void MoverInit(const idVec3& _speed, float _rotationSpeed); + + virtual void EntityUpdate(); + + +}; + +/* +***************************************************************************** +* SSDAsteroid +**************************************************************************** +*/ + +#define MAX_ASTEROIDS 64 + +class SSDAsteroid : public SSDMover { + +public: + + int health; + +public: + SSDAsteroid(); + ~SSDAsteroid(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void Init(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health); + + virtual void EntityUpdate(); + static SSDAsteroid* GetNewAsteroid(idGameSSDWindow* _game, const idVec3& startPosition, const idVec2& _size, float _speed, float rotate, int _health); + static SSDAsteroid* GetSpecificAsteroid(int id); + static void WriteAsteroids(idFile* savefile); + static void ReadAsteroids(idFile* savefile, idGameSSDWindow* _game); + + + +protected: + static SSDAsteroid asteroidPool[MAX_ASTEROIDS]; + +}; + +/* +***************************************************************************** +* SSDAstronaut +**************************************************************************** +*/ +#define MAX_ASTRONAUT 8 + +class SSDAstronaut : public SSDMover { + +public: + + int health; + +public: + SSDAstronaut(); + ~SSDAstronaut(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void Init(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health); + + static SSDAstronaut* GetNewAstronaut(idGameSSDWindow* _game, const idVec3& startPosition, float _speed, float rotate, int _health); + static SSDAstronaut* GetSpecificAstronaut(int id); + static void WriteAstronauts(idFile* savefile); + static void ReadAstronauts(idFile* savefile, idGameSSDWindow* _game); + +protected: + static SSDAstronaut astronautPool[MAX_ASTRONAUT]; + +}; + +/* +***************************************************************************** +* SSDExplosion +**************************************************************************** +*/ +#define MAX_EXPLOSIONS 64 + +class SSDExplosion : public SSDEntity { + +public: + idVec2 finalSize; + int length; + int beginTime; + int endTime; + int explosionType; + + //The entity that is exploding + SSDEntity* buddy; + bool killBuddy; + bool followBuddy; + + enum { + EXPLOSION_NORMAL = 0, + EXPLOSION_TELEPORT = 1 + }; + +public: + SSDExplosion(); + ~SSDExplosion(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void Init(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy = true, bool _followBuddy = true); + + virtual void EntityUpdate(); + static SSDExplosion* GetNewExplosion(idGameSSDWindow* _game, const idVec3& _position, const idVec2& _size, int _length, int _type, SSDEntity* _buddy, bool _killBuddy = true, bool _followBuddy = true); + static SSDExplosion* GetSpecificExplosion(int id); + static void WriteExplosions(idFile* savefile); + static void ReadExplosions(idFile* savefile, idGameSSDWindow* _game); + +protected: + static SSDExplosion explosionPool[MAX_EXPLOSIONS]; +}; + +#define MAX_POINTS 16 + +class SSDPoints : public SSDEntity { + + int length; + int distance; + int beginTime; + int endTime; + + idVec3 beginPosition; + idVec3 endPosition; + + idVec4 beginColor; + idVec4 endColor; + + +public: + SSDPoints(); + ~SSDPoints(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void Init(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color); + virtual void EntityUpdate(); + + static SSDPoints* GetNewPoints(idGameSSDWindow* _game, SSDEntity* _ent, int _points, int _length, int _distance, const idVec4& color); + static SSDPoints* GetSpecificPoints(int id); + static void WritePoints(idFile* savefile); + static void ReadPoints(idFile* savefile, idGameSSDWindow* _game); + +protected: + static SSDPoints pointsPool[MAX_POINTS]; +}; + +#define MAX_PROJECTILES 64 + +class SSDProjectile : public SSDEntity { + + idVec3 dir; + idVec3 speed; + int beginTime; + int endTime; + + idVec3 endPosition; + +public: + SSDProjectile(); + ~SSDProjectile(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + void Init(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size); + virtual void EntityUpdate(); + + static SSDProjectile* GetNewProjectile(idGameSSDWindow* _game, const idVec3& _beginPosition, const idVec3& _endPosition, float _speed, float _size); + static SSDProjectile* GetSpecificProjectile(int id); + static void WriteProjectiles(idFile* savefile); + static void ReadProjectiles(idFile* savefile, idGameSSDWindow* _game); + +protected: + static SSDProjectile projectilePool[MAX_PROJECTILES]; +}; + + +#define MAX_POWERUPS 64 + +/** +* Powerups work in two phases: +* 1.) Closed container hurls at you +* If you shoot the container it open +* 3.) If an opened powerup hits the player he aquires the powerup +* Powerup Types: +* Health - Give a specific amount of health +* Super Blaster - Increases the power of the blaster (lasts a specific amount of time) +* Asteroid Nuke - Destroys all asteroids on screen as soon as it is aquired +* Rescue Powerup - Rescues all astronauts as soon as it is acquited +* Bonus Points - Gives some bonus points when acquired +*/ +class SSDPowerup : public SSDMover { + + enum { + POWERUP_STATE_CLOSED = 0, + POWERUP_STATE_OPEN + }; + + enum { + POWERUP_TYPE_HEALTH = 0, + POWERUP_TYPE_SUPER_BLASTER, + POWERUP_TYPE_ASTEROID_NUKE, + POWERUP_TYPE_RESCUE_ALL, + POWERUP_TYPE_BONUS_POINTS, + POWERUP_TYPE_DAMAGE, + POWERUP_TYPE_MAX + }; + + int powerupState; + int powerupType; + + +public: + + +public: + SSDPowerup(); + virtual ~SSDPowerup(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile, idGameSSDWindow* _game ); + + virtual void OnHit(int key); + virtual void OnStrikePlayer(); + + void OnOpenPowerup(); + void OnActivatePowerup(); + + + + void Init(idGameSSDWindow* _game, float _speed, float _rotation); + + static SSDPowerup* GetNewPowerup(idGameSSDWindow* _game, float _speed, float _rotation); + static SSDPowerup* GetSpecificPowerup(int id); + static void WritePowerups(idFile* savefile); + static void ReadPowerups(idFile* savefile, idGameSSDWindow* _game); + +protected: + static SSDPowerup powerupPool[MAX_POWERUPS]; + +}; + + +typedef struct { + float spawnBuffer; + int needToWin; +} SSDLevelData_t; + +typedef struct { + float speedMin, speedMax; + float sizeMin, sizeMax; + float rotateMin, rotateMax; + int spawnMin, spawnMax; + int asteroidHealth; + int asteroidPoints; + int asteroidDamage; +} SSDAsteroidData_t; + +typedef struct { + float speedMin, speedMax; + float rotateMin, rotateMax; + int spawnMin, spawnMax; + int health; + int points; + int penalty; +} SSDAstronautData_t; + +typedef struct { + float speedMin, speedMax; + float rotateMin, rotateMax; + int spawnMin, spawnMax; +} SSDPowerupData_t; + +typedef struct { + float speed; + int damage; + int size; +} SSDWeaponData_t; + +/** +* SSDLevelStats_t +* Data that is used for each level. This data is reset +* each new level. +*/ +typedef struct { + int shotCount; + int hitCount; + int destroyedAsteroids; + int nextAsteroidSpawnTime; + + int killedAstronauts; + int savedAstronauts; + + //Astronaut Level Data + int nextAstronautSpawnTime; + + //Powerup Level Data + int nextPowerupSpawnTime; + + SSDEntity* targetEnt; +} SSDLevelStats_t; + +/** +* SSDGameStats_t +* Data that is used for the game that is currently running. Memset this +* to completely reset the game +*/ +typedef struct { + bool gameRunning; + + int score; + int prebonusscore; + + int health; + + int currentWeapon; + int currentLevel; + int nextLevel; + + SSDLevelStats_t levelStats; +} SSDGameStats_t; + + +class idGameSSDWindow : public idWindow { +public: + idGameSSDWindow(idUserInterfaceLocal *gui); + idGameSSDWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + ~idGameSSDWindow(); + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + + virtual const char* HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual idWinVar* GetWinVarByName (const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + + + virtual void Draw(int time, float x, float y); + + void AddHealth(int health); + void AddScore(SSDEntity* ent, int points); + void AddDamage(int damage); + + void OnNuke(); + void OnRescueAll(); + void OnSuperBlaster(); + + SSDEntity* GetSpecificEntity(int type, int id); + + void PlaySound(const char* sound); + + + + + static idRandom random; + int ssdTime; + +private: + + //Initialization + virtual bool ParseInternalVar(const char *name, idParser *src); + void ParseLevelData(int level, const idStr& levelDataString); + void ParseAsteroidData(int level, const idStr& asteroidDataString); + void ParseWeaponData(int weapon, const idStr& weaponDataString); + void ParseAstronautData(int level, const idStr& astronautDataString); + void ParsePowerupData(int level, const idStr& powerupDataString); + + void CommonInit(); + void ResetGameStats(); + void ResetLevelStats(); + void ResetEntities(); + + //Game Running Methods + void StartGame(); + void StopGame(); + void GameOver(); + + //Starting the Game + void BeginLevel(int level); + void ContinueGame(); + + //Stopping the Game + void LevelComplete(); + void GameComplete(); + + + + void UpdateGame(); + void CheckForHits(); + void ZOrderEntities(); + + void SpawnAsteroid(); + + void FireWeapon(int key); + SSDEntity* EntityHitTest(const idVec2& pt); + + void HitAsteroid(SSDAsteroid* asteroid, int key); + void AsteroidStruckPlayer(SSDAsteroid* asteroid); + + + + + + void RefreshGuiData(); + + idVec2 GetCursorWorld(); + + //Astronaut Methods + void SpawnAstronaut(); + void HitAstronaut(SSDAstronaut* astronaut, int key); + void AstronautStruckPlayer(SSDAstronaut* astronaut); + + //Powerup Methods + void SpawnPowerup(); + + + void StartSuperBlaster(); + void StopSuperBlaster(); + + //void FreeSoundEmitter( bool immediate ); + + + + +public: + + //WinVars used to call functions from the guis + idWinBool beginLevel; + idWinBool resetGame; + idWinBool continueGame; + idWinBool refreshGuiData; + + SSDCrossHair crosshair; + idBounds screenBounds; + + //Level Data + int levelCount; + idList levelData; + idList asteroidData; + idList astronautData; + idList powerupData; + + + //Weapon Data + int weaponCount; + idList weaponData; + + int superBlasterTimeout; + + //All current game data is stored in this structure (except the entity list) + SSDGameStats_t gameStats; + idList entities; + + int currentSound; + +}; + +#endif //__GAME_SSD_WINDOW_H__ diff --git a/ui/GameWindow.cpp b/ui/GameWindow.cpp new file mode 100644 index 000000000..a4eb75690 --- /dev/null +++ b/ui/GameWindow.cpp @@ -0,0 +1,43 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "GameWindow.h" + +/* +================ +idGameWindowProxy::idGameWindowProxy +================ +*/ +idGameWindowProxy::idGameWindowProxy( idDeviceContext *d, idUserInterfaceLocal *g ) : idWindow( d, g ) { } + +/* +================ +idGameWindowProxy::Draw +================ +*/ +void idGameWindowProxy::Draw( int time, float x, float y ) { + common->Printf( "TODO: idGameWindowProxy::Draw\n" ); +} + diff --git a/ui/GameWindow.h b/ui/GameWindow.h new file mode 100644 index 000000000..a479eec21 --- /dev/null +++ b/ui/GameWindow.h @@ -0,0 +1,29 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __GAMEWINDOW_H__ +#define __GAMEWINDOW_H__ + +class idGameWindowProxy : public idWindow { +public: + idGameWindowProxy( idDeviceContext *d, idUserInterfaceLocal *gui ); + void Draw( int time, float x, float y ); +}; + +#endif diff --git a/ui/GuiScript.cpp b/ui/GuiScript.cpp new file mode 100644 index 000000000..54affe5ce --- /dev/null +++ b/ui/GuiScript.cpp @@ -0,0 +1,616 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Window.h" +#include "Winvar.h" +#include "GuiScript.h" +#include "UserInterfaceLocal.h" + + +/* +========================= +Script_Set +========================= +*/ +void Script_Set(idWindow *window, idList *src) { + idStr key, val; + idWinStr *dest = dynamic_cast((*src)[0].var); + if (dest) { + if (idStr::Icmp(*dest, "cmd") == 0) { + dest = dynamic_cast((*src)[1].var); + int parmCount = src->Num(); + if (parmCount > 2) { + val = dest->c_str(); + int i = 2; + while (i < parmCount) { + val += " \""; + val += (*src)[i].var->c_str(); + val += "\""; + i++; + } + window->AddCommand(val); + } else { + window->AddCommand(*dest); + } + return; + } + } + (*src)[0].var->Set((*src)[1].var->c_str()); + (*src)[0].var->SetEval(false); +} + +/* +========================= +Script_SetFocus +========================= +*/ +void Script_SetFocus(idWindow *window, idList *src) { + idWinStr *parm = dynamic_cast((*src)[0].var); + if (parm) { + drawWin_t *win = window->GetGui()->GetDesktop()->FindChildByName(*parm); + if (win && win->win) { + window->SetFocus(win->win); + } + } +} + +/* +========================= +Script_ShowCursor +========================= +*/ +void Script_ShowCursor(idWindow *window, idList *src) { + idWinStr *parm = dynamic_cast((*src)[0].var); + if ( parm ) { + if ( atoi( *parm ) ) { + window->GetGui()->GetDesktop()->ClearFlag( WIN_NOCURSOR ); + } else { + window->GetGui()->GetDesktop()->SetFlag( WIN_NOCURSOR ); + } + } +} + +/* +========================= +Script_RunScript + + run scripts must come after any set cmd set's in the script +========================= +*/ +void Script_RunScript(idWindow *window, idList *src) { + idWinStr *parm = dynamic_cast((*src)[0].var); + if (parm) { + idStr str = window->cmd; + str += " ; runScript "; + str += parm->c_str(); + window->cmd = str; + } +} + +/* +========================= +Script_LocalSound +========================= +*/ +void Script_LocalSound(idWindow *window, idList *src) { + idWinStr *parm = dynamic_cast((*src)[0].var); + if (parm) { + session->sw->PlayShaderDirectly(*parm); + } +} + +/* +========================= +Script_EvalRegs +========================= +*/ +void Script_EvalRegs(idWindow *window, idList *src) { + window->EvalRegs(-1, true); +} + +/* +========================= +Script_EndGame +========================= +*/ +void Script_EndGame( idWindow *window, idList *src ) { + cvarSystem->SetCVarBool( "g_nightmare", true ); + cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); +} + +/* +========================= +Script_ResetTime +========================= +*/ +void Script_ResetTime(idWindow *window, idList *src) { + idWinStr *parm = dynamic_cast((*src)[0].var); + drawWin_t *win = NULL; + if (parm && src->Num() > 1) { + win = window->GetGui()->GetDesktop()->FindChildByName(*parm); + parm = dynamic_cast((*src)[1].var); + } + if (win && win->win) { + win->win->ResetTime(atoi(*parm)); + win->win->EvalRegs(-1, true); + } else { + window->ResetTime(atoi(*parm)); + window->EvalRegs(-1, true); + } +} + +/* +========================= +Script_ResetCinematics +========================= +*/ +void Script_ResetCinematics(idWindow *window, idList *src) { + window->ResetCinematics(); +} + +/* +========================= +Script_Transition +========================= +*/ +void Script_Transition(idWindow *window, idList *src) { + // transitions always affect rect or vec4 vars + if (src->Num() >= 4) { + idWinRectangle *rect = NULL; + idWinVec4 *vec4 = dynamic_cast((*src)[0].var); + // + // added float variable + idWinFloat* val = NULL; + // + if (vec4 == NULL) { + rect = dynamic_cast((*src)[0].var); + // + // added float variable + if ( NULL == rect ) { + val = dynamic_cast((*src)[0].var); + } + // + } + idWinVec4 *from = dynamic_cast((*src)[1].var); + idWinVec4 *to = dynamic_cast((*src)[2].var); + idWinStr *timeStr = dynamic_cast((*src)[3].var); + // + // added float variable + if (!((vec4 || rect || val) && from && to && timeStr)) { + // + common->Warning("Bad transition in gui %s in window %s\n", window->GetGui()->GetSourceFile(), window->GetName()); + return; + } + int time = atoi(*timeStr); + float ac = 0.0f; + float dc = 0.0f; + if (src->Num() > 4) { + idWinStr *acv = dynamic_cast((*src)[4].var); + idWinStr *dcv = dynamic_cast((*src)[5].var); + assert(acv && dcv); + ac = atof(*acv); + dc = atof(*dcv); + } + + if (vec4) { + vec4->SetEval(false); + window->AddTransition(vec4, *from, *to, time, ac, dc); + // + // added float variable + } else if ( val ) { + val->SetEval ( false ); + window->AddTransition(val, *from, *to, time, ac, dc); + // + } else { + rect->SetEval(false); + window->AddTransition(rect, *from, *to, time, ac, dc); + } + window->StartTransition(); + } +} + +typedef struct { + const char *name; + void (*handler) (idWindow *window, idList *src); + int mMinParms; + int mMaxParms; +} guiCommandDef_t; + +guiCommandDef_t commandList[] = { + { "set", Script_Set, 2, 999 }, + { "setFocus", Script_SetFocus, 1, 1 }, + { "endGame", Script_EndGame, 0, 0 }, + { "resetTime", Script_ResetTime, 0, 2 }, + { "showCursor", Script_ShowCursor, 1, 1 }, + { "resetCinematics", Script_ResetCinematics, 0, 2 }, + { "transition", Script_Transition, 4, 6 }, + { "localSound", Script_LocalSound, 1, 1 }, + { "runScript", Script_RunScript, 1, 1 }, + { "evalRegs", Script_EvalRegs, 0, 0 } +}; + +int scriptCommandCount = sizeof(commandList) / sizeof(guiCommandDef_t); + + +/* +========================= +idGuiScript::idGuiScript +========================= +*/ +idGuiScript::idGuiScript() { + ifList = NULL; + elseList = NULL; + conditionReg = -1; + handler = NULL; + parms.SetGranularity( 2 ); +} + +/* +========================= +idGuiScript::~idGuiScript +========================= +*/ +idGuiScript::~idGuiScript() { + delete ifList; + delete elseList; + int c = parms.Num(); + for ( int i = 0; i < c; i++ ) { + if ( parms[i].own ) { + delete parms[i].var; + } + } +} + +/* +========================= +idGuiScript::WriteToSaveGame +========================= +*/ +void idGuiScript::WriteToSaveGame( idFile *savefile ) { + int i; + + if ( ifList ) { + ifList->WriteToSaveGame( savefile ); + } + if ( elseList ) { + elseList->WriteToSaveGame( savefile ); + } + + savefile->Write( &conditionReg, sizeof( conditionReg ) ); + + for ( i = 0; i < parms.Num(); i++ ) { + if ( parms[i].own ) { + parms[i].var->WriteToSaveGame( savefile ); + } + } +} + +/* +========================= +idGuiScript::ReadFromSaveGame +========================= +*/ +void idGuiScript::ReadFromSaveGame( idFile *savefile ) { + int i; + + if ( ifList ) { + ifList->ReadFromSaveGame( savefile ); + } + if ( elseList ) { + elseList->ReadFromSaveGame( savefile ); + } + + savefile->Read( &conditionReg, sizeof( conditionReg ) ); + + for ( i = 0; i < parms.Num(); i++ ) { + if ( parms[i].own ) { + parms[i].var->ReadFromSaveGame( savefile ); + } + } +} + +/* +========================= +idGuiScript::Parse +========================= +*/ +bool idGuiScript::Parse(idParser *src) { + int i; + + // first token should be function call + // then a potentially variable set of parms + // ended with a ; + idToken token; + if ( !src->ReadToken(&token) ) { + src->Error( "Unexpected end of file" ); + return false; + } + + handler = NULL; + + for ( i = 0; i < scriptCommandCount ; i++ ) { + if ( idStr::Icmp(token, commandList[i].name) == 0 ) { + handler = commandList[i].handler; + break; + } + } + + if (handler == NULL) { + src->Error("Uknown script call %s", token.c_str()); + } + // now read parms til ; + // all parms are read as idWinStr's but will be fixed up later + // to be proper types + while (1) { + if ( !src->ReadToken(&token) ) { + src->Error( "Unexpected end of file" ); + return false; + } + + if (idStr::Icmp(token, ";") == 0) { + break; + } + + if (idStr::Icmp(token, "}") == 0) { + src->UnreadToken(&token); + break; + } + + idWinStr *str = new idWinStr(); + *str = token; + idGSWinVar wv; + wv.own = true; + wv.var = str; + parms.Append( wv ); + } + + // + // verify min/max params + if ( handler && (parms.Num() < commandList[i].mMinParms || parms.Num() > commandList[i].mMaxParms ) ) { + src->Error("incorrect number of parameters for script %s", commandList[i].name ); + } + // + + return true; +} + +/* +========================= +idGuiScriptList::Execute +========================= +*/ +void idGuiScriptList::Execute(idWindow *win) { + int c = list.Num(); + for (int i = 0; i < c; i++) { + idGuiScript *gs = list[i]; + assert(gs); + if (gs->conditionReg >= 0) { + if (win->HasOps()) { + float f = win->EvalRegs(gs->conditionReg); + if (f) { + if (gs->ifList) { + win->RunScriptList(gs->ifList); + } + } else if (gs->elseList) { + win->RunScriptList(gs->elseList); + } + } + } + gs->Execute(win); + } +} + +/* +========================= +idGuiScriptList::FixupParms +========================= +*/ +void idGuiScript::FixupParms(idWindow *win) { + if (handler == &Script_Set) { + bool precacheBackground = false; + bool precacheSounds = false; + idWinStr *str = dynamic_cast(parms[0].var); + assert(str); + idWinVar *dest = win->GetWinVarByName(*str, true); + if (dest) { + delete parms[0].var; + parms[0].var = dest; + parms[0].own = false; + + if ( dynamic_cast(dest) != NULL ) { + precacheBackground = true; + } + } else if ( idStr::Icmp( str->c_str(), "cmd" ) == 0 ) { + precacheSounds = true; + } + int parmCount = parms.Num(); + for (int i = 1; i < parmCount; i++) { + idWinStr *str = dynamic_cast(parms[i].var); + if (idStr::Icmpn(*str, "gui::", 5) == 0) { + + // always use a string here, no point using a float if it is one + // FIXME: This creates duplicate variables, while not technically a problem since they + // are all bound to the same guiDict, it does consume extra memory and is generally a bad thing + idWinStr* defvar = new idWinStr(); + defvar->Init ( *str, win ); + win->AddDefinedVar ( defvar ); + delete parms[i].var; + parms[i].var = defvar; + parms[i].own = false; + + //dest = win->GetWinVarByName(*str, true); + //if (dest) { + // delete parms[i].var; + // parms[i].var = dest; + // parms[i].own = false; + //} + // + } else if ((*str[0]) == '$') { + // + // dont include the $ when asking for variable + dest = win->GetGui()->GetDesktop()->GetWinVarByName((const char*)(*str) + 1, true); + // + if (dest) { + delete parms[i].var; + parms[i].var = dest; + parms[i].own = false; + } + } else if ( idStr::Cmpn( str->c_str(), STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ) { + str->Set( common->GetLanguageDict()->GetString( str->c_str() ) ); + } else if ( precacheBackground ) { + const idMaterial *mat = declManager->FindMaterial( str->c_str() ); + mat->SetSort( SS_GUI ); + } else if ( precacheSounds ) { + // Search for "play <...>" + idToken token; + idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + parser.LoadMemory(str->c_str(), str->Length(), "command"); + + while ( parser.ReadToken(&token) ) { + if ( token.Icmp("play") == 0 ) { + if ( parser.ReadToken(&token) && ( token != "" ) ) { + declManager->FindSound( token.c_str() ); + } + } + } + } + } + } else if (handler == &Script_Transition) { + if (parms.Num() < 4) { + common->Warning("Window %s in gui %s has a bad transition definition", win->GetName(), win->GetGui()->GetSourceFile()); + } + idWinStr *str = dynamic_cast(parms[0].var); + assert(str); + + // + drawWin_t *destowner; + idWinVar *dest = win->GetWinVarByName(*str, true, &destowner ); + // + + if (dest) { + delete parms[0].var; + parms[0].var = dest; + parms[0].own = false; + } else { + common->Warning("Window %s in gui %s: a transition does not have a valid destination var %s", win->GetName(), win->GetGui()->GetSourceFile(),str->c_str()); + } + + // + // support variables as parameters + int c; + for ( c = 1; c < 3; c ++ ) { + str = dynamic_cast(parms[c].var); + + idWinVec4 *v4 = new idWinVec4; + parms[c].var = v4; + parms[c].own = true; + + drawWin_t* owner; + + if ( (*str[0]) == '$' ) { + dest = win->GetWinVarByName ( (const char*)(*str) + 1, true, &owner ); + } else { + dest = NULL; + } + + if ( dest ) { + idWindow* ownerparent; + idWindow* destparent; + if ( owner ) { + ownerparent = owner->simp?owner->simp->GetParent():owner->win->GetParent(); + destparent = destowner->simp?destowner->simp->GetParent():destowner->win->GetParent(); + + // If its the rectangle they are referencing then adjust it + if ( ownerparent && destparent && + (dest == (owner->simp?owner->simp->GetWinVarByName ( "rect" ):owner->win->GetWinVarByName ( "rect" ) ) ) ) + { + idRectangle rect; + rect = *(dynamic_cast(dest)); + ownerparent->ClientToScreen ( &rect ); + destparent->ScreenToClient ( &rect ); + *v4 = rect.ToVec4 ( ); + } else { + v4->Set ( dest->c_str ( ) ); + } + } else { + v4->Set ( dest->c_str ( ) ); + } + } else { + v4->Set(*str); + } + + delete str; + } + // + + } else { + int c = parms.Num(); + for (int i = 0; i < c; i++) { + parms[i].var->Init(parms[i].var->c_str(), win); + } + } +} + +/* +========================= +idGuiScriptList::FixupParms +========================= +*/ +void idGuiScriptList::FixupParms(idWindow *win) { + int c = list.Num(); + for (int i = 0; i < c; i++) { + idGuiScript *gs = list[i]; + gs->FixupParms(win); + if (gs->ifList) { + gs->ifList->FixupParms(win); + } + if (gs->elseList) { + gs->elseList->FixupParms(win); + } + } +} + +/* +========================= +idGuiScriptList::WriteToSaveGame +========================= +*/ +void idGuiScriptList::WriteToSaveGame( idFile *savefile ) { + int i; + + for ( i = 0; i < list.Num(); i++ ) { + list[i]->WriteToSaveGame( savefile ); + } +} + +/* +========================= +idGuiScriptList::ReadFromSaveGame +========================= +*/ +void idGuiScriptList::ReadFromSaveGame( idFile *savefile ) { + int i; + + for ( i = 0; i < list.Num(); i++ ) { + list[i]->ReadFromSaveGame( savefile ); + } +} diff --git a/ui/GuiScript.h b/ui/GuiScript.h new file mode 100644 index 000000000..b0adc7215 --- /dev/null +++ b/ui/GuiScript.h @@ -0,0 +1,96 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __GUISCRIPT_H +#define __GUISCRIPT_H + +#include "Window.h" +#include "Winvar.h" + +struct idGSWinVar { + idGSWinVar() { + var = NULL; + own = false; + } + idWinVar* var; + bool own; +}; + +class idGuiScriptList; + +class idGuiScript { + friend class idGuiScriptList; + friend class idWindow; + +public: + idGuiScript(); + ~idGuiScript(); + + bool Parse(idParser *src); + void Execute(idWindow *win) { + if (handler) { + handler(win, &parms); + } + } + void FixupParms(idWindow *win); + size_t Size() { + int sz = sizeof(*this); + for (int i = 0; i < parms.Num(); i++) { + sz += parms[i].var->Size(); + } + return sz; + } + + void WriteToSaveGame( idFile *savefile ); + void ReadFromSaveGame( idFile *savefile ); + +protected: + int conditionReg; + idGuiScriptList *ifList; + idGuiScriptList *elseList; + idList parms; + void (*handler) (idWindow *window, idList *src); + +}; + + +class idGuiScriptList { + idList list; +public: + idGuiScriptList() { list.SetGranularity( 4 ); }; + ~idGuiScriptList() { list.DeleteContents(true); }; + void Execute(idWindow *win); + void Append(idGuiScript* gs) { + list.Append(gs); + } + size_t Size() { + int sz = sizeof(*this); + for (int i = 0; i < list.Num(); i++) { + sz += list[i]->Size(); + } + return sz; + } + void FixupParms(idWindow *win); + void ReadFromDemoFile( class idDemoFile *f ) {}; + void WriteToDemoFile( class idDemoFile *f ) {}; + + void WriteToSaveGame( idFile *savefile ); + void ReadFromSaveGame( idFile *savefile ); +}; + +#endif // __GUISCRIPT_H diff --git a/ui/ListGUI.cpp b/ui/ListGUI.cpp new file mode 100644 index 000000000..cde2bc465 --- /dev/null +++ b/ui/ListGUI.cpp @@ -0,0 +1,175 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "ListGUILocal.h" + +/* +==================== +idListGUILocal::StateChanged +==================== +*/ +void idListGUILocal::StateChanged() { + int i; + + if ( !m_stateUpdates ) { + return; + } + + for( i = 0; i < Num(); i++ ) { + m_pGUI->SetStateString( va( "%s_item_%i", m_name.c_str(), i ), (*this)[i].c_str() ); + } + for( i = Num() ; i < m_water ; i++ ) { + m_pGUI->SetStateString( va( "%s_item_%i", m_name.c_str(), i ), "" ); + } + m_water = Num(); + m_pGUI->StateChanged( com_frameTime ); +} + +/* +==================== +idListGUILocal::GetNumSelections +==================== +*/ +int idListGUILocal::GetNumSelections() { + return m_pGUI->State().GetInt( va( "%s_numsel", m_name.c_str() ) ); +} + +/* +==================== +idListGUILocal::GetSelection +==================== +*/ +int idListGUILocal::GetSelection( char *s, int size, int _sel ) const { + if ( s ) { + s[ 0 ] = '\0'; + } + int sel = m_pGUI->State().GetInt( va( "%s_sel_%i", m_name.c_str(), _sel ), "-1" ); + if ( sel == -1 || sel >= m_ids.Num() ) { + return -1; + } + if ( s ) { + idStr::snPrintf( s, size, m_pGUI->State().GetString( va( "%s_item_%i", m_name.c_str(), sel ), "" ) ); + } + // don't let overflow + if ( sel >= m_ids.Num() ) { + sel = 0; + } + m_pGUI->SetStateInt( va( "%s_selid_0", m_name.c_str() ), m_ids[ sel ] ); + return m_ids[ sel ]; +} + +/* +==================== +idListGUILocal::SetSelection +==================== +*/ +void idListGUILocal::SetSelection( int sel ) { + m_pGUI->SetStateInt( va( "%s_sel_0", m_name.c_str() ), sel ); + StateChanged(); +} + +/* +==================== +idListGUILocal::Add +==================== +*/ +void idListGUILocal::Add( int id, const idStr &s ) { + int i = m_ids.FindIndex( id ); + if ( i == -1 ) { + Append( s ); + m_ids.Append( id ); + } else { + (*this)[ i ] = s; + } + StateChanged(); +} + +/* +==================== +idListGUILocal::Push +==================== +*/ +void idListGUILocal::Push( const idStr& s ) { + Append( s ); + m_ids.Append( m_ids.Num() ); + StateChanged(); +} + +/* +==================== +idListGUILocal::Del +==================== +*/ +bool idListGUILocal::Del(int id) { + int i = m_ids.FindIndex(id); + if ( i == -1 ) { + return false; + } + m_ids.RemoveIndex( i ); + this->RemoveIndex( i ); + StateChanged(); + return true; +} + +/* +==================== +idListGUILocal::Clear +==================== +*/ +void idListGUILocal::Clear() { + m_ids.Clear(); + idList::Clear(); + if ( m_pGUI ) { + // will clear all the GUI variables and will set m_water back to 0 + StateChanged(); + } +} + +/* +==================== +idListGUILocal::IsConfigured +==================== +*/ +bool idListGUILocal::IsConfigured( void ) const { + return m_pGUI != NULL; +} + +/* +==================== +idListGUILocal::SetStateChanges +==================== +*/ +void idListGUILocal::SetStateChanges( bool enable ) { + m_stateUpdates = enable; + StateChanged(); +} + +/* +==================== +idListGUILocal::Shutdown +==================== +*/ +void idListGUILocal::Shutdown( void ) { + m_pGUI = NULL; + m_name.Clear(); + Clear(); +} diff --git a/ui/ListGUI.h b/ui/ListGUI.h new file mode 100644 index 000000000..e2863d5ed --- /dev/null +++ b/ui/ListGUI.h @@ -0,0 +1,52 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LISTGUI_H__ +#define __LISTGUI_H__ + +/* +=============================================================================== + + feed data to a listDef + each item has an id and a display string + +=============================================================================== +*/ + +class idListGUI { +public: + virtual ~idListGUI() { } + + virtual void Config( idUserInterface *pGUI, const char *name ) = 0; + virtual void Add( int id, const idStr& s ) = 0; + // use the element count as index for the ids + virtual void Push( const idStr& s ) = 0; + virtual bool Del( int id ) = 0; + virtual void Clear( void ) = 0; + virtual int Num( void ) = 0; + virtual int GetSelection( char *s, int size, int sel = 0 ) const = 0; // returns the id, not the list index (or -1) + virtual void SetSelection( int sel ) = 0; + virtual int GetNumSelections() = 0; + virtual bool IsConfigured( void ) const = 0; + // by default, any modification to the list will trigger a full GUI refresh immediately + virtual void SetStateChanges( bool enable ) = 0; + virtual void Shutdown( void ) = 0; +}; + +#endif /* !__LISTGUI_H__ */ diff --git a/ui/ListGUILocal.h b/ui/ListGUILocal.h new file mode 100644 index 000000000..14852994d --- /dev/null +++ b/ui/ListGUILocal.h @@ -0,0 +1,61 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __LISTGUILOCAL_H__ +#define __LISTGUILOCAL_H__ + +/* +=============================================================================== + + feed data to a listDef + each item has an id and a display string + +=============================================================================== +*/ + +class idListGUILocal : protected idList, public idListGUI { +public: + idListGUILocal() { m_pGUI = NULL; m_water = 0; m_stateUpdates = true; } + + // idListGUI interface + void Config( idUserInterface *pGUI, const char *name ) { m_pGUI = pGUI; m_name = name; } + void Add( int id, const idStr& s ); + // use the element count as index for the ids + void Push( const idStr& s ); + bool Del( int id ); + void Clear( void ); + int Num( void ) { return idList::Num(); } + int GetSelection( char *s, int size, int sel = 0 ) const; // returns the id, not the list index (or -1) + void SetSelection( int sel ); + int GetNumSelections(); + bool IsConfigured( void ) const; + void SetStateChanges( bool enable ); + void Shutdown( void ); + +private: + idUserInterface * m_pGUI; + idStr m_name; + int m_water; + idList m_ids; + bool m_stateUpdates; + + void StateChanged(); +}; + +#endif /* !__LISTGUILOCAL_H__ */ diff --git a/ui/ListWindow.cpp b/ui/ListWindow.cpp new file mode 100644 index 000000000..0090322ba --- /dev/null +++ b/ui/ListWindow.cpp @@ -0,0 +1,621 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "../framework/Session_local.h" + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "SliderWindow.h" +#include "ListWindow.h" + +// Number of pixels above the text that the rect starts +static const int pixelOffset = 3; + +// number of pixels between columns +static const int tabBorder = 4; + +// Time in milliseconds between clicks to register as a double-click +static const int doubleClickSpeed = 300; + +void idListWindow::CommonInit() { + typed = ""; + typedTime = 0; + clickTime = 0; + currentSel.Clear(); + top = 0; + sizeBias = 0; + horizontal = false; + scroller = new idSliderWindow(dc, gui); + multipleSel = false; +} + +idListWindow::idListWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idListWindow::idListWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +void idListWindow::SetCurrentSel( int sel ) { + currentSel.Clear(); + currentSel.Append( sel ); +} + +void idListWindow::ClearSelection( int sel ) { + int cur = currentSel.FindIndex( sel ); + if ( cur >= 0 ) { + currentSel.RemoveIndex( cur ); + } +} + +void idListWindow::AddCurrentSel( int sel ) { + currentSel.Append( sel ); +} + +int idListWindow::GetCurrentSel() { + return ( currentSel.Num() ) ? currentSel[0] : 0; +} + +bool idListWindow::IsSelected( int index ) { + return ( currentSel.FindIndex( index ) >= 0 ); +} + +const char *idListWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + // need to call this to allow proper focus and capturing on embedded children + const char *ret = idWindow::HandleEvent(event, updateVisuals); + + float vert = GetMaxCharHeight(); + int numVisibleLines = textRect.h / vert; + + int key = event->evValue; + + if ( event->evType == SE_KEY ) { + if ( !event->evValue2 ) { + // We only care about key down, not up + return ret; + } + + if ( key == K_MOUSE1 || key == K_MOUSE2 ) { + // If the user clicked in the scroller, then ignore it + if ( scroller->Contains(gui->CursorX(), gui->CursorY()) ) { + return ret; + } + } + + if ( ( key == K_ENTER || key == K_KP_ENTER ) ) { + RunScript( ON_ENTER ); + return cmd; + } + + if ( key == K_MWHEELUP ) { + key = K_UPARROW; + } else if ( key == K_MWHEELDOWN ) { + key = K_DOWNARROW; + } + + if ( key == K_MOUSE1) { + if (Contains(gui->CursorX(), gui->CursorY())) { + int cur = ( int )( ( gui->CursorY() - actualY - pixelOffset ) / vert ) + top; + if ( cur >= 0 && cur < listItems.Num() ) { + if ( multipleSel && idKeyInput::IsDown( K_CTRL ) ) { + if ( IsSelected( cur ) ) { + ClearSelection( cur ); + } else { + AddCurrentSel( cur ); + } + } else { + if ( IsSelected( cur ) && ( gui->GetTime() < clickTime + doubleClickSpeed ) ) { + // Double-click causes ON_ENTER to get run + RunScript(ON_ENTER); + return cmd; + } + SetCurrentSel( cur ); + + clickTime = gui->GetTime(); + } + } else { + SetCurrentSel( listItems.Num() - 1 ); + } + } + } else if ( key == K_UPARROW || key == K_PGUP || key == K_DOWNARROW || key == K_PGDN ) { + int numLines = 1; + + if ( key == K_PGUP || key == K_PGDN ) { + numLines = numVisibleLines / 2; + } + + if ( key == K_UPARROW || key == K_PGUP ) { + numLines = -numLines; + } + + if ( idKeyInput::IsDown( K_CTRL ) ) { + top += numLines; + } else { + SetCurrentSel( GetCurrentSel() + numLines ); + } + } else { + return ret; + } + } else if ( event->evType == SE_CHAR ) { + if ( !idStr::CharIsPrintable(key) ) { + return ret; + } + + if ( gui->GetTime() > typedTime + 1000 ) { + typed = ""; + } + typedTime = gui->GetTime(); + typed.Append( key ); + + for ( int i=0; i= listItems.Num() ) { + SetCurrentSel( listItems.Num() - 1 ); + } + + if ( scroller->GetHigh() > 0.0f ) { + if ( !idKeyInput::IsDown( K_CTRL ) ) { + if ( top > GetCurrentSel() - 1 ) { + top = GetCurrentSel() - 1; + } + if ( top < GetCurrentSel() - numVisibleLines + 2 ) { + top = GetCurrentSel() - numVisibleLines + 2; + } + } + + if ( top > listItems.Num() - 2 ) { + top = listItems.Num() - 2; + } + if ( top < 0 ) { + top = 0; + } + scroller->SetValue(top); + } else { + top = 0; + scroller->SetValue(0.0f); + } + + if ( key != K_MOUSE1 ) { + // Send a fake mouse click event so onAction gets run in our parents + const sysEvent_t ev = sys->GenerateMouseButtonEvent( 1, true ); + idWindow::HandleEvent(&ev, updateVisuals); + } + + if ( currentSel.Num() > 0 ) { + for ( int i = 0; i < currentSel.Num(); i++ ) { + gui->SetStateInt( va( "%s_sel_%i", listName.c_str(), i ), currentSel[i] ); + } + } else { + gui->SetStateInt( va( "%s_sel_0", listName.c_str() ), 0 ); + } + gui->SetStateInt( va( "%s_numsel", listName.c_str() ), currentSel.Num() ); + + return ret; +} + + +bool idListWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "horizontal") == 0) { + horizontal = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "listname") == 0) { + ParseString(src, listName); + return true; + } + if (idStr::Icmp(_name, "tabstops") == 0) { + ParseString(src, tabStopStr); + return true; + } + if (idStr::Icmp(_name, "tabaligns") == 0) { + ParseString(src, tabAlignStr); + return true; + } + if (idStr::Icmp(_name, "multipleSel") == 0) { + multipleSel = src->ParseBool(); + return true; + } + if(idStr::Icmp(_name, "tabvaligns") == 0) { + ParseString(src, tabVAlignStr); + return true; + } + if(idStr::Icmp(_name, "tabTypes") == 0) { + ParseString(src, tabTypeStr); + return true; + } + if(idStr::Icmp(_name, "tabIconSizes") == 0) { + ParseString(src, tabIconSizeStr); + return true; + } + if(idStr::Icmp(_name, "tabIconVOffset") == 0) { + ParseString(src, tabIconVOffsetStr); + return true; + } + + idStr strName = _name; + if(idStr::Icmp(strName.Left(4), "mtr_") == 0) { + idStr matName; + const idMaterial* mat; + + ParseString(src, matName); + mat = declManager->FindMaterial(matName); + mat->SetImageClassifications( 1 ); // just for resource tracking + if ( mat && !mat->TestMaterialFlag( MF_DEFAULTED ) ) { + mat->SetSort(SS_GUI ); + } + iconMaterials.Set(_name, mat); + return true; + } + + return idWindow::ParseInternalVar(_name, src); +} + +idWinVar *idListWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { + return idWindow::GetWinVarByName(_name, fixup, owner); +} + +void idListWindow::PostParse() { + idWindow::PostParse(); + + InitScroller(horizontal); + + idList tabStops; + idList tabAligns; + if (tabStopStr.Length()) { + idParser src(tabStopStr, tabStopStr.Length(), "tabstops", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + tabStops.Append(atoi(tok)); + } + } + if (tabAlignStr.Length()) { + idParser src(tabAlignStr, tabAlignStr.Length(), "tabaligns", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + tabAligns.Append(atoi(tok)); + } + } + idList tabVAligns; + if (tabVAlignStr.Length()) { + idParser src(tabVAlignStr, tabVAlignStr.Length(), "tabvaligns", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + tabVAligns.Append(atoi(tok)); + } + } + + idList tabTypes; + if (tabTypeStr.Length()) { + idParser src(tabTypeStr, tabTypeStr.Length(), "tabtypes", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + tabTypes.Append(atoi(tok)); + } + } + idList tabSizes; + if (tabIconSizeStr.Length()) { + idParser src(tabIconSizeStr, tabIconSizeStr.Length(), "tabiconsizes", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + idVec2 size; + size.x = atoi(tok); + + src.ReadToken(&tok); //"," + src.ReadToken(&tok); + + size.y = atoi(tok); + tabSizes.Append(size); + } + } + + idList tabIconVOffsets; + if (tabIconVOffsetStr.Length()) { + idParser src(tabIconVOffsetStr, tabIconVOffsetStr.Length(), "tabiconvoffsets", LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS); + idToken tok; + while (src.ReadToken(&tok)) { + if (tok == ",") { + continue; + } + tabIconVOffsets.Append(atof(tok)); + } + } + + int c = tabStops.Num(); + bool doAligns = (tabAligns.Num() == tabStops.Num()); + for (int i = 0; i < c; i++) { + idTabRect r; + r.x = tabStops[i]; + r.w = (i < c - 1) ? tabStops[i+1] - r.x - tabBorder : -1; + r.align = (doAligns) ? tabAligns[i] : 0; + if(tabVAligns.Num() > 0) { + r.valign = tabVAligns[i]; + } else { + r.valign = 0; + } + if(tabTypes.Num() > 0) { + r.type = tabTypes[i]; + } else { + r.type = TAB_TYPE_TEXT; + } + if(tabSizes.Num() > 0) { + r.iconSize = tabSizes[i]; + } else { + r.iconSize.Zero(); + } + if(tabIconVOffsets.Num() > 0 ) { + r.iconVOffset = tabIconVOffsets[i]; + } else { + r.iconVOffset = 0; + } + tabInfo.Append(r); + } + flags |= WIN_CANFOCUS; +} + +/* +================ +idListWindow::InitScroller + +This is the same as in idEditWindow +================ +*/ +void idListWindow::InitScroller( bool horizontal ) +{ + const char *thumbImage = "guis/assets/scrollbar_thumb.tga"; + const char *barImage = "guis/assets/scrollbarv.tga"; + const char *scrollerName = "_scrollerWinV"; + + if (horizontal) { + barImage = "guis/assets/scrollbarh.tga"; + scrollerName = "_scrollerWinH"; + } + + const idMaterial *mat = declManager->FindMaterial( barImage ); + mat->SetSort( SS_GUI ); + sizeBias = mat->GetImageWidth(); + + idRectangle scrollRect; + if (horizontal) { + sizeBias = mat->GetImageHeight(); + scrollRect.x = 0; + scrollRect.y = (clientRect.h - sizeBias); + scrollRect.w = clientRect.w; + scrollRect.h = sizeBias; + } else { + scrollRect.x = (clientRect.w - sizeBias); + scrollRect.y = 0; + scrollRect.w = sizeBias; + scrollRect.h = clientRect.h; + } + + scroller->InitWithDefaults(scrollerName, scrollRect, foreColor, matColor, mat->GetName(), thumbImage, !horizontal, true); + InsertChild(scroller, NULL); + scroller->SetBuddy(this); +} + +void idListWindow::Draw(int time, float x, float y) { + idVec4 color; + idStr work; + int count = listItems.Num(); + idRectangle rect = textRect; + float scale = textScale; + float lineHeight = GetMaxCharHeight(); + + float bottom = textRect.Bottom(); + float width = textRect.w; + + if ( scroller->GetHigh() > 0.0f ) { + if ( horizontal ) { + bottom -= sizeBias; + } else { + width -= sizeBias; + rect.w = width; + } + } + + if ( noEvents || !Contains(gui->CursorX(), gui->CursorY()) ) { + hover = false; + } + + for (int i = top; i < count; i++) { + if ( IsSelected( i ) ) { + rect.h = lineHeight; + dc->DrawFilledRect(rect.x, rect.y + pixelOffset, rect.w, rect.h, borderColor); + if ( flags & WIN_FOCUS ) { + idVec4 color = borderColor; + color.w = 1.0f; + dc->DrawRect(rect.x, rect.y + pixelOffset, rect.w, rect.h, 1.0f, color ); + } + } + rect.y ++; + rect.h = lineHeight - 1; + if ( hover && !noEvents && Contains(rect, gui->CursorX(), gui->CursorY()) ) { + color = hoverColor; + } else { + color = foreColor; + } + rect.h = lineHeight + pixelOffset; + rect.y --; + + if ( tabInfo.Num() > 0 ) { + int start = 0; + int tab = 0; + int stop = listItems[i].Find('\t', 0); + while ( start < listItems[i].Length() ) { + if ( tab >= tabInfo.Num() ) { + common->Warning( "idListWindow::Draw: gui '%s' window '%s' tabInfo.Num() exceeded", gui->GetSourceFile(), name.c_str() ); + break; + } + listItems[i].Mid(start, stop - start, work); + + rect.x = textRect.x + tabInfo[tab].x; + rect.w = (tabInfo[tab].w == -1) ? width - tabInfo[tab].x : tabInfo[tab].w; + dc->PushClipRect( rect ); + + if ( tabInfo[tab].type == TAB_TYPE_TEXT ) { + dc->DrawText(work, scale, tabInfo[tab].align, color, rect, false, -1); + } else if (tabInfo[tab].type == TAB_TYPE_ICON) { + + const idMaterial **hashMat; + const idMaterial *iconMat; + + // leaving the icon name empty doesn't draw anything + if ( work[0] != '\0' ) { + + if ( iconMaterials.Get(work, &hashMat) == false ) { + iconMat = declManager->FindMaterial("_default"); + } else { + iconMat = *hashMat; + } + + idRectangle iconRect; + iconRect.w = tabInfo[tab].iconSize.x; + iconRect.h = tabInfo[tab].iconSize.y; + + if(tabInfo[tab].align == idDeviceContext::ALIGN_LEFT) { + iconRect.x = rect.x; + } else if (tabInfo[tab].align == idDeviceContext::ALIGN_CENTER) { + iconRect.x = rect.x + rect.w/2.0f - iconRect.w/2.0f; + } else if (tabInfo[tab].align == idDeviceContext::ALIGN_RIGHT) { + iconRect.x = rect.x + rect.w - iconRect.w; + } + + if(tabInfo[tab].valign == 0) { //Top + iconRect.y = rect.y + tabInfo[tab].iconVOffset; + } else if(tabInfo[tab].valign == 1) { //Center + iconRect.y = rect.y + rect.h/2.0f - iconRect.h/2.0f + tabInfo[tab].iconVOffset; + } else if(tabInfo[tab].valign == 2) { //Bottom + iconRect.y = rect.y + rect.h - iconRect.h + tabInfo[tab].iconVOffset; + } + + dc->DrawMaterial(iconRect.x, iconRect.y, iconRect.w, iconRect.h, iconMat, idVec4(1.0f,1.0f,1.0f,1.0f), 1.0f, 1.0f); + + } + } + + dc->PopClipRect(); + + start = stop + 1; + stop = listItems[i].Find('\t', start); + if ( stop < 0 ) { + stop = listItems[i].Length(); + } + tab++; + } + rect.x = textRect.x; + rect.w = width; + } else { + dc->DrawText(listItems[i], scale, 0, color, rect, false, -1); + } + rect.y += lineHeight; + if ( rect.y > bottom ) { + break; + } + } +} + +void idListWindow::Activate(bool activate, idStr &act) { + idWindow::Activate(activate, act); + + if ( activate ) { + UpdateList(); + } +} + +void idListWindow::HandleBuddyUpdate(idWindow *buddy) { + top = scroller->GetValue(); +} + +void idListWindow::UpdateList() { + idStr str, strName; + listItems.Clear(); + for (int i = 0; i < MAX_LIST_ITEMS; i++) { + if (gui->State().GetString( va("%s_item_%i", listName.c_str(), i), "", str) ) { + if ( str.Length() ) { + listItems.Append(str); + } + } else { + break; + } + } + float vert = GetMaxCharHeight(); + int fit = textRect.h / vert; + if ( listItems.Num() < fit ) { + scroller->SetRange(0.0f, 0.0f, 1.0f); + } else { + scroller->SetRange(0.0f, (listItems.Num() - fit) + 1.0f, 1.0f); + } + + SetCurrentSel( gui->State().GetInt( va( "%s_sel_0", listName.c_str() ) ) ); + + float value = scroller->GetValue(); + if ( value > listItems.Num() - 1 ) { + value = listItems.Num() - 1; + } + if ( value < 0.0f ) { + value = 0.0f; + } + scroller->SetValue(value); + top = value; + + typedTime = 0; + clickTime = 0; + typed = ""; +} + +void idListWindow::StateChanged( bool redraw ) { + UpdateList(); +} + diff --git a/ui/ListWindow.h b/ui/ListWindow.h new file mode 100644 index 000000000..815abbea2 --- /dev/null +++ b/ui/ListWindow.h @@ -0,0 +1,89 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __LISTWINDOW_H +#define __LISTWINDOW_H + +class idSliderWindow; + +enum { + TAB_TYPE_TEXT = 0, + TAB_TYPE_ICON = 1 +}; + +struct idTabRect { + int x; + int w; + int align; + int valign; + int type; + idVec2 iconSize; + float iconVOffset; +}; + +class idListWindow : public idWindow { +public: + idListWindow(idUserInterfaceLocal *gui); + idListWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + + virtual const char* HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual void Activate(bool activate, idStr &act); + virtual void HandleBuddyUpdate(idWindow *buddy); + virtual void StateChanged( bool redraw = false ); + virtual size_t Allocated(){return idWindow::Allocated();}; + virtual idWinVar* GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + + void UpdateList(); + +private: + virtual bool ParseInternalVar(const char *name, idParser *src); + void CommonInit(); + void InitScroller( bool horizontal ); + void SetCurrentSel( int sel ); + void AddCurrentSel( int sel ); + int GetCurrentSel(); + bool IsSelected( int index ); + void ClearSelection( int sel ); + + idList tabInfo; + int top; + float sizeBias; + bool horizontal; + idStr tabStopStr; + idStr tabAlignStr; + idStr tabVAlignStr; + idStr tabTypeStr; + idStr tabIconSizeStr; + idStr tabIconVOffsetStr; + idHashTable iconMaterials; + bool multipleSel; + + idStrList listItems; + idSliderWindow* scroller; + idList currentSel; + idStr listName; + + int clickTime; + + int typedTime; + idStr typed; +}; + +#endif // __LISTWINDOW_H diff --git a/ui/MarkerWindow.cpp b/ui/MarkerWindow.cpp new file mode 100644 index 000000000..2b344ea88 --- /dev/null +++ b/ui/MarkerWindow.cpp @@ -0,0 +1,350 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +// included for image uploading for player stat graph +#include "../renderer/Image.h" + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "MarkerWindow.h" + +class idImage; +void idMarkerWindow::CommonInit() { + numStats = 0; + currentTime = -1; + currentMarker = -1; + stopTime = -1; + imageBuff = NULL; + markerMat = NULL; + markerStop = NULL; +} + +idMarkerWindow::idMarkerWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idMarkerWindow::idMarkerWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idMarkerWindow::~idMarkerWindow() { +} + +bool idMarkerWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "markerMat") == 0) { + idStr str; + ParseString(src, str); + markerMat = declManager->FindMaterial(str); + markerMat->SetSort( SS_GUI ); + return true; + } + if (idStr::Icmp(_name, "markerStop") == 0) { + idStr str; + ParseString(src, str); + markerStop = declManager->FindMaterial(str); + markerStop->SetSort( SS_GUI ); + return true; + } + if (idStr::Icmp(_name, "markerColor") == 0) { + ParseVec4(src, markerColor); + return true; + } + return idWindow::ParseInternalVar(_name, src); +} + +idWinVar *idMarkerWindow::GetWinVarByName(const char *_name, bool fixup) { + return idWindow::GetWinVarByName(_name, fixup); +} + +const char *idMarkerWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + + if (!(event->evType == SE_KEY && event->evValue2)) { + return ""; + } + + int key = event->evValue; + if (event->evValue2 && key == K_MOUSE1) { + gui->GetDesktop()->SetChildWinVarVal("markerText", "text", ""); + idRectangle r; + int c = markerTimes.Num(); + int i; + for (i = 0; i < c; i++) { + markerData_t &md = markerTimes[i]; + if (md.rect.Contains(gui->CursorX(), gui->CursorY())) { + currentMarker = i; + gui->SetStateInt( "currentMarker", md.time ); + stopTime = md.time; + gui->GetDesktop()->SetChildWinVarVal("markerText", "text", va("Marker set at %.2i:%.2i", md.time / 60 / 60, (md.time / 60) % 60)); + gui->GetDesktop()->SetChildWinVarVal("markerText", "visible", "1"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "matcolor", "1 1 1 1"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "text", ""); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "background", md.mat->GetName()); + break; + } + } + if ( i == c ) { + // no marker selected; + currentMarker = -1; + gui->SetStateInt( "currentMarker", currentTime ); + stopTime = currentTime; + gui->GetDesktop()->SetChildWinVarVal("markerText", "text", va("Marker set at %.2i:%.2i", currentTime / 60 / 60, (currentTime / 60) % 60)); + gui->GetDesktop()->SetChildWinVarVal("markerText", "visible", "1"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "matcolor", "0 0 0 0"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "text", "No Preview"); + } + float pct = gui->State().GetFloat( "loadPct" ); + int len = gui->State().GetInt( "loadLength" ); + if (stopTime > len * pct) { + return "cmdDemoGotoMarker"; + } + } else if (key == K_MOUSE2) { + stopTime = -1; + gui->GetDesktop()->SetChildWinVarVal("markerText", "text", ""); + gui->SetStateInt( "currentMarker", -1 ); + return "cmdDemoGotoMarker"; + } else if (key == K_SPACE) { + return "cmdDemoPauseFrame"; + } + + return ""; +} + +void idMarkerWindow::PostParse() { + idWindow::PostParse(); +} + +static const int HEALTH_MAX = 100; +static const int COMBAT_MAX = 100; +static const int RATE_MAX = 125; +static const int STAMINA_MAX = 12; +void idMarkerWindow::Draw(int time, float x, float y) { + float pct; + idRectangle r = clientRect; + int len = gui->State().GetInt( "loadLength" ); + if (len == 0) { + len = 1; + } + if (numStats > 1) { + int c = markerTimes.Num(); + if (c > 0) { + for (int i = 0; i < c; i++) { + markerData_t &md = markerTimes[i]; + if (md.rect.w == 0) { + md.rect.x = (r.x + r.w * ((float)md.time / len)) - 8; + md.rect.y = r.y + r.h - 20; + md.rect.w = 16; + md.rect.h = 16; + } + dc->DrawMaterial(md.rect.x, md.rect.y, md.rect.w, md.rect.h, markerMat, markerColor); + } + } + } + + r.y += 10; + if (r.w > 0 && r.Contains(gui->CursorX(), gui->CursorY())) { + pct = (gui->CursorX() - r.x) / r.w; + currentTime = len * pct; + r.x = (gui->CursorX() > r.x + r.w - 40) ? gui->CursorX() - 40 : gui->CursorX(); + r.y = gui->CursorY() - 15; + r.w = 40; + r.h = 20; + dc->DrawText(va("%.2i:%.2i", currentTime / 60 / 60, (currentTime / 60) % 60), 0.25, 0, idDeviceContext::colorWhite, r, false); + } + + if (stopTime >= 0 && markerStop) { + r = clientRect; + r.y += (r.h - 32) / 2; + pct = (float)stopTime / len; + r.x += (r.w * pct) - 16; + idVec4 color(1, 1, 1, 0.65f); + dc->DrawMaterial(r.x, r.y, 32, 32, markerStop, color); + } + +} + + + +const char *idMarkerWindow::RouteMouseCoords(float xd, float yd) { + const char * ret = idWindow::RouteMouseCoords(xd, yd); + idRectangle r; + int i, c = markerTimes.Num(); + int len = gui->State().GetInt( "loadLength" ); + if (len == 0) { + len = 1; + } + for (i = 0; i < c; i++) { + markerData_t &md = markerTimes[i]; + if (md.rect.Contains(gui->CursorY(), gui->CursorX())) { + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "background", md.mat->GetName()); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "matcolor", "1 1 1 1"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "text", ""); + break; + } + } + + if (i >= c) { + if (currentMarker == -1) { + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "matcolor", "0 0 0 0"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "text", "No Preview"); + } else { + markerData_t &md = markerTimes[currentMarker]; + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "background", md.mat->GetName()); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "matcolor", "1 1 1 1"); + gui->GetDesktop()->SetChildWinVarVal("markerBackground", "text", ""); + } + } + return ret; +} + +void idMarkerWindow::Point(int x, int y, dword *out, dword color) { + int index = (63-y) * 512 + x; + if (index >= 0 && index < 512 * 64) { + out[index] = color; + } else { + common->Warning("Out of bounds on point %i : %i", x, y); + } +} + +void idMarkerWindow::Line(int x1, int y1, int x2, int y2, dword* out, dword color) { + int deltax = abs(x2 - x1); + int deltay = abs(y2 - y1); + int incx = (x1 > x2) ? -1 : 1; + int incy = (y1 > y2) ? -1 : 1; + int right, up, dir; + if (deltax > deltay) { + right = deltay * 2; + up = right - deltax * 2; + dir = right - deltax; + while (deltax-- >= 0) { + Point(x1, y1, out, color); + x1 += incx; + y1 += (dir > 0) ? incy : 0; + dir += (dir > 0) ? up : right; + } + } else { + right = deltax * 2; + up = right - deltay * 2; + dir = right - deltay; + while ( deltay-- >= 0) { + Point(x1, y1, out, color); + x1 += (dir > 0) ? incx : 0; + y1 += incy; + dir += (dir > 0) ? up : right; + } + } +} + + +void idMarkerWindow::Activate(bool activate, idStr &act) { + idWindow::Activate(activate, act); + if (activate) { + int i; + gui->GetDesktop()->SetChildWinVarVal("markerText", "text", ""); + imageBuff = (dword*)Mem_Alloc(512*64*4); + markerTimes.Clear(); + currentMarker = -1; + currentTime = -1; + stopTime = -1; + statData = gui->State().GetString( "statData" ); + numStats = 0; + if (statData.Length()) { + idFile *file = fileSystem->OpenFileRead(statData); + if (file) { + file->Read(&numStats, sizeof(numStats)); + file->Read(loggedStats, numStats * sizeof(loggedStats[0])); + for (i = 0; i < numStats; i++) { + if (loggedStats[i].health < 0) { + loggedStats[i].health = 0; + } + if (loggedStats[i].stamina < 0) { + loggedStats[i].stamina = 0; + } + if (loggedStats[i].heartRate < 0) { + loggedStats[i].heartRate = 0; + } + if (loggedStats[i].combat < 0) { + loggedStats[i].combat = 0; + } + } + fileSystem->CloseFile(file); + } + } + + if (numStats > 1 && background) { + idStr markerPath = statData; + markerPath.StripFilename(); + idFileList *markers; + markers = fileSystem->ListFiles( markerPath, ".tga", false, true ); + idStr name; + for ( i = 0; i < markers->GetNumFiles(); i++ ) { + name = markers->GetFile( i ); + markerData_t md; + md.mat = declManager->FindMaterial( name ); + md.mat->SetSort( SS_GUI ); + name.StripPath(); + name.StripFileExtension(); + md.time = atoi(name); + markerTimes.Append(md); + } + fileSystem->FreeFileList( markers ); + memset(imageBuff, 0, 512*64*4); + float step = 511.0f / (numStats - 1); + float startX = 0; + float x1, y1, x2, y2; + x1 = 0 - step; + for (i = 0; i < numStats-1; i++) { + x1 += step; + x2 = x1 + step; + y1 = 63 * ((float)loggedStats[i].health / HEALTH_MAX); + y2 = 63 * ((float)loggedStats[i+1].health / HEALTH_MAX); + Line(x1, y1, x2, y2, imageBuff, 0xff0000ff); + y1 = 63 * ((float)loggedStats[i].heartRate / RATE_MAX); + y2 = 63 * ((float)loggedStats[i+1].heartRate / RATE_MAX); + Line(x1, y1, x2, y2, imageBuff, 0xff00ff00); + // stamina not quite as high on graph so health does not get obscured with both at 100% + y1 = 62 * ((float)loggedStats[i].stamina / STAMINA_MAX); + y2 = 62 * ((float)loggedStats[i+1].stamina / STAMINA_MAX); + Line(x1, y1, x2, y2, imageBuff, 0xffff0000); + y1 = 63 * ((float)loggedStats[i].combat / COMBAT_MAX); + y2 = 63 * ((float)loggedStats[i+1].combat / COMBAT_MAX); + Line(x1, y1, x2, y2, imageBuff, 0xff00ffff); + } + const shaderStage_t *stage = background->GetStage(0); + if (stage) { + stage->texture.image->UploadScratch((byte*)imageBuff, 512, 64); + } + Mem_Free(imageBuff); + } + } +} + +void idMarkerWindow::MouseExit() { + idWindow::MouseExit(); +} + +void idMarkerWindow::MouseEnter() { + idWindow::MouseEnter(); +} diff --git a/ui/MarkerWindow.h b/ui/MarkerWindow.h new file mode 100644 index 000000000..0ff51aec7 --- /dev/null +++ b/ui/MarkerWindow.h @@ -0,0 +1,65 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __MARKERWINDOW_H +#define __MARKERWINDOW_H + +class idUserInterfaceLocal; + +typedef struct { + int time; + const idMaterial *mat; + idRectangle rect; +} markerData_t; + +class idMarkerWindow : public idWindow { +public: + idMarkerWindow(idUserInterfaceLocal *gui); + idMarkerWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idMarkerWindow(); + virtual size_t Allocated(){return idWindow::Allocated();}; + virtual idWinVar *GetWinVarByName(const char *_name, bool winLookup = false); + + virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual const char *RouteMouseCoords(float xd, float yd); + virtual void Activate(bool activate, idStr &act); + virtual void MouseExit(); + virtual void MouseEnter(); + + +private: + virtual bool ParseInternalVar(const char *name, idParser *src); + void CommonInit(); + void Line(int x1, int y1, int x2, int y2, dword* out, dword color); + void Point(int x, int y, dword *out, dword color); + logStats_t loggedStats[MAX_LOGGED_STATS]; + idList markerTimes; + idStr statData; + int numStats; + dword *imageBuff; + const idMaterial *markerMat; + const idMaterial *markerStop; + idVec4 markerColor; + int currentMarker; + int currentTime; + int stopTime; +}; + +#endif // __MARKERWINDOW_H diff --git a/ui/Rectangle.h b/ui/Rectangle.h new file mode 100644 index 000000000..0f66b8971 --- /dev/null +++ b/ui/Rectangle.h @@ -0,0 +1,213 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef IDRECTANGLE_H_ +#define IDRECTANGLE_H_ +// +// simple rectangle +// +extern void RotateVector(idVec3 &v, idVec3 origin, float a, float c, float s); +class idRectangle { +public: + float x; // horiz position + float y; // vert position + float w; // width + float h; // height; + idRectangle() { x = y = w= h = 0.0; } + idRectangle(float ix, float iy, float iw, float ih) { x = ix; y = iy; w = iw; h = ih; } + float Bottom() const { return y + h; } + float Right() const { return x + w; } + void Offset (float x, float y) { + this->x += x; + this->y += y; + } + bool Contains(float xt, float yt) { + if (w == 0.0 && h == 0.0) { + return false; + } + if (xt >= x && xt <= Right() && yt >= y && yt <= Bottom()) { + return true; + } + return false; + } + void Empty() { x = y = w = h = 0.0; }; + + void ClipAgainst(idRectangle r, bool sizeOnly) { + if (!sizeOnly) { + if (x < r.x) { + x = r.x; + } + if (y < r.y) { + y = r.y; + } + } + if (x + w > r.x + r.w) { + w = (r.x + r.w) - x; + } + if (y + h > r.y + r.h) { + h = (r.y + r.h) - y; + } + } + + + + void Rotate(float a, idRectangle &out) { + idVec3 p1, p2, p3, p4, p5; + float c, s; + idVec3 center; + center.Set((x + w) / 2.0, (y + h) / 2.0, 0); + p1.Set(x, y, 0); + p2.Set(Right(), y, 0); + p4.Set(x, Bottom(), 0); + if (a) { + s = sin( DEG2RAD( a ) ); + c = cos( DEG2RAD( a ) ); + } + else { + s = c = 0; + } + RotateVector(p1, center, a, c, s); + RotateVector(p2, center, a, c, s); + RotateVector(p4, center, a, c, s); + out.x = p1.x; + out.y = p1.y; + out.w = (p2 - p1).Length(); + out.h = (p4 - p1).Length(); + } + + idRectangle & operator+=( const idRectangle &a ); + idRectangle & operator-=( const idRectangle &a ); + idRectangle & operator/=( const idRectangle &a ); + idRectangle & operator/=( const float a ); + idRectangle & operator*=( const float a ); + idRectangle & operator=( const idVec4 v ); + int operator==(const idRectangle &a) const; + float & operator[]( const int index ); + char * String( void ) const; + const idVec4& ToVec4() const; + +}; + +ID_INLINE const idVec4 &idRectangle::ToVec4() const { + return *reinterpret_cast(&x); +} + + +ID_INLINE idRectangle &idRectangle::operator+=( const idRectangle &a ) { + x += a.x; + y += a.y; + w += a.w; + h += a.h; + + return *this; +} + +ID_INLINE idRectangle &idRectangle::operator/=( const idRectangle &a ) { + x /= a.x; + y /= a.y; + w /= a.w; + h /= a.h; + + return *this; +} + +ID_INLINE idRectangle &idRectangle::operator/=( const float a ) { + float inva = 1.0f / a; + x *= inva; + y *= inva; + w *= inva; + h *= inva; + + return *this; +} + +ID_INLINE idRectangle &idRectangle::operator-=( const idRectangle &a ) { + x -= a.x; + y -= a.y; + w -= a.w; + h -= a.h; + + return *this; +} + +ID_INLINE idRectangle &idRectangle::operator*=( const float a ) { + x *= a; + y *= a; + w *= a; + h *= a; + + return *this; +} + + +ID_INLINE idRectangle &idRectangle::operator=( const idVec4 v ) { + x = v.x; + y = v.y; + w = v.z; + h = v.w; + return *this; +} + +ID_INLINE int idRectangle::operator==( const idRectangle &a ) const { + return (x == a.x && y == a.y && w == a.w && a.h); +} + +ID_INLINE float& idRectangle::operator[]( int index ) { + return ( &x )[ index ]; +} + +class idRegion { +public: + idRegion() { }; + + void Empty() { + rects.Clear(); + } + + bool Contains(float xt, float yt) { + int c = rects.Num(); + for (int i = 0; i < c; i++) { + if (rects[i].Contains(xt, yt)) { + return true; + } + } + return false; + } + + void AddRect(float x, float y, float w, float h) { + rects.Append(idRectangle(x, y, w, h)); + } + + int GetRectCount() { + return rects.Num(); + } + + idRectangle *GetRect(int index) { + if (index >= 0 && index < rects.Num()) { + return &rects[index]; + } + return NULL; + } + +protected: + + idList rects; +}; + + +#endif diff --git a/ui/RegExp.cpp b/ui/RegExp.cpp new file mode 100644 index 000000000..4e007161e --- /dev/null +++ b/ui/RegExp.cpp @@ -0,0 +1,393 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "RegExp.h" +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" + +int idRegister::REGCOUNT[NUMTYPES] = {4, 1, 1, 1, 0, 2, 3, 4}; + +/* +==================== +idRegister::SetToRegs +==================== +*/ +void idRegister::SetToRegs( float *registers ) { + int i; + idVec4 v; + idVec2 v2; + idVec3 v3; + idRectangle rect; + + if ( !enabled || var == NULL || ( var && ( var->GetDict() || !var->GetEval() ) ) ) { + return; + } + + switch( type ) { + case VEC4: { + v = *static_cast(var); + break; + } + case RECTANGLE: { + rect = *static_cast(var); + v = rect.ToVec4(); + break; + } + case VEC2: { + v2 = *static_cast(var); + v[0] = v2[0]; + v[1] = v2[1]; + break; + } + case VEC3: { + v3 = *static_cast(var); + v[0] = v3[0]; + v[1] = v3[1]; + v[2] = v3[2]; + break; + } + case FLOAT: { + v[0] = *static_cast(var); + break; + } + case INT: { + v[0] = *static_cast(var); + break; + } + case BOOL: { + v[0] = *static_cast(var); + break; + } + default: { + common->FatalError( "idRegister::SetToRegs: bad reg type" ); + break; + } + } + for ( i = 0; i < regCount; i++ ) { + registers[ regs[ i ] ] = v[i]; + } +} + +/* +================= +idRegister::GetFromRegs +================= +*/ +void idRegister::GetFromRegs( float *registers ) { + idVec4 v; + idRectangle rect; + + if (!enabled || var == NULL || (var && (var->GetDict() || !var->GetEval()))) { + return; + } + + for ( int i = 0; i < regCount; i++ ) { + v[i] = registers[regs[i]]; + } + + switch( type ) { + case VEC4: { + *dynamic_cast(var) = v; + break; + } + case RECTANGLE: { + rect.x = v.x; + rect.y = v.y; + rect.w = v.z; + rect.h = v.w; + *static_cast(var) = rect; + break; + } + case VEC2: { + *static_cast(var) = v.ToVec2(); + break; + } + case VEC3: { + *static_cast(var) = v.ToVec3(); + break; + } + case FLOAT: { + *static_cast(var) = v[0]; + break; + } + case INT: { + *static_cast(var) = v[0]; + break; + } + case BOOL: { + *static_cast(var) = ( v[0] != 0.0f ); + break; + } + default: { + common->FatalError( "idRegister::GetFromRegs: bad reg type" ); + break; + } + } +} + +/* +================= +idRegister::ReadFromDemoFile +================= +*/ +void idRegister::ReadFromDemoFile(idDemoFile *f) { + f->ReadBool( enabled ); + f->ReadShort( type ); + f->ReadInt( regCount ); + for ( int i = 0; i < 4; i++ ) + f->ReadUnsignedShort( regs[i] ); + name = f->ReadHashString(); +} + +/* +================= +idRegister::WriteToDemoFile +================= +*/ +void idRegister::WriteToDemoFile( idDemoFile *f ) { + f->WriteBool( enabled ); + f->WriteShort( type ); + f->WriteInt( regCount ); + for (int i = 0; i < 4; i++) + f->WriteUnsignedShort( regs[i] ); + f->WriteHashString( name ); +} + +/* +================= +idRegister::WriteToSaveGame +================= +*/ +void idRegister::WriteToSaveGame( idFile *savefile ) { + int len; + + savefile->Write( &enabled, sizeof( enabled ) ); + savefile->Write( &type, sizeof( type ) ); + savefile->Write( ®Count, sizeof( regCount ) ); + savefile->Write( ®s[0], sizeof( regs ) ); + + len = name.Length(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( name.c_str(), len ); + + var->WriteToSaveGame( savefile ); +} + +/* +================ +idRegister::ReadFromSaveGame +================ +*/ +void idRegister::ReadFromSaveGame( idFile *savefile ) { + int len; + + savefile->Read( &enabled, sizeof( enabled ) ); + savefile->Read( &type, sizeof( type ) ); + savefile->Read( ®Count, sizeof( regCount ) ); + savefile->Read( ®s[0], sizeof( regs ) ); + + savefile->Read( &len, sizeof( len ) ); + name.Fill( ' ', len ); + savefile->Read( &name[0], len ); + + var->ReadFromSaveGame( savefile ); +} + +/* +==================== +idRegisterList::AddReg +==================== +*/ +void idRegisterList::AddReg( const char *name, int type, idVec4 data, idWindow *win, idWinVar *var ) { + if ( FindReg( name ) == NULL ) { + assert( type >= 0 && type < idRegister::NUMTYPES ); + int numRegs = idRegister::REGCOUNT[type]; + idRegister *reg = new idRegister( name, type ); + reg->var = var; + for ( int i = 0; i < numRegs; i++ ) { + reg->regs[i] = win->ExpressionConstant(data[i]); + } + int hash = regHash.GenerateKey( name, false ); + regHash.Add( hash, regs.Append( reg ) ); + } +} + +/* +==================== +idRegisterList::AddReg +==================== +*/ +void idRegisterList::AddReg( const char *name, int type, idParser *src, idWindow *win, idWinVar *var ) { + idRegister* reg; + + reg = FindReg( name ); + + if ( reg == NULL ) { + assert(type >= 0 && type < idRegister::NUMTYPES); + int numRegs = idRegister::REGCOUNT[type]; + reg = new idRegister( name, type ); + reg->var = var; + if ( type == idRegister::STRING ) { + idToken tok; + if ( src->ReadToken( &tok ) ) { + tok = common->GetLanguageDict()->GetString( tok ); + var->Init( tok, win ); + } + } else { + for ( int i = 0; i < numRegs; i++ ) { + reg->regs[i] = win->ParseExpression(src, NULL); + if ( i < numRegs-1 ) { + src->ExpectTokenString(","); + } + } + } + int hash = regHash.GenerateKey( name, false ); + regHash.Add( hash, regs.Append( reg ) ); + } else { + int numRegs = idRegister::REGCOUNT[type]; + reg->var = var; + if ( type == idRegister::STRING ) { + idToken tok; + if ( src->ReadToken( &tok ) ) { + var->Init( tok, win ); + } + } else { + for ( int i = 0; i < numRegs; i++ ) { + reg->regs[i] = win->ParseExpression( src, NULL ); + if ( i < numRegs-1 ) { + src->ExpectTokenString(","); + } + } + } + } +} + +/* +==================== +idRegisterList::GetFromRegs +==================== +*/ +void idRegisterList::GetFromRegs(float *registers) { + for ( int i = 0; i < regs.Num(); i++ ) { + regs[i]->GetFromRegs( registers ); + } +} + +/* +==================== +idRegisterList::SetToRegs +==================== +*/ + +void idRegisterList::SetToRegs( float *registers ) { + int i; + for ( i = 0; i < regs.Num(); i++ ) { + regs[i]->SetToRegs( registers ); + } +} + +/* +==================== +idRegisterList::FindReg +==================== +*/ +idRegister *idRegisterList::FindReg( const char *name ) { + int hash = regHash.GenerateKey( name, false ); + for ( int i = regHash.First( hash ); i != -1; i = regHash.Next( i ) ) { + if ( regs[i]->name.Icmp( name ) == 0 ) { + return regs[i]; + } + } + return NULL; +} + +/* +==================== +idRegisterList::Reset +==================== +*/ +void idRegisterList::Reset() { + regs.DeleteContents( true ); + regHash.Clear(); +} + +/* +==================== +idRegisterList::ReadFromSaveGame +==================== +*/ +void idRegisterList::ReadFromDemoFile(idDemoFile *f) { + int c; + + f->ReadInt( c ); + regs.DeleteContents( true ); + for ( int i = 0; i < c; i++ ) { + idRegister *reg = new idRegister; + reg->ReadFromDemoFile( f ); + regs.Append( reg ); + } +} + +/* +==================== +idRegisterList::ReadFromSaveGame +==================== +*/ +void idRegisterList::WriteToDemoFile(idDemoFile *f) { + int c = regs.Num(); + + f->WriteInt( c ); + for ( int i = 0 ; i < c; i++ ) { + regs[i]->WriteToDemoFile(f); + } +} + +/* +===================== +idRegisterList::WriteToSaveGame +===================== +*/ +void idRegisterList::WriteToSaveGame( idFile *savefile ) { + int i, num; + + num = regs.Num(); + savefile->Write( &num, sizeof( num ) ); + + for ( i = 0; i < num; i++ ) { + regs[i]->WriteToSaveGame( savefile ); + } +} + +/* +==================== +idRegisterList::ReadFromSaveGame +==================== +*/ +void idRegisterList::ReadFromSaveGame( idFile *savefile ) { + int i, num; + + savefile->Read( &num, sizeof( num ) ); + for ( i = 0; i < num; i++ ) { + regs[i]->ReadFromSaveGame( savefile ); + } +} diff --git a/ui/RegExp.h b/ui/RegExp.h new file mode 100644 index 000000000..8d99f0545 --- /dev/null +++ b/ui/RegExp.h @@ -0,0 +1,102 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __REGEXP_H__ +#define __REGEXP_H__ + +class idWindow; +class idWinVar; + +class idRegister { +public: + idRegister(); + idRegister( const char *p, int t ); + + enum REGTYPE { VEC4 = 0, FLOAT, BOOL, INT, STRING, VEC2, VEC3, RECTANGLE, NUMTYPES } ; + static int REGCOUNT[NUMTYPES]; + + bool enabled; + short type; + idStr name; + int regCount; + unsigned short regs[4]; + idWinVar * var; + + void SetToRegs( float *registers ); + void GetFromRegs( float *registers ); + void CopyRegs( idRegister *src ); + void Enable( bool b ) { enabled = b; } + void ReadFromDemoFile( idDemoFile *f ); + void WriteToDemoFile( idDemoFile *f ); + void WriteToSaveGame( idFile *savefile ); + void ReadFromSaveGame( idFile *savefile ); +}; + +ID_INLINE idRegister::idRegister( void ) { +} + +ID_INLINE idRegister::idRegister( const char *p, int t ) { + name = p; + type = t; + assert( t >= 0 && t < NUMTYPES ); + regCount = REGCOUNT[t]; + enabled = ( type == STRING ) ? false : true; + var = NULL; +}; + +ID_INLINE void idRegister::CopyRegs( idRegister *src ) { + regs[0] = src->regs[0]; + regs[1] = src->regs[1]; + regs[2] = src->regs[2]; + regs[3] = src->regs[3]; +} + +class idRegisterList { +public: + + idRegisterList(); + ~idRegisterList(); + + void AddReg( const char *name, int type, idParser *src, idWindow *win, idWinVar *var ); + void AddReg( const char *name, int type, idVec4 data, idWindow *win, idWinVar *var ); + + idRegister * FindReg( const char *name ); + void SetToRegs( float *registers ); + void GetFromRegs( float *registers ); + void Reset(); + void ReadFromDemoFile( idDemoFile *f ); + void WriteToDemoFile( idDemoFile *f ); + void WriteToSaveGame( idFile *savefile ); + void ReadFromSaveGame( idFile *savefile ); + +private: + idList regs; + idHashIndex regHash; +}; + +ID_INLINE idRegisterList::idRegisterList() { + regs.SetGranularity( 4 ); + regHash.SetGranularity( 4 ); + regHash.Clear( 32, 4 ); +} + +ID_INLINE idRegisterList::~idRegisterList() { +} + +#endif /* !__REGEXP_H__ */ diff --git a/ui/RegExp_old.h b/ui/RegExp_old.h new file mode 100644 index 000000000..b2d88e2ec --- /dev/null +++ b/ui/RegExp_old.h @@ -0,0 +1,78 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef REGEXP_H_ +#define REGEXP_H_ + +class idWindow; + +class idRegister { +public: + idRegister() {}; + idRegister(const char *p, int t) { + name = p; + type = t; + assert(t >= 0 && t < NUMTYPES); + regCount = REGCOUNT[t]; + enabled = (type == STRING) ? false : true; + }; + bool enabled; + int type; + int regCount; + enum REGTYPE { VEC4 = 0, FLOAT, BOOL, INT, STRING, VEC2, VEC3, NUMTYPES } ; + static int REGCOUNT[NUMTYPES]; + idStr name; + int regs[4]; + void SetToRegs(float *registers, idTypedDict *state); + void SetToRegList(idList *registers, idTypedDict *state); + void GetFromRegs(float *registers, idTypedDict *state); + void CopyRegs(idRegister *src) { + regs[0] = src->regs[0]; + regs[1] = src->regs[1]; + regs[2] = src->regs[2]; + regs[3] = src->regs[3]; + } + void Enable(bool b) { + enabled = b; + } + void ReadFromDemoFile(idDemoFile *f); + void WriteToDemoFile(idDemoFile *f); + +}; + +class idRegisterList { + idList regs; +public: + + // + void RemoveReg ( const char* name ); + // + + void AddReg(const char *name, int type, idParser *src, idWindow *win); + void AddReg(const char *name, int type, idVec4 data, idWindow *win); + idRegister *FindReg(const char *name); + int FindRegIndex ( const char* name ); + void SetToRegs(float *registers, idTypedDict *state); + void GetFromRegs(float *registers, idTypedDict *state); + void Reset(); + void ReadFromDemoFile(idDemoFile *f); + void WriteToDemoFile(idDemoFile *f); + +}; + +#endif \ No newline at end of file diff --git a/ui/RenderWindow.cpp b/ui/RenderWindow.cpp new file mode 100644 index 000000000..a8c9a1926 --- /dev/null +++ b/ui/RenderWindow.cpp @@ -0,0 +1,203 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "RenderWindow.h" + +idRenderWindow::idRenderWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idRenderWindow::idRenderWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idRenderWindow::~idRenderWindow() { + renderSystem->FreeRenderWorld( world ); +} + +void idRenderWindow::CommonInit() { + world = renderSystem->AllocRenderWorld(); + needsRender = true; + lightOrigin = idVec4(-128.0f, 0.0f, 0.0f, 1.0f); + lightColor = idVec4(1.0f, 1.0f, 1.0f, 1.0f); + modelOrigin.Zero(); + viewOffset = idVec4(-128.0f, 0.0f, 0.0f, 1.0f); + modelAnim = NULL; + animLength = 0; + animEndTime = -1; + modelDef = -1; + updateAnimation = true; +} + + +void idRenderWindow::BuildAnimation(int time) { + + if (!updateAnimation) { + return; + } + + if (animName.Length() && animClass.Length()) { + worldEntity.numJoints = worldEntity.hModel->NumJoints(); + worldEntity.joints = ( idJointMat * )Mem_Alloc16( worldEntity.numJoints * sizeof( *worldEntity.joints ) ); + modelAnim = gameEdit->ANIM_GetAnimFromEntityDef(animClass, animName); + if (modelAnim) { + animLength = gameEdit->ANIM_GetLength(modelAnim); + animEndTime = time + animLength; + } + } + updateAnimation = false; + +} + +void idRenderWindow::PreRender() { + if (needsRender) { + world->InitFromMap( NULL ); + idDict spawnArgs; + spawnArgs.Set("classname", "light"); + spawnArgs.Set("name", "light_1"); + spawnArgs.Set("origin", lightOrigin.ToVec3().ToString()); + spawnArgs.Set("_color", lightColor.ToVec3().ToString()); + gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &rLight ); + lightDef = world->AddLightDef( &rLight ); + if ( !modelName[0] ) { + common->Warning( "Window '%s' in gui '%s': no model set", GetName(), GetGui()->GetSourceFile() ); + } + memset( &worldEntity, 0, sizeof( worldEntity ) ); + spawnArgs.Clear(); + spawnArgs.Set("classname", "func_static"); + spawnArgs.Set("model", modelName); + spawnArgs.Set("origin", modelOrigin.c_str()); + gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &worldEntity ); + if ( worldEntity.hModel ) { + idVec3 v = modelRotate.ToVec3(); + worldEntity.axis = v.ToMat3(); + worldEntity.shaderParms[0] = 1; + worldEntity.shaderParms[1] = 1; + worldEntity.shaderParms[2] = 1; + worldEntity.shaderParms[3] = 1; + modelDef = world->AddEntityDef( &worldEntity ); + } + needsRender = false; + } +} + +void idRenderWindow::Render( int time ) { + rLight.origin = lightOrigin.ToVec3(); + rLight.shaderParms[SHADERPARM_RED] = lightColor.x(); + rLight.shaderParms[SHADERPARM_GREEN] = lightColor.y(); + rLight.shaderParms[SHADERPARM_BLUE] = lightColor.z(); + world->UpdateLightDef(lightDef, &rLight); + if ( worldEntity.hModel ) { + if (updateAnimation) { + BuildAnimation(time); + } + if (modelAnim) { + if (time > animEndTime) { + animEndTime = time + animLength; + } + gameEdit->ANIM_CreateAnimFrame(worldEntity.hModel, modelAnim, worldEntity.numJoints, worldEntity.joints, animLength - (animEndTime - time), vec3_origin, false ); + } + worldEntity.axis = idAngles(modelRotate.x(), modelRotate.y(), modelRotate.z()).ToMat3(); + world->UpdateEntityDef(modelDef, &worldEntity); + } +} + + + + +void idRenderWindow::Draw(int time, float x, float y) { + PreRender(); + Render(time); + + memset( &refdef, 0, sizeof( refdef ) ); + refdef.vieworg = viewOffset.ToVec3();; + //refdef.vieworg.Set(-128, 0, 0); + + refdef.viewaxis.Identity(); + refdef.shaderParms[0] = 1; + refdef.shaderParms[1] = 1; + refdef.shaderParms[2] = 1; + refdef.shaderParms[3] = 1; + + refdef.x = drawRect.x; + refdef.y = drawRect.y; + refdef.width = drawRect.w; + refdef.height = drawRect.h; + refdef.fov_x = 90; + refdef.fov_y = 2 * atan((float)drawRect.h / drawRect.w) * idMath::M_RAD2DEG; + + refdef.time = time; + world->RenderScene(&refdef); +} + +void idRenderWindow::PostParse() { + idWindow::PostParse(); +} + +// +// +idWinVar *idRenderWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner ) { +// + if (idStr::Icmp(_name, "model") == 0) { + return &modelName; + } + if (idStr::Icmp(_name, "anim") == 0) { + return &animName; + } + if (idStr::Icmp(_name, "lightOrigin") == 0) { + return &lightOrigin; + } + if (idStr::Icmp(_name, "lightColor") == 0) { + return &lightColor; + } + if (idStr::Icmp(_name, "modelOrigin") == 0) { + return &modelOrigin; + } + if (idStr::Icmp(_name, "modelRotate") == 0) { + return &modelRotate; + } + if (idStr::Icmp(_name, "viewOffset") == 0) { + return &viewOffset; + } + if (idStr::Icmp(_name, "needsRender") == 0) { + return &needsRender; + } + +// +// + return idWindow::GetWinVarByName(_name, fixup, owner); +// +} + +bool idRenderWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "animClass") == 0) { + ParseString(src, animClass); + return true; + } + return idWindow::ParseInternalVar(_name, src); +} diff --git a/ui/RenderWindow.h b/ui/RenderWindow.h new file mode 100644 index 000000000..14c5e2330 --- /dev/null +++ b/ui/RenderWindow.h @@ -0,0 +1,66 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ +#ifndef __RENDERWINDOW_H +#define __RENDERWINDOW_H + +class idUserInterfaceLocal; +class idRenderWindow : public idWindow { +public: + idRenderWindow(idUserInterfaceLocal *gui); + idRenderWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idRenderWindow(); + + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual size_t Allocated(){return idWindow::Allocated();}; +// +// + virtual idWinVar *GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL); +// + +private: + void CommonInit(); + virtual bool ParseInternalVar(const char *name, idParser *src); + void Render(int time); + void PreRender(); + void BuildAnimation(int time); + renderView_t refdef; + idRenderWorld *world; + renderEntity_t worldEntity; + renderLight_t rLight; + const idMD5Anim *modelAnim; + + qhandle_t worldModelDef; + qhandle_t lightDef; + qhandle_t modelDef; + idWinStr modelName; + idWinStr animName; + idStr animClass; + idWinVec4 lightOrigin; + idWinVec4 lightColor; + idWinVec4 modelOrigin; + idWinVec4 modelRotate; + idWinVec4 viewOffset; + idWinBool needsRender; + int animLength; + int animEndTime; + bool updateAnimation; +}; + +#endif // __RENDERWINDOW_H diff --git a/ui/SimpleWindow.cpp b/ui/SimpleWindow.cpp new file mode 100644 index 000000000..65e107e57 --- /dev/null +++ b/ui/SimpleWindow.cpp @@ -0,0 +1,430 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "SimpleWindow.h" + + +idSimpleWindow::idSimpleWindow(idWindow *win) { + gui = win->GetGui(); + dc = win->dc; + drawRect = win->drawRect; + clientRect = win->clientRect; + textRect = win->textRect; + origin = win->origin; + fontNum = win->fontNum; + name = win->name; + matScalex = win->matScalex; + matScaley = win->matScaley; + borderSize = win->borderSize; + textAlign = win->textAlign; + textAlignx = win->textAlignx; + textAligny = win->textAligny; + background = win->background; + flags = win->flags; + textShadow = win->textShadow; + + visible = win->visible; + text = win->text; + rect = win->rect; + backColor = win->backColor; + matColor = win->matColor; + foreColor = win->foreColor; + borderColor = win->borderColor; + textScale = win->textScale; + rotate = win->rotate; + shear = win->shear; + backGroundName = win->backGroundName; + if (backGroundName.Length()) { + background = declManager->FindMaterial(backGroundName); + background->SetSort( SS_GUI ); + background->SetImageClassifications( 1 ); // just for resource tracking + } + backGroundName.SetMaterialPtr(&background); + +// +// added parent + mParent = win->GetParent(); +// + + hideCursor = win->hideCursor; + + idWindow *parent = win->GetParent(); + if (parent) { + if (text.NeedsUpdate()) { + parent->AddUpdateVar(&text); + } + if (visible.NeedsUpdate()) { + parent->AddUpdateVar(&visible); + } + if (rect.NeedsUpdate()) { + parent->AddUpdateVar(&rect); + } + if (backColor.NeedsUpdate()) { + parent->AddUpdateVar(&backColor); + } + if (matColor.NeedsUpdate()) { + parent->AddUpdateVar(&matColor); + } + if (foreColor.NeedsUpdate()) { + parent->AddUpdateVar(&foreColor); + } + if (borderColor.NeedsUpdate()) { + parent->AddUpdateVar(&borderColor); + } + if (textScale.NeedsUpdate()) { + parent->AddUpdateVar(&textScale); + } + if (rotate.NeedsUpdate()) { + parent->AddUpdateVar(&rotate); + } + if (shear.NeedsUpdate()) { + parent->AddUpdateVar(&shear); + } + if (backGroundName.NeedsUpdate()) { + parent->AddUpdateVar(&backGroundName); + } + } +} + +idSimpleWindow::~idSimpleWindow() { + +} + +void idSimpleWindow::StateChanged( bool redraw ) { + if ( redraw && background && background->CinematicLength() ) { + background->UpdateCinematic( gui->GetTime() ); + } +} + +void idSimpleWindow::SetupTransforms(float x, float y) { + static idMat3 trans; + static idVec3 org; + + trans.Identity(); + org.Set( origin.x + x, origin.y + y, 0 ); + if ( rotate ) { + static idRotation rot; + static idVec3 vec( 0, 0, 1 ); + rot.Set( org, vec, rotate ); + trans = rot.ToMat3(); + } + + static idMat3 smat; + smat.Identity(); + if (shear.x() || shear.y()) { + smat[0][1] = shear.x(); + smat[1][0] = shear.y(); + trans *= smat; + } + + if ( !trans.IsIdentity() ) { + dc->SetTransformInfo( org, trans ); + } +} + +void idSimpleWindow::DrawBackground(const idRectangle &drawRect) { + if (backColor.w() > 0) { + dc->DrawFilledRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, backColor); + } + + if (background) { + if (matColor.w() > 0) { + float scalex, scaley; + if ( flags & WIN_NATURALMAT ) { + scalex = drawRect.w / background->GetImageWidth(); + scaley = drawRect.h / background->GetImageHeight(); + } else { + scalex = matScalex; + scaley = matScaley; + } + dc->DrawMaterial(drawRect.x, drawRect.y, drawRect.w, drawRect.h, background, matColor, scalex, scaley); + } + } +} + +void idSimpleWindow::DrawBorderAndCaption(const idRectangle &drawRect) { + if (flags & WIN_BORDER) { + if (borderSize) { + dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, borderSize, borderColor); + } + } +} + +void idSimpleWindow::CalcClientRect(float xofs, float yofs) { + + drawRect = rect; + + if ( flags & WIN_INVERTRECT ) { + drawRect.x = rect.x() - rect.w(); + drawRect.y = rect.y() - rect.h(); + } + + drawRect.x += xofs; + drawRect.y += yofs; + + clientRect = drawRect; + if (rect.h() > 0.0 && rect.w() > 0.0) { + + if (flags & WIN_BORDER && borderSize != 0.0) { + clientRect.x += borderSize; + clientRect.y += borderSize; + clientRect.w -= borderSize; + clientRect.h -= borderSize; + } + + textRect = clientRect; + textRect.x += 2.0; + textRect.w -= 2.0; + textRect.y += 2.0; + textRect.h -= 2.0; + textRect.x += textAlignx; + textRect.y += textAligny; + + } + origin.Set( rect.x() + ( rect.w() / 2 ), rect.y() + ( rect.h() / 2 ) ); + +} + + +void idSimpleWindow::Redraw(float x, float y) { + + if (!visible) { + return; + } + + CalcClientRect(0, 0); + dc->SetFont(fontNum); + drawRect.Offset(x, y); + clientRect.Offset(x, y); + textRect.Offset(x, y); + SetupTransforms(x, y); + if ( flags & WIN_NOCLIP ) { + dc->EnableClipping( false ); + } + DrawBackground(drawRect); + DrawBorderAndCaption(drawRect); + if ( textShadow ) { + idStr shadowText = text; + idRectangle shadowRect = textRect; + + shadowText.RemoveColors(); + shadowRect.x += textShadow; + shadowRect.y += textShadow; + + dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, !( flags & WIN_NOWRAP ), -1 ); + } + dc->DrawText(text, textScale, textAlign, foreColor, textRect, !( flags & WIN_NOWRAP ), -1); + dc->SetTransformInfo(vec3_origin, mat3_identity); + if ( flags & WIN_NOCLIP ) { + dc->EnableClipping( true ); + } + drawRect.Offset(-x, -y); + clientRect.Offset(-x, -y); + textRect.Offset(-x, -y); +} + +int idSimpleWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { + int ret = -1; + + if ( wv == &rect ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->rect; + } + + if ( wv == &backColor ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->backColor; + } + + if ( wv == &matColor ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->matColor; + } + + if ( wv == &foreColor ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->foreColor; + } + + if ( wv == &borderColor ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->borderColor; + } + + if ( wv == &textScale ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->textScale; + } + + if ( wv == &rotate ) { + ret = (int)&( ( idSimpleWindow * ) 0 )->rotate; + } + + if ( ret != -1 ) { + owner->simp = this; + } + return ret; +} + +idWinVar *idSimpleWindow::GetWinVarByName(const char *_name) { + idWinVar *retVar = NULL; + if (idStr::Icmp(_name, "background") == 0) { + retVar = &backGroundName; + } + if (idStr::Icmp(_name, "visible") == 0) { + retVar = &visible; + } + if (idStr::Icmp(_name, "rect") == 0) { + retVar = ▭ + } + if (idStr::Icmp(_name, "backColor") == 0) { + retVar = &backColor; + } + if (idStr::Icmp(_name, "matColor") == 0) { + retVar = &matColor; + } + if (idStr::Icmp(_name, "foreColor") == 0) { + retVar = &foreColor; + } + if (idStr::Icmp(_name, "borderColor") == 0) { + retVar = &borderColor; + } + if (idStr::Icmp(_name, "textScale") == 0) { + retVar = &textScale; + } + if (idStr::Icmp(_name, "rotate") == 0) { + retVar = &rotate; + } + if (idStr::Icmp(_name, "shear") == 0) { + retVar = &shear; + } + if (idStr::Icmp(_name, "text") == 0) { + retVar = &text; + } + return retVar; +} + +/* +======================== +idSimpleWindow::WriteToSaveGame +======================== +*/ +void idSimpleWindow::WriteToSaveGame( idFile *savefile ) { + + savefile->Write( &flags, sizeof( flags ) ); + savefile->Write( &drawRect, sizeof( drawRect ) ); + savefile->Write( &clientRect, sizeof( clientRect ) ); + savefile->Write( &textRect, sizeof( textRect ) ); + savefile->Write( &origin, sizeof( origin ) ); + savefile->Write( &fontNum, sizeof( fontNum ) ); + savefile->Write( &matScalex, sizeof( matScalex ) ); + savefile->Write( &matScaley, sizeof( matScaley ) ); + savefile->Write( &borderSize, sizeof( borderSize ) ); + savefile->Write( &textAlign, sizeof( textAlign ) ); + savefile->Write( &textAlignx, sizeof( textAlignx ) ); + savefile->Write( &textAligny, sizeof( textAligny ) ); + savefile->Write( &textShadow, sizeof( textShadow ) ); + + text.WriteToSaveGame( savefile ); + visible.WriteToSaveGame( savefile ); + rect.WriteToSaveGame( savefile ); + backColor.WriteToSaveGame( savefile ); + matColor.WriteToSaveGame( savefile ); + foreColor.WriteToSaveGame( savefile ); + borderColor.WriteToSaveGame( savefile ); + textScale.WriteToSaveGame( savefile ); + rotate.WriteToSaveGame( savefile ); + shear.WriteToSaveGame( savefile ); + backGroundName.WriteToSaveGame( savefile ); + + int stringLen; + + if ( background ) { + stringLen = strlen( background->GetName() ); + savefile->Write( &stringLen, sizeof( stringLen ) ); + savefile->Write( background->GetName(), stringLen ); + } else { + stringLen = 0; + savefile->Write( &stringLen, sizeof( stringLen ) ); + } + +} + +/* +======================== +idSimpleWindow::ReadFromSaveGame +======================== +*/ +void idSimpleWindow::ReadFromSaveGame( idFile *savefile ) { + + savefile->Read( &flags, sizeof( flags ) ); + savefile->Read( &drawRect, sizeof( drawRect ) ); + savefile->Read( &clientRect, sizeof( clientRect ) ); + savefile->Read( &textRect, sizeof( textRect ) ); + savefile->Read( &origin, sizeof( origin ) ); + savefile->Read( &fontNum, sizeof( fontNum ) ); + savefile->Read( &matScalex, sizeof( matScalex ) ); + savefile->Read( &matScaley, sizeof( matScaley ) ); + savefile->Read( &borderSize, sizeof( borderSize ) ); + savefile->Read( &textAlign, sizeof( textAlign ) ); + savefile->Read( &textAlignx, sizeof( textAlignx ) ); + savefile->Read( &textAligny, sizeof( textAligny ) ); + savefile->Read( &textShadow, sizeof( textShadow ) ); + + text.ReadFromSaveGame( savefile ); + visible.ReadFromSaveGame( savefile ); + rect.ReadFromSaveGame( savefile ); + backColor.ReadFromSaveGame( savefile ); + matColor.ReadFromSaveGame( savefile ); + foreColor.ReadFromSaveGame( savefile ); + borderColor.ReadFromSaveGame( savefile ); + textScale.ReadFromSaveGame( savefile ); + rotate.ReadFromSaveGame( savefile ); + shear.ReadFromSaveGame( savefile ); + backGroundName.ReadFromSaveGame( savefile ); + + int stringLen; + + savefile->Read( &stringLen, sizeof( stringLen ) ); + if ( stringLen > 0 ) { + idStr backName; + + backName.Fill( ' ', stringLen ); + savefile->Read( &(backName)[0], stringLen ); + + background = declManager->FindMaterial( backName ); + background->SetSort( SS_GUI ); + } else { + background = NULL; + } + +} + + +/* +=============================== +*/ + +size_t idSimpleWindow::Size() { + size_t sz = sizeof(*this); + sz += name.Size(); + sz += text.Size(); + sz += backGroundName.Size(); + return sz; +} diff --git a/ui/SimpleWindow.h b/ui/SimpleWindow.h new file mode 100644 index 000000000..ab30e0e86 --- /dev/null +++ b/ui/SimpleWindow.h @@ -0,0 +1,92 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SIMPLEWIN_H__ +#define __SIMPLEWIN_H__ + +class idUserInterfaceLocal; +class idDeviceContext; +class idSimpleWindow; + +typedef struct { + idWindow *win; + idSimpleWindow *simp; +} drawWin_t; + +class idSimpleWindow { + friend class idWindow; +public: + idSimpleWindow(idWindow* win); + virtual ~idSimpleWindow(); + void Redraw(float x, float y); + void StateChanged( bool redraw ); + + idStr name; + + idWinVar * GetWinVarByName(const char *_name); + int GetWinVarOffset( idWinVar *wv, drawWin_t* owner); + size_t Size(); + + idWindow* GetParent ( void ) { return mParent; } + + virtual void WriteToSaveGame( idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + +protected: + void CalcClientRect(float xofs, float yofs); + void SetupTransforms(float x, float y); + void DrawBackground(const idRectangle &drawRect); + void DrawBorderAndCaption(const idRectangle &drawRect); + + idUserInterfaceLocal *gui; + idDeviceContext *dc; + int flags; + idRectangle drawRect; // overall rect + idRectangle clientRect; // client area + idRectangle textRect; + idVec2 origin; + int fontNum; + float matScalex; + float matScaley; + float borderSize; + int textAlign; + float textAlignx; + float textAligny; + int textShadow; + + idWinStr text; + idWinBool visible; + idWinRectangle rect; // overall rect + idWinVec4 backColor; + idWinVec4 matColor; + idWinVec4 foreColor; + idWinVec4 borderColor; + idWinFloat textScale; + idWinFloat rotate; + idWinVec2 shear; + idWinBackground backGroundName; + + const idMaterial* background; + + idWindow * mParent; + + idWinBool hideCursor; +}; + +#endif /* !__SIMPLEWIN_H__ */ diff --git a/ui/SliderWindow.cpp b/ui/SliderWindow.cpp new file mode 100644 index 000000000..7c4347f8d --- /dev/null +++ b/ui/SliderWindow.cpp @@ -0,0 +1,407 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "SliderWindow.h" + +/* +============ +idSliderWindow::CommonInit +============ +*/ +void idSliderWindow::CommonInit() { + value = 0.0; + low = 0.0; + high = 100.0; + stepSize = 1.0; + thumbMat = declManager->FindMaterial("_default"); + buddyWin = NULL; + + cvar = NULL; + cvar_init = false; + liveUpdate = true; + + vertical = false; + scrollbar = false; + + verticalFlip = false; +} + +idSliderWindow::idSliderWindow(idDeviceContext *d, idUserInterfaceLocal *g) : idWindow(d, g) { + dc = d; + gui = g; + CommonInit(); +} + +idSliderWindow::idSliderWindow(idUserInterfaceLocal *g) : idWindow(g) { + gui = g; + CommonInit(); +} + +idSliderWindow::~idSliderWindow() { + +} + +bool idSliderWindow::ParseInternalVar(const char *_name, idParser *src) { + if (idStr::Icmp(_name, "stepsize") == 0 || idStr::Icmp(_name, "step") == 0) { + stepSize = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "low") == 0) { + low = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "high") == 0) { + high = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "vertical") == 0) { + vertical = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "verticalflip") == 0) { + verticalFlip = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "scrollbar") == 0) { + scrollbar = src->ParseBool(); + return true; + } + if (idStr::Icmp(_name, "thumbshader") == 0) { + ParseString(src, thumbShader); + declManager->FindMaterial(thumbShader); + return true; + } + return idWindow::ParseInternalVar(_name, src); +} + +idWinVar *idSliderWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { + + if (idStr::Icmp(_name, "value") == 0) { + return &value; + } + if (idStr::Icmp(_name, "cvar") == 0) { + return &cvarStr; + } + if ( idStr::Icmp( _name, "liveUpdate" ) == 0 ) { + return &liveUpdate; + } + if ( idStr::Icmp( _name, "cvarGroup" ) == 0 ) { + return &cvarGroup; + } + + return idWindow::GetWinVarByName(_name, fixup, owner); +} + +const char *idSliderWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + + if (!(event->evType == SE_KEY && event->evValue2)) { + return ""; + } + + int key = event->evValue; + + if ( event->evValue2 && key == K_MOUSE1 ) { + SetCapture(this); + RouteMouseCoords(0.0f, 0.0f); + return ""; + } + + if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW || ( key == K_MOUSE2 && gui->CursorY() > thumbRect.y ) ) { + value = value + stepSize; + } + + if ( key == K_LEFTARROW || key == K_KP_LEFTARROW || ( key == K_MOUSE2 && gui->CursorY() < thumbRect.y ) ) { + value = value - stepSize; + } + + if (buddyWin) { + buddyWin->HandleBuddyUpdate(this); + } else { + gui->SetStateFloat( cvarStr, value ); + UpdateCvar( false ); + } + + return ""; +} + + +void idSliderWindow::SetBuddy(idWindow *buddy) { + buddyWin = buddy; +} + +void idSliderWindow::PostParse() { + idWindow::PostParse(); + value = 0.0; + thumbMat = declManager->FindMaterial(thumbShader); + thumbMat->SetSort( SS_GUI ); + thumbWidth = thumbMat->GetImageWidth(); + thumbHeight = thumbMat->GetImageHeight(); + //vertical = state.GetBool("vertical"); + //scrollbar = state.GetBool("scrollbar"); + flags |= (WIN_HOLDCAPTURE | WIN_CANFOCUS); + InitCvar(); +} + +void idSliderWindow::InitWithDefaults(const char *_name, const idRectangle &_rect, const idVec4 &_foreColor, const idVec4 &_matColor, const char *_background, const char *thumbShader, bool _vertical, bool _scrollbar) { + SetInitialState(_name); + rect = _rect; + foreColor = _foreColor; + matColor = _matColor; + thumbMat = declManager->FindMaterial(thumbShader); + thumbMat->SetSort( SS_GUI ); + thumbWidth = thumbMat->GetImageWidth(); + thumbHeight = thumbMat->GetImageHeight(); + background = declManager->FindMaterial(_background); + background->SetSort( SS_GUI ); + vertical = _vertical; + scrollbar = _scrollbar; + flags |= WIN_HOLDCAPTURE; +} + +void idSliderWindow::SetRange(float _low, float _high, float _step) { + low = _low; + high = _high; + stepSize = _step; +} + +void idSliderWindow::SetValue(float _value) { + value = _value; +} + +void idSliderWindow::Draw(int time, float x, float y) { + idVec4 color = foreColor; + + if ( !cvar && !buddyWin ) { + return; + } + + if ( !thumbWidth || !thumbHeight ) { + thumbWidth = thumbMat->GetImageWidth(); + thumbHeight = thumbMat->GetImageHeight(); + } + + UpdateCvar( true ); + if ( value > high ) { + value = high; + } else if ( value < low ) { + value = low; + } + + float range = high - low; + + if ( range <= 0.0f ) { + return; + } + + float thumbPos = (range) ? (value - low) / range : 0.0; + if (vertical) { + if ( verticalFlip ) { + thumbPos = 1.f - thumbPos; + } + thumbPos *= drawRect.h - thumbHeight; + thumbPos += drawRect.y; + thumbRect.y = thumbPos; + thumbRect.x = drawRect.x; + } else { + thumbPos *= drawRect.w - thumbWidth; + thumbPos += drawRect.x; + thumbRect.x = thumbPos; + thumbRect.y = drawRect.y; + } + thumbRect.w = thumbWidth; + thumbRect.h = thumbHeight; + + if ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) { + color = hoverColor; + } else { + hover = false; + } + if ( flags & WIN_CAPTURE ) { + color = hoverColor; + hover = true; + } + + dc->DrawMaterial(thumbRect.x, thumbRect.y, thumbRect.w, thumbRect.h, thumbMat, color); + if ( flags & WIN_FOCUS ) { + dc->DrawRect(thumbRect.x+1.0f, thumbRect.y+1.0f, thumbRect.w-2.0f, thumbRect.h-2.0f, 1.0f, color); + } +} + + +void idSliderWindow::DrawBackground(const idRectangle &_drawRect) { + if ( !cvar && !buddyWin ) { + return; + } + + if ( high - low <= 0.0f ) { + return; + } + + idRectangle r = _drawRect; + if (!scrollbar) { + if ( vertical ) { + r.y += thumbHeight / 2.f; + r.h -= thumbHeight; + } else { + r.x += thumbWidth / 2.0; + r.w -= thumbWidth; + } + } + idWindow::DrawBackground(r); +} + +const char *idSliderWindow::RouteMouseCoords(float xd, float yd) { + float pct; + + if (!(flags & WIN_CAPTURE)) { + return ""; + } + + idRectangle r = drawRect; + r.x = actualX; + r.y = actualY; + r.x += thumbWidth / 2.0; + r.w -= thumbWidth; + if (vertical) { + r.y += thumbHeight / 2; + r.h -= thumbHeight; + if (gui->CursorY() >= r.y && gui->CursorY() <= r.Bottom()) { + pct = (gui->CursorY() - r.y) / r.h; + if ( verticalFlip ) { + pct = 1.f - pct; + } + value = low + (high - low) * pct; + } else if (gui->CursorY() < r.y) { + if ( verticalFlip ) { + value = high; + } else { + value = low; + } + } else { + if ( verticalFlip ) { + value = low; + } else { + value = high; + } + } + } else { + r.x += thumbWidth / 2; + r.w -= thumbWidth; + if (gui->CursorX() >= r.x && gui->CursorX() <= r.Right()) { + pct = (gui->CursorX() - r.x) / r.w; + value = low + (high - low) * pct; + } else if (gui->CursorX() < r.x) { + value = low; + } else { + value = high; + } + } + + if (buddyWin) { + buddyWin->HandleBuddyUpdate(this); + } else { + gui->SetStateFloat( cvarStr, value ); + } + UpdateCvar( false ); + + return ""; +} + + +void idSliderWindow::Activate(bool activate, idStr &act) { + idWindow::Activate(activate, act); + if ( activate ) { + UpdateCvar( true, true ); + } +} + +/* +============ +idSliderWindow::InitCvar +============ +*/ +void idSliderWindow::InitCvar( ) { + if ( cvarStr[0] == '\0' ) { + if ( !buddyWin ) { + common->Warning( "idSliderWindow::InitCvar: gui '%s' window '%s' has an empty cvar string", gui->GetSourceFile(), name.c_str() ); + } + cvar_init = true; + cvar = NULL; + return; + } + + cvar = cvarSystem->Find( cvarStr ); + if ( !cvar ) { + common->Warning( "idSliderWindow::InitCvar: gui '%s' window '%s' references undefined cvar '%s'", gui->GetSourceFile(), name.c_str(), cvarStr.c_str() ); + cvar_init = true; + return; + } +} + +/* +============ +idSliderWindow::UpdateCvar +============ +*/ +void idSliderWindow::UpdateCvar( bool read, bool force ) { + if ( buddyWin || !cvar ) { + return; + } + if ( force || liveUpdate ) { + value = cvar->GetFloat(); + if ( value != gui->State().GetFloat( cvarStr ) ) { + if ( read ) { + gui->SetStateFloat( cvarStr, value ); + } else { + value = gui->State().GetFloat( cvarStr ); + cvar->SetFloat( value ); + } + } + } +} + +/* +============ +idSliderWindow::RunNamedEvent +============ +*/ +void idSliderWindow::RunNamedEvent( const char* eventName ) { + idStr event, group; + + if ( !idStr::Cmpn( eventName, "cvar read ", 10 ) ) { + event = eventName; + group = event.Mid( 10, event.Length() - 10 ); + if ( !group.Cmp( cvarGroup ) ) { + UpdateCvar( true, true ); + } + } else if ( !idStr::Cmpn( eventName, "cvar write ", 11 ) ) { + event = eventName; + group = event.Mid( 11, event.Length() - 11 ); + if ( !group.Cmp( cvarGroup ) ) { + UpdateCvar( false, true ); + } + } +} + diff --git a/ui/SliderWindow.h b/ui/SliderWindow.h new file mode 100644 index 000000000..d79142980 --- /dev/null +++ b/ui/SliderWindow.h @@ -0,0 +1,84 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __SLIDERWINDOW_H__ +#define __SLIDERWINDOW_H__ + +class idUserInterfaceLocal; + +class idSliderWindow : public idWindow { +public: + idSliderWindow(idUserInterfaceLocal *gui); + idSliderWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idSliderWindow(); + + void InitWithDefaults(const char *_name, const idRectangle &rect, const idVec4 &foreColor, const idVec4 &matColor, const char *_background, const char *thumbShader, bool _vertical, bool _scrollbar); + + void SetRange(float _low, float _high, float _step); + float GetLow() { return low; } + float GetHigh() { return high; } + + void SetValue(float _value); + float GetValue() { return value; }; + + virtual size_t Allocated(){return idWindow::Allocated();}; + virtual idWinVar * GetWinVarByName(const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual void PostParse(); + virtual void Draw(int time, float x, float y); + virtual void DrawBackground(const idRectangle &drawRect); + virtual const char *RouteMouseCoords(float xd, float yd); + virtual void Activate(bool activate, idStr &act); + virtual void SetBuddy(idWindow *buddy); + + void RunNamedEvent( const char* eventName ); + +private: + virtual bool ParseInternalVar(const char *name, idParser *src); + void CommonInit(); + void InitCvar(); + // true: read the updated cvar from cvar system + // false: write to the cvar system + // force == true overrides liveUpdate 0 + void UpdateCvar( bool read, bool force = false ); + + idWinFloat value; + float low; + float high; + float thumbWidth; + float thumbHeight; + float stepSize; + float lastValue; + idRectangle thumbRect; + const idMaterial * thumbMat; + bool vertical; + bool verticalFlip; + bool scrollbar; + idWindow * buddyWin; + idStr thumbShader; + + idWinStr cvarStr; + idCVar * cvar; + bool cvar_init; + idWinBool liveUpdate; + idWinStr cvarGroup; +}; + +#endif /* !__SLIDERWINDOW_H__ */ + diff --git a/ui/UserInterface.cpp b/ui/UserInterface.cpp new file mode 100644 index 000000000..51805f1e2 --- /dev/null +++ b/ui/UserInterface.cpp @@ -0,0 +1,631 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "ListGUILocal.h" +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" + +extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces + +idUserInterfaceManagerLocal uiManagerLocal; +idUserInterfaceManager * uiManager = &uiManagerLocal; + +/* +=============================================================================== + + idUserInterfaceManagerLocal + +=============================================================================== +*/ + +void idUserInterfaceManagerLocal::Init() { + screenRect = idRectangle(0, 0, 640, 480); + dc.Init(); +} + +void idUserInterfaceManagerLocal::Shutdown() { + guis.DeleteContents( true ); + demoGuis.DeleteContents( true ); + dc.Shutdown(); +} + +void idUserInterfaceManagerLocal::Touch( const char *name ) { + idUserInterface *gui = Alloc(); + gui->InitFromFile( name ); +// delete gui; +} + +void idUserInterfaceManagerLocal::WritePrecacheCommands( idFile *f ) { + + int c = guis.Num(); + for( int i = 0; i < c; i++ ) { + char str[1024]; + sprintf( str, "touchGui %s\n", guis[i]->Name() ); + common->Printf( "%s", str ); + f->Printf( "%s", str ); + } +} + +void idUserInterfaceManagerLocal::SetSize( float width, float height ) { + dc.SetSize( width, height ); +} + +void idUserInterfaceManagerLocal::BeginLevelLoad() { + int c = guis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( (guis[ i ]->GetDesktop()->GetFlags() & WIN_MENUGUI) == 0 ) { + guis[ i ]->ClearRefs(); + /* + delete guis[ i ]; + guis.RemoveIndex( i ); + i--; c--; + */ + } + } +} + +void idUserInterfaceManagerLocal::EndLevelLoad() { + int c = guis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( guis[i]->GetRefs() == 0 ) { + //common->Printf( "purging %s.\n", guis[i]->GetSourceFile() ); + + // use this to make sure no materials still reference this gui + bool remove = true; + for ( int j = 0; j < declManager->GetNumDecls( DECL_MATERIAL ); j++ ) { + const idMaterial *material = static_cast(declManager->DeclByIndex( DECL_MATERIAL, j, false )); + if ( material->GlobalGui() == guis[i] ) { + remove = false; + break; + } + } + if ( remove ) { + delete guis[ i ]; + guis.RemoveIndex( i ); + i--; c--; + } + } + } +} + +void idUserInterfaceManagerLocal::Reload( bool all ) { + ID_TIME_T ts; + + int c = guis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( !all ) { + fileSystem->ReadFile( guis[i]->GetSourceFile(), NULL, &ts ); + if ( ts <= guis[i]->GetTimeStamp() ) { + continue; + } + } + + guis[i]->InitFromFile( guis[i]->GetSourceFile() ); + common->Printf( "reloading %s.\n", guis[i]->GetSourceFile() ); + } +} + +void idUserInterfaceManagerLocal::ListGuis() const { + int c = guis.Num(); + common->Printf( "\n size refs name\n" ); + size_t total = 0; + int copies = 0; + int unique = 0; + for ( int i = 0; i < c; i++ ) { + idUserInterfaceLocal *gui = guis[i]; + size_t sz = gui->Size(); + bool isUnique = guis[i]->interactive; + if ( isUnique ) { + unique++; + } else { + copies++; + } + common->Printf( "%6.1fk %4i (%s) %s ( %i transitions )\n", sz / 1024.0f, guis[i]->GetRefs(), isUnique ? "unique" : "copy", guis[i]->GetSourceFile(), guis[i]->desktop->NumTransitions() ); + total += sz; + } + common->Printf( "===========\n %i total Guis ( %i copies, %i unique ), %.2f total Mbytes", c, copies, unique, total / ( 1024.0f * 1024.0f ) ); +} + +bool idUserInterfaceManagerLocal::CheckGui( const char *qpath ) const { + idFile *file = fileSystem->OpenFileRead( qpath ); + if ( file ) { + fileSystem->CloseFile( file ); + return true; + } + return false; +} + +idUserInterface *idUserInterfaceManagerLocal::Alloc( void ) const { + return new idUserInterfaceLocal(); +} + +void idUserInterfaceManagerLocal::DeAlloc( idUserInterface *gui ) { + if ( gui ) { + int c = guis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( guis[i] == gui ) { + delete guis[i]; + guis.RemoveIndex( i ); + return; + } + } + } +} + +idUserInterface *idUserInterfaceManagerLocal::FindGui( const char *qpath, bool autoLoad, bool needUnique, bool forceNOTUnique ) { + int c = guis.Num(); + + for ( int i = 0; i < c; i++ ) { + idUserInterfaceLocal *gui = guis[i]; + if ( !idStr::Icmp( guis[i]->GetSourceFile(), qpath ) ) { + if ( !forceNOTUnique && ( needUnique || guis[i]->IsInteractive() ) ) { + break; + } + guis[i]->AddRef(); + return guis[i]; + } + } + + if ( autoLoad ) { + idUserInterface *gui = Alloc(); + if ( gui->InitFromFile( qpath ) ) { + gui->SetUniqued( forceNOTUnique ? false : needUnique ); + return gui; + } else { + delete gui; + } + } + return NULL; +} + +idUserInterface *idUserInterfaceManagerLocal::FindDemoGui( const char *qpath ) { + int c = demoGuis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( !idStr::Icmp( demoGuis[i]->GetSourceFile(), qpath ) ) { + return demoGuis[i]; + } + } + return NULL; +} + +idListGUI * idUserInterfaceManagerLocal::AllocListGUI( void ) const { + return new idListGUILocal(); +} + +void idUserInterfaceManagerLocal::FreeListGUI( idListGUI *listgui ) { + delete listgui; +} + +/* +=============================================================================== + + idUserInterfaceLocal + +=============================================================================== +*/ + +idUserInterfaceLocal::idUserInterfaceLocal() { + cursorX = cursorY = 0.0; + desktop = NULL; + loading = false; + active = false; + interactive = false; + uniqued = false; + bindHandler = NULL; + //so the reg eval in gui parsing doesn't get bogus values + time = 0; + refs = 1; +} + +idUserInterfaceLocal::~idUserInterfaceLocal() { + delete desktop; + desktop = NULL; +} + +const char *idUserInterfaceLocal::Name() const { + return source; +} + +const char *idUserInterfaceLocal::Comment() const { + if ( desktop ) { + return desktop->GetComment(); + } + return ""; +} + +bool idUserInterfaceLocal::IsInteractive() const { + return interactive; +} + +bool idUserInterfaceLocal::InitFromFile( const char *qpath, bool rebuild, bool cache ) { + + if ( !( qpath && *qpath ) ) { + // FIXME: Memory leak!! + return false; + } + + int sz = sizeof( idWindow ); + sz = sizeof( idSimpleWindow ); + loading = true; + + if ( rebuild ) { + delete desktop; + desktop = new idWindow( this ); + } else if ( desktop == NULL ) { + desktop = new idWindow( this ); + } + + source = qpath; + state.Set( "text", "Test Text!" ); + + idParser src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + + //Load the timestamp so reload guis will work correctly + fileSystem->ReadFile(qpath, NULL, &timeStamp); + + src.LoadFile( qpath ); + + if ( src.IsLoaded() ) { + idToken token; + while( src.ReadToken( &token ) ) { + if ( idStr::Icmp( token, "windowDef" ) == 0 ) { + desktop->SetDC( &uiManagerLocal.dc ); + if ( desktop->Parse( &src, rebuild ) ) { + desktop->SetFlag( WIN_DESKTOP ); + desktop->FixupParms(); + } + continue; + } + } + + state.Set( "name", qpath ); + } else { + desktop->SetDC( &uiManagerLocal.dc ); + desktop->SetFlag( WIN_DESKTOP ); + desktop->name = "Desktop"; + desktop->text = va( "Invalid GUI: %s", qpath ); + desktop->rect = idRectangle( 0.0f, 0.0f, 640.0f, 480.0f ); + desktop->drawRect = desktop->rect; + desktop->foreColor = idVec4( 1.0f, 1.0f, 1.0f, 1.0f ); + desktop->backColor = idVec4( 0.0f, 0.0f, 0.0f, 1.0f ); + desktop->SetupFromState(); + common->Warning( "Couldn't load gui: '%s'", qpath ); + } + + interactive = desktop->Interactive(); + + if ( uiManagerLocal.guis.Find( this ) == NULL ) { + uiManagerLocal.guis.Append( this ); + } + + loading = false; + + return true; +} + +const char *idUserInterfaceLocal::HandleEvent( const sysEvent_t *event, int _time, bool *updateVisuals ) { + + time = _time; + + if ( bindHandler && event->evType == SE_KEY && event->evValue2 == 1 ) { + const char *ret = bindHandler->HandleEvent( event, updateVisuals ); + bindHandler = NULL; + return ret; + } + + if ( event->evType == SE_MOUSE ) { + cursorX += event->evValue; + cursorY += event->evValue2; + + if (cursorX < 0) { + cursorX = 0; + } + if (cursorY < 0) { + cursorY = 0; + } + } + + if ( desktop ) { + return desktop->HandleEvent( event, updateVisuals ); + } + + return ""; +} + +void idUserInterfaceLocal::HandleNamedEvent ( const char* eventName ) { + desktop->RunNamedEvent( eventName ); +} + +void idUserInterfaceLocal::Redraw( int _time ) { + if ( r_skipGuiShaders.GetInteger() > 5 ) { + return; + } + if ( !loading && desktop ) { + time = _time; + uiManagerLocal.dc.PushClipRect( uiManagerLocal.screenRect ); + desktop->Redraw( 0, 0 ); + uiManagerLocal.dc.PopClipRect(); + } +} + +void idUserInterfaceLocal::DrawCursor() { + if ( !desktop || desktop->GetFlags() & WIN_MENUGUI ) { + uiManagerLocal.dc.DrawCursor(&cursorX, &cursorY, 32.0f ); + } else { + uiManagerLocal.dc.DrawCursor(&cursorX, &cursorY, 64.0f ); + } +} + +const idDict &idUserInterfaceLocal::State() const { + return state; +} + +void idUserInterfaceLocal::DeleteStateVar( const char *varName ) { + state.Delete( varName ); +} + +void idUserInterfaceLocal::SetStateString( const char *varName, const char *value ) { + state.Set( varName, value ); +} + +void idUserInterfaceLocal::SetStateBool( const char *varName, const bool value ) { + state.SetBool( varName, value ); +} + +void idUserInterfaceLocal::SetStateInt( const char *varName, const int value ) { + state.SetInt( varName, value ); +} + +void idUserInterfaceLocal::SetStateFloat( const char *varName, const float value ) { + state.SetFloat( varName, value ); +} + +const char* idUserInterfaceLocal::GetStateString( const char *varName, const char* defaultString ) const { + return state.GetString(varName, defaultString); +} + +bool idUserInterfaceLocal::GetStateBool( const char *varName, const char* defaultString ) const { + return state.GetBool(varName, defaultString); +} + +int idUserInterfaceLocal::GetStateInt( const char *varName, const char* defaultString ) const { + return state.GetInt(varName, defaultString); +} + +float idUserInterfaceLocal::GetStateFloat( const char *varName, const char* defaultString ) const { + return state.GetFloat(varName, defaultString); +} + +void idUserInterfaceLocal::StateChanged( int _time, bool redraw ) { + time = _time; + if (desktop) { + desktop->StateChanged( redraw ); + } + if ( state.GetBool( "noninteractive" ) ) { + interactive = false; + } + else { + if (desktop) { + interactive = desktop->Interactive(); + } else { + interactive = false; + } + } +} + +const char *idUserInterfaceLocal::Activate(bool activate, int _time) { + time = _time; + active = activate; + if ( desktop ) { + activateStr = ""; + desktop->Activate( activate, activateStr ); + return activateStr; + } + return ""; +} + +void idUserInterfaceLocal::Trigger(int _time) { + time = _time; + if ( desktop ) { + desktop->Trigger(); + } +} + +void idUserInterfaceLocal::ReadFromDemoFile( class idDemoFile *f ) { + idStr work; + f->ReadDict( state ); + source = state.GetString("name"); + + if (desktop == NULL) { + f->Log("creating new gui\n"); + desktop = new idWindow(this); + desktop->SetFlag( WIN_DESKTOP ); + desktop->SetDC( &uiManagerLocal.dc ); + desktop->ReadFromDemoFile(f); + } else { + f->Log("re-using gui\n"); + desktop->ReadFromDemoFile(f, false); + } + + f->ReadFloat( cursorX ); + f->ReadFloat( cursorY ); + + bool add = true; + int c = uiManagerLocal.demoGuis.Num(); + for ( int i = 0; i < c; i++ ) { + if ( uiManagerLocal.demoGuis[i] == this ) { + add = false; + break; + } + } + + if (add) { + uiManagerLocal.demoGuis.Append(this); + } +} + +void idUserInterfaceLocal::WriteToDemoFile( class idDemoFile *f ) { + idStr work; + f->WriteDict( state ); + if (desktop) { + desktop->WriteToDemoFile(f); + } + + f->WriteFloat( cursorX ); + f->WriteFloat( cursorY ); +} + +bool idUserInterfaceLocal::WriteToSaveGame( idFile *savefile ) const { + int len; + const idKeyValue *kv; + const char *string; + + int num = state.GetNumKeyVals(); + savefile->Write( &num, sizeof( num ) ); + + for( int i = 0; i < num; i++ ) { + kv = state.GetKeyVal( i ); + len = kv->GetKey().Length(); + string = kv->GetKey().c_str(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( string, len ); + + len = kv->GetValue().Length(); + string = kv->GetValue().c_str(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( string, len ); + } + + savefile->Write( &active, sizeof( active ) ); + savefile->Write( &interactive, sizeof( interactive ) ); + savefile->Write( &uniqued, sizeof( uniqued ) ); + savefile->Write( &time, sizeof( time ) ); + len = activateStr.Length(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( activateStr.c_str(), len ); + len = pendingCmd.Length(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( pendingCmd.c_str(), len ); + len = returnCmd.Length(); + savefile->Write( &len, sizeof( len ) ); + savefile->Write( returnCmd.c_str(), len ); + + savefile->Write( &cursorX, sizeof( cursorX ) ); + savefile->Write( &cursorY, sizeof( cursorY ) ); + + desktop->WriteToSaveGame( savefile ); + + return true; +} + +bool idUserInterfaceLocal::ReadFromSaveGame( idFile *savefile ) { + int num; + int i, len; + idStr key; + idStr value; + + savefile->Read( &num, sizeof( num ) ); + + state.Clear(); + for( i = 0; i < num; i++ ) { + savefile->Read( &len, sizeof( len ) ); + key.Fill( ' ', len ); + savefile->Read( &key[0], len ); + + savefile->Read( &len, sizeof( len ) ); + value.Fill( ' ', len ); + savefile->Read( &value[0], len ); + + state.Set( key, value ); + } + + savefile->Read( &active, sizeof( active ) ); + savefile->Read( &interactive, sizeof( interactive ) ); + savefile->Read( &uniqued, sizeof( uniqued ) ); + savefile->Read( &time, sizeof( time ) ); + + savefile->Read( &len, sizeof( len ) ); + activateStr.Fill( ' ', len ); + savefile->Read( &activateStr[0], len ); + savefile->Read( &len, sizeof( len ) ); + pendingCmd.Fill( ' ', len ); + savefile->Read( &pendingCmd[0], len ); + savefile->Read( &len, sizeof( len ) ); + returnCmd.Fill( ' ', len ); + savefile->Read( &returnCmd[0], len ); + + savefile->Read( &cursorX, sizeof( cursorX ) ); + savefile->Read( &cursorY, sizeof( cursorY ) ); + + desktop->ReadFromSaveGame( savefile ); + + return true; +} + +size_t idUserInterfaceLocal::Size() { + size_t sz = sizeof(*this) + state.Size() + source.Allocated(); + if ( desktop ) { + sz += desktop->Size(); + } + return sz; +} + +void idUserInterfaceLocal::RecurseSetKeyBindingNames( idWindow *window ) { + int i; + idWinVar *v = window->GetWinVarByName( "bind" ); + if ( v ) { + SetStateString( v->GetName(), idKeyInput::KeysFromBinding( v->GetName() ) ); + } + i = 0; + while ( i < window->GetChildCount() ) { + idWindow *next = window->GetChild( i ); + if ( next ) { + RecurseSetKeyBindingNames( next ); + } + i++; + } +} + +/* +============== +idUserInterfaceLocal::SetKeyBindingNames +============== +*/ +void idUserInterfaceLocal::SetKeyBindingNames( void ) { + if ( !desktop ) { + return; + } + // walk the windows + RecurseSetKeyBindingNames( desktop ); +} + +/* +============== +idUserInterfaceLocal::SetCursor +============== +*/ +void idUserInterfaceLocal::SetCursor( float x, float y ) { + cursorX = x; + cursorY = y; +} + diff --git a/ui/UserInterface.h b/ui/UserInterface.h new file mode 100644 index 000000000..d92078555 --- /dev/null +++ b/ui/UserInterface.h @@ -0,0 +1,153 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __USERINTERFACE_H__ +#define __USERINTERFACE_H__ + +/* +=============================================================================== + + Draws an interactive 2D surface. + Used for all user interaction with the game. + +=============================================================================== +*/ + +class idFile; +class idDemoFile; + + +class idUserInterface { +public: + virtual ~idUserInterface() {}; + + // Returns the name of the gui. + virtual const char * Name() const = 0; + + // Returns a comment on the gui. + virtual const char * Comment() const = 0; + + // Returns true if the gui is interactive. + virtual bool IsInteractive() const = 0; + + virtual bool IsUniqued() const = 0; + + virtual void SetUniqued( bool b ) = 0; + // returns false if it failed to load + virtual bool InitFromFile( const char *qpath, bool rebuild = true, bool cache = true ) = 0; + + // handles an event, can return an action string, the caller interprets + // any return and acts accordingly + virtual const char * HandleEvent( const sysEvent_t *event, int time, bool *updateVisuals = NULL ) = 0; + + // handles a named event + virtual void HandleNamedEvent( const char *eventName ) = 0; + + // repaints the ui + virtual void Redraw( int time ) = 0; + + // repaints the cursor + virtual void DrawCursor() = 0; + + // Provides read access to the idDict that holds this gui's state. + virtual const idDict & State() const = 0; + + // Removes a gui state variable + virtual void DeleteStateVar( const char *varName ) = 0; + + // Sets a gui state variable. + virtual void SetStateString( const char *varName, const char *value ) = 0; + virtual void SetStateBool( const char *varName, const bool value ) = 0; + virtual void SetStateInt( const char *varName, const int value ) = 0; + virtual void SetStateFloat( const char *varName, const float value ) = 0; + + // Gets a gui state variable + virtual const char* GetStateString( const char *varName, const char* defaultString = "" ) const = 0; + virtual bool GetStateBool( const char *varName, const char* defaultString = "0" ) const = 0; + virtual int GetStateInt( const char *varName, const char* defaultString = "0" ) const = 0; + virtual float GetStateFloat( const char *varName, const char* defaultString = "0" ) const = 0; + + // The state has changed and the gui needs to update from the state idDict. + virtual void StateChanged( int time, bool redraw = false ) = 0; + + // Activated the gui. + virtual const char * Activate( bool activate, int time ) = 0; + + // Triggers the gui and runs the onTrigger scripts. + virtual void Trigger( int time ) = 0; + + virtual void ReadFromDemoFile( class idDemoFile *f ) = 0; + virtual void WriteToDemoFile( class idDemoFile *f ) = 0; + + virtual bool WriteToSaveGame( idFile *savefile ) const = 0; + virtual bool ReadFromSaveGame( idFile *savefile ) = 0; + virtual void SetKeyBindingNames( void ) = 0; + + virtual void SetCursor( float x, float y ) = 0; + virtual float CursorX() = 0; + virtual float CursorY() = 0; +}; + + +class idUserInterfaceManager { +public: + virtual ~idUserInterfaceManager( void ) {}; + + virtual void Init() = 0; + virtual void Shutdown() = 0; + virtual void Touch( const char *name ) = 0; + virtual void WritePrecacheCommands( idFile *f ) = 0; + + // Sets the size for 640x480 adjustment. + virtual void SetSize( float width, float height ) = 0; + + virtual void BeginLevelLoad() = 0; + virtual void EndLevelLoad() = 0; + + // Reloads changed guis, or all guis. + virtual void Reload( bool all ) = 0; + + // lists all guis + virtual void ListGuis() const = 0; + + // Returns true if gui exists. + virtual bool CheckGui( const char *qpath ) const = 0; + + // Allocates a new gui. + virtual idUserInterface * Alloc( void ) const = 0; + + // De-allocates a gui.. ONLY USE FOR PRECACHING + virtual void DeAlloc( idUserInterface *gui ) = 0; + + // Returns NULL if gui by that name does not exist. + virtual idUserInterface * FindGui( const char *qpath, bool autoLoad = false, bool needUnique = false, bool forceUnique = false ) = 0; + + // Returns NULL if gui by that name does not exist. + virtual idUserInterface * FindDemoGui( const char *qpath ) = 0; + + // Allocates a new GUI list handler + virtual idListGUI * AllocListGUI( void ) const = 0; + + // De-allocates a list gui + virtual void FreeListGUI( idListGUI *listgui ) = 0; +}; + +extern idUserInterfaceManager * uiManager; + +#endif /* !__USERINTERFACE_H__ */ diff --git a/ui/UserInterfaceLocal.h b/ui/UserInterfaceLocal.h new file mode 100644 index 000000000..6fbcc243b --- /dev/null +++ b/ui/UserInterfaceLocal.h @@ -0,0 +1,137 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +class idWindow; + +class idUserInterfaceLocal : public idUserInterface { + friend class idUserInterfaceManagerLocal; +public: + idUserInterfaceLocal(); + virtual ~idUserInterfaceLocal(); + + virtual const char * Name() const; + virtual const char * Comment() const; + virtual bool IsInteractive() const; + virtual bool InitFromFile( const char *qpath, bool rebuild = true, bool cache = true ); + virtual const char * HandleEvent( const sysEvent_t *event, int time, bool *updateVisuals ); + virtual void HandleNamedEvent( const char* namedEvent ); + virtual void Redraw( int time ); + virtual void DrawCursor(); + virtual const idDict & State() const; + virtual void DeleteStateVar( const char *varName ); + virtual void SetStateString( const char *varName, const char *value ); + virtual void SetStateBool( const char *varName, const bool value ); + virtual void SetStateInt( const char *varName, const int value ); + virtual void SetStateFloat( const char *varName, const float value ); + + // Gets a gui state variable + virtual const char* GetStateString( const char *varName, const char* defaultString = "" ) const; + virtual bool GetStateBool( const char *varName, const char* defaultString = "0" ) const; + virtual int GetStateInt( const char *varName, const char* defaultString = "0" ) const; + virtual float GetStateFloat( const char *varName, const char* defaultString = "0" ) const; + + virtual void StateChanged( int time, bool redraw ); + virtual const char * Activate( bool activate, int time ); + virtual void Trigger( int time ); + virtual void ReadFromDemoFile( class idDemoFile *f ); + virtual void WriteToDemoFile( class idDemoFile *f ); + virtual bool WriteToSaveGame( idFile *savefile ) const; + virtual bool ReadFromSaveGame( idFile *savefile ); + virtual void SetKeyBindingNames( void ); + virtual bool IsUniqued() const { return uniqued; }; + virtual void SetUniqued( bool b ) { uniqued = b; }; + virtual void SetCursor( float x, float y ); + + virtual float CursorX() { return cursorX; } + virtual float CursorY() { return cursorY; } + + size_t Size(); + + idDict * GetStateDict() { return &state; } + + const char * GetSourceFile( void ) const { return source; } + ID_TIME_T GetTimeStamp( void ) const { return timeStamp; } + + idWindow * GetDesktop() const { return desktop; } + void SetBindHandler( idWindow *win ) { bindHandler = win; } + bool Active() const { return active; } + int GetTime() const { return time; } + void SetTime( int _time ) { time = _time; } + + void ClearRefs() { refs = 0; } + void AddRef() { refs++; } + int GetRefs() { return refs; } + + void RecurseSetKeyBindingNames( idWindow *window ); + idStr &GetPendingCmd() { return pendingCmd; }; + idStr &GetReturnCmd() { return returnCmd; }; + +private: + bool active; + bool loading; + bool interactive; + bool uniqued; + + idDict state; + idWindow * desktop; + idWindow * bindHandler; + + idStr source; + idStr activateStr; + idStr pendingCmd; + idStr returnCmd; + ID_TIME_T timeStamp; + + float cursorX; + float cursorY; + + int time; + + int refs; +}; + +class idUserInterfaceManagerLocal : public idUserInterfaceManager { + friend class idUserInterfaceLocal; + +public: + virtual void Init(); + virtual void Shutdown(); + virtual void Touch( const char *name ); + virtual void WritePrecacheCommands( idFile *f ); + virtual void SetSize( float width, float height ); + virtual void BeginLevelLoad(); + virtual void EndLevelLoad(); + virtual void Reload( bool all ); + virtual void ListGuis() const; + virtual bool CheckGui( const char *qpath ) const; + virtual idUserInterface * Alloc( void ) const; + virtual void DeAlloc( idUserInterface *gui ); + virtual idUserInterface * FindGui( const char *qpath, bool autoLoad = false, bool needInteractive = false, bool forceUnique = false ); + virtual idUserInterface * FindDemoGui( const char *qpath ); + virtual idListGUI * AllocListGUI( void ) const; + virtual void FreeListGUI( idListGUI *listgui ); + +private: + idRectangle screenRect; + idDeviceContext dc; + + idList guis; + idList demoGuis; + +}; diff --git a/ui/Window.cpp b/ui/Window.cpp new file mode 100644 index 000000000..77d1ae88b --- /dev/null +++ b/ui/Window.cpp @@ -0,0 +1,4221 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "DeviceContext.h" +#include "Window.h" +#include "UserInterfaceLocal.h" +#include "EditWindow.h" +#include "ChoiceWindow.h" +#include "SliderWindow.h" +#include "BindWindow.h" +#include "ListWindow.h" +#include "RenderWindow.h" +#include "MarkerWindow.h" +#include "FieldWindow.h" + +#include "GameSSDWindow.h" +#include "GameBearShootWindow.h" +#include "GameBustOutWindow.h" + +// +// gui editor is more integrated into the window now +#include "../tools/guied/GEWindowWrapper.h" + +bool idWindow::registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing +//float idWindow::shaderRegisters[MAX_EXPRESSION_REGISTERS]; +//wexpOp_t idWindow::shaderOps[MAX_EXPRESSION_OPS]; + +idCVar idWindow::gui_debug( "gui_debug", "0", CVAR_GUI | CVAR_BOOL, "" ); +idCVar idWindow::gui_edit( "gui_edit", "0", CVAR_GUI | CVAR_BOOL, "" ); + +extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces + +// made RegisterVars a member of idWindow +const idRegEntry idWindow::RegisterVars[] = { + { "forecolor", idRegister::VEC4 }, + { "hovercolor", idRegister::VEC4 }, + { "backcolor", idRegister::VEC4 }, + { "bordercolor", idRegister::VEC4 }, + { "rect", idRegister::RECTANGLE }, + { "matcolor", idRegister::VEC4 }, + { "scale", idRegister::VEC2 }, + { "translate", idRegister::VEC2 }, + { "rotate", idRegister::FLOAT }, + { "textscale", idRegister::FLOAT }, + { "visible", idRegister::BOOL }, + { "noevents", idRegister::BOOL }, + { "text", idRegister::STRING }, + { "background", idRegister::STRING }, + { "runscript", idRegister::STRING }, + { "varbackground", idRegister::STRING }, + { "cvar", idRegister::STRING }, + { "choices", idRegister::STRING }, + { "choiceVar", idRegister::STRING }, + { "bind", idRegister::STRING }, + { "modelRotate", idRegister::VEC4 }, + { "modelOrigin", idRegister::VEC4 }, + { "lightOrigin", idRegister::VEC4 }, + { "lightColor", idRegister::VEC4 }, + { "viewOffset", idRegister::VEC4 }, + { "hideCursor", idRegister::BOOL} +}; + +const int idWindow::NumRegisterVars = sizeof(RegisterVars) / sizeof(idRegEntry); + +const char *idWindow::ScriptNames[] = { + "onMouseEnter", + "onMouseExit", + "onAction", + "onActivate", + "onDeactivate", + "onESC", + "onEvent", + "onTrigger", + "onActionRelease", + "onEnter", + "onEnterRelease" +}; + +/* +================ +idWindow::CommonInit +================ +*/ +void idWindow::CommonInit() { + childID = 0; + flags = 0; + lastTimeRun = 0; + origin.Zero(); + fontNum = 0; + timeLine = -1; + xOffset = yOffset = 0.0; + cursor = 0; + forceAspectWidth = 640; + forceAspectHeight = 480; + matScalex = 1; + matScaley = 1; + borderSize = 0; + noTime = false; + visible = true; + textAlign = 0; + textAlignx = 0; + textAligny = 0; + noEvents = false; + rotate = 0; + shear.Zero(); + textScale = 0.35f; + backColor.Zero(); + foreColor = idVec4(1, 1, 1, 1); + hoverColor = idVec4(1, 1, 1, 1); + matColor = idVec4(1, 1, 1, 1); + borderColor.Zero(); + background = NULL; + backGroundName = ""; + focusedChild = NULL; + captureChild = NULL; + overChild = NULL; + parent = NULL; + saveOps = NULL; + saveRegs = NULL; + timeLine = -1; + textShadow = 0; + hover = false; + + for (int i = 0; i < SCRIPT_COUNT; i++) { + scripts[i] = NULL; + } + + hideCursor = false; +} + +/* +================ +idWindow::Size +================ +*/ +size_t idWindow::Size() { + int c = children.Num(); + int sz = 0; + for (int i = 0; i < c; i++) { + sz += children[i]->Size(); + } + sz += sizeof(*this) + Allocated(); + return sz; +} + +/* +================ +idWindow::Allocated +================ +*/ +size_t idWindow::Allocated() { + int i, c; + int sz = name.Allocated(); + sz += text.Size(); + sz += backGroundName.Size(); + + c = definedVars.Num(); + for (i = 0; i < c; i++) { + sz += definedVars[i]->Size(); + } + + for (i = 0; i < SCRIPT_COUNT; i++) { + if (scripts[i]) { + sz += scripts[i]->Size(); + } + } + c = timeLineEvents.Num(); + for (i = 0; i < c; i++) { + sz += timeLineEvents[i]->Size(); + } + + c = namedEvents.Num(); + for (i = 0; i < c; i++) { + sz += namedEvents[i]->Size(); + } + + c = drawWindows.Num(); + for (i = 0; i < c; i++) { + if (drawWindows[i].simp) { + sz += drawWindows[i].simp->Size(); + } + } + + return sz; +} + +/* +================ +idWindow::idWindow +================ +*/ +idWindow::idWindow(idUserInterfaceLocal *ui) { + dc = NULL; + gui = ui; + CommonInit(); +} + +/* +================ +idWindow::idWindow +================ +*/ +idWindow::idWindow(idDeviceContext *d, idUserInterfaceLocal *ui) { + dc = d; + gui = ui; + CommonInit(); +} + +/* +================ +idWindow::CleanUp +================ +*/ +void idWindow::CleanUp() { + int i, c = drawWindows.Num(); + for (i = 0; i < c; i++) { + delete drawWindows[i].simp; + } + + // ensure the register list gets cleaned up + regList.Reset ( ); + + // Cleanup the named events + namedEvents.DeleteContents(true); + + drawWindows.Clear(); + children.DeleteContents(true); + definedVars.DeleteContents(true); + timeLineEvents.DeleteContents(true); + for (i = 0; i < SCRIPT_COUNT; i++) { + delete scripts[i]; + } + CommonInit(); +} + +/* +================ +idWindow::~idWindow +================ +*/ +idWindow::~idWindow() { + CleanUp(); +} + +/* +================ +idWindow::Move +================ +*/ +void idWindow::Move(float x, float y) { + idRectangle rct = rect; + rct.x = x; + rct.y = y; + idRegister *reg = RegList()->FindReg("rect"); + if (reg) { + reg->Enable(false); + } + rect = rct; +} + +/* +================ +idWindow::SetFont +================ +*/ +void idWindow::SetFont() { + dc->SetFont(fontNum); +} + +/* +================ +idWindow::GetMaxCharHeight +================ +*/ +float idWindow::GetMaxCharHeight() { + SetFont(); + return dc->MaxCharHeight(textScale); +} + +/* +================ +idWindow::GetMaxCharWidth +================ +*/ +float idWindow::GetMaxCharWidth() { + SetFont(); + return dc->MaxCharWidth(textScale); +} + +/* +================ +idWindow::Draw +================ +*/ +void idWindow::Draw( int time, float x, float y ) { + if ( text.Length() == 0 ) { + return; + } + if ( textShadow ) { + idStr shadowText = text; + idRectangle shadowRect = textRect; + + shadowText.RemoveColors(); + shadowRect.x += textShadow; + shadowRect.y += textShadow; + + dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, !( flags & WIN_NOWRAP ), -1 ); + } + dc->DrawText( text, textScale, textAlign, foreColor, textRect, !( flags & WIN_NOWRAP ), -1 ); + + if ( gui_edit.GetBool() ) { + dc->EnableClipping( false ); + dc->DrawText( va( "x: %i y: %i", ( int )rect.x(), ( int )rect.y() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x(), rect.y() - 15, 100, 20 ), false ); + dc->DrawText( va( "w: %i h: %i", ( int )rect.w(), ( int )rect.h() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x() + rect.w(), rect.w() + rect.h() + 5, 100, 20 ), false ); + dc->EnableClipping( true ); + } + +} + +/* +================ +idWindow::BringToTop +================ +*/ +void idWindow::BringToTop(idWindow *w) { + + if (w && !(w->flags & WIN_MODAL)) { + return; + } + + int c = children.Num(); + for (int i = 0; i < c; i++) { + if (children[i] == w) { + // this is it move from i - 1 to 0 to i to 1 then shove this one into 0 + for (int j = i+1; j < c; j++) { + children[j-1] = children[j]; + } + children[c-1] = w; + break; + } + } +} + +/* +================ +idWindow::Size +================ +*/ +void idWindow::Size(float x, float y, float w, float h) { + idRectangle rct = rect; + rct.x = x; + rct.y = y; + rct.w = w; + rct.h = h; + rect = rct; + CalcClientRect(0,0); +} + +/* +================ +idWindow::MouseEnter +================ +*/ +void idWindow::MouseEnter() { + + if (noEvents) { + return; + } + + RunScript(ON_MOUSEENTER); +} + +/* +================ +idWindow::MouseExit +================ +*/ +void idWindow::MouseExit() { + + if (noEvents) { + return; + } + + RunScript(ON_MOUSEEXIT); +} + + +/* +================ +idWindow::RouteMouseCoords +================ +*/ +const char *idWindow::RouteMouseCoords(float xd, float yd) { + idStr str; + if (GetCaptureChild()) { + //FIXME: unkludge this whole mechanism + return GetCaptureChild()->RouteMouseCoords(xd, yd); + } + + if (xd == -2000 || yd == -2000) { + return ""; + } + + int c = children.Num(); + while (c > 0) { + idWindow *child = children[--c]; + if (child->visible && !child->noEvents && child->Contains(child->drawRect, gui->CursorX(), gui->CursorY())) { + + dc->SetCursor(child->cursor); + child->hover = true; + + if (overChild != child) { + if (overChild) { + overChild->MouseExit(); + str = overChild->cmd; + if (str.Length()) { + gui->GetDesktop()->AddCommand(str); + overChild->cmd = ""; + } + } + overChild = child; + overChild->MouseEnter(); + str = overChild->cmd; + if (str.Length()) { + gui->GetDesktop()->AddCommand(str); + overChild->cmd = ""; + } + } else { + if (!(child->flags & WIN_HOLDCAPTURE)) { + child->RouteMouseCoords(xd, yd); + } + } + return ""; + } + } + if (overChild) { + overChild->MouseExit(); + str = overChild->cmd; + if (str.Length()) { + gui->GetDesktop()->AddCommand(str); + overChild->cmd = ""; + } + overChild = NULL; + } + return ""; +} + +/* +================ +idWindow::Activate +================ +*/ +void idWindow::Activate( bool activate, idStr &act ) { + + int n = (activate) ? ON_ACTIVATE : ON_DEACTIVATE; + + // make sure win vars are updated before activation + UpdateWinVars ( ); + + RunScript(n); + int c = children.Num(); + for (int i = 0; i < c; i++) { + children[i]->Activate( activate, act ); + } + + if ( act.Length() ) { + act += " ; "; + } +} + +/* +================ +idWindow::Trigger +================ +*/ +void idWindow::Trigger() { + RunScript( ON_TRIGGER ); + int c = children.Num(); + for ( int i = 0; i < c; i++ ) { + children[i]->Trigger(); + } + StateChanged( true ); +} + +/* +================ +idWindow::StateChanged +================ +*/ +void idWindow::StateChanged( bool redraw ) { + + UpdateWinVars(); + + if (expressionRegisters.Num() && ops.Num()) { + EvalRegs(); + } + + int c = drawWindows.Num(); + for ( int i = 0; i < c; i++ ) { + if ( drawWindows[i].win ) { + drawWindows[i].win->StateChanged( redraw ); + } else { + drawWindows[i].simp->StateChanged( redraw ); + } + } + + if ( redraw ) { + if ( flags & WIN_DESKTOP ) { + Redraw( 0.0f, 0.0f ); + } + if ( background && background->CinematicLength() ) { + background->UpdateCinematic( gui->GetTime() ); + } + } +} + +/* +================ +idWindow::SetCapture +================ +*/ +idWindow *idWindow::SetCapture(idWindow *w) { + // only one child can have the focus + + idWindow *last = NULL; + int c = children.Num(); + for (int i = 0; i < c; i++) { + if ( children[i]->flags & WIN_CAPTURE ) { + last = children[i]; + //last->flags &= ~WIN_CAPTURE; + last->LoseCapture(); + break; + } + } + + w->flags |= WIN_CAPTURE; + w->GainCapture(); + gui->GetDesktop()->captureChild = w; + return last; +} + +/* +================ +idWindow::AddUpdateVar +================ +*/ +void idWindow::AddUpdateVar(idWinVar *var) { + updateVars.AddUnique(var); +} + +/* +================ +idWindow::UpdateWinVars +================ +*/ +void idWindow::UpdateWinVars() { + int c = updateVars.Num(); + for (int i = 0; i < c; i++) { + updateVars[i]->Update(); + } +} + +/* +================ +idWindow::RunTimeEvents +================ +*/ +bool idWindow::RunTimeEvents(int time) { + + if ( time - lastTimeRun < USERCMD_MSEC ) { + //common->Printf("Skipping gui time events at %i\n", time); + return false; + } + + lastTimeRun = time; + + UpdateWinVars(); + + if (expressionRegisters.Num() && ops.Num()) { + EvalRegs(); + } + + if ( flags & WIN_INTRANSITION ) { + Transition(); + } + + Time(); + + // renamed ON_EVENT to ON_FRAME + RunScript(ON_FRAME); + + int c = children.Num(); + for (int i = 0; i < c; i++) { + children[i]->RunTimeEvents(time); + } + + return true; +} + +/* +================ +idWindow::RunNamedEvent +================ +*/ +void idWindow::RunNamedEvent ( const char* eventName ) +{ + int i; + int c; + + // Find and run the event + c = namedEvents.Num( ); + for ( i = 0; i < c; i ++ ) { + if ( namedEvents[i]->mName.Icmp( eventName ) ) { + continue; + } + + UpdateWinVars(); + + // Make sure we got all the current values for stuff + if (expressionRegisters.Num() && ops.Num()) { + EvalRegs(-1, true); + } + + RunScriptList( namedEvents[i]->mEvent ); + + break; + } + + // Run the event in all the children as well + c = children.Num(); + for ( i = 0; i < c; i++ ) { + children[i]->RunNamedEvent ( eventName ); + } +} + +/* +================ +idWindow::Contains +================ +*/ +bool idWindow::Contains(const idRectangle &sr, float x, float y) { + idRectangle r = sr; + r.x += actualX - drawRect.x; + r.y += actualY - drawRect.y; + return r.Contains(x, y); +} + +/* +================ +idWindow::Contains +================ +*/ +bool idWindow::Contains(float x, float y) { + idRectangle r = drawRect; + r.x = actualX; + r.y = actualY; + return r.Contains(x, y); +} + +/* +================ +idWindow::AddCommand +================ +*/ +void idWindow::AddCommand(const char *_cmd) { + idStr str = cmd; + if (str.Length()) { + str += " ; "; + str += _cmd; + } else { + str = _cmd; + } + cmd = str; +} + +/* +================ +idWindow::HandleEvent +================ +*/ +const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { + static bool actionDownRun; + static bool actionUpRun; + + cmd = ""; + + if ( flags & WIN_DESKTOP ) { + actionDownRun = false; + actionUpRun = false; + if (expressionRegisters.Num() && ops.Num()) { + EvalRegs(); + } + RunTimeEvents(gui->GetTime()); + CalcRects(0,0); + dc->SetCursor( idDeviceContext::CURSOR_ARROW ); + } + + if (visible && !noEvents) { + + if (event->evType == SE_KEY) { + EvalRegs(-1, true); + if (updateVisuals) { + *updateVisuals = true; + } + + if (event->evValue == K_MOUSE1) { + + if (!event->evValue2 && GetCaptureChild()) { + GetCaptureChild()->LoseCapture(); + gui->GetDesktop()->captureChild = NULL; + return ""; + } + + int c = children.Num(); + while (--c >= 0) { + if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) { + idWindow *child = children[c]; + if (event->evValue2) { + BringToTop(child); + SetFocus(child); + if (child->flags & WIN_HOLDCAPTURE) { + SetCapture(child); + } + } + if (child->Contains(child->clientRect, gui->CursorX(), gui->CursorY())) { + //if ((gui_edit.GetBool() && (child->flags & WIN_SELECTED)) || (!gui_edit.GetBool() && (child->flags & WIN_MOVABLE))) { + // SetCapture(child); + //} + SetFocus(child); + const char *childRet = child->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + if (child->flags & WIN_MODAL) { + return ""; + } + } else { + if (event->evValue2) { + SetFocus(child); + bool capture = true; + if (capture && ((child->flags & WIN_MOVABLE) || gui_edit.GetBool())) { + SetCapture(child); + } + return ""; + } else { + } + } + } + } + if (event->evValue2 && !actionDownRun) { + actionDownRun = RunScript( ON_ACTION ); + } else if (!actionUpRun) { + actionUpRun = RunScript( ON_ACTIONRELEASE ); + } + } else if (event->evValue == K_MOUSE2) { + + if (!event->evValue2 && GetCaptureChild()) { + GetCaptureChild()->LoseCapture(); + gui->GetDesktop()->captureChild = NULL; + return ""; + } + + int c = children.Num(); + while (--c >= 0) { + if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) { + idWindow *child = children[c]; + if (event->evValue2) { + BringToTop(child); + SetFocus(child); + } + if (child->Contains(child->clientRect,gui->CursorX(), gui->CursorY()) || GetCaptureChild() == child) { + if ((gui_edit.GetBool() && (child->flags & WIN_SELECTED)) || (!gui_edit.GetBool() && (child->flags & WIN_MOVABLE))) { + SetCapture(child); + } + const char *childRet = child->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + if (child->flags & WIN_MODAL) { + return ""; + } + } + } + } + } else if (event->evValue == K_MOUSE3) { + if (gui_edit.GetBool()) { + int c = children.Num(); + for (int i = 0; i < c; i++) { + if (children[i]->drawRect.Contains(gui->CursorX(), gui->CursorY())) { + if (event->evValue2) { + children[i]->flags ^= WIN_SELECTED; + if (children[i]->flags & WIN_SELECTED) { + flags &= ~WIN_SELECTED; + return "childsel"; + } + } + } + } + } + } else if (event->evValue == K_TAB && event->evValue2) { + if (GetFocusedChild()) { + const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + + // If the window didn't handle the tab, then move the focus to the next window + // or the previous window if shift is held down + + int direction = 1; + if ( idKeyInput::IsDown( K_SHIFT ) ) { + direction = -1; + } + + idWindow *currentFocus = GetFocusedChild(); + idWindow *child = GetFocusedChild(); + idWindow *parent = child->GetParent(); + while ( parent ) { + bool foundFocus = false; + bool recurse = false; + int index = 0; + if ( child ) { + index = parent->GetChildIndex( child ) + direction; + } else if ( direction < 0 ) { + index = parent->GetChildCount() - 1; + } + while ( index < parent->GetChildCount() && index >= 0) { + idWindow *testWindow = parent->GetChild( index ); + if ( testWindow == currentFocus ) { + // we managed to wrap around and get back to our starting window + foundFocus = true; + break; + } + if ( testWindow && !testWindow->noEvents && testWindow->visible ) { + if ( testWindow->flags & WIN_CANFOCUS ) { + SetFocus( testWindow ); + foundFocus = true; + break; + } else if ( testWindow->GetChildCount() > 0 ) { + parent = testWindow; + child = NULL; + recurse = true; + break; + } + } + index += direction; + } + if ( foundFocus ) { + // We found a child to focus on + break; + } else if ( recurse ) { + // We found a child with children + continue; + } else { + // We didn't find anything, so go back up to our parent + child = parent; + parent = child->GetParent(); + if ( parent == gui->GetDesktop() ) { + // We got back to the desktop, so wrap around but don't actually go to the desktop + parent = NULL; + child = NULL; + } + } + } + } + } else if (event->evValue == K_ESCAPE && event->evValue2) { + if (GetFocusedChild()) { + const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + } + RunScript( ON_ESC ); + } else if (event->evValue == K_ENTER ) { + if (GetFocusedChild()) { + const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + } + if ( flags & WIN_WANTENTER ) { + if ( event->evValue2 ) { + RunScript( ON_ACTION ); + } else { + RunScript( ON_ACTIONRELEASE ); + } + } + } else { + if (GetFocusedChild()) { + const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + } + } + + } else if (event->evType == SE_MOUSE) { + if (updateVisuals) { + *updateVisuals = true; + } + const char *mouseRet = RouteMouseCoords(event->evValue, event->evValue2); + if (mouseRet && *mouseRet) { + return mouseRet; + } + } else if (event->evType == SE_NONE) { + } else if (event->evType == SE_CHAR) { + if (GetFocusedChild()) { + const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + } + } + } + + gui->GetReturnCmd() = cmd; + if ( gui->GetPendingCmd().Length() ) { + gui->GetReturnCmd() += " ; "; + gui->GetReturnCmd() += gui->GetPendingCmd(); + gui->GetPendingCmd().Clear(); + } + cmd = ""; + return gui->GetReturnCmd(); +} + +/* +================ +idWindow::DebugDraw +================ +*/ +void idWindow::DebugDraw(int time, float x, float y) { + static char buff[16384]; + if (dc) { + dc->EnableClipping(false); + if (gui_debug.GetInteger() == 1) { + dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, 1, idDeviceContext::colorRed); + } else if (gui_debug.GetInteger() == 2) { + char out[1024]; + idStr str; + str = text.c_str(); + + if (str.Length()) { + sprintf(buff, "%s\n", str.c_str()); + } + + sprintf(out, "Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", rect.x(), rect.y(), rect.w(), rect.h()); + strcat(buff, out); + sprintf(out, "Draw Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", drawRect.x, drawRect.y, drawRect.w, drawRect.h); + strcat(buff, out); + sprintf(out, "Client Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", clientRect.x, clientRect.y, clientRect.w, clientRect.h); + strcat(buff, out); + sprintf(out, "Cursor: %0.1f : %0.1f\n", gui->CursorX(), gui->CursorY()); + strcat(buff, out); + + + //idRectangle tempRect = textRect; + //tempRect.x += offsetX; + //drawRect.y += offsetY; + dc->DrawText(buff, textScale, textAlign, foreColor, textRect, true); + } + dc->EnableClipping(true); + } +} + +/* +================ +idWindow::Transition +================ +*/ +void idWindow::Transition() { + int i, c = transitions.Num(); + bool clear = true; + + for ( i = 0; i < c; i++ ) { + idTransitionData *data = &transitions[i]; + idWinRectangle *r = NULL; + idWinVec4 *v4 = dynamic_cast(data->data); + idWinFloat* val = NULL; + if (v4 == NULL) { + r = dynamic_cast(data->data); + if ( !r ) { + val = dynamic_cast(data->data); + } + } + if ( data->interp.IsDone( gui->GetTime() ) && data->data) { + if (v4) { + *v4 = data->interp.GetEndValue(); + } else if ( val ) { + *val = data->interp.GetEndValue()[0]; + } else { + *r = data->interp.GetEndValue(); + } + } else { + clear = false; + if (data->data) { + if (v4) { + *v4 = data->interp.GetCurrentValue( gui->GetTime() ); + } else if ( val ) { + *val = data->interp.GetCurrentValue( gui->GetTime() )[0]; + } else { + *r = data->interp.GetCurrentValue( gui->GetTime() ); + } + } else { + common->Warning("Invalid transitional data for window %s in gui %s", GetName(), gui->GetSourceFile()); + } + } + } + + if ( clear ) { + transitions.SetNum( 0, false ); + flags &= ~WIN_INTRANSITION; + } +} + +/* +================ +idWindow::Time +================ +*/ +void idWindow::Time() { + + if ( noTime ) { + return; + } + + if ( timeLine == -1 ) { + timeLine = gui->GetTime(); + } + + cmd = ""; + + int c = timeLineEvents.Num(); + if ( c > 0 ) { + for (int i = 0; i < c; i++) { + if ( timeLineEvents[i]->pending && gui->GetTime() - timeLine >= timeLineEvents[i]->time ) { + timeLineEvents[i]->pending = false; + RunScriptList( timeLineEvents[i]->event ); + } + } + } + if ( gui->Active() ) { + gui->GetPendingCmd() += cmd; + } +} + +/* +================ +idWindow::EvalRegs +================ +*/ +float idWindow::EvalRegs(int test, bool force) { + static float regs[MAX_EXPRESSION_REGISTERS]; + static idWindow *lastEval = NULL; + + if (!force && test >= 0 && test < MAX_EXPRESSION_REGISTERS && lastEval == this) { + return regs[test]; + } + + lastEval = this; + + if (expressionRegisters.Num()) { + regList.SetToRegs(regs); + EvaluateRegisters(regs); + regList.GetFromRegs(regs); + } + + if (test >= 0 && test < MAX_EXPRESSION_REGISTERS) { + return regs[test]; + } + + return 0.0; +} + +/* +================ +idWindow::DrawBackground +================ +*/ +void idWindow::DrawBackground(const idRectangle &drawRect) { + if ( backColor.w() ) { + dc->DrawFilledRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, backColor); + } + + if ( background && matColor.w() ) { + float scalex, scaley; + if ( flags & WIN_NATURALMAT ) { + scalex = drawRect.w / background->GetImageWidth(); + scaley = drawRect.h / background->GetImageHeight(); + } else { + scalex = matScalex; + scaley = matScaley; + } + dc->DrawMaterial(drawRect.x, drawRect.y, drawRect.w, drawRect.h, background, matColor, scalex, scaley); + } +} + +/* +================ +idWindow::DrawBorderAndCaption +================ +*/ +void idWindow::DrawBorderAndCaption(const idRectangle &drawRect) { + if ( flags & WIN_BORDER && borderSize && borderColor.w() ) { + dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, borderSize, borderColor); + } +} + +/* +================ +idWindow::SetupTransforms +================ +*/ +void idWindow::SetupTransforms(float x, float y) { + static idMat3 trans; + static idVec3 org; + + trans.Identity(); + org.Set( origin.x + x, origin.y + y, 0 ); + + if ( rotate ) { + static idRotation rot; + static idVec3 vec(0, 0, 1); + rot.Set( org, vec, rotate ); + trans = rot.ToMat3(); + } + + if ( shear.x || shear.y ) { + static idMat3 smat; + smat.Identity(); + smat[0][1] = shear.x; + smat[1][0] = shear.y; + trans *= smat; + } + + if ( !trans.IsIdentity() ) { + dc->SetTransformInfo( org, trans ); + } +} + +/* +================ +idWindow::CalcRects +================ +*/ +void idWindow::CalcRects(float x, float y) { + CalcClientRect(0, 0); + drawRect.Offset(x, y); + clientRect.Offset(x, y); + actualX = drawRect.x; + actualY = drawRect.y; + int c = drawWindows.Num(); + for (int i = 0; i < c; i++) { + if (drawWindows[i].win) { + drawWindows[i].win->CalcRects(clientRect.x + xOffset, clientRect.y + yOffset); + } + } + drawRect.Offset(-x, -y); + clientRect.Offset(-x, -y); +} + +/* +================ +idWindow::Redraw +================ +*/ +void idWindow::Redraw(float x, float y) { + idStr str; + + if (r_skipGuiShaders.GetInteger() == 1 || dc == NULL ) { + return; + } + + int time = gui->GetTime(); + + if ( flags & WIN_DESKTOP && r_skipGuiShaders.GetInteger() != 3 ) { + RunTimeEvents( time ); + } + + if ( r_skipGuiShaders.GetInteger() == 2 ) { + return; + } + + if ( flags & WIN_SHOWTIME ) { + dc->DrawText(va(" %0.1f seconds\n%s", (float)(time - timeLine) / 1000, gui->State().GetString("name")), 0.35f, 0, dc->colorWhite, idRectangle(100, 0, 80, 80), false); + } + + if ( flags & WIN_SHOWCOORDS ) { + dc->EnableClipping(false); + sprintf(str, "x: %i y: %i cursorx: %i cursory: %i", (int)rect.x(), (int)rect.y(), (int)gui->CursorX(), (int)gui->CursorY()); + dc->DrawText(str, 0.25f, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false); + dc->EnableClipping(true); + } + + if (!visible) { + return; + } + + CalcClientRect(0, 0); + + SetFont(); + //if (flags & WIN_DESKTOP) { + // see if this window forces a new aspect ratio + dc->SetSize(forceAspectWidth, forceAspectHeight); + //} + + //FIXME: go to screen coord tracking + drawRect.Offset(x, y); + clientRect.Offset(x, y); + textRect.Offset(x, y); + actualX = drawRect.x; + actualY = drawRect.y; + + idVec3 oldOrg; + idMat3 oldTrans; + + dc->GetTransformInfo( oldOrg, oldTrans ); + + SetupTransforms(x, y); + DrawBackground(drawRect); + DrawBorderAndCaption(drawRect); + + if ( !( flags & WIN_NOCLIP) ) { + dc->PushClipRect(clientRect); + } + + if ( r_skipGuiShaders.GetInteger() < 5 ) { + Draw(time, x, y); + } + + if ( gui_debug.GetInteger() ) { + DebugDraw(time, x, y); + } + + int c = drawWindows.Num(); + for ( int i = 0; i < c; i++ ) { + if ( drawWindows[i].win ) { + drawWindows[i].win->Redraw( clientRect.x + xOffset, clientRect.y + yOffset ); + } else { + drawWindows[i].simp->Redraw( clientRect.x + xOffset, clientRect.y + yOffset ); + } + } + + // Put transforms back to what they were before the children were processed + dc->SetTransformInfo(oldOrg, oldTrans); + + if ( ! ( flags & WIN_NOCLIP ) ) { + dc->PopClipRect(); + } + + if (gui_edit.GetBool() || (flags & WIN_DESKTOP && !( flags & WIN_NOCURSOR ) && !hideCursor && (gui->Active() || ( flags & WIN_MENUGUI ) ))) { + dc->SetTransformInfo(vec3_origin, mat3_identity); + gui->DrawCursor(); + } + + if (gui_debug.GetInteger() && flags & WIN_DESKTOP) { + dc->EnableClipping(false); + sprintf(str, "x: %1.f y: %1.f", gui->CursorX(), gui->CursorY()); + dc->DrawText(str, 0.25, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false); + dc->DrawText(gui->GetSourceFile(), 0.25, 0, dc->colorWhite, idRectangle(0, 20, 300, 20), false); + dc->EnableClipping(true); + } + + drawRect.Offset(-x, -y); + clientRect.Offset(-x, -y); + textRect.Offset(-x, -y); +} + +/* +================ +idWindow::SetDC +================ +*/ +void idWindow::SetDC(idDeviceContext *d) { + dc = d; + //if (flags & WIN_DESKTOP) { + dc->SetSize(forceAspectWidth, forceAspectHeight); + //} + int c = children.Num(); + for (int i = 0; i < c; i++) { + children[i]->SetDC(d); + } +} + +/* +================ +idWindow::ArchiveToDictionary +================ +*/ +void idWindow::ArchiveToDictionary(idDict *dict, bool useNames) { + //FIXME: rewrite without state + int c = children.Num(); + for (int i = 0; i < c; i++) { + children[i]->ArchiveToDictionary(dict); + } +} + +/* +================ +idWindow::InitFromDictionary +================ +*/ +void idWindow::InitFromDictionary(idDict *dict, bool byName) { + //FIXME: rewrite without state + int c = children.Num(); + for (int i = 0; i < c; i++) { + children[i]->InitFromDictionary(dict); + } +} + +/* +================ +idWindow::CalcClientRect +================ +*/ +void idWindow::CalcClientRect(float xofs, float yofs) { + drawRect = rect; + + if ( flags & WIN_INVERTRECT ) { + drawRect.x = rect.x() - rect.w(); + drawRect.y = rect.y() - rect.h(); + } + + if (flags & (WIN_HCENTER | WIN_VCENTER) && parent) { + // in this case treat xofs and yofs as absolute top left coords + // and ignore the original positioning + if (flags & WIN_HCENTER) { + drawRect.x = (parent->rect.w() - rect.w()) / 2; + } else { + drawRect.y = (parent->rect.h() - rect.h()) / 2; + } + } + + drawRect.x += xofs; + drawRect.y += yofs; + + clientRect = drawRect; + if (rect.h() > 0.0 && rect.w() > 0.0) { + + if (flags & WIN_BORDER && borderSize != 0.0) { + clientRect.x += borderSize; + clientRect.y += borderSize; + clientRect.w -= borderSize; + clientRect.h -= borderSize; + } + + textRect = clientRect; + textRect.x += 2.0; + textRect.w -= 2.0; + textRect.y += 2.0; + textRect.h -= 2.0; + + textRect.x += textAlignx; + textRect.y += textAligny; + + } + origin.Set( rect.x() + (rect.w() / 2 ), rect.y() + ( rect.h() / 2 ) ); + +} + +/* +================ +idWindow::SetupBackground +================ +*/ +void idWindow::SetupBackground() { + if (backGroundName.Length()) { + background = declManager->FindMaterial(backGroundName); + background->SetImageClassifications( 1 ); // just for resource tracking + if ( background && !background->TestMaterialFlag( MF_DEFAULTED ) ) { + background->SetSort(SS_GUI ); + } + } + backGroundName.SetMaterialPtr(&background); +} + +/* +================ +idWindow::SetupFromState +================ +*/ +void idWindow::SetupFromState() { + idStr str; + background = NULL; + + SetupBackground(); + + if (borderSize) { + flags |= WIN_BORDER; + } + + if (regList.FindReg("rotate") || regList.FindReg("shear")) { + flags |= WIN_TRANSFORM; + } + + CalcClientRect(0,0); + if ( scripts[ ON_ACTION ] ) { + cursor = idDeviceContext::CURSOR_HAND; + flags |= WIN_CANFOCUS; + } +} + +/* +================ +idWindow::Moved +================ +*/ +void idWindow::Moved() { +} + +/* +================ +idWindow::Sized +================ +*/ +void idWindow::Sized() { +} + +/* +================ +idWindow::GainFocus +================ +*/ +void idWindow::GainFocus() { +} + +/* +================ +idWindow::LoseFocus +================ +*/ +void idWindow::LoseFocus() { +} + +/* +================ +idWindow::GainCapture +================ +*/ +void idWindow::GainCapture() { +} + +/* +================ +idWindow::LoseCapture +================ +*/ +void idWindow::LoseCapture() { + flags &= ~WIN_CAPTURE; +} + +/* +================ +idWindow::SetFlag +================ +*/ +void idWindow::SetFlag(unsigned int f) { + flags |= f; +} + +/* +================ +idWindow::ClearFlag +================ +*/ +void idWindow::ClearFlag(unsigned int f) { + flags &= ~f; +} + + +/* +================ +idWindow::SetParent +================ +*/ +void idWindow::SetParent(idWindow *w) { + parent = w; +} + +/* +================ +idWindow::GetCaptureChild +================ +*/ +idWindow *idWindow::GetCaptureChild() { + if (flags & WIN_DESKTOP) { + return gui->GetDesktop()->captureChild; + } + return NULL; +} + +/* +================ +idWindow::GetFocusedChild +================ +*/ +idWindow *idWindow::GetFocusedChild() { + if (flags & WIN_DESKTOP) { + return gui->GetDesktop()->focusedChild; + } + return NULL; +} + + +/* +================ +idWindow::SetFocus +================ +*/ +idWindow *idWindow::SetFocus(idWindow *w, bool scripts) { + // only one child can have the focus + idWindow *lastFocus = NULL; + if (w->flags & WIN_CANFOCUS) { + lastFocus = gui->GetDesktop()->focusedChild; + if ( lastFocus ) { + lastFocus->flags &= ~WIN_FOCUS; + lastFocus->LoseFocus(); + } + + // call on lose focus + if ( scripts && lastFocus ) { + // calling this broke all sorts of guis + // lastFocus->RunScript(ON_MOUSEEXIT); + } + // call on gain focus + if ( scripts && w ) { + // calling this broke all sorts of guis + // w->RunScript(ON_MOUSEENTER); + } + + w->flags |= WIN_FOCUS; + w->GainFocus(); + gui->GetDesktop()->focusedChild = w; + } + + return lastFocus; +} + +/* +================ +idWindow::ParseScript +================ +*/ +bool idWindow::ParseScript(idParser *src, idGuiScriptList &list, int *timeParm, bool elseBlock ) { + + bool ifElseBlock = false; + + idToken token; + + // scripts start with { ( unless parm is true ) and have ; separated command lists.. commands are command, + // arg.. basically we want everything between the { } as it will be interpreted at + // run time + + if ( elseBlock ) { + src->ReadToken ( &token ); + + if ( !token.Icmp ( "if" ) ) { + ifElseBlock = true; + } + + src->UnreadToken ( &token ); + + if ( !ifElseBlock && !src->ExpectTokenString( "{" ) ) { + return false; + } + } + else if ( !src->ExpectTokenString( "{" ) ) { + return false; + } + + int nest = 0; + + while (1) { + if ( !src->ReadToken(&token) ) { + src->Error( "Unexpected end of file" ); + return false; + } + + if ( token == "{" ) { + nest++; + } + + if ( token == "}" ) { + if (nest-- <= 0) { + return true; + } + } + + idGuiScript *gs = new idGuiScript(); + if (token.Icmp("if") == 0) { + gs->conditionReg = ParseExpression(src); + gs->ifList = new idGuiScriptList(); + ParseScript(src, *gs->ifList, NULL); + if (src->ReadToken(&token)) { + if (token == "else") { + gs->elseList = new idGuiScriptList(); + // pass true to indicate we are parsing an else condition + ParseScript(src, *gs->elseList, NULL, true ); + } else { + src->UnreadToken(&token); + } + } + + list.Append(gs); + + // if we are parsing an else if then return out so + // the initial "if" parser can handle the rest of the tokens + if ( ifElseBlock ) { + return true; + } + continue; + } else { + src->UnreadToken(&token); + } + + // empty { } is not allowed + if ( token == "{" ) { + src->Error ( "Unexpected {" ); + delete gs; + return false; + } + + gs->Parse(src); + list.Append(gs); + } + +} + +/* +================ +idWindow::SaveExpressionParseState +================ +*/ +void idWindow::SaveExpressionParseState() { + saveTemps = (bool*)Mem_Alloc(MAX_EXPRESSION_REGISTERS * sizeof(bool)); + memcpy(saveTemps, registerIsTemporary, MAX_EXPRESSION_REGISTERS * sizeof(bool)); +} + +/* +================ +idWindow::RestoreExpressionParseState +================ +*/ +void idWindow::RestoreExpressionParseState() { + memcpy(registerIsTemporary, saveTemps, MAX_EXPRESSION_REGISTERS * sizeof(bool)); + Mem_Free(saveTemps); +} + +/* +================ +idWindow::ParseScriptEntry +================ +*/ +bool idWindow::ParseScriptEntry(const char *name, idParser *src) { + for (int i = 0; i < SCRIPT_COUNT; i++) { + if (idStr::Icmp(name, ScriptNames[i]) == 0) { + delete scripts[i]; + scripts[i] = new idGuiScriptList; + return ParseScript(src, *scripts[i]); + } + } + return false; +} + +/* +================ +idWindow::DisableRegister +================ +*/ +void idWindow::DisableRegister(const char *_name) { + idRegister *reg = RegList()->FindReg(_name); + if (reg) { + reg->Enable(false); + } +} + +/* +================ +idWindow::PostParse +================ +*/ +void idWindow::PostParse() { +} + +/* +================ +idWindow::GetWinVarOffset +================ +*/ +int idWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { + int ret = -1; + + if ( wv == &rect ) { + ret = (int)&( ( idWindow * ) 0 )->rect; + } + + if ( wv == &backColor ) { + ret = (int)&( ( idWindow * ) 0 )->backColor; + } + + if ( wv == &matColor ) { + ret = (int)&( ( idWindow * ) 0 )->matColor; + } + + if ( wv == &foreColor ) { + ret = (int)&( ( idWindow * ) 0 )->foreColor; + } + + if ( wv == &hoverColor ) { + ret = (int)&( ( idWindow * ) 0 )->hoverColor; + } + + if ( wv == &borderColor ) { + ret = (int)&( ( idWindow * ) 0 )->borderColor; + } + + if ( wv == &textScale ) { + ret = (int)&( ( idWindow * ) 0 )->textScale; + } + + if ( wv == &rotate ) { + ret = (int)&( ( idWindow * ) 0 )->rotate; + } + + if ( ret != -1 ) { + owner->win = this; + return ret; + } + + for ( int i = 0; i < drawWindows.Num(); i++ ) { + if ( drawWindows[i].win ) { + ret = drawWindows[i].win->GetWinVarOffset( wv, owner ); + } else { + ret = drawWindows[i].simp->GetWinVarOffset( wv, owner ); + } + if ( ret != -1 ) { + break; + } + } + + return ret; +} + +/* +================ +idWindow::GetWinVarByName +================ +*/ +idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { + idWinVar *retVar = NULL; + + if ( owner ) { + *owner = NULL; + } + + if (idStr::Icmp(_name, "notime") == 0) { + retVar = &noTime; + } + if (idStr::Icmp(_name, "background") == 0) { + retVar = &backGroundName; + } + if (idStr::Icmp(_name, "visible") == 0) { + retVar = &visible; + } + if (idStr::Icmp(_name, "rect") == 0) { + retVar = ▭ + } + if (idStr::Icmp(_name, "backColor") == 0) { + retVar = &backColor; + } + if (idStr::Icmp(_name, "matColor") == 0) { + retVar = &matColor; + } + if (idStr::Icmp(_name, "foreColor") == 0) { + retVar = &foreColor; + } + if (idStr::Icmp(_name, "hoverColor") == 0) { + retVar = &hoverColor; + } + if (idStr::Icmp(_name, "borderColor") == 0) { + retVar = &borderColor; + } + if (idStr::Icmp(_name, "textScale") == 0) { + retVar = &textScale; + } + if (idStr::Icmp(_name, "rotate") == 0) { + retVar = &rotate; + } + if (idStr::Icmp(_name, "noEvents") == 0) { + retVar = &noEvents; + } + if (idStr::Icmp(_name, "text") == 0) { + retVar = &text; + } + if (idStr::Icmp(_name, "backGroundName") == 0) { + retVar = &backGroundName; + } + if (idStr::Icmp(_name, "hidecursor") == 0) { + retVar = &hideCursor; + } + + idStr key = _name; + bool guiVar = (key.Find(VAR_GUIPREFIX) >= 0); + int c = definedVars.Num(); + for (int i = 0; i < c; i++) { + if (idStr::Icmp(_name, (guiVar) ? va("%s",definedVars[i]->GetName()) : definedVars[i]->GetName()) == 0) { + retVar = definedVars[i]; + break; + } + } + + if (retVar) { + if (fixup && *_name != '$') { + DisableRegister(_name); + } + + if ( owner && parent ) { + *owner = parent->FindChildByName ( name ); + } + + return retVar; + } + + int len = key.Length(); + if ( len > 5 && guiVar ) { + idWinVar *var = new idWinStr; + var->Init(_name, this); + definedVars.Append(var); + return var; + } else if (fixup) { + int n = key.Find("::"); + if (n > 0) { + idStr winName = key.Left(n); + idStr var = key.Right(key.Length() - n - 2); + drawWin_t *win = GetGui()->GetDesktop()->FindChildByName(winName); + if (win) { + if (win->win) { + return win->win->GetWinVarByName(var, false, owner); + } else { + if ( owner ) { + *owner = win; + } + return win->simp->GetWinVarByName(var); + } + } + } + } + return NULL; +} + +/* +================ +idWindow::ParseString +================ +*/ +void idWindow::ParseString(idParser *src, idStr &out) { + idToken tok; + if (src->ReadToken(&tok)) { + out = tok; + } +} + +/* +================ +idWindow::ParseVec4 +================ +*/ +void idWindow::ParseVec4(idParser *src, idVec4 &out) { + idToken tok; + src->ReadToken(&tok); + out.x = atof(tok); + src->ExpectTokenString(","); + src->ReadToken(&tok); + out.y = atof(tok); + src->ExpectTokenString(","); + src->ReadToken(&tok); + out.z = atof(tok); + src->ExpectTokenString(","); + src->ReadToken(&tok); + out.w = atof(tok); +} + +/* +================ +idWindow::ParseInternalVar +================ +*/ +bool idWindow::ParseInternalVar(const char *_name, idParser *src) { + + if (idStr::Icmp(_name, "showtime") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_SHOWTIME; + } + return true; + } + if (idStr::Icmp(_name, "showcoords") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_SHOWCOORDS; + } + return true; + } + if (idStr::Icmp(_name, "forceaspectwidth") == 0) { + forceAspectWidth = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "forceaspectheight") == 0) { + forceAspectHeight = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "matscalex") == 0) { + matScalex = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "matscaley") == 0) { + matScaley = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "bordersize") == 0) { + borderSize = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "nowrap") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_NOWRAP; + } + return true; + } + if (idStr::Icmp(_name, "shadow") == 0) { + textShadow = src->ParseInt(); + return true; + } + if (idStr::Icmp(_name, "textalign") == 0) { + textAlign = src->ParseInt(); + return true; + } + if (idStr::Icmp(_name, "textalignx") == 0) { + textAlignx = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "textaligny") == 0) { + textAligny = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "shear") == 0) { + shear.x = src->ParseFloat(); + idToken tok; + src->ReadToken( &tok ); + if ( tok.Icmp( "," ) ) { + src->Error( "Expected comma in shear definiation" ); + return false; + } + shear.y = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "wantenter") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_WANTENTER; + } + return true; + } + if (idStr::Icmp(_name, "naturalmatscale") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_NATURALMAT; + } + return true; + } + if (idStr::Icmp(_name, "noclip") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_NOCLIP; + } + return true; + } + if (idStr::Icmp(_name, "nocursor") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_NOCURSOR; + } + return true; + } + if (idStr::Icmp(_name, "menugui") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_MENUGUI; + } + return true; + } + if (idStr::Icmp(_name, "modal") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_MODAL; + } + return true; + } + if (idStr::Icmp(_name, "invertrect") == 0) { + if ( src->ParseBool() ) { + flags |= WIN_INVERTRECT; + } + return true; + } + if (idStr::Icmp(_name, "name") == 0) { + ParseString(src, name); + return true; + } + if (idStr::Icmp(_name, "play") == 0) { + common->Warning( "play encountered during gui parse.. see Robert\n" ); + idStr playStr; + ParseString(src, playStr); + return true; + } + if (idStr::Icmp(_name, "comment") == 0) { + ParseString(src, comment); + return true; + } + if ( idStr::Icmp( _name, "font" ) == 0 ) { + idStr fontStr; + ParseString( src, fontStr ); + fontNum = dc->FindFont( fontStr ); + return true; + } + return false; +} + +/* +================ +idWindow::ParseRegEntry +================ +*/ +bool idWindow::ParseRegEntry(const char *name, idParser *src) { + idStr work; + work = name; + work.ToLower(); + + idWinVar *var = GetWinVarByName(work, NULL); + if ( var ) { + for (int i = 0; i < NumRegisterVars; i++) { + if (idStr::Icmp(work, RegisterVars[i].name) == 0) { + regList.AddReg(work, RegisterVars[i].type, src, this, var); + return true; + } + } + } + + // not predefined so just read the next token and add it to the state + idToken tok; + idVec4 v; + idWinInt *vari; + idWinFloat *varf; + idWinStr *vars; + if (src->ReadToken(&tok)) { + if (var) { + var->Set(tok); + return true; + } + switch (tok.type) { + case TT_NUMBER : + if (tok.subtype & TT_INTEGER) { + vari = new idWinInt(); + *vari = atoi(tok); + vari->SetName(work); + definedVars.Append(vari); + } else if (tok.subtype & TT_FLOAT) { + varf = new idWinFloat(); + *varf = atof(tok); + varf->SetName(work); + definedVars.Append(varf); + } else { + vars = new idWinStr(); + *vars = tok; + vars->SetName(work); + definedVars.Append(vars); + } + break; + default : + vars = new idWinStr(); + *vars = tok; + vars->SetName(work); + definedVars.Append(vars); + break; + } + } + + return true; +} + +/* +================ +idWindow::SetInitialState +================ +*/ +void idWindow::SetInitialState(const char *_name) { + name = _name; + matScalex = 1.0; + matScaley = 1.0; + forceAspectWidth = 640.0; + forceAspectHeight = 480.0; + noTime = false; + visible = true; + flags = 0; +} + +/* +================ +idWindow::Parse +================ +*/ +bool idWindow::Parse( idParser *src, bool rebuild) { + idToken token, token2, token3, token4, token5, token6, token7; + idStr work; + + if (rebuild) { + CleanUp(); + } + + drawWin_t dwt; + + timeLineEvents.Clear(); + transitions.Clear(); + + namedEvents.DeleteContents( true ); + + src->ExpectTokenType( TT_NAME, 0, &token ); + + SetInitialState(token); + + src->ExpectTokenString( "{" ); + src->ExpectAnyToken( &token ); + + bool ret = true; + + // attach a window wrapper to the window if the gui editor is running +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + new rvGEWindowWrapper ( this, rvGEWindowWrapper::WT_NORMAL ); + } +#endif + + while( token != "}" ) { + // track what was parsed so we can maintain it for the guieditor + src->SetMarker ( ); + + if ( token == "windowDef" || token == "animationDef" ) { + if (token == "animationDef") { + visible = false; + rect = idRectangle(0,0,0,0); + } + src->ExpectTokenType( TT_NAME, 0, &token ); + token2 = token; + src->UnreadToken(&token); + drawWin_t *dw = FindChildByName(token2.c_str()); + if (dw && dw->win) { + SaveExpressionParseState(); + dw->win->Parse(src, rebuild); + RestoreExpressionParseState(); + } else { + idWindow *win = new idWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = NULL; + if (win->IsSimple()) { + idSimpleWindow *simple = new idSimpleWindow(win); + dwt.simp = simple; + drawWindows.Append(dwt); + delete win; + } else { + AddChild(win); + SetFocus(win,false); + dwt.win = win; + drawWindows.Append(dwt); + } + } + } + else if ( token == "editDef" ) { + idEditWindow *win = new idEditWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "choiceDef" ) { + idChoiceWindow *win = new idChoiceWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "sliderDef" ) { + idSliderWindow *win = new idSliderWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "markerDef" ) { + idMarkerWindow *win = new idMarkerWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "bindDef" ) { + idBindWindow *win = new idBindWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "listDef" ) { + idListWindow *win = new idListWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "fieldDef" ) { + idFieldWindow *win = new idFieldWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "renderDef" ) { + idRenderWindow *win = new idRenderWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "gameSSDDef" ) { + idGameSSDWindow *win = new idGameSSDWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "gameBearShootDef" ) { + idGameBearShootWindow *win = new idGameBearShootWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } + else if ( token == "gameBustOutDef" ) { + idGameBustOutWindow *win = new idGameBustOutWindow(dc, gui); + SaveExpressionParseState(); + win->Parse(src, rebuild); + RestoreExpressionParseState(); + AddChild(win); + win->SetParent(this); + dwt.simp = NULL; + dwt.win = win; + drawWindows.Append(dwt); + } +// +// added new onEvent + else if ( token == "onNamedEvent" ) { + // Read the event name + if ( !src->ReadToken(&token) ) { + src->Error( "Expected event name" ); + return false; + } + + rvNamedEvent* ev = new rvNamedEvent ( token ); + + src->SetMarker ( ); + + if ( !ParseScript ( src, *ev->mEvent ) ) { + ret = false; + break; + } + + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + idStr out; + + // Grab the string from the last marker + src->GetStringFromMarker ( str, false ); + + // Parse it one more time to knock unwanted tabs out + idLexer src2( str, str.Length(), "", src->GetFlags() ); + src2.ParseBracedSectionExact ( out, 1); + + // Save the script + rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( va("onEvent %s", token.c_str()), out ); + } +#endif + namedEvents.Append(ev); + } + else if ( token == "onTime" ) { + idTimeLineEvent *ev = new idTimeLineEvent; + + if ( !src->ReadToken(&token) ) { + src->Error( "Unexpected end of file" ); + return false; + } + ev->time = atoi(token.c_str()); + + // reset the mark since we dont want it to include the time + src->SetMarker ( ); + + if (!ParseScript(src, *ev->event, &ev->time)) { + ret = false; + break; + } + + // add the script to the wrappers script list + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + idStr out; + + // Grab the string from the last marker + src->GetStringFromMarker ( str, false ); + + // Parse it one more time to knock unwanted tabs out + idLexer src2( str, str.Length(), "", src->GetFlags() ); + src2.ParseBracedSectionExact ( out, 1); + + // Save the script + rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( va("onTime %d", ev->time), out ); + } +#endif + // this is a timeline event + ev->pending = true; + timeLineEvents.Append(ev); + } + else if ( token == "definefloat" ) { + src->ReadToken(&token); + work = token; + work.ToLower(); + idWinFloat *varf = new idWinFloat(); + varf->SetName(work); + definedVars.Append(varf); + + // add the float to the editors wrapper dict + // Set the marker after the float name + src->SetMarker ( ); + + // Read in the float + regList.AddReg(work, idRegister::FLOAT, src, this, varf); + + // If we are in the gui editor then add the float to the defines +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + + // Grab the string from the last marker and save it in the wrapper + src->GetStringFromMarker ( str, true ); + rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("definefloat\t\"%s\"",token.c_str()), str ); + } +#endif + } + else if ( token == "definevec4" ) { + src->ReadToken(&token); + work = token; + work.ToLower(); + idWinVec4 *var = new idWinVec4(); + var->SetName(work); + + // set the marker so we can determine what was parsed + // set the marker after the vec4 name + src->SetMarker ( ); + + // FIXME: how about we add the var to the desktop instead of this window so it won't get deleted + // when this window is destoyed which even happens during parsing with simple windows ? + //definedVars.Append(var); + gui->GetDesktop()->definedVars.Append( var ); + gui->GetDesktop()->regList.AddReg( work, idRegister::VEC4, src, gui->GetDesktop(), var ); + + // store the original vec4 for the editor + // If we are in the gui editor then add the float to the defines +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + + // Grab the string from the last marker and save it in the wrapper + src->GetStringFromMarker ( str, true ); + rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("definevec4\t\"%s\"",token.c_str()), str ); + } +#endif + } + else if ( token == "float" ) { + src->ReadToken(&token); + work = token; + work.ToLower(); + idWinFloat *varf = new idWinFloat(); + varf->SetName(work); + definedVars.Append(varf); + + // add the float to the editors wrapper dict + // set the marker to after the float name + src->SetMarker ( ); + + // Parse the float + regList.AddReg(work, idRegister::FLOAT, src, this, varf); + + // If we are in the gui editor then add the float to the defines +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + + // Grab the string from the last marker and save it in the wrapper + src->GetStringFromMarker ( str, true ); + rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("float\t\"%s\"",token.c_str()), str ); + } +#endif + } + else if (ParseScriptEntry(token, src)) { + // add the script to the wrappers script list + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + idStr out; + + // Grab the string from the last marker + src->GetStringFromMarker ( str, false ); + + // Parse it one more time to knock unwanted tabs out + idLexer src2( str, str.Length(), "", src->GetFlags() ); + src2.ParseBracedSectionExact ( out, 1); + + // Save the script + rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( token, out ); + } +#endif + } else if (ParseInternalVar(token, src)) { + // gui editor support + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + src->GetStringFromMarker ( str ); + rvGEWindowWrapper::GetWrapper ( this )->SetStateKey ( token, str, false ); + } +#endif + } + else { + ParseRegEntry(token, src); + // hook into the main window parsing for the gui editor + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + idStr str; + src->GetStringFromMarker ( str ); + rvGEWindowWrapper::GetWrapper ( this )->SetStateKey ( token, str, false ); + } +#endif + } + if ( !src->ReadToken( &token ) ) { + src->Error( "Unexpected end of file" ); + ret = false; + break; + } + } + + if (ret) { + EvalRegs(-1, true); + } + + SetupFromState(); + PostParse(); + + // hook into the main window parsing for the gui editor + // If we are in the gui editor then add the internal var to the + // the wrapper +#ifdef ID_ALLOW_TOOLS + if ( com_editors & EDITOR_GUI ) { + rvGEWindowWrapper::GetWrapper ( this )->Finish ( ); + } +#endif + + return ret; +} + +/* +================ +idWindow::FindSimpleWinByName +================ +*/ +idSimpleWindow *idWindow::FindSimpleWinByName(const char *_name) { + int c = drawWindows.Num(); + for (int i = 0; i < c; i++) { + if (drawWindows[i].simp == NULL) { + continue; + } + if ( idStr::Icmp(drawWindows[i].simp->name, _name) == 0 ) { + return drawWindows[i].simp; + } + } + return NULL; +} + +/* +================ +idWindow::FindChildByName +================ +*/ +drawWin_t *idWindow::FindChildByName(const char *_name) { + static drawWin_t dw; + if (idStr::Icmp(name,_name) == 0) { + dw.simp = NULL; + dw.win = this; + return &dw; + } + int c = drawWindows.Num(); + for (int i = 0; i < c; i++) { + if (drawWindows[i].win) { + if (idStr::Icmp(drawWindows[i].win->name, _name) == 0) { + return &drawWindows[i]; + } + drawWin_t *win = drawWindows[i].win->FindChildByName(_name); + if (win) { + return win; + } + } else { + if (idStr::Icmp(drawWindows[i].simp->name, _name) == 0) { + return &drawWindows[i]; + } + } + } + return NULL; +} + +/* +================ +idWindow::GetStrPtrByName +================ +*/ +idStr* idWindow::GetStrPtrByName(const char *_name) { + return NULL; +} + +/* +================ +idWindow::AddTransition +================ +*/ +void idWindow::AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime) { + idTransitionData data; + data.data = dest; + data.interp.Init(gui->GetTime(), accelTime * time, decelTime * time, time, from, to); + transitions.Append(data); +} + + +/* +================ +idWindow::StartTransition +================ +*/ +void idWindow::StartTransition() { + flags |= WIN_INTRANSITION; +} + +/* +================ +idWindow::ResetCinematics +================ +*/ +void idWindow::ResetCinematics() { + if ( background ) { + background->ResetCinematicTime( gui->GetTime() ); + } +} + +/* +================ +idWindow::ResetTime +================ +*/ +void idWindow::ResetTime(int t) { + + timeLine = gui->GetTime() - t; + + int i, c = timeLineEvents.Num(); + for ( i = 0; i < c; i++ ) { + if ( timeLineEvents[i]->time >= t ) { + timeLineEvents[i]->pending = true; + } + } + + noTime = false; + + c = transitions.Num(); + for ( i = 0; i < c; i++ ) { + idTransitionData *data = &transitions[i]; + if ( data->interp.IsDone( gui->GetTime() ) && data->data ) { + transitions.RemoveIndex( i ); + i--; + c--; + } + } + +} + + +/* +================ +idWindow::RunScriptList +================ +*/ +bool idWindow::RunScriptList(idGuiScriptList *src) { + if (src == NULL) { + return false; + } + src->Execute(this); + return true; +} + +/* +================ +idWindow::RunScript +================ +*/ +bool idWindow::RunScript(int n) { + if (n >= ON_MOUSEENTER && n < SCRIPT_COUNT) { + return RunScriptList(scripts[n]); + } + return false; +} + +/* +================ +idWindow::ExpressionConstant +================ +*/ +int idWindow::ExpressionConstant(float f) { + int i; + + for ( i = WEXP_REG_NUM_PREDEFINED ; i < expressionRegisters.Num() ; i++ ) { + if ( !registerIsTemporary[i] && expressionRegisters[i] == f ) { + return i; + } + } + if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) { + common->Warning( "expressionConstant: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile() ); + return 0; + } + + int c = expressionRegisters.Num(); + if (i > c) { + while (i > c) { + expressionRegisters.Append(-9999999); + i--; + } + } + + i = expressionRegisters.Append(f); + registerIsTemporary[i] = false; + return i; +} + +/* +================ +idWindow::ExpressionTemporary +================ +*/ +int idWindow::ExpressionTemporary() { + if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) { + common->Warning( "expressionTemporary: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile()); + return 0; + } + int i = expressionRegisters.Num(); + registerIsTemporary[i] = true; + i = expressionRegisters.Append(0); + return i; +} + +/* +================ +idWindow::ExpressionOp +================ +*/ +wexpOp_t *idWindow::ExpressionOp() { + if ( ops.Num() == MAX_EXPRESSION_OPS ) { + common->Warning( "expressionOp: gui %s hit MAX_EXPRESSION_OPS", gui->GetSourceFile()); + return &ops[0]; + } + wexpOp_t wop; + memset(&wop, 0, sizeof(wexpOp_t)); + int i = ops.Append(wop); + return &ops[i]; +} + +/* +================ +idWindow::EmitOp +================ +*/ + +int idWindow::EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t **opp ) { + wexpOp_t *op; +/* + // optimize away identity operations + if ( opType == WOP_TYPE_ADD ) { + if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { + return b; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { + return a; + } + if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { + return ExpressionConstant( shaderRegisters[a] + shaderRegisters[b] ); + } + } + if ( opType == WOP_TYPE_MULTIPLY ) { + if ( !registerIsTemporary[a] && shaderRegisters[a] == 1 ) { + return b; + } + if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { + return a; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 1 ) { + return a; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { + return b; + } + if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { + return ExpressionConstant( shaderRegisters[a] * shaderRegisters[b] ); + } + } +*/ + op = ExpressionOp(); + + op->opType = opType; + op->a = a; + op->b = b; + op->c = ExpressionTemporary(); + + if (opp) { + *opp = op; + } + return op->c; +} + +/* +================ +idWindow::ParseEmitOp +================ +*/ +int idWindow::ParseEmitOp( idParser *src, int a, wexpOpType_t opType, int priority, wexpOp_t **opp ) { + int b = ParseExpressionPriority( src, priority ); + return EmitOp( a, b, opType, opp ); +} + + +/* +================ +idWindow::ParseTerm + +Returns a register index +================= +*/ +int idWindow::ParseTerm( idParser *src, idWinVar *var, int component ) { + idToken token; + int a, b; + + src->ReadToken( &token ); + + if ( token == "(" ) { + a = ParseExpression( src ); + src->ExpectTokenString(")"); + return a; + } + + if ( !token.Icmp( "time" ) ) { + return WEXP_REG_TIME; + } + + // parse negative numbers + if ( token == "-" ) { + src->ReadToken( &token ); + if ( token.type == TT_NUMBER || token == "." ) { + return ExpressionConstant( -(float) token.GetFloatValue() ); + } + src->Warning( "Bad negative number '%s'", token.c_str() ); + return 0; + } + + if ( token.type == TT_NUMBER || token == "." || token == "-" ) { + return ExpressionConstant( (float) token.GetFloatValue() ); + } + + // see if it is a table name + const idDeclTable *table = static_cast( declManager->FindType( DECL_TABLE, token.c_str(), false ) ); + if ( table ) { + a = table->Index(); + // parse a table expression + src->ExpectTokenString("["); + b = ParseExpression(src); + src->ExpectTokenString("]"); + return EmitOp( a, b, WOP_TYPE_TABLE ); + } + + if (var == NULL) { + var = GetWinVarByName(token, true); + } + if (var) { + a = (int)var; + //assert(dynamic_cast(var)); + var->Init(token, this); + b = component; + if (dynamic_cast(var)) { + if (src->ReadToken(&token)) { + if (token == "[") { + b = ParseExpression(src); + src->ExpectTokenString("]"); + } else { + src->UnreadToken(&token); + } + } + return EmitOp(a, b, WOP_TYPE_VAR); + } else if (dynamic_cast(var)) { + return EmitOp(a, b, WOP_TYPE_VARF); + } else if (dynamic_cast(var)) { + return EmitOp(a, b, WOP_TYPE_VARI); + } else if (dynamic_cast(var)) { + return EmitOp(a, b, WOP_TYPE_VARB); + } else if (dynamic_cast(var)) { + return EmitOp(a, b, WOP_TYPE_VARS); + } else { + src->Warning("Var expression not vec4, float or int '%s'", token.c_str()); + } + return 0; + } else { + // ugly but used for post parsing to fixup named vars + char *p = new char[token.Length()+1]; + strcpy(p, token); + a = (int)p; + b = -2; + return EmitOp(a, b, WOP_TYPE_VAR); + } + +} + +/* +================= +idWindow::ParseExpressionPriority + +Returns a register index +================= +*/ +#define TOP_PRIORITY 4 +int idWindow::ParseExpressionPriority( idParser *src, int priority, idWinVar *var, int component ) { + idToken token; + int a; + + if ( priority == 0 ) { + return ParseTerm( src, var, component ); + } + + a = ParseExpressionPriority( src, priority - 1, var, component ); + + if ( !src->ReadToken( &token ) ) { + // we won't get EOF in a real file, but we can + // when parsing from generated strings + return a; + } + + if ( priority == 1 && token == "*" ) { + return ParseEmitOp( src, a, WOP_TYPE_MULTIPLY, priority ); + } + if ( priority == 1 && token == "/" ) { + return ParseEmitOp( src, a, WOP_TYPE_DIVIDE, priority ); + } + if ( priority == 1 && token == "%" ) { // implied truncate both to integer + return ParseEmitOp( src, a, WOP_TYPE_MOD, priority ); + } + if ( priority == 2 && token == "+" ) { + return ParseEmitOp( src, a, WOP_TYPE_ADD, priority ); + } + if ( priority == 2 && token == "-" ) { + return ParseEmitOp( src, a, WOP_TYPE_SUBTRACT, priority ); + } + if ( priority == 3 && token == ">" ) { + return ParseEmitOp( src, a, WOP_TYPE_GT, priority ); + } + if ( priority == 3 && token == ">=" ) { + return ParseEmitOp( src, a, WOP_TYPE_GE, priority ); + } + if ( priority == 3 && token == "<" ) { + return ParseEmitOp( src, a, WOP_TYPE_LT, priority ); + } + if ( priority == 3 && token == "<=" ) { + return ParseEmitOp( src, a, WOP_TYPE_LE, priority ); + } + if ( priority == 3 && token == "==" ) { + return ParseEmitOp( src, a, WOP_TYPE_EQ, priority ); + } + if ( priority == 3 && token == "!=" ) { + return ParseEmitOp( src, a, WOP_TYPE_NE, priority ); + } + if ( priority == 4 && token == "&&" ) { + return ParseEmitOp( src, a, WOP_TYPE_AND, priority ); + } + if ( priority == 4 && token == "||" ) { + return ParseEmitOp( src, a, WOP_TYPE_OR, priority ); + } + if ( priority == 4 && token == "?" ) { + wexpOp_t *oop = NULL; + int o = ParseEmitOp( src, a, WOP_TYPE_COND, priority, &oop ); + if ( !src->ReadToken( &token ) ) { + return o; + } + if (token == ":") { + a = ParseExpressionPriority( src, priority - 1, var ); + oop->d = a; + } + return o; + } + + // assume that anything else terminates the expression + // not too robust error checking... + + src->UnreadToken( &token ); + + return a; +} + +/* +================ +idWindow::ParseExpression + +Returns a register index +================ +*/ +int idWindow::ParseExpression(idParser *src, idWinVar *var, int component) { + return ParseExpressionPriority( src, TOP_PRIORITY, var ); +} + +/* +================ +idWindow::ParseBracedExpression +================ +*/ +void idWindow::ParseBracedExpression(idParser *src) { + src->ExpectTokenString("{"); + ParseExpression(src); + src->ExpectTokenString("}"); +} + +/* +=============== +idWindow::EvaluateRegisters + +Parameters are taken from the localSpace and the renderView, +then all expressions are evaluated, leaving the shader registers +set to their apropriate values. +=============== +*/ +void idWindow::EvaluateRegisters(float *registers) { + int i, b; + wexpOp_t *op; + idVec4 v; + + int erc = expressionRegisters.Num(); + int oc = ops.Num(); + // copy the constants + for ( i = WEXP_REG_NUM_PREDEFINED ; i < erc ; i++ ) { + registers[i] = expressionRegisters[i]; + } + + // copy the local and global parameters + registers[WEXP_REG_TIME] = gui->GetTime(); + + for ( i = 0 ; i < oc ; i++ ) { + op = &ops[i]; + if (op->b == -2) { + continue; + } + switch( op->opType ) { + case WOP_TYPE_ADD: + registers[op->c] = registers[op->a] + registers[op->b]; + break; + case WOP_TYPE_SUBTRACT: + registers[op->c] = registers[op->a] - registers[op->b]; + break; + case WOP_TYPE_MULTIPLY: + registers[op->c] = registers[op->a] * registers[op->b]; + break; + case WOP_TYPE_DIVIDE: + if ( registers[op->b] == 0.0f ) { + common->Warning( "Divide by zero in window '%s' in %s", GetName(), gui->GetSourceFile() ); + registers[op->c] = registers[op->a]; + } else { + registers[op->c] = registers[op->a] / registers[op->b]; + } + break; + case WOP_TYPE_MOD: + b = (int)registers[op->b]; + b = b != 0 ? b : 1; + registers[op->c] = (int)registers[op->a] % b; + break; + case WOP_TYPE_TABLE: + { + const idDeclTable *table = static_cast( declManager->DeclByIndex( DECL_TABLE, op->a ) ); + registers[op->c] = table->TableLookup( registers[op->b] ); + } + break; + case WOP_TYPE_GT: + registers[op->c] = registers[ op->a ] > registers[op->b]; + break; + case WOP_TYPE_GE: + registers[op->c] = registers[ op->a ] >= registers[op->b]; + break; + case WOP_TYPE_LT: + registers[op->c] = registers[ op->a ] < registers[op->b]; + break; + case WOP_TYPE_LE: + registers[op->c] = registers[ op->a ] <= registers[op->b]; + break; + case WOP_TYPE_EQ: + registers[op->c] = registers[ op->a ] == registers[op->b]; + break; + case WOP_TYPE_NE: + registers[op->c] = registers[ op->a ] != registers[op->b]; + break; + case WOP_TYPE_COND: + registers[op->c] = (registers[ op->a ]) ? registers[op->b] : registers[op->d]; + break; + case WOP_TYPE_AND: + registers[op->c] = registers[ op->a ] && registers[op->b]; + break; + case WOP_TYPE_OR: + registers[op->c] = registers[ op->a ] || registers[op->b]; + break; + case WOP_TYPE_VAR: + if ( !op->a ) { + registers[op->c] = 0.0f; + break; + } + if ( op->b >= 0 && registers[op->b] >= 0 && registers[op->b] < 4 ) { + // grabs vector components + idWinVec4 *var = (idWinVec4 *)( op->a ); + registers[op->c] = ((idVec4&)var)[registers[op->b]]; + } else { + registers[op->c] = ((idWinVar*)(op->a))->x(); + } + break; + case WOP_TYPE_VARS: + if (op->a) { + idWinStr *var = (idWinStr*)(op->a); + registers[op->c] = atof(var->c_str()); + } else { + registers[op->c] = 0; + } + break; + case WOP_TYPE_VARF: + if (op->a) { + idWinFloat *var = (idWinFloat*)(op->a); + registers[op->c] = *var; + } else { + registers[op->c] = 0; + } + break; + case WOP_TYPE_VARI: + if (op->a) { + idWinInt *var = (idWinInt*)(op->a); + registers[op->c] = *var; + } else { + registers[op->c] = 0; + } + break; + case WOP_TYPE_VARB: + if (op->a) { + idWinBool *var = (idWinBool*)(op->a); + registers[op->c] = *var; + } else { + registers[op->c] = 0; + } + break; + default: + common->FatalError( "R_EvaluateExpression: bad opcode" ); + } + } + +} + +/* +================ +idWindow::ReadFromDemoFile +================ +*/ +void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { + + // should never hit unless we re-enable WRITE_GUIS +#ifndef WRITE_GUIS + assert( false ); +#else + + if (rebuild) { + CommonInit(); + } + + f->SetLog(true, "window1"); + backGroundName = f->ReadHashString(); + f->SetLog(true, backGroundName); + if ( backGroundName[0] ) { + background = declManager->FindMaterial(backGroundName); + } else { + background = NULL; + } + f->ReadUnsignedChar( cursor ); + f->ReadUnsignedInt( flags ); + f->ReadInt( timeLine ); + f->ReadInt( lastTimeRun ); + idRectangle rct = rect; + f->ReadFloat( rct.x ); + f->ReadFloat( rct.y ); + f->ReadFloat( rct.w ); + f->ReadFloat( rct.h ); + f->ReadFloat( drawRect.x ); + f->ReadFloat( drawRect.y ); + f->ReadFloat( drawRect.w ); + f->ReadFloat( drawRect.h ); + f->ReadFloat( clientRect.x ); + f->ReadFloat( clientRect.y ); + f->ReadFloat( clientRect.w ); + f->ReadFloat( clientRect.h ); + f->ReadFloat( textRect.x ); + f->ReadFloat( textRect.y ); + f->ReadFloat( textRect.w ); + f->ReadFloat( textRect.h ); + f->ReadFloat( xOffset); + f->ReadFloat( yOffset); + int i, c; + + idStr work; + if (rebuild) { + f->SetLog(true, (work + "-scripts")); + for (i = 0; i < SCRIPT_COUNT; i++) { + bool b; + f->ReadBool( b ); + if (b) { + delete scripts[i]; + scripts[i] = new idGuiScriptList; + scripts[i]->ReadFromDemoFile(f); + } + } + + f->SetLog(true, (work + "-timelines")); + f->ReadInt( c ); + for (i = 0; i < c; i++) { + idTimeLineEvent *tl = new idTimeLineEvent; + f->ReadInt( tl->time ); + f->ReadBool( tl->pending ); + tl->event->ReadFromDemoFile(f); + if (rebuild) { + timeLineEvents.Append(tl); + } else { + assert(i < timeLineEvents.Num()); + timeLineEvents[i]->time = tl->time; + timeLineEvents[i]->pending = tl->pending; + } + } + } + + f->SetLog(true, (work + "-transitions")); + f->ReadInt( c ); + for (i = 0; i < c; i++) { + idTransitionData td; + td.data = NULL; + f->ReadInt ( td.offset ); + + float startTime, accelTime, linearTime, decelTime; + idVec4 startValue, endValue; + f->ReadFloat( startTime ); + f->ReadFloat( accelTime ); + f->ReadFloat( linearTime ); + f->ReadFloat( decelTime ); + f->ReadVec4( startValue ); + f->ReadVec4( endValue ); + td.interp.Init( startTime, accelTime, decelTime, accelTime + linearTime + decelTime, startValue, endValue ); + + // read this for correct data padding with the win32 savegames + // the extrapolate is correctly initialized through the above Init call + int extrapolationType; + float duration; + idVec4 baseSpeed, speed; + float currentTime; + idVec4 currentValue; + f->ReadInt( extrapolationType ); + f->ReadFloat( startTime ); + f->ReadFloat( duration ); + f->ReadVec4( startValue ); + f->ReadVec4( baseSpeed ); + f->ReadVec4( speed ); + f->ReadFloat( currentTime ); + f->ReadVec4( currentValue ); + + transitions.Append(td); + } + + f->SetLog(true, (work + "-regstuff")); + if (rebuild) { + f->ReadInt( c ); + for (i = 0; i < c; i++) { + wexpOp_t w; + f->ReadInt( (int&)w.opType ); + f->ReadInt( w.a ); + f->ReadInt( w.b ); + f->ReadInt( w.c ); + f->ReadInt( w.d ); + ops.Append(w); + } + + f->ReadInt( c ); + for (i = 0; i < c; i++) { + float ff; + f->ReadFloat( ff ); + expressionRegisters.Append(ff); + } + + regList.ReadFromDemoFile(f); + + } + f->SetLog(true, (work + "-children")); + f->ReadInt( c ); + for (i = 0; i < c; i++) { + if (rebuild) { + idWindow *win = new idWindow(dc, gui); + win->ReadFromDemoFile(f); + AddChild(win); + } else { + for (int j = 0; j < c; j++) { + if (children[j]->childID == i) { + children[j]->ReadFromDemoFile(f,rebuild); + break; + } else { + continue; + } + } + } + } +#endif /* WRITE_GUIS */ +} + +/* +================ +idWindow::WriteToDemoFile +================ +*/ +void idWindow::WriteToDemoFile( class idDemoFile *f ) { + // should never hit unless we re-enable WRITE_GUIS +#ifndef WRITE_GUIS + assert( false ); +#else + + f->SetLog(true, "window"); + f->WriteHashString(backGroundName); + f->SetLog(true, backGroundName); + f->WriteUnsignedChar( cursor ); + f->WriteUnsignedInt( flags ); + f->WriteInt( timeLine ); + f->WriteInt( lastTimeRun ); + idRectangle rct = rect; + f->WriteFloat( rct.x ); + f->WriteFloat( rct.y ); + f->WriteFloat( rct.w ); + f->WriteFloat( rct.h ); + f->WriteFloat( drawRect.x ); + f->WriteFloat( drawRect.y ); + f->WriteFloat( drawRect.w ); + f->WriteFloat( drawRect.h ); + f->WriteFloat( clientRect.x ); + f->WriteFloat( clientRect.y ); + f->WriteFloat( clientRect.w ); + f->WriteFloat( clientRect.h ); + f->WriteFloat( textRect.x ); + f->WriteFloat( textRect.y ); + f->WriteFloat( textRect.w ); + f->WriteFloat( textRect.h ); + f->WriteFloat( xOffset ); + f->WriteFloat( yOffset ); + idStr work; + f->SetLog(true, work); + + int i, c; + + f->SetLog(true, (work + "-transitions")); + c = transitions.Num(); + f->WriteInt( c ); + for (i = 0; i < c; i++) { + f->WriteInt( 0 ); + f->WriteInt( transitions[i].offset ); + + f->WriteFloat( transitions[i].interp.GetStartTime() ); + f->WriteFloat( transitions[i].interp.GetAccelTime() ); + f->WriteFloat( transitions[i].interp.GetLinearTime() ); + f->WriteFloat( transitions[i].interp.GetDecelTime() ); + f->WriteVec4( transitions[i].interp.GetStartValue() ); + f->WriteVec4( transitions[i].interp.GetEndValue() ); + + // write to keep win32 render demo format compatiblity - we don't actually read them back anymore + f->WriteInt( transitions[i].interp.GetExtrapolate()->GetExtrapolationType() ); + f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetStartTime() ); + f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetDuration() ); + f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetStartValue() ); + f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetBaseSpeed() ); + f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetSpeed() ); + f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetCurrentTime() ); + f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetCurrentValue() ); + } + + f->SetLog(true, (work + "-regstuff")); + + f->SetLog(true, (work + "-children")); + c = children.Num(); + f->WriteInt( c ); + for (i = 0; i < c; i++) { + for (int j = 0; j < c; j++) { + if (children[j]->childID == i) { + children[j]->WriteToDemoFile(f); + break; + } else { + continue; + } + } + } +#endif /* WRITE_GUIS */ +} + +/* +=============== +idWindow::WriteString +=============== +*/ +void idWindow::WriteSaveGameString( const char *string, idFile *savefile ) { + int len = strlen( string ); + + savefile->Write( &len, sizeof( len ) ); + savefile->Write( string, len ); +} + +/* +=============== +idWindow::WriteSaveGameTransition +=============== +*/ +void idWindow::WriteSaveGameTransition( idTransitionData &trans, idFile *savefile ) { + drawWin_t dw, *fdw; + idStr winName(""); + dw.simp = NULL; + dw.win = NULL; + int offset = gui->GetDesktop()->GetWinVarOffset( trans.data, &dw ); + if ( dw.win || dw.simp ) { + winName = ( dw.win ) ? dw.win->GetName() : dw.simp->name.c_str(); + } + fdw = gui->GetDesktop()->FindChildByName( winName ); + if ( offset != -1 && fdw && ( fdw->win || fdw->simp ) ) { + savefile->Write( &offset, sizeof( offset ) ); + WriteSaveGameString( winName, savefile ); + savefile->Write( &trans.interp, sizeof( trans.interp ) ); + } else { + offset = -1; + savefile->Write( &offset, sizeof( offset ) ); + } +} + +/* +=============== +idWindow::ReadSaveGameTransition +=============== +*/ +void idWindow::ReadSaveGameTransition( idTransitionData &trans, idFile *savefile ) { + int offset; + + savefile->Read( &offset, sizeof( offset ) ); + if ( offset != -1 ) { + idStr winName; + ReadSaveGameString( winName, savefile ); + savefile->Read( &trans.interp, sizeof( trans.interp ) ); + trans.data = NULL; + trans.offset = offset; + if ( winName.Length() ) { + idWinStr *strVar = new idWinStr(); + strVar->Set( winName ); + trans.data = dynamic_cast< idWinVar* >( strVar ); + } + } +} + +/* +=============== +idWindow::WriteToSaveGame +=============== +*/ +void idWindow::WriteToSaveGame( idFile *savefile ) { + int i; + + WriteSaveGameString( cmd, savefile ); + + savefile->Write( &actualX, sizeof( actualX ) ); + savefile->Write( &actualY, sizeof( actualY ) ); + savefile->Write( &childID, sizeof( childID ) ); + savefile->Write( &flags, sizeof( flags ) ); + savefile->Write( &lastTimeRun, sizeof( lastTimeRun ) ); + savefile->Write( &drawRect, sizeof( drawRect ) ); + savefile->Write( &clientRect, sizeof( clientRect ) ); + savefile->Write( &origin, sizeof( origin ) ); + savefile->Write( &fontNum, sizeof( fontNum ) ); + savefile->Write( &timeLine, sizeof( timeLine ) ); + savefile->Write( &xOffset, sizeof( xOffset ) ); + savefile->Write( &yOffset, sizeof( yOffset ) ); + savefile->Write( &cursor, sizeof( cursor ) ); + savefile->Write( &forceAspectWidth, sizeof( forceAspectWidth ) ); + savefile->Write( &forceAspectHeight, sizeof( forceAspectHeight ) ); + savefile->Write( &matScalex, sizeof( matScalex ) ); + savefile->Write( &matScaley, sizeof( matScaley ) ); + savefile->Write( &borderSize, sizeof( borderSize ) ); + savefile->Write( &textAlign, sizeof( textAlign ) ); + savefile->Write( &textAlignx, sizeof( textAlignx ) ); + savefile->Write( &textAligny, sizeof( textAligny ) ); + savefile->Write( &textShadow, sizeof( textShadow ) ); + savefile->Write( &shear, sizeof( shear ) ); + + WriteSaveGameString( name, savefile ); + WriteSaveGameString( comment, savefile ); + + // WinVars + noTime.WriteToSaveGame( savefile ); + visible.WriteToSaveGame( savefile ); + rect.WriteToSaveGame( savefile ); + backColor.WriteToSaveGame( savefile ); + matColor.WriteToSaveGame( savefile ); + foreColor.WriteToSaveGame( savefile ); + hoverColor.WriteToSaveGame( savefile ); + borderColor.WriteToSaveGame( savefile ); + textScale.WriteToSaveGame( savefile ); + noEvents.WriteToSaveGame( savefile ); + rotate.WriteToSaveGame( savefile ); + text.WriteToSaveGame( savefile ); + backGroundName.WriteToSaveGame( savefile ); + hideCursor.WriteToSaveGame(savefile); + + // Defined Vars + for ( i = 0; i < definedVars.Num(); i++ ) { + definedVars[i]->WriteToSaveGame( savefile ); + } + + savefile->Write( &textRect, sizeof( textRect ) ); + + // Window pointers saved as the child ID of the window + int winID; + + winID = focusedChild ? focusedChild->childID : -1 ; + savefile->Write( &winID, sizeof( winID ) ); + + winID = captureChild ? captureChild->childID : -1 ; + savefile->Write( &winID, sizeof( winID ) ); + + winID = overChild ? overChild->childID : -1 ; + savefile->Write( &winID, sizeof( winID ) ); + + + // Scripts + for ( i = 0; i < SCRIPT_COUNT; i++ ) { + if ( scripts[i] ) { + scripts[i]->WriteToSaveGame( savefile ); + } + } + + // TimeLine Events + for ( i = 0; i < timeLineEvents.Num(); i++ ) { + if ( timeLineEvents[i] ) { + savefile->Write( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) ); + savefile->Write( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) ); + if ( timeLineEvents[i]->event ) { + timeLineEvents[i]->event->WriteToSaveGame( savefile ); + } + } + } + + // Transitions + int num = transitions.Num(); + + savefile->Write( &num, sizeof( num ) ); + for ( i = 0; i < transitions.Num(); i++ ) { + WriteSaveGameTransition( transitions[ i ], savefile ); + } + + + // Named Events + for ( i = 0; i < namedEvents.Num(); i++ ) { + if ( namedEvents[i] ) { + WriteSaveGameString( namedEvents[i]->mName, savefile ); + if ( namedEvents[i]->mEvent ) { + namedEvents[i]->mEvent->WriteToSaveGame( savefile ); + } + } + } + + // regList + regList.WriteToSaveGame( savefile ); + + + // Save children + for ( i = 0; i < drawWindows.Num(); i++ ) { + drawWin_t window = drawWindows[i]; + + if ( window.simp ) { + window.simp->WriteToSaveGame( savefile ); + } else if ( window.win ) { + window.win->WriteToSaveGame( savefile ); + } + } +} + +/* +=============== +idWindow::ReadSaveGameString +=============== +*/ +void idWindow::ReadSaveGameString( idStr &string, idFile *savefile ) { + int len; + + savefile->Read( &len, sizeof( len ) ); + if ( len < 0 ) { + common->Warning( "idWindow::ReadSaveGameString: invalid length" ); + } + + string.Fill( ' ', len ); + savefile->Read( &string[0], len ); +} + +/* +=============== +idWindow::ReadFromSaveGame +=============== +*/ +void idWindow::ReadFromSaveGame( idFile *savefile ) { + int i; + + transitions.Clear(); + + ReadSaveGameString( cmd, savefile ); + + savefile->Read( &actualX, sizeof( actualX ) ); + savefile->Read( &actualY, sizeof( actualY ) ); + savefile->Read( &childID, sizeof( childID ) ); + savefile->Read( &flags, sizeof( flags ) ); + savefile->Read( &lastTimeRun, sizeof( lastTimeRun ) ); + savefile->Read( &drawRect, sizeof( drawRect ) ); + savefile->Read( &clientRect, sizeof( clientRect ) ); + savefile->Read( &origin, sizeof( origin ) ); + savefile->Read( &fontNum, sizeof( fontNum ) ); + savefile->Read( &timeLine, sizeof( timeLine ) ); + savefile->Read( &xOffset, sizeof( xOffset ) ); + savefile->Read( &yOffset, sizeof( yOffset ) ); + savefile->Read( &cursor, sizeof( cursor ) ); + savefile->Read( &forceAspectWidth, sizeof( forceAspectWidth ) ); + savefile->Read( &forceAspectHeight, sizeof( forceAspectHeight ) ); + savefile->Read( &matScalex, sizeof( matScalex ) ); + savefile->Read( &matScaley, sizeof( matScaley ) ); + savefile->Read( &borderSize, sizeof( borderSize ) ); + savefile->Read( &textAlign, sizeof( textAlign ) ); + savefile->Read( &textAlignx, sizeof( textAlignx ) ); + savefile->Read( &textAligny, sizeof( textAligny ) ); + savefile->Read( &textShadow, sizeof( textShadow ) ); + savefile->Read( &shear, sizeof( shear ) ); + + ReadSaveGameString( name, savefile ); + ReadSaveGameString( comment, savefile ); + + // WinVars + noTime.ReadFromSaveGame( savefile ); + visible.ReadFromSaveGame( savefile ); + rect.ReadFromSaveGame( savefile ); + backColor.ReadFromSaveGame( savefile ); + matColor.ReadFromSaveGame( savefile ); + foreColor.ReadFromSaveGame( savefile ); + hoverColor.ReadFromSaveGame( savefile ); + borderColor.ReadFromSaveGame( savefile ); + textScale.ReadFromSaveGame( savefile ); + noEvents.ReadFromSaveGame( savefile ); + rotate.ReadFromSaveGame( savefile ); + text.ReadFromSaveGame( savefile ); + backGroundName.ReadFromSaveGame( savefile ); + + if ( session->GetSaveGameVersion() >= 17 ) { + hideCursor.ReadFromSaveGame(savefile); + } else { + hideCursor = false; + } + + // Defined Vars + for ( i = 0; i < definedVars.Num(); i++ ) { + definedVars[i]->ReadFromSaveGame( savefile ); + } + + savefile->Read( &textRect, sizeof( textRect ) ); + + // Window pointers saved as the child ID of the window + int winID = -1; + + savefile->Read( &winID, sizeof( winID ) ); + for ( i = 0; i < children.Num(); i++ ) { + if ( children[i]->childID == winID ) { + focusedChild = children[i]; + } + } + savefile->Read( &winID, sizeof( winID ) ); + for ( i = 0; i < children.Num(); i++ ) { + if ( children[i]->childID == winID ) { + captureChild = children[i]; + } + } + savefile->Read( &winID, sizeof( winID ) ); + for ( i = 0; i < children.Num(); i++ ) { + if ( children[i]->childID == winID ) { + overChild = children[i]; + } + } + + // Scripts + for ( i = 0; i < SCRIPT_COUNT; i++ ) { + if ( scripts[i] ) { + scripts[i]->ReadFromSaveGame( savefile ); + } + } + + // TimeLine Events + for ( i = 0; i < timeLineEvents.Num(); i++ ) { + if ( timeLineEvents[i] ) { + savefile->Read( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) ); + savefile->Read( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) ); + if ( timeLineEvents[i]->event ) { + timeLineEvents[i]->event->ReadFromSaveGame( savefile ); + } + } + } + + + // Transitions + int num; + savefile->Read( &num, sizeof( num ) ); + for ( i = 0; i < num; i++ ) { + idTransitionData trans; + trans.data = NULL; + ReadSaveGameTransition( trans, savefile ); + if ( trans.data ) { + transitions.Append( trans ); + } + } + + + // Named Events + for ( i = 0; i < namedEvents.Num(); i++ ) { + if ( namedEvents[i] ) { + ReadSaveGameString( namedEvents[i]->mName, savefile ); + if ( namedEvents[i]->mEvent ) { + namedEvents[i]->mEvent->ReadFromSaveGame( savefile ); + } + } + } + + // regList + regList.ReadFromSaveGame( savefile ); + + // Read children + for ( i = 0; i < drawWindows.Num(); i++ ) { + drawWin_t window = drawWindows[i]; + + if ( window.simp ) { + window.simp->ReadFromSaveGame( savefile ); + } else if ( window.win ) { + window.win->ReadFromSaveGame( savefile ); + } + } + + if ( flags & WIN_DESKTOP ) { + FixupTransitions(); + } +} + +/* +=============== +idWindow::NumTransitions +=============== +*/ +int idWindow::NumTransitions() { + int c = transitions.Num(); + for ( int i = 0; i < children.Num(); i++ ) { + c += children[i]->NumTransitions(); + } + return c; +} + + +/* +=============== +idWindow::FixupTransitions +=============== +*/ +void idWindow::FixupTransitions() { + int i, c = transitions.Num(); + for ( i = 0; i < c; i++ ) { + drawWin_t *dw = gui->GetDesktop()->FindChildByName( ( ( idWinStr* )transitions[i].data )->c_str() ); + delete transitions[i].data; + transitions[i].data = NULL; + if ( dw && ( dw->win || dw->simp ) ){ + if ( dw->win ) { + if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->rect ) { + transitions[i].data = &dw->win->rect; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->backColor ) { + transitions[i].data = &dw->win->backColor; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->matColor ) { + transitions[i].data = &dw->win->matColor; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->foreColor ) { + transitions[i].data = &dw->win->foreColor; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->borderColor ) { + transitions[i].data = &dw->win->borderColor; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->textScale ) { + transitions[i].data = &dw->win->textScale; + } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->rotate ) { + transitions[i].data = &dw->win->rotate; + } + } else { + if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->rect ) { + transitions[i].data = &dw->simp->rect; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->backColor ) { + transitions[i].data = &dw->simp->backColor; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->matColor ) { + transitions[i].data = &dw->simp->matColor; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->foreColor ) { + transitions[i].data = &dw->simp->foreColor; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->borderColor ) { + transitions[i].data = &dw->simp->borderColor; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->textScale ) { + transitions[i].data = &dw->simp->textScale; + } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->rotate ) { + transitions[i].data = &dw->simp->rotate; + } + } + } + if ( transitions[i].data == NULL ) { + transitions.RemoveIndex( i ); + i--; + c--; + } + } + for ( c = 0; c < children.Num(); c++ ) { + children[c]->FixupTransitions(); + } +} + + +/* +=============== +idWindow::AddChild +=============== +*/ +void idWindow::AddChild(idWindow *win) { + win->childID = children.Append(win); +} + +/* +================ +idWindow::FixupParms +================ +*/ +void idWindow::FixupParms() { + int i; + int c = children.Num(); + for (i = 0; i < c; i++) { + children[i]->FixupParms(); + } + for (i = 0; i < SCRIPT_COUNT; i++) { + if (scripts[i]) { + scripts[i]->FixupParms(this); + } + } + + c = timeLineEvents.Num(); + for (i = 0; i < c; i++) { + timeLineEvents[i]->event->FixupParms(this); + } + + c = namedEvents.Num(); + for (i = 0; i < c; i++) { + namedEvents[i]->mEvent->FixupParms(this); + } + + c = ops.Num(); + for (i = 0; i < c; i++) { + if (ops[i].b == -2) { + // need to fix this up + const char *p = (const char*)(ops[i].a); + idWinVar *var = GetWinVarByName(p, true); + delete []p; + ops[i].a = (int)var; + ops[i].b = -1; + } + } + + + if (flags & WIN_DESKTOP) { + CalcRects(0,0); + } + +} + +/* +================ +idWindow::IsSimple +================ +*/ +bool idWindow::IsSimple() { + + // dont do simple windows when in gui editor + if ( com_editors & EDITOR_GUI ) { + return false; + } + + if (ops.Num()) { + return false; + } + if (flags & (WIN_HCENTER | WIN_VCENTER)) { + return false; + } + if (children.Num() || drawWindows.Num()) { + return false; + } + for (int i = 0; i < SCRIPT_COUNT; i++) { + if (scripts[i]) { + return false; + } + } + if (timeLineEvents.Num()) { + return false; + } + + if ( namedEvents.Num() ) { + return false; + } + + return true; +} + +/* +================ +idWindow::ContainsStateVars +================ +*/ +bool idWindow::ContainsStateVars() { + if ( updateVars.Num() ) { + return true; + } + int c = children.Num(); + for (int i = 0; i < c; i++) { + if ( children[i]->ContainsStateVars() ) { + return true; + } + } + return false; +} + +/* +================ +idWindow::Interactive +================ +*/ +bool idWindow::Interactive() { + if ( scripts[ ON_ACTION ] ) { + return true; + } + int c = children.Num(); + for (int i = 0; i < c; i++) { + if (children[i]->Interactive()) { + return true; + } + } + return false; +} + +/* +================ +idWindow::SetChildWinVarVal +================ +*/ +void idWindow::SetChildWinVarVal(const char *name, const char *var, const char *val) { + drawWin_t *dw = FindChildByName(name); + idWinVar *wv = NULL; + if (dw && dw->simp) { + wv = dw->simp->GetWinVarByName(var); + } else if (dw && dw->win) { + wv = dw->win->GetWinVarByName(var); + } + if (wv) { + wv->Set(val); + wv->SetEval(false); + } +} + + +/* +================ +idWindow::FindChildByPoint + +Finds the window under the given point +================ +*/ +idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow** below ) { + int c = children.Num(); + + // If we are looking for a window below this one then + // the next window should be good, but this one wasnt it + if ( *below == this ) { + *below = NULL; + return NULL; + } + + if ( !Contains ( drawRect, x, y ) ) { + return NULL; + } + + for (int i = c - 1; i >= 0 ; i-- ) { + idWindow* found = children[i]->FindChildByPoint ( x, y, below ); + if ( found ) { + if ( *below ) { + continue; + } + + return found; + } + } + + return this; +} + +/* +================ +idWindow::FindChildByPoint +================ +*/ +idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow* below ) +{ + return FindChildByPoint ( x, y, &below ); +} + +/* +================ +idWindow::GetChildCount + +Returns the number of children +================ +*/ +int idWindow::GetChildCount ( void ) +{ + return drawWindows.Num ( ); +} + +/* +================ +idWindow::GetChild + +Returns the child window at the given index +================ +*/ +idWindow* idWindow::GetChild ( int index ) +{ + return drawWindows[index].win; +} + +/* +================ +idWindow::GetChildIndex + +Returns the index of the given child window +================ +*/ +int idWindow::GetChildIndex ( idWindow* window ) { + int find; + for ( find = 0; find < drawWindows.Num(); find ++ ) { + if ( drawWindows[find].win == window ) { + return find; + } + } + return -1; +} + +/* +================ +idWindow::RemoveChild + +Removes the child from the list of children. Note that the child window being +removed must still be deallocated by the caller +================ +*/ +void idWindow::RemoveChild ( idWindow *win ) { + int find; + + // Remove the child window + children.Remove ( win ); + + for ( find = 0; find < drawWindows.Num(); find ++ ) + { + if ( drawWindows[find].win == win ) + { + drawWindows.RemoveIndex ( find ); + break; + } + } +} + +/* +================ +idWindow::InsertChild + +Inserts the given window as a child into the given location in the zorder. +================ +*/ +bool idWindow::InsertChild ( idWindow *win, idWindow* before ) +{ + AddChild ( win ); + + win->parent = this; + + drawWin_t dwt; + dwt.simp = NULL; + dwt.win = win; + + // If not inserting before anything then just add it at the end + if ( before ) { + int index; + index = GetChildIndex ( before ); + if ( index != -1 ) { + drawWindows.Insert ( dwt, index ); + return true; + } + } + + drawWindows.Append ( dwt ); + return true; +} + +/* +================ +idWindow::ScreenToClient +================ +*/ +void idWindow::ScreenToClient ( idRectangle* r ) { + int x; + int y; + idWindow* p; + + for ( p = this, x = 0, y = 0; p; p = p->parent ) { + x += p->rect.x(); + y += p->rect.y(); + } + + r->x -= x; + r->y -= y; +} + +/* +================ +idWindow::ClientToScreen +================ +*/ +void idWindow::ClientToScreen ( idRectangle* r ) { + int x; + int y; + idWindow* p; + + for ( p = this, x = 0, y = 0; p; p = p->parent ) { + x += p->rect.x(); + y += p->rect.y(); + } + + r->x += x; + r->y += y; +} + +/* +================ +idWindow::SetDefaults + +Set the window do a default window with no text, no background and +default colors, etc.. +================ +*/ +void idWindow::SetDefaults ( void ) { + forceAspectWidth = 640.0f; + forceAspectHeight = 480.0f; + matScalex = 1; + matScaley = 1; + borderSize = 0; + noTime = false; + visible = true; + textAlign = 0; + textAlignx = 0; + textAligny = 0; + noEvents = false; + rotate = 0; + shear.Zero(); + textScale = 0.35f; + backColor.Zero(); + foreColor = idVec4(1, 1, 1, 1); + hoverColor = idVec4(1, 1, 1, 1); + matColor = idVec4(1, 1, 1, 1); + borderColor.Zero(); + text = ""; + + background = NULL; + backGroundName = ""; +} + +/* +================ +idWindow::UpdateFromDictionary + +The editor only has a dictionary to work with so the easiest way to push the +values of the dictionary onto the window is for the window to interpret the +dictionary as if were a file being parsed. +================ +*/ +bool idWindow::UpdateFromDictionary ( idDict& dict ) { + const idKeyValue* kv; + int i; + + SetDefaults ( ); + + // Clear all registers since they will get recreated + regList.Reset ( ); + expressionRegisters.Clear ( ); + ops.Clear ( ); + + for ( i = 0; i < dict.GetNumKeyVals(); i ++ ) { + kv = dict.GetKeyVal ( i ); + + // Special case name + if ( !kv->GetKey().Icmp ( "name" ) ) { + name = kv->GetValue(); + continue; + } + + idParser src( kv->GetValue().c_str(), kv->GetValue().Length(), "", + LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + if ( !ParseInternalVar ( kv->GetKey(), &src ) ) { + // Kill the old register since the parse reg entry will add a new one + if ( !ParseRegEntry ( kv->GetKey(), &src ) ) { + continue; + } + } + } + + EvalRegs(-1, true); + + SetupFromState(); + PostParse(); + + return true; +} diff --git a/ui/Window.h b/ui/Window.h new file mode 100644 index 000000000..b153caea0 --- /dev/null +++ b/ui/Window.h @@ -0,0 +1,446 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __WINDOW_H__ +#define __WINDOW_H__ + +#include "Rectangle.h" +#include "DeviceContext.h" +#include "RegExp.h" +#include "Winvar.h" +#include "GuiScript.h" +#include "SimpleWindow.h" + +const int WIN_CHILD = 0x00000001; +const int WIN_CAPTION = 0x00000002; +const int WIN_BORDER = 0x00000004; +const int WIN_SIZABLE = 0x00000008; +const int WIN_MOVABLE = 0x00000010; +const int WIN_FOCUS = 0x00000020; +const int WIN_CAPTURE = 0x00000040; +const int WIN_HCENTER = 0x00000080; +const int WIN_VCENTER = 0x00000100; +const int WIN_MODAL = 0x00000200; +const int WIN_INTRANSITION = 0x00000400; +const int WIN_CANFOCUS = 0x00000800; +const int WIN_SELECTED = 0x00001000; +const int WIN_TRANSFORM = 0x00002000; +const int WIN_HOLDCAPTURE = 0x00004000; +const int WIN_NOWRAP = 0x00008000; +const int WIN_NOCLIP = 0x00010000; +const int WIN_INVERTRECT = 0x00020000; +const int WIN_NATURALMAT = 0x00040000; +const int WIN_NOCURSOR = 0x00080000; +const int WIN_MENUGUI = 0x00100000; +const int WIN_ACTIVE = 0x00200000; +const int WIN_SHOWCOORDS = 0x00400000; +const int WIN_SHOWTIME = 0x00800000; +const int WIN_WANTENTER = 0x01000000; + +const int WIN_DESKTOP = 0x10000000; + +const char CAPTION_HEIGHT[] = "16.0"; +const char SCROLLER_SIZE[] = "16.0"; +const int SCROLLBAR_SIZE = 16; + +const int MAX_WINDOW_NAME = 32; +const int MAX_LIST_ITEMS = 1024; + +const char DEFAULT_BACKCOLOR[] = "1 1 1 1"; +const char DEFAULT_FORECOLOR[] = "0 0 0 1"; +const char DEFAULT_BORDERCOLOR[] = "0 0 0 1"; +const char DEFAULT_TEXTSCALE[] = "0.4"; + +typedef enum { + WOP_TYPE_ADD, + WOP_TYPE_SUBTRACT, + WOP_TYPE_MULTIPLY, + WOP_TYPE_DIVIDE, + WOP_TYPE_MOD, + WOP_TYPE_TABLE, + WOP_TYPE_GT, + WOP_TYPE_GE, + WOP_TYPE_LT, + WOP_TYPE_LE, + WOP_TYPE_EQ, + WOP_TYPE_NE, + WOP_TYPE_AND, + WOP_TYPE_OR, + WOP_TYPE_VAR, + WOP_TYPE_VARS, + WOP_TYPE_VARF, + WOP_TYPE_VARI, + WOP_TYPE_VARB, + WOP_TYPE_COND +} wexpOpType_t; + +typedef enum { + WEXP_REG_TIME, + WEXP_REG_NUM_PREDEFINED +} wexpRegister_t; + +typedef struct { + wexpOpType_t opType; + int a, b, c, d; +} wexpOp_t; + +struct idRegEntry { + const char *name; + idRegister::REGTYPE type; + int index; +}; + +class rvGEWindowWrapper; +class idWindow; + +struct idTimeLineEvent { + idTimeLineEvent() { + event = new idGuiScriptList; + } + ~idTimeLineEvent() { + delete event; + } + int time; + idGuiScriptList *event; + bool pending; + size_t Size() { + return sizeof(*this) + event->Size(); + } +}; + +class rvNamedEvent +{ +public: + + rvNamedEvent(const char* name) + { + mEvent = new idGuiScriptList; + mName = name; + } + ~rvNamedEvent(void) + { + delete mEvent; + } + size_t Size() + { + return sizeof(*this) + mEvent->Size(); + } + + idStr mName; + idGuiScriptList* mEvent; +}; + +struct idTransitionData { + idWinVar *data; + int offset; + idInterpolateAccelDecelLinear interp; +}; + + +class idUserInterfaceLocal; +class idWindow { +public: + idWindow(idUserInterfaceLocal *gui); + idWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + virtual ~idWindow(); + + enum { + ON_MOUSEENTER = 0, + ON_MOUSEEXIT, + ON_ACTION, + ON_ACTIVATE, + ON_DEACTIVATE, + ON_ESC, + ON_FRAME, + ON_TRIGGER, + ON_ACTIONRELEASE, + ON_ENTER, + ON_ENTERRELEASE, + SCRIPT_COUNT + }; + + enum { + ADJUST_MOVE = 0, + ADJUST_TOP, + ADJUST_RIGHT, + ADJUST_BOTTOM, + ADJUST_LEFT, + ADJUST_TOPLEFT, + ADJUST_BOTTOMRIGHT, + ADJUST_TOPRIGHT, + ADJUST_BOTTOMLEFT + }; + + static const char *ScriptNames[SCRIPT_COUNT]; + + static const idRegEntry RegisterVars[]; + static const int NumRegisterVars; + + void SetDC(idDeviceContext *d); + + idDeviceContext* GetDC ( void ) { return dc; } + + idWindow *SetFocus(idWindow *w, bool scripts = true); + + idWindow *SetCapture(idWindow *w); + void SetParent(idWindow *w); + void SetFlag(unsigned int f); + void ClearFlag(unsigned int f); + unsigned GetFlags() {return flags;}; + void Move(float x, float y); + void BringToTop(idWindow *w); + void Adjust(float xd, float yd); + void SetAdjustMode(idWindow *child); + void Size(float x, float y, float w, float h); + void SetupFromState(); + void SetupBackground(); + drawWin_t *FindChildByName(const char *name); + idSimpleWindow *FindSimpleWinByName(const char *_name); + idWindow *GetParent() { return parent; } + idUserInterfaceLocal *GetGui() {return gui;}; + bool Contains(float x, float y); + size_t Size(); + virtual size_t Allocated(); + idStr* GetStrPtrByName(const char *_name); + + virtual idWinVar *GetWinVarByName (const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + + int GetWinVarOffset( idWinVar *wv, drawWin_t *dw ); + float GetMaxCharHeight(); + float GetMaxCharWidth(); + void SetFont(); + void SetInitialState(const char *_name); + void AddChild(idWindow *win); + void DebugDraw(int time, float x, float y); + void CalcClientRect(float xofs, float yofs); + void CommonInit(); + void CleanUp(); + void DrawBorderAndCaption(const idRectangle &drawRect); + void DrawCaption(int time, float x, float y); + void SetupTransforms(float x, float y); + bool Contains(const idRectangle &sr, float x, float y); + const char *GetName() { return name; }; + + virtual bool Parse(idParser *src, bool rebuild = true); + virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + void CalcRects(float x, float y); + virtual void Redraw(float x, float y); + + virtual void ArchiveToDictionary(idDict *dict, bool useNames = true); + virtual void InitFromDictionary(idDict *dict, bool byName = true); + virtual void PostParse(); + virtual void Activate( bool activate, idStr &act ); + virtual void Trigger(); + virtual void GainFocus(); + virtual void LoseFocus(); + virtual void GainCapture(); + virtual void LoseCapture(); + virtual void Sized(); + virtual void Moved(); + virtual void Draw(int time, float x, float y); + virtual void MouseExit(); + virtual void MouseEnter(); + virtual void DrawBackground(const idRectangle &drawRect); + virtual const char *RouteMouseCoords(float xd, float yd); + virtual void SetBuddy(idWindow *buddy) {}; + virtual void HandleBuddyUpdate(idWindow *buddy) {}; + virtual void StateChanged( bool redraw ); + virtual void ReadFromDemoFile( class idDemoFile *f, bool rebuild = true ); + virtual void WriteToDemoFile( class idDemoFile *f ); + + // SaveGame support + void WriteSaveGameString( const char *string, idFile *savefile ); + void WriteSaveGameTransition( idTransitionData &trans, idFile *savefile ); + virtual void WriteToSaveGame( idFile *savefile ); + void ReadSaveGameString( idStr &string, idFile *savefile ); + void ReadSaveGameTransition( idTransitionData & trans, idFile *savefile ); + virtual void ReadFromSaveGame( idFile *savefile ); + void FixupTransitions(); + virtual void HasAction(){}; + virtual void HasScripts(){}; + + void FixupParms(); + void GetScriptString(const char *name, idStr &out); + void SetScriptParams(); + bool HasOps() { return (ops.Num() > 0); }; + float EvalRegs(int test = -1, bool force = false); + void StartTransition(); + void AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime); + void ResetTime(int time); + void ResetCinematics(); + + int NumTransitions(); + + bool ParseScript(idParser *src, idGuiScriptList &list, int *timeParm = NULL, bool allowIf = false); + bool RunScript(int n); + bool RunScriptList(idGuiScriptList *src); + void SetRegs(const char *key, const char *val); + int ParseExpression( idParser *src, idWinVar *var = NULL, int component = 0 ); + int ExpressionConstant(float f); + idRegisterList *RegList() { return ®List; } + void AddCommand(const char *cmd); + void AddUpdateVar(idWinVar *var); + bool Interactive(); + bool ContainsStateVars(); + void SetChildWinVarVal(const char *name, const char *var, const char *val); + idWindow *GetFocusedChild(); + idWindow *GetCaptureChild(); + const char *GetComment() { return comment; } + void SetComment( const char * p) { comment = p; } + + idStr cmd; + + virtual void RunNamedEvent ( const char* eventName ); + + void AddDefinedVar ( idWinVar* var ); + + idWindow* FindChildByPoint ( float x, float y, idWindow* below = NULL ); + int GetChildIndex ( idWindow* window ); + int GetChildCount ( void ); + idWindow* GetChild ( int index ); + void RemoveChild ( idWindow *win ); + bool InsertChild ( idWindow *win, idWindow* before ); + + void ScreenToClient ( idRectangle* rect ); + void ClientToScreen ( idRectangle* rect ); + + bool UpdateFromDictionary ( idDict& dict ); + +protected: + + friend class rvGEWindowWrapper; + + idWindow* FindChildByPoint ( float x, float y, idWindow** below ); + void SetDefaults ( void ); + + friend class idSimpleWindow; + friend class idUserInterfaceLocal; + bool IsSimple(); + void UpdateWinVars(); + void DisableRegister(const char *_name); + void Transition(); + void Time(); + bool RunTimeEvents(int time); + void Dump(); + + int ExpressionTemporary(); + wexpOp_t *ExpressionOp(); + int EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t **opp = NULL ); + int ParseEmitOp( idParser *src, int a, wexpOpType_t opType, int priority, wexpOp_t **opp = NULL ); + int ParseTerm( idParser *src, idWinVar *var = NULL, int component = 0 ); + int ParseExpressionPriority( idParser *src, int priority, idWinVar *var = NULL, int component = 0 ); + void EvaluateRegisters(float *registers); + void SaveExpressionParseState(); + void RestoreExpressionParseState(); + void ParseBracedExpression(idParser *src); + bool ParseScriptEntry(const char *name, idParser *src); + bool ParseRegEntry(const char *name, idParser *src); + virtual bool ParseInternalVar(const char *name, idParser *src); + void ParseString(idParser *src, idStr &out); + void ParseVec4(idParser *src, idVec4 &out); + void ConvertRegEntry(const char *name, idParser *src, idStr &out, int tabs); + + float actualX; // physical coords + float actualY; // '' + int childID; // this childs id + unsigned int flags; // visible, focus, mouseover, cursor, border, etc.. + int lastTimeRun; // + idRectangle drawRect; // overall rect + idRectangle clientRect; // client area + idVec2 origin; + + int timeLine; // time stamp used for various fx + float xOffset; + float yOffset; + float forceAspectWidth; + float forceAspectHeight; + float matScalex; + float matScaley; + float borderSize; + float textAlignx; + float textAligny; + idStr name; + idStr comment; + idVec2 shear; + + signed char textShadow; + unsigned char fontNum; + unsigned char cursor; // + signed char textAlign; + + idWinBool noTime; // + idWinBool visible; // + idWinBool noEvents; + idWinRectangle rect; // overall rect + idWinVec4 backColor; + idWinVec4 matColor; + idWinVec4 foreColor; + idWinVec4 hoverColor; + idWinVec4 borderColor; + idWinFloat textScale; + idWinFloat rotate; + idWinStr text; + idWinBackground backGroundName; // + + idList definedVars; + idList updateVars; + + idRectangle textRect; // text extented rect + const idMaterial *background; // background asset + + idWindow *parent; // parent window + idList children; // child windows + idList drawWindows; + + idWindow *focusedChild; // if a child window has the focus + idWindow *captureChild; // if a child window has mouse capture + idWindow *overChild; // if a child window has mouse capture + bool hover; + + idDeviceContext *dc; + + idUserInterfaceLocal *gui; + + static idCVar gui_debug; + static idCVar gui_edit; + + idGuiScriptList *scripts[SCRIPT_COUNT]; + bool *saveTemps; + + idList timeLineEvents; + idList transitions; + + static bool registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing + + idList ops; // evaluate to make expressionRegisters + idList expressionRegisters; + idList *saveOps; // evaluate to make expressionRegisters + idList namedEvents; // added named events + idList *saveRegs; + + idRegisterList regList; + + idWinBool hideCursor; +}; + +ID_INLINE void idWindow::AddDefinedVar( idWinVar* var ) { + definedVars.AddUnique( var ); +} + +#endif /* !__WINDOW_H__ */ diff --git a/ui/Winvar.cpp b/ui/Winvar.cpp new file mode 100644 index 000000000..660ae06ba --- /dev/null +++ b/ui/Winvar.cpp @@ -0,0 +1,74 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#include "../idlib/precompiled.h" +#pragma hdrstop + +#include "Window.h" +#include "Winvar.h" +#include "UserInterfaceLocal.h" + +idWinVar::idWinVar() { + guiDict = NULL; + name = NULL; + eval = true; +} + +idWinVar::~idWinVar() { + delete name; + name = NULL; +} + +void idWinVar::SetGuiInfo(idDict *gd, const char *_name) { + guiDict = gd; + SetName(_name); +} + + +void idWinVar::Init(const char *_name, idWindow *win) { + idStr key = _name; + guiDict = NULL; + int len = key.Length(); + if (len > 5 && key[0] == 'g' && key[1] == 'u' && key[2] == 'i' && key[3] == ':') { + key = key.Right(len - VAR_GUIPREFIX_LEN); + SetGuiInfo( win->GetGui()->GetStateDict(), key ); + win->AddUpdateVar(this); + } else { + Set(_name); + } +} + +void idMultiWinVar::Set( const char *val ) { + for ( int i = 0; i < Num(); i++ ) { + (*this)[i]->Set( val ); + } +} + +void idMultiWinVar::Update( void ) { + for ( int i = 0; i < Num(); i++ ) { + (*this)[i]->Update(); + } +} + +void idMultiWinVar::SetGuiInfo( idDict *dict ) { + for ( int i = 0; i < Num(); i++ ) { + (*this)[i]->SetGuiInfo( dict, (*this)[i]->c_str() ); + } +} + diff --git a/ui/Winvar.h b/ui/Winvar.h new file mode 100644 index 000000000..0134a6f74 --- /dev/null +++ b/ui/Winvar.h @@ -0,0 +1,847 @@ +/***************************************************************************** + The Dark Mod GPL Source Code + + This file is part of the The Dark Mod Source Code, originally based + on the Doom 3 GPL Source Code as published in 2011. + + The Dark Mod Source Code is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. For details, see LICENSE.TXT. + + Project: The Dark Mod (http://www.thedarkmod.com/) + + $Revision$ (Revision of last commit) + $Date$ (Date of last commit) + $Author$ (Author of last commit) + +******************************************************************************/ + +#ifndef __WINVAR_H__ +#define __WINVAR_H__ + +#include "Rectangle.h" + +static const char *VAR_GUIPREFIX = "gui::"; +static const int VAR_GUIPREFIX_LEN = strlen(VAR_GUIPREFIX); + +class idWindow; +class idWinVar { +public: + idWinVar(); + virtual ~idWinVar(); + + void SetGuiInfo(idDict *gd, const char *_name); + const char *GetName() const { + if (name) { + if (guiDict && *name == '*') { + return guiDict->GetString(&name[1]); + } + return name; + } + return ""; + } + void SetName(const char *_name) { + delete []name; + name = NULL; + if (_name) { + name = new char[strlen(_name)+1]; + strcpy(name, _name); + } + } + + idWinVar &operator=( const idWinVar &other ) { + guiDict = other.guiDict; + SetName(other.name); + return *this; + } + + idDict *GetDict() const { return guiDict; } + bool NeedsUpdate() { return (guiDict != NULL); } + + virtual void Init(const char *_name, idWindow* win) = 0; + virtual void Set(const char *val) = 0; + virtual void Update() = 0; + virtual const char *c_str() const = 0; + virtual size_t Size() { size_t sz = (name) ? strlen(name) : 0; return sz + sizeof(*this); } + + virtual void WriteToSaveGame( idFile *savefile ) = 0; + virtual void ReadFromSaveGame( idFile *savefile ) = 0; + + virtual float x( void ) const = 0; + + void SetEval(bool b) { + eval = b; + } + bool GetEval() { + return eval; + } + +protected: + idDict *guiDict; + char *name; + bool eval; +}; + +class idWinBool : public idWinVar { +public: + idWinBool() : idWinVar() {}; + ~idWinBool() {}; + virtual void Init(const char *_name, idWindow *win) { idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetBool(GetName()); + } + } + int operator==( const bool &other ) { return (other == data); } + bool &operator=( const bool &other ) { + data = other; + if (guiDict) { + guiDict->SetBool(GetName(), data); + } + return data; + } + idWinBool &operator=( const idWinBool &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + + operator bool() const { return data; } + + virtual void Set(const char *val) { + data = ( atoi( val ) != 0 ); + if (guiDict) { + guiDict->SetBool(GetName(), data); + } + } + + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetBool( s ); + } + } + + virtual const char *c_str() const {return va("%i", data); } + + // SaveGames + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + + virtual float x( void ) const { return data ? 1.0f : 0.0f; }; + +protected: + bool data; +}; + +class idWinStr : public idWinVar { +public: + idWinStr() : idWinVar() {}; + ~idWinStr() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetString(GetName()); + } + } + int operator==( const idStr &other ) const { + return (other == data); + } + int operator==( const char *other ) const { + return (data == other); + } + idStr &operator=( const idStr &other ) { + data = other; + if (guiDict) { + guiDict->Set(GetName(), data); + } + return data; + } + idWinStr &operator=( const idWinStr &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + operator const char *() const { + return data.c_str(); + } + operator const idStr &() const { + return data; + } + int LengthWithoutColors() { + if (guiDict && name && *name) { + data = guiDict->GetString(GetName()); + } + return data.LengthWithoutColors(); + } + int Length() { + if (guiDict && name && *name) { + data = guiDict->GetString(GetName()); + } + return data.Length(); + } + void RemoveColors() { + if (guiDict && name && *name) { + data = guiDict->GetString(GetName()); + } + data.RemoveColors(); + } + virtual const char *c_str() const { + return data.c_str(); + } + + virtual void Set(const char *val) { + data = val; + if ( guiDict ) { + guiDict->Set(GetName(), data); + } + } + + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetString( s ); + } + } + + virtual size_t Size() { + size_t sz = idWinVar::Size(); + return sz +data.Allocated(); + } + + // SaveGames + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + + int len = data.Length(); + savefile->Write( &len, sizeof( len ) ); + if ( len > 0 ) { + savefile->Write( data.c_str(), len ); + } + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + + int len; + savefile->Read( &len, sizeof( len ) ); + if ( len > 0 ) { + data.Fill( ' ', len ); + savefile->Read( &data[0], len ); + } + } + + // return wether string is emtpy + virtual float x( void ) const { return data[0] ? 1.0f : 0.0f; }; + +protected: + idStr data; +}; + +class idWinInt : public idWinVar { +public: + idWinInt() : idWinVar() {}; + ~idWinInt() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetInt(GetName()); + } + } + int &operator=( const int &other ) { + data = other; + if (guiDict) { + guiDict->SetInt(GetName(), data); + } + return data; + } + idWinInt &operator=( const idWinInt &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + operator int () const { + return data; + } + virtual void Set(const char *val) { + data = atoi(val);; + if (guiDict) { + guiDict->SetInt(GetName(), data); + } + } + + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetInt( s ); + } + } + virtual const char *c_str() const { + return va("%i", data); + } + + // SaveGames + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + + // no suitable conversion + virtual float x( void ) const { assert( false ); return 0.0f; }; + +protected: + int data; +}; + +class idWinFloat : public idWinVar { +public: + idWinFloat() : idWinVar() {}; + ~idWinFloat() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetFloat(GetName()); + } + } + idWinFloat &operator=( const idWinFloat &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + float &operator=( const float &other ) { + data = other; + if (guiDict) { + guiDict->SetFloat(GetName(), data); + } + return data; + } + operator float() const { + return data; + } + virtual void Set(const char *val) { + data = atof(val); + if (guiDict) { + guiDict->SetFloat(GetName(), data); + } + } + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetFloat( s ); + } + } + virtual const char *c_str() const { + return va("%f", data); + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + + virtual float x( void ) const { return data; }; +protected: + float data; +}; + +class idWinRectangle : public idWinVar { +public: + idWinRectangle() : idWinVar() {}; + ~idWinRectangle() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + idVec4 v = guiDict->GetVec4(GetName()); + data.x = v.x; + data.y = v.y; + data.w = v.z; + data.h = v.w; + } + } + + int operator==( const idRectangle &other ) const { + return (other == data); + } + + idWinRectangle &operator=( const idWinRectangle &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + idRectangle &operator=( const idVec4 &other ) { + data = other; + if (guiDict) { + guiDict->SetVec4(GetName(), other); + } + return data; + } + + idRectangle &operator=( const idRectangle &other ) { + data = other; + if (guiDict) { + idVec4 v = data.ToVec4(); + guiDict->SetVec4(GetName(), v); + } + return data; + } + + operator const idRectangle&() const { + return data; + } + + float x() const { + return data.x; + } + float y() const { + return data.y; + } + float w() const { + return data.w; + } + float h() const { + return data.h; + } + float Right() const { + return data.Right(); + } + float Bottom() const { + return data.Bottom(); + } + idVec4 &ToVec4() { + static idVec4 ret; + ret = data.ToVec4(); + return ret; + } + virtual void Set(const char *val) { + if ( strchr ( val, ',' ) ) { + sscanf( val, "%f,%f,%f,%f", &data.x, &data.y, &data.w, &data.h ); + } else { + sscanf( val, "%f %f %f %f", &data.x, &data.y, &data.w, &data.h ); + } + if (guiDict) { + idVec4 v = data.ToVec4(); + guiDict->SetVec4(GetName(), v); + } + } + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + idVec4 v = guiDict->GetVec4( s ); + data.x = v.x; + data.y = v.y; + data.w = v.z; + data.h = v.w; + } + } + + virtual const char *c_str() const { + return data.ToVec4().ToString(); + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + +protected: + idRectangle data; +}; + +class idWinVec2 : public idWinVar { +public: + idWinVec2() : idWinVar() {}; + ~idWinVec2() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetVec2(GetName()); + } + } + int operator==( const idVec2 &other ) const { + return (other == data); + } + idWinVec2 &operator=( const idWinVec2 &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + + idVec2 &operator=( const idVec2 &other ) { + data = other; + if (guiDict) { + guiDict->SetVec2(GetName(), data); + } + return data; + } + float x() const { + return data.x; + } + float y() const { + return data.y; + } + virtual void Set(const char *val) { + if ( strchr ( val, ',' ) ) { + sscanf( val, "%f,%f", &data.x, &data.y ); + } else { + sscanf( val, "%f %f", &data.x, &data.y); + } + if (guiDict) { + guiDict->SetVec2(GetName(), data); + } + } + operator const idVec2&() const { + return data; + } + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetVec2( s ); + } + } + virtual const char *c_str() const { + return data.ToString(); + } + void Zero() { + data.Zero(); + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + +protected: + idVec2 data; +}; + +class idWinVec4 : public idWinVar { +public: + idWinVec4() : idWinVar() {}; + ~idWinVec4() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetVec4(GetName()); + } + } + int operator==( const idVec4 &other ) const { + return (other == data); + } + idWinVec4 &operator=( const idWinVec4 &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + idVec4 &operator=( const idVec4 &other ) { + data = other; + if (guiDict) { + guiDict->SetVec4(GetName(), data); + } + return data; + } + operator const idVec4&() const { + return data; + } + + float x() const { + return data.x; + } + + float y() const { + return data.y; + } + + float z() const { + return data.z; + } + + float w() const { + return data.w; + } + virtual void Set(const char *val) { + if ( strchr ( val, ',' ) ) { + sscanf( val, "%f,%f,%f,%f", &data.x, &data.y, &data.z, &data.w ); + } else { + sscanf( val, "%f %f %f %f", &data.x, &data.y, &data.z, &data.w); + } + if ( guiDict ) { + guiDict->SetVec4( GetName(), data ); + } + } + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetVec4( s ); + } + } + virtual const char *c_str() const { + return data.ToString(); + } + + void Zero() { + data.Zero(); + if ( guiDict ) { + guiDict->SetVec4(GetName(), data); + } + } + + const idVec3 &ToVec3() const { + return data.ToVec3(); + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + +protected: + idVec4 data; +}; + +class idWinVec3 : public idWinVar { +public: + idWinVec3() : idWinVar() {}; + ~idWinVec3() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinVar::Init(_name, win); + if (guiDict) { + data = guiDict->GetVector(GetName()); + } + } + int operator==( const idVec3 &other ) const { + return (other == data); + } + idWinVec3 &operator=( const idWinVec3 &other ) { + idWinVar::operator=(other); + data = other.data; + return *this; + } + idVec3 &operator=( const idVec3 &other ) { + data = other; + if (guiDict) { + guiDict->SetVector(GetName(), data); + } + return data; + } + operator const idVec3&() const { + return data; + } + + float x() const { + return data.x; + } + + float y() const { + return data.y; + } + + float z() const { + return data.z; + } + + virtual void Set(const char *val) { + sscanf( val, "%f %f %f", &data.x, &data.y, &data.z); + if (guiDict) { + guiDict->SetVector(GetName(), data); + } + } + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetVector( s ); + } + } + virtual const char *c_str() const { + return data.ToString(); + } + + void Zero() { + data.Zero(); + if (guiDict) { + guiDict->SetVector(GetName(), data); + } + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + savefile->Write( &data, sizeof( data ) ); + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + savefile->Read( &data, sizeof( data ) ); + } + +protected: + idVec3 data; +}; + +class idWinBackground : public idWinStr { +public: + idWinBackground() : idWinStr() { + mat = NULL; + }; + ~idWinBackground() {}; + virtual void Init(const char *_name, idWindow *win) { + idWinStr::Init(_name, win); + if (guiDict) { + data = guiDict->GetString(GetName()); + } + } + int operator==( const idStr &other ) const { + return (other == data); + } + int operator==( const char *other ) const { + return (data == other); + } + idStr &operator=( const idStr &other ) { + data = other; + if (guiDict) { + guiDict->Set(GetName(), data); + } + if (mat) { + if ( data == "" ) { + (*mat) = NULL; + } else { + (*mat) = declManager->FindMaterial(data); + } + } + return data; + } + idWinBackground &operator=( const idWinBackground &other ) { + idWinVar::operator=(other); + data = other.data; + mat = other.mat; + if (mat) { + if ( data == "" ) { + (*mat) = NULL; + } else { + (*mat) = declManager->FindMaterial(data); + } + } + return *this; + } + operator const char *() const { + return data.c_str(); + } + operator const idStr &() const { + return data; + } + int Length() { + if (guiDict) { + data = guiDict->GetString(GetName()); + } + return data.Length(); + } + virtual const char *c_str() const { + return data.c_str(); + } + + virtual void Set(const char *val) { + data = val; + if (guiDict) { + guiDict->Set(GetName(), data); + } + if (mat) { + if ( data == "" ) { + (*mat) = NULL; + } else { + (*mat) = declManager->FindMaterial(data); + } + } + } + + virtual void Update() { + const char *s = GetName(); + if ( guiDict && s[0] != '\0' ) { + data = guiDict->GetString( s ); + if (mat) { + if ( data == "" ) { + (*mat) = NULL; + } else { + (*mat) = declManager->FindMaterial(data); + } + } + } + } + + virtual size_t Size() { + size_t sz = idWinVar::Size(); + return sz +data.Allocated(); + } + + void SetMaterialPtr( const idMaterial **m ) { + mat = m; + } + + virtual void WriteToSaveGame( idFile *savefile ) { + savefile->Write( &eval, sizeof( eval ) ); + + int len = data.Length(); + savefile->Write( &len, sizeof( len ) ); + if ( len > 0 ) { + savefile->Write( data.c_str(), len ); + } + } + virtual void ReadFromSaveGame( idFile *savefile ) { + savefile->Read( &eval, sizeof( eval ) ); + + int len; + savefile->Read( &len, sizeof( len ) ); + if ( len > 0 ) { + data.Fill( ' ', len ); + savefile->Read( &data[0], len ); + } + if ( mat ) { + if ( len > 0 ) { + (*mat) = declManager->FindMaterial( data ); + } else { + (*mat) = NULL; + } + } + } + +protected: + idStr data; + const idMaterial **mat; +}; + +/* +================ +idMultiWinVar +multiplexes access to a list if idWinVar* +================ +*/ +class idMultiWinVar : public idList< idWinVar * > { +public: + void Set( const char *val ); + void Update( void ); + void SetGuiInfo( idDict *dict ); +}; + +#endif /* !__WINVAR_H__ */ + diff --git a/ui/listgui.h b/ui/listgui.h deleted file mode 100644 index 3701015a4..000000000 --- a/ui/listgui.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __LISTGUI_H__ -#define __LISTGUI_H__ - -/* -=============================================================================== - - feed data to a listDef - each item has an id and a display string - -=============================================================================== -*/ - -class idListGUI { -public: - virtual ~idListGUI() { } - - virtual void Config( idUserInterface *pGUI, const char *name ) = 0; - virtual void Add( int id, const idStr& s ) = 0; - // use the element count as index for the ids - virtual void Push( const idStr& s ) = 0; - virtual bool Del( int id ) = 0; - virtual void Clear( void ) = 0; - virtual int Num( void ) = 0; - virtual int GetSelection( char *s, int size, int sel = 0 ) const = 0; // returns the id, not the list index (or -1) - virtual void SetSelection( int sel ) = 0; - virtual int GetNumSelections() = 0; - virtual bool IsConfigured( void ) const = 0; - // by default, any modification to the list will trigger a full GUI refresh immediately - virtual void SetStateChanges( bool enable ) = 0; - virtual void Shutdown( void ) = 0; -}; - -#endif /* !__LISTGUI_H__ */ diff --git a/ui/userinterface.h b/ui/userinterface.h deleted file mode 100644 index 129bb6583..000000000 --- a/ui/userinterface.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * - * PROJECT: The Dark Mod - * $Revision$ - * $Date$ - * $Author$ - * - ***************************************************************************/ - -// Copyright (C) 2004 Id Software, Inc. -// - -#ifndef __USERINTERFACE_H__ -#define __USERINTERFACE_H__ - -/* -=============================================================================== - - Draws an interactive 2D surface. - Used for all user interaction with the game. - -=============================================================================== -*/ - -class idFile; -class idDemoFile; - - -class idUserInterface { -public: - virtual ~idUserInterface() {}; - - // Returns the name of the gui. - virtual const char * Name() const = 0; - - // Returns a comment on the gui. - virtual const char * Comment() const = 0; - - // Returns true if the gui is interactive. - virtual bool IsInteractive() const = 0; - - virtual bool IsUniqued() const = 0; - - virtual void SetUniqued( bool b ) = 0; - // returns false if it failed to load - virtual bool InitFromFile( const char *qpath, bool rebuild = true, bool cache = true ) = 0; - - // handles an event, can return an action string, the caller interprets - // any return and acts accordingly - virtual const char * HandleEvent( const sysEvent_t *event, int time, bool *updateVisuals = NULL ) = 0; - - // handles a named event - virtual void HandleNamedEvent( const char *eventName ) = 0; - - // repaints the ui - virtual void Redraw( int time ) = 0; - - // repaints the cursor - virtual void DrawCursor() = 0; - - // Provides read access to the idDict that holds this gui's state. - virtual const idDict & State() const = 0; - - // Removes a gui state variable - virtual void DeleteStateVar( const char *varName ) = 0; - - // Sets a gui state variable. - virtual void SetStateString( const char *varName, const char *value ) = 0; - virtual void SetStateBool( const char *varName, const bool value ) = 0; - virtual void SetStateInt( const char *varName, const int value ) = 0; - virtual void SetStateFloat( const char *varName, const float value ) = 0; - - // Gets a gui state variable - virtual const char* GetStateString( const char *varName, const char* defaultString = "" ) const = 0; - virtual bool GetStateBool( const char *varName, const char* defaultString = "0" ) const = 0; - virtual int GetStateInt( const char *varName, const char* defaultString = "0" ) const = 0; - virtual float GetStateFloat( const char *varName, const char* defaultString = "0" ) const = 0; - - // The state has changed and the gui needs to update from the state idDict. - // greebo: NEVER call this on the main menu - virtual void StateChanged( int time, bool redraw = false ) = 0; - - // Activated the gui. - virtual const char * Activate( bool activate, int time ) = 0; - - // Triggers the gui and runs the onTrigger scripts. - virtual void Trigger( int time ) = 0; - - virtual void ReadFromDemoFile( class idDemoFile *f ) = 0; - virtual void WriteToDemoFile( class idDemoFile *f ) = 0; - - virtual bool WriteToSaveGame( idFile *savefile ) const = 0; - virtual bool ReadFromSaveGame( idFile *savefile ) = 0; - virtual void SetKeyBindingNames( void ) = 0; - - virtual void SetCursor( float x, float y ) = 0; - virtual float CursorX() = 0; - virtual float CursorY() = 0; -}; - - -class idUserInterfaceManager { -public: - virtual ~idUserInterfaceManager( void ) {}; - - virtual void Init() = 0; - virtual void Shutdown() = 0; - virtual void Touch( const char *name ) = 0; - virtual void WritePrecacheCommands( idFile *f ) = 0; - - // Sets the size for 640x480 adjustment. - virtual void SetSize( float width, float height ) = 0; - - virtual void BeginLevelLoad() = 0; - virtual void EndLevelLoad() = 0; - - // Reloads changed guis, or all guis. - virtual void Reload( bool all ) = 0; - - // lists all guis - virtual void ListGuis() const = 0; - - // Returns true if gui exists. - virtual bool CheckGui( const char *qpath ) const = 0; - - // Allocates a new gui. - virtual idUserInterface * Alloc( void ) const = 0; - - // De-allocates a gui.. ONLY USE FOR PRECACHING - virtual void DeAlloc( idUserInterface *gui ) = 0; - - // Returns NULL if gui by that name does not exist. - virtual idUserInterface * FindGui( const char *qpath, bool autoLoad = false, bool needUnique = false, bool forceUnique = false ) = 0; - - // Returns NULL if gui by that name does not exist. - virtual idUserInterface * FindDemoGui( const char *qpath ) = 0; - - // Allocates a new GUI list handler - virtual idListGUI * AllocListGUI( void ) const = 0; - - // De-allocates a list gui - virtual void FreeListGUI( idListGUI *listgui ) = 0; -}; - -extern idUserInterfaceManager * uiManager; - -#endif /* !__USERINTERFACE_H__ */ diff --git a/win32/devil/include/IL/devil_internal_exports.h b/win32/devil/include/IL/devil_internal_exports.h deleted file mode 100644 index f457176e2..000000000 --- a/win32/devil/include/IL/devil_internal_exports.h +++ /dev/null @@ -1,156 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/19/2002 <--Y2K Compliant! =] -// -// Filename: IL/devil_internal_exports.h -// -// Description: Internal stuff for DevIL (IL, ILU and ILUT) -// -//----------------------------------------------------------------------------- - -#ifndef IL_EXPORTS_H -#define IL_EXPORTS_H - -#include "IL/il.h" - -#ifdef DEBUG - #include -#else - #define assert(x) -#endif - -#ifndef NOINLINE -#ifndef INLINE -#if defined(__GNUC__) - #define INLINE extern inline -#elif defined(_MSC_VER) - #define NOINLINE - #define INLINE - //#define INLINE __inline -#else - #define INLINE inline -#endif -#endif -#else -#define INLINE -#endif //NOINLINE - -#ifdef __cplusplus -extern "C" { -#endif - -#define IL_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define IL_MIN(a,b) (((a) < (b)) ? (a) : (b)) - - -// Basic Palette struct -typedef struct ILpal -{ - ILubyte* Palette; // the image palette (if any) - ILuint PalSize; // size of the palette (in bytes) - ILenum PalType; // the palette types below (0x0500 range) -} ILpal; - - -// The Fundamental Image struct -typedef struct ILimage { - ILuint Width; // the image's width - ILuint Height; // the image's height - ILuint Depth; // the image's depth - ILubyte Bpp; // bytes per pixel (now number of channels) - ILubyte Bpc; // bytes per channel - ILuint Bps; // bytes per scanline (components for IL) - ILubyte* Data; // the image data - ILuint SizeOfData; // the total size of the data (in bytes) - ILuint SizeOfPlane; // SizeOfData in a 2d image, size of each plane slice in a 3d image (in bytes) - ILenum Format; // image format (in IL enum style) - ILenum Type; // image type (in IL enum style) - ILenum Origin; // origin of the image - ILpal Pal; // palette details - ILuint Duration; // length of the time to display this "frame" - ILenum CubeFlags; // cube map flags for sides present in chain - struct ILimage* Mipmaps; // mipmapped versions of this image terminated by a NULL - usu. NULL - struct ILimage* Next; // next image in the chain - usu. NULL - struct ILimage* Layers; // subsequent layers in the chain - usu. NULL -// ILuint NumNext; // number of images following this one (0 when not parent). These are calculated on request -// ILuint NumMips; // number of mipmaps (0 when not parent) -// ILuint NumLayers; // number of layers (0 when not parent) - ILuint* AnimList; // animation list - ILuint AnimSize; // animation list size - ILvoid* Profile; // colour profile - ILuint ProfileSize; // colour profile size - ILuint OffX, OffY; // offset of the image - ILubyte* DxtcData; // compressed data - ILenum DxtcFormat; // compressed data format - ILuint DxtcSize; // compressed data size -} ILimage; - - -// Memory functions -ILAPI ILvoid* ILAPIENTRY ialloc(const ILuint Size); -ILAPI ILvoid ILAPIENTRY ifree(const ILvoid *Ptr); -ILAPI ILvoid* ILAPIENTRY icalloc(const ILuint Size, const ILuint Num); -#ifdef ALTIVEC_GCC -ILAPI ILvoid* ILAPIENTRY ivec_align_buffer(ILvoid *buffer, const ILuint size); -#endif - -// Internal library functions in IL -ILAPI ILimage* ILAPIENTRY ilGetCurImage(void); -ILAPI ILvoid ILAPIENTRY ilSetCurImage(ILimage *Image); -ILAPI ILvoid ILAPIENTRY ilSetError(ILenum Error); -ILAPI ILvoid ILAPIENTRY ilSetPal(ILpal *Pal); - -// -// Utility functions -// -ILAPI ILubyte ILAPIENTRY ilGetBppFormat(ILenum Format); -ILAPI ILenum ILAPIENTRY ilGetFormatBpp(ILubyte Bpp); -ILAPI ILubyte ILAPIENTRY ilGetBpcType(ILenum Type); -ILAPI ILenum ILAPIENTRY ilGetTypeBpc(ILubyte Bpc); -ILAPI ILubyte ILAPIENTRY ilGetBppPal(ILenum PalType); -ILAPI ILenum ILAPIENTRY ilGetPalBaseType(ILenum PalType); -ILAPI ILuint ILAPIENTRY ilNextPower2(ILuint Num); -ILAPI ILenum ILAPIENTRY ilTypeFromExt(ILconst_string FileName); -ILAPI ILvoid ILAPIENTRY ilReplaceCurImage(ILimage *Image); -ILAPI ILvoid ILAPIENTRY iMemSwap( ILubyte *, ILubyte *, const ILuint ); - -// -// Image functions -// -ILAPI ILvoid ILAPIENTRY iBindImageTemp (void); -ILAPI ILboolean ILAPIENTRY ilClearImage_ (ILimage *Image); -ILAPI ILvoid ILAPIENTRY ilCloseImage (ILimage *Image); -ILAPI ILvoid ILAPIENTRY ilClosePal (ILpal *Palette); -ILAPI ILpal* ILAPIENTRY iCopyPal (void); -ILAPI ILboolean ILAPIENTRY ilCopyImageAttr (ILimage *Dest, ILimage *Src); -ILAPI ILimage* ILAPIENTRY ilCopyImage_ (ILimage *Src); -ILAPI ILvoid ILAPIENTRY ilGetClear (ILvoid *Colours, ILenum Format, ILenum Type); -ILAPI ILuint ILAPIENTRY ilGetCurName (void); -ILAPI ILboolean ILAPIENTRY ilIsValidPal (ILpal *Palette); -ILAPI ILimage* ILAPIENTRY ilNewImage (ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc); -ILAPI ILimage* ILAPIENTRY ilNewImageFull (ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILboolean ILAPIENTRY ilInitImage (ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILboolean ILAPIENTRY ilResizeImage (ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc); -ILAPI ILboolean ILAPIENTRY ilTexImage_ (ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILboolean ILAPIENTRY ilTexSubImage_ (ILimage *Image, ILvoid *Data); -ILAPI ILvoid* ILAPIENTRY ilConvertBuffer (ILuint SizeOfData, ILenum SrcFormat, ILenum DestFormat, ILenum SrcType, ILenum DestType, ILvoid *Buffer); -ILAPI ILimage* ILAPIENTRY iConvertImage (ILimage *Image, ILenum DestFormat, ILenum DestType); -ILAPI ILpal* ILAPIENTRY iConvertPal (ILpal *Pal, ILenum DestFormat); -ILAPI ILubyte* ILAPIENTRY iGetFlipped (ILimage *Image); -ILAPI ILboolean ILAPIENTRY iMirror(); -ILAPI ILvoid ILAPIENTRY iFlipBuffer( ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num ); -ILubyte *iFlipNewBuffer( ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num ); -ILAPI ILvoid ILAPIENTRY iGetIntegervImage(ILimage *Image, ILenum Mode, ILint *Param); - -// Internal library functions in ILU -ILAPI ILimage* ILAPIENTRY iluRotate_(ILimage *Image, ILfloat Angle); -ILAPI ILimage* ILAPIENTRY iluRotate3D_(ILimage *Image, ILfloat x, ILfloat y, ILfloat z, ILfloat Angle); -ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth); - -#ifdef __cplusplus -} -#endif - -#endif//IL_EXPORTS_H diff --git a/win32/devil/include/IL/il.h b/win32/devil/include/IL/il.h deleted file mode 100644 index 7d2ffb479..000000000 --- a/win32/devil/include/IL/il.h +++ /dev/null @@ -1,584 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: IL/il.h -// -// Description: The main include file for DevIL -// -//----------------------------------------------------------------------------- - - -#ifndef __il_h_ -#ifndef __IL_H__ - -#define __il_h_ -#define __IL_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -// Compiling Options -#define IL_INLINE_ASM - -//this define controls if floats and doubles are clampled to [0..1] -//during conversion. It takes a little more time, but it is the correct -//way of doing this. If you are sure your floats are always valid, -//you can undefine this value... -#define CLAMP_HALF 1 -#define CLAMP_FLOATS 1 -#define CLAMP_DOUBLES 1 - -#ifdef _WIN32_WCE - #define IL_NO_GIF - #define IL_NO_JPG - #define IL_NO_MNG - #define IL_NO_PNG - #define IL_NO_TIF - #define IL_NO_LCMS -#endif //_WIN32_WCE - -#ifdef DJGPP - #define IL_NO_GIF - #define IL_NO_JPG - #define IL_NO_MNG - #define IL_NO_PNG - #define IL_NO_TIF - #define IL_NO_LCMS -#endif //DJGPP - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) && (!defined(_IL_BUILD_LIBRARY)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "DevIL.lib") - #endif - #endif -#endif - -#ifdef RESTRICT_KEYWORD -#define RESTRICT restrict -#define CONST_RESTRICT const restrict -#else -#define RESTRICT -#define CONST_RESTRICT const -#endif - -#include - -typedef unsigned int ILenum; -typedef unsigned char ILboolean; -typedef unsigned int ILbitfield; -typedef signed char ILbyte; -typedef signed short ILshort; -typedef int ILint; -typedef int ILsizei; -typedef unsigned char ILubyte; -typedef unsigned short ILushort; -typedef unsigned int ILuint; -typedef float ILfloat; -typedef float ILclampf; -typedef double ILdouble; -typedef double ILclampd; -typedef void ILvoid; -#include -#ifdef _UNICODE - #ifndef _WIN32_WCE - #include - #endif - //if we use a define instead of a typedef, - //ILconst_string works as intended - #define ILstring wchar_t* - #define ILconst_string wchar_t const * -#else - //if we use a define instead of a typedef, - //ILconst_string works as intended - #define ILstring char* - #define ILconst_string char const * -#endif //_UNICODE - -#define IL_FALSE 0 -#define IL_TRUE 1 - -// Matches OpenGL's right now. -#define IL_COLOUR_INDEX 0x1900 -#define IL_COLOR_INDEX 0x1900 -#define IL_RGB 0x1907 -#define IL_RGBA 0x1908 -#define IL_BGR 0x80E0 -#define IL_BGRA 0x80E1 -#define IL_LUMINANCE 0x1909 -#define IL_LUMINANCE_ALPHA 0x190A - - -#define IL_BYTE 0x1400 -#define IL_UNSIGNED_BYTE 0x1401 -#define IL_SHORT 0x1402 -#define IL_UNSIGNED_SHORT 0x1403 -#define IL_INT 0x1404 -#define IL_UNSIGNED_INT 0x1405 -#define IL_FLOAT 0x1406 -#define IL_DOUBLE 0x140A -#define IL_HALF 0x140B - - -#define IL_MAX_BYTE SCHAR_MAX -#define IL_MAX_UNSIGNED_BYTE UCHAR_MAX -#define IL_MAX_SHORT SHRT_MAX -#define IL_MAX_UNSIGNED_SHORT USHRT_MAX -#define IL_MAX_INT INT_MAX -#define IL_MAX_UNSIGNED_INT UINT_MAX - -#define limit(x,m,M) (xM?M:x)) -#define clamp(x) limit(x,0,1) - -#define IL_VENDOR 0x1F00 -#define IL_LOAD_EXT 0x1F01 -#define IL_SAVE_EXT 0x1F02 - - -// -// IL-specific #define's -// - -#define IL_VERSION_1_7_2 1 -#define IL_VERSION 172 - - -// Attribute Bits -#define IL_ORIGIN_BIT 0x00000001 -#define IL_FILE_BIT 0x00000002 -#define IL_PAL_BIT 0x00000004 -#define IL_FORMAT_BIT 0x00000008 -#define IL_TYPE_BIT 0x00000010 -#define IL_COMPRESS_BIT 0x00000020 -#define IL_LOADFAIL_BIT 0x00000040 -#define IL_FORMAT_SPECIFIC_BIT 0x00000080 -#define IL_ALL_ATTRIB_BITS 0x000FFFFF - - -// Palette types -#define IL_PAL_NONE 0x0400 -#define IL_PAL_RGB24 0x0401 -#define IL_PAL_RGB32 0x0402 -#define IL_PAL_RGBA32 0x0403 -#define IL_PAL_BGR24 0x0404 -#define IL_PAL_BGR32 0x0405 -#define IL_PAL_BGRA32 0x0406 - - -// Image types -#define IL_TYPE_UNKNOWN 0x0000 -#define IL_BMP 0x0420 -#define IL_CUT 0x0421 -#define IL_DOOM 0x0422 -#define IL_DOOM_FLAT 0x0423 -#define IL_ICO 0x0424 -#define IL_JPG 0x0425 -#define IL_JFIF 0x0425 -#define IL_LBM 0x0426 -#define IL_PCD 0x0427 -#define IL_PCX 0x0428 -#define IL_PIC 0x0429 -#define IL_PNG 0x042A -#define IL_PNM 0x042B -#define IL_SGI 0x042C -#define IL_TGA 0x042D -#define IL_TIF 0x042E -#define IL_CHEAD 0x042F -#define IL_RAW 0x0430 -#define IL_MDL 0x0431 -#define IL_WAL 0x0432 -#define IL_LIF 0x0434 -#define IL_MNG 0x0435 -#define IL_JNG 0x0435 -#define IL_GIF 0x0436 -#define IL_DDS 0x0437 -#define IL_DCX 0x0438 -#define IL_PSD 0x0439 -#define IL_EXIF 0x043A -#define IL_PSP 0x043B -#define IL_PIX 0x043C -#define IL_PXR 0x043D -#define IL_XPM 0x043E -#define IL_HDR 0x043F -#define IL_ICNS 0x0440 -#define IL_JP2 0x0441 -#define IL_EXR 0x0442 - - -#define IL_JASC_PAL 0x0475 - - -// Error Types -#define IL_NO_ERROR 0x0000 -#define IL_INVALID_ENUM 0x0501 -#define IL_OUT_OF_MEMORY 0x0502 -#define IL_FORMAT_NOT_SUPPORTED 0x0503 -#define IL_INTERNAL_ERROR 0x0504 -#define IL_INVALID_VALUE 0x0505 -#define IL_ILLEGAL_OPERATION 0x0506 -#define IL_ILLEGAL_FILE_VALUE 0x0507 -#define IL_INVALID_FILE_HEADER 0x0508 -#define IL_INVALID_PARAM 0x0509 -#define IL_COULD_NOT_OPEN_FILE 0x050A -#define IL_INVALID_EXTENSION 0x050B -#define IL_FILE_ALREADY_EXISTS 0x050C -#define IL_OUT_FORMAT_SAME 0x050D -#define IL_STACK_OVERFLOW 0x050E -#define IL_STACK_UNDERFLOW 0x050F -#define IL_INVALID_CONVERSION 0x0510 -#define IL_BAD_DIMENSIONS 0x0511 -#define IL_FILE_READ_ERROR 0x0512 // 05/12/2002: Addition by Sam. -#define IL_FILE_WRITE_ERROR 0x0512 - -#define IL_LIB_GIF_ERROR 0x05E1 -#define IL_LIB_JPEG_ERROR 0x05E2 -#define IL_LIB_PNG_ERROR 0x05E3 -#define IL_LIB_TIFF_ERROR 0x05E4 -#define IL_LIB_MNG_ERROR 0x05E5 -#define IL_LIB_JP2_ERROR 0x05E6 -#define IL_UNKNOWN_ERROR 0x05FF - - -// Origin Definitions -#define IL_ORIGIN_SET 0x0600 -#define IL_ORIGIN_LOWER_LEFT 0x0601 -#define IL_ORIGIN_UPPER_LEFT 0x0602 -#define IL_ORIGIN_MODE 0x0603 - - -// Format and Type Mode Definitions -#define IL_FORMAT_SET 0x0610 -#define IL_FORMAT_MODE 0x0611 -#define IL_TYPE_SET 0x0612 -#define IL_TYPE_MODE 0x0613 - - -// File definitions -#define IL_FILE_OVERWRITE 0x0620 -#define IL_FILE_MODE 0x0621 - - -// Palette definitions -#define IL_CONV_PAL 0x0630 - - -// Load fail definitions -#define IL_DEFAULT_ON_FAIL 0x0632 - - -// Key colour definitions -#define IL_USE_KEY_COLOUR 0x0635 -#define IL_USE_KEY_COLOR 0x0635 - - -// Interlace definitions -#define IL_SAVE_INTERLACED 0x0639 -#define IL_INTERLACE_MODE 0x063A - - -// Quantization definitions -#define IL_QUANTIZATION_MODE 0x0640 -#define IL_WU_QUANT 0x0641 -#define IL_NEU_QUANT 0x0642 -#define IL_NEU_QUANT_SAMPLE 0x0643 -#define IL_MAX_QUANT_INDEXS 0x0644 //XIX : ILint : Maximum number of colors to reduce to, default of 256. and has a range of 2-256 - - -// Hints -#define IL_FASTEST 0x0660 -#define IL_LESS_MEM 0x0661 -#define IL_DONT_CARE 0x0662 -#define IL_MEM_SPEED_HINT 0x0665 -#define IL_USE_COMPRESSION 0x0666 -#define IL_NO_COMPRESSION 0x0667 -#define IL_COMPRESSION_HINT 0x0668 - - -// Subimage types -#define IL_SUB_NEXT 0x0680 -#define IL_SUB_MIPMAP 0x0681 -#define IL_SUB_LAYER 0x0682 - - -// Compression definitions -#define IL_COMPRESS_MODE 0x0700 -#define IL_COMPRESS_NONE 0x0701 -#define IL_COMPRESS_RLE 0x0702 -#define IL_COMPRESS_LZO 0x0703 -#define IL_COMPRESS_ZLIB 0x0704 - - -// File format-specific values -#define IL_TGA_CREATE_STAMP 0x0710 -#define IL_JPG_QUALITY 0x0711 -#define IL_PNG_INTERLACE 0x0712 -#define IL_TGA_RLE 0x0713 -#define IL_BMP_RLE 0x0714 -#define IL_SGI_RLE 0x0715 -#define IL_TGA_ID_STRING 0x0717 -#define IL_TGA_AUTHNAME_STRING 0x0718 -#define IL_TGA_AUTHCOMMENT_STRING 0x0719 -#define IL_PNG_AUTHNAME_STRING 0x071A -#define IL_PNG_TITLE_STRING 0x071B -#define IL_PNG_DESCRIPTION_STRING 0x071C -#define IL_TIF_DESCRIPTION_STRING 0x071D -#define IL_TIF_HOSTCOMPUTER_STRING 0x071E -#define IL_TIF_DOCUMENTNAME_STRING 0x071F -#define IL_TIF_AUTHNAME_STRING 0x0720 -#define IL_JPG_SAVE_FORMAT 0x0721 -#define IL_CHEAD_HEADER_STRING 0x0722 -#define IL_PCD_PICNUM 0x0723 - -#define IL_PNG_ALPHA_INDEX 0x0724 //XIX : ILint : the color in the pallete at this index value (0-255) is considered transparent, -1 for no trasparent color - -// DXTC definitions -#define IL_DXTC_FORMAT 0x0705 -#define IL_DXT1 0x0706 -#define IL_DXT2 0x0707 -#define IL_DXT3 0x0708 -#define IL_DXT4 0x0709 -#define IL_DXT5 0x070A -#define IL_DXT_NO_COMP 0x070B -#define IL_KEEP_DXTC_DATA 0x070C -#define IL_DXTC_DATA_FORMAT 0x070D -#define IL_3DC 0x070E -#define IL_RXGB 0x070F -#define IL_ATI1N 0x0710 - -// Cube map definitions -#define IL_CUBEMAP_POSITIVEX 0x00000400 -#define IL_CUBEMAP_NEGATIVEX 0x00000800 -#define IL_CUBEMAP_POSITIVEY 0x00001000 -#define IL_CUBEMAP_NEGATIVEY 0x00002000 -#define IL_CUBEMAP_POSITIVEZ 0x00004000 -#define IL_CUBEMAP_NEGATIVEZ 0x00008000 - - -// Values -#define IL_VERSION_NUM 0x0DE2 -#define IL_IMAGE_WIDTH 0x0DE4 -#define IL_IMAGE_HEIGHT 0x0DE5 -#define IL_IMAGE_DEPTH 0x0DE6 -#define IL_IMAGE_SIZE_OF_DATA 0x0DE7 -#define IL_IMAGE_BPP 0x0DE8 -#define IL_IMAGE_BYTES_PER_PIXEL 0x0DE8 -#define IL_IMAGE_BPP 0x0DE8 -#define IL_IMAGE_BITS_PER_PIXEL 0x0DE9 -#define IL_IMAGE_FORMAT 0x0DEA -#define IL_IMAGE_TYPE 0x0DEB -#define IL_PALETTE_TYPE 0x0DEC -#define IL_PALETTE_SIZE 0x0DED -#define IL_PALETTE_BPP 0x0DEE -#define IL_PALETTE_NUM_COLS 0x0DEF -#define IL_PALETTE_BASE_TYPE 0x0DF0 -#define IL_NUM_IMAGES 0x0DF1 -#define IL_NUM_MIPMAPS 0x0DF2 -#define IL_NUM_LAYERS 0x0DF3 -#define IL_ACTIVE_IMAGE 0x0DF4 -#define IL_ACTIVE_MIPMAP 0x0DF5 -#define IL_ACTIVE_LAYER 0x0DF6 -#define IL_CUR_IMAGE 0x0DF7 -#define IL_IMAGE_DURATION 0x0DF8 -#define IL_IMAGE_PLANESIZE 0x0DF9 -#define IL_IMAGE_BPC 0x0DFA -#define IL_IMAGE_OFFX 0x0DFB -#define IL_IMAGE_OFFY 0x0DFC -#define IL_IMAGE_CUBEFLAGS 0x0DFD -#define IL_IMAGE_ORIGIN 0x0DFE -#define IL_IMAGE_CHANNELS 0x0DFF - -# if defined __GNUC__ && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)) -// __attribute__((deprecated)) is supported by GCC 3.1 and later. -# define DEPRECATED(D) D __attribute__((deprecated)) -# elif defined _MSC_VER && _MSC_VER >= 1300 -// __declspec(deprecated) is supported by MSVC 7.0 and later. -# define DEPRECATED(D) __declspec(deprecated) D -# else -# define DEPRECATED (D) D -# endif - -// -// Section shamelessly modified from the glut header. -// - -// This is from Win32's -#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) - #define ILAPIENTRY __stdcall - #define IL_PACKSTRUCT -//#elif defined(linux) || defined(MACOSX) || defined(__CYGWIN__) //fix bug 840364 -#elif defined( __GNUC__ ) - // this should work for any of the above commented platforms - // plus any platform using GCC - #ifdef __MINGW32__ - #define ILAPIENTRY __stdcall - #else - #define ILAPIENTRY - #endif - #define IL_PACKSTRUCT __attribute__ ((packed)) -#else - #define ILAPIENTRY - #define IL_PACKSTRUCT -#endif - -// This is from Win32's and -#if defined(__LCC__) - #define ILAPI __stdcall -#elif defined(_WIN32) //changed 20031221 to fix bug 840421 - #ifdef IL_STATIC_LIB - #define ILAPI - #else - #ifdef _IL_BUILD_LIBRARY - #define ILAPI __declspec(dllexport) - #else - #define ILAPI __declspec(dllimport) - #endif - #endif -#elif __APPLE__ - #define ILAPI extern -#else - #define ILAPI -#endif - - -#define IL_SEEK_SET 0 -#define IL_SEEK_CUR 1 -#define IL_SEEK_END 2 -#define IL_EOF -1 - - -// Callback functions for file reading -typedef void* ILHANDLE; -typedef ILvoid (ILAPIENTRY *fCloseRProc)(ILHANDLE); -typedef ILboolean (ILAPIENTRY *fEofProc) (ILHANDLE); -typedef ILint (ILAPIENTRY *fGetcProc) (ILHANDLE); -typedef ILHANDLE (ILAPIENTRY *fOpenRProc) (ILconst_string); -typedef ILint (ILAPIENTRY *fReadProc) (void*, ILuint, ILuint, ILHANDLE); -typedef ILint (ILAPIENTRY *fSeekRProc) (ILHANDLE, ILint, ILint); -typedef ILint (ILAPIENTRY *fTellRProc) (ILHANDLE); - -// Callback functions for file writing -typedef ILvoid (ILAPIENTRY *fCloseWProc)(ILHANDLE); -typedef ILHANDLE (ILAPIENTRY *fOpenWProc) (ILconst_string); -typedef ILint (ILAPIENTRY *fPutcProc) (ILubyte, ILHANDLE); -typedef ILint (ILAPIENTRY *fSeekWProc) (ILHANDLE, ILint, ILint); -typedef ILint (ILAPIENTRY *fTellWProc) (ILHANDLE); -typedef ILint (ILAPIENTRY *fWriteProc) (const void*, ILuint, ILuint, ILHANDLE); - -// Callback functions for allocation and deallocation -typedef ILvoid* (ILAPIENTRY *mAlloc)(const ILuint); -typedef ILvoid (ILAPIENTRY *mFree) (const ILvoid* CONST_RESTRICT); - -// Registered format procedures -typedef ILenum (ILAPIENTRY *IL_LOADPROC)(ILconst_string); -typedef ILenum (ILAPIENTRY *IL_SAVEPROC)(ILconst_string); - - -// ImageLib Functions -ILAPI ILboolean ILAPIENTRY ilActiveImage(ILuint Number); -ILAPI ILboolean ILAPIENTRY ilActiveLayer(ILuint Number); -ILAPI ILboolean ILAPIENTRY ilActiveMipmap(ILuint Number); -ILAPI ILboolean ILAPIENTRY ilApplyPal(ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY ilApplyProfile(ILstring InProfile, ILstring OutProfile); -ILAPI ILvoid ILAPIENTRY ilBindImage(ILuint Image); -ILAPI ILboolean ILAPIENTRY ilBlit(ILuint Source, ILint DestX, ILint DestY, ILint DestZ, ILuint SrcX, ILuint SrcY, ILuint SrcZ, ILuint Width, ILuint Height, ILuint Depth); -ILAPI ILvoid ILAPIENTRY ilClearColour(ILclampf Red, ILclampf Green, ILclampf Blue, ILclampf Alpha); -ILAPI ILboolean ILAPIENTRY ilClearImage(void); -ILAPI ILuint ILAPIENTRY ilCloneCurImage(void); -ILAPI ILboolean ILAPIENTRY ilCompressFunc(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilConvertImage(ILenum DestFormat, ILenum DestType); -ILAPI ILboolean ILAPIENTRY ilConvertPal(ILenum DestFormat); -ILAPI ILboolean ILAPIENTRY ilCopyImage(ILuint Src); -ILAPI ILuint ILAPIENTRY ilCopyPixels(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILuint ILAPIENTRY ilCreateSubImage(ILenum Type, ILuint Num); -ILAPI ILboolean ILAPIENTRY ilDefaultImage(void); -ILAPI ILvoid ILAPIENTRY ilDeleteImage(const ILuint Num); -ILAPI ILvoid ILAPIENTRY ilDeleteImages(ILsizei Num, const ILuint *Images); -ILAPI ILboolean ILAPIENTRY ilDisable(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilEnable(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilFormatFunc(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilGenImages(ILsizei Num, ILuint *Images); -ILAPI ILint ILAPIENTRY ilGenImage(); -ILAPI ILubyte* ILAPIENTRY ilGetAlpha(ILenum Type); -ILAPI ILboolean ILAPIENTRY ilGetBoolean(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilGetBooleanv(ILenum Mode, ILboolean *Param); -ILAPI ILubyte* ILAPIENTRY ilGetData(void); -ILAPI ILuint ILAPIENTRY ilGetDXTCData(ILvoid *Buffer, ILuint BufferSize, ILenum DXTCFormat); -ILAPI ILenum ILAPIENTRY ilGetError(void); -ILAPI ILint ILAPIENTRY ilGetInteger(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilGetIntegerv(ILenum Mode, ILint *Param); -ILAPI ILuint ILAPIENTRY ilGetLumpPos(ILvoid); -ILAPI ILubyte* ILAPIENTRY ilGetPalette(ILvoid); -ILAPI ILstring ILAPIENTRY ilGetString(ILenum StringName); -ILAPI ILvoid ILAPIENTRY ilHint(ILenum Target, ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilInit(void); -ILAPI ILboolean ILAPIENTRY ilIsDisabled(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilIsEnabled(ILenum Mode); -ILAPI ILenum ILAPIENTRY ilDetermineTypeF(ILHANDLE File); -ILAPI ILboolean ILAPIENTRY ilIsImage(ILuint Image); -ILAPI ILboolean ILAPIENTRY ilIsValid(ILenum Type, ILstring FileName); -ILAPI ILboolean ILAPIENTRY ilIsValidF(ILenum Type, ILHANDLE File); -ILAPI ILboolean ILAPIENTRY ilIsValidL(ILenum Type, ILvoid *Lump, ILuint Size); -ILAPI ILvoid ILAPIENTRY ilKeyColour(ILclampf Red, ILclampf Green, ILclampf Blue, ILclampf Alpha); -ILAPI ILboolean ILAPIENTRY ilLoad(ILenum Type, ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY ilLoadF(ILenum Type, ILHANDLE File); -ILAPI ILboolean ILAPIENTRY ilLoadImage(ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY ilLoadL(ILenum Type, const ILvoid *Lump, ILuint Size); -ILAPI ILboolean ILAPIENTRY ilLoadPal(ILconst_string FileName); -ILAPI ILvoid ILAPIENTRY ilModAlpha( ILdouble AlphaValue ); -ILAPI ILboolean ILAPIENTRY ilOriginFunc(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilOverlayImage(ILuint Source, ILint XCoord, ILint YCoord, ILint ZCoord); -ILAPI ILvoid ILAPIENTRY ilPopAttrib(void); -ILAPI ILvoid ILAPIENTRY ilPushAttrib(ILuint Bits); -ILAPI ILvoid ILAPIENTRY ilRegisterFormat(ILenum Format); -ILAPI ILboolean ILAPIENTRY ilRegisterLoad(ILconst_string Ext, IL_LOADPROC Load); -ILAPI ILboolean ILAPIENTRY ilRegisterMipNum(ILuint Num); -ILAPI ILboolean ILAPIENTRY ilRegisterNumImages(ILuint Num); -ILAPI ILvoid ILAPIENTRY ilRegisterOrigin(ILenum Origin); -ILAPI ILvoid ILAPIENTRY ilRegisterPal(ILvoid *Pal, ILuint Size, ILenum Type); -ILAPI ILboolean ILAPIENTRY ilRegisterSave(ILconst_string Ext, IL_SAVEPROC Save); -ILAPI ILvoid ILAPIENTRY ilRegisterType(ILenum Type); -ILAPI ILboolean ILAPIENTRY ilRemoveLoad(ILconst_string Ext); -ILAPI ILboolean ILAPIENTRY ilRemoveSave(ILconst_string Ext); -ILAPI ILvoid ILAPIENTRY ilResetMemory(void); // Deprecated -ILAPI ILvoid ILAPIENTRY ilResetRead(void); -ILAPI ILvoid ILAPIENTRY ilResetWrite(void); -ILAPI ILboolean ILAPIENTRY ilSave(ILenum Type, ILstring FileName); -ILAPI ILuint ILAPIENTRY ilSaveF(ILenum Type, ILHANDLE File); -ILAPI ILboolean ILAPIENTRY ilSaveImage(ILconst_string FileName); -ILAPI ILuint ILAPIENTRY ilSaveL(ILenum Type, ILvoid *Lump, ILuint Size); -ILAPI ILboolean ILAPIENTRY ilSavePal(ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY ilSetAlpha( ILdouble AlphaValue ); -ILAPI ILboolean ILAPIENTRY ilSetData(ILvoid *Data); -ILAPI ILboolean ILAPIENTRY ilSetDuration(ILuint Duration); -ILAPI ILvoid ILAPIENTRY ilSetInteger(ILenum Mode, ILint Param); -ILAPI ILvoid ILAPIENTRY ilSetMemory(mAlloc, mFree); -ILAPI ILvoid ILAPIENTRY ilSetPixels(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILvoid ILAPIENTRY ilSetRead(fOpenRProc, fCloseRProc, fEofProc, fGetcProc, fReadProc, fSeekRProc, fTellRProc); -ILAPI ILvoid ILAPIENTRY ilSetString(ILenum Mode, const char *String); -ILAPI ILvoid ILAPIENTRY ilSetWrite(fOpenWProc, fCloseWProc, fPutcProc, fSeekWProc, fTellWProc, fWriteProc); -ILAPI ILvoid ILAPIENTRY ilShutDown(void); -ILAPI ILboolean ILAPIENTRY ilTexImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte numChannels, ILenum Format, ILenum Type, ILvoid *Data); -ILAPI ILenum ILAPIENTRY ilTypeFromExt(ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY ilTypeFunc(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilLoadData(ILconst_string FileName, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp); -ILAPI ILboolean ILAPIENTRY ilLoadDataF(ILHANDLE File, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp); -ILAPI ILboolean ILAPIENTRY ilLoadDataL(ILvoid *Lump, ILuint Size, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp); -ILAPI ILboolean ILAPIENTRY ilSaveData(ILconst_string FileName); - -// For all those weirdos that spell "colour" without the 'u'. -#define ilClearColor ilClearColour -#define ilKeyColor ilKeyColour - - -#ifdef __cplusplus -} -#endif - -#endif // __IL_H__ -#endif // __il_h__ - -#define imemclear(x,y) memset(x,0,y); diff --git a/win32/devil/include/IL/il_wrap.h b/win32/devil/include/IL/il_wrap.h deleted file mode 100644 index 5cf9b0e0a..000000000 --- a/win32/devil/include/IL/il_wrap.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef WRAPPER_H -#define WRAPPER_H - -/*#include -#include */ -#include // Probably only have to #include this one - -#ifdef _MSC_VER - #ifndef _IL_WRAP_BUILD_LIB - #pragma comment(lib, "il_wrap.lib") - #endif -#endif - -class ilImage -{ -public: - ilImage(); - ilImage(char *); - ilImage(const ilImage &); - virtual ~ilImage(); - - ILboolean Load(char *); - ILboolean Load(char *, ILenum); - ILboolean Save(char *); - ILboolean Save(char *, ILenum); - - - // ImageLib functions - ILboolean ActiveImage(ILuint); - ILboolean ActiveLayer(ILuint); - ILboolean ActiveMipmap(ILuint); - ILboolean Clear(void); - ILvoid ClearColour(ILclampf, ILclampf, ILclampf, ILclampf); - ILboolean Convert(ILenum); - ILboolean Copy(ILuint); - ILboolean Default(void); - ILboolean Flip(void); - ILboolean SwapColours(void); - ILboolean Resize(ILuint, ILuint, ILuint); - ILboolean TexImage(ILuint, ILuint, ILuint, ILubyte, ILenum, ILenum, ILvoid*); - - - // Image handling - ILvoid Bind(void) const; - ILvoid Bind(ILuint); - ILvoid Close(void) { this->Delete(); } - ILvoid Delete(void); - ILvoid iGenBind(); - ILenum PaletteAlphaIndex(); - - // Image characteristics - ILuint Width(void); - ILuint Height(void); - ILuint Depth(void); - ILubyte Bpp(void); - ILubyte Bitpp(void); - ILenum PaletteType(void); - ILenum Format(void); - ILenum Type(void); - ILuint NumImages(void); - ILuint NumMipmaps(void); - ILuint GetId(void) const; - ILenum GetOrigin(void); - ILubyte *GetData(void); - ILubyte *GetPalette(void); - - - // Rendering - ILuint BindImage(void); - ILuint BindImage(ILenum); - - - // Operators - ilImage& operator = (ILuint); - ilImage& operator = (const ilImage &); - - -protected: - ILuint Id; - -private: - ILvoid iStartUp(); - - -}; - - -class ilFilters -{ -public: - static ILboolean Alienify(ilImage &); - static ILboolean BlurAvg(ilImage &, ILuint Iter); - static ILboolean BlurGaussian(ilImage &, ILuint Iter); - static ILboolean Contrast(ilImage &, ILfloat Contrast); - static ILboolean EdgeDetectE(ilImage &); - static ILboolean EdgeDetectP(ilImage &); - static ILboolean EdgeDetectS(ilImage &); - static ILboolean Emboss(ilImage &); - static ILboolean Gamma(ilImage &, ILfloat Gamma); - static ILboolean Negative(ilImage &); - static ILboolean Noisify(ilImage &, ILubyte Factor); - static ILboolean Pixelize(ilImage &, ILuint PixSize); - static ILboolean Saturate(ilImage &, ILfloat Saturation); - static ILboolean Saturate(ilImage &, ILfloat r, ILfloat g, ILfloat b, ILfloat Saturation); - static ILboolean ScaleColours(ilImage &, ILfloat r, ILfloat g, ILfloat b); - static ILboolean Sharpen(ilImage &, ILfloat Factor, ILuint Iter); -}; - - -#ifdef ILUT_USE_OPENGL -class ilOgl -{ -public: - static ILvoid Init(void); - static GLuint BindTex(ilImage &); - static ILboolean Upload(ilImage &, ILuint); - static GLuint Mipmap(ilImage &); - static ILboolean Screen(void); - static ILboolean Screenie(void); -}; -#endif//ILUT_USE_OPENGL - - -#ifdef ILUT_USE_ALLEGRO -class ilAlleg -{ -public: - static ILvoid Init(void); - static BITMAP *Convert(ilImage &); -}; -#endif//ILUT_USE_ALLEGRO - - -#ifdef ILUT_USE_WIN32 -class ilWin32 -{ -public: - static ILvoid Init(void); - static HBITMAP Convert(ilImage &); - static ILboolean GetClipboard(ilImage &); - static ILvoid GetInfo(ilImage &, BITMAPINFO *Info); - static ILubyte *GetPadData(ilImage &); - static HPALETTE GetPal(ilImage &); - static ILboolean GetResource(ilImage &, HINSTANCE hInst, ILint ID, char *ResourceType); - static ILboolean GetResource(ilImage &, HINSTANCE hInst, ILint ID, char *ResourceType, ILenum Type); - static ILboolean SetClipboard(ilImage &); -}; -#endif//ILUT_USE_WIN32 - - -class ilValidate -{ -public: - static ILboolean Valid(ILenum, char *); - static ILboolean Valid(ILenum, FILE *); - static ILboolean Valid(ILenum, ILvoid *, ILuint); - -protected: - -private: - -}; - - -class ilState -{ -public: - static ILboolean Disable(ILenum); - static ILboolean Enable(ILenum); - static ILvoid Get(ILenum, ILboolean &); - static ILvoid Get(ILenum, ILint &); - static ILboolean GetBool(ILenum); - static ILint GetInt(ILenum); - static const char *GetString(ILenum); - static ILboolean IsDisabled(ILenum); - static ILboolean IsEnabled(ILenum); - static ILboolean Origin(ILenum); - static ILvoid Pop(void); - static ILvoid Push(ILuint); - - -protected: - -private: - -}; - - -class ilError -{ -public: - static ILvoid Check(ILvoid (*Callback)(const char*)); - static ILvoid Check(ILvoid (*Callback)(ILenum)); - static ILenum Get(void); - static const char *String(void); - static const char *String(ILenum); - -protected: - -private: - -}; - - -#endif//WRAPPER_H diff --git a/win32/devil/include/IL/ilu.h b/win32/devil/include/IL/ilu.h deleted file mode 100644 index 846715959..000000000 --- a/win32/devil/include/IL/ilu.h +++ /dev/null @@ -1,180 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Utility Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: IL/ilu.h -// -// Description: The main include file for ILU -// -//----------------------------------------------------------------------------- - - -#ifndef __ilu_h_ -#ifndef __ILU_H__ - -#define __ilu_h_ -#define __ILU_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) && (!defined(_IL_BUILD_LIBRARY)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "ILU.lib") - #endif - #endif -#endif - - -#define ILU_VERSION_1_7_2 1 -#define ILU_VERSION 172 - - -#define ILU_FILTER 0x2600 -#define ILU_NEAREST 0x2601 -#define ILU_LINEAR 0x2602 -#define ILU_BILINEAR 0x2603 -#define ILU_SCALE_BOX 0x2604 -#define ILU_SCALE_TRIANGLE 0x2605 -#define ILU_SCALE_BELL 0x2606 -#define ILU_SCALE_BSPLINE 0x2607 -#define ILU_SCALE_LANCZOS3 0x2608 -#define ILU_SCALE_MITCHELL 0x2609 - - -// Error types -#define ILU_INVALID_ENUM 0x0501 -#define ILU_OUT_OF_MEMORY 0x0502 -#define ILU_INTERNAL_ERROR 0x0504 -#define ILU_INVALID_VALUE 0x0505 -#define ILU_ILLEGAL_OPERATION 0x0506 -#define ILU_INVALID_PARAM 0x0509 - - -// Values -#define ILU_PLACEMENT 0x0700 -#define ILU_LOWER_LEFT 0x0701 -#define ILU_LOWER_RIGHT 0x0702 -#define ILU_UPPER_LEFT 0x0703 -#define ILU_UPPER_RIGHT 0x0704 -#define ILU_CENTER 0x0705 -#define ILU_CONVOLUTION_MATRIX 0x0710 - -#define ILU_VERSION_NUM IL_VERSION_NUM -#define ILU_VENDOR IL_VENDOR - - -// Filters -/* -#define ILU_FILTER_BLUR 0x0803 -#define ILU_FILTER_GAUSSIAN_3x3 0x0804 -#define ILU_FILTER_GAUSSIAN_5X5 0x0805 -#define ILU_FILTER_EMBOSS1 0x0807 -#define ILU_FILTER_EMBOSS2 0x0808 -#define ILU_FILTER_LAPLACIAN1 0x080A -#define ILU_FILTER_LAPLACIAN2 0x080B -#define ILU_FILTER_LAPLACIAN3 0x080C -#define ILU_FILTER_LAPLACIAN4 0x080D -#define ILU_FILTER_SHARPEN1 0x080E -#define ILU_FILTER_SHARPEN2 0x080F -#define ILU_FILTER_SHARPEN3 0x0810 -*/ - - -typedef struct ILinfo -{ - ILuint Id; // the image's id - ILubyte *Data; // the image's data - ILuint Width; // the image's width - ILuint Height; // the image's height - ILuint Depth; // the image's depth - ILubyte Bpp; // bytes per pixel (not bits) of the image - ILuint SizeOfData; // the total size of the data (in bytes) - ILenum Format; // image format (in IL enum style) - ILenum Type; // image type (in IL enum style) - ILenum Origin; // origin of the image - ILubyte *Palette; // the image's palette - ILenum PalType; // palette type - ILuint PalSize; // palette size - ILenum CubeFlags; // flags for what cube map sides are present - ILuint NumNext; // number of images following - ILuint NumMips; // number of mipmaps - ILuint NumLayers; // number of layers -} ILinfo; - - -typedef struct ILpointf { - ILfloat x; - ILfloat y; -} ILpointf; - -typedef struct ILpointi { - ILint x; - ILint y; -} ILpointi; - -ILAPI ILboolean ILAPIENTRY iluAlienify(void); -ILAPI ILboolean ILAPIENTRY iluBlurAvg(ILuint Iter); -ILAPI ILboolean ILAPIENTRY iluBlurGaussian(ILuint Iter); -ILAPI ILboolean ILAPIENTRY iluBuildMipmaps(void); -ILAPI ILuint ILAPIENTRY iluColoursUsed(void); -ILAPI ILboolean ILAPIENTRY iluCompareImage(ILuint Comp); -ILAPI ILboolean ILAPIENTRY iluContrast(ILfloat Contrast); -ILAPI ILboolean ILAPIENTRY iluCrop(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth); -ILAPI ILvoid ILAPIENTRY iluDeleteImage(ILuint Id); // Deprecated -ILAPI ILboolean ILAPIENTRY iluEdgeDetectE(void); -ILAPI ILboolean ILAPIENTRY iluEdgeDetectP(void); -ILAPI ILboolean ILAPIENTRY iluEdgeDetectS(void); -ILAPI ILboolean ILAPIENTRY iluEmboss(void); -ILAPI ILboolean ILAPIENTRY iluEnlargeCanvas(ILuint Width, ILuint Height, ILuint Depth); -ILAPI ILboolean ILAPIENTRY iluEnlargeImage(ILfloat XDim, ILfloat YDim, ILfloat ZDim); -ILAPI ILboolean ILAPIENTRY iluEqualize(void); -ILAPI ILstring ILAPIENTRY iluErrorString(ILenum Error); -ILAPI ILboolean ILAPIENTRY iluConvolution(ILint *matrix, ILint scale, ILint bias); -ILAPI ILboolean ILAPIENTRY iluFlipImage(void); -ILAPI ILboolean ILAPIENTRY iluGammaCorrect(ILfloat Gamma); -ILAPI ILuint ILAPIENTRY iluGenImage(void); // Deprecated -ILAPI ILvoid ILAPIENTRY iluGetImageInfo(ILinfo *Info); -ILAPI ILint ILAPIENTRY iluGetInteger(ILenum Mode); -ILAPI ILvoid ILAPIENTRY iluGetIntegerv(ILenum Mode, ILint *Param); -ILAPI ILstring ILAPIENTRY iluGetString(ILenum StringName); -ILAPI ILvoid ILAPIENTRY iluImageParameter(ILenum PName, ILenum Param); -ILAPI ILvoid ILAPIENTRY iluInit(void); -ILAPI ILboolean ILAPIENTRY iluInvertAlpha(void); -ILAPI ILuint ILAPIENTRY iluLoadImage(ILconst_string FileName); -ILAPI ILboolean ILAPIENTRY iluMirror(void); -ILAPI ILboolean ILAPIENTRY iluNegative(void); -ILAPI ILboolean ILAPIENTRY iluNoisify(ILclampf Tolerance); -ILAPI ILboolean ILAPIENTRY iluPixelize(ILuint PixSize); -ILAPI ILvoid ILAPIENTRY iluRegionfv(ILpointf *Points, ILuint n); -ILAPI ILvoid ILAPIENTRY iluRegioniv(ILpointi *Points, ILuint n); -ILAPI ILboolean ILAPIENTRY iluReplaceColour(ILubyte Red, ILubyte Green, ILubyte Blue, ILfloat Tolerance); -ILAPI ILboolean ILAPIENTRY iluRotate(ILfloat Angle); -ILAPI ILboolean ILAPIENTRY iluRotate3D(ILfloat x, ILfloat y, ILfloat z, ILfloat Angle); -ILAPI ILboolean ILAPIENTRY iluSaturate1f(ILfloat Saturation); -ILAPI ILboolean ILAPIENTRY iluSaturate4f(ILfloat r, ILfloat g, ILfloat b, ILfloat Saturation); -ILAPI ILboolean ILAPIENTRY iluScale(ILuint Width, ILuint Height, ILuint Depth); -ILAPI ILboolean ILAPIENTRY iluScaleAlpha(ILfloat scale); -ILAPI ILboolean ILAPIENTRY iluScaleColours(ILfloat r, ILfloat g, ILfloat b); -ILAPI ILboolean ILAPIENTRY iluSharpen(ILfloat Factor, ILuint Iter); -ILAPI ILboolean ILAPIENTRY iluSwapColours(void); -ILAPI ILboolean ILAPIENTRY iluWave(ILfloat Angle); - -#define iluColorsUsed iluColoursUsed -#define iluSwapColors iluSwapColours -#define iluReplaceColor iluReplaceColour -#define iluScaleColor iluScaleColour - -#ifdef __cplusplus -} -#endif - -#endif // __ILU_H__ -#endif // __ilu_h_ diff --git a/win32/devil/include/IL/ilu_region.h b/win32/devil/include/IL/ilu_region.h deleted file mode 100644 index b5b3adc2d..000000000 --- a/win32/devil/include/IL/ilu_region.h +++ /dev/null @@ -1,25 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Utility Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 07/09/2002 <--Y2K Compliant! =] -// -// Filename: src-ILU/src/ilu_region.h -// -// Description: Creates an image region. -// -//----------------------------------------------------------------------------- - -#ifndef ILU_REGION_H -#define ILU_REGION_H - -typedef struct Edge -{ - ILint yUpper; - ILfloat xIntersect, dxPerScan; - struct Edge *next; -} Edge; - - -#endif//ILU_REGION_H - diff --git a/win32/devil/include/IL/ilut.h b/win32/devil/include/IL/ilut.h deleted file mode 100644 index 48046a5e4..000000000 --- a/win32/devil/include/IL/ilut.h +++ /dev/null @@ -1,353 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Utility Toolkit Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: IL/ilut.h -// -// Description: The main include file for ILUT -// -//----------------------------------------------------------------------------- - - -#ifndef __ilut_h_ -#ifndef __ILUT_H__ - -#define __ilut_h_ -#define __ILUT_H__ - -#include -#include - - -//----------------------------------------------------------------------------- -// Defines -//----------------------------------------------------------------------------- - -#define ILUT_VERSION_1_7_2 1 -#define ILUT_VERSION 172 - - -// Attribute Bits -#define ILUT_OPENGL_BIT 0x00000001 -#define ILUT_D3D_BIT 0x00000002 -#define ILUT_ALL_ATTRIB_BITS 0x000FFFFF - - -// Error Types -#define ILUT_INVALID_ENUM 0x0501 -#define ILUT_OUT_OF_MEMORY 0x0502 -#define ILUT_INVALID_VALUE 0x0505 -#define ILUT_ILLEGAL_OPERATION 0x0506 -#define ILUT_INVALID_PARAM 0x0509 -#define ILUT_COULD_NOT_OPEN_FILE 0x050A -#define ILUT_STACK_OVERFLOW 0x050E -#define ILUT_STACK_UNDERFLOW 0x050F -#define ILUT_BAD_DIMENSIONS 0x0511 -#define ILUT_NOT_SUPPORTED 0x0550 - - -// State Definitions -#define ILUT_PALETTE_MODE 0x0600 -#define ILUT_OPENGL_CONV 0x0610 -#define ILUT_D3D_MIPLEVELS 0x0620 -#define ILUT_MAXTEX_WIDTH 0x0630 -#define ILUT_MAXTEX_HEIGHT 0x0631 -#define ILUT_MAXTEX_DEPTH 0x0632 -#define ILUT_GL_USE_S3TC 0x0634 -#define ILUT_D3D_USE_DXTC 0x0634 -#define ILUT_GL_GEN_S3TC 0x0635 -#define ILUT_D3D_GEN_DXTC 0x0635 -#define ILUT_S3TC_FORMAT 0x0705 -#define ILUT_DXTC_FORMAT 0x0705 -#define ILUT_D3D_POOL 0x0706 -#define ILUT_D3D_ALPHA_KEY_COLOR 0x0707 -#define ILUT_D3D_ALPHA_KEY_COLOUR 0x0707 -#define ILUT_FORCE_INTEGER_FORMAT 0x0636 - -//This new state does automatic texture target detection -//if enabled. Currently, only cubemap detection is supported. -//if the current image is no cubemap, the 2d texture is chosen. -#define ILUT_GL_AUTODETECT_TEXTURE_TARGET 0x0807 - - -// Values -#define ILUT_VERSION_NUM IL_VERSION_NUM -#define ILUT_VENDOR IL_VENDOR - -// The different rendering api's...more to be added later? -#define ILUT_OPENGL 0 -#define ILUT_ALLEGRO 1 -#define ILUT_WIN32 2 -#define ILUT_DIRECT3D8 3 -#define ILUT_DIRECT3D9 4 -#define ILUT_X11 5 - -/* -// Includes specific config -#ifdef DJGPP - #define ILUT_USE_ALLEGRO -#elif _WIN32_WCE - #define ILUT_USE_WIN32 -#elif _WIN32 - //#ifdef __GNUC__ //__CYGWIN32__ (Cygwin seems to not define this with DevIL builds) - #define ILUT_USE_WIN32 - #include "IL/config.h" - - // Temporary fix for the SDL main() linker bug. - //#ifdef ILUT_USE_SDL - //#undef ILUT_USE_SDL - //#endif//ILUT_USE_SDL - - //#else - // #define ILUT_USE_WIN32 - // #define ILUT_USE_OPENGL - // #define ILUT_USE_SDL - // #define ILUT_USE_DIRECTX8 - //#endif -#elif BEOS // Don't know the #define - #define ILUT_USE_BEOS - #define ILUT_USE_OPENGL -#elif MACOSX - #define ILUT_USE_OPENGL -#else - - // We are surely using a *nix so the configure script - // may have written the configured config.h header - #include "IL/config.h" -#endif -*/ - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) && (!defined(_IL_BUILD_LIBRARY)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "ILUT.lib") - #endif - #endif -#endif - - - - -#include "IL/config.h" - -////////////// -// Opengl -////////////// - -#ifdef ILUT_USE_OPENGL - #if defined(_MSC_VER) || defined(_WIN32) - //#define WIN32_LEAN_AND_MEAN - #include - #endif//_MSC_VER - - #ifdef __APPLE__ - #include - #include - #else - #include - #include - #endif//__APPLE__ -#endif - - -#ifdef ILUT_USE_WIN32 - //#define WIN32_LEAN_AND_MEAN - #include -#endif - - -// -// If we can avoid including these in all cases thing tend to break less -// and we can keep all of them defined as available -// -// Kriss -// - -// ImageLib Utility Toolkit's Allegro Functions -#ifdef ILUT_USE_ALLEGRO -// #include -#endif//ILUT_USE_ALLEGRO - -#ifdef ILUT_USE_SDL -// #include -#endif - -#ifdef ILUT_USE_DIRECTX8 -// #include -#endif//ILUT_USE_DIRECTX9 - -#ifdef ILUT_USE_DIRECTX9 -// #include -#endif//ILUT_USE_DIRECTX9 - -#ifdef ILUT_USE_X11 - #include - #include -#ifdef ILUT_USE_XSHM - #include - #include - #include -#endif//ILUT_USE_XSHM -#endif//ILUT_USE_X11 - - - -//----------------------------------------------------------------------------- -// Functions -//----------------------------------------------------------------------------- - -#ifdef __cplusplus -extern "C" { -#endif - -// ImageLib Utility Toolkit Functions -ILAPI ILboolean ILAPIENTRY ilutDisable(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilutEnable(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilutGetBoolean(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilutGetBooleanv(ILenum Mode, ILboolean *Param); -ILAPI ILint ILAPIENTRY ilutGetInteger(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilutGetIntegerv(ILenum Mode, ILint *Param); -ILAPI ILstring ILAPIENTRY ilutGetString(ILenum StringName); -ILAPI ILvoid ILAPIENTRY ilutInit(void); -ILAPI ILboolean ILAPIENTRY ilutIsDisabled(ILenum Mode); -ILAPI ILboolean ILAPIENTRY ilutIsEnabled(ILenum Mode); -ILAPI ILvoid ILAPIENTRY ilutPopAttrib(void); -ILAPI ILvoid ILAPIENTRY ilutPushAttrib(ILuint Bits); -ILAPI ILvoid ILAPIENTRY ilutSetInteger(ILenum Mode, ILint Param); - -ILAPI ILboolean ILAPIENTRY ilutRenderer(ILenum Renderer); - - -// ImageLib Utility Toolkit's OpenGL Functions -#ifdef ILUT_USE_OPENGL - ILAPI GLuint ILAPIENTRY ilutGLBindTexImage(); - ILAPI GLuint ILAPIENTRY ilutGLBindMipmaps(void); - ILAPI ILboolean ILAPIENTRY ilutGLBuildMipmaps(void); - ILAPI GLuint ILAPIENTRY ilutGLLoadImage(ILstring FileName); - ILAPI ILboolean ILAPIENTRY ilutGLScreen(void); - ILAPI ILboolean ILAPIENTRY ilutGLScreenie(void); - ILAPI ILboolean ILAPIENTRY ilutGLSaveImage(ILstring FileName, GLuint TexID); - ILAPI ILboolean ILAPIENTRY ilutGLSetTex(GLuint TexID); - ILAPI ILboolean ILAPIENTRY ilutGLTexImage(GLuint Level); - ILAPI ILboolean ILAPIENTRY ilutGLSubTex(GLuint TexID, ILuint XOff, ILuint YOff); -#endif//ILUT_USE_OPENGL - - -// ImageLib Utility Toolkit's Allegro Functions -#ifdef ILUT_USE_ALLEGRO - -#ifdef __cplusplus -} -#endif - #include -#ifdef __cplusplus -extern "C" { -#endif - - ILAPI BITMAP* ILAPIENTRY ilutAllegLoadImage(ILstring FileName); - ILAPI BITMAP* ILAPIENTRY ilutConvertToAlleg(PALETTE Pal); -#endif//ILUT_USE_ALLEGRO - - -// ImageLib Utility Toolkit's SDL Functions -#ifdef ILUT_USE_SDL - ILAPI struct SDL_Surface* ILAPIENTRY ilutConvertToSDLSurface(unsigned int flags); - ILAPI struct SDL_Surface* ILAPIENTRY ilutSDLSurfaceLoadImage(ILstring FileName); - ILAPI ILboolean ILAPIENTRY ilutSDLSurfaceFromBitmap(struct SDL_Surface *Bitmap); -#endif//ILUT_USE_SDL - - -// ImageLib Utility Toolkit's BeOS Functions -#ifdef ILUT_USE_BEOS - ILAPI BBitmap ILAPIENTRY ilutConvertToBBitmap(void); -#endif//ILUT_USE_BEOS - - -// ImageLib Utility Toolkit's Win32 GDI Functions -#ifdef ILUT_USE_WIN32 - ILAPI HBITMAP ILAPIENTRY ilutConvertToHBitmap(HDC hDC); - ILAPI HBITMAP ILAPIENTRY ilutConvertSliceToHBitmap(HDC hDC, ILuint slice); - ILAPI ILvoid ILAPIENTRY ilutFreePaddedData(ILubyte *Data); - ILAPI ILvoid ILAPIENTRY ilutGetBmpInfo(BITMAPINFO *Info); - ILAPI HPALETTE ILAPIENTRY ilutGetHPal(void); - ILAPI ILubyte* ILAPIENTRY ilutGetPaddedData(void); - ILAPI ILboolean ILAPIENTRY ilutGetWinClipboard(void); - ILAPI ILboolean ILAPIENTRY ilutLoadResource(HINSTANCE hInst, ILint ID, ILstring ResourceType, ILenum Type); - ILAPI ILboolean ILAPIENTRY ilutSetHBitmap(HBITMAP Bitmap); - ILAPI ILboolean ILAPIENTRY ilutSetHPal(HPALETTE Pal); - ILAPI ILboolean ILAPIENTRY ilutSetWinClipboard(void); - ILAPI HBITMAP ILAPIENTRY ilutWinLoadImage(ILstring FileName, HDC hDC); - ILAPI ILboolean ILAPIENTRY ilutWinLoadUrl(ILstring Url); - ILAPI ILboolean ILAPIENTRY ilutWinPrint(ILuint XPos, ILuint YPos, ILuint Width, ILuint Height, HDC hDC); - ILAPI ILboolean ILAPIENTRY ilutWinSaveImage(ILstring FileName, HBITMAP Bitmap); -#endif//ILUT_USE_WIN32 - -// ImageLib Utility Toolkit's DirectX 8 Functions -#ifdef ILUT_USE_DIRECTX8 -// ILAPI ILvoid ILAPIENTRY ilutD3D8MipFunc(ILuint NumLevels); - ILAPI struct IDirect3DTexture8* ILAPIENTRY ilutD3D8Texture(struct IDirect3DDevice8 *Device); - ILAPI struct IDirect3DVolumeTexture8* ILAPIENTRY ilutD3D8VolumeTexture(struct IDirect3DDevice8 *Device); - ILAPI ILboolean ILAPIENTRY ilutD3D8TexFromFile(struct IDirect3DDevice8 *Device, char *FileName, struct IDirect3DTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8VolTexFromFile(struct IDirect3DDevice8 *Device, char *FileName, struct IDirect3DVolumeTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8TexFromFileInMemory(struct IDirect3DDevice8 *Device, ILvoid *Lump, ILuint Size, struct IDirect3DTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8VolTexFromFileInMemory(struct IDirect3DDevice8 *Device, ILvoid *Lump, ILuint Size, struct IDirect3DVolumeTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8TexFromFileHandle(struct IDirect3DDevice8 *Device, ILHANDLE File, struct IDirect3DTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8VolTexFromFileHandle(struct IDirect3DDevice8 *Device, ILHANDLE File, struct IDirect3DVolumeTexture8 **Texture); - // These two are not tested yet. - ILAPI ILboolean ILAPIENTRY ilutD3D8TexFromResource(struct IDirect3DDevice8 *Device, HMODULE SrcModule, char *SrcResource, struct IDirect3DTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8VolTexFromResource(struct IDirect3DDevice8 *Device, HMODULE SrcModule, char *SrcResource, struct IDirect3DVolumeTexture8 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D8LoadSurface(struct IDirect3DDevice8 *Device, struct IDirect3DSurface8 *Surface); -#endif//ILUT_USE_DIRECTX8 - -#ifdef ILUT_USE_DIRECTX9 - #pragma warning(push) - #pragma warning(disable : 4115) // Disables 'named type definition in parentheses' warning -// ILAPI ILvoid ILAPIENTRY ilutD3D9MipFunc(ILuint NumLevels); - ILAPI struct IDirect3DTexture9* ILAPIENTRY ilutD3D9Texture (struct IDirect3DDevice9* Device); - ILAPI struct IDirect3DVolumeTexture9* ILAPIENTRY ilutD3D9VolumeTexture (struct IDirect3DDevice9* Device); - ILAPI struct IDirect3DCubeTexture9* ILAPIENTRY ilutD3D9CubeTexture (struct IDirect3DDevice9* Device); - - ILAPI ILboolean ILAPIENTRY ilutD3D9CubeTexFromFile(struct IDirect3DDevice9 *Device, char *FileName, struct IDirect3DCubeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileInMemory(struct IDirect3DDevice9 *Device, ILvoid *Lump, ILuint Size, struct IDirect3DCubeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileHandle(struct IDirect3DDevice9 *Device, ILHANDLE File, struct IDirect3DCubeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9CubeTexFromResource(struct IDirect3DDevice9 *Device, HMODULE SrcModule, char *SrcResource, struct IDirect3DCubeTexture9 **Texture); - - ILAPI ILboolean ILAPIENTRY ilutD3D9TexFromFile(struct IDirect3DDevice9 *Device, char *FileName, struct IDirect3DTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9VolTexFromFile(struct IDirect3DDevice9 *Device, char *FileName, struct IDirect3DVolumeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9TexFromFileInMemory(struct IDirect3DDevice9 *Device, ILvoid *Lump, ILuint Size, struct IDirect3DTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9VolTexFromFileInMemory(struct IDirect3DDevice9 *Device, ILvoid *Lump, ILuint Size, struct IDirect3DVolumeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9TexFromFileHandle(struct IDirect3DDevice9 *Device, ILHANDLE File, struct IDirect3DTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9VolTexFromFileHandle(struct IDirect3DDevice9 *Device, ILHANDLE File, struct IDirect3DVolumeTexture9 **Texture); - - // These two are not tested yet. - ILAPI ILboolean ILAPIENTRY ilutD3D9TexFromResource(struct IDirect3DDevice9 *Device, HMODULE SrcModule, char *SrcResource, struct IDirect3DTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9VolTexFromResource(struct IDirect3DDevice9 *Device, HMODULE SrcModule, char *SrcResource, struct IDirect3DVolumeTexture9 **Texture); - ILAPI ILboolean ILAPIENTRY ilutD3D9LoadSurface(struct IDirect3DDevice9 *Device, struct IDirect3DSurface9 *Surface); - #pragma warning(pop) -#endif//ILUT_USE_DIRECTX9 - - -#ifdef ILUT_USE_X11 - ILAPI XImage * ILAPIENTRY ilutXCreateImage( Display* ); - ILAPI Pixmap ILAPIENTRY ilutXCreatePixmap( Display*,Drawable ); - ILAPI XImage * ILAPIENTRY ilutXLoadImage( Display*,char* ); - ILAPI Pixmap ILAPIENTRY ilutXLoadPixmap( Display*,Drawable,char* ); -#ifdef ILUT_USE_XSHM - ILAPI XImage * ILAPIENTRY ilutXShmCreateImage( Display*,XShmSegmentInfo* ); - ILAPI void ILAPIENTRY ilutXShmDestroyImage( Display*,XImage*,XShmSegmentInfo* ); - ILAPI Pixmap ILAPIENTRY ilutXShmCreatePixmap( Display*,Drawable,XShmSegmentInfo* ); - ILAPI void ILAPIENTRY ilutXShmFreePixmap( Display*,Pixmap,XShmSegmentInfo* ); - ILAPI XImage * ILAPIENTRY ilutXShmLoadImage( Display*,char*,XShmSegmentInfo* ); - ILAPI Pixmap ILAPIENTRY ilutXShmLoadPixmap( Display*,Drawable,char*,XShmSegmentInfo* ); -#endif//ILUT_USE_XSHM -#endif//ILUT_USE_X11 - - -#ifdef __cplusplus -} -#endif - -#endif // __ILUT_H__ -#endif // __ilut_h_ diff --git a/win32/devil/include/altivec_common.h b/win32/devil/include/altivec_common.h deleted file mode 100644 index fb69075cc..000000000 --- a/win32/devil/include/altivec_common.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * altivec_typeconversion.h - * DevIL - * - * Created by Meloni Dario on 17/04/05. - * - */ - -#include "il_internal.h" - -#ifdef ALTIVEC_GCC -#ifndef ALTIVEC_COMMON -#define ALTIVEC_COMMON - -typedef union { - vector unsigned int vuint; - unsigned int suint[4]; - vector unsigned char vuchar; - unsigned char suchar[4]; - vector float vf; - float sf[4]; -} vector_t; - -// Loads 16 byte from the specified address, aligned or not -//vector unsigned char load_unaligned( unsigned char *buffer ); - -// Fills a vector with the specified value -vector float fill_vector_f( float value ); - -#define eround(v,x) (((int)((v/x)*10)%10) > 0 ? (v/x) : (v/x)+1) -#define eround16(v) eround(v,16) - -#endif -#endif diff --git a/win32/devil/include/altivec_typeconversion.h b/win32/devil/include/altivec_typeconversion.h deleted file mode 100644 index 95ec0e666..000000000 --- a/win32/devil/include/altivec_typeconversion.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * altivec_typeconversion.h - * DevIL - * - * Created by Meloni Dario on 24/04/05. - * - */ - -#include "altivec_common.h" -#ifdef ALTIVEC_GCC - -// data and newdata may be the same buffer - -// Used to convert RGB <-> BGR in various data types -void abc2cba_byte( ILubyte *data, ILuint length, ILubyte *newdata ); -void abc2cba_short( ILushort *data, ILuint length, ILushort *newdata ); -void abc2cba_int( ILuint *data, ILuint length, ILuint *newdata ); -#define abc2cba_float(x,y,z) abc2cba_int(((ILuint*)(x)),y,((ILuint*)(z))) -void abc2cba_double( ILdouble *data, ILuint length, ILdouble *newdata ); - -// Used to convert RGBA <-> BGRA in various data types -void abcd2cbad_byte( ILubyte *data, ILuint length, ILubyte *newdata ); -void abcd2cbad_short( ILushort *data, ILuint length, ILushort *newdata ); -void abcd2cbad_int( ILuint *data, ILuint length, ILuint *newdata ); -#define abcd2cbad_float(x,y,z) abcd2cbad_int(((ILuint*)(x)),y,((ILuint*)(z))) -void abcd2cbad_double( ILdouble *data, ILuint length, ILdouble *newdata ); - -#endif diff --git a/win32/devil/include/config.h b/win32/devil/include/config.h deleted file mode 100644 index 729cf7269..000000000 --- a/win32/devil/include/config.h +++ /dev/null @@ -1,126 +0,0 @@ -/* include/IL/config.h. Generated by configure. */ -/* include/IL/config.h.in. Generated from configure.in by autoheader. */ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -/* Supported images formats (il) */ - -/* #undef IL_NO_BMP */ -#define IL_NO_CUT -#define IL_NO_CHEAD -#define IL_NO_DCX -/* #undef IL_NO_DDS */ -/* #undef IL_NO_DOOM */ -//#define IL_NO_GIF -#define IL_NO_HDR -#define IL_NO_ICO -#define IL_NO_ICNS -#define IL_NO_JP2 -//#define IL_NO_JPG -#define IL_NO_LCMS -#define IL_NO_LIF -#define IL_NO_MDL -#define IL_NO_MNG -#define IL_NO_PCD -#define IL_NO_PCX -#define IL_NO_PIC -#define IL_NO_PIX -//#define IL_NO_PNG -#define IL_NO_PNM -#define IL_NO_PSD -#define IL_NO_PSP -#define IL_NO_PXR -#define IL_NO_RAW -#define IL_NO_SGI -/* #undef IL_NO_TGA */ -#define IL_NO_TIF -#define IL_NO_WAL -#define IL_NO_XPM -#define IL_NO_EXR -#define IL_USE_JPEGLIB_UNMODIFIED 1 - -/* Supported api (ilut) */ - - -// -// sorry just -// cant get this one to work under windows -// have disabled for the now -// -// will look at it some more later -// -// Kriss -// -#undef ILUT_USE_ALLEGRO - -#undef ILUT_USE_DIRECTX8 -#define ILUT_USE_DIRECTX9 -#define ILUT_USE_OPENGL -#undef ILUT_USE_SDL -#define ILUT_USE_WIN32 - - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -//#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -//#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -//#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -//#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define IL_PACKAGE "DevIL" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define IL_PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define IL_PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define IL_PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define IL_PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -//#define IL_VERSION "1.7.2" - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* If using Mac OS X uncomment this line */ -/* #include "macconfig.h" */ - -/* Define to 1 if the X Window System is missing or not being used. */ -/* #undef X_DISPLAY_MISSING */ -#endif /* __CONFIG_H__ */ diff --git a/win32/devil/include/il_alloc.h b/win32/devil/include/il_alloc.h deleted file mode 100644 index b8963e5db..000000000 --- a/win32/devil/include/il_alloc.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef ALLOC_H -#define ALLOC_H - -/*#if defined(_WIN32) && defined(_MEM_DEBUG) - void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line); - void *m_alloc(unsigned long size, const char *file, unsigned long line); - void f_ree(void *ptr); - - #ifdef malloc - #undef malloc - #endif - - #ifdef calloc - #undef calloc - #endif - - #ifdef free - #undef free - #endif - - - #define malloc(size) m_alloc(size, __FILE__, __LINE__) - #define calloc(size, num) c_alloc(size, num, __FILE__, __LINE__) - #define free(addr) f_ree(addr) -#endif//defined(_WIN32) && defined(_MEM_DEBUG)*/ - - -#if defined (__ALLOC_C) - #define __ALLOC_EXTERN -#else - #define __ALLOC_EXTERN extern -#endif -#include - - -__ALLOC_EXTERN mAlloc ialloc_ptr; -__ALLOC_EXTERN mFree ifree_ptr; - - - -#endif//ALLOC_H diff --git a/win32/devil/include/il_bits.h b/win32/devil/include/il_bits.h deleted file mode 100644 index eeea9fce5..000000000 --- a/win32/devil/include/il_bits.h +++ /dev/null @@ -1,43 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_bits.h -// -// Description: Implements a file class that reads/writes bits directly. -// -//----------------------------------------------------------------------------- - - -#ifndef BITS_H -#define BITS_H - -#include "il_internal.h" - - -// Struct for dealing with reading bits from a file -typedef struct BITFILE -{ - ILHANDLE File; - ILuint BitPos; - ILint ByteBitOff; - ILubyte Buff; -} BITFILE; - -// Functions for reading bits from a file -//BITFILE* bopen(const char *FileName, const char *Mode); -ILint bclose(BITFILE *BitFile); -BITFILE* bfile(ILHANDLE File); -ILint btell(BITFILE *BitFile); -ILint bseek(BITFILE *BitFile, ILuint Offset, ILuint Mode); -ILint bread(ILvoid *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile); -//ILint bwrite(ILvoid *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile); - -// Useful macros for manipulating bits -#define SetBits(var, bits) (var |= bits) -#define ClearBits(var, bits) (var &= ~(bits)) - - -#endif//BITS_H diff --git a/win32/devil/include/il_bmp.h b/win32/devil/include/il_bmp.h deleted file mode 100644 index 4e296dbe3..000000000 --- a/win32/devil/include/il_bmp.h +++ /dev/null @@ -1,107 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 09/01/2003 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_bmp.h -// -// Description: Reads and writes to a bitmap (.bmp) file. -// -//----------------------------------------------------------------------------- - - -#ifndef BMP_H -#define BMP_H - -#include "il_internal.h" - -#ifdef _WIN32 - #pragma pack(push, bmp_struct, 1) -#endif -typedef struct BMPHEAD { - ILushort bfType; - ILint bfSize; - ILuint bfReserved; - ILint bfDataOff; - ILint biSize; - ILint biWidth; - ILint biHeight; - ILshort biPlanes; - ILshort biBitCount; - ILint biCompression; - ILint biSizeImage; - ILint biXPelsPerMeter; - ILint biYPelsPerMeter; - ILint biClrUsed; - ILint biClrImportant; -} IL_PACKSTRUCT BMPHEAD; - -typedef struct OS2_HEAD -{ - // Bitmap file header. - ILushort bfType; - ILuint biSize; - ILshort xHotspot; - ILshort yHotspot; - ILuint DataOff; - - // Bitmap core header. - ILuint cbFix; - //2003-09-01: changed cx, cy to ushort according to MSDN - ILushort cx; - ILushort cy; - ILushort cPlanes; - ILushort cBitCount; -} IL_PACKSTRUCT OS2_HEAD; -#ifdef _WIN32 - #pragma pack(pop, bmp_struct) -#endif - -// Internal functions -ILboolean iGetBmpHead(BMPHEAD * const Header); -ILboolean iGetOS2Head(OS2_HEAD * const Header); -ILboolean iIsValidBmp(); -ILboolean iCheckBmp(const BMPHEAD *CONST_RESTRICT Header); -ILboolean iCheckOS2(const OS2_HEAD *CONST_RESTRICT Header); -ILboolean iLoadBitmapInternal(); -ILboolean iSaveBitmapInternal(); -ILboolean ilReadUncompBmp(BMPHEAD *Info); -ILboolean ilReadRLE8Bmp(BMPHEAD *Info); -ILboolean ilReadRLE4Bmp(BMPHEAD *Info); -ILboolean iGetOS2Bmp(OS2_HEAD *Header); - -#ifdef IL_BMP_C -#undef NOINLINE -#undef INLINE -#define INLINE -#endif - -#ifndef NOINLINE -INLINE ILvoid GetShiftFromMask(const ILuint Mask, ILuint * CONST_RESTRICT ShiftLeft, ILuint * CONST_RESTRICT ShiftRight) { - ILuint Temp, i; - - if( Mask == 0 ) { - *ShiftLeft = *ShiftRight = 0; - return; - } - - Temp = Mask; - for( i = 0; i < 32; i++, Temp >>= 1 ) { - if( Temp & 1 ) - break; - } - *ShiftRight = i; - - // Temp is preserved, so use it again: - for( i = 0; i < 8; i++, Temp >>= 1 ) { - if( !(Temp & 1) ) - break; - } - *ShiftLeft = 8 - i; - - return; -} -#endif - -#endif//BMP_H diff --git a/win32/devil/include/il_dcx.h b/win32/devil/include/il_dcx.h deleted file mode 100644 index 3f954d6d9..000000000 --- a/win32/devil/include/il_dcx.h +++ /dev/null @@ -1,52 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 12/03/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_dcx.h -// -// Description: Reads from a .dcx file. -// -//----------------------------------------------------------------------------- - - -#ifndef DCX_H -#define DCX_H - -#include "il_internal.h" - - -#ifdef _WIN32 -#pragma pack(push, packed_struct, 1) -#endif -typedef struct DCXHEAD -{ - ILubyte Manufacturer; - ILubyte Version; - ILubyte Encoding; - ILubyte Bpp; - ILushort Xmin, Ymin, Xmax, Ymax; - ILushort HDpi; - ILushort VDpi; - ILubyte ColMap[48]; - ILubyte Reserved; - ILubyte NumPlanes; - ILushort Bps; - ILushort PaletteInfo; - ILushort HScreenSize; - ILushort VScreenSize; - ILubyte Filler[54]; -} IL_PACKSTRUCT DCXHEAD; -#ifdef _WIN32 -#pragma pack(pop, packed_struct) -#endif - -// For checking and reading -ILboolean iIsValidDcx(void); -ILboolean iCheckDcx(DCXHEAD *Header); -ILboolean iLoadDcxInternal(void); -ILimage* iUncompressDcx(DCXHEAD *Header); -ILimage* iUncompressDcxSmall(DCXHEAD *Header); - -#endif//PCX_H diff --git a/win32/devil/include/il_dds.h b/win32/devil/include/il_dds.h deleted file mode 100644 index 98be4057e..000000000 --- a/win32/devil/include/il_dds.h +++ /dev/null @@ -1,235 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/21/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_dds.h -// -// Description: Reads from a DirectDraw Surface (.dds) file. -// -//----------------------------------------------------------------------------- - - -#ifndef DDS_H -#define DDS_H - -#include "il_internal.h" - - -#ifdef _WIN32 - #pragma pack(push, dds_struct, 1) -#endif -typedef struct DDSHEAD -{ - ILbyte Signature[4]; - - ILuint Size1; // size of the structure (minus MagicNum) - ILuint Flags1; // determines what fields are valid - ILuint Height; // height of surface to be created - ILuint Width; // width of input surface - ILuint LinearSize; // Formless late-allocated optimized surface size - ILuint Depth; // Depth if a volume texture - ILuint MipMapCount; // number of mip-map levels requested - ILuint AlphaBitDepth; // depth of alpha buffer requested - - ILuint NotUsed[10]; - - ILuint Size2; // size of structure - ILuint Flags2; // pixel format flags - ILuint FourCC; // (FOURCC code) - ILuint RGBBitCount; // how many bits per pixel - ILuint RBitMask; // mask for red bit - ILuint GBitMask; // mask for green bits - ILuint BBitMask; // mask for blue bits - ILuint RGBAlphaBitMask; // mask for alpha channel - - ILuint ddsCaps1, ddsCaps2, ddsCaps3, ddsCaps4; // direct draw surface capabilities - ILuint TextureStage; -} IL_PACKSTRUCT DDSHEAD; -#ifdef _WIN32 - #pragma pack(pop, dds_struct) -#endif - - - -// use cast to struct instead of RGBA_MAKE as struct is -// much -typedef struct Color8888 -{ - ILubyte r; // change the order of names to change the - ILubyte g; // order of the output ARGB or BGRA, etc... - ILubyte b; // Last one is MSB, 1st is LSB. - ILubyte a; -} Color8888; - - -typedef struct Color888 -{ - ILubyte r; // change the order of names to change the - ILubyte g; // order of the output ARGB or BGRA, etc... - ILubyte b; // Last one is MSB, 1st is LSB. -} Color888; - - -typedef struct Color565 -{ - unsigned nBlue : 5; // order of names changes - unsigned nGreen : 6; // byte order of output to 32 bit - unsigned nRed : 5; -} Color565; - - -typedef struct DXTColBlock -{ - ILshort col0; - ILshort col1; - - // no bit fields - use bytes - ILbyte row[4]; -} DXTColBlock; - -typedef struct DXTAlphaBlockExplicit -{ - ILshort row[4]; -} DXTAlphaBlockExplicit; - -typedef struct DXTAlphaBlock3BitLinear -{ - ILbyte alpha0; - ILbyte alpha1; - - ILbyte stuff[6]; -} DXTAlphaBlock3BitLinear; - - -// Defines - -//Those 4 were added on 20040516 to make -//the written dds files more standard compliant -#define DDS_CAPS 0x00000001L -#define DDS_HEIGHT 0x00000002L -#define DDS_WIDTH 0x00000004L - -#define DDS_RGB 0x00000040L -#define DDS_PIXELFORMAT 0x00001000L - -#define DDS_LUMINANCE 0x00020000L - -#define DDS_ALPHAPIXELS 0x00000001L -#define DDS_ALPHA 0x00000002L -#define DDS_FOURCC 0x00000004L -#define DDS_PITCH 0x00000008L -#define DDS_COMPLEX 0x00000008L -#define DDS_TEXTURE 0x00001000L -#define DDS_MIPMAPCOUNT 0x00020000L -#define DDS_LINEARSIZE 0x00080000L -#define DDS_VOLUME 0x00200000L -#define DDS_MIPMAP 0x00400000L -#define DDS_DEPTH 0x00800000L - -#define DDS_CUBEMAP 0x00000200L -#define DDS_CUBEMAP_POSITIVEX 0x00000400L -#define DDS_CUBEMAP_NEGATIVEX 0x00000800L -#define DDS_CUBEMAP_POSITIVEY 0x00001000L -#define DDS_CUBEMAP_NEGATIVEY 0x00002000L -#define DDS_CUBEMAP_POSITIVEZ 0x00004000L -#define DDS_CUBEMAP_NEGATIVEZ 0x00008000L - - -#define IL_MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((ILint)(ILbyte)(ch0) | ((ILint)(ILbyte)(ch1) << 8) | \ - ((ILint)(ILbyte)(ch2) << 16) | ((ILint)(ILbyte)(ch3) << 24 )) - -enum PixFormat -{ - PF_ARGB, - PF_RGB, - PF_DXT1, - PF_DXT2, - PF_DXT3, - PF_DXT4, - PF_DXT5, - - PF_3DC, - - PF_ATI1N, - - PF_LUMINANCE, - - PF_LUMINANCE_ALPHA, - - PF_RXGB, //Doom3 normal maps - - PF_A16B16G16R16, - - PF_R16F, - - PF_G16R16F, - - PF_A16B16G16R16F, - - PF_R32F, - - PF_G32R32F, - - PF_A32B32G32R32F, - PF_UNKNOWN = 0xFF -}; - -#define CUBEMAP_SIDES 6 - -// Internal functions -ILboolean iLoadDdsInternal(ILvoid); -ILboolean iIsValidDds(void); -ILboolean iCheckDds(DDSHEAD *Head); -ILvoid AdjustVolumeTexture(DDSHEAD *Head); -ILboolean ReadData(void); -ILboolean AllocImage(void); -ILboolean Decompress(void); -ILboolean ReadMipmaps(void); -ILuint DecodePixelFormat(void); -ILboolean DecompressARGB(void); -ILboolean DecompressDXT1(void); -ILboolean DecompressDXT2(void); -ILboolean DecompressDXT3(void); -ILboolean DecompressDXT4(void); -ILboolean DecompressDXT5(void); - -ILboolean Decompress3Dc(void); - -ILboolean DecompressAti1n(void); - -ILboolean DecompressRXGB(void); - -ILboolean DecompressFloat(void); -ILvoid CorrectPreMult(void); -ILvoid GetBitsFromMask(ILuint Mask, ILuint *ShiftLeft, ILuint *ShiftRight); -ILboolean iSaveDdsInternal(void); -ILboolean WriteHeader(ILimage *Image, ILenum DXTCFormat, ILuint CubeFlags); -ILushort *CompressTo565(ILimage *Image); - -ILubyte *CompressTo88(ILimage *Image); -ILuint Compress(ILimage *Image, ILenum DXTCFormat); -ILboolean GetBlock(ILushort *Block, ILushort *Data, ILimage *Image, ILuint XPos, ILuint YPos); -ILboolean GetAlphaBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos); - -ILboolean Get3DcBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos, int channel); -ILvoid ShortToColor565(ILushort Pixel, Color565 *Colour); -ILvoid ShortToColor888(ILushort Pixel, Color888 *Colour); -ILushort Color565ToShort(Color565 *Colour); -ILushort Color888ToShort(Color888 *Colour); -ILuint GenBitMask(ILushort ex0, ILushort ex1, ILuint NumCols, ILushort *In, ILubyte *Alpha, Color888 *OutCol); -ILvoid GenAlphaBitMask(ILubyte a0, ILubyte a1, ILubyte *In, ILubyte *Mask, ILubyte *Out); -ILuint RMSAlpha(ILubyte *Orig, ILubyte *Test); -ILuint Distance(Color888 *c1, Color888 *c2); -ILvoid ChooseEndpoints(ILushort *Block, ILushort *ex0, ILushort *ex1); -ILvoid ChooseAlphaEndpoints(ILubyte *Block, ILubyte *a0, ILubyte *a1); -ILvoid CorrectEndDXT1(ILushort *ex0, ILushort *ex1, ILboolean HasAlpha); -ILvoid PreMult(ILushort *Data, ILubyte *Alpha); - - -extern ILuint CubemapDirections[CUBEMAP_SIDES]; - - -#endif//DDS_H diff --git a/win32/devil/include/il_doompal.h b/win32/devil/include/il_doompal.h deleted file mode 100644 index 563e15499..000000000 --- a/win32/devil/include/il_doompal.h +++ /dev/null @@ -1,276 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_doompal.h -// -// Description: The default Doom palette -// -//----------------------------------------------------------------------------- - -#ifndef DOOMPAL_H -#define DOOMPAL_H - -#define IL_DOOMPAL_SIZE 768 -ILubyte ilDefaultDoomPal[IL_DOOMPAL_SIZE] = { - 0, 0, 0, - 31, 23, 11, - 23, 15, 7, - 75, 75, 75, - 255, 255, 255, - 27, 27, 27, - 19, 19, 19, - 11, 11, 11, - 7, 7, 7, - 47, 55, 31, - 35, 43, 15, - 23, 31, 7, - 15, 23, 0, - 79, 59, 43, - 71, 51, 35, - 63, 43, 27, - 255, 183, 183, - 247, 171, 171, - 243, 163, 163, - 235, 151, 151, - 231, 143, 143, - 223, 135, 135, - 219, 123, 123, - 211, 115, 115, - 203, 107, 107, - 199, 99, 99, - 191, 91, 91, - 187, 87, 87, - 179, 79, 79, - 175, 71, 71, - 167, 63, 63, - 163, 59, 59, - 155, 51, 51, - 151, 47, 47, - 143, 43, 43, - 139, 35, 35, - 131, 31, 31, - 127, 27, 27, - 119, 23, 23, - 115, 19, 19, - 107, 15, 15, - 103, 11, 11, - 95, 7, 7, - 91, 7, 7, - 83, 7, 7, - 79, 0, 0, - 71, 0, 0, - 67, 0, 0, - 255, 235, 223, - 255, 227, 211, - 255, 219, 199, - 255, 211, 187, - 255, 207, 179, - 255, 199, 167, - 255, 191, 155, - 255, 187, 147, - 255, 179, 131, - 247, 171, 123, - 239, 163, 115, - 231, 155, 107, - 223, 147, 99, - 215, 139, 91, - 207, 131, 83, - 203, 127, 79, - 191, 123, 75, - 179, 115, 71, - 171, 111, 67, - 163, 107, 63, - 155, 99, 59, - 143, 95, 55, - 135, 87, 51, - 127, 83, 47, - 119, 79, 43, - 107, 71, 39, - 95, 67, 35, - 83, 63, 31, - 75, 55, 27, - 63, 47, 23, - 51, 43, 19, - 43, 35, 15, - 239, 239, 239, - 231, 231, 231, - 223, 223, 223, - 219, 219, 219, - 211, 211, 211, - 203, 203, 203, - 199, 199, 199, - 191, 191, 191, - 183, 183, 183, - 179, 179, 179, - 171, 171, 171, - 167, 167, 167, - 159, 159, 159, - 151, 151, 151, - 147, 147, 147, - 139, 139, 139, - 131, 131, 131, - 127, 127, 127, - 119, 119, 119, - 111, 111, 111, - 107, 107, 107, - 99, 99, 99, - 91, 91, 91, - 87, 87, 87, - 79, 79, 79, - 71, 71, 71, - 67, 67, 67, - 59, 59, 59, - 55, 55, 55, - 47, 47, 47, - 39, 39, 39, - 35, 35, 35, - 119, 255, 111, - 111, 239, 103, - 103, 223, 95, - 95, 207, 87, - 91, 191, 79, - 83, 175, 71, - 75, 159, 63, - 67, 147, 55, - 63, 131, 47, - 55, 115, 43, - 47, 99, 35, - 39, 83, 27, - 31, 67, 23, - 23, 51, 15, - 19, 35, 11, - 11, 23, 7, - 191, 167, 143, - 183, 159, 135, - 175, 151, 127, - 167, 143, 119, - 159, 135, 111, - 155, 127, 107, - 147, 123, 99, - 139, 115, 91, - 131, 107, 87, - 123, 99, 79, - 119, 95, 75, - 111, 87, 67, - 103, 83, 63, - 95, 75, 55, - 87, 67, 51, - 83, 63, 47, - 159, 131, 99, - 143, 119, 83, - 131, 107, 75, - 119, 95, 63, - 103, 83, 51, - 91, 71, 43, - 79, 59, 35, - 67, 51, 27, - 123, 127, 99, - 111, 115, 87, - 103, 107, 79, - 91, 99, 71, - 83, 87, 59, - 71, 79, 51, - 63, 71, 43, - 55, 63, 39, - 255, 255, 115, - 235, 219, 87, - 215, 187, 67, - 195, 155, 47, - 175, 123, 31, - 155, 91, 19, - 135, 67, 7, - 115, 43, 0, - 255, 255, 255, - 255, 219, 219, - 255, 187, 187, - 255, 155, 155, - 255, 123, 123, - 255, 95, 95, - 255, 63, 63, - 255, 31, 31, - 255, 0, 0, - 239, 0, 0, - 227, 0, 0, - 215, 0, 0, - 203, 0, 0, - 191, 0, 0, - 179, 0, 0, - 167, 0, 0, - 155, 0, 0, - 139, 0, 0, - 127, 0, 0, - 115, 0, 0, - 103, 0, 0, - 91, 0, 0, - 79, 0, 0, - 67, 0, 0, - 231, 231, 255, - 199, 199, 255, - 171, 171, 255, - 143, 143, 255, - 115, 115, 255, - 83, 83, 255, - 55, 55, 255, - 27, 27, 255, - 0, 0, 255, - 0, 0, 227, - 0, 0, 203, - 0, 0, 179, - 0, 0, 155, - 0, 0, 131, - 0, 0, 107, - 0, 0, 83, - 255, 255, 255, - 255, 235, 219, - 255, 215, 187, - 255, 199, 155, - 255, 179, 123, - 255, 163, 91, - 255, 143, 59, - 255, 127, 27, - 243, 115, 23, - 235, 111, 15, - 223, 103, 15, - 215, 95, 11, - 203, 87, 7, - 195, 79, 0, - 183, 71, 0, - 175, 67, 0, - 255, 255, 255, - 255, 255, 215, - 255, 255, 179, - 255, 255, 143, - 255, 255, 107, - 255, 255, 71, - 255, 255, 35, - 255, 255, 0, - 167, 63, 0, - 159, 55, 0, - 147, 47, 0, - 135, 35, 0, - 79, 59, 39, - 67, 47, 27, - 55, 35, 19, - 47, 27, 11, - 0, 0, 83, - 0, 0, 71, - 0, 0, 59, - 0, 0, 47, - 0, 0, 35, - 0, 0, 23, - 0, 0, 11, - 0, 255, 255, - 255, 159, 67, - 255, 231, 75, - 255, 123, 255, - 255, 0, 255, - 207, 0, 207, - 159, 0, 155, - 111, 0, 107, - 167, 107, 107 -}; - -#endif//DOOMPAL_H diff --git a/win32/devil/include/il_endian.h b/win32/devil/include/il_endian.h deleted file mode 100644 index df0ad9e5b..000000000 --- a/win32/devil/include/il_endian.h +++ /dev/null @@ -1,377 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 01/29/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_endian.h -// -// Description: Handles Endian-ness -// -//----------------------------------------------------------------------------- - -#ifndef IL_ENDIAN_H -#define IL_ENDIAN_H - -#include "il_internal.h" - -#ifdef WORDS_BIGENDIAN //this is defined by ./configure - #ifndef __BIG_ENDIAN__ - #define __BIG_ENDIAN__ - #endif -#endif - -#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __BIG_ENDIAN__) \ - || (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) - #undef __LITTLE_ENDIAN__ - #define Short(s) iSwapShort(s) - #define UShort(s) iSwapUShort(s) - #define Int(i) iSwapInt(i) - #define UInt(i) iSwapUInt(i) - #define Float(f) iSwapFloat(f) - #define Double(d) iSwapDouble(d) - - #define BigShort(s) - #define BigUShort(s) - #define BigInt(i) - #define BigUInt(i) - #define BigFloat(f) - #define BigDouble(d) -#else - #undef __BIG_ENDIAN__ - #undef __LITTLE_ENDIAN__ // Not sure if it's defined by any compiler... - #define __LITTLE_ENDIAN__ - #define Short(s) - #define UShort(s) - #define Int(i) - #define UInt(i) - #define Float(f) - #define Double(d) - - #define BigShort(s) iSwapShort(s) - #define BigUShort(s) iSwapUShort(s) - #define BigInt(i) iSwapInt(i) - #define BigUInt(i) iSwapUInt(i) - #define BigFloat(f) iSwapFloat(f) - #define BigDouble(d) iSwapDouble(d) -#endif - -ILvoid iSwapUShort(ILushort *s); -ILvoid iSwapShort(ILshort *s); -ILvoid iSwapUInt(ILuint *i); -ILvoid iSwapInt(ILint *i); -ILvoid iSwapFloat(ILfloat *f); -ILvoid iSwapDouble(ILdouble *d); -ILushort GetLittleUShort(); -ILshort GetLittleShort(); -ILuint GetLittleUInt(); -ILint GetLittleInt(); -ILfloat GetLittleFloat(); -ILdouble GetLittleDouble(); -ILushort GetBigUShort(); -ILshort GetBigShort(); -ILuint GetBigUInt(); -ILint GetBigInt(); -ILfloat GetBigFloat(); -ILdouble GetBigDouble(); -ILubyte SaveLittleUShort(ILushort s); -ILubyte SaveLittleShort(ILshort s); -ILubyte SaveLittleUInt(ILuint i); -ILubyte SaveLittleInt(ILint i); -ILubyte SaveLittleFloat(ILfloat f); -ILubyte SaveLittleDouble(ILdouble d); -ILubyte SaveBigUShort(ILushort s); -ILubyte SaveBigShort(ILshort s); -ILubyte SaveBigUInt(ILuint i); -ILubyte SaveBigInt(ILint i); -ILubyte SaveBigFloat(ILfloat f); -ILubyte SaveBigDouble(ILdouble d); - -#ifdef IL_ENDIAN_C -#undef NOINLINE -#undef INLINE -#define INLINE -#endif - -#ifndef NOINLINE -INLINE ILvoid iSwapUShort(ILushort *s) { - #ifdef USE_WIN32_ASM - __asm { - mov ebx, s - mov al, [ebx+1] - mov ah, [ebx ] - mov [ebx], ax - } - #else - #ifdef GCC_X86_ASM - asm("ror $8,%0" - : - : "r" (*s) ); - #else - *s = ((*s)>>8) | ((*s)<<8); - #endif //GCC_X86_ASM - #endif //USE_WIN32_ASM -} - -INLINE ILvoid iSwapShort(ILshort *s) { - iSwapUShort((ILushort*)s); -} - -INLINE ILvoid iSwapUInt(ILuint *i) { - #ifdef USE_WIN32_ASM - __asm { - mov ebx, i - mov eax, [ebx] - bswap eax - mov [ebx], eax - } - #else - #ifdef GCC_X86_ASM - asm("bswap %0;" - : "=r" (*i) ); - #else - *i = ((*i)>>24) | (((*i)>>8) & 0xff00) | (((*i)<<8) & 0xff0000) | ((*i)<<24); - #endif //GCC_X86_ASM - #endif //USE_WIN32_ASM -} - -INLINE ILvoid iSwapInt(ILint *i) { - iSwapUInt((ILuint*)i); -} - -INLINE ILvoid iSwapFloat(ILfloat *f) { - iSwapUInt((ILuint*)f); -} - -INLINE ILvoid iSwapDouble(ILdouble *d) { - #ifdef GCC_X86_ASM - int *t = (int*)d; - asm("bswap %2 \n" - "bswap %3 \n" - "movl %2,%1 \n" - "movl %3,%0 \n" - : "=g" (t[0]), "=g" (t[1]) - : "r" (t[0]), "r" (t[1])); - #else - ILubyte t,*b = (ILubyte*)d; - #define dswap(x,y) t=b[x];b[x]=b[y];b[y]=b[x]; - dswap(0,7); - dswap(1,6); - dswap(2,5); - dswap(3,4); - #undef dswap - #endif -} - - -INLINE ILushort GetLittleUShort() { - ILushort s; - iread(&s, sizeof(ILushort), 1); -#ifdef __BIG_ENDIAN__ - iSwapUShort(&s); -#endif - return s; -} - -INLINE ILshort GetLittleShort() { - ILshort s; - iread(&s, sizeof(ILshort), 1); -#ifdef __BIG_ENDIAN__ - iSwapShort(&s); -#endif - return s; -} - -INLINE ILuint GetLittleUInt() { - ILuint i; - iread(&i, sizeof(ILuint), 1); -#ifdef __BIG_ENDIAN__ - iSwapUInt(&i); -#endif - return i; -} - -INLINE ILint GetLittleInt() { - ILint i; - iread(&i, sizeof(ILint), 1); -#ifdef __BIG_ENDIAN__ - iSwapInt(&i); -#endif - return i; -} - -INLINE ILfloat GetLittleFloat() { - ILfloat f; - iread(&f, sizeof(ILfloat), 1); -#ifdef __BIG_ENDIAN__ - iSwapFloat(&f); -#endif - return f; -} - -INLINE ILdouble GetLittleDouble() { - ILdouble d; - iread(&d, sizeof(ILdouble), 1); -#ifdef __BIG_ENDIAN__ - iSwapDouble(&d); -#endif - return d; -} - - -INLINE ILushort GetBigUShort() { - ILushort s; - iread(&s, sizeof(ILushort), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapUShort(&s); -#endif - return s; -} - - -INLINE ILshort GetBigShort() { - ILshort s; - iread(&s, sizeof(ILshort), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapShort(&s); -#endif - return s; -} - - -INLINE ILuint GetBigUInt() { - ILuint i; - iread(&i, sizeof(ILuint), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapUInt(&i); -#endif - return i; -} - - -INLINE ILint GetBigInt() { - ILint i; - iread(&i, sizeof(ILint), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapInt(&i); -#endif - return i; -} - - -INLINE ILfloat GetBigFloat() { - ILfloat f; - iread(&f, sizeof(ILfloat), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapFloat(&f); -#endif - return f; -} - - -INLINE ILdouble GetBigDouble() { - ILdouble d; - iread(&d, sizeof(ILdouble), 1); -#ifdef __LITTLE_ENDIAN__ - iSwapDouble(&d); -#endif - return d; -} - -INLINE ILubyte SaveLittleUShort(ILushort s) { -#ifdef __BIG_ENDIAN__ - iSwapUShort(&s); -#endif - return iwrite(&s, sizeof(ILushort), 1); -} - -INLINE ILubyte SaveLittleShort(ILshort s) { -#ifdef __BIG_ENDIAN__ - iSwapShort(&s); -#endif - return iwrite(&s, sizeof(ILshort), 1); -} - - -INLINE ILubyte SaveLittleUInt(ILuint i) { -#ifdef __BIG_ENDIAN__ - iSwapUInt(&i); -#endif - return iwrite(&i, sizeof(ILuint), 1); -} - - -INLINE ILubyte SaveLittleInt(ILint i) { -#ifdef __BIG_ENDIAN__ - iSwapInt(&i); -#endif - return iwrite(&i, sizeof(ILint), 1); -} - -INLINE ILubyte SaveLittleFloat(ILfloat f) { -#ifdef __BIG_ENDIAN__ - iSwapFloat(&f); -#endif - return iwrite(&f, sizeof(ILfloat), 1); -} - - -INLINE ILubyte SaveLittleDouble(ILdouble d) { -#ifdef __BIG_ENDIAN__ - iSwapDouble(&d); -#endif - return iwrite(&d, sizeof(ILdouble), 1); -} - - -INLINE ILubyte SaveBigUShort(ILushort s) { -#ifdef __LITTLE_ENDIAN__ - iSwapUShort(&s); -#endif - return iwrite(&s, sizeof(ILushort), 1); -} - - -INLINE ILubyte SaveBigShort(ILshort s) { -#ifdef __LITTLE_ENDIAN__ - iSwapShort(&s); -#endif - return iwrite(&s, sizeof(ILshort), 1); -} - - -INLINE ILubyte SaveBigUInt(ILuint i) { -#ifdef __LITTLE_ENDIAN__ - iSwapUInt(&i); -#endif - return iwrite(&i, sizeof(ILuint), 1); -} - - -INLINE ILubyte SaveBigInt(ILint i) { -#ifdef __LITTLE_ENDIAN__ - iSwapInt(&i); -#endif - return iwrite(&i, sizeof(ILint), 1); -} - - -INLINE ILubyte SaveBigFloat(ILfloat f) { -#ifdef __LITTLE_ENDIAN__ - iSwapFloat(&f); -#endif - return iwrite(&f, sizeof(ILfloat), 1); -} - - -INLINE ILubyte SaveBigDouble(ILdouble d) { -#ifdef __LITTLE_ENDIAN__ - iSwapDouble(&d); -#endif - return iwrite(&d, sizeof(ILdouble), 1); -} -#endif - -ILvoid EndianSwapData(void *_Image); - -#endif//ENDIAN_H diff --git a/win32/devil/include/il_exr.h b/win32/devil/include/il_exr.h deleted file mode 100644 index f0ae8f640..000000000 --- a/win32/devil/include/il_exr.h +++ /dev/null @@ -1,31 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/29/2008 -// -// Filename: src-IL/include/il_exr.h -// -// Description: Reads from an OpenEXR (.exr) file. -// -//----------------------------------------------------------------------------- - - -#ifndef EXR_H -#define EXR_H - -#include "il_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -ILboolean ilLoadExr(ILconst_string FileName); - -#ifdef __cplusplus -} -#endif - -ILboolean iLoadExrInternal(ILconst_string FileName); - -#endif//EXR_H diff --git a/win32/devil/include/il_files.h b/win32/devil/include/il_files.h deleted file mode 100644 index bedcc2d3a..000000000 --- a/win32/devil/include/il_files.h +++ /dev/null @@ -1,76 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 10/20/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_files.h -// -// Description: File handling for DevIL -// -//----------------------------------------------------------------------------- - -#ifndef FILES_H -#define FILES_H - -#if defined (__FILES_C) -#define __FILES_EXTERN -#else -#define __FILES_EXTERN extern -#endif -#include - - -__FILES_EXTERN ILvoid ILAPIENTRY iPreserveReadFuncs(void); -__FILES_EXTERN ILvoid ILAPIENTRY iRestoreReadFuncs(void); - -__FILES_EXTERN fEofProc EofProc; -__FILES_EXTERN fGetcProc GetcProc; -__FILES_EXTERN fReadProc ReadProc; -__FILES_EXTERN fSeekRProc SeekRProc; -__FILES_EXTERN fSeekWProc SeekWProc; -__FILES_EXTERN fTellRProc TellRProc; -__FILES_EXTERN fTellWProc TellWProc; -__FILES_EXTERN fPutcProc PutcProc; -__FILES_EXTERN fWriteProc WriteProc; - -__FILES_EXTERN ILHANDLE ILAPIENTRY iDefaultOpen(ILconst_string FileName); -__FILES_EXTERN ILvoid ILAPIENTRY iDefaultClose(ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultRead(ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultSeekR(ILHANDLE Handle, ILint Offset, ILint Mode); -__FILES_EXTERN ILint ILAPIENTRY iDefaultSeekW(ILHANDLE Handle, ILint Offset, ILint Mode); -__FILES_EXTERN ILint ILAPIENTRY iDefaultTellR(ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultTellW(ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle); -__FILES_EXTERN ILint ILAPIENTRY iDefaultWrite(const ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle); - -__FILES_EXTERN ILvoid iSetInputFile(ILHANDLE File); -__FILES_EXTERN ILvoid iSetInputLump(const ILvoid *Lump, ILuint Size); -__FILES_EXTERN ILboolean (ILAPIENTRY *ieof)(void); -__FILES_EXTERN ILHANDLE (ILAPIENTRY *iopenr)(ILconst_string); -__FILES_EXTERN ILvoid (ILAPIENTRY *icloser)(ILHANDLE); -__FILES_EXTERN ILint (ILAPIENTRY *igetc)(void); -__FILES_EXTERN ILuint (ILAPIENTRY *iread)(ILvoid *Buffer, ILuint Size, ILuint Number); -__FILES_EXTERN ILuint (ILAPIENTRY *iseek)(ILint Offset, ILuint Mode); -__FILES_EXTERN ILuint (ILAPIENTRY *itell)(void); - -__FILES_EXTERN ILvoid iSetOutputFile(ILHANDLE File); -__FILES_EXTERN ILvoid iSetOutputLump(ILvoid *Lump, ILuint Size); -__FILES_EXTERN ILvoid (ILAPIENTRY *iclosew)(ILHANDLE); -__FILES_EXTERN ILHANDLE (ILAPIENTRY *iopenw)(ILconst_string); -__FILES_EXTERN ILint (ILAPIENTRY *iputc)(ILubyte Char); -__FILES_EXTERN ILuint (ILAPIENTRY *iseekw)(ILint Offset, ILuint Mode); -__FILES_EXTERN ILuint (ILAPIENTRY *itellw)(void); -__FILES_EXTERN ILint (ILAPIENTRY *iwrite)(const ILvoid *Buffer, ILuint Size, ILuint Number); - -__FILES_EXTERN ILHANDLE ILAPIENTRY iGetFile(void); -__FILES_EXTERN const ILubyte* ILAPIENTRY iGetLump(void); - -__FILES_EXTERN ILuint ILAPIENTRY ilprintf(const char *, ...); -__FILES_EXTERN ILvoid ipad(ILuint NumZeros); - -__FILES_EXTERN ILboolean iPreCache(ILuint Size); -__FILES_EXTERN ILvoid iUnCache(void); - -#endif//FILES_H diff --git a/win32/devil/include/il_gif.h b/win32/devil/include/il_gif.h deleted file mode 100644 index 99f14a759..000000000 --- a/win32/devil/include/il_gif.h +++ /dev/null @@ -1,72 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/18/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_gif.h -// -// Description: Reads from a Graphics Interchange Format (.gif) file. -// -//----------------------------------------------------------------------------- - - -#ifndef GIF_H -#define GIF_H - -#include "il_internal.h" - -#define GIF87A 87 -#define GIF89A 89 - -#ifdef _WIN32 - #pragma pack(push, gif_struct, 1) -#endif -typedef struct GIFHEAD -{ - char Sig[6]; - ILushort Width; - ILushort Height; - ILubyte ColourInfo; - ILubyte Background; - ILubyte Aspect; -} IL_PACKSTRUCT GIFHEAD; - -typedef struct IMAGEDESC -{ - ILubyte Separator; - ILushort OffX; - ILushort OffY; - ILushort Width; - ILushort Height; - ILubyte ImageInfo; -} IL_PACKSTRUCT IMAGEDESC; - -typedef struct GFXCONTROL -{ - ILubyte Size; - ILubyte Packed; - ILushort Delay; - ILubyte Transparent; - ILubyte Terminator; - ILboolean Used; //this stores if a gfxcontrol was read - it is IL_FALSE (!) - - //if a gfxcontrol was read from the file, IL_TRUE otherwise -} IL_PACKSTRUCT GFXCONTROL; -#ifdef _WIN32 - #pragma pack(pop, gif_struct) -#endif - -// Internal functions -ILboolean iLoadGifInternal(void); -ILboolean ilLoadGifF(ILHANDLE File); -ILboolean iIsValidGif(void); -ILboolean iGetPalette(ILubyte Info, ILpal *Pal); -ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead); -ILboolean SkipExtensions(GFXCONTROL *Gfx); -ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, GFXCONTROL *Gfx); -ILboolean RemoveInterlace(ILimage *image); -ILboolean iCopyPalette(ILpal *Dest, ILpal *Src); -ILboolean ConvertTransparent(ILimage *Image, ILubyte TransColour); - -#endif//GIF_H diff --git a/win32/devil/include/il_hdr.h b/win32/devil/include/il_hdr.h deleted file mode 100644 index 1400c56bf..000000000 --- a/win32/devil/include/il_hdr.h +++ /dev/null @@ -1,42 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2004 by Denton Woods (this file by thakis) -// Last modified: 06/09/2004 -// -// Filename: src-IL/include/il_hdr.h -// -// Description: Reads a RADIANCE High Dynamic Range Image -// -//----------------------------------------------------------------------------- - - -#ifndef HDR_H -#define HDR_H - -#include "il_internal.h" - -#ifdef _WIN32 - #pragma pack(push, gif_struct, 1) -#endif - -typedef struct HDRHEADER -{ - char Signature[10]; //must be "#?RADIANCE" - ILuint Width, Height; -} IL_PACKSTRUCT HDRHEADER; - -#ifdef _WIN32 - #pragma pack(pop, gif_struct) -#endif - -// Internal functions -ILboolean ilIsValidHdrF(ILHANDLE file); -ILboolean iIsValidHdr(); -ILboolean iCheckHdr(HDRHEADER *Header); -ILboolean ilLoadHdrF(ILHANDLE file); -ILboolean iLoadHdrInternal(); - -ILvoid ReadScanline(ILubyte *scanline, ILuint w); - -#endif//HDR_H diff --git a/win32/devil/include/il_icns.h b/win32/devil/include/il_icns.h deleted file mode 100644 index 560ac2a2a..000000000 --- a/win32/devil/include/il_icns.h +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: src-IL/include/il_icns.h -// -// Description: Reads from a Mac OS X icon (.icns) file. -// -//----------------------------------------------------------------------------- - - -#ifndef ICNS_H -#define ICNS_H - -#include "il_internal.h" - -#ifdef _WIN32 - #pragma pack(push, icns_struct, 1) -#endif -typedef struct ICNSHEAD -{ - ILbyte Head[4]; // Must be 'ICNS' - ILint Size; // Total size of the file (including header) -} IL_PACKSTRUCT ICNSHEAD; - -typedef struct ICNSDATA -{ - ILbyte ID[4]; // Identifier ('it32', 'il32', etc.) - ILint Size; // Total size of the file (including header) -} IL_PACKSTRUCT ICNSDATA; - -#ifdef _WIN32 - #pragma pack(pop, icns_struct) -#endif - -ILboolean iLoadIcnsInternal(); -ILboolean iIcnsReadData(ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image); - -#endif//ICNS_H diff --git a/win32/devil/include/il_icon.h b/win32/devil/include/il_icon.h deleted file mode 100644 index 4f314950e..000000000 --- a/win32/devil/include/il_icon.h +++ /dev/null @@ -1,70 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_icon.h -// -// Description: Reads from a Windows icon (.ico) file. -// -//----------------------------------------------------------------------------- - - -#ifndef ICON_H -#define ICON_H - -#include "il_internal.h" - -#ifdef _WIN32 - #pragma pack(push, ico_struct, 1) -#endif -typedef struct ICODIR -{ - ILshort Reserved; // Reserved (must be 0) - ILshort Type; // Type (1 for icons, 2 for cursors) - ILshort Count; // How many different images? -} IL_PACKSTRUCT ICODIR; - -typedef struct ICODIRENTRY -{ - ILubyte Width; // Width, in pixels - ILubyte Height; // Height, in pixels - ILubyte NumColours; // Number of colors in image (0 if >=8bpp) - ILubyte Reserved; // Reserved (must be 0) - ILshort Planes; // Colour planes - ILshort Bpp; // Bits per pixel - ILuint SizeOfData; // How many bytes in this resource? - ILuint Offset; // Offset from beginning of the file -} IL_PACKSTRUCT ICODIRENTRY; - -typedef struct INFOHEAD -{ - ILint Size; - ILint Width; - ILint Height; - ILshort Planes; - ILshort BitCount; - ILint Compression; - ILint SizeImage; - ILint XPixPerMeter; - ILint YPixPerMeter; - ILint ColourUsed; - ILint ColourImportant; -} IL_PACKSTRUCT INFOHEAD; - -typedef struct ICOIMAGE -{ - INFOHEAD Head; - ILubyte *Pal; // Palette - ILubyte *Data; // XOR mask - ILubyte *AND; // AND mask -} ICOIMAGE; -#ifdef _WIN32 - #pragma pack(pop, ico_struct) -#endif - -ILboolean iLoadIconInternal(); -ILboolean iLoadIconPNG(ICOIMAGE *Icon); - -#endif//ICON_H diff --git a/win32/devil/include/il_internal.h b/win32/devil/include/il_internal.h deleted file mode 100644 index 1f37ce49c..000000000 --- a/win32/devil/include/il_internal.h +++ /dev/null @@ -1,411 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/19/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_internal.h -// -// Description: Internal stuff for DevIL -// -//----------------------------------------------------------------------------- -#ifndef INTERNAL_H -#define INTERNAL_H -#define _IL_BUILD_LIBRARY - -// Standard headers -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Local headers -#if defined(_WIN32) && !defined(HAVE_CONFIG_H) -#define HAVE_CONFIG_H -#endif -#ifdef HAVE_CONFIG_H - #include -#endif -#include -#include -#include "il_files.h" -#include "il_endian.h" - -// Windows-specific -#ifdef _WIN32 - #ifdef _MSC_VER - #if _MSC_VER > 1000 - #pragma once - #pragma intrinsic(memcpy) - #pragma intrinsic(memset) - #pragma intrinsic(strcmp) - #pragma intrinsic(strlen) - #pragma intrinsic(strcpy) - /* - #if _MSC_VER >= 1300 // Erroneous size_t conversion warnings - pragma warning(disable : 4267) - #endif - pragma comment(linker, "/NODEFAULTLIB:libc") - pragma comment(linker, "/NODEFAULTLIB:libcd") - pragma comment(linker, "/NODEFAULTLIB:libcmt.lib") - #ifdef _DEBUG - pragma comment(linker, "/NODEFAULTLIB:libcmtd") - pragma comment(linker, "/NODEFAULTLIB:msvcrt.lib") - #endif // _DEBUG - */ - #endif // _MSC_VER > 1000 - #endif - #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - #include -#endif -// Windows has a TEXT macro defined in WinNT.h that makes string Unicode if UNICODE is defined. -/*#ifndef _WIN32 - #define IL_TEXT(s) s -#endif*/ -/*#ifdef _WIN32_WCE - #define IL_TEXT(s) ((char*)TEXT(s)) -#elif _WIN32 - #define IL_TEXT(s) (s) -#else - #define IL_TEXT(s) (s) - #define TEXT(s) (s) -#endif*/ -#ifdef _UNICODE - #define IL_TEXT(s) L##s -#else - #define IL_TEXT(s) (s) -#endif -#ifdef IL_INLINE_ASM - #ifdef _MSC_VER // MSVC++ only - #define USE_WIN32_ASM - #endif -#endif -extern ILimage *iCurImage; -#define BIT_0 0x00000001 -#define BIT_1 0x00000002 -#define BIT_2 0x00000004 -#define BIT_3 0x00000008 -#define BIT_4 0x00000010 -#define BIT_5 0x00000020 -#define BIT_6 0x00000040 -#define BIT_7 0x00000080 -#define BIT_8 0x00000100 -#define BIT_9 0x00000200 -#define BIT_10 0x00000400 -#define BIT_11 0x00000800 -#define BIT_12 0x00001000 -#define BIT_13 0x00002000 -#define BIT_14 0x00004000 -#define BIT_15 0x00008000 -#define BIT_16 0x00010000 -#define BIT_17 0x00020000 -#define BIT_18 0x00040000 -#define BIT_19 0x00080000 -#define BIT_20 0x00100000 -#define BIT_21 0x00200000 -#define BIT_22 0x00400000 -#define BIT_23 0x00800000 -#define BIT_24 0x01000000 -#define BIT_25 0x02000000 -#define BIT_26 0x04000000 -#define BIT_27 0x08000000 -#define BIT_28 0x10000000 -#define BIT_29 0x20000000 -#define BIT_30 0x40000000 -#define BIT_31 0x80000000 -#define NUL '\0' // Easier to type and ?portable? -#if !_WIN32 || _WIN32_WCE - int stricmp(const char *src1, const char *src2); - int strnicmp(const char *src1, const char *src2, size_t max); -#endif//_WIN32 -int iStrCmp(ILconst_string src1, ILconst_string src2); - -// -// Some math functions -// -// A fast integer squareroot, completely accurate for x < 289. -// Taken from http://atoms.org.uk/sqrt/ -// There is also a version that is accurate for all integers -// < 2^31, if we should need it -int iSqrt(int x); -// -// Useful miscellaneous functions -// -ILboolean iCheckExtension(ILconst_string Arg, ILconst_string Ext); -ILbyte* iFgets(char *buffer, ILuint maxlen); -ILboolean iFileExists(ILconst_string FileName); -ILstring iGetExtension(ILconst_string FileName); -char* ilStrDup(const char *Str); -ILuint ilStrLen(const char *Str); -// Miscellaneous functions -ILvoid ilDefaultStates(void); -ILenum iGetHint(ILenum Target); -ILint iGetInt(ILenum Mode); -ILvoid ilRemoveRegistered(void); -ILAPI ILvoid ILAPIENTRY ilSetCurImage(ILimage *Image); -// -// Rle compression -// -#define IL_TGACOMP 0x01 -#define IL_PCXCOMP 0x02 -#define IL_SGICOMP 0x03 -#define IL_BMPCOMP 0x04 -ILboolean ilRleCompressLine(ILubyte *ScanLine, ILuint Width, ILubyte Bpp, ILubyte *Dest, ILuint *DestWidth, ILenum CompressMode); -ILuint ilRleCompress(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte *Dest, ILenum CompressMode, ILuint *ScanTable); -ILvoid iSetImage0(void); -// Conversion functions -ILboolean ilAddAlpha(void); -ILboolean ilAddAlphaKey(ILimage *Image); -ILboolean iFastConvert(ILenum DestFormat); -ILboolean ilFixImage(void); -ILboolean ilRemoveAlpha(void); -ILboolean ilSwapColours(void); -// Miscellaneous functions -char *iGetString(ILenum StringName); // Internal version of ilGetString -// Library usage -#if _MSC_VER && !_WIN32_WCE - #ifndef IL_NO_JPG - #ifdef IL_USE_IJL - //pragma comment(lib, "ijl15.lib") - #else - #ifndef IL_DEBUG - //pragma comment(lib, "libjpeg.lib") - #else - //ragma comment(lib, "debug/libjpeg.lib") - #endif - #endif - #endif - #ifndef IL_NO_MNG - #ifndef IL_DEBUG - //pragma comment(lib, "libmng.lib") - //pragma comment(lib, "libjpeg.lib") // For JNG support. - #else - //pragma comment(lib, "debug/libmng.lib") - //pragma comment(lib, "debug/libjpeg.lib") // For JNG support. - #endif - #endif - #ifndef IL_NO_PNG - #ifndef IL_DEBUG - //pragma comment(lib, "libpng.lib") - #else - //pragma comment(lib, "debug/libpng.lib") - #endif - #endif - #ifndef IL_NO_TIF - #ifndef IL_DEBUG - //pragma comment(lib, "libtiff.lib") - #else - //pragma comment(lib, "debug/libtiff.lib") - #endif - #endif - #if !defined(IL_NO_MNG) || !defined(IL_NO_PNG) - #ifndef IL_DEBUG - //pragma comment(lib, "zlib.lib") - #else - //pragma comment(lib, "debug/zlib.lib") - #endif - #endif -#endif -// -// Image loading/saving functions -// -ILboolean ilIsValidBmp(ILconst_string CONST_RESTRICT FileName); -ILboolean ilIsValidBmpF(ILHANDLE File); -ILboolean ilIsValidBmpL(const ILvoid *Lump, const ILuint Size); -ILboolean ilLoadBmp(ILconst_string FileName); -ILboolean ilLoadBmpF(ILHANDLE File); -ILboolean ilLoadBmpL(const ILvoid *Lump, const ILuint Size); -ILboolean ilSaveBmp(ILconst_string FileName); -ILboolean ilSaveBmpF(ILHANDLE File); -ILboolean ilSaveBmpL(ILvoid *Lump, ILuint Size); -ILboolean ilSaveCHeader(ILconst_string FileName, const char *InternalName); -ILboolean ilLoadCut(ILconst_string FileName); -ILboolean ilLoadCutF(ILHANDLE File); -ILboolean ilLoadCutL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidDcx(ILconst_string FileName); -ILboolean ilIsValidDcxF(ILHANDLE File); -ILboolean ilIsValidDcxL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadDcx(ILconst_string FileName); -ILboolean ilLoadDcxF(ILHANDLE File); -ILboolean ilLoadDcxL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidDds(ILconst_string FileName); -ILboolean ilIsValidDdsF(ILHANDLE File); -ILboolean ilIsValidDdsL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadDds(ILconst_string FileName); -ILboolean ilLoadDdsF(ILHANDLE File); -ILboolean ilLoadDdsL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveDds(ILconst_string FileName); -ILboolean ilSaveDdsF(ILHANDLE File); -ILboolean ilSaveDdsL(ILvoid *Lump, ILuint Size); -ILboolean ilLoadDoom(ILconst_string FileName); -ILboolean ilLoadDoomF(ILHANDLE File); -ILboolean ilLoadDoomL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadDoomFlat(ILconst_string FileName); -ILboolean ilLoadDoomFlatF(ILHANDLE File); -ILboolean ilLoadDoomFlatL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidGif(ILconst_string FileName); -ILboolean ilIsValidGifF(ILHANDLE File); -ILboolean ilIsValidGifL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadGif(ILconst_string FileName); -ILboolean ilLoadGifF(ILHANDLE File); -ILboolean ilLoadGifL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidHdr(ILconst_string FileName); -ILboolean ilIsValidHdrF(ILHANDLE File); -ILboolean ilIsValidHdrL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadHdr(ILconst_string FileName); -ILboolean ilLoadHdrF(ILHANDLE File); -ILboolean ilLoadHdrL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadIcon(ILconst_string FileName); -ILboolean ilLoadIconF(ILHANDLE File); -ILboolean ilLoadIconL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadIcns(ILconst_string FileName); -ILboolean ilLoadIcnsF(ILHANDLE File); -ILboolean ilLoadIcnsL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidJpg(ILconst_string FileName); -ILboolean ilIsValidJpgF(ILHANDLE File); -ILboolean ilIsValidJpgL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadJp2(ILconst_string FileName); -ILboolean ilLoadJp2L(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadJp2LInternal(const ILvoid *Lump, ILuint Size, ILimage *Image); -ILboolean ilLoadJpeg(ILconst_string FileName); -ILboolean ilLoadJpegF(ILHANDLE File); -ILboolean ilLoadJpegL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveJpeg(ILconst_string FileName); -ILboolean ilSaveJpegF(ILHANDLE File); -ILboolean ilSaveJpegL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidLif(ILconst_string FileName); -ILboolean ilIsValidLifF(ILHANDLE File); -ILboolean ilIsValidLifL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadLif(ILconst_string FileName); -ILboolean ilLoadLifF(ILHANDLE File); -ILboolean ilLoadLifL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadMdl(ILconst_string FileName); -ILboolean ilLoadMdlF(ILHANDLE File); -ILboolean ilLoadMdlL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadMng(ILconst_string FileName); -ILboolean ilLoadMngF(ILHANDLE File); -ILboolean ilLoadMngL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveMng(ILconst_string FileName); -ILboolean ilSaveMngF(ILHANDLE File); -ILboolean ilSaveMngL(ILvoid *Lump, ILuint Size); -ILboolean ilLoadPcd(ILconst_string FileName); -ILboolean ilLoadPcdF(ILHANDLE File); -ILboolean ilLoadPcdL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPcx(ILconst_string FileName); -ILboolean ilIsValidPcxF(ILHANDLE File); -ILboolean ilIsValidPcxL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPcx(ILconst_string FileName); -ILboolean ilLoadPcxF(ILHANDLE File); -ILboolean ilLoadPcxL(const ILvoid *Lump, ILuint Size); -ILboolean ilSavePcx(ILconst_string FileName); -ILboolean ilSavePcxF(ILHANDLE File); -ILboolean ilSavePcxL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPic(ILconst_string FileName); -ILboolean ilIsValidPicF(ILHANDLE File); -ILboolean ilIsValidPicL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPic(ILconst_string FileName); -ILboolean ilLoadPicF(ILHANDLE File); -ILboolean ilLoadPicL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPix(ILconst_string FileName); -ILboolean ilLoadPixF(ILHANDLE File); -ILboolean ilLoadPixL(const ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPng(ILconst_string FileName); -ILboolean ilIsValidPngF(ILHANDLE File); -ILboolean ilIsValidPngL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPng(ILconst_string FileName); -ILboolean ilLoadPngF(ILHANDLE File); -ILboolean ilLoadPngL(const ILvoid *Lump, ILuint Size); -ILboolean ilSavePng(ILconst_string FileName); -ILboolean ilSavePngF(ILHANDLE File); -ILboolean ilSavePngL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPnm(ILconst_string FileName); -ILboolean ilIsValidPnmF(ILHANDLE File); -ILboolean ilIsValidPnmL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPnm(ILconst_string FileName); -ILboolean ilLoadPnmF(ILHANDLE File); -ILboolean ilLoadPnmL(const ILvoid *Lump, ILuint Size); -ILboolean ilSavePnm(ILconst_string FileName); -ILboolean ilSavePnmF(ILHANDLE File); -ILboolean ilSavePnmL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPsd(ILconst_string FileName); -ILboolean ilIsValidPsdF(ILHANDLE File); -ILboolean ilIsValidPsdL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPsd(ILconst_string FileName); -ILboolean ilLoadPsdF(ILHANDLE File); -ILboolean ilLoadPsdL(const ILvoid *Lump, ILuint Size); -ILboolean ilSavePsd(ILconst_string FileName); -ILboolean ilSavePsdF(ILHANDLE File); -ILboolean ilSavePsdL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidPsp(ILconst_string FileName); -ILboolean ilIsValidPspF(ILHANDLE File); -ILboolean ilIsValidPspL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPsp(ILconst_string FileName); -ILboolean ilLoadPspF(ILHANDLE File); -ILboolean ilLoadPspL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadPxr(ILconst_string FileName); -ILboolean ilLoadPxrF(ILHANDLE File); -ILboolean ilLoadPxrL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadRaw(ILconst_string FileName); -ILboolean ilLoadRawF(ILHANDLE File); -ILboolean ilLoadRawL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveRaw(ILconst_string FileName); -ILboolean ilSaveRawF(ILHANDLE File); -ILboolean ilSaveRawL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidSgi(ILconst_string FileName); -ILboolean ilIsValidSgiF(ILHANDLE File); -ILboolean ilIsValidSgiL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadSgi(ILconst_string FileName); -ILboolean ilLoadSgiF(ILHANDLE File); -ILboolean ilLoadSgiL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveSgi(ILconst_string FileName); -ILboolean ilSaveSgiF(ILHANDLE File); -ILboolean ilSaveSgiL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidTga(ILconst_string FileName); -ILboolean ilIsValidTgaF(ILHANDLE File); -ILboolean ilIsValidTgaL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadTarga(ILconst_string FileName); -ILboolean ilLoadTargaF(ILHANDLE File); -ILboolean ilLoadTargaL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveTarga(ILconst_string FileName); -ILboolean ilSaveTargaF(ILHANDLE File); -ILboolean ilSaveTargaL(ILvoid *Lump, ILuint Size); -ILboolean ilIsValidTiff(ILconst_string FileName); -ILboolean ilIsValidTiffF(ILHANDLE File); -ILboolean ilIsValidTiffL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadTiff(ILconst_string FileName); -ILboolean ilLoadTiffF(ILHANDLE File); -ILboolean ilLoadTiffL(const ILvoid *Lump, ILuint Size); -ILboolean ilSaveTiff(ILconst_string FileName); -ILboolean ilSaveTiffF(ILHANDLE File); -ILboolean ilSaveTiffL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadWal(ILconst_string FileName); -ILboolean ilLoadWalF(ILHANDLE File); -ILboolean ilLoadWalL(const ILvoid *Lump, ILuint Size); -ILboolean ilLoadXpm(ILconst_string FileName); -ILboolean ilLoadXpmF(ILHANDLE File); -ILboolean ilLoadXpmL(const ILvoid *Lump, ILuint Size); - - -// OpenEXR is written in C++, so we have to wrap this to avoid linker errors. -/*#ifndef IL_NO_EXR - #ifdef __cplusplus - extern "C" { - #endif - ILboolean ilLoadExr(ILconst_string FileName); - #ifdef __cplusplus - } - #endif -#endif*/ - -ILboolean ilLoadExr(ILconst_string FileName); - - -#ifdef __cplusplus -} -#endif - -#endif//INTERNAL_H diff --git a/win32/devil/include/il_jp2.h b/win32/devil/include/il_jp2.h deleted file mode 100644 index ec3f44496..000000000 --- a/win32/devil/include/il_jp2.h +++ /dev/null @@ -1,20 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/24/2008 -// -// Filename: src-IL/src/il_jp2.h -// -// Description: Jpeg-2000 (.jp2) functions -// -//----------------------------------------------------------------------------- - -#ifndef JP2_H -#define JP2_H - -#include "il_internal.h" - -ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image); - -#endif//JP2_H diff --git a/win32/devil/include/il_jpeg.h b/win32/devil/include/il_jpeg.h deleted file mode 100644 index 46ef98ddc..000000000 --- a/win32/devil/include/il_jpeg.h +++ /dev/null @@ -1,29 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/16/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_jpeg.h -// -// Description: Jpeg (.jpg) functions -// -//----------------------------------------------------------------------------- - -#ifndef JPEG_H -#define JPEG_H - -#include "il_internal.h" - -ILboolean iCheckJpg(ILubyte Header[2]); -ILboolean iIsValidJpg(void); - -#ifndef IL_USE_IJL - ILboolean iLoadJpegInternal(void); - ILboolean iSaveJpegInternal(void); -#else - ILboolean iLoadJpegInternal(ILconst_string FileName, ILvoid *Lump, ILuint Size); - ILboolean iSaveJpegInternal(ILconst_string FileName, ILvoid *Lump, ILuint Size); -#endif - -#endif//JPEG_H diff --git a/win32/devil/include/il_lif.h b/win32/devil/include/il_lif.h deleted file mode 100644 index 781ac8cd5..000000000 --- a/win32/devil/include/il_lif.h +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2001 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_lif.c -// -// Description: Reads a Homeworld image. -// -//----------------------------------------------------------------------------- - - -#ifndef LIF_H -#define LIF_H - -#include "il_internal.h" - -typedef struct LIF_HEAD -{ - char Id[8]; //"Willy 7" - ILuint Version; // Version Number (260) - ILuint Flags; // Usually 50 - ILuint Width; - ILuint Height; - ILuint PaletteCRC; // CRC of palettes for fast comparison. - ILuint ImageCRC; // CRC of the image. - ILuint PalOffset; // Offset to the palette (not used). - ILuint TeamEffect0; // Team effect offset 0 - ILuint TeamEffect1; // Team effect offset 1 -} LIF_HEAD; - -ILboolean iIsValidLif(void); -ILboolean iCheckLif(LIF_HEAD *Header); -ILboolean iLoadLifInternal(void); - -#endif//LIF_H diff --git a/win32/devil/include/il_manip.h b/win32/devil/include/il_manip.h deleted file mode 100644 index 63b7ca761..000000000 --- a/win32/devil/include/il_manip.h +++ /dev/null @@ -1,245 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2001-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_manip.h -// -// Description: Image manipulation -// -//----------------------------------------------------------------------------- - -#ifndef MANIP_H -#define MANIP_H - -#ifdef _cplusplus -extern "C" { -#endif - -ILboolean ilFlipImage(void); -ILboolean ilMirrorImage(void); //@JASON New routine created 03/28/2001 - -//----------------------------------------------- -// Overflow handler for float-to-half conversion; -// generates a hardware floating-point overflow, -// which may be trapped by the operating system. -//----------------------------------------------- -#ifndef NOINLINE - -#pragma warning(push) -#pragma warning(disable : 4756) // Disables 'named type definition in parentheses' warning -INLINE ILfloat ILAPIENTRY ilFloatToHalfOverflow() { - ILfloat f = 1e10; - ILint j; - for (j = 0; j < 10; j++) - f *= f; // this will overflow before - // the for loop terminates - return f; -} -#pragma warning(pop) - -//----------------------------------------------------- -// Float-to-half conversion -- general case, including -// zeroes, denormalized numbers and exponent overflows. -//----------------------------------------------------- -INLINE ILushort ILAPIENTRY ilFloatToHalf(ILuint i) { - // - // Our floating point number, f, is represented by the bit - // pattern in integer i. Disassemble that bit pattern into - // the sign, s, the exponent, e, and the significand, m. - // Shift s into the position where it will go in in the - // resulting half number. - // Adjust e, accounting for the different exponent bias - // of float and half (127 versus 15). - // - - register int s = (i >> 16) & 0x00008000; - register int e = ((i >> 23) & 0x000000ff) - (127 - 15); - register int m = i & 0x007fffff; - - // - // Now reassemble s, e and m into a half: - // - - if (e <= 0) - { - if (e < -10) - { - // - // E is less than -10. The absolute value of f is - // less than HALF_MIN (f may be a small normalized - // float, a denormalized float or a zero). - // - // We convert f to a half zero. - // - - return 0; - } - - // - // E is between -10 and 0. F is a normalized float, - // whose magnitude is less than HALF_NRM_MIN. - // - // We convert f to a denormalized half. - // - - m = (m | 0x00800000) >> (1 - e); - - // - // Round to nearest, round "0.5" up. - // - // Rounding may cause the significand to overflow and make - // our number normalized. Because of the way a half's bits - // are laid out, we don't have to treat this case separately; - // the code below will handle it correctly. - // - - if (m & 0x00001000) - m += 0x00002000; - - // - // Assemble the half from s, e (zero) and m. - // - - return s | (m >> 13); - } - else if (e == 0xff - (127 - 15)) - { - if (m == 0) - { - // - // F is an infinity; convert f to a half - // infinity with the same sign as f. - // - - return s | 0x7c00; - } - else - { - // - // F is a NAN; we produce a half NAN that preserves - // the sign bit and the 10 leftmost bits of the - // significand of f, with one exception: If the 10 - // leftmost bits are all zero, the NAN would turn - // into an infinity, so we have to set at least one - // bit in the significand. - // - - m >>= 13; - return s | 0x7c00 | m | (m == 0); - } - } - else - { - // - // E is greater than zero. F is a normalized float. - // We try to convert f to a normalized half. - // - - // - // Round to nearest, round "0.5" up - // - - if (m & 0x00001000) - { - m += 0x00002000; - - if (m & 0x00800000) - { - m = 0; // overflow in significand, - e += 1; // adjust exponent - } - } - - // - // Handle exponent overflow - // - - if (e > 30) - { - ilFloatToHalfOverflow(); // Cause a hardware floating point overflow; - return s | 0x7c00; // if this returns, the half becomes an - } // infinity with the same sign as f. - - // - // Assemble the half from s, e and m. - // - - return s | (e << 10) | (m >> 13); - } -} - -//stolen from OpenEXR -INLINE ILuint ILAPIENTRY ilHalfToFloat (ILushort y) { - - int s = (y >> 15) & 0x00000001; - int e = (y >> 10) & 0x0000001f; - int m = y & 0x000003ff; - - if (e == 0) - { - if (m == 0) - { - // - // Plus or minus zero - // - - return s << 31; - } - else - { - // - // Denormalized number -- renormalize it - // - - while (!(m & 0x00000400)) - { - m <<= 1; - e -= 1; - } - - e += 1; - m &= ~0x00000400; - } - } - else if (e == 31) - { - if (m == 0) - { - // - // Positive or negative infinity - // - - return (s << 31) | 0x7f800000; - } - else - { - // - // Nan -- preserve sign and significand bits - // - - return (s << 31) | 0x7f800000 | (m << 13); - } - } - - // - // Normalized number - // - - e = e + (127 - 15); - m = m << 13; - - // - // Assemble s, e and m. - // - - return (s << 31) | (e << 23) | m; -} -#endif //NOINLINE - -#ifdef _cplusplus -} -#endif - -#endif//MANIP_H diff --git a/win32/devil/include/il_mdl.h b/win32/devil/include/il_mdl.h deleted file mode 100644 index 1c8c946c5..000000000 --- a/win32/devil/include/il_mdl.h +++ /dev/null @@ -1,28 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_mdl.h -// -// Description: Reads a Half-Life model file. -// -//----------------------------------------------------------------------------- - - -#ifndef MD2_H -#define MD2_H - -#include "il_internal.h" - -typedef struct TEX_HEAD -{ - char Name[64]; - ILuint Flags; - ILuint Width; - ILuint Height; - ILuint Offset; -} TEX_HEAD; - -#endif//MD2_H diff --git a/win32/devil/include/il_pal.h b/win32/devil/include/il_pal.h deleted file mode 100644 index b2b810818..000000000 --- a/win32/devil/include/il_pal.h +++ /dev/null @@ -1,54 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_pal.h -// -// Description: Loads palettes from different file formats -// -//----------------------------------------------------------------------------- - - -#ifndef IL_PAL_H -#define IL_PAL_H - -#include "il_internal.h" - -#define BUFFLEN 256 -#define PALBPP 3 - -#ifdef _MSC_VER -#pragma pack(push, packed_struct, 1) -#endif -typedef struct HALOHEAD -{ - ILushort Id; // 'AH' - ILshort Version; - ILshort Size; - ILbyte Filetype; - ILbyte Subtype; - //ILshort Brdid, Grmode; - ILint Ignored; - ILushort MaxIndex; // Colors = maxindex + 1 - ILushort MaxRed; - ILushort MaxGreen; - ILushort MaxBlue; - /*ILbyte Signature[8]; - ILbyte Filler[12];*/ - ILbyte Filler[20]; // Always 0 by PSP 4 -} IL_PACKSTRUCT HALOHEAD; -#ifdef _MSC_VER -#pragma pack(pop, packed_struct) -#endif - -ILboolean ilLoadJascPal(ILconst_string FileName); -ILboolean ilSaveJascPal(ILconst_string FileName); -char *iFgetw(ILubyte *Buff, ILint MaxLen, FILE *File); -ILboolean ilLoadHaloPal(ILconst_string FileName); -ILboolean ilLoadColPal(ILconst_string FileName); -ILboolean ilLoadActPal(ILconst_string FileName); -ILboolean ilLoadPltPal(ILconst_string FileName); - -#endif//IL_PAL_H diff --git a/win32/devil/include/il_pcx.h b/win32/devil/include/il_pcx.h deleted file mode 100644 index 3bd44ac20..000000000 --- a/win32/devil/include/il_pcx.h +++ /dev/null @@ -1,58 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_pcx.h -// -// Description: Reads and writes from/to a .pcx file. -// -//----------------------------------------------------------------------------- - - -#ifndef PCX_H -#define PCX_H - -#include "il_internal.h" - - -#ifdef _WIN32 -#pragma pack(push, packed_struct, 1) -#endif -typedef struct PCXHEAD -{ - ILubyte Manufacturer; - ILubyte Version; - ILubyte Encoding; - ILubyte Bpp; - ILushort Xmin, Ymin, Xmax, Ymax; - ILushort HDpi; - ILushort VDpi; - ILubyte ColMap[48]; - ILubyte Reserved; - ILubyte NumPlanes; - ILushort Bps; - ILushort PaletteInfo; - ILushort HScreenSize; - ILushort VScreenSize; - ILubyte Filler[54]; -} IL_PACKSTRUCT PCXHEAD; -#ifdef _WIN32 -#pragma pack(pop, packed_struct) -#endif - -// For checking and reading -ILboolean iIsValidPcx(void); -ILboolean iCheckPcx(PCXHEAD *Header); -ILboolean iLoadPcxInternal(void); -ILboolean iSavePcxInternal(void); -ILboolean iUncompressPcx(PCXHEAD *Header); -ILboolean iUncompressSmall(PCXHEAD *Header); - -// For writing -ILuint encput(ILubyte byt, ILubyte cnt); -ILuint encLine(ILubyte *inBuff, ILint inLen, ILubyte Stride); - - -#endif//PCX_H diff --git a/win32/devil/include/il_pic.h b/win32/devil/include/il_pic.h deleted file mode 100644 index ba7edff12..000000000 --- a/win32/devil/include/il_pic.h +++ /dev/null @@ -1,79 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/21/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_pic.h -// -// Description: Softimage Pic (.pic) functions -// -//----------------------------------------------------------------------------- - - -#ifndef PIC_H -#define PIC_H - -#include "il_internal.h" - -#ifdef _MSC_VER -#pragma pack(push, packed_struct, 1) -#endif -typedef struct PIC_HEAD -{ - ILint Magic; // PIC_MAGIC_NUMBER - ILfloat Version; // Version of format - ILbyte Comment[80]; // Prototype description - ILbyte Id[4]; // 'PICT' - ILshort Width; // Image width, in pixels - ILshort Height; // Image height, in pixels - ILfloat Ratio; // Pixel aspect ratio - ILshort Fields; // Picture field type - ILshort Padding; // Unused -} IL_PACKSTRUCT PIC_HEAD; - -typedef struct CHANNEL -{ - ILubyte Size; - ILubyte Type; - ILubyte Chan; - ILvoid *Next; -} CHANNEL; -#ifdef _MSC_VER -#pragma pack(pop, packed_struct) -#endif - - -// Data type -#define PIC_UNSIGNED_INTEGER 0x00 -#define PIC_SIGNED_INTEGER 0x10 // XXX: Not implemented -#define PIC_SIGNED_FLOAT 0x20 // XXX: Not implemented - - -// Compression type -#define PIC_UNCOMPRESSED 0x00 -#define PIC_PURE_RUN_LENGTH 0x01 -#define PIC_MIXED_RUN_LENGTH 0x02 - -// CHANNEL types (OR'd) -#define PIC_RED_CHANNEL 0x80 -#define PIC_GREEN_CHANNEL 0x40 -#define PIC_BLUE_CHANNEL 0x20 -#define PIC_ALPHA_CHANNEL 0x10 -#define PIC_SHADOW_CHANNEL 0x08 // XXX: Not implemented -#define PIC_DEPTH_CHANNEL 0x04 // XXX: Not implemented -#define PIC_AUXILIARY_1_CHANNEL 0x02 // XXX: Not implemented -#define PIC_AUXILIARY_2_CHANNEL 0x01 // XXX: Not implemented - -ILboolean iIsValidPic(void); -ILboolean iCheckPic(PIC_HEAD *Header); -ILboolean iLoadPicInternal(void); -ILboolean readScanlines(ILuint *image, ILint width, ILint height, CHANNEL *channel, ILuint alpha); -ILuint readScanline(ILubyte *scan, ILint width, CHANNEL *channel, ILint bytes); -ILboolean channelReadRaw(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes); -ILboolean channelReadPure(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes); -ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes); - - - -#endif//PIC_H diff --git a/win32/devil/include/il_pnm.h b/win32/devil/include/il_pnm.h deleted file mode 100644 index a93a1a6bb..000000000 --- a/win32/devil/include/il_pnm.h +++ /dev/null @@ -1,46 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_pnm.h -// -// Description: Reads/writes to/from pbm/pgm/ppm formats -// -//----------------------------------------------------------------------------- - - -#ifndef PPMPGM_H -#define PPMPGM_H - -#include "il_internal.h" - -#define IL_PBM_ASCII 0x0001 -#define IL_PGM_ASCII 0x0002 -#define IL_PPM_ASCII 0x0003 -#define IL_PBM_BINARY 0x0004 -#define IL_PGM_BINARY 0x0005 -#define IL_PPM_BINARY 0x0006 - -typedef struct PPMINFO -{ - ILenum Type; - ILuint Width; - ILuint Height; - ILuint MaxColour; - ILubyte Bpp; -} PPMINFO; - -ILboolean iIsValidPnm(void); -ILboolean iCheckPnm(char Header[2]); -ILboolean iLoadPnmInternal(void); -ILboolean iSavePnmInternal(void); -ILimage *ilReadAsciiPpm(PPMINFO *Info); -ILimage *ilReadBinaryPpm(PPMINFO *Info); -ILimage *ilReadBitPbm(PPMINFO *Info); -ILboolean iGetWord(ILboolean); -ILvoid PbmMaximize(ILimage *Image); - - -#endif//PPMPGM_H diff --git a/win32/devil/include/il_psd.h b/win32/devil/include/il_psd.h deleted file mode 100644 index 8d7028d7b..000000000 --- a/win32/devil/include/il_psd.h +++ /dev/null @@ -1,56 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2001 by Denton Woods -// Last modified: 01/23/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_il_psd.c -// -// Description: Reads from a PhotoShop (.psd) file. -// -//----------------------------------------------------------------------------- - - -#ifndef PSD_H -#define PSD_H - -#include "il_internal.h" - -#ifdef _MSC_VER -#pragma pack(push, packed_struct, 1) -#endif -typedef struct PSDHEAD -{ - ILubyte Signature[4]; - ILushort Version; - ILubyte Reserved[6]; - ILushort Channels; - ILuint Height; - ILuint Width; - ILushort Depth; - ILushort Mode; -} IL_PACKSTRUCT PSDHEAD; - -#ifdef _MSC_VER -#pragma pack(pop, packed_struct) -#endif - -ILushort ChannelNum; - -ILboolean iIsValidPsd(void); -ILboolean iCheckPsd(PSDHEAD *Header); -ILboolean iLoadPsdInternal(void); -ILboolean ReadPsd(PSDHEAD *Head); -ILboolean ReadGrey(PSDHEAD *Head); -ILboolean ReadIndexed(PSDHEAD *Head); -ILboolean ReadRGB(PSDHEAD *Head); -ILboolean ReadCMYK(PSDHEAD *Head); -ILuint *GetCompChanLen(PSDHEAD *Head); -ILboolean PsdGetData(PSDHEAD *Head, ILvoid *Buffer, ILboolean Compressed); -ILboolean ParseResources(ILuint ResourceSize, ILubyte *Resources); -ILboolean GetSingleChannel(PSDHEAD *Head, ILubyte *Buffer, ILboolean Compressed); -ILboolean iSavePsdInternal(void); - - - -#endif//PSD_H diff --git a/win32/devil/include/il_psp.h b/win32/devil/include/il_psp.h deleted file mode 100644 index ec59885ba..000000000 --- a/win32/devil/include/il_psp.h +++ /dev/null @@ -1,250 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/02/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_psp.h -// -// Description: Reads a Paint Shop Pro file. -// -//----------------------------------------------------------------------------- - - -#ifndef PSP_H -#define PSP_H - -#include "il_internal.h" - - -// Block identifiers -enum PSPBlockID { - PSP_IMAGE_BLOCK = 0, // (0) General Image Attributes Block (main) - PSP_CREATOR_BLOCK, // (1) Creator Data Block (main) - PSP_COLOR_BLOCK, // (2) Color Palette Block (main and sub) - PSP_LAYER_START_BLOCK, // (3) Layer Bank Block (main) - PSP_LAYER_BLOCK, // (4) Layer Block (sub) - PSP_CHANNEL_BLOCK, // (5) Channel Block (sub) - PSP_SELECTION_BLOCK, // (6) Selection Block (main) - PSP_ALPHA_BANK_BLOCK, // (7) Alpha Bank Block (main) - PSP_ALPHA_CHANNEL_BLOCK, // (8) Alpha Channel Block (sub) - PSP_COMPOSITE_IMAGE_BLOCK, // (9) Composite Image Block (sub) - PSP_EXTENDED_DATA_BLOCK, // (10) Extended Data Block (main) - PSP_TUBE_BLOCK, // (11) Picture Tube Data Block (main) - PSP_ADJUSTMENT_EXTENSION_BLOCK, // (12) Adjustment Layer Block (sub) - PSP_VECTOR_EXTENSION_BLOCK, // (13) Vector Layer Block (sub) - PSP_SHAPE_BLOCK, // (14) Vector Shape Block (sub) - PSP_PAINTSTYLE_BLOCK, // (15) Paint Style Block (sub) - PSP_COMPOSITE_IMAGE_BANK_BLOCK, // (16) Composite Image Bank (main) - PSP_COMPOSITE_ATTRIBUTES_BLOCK, // (17) Composite Image Attr. (sub) - PSP_JPEG_BLOCK, // (18) JPEG Image Block (sub) - PSP_LINESTYLE_BLOCK, // (19) Line Style Block (sub) - PSP_TABLE_BANK_BLOCK, // (20) Table Bank Block (main) - PSP_TABLE_BLOCK, // (21) Table Block (sub) - PSP_PAPER_BLOCK, // (22) Vector Table Paper Block (sub) - PSP_PATTERN_BLOCK, // (23) Vector Table Pattern Block (sub) -}; - - -// Bitmap type -enum PSPDIBType { - PSP_DIB_IMAGE = 0, // Layer color bitmap - PSP_DIB_TRANS_MASK, // Layer transparency mask bitmap - PSP_DIB_USER_MASK, // Layer user mask bitmap - PSP_DIB_SELECTION, // Selection mask bitmap - PSP_DIB_ALPHA_MASK, // Alpha channel mask bitmap - PSP_DIB_THUMBNAIL // Thumbnail bitmap -}; - -// Channel types -enum PSPChannelType { - PSP_CHANNEL_COMPOSITE = 0, // Channel of single channel bitmap - PSP_CHANNEL_RED, // Red channel of 24 bit bitmap - PSP_CHANNEL_GREEN, // Green channel of 24 bit bitmap - PSP_CHANNEL_BLUE // Blue channel of 24 bit bitmap -}; - -// Possible metrics used to measure resolution -enum PSP_METRIC { - PSP_METRIC_UNDEFINED = 0, // Metric unknown - PSP_METRIC_INCH, // Resolution is in inches - PSP_METRIC_CM // Resolution is in centimeters -}; - - -// Possible types of compression. -enum PSPCompression { - PSP_COMP_NONE = 0, // No compression - PSP_COMP_RLE, // RLE compression - PSP_COMP_LZ77, // LZ77 compression - PSP_COMP_JPEG // JPEG compression (only used by thumbnail and composite image) -}; - - -// Picture tube placement mode. -enum TubePlacementMode { - tpmRandom, // Place tube images in random intervals - tpmConstant // Place tube images in constant intervals -}; - -// Picture tube selection mode. -enum TubeSelectionMode { - tsmRandom, // Randomly select the next image in tube to display - tsmIncremental, // Select each tube image in turn - tsmAngular, // Select image based on cursor direction - tsmPressure, // Select image based on pressure (from pressure-sensitive pad) - tsmVelocity // Select image based on cursor speed -}; - -// Extended data field types. -enum PSPExtendedDataID { - PSP_XDATA_TRNS_INDEX = 0 // Transparency index field -}; - -// Creator field types. -enum PSPCreatorFieldID { - PSP_CRTR_FLD_TITLE = 0, // Image document title field - PSP_CRTR_FLD_CRT_DATE, // Creation date field - PSP_CRTR_FLD_MOD_DATE, // Modification date field - PSP_CRTR_FLD_ARTIST, // Artist name field - PSP_CRTR_FLD_CPYRGHT, // Copyright holder name field - PSP_CRTR_FLD_DESC, // Image document description field - PSP_CRTR_FLD_APP_ID, // Creating app id field - PSP_CRTR_FLD_APP_VER, // Creating app version field -}; - -// Creator application identifiers. -enum PSPCreatorAppID { - PSP_CREATOR_APP_UNKNOWN = 0, // Creator application unknown - PSP_CREATOR_APP_PAINT_SHOP_PRO // Creator is Paint Shop Pro -}; - -// Layer types. -enum PSPLayerType { - PSP_LAYER_NORMAL = 0, // Normal layer - PSP_LAYER_FLOATING_SELECTION // Floating selection layer -}; - -// Truth values. -/*enum PSP_BOOLEAN { - FALSE = 0, - TRUE -};*/ - - - -#ifdef _MSC_VER -#pragma pack(push, packed_struct, 1) -#endif -typedef struct PSPRECT -{ - ILuint x1,y1,x2,y2; -} IL_PACKSTRUCT PSPRECT; - -typedef struct PSPHEAD -{ - char FileSig[32]; - ILushort MajorVersion; - ILushort MinorVersion; -} IL_PACKSTRUCT PSPHEAD; - -typedef struct BLOCKHEAD -{ - ILubyte HeadID[4]; - ILushort BlockID; - ILuint BlockLen; -} IL_PACKSTRUCT BLOCKHEAD; - -typedef struct GENATT_CHUNK -{ - ILint Width; - ILint Height; - ILdouble Resolution; - ILubyte ResMetric; - ILushort Compression; - ILushort BitDepth; - ILushort PlaneCount; - ILuint ColourCount; - ILubyte GreyscaleFlag; - ILuint SizeOfImage; - ILint ActiveLayer; - ILushort LayerCount; - ILuint GraphicContents; -} IL_PACKSTRUCT GENATT_CHUNK; - -typedef struct LAYERINFO_CHUNK -{ - ILubyte LayerType; - PSPRECT ImageRect; - PSPRECT SavedImageRect; - ILubyte Opacity; - ILubyte BlendingMode; - ILubyte LayerFlags; - ILubyte TransProtFlag; - ILubyte LinkID; - PSPRECT MaskRect; - PSPRECT SavedMaskRect; - ILubyte MaskLinked; - ILubyte MaskDisabled; - ILubyte InvertMaskBlend; - ILushort BlendRange; - ILubyte SourceBlend1[4]; - ILubyte DestBlend1[4]; - ILubyte SourceBlend2[4]; - ILubyte DestBlend2[4]; - ILubyte SourceBlend3[4]; - ILubyte DestBlend3[4]; - ILubyte SourceBlend4[4]; - ILubyte DestBlend4[4]; - ILubyte SourceBlend5[4]; - ILubyte DestBlend5[4]; -} IL_PACKSTRUCT LAYERINFO_CHUNK; - -typedef struct LAYERBITMAP_CHUNK -{ - ILushort NumBitmaps; - ILushort NumChannels; -} IL_PACKSTRUCT LAYERBITMAP_CHUNK; - -typedef struct CHANNEL_CHUNK -{ - ILuint CompLen; - ILuint Length; - ILushort BitmapType; - ILushort ChanType; -} IL_PACKSTRUCT CHANNEL_CHUNK; - -typedef struct ALPHAINFO_CHUNK -{ - PSPRECT AlphaRect; - PSPRECT AlphaSavedRect; -} IL_PACKSTRUCT ALPHAINFO_CHUNK; - -typedef struct ALPHA_CHUNK -{ - ILushort BitmapCount; - ILushort ChannelCount; -} IL_PACKSTRUCT ALPHA_CHUNK; - -#ifdef _MSC_VER -#pragma pack(pop, packed_struct) -#endif - - -// Function definitions -ILboolean iLoadPspInternal(void); -ILboolean iCheckPsp(void); -ILboolean iIsValidPsp(void); -ILboolean ReadGenAttributes(void); -ILboolean ParseChunks(void); -ILboolean ReadLayerBlock(ILuint BlockLen); -ILboolean ReadAlphaBlock(ILuint BlockLen); -ILubyte *GetChannel(void); -ILboolean UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen); -ILboolean ReadPalette(ILuint BlockLen); -ILboolean AssembleImage(void); -ILboolean Cleanup(void); - - - -#endif//PSP_H diff --git a/win32/devil/include/il_q2pal.h b/win32/devil/include/il_q2pal.h deleted file mode 100644 index 1a3ff1b6e..000000000 --- a/win32/devil/include/il_q2pal.h +++ /dev/null @@ -1,276 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_q2pal.h -// -// Description: The default Quake2 palette -// -//----------------------------------------------------------------------------- - -#ifndef Q2PAL_H -#define Q2PAL_H - -#define IL_Q2PAL_SIZE 768 -ILubyte ilDefaultQ2Pal[IL_Q2PAL_SIZE] = { - 0, 0, 0, - 15, 15, 15, - 31, 31, 31, - 47, 47, 47, - 63, 63, 63, - 75, 75, 75, - 91, 91, 91, - 107, 107, 107, - 123, 123, 123, - 139, 139, 139, - 155, 155, 155, - 171, 171, 171, - 187, 187, 187, - 203, 203, 203, - 219, 219, 219, - 235, 235, 235, - 99, 75, 35, - 91, 67, 31, - 83, 63, 31, - 79, 59, 27, - 71, 55, 27, - 63, 47, 23, - 59, 43, 23, - 51, 39, 19, - 47, 35, 19, - 43, 31, 19, - 39, 27, 15, - 35, 23, 15, - 27, 19, 11, - 23, 15, 11, - 19, 15, 7, - 15, 11, 7, - 95, 95, 111, - 91, 91, 103, - 91, 83, 95, - 87, 79, 91, - 83, 75, 83, - 79, 71, 75, - 71, 63, 67, - 63, 59, 59, - 59, 55, 55, - 51, 47, 47, - 47, 43, 43, - 39, 39, 39, - 35, 35, 35, - 27, 27, 27, - 23, 23, 23, - 19, 19, 19, - 143, 119, 83, - 123, 99, 67, - 115, 91, 59, - 103, 79, 47, - 207, 151, 75, - 167, 123, 59, - 139, 103, 47, - 111, 83, 39, - 235, 159, 39, - 203, 139, 35, - 175, 119, 31, - 147, 99, 27, - 119, 79, 23, - 91, 59, 15, - 63, 39, 11, - 35, 23, 7, - 167, 59, 43, - 159, 47, 35, - 151, 43, 27, - 139, 39, 19, - 127, 31, 15, - 115, 23, 11, - 103, 23, 7, - 87, 19, 0, - 75, 15, 0, - 67, 15, 0, - 59, 15, 0, - 51, 11, 0, - 43, 11, 0, - 35, 11, 0, - 27, 7, 0, - 19, 7, 0, - 123, 95, 75, - 115, 87, 67, - 107, 83, 63, - 103, 79, 59, - 95, 71, 55, - 87, 67, 51, - 83, 63, 47, - 75, 55, 43, - 67, 51, 39, - 63, 47, 35, - 55, 39, 27, - 47, 35, 23, - 39, 27, 19, - 31, 23, 15, - 23, 15, 11, - 15, 11, 7, - 111, 59, 23, - 95, 55, 23, - 83, 47, 23, - 67, 43, 23, - 55, 35, 19, - 39, 27, 15, - 27, 19, 11, - 15, 11, 7, - 179, 91, 79, - 191, 123, 111, - 203, 155, 147, - 215, 187, 183, - 203, 215, 223, - 179, 199, 211, - 159, 183, 195, - 135, 167, 183, - 115, 151, 167, - 91, 135, 155, - 71, 119, 139, - 47, 103, 127, - 23, 83, 111, - 19, 75, 103, - 15, 67, 91, - 11, 63, 83, - 7, 55, 75, - 7, 47, 63, - 7, 39, 51, - 0, 31, 43, - 0, 23, 31, - 0, 15, 19, - 0, 7, 11, - 0, 0, 0, - 139, 87, 87, - 131, 79, 79, - 123, 71, 71, - 115, 67, 67, - 107, 59, 59, - 99, 51, 51, - 91, 47, 47, - 87, 43, 43, - 75, 35, 35, - 63, 31, 31, - 51, 27, 27, - 43, 19, 19, - 31, 15, 15, - 19, 11, 11, - 11, 7, 7, - 0, 0, 0, - 151, 159, 123, - 143, 151, 115, - 135, 139, 107, - 127, 131, 99, - 119, 123, 95, - 115, 115, 87, - 107, 107, 79, - 99, 99, 71, - 91, 91, 67, - 79, 79, 59, - 67, 67, 51, - 55, 55, 43, - 47, 47, 35, - 35, 35, 27, - 23, 23, 19, - 15, 15, 11, - 159, 75, 63, - 147, 67, 55, - 139, 59, 47, - 127, 55, 39, - 119, 47, 35, - 107, 43, 27, - 99, 35, 23, - 87, 31, 19, - 79, 27, 15, - 67, 23, 11, - 55, 19, 11, - 43, 15, 7, - 31, 11, 7, - 23, 7, 0, - 11, 0, 0, - 0, 0, 0, - 119, 123, 207, - 111, 115, 195, - 103, 107, 183, - 99, 99, 167, - 91, 91, 155, - 83, 87, 143, - 75, 79, 127, - 71, 71, 115, - 63, 63, 103, - 55, 55, 87, - 47, 47, 75, - 39, 39, 63, - 35, 31, 47, - 27, 23, 35, - 19, 15, 23, - 11, 7, 7, - 155, 171, 123, - 143, 159, 111, - 135, 151, 99, - 123, 139, 87, - 115, 131, 75, - 103, 119, 67, - 95, 111, 59, - 87, 103, 51, - 75, 91, 39, - 63, 79, 27, - 55, 67, 19, - 47, 59, 11, - 35, 47, 7, - 27, 35, 0, - 19, 23, 0, - 11, 15, 0, - 0, 255, 0, - 35, 231, 15, - 63, 211, 27, - 83, 187, 39, - 95, 167, 47, - 95, 143, 51, - 95, 123, 51, - 255, 255, 255, - 255, 255, 211, - 255, 255, 167, - 255, 255, 127, - 255, 255, 83, - 255, 255, 39, - 255, 235, 31, - 255, 215, 23, - 255, 191, 15, - 255, 171, 7, - 255, 147, 0, - 239, 127, 0, - 227, 107, 0, - 211, 87, 0, - 199, 71, 0, - 183, 59, 0, - 171, 43, 0, - 155, 31, 0, - 143, 23, 0, - 127, 15, 0, - 115, 7, 0, - 95, 0, 0, - 71, 0, 0, - 47, 0, 0, - 27, 0, 0, - 239, 0, 0, - 55, 55, 255, - 255, 0, 0, - 0, 0, 255, - 43, 43, 35, - 27, 27, 23, - 19, 19, 15, - 235, 151, 127, - 195, 115, 83, - 159, 87, 51, - 123, 63, 27, - 235, 211, 199, - 199, 171, 155, - 167, 139, 119, - 135, 107, 87, - 159, 91, 83 -}; - -#endif//Q2PAL_H diff --git a/win32/devil/include/il_register.h b/win32/devil/include/il_register.h deleted file mode 100644 index 916df28f4..000000000 --- a/win32/devil/include/il_register.h +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_register.h -// -// Description: Allows the caller to specify user-defined callback functions -// to open files DevIL does not support, to parse files -// differently, or anything else a person can think up. -// -//----------------------------------------------------------------------------- - - -#ifndef REGISTER_H -#define REGISTER_H - -#include "il_internal.h" - -typedef struct iFormatL -{ - ILstring Ext; - IL_LOADPROC Load; - struct iFormatL *Next; -} iFormatL; - -typedef struct iFormatS -{ - ILstring Ext; - IL_SAVEPROC Save; - struct iFormatS *Next; -} iFormatS; - -#define I_LOAD_FUNC 0 -#define I_SAVE_FUNC 1 - -ILboolean iRegisterLoad(ILconst_string FileName); -ILboolean iRegisterSave(ILconst_string FileName); - -#endif//REGISTER_H diff --git a/win32/devil/include/il_rle.h b/win32/devil/include/il_rle.h deleted file mode 100644 index 498bddbe7..000000000 --- a/win32/devil/include/il_rle.h +++ /dev/null @@ -1,92 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_rle.h -// -// Description: Functions for run-length encoding -// -//----------------------------------------------------------------------------- - -#ifndef RLE_H -#define RLE_H - -#include "il_internal.h" - -#define TGA_MAX_RUN 128 -#define SGI_MAX_RUN 127 -#define BMP_MAX_RUN 127 - -#ifdef IL_RLE_C -#undef NOINLINE -#undef INLINE -#define INLINE -#endif - -#ifndef NOINLINE -INLINE ILuint GetPix(ILubyte *p, ILuint bpp) { - ILuint Pixel; - Pixel = (ILuint)*p++; - - while( bpp-- > 1 ) { - Pixel <<= 8; - Pixel |= (ILuint)*p++; - } - return Pixel; -} - -INLINE ILint CountDiffPixels(ILubyte *p, ILuint bpp, ILuint pixCnt) { - ILuint pixel; - ILuint nextPixel = 0; - ILint n; - - n = 0; - if (pixCnt == 1) - return pixCnt; - pixel = GetPix(p, bpp); - - while (pixCnt > 1) { - p += bpp; - nextPixel = GetPix(p, bpp); - if (nextPixel == pixel) - break; - pixel = nextPixel; - ++n; - --pixCnt; - } - - if (nextPixel == pixel) - return n; - return n + 1; -} - - -INLINE ILint CountSamePixels(ILubyte *p, ILuint bpp, ILuint pixCnt) { - ILuint pixel; - ILuint nextPixel; - ILint n; - - n = 1; - pixel = GetPix(p, bpp); - pixCnt--; - - while (pixCnt > 0) { - p += bpp; - nextPixel = GetPix(p, bpp); - if (nextPixel != pixel) - break; - ++n; - --pixCnt; - } - - return n; -} -#endif - -ILuint GetPix(ILubyte *p, ILuint bpp); -ILint CountDiffPixels(ILubyte *p, ILuint bpp, ILuint pixCnt); -ILint CountSamePixels(ILubyte *p, ILuint bpp, ILuint pixCnt); - -#endif//RLE_H diff --git a/win32/devil/include/il_sgi.h b/win32/devil/include/il_sgi.h deleted file mode 100644 index 859de327f..000000000 --- a/win32/devil/include/il_sgi.h +++ /dev/null @@ -1,66 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/include/sgi.h -// -// Description: Reads from and writes to SGI graphics files. -// -//----------------------------------------------------------------------------- - - -#ifndef SGI_H -#define SGI_H - -#include "il_internal.h" - -typedef struct iSgiHeader -{ - ILshort MagicNum; // IRIS image file magic number - ILbyte Storage; // Storage format - ILbyte Bpc; // Number of bytes per pixel channel - ILushort Dim; // Number of dimensions - // 1: single channel, 1 row with XSize pixels - // 2: single channel, XSize*YSize pixels - // 3: ZSize channels, XSize*YSize pixels - - ILushort XSize; // X size in pixels - ILushort YSize; // Y size in pixels - ILushort ZSize; // Number of channels - ILint PixMin; // Minimum pixel value - ILint PixMax; // Maximum pixel value - ILint Dummy1; // Ignored - ILbyte Name[80]; // Image name - ILint ColMap; // Colormap ID - ILbyte Dummy[404]; // Ignored -} IL_PACKSTRUCT iSgiHeader; - -// Sgi format #define's -#define SGI_VERBATIM 0 -#define SGI_RLE 1 -#define SGI_MAGICNUM 474 - -// Sgi colormap types -#define SGI_COLMAP_NORMAL 0 -#define SGI_COLMAP_DITHERED 1 -#define SGI_COLMAP_SCREEN 2 -#define SGI_COLMAP_COLMAP 3 - - -// Internal functions -ILboolean iIsValidSgi(void); -ILboolean iCheckSgi(iSgiHeader *Header); -ILboolean iLoadSgiInternal(void); -ILboolean iSaveSgiInternal(void); -ILvoid iExpandScanLine(ILubyte *Dest, ILubyte *Src, ILuint Bpc); -ILint iGetScanLine(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length); -ILint iGetScanLineFast(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length, ILubyte*); -ILvoid sgiSwitchData(ILubyte *Data, ILuint SizeOfData); -ILboolean iNewSgi(iSgiHeader *Head); -ILboolean iReadNonRleSgi(iSgiHeader *Head); -ILboolean iReadRleSgi(iSgiHeader *Head); -ILboolean iSaveRleSgi(ILubyte *Data, ILuint w, ILuint h, ILuint numChannels, ILuint bps); - -#endif//SGI_H diff --git a/win32/devil/include/il_stack.h b/win32/devil/include/il_stack.h deleted file mode 100644 index 05fbe4f19..000000000 --- a/win32/devil/include/il_stack.h +++ /dev/null @@ -1,43 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_stack.h -// -// Description: The main image stack -// -//----------------------------------------------------------------------------- - -#ifndef IMAGESTACK_H -#define IMAGESTACK_H - -#include "il_internal.h" - - -// Just a guess...seems large enough -#define I_STACK_INCREMENT 1024 - -typedef struct iFree -{ - ILuint Name; - void *Next; -} iFree; - - -// Internal functions -ILboolean iEnlargeStack(void); -ILvoid iFreeMem(void); - -// Globals for il_stack.c -ILuint StackSize = 0; -ILuint LastUsed = 0; -ILuint CurName = 0; -ILimage **ImageStack = NULL; -iFree *FreeNames = NULL; -ILboolean OnExit = IL_FALSE; -ILboolean ParentImage = IL_TRUE; - - -#endif//IMAGESTACK_H diff --git a/win32/devil/include/il_states.h b/win32/devil/include/il_states.h deleted file mode 100644 index 114a14ece..000000000 --- a/win32/devil/include/il_states.h +++ /dev/null @@ -1,290 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/24/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_states.h -// -// Description: State machine -// -//----------------------------------------------------------------------------- - - -#ifndef STATES_H -#define STATES_H - -#include "il_internal.h" - - -ILboolean ilAble(ILenum Mode, ILboolean Flag); - - -#define IL_ATTRIB_STACK_MAX 32 - -ILuint ilCurrentPos = 0; // Which position on the stack - -// -// Various states -// - -typedef struct IL_STATES -{ - // Origin states - ILboolean ilOriginSet; - ILenum ilOriginMode; - // Format and type states - ILboolean ilFormatSet; - ILboolean ilTypeSet; - ILenum ilFormatMode; - ILenum ilTypeMode; - // File mode states - ILboolean ilOverWriteFiles; - // Palette states - ILboolean ilAutoConvPal; - // Load fail states - ILboolean ilDefaultOnFail; - // Key colour states - ILboolean ilUseKeyColour; - // Compression states - ILenum ilCompression; - // Interlace states - ILenum ilInterlace; - // Quantization states - ILenum ilQuantMode; - ILuint ilNeuSample; - ILuint ilQuantMaxIndexs; - // DXTC states - ILboolean ilKeepDxtcData; - - - // - // Format-specific states - // - - ILboolean ilTgaCreateStamp; - ILuint ilJpgQuality; - ILboolean ilPngInterlace; - ILboolean ilTgaRle; - ILboolean ilBmpRle; - ILboolean ilSgiRle; - ILenum ilJpgFormat; - ILenum ilDxtcFormat; - ILenum ilPcdPicNum; - - ILint ilPngAlphaIndex; // this index should be treated as an alpha key (most formats use this rather than having alpha in the palette), -1 for none - // currently only used when writing out .png files and should obviously be set to -1 most of the time - - // - // Format-specific strings - // - - char *ilTgaId; - char *ilTgaAuthName; - char *ilTgaAuthComment; - char *ilPngAuthName; - char *ilPngTitle; - char *ilPngDescription; - char *ilTifDescription; - char *ilTifHostComputer; - char *ilTifDocumentName; - char *ilTifAuthName; - char *ilCHeader; - - - - -} IL_STATES; - -IL_STATES ilStates[IL_ATTRIB_STACK_MAX]; - - -typedef struct IL_HINTS -{ - // Memory vs. Speed trade-off - ILenum MemVsSpeedHint; - // Compression hints - ILenum CompressHint; - -} IL_HINTS; - -IL_HINTS ilHints; - - -#ifndef IL_NO_BMP - #define IL_BMP_EXT "bmp dib " -#else - #define IL_BMP_EXT "" -#endif - -#ifndef IL_NO_CHEAD - #define IL_CHEAD_EXT "h " -#else - #define IL_CHEAD_EXT "" -#endif - -#ifndef IL_NO_CUT - #define IL_CUT_EXT "cut " -#else - #define IL_CUT_EXT "" -#endif - -#ifndef IL_NO_DCX - #define IL_DCX_EXT "dcx " -#else - #define IL_DCX_EXT "" -#endif - -#ifndef IL_NO_DDS - #define IL_DDS_EXT "dds " -#else - #define IL_DDS_EXT "" -#endif - -#ifndef IL_NO_EXR - #define IL_EXR_EXT "exr " -#else - #define IL_EXR_EXT "" -#endif - -#ifndef IL_NO_GIF - #define IL_GIF_EXT "gif " -#else - #define IL_GIF_EXT "" -#endif - - -#ifndef IL_NO_HDR - - #define IL_HDR_EXT "hdr " - -#else - - #define IL_HDR_EXT "" - -#endif - - -#ifndef IL_NO_ICNS - #define IL_ICNS_EXT "icns " -#else - #define IL_ICNS_EXT "" -#endif - -#ifndef IL_NO_ICO - #define IL_ICO_EXT "ico cur " -#else - #define IL_ICO_EXT "" -#endif - -#ifndef IL_NO_JP2 - #define IL_JP2_EXT "jp2 " -#else - #define IL_JP2_EXT "" -#endif - -#ifndef IL_NO_JPG - #define IL_JPG_EXT "jpg jpe jpeg " -#else - #define IL_JPG_EXT "" -#endif - -#ifndef IL_NO_LIF - #define IL_LIF_EXT "lif " -#else - #define IL_LIF_EXT "" -#endif - -#ifndef IL_NO_MDL - #define IL_MDL_EXT "mdl " -#else - #define IL_MDL_EXT "" -#endif - -#ifndef IL_NO_MNG - #define IL_MNG_EXT "mng jng " -#else - #define IL_MNG_EXT "" -#endif - -#ifndef IL_NO_PCX - #define IL_PCX_EXT "pcx " -#else - #define IL_PCX_EXT "" -#endif - -#ifndef IL_NO_PIC - #define IL_PIC_EXT "pic " -#else - #define IL_PIC_EXT "" -#endif - -#ifndef IL_NO_PIX - #define IL_PIX_EXT "pix " -#else - #define IL_PIX_EXT "" -#endif - -#ifndef IL_NO_PNG - #define IL_PNG_EXT "png " -#else - #define IL_PNG_EXT "" -#endif - -#ifndef IL_NO_PNM - #define IL_PNM_EXT "pbm pgm pnm ppm " -#else - #define IL_PNM_EXT "" -#endif - -#ifndef IL_NO_PSD - #define IL_PSD_EXT "psd pdd " -#else - #define IL_PSD_EXT "" -#endif - -#ifndef IL_NO_PSP - #define IL_PSP_EXT "psp " -#else - #define IL_PSP_EXT "" -#endif - -#ifndef IL_NO_PXR - #define IL_PXR_EXT "pxr " -#else - #define IL_PXR_EXT "" -#endif - -#ifndef IL_NO_SGI - #define IL_SGI_EXT "sgi bw rgb rgba " -#else - #define IL_SGI_EXT "" -#endif - -#ifndef IL_NO_TGA - #define IL_TGA_EXT "tga vda icb vst " -#else - #define IL_TGA_EXT "" -#endif - -#ifndef IL_NO_TIF - #define IL_TIF_EXT "tif tiff " -#else - #define IL_TIF_EXT "" -#endif - -#ifndef IL_NO_WAL - #define IL_WAL_EXT "wal " -#else - #define IL_WAL_EXT "" -#endif - -#ifndef IL_NO_XPM - #define IL_XPM_EXT "xpm " -#else - #define IL_XPM_EXT "" -#endif - - - -#endif//STATES_H diff --git a/win32/devil/include/il_targa.h b/win32/devil/include/il_targa.h deleted file mode 100644 index f840077e5..000000000 --- a/win32/devil/include/il_targa.h +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/include/il_targa.h -// -// Description: Targa (.tga) functions -// -//----------------------------------------------------------------------------- - - -#ifndef TARGA_H -#define TARGA_H - -#include "il_internal.h" - -#ifdef _MSC_VER -#pragma pack(push, tga_struct, 1) -#elif defined(MACOSX) || defined(__GNUC__) -#pragma pack(1) -#endif - -typedef struct TARGAHEAD -{ - ILubyte IDLen; - ILubyte ColMapPresent; - ILubyte ImageType; - ILshort FirstEntry; - ILshort ColMapLen; - ILubyte ColMapEntSize; - - ILshort OriginX; - ILshort OriginY; - ILushort Width; - ILushort Height; - ILubyte Bpp; - ILubyte ImageDesc; -} IL_PACKSTRUCT TARGAHEAD; - -typedef struct TARGAFOOTER -{ - ILuint ExtOff; // Extension Area Offset - ILuint DevDirOff; // Developer Directory Offset - ILbyte Signature[16]; // TRUEVISION-XFILE - ILbyte Reserved; // ASCII period '.' - ILbyte NullChar; // NULL -} IL_PACKSTRUCT TARGAFOOTER; -#if defined(MACOSX) || defined(__GNUC__) -#pragma pack() -#elif _MSC_VER -#pragma pack(pop, tga_struct) -#endif - -#define TGA_EXT_LEN 495 -typedef struct TARGAEXT -{ - // Dev Directory - // We don't mess with this - - // Extension Area - ILshort Size; // should be TGA_EXT_LEN - ILbyte AuthName[41]; // the image author's name - ILbyte AuthComments[324]; // author's comments - ILshort Month, Day, Year, Hour, Minute, Second; // internal date of file - ILbyte JobID[41]; // the job description (if any) - ILshort JobHour, JobMin, JobSecs; // the job's time - ILbyte SoftwareID[41]; // the software that created this - ILshort SoftwareVer; // the software version number * 100 - ILbyte SoftwareVerByte; // the software version letter - ILint KeyColor; // the transparent colour -} TARGAEXT; - - -// Different Targa formats -#define TGA_NO_DATA 0 -#define TGA_COLMAP_UNCOMP 1 -#define TGA_UNMAP_UNCOMP 2 -#define TGA_BW_UNCOMP 3 -#define TGA_COLMAP_COMP 9 -#define TGA_UNMAP_COMP 10 -#define TGA_BW_COMP 11 - - -// Targa origins -#define IMAGEDESC_ORIGIN_MASK 0x30 -#define IMAGEDESC_TOPLEFT 0x20 -#define IMAGEDESC_BOTLEFT 0x00 -#define IMAGEDESC_BOTRIGHT 0x10 -#define IMAGEDESC_TOPRIGHT 0x30 - - -// Internal functions -ILboolean iIsValidTarga(); -ILboolean iGetTgaHead(TARGAHEAD *Header); -ILboolean iCheckTarga(TARGAHEAD *Header); -ILboolean iLoadTargaInternal(void); -ILboolean iSaveTargaInternal(void); -//ILvoid iMakeString(char *Str); -ILboolean iReadBwTga(TARGAHEAD *Header); -ILboolean iReadColMapTga(TARGAHEAD *Header); -ILboolean iReadUnmapTga(TARGAHEAD *Header); -ILboolean iUncompressTgaData(ILimage *Image); -ILboolean i16BitTarga(ILimage *Image); -ILvoid iGetDateTime(ILuint *Month, ILuint *Day, ILuint *Yr, ILuint *Hr, ILuint *Min, ILuint *Sec); - - -#endif//TARGA_H diff --git a/win32/devil/lib/DevIL.lib b/win32/devil/lib/DevIL.lib index 0ba0a7526..0865b77be 100644 Binary files a/win32/devil/lib/DevIL.lib and b/win32/devil/lib/DevIL.lib differ diff --git a/win32/devil/src/altivec_common.c b/win32/devil/src/altivec_common.c deleted file mode 100644 index 467842d3d..000000000 --- a/win32/devil/src/altivec_common.c +++ /dev/null @@ -1,38 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Last modified: 17/04/2005 -// by Meloni Dario -// -// Description: Common altivec function. -// -//----------------------------------------------------------------------------- - -#include "config.h" - -#ifdef ALTIVEC_GCC -#include "altivec_common.h" - -// from http://developer.apple.com/hardware/ve/alignment.html -/*vector unsigned char load_unaligned( unsigned char *buffer ) { - vector unsigned char MSQ, LSQ; - vector unsigned char mask; - MSQ = vec_ld(0, buffer); // most significant quadword - LSQ = vec_ld(15, buffer); // least significant quadword - mask = vec_lvsl(0, buffer); // create the permute mask - return vec_perm(MSQ, LSQ, mask);// align the data -}*/ - -vector float fill_vector_f( float value ) { - vector_t vec; - vec.sf[0] = value; - vector float temp = vec_ld(0,vec.sf); - return vec_splat(temp,0); -} - -inline unsigned int round16( unsigned int v ) { - return ((int)((v/16)*10)%10) > 0 ? (v/16) : (v/16)+1; -} - - -#endif diff --git a/win32/devil/src/altivec_typeconversion.c b/win32/devil/src/altivec_typeconversion.c deleted file mode 100644 index e03c0ed92..000000000 --- a/win32/devil/src/altivec_typeconversion.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "config.h" - -#ifdef ALTIVEC_GCC -#include "altivec_typeconversion.h" - -static inline void abc2cba_internal( register const vector unsigned char p[4], unsigned char *data, register unsigned int length, unsigned char *newdata ) { - register vector unsigned char d0,d1,d2,t0,t1,t2; - - length = eround16(length); - - if( length >= 3 ) { - length -= 3; - - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - - while( length >= 3 ) { - t0 = vec_perm(d0,d1,p[0]); - t1 = vec_perm(d1,d0,p[1]); - t2 = vec_perm(d2,d1,p[2]); - t1 = vec_perm(t1,d2,p[3]); - - vec_st(t0,0,newdata); - vec_st(t1,16,newdata); - vec_st(t2,32,newdata); - - length -= 3; - data += 16*3; - newdata += 16*3; - - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - } - t0 = vec_perm(d0,d1,p[0]); - t1 = vec_perm(d1,d0,p[1]); - t2 = vec_perm(d2,d1,p[2]); - t1 = vec_perm(t1,d2,p[3]); - - vec_st(t0,0,newdata); - vec_st(t1,16,newdata); - vec_st(t2,32,newdata); - } - - if( length == 2 ) { - d0 = vec_ld(0,data); - d1 = vec_ld(16,data); - - t0 = vec_perm(d0,d1,p[0]); - t1 = vec_perm(d1,d0,p[1]); - - vec_st(t0,0,newdata); - vec_st(t1,16,newdata); - } else if( length == 1 ) { - d0 = vec_ld(0,data); - t0 = vec_perm(d0,d0,p[0]); - vec_st(t0,0,newdata); - } -} - -static inline void abcd2cbad_internal( register const vector unsigned char p, unsigned char *data, unsigned int length, unsigned char *newdata ) { - register vector unsigned char d0,d1,d2,z; - z = vec_splat_u8(0); - - length = eround16(length); - - if( length >= 3 ) { - length -= 3; - - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - - while( length >= 3 ) { - d0 = vec_perm(d0,z,p); - d1 = vec_perm(d1,z,p); - d2 = vec_perm(d2,z,p); - - vec_st(d0,0,newdata); - vec_st(d1,16,newdata); - vec_st(d2,32,newdata); - - length -= 3; - data += 16*3; - newdata += 16*3; - - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - } - d0 = vec_perm(d0,z,p); - d1 = vec_perm(d1,z,p); - d2 = vec_perm(d2,z,p); - - vec_st(d0,0,newdata); - vec_st(d1,16,newdata); - vec_st(d2,32,newdata); - } - - if( length == 2 ) { - d0 = vec_ld(0,data); - d1 = vec_ld(16,data); - - d0 = vec_perm(d0,z,p); - d1 = vec_perm(d1,z,p); - - vec_st(d0,0,newdata); - vec_st(d1,16,newdata); - } else if( length == 1 ) { - d0 = vec_ld(0,data); - d0 = vec_perm(d0,d0,z); - vec_st(d0,0,newdata); - } -} - -// Format conversion function -void abc2cba_byte( ILubyte *data, ILuint length, ILubyte *newdata ) { - const vector unsigned char p[4] = -{ (vector unsigned char)(0x02,0x01,0x00,0x05,0x04,0x03,0x08,0x07,0x06,0x0B,0x0A,0x09,0x0E,0x0D,0x0C,0x11), - (vector unsigned char)(0x00,0x10,0x04,0x03,0x02,0x07,0x06,0x05,0x0A,0x09,0x08,0x0D,0x0C,0x0B,0x0E,0x0F), - (vector unsigned char)(0x1E,0x03,0x02,0x01,0x06,0x05,0x04,0x09,0x08,0x07,0x0C,0x0B,0x0A,0x0F,0x0E,0x0D), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x10,0x0F)}; - abc2cba_internal(p,data,length,newdata); -} - -void abc2cba_short( ILushort *data, ILuint length, ILushort *newdata ) { - const vector unsigned char p[4] = -{ (vector unsigned char)(0x04,0x05,0x02,0x03,0x00,0x01,0x0A,0x0B,0x08,0x09,0x06,0x07,0x10,0x11,0x0E,0x0F), - (vector unsigned char)(0x1C,0x1D,0x06,0x07,0x04,0x05,0x02,0x03,0x0C,0x0D,0x0A,0x0B,0x08,0x09,0x0E,0x0F), - (vector unsigned char)(0x00,0x01,0x1E,0x1F,0x08,0x09,0x06,0x07,0x04,0x05,0x0E,0x0F,0x0C,0x0D,0x0A,0x0B), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x12,0x13)}; - abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata); -} - -void abc2cba_int( ILuint *data, ILuint length, ILuint *newdata ) { - const vector unsigned char p[4] = -{ (vector unsigned char)(0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x14,0x15,0x16,0x17), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x1C,0x1D,0x1E,0x1F,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F), - (vector unsigned char)(0x18,0x19,0x1A,0x1B,0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x0C,0x0D,0x0E,0x0F)}; - abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata); -} - -void abc2cba_double( ILdouble *data, ILuint length, ILdouble *newdata ) { - const vector unsigned char p[4] = -{ (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F), - (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F), - (vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F)}; - abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata); -} - -void abcd2cbad_byte( ILubyte *data, ILuint length, ILubyte *newdata ) { - const vector unsigned char p = (vector unsigned char)(0x02,0x01,0x00,0x03,0x06,0x05,0x04,0x07,0x0A,0x09,0x08,0x0B, 0x0E,0x0D,0x0C,0x0F); - abcd2cbad_internal(p,data,length,newdata); -} - -void abcd2cbad_short( ILushort *data, ILuint length, ILushort *newdata ) { - const vector unsigned char p = (vector unsigned char)(0x04,0x05,0x02,0x03,0x00,0x01,0x06,0x07,0x0C,0x0D,0x0A,0x0B,0x08,0x09,0x0E,0x0F); - abcd2cbad_internal(p,(ILubyte*)data,length,(ILubyte*)newdata); -} - -void abcd2cbad_int( ILuint *data, ILuint length, ILuint *newdata ) { - const vector unsigned char p = (vector unsigned char)(0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0C,0x0D,0x0E,0x0F); - abcd2cbad_internal(p,(ILubyte*)data,length,(ILubyte*)newdata); -} - -void abcd2cbad_double( ILdouble *tdata, ILuint length, ILdouble *tnewdata ) { - register ILubyte *data = (ILubyte*)tdata; - register ILubyte *newdata = (ILubyte*)tnewdata; - const vector unsigned char p = (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F); - register vector unsigned char d0,d1,d2,d3,t0,t1,t2,t3; - - length = eround16(length); - - if( length >= 4 ) { - length -= 4; - - d3 = vec_ld(48,data); - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - - while( length >= 4 ) { - t0 = vec_perm(d0,d1,p); - t1 = vec_perm(d1,d0,p); - t2 = vec_perm(d2,d3,p); - t3 = vec_perm(d3,d2,p); - - vec_st(t0,0,newdata); - vec_st(t1,16,newdata); - vec_st(t2,32,newdata); - vec_st(t3,48,newdata); - - length -= 4; - data += 16*4; - newdata += 16*4; - - d3 = vec_ld(48,data); - d2 = vec_ld(32,data); - d1 = vec_ld(16,data); - d0 = vec_ld(0,data); - } - t0 = vec_perm(d0,d1,p); - t1 = vec_perm(d1,d0,p); - t2 = vec_perm(d2,d3,p); - t3 = vec_perm(d3,d2,p); - - vec_st(d0,0,newdata); - vec_st(d1,16,newdata); - vec_st(d2,32,newdata); - vec_st(d3,48,newdata); - } - - if( length == 2 ) { - d0 = vec_ld(0,data); - d1 = vec_ld(16,data); - - t0 = vec_perm(d0,d1,p); - t1 = vec_perm(d1,d0,p); - - vec_st(t0,0,newdata); - vec_st(t1,16,newdata); - } -} - -#endif diff --git a/win32/devil/src/il_alloc.c b/win32/devil/src/il_alloc.c deleted file mode 100644 index 2604153c8..000000000 --- a/win32/devil/src/il_alloc.c +++ /dev/null @@ -1,271 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Last modified: 08/17/2008 -// -// Filename: src-IL/src/il_alloc.c -// -// Description: Memory allocation functions -// -//----------------------------------------------------------------------------- - - -#define __ALLOC_C -#include "il_internal.h" -#include -#include - -#ifdef MM_MALLOC -#include -#endif - -static ILvoid ILAPIENTRY DefaultFreeFunc(const ILvoid * CONST_RESTRICT Ptr); -static ILvoid* ILAPIENTRY DefaultAllocFunc(const ILuint Size); - -static mAlloc ialloc_ptr = DefaultAllocFunc; -static mFree ifree_ptr = DefaultFreeFunc; - -/*** Vector Allocation/Deallocation Function ***/ -#ifdef VECTORMEM -ILvoid *vec_malloc(const ILuint size) -{ - const ILuint _size = size % 16 > 0 ? size + 16 - (size % 16) : size; // align size value - -#ifdef MM_MALLOC - return _mm_malloc(_size,16); -#else -#ifdef VALLOC - return valloc( _size ); -#else -#ifdef POSIX_MEMALIGN - char *buffer; - return posix_memalign(&buffer, 16, _size) == 0 ? buffer : NULL; -#else -#ifdef MEMALIGN - return memalign( 16, _size ); -#else - // Memalign hack from ffmpeg for MinGW - void *ptr; - int diff; - ptr = malloc(_size+16+1); - diff= ((-(int)ptr - 1)&15) + 1; - ptr += diff; - ((char*)ptr)[-1]= diff; - return ptr; -#endif //MEMALIGN -#endif //POSIX_MEMALIGN -#endif //VALLOC -#endif //MM_MALLOC -} - -ILvoid *ivec_align_buffer(ILvoid *buffer, const ILuint size) -{ - if( (size_t)buffer % 16 != 0 ) { - void *aligned_buffer = vec_malloc( size ); - memcpy( aligned_buffer, buffer, size ); - ifree( buffer ); - return aligned_buffer; - } - return buffer; -} -#endif - - -/*** Allocation/Deallocation Function ***/ -ILvoid* ILAPIENTRY ialloc(const ILuint Size) { - ILvoid *Ptr = ialloc_ptr(Size); - if (Ptr == NULL) - ilSetError(IL_OUT_OF_MEMORY); - return Ptr; -} - -ILvoid ILAPIENTRY ifree(const ILvoid * CONST_RESTRICT Ptr) { - ifree_ptr(Ptr); - return; -} - -ILvoid* ILAPIENTRY icalloc(const ILuint Size, const ILuint Num) -{ - ILvoid *Ptr = ialloc(Size * Num); - if (Ptr == NULL) - return Ptr; - imemclear(Ptr, Size * Num); - return Ptr; -} - -/*** Default Allocation/Deallocation Function ***/ -static ILvoid* ILAPIENTRY DefaultAllocFunc(const ILuint Size) -{ -#ifdef VECTORMEM - return (ILvoid*)vec_malloc(Size); -#else - return malloc(Size); -#endif //VECTORMEM -} - -static ILvoid ILAPIENTRY DefaultFreeFunc(const ILvoid * CONST_RESTRICT ptr) -{ - if (ptr) - { -#ifdef MM_MALLOC - _mm_free((ILvoid*)ptr); -#else -#if defined(VECTORMEM) & !defined(POSIX_MEMALIGN) & !defined(VALLOC) & !defined(MEMALIGN) & !defined(MM_MALLOC) - free(ptr - ((char*)ptr)[-1]); -#else - free((void*)ptr); -#endif //OTHERS... -#endif //MM_MALLOC - } -} - -/*** Manipulate Allocation/Deallocation Function ***/ -ILvoid ILAPIENTRY ilResetMemory() // Deprecated -{ - ialloc_ptr = DefaultAllocFunc; - ifree_ptr = DefaultFreeFunc; -} - -ILvoid ILAPIENTRY ilSetMemory(mAlloc AllocFunc, mFree FreeFunc) -{ - ialloc_ptr = AllocFunc == NULL ? DefaultAllocFunc : AllocFunc; - ifree_ptr = FreeFunc == NULL ? DefaultFreeFunc : FreeFunc; -} - - -/*#if defined(_WIN32) && defined(_MEM_DEBUG) -#include - -int bAtexit = 0; - - -typedef struct ALLOC_INFO -{ - unsigned long address; - unsigned long size; - char file[64]; - unsigned long line; - struct ALLOC_INFO *Next; -} ALLOC_INFO; -ALLOC_INFO *AllocList; - - -void AddTrack(unsigned long addr, unsigned long size, const char *file, unsigned long line) -{ - ALLOC_INFO *Temp; - - if (AllocList == NULL) { - AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds. - AllocList->address = addr; - AllocList->size = size; - AllocList->line = line; - strncpy(AllocList->file, file, 63); - AllocList->Next = NULL; - } - else { - Temp = AllocList; - AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds. - AllocList->address = addr; - AllocList->size = size; - AllocList->line = line; - strncpy(AllocList->file, file, 63); - AllocList->Next = Temp; - } - - return; -} - - -void RemoveTrack(unsigned long addr) -{ - ALLOC_INFO *Temp, *Prev; - - Temp = AllocList; - Prev = NULL; - - if (Temp == NULL) - return; - - while (Temp != NULL) { - if (Temp->address == addr) { - if (Prev == NULL) { - AllocList = Temp->Next; - free(Temp); - } - else { - Prev->Next = Temp->Next; - free(Temp); - } - break; - } - Prev = Temp; - Temp = Temp->Next; - } - - return; -} - - -void DumpUnfreed(void) -{ - unsigned long TotalSize = 0; - char buf[1024]; - ALLOC_INFO *i = AllocList; - - OutputDebugString("DevIL Unfreed Information:\n"); - while (i != NULL) { - sprintf(buf, "%s(%d) : %d bytes unfreed at %d\n", i->file, i->line, i->size, i->address); - OutputDebugString(buf); - TotalSize += i->size; - - AllocList = i->Next; - free(i); - i = AllocList; - } - - sprintf(buf, "-----------------------------------------------------------\n"); - OutputDebugString(buf); - sprintf(buf, "Total Unfreed: %d bytes\n\n\n", TotalSize); - OutputDebugString(buf); -} - -void AddToAtexit() -{ - if (bAtexit) - return; - atexit(DumpUnfreed); - bAtexit = 1; -} - -void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line) -{ - void *ptr; - ptr = calloc(size, num); - if (!ptr) - return NULL; - AddToAtexit(); - AddTrack((unsigned long)ptr, size * num, file, line); - return ptr; -} - - -void *m_alloc(unsigned long size, const char *file, unsigned long line) -{ - void *ptr; - ptr = malloc(size); - if (!ptr) - return NULL; - AddToAtexit(); - AddTrack((unsigned long)ptr, size, file, line); - return ptr; -} - - -void f_ree(void *ptr) -{ - RemoveTrack((unsigned long)ptr); - free(ptr); - return; -} - -#endif//defined(_WIN32) && defined(_MEM_DEBUG)*/ diff --git a/win32/devil/src/il_bits.c b/win32/devil/src/il_bits.c deleted file mode 100644 index 02f02321a..000000000 --- a/win32/devil/src/il_bits.c +++ /dev/null @@ -1,156 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/14/2004 -// -// Filename: src-IL/src/il_bits.c -// -// Description: Implements a file class that reads/writes bits directly. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_bits.h" - - -// Opens a BITFILE just like fopen opens a FILE. -/*BITFILE *bopen(const char *FileName, const char *Mode) -{ - BITFILE *ToReturn = NULL; - - if (FileName != NULL) { - ToReturn = (BITFILE*)ialloc(sizeof(BITFILE)); - if (ToReturn != NULL) { - iopenr((char*)FileName); - ToReturn->File = iGetFile(); - ToReturn->BitPos = 0; - ToReturn->ByteBitOff = 8; - ToReturn->Buff = 0; - } - } - - return ToReturn; -}*/ - - -// Converts a FILE to a BITFILE. -BITFILE *bfile(ILHANDLE File) -{ - BITFILE *ToReturn = NULL; - - if (File != NULL) { - ToReturn = (BITFILE*)ialloc(sizeof(BITFILE)); - if (ToReturn != NULL) { - ToReturn->File = File; - ToReturn->BitPos = itell() << 3; - ToReturn->ByteBitOff = 8; - ToReturn->Buff = 0; - } - } - - return ToReturn; -} - - -// Closes an open BITFILE and frees memory for it. -ILint bclose(BITFILE *BitFile) -{ - if (BitFile == NULL || BitFile->File == NULL) - return IL_EOF; - - icloser(BitFile->File); - ifree(BitFile); - - return 0; -} - - -// Returns the current bit position of a BITFILE. -ILint btell(BITFILE *BitFile) -{ - return BitFile->BitPos; -} - - -// Seeks in a BITFILE just like fseek for FILE. -ILint bseek(BITFILE *BitFile, ILuint Offset, ILuint Mode) -{ - ILint KeepPos, Len; - - if (BitFile == NULL || BitFile->File == NULL) - return 1; - - switch (Mode) - { - case IL_SEEK_SET: - if (iseek(Offset >> 3, Mode)) { - BitFile->BitPos = Offset; - BitFile->ByteBitOff = BitFile->BitPos % 8; - } - break; - case IL_SEEK_CUR: - if (iseek(Offset >> 3, Mode)) { - BitFile->BitPos += Offset; - BitFile->ByteBitOff = BitFile->BitPos % 8; - } - break; - case IL_SEEK_END: - KeepPos = itell(); - iseek(0, IL_SEEK_END); - Len = itell(); - iseek(0, IL_SEEK_SET); - - if (iseek(Offset >> 3, Mode)) { - BitFile->BitPos = (Len << 3) + Offset; - BitFile->ByteBitOff = BitFile->BitPos % 8; - } - - break; - - default: - return 1; - } - - return 0; -} - - -// hehe, "bread". It reads data into Buffer from the BITFILE, just like fread for FILE. -ILint bread(ILvoid *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile) -{ - - //Note that this function is somewhat useless: In binary image - - //formats, there are some pad bits after each scanline. This - - //function does not take that into account, so... - - - ILuint BuffPos = 0, Count = Size * Number; - - while (BuffPos < Count) { - if (BitFile->ByteBitOff < 0 || BitFile->ByteBitOff > 7) { - BitFile->ByteBitOff = 7; - if (iread(&BitFile->Buff, 1, 1) != 1) // Reached eof or error... - return BuffPos; - } - - *((ILubyte*)(Buffer) + BuffPos) = (ILubyte)!!(BitFile->Buff & (1 << BitFile->ByteBitOff)); - - BuffPos++; - BitFile->ByteBitOff--; - } - - return BuffPos; -} - - -// Not implemented yet. -/*ILint bwrite(ILvoid *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile) -{ - - - return 0; -}*/ diff --git a/win32/devil/src/il_bmp.c b/win32/devil/src/il_bmp.c deleted file mode 100644 index 86b620d7d..000000000 --- a/win32/devil/src/il_bmp.c +++ /dev/null @@ -1,1020 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/19/2008 -// -// Filename: src-IL/src/il_bmp.c -// -// Description: Reads from and writes to a bitmap (.bmp) file. -// -//----------------------------------------------------------------------------- - -#define IL_BMP_C - -#include "il_internal.h" -#ifndef IL_NO_BMP -#include "il_bmp.h" -#include "il_manip.h" -#include "il_endian.h" -#include -ILvoid GetShiftFromMask(const ILuint Mask, ILuint * CONST_RESTRICT ShiftLeft, ILuint * CONST_RESTRICT ShiftRight); - -//! Checks if the file specified in FileName is a valid .bmp file. -ILboolean ilIsValidBmp(ILconst_string CONST_RESTRICT FileName) -{ - ILHANDLE BitmapFile; - ILboolean bBitmap = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("bmp"))) { - ilSetError(IL_INVALID_EXTENSION); - return bBitmap; - } - - BitmapFile = iopenr(FileName); - if (BitmapFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bBitmap; - } - - bBitmap = ilIsValidBmpF(BitmapFile); - icloser(BitmapFile); - - return bBitmap; -} - - -//! Checks if the ILHANDLE contains a valid .bmp file at the current position. -ILboolean ilIsValidBmpF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidBmp(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .bmp lump. -ILboolean ilIsValidBmpL(const ILvoid * Lump, const ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidBmp(); -} - -// Internal function used to get the .bmp header from the current file. -ILboolean iGetBmpHead(BMPHEAD * const Header) -{ - Header->bfType = GetLittleUShort(); - Header->bfSize = GetLittleInt(); - Header->bfReserved = GetLittleUInt(); - Header->bfDataOff = GetLittleInt(); - Header->biSize = GetLittleInt(); - Header->biWidth = GetLittleInt(); - Header->biHeight = GetLittleInt(); - Header->biPlanes = GetLittleShort(); - Header->biBitCount = GetLittleShort(); - Header->biCompression = GetLittleInt(); - Header->biSizeImage = GetLittleInt(); - Header->biXPelsPerMeter = GetLittleInt(); - Header->biYPelsPerMeter = GetLittleInt(); - Header->biClrUsed = GetLittleInt(); - Header->biClrImportant = GetLittleInt(); - return IL_TRUE; -} - - -ILboolean iGetOS2Head(OS2_HEAD * const Header) -{ - if (iread(Header, sizeof(OS2_HEAD), 1) != 1) - return IL_FALSE; - - UShort(&Header->bfType); - UInt(&Header->biSize); - Short(&Header->xHotspot); - Short(&Header->yHotspot); - UInt(&Header->DataOff); - UInt(&Header->cbFix); - - //2003-09-01 changed to UShort according to MSDN - UShort(&Header->cx); - UShort(&Header->cy); - UShort(&Header->cPlanes); - UShort(&Header->cBitCount); - - iseek((ILint)Header->cbFix - 12, IL_SEEK_CUR); // Skip rest of header, if any. - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidBmp() { - BMPHEAD Head; - OS2_HEAD Os2Head; - ILboolean IsValid; - - iGetBmpHead(&Head); - iseek(-(ILint)sizeof(BMPHEAD), IL_SEEK_CUR); // Go ahead and restore to previous state - - IsValid = iCheckBmp(&Head); - if (!IsValid) { - iGetOS2Head(&Os2Head); - iseek(-(ILint)sizeof(BMPHEAD), IL_SEEK_CUR); - IsValid = iCheckOS2(&Os2Head); - } - return IsValid; -} - - -// Internal function used to check if the HEADER is a valid .bmp header. -ILboolean iCheckBmp(const BMPHEAD * CONST_RESTRICT Header) { - //if ((Header->bfType != ('B'|('M'<<8))) || ((Header->biSize != 0x28) && (Header->biSize != 0x0C))) - if ((Header->bfType != ('B'|('M'<<8))) || (Header->biSize != 0x28)) - return IL_FALSE; - if (Header->biHeight == 0 || Header->biWidth < 1) - return IL_FALSE; - if (Header->biPlanes > 1) // Not sure... - return IL_FALSE; - if(Header->biCompression != 0 && Header->biCompression != 1 && - Header->biCompression != 2 && Header->biCompression != 3) - return IL_FALSE; - if(Header->biCompression == 3 && Header->biBitCount != 16 && Header->biBitCount != 32) - return IL_FALSE; - if (Header->biBitCount != 1 && Header->biBitCount != 4 && Header->biBitCount != 8 && - Header->biBitCount != 16 && Header->biBitCount != 24 && Header->biBitCount != 32) - return IL_FALSE; - return IL_TRUE; -} - - -ILboolean iCheckOS2( const OS2_HEAD * CONST_RESTRICT Header) { - if ((Header->bfType != ('B'|('M'<<8))) || (Header->DataOff < 26) || (Header->cbFix < 12)) - return IL_FALSE; - if (Header->cPlanes != 1) - return IL_FALSE; - if (Header->cx == 0 || Header->cy == 0) - return IL_FALSE; - if (Header->cBitCount != 1 && Header->cBitCount != 4 && Header->cBitCount != 8 && - Header->cBitCount != 24) - return IL_FALSE; - - return IL_TRUE; -} - - -//! Reads a .bmp file -ILboolean ilLoadBmp(ILconst_string FileName) { - ILHANDLE BitmapFile; - ILboolean bBitmap = IL_FALSE; - - BitmapFile = iopenr(FileName); - if (BitmapFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bBitmap; - } - - bBitmap = ilLoadBmpF(BitmapFile); - icloser(BitmapFile); - - return bBitmap; -} - - -//! Reads an already-opened .bmp file -ILboolean ilLoadBmpF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadBitmapInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .bmp -ILboolean ilLoadBmpL(const ILvoid *Lump, const ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadBitmapInternal(); -} - - -// Internal function used to load the .bmp. -ILboolean iLoadBitmapInternal() { - BMPHEAD Header; - OS2_HEAD Os2Head; - ILboolean bBitmap; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iGetBmpHead(&Header); - if (!iCheckBmp(&Header)) { - iseek(-(ILint)sizeof(BMPHEAD), IL_SEEK_CUR); - iGetOS2Head(&Os2Head); - if (!iCheckOS2(&Os2Head)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - else { - return iGetOS2Bmp(&Os2Head); - } - } - - // Don't know what to do if it has more than one plane... - if (Header.biPlanes != 1) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - switch (Header.biCompression) - { - case 0: // No compression - case 3: // BITFIELDS compression is handled in 16 bit - // and 32 bit code in ilReadUncompBmp() - bBitmap = ilReadUncompBmp(&Header); - break; - case 1: // RLE 8-bit / pixel (BI_RLE4) - bBitmap = ilReadRLE8Bmp(&Header); - break; - case 2: // RLE 4-bit / pixel (BI_RLE8) - bBitmap = ilReadRLE4Bmp(&Header); - break; - - default: - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - ilFixImage(); - - return bBitmap; -} - - -// Reads an uncompressed .bmp -// One of the absolute ugliest functions I've ever written! -ILboolean ilReadUncompBmp(BMPHEAD * Header) { - ILuint i, j, k, c, Read; - ILubyte Bpp, ByteData, PadSize, Padding[4]; - ILuint rMask, gMask, bMask; //required for bitfields packing - ILuint rShiftR, gShiftR, bShiftR; //required for bitfields packing - ILuint rShiftL, gShiftL, bShiftL; //required for bitfields packing - ILushort Read16; //used for 16bit bmp loading - - if (Header->biBitCount < 8) - Bpp = 1; // We can't have an integral number less than one and greater than 0 - else - Bpp = (ILubyte)(Header->biBitCount >> 3); // Convert to bytes per pixel - - if(Bpp == 2 || Bpp == 4) - Bpp = 3; - - // Update the current image with the new dimensions - if (!ilTexImage(Header->biWidth, abs(Header->biHeight), 1, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - switch (Header->biBitCount) - { - case 1: - //iCurImage->Format = IL_LUMINANCE; - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalType = IL_PAL_BGR32; - iCurImage->Pal.PalSize = 2 * 4; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - break; - - case 4: - case 8: - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalType = IL_PAL_BGR32; - - // if there are 256 colors biClrUsed is 0 - iCurImage->Pal.PalSize = Header->biClrUsed ? - Header->biClrUsed * 4 : 256 * 4; - - if (Header->biBitCount == 4) // biClrUsed is 0 for 4-bit bitmaps - iCurImage->Pal.PalSize = 16 * 4; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - break; - - case 16: - case 24: - case 32: - iCurImage->Format = IL_BGR; - break; - - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - // A height of 0 is illegal - if (Header->biHeight == 0) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - if (iCurImage->Pal.Palette) - ifree(iCurImage->Pal.Palette); - return IL_FALSE; - } - - // If the image height is negative, then the image is flipped - // (Normal is IL_ORIGIN_LOWER_LEFT) - if (Header->biHeight < 0) { - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - } - else { - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - } - - // Read the palette - iseek(sizeof(BMPHEAD), IL_SEEK_SET); - if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize) - return IL_FALSE; - - // Seek to the data from the "beginning" of the file - iseek(Header->bfDataOff, IL_SEEK_SET); - - // We have to handle 1 and 4-bit images separately, because we have to expand them. - switch (Header->biBitCount) - { - case 1: - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width / 8 * iCurImage->Height); - - PadSize = ((32 - (iCurImage->Width % 32)) / 8) % 4; // Has to truncate - for (j = 0; j < iCurImage->Height; j++) { - Read = 0; - for (i = 0; i < iCurImage->Width; ) { - if (iread(&ByteData, 1, 1) != 1) { - iUnCache(); - return IL_FALSE; - } - Read++; - k = 128; - for (c = 0; c < 8; c++) { - iCurImage->Data[j * iCurImage->Width + i] = - (!!(ByteData & k) == 1 ? 1 : 0); - k >>= 1; - if (++i >= iCurImage->Width) - break; - } - } - //iseek(PadSize, IL_SEEK_CUR); - iread(Padding, 1, PadSize); - } - - iUnCache(); - break; - - case 4: - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width / 2 * iCurImage->Height); - - PadSize = ((8 - (iCurImage->Width % 8)) / 2) % 4; // Has to truncate - for (j = 0; j < iCurImage->Height; j++) { - for (i = 0; i < iCurImage->Width; i++) { - if (iread(&ByteData, 1, 1) != 1) { - iUnCache(); - return IL_FALSE; - } - iCurImage->Data[j * iCurImage->Width + i] = ByteData >> 4; - if (++i == iCurImage->Width) - break; - iCurImage->Data[j * iCurImage->Width + i] = ByteData & 0x0F; - } - iread(Padding, 1, PadSize);//iseek(PadSize, IL_SEEK_CUR); - } - - iUnCache(); - break; - - case 16: - //padding - //2003-09-09: changed iCurImage->Bps to iCurImage->Width*2, - //because iCurImage->Bps refers to the 24 bit devil image - PadSize = (4 - (iCurImage->Width*2 % 4)) % 4; - - //check if bitfield compression is used - rMask = 0x7C00; - gMask = 0x03E0; - bMask = 0x001F; - rShiftR = 10; - gShiftR = 5; - bShiftR = 0; - rShiftL = 3; - gShiftL = 3; - bShiftL = 3; - if(Header->biCompression == 3) //bitfields - { - iseek(Header->bfDataOff - 12, IL_SEEK_SET); //seek to bitfield data - iread(&rMask, 4, 1); - iread(&gMask, 4, 1); - iread(&bMask, 4, 1); - UInt(&rMask); - UInt(&gMask); - UInt(&bMask); - GetShiftFromMask(rMask, &rShiftL, &rShiftR); - GetShiftFromMask(gMask, &gShiftL, &gShiftR); - GetShiftFromMask(bMask, &bShiftL, &bShiftR); - } - - k = 0; - - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width * iCurImage->Height); - - for (j = 0; j < iCurImage->Height; j++) { - for(i = 0; i < iCurImage->Width; i++, k += 3) { - if (iread(&Read16, 2, 1) != 1) { - iUnCache(); - return IL_FALSE; - } - iCurImage->Data[k] = ((Read16 & bMask) >> bShiftR) << bShiftL; - iCurImage->Data[k + 1] = ((Read16 & gMask) >> gShiftR) << gShiftL; - iCurImage->Data[k + 2] = ((Read16 & rMask) >> rShiftR) << rShiftL; - } - iread(Padding, 1, PadSize); - } - - iUnCache(); - break; - - case 8: - case 24: - //for 8 and 24 bit, Bps is equal to the bmps bps - PadSize = (4 - (iCurImage->Bps % 4)) % 4; - if (PadSize == 0) { - if (iread(iCurImage->Data, 1, iCurImage->SizeOfPlane) != iCurImage->SizeOfPlane) - return IL_FALSE; - } - else { // M$ requires lines to be padded if the widths aren't multiples of 4. - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width * iCurImage->Height); - - PadSize = (4 - (iCurImage->Bps % 4)); - for (i = 0; i < iCurImage->SizeOfPlane; i += iCurImage->Bps) { - if (iread(iCurImage->Data + i, 1, iCurImage->Bps) != iCurImage->Bps) { - iUnCache(); - return IL_FALSE; - } - //iseek(PadSize, IL_SEEK_CUR); - iread(Padding, 1, PadSize); - } - - iUnCache(); - } - break; - - case 32: - //32bit files are always padded to 4 byte... - //check if bitfield compression is used - rMask = 0xFF0000; - gMask = 0x00FF00; - bMask = 0x0000FF; - rShiftR = 16; - gShiftR = 8; - bShiftR = 0; - rShiftL = 0; - gShiftL = 0; - bShiftL = 0; - if(Header->biCompression == 3) //bitfields - { - iseek(Header->bfDataOff - 12, IL_SEEK_SET); //seek to bitfield data - iread(&rMask, 4, 1); - iread(&gMask, 4, 1); - iread(&bMask, 4, 1); - UInt(&rMask); - UInt(&gMask); - UInt(&bMask); - GetShiftFromMask(rMask, &rShiftL, &rShiftR); - GetShiftFromMask(gMask, &gShiftL, &gShiftR); - GetShiftFromMask(bMask, &bShiftL, &bShiftR); - } - - //TODO: win98 supports per-pixel alpha, so - //load to rgba???? - - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width * iCurImage->Height); - - for(i = 0; i < iCurImage->SizeOfData; i += 3) { - if (iread(&Read, 4, 1) != 1) { - iUnCache(); - return IL_FALSE; - } - - iCurImage->Data[i] = ((Read & bMask) >> bShiftR) << bShiftL; - iCurImage->Data[i + 1] = ((Read & gMask) >> gShiftR) << gShiftL; - iCurImage->Data[i + 2] = ((Read & rMask) >> rShiftR) << rShiftL; - } - - iUnCache(); - break; - - default: - return IL_FALSE; //shouldn't happen, we checked that before - } - - return IL_TRUE; -} - - -ILboolean ilReadRLE8Bmp(BMPHEAD *Header) { - ILubyte Bytes[2]; - size_t offset = 0, count, endOfLine = iCurImage->Width; - - // Update the current image with the new dimensions - if (!ilTexImage(Header->biWidth, abs(Header->biHeight), 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - // A height of 0 is illegal - if (Header->biHeight == 0) - return IL_FALSE; - - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalType = IL_PAL_BGR32; - iCurImage->Pal.PalSize = Header->biClrUsed * 4; // 256 * 4 for most images - if (iCurImage->Pal.PalSize == 0) - iCurImage->Pal.PalSize = 256 * 4; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) - return IL_FALSE; - - // If the image height is negative, then the image is flipped - // (Normal is IL_ORIGIN_LOWER_LEFT) - iCurImage->Origin = Header->biHeight < 0 ? - IL_ORIGIN_UPPER_LEFT : IL_ORIGIN_LOWER_LEFT; - - // Read the palette - iseek(sizeof(BMPHEAD), IL_SEEK_SET); - if (iread(iCurImage->Pal.Palette, iCurImage->Pal.PalSize, 1) != 1) - return IL_FALSE; - - // Seek to the data from the "beginning" of the file - iseek(Header->bfDataOff, IL_SEEK_SET); - - while (offset < iCurImage->SizeOfData) { - if (iread(Bytes, sizeof(Bytes), 1) != 1) - return IL_FALSE; - if (Bytes[0] == 0x00) { // Escape sequence - switch (Bytes[1]) { - case 0x00: // End of line - offset = endOfLine; - endOfLine += iCurImage->Width; - break; - case 0x01: // End of bitmap - offset = iCurImage->SizeOfData; - break; - case 0x2: - if (iread(Bytes, sizeof(Bytes), 1) != 1) - return IL_FALSE; - offset += Bytes[0] + Bytes[1] * iCurImage->Width; - endOfLine += Bytes[1] * iCurImage->Width; - break; - default: - count = IL_MIN(Bytes[1], iCurImage->SizeOfData-offset); - if (iread(iCurImage->Data + offset, count, 1) != 1) - return IL_FALSE; - offset += count; - if ((count & 1) == 1) // Must be on a word boundary - if (iread(Bytes, 1, 1) != 1) - return IL_FALSE; - } - } else { - count = IL_MIN (Bytes[0], iCurImage->SizeOfData-offset); - memset( iCurImage->Data + offset, Bytes[1], count); - offset += count; - } - } - return IL_TRUE; -} - -//changed 2003-09-01 -//deleted ilReadRLE8Bmp() USE_POINTER version - -ILboolean ilReadRLE4Bmp(BMPHEAD *Header) { - ILubyte Bytes[2]; - ILuint i; - size_t offset, count, endOfLine; - - // Update the current image with the new dimensions - if (!ilTexImage( Header->biWidth, abs(Header->biHeight), 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - // A height of 0 is illegal - if (Header->biHeight == 0) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalType = IL_PAL_BGR32; - iCurImage->Pal.PalSize = 16 * 4; //Header->biClrUsed * 4; // 16 * 4 for most images - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) - return IL_FALSE; - - // If the image height is negative, then the image is flipped - // (Normal is IL_ORIGIN_LOWER_LEFT) - iCurImage->Origin = Header->biHeight < 0 ? - IL_ORIGIN_UPPER_LEFT : IL_ORIGIN_LOWER_LEFT; - - // Read the palette - iseek(sizeof(BMPHEAD), IL_SEEK_SET); - - if (iread(iCurImage->Pal.Palette, iCurImage->Pal.PalSize, 1) != 1) - return IL_FALSE; - - // Seek to the data from the "beginning" of the file - iseek(Header->bfDataOff, IL_SEEK_SET); - offset = 0; - endOfLine = iCurImage->Width; - - while (offset < iCurImage->SizeOfData) { - int align; - if (iread(&Bytes[0], sizeof(Bytes), 1) != 1) - return IL_FALSE; - if (Bytes[0] == 0x0) { // Escape sequence - switch (Bytes[1]) { - case 0x0: // End of line - offset = endOfLine; - endOfLine += iCurImage->Width; - break; - case 0x1: // End of bitmap - offset = iCurImage->SizeOfData; - break; - case 0x2: - if (iread(&Bytes[0], sizeof(Bytes), 1) != 1) - return IL_FALSE; - offset += Bytes[0] + Bytes[1] * iCurImage->Width; - endOfLine += Bytes[1] * iCurImage->Width; - break; - default: // Run of pixels - count = IL_MIN (Bytes[1], iCurImage->SizeOfData-offset); - - for (i = 0; i < count; i++) { - int byte; - - if ((i & 0x01) == 0) { - if (iread(&Bytes[0], sizeof(Bytes[0]), 1) != 1) - return IL_FALSE; - byte = (Bytes[0] >> 4); - } - else - byte = (Bytes[0] & 0x0F); - iCurImage->Data[offset++] = byte; - } - - align = Bytes[1] % 4; - - if (align == 1 || align == 2) // Must be on a word boundary - if (iread(&Bytes[0], sizeof(Bytes[0]), 1) != 1) - return IL_FALSE; - } - } else { - count = IL_MIN (Bytes[0], iCurImage->SizeOfData-offset); - Bytes[0] = (Bytes[1] >> 4); - Bytes[1] &= 0x0F; - for (i = 0; i < count; i++) - iCurImage->Data[offset++] = Bytes [i & 1]; - } - } - - return IL_TRUE; -} - -//changed 2003-09-01 -//deleted ilReadRLE4Bmp() USE_POINTER version - -ILboolean iGetOS2Bmp(OS2_HEAD *Header) -{ - ILuint PadSize, Read, i, j, k, c; - ILubyte ByteData; - - if (Header->cBitCount == 1) { - if (!ilTexImage(Header->cx, Header->cy, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(2 * 3); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - iCurImage->Pal.PalSize = 2 * 3; - iCurImage->Pal.PalType = IL_PAL_BGR24; - - if (iread(iCurImage->Pal.Palette, 1, 2 * 3) != 6) - return IL_FALSE; - - PadSize = ((32 - (iCurImage->Width % 32)) / 8) % 4; // Has to truncate. - iseek(Header->DataOff, IL_SEEK_SET); - - for (j = 0; j < iCurImage->Height; j++) { - Read = 0; - for (i = 0; i < iCurImage->Width; ) { - if (iread(&ByteData, 1, 1) != 1) - return IL_FALSE; - Read++; - k = 128; - for (c = 0; c < 8; c++) { - iCurImage->Data[j * iCurImage->Width + i] = - (!!(ByteData & k) == 1 ? 1 : 0); - k >>= 1; - if (++i >= iCurImage->Width) - break; - } - } - iseek(PadSize, IL_SEEK_CUR); - } - return IL_TRUE; - } - - if (Header->cBitCount == 4) { - if (!ilTexImage(Header->cx, Header->cy, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(16 * 3); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - iCurImage->Pal.PalSize = 16 * 3; - iCurImage->Pal.PalType = IL_PAL_BGR24; - - if (iread(iCurImage->Pal.Palette, 1, 16 * 3) != 16*3) - return IL_FALSE; - - PadSize = ((8 - (iCurImage->Width % 8)) / 2) % 4; // Has to truncate - iseek(Header->DataOff, IL_SEEK_SET); - - for (j = 0; j < iCurImage->Height; j++) { - for (i = 0; i < iCurImage->Width; i++) { - if (iread(&ByteData, 1, 1) != 1) - return IL_FALSE; - iCurImage->Data[j * iCurImage->Width + i] = ByteData >> 4; - if (++i == iCurImage->Width) - break; - iCurImage->Data[j * iCurImage->Width + i] = ByteData & 0x0F; - } - iseek(PadSize, IL_SEEK_CUR); - } - - return IL_TRUE; - } - - if (Header->cBitCount == 8) { - //added this line 2003-09-01...strange no-one noticed before... - if (!ilTexImage(Header->cx, Header->cy, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(256 * 3); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - iCurImage->Pal.PalSize = 256 * 3; - iCurImage->Pal.PalType = IL_PAL_BGR24; - - if (iread(iCurImage->Pal.Palette, 1, 256 * 3) != 256*3) - return IL_FALSE; - } - else { //has to be 24 bpp - if (!ilTexImage(Header->cx, Header->cy, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - iseek(Header->DataOff, IL_SEEK_SET); - - PadSize = (4 - (iCurImage->Bps % 4)) % 4; - if (PadSize == 0) { - if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) - return IL_FALSE; - } - else { - for (i = 0; i < iCurImage->Height; i++) { - if (iread(iCurImage->Data + i * iCurImage->Bps, 1, iCurImage->Bps) != iCurImage->Bps) - return IL_FALSE; - iseek(PadSize, IL_SEEK_CUR); - } - } - - return IL_TRUE; -} - - -//! Writes a .bmp file -ILboolean ilSaveBmp(const ILstring FileName) -{ - ILHANDLE BitmapFile; - ILboolean bBitmap = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - BitmapFile = iopenw(FileName); - if (BitmapFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bBitmap; - } - - bBitmap = ilSaveBmpF(BitmapFile); - iclosew(BitmapFile); - - return bBitmap; -} - - -//! Writes a .bmp to an already-opened file -ILboolean ilSaveBmpF(ILHANDLE File) { - iSetOutputFile(File); - return iSaveBitmapInternal(); -} - - -//! Writes a .bmp to a memory "lump" -ILboolean ilSaveBmpL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveBitmapInternal(); -} - - -// Internal function used to save the .bmp. -ILboolean iSaveBitmapInternal() { - //int compress_rle8 = ilGetInteger(IL_BMP_RLE); - int compress_rle8 = IL_FALSE; // disabled BMP RLE compression. broken - ILuint FileSize, i, PadSize, Padding = 0; - ILimage *TempImage = NULL; - ILpal *TempPal; - ILubyte *TempData; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iputc('B'); // Comprises the - iputc('M'); // "signature" - - SaveLittleUInt(0); // Will come back and change later in this function (filesize) - SaveLittleUInt(0); // Reserved - - if (compress_rle8 == IL_TRUE) - { - TempImage = iConvertImage(iCurImage, IL_COLOR_INDEX, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - TempPal = iConvertPal(&TempImage->Pal, IL_PAL_BGR32); - if (TempPal == NULL) - { - ilCloseImage(TempImage); - return IL_FALSE; - } - } - - // If the current image has a palette, take care of it - TempPal = &iCurImage->Pal; - if( iCurImage->Pal.PalSize && iCurImage->Pal.Palette && iCurImage->Pal.PalType != IL_PAL_NONE ) { - // If the palette in .bmp format, write it directly - if (iCurImage->Pal.PalType == IL_PAL_BGR32) { - TempPal = &iCurImage->Pal; - } else { - TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_BGR32); - if (TempPal == NULL) { - return IL_FALSE; - } - } - } - - SaveLittleUInt(54 + TempPal->PalSize); // Offset of the data - - //Changed 20040923: moved this block above writing of - //BITMAPINFOHEADER, so that the written header refers to - //TempImage instead of the original image - - // @TODO LUMINANCE converted to BGR insteaf of beign saved to luminance - if (iCurImage->Format != IL_BGR && iCurImage->Format != IL_BGRA && iCurImage->Format != IL_COLOUR_INDEX) { - if (iCurImage->Format == IL_RGBA) { - TempImage = iConvertImage(iCurImage, IL_BGRA, IL_UNSIGNED_BYTE); - } else { - TempImage = iConvertImage(iCurImage, IL_BGR, IL_UNSIGNED_BYTE); - } - if (TempImage == NULL) - return IL_FALSE; - } else if (iCurImage->Bpc > 1) { - TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - } else { - TempImage = iCurImage; - } - - if (TempImage->Origin != IL_ORIGIN_LOWER_LEFT) { - TempData = iGetFlipped(TempImage); - } else { - TempData = TempImage->Data; - } - - SaveLittleUInt(0x28); // Header size - SaveLittleUInt(iCurImage->Width); - - // Removed because some image viewers don't like the negative height. - // even if it is standard. @TODO should be enabled or disabled - // usually enabled. - /*if (iCurImage->Origin == IL_ORIGIN_UPPER_LEFT) - SaveLittleInt(-(ILint)iCurImage->Height); - else*/ - SaveLittleInt(TempImage->Height); - - SaveLittleUShort(1); // Number of planes - SaveLittleUShort((ILushort)((ILushort)TempImage->Bpp << 3)); // Bpp - if( compress_rle8 == IL_TRUE ) { - SaveLittleInt(1); // rle8 compression - } else { - SaveLittleInt(0); - } - SaveLittleInt(0); // Size of image (Obsolete) - SaveLittleInt(0); // (Obsolete) - SaveLittleInt(0); // (Obsolete) - - if (TempImage->Pal.PalType != IL_PAL_NONE) { - SaveLittleInt(ilGetInteger(IL_PALETTE_NUM_COLS)); // Num colours used - } else { - SaveLittleInt(0); - } - SaveLittleInt(0); // Important colour (none) - - iwrite(TempPal->Palette, 1, TempPal->PalSize); - - - if( compress_rle8 == IL_TRUE ) { - //@TODO compress and save - ILubyte *Dest = (ILubyte*)ialloc((long)((double)TempImage->SizeOfPlane*130/127)); - FileSize = ilRleCompress(TempImage->Data,TempImage->Width,TempImage->Height, - TempImage->Depth,TempImage->Bpp,Dest,IL_BMPCOMP,NULL); - iwrite(Dest,1,FileSize); - } else { - PadSize = (4 - (TempImage->Bps % 4)) % 4; - // No padding, so write data directly. - if (PadSize == 0) { - iwrite(TempData, 1, TempImage->SizeOfPlane); - } else { // Odd width, so we must pad each line. - for (i = 0; i < TempImage->SizeOfPlane; i += TempImage->Bps) { - iwrite(TempData + i, 1, TempImage->Bps); // Write data - iwrite(&Padding, 1, PadSize); // Write pad byte(s) - } - } - } - - // Write the filesize - FileSize = itellw(); - iseekw(2, IL_SEEK_SET); - SaveLittleUInt(FileSize); - - if (TempPal != &iCurImage->Pal) { - ifree(TempPal->Palette); - ifree(TempPal); - } - if (TempData != TempImage->Data) - ifree(TempData); - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - iseekw(FileSize, IL_SEEK_SET); - - return IL_TRUE; -} - - -#endif//IL_NO_BMP diff --git a/win32/devil/src/il_convbuff.c b/win32/devil/src/il_convbuff.c deleted file mode 100644 index 0f10980fb..000000000 --- a/win32/devil/src/il_convbuff.c +++ /dev/null @@ -1,1975 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 01/08/2007 -// -// Filename: src-IL/src/il_convbuff.c -// -// Description: Converts between several image formats -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_manip.h" -#ifdef ALTIVEC_GCC -#include "altivec_typeconversion.h" -#endif -#include - - -ILvoid* ILAPIENTRY iSwitchTypes(ILuint SizeOfData, ILenum SrcType, ILenum DestType, ILvoid *Buffer); -ILushort ILAPIENTRY ilFloatToHalf(ILuint i); -ILuint ILAPIENTRY ilHalfToFloat (ILushort y); -ILfloat ILAPIENTRY ilFloatToHalfOverflow(); - -#define CHECK_ALLOC() if (NewData == NULL) { \ - if (Data != Buffer) \ - ifree(Data); \ - return IL_FALSE; \ - } - -ILAPI ILvoid* ILAPIENTRY ilConvertBuffer(ILuint SizeOfData, ILenum SrcFormat, ILenum DestFormat, ILenum SrcType, ILenum DestType, ILvoid *Buffer) { - //static const ILfloat LumFactor[3] = { 0.299f, 0.587f, 0.114f }; // Used for conversion to luminance - //static const ILfloat LumFactor[3] = { 0.3086f, 0.6094f, 0.0820f }; // http://www.sgi.com/grafica/matrix/index.html - static const ILfloat LumFactor[3] = { 0.212671f, 0.715160f, 0.072169f }; // http://www.inforamp.net/~poynton/ and libpng's libpng.txt - - ILubyte *NewData = NULL; - ILuint i, j, c, Size; - ILfloat Resultf; - ILdouble Resultd; - ILuint NumPix; // Really number of pixels * bpp. - ILuint BpcDest; - ILvoid *Data = NULL; - - if (SizeOfData == 0 || Buffer == NULL) { - ilSetError(IL_INVALID_PARAM); - return NULL; - } - - Data = iSwitchTypes(SizeOfData, SrcType, DestType, Buffer); - if (Data == NULL) - return NULL; - - BpcDest = ilGetBpcType(DestType); - NumPix = SizeOfData / ilGetBpcType(SrcType); - - if (DestFormat == SrcFormat) { - NewData = (ILubyte*)ialloc(NumPix * BpcDest); - if (NewData == NULL) { - return IL_FALSE; - } - memcpy(NewData, Data, NumPix * BpcDest); - if (Data != Buffer) - ifree(Data); - - return NewData; - } - - switch (SrcFormat) - { - case IL_RGB: - switch (DestFormat) - { - case IL_BGR: - NewData = (ILubyte*)ialloc(NumPix * BpcDest); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - #ifdef ALTIVEC_GCC - abc2cba_byte((ILubyte*)Data,NumPix * BpcDest,NewData); - #else - for (i = 0; i < NumPix; i += 3) { - NewData[i] = ((ILubyte*)(Data))[i+2]; - NewData[i+1] = ((ILubyte*)(Data))[i+1]; - NewData[i+2] = ((ILubyte*)(Data))[i]; - } - #endif - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - #ifdef ALTIVEC_GCC - abc2cba_short((ILushort*)Data,NumPix * BpcDest,(ILushort*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILushort*)(NewData))[i] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[i+2] = ((ILushort*)(Data))[i]; - } - #endif - break; - case IL_UNSIGNED_INT: - case IL_INT: - #ifdef ALTIVEC_GCC - abc2cba_int((ILuint*)Data,NumPix * BpcDest,(ILuint*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILuint*)(NewData))[i] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[i+2] = ((ILuint*)(Data))[i]; - } - #endif - break; - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abc2cba_float(Data,NumPix * BpcDest,NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILfloat*)(NewData))[i] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[i+2] = ((ILfloat*)(Data))[i]; - } - #endif - break; - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abc2cba_double((ILdouble*)Data,NumPix * BpcDest,(ILdouble*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILdouble*)(NewData))[i] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[i+2] = ((ILdouble*)(Data))[i]; - } - break; - #endif - } - break; - - case IL_RGBA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 4 / 3); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - NewData[j] = ((ILubyte*)(Data))[i]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i+2]; - NewData[j+3] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+3] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+3] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+3] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+3] = 1.0; - } - break; - } - break; - - case IL_BGRA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 4 / 3); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - NewData[j] = ((ILubyte*)(Data))[i+2]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i]; - NewData[j+3] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+3] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+3] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+3] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+3] = 1.0f; - } - break; - } - break; - - case IL_LUMINANCE: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 3); - CHECK_ALLOC(); - Size = NumPix / 3; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 3 + c] * LumFactor[c]; - } - NewData[i] = (ILubyte)Resultf; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILuint*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultf; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILfloat*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i] = Resultf; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i] = Resultd; - } - break; - } - break; - - case IL_LUMINANCE_ALPHA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 3 * 2); - CHECK_ALLOC(); - Size = NumPix / 3; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 3 + c] * LumFactor[c]; - } - NewData[i*2] = (ILubyte)Resultf; - NewData[i*2+1] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i*2] = (ILushort)Resultf; - ((ILushort*)(NewData))[i*2+1] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILuint*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i*2] = (ILuint)Resultf; - ((ILuint*)(NewData))[i*2+1] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILfloat*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i*2] = Resultf; - ((ILfloat*)(NewData))[i*2+1] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i*2] = Resultd; - ((ILdouble*)(NewData))[i*2+1] = 1.0; - } - break; - } - break; - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - - case IL_RGBA: - switch (DestFormat) - { - case IL_BGRA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - #ifdef ALTIVEC_GCC - abcd2cbad_byte(NewData,iCurImage->SizeOfData,NewData); - #else - for (i = 0; i < NumPix; i += 4) { - NewData[i] = ((ILubyte*)(Data))[i+2]; - NewData[i+1] = ((ILubyte*)(Data))[i+1]; - NewData[i+2] = ((ILubyte*)(Data))[i]; - NewData[i+3] = ((ILubyte*)(Data))[i+3]; - } - #endif - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - #ifdef ALTIVEC_GCC - abcd2cbad_short((ILushort*)Data,iCurImage->SizeOfData,(ILushort*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILushort*)(NewData))[i] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[i+2] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[i+3] = ((ILushort*)(Data))[i+3]; - } - #endif - break; - case IL_UNSIGNED_INT: - case IL_INT: - #ifdef ALTIVEC_GCC - abcd2cbad_int((ILuint*)Data,iCurImage->SizeOfData,(ILuint*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILuint*)(NewData))[i] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[i+2] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[i+3] = ((ILuint*)(Data))[i+3]; - } - #endif - break; - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abcd2cbad_float(Data,iCurImage->SizeOfData,NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILfloat*)(NewData))[i] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[i+2] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[i+3] = ((ILfloat*)(Data))[i+3]; - } - #endif - break; - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abcd2cbad_double((ILdouble*)Data,iCurImage->SizeOfData,(ILdouble*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILdouble*)(NewData))[i] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[i+2] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[i+3] = ((ILdouble*)(Data))[i+3]; - } - #endif - break; - } - break; - - case IL_RGB: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 3 / 4); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - NewData[j] = ((ILubyte*)(Data))[i]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i+2]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i+2]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i+2]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i+2]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i+2]; - } - break; - } - break; - - case IL_BGR: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 3 / 4); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - NewData[j] = ((ILubyte*)(Data))[i+2]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i]; - } - break; - } - break; - - case IL_LUMINANCE: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 4); - CHECK_ALLOC(); - Size = NumPix / 4; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 4 + c] * LumFactor[c]; - } - NewData[i] = (ILubyte)Resultf; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 4 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILuint*)(Data))[i * 4 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultd; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILfloat*)(Data))[i * 4 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i] = (ILfloat)Resultd; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 4 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i] = Resultd; - } - break; - } - break; - - case IL_LUMINANCE_ALPHA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 4 * 2); - CHECK_ALLOC(); - Size = NumPix / 4 * 2; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i += 2) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 2 + c] * LumFactor[c]; - } - NewData[i] = (ILubyte)Resultf; - NewData[i+1] = ((ILubyte*)(Data))[i * 2 + 3]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i += 2) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i * 2 + 3]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILuint*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultd; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i * 2 + 3]; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILfloat*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i] = (ILfloat)Resultd; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i * 2 + 3]; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i] = Resultd; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i * 2 + 3]; - } - break; - } - break; - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - - case IL_BGR: - switch (DestFormat) - { - case IL_RGB: - NewData = (ILubyte*)ialloc(NumPix * BpcDest); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - #ifdef ALTIVEC_GCC - abc2cba_byte(((ILubyte*)Data),NumPix * BpcDest,NewData); - #else - for (i = 0; i < NumPix; i += 3) { - NewData[i] = ((ILubyte*)(Data))[i+2]; - NewData[i+1] = ((ILubyte*)(Data))[i+1]; - NewData[i+2] = ((ILubyte*)(Data))[i]; - } - #endif - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - #ifdef ALTIVEC_GCC - abc2cba_short((ILushort*)Data,NumPix * BpcDest,(ILushort*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILushort*)(NewData))[i] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[i+2] = ((ILushort*)(Data))[i]; - } - #endif - break; - case IL_UNSIGNED_INT: - case IL_INT: - #ifdef ALTIVEC_GCC - abc2cba_int((ILuint*)Data,NumPix * BpcDest,(ILuint*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILuint*)(NewData))[i] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[i+2] = ((ILuint*)(Data))[i]; - } - #endif - break; - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abc2cba_float(Data,NumPix * BpcDest,NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILfloat*)(NewData))[i] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[i+2] = ((ILfloat*)(Data))[i]; - } - #endif - break; - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abc2cba_double((ILdouble*)Data,iCurImage->SizeOfData,(ILdouble*)NewData); - #else - for (i = 0; i < NumPix; i += 3) { - ((ILdouble*)(NewData))[i] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[i+2] = ((ILdouble*)(Data))[i]; - } - #endif - break; - } - break; - - case IL_BGRA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 4 / 3); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - NewData[j] = ((ILubyte*)(Data))[i]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i+2]; - NewData[j+3] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+3] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+3] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+3] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+3] = 1.0; - } - break; - } - break; - - case IL_RGBA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 4 / 3); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - NewData[j] = ((ILubyte*)(Data))[i+2]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i]; - NewData[j+3] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+3] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+3] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+3] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 3, j += 4) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+3] = 1.0; - } - break; - } - break; - - case IL_LUMINANCE: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 3); - CHECK_ALLOC(); - Size = NumPix / 3; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultf += ((ILubyte*)(Data))[i * 3 + c] * LumFactor[j]; - } - NewData[i] = (ILubyte)Resultf; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultf += ((ILushort*)(Data))[i * 3 + c] * LumFactor[j]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILuint*)(Data))[i * 3 + c] * LumFactor[j]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultd; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILfloat*)(Data))[i * 3 + c] * LumFactor[j]; - } - ((ILfloat*)(NewData))[i] = (ILfloat)Resultd; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILdouble*)(Data))[i * 3 + c] * LumFactor[j]; - } - ((ILdouble*)(NewData))[i] = Resultd; - } - break; - } - break; - - case IL_LUMINANCE_ALPHA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 3 * 2); - CHECK_ALLOC(); - Size = NumPix / 3; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 3 + c] * LumFactor[c]; - } - NewData[i*2] = (ILubyte)Resultf; - NewData[i*2+1] = UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i*2] = (ILushort)Resultf; - ((ILushort*)(NewData))[i*2+1] = USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILuint*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i*2] = (ILuint)Resultf; - ((ILuint*)(NewData))[i*2+1] = UINT_MAX; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultf = 0; - for (c = 0; c < 3; c++) { - Resultf += ((ILfloat*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i*2] = Resultf; - ((ILfloat*)(NewData))[i*2+1] = 1.0f; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 3 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i*2] = Resultd; - ((ILdouble*)(NewData))[i*2+1] = 1.0; - } - break; - } - break; - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - - case IL_BGRA: - switch (DestFormat) - { - case IL_RGBA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - #ifdef ALTIVEC_GCC - abcd2cbad_byte(NewData,iCurImage->SizeOfData,NewData); - #else - for (i = 0; i < NumPix; i += 4) { - NewData[i] = ((ILubyte*)(Data))[i+2]; - NewData[i+1] = ((ILubyte*)(Data))[i+1]; - NewData[i+2] = ((ILubyte*)(Data))[i]; - NewData[i+3] = ((ILubyte*)(Data))[i+3]; - } - #endif - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - #ifdef ALTIVEC_GCC - abcd2cbad_short((ILushort*)Data,iCurImage->SizeOfData,(ILushort*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILushort*)(NewData))[i] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[i+2] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[i+3] = ((ILushort*)(Data))[i+3]; - } - #endif - break; - case IL_UNSIGNED_INT: - case IL_INT: - #ifdef ALTIVEC_GCC - abcd2cbad_int((ILuint*)NewData,iCurImage->SizeOfData,(ILuint*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILuint*)(NewData))[i] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[i+2] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[i+3] = ((ILuint*)(Data))[i+3]; - } - #endif - break; - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abcd2cbad_float(NewData,iCurImage->SizeOfData,NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILfloat*)(NewData))[i] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[i+2] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[i+3] = ((ILfloat*)(Data))[i+3]; - } - #endif - break; - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abcd2cbad_double((ILdouble*)Data,iCurImage->SizeOfData,(ILdouble*)NewData); - #else - for (i = 0; i < NumPix; i += 4) { - ((ILdouble*)(NewData))[i] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[i+2] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[i+3] = ((ILdouble*)(Data))[i+3]; - } - #endif - break; - } - break; - - case IL_BGR: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 3 / 4); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - NewData[j] = ((ILubyte*)(Data))[i]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i+2]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i+2]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i+2]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i+2]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i+2]; - } - break; - } - break; - - case IL_RGB: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 3 / 4); - CHECK_ALLOC(); - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - NewData[j] = ((ILubyte*)(Data))[i+2]; - NewData[j+1] = ((ILubyte*)(Data))[i+1]; - NewData[j+2] = ((ILubyte*)(Data))[i]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i+2]; - ((ILushort*)(NewData))[j+1] = ((ILushort*)(Data))[i+1]; - ((ILushort*)(NewData))[j+2] = ((ILushort*)(Data))[i]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i+2]; - ((ILuint*)(NewData))[j+1] = ((ILuint*)(Data))[i+1]; - ((ILuint*)(NewData))[j+2] = ((ILuint*)(Data))[i]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i+2]; - ((ILfloat*)(NewData))[j+1] = ((ILfloat*)(Data))[i+1]; - ((ILfloat*)(NewData))[j+2] = ((ILfloat*)(Data))[i]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 4, j += 3) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i+2]; - ((ILdouble*)(NewData))[j+1] = ((ILdouble*)(Data))[i+1]; - ((ILdouble*)(NewData))[j+2] = ((ILdouble*)(Data))[i]; - } - break; - } - break; - - case IL_LUMINANCE: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 4); - CHECK_ALLOC(); - Size = NumPix / 4; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultf += ((ILubyte*)(Data))[i * 4 + c] * LumFactor[j]; - } - NewData[i] = (ILubyte)Resultf; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i++) { - Resultf = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultf += ((ILushort*)(Data))[i * 4 + c] * LumFactor[j]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILuint*)(Data))[i * 4 + c] * LumFactor[j]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultd; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILfloat*)(Data))[i * 4 + c] * LumFactor[j]; - } - ((ILfloat*)(NewData))[i] = (ILfloat)Resultd; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - Resultd = 0.0f; j = 2; - for (c = 0; c < 3; c++, j--) { - Resultd += ((ILdouble*)(Data))[i * 4 + c] * LumFactor[j]; - } - ((ILdouble*)(NewData))[i] = Resultd; - } - break; - } - break; - - case IL_LUMINANCE_ALPHA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 4 * 2); - CHECK_ALLOC(); - Size = NumPix / 4 * 2; - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i += 2) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILubyte*)(Data))[i * 2 + c] * LumFactor[c]; - } - NewData[i] = (ILubyte)Resultf; - NewData[i+1] = ((ILubyte*)(Data))[i * 2 + 3]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < Size; i += 2) { - Resultf = 0.0f; - for (c = 0; c < 3; c++) { - Resultf += ((ILushort*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILushort*)(NewData))[i] = (ILushort)Resultf; - ((ILushort*)(NewData))[i+1] = ((ILushort*)(Data))[i * 2 + 3]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILuint*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILuint*)(NewData))[i] = (ILuint)Resultd; - ((ILuint*)(NewData))[i+1] = ((ILuint*)(Data))[i * 2 + 3]; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILfloat*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILfloat*)(NewData))[i] = (ILfloat)Resultd; - ((ILfloat*)(NewData))[i+1] = ((ILfloat*)(Data))[i * 2 + 3]; - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i += 2) { - Resultd = 0.0; - for (c = 0; c < 3; c++) { - Resultd += ((ILdouble*)(Data))[i * 2 + c] * LumFactor[c]; - } - ((ILdouble*)(NewData))[i] = Resultd; - ((ILdouble*)(NewData))[i+1] = ((ILdouble*)(Data))[i * 2 + 3]; - } - break; - } - break; - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - - case IL_LUMINANCE: - switch (DestFormat) - { - case IL_RGB: - case IL_BGR: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 3); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i++, j += 3) { - for (c = 0; c < 3; c++) { - NewData[j + c] = ((ILubyte*)(Data))[i]; - } - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i++, j += 3) { - for (c = 0; c < 3; c++) { - ((ILushort*)(NewData))[j + c] = ((ILushort*)(Data))[i]; - } - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i++, j += 3) { - for (c = 0; c < 3; c++) { - ((ILuint*)(NewData))[j + c] = ((ILuint*)(Data))[i]; - } - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i++, j += 3) { - for (c = 0; c < 3; c++) { - ((ILfloat*)(NewData))[j + c] = ((ILfloat*)(Data))[i]; - } - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i++, j += 3) { - for (c = 0; c < 3; c++) { - ((ILdouble*)(NewData))[j + c] = ((ILdouble*)(Data))[i]; - } - } - break; - } - break; - - case IL_RGBA: - case IL_BGRA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 4); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i++, j += 4) { - for (c = 0; c < 3; c++) { - NewData[j + c] = ((ILubyte*)(Data))[i]; - } - NewData[j + 3] = UCHAR_MAX; // Full opacity - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i++, j += 4) { - for (c = 0; c < 3; c++) { - ((ILushort*)(NewData))[j + c] = ((ILushort*)(Data))[i]; - } - ((ILushort*)(NewData))[j + 3] = USHRT_MAX; // Full opacity - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i++, j += 4) { - for (c = 0; c < 3; c++) { - ((ILuint*)(NewData))[j + c] = ((ILuint*)(Data))[i]; - } - ((ILuint*)(NewData))[j + 3] = UINT_MAX; // Full opacity - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i++, j += 4) { - for (c = 0; c < 3; c++) { - ((ILfloat*)(NewData))[j + c] = ((ILfloat*)(Data))[i]; - } - ((ILfloat*)(NewData))[j + 3] = 1.0f; // Full opacity - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i++, j += 4) { - for (c = 0; c < 3; c++) { - ((ILdouble*)(NewData))[j + c] = ((ILdouble*)(Data))[i]; - } - ((ILdouble*)(NewData))[j + 3] = 1.0; // Full opacity - } - break; - } - break; - - case IL_LUMINANCE_ALPHA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest * 2); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < NumPix; i++) { - NewData[i * 2] = ((ILubyte*)(Data))[i]; - NewData[i * 2 + 1] = UCHAR_MAX; // Full opacity - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0; i < NumPix; i++) { - ((ILushort*)(NewData))[i * 2] = ((ILushort*)(Data))[i]; - ((ILushort*)(NewData))[i * 2 + 1] = USHRT_MAX; // Full opacity - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < NumPix; i++) { - ((ILuint*)(NewData))[i * 2] = ((ILuint*)(Data))[i]; - ((ILuint*)(NewData))[i * 2 + 1] = UINT_MAX; // Full opacity - } - break; - case IL_FLOAT: - for (i = 0; i < NumPix; i++) { - ((ILfloat*)(NewData))[i * 2] = ((ILfloat*)(Data))[i]; - ((ILfloat*)(NewData))[i * 2 + 1] = 1.0f; // Full opacity - } - break; - case IL_DOUBLE: - for (i = 0; i < NumPix; i++) { - ((ILdouble*)(NewData))[i * 2] = ((ILdouble*)(Data))[i]; - ((ILdouble*)(NewData))[i * 2 + 1] = 1.0; // Full opacity - } - break; - } - break; - - - /*case IL_COLOUR_INDEX: - NewData = (ILubyte*)ialloc(iCurImage->SizeOfData); - NewImage->Pal.Palette = (ILubyte*)ialloc(768); - if (NewData == NULL || NewImage->Pal.Palette) { - ifree(NewImage); - return IL_FALSE; - } - - // Fill the palette - for (i = 0; i < 256; i++) { - for (c = 0; c < 3; c++) { - NewImage->Pal.Palette[i * 3 + c] = (ILubyte)i; - } - } - // Copy the data - for (i = 0; i < iCurImage->SizeOfData; i++) { - NewData[i] = iCurImage->Data[i]; - } - break;*/ - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - - - case IL_LUMINANCE_ALPHA: - switch (DestFormat) - { - case IL_RGB: - case IL_BGR: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 2 * 3); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 2, j += 3) { - for (c = 0; c < 3; c++) { - NewData[j + c] = ((ILubyte*)(Data))[i]; - } - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 2, j += 3) { - for (c = 0; c < 3; c++) { - ((ILushort*)(NewData))[j + c] = ((ILushort*)(Data))[i]; - } - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 2, j += 3) { - for (c = 0; c < 3; c++) { - ((ILuint*)(NewData))[j + c] = ((ILuint*)(Data))[i]; - } - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 2, j += 3) { - for (c = 0; c < 3; c++) { - ((ILfloat*)(NewData))[j + c] = ((ILfloat*)(Data))[i]; - } - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 2, j += 3) { - for (c = 0; c < 3; c++) { - ((ILdouble*)(NewData))[j + c] = ((ILdouble*)(Data))[i]; - } - } - break; - } - break; - - case IL_RGBA: - case IL_BGRA: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 2 * 4); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 2, j += 4) { - for (c = 0; c < 3; c++) { - NewData[j + c] = ((ILubyte*)(Data))[i]; - } - NewData[j + 3] = ((ILubyte*)(Data))[i+1]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 2, j += 4) { - for (c = 0; c < 3; c++) { - ((ILushort*)(NewData))[j + c] = ((ILushort*)(Data))[i]; - } - ((ILushort*)(NewData))[j + 3] = ((ILushort*)(Data))[i+1]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 2, j += 4) { - for (c = 0; c < 3; c++) { - ((ILuint*)(NewData))[j + c] = ((ILuint*)(Data))[i]; - } - ((ILuint*)(NewData))[j + 3] = ((ILuint*)(Data))[i+1]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 2, j += 4) { - for (c = 0; c < 3; c++) { - ((ILfloat*)(NewData))[j + c] = ((ILfloat*)(Data))[i]; - } - ((ILfloat*)(NewData))[j + 3] = ((ILfloat*)(Data))[i+1]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 2, j += 4) { - for (c = 0; c < 3; c++) { - ((ILdouble*)(NewData))[j + c] = ((ILdouble*)(Data))[i]; - } - ((ILdouble*)(NewData))[j + 3] = ((ILdouble*)(Data))[i+1]; - } - break; - } - break; - - case IL_LUMINANCE: - NewData = (ILubyte*)ialloc(NumPix * BpcDest / 2); - CHECK_ALLOC(); - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0, j = 0; i < NumPix; i += 2, j++) { - NewData[j] = ((ILubyte*)(Data))[i]; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - case IL_HALF: - for (i = 0, j = 0; i < NumPix; i += 2, j++) { - ((ILushort*)(NewData))[j] = ((ILushort*)(Data))[i]; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0, j = 0; i < NumPix; i += 2, j++) { - ((ILuint*)(NewData))[j] = ((ILuint*)(Data))[i]; - } - break; - case IL_FLOAT: - for (i = 0, j = 0; i < NumPix; i += 2, j++) { - ((ILfloat*)(NewData))[j] = ((ILfloat*)(Data))[i]; - } - break; - case IL_DOUBLE: - for (i = 0, j = 0; i < NumPix; i += 2, j++) { - ((ILdouble*)(NewData))[j] = ((ILdouble*)(Data))[i]; - } - break; - } - break; - - /*case IL_COLOUR_INDEX: - NewData = (ILubyte*)ialloc(iCurImage->SizeOfData); - NewImage->Pal.Palette = (ILubyte*)ialloc(768); - if (NewData == NULL || NewImage->Pal.Palette) { - ifree(NewImage); - return IL_FALSE; - } - - // Fill the palette - for (i = 0; i < 256; i++) { - for (c = 0; c < 3; c++) { - NewImage->Pal.Palette[i * 3 + c] = (ILubyte)i; - } - } - // Copy the data - for (i = 0; i < iCurImage->SizeOfData; i++) { - NewData[i] = iCurImage->Data[i]; - } - break;*/ - - default: - ilSetError(IL_INVALID_CONVERSION); - if (Data != Buffer) - ifree(Data); - return NULL; - } - break; - } - - if (Data != Buffer) - ifree(Data); - - return NewData; -} - - -// Really shouldn't have to check for default, as in above ilConvertBuffer(). -ILvoid* ILAPIENTRY iSwitchTypes(ILuint SizeOfData, ILenum SrcType, ILenum DestType, ILvoid *Buffer) { - ILuint BpcSrc, BpcDest, Size, i; - ILubyte *NewData, *BytePtr; - ILushort *ShortPtr; - ILuint *IntPtr; - ILfloat *FloatPtr, tempFloat; - ILdouble *DblPtr, tempDouble; - ILushort *HalfPtr; - - BpcSrc = ilGetBpcType(SrcType); - BpcDest = ilGetBpcType(DestType); - - if (BpcSrc == 0 || BpcDest == 0) { - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - Size = SizeOfData / BpcSrc; - - if (BpcSrc == BpcDest) { - return Buffer; - } - - NewData = (ILubyte*)ialloc(Size * BpcDest); - if (NewData == NULL) { - return IL_FALSE; - } - - switch (DestType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - BytePtr = (ILubyte*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_SHORT: - case IL_SHORT: - for (i = 0; i < Size; i++) { - BytePtr[i] = ((ILushort*)Buffer)[i] >> 8; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - BytePtr[i] = ((ILuint*)Buffer)[i] >> 24; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - #if CLAMP_FLOATS - tempFloat = clamp(((ILfloat*)Buffer)[i]); - BytePtr[i] = (ILubyte)(tempFloat * UCHAR_MAX); - #else - BytePtr[i] = (ILubyte)( ((ILfloat*)Buffer)[i] * UCHAR_MAX); - #endif - } - break; - case IL_HALF: - for (i = 0; i < Size; i++) { - #if CLAMP_HALF - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - tempFloat = clamp(tempFloat); - BytePtr[i] = (ILubyte)(tempFloat * UCHAR_MAX); - #else - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - BytePtr[i] = (ILubyte)(tempFloat * UCHAR_MAX); - #endif - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - #if CLAMP_DOUBLES - tempDouble = clamp(((ILdouble*)Buffer)[i]); - BytePtr[i] = (ILubyte)(tempDouble * UCHAR_MAX); - #else - BytePtr[i] = (ILubyte)( ((ILdouble*)Buffer)[i] * UCHAR_MAX); - #endif - } - break; - } - break; - - case IL_UNSIGNED_SHORT: - case IL_SHORT: - ShortPtr = (ILushort*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - ShortPtr[i] = ((ILubyte*)Buffer)[i] << 8; - } - break; - case IL_UNSIGNED_INT: - case IL_INT: - for (i = 0; i < Size; i++) { - ShortPtr[i] = ((ILuint*)Buffer)[i] >> 16; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - #if CLAMP_FLOATS - tempFloat = clamp(((ILfloat*)Buffer)[i]); - ShortPtr[i] = (ILushort)(tempFloat * USHRT_MAX); - #else - ShortPtr[i] = (ILushort)( ((ILfloat*)Buffer)[i] * USHRT_MAX); - #endif - } - break; - case IL_HALF: - for (i = 0; i < Size; i++) { - #if CLAMP_FLOATS - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - tempFloat = clamp(tempFloat); - ShortPtr[i] = (ILushort)(tempFloat * USHRT_MAX); - #else - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - ShortPtr[i] = (ILushort)(tempFloat * USHRT_MAX); - #endif - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - #if CLAMP_DOUBLES - tempDouble = clamp(((ILdouble*)Buffer)[i]); - ShortPtr[i] = (ILushort)(tempDouble * USHRT_MAX); - #else - ShortPtr[i] = (ILushort)( ((ILdouble*)Buffer)[i] * USHRT_MAX); - #endif - } - break; - } - break; - - case IL_UNSIGNED_INT: - case IL_INT: - IntPtr = (ILuint*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_BYTE: - case IL_BYTE: - for (i = 0; i < Size; i++) { - IntPtr[i] = ((ILubyte*)Buffer)[i] << 24; - } - break; - case IL_UNSIGNED_SHORT: - case IL_SHORT: - for (i = 0; i < Size; i++) { - IntPtr[i] = ((ILushort*)Buffer)[i] << 16; - } - break; - case IL_FLOAT: - for (i = 0; i < Size; i++) { - #if CLAMP_FLOATS - tempFloat = clamp(((ILfloat*)Buffer)[i]); - IntPtr[i] = (ILuint)(tempFloat * UINT_MAX); - #else - IntPtr[i] = (ILuint)( ((ILfloat*)Buffer)[i] * UINT_MAX); - #endif - } - break; - case IL_HALF: - for (i = 0; i < Size; i++) { - #if CLAMP_FLOATS - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - tempFloat = clamp(tempFloat); - IntPtr[i] = (ILuint)(tempFloat * UINT_MAX); - #else - *((ILuint*)&tempFloat) = ilHalfToFloat(((ILushort*)Buffer)[i]); - IntPtr[i] = (ILuint)(tempFloat * UINT_MAX); - #endif - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - #if CLAMP_DOUBLES - tempDouble = clamp(((ILdouble*)Buffer)[i]); - IntPtr[i] = (ILuint)(tempDouble * UINT_MAX); - #else - IntPtr[i] = (ILuint)( ((ILdouble*)Buffer)[i] * UINT_MAX); - #endif - } - break; - } - break; - - // @TODO: Handle signed better. - case IL_FLOAT: - FloatPtr = (ILfloat*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_BYTE: - for (i = 0; i < Size; i++) { - FloatPtr[i] = ((ILubyte*)Buffer)[i] / (ILfloat)UCHAR_MAX; - } - break; - case IL_BYTE: - for (i = 0; i < Size; i++) { - FloatPtr[i] = ((ILbyte*)Buffer)[i] / (ILfloat)UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - for (i = 0; i < Size; i++) { - FloatPtr[i] = ((ILushort*)Buffer)[i] / (ILfloat)USHRT_MAX; - } - break; - case IL_SHORT: - for (i = 0; i < Size; i++) { - FloatPtr[i] = ((ILshort*)Buffer)[i] / (ILfloat)USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - for (i = 0; i < Size; i++) { - FloatPtr[i] = (ILfloat)((ILuint*)Buffer)[i] / (ILfloat)UINT_MAX; - } - break; - case IL_INT: - for (i = 0; i < Size; i++) { - FloatPtr[i] = (ILfloat)((ILint*)Buffer)[i] / (ILfloat)UINT_MAX; - } - break; - case IL_HALF: - for (i = 0; i < Size; i++) { - *((ILuint*)&FloatPtr[i]) = ilHalfToFloat(((ILushort*)Buffer)[i]); - } - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - FloatPtr[i] = (ILfloat)((ILdouble*)Buffer)[i]; - } - break; - } - break; - - case IL_DOUBLE: - DblPtr = (ILdouble*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_BYTE: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILubyte*)Buffer)[i] / (ILdouble)UCHAR_MAX; - } - break; - case IL_BYTE: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILbyte*)Buffer)[i] / (ILdouble)UCHAR_MAX; - } - break; - case IL_UNSIGNED_SHORT: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILushort*)Buffer)[i] / (ILdouble)USHRT_MAX; - } - break; - case IL_SHORT: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILshort*)Buffer)[i] / (ILdouble)USHRT_MAX; - } - break; - case IL_UNSIGNED_INT: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILuint*)Buffer)[i] / (ILdouble)UINT_MAX; - } - break; - case IL_INT: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILint*)Buffer)[i] / (ILdouble)UINT_MAX; - } - break; - case IL_HALF: - for (i = 0; i < Size; i++) { - *(ILushort*)&tempFloat = ilHalfToFloat(((ILushort*)Buffer)[i]); - DblPtr[i] = tempFloat; - } - case IL_FLOAT: - for (i = 0; i < Size; i++) { - DblPtr[i] = ((ILfloat*)Buffer)[i]; - } - break; - } - break; - - case IL_HALF: - HalfPtr = (ILushort*)NewData; - switch (SrcType) - { - case IL_UNSIGNED_BYTE: - for (i = 0; i < Size; i++) { - tempFloat = ((ILubyte*)Buffer)[i] / (ILfloat)UCHAR_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_BYTE: - for (i = 0; i < Size; i++) { - tempFloat = ((ILbyte*)Buffer)[i] / (ILfloat)UCHAR_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_UNSIGNED_SHORT: - for (i = 0; i < Size; i++) { - tempFloat = ((ILushort*)Buffer)[i] / (ILfloat)USHRT_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_SHORT: - for (i = 0; i < Size; i++) { - tempFloat = ((ILshort*)Buffer)[i] / (ILfloat)USHRT_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_UNSIGNED_INT: - for (i = 0; i < Size; i++) { - tempFloat = ((ILuint*)Buffer)[i] / (ILfloat)UINT_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_INT: - for (i = 0; i < Size; i++) { - tempFloat = ((ILint*)Buffer)[i] / (ILfloat)UINT_MAX; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - case IL_DOUBLE: - for (i = 0; i < Size; i++) { - tempFloat = (ILfloat)((ILdouble*)Buffer)[i]; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - case IL_FLOAT: - for (i = 0; i < Size; i++) { - tempFloat = ((ILfloat*)Buffer)[i]; - *((ILushort*)&HalfPtr[i]) = ilFloatToHalf(*(ILuint*)&tempFloat); - } - break; - } - break; - } - - - return NewData; -} - - - - diff --git a/win32/devil/src/il_convert.c b/win32/devil/src/il_convert.c deleted file mode 100644 index 8770c5ca9..000000000 --- a/win32/devil/src/il_convert.c +++ /dev/null @@ -1,1042 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 12/06/2006 -// -// Filename: src-IL/src/il_convert.c -// -// Description: Converts between several image formats -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_manip.h" -#include - - -ILimage *iConvertPalette(ILimage *Image, ILenum DestFormat) -{ - static const ILfloat LumFactor[3] = { 0.212671f, 0.715160f, 0.072169f }; // http://www.inforamp.net/~poynton/ and libpng's libpng.txt - Used for conversion to luminance. - ILimage *NewImage = NULL, *CurImage = NULL; - ILuint i, j, k, c, Size, LumBpp = 1; - ILfloat Resultf; - ILubyte *Temp = NULL; - ILboolean Converted; - - NewImage = (ILimage*)icalloc(1, sizeof(ILimage)); // Much better to have it all set to 0. - if (NewImage == NULL) { - return IL_FALSE; - } - - ilCopyImageAttr(NewImage, Image); - - if (!iCurImage->Pal.Palette || !iCurImage->Pal.PalSize || iCurImage->Pal.PalType == IL_PAL_NONE || iCurImage->Bpp != 1) { - ilCloseImage(NewImage); - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - if (DestFormat == IL_LUMINANCE || DestFormat == IL_LUMINANCE_ALPHA) { - if (NewImage->Pal.Palette) - ifree(NewImage->Pal.Palette); - if (DestFormat == IL_LUMINANCE_ALPHA) - LumBpp = 2; - - switch (iCurImage->Pal.PalType) - { - case IL_PAL_RGB24: - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - Temp = (ILubyte*)ialloc(LumBpp * Image->Pal.PalSize / ilGetBppPal(Image->Pal.PalType)); - if (Temp == NULL) - goto alloc_error; - - Size = ilGetBppPal(Image->Pal.PalType); - for (i = 0, k = 0; i < Image->Pal.PalSize; i += Size, k += LumBpp) { - Resultf = 0.0f; - for (c = 0; c < Size; c++) { - Resultf += Image->Pal.Palette[i + c] * LumFactor[c]; - } - Temp[k] = (ILubyte)Resultf; - if (LumBpp == 2) { - if (iCurImage->Pal.PalType == IL_PAL_RGBA32) - Temp[k+1] = Image->Pal.Palette[i + 3]; - else - Temp[k+1] = 0xff; - } - } - - break; - - case IL_PAL_BGR24: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - Temp = (ILubyte*)ialloc(LumBpp * Image->Pal.PalSize / ilGetBppPal(Image->Pal.PalType)); - if (Temp == NULL) - goto alloc_error; - - Size = ilGetBppPal(Image->Pal.PalType); - for (i = 0, k = 0; i < Image->Pal.PalSize; i += Size, k += LumBpp) { - Resultf = 0.0f; j = 2; - for (c = 0; c < Size; c++, j--) { - Resultf += Image->Pal.Palette[i + c] * LumFactor[j]; - } - Temp[k] = (ILubyte)Resultf; - if (LumBpp == 2) { - if (iCurImage->Pal.PalType == IL_PAL_RGBA32) - Temp[k+1] = Image->Pal.Palette[i + 3]; - else - Temp[k+1] = 0xff; - } - } - - break; - } - - NewImage->Pal.Palette = NULL; - NewImage->Pal.PalSize = 0; - NewImage->Pal.PalType = IL_PAL_NONE; - NewImage->Format = DestFormat; - NewImage->Bpp = LumBpp; - NewImage->Bps = NewImage->Width * LumBpp; - NewImage->SizeOfData = NewImage->SizeOfPlane = NewImage->Bps * NewImage->Height; - NewImage->Data = (ILubyte*)ialloc(NewImage->SizeOfData); - if (NewImage->Data == NULL) - goto alloc_error; - - if (LumBpp == 2) { - for (i = 0; i < Image->SizeOfData; i++) { - NewImage->Data[i*2] = Temp[Image->Data[i] * 2]; - NewImage->Data[i*2+1] = Temp[Image->Data[i] * 2 + 1]; - } - } - else { - for (i = 0; i < Image->SizeOfData; i++) { - NewImage->Data[i] = Temp[Image->Data[i]]; - } - } - - ifree(Temp); - - return NewImage; - } - - //NewImage->Format = ilGetPalBaseType(iCurImage->Pal.PalType); - NewImage->Format = DestFormat; - - if (ilGetBppFormat(NewImage->Format) == 0) { - ilCloseImage(NewImage); - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - CurImage = iCurImage; - ilSetCurImage(NewImage); - - switch (DestFormat) - { - case IL_RGB: - Converted = ilConvertPal(IL_PAL_RGB24); - break; - - case IL_BGR: - Converted = ilConvertPal(IL_PAL_BGR24); - break; - - case IL_RGBA: - Converted = ilConvertPal(IL_PAL_RGB32); - break; - - case IL_BGRA: - Converted = ilConvertPal(IL_PAL_BGR32); - break; - - case IL_COLOUR_INDEX: - // Just copy the original image over. - NewImage->Data = (ILubyte*)ialloc(CurImage->SizeOfData); - if (NewImage->Data == NULL) - goto alloc_error; - NewImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (NewImage->Pal.Palette == NULL) - goto alloc_error; - memcpy(NewImage->Data, CurImage->Data, CurImage->SizeOfData); - memcpy(NewImage->Pal.Palette, Image->Pal.Palette, Image->Pal.PalSize); - NewImage->Pal.PalSize = Image->Pal.PalSize; - NewImage->Pal.PalType = Image->Pal.PalType; - ilSetCurImage(CurImage); - return NewImage; - - default: - ilCloseImage(NewImage); - ilSetError(IL_INVALID_CONVERSION); - return NULL; - } - - // Resize to new bpp - ilResizeImage(NewImage, NewImage->Width, NewImage->Height, NewImage->Depth, ilGetBppFormat(DestFormat), /*ilGetBpcType(DestType)*/1); - - // ilConvertPal already sets the error message - no need to confuse the user. - if (!Converted) { - ilSetCurImage(CurImage); - ilCloseImage(NewImage); - return NULL; - } - - Size = ilGetBppPal(NewImage->Pal.PalType); - for (i = 0; i < Image->SizeOfData; i++) { - for (c = 0; c < NewImage->Bpp; c++) { - NewImage->Data[i * NewImage->Bpp + c] = NewImage->Pal.Palette[Image->Data[i] * Size + c]; - } - } - - ifree(NewImage->Pal.Palette); - - NewImage->Pal.Palette = NULL; - NewImage->Pal.PalSize = 0; - NewImage->Pal.PalType = IL_PAL_NONE; - ilSetCurImage(CurImage); - - return NewImage; - -alloc_error: - ifree(Temp); - if (NewImage) - ilCloseImage(NewImage); - if (CurImage != iCurImage) - ilSetCurImage(CurImage); - return NULL; -} - - -// In il_quantizer.c -ILimage *iQuantizeImage(ILimage *Image, ILuint NumCols); -// In il_neuquant.c -ILimage *iNeuQuant(ILimage *Image); - -// Converts an image from one format to another -ILAPI ILimage* ILAPIENTRY iConvertImage(ILimage *Image, ILenum DestFormat, ILenum DestType) -{ - ILimage *NewImage, *CurImage; - ILuint i; - ILubyte *NewData; - - CurImage = Image; - if (Image == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - // We don't support 16-bit color indices (or higher). - if (DestFormat == IL_COLOUR_INDEX && DestType >= IL_SHORT) { - ilSetError(IL_INVALID_CONVERSION); - return NULL; - } - - if (Image->Format == IL_COLOUR_INDEX) { - NewImage = iConvertPalette(Image, DestFormat); - - //added test 2003-09-01 - if(NewImage == NULL) - return NULL; - - if (DestType == NewImage->Type) - return NewImage; - - NewData = (ILubyte*)ilConvertBuffer(NewImage->SizeOfData, NewImage->Format, DestFormat, NewImage->Type, DestType, NewImage->Data); - if (NewData == NULL) { - ifree(NewImage); // ilCloseImage not needed. - return NULL; - } - ifree(NewImage->Data); - NewImage->Data = NewData; - - ilCopyImageAttr(NewImage, Image); - NewImage->Format = DestFormat; - NewImage->Type = DestType; - NewImage->Bpc = ilGetBpcType(DestType); - NewImage->Bpp = ilGetBppFormat(DestFormat); - NewImage->Bps = NewImage->Bpp * NewImage->Bpc * NewImage->Width; - NewImage->SizeOfPlane = NewImage->Bps * NewImage->Height; - NewImage->SizeOfData = NewImage->SizeOfPlane * NewImage->Depth; - } - else if (DestFormat == IL_COLOUR_INDEX && Image->Format != IL_LUMINANCE) { - if (iGetInt(IL_QUANTIZATION_MODE) == IL_NEU_QUANT) - return iNeuQuant(Image); - else // Assume IL_WU_QUANT otherwise. - return iQuantizeImage(Image, iGetInt(IL_MAX_QUANT_INDEXS)); - } - else { - NewImage = (ILimage*)icalloc(1, sizeof(ILimage)); // Much better to have it all set to 0. - if (NewImage == NULL) { - return NULL; - } - - if (ilGetBppFormat(DestFormat) == 0) { - ilSetError(IL_INVALID_PARAM); - ifree(NewImage); - return NULL; - } - - ilCopyImageAttr(NewImage, Image); - NewImage->Format = DestFormat; - NewImage->Type = DestType; - NewImage->Bpc = ilGetBpcType(DestType); - NewImage->Bpp = ilGetBppFormat(DestFormat); - NewImage->Bps = NewImage->Bpp * NewImage->Bpc * NewImage->Width; - NewImage->SizeOfPlane = NewImage->Bps * NewImage->Height; - NewImage->SizeOfData = NewImage->SizeOfPlane * NewImage->Depth; - - if (DestFormat == IL_COLOUR_INDEX && Image->Format == IL_LUMINANCE) { - NewImage->Pal.PalSize = 768; - NewImage->Pal.PalType = IL_PAL_RGB24; - NewImage->Pal.Palette = (ILubyte*)ialloc(768); - for (i = 0; i < 256; i++) { - NewImage->Pal.Palette[i * 3] = i; - NewImage->Pal.Palette[i * 3 + 1] = i; - NewImage->Pal.Palette[i * 3 + 2] = i; - } - NewImage->Data = (ILubyte*)ialloc(Image->SizeOfData); - if (NewImage->Data == NULL) { - ilCloseImage(NewImage); - return NULL; - } - memcpy(NewImage->Data, Image->Data, Image->SizeOfData); - } - else { - NewImage->Data = (ILubyte*)ilConvertBuffer(Image->SizeOfData, Image->Format, DestFormat, Image->Type, DestType, Image->Data); - if (NewImage->Data == NULL) { - ifree(NewImage); // ilCloseImage not needed. - return NULL; - } - } - } - - return NewImage; -} - - -//! Converts the current image to the DestFormat format. -ILboolean ILAPIENTRY ilConvertImage(ILenum DestFormat, ILenum DestType) -{ - ILimage *Image; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (DestFormat == iCurImage->Format && DestType == iCurImage->Type) - return IL_TRUE; // No conversion needed. - - if (DestType == iCurImage->Type) { - if (iFastConvert(DestFormat)) { - iCurImage->Format = DestFormat; - return IL_TRUE; - } - } - - if (ilIsEnabled(IL_USE_KEY_COLOUR)) { - ilAddAlphaKey(iCurImage); - } - Image = iConvertImage(iCurImage, DestFormat, DestType); - if (Image == NULL) - return IL_FALSE; - - //ilCopyImageAttr(iCurImage, Image); // Destroys subimages. - - // We don't copy the colour profile here, since it stays the same. - // Same with the DXTC data. - iCurImage->Format = DestFormat; - iCurImage->Type = DestType; - iCurImage->Bpc = ilGetBpcType(DestType); - iCurImage->Bpp = ilGetBppFormat(DestFormat); - iCurImage->Bps = iCurImage->Width * iCurImage->Bpc * iCurImage->Bpp; - iCurImage->SizeOfPlane = iCurImage->Bps * iCurImage->Height; - iCurImage->SizeOfData = iCurImage->Depth * iCurImage->SizeOfPlane; - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = Image->Pal.Palette; - iCurImage->Pal.PalSize = Image->Pal.PalSize; - iCurImage->Pal.PalType = Image->Pal.PalType; - Image->Pal.Palette = NULL; - ifree(iCurImage->Data); - iCurImage->Data = Image->Data; - Image->Data = NULL; - ilCloseImage(Image); - - return IL_TRUE; -} - - -// Swaps the colour order of the current image (rgb(a)->bgr(a) or vice-versa). -// Must be either an 8, 24 or 32-bit (coloured) image (or palette). -ILboolean ilSwapColours() -{ - ILuint i = 0, Size = iCurImage->Bpp * iCurImage->Width * iCurImage->Height; - ILbyte PalBpp = ilGetBppPal(iCurImage->Pal.PalType); - ILushort *ShortPtr; - ILuint *IntPtr, Temp; - ILdouble *DoublePtr, DoubleTemp; - - if ((iCurImage->Bpp != 1 && iCurImage->Bpp != 3 && iCurImage->Bpp != 4)) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - // Just check before we change the format. - if (iCurImage->Format == IL_COLOUR_INDEX) { - if (PalBpp == 0 || iCurImage->Format != IL_COLOUR_INDEX) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - } - - switch (iCurImage->Format) - { - case IL_RGB: - iCurImage->Format = IL_BGR; - break; - case IL_RGBA: - iCurImage->Format = IL_BGRA; - break; - case IL_BGR: - iCurImage->Format = IL_RGB; - break; - case IL_BGRA: - iCurImage->Format = IL_RGBA; - break; - case IL_LUMINANCE: - case IL_LUMINANCE_ALPHA: - return IL_TRUE; // No need to do anything to luminance images. - case IL_COLOUR_INDEX: - switch (iCurImage->Pal.PalType) - { - case IL_PAL_RGB24: - iCurImage->Pal.PalType = IL_PAL_BGR24; - break; - case IL_PAL_RGB32: - iCurImage->Pal.PalType = IL_PAL_BGR32; - break; - case IL_PAL_RGBA32: - iCurImage->Pal.PalType = IL_PAL_BGRA32; - break; - case IL_PAL_BGR24: - iCurImage->Pal.PalType = IL_PAL_RGB24; - break; - case IL_PAL_BGR32: - iCurImage->Pal.PalType = IL_PAL_RGB32; - break; - case IL_PAL_BGRA32: - iCurImage->Pal.PalType = IL_PAL_RGBA32; - break; - default: - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - break; - default: - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iCurImage->Format == IL_COLOUR_INDEX) { - for (; i < iCurImage->Pal.PalSize; i += PalBpp) { - Temp = iCurImage->Pal.Palette[i]; - iCurImage->Pal.Palette[i] = iCurImage->Pal.Palette[i+2]; - iCurImage->Pal.Palette[i+2] = Temp; - } - } - else { - ShortPtr = (ILushort*)iCurImage->Data; - IntPtr = (ILuint*)iCurImage->Data; - DoublePtr = (ILdouble*)iCurImage->Data; - switch (iCurImage->Bpc) - { - case 1: - for (; i < Size; i += iCurImage->Bpp) { - Temp = iCurImage->Data[i]; - iCurImage->Data[i] = iCurImage->Data[i+2]; - iCurImage->Data[i+2] = Temp; - } - break; - case 2: - for (; i < Size; i += iCurImage->Bpp) { - Temp = ShortPtr[i]; - ShortPtr[i] = ShortPtr[i+2]; - ShortPtr[i+2] = Temp; - } - break; - case 4: // Works fine with ILint, ILuint and ILfloat. - for (; i < Size; i += iCurImage->Bpp) { - Temp = IntPtr[i]; - IntPtr[i] = IntPtr[i+2]; - IntPtr[i+2] = Temp; - } - break; - case 8: - for (; i < Size; i += iCurImage->Bpp) { - DoubleTemp = DoublePtr[i]; - DoublePtr[i] = DoublePtr[i+2]; - DoublePtr[i+2] = DoubleTemp; - } - break; - } - } - - return IL_TRUE; -} - - -// Adds an opaque alpha channel to a 24-bit image -ILboolean ilAddAlpha() -{ - ILubyte *NewData, NewBpp; - ILuint i = 0, j = 0, Size; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iCurImage->Bpp != 3) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - Size = iCurImage->Bps * iCurImage->Height / iCurImage->Bpc; - NewBpp = (ILubyte)(iCurImage->Bpp + 1); - - NewData = (ILubyte*)ialloc(NewBpp * iCurImage->Bpc * iCurImage->Width * iCurImage->Height); - if (NewData == NULL) { - return IL_FALSE; - } - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - NewData[j] = iCurImage->Data[i]; - NewData[j+1] = iCurImage->Data[i+1]; - NewData[j+2] = iCurImage->Data[i+2]; - NewData[j+3] = UCHAR_MAX; // Max opaqueness - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILushort*)NewData)[j] = ((ILushort*)iCurImage->Data)[i]; - ((ILushort*)NewData)[j+1] = ((ILushort*)iCurImage->Data)[i+1]; - ((ILushort*)NewData)[j+2] = ((ILushort*)iCurImage->Data)[i+2]; - ((ILushort*)NewData)[j+3] = USHRT_MAX; - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILuint*)NewData)[j] = ((ILuint*)iCurImage->Data)[i]; - ((ILuint*)NewData)[j+1] = ((ILuint*)iCurImage->Data)[i+1]; - ((ILuint*)NewData)[j+2] = ((ILuint*)iCurImage->Data)[i+2]; - ((ILuint*)NewData)[j+3] = UINT_MAX; - } - break; - - case IL_FLOAT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILfloat*)NewData)[j] = ((ILfloat*)iCurImage->Data)[i]; - ((ILfloat*)NewData)[j+1] = ((ILfloat*)iCurImage->Data)[i+1]; - ((ILfloat*)NewData)[j+2] = ((ILfloat*)iCurImage->Data)[i+2]; - ((ILfloat*)NewData)[j+3] = 1.0f; - } - break; - - case IL_DOUBLE: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILdouble*)NewData)[j] = ((ILdouble*)iCurImage->Data)[i]; - ((ILdouble*)NewData)[j+1] = ((ILdouble*)iCurImage->Data)[i+1]; - ((ILdouble*)NewData)[j+2] = ((ILdouble*)iCurImage->Data)[i+2]; - ((ILdouble*)NewData)[j+3] = 1.0; - } - break; - - default: - ifree(NewData); - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - - iCurImage->Bpp = NewBpp; - iCurImage->Bps = iCurImage->Width * iCurImage->Bpc * NewBpp; - iCurImage->SizeOfPlane = iCurImage->Bps * iCurImage->Height; - iCurImage->SizeOfData = iCurImage->SizeOfPlane * iCurImage->Depth; - ifree(iCurImage->Data); - iCurImage->Data = NewData; - - switch (iCurImage->Format) - { - case IL_RGB: - iCurImage->Format = IL_RGBA; - break; - case IL_BGR: - iCurImage->Format = IL_BGRA; - break; - } - - return IL_TRUE; -} - - -//ILfloat KeyRed = 0, KeyGreen = 0, KeyBlue = 0, KeyAlpha = 0; - -ILvoid ILAPIENTRY ilKeyColour(ILclampf Red, ILclampf Green, ILclampf Blue, ILclampf Alpha) -{ - ILfloat KeyRed = 0, KeyGreen = 0, KeyBlue = 0, KeyAlpha = 0; - KeyRed = Red; - KeyGreen = Green; - KeyBlue = Blue; - KeyAlpha = Alpha; - return; -} - - -// Adds an alpha channel to an 8 or 24-bit image, -// making the image transparent where Key is equal to the pixel. -ILboolean ilAddAlphaKey(ILimage *Image) -{ - ILfloat KeyRed = 0, KeyGreen = 0, KeyBlue = 0, KeyAlpha = 0; - ILubyte *NewData, NewBpp; - ILfloat KeyColour[3]; - ILuint i = 0, j = 0, c, Size; - ILboolean Same; - - if (Image == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (Image->Format != IL_COLOUR_INDEX) { - if (Image->Bpp != 3) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - if (Image->Format == IL_BGR || Image->Format == IL_BGRA) { - KeyColour[0] = KeyBlue; - KeyColour[1] = KeyGreen; - KeyColour[2] = KeyRed; - } - else { - KeyColour[0] = KeyRed; - KeyColour[1] = KeyGreen; - KeyColour[2] = KeyBlue; - } - - Size = Image->Bps * Image->Height / Image->Bpc; - - NewBpp = (ILubyte)(Image->Bpp + 1); - - NewData = (ILubyte*)ialloc(NewBpp * Image->Bpc * Image->Width * Image->Height); - if (NewData == NULL) { - return IL_FALSE; - } - - switch (Image->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - for (; i < Size; i += Image->Bpp, j += NewBpp) { - NewData[j] = Image->Data[i]; - NewData[j+1] = Image->Data[i+1]; - NewData[j+2] = Image->Data[i+2]; - Same = IL_TRUE; - for (c = 0; c < Image->Bpp; c++) { - if (Image->Data[i+c] != KeyColour[c] * UCHAR_MAX) - Same = IL_FALSE; - } - - if (Same) - NewData[j+3] = 0; // Transparent - matches key colour - else - NewData[j+3] = UCHAR_MAX; - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - for (; i < Size; i += Image->Bpp, j += NewBpp) { - ((ILushort*)NewData)[j] = ((ILushort*)Image->Data)[i]; - ((ILushort*)NewData)[j+1] = ((ILushort*)Image->Data)[i+1]; - ((ILushort*)NewData)[j+2] = ((ILushort*)Image->Data)[i+2]; - Same = IL_TRUE; - for (c = 0; c < Image->Bpp; c++) { - if (((ILushort*)Image->Data)[i+c] != KeyColour[c] * USHRT_MAX) - Same = IL_FALSE; - } - - if (Same) - ((ILushort*)NewData)[j+3] = 0; - else - ((ILushort*)NewData)[j+3] = USHRT_MAX; - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - for (; i < Size; i += Image->Bpp, j += NewBpp) { - ((ILuint*)NewData)[j] = ((ILuint*)Image->Data)[i]; - ((ILuint*)NewData)[j+1] = ((ILuint*)Image->Data)[i+1]; - ((ILuint*)NewData)[j+2] = ((ILuint*)Image->Data)[i+2]; - Same = IL_TRUE; - for (c = 0; c < Image->Bpp; c++) { - if (((ILuint*)Image->Data)[i+c] != KeyColour[c] * UINT_MAX) - Same = IL_FALSE; - } - - if (Same) - ((ILuint*)NewData)[j+3] = 0; - else - ((ILuint*)NewData)[j+3] = UINT_MAX; - } - break; - - case IL_FLOAT: - for (; i < Size; i += Image->Bpp, j += NewBpp) { - ((ILfloat*)NewData)[j] = ((ILfloat*)Image->Data)[i]; - ((ILfloat*)NewData)[j+1] = ((ILfloat*)Image->Data)[i+1]; - ((ILfloat*)NewData)[j+2] = ((ILfloat*)Image->Data)[i+2]; - Same = IL_TRUE; - for (c = 0; c < Image->Bpp; c++) { - if (((ILfloat*)Image->Data)[i+c] != KeyColour[c]) - Same = IL_FALSE; - } - - if (Same) - ((ILfloat*)NewData)[j+3] = 0.0f; - else - ((ILfloat*)NewData)[j+3] = 1.0f; - } - break; - - case IL_DOUBLE: - for (; i < Size; i += Image->Bpp, j += NewBpp) { - ((ILdouble*)NewData)[j] = ((ILdouble*)Image->Data)[i]; - ((ILdouble*)NewData)[j+1] = ((ILdouble*)Image->Data)[i+1]; - ((ILdouble*)NewData)[j+2] = ((ILdouble*)Image->Data)[i+2]; - Same = IL_TRUE; - for (c = 0; c < Image->Bpp; c++) { - if (((ILdouble*)Image->Data)[i+c] != KeyColour[c]) - Same = IL_FALSE; - } - - if (Same) - ((ILdouble*)NewData)[j+3] = 0.0; - else - ((ILdouble*)NewData)[j+3] = 1.0; - } - break; - - default: - ifree(NewData); - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - - Image->Bpp = NewBpp; - Image->Bps = Image->Width * Image->Bpc * NewBpp; - Image->SizeOfPlane = Image->Bps * Image->Height; - Image->SizeOfData = Image->SizeOfPlane * Image->Depth; - ifree(Image->Data); - Image->Data = NewData; - - switch (Image->Format) - { - case IL_RGB: - Image->Format = IL_RGBA; - break; - case IL_BGR: - Image->Format = IL_BGRA; - break; - } - } - else { // IL_COLOUR_INDEX - if (Image->Bpp != 1) { - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - Size = ilGetInteger(IL_PALETTE_NUM_COLS); - if (Size == 0) { - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - if ((ILuint)(KeyAlpha * UCHAR_MAX) > Size) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - switch (Image->Pal.PalType) - { - case IL_PAL_RGB24: - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - if (!ilConvertPal(IL_PAL_RGBA32)) - return IL_FALSE; - break; - case IL_PAL_BGR24: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - if (!ilConvertPal(IL_PAL_BGRA32)) - return IL_FALSE; - break; - default: - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - // Set the colour index to be transparent. - Image->Pal.Palette[(ILuint)(KeyAlpha * UCHAR_MAX) * 4 + 3] = 0; - - // @TODO: Check if this is the required behaviour. - - if (Image->Pal.PalType == IL_PAL_RGBA32) - ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); - else - ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); - } - - return IL_TRUE; -} - - -// Removes alpha from a 32-bit image -// Should we maybe add an option that changes the image based on the alpha? -ILboolean ilRemoveAlpha() -{ - ILubyte *NewData, NewBpp; - ILuint i = 0, j = 0, Size; - - if (iCurImage == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (iCurImage->Bpp != 4) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - Size = iCurImage->Bps * iCurImage->Height; - NewBpp = (ILubyte)(iCurImage->Bpp - 1); - - NewData = (ILubyte*)ialloc(NewBpp * iCurImage->Bpc * iCurImage->Width * iCurImage->Height); - if (NewData == NULL) { - return IL_FALSE; - } - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - NewData[j] = iCurImage->Data[i]; - NewData[j+1] = iCurImage->Data[i+1]; - NewData[j+2] = iCurImage->Data[i+2]; - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILushort*)NewData)[j] = ((ILushort*)iCurImage->Data)[i]; - ((ILushort*)NewData)[j+1] = ((ILushort*)iCurImage->Data)[i+1]; - ((ILushort*)NewData)[j+2] = ((ILushort*)iCurImage->Data)[i+2]; - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILuint*)NewData)[j] = ((ILuint*)iCurImage->Data)[i]; - ((ILuint*)NewData)[j+1] = ((ILuint*)iCurImage->Data)[i+1]; - ((ILuint*)NewData)[j+2] = ((ILuint*)iCurImage->Data)[i+2]; - } - break; - - case IL_FLOAT: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILfloat*)NewData)[j] = ((ILfloat*)iCurImage->Data)[i]; - ((ILfloat*)NewData)[j+1] = ((ILfloat*)iCurImage->Data)[i+1]; - ((ILfloat*)NewData)[j+2] = ((ILfloat*)iCurImage->Data)[i+2]; - } - break; - - case IL_DOUBLE: - for (; i < Size; i += iCurImage->Bpp, j += NewBpp) { - ((ILdouble*)NewData)[j] = ((ILdouble*)iCurImage->Data)[i]; - ((ILdouble*)NewData)[j+1] = ((ILdouble*)iCurImage->Data)[i+1]; - ((ILdouble*)NewData)[j+2] = ((ILdouble*)iCurImage->Data)[i+2]; - } - break; - - default: - ifree(NewData); - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - - iCurImage->Bpp = NewBpp; - iCurImage->Bps = iCurImage->Width * iCurImage->Bpc * NewBpp; - iCurImage->SizeOfPlane = iCurImage->Bps * iCurImage->Height; - iCurImage->SizeOfData = iCurImage->SizeOfPlane * iCurImage->Depth; - ifree(iCurImage->Data); - iCurImage->Data = NewData; - - switch (iCurImage->Format) - { - case IL_RGBA: - iCurImage->Format = IL_RGB; - break; - case IL_BGRA: - iCurImage->Format = IL_BGR; - break; - } - - return IL_TRUE; -} - - -ILboolean ilFixCur() -{ - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - if (!ilFlipImage()) { - return IL_FALSE; - } - } - } - - if (ilIsEnabled(IL_TYPE_SET)) { - if ((ILenum)ilGetInteger(IL_TYPE_MODE) != iCurImage->Type) { - if (!ilConvertImage(iCurImage->Format, ilGetInteger(IL_TYPE_MODE))) { - return IL_FALSE; - } - } - } - if (ilIsEnabled(IL_FORMAT_SET)) { - if ((ILenum)ilGetInteger(IL_FORMAT_MODE) != iCurImage->Format) { - if (!ilConvertImage(ilGetInteger(IL_FORMAT_MODE), iCurImage->Type)) { - return IL_FALSE; - } - } - } - - if (iCurImage->Format == IL_COLOUR_INDEX) { - if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { - if (!ilConvertImage(IL_BGR, IL_UNSIGNED_BYTE)) { - return IL_FALSE; - } - } - } -/* Swap Colors on Big Endian !!!!! -#ifdef __BIG_ENDIAN__ - // Swap endian - EndianSwapData(iCurImage); -#endif -*/ - return IL_TRUE; -} - -/* -ILboolean ilFixImage() -{ - ILuint NumImages, i; - - NumImages = ilGetInteger(IL_NUM_IMAGES); - for (i = 0; i < NumImages; i++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveImage(i+1)) - return IL_FALSE; - if (!ilFixCur()) - return IL_FALSE; - } - - NumImages = ilGetInteger(IL_NUM_MIPMAPS); - for (i = 0; i < NumImages; i++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveMipmap(i+1)) - return IL_FALSE; - if (!ilFixCur()) - return IL_FALSE; - } - - NumImages = ilGetInteger(IL_NUM_LAYERS); - for (i = 0; i < NumImages; i++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveLayer(i+1)) - return IL_FALSE; - if (!ilFixCur()) - return IL_FALSE; - } - - ilBindImage(ilGetCurName()); - ilFixCur(); - - return IL_TRUE; -} -*/ - -/* -This function was replaced 20050304, because the previous version -didn't fix the mipmaps of the subimages etc. This version is not -completely correct either, because the subimages of the subimages -etc. are not fixed, but at the moment no images of this type can -be loaded anyway. Thanks to Chris Lux for pointing this out. -*/ - -ILboolean ilFixImage() -{ - ILuint NumImages, i; - ILuint NumMipmaps,j; - ILuint NumLayers, k; - - NumImages = ilGetInteger(IL_NUM_IMAGES); - for (i = 0; i <= NumImages; i++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveImage(i)) - return IL_FALSE; - - NumLayers = ilGetInteger(IL_NUM_LAYERS); - for (k = 0; k <= NumLayers; k++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveImage(i)) - return IL_FALSE; - if (!ilActiveLayer(k)) - return IL_FALSE; - - NumMipmaps = ilGetInteger(IL_NUM_MIPMAPS); - - for (j = 0; j <= NumMipmaps; j++) { - ilBindImage(ilGetCurName()); // Set to parent image first. - if (!ilActiveImage(i)) - return IL_FALSE; - if (!ilActiveLayer(k)) - return IL_FALSE; - if (!ilActiveMipmap(j)) - return IL_FALSE; - if (!ilFixCur()) - return IL_FALSE; - } - } - } - ilBindImage(ilGetCurName()); - - return IL_TRUE; -} diff --git a/win32/devil/src/il_cut.c b/win32/devil/src/il_cut.c deleted file mode 100644 index 83d1dc571..000000000 --- a/win32/devil/src/il_cut.c +++ /dev/null @@ -1,150 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 10/10/2006 -// -// Filename: src-IL/src/il_cut.c -// -// Description: Reads a Dr. Halo .cut file -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_CUT -#include "il_manip.h" -#include "il_pal.h" -#include "il_bits.h" - - -// Wrap it just in case... -#ifdef _MSC_VER -#pragma pack(push, packed_struct, 1) -#endif -typedef struct CUT_HEAD -{ - ILushort Width; - ILushort Height; - ILint Dummy; -} IL_PACKSTRUCT CUT_HEAD; -#ifdef _MSC_VER -#pragma pack(pop, packed_struct) -#endif - -ILboolean iLoadCutInternal(); - -//! Reads a .cut file -ILboolean ilLoadCut(ILconst_string FileName) -{ - ILHANDLE CutFile; - ILboolean bCut = IL_FALSE; - - CutFile = iopenr(FileName); - if (CutFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bCut; - } - - bCut = ilLoadCutF(CutFile); - icloser(CutFile); - - return bCut; -} - - -//! Reads an already-opened .cut file -ILboolean ilLoadCutF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadCutInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .cut -ILboolean ilLoadCutL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadCutInternal(); -} - - -// Note: .Cut support has not been tested yet! -// A .cut can only have 1 bpp. -// We need to add support for the .pal's PSP outputs with these... -ILboolean iLoadCutInternal() -{ - CUT_HEAD Header; - ILuint Size, i = 0, j; - ILubyte Count, Run; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Header.Width = GetLittleShort(); - Header.Height = GetLittleShort(); - Header.Dummy = GetLittleInt(); - - if (Header.Width == 0 || Header.Height == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { // always 1 bpp - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - Size = Header.Width * Header.Height; - - while (i < Size) { - Count = igetc(); - if (Count == 0) { // end of row - igetc(); // Not supposed to be here, but - igetc(); // PSP is putting these two bytes here...WHY?! - continue; - } - if (Count & BIT_7) { // rle-compressed - ClearBits(Count, BIT_7); - Run = igetc(); - for (j = 0; j < Count; j++) { - iCurImage->Data[i++] = Run; - } - } - else { // run of pixels - for (j = 0; j < Count; j++) { - iCurImage->Data[i++] = igetc(); - } - } - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Not sure - - /*iCurImage->Pal.Palette = SharedPal.Palette; - iCurImage->Pal.PalSize = SharedPal.PalSize; - iCurImage->Pal.PalType = SharedPal.PalType;*/ - - ilFixImage(); - - return IL_TRUE; -} - -/* ????????? -ILvoid ilPopToast() { - ILstring flipCode = IL_TEXT("#flipCode and www.flipCode.com rule you all."); - flipCode[0] = flipCode[0]; -} -*/ - - - -#endif//IL_NO_CUT diff --git a/win32/devil/src/il_dcx.c b/win32/devil/src/il_dcx.c deleted file mode 100644 index 84cdba0f1..000000000 --- a/win32/devil/src/il_dcx.c +++ /dev/null @@ -1,493 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/10/2006 -// -// Filename: src-IL/src/il_dcx.c -// -// Description: Reads from a .dcx file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_DCX -#include "il_dcx.h" -#include "il_manip.h" - - -//! Checks if the file specified in FileName is a valid .dcx file. -ILboolean ilIsValidDcx(ILconst_string FileName) { - ILHANDLE DcxFile; - ILboolean bDcx = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("dcx"))) { - ilSetError(IL_INVALID_EXTENSION); - return bDcx; - } - - DcxFile = iopenr(FileName); - if (DcxFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDcx; - } - - bDcx = ilIsValidDcxF(DcxFile); - icloser(DcxFile); - - return bDcx; -} - - -//! Checks if the ILHANDLE contains a valid .dcx file at the current position. -ILboolean ilIsValidDcxF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidDcx(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .dcx lump. -ILboolean ilIsValidDcxL(const ILvoid *Lump, ILuint Size) { - iSetInputLump(Lump, Size); - return iIsValidDcx(); -} - - -// Internal function obtain the .dcx header from the current file. -ILboolean iGetDcxHead(DCXHEAD *Head) { - Head->Xmin = GetLittleUShort(); - - Head->Ymin = GetLittleUShort(); - - Head->Xmax = GetLittleUShort(); - - Head->Ymax = GetLittleUShort(); - - Head->HDpi = GetLittleUShort(); - - Head->VDpi = GetLittleUShort(); - - Head->Bps = GetLittleUShort(); - - Head->PaletteInfo = GetLittleUShort(); - - Head->HScreenSize = GetLittleUShort(); - - Head->VScreenSize = GetLittleUShort(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidDcx() -{ - ILuint Signature; - - if (iread(&Signature, 1, 4) != 4) - return IL_FALSE; - iseek(-4, IL_SEEK_CUR); - - return (Signature == 987654321); -} - - -// Internal function used to check if the HEADER is a valid .dcx header. -// Should we also do a check on Header->Bpp? -ILboolean iCheckDcx(DCXHEAD *Header) -{ - ILuint Test, i; - - // There are other versions, but I am not supporting them as of yet. - // Got rid of the Reserved check, because I've seen some .dcx files with invalid values in it. - if (Header->Manufacturer != 10 || Header->Version != 5 || Header->Encoding != 1/* || Header->Reserved != 0*/) - return IL_FALSE; - - // See if the padding size is correct - Test = Header->Xmax - Header->Xmin + 1; - /*if (Header->Bpp >= 8) { - if (Test & 1) { - if (Header->Bps != Test + 1) - return IL_FALSE; - } - else { - if (Header->Bps != Test) // No padding - return IL_FALSE; - } - }*/ - - for (i = 0; i < 54; i++) { - if (Header->Filler[i] != 0) - return IL_FALSE; - } - - return IL_TRUE; -} - - -//! Reads a .dcx file -ILboolean ilLoadDcx(ILconst_string FileName) -{ - ILHANDLE DcxFile; - ILboolean bDcx = IL_FALSE; - - DcxFile = iopenr(FileName); - if (DcxFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDcx; - } - - bDcx = ilLoadDcxF(DcxFile); - icloser(DcxFile); - - return bDcx; -} - - -//! Reads an already-opened .dcx file -ILboolean ilLoadDcxF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadDcxInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .dcx -ILboolean ilLoadDcxL(const ILvoid *Lump, ILuint Size) { - iSetInputLump(Lump, Size); - return iLoadDcxInternal(); -} - - -// Internal function used to load the .dcx. -ILboolean iLoadDcxInternal() -{ - DCXHEAD Header; - ILuint Signature, i, Entries[1024], Num = 0; - ILimage *Image, *Base; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iIsValidDcx()) - return IL_FALSE; - iread(&Signature, 1, 4); - - do { - if (iread(&Entries[Num], 1, 4) != 4) - return IL_FALSE; - Num++; - } while (Entries[Num-1] != 0); - - for (i = 0; i < Num; i++) { - iseek(Entries[i], IL_SEEK_SET); - iGetDcxHead(&Header); - /*if (!iCheckDcx(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - }*/ - - Image = iUncompressDcx(&Header); - if (Image == NULL) - return IL_FALSE; - - if (i == 0) { - ilTexImage(Image->Width, Image->Height, 1, Image->Bpp, Image->Format, Image->Type, Image->Data); - Base = iCurImage; - Base->Origin = IL_ORIGIN_UPPER_LEFT; - ilCloseImage(Image); - } - else { - iCurImage->Next = Image; - iCurImage = iCurImage->Next; - } - } - - ilFixImage(); - - return IL_TRUE; -} - - -// Internal function to uncompress the .dcx (all .dcx files are rle compressed) -ILimage *iUncompressDcx(DCXHEAD *Header) -{ - ILubyte ByteHead, Colour, *ScanLine = NULL /* Only one plane */; - ILuint c, i, x, y;//, Read = 0; - ILimage *Image = NULL; - - if (Header->Bpp < 8) { - /*ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE;*/ - return iUncompressDcxSmall(Header); - } - - Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1); - if (Image == NULL) - return NULL; - /*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - }*/ - Image->Origin = IL_ORIGIN_UPPER_LEFT; - - ScanLine = (ILubyte*)ialloc(Header->Bps); - if (ScanLine == NULL) - goto dcx_error; - - switch (Image->Bpp) - { - case 1: - Image->Format = IL_COLOUR_INDEX; - Image->Pal.PalType = IL_PAL_RGB24; - Image->Pal.PalSize = 256 * 3; // Need to find out for sure... - Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize); - if (Image->Pal.Palette == NULL) - goto dcx_error; - break; - //case 2: // No 16-bit images in the dcx format! - case 3: - Image->Format = IL_RGB; - Image->Pal.Palette = NULL; - Image->Pal.PalSize = 0; - Image->Pal.PalType = IL_PAL_NONE; - break; - case 4: - Image->Format = IL_RGBA; - Image->Pal.Palette = NULL; - Image->Pal.PalSize = 0; - Image->Pal.PalType = IL_PAL_NONE; - break; - - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - goto dcx_error; - } - - - /*StartPos = itell(); - Compressed = (ILubyte*)ialloc(Image->SizeOfData * 4 / 3); - iread(Compressed, 1, Image->SizeOfData * 4 / 3); - - for (y = 0; y < Image->Height; y++) { - for (c = 0; c < Image->Bpp; c++) { - x = 0; - while (x < Header->Bps) { - ByteHead = Compressed[Read++]; - if ((ByteHead & 0xC0) == 0xC0) { - ByteHead &= 0x3F; - Colour = Compressed[Read++]; - for (i = 0; i < ByteHead; i++) { - ScanLine[x++] = Colour; - } - } - else { - ScanLine[x++] = ByteHead; - } - } - - for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;) - Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x]; - } - } - } - - ifree(Compressed); - iseek(StartPos + Read, IL_SEEK_SET);*/ - - //changed 2003-09-01 - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->SizeOfData); - - //TODO: because the .pcx-code was broken this - //code is probably broken, too - for (y = 0; y < Image->Height; y++) { - for (c = 0; c < Image->Bpp; c++) { - x = 0; - while (x < Header->Bps) { - if (iread(&ByteHead, 1, 1) != 1) { - iUnCache(); - goto dcx_error; - } - if ((ByteHead & 0xC0) == 0xC0) { - ByteHead &= 0x3F; - if (iread(&Colour, 1, 1) != 1) { - iUnCache(); - goto dcx_error; - } - for (i = 0; i < ByteHead; i++) { - ScanLine[x++] = Colour; - } - } - else { - ScanLine[x++] = ByteHead; - } - } - - for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;) - Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x]; - } - } - } - - iUnCache(); - - - ifree(ScanLine); - - // Read in the palette - if (Image->Bpp == 1) { - ByteHead = igetc(); // the value 12, because it signals there's a palette for some reason... - // We should do a check to make certain it's 12... - if (ByteHead != 12) - iseek(-1, IL_SEEK_CUR); - if (iread(Image->Pal.Palette, 1, Image->Pal.PalSize) != Image->Pal.PalSize) { - ilCloseImage(Image); - return NULL; - } - } - - return Image; - -dcx_error: - ifree(ScanLine); - ilCloseImage(Image); - return NULL; -} - - -ILimage *iUncompressDcxSmall(DCXHEAD *Header) -{ - ILuint i = 0, j, k, c, d, x, y, Bps; - ILubyte HeadByte, Colour, Data = 0, *ScanLine = NULL; - ILimage *Image; - - Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1); - if (Image == NULL) - return NULL; - - /*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - }*/ - Image->Origin = IL_ORIGIN_UPPER_LEFT; - - switch (Header->NumPlanes) - { - case 1: - Image->Format = IL_LUMINANCE; - break; - case 4: - Image->Format = IL_COLOUR_INDEX; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - ilCloseImage(Image); - return NULL; - } - - if (Header->NumPlanes == 1) { - for (j = 0; j < Image->Height; j++) { - i = 0; - while (i < Image->Width) { - if (iread(&HeadByte, 1, 1) != 1) - goto file_read_error; - if (HeadByte >= 192) { - HeadByte -= 192; - if (iread(&Data, 1, 1) != 1) - goto file_read_error; - - for (c = 0; c < HeadByte; c++) { - k = 128; - for (d = 0; d < 8 && i < Image->Width; d++) { - Image->Data[j * Image->Width + i++] = (!!(Data & k) == 1 ? 255 : 0); - k >>= 1; - } - } - } - else { - k = 128; - for (c = 0; c < 8 && i < Image->Width; c++) { - Image->Data[j * Image->Width + i++] = (!!(HeadByte & k) == 1 ? 255 : 0); - k >>= 1; - } - } - } - if (Data != 0) - igetc(); // Skip pad byte if last byte not a 0 - } - } - else { // 4-bit images - Bps = Header->Bps * Header->NumPlanes * 2; - Image->Pal.Palette = (ILubyte*)ialloc(16 * 3); // Size of palette always (48 bytes). - Image->Pal.PalSize = 16 * 3; - Image->Pal.PalType = IL_PAL_RGB24; - ScanLine = (ILubyte*)ialloc(Bps); - if (Image->Pal.Palette == NULL || ScanLine == NULL) { - ifree(ScanLine); - ilCloseImage(Image); - return NULL; - } - - memcpy(Image->Pal.Palette, Header->ColMap, 16 * 3); - imemclear(Image->Data, Image->SizeOfData); // Since we do a += later. - - for (y = 0; y < Image->Height; y++) { - for (c = 0; c < Header->NumPlanes; c++) { - x = 0; - while (x < Bps) { - if (iread(&HeadByte, 1, 1) != 1) - goto file_read_error; - if ((HeadByte & 0xC0) == 0xC0) { - HeadByte &= 0x3F; - if (iread(&Colour, 1, 1) != 1) - goto file_read_error; - for (i = 0; i < HeadByte; i++) { - k = 128; - for (j = 0; j < 8; j++) { - ScanLine[x++] = !!(Colour & k); - k >>= 1; - } - } - } - else { - k = 128; - for (j = 0; j < 8; j++) { - ScanLine[x++] = !!(HeadByte & k); - k >>= 1; - } - } - } - - for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes. ;) - Image->Data[y * Image->Width + x] += ScanLine[x] << c; - } - } - } - ifree(ScanLine); - } - - return Image; - -file_read_error: - ifree(ScanLine); - ilCloseImage(Image); - return NULL; -} - -#endif//IL_NO_DCX diff --git a/win32/devil/src/il_dds-save.c b/win32/devil/src/il_dds-save.c deleted file mode 100644 index ace221f44..000000000 --- a/win32/devil/src/il_dds-save.c +++ /dev/null @@ -1,1296 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 12/06/2006 -// -// Filename: src-IL/src/il_dds-save.c -// -// Description: Saves a DirectDraw Surface (.dds) file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_dds.h" -#include "il_manip.h" -#include - - -#ifndef IL_NO_DDS - -//! Writes a Dds file -ILboolean ilSaveDds(ILconst_string FileName) { - ILHANDLE DdsFile; - ILboolean bDds = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - DdsFile = iopenw(FileName); - if (DdsFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDds; - } - - bDds = ilSaveDdsF(DdsFile); - iclosew(DdsFile); - - return bDds; -} - - -//! Writes a Dds to an already-opened file -ILboolean ilSaveDdsF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSaveDdsInternal(); -} - - -//! Writes a Dds to a memory "lump" -ILboolean ilSaveDdsL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveDdsInternal(); -} - - - - - -//! Checks if an image is a cubemap - -ILuint GetCubemapInfo(ILimage* image, ILint* faces) - -{ - - ILint indices[] = { -1, -1, -1, -1, -1, -1 }, i; - - ILimage* img; - - ILuint ret = 0, srcMipmapCount, srcImagesCount, mipmapCount; - - - - if (image == NULL) - - return 0; - - - iGetIntegervImage(image, IL_NUM_IMAGES, (ILint*) &srcImagesCount ); - - if (srcImagesCount != 5) //write only complete cubemaps (TODO?) - - return 0; - - - - img = image; - iGetIntegervImage(image, IL_NUM_MIPMAPS, (ILint*) &srcMipmapCount ); - - mipmapCount = srcMipmapCount; - - for (i = 0; i < 6; ++i) { - - switch(img->CubeFlags) - - { - - case DDS_CUBEMAP_POSITIVEX: - - indices[i] = 0; - - break; - - case DDS_CUBEMAP_NEGATIVEX: - - indices[i] = 1; - - break; - - case DDS_CUBEMAP_POSITIVEY: - - indices[i] = 2; - - break; - - case DDS_CUBEMAP_NEGATIVEY: - - indices[i] = 3; - - break; - - case DDS_CUBEMAP_POSITIVEZ: - - indices[i] = 4; - - break; - - case DDS_CUBEMAP_NEGATIVEZ: - - indices[i] = 5; - - break; - - } - - iGetIntegervImage(img, IL_NUM_MIPMAPS, (ILint*) &srcMipmapCount ); - - if (srcMipmapCount != mipmapCount) - - return 0; //equal # of mipmaps required - - - - ret |= img->CubeFlags; - - img = img->Next; - - } - - - - for (i = 0; i < 6; ++i) - - if (indices[i] == -1) - - return 0; //one face not found - - - - if (ret != 0) //should always be true - - ret |= DDS_CUBEMAP; - - - - - - for (i =0; i < 6; ++i) - - faces[indices[i]] = i; - - - - return ret; - -} - - -// Internal function used to save the Dds. -ILboolean iSaveDdsInternal() -{ - ILenum DXTCFormat; - ILuint counter, numMipMaps, image, numFaces, i; - ILubyte *CurData = NULL; - - ILint CubeTable[6] = { 0 }; - - ILuint CubeFlags; - - CubeFlags = GetCubemapInfo(iCurImage, CubeTable); - - - image = ilGetInteger(IL_CUR_IMAGE); - DXTCFormat = iGetInt(IL_DXTC_FORMAT); - WriteHeader(iCurImage, DXTCFormat, CubeFlags); - - - if (CubeFlags != 0) - - numFaces = ilGetInteger(IL_NUM_IMAGES); //should always be 5 for now - - else - - numFaces = 0; - - - numMipMaps = ilGetInteger(IL_NUM_MIPMAPS); //this assumes all faces have same # of mipmaps - - - - for (i = 0; i <= numFaces; ++i) { - for (counter = 0; counter <= numMipMaps; counter++) { - ilBindImage(image); - - ilActiveImage(CubeTable[i]); - - ilActiveMipmap(counter); - - if (iCurImage->Origin != IL_ORIGIN_UPPER_LEFT) { - CurData = iCurImage->Data; - iCurImage->Data = iGetFlipped(iCurImage); - if (iCurImage->Data == NULL) { - iCurImage->Data = CurData; - return IL_FALSE; - } - } - - if (!Compress(iCurImage, DXTCFormat)) - return IL_FALSE; - - if (iCurImage->Origin != IL_ORIGIN_UPPER_LEFT) { - ifree(iCurImage->Data); - iCurImage->Data = CurData; - } - } - - } - - return IL_TRUE; -} - - -// @TODO: Finish this, as it is incomplete. -ILboolean WriteHeader(ILimage *Image, ILenum DXTCFormat, ILuint CubeFlags) -{ - ILuint i, FourCC, Flags1 = 0, Flags2 = 0, ddsCaps1 = 0, - - LinearSize, BlockSize, ddsCaps2 = 0; - - Flags1 |= DDS_LINEARSIZE | DDS_MIPMAPCOUNT - | DDS_WIDTH | DDS_HEIGHT | DDS_CAPS | DDS_PIXELFORMAT; - Flags2 |= DDS_FOURCC; - - - - if (Image->Depth > 1) - - Flags1 |= DDS_DEPTH; - - // @TODO: Fix the pre-multiplied alpha problem. - if (DXTCFormat == IL_DXT2) - DXTCFormat = IL_DXT3; - else if (DXTCFormat == IL_DXT4) - DXTCFormat = IL_DXT5; - - switch (DXTCFormat) - { - case IL_DXT1: - FourCC = IL_MAKEFOURCC('D','X','T','1'); - break; - case IL_DXT2: - FourCC = IL_MAKEFOURCC('D','X','T','2'); - break; - case IL_DXT3: - FourCC = IL_MAKEFOURCC('D','X','T','3'); - break; - case IL_DXT4: - FourCC = IL_MAKEFOURCC('D','X','T','4'); - break; - case IL_DXT5: - FourCC = IL_MAKEFOURCC('D','X','T','5'); - break; - - case IL_ATI1N: - - FourCC = IL_MAKEFOURCC('A', 'T', 'I', '1'); - - break; - - - case IL_3DC: - FourCC = IL_MAKEFOURCC('A','T','I','2'); - break; - case IL_RXGB: - FourCC = IL_MAKEFOURCC('R','X','G','B'); - break; - default: - // Error! - ilSetError(IL_INTERNAL_ERROR); // Should never happen, though. - return IL_FALSE; - } - - iwrite("DDS ", 1, 4); - SaveLittleUInt(124); // Size1 - SaveLittleUInt(Flags1); // Flags1 - SaveLittleUInt(Image->Height); - SaveLittleUInt(Image->Width); - - if (DXTCFormat == IL_DXT1 || DXTCFormat == IL_ATI1N) { - - BlockSize = 8; - } - else { - - BlockSize = 16; - } - - LinearSize = (((Image->Width + 3)/4) * ((Image->Height + 3)/4)) * BlockSize * Image->Depth; - - - - /* - - // doing this is actually wrong, linear size is only size of one cube face - - if (CubeFlags != 0) { - - ILint numFaces = 0; - - for (i = 0; i < 6; ++i) - - if (CubeFlags & CubemapDirections[i]) - - ++numFaces; - - - - LinearSize *= numFaces; - - } - - */ - - - - - SaveLittleUInt(LinearSize); // LinearSize (TODO: change this when uncompressed formats are supported) - - if (Image->Depth > 1) { - SaveLittleUInt(Image->Depth); // Depth - - ddsCaps2 |= DDS_VOLUME; - - } - - else - - SaveLittleUInt(0); // Depth - SaveLittleUInt(ilGetInteger(IL_NUM_MIPMAPS) + 1); // MipMapCount - SaveLittleUInt(0); // AlphaBitDepth - - for (i = 0; i < 10; i++) - SaveLittleUInt(0); // Not used - - SaveLittleUInt(32); // Size2 - SaveLittleUInt(Flags2); // Flags2 - SaveLittleUInt(FourCC); // FourCC - SaveLittleUInt(0); // RGBBitCount - SaveLittleUInt(0); // RBitMask - SaveLittleUInt(0); // GBitMask - SaveLittleUInt(0); // BBitMask - SaveLittleUInt(0); // RGBAlphaBitMask - ddsCaps1 |= DDS_TEXTURE; - //changed 20040516: set mipmap flag on mipmap images - //(non-compressed .dds files still not supported, - //though) - if (ilGetInteger(IL_NUM_MIPMAPS) > 0) - ddsCaps1 |= DDS_MIPMAP | DDS_COMPLEX; - if (CubeFlags != 0) { - - ddsCaps1 |= DDS_COMPLEX; - - ddsCaps2 |= CubeFlags; - - } - - SaveLittleUInt(ddsCaps1); // ddsCaps1 - - SaveLittleUInt(ddsCaps2); // ddsCaps2 - SaveLittleUInt(0); // ddsCaps3 - SaveLittleUInt(0); // ddsCaps4 - SaveLittleUInt(0); // TextureStage - - return IL_TRUE; -} - -#endif//IL_NO_DDS - - -ILuint ILAPIENTRY ilGetDXTCData(ILvoid *Buffer, ILuint BufferSize, ILenum DXTCFormat) -{ - ILubyte *CurData = NULL; - ILuint retVal; - - ILint BlockNum; - - if (Buffer == NULL) { // Return the number that will be written with a subsequent call. - - BlockNum = ((iCurImage->Width + 3)/4) * ((iCurImage->Height + 3)/4) - - * iCurImage->Depth; - - - switch (DXTCFormat) - { - case IL_DXT1: - - case IL_ATI1N: - return BlockNum * 8; - case IL_DXT3: - case IL_DXT5: - case IL_3DC: - case IL_RXGB: - return BlockNum * 16; - default: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return 0; - } - } - - if (DXTCFormat == iCurImage->DxtcFormat && iCurImage->DxtcSize && iCurImage->DxtcData) { - memcpy(Buffer, iCurImage->DxtcData, IL_MIN(BufferSize, iCurImage->DxtcSize)); - return IL_MIN(BufferSize, iCurImage->DxtcSize); - } - - if (iCurImage->Origin != IL_ORIGIN_UPPER_LEFT) { - CurData = iCurImage->Data; - iCurImage->Data = iGetFlipped(iCurImage); - if (iCurImage->Data == NULL) { - iCurImage->Data = CurData; - return 0; - } - ifree(CurData); - } - - iSetOutputLump(Buffer, BufferSize); - retVal = Compress(iCurImage, DXTCFormat); - - if (iCurImage->Origin != IL_ORIGIN_UPPER_LEFT) { - ifree(iCurImage->Data); - iCurImage->Data = CurData; - } - - return retVal; -} - - -ILushort *CompressTo565(ILimage *Image) -{ - ILimage *TempImage; - ILushort *Data; - ILuint i, j; - - if ((Image->Type != IL_UNSIGNED_BYTE && Image->Type != IL_BYTE) || Image->Format == IL_COLOUR_INDEX) { - TempImage = iConvertImage(iCurImage, IL_BGR, IL_UNSIGNED_BYTE); // @TODO: Needs to be BGRA. - if (TempImage == NULL) - return NULL; - } - else { - TempImage = Image; - } - - Data = (ILushort*)ialloc(iCurImage->Width * iCurImage->Height * 2 * iCurImage->Depth); - if (Data == NULL) { - if (TempImage != Image) - ilCloseImage(TempImage); - return NULL; - } - - //changed 20040623: Use TempImages format :) - switch (TempImage->Format) - { - case IL_RGB: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j++) { - Data[j] = (TempImage->Data[i ] >> 3) << 11; - Data[j] |= (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i+2] >> 3; - } - break; - - case IL_RGBA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j++) { - Data[j] = (TempImage->Data[i ] >> 3) << 11; - Data[j] |= (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i+2] >> 3; - } - break; - - case IL_BGR: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j++) { - Data[j] = (TempImage->Data[i+2] >> 3) << 11; - Data[j] |= (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i ] >> 3; - } - break; - - case IL_BGRA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j++) { - Data[j] = (TempImage->Data[i+2] >> 3) << 11; - Data[j] |= (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i ] >> 3; - } - break; - - case IL_LUMINANCE: - for (i = 0, j = 0; i < TempImage->SizeOfData; i++, j++) { - Data[j] = (TempImage->Data[i] >> 3) << 11; - Data[j] |= (TempImage->Data[i] >> 2) << 5; - Data[j] |= TempImage->Data[i] >> 3; - } - break; - - case IL_LUMINANCE_ALPHA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 2, j++) { - Data[j] = (TempImage->Data[i] >> 3) << 11; - Data[j] |= (TempImage->Data[i] >> 2) << 5; - Data[j] |= TempImage->Data[i] >> 3; - } - break; - } - - if (TempImage != Image) - ilCloseImage(TempImage); - - return Data; -} - - -ILubyte *CompressTo88(ILimage *Image) -{ - ILimage *TempImage; - ILubyte *Data; - ILuint i, j; - - if ((Image->Type != IL_UNSIGNED_BYTE && Image->Type != IL_BYTE) || Image->Format == IL_COLOUR_INDEX) { - TempImage = iConvertImage(iCurImage, IL_BGR, IL_UNSIGNED_BYTE); // @TODO: Needs to be BGRA. - if (TempImage == NULL) - return NULL; - } - else { - TempImage = Image; - } - - Data = (ILubyte*)ialloc(iCurImage->Width * iCurImage->Height * 2 * iCurImage->Depth); - if (Data == NULL) { - if (TempImage != Image) - ilCloseImage(TempImage); - return NULL; - } - - //changed 20040623: Use TempImages format :) - switch (TempImage->Format) - { - case IL_RGB: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j += 2) { - Data[j ] = TempImage->Data[i+1]; - Data[j+1] = TempImage->Data[i ]; - } - break; - - case IL_RGBA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j += 2) { - Data[j ] = TempImage->Data[i+1]; - Data[j+1] = TempImage->Data[i ]; - } - break; - - case IL_BGR: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j += 2) { - Data[j ] = TempImage->Data[i+1]; - Data[j+1] = TempImage->Data[i+2]; - } - break; - - case IL_BGRA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j += 2) { - Data[j ] = TempImage->Data[i+1]; - Data[j+1] = TempImage->Data[i+2]; - } - break; - - case IL_LUMINANCE: - case IL_LUMINANCE_ALPHA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i++, j += 2) { - Data[j ] = Data[j+1] = 0; //??? Luminance is no normal map format... - } - break; - } - - if (TempImage != Image) - ilCloseImage(TempImage); - - return Data; -} - -void CompressToRXGB(ILimage *Image, ILushort** xgb, ILubyte** r) -{ - ILimage *TempImage; - ILuint i, j; - ILushort *Data; - ILubyte *Alpha; - - *xgb = NULL; - *r = NULL; - - if ((Image->Type != IL_UNSIGNED_BYTE && Image->Type != IL_BYTE) || Image->Format == IL_COLOUR_INDEX) { - TempImage = iConvertImage(iCurImage, IL_BGR, IL_UNSIGNED_BYTE); // @TODO: Needs to be BGRA. - if (TempImage == NULL) - return; - } - else { - TempImage = Image; - } - - *xgb = (ILushort*)ialloc(iCurImage->Width * iCurImage->Height * 2 * iCurImage->Depth); - *r = (ILubyte*)ialloc(iCurImage->Width * iCurImage->Height * iCurImage->Depth); - if (*xgb == NULL || *r == NULL) { - if (TempImage != Image) - ilCloseImage(TempImage); - return; - } - - //Alias pointers to be able to use copy'n'pasted code :) - Data = *xgb; - Alpha = *r; - - switch (TempImage->Format) - { - case IL_RGB: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j++) { - Alpha[j] = TempImage->Data[i]; - Data[j] = (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i+2] >> 3; - } - break; - - case IL_RGBA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j++) { - Alpha[j] = TempImage->Data[i]; - Data[j] = (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i+2] >> 3; - } - break; - - case IL_BGR: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 3, j++) { - Alpha[j] = TempImage->Data[i+2]; - Data[j] = (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i ] >> 3; - } - break; - - case IL_BGRA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 4, j++) { - Alpha[j] = TempImage->Data[i+2]; - Data[j] = (TempImage->Data[i+1] >> 2) << 5; - Data[j] |= TempImage->Data[i ] >> 3; - } - break; - - case IL_LUMINANCE: - for (i = 0, j = 0; i < TempImage->SizeOfData; i++, j++) { - Alpha[j] = TempImage->Data[i]; - Data[j] = (TempImage->Data[i] >> 2) << 5; - Data[j] |= TempImage->Data[i] >> 3; - } - break; - - case IL_LUMINANCE_ALPHA: - for (i = 0, j = 0; i < TempImage->SizeOfData; i += 2, j++) { - Alpha[j] = TempImage->Data[i]; - Data[j] = (TempImage->Data[i] >> 2) << 5; - Data[j] |= TempImage->Data[i] >> 3; - } - break; - } - - if (TempImage != Image) - ilCloseImage(TempImage); -} - - -ILuint Compress(ILimage *Image, ILenum DXTCFormat) -{ - ILushort *Data, Block[16], ex0, ex1, *Runner16, t0, t1; - ILuint x, y, z, i, BitMask;//, Rms1, Rms2; - ILubyte *Alpha, AlphaBlock[16], AlphaBitMask[6], /*AlphaOut[16],*/ a0, a1; - ILboolean HasAlpha; - ILuint Count = 0; - ILubyte *Data3Dc, *Runner8; - - if (DXTCFormat == IL_3DC) { - Data3Dc = CompressTo88(Image); - if (Data3Dc == NULL) - return 0; - - - Runner8 = Data3Dc; - - - - for (z = 0; z < Image->Depth; z++) { - for (y = 0; y < Image->Height; y += 4) { - for (x = 0; x < Image->Width; x += 4) { - Get3DcBlock(AlphaBlock, Runner8, Image, x, y, 0); - ChooseAlphaEndpoints(AlphaBlock, &a0, &a1); - GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL); - iputc(a0); - iputc(a1); - iwrite(AlphaBitMask, 1, 6); - - Get3DcBlock(AlphaBlock, Runner8, Image, x, y, 1); - ChooseAlphaEndpoints(AlphaBlock, &a0, &a1); - GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL); - iputc(a0); - iputc(a1); - iwrite(AlphaBitMask, 1, 6); - - Count += 16; - } - } - - Runner8 += Image->Width * Image->Height * 2; - - } - - ifree(Data3Dc); - } - - else if(DXTCFormat == IL_ATI1N) - - { - - ILimage *TempImage; - - - - if (Image->Bpp != 1) { - - TempImage = iConvertImage(iCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE); - - if (TempImage == NULL) - - return 0; - - } - - else { - - TempImage = Image; - - } - - - - Runner8 = TempImage->Data; - - - - for (z = 0; z < Image->Depth; z++) { - - for (y = 0; y < Image->Height; y += 4) { - - for (x = 0; x < Image->Width; x += 4) { - - GetAlphaBlock(AlphaBlock, Runner8, Image, x, y); - - ChooseAlphaEndpoints(AlphaBlock, &a0, &a1); - - GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL); - - iputc(a0); - - iputc(a1); - - iwrite(AlphaBitMask, 1, 6); - - Count += 8; - - } - - } - - Runner8 += Image->Width * Image->Height; - - } - - - - if (TempImage != Image) - - ilCloseImage(TempImage); - - } - else - { - if (DXTCFormat != IL_RXGB) { - Data = CompressTo565(Image); - if (Data == NULL) - return 0; - - Alpha = ilGetAlpha(IL_UNSIGNED_BYTE); - if (Alpha == NULL) { - ifree(Data); - return 0; - } - } - else { - CompressToRXGB(Image, &Data, &Alpha); - if (Data == NULL || Alpha == NULL) { - if (Data != NULL) - ifree(Data); - if (Alpha != NULL) - ifree(Alpha); - return 0; - } - } - - - - Runner8 = Alpha; - - Runner16 = Data; - - switch (DXTCFormat) - { - case IL_DXT1: - - for (z = 0; z < Image->Depth; z++) { - for (y = 0; y < Image->Height; y += 4) { - for (x = 0; x < Image->Width; x += 4) { - GetAlphaBlock(AlphaBlock, Runner8, Image, x, y); - HasAlpha = IL_FALSE; - for (i = 0 ; i < 16; i++) { - if (AlphaBlock[i] < 128) { - HasAlpha = IL_TRUE; - break; - } - } - - GetBlock(Block, Runner16, Image, x, y); - ChooseEndpoints(Block, &ex0, &ex1); - CorrectEndDXT1(&ex0, &ex1, HasAlpha); - SaveLittleUShort(ex0); - SaveLittleUShort(ex1); - if (HasAlpha) - BitMask = GenBitMask(ex0, ex1, 3, Block, AlphaBlock, NULL); - else - BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL); - SaveLittleUInt(BitMask); - Count += 8; - } - } - - - - Runner16 += Image->Width * Image->Height; - - Runner8 += Image->Width * Image->Height; - - } - break; - - /*case IL_DXT2: - for (y = 0; y < Image->Height; y += 4) { - for (x = 0; x < Image->Width; x += 4) { - GetAlphaBlock(AlphaBlock, Alpha, Image, x, y); - for (i = 0; i < 16; i += 2) { - iputc((ILubyte)(((AlphaBlock[i] >> 4) << 4) | (AlphaBlock[i+1] >> 4))); - } - - GetBlock(Block, Data, Image, x, y); - PreMult(Block, AlphaBlock); - ChooseEndpoints(Block, &ex0, &ex1); - SaveLittleUShort(ex0); - SaveLittleUShort(ex1); - BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL); - SaveLittleUInt(BitMask); - } - } - break;*/ - - case IL_DXT3: - - for (z = 0; z < Image->Depth; z++) { - for (y = 0; y < Image->Height; y += 4) { - for (x = 0; x < Image->Width; x += 4) { - GetAlphaBlock(AlphaBlock, Runner8, Image, x, y); - for (i = 0; i < 16; i += 2) { - iputc((ILubyte)(((AlphaBlock[i+1] >> 4) << 4) | (AlphaBlock[i] >> 4))); - } - - GetBlock(Block, Runner16, Image, x, y); - ChooseEndpoints(Block, &t0, &t1); - ex0 = IL_MAX(t0, t1); - ex1 = IL_MIN(t0, t1); - CorrectEndDXT1(&ex0, &ex1, 0); - SaveLittleUShort(ex0); - SaveLittleUShort(ex1); - BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL); - SaveLittleUInt(BitMask); - Count += 16; - } - } - - - - Runner16 += Image->Width * Image->Height; - - Runner8 += Image->Width * Image->Height; - - } - break; - - case IL_RXGB: - case IL_DXT5: - - for (z = 0; z < Image->Depth; z++) { - for (y = 0; y < Image->Height; y += 4) { - for (x = 0; x < Image->Width; x += 4) { - GetAlphaBlock(AlphaBlock, Runner8, Image, x, y); - ChooseAlphaEndpoints(AlphaBlock, &a0, &a1); - GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL/*AlphaOut*/); - /*Rms2 = RMSAlpha(AlphaBlock, AlphaOut); - GenAlphaBitMask(a0, a1, 8, AlphaBlock, AlphaBitMask, AlphaOut); - Rms1 = RMSAlpha(AlphaBlock, AlphaOut); - if (Rms2 <= Rms1) { // Yeah, we have to regenerate... - GenAlphaBitMask(a0, a1, 6, AlphaBlock, AlphaBitMask, AlphaOut); - Rms2 = a1; // Just reuse Rms2 as a temporary variable... - a1 = a0; - a0 = Rms2; - }*/ - iputc(a0); - iputc(a1); - iwrite(AlphaBitMask, 1, 6); - - GetBlock(Block, Runner16, Image, x, y); - ChooseEndpoints(Block, &t0, &t1); - ex0 = IL_MAX(t0, t1); - ex1 = IL_MIN(t0, t1); - CorrectEndDXT1(&ex0, &ex1, 0); - SaveLittleUShort(ex0); - SaveLittleUShort(ex1); - BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL); - SaveLittleUInt(BitMask); - Count += 16; - } - } - - - - Runner16 += Image->Width * Image->Height; - - Runner8 += Image->Width * Image->Height; - - } - break; - } - - ifree(Data); - ifree(Alpha); - } //else no 3dc - - return Count; -} - - -// Assumed to be 16-bit (5:6:5). -ILboolean GetBlock(ILushort *Block, ILushort *Data, ILimage *Image, ILuint XPos, ILuint YPos) -{ - ILuint x, y, i = 0, Offset = YPos * Image->Width + XPos; - - for (y = 0; y < 4; y++) { - for (x = 0; x < 4; x++) { - if (x < Image->Width && y < Image->Height) - Block[i++] = Data[Offset + x]; - else - Block[i++] = Data[Offset]; - } - Offset += Image->Width; - } - - return IL_TRUE; -} - - -ILboolean GetAlphaBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos) -{ - ILuint x, y, i = 0, Offset = YPos * Image->Width + XPos; - - for (y = 0; y < 4; y++) { - for (x = 0; x < 4; x++) { - if (x < Image->Width && y < Image->Height) - Block[i++] = Data[Offset + x]; - else - Block[i++] = Data[Offset]; - } - Offset += Image->Width; - } - - return IL_TRUE; -} - -ILboolean Get3DcBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos, int channel) -{ - ILuint x, y, i = 0, Offset = 2*(YPos * Image->Width + XPos) + channel; - - for (y = 0; y < 4; y++) { - for (x = 0; x < 4; x++) { - if (x < Image->Width && y < Image->Height) - Block[i++] = Data[Offset + 2*x]; - else - Block[i++] = Data[Offset]; - } - Offset += 2*Image->Width; - } - - return IL_TRUE; -} - - -ILvoid ShortToColor565(ILushort Pixel, Color565 *Colour) -{ - Colour->nRed = (Pixel & 0xF800) >> 11; - Colour->nGreen = (Pixel & 0x07E0) >> 5; - Colour->nBlue = (Pixel & 0x001F); - return; -} - - -ILvoid ShortToColor888(ILushort Pixel, Color888 *Colour) -{ - Colour->r = ((Pixel & 0xF800) >> 11) << 3; - Colour->g = ((Pixel & 0x07E0) >> 5) << 2; - Colour->b = ((Pixel & 0x001F)) << 3; - return; -} - - -ILushort Color565ToShort(Color565 *Colour) -{ - return (Colour->nRed << 11) | (Colour->nGreen << 5) | (Colour->nBlue); -} - - -ILushort Color888ToShort(Color888 *Colour) -{ - return ((Colour->r >> 3) << 11) | ((Colour->g >> 2) << 5) | (Colour->b >> 3); -} - - -ILuint GenBitMask(ILushort ex0, ILushort ex1, ILuint NumCols, ILushort *In, ILubyte *Alpha, Color888 *OutCol) -{ - ILuint i, j, Closest, Dist, BitMask = 0; - ILubyte Mask[16]; - Color888 c, Colours[4]; - - ShortToColor888(ex0, &Colours[0]); - ShortToColor888(ex1, &Colours[1]); - if (NumCols == 3) { - Colours[2].r = (Colours[0].r + Colours[1].r) / 2; - Colours[2].g = (Colours[0].g + Colours[1].g) / 2; - Colours[2].b = (Colours[0].b + Colours[1].b) / 2; - Colours[3].r = (Colours[0].r + Colours[1].r) / 2; - Colours[3].g = (Colours[0].g + Colours[1].g) / 2; - Colours[3].b = (Colours[0].b + Colours[1].b) / 2; - } - else { // NumCols == 4 - Colours[2].r = (2 * Colours[0].r + Colours[1].r + 1) / 3; - Colours[2].g = (2 * Colours[0].g + Colours[1].g + 1) / 3; - Colours[2].b = (2 * Colours[0].b + Colours[1].b + 1) / 3; - Colours[3].r = (Colours[0].r + 2 * Colours[1].r + 1) / 3; - Colours[3].g = (Colours[0].g + 2 * Colours[1].g + 1) / 3; - Colours[3].b = (Colours[0].b + 2 * Colours[1].b + 1) / 3; - } - - for (i = 0; i < 16; i++) { - if (Alpha) { // Test to see if we have 1-bit transparency - if (Alpha[i] < 128) { - Mask[i] = 3; // Transparent - if (OutCol) { - OutCol[i].r = Colours[3].r; - OutCol[i].g = Colours[3].g; - OutCol[i].b = Colours[3].b; - } - continue; - } - } - - // If no transparency, try to find which colour is the closest. - Closest = UINT_MAX; - ShortToColor888(In[i], &c); - for (j = 0; j < NumCols; j++) { - Dist = Distance(&c, &Colours[j]); - if (Dist < Closest) { - Closest = Dist; - Mask[i] = j; - if (OutCol) { - OutCol[i].r = Colours[j].r; - OutCol[i].g = Colours[j].g; - OutCol[i].b = Colours[j].b; - } - } - } - } - - for (i = 0; i < 16; i++) { - BitMask |= (Mask[i] << (i*2)); - } - - return BitMask; -} - - -ILvoid GenAlphaBitMask(ILubyte a0, ILubyte a1, ILubyte *In, ILubyte *Mask, ILubyte *Out) -{ - ILubyte Alphas[8], M[16]; - ILuint i, j, Closest, Dist; - - Alphas[0] = a0; - Alphas[1] = a1; - - // 8-alpha or 6-alpha block? - if (a0 > a1) { - // 8-alpha block: derive the other six alphas. - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - Alphas[2] = (6 * Alphas[0] + 1 * Alphas[1] + 3) / 7; // bit code 010 - Alphas[3] = (5 * Alphas[0] + 2 * Alphas[1] + 3) / 7; // bit code 011 - Alphas[4] = (4 * Alphas[0] + 3 * Alphas[1] + 3) / 7; // bit code 100 - Alphas[5] = (3 * Alphas[0] + 4 * Alphas[1] + 3) / 7; // bit code 101 - Alphas[6] = (2 * Alphas[0] + 5 * Alphas[1] + 3) / 7; // bit code 110 - Alphas[7] = (1 * Alphas[0] + 6 * Alphas[1] + 3) / 7; // bit code 111 - } - else { - // 6-alpha block. - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - Alphas[2] = (4 * Alphas[0] + 1 * Alphas[1] + 2) / 5; // Bit code 010 - Alphas[3] = (3 * Alphas[0] + 2 * Alphas[1] + 2) / 5; // Bit code 011 - Alphas[4] = (2 * Alphas[0] + 3 * Alphas[1] + 2) / 5; // Bit code 100 - Alphas[5] = (1 * Alphas[0] + 4 * Alphas[1] + 2) / 5; // Bit code 101 - Alphas[6] = 0x00; // Bit code 110 - Alphas[7] = 0xFF; // Bit code 111 - } - - for (i = 0; i < 16; i++) { - Closest = UINT_MAX; - for (j = 0; j < 8; j++) { - Dist = abs((ILint)In[i] - (ILint)Alphas[j]); - if (Dist < Closest) { - Closest = Dist; - M[i] = j; - } - } - } - - if (Out) { - for (i = 0; i < 16; i++) { - Out[i] = Alphas[M[i]]; - } - } - - //this was changed 20040623. There was a shift bug in here. Now the code - //produces much higher quality images. - // First three bytes. - Mask[0] = (M[0]) | (M[1] << 3) | ((M[2] & 0x03) << 6); - Mask[1] = ((M[2] & 0x04) >> 2) | (M[3] << 1) | (M[4] << 4) | ((M[5] & 0x01) << 7); - Mask[2] = ((M[5] & 0x06) >> 1) | (M[6] << 2) | (M[7] << 5); - - // Second three bytes. - Mask[3] = (M[8]) | (M[9] << 3) | ((M[10] & 0x03) << 6); - Mask[4] = ((M[10] & 0x04) >> 2) | (M[11] << 1) | (M[12] << 4) | ((M[13] & 0x01) << 7); - Mask[5] = ((M[13] & 0x06) >> 1) | (M[14] << 2) | (M[15] << 5); - - return; -} - - -ILuint RMSAlpha(ILubyte *Orig, ILubyte *Test) -{ - ILuint RMS = 0, i; - ILint d; - - for (i = 0; i < 16; i++) { - d = Orig[i] - Test[i]; - RMS += d*d; - } - - //RMS /= 16; - - return RMS; -} - - -ILuint Distance(Color888 *c1, Color888 *c2) { - return (c1->r - c2->r) * (c1->r - c2->r) + - (c1->g - c2->g) * (c1->g - c2->g) + - (c1->b - c2->b) * (c1->b - c2->b); -} - -#define Sum(c) ((c)->r + (c)->g + (c)->b) - -ILvoid ChooseEndpoints(ILushort *Block, ILushort *ex0, ILushort *ex1) { - ILuint i; - Color888 Colours[16]; - ILint Lowest=0, Highest=0; - - for (i = 0; i < 16; i++) { - ShortToColor888(Block[i], &Colours[i]); - - if (Sum(&Colours[i]) < Sum(&Colours[Lowest])) - Lowest = i; - if (Sum(&Colours[i]) > Sum(&Colours[Highest])) - Highest = i; - } - *ex0 = Block[Highest]; - *ex1 = Block[Lowest]; -} - -#undef Sum - - -ILvoid ChooseAlphaEndpoints(ILubyte *Block, ILubyte *a0, ILubyte *a1) { - ILuint i, Lowest = 0xFF, Highest = 0; - - for (i = 0; i < 16; i++) { - if( Block[i] < Lowest) - Lowest = Block[i]; - if (Block[i] > Highest) - Highest = Block[i]; - } - - *a0 = Lowest; - *a1 = Highest; -} - - -ILvoid CorrectEndDXT1(ILushort *ex0, ILushort *ex1, ILboolean HasAlpha) -{ - ILushort Temp; - - if (HasAlpha) { - if (*ex0 > *ex1) { - Temp = *ex0; - *ex0 = *ex1; - *ex1 = Temp; - } - } - else { - if (*ex0 < *ex1) { - Temp = *ex0; - *ex0 = *ex1; - *ex1 = Temp; - } - } - - return; -} - - -ILvoid PreMult(ILushort *Data, ILubyte *Alpha) -{ - Color888 Colour; - ILuint i; - - for (i = 0; i < 16; i++) { - ShortToColor888(Data[i], &Colour); - Colour.r = (ILubyte)(((ILuint)Colour.r * Alpha[i]) >> 8); - Colour.g = (ILubyte)(((ILuint)Colour.g * Alpha[i]) >> 8); - Colour.b = (ILubyte)(((ILuint)Colour.b * Alpha[i]) >> 8); - - /*Colour.r = (ILubyte)(Colour.r * (Alpha[i] / 255.0)); - Colour.g = (ILubyte)(Colour.g * (Alpha[i] / 255.0)); - Colour.b = (ILubyte)(Colour.b * (Alpha[i] / 255.0));*/ - - Data[i] = Color888ToShort(&Colour); - ShortToColor888(Data[i], &Colour); - } - - return; -} diff --git a/win32/devil/src/il_dds.c b/win32/devil/src/il_dds.c deleted file mode 100644 index 29c26deeb..000000000 --- a/win32/devil/src/il_dds.c +++ /dev/null @@ -1,2869 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 01/08/2007 -// -// Filename: src-IL/src/il_dds.c -// -// Description: Reads from a DirectDraw Surface (.dds) file. -// -//----------------------------------------------------------------------------- - - -// -// -// Note: Almost all this code is from nVidia's DDS-loading example at -// http://www.nvidia.com/view.asp?IO=dxtc_decompression_code -// and from the specs at -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/hh/dx8_c/graphics_using_0j03.asp -// and -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/ProgrammersGuide/Appendix/DDSFileFormat/ovwDDSFileFormat.asp -// However, some not really valid .dds files are also read, for example -// Volume Textures without the COMPLEX bit set, so the specs aren't taken -// too strictly while reading. - - -#include "il_internal.h" -#ifndef IL_NO_DDS -#include "il_dds.h" - - -// Global variables -static DDSHEAD Head; // Image header -static ILubyte *CompData; // Compressed data -static ILuint CompSize; // Compressed size -static ILuint CompFormat; // Compressed format -static ILimage *Image; -static ILint Width, Height, Depth; - -ILuint CubemapDirections[CUBEMAP_SIDES] = { - DDS_CUBEMAP_POSITIVEX, - DDS_CUBEMAP_NEGATIVEX, - DDS_CUBEMAP_POSITIVEY, - DDS_CUBEMAP_NEGATIVEY, - DDS_CUBEMAP_POSITIVEZ, - DDS_CUBEMAP_NEGATIVEZ -}; - - -//! Checks if the file specified in FileName is a valid .dds file. -ILboolean ilIsValidDds(ILconst_string FileName) -{ - ILHANDLE DdsFile; - ILboolean bDds = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("dds"))) { - ilSetError(IL_INVALID_EXTENSION); - return bDds; - } - - DdsFile = iopenr(FileName); - if (DdsFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDds; - } - - bDds = ilIsValidDdsF(DdsFile); - icloser(DdsFile); - - return bDds; -} - - -//! Checks if the ILHANDLE contains a valid .dds file at the current position. -ILboolean ilIsValidDdsF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidDds(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .dds lump. -ILboolean ilIsValidDdsL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidDds(); -} - - -// Internal function used to get the .dds header from the current file. -ILboolean iGetDdsHead(DDSHEAD *Header) -{ - - ILint i; - - - - iread(&Header->Signature, 1, 4); - Header->Size1 = GetLittleUInt(); - Header->Flags1 = GetLittleUInt(); - Header->Height = GetLittleUInt(); - Header->Width = GetLittleUInt(); - Header->LinearSize = GetLittleUInt(); - Header->Depth = GetLittleUInt(); - Header->MipMapCount = GetLittleUInt(); - Header->AlphaBitDepth = GetLittleUInt(); - - - - for (i = 0; i < 10; ++i) - - Header->NotUsed[i] = GetLittleUInt(); - - - Header->Size2 = GetLittleUInt(); - Header->Flags2 = GetLittleUInt(); - Header->FourCC = GetLittleUInt(); - Header->RGBBitCount = GetLittleUInt(); - Header->RBitMask = GetLittleUInt(); - Header->GBitMask = GetLittleUInt(); - Header->BBitMask = GetLittleUInt(); - Header->RGBAlphaBitMask = GetLittleUInt(); - Header->ddsCaps1 = GetLittleUInt(); - Header->ddsCaps2 = GetLittleUInt(); - Header->ddsCaps3 = GetLittleUInt(); - Header->ddsCaps4 = GetLittleUInt(); - Header->TextureStage = GetLittleUInt(); - - if (Head.Depth == 0) - Head.Depth = 1; - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidDds() -{ - ILboolean IsValid; - DDSHEAD Head; - - iGetDdsHead(&Head); - iseek(-(ILint)sizeof(DDSHEAD), IL_SEEK_CUR); // Go ahead and restore to previous state - - IsValid = iCheckDds(&Head); - - return IsValid; -} - - -// Internal function used to check if the HEADER is a valid .dds header. -ILboolean iCheckDds(DDSHEAD *Head) -{ - if (strncmp((const char*)Head->Signature, "DDS ", 4)) - return IL_FALSE; - //note that if Size1 is "DDS " this is not a valid dds file according - //to the file spec. Some broken tool out there seems to produce files - //with this value in the size field, so we support reading them... - if (Head->Size1 != 124 && Head->Size1 != IL_MAKEFOURCC('D', 'D', 'S', ' ')) - return IL_FALSE; - if (Head->Size2 != 32) - return IL_FALSE; - if (Head->Width == 0 || Head->Height == 0) - return IL_FALSE; - return IL_TRUE; -} - - -//! Reads a .dds file -ILboolean ilLoadDds(ILconst_string FileName) -{ - ILHANDLE DdsFile; - ILboolean bDds = IL_FALSE; - - DdsFile = iopenr(FileName); - if (DdsFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDds; - } - - bDds = ilLoadDdsF(DdsFile); - icloser(DdsFile); - - return bDds; -} - - -//! Reads an already-opened .dds file -ILboolean ilLoadDdsF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadDdsInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .dds -ILboolean ilLoadDdsL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadDdsInternal(); -} - - -ILubyte iCompFormatToBpp(ILenum Format) - -{ - - //non-compressed (= non-FOURCC) codes - - if (Format == PF_LUMINANCE || Format == PF_LUMINANCE_ALPHA || Format == PF_ARGB) - - return Head.RGBBitCount/8; - - - - //fourcc formats - - else if (Format == PF_RGB || Format == PF_3DC || Format == PF_RXGB) - - return 3; - - else if (Format == PF_ATI1N) - - return 1; - - else if (Format == PF_R16F) - - return 2; - - else if (Format == PF_A16B16G16R16 || Format == PF_A16B16G16R16F - - || Format == PF_G32R32F) - - return 8; - - else if (Format == PF_A32B32G32R32F) - - return 16; - - else //if (Format == PF_G16R16F || Format == PF_R32F || dxt) - - return 4; - -} - - - -ILubyte iCompFormatToBpc(ILenum Format) - -{ - - if (Format == PF_R16F || Format == PF_G16R16F || Format == PF_A16B16G16R16F) - - //DevIL has no internal half type, so these formats are converted to 32 bits - - return 4; - - else if (Format == PF_R32F || Format == PF_G32R32F || Format == PF_A32B32G32R32F) - - return 4; - - else if(Format == PF_A16B16G16R16) - - return 2; - - else - - return 1; - -} - - - -ILubyte iCompFormatToChannelCount(ILenum Format) - -{ - - if (Format == PF_RGB || Format == PF_3DC || Format == PF_RXGB) - - return 3; - - else if (Format == PF_LUMINANCE || Format == PF_R16F || Format == PF_R32F || Format == PF_ATI1N) - - return 1; - - else if (Format == PF_LUMINANCE_ALPHA || Format == PF_G16R16F || Format == PF_G32R32F) - - return 2; - - else //if(Format == PF_ARGB || dxt) - - return 4; - -} - -ILboolean iLoadDdsCubemapInternal() -{ - ILuint i; - ILubyte Bpp, Channels, Bpc; - ILimage *startImage; - - CompData = NULL; - - Bpp = iCompFormatToBpp(CompFormat); - - Channels = iCompFormatToChannelCount(CompFormat); - - Bpc = iCompFormatToBpc(CompFormat); - - if(CompFormat == PF_LUMINANCE && Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK - - Bpc = 2; Bpp = 2; - - } - - - startImage = Image; - // run through cube map possibilities - for (i = 0; i < CUBEMAP_SIDES; i++) { - // reset each time - Width = Head.Width; - Height = Head.Height; - Depth = Head.Depth; - if (Head.ddsCaps2 & CubemapDirections[i]) { - if (i != 0) { - Image->Next = ilNewImage(Width, Height, Depth, Channels, Bpc); - if (Image->Next == NULL) - return IL_FALSE; - - Image = Image->Next; - - if (CompFormat == PF_R16F - || CompFormat == PF_G16R16F - || CompFormat == PF_A16B16G16R16F - || CompFormat == PF_R32F - || CompFormat == PF_G32R32F - || CompFormat == PF_A32B32G32R32F) { - //DevIL's format autodetection doesn't work for - //float images...correct this - Image->Type = IL_FLOAT; - Image->Bpp = Channels; - } - - ilBindImage(ilGetCurName()); // Set to parent image first. - ilActiveImage(i); //now Image == iCurImage...globals SUCK, fix this!!! - } - - if (!ReadData()) - return IL_FALSE; - - if (!AllocImage()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - - Image->CubeFlags = CubemapDirections[i]; - - if (!Decompress()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - - if (!ReadMipmaps()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - } - } - - if (CompData) { - ifree(CompData); - CompData = NULL; - } - - ilBindImage(ilGetCurName()); // Set to parent image first. - return ilFixImage(); -} - - -ILboolean iLoadDdsInternal() -{ - ILuint BlockSize = 0; - - CompData = NULL; - Image = NULL; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetDdsHead(&Head)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - if(!iCheckDds(&Head)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - BlockSize = DecodePixelFormat(); - if (CompFormat == PF_UNKNOWN) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // Microsoft bug, they're not following their own documentation. - if (!(Head.Flags1 & (DDS_LINEARSIZE | DDS_PITCH)) - || Head.LinearSize == 0) { - Head.Flags1 |= DDS_LINEARSIZE; - Head.LinearSize = BlockSize; - } - - Image = iCurImage; - if (Head.ddsCaps1 & DDS_COMPLEX) { - if (Head.ddsCaps2 & DDS_CUBEMAP) { - if (!iLoadDdsCubemapInternal()) - return IL_FALSE; - return IL_TRUE; - } - } - - Width = Head.Width; - Height = Head.Height; - Depth = Head.Depth; - AdjustVolumeTexture(&Head); - - if (!ReadData()) - return IL_FALSE; - if (!AllocImage()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - if (!Decompress()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - - if (!ReadMipmaps()) { - if (CompData) { - ifree(CompData); - CompData = NULL; - } - return IL_FALSE; - } - - if (CompData) { - ifree(CompData); - CompData = NULL; - } - - ilBindImage(ilGetCurName()); // Set to parent image first. - return ilFixImage(); -} - - -ILuint DecodePixelFormat() -{ - ILuint BlockSize; - - if (Head.Flags2 & DDS_FOURCC) { - BlockSize = ((Head.Width + 3)/4) * ((Head.Height + 3)/4) * Head.Depth; - switch (Head.FourCC) - { - case IL_MAKEFOURCC('D','X','T','1'): - CompFormat = PF_DXT1; - BlockSize *= 8; - break; - - case IL_MAKEFOURCC('D','X','T','2'): - CompFormat = PF_DXT2; - BlockSize *= 16; - break; - - case IL_MAKEFOURCC('D','X','T','3'): - CompFormat = PF_DXT3; - BlockSize *= 16; - break; - - case IL_MAKEFOURCC('D','X','T','4'): - CompFormat = PF_DXT4; - BlockSize *= 16; - break; - - case IL_MAKEFOURCC('D','X','T','5'): - CompFormat = PF_DXT5; - BlockSize *= 16; - break; - - - - case IL_MAKEFOURCC('A', 'T', 'I', '1'): - - CompFormat = PF_ATI1N; - - BlockSize *= 8; - - break; - - case IL_MAKEFOURCC('A', 'T', 'I', '2'): - CompFormat = PF_3DC; - BlockSize *= 16; - break; - - case IL_MAKEFOURCC('R', 'X', 'G', 'B'): - CompFormat = PF_RXGB; - BlockSize *= 16; - break; - - case IL_MAKEFOURCC('$', '\0', '\0', '\0'): - CompFormat = PF_A16B16G16R16; - BlockSize = Head.Width * Head.Height * Head.Depth * 8; - break; - - case IL_MAKEFOURCC('o', '\0', '\0', '\0'): - CompFormat = PF_R16F; - BlockSize = Head.Width * Head.Height * Head.Depth * 2; - break; - - case IL_MAKEFOURCC('p', '\0', '\0', '\0'): - CompFormat = PF_G16R16F; - BlockSize = Head.Width * Head.Height * Head.Depth * 4; - break; - - case IL_MAKEFOURCC('q', '\0', '\0', '\0'): - CompFormat = PF_A16B16G16R16F; - BlockSize = Head.Width * Head.Height * Head.Depth * 8; - break; - - case IL_MAKEFOURCC('r', '\0', '\0', '\0'): - CompFormat = PF_R32F; - BlockSize = Head.Width * Head.Height * Head.Depth * 4; - break; - - case IL_MAKEFOURCC('s', '\0', '\0', '\0'): - CompFormat = PF_G32R32F; - BlockSize = Head.Width * Head.Height * Head.Depth * 8; - break; - - case IL_MAKEFOURCC('t', '\0', '\0', '\0'): - CompFormat = PF_A32B32G32R32F; - BlockSize = Head.Width * Head.Height * Head.Depth * 16; - break; - - default: - CompFormat = PF_UNKNOWN; - BlockSize *= 16; - break; - } - } else { - // This dds texture isn't compressed so write out ARGB or luminance format - if (Head.Flags2 & DDS_LUMINANCE) { - if (Head.Flags2 & DDS_ALPHAPIXELS) { - CompFormat = PF_LUMINANCE_ALPHA; - } else { - CompFormat = PF_LUMINANCE; - } - } - else { - if (Head.Flags2 & DDS_ALPHAPIXELS) { - CompFormat = PF_ARGB; - } else { - CompFormat = PF_RGB; - } - } - BlockSize = (Head.Width * Head.Height * Head.Depth * (Head.RGBBitCount >> 3)); - } - - return BlockSize; -} - - -// The few volume textures that I have don't have consistent LinearSize -// entries, even though the DDS_LINEARSIZE flag is set. -ILvoid AdjustVolumeTexture(DDSHEAD *Head) -{ - if (Head->Depth <= 1) - return; - - // All volume textures I've seem so far didn't have the DDS_COMPLEX flag set, - // even though this is normally required. But because noone does set it, - // also read images without it (TODO: check file size for 3d texture?) - if (/*!(Head->ddsCaps1 & DDS_COMPLEX) ||*/ !(Head->ddsCaps2 & DDS_VOLUME)) { - Head->Depth = 1; - Depth = 1; - } - - switch (CompFormat) - { - case PF_ARGB: - case PF_RGB: - case PF_LUMINANCE: - case PF_LUMINANCE_ALPHA: - //don't use the iCompFormatToBpp() function because this way - //argb images with only 8 bits (eg. a1r2g3b2) work as well - Head->LinearSize = IL_MAX(1,Head->Width) * IL_MAX(1,Head->Height) * - (Head->RGBBitCount / 8); - break; - - case PF_DXT1: - - case PF_ATI1N: - Head->LinearSize = ((Head->Width+3)/4) * ((Head->Height+3)/4) * 8; - break; - - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: - case PF_3DC: - case PF_RXGB: - Head->LinearSize = ((Head->Width+3)/4) * ((Head->Height+3)/4) * 16; - break; - - case PF_A16B16G16R16: - case PF_R16F: - case PF_G16R16F: - case PF_A16B16G16R16F: - case PF_R32F: - case PF_G32R32F: - case PF_A32B32G32R32F: - Head->LinearSize = IL_MAX(1,Head->Width) * IL_MAX(1,Head->Height) * - iCompFormatToBpp(CompFormat); - break; - } - - Head->Flags1 |= DDS_LINEARSIZE; - Head->LinearSize *= Head->Depth; - - return; -} - - -// Reads the compressed data -ILboolean ReadData() -{ - ILuint Bps; - ILint y, z; - ILubyte *Temp; - - if (CompData) { - ifree(CompData); - CompData = NULL; - } - - if (Head.Flags1 & DDS_LINEARSIZE) { - //Head.LinearSize = Head.LinearSize * Depth; - - CompData = (ILubyte*)ialloc(Head.LinearSize); - if (CompData == NULL) { - return IL_FALSE; - } - - if (iread(CompData, 1, Head.LinearSize) != (ILuint)Head.LinearSize) { - ifree(CompData); - CompData = NULL; - return IL_FALSE; - } - } - else { - Bps = Width * Head.RGBBitCount / 8; - CompSize = Bps * Height * Depth; - - CompData = (ILubyte*)ialloc(CompSize); - if (CompData == NULL) { - return IL_FALSE; - } - - Temp = CompData; - for (z = 0; z < Depth; z++) { - for (y = 0; y < Height; y++) { - if (iread(Temp, 1, Bps) != Bps) { - ifree(CompData); - CompData = NULL; - return IL_FALSE; - } - Temp += Bps; - } - } - } - - return IL_TRUE; -} - - -ILboolean AllocImage() -{ - ILubyte channels = 4; - ILenum format = IL_RGBA; - - switch (CompFormat) - { - case PF_RGB: - if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - break; - case PF_ARGB: - if (!ilTexImage(Width, Height, Depth, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - break; - - case PF_LUMINANCE: - - if(Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK - - if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, NULL)) - - return IL_FALSE; - - } - - else - - if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL)) - - return IL_FALSE; - - break; - - case PF_LUMINANCE_ALPHA: - - if (!ilTexImage(Width, Height, Depth, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL)) - - return IL_FALSE; - - break; - - - - case PF_ATI1N: - - //right now there's no OpenGL api to use the compressed 3dc data, so - - //throw it away (I don't know how DirectX works, though)? - - if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL)) - - return IL_FALSE; - - break; - - - - case PF_3DC: - - //right now there's no OpenGL api to use the compressed 3dc data, so - - //throw it away (I don't know how DirectX works, though)? - - if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) - - return IL_FALSE; - - break; - - - - case PF_A16B16G16R16: - - if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat), - - ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_UNSIGNED_SHORT, NULL)) - - return IL_FALSE; - - break; - - - - case PF_R16F: - - case PF_G16R16F: - - case PF_A16B16G16R16F: - - case PF_R32F: - - case PF_G32R32F: - - case PF_A32B32G32R32F: - - if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat), - - ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_FLOAT, NULL)) - - return IL_FALSE; - - break; - - - default: - - if (CompFormat == PF_RXGB) { - - channels = 3; //normal map - - format = IL_RGB; - - } - - - if (!ilTexImage(Width, Height, Depth, channels, format, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE && CompData) { - iCurImage->DxtcData = (ILubyte*)ialloc(Head.LinearSize); - if (iCurImage->DxtcData == NULL) - return IL_FALSE; - iCurImage->DxtcFormat = CompFormat - PF_DXT1 + IL_DXT1; - iCurImage->DxtcSize = Head.LinearSize; - memcpy(iCurImage->DxtcData, CompData, iCurImage->DxtcSize); - } - break; - } - - Image->Origin = IL_ORIGIN_UPPER_LEFT; - - return IL_TRUE; -} - - -/* - * Assumes that the global variable CompFormat stores the format of the - * global pointer CompData (that's the pointer to the compressed data). - * Decompresses this data into Image->Data, returns if it was successful. - * It also uses the globals Width and Height. - * - * Assumes that iCurImage has valid Width, Height, Depth, Data, SizeOfData, - * Bpp, Bpc, Bps, SizeOfPlane, Format and Type fields. It is more or - * less assumed that the image has u8 rgba data (perhaps not for float - * images...) - * - * - * TODO: don't use globals, clean this function (and this file) up - */ -ILboolean Decompress() -{ - switch (CompFormat) - { - case PF_ARGB: - case PF_RGB: - case PF_LUMINANCE: - case PF_LUMINANCE_ALPHA: - return DecompressARGB(); - - case PF_DXT1: - return DecompressDXT1(); - - case PF_DXT2: - return DecompressDXT2(); - - case PF_DXT3: - return DecompressDXT3(); - - case PF_DXT4: - return DecompressDXT4(); - - case PF_DXT5: - return DecompressDXT5(); - - - case PF_ATI1N: - - return DecompressAti1n(); - - - case PF_3DC: - return Decompress3Dc(); - - case PF_RXGB: - return DecompressRXGB(); - - case PF_A16B16G16R16: - memcpy(Image->Data, CompData, Image->SizeOfData); - return IL_TRUE; - - - case PF_R16F: - case PF_G16R16F: - case PF_A16B16G16R16F: - case PF_R32F: - case PF_G32R32F: - case PF_A32B32G32R32F: - return DecompressFloat(); - - - case PF_UNKNOWN: - return IL_FALSE; - } - - return IL_FALSE; -} - - -ILboolean ReadMipmaps() -{ - ILuint i, CompFactor=0; - ILubyte Bpp, Channels, Bpc; - ILimage *StartImage, *TempImage; - ILuint LastLinear; - ILuint minW, minH; - - ILboolean isCompressed = IL_FALSE; - - - Bpp = iCompFormatToBpp(CompFormat); - - Channels = iCompFormatToChannelCount(CompFormat); - - Bpc = iCompFormatToBpc(CompFormat); - - if(CompFormat == PF_LUMINANCE && Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK - - Bpc = 2; Bpp = 2; - - } - - - //This doesn't work for images which first mipmap (= the image - - //itself) has width or height < 4 - //if (Head.Flags1 & DDS_LINEARSIZE) { - // CompFactor = (Width * Height * Depth * Bpp) / Head.LinearSize; - //} - switch(CompFormat) - { - case PF_DXT1: - //This is officially 6, we have 8 here because DXT1 may contain alpha - CompFactor = 8; - break; - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: - CompFactor = 4; - break; - case PF_RXGB: - case PF_3DC: - //This is officially 4 for 3dc, but that's bullshit :) There's no - //alpha data in 3dc images - CompFactor = 3; - break; - - case PF_ATI1N: - - CompFactor = 2; - - break; - default: - CompFactor = 1; - } - - StartImage = Image; - - if (!(Head.Flags1 & DDS_MIPMAPCOUNT) || Head.MipMapCount == 0) { - //some .dds-files have their mipmap flag set, - //but a mipmapcount of 0. Because mipMapCount is an uint, 0 - 1 gives - //overflow - don't let this happen: - Head.MipMapCount = 1; - } - - LastLinear = Head.LinearSize; - for (i = 0; i < Head.MipMapCount - 1; i++) { - Depth = Depth / 2; - Width = Width / 2; - Height = Height / 2; - - if (Depth == 0) - Depth = 1; - if (Width == 0) - Width = 1; - if (Height == 0) - Height = 1; - - Image->Next = ilNewImage(Width, Height, Depth, Channels, Bpc); - if (Image->Next == NULL) - goto mip_fail; - Image = Image->Next; - Image->Origin = IL_ORIGIN_UPPER_LEFT; - - if (Head.Flags1 & DDS_LINEARSIZE) { - - if (CompFormat == PF_R16F - - || CompFormat == PF_G16R16F - - || CompFormat == PF_A16B16G16R16F - - || CompFormat == PF_R32F - - || CompFormat == PF_G32R32F - - || CompFormat == PF_A32B32G32R32F) { - - Head.LinearSize = Width * Height * Depth * Bpp; - - - - //DevIL's format autodetection doesn't work for - - //float images...correct this - - Image->Type = IL_FLOAT; - - Image->Bpp = Channels; - - } - - else if (CompFormat == PF_A16B16G16R16) - - Head.LinearSize = Width * Height * Depth * Bpp; - else if (CompFormat != PF_RGB && CompFormat != PF_ARGB - - && CompFormat != PF_LUMINANCE - - && CompFormat != PF_LUMINANCE_ALPHA) { - - //compressed format - minW = (((Width+3)/4))*4; - minH = (((Height+3)/4))*4; - Head.LinearSize = (minW * minH * Depth * Bpp) / CompFactor; - - isCompressed = IL_TRUE; - } - else { - //don't use Bpp to support argb images with less than 32 bits - Head.LinearSize = Width * Height * Depth * (Head.RGBBitCount >> 3); - } - } - else { - Head.LinearSize >>= 1; - } - - if (!ReadData()) - goto mip_fail; - - - - if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE && isCompressed == IL_TRUE && CompData) { - - Image->DxtcData = (ILubyte*)ialloc(Head.LinearSize); - - if (Image->DxtcData == NULL) - - return IL_FALSE; - - Image->DxtcFormat = CompFormat - PF_DXT1 + IL_DXT1; - - Image->DxtcSize = Head.LinearSize; - - memcpy(Image->DxtcData, CompData, Image->DxtcSize); - - } - - - if (!Decompress()) - goto mip_fail; - } - - Head.LinearSize = LastLinear; - StartImage->Mipmaps = StartImage->Next; - StartImage->Next = NULL; - Image = StartImage; - - return IL_TRUE; - -mip_fail: - Image = StartImage; - StartImage = StartImage->Next; - while (StartImage) { - TempImage = StartImage; - StartImage = StartImage->Next; - ifree(TempImage); - } - - Image->Next = NULL; - return IL_FALSE; -} - -ILvoid ReadColors(const ILubyte* Data, Color8888* Out) -{ - ILubyte r0, g0, b0, r1, g1, b1; - - b0 = Data[0] & 0x1F; - g0 = ((Data[0] & 0xE0) >> 5) | ((Data[1] & 0x7) << 3); - r0 = (Data[1] & 0xF8) >> 3; - - b1 = Data[2] & 0x1F; - g1 = ((Data[2] & 0xE0) >> 5) | ((Data[3] & 0x7) << 3); - r1 = (Data[3] & 0xF8) >> 3; - - Out[0].r = r0 << 3; - Out[0].g = g0 << 2; - Out[0].b = b0 << 3; - - Out[1].r = r1 << 3; - Out[1].g = g1 << 2; - Out[1].b = b1 << 3; -} - -ILvoid ReadColor(ILushort Data, Color8888* Out) -{ - ILubyte r, g, b; - - b = Data & 0x1f; - g = (Data & 0x7E0) >> 5; - r = (Data & 0xF800) >> 11; - - Out->r = r << 3; - Out->g = g << 2; - Out->b = b << 3; -} - -ILboolean DecompressDXT1() -{ - int x, y, z, i, j, k, Select; - ILubyte *Temp; - Color8888 colours[4], *col; - ILushort color_0, color_1; - ILuint bitmask, Offset; - - if (!CompData) - return IL_FALSE; - - Temp = CompData; - colours[0].a = 0xFF; - colours[1].a = 0xFF; - colours[2].a = 0xFF; - //colours[3].a = 0xFF; - for (z = 0; z < Depth; z++) { - for (y = 0; y < Height; y += 4) { - for (x = 0; x < Width; x += 4) { - color_0 = *((ILushort*)Temp); - UShort(&color_0); - color_1 = *((ILushort*)(Temp + 2)); - UShort(&color_1); - ReadColor(color_0, colours); - ReadColor(color_1, colours + 1); - bitmask = ((ILuint*)Temp)[1]; - UInt(&bitmask); - Temp += 8; - - if (color_0 > color_1) { - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These 2-bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3; - colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3; - colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3; - //colours[2].a = 0xFF; - - colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3; - colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3; - colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3; - colours[3].a = 0xFF; - } - else { - // Three-color block: derive the other color. - // 00 = color_0, 01 = color_1, 10 = color_2, - // 11 = transparent. - // These 2-bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - colours[2].b = (colours[0].b + colours[1].b) / 2; - colours[2].g = (colours[0].g + colours[1].g) / 2; - colours[2].r = (colours[0].r + colours[1].r) / 2; - //colours[2].a = 0xFF; - - colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3; - colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3; - colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3; - colours[3].a = 0x00; - } - - for (j = 0, k = 0; j < 4; j++) { - for (i = 0; i < 4; i++, k++) { - - Select = (bitmask & (0x03 << k*2)) >> k*2; - col = &colours[Select]; - - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp; - Image->Data[Offset + 0] = col->r; - Image->Data[Offset + 1] = col->g; - Image->Data[Offset + 2] = col->b; - Image->Data[Offset + 3] = col->a; - } - } - } - } - } - } - - return IL_TRUE; -} - - -ILboolean DecompressDXT2() -{ - // Can do color & alpha same as dxt3, but color is pre-multiplied - // so the result will be wrong unless corrected. - if (!DecompressDXT3()) - return IL_FALSE; - CorrectPreMult(); - - return IL_TRUE; -} - - -ILboolean DecompressDXT3() -{ - int x, y, z, i, j, k, Select; - ILubyte *Temp; - //Color565 *color_0, *color_1; - Color8888 colours[4], *col; - ILuint bitmask, Offset; - ILushort word; - ILubyte *alpha; - - if (!CompData) - return IL_FALSE; - - Temp = CompData; - for (z = 0; z < Depth; z++) { - for (y = 0; y < Height; y += 4) { - for (x = 0; x < Width; x += 4) { - alpha = Temp; - Temp += 8; - ReadColors(Temp, colours); - bitmask = ((ILuint*)Temp)[1]; - UInt(&bitmask); - Temp += 8; - - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These 2-bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3; - colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3; - colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3; - //colours[2].a = 0xFF; - - colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3; - colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3; - colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3; - //colours[3].a = 0xFF; - - k = 0; - for (j = 0; j < 4; j++) { - for (i = 0; i < 4; i++, k++) { - - Select = (bitmask & (0x03 << k*2)) >> k*2; - col = &colours[Select]; - - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp; - Image->Data[Offset + 0] = col->r; - Image->Data[Offset + 1] = col->g; - Image->Data[Offset + 2] = col->b; - } - } - } - - for (j = 0; j < 4; j++) { - word = alpha[2*j] + 256*alpha[2*j+1]; - for (i = 0; i < 4; i++) { - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp + 3; - Image->Data[Offset] = word & 0x0F; - Image->Data[Offset] = Image->Data[Offset] | (Image->Data[Offset] << 4); - } - word >>= 4; - } - } - - } - } - } - - return IL_TRUE; -} - - -ILboolean DecompressDXT4() -{ - // Can do color & alpha same as dxt5, but color is pre-multiplied - // so the result will be wrong unless corrected. - if (!DecompressDXT5()) - return IL_FALSE; - CorrectPreMult(); - - return IL_FALSE; -} - - -ILboolean DecompressDXT5() -{ - int x, y, z, i, j, k, Select; - ILubyte *Temp; //, r0, g0, b0, r1, g1, b1; - Color8888 colours[4], *col; - ILuint bitmask, Offset; - ILubyte alphas[8], *alphamask; - ILuint bits; - - if (!CompData) - return IL_FALSE; - - Temp = CompData; - for (z = 0; z < Depth; z++) { - for (y = 0; y < Height; y += 4) { - for (x = 0; x < Width; x += 4) { - if (y >= Height || x >= Width) - break; - alphas[0] = Temp[0]; - alphas[1] = Temp[1]; - alphamask = Temp + 2; - Temp += 8; - - ReadColors(Temp, colours); - bitmask = ((ILuint*)Temp)[1]; - UInt(&bitmask); - Temp += 8; - - // Four-color block: derive the other two colors. - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - // These 2-bit codes correspond to the 2-bit fields - // stored in the 64-bit block. - colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3; - colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3; - colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3; - //colours[2].a = 0xFF; - - colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3; - colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3; - colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3; - //colours[3].a = 0xFF; - - k = 0; - for (j = 0; j < 4; j++) { - for (i = 0; i < 4; i++, k++) { - - Select = (bitmask & (0x03 << k*2)) >> k*2; - col = &colours[Select]; - - // only put pixels out < width or height - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp; - Image->Data[Offset + 0] = col->r; - Image->Data[Offset + 1] = col->g; - Image->Data[Offset + 2] = col->b; - } - } - } - - // 8-alpha or 6-alpha block? - if (alphas[0] > alphas[1]) { - // 8-alpha block: derive the other six alphas. - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - alphas[2] = (6 * alphas[0] + 1 * alphas[1] + 3) / 7; // bit code 010 - alphas[3] = (5 * alphas[0] + 2 * alphas[1] + 3) / 7; // bit code 011 - alphas[4] = (4 * alphas[0] + 3 * alphas[1] + 3) / 7; // bit code 100 - alphas[5] = (3 * alphas[0] + 4 * alphas[1] + 3) / 7; // bit code 101 - alphas[6] = (2 * alphas[0] + 5 * alphas[1] + 3) / 7; // bit code 110 - alphas[7] = (1 * alphas[0] + 6 * alphas[1] + 3) / 7; // bit code 111 - } - else { - // 6-alpha block. - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - alphas[2] = (4 * alphas[0] + 1 * alphas[1] + 2) / 5; // Bit code 010 - alphas[3] = (3 * alphas[0] + 2 * alphas[1] + 2) / 5; // Bit code 011 - alphas[4] = (2 * alphas[0] + 3 * alphas[1] + 2) / 5; // Bit code 100 - alphas[5] = (1 * alphas[0] + 4 * alphas[1] + 2) / 5; // Bit code 101 - alphas[6] = 0x00; // Bit code 110 - alphas[7] = 0xFF; // Bit code 111 - } - - // Note: Have to separate the next two loops, - // it operates on a 6-byte system. - - // First three bytes - //bits = *((ILint*)alphamask); - bits = (alphamask[0]) | (alphamask[1] << 8) | (alphamask[2] << 16); - for (j = 0; j < 2; j++) { - for (i = 0; i < 4; i++) { - // only put pixels out < width or height - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp + 3; - Image->Data[Offset] = alphas[bits & 0x07]; - } - bits >>= 3; - } - } - - // Last three bytes - //bits = *((ILint*)&alphamask[3]); - bits = (alphamask[3]) | (alphamask[4] << 8) | (alphamask[5] << 16); - for (j = 2; j < 4; j++) { - for (i = 0; i < 4; i++) { - // only put pixels out < width or height - if (((x + i) < Width) && ((y + j) < Height)) { - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp + 3; - Image->Data[Offset] = alphas[bits & 0x07]; - } - bits >>= 3; - } - } - } - } - } - - return IL_TRUE; -} - - -ILboolean Decompress3Dc() - -{ - - int x, y, z, i, j, k, t1, t2; - - ILubyte *Temp, *Temp2; - - ILubyte XColours[8], YColours[8]; - - ILuint bitmask, bitmask2, Offset, CurrOffset; - - - - if (!CompData) - - return IL_FALSE; - - - - Temp = CompData; - - Offset = 0; - - for (z = 0; z < Depth; z++) { - - for (y = 0; y < Height; y += 4) { - - for (x = 0; x < Width; x += 4) { - - Temp2 = Temp + 8; - - - - //Read Y palette - - t1 = YColours[0] = Temp[0]; - - t2 = YColours[1] = Temp[1]; - - Temp += 2; - - if (t1 > t2) - - for (i = 2; i < 8; ++i) - - YColours[i] = t1 + ((t2 - t1)*(i - 1))/7; - - else { - - for (i = 2; i < 6; ++i) - - YColours[i] = t1 + ((t2 - t1)*(i - 1))/5; - - YColours[6] = 0; - - YColours[7] = 255; - - } - - - - // Read X palette - - t1 = XColours[0] = Temp2[0]; - - t2 = XColours[1] = Temp2[1]; - - Temp2 += 2; - - if (t1 > t2) - - for (i = 2; i < 8; ++i) - - XColours[i] = t1 + ((t2 - t1)*(i - 1))/7; - - else { - - for (i = 2; i < 6; ++i) - - XColours[i] = t1 + ((t2 - t1)*(i - 1))/5; - - XColours[6] = 0; - - XColours[7] = 255; - - } - - - - //decompress pixel data - - CurrOffset = Offset; - - for (k = 0; k < 4; k += 2) { - - // First three bytes - - bitmask = ((ILuint)(Temp[0]) << 0) | ((ILuint)(Temp[1]) << 8) | ((ILuint)(Temp[2]) << 16); - - bitmask2 = ((ILuint)(Temp2[0]) << 0) | ((ILuint)(Temp2[1]) << 8) | ((ILuint)(Temp2[2]) << 16); - - for (j = 0; j < 2; j++) { - - // only put pixels out < height - - if ((y + k + j) < Height) { - - for (i = 0; i < 4; i++) { - - // only put pixels out < width - - if (((x + i) < Width)) { - - ILint t, tx, ty; - - - - t1 = CurrOffset + (x + i)*3; - - Image->Data[t1 + 1] = ty = YColours[bitmask & 0x07]; - - Image->Data[t1 + 0] = tx = XColours[bitmask2 & 0x07]; - - - - //calculate b (z) component ((r/255)^2 + (g/255)^2 + (b/255)^2 = 1 - - t = 127*128 - (tx - 127)*(tx - 128) - (ty - 127)*(ty - 128); - - if (t > 0) - - Image->Data[t1 + 2] = (ILubyte)(iSqrt(t) + 128); - - else - - Image->Data[t1 + 2] = 0x7F; - - } - - bitmask >>= 3; - - bitmask2 >>= 3; - - } - - CurrOffset += Image->Bps; - - } - - } - - Temp += 3; - - Temp2 += 3; - - } - - - - //skip bytes that were read via Temp2 - - Temp += 8; - - } - - Offset += Image->Bps*4; - - } - - } - - - - return IL_TRUE; - -} - - - -ILboolean DecompressAti1n() - -{ - - int x, y, z, i, j, k, t1, t2; - - ILubyte *Temp; - - ILubyte Colours[8]; - - ILuint bitmask, Offset, CurrOffset; - - - - if (!CompData) - - return IL_FALSE; - - - - Temp = CompData; - - Offset = 0; - - for (z = 0; z < Depth; z++) { - - for (y = 0; y < Height; y += 4) { - - for (x = 0; x < Width; x += 4) { - - //Read palette - - t1 = Colours[0] = Temp[0]; - - t2 = Colours[1] = Temp[1]; - - Temp += 2; - - if (t1 > t2) - - for (i = 2; i < 8; ++i) - - Colours[i] = t1 + ((t2 - t1)*(i - 1))/7; - - else { - - for (i = 2; i < 6; ++i) - - Colours[i] = t1 + ((t2 - t1)*(i - 1))/5; - - Colours[6] = 0; - - Colours[7] = 255; - - } - - - - //decompress pixel data - - CurrOffset = Offset; - - for (k = 0; k < 4; k += 2) { - - // First three bytes - - bitmask = ((ILuint)(Temp[0]) << 0) | ((ILuint)(Temp[1]) << 8) | ((ILuint)(Temp[2]) << 16); - - for (j = 0; j < 2; j++) { - - // only put pixels out < height - - if ((y + k + j) < Height) { - - for (i = 0; i < 4; i++) { - - // only put pixels out < width - - if (((x + i) < Width)) { - - t1 = CurrOffset + (x + i); - - Image->Data[t1] = Colours[bitmask & 0x07]; - - } - - bitmask >>= 3; - - } - - CurrOffset += Image->Bps; - - } - - } - - Temp += 3; - - } - - } - - Offset += Image->Bps*4; - - } - - } - - - - return IL_TRUE; - -} - - - -//This is nearly exactly the same as DecompressDXT5... - -//I have to clean up this file (put common code in - -//helper functions etc) - -ILboolean DecompressRXGB() - -{ - - int x, y, z, i, j, k, Select; - - ILubyte *Temp; - - Color565 *color_0, *color_1; - - Color8888 colours[4], *col; - - ILuint bitmask, Offset; - - ILubyte alphas[8], *alphamask; - - ILuint bits; - - - - if (!CompData) - - return IL_FALSE; - - - - Temp = CompData; - - for (z = 0; z < Depth; z++) { - - for (y = 0; y < Height; y += 4) { - - for (x = 0; x < Width; x += 4) { - - if (y >= Height || x >= Width) - - break; - - alphas[0] = Temp[0]; - - alphas[1] = Temp[1]; - - alphamask = Temp + 2; - - Temp += 8; - - color_0 = ((Color565*)Temp); - - color_1 = ((Color565*)(Temp+2)); - - bitmask = ((ILuint*)Temp)[1]; - - Temp += 8; - - - - colours[0].r = color_0->nRed << 3; - - colours[0].g = color_0->nGreen << 2; - - colours[0].b = color_0->nBlue << 3; - - colours[0].a = 0xFF; - - - - colours[1].r = color_1->nRed << 3; - - colours[1].g = color_1->nGreen << 2; - - colours[1].b = color_1->nBlue << 3; - - colours[1].a = 0xFF; - - - - // Four-color block: derive the other two colors. - - // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 - - // These 2-bit codes correspond to the 2-bit fields - - // stored in the 64-bit block. - - colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3; - - colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3; - - colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3; - - colours[2].a = 0xFF; - - - - colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3; - - colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3; - - colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3; - - colours[3].a = 0xFF; - - - - k = 0; - - for (j = 0; j < 4; j++) { - - for (i = 0; i < 4; i++, k++) { - - - - Select = (bitmask & (0x03 << k*2)) >> k*2; - - col = &colours[Select]; - - - - // only put pixels out < width or height - - if (((x + i) < Width) && ((y + j) < Height)) { - - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp; - - Image->Data[Offset + 0] = col->r; - - Image->Data[Offset + 1] = col->g; - - Image->Data[Offset + 2] = col->b; - - } - - } - - } - - - - // 8-alpha or 6-alpha block? - - if (alphas[0] > alphas[1]) { - - // 8-alpha block: derive the other six alphas. - - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - - alphas[2] = (6 * alphas[0] + 1 * alphas[1] + 3) / 7; // bit code 010 - - alphas[3] = (5 * alphas[0] + 2 * alphas[1] + 3) / 7; // bit code 011 - - alphas[4] = (4 * alphas[0] + 3 * alphas[1] + 3) / 7; // bit code 100 - - alphas[5] = (3 * alphas[0] + 4 * alphas[1] + 3) / 7; // bit code 101 - - alphas[6] = (2 * alphas[0] + 5 * alphas[1] + 3) / 7; // bit code 110 - - alphas[7] = (1 * alphas[0] + 6 * alphas[1] + 3) / 7; // bit code 111 - - } - - else { - - // 6-alpha block. - - // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. - - alphas[2] = (4 * alphas[0] + 1 * alphas[1] + 2) / 5; // Bit code 010 - - alphas[3] = (3 * alphas[0] + 2 * alphas[1] + 2) / 5; // Bit code 011 - - alphas[4] = (2 * alphas[0] + 3 * alphas[1] + 2) / 5; // Bit code 100 - - alphas[5] = (1 * alphas[0] + 4 * alphas[1] + 2) / 5; // Bit code 101 - - alphas[6] = 0x00; // Bit code 110 - - alphas[7] = 0xFF; // Bit code 111 - - } - - - - // Note: Have to separate the next two loops, - - // it operates on a 6-byte system. - - // First three bytes - - bits = *((ILint*)alphamask); - - for (j = 0; j < 2; j++) { - - for (i = 0; i < 4; i++) { - - // only put pixels out < width or height - - if (((x + i) < Width) && ((y + j) < Height)) { - - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp + 0; - - Image->Data[Offset] = alphas[bits & 0x07]; - - } - - bits >>= 3; - - } - - } - - - - // Last three bytes - - bits = *((ILint*)&alphamask[3]); - - for (j = 2; j < 4; j++) { - - for (i = 0; i < 4; i++) { - - // only put pixels out < width or height - - if (((x + i) < Width) && ((y + j) < Height)) { - - Offset = z * Image->SizeOfPlane + (y + j) * Image->Bps + (x + i) * Image->Bpp + 0; - - Image->Data[Offset] = alphas[bits & 0x07]; - - } - - bits >>= 3; - - } - - } - - } - - } - - } - - - - return IL_TRUE; - -} - - - -//stolen from OpenEXR - -unsigned int - -halfToFloat (unsigned short y) - -{ - - - - int s = (y >> 15) & 0x00000001; - - int e = (y >> 10) & 0x0000001f; - - int m = y & 0x000003ff; - - - - if (e == 0) - - { - - if (m == 0) - - { - - // - - // Plus or minus zero - - // - - - - return s << 31; - - } - - else - - { - - // - - // Denormalized number -- renormalize it - - // - - - - while (!(m & 0x00000400)) - - { - - m <<= 1; - - e -= 1; - - } - - - - e += 1; - - m &= ~0x00000400; - - } - - } - - else if (e == 31) - - { - - if (m == 0) - - { - - // - - // Positive or negative infinity - - // - - - - return (s << 31) | 0x7f800000; - - } - - else - - { - - // - - // Nan -- preserve sign and significand bits - - // - - - - return (s << 31) | 0x7f800000 | (m << 13); - - } - - } - - - - // - - // Normalized number - - // - - - - e = e + (127 - 15); - - m = m << 13; - - - - // - - // Assemble s, e and m. - - // - - - - return (s << 31) | (e << 23) | m; - -} - - - - - -ILboolean iConvFloat16ToFloat32(ILuint* dest, ILushort* src, ILuint size) - -{ - - ILuint i; - - for(i = 0; i < size; ++i, ++dest, ++src) { - - //float: 1 sign bit, 8 exponent bits, 23 mantissa bits - - //half: 1 sign bit, 5 exponent bits, 10 mantissa bits - - *dest = halfToFloat(*src); - - - - } - - return IL_TRUE; - -} - - - -ILboolean DecompressFloat() - -{ - - switch(CompFormat) - - { - - case PF_R32F: - - case PF_G32R32F: - - case PF_A32B32G32R32F: - - memcpy(Image->Data, CompData, Image->SizeOfData); - - return IL_TRUE; - - case PF_R16F: - - case PF_G16R16F: - - case PF_A16B16G16R16F: - - return iConvFloat16ToFloat32((ILuint*)Image->Data, (ILushort*)CompData, - - Image->Width * Image->Height * Image->Depth * Image->Bpp); - - default: - - return IL_FALSE; - - } - -} - - -ILvoid CorrectPreMult() -{ - ILuint i; - - for (i = 0; i < Image->SizeOfData; i += 4) { - if (Image->Data[i+3] != 0) { // Cannot divide by 0. - Image->Data[i] = (ILubyte)(((ILuint)Image->Data[i] << 8) / Image->Data[i+3]); - Image->Data[i+1] = (ILubyte)(((ILuint)Image->Data[i+1] << 8) / Image->Data[i+3]); - Image->Data[i+2] = (ILubyte)(((ILuint)Image->Data[i+2] << 8) / Image->Data[i+3]); - } - } - - return; -} - - -ILboolean DecompressARGB() { - ILuint ReadI = 0, TempBpp, i; - ILuint RedL, RedR; - ILuint GreenL, GreenR; - ILuint BlueL, BlueR; - ILuint AlphaL, AlphaR; - ILubyte *Temp; - - - if (!CompData) - - return IL_FALSE; - - - - if(CompFormat == PF_LUMINANCE && Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK - - memcpy(Image->Data, CompData, Image->SizeOfData); - - return IL_TRUE; - - } - - - GetBitsFromMask(Head.RBitMask, &RedL, &RedR); - GetBitsFromMask(Head.GBitMask, &GreenL, &GreenR); - GetBitsFromMask(Head.BBitMask, &BlueL, &BlueR); - GetBitsFromMask(Head.RGBAlphaBitMask, &AlphaL, &AlphaR); - Temp = CompData; - TempBpp = Head.RGBBitCount / 8; - - for (i = 0; i < Image->SizeOfData; i += Image->Bpp) { - - //TODO: This is SLOOOW... - //but the old version crashed in release build under - //winxp (and xp is right to stop this code - I always - //wondered that it worked the old way at all) - if (Image->SizeOfData - i < 4) { //less than 4 byte to write? - if (TempBpp == 3) { //this branch is extra-SLOOOW - ReadI = - *Temp - | ((*(Temp + 1)) << 8) - | ((*(Temp + 2)) << 16); - } - else if (TempBpp == 1) - ReadI = *((ILubyte*)Temp); - else if (TempBpp == 2) - ReadI = Temp[0] | (Temp[1] << 8); - } - else - ReadI = Temp[0] | (Temp[1] << 8) | (Temp[2] << 16) | (Temp[3] << 24); - Temp += TempBpp; - - Image->Data[i] = ((ReadI & Head.RBitMask) >> RedR) << RedL; - - if(Image->Bpp >= 3) { - Image->Data[i+1] = ((ReadI & Head.GBitMask) >> GreenR) << GreenL; - Image->Data[i+2] = ((ReadI & Head.BBitMask) >> BlueR) << BlueL; - - if (Image->Bpp == 4) { - Image->Data[i+3] = ((ReadI & Head.RGBAlphaBitMask) >> AlphaR) << AlphaL; - if (AlphaL >= 7) { - Image->Data[i+3] = Image->Data[i+3] ? 0xFF : 0x00; - } - else if (AlphaL >= 4) { - Image->Data[i+3] = Image->Data[i+3] | (Image->Data[i+3] >> 4); - } - } - } - else if (Image->Bpp == 2) { - Image->Data[i+1] = ((ReadI & Head.RGBAlphaBitMask) >> AlphaR) << AlphaL; - if (AlphaL >= 7) { - Image->Data[i+1] = Image->Data[i+1] ? 0xFF : 0x00; - } - else if (AlphaL >= 4) { - Image->Data[i+1] = Image->Data[i+1] | (Image->Data[i+3] >> 4); - } - } - } - - return IL_TRUE; -} - - -// @TODO: Look at using the BSF/BSR operands for inline ASM here. -ILvoid GetBitsFromMask(ILuint Mask, ILuint *ShiftLeft, ILuint *ShiftRight) -{ - ILuint Temp, i; - - if (Mask == 0) { - *ShiftLeft = *ShiftRight = 0; - return; - } - - Temp = Mask; - for (i = 0; i < 32; i++, Temp >>= 1) { - if (Temp & 1) - break; - } - *ShiftRight = i; - - // Temp is preserved, so use it again: - for (i = 0; i < 8; i++, Temp >>= 1) { - if (!(Temp & 1)) - break; - } - *ShiftLeft = 8 - i; - - return; -} - - -#if 0 - -//dxt extension code. this works, but it's to much to enable - -//it for 1.6.8, especially because all these functions - -//are not documented. perhaps we'll use it later, perhaps - -//we'll delete it again, let's see. -ILubyte* ILAPIENTRY ilGetDxtcData() -{ - if (iCurImage == NULL) { - ilSetError(IL_INTERNAL_ERROR); - return NULL; - } - return iCurImage->DxtcData; -} - -ILvoid ilFreeSurfaceDxtcData() -{ - if (iCurImage != NULL && iCurImage->DxtcData != NULL) { - ifree(iCurImage->DxtcData); - iCurImage->DxtcData = NULL; - iCurImage->DxtcSize = 0; - iCurImage->DxtcFormat = IL_DXT_NO_COMP; - } -} - -ILvoid ilFreeImageDxtcData() -{ - ILint i, j; - ILuint ImgID = ilGetInteger(IL_CUR_IMAGE); - ILint ImgCount = ilGetInteger(IL_NUM_IMAGES); - ILint MipCount; - - for(i = 0; i <= ImgCount; ++i) { - ilBindImage(ImgID); - ilActiveImage(i); - - MipCount = ilGetInteger(IL_NUM_MIPMAPS); - for(j = 0; j <= MipCount; ++j) { - ilBindImage(ImgID); - ilActiveImage(i); - ilActiveMipmap(j); - - ilFreeSurfaceDxtcData(); - } - } -} - -/* - * This assumes DxtcData, DxtcFormat, width, height, and depth are valid - */ -ILAPI ILboolean ILAPIENTRY ilDxtcDataToSurface() -{ - if (iCurImage == NULL || iCurImage->DxtcData == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (!(iCurImage->DxtcFormat == IL_DXT1 || iCurImage->DxtcFormat == IL_DXT3 - || iCurImage->DxtcFormat == IL_DXT5)) { - ilSetError(IL_INVALID_PARAM); //TODO - return IL_FALSE; - } - - - //TODO: is this right for all dxt formats? works for - //dxt1, 3, 5 - iCurImage->Bpp = 4; - iCurImage->Bpc = 1; - iCurImage->Bps = iCurImage->Width*iCurImage->Bpp*iCurImage->Bpc; - iCurImage->SizeOfPlane = iCurImage->Height*iCurImage->Bps; - iCurImage->Format = IL_RGBA; - iCurImage->Type = IL_UNSIGNED_BYTE; - - if (iCurImage->SizeOfData != iCurImage->SizeOfPlane*iCurImage->Depth) { - iCurImage->SizeOfData = iCurImage->Depth*iCurImage->SizeOfPlane; - if (iCurImage->Data != NULL) - ifree(iCurImage->Data); - iCurImage->Data = NULL; - } - - if (iCurImage->Data == NULL) { - iCurImage->Data = ialloc(iCurImage->SizeOfData); - } - - Image = iCurImage; - Width = iCurImage->Width; - Height = iCurImage->Height; - Depth = iCurImage->Depth; - switch(iCurImage->DxtcFormat) - { - case IL_DXT1: CompFormat = PF_DXT1; break; - case IL_DXT3: CompFormat = PF_DXT3; break; - case IL_DXT5: CompFormat = PF_DXT5; break; - } - CompData = iCurImage->DxtcData; - Decompress(); //globals suck...fix this - - //TODO: origin should be set in Decompress()... - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - return ilFixCur(); -} - -ILAPI ILboolean ILAPIENTRY ilDxtcDataToImage() -{ - ILint i, j; - ILuint ImgID = ilGetInteger(IL_CUR_IMAGE); - ILint ImgCount = ilGetInteger(IL_NUM_IMAGES); - ILint MipCount; - ILboolean ret = IL_TRUE; - - for(i = 0; i <= ImgCount; ++i) { - ilBindImage(ImgID); - ilActiveImage(i); - - MipCount = ilGetInteger(IL_NUM_MIPMAPS); - for(j = 0; j <= MipCount; ++j) { - ilBindImage(ImgID); - ilActiveImage(i); - ilActiveMipmap(j); - - if (!ilDxtcDataToSurface()) - ret = IL_FALSE; - } - } - ilBindImage(ImgID); - - return ret; -} - -ILAPI ILboolean ILAPIENTRY ilSurfaceToDxtcData(ILenum Format) -{ - ILuint Size; - ILvoid* Data; - ilFreeSurfaceDxtcData(); - - Size = ilGetDXTCData(NULL, 0, Format); - if (Size == 0) { - return IL_FALSE; - } - - Data = ialloc(Size); - - if (Data == NULL) - return IL_FALSE; - - ilGetDXTCData(Data, Size, Format); - - //These have to be after the call to ilGetDXTCData() - iCurImage->DxtcData = Data; - iCurImage->DxtcFormat = Format; - iCurImage->DxtcSize = Size; - - return IL_TRUE; -} - -ILAPI ILboolean ILAPIENTRY ilImageToDxtcData(ILenum Format) -{ - ILint i, j; - ILuint ImgID = ilGetInteger(IL_CUR_IMAGE); - ILint ImgCount = ilGetInteger(IL_NUM_IMAGES); - ILint MipCount; - ILboolean ret = IL_TRUE; - - for(i = 0; i <= ImgCount; ++i) { - ilBindImage(ImgID); - ilActiveImage(i); - - MipCount = ilGetInteger(IL_NUM_MIPMAPS); - for(j = 0; j <= MipCount; ++j) { - ilBindImage(ImgID); - ilActiveImage(i); - ilActiveMipmap(j); - - if (!ilSurfaceToDxtcData(Format)) - ret = IL_FALSE; - } - } - - return ret; -} - -//works like ilTexImage(), ie. destroys mipmaps etc (which sucks, but -//is consistent. There should be a ilTexSurface() and ilTexSurfaceDxtc() -//functions as well, but for now this is sufficient) -ILAPI ILboolean ILAPIENTRY ilTexImageDxtc(ILint w, ILint h, ILint d, ILenum DxtFormat, const ILubyte* data) -{ - ILimage* Image = iCurImage; - - ILint xBlocks, yBlocks, BlockSize, LineSize, DataSize; - - - //The next few lines are copied from ilTexImage() and ilInitImage() - - //should be factored in more reusable functions... - - if (Image == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - //// - - // Not sure if we should be getting rid of the palette... - if (Image->Pal.Palette && Image->Pal.PalSize && Image->Pal.PalType != IL_PAL_NONE) { - ifree(Image->Pal.Palette); - } - - ilCloseImage(Image->Mipmaps); - ilCloseImage(Image->Next); - ilCloseImage(Image->Layers); - - if (Image->AnimList) ifree(Image->AnimList); - if (Image->Profile) ifree(Image->Profile); - if (Image->DxtcData) ifree(Image->DxtcData); - if (Image->Data) ifree(Image->Data); - - - //// - - memset (Image, 0, sizeof(ILimage)); - Image->Width = w; - Image->Height = h; - Image->Depth = d; - - //TODO: What about origin with dxtc data? - Image->Origin = IL_ORIGIN_LOWER_LEFT; - Image->Pal.PalType = IL_PAL_NONE; - - //alloc dxtc data buffer - xBlocks = (w + 3)/4; - yBlocks = (h + 3)/4; - if (DxtFormat == IL_DXT1) - BlockSize = 8; - else - BlockSize = 16; - - LineSize = xBlocks * BlockSize; - - DataSize = yBlocks * LineSize * d; - - Image->DxtcFormat = DxtFormat; - Image->DxtcSize = DataSize; - Image->DxtcData = ialloc(DataSize); - - if (Image->DxtcData == NULL) { - return IL_FALSE; - } - - if (data != NULL) - memcpy(Image->DxtcData, data, DataSize); - - return IL_TRUE; -} - - -/* ------------------------------------------------------------------- */ - -ILvoid iFlipColorBlock(ILubyte *data) -{ - ILubyte tmp; - - tmp = data[4]; - data[4] = data[7]; - data[7] = tmp; - - tmp = data[5]; - data[5] = data[6]; - data[6] = tmp; -} - -ILvoid iFlipSimpleAlphaBlock(ILushort *data) -{ - ILushort tmp; - - tmp = data[0]; - data[0] = data[3]; - data[3] = tmp; - - tmp = data[1]; - data[1] = data[2]; - data[2] = tmp; -} - -ILvoid iComplexAlphaHelper(ILubyte* Data) -{ - ILushort tmp[2]; - - //one 4 pixel line is 12 bit, copy each line into - //a ushort, swap them and copy back - tmp[0] = (Data[0] | (Data[1] << 8)) & 0xfff; - tmp[1] = ((Data[1] >> 4) | (Data[2] << 4)) & 0xfff; - - Data[0] = tmp[1]; - Data[1] = (tmp[1] >> 8) | (tmp[0] << 4); - Data[2] = tmp[0] >> 4; -} - -ILvoid iFlipComplexAlphaBlock(ILubyte *Data) -{ - ILubyte tmp[3]; - Data += 2; //Skip 'palette' - - //swap upper two rows with lower two rows - memcpy(tmp, Data, 3); - memcpy(Data, Data + 3, 3); - memcpy(Data + 3, tmp, 3); - - //swap 1st with 2nd row, 3rd with 4th - iComplexAlphaHelper(Data); - iComplexAlphaHelper(Data + 3); -} - -ILvoid iFlipDxt1(ILubyte* data, ILuint count) -{ - ILint i; - - for (i = 0; i < count; ++i) { - iFlipColorBlock(data); - data += 8; //advance to next block - } -} - -ILvoid iFlipDxt3(ILubyte* data, ILuint count) -{ - ILint i; - for (i = 0; i < count; ++i) { - iFlipSimpleAlphaBlock((ILushort*)data); - iFlipColorBlock(data + 8); - data += 16; //advance to next block - } -} - -ILvoid iFlipDxt5(ILubyte* data, ILuint count) -{ - ILint i; - for (i = 0; i < count; ++i) { - iFlipComplexAlphaBlock(data); - iFlipColorBlock(data + 8); - data += 16; //advance to next block - } -} - -ILvoid iFlip3dc(ILubyte* data, ILuint count) -{ - ILint i; - for (i = 0; i < count; ++i) { - iFlipComplexAlphaBlock(data); - iFlipComplexAlphaBlock(data + 8); - data += 16; //advance to next block - } -} - - -ILAPI ILvoid ILAPIENTRY ilFlipSurfaceDxtcData() -{ - ILint x, y, z; - ILuint BlockSize, LineSize; - ILubyte *Temp, *Runner, *Top, *Bottom; - ILint numXBlocks, numYBlocks; - ILvoid (*FlipBlocks)(ILubyte* data, ILuint count); - - if (iCurImage == NULL || iCurImage->DxtcData == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - numXBlocks = (iCurImage->Width + 3)/4; - numYBlocks = (iCurImage->Height + 3)/4; - - switch (iCurImage->DxtcFormat) - { - case IL_DXT1: - BlockSize = 8; - FlipBlocks = iFlipDxt1; - break; - case IL_DXT2: - case IL_DXT3: - BlockSize = 16; - FlipBlocks = iFlipDxt3; - break; - case IL_DXT4: - case IL_DXT5: - case IL_RXGB: - BlockSize = 16; - FlipBlocks = iFlipDxt5; - break; - case IL_3DC: - BlockSize = 16; - FlipBlocks = iFlip3dc; - break; - default: - ilSetError(IL_INVALID_PARAM); - return; - } - - LineSize = numXBlocks * BlockSize; - Temp = ialloc(LineSize); - - if (Temp == NULL) - return; - - Runner = iCurImage->DxtcData; - for (z = 0; z < iCurImage->Depth; ++z) { - Top = Runner; - Bottom = Runner + (numYBlocks - 1)*LineSize; - - for (y = 0; y < numYBlocks/2; ++y) { - //swap block row - memcpy(Temp, Top, LineSize); - memcpy(Top, Bottom, LineSize); - memcpy(Bottom, Temp, LineSize); - - - //swap blocks - FlipBlocks(Top, numXBlocks); - FlipBlocks(Bottom, numXBlocks); - - Top += LineSize; - Bottom -= LineSize; - } - - //middle line - if (numYBlocks % 2 != 0) - FlipBlocks(Top, numXBlocks); - - Runner += LineSize * numYBlocks; - } - - ifree(Temp); -} - -/**********************************************************************/ - -ILvoid iInvertDxt3Alpha(ILubyte *data) -{ - ILint i; - - for (i = 0; i < 8; ++i) { - /* - ILubyte b, t1, t2; - b = data[i]; - - t1 = b & 0xf; - t1 = 15 - t1; - t2 = b >> 4; - t2 = 15 - t2; - - data[i] = (t2 << 4) | t1; - */ - //simpler: - data[i] = ~data[i]; - } -} - -ILvoid iInvertDxt5Alpha(ILubyte *data) -{ - ILubyte a0, a1; - ILint i, j; - - a0 = data[0]; - a1 = data[1]; - - //a0 > a1 <=> 255 - a0 < 255 - a1. Because of this, - //a1 and a2 have to be swapped, and the indices - //have to be changed as well. - - //invert and swap alpha - data[0] = 255 - a1; - data[1] = 255 - a0; - data += 2; - - //fix indices - const ILubyte map1[] = { 1, 0, 7, 6, 5, 4, 3, 2 }; - const ILubyte map2[] = { 1, 0, 5, 4, 3, 2, 7, 6 }; - for (i = 0; i < 6; i += 3) { - ILuint in = data[i] | (data[i+1] << 8) | (data[i+2] << 16); - ILuint out = 0; - - for (j = 0; j < 24; j += 3) { - ILubyte b = (in >> j) & 0x7; - - if (a0 > a1) - b = map1[b]; - else - b = map2[b]; - - out |= b << j; - } - - data[i] = out; - data[i+1] = out >> 8; - data[i+2] = out >> 16; - } -} - -ILAPI ILvoid ILAPIENTRY ilInvertSurfaceDxtcDataAlpha() -{ - ILint i; - ILuint BlockSize; - ILubyte *Runner; - ILint numXBlocks, numYBlocks, numBlocks; - ILvoid (*InvertAlpha)(ILubyte* data); - - if (iCurImage == NULL || iCurImage->DxtcData == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - numXBlocks = (iCurImage->Width + 3)/4; - numYBlocks = (iCurImage->Height + 3)/4; - numBlocks = numXBlocks*numYBlocks*iCurImage->Depth; - BlockSize = 16; - - switch (iCurImage->DxtcFormat) - { - case IL_DXT3: - InvertAlpha = iInvertDxt3Alpha; - break; - case IL_DXT5: - InvertAlpha = iInvertDxt5Alpha; - break; - default: - //DXT2/4 are not supported yet because nobody - //uses them anyway and I would have to change - //the color blocks as well... - //DXT1 is not supported because DXT1 alpha is - //seldom used and it's not easily invertable. - ilSetError(IL_INVALID_PARAM); - return; - } - - Runner = iCurImage->DxtcData; - for (i = 0; i < numBlocks; ++i, Runner += BlockSize) { - InvertAlpha(Runner); - } -} -#endif //dxt extension - - - - - - -#endif//IL_NO_DDS diff --git a/win32/devil/src/il_devil.c b/win32/devil/src/il_devil.c deleted file mode 100644 index ffa6fdec5..000000000 --- a/win32/devil/src/il_devil.c +++ /dev/null @@ -1,1107 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/17/2008 -// -// Filename: src-IL/src/il_devil.c -// -// Description: Functions for working with the ILimage's and the current image -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include -#include -#include "il_manip.h" - -ILAPI ILboolean ILAPIENTRY ilInitImage(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data) -{ - ILubyte BpcType = ilGetBpcType(Type); - if (BpcType == 0) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - memset (Image, 0, sizeof(ILimage)); - - //// - if( Width == 0 ) Width = 1; - if( Height == 0 ) Height = 1; - if( Depth == 0 ) Depth = 1; - Image->Width = Width; - Image->Height = Height; - Image->Depth = Depth; - Image->Bpp = Bpp; - Image->Bpc = BpcType; - Image->Bps = Width * Bpp * Image->Bpc; - Image->SizeOfPlane = Image->Bps * Height; - Image->SizeOfData = Image->SizeOfPlane * Depth; - Image->Format = Format; - Image->Type = Type; - Image->Origin = IL_ORIGIN_LOWER_LEFT; - Image->Pal.PalType = IL_PAL_NONE; - Image->DxtcFormat = IL_DXT_NO_COMP; - Image->DxtcData = NULL; - - Image->Data = (ILubyte*)ialloc(Image->SizeOfData); - if (Image->Data == NULL) { - return IL_FALSE; - } - - if (Data != NULL) { - memcpy(Image->Data, Data, Image->SizeOfData); - } - - return IL_TRUE; -} - - - -// Creates a new ILimage based on the specifications given -ILAPI ILimage* ILAPIENTRY ilNewImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc) -{ - ILimage *Image; - - if (Bpp == 0 || Bpp > 4) { - return NULL; - } - - Image = (ILimage*)ialloc(sizeof(ILimage)); - if (Image == NULL) { - return NULL; - } - - if (!ilInitImage (Image, Width, Height, Depth, Bpp, ilGetFormatBpp(Bpp), ilGetTypeBpc(Bpc), NULL)) { - if (Image->Data != NULL) { - ifree(Image->Data); - } - ifree(Image); - return NULL; - } - - return Image; -} - -ILAPI ILimage* ILAPIENTRY ilNewImageFull(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data) -{ - ILimage *Image; - - if (Bpp == 0 || Bpp > 4) { - return NULL; - } - - Image = (ILimage*)ialloc(sizeof(ILimage)); - if (Image == NULL) { - return NULL; - } - - if (!ilInitImage (Image, Width, Height, Depth, Bpp, Format, Type, Data)) { - if (Image->Data != NULL) { - ifree(Image->Data); - } - ifree(Image); - return NULL; - } - - return Image; -} - - -//! Changes the current bound image to use these new dimensions (current data is destroyed). -ILboolean ILAPIENTRY ilTexImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data) -{ - return ilTexImage_(iCurImage, Width, Height, Depth, Bpp, Format, Type, Data); -} - - -// Internal version of ilTexImage. -ILAPI ILboolean ILAPIENTRY ilTexImage_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data) -{ - if (Image == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - //// - - // Not sure if we should be getting rid of the palette... - if (Image->Pal.Palette && Image->Pal.PalSize && Image->Pal.PalType != IL_PAL_NONE) { - ifree(Image->Pal.Palette); - } - - ilCloseImage(Image->Mipmaps); - ilCloseImage(Image->Next); - ilCloseImage(Image->Layers); - - if (Image->AnimList) ifree(Image->AnimList); - if (Image->Profile) ifree(Image->Profile); - if (Image->DxtcData) ifree(Image->DxtcData); - if (Image->Data) ifree(Image->Data); - - //// - - // Also check against format? - /*if (Width == 0 || Height == 0 || Depth == 0 || Bpp == 0) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - }*/ - - return ilInitImage(Image, Width, Height, Depth, Bpp, Format, Type, Data); -} - - -//! Uploads Data of the same size to replace the current image's data. -ILboolean ILAPIENTRY ilSetData(ILvoid *Data) -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - return ilTexSubImage_(iCurImage, Data); -} - - -// Internal version of ilTexSubImage. -ILAPI ILboolean ILAPIENTRY ilTexSubImage_(ILimage *Image, ILvoid *Data) -{ - if (Image == NULL || Data == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - if (!Image->Data) { - Image->Data = (ILubyte*)ialloc(Image->SizeOfData); - if (Image->Data == NULL) - return IL_FALSE; - } - memcpy(Image->Data, Data, Image->SizeOfData); - return IL_TRUE; -} - - -ILubyte* ILAPIENTRY ilGetData() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - return iCurImage->Data; -} - - -ILubyte* ILAPIENTRY ilGetPalette() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - return iCurImage->Pal.Palette; -} - - -//ILfloat ClearRed = 0.0f, ClearGreen = 0.0f, ClearBlue = 0.0f, ClearAlpha = 0.0f; - -// Changed to the colour of the Universe -// (http://www.newscientist.com/news/news.jsp?id=ns99991775) -// *(http://www.space.com/scienceastronomy/universe_color_020308.html)* -//ILfloat ClearRed = 0.269f, ClearGreen = 0.388f, ClearBlue = 0.342f, ClearAlpha = 0.0f; -static ILfloat ClearRed = 1.0f; -static ILfloat ClearGreen = 0.972549f; -static ILfloat ClearBlue = 0.90588f; -static ILfloat ClearAlpha = 0.0f; -static ILfloat ClearLum = 1.0f; - -ILvoid ILAPIENTRY ilClearColour(ILclampf Red, ILclampf Green, ILclampf Blue, ILclampf Alpha) -{ - // Clamp to 0.0f - 1.0f. - ClearRed = Red < 0.0f ? 0.0f : (Red > 1.0f ? 1.0f : Red); - ClearGreen = Green < 0.0f ? 0.0f : (Green > 1.0f ? 1.0f : Green); - ClearBlue = Blue < 0.0f ? 0.0f : (Blue > 1.0f ? 1.0f : Blue); - ClearAlpha = Alpha < 0.0f ? 0.0f : (Alpha > 1.0f ? 1.0f : Alpha); - - if ((Red == Green) && (Red == Blue) && (Green == Blue)) { - ClearLum = Red < 0.0f ? 0.0f : (Red > 1.0f ? 1.0f : Red); - } - else { - ClearLum = 0.212671f * ClearRed + 0.715160f * ClearGreen + 0.072169f * ClearBlue; - ClearLum = ClearLum < 0.0f ? 0.0f : (ClearLum > 1.0f ? 1.0f : ClearLum); - } - - return; -} - - -ILAPI ILvoid ILAPIENTRY ilGetClear(ILvoid *Colours, ILenum Format, ILenum Type) -{ - ILubyte *BytePtr; - ILushort *ShortPtr; - ILuint *IntPtr; - ILfloat *FloatPtr; - ILdouble *DblPtr; - - switch (Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - BytePtr = (ILubyte*)Colours; - switch (Format) - { - case IL_RGB: - BytePtr[0] = (ILubyte)(ClearRed * UCHAR_MAX); - BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX); - BytePtr[2] = (ILubyte)(ClearBlue * UCHAR_MAX); - break; - - case IL_RGBA: - BytePtr[0] = (ILubyte)(ClearRed * UCHAR_MAX); - BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX); - BytePtr[2] = (ILubyte)(ClearBlue * UCHAR_MAX); - BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX); - break; - - case IL_BGR: - BytePtr[2] = (ILubyte)(ClearRed * UCHAR_MAX); - BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX); - BytePtr[0] = (ILubyte)(ClearBlue * UCHAR_MAX); - BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX); - break; - - case IL_BGRA: - BytePtr[2] = (ILubyte)(ClearRed * UCHAR_MAX); - BytePtr[1] = (ILubyte)(ClearGreen * UCHAR_MAX); - BytePtr[0] = (ILubyte)(ClearBlue * UCHAR_MAX); - BytePtr[3] = (ILubyte)(ClearAlpha * UCHAR_MAX); - break; - - case IL_LUMINANCE: - BytePtr[0] = (ILubyte)(ClearAlpha * UCHAR_MAX); - break; - - case IL_LUMINANCE_ALPHA: - BytePtr[0] = (ILubyte)(ClearLum * UCHAR_MAX); - BytePtr[1] = (ILubyte)(ClearAlpha * UCHAR_MAX); - - case IL_COLOUR_INDEX: - BytePtr[0] = (ILubyte)(ClearAlpha * UCHAR_MAX); - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - ShortPtr = (ILushort*)Colours; - switch (Format) - { - case IL_RGB: - ShortPtr[0] = (ILushort)(ClearRed * USHRT_MAX); - ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX); - ShortPtr[2] = (ILushort)(ClearBlue * USHRT_MAX); - break; - - case IL_RGBA: - ShortPtr[0] = (ILushort)(ClearRed * USHRT_MAX); - ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX); - ShortPtr[2] = (ILushort)(ClearBlue * USHRT_MAX); - ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - case IL_BGR: - ShortPtr[2] = (ILushort)(ClearRed * USHRT_MAX); - ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX); - ShortPtr[0] = (ILushort)(ClearBlue * USHRT_MAX); - ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - case IL_BGRA: - ShortPtr[2] = (ILushort)(ClearRed * USHRT_MAX); - ShortPtr[1] = (ILushort)(ClearGreen * USHRT_MAX); - ShortPtr[0] = (ILushort)(ClearBlue * USHRT_MAX); - ShortPtr[3] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - case IL_LUMINANCE: - ShortPtr[0] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - case IL_LUMINANCE_ALPHA: - ShortPtr[0] = (ILushort)(ClearLum * USHRT_MAX); - ShortPtr[1] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - case IL_COLOUR_INDEX: - ShortPtr[0] = (ILushort)(ClearAlpha * USHRT_MAX); - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - IntPtr = (ILuint*)Colours; - switch (Format) - { - case IL_RGB: - IntPtr[0] = (ILuint)(ClearRed * UINT_MAX); - IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX); - IntPtr[2] = (ILuint)(ClearBlue * UINT_MAX); - break; - - case IL_RGBA: - IntPtr[0] = (ILuint)(ClearRed * UINT_MAX); - IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX); - IntPtr[2] = (ILuint)(ClearBlue * UINT_MAX); - IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - case IL_BGR: - IntPtr[2] = (ILuint)(ClearRed * UINT_MAX); - IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX); - IntPtr[0] = (ILuint)(ClearBlue * UINT_MAX); - IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - case IL_BGRA: - IntPtr[2] = (ILuint)(ClearRed * UINT_MAX); - IntPtr[1] = (ILuint)(ClearGreen * UINT_MAX); - IntPtr[0] = (ILuint)(ClearBlue * UINT_MAX); - IntPtr[3] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - case IL_LUMINANCE: - IntPtr[0] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - case IL_LUMINANCE_ALPHA: - IntPtr[0] = (ILuint)(ClearLum * UINT_MAX); - IntPtr[1] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - case IL_COLOUR_INDEX: - IntPtr[0] = (ILuint)(ClearAlpha * UINT_MAX); - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - break; - - case IL_FLOAT: - FloatPtr = (ILfloat*)Colours; - switch (Format) - { - case IL_RGB: - FloatPtr[0] = ClearRed; - FloatPtr[1] = ClearGreen; - FloatPtr[2] = ClearBlue; - break; - - case IL_RGBA: - FloatPtr[0] = ClearRed; - FloatPtr[1] = ClearGreen; - FloatPtr[2] = ClearBlue; - FloatPtr[3] = ClearAlpha; - break; - - case IL_BGR: - FloatPtr[2] = ClearRed; - FloatPtr[1] = ClearGreen; - FloatPtr[0] = ClearBlue; - FloatPtr[3] = ClearAlpha; - break; - - case IL_BGRA: - FloatPtr[2] = ClearRed; - FloatPtr[1] = ClearGreen; - FloatPtr[0] = ClearBlue; - FloatPtr[3] = ClearAlpha; - break; - - case IL_LUMINANCE: - FloatPtr[0] = ClearAlpha; - break; - - case IL_LUMINANCE_ALPHA: - FloatPtr[0] = ClearLum; - FloatPtr[0] = ClearAlpha; - break; - - case IL_COLOUR_INDEX: - FloatPtr[0] = ClearAlpha; - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - break; - - case IL_DOUBLE: - DblPtr = (ILdouble*)Colours; - switch (Format) - { - case IL_RGB: - DblPtr[0] = ClearRed; - DblPtr[1] = ClearGreen; - DblPtr[2] = ClearBlue; - break; - - case IL_RGBA: - DblPtr[0] = ClearRed; - DblPtr[1] = ClearGreen; - DblPtr[2] = ClearBlue; - DblPtr[3] = ClearAlpha; - break; - - case IL_BGR: - DblPtr[2] = ClearRed; - DblPtr[1] = ClearGreen; - DblPtr[0] = ClearBlue; - DblPtr[3] = ClearAlpha; - break; - - case IL_BGRA: - DblPtr[2] = ClearRed; - DblPtr[1] = ClearGreen; - DblPtr[0] = ClearBlue; - DblPtr[3] = ClearAlpha; - break; - - case IL_LUMINANCE: - DblPtr[0] = ClearAlpha; - break; - - case IL_LUMINANCE_ALPHA: - DblPtr[0] = ClearLum; - DblPtr[1] = ClearAlpha; - break; - - case IL_COLOUR_INDEX: - DblPtr[0] = ClearAlpha; - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - break; - - default: - ilSetError(IL_INTERNAL_ERROR); - return; - } - - return; -} - - -//! Clears the current bound image to the values specified in ilClearColour -ILboolean ILAPIENTRY ilClearImage() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - return ilClearImage_(iCurImage); -} - - -ILAPI ILboolean ILAPIENTRY ilClearImage_(ILimage *Image) -{ - ILuint i, c, NumBytes; - ILubyte Colours[32]; // Maximum is sizeof(double) * 4 = 32 - ILubyte *BytePtr; - ILushort *ShortPtr; - ILuint *IntPtr; - ILfloat *FloatPtr; - ILdouble *DblPtr; - - NumBytes = Image->Bpp * Image->Bpc; - ilGetClear(Colours, Image->Format, Image->Type); - - if (Image->Format != IL_COLOUR_INDEX) { - switch (Image->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - BytePtr = (ILubyte*)Colours; - for (c = 0; c < NumBytes; c += Image->Bpc) { - for (i = c; i < Image->SizeOfData; i += NumBytes) { - Image->Data[i] = BytePtr[c]; - } - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - ShortPtr = (ILushort*)Colours; - for (c = 0; c < NumBytes; c += Image->Bpc) { - for (i = c; i < Image->SizeOfData; i += NumBytes) { - *((ILushort*)(Image->Data + i)) = ShortPtr[c / Image->Bpc]; - } - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - IntPtr = (ILuint*)Colours; - for (c = 0; c < NumBytes; c += Image->Bpc) { - for (i = c; i < Image->SizeOfData; i += NumBytes) { - *((ILuint*)(Image->Data + i)) = IntPtr[c / Image->Bpc]; - } - } - break; - - case IL_FLOAT: - FloatPtr = (ILfloat*)Colours; - for (c = 0; c < NumBytes; c += Image->Bpc) { - for (i = c; i < Image->SizeOfData; i += NumBytes) { - *((ILfloat*)(Image->Data + i)) = FloatPtr[c / Image->Bpc]; - } - } - break; - - case IL_DOUBLE: - DblPtr = (ILdouble*)Colours; - for (c = 0; c < NumBytes; c += Image->Bpc) { - for (i = c; i < Image->SizeOfData; i += NumBytes) { - *((ILdouble*)(Image->Data + i)) = DblPtr[c / Image->Bpc]; - } - } - break; - } - } - else { - imemclear(Image->Data, Image->SizeOfData); - - if (Image->Pal.Palette) - ifree(Image->Pal.Palette); - Image->Pal.Palette = (ILubyte*)ialloc(4); - if (Image->Pal.Palette == NULL) { - return IL_FALSE; - } - - Image->Pal.PalType = IL_PAL_RGBA32; - Image->Pal.PalSize = 4; - - Image->Pal.Palette[0] = Colours[0] * UCHAR_MAX; - Image->Pal.Palette[1] = Colours[1] * UCHAR_MAX; - Image->Pal.Palette[2] = Colours[2] * UCHAR_MAX; - Image->Pal.Palette[3] = Colours[3] * UCHAR_MAX; - } - - return IL_TRUE; -} - - -//! Overlays the image found in Src on top of the current bound image at the coords specified. -ILboolean ILAPIENTRY ilOverlayImage(ILuint Source, ILint XCoord, ILint YCoord, ILint ZCoord) -{ - ILuint x, y, z, SrcIndex, DestIndex, ConvBps, ConvSizePlane; - ILint c; - ILimage *Dest;//, *Src; - ILubyte *Converted; - ILuint DestName = ilGetCurName(); - ILfloat FrontPer, BackPer; - ILenum DestOrigin, SrcOrigin; - ILuint StartX, StartY, StartZ, AlphaOff; - ILubyte *SrcTemp = NULL; - ILboolean DestFlipped = IL_FALSE; - - - if (DestName == 0 || iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { // Dest - DestFlipped = IL_TRUE; - ilFlipImage(); - } - - Dest = iCurImage; - DestOrigin = iCurImage->Origin; - ilBindImage(Source); - SrcOrigin = iCurImage->Origin; - - if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) { - SrcTemp = iGetFlipped(iCurImage); - if (SrcTemp == NULL) { - ilBindImage(DestName); - if (DestFlipped) - ilFlipImage(); - return IL_FALSE; - } - } - else { - SrcTemp = iCurImage->Data; - } - - if (Dest == NULL || iCurImage == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - Converted = (ILubyte*)ilConvertBuffer(iCurImage->SizeOfData, iCurImage->Format, Dest->Format, iCurImage->Type, Dest->Type, SrcTemp); - if (Converted == NULL) - return IL_FALSE; - - ConvBps = Dest->Bpp * iCurImage->Width; - ConvSizePlane = ConvBps * iCurImage->Height; - - StartX = XCoord >= 0 ? 0 : -XCoord; - StartY = YCoord >= 0 ? 0 : -YCoord; - StartZ = ZCoord >= 0 ? 0 : -ZCoord; - - if (iCurImage->Format == IL_RGBA || iCurImage->Format == IL_BGRA || iCurImage->Format == IL_LUMINANCE_ALPHA) { - if (iCurImage->Format == IL_LUMINANCE_ALPHA) - AlphaOff = 1; - else - AlphaOff = 3; - - for (z = StartZ; z < iCurImage->Depth && (ILint)z + ZCoord < (ILint)Dest->Depth; z++) { - for (y = StartY; y < iCurImage->Height && (ILint)y + YCoord < (ILint)Dest->Height; y++) { - for (x = StartX; x < iCurImage->Width && (ILint)x + XCoord < (ILint)Dest->Width; x++) { - SrcIndex = z * ConvSizePlane + y * ConvBps + x * Dest->Bpp; - DestIndex = (z + ZCoord) * Dest->SizeOfPlane + (y + YCoord) * Dest->Bps + (x + XCoord) * Dest->Bpp; - FrontPer = iCurImage->Data[z * iCurImage->SizeOfPlane + y * iCurImage->Bps + x * iCurImage->Bpp + AlphaOff] / 255.0f; - BackPer = 1.0f - FrontPer; - for (c = 0; c < iCurImage->Bpp - 1; c++) { - Dest->Data[DestIndex + c] = (ILubyte)(Converted[SrcIndex + c] * FrontPer - + Dest->Data[DestIndex + c] * BackPer); - } - // Keep the original alpha. - //Dest->Data[DestIndex + c + 1] = Dest->Data[DestIndex + c + 1]; - } - } - } - } - else { - for (z = StartZ; z < iCurImage->Depth && z + ZCoord < Dest->Depth; z++) { - for (y = StartY; y < iCurImage->Height && y + YCoord < Dest->Height; y++) { - for (x = StartX; x < iCurImage->Width && x + XCoord < Dest->Width; x++) { - for (c = 0; c < iCurImage->Bpp; c++) { - Dest->Data[(z + ZCoord) * Dest->SizeOfPlane + (y + YCoord) * Dest->Bps + (x + XCoord) * Dest->Bpp + c] = - Converted[z * ConvSizePlane + y * ConvBps + x * Dest->Bpp + c]; - } - } - } - } - } - - if (SrcTemp != iCurImage->Data) - ifree(SrcTemp); - - ilBindImage(DestName); - if (DestFlipped) - ilFlipImage(); - - ifree(Converted); - - return IL_TRUE; -} - -//@NEXT DestX,DestY,DestZ must be set to ILuint -ILboolean ILAPIENTRY ilBlit(ILuint Source, ILint DestX, ILint DestY, ILint DestZ, - ILuint SrcX, ILuint SrcY, ILuint SrcZ, - ILuint Width, ILuint Height, ILuint Depth) -{ - ILuint x, y, z, ConvBps, ConvSizePlane; - ILimage *Dest,*Src; - ILubyte *Converted; - ILuint DestName = ilGetCurName(); - ILuint c; - ILuint StartX, StartY, StartZ; - ILboolean DestFlipped = IL_FALSE; - ILubyte *SrcTemp; - ILfloat Back; - - // Check if the desiination image really exists - if( DestName == 0 || iCurImage == NULL ) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - Dest = iCurImage; - - // set the destination image to upper left origin - if( Dest->Origin == IL_ORIGIN_LOWER_LEFT ) { // Dest - DestFlipped = IL_TRUE; - ilFlipImage(); - } - //DestOrigin = Dest->Origin; - ilBindImage(Source); - - // Check if the source image really exists - if( iCurImage == NULL ) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - Src = iCurImage; - - //@TODO test if coordinates are inside the images (hard limit for source) - - // set the source image to upper left origin - if (Src->Origin == IL_ORIGIN_LOWER_LEFT) - { - SrcTemp = iGetFlipped(iCurImage); - if (SrcTemp == NULL) - { - ilBindImage(DestName); - if (DestFlipped) - ilFlipImage(); - return IL_FALSE; - } - } - else - { - SrcTemp = iCurImage->Data; - } - - // convert source image to match the destination image type and format - Converted = (ILubyte*)ilConvertBuffer(Src->SizeOfData, Src->Format, Dest->Format, Src->Type, Dest->Type, SrcTemp); - if (Converted == NULL) - return IL_FALSE; - - ConvBps = Dest->Bpp * Src->Width; - ConvSizePlane = ConvBps * Src->Height; - - //@NEXT in next version this would have to be removed since Dest* will be unsigned - StartX = DestX >= 0 ? 0 : -DestX; - StartY = DestY >= 0 ? 0 : -DestY; - StartZ = DestZ >= 0 ? 0 : -DestZ; - - // Limit the copy of data inside of the destination image - if (Width + DestX > Dest->Width) Width = Dest->Width - DestX; - if (Height + DestY > Dest->Height) Height = Dest->Height - DestY; - if (Depth + DestZ > Dest->Depth) Depth = Dest->Depth - DestZ; - - // non funziona con rgba - // In case of Alpha channelm the data is blended. Keeps the original alpha. - if( Src->Format == IL_RGBA || Src->Format == IL_BGRA || Src->Format == IL_LUMINANCE_ALPHA ) { - const ILuint bpp_without_alpha = Dest->Bpp - 1; - for( z = 0; z < Depth; z++ ) { - for( y = 0; y < Height; y++ ) { - for( x = 0; x < Width; x++ ) { - const ILuint SrcIndex = (z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp; - const ILuint DestIndex = (z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp; - const ILuint AlphaIdx = SrcIndex + bpp_without_alpha; - ILfloat Front = 0; - - switch (Dest->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - Front = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE); - break; - case IL_SHORT: - case IL_UNSIGNED_SHORT: - Front = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT); - break; - case IL_INT: - case IL_UNSIGNED_INT: - Front = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT); - break; - case IL_FLOAT: - Front = ((ILfloat*)Converted)[AlphaIdx]; - break; - case IL_DOUBLE: - Front = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]); - break; - } - Back = 1.0f - Front; - for (c = 0; c < bpp_without_alpha; c++) - { - Dest->Data[DestIndex + c] = - (ILubyte)(Converted[SrcIndex + c] * Front - + Dest->Data[DestIndex + c] * Back); - } - } - } - } - } else { - for( z = 0; z < Depth; z++ ) { - for( y = 0; y < Height; y++ ) { - for( x = 0; x < Width; x++ ) { - for( c = 0; c < Dest->Bpp; c++ ) { - Dest->Data[(z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp + c] = - Converted[(z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp + c]; - } - } - } - } - } - - if (SrcTemp != iCurImage->Data) - ifree(SrcTemp); - - ilBindImage(DestName); - if (DestFlipped) - ilFlipImage(); - - ifree(Converted); - - return IL_TRUE; -} - - -ILboolean iCopySubImage(ILimage *Dest, ILimage *Src) -{ - ILimage *DestTemp, *SrcTemp; - - DestTemp = Dest; - SrcTemp = Src; - - do { - ilCopyImageAttr(DestTemp, SrcTemp); - DestTemp->Data = (ILubyte*)ialloc(SrcTemp->SizeOfData); - if (DestTemp->Data == NULL) { - return IL_FALSE; - } - memcpy(DestTemp->Data, SrcTemp->Data, SrcTemp->SizeOfData); - - if (SrcTemp->Next) { - DestTemp->Next = (ILimage*)icalloc(1, sizeof(ILimage)); - if (!DestTemp->Next) { - return IL_FALSE; - } - } - else { - DestTemp->Next = NULL; - } - - DestTemp = DestTemp->Next; - SrcTemp = SrcTemp->Next; - } while (SrcTemp); - - return IL_TRUE; -} - -ILboolean iCopySubImages(ILimage *Dest, ILimage *Src) -{ - if (Src->Layers) { - Dest->Layers = (ILimage*)icalloc(1, sizeof(ILimage)); - if (!Dest->Layers) { - return IL_FALSE; - } - if (!iCopySubImage(Dest->Layers, Src->Layers)) - return IL_FALSE; - } - - if (Src->Mipmaps) { - Dest->Mipmaps = (ILimage*)icalloc(1, sizeof(ILimage)); - if (!Dest->Mipmaps) { - return IL_FALSE; - } - if (!iCopySubImage(Dest->Mipmaps, Src->Mipmaps)) - return IL_FALSE; - } - - if (Src->Next) { - Dest->Next = (ILimage*)icalloc(1, sizeof(ILimage)); - if (!Dest->Next) { - return IL_FALSE; - } - if (!iCopySubImage(Dest->Next, Src->Next)) - return IL_FALSE; - } - - return IL_TRUE; -} - - -// Copies everything but the Data from Src to Dest. -ILAPI ILboolean ILAPIENTRY ilCopyImageAttr(ILimage *Dest, ILimage *Src) -{ - if (Dest == NULL || Src == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (Dest->Pal.Palette && Dest->Pal.PalSize && Dest->Pal.PalType != IL_PAL_NONE) { - ifree(Dest->Pal.Palette); - Dest->Pal.Palette = NULL; - } - if (Dest->Layers) { - ilCloseImage(Dest->Layers); - Dest->Layers = NULL; - } - if (Dest->Mipmaps) { - ilCloseImage(Dest->Mipmaps); - Dest->Mipmaps = NULL; - } - if (Dest->Next) { - ilCloseImage(Dest->Next); - Dest->Next = NULL; - } - if (Dest->Profile) { - ifree(Dest->Profile); - Dest->Profile = NULL; - Dest->ProfileSize = 0; - } - if (Dest->DxtcData) { - ifree(Dest->DxtcData); - Dest->DxtcData = NULL; - Dest->DxtcFormat = IL_DXT_NO_COMP; - Dest->DxtcSize = 0; - } - - if (Src->AnimList && Src->AnimSize) { - Dest->AnimList = (ILuint*)ialloc(Src->AnimSize * sizeof(ILuint)); - if (Dest->AnimList == NULL) { - return IL_FALSE; - } - memcpy(Dest->AnimList, Src->AnimList, Src->AnimSize * sizeof(ILuint)); - } - if (Src->Profile) { - Dest->Profile = (ILubyte*)ialloc(Src->ProfileSize); - if (Dest->Profile == NULL) { - return IL_FALSE; - } - memcpy(Dest->Profile, Src->Profile, Src->ProfileSize); - Dest->ProfileSize = Src->ProfileSize; - } - if (Src->Pal.Palette) { - Dest->Pal.Palette = (ILubyte*)ialloc(Src->Pal.PalSize); - if (Dest->Pal.Palette == NULL) { - return IL_FALSE; - } - memcpy(Dest->Pal.Palette, Src->Pal.Palette, Src->Pal.PalSize); - } - else { - Dest->Pal.Palette = NULL; - } - - Dest->Pal.PalSize = Src->Pal.PalSize; - Dest->Pal.PalType = Src->Pal.PalType; - Dest->Width = Src->Width; - Dest->Height = Src->Height; - Dest->Depth = Src->Depth; - Dest->Bpp = Src->Bpp; - Dest->Bpc = Src->Bpc; - Dest->Bps = Src->Bps; - Dest->SizeOfPlane = Src->SizeOfPlane; - Dest->SizeOfData = Src->SizeOfData; - Dest->Format = Src->Format; - Dest->Type = Src->Type; - Dest->Origin = Src->Origin; - Dest->Duration = Src->Duration; - Dest->CubeFlags = Src->CubeFlags; - Dest->AnimSize = Src->AnimSize; - Dest->OffX = Src->OffX; - Dest->OffY = Src->OffY; - - return IL_TRUE/*iCopySubImages(Dest, Src)*/; -} - - -//! Copies everything from Src to the current bound image. -ILboolean ILAPIENTRY ilCopyImage(ILuint Src) -{ - ILuint DestName = ilGetCurName(); - ILimage *DestImage = iCurImage, *SrcImage; - - if (iCurImage == NULL || DestName == 0) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - ilBindImage(Src); - SrcImage = iCurImage; - ilBindImage(DestName); - ilTexImage(SrcImage->Width, SrcImage->Height, SrcImage->Depth, SrcImage->Bpp, SrcImage->Format, SrcImage->Type, SrcImage->Data); - ilCopyImageAttr(DestImage, SrcImage); - - return IL_TRUE; -} - - -// Creates a copy of Src and returns it. -ILAPI ILimage* ILAPIENTRY ilCopyImage_(ILimage *Src) -{ - ILimage *Dest; - - if (Src == NULL) { - ilSetError(IL_INVALID_PARAM); - return NULL; - } - - Dest = ilNewImage(Src->Width, Src->Height, Src->Depth, Src->Bpp, Src->Bpc); - if (Dest == NULL) { - return NULL; - } - - if (ilCopyImageAttr(Dest, Src) == IL_FALSE) - return NULL; - - memcpy(Dest->Data, Src->Data, Src->SizeOfData); - - return Dest; -} - - -ILuint ILAPIENTRY ilCloneCurImage() -{ - ILuint Id; - ILimage *CurImage; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return 0; - } - - ilGenImages(1, &Id); - if (Id == 0) - return 0; - - CurImage = iCurImage; - - ilBindImage(Id); - ilTexImage(CurImage->Width, CurImage->Height, CurImage->Depth, CurImage->Bpp, CurImage->Format, CurImage->Type, CurImage->Data); - ilCopyImageAttr(iCurImage, CurImage); - - iCurImage = CurImage; - - return Id; -} - - -// Like ilTexImage but doesn't destroy the palette. -ILAPI ILboolean ILAPIENTRY ilResizeImage(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc) -{ - if (Image == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (Image->Data != NULL) - ifree(Image->Data); - - Image->Depth = Depth; - Image->Width = Width; - Image->Height = Height; - Image->Bpp = Bpp; - Image->Bpc = Bpc; - Image->Bps = Bpp * Bpc * Width; - Image->SizeOfPlane = Image->Bps * Height; - Image->SizeOfData = Image->SizeOfPlane * Depth; - - Image->Data = (ILubyte*)ialloc(Image->SizeOfData); - if (Image->Data == NULL) { - return IL_FALSE; - } - - return IL_TRUE; -} diff --git a/win32/devil/src/il_doom.c b/win32/devil/src/il_doom.c deleted file mode 100644 index 6298465bd..000000000 --- a/win32/devil/src/il_doom.c +++ /dev/null @@ -1,276 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 06/07/2007 -// -// Filename: src-IL/src/il_doom.c -// -// Description: Reads Doom textures and flats -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_DOOM -#include "il_manip.h" -#include "il_pal.h" -#include "il_doompal.h" - - -ILboolean iLoadDoomInternal(void); -ILboolean iLoadDoomFlatInternal(void); - - -// -// READ A DOOM IMAGE -// - -//! Reads a Doom file -ILboolean ilLoadDoom(ILconst_string FileName) -{ - ILHANDLE DoomFile; - ILboolean bDoom = IL_FALSE; - - // Not sure of any kind of specified extension...maybe .lmp? - /*if (!iCheckExtension(FileName, "")) { - ilSetError(IL_INVALID_EXTENSION); - return NULL; - }*/ - - DoomFile = iopenr(FileName); - if (DoomFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bDoom; - } - - bDoom = ilLoadDoomF(DoomFile); - icloser(DoomFile); - - return bDoom; -} - - -//! Reads an already-opened Doom file -ILboolean ilLoadDoomF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadDoomInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Doom texture -ILboolean ilLoadDoomL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadDoomInternal(); -} - - -// From the DTE sources (mostly by Denton Woods with corrections by Randy Heit) -ILboolean iLoadDoomInternal() -{ - ILshort width, height, graphic_header[2], column_loop, row_loop; - ILint column_offset, pointer_position, first_pos; - ILubyte post, topdelta, length; - ILubyte *NewData; - ILuint i; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - first_pos = itell(); // Needed to go back to the offset table - width = GetLittleShort(); - height = GetLittleShort(); - graphic_header[0] = GetLittleShort(); // Not even used - graphic_header[1] = GetLittleShort(); // Not even used - - if (!ilTexImage(width, height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; - iCurImage->Pal.PalType = IL_PAL_RGB24; - memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); - - // 247 is always the transparent colour (usually cyan) - memset(iCurImage->Data, 247, iCurImage->SizeOfData); - - for (column_loop = 0; column_loop < width; column_loop++) { - column_offset = GetLittleInt(); - pointer_position = itell(); - iseek(first_pos + column_offset, IL_SEEK_SET); - - while (1) { - if (iread(&topdelta, 1, 1) != 1) - return IL_FALSE; - if (topdelta == 255) - break; - if (iread(&length, 1, 1) != 1) - return IL_FALSE; - if (iread(&post, 1, 1) != 1) - return IL_FALSE; // Skip extra byte for scaling - - for (row_loop = 0; row_loop < length; row_loop++) { - if (iread(&post, 1, 1) != 1) - return IL_FALSE; - if (row_loop + topdelta < height) - iCurImage->Data[(row_loop+topdelta) * width + column_loop] = post; - } - iread(&post, 1, 1); // Skip extra scaling byte - } - - iseek(pointer_position, IL_SEEK_SET); - } - - // Converts palette entry 247 (cyan) to transparent. - if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { - NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); - if (NewData == NULL) { - return IL_FALSE; - } - - for (i = 0; i < iCurImage->SizeOfData; i++) { - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; - } - - if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, - 4, IL_RGBA, iCurImage->Type, NewData)) { - ifree(NewData); - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - ifree(NewData); - } - - ilFixImage(); - - return IL_TRUE; -} - - -// -// READ A DOOM FLAT -// - -//! Reads a Doom flat file -ILboolean ilLoadDoomFlat(ILconst_string FileName) -{ - ILHANDLE FlatFile; - ILboolean bFlat = IL_FALSE; - - // Not sure of any kind of specified extension...maybe .lmp? - /*if (!iCheckExtension(FileName, "")) { - ilSetError(IL_INVALID_EXTENSION); - return NULL; - }*/ - - FlatFile = iopenr(FileName); - if (FlatFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bFlat; - } - - bFlat = ilLoadDoomF(FlatFile); - icloser(FlatFile); - - return bFlat; -} - - -//! Reads an already-opened Doom flat file -ILboolean ilLoadDoomFlatF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadDoomFlatInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Doom flat -ILboolean ilLoadDoomFlatL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadDoomFlatInternal(); -} - - -// Basically just ireads 4096 bytes and copies the palette -ILboolean iLoadDoomFlatInternal() -{ - ILubyte *NewData; - ILuint i; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!ilTexImage(64, 64, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; - iCurImage->Pal.PalType = IL_PAL_RGB24; - memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); - - if (iread(iCurImage->Data, 1, 4096) != 4096) - return IL_FALSE; - - if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { - NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); - if (NewData == NULL) { - return IL_FALSE; - } - - for (i = 0; i < iCurImage->SizeOfData; i++) { - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; - } - - if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, - 4, IL_RGBA, iCurImage->Type, NewData)) { - ifree(NewData); - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - ifree(NewData); - } - - ilFixImage(); - - return IL_TRUE; -} - - -#endif diff --git a/win32/devil/src/il_endian.c b/win32/devil/src/il_endian.c deleted file mode 100644 index b620af4c8..000000000 --- a/win32/devil/src/il_endian.c +++ /dev/null @@ -1,277 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Last modified: 12/06/2006 -// -// Filename: src-IL/src/il_endian.c -// -// Description: Takes care of endian issues -// -//----------------------------------------------------------------------------- - - -#define IL_ENDIAN_C - -#include "il_endian.h" - -ILvoid EndianSwapData(void *_Image) { - ILuint i; - ILubyte *temp, *s, *d; - ILushort *ShortS, *ShortD; - ILuint *IntS, *IntD; - ILfloat *FltS, *FltD; - ILdouble *DblS, *DblD; - - ILimage *Image = (ILimage*)_Image; - - switch (Image->Type) { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - switch (Image->Bpp) { - case 3: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - s = Image->Data; - d = temp; - - for( i = Image->Width * Image->Height; i > 0; i-- ) { - *d++ = *(s+2); - *d++ = *(s+1); - *d++ = *s; - s += 3; - } - - ifree(Image->Data); - Image->Data = temp; - break; - - case 4: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - s = Image->Data; - d = temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *d++ = *(s+3); - *d++ = *(s+2); - *d++ = *(s+1); - *d++ = *s; - s += 4; - } - - ifree(Image->Data); - Image->Data = temp; - break; - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - switch (Image->Bpp) { - case 3: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - ShortS = (ILushort*)Image->Data; - ShortD = (ILushort*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *ShortD = *ShortS++; iSwapUShort(ShortD++); - *ShortD = *ShortS++; iSwapUShort(ShortD++); - *ShortD = *ShortS++; iSwapUShort(ShortD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - - case 4: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - ShortS = (ILushort*)Image->Data; - ShortD = (ILushort*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *ShortD = *ShortS++; iSwapUShort(ShortD++); - *ShortD = *ShortS++; iSwapUShort(ShortD++); - *ShortD = *ShortS++; iSwapUShort(ShortD++); - *ShortD = *ShortS++; iSwapUShort(ShortD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - } - break; - - case IL_INT: - case IL_UNSIGNED_INT: - switch (Image->Bpp) - { - case 3: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - IntS = (ILuint*)Image->Data; - IntD = (ILuint*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *IntD = *IntS++; iSwapUInt(IntD++); - *IntD = *IntS++; iSwapUInt(IntD++); - *IntD = *IntS++; iSwapUInt(IntD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - - case 4: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - IntS = (ILuint*)Image->Data; - IntD = (ILuint*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *IntD = *IntS++; iSwapUInt(IntD++); - *IntD = *IntS++; iSwapUInt(IntD++); - *IntD = *IntS++; iSwapUInt(IntD++); - *IntD = *IntS++; iSwapUInt(IntD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - } - break; - - case IL_FLOAT: - switch (Image->Bpp) - { - case 3: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - FltS = (ILfloat*)Image->Data; - FltD = (ILfloat*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *FltD = *FltS++; iSwapFloat(FltD++); - *FltD = *FltS++; iSwapFloat(FltD++); - *FltD = *FltS++; iSwapFloat(FltD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - - case 4: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - FltS = (ILfloat*)Image->Data; - FltD = (ILfloat*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *FltD = *FltS++; iSwapFloat(FltD++); - *FltD = *FltS++; iSwapFloat(FltD++); - *FltD = *FltS++; iSwapFloat(FltD++); - *FltD = *FltS++; iSwapFloat(FltD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - } - break; - - case IL_DOUBLE: - switch (Image->Bpp) - { - case 3: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - DblS = (ILdouble*)Image->Data; - DblD = (ILdouble*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *DblD = *DblS++; iSwapDouble(DblD++); - *DblD = *DblS++; iSwapDouble(DblD++); - *DblD = *DblS++; iSwapDouble(DblD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - - case 4: - temp = (ILubyte*)ialloc(Image->SizeOfData); - if (temp == NULL) - return; - DblS = (ILdouble*)Image->Data; - DblD = (ILdouble*)temp; - - for (i = Image->Width * Image->Height; i > 0; i--) { - *DblD = *DblS++; iSwapDouble(DblD++); - *DblD = *DblS++; iSwapDouble(DblD++); - *DblD = *DblS++; iSwapDouble(DblD++); - *DblD = *DblS++; iSwapDouble(DblD++); - } - - ifree(Image->Data); - Image->Data = temp; - break; - } - break; - } - - if( iCurImage->Format == IL_COLOUR_INDEX ) { - switch (iCurImage->Pal.PalType) { - case IL_PAL_RGB24: - case IL_PAL_BGR24: - temp = (ILubyte*)ialloc(Image->Pal.PalSize); - if (temp == NULL) - return; - s = Image->Pal.Palette; - d = temp; - - for (i = Image->Pal.PalSize / 3; i > 0; i--) { - *d++ = *(s+2); - *d++ = *(s+1); - *d++ = *s; - s += 3; - } - - ifree(Image->Pal.Palette); - Image->Pal.Palette = temp; - break; - - case IL_PAL_RGBA32: - case IL_PAL_RGB32: - case IL_PAL_BGRA32: - case IL_PAL_BGR32: - temp = (ILubyte*)ialloc(Image->Pal.PalSize); - if (temp == NULL) - return; - s = Image->Pal.Palette; - d = temp; - - for (i = Image->Pal.PalSize / 4; i > 0; i--) { - *d++ = *(s+3); - *d++ = *(s+2); - *d++ = *(s+1); - *d++ = *s; - s += 4; - } - - ifree(Image->Pal.Palette); - Image->Pal.Palette = temp; - break; - } - } - return; -} diff --git a/win32/devil/src/il_error.c b/win32/devil/src/il_error.c deleted file mode 100644 index 751363184..000000000 --- a/win32/devil/src/il_error.c +++ /dev/null @@ -1,56 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 06/02/2007 -// -// Filename: src-IL/src/il_error.c -// -// Description: The error functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" - - -#define IL_ERROR_STACK_SIZE 32 // Needed elsewhere? - - -ILenum ilErrorNum[IL_ERROR_STACK_SIZE]; -ILint ilErrorPlace = (-1); - - -// Sets the current error -// If you go past the stack size for this, it cycles the errors, almost like a LRU algo. -ILAPI ILvoid ILAPIENTRY ilSetError(ILenum Error) -{ - ILuint i; - - ilErrorPlace++; - if (ilErrorPlace >= IL_ERROR_STACK_SIZE) { - for (i = 0; i < IL_ERROR_STACK_SIZE - 2; i++) { - ilErrorNum[i] = ilErrorNum[i+1]; - } - ilErrorPlace = IL_ERROR_STACK_SIZE - 1; - } - ilErrorNum[ilErrorPlace] = Error; - - return; -} - - -//! Gets the last error on the error stack -ILenum ILAPIENTRY ilGetError(void) -{ - ILenum ilReturn; - - if (ilErrorPlace >= 0) { - ilReturn = ilErrorNum[ilErrorPlace]; - ilErrorPlace--; - } - else - ilReturn = IL_NO_ERROR; - - return ilReturn; -} diff --git a/win32/devil/src/il_fastconv.c b/win32/devil/src/il_fastconv.c deleted file mode 100644 index 1103a8788..000000000 --- a/win32/devil/src/il_fastconv.c +++ /dev/null @@ -1,290 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 07/07/2006 -// -// Filename: src-IL/src/il_fastconv.c -// -// Description: Converts between several image formats -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifdef ALTIVEC_GCC -#include "altivec_typeconversion.h" -#endif - -ILboolean iFastConvert(ILenum DestFormat) -{ - ILubyte *BytePtr = iCurImage->Data; - ILushort *ShortPtr = (ILushort*)iCurImage->Data; - ILuint *IntPtr = (ILuint*)iCurImage->Data; - ILfloat *FloatPtr = (ILfloat*)iCurImage->Data; - ILdouble *DblPtr = (ILdouble*)iCurImage->Data; - -#ifndef ALTIVEC_GCC - ILuint SizeOfData, i=0; - ILubyte TempByte = 0; - ILushort TempShort = 0; - ILuint TempInt = 0; - ILfloat TempFloat = 0; - ILdouble TempDbl = 0; -#endif - - switch (DestFormat) - { - case IL_RGB: - case IL_BGR: - if (iCurImage->Format != IL_RGB && iCurImage->Format != IL_BGR) - return IL_FALSE; - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - #ifdef ALTIVEC_GCC - abc2cba_byte(BytePtr,iCurImage->SizeOfData,BytePtr); - #else - SizeOfData = iCurImage->SizeOfData / 3; - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, BytePtr - mov ecx, SizeOfData - L1: - mov al,[ebx+0] - xchg al,[ebx+2] - mov [ebx+0],al - add ebx,3 - loop L1 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempByte = BytePtr[0]; - BytePtr[0] = BytePtr[2]; - BytePtr[2] = TempByte; - BytePtr += 3; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - #ifdef ALTIVEC_GCC - abc2cba_short(ShortPtr,iCurImage->SizeOfData,ShortPtr); - #else - SizeOfData = iCurImage->SizeOfData / 6; // 3*2 - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, ShortPtr - mov ecx, SizeOfData - L2: - mov ax,[ebx+0] - xchg ax,[ebx+4] - mov [ebx+0],ax - add ebx,6 - loop L2 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempShort = ShortPtr[0]; - ShortPtr[0] = ShortPtr[2]; - ShortPtr[2] = TempShort; - ShortPtr += 3; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_INT: - case IL_UNSIGNED_INT: - #ifdef ALTIVEC_GCC - abc2cba_int(IntPtr,iCurImage->SizeOfData,IntPtr); - #else - SizeOfData = iCurImage->SizeOfData / 12; // 3*4 - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, IntPtr - mov ecx, SizeOfData - L3: - mov eax,[ebx+0] - xchg eax,[ebx+8] - mov [ebx+0],ax - add ebx,12 - loop L3 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempInt = IntPtr[0]; - IntPtr[0] = IntPtr[2]; - IntPtr[2] = TempInt; - IntPtr += 3; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abc2cba_float(FloatPtr,iCurImage->SizeOfData,FloatPtr); - #else - SizeOfData = iCurImage->SizeOfData / 12; // 3*4 - for (i = 0; i < SizeOfData; i++) { - TempFloat = FloatPtr[0]; - FloatPtr[0] = FloatPtr[2]; - FloatPtr[2] = TempFloat; - FloatPtr += 3; - } - #endif - return IL_TRUE; - - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abc2cba_double(DblPtr,iCurImage->SizeOfData,DblPtr); - #else - SizeOfData = iCurImage->SizeOfData / 24; // 3*8 - for (i = 0; i < SizeOfData; i++) { - TempDbl = DblPtr[0]; - DblPtr[0] = DblPtr[2]; - DblPtr[2] = TempDbl; - DblPtr += 3; - } - #endif - return IL_TRUE; - } - break; - - case IL_RGBA: - case IL_BGRA: - if (iCurImage->Format != IL_RGBA && iCurImage->Format != IL_BGRA) - return IL_FALSE; - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - #ifdef ALTIVEC_GCC - abcd2cbad_byte(BytePtr,iCurImage->SizeOfData,BytePtr); - #else - SizeOfData = iCurImage->SizeOfData / 4; - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, BytePtr - mov ecx, SizeOfData - L4: - mov eax,[ebx] - bswap eax - ror eax,8 - mov [ebx], eax - add ebx,4 - loop L4 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempByte = BytePtr[0]; - BytePtr[0] = BytePtr[2]; - BytePtr[2] = TempByte; - BytePtr += 4; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - #ifdef ALTIVEC_GCC - abcd2cbad_short(ShortPtr,iCurImage->SizeOfData,ShortPtr); - #else - SizeOfData = iCurImage->SizeOfData / 8; // 4*2 - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, ShortPtr - mov ecx, SizeOfData - L5: - mov ax,[ebx+0] - xchg ax,[ebx+4] - mov [ebx+0],ax - add ebx,8 - loop L5 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempShort = ShortPtr[0]; - ShortPtr[0] = ShortPtr[2]; - ShortPtr[2] = TempShort; - ShortPtr += 4; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_INT: - case IL_UNSIGNED_INT: - #ifdef ALTIVEC_GCC - abcd2cbad_int(IntPtr,iCurImage->SizeOfData,IntPtr); - #else - SizeOfData = iCurImage->SizeOfData / 16; // 4*4 - #ifdef USE_WIN32_ASM - __asm - { - mov ebx, IntPtr - mov ecx, SizeOfData - L6: - mov eax,[ebx+0] - xchg eax,[ebx+8] - mov [ebx+0],ax - add ebx,16 - loop L6 - } - #else - for (i = 0; i < SizeOfData; i++) { - TempInt = IntPtr[0]; - IntPtr[0] = IntPtr[2]; - IntPtr[2] = TempInt; - IntPtr += 4; - } - #endif//USE_WIN32_ASM - #endif - return IL_TRUE; - - case IL_FLOAT: - #ifdef ALTIVEC_GCC - abcd2cbad_float(FloatPtr,iCurImage->SizeOfData,FloatPtr); - #else - SizeOfData = iCurImage->SizeOfData / 16; // 4*4 - for (i = 0; i < SizeOfData; i++) { - TempFloat = FloatPtr[0]; - FloatPtr[0] = FloatPtr[2]; - FloatPtr[2] = TempFloat; - FloatPtr += 4; - } - #endif - return IL_TRUE; - - case IL_DOUBLE: - #ifdef ALTIVEC_GCC - abcd2cbad_double(DblPtr,iCurImage->SizeOfData,DblPtr); - #else - SizeOfData = iCurImage->SizeOfData / 32; // 4*8 - for (i = 0; i < SizeOfData; i++) { - TempDbl = DblPtr[0]; - DblPtr[0] = DblPtr[2]; - DblPtr[2] = TempDbl; - DblPtr += 4; - } - #endif - return IL_TRUE; - } - } - - - return IL_FALSE; -} - diff --git a/win32/devil/src/il_files.c b/win32/devil/src/il_files.c deleted file mode 100644 index 679d64cfa..000000000 --- a/win32/devil/src/il_files.c +++ /dev/null @@ -1,699 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 06/02/2007 -// -// Filename: src-IL/src/il_files.c -// -// Description: File handling for DevIL -// -//----------------------------------------------------------------------------- - - -#define __FILES_C -#include "il_internal.h" -#include - - -// All specific to the next set of functions -ILboolean ILAPIENTRY iEofFile(void); -ILboolean ILAPIENTRY iEofLump(void); -ILint ILAPIENTRY iGetcFile(void); -ILint ILAPIENTRY iGetcLump(void); -ILuint ILAPIENTRY iReadFile(ILvoid *Buffer, ILuint Size, ILuint Number); -ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, const ILuint Size, const ILuint Number); -ILuint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode); -ILuint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode); -ILuint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode); -ILuint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode); -ILuint ILAPIENTRY iTellRFile(void); -ILuint ILAPIENTRY iTellRLump(void); -ILuint ILAPIENTRY iTellWFile(void); -ILuint ILAPIENTRY iTellWLump(void); -ILint ILAPIENTRY iPutcFile(ILubyte Char); -ILint ILAPIENTRY iPutcLump(ILubyte Char); -ILint ILAPIENTRY iWriteFile(const ILvoid *Buffer, ILuint Size, ILuint Number); -ILint ILAPIENTRY iWriteLump(const ILvoid *Buffer, ILuint Size, ILuint Number); -ILHANDLE FileRead = NULL, FileWrite = NULL; -const ILvoid *ReadLump = NULL; -ILvoid *WriteLump = NULL; -ILuint ReadLumpPos = 0, ReadLumpSize = 0, ReadFileStart = 0, WriteFileStart = 0; -ILuint WriteLumpPos = 0, WriteLumpSize = 0; - -fGetcProc GetcProcCopy; -fReadProc ReadProcCopy; -fSeekRProc SeekProcCopy; -fTellRProc TellProcCopy; -ILHANDLE (ILAPIENTRY *iopenCopy)(ILstring); -ILvoid (ILAPIENTRY *icloseCopy)(ILHANDLE); - -ILboolean UseCache = IL_FALSE; -ILubyte *Cache = NULL; -ILuint CacheSize, CachePos, CacheStartPos, CacheBytesRead; - - -/*// Just preserves the current read functions and replaces -// the current read functions with the default read funcs. -ILvoid ILAPIENTRY iPreserveReadFuncs() -{ - // Create backups - GetcProcCopy = GetcProc; - ReadProcCopy = ReadProc; - SeekProcCopy = SeekRProc; - TellProcCopy = TellRProc; - iopenCopy = iopenr; - icloseCopy = icloser; - - // Set the standard procs to read - ilResetRead(); - - return; -} - - -// Restores the read functions - must be used after iPreserveReadFuncs(). -ILvoid ILAPIENTRY iRestoreReadFuncs() -{ - GetcProc = GetcProcCopy; - ReadProc = ReadProcCopy; - SeekRProc = SeekProcCopy; - TellRProc = TellProcCopy; - iopenr = iopenCopy; - icloser = icloseCopy; - - return; -}*/ - - -// Next 7 functions are the default read functions - -ILHANDLE ILAPIENTRY iDefaultOpenR(ILconst_string FileName) -{ -#ifndef _UNICODE - return (ILHANDLE)fopen(FileName, "rb"); -#else - return (ILHANDLE)_wfopen(FileName, L"rb"); -#endif//UNICODE -} - - -ILvoid ILAPIENTRY iDefaultCloseR(ILHANDLE Handle) -{ - fclose((FILE*)Handle); - return; -} - - -ILboolean ILAPIENTRY iDefaultEof(ILHANDLE Handle) -{ - ILuint OrigPos, FileSize; - - // Find out the filesize for checking for the end of file - OrigPos = itell(); - iseek(0, IL_SEEK_END); - FileSize = itell(); - iseek(OrigPos, IL_SEEK_SET); - - if (itell() >= FileSize) - return IL_TRUE; - return IL_FALSE; -} - - -ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle) -{ - ILint Val; - - if (!UseCache) { - Val = fgetc((FILE*)Handle); - if (Val == IL_EOF) - ilSetError(IL_FILE_READ_ERROR); - } - else { - Val = 0; - if (iread(&Val, 1, 1) != 1) - return IL_EOF; - } - return Val; -} - - -ILint ILAPIENTRY iDefaultRead(ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle) -{ - return fread(Buffer, Size, Number, (FILE*)Handle); -} - - -ILint ILAPIENTRY iDefaultRSeek(ILHANDLE Handle, ILint Offset, ILint Mode) -{ - return fseek((FILE*)Handle, Offset, Mode); -} - - -ILint ILAPIENTRY iDefaultWSeek(ILHANDLE Handle, ILint Offset, ILint Mode) -{ - return fseek((FILE*)Handle, Offset, Mode); -} - - -ILint ILAPIENTRY iDefaultRTell(ILHANDLE Handle) -{ - return ftell((FILE*)Handle); -} - - -ILint ILAPIENTRY iDefaultWTell(ILHANDLE Handle) -{ - return ftell((FILE*)Handle); -} - - -ILHANDLE ILAPIENTRY iDefaultOpenW(ILconst_string FileName) -{ -#ifndef _UNICODE - return (ILHANDLE)fopen(FileName, "wb"); -#else - return (ILHANDLE)_wfopen(FileName, L"wb"); -#endif//_UNICODE -} - - -ILvoid ILAPIENTRY iDefaultCloseW(ILHANDLE Handle) -{ - fclose((FILE*)Handle); - return; -} - - -ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle) -{ - return fputc(Char, (FILE*)Handle); -} - - -ILint ILAPIENTRY iDefaultWrite(const ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle) -{ - return fwrite(Buffer, Size, Number, (FILE*)Handle); -} - - -ILvoid ILAPIENTRY ilResetRead() -{ - ilSetRead(iDefaultOpenR, iDefaultCloseR, iDefaultEof, iDefaultGetc, - iDefaultRead, iDefaultRSeek, iDefaultRTell); - return; -} - - -ILvoid ILAPIENTRY ilResetWrite() -{ - ilSetWrite(iDefaultOpenW, iDefaultCloseW, iDefaultPutc, - iDefaultWSeek, iDefaultWTell, iDefaultWrite); - return; -} - - -//! Allows you to override the default file-reading functions. -ILvoid ILAPIENTRY ilSetRead(fOpenRProc Open, fCloseRProc Close, fEofProc Eof, fGetcProc Getc, fReadProc Read, fSeekRProc Seek, fTellRProc Tell) -{ - iopenr = Open; - icloser = Close; - EofProc = Eof; - GetcProc = Getc; - ReadProc = Read; - SeekRProc = Seek; - TellRProc = Tell; - - return; -} - - -//! Allows you to override the default file-writing functions. -ILvoid ILAPIENTRY ilSetWrite(fOpenRProc Open, fCloseRProc Close, fPutcProc Putc, fSeekWProc Seek, fTellWProc Tell, fWriteProc Write) -{ - iopenw = Open; - iclosew = Close; - PutcProc = Putc; - WriteProc = Write; - SeekWProc = Seek; - TellWProc = Tell; - - return; -} - - -// Tells DevIL that we're reading from a file, not a lump -ILvoid iSetInputFile(ILHANDLE File) -{ - ieof = iEofFile; - igetc = iGetcFile; - iread = iReadFile; - iseek = iSeekRFile; - itell = iTellRFile; - FileRead = File; - ReadFileStart = itell(); -} - - -// Tells DevIL that we're reading from a lump, not a file -ILvoid iSetInputLump(const ILvoid *Lump, ILuint Size) -{ - ieof = iEofLump; - igetc = iGetcLump; - iread = iReadLump; - iseek = iSeekRLump; - itell = iTellRLump; - ReadLump = Lump; - ReadLumpPos = 0; - ReadLumpSize = Size; -} - - -// Tells DevIL that we're writing to a file, not a lump -ILvoid iSetOutputFile(ILHANDLE File) -{ - // Helps with ilGetLumpPos(). - WriteLump = NULL; - WriteLumpPos = 0; - WriteLumpSize = 0; - - iputc = iPutcFile; - iseekw = iSeekWFile; - itellw = iTellWFile; - iwrite = iWriteFile; - FileWrite = File; -} - - -// Tells DevIL that we're writing to a lump, not a file -ILvoid iSetOutputLump(ILvoid *Lump, ILuint Size) -{ - iputc = iPutcLump; - iseekw = iSeekWLump; - itellw = iTellWLump; - iwrite = iWriteLump; - WriteLump = Lump; - WriteLumpPos = 0; - WriteLumpSize = Size; -} - - -ILuint ILAPIENTRY ilGetLumpPos() -{ - if (WriteLump) - return WriteLumpPos; - return 0; -} - - -ILuint ILAPIENTRY ilprintf(const char *Line, ...) -{ - char Buffer[2048]; // Hope this is large enough - va_list VaLine; - ILuint i; - - va_start(VaLine, Line); - vsprintf(Buffer, Line, VaLine); - va_end(VaLine); - - i = strlen(Buffer); - iwrite(Buffer, 1, i); - - return i; -} - - -// To pad zeros where needed... -ILvoid ipad(ILuint NumZeros) -{ - ILuint i = 0; - for (; i < NumZeros; i++) - iputc(0); - return; -} - - -// -// The rest of the functions following in this file are quite -// self-explanatory, except where commented. -// - -// Next 12 functions are the default write functions - -ILboolean ILAPIENTRY iEofFile(void) -{ - return EofProc((FILE*)FileRead); -} - - -ILboolean ILAPIENTRY iEofLump(void) -{ - if (ReadLumpSize) - return (ReadLumpPos >= ReadLumpSize); - return IL_FALSE; -} - - -ILint ILAPIENTRY iGetcFile(void) -{ - if (!UseCache) { - return GetcProc(FileRead); - } - if (CachePos >= CacheSize) { - iPreCache(CacheSize); - } - - CacheBytesRead++; - return Cache[CachePos++]; -} - - -ILint ILAPIENTRY iGetcLump(void) -{ - // If ReadLumpSize is 0, don't even check to see if we've gone past the bounds. - if (ReadLumpSize > 0) { - if (ReadLumpPos + 1 > ReadLumpSize) { - ReadLumpPos--; - ilSetError(IL_FILE_READ_ERROR); - return IL_EOF; - } - } - - return *((ILubyte*)ReadLump + ReadLumpPos++); -} - - -ILuint ILAPIENTRY iReadFile(ILvoid *Buffer, ILuint Size, ILuint Number) -{ - ILuint TotalBytes = 0, BytesCopied; - ILuint BuffSize = Size * Number; - ILuint NumRead; - - if (!UseCache) { - NumRead = ReadProc(Buffer, Size, Number, FileRead); - if (NumRead != Number) - ilSetError(IL_FILE_READ_ERROR); - return NumRead; - } - - /*if (Cache == NULL || CacheSize == 0) { // Shouldn't happen, but we check anyway. - return ReadProc(Buffer, Size, Number, FileRead); - }*/ - - if (BuffSize < CacheSize - CachePos) { - memcpy(Buffer, Cache + CachePos, BuffSize); - CachePos += BuffSize; - CacheBytesRead += BuffSize; - if (Size != 0) - BuffSize /= Size; - return BuffSize; - } - else { - while (TotalBytes < BuffSize) { - // If loop through more than once, after first, CachePos is 0. - if (TotalBytes + CacheSize - CachePos > BuffSize) - BytesCopied = BuffSize - TotalBytes; - else - BytesCopied = CacheSize - CachePos; - - memcpy((ILubyte*)Buffer + TotalBytes, Cache + CachePos, BytesCopied); - TotalBytes += BytesCopied; - CachePos += BytesCopied; - if (TotalBytes < BuffSize) { - iPreCache(CacheSize); - } - } - } - - CacheBytesRead += TotalBytes; - if (Size != 0) - TotalBytes /= Size; - if (TotalBytes != Number) - ilSetError(IL_FILE_READ_ERROR); - return TotalBytes; -} - - -ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, const ILuint Size, const ILuint Number) -{ - ILuint i, ByteSize = IL_MIN( Size*Number, ReadLumpSize-ReadLumpPos); - - - // stgatilov: the bounds check is always success anyway, so we may use memcpy instead - memcpy((ILubyte*)Buffer, (ILubyte*)ReadLump + ReadLumpPos, ByteSize); - i = ByteSize; -/* for (i = 0; i < ByteSize; i++) { - *((ILubyte*)Buffer + i) = *((ILubyte*)ReadLump + ReadLumpPos + i); - if (ReadLumpSize > 0) { // ReadLumpSize is too large to care about apparently - if (ReadLumpPos + i > ReadLumpSize) { // stgatilov: CAN IT HAPPEN?!!! I think not. - ReadLumpPos += i; - if (i != Number) - ilSetError(IL_FILE_READ_ERROR); - return i; - } - } - }*/ - - ReadLumpPos += i; - if (Size != 0) - i /= Size; - if (i != Number) - ilSetError(IL_FILE_READ_ERROR); - return i; -} - - -ILboolean iPreCache(ILuint Size) -{ - // Reading from a memory lump, so don't cache. - if (iread == iReadLump) { - //iUnCache(); // DW: Removed 06-10-2002. - return IL_TRUE; - } - - if (Cache) { - ifree(Cache); - } - - if (Size == 0) { - Size = 1; - } - - Cache = (ILubyte*)ialloc(Size); - if (Cache == NULL) { - return IL_FALSE; - } - - UseCache = IL_FALSE; - CacheStartPos = itell(); - CacheSize = iread(Cache, 1, Size); - if (CacheSize != Size) - ilGetError(); // Get rid of the IL_FILE_READ_ERROR. - - //2003-09-09: uncommented the following line to prevent - //an infinite loop in ilPreCache() - CacheSize = Size; - CachePos = 0; - UseCache = IL_TRUE; - CacheBytesRead = 0; - - return IL_TRUE; -} - - -ILvoid iUnCache() -{ - //changed 2003-09-01: - //make iUnCache smart enough to return if - //no cache is used - if(!UseCache) - return; - - if (iread == iReadLump) - return; - - CacheSize = 0; - CachePos = 0; - if (Cache) { - ifree(Cache); - Cache = NULL; - } - UseCache = IL_FALSE; - - iseek(CacheStartPos + CacheBytesRead, IL_SEEK_SET); - - return; -} - - -ILuint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode) -{ - if (Mode == IL_SEEK_SET) - Offset += ReadFileStart; // This allows us to use IL_SEEK_SET in the middle of a file. - return SeekRProc(FileRead, Offset, Mode); -} - - -// Returns 1 on error, 0 on success -ILuint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode) -{ - switch (Mode) - { - case IL_SEEK_SET: - if (Offset > (ILint)ReadLumpSize) - return 1; - ReadLumpPos = Offset; - break; - - case IL_SEEK_CUR: - if (ReadLumpPos + Offset > ReadLumpSize) - return 1; - ReadLumpPos += Offset; - break; - - case IL_SEEK_END: - if (Offset > 0) - return 1; - // Should we use >= instead? - if (abs(Offset) > (ILint)ReadLumpSize) // If ReadLumpSize == 0, too bad - return 1; - ReadLumpPos = ReadLumpSize + Offset; - break; - - default: - return 1; - } - - return 0; -} - - -ILuint ILAPIENTRY iTellRFile(void) -{ - return TellRProc(FileRead); -} - - -ILuint ILAPIENTRY iTellRLump(void) -{ - return ReadLumpPos; -} - - -ILHANDLE ILAPIENTRY iGetFile(void) -{ - return FileRead; -} - - -const ILubyte* ILAPIENTRY iGetLump(void) { - return (ILubyte *)ReadLump; -} - - - -// Next 4 functions are the default write functions - -ILint ILAPIENTRY iPutcFile(ILubyte Char) -{ - return PutcProc(Char, FileWrite); -} - - -ILint ILAPIENTRY iPutcLump(ILubyte Char) -{ - if (WriteLumpPos >= WriteLumpSize) - return IL_EOF; // IL_EOF - *((ILubyte*)(WriteLump) + WriteLumpPos++) = Char; - return Char; -} - - -ILint ILAPIENTRY iWriteFile(const ILvoid *Buffer, ILuint Size, ILuint Number) -{ - ILuint NumWritten; - NumWritten = WriteProc(Buffer, Size, Number, FileWrite); - if (NumWritten != Number) { - ilSetError(IL_FILE_WRITE_ERROR); - return 0; - } - return NumWritten; -} - - -ILint ILAPIENTRY iWriteLump(const ILvoid *Buffer, ILuint Size, ILuint Number) -{ - ILuint SizeBytes = Size * Number; - ILuint i = 0; - - for (; i < SizeBytes; i++) { - if (WriteLumpSize > 0) { - if (WriteLumpPos + i >= WriteLumpSize) { // Should we use > instead? - ilSetError(IL_FILE_WRITE_ERROR); - WriteLumpPos += i; - return i; - } - } - - *((ILubyte*)WriteLump + WriteLumpPos + i) = *((ILubyte*)Buffer + i); - } - - WriteLumpPos += SizeBytes; - - return SizeBytes; -} - - -ILuint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode) -{ - if (Mode == IL_SEEK_SET) - Offset += WriteFileStart; // This allows us to use IL_SEEK_SET in the middle of a file. - return SeekWProc(FileWrite, Offset, Mode); -} - - -// Returns 1 on error, 0 on success -ILuint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode) -{ - switch (Mode) - { - case IL_SEEK_SET: - if (Offset > (ILint)WriteLumpSize) - return 1; - WriteLumpPos = Offset; - break; - - case IL_SEEK_CUR: - if (WriteLumpPos + Offset > WriteLumpSize) - return 1; - WriteLumpPos += Offset; - break; - - case IL_SEEK_END: - if (Offset > 0) - return 1; - // Should we use >= instead? - if (abs(Offset) > (ILint)WriteLumpSize) // If WriteLumpSize == 0, too bad - return 1; - WriteLumpPos = WriteLumpSize + Offset; - break; - - default: - return 1; - } - - return 0; -} - - -ILuint ILAPIENTRY iTellWFile(void) -{ - return TellWProc(FileWrite); -} - - -ILuint ILAPIENTRY iTellWLump(void) -{ - return WriteLumpPos; -} diff --git a/win32/devil/src/il_gif.c b/win32/devil/src/il_gif.c deleted file mode 100644 index f1d439f73..000000000 --- a/win32/devil/src/il_gif.c +++ /dev/null @@ -1,744 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/17/2008 -// -// Filename: src-IL/src/il_gif.c -// -// Description: Reads from a Graphics Interchange Format (.gif) file. -// -// The LZW decompression code is based on code released to the public domain -// by Javier Arevalo and can be found at -// http://www.programmersheaven.com/zone10/cat452 -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_GIF - -#include "il_gif.h" - - -ILenum GifType; - -//! Checks if the file specified in FileName is a valid Gif file. -ILboolean ilIsValidGif(ILconst_string FileName) -{ - ILHANDLE GifFile; - ILboolean bGif = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("gif"))) { - ilSetError(IL_INVALID_EXTENSION); - return bGif; - } - - GifFile = iopenr(FileName); - if (GifFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bGif; - } - - bGif = ilIsValidGifF(GifFile); - icloser(GifFile); - - return bGif; -} - - -//! Checks if the ILHANDLE contains a valid Gif file at the current position. -ILboolean ilIsValidGifF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidGif(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid Gif lump. -ILboolean ilIsValidGifL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidGif(); -} - - -// Internal function to get the header and check it. -ILboolean iIsValidGif() -{ - char Header[6]; - - if (iread(Header, 1, 6) != 6) - return IL_FALSE; - iseek(-6, IL_SEEK_CUR); - - if (!strnicmp(Header, "GIF87A", 6)) - return IL_TRUE; - if (!strnicmp(Header, "GIF89A", 6)) - return IL_TRUE; - - return IL_FALSE; -} - - -//! Reads a Gif file -ILboolean ilLoadGif(ILconst_string FileName) -{ - ILHANDLE GifFile; - ILboolean bGif = IL_FALSE; - - GifFile = iopenr(FileName); - if (GifFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bGif; - } - - bGif = ilLoadGifF(GifFile); - icloser(GifFile); - - return bGif; -} - - -//! Reads an already-opened Gif file -ILboolean ilLoadGifF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadGifInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Gif -ILboolean ilLoadGifL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadGifInternal(); -} - - -// Internal function used to load the Gif. -ILboolean iLoadGifInternal() -{ - GIFHEAD Header; - ILpal GlobalPal; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - GlobalPal.Palette = NULL; - GlobalPal.PalSize = 0; - - //read header - iread(&Header.Sig, 1, 6); - Header.Width = GetLittleUShort(); - Header.Height = GetLittleUShort(); - Header.ColourInfo = igetc(); - Header.Background = igetc(); - Header.Aspect = igetc(); - - if (!strnicmp(Header.Sig, "GIF87A", 6)) { - GifType = GIF87A; - } - else if (!strnicmp(Header.Sig, "GIF89A", 6)) { - GifType = GIF89A; - } - else { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - // Check for a global colour map. - if (Header.ColourInfo & (1 << 7)) { - if (!iGetPalette(Header.ColourInfo, &GlobalPal)) { - return IL_FALSE; - } - } - - if (!GetImages(&GlobalPal, &Header)) - return IL_FALSE; - - if (GlobalPal.Palette && GlobalPal.PalSize) - ifree(GlobalPal.Palette); - GlobalPal.Palette = NULL; - GlobalPal.PalSize = 0; - - ilFixImage(); - - return IL_TRUE; -} - - -ILboolean iGetPalette(ILubyte Info, ILpal *Pal) -{ - - // The ld(palettes bpp - 1) is stored in the lower - - // 3 bits of Info (weird gif format ... :) ) - Pal->PalSize = (1 << ((Info & 0x7) + 1)) * 3; - Pal->PalType = IL_PAL_RGB24; - Pal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (Pal->Palette == NULL) - return IL_FALSE; - if (iread(Pal->Palette, 1, Pal->PalSize) != Pal->PalSize) { - ifree(Pal->Palette); - Pal->Palette = NULL; - return IL_FALSE; - } - - return IL_TRUE; -} - - -ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead) -{ - IMAGEDESC ImageDesc, OldImageDesc; - GFXCONTROL Gfx; - ILboolean BaseImage = IL_TRUE; - ILimage *Image = iCurImage, *TempImage = NULL; - ILuint NumImages = 0, i; - ILint input; - - OldImageDesc.ImageInfo = 0; // to initialize the data with an harmless value - Gfx.Used = IL_TRUE; - - while (!ieof()) { - ILubyte DisposalMethod = 1; - - i = itell(); - if (!SkipExtensions(&Gfx)) - goto error_clean; - i = itell(); - - if (!Gfx.Used) - DisposalMethod = (Gfx.Packed & 0x1C) >> 2; - - //read image descriptor - ImageDesc.Separator = igetc(); - if (ImageDesc.Separator != 0x2C) //end of image - break; - ImageDesc.OffX = GetLittleUShort(); - ImageDesc.OffY = GetLittleUShort(); - ImageDesc.Width = GetLittleUShort(); - ImageDesc.Height = GetLittleUShort(); - ImageDesc.ImageInfo = igetc(); - - if (ieof()) { - ilGetError(); // Gets rid of the IL_FILE_READ_ERROR that inevitably results. - break; - } - - - if (!BaseImage) { - NumImages++; - Image->Next = ilNewImage(iCurImage->Width, iCurImage->Height, 1, 1, 1); - if (Image->Next == NULL) - goto error_clean; - //20040612: DisposalMethod controls how the new images data is to be combined - //with the old image. 0 means that it doesn't matter how they are combined, - //1 means keep the old image, 2 means set to background color, 3 is - //load the image that was in place before the current (this is not implemented - //here! (TODO?)) - if (DisposalMethod == 2 || DisposalMethod == 3) - //Note that this is actually wrong, too: If the image has a local - //color table, we should really search for the best fit of the - //background color table and use that index (?). Furthermore, - //we should only memset the part of the image that is not read - //later (if we are sure that no parts of the read image are transparent). - if (!Gfx.Used && Gfx.Packed & 0x1) - memset(Image->Next->Data, Gfx.Transparent, Image->SizeOfData); - else - memset(Image->Next->Data, GifHead->Background, Image->SizeOfData); - else if (DisposalMethod == 1 || DisposalMethod == 0) - memcpy(Image->Next->Data, Image->Data, Image->SizeOfData); - //Interlacing has to be removed after the image was copied (line above) - if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced. - if (!RemoveInterlace(Image)) - goto error_clean; - } - - Image = Image->Next; - Image->Format = IL_COLOUR_INDEX; - Image->Origin = IL_ORIGIN_UPPER_LEFT; - } else { - BaseImage = IL_FALSE; - if (!Gfx.Used && Gfx.Packed & 0x1) - memset(Image->Data, Gfx.Transparent, Image->SizeOfData); - else - memset(Image->Data, GifHead->Background, Image->SizeOfData); - } - - Image->OffX = ImageDesc.OffX; - Image->OffY = ImageDesc.OffY; - - // Check to see if the image has its own palette. - if (ImageDesc.ImageInfo & (1 << 7)) { - if (!iGetPalette(ImageDesc.ImageInfo, &Image->Pal)) { - goto error_clean; - } - } else { - if (!iCopyPalette(&Image->Pal, GlobalPal)) { - goto error_clean; - } - } - - if (!GifGetData(Image, Image->Data + ImageDesc.OffX + ImageDesc.OffY*Image->Width, Image->SizeOfData, - ImageDesc.Width, ImageDesc.Height, Image->Width, &Gfx)) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - goto error_clean; - } - - // See if there was a valid graphics control extension. - if (!Gfx.Used) { - Gfx.Used = IL_TRUE; - Image->Duration = Gfx.Delay * 10; // We want it in milliseconds. - - // See if a transparent colour is defined. - if (Gfx.Packed & 1) { - if (!ConvertTransparent(Image, Gfx.Transparent)) { - goto error_clean; - } - } - } - i = itell(); - // Terminates each block. - if((input = igetc()) == IL_EOF) - goto error_clean; - - if (input != 0x00) - iseek(-1, IL_SEEK_CUR); - // break; - - OldImageDesc = ImageDesc; - } - - //Deinterlace last image - if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced. - if (!RemoveInterlace(Image)) - goto error_clean; - } - - if (BaseImage) // Was not able to load any images in... - return IL_FALSE; - - return IL_TRUE; - -error_clean: - Image = iCurImage->Next; - /* while (Image) { - TempImage = Image; - Image = Image->Next; - ilCloseImage(TempImage); - }*/ - return IL_FALSE; -} - - -ILboolean SkipExtensions(GFXCONTROL *Gfx) -{ - ILint Code; - ILint Label; - ILint Size; - - // DW (06-03-2002): Apparently there can be... - //if (GifType == GIF87A) - // return IL_TRUE; // No extensions in the GIF87a format. - - do { - if((Code = igetc()) == IL_EOF) - return IL_FALSE; - - if (Code != 0x21) { - iseek(-1, IL_SEEK_CUR); - return IL_TRUE; - } - - if((Label = igetc()) == IL_EOF) - return IL_FALSE; - - switch (Label) - { - case 0xF9: - Gfx->Size = igetc(); - Gfx->Packed = igetc(); - Gfx->Delay = GetLittleUShort(); - Gfx->Transparent = igetc(); - Gfx->Terminator = igetc(); - if (ieof()) - return IL_FALSE; - Gfx->Used = IL_FALSE; - break; - /*case 0xFE: - break; - - case 0x01: - break;*/ - default: - do { - if((Size = igetc()) == IL_EOF) - return IL_FALSE; - iseek(Size, IL_SEEK_CUR); - } while (!ieof() && Size != 0); - } - - // @TODO: Handle this better. - if (ieof()) { - ilSetError(IL_FILE_READ_ERROR); - return IL_FALSE; - } - } while (1); - - return IL_TRUE; -} - - -#define MAX_CODES 4096 - -ILint curr_size, clear, ending, newcodes, top_slot, slot, navail_bytes = 0, nbits_left = 0; -ILubyte b1; -ILubyte byte_buff[257]; -ILubyte *pbytes; -ILubyte *stack; -ILubyte *suffix; -ILshort *prefix; - -ILboolean success; - -ILuint code_mask[13] = -{ - 0L, - 0x0001L, 0x0003L, - 0x0007L, 0x000FL, - 0x001FL, 0x003FL, - 0x007FL, 0x00FFL, - 0x01FFL, 0x03FFL, - 0x07FFL, 0x0FFFL -}; - - -ILint get_next_code(void) { - ILint i, t; - ILuint ret; - - //20050102: Tests for IL_EOF were added because this function - //crashed sometimes if igetc() returned IL_EOF - //(for example "table-add-column-before-active.gif" included in the - //mozilla source package) - - if (!nbits_left) { - if (navail_bytes <= 0) { - pbytes = byte_buff; - navail_bytes = igetc(); - - if(navail_bytes == IL_EOF) { - success = IL_FALSE; - return ending; - } - - if (navail_bytes) { - for (i = 0; i < navail_bytes; i++) { - if((t = igetc()) == IL_EOF) { - success = IL_FALSE; - return ending; - } - byte_buff[i] = t; - } - } - } - b1 = *pbytes++; - nbits_left = 8; - navail_bytes--; - } - - ret = b1 >> (8 - nbits_left); - while (curr_size > nbits_left) { - if (navail_bytes <= 0) { - pbytes = byte_buff; - navail_bytes = igetc(); - - if(navail_bytes == IL_EOF) { - success = IL_FALSE; - return ending; - } - - if (navail_bytes) { - for (i = 0; i < navail_bytes; i++) { - if((t = igetc()) == IL_EOF) { - success = IL_FALSE; - return ending; - } - byte_buff[i] = t; - } - } - } - b1 = *pbytes++; - ret |= b1 << nbits_left; - nbits_left += 8; - navail_bytes--; - } - nbits_left -= curr_size; - - return (ret & code_mask[curr_size]); -} - -static void cleanUpGifLoadState() -{ - ifree(stack); - ifree(suffix); - ifree(prefix); - -} - -ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, GFXCONTROL *Gfx) -{ - ILubyte *sp; - ILint code, fc, oc; - ILubyte DisposalMethod = 0; - ILint c, size; - ILuint i = 0, Read = 0, j = 0; - - if (!Gfx->Used) - DisposalMethod = (Gfx->Packed & 0x1C) >> 2; - if((size = igetc()) == IL_EOF) - return IL_FALSE; - - if (size < 2 || 9 < size) { - return IL_FALSE; - } - - stack = (ILubyte*)ialloc(MAX_CODES + 1); - suffix = (ILubyte*)ialloc(MAX_CODES + 1); - prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1)); - if (!stack || !suffix || !prefix) - { - cleanUpGifLoadState(); - return IL_FALSE; - } - - curr_size = size + 1; - top_slot = 1 << curr_size; - clear = 1 << size; - ending = clear + 1; - slot = newcodes = ending + 1; - navail_bytes = nbits_left = 0; - oc = fc = 0; - sp = stack; - - while ((c = get_next_code()) != ending && Read < Height) { - if (c == clear) - { - curr_size = size + 1; - slot = newcodes; - top_slot = 1 << curr_size; - while ((c = get_next_code()) == clear); - if (c == ending) - break; - if (c >= slot) - c = 0; - oc = fc = c; - - if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0) - i++; - else if (i < Width) - Data[i++] = c; - - if (i == Width) - { - Data += Stride; - i = 0; - Read += 1; - ++j; - if (j >= Height) { - cleanUpGifLoadState(); - return IL_FALSE; - } - } - } - else - { - code = c; - //BG-2007-01-10: several fixes for incomplete GIFs - if (code >= slot) - { - code = oc; - if (sp >= stack + MAX_CODES) { - cleanUpGifLoadState(); - return IL_FALSE; - } - *sp++ = fc; - } - - if (code >= MAX_CODES) - return IL_FALSE; - while (code >= newcodes) - { - if (sp >= stack + MAX_CODES) - { - cleanUpGifLoadState(); - return IL_FALSE; - } - *sp++ = suffix[code]; - code = prefix[code]; - } - - if (sp >= stack + MAX_CODES) { - cleanUpGifLoadState(); - return IL_FALSE; - } - - *sp++ = (ILbyte)code; - if (slot < top_slot) - { - fc = code; - suffix[slot] = fc; - prefix[slot++] = oc; - oc = c; - } - if (slot >= top_slot && curr_size < 12) - { - top_slot <<= 1; - curr_size++; - } - while (sp > stack) - { - sp--; - if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0) - i++; - else if (i < Width) - Data[i++] = *sp; - - if (i == Width) - { - i = 0; - Read += 1; - j = (j+1) % Height; - Data = Image->Data + j*Stride; - } - } - } - } - cleanUpGifLoadState(); - return IL_TRUE; -} - - -/*From the GIF spec: - - The rows of an Interlaced images are arranged in the following order: - - Group 1 : Every 8th. row, starting with row 0. (Pass 1) - Group 2 : Every 8th. row, starting with row 4. (Pass 2) - Group 3 : Every 4th. row, starting with row 2. (Pass 3) - Group 4 : Every 2nd. row, starting with row 1. (Pass 4) -*/ - -ILboolean RemoveInterlace(ILimage *image) -{ - ILubyte *NewData; - ILuint i, j = 0; - - NewData = (ILubyte*)ialloc(image->SizeOfData); - if (NewData == NULL) - return IL_FALSE; - - //changed 20041230: images with offsety != 0 were not - //deinterlaced correctly before... - for (i = 0; i < image->OffY; i++, j++) { - memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps); - } - - for (i = 0 + image->OffY; i < image->Height; i += 8, j++) { - memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps); - } - - for (i = 4 + image->OffY; i < image->Height; i += 8, j++) { - memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps); - } - - for (i = 2 + image->OffY; i < image->Height; i += 4, j++) { - memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps); - } - - for (i = 1 + image->OffY; i < image->Height; i += 2, j++) { - memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps); - } - - ifree(image->Data); - image->Data = NewData; - - return IL_TRUE; -} - - -// Assumes that Dest has nothing in it. -ILboolean iCopyPalette(ILpal *Dest, ILpal *Src) -{ - if (Src->Palette == NULL || Src->PalSize == 0) - return IL_FALSE; - - Dest->Palette = (ILubyte*)ialloc(Src->PalSize); - if (Dest->Palette == NULL) - return IL_FALSE; - - memcpy(Dest->Palette, Src->Palette, Src->PalSize); - - Dest->PalSize = Src->PalSize; - Dest->PalType = Src->PalType; - - return IL_TRUE; -} - - -// Uses the transparent colour index to make an alpha channel. -ILboolean ConvertTransparent(ILimage *Image, ILubyte TransColour) -{ - ILubyte *Palette; - ILuint i, j; - - if (!Image->Pal.Palette || !Image->Pal.PalSize) { - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - Palette = (ILubyte*)ialloc(Image->Pal.PalSize / 3 * 4); - if (Palette == NULL) - return IL_FALSE; - - for (i = 0, j = 0; i < Image->Pal.PalSize; i += 3, j += 4) { - Palette[j ] = Image->Pal.Palette[i ]; - Palette[j+1] = Image->Pal.Palette[i+1]; - Palette[j+2] = Image->Pal.Palette[i+2]; - if (j/4 == TransColour) - Palette[j+3] = 0x00; - else - Palette[j+3] = 0xFF; - } - - ifree(Image->Pal.Palette); - Image->Pal.Palette = Palette; - Image->Pal.PalSize = Image->Pal.PalSize / 3 * 4; - Image->Pal.PalType = IL_PAL_RGBA32; - - return IL_TRUE; -} - -#endif //IL_NO_GIF diff --git a/win32/devil/src/il_hdr.c b/win32/devil/src/il_hdr.c deleted file mode 100644 index 005ebc9b4..000000000 --- a/win32/devil/src/il_hdr.c +++ /dev/null @@ -1,349 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods (this file by thakis) -// Last modified: 12/06/2006 -// -// Filename: src-IL/src/il_bmp.c -// -// Description: Reads a RADIANCE High Dynamic Range Image -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_HDR -#include "il_hdr.h" -#include "il_endian.h" - -//! Checks if the file specified in FileName is a valid .hdr file. -ILboolean ilIsValidHdr(ILconst_string FileName) -{ - ILHANDLE HdrFile; - ILboolean bHdr = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("hdr"))) { - ilSetError(IL_INVALID_EXTENSION); - return bHdr; - } - - HdrFile = iopenr(FileName); - if (HdrFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bHdr; - } - - bHdr = ilIsValidHdrF(HdrFile); - icloser(HdrFile); - - return bHdr; -} - - -//! Checks if the ILHANDLE contains a valid .hdr file at the current position. -ILboolean ilIsValidHdrF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidHdr(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .hdr lump. -ILboolean ilIsValidHdrL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidHdr(); -} - - -// Internal function used to get the .hdr header from the current file. -ILboolean iGetHdrHead(HDRHEADER *Header) -{ - ILboolean done = IL_FALSE; - char a, b; - char x[3], y[3]; //changed 20050217: added space for the '\0' char - char buff[80]; - ILuint count = 0; - - iread(Header->Signature, 1, 10); - - //skip lines until an empty line is found. - //this marks the end of header information, - //the next line contains the image's dimension. - - //TODO: read header contents into variables - //(EXPOSURE, orientation, xyz correction, ...) - - if (iread(&a, 1, 1) != 1) - return IL_FALSE; - - while(!done) { - if (iread(&b, 1, 1) != 1) - return IL_FALSE; - if (b == '\n' && a == '\n') - done = IL_TRUE; - else - a = b; - } - - //read dimensions (note that this assumes a somewhat valid image) - if (iread(&a, 1, 1) != 1) - return IL_FALSE; - while (a != '\n') { - buff[count] = a; - if (iread(&a, 1, 1) != 1) - return IL_FALSE; - ++count; - } - buff[count] = '\0'; - - //note that this is not the 100% correct way to load hdr images: - //in a perfect world we would check if there's a +/- X/Y in front - //of width and heigth and mirror + rotate the image after decoding - //according to that. But HDRShop doesn't do that either (and that's - //my reference program :) ) and it's just a rotate and a mirror, - //nothing that really changes the appearance of the loaded image... - //(The code as it is now assumes that y contains "-Y" and x contains - //"+X" after the following line) - //Furthermore, this crashes if the read strings are longer than 2 chars o_O - sscanf(buff, "%s %d %s %d", y, &Header->Height, x, &Header->Width); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidHdr() -{ - char Head[10]; - ILint Read; - - Read = iread(Head, 1, 10); - iseek(-Read, IL_SEEK_CUR); // Go ahead and restore to previous state - if (Read != 10) - return IL_FALSE; - - return - strnicmp(Head, "#?RADIANCE", 10) == 0 - || strnicmp(Head, "#?RGBE", 6) == 0; -} - - -// Internal function used to check if the HEADER is a valid .hdr header. -ILboolean iCheckHdr(HDRHEADER *Header) -{ - return - strnicmp(Header->Signature, "#?RADIANCE", 10) == 0 - || strnicmp(Header->Signature, "#?RGBE", 6) == 0; -} - - -//! Reads a .hdr file -ILboolean ilLoadHdr(ILconst_string FileName) -{ - ILHANDLE HdrFile; - ILboolean bHdr = IL_FALSE; - - HdrFile = iopenr(FileName); - if (HdrFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bHdr; - } - - bHdr = ilLoadHdrF(HdrFile); - icloser(HdrFile); - - return bHdr; -} - - -//! Reads an already-opened .hdr file -ILboolean ilLoadHdrF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadHdrInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .hdr -ILboolean ilLoadHdrL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadHdrInternal(); -} - - -// Internal function used to load the .hdr. -ILboolean iLoadHdrInternal() -{ - HDRHEADER Header; - ILfloat *data; - ILubyte *scanline; - ILuint i, j, e, r, g, b; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetHdrHead(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - if (!iCheckHdr(&Header)) { - //iseek(-(ILint)sizeof(BMPHEAD), IL_SEEK_CUR); - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // Update the current image with the new dimensions - if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_FLOAT, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - //read image data - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->Width / 8 * iCurImage->Height); - - data = (ILfloat*)iCurImage->Data; - scanline = (ILubyte*)ialloc(Header.Width*4); - for (i = 0; i < Header.Height; ++i) { - ReadScanline(scanline, Header.Width); - - //convert hdrs internal format to floats - for (j = 0; j < 4*Header.Width; j += 4) { - ILuint *ee; - ILfloat t, *ff; - e = scanline[j + 3]; - r = scanline[j + 0]; - g = scanline[j + 1]; - b = scanline[j + 2]; - - //t = (float)pow(2.f, ((ILint)e) - 128); - if (e != 0) - e = (e - 1) << 23; - - // All this just to avoid stric-aliasing warnings... - // was: t = *(ILfloat*)&e - ee = &e; - ff = (ILfloat*)ee; - t = *ff; - - data[0] = (r/255.0f)*t; - data[1] = (g/255.0f)*t; - data[2] = (b/255.0f)*t; - data += 3; - } - } - iUnCache(); - ifree(scanline); - - return ilFixImage(); -} - -ILvoid ReadScanline(ILubyte *scanline, ILuint w) { - ILubyte *runner; - ILuint r, g, b, e, read, shift; - - r = igetc(); - g = igetc(); - b = igetc(); - e = igetc(); - - //check if the scanline is in the new format - //if so, e, r, g, g are stored separated and are - //rle-compressed independently. - if (r == 2 && g == 2) { - ILuint length = (b << 8) | e; - ILuint j, t, k; - if (length > w) - length = w; //fix broken files - for (k = 0; k < 4; ++k) { - runner = scanline + k; - j = 0; - while (j < length) { - t = igetc(); - if (t > 128) { //Run? - ILubyte val = igetc(); - t &= 127; - //copy current byte - while (t > 0 && j < length) { - *runner = val; - runner += 4; - --t; - ++j; - } - } - else { //No Run. - //read new bytes - while (t > 0 && j < length) { - *runner = igetc(); - runner += 4; - --t; - ++j; - } - } - } - } - return; //done decoding a scanline in separated format - } - - //if we come here, we are dealing with old-style scanlines - shift = 0; - read = 0; - runner = scanline; - while (read < w) { - if (read != 0) { - r = igetc(); - g = igetc(); - b = igetc(); - e = igetc(); - } - - //if all three mantissas are 1, then this is a rle - //count dword - if (r == 1 && g == 1 && b == 1) { - ILuint length = e; - ILuint j; - for (j = length << shift; j > 0 && read < w; --j) { - memcpy(runner, runner - 4, 4); - runner += 4; - ++read; - } - //if more than one rle count dword is read - //consecutively, they are higher order bytes - //of the first read value. shift keeps track of - //that. - shift += 8; - } - else { - runner[0] = r; - runner[1] = g; - runner[2] = b; - runner[3] = e; - - shift = 0; - runner += 4; - ++read; - } - } -} - - - -#endif//IL_NO_HDR diff --git a/win32/devil/src/il_header.c b/win32/devil/src/il_header.c deleted file mode 100644 index 82cad3b81..000000000 --- a/win32/devil/src/il_header.c +++ /dev/null @@ -1,135 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 10/10/2006 -// -// Filename: src-IL/src/il_header.c -// -// Description: Generates a C-style header file for the current image. -// -//----------------------------------------------------------------------------- - -#ifndef IL_NO_CHEAD - -#include "il_internal.h" - -// Just a guess...let's see what's purty! -#define MAX_LINE_WIDTH 14 - -//! Generates a C-style header file for the current image. -ILboolean ilSaveCHeader(ILconst_string FileName, const char *InternalName) -{ - FILE *HeadFile; - ILuint i = 0, j; - ILimage *TempImage; - const char *Name; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Name = iGetString(IL_CHEAD_HEADER_STRING); - if (Name == NULL) - Name = InternalName; - - if (FileName == NULL || Name == NULL || -#ifndef _UNICODE - strlen(FileName) < 1 || strlen(Name) < 1) { -#else - wcslen(FileName) < 1 || wcslen(FileName) < 1) { -#endif//_UNICODE - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - if (!iCheckExtension(FileName, IL_TEXT("h"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - if (iCurImage->Bpc > 1) { - TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - } else { - TempImage = iCurImage; - } - -#ifndef _WIN32_WCE - HeadFile = fopen(FileName, "wb"); -#else - HeadFile = _wfopen(FileName, L"wb"); -#endif//_WIN32_WCE - - - if (HeadFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - fprintf(HeadFile, "//#include \n"); - fprintf(HeadFile, "// C Image Header:\n\n\n"); - fprintf(HeadFile, "// IMAGE_BPP is in bytes per pixel, *not* bits\n"); - fprintf(HeadFile, "#define IMAGE_BPP %d\n",iCurImage->Bpp); - fprintf(HeadFile, "#define IMAGE_WIDTH %d\n", iCurImage->Width); - fprintf(HeadFile, "#define IMAGE_HEIGHT %d\n", iCurImage->Height); - fprintf(HeadFile, "#define IMAGE_DEPTH %d\n\n\n", iCurImage->Depth); - fprintf(HeadFile, "#define IMAGE_TYPE 0x%X\n", iCurImage->Type); - fprintf(HeadFile, "#define IMAGE_FORMAT 0x%X\n\n\n", iCurImage->Format); - fprintf(HeadFile, "ILubyte %s[] = {\n", Name); - - - for (; i < TempImage->SizeOfData; i += MAX_LINE_WIDTH) { - fprintf(HeadFile, "\t"); - for (j = 0; j < MAX_LINE_WIDTH; j++) { - if (i + j >= TempImage->SizeOfData - 1) { - fprintf(HeadFile, "%4d", TempImage->Data[i+j]); - break; - } - else - fprintf(HeadFile, "%4d,", TempImage->Data[i+j]); - } - fprintf(HeadFile, "\n"); - } - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - fprintf(HeadFile, "};\n"); - - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) { - fprintf(HeadFile, "\n\n"); - fprintf(HeadFile, "#define IMAGE_PALSIZE %u\n\n", iCurImage->Pal.PalSize); - fprintf(HeadFile, "#define IMAGE_PALTYPE 0x%X\n\n", iCurImage->Pal.PalType); - fprintf(HeadFile, "ILubyte %sPal[] = {\n", Name); - for (i = 0; i < iCurImage->Pal.PalSize; i += MAX_LINE_WIDTH) { - fprintf(HeadFile, "\t"); - for (j = 0; j < MAX_LINE_WIDTH; j++) { - if (i + j >= iCurImage->Pal.PalSize - 1) { - fprintf(HeadFile, " %4d", iCurImage->Pal.Palette[i+j]); - break; - } - else - fprintf(HeadFile, " %4d,", iCurImage->Pal.Palette[i+j]); - } - fprintf(HeadFile, "\n"); - } - - fprintf(HeadFile, "};\n"); - } - fclose(HeadFile); - return IL_TRUE; -} - - - -#endif//IL_NO_CHEAD diff --git a/win32/devil/src/il_icns.c b/win32/devil/src/il_icns.c deleted file mode 100644 index 8d81e0b91..000000000 --- a/win32/devil/src/il_icns.c +++ /dev/null @@ -1,286 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2001-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: src-IL/src/il_icns.c -// -// Description: Reads from a Mac OS X icon (.icns) file. -// Credit for the format of .icns files goes to -// http://www.macdisk.com/maciconen.php3 and -// http://ezix.org/project/wiki/MacOSXIcons -// -//----------------------------------------------------------------------------- - -//@TODO: Put ilSetError calls in when errors occur. -//@TODO: Should we clear the alpha channel just in case there isn't one in the file? -//@TODO: Checks on iread - -#include "il_internal.h" -#ifndef IL_NO_ICNS -#include "il_icns.h" - -//! Reads an icon file. -ILboolean ilLoadIcns(ILconst_string FileName) -{ - ILHANDLE IcnsFile; - ILboolean bIcns = IL_FALSE; - - IcnsFile = iopenr(FileName); - if (IcnsFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bIcns; - } - - bIcns = ilLoadIcnsF(IcnsFile); - icloser(IcnsFile); - - return bIcns; -} - - -//! Reads an already-opened icon file. -ILboolean ilLoadIcnsF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadIcnsInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains an icon. -ILboolean ilLoadIcnsL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadIcnsInternal(); -} - - -// Internal function used to load the icon. -ILboolean iLoadIcnsInternal() -{ - ICNSHEAD Header; - ICNSDATA Entry; - ILimage *Image = NULL; - ILboolean BaseCreated = IL_FALSE; - - - if (iCurImage == NULL) - { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iread(Header.Head, 4, 1); - Header.Size = GetBigInt(); - - if (strncmp(Header.Head, "icns", 4)) // First 4 bytes have to be 'icns'. - return IL_FALSE; - - while ((ILint)itell() < Header.Size && !ieof()) - { - iread(Entry.ID, 4, 1); - Entry.Size = GetBigInt(); - - if (!strncmp(Entry.ID, "it32", 4)) // 128x128 24-bit - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 128, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "t8mk", 4)) // 128x128 alpha mask - { - if (iIcnsReadData(&BaseCreated, IL_TRUE, 128, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "ih32", 4)) // 48x48 24-bit - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 48, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "h8mk", 4)) // 48x48 alpha mask - { - if (iIcnsReadData(&BaseCreated, IL_TRUE, 48, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "il32", 4)) // 32x32 24-bit - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 32, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "l8mk", 4)) // 32x32 alpha mask - { - if (iIcnsReadData(&BaseCreated, IL_TRUE, 32, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "is32", 4)) // 16x16 24-bit - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 16, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "s8mk", 4)) // 16x16 alpha mask - { - if (iIcnsReadData(&BaseCreated, IL_TRUE, 16, &Entry, &Image) == IL_FALSE) - goto icns_error; - } -#ifndef IL_NO_JP2 - else if (!strncmp(Entry.ID, "ic09", 4)) // 512x512 JPEG2000 encoded - Uses JasPer - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 512, &Entry, &Image) == IL_FALSE) - goto icns_error; - } - else if (!strncmp(Entry.ID, "ic08", 4)) // 256x256 JPEG2000 encoded - Uses JasPer - { - if (iIcnsReadData(&BaseCreated, IL_FALSE, 256, &Entry, &Image) == IL_FALSE) - goto icns_error; - } -#endif//IL_NO_JP2 - else // Not a valid format or one that we can use - { - iseek(Entry.Size - 8, IL_SEEK_CUR); - } - } - - ilFixImage(); - - return IL_TRUE; - -icns_error: - return IL_FALSE; -} - -ILboolean iIcnsReadData(ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image) -{ - ILint Position = 0, RLEPos = 0, Channel, i; - ILubyte RLERead, *Data = NULL; - ILimage *TempImage = NULL; - ILboolean ImageAlreadyExists = IL_FALSE; - - // The .icns format stores the alpha and RGB as two separate images, so this - // checks to see if one exists for that particular size. Unfortunately, - // there is no guarantee that they are in any particular order. - if (*BaseCreated && iCurImage != NULL) - { - TempImage = iCurImage; - while (TempImage != NULL) - { - if ((ILuint)Width == TempImage->Width) - { - ImageAlreadyExists = IL_TRUE; - break; - } - TempImage = TempImage->Next; - } - } - - Data = ialloc(Entry->Size - 8); - if (Data == NULL) - return IL_FALSE; - - if (!ImageAlreadyExists) - { - if (!*BaseCreated) // Create base image - { - ilTexImage(Width, Width, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - *Image = iCurImage; - *BaseCreated = IL_TRUE; - } - else // Create next image in list - { - (*Image)->Next = ilNewImage(Width, Width, 1, 4, 1); - *Image = (*Image)->Next; - (*Image)->Format = IL_RGBA; - (*Image)->Origin = IL_ORIGIN_UPPER_LEFT; - } - - TempImage = *Image; - } - - if (IsAlpha) // Alpha is never compressed. - { - iread(Data, Entry->Size - 8, 1); // Size includes the header - if (Entry->Size - 8 != Width * Width) - { - ifree(Data); - return IL_FALSE; - } - - for (i = 0; i < Width * Width; i++) - { - TempImage->Data[(i * 4) + 3] = Data[i]; - } - } -#ifndef IL_NO_JP2 - else if (Width == 256 || Width == 512) // JPEG2000 encoded - uses JasPer - { - iread(Data, Entry->Size - 8, 1); // Size includes the header - if (ilLoadJp2LInternal(Data, Entry->Size - 8, TempImage) == IL_FALSE) - { - ifree(Data); - ilSetError(IL_LIB_JP2_ERROR); - return IL_TRUE; - } - } -#endif//IL_NO_JP2 - else // RGB data - { - iread(Data, Entry->Size - 8, 1); // Size includes the header - if (Width == 128) - RLEPos += 4; // There are an extra 4 bytes here of zeros. - //@TODO: Should we check to make sure they are all 0? - - if (Entry->Size - 8 == Width * Width * 4) // Uncompressed - { - //memcpy(TempImage->Data, Data, Entry->Size); - for (i = 0; i < Width * Width; i++, Position += 4) - { - TempImage->Data[i * 4 + 0] = Data[Position+1]; - TempImage->Data[i * 4 + 1] = Data[Position+2]; - TempImage->Data[i * 4 + 2] = Data[Position+3]; - } - } - else // RLE decoding - { - for (Channel = 0; Channel < 3; Channel++) - { - Position = 0; - while (Position < Width * Width) - { - RLERead = Data[RLEPos]; - RLEPos++; - - if (RLERead >= 128) - { - for (i = 0; i < RLERead - 125 && (Position + i) < Width * Width; i++) - { - TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos]; - } - RLEPos++; - Position += RLERead - 125; - } - else - { - for (i = 0; i < RLERead + 1 && (Position + i) < Width * Width; i++) - { - TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos + i]; - } - RLEPos += RLERead + 1; - Position += RLERead + 1; - } - } - } - } - } - - ifree(Data); - return IL_TRUE; -} - -#endif//IL_NO_ICNS diff --git a/win32/devil/src/il_icon.c b/win32/devil/src/il_icon.c deleted file mode 100644 index e86ba6161..000000000 --- a/win32/devil/src/il_icon.c +++ /dev/null @@ -1,679 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2001-2008 by Denton Woods -// Last modified: 08/23/2008 -// -// Filename: src-IL/src/il_icon.c -// -// Description: Reads from a Windows icon (.ico) file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_ICO -#include "il_icon.h" - #ifndef IL_NO_PNG - #include - #endif - -//! Reads an icon file. -ILboolean ilLoadIcon(ILconst_string FileName) -{ - ILHANDLE IconFile; - ILboolean bIcon = IL_FALSE; - - IconFile = iopenr(FileName); - if (IconFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bIcon; - } - - bIcon = ilLoadIconF(IconFile); - icloser(IconFile); - - return bIcon; -} - - -//! Reads an already-opened icon file. -ILboolean ilLoadIconF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadIconInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains an icon. -ILboolean ilLoadIconL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadIconInternal(); -} - - -// Internal function used to load the icon. -ILboolean iLoadIconInternal() -{ - ICODIR IconDir; - ICODIRENTRY *DirEntries = NULL; - ICOIMAGE *IconImages = NULL; - ILimage *Image = NULL; - ILint i; - ILuint Size, PadSize, ANDPadSize, j, k, l, m, x, w, CurAndByte, AndBytes; - ILboolean BaseCreated = IL_FALSE; - ILubyte PNGTest[3]; - - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - - IconDir.Reserved = GetLittleShort(); - - IconDir.Type = GetLittleShort(); - - IconDir.Count = GetLittleShort(); - - if (ieof()) - goto file_read_error; - - DirEntries = (ICODIRENTRY*)ialloc(sizeof(ICODIRENTRY) * IconDir.Count); - IconImages = (ICOIMAGE*)ialloc(sizeof(ICOIMAGE) * IconDir.Count); - if (DirEntries == NULL || IconImages == NULL) { - ifree(DirEntries); - ifree(IconImages); - return IL_FALSE; - } - - // Make it easier for file_read_error. - for (i = 0; i < IconDir.Count; i++) - imemclear(&IconImages[i], sizeof(ICOIMAGE)); - - for (i = 0; i < IconDir.Count; ++i) { - DirEntries[i].Width = (ILubyte)igetc(); - DirEntries[i].Height = (ILubyte)igetc(); - DirEntries[i].NumColours = (ILubyte)igetc(); - DirEntries[i].Reserved = (ILubyte)igetc(); - DirEntries[i].Planes = GetLittleShort(); - DirEntries[i].Bpp = GetLittleShort(); - DirEntries[i].SizeOfData = GetLittleUInt(); - DirEntries[i].Offset = GetLittleUInt(); - - if (ieof()) - goto file_read_error; - } - - for (i = 0; i < IconDir.Count; i++) { - iseek(DirEntries[i].Offset, IL_SEEK_SET); - - // 08-22-2008: Adding test for compressed PNG data - igetc(); // Skip the first character...seems to vary. - iread(PNGTest, 3, 1); - if (!strnicmp((char*)PNGTest, "PNG", 3)) // Characters 'P', 'N', 'G' for PNG header - { -#ifdef IL_NO_PNG - ilSetError(IL_FORMAT_NOT_SUPPORTED); // Cannot handle thesse without libpng. - goto file_read_error; -#else - iseek(DirEntries[i].Offset, IL_SEEK_SET); - if (!iLoadIconPNG(&IconImages[i])) - goto file_read_error; -#endif - } - else - { - iseek(DirEntries[i].Offset, IL_SEEK_SET); - - IconImages[i].Head.Size = GetLittleInt(); - IconImages[i].Head.Width = GetLittleInt(); - IconImages[i].Head.Height = GetLittleInt(); - IconImages[i].Head.Planes = GetLittleShort(); - IconImages[i].Head.BitCount = GetLittleShort(); - IconImages[i].Head.Compression = GetLittleInt(); - IconImages[i].Head.SizeImage = GetLittleInt(); - IconImages[i].Head.XPixPerMeter = GetLittleInt(); - IconImages[i].Head.YPixPerMeter = GetLittleInt(); - IconImages[i].Head.ColourUsed = GetLittleInt(); - IconImages[i].Head.ColourImportant = GetLittleInt(); - - if (ieof()) - goto file_read_error; - - if (IconImages[i].Head.BitCount < 8) { - if (IconImages[i].Head.ColourUsed == 0) { - switch (IconImages[i].Head.BitCount) - { - case 1: - IconImages[i].Head.ColourUsed = 2; - break; - case 4: - IconImages[i].Head.ColourUsed = 16; - break; - } - } - IconImages[i].Pal = (ILubyte*)ialloc(IconImages[i].Head.ColourUsed * 4); - if (IconImages[i].Pal == NULL) - goto file_read_error; // @TODO: Rename the label. - if (iread(IconImages[i].Pal, IconImages[i].Head.ColourUsed * 4, 1) != 1) - goto file_read_error; - } - else if (IconImages[i].Head.BitCount == 8) { - IconImages[i].Pal = (ILubyte*)ialloc(256 * 4); - if (IconImages[i].Pal == NULL) - goto file_read_error; - if (iread(IconImages[i].Pal, 1, 256 * 4) != 256*4) - goto file_read_error; - } - else { - IconImages[i].Pal = NULL; - } - - PadSize = (4 - ((IconImages[i].Head.Width*IconImages[i].Head.BitCount + 7) / 8) % 4) % 4; // Has to be DWORD-aligned. - ANDPadSize = (4 - ((IconImages[i].Head.Width + 7) / 8) % 4) % 4; // AND is 1 bit/pixel - Size = ((IconImages[i].Head.Width*IconImages[i].Head.BitCount + 7) / 8 + PadSize) - * (IconImages[i].Head.Height / 2); - - - IconImages[i].Data = (ILubyte*)ialloc(Size); - if (IconImages[i].Data == NULL) - goto file_read_error; - if (iread(IconImages[i].Data, 1, Size) != Size) - goto file_read_error; - - Size = (((IconImages[i].Head.Width + 7) /8) + ANDPadSize) * (IconImages[i].Head.Height / 2); - IconImages[i].AND = (ILubyte*)ialloc(Size); - if (IconImages[i].AND == NULL) - goto file_read_error; - if (iread(IconImages[i].AND, 1, Size) != Size) - goto file_read_error; - } - } - - - for (i = 0; i < IconDir.Count; i++) { - if (IconImages[i].Head.BitCount != 1 && IconImages[i].Head.BitCount != 4 && - IconImages[i].Head.BitCount != 8 && IconImages[i].Head.BitCount != 24 && - - IconImages[i].Head.BitCount != 32) - continue; - - if (!BaseCreated) { - if (IconImages[i].Head.Size == 0) // PNG compressed icon - ilTexImage(IconImages[i].Head.Width, IconImages[i].Head.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL); - else - ilTexImage(IconImages[i].Head.Width, IconImages[i].Head.Height / 2, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL); - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - Image = iCurImage; - BaseCreated = IL_TRUE; - } - else { - if (IconImages[i].Head.Size == 0) // PNG compressed icon - Image->Next = ilNewImage(IconImages[i].Head.Width, IconImages[i].Head.Height, 1, 4, 1); - else - Image->Next = ilNewImage(IconImages[i].Head.Width, IconImages[i].Head.Height / 2, 1, 4, 1); - Image = Image->Next; - Image->Format = IL_BGRA; - } - Image->Type = IL_UNSIGNED_BYTE; - - j = 0; k = 0; l = 128; CurAndByte = 0; x = 0; - - w = IconImages[i].Head.Width; - PadSize = (4 - ((w*IconImages[i].Head.BitCount + 7) / 8) % 4) % 4; // Has to be DWORD-aligned. - - ANDPadSize = (4 - ((w + 7) / 8) % 4) % 4; // AND is 1 bit/pixel - AndBytes = (w + 7) / 8; - - if (IconImages[i].Head.BitCount == 1) { - for (; j < Image->SizeOfData; k++) { - for (m = 128; m && x < w; m >>= 1) { - Image->Data[j] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4]; - Image->Data[j+1] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4 + 1]; - Image->Data[j+2] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4 + 2]; - Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255; - j += 4; - l >>= 1; - - ++x; - } - if (l == 0 || x == w) { - l = 128; - CurAndByte++; - if (x == w) { - CurAndByte += ANDPadSize; - k += PadSize; - x = 0; - } - - } - } - } - else if (IconImages[i].Head.BitCount == 4) { - for (; j < Image->SizeOfData; j += 8, k++) { - Image->Data[j] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4]; - Image->Data[j+1] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4 + 1]; - Image->Data[j+2] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4 + 2]; - Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255; - l >>= 1; - - ++x; - - if(x < w) { - Image->Data[j+4] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4]; - Image->Data[j+5] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4 + 1]; - Image->Data[j+6] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4 + 2]; - Image->Data[j+7] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255; - l >>= 1; - - ++x; - - } - - else - - j -= 4; - - - if (l == 0 || x == w) { - l = 128; - CurAndByte++; - if (x == w) { - CurAndByte += ANDPadSize; - - k += PadSize; - x = 0; - } - } - } - } - else if (IconImages[i].Head.BitCount == 8) { - for (; j < Image->SizeOfData; j += 4, k++) { - Image->Data[j] = IconImages[i].Pal[IconImages[i].Data[k] * 4]; - Image->Data[j+1] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 1]; - Image->Data[j+2] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 2]; - if (IconImages[i].AND == NULL) // PNG Palette - { - Image->Data[j+3] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 3]; - } - else - { - Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255; - } - l >>= 1; - - ++x; - if (l == 0 || x == w) { - l = 128; - CurAndByte++; - if (x == w) { - CurAndByte += ANDPadSize; - - k += PadSize; - x = 0; - } - } - } - } - else if (IconImages[i].Head.BitCount == 24) { - for (; j < Image->SizeOfData; j += 4, k += 3) { - Image->Data[j] = IconImages[i].Data[k]; - Image->Data[j+1] = IconImages[i].Data[k+1]; - Image->Data[j+2] = IconImages[i].Data[k+2]; - Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255; - l >>= 1; - - ++x; - if (l == 0 || x == w) { - l = 128; - CurAndByte++; - if (x == w) { - CurAndByte += ANDPadSize; - - k += PadSize; - x = 0; - } - } - } - } - - else if (IconImages[i].Head.BitCount == 32) { - for (; j < Image->SizeOfData; j += 4, k += 4) { - Image->Data[j] = IconImages[i].Data[k]; - Image->Data[j+1] = IconImages[i].Data[k+1]; - Image->Data[j+2] = IconImages[i].Data[k+2]; - - //If the icon has 4 channels, use 4th channel for alpha... - //(for Windows XP style icons with true alpha channel - Image->Data[j+3] = IconImages[i].Data[k+3]; - } - } - } - - - for (i = 0; i < IconDir.Count; i++) { - ifree(IconImages[i].Pal); - ifree(IconImages[i].Data); - ifree(IconImages[i].AND); - } - ifree(IconImages); - ifree(DirEntries); - - ilFixImage(); - - return IL_TRUE; - -file_read_error: - if (IconImages) { - for (i = 0; i < IconDir.Count; i++) { - if (IconImages[i].Pal) - ifree(IconImages[i].Pal); - if (IconImages[i].Data) - ifree(IconImages[i].Data); - if (IconImages[i].AND) - ifree(IconImages[i].AND); - } - ifree(IconImages); - } - if (DirEntries) - ifree(DirEntries); - return IL_FALSE; -} - - -#ifndef IL_NO_PNG -// 08-22-2008: Copying a lot of this over from il_png.c for the moment. -// @TODO: Make .ico and .png use the same functions. -png_structp ico_png_ptr = NULL; -png_infop ico_info_ptr = NULL; -ILint color_type; - -#define GAMMA_CORRECTION 1.0 // Doesn't seem to be doing anything... - -ILint ico_readpng_init(); -ILboolean ico_readpng_get_image(ICOIMAGE *Icon, ILdouble display_exponent); -ILvoid ico_readpng_cleanup(); -#endif - -ILboolean iLoadIconPNG(ICOIMAGE *Icon) -{ -#ifndef IL_NO_PNG - ILint init; - init = ico_readpng_init(); - if (init) - return IL_FALSE; - if (!ico_readpng_get_image(Icon, GAMMA_CORRECTION)) - return IL_FALSE; - - ico_readpng_cleanup(); - Icon->Head.Size = 0; // Easiest way to tell that this is a PNG. - // In the normal routine, it will not be 0. - - return IL_TRUE; -#else - Icon; - return IL_FALSE; -#endif -} - -#ifndef IL_NO_PNG -static ILvoid ico_png_read(png_structp png_ptr, png_bytep data, png_size_t length) -{ - (void)png_ptr; - iread(data, 1, length); - return; -} - - -static void ico_png_error_func(png_structp png_ptr, png_const_charp message) -{ - message; - ilSetError(IL_LIB_PNG_ERROR); - - /* - changed 20040224 - From the libpng docs: - "Errors handled through png_error() are fatal, meaning that png_error() - should never return to its caller. Currently, this is handled via - setjmp() and longjmp()" - */ - //return; - longjmp(png_jmpbuf(png_ptr), 1); -} - -static void ico_png_warn_func(png_structp png_ptr, png_const_charp message) -{ - png_ptr; message; - return; -} - - -ILint ico_readpng_init() -{ - ico_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, ico_png_error_func, ico_png_warn_func); - if (!ico_png_ptr) - return 4; /* out of memory */ - - ico_info_ptr = png_create_info_struct(ico_png_ptr); - if (!ico_info_ptr) { - png_destroy_read_struct(&ico_png_ptr, NULL, NULL); - return 4; /* out of memory */ - } - - - /* we could create a second info struct here (end_info), but it's only - * useful if we want to keep pre- and post-IDAT chunk info separated - * (mainly for PNG-aware image editors and converters) */ - - - /* setjmp() must be called in every function that calls a PNG-reading - * libpng function */ - - if (setjmp(png_jmpbuf(ico_png_ptr))) { - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return 2; - } - - - png_set_read_fn(ico_png_ptr, NULL, ico_png_read); - png_set_error_fn(ico_png_ptr, NULL, ico_png_error_func, ico_png_warn_func); - -// png_set_sig_bytes(ico_png_ptr, 8); /* we already read the 8 signature bytes */ - - png_read_info(ico_png_ptr, ico_info_ptr); /* read all PNG info up to image data */ - - /* alternatively, could make separate calls to png_get_image_width(), - * etc., but want bit_depth and color_type for later [don't care about - * compression_type and filter_type => NULLs] */ - - /* OK, that's all we need for now; return happy */ - - return 0; -} - - -ILboolean ico_readpng_get_image(ICOIMAGE *Icon, ILdouble display_exponent) -{ - png_bytepp row_pointers = NULL; - png_uint_32 width, height; // Changed the type to fix AMD64 bit problems, thanks to Eric Werness - ILdouble screen_gamma = 1.0; - ILuint i, channels; - ILenum format; - png_colorp palette; - ILint num_palette, j, bit_depth; -#if _WIN32 || DJGPP - ILdouble image_gamma; -#endif - - display_exponent; - - /* setjmp() must be called in every function that calls a PNG-reading - * libpng function */ - - if (setjmp(png_jmpbuf(ico_png_ptr))) { - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return IL_FALSE; - } - - png_get_IHDR(ico_png_ptr, ico_info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, - &bit_depth, &color_type, NULL, NULL, NULL); - - // Expand low-bit-depth grayscale images to 8 bits - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { - png_set_expand_gray_1_2_4_to_8(ico_png_ptr); - } - - // Expand RGB images with transparency to full alpha channels - // so the data will be available as RGBA quartets. - // But don't expand paletted images, since we want alpha palettes! - if (png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_tRNS) && !(png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_PLTE))) - png_set_tRNS_to_alpha(ico_png_ptr); - - //refresh information (added 20040224) - png_get_IHDR(ico_png_ptr, ico_info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, - &bit_depth, &color_type, NULL, NULL, NULL); - - if (bit_depth < 8) { // Expanded earlier for grayscale, now take care of palette and rgb - bit_depth = 8; - png_set_packing(ico_png_ptr); - } - - // Perform gamma correction. - // @TODO: Determine if we should call png_set_gamma if image_gamma is 1.0. -#if _WIN32 || DJGPP - screen_gamma = 2.2; - if (png_get_gAMA(ico_png_ptr, ico_info_ptr, &image_gamma)) - png_set_gamma(ico_png_ptr, screen_gamma, image_gamma); -#else - screen_gamma = screen_gamma; -#endif - - //fix endianess -#ifdef __LITTLE_ENDIAN__ - if (bit_depth == 16) - png_set_swap(ico_png_ptr); -#endif - - - png_read_update_info(ico_png_ptr, ico_info_ptr); - channels = (ILint)png_get_channels(ico_png_ptr, ico_info_ptr); - // added 20040224: update color_type so that it has the correct value - // in iLoadPngInternal (globals rule...) - color_type = png_get_color_type(ico_png_ptr, ico_info_ptr); - - // Determine internal format - switch (color_type) - { - case PNG_COLOR_TYPE_PALETTE: - Icon->Head.BitCount = 8; - format = IL_COLOUR_INDEX; - break; - case PNG_COLOR_TYPE_RGB: - Icon->Head.BitCount = 24; - format = IL_RGB; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - Icon->Head.BitCount = 32; - format = IL_RGBA; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return IL_FALSE; - } - - if (color_type & PNG_COLOR_MASK_COLOR) - png_set_bgr(ico_png_ptr); - - Icon->Head.Width = width; - Icon->Head.Height = height; - Icon->Data = ialloc(width * height * Icon->Head.BitCount / 8); - if (Icon->Data == NULL) - { - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return IL_FALSE; - } - - // Copy Palette - if (format == IL_COLOUR_INDEX) - { - int chans; - png_bytep trans = NULL; - int num_trans = -1; - if (!png_get_PLTE(ico_png_ptr, ico_info_ptr, &palette, &num_palette)) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return IL_FALSE; - } - - chans = 4; - - if (png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(ico_png_ptr, ico_info_ptr, &trans, &num_trans, NULL); - } - -// @TODO: We may need to keep track of the size of the palette. - Icon->Pal = (ILubyte*)ialloc(num_palette * chans); - - for (j = 0; j < num_palette; ++j) { - Icon->Pal[chans*j + 0] = palette[j].blue; - Icon->Pal[chans*j + 1] = palette[j].green; - Icon->Pal[chans*j + 2] = palette[j].red; - if (trans != NULL) { - if (j < num_trans) - Icon->Pal[chans*j + 3] = trans[j]; - else - Icon->Pal[chans*j + 3] = 255; - } - } - - Icon->AND = NULL; // Transparency information is obtained from libpng. - } - - //allocate row pointers - if ((row_pointers = (png_bytepp)ialloc(height * sizeof(png_bytep))) == NULL) { - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - return IL_FALSE; - } - - - // Set the individual row_pointers to point at the correct offsets - // Needs to be flipped - for (i = 0; i < height; i++) - row_pointers[height - i - 1] = Icon->Data + i * width * Icon->Head.BitCount / 8; - //row_pointers[i] = Icon->Data + i * width * Icon->Head.BitCount / 8; - - - // Now we can go ahead and just read the whole image - png_read_image(ico_png_ptr, row_pointers); - - /* and we're done! (png_read_end() can be omitted if no processing of - * post-IDAT text/time/etc. is desired) */ - //png_read_end(ico_png_ptr, NULL); - ifree(row_pointers); - - return IL_TRUE; -} - - -ILvoid ico_readpng_cleanup() -{ - if (ico_png_ptr && ico_info_ptr) { - png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL); - ico_png_ptr = NULL; - ico_info_ptr = NULL; - } -} -#endif//IL_NO_PNG - -#endif//IL_NO_ICO diff --git a/win32/devil/src/il_internal.c b/win32/devil/src/il_internal.c deleted file mode 100644 index 61be96a1e..000000000 --- a/win32/devil/src/il_internal.c +++ /dev/null @@ -1,350 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_internal.c -// -// Description: Internal stuff for DevIL -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include -#include - - -ILimage *iCurImage = NULL; - - -/* Siigron: added this for Linux... a #define should work, but for some reason - it doesn't (anyone who knows why?) */ -#if !_WIN32 || (_WIN32 && __GNUC__) // Cygwin - int stricmp(const char *src1, const char *src2) - { - return strcasecmp(src1, src2); - } - int strnicmp(const char *src1, const char *src2, size_t max) - { - return strncasecmp(src1, src2, max); - } -#elif _WIN32_WCE - int stricmp(const char *src1, const char *src2) - { - return _stricmp(src1, src2); - } - int strnicmp(const char *src1, const char *src2, size_t max) - { - return _strnicmp(src1, src2, max); - } -#endif /* _WIN32 */ - -#if _UNICODE //_WIN32_WCE - int iStrCmp(ILconst_string src1, ILconst_string src2) - { - return wcsicmp(src1, src2); - } -#else - int iStrCmp(ILconst_string src1, ILconst_string src2) - { - return stricmp(src1, src2); - } -#endif - - -//! Glut's portability.txt says to use this... -char *ilStrDup(const char *Str) -{ - char *copy; - - copy = (char*)ialloc(strlen(Str) + 1); - if (copy == NULL) - return NULL; - strcpy(copy, Str); - return copy; -} - - -// Because MSVC++'s version is too stupid to check for NULL... -ILuint ilStrLen(const char *Str) -{ - const char *eos = Str; - - if (Str == NULL) - return 0; - - while (*eos++); - - return((int)(eos - Str - 1)); -} - - -// Simple function to test if a filename has a given extension, disregarding case -ILboolean iCheckExtension(ILconst_string Arg, ILconst_string Ext) -{ - ILboolean PeriodFound = IL_FALSE; - ILint i; -#ifndef _UNICODE - char *Argu = (char*)Arg; // pointer to arg so we don't destroy arg - - if (Arg == NULL || Ext == NULL || !strlen(Arg) || !strlen(Ext)) // if not a good filename/extension, exit early - return IL_FALSE; - - Argu += strlen(Arg); // start at the end - - - for (i = strlen(Arg); i >= 0; i--) { - if (*Argu == '.') { // try to find a period - PeriodFound = IL_TRUE; - break; - } - Argu--; - } - - if (!PeriodFound) // if no period, no extension - return IL_FALSE; - - if (!stricmp(Argu+1, Ext)) // extension and ext match? - return IL_TRUE; - -#else - wchar_t *Argu = (wchar_t*)Arg; - - if (Arg == NULL || Ext == NULL || !wcslen(Arg) || !wcslen(Ext)) // if not a good filename/extension, exit early - return IL_FALSE; - - Argu += wcslen(Arg); // start at the end - - - for (i = wcslen(Arg); i >= 0; i--) { - if (*Argu == '.') { // try to find a period - PeriodFound = IL_TRUE; - break; - } - Argu--; - } - - if (!PeriodFound) // if no period, no extension - return IL_FALSE; - - if (!wcsicmp(Argu+1, Ext)) // extension and ext match? - return IL_TRUE; - -#endif//_WIN32_WCE - - return IL_FALSE; // if all else fails, return IL_FALSE -} - - -ILstring iGetExtension(ILconst_string FileName) -{ - ILboolean PeriodFound = IL_FALSE; -#ifndef _UNICODE - char *Ext = (char*)FileName; - ILint i, Len = strlen(FileName); -#else - wchar_t *Ext = (wchar_t*)FileName; - ILint i, Len = wcslen(FileName); -#endif//_UNICODE - - if (FileName == NULL || !Len) // if not a good filename/extension, exit early - return NULL; - - Ext += Len; // start at the end - - for (i = Len; i >= 0; i--) { - if (*Ext == '.') { // try to find a period - PeriodFound = IL_TRUE; - break; - } - Ext--; - } - - if (!PeriodFound) // if no period, no extension - return NULL; - - return Ext+1; -} - - -// Checks if the file exists -ILboolean iFileExists(ILconst_string FileName) -{ -#ifndef _UNICODE - FILE *CheckFile = fopen(FileName, "rb"); -#else - FILE *CheckFile = _wfopen(FileName, L"rb"); -#endif//_UNICODE - - - if (CheckFile) { - fclose(CheckFile); - return IL_TRUE; - } - return IL_FALSE; -} - - -// Last time I tried, MSVC++'s fgets() was really really screwy -ILbyte *iFgets(char *buffer, ILuint maxlen) -{ - ILuint counter = 0; - ILint temp = '\0'; - - while ((temp = igetc()) && temp != '\n' && temp != IL_EOF && counter < maxlen) { - buffer[counter] = temp; - counter++; - } - buffer[counter] = '\0'; - - if (temp == IL_EOF && counter == 0) // Only return NULL if no data was "got". - return NULL; - - return (ILbyte*)buffer; -} - - -// A fast integer squareroot, completely accurate for x < 289. - -// Taken from http://atoms.org.uk/sqrt/ - -// There is also a version that is accurate for all integers - -// < 2^31, if we should need it - - - -static int table[] = { - - 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, - - 59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, - - 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, - - 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, - - 119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132, - - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145, - - 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157, - - 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, - - 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, - - 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, - - 189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, - - 198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206, - - 207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215, - - 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223, - - 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231, - - 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, - - 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, - - 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, - - 253, 254, 254, 255 - -}; - - - -int iSqrt(int x) { - - if (x >= 0x10000) { - - if (x >= 0x1000000) { - - if (x >= 0x10000000) { - - if (x >= 0x40000000) { - - return (table[x >> 24] << 8); - - } else { - - return (table[x >> 22] << 7); - - } - - } else if (x >= 0x4000000) { - - return (table[x >> 20] << 6); - - } else { - - return (table[x >> 18] << 5); - - } - - } else if (x >= 0x100000) { - - if (x >= 0x400000) { - - return (table[x >> 16] << 4); - - } else { - - return (table[x >> 14] << 3); - - } - - } else if (x >= 0x40000) { - - return (table[x >> 12] << 2); - - } else { - - return (table[x >> 10] << 1); - - } - - } else if (x >= 0x100) { - - if (x >= 0x1000) { - - if (x >= 0x4000) { - - return (table[x >> 8]); - - } else { - - return (table[x >> 6] >> 1); - - } - - } else if (x >= 0x400) { - - return (table[x >> 4] >> 2); - - } else { - - return (table[x >> 2] >> 3); - - } - - } else if (x >= 0) { - - return table[x] >> 4; - - } - - - - //hm, x was negative.... - - return -1; - -} - diff --git a/win32/devil/src/il_io.c b/win32/devil/src/il_io.c deleted file mode 100644 index f153d5563..000000000 --- a/win32/devil/src/il_io.c +++ /dev/null @@ -1,1628 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/28/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_io.c -// -// Description: Determines image types and loads images -// -//----------------------------------------------------------------------------- - -#include "il_internal.h" -#include "il_register.h" -#include "il_pal.h" -#include - - -ILAPI ILenum ILAPIENTRY ilTypeFromExt(ILconst_string FileName) -{ - ILstring Ext; - -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 1) { -#else - if (FileName == NULL || wcslen(FileName) < 1) { -#endif//_UNICODE - ilSetError(IL_INVALID_PARAM); - return IL_TYPE_UNKNOWN; - } - - //added 2003-08-31: fix sf bug 789535 - Ext = iGetExtension(FileName); - if(Ext == NULL) - return IL_TYPE_UNKNOWN; - - if (!iStrCmp(Ext, IL_TEXT("tga")) || !iStrCmp(Ext, IL_TEXT("vda")) || - !iStrCmp(Ext, IL_TEXT("icb")) || !iStrCmp(Ext, IL_TEXT("vst"))) - return IL_TGA; - if (!iStrCmp(Ext, IL_TEXT("jpg")) || !iStrCmp(Ext, IL_TEXT("jpe")) || !iStrCmp(Ext, IL_TEXT("jpeg"))) - return IL_JPG; - if (!iStrCmp(Ext, IL_TEXT("jp2"))) - return IL_JP2; - if (!iStrCmp(Ext, IL_TEXT("dds"))) - return IL_DDS; - if (!iStrCmp(Ext, IL_TEXT("png"))) - return IL_PNG; - if (!iStrCmp(Ext, IL_TEXT("bmp")) || !iStrCmp(Ext, IL_TEXT("dib"))) - return IL_BMP; - if (!iStrCmp(Ext, IL_TEXT("gif"))) - return IL_GIF; - if (!iStrCmp(Ext, IL_TEXT("cut"))) - return IL_CUT; - if (!iStrCmp(Ext, IL_TEXT("hdr"))) - return IL_HDR; - if (!iStrCmp(Ext, IL_TEXT("ico")) || !iStrCmp(Ext, IL_TEXT("cur"))) - return IL_ICO; - if (!iStrCmp(Ext, IL_TEXT("icns"))) - return IL_ICNS; - if (!iStrCmp(Ext, IL_TEXT("jng"))) - return IL_JNG; - if (!iStrCmp(Ext, IL_TEXT("lif"))) - return IL_LIF; - if (!iStrCmp(Ext, IL_TEXT("mdl"))) - return IL_MDL; - if (!iStrCmp(Ext, IL_TEXT("mng")) || !iStrCmp(Ext, IL_TEXT("jng"))) - return IL_MNG; - if (!iStrCmp(Ext, IL_TEXT("pcd"))) - return IL_PCD; - if (!iStrCmp(Ext, IL_TEXT("pcx"))) - return IL_PCX; - if (!iStrCmp(Ext, IL_TEXT("pic"))) - return IL_PIC; - if (!iStrCmp(Ext, IL_TEXT("pix"))) - return IL_PIX; - if (!iStrCmp(Ext, IL_TEXT("pbm")) || !iStrCmp(Ext, IL_TEXT("pgm")) || - !iStrCmp(Ext, IL_TEXT("pnm")) || !iStrCmp(Ext, IL_TEXT("ppm"))) - return IL_PNM; - if (!iStrCmp(Ext, IL_TEXT("psd")) || !iStrCmp(Ext, IL_TEXT("pdd"))) - return IL_PSD; - if (!iStrCmp(Ext, IL_TEXT("psp"))) - return IL_PSP; - if (!iStrCmp(Ext, IL_TEXT("pxr"))) - return IL_PXR; - if (!iStrCmp(Ext, IL_TEXT("sgi")) || !iStrCmp(Ext, IL_TEXT("bw")) || - !iStrCmp(Ext, IL_TEXT("rgb")) || !iStrCmp(Ext, IL_TEXT("rgba"))) - return IL_SGI; - if (!iStrCmp(Ext, IL_TEXT("tif")) || !iStrCmp(Ext, IL_TEXT("tiff"))) - return IL_TIF; - if (!iStrCmp(Ext, IL_TEXT("wal"))) - return IL_WAL; - if (!iStrCmp(Ext, IL_TEXT("xpm"))) - return IL_XPM; - - return IL_TYPE_UNKNOWN; -} - - -//ILenum ilDetermineTypeF(ILHANDLE File); - -//changed 2003-09-17 to ILAPIENTRY -ILAPI ILenum ILAPIENTRY ilDetermineType(ILconst_string FileName) -{ - ILHANDLE File; - ILenum Type; - - if (FileName == NULL) - return IL_TYPE_UNKNOWN; - - File = iopenr(FileName); - if (File == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - Type = ilDetermineTypeF(File); - icloser(File); - - return Type; -} - - -ILenum ILAPIENTRY ilDetermineTypeF(ILHANDLE File) -{ - if (File == NULL) - return IL_TYPE_UNKNOWN; - - #ifndef IL_NO_JPG - if (ilIsValidJpgF(File)) - return IL_JPG; - #endif - - #ifndef IL_NO_DDS - if (ilIsValidDdsF(File)) - return IL_DDS; - #endif - - #ifndef IL_NO_PNG - if (ilIsValidPngF(File)) - return IL_PNG; - #endif - - #ifndef IL_NO_BMP - if (ilIsValidBmpF(File)) - return IL_BMP; - #endif - - #ifndef IL_NO_GIF - if (ilIsValidGifF(File)) - return IL_GIF; - #endif - - #ifndef IL_NO_HDR - if (ilIsValidHdrF(File)) - return IL_HDR; - #endif - - #ifndef IL_NO_LIF - if (ilIsValidLifF(File)) - return IL_LIF; - #endif - - #ifndef IL_NO_PCX - if (ilIsValidPcxF(File)) - return IL_PCX; - #endif - - #ifndef IL_NO_PIC - if (ilIsValidPicF(File)) - return IL_PIC; - #endif - - #ifndef IL_NO_PNM - if (ilIsValidPnmF(File)) - return IL_PNM; - #endif - - #ifndef IL_NO_PSD - if (ilIsValidPsdF(File)) - return IL_PSD; - #endif - - #ifndef IL_NO_PSP - if (ilIsValidPspF(File)) - return IL_PSP; - #endif - - #ifndef IL_NO_SGI - if (ilIsValidSgiF(File)) - return IL_SGI; - #endif - - #ifndef IL_NO_TIF - if (ilIsValidTiffF(File)) - return IL_TIF; - #endif - - //moved tga to end of list because it has no magic number - //in header to assure that this is really a tga... (20040218) - #ifndef IL_NO_TGA - if (ilIsValidTgaF(File)) - return IL_TGA; - #endif - - return IL_TYPE_UNKNOWN; -} - - -ILenum ilDetermineTypeL( const ILvoid *Lump, ILuint Size) { - if (Lump == NULL) - return IL_TYPE_UNKNOWN; - - #ifndef IL_NO_JPG - if (ilIsValidJpgL(Lump, Size)) - return IL_JPG; - #endif - - #ifndef IL_NO_DDS - if (ilIsValidDdsL(Lump, Size)) - return IL_DDS; - #endif - - #ifndef IL_NO_PNG - if (ilIsValidPngL(Lump, Size)) - return IL_PNG; - #endif - - #ifndef IL_NO_BMP - if (ilIsValidBmpL(Lump, Size)) - return IL_BMP; - #endif - - #ifndef IL_NO_GIF - if (ilIsValidGifL(Lump, Size)) - return IL_GIF; - #endif - - #ifndef IL_NO_HDR - if (ilIsValidHdrL(Lump, Size)) - return IL_HDR; - #endif - - #ifndef IL_NO_LIF - if (ilIsValidLifL(Lump, Size)) - return IL_LIF; - #endif - - #ifndef IL_NO_PCX - if (ilIsValidPcxL(Lump, Size)) - return IL_PCX; - #endif - - #ifndef IL_NO_PIC - if (ilIsValidPicL(Lump, Size)) - return IL_PIC; - #endif - - #ifndef IL_NO_PNM - if (ilIsValidPnmL(Lump, Size)) - return IL_PNM; - #endif - - #ifndef IL_NO_PSD - if (ilIsValidPsdL(Lump, Size)) - return IL_PSD; - #endif - - #ifndef IL_NO_PSP - if (ilIsValidPspL(Lump, Size)) - return IL_PSP; - #endif - - #ifndef IL_NO_SGI - if (ilIsValidSgiL(Lump, Size)) - return IL_SGI; - #endif - - #ifndef IL_NO_TIF - if (ilIsValidTiffL(Lump, Size)) - return IL_TIF; - #endif - - //moved tga to end of list because it has no magic number - //in header to assure that this is really a tga... (20040218) - #ifndef IL_NO_TGA - if (ilIsValidTgaL(Lump, Size)) - return IL_TGA; - #endif - - return IL_TYPE_UNKNOWN; -} - - -ILboolean ILAPIENTRY ilIsValid(ILenum Type, ILstring FileName) -{ - if (FileName == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - switch (Type) - { - #ifndef IL_NO_TGA - case IL_TGA: - return ilIsValidTga(FileName); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilIsValidJpg(FileName); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilIsValidDds(FileName); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilIsValidPng(FileName); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilIsValidBmp(FileName); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilIsValidGif(FileName); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilIsValidHdr(FileName); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilIsValidLif(FileName); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilIsValidPcx(FileName); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilIsValidPic(FileName); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilIsValidPnm(FileName); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilIsValidPsd(FileName); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilIsValidPsp(FileName); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilIsValidSgi(FileName); - #endif - - #ifndef IL_NO_TIF - case IL_TIF: - return ilIsValidTiff(FileName); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILboolean ILAPIENTRY ilIsValidF(ILenum Type, ILHANDLE File) -{ - if (File == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - switch (Type) - { - #ifndef IL_NO_TGA - case IL_TGA: - return ilIsValidTgaF(File); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilIsValidJpgF(File); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilIsValidDdsF(File); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilIsValidPngF(File); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilIsValidBmpF(File); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilIsValidGifF(File); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilIsValidHdrF(File); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilIsValidLifF(File); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilIsValidPcxF(File); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilIsValidPicF(File); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilIsValidPnmF(File); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilIsValidPsdF(File); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilIsValidPspF(File); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilIsValidSgiF(File); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILboolean ILAPIENTRY ilIsValidL(ILenum Type, ILvoid *Lump, ILuint Size) -{ - if (Lump == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - switch (Type) - { - #ifndef IL_NO_TGA - case IL_TGA: - return ilIsValidTgaL(Lump, Size); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilIsValidJpgL(Lump, Size); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilIsValidDdsL(Lump, Size); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilIsValidPngL(Lump, Size); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilIsValidBmpL(Lump, Size); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilIsValidGifL(Lump, Size); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilIsValidHdrL(Lump, Size); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilIsValidLifL(Lump, Size); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilIsValidPcxL(Lump, Size); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilIsValidPicL(Lump, Size); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilIsValidPnmL(Lump, Size); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilIsValidPsdL(Lump, Size); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilIsValidPspL(Lump, Size); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilIsValidSgiL(Lump, Size); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILboolean ILAPIENTRY ilLoad(ILenum Type, ILconst_string FileName) -{ -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 1) { -#else - if (FileName == NULL || wcslen(FileName) < 1) { -#endif//_UNICODE - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - switch (Type) - { - case IL_TYPE_UNKNOWN: - return ilLoadImage(FileName); - - #ifndef IL_NO_TGA - case IL_TGA: - return ilLoadTarga(FileName); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilLoadJpeg(FileName); - #endif - - #ifndef IL_NO_JP2 - case IL_JP2: - return ilLoadJp2(FileName); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilLoadDds(FileName); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilLoadPng(FileName); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilLoadBmp(FileName); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilLoadGif(FileName); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilLoadHdr(FileName); - #endif - - #ifndef IL_NO_CUT - case IL_CUT: - return ilLoadCut(FileName); - #endif - - #ifndef IL_NO_DOOM - case IL_DOOM: - return ilLoadDoom(FileName); - case IL_DOOM_FLAT: - return ilLoadDoomFlat(FileName); - #endif - - #ifndef IL_NO_ICO - case IL_ICO: - return ilLoadIcon(FileName); - #endif - - #ifndef IL_NO_ICNS - case IL_ICNS: - return ilLoadIcns(FileName); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilLoadLif(FileName); - #endif - - #ifndef IL_NO_MDL - case IL_MDL: - return ilLoadMdl(FileName); - #endif - - #ifndef IL_NO_MNG - case IL_MNG: - return ilLoadMng(FileName); - #endif - - #ifndef IL_NO_PCD - case IL_PCD: - return IL_FALSE;//ilLoadPcd(FileName); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilLoadPcx(FileName); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilLoadPic(FileName); - #endif - - #ifndef IL_NO_PIX - case IL_PIX: - return ilLoadPix(FileName); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilLoadPnm(FileName); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilLoadPsd(FileName); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilLoadPsp(FileName); - #endif - - #ifndef IL_NO_PXR - case IL_PXR: - return ilLoadPxr(FileName); - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - return ilLoadRaw(FileName); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilLoadSgi(FileName); - #endif - - #ifndef IL_NO_TIF - case IL_TIF: - //#ifndef _UNICODE - return ilLoadTiff(FileName); - //#else - // wcstombs(AnsiName, FileName, 512); - // //WideCharToMultiByte(CP_ACP, 0, FileName, -1, AnsiName, 512, NULL, NULL); - // return ilLoadTiff(AnsiName); - //#endif//_UNICODE - #endif - - #ifndef IL_NO_WAL - case IL_WAL: - return ilLoadWal(FileName); - #endif - - #ifndef IL_NO_XPM - case IL_XPM: - return ilLoadXpm(FileName); - #endif - - #ifndef IL_NO_EXR - case IL_EXR: - return ilLoadExr(FileName); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILboolean ILAPIENTRY ilLoadF(ILenum Type, ILHANDLE File) -{ - if (File == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (Type == IL_TYPE_UNKNOWN) - Type = ilDetermineTypeF(File); - - switch (Type) - { - case IL_TYPE_UNKNOWN: - return IL_FALSE; - - #ifndef IL_NO_TGA - case IL_TGA: - return ilLoadTargaF(File); - #endif - - #ifndef IL_NO_JPG - #ifndef IL_USE_IJL - case IL_JPG: - return ilLoadJpegF(File); - #endif - #endif - - // There is not a way to do this with the JasPer library. - /*#ifndef IL_NO_JP2 - case IL_JP2: - return ilLoadJp2F(File); - #endif*/ - - #ifndef IL_NO_DDS - case IL_DDS: - return ilLoadDdsF(File); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilLoadPngF(File); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilLoadBmpF(File); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilLoadGifF(File); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilLoadHdrF(File); - #endif - - #ifndef IL_NO_CUT - case IL_CUT: - return ilLoadCutF(File); - #endif - - #ifndef IL_NO_DOOM - case IL_DOOM: - return ilLoadDoomF(File); - case IL_DOOM_FLAT: - return ilLoadDoomFlatF(File); - #endif - - #ifndef IL_NO_ICO - case IL_ICO: - return ilLoadIconF(File); - #endif - - #ifndef IL_NO_ICNS - case IL_ICNS: - return ilLoadIcnsF(File); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilLoadLifF(File); - #endif - - #ifndef IL_NO_MDL - case IL_MDL: - return ilLoadMdlF(File); - #endif - - #ifndef IL_NO_MNG - case IL_MNG: - return ilLoadMngF(File); - #endif - - #ifndef IL_NO_PCD - case IL_PCD: - return IL_FALSE;//return ilLoadPcdF(File); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilLoadPcxF(File); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilLoadPicF(File); - #endif - - #ifndef IL_NO_PIX - case IL_PIX: - return ilLoadPixF(File); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilLoadPnmF(File); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilLoadPsdF(File); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilLoadPspF(File); - #endif - - #ifndef IL_NO_PXR - case IL_PXR: - return ilLoadPxrF(File); - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - return ilLoadRawF(File); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilLoadSgiF(File); - #endif - - #ifndef IL_NO_TIF - case IL_TIF: - return ilLoadTiffF(File); - #endif - - #ifndef IL_NO_WAL - case IL_WAL: - return ilLoadWalF(File); - #endif - - #ifndef IL_NO_XPM - case IL_XPM: - return ilLoadXpmF(File); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILboolean ILAPIENTRY ilLoadL(ILenum Type, const ILvoid *Lump, ILuint Size) { - if (Lump == NULL || Size == 0) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (Type == IL_TYPE_UNKNOWN) - Type = ilDetermineTypeL(Lump, Size); - - switch (Type) - { - case IL_TYPE_UNKNOWN: - return IL_FALSE; - - #ifndef IL_NO_TGA - case IL_TGA: - return ilLoadTargaL(Lump, Size); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilLoadJpegL(Lump, Size); - #endif - - #ifndef IL_NO_JP2 - case IL_JP2: - return ilLoadJp2L(Lump, Size); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilLoadDdsL(Lump, Size); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilLoadPngL(Lump, Size); - #endif - - #ifndef IL_NO_BMP - case IL_BMP: - return ilLoadBmpL(Lump, Size); - #endif - - #ifndef IL_NO_GIF - case IL_GIF: - return ilLoadGifL(Lump, Size); - #endif - - #ifndef IL_NO_HDR - case IL_HDR: - return ilLoadHdrL(Lump, Size); - #endif - - #ifndef IL_NO_CUT - case IL_CUT: - return ilLoadCutL(Lump, Size); - #endif - - #ifndef IL_NO_DOOM - case IL_DOOM: - return ilLoadDoomL(Lump, Size); - case IL_DOOM_FLAT: - return ilLoadDoomFlatL(Lump, Size); - #endif - - #ifndef IL_NO_ICO - case IL_ICO: - return ilLoadIconL(Lump, Size); - #endif - - #ifndef IL_NO_ICNS - case IL_ICNS: - return ilLoadIcnsL(Lump, Size); - #endif - - #ifndef IL_NO_LIF - case IL_LIF: - return ilLoadLifL(Lump, Size); - #endif - - #ifndef IL_NO_MDL - case IL_MDL: - return ilLoadMdlL(Lump, Size); - #endif - - #ifndef IL_NO_MNG - case IL_MNG: - return ilLoadMngL(Lump, Size); - #endif - - #ifndef IL_NO_PCD - case IL_PCD: - return IL_FALSE;//return ilLoadPcdL(Lump, Size); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilLoadPcxL(Lump, Size); - #endif - - #ifndef IL_NO_PIC - case IL_PIC: - return ilLoadPicL(Lump, Size); - #endif - - #ifndef IL_NO_PIX - case IL_PIX: - return ilLoadPixL(Lump, Size); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilLoadPnmL(Lump, Size); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilLoadPsdL(Lump, Size); - #endif - - #ifndef IL_NO_PSP - case IL_PSP: - return ilLoadPspL(Lump, Size); - #endif - - #ifndef IL_NO_PXR - case IL_PXR: - return ilLoadPxrL(Lump, Size); - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - return ilLoadRawL(Lump, Size); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilLoadSgiL(Lump, Size); - #endif - - #ifndef IL_NO_TIF - case IL_TIF: - return ilLoadTiffL(Lump, Size); - #endif - - #ifndef IL_NO_WAL - case IL_WAL: - return ilLoadWalL(Lump, Size); - #endif - - #ifndef IL_NO_XPM - case IL_XPM: - return ilLoadXpmL(Lump, Size); - #endif - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -//! Attempts to load an image with various different methods before failing - very generic. -ILboolean ILAPIENTRY ilLoadImage(ILconst_string FileName) -{ - ILstring Ext = iGetExtension(FileName); - ILenum Type; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 1) { -#else - if (FileName == NULL || wcslen(FileName) < 1) { -#endif//_UNICODE - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - // Try registered procedures first (so users can override default lib functions). - if (Ext) { - if (iRegisterLoad(FileName)) - return IL_TRUE; - - #ifndef IL_NO_TGA - if (!iStrCmp(Ext, IL_TEXT("tga")) || !iStrCmp(Ext, IL_TEXT("vda")) || - !iStrCmp(Ext, IL_TEXT("icb")) || !iStrCmp(Ext, IL_TEXT("vst"))) { - return ilLoadTarga(FileName); - } - #endif - - #ifndef IL_NO_JPG - if (!iStrCmp(Ext, IL_TEXT("jpg")) || !iStrCmp(Ext, IL_TEXT("jpe")) || - !iStrCmp(Ext, IL_TEXT("jpeg"))) { - return ilLoadJpeg(FileName); - } - #endif - - #ifndef IL_NO_JP2 - if (!iStrCmp(Ext, IL_TEXT("jp2"))) { - return ilLoadJp2(FileName); - } - #endif - - #ifndef IL_NO_DDS - if (!iStrCmp(Ext, IL_TEXT("dds"))) { - return ilLoadDds(FileName); - } - #endif - - #ifndef IL_NO_PNG - if (!iStrCmp(Ext, IL_TEXT("png"))) { - return ilLoadPng(FileName); - } - #endif - - #ifndef IL_NO_BMP - if (!iStrCmp(Ext, IL_TEXT("bmp")) || !iStrCmp(Ext, IL_TEXT("dib"))) { - return ilLoadBmp(FileName); - } - #endif - - #ifndef IL_NO_GIF - if (!iStrCmp(Ext, IL_TEXT("gif"))) { - return ilLoadGif(FileName); - } - #endif - - #ifndef IL_NO_HDR - if (!iStrCmp(Ext, IL_TEXT("hdr"))) { - return ilLoadHdr(FileName); - } - #endif - - #ifndef IL_NO_CUT - if (!iStrCmp(Ext, IL_TEXT("cut"))) { - return ilLoadCut(FileName); - } - #endif - - #ifndef IL_NO_DCX - if (!iStrCmp(Ext, IL_TEXT("dcx"))) { - return ilLoadDcx(FileName); - } - #endif - - #ifndef IL_NO_ICO - if (!iStrCmp(Ext, IL_TEXT("ico")) || !iStrCmp(Ext, IL_TEXT("cur"))) { - return ilLoadIcon(FileName); - } - #endif - - #ifndef IL_NO_ICNS - if (!iStrCmp(Ext, IL_TEXT("icns"))) { - return ilLoadIcns(FileName); - } - #endif - - #ifndef IL_NO_LIF - if (!iStrCmp(Ext, IL_TEXT("lif"))) { - return ilLoadLif(FileName); - } - #endif - - #ifndef IL_NO_MDL - if (!iStrCmp(Ext, IL_TEXT("mdl"))) { - return ilLoadMdl(FileName); - } - #endif - - #ifndef IL_NO_MNG - if (!iStrCmp(Ext, IL_TEXT("mng")) || !iStrCmp(Ext, IL_TEXT("jng"))) { - return ilLoadMng(FileName); - } - #endif - - #ifndef IL_NO_PCD - if (!iStrCmp(Ext, IL_TEXT("pcd"))) { - return IL_FALSE;//return ilLoadPcd(FileName); - } - #endif - - #ifndef IL_NO_PCX - if (!iStrCmp(Ext, IL_TEXT("pcx"))) { - return ilLoadPcx(FileName); - } - #endif - - #ifndef IL_NO_PIC - if (!iStrCmp(Ext, IL_TEXT("pic"))) { - return ilLoadPic(FileName); - } - #endif - - #ifndef IL_NO_PIX - if (!iStrCmp(Ext, IL_TEXT("pix"))) { - return ilLoadPix(FileName); - } - #endif - - #ifndef IL_NO_PNM - if (!iStrCmp(Ext, IL_TEXT("pbm"))) { - return ilLoadPnm(FileName); - } - if (!iStrCmp(Ext, IL_TEXT("pgm"))) { - return ilLoadPnm(FileName); - } - if (!iStrCmp(Ext, IL_TEXT("pnm"))) { - return ilLoadPnm(FileName); - } - if (!iStrCmp(Ext, IL_TEXT("ppm"))) { - return ilLoadPnm(FileName); - } - #endif - - #ifndef IL_NO_PSD - if (!iStrCmp(Ext, IL_TEXT("psd")) || !iStrCmp(Ext, IL_TEXT("pdd"))) { - return ilLoadPsd(FileName); - } - #endif - - #ifndef IL_NO_PSP - if (!iStrCmp(Ext, IL_TEXT("psp"))) { - return ilLoadPsp(FileName); - } - #endif - - #ifndef IL_NO_PXR - if (!iStrCmp(Ext, IL_TEXT("pxr"))) { - return ilLoadPxr(FileName); - } - #endif - - #ifndef IL_NO_SGI - if (!iStrCmp(Ext, IL_TEXT("sgi")) || !iStrCmp(Ext, IL_TEXT("bw")) || - !iStrCmp(Ext, IL_TEXT("rgb")) || !iStrCmp(Ext, IL_TEXT("rgba"))) { - return ilLoadSgi(FileName); - } - #endif - - #ifndef IL_NO_TIF - if (!iStrCmp(Ext, IL_TEXT("tif")) || !iStrCmp(Ext, IL_TEXT("tiff"))) { - return ilLoadTiff(FileName); - } - #endif - - #ifndef IL_NO_WAL - if (!iStrCmp(Ext, IL_TEXT("wal"))) { - return ilLoadWal(FileName); - } - #endif - - #ifndef IL_NO_XPM - if (!iStrCmp(Ext, IL_TEXT("xpm"))) { - return ilLoadXpm(FileName); - } - #endif - - #ifndef IL_NO_EXR - if (!iStrCmp(Ext, IL_TEXT("exr"))) { - return ilLoadExr(FileName); - } - #endif - } - - // As a last-ditch effort, try to identify the image - Type = ilDetermineType(FileName); - if (Type == IL_TYPE_UNKNOWN) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - return ilLoad(Type, FileName); -} - - -ILboolean ILAPIENTRY ilSave(ILenum Type, ILstring FileName) -{ - switch (Type) - { - case IL_TYPE_UNKNOWN: - return ilSaveImage(FileName); - - #ifndef IL_NO_BMP - case IL_BMP: - return ilSaveBmp(FileName); - #endif - - #ifndef IL_NO_CHEAD - case IL_CHEAD: - return ilSaveCHeader(FileName, "IL_IMAGE"); - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - return ilSaveJpeg(FileName); - #endif - - #ifndef IL_NO_PCX - case IL_PCX: - return ilSavePcx(FileName); - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - return ilSavePng(FileName); - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - return ilSavePnm(FileName); - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - return ilSavePsd(FileName); - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - return ilSaveRaw(FileName); - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - return ilSaveSgi(FileName); - #endif - - #ifndef IL_NO_TGA - case IL_TGA: - return ilSaveTarga(FileName); - #endif - - #ifndef IL_NO_TIF - case IL_TIF: - return ilSaveTiff(FileName); - #endif - - #ifndef IL_NO_DDS - case IL_DDS: - return ilSaveDds(FileName); - #endif - - case IL_JASC_PAL: - return ilSaveJascPal(FileName); - } - - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; -} - - -ILuint ILAPIENTRY ilSaveF(ILenum Type, ILHANDLE File) -{ - ILboolean Ret; - - if (File == NULL) { - ilSetError(IL_INVALID_PARAM); - return 0; - } - - switch (Type) - { - #ifndef IL_NO_BMP - case IL_BMP: - Ret = ilSaveBmpF(File); - break; - #endif - - #ifndef IL_NO_JPG - #ifndef IL_USE_IJL - case IL_JPG: - Ret = ilSaveJpegF(File); - break; - #endif - #endif - - #ifndef IL_NO_PNM - case IL_PNM: - Ret = ilSavePnmF(File); - break; - #endif - - #ifndef IL_NO_PNG - case IL_PNG: - Ret = ilSavePngF(File); - break; - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - Ret = ilSavePsdF(File); - break; - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - Ret = ilSaveRawF(File); - break; - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - Ret = ilSaveSgiF(File); - break; - #endif - - #ifndef IL_NO_TGA - case IL_TGA: - Ret = ilSaveTargaF(File); - break; - #endif - - case IL_DDS: - Ret = ilSaveDdsF(File); - break; - - /*#ifndef IL_NO_TIF - case IL_TIF: - Ret = ilSaveTiffF(File); - break; - #endif*/ - - default: - ilSetError(IL_INVALID_ENUM); - return 0; - } - - if (Ret == IL_FALSE) - return 0; - - return itellw(); -} - - -ILuint ILAPIENTRY ilSaveL(ILenum Type, ILvoid *Lump, ILuint Size) -{ - ILboolean Ret; - - if (Lump == NULL) { - ilSetError(IL_INVALID_PARAM); - return 0; - } - - switch (Type) - { - #ifndef IL_NO_BMP - case IL_BMP: - Ret = ilSaveBmpL(Lump, Size); - break; - #endif - - #ifndef IL_NO_JPG - case IL_JPG: - Ret = ilSaveJpegL(Lump, Size); - break; - #endif - - - #ifndef IL_NO_PNG - - case IL_PNG: - - Ret = ilSavePngL(Lump, Size); - - break; - - #endif - - - #ifndef IL_NO_PNM - case IL_PNM: - Ret = ilSavePnmL(Lump, Size); - break; - #endif - - #ifndef IL_NO_PSD - case IL_PSD: - Ret = ilSavePsdL(Lump, Size); - break; - #endif - - #ifndef IL_NO_RAW - case IL_RAW: - Ret = ilSaveRawL(Lump, Size); - break; - #endif - - #ifndef IL_NO_SGI - case IL_SGI: - Ret = ilSaveSgiL(Lump, Size); - break; - #endif - - #ifndef IL_NO_TGA - case IL_TGA: - Ret = ilSaveTargaL(Lump, Size); - break; - #endif - - case IL_DDS: - Ret = ilSaveDdsL(Lump, Size); - break; - - /*#ifndef IL_NO_TIF - case IL_TIF: - Ret = ilSaveTiffL(Lump, Size); - break; - #endif*/ - - default: - ilSetError(IL_INVALID_ENUM); - return 0; - } - - if (Ret == IL_FALSE) - return 0; - - return itellw(); -} - - -//! Determines what image type to save based on the extension and attempts to save -// the current image based on the extension given in FileName. -ILboolean ILAPIENTRY ilSaveImage(ILconst_string FileName) -{ - ILstring Ext = iGetExtension(FileName); - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 1 || Ext == NULL) { -#else - if (FileName == NULL || wcslen(FileName) < 1 || Ext == NULL) { -#endif//_UNICODE - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - #ifndef IL_NO_BMP - if (!iStrCmp(Ext, IL_TEXT("bmp"))) { - return ilSaveBmp(FileName); - } - #endif - - #ifndef IL_NO_CHEAD - if (!iStrCmp(Ext, IL_TEXT("h"))) { - return ilSaveCHeader(FileName, "IL_IMAGE"); - } - #endif - - #ifndef IL_NO_DDS - if (!iStrCmp(Ext, IL_TEXT("dds"))) { - return ilSaveDds(FileName); - } - #endif - - #ifndef IL_NO_JPG - if (!iStrCmp(Ext, IL_TEXT("jpg")) || !iStrCmp(Ext, IL_TEXT("jpeg")) || !iStrCmp(Ext, IL_TEXT("jpe"))) { - return ilSaveJpeg(FileName); - } - #endif - - #ifndef IL_NO_PCX - if (!iStrCmp(Ext, IL_TEXT("pcx"))) { - return ilSavePcx(FileName); - } - #endif - - #ifndef IL_NO_PNG - if (!iStrCmp(Ext, IL_TEXT("png"))) { - return ilSavePng(FileName); - } - #endif - - #ifndef IL_NO_PNM // Not sure if binary or ascii should be defaulted...maybe an option? - if (!iStrCmp(Ext, IL_TEXT("pbm"))) { - return ilSavePnm(FileName); - } - if (!iStrCmp(Ext, IL_TEXT("pgm"))) { - return ilSavePnm(FileName); - } - if (!iStrCmp(Ext, IL_TEXT("ppm"))) { - return ilSavePnm(FileName); - } - #endif - - #ifndef IL_NO_PSD - if (!iStrCmp(Ext, IL_TEXT("psd"))) { - return ilSavePsd(FileName); - } - #endif - - #ifndef IL_NO_RAW - if (!iStrCmp(Ext, IL_TEXT("raw"))) { - return ilSaveRaw(FileName); - } - #endif - - #ifndef IL_NO_SGI - if (!iStrCmp(Ext, IL_TEXT("sgi")) || !iStrCmp(Ext, IL_TEXT("bw")) || - !iStrCmp(Ext, IL_TEXT("rgb")) || !iStrCmp(Ext, IL_TEXT("rgba"))) { - return ilSaveSgi(FileName); - } - #endif - - #ifndef IL_NO_TGA - if (!iStrCmp(Ext, IL_TEXT("tga"))) { - return ilSaveTarga(FileName); - } - #endif - - #ifndef IL_NO_TIF - if (!iStrCmp(Ext, IL_TEXT("tif")) || !iStrCmp(Ext, IL_TEXT("tiff"))) { - return ilSaveTiff(FileName); - } - #endif - - // Check if we just want to save the palette. - if (!iStrCmp(Ext, IL_TEXT("pal"))) { - return ilSavePal(FileName); - } - - // Try registered procedures - if (iRegisterSave(FileName)) - return IL_TRUE; - - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; -} diff --git a/win32/devil/src/il_jp2.c b/win32/devil/src/il_jp2.c deleted file mode 100644 index ae15a7051..000000000 --- a/win32/devil/src/il_jp2.c +++ /dev/null @@ -1,195 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/24/2008 -// -// Filename: src-IL/src/il_jp2.c -// -// Description: Jpeg-2000 (.jp2) functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_JP2 -#include -#include "il_jp2.h" - -//! Reads a Jpeg2000 file. -ILboolean ilLoadJp2(ILconst_string FileName) -{ -// ILHANDLE Jp2File; - ILboolean bRet = IL_FALSE; - jas_stream_t *Stream; - - /*Jp2File = iopenr(FileName); - if (Jp2File == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bJp2; - } - - bJp2 = iLoadJp2Internal(); - icloser(Jp2File);*/ - - if (jas_init()) - { - ilSetError(IL_LIB_JP2_ERROR); - return IL_FALSE; - } - Stream = jas_stream_fopen(FileName, "rb"); - if (!Stream) - { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - bRet = iLoadJp2Internal(Stream, NULL); - // Close the input stream. - jas_stream_close(Stream); - - return bRet; -} - - -// No way to do this with the JasPer library. -//! Reads an already-opened Jpeg2000 file. -/*ILboolean ilLoadJp2F(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadJp2Internal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -}*/ - - -//! Reads from a memory "lump" that contains a Jpeg2000 stream. -ILboolean ilLoadJp2L(const ILvoid *Lump, ILuint Size) -{ - return ilLoadJp2LInternal(Lump, Size, NULL); -} - - -//! This is separated so that it can be called for other file types, such as .icns. -ILboolean ilLoadJp2LInternal(const ILvoid *Lump, ILuint Size, ILimage *Image) -{ - ILboolean bRet; - jas_stream_t *Stream; - - if (jas_init()) - { - ilSetError(IL_LIB_JP2_ERROR); - return IL_FALSE; - } - Stream = jas_stream_memopen(Lump, Size); - if (!Stream) - { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - bRet = iLoadJp2Internal(Stream, Image); - // Close the input stream. - jas_stream_close(Stream); - - return bRet; -} - - -// Internal function used to load the Jpeg2000 stream. -ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image) -{ - jas_image_t *Jp2Image = NULL; - jas_matrix_t *origdata; - ILint x, y, c; - ILimage *TempImage; - - // Decode image - Jp2Image = jas_image_decode(Stream, -1, 0); - if (!Jp2Image) - { - ilSetError(IL_ILLEGAL_FILE_VALUE); - jas_stream_close(Stream); - return IL_FALSE; - } - - // We're not supporting anything other than 8 bits/component yet. - if (jas_image_cmptprec(Jp2Image, 0) != 8) - { - jas_image_destroy(Jp2Image); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - switch (jas_image_numcmpts(Jp2Image)) - { - case 3: - if (Image == NULL) { - ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); - TempImage = iCurImage; - } - else { - ifree(Image->Data); // @TODO: Not really the most efficient way to do this... - ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); - TempImage = Image; - } - break; - case 4: - if (Image == NULL) { - ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - TempImage = iCurImage; - } - else { - ifree(Image->Data); // @TODO: Not really the most efficient way to do this... - ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - TempImage = Image; - } - break; - default: - jas_image_destroy(Jp2Image); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - TempImage->Origin = IL_ORIGIN_UPPER_LEFT; - - // JasPer stores the data channels separately. - // I am assuming RGBA format. Is it possible for other formats to be included? - for (c = 0; c < TempImage->Bpp; c++) - { - origdata = jas_matrix_create(TempImage->Height, TempImage->Width); - if (!origdata) - { - ilSetError(IL_LIB_JP2_ERROR); - return IL_FALSE; // @TODO: Error - } - // Have to convert data into an intermediate matrix format. - if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata)) - { - return IL_FALSE; - } - - for (y = 0; y < TempImage->Height; y++) - { - for (x = 0; x < TempImage->Width; x++) - { - TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x]; - } - } - - jas_matrix_destroy(origdata); - } - - jas_image_destroy(Jp2Image); - - ilFixImage(); - - return IL_TRUE; -} - - -#endif//IL_NO_JP2 diff --git a/win32/devil/src/il_jpeg.c b/win32/devil/src/il_jpeg.c deleted file mode 100644 index cd037040f..000000000 --- a/win32/devil/src/il_jpeg.c +++ /dev/null @@ -1,1910 +0,0 @@ -//----------------------------------------------------------------------------- - -// - -// ImageLib Sources - -// Copyright (C) 2000-2002 by Denton Woods - -// Last modified: 05/26/2002 <--Y2K Compliant! =] - -// - -// Filename: src-IL/src/il_jpeg.c - -// - -// Description: Jpeg (.jpg) functions - -// - -//----------------------------------------------------------------------------- - - - - - -// - -// Most of the comments here are sufficient, as we're just using libjpeg. - -// I have left most of the libjpeg example's comments intact, though. - -// - - - -#include "il_internal.h" - -#ifndef IL_NO_JPG - - #ifndef IL_USE_IJL - - #ifdef RGB_RED - - #undef RGB_RED - - #undef RGB_GREEN - - #undef RGB_BLUE - - #endif - - #define RGB_RED 0 - - #define RGB_GREEN 1 - - #define RGB_BLUE 2 - - - - #include "jpeglib.h" - - - - #if JPEG_LIB_VERSION < 62 - - #warning DevIL was designed with libjpeg 6b or higher in mind. Consider upgrading at www.ijg.org - - #endif - - #else - - #include - - #include - - #endif - -#include "il_jpeg.h" - -#include "il_manip.h" - -#include - - - - #ifdef _WIN32 - - #if (defined(IL_USE_PRAGMA_LIBS)) - - #if defined(IL_USE_PRAGMA_LIBS) || defined(__BORLANDC__) - - #pragma comment(lib, "libjpeg.lib") - - #endif - - #endif - - #endif - - - -static ILboolean jpgErrorOccured = IL_FALSE; - - - -// define a protype of ilLoadFromJpegStruct - -ILboolean ilLoadFromJpegStruct(ILvoid *_JpegInfo); - - - -// Internal function used to get the .jpg header from the current file. - -ILvoid iGetJpgHead(ILubyte *Header) - -{ - - Header[0] = igetc(); - - Header[1] = igetc(); - - return; - -} - - - - - -// Internal function used to check if the HEADER is a valid .Jpg header. - -ILboolean iCheckJpg(ILubyte Header[2]) - -{ - - if (Header[0] != 0xFF || Header[1] != 0xD8) - - return IL_FALSE; - - return IL_TRUE; - -} - - - - - -// Internal function to get the header and check it. - -ILboolean iIsValidJpg() - -{ - - ILubyte Head[2]; - - - - iGetJpgHead(Head); - - iseek(-2, IL_SEEK_CUR); // Go ahead and restore to previous state - - - - return iCheckJpg(Head); - -} - - - - - -//! Checks if the file specified in FileName is a valid .jpg file. - -ILboolean ilIsValidJpg(ILconst_string FileName) - -{ - - ILHANDLE JpegFile; - - ILboolean bJpeg = IL_FALSE; - - - - if (!iCheckExtension(FileName, IL_TEXT( "jpg" ) ) && - - !iCheckExtension(FileName, IL_TEXT( "jpe" ) ) && - - !iCheckExtension(FileName, IL_TEXT( "jpeg" ) ) ) - - { - - ilSetError(IL_INVALID_EXTENSION); - - return bJpeg; - - } - - - - JpegFile = iopenr(FileName); - - if (JpegFile == NULL) { - - ilSetError(IL_COULD_NOT_OPEN_FILE); - - return bJpeg; - - } - - - - bJpeg = ilIsValidJpgF(JpegFile); - - icloser(JpegFile); - - - - return bJpeg; - -} - - - - - -//! Checks if the ILHANDLE contains a valid .jpg file at the current position. - -ILboolean ilIsValidJpgF(ILHANDLE File) - -{ - - ILuint FirstPos; - - ILboolean bRet; - - - - iSetInputFile(File); - - FirstPos = itell(); - - bRet = iIsValidJpg(); - - iseek(FirstPos, IL_SEEK_SET); - - - - return bRet; - -} - - - - - -ILboolean ilIsValidJpgL(const ILvoid *Lump, ILuint Size) - -{ - - iSetInputLump(Lump, Size); - - return iIsValidJpg(); - -} - - - - - -#ifndef IL_USE_IJL // Use libjpeg instead of the IJL. - - - -// Overrides libjpeg's stupid error/warning handlers. =P - -void ExitErrorHandle (struct jpeg_common_struct *JpegInfo) - -{ - - ilSetError(IL_LIB_JPEG_ERROR); - - jpgErrorOccured = IL_TRUE; - - return; - -} - -void OutputMsg(struct jpeg_common_struct *JpegInfo) - -{ - - return; - -} - - - - - -//! Reads a jpeg file - -ILboolean ilLoadJpeg(ILconst_string FileName) - -{ - - ILHANDLE JpegFile; - - ILboolean bJpeg = IL_FALSE; - - - - JpegFile = iopenr(FileName); - - if (JpegFile == NULL) { - - ilSetError(IL_COULD_NOT_OPEN_FILE); - - return bJpeg; - - } - - - - bJpeg = ilLoadJpegF(JpegFile); - - icloser(JpegFile); - - - - return bJpeg; - -} - - - - - -//! Reads an already-opened jpeg file - -ILboolean ilLoadJpegF(ILHANDLE File) - -{ - - ILboolean bRet; - - ILuint FirstPos; - - - - iSetInputFile(File); - - FirstPos = itell(); - - bRet = iLoadJpegInternal(); - - iseek(FirstPos, IL_SEEK_SET); - - - - return bRet; - -} - - - - - -// Reads from a memory "lump" containing a jpeg - -ILboolean ilLoadJpegL(const ILvoid *Lump, ILuint Size) - -{ - - iSetInputLump(Lump, Size); - - return iLoadJpegInternal(); - -} - - - - - -typedef struct { - - struct jpeg_source_mgr pub; /* public fields */ - - - - JOCTET * buffer; /* start of buffer */ - - boolean start_of_file; /* have we gotten any data yet? */ - -} iread_mgr; - - - -typedef iread_mgr * iread_ptr; - - - -#define INPUT_BUF_SIZE 4096 // choose an efficiently iread'able size - - - - - -METHODDEF(void) - -init_source (j_decompress_ptr cinfo) - -{ - - iread_ptr src = (iread_ptr) cinfo->src; - - src->start_of_file = TRUE; - -} - - - - - -METHODDEF(boolean) - -fill_input_buffer (j_decompress_ptr cinfo) - -{ - - iread_ptr src = (iread_ptr) cinfo->src; - - ILint nbytes; - - - - nbytes = iread(src->buffer, 1, INPUT_BUF_SIZE); - - - - if (nbytes <= 0) { - - if (src->start_of_file) { // Treat empty input file as fatal error - - //ERREXIT(cinfo, JERR_INPUT_EMPTY); - - jpgErrorOccured = IL_TRUE; - - } - - //WARNMS(cinfo, JWRN_JPEG_EOF); - - // Insert a fake EOI marker - - src->buffer[0] = (JOCTET) 0xFF; - - src->buffer[1] = (JOCTET) JPEG_EOI; - - nbytes = 2; - - return IL_FALSE; - - } - - if (nbytes < INPUT_BUF_SIZE) { - - ilGetError(); // Gets rid of the IL_FILE_READ_ERROR. - - } - - - - src->pub.next_input_byte = src->buffer; - - src->pub.bytes_in_buffer = nbytes; - - src->start_of_file = IL_FALSE; - - - - return IL_TRUE; - -} - - - - - -METHODDEF(void) - -skip_input_data (j_decompress_ptr cinfo, long num_bytes) - -{ - - iread_ptr src = (iread_ptr) cinfo->src; - - - - if (num_bytes > 0) { - - while (num_bytes > (long) src->pub.bytes_in_buffer) { - - num_bytes -= (long) src->pub.bytes_in_buffer; - - (void) fill_input_buffer(cinfo); - - } - - src->pub.next_input_byte += (size_t) num_bytes; - - src->pub.bytes_in_buffer -= (size_t) num_bytes; - - } - -} - - - - - -METHODDEF(void) - -term_source (j_decompress_ptr cinfo) - -{ - - // no work necessary here - -} - - - - - -GLOBAL(void) - -devil_jpeg_read_init (j_decompress_ptr cinfo) - -{ - - iread_ptr src; - - - - if ( cinfo->src == NULL ) { // first time for this JPEG object? - - cinfo->src = (struct jpeg_source_mgr *) - - (*cinfo->mem->alloc_small)( (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(iread_mgr) ); - - src = (iread_ptr) cinfo->src; - - src->buffer = (JOCTET *) - - (*cinfo->mem->alloc_small)( (j_common_ptr)cinfo, JPOOL_PERMANENT, - - INPUT_BUF_SIZE * sizeof(JOCTET) ); - - } - - - - src = (iread_ptr) cinfo->src; - - src->pub.init_source = init_source; - - src->pub.fill_input_buffer = fill_input_buffer; - - src->pub.skip_input_data = skip_input_data; - - src->pub.resync_to_restart = jpeg_resync_to_restart; // use default method - - src->pub.term_source = term_source; - - src->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read - - src->pub.next_input_byte = NULL; // until buffer loaded - -} - - - - - -jmp_buf JpegJumpBuffer; - - - -static void iJpegErrorExit( j_common_ptr cinfo ) - -{ - - ilSetError( IL_LIB_JPEG_ERROR ); - - jpeg_destroy( cinfo ); - - longjmp( JpegJumpBuffer, 1 ); - -} - - - -// Internal function used to load the jpeg. - -ILboolean iLoadJpegInternal() - -{ - - struct jpeg_error_mgr Error; - - struct jpeg_decompress_struct JpegInfo; - - ILboolean result; - - - - if (iCurImage == NULL) - { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - - - JpegInfo.err = jpeg_std_error( &Error ); // init standard error handlers - Error.error_exit = iJpegErrorExit; // add our exit handler - Error.output_message = OutputMsg; - - - - if ((result = setjmp(JpegJumpBuffer) == 0) != IL_FALSE) - { - jpeg_create_decompress( &JpegInfo ); - JpegInfo.do_block_smoothing = IL_TRUE; - JpegInfo.do_fancy_upsampling = IL_TRUE; - - //jpeg_stdio_src(&JpegInfo, iGetFile()); - - devil_jpeg_read_init( &JpegInfo ); - jpeg_read_header( &JpegInfo, IL_TRUE ); - - result = ilLoadFromJpegStruct( &JpegInfo ); - - jpeg_finish_decompress( &JpegInfo ); - jpeg_destroy_decompress( &JpegInfo ); - - } - else - { - jpeg_destroy_decompress(&JpegInfo); - } - - return result; - -} - - - - - -typedef struct - -{ - - struct jpeg_destination_mgr pub; - - JOCTET *buffer; - - ILboolean bah; - -} iwrite_mgr; - - - -typedef iwrite_mgr *iwrite_ptr; - - - -#define OUTPUT_BUF_SIZE 4096 - - - - - -METHODDEF(void) - -init_destination(j_compress_ptr cinfo) - -{ - - iwrite_ptr dest = (iwrite_ptr)cinfo->dest; - - dest->buffer = (JOCTET *) - - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - - OUTPUT_BUF_SIZE * sizeof(JOCTET)); - - - - dest->pub.next_output_byte = dest->buffer; - - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - - return; - -} - - - -METHODDEF(boolean) - -empty_output_buffer (j_compress_ptr cinfo) - -{ - - iwrite_ptr dest = (iwrite_ptr)cinfo->dest; - - iwrite(dest->buffer, 1, OUTPUT_BUF_SIZE); - - dest->pub.next_output_byte = dest->buffer; - - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - - return IL_TRUE; - -} - - - -METHODDEF(void) - -term_destination (j_compress_ptr cinfo) - -{ - - iwrite_ptr dest = (iwrite_ptr)cinfo->dest; - - iwrite(dest->buffer, 1, OUTPUT_BUF_SIZE - dest->pub.free_in_buffer); - - return; - -} - - - - - -GLOBAL(void) - -devil_jpeg_write_init(j_compress_ptr cinfo) - -{ - - iwrite_ptr dest; - - - - if (cinfo->dest == NULL) { // first time for this JPEG object? - - cinfo->dest = (struct jpeg_destination_mgr *) - - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - - sizeof(iwrite_mgr)); - - dest = (iwrite_ptr)cinfo->dest; - - } - - - - dest = (iwrite_ptr)cinfo->dest; - - dest->pub.init_destination = init_destination; - - dest->pub.empty_output_buffer = empty_output_buffer; - - dest->pub.term_destination = term_destination; - - - - return; - -} - - - - - -//! Writes a Jpeg file - -ILboolean ilSaveJpeg(ILconst_string FileName) - -{ - - ILHANDLE JpegFile; - - ILboolean bJpeg = IL_FALSE; - - - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - - if (iFileExists(FileName)) { - - ilSetError(IL_FILE_ALREADY_EXISTS); - - return IL_FALSE; - - } - - } - - - - JpegFile = iopenw(FileName); - - if (JpegFile == NULL) { - - ilSetError(IL_COULD_NOT_OPEN_FILE); - - return bJpeg; - - } - - - - bJpeg = ilSaveJpegF(JpegFile); - - iclosew(JpegFile); - - - - return bJpeg; - -} - - - - - -//! Writes a Jpeg to an already-opened file - -ILboolean ilSaveJpegF(ILHANDLE File) - -{ - - iSetOutputFile(File); - - return iSaveJpegInternal(); - -} - - - - - -//! Writes a Jpeg to a memory "lump" - -ILboolean ilSaveJpegL(ILvoid *Lump, ILuint Size) - -{ - - iSetOutputLump(Lump, Size); - - return iSaveJpegInternal(); - -} - - - - - -// Internal function used to save the Jpeg. - -ILboolean iSaveJpegInternal() - -{ - - struct jpeg_compress_struct JpegInfo; - - struct jpeg_error_mgr Error; - - JSAMPROW row_pointer[1]; - - ILimage *TempImage; - - ILubyte *TempData; - - ILenum Type = 0; - - - - if (iCurImage == NULL) { - - ilSetError(IL_ILLEGAL_OPERATION); - - return IL_FALSE; - - } - - - - /*if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) - - Quality = 85; // Not sure how low we should dare go... - - else - - Quality = 99;*/ - - - - if ((iCurImage->Format != IL_RGB && iCurImage->Format != IL_LUMINANCE) || iCurImage->Bpc != 1) { - - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - - if (TempImage == NULL) { - - return IL_FALSE; - - } - - } - - else { - - TempImage = iCurImage; - - } - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { - - TempData = iGetFlipped(TempImage); - - if (TempData == NULL) { - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - return IL_FALSE; - - } - - } - - else { - - TempData = TempImage->Data; - - } - - - - - - JpegInfo.err = jpeg_std_error(&Error); - - // Now we can initialize the JPEG compression object. - - jpeg_create_compress(&JpegInfo); - - - - //jpeg_stdio_dest(&JpegInfo, JpegFile); - - devil_jpeg_write_init(&JpegInfo); - - - - JpegInfo.image_width = TempImage->Width; // image width and height, in pixels - - JpegInfo.image_height = TempImage->Height; - - JpegInfo.input_components = TempImage->Bpp; // # of color components per pixel - - - - // John Villar's addition - - if (TempImage->Bpp == 1) - - JpegInfo.in_color_space = JCS_GRAYSCALE; - - else - - JpegInfo.in_color_space = JCS_RGB; - - - - jpeg_set_defaults(&JpegInfo); - - - -/*#ifndef IL_USE_JPEGLIB_UNMODIFIED - - Type = iGetInt(IL_JPG_SAVE_FORMAT); - - if (Type == IL_EXIF) { - - JpegInfo.write_JFIF_header = FALSE; - - JpegInfo.write_EXIF_header = TRUE; - - } - - else if (Type == IL_JFIF) { - - JpegInfo.write_JFIF_header = TRUE; - - JpegInfo.write_EXIF_header = FALSE; - - } EXIF not present int libjpeg... - -#else*/ - - Type = Type; - - JpegInfo.write_JFIF_header = TRUE; - -//#endif//IL_USE_JPEGLIB_UNMODIFIED - - - - jpeg_set_quality(&JpegInfo, iGetInt(IL_JPG_QUALITY), IL_TRUE); - - - - jpeg_start_compress(&JpegInfo, IL_TRUE); - - - - //row_stride = image_width * 3; // JSAMPLEs per row in image_buffer - - - - while (JpegInfo.next_scanline < JpegInfo.image_height) { - - // jpeg_write_scanlines expects an array of pointers to scanlines. - - // Here the array is only one element long, but you could pass - - // more than one scanline at a time if that's more convenient. - - row_pointer[0] = &TempData[JpegInfo.next_scanline * TempImage->Bps]; - - (void) jpeg_write_scanlines(&JpegInfo, row_pointer, 1); - - } - - - - // Step 6: Finish compression - - jpeg_finish_compress(&JpegInfo); - - - - // Step 7: release JPEG compression object - - - - // This is an important step since it will release a good deal of memory. - - jpeg_destroy_compress(&JpegInfo); - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) - - ifree(TempData); - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - - - return IL_TRUE; - -} - - - - - - - -#else // Use the IJL instead of libjpeg. - - - - - - - -//! Reads a jpeg file - -ILboolean ilLoadJpeg(ILconst_string FileName) - -{ - - if (!iFileExists(FileName)) { - - ilSetError(IL_COULD_NOT_OPEN_FILE); - - return IL_FALSE; - - } - - return iLoadJpegInternal(FileName, NULL, 0); - -} - - - - - -// Reads from a memory "lump" containing a jpeg - -ILboolean ilLoadJpegL(ILvoid *Lump, ILuint Size) - -{ - - return iLoadJpegInternal(NULL, Lump, Size); - -} - - - - - -// Internal function used to load the jpeg. - -ILboolean iLoadJpegInternal(ILstring FileName, ILvoid *Lump, ILuint Size) - -{ - - JPEG_CORE_PROPERTIES Image; - - - - if (iCurImage == NULL) { - - ilSetError(IL_ILLEGAL_OPERATION); - - return IL_FALSE; - - } - - - - if (ijlInit(&Image) != IJL_OK) { - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - - - if (FileName != NULL) { - - Image.JPGFile = FileName; - - if (ijlRead(&Image, IJL_JFILE_READPARAMS) != IJL_OK) { - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - else { - - Image.JPGBytes = Lump; - - Image.JPGSizeBytes = Size > 0 ? Size : UINT_MAX; - - if (ijlRead(&Image, IJL_JBUFF_READPARAMS) != IJL_OK) { - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - - - switch (Image.JPGChannels) - - { - - case 1: - - Image.JPGColor = IJL_G; - - Image.DIBChannels = 1; - - Image.DIBColor = IJL_G; - - iCurImage->Format = IL_LUMINANCE; - - break; - - - - case 3: - - Image.JPGColor = IJL_YCBCR; - - Image.DIBChannels = 3; - - Image.DIBColor = IJL_RGB; - - iCurImage->Format = IL_RGB; - - break; - - - - case 4: - - Image.JPGColor = IJL_YCBCRA_FPX; - - Image.DIBChannels = 4; - - Image.DIBColor = IJL_RGBA_FPX; - - iCurImage->Format = IL_RGBA; - - break; - - - - default: - - // This catches everything else, but no - - // color twist will be performed by the IJL. - - /*Image.DIBColor = (IJL_COLOR)IJL_OTHER; - - Image.JPGColor = (IJL_COLOR)IJL_OTHER; - - Image.DIBChannels = Image.JPGChannels; - - break;*/ - - ijlFree(&Image); - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - - - if (!ilTexImage(Image.JPGWidth, Image.JPGHeight, 1, (ILubyte)Image.DIBChannels, iCurImage->Format, IL_UNSIGNED_BYTE, NULL)) { - - ijlFree(&Image); - - return IL_FALSE; - - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - - - Image.DIBWidth = Image.JPGWidth; - - Image.DIBHeight = Image.JPGHeight; - - Image.DIBPadBytes = 0; - - Image.DIBBytes = iCurImage->Data; - - - - if (FileName != NULL) { - - if (ijlRead(&Image, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { - - ijlFree(&Image); - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - else { - - if (ijlRead(&Image, IJL_JBUFF_READWHOLEIMAGE) != IJL_OK) { - - ijlFree(&Image); - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - - - ijlFree(&Image); - - ilFixImage(); - - - - return IL_TRUE; - -} - - - - - -//! Writes a Jpeg file - -ILboolean ilSaveJpeg(ILconst_string FileName) - -{ - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - - if (iFileExists(FileName)) { - - ilSetError(IL_FILE_ALREADY_EXISTS); - - return IL_FALSE; - - } - - } - - - - return iSaveJpegInternal(FileName, NULL, 0); - -} - - - - - -//! Writes a Jpeg to a memory "lump" - -ILboolean ilSaveJpegL(ILvoid *Lump, ILuint Size) - -{ - - return iSaveJpegInternal(NULL, Lump, Size); - -} - - - - - -// Internal function used to save the Jpeg. - -ILboolean iSaveJpegInternal(ILstring FileName, ILvoid *Lump, ILuint Size) - -{ - - JPEG_CORE_PROPERTIES Image; - - ILuint Quality; - - ILimage *TempImage; - - ILubyte *TempData; - - - - imemclear(&Image, sizeof(JPEG_CORE_PROPERTIES)); - - - - if (iCurImage == NULL) { - - ilSetError(IL_ILLEGAL_OPERATION); - - return IL_FALSE; - - } - - if (FileName == NULL && Lump == NULL) { - - ilSetError(IL_INVALID_PARAM); - - return IL_FALSE; - - } - - - - if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) - - Quality = 85; // Not sure how low we should dare go... - - else - - Quality = 99; - - - - if (ijlInit(&Image) != IJL_OK) { - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - - - if ((iCurImage->Format != IL_RGB && iCurImage->Format != IL_RGBA && iCurImage->Format != IL_LUMINANCE) - - || iCurImage->Bpc != 1) { - - if (iCurImage->Format == IL_BGRA) - - Temp = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); - - else - - Temp = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - - if (Temp == NULL) { - - return IL_FALSE; - - } - - } - - else { - - Temp = iCurImage; - - } - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { - - TempData = iGetFlipped(TempImage); - - if (TempData == NULL) { - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - return IL_FALSE; - - } - - } - - else { - - TempData = TempImage->Data; - - } - - - - // Setup DIB - - Image.DIBWidth = TempImage->Width; - - Image.DIBHeight = TempImage->Height; - - Image.DIBChannels = TempImage->Bpp; - - Image.DIBBytes = TempData; - - Image.DIBPadBytes = 0; - - - - // Setup JPEG - - Image.JPGWidth = TempImage->Width; - - Image.JPGHeight = TempImage->Height; - - Image.JPGChannels = TempImage->Bpp; - - - - switch (Temp->Bpp) - - { - - case 1: - - Image.DIBColor = IJL_G; - - Image.JPGColor = IJL_G; - - Image.JPGSubsampling = IJL_NONE; - - break; - - case 3: - - Image.DIBColor = IJL_RGB; - - Image.JPGColor = IJL_YCBCR; - - Image.JPGSubsampling = IJL_411; - - break; - - case 4: - - Image.DIBColor = IJL_RGBA_FPX; - - Image.JPGColor = IJL_YCBCRA_FPX; - - Image.JPGSubsampling = IJL_4114; - - break; - - } - - - - if (FileName != NULL) { - - Image.JPGFile = FileName; - - if (ijlWrite(&Image, IJL_JFILE_WRITEWHOLEIMAGE) != IJL_OK) { - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - else { - - Image.JPGBytes = Lump; - - Image.JPGSizeBytes = Size; - - if (ijlWrite(&Image, IJL_JBUFF_WRITEWHOLEIMAGE) != IJL_OK) { - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - ilSetError(IL_LIB_JPEG_ERROR); - - return IL_FALSE; - - } - - } - - - - ijlFree(&Image); - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) - - ifree(TempData); - - if (Temp != iCurImage) - - ilCloseImage(Temp); - - - - return IL_TRUE; - -} - - - -#endif//IL_USE_IJL - - - - - -// Access point for applications wishing to use the jpeg library directly in - -// conjunction with DevIL. - -// - -// The decompressor must be set up with an input source and all desired parameters - -// this function is called. The caller must call jpeg_finish_decompress because - -// the caller may still need decompressor after calling this for e.g. examining - -// saved markers. - -ILboolean ilLoadFromJpegStruct(ILvoid *_JpegInfo) - -{ - -#ifndef IL_NO_JPG - -#ifndef IL_USE_IJL - - // sam. void (*errorHandler)(j_common_ptr); - - ILubyte *TempPtr[1]; - - ILuint Returned; - - j_decompress_ptr JpegInfo = (j_decompress_ptr)_JpegInfo; - - - - //added on 2003-08-31 as explained in sf bug 596793 - - jpgErrorOccured = IL_FALSE; - - - - // sam. errorHandler = JpegInfo->err->error_exit; - - // sam. JpegInfo->err->error_exit = ExitErrorHandle; - - jpeg_start_decompress((j_decompress_ptr)JpegInfo); - - - - if (!ilTexImage(JpegInfo->output_width, JpegInfo->output_height, 1, (ILubyte)JpegInfo->output_components, 0, IL_UNSIGNED_BYTE, NULL)) { - - return IL_FALSE; - - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - - - switch (iCurImage->Bpp) - - { - - case 1: - - iCurImage->Format = IL_LUMINANCE; - - break; - - case 3: - - iCurImage->Format = IL_RGB; - - break; - - case 4: - - iCurImage->Format = IL_RGBA; - - break; - - default: - - // Anyway to get here? Need to error out or something... - - break; - - } - - - - TempPtr[0] = iCurImage->Data; - - while (JpegInfo->output_scanline < JpegInfo->output_height) { - - Returned = jpeg_read_scanlines(JpegInfo, TempPtr, 1); // anyway to make it read all at once? - - TempPtr[0] += iCurImage->Bps; - - if (Returned == 0) - - break; - - } - - - - // sam. JpegInfo->err->error_exit = errorHandler; - - - - if (jpgErrorOccured) - - return IL_FALSE; - - - - ilFixImage(); - - return IL_TRUE; - -#endif - -#endif - - return IL_FALSE; - -} - - - - - - - -// Access point for applications wishing to use the jpeg library directly in - -// conjunction with DevIL. - -// - -// The caller must set up the desired parameters by e.g. calling - -// jpeg_set_defaults and overriding the parameters the caller wishes - -// to change, such as quality, before calling this function. The caller - -// is also responsible for calling jpeg_finish_compress in case the - -// caller still needs to compressor for something. - -// - -ILboolean ilSaveFromJpegStruct(ILvoid *_JpegInfo) - -{ - -#ifndef IL_NO_JPG - -#ifndef IL_USE_IJL - - void (*errorHandler)(j_common_ptr); - - JSAMPROW row_pointer[1]; - - ILimage *TempImage; - - ILubyte *TempData; - - j_compress_ptr JpegInfo = (j_compress_ptr)_JpegInfo; - - - - if (iCurImage == NULL) { - - ilSetError(IL_ILLEGAL_OPERATION); - - return IL_FALSE; - - } - - - - //added on 2003-08-31 as explained in sf bug 596793 - - jpgErrorOccured = IL_FALSE; - - - - errorHandler = JpegInfo->err->error_exit; - - JpegInfo->err->error_exit = ExitErrorHandle; - - - - - - if ((iCurImage->Format != IL_RGB && iCurImage->Format != IL_LUMINANCE) || iCurImage->Bpc != 1) { - - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - - if (TempImage == NULL) { - - return IL_FALSE; - - } - - } - - else { - - TempImage = iCurImage; - - } - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { - - TempData = iGetFlipped(TempImage); - - if (TempData == NULL) { - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - return IL_FALSE; - - } - - } - - else { - - TempData = TempImage->Data; - - } - - - - JpegInfo->image_width = TempImage->Width; // image width and height, in pixels - - JpegInfo->image_height = TempImage->Height; - - JpegInfo->input_components = TempImage->Bpp; // # of color components per pixel - - - - jpeg_start_compress(JpegInfo, IL_TRUE); - - - - //row_stride = image_width * 3; // JSAMPLEs per row in image_buffer - - - - while (JpegInfo->next_scanline < JpegInfo->image_height) { - - // jpeg_write_scanlines expects an array of pointers to scanlines. - - // Here the array is only one element long, but you could pass - - // more than one scanline at a time if that's more convenient. - - row_pointer[0] = &TempData[JpegInfo->next_scanline * TempImage->Bps]; - - (void) jpeg_write_scanlines(JpegInfo, row_pointer, 1); - - } - - - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) - - ifree(TempData); - - if (TempImage != iCurImage) - - ilCloseImage(TempImage); - - - - return (!jpgErrorOccured); - -#endif - -#endif - - return IL_FALSE; - -} - - - -#endif//IL_NO_JPG - - - diff --git a/win32/devil/src/il_lif.c b/win32/devil/src/il_lif.c deleted file mode 100644 index fd09b6bbf..000000000 --- a/win32/devil/src/il_lif.c +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_lif.c -// -// Description: Reads a Homeworld image. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_LIF -#include "il_lif.h" - - -//! Checks if the file specified in FileName is a valid Lif file. -ILboolean ilIsValidLif(ILconst_string FileName) -{ - ILHANDLE LifFile; - ILboolean bLif = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("lif"))) { - ilSetError(IL_INVALID_EXTENSION); - return bLif; - } - - LifFile = iopenr(FileName); - if (LifFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bLif; - } - - bLif = ilIsValidLifF(LifFile); - icloser(LifFile); - - return bLif; -} - - -//! Checks if the ILHANDLE contains a valid Lif file at the current position. -ILboolean ilIsValidLifF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidLif(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid Lif lump. -ILboolean ilIsValidLifL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidLif(); -} - - -// Internal function used to get the Lif header from the current file. -ILboolean iGetLifHead(LIF_HEAD *Header) -{ - - iread(Header->Id, 1, 8); - - Header->Version = GetLittleUInt(); - - Header->Flags = GetLittleUInt(); - - Header->Width = GetLittleUInt(); - - Header->Height = GetLittleUInt(); - - Header->PaletteCRC = GetLittleUInt(); - - Header->ImageCRC = GetLittleUInt(); - - Header->PalOffset = GetLittleUInt(); - - Header->TeamEffect0 = GetLittleUInt(); - - Header->TeamEffect1 = GetLittleUInt(); - - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidLif() -{ - LIF_HEAD Head; - - if (!iGetLifHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(LIF_HEAD), IL_SEEK_CUR); - - return iCheckLif(&Head); -} - - -// Internal function used to check if the HEADER is a valid Lif header. -ILboolean iCheckLif(LIF_HEAD *Header) -{ - if (Header->Version != 260 || Header->Flags != 50) - return IL_FALSE; - if (stricmp(Header->Id, "Willy 7")) - return IL_FALSE; - return IL_TRUE; -} - - -//! Reads a .Lif file -ILboolean ilLoadLif(ILconst_string FileName) -{ - ILHANDLE LifFile; - ILboolean bLif = IL_FALSE; - - LifFile = iopenr(FileName); - if (LifFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bLif; - } - - bLif = ilLoadLifF(LifFile); - icloser(LifFile); - - return bLif; -} - - -//! Reads an already-opened .Lif file -ILboolean ilLoadLifF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadLifInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .Lif -ILboolean ilLoadLifL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadLifInternal(); -} - - -ILboolean iLoadLifInternal() -{ - LIF_HEAD LifHead; - ILuint i; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetLifHead(&LifHead)) - return IL_FALSE; - - if (!ilTexImage(LifHead.Width, LifHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(1024); - if (iCurImage->Pal.Palette == NULL) - return IL_FALSE; - iCurImage->Pal.PalSize = 1024; - iCurImage->Pal.PalType = IL_PAL_RGBA32; - - if (iread(iCurImage->Data, LifHead.Width * LifHead.Height, 1) != 1) - return IL_FALSE; - if (iread(iCurImage->Pal.Palette, 1, 1024) != 1024) - return IL_FALSE; - - // Each data offset is offset by -1, so we add one. - for (i = 0; i < iCurImage->SizeOfData; i++) { - iCurImage->Data[i]++; - } - - ilFixImage(); - - return IL_TRUE; -} - -#endif//IL_NO_LIF diff --git a/win32/devil/src/il_main.c b/win32/devil/src/il_main.c deleted file mode 100644 index ffde20520..000000000 --- a/win32/devil/src/il_main.c +++ /dev/null @@ -1,30 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/16/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_main.c -// -// Description: Startup function -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" - -/* Only needed for MSVC++ unless extended to actually do something =) */ -#if defined(_WIN32) && defined(_MSC_VER) -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - hModule; ul_reason_for_call; lpReserved; - - if (ul_reason_for_call == DLL_PROCESS_ATTACH) { - //ilInit(); - } - - return TRUE; -} -#endif - - diff --git a/win32/devil/src/il_manip.c b/win32/devil/src/il_manip.c deleted file mode 100644 index 2604457e2..000000000 --- a/win32/devil/src/il_manip.c +++ /dev/null @@ -1,882 +0,0 @@ -//----------------------------------------------------------------------------- - -// Description: Image manipulation -#include "il_internal.h" -#include -#include "il_manip.h" - -ILAPI ILvoid ILAPIENTRY iFlipBuffer( ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num ) { - ILubyte *StartPtr, *EndPtr; - ILuint y, d; - const ILuint size = line_num * line_size; - - for( d = 0; d < depth; d++ ) { - StartPtr = buff + d * size; - EndPtr = buff + d * size + size; - - for( y = 0; y < (line_num/2); y++ ) { - EndPtr -= line_size; - iMemSwap(StartPtr,EndPtr,line_size); - StartPtr += line_size; - } - } -} - -// Just created for internal use. -ILubyte* iFlipNewBuffer( ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num ) { - ILubyte *data; - ILubyte *s1, *s2; - ILuint y, d; - const ILuint size = line_num * line_size; - - if( (data = (ILubyte*)ialloc(depth*size)) == NULL) - return IL_FALSE; - - for( d = 0; d < depth; d++ ) { - s1 = buff + d * size; - s2 = data + d * size+size; - - for( y = 0; y < line_num; y++ ) { - s2 -= line_size; - memcpy(s2,s1,line_size); - s1 += line_size; - } - } - return data; -} - - -// Flips an image over its x axis -ILboolean ilFlipImage() { - if( iCurImage == NULL ) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iCurImage->Origin = (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) ? - IL_ORIGIN_UPPER_LEFT : IL_ORIGIN_LOWER_LEFT; - - iFlipBuffer(iCurImage->Data,iCurImage->Depth,iCurImage->Bps,iCurImage->Height); - - return IL_TRUE; -} - -// Just created for internal use. -ILubyte* ILAPIENTRY iGetFlipped(ILimage *img) { - if( img == NULL ) { - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - return iFlipNewBuffer(img->Data,img->Depth,img->Bps,img->Height); -} - - -//@JASON New routine created 28/03/2001 -//! Mirrors an image over its y axis -ILboolean ILAPIENTRY iMirror() { - ILubyte *Data, *DataPtr, *Temp; - ILuint y, d, PixLine; - ILint x, c; - ILushort *ShortPtr, *TempShort; - ILuint *IntPtr, *TempInt; - ILdouble *DblPtr, *TempDbl; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Data = (ILubyte*)ialloc(iCurImage->SizeOfData); - if (Data == NULL) - return IL_FALSE; - - PixLine = iCurImage->Bps / iCurImage->Bpc; - switch (iCurImage->Bpc) - { - case 1: - Temp = iCurImage->Data; - for (d = 0; d < iCurImage->Depth; d++) { - DataPtr = Data + d * iCurImage->SizeOfPlane; - for (y = 0; y < iCurImage->Height; y++) { - for (x = iCurImage->Width - 1; x >= 0; x--) { - for (c = 0; c < iCurImage->Bpp; c++, Temp++) { - DataPtr[y * PixLine + x * iCurImage->Bpp + c] = *Temp; - } - } - } - } - break; - - case 2: - TempShort = (ILushort*)iCurImage->Data; - for (d = 0; d < iCurImage->Depth; d++) { - ShortPtr = (ILushort*)(Data + d * iCurImage->SizeOfPlane); - for (y = 0; y < iCurImage->Height; y++) { - for (x = iCurImage->Width - 1; x >= 0; x--) { - for (c = 0; c < iCurImage->Bpp; c++, TempShort++) { - ShortPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempShort; - } - } - } - } - break; - - case 4: - TempInt = (ILuint*)iCurImage->Data; - for (d = 0; d < iCurImage->Depth; d++) { - IntPtr = (ILuint*)(Data + d * iCurImage->SizeOfPlane); - for (y = 0; y < iCurImage->Height; y++) { - for (x = iCurImage->Width - 1; x >= 0; x--) { - for (c = 0; c < iCurImage->Bpp; c++, TempInt++) { - IntPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempInt; - } - } - } - } - break; - - case 8: - TempDbl = (ILdouble*)iCurImage->Data; - for (d = 0; d < iCurImage->Depth; d++) { - DblPtr = (ILdouble*)(Data + d * iCurImage->SizeOfPlane); - for (y = 0; y < iCurImage->Height; y++) { - for (x = iCurImage->Width - 1; x >= 0; x--) { - for (c = 0; c < iCurImage->Bpp; c++, TempDbl++) { - DblPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempDbl; - } - } - } - } - break; - } - - ifree(iCurImage->Data); - iCurImage->Data = Data; - - return IL_TRUE; -} - - -// Should we add type to the parameter list? -// Copies a 1d block of pixels to the buffer pointed to by Data. -ILboolean ilCopyPixels1D(ILuint XOff, ILuint Width, ILvoid *Data) -{ - ILuint x, c, NewBps, NewOff, PixBpp; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (iCurImage->Width < XOff + Width) { - NewBps = (iCurImage->Width - XOff) * PixBpp; - } - else { - NewBps = Width * PixBpp; - } - NewOff = XOff * PixBpp; - - for (x = 0; x < NewBps; x += PixBpp) { - for (c = 0; c < PixBpp; c++) { - Temp[x + c] = TempData[(x + NewOff) + c]; - } - } - - if (TempData != iCurImage->Data) - ifree(TempData); - - return IL_TRUE; -} - - -// Copies a 2d block of pixels to the buffer pointed to by Data. -ILboolean ilCopyPixels2D(ILuint XOff, ILuint YOff, ILuint Width, ILuint Height, ILvoid *Data) -{ - ILuint x, y, c, NewBps, DataBps, NewXOff, NewHeight, PixBpp; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (iCurImage->Width < XOff + Width) - NewBps = (iCurImage->Width - XOff) * PixBpp; - else - NewBps = Width * PixBpp; - - if (iCurImage->Height < YOff + Height) - NewHeight = iCurImage->Height - YOff; - else - NewHeight = Height; - - DataBps = Width * PixBpp; - NewXOff = XOff * PixBpp; - - for (y = 0; y < NewHeight; y++) { - for (x = 0; x < NewBps; x += PixBpp) { - for (c = 0; c < PixBpp; c++) { - Temp[y * DataBps + x + c] = - TempData[(y + YOff) * iCurImage->Bps + x + NewXOff + c]; - } - } - } - - if (TempData != iCurImage->Data) - ifree(TempData); - - return IL_TRUE; -} - - -// Copies a 3d block of pixels to the buffer pointed to by Data. -ILboolean ilCopyPixels3D(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILvoid *Data) -{ - ILuint x, y, z, c, NewBps, DataBps, NewSizePlane, NewH, NewD, NewXOff, PixBpp; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (iCurImage->Width < XOff + Width) - NewBps = (iCurImage->Width - XOff) * PixBpp; - else - NewBps = Width * PixBpp; - - if (iCurImage->Height < YOff + Height) - NewH = iCurImage->Height - YOff; - else - NewH = Height; - - if (iCurImage->Depth < ZOff + Depth) - NewD = iCurImage->Depth - ZOff; - else - NewD = Depth; - - DataBps = Width * PixBpp; - NewSizePlane = NewBps * NewH; - - NewXOff = XOff * PixBpp; - - for (z = 0; z < NewD; z++) { - for (y = 0; y < NewH; y++) { - for (x = 0; x < NewBps; x += PixBpp) { - for (c = 0; c < PixBpp; c++) { - Temp[z * NewSizePlane + y * DataBps + x + c] = - TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + x + NewXOff + c]; - //TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * iCurImage->Bpp + c]; - } - } - } - } - - if (TempData != iCurImage->Data) - ifree(TempData); - - return IL_TRUE; -} - - -ILuint ILAPIENTRY ilCopyPixels(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, ILvoid *Data) -{ - ILvoid *Converted = NULL; - ILubyte *TempBuff = NULL; - ILuint SrcSize, DestSize; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return 0; - } - DestSize = Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type); - if (DestSize == 0) { - return DestSize; - } - if (Data == NULL) { - ilSetError(IL_INVALID_PARAM); - return 0; - } - SrcSize = Width * Height * Depth * iCurImage->Bpp * iCurImage->Bpc; - - if (Format == iCurImage->Format && Type == iCurImage->Type) { - TempBuff = (ILubyte*)Data; - } - else { - TempBuff = (ILubyte*)ialloc(SrcSize); - if (TempBuff == NULL) { - return 0; - } - } - - if (YOff + Height <= 1) { - if (!ilCopyPixels1D(XOff, Width, TempBuff)) { - goto failed; - } - } - else if (ZOff + Depth <= 1) { - if (!ilCopyPixels2D(XOff, YOff, Width, Height, TempBuff)) { - goto failed; - } - } - else { - if (!ilCopyPixels3D(XOff, YOff, ZOff, Width, Height, Depth, TempBuff)) { - goto failed; - } - } - - if (Format == iCurImage->Format && Type == iCurImage->Type) { - return IL_TRUE; - } - - Converted = ilConvertBuffer(SrcSize, iCurImage->Format, Format, iCurImage->Type, Type, TempBuff); - if (Converted == NULL) - goto failed; - - memcpy(Data, Converted, DestSize); - - ifree(Converted); - if (TempBuff != Data) - ifree(TempBuff); - - return DestSize; - -failed: - if (TempBuff != Data) - ifree(TempBuff); - ifree(Converted); - return 0; -} - - -ILboolean ilSetPixels1D(ILint XOff, ILuint Width, ILvoid *Data) -{ - ILuint c, SkipX = 0, PixBpp; - ILint x, NewWidth; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (XOff < 0) { - SkipX = abs(XOff); - XOff = 0; - } - - if (iCurImage->Width < XOff + Width) { - NewWidth = iCurImage->Width - XOff; - } - else { - NewWidth = Width; - } - - NewWidth -= SkipX; - - for (x = 0; x < NewWidth; x++) { - for (c = 0; c < PixBpp; c++) { - TempData[(x + XOff) * PixBpp + c] = Temp[(x + SkipX) * PixBpp + c]; - } - } - - if (TempData != iCurImage->Data) { - ifree(iCurImage->Data); - iCurImage->Data = TempData; - } - - return IL_TRUE; -} - - -ILboolean ilSetPixels2D(ILint XOff, ILint YOff, ILuint Width, ILuint Height, ILvoid *Data) -{ - ILuint c, SkipX = 0, SkipY = 0, NewBps, PixBpp; - ILint x, y, NewWidth, NewHeight; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (XOff < 0) { - SkipX = abs(XOff); - XOff = 0; - } - if (YOff < 0) { - SkipY = abs(YOff); - YOff = 0; - } - - if (iCurImage->Width < XOff + Width) - NewWidth = iCurImage->Width - XOff; - else - NewWidth = Width; - NewBps = Width * PixBpp; - - if (iCurImage->Height < YOff + Height) - NewHeight = iCurImage->Height - YOff; - else - NewHeight = Height; - - NewWidth -= SkipX; - NewHeight -= SkipY; - - for (y = 0; y < NewHeight; y++) { - for (x = 0; x < NewWidth; x++) { - for (c = 0; c < PixBpp; c++) { - TempData[(y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] = - Temp[(y + SkipY) * NewBps + (x + SkipX) * PixBpp + c]; - } - } - } - - if (TempData != iCurImage->Data) { - ifree(iCurImage->Data); - iCurImage->Data = TempData; - } - - return IL_TRUE; -} - - -ILboolean ilSetPixels3D(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILvoid *Data) -{ - ILuint SkipX = 0, SkipY = 0, SkipZ = 0, c, NewBps, NewSizePlane, PixBpp; - ILint x, y, z, NewW, NewH, NewD; - ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) { - TempData = iGetFlipped(iCurImage); - if (TempData == NULL) - return IL_FALSE; - } - } - - PixBpp = iCurImage->Bpp * iCurImage->Bpc; - - if (XOff < 0) { - SkipX = abs(XOff); - XOff = 0; - } - if (YOff < 0) { - SkipY = abs(YOff); - YOff = 0; - } - if (ZOff < 0) { - SkipZ = abs(ZOff); - ZOff = 0; - } - - if (iCurImage->Width < XOff + Width) - NewW = iCurImage->Width - XOff; - else - NewW = Width; - NewBps = Width * PixBpp; - - if (iCurImage->Height < YOff + Height) - NewH = iCurImage->Height - YOff; - else - NewH = Height; - - if (iCurImage->Depth < ZOff + Depth) - NewD = iCurImage->Depth - ZOff; - else - NewD = Depth; - NewSizePlane = NewBps * Height; - - NewW -= SkipX; - NewH -= SkipY; - NewD -= SkipZ; - - for (z = 0; z < NewD; z++) { - for (y = 0; y < NewH; y++) { - for (x = 0; x < NewW; x++) { - for (c = 0; c < PixBpp; c++) { - TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] = - Temp[(z + SkipZ) * NewSizePlane + (y + SkipY) * NewBps + (x + SkipX) * PixBpp + c]; - } - } - } - } - - if (TempData != iCurImage->Data) { - ifree(iCurImage->Data); - iCurImage->Data = TempData; - } - - return IL_TRUE; -} - - -ILvoid ILAPIENTRY ilSetPixels(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, ILvoid *Data) -{ - ILvoid *Converted; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return; - } - if (Data == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - if (Format == iCurImage->Format && Type == iCurImage->Type) { - Converted = (ILvoid*)Data; - } - else { - Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, iCurImage->Format, iCurImage->Type, Type, Data); - if (!Converted) - return; - } - - if (YOff + Height <= 1) { - ilSetPixels1D(XOff, Width, Converted); - } - else if (ZOff + Depth <= 1) { - ilSetPixels2D(XOff, YOff, Width, Height, Converted); - } - else { - ilSetPixels3D(XOff, YOff, ZOff, Width, Height, Depth, Converted); - } - - if (Format == iCurImage->Format && Type == iCurImage->Type) { - return; - } - - if (Converted != Data) - ifree(Converted); - - return; -} - - - -// Ripped from Platinum (DooMWiz's sources) -// This could very well easily be changed to a 128x128 image instead...needed? - -//! Creates an ugly 64x64 black and yellow checkerboard image. -ILboolean ILAPIENTRY ilDefaultImage() -{ - ILubyte *TempData; - ILubyte Yellow[3] = { 18, 246, 243 }; - ILubyte Black[3] = { 0, 0, 0 }; - ILubyte *ColorPtr = Yellow; // The start color - ILboolean Color = IL_TRUE; - - // Loop Variables - ILint v, w, x, y; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!ilTexImage(64, 64, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - TempData = iCurImage->Data; - - for (v = 0; v < 8; v++) { - // We do this because after a "block" line ends, the next row of blocks - // above starts with the ending colour, but the very inner loop switches them. - if (Color) { - Color = IL_FALSE; - ColorPtr = Black; - } - else { - Color = IL_TRUE; - ColorPtr = Yellow; - } - - for (w = 0; w < 8; w++) { - for (x = 0; x < 8; x++) { - for (y = 0; y < 8; y++, TempData += iCurImage->Bpp) { - TempData[0] = ColorPtr[0]; - TempData[1] = ColorPtr[1]; - TempData[2] = ColorPtr[2]; - } - - // Switch to alternate between black and yellow - if (Color) { - Color = IL_FALSE; - ColorPtr = Black; - } - else { - Color = IL_TRUE; - ColorPtr = Yellow; - } - } - } - } - - return IL_TRUE; -} - - -ILubyte* ILAPIENTRY ilGetAlpha(ILenum Type) -{ - ILimage *TempImage; - ILubyte *Alpha; - ILushort *AlphaShort; - ILuint *AlphaInt; - ILdouble *AlphaDbl; - ILuint i, j, Bpc, Size, AlphaOff; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Bpc = ilGetBpcType(Type); - if (Bpc == 0) { - ilSetError(IL_INVALID_PARAM); - return NULL; - } - - if (iCurImage->Type == Type) { - TempImage = iCurImage; - } else { - TempImage = iConvertImage(iCurImage, iCurImage->Format, Type); - if (TempImage == NULL) - return NULL; - } - - Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * TempImage->Bpp; - Alpha = (ILubyte*)ialloc(Size / TempImage->Bpp * Bpc); - if (Alpha == NULL) { - if (TempImage != iCurImage) - ilCloseImage(TempImage); - return NULL; - } - - switch (TempImage->Format) - { - case IL_RGB: - case IL_BGR: - case IL_LUMINANCE: - case IL_COLOUR_INDEX: // @TODO: Make IL_COLOUR_INDEX separate. - memset(Alpha, 0xFF, Size / TempImage->Bpp * Bpc); - if (TempImage != iCurImage) - ilCloseImage(TempImage); - return Alpha; - } - - if (TempImage->Format == IL_LUMINANCE_ALPHA) - AlphaOff = 2; - else - AlphaOff = 4; - - switch (TempImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - Alpha[j] = TempImage->Data[i]; - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - AlphaShort = (ILushort*)Alpha; - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - AlphaShort[j] = ((ILushort*)TempImage->Data)[i]; - break; - - case IL_INT: - case IL_UNSIGNED_INT: - case IL_FLOAT: // Can throw float in here, because it's the same size. - AlphaInt = (ILuint*)Alpha; - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - AlphaInt[j] = ((ILuint*)TempImage->Data)[i]; - break; - - case IL_DOUBLE: - AlphaDbl = (ILdouble*)Alpha; - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - AlphaDbl[j] = ((ILdouble*)TempImage->Data)[i]; - break; - } - - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - return Alpha; -} - -// sets the Alpha value to a specific value for each pixel in the image -ILboolean ILAPIENTRY ilSetAlpha( ILdouble AlphaValue ) { - ILboolean ret = IL_TRUE; - ILuint i,Size; - ILimage *image = iCurImage; - ILuint AlphaOff; - - if( image == NULL ) - { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - AlphaValue = clamp(AlphaValue); - - switch( image->Format ) { - case IL_RGB: - ret = ilConvertImage(IL_RGBA,image->Type); - case IL_RGBA: - AlphaOff = 4; - break; - case IL_BGR: - ret = ilConvertImage(IL_BGRA,image->Type); - case IL_BGRA: - AlphaOff = 4; - break; - case IL_LUMINANCE: - ret = ilConvertImage(IL_LUMINANCE_ALPHA,image->Type); - case IL_LUMINANCE_ALPHA: - AlphaOff = 2; - break; - case IL_COLOUR_INDEX: //@TODO use palette with alpha - ret = ilConvertImage(IL_RGBA,image->Type); - AlphaOff = 4; - break; - } - if( ret == IL_FALSE ) { - return IL_FALSE; - // error has been set by ilConvertImage - } - Size = image->Width * image->Height * image->Depth * image->Bpp; - - switch( iCurImage->Type ) { - case IL_BYTE: - case IL_UNSIGNED_BYTE: { - const ILbyte alpha = (ILubyte)(AlphaValue * IL_MAX_UNSIGNED_BYTE + .5); - for( i = AlphaOff-1; i < Size; i += AlphaOff) - image->Data[i] = alpha; - break; } - case IL_SHORT: - case IL_UNSIGNED_SHORT: { - const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_SHORT + .5); - for( i = AlphaOff-1; i < Size; i += AlphaOff) - ((ILushort*)image->Data)[i] = alpha; - break; } - case IL_INT: - case IL_UNSIGNED_INT: { - const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_INT + .5); - for( i = AlphaOff-1; i < Size; i += AlphaOff) - ((ILushort*)image->Data)[i] = alpha; - break; } - case IL_FLOAT: { - const ILfloat alpha = (ILfloat)AlphaValue; - for( i = AlphaOff-1; i < Size; i += AlphaOff ) - ((ILfloat*)image->Data)[i] = alpha; - break; } - case IL_DOUBLE: { - const ILdouble alpha = AlphaValue; - for( i = AlphaOff-1; i < Size; i += AlphaOff ) - ((ILdouble*)image->Data)[i] = alpha; - break; } - } - return IL_TRUE; -} - -ILvoid ILAPIENTRY ilModAlpha( ILdouble AlphaValue ) { - ILuint AlphaOff = 0; - ILboolean ret = IL_FALSE; - ILuint i,j,Size; - - union { - ILubyte alpha_byte; - ILushort alpha_short; - ILuint alpha_int; - ILfloat alpha_float; - ILdouble alpha_double; - } Alpha; - - - if( iCurImage == NULL ) { - ilSetError(IL_ILLEGAL_OPERATION); - return; - } - - switch( iCurImage->Format ) { - case IL_RGB: - ret = ilConvertImage(IL_RGBA,iCurImage->Type); - AlphaOff = 4; - break; - case IL_BGR: - ret = ilConvertImage(IL_BGRA,iCurImage->Type); - AlphaOff = 4; - break; - case IL_LUMINANCE: - ret = ilConvertImage(IL_LUMINANCE_ALPHA,iCurImage->Type); - AlphaOff = 2; - break; - case IL_COLOUR_INDEX: - ret = ilConvertImage(IL_RGBA,iCurImage->Type); - AlphaOff = 4; - break; - } - Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * iCurImage->Bpp; - - if( !ret ) return; - - switch (iCurImage->Type) { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - Alpha.alpha_byte = (ILubyte)(AlphaValue * 0x000000FF + .5); - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - iCurImage->Data[i] = Alpha.alpha_byte; - break; - case IL_SHORT: - case IL_UNSIGNED_SHORT: - Alpha.alpha_short = (ILushort)(AlphaValue * 0x0000FFFF + .5); - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - ((ILushort*)iCurImage->Data)[i] = Alpha.alpha_short; - break; - case IL_INT: - case IL_UNSIGNED_INT: - Alpha.alpha_int = (ILuint)(AlphaValue * 0xFFFFFFFF + .5); - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - ((ILuint*)iCurImage->Data)[i] = Alpha.alpha_int; - break; - case IL_FLOAT: - Alpha.alpha_float = (ILfloat)AlphaValue; - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - ((ILfloat*)iCurImage->Data)[i] = Alpha.alpha_float; - break; - case IL_DOUBLE: - Alpha.alpha_double = AlphaValue; - for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++) - ((ILdouble*)iCurImage->Data)[i] = Alpha.alpha_double; - break; - } -} diff --git a/win32/devil/src/il_mdl.c b/win32/devil/src/il_mdl.c deleted file mode 100644 index 2ef7c2522..000000000 --- a/win32/devil/src/il_mdl.c +++ /dev/null @@ -1,157 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_mdl.c -// -// Description: Reads a Half-Life model file (.mdl). -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_MDL -#include "il_mdl.h" - - -ILboolean iLoadMdlInternal(void); - - -//! Reads a .Mdl file -ILboolean ilLoadMdl(ILconst_string FileName) -{ - ILHANDLE MdlFile; - ILboolean bMdl = IL_FALSE; - - MdlFile = iopenr(FileName); - if (MdlFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bMdl; - } - - bMdl = ilLoadMdlF(MdlFile); - icloser(MdlFile); - - return bMdl; -} - - -//! Reads an already-opened .Mdl file -ILboolean ilLoadMdlF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadMdlInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .Mdl -ILboolean ilLoadMdlL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadMdlInternal(); -} - - -ILboolean iLoadMdlInternal() -{ - ILuint Id, Version, NumTex, TexOff, TexDataOff, Position, ImageNum; - ILubyte *TempPal; - TEX_HEAD TexHead; - ILimage *BaseImage=NULL; - ILboolean BaseCreated = IL_FALSE; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Id = GetLittleUInt(); - Version = GetLittleUInt(); - - // 0x54534449 == "IDST" - if (Id != 0x54534449 || Version != 10) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // Skips the actual model header. - iseek(172, IL_SEEK_CUR); - - NumTex = GetLittleUInt(); - TexOff = GetLittleUInt(); - TexDataOff = GetLittleUInt(); - - if (NumTex == 0 || TexOff == 0 || TexDataOff == 0) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - iseek(TexOff, IL_SEEK_SET); - - for (ImageNum = 0; ImageNum < NumTex; ImageNum++) { - if (iread(TexHead.Name, 1, 64) != 64) - return IL_FALSE; - TexHead.Flags = GetLittleUInt(); - TexHead.Width = GetLittleUInt(); - TexHead.Height = GetLittleUInt(); - TexHead.Offset = GetLittleUInt(); - Position = itell(); - - if (TexHead.Offset == 0) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - if (!BaseCreated) { - ilTexImage(TexHead.Width, TexHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL); - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - BaseCreated = IL_TRUE; - BaseImage = iCurImage; - //iCurImage->NumNext = NumTex - 1; // Don't count the first image. - } - else { - //iCurImage->Next = ilNewImage(TexHead.Width, TexHead.Height, 1, 1, 1); - iCurImage = iCurImage->Next; - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Type = IL_UNSIGNED_BYTE; - } - - TempPal = (ILubyte*)ialloc(768); - if (TempPal == NULL) { - iCurImage = BaseImage; - return IL_FALSE; - } - iCurImage->Pal.Palette = TempPal; - iCurImage->Pal.PalSize = 768; - iCurImage->Pal.PalType = IL_PAL_RGB24; - - iseek(TexHead.Offset, IL_SEEK_SET); - if (iread(iCurImage->Data, TexHead.Width * TexHead.Height, 1) != 1) - return IL_FALSE; - if (iread(iCurImage->Pal.Palette, 1, 768) != 768) - return IL_FALSE; - - if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { - ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); - } - - iseek(Position, IL_SEEK_SET); - } - - iCurImage = BaseImage; - - ilFixImage(); - - return IL_TRUE; -} - -#endif//IL_NO_MDL diff --git a/win32/devil/src/il_mng.c b/win32/devil/src/il_mng.c deleted file mode 100644 index a57352aeb..000000000 --- a/win32/devil/src/il_mng.c +++ /dev/null @@ -1,349 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_mng.c -// -// Description: Multiple Network Graphics (.mng) functions -// -//----------------------------------------------------------------------------- - -#include "il_internal.h" -#ifndef IL_NO_MNG -#define MNG_SUPPORT_READ -#define MNG_SUPPORT_WRITE -#define MNG_SUPPORT_DISPLAY - -#ifdef _WIN32 -//#define MNG_USE_SO -#endif - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "libmng.lib") - #pragma comment(lib, "lcms.lib") - #pragma comment(lib, "libjpeg.lib") - #pragma comment(lib, "zlib.lib") - #endif - #endif -#endif - -#include - -//--------------------------------------------------------------------------------------------- -// memory allocation; data must be zeroed -//--------------------------------------------------------------------------------------------- -mng_ptr MNG_DECL mymngalloc(mng_size_t size) -{ - return (mng_ptr)icalloc(1, size); -} - - -//--------------------------------------------------------------------------------------------- -// memory deallocation -//--------------------------------------------------------------------------------------------- -void MNG_DECL mymngfree(mng_ptr p, mng_size_t size) -{ - ifree(p); -} - - -//--------------------------------------------------------------------------------------------- -// Stream open: -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngopenstream(mng_handle mng) -{ - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// Stream open for Writing: -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngopenstreamwrite(mng_handle mng) -{ - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// Stream close: -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngclosestream(mng_handle mng) -{ - return MNG_TRUE; // We close the file ourself, mng_cleanup doesnt seem to do it... -} - - -//--------------------------------------------------------------------------------------------- -// feed data to the decoder -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngreadstream(mng_handle mng, mng_ptr buffer, mng_size_t size, mng_uint32 *bytesread) -{ - // read the requested amount of data from the file - *bytesread = iread(buffer, 1, size); - - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// callback for writing data -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngwritedata(mng_handle mng, mng_ptr buffer, mng_size_t size, mng_uint32 *byteswritten) -{ - *byteswritten = iwrite(buffer, 1, size); - - if (*byteswritten < size) { - ilSetError(IL_FILE_WRITE_ERROR); - return MNG_FALSE; - } - - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// the header's been read. set up the display stuff -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngprocessheader(mng_handle mng, mng_uint32 width, mng_uint32 height) -{ - ILuint AlphaDepth; - - AlphaDepth = mng_get_alphadepth(mng); - - if (AlphaDepth == 0) { - ilTexImage(width, height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL); - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - mng_set_canvasstyle(mng, MNG_CANVAS_BGR8); - } - else { // Use alpha channel - ilTexImage(width, height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL); - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8); - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// return a row pointer for the decoder to fill -//--------------------------------------------------------------------------------------------- -mng_ptr MNG_DECL mymnggetcanvasline(mng_handle mng, mng_uint32 line) -{ - return (mng_ptr)(iCurImage->Data + iCurImage->Bps * line); -} - - -//--------------------------------------------------------------------------------------------- -// timer -//--------------------------------------------------------------------------------------------- -mng_uint32 MNG_DECL mymnggetticks(mng_handle mng) -{ - return 0; -} - - -//--------------------------------------------------------------------------------------------- -// Refresh: -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h) -{ - return MNG_TRUE; -} - - -//--------------------------------------------------------------------------------------------- -// interframe delay callback -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngsettimer(mng_handle mng, mng_uint32 msecs) -{ - return MNG_TRUE; -} - - - -// Make this do something different soon! - -//--------------------------------------------------------------------------------------------- -// Error Callback; -//--------------------------------------------------------------------------------------------- -mng_bool MNG_DECL mymngerror( - mng_handle mng, mng_int32 code, mng_int8 severity, - mng_chunkid chunktype, mng_uint32 chunkseq, - mng_int32 extra1, mng_int32 extra2, mng_pchar text - ) -{ - // error occured; - return MNG_FALSE; -} - - -ILboolean iLoadMngInternal(void); - -// Reads a file -ILboolean ilLoadMng(ILconst_string FileName) -{ - ILHANDLE MngFile; - ILboolean bMng = IL_FALSE; - - MngFile = iopenr(FileName); - if (MngFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bMng; - } - - bMng = ilLoadMngF(MngFile); - icloser(MngFile); - - return bMng; -} - - -// Reads an already-opened file -ILboolean ilLoadMngF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadMngInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -// Reads from a memory "lump" -ILboolean ilLoadMngL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadMngInternal(); -} - - -ILboolean iLoadMngInternal() -{ - mng_handle mng; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL); - if (mng == MNG_NULL) { - ilSetError(IL_LIB_MNG_ERROR); - return IL_FALSE; - } - - // If .mng background is available, use it. - mng_set_usebkgd(mng, MNG_TRUE); - - // Set the callbacks. - mng_setcb_errorproc(mng, mymngerror); - mng_setcb_openstream(mng, mymngopenstream); - mng_setcb_closestream(mng, mymngclosestream); - mng_setcb_readdata(mng, (mng_readdata)mymngreadstream); - mng_setcb_gettickcount(mng, mymnggetticks); - mng_setcb_settimer(mng, mymngsettimer); - mng_setcb_processheader(mng, mymngprocessheader); - mng_setcb_getcanvasline(mng, mymnggetcanvasline); - mng_setcb_refresh(mng, mymngrefresh); - - mng_read(mng); - mng_display(mng); - - ilFixImage(); - - return IL_TRUE; -} - - -ILboolean iSaveMngInternal(void); - -//! Writes a Mng file -ILboolean ilSaveMng(ILconst_string FileName) -{ - ILHANDLE MngFile; - ILboolean bMng = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - MngFile = iopenw(FileName); - if (MngFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bMng; - } - - bMng = ilSaveMngF(MngFile); - iclosew(MngFile); - - return bMng; -} - - -//! Writes a Mng to an already-opened file -ILboolean ilSaveMngF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSaveMngInternal(); -} - - -//! Writes a Mng to a memory "lump" -ILboolean ilSaveMngL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveMngInternal(); -} - - -// Internal function used to save the Mng. -ILboolean iSaveMngInternal() -{ - /*mng_handle mng; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL); - if (mng == MNG_NULL) { - ilSetError(IL_LIB_MNG_ERROR); - return IL_FALSE; - } - - - mng_setcb_openstream(mng, mymngopenstreamwrite); - mng_setcb_closestream(mng, mymngclosestream); - mng_setcb_writedata(mng, mymngwritedata); - - // Write File: - mng_create(mng); - - // Just a single Frame (save a normal PNG): - //WritePNG( mng, 0, 1 ); - - // Now write file: - mng_write(mng); - - mng_cleanup(&mng);*/ - - return IL_TRUE; -} - -#endif//IL_NO_MNG diff --git a/win32/devil/src/il_neuquant.c b/win32/devil/src/il_neuquant.c deleted file mode 100644 index db28fc7c0..000000000 --- a/win32/devil/src/il_neuquant.c +++ /dev/null @@ -1,462 +0,0 @@ -/* NeuQuant Neural-Net Quantization Algorithm - * ------------------------------------------ - * - * Copyright (c) 1994 Anthony Dekker - * - * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. - * See "Kohonen neural networks for optimal colour quantization" - * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. - * for a discussion of the algorithm. - * See also http://www.acm.org/~dekker/NEUQUANT.HTML - * - * Any party obtaining a copy of these files from the author, directly or - * indirectly, is granted, free of charge, a full and unrestricted irrevocable, - * world-wide, paid up, royalty-free, nonexclusive right and license to deal - * in this software and documentation files (the "Software"), including without - * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons who receive - * copies from any such party to do so, with the only requirement being - * that this copyright notice remain intact. - */ - -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// by Denton Woods -// Last modified: 02/02/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_neuquant.c -// -// Description: Heavily modified by Denton Woods. -// -//----------------------------------------------------------------------------- - -#include "il_internal.h" - - -// Function definitions -ILvoid initnet(ILubyte *thepic, ILint len, ILint sample); -ILvoid unbiasnet(); -ILvoid inxbuild(); -ILubyte inxsearch(ILint b, ILint g, ILint r); -ILvoid learn(); - -// four primes near 500 - assume no image has a length so large -// that it is divisible by all four primes -#define prime1 499 -#define prime2 491 -#define prime3 487 -#define prime4 503 - -#define minpicturebytes (3*prime4) // minimum size for input image - - -// Network Definitions -// ------------------- - -#define netsize 256 // number of colours used -#define maxnetpos (netsizethink-1) -#define netbiasshift 4 // bias for colour values -#define ncycles 100 // no. of learning cycles - -// defs for freq and bias -#define intbiasshift 16 // bias for fractions -#define intbias (((ILint) 1)<>betashift)// beta = 1/1024 -#define betagamma (intbias<<(gammashift-betashift)) - -// defs for decreasing radius factor -#define initrad (netsize>>3) // for 256 cols, radius starts -#define radiusbiasshift 6 // at 32.0 biased by 6 bits -#define radiusbias (((ILint) 1)<>= netbiasshift; - network[i][3] = i; // record colour no - } - return; -} - - -// Insertion sort of network and building of netindex[0..255] (to do after unbias) -// ------------------------------------------------------------------------------- - -ILvoid inxbuild() -{ - ILint i,j,smallpos,smallval; - ILint *p,*q; - ILint previouscol,startpos; - - previouscol = 0; - startpos = 0; - for (i=0; i>1; - for (j=previouscol+1; j>1; - for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; // really 256 - return; -} - - -// Search for BGR values 0..255 (after net is unbiased) and return colour index -// ---------------------------------------------------------------------------- - -ILubyte inxsearch(ILint b, ILint g, ILint r) -{ - ILint i,j,dist,a,bestd; - ILint *p; - ILint best; - - bestd = 1000; // biggest possible dist is 256*3 - best = -1; - i = netindex[g]; // index on g - j = i-1; // start at netindex[g] and work outwards - - while ((i=0)) { - if (i= bestd) i = netsizethink; // stop iter - else { - i++; - if (dist<0) dist = -dist; - a = p[0] - b; if (a<0) a = -a; - dist += a; - if (dist=0) { - p = network[j]; - dist = g - p[1]; // inx key - reverse dif - if (dist >= bestd) j = -1; // stop iter - else { - j--; - if (dist<0) dist = -dist; - a = p[0] - b; if (a<0) a = -a; - dist += a; - if (dist>(intbiasshift-netbiasshift)); - if (biasdist> betashift); - *f++ -= betafreq; - *p++ += (betafreq<netsizethink) hi=netsizethink; - - j = i+1; - k = i-1; - q = radpower; - while ((jlo)) { - a = (*(++q)); - if (jlo) { - p = network[k]; - *p -= (a*(*p - b)) / alpharadbias; - p++; - *p -= (a*(*p - g)) / alpharadbias; - p++; - *p -= (a*(*p - r)) / alpharadbias; - k--; - } - } - return; -} - - -// Main Learning Loop -// ------------------ - -ILvoid learn() -{ - ILint i,j,b,g,r; - ILint radius,rad,alpha,step,delta,samplepixels; - ILubyte *p; - ILubyte *lim; - - alphadec = 30 + ((samplefac-1)/3); - p = thepicture; - lim = thepicture + lengthcount; - samplepixels = lengthcount/(3*samplefac); - delta = samplepixels/ncycles; - alpha = initalpha; - radius = initradius; - - rad = radius >> radiusbiasshift; - if (rad <= 1) rad = 0; - for (i=0; i= lim) p -= lengthcount; - - i++; - if (i%delta == 0) { - alpha -= alpha / alphadec; - radius -= radius / radiusdec; - rad = radius >> radiusbiasshift; - if (rad <= 1) rad = 0; - for (j=0; jData, TempImage->SizeOfData, sample); - learn(); - unbiasnet(); - - NewImage = (ILimage*)icalloc(sizeof(ILimage), 1); - if (NewImage == NULL) { - ilCloseImage(TempImage); - return NULL; - } - NewImage->Data = (ILubyte*)ialloc(TempImage->SizeOfData / 3); - if (NewImage->Data == NULL) { - ilCloseImage(TempImage); - ifree(NewImage); - return NULL; - } - ilCopyImageAttr(NewImage, Image); - NewImage->Bpp = 1; - NewImage->Bps = Image->Width; - NewImage->SizeOfPlane = NewImage->Bps * Image->Height; - NewImage->SizeOfData = NewImage->SizeOfPlane; - NewImage->Format = IL_COLOUR_INDEX; - NewImage->Type = IL_UNSIGNED_BYTE; - - NewImage->Pal.PalSize = netsizethink * 3; - NewImage->Pal.PalType = IL_PAL_BGR24; - NewImage->Pal.Palette = (ILubyte*)ialloc(256*3); - if (NewImage->Pal.Palette == NULL) { - ilCloseImage(TempImage); - ilCloseImage(NewImage); - return NULL; - } - - for (i = 0, j = 0; i < (unsigned)netsizethink; i++, j += 3) { - NewImage->Pal.Palette[j ] = network[i][0]; - NewImage->Pal.Palette[j+1] = network[i][1]; - NewImage->Pal.Palette[j+2] = network[i][2]; - } - - inxbuild(); - for (i = 0, j = 0; j < TempImage->SizeOfData; i++, j += 3) { - NewImage->Data[i] = inxsearch( - TempImage->Data[j], TempImage->Data[j+1], TempImage->Data[j+2]); - } - - ilCloseImage(TempImage); - - return NewImage; -} diff --git a/win32/devil/src/il_pal.c b/win32/devil/src/il_pal.c deleted file mode 100644 index d8f7db516..000000000 --- a/win32/devil/src/il_pal.c +++ /dev/null @@ -1,1096 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 03/15/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pal.c -// -// Description: Loads palettes from different file formats -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_pal.h" -#include -#include -#include - - -//! Loads a palette from FileName into the current image's palette. -ILboolean ILAPIENTRY ilLoadPal(ILconst_string FileName) -{ - FILE *f; - ILboolean IsPsp; - char Head[8]; - - if (FileName == NULL) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (iCheckExtension(FileName, IL_TEXT("col"))) { - return ilLoadColPal(FileName); - } - if (iCheckExtension(FileName, IL_TEXT("act"))) { - return ilLoadActPal(FileName); - } - if (iCheckExtension(FileName, IL_TEXT("plt"))) { - return ilLoadPltPal(FileName); - } - -#ifndef _UNICODE - f = fopen(FileName, "rt"); -#else - f = _wfopen(FileName, L"rt"); -#endif//_UNICODE - if (f == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - fread(Head, 1, 8, f); - if (!strncmp(Head, "JASC-PAL", 8)) - IsPsp = IL_TRUE; - else - IsPsp = IL_FALSE; - - fclose(f); - - if (IsPsp) - return ilLoadJascPal(FileName); - return ilLoadHaloPal(FileName); -} - - -//! Loads a Paint Shop Pro formatted palette (.pal) file. -ILboolean ilLoadJascPal(ILconst_string FileName) -{ - FILE *PalFile; - ILuint NumColours, i, c; - ILubyte Buff[BUFFLEN]; - ILboolean Error = IL_FALSE; - ILpal *Pal = &iCurImage->Pal; - - if (!iCheckExtension(FileName, IL_TEXT("pal"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#ifndef _UNICODE - PalFile = fopen(FileName, "rt"); -#else - PalFile = _wfopen(FileName, L"rt"); -#endif//_UNICODE - if (PalFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - } - - iFgetw(Buff, BUFFLEN, PalFile); - if (stricmp((const char*)Buff, "JASC-PAL")) { - Error = IL_TRUE; - } - iFgetw(Buff, BUFFLEN, PalFile); - if (stricmp((const char*)Buff, "0100")) { - Error = IL_TRUE; - } - - iFgetw(Buff, BUFFLEN, PalFile); - NumColours = atoi((const char*)Buff); - if (NumColours == 0 || Error) { - ilSetError(IL_INVALID_FILE_HEADER); - fclose(PalFile); - return IL_FALSE; - } - - Pal->PalSize = NumColours * PALBPP; - Pal->PalType = IL_PAL_RGB24; - Pal->Palette = (ILubyte*)ialloc(NumColours * PALBPP); - if (Pal->Palette == NULL) { - fclose(PalFile); - return IL_FALSE; - } - - for (i = 0; i < NumColours; i++) { - for (c = 0; c < PALBPP; c++) { - iFgetw(Buff, BUFFLEN, PalFile); - Pal->Palette[i * PALBPP + c] = atoi((const char*)Buff); - } - } - - fclose(PalFile); - - return IL_TRUE; -} - - -// File Get Word -// MaxLen must be greater than 1, because the trailing NULL is always stored. -char *iFgetw(ILubyte *Buff, ILint MaxLen, FILE *File) -{ - ILint Temp; - ILint i; - - if (Buff == NULL || File == NULL || MaxLen < 2) { - ilSetError(IL_INVALID_PARAM); - return NULL; - } - - for (i = 0; i < MaxLen - 1; i++) { - Temp = fgetc(File); - if (Temp == '\n' || Temp == '\0' || Temp == IL_EOF || feof(File)) { - break; - } - - if (Temp == ' ') { - while (Temp == ' ') { // Just to get rid of any extra spaces - Temp = fgetc(File); - } - fseek(File, -1, IL_SEEK_CUR); // Go back one - break; - } - - if (!isprint(Temp)) { // Skips any non-printing characters - while (!isprint(Temp)) { - Temp = fgetc(File); - } - fseek(File, -1, IL_SEEK_CUR); - break; - } - - Buff[i] = Temp; - } - - Buff[i] = '\0'; - return (char *)Buff; -} - - -ILboolean ILAPIENTRY ilSavePal(ILconst_string FileName) -{ - ILstring Ext = iGetExtension(FileName); - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 1 || Ext == NULL) { -#else - if (FileName == NULL || wcslen(FileName) < 1 || Ext == NULL) { -#endif//_UNICODE - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - if (!iCurImage->Pal.Palette || !iCurImage->Pal.PalSize || iCurImage->Pal.PalType == IL_PAL_NONE) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iStrCmp(Ext, IL_TEXT("pal"))) { - return ilSaveJascPal(FileName); - } - - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; -} - - -//! Saves a Paint Shop Pro formatted palette (.pal) file. -ILboolean ilSaveJascPal(ILconst_string FileName) -{ - FILE *PalFile; - ILuint i, PalBpp, NumCols = ilGetInteger(IL_PALETTE_NUM_COLS); - ILubyte *CurPal; - - if (iCurImage == NULL || NumCols == 0 || NumCols > 256) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#ifndef _UNICODE - if (FileName == NULL || strlen(FileName) < 5) { -#else - if (FileName == NULL || wcslen(FileName) < 5) { -#endif//_UNICODE - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - if (!iCheckExtension(FileName, IL_TEXT("pal"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - // Create a copy of the current palette and convert it to RGB24 format. - CurPal = iCurImage->Pal.Palette; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (!iCurImage->Pal.Palette) { - iCurImage->Pal.Palette = CurPal; - return IL_FALSE; - } - - memcpy(iCurImage->Pal.Palette, CurPal, iCurImage->Pal.PalSize); - if (!ilConvertPal(IL_PAL_RGB24)) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = CurPal; - return IL_FALSE; - } - -#ifndef _UNICODE - PalFile = fopen(FileName, "wt"); -#else - PalFile = _wfopen(FileName, L"wt"); -#endif//_UNICODE - if (!PalFile) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - // Header needed on all .pal files - fputs("JASC-PAL\n0100\n256\n", PalFile); - - PalBpp = ilGetBppPal(iCurImage->Pal.PalType); - for (i = 0; i < iCurImage->Pal.PalSize; i += PalBpp) { - fprintf(PalFile, "%d %d %d\n", - iCurImage->Pal.Palette[i], iCurImage->Pal.Palette[i+1], iCurImage->Pal.Palette[i+2]); - } - - NumCols = 256 - NumCols; - for (i = 0; i < NumCols; i++) { - fprintf(PalFile, "0 0 0\n"); - } - - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = CurPal; - - fclose(PalFile); - - return IL_TRUE; -} - - -//! Loads a Halo formatted palette (.pal) file. -ILboolean ilLoadHaloPal(ILconst_string FileName) -{ - ILHANDLE HaloFile; - HALOHEAD HaloHead; - ILushort *TempPal; - ILuint i, Size; - - if (!iCheckExtension(FileName, IL_TEXT("pal"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - HaloFile = iopenr(FileName); - if (HaloFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - if (iread(&HaloHead, sizeof(HALOHEAD), 1) != 1) - return IL_FALSE; - - if (HaloHead.Id != 'A' + ('H' << 8) || HaloHead.Version != 0xe3) { - icloser(HaloFile); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - Size = (HaloHead.MaxIndex + 1) * 3; - TempPal = (ILushort*)ialloc(Size * sizeof(ILushort)); - if (TempPal == NULL) { - icloser(HaloFile); - return IL_FALSE; - } - - if (iread(TempPal, sizeof(ILushort), Size) != Size) { - icloser(HaloFile); - ifree(TempPal); - return IL_FALSE; - } - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - } - iCurImage->Pal.PalType = IL_PAL_RGB24; - iCurImage->Pal.PalSize = Size; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) { - icloser(HaloFile); - return IL_FALSE; - } - - for (i = 0; i < iCurImage->Pal.PalSize; i++, TempPal++) { - iCurImage->Pal.Palette[i] = (ILubyte)*TempPal; - } - TempPal -= iCurImage->Pal.PalSize; - ifree(TempPal); - - icloser(HaloFile); - - return IL_TRUE; -} - - -// Hasn't been tested -// @TODO: Test the thing! - -//! Loads a .col palette file -ILboolean ilLoadColPal(ILconst_string FileName) -{ - ILuint RealFileSize, FileSize; - ILushort Version; - ILHANDLE ColFile; - - if (!iCheckExtension(FileName, IL_TEXT("col"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - ColFile = iopenr(FileName); - if (ColFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - } - - iseek(0, IL_SEEK_END); - RealFileSize = ftell((FILE*)ColFile); - iseek(0, IL_SEEK_SET); - - if (RealFileSize > 768) { // has a header - fread(&FileSize, 4, 1, (FILE*)ColFile); - if ((FileSize - 8) % 3 != 0) { // check to make sure an even multiple of 3! - icloser(ColFile); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - if (iread(&Version, 2, 1) != 1) { - icloser(ColFile); - return IL_FALSE; - } - if (Version != 0xB123) { - icloser(ColFile); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - if (iread(&Version, 2, 1) != 1) { - icloser(ColFile); - return IL_FALSE; - } - if (Version != 0) { - icloser(ColFile); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - } - - iCurImage->Pal.Palette = (ILubyte*)ialloc(768); - if (iCurImage->Pal.Palette == NULL) { - icloser(ColFile); - return IL_FALSE; - } - - if (iread(iCurImage->Pal.Palette, 1, 768) != 768) { - icloser(ColFile); - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - return IL_FALSE; - } - - iCurImage->Pal.PalSize = 768; - iCurImage->Pal.PalType = IL_PAL_RGB24; - - icloser(ColFile); - - return IL_TRUE; -} - - -//! Loads an .act palette file. -ILboolean ilLoadActPal(ILconst_string FileName) -{ - ILHANDLE ActFile; - - if (!iCheckExtension(FileName, IL_TEXT("act"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - ActFile = iopenr(FileName); - if (ActFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - } - - iCurImage->Pal.PalType = IL_PAL_RGB24; - iCurImage->Pal.PalSize = 768; - iCurImage->Pal.Palette = (ILubyte*)ialloc(768); - if (!iCurImage->Pal.Palette) { - icloser(ActFile); - return IL_FALSE; - } - - if (iread(iCurImage->Pal.Palette, 1, 768) != 768) { - icloser(ActFile); - return IL_FALSE; - } - - icloser(ActFile); - - return IL_TRUE; -} - - -//! Loads an .plt palette file. -ILboolean ilLoadPltPal(ILconst_string FileName) -{ - ILHANDLE PltFile; - - if (!iCheckExtension(FileName, IL_TEXT("plt"))) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - } - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - PltFile = iopenr(FileName); - if (PltFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - } - - iCurImage->Pal.PalSize = GetLittleUInt(); - if (iCurImage->Pal.PalSize == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - iCurImage->Pal.PalType = IL_PAL_RGB24; - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (!iCurImage->Pal.Palette) { - icloser(PltFile); - return IL_FALSE; - } - - if (iread(iCurImage->Pal.Palette, iCurImage->Pal.PalSize, 1) != 1) { - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = NULL; - icloser(PltFile); - return IL_FALSE; - } - - icloser(PltFile); - - return IL_TRUE; -} - - -ILAPI ILpal* ILAPIENTRY iCopyPal() -{ - ILpal *Pal; - - if (iCurImage == NULL || iCurImage->Pal.Palette == NULL || - iCurImage->Pal.PalSize == 0 || iCurImage->Pal.PalType == IL_PAL_NONE) { - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - Pal = (ILpal*)ialloc(sizeof(ILpal)); - if (Pal == NULL) { - return NULL; - } - Pal->Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (Pal->Palette == NULL) { - ifree(Pal); - return NULL; - } - - memcpy(Pal->Palette, iCurImage->Pal.Palette, iCurImage->Pal.PalSize); - Pal->PalSize = iCurImage->Pal.PalSize; - Pal->PalType = iCurImage->Pal.PalType; - - return Pal; -} - - -// Converts the palette to the DestFormat format. -ILAPI ILpal* ILAPIENTRY iConvertPal(ILpal *Pal, ILenum DestFormat) -{ - ILpal *NewPal = NULL; - ILuint i, j, NewPalSize; - - // Checks to see if the current image is valid and has a palette - if (Pal == NULL || Pal->PalSize == 0 || Pal->Palette == NULL || Pal->PalType == IL_PAL_NONE) { - ilSetError(IL_ILLEGAL_OPERATION); - return NULL; - } - - /*if (Pal->PalType == DestFormat) { - return NULL; - }*/ - - NewPal = (ILpal*)ialloc(sizeof(ILpal)); - if (NewPal == NULL) { - return NULL; - } - NewPal->PalSize = Pal->PalSize; - NewPal->PalType = Pal->PalType; - - switch (DestFormat) - { - case IL_PAL_RGB24: - case IL_PAL_BGR24: - switch (Pal->PalType) - { - case IL_PAL_RGB24: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_BGR24) { - j = ilGetBppPal(Pal->PalType); - for (i = 0; i < Pal->PalSize; i += j) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - } - } - else { - memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); - } - NewPal->PalType = DestFormat; - break; - - case IL_PAL_BGR24: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_RGB24) { - j = ilGetBppPal(Pal->PalType); - for (i = 0; i < Pal->PalSize; i += j) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - } - } - else { - memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); - } - NewPal->PalType = DestFormat; - break; - - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - NewPalSize = (ILuint)((ILfloat)Pal->PalSize * 3.0f / 4.0f); - NewPal->Palette = (ILubyte*)ialloc(NewPalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_RGB24) { - for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { - NewPal->Palette[j] = Pal->Palette[i+2]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i]; - } - } - else { - for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { - NewPal->Palette[j] = Pal->Palette[i]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i+2]; - } - } - NewPal->PalSize = NewPalSize; - NewPal->PalType = DestFormat; - break; - - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - NewPalSize = (ILuint)((ILfloat)Pal->PalSize * 3.0f / 4.0f); - NewPal->Palette = (ILubyte*)ialloc(NewPalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_RGB24) { - for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { - NewPal->Palette[j] = Pal->Palette[i]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i+2]; - } - } - else { - for (i = 0, j = 0; i < Pal->PalSize; i += 4, j += 3) { - NewPal->Palette[j] = Pal->Palette[i+2]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i]; - } - } - NewPal->PalSize = NewPalSize; - NewPal->PalType = DestFormat; - break; - - default: - ilSetError(IL_INVALID_PARAM); - return NULL; - } - break; - - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - switch (Pal->PalType) - { - case IL_PAL_RGB24: - case IL_PAL_BGR24: - NewPalSize = Pal->PalSize * 4 / 3; - NewPal->Palette = (ILubyte*)ialloc(NewPalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if ((Pal->PalType == IL_PAL_BGR24 && (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32)) || - (Pal->PalType == IL_PAL_RGB24 && (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32))) { - for (i = 0, j = 0; i < Pal->PalSize; i += 3, j += 4) { - NewPal->Palette[j] = Pal->Palette[i+2]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i]; - NewPal->Palette[j+3] = 255; - } - } - else { - for (i = 0, j = 0; i < Pal->PalSize; i += 3, j += 4) { - NewPal->Palette[j] = Pal->Palette[i]; - NewPal->Palette[j+1] = Pal->Palette[i+1]; - NewPal->Palette[j+2] = Pal->Palette[i+2]; - NewPal->Palette[j+3] = 255; - } - } - NewPal->PalSize = NewPalSize; - NewPal->PalType = DestFormat; - break; - - case IL_PAL_RGB32: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - - if (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32) { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - NewPal->Palette[i+3] = 255; - } - } - else { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i+2]; - NewPal->Palette[i+3] = 255; - } - } - NewPal->PalType = DestFormat; - break; - - case IL_PAL_RGBA32: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_BGR32 || DestFormat == IL_PAL_BGRA32) { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - NewPal->Palette[i+3] = Pal->Palette[i+3]; - } - } - else { - memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); - } - NewPal->PalType = DestFormat; - break; - - case IL_PAL_BGR32: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32) { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - NewPal->Palette[i+3] = 255; - } - } - else { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i+2]; - NewPal->Palette[i+3] = 255; - } - } - NewPal->PalType = DestFormat; - break; - - case IL_PAL_BGRA32: - NewPal->Palette = (ILubyte*)ialloc(Pal->PalSize); - if (NewPal->Palette == NULL) - goto alloc_error; - if (DestFormat == IL_PAL_RGB32 || DestFormat == IL_PAL_RGBA32) { - for (i = 0; i < Pal->PalSize; i += 4) { - NewPal->Palette[i] = Pal->Palette[i+2]; - NewPal->Palette[i+1] = Pal->Palette[i+1]; - NewPal->Palette[i+2] = Pal->Palette[i]; - NewPal->Palette[i+3] = Pal->Palette[i+3]; - } - } - else { - memcpy(NewPal->Palette, Pal->Palette, Pal->PalSize); - } - NewPal->PalType = DestFormat; - break; - - default: - ilSetError(IL_INVALID_PARAM); - return NULL; - } - break; - - - default: - ilSetError(IL_INVALID_PARAM); - return NULL; - } - - NewPal->PalType = DestFormat; - - return NewPal; - -alloc_error: - ifree(NewPal); - return NULL; -} - - -//! Converts the current image to the DestFormat format. -ILboolean ILAPIENTRY ilConvertPal(ILenum DestFormat) -{ - ILpal *Pal; - - if (iCurImage == NULL || iCurImage->Pal.Palette == NULL || - iCurImage->Pal.PalSize == 0 || iCurImage->Pal.PalType == IL_PAL_NONE) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Pal = iConvertPal(&iCurImage->Pal, DestFormat); - if (Pal == NULL) - return IL_FALSE; - - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.PalSize = Pal->PalSize; - iCurImage->Pal.PalType = Pal->PalType; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(Pal->PalSize); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - memcpy(iCurImage->Pal.Palette, Pal->Palette, Pal->PalSize); - - ifree(Pal->Palette); - ifree(Pal); - - return IL_TRUE; -} - - -// Sets the current palette. -ILAPI ILvoid ILAPIENTRY ilSetPal(ILpal *Pal) -{ - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - } - - if (Pal->Palette && Pal->PalSize && Pal->PalType != IL_PAL_NONE) { - iCurImage->Pal.Palette = (ILubyte*)ialloc(Pal->PalSize); - if (iCurImage->Pal.Palette == NULL) - return; - memcpy(iCurImage->Pal.Palette, Pal->Palette, Pal->PalSize); - iCurImage->Pal.PalSize = Pal->PalSize; - iCurImage->Pal.PalType = Pal->PalType; - } - else { - iCurImage->Pal.Palette = NULL; - iCurImage->Pal.PalSize = 0; - iCurImage->Pal.PalType = IL_PAL_NONE; - } - - return; -} - - -ILuint CurSort = 0; -typedef struct COL_CUBE -{ - ILubyte Min[3]; - ILubyte Val[3]; - ILubyte Max[3]; -} COL_CUBE; - -int sort_func(void *e1, void *e2) -{ - return ((COL_CUBE*)e1)->Val[CurSort] - ((COL_CUBE*)e2)->Val[CurSort]; -} - - -ILboolean ILAPIENTRY ilApplyPal(ILconst_string FileName) -{ - ILimage Image, *CurImage = iCurImage; - ILubyte *NewData; - ILuint *PalInfo, NumColours, NumPix, MaxDist, DistEntry=0, i, j; - ILint Dist1, Dist2, Dist3; - ILboolean Same; - ILenum Origin; -// COL_CUBE *Cubes; - - if( iCurImage == NULL || (iCurImage->Format != IL_BYTE || iCurImage->Format != IL_UNSIGNED_BYTE) ) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - NewData = (ILubyte*)ialloc(iCurImage->Width * iCurImage->Height * iCurImage->Depth); - if (NewData == NULL) { - return IL_FALSE; - } - - iCurImage = &Image; - imemclear(&Image, sizeof(ILimage)); - // IL_PAL_RGB24, because we don't want to make parts transparent that shouldn't be. - if (!ilLoadPal(FileName) || !ilConvertPal(IL_PAL_RGB24)) { - ifree(NewData); - iCurImage = CurImage; - return IL_FALSE; - } - - NumColours = Image.Pal.PalSize / 3; // RGB24 is 3 bytes per entry. - PalInfo = (ILuint*)ialloc(NumColours * sizeof(ILuint)); - if (PalInfo == NULL) { - ifree(NewData); - iCurImage = CurImage; - return IL_FALSE; - } - - NumPix = CurImage->SizeOfData / ilGetBppFormat(CurImage->Format); - switch (CurImage->Format) - { - case IL_COLOUR_INDEX: - iCurImage = CurImage; - if (!ilConvertPal(IL_PAL_RGB24)) { - ifree(NewData); - ifree(PalInfo); - return IL_FALSE; - } - - NumPix = iCurImage->Pal.PalSize / ilGetBppPal(iCurImage->Pal.PalType); - for (i = 0; i < NumPix; i++) { - for (j = 0; j < Image.Pal.PalSize; j += 3) { - // No need to perform a sqrt. - Dist1 = (ILint)iCurImage->Pal.Palette[i] - (ILint)Image.Pal.Palette[j]; - Dist2 = (ILint)iCurImage->Pal.Palette[i+1] - (ILint)Image.Pal.Palette[j+1]; - Dist3 = (ILint)iCurImage->Pal.Palette[i+2] - (ILint)Image.Pal.Palette[j+2]; - PalInfo[j / 3] = Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3; - } - MaxDist = UINT_MAX; - DistEntry = 0; - for (j = 0; j < NumColours; j++) { - if (PalInfo[j] < MaxDist) { - DistEntry = j; - MaxDist = PalInfo[j]; - } - } - iCurImage->Pal.Palette[i] = DistEntry; - } - - for (i = 0; i < iCurImage->SizeOfData; i++) { - NewData[i] = iCurImage->Pal.Palette[iCurImage->Data[i]]; - } - break; - case IL_RGB: - case IL_RGBA: - /*Cube = (COL_CUBE*)ialloc(NumColours * sizeof(COL_CUBE)); - // @TODO: Check if ialloc failed here! - for (i = 0; i < NumColours; i++) - memcpy(&Cubes[i].Val, Image.Pal.Palette[i * 3], 3); - for (j = 0; j < 3; j++) { - qsort(Cubes, NumColours, sizeof(COL_CUBE), sort_func); - Cubes[0].Min = 0; - Cubes[NumColours-1] = UCHAR_MAX; - NumColours--; - for (i = 1; i < NumColours; i++) { - Cubes[i].Min[CurSort] = Cubes[i-1].Val[CurSort] + 1; - Cubes[i-1].Max[CurSort] = Cubes[i].Val[CurSort] - 1; - } - CurSort++; - NumColours++; - }*/ - for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp) { - Same = IL_TRUE; - if (i != 0) { - for (j = 0; j < CurImage->Bpp; j++) { - if (CurImage->Data[i-CurImage->Bpp+j] != CurImage->Data[i+j]) { - Same = IL_FALSE; - break; - } - } - } - if (Same) { - NewData[i / CurImage->Bpp] = DistEntry; - continue; - } - for (j = 0; j < Image.Pal.PalSize; j += 3) { - // No need to perform a sqrt. - Dist1 = (ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j]; - Dist2 = (ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j+1]; - Dist3 = (ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j+2]; - PalInfo[j / 3] = Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3; - } - MaxDist = UINT_MAX; - DistEntry = 0; - for (j = 0; j < NumColours; j++) { - if (PalInfo[j] < MaxDist) { - DistEntry = j; - MaxDist = PalInfo[j]; - } - } - NewData[i / CurImage->Bpp] = DistEntry; - } - - break; - - case IL_BGR: - case IL_BGRA: - for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp) { - for (j = 0; j < NumColours; j++) { - // No need to perform a sqrt. - PalInfo[j] = ((ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j * 3]) * - ((ILint)CurImage->Data[i+2] - (ILint)Image.Pal.Palette[j * 3]) + - ((ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j * 3 + 1]) * - ((ILint)CurImage->Data[i+1] - (ILint)Image.Pal.Palette[j * 3 + 1]) + - ((ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j * 3 + 2]) * - ((ILint)CurImage->Data[i] - (ILint)Image.Pal.Palette[j * 3 + 2]); - } - MaxDist = UINT_MAX; - DistEntry = 0; - for (j = 0; j < NumColours; j++) { - if (PalInfo[j] < MaxDist) { - DistEntry = j; - MaxDist = PalInfo[j]; - } - } - NewData[i / CurImage->Bpp] = DistEntry; - } - - break; - - case IL_LUMINANCE: - case IL_LUMINANCE_ALPHA: - for (i = 0; i < CurImage->SizeOfData; i += CurImage->Bpp ) { - for (j = 0; j < NumColours; j++) { - // No need to perform a sqrt. - PalInfo[j] = ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3]) * - ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3]) + - ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 1]) * - ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 1]) + - ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 2]) * - ((ILuint)CurImage->Data[i] - (ILuint)Image.Pal.Palette[j * 3 + 2]); - } - MaxDist = UINT_MAX; - DistEntry = 0; - for (j = 0; j < NumColours; j++) { - if (PalInfo[j] < MaxDist) { - DistEntry = j; - MaxDist = PalInfo[j]; - } - } - NewData[i] = DistEntry; - } - - break; - - default: // Should be no other! - break; - } - - iCurImage = CurImage; - Origin = iCurImage->Origin; - if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, 1, - IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NewData)) { - ifree(Image.Pal.Palette); - ifree(PalInfo); - ifree(NewData); - return IL_FALSE; - } - iCurImage->Origin = Origin; - - iCurImage->Pal.Palette = Image.Pal.Palette; - iCurImage->Pal.PalSize = Image.Pal.PalSize; - iCurImage->Pal.PalType = Image.Pal.PalType; - ifree(PalInfo); - ifree(NewData); - - return IL_TRUE; -} diff --git a/win32/devil/src/il_pcd.c b/win32/devil/src/il_pcd.c deleted file mode 100644 index cf6057269..000000000 --- a/win32/devil/src/il_pcd.c +++ /dev/null @@ -1,206 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/19/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pcd.c -// -// Description: Reads from a Kodak PhotoCD (.pcd) file. -// Note: The code here is sloppy - I had to convert it from Pascal, -// which I've never even attempted to read before...enjoy! =) -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_PCD -#include "il_manip.h" - - -ILboolean iLoadPcdInternal(void); - -//! Reads a .pcd file -ILboolean ilLoadPcd(ILconst_string FileName) -{ - ILHANDLE PcdFile; - ILboolean bPcd = IL_FALSE; - - PcdFile = iopenr(FileName); - if (PcdFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPcd; - } - - bPcd = ilLoadPcdF(PcdFile); - icloser(PcdFile); - - return bPcd; -} - - -//! Reads an already-opened .pcd file -ILboolean ilLoadPcdF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPcdInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .pcd file -ILboolean ilLoadPcdL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPcdInternal(); -} - - -ILvoid YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b) -{ - static const ILdouble c11 = 0.0054980*256; - static const ILdouble c12 = 0.0000000*256; - static const ILdouble c13 = 0.0051681*256; - static const ILdouble c21 = 0.0054980*256; - static const ILdouble c22 =-0.0015446*256; - static const ILdouble c23 =-0.0026325*256; - static const ILdouble c31 = 0.0054980*256; - static const ILdouble c32 = 0.0079533*256; - static const ILdouble c33 = 0.0000000*256; - ILint r1, g1, b1; - - r1 = (ILint)(c11*Y + c12*(Cb-156) + c13*(Cr-137)); - g1 = (ILint)(c21*Y + c22*(Cb-156) + c23*(Cr-137)); - b1 = (ILint)(c31*Y + c32*(Cb-156) + c33*(Cr-137)); - - if (r1 < 0) - *r = 0; - else if (r1 > 255) - *r = 255; - else - *r = r1; - - if (g1 < 0) - *g = 0; - else if (g1 > 255) - *g = 255; - else - *g = g1; - - if (b1 < 0) - *b = 0; - else if (b1 > 255) - *b = 255; - else - *b = b1; - - return; -} - - -ILboolean iLoadPcdInternal() -{ - ILubyte VertOrientation; - ILuint Width, Height, i, Total, x, CurPos = 0; - ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0; - ILuint PicNum; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iseek(72, IL_SEEK_CUR); - if (iread(&VertOrientation, 1, 1) != 1) - return IL_FALSE; - - iseek(-72, IL_SEEK_CUR); // Can't rewind - - PicNum = iGetInt(IL_PCD_PICNUM); - - switch (PicNum) - { - case 0: - iseek(0x02000, IL_SEEK_CUR); - Width = 192; - Height = 128; - break; - case 1: - iseek(0x0b800, IL_SEEK_CUR); - Width = 384; - Height = 256; - break; - case 2: - iseek(0x30000, IL_SEEK_CUR); - Width = 768; - Height = 512; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - Y1 = (ILubyte*)ialloc(Width); - Y2 = (ILubyte*)ialloc(Width); - CbCr = (ILubyte*)ialloc(Width); - if (Y1 == NULL || Y2 == NULL || CbCr == NULL) { - ifree(Y1); - ifree(Y2); - ifree(CbCr); - return IL_FALSE; - } - - if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - Total = Height >> 1; - for (i = 0; i < Total; i++) { - iread(Y1, 1, Width); - iread(Y2, 1, Width); - if (iread(CbCr, 1, Width) != Width) { // Only really need to check the last one. - ifree(Y1); - ifree(Y2); - ifree(CbCr); - return IL_FALSE; - } - - for (x = 0; x < Width; x++) { - YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); - iCurImage->Data[CurPos++] = r; - iCurImage->Data[CurPos++] = g; - iCurImage->Data[CurPos++] = b; - } - - for (x = 0; x < Width; x++) { - YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); - iCurImage->Data[CurPos++] = r; - iCurImage->Data[CurPos++] = g; - iCurImage->Data[CurPos++] = b; - } - } - - ifree(Y1); - ifree(Y2); - ifree(CbCr); - - // Not sure how it is...the documentation is hard to understand - if ((VertOrientation & 0x3F) != 8) - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - else - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - ilFixImage(); - - return IL_TRUE; -} - - -#endif//IL_NO_PCD diff --git a/win32/devil/src/il_pcx.c b/win32/devil/src/il_pcx.c deleted file mode 100644 index 246d689dd..000000000 --- a/win32/devil/src/il_pcx.c +++ /dev/null @@ -1,733 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 09/01/2003 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pcx.c -// -// Description: Reads and writes from/to a .pcx file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_PCX -#include "il_pcx.h" -#include "il_manip.h" - - -//! Checks if the file specified in FileName is a valid .pcx file. -ILboolean ilIsValidPcx(ILconst_string FileName) { - ILHANDLE PcxFile; - ILboolean bPcx = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("pcx"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPcx; - } - - PcxFile = iopenr(FileName); - if (PcxFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPcx; - } - - bPcx = ilIsValidPcxF(PcxFile); - icloser(PcxFile); - - return bPcx; -} - - -//! Checks if the ILHANDLE contains a valid .pcx file at the current position. -ILboolean ilIsValidPcxF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPcx(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .pcx lump. -ILboolean ilIsValidPcxL(const ILvoid *Lump, ILuint Size) { - iSetInputLump(Lump, Size); - return iIsValidPcx(); -} - - -// Internal function obtain the .pcx header from the current file. -ILboolean iGetPcxHead(PCXHEAD *Head) { - - Head->Manufacturer = igetc(); - - Head->Version = igetc(); - - Head->Encoding = igetc(); - - Head->Bpp = igetc(); - - Head->Xmin = GetLittleUShort(); - - Head->Ymin = GetLittleUShort(); - - Head->Xmax = GetLittleUShort(); - - Head->Ymax = GetLittleUShort(); - - Head->HDpi = GetLittleUShort(); - - Head->VDpi = GetLittleUShort(); - - iread(Head->ColMap, 1, 48); - - Head->Reserved = igetc(); - - Head->NumPlanes = igetc(); - - Head->Bps = GetLittleUShort(); - - Head->PaletteInfo = GetLittleUShort(); - - Head->HScreenSize = GetLittleUShort(); - - Head->VScreenSize = GetLittleUShort(); - - iread(Head->Filler, 1, 54); - - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPcx() { - PCXHEAD Head; - - if (!iGetPcxHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(PCXHEAD), IL_SEEK_CUR); - - return iCheckPcx(&Head); -} - - -// Internal function used to check if the HEADER is a valid .pcx header. -// Should we also do a check on Header->Bpp? -ILboolean iCheckPcx(PCXHEAD *Header) { - ILuint Test; - - // Got rid of the Reserved check, because I've seen some .pcx files with invalid values in it. - if (Header->Manufacturer != 10 || Header->Encoding != 1/* || Header->Reserved != 0*/) - return IL_FALSE; - - // Try to support all pcx versions, as they only differ in allowed formats... - // Let's hope it works. - if(Header->Version != 5 && Header->Version != 0 && Header->Version != 2 && - Header->VDpi != 3 && Header->VDpi != 4) - return IL_FALSE; - - // See if the padding size is correct - Test = Header->Xmax - Header->Xmin + 1; - if (Header->Bpp >= 8) { - if (Test & 1) { - if (Header->Bps != Test + 1) - return IL_FALSE; - } - else { - if (Header->Bps != Test) // No padding - return IL_FALSE; - } - } - - /* for (i = 0; i < 54; i++) { useless check - if (Header->Filler[i] != 0) - return IL_FALSE; - } */ - - return IL_TRUE; -} - - -//! Reads a .pcx file -ILboolean ilLoadPcx(ILconst_string FileName) { - ILHANDLE PcxFile; - ILboolean bPcx = IL_FALSE; - - PcxFile = iopenr(FileName); - if (PcxFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPcx; - } - - bPcx = ilLoadPcxF(PcxFile); - icloser(PcxFile); - - return bPcx; -} - - -//! Reads an already-opened .pcx file -ILboolean ilLoadPcxF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPcxInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .pcx -ILboolean ilLoadPcxL(const ILvoid *Lump, ILuint Size) { - iSetInputLump(Lump, Size); - return iLoadPcxInternal(); -} - - -// Internal function used to load the .pcx. -ILboolean iLoadPcxInternal() { - PCXHEAD Header; - ILboolean bPcx = IL_FALSE; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return bPcx; - } - - if (!iGetPcxHead(&Header)) - return IL_FALSE; - if (!iCheckPcx(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - bPcx = iUncompressPcx(&Header); - - ilFixImage(); - - return bPcx; -} - - -// Internal function to uncompress the .pcx (all .pcx files are rle compressed) -ILboolean iUncompressPcx(PCXHEAD *Header) { - //changed decompression loop 2003-09-01 - //From the pcx spec: "There should always - //be a decoding break at the end of each scan line. - //But there will not be a decoding break at the end of - //each plane within each scan line." - //This is now handled correctly (hopefully ;) ) - - ILubyte ByteHead, Colour, *ScanLine /* For all planes */; - ILuint ScanLineSize; - ILuint c, i, x, y; - - if (Header->Bpp < 8) { - /*ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE;*/ - return iUncompressSmall(Header); - } - - if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - switch (iCurImage->Bpp) - { - case 1: - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalType = IL_PAL_RGB24; - iCurImage->Pal.PalSize = 256 * 3; // Need to find out for sure... - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - break; - //case 2: // No 16-bit images in the pcx format! - case 3: - iCurImage->Format = IL_RGB; - iCurImage->Pal.Palette = NULL; - iCurImage->Pal.PalSize = 0; - iCurImage->Pal.PalType = IL_PAL_NONE; - break; - case 4: - iCurImage->Format = IL_RGBA; - iCurImage->Pal.Palette = NULL; - iCurImage->Pal.PalSize = 0; - iCurImage->Pal.PalType = IL_PAL_NONE; - break; - - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - ScanLineSize = iCurImage->Bpp*Header->Bps; - ScanLine = (ILubyte*)ialloc(ScanLineSize); - if (ScanLine == NULL) { - return IL_FALSE; - } - - - //changed 2003-09-01 - //having the decoding code twice is error-prone, - //so I made iUnCache() smart enough to grasp - //if iPreCache() wasn't called and call it - //anyways. - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->SizeOfData / 4); - - for (y = 0; y < iCurImage->Height; y++) { - x = 0; - //read scanline - while (x < ScanLineSize) { - if (iread(&ByteHead, 1, 1) != 1) { - iUnCache(); - goto file_read_error; - } - if ((ByteHead & 0xC0) == 0xC0) { - ByteHead &= 0x3F; - if (iread(&Colour, 1, 1) != 1) { - iUnCache(); - goto file_read_error; - } - if (x + ByteHead > ScanLineSize) { - iUnCache(); - goto file_read_error; - } - for (i = 0; i < ByteHead; i++) { - ScanLine[x++] = Colour; - } - } - else { - ScanLine[x++] = ByteHead; - } - } - - //convert plane-separated scanline into index, rgb or rgba pixels. - //there might be a padding byte at the end of each scanline... - for (x = 0; x < iCurImage->Width; x++) { - for(c = 0; c < iCurImage->Bpp; c++) { - iCurImage->Data[y * iCurImage->Bps + x * iCurImage->Bpp + c] = - ScanLine[x + c * Header->Bps]; - } - } - } - - iUnCache(); - - // Read in the palette - if (Header->Version == 5 && iCurImage->Bpp == 1) { - x = itell(); - if (iread(&ByteHead, 1, 1) == 0) { // If true, assume that we have a luminance image. - ilGetError(); // Get rid of the IL_FILE_READ_ERROR. - iCurImage->Format = IL_LUMINANCE; - if (iCurImage->Pal.Palette) - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.PalSize = 0; - iCurImage->Pal.PalType = IL_PAL_NONE; - } - else { - if (ByteHead != 12) // Some Quake2 .pcx files don't have this byte for some reason. - iseek(-1, IL_SEEK_CUR); - if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize) - goto file_read_error; - } - } - - ifree(ScanLine); - - return IL_TRUE; - -file_read_error: - ifree(ScanLine); - - //added 2003-09-01 - ilSetError(IL_FILE_READ_ERROR); - return IL_FALSE; -} - - -ILboolean iUncompressSmall(PCXHEAD *Header) { - ILuint i = 0, j, k, c, d, x, y, Bps; - ILubyte HeadByte, Colour, Data = 0, *ScanLine; - - if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - switch (Header->NumPlanes) - { - case 1: - iCurImage->Format = IL_LUMINANCE; - break; - case 4: - iCurImage->Format = IL_COLOUR_INDEX; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - if (Header->NumPlanes == 1 && Header->Bpp == 1) { - for (j = 0; j < iCurImage->Height; j++) { - i = 0; //number of written pixels - while (i < iCurImage->Width) { - if (iread(&HeadByte, 1, 1) != 1) - return IL_FALSE; - if (HeadByte >= 192) { - HeadByte -= 192; - if (iread(&Data, 1, 1) != 1) - return IL_FALSE; - - for (c = 0; c < HeadByte; c++) { - k = 128; - for (d = 0; d < 8 && i < iCurImage->Width; d++) { - iCurImage->Data[j * iCurImage->Width + i++] = ((Data & k) != 0 ? 255 : 0); - k >>= 1; - } - } - } - else { - k = 128; - for (c = 0; c < 8 && i < iCurImage->Width; c++) { - iCurImage->Data[j * iCurImage->Width + i++] = ((HeadByte & k) != 0 ? 255 : 0); - k >>= 1; - } - } - } - - //if(Data != 0) - //changed 2003-09-01: - //There has to be an even number of bytes per line in a pcx. - //One byte can hold up to 8 bits, so Width/8 bytes - //are needed to hold a 1 bit per pixel image line. - //If Width/8 is even no padding is needed, - //one pad byte has to be read otherwise. - //(let's hope the above is true ;-)) - if(!((iCurImage->Width >> 3) & 0x1)) - igetc(); // Skip pad byte - } - } - else if (Header->NumPlanes == 4 && Header->Bpp == 1){ // 4-bit images - //changed decoding 2003-09-10 (was buggy)...could need a speedup - - Bps = Header->Bps * Header->NumPlanes * 8; - iCurImage->Pal.Palette = (ILubyte*)ialloc(16 * 3); // Size of palette always (48 bytes). - ScanLine = (ILubyte*)ialloc(Bps); - if (iCurImage->Pal.Palette == NULL || ScanLine == NULL) { - ifree(ScanLine); - ifree(iCurImage->Pal.Palette); - return IL_FALSE; - } - memcpy(iCurImage->Pal.Palette, Header->ColMap, 16 * 3); - iCurImage->Pal.PalSize = 16 * 3; - iCurImage->Pal.PalType = IL_PAL_RGB24; - - memset(iCurImage->Data, 0, iCurImage->SizeOfData); - - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->SizeOfData / 4); - for (y = 0; y < iCurImage->Height; y++) { - x = 0; - while (x < Bps) { - if (iread(&HeadByte, 1, 1) != 1) { - iUnCache(); - ifree(ScanLine); - return IL_FALSE; - } - if ((HeadByte & 0xC0) == 0xC0) { - HeadByte &= 0x3F; - if (iread(&Colour, 1, 1) != 1) { - iUnCache(); - ifree(ScanLine); - return IL_FALSE; - } - for (i = 0; i < HeadByte; i++) { - k = 128; - for (j = 0; j < 8 && x < Bps; j++) { - ScanLine[x++] = (Colour & k)?1:0; - k >>= 1; - } - } - } - else { - k = 128; - for (j = 0; j < 8 && x < Bps; j++) { - ScanLine[x++] = (HeadByte & k)?1:0; - k >>= 1; - } - } - } - - for (x = 0; x < iCurImage->Width; x++) { // 'Cleverly' ignores the pad bytes. ;) - for(c = 0; c < Header->NumPlanes; c++) - iCurImage->Data[y * iCurImage->Width + x] |= ScanLine[x + c*Header->Bps*8] << c; - } - } - iUnCache(); - ifree(ScanLine); - } - else { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - - return IL_TRUE; -} - - -//! Writes a .pcx file -ILboolean ilSavePcx(ILconst_string FileName) { - ILHANDLE PcxFile; - ILboolean bPcx = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - PcxFile = iopenw(FileName); - if (PcxFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPcx; - } - - bPcx = ilSavePcxF(PcxFile); - iclosew(PcxFile); - - return bPcx; -} - - -//! Writes a .pcx to an already-opened file -ILboolean ilSavePcxF(ILHANDLE File) { - iSetOutputFile(File); - return iSavePcxInternal(); -} - - -//! Writes a .pcx to a memory "lump" -ILboolean ilSavePcxL(ILvoid *Lump, ILuint Size) { - iSetOutputLump(Lump, Size); - return iSavePcxInternal(); -} - - -// Internal function used to save the .pcx. -ILboolean iSavePcxInternal() { - ILuint i, c, PalSize; - ILpal *TempPal; - ILimage *TempImage = iCurImage; - ILubyte *TempData; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - switch (iCurImage->Format) - { - case IL_LUMINANCE: - TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - break; - - case IL_BGR: - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - break; - - case IL_BGRA: - TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - break; - - default: - if (iCurImage->Bpc > 1) { - TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE); - if (TempImage == NULL) - return IL_FALSE; - } - } - - if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) { - TempData = iGetFlipped(TempImage); - if (TempData == NULL) { - if (TempImage != iCurImage) { - ilCloseImage(TempImage); - } - return IL_FALSE; - } - } - else { - TempData = TempImage->Data; - } - - - iputc(0xA); // Manufacturer - always 10 - iputc(0x5); // Version Number - always 5 - iputc(0x1); // Encoding - always 1 - iputc(0x8); // Bits per channel - SaveLittleUShort(0); // X Minimum - SaveLittleUShort(0); // Y Minimum - SaveLittleUShort((ILushort)(iCurImage->Width - 1)); - SaveLittleUShort((ILushort)(iCurImage->Height - 1)); - SaveLittleUShort(0); - SaveLittleUShort(0); - - // Useless palette info? - for (i = 0; i < 48; i++) { - iputc(0); - } - iputc(0x0); // Reserved - always 0 - - iputc(iCurImage->Bpp); // Number of planes - only 1 is supported right now - - SaveLittleUShort((ILushort)(iCurImage->Width & 1 ? iCurImage->Width + 1 : iCurImage->Width)); // Bps - SaveLittleUShort(0x1); // Palette type - ignored? - - // Mainly filler info - for (i = 0; i < 58; i++) { - iputc(0x0); - } - - // Output data - for (i = 0; i < TempImage->Height; i++) { - for (c = 0; c < TempImage->Bpp; c++) { - encLine(TempData + TempImage->Bps * i + c, TempImage->Width, (ILubyte)(TempImage->Bpp - 1)); - } - } - - // Automatically assuming we have a palette...dangerous! - // Also assuming 3 bpp palette - iputc(0xC); // Pad byte must have this value - - // If the current image has a palette, take care of it - if (TempImage->Format == IL_COLOUR_INDEX) { - // If the palette in .pcx format, write it directly - if (TempImage->Pal.PalType == IL_PAL_RGB24) { - iwrite(TempImage->Pal.Palette, 1, TempImage->Pal.PalSize); - } - else { - TempPal = iConvertPal(&TempImage->Pal, IL_PAL_RGB24); - if (TempPal == NULL) { - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) - ifree(TempData); - if (TempImage != iCurImage) - ilCloseImage(TempImage); - return IL_FALSE; - } - - iwrite(TempPal->Palette, 1, TempPal->PalSize); - ifree(TempPal->Palette); - ifree(TempPal); - } - } - - // If the palette is not all 256 colours, we have to pad it. - PalSize = 768 - iCurImage->Pal.PalSize; - for (i = 0; i < PalSize; i++) { - iputc(0x0); - } - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) - ifree(TempData); - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - return IL_TRUE; -} - - -// Routine used from ZSoft's pcx documentation -ILuint encput(ILubyte byt, ILubyte cnt) { - if (cnt) { - if ((cnt == 1) && (0xC0 != (0xC0 & byt))) { - if (IL_EOF == iputc(byt)) - return(0); /* disk write error (probably full) */ - return(1); - } - else { - if (IL_EOF == iputc((ILubyte)((ILuint)0xC0 | cnt))) - return (0); /* disk write error */ - if (IL_EOF == iputc(byt)) - return (0); /* disk write error */ - return (2); - } - } - - return (0); -} - -/* This subroutine encodes one scanline and writes it to a file. -It returns number of bytes written into outBuff, 0 if failed. */ - -ILuint encLine(ILubyte *inBuff, ILint inLen, ILubyte Stride) -{ - ILubyte _this, last; - ILint srcIndex, i; - ILint total; - ILubyte runCount; // max single runlength is 63 - total = 0; - runCount = 1; - last = *(inBuff); - - // Find the pixel dimensions of the image by calculating - //[XSIZE = Xmax - Xmin + 1] and [YSIZE = Ymax - Ymin + 1]. - //Then calculate how many bytes are in a "run" - - for (srcIndex = 1; srcIndex < inLen; srcIndex++) { - inBuff += Stride; - _this = *(++inBuff); - if (_this == last) { // There is a "run" in the data, encode it - runCount++; - if (runCount == 63) { - if (! (i = encput(last, runCount))) - return (0); - total += i; - runCount = 0; - } - } - else { // No "run" - _this != last - if (runCount) { - if (! (i = encput(last, runCount))) - return(0); - total += i; - } - last = _this; - runCount = 1; - } - } // endloop - - if (runCount) { // finish up - if (! (i = encput(last, runCount))) - return (0); - if (inLen % 2) - iputc(0); - return (total + i); - } - else { - if (inLen % 2) - iputc(0); - } - - return (total); -} - -#endif//IL_NO_PCX diff --git a/win32/devil/src/il_pic.c b/win32/devil/src/il_pic.c deleted file mode 100644 index 36bbe973a..000000000 --- a/win32/devil/src/il_pic.c +++ /dev/null @@ -1,432 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/21/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pic.c -// -// Description: Softimage Pic (.pic) functions -// -//----------------------------------------------------------------------------- - -// @TODO: Test these extensively...haven't even been tested yet!!! - -#include "il_internal.h" -#ifndef IL_NO_PIC -#include "il_pic.h" -#include "il_manip.h" -#include - - -//! Checks if the file specified in FileName is a valid .pic file. -ILboolean ilIsValidPic(ILconst_string FileName) -{ - ILHANDLE PicFile; - ILboolean bPic = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("pic"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPic; - } - - PicFile = iopenr(FileName); - if (PicFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPic; - } - - bPic = ilIsValidPicF(PicFile); - icloser(PicFile); - - return bPic; -} - - -//! Checks if the ILHANDLE contains a valid .pic file at the current position. -ILboolean ilIsValidPicF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPic(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .pic lump. -ILboolean ilIsValidPicL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidPic(); -} - - -// Internal function used to get the .pic header from the current file. -ILboolean iGetPicHead(PIC_HEAD *Header) -{ - Header->Magic = GetLittleInt(); - - Header->Version = GetLittleFloat(); - - iread(Header->Comment, 1, 80); - - iread(Header->Id, 1, 4); - - Header->Width = GetLittleShort(); - - Header->Height = GetLittleShort(); - - Header->Ratio = GetLittleFloat(); - - Header->Fields = GetLittleShort(); - - Header->Padding = GetLittleShort(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPic() -{ - PIC_HEAD Head; - - if (!iGetPicHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(PIC_HEAD), IL_SEEK_CUR); // Go ahead and restore to previous state - - return iCheckPic(&Head); -} - - -// Internal function used to check if the header is a valid .pic header. -ILboolean iCheckPic(PIC_HEAD *Header) -{ - if (Header->Magic != 0x5380F634) - return IL_FALSE; - if (strncmp((const char*)Header->Id, "PICT", 4)) - return IL_FALSE; - if (Header->Width == 0) - return IL_FALSE; - if (Header->Height == 0) - return IL_FALSE; - - return IL_TRUE; -} - - -//! Reads a .pic file -ILboolean ilLoadPic(ILconst_string FileName) -{ - ILHANDLE PicFile; - ILboolean bPic = IL_FALSE; - - PicFile = iopenr(FileName); - if (PicFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPic; - } - - bPic = ilLoadPicF(PicFile); - icloser(PicFile); - - return bPic; -} - - -//! Reads an already-opened .pic file -ILboolean ilLoadPicF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPicInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .pic -ILboolean ilLoadPicL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPicInternal(); -} - - -// Internal function used to load the .pic -ILboolean iLoadPicInternal() -{ - ILuint Alpha = IL_FALSE; - ILubyte Chained; - CHANNEL *Channel = NULL, *Channels = NULL, *Prev; - PIC_HEAD Header; - ILboolean Read; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetPicHead(&Header)) - return IL_FALSE; - if (!iCheckPic(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ilTexImage(Header.Width, Header.Height, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - // Read channels - do { - if (Channel == NULL) { - Channel = Channels = (CHANNEL*)ialloc(sizeof(CHANNEL)); - if (Channels == NULL) - return IL_FALSE; - } - else { - Channels->Next = (CHANNEL*)ialloc(sizeof(CHANNEL)); - if (Channels->Next == NULL) { - // Clean up the list before erroring out. - while (Channel) { - Prev = Channel; - Channel = (CHANNEL*)Channel->Next; - ifree(Prev); - } - return IL_FALSE; - } - Channels = (CHANNEL*)Channels->Next; - } - Channels->Next = NULL; - - Chained = igetc(); - Channels->Size = igetc(); - Channels->Type = igetc(); - Channels->Chan = igetc(); - if (ieof()) { - Read = IL_FALSE; - goto finish; - } - - // See if we have an alpha channel in there - if (Channels->Chan & PIC_ALPHA_CHANNEL) - Alpha = IL_TRUE; - - } while (Chained); - - Read = readScanlines((ILuint*)iCurImage->Data, Header.Width, Header.Height, Channel, Alpha); - -finish: - - // Destroy channels - while (Channel) { - Prev = Channel; - Channel = (CHANNEL*)Channel->Next; - ifree(Prev); - } - - if (Read == IL_FALSE) - return IL_FALSE; - - ilFixImage(); - - return IL_TRUE; -} - - -ILboolean readScanlines(ILuint *image, ILint width, ILint height, CHANNEL *channel, ILuint alpha) -{ - ILint i; - ILuint *scan; - - (void)alpha; - - for (i = height - 1; i >= 0; i--) { - scan = image + i * width; - - if (!readScanline((ILubyte *)scan, width, channel, 4)) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - } - - return IL_TRUE; -} - -ILuint readScanline(ILubyte *scan, ILint width, CHANNEL *channel, ILint bytes) -{ - ILint noCol; - ILint off[4]; - ILuint status=0; - - while (channel) { - noCol = 0; -//#ifndef sgi - if(channel->Chan & PIC_RED_CHANNEL) { - off[noCol] = 0; - noCol++; - } - if(channel->Chan & PIC_GREEN_CHANNEL) { - off[noCol] = 1; - noCol++; - } - if(channel->Chan & PIC_BLUE_CHANNEL) { - off[noCol] = 2; - noCol++; - } - if(channel->Chan & PIC_ALPHA_CHANNEL) { - off[noCol] = 3; - noCol++; - } -/*#else - if(channel->channels & PIC_RED_CHANNEL) { - off[noCol] = 3; - noCol++; - } - if(channel->channels & PIC_GREEN_CHANNEL) { - off[noCol] = 2; - noCol++; - } - if(channel->channels & PIC_BLUE_CHANNEL) { - off[noCol] = 1; - noCol++; - } - if(channel->channels & PIC_ALPHA_CHANNEL) { - off[noCol] = 0; - noCol++; - } -#endif*/ - - switch(channel->Type & 0x0F) { - case PIC_UNCOMPRESSED: - status = channelReadRaw(scan, width, noCol, off, bytes); - break; - case PIC_PURE_RUN_LENGTH: - status = channelReadPure(scan, width, noCol, off, bytes); - break; - case PIC_MIXED_RUN_LENGTH: - status = channelReadMixed(scan, width, noCol, off, bytes); - break; - } - if (!status) - break; - - channel = (CHANNEL*)channel->Next; - } - return status; -} - -ILboolean channelReadRaw(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes) -{ - ILint i, j; - - for (i = 0; i < width; i++) { - if (ieof()) - return IL_FALSE; - for (j = 0; j < noCol; j++) - if (iread(&scan[off[j]], 1, 1) != 1) - return IL_FALSE; - scan += bytes; - } - return IL_TRUE; -} - -ILboolean channelReadPure(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes) -{ - ILubyte col[4]; - ILint count; - int i, j, k; - - for (i = width; i > 0; ) { - count = igetc(); - if (count == IL_EOF) - return IL_FALSE; - if (count > width) - count = width; - i -= count; - - if (ieof()) - return IL_FALSE; - - for (j = 0; j < noCol; j++) - if (iread(&col[j], 1, 1) != 1) - return IL_FALSE; - - for (k = 0; k < count; k++, scan += bytes) { - for(j = 0; j < noCol; j++) - scan[off[j] + k] = col[j]; - } - } - return IL_TRUE; -} - -ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes) -{ - ILint count; - int i, j, k; - ILubyte col[4]; - - for(i = 0; i < width; i += count) { - if (ieof()) - return IL_FALSE; - - count = igetc(); - if (count == IL_EOF) - return IL_FALSE; - - if (count >= 128) { // Repeated sequence - if (count == 128) { // Long run - count = GetLittleUShort(); - if (ieof()) - return IL_FALSE; - } - else - count -= 127; - - // We've run past... - if ((i + count) > width) { - //fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Repeat) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol); - return IL_FALSE; - } - - for (j = 0; j < noCol; j++) - if (iread(&col[j], 1, 1) != 1) - return IL_FALSE; - - for (k = 0; k < count; k++, scan += bytes) { - for (j = 0; j < noCol; j++) - scan[off[j]] = col[j]; - } - } else { // Raw sequence - count++; - if ((i + count) > width) { - //fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Raw) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol); - return IL_FALSE; - } - - for (k = count; k > 0; k--, scan += bytes) { - for (j = 0; j < noCol; j++) - if (iread(&scan[off[j]], 1, 1) != 1) - return IL_FALSE; - } - } - } - - return IL_TRUE; -} - - - - -#endif//IL_NO_PIC diff --git a/win32/devil/src/il_pix.c b/win32/devil/src/il_pix.c deleted file mode 100644 index b5b4742e7..000000000 --- a/win32/devil/src/il_pix.c +++ /dev/null @@ -1,164 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/26/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pix.c -// -// Description: Reads from an Alias | Wavefront .pix file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_PIX -#include "il_manip.h" -#include "il_endian.h" - - -#ifdef _MSC_VER -#pragma pack(push, pix_struct, 1) -#endif -typedef struct PIXHEAD -{ - ILushort Width; - ILushort Height; - ILushort OffX; - ILushort OffY; - ILushort Bpp; -} IL_PACKSTRUCT PIXHEAD; -#ifdef _MSC_VER -#pragma pack(pop, pix_struct) -#endif - -ILboolean iCheckPix(PIXHEAD *Header); -ILboolean iLoadPixInternal(void); - - -// Internal function used to get the Pix header from the current file. -ILboolean iGetPixHead(PIXHEAD *Header) { - Header->Width = GetBigUShort(); - - Header->Height = GetBigUShort(); - - Header->OffX = GetBigUShort(); - - Header->OffY = GetBigUShort(); - - Header->Bpp = GetBigUShort(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPix() -{ - PIXHEAD Head; - - if (!iGetPixHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(PIXHEAD), IL_SEEK_CUR); - - return iCheckPix(&Head); -} - - -// Internal function used to check if the HEADER is a valid Pix header. -ILboolean iCheckPix(PIXHEAD *Header) -{ - if (Header->Width == 0 || Header->Height == 0) - return IL_FALSE; - if (Header->Bpp != 24) - return IL_FALSE; - //if (Header->OffY != Header->Height) - // return IL_FALSE; - - return IL_TRUE; -} - - -//! Reads a Pix file -ILboolean ilLoadPix(ILconst_string FileName) -{ - ILHANDLE PixFile; - ILboolean bPix = IL_FALSE; - - PixFile = iopenr(FileName); - if (PixFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPix; - } - - bPix = ilLoadPixF(PixFile); - icloser(PixFile); - - return bPix; -} - - -//! Reads an already-opened Pix file -ILboolean ilLoadPixF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPixInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Pix -ILboolean ilLoadPixL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPixInternal(); -} - - -// Internal function used to load the Pix. -ILboolean iLoadPixInternal() -{ - PIXHEAD Header; - ILuint i, j; - ILubyte ByteHead, Colour[3]; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetPixHead(&Header)) - return IL_FALSE; - if (!iCheckPix(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - - for (i = 0; i < iCurImage->SizeOfData; ) { - ByteHead = igetc(); - if (iread(Colour, 1, 3) != 3) - return IL_FALSE; - for (j = 0; j < ByteHead; j++) { - iCurImage->Data[i++] = Colour[0]; - iCurImage->Data[i++] = Colour[1]; - iCurImage->Data[i++] = Colour[2]; - } - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - ilFixImage(); - - return IL_TRUE; -} - -#endif//IL_NO_PIX diff --git a/win32/devil/src/il_png.c b/win32/devil/src/il_png.c deleted file mode 100644 index 688c606fe..000000000 --- a/win32/devil/src/il_png.c +++ /dev/null @@ -1,714 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 02/01/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_png.c -// -// Description: Portable network graphics file (.png) functions -// -// 20040223 XIX : now may spit out pngs with a transparent index, this is mostly a hack -// but the proper way of doing it would be to change the pal stuff to think in argb rather than rgb -// which is something of a bigger job. -// -//----------------------------------------------------------------------------- - -// Most of the comments are left in this file from libpng's excellent example.c - -#include "il_internal.h" -#ifndef IL_NO_PNG -#include -#include "il_manip.h" -#include -#if PNG_LIBPNG_VER < 10200 - #warning DevIL was designed with libpng 1.2.0 or higher in mind. Consider upgrading at www.libpng.org -#endif - - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "libpng.lib") - #pragma comment(lib, "zlib.lib") - #endif - #endif -#endif - - -ILboolean iIsValidPng(void); -ILboolean iLoadPngInternal(void); -ILboolean iSavePngInternal(void); - -ILint readpng_init(void); -ILboolean readpng_get_image(ILdouble display_exponent); -ILvoid readpng_cleanup(void); - -png_structp png_ptr = NULL; -png_infop info_ptr = NULL; -ILint color_type; - -#define GAMMA_CORRECTION 1.0 // Doesn't seem to be doing anything... - - -ILboolean ilIsValidPng(ILconst_string FileName) -{ - ILHANDLE PngFile; - ILboolean bPng = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("png"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPng; - } - - PngFile = iopenr(FileName); - if (PngFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPng; - } - - bPng = ilIsValidPngF(PngFile); - icloser(PngFile); - - return bPng; -} - - -ILboolean ilIsValidPngF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPng(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -ILboolean ilIsValidPngL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidPng(); -} - - -ILboolean iIsValidPng() -{ - ILubyte Signature[8]; - ILint Read; - - Read = iread(Signature, 1, 8); - iseek(-Read, IL_SEEK_CUR); - - return png_check_sig(Signature, 8); -} - - -// Reads a file -ILboolean ilLoadPng(ILconst_string FileName) -{ - ILHANDLE PngFile; - ILboolean bPng = IL_FALSE; - - PngFile = iopenr(FileName); - if (PngFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPng; - } - - bPng = ilLoadPngF(PngFile); - icloser(PngFile); - - return bPng; -} - - -// Reads an already-opened file -ILboolean ilLoadPngF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPngInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -// Reads from a memory "lump" -ILboolean ilLoadPngL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPngInternal(); -} - - -ILboolean iLoadPngInternal() -{ - png_ptr = NULL; - info_ptr = NULL; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - if (!iIsValidPng()) { - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - if (readpng_init()) - return IL_FALSE; - if (!readpng_get_image(GAMMA_CORRECTION)) - return IL_FALSE; - - readpng_cleanup(); - - ilFixImage(); - - return IL_TRUE; -} - - -static ILvoid png_read(png_structp png_ptr, png_bytep data, png_size_t length) -{ - (void)png_ptr; - iread(data, 1, length); - return; -} - - -static void png_error_func(png_structp png_ptr, png_const_charp message) -{ - ilSetError(IL_LIB_PNG_ERROR); - - /* - changed 20040224 - From the libpng docs: - "Errors handled through png_error() are fatal, meaning that png_error() - should never return to its caller. Currently, this is handled via - setjmp() and longjmp()" - */ - //return; - longjmp(png_jmpbuf(png_ptr), 1); -} - -static void png_warn_func(png_structp png_ptr, png_const_charp message) -{ - return; -} - - -ILint readpng_init() -{ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_func, png_warn_func); - if (!png_ptr) - return 4; /* out of memory */ - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, NULL, NULL); - return 4; /* out of memory */ - } - - - /* we could create a second info struct here (end_info), but it's only - * useful if we want to keep pre- and post-IDAT chunk info separated - * (mainly for PNG-aware image editors and converters) */ - - - /* setjmp() must be called in every function that calls a PNG-reading - * libpng function */ - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return 2; - } - - - png_set_read_fn(png_ptr, NULL, png_read); - png_set_error_fn(png_ptr, NULL, png_error_func, png_warn_func); - -// png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ - - png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ - - - /* alternatively, could make separate calls to png_get_image_width(), - * etc., but want bit_depth and color_type for later [don't care about - * compression_type and filter_type => NULLs] */ - - /* OK, that's all we need for now; return happy */ - - return 0; -} - - -/* display_exponent == LUT_exponent * CRT_exponent */ - -ILboolean readpng_get_image(ILdouble display_exponent) -{ - png_bytepp row_pointers = NULL; - png_uint_32 width, height; // Changed the type to fix AMD64 bit problems, thanks to Eric Werness - ILdouble screen_gamma = 1.0; - ILuint i, channels; - ILenum format; - png_colorp palette; - ILint num_palette, j, bit_depth; -#if _WIN32 || DJGPP - ILdouble image_gamma; -#endif - - /* setjmp() must be called in every function that calls a PNG-reading - * libpng function */ - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return IL_FALSE; - } - - png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, - &bit_depth, &color_type, NULL, NULL, NULL); - - // Expand low-bit-depth grayscale images to 8 bits - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { - png_set_expand_gray_1_2_4_to_8(png_ptr); - } - - // Expand RGB images with transparency to full alpha channels - // so the data will be available as RGBA quartets. - // But don't expand paletted images, since we want alpha palettes! - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) && !(png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))) - png_set_tRNS_to_alpha(png_ptr); - - //refresh information (added 20040224) - png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, - &bit_depth, &color_type, NULL, NULL, NULL); - - if (bit_depth < 8) { // Expanded earlier for grayscale, now take care of palette and rgb - bit_depth = 8; - png_set_packing(png_ptr); - } - - // Perform gamma correction. - // @TODO: Determine if we should call png_set_gamma if image_gamma is 1.0. -#if _WIN32 || DJGPP - screen_gamma = 2.2; - if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) - png_set_gamma(png_ptr, screen_gamma, image_gamma); -#else - screen_gamma = screen_gamma; -#endif - - //fix endianess -#ifdef __LITTLE_ENDIAN__ - if (bit_depth == 16) - png_set_swap(png_ptr); -#endif - - - png_read_update_info(png_ptr, info_ptr); - channels = (ILint)png_get_channels(png_ptr, info_ptr); - //added 20040224: update color_type so that it has the correct value - //in iLoadPngInternal (globals rule...) - color_type = png_get_color_type(png_ptr, info_ptr); - - //determine internal format - switch(color_type) - { - case PNG_COLOR_TYPE_PALETTE: - format = IL_COLOUR_INDEX; - break; - case PNG_COLOR_TYPE_GRAY: - format = IL_LUMINANCE; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - format = IL_LUMINANCE_ALPHA; - break; - case PNG_COLOR_TYPE_RGB: - format = IL_RGB; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - format = IL_RGBA; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return IL_FALSE; - } - - if (!ilTexImage(width, height, 1, (ILubyte)channels, format, ilGetTypeBpc((ILubyte)(bit_depth >> 3)), NULL)) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - //copy palette - if (format == IL_COLOUR_INDEX) { - int chans; - png_bytep trans = NULL; - int num_trans = -1; - if (!png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return IL_FALSE; - } - - chans = 3; - iCurImage->Pal.PalType = IL_PAL_RGB24; - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); - iCurImage->Pal.PalType = IL_PAL_RGBA32; - chans = 4; - } - - iCurImage->Pal.PalSize = num_palette * chans; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - - for (j = 0; j < num_palette; ++j) { - iCurImage->Pal.Palette[chans*j + 0] = palette[j].red; - iCurImage->Pal.Palette[chans*j + 1] = palette[j].green; - iCurImage->Pal.Palette[chans*j + 2] = palette[j].blue; - if (trans!=NULL) { - if (jPal.Palette[chans*j + 3] = trans[j]; - else - iCurImage->Pal.Palette[chans*j + 3] = 255; - } - } - } - - //allocate row pointers - if ((row_pointers = (png_bytepp)ialloc(height * sizeof(png_bytep))) == NULL) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return IL_FALSE; - } - - - // Set the individual row_pointers to point at the correct offsets */ - for (i = 0; i < height; i++) - row_pointers[i] = iCurImage->Data + i * iCurImage->Bps; - - - // Now we can go ahead and just read the whole image - png_read_image(png_ptr, row_pointers); - - - /* and we're done! (png_read_end() can be omitted if no processing of - * post-IDAT text/time/etc. is desired) */ - //png_read_end(png_ptr, NULL); - ifree(row_pointers); - - return IL_TRUE; -} - - -ILvoid readpng_cleanup() -{ - if (png_ptr && info_ptr) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - png_ptr = NULL; - info_ptr = NULL; - } -} - - -//! Writes a Png file -ILboolean ilSavePng(ILconst_string FileName) -{ - ILHANDLE PngFile; - ILboolean bPng = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - PngFile = iopenw(FileName); - if (PngFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPng; - } - - bPng = ilSavePngF(PngFile); - iclosew(PngFile); - - return bPng; -} - - -//! Writes a Png to an already-opened file -ILboolean ilSavePngF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSavePngInternal(); -} - - -//! Writes a Png to a memory "lump" -ILboolean ilSavePngL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSavePngInternal(); -} - - -ILvoid png_write(png_structp png_ptr, png_bytep data, png_size_t length) -{ - (void)png_ptr; - iwrite(data, 1, length); - return; -} - -ILvoid flush_data(png_structp png_ptr) -{ - return; -} - - -// Internal function used to save the Png. -ILboolean iSavePngInternal() -{ - png_structp png_ptr; - png_infop info_ptr; - png_text text[3]; - ILenum PngType; - ILuint BitDepth, i, j; - ILubyte **RowPtr = NULL; - ILimage *Temp = NULL; - ILpal *TempPal = NULL; - -//XIX alpha - ILubyte transpart[1]; - ILint trans; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also check that - * the library version is compatible with the one used at compile time, - * in case we are using dynamically linked libraries. REQUIRED. - */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_func, png_warn_func); - if (png_ptr == NULL) { - ilSetError(IL_LIB_PNG_ERROR); - return IL_FALSE; - } - - // Allocate/initialize the image information data. REQUIRED - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - ilSetError(IL_LIB_PNG_ERROR); - goto error_label; - } - - /*// Set error handling. REQUIRED if you aren't supplying your own - // error handling functions in the png_create_write_struct() call. - if (setjmp(png_jmpbuf(png_ptr))) { - // If we get here, we had a problem reading the file - png_destroy_write_struct(&png_ptr, &info_ptr); - ilSetError(IL_LIB_PNG_ERROR); - return IL_FALSE; - }*/ - -// png_init_io(png_ptr, PngFile); - png_set_write_fn(png_ptr, NULL, png_write, flush_data); - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - Temp = iCurImage; - BitDepth = 8; - break; - case IL_SHORT: - case IL_UNSIGNED_SHORT: - Temp = iCurImage; - BitDepth = 16; - break; - case IL_INT: - case IL_UNSIGNED_INT: - Temp = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_SHORT); - if (Temp == NULL) { - png_destroy_write_struct(&png_ptr, &info_ptr); - return IL_FALSE; - } - BitDepth = 16; - break; - default: - ilSetError(IL_INTERNAL_ERROR); - goto error_label; - } - - switch (iCurImage->Format) - { - case IL_COLOUR_INDEX: - PngType = PNG_COLOR_TYPE_PALETTE; - break; - case IL_LUMINANCE: - PngType = PNG_COLOR_TYPE_GRAY; - break; - case IL_LUMINANCE_ALPHA: //added 20050328 - PngType = PNG_COLOR_TYPE_GRAY_ALPHA; - break; - case IL_RGB: - case IL_BGR: - PngType = PNG_COLOR_TYPE_RGB; - break; - case IL_RGBA: - case IL_BGRA: - PngType = PNG_COLOR_TYPE_RGB_ALPHA; - break; - default: - ilSetError(IL_INTERNAL_ERROR); - goto error_label; - } - - // Set the image information here. Width and height are up to 2^31, - // bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on - // the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, - // PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, - // or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or - // PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST - // currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED - if (iGetInt(IL_PNG_INTERLACE) == IL_TRUE) { - png_set_IHDR(png_ptr, info_ptr, iCurImage->Width, iCurImage->Height, BitDepth, PngType, - PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - } - else { - png_set_IHDR(png_ptr, info_ptr, iCurImage->Width, iCurImage->Height, BitDepth, PngType, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - } - - if (iCurImage->Format == IL_COLOUR_INDEX) { - // set the palette if there is one. REQUIRED for indexed-color images. - TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_RGB24); - png_set_PLTE(png_ptr, info_ptr, (png_colorp)TempPal->Palette, - ilGetInteger(IL_PALETTE_NUM_COLS)); - -//XIX alpha - trans=iGetInt(IL_PNG_ALPHA_INDEX); - if ( trans>=0) - { - transpart[0]=(ILubyte)trans; - png_set_tRNS(png_ptr, info_ptr, transpart, 1, 0); - } - } - - /* - // optional significant bit chunk - // if we are dealing with a grayscale image then - sig_bit.gray = true_bit_depth; - // otherwise, if we are dealing with a color image then - sig_bit.red = true_red_bit_depth; - sig_bit.green = true_green_bit_depth; - sig_bit.blue = true_blue_bit_depth; - // if the image has an alpha channel then - sig_bit.alpha = true_alpha_bit_depth; - png_set_sBIT(png_ptr, info_ptr, sig_bit);*/ - - - /* Optional gamma chunk is strongly suggested if you have any guess - * as to the correct gamma of the image. - */ - //png_set_gAMA(png_ptr, info_ptr, gamma); - - // Optionally write comments into the image. - imemclear(text, sizeof(png_text) * 3); - text[0].key = "Generated by"; - text[0].text = "Generated by the Developer's Image Library (DevIL)"; - text[0].compression = PNG_TEXT_COMPRESSION_NONE; - text[1].key = "Author's name"; - text[1].text = iGetString(IL_PNG_AUTHNAME_STRING); - text[1].compression = PNG_TEXT_COMPRESSION_NONE; - text[2].key = "Author's comments"; - text[2].text = iGetString(IL_PNG_AUTHNAME_STRING); - text[2].compression = PNG_TEXT_COMPRESSION_NONE; - png_set_text(png_ptr, info_ptr, text, 3); - - // Write the file header information. REQUIRED. - png_write_info(png_ptr, info_ptr); - - // Free up our user-defined text. - if (text[1].text) - ifree(text[1].text); - if (text[2].text) - ifree(text[2].text); - - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ - //png_set_shift(png_ptr, &sig_bit); - - /* pack pixels into bytes */ - //png_set_packing(png_ptr); - - // swap location of alpha bytes from ARGB to RGBA - //png_set_swap_alpha(png_ptr); - - // flip BGR pixels to RGB - if (iCurImage->Format == IL_BGR || iCurImage->Format == IL_BGRA) - png_set_bgr(png_ptr); - - // swap bytes of 16-bit files to most significant byte first - #ifdef __LITTLE_ENDIAN__ - png_set_swap(png_ptr); - #endif//__LITTLE_ENDIAN__ - - RowPtr = (ILubyte**)ialloc(iCurImage->Height * sizeof(ILubyte*)); - if (RowPtr == NULL) - goto error_label; - if (iCurImage->Origin == IL_ORIGIN_UPPER_LEFT) { - for (i = 0; i < iCurImage->Height; i++) { - RowPtr[i] = Temp->Data + i * Temp->Bps; - } - } - else { - j = iCurImage->Height - 1; - for (i = 0; i < iCurImage->Height; i++, j--) { - RowPtr[i] = Temp->Data + j * Temp->Bps; - } - } - - // Writes the image. - png_write_image(png_ptr, RowPtr); - - // It is REQUIRED to call this to finish writing the rest of the file - png_write_end(png_ptr, info_ptr); - - // clean up after the write, and ifree any memory allocated - png_destroy_write_struct(&png_ptr, &info_ptr); - - ifree(RowPtr); - - if (Temp != iCurImage) - ilCloseImage(Temp); - ilClosePal(TempPal); - - return IL_TRUE; - -error_label: - png_destroy_write_struct(&png_ptr, &info_ptr); - ifree(RowPtr); - if (Temp != iCurImage) - ilCloseImage(Temp); - ilClosePal(TempPal); - return IL_FALSE; -} - - -#endif//IL_NO_PNG diff --git a/win32/devil/src/il_pnm.c b/win32/devil/src/il_pnm.c deleted file mode 100644 index 7d58c1605..000000000 --- a/win32/devil/src/il_pnm.c +++ /dev/null @@ -1,691 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/21/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pnm.c -// -// Description: Reads/writes to/from pbm/pgm/ppm formats (enough slashes? =) -// -//----------------------------------------------------------------------------- - - - -#include "il_internal.h" -#ifndef IL_NO_PNM -#include "il_pnm.h" -#include // for maximum values -#include -#include "il_manip.h" -#include "il_bits.h" - -// According to the ppm specs, it's 70, but PSP -// likes to output longer lines... -#define MAX_BUFFER 180 -static ILbyte LineBuffer[MAX_BUFFER]; -static ILbyte SmallBuff[MAX_BUFFER]; - -// Can't read direct bits from a lump yet -ILboolean IsLump = IL_FALSE; - - -//! Checks if the file specified in FileName is a valid .pnm file. -ILboolean ilIsValidPnm(ILconst_string FileName) -{ - ILHANDLE PnmFile; - ILboolean bPnm = IL_FALSE; - - if ( !iCheckExtension(FileName, IL_TEXT("pbm")) - && !iCheckExtension(FileName, IL_TEXT("pgm")) - && !iCheckExtension(FileName, IL_TEXT("ppm")) - && !iCheckExtension(FileName, IL_TEXT("pnm"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPnm; - } - - PnmFile = iopenr(FileName); - if (PnmFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPnm; - } - - bPnm = ilIsValidPnmF(PnmFile); - icloser(PnmFile); - - return bPnm; -} - - -//! Checks if the ILHANDLE contains a valid .pnm file at the current position. -ILboolean ilIsValidPnmF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPnm(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid .pnm lump. -ILboolean ilIsValidPnmL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidPnm(); -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPnm() -{ - char Head[2]; - ILint Read; - - Read = iread(Head, 1, 2); - iseek(-Read, IL_SEEK_CUR); // Go ahead and restore to previous state - if (Read != 2) - return IL_FALSE; - - return iCheckPnm(Head); -} - - -// Internal function used to check if the HEADER is a valid .pnm header. -ILboolean iCheckPnm(char Header[2]) -{ - if (Header[0] != 'P') - return IL_FALSE; - switch (Header[1]) - { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - return IL_TRUE; - } - - return IL_FALSE; -} - - -// Reads a file -ILboolean ilLoadPnm(ILconst_string FileName) -{ - ILHANDLE PnmFile; - ILboolean bPnm = IL_FALSE; - - PnmFile = iopenr(FileName); - if (PnmFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPnm; - } - - bPnm = ilLoadPnmF(PnmFile); - icloser(PnmFile); - - return bPnm; -} - - -// Reads an already-opened file -ILboolean ilLoadPnmF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPnmInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -// Reads from a memory "lump" -ILboolean ilLoadPnmL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPnmInternal(); -} - - -// Load either a pgm or a ppm -ILboolean iLoadPnmInternal() -{ - ILimage *PmImage = NULL; - PPMINFO Info; -// ILuint LineInc = 0, SmallInc = 0; - - Info.Type = 0; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - // Find out what type of pgm/ppm this is - if (iGetWord(IL_FALSE) == IL_FALSE) - return IL_FALSE; - - if (SmallBuff[0] != 'P') { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - switch( SmallBuff[1] ) { - case '1': - Info.Type = IL_PBM_ASCII; - break; - case '2': - Info.Type = IL_PGM_ASCII; - break; - case '3': - Info.Type = IL_PPM_ASCII; - break; - case '4': - Info.Type = IL_PBM_BINARY; - if (IsLump) { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - break; - case '5': - Info.Type = IL_PGM_BINARY; - break; - case '6': - Info.Type = IL_PPM_BINARY; - break; - default: - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // Retrieve the width and height - if (iGetWord(IL_FALSE) == IL_FALSE) - return IL_FALSE; - Info.Width = atoi((const char*)SmallBuff); - if (Info.Width == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (iGetWord(IL_FALSE) == IL_FALSE) - return IL_FALSE; - Info.Height = atoi((const char*)SmallBuff); - if (Info.Height == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // Retrieve the maximum colour component value - if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY) { - if (iGetWord(IL_TRUE) == IL_FALSE) - return IL_FALSE; - if ((Info.MaxColour = atoi((const char*)SmallBuff)) == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - } else { - Info.MaxColour = 1; - } - - if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || - Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) { - if (Info.Type == IL_PGM_ASCII) { - Info.Bpp = Info.MaxColour < 256 ? 1 : 2; - } else { - Info.Bpp = 1; - } - } else { - Info.Bpp = 3; - } - - switch (Info.Type) { - case IL_PBM_ASCII: - case IL_PGM_ASCII: - case IL_PPM_ASCII: - PmImage = ilReadAsciiPpm(&Info); - break; - case IL_PBM_BINARY: - PmImage = ilReadBitPbm(&Info); - break; - case IL_PGM_BINARY: - case IL_PPM_BINARY: - PmImage = ilReadBinaryPpm(&Info); - break; - default: - return IL_FALSE; - } - - if (PmImage == NULL) { - iCurImage->Format = ilGetFormatBpp(iCurImage->Bpp); - ilSetError(IL_FILE_READ_ERROR); - return IL_FALSE; - } - - // Is this conversion needed? Just 0's and 1's shows up as all black - if (Info.Type == IL_PBM_ASCII) { - PbmMaximize(PmImage); - } - - if (Info.MaxColour > 255) - PmImage->Type = IL_UNSIGNED_SHORT; - PmImage->Origin = IL_ORIGIN_UPPER_LEFT; - if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || - Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) - PmImage->Format = IL_LUMINANCE; - else - PmImage->Format = IL_RGB; - PmImage->Origin = IL_ORIGIN_UPPER_LEFT; - - ilFixImage(); - - if (PmImage == NULL) - return IL_FALSE; - - return IL_TRUE; -} - - - -ILimage *ilReadAsciiPpm(PPMINFO *Info) -{ - ILint LineInc = 0, SmallInc = 0, DataInc = 0, Size; -// ILint BytesRead = 0; - - if (Info->MaxColour > 255) - Info->Bpp *= 2; - - Size = Info->Width * Info->Height * Info->Bpp; - - if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - if (Info->MaxColour > 255) - iCurImage->Type = IL_UNSIGNED_SHORT; - - while (DataInc < Size) { // && !feof(File)) { - LineInc = 0; - - if (iFgets((char *)LineBuffer, MAX_BUFFER) == NULL) { - //ilSetError(IL_ILLEGAL_FILE_VALUE); - //return NULL; - //return iCurImage; - break; - } - if (LineBuffer[0] == '#') { // Comment - continue; - } - - while ((LineBuffer[LineInc] != NUL) && (LineBuffer[LineInc] != '\n')) { - - SmallInc = 0; - while (!isalnum(LineBuffer[LineInc])) { // Skip any whitespace - LineInc++; - } - while (isalnum(LineBuffer[LineInc])) { - SmallBuff[SmallInc] = LineBuffer[LineInc]; - SmallInc++; - LineInc++; - } - SmallBuff[SmallInc] = NUL; - iCurImage->Data[DataInc] = atoi((const char*)SmallBuff); // Convert from string to colour - - // PSP likes to put whitespace at the end of lines...figures. =/ - while (!isalnum(LineBuffer[LineInc]) && LineBuffer[LineInc] != NUL) { // Skip any whitespace - LineInc++; - } - - // We should set some kind of state flag that enables this - //Image->Data[DataInc] *= (ILubyte)(255 / Info->MaxColour); // Scales to 0-255 - if (Info->MaxColour > 255) - DataInc++; - DataInc++; - } - } - - // If we read less than what we should have... - if (DataInc < Size) { - //ilCloseImage(iCurImage); - //ilSetCurImage(NULL); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return NULL; - } - - return iCurImage; -} - - -ILimage *ilReadBinaryPpm(PPMINFO *Info) -{ - ILuint Size; - - Size = Info->Width * Info->Height * Info->Bpp; - - if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - /* 4/3/2007 Dario Meloni - Here it seems we have eaten too much bytes and it is needed to fix - the starting point - works well on various images - - No more need of this workaround. fixed iGetWord - iseek(0,IL_SEEK_END); - ILuint size = itell(); - iseek(size-Size,IL_SEEK_SET); - */ - if (iread(iCurImage->Data, 1, Size ) != Size) { - ilCloseImage(iCurImage); - return NULL; - } - return iCurImage; -} - - -ILimage *ilReadBitPbm(PPMINFO *Info) -{ - ILuint m, j, x, CurrByte; - - if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - x = 0; - for (j = 0; j < iCurImage->SizeOfData;) { - CurrByte = igetc(); - for (m = 128; m > 0 && x < Info->Width; m >>= 1, ++x, ++j) { - iCurImage->Data[j] = (CurrByte & m)?255:0; - } - if (x == Info->Width) - x = 0; - } - - return iCurImage; -} - - -ILboolean iGetWord(ILboolean final) -{ - ILint WordPos = 0; - ILint Current = 0; - ILboolean Started = IL_FALSE; - ILboolean Looping = IL_TRUE; - - if (ieof()) - return IL_FALSE; - - while (Looping) { - Current = igetc(); - while (Current != IL_EOF && Current != '\n' && Current != '#' && Current != ' ') { - if (Current == IL_EOF) - return IL_FALSE; - if (!isalnum(Current)) { - if (Started) { - Looping = IL_FALSE; - break; - } - continue; - } - - if (Looping) - SmallBuff[WordPos++] = Current; - if (final == IL_TRUE) - break; - } - SmallBuff[WordPos] = 0; // 08-17-2008 - was NULL, changed to avoid warning - - if (!Looping) - break; - - if (Current == '#') { // '#' is a comment...read until end of line - while ((Current = igetc()) != IL_EOF && Current != '\n'); - } - - // Get rid of any erroneous spaces - while ((Current = igetc()) != IL_EOF) { - if (Current != ' ') - break; - } - iseek(-1, IL_SEEK_CUR); - - if (WordPos > 0) - break; - } - - if (Current == -1 || WordPos == 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - return IL_TRUE; -} - - -ILstring FName; - -//! Writes a Pnm file -ILboolean ilSavePnm(ILconst_string FileName) -{ - ILHANDLE PnmFile; - ILboolean bPnm = IL_FALSE; - - FName = (ILstring)FileName; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - PnmFile = iopenw(FileName); - if (PnmFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPnm; - } - - bPnm = ilSavePnmF(PnmFile); - iclosew(PnmFile); - - return bPnm; -} - - -//! Writes a Pnm to an already-opened file -ILboolean ilSavePnmF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSavePnmInternal(); -} - - -//! Writes a Pnm to a memory "lump" -ILboolean ilSavePnmL(ILvoid *Lump, ILuint Size) -{ - FName = NULL; - iSetOutputLump(Lump, Size); - return iSavePnmInternal(); -} - - -// Internal function used to save the Pnm. -ILboolean iSavePnmInternal() -{ - ILuint Bpp, MaxVal = UCHAR_MAX, i = 0, j, k; - ILenum Type = 0; - ILuint LinePos = 0; // Cannot exceed 70 for pnm's! - ILboolean Binary; - ILimage *TempImage; - ILubyte *TempData; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iCheckExtension(FName, IL_TEXT("pbm"))) - Type = IL_PBM_ASCII; - else if (iCheckExtension(FName, IL_TEXT("pgm"))) - Type = IL_PGM_ASCII; - else if (iCheckExtension(FName, IL_TEXT("ppm"))) - Type = IL_PPM_ASCII; - else - Type = IL_PPM_ASCII; - - /*if (!Type) { - ilSetError(IL_INVALID_EXTENSION); - return IL_FALSE; - }*/ - - if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) { - Type += 3; - Binary = IL_TRUE; - } - else { - Binary = IL_FALSE; - } - - if (iCurImage->Type == IL_UNSIGNED_BYTE) { - MaxVal = UCHAR_MAX; - } - else if (iCurImage->Type == IL_UNSIGNED_SHORT) { - MaxVal = USHRT_MAX; - } - else { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - if (MaxVal > UCHAR_MAX && Type >= IL_PBM_BINARY) { // binary cannot be higher than 255 - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - - switch (Type) - { - case IL_PBM_ASCII: - Bpp = 1; - ilprintf("P1\n"); - TempImage = iConvertImage(iCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE); - break; - //case IL_PBM_BINARY: // Don't want to mess with saving bits just yet... - //Bpp = 1; - //ilprintf("P4\n"); - //break; - case IL_PBM_BINARY: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - case IL_PGM_ASCII: - Bpp = 1; - ilprintf("P2\n"); - TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); - break; - case IL_PGM_BINARY: - Bpp = 1; - ilprintf("P5\n"); - TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); - break; - case IL_PPM_ASCII: - Bpp = 3; - ilprintf("P3\n"); - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - break; - case IL_PPM_BINARY: - Bpp = 3; - ilprintf("P6\n"); - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - break; - default: - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - if (TempImage == NULL) - return IL_FALSE; - - if (Bpp != TempImage->Bpp) { - ilSetError(IL_INVALID_CONVERSION); - return IL_FALSE; - } - - if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) { - TempData = iGetFlipped(TempImage); - if (TempData == NULL) { - ilCloseImage(TempImage); - return IL_FALSE; - } - } - else { - TempData = TempImage->Data; - } - - ilprintf("%d %d\n", TempImage->Width, TempImage->Height); - if (Type != IL_PBM_BINARY && Type != IL_PBM_ASCII) // not needed for .pbm's (only 0 and 1) - ilprintf("%d\n", MaxVal); - - while (i < TempImage->SizeOfPlane) { - for (j = 0; j < Bpp; j++) { - if (Binary) { - if (Type == IL_PBM_BINARY) { - iputc((ILubyte)(TempData[i] > 127 ? 1 : 0)); - } - else { - iputc(TempData[i]); - } - } - else { - if (TempImage->Type == IL_UNSIGNED_BYTE) - k = TempData[i]; - else // IL_UNSIGNED_SHORT - k = *((ILushort*)TempData + i); - if (Type == IL_PBM_ASCII) { - LinePos += ilprintf("%d ", TempData[i] > 127 ? 1 : 0); - } - else { - LinePos += ilprintf("%d ", TempData[i]); - } - } - - if (TempImage->Type == IL_UNSIGNED_SHORT) - i++; - i++; - } - - if (LinePos > 65) { // Just a good number =] - ilprintf("\n"); - LinePos = 0; - } - } - - if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) - ifree(TempData); - ilCloseImage(TempImage); - - return IL_TRUE; -} - - -// Converts a .pbm to something viewable. -ILvoid PbmMaximize(ILimage *Image) -{ - ILuint i = 0; - for (i = 0; i < Image->SizeOfPlane; i++) - if (Image->Data[i] == 1) - Image->Data[i] = 0xFF; - return; -} - - -#endif//IL_NO_PNM diff --git a/win32/devil/src/il_profiles.c b/win32/devil/src/il_profiles.c deleted file mode 100644 index 2dff482ec..000000000 --- a/win32/devil/src/il_profiles.c +++ /dev/null @@ -1,169 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 01/23/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_profiles.c -// -// Description: Colour profile handler -// -//----------------------------------------------------------------------------- - -#include "il_internal.h" -#ifndef IL_NO_LCMS - -#ifdef PACKAGE_NAME -#define IL_PACKAGE_NAME PACKAGE_NAME; -#undef PACKAGE_NAME -#endif - -#ifndef _WIN32 - #define NON_WINDOWS 1 - #ifndef LCMS_NODIRINCLUDE - #include - #else - #include - #endif - -#else -// #ifndef IL_DEBUG -// pragma comment(lib, "lcms108.lib") -// #else -// pragma comment(lib, "debug/lcms108.lib") -// #endif - #include -#endif//_WIN32 - -#ifdef PACKAGE_NAME -#undef PACKAGE_NAME -#endif - -#ifdef IL_PACKAGE_NAME -#define PACKAGE_NAME IL_PACKAGE_NAME -#undef IL_PACKAGE_NAME -#endif - -#endif//IL_NO_LCMS - -ILboolean ILAPIENTRY ilApplyProfile(ILstring InProfile, ILstring OutProfile) -{ -#ifndef IL_NO_LCMS - cmsHPROFILE hInProfile, hOutProfile; - cmsHTRANSFORM hTransform; - ILubyte *Temp; - ILint Format=0; -#ifdef _UNICODE - char AnsiName[512]; -#endif//_UNICODE - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - switch (iCurImage->Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - switch (iCurImage->Format) - { - case IL_LUMINANCE: - Format = TYPE_GRAY_8; - break; - case IL_RGB: - Format = TYPE_RGB_8; - break; - case IL_BGR: - Format = TYPE_BGR_8; - break; - case IL_RGBA: - Format = TYPE_RGBA_8; - break; - case IL_BGRA: - Format = TYPE_BGRA_8; - break; - default: - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - break; - - case IL_SHORT: - case IL_UNSIGNED_SHORT: - switch (iCurImage->Format) - { - case IL_LUMINANCE: - Format = TYPE_GRAY_16; - break; - case IL_RGB: - Format = TYPE_RGB_16; - break; - case IL_BGR: - Format = TYPE_BGR_16; - break; - case IL_RGBA: - Format = TYPE_RGBA_16; - break; - case IL_BGRA: - Format = TYPE_BGRA_16; - break; - default: - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - break; - - // These aren't supported right now. - case IL_INT: - case IL_UNSIGNED_INT: - case IL_FLOAT: - case IL_DOUBLE: - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - - if (InProfile == NULL) { - if (!iCurImage->Profile || !iCurImage->ProfileSize) { - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - hInProfile = iCurImage->Profile; - } - else { -#ifndef _UNICODE - hInProfile = cmsOpenProfileFromFile(InProfile, "r"); -#else - wcstombs(AnsiName, InProfile, 512); - hInProfile = cmsOpenProfileFromFile(AnsiName, "r"); -#endif//_UNICODE - } -#ifndef _UNICODE - hOutProfile = cmsOpenProfileFromFile(OutProfile, "r"); -#else - wcstombs(AnsiName, OutProfile, 512); - hOutProfile = cmsOpenProfileFromFile(AnsiName, "r"); -#endif//_UNICODE - - hTransform = cmsCreateTransform(hInProfile, Format, hOutProfile, Format, INTENT_PERCEPTUAL, 0); - - Temp = (ILubyte*)ialloc(iCurImage->SizeOfData); - if (Temp == NULL) { - return IL_FALSE; - } - - cmsDoTransform(hTransform, iCurImage->Data, Temp, iCurImage->SizeOfData / 3); - - ifree(iCurImage->Data); - iCurImage->Data = Temp; - - cmsDeleteTransform(hTransform); - if (InProfile != NULL) - cmsCloseProfile(hInProfile); - cmsCloseProfile(hOutProfile); - -#endif//IL_NO_LCMS - - return IL_TRUE; -} diff --git a/win32/devil/src/il_psd.c b/win32/devil/src/il_psd.c deleted file mode 100644 index c5bf89c8e..000000000 --- a/win32/devil/src/il_psd.c +++ /dev/null @@ -1,935 +0,0 @@ - -// Information about the .psd format was taken from Adobe's PhotoShop SDK at -// http://partners.adobe.com/asn/developer/gapsdk/PhotoshopSDK.html -// Information about the Packbits compression scheme was found at -// http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf - -#include "il_internal.h" -#ifndef IL_NO_PSD -#include "il_psd.h" - - -//! Checks if the file specified in FileName is a valid Psd file. -ILboolean ilIsValidPsd(ILconst_string FileName) -{ - ILHANDLE PsdFile; - ILboolean bPsd = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("psd")) && - !iCheckExtension(FileName, IL_TEXT("pdd"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPsd; - } - - PsdFile = iopenr(FileName); - if (PsdFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPsd; - } - - bPsd = ilIsValidPsdF(PsdFile); - icloser(PsdFile); - - return bPsd; -} - - -//! Checks if the ILHANDLE contains a valid Psd file at the current position. -ILboolean ilIsValidPsdF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPsd(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid Psd lump. -ILboolean ilIsValidPsdL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidPsd(); -} - - -// Internal function used to get the Psd header from the current file. -ILboolean iGetPsdHead(PSDHEAD *Header) -{ - iread(Header->Signature, 1, 4); - Header->Version = GetBigUShort(); - iread(Header->Reserved, 1, 6); - Header->Channels = GetBigUShort(); - Header->Height = GetBigUInt(); - Header->Width = GetBigUInt(); - Header->Depth = GetBigUShort(); - Header->Mode = GetBigUShort(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPsd() -{ - PSDHEAD Head; - - iGetPsdHead(&Head); - iseek(-(ILint)sizeof(PSDHEAD), IL_SEEK_CUR); - - return iCheckPsd(&Head); -} - - -// Internal function used to check if the HEADER is a valid Psd header. -ILboolean iCheckPsd(PSDHEAD *Header) -{ - ILuint i; - - if (strncmp((char*)Header->Signature, "8BPS", 4)) - return IL_FALSE; - if (Header->Version != 1) - return IL_FALSE; - for (i = 0; i < 6; i++) { - if (Header->Reserved[i] != 0) - return IL_FALSE; - } - if (Header->Channels < 1 || Header->Channels > 24) - return IL_FALSE; - if (Header->Height < 1 || Header->Width < 1) - return IL_FALSE; - if (Header->Depth != 1 && Header->Depth != 8 && Header->Depth != 16) - return IL_FALSE; - - return IL_TRUE; -} - - -//! Reads a Psd file -ILboolean ilLoadPsd(ILconst_string FileName) -{ - ILHANDLE PsdFile; - ILboolean bPsd = IL_FALSE; - - PsdFile = iopenr(FileName); - if (PsdFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPsd; - } - - bPsd = ilLoadPsdF(PsdFile); - icloser(PsdFile); - - return bPsd; -} - - -//! Reads an already-opened Psd file -ILboolean ilLoadPsdF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPsdInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Psd -ILboolean ilLoadPsdL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPsdInternal(); -} - - -// Internal function used to load the Psd. -ILboolean iLoadPsdInternal() -{ - PSDHEAD Header; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iGetPsdHead(&Header); - if (!iCheckPsd(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ReadPsd(&Header)) - return IL_FALSE; - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - ilFixImage(); - - return IL_TRUE; -} - - -ILboolean ReadPsd(PSDHEAD *Head) -{ - switch (Head->Mode) - { - case 1: // Greyscale - return ReadGrey(Head); - case 2: // Indexed - return ReadIndexed(Head); - case 3: // RGB - return ReadRGB(Head); - case 4: // CMYK - return ReadCMYK(Head); - } - - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; -} - - -ILboolean ReadGrey(PSDHEAD *Head) -{ - ILuint ColorMode, ResourceSize, MiscInfo; - ILushort Compressed; - ILenum Type; - ILubyte *Resources = NULL; - - ColorMode = GetBigUInt(); // Skip over the 'color mode data section' - iseek(ColorMode, IL_SEEK_CUR); - - ResourceSize = GetBigUInt(); // Read the 'image resources section' - Resources = (ILubyte*)ialloc(ResourceSize); - if (Resources == NULL) { - return IL_FALSE; - } - if (iread(Resources, 1, ResourceSize) != ResourceSize) - goto cleanup_error; - - MiscInfo = GetBigUInt(); - iseek(MiscInfo, IL_SEEK_CUR); - - Compressed = GetBigUShort(); - - ChannelNum = Head->Channels; - Head->Channels = 1; // Temporary to read only one channel...some greyscale .psd files have 2. - if (Head->Channels != 1) { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - switch (Head->Depth) - { - case 8: - Type = IL_UNSIGNED_BYTE; - break; - case 16: - Type = IL_UNSIGNED_SHORT; - break; - default: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - - if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_LUMINANCE, Type, NULL)) - goto cleanup_error; - if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) - goto cleanup_error; - if (!ParseResources(ResourceSize, Resources)) - goto cleanup_error; - ifree(Resources); - - return IL_TRUE; - -cleanup_error: - ifree(Resources); - return IL_FALSE; -} - - -ILboolean ReadIndexed(PSDHEAD *Head) -{ - ILuint ColorMode, ResourceSize, MiscInfo, i, j, NumEnt; - ILushort Compressed; - ILubyte *Palette = NULL, *Resources = NULL; - - ColorMode = GetBigUInt(); // Skip over the 'color mode data section' - if (ColorMode % 3 != 0) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - Palette = (ILubyte*)ialloc(ColorMode); - if (Palette == NULL) - return IL_FALSE; - if (iread(Palette, 1, ColorMode) != ColorMode) - goto cleanup_error; - - ResourceSize = GetBigUInt(); // Read the 'image resources section' - Resources = (ILubyte*)ialloc(ResourceSize); - if (Resources == NULL) { - return IL_FALSE; - } - if (iread(Resources, 1, ResourceSize) != ResourceSize) - goto cleanup_error; - - MiscInfo = GetBigUInt(); - if (ieof()) - goto cleanup_error; - iseek(MiscInfo, IL_SEEK_CUR); - - Compressed = GetBigUShort(); - if (ieof()) - goto cleanup_error; - - if (Head->Channels != 1 || Head->Depth != 8) { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - goto cleanup_error; - } - ChannelNum = Head->Channels; - - if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) - goto cleanup_error; - - iCurImage->Pal.Palette = (ILubyte*)ialloc(ColorMode); - if (iCurImage->Pal.Palette == NULL) { - goto cleanup_error; - } - iCurImage->Pal.PalSize = ColorMode; - iCurImage->Pal.PalType = IL_PAL_RGB24; - - NumEnt = iCurImage->Pal.PalSize / 3; - for (i = 0, j = 0; i < iCurImage->Pal.PalSize; i += 3, j++) { - iCurImage->Pal.Palette[i ] = Palette[j]; - iCurImage->Pal.Palette[i+1] = Palette[j+NumEnt]; - iCurImage->Pal.Palette[i+2] = Palette[j+NumEnt*2]; - } - ifree(Palette); - Palette = NULL; - - if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) - goto cleanup_error; - - ParseResources(ResourceSize, Resources); - ifree(Resources); - Resources = NULL; - - return IL_TRUE; - -cleanup_error: - ifree(Palette); - ifree(Resources); - - return IL_FALSE; -} - - -ILboolean ReadRGB(PSDHEAD *Head) -{ - ILuint ColorMode, ResourceSize, MiscInfo; - ILushort Compressed; - ILenum Format, Type; - ILubyte *Resources = NULL; - - ColorMode = GetBigUInt(); // Skip over the 'color mode data section' - iseek(ColorMode, IL_SEEK_CUR); - - ResourceSize = GetBigUInt(); // Read the 'image resources section' - Resources = (ILubyte*)ialloc(ResourceSize); - if (Resources == NULL) - return IL_FALSE; - if (iread(Resources, 1, ResourceSize) != ResourceSize) - goto cleanup_error; - - MiscInfo = GetBigUInt(); - iseek(MiscInfo, IL_SEEK_CUR); - - Compressed = GetBigUShort(); - - ChannelNum = Head->Channels; - switch (Head->Channels) - { - case 3: - Format = IL_RGB; - break; - case 4: - Format = IL_RGBA; - break; - default: - // ilSetError(IL_FORMAT_NOT_SUPPORTED); - // return IL_FALSE; - //drop additional channels. This is not the 100% correct - //way of loading the image, but it is better than loading - //the image not at all. - Format = IL_RGBA; - Head->Channels = 4; - } - switch (Head->Depth) - { - case 8: - Type = IL_UNSIGNED_BYTE; - break; - case 16: - Type = IL_UNSIGNED_SHORT; - break; - default: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL)) - goto cleanup_error; - if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) - goto cleanup_error; - if (!ParseResources(ResourceSize, Resources)) - goto cleanup_error; - ifree(Resources); - - return IL_TRUE; - -cleanup_error: - ifree(Resources); - return IL_FALSE; -} - - -ILboolean ReadCMYK(PSDHEAD *Head) -{ - ILuint ColorMode, ResourceSize, MiscInfo, Size, i, j; - ILushort Compressed; - ILenum Format, Type; - ILubyte *Resources = NULL, *KChannel = NULL; - - ColorMode = GetBigUInt(); // Skip over the 'color mode data section' - iseek(ColorMode, IL_SEEK_CUR); - - ResourceSize = GetBigUInt(); // Read the 'image resources section' - Resources = (ILubyte*)ialloc(ResourceSize); - if (Resources == NULL) { - return IL_FALSE; - } - if (iread(Resources, 1, ResourceSize) != ResourceSize) - goto cleanup_error; - - MiscInfo = GetBigUInt(); - iseek(MiscInfo, IL_SEEK_CUR); - - Compressed = GetBigUShort(); - - switch (Head->Channels) - { - case 4: - Format = IL_RGB; - ChannelNum = 4; - Head->Channels = 3; - break; - case 5: - Format = IL_RGBA; - ChannelNum = 5; - Head->Channels = 4; - break; - default: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - switch (Head->Depth) - { - case 8: - Type = IL_UNSIGNED_BYTE; - break; - case 16: - Type = IL_UNSIGNED_SHORT; - break; - default: - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL)) - goto cleanup_error; - if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) - goto cleanup_error; - - Size = iCurImage->Bpc * iCurImage->Width * iCurImage->Height; - KChannel = (ILubyte*)ialloc(Size); - if (KChannel == NULL) - goto cleanup_error; - if (!GetSingleChannel(Head, KChannel, (ILboolean)Compressed)) - goto cleanup_error; - - if (Format == IL_RGB) { - for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 3, j++) { - iCurImage->Data[i ] = (iCurImage->Data[i ] * KChannel[j]) >> 8; - iCurImage->Data[i+1] = (iCurImage->Data[i+1] * KChannel[j]) >> 8; - iCurImage->Data[i+2] = (iCurImage->Data[i+2] * KChannel[j]) >> 8; - } - } - else { // IL_RGBA - // The KChannel array really holds the alpha channel on this one. - for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 4, j++) { - iCurImage->Data[i ] = (iCurImage->Data[i ] * iCurImage->Data[i+3]) >> 8; - iCurImage->Data[i+1] = (iCurImage->Data[i+1] * iCurImage->Data[i+3]) >> 8; - iCurImage->Data[i+2] = (iCurImage->Data[i+2] * iCurImage->Data[i+3]) >> 8; - iCurImage->Data[i+3] = KChannel[j]; // Swap 'K' with alpha channel. - } - } - - if (!ParseResources(ResourceSize, Resources)) - goto cleanup_error; - - ifree(Resources); - ifree(KChannel); - - return IL_TRUE; - -cleanup_error: - ifree(Resources); - ifree(KChannel); - return IL_FALSE; -} - - -ILuint *GetCompChanLen(PSDHEAD *Head) -{ - ILushort *RleTable; - ILuint *ChanLen, c, i, j; - - RleTable = (ILushort*)ialloc(Head->Height * ChannelNum * sizeof(ILushort)); - ChanLen = (ILuint*)ialloc(ChannelNum * sizeof(ILuint)); - if (RleTable == NULL || ChanLen == NULL) { - return NULL; - } - - if (iread(RleTable, sizeof(ILushort), Head->Height * ChannelNum) != Head->Height * ChannelNum) { - ifree(RleTable); - ifree(ChanLen); - return NULL; - } -#ifdef __LITTLE_ENDIAN__ - for (i = 0; i < Head->Height * ChannelNum; i++) { - iSwapUShort(&RleTable[i]); - } -#endif - - imemclear(ChanLen, ChannelNum * sizeof(ILuint)); - for (c = 0; c < ChannelNum; c++) { - j = c * Head->Height; - for (i = 0; i < Head->Height; i++) { - ChanLen[c] += RleTable[i + j]; - } - } - - ifree(RleTable); - - return ChanLen; -} - - -ILboolean PsdGetData(PSDHEAD *Head, ILvoid *Buffer, ILboolean Compressed) -{ - ILuint c, x, y, i, Size; - ILubyte *Channel = NULL; - ILushort *ShortPtr; - ILbyte HeadByte; - ILint Run; - ILuint *ChanLen = NULL; - ILboolean PreCache = IL_FALSE; - - Channel = (ILubyte*)ialloc(Head->Width * Head->Height * iCurImage->Bpc); - if (Channel == NULL) { - return IL_FALSE; - } - ShortPtr = (ILushort*)Channel; - - // @TODO: Add support for this in, though I have yet to run across a .psd - // file that uses this. - if (Compressed && iCurImage->Type == IL_UNSIGNED_SHORT) { - ilSetError(IL_FORMAT_NOT_SUPPORTED); - return IL_FALSE; - } - - if (!Compressed) { - if (iCurImage->Bpc == 1) { - for (c = 0; c < Head->Channels; c++) { - i = 0; - if (iread(Channel, Head->Width * Head->Height, 1) != 1) { - ifree(Channel); - return IL_FALSE; - } - for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) { - for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) { - iCurImage->Data[y + x + c] = Channel[i]; - } - } - } - } - else { // iCurImage->Bpc == 2 - for (c = 0; c < Head->Channels; c++) { - i = 0; - if (iread(Channel, Head->Width * Head->Height * 2, 1) != 1) { - ifree(Channel); - return IL_FALSE; - } - iCurImage->Bps /= 2; - for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) { - for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) { - #ifndef WORDS_BIGENDIAN - iSwapUShort(ShortPtr+i); - #endif - ((ILushort*)iCurImage->Data)[y + x + c] = ShortPtr[i]; - } - } - iCurImage->Bps *= 2; - } - } - } - else { - ChanLen = GetCompChanLen(Head); - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - PreCache = IL_TRUE; - - Size = Head->Width * Head->Height; - for (c = 0; c < Head->Channels; c++) { - if (PreCache) - iPreCache(ChanLen[c]); - for (i = 0; i < Size; ) { - HeadByte = igetc(); - - if (HeadByte >= 0) { // && HeadByte <= 127 - if (i + HeadByte > Size) - goto file_corrupt; - if (iread(Channel + i, HeadByte + 1, 1) != 1) - goto file_read_error; - - i += HeadByte + 1; - } - if (HeadByte >= -127 && HeadByte <= -1) { - Run = igetc(); - if (Run == IL_EOF) - goto file_read_error; - if (i + (-HeadByte + 1) > Size) - goto file_corrupt; - - memset(Channel + i, Run, -HeadByte + 1); - i += -HeadByte + 1; - } - if (HeadByte == -128) - { } // Noop - } - if (PreCache) - iUnCache(); - - i = 0; - for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) { - for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) { - iCurImage->Data[y + x + c] = Channel[i]; - } - } - } - - ifree(ChanLen); - } - - ifree(Channel); - - return IL_TRUE; - -file_corrupt: - ifree(ChanLen); - ifree(Channel); - if (PreCache) - iUnCache(); - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - -file_read_error: - ifree(ChanLen); - ifree(Channel); - if (PreCache) - iUnCache(); - return IL_FALSE; -} - - -ILboolean ParseResources(ILuint ResourceSize, ILubyte *Resources) -{ - ILushort ID; - ILubyte NameLen; - ILuint Size; - - if (Resources == NULL) { - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - while (ResourceSize) { - if (strncmp("8BIM", (const char*)Resources, 4)) { - //return IL_FALSE; - return IL_TRUE; // 05-30-2002: May not necessarily mean corrupt data... - } - Resources += 4; - - ID = *((ILushort*)Resources); - BigUShort(&ID); - Resources += 2; - - NameLen = *Resources++; - // NameLen + the byte it occupies must be padded to an even number, so NameLen must be odd. - NameLen = NameLen + (NameLen & 1 ? 0 : 1); - Resources += NameLen; - - // Get the resource data size. - Size = *((ILuint*)Resources); - BigUInt(&Size); - Resources += 4; - - ResourceSize -= (4 + 2 + 1 + NameLen); - - switch (ID) - { - case 0x040F: // ICC Profile - iCurImage->Profile = (ILubyte*)ialloc(Size); - if (iCurImage->Profile == NULL) { - return IL_FALSE; - } - memcpy(iCurImage->Profile, Resources, Size); - iCurImage->ProfileSize = Size; - break; - - default: - break; - } - - if (Size & 1) // Must be an even number. - Size++; - ResourceSize -= Size; - Resources += Size; - } - - return IL_TRUE; -} - - -ILboolean GetSingleChannel(PSDHEAD *Head, ILubyte *Buffer, ILboolean Compressed) -{ - ILuint i; - ILushort *ShortPtr; - ILbyte HeadByte; - ILint Run; - - ShortPtr = (ILushort*)Buffer; - - if (!Compressed) { - if (iCurImage->Bpc == 1) { - if (iread(Buffer, Head->Width * Head->Height, 1) != 1) - return IL_FALSE; - } - else { // iCurImage->Bpc == 2 - if (iread(Buffer, Head->Width * Head->Height * 2, 1) != 1) - return IL_FALSE; - } - } - else { - for (i = 0; i < Head->Width * Head->Height; ) { - HeadByte = igetc(); - - if (HeadByte >= 0) { // && HeadByte <= 127 - if (iread(Buffer + i, HeadByte + 1, 1) != 1) - return IL_FALSE; - i += HeadByte + 1; - } - if (HeadByte >= -127 && HeadByte <= -1) { - Run = igetc(); - if (Run == IL_EOF) - return IL_FALSE; - memset(Buffer + i, Run, -HeadByte + 1); - i += -HeadByte + 1; - } - if (HeadByte == -128) - { } // Noop - } - } - - return IL_TRUE; -} - - - -//! Writes a Psd file -ILboolean ilSavePsd(ILconst_string FileName) -{ - ILHANDLE PsdFile; - ILboolean bPsd = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - PsdFile = iopenw(FileName); - if (PsdFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPsd; - } - - bPsd = ilSavePsdF(PsdFile); - iclosew(PsdFile); - - return bPsd; -} - - -//! Writes a Psd to an already-opened file -ILboolean ilSavePsdF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSavePsdInternal(); -} - - -//! Writes a Psd to a memory "lump" -ILboolean ilSavePsdL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSavePsdInternal(); -} - - -// Internal function used to save the Psd. -ILboolean iSavePsdInternal() -{ - ILubyte *Signature = (ILubyte*)"8BPS"; - ILimage *TempImage; - ILpal *TempPal; - ILuint c, i; - ILubyte *TempData; - ILushort *ShortPtr; - ILenum Format, Type; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Format = iCurImage->Format; - Type = iCurImage->Type; - - // All of these comprise the actual signature. - iwrite(Signature, 1, 4); - SaveBigShort(1); - SaveBigInt(0); - SaveBigShort(0); - - SaveBigShort(iCurImage->Bpp); - SaveBigInt(iCurImage->Height); - SaveBigInt(iCurImage->Width); - if (iCurImage->Bpc > 2) - Type = IL_UNSIGNED_SHORT; - - if (iCurImage->Format == IL_BGR) - Format = IL_RGB; - else if (iCurImage->Format == IL_BGRA) - Format = IL_RGBA; - - if (Format != iCurImage->Format || Type != iCurImage->Type) { - TempImage = iConvertImage(iCurImage, Format, Type); - if (TempImage == NULL) - return IL_FALSE; - } - else { - TempImage = iCurImage; - } - SaveBigShort((ILushort)(TempImage->Bpc * 8)); - - // @TODO: Put the other formats here. - switch (TempImage->Format) - { - case IL_COLOUR_INDEX: - SaveBigShort(2); - break; - case IL_LUMINANCE: - SaveBigShort(1); - break; - case IL_RGB: - case IL_RGBA: - SaveBigShort(3); - break; - default: - ilSetError(IL_INTERNAL_ERROR); - return IL_FALSE; - } - - if (TempImage->Format == IL_COLOUR_INDEX) { - // @TODO: We're currently making a potentially fatal assumption that - // iConvertImage was not called if the format is IL_COLOUR_INDEX. - TempPal = iConvertPal(&TempImage->Pal, IL_PAL_RGB24); - if (TempPal == NULL) - return IL_FALSE; - SaveBigInt(768); - - // Have to save the palette in a planar format. - for (c = 0; c < 3; c++) { - for (i = c; i < TempPal->PalSize; i += 3) { - iputc(TempPal->Palette[i]); - } - } - - ifree(TempPal->Palette); - } - else { - SaveBigInt(0); // No colour mode data. - } - - SaveBigInt(0); // No image resources. - SaveBigInt(0); // No layer information. - SaveBigShort(0); // Raw data, no compression. - - // @TODO: Add RLE compression. - - if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { - TempData = iGetFlipped(TempImage); - if (TempData == NULL) { - ilCloseImage(TempImage); - return IL_FALSE; - } - } - else { - TempData = TempImage->Data; - } - - if (TempImage->Bpc == 1) { - for (c = 0; c < TempImage->Bpp; c++) { - for (i = c; i < TempImage->SizeOfPlane; i += TempImage->Bpp) { - iputc(TempData[i]); - } - } - } - else { // TempImage->Bpc == 2 - ShortPtr = (ILushort*)TempData; - TempImage->SizeOfPlane /= 2; - for (c = 0; c < TempImage->Bpp; c++) { - for (i = c; i < TempImage->SizeOfPlane; i += TempImage->Bpp) { - SaveBigUShort(ShortPtr[i]); - } - } - TempImage->SizeOfPlane *= 2; - } - - if (TempData != TempImage->Data) - ifree(TempData); - - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - - return IL_TRUE; -} - - -#endif//IL_NO_PSD diff --git a/win32/devil/src/il_psp.c b/win32/devil/src/il_psp.c deleted file mode 100644 index 7decd8c05..000000000 --- a/win32/devil/src/il_psp.c +++ /dev/null @@ -1,714 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/04/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_psp.c -// -// Description: Reads a Paint Shop Pro file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_psp.h" -#ifndef IL_NO_PSP - - -ILubyte PSPSignature[32] = { - 0x50, 0x61, 0x69, 0x6E, 0x74, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x49, - 0x6D, 0x61, 0x67, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -ILubyte GenAttHead[4] = { - 0x7E, 0x42, 0x4B, 0x00 -}; - - -// Make these global, since they contain most of the image information. -GENATT_CHUNK AttChunk; -PSPHEAD Header; -ILuint NumChannels; -ILubyte **Channels = NULL; -ILubyte *Alpha = NULL; -ILpal Pal; - - - -//! Checks if the file specified in FileName is a valid Psp file. -ILboolean ilIsValidPsp(ILconst_string FileName) -{ - ILHANDLE PspFile; - ILboolean bPsp = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("psp"))) { - ilSetError(IL_INVALID_EXTENSION); - return bPsp; - } - - PspFile = iopenr(FileName); - if (PspFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPsp; - } - - bPsp = ilIsValidPspF(PspFile); - icloser(PspFile); - - return bPsp; -} - - -//! Checks if the ILHANDLE contains a valid Psp file at the current position. -ILboolean ilIsValidPspF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidPsp(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid Psp lump. -ILboolean ilIsValidPspL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidPsp(); -} - - -// Internal function used to get the Psp header from the current file. -ILboolean iGetPspHead() -{ - if (iread(Header.FileSig, 1, 32) != 32) - return IL_FALSE; - Header.MajorVersion = GetLittleUShort(); - Header.MinorVersion = GetLittleUShort(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidPsp() -{ - if (!iGetPspHead()) - return IL_FALSE; - iseek(-(ILint)sizeof(PSPHEAD), IL_SEEK_CUR); - - return iCheckPsp(); -} - - -// Internal function used to check if the HEADER is a valid Psp header. -ILboolean iCheckPsp() -{ - if (stricmp(Header.FileSig, "Paint Shop Pro Image File\n\x1a")) - return IL_FALSE; - if (Header.MajorVersion < 3 || Header.MajorVersion > 5) - return IL_FALSE; - if (Header.MinorVersion != 0) - return IL_FALSE; - - - return IL_TRUE; -} - - -//! Reads a PSP file -ILboolean ilLoadPsp(ILconst_string FileName) -{ - ILHANDLE PSPFile; - ILboolean bPsp = IL_FALSE; - - PSPFile = iopenr(FileName); - if (PSPFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPsp; - } - - bPsp = ilLoadPspF(PSPFile); - icloser(PSPFile); - - return bPsp; -} - - -//! Reads an already-opened PSP file -ILboolean ilLoadPspF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPspInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a PSP -ILboolean ilLoadPspL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPspInternal(); -} - - -// Internal function used to load the PSP. -ILboolean iLoadPspInternal() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - Channels = NULL; - Alpha = NULL; - Pal.Palette = NULL; - - if (!iGetPspHead()) - return IL_FALSE; - if (!iCheckPsp()) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (!ReadGenAttributes()) - return IL_FALSE; - if (!ParseChunks()) - return IL_FALSE; - if (!AssembleImage()) - return IL_FALSE; - - Cleanup(); - ilFixImage(); - - return IL_TRUE; -} - - -ILboolean ReadGenAttributes() -{ - BLOCKHEAD AttHead; - ILint Padding; - ILuint ChunkLen; - - if (iread(&AttHead, sizeof(AttHead), 1) != 1) - return IL_FALSE; - UShort(&AttHead.BlockID); - UInt(&AttHead.BlockLen); - - if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 || - AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - if (AttHead.BlockID != PSP_IMAGE_BLOCK) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - ChunkLen = GetLittleUInt(); - if (Header.MajorVersion != 3) - ChunkLen -= 4; - if (iread(&AttChunk, IL_MIN(sizeof(AttChunk), ChunkLen), 1) != 1) - return IL_FALSE; - - // Can have new entries in newer versions of the spec (4.0). - Padding = (ChunkLen) - sizeof(AttChunk); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - - // @TODO: Anything but 24 not supported yet... - if (AttChunk.BitDepth != 24 && AttChunk.BitDepth != 8) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // @TODO; Add support for compression... - if (AttChunk.Compression != PSP_COMP_NONE && AttChunk.Compression != PSP_COMP_RLE) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - // @TODO: Check more things in the general attributes chunk here. - - return IL_TRUE; -} - - -ILboolean ParseChunks() -{ - BLOCKHEAD Block; - ILuint Pos; - - do { - if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) { - ilGetError(); // Get rid of the erroneous IL_FILE_READ_ERROR. - return IL_TRUE; - } - if (Header.MajorVersion == 3) - Block.BlockLen = GetLittleUInt(); - else - UInt(&Block.BlockLen); - - if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || - Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { - return IL_TRUE; - } - UShort(&Block.BlockID); - UInt(&Block.BlockLen); - - Pos = itell(); - - switch (Block.BlockID) - { - case PSP_LAYER_START_BLOCK: - if (!ReadLayerBlock(Block.BlockLen)) - return IL_FALSE; - break; - - case PSP_ALPHA_BANK_BLOCK: - if (!ReadAlphaBlock(Block.BlockLen)) - return IL_FALSE; - break; - - case PSP_COLOR_BLOCK: - if (!ReadPalette(Block.BlockLen)) - return IL_FALSE; - break; - - // Gets done in the next iseek, so this is now commented out. - //default: - //iseek(Block.BlockLen, IL_SEEK_CUR); - } - - // Skip to next block just in case we didn't read the entire block. - iseek(Pos + Block.BlockLen, IL_SEEK_SET); - - // @TODO: Do stuff here. - - } while (1); - - return IL_TRUE; -} - - -ILboolean ReadLayerBlock(ILuint BlockLen) -{ - BLOCKHEAD Block; - LAYERINFO_CHUNK LayerInfo; - LAYERBITMAP_CHUNK Bitmap; - ILuint ChunkSize, Padding, i, j; - ILushort NumChars; - - BlockLen; - - // Layer sub-block header - if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) - return IL_FALSE; - if (Header.MajorVersion == 3) - Block.BlockLen = GetLittleUInt(); - else - UInt(&Block.BlockLen); - - if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || - Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { - return IL_FALSE; - } - if (Block.BlockID != PSP_LAYER_BLOCK) - return IL_FALSE; - - - if (Header.MajorVersion == 3) { - iseek(256, IL_SEEK_CUR); // We don't care about the name of the layer. - iread(&LayerInfo, sizeof(LayerInfo), 1); - if (iread(&Bitmap, sizeof(Bitmap), 1) != 1) - return IL_FALSE; - } - else { // Header.MajorVersion >= 4 - ChunkSize = GetLittleUInt(); - NumChars = GetLittleUShort(); - iseek(NumChars, IL_SEEK_CUR); // We don't care about the layer's name. - - ChunkSize -= (2 + 4 + NumChars); - - if (iread(&LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1) - return IL_FALSE; - - // Can have new entries in newer versions of the spec (5.0). - Padding = (ChunkSize) - sizeof(LayerInfo); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - - ChunkSize = GetLittleUInt(); - if (iread(&Bitmap, sizeof(Bitmap), 1) != 1) - return IL_FALSE; - Padding = (ChunkSize - 4) - sizeof(Bitmap); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - } - - - Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels); - if (Channels == NULL) { - return IL_FALSE; - } - - NumChannels = Bitmap.NumChannels; - - for (i = 0; i < NumChannels; i++) { - Channels[i] = GetChannel(); - if (Channels[i] == NULL) { - for (j = 0; j < i; j++) - ifree(Channels[j]); - return IL_FALSE; - } - } - - return IL_TRUE; -} - - -ILboolean ReadAlphaBlock(ILuint BlockLen) -{ - BLOCKHEAD Block; - ALPHAINFO_CHUNK AlphaInfo; - ALPHA_CHUNK AlphaChunk; - ILushort NumAlpha, StringSize; - ILuint ChunkSize, Padding; - - if (Header.MajorVersion == 3) { - NumAlpha = GetLittleUShort(); - } - else { - ChunkSize = GetLittleUInt(); - NumAlpha = GetLittleUShort(); - Padding = (ChunkSize - 4 - 2); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - } - - // Alpha channel header - if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) - return IL_FALSE; - if (Header.MajorVersion == 3) - Block.BlockLen = GetLittleUInt(); - else - UInt(&Block.BlockLen); - - if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || - Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { - return IL_FALSE; - } - if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK) - return IL_FALSE; - - - if (Header.MajorVersion >= 4) { - ChunkSize = GetLittleUInt(); - StringSize = GetLittleUShort(); - iseek(StringSize, IL_SEEK_CUR); - if (iread(&AlphaInfo, sizeof(AlphaInfo), 1) != 1) - return IL_FALSE; - Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo)); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - - ChunkSize = GetLittleUInt(); - if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1) - return IL_FALSE; - Padding = (ChunkSize - 4 - sizeof(AlphaChunk)); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - } - else { - iseek(256, IL_SEEK_CUR); - iread(&AlphaInfo, sizeof(AlphaInfo), 1); - if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1) - return IL_FALSE; - } - - - /*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2); - if (Alpha == NULL) { - return IL_FALSE; - }*/ - - - Alpha = GetChannel(); - if (Alpha == NULL) - return IL_FALSE; - - return IL_TRUE; -} - - -ILubyte *GetChannel() -{ - BLOCKHEAD Block; - CHANNEL_CHUNK Channel; - ILubyte *CompData, *Data; - ILuint ChunkSize, Padding; - - if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) - return NULL; - if (Header.MajorVersion == 3) - Block.BlockLen = GetLittleUInt(); - else - UInt(&Block.BlockLen); - - if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || - Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return NULL; - } - if (Block.BlockID != PSP_CHANNEL_BLOCK) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - return NULL; - } - - - if (Header.MajorVersion >= 4) { - ChunkSize = GetLittleUInt(); - if (iread(&Channel, sizeof(Channel), 1) != 1) - return NULL; - - Padding = (ChunkSize - 4) - sizeof(Channel); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - } - else { - if (iread(&Channel, sizeof(Channel), 1) != 1) - return NULL; - } - - - CompData = (ILubyte*)ialloc(Channel.CompLen); - Data = (ILubyte*)ialloc(AttChunk.Width * AttChunk.Height); - if (CompData == NULL || Data == NULL) { - ifree(Data); - ifree(CompData); - return NULL; - } - - if (iread(CompData, 1, Channel.CompLen) != Channel.CompLen) { - ifree(CompData); - ifree(Data); - return NULL; - } - - switch (AttChunk.Compression) - { - case PSP_COMP_NONE: - ifree(Data); - return CompData; - break; - - case PSP_COMP_RLE: - if (!UncompRLE(CompData, Data, Channel.CompLen)) { - ifree(CompData); - ifree(Data); - return IL_FALSE; - } - break; - - default: - ifree(CompData); - ifree(Data); - ilSetError(IL_INVALID_FILE_HEADER); - return NULL; - } - - ifree(CompData); - - return Data; -} - - -ILboolean UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen) -{ - ILubyte Run, Colour; - ILint i, /*x, y,*/ Count/*, Total = 0*/; - - /*for (y = 0; y < AttChunk.Height; y++) { - for (x = 0, Count = 0; x < AttChunk.Width; ) { - Run = *CompData++; - if (Run > 128) { - Run -= 128; - Colour = *CompData++; - memset(Data, Colour, Run); - Data += Run; - Count += 2; - } - else { - memcpy(Data, CompData, Run); - CompData += Run; - Data += Run; - Count += Run; - } - x += Run; - } - - Total += Count; - - if (Count % 4) { // Has to be on a 4-byte boundary. - CompData += (4 - (Count % 4)) % 4; - Total += (4 - (Count % 4)) % 4; - } - - if (Total >= CompLen) - return IL_FALSE; - }*/ - - for (i = 0, Count = 0; i < (ILint)CompLen; ) { - Run = *CompData++; - i++; - if (Run > 128) { - Run -= 128; - Colour = *CompData++; - i++; - memset(Data, Colour, Run); - } - else { - memcpy(Data, CompData, Run); - CompData += Run; - i += Run; - } - Data += Run; - Count += Run; - } - - return IL_TRUE; -} - - -ILboolean ReadPalette(ILuint BlockLen) -{ - ILuint ChunkSize, PalCount, Padding; - - if (Header.MajorVersion >= 4) { - ChunkSize = GetLittleUInt(); - PalCount = GetLittleUInt(); - Padding = (ChunkSize - 4 - 4); - if (Padding > 0) - iseek(Padding, IL_SEEK_CUR); - } - else { - PalCount = GetLittleUInt(); - } - - Pal.PalSize = PalCount * 4; - Pal.PalType = IL_PAL_BGRA32; - Pal.Palette = (ILubyte*)ialloc(Pal.PalSize); - if (Pal.Palette == NULL) - return IL_FALSE; - - if (iread(Pal.Palette, Pal.PalSize, 1) != 1) { - ifree(Pal.Palette); - return IL_FALSE; - } - - return IL_TRUE; -} - - -ILboolean AssembleImage() -{ - ILuint Size, i, j; - - Size = AttChunk.Width * AttChunk.Height; - - if (NumChannels == 1) { - ilTexImage(AttChunk.Width, AttChunk.Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL); - for (i = 0; i < Size; i++) { - iCurImage->Data[i] = Channels[0][i]; - } - - if (Pal.Palette) { - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalSize = Pal.PalSize; - iCurImage->Pal.PalType = Pal.PalType; - iCurImage->Pal.Palette = Pal.Palette; - } - } - else { - if (Alpha) { - ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - for (i = 0, j = 0; i < Size; i++, j += 4) { - iCurImage->Data[j ] = Channels[0][i]; - iCurImage->Data[j+1] = Channels[1][i]; - iCurImage->Data[j+2] = Channels[2][i]; - iCurImage->Data[j+3] = Alpha[i]; - } - } - - else if (NumChannels == 4) { - - ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - - for (i = 0, j = 0; i < Size; i++, j += 4) { - - iCurImage->Data[j ] = Channels[0][i]; - - iCurImage->Data[j+1] = Channels[1][i]; - - iCurImage->Data[j+2] = Channels[2][i]; - - iCurImage->Data[j+3] = Channels[3][i]; - - } - - } - else if (NumChannels == 3) { - ilTexImage(AttChunk.Width, AttChunk.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); - for (i = 0, j = 0; i < Size; i++, j += 3) { - iCurImage->Data[j ] = Channels[0][i]; - iCurImage->Data[j+1] = Channels[1][i]; - iCurImage->Data[j+2] = Channels[2][i]; - } - } - else - return IL_FALSE; - } - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - return IL_TRUE; -} - - -ILboolean Cleanup() -{ - ILuint i; - - if (Channels) { - for (i = 0; i < NumChannels; i++) { - ifree(Channels[i]); - } - ifree(Channels); - } - - if (Alpha) { - ifree(Alpha); - } - - Channels = NULL; - Alpha = NULL; - Pal.Palette = NULL; - - return IL_TRUE; -} - - - -#endif//IL_NO_PSP diff --git a/win32/devil/src/il_pxr.c b/win32/devil/src/il_pxr.c deleted file mode 100644 index 76e069930..000000000 --- a/win32/devil/src/il_pxr.c +++ /dev/null @@ -1,120 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/26/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_pxr.c -// -// Description: Reads from a Pxrar (.pxr) file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_PXR -#include "il_manip.h" -#include "il_endian.h" - - -#ifdef _MSC_VER -#pragma pack(push, pxr_struct, 1) -#endif -typedef struct PIXHEAD -{ - ILushort Signature; - ILubyte Reserved1[413]; - ILushort Height; - ILushort Width; - ILubyte Reserved2[4]; - ILubyte BppInfo; - ILubyte Reserved3[598]; -} IL_PACKSTRUCT PIXHEAD; -#ifdef _MSC_VER -#pragma pack(pop, pxr_struct) -#endif - -ILboolean iLoadPxrInternal(void); - - -//! Reads a Pxr file -ILboolean ilLoadPxr(ILconst_string FileName) -{ - ILHANDLE PxrFile; - ILboolean bPxr = IL_FALSE; - - PxrFile = iopenr(FileName); - if (PxrFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bPxr; - } - - bPxr = ilLoadPxrF(PxrFile); - icloser(PxrFile); - - return bPxr; -} - - -//! Reads an already-opened Pxr file -ILboolean ilLoadPxrF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadPxrInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Pxr -ILboolean ilLoadPxrL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadPxrInternal(); -} - - -// Internal function used to load the Pxr. -ILboolean iLoadPxrInternal() -{ - ILushort Width, Height; - ILubyte Bpp; - - Width = sizeof(PIXHEAD); - - iseek(416, IL_SEEK_SET); - Height = GetLittleUShort(); - Width = GetLittleUShort(); - iseek(424, IL_SEEK_SET); - Bpp = (ILubyte)igetc(); - - switch (Bpp) - { - case 0x08: - ilTexImage(Width, Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL); - break; - case 0x0E: - ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); - break; - case 0x0F: - ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); - break; - default: - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - iseek(1024, IL_SEEK_SET); - iread(iCurImage->Data, 1, iCurImage->SizeOfData); - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - return IL_TRUE; -} - - -#endif//IL_NO_PXR diff --git a/win32/devil/src/il_quantizer.c b/win32/devil/src/il_quantizer.c deleted file mode 100644 index 276aa115d..000000000 --- a/win32/devil/src/il_quantizer.c +++ /dev/null @@ -1,643 +0,0 @@ -//----------------------------------------------------------------------- -// Color Quantization Demo -// -// Author: Roman Podobedov -// Email: romka@ut.ee -// Romka Graphics: www.ut.ee/~romka -// -// Also in this file implemented Wu's Color Quantizer algorithm (v. 2) -// For details see Graphics Gems vol. II, pp. 126-133 -// -// Wu's Color Quantizer Algorithm: -// Author: Xiaolin Wu -// Dept. of Computer Science -// Univ. of Western Ontario -// London, Ontario N6A 5B7 -// wu@csd.uwo.ca -// http://www.csd.uwo.ca/faculty/wu/ -//----------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// by Denton Woods -// Last modified: 02/02/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_quantizer.c -// -// Description: Heavily modified by Denton Woods. -// -// 20040223 XIX : Modified so it works better with color requests < 256 -// pallete always has memory space for 256 entries -// used so we can quant down to 255 colors then add a transparent color in there. -// -//----------------------------------------------------------------------------- - -#include "il_internal.h" - -#define MAXCOLOR 256 -#define RED 2 -#define GREEN 1 -#define BLUE 0 - -typedef struct Box -{ - ILint r0; // min value, exclusive - ILint r1; // max value, inclusive - ILint g0; - ILint g1; - ILint b0; - ILint b1; - ILint vol; -} Box; - -/* Histogram is in elements 1..HISTSIZE along each axis, - * element 0 is for base or marginal value - * NB: these must start out 0! - */ - -ILfloat gm2[33][33][33]; -ILint wt[33][33][33], mr[33][33][33], mg[33][33][33], mb[33][33][33]; -ILuint size; //image size -ILint K; //colour look-up table size -ILushort *Qadd; - - -ILint WindW, WindH, WindD; -ILint i; -ILubyte *buffer; -static ILint Width, Height, Depth, Comp; -/*ILint TotalColors; -ILint a, b; -ILubyte *buf1, *buf2;*/ - -ILuint n2(ILint s) -{ - ILint i; - ILint res; - - res = 1; - for (i = 0; i < s; i++) { - res = res*2; - } - - return res; -} - - -// Build 3-D color histogram of counts, r/g/b, c^2 -ILboolean Hist3d(ILubyte *Ir, ILubyte *Ig, ILubyte *Ib, ILint *vwt, ILint *vmr, ILint *vmg, ILint *vmb, ILfloat *m2) -{ - ILint ind, r, g, b; - ILint inr, ing, inb, table[2560]; - ILuint i; - - for (i = 0; i < 256; i++) - { - table[i] = i * i; - } - Qadd = (ILushort*)ialloc(sizeof(ILushort) * size); - if (Qadd == NULL) - { - return IL_FALSE; - } - - imemclear(Qadd, sizeof(ILushort) * size); - - for (i = 0; i < size; i++) - { - r = Ir[i]; g = Ig[i]; b = Ib[i]; - inr = (r>>3) + 1; - ing = (g>>3) + 1; - inb = (b>>3) + 1; - Qadd[i] = ind = (inr<<10)+(inr<<6)+inr+(ing<<5)+ing+inb; - //[inr][ing][inb] - vwt[ind]++; - vmr[ind] += r; - vmg[ind] += g; - vmb[ind] += b; - m2[ind] += (ILfloat)(table[r]+table[g]+table[b]); - } - return IL_TRUE; -} - -/* At conclusion of the histogram step, we can interpret - * wt[r][g][b] = sum over voxel of P(c) - * mr[r][g][b] = sum over voxel of r*P(c) , similarly for mg, mb - * m2[r][g][b] = sum over voxel of c^2*P(c) - * Actually each of these should be divided by 'size' to give the usual - * interpretation of P() as ranging from 0 to 1, but we needn't do that here. - */ - -/* We now convert histogram into moments so that we can rapidly calculate - * the sums of the above quantities over any desired Box. - */ - - -// Compute cumulative moments -ILvoid M3d(ILint *vwt, ILint *vmr, ILint *vmg, ILint *vmb, ILfloat *m2) -{ - ILushort ind1, ind2; - ILubyte i, r, g, b; - ILint line, line_r, line_g, line_b, area[33], area_r[33], area_g[33], area_b[33]; - ILfloat line2, area2[33]; - - for (r = 1; r <= 32; r++) { - for (i = 0; i <= 32; i++) { - area2[i] = 0.0f; - area[i]=area_r[i]=area_g[i]=area_b[i]=0; - } - for (g = 1; g <= 32; g++) { - line2 = 0.0f; - line = line_r = line_g = line_b = 0; - for (b = 1; b <= 32; b++) { - ind1 = (r<<10) + (r<<6) + r + (g<<5) + g + b; // [r][g][b] - line += vwt[ind1]; - line_r += vmr[ind1]; - line_g += vmg[ind1]; - line_b += vmb[ind1]; - line2 += m2[ind1]; - area[b] += line; - area_r[b] += line_r; - area_g[b] += line_g; - area_b[b] += line_b; - area2[b] += line2; - ind2 = ind1 - 1089; // [r-1][g][b] - vwt[ind1] = vwt[ind2] + area[b]; - vmr[ind1] = vmr[ind2] + area_r[b]; - vmg[ind1] = vmg[ind2] + area_g[b]; - vmb[ind1] = vmb[ind2] + area_b[b]; - m2[ind1] = m2[ind2] + area2[b]; - } - } - } - - return; -} - - -// Compute sum over a Box of any given statistic -ILint Vol(Box *cube, ILint mmt[33][33][33]) -{ - return( mmt[cube->r1][cube->g1][cube->b1] - -mmt[cube->r1][cube->g1][cube->b0] - -mmt[cube->r1][cube->g0][cube->b1] - +mmt[cube->r1][cube->g0][cube->b0] - -mmt[cube->r0][cube->g1][cube->b1] - +mmt[cube->r0][cube->g1][cube->b0] - +mmt[cube->r0][cube->g0][cube->b1] - -mmt[cube->r0][cube->g0][cube->b0] ); -} - -/* The next two routines allow a slightly more efficient calculation - * of Vol() for a proposed subBox of a given Box. The sum of Top() - * and Bottom() is the Vol() of a subBox split in the given direction - * and with the specified new upper bound. - */ - -// Compute part of Vol(cube, mmt) that doesn't depend on r1, g1, or b1 -// (depending on dir) -ILint Bottom(Box *cube, ILubyte dir, ILint mmt[33][33][33]) -{ - switch(dir) - { - case RED: - return( -mmt[cube->r0][cube->g1][cube->b1] - +mmt[cube->r0][cube->g1][cube->b0] - +mmt[cube->r0][cube->g0][cube->b1] - -mmt[cube->r0][cube->g0][cube->b0] ); - break; - case GREEN: - return( -mmt[cube->r1][cube->g0][cube->b1] - +mmt[cube->r1][cube->g0][cube->b0] - +mmt[cube->r0][cube->g0][cube->b1] - -mmt[cube->r0][cube->g0][cube->b0] ); - break; - case BLUE: - return( -mmt[cube->r1][cube->g1][cube->b0] - +mmt[cube->r1][cube->g0][cube->b0] - +mmt[cube->r0][cube->g1][cube->b0] - -mmt[cube->r0][cube->g0][cube->b0] ); - break; - } - return 0; -} - - -// Compute remainder of Vol(cube, mmt), substituting pos for -// r1, g1, or b1 (depending on dir) -ILint Top(Box *cube, ILubyte dir, ILint pos, ILint mmt[33][33][33]) -{ - switch (dir) - { - case RED: - return( mmt[pos][cube->g1][cube->b1] - -mmt[pos][cube->g1][cube->b0] - -mmt[pos][cube->g0][cube->b1] - +mmt[pos][cube->g0][cube->b0] ); - break; - case GREEN: - return( mmt[cube->r1][pos][cube->b1] - -mmt[cube->r1][pos][cube->b0] - -mmt[cube->r0][pos][cube->b1] - +mmt[cube->r0][pos][cube->b0] ); - break; - case BLUE: - return( mmt[cube->r1][cube->g1][pos] - -mmt[cube->r1][cube->g0][pos] - -mmt[cube->r0][cube->g1][pos] - +mmt[cube->r0][cube->g0][pos] ); - break; - } - - return 0; -} - - -// Compute the weighted variance of a Box -// NB: as with the raw statistics, this is really the variance * size -ILfloat Var(Box *cube) -{ - ILfloat dr, dg, db, xx; - - dr = (ILfloat)Vol(cube, mr); - dg = (ILfloat)Vol(cube, mg); - db = (ILfloat)Vol(cube, mb); - xx = gm2[cube->r1][cube->g1][cube->b1] - -gm2[cube->r1][cube->g1][cube->b0] - -gm2[cube->r1][cube->g0][cube->b1] - +gm2[cube->r1][cube->g0][cube->b0] - -gm2[cube->r0][cube->g1][cube->b1] - +gm2[cube->r0][cube->g1][cube->b0] - +gm2[cube->r0][cube->g0][cube->b1] - -gm2[cube->r0][cube->g0][cube->b0]; - - return xx - (dr*dr+dg*dg+db*db) / (ILfloat)Vol(cube, wt); -} - -/* We want to minimize the sum of the variances of two subBoxes. - * The sum(c^2) terms can be ignored since their sum over both subBoxes - * is the same (the sum for the whole Box) no matter where we split. - * The remaining terms have a minus sign in the variance formula, - * so we drop the minus sign and MAXIMIZE the sum of the two terms. - */ - -ILfloat Maximize(Box *cube, ILubyte dir, ILint first, ILint last, ILint *cut, - ILint whole_r, ILint whole_g, ILint whole_b, ILint whole_w) -{ - ILint half_r, half_g, half_b, half_w; - ILint base_r, base_g, base_b, base_w; - ILint i; - ILfloat temp, max; - - base_r = Bottom(cube, dir, mr); - base_g = Bottom(cube, dir, mg); - base_b = Bottom(cube, dir, mb); - base_w = Bottom(cube, dir, wt); - max = 0.0; - *cut = -1; - - for (i = first; i < last; ++i) { - half_r = base_r + Top(cube, dir, i, mr); - half_g = base_g + Top(cube, dir, i, mg); - half_b = base_b + Top(cube, dir, i, mb); - half_w = base_w + Top(cube, dir, i, wt); - // Now half_x is sum over lower half of Box, if split at i - if (half_w == 0) { // subBox could be empty of pixels! - continue; // never split into an empty Box - } - else { - temp = ((ILfloat)half_r*half_r + (ILfloat)half_g * half_g + - (ILfloat)half_b*half_b) / half_w; - } - - half_r = whole_r - half_r; - half_g = whole_g - half_g; - half_b = whole_b - half_b; - half_w = whole_w - half_w; - if (half_w == 0) { // subBox could be empty of pixels! - continue; // never split into an empty Box - } - else { - temp += ((ILfloat)half_r*half_r + (ILfloat)half_g * half_g + - (ILfloat)half_b*half_b) / half_w; - } - - if (temp > max) { - max = temp; - *cut = i; - } - } - - return max; -} - - -ILint Cut(Box *set1, Box *set2) -{ - ILubyte dir; - ILint cutr, cutg, cutb; - ILfloat maxr, maxg, maxb; - ILint whole_r, whole_g, whole_b, whole_w; - - whole_r = Vol(set1, mr); - whole_g = Vol(set1, mg); - whole_b = Vol(set1, mb); - whole_w = Vol(set1, wt); - - maxr = Maximize(set1, RED, set1->r0+1, set1->r1, &cutr, whole_r, whole_g, whole_b, whole_w); - maxg = Maximize(set1, GREEN, set1->g0+1, set1->g1, &cutg, whole_r, whole_g, whole_b, whole_w); - maxb = Maximize(set1, BLUE, set1->b0+1, set1->b1, &cutb, whole_r, whole_g, whole_b, whole_w); - - if ((maxr >= maxg) && (maxr >= maxb)) { - dir = RED; - if (cutr < 0) - return 0; // can't split the Box - } - else if ((maxg >= maxr) && (maxg >= maxb)) - dir = GREEN; - else - dir = BLUE; - - set2->r1 = set1->r1; - set2->g1 = set1->g1; - set2->b1 = set1->b1; - - switch (dir) - { - case RED: - set2->r0 = set1->r1 = cutr; - set2->g0 = set1->g0; - set2->b0 = set1->b0; - break; - case GREEN: - set2->g0 = set1->g1 = cutg; - set2->r0 = set1->r0; - set2->b0 = set1->b0; - break; - case BLUE: - set2->b0 = set1->b1 = cutb; - set2->r0 = set1->r0; - set2->g0 = set1->g0; - break; - } - - set1->vol = (set1->r1-set1->r0) * (set1->g1-set1->g0) * (set1->b1-set1->b0); - set2->vol = (set2->r1-set2->r0) * (set2->g1-set2->g0) * (set2->b1-set2->b0); - - return 1; -} - - -void Mark(struct Box *cube, int label, unsigned char *tag) -{ - ILint r, g, b; - - for (r = cube->r0 + 1; r <= cube->r1; r++) { - for (g = cube->g0 + 1; g <= cube->g1; g++) { - for (b = cube->b0 + 1; b <= cube->b1; b++) { - tag[(r<<10) + (r<<6) + r + (g<<5) + g + b] = label; - } - } - } - return; -} - - -ILimage *iQuantizeImage(ILimage *Image, ILuint NumCols) -{ - Box cube[MAXCOLOR]; - ILubyte *tag = NULL; - ILubyte lut_r[MAXCOLOR], lut_g[MAXCOLOR], lut_b[MAXCOLOR]; - ILint next; - ILint weight; - ILuint k; - ILfloat vv[MAXCOLOR], temp; - //ILint color_num; - ILubyte *NewData = NULL, *Palette = NULL; - ILimage *TempImage = NULL, *NewImage = NULL; - ILubyte *Ir = NULL, *Ig = NULL, *Ib = NULL; - - ILint num_alloced_colors; // number of colors we allocated space for in palette, as NumCols but eill not be less than 256 - - num_alloced_colors=NumCols; - if(num_alloced_colors<256) { num_alloced_colors=256; } - - - NewImage = iCurImage; - iCurImage = Image; - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - iCurImage = NewImage; - - - - if (TempImage == NULL) - return NULL; - - buffer = Image->Data; - WindW = Width = Image->Width; - WindH = Height = Image->Height; - WindD = Depth = Image->Depth; - Comp = Image->Bpp; - Qadd = NULL; - - //color_num = ImagePrecalculate(Image); - - NewData = (ILubyte*)ialloc(Image->Width * Image->Height * Image->Depth); - Palette = (ILubyte*)ialloc(3 * num_alloced_colors); - if (!NewData || !Palette) { - ifree(NewData); - ifree(Palette); - return NULL; - } - - Ir = (ILubyte*)ialloc(Width * Height * Depth); - Ig = (ILubyte*)ialloc(Width * Height * Depth); - Ib = (ILubyte*)ialloc(Width * Height * Depth); - if (!Ir || !Ig || !Ib) { - ifree(Ir); - ifree(Ig); - ifree(Ib); - ifree(NewData); - ifree(Palette); - return NULL; - } - - size = Width * Height * Depth; - - #ifdef ALTIVEC_GCC - register ILuint v_size = size>>4; - register ILuint pos = 0; - v_size = v_size /3; - register vector unsigned char d0,d1,d2; - register vector unsigned char red[3],blu[3],green[3]; - - register union{ - vector unsigned char vec; - vector unsigned int load; - } mask_1, mask_2, mask_3; - - mask_1.load = (vector unsigned int){0xFF0000FF,0x0000FF00,0x00FF0000,0xFF0000FF}; - mask_2.load = (vector unsigned int){0x00FF0000,0xFF0000FF,0x0000FF00,0x00FF0000}; - mask_2.load = (vector unsigned int){0x0000FF00,0x00FF0000,0xFF0000FF,0x0000FF00}; - - while( v_size >= 0 ) { - d0 = vec_ld(pos,TempImage->Data); - d1 = vec_ld(pos+16,TempImage->Data); - d2 = vec_ld(pos+32,TempImage->Data); - - red[0] = vec_and(d0,mask_1.vec); - green[0] = vec_and(d0,mask_2.vec); - blu[0] = vec_and(d0,mask_3.vec); - - red[1] = vec_and(d1,mask_3.vec); - green[1] = vec_and(d1,mask_1.vec); - blu[1] = vec_and(d1,mask_2.vec); - - red[2] = vec_and(d2,mask_2.vec); - green[2] = vec_and(d2,mask_3.vec); - blu[2] = vec_and(d2,mask_1.vec); - - vec_st(red[0],pos,Ir); - vec_st(red[1],pos+16,Ir); - vec_st(red[2],pos+32,Ir); - - vec_st(blu[0],pos,Ib); - vec_st(blu[1],pos+16,Ib); - vec_st(blu[2],pos+32,Ib); - - vec_st(green[0],pos,Ig); - vec_st(green[1],pos+16,Ig); - vec_st(green[2],pos+32,Ig); - - pos += 48; - } - size -= pos; - #endif - - for (k = 0; k < size; k++) { - Ir[k] = TempImage->Data[k * 3]; - Ig[k] = TempImage->Data[k * 3 + 1]; - Ib[k] = TempImage->Data[k * 3 + 2]; - } - - #ifdef ALTIVEC_GCC - size = Width * Height * Depth; - #endif - - // Set new colors number - K = NumCols; - - if (K <= 256) { - // Begin Wu's color quantization algorithm - - // May have "leftovers" from a previous run. - - imemclear(gm2, 33 * 33 * 33 * sizeof(ILfloat)); - imemclear(wt, 33 * 33 * 33 * sizeof(ILint)); - imemclear(mr, 33 * 33 * 33 * sizeof(ILint)); - imemclear(mg, 33 * 33 * 33 * sizeof(ILint)); - imemclear(mb, 33 * 33 * 33 * sizeof(ILint)); - - if (!Hist3d(Ir, Ig, Ib, (ILint*)wt, (ILint*)mr, (ILint*)mg, (ILint*)mb, (ILfloat*)gm2)) - goto error_label; - - M3d((ILint*)wt, (ILint*)mr, (ILint*)mg, (ILint*)mb, (ILfloat*)gm2); - - cube[0].r0 = cube[0].g0 = cube[0].b0 = 0; - cube[0].r1 = cube[0].g1 = cube[0].b1 = 32; - next = 0; - for (i = 1; i < K; ++i) { - if (Cut(&cube[next], &cube[i])) { // volume test ensures we won't try to cut one-cell Box */ - vv[next] = (cube[next].vol>1) ? Var(&cube[next]) : 0.0f; - vv[i] = (cube[i].vol>1) ? Var(&cube[i]) : 0.0f; - } - else { - vv[next] = 0.0; // don't try to split this Box again - i--; // didn't create Box i - } - next = 0; - temp = vv[0]; - for (k = 1; (ILint)k <= i; ++k) { - if (vv[k] > temp) { - temp = vv[k]; next = k; - } - } - - if (temp <= 0.0) { - K = i+1; - // Only got K Boxes - break; - } - } - - tag = (ILubyte*)ialloc(33 * 33 * 33 * sizeof(ILubyte)); - if (tag == NULL) - goto error_label; - for (k = 0; (ILint)k < K; k++) { - Mark(&cube[k], k, tag); - weight = Vol(&cube[k], wt); - if (weight) { - lut_r[k] = (ILubyte)(Vol(&cube[k], mr) / weight); - lut_g[k] = (ILubyte)(Vol(&cube[k], mg) / weight); - lut_b[k] = (ILubyte)(Vol(&cube[k], mb) / weight); - } - else { - // Bogus Box - lut_r[k] = lut_g[k] = lut_b[k] = 0; - } - } - - for (i = 0; i < (ILint)size; i++) { - NewData[i] = tag[Qadd[i]]; - } - ifree(tag); - ifree(Qadd); - - for (k = 0; k < NumCols; k++) { - Palette[k * 3] = lut_b[k]; - Palette[k * 3 + 1] = lut_g[k]; - Palette[k * 3 + 2] = lut_r[k]; - } - } - else { // If colors more than 256 - // Begin Octree quantization - //Quant_Octree(Image->Width, Image->Height, Image->Bpp, buffer2, NewData, Palette, K); - ilSetError(IL_INTERNAL_ERROR); // Can't get much more specific than this. - goto error_label; - } - - ifree(Ig); - ifree(Ib); - ifree(Ir); - ilCloseImage(TempImage); - - NewImage = (ILimage*)icalloc(sizeof(ILimage), 1); - if (NewImage == NULL) { - return NULL; - } - ilCopyImageAttr(NewImage, Image); - NewImage->Bpp = 1; - NewImage->Bps = Image->Width; - NewImage->SizeOfPlane = NewImage->Bps * Image->Height; - NewImage->SizeOfData = NewImage->SizeOfPlane; - NewImage->Format = IL_COLOUR_INDEX; - NewImage->Type = IL_UNSIGNED_BYTE; - - NewImage->Pal.Palette = Palette; - NewImage->Pal.PalSize = 256 * 3; - NewImage->Pal.PalType = IL_PAL_BGR24; - NewImage->Data = NewData; - - return NewImage; - -error_label: - ifree(NewData); - ifree(Palette); - ifree(Ig); - ifree(Ib); - ifree(Ir); - ifree(tag); - ifree(Qadd); - return NULL; -} diff --git a/win32/devil/src/il_raw.c b/win32/devil/src/il_raw.c deleted file mode 100644 index aebfa0c3b..000000000 --- a/win32/devil/src/il_raw.c +++ /dev/null @@ -1,180 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2001 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_raw.c -// -// Description: "Raw" file functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_RAW - - -ILboolean iLoadRawInternal(void); -ILboolean iSaveRawInternal(void); - - -//! Reads a raw file -ILboolean ilLoadRaw(ILconst_string FileName) -{ - ILHANDLE RawFile; - ILboolean bRaw = IL_FALSE; - - // No need to check for raw - /*if (!iCheckExtension(FileName, "raw")) { - ilSetError(IL_INVALID_EXTENSION); - return bRaw; - }*/ - - RawFile = iopenr(FileName); - if (RawFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bRaw; - } - - bRaw = ilLoadRawF(RawFile); - icloser(RawFile); - - return bRaw; -} - - -//! Reads an already-opened raw file -ILboolean ilLoadRawF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadRawInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a raw memory "lump" -ILboolean ilLoadRawL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadRawInternal(); -} - - -// Internal function to load a raw image -ILboolean iLoadRawInternal() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - - iCurImage->Width = GetLittleUInt(); - - iCurImage->Height = GetLittleUInt(); - - iCurImage->Depth = GetLittleUInt(); - - iCurImage->Bpp = (ILubyte)igetc(); - - if (iread(&iCurImage->Bpc, 1, 1) != 1) - return IL_FALSE; - - if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, iCurImage->Bpp, 0, ilGetTypeBpc(iCurImage->Bpc), NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - // Tries to read the correct amount of data - if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) < iCurImage->SizeOfData) - return IL_FALSE; - - if (ilIsEnabled(IL_ORIGIN_SET)) { - iCurImage->Origin = ilGetInteger(IL_ORIGIN_MODE); - } - else { - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - } - - if (iCurImage->Bpp == 1) - iCurImage->Format = IL_LUMINANCE; - else if (iCurImage->Bpp == 3) - iCurImage->Format = IL_RGB; - else // 4 - iCurImage->Format = IL_RGBA; - - ilFixImage(); - - return IL_TRUE; -} - - -//! Writes a Raw file -ILboolean ilSaveRaw(ILconst_string FileName) -{ - ILHANDLE RawFile; - ILboolean bRaw = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - RawFile = iopenw(FileName); - if (RawFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bRaw; - } - - bRaw = ilSaveRawF(RawFile); - iclosew(RawFile); - - return bRaw; -} - - -//! Writes raw data to an already-opened file -ILboolean ilSaveRawF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSaveRawInternal(); -} - - -//! Writes raw data to a memory "lump" -ILboolean ilSaveRawL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveRawInternal(); -} - - -// Internal function used to load the raw data. -ILboolean iSaveRawInternal() -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - SaveLittleUInt(iCurImage->Width); - SaveLittleUInt(iCurImage->Height); - SaveLittleUInt(iCurImage->Depth); - iputc(iCurImage->Bpp); - iputc(iCurImage->Bpc); - iwrite(iCurImage->Data, 1, iCurImage->SizeOfData); - - return IL_TRUE; -} - - -#endif//IL_NO_RAW diff --git a/win32/devil/src/il_rawdata.c b/win32/devil/src/il_rawdata.c deleted file mode 100644 index 69f7f8343..000000000 --- a/win32/devil/src/il_rawdata.c +++ /dev/null @@ -1,123 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2001 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/rawdata.c -// -// Description: "Raw" file functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -//#ifndef IL_NO_DATA -#include "il_manip.h" - - -ILboolean iLoadDataInternal(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp); - - -//! Reads a raw data file -ILboolean ILAPIENTRY ilLoadData(ILconst_string FileName, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp) -{ - ILHANDLE RawFile; - ILboolean bRaw = IL_FALSE; - - // No need to check for raw data - /*if (!iCheckExtension(FileName, "raw")) { - ilSetError(IL_INVALID_EXTENSION); - return bRaw; - }*/ - - RawFile = iopenr(FileName); - if (RawFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bRaw; - } - - bRaw = ilLoadDataF(RawFile, Width, Height, Depth, Bpp); - icloser(RawFile); - - return bRaw; -} - - -//! Reads an already-opened raw data file -ILboolean ILAPIENTRY ilLoadDataF(ILHANDLE File, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadDataInternal(Width, Height, Depth, Bpp); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a raw data memory "lump" -ILboolean ILAPIENTRY ilLoadDataL(ILvoid *Lump, ILuint Size, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp) -{ - iSetInputLump(Lump, Size); - return iLoadDataInternal(Width, Height, Depth, Bpp); -} - - -// Internal function to load a raw data image -ILboolean iLoadDataInternal(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp) -{ - if (iCurImage == NULL || ((Bpp != 1) && (Bpp != 3) && (Bpp != 4))) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!ilTexImage(Width, Height, Depth, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - // Tries to read the correct amount of data - if (iread(iCurImage->Data, Width * Height * Depth * Bpp, 1) != 1) - return IL_FALSE; - - if (iCurImage->Bpp == 1) - iCurImage->Format = IL_LUMINANCE; - else if (iCurImage->Bpp == 3) - iCurImage->Format = IL_RGB; - else // 4 - iCurImage->Format = IL_RGBA; - - ilFixImage(); - - return IL_TRUE; -} - - -//! Save the current image to FileName as raw data -ILboolean ILAPIENTRY ilSaveData(ILconst_string FileName) -{ - ILHANDLE DataFile; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - DataFile = iopenr(FileName); - if (DataFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - iwrite(iCurImage->Data, 1, iCurImage->SizeOfData); - icloser(DataFile); - - return IL_TRUE; -} - - -//#endif//IL_NO_DATA diff --git a/win32/devil/src/il_register.c b/win32/devil/src/il_register.c deleted file mode 100644 index 75425a8de..000000000 --- a/win32/devil/src/il_register.c +++ /dev/null @@ -1,429 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 10/20/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_register.c -// -// Description: Allows the caller to specify user-defined callback functions -// to open files DevIL does not support, to parse files -// differently, or anything else a person can think up. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_register.h" -#include - - -// Linked lists of registered formats -iFormatL *LoadProcs = NULL; -iFormatS *SaveProcs = NULL; - - -ILboolean ILAPIENTRY ilRegisterLoad(ILconst_string Ext, IL_LOADPROC Load) { - iFormatL *TempNode, *NewNode; - - TempNode = LoadProcs; - if (TempNode != NULL) { - while (TempNode->Next != NULL) { - TempNode = TempNode->Next; -#ifndef _UNICODE - if (!stricmp(TempNode->Ext, Ext)) { // already registered -#else - if (!wcsicmp(TempNode->Ext, Ext)) { -#endif//_UNICODE - return IL_TRUE; - } - } - } - - NewNode = (iFormatL*)ialloc(sizeof(iFormatL)); - if (NewNode == NULL) { - return IL_FALSE; - } - - if (LoadProcs == NULL) { - LoadProcs = NewNode; - } - else { - TempNode->Next = NewNode; - } - -#ifndef _UNICODE - NewNode->Ext = ilStrDup(Ext); -#else - NewNode->Ext = _wcsdup(Ext); -#endif//_UNICODE - NewNode->Load = Load; - NewNode->Next = NULL; - - return IL_TRUE; -} - - -ILboolean ILAPIENTRY ilRegisterSave(ILconst_string Ext, IL_SAVEPROC Save) -{ - iFormatS *TempNode, *NewNode; - - TempNode = SaveProcs; - if (TempNode != NULL) { - while (TempNode->Next != NULL) { - TempNode = TempNode->Next; -#ifndef _UNICODE - if (!stricmp(TempNode->Ext, Ext)) { // already registered -#else - if (!_wcsicmp(TempNode->Ext, Ext)) { -#endif//_UNICODE - return IL_TRUE; - } - } - } - - NewNode = (iFormatS*)ialloc(sizeof(iFormatL)); - if (NewNode == NULL) { - return IL_FALSE; - } - - if (SaveProcs == NULL) { - SaveProcs = NewNode; - } - else { - TempNode->Next = NewNode; - } - -#ifndef _UNICODE - NewNode->Ext = ilStrDup(Ext); -#else - NewNode->Ext = _wcsdup(Ext); -#endif//_UNICODE - NewNode->Save = Save; - NewNode->Next = NULL; - - return IL_TRUE; -} - - -//! Unregisters a load extension - doesn't have to be called. -ILboolean ILAPIENTRY ilRemoveLoad(ILconst_string Ext) -{ - iFormatL *TempNode = LoadProcs, *PrevNode = NULL; - - while (TempNode != NULL) { -#ifndef _UNICODE - if (!stricmp(Ext, TempNode->Ext)) { -#else - if (_wcsicmp(Ext, TempNode->Ext)) { -#endif//_UNICODE - if (PrevNode == NULL) { // first node in the list - LoadProcs = TempNode->Next; - ifree((void*)TempNode->Ext); - ifree(TempNode); - } - else { - PrevNode->Next = TempNode->Next; - ifree((void*)TempNode->Ext); - ifree(TempNode); - } - - return IL_TRUE; - } - - PrevNode = TempNode; - TempNode = TempNode->Next; - } - - return IL_FALSE; -} - - -//! Unregisters a save extension - doesn't have to be called. -ILboolean ILAPIENTRY ilRemoveSave(ILconst_string Ext) -{ - iFormatS *TempNode = SaveProcs, *PrevNode = NULL; - - while (TempNode != NULL) { -#ifndef _UNICODE - if (!stricmp(Ext, TempNode->Ext)) { -#else - if (_wcsicmp(Ext, TempNode->Ext)) { -#endif//_UNICODE - if (PrevNode == NULL) { // first node in the list - SaveProcs = TempNode->Next; - ifree((void*)TempNode->Ext); - ifree(TempNode); - } - else { - PrevNode->Next = TempNode->Next; - ifree((void*)TempNode->Ext); - ifree(TempNode); - } - - return IL_TRUE; - } - - PrevNode = TempNode; - TempNode = TempNode->Next; - } - - return IL_FALSE; -} - - -// Automatically removes all registered formats. -ILvoid ilRemoveRegistered() -{ - iFormatL *TempNodeL = LoadProcs; - iFormatS *TempNodeS = SaveProcs; - - while (LoadProcs != NULL) { - TempNodeL = LoadProcs->Next; - ifree((void*)LoadProcs->Ext); - ifree(LoadProcs); - LoadProcs = TempNodeL; - } - - while (SaveProcs != NULL) { - TempNodeS = SaveProcs->Next; - ifree((void*)SaveProcs->Ext); - ifree(SaveProcs); - SaveProcs = TempNodeS; - } - - return; -} - - -ILboolean iRegisterLoad(ILconst_string FileName) -{ - iFormatL *TempNode = LoadProcs; - ILstring Ext = iGetExtension(FileName); - ILenum Error; - - if (!Ext) - return IL_FALSE; - - while (TempNode != NULL) { -#ifndef _UNICODE - if (!stricmp(Ext, TempNode->Ext)) { -#else - if (_wcsicmp(Ext, TempNode->Ext)) { -#endif//_UNICODE - Error = TempNode->Load(FileName); - if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid. - return IL_TRUE; - } - else { - ilSetError(Error); - return IL_FALSE; - } - } - TempNode = TempNode->Next; - } - - return IL_FALSE; -} - - -ILboolean iRegisterSave(ILconst_string FileName) -{ - iFormatS *TempNode = SaveProcs; - ILstring Ext = iGetExtension(FileName); - ILenum Error; - - if (!Ext) - return IL_FALSE; - - while (TempNode != NULL) { -#ifndef _UNICODE - if (!stricmp(Ext, TempNode->Ext)) { -#else - if (_wcsicmp(Ext, TempNode->Ext)) { -#endif//_UNICODE - Error = TempNode->Save(FileName); - if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid. - return IL_TRUE; - } - else { - ilSetError(Error); - return IL_FALSE; - } - } - TempNode = TempNode->Next; - } - - return IL_FALSE; -} - - -// -// "Reporting" functions -// - -ILvoid ILAPIENTRY ilRegisterOrigin(ILenum Origin) -{ - switch (Origin) - { - case IL_ORIGIN_LOWER_LEFT: - case IL_ORIGIN_UPPER_LEFT: - iCurImage->Origin = Origin; - break; - default: - ilSetError(IL_INVALID_ENUM); - } - return; -} - - -ILvoid ILAPIENTRY ilRegisterFormat(ILenum Format) -{ - switch (Format) - { - case IL_COLOUR_INDEX: - case IL_RGB: - case IL_RGBA: - case IL_BGR: - case IL_BGRA: - case IL_LUMINANCE: - case IL_LUMINANCE_ALPHA: - iCurImage->Format = Format; - break; - default: - ilSetError(IL_INVALID_ENUM); - } - return; -} - - -ILboolean ILAPIENTRY ilRegisterMipNum(ILuint Num) -{ - ILimage *Next, *Prev; - - ilBindImage(ilGetCurName()); // Make sure the current image is actually bound. - ilCloseImage(iCurImage->Mipmaps); // Close any current mipmaps. - - iCurImage->Mipmaps = NULL; - if (Num == 0) // Just gets rid of all the mipmaps. - return IL_TRUE; - - iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1); - if (iCurImage->Mipmaps == NULL) - return IL_FALSE; - Next = iCurImage->Mipmaps; - Num--; - - while (Num) { - Next->Next = ilNewImage(1, 1, 1, 1, 1); - if (Next->Next == NULL) { - // Clean up before we error out. - Prev = iCurImage->Mipmaps; - while (Prev) { - Next = Prev->Next; - ilCloseImage(Prev); - Prev = Next; - } - return IL_FALSE; - } - Next = Next->Next; - Num--; - } - - return IL_TRUE; -} - - -ILboolean ILAPIENTRY ilRegisterNumImages(ILuint Num) -{ - ILimage *Next, *Prev; - - ilBindImage(ilGetCurName()); // Make sure the current image is actually bound. - ilCloseImage(iCurImage->Next); // Close any current "next" images. - - iCurImage->Next = NULL; - if (Num == 0) // Just gets rid of all the "next" images. - return IL_TRUE; - - iCurImage->Next = ilNewImage(1, 1, 1, 1, 1); - if (iCurImage->Next == NULL) - return IL_FALSE; - Next = iCurImage->Next; - Num--; - - while (Num) { - Next->Next = ilNewImage(1, 1, 1, 1, 1); - if (Next->Next == NULL) { - // Clean up before we error out. - Prev = iCurImage->Next; - while (Prev) { - Next = Prev->Next; - ilCloseImage(Prev); - Prev = Next; - } - return IL_FALSE; - } - Next = Next->Next; - Num--; - } - - return IL_TRUE; -} - - -ILvoid ILAPIENTRY ilRegisterType(ILenum Type) -{ - switch (Type) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - case IL_SHORT: - case IL_UNSIGNED_SHORT: - case IL_INT: - case IL_UNSIGNED_INT: - case IL_FLOAT: - case IL_DOUBLE: - iCurImage->Type = Type; - break; - default: - ilSetError(IL_INVALID_ENUM); - } - - return; -} - - -ILvoid ILAPIENTRY ilRegisterPal(ILvoid *Pal, ILuint Size, ILenum Type) -{ - if (!iCurImage->Pal.Palette || !iCurImage->Pal.PalSize || iCurImage->Pal.PalType != IL_PAL_NONE) { - ifree(iCurImage->Pal.Palette); - } - - iCurImage->Pal.PalSize = Size; - iCurImage->Pal.PalType = Type; - iCurImage->Pal.Palette = (ILubyte*)ialloc(Size); - if (iCurImage->Pal.Palette == NULL) - return; - - if (Pal != NULL) { - memcpy(iCurImage->Pal.Palette, Pal, Size); - } - else { - ilSetError(IL_INVALID_PARAM); - } - - return; -} - - -ILboolean ILAPIENTRY ilSetDuration(ILuint Duration) -{ - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - iCurImage->Duration = Duration; - - return IL_TRUE; -} diff --git a/win32/devil/src/il_rle.c b/win32/devil/src/il_rle.c deleted file mode 100644 index ed8cac6b7..000000000 --- a/win32/devil/src/il_rle.c +++ /dev/null @@ -1,153 +0,0 @@ -//----------------------------------------------------------------------------- -// Description: Functions for run-length encoding -//----------------------------------------------------------------------------- - -// RLE code from TrueVision's TGA sample code available as Tgautils.zip at -// ftp://ftp.truevision.com/pub/TGA.File.Format.Spec/PC.Version - -#define IL_RLE_C - -#include "il_internal.h" -#include "il_rle.h" - -ILboolean ilRleCompressLine(ILubyte *p, ILuint n, ILubyte bpp, - ILubyte *q, ILuint *DestWidth, ILenum CompressMode) { - - ILint DiffCount; // pixel count until two identical - ILint SameCount; // number of identical adjacent pixels - ILint RLEBufSize = 0; // count of number of bytes encoded - ILint MaxRun; - const ILint bmp_pad_to_even = 1 - ((long)q - *DestWidth) % 2; - - switch( CompressMode ) { - case IL_TGACOMP: - MaxRun = TGA_MAX_RUN; - break; - case IL_SGICOMP: - MaxRun = SGI_MAX_RUN; - break; - case IL_BMPCOMP: - MaxRun = BMP_MAX_RUN; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - - while( n > 0 ) { - // Analyze pixels - DiffCount = CountDiffPixels(p, bpp, (ILint)n > MaxRun ? MaxRun : n); - SameCount = CountSamePixels(p, bpp, (ILint)n > MaxRun ? MaxRun : n); - - if( CompressMode == IL_BMPCOMP ) { - ILint remaining_data = n - DiffCount - SameCount; - if( remaining_data < 3 ) { // check if the run has gone near the end - // no absolute run can be done - // complete the line adding 0x01 + pixel, for each pixel - while( remaining_data > 0 ) { - *q++ = 0x01; - *q++ = *p++; - remaining_data--; - } - DiffCount = 0; - SameCount = 0; - n = 0; - } - } - - if( DiffCount > 0 ) { // create a raw packet (bmp absolute run) - switch(CompressMode) { - case IL_TGACOMP: - *q++ = (ILbyte)(DiffCount - 1); - break; - case IL_BMPCOMP: - *q++ = 0x00; RLEBufSize++; - *q++ = (ILbyte)DiffCount; - break; - case IL_SGICOMP: - *q++ = (ILbyte)(DiffCount | 0x80); - break; - } - n -= DiffCount; - RLEBufSize += (DiffCount * bpp) + 1; - - while( DiffCount > 0 ) { - switch(bpp) { - case 4: *q++ = *p++; - case 3: *q++ = *p++; - case 2: *q++ = *p++; - case 1: *q++ = *p++; - } - DiffCount--; - } - - if( CompressMode == IL_BMPCOMP ) { - if( (long)q % 2 == bmp_pad_to_even ) { - *q++ = 0x00; // insert padding - } - } - } - - if( SameCount > 1 ) { // create a RLE packet - switch(CompressMode) { - case IL_TGACOMP: - *q++ = (ILbyte)((SameCount - 1) | 0x80); - break; - case IL_SGICOMP: - case IL_BMPCOMP: - *q++ = (ILbyte)(SameCount); - break; - } - n -= SameCount; - RLEBufSize += bpp + 1; - p += (SameCount - 1) * bpp; - *q++ = *p++; - switch(bpp) { - case 4: *q++ = *p++; - case 3: *q++ = *p++; - case 2: *q++ = *p++; - case 1: *q++ = *p++; - } - } - } - - // write line termination code - switch(CompressMode) { - case IL_SGICOMP: - ++RLEBufSize; - *q++ = 0; - break; - case IL_BMPCOMP: - *q++ = 0x00; RLEBufSize++; - *q++ = 0x00; RLEBufSize++; - break; - } - *DestWidth = RLEBufSize; - - return IL_TRUE; -} - - -// Compresses an entire image using run-length encoding -ILuint ilRleCompress(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, - ILubyte *Dest, ILenum CompressMode, ILuint *ScanTable) { - ILuint DestW = 0, i, j, LineLen, Bps = Width * Bpp, SizeOfPlane = Width * Height * Bpp; - - if( ScanTable ) - imemclear(ScanTable,Depth*Height*sizeof(ILuint)); - for( j = 0; j < Depth; j++ ) { - for( i = 0; i < Height; i++ ) { - if( ScanTable ) - *ScanTable++ = DestW; - ilRleCompressLine(Data + j * SizeOfPlane + i * Bps, Width, Bpp, Dest + DestW, &LineLen, CompressMode); - DestW += LineLen; - } - } - - if( CompressMode == IL_BMPCOMP ) { // add end of image - *(Data+DestW) = 0x00; DestW++; - *(Data+DestW) = 0x01; DestW++; - } - - return DestW; -} diff --git a/win32/devil/src/il_sgi.c b/win32/devil/src/il_sgi.c deleted file mode 100644 index bde307e03..000000000 --- a/win32/devil/src/il_sgi.c +++ /dev/null @@ -1,737 +0,0 @@ - -#include "il_internal.h" -#ifndef IL_NO_SGI -#include "il_sgi.h" -#include "il_manip.h" -#include - -static char *FName = NULL; - -/*----------------------------------------------------------------------------*/ - -/*! Checks if the file specified in FileName is a valid .sgi file. */ -ILboolean ilIsValidSgi(ILconst_string FileName) -{ - ILHANDLE SgiFile; - ILboolean bSgi = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("sgi"))) { - ilSetError(IL_INVALID_EXTENSION); - return bSgi; - } - - FName = (char*) FileName; - - SgiFile = iopenr(FileName); - if (SgiFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bSgi; - } - - bSgi = ilIsValidSgiF(SgiFile); - icloser(SgiFile); - - return bSgi; -} - -/*----------------------------------------------------------------------------*/ - -/*! Checks if the ILHANDLE contains a valid .sgi file at the current position.*/ -ILboolean ilIsValidSgiF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidSgi(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - -/*----------------------------------------------------------------------------*/ - -//! Checks if Lump is a valid .sgi lump. -ILboolean ilIsValidSgiL(const ILvoid *Lump, ILuint Size) -{ - FName = NULL; - iSetInputLump(Lump, Size); - return iIsValidSgi(); -} - -/*----------------------------------------------------------------------------*/ - -// Internal function used to get the .sgi header from the current file. -ILboolean iGetSgiHead(iSgiHeader *Header) -{ - Header->MagicNum = GetBigUShort(); - Header->Storage = (ILbyte)igetc(); - Header->Bpc = (ILbyte)igetc(); - Header->Dim = GetBigUShort(); - Header->XSize = GetBigUShort(); - Header->YSize = GetBigUShort(); - Header->ZSize = GetBigUShort(); - Header->PixMin = GetBigInt(); - Header->PixMax = GetBigInt(); - Header->Dummy1 = GetBigInt(); - iread(Header->Name, 1, 80); - Header->ColMap = GetBigInt(); - iread(Header->Dummy, 1, 404); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -/* Internal function to get the header and check it. */ -ILboolean iIsValidSgi() -{ - iSgiHeader Head; - - if (!iGetSgiHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(iSgiHeader), IL_SEEK_CUR); // Go ahead and restore to previous state - - return iCheckSgi(&Head); -} - -/*----------------------------------------------------------------------------*/ - -/* Internal function used to check if the HEADER is a valid .sgi header. */ -ILboolean iCheckSgi(iSgiHeader *Header) -{ - if (Header->MagicNum != SGI_MAGICNUM) - return IL_FALSE; - if (Header->Storage != SGI_RLE && Header->Storage != SGI_VERBATIM) - return IL_FALSE; - if (Header->Bpc == 0 || Header->Dim == 0) - return IL_FALSE; - if (Header->XSize == 0 || Header->YSize == 0 || Header->ZSize == 0) - return IL_FALSE; - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -/*! Reads a SGI file */ -ILboolean ilLoadSgi(ILconst_string FileName) -{ - ILHANDLE SgiFile; - ILboolean bSgi = IL_FALSE; - - SgiFile = iopenr(FileName); - if (SgiFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bSgi; - } - - bSgi = ilLoadSgiF(SgiFile); - icloser(SgiFile); - - return bSgi; -} - -/*----------------------------------------------------------------------------*/ - -/*! Reads an already-opened SGI file */ -ILboolean ilLoadSgiF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadSgiInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - -/*----------------------------------------------------------------------------*/ - -/*! Reads from a memory "lump" that contains a SGI image */ -ILboolean ilLoadSgiL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadSgiInternal(); -} - -/*----------------------------------------------------------------------------*/ - -/* Internal function used to load the SGI image */ -ILboolean iLoadSgiInternal() -{ - iSgiHeader Header; - ILboolean bSgi; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetSgiHead(&Header)) - return IL_FALSE; - if (!iCheckSgi(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - if (Header.Storage == SGI_RLE) { // RLE - bSgi = iReadRleSgi(&Header); - } - else { // Non-RLE //(Header.Storage == SGI_VERBATIM) - bSgi = iReadNonRleSgi(&Header); - } - - ilFixImage(); - - return bSgi; -} - -/*----------------------------------------------------------------------------*/ - -ILboolean iReadRleSgi(iSgiHeader *Head) -{ - #ifdef __LITTLE_ENDIAN__ - ILuint ixTable; - #endif - ILuint ChanInt = 0; - ILuint ixPlane, ixHeight,ixPixel, RleOff, RleLen; - ILuint *OffTable=NULL, *LenTable=NULL, TableSize, Cur; - ILubyte **TempData=NULL; - - if (!iNewSgi(Head)) - return IL_FALSE; - - TableSize = Head->YSize * Head->ZSize; - OffTable = (ILuint*)ialloc(TableSize * sizeof(ILuint)); - LenTable = (ILuint*)ialloc(TableSize * sizeof(ILuint)); - if (OffTable == NULL || LenTable == NULL) - goto cleanup_error; - if (iread(OffTable, TableSize * sizeof(ILuint), 1) != 1) - goto cleanup_error; - if (iread(LenTable, TableSize * sizeof(ILuint), 1) != 1) - goto cleanup_error; - -#ifdef __LITTLE_ENDIAN__ - // Fix the offset/len table (it's big endian format) - for (ixTable = 0; ixTable < TableSize; ixTable++) { - iSwapUInt(OffTable + ixTable); - iSwapUInt(LenTable + ixTable); - } -#endif //__LITTLE_ENDIAN__ - - // We have to create a temporary buffer for the image, because SGI - // images are plane-separated. */ - TempData = (ILubyte**)ialloc(Head->ZSize * sizeof(ILubyte*)); - if (TempData == NULL) - goto cleanup_error; - imemclear(TempData, Head->ZSize * sizeof(ILubyte*)); // Just in case ialloc fails then cleanup_error. - for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) { - TempData[ixPlane] = (ILubyte*)ialloc(Head->XSize * Head->YSize * Head->Bpc); - if (TempData[ixPlane] == NULL) - goto cleanup_error; - } - - // Read the Planes into the temporary memory - for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) { - for (ixHeight = 0, Cur = 0; ixHeight < Head->YSize; - ixHeight++, Cur += Head->XSize * Head->Bpc) { - - RleOff = OffTable[ixHeight + ixPlane * Head->YSize]; - RleLen = LenTable[ixHeight + ixPlane * Head->YSize]; - - // Seeks to the offset table position - iseek(RleOff, IL_SEEK_SET); - if (iGetScanLine((TempData[ixPlane]) + (ixHeight * Head->XSize * Head->Bpc), - Head, RleLen) != Head->XSize * Head->Bpc) { - ilSetError(IL_ILLEGAL_FILE_VALUE); - goto cleanup_error; - } - } - } - - // DW: Removed on 05/25/2002. - /*// Check if an alphaplane exists and invert it - if (Head->ZSize == 4) { - for (ixPixel=0; (ILint)ixPixelXSize * Head->YSize; ixPixel++) { - TempData[3][ixPixel] = TempData[3][ixPixel] ^ 255; - } - }*/ - - // Assemble the image from its planes - for (ixPixel = 0; ixPixel < iCurImage->SizeOfData; - ixPixel += Head->ZSize * Head->Bpc, ChanInt += Head->Bpc) { - for (ixPlane = 0; (ILint)ixPlane < Head->ZSize * Head->Bpc; ixPlane += Head->Bpc) { - iCurImage->Data[ixPixel + ixPlane] = TempData[ixPlane][ChanInt]; - if (Head->Bpc == 2) - iCurImage->Data[ixPixel + ixPlane + 1] = TempData[ixPlane][ChanInt + 1]; - } - } - - #ifdef __LITTLE_ENDIAN__ - if (Head->Bpc == 2) - sgiSwitchData(iCurImage->Data, iCurImage->SizeOfData); - #endif - - ifree(OffTable); - ifree(LenTable); - - for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) { - ifree(TempData[ixPlane]); - } - ifree(TempData); - - return IL_TRUE; - -cleanup_error: - ifree(OffTable); - ifree(LenTable); - if (TempData) { - for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) { - ifree(TempData[ixPlane]); - } - ifree(TempData); - } - - return IL_FALSE; -} - -/*----------------------------------------------------------------------------*/ - -ILint iGetScanLine(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length) -{ - ILushort Pixel, Count; // For current pixel - ILuint BppRead = 0, CurPos = 0, Bps = Head->XSize * Head->Bpc; - - while (BppRead < Length && CurPos < Bps) - { - Pixel = 0; - if (iread(&Pixel, Head->Bpc, 1) != 1) - return -1; - -#ifndef __LITTLE_ENDIAN__ - iSwapUShort(&Pixel); -#endif - - if (!(Count = (Pixel & 0x7f))) // If 0, line ends - return CurPos; - if (Pixel & 0x80) { // If top bit set, then it is a "run" - if (iread(ScanLine, Head->Bpc, Count) != Count) - return -1; - BppRead += Head->Bpc * Count + Head->Bpc; - ScanLine += Head->Bpc * Count; - CurPos += Head->Bpc * Count; - } - else { - if (iread(&Pixel, Head->Bpc, 1) != 1) - return -1; -#ifndef __LITTLE_ENDIAN__ - iSwapUShort(&Pixel); -#endif - if (Head->Bpc == 1) { - while (Count--) { - *ScanLine = (ILubyte)Pixel; - ScanLine++; - CurPos++; - } - } - else { - while (Count--) { - *(ILushort*)ScanLine = Pixel; - ScanLine += 2; - CurPos += 2; - } - } - BppRead += Head->Bpc + Head->Bpc; - } - } - - return CurPos; -} - - -/*----------------------------------------------------------------------------*/ - -// Much easier to read - just assemble from planes, no decompression -ILboolean iReadNonRleSgi(iSgiHeader *Head) -{ - ILuint i, c; - // ILint ChanInt = 0; Unused - ILint ChanSize; - ILboolean Cache = IL_FALSE; - - if (!iNewSgi(Head)) { - return IL_FALSE; - } - - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) { - Cache = IL_TRUE; - ChanSize = Head->XSize * Head->YSize * Head->Bpc; - iPreCache(ChanSize); - } - - for (c = 0; c < iCurImage->Bpp; c++) { - for (i = c; i < iCurImage->SizeOfData; i += iCurImage->Bpp) { - if (iread(iCurImage->Data + i, 1, 1) != 1) { - if (Cache) - iUnCache(); - return IL_FALSE; - } - } - } - - if (Cache) - iUnCache(); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -ILvoid sgiSwitchData(ILubyte *Data, ILuint SizeOfData) -{ - ILubyte Temp; - ILuint i; - #ifdef ALTIVEC_GCC - i = 0; - union { - vector unsigned char vec; - vector unsigned int load; - }inversion_vector; - - inversion_vector.load = (vector unsigned int)\ - {0x01000302,0x05040706,0x09080B0A,0x0D0C0F0E}; - while( i <= SizeOfData-16 ) { - vector unsigned char data = vec_ld(i,Data); - vec_perm(data,data,inversion_vector.vec); - vec_st(data,i,Data); - i+=16; - } - SizeOfData -= i; - #endif - for (i = 0; i < SizeOfData; i += 2) { - Temp = Data[i]; - Data[i] = Data[i+1]; - Data[i+1] = Temp; - } - return; -} - -/*----------------------------------------------------------------------------*/ - -// Just an internal convenience function for reading SGI files -ILboolean iNewSgi(iSgiHeader *Head) -{ - if (!ilTexImage(Head->XSize, Head->YSize, Head->Bpc, (ILubyte)Head->ZSize, 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - switch (Head->ZSize) - { - case 1: - iCurImage->Format = IL_LUMINANCE; - break; - case 2: - iCurImage->Format = IL_LUMINANCE_ALPHA; - break; - case 3: - iCurImage->Format = IL_RGB; - break; - case 4: - iCurImage->Format = IL_RGBA; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - switch (Head->Bpc) - { - case 1: - if (Head->PixMin < 0) - iCurImage->Type = IL_BYTE; - else - iCurImage->Type = IL_UNSIGNED_BYTE; - break; - case 2: - if (Head->PixMin < 0) - iCurImage->Type = IL_SHORT; - else - iCurImage->Type = IL_UNSIGNED_SHORT; - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -//! Writes a SGI file -ILboolean ilSaveSgi(ILconst_string FileName) -{ - ILHANDLE SgiFile; - ILboolean bSgi = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - SgiFile = iopenw(FileName); - if (SgiFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bSgi; - } - - bSgi = ilSaveSgiF(SgiFile); - iclosew(SgiFile); - - return bSgi; -} - -/*----------------------------------------------------------------------------*/ - -//! Writes a SGI to an already-opened file -ILboolean ilSaveSgiF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSaveSgiInternal(); -} - -/*----------------------------------------------------------------------------*/ - -//! Writes a SGI to a memory "lump" -ILboolean ilSaveSgiL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveSgiInternal(); -} - - -ILenum DetermineSgiType(ILenum Type) -{ - if (Type > IL_UNSIGNED_SHORT) { - if (iCurImage->Type == IL_INT) - return IL_SHORT; - return IL_UNSIGNED_SHORT; - } - return Type; -} - -/*----------------------------------------------------------------------------*/ - -// Rle does NOT work yet. - -// Internal function used to save the Sgi. -ILboolean iSaveSgiInternal() -{ - ILuint i, c; - ILboolean Compress; - ILimage *Temp = iCurImage; - ILubyte *TempData; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iCurImage->Format != IL_LUMINANCE - //while the sgi spec doesn't directly forbid rgb files with 2 - //channels, they are quite uncommon and most apps don't support - //them. so convert lum_a images to rgba before writing. - //&& iCurImage->Format != IL_LUMINANCE_ALPHA - && iCurImage->Format != IL_RGB - && iCurImage->Format != IL_RGBA) { - if (iCurImage->Format == IL_BGRA || iCurImage->Format == IL_LUMINANCE_ALPHA) - Temp = iConvertImage(iCurImage, IL_RGBA, DetermineSgiType(iCurImage->Type)); - else - Temp = iConvertImage(iCurImage, IL_RGB, DetermineSgiType(iCurImage->Type)); - } - else if (iCurImage->Type > IL_UNSIGNED_SHORT) { - Temp = iConvertImage(iCurImage, iCurImage->Format, DetermineSgiType(iCurImage->Type)); - } - - //compression of images with 2 bytes per channel doesn't work yet - Compress = iGetInt(IL_SGI_RLE) && Temp->Bpc == 1; - - if (Temp == NULL) - return IL_FALSE; - - SaveBigUShort(SGI_MAGICNUM); // 'Magic' number - if (Compress) - iputc(1); - else - iputc(0); - - if (Temp->Type == IL_UNSIGNED_BYTE) - iputc(1); - else if (Temp->Type == IL_UNSIGNED_SHORT) - iputc(2); - // Need to error here if not one of the two... - - if (Temp->Format == IL_LUMINANCE || Temp->Format == IL_COLOUR_INDEX) - SaveBigUShort(2); - else - SaveBigUShort(3); - - SaveBigUShort((ILushort)Temp->Width); - SaveBigUShort((ILushort)Temp->Height); - SaveBigUShort((ILushort)Temp->Bpp); - - switch (Temp->Type) - { - case IL_BYTE: - SaveBigInt(SCHAR_MIN); // Minimum pixel value - SaveBigInt(SCHAR_MAX); // Maximum pixel value - break; - case IL_UNSIGNED_BYTE: - SaveBigInt(0); // Minimum pixel value - SaveBigInt(UCHAR_MAX); // Maximum pixel value - break; - case IL_SHORT: - SaveBigInt(SHRT_MIN); // Minimum pixel value - SaveBigInt(SHRT_MAX); // Maximum pixel value - break; - case IL_UNSIGNED_SHORT: - SaveBigInt(0); // Minimum pixel value - SaveBigInt(USHRT_MAX); // Maximum pixel value - break; - } - - SaveBigInt(0); // Dummy value - - if (FName) { - c = strlen(FName); - c = c < 79 ? 79 : c; - iwrite(FName, 1, c); - c = 80 - c; - for (i = 0; i < c; i++) { - iputc(0); - } - } - else { - for (i = 0; i < 80; i++) { - iputc(0); - } - } - - SaveBigUInt(0); // Colormap - - // Padding - for (i = 0; i < 101; i++) { - SaveLittleInt(0); - } - - - if (iCurImage->Origin == IL_ORIGIN_UPPER_LEFT) { - TempData = iGetFlipped(Temp); - if (TempData == NULL) { - if (Temp!= iCurImage) - ilCloseImage(Temp); - return IL_FALSE; - } - } - else { - TempData = Temp->Data; - } - - - if (!Compress) { - for (c = 0; c < Temp->Bpp; c++) { - for (i = c; i < Temp->SizeOfData; i += Temp->Bpp) { - iputc(TempData[i]); // Have to save each colour plane separately. - } - } - } - else { - iSaveRleSgi(TempData, Temp->Width, Temp->Height, Temp->Bpp, Temp->Bps); - } - - - if (TempData != Temp->Data) - ifree(TempData); - if (Temp != iCurImage) - ilCloseImage(Temp); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -ILboolean iSaveRleSgi(ILubyte *Data, ILuint w, ILuint h, ILuint numChannels, - ILuint bps) -{ - //works only for sgi files with only 1 bpc - - ILuint c, i, y, j; - ILubyte *ScanLine = NULL, *CompLine = NULL; - ILuint *StartTable = NULL, *LenTable = NULL; - ILuint TableOff, DataOff = 0; - - ScanLine = (ILubyte*)ialloc(w); - CompLine = (ILubyte*)ialloc(w * 2 + 1); // Absolute worst case. - StartTable = (ILuint*)ialloc(h * numChannels * sizeof(ILuint)); - LenTable = (ILuint*)icalloc(h * numChannels, sizeof(ILuint)); - if (!ScanLine || !CompLine || !StartTable || !LenTable) { - ifree(ScanLine); - ifree(CompLine); - ifree(StartTable); - ifree(LenTable); - return IL_FALSE; - } - - // These just contain dummy values at this point. - TableOff = itellw(); - iwrite(StartTable, sizeof(ILuint), h * numChannels); - iwrite(LenTable, sizeof(ILuint), h * numChannels); - - DataOff = itellw(); - for (c = 0; c < numChannels; c++) { - for (y = 0; y < h; y++) { - i = y * bps + c; - for (j = 0; j < w; j++, i += numChannels) { - ScanLine[j] = Data[i]; - } - - ilRleCompressLine(ScanLine, w, 1, CompLine, LenTable + h * c + y, IL_SGICOMP); - iwrite(CompLine, 1, *(LenTable + h * c + y)); - } - } - - iseekw(TableOff, IL_SEEK_SET); - - j = h * numChannels; - for (y = 0; y < j; y++) { - StartTable[y] = DataOff; - DataOff += LenTable[y]; -#ifdef __LITTLE_ENDIAN__ - iSwapUInt(&StartTable[y]); - iSwapUInt(&LenTable[y]); -#endif - } - - iwrite(StartTable, sizeof(ILuint), h * numChannels); - iwrite(LenTable, sizeof(ILuint), h * numChannels); - - ifree(ScanLine); - ifree(CompLine); - ifree(StartTable); - ifree(LenTable); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -#endif//IL_NO_SGI diff --git a/win32/devil/src/il_stack.c b/win32/devil/src/il_stack.c deleted file mode 100644 index d82d27dc0..000000000 --- a/win32/devil/src/il_stack.c +++ /dev/null @@ -1,605 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2001 by Denton Woods -// Last modified: 12/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_stack.c -// -// Description: The main image stack -// -//----------------------------------------------------------------------------- - -// Credit goes to John Villar (johnny@reliaschev.com) for making the suggestion -// of not letting the user use ILimage structs but instead binding images -// like OpenGL. - -#include "il_internal.h" -#include "il_stack.h" - -//! Creates Num images and puts their index in Images - similar to glGenTextures(). -ILvoid ILAPIENTRY ilGenImages(ILsizei Num, ILuint *Images) -{ - ILsizei Index = 0; - iFree *TempFree = FreeNames; - - if (Num < 1 || Images == NULL) { - ilSetError(IL_INVALID_VALUE); - return; - } - - // No images have been generated yet, so create the image stack. - if (ImageStack == NULL) - if (!iEnlargeStack()) - return; - - do { - if (FreeNames != NULL) { // If any have been deleted, then reuse their image names. - TempFree = (iFree*)FreeNames->Next; - Images[Index] = FreeNames->Name; - ImageStack[FreeNames->Name] = ilNewImage(1, 1, 1, 1, 1); - ifree(FreeNames); - FreeNames = TempFree; - } else { - if (LastUsed >= StackSize) - if (!iEnlargeStack()) - return; - Images[Index] = LastUsed; - // Must be all 1's instead of 0's, because some functions would divide by 0. - ImageStack[LastUsed] = ilNewImage(1, 1, 1, 1, 1); - LastUsed++; - } - } while (++Index < Num); - - return; -} - -ILint ILAPIENTRY ilGenImage() { - ILuint i; - ilGenImages(1,&i); - return i; -} - -//! Makes Image the current active image - similar to glBindTexture(). -ILvoid ILAPIENTRY ilBindImage(ILuint Image) -{ - if (ImageStack == NULL || StackSize == 0) { - if (!iEnlargeStack()) { - return; - } - } - - // If the user requests a high image name. - while (Image >= StackSize) { - if (!iEnlargeStack()) { - return; - } - } - - if (ImageStack[Image] == NULL) { - ImageStack[Image] = ilNewImage(1, 1, 1, 1, 1); - if (Image >= LastUsed) // >= ? - LastUsed = Image + 1; - } - - iCurImage = ImageStack[Image]; - CurName = Image; - - ParentImage = IL_TRUE; - - return; -} - - -//! Deletes Num images from the image stack - similar to glDeleteTextures(). -ILvoid ILAPIENTRY ilDeleteImages(ILsizei Num, const ILuint *Images) -{ - iFree *Temp = FreeNames; - ILuint Index = 0; - - if (Num < 1) { - //ilSetError(IL_INVALID_VALUE); - return; - } - if (StackSize == 0) - return; - - do { - if (Images[Index] > 0 && Images[Index] < LastUsed) { // <= ? - /*if (FreeNames != NULL) { // Terribly inefficient - Temp = FreeNames; - do { - if (Temp->Name == Images[Index]) { - continue; // Sufficient? - } - } while ((Temp = Temp->Next)); - }*/ - - // Already has been deleted or was never used. - if (ImageStack[Images[Index]] == NULL) - continue; - - // Find out if current image - if so, set to default image zero. - if (Images[Index] == CurName || Images[Index] == 0) { - iCurImage = ImageStack[0]; - CurName = 0; - } - - // Should *NOT* be NULL here! - ilCloseImage(ImageStack[Images[Index]]); - ImageStack[Images[Index]] = NULL; - - // Add to head of list - works for empty and non-empty lists - Temp = (iFree*)ialloc(sizeof(iFree)); - if (!Temp) { - return; - } - Temp->Name = Images[Index]; - Temp->Next = FreeNames; - FreeNames = Temp; - } - /*else { // Shouldn't set an error...just continue onward. - ilSetError(IL_ILLEGAL_OPERATION); - }*/ - } while (++Index < (ILuint)Num); -} - - -ILvoid ILAPIENTRY ilDeleteImage(const ILuint Num) { - ilDeleteImages(1,&Num); -} - -//! Checks if Image is a valid ilGenImages-generated image (like glIsTexture()). -ILboolean ILAPIENTRY ilIsImage(ILuint Image) -{ - //iFree *Temp = FreeNames; - - if (ImageStack == NULL) - return IL_FALSE; - if (Image >= LastUsed || Image == 0) - return IL_FALSE; - - /*do { - if (Temp->Name == Image) - return IL_FALSE; - } while ((Temp = Temp->Next));*/ - - if (ImageStack[Image] == NULL) // Easier check. - return IL_FALSE; - - return IL_TRUE; -} - - -//! Closes Image and frees all memory associated with it. -ILAPI ILvoid ILAPIENTRY ilCloseImage(ILimage *Image) -{ - if (Image == NULL) - return; - - if (Image->Data != NULL) { - ifree(Image->Data); - Image->Data = NULL; - } - - if (Image->Pal.Palette != NULL && Image->Pal.PalSize > 0 && Image->Pal.PalType != IL_PAL_NONE) { - ifree(Image->Pal.Palette); - Image->Pal.Palette = NULL; - } - - if (Image->Next != NULL) { - ilCloseImage(Image->Next); - Image->Next = NULL; - } - - if (Image->Mipmaps != NULL) { - ilCloseImage(Image->Mipmaps); - Image->Mipmaps = NULL; - } - - if (Image->Layers != NULL) { - ilCloseImage(Image->Layers); - Image->Layers = NULL; - } - - if (Image->AnimList != NULL && Image->AnimSize != 0) { - ifree(Image->AnimList); - Image->AnimList = NULL; - } - - if (Image->Profile != NULL && Image->ProfileSize != 0) { - ifree(Image->Profile); - Image->Profile = NULL; - Image->ProfileSize = 0; - } - - if (Image->DxtcData != NULL && Image->DxtcFormat != IL_DXT_NO_COMP) { - ifree(Image->DxtcData); - Image->DxtcData = NULL; - Image->DxtcFormat = IL_DXT_NO_COMP; - Image->DxtcSize = 0; - } - - ifree(Image); - Image = NULL; - - return; -} - - -ILAPI ILboolean ILAPIENTRY ilIsValidPal(ILpal *Palette) -{ - if (Palette == NULL) - return IL_FALSE; - if (Palette->PalSize == 0 || Palette->Palette == NULL) - return IL_FALSE; - switch (Palette->PalType) - { - case IL_PAL_RGB24: - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - case IL_PAL_BGR24: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - return IL_TRUE; - } - return IL_FALSE; -} - - -//! Closes Palette and frees all memory associated with it. -ILAPI ILvoid ILAPIENTRY ilClosePal(ILpal *Palette) -{ - if (Palette == NULL) - return; - if (!ilIsValidPal(Palette)) - return; - ifree(Palette->Palette); - ifree(Palette); - return; -} - - -ILimage *iGetBaseImage() -{ - return ImageStack[ilGetCurName()]; -} - - -//! Sets the current mipmap level -ILboolean ILAPIENTRY ilActiveMipmap(ILuint Number) -{ - ILuint Current; - ILimage *iTempImage; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (Number == 0) { - return IL_TRUE; - } - - iTempImage = iCurImage; - iCurImage = iCurImage->Mipmaps; - for (Current = 1; Current < Number; Current++) { - iCurImage = iCurImage->Next; - if (iCurImage == NULL) { - ilSetError(IL_INTERNAL_ERROR); - iCurImage = iTempImage; - return IL_FALSE; - } - } - - ParentImage = IL_FALSE; - - return IL_TRUE; -} - - -//! Used for setting the current image if it is an animation. -ILboolean ILAPIENTRY ilActiveImage(ILuint Number) -{ - ILuint Current; - ILimage *iTempImage; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (Number == 0) { - return IL_TRUE; - } - - iTempImage = iCurImage; - iCurImage = iCurImage->Next; - Number--; // Skip 0 (parent image) - for (Current = 0; Current < Number; Current++) { - iCurImage = iCurImage->Next; - if (iCurImage == NULL) { - ilSetError(IL_INTERNAL_ERROR); - iCurImage = iTempImage; - return IL_FALSE; - } - } - - ParentImage = IL_FALSE; - - return IL_TRUE; -} - - -//! Used for setting the current layer if layers exist. -ILboolean ILAPIENTRY ilActiveLayer(ILuint Number) -{ - ILuint Current; - ILimage *iTempImage; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (Number == 0) { - return IL_TRUE; - } - - iTempImage = iCurImage; - iCurImage = iCurImage->Layers; - //Number--; // Skip 0 (parent image) - for (Current = 1; Current < Number; Current++) { - iCurImage = iCurImage->Layers; - if (iCurImage == NULL) { - ilSetError(IL_INTERNAL_ERROR); - iCurImage = iTempImage; - return IL_FALSE; - } - } - - ParentImage = IL_FALSE; - - return IL_TRUE; -} - - -ILuint ILAPIENTRY ilCreateSubImage(ILenum Type, ILuint Num) -{ - ILimage *SubImage; - ILuint Count ; // Create one before we go in the loop. - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return 0; - } - if (Num == 0) { - return 0; - } - - switch (Type) - { - case IL_SUB_NEXT: - if (iCurImage->Next) - ilCloseImage(iCurImage->Next); - iCurImage->Next = ilNewImage(1, 1, 1, 1, 1); - SubImage = iCurImage->Next; - break; - - case IL_SUB_MIPMAP: - if (iCurImage->Mipmaps) - ilCloseImage(iCurImage->Mipmaps); - iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1); - SubImage = iCurImage->Mipmaps; - break; - - case IL_SUB_LAYER: - if (iCurImage->Layers) - ilCloseImage(iCurImage->Layers); - iCurImage->Layers = ilNewImage(1, 1, 1, 1, 1); - SubImage = iCurImage->Layers; - break; - - default: - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; - } - - if (SubImage == NULL) { - return 0; - } - - for (Count = 1; Count < Num; Count++) { - SubImage->Next = ilNewImage(1, 1, 1, 1, 1); - SubImage = SubImage->Next; - if (SubImage == NULL) - return Count; - } - - return Count; -} - - -// Returns the current index. -ILAPI ILuint ILAPIENTRY ilGetCurName() -{ - if (iCurImage == NULL || ImageStack == NULL || StackSize == 0) - return 0; - return CurName; -} - - -// Returns the current image. -ILAPI ILimage* ILAPIENTRY ilGetCurImage() -{ - return iCurImage; -} - - -// To be only used when the original image is going to be set back almost immediately. -ILAPI ILvoid ILAPIENTRY ilSetCurImage(ILimage *Image) -{ - iCurImage = Image; - return; -} - - -// Completely replaces the current image and the version in the image stack. -ILAPI ILvoid ILAPIENTRY ilReplaceCurImage(ILimage *Image) -{ - if (iCurImage) { - ilActiveImage(0); - ilCloseImage(iCurImage); - } - ImageStack[ilGetCurName()] = Image; - iCurImage = Image; - ParentImage = IL_TRUE; - return; -} - - -// Like realloc but sets new memory to 0. -ILvoid* ILAPIENTRY ilRecalloc(ILvoid *Ptr, ILuint OldSize, ILuint NewSize) -{ - ILvoid *Temp = ialloc(NewSize); - ILuint CopySize = (OldSize < NewSize) ? OldSize : NewSize; - - if (Temp != NULL) { - if (Ptr != NULL) { - memcpy(Temp, Ptr, CopySize); - ifree(Ptr); - } - - Ptr = Temp; - - if (OldSize < NewSize) - imemclear((ILubyte*)Temp + OldSize, NewSize - OldSize); - } - - return Temp; -} - - -// Internal function to enlarge the image stack by I_STACK_INCREMENT members. -ILboolean iEnlargeStack() -{ - // 02-05-2001: Moved from ilGenImages(). - // Puts the cleanup function on the exit handler once. - if (!OnExit) { - #ifdef _MEM_DEBUG - AddToAtexit(); // So iFreeMem doesn't get called after unfreed information. - #endif//_MEM_DEBUG -#if (!defined(_WIN32_WCE)) && (!defined(IL_STATIC_LIB)) - atexit((void*)ilShutDown); -#endif - OnExit = IL_TRUE; - } - - if (!(ImageStack = (ILimage**)ilRecalloc(ImageStack, StackSize * sizeof(ILimage*), (StackSize + I_STACK_INCREMENT) * sizeof(ILimage*)))) { - return IL_FALSE; - } - StackSize += I_STACK_INCREMENT; - return IL_TRUE; -} - - -static ILboolean IsInit = IL_FALSE; - -// ONLY call at startup. -ILvoid ILAPIENTRY ilInit() -{ - // if it is already initialized skip initialization - if (IsInit == IL_TRUE ) - return; - - //ilSetMemory(NULL, NULL); Now useless 3/4/2006 (due to modification in il_alloc.c) - ilSetError(IL_NO_ERROR); - ilDefaultStates(); // Set states to their defaults. - // Sets default file-reading callbacks. - ilResetRead(); - ilResetWrite(); -#if (!defined(_WIN32_WCE)) && (!defined(IL_STATIC_LIB)) - atexit((void*)ilRemoveRegistered); -#endif - //_WIN32_WCE - //ilShutDown(); - iSetImage0(); // Beware! Clears all existing textures! - iBindImageTemp(); // Go ahead and create the temporary image. - IsInit = IL_TRUE; - return; -} - - -// Frees any extra memory in the stack. -// - Called on exit -ILvoid ILAPIENTRY ilShutDown() -{ - // if it is not initialized do not shutdown - iFree* TempFree = (iFree*)FreeNames; - ILuint i; - - if (!IsInit) - return; - - if (!IsInit) { // Prevent from being called when not initialized. - ilSetError(IL_ILLEGAL_OPERATION); - return; - } - - while (TempFree != NULL) { - FreeNames = (iFree*)TempFree->Next; - ifree(TempFree); - TempFree = FreeNames; - } - - //for (i = 0; i < LastUsed; i++) { - for (i = 0; i < StackSize; i++) { - if (ImageStack[i] != NULL) - ilCloseImage(ImageStack[i]); - } - - if (ImageStack) - ifree(ImageStack); - ImageStack = NULL; - LastUsed = 0; - StackSize = 0; - IsInit = IL_FALSE; - return; -} - - -// Initializes the image stack's first entry (default image) -- ONLY CALL ONCE! -ILvoid iSetImage0() -{ - if (ImageStack == NULL) - if (!iEnlargeStack()) - return; - - LastUsed = 1; - CurName = 0; - ParentImage = IL_TRUE; - if (!ImageStack[0]) - ImageStack[0] = ilNewImage(1, 1, 1, 1, 1); - iCurImage = ImageStack[0]; - ilDefaultImage(); - - return; -} - - -ILAPI ILvoid ILAPIENTRY iBindImageTemp() -{ - if (ImageStack == NULL || StackSize <= 1) - if (!iEnlargeStack()) - return; - - if (LastUsed <2 ) - LastUsed = 2; - CurName = 1; - ParentImage = IL_TRUE; - if (!ImageStack[1]) - ImageStack[1] = ilNewImage(1, 1, 1, 1, 1); - iCurImage = ImageStack[1]; - - return; -} diff --git a/win32/devil/src/il_states.c b/win32/devil/src/il_states.c deleted file mode 100644 index 375520c48..000000000 --- a/win32/devil/src/il_states.c +++ /dev/null @@ -1,1112 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2008 by Denton Woods -// Last modified: 08/24/2008 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_states.c -// -// Description: State machine -// -// -// 20040223 XIX : now has a ilPngAlphaIndex member, so we can spit out png files with a transparent index, set to -1 for none -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#include "il_states.h" -//#include -#include - -ILstring _ilVendor = IL_TEXT("Abysmal Software"); -ILstring _ilVersion = IL_TEXT("Developer's Image Library (DevIL) 1.7.2"); - - -char* _ilLoadExt = "" IL_BMP_EXT IL_CUT_EXT IL_DCX_EXT IL_DDS_EXT - IL_GIF_EXT IL_HDR_EXT IL_ICO_EXT IL_JPG_EXT IL_LIF_EXT - IL_MDL_EXT IL_MNG_EXT IL_PCX_EXT IL_PIC_EXT - IL_PIX_EXT IL_PNG_EXT IL_PNM_EXT IL_PSD_EXT - IL_PSP_EXT IL_PXR_EXT IL_SGI_EXT IL_TGA_EXT - IL_TIF_EXT IL_WAL_EXT IL_XPM_EXT IL_JP2_EXT - IL_EXR_EXT IL_ICNS_EXT; -char* _ilSaveExt = "" IL_BMP_EXT IL_CHEAD_EXT IL_DDS_EXT IL_JPG_EXT - IL_PCX_EXT IL_PNG_EXT IL_PNM_EXT IL_PSD_EXT - IL_SGI_EXT IL_TGA_EXT IL_TIF_EXT; - - -//! Set all states to their defaults. -ILvoid ilDefaultStates() -{ - ilStates[ilCurrentPos].ilOriginSet = IL_FALSE; - ilStates[ilCurrentPos].ilOriginMode = IL_ORIGIN_LOWER_LEFT; - ilStates[ilCurrentPos].ilFormatSet = IL_FALSE; - ilStates[ilCurrentPos].ilFormatMode = IL_BGRA; - ilStates[ilCurrentPos].ilTypeSet = IL_FALSE; - ilStates[ilCurrentPos].ilTypeMode = IL_UNSIGNED_BYTE; - ilStates[ilCurrentPos].ilOverWriteFiles = IL_FALSE; - ilStates[ilCurrentPos].ilAutoConvPal = IL_FALSE; - ilStates[ilCurrentPos].ilDefaultOnFail = IL_FALSE; - ilStates[ilCurrentPos].ilUseKeyColour = IL_FALSE; - ilStates[ilCurrentPos].ilCompression = IL_COMPRESS_ZLIB; - ilStates[ilCurrentPos].ilInterlace = IL_FALSE; - - ilStates[ilCurrentPos].ilTgaCreateStamp = IL_FALSE; - ilStates[ilCurrentPos].ilJpgQuality = 99; - ilStates[ilCurrentPos].ilPngInterlace = IL_FALSE; - ilStates[ilCurrentPos].ilTgaRle = IL_FALSE; - ilStates[ilCurrentPos].ilBmpRle = IL_FALSE; - ilStates[ilCurrentPos].ilSgiRle = IL_FALSE; - ilStates[ilCurrentPos].ilJpgFormat = IL_JFIF; - ilStates[ilCurrentPos].ilDxtcFormat = IL_DXT1; - ilStates[ilCurrentPos].ilPcdPicNum = 2; - ilStates[ilCurrentPos].ilPngAlphaIndex = -1; - - ilStates[ilCurrentPos].ilTgaId = NULL; - ilStates[ilCurrentPos].ilTgaAuthName = NULL; - ilStates[ilCurrentPos].ilTgaAuthComment = NULL; - ilStates[ilCurrentPos].ilPngAuthName = NULL; - ilStates[ilCurrentPos].ilPngTitle = NULL; - ilStates[ilCurrentPos].ilPngDescription = NULL; - - //2003-09-01: added tiff strings - ilStates[ilCurrentPos].ilTifDescription = NULL; - ilStates[ilCurrentPos].ilTifHostComputer = NULL; - ilStates[ilCurrentPos].ilTifDocumentName = NULL; - ilStates[ilCurrentPos].ilTifAuthName = NULL; - ilStates[ilCurrentPos].ilCHeader = NULL; - - ilStates[ilCurrentPos].ilQuantMode = IL_WU_QUANT; - ilStates[ilCurrentPos].ilNeuSample = 15; - ilStates[ilCurrentPos].ilQuantMaxIndexs = 256; - - ilStates[ilCurrentPos].ilKeepDxtcData = IL_FALSE; - - - - - ilHints.MemVsSpeedHint = IL_FASTEST; - ilHints.CompressHint = IL_USE_COMPRESSION; - - while (ilGetError() != IL_NO_ERROR); - - return; -} - - -//! Returns a constant string detailing aspects about this library. -ILstring ILAPIENTRY ilGetString(ILenum StringName) -{ - switch (StringName) - { - case IL_VENDOR: - return (ILstring)_ilVendor; - case IL_VERSION_NUM: //changed 2003-08-30: IL_VERSION changes //switch define ;-) - return (ILstring)_ilVersion; - case IL_LOAD_EXT: - return (ILstring)_ilLoadExt; - case IL_SAVE_EXT: - return (ILstring)_ilSaveExt; - case IL_TGA_ID_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTgaId; - case IL_TGA_AUTHNAME_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTgaAuthName; - case IL_TGA_AUTHCOMMENT_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTgaAuthComment; - case IL_PNG_AUTHNAME_STRING: - return (ILstring)ilStates[ilCurrentPos].ilPngAuthName; - case IL_PNG_TITLE_STRING: - return (ILstring)ilStates[ilCurrentPos].ilPngTitle; - case IL_PNG_DESCRIPTION_STRING: - return (ILstring)ilStates[ilCurrentPos].ilPngDescription; - //2003-08-31: added tif strings - case IL_TIF_DESCRIPTION_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTifDescription; - case IL_TIF_HOSTCOMPUTER_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTifHostComputer; - case IL_TIF_DOCUMENTNAME_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTifDocumentName; - case IL_TIF_AUTHNAME_STRING: - return (ILstring)ilStates[ilCurrentPos].ilTifAuthName; - case IL_CHEAD_HEADER_STRING: - return (ILstring)ilStates[ilCurrentPos].ilCHeader; - default: - ilSetError(IL_INVALID_ENUM); - break; - } - return NULL; -} - - -// Clips a string to a certain length and returns a new string. -char *iClipString(char *String, ILuint MaxLen) -{ - char *Clipped; - ILuint Length; - - if (String == NULL) - return NULL; - - Length = strlen(String); - - Clipped = (char*)ialloc(MaxLen + 1); // Terminating NULL makes it +1. - if (Clipped == NULL) { - return NULL; - } - - memcpy(Clipped, String, Length); - Clipped[Length] = 0; - - return Clipped; -} - - -// Returns format-specific strings, truncated to MaxLen (not counting the terminating NULL). -char *iGetString(ILenum StringName) -{ - switch (StringName) - { - case IL_TGA_ID_STRING: - return iClipString(ilStates[ilCurrentPos].ilTgaId, 254); - case IL_TGA_AUTHNAME_STRING: - return iClipString(ilStates[ilCurrentPos].ilTgaAuthName, 40); - case IL_TGA_AUTHCOMMENT_STRING: - return iClipString(ilStates[ilCurrentPos].ilTgaAuthComment, 80); - case IL_PNG_AUTHNAME_STRING: - return iClipString(ilStates[ilCurrentPos].ilPngAuthName, 255); - case IL_PNG_TITLE_STRING: - return iClipString(ilStates[ilCurrentPos].ilPngTitle, 255); - case IL_PNG_DESCRIPTION_STRING: - return iClipString(ilStates[ilCurrentPos].ilPngDescription, 255); - - //changed 2003-08-31...here was a serious copy and paste bug ;-) - case IL_TIF_DESCRIPTION_STRING: - return iClipString(ilStates[ilCurrentPos].ilTifDescription, 255); - case IL_TIF_HOSTCOMPUTER_STRING: - return iClipString(ilStates[ilCurrentPos].ilTifHostComputer, 255); - case IL_TIF_DOCUMENTNAME_STRING: - return iClipString(ilStates[ilCurrentPos].ilTifDocumentName, 255); - case IL_TIF_AUTHNAME_STRING: - return iClipString(ilStates[ilCurrentPos].ilTifAuthName, 255); - case IL_CHEAD_HEADER_STRING: - return iClipString(ilStates[ilCurrentPos].ilCHeader, 32); - default: - ilSetError(IL_INVALID_ENUM); - } - return NULL; -} - - -//! Enables a mode -ILboolean ILAPIENTRY ilEnable(ILenum Mode) -{ - return ilAble(Mode, IL_TRUE); -} - - -//! Disables a mode -ILboolean ILAPIENTRY ilDisable(ILenum Mode) -{ - return ilAble(Mode, IL_FALSE); -} - - -// Internal function that sets the Mode equal to Flag -ILboolean ilAble(ILenum Mode, ILboolean Flag) -{ - switch (Mode) - { - case IL_ORIGIN_SET: - ilStates[ilCurrentPos].ilOriginSet = Flag; - break; - case IL_FORMAT_SET: - ilStates[ilCurrentPos].ilFormatSet = Flag; - break; - case IL_TYPE_SET: - ilStates[ilCurrentPos].ilTypeSet = Flag; - break; - case IL_FILE_OVERWRITE: - ilStates[ilCurrentPos].ilOverWriteFiles = Flag; - break; - case IL_CONV_PAL: - ilStates[ilCurrentPos].ilAutoConvPal = Flag; - break; - case IL_DEFAULT_ON_FAIL: - ilStates[ilCurrentPos].ilDefaultOnFail = Flag; - break; - case IL_USE_KEY_COLOUR: - ilStates[ilCurrentPos].ilUseKeyColour = Flag; - break; - case IL_SAVE_INTERLACED: - ilStates[ilCurrentPos].ilInterlace = Flag; - break; - - default: - ilSetError(IL_INVALID_ENUM); - return IL_FALSE; - } - - return IL_TRUE; -} - - -//! Checks whether the mode is enabled. -ILboolean ILAPIENTRY ilIsEnabled(ILenum Mode) -{ - switch (Mode) - { - case IL_ORIGIN_SET: - return ilStates[ilCurrentPos].ilOriginSet; - case IL_FORMAT_SET: - return ilStates[ilCurrentPos].ilFormatSet; - case IL_TYPE_SET: - return ilStates[ilCurrentPos].ilTypeSet; - case IL_FILE_OVERWRITE: - return ilStates[ilCurrentPos].ilOverWriteFiles; - case IL_CONV_PAL: - return ilStates[ilCurrentPos].ilAutoConvPal; - case IL_DEFAULT_ON_FAIL: - return ilStates[ilCurrentPos].ilDefaultOnFail; - case IL_USE_KEY_COLOUR: - return ilStates[ilCurrentPos].ilUseKeyColour; - - default: - ilSetError(IL_INVALID_ENUM); - } - - return IL_FALSE; -} - - -//! Checks whether the mode is disabled. -ILboolean ILAPIENTRY ilIsDisabled(ILenum Mode) -{ - return !ilIsEnabled(Mode); -} - - -//! Sets Param equal to the current value of the Mode -ILvoid ILAPIENTRY ilGetBooleanv(ILenum Mode, ILboolean *Param) -{ - if (Param == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - *Param = ilGetInteger(Mode); - - return; -} - - -//! Returns the current value of the Mode -ILboolean ILAPIENTRY ilGetBoolean(ILenum Mode) -{ - ILboolean Temp; - Temp = IL_FALSE; - ilGetBooleanv(Mode, &Temp); - return Temp; -} - - -ILimage *iGetBaseImage(void); - -ILuint iGetActiveNum(ILenum Type) -{ - ILimage *BaseImage; - ILuint Num = 0; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return 0; - } - - BaseImage = iGetBaseImage(); - - if (BaseImage == iCurImage) - return 0; - - switch (Type) - { - case IL_ACTIVE_IMAGE: - BaseImage = BaseImage->Next; - break; - case IL_ACTIVE_MIPMAP: - BaseImage = BaseImage->Mipmaps; - break; - case IL_ACTIVE_LAYER: - BaseImage = BaseImage->Layers; - break; - } - - do { - if (BaseImage == NULL) - return 0; - Num++; - if (BaseImage == iCurImage) - return Num; - } while ((BaseImage = BaseImage->Next)); - - //ilSetError(IL_ILLEGAL_OPERATION); - - return 0; -} - - -//! Sets Param equal to the current value of the Mode -ILvoid ILAPIENTRY ilGetIntegerv(ILenum Mode, ILint *Param) { - if (Param == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - *Param = 0; - - switch (Mode) { - // Integer values - case IL_COMPRESS_MODE: - *Param = ilStates[ilCurrentPos].ilCompression; - break; - case IL_CUR_IMAGE: - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - break; - } - *Param = ilGetCurName(); - break; - case IL_FORMAT_MODE: - *Param = ilStates[ilCurrentPos].ilFormatMode; - break; - case IL_INTERLACE_MODE: - *Param = ilStates[ilCurrentPos].ilInterlace; - break; - case IL_KEEP_DXTC_DATA: - *Param = ilStates[ilCurrentPos].ilKeepDxtcData; - break; - case IL_ORIGIN_MODE: - *Param = ilStates[ilCurrentPos].ilOriginMode; - break; - case IL_MAX_QUANT_INDEXS: - *Param = ilStates[ilCurrentPos].ilQuantMaxIndexs; - break; - case IL_NEU_QUANT_SAMPLE: - *Param = ilStates[ilCurrentPos].ilNeuSample; - break; - case IL_QUANTIZATION_MODE: - *Param = ilStates[ilCurrentPos].ilQuantMode; - break; - case IL_TYPE_MODE: - *Param = ilStates[ilCurrentPos].ilTypeMode; - break; - case IL_VERSION_NUM: - *Param = IL_VERSION; - break; - - // Image specific values - case IL_ACTIVE_IMAGE: - case IL_ACTIVE_MIPMAP: - case IL_ACTIVE_LAYER: - *Param = iGetActiveNum(Mode); - break; - - // Format-specific values - case IL_BMP_RLE: - *Param = ilStates[ilCurrentPos].ilBmpRle; - break; - case IL_DXTC_FORMAT: - *Param = ilStates[ilCurrentPos].ilDxtcFormat; - break; - case IL_JPG_QUALITY: - *Param = ilStates[ilCurrentPos].ilJpgQuality; - break; - case IL_JPG_SAVE_FORMAT: - *Param = ilStates[ilCurrentPos].ilJpgFormat; - break; - case IL_PCD_PICNUM: - *Param = ilStates[ilCurrentPos].ilPcdPicNum; - break; - case IL_PNG_ALPHA_INDEX: - *Param = ilStates[ilCurrentPos].ilPngAlphaIndex; - break; - case IL_PNG_INTERLACE: - *Param = ilStates[ilCurrentPos].ilPngInterlace; - break; - case IL_SGI_RLE: - *Param = ilStates[ilCurrentPos].ilSgiRle; - break; - case IL_TGA_CREATE_STAMP: - *Param = ilStates[ilCurrentPos].ilTgaCreateStamp; - break; - case IL_TGA_RLE: - *Param = ilStates[ilCurrentPos].ilTgaRle; - break; - - // Boolean values - case IL_CONV_PAL: - *Param = ilStates[ilCurrentPos].ilAutoConvPal; - break; - case IL_DEFAULT_ON_FAIL: - *Param = ilStates[ilCurrentPos].ilDefaultOnFail; - break; - case IL_FILE_MODE: - *Param = ilStates[ilCurrentPos].ilOverWriteFiles; - break; - case IL_FORMAT_SET: - *Param = ilStates[ilCurrentPos].ilFormatSet; - break; - case IL_ORIGIN_SET: - *Param = ilStates[ilCurrentPos].ilOriginSet; - break; - case IL_TYPE_SET: - *Param = ilStates[ilCurrentPos].ilTypeSet; - break; - case IL_USE_KEY_COLOUR: - *Param = ilStates[ilCurrentPos].ilUseKeyColour; - break; - - default: - iGetIntegervImage(iCurImage, Mode, Param); - } - - return; -} - -//@TODO rename to ilGetImageIntegerv for 1.6.9 and make it public -//! Sets Param equal to the current value of the Mode -ILvoid ILAPIENTRY iGetIntegervImage(ILimage *Image, ILenum Mode, ILint *Param) { - ILimage *SubImage; - if (Image == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return; - } - if (Param == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - *Param = 0; - switch (Mode) - { - case IL_DXTC_DATA_FORMAT: - if (Image->DxtcData == NULL || Image->DxtcSize == 0) { - *Param = IL_DXT_NO_COMP; - break; - } - *Param = Image->DxtcFormat; - break; - //// - case IL_IMAGE_BITS_PER_PIXEL: - //changed 20040610 to channel count (Bpp) times Byte per channel - *Param = (Image->Bpp << 3)*Image->Bpc; - break; - case IL_IMAGE_BYTES_PER_PIXEL: - //changed 20040610 to channel count (Bpp) times Byte per channel - *Param = Image->Bpp*Image->Bpc; - break; - case IL_IMAGE_BPC: - *Param = Image->Bpc; - break; - case IL_IMAGE_CHANNELS: - *Param = Image->Bpp; - break; - case IL_IMAGE_CUBEFLAGS: - *Param = Image->CubeFlags; - break; - case IL_IMAGE_DEPTH: - *Param = Image->Depth; - break; - case IL_IMAGE_DURATION: - *Param = Image->Duration; - break; - case IL_IMAGE_FORMAT: - *Param = Image->Format; - break; - case IL_IMAGE_HEIGHT: - *Param = Image->Height; - break; - case IL_IMAGE_SIZE_OF_DATA: - *Param = Image->SizeOfData; - - break; - case IL_IMAGE_OFFX: - *Param = Image->OffX; - break; - case IL_IMAGE_OFFY: - *Param = Image->OffY; - break; - case IL_IMAGE_ORIGIN: - *Param = Image->Origin; - break; - case IL_IMAGE_PLANESIZE: - *Param = Image->SizeOfPlane; - break; - case IL_IMAGE_TYPE: - *Param = Image->Type; - break; - case IL_IMAGE_WIDTH: - *Param = Image->Width; - break; - case IL_NUM_IMAGES: - for(SubImage = Image->Next; SubImage; SubImage = SubImage->Next) - (*Param)++; - break; - case IL_NUM_LAYERS: - for(SubImage = Image->Layers; SubImage; SubImage = SubImage->Next) - (*Param)++; - break; - case IL_NUM_MIPMAPS: - for(SubImage = Image->Mipmaps; SubImage; SubImage = SubImage->Next) - (*Param)++; - break; - - case IL_PALETTE_TYPE: - *Param = Image->Pal.PalType; - break; - case IL_PALETTE_BPP: - *Param = ilGetBppPal(Image->Pal.PalType); - break; - case IL_PALETTE_NUM_COLS: - if (!Image->Pal.Palette || !Image->Pal.PalSize || Image->Pal.PalType == -IL_PAL_NONE) - *Param = 0; - else - *Param = Image->Pal.PalSize / ilGetBppPal(Image->Pal.PalType); - break; - case IL_PALETTE_BASE_TYPE: - switch (Image->Pal.PalType) - { - case IL_PAL_RGB24: - *Param = IL_RGB; - case IL_PAL_RGB32: - *Param = IL_RGBA; // Not sure - case IL_PAL_RGBA32: - *Param = IL_RGBA; - case IL_PAL_BGR24: - *Param = IL_BGR; - case IL_PAL_BGR32: - *Param = IL_BGRA; // Not sure - case IL_PAL_BGRA32: - *Param = IL_BGRA; - } - break; - default: - ilSetError(IL_INVALID_ENUM); - } -} - - - -//! Returns the current value of the Mode -ILint ILAPIENTRY ilGetInteger(ILenum Mode) -{ - ILint Temp; - Temp = 0; - ilGetIntegerv(Mode, &Temp); - return Temp; -} - - -//! Sets the default origin to be used. -ILboolean ILAPIENTRY ilOriginFunc(ILenum Mode) -{ - switch (Mode) - { - case IL_ORIGIN_LOWER_LEFT: - case IL_ORIGIN_UPPER_LEFT: - ilStates[ilCurrentPos].ilOriginMode = Mode; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - return IL_TRUE; -} - - -//! Sets the default format to be used. -ILboolean ILAPIENTRY ilFormatFunc(ILenum Mode) -{ - switch (Mode) - { - //case IL_COLOUR_INDEX: - case IL_RGB: - case IL_RGBA: - case IL_BGR: - case IL_BGRA: - case IL_LUMINANCE: - case IL_LUMINANCE_ALPHA: - ilStates[ilCurrentPos].ilFormatMode = Mode; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - return IL_TRUE; -} - - -//! Sets the default type to be used. -ILboolean ILAPIENTRY ilTypeFunc(ILenum Mode) -{ - switch (Mode) - { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - case IL_SHORT: - case IL_UNSIGNED_SHORT: - case IL_INT: - case IL_UNSIGNED_INT: - case IL_FLOAT: - case IL_DOUBLE: - ilStates[ilCurrentPos].ilTypeMode = Mode; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - return IL_TRUE; -} - - -ILboolean ILAPIENTRY ilCompressFunc(ILenum Mode) -{ - switch (Mode) - { - case IL_COMPRESS_NONE: - case IL_COMPRESS_RLE: - //case IL_COMPRESS_LZO: - case IL_COMPRESS_ZLIB: - ilStates[ilCurrentPos].ilCompression = Mode; - break; - default: - ilSetError(IL_INVALID_PARAM); - return IL_FALSE; - } - return IL_TRUE; -} - - -//! Pushes the states indicated by Bits onto the state stack -ILvoid ILAPIENTRY ilPushAttrib(ILuint Bits) -{ - // Should we check here to see if ilCurrentPos is negative? - - if (ilCurrentPos >= IL_ATTRIB_STACK_MAX - 1) { - ilCurrentPos = IL_ATTRIB_STACK_MAX - 1; - ilSetError(IL_STACK_OVERFLOW); - return; - } - - ilCurrentPos++; - - // memcpy(&ilStates[ilCurrentPos], &ilStates[ilCurrentPos - 1], sizeof(IL_STATES)); - - ilDefaultStates(); - - if (Bits & IL_ORIGIN_BIT) { - ilStates[ilCurrentPos].ilOriginMode = ilStates[ilCurrentPos-1].ilOriginMode; - ilStates[ilCurrentPos].ilOriginSet = ilStates[ilCurrentPos-1].ilOriginSet; - } - if (Bits & IL_FORMAT_BIT) { - ilStates[ilCurrentPos].ilFormatMode = ilStates[ilCurrentPos-1].ilFormatMode; - ilStates[ilCurrentPos].ilFormatSet = ilStates[ilCurrentPos-1].ilFormatSet; - } - if (Bits & IL_TYPE_BIT) { - ilStates[ilCurrentPos].ilTypeMode = ilStates[ilCurrentPos-1].ilTypeMode; - ilStates[ilCurrentPos].ilTypeSet = ilStates[ilCurrentPos-1].ilTypeSet; - } - if (Bits & IL_FILE_BIT) { - ilStates[ilCurrentPos].ilOverWriteFiles = ilStates[ilCurrentPos-1].ilOverWriteFiles; - } - if (Bits & IL_PAL_BIT) { - ilStates[ilCurrentPos].ilAutoConvPal = ilStates[ilCurrentPos-1].ilAutoConvPal; - } - if (Bits & IL_LOADFAIL_BIT) { - ilStates[ilCurrentPos].ilDefaultOnFail = ilStates[ilCurrentPos-1].ilDefaultOnFail; - } - if (Bits & IL_COMPRESS_BIT) { - ilStates[ilCurrentPos].ilCompression = ilStates[ilCurrentPos-1].ilCompression; - } - if (Bits & IL_FORMAT_SPECIFIC_BIT) { - ilStates[ilCurrentPos].ilTgaCreateStamp = ilStates[ilCurrentPos-1].ilTgaCreateStamp; - ilStates[ilCurrentPos].ilJpgQuality = ilStates[ilCurrentPos-1].ilJpgQuality; - ilStates[ilCurrentPos].ilPngInterlace = ilStates[ilCurrentPos-1].ilPngInterlace; - ilStates[ilCurrentPos].ilTgaRle = ilStates[ilCurrentPos-1].ilTgaRle; - ilStates[ilCurrentPos].ilBmpRle = ilStates[ilCurrentPos-1].ilBmpRle; - ilStates[ilCurrentPos].ilSgiRle = ilStates[ilCurrentPos-1].ilSgiRle; - ilStates[ilCurrentPos].ilJpgFormat = ilStates[ilCurrentPos-1].ilJpgFormat; - ilStates[ilCurrentPos].ilDxtcFormat = ilStates[ilCurrentPos-1].ilDxtcFormat; - ilStates[ilCurrentPos].ilPcdPicNum = ilStates[ilCurrentPos-1].ilPcdPicNum; - - ilStates[ilCurrentPos].ilPngAlphaIndex = ilStates[ilCurrentPos-1].ilPngAlphaIndex; - - // Strings - if (ilStates[ilCurrentPos].ilTgaId) - ifree(ilStates[ilCurrentPos].ilTgaId); - if (ilStates[ilCurrentPos].ilTgaAuthName) - ifree(ilStates[ilCurrentPos].ilTgaAuthName); - if (ilStates[ilCurrentPos].ilTgaAuthComment) - ifree(ilStates[ilCurrentPos].ilTgaAuthComment); - if (ilStates[ilCurrentPos].ilPngAuthName) - ifree(ilStates[ilCurrentPos].ilPngAuthName); - if (ilStates[ilCurrentPos].ilPngTitle) - ifree(ilStates[ilCurrentPos].ilPngTitle); - if (ilStates[ilCurrentPos].ilPngDescription) - ifree(ilStates[ilCurrentPos].ilPngDescription); - - //2003-09-01: added tif strings - if (ilStates[ilCurrentPos].ilTifDescription) - ifree(ilStates[ilCurrentPos].ilTifDescription); - if (ilStates[ilCurrentPos].ilTifHostComputer) - ifree(ilStates[ilCurrentPos].ilTifHostComputer); - if (ilStates[ilCurrentPos].ilTifDocumentName) - ifree(ilStates[ilCurrentPos].ilTifDocumentName); - if (ilStates[ilCurrentPos].ilTifAuthName) - ifree(ilStates[ilCurrentPos].ilTifAuthName); - - if (ilStates[ilCurrentPos].ilCHeader) - ifree(ilStates[ilCurrentPos].ilCHeader); - - ilStates[ilCurrentPos].ilTgaId = ilStrDup(ilStates[ilCurrentPos-1].ilTgaId); - ilStates[ilCurrentPos].ilTgaAuthName = ilStrDup(ilStates[ilCurrentPos-1].ilTgaAuthName); - ilStates[ilCurrentPos].ilTgaAuthComment = ilStrDup(ilStates[ilCurrentPos-1].ilTgaAuthComment); - ilStates[ilCurrentPos].ilPngAuthName = ilStrDup(ilStates[ilCurrentPos-1].ilPngAuthName); - ilStates[ilCurrentPos].ilPngTitle = ilStrDup(ilStates[ilCurrentPos-1].ilPngTitle); - ilStates[ilCurrentPos].ilPngDescription = ilStrDup(ilStates[ilCurrentPos-1].ilPngDescription); - - //2003-09-01: added tif strings - ilStates[ilCurrentPos].ilTifDescription = ilStrDup(ilStates[ilCurrentPos-1].ilTifDescription); - ilStates[ilCurrentPos].ilTifHostComputer = ilStrDup(ilStates[ilCurrentPos-1].ilTifHostComputer); - ilStates[ilCurrentPos].ilTifDocumentName = ilStrDup(ilStates[ilCurrentPos-1].ilTifDocumentName); - ilStates[ilCurrentPos].ilTifAuthName = ilStrDup(ilStates[ilCurrentPos-1].ilTifAuthName); - - ilStates[ilCurrentPos].ilCHeader = ilStrDup(ilStates[ilCurrentPos-1].ilCHeader); - } - - return; -} - - -// @TODO: Find out how this affects strings!!! - -//! Pops the last entry off the state stack into the current states -ILvoid ILAPIENTRY ilPopAttrib() -{ - if (ilCurrentPos <= 0) { - ilCurrentPos = 0; - ilSetError(IL_STACK_UNDERFLOW); - return; - } - - // Should we check here to see if ilCurrentPos is too large? - ilCurrentPos--; - - return; -} - - -//! Specifies implementation-dependent performance hints -ILvoid ILAPIENTRY ilHint(ILenum Target, ILenum Mode) -{ - switch (Target) - { - case IL_MEM_SPEED_HINT: - switch (Mode) - { - case IL_FASTEST: - ilHints.MemVsSpeedHint = Mode; - break; - case IL_LESS_MEM: - ilHints.MemVsSpeedHint = Mode; - break; - case IL_DONT_CARE: - ilHints.MemVsSpeedHint = IL_FASTEST; - break; - default: - ilSetError(IL_INVALID_ENUM); - return; - } - break; - - case IL_COMPRESSION_HINT: - switch (Mode) - { - case IL_USE_COMPRESSION: - ilHints.CompressHint = Mode; - break; - case IL_NO_COMPRESSION: - ilHints.CompressHint = Mode; - break; - case IL_DONT_CARE: - ilHints.CompressHint = IL_NO_COMPRESSION; - break; - default: - ilSetError(IL_INVALID_ENUM); - return; - } - break; - - - default: - ilSetError(IL_INVALID_ENUM); - return; - } - - return; -} - - -ILenum iGetHint(ILenum Target) -{ - switch (Target) - { - case IL_MEM_SPEED_HINT: - return ilHints.MemVsSpeedHint; - case IL_COMPRESSION_HINT: - return ilHints.CompressHint; - default: - ilSetError(IL_INTERNAL_ERROR); - return 0; - } -} - - -ILvoid ILAPIENTRY ilSetString(ILenum Mode, const char *String) -{ - if (String == NULL) { - ilSetError(IL_INVALID_PARAM); - return; - } - - switch (Mode) - { - case IL_TGA_ID_STRING: - if (ilStates[ilCurrentPos].ilTgaId) - ifree(ilStates[ilCurrentPos].ilTgaId); - ilStates[ilCurrentPos].ilTgaId = ilStrDup(String); - break; - case IL_TGA_AUTHNAME_STRING: - if (ilStates[ilCurrentPos].ilTgaAuthName) - ifree(ilStates[ilCurrentPos].ilTgaAuthName); - ilStates[ilCurrentPos].ilTgaAuthName = ilStrDup(String); - break; - case IL_TGA_AUTHCOMMENT_STRING: - if (ilStates[ilCurrentPos].ilTgaAuthComment) - ifree(ilStates[ilCurrentPos].ilTgaAuthComment); - ilStates[ilCurrentPos].ilTgaAuthComment = ilStrDup(String); - break; - case IL_PNG_AUTHNAME_STRING: - if (ilStates[ilCurrentPos].ilPngAuthName) - ifree(ilStates[ilCurrentPos].ilPngAuthName); - ilStates[ilCurrentPos].ilPngAuthName = ilStrDup(String); - break; - case IL_PNG_TITLE_STRING: - if (ilStates[ilCurrentPos].ilPngTitle) - ifree(ilStates[ilCurrentPos].ilPngTitle); - ilStates[ilCurrentPos].ilPngTitle = ilStrDup(String); - break; - case IL_PNG_DESCRIPTION_STRING: - if (ilStates[ilCurrentPos].ilPngDescription) - ifree(ilStates[ilCurrentPos].ilPngDescription); - ilStates[ilCurrentPos].ilPngDescription = ilStrDup(String); - break; - - //2003-09-01: added tif strings - case IL_TIF_DESCRIPTION_STRING: - if (ilStates[ilCurrentPos].ilTifDescription) - ifree(ilStates[ilCurrentPos].ilTifDescription); - ilStates[ilCurrentPos].ilTifDescription = ilStrDup(String); - break; - case IL_TIF_HOSTCOMPUTER_STRING: - if (ilStates[ilCurrentPos].ilTifHostComputer) - ifree(ilStates[ilCurrentPos].ilTifHostComputer); - ilStates[ilCurrentPos].ilTifHostComputer = ilStrDup(String); - break; - case IL_TIF_DOCUMENTNAME_STRING: - if (ilStates[ilCurrentPos].ilTifDocumentName) - ifree(ilStates[ilCurrentPos].ilTifDocumentName); - ilStates[ilCurrentPos].ilTifDocumentName = ilStrDup(String); - break; - case IL_TIF_AUTHNAME_STRING: - if (ilStates[ilCurrentPos].ilTifAuthName) - ifree(ilStates[ilCurrentPos].ilTifAuthName); - ilStates[ilCurrentPos].ilTifAuthName = ilStrDup(String); - break; - - case IL_CHEAD_HEADER_STRING: - if (ilStates[ilCurrentPos].ilCHeader) - ifree(ilStates[ilCurrentPos].ilCHeader); - ilStates[ilCurrentPos].ilCHeader = ilStrDup(String); - break; - - - - default: - ilSetError(IL_INVALID_ENUM); - } - - - return; -} - - -ILvoid ILAPIENTRY ilSetInteger(ILenum Mode, ILint Param) -{ - switch (Mode) - { - // Integer values - case IL_FORMAT_MODE: - ilFormatFunc(Param); - return; - case IL_KEEP_DXTC_DATA: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilKeepDxtcData = Param; - return; - } - break; - case IL_MAX_QUANT_INDEXS: - if (Param >= 2 && Param <= 256) { - ilStates[ilCurrentPos].ilQuantMaxIndexs = Param; - return; - } - break; - case IL_NEU_QUANT_SAMPLE: - if (Param >= 1 && Param <= 30) { - ilStates[ilCurrentPos].ilNeuSample = Param; - return; - } - break; - case IL_ORIGIN_MODE: - ilOriginFunc(Param); - return; - case IL_QUANTIZATION_MODE: - if (Param == IL_WU_QUANT || Param == IL_NEU_QUANT) { - ilStates[ilCurrentPos].ilQuantMode = Param; - return; - } - break; - case IL_TYPE_MODE: - ilTypeFunc(Param); - return; - - // Image specific values - case IL_IMAGE_DURATION: - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - break; - } - iCurImage->Duration = Param; - return; - case IL_IMAGE_OFFX: - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - break; - } - iCurImage->OffX = Param; - return; - case IL_IMAGE_OFFY: - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - break; - } - iCurImage->OffY = Param; - return; - case IL_IMAGE_CUBEFLAGS: - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - break; - } - iCurImage->CubeFlags = Param; - break; - - // Format specific values - case IL_BMP_RLE: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilBmpRle = Param; - return; - } - break; - case IL_DXTC_FORMAT: - if (Param >= IL_DXT1 || Param <= IL_DXT5) { - ilStates[ilCurrentPos].ilDxtcFormat = Param; - return; - } - break; - case IL_JPG_SAVE_FORMAT: - if (Param == IL_JFIF || Param == IL_EXIF) { - ilStates[ilCurrentPos].ilJpgFormat = Param; - return; - } - break; - case IL_JPG_QUALITY: - if (Param >= 0 && Param <= 99) { - ilStates[ilCurrentPos].ilJpgQuality = Param; - return; - } - break; - case IL_PNG_INTERLACE: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilPngInterlace = Param; - return; - } - break; - case IL_PCD_PICNUM: - if (Param >= 0 || Param <= 2) { - ilStates[ilCurrentPos].ilPcdPicNum = Param; - return; - } - break; - case IL_PNG_ALPHA_INDEX: - if (Param >= -1 || Param <= 255) { - ilStates[ilCurrentPos].ilPngAlphaIndex=Param; - return; - } - break; - case IL_SGI_RLE: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilSgiRle = Param; - return; - } - break; - case IL_TGA_CREATE_STAMP: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilTgaCreateStamp = Param; - return; - } - break; - case IL_TGA_RLE: - if (Param == IL_FALSE || Param == IL_TRUE) { - ilStates[ilCurrentPos].ilTgaRle = Param; - return; - } - break; - - default: - ilSetError(IL_INVALID_ENUM); - return; - } - - ilSetError(IL_INVALID_PARAM); // Parameter not in valid bounds. - return; -} - - - -ILint iGetInt(ILenum Mode) -{ - //like ilGetInteger(), but sets another error on failure - - //call ilGetIntegerv() for more robust code - ILenum err; - ILint r = -1; - - ilGetIntegerv(Mode, &r); - - //check if an error occured, set another error - err = ilGetError(); - if (r == -1 && err == IL_INVALID_ENUM) - ilSetError(IL_INTERNAL_ERROR); - else - ilSetError(err); //restore error - - return r; -} diff --git a/win32/devil/src/il_targa.c b/win32/devil/src/il_targa.c deleted file mode 100644 index 0686d84b1..000000000 --- a/win32/devil/src/il_targa.c +++ /dev/null @@ -1,893 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/22/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_targa.c -// -// Description: Reads from and writes to a targa (.tga) file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_TGA -#include "il_targa.h" -//#include // for ilMakeString() -#include -#include "il_manip.h" -#include "il_bits.h" - -#ifdef DJGPP -#include -#endif - - -//! Checks if the file specified in FileName is a valid Targa file. -ILboolean ilIsValidTga(ILconst_string FileName) -{ - ILHANDLE TargaFile; - ILboolean bTarga = IL_FALSE; - - if (!iCheckExtension(FileName, IL_TEXT("tga")) && - !iCheckExtension(FileName, IL_TEXT("vda")) && - !iCheckExtension(FileName, IL_TEXT("icb")) && - !iCheckExtension(FileName, IL_TEXT("vst"))) { - ilSetError(IL_INVALID_EXTENSION); - return bTarga; - } - - TargaFile = iopenr(FileName); - if (TargaFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bTarga; - } - - bTarga = ilIsValidTgaF(TargaFile); - icloser(TargaFile); - - return bTarga; -} - - -//! Checks if the ILHANDLE contains a valid Targa file at the current position. -ILboolean ilIsValidTgaF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iIsValidTarga(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Checks if Lump is a valid Targa lump. -ILboolean ilIsValidTgaL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iIsValidTarga(); -} - - -// Internal function used to get the Targa header from the current file. -ILboolean iGetTgaHead(TARGAHEAD *Header) -{ - Header->IDLen = (ILubyte)igetc(); - Header->ColMapPresent = (ILubyte)igetc(); - Header->ImageType = (ILubyte)igetc(); - Header->FirstEntry = GetLittleShort(); - Header->ColMapLen = GetLittleShort(); - Header->ColMapEntSize = (ILubyte)igetc(); - - Header->OriginX = GetLittleShort(); - Header->OriginY = GetLittleShort(); - Header->Width = GetLittleUShort(); - Header->Height = GetLittleUShort(); - Header->Bpp = (ILubyte)igetc(); - Header->ImageDesc = (ILubyte)igetc(); - - return IL_TRUE; -} - - -// Internal function to get the header and check it. -ILboolean iIsValidTarga() -{ - TARGAHEAD Head; - - if (!iGetTgaHead(&Head)) - return IL_FALSE; - iseek(-(ILint)sizeof(TARGAHEAD), IL_SEEK_CUR); - - return iCheckTarga(&Head); -} - - -// Internal function used to check if the HEADER is a valid Targa header. -ILboolean iCheckTarga(TARGAHEAD *Header) -{ - if (Header->Width == 0 || Header->Height == 0) - return IL_FALSE; - if (Header->Bpp != 8 && Header->Bpp != 15 && Header->Bpp != 16 - && Header->Bpp != 24 && Header->Bpp != 32) - return IL_FALSE; - if (Header->ImageDesc & BIT_4) // Supposed to be set to 0 - return IL_FALSE; - - // check type (added 20040218) - if(Header->ImageType != TGA_NO_DATA - && Header->ImageType != TGA_COLMAP_UNCOMP - && Header->ImageType != TGA_UNMAP_UNCOMP - && Header->ImageType != TGA_BW_UNCOMP - && Header->ImageType != TGA_COLMAP_COMP - && Header->ImageType != TGA_UNMAP_COMP - && Header->ImageType != TGA_BW_COMP) - return IL_FALSE; - - // Doesn't work well with the bitshift so change it. - if (Header->Bpp == 15) - Header->Bpp = 16; - - return IL_TRUE; -} - - -//! Reads a Targa file -ILboolean ilLoadTarga(ILconst_string FileName) -{ - ILHANDLE TargaFile; - ILboolean bTarga = IL_FALSE; - - TargaFile = iopenr(FileName); - if (TargaFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bTarga; - } - - bTarga = ilLoadTargaF(TargaFile); - icloser(TargaFile); - - return bTarga; -} - - -//! Reads an already-opened Targa file -ILboolean ilLoadTargaF(ILHANDLE File) { - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadTargaInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a Targa -ILboolean ilLoadTargaL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadTargaInternal(); -} - - -// Internal function used to load the Targa. -ILboolean iLoadTargaInternal() -{ - TARGAHEAD Header; - ILboolean bTarga; - ILenum iOrigin; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (!iGetTgaHead(&Header)) - return IL_FALSE; - if (!iCheckTarga(&Header)) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - switch (Header.ImageType) - { - case TGA_NO_DATA: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - case TGA_COLMAP_UNCOMP: - case TGA_COLMAP_COMP: - bTarga = iReadColMapTga(&Header); - break; - case TGA_UNMAP_UNCOMP: - case TGA_UNMAP_COMP: - bTarga = iReadUnmapTga(&Header); - break; - case TGA_BW_UNCOMP: - case TGA_BW_COMP: - bTarga = iReadBwTga(&Header); - break; - default: - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - // @JASON Extra Code to manipulate the image depending on - // the Image Descriptor's origin bits. - iOrigin = Header.ImageDesc & IMAGEDESC_ORIGIN_MASK; - - switch (iOrigin) - { - case IMAGEDESC_TOPLEFT: - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - break; - - case IMAGEDESC_TOPRIGHT: - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - iMirror(); - break; - - case IMAGEDESC_BOTLEFT: - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - break; - - case IMAGEDESC_BOTRIGHT: - iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; - iMirror(); - break; - } - - ilFixImage(); - - return bTarga; -} - - -ILboolean iReadColMapTga(TARGAHEAD *Header) -{ - char ID[255]; - ILuint i; - ILushort Pixel; - - if (iread(ID, 1, Header->IDLen) != Header->IDLen) - return IL_FALSE; - - if (!ilTexImage(Header->Width, Header->Height, 1, (ILubyte)(Header->Bpp >> 3), 0, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize) - ifree(iCurImage->Pal.Palette); - - iCurImage->Format = IL_COLOUR_INDEX; - iCurImage->Pal.PalSize = Header->ColMapLen * (Header->ColMapEntSize >> 3); - - switch (Header->ColMapEntSize) - { - case 16: - iCurImage->Pal.PalType = IL_PAL_BGRA32; - iCurImage->Pal.PalSize = Header->ColMapLen * 4; - break; - case 24: - iCurImage->Pal.PalType = IL_PAL_BGR24; - break; - case 32: - iCurImage->Pal.PalType = IL_PAL_BGRA32; - break; - default: - // Should *never* reach here - ilSetError(IL_ILLEGAL_FILE_VALUE); - return IL_FALSE; - } - - iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); - if (iCurImage->Pal.Palette == NULL) { - return IL_FALSE; - } - - // Do we need to do something with FirstEntry? Like maybe: - // iread(Image->Pal + Targa->FirstEntry, 1, Image->Pal.PalSize); ?? - if (Header->ColMapEntSize != 16) - { - if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize) - return IL_FALSE; - } - else { - // 16 bit palette, so we have to break it up. - for (i = 0; i < iCurImage->Pal.PalSize; i += 4) - { - Pixel = GetBigUShort(); - if (ieof()) - return IL_FALSE; - iCurImage->Pal.Palette[3] = (Pixel & 0x8000) >> 12; - iCurImage->Pal.Palette[0] = (Pixel & 0xFC00) >> 7; - iCurImage->Pal.Palette[1] = (Pixel & 0x03E0) >> 2; - iCurImage->Pal.Palette[2] = (Pixel & 0x001F) << 3; - } - } - - if (Header->ImageType == TGA_COLMAP_COMP) - { - if (!iUncompressTgaData(iCurImage)) - { - return IL_FALSE; - } - } - else - { - if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) - { - return IL_FALSE; - } - } - - return IL_TRUE; -} - - -ILboolean iReadUnmapTga(TARGAHEAD *Header) -{ - ILubyte Bpp; - char ID[255]; - - if (iread(ID, 1, Header->IDLen) != Header->IDLen) - return IL_FALSE; - - /*if (Header->Bpp == 16) - Bpp = 3; - else*/ - Bpp = (ILubyte)(Header->Bpp >> 3); - - if (!ilTexImage(Header->Width, Header->Height, 1, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) - { - return IL_FALSE; - } - - switch (iCurImage->Bpp) - { - case 1: - iCurImage->Format = IL_COLOUR_INDEX; // wtf? How is this possible? - break; - case 2: // 16-bit is not supported directly! - //iCurImage->Format = IL_RGB5_A1; - /*iCurImage->Format = IL_RGBA; - iCurImage->Type = IL_UNSIGNED_SHORT_5_5_5_1_EXT;*/ - //iCurImage->Type = IL_UNSIGNED_SHORT_5_6_5_REV; - - // Remove? - //ilCloseImage(iCurImage); - //ilSetError(IL_FORMAT_NOT_SUPPORTED); - //return IL_FALSE; - - /*iCurImage->Bpp = 4; - iCurImage->Format = IL_BGRA; - iCurImage->Type = IL_UNSIGNED_SHORT_1_5_5_5_REV;*/ - - iCurImage->Format = IL_BGR; - - break; - case 3: - iCurImage->Format = IL_BGR; - break; - case 4: - iCurImage->Format = IL_BGRA; - break; - default: - ilSetError(IL_INVALID_VALUE); - return IL_FALSE; - } - - - // @TODO: Determine this: - // We assume that no palette is present, but it's possible... - // Should we mess with it or not? - - - if (Header->ImageType == TGA_UNMAP_COMP) { - if (!iUncompressTgaData(iCurImage)) { - return IL_FALSE; - } - } - else { - if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) { - return IL_FALSE; - } - } - - // Go ahead and expand it to 24-bit. - if (Header->Bpp == 16) { - if (!i16BitTarga(iCurImage)) - return IL_FALSE; - return IL_TRUE; - } - - return IL_TRUE; -} - - -ILboolean iReadBwTga(TARGAHEAD *Header) -{ - char ID[255]; - - if (iread(ID, 1, Header->IDLen) != Header->IDLen) - return IL_FALSE; - - // We assume that no palette is present, but it's possible... - // Should we mess with it or not? - - if (!ilTexImage(Header->Width, Header->Height, 1, (ILubyte)(Header->Bpp >> 3), IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL)) { - return IL_FALSE; - } - - if (Header->ImageType == TGA_BW_COMP) { - if (!iUncompressTgaData(iCurImage)) { - return IL_FALSE; - } - } - else { - if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) { - return IL_FALSE; - } - } - - return IL_TRUE; -} - - -ILboolean iUncompressTgaData(ILimage *Image) -{ - ILuint BytesRead = 0, Size, RunLen, i; - ILubyte Header, Color[4]; - ILint c; - - Size = Image->Width * Image->Height * Image->Depth * Image->Bpp; - - if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) - iPreCache(iCurImage->SizeOfData / 2); - - while (BytesRead < Size) { - Header = (ILubyte)igetc(); - if (Header & BIT_7) { - ClearBits(Header, BIT_7); - if (iread(Color, 1, Image->Bpp) != Image->Bpp) { - iUnCache(); - return IL_FALSE; - } - RunLen = (Header+1) * Image->Bpp; - for (i = 0; i < RunLen; i += Image->Bpp) { - for (c = 0; c < Image->Bpp; c++) { - Image->Data[BytesRead+i+c] = Color[c]; - } - } - BytesRead += RunLen; - } - else { - RunLen = (Header+1) * Image->Bpp; - if (iread(Image->Data + BytesRead, 1, RunLen) != RunLen) { - iUnCache(); - return IL_FALSE; - } - BytesRead += RunLen; - } - } - - iUnCache(); - - return IL_TRUE; -} - - -// Pretty damn unoptimized -ILboolean i16BitTarga(ILimage *Image) -{ - ILushort *Temp1; - ILubyte *Data, *Temp2; - ILuint x, PixSize = Image->Width * Image->Height; - - Data = (ILubyte*)ialloc(Image->Width * Image->Height * 3); - Temp1 = (ILushort*)Image->Data; - Temp2 = Data; - - if (Data == NULL) - return IL_FALSE; - - for (x = 0; x < PixSize; x++) { - *Temp2++ = (*Temp1 & 0x001F) << 3; // Blue - *Temp2++ = (*Temp1 & 0x03E0) >> 2; // Green - *Temp2++ = (*Temp1 & 0x7C00) >> 7; // Red - - Temp1++; - - - /*s = *Temp; - s = SwapShort(s); - a = !!(s & BIT_15); - - s = s << 1; - - //if (a) { - SetBits(s, BIT_0); - //} - - //SetBits(s, BIT_15); - - *Temp++ = s;*/ - } - - if (!ilTexImage(Image->Width, Image->Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, Data)) { - ifree(Data); - return IL_FALSE; - } - - ifree(Data); - - return IL_TRUE; -} - - -//! Writes a Targa file -ILboolean ilSaveTarga(ILconst_string FileName) -{ - ILHANDLE TargaFile; - ILboolean bTarga = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } - - TargaFile = iopenw(FileName); - if (TargaFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bTarga; - } - - bTarga = ilSaveTargaF(TargaFile); - iclosew(TargaFile); - - return bTarga; -} - - -//! Writes a Targa to an already-opened file -ILboolean ilSaveTargaF(ILHANDLE File) -{ - iSetOutputFile(File); - return iSaveTargaInternal(); -} - - -//! Writes a Targa to a memory "lump" -ILboolean ilSaveTargaL(ILvoid *Lump, ILuint Size) -{ - iSetOutputLump(Lump, Size); - return iSaveTargaInternal(); -} - - -// Internal function used to save the Targa. -ILboolean iSaveTargaInternal() -{ - char *ID = iGetString(IL_TGA_ID_STRING); - char *AuthName = iGetString(IL_TGA_AUTHNAME_STRING); - char *AuthComment = iGetString(IL_TGA_AUTHCOMMENT_STRING); - ILubyte IDLen = 0, UsePal, Type, PalEntSize; - ILshort ColMapStart = 0, PalSize; - ILubyte Temp; - ILenum Format; - ILboolean Compress; - ILuint RleLen; - ILubyte *Rle; - ILpal *TempPal = NULL; - ILimage *TempImage = NULL; - ILuint ExtOffset, i; - char *Footer = "TRUEVISION-XFILE.\0"; - char *idString = "Developer's Image Library (DevIL)"; - ILuint Day, Month, Year, Hour, Minute, Second; - char *TempData; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - if (iGetInt(IL_TGA_RLE) == IL_TRUE) - Compress = IL_TRUE; - else - Compress = IL_FALSE; - - if (ID) - IDLen = (ILubyte)strlen(ID); - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) - UsePal = IL_TRUE; - else - UsePal = IL_FALSE; - - iwrite(&IDLen, sizeof(ILubyte), 1); - iwrite(&UsePal, sizeof(ILubyte), 1); - - Format = iCurImage->Format; - switch (Format) { - case IL_COLOUR_INDEX: - if (Compress) - Type = 9; - else - Type = 1; - break; - case IL_BGR: - case IL_BGRA: - if (Compress) - Type = 10; - else - Type = 2; - break; - case IL_RGB: - case IL_RGBA: - ilSwapColours(); - if (Compress) - Type = 10; - else - Type = 2; - break; - case IL_LUMINANCE: - if (Compress) - Type = 11; - else - Type = 3; - break; - default: - // Should convert the types here... - ilSetError(IL_INVALID_VALUE); - ifree(ID); - ifree(AuthName); - ifree(AuthComment); - return IL_FALSE; - } - - iwrite(&Type, sizeof(ILubyte), 1); - SaveLittleShort(ColMapStart); - - switch (iCurImage->Pal.PalType) - { - case IL_PAL_NONE: - PalSize = 0; - PalEntSize = 0; - break; - case IL_PAL_BGR24: - PalSize = (ILshort)(iCurImage->Pal.PalSize / 3); - PalEntSize = 24; - TempPal = &iCurImage->Pal; - break; - - case IL_PAL_RGB24: - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_BGR24); - if (TempPal == NULL) - return IL_FALSE; - PalSize = (ILshort)(TempPal->PalSize / 3); - PalEntSize = 24; - break; - default: - ilSetError(IL_INVALID_VALUE); - ifree(ID); - ifree(AuthName); - ifree(AuthComment); - PalSize = 0; - PalEntSize = 0; - return IL_FALSE; - } - SaveLittleShort(PalSize); - iwrite(&PalEntSize, sizeof(ILubyte), 1); - - if (iCurImage->Bpc > 1) { - TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE); - if (TempImage == NULL) { - ifree(ID); - ifree(AuthName); - ifree(AuthComment); - return IL_FALSE; - } - } - else { - TempImage = iCurImage; - } - - if (TempImage->Origin != IL_ORIGIN_LOWER_LEFT) - TempData = (char*)iGetFlipped(TempImage); - else - TempData = (char*)TempImage->Data; - - // Write out the origin stuff. - Temp = 0; - iwrite(&Temp, sizeof(ILshort), 1); - iwrite(&Temp, sizeof(ILshort), 1); - - Temp = iCurImage->Bpp << 3; // Changes to bits per pixel - SaveLittleUShort((ILushort)iCurImage->Width); - SaveLittleUShort((ILushort)iCurImage->Height); - iwrite(&Temp, sizeof(ILubyte), 1); - - // Still don't know what exactly this is for... - Temp = 0; - iwrite(&Temp, sizeof(ILubyte), 1); - iwrite(ID, sizeof(char), IDLen); - ifree(ID); - //iwrite(ID, sizeof(ILbyte), IDLen - sizeof(ILuint)); - //iwrite(&iCurImage->Depth, sizeof(ILuint), 1); - - // Write out the colormap - if (UsePal) - iwrite(TempPal->Palette, sizeof(ILubyte), TempPal->PalSize); - // else do nothing - - if (!Compress) - iwrite(TempData, sizeof(ILubyte), TempImage->SizeOfData); - else { - Rle = (ILubyte*)ialloc(TempImage->SizeOfData + TempImage->SizeOfData / 2 + 1); // max - if (Rle == NULL) { - ifree(AuthName); - ifree(AuthComment); - return IL_FALSE; - } - RleLen = ilRleCompress((unsigned char*)TempData, TempImage->Width, TempImage->Height, - TempImage->Depth, TempImage->Bpp, Rle, IL_TGACOMP, NULL); - - iwrite(Rle, 1, RleLen); - ifree(Rle); - } - - // Write the extension area. - ExtOffset = itellw(); - SaveLittleUShort(495); // Number of bytes in the extension area (TGA 2.0 spec) - iwrite(AuthName, 1, ilStrLen(AuthName)); - ipad(41 - ilStrLen(AuthName)); - iwrite(AuthComment, 1, ilStrLen(AuthComment)); - ipad(324 - ilStrLen(AuthComment)); - ifree(AuthName); - ifree(AuthComment); - - // Write time/date - iGetDateTime(&Month, &Day, &Year, &Hour, &Minute, &Second); - SaveLittleUShort((ILushort)Month); - SaveLittleUShort((ILushort)Day); - SaveLittleUShort((ILushort)Year); - SaveLittleUShort((ILushort)Hour); - SaveLittleUShort((ILushort)Minute); - SaveLittleUShort((ILushort)Second); - - for (i = 0; i < 6; i++) { // Time created - SaveLittleUShort(0); - } - for (i = 0; i < 41; i++) { // Job name/ID - iputc(0); - } - for (i = 0; i < 3; i++) { // Job time - SaveLittleUShort(0); - } - - iwrite(idString, 1, strlen(idString)); // Software ID - for (i = 0; i < 41 - strlen(idString); i++) { - iputc(0); - } - SaveLittleUShort(IL_VERSION); // Software version - iputc(' '); // Release letter (not beta anymore, so use a space) - - SaveLittleUInt(0); // Key colour - SaveLittleUInt(0); // Pixel aspect ratio - SaveLittleUInt(0); // Gamma correction offset - SaveLittleUInt(0); // Colour correction offset - SaveLittleUInt(0); // Postage stamp offset - SaveLittleUInt(0); // Scan line offset - iputc(3); // Attributes type - - // Write the footer. - SaveLittleUInt(ExtOffset); // No extension area - SaveLittleUInt(0); // No developer directory - iwrite(Footer, 1, strlen(Footer)); - - if (TempImage->Origin != IL_ORIGIN_LOWER_LEFT) { - ifree(TempData); - } - if (Format == IL_RGB || Format == IL_RGBA) { - ilSwapColours(); - } - - if (TempPal != &iCurImage->Pal && TempPal != NULL) { - ifree(TempPal->Palette); - ifree(TempPal); - } - - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - return IL_TRUE; -} - - -/*// Makes a neat string to go into the id field of the .tga -ILvoid iMakeString(char *Str) -{ - char *PSG = "Generated by Developer's Image Library: "; - char TimeStr[255]; - - time_t Time; - struct tm *CurTime; - - time(&Time); -#ifdef _WIN32 - _tzset(); -#endif - CurTime = localtime(&Time); - - strftime(TimeStr, 255 - strlen(PSG), "%#c (%z)", CurTime); - //strftime(TimeStr, 255 - strlen(PSG), "%C (%Z)", CurTime); - sprintf(Str, "%s%s", PSG, TimeStr); - - return; -}*/ - - -//changed name to iGetDateTime on 20031221 to fix bug 830196 -ILvoid iGetDateTime(ILuint *Month, ILuint *Day, ILuint *Yr, ILuint *Hr, ILuint *Min, ILuint *Sec) -{ -#ifdef DJGPP - struct date day; - struct time curtime; - - gettime(&curtime); - getdate(&day); - - *Month = day.da_mon; - *Day = day.da_day; - *Yr = day.da_year; - - *Hr = curtime.ti_hour; - *Min = curtime.ti_min; - *Sec = curtime.ti_sec; - - return; -#else - -#ifdef _WIN32 - SYSTEMTIME Time; - - GetSystemTime(&Time); - - *Month = Time.wMonth; - *Day = Time.wDay; - *Yr = Time.wYear; - - *Hr = Time.wHour; - *Min = Time.wMinute; - *Sec = Time.wSecond; - - return; -#else - - *Month = 0; - *Day = 0; - *Yr = 0; - - *Hr = 0; - *Min = 0; - *Sec = 0; - - return; -#endif -#endif -} - - -#endif//IL_NO_TGA diff --git a/win32/devil/src/il_tiff.c b/win32/devil/src/il_tiff.c deleted file mode 100644 index e553c5676..000000000 --- a/win32/devil/src/il_tiff.c +++ /dev/null @@ -1,1113 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 06/13/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_tiff.c -// -// Description: Tiff (.tif) functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_TIF - -#include "tiffio.h" - -#include -#include "il_manip.h" - -#define MAGIC_HEADER1 0x4949 -#define MAGIC_HEADER2 0x4D4D - - - -#ifdef _WIN32 - #if (defined(IL_USE_PRAGMA_LIBS)) - #if defined(_MSC_VER) || defined(__BORLANDC__) - #pragma comment(lib, "libtiff.lib") - #endif - #endif -#endif - - -/*----------------------------------------------------------------------------*/ - -// No need for a separate header -static ILboolean iLoadTiffInternal(void); -static char* iMakeString(void); -static TIFF* iTIFFOpen(char *Mode); -//static ILboolean iSaveTiffInternal(); - -static ILboolean iSaveTiffInternal(ILconst_string Filename); - -/*----------------------------------------------------------------------------*/ - -ILboolean ilisValidTiffExtension(ILconst_string FileName) -{ - if (!iCheckExtension((ILstring)FileName, IL_TEXT("tif")) && - !iCheckExtension((ILstring)FileName, IL_TEXT("tiff"))) - return IL_FALSE; - else - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -//! Checks if the file specified in FileName is a valid tiff file. -ILboolean ilIsValidTiff(ILconst_string FileName) -{ - ILHANDLE TiffFile; - ILboolean bTiff = IL_FALSE; - - if (!ilisValidTiffExtension((ILstring) FileName)) { - ilSetError(IL_INVALID_EXTENSION); - return bTiff; - } - - TiffFile = iopenr((ILstring)FileName); - if (TiffFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bTiff; - } - - bTiff = ilIsValidTiffF(TiffFile); - icloser(TiffFile); - - return bTiff; -} - -/*----------------------------------------------------------------------------*/ - -ILboolean ilisValidTiffFunc() -{ - ILushort Header1, Header2; - - Header1 = GetLittleUShort(); - - if (Header1 != MAGIC_HEADER1 && Header1 != MAGIC_HEADER2) - return IL_FALSE; - - if (Header1 == MAGIC_HEADER1) - Header2 = GetLittleUShort(); - else - Header2 = GetBigUShort(); - - if (Header2 != 42) - return IL_FALSE; - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -//! Checks if the ILHANDLE contains a valid tiff file at the current position. -ILboolean ilIsValidTiffF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = ilisValidTiffFunc(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - -/*----------------------------------------------------------------------------*/ - -//! Checks if Lump is a valid Tiff lump. -ILboolean ilIsValidTiffL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return ilisValidTiffFunc(); -} - -/*----------------------------------------------------------------------------*/ - -//! Reads a Tiff file -ILboolean ilLoadTiff(ILconst_string FileName) -{ - ILHANDLE TiffFile; - ILboolean bTiff = IL_FALSE; - - TiffFile = iopenr(FileName); - if (TiffFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - } - else { - bTiff = ilLoadTiffF(TiffFile); - icloser(TiffFile); - } - - return bTiff; -} - -/*----------------------------------------------------------------------------*/ - -//! Reads an already-opened Tiff file -ILboolean ilLoadTiffF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadTiffInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - -/*----------------------------------------------------------------------------*/ - -//! Reads from a memory "lump" that contains a Tiff -ILboolean ilLoadTiffL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadTiffInternal(); -} - -/*----------------------------------------------------------------------------*/ - -void warningHandler(const char* mod, const char* fmt, va_list ap) -{ - mod; fmt; ap; - //char buff[1024]; - //_vsnprintf(buff, 1024, fmt, ap); -} - -void errorHandler(const char* mod, const char* fmt, va_list ap) -{ - mod; fmt; ap; - //char buff[1024]; - //_vsnprintf(buff, 1024, fmt, ap); -} - -//// - -/* -ILboolean iLoadTiffInternal (TIFF* tif, ILimage* Image) -{ - //// - - uint16 photometric, planarconfig, orientation; - uint16 samplesperpixel, bitspersample, *sampleinfo, extrasamples; - uint32 w, h, d, linesize, tilewidth, tilelength; - ILushort si; - - //// - - TIFFSetDirectory(tif, directory); - //// - - // Process fields - - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); - - TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGEDEPTH, &d); //TODO: d is ignored... - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); - TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); - TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation); - - linesize = TIFFScanlineSize(tif); - - TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric); - TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); - - tilewidth = w; tilelength = h; - TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tilewidth); - TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tilelength); - - //// - - if (extrasamples != 0) { - return IL_FALSE; - } - - //// - - if (!Image) { - int type = IL_UNSIGNED_BYTE; - if (bitspersample == 16) type = IL_UNSIGNED_SHORT; - if(!ilTexImage(w, h, 1, 1, IL_LUMINANCE, type, NULL)) { - TIFFClose(tif); - return IL_FALSE; - } - iCurImage->NumNext = 0; - Image = iCurImage; - } - else { - Image->Next = ilNewImage(w, h, 1, 1, 1); - if(Image->Next == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - Image = Image->Next; - iCurImage->NumNext++; - } -} -*/ - -//// - - -// Internal function used to load the Tiff. -ILboolean iLoadTiffInternal() -{ - TIFF *tif; - uint16 photometric, planarconfig, orientation; - uint16 samplesperpixel, bitspersample, *sampleinfo, extrasamples; - uint32 w, h, d, linesize, tilewidth, tilelength; - ILubyte *pImageData; - ILuint i, ProfileLen, DirCount = 0; - ILvoid *Buffer; - ILimage *Image, *TempImage; - ILushort si; - ILfloat x_position, x_resolution, y_position, y_resolution; - //TIFFRGBAImage img; - //char emsg[1024]; - - // to avoid high order bits garbage when used as shorts - w = h = d = linesize = tilewidth = tilelength = 0; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - - TIFFSetWarningHandler (NULL); - TIFFSetErrorHandler (NULL); - - //for debugging only - //TIFFSetWarningHandler(warningHandler); - //TIFFSetErrorHandler(errorHandler); - - tif = iTIFFOpen("r"); - if (tif == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - do { - DirCount++; - } while (TIFFReadDirectory(tif)); - - /* - if (!ilTexImage(1, 1, 1, 1, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { - TIFFClose(tif); - return IL_FALSE; - } - Image = iCurImage; - for (i = 1; i < DirCount; i++) { - Image->Next = ilNewImage(1, 1, 1, 1, 1); - if (Image->Next == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - Image = Image->Next; - } - iCurImage->NumNext = DirCount - 1; - */ - Image = NULL; - for (i = 0; i < DirCount; i++) { - TIFFSetDirectory(tif, (tdir_t)i); - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); - - TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGEDEPTH, &d); //TODO: d is ignored... - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); - TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); - TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation); - - linesize = TIFFScanlineSize(tif); - - //added 2003-08-31 - //1 bpp tiffs are not neccessarily greyscale, they can - //have a palette (photometric == 3)...get this information - TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric); - TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); - - //special-case code for frequent data cases that may be read more - //efficiently than with the TIFFReadRGBAImage() interface. - - //added 2004-05-12 - //Get tile sizes and use TIFFReadRGBAImage() for tiled images for now - tilewidth = w; tilelength = h; - TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tilewidth); - TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tilelength); - - - if (extrasamples == 0 - && samplesperpixel == 1 //luminance or palette - && (bitspersample == 8 || bitspersample == 1 || bitspersample == 16) - && (photometric == PHOTOMETRIC_MINISWHITE - || photometric == PHOTOMETRIC_MINISBLACK - || photometric == PHOTOMETRIC_PALETTE) - && (orientation == ORIENTATION_TOPLEFT || orientation == ORIENTATION_BOTLEFT) - && tilewidth == w && tilelength == h - ) { - ILubyte* strip; - tsize_t stripsize; - ILuint y; - uint32 rowsperstrip, j, linesread; - - //TODO: 1 bit/pixel images should not be stored as 8 bits... - //(-> add new format) - if (!Image) { - int type = IL_UNSIGNED_BYTE; - if (bitspersample == 16) type = IL_UNSIGNED_SHORT; - if(!ilTexImage(w, h, 1, 1, IL_LUMINANCE, type, NULL)) { - TIFFClose(tif); - return IL_FALSE; - } - Image = iCurImage; - } - else { - Image->Next = ilNewImage(w, h, 1, 1, 1); - if(Image->Next == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - Image = Image->Next; - } - - if (photometric == PHOTOMETRIC_PALETTE) { //read palette - uint16 *red, *green, *blue; - //ILboolean is16bitpalette = IL_FALSE; - ILubyte *entry; - uint32 count = 1 << bitspersample, j; - - TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); - - Image->Format = IL_COLOUR_INDEX; - Image->Pal.PalSize = (count)*3; - Image->Pal.PalType = IL_PAL_RGB24; - Image->Pal.Palette = ialloc(Image->Pal.PalSize); - entry = Image->Pal.Palette; - for (j = 0; j < count; ++j) { - entry[0] = (ILubyte)(red[j] >> 8); - entry[1] = (ILubyte)(green[j] >> 8); - entry[2] = (ILubyte)(blue[j] >> 8); - - entry += 3; - } - } - - TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - stripsize = TIFFStripSize(tif); - - strip = ialloc(stripsize); - - if (bitspersample == 8 || bitspersample == 16) { - ILubyte *dat = Image->Data; - for (y = 0; y < h; y += rowsperstrip) { - //the last strip may contain less data if the image - //height is not evenly divisible by rowsperstrip - if (y + rowsperstrip > h) { - stripsize = linesize*(h - y); - linesread = h - y; - } - else - linesread = rowsperstrip; - - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), strip, stripsize) == -1) { - ilSetError(IL_LIB_TIFF_ERROR); - ifree(strip); - TIFFClose(tif); - return IL_FALSE; - } - - if (photometric == PHOTOMETRIC_MINISWHITE) { //invert channel - uint32 k, t2; - for (j = 0; j < linesread; ++j) { - t2 = j*linesize; - //this works for 16bit images as well: the two bytes - //making up a pixel can be inverted independently - for (k = 0; k < Image->Bps; ++k) - dat[k] = ~strip[t2 + k]; - dat += w; - } - } - else - for(j = 0; j < linesread; ++j) - memcpy(&Image->Data[(y + j)*Image->Bps], &strip[j*linesize], Image->Bps); - } - } - else if (bitspersample == 1) { - //TODO: add a native format to devil, so we don't have to - //unpack the values here - ILubyte mask, curr, *dat = Image->Data; - uint32 k, sx, t2; - for (y = 0; y < h; y += rowsperstrip) { - //the last strip may contain less data if the image - //height is not evenly divisible by rowsperstrip - if (y + rowsperstrip > h) { - stripsize = linesize*(h - y); - linesread = h - y; - } - else - linesread = rowsperstrip; - - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), strip, stripsize) == -1) { - ilSetError(IL_LIB_TIFF_ERROR); - ifree(strip); - TIFFClose(tif); - return IL_FALSE; - } - - for (j = 0; j < linesread; ++j) { - k = 0; - sx = 0; - t2 = j*linesize; - while (k < w) { - curr = strip[t2 + sx]; - if (photometric == PHOTOMETRIC_MINISWHITE) - curr = ~curr; - for (mask = 0x80; mask != 0 && k < w; mask >>= 1){ - if((curr & mask) != 0) - dat[k] = 255; - else - dat[k] = 0; - ++k; - } - ++sx; - } - dat += w; - } - } - } - - ifree(strip); - - if(orientation == ORIENTATION_TOPLEFT) - Image->Origin = IL_ORIGIN_UPPER_LEFT; - else if(orientation == ORIENTATION_BOTLEFT) - Image->Origin = IL_ORIGIN_LOWER_LEFT; - } - //for 16bit rgb images: - else if (extrasamples == 0 - && samplesperpixel == 3 - && (bitspersample == 8 || bitspersample == 16) - && photometric == PHOTOMETRIC_RGB - && planarconfig == 1 - && (orientation == ORIENTATION_TOPLEFT || orientation == ORIENTATION_BOTLEFT) - && tilewidth == w && tilelength == h - ) { - ILubyte *strip, *dat; - tsize_t stripsize; - ILuint y; - uint32 rowsperstrip, j, linesread; - - if (!Image) { - int type = IL_UNSIGNED_BYTE; - if (bitspersample == 16) type = IL_UNSIGNED_SHORT; - if(!ilTexImage(w, h, 1, 3, IL_RGB, type, NULL)) { - TIFFClose(tif); - return IL_FALSE; - } - Image = iCurImage; - } - else { - Image->Next = ilNewImage(w, h, 1, 1, 1); - if(Image->Next == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - Image = Image->Next; - } - - TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - stripsize = TIFFStripSize(tif); - - strip = ialloc(stripsize); - - dat = Image->Data; - for (y = 0; y < h; y += rowsperstrip) { - //the last strip may contain less data if the image - //height is not evenly divisible by rowsperstrip - if (y + rowsperstrip > h) { - stripsize = linesize*(h - y); - linesread = h - y; - } - else - linesread = rowsperstrip; - - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), strip, stripsize) == -1) { - ilSetError(IL_LIB_TIFF_ERROR); - ifree(strip); - TIFFClose(tif); - return IL_FALSE; - } - - for(j = 0; j < linesread; ++j) - memcpy(&Image->Data[(y + j)*Image->Bps], &strip[j*linesize], Image->Bps); - } - - ifree(strip); - - if(orientation == ORIENTATION_TOPLEFT) - Image->Origin = IL_ORIGIN_UPPER_LEFT; - else if(orientation == ORIENTATION_BOTLEFT) - Image->Origin = IL_ORIGIN_LOWER_LEFT; - }/* - else if (extrasamples == 0 && samplesperpixel == 3 //rgb - && (bitspersample == 8 || bitspersample == 1 || bitspersample == 16) - && photometric == PHOTOMETRIC_RGB - && (planarconfig == PLANARCONFIG_CONTIG || planarcon - && (orientation == ORIENTATION_TOPLEFT || orientation == ORIENTATION_BOTLEFT) - ) { - } - */ - else { - //not direclty supported format - if(!Image) { - if(!ilTexImage(w, h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { - TIFFClose(tif); - return IL_FALSE; - } - Image = iCurImage; - } - else { - Image->Next = ilNewImage(w, h, 1, 4, 1); - if(Image->Next == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - Image = Image->Next; - } - - if (samplesperpixel == 4) { - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); - if (!sampleinfo || sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED) { - si = EXTRASAMPLE_ASSOCALPHA; - TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, &si); - } - } - /* - if (!ilResizeImage(Image, Image->Width, Image->Height, 1, 4, 1)) { - TIFFClose(tif); - return IL_FALSE; - } - */ - Image->Format = IL_RGBA; - Image->Type = IL_UNSIGNED_BYTE; - - // Siigron: added u_long cast to shut up compiler warning - //2003-08-31: changed flag from 1 (exit on error) to 0 (keep decoding) - //this lets me view text.tif, but can give crashes with unsupported - //tiffs... - //2003-09-04: keep flag 1 for official version for now - if (!TIFFReadRGBAImage(tif, Image->Width, Image->Height, (uint32*)Image->Data, 0)) { - TIFFClose(tif); - ilSetError(IL_LIB_TIFF_ERROR); - return IL_FALSE; - } - Image->Origin = IL_ORIGIN_LOWER_LEFT; // eiu...dunno if this is right - -#ifdef __BIG_ENDIAN__ //TIFFReadRGBAImage reads abgr on big endian, convert to rgba - EndianSwapData(Image); -#endif - - /* - The following switch() should not be needed, - because we take care of the special cases that needed - these conversions. But since not all special cases - are handled right now, keep it :) - */ - //TODO: put switch into the loop?? - TempImage = iCurImage; - iCurImage = Image; //ilConvertImage() converts iCurImage - switch (samplesperpixel) - { - case 1: - //added 2003-08-31 to keep palettized tiffs colored - if(photometric != 3) - ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE); - else //strip alpha as tiff supports no alpha palettes - ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); - break; - - case 3: - //TODO: why the ifdef?? -#ifdef __LITTLE_ENDIAN__ - ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); -#endif - break; - - case 4: - pImageData = Image->Data; - //removed on 2003-08-26...why was this here? libtiff should and does - //take care of these things??? - /* - //invert alpha -#ifdef __LITTLE_ENDIAN__ - pImageData += 3; -#endif - for (i = Image->Width * Image->Height; i > 0; i--) { - *pImageData ^= 255; - pImageData += 4; - } - */ - break; - } - iCurImage = TempImage; - - } //else not directly supported format - - if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &ProfileLen, &Buffer)) { - if (Image->Profile && Image->ProfileSize) - ifree(Image->Profile); - Image->Profile = (ILubyte*)ialloc(ProfileLen); - if (Image->Profile == NULL) { - TIFFClose(tif); - return IL_FALSE; - } - - memcpy(Image->Profile, Buffer, ProfileLen); - Image->ProfileSize = ProfileLen; - - //removed on 2003-08-24 as explained in bug 579574 on sourceforge - //_TIFFfree(Buffer); - } - - // dangelo: read offset from tiff tags. - //If nothing is stored in these tags, then this must be an "uncropped" TIFF - //file, in which case, the "full size" width/height is the same as the - //"cropped" width and height - // - // the full size is currently not supported by DevIL - //if (TIFFGetField(tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &(c->full_width)) == - // 0) - // (c->full_width = c->cropped_width); - //if (TIFFGetField(tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &(c->full_height)) == - // 0) - // (c->full_height = c->cropped_height); - - if (TIFFGetField(tif, TIFFTAG_XPOSITION, &x_position) == 0) - x_position = 0; - if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &x_resolution) == 0) - x_resolution = 0; - if (TIFFGetField(tif, TIFFTAG_YPOSITION, &y_position) == 0) - y_position = 0; - if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &y_resolution) == 0) - y_resolution = 0; - - //offset in pixels of "cropped" image from top left corner of - //full image (rounded to nearest integer) - Image->OffX = (uint32) ((x_position * x_resolution) + 0.49); - Image->OffY = (uint32) ((y_position * y_resolution) + 0.49); - - - /* - Image = Image->Next; - if (Image == NULL) // Should never happen except when we reach the end, but check anyway. - break; - */ - } //for tiff directories - - TIFFClose(tif); - - ilFixImage(); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ - -///////////////////////////////////////////////////////////////////////////////////////// -// Extension to load tiff files from memory -// Marco Fabbricatore (fabbrica@ai-lab.fh-furtwangen.de) -///////////////////////////////////////////////////////////////////////////////////////// - -static tsize_t -_tiffFileReadProc(thandle_t fd, tdata_t pData, tsize_t tSize) -{ - fd; - return iread(pData, 1, tSize); -} - -/*----------------------------------------------------------------------------*/ - -static tsize_t -_tiffFileWriteProc(thandle_t fd, tdata_t pData, tsize_t tSize) -{ - fd; - /*TIFFWarning("TIFFMemFile", "_tiffFileWriteProc() Not implemented"); - return(0); - */ - return iwrite(pData, 1, tSize); -} - -/*----------------------------------------------------------------------------*/ - -static toff_t -_tiffFileSeekProc(thandle_t fd, toff_t tOff, int whence) -{ - fd; - /* we use this as a special code, so avoid accepting it */ - if (tOff == 0xFFFFFFFF) - return 0xFFFFFFFF; - - iseek(tOff, whence); - return tOff; -} - -/*----------------------------------------------------------------------------*/ - -#if 0 -static toff_t -_tiffFileSeekProcW(thandle_t fd, toff_t tOff, int whence) -{ - /* we use this as a special code, so avoid accepting it */ - if (tOff == 0xFFFFFFFF) - return 0xFFFFFFFF; - - iseekw(tOff, whence); - return tOff; -} -#endif -/*----------------------------------------------------------------------------*/ - -static int -_tiffFileCloseProc(thandle_t fd) -{ - fd; - return (0); -} - -/*----------------------------------------------------------------------------*/ - -static toff_t -_tiffFileSizeProc(thandle_t fd) -{ - ILint Offset, Size; - Offset = itell(); - iseek(0, IL_SEEK_END); - Size = itell(); - iseek(Offset, IL_SEEK_SET); - - fd; - - return Size; -} - -/*----------------------------------------------------------------------------*/ - -#if 0 -static toff_t -_tiffFileSizeProcW(thandle_t fd) -{ - ILint Offset, Size; - Offset = itellw(); - iseekw(0, IL_SEEK_END); - Size = itellw(); - iseekw(Offset, IL_SEEK_SET); - - return Size; -} -#endif -/*----------------------------------------------------------------------------*/ - -#ifdef __BORLANDC__ -#pragma argsused -#endif -static int -_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) -{ - fd; pbase; psize; - return 0; -} - -/*----------------------------------------------------------------------------*/ - -#ifdef __BORLANDC__ -#pragma argsused -#endif -static void -_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) -{ - fd; base; size; - return; -} - -/*----------------------------------------------------------------------------*/ - -TIFF *iTIFFOpen(char *Mode) -{ - TIFF *tif; -#if 0 - if (Mode[0] == 'w') - tif = TIFFClientOpen("TIFFMemFile", Mode, - NULL, - _tiffFileReadProc, _tiffFileWriteProc, - _tiffFileSeekProcW, _tiffFileCloseProc, - _tiffFileSizeProcW, _tiffDummyMapProc, - _tiffDummyUnmapProc); - else -#endif - tif = TIFFClientOpen("TIFFMemFile", Mode, - NULL, - _tiffFileReadProc, _tiffFileWriteProc, - _tiffFileSeekProc, _tiffFileCloseProc, - _tiffFileSizeProc, _tiffDummyMapProc, - _tiffDummyUnmapProc); - - return tif; -} - -/*----------------------------------------------------------------------------*/ - - -//! Writes a Tiff file -ILboolean ilSaveTiff(ILconst_string FileName) -{ - //ILHANDLE TiffFile; - ILboolean bTiff = IL_FALSE; - - if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) { - if (iFileExists(FileName)) { - ilSetError(IL_FILE_ALREADY_EXISTS); - return IL_FALSE; - } - } -/* - TiffFile = iopenw(FileName); - if (TiffFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bTiff; - } -*/ - //bTiff = ilSaveTiffF(TiffFile); - bTiff = iSaveTiffInternal(FileName); - -/* - iclosew(TiffFile); -*/ - return bTiff; -} - - -//! Writes a Tiff to an already-opened file -ILboolean ilSaveTiffF(ILHANDLE File) -{ - File; -/* - iSetOutputFile(File); - return iSaveTiffInternal(); - -*/ - //ilSetError(IL_FILE_READ_ERROR); - return IL_FALSE; -} - - -//! Writes a Tiff to a memory "lump" -ILboolean ilSaveTiffL(const ILvoid *Lump, ILuint Size) -{ -/* - - iSetOutputLump(Lump, Size); - return iSaveTiffInternal(); - -*/ - //ilSetError(IL_FILE_READ_ERROR); - return IL_FALSE; -} - - -// @TODO: Accept palettes! - -// Internal function used to save the Tiff. -//ILboolean iSaveTiffInternal() - -ILboolean iSaveTiffInternal(ILconst_string Filename) -{ - ILenum Format; - ILenum Compression; - ILuint ixLine; - TIFF *File; - char Description[512]; - ILimage *TempImage; - char *str; - ILboolean SwapColors; - ILubyte *OldData; - - if(iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - -#if 1 - TIFFSetWarningHandler (NULL); - TIFFSetErrorHandler (NULL); -#else - //for debugging only - TIFFSetWarningHandler(warningHandler); - TIFFSetErrorHandler(errorHandler); -#endif - if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) - Compression = COMPRESSION_LZW; - else - Compression = COMPRESSION_NONE; - - if (iCurImage->Format == IL_COLOUR_INDEX) { - if (ilGetBppPal(iCurImage->Pal.PalType) == 4) // Preserve the alpha. - TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); - else - TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); - - if (TempImage == NULL) { - return IL_FALSE; - } - } - else { - TempImage = iCurImage; - } - - #ifndef _UNICODE - File = TIFFOpen(Filename, "w"); - #else - File = TIFFOpenW(Filename, "w"); - #endif - - if (File == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return IL_FALSE; - } - - sprintf(Description, "Tiff generated by %s", ilGetString(IL_VERSION_NUM)); - - TIFFSetField(File, TIFFTAG_IMAGEWIDTH, TempImage->Width); - TIFFSetField(File, TIFFTAG_IMAGELENGTH, TempImage->Height); - TIFFSetField(File, TIFFTAG_COMPRESSION, Compression); - TIFFSetField(File, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(File, TIFFTAG_BITSPERSAMPLE, TempImage->Bpc << 3); - TIFFSetField(File, TIFFTAG_SAMPLESPERPIXEL, TempImage->Bpp); - if(TempImage->Bpp == 4) //TODO: LUMINANCE, LUMINANCE_ALPHA - TIFFSetField(File, TIFFTAG_MATTEING, 1); - TIFFSetField(File, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(File, TIFFTAG_ROWSPERSTRIP, 1); - TIFFSetField(File, TIFFTAG_SOFTWARE, ilGetString(IL_VERSION_NUM)); - /*TIFFSetField(File, TIFFTAG_DOCUMENTNAME, - iGetString(IL_TIF_DOCUMENTNAME_STRING) ? - iGetString(IL_TIF_DOCUMENTNAME_STRING) : FileName); -*/ - str = iGetString(IL_TIF_DOCUMENTNAME_STRING); - if (str) { - TIFFSetField(File, TIFFTAG_DOCUMENTNAME, str); - ifree(str); - } - - - str = iGetString(IL_TIF_AUTHNAME_STRING); - if (iGetString(IL_TIF_AUTHNAME_STRING)) { - TIFFSetField(File, TIFFTAG_ARTIST, str); - ifree(str); - } - - str = iGetString(IL_TIF_HOSTCOMPUTER_STRING); - if (str) { - TIFFSetField(File, TIFFTAG_HOSTCOMPUTER, str); - ifree(str); - } - - str = iGetString(IL_TIF_HOSTCOMPUTER_STRING); - if (str) { - TIFFSetField(File, TIFFTAG_IMAGEDESCRIPTION, str); - ifree(str); - } - - //The date time string is not formatted correctly, - //so leave it out for now - //(from http://www.awaresystems.be/imaging/tiff/tifftags/datetime.html : - //The format is: "YYYY:MM:DD HH:MM:SS", with hours like those on - //a 24-hour clock, and one space character between the date and the - //time. The length of the string, including the terminating NUL, is - //20 bytes.) - //TIFFSetField(File, TIFFTAG_DATETIME, iMakeString()); - - // 24/4/2003 - // Orientation flag is not always supported ( Photoshop, ...), orient the image data - // and set it always to normal view - TIFFSetField(File, TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT ); - if( TempImage->Origin != IL_ORIGIN_UPPER_LEFT ) { - ILubyte* Data = iGetFlipped(TempImage); - OldData = TempImage->Data; - TempImage->Data = Data; - } - else - OldData = TempImage->Data; - - /* - TIFFSetField(File, TIFFTAG_ORIENTATION, - TempImage->Origin == IL_ORIGIN_UPPER_LEFT ? ORIENTATION_TOPLEFT : ORIENTATION_BOTLEFT); - */ - - Format = TempImage->Format; - SwapColors = (Format == IL_BGR || Format == IL_BGRA); - if (SwapColors) - ilSwapColours(); - - for (ixLine = 0; ixLine < TempImage->Height; ++ixLine) { - if (TIFFWriteScanline(File, TempImage->Data + ixLine * TempImage->Bps, ixLine, 0) < 0) { - TIFFClose(File); - ilSetError(IL_LIB_TIFF_ERROR); - if (SwapColors) - ilSwapColours(); - if (TempImage->Data != OldData) { - ifree( TempImage->Data ); - TempImage->Data = OldData; - } - if (TempImage != iCurImage) - ilCloseImage(TempImage); - return IL_FALSE; - } - } - - if (SwapColors) - ilSwapColours(); - - if (TempImage->Data != OldData) { - ifree( TempImage->Data ); - TempImage->Data = OldData; - } - - if (TempImage != iCurImage) - ilCloseImage(TempImage); - - TIFFClose(File); - - return IL_TRUE; -} - -/*----------------------------------------------------------------------------*/ -// Makes a neat date string for the date field. -char *iMakeString() -{ - static char TimeStr[255]; - time_t Time; - struct tm *CurTime; - - imemclear(TimeStr, 255); - - time(&Time); -#ifdef _WIN32 - _tzset(); -#endif - CurTime = localtime(&Time); - - strftime(TimeStr, 255, "%s (%z)", CurTime); // "%#c (%z)" // %s was %c - - return TimeStr; -} - -/*----------------------------------------------------------------------------*/ - -#endif//IL_NO_TIF diff --git a/win32/devil/src/il_utility.c b/win32/devil/src/il_utility.c deleted file mode 100644 index 1ac4a25c4..000000000 --- a/win32/devil/src/il_utility.c +++ /dev/null @@ -1,155 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_utility.c -// -// Description: Utility functions -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" - - -// Returns the bpp of any Format -ILAPI ILubyte ILAPIENTRY ilGetBppFormat(ILenum Format) { - switch (Format) { - case IL_COLOUR_INDEX: - case IL_LUMINANCE: - return 1; - case IL_LUMINANCE_ALPHA: - return 2; - case IL_RGB: - case IL_BGR: - return 3; - case IL_RGBA: - case IL_BGRA: - return 4; - } - return 0; -} - - -// Returns the format of any bpp -ILAPI ILenum ILAPIENTRY ilGetFormatBpp(ILubyte Bpp) { - switch (Bpp) { - case 1: - return IL_LUMINANCE; - case 2: - return IL_LUMINANCE_ALPHA; - case 3: - return IL_RGB; - case 4: - return IL_RGBA; - } - return 0; -} - - -// Returns the bpc of any Type -ILAPI ILubyte ILAPIENTRY ilGetBpcType(ILenum Type) { - switch (Type) { - case IL_BYTE: - case IL_UNSIGNED_BYTE: - return 1; - case IL_SHORT: - case IL_UNSIGNED_SHORT: - case IL_HALF: - return 2; - case IL_INT: - case IL_UNSIGNED_INT: - case IL_FLOAT: - return 4; - case IL_DOUBLE: - return 8; - } - return 0; -} - - -// Returns the type matching a bpc -ILAPI ILenum ILAPIENTRY ilGetTypeBpc(ILubyte Bpc) { - switch (Bpc) { - case 1: - return IL_UNSIGNED_BYTE; - case 2: - return IL_UNSIGNED_SHORT; - case 4: - return IL_UNSIGNED_INT; - case 8: - return IL_DOUBLE; - } - return 0; -} - - -// Returns the bpp of any palette type (PalType) -ILAPI ILubyte ILAPIENTRY ilGetBppPal(ILenum PalType) { - switch (PalType) { - case IL_PAL_RGB24: - case IL_PAL_BGR24: - return 3; - case IL_PAL_RGB32: - case IL_PAL_RGBA32: - case IL_PAL_BGR32: - case IL_PAL_BGRA32: - return 4; - } - return 0; -} - -// Returns the base format of a palette type (PalType) -ILAPI ILenum ILAPIENTRY ilGetPalBaseType(ILenum PalType) { - switch (PalType) { - case IL_PAL_RGB24: - return IL_RGB; - case IL_PAL_RGB32: - return IL_RGBA; // Not sure - case IL_PAL_RGBA32: - return IL_RGBA; - case IL_PAL_BGR24: - return IL_BGR; - case IL_PAL_BGR32: - return IL_BGRA; // Not sure - case IL_PAL_BGRA32: - return IL_BGRA; - } - - return 0; -} - - -// Returns the next power of 2 if Num isn't 2^n or returns Num if Num is 2^n -ILAPI ILuint ILAPIENTRY ilNextPower2(ILuint n) { - ILuint power = 1; - while( power < n ) { - power <<= 1; - } - return power; -} - -ILAPI ILvoid ILAPIENTRY iMemSwap( ILubyte *s1, ILubyte *s2, const ILuint size ) { - const ILuint block_size = 4096; - const ILuint blocks = size/block_size; - ILuint i; - - ILubyte *block = (ILubyte*)ialloc(block_size); - if(block == NULL) return; - for( i = 0; i < blocks; i++ ) { - memcpy(block,s1,block_size); - memcpy(s1,s2,block_size); - memcpy(s2,block,block_size); - s2 += block_size; - s1 += block_size; - } - i = size - i*block_size; - if( i > 0 ) { - memcpy(block,s1,i); - memcpy(s1,s2,i); - memcpy(s2,block,i); - } - ifree(block); -} diff --git a/win32/devil/src/il_wal.c b/win32/devil/src/il_wal.c deleted file mode 100644 index ffc59c2d7..000000000 --- a/win32/devil/src/il_wal.c +++ /dev/null @@ -1,179 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/25/2001 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_wal.c -// -// Description: Loads a Quake .wal texture. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_WAL -#include "il_manip.h" -#include "il_q2pal.h" - - -typedef struct WALHEAD -{ - ILbyte FileName[32]; // Image name - ILuint Width; // Width of first image - ILuint Height; // Height of first image - ILuint Offsets[4]; // Offsets to image data - ILbyte AnimName[32]; // Name of next frame - ILuint Flags; // ?? - ILuint Contents; // ?? - ILuint Value; // ?? -} WALHEAD; - -ILboolean iLoadWalInternal(void); - - -//! Reads a .wal file -ILboolean ilLoadWal(ILconst_string FileName) -{ - ILHANDLE WalFile; - ILboolean bWal = IL_FALSE; - - WalFile = iopenr(FileName); - if (WalFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bWal; - } - - bWal = ilLoadWalF(WalFile); - icloser(WalFile); - - return bWal; -} - - -//! Reads an already-opened .wal file -ILboolean ilLoadWalF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadWalInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains a .wal file -ILboolean ilLoadWalL(const ILvoid *Lump, ILuint Size) -{ - iSetInputLump(Lump, Size); - return iLoadWalInternal(); -} - - -ILboolean iLoadWalInternal() -{ - WALHEAD Header; - ILimage *Mipmaps[3], *CurImage; - ILuint i, NewW, NewH; - - if (iCurImage == NULL) { - ilSetError(IL_ILLEGAL_OPERATION); - return IL_FALSE; - } - CurImage = iCurImage; - - - //read header - - iread(&Header.FileName, 1, 32); - - Header.Width = GetLittleUInt(); - - Header.Height = GetLittleUInt(); - - for (i = 0; i < 4; i++) - - Header.Offsets[i] = GetLittleUInt(); - - iread(Header.AnimName, 1, 32); - - Header.Flags = GetLittleUInt(); - - Header.Contents = GetLittleUInt(); - - Header.Value = GetLittleUInt(); - - - if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) - return IL_FALSE; - - for (i = 0; i < 3; i++) { - Mipmaps[i] = (ILimage*)icalloc(sizeof(ILimage), 1); - if (Mipmaps[i] == NULL) - goto cleanup_error; - Mipmaps[i]->Pal.Palette = (ILubyte*)ialloc(768); - if (Mipmaps[i]->Pal.Palette == NULL) - goto cleanup_error; - memcpy(Mipmaps[i]->Pal.Palette, ilDefaultQ2Pal, 768); - Mipmaps[i]->Pal.PalType = IL_PAL_RGB24; - } - - NewW = Header.Width; - NewH = Header.Height; - for (i = 0; i < 3; i++) { - NewW /= 2; - NewH /= 2; - iCurImage = Mipmaps[i]; - if (!ilTexImage(NewW, NewH, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) - goto cleanup_error; - // Don't set until now so ilTexImage won't get rid of the palette. - Mipmaps[i]->Pal.PalSize = 768; - Mipmaps[i]->Origin = IL_ORIGIN_UPPER_LEFT; - } - - iCurImage = CurImage; - ilCloseImage(iCurImage->Mipmaps); - iCurImage->Mipmaps = Mipmaps[0]; - Mipmaps[0]->Next = Mipmaps[1]; - Mipmaps[1]->Next = Mipmaps[2]; - - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) - ifree(iCurImage->Pal.Palette); - iCurImage->Pal.Palette = (ILubyte*)ialloc(768); - if (iCurImage->Pal.Palette == NULL) - goto cleanup_error; - - iCurImage->Pal.PalSize = 768; - iCurImage->Pal.PalType = IL_PAL_RGB24; - memcpy(iCurImage->Pal.Palette, ilDefaultQ2Pal, 768); - - iseek(Header.Offsets[0], IL_SEEK_SET); - if (iread(iCurImage->Data, Header.Width * Header.Height, 1) != 1) - goto cleanup_error; - - for (i = 0; i < 3; i++) { - iseek(Header.Offsets[i+1], IL_SEEK_SET); - if (iread(Mipmaps[i]->Data, Mipmaps[i]->Width * Mipmaps[i]->Height, 1) != 1) - goto cleanup_error; - } - - // Fixes all images, even mipmaps. - ilFixImage(); - - return IL_TRUE; - -cleanup_error: - for (i = 0; i < 3; i++) { - ilCloseImage(Mipmaps[i]); - } - return IL_FALSE; -} - - -#endif//IL_NO_WAL diff --git a/win32/devil/src/il_xpm.c b/win32/devil/src/il_xpm.c deleted file mode 100644 index 0d0bbe704..000000000 --- a/win32/devil/src/il_xpm.c +++ /dev/null @@ -1,789 +0,0 @@ -//----------------------------------------------------------------------------- -// -// ImageLib Sources -// Copyright (C) 2000-2002 by Denton Woods -// Last modified: 05/27/2002 <--Y2K Compliant! =] -// -// Filename: src-IL/src/il_xpm.c -// -// Description: Reads from an .xpm file. -// -//----------------------------------------------------------------------------- - - -#include "il_internal.h" -#ifndef IL_NO_XPM -#include - - -//If this is defined, only xpm files with 1 char/pixel - -//can be loaded. They load somewhat faster then, though - -//(not much). - -//#define XPM_DONT_USE_HASHTABLE - -ILboolean iLoadXpmInternal(void); - - -// Reads an .xpm file -ILboolean ilLoadXpm(ILconst_string FileName) -{ - ILHANDLE XpmFile; - ILboolean bXpm = IL_FALSE; - - XpmFile = iopenr(FileName); - if (XpmFile == NULL) { - ilSetError(IL_COULD_NOT_OPEN_FILE); - return bXpm; - } - - iSetInputFile(XpmFile); - - bXpm = ilLoadXpmF(XpmFile); - - icloser(XpmFile); - - return bXpm; -} - - -//! Reads an already-opened .xpm file -ILboolean ilLoadXpmF(ILHANDLE File) -{ - ILuint FirstPos; - ILboolean bRet; - - iSetInputFile(File); - FirstPos = itell(); - bRet = iLoadXpmInternal(); - iseek(FirstPos, IL_SEEK_SET); - - return bRet; -} - - -//! Reads from a memory "lump" that contains an .xpm -ILboolean ilLoadXpmL( const ILvoid *Lump, ILuint Size) { - iSetInputLump(Lump, Size); - return iLoadXpmInternal(); -} - - -typedef ILubyte XpmPixel[4]; - -#define XPM_MAX_CHAR_PER_PIXEL 2 - - - - - -#ifndef XPM_DONT_USE_HASHTABLE - - - -//The following hash table code was inspired by the xpm - -//loading code of xv, one of the best image viewers of X11 - - - -//For xpm files with more than one character/pixel, it is - -//impractical to use a simple lookup table for the - -//character-to-color mapping (because the table requires - -//2^(chars/pixel) entries, this is quite big). - -//Because of that, a hash table is used for the mapping. - -//The hash table has 257 entries, and collisions are - -//resolved by chaining. - - - -//257 is the smallest prime > 256 - -#define XPM_HASH_LEN 257 - - - -typedef struct XPMHASHENTRY - -{ - - ILubyte ColourName[XPM_MAX_CHAR_PER_PIXEL]; - - XpmPixel ColourValue; - - struct XPMHASHENTRY *Next; - -} XPMHASHENTRY; - - - - - -static ILuint XpmHash(const ILubyte* name, int len) - -{ - - ILint i, sum; - - for (sum = i = 0; i < len; ++i) - - sum += name[i]; - - return sum % XPM_HASH_LEN; - -} - - - - - -XPMHASHENTRY** XpmCreateHashTable() - -{ - - XPMHASHENTRY** Table = - - (XPMHASHENTRY**)ialloc(XPM_HASH_LEN*sizeof(XPMHASHENTRY*)); - - if (Table != NULL) - - memset(Table, 0, XPM_HASH_LEN*sizeof(XPMHASHENTRY*)); - - return Table; - -} - - - - -void XpmDestroyHashTable(XPMHASHENTRY **Table) - -{ - - ILint i; - - XPMHASHENTRY* Entry; - - - - for (i = 0; i < XPM_HASH_LEN; ++i) { - - while (Table[i] != NULL) { - - Entry = Table[i]->Next; - - ifree(Table[i]); - - Table[i] = Entry; - - } - - } - - - - ifree(Table); - -} - - - - - -void XpmInsertEntry(XPMHASHENTRY **Table, const ILubyte* Name, int Len, XpmPixel Colour) - -{ - - XPMHASHENTRY* NewEntry; - - ILuint Index; - - Index = XpmHash(Name, Len); - - - - NewEntry = (XPMHASHENTRY*)ialloc(sizeof(XPMHASHENTRY)); - - if (NewEntry != NULL) { - - NewEntry->Next = Table[Index]; - - memcpy(NewEntry->ColourName, Name, Len); - - memcpy(NewEntry->ColourValue, Colour, sizeof(Colour)); - - Table[Index] = NewEntry; - - } - -} - - - - - -void XpmGetEntry(XPMHASHENTRY **Table, const ILubyte* Name, int Len, XpmPixel Colour) - -{ - - XPMHASHENTRY* Entry; - - ILuint Index; - - - - Index = XpmHash(Name, Len); - - Entry = Table[Index]; - - while (Entry != NULL && strncmp((char*)(Entry->ColourName), (char*)Name, Len) != 0) - - Entry = Entry->Next; - - - - if (Entry != NULL) - - memcpy(Colour, Entry->ColourValue, sizeof(Colour)); - -} - - - -#endif //XPM_DONT_USE_HASHTABLE - - - - -ILint XpmGetsInternal(ILubyte *Buffer, ILint MaxLen) -{ - ILint i = 0, Current; - - if (ieof()) - return IL_EOF; - - while ((Current = igetc()) != IL_EOF && i < MaxLen - 1) { - if (Current == IL_EOF) - return 0; - if (Current == '\n') //unix line ending - break; - - if (Current == '\r') { //dos/mac line ending - - Current = igetc(); - - if (Current == '\n') //dos line ending - - break; - - - - if (Current == IL_EOF) - - break; - - - - Buffer[i++] = (ILubyte)Current; - - continue; - - } - - Buffer[i++] = (ILubyte)Current; - } - - Buffer[i++] = 0; - - return i; -} - - -ILint XpmGets(ILubyte *Buffer, ILint MaxLen) -{ - ILint Size, i, j; - ILboolean NotComment = IL_FALSE, InsideComment = IL_FALSE; - - - do { - Size = XpmGetsInternal(Buffer, MaxLen); - if (Size == IL_EOF) - return IL_EOF; - - - - //stip leading whitespace (sometimes there's whitespace - - //before a comment or before the pixel data) - - for(i = 0; i < Size && isspace(Buffer[i]); ++i) ; - - Size = Size - i; - - for(j = 0; j < Size; ++j) - - Buffer[j] = Buffer[j + i]; - - - - - - if (Size == 0) - - continue; - - - if (Buffer[0] == '/' && Buffer[1] == '*') { - for (i = 2; i < Size; i++) { - if (Buffer[i] == '*' && Buffer[i+1] == '/') { - break; - } - } - if (i >= Size) - InsideComment = IL_TRUE; - } - else if (InsideComment) { - for (i = 0; i < Size; i++) { - if (Buffer[i] == '*' && Buffer[i+1] == '/') { - break; - } - } - if (i < Size) - InsideComment = IL_FALSE; - } - else { - NotComment = IL_TRUE; - } - } while (!NotComment); - - return Size; -} - - -ILint XpmGetInt(ILubyte *Buffer, ILint Size, ILint *Position) -{ - char Buff[1024]; - ILint i, j; - ILboolean IsInNum = IL_FALSE; - - for (i = *Position, j = 0; i < Size; i++) { - if (isdigit(Buffer[i])) { - IsInNum = IL_TRUE; - Buff[j++] = Buffer[i]; - } - else { - if (IsInNum) { - Buff[j] = 0; - *Position = i; - return atoi(Buff); - } - } - } - - return -1; -} - - -ILboolean XpmPredefCol(char *Buff, XpmPixel *Colour) -{ - ILint len; - ILint val = 128; - - if (!stricmp(Buff, "none")) { - (*Colour)[0] = 0; - (*Colour)[1] = 0; - (*Colour)[2] = 0; - (*Colour)[3] = 0; - return IL_TRUE; - } - - (*Colour)[3] = 255; - - if (!stricmp(Buff, "black")) { - (*Colour)[0] = 0; - (*Colour)[1] = 0; - (*Colour)[2] = 0; - return IL_TRUE; - } - if (!stricmp(Buff, "white")) { - (*Colour)[0] = 255; - (*Colour)[1] = 255; - (*Colour)[2] = 255; - return IL_TRUE; - } - if (!stricmp(Buff, "red")) { - (*Colour)[0] = 255; - (*Colour)[1] = 0; - (*Colour)[2] = 0; - return IL_TRUE; - } - if (!stricmp(Buff, "green")) { - (*Colour)[0] = 0; - (*Colour)[1] = 255; - (*Colour)[2] = 0; - return IL_TRUE; - } - if (!stricmp(Buff, "blue")) { - (*Colour)[0] = 0; - (*Colour)[1] = 0; - (*Colour)[2] = 255; - return IL_TRUE; - } - if (!stricmp(Buff, "yellow")) { - (*Colour)[0] = 255; - (*Colour)[1] = 255; - (*Colour)[2] = 0; - return IL_TRUE; - } - if (!stricmp(Buff, "cyan")) { - (*Colour)[0] = 0; - (*Colour)[1] = 255; - (*Colour)[2] = 255; - return IL_TRUE; - } - if (!stricmp(Buff, "gray")) { - (*Colour)[0] = 128; - (*Colour)[1] = 128; - (*Colour)[2] = 128; - return IL_TRUE; - } - - //check for grayXXX codes (added 20040218) - len = strlen(Buff); - if (len >= 4) { - if (Buff[0] == 'g' || Buff[0] == 'G' - || Buff[1] == 'r' || Buff[1] == 'R' - || Buff[2] == 'a' || Buff[2] == 'A' - || Buff[3] == 'y' || Buff[3] == 'Y') { - if (isdigit(Buff[4])) { // isdigit returns false on '\0' - val = Buff[4] - '0'; - if (isdigit(Buff[5])) { - val = val*10 + Buff[5] - '0'; - if (isdigit(Buff[6])) - val = val*10 + Buff[6] - '0'; - } - val = (255*val)/100; - } - (*Colour)[0] = (ILubyte)val; - (*Colour)[1] = (ILubyte)val; - (*Colour)[2] = (ILubyte)val; - return IL_TRUE; - } - } - - - // Unknown colour string, so use black - // (changed 20040218) - (*Colour)[0] = 0; - (*Colour)[1] = 0; - (*Colour)[2] = 0; - - return IL_FALSE; -} - - -#ifndef XPM_DONT_USE_HASHTABLE -ILboolean XpmGetColour(ILubyte *Buffer, ILint Size, int Len, XPMHASHENTRY **Table) - -#else - -ILboolean XpmGetColour(ILubyte *Buffer, ILint Size, int Len, XpmPixel* Colours) - -#endif -{ - ILint i = 0, j, strLen = 0; - ILubyte ColBuff[3]; - char Buff[1024]; - - XpmPixel Colour; - - ILubyte Name[XPM_MAX_CHAR_PER_PIXEL]; - - - for ( ; i < Size; i++) { - if (Buffer[i] == '\"') - break; - } - i++; // Skip the quotes. - - if (i >= Size) - return IL_FALSE; - - // Get the characters. - - for (j = 0; j < Len; ++j) { - Name[j] = Buffer[i++]; - - } - - // Skip to the colour definition. - for ( ; i < Size; i++) { - if (Buffer[i] == 'c') - break; - } - i++; // Skip the 'c'. - - if (i >= Size || Buffer[i] != ' ') { // no 'c' found...assume black - -#ifndef XPM_DONT_USE_HASHTABLE - - memset(Colour, 0, sizeof(Colour)); - - Colour[3] = 255; - - XpmInsertEntry(Table, Name, Len, Colour); - -#else - - memset(Colours[Name[0]], 0, sizeof(Colour)); - - Colours[Name[0]][3] = 255; - -#endif - return IL_TRUE; - - } - - for ( ; i < Size; i++) { - if (Buffer[i] != ' ') - break; - } - - if (i >= Size) - return IL_FALSE; - - if (Buffer[i] == '#') { - // colour string may 4 digits/color or 1 digit/color - // (added 20040218) TODO: is isxdigit() ANSI??? - ++i; - while (i + strLen < Size && isxdigit(Buffer[i + strLen])) - ++strLen; - - for (j = 0; j < 3; j++) { - if (strLen >= 10) { // 4 digits - ColBuff[0] = Buffer[i + j*4]; - ColBuff[1] = Buffer[i + j*4 + 1]; - } - else if (strLen >= 8) { // 3 digits - ColBuff[0] = Buffer[i + j*3]; - ColBuff[1] = Buffer[i + j*3 + 1]; - } - else if (strLen >= 6) { // 2 digits - ColBuff[0] = Buffer[i + j*2]; - ColBuff[1] = Buffer[i + j*2 + 1]; - } - else if(j < strLen) { // 1 digit, strLen >= 1 - ColBuff[0] = Buffer[i + j]; - ColBuff[1] = 0; - } - - ColBuff[2] = 0; // add terminating '\0' char - Colour[j] = (ILubyte)strtol((char*)ColBuff, NULL, 16); - } - Colour[3] = 255; // Full alpha. - } - else { - for (j = 0; i < Size; i++) { - if (!isalnum(Buffer[i])) - break; - Buff[j++] = Buffer[i]; - } - Buff[j] = 0; - - if (i >= Size) - return IL_FALSE; - - if (!XpmPredefCol(Buff, &Colour)) - - return IL_FALSE; - } - - - -#ifndef XPM_DONT_USE_HASHTABLE - - XpmInsertEntry(Table, Name, Len, Colour); - -#else - - memcpy(Colours[Name[0]], Colour, sizeof(Colour)); - -#endif - - return IL_TRUE; -} - - -ILboolean iLoadXpmInternal() -{ - -#define BUFFER_SIZE 2000 - ILubyte Buffer[BUFFER_SIZE], *Data; - ILint Size, Pos, Width, Height, NumColours, i, x, y; - - ILint CharsPerPixel; - -#ifndef XPM_DONT_USE_HASHTABLE - XPMHASHENTRY **HashTable; - -#else - - XpmPixel *Colours; - - ILint Offset; - -#endif - - - Size = XpmGetsInternal(Buffer, BUFFER_SIZE); - if (strncmp("/* XPM */", (char*)Buffer, strlen("/* XPM */"))) { - ilSetError(IL_INVALID_FILE_HEADER); - return IL_FALSE; - } - - Size = XpmGets(Buffer, BUFFER_SIZE); - // @TODO: Actually check the variable name here. - - Size = XpmGets(Buffer, BUFFER_SIZE); - Pos = 0; - Width = XpmGetInt(Buffer, Size, &Pos); - Height = XpmGetInt(Buffer, Size, &Pos); - NumColours = XpmGetInt(Buffer, Size, &Pos); - - CharsPerPixel = XpmGetInt(Buffer, Size, &Pos); - - - -#ifdef XPM_DONT_USE_HASHTABLE - - if (CharsPerPixel != 1) { - - ilSetError(IL_FORMAT_NOT_SUPPORTED); - - return IL_FALSE; - - } - -#endif - - - - if (CharsPerPixel > XPM_MAX_CHAR_PER_PIXEL - - || Width*CharsPerPixel > BUFFER_SIZE) { - - ilSetError(IL_FORMAT_NOT_SUPPORTED); - - return IL_FALSE; - - } - - -#ifndef XPM_DONT_USE_HASHTABLE - HashTable = XpmCreateHashTable(); - - if (HashTable == NULL) - - return IL_FALSE; - -#else - - Colours = ialloc(256 * sizeof(XpmPixel)); - - if (Colours == NULL) - - return IL_FALSE; - -#endif - - for (i = 0; i < NumColours; i++) { - Size = XpmGets(Buffer, BUFFER_SIZE); -#ifndef XPM_DONT_USE_HASHTABLE - - if (!XpmGetColour(Buffer, Size, CharsPerPixel, HashTable)) { - - XpmDestroyHashTable(HashTable); - -#else - - if (!XpmGetColour(Buffer, Size, CharsPerPixel, Colours)) { - - ifree(Colours); - -#endif - - return IL_FALSE; - } - } - - if (!ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { - -#ifndef XPM_DONT_USE_HASHTABLE - - XpmDestroyHashTable(HashTable); - -#else - - ifree(Colours); - -#endif - return IL_FALSE; - - } - - - Data = iCurImage->Data; - - for (y = 0; y < Height; y++) { - Size = XpmGets(Buffer, BUFFER_SIZE); - for (x = 0; x < Width; x++) { - -#ifndef XPM_DONT_USE_HASHTABLE - XpmGetEntry(HashTable, &Buffer[1 + x*CharsPerPixel], CharsPerPixel, &Data[(x << 2)]); - -#else - - Offset = (x << 2); - - Data[Offset + 0] = Colours[Buffer[x + 1]][0]; - - Data[Offset + 1] = Colours[Buffer[x + 1]][1]; - - Data[Offset + 2] = Colours[Buffer[x + 1]][2]; - - Data[Offset + 3] = Colours[Buffer[x + 1]][3]; - -#endif - } - - Data += iCurImage->Bps; - } - - //added 20040218 - iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; - - -#ifndef XPM_DONT_USE_HASHTABLE - - XpmDestroyHashTable(HashTable); - -#else - ifree(Colours); - -#endif - - return IL_TRUE; - -#undef BUFFER_SIZE -} - -#endif//IL_NO_XPM - diff --git a/win32/devil/vcproj/DevIL.sln b/win32/devil/vcproj/DevIL.sln index 715a19244..c2323473e 100644 --- a/win32/devil/vcproj/DevIL.sln +++ b/win32/devil/vcproj/DevIL.sln @@ -1,6 +1,6 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DevIL", "DevIL.vcproj", "{BF596451-4DBC-4E04-B327-9C3EF65064FD}" +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DevIL", "DevIL.vcxproj", "{BF596451-4DBC-4E04-B327-9C3EF65064FD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/win32/devil/vcproj/DevIL.vcproj b/win32/devil/vcproj/DevIL.vcproj deleted file mode 100644 index af4fd3115..000000000 --- a/win32/devil/vcproj/DevIL.vcproj +++ /dev/null @@ -1,604 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/win32/devil/vcproj/DevIL.vcxproj b/win32/devil/vcproj/DevIL.vcxproj new file mode 100644 index 000000000..5a47a2012 --- /dev/null +++ b/win32/devil/vcproj/DevIL.vcxproj @@ -0,0 +1,237 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {BF596451-4DBC-4E04-B327-9C3EF65064FD} + DevIL + + + + StaticLibrary + Static + MultiByte + + + StaticLibrary + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ./../lib\ + Debug\ + ./../lib/\ + Release\ + AllRules.ruleset + + + AllRules.ruleset + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\../../lib/debug/IL.tlb + + + + + Disabled + $(SolutionDir)/../include/IL;$(SolutionDir)/../include/;$(SolutionDir)/../../../include/devil/IL;$(SolutionDir)/../../../include/devil;$(SolutionDir)/../../../include;$(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;IL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + .\../src/obj/debug/IL.pch + .\../src/obj/debug/ + .\../src/obj/debug/ + .\../src/obj/debug/ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + ../src/obj/debug/DevIL.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\../../lib/IL.tlb + + + + + /MP %(AdditionalOptions) + MinSpace + OnlyExplicitInline + $(SolutionDir)/../include/IL;$(SolutionDir)/../include/;$(SolutionDir)/../../../include/devil/IL;$(SolutionDir)/../../../include/devil;$(SolutionDir)/../../../include;$(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;IL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\../src/obj/IL.pch + .\../src/obj/ + .\../src/obj/ + .\../src/obj/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\include;%(AdditionalIncludeDirectories) + + + true + ../src/obj/DevIL.bsc + + + + + + + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/win32/devil/vcproj/DevIL.vcxproj.filters b/win32/devil/vcproj/DevIL.vcxproj.filters new file mode 100644 index 000000000..a550ded17 --- /dev/null +++ b/win32/devil/vcproj/DevIL.vcxproj.filters @@ -0,0 +1,319 @@ + + + + + {d3dabc65-6c9a-47db-89bc-bc07b7384cf1} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {15e91dc4-7d9b-45a6-88b8-c5633ee91ccb} + h;hpp;hxx;hm;inl + + + {0368889d-2e7b-4029-9a31-6b54fcc403b1} + + + {0e7c0c5d-4bfd-49ea-b358-6512737aa57a} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\IL + + + Header Files\IL + + + Header Files\IL + + + Header Files\IL + + + Header Files\IL + + + Header Files\IL + + + Header Files\Win32 Config + + + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/win32/lib/libboost_binaries_vc++2005.7z b/win32/lib/libboost_binaries_vc++2005.7z deleted file mode 100644 index ee0e16aa8..000000000 Binary files a/win32/lib/libboost_binaries_vc++2005.7z and /dev/null differ diff --git a/win32/lib/libboost_date_time-vc90-mt-s-1_45.lib b/win32/lib/libboost_date_time-vc90-mt-s-1_45.lib deleted file mode 100644 index aa7f9a638..000000000 Binary files a/win32/lib/libboost_date_time-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_date_time-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_date_time-vc90-mt-sgd-1_45.lib deleted file mode 100644 index fb73c84de..000000000 Binary files a/win32/lib/libboost_date_time-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_filesystem-vc90-mt-s-1_45.lib b/win32/lib/libboost_filesystem-vc90-mt-s-1_45.lib deleted file mode 100644 index 3cf8bb9ea..000000000 Binary files a/win32/lib/libboost_filesystem-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_filesystem-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_filesystem-vc90-mt-sgd-1_45.lib deleted file mode 100644 index fa9303a23..000000000 Binary files a/win32/lib/libboost_filesystem-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_program_options-vc90-mt-s-1_45.lib b/win32/lib/libboost_program_options-vc90-mt-s-1_45.lib deleted file mode 100644 index e4b3ee825..000000000 Binary files a/win32/lib/libboost_program_options-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_program_options-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_program_options-vc90-mt-sgd-1_45.lib deleted file mode 100644 index 57963c7d0..000000000 Binary files a/win32/lib/libboost_program_options-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_regex-vc90-mt-s-1_45.lib b/win32/lib/libboost_regex-vc90-mt-s-1_45.lib deleted file mode 100644 index 581c1c6ad..000000000 Binary files a/win32/lib/libboost_regex-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_regex-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_regex-vc90-mt-sgd-1_45.lib deleted file mode 100644 index 9c057e115..000000000 Binary files a/win32/lib/libboost_regex-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_system-vc90-mt-s-1_45.lib b/win32/lib/libboost_system-vc90-mt-s-1_45.lib deleted file mode 100644 index 697f077f5..000000000 Binary files a/win32/lib/libboost_system-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_system-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_system-vc90-mt-sgd-1_45.lib deleted file mode 100644 index 2db81ab0f..000000000 Binary files a/win32/lib/libboost_system-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_thread-vc90-mt-s-1_45.lib b/win32/lib/libboost_thread-vc90-mt-s-1_45.lib deleted file mode 100644 index c4a9936df..000000000 Binary files a/win32/lib/libboost_thread-vc90-mt-s-1_45.lib and /dev/null differ diff --git a/win32/lib/libboost_thread-vc90-mt-sgd-1_45.lib b/win32/lib/libboost_thread-vc90-mt-sgd-1_45.lib deleted file mode 100644 index 7c8d0adcc..000000000 Binary files a/win32/lib/libboost_thread-vc90-mt-sgd-1_45.lib and /dev/null differ diff --git a/win32/libcurl/libcurl.sln b/win32/libcurl/libcurl.sln index c59ebbb66..06d52bded 100644 --- a/win32/libcurl/libcurl.sln +++ b/win32/libcurl/libcurl.sln @@ -1,7 +1,7 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "libcurl.vcproj", "{87EE9DA4-DE1E-4448-8324-183C98DCA588}" +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "libcurl.vcxproj", "{87EE9DA4-DE1E-4448-8324-183C98DCA588}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/win32/libcurl/libcurl.vcproj b/win32/libcurl/libcurl.vcproj deleted file mode 100644 index d0f035b12..000000000 --- a/win32/libcurl/libcurl.vcproj +++ /dev/null @@ -1,964 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/win32/libcurl/libcurl.vcxproj b/win32/libcurl/libcurl.vcxproj new file mode 100644 index 000000000..689600f44 --- /dev/null +++ b/win32/libcurl/libcurl.vcxproj @@ -0,0 +1,327 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {87EE9DA4-DE1E-4448-8324-183C98DCA588} + + + + StaticLibrary + false + MultiByte + + + StaticLibrary + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../lib\ + .\Release\ + ../lib\ + .\Debug\ + AllRules.ruleset + + + AllRules.ruleset + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/libcurl.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;BUILDING_LIBCURL;CURL_DISABLE_LDAP;CURL_DISABLE_POP3;CURL_DISABLE_SMTP;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/libcurl.pch + .\Release/ + .\Release/ + .\Release/ + + + TurnOffAllWarnings + true + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + false + %(IgnoreSpecificDefaultLibraries) + + + true + .\Release/libcurl.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/libcurl.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;BUILDING_LIBCURL;CURL_DISABLE_LDAP;CURL_DISABLE_POP3;CURL_DISABLE_SMTP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + .\Debug/libcurl.pch + .\Debug/ + .\Debug/ + .\Debug/ + true + TurnOffAllWarnings + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + .\Debug/libcurl.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/win32/libcurl/libcurl.vcxproj.filters b/win32/libcurl/libcurl.vcxproj.filters new file mode 100644 index 000000000..8f797712b --- /dev/null +++ b/win32/libcurl/libcurl.vcxproj.filters @@ -0,0 +1,592 @@ + + + + + {e26f1eb4-005b-4499-9004-04d4f56b5619} + + + {d750805f-c083-4d2c-a5af-750e90ebf58c} + + + {11f95342-1657-416d-a09f-e08d12e94e6a} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/win32/libjpeg/lib/libjpeg.lib b/win32/libjpeg/lib/libjpeg.lib index d7bf2a35e..c51623ded 100644 Binary files a/win32/libjpeg/lib/libjpeg.lib and b/win32/libjpeg/lib/libjpeg.lib differ diff --git a/win32/libjpeg/vcproj/libjpeg.sln b/win32/libjpeg/vcproj/libjpeg.sln index 19bfe5b94..0a64fa05e 100644 --- a/win32/libjpeg/vcproj/libjpeg.sln +++ b/win32/libjpeg/vcproj/libjpeg.sln @@ -1,13 +1,23 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libpng.vcproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libjpeg.vcxproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL Debug|Win32 = DLL Debug|Win32 + DLL Release|Win32 = DLL Release|Win32 + DLL VB|Win32 = DLL VB|Win32 LIB Debug|Win32 = LIB Debug|Win32 LIB Release|Win32 = LIB Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB|Win32.ActiveCfg = DLL VB|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB|Win32.Build.0 = DLL VB|Win32 {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32 {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug|Win32.Build.0 = LIB Debug|Win32 {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Release|Win32.ActiveCfg = LIB Release|Win32 diff --git a/win32/libjpeg/vcproj/libjpeg.vcxproj b/win32/libjpeg/vcproj/libjpeg.vcxproj new file mode 100644 index 000000000..65bfcd653 --- /dev/null +++ b/win32/libjpeg/vcproj/libjpeg.vcxproj @@ -0,0 +1,289 @@ + + + + + DLL Debug + Win32 + + + DLL Release + Win32 + + + DLL VB + Win32 + + + LIB Debug + Win32 + + + LIB Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + libjpeg + {0008960E-E0DD-41A6-8265-00B31DDB4C21} + libpng + + + + StaticLibrary + + + StaticLibrary + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + false + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + false + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + OnlyExplicitInline + $(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + NotUsing + + + Level3 + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14.dll + ..\..\scripts\pngwin.def + false + + + + + + + Disabled + $(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + NotUsing + + + Level3 + EditAndContinue + Default + + + _DEBUG;PNG_DEBUG=1;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14d.dll + ..\..\scripts\pngwin.def + true + false + + + + + + + OnlyExplicitInline + $(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;PNGAPI=__stdcall;PNG_NO_MODULEDEF;PNG_LIBPNG_SPECIALBUILD;PNG_USER_PRIVATEBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + NotUsing + + + Level3 + Default + + + /d PNG_NO_PEDANTIC_WARNINGS /d PNG_LIBPNG_DLLFNAME_POSTFIX=""""VB"""" /d PNG_LIBPNG_SPECIALBUILD=""""__stdcall calling convention used for exported functions"""" %(AdditionalOptions) + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14vb.dll + false + + + + + + + /MP %(AdditionalOptions) + OnlyExplicitInline + $(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + NotUsing + + + Level3 + Default + + + $(OutDir)libjpeg.lib + + + + + Disabled + $(SolutionDir)/../../../include/libjpeg;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + NotUsing + + + Level3 + EditAndContinue + Default + + + $(OutDir)libjpeg.lib + + + + + + \ No newline at end of file diff --git a/win32/libjpeg/vcproj/libjpeg.vcxproj.filters b/win32/libjpeg/vcproj/libjpeg.vcxproj.filters new file mode 100644 index 000000000..776ce9b66 --- /dev/null +++ b/win32/libjpeg/vcproj/libjpeg.vcxproj.filters @@ -0,0 +1,206 @@ + + + + + {7d5f6be9-6f9c-4875-b77d-1172c4fa54f1} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {c6fb2a11-0ea0-44e7-a22c-d1dac604a1f8} + h;hpp;hxx;hm;inl + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/win32/libjpeg/vcproj/libpng.vcproj b/win32/libjpeg/vcproj/libpng.vcproj deleted file mode 100644 index 5a8000c6c..000000000 --- a/win32/libjpeg/vcproj/libpng.vcproj +++ /dev/null @@ -1,631 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/win32/libpng/lib/libpng.lib b/win32/libpng/lib/libpng.lib index d59194362..cd8a0b748 100644 Binary files a/win32/libpng/lib/libpng.lib and b/win32/libpng/lib/libpng.lib differ diff --git a/win32/libpng/vcproj/libpng.sln b/win32/libpng/vcproj/libpng.sln index a1bf7b759..84fab5ab5 100644 --- a/win32/libpng/vcproj/libpng.sln +++ b/win32/libpng/vcproj/libpng.sln @@ -1,6 +1,6 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng.vcproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng.vcxproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/win32/libpng/vcproj/libpng.vcproj b/win32/libpng/vcproj/libpng.vcproj deleted file mode 100644 index 8300cf068..000000000 --- a/win32/libpng/vcproj/libpng.vcproj +++ /dev/null @@ -1,471 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/win32/libpng/vcproj/libpng.vcxproj b/win32/libpng/vcproj/libpng.vcxproj new file mode 100644 index 000000000..cad4db4ac --- /dev/null +++ b/win32/libpng/vcproj/libpng.vcxproj @@ -0,0 +1,240 @@ + + + + + DLL Debug + Win32 + + + DLL Release + Win32 + + + DLL VB + Win32 + + + LIB Debug + Win32 + + + LIB Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + {0008960E-E0DD-41A6-8265-00B31DDB4C21} + libpng + + + + StaticLibrary + + + StaticLibrary + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + false + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + false + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + $(SolutionDir)/../lib\ + $(SolutionDir)/../build\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + OnlyExplicitInline + $(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + png.h + Level3 + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14.dll + ..\..\scripts\pngwin.def + false + + + + + + + Disabled + $(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + png.h + Level3 + EditAndContinue + Default + + + _DEBUG;PNG_DEBUG=1;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14d.dll + ..\..\scripts\pngwin.def + true + false + + + + + + + OnlyExplicitInline + $(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;PNGAPI=__stdcall;PNG_NO_MODULEDEF;PNG_LIBPNG_SPECIALBUILD;PNG_USER_PRIVATEBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + png.h + Level3 + Default + + + /d PNG_NO_PEDANTIC_WARNINGS /d PNG_LIBPNG_DLLFNAME_POSTFIX=""""VB"""" /d PNG_LIBPNG_SPECIALBUILD=""""__stdcall calling convention used for exported functions"""" %(AdditionalOptions) + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..;..\..\scripts;..\..\..\zlib;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)libpng14vb.dll + false + + + + + + + /MP %(AdditionalOptions) + OnlyExplicitInline + $(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + png.h + Level3 + Default + + + $(OutDir)libpng.lib + + + + + Disabled + $(SolutionDir)/../../../include/libpng;$(SolutionDir)/../../../include/zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + Use + png.h + Level3 + EditAndContinue + Default + + + $(OutDir)libpngd.lib + + + + + + \ No newline at end of file diff --git a/win32/libpng/vcproj/libpng.vcxproj.filters b/win32/libpng/vcproj/libpng.vcxproj.filters new file mode 100644 index 000000000..71e2d908d --- /dev/null +++ b/win32/libpng/vcproj/libpng.vcxproj.filters @@ -0,0 +1,74 @@ + + + + + {da14c05c-b79b-4272-b23d-84935bcdd32f} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {5f368990-b45a-4cd5-981c-17ccaee7415c} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file